summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBryan O'Sullivan <bos@lindenlab.com>2009-08-31 13:47:47 -0700
committerBryan O'Sullivan <bos@lindenlab.com>2009-08-31 13:47:47 -0700
commit30ff6cabd61f2f083df5df1e6e70cc94742af477 (patch)
tree631935f1cf59d19a91cdad65e9a75fe825afda7d
parentff11d74820c89822cd067b51727d9df1dc87d0d0 (diff)
parent3ac3a4b206c08ed06b889bdaa24074b6aa0e020a (diff)
Merge with trunk
-rw-r--r--doc/contributions.txt4
-rw-r--r--etc/message.xml16
-rw-r--r--indra/CMakeLists.txt19
-rw-r--r--indra/cmake/00-Common.cmake3
-rw-r--r--indra/cmake/CMakeLists.txt6
-rw-r--r--indra/cmake/GStreamer010Plugin.cmake39
-rw-r--r--indra/cmake/Glui.cmake28
-rw-r--r--indra/cmake/Glut.cmake19
-rw-r--r--indra/cmake/GooglePerfTools.cmake8
-rw-r--r--indra/cmake/LLAddBuildTest.cmake76
-rw-r--r--indra/cmake/LLCommon.cmake4
-rw-r--r--indra/cmake/LLPlugin.cmake8
-rw-r--r--indra/cmake/LLXUIXML.cmake7
-rw-r--r--indra/cmake/Linking.cmake1
-rw-r--r--indra/cmake/MediaPluginBase.cmake8
-rw-r--r--indra/cmake/PluginAPI.cmake16
-rw-r--r--indra/cmake/QuickTimePlugin.cmake46
-rw-r--r--indra/cmake/Variables.cmake1
-rw-r--r--indra/cmake/WebKitLibPlugin.cmake63
-rwxr-xr-xindra/develop.py13
-rw-r--r--indra/integration_tests/CMakeLists.txt3
-rw-r--r--indra/integration_tests/llui_libtest/CMakeLists.txt103
-rw-r--r--indra/integration_tests/llui_libtest/llui_libtest.cpp221
-rw-r--r--indra/integration_tests/llui_libtest/llui_libtest.h36
-rw-r--r--indra/integration_tests/llui_libtest/llwidgetreg.cpp108
-rw-r--r--indra/integration_tests/llui_libtest/llwidgetreg.h43
-rw-r--r--indra/linux_updater/CMakeLists.txt58
-rw-r--r--indra/linux_updater/linux_updater.cpp818
-rw-r--r--indra/llaudio/CMakeLists.txt42
-rw-r--r--indra/llaudio/llaudiodecodemgr.cpp6
-rw-r--r--indra/llaudio/llaudioengine.cpp1751
-rw-r--r--indra/llaudio/llaudioengine.h452
-rw-r--r--indra/llaudio/llaudioengine_fmod.cpp766
-rw-r--r--indra/llaudio/llaudioengine_fmod.h129
-rw-r--r--indra/llaudio/llaudioengine_openal.cpp546
-rw-r--r--indra/llaudio/llaudioengine_openal.h114
-rw-r--r--indra/llaudio/lllistener.cpp142
-rw-r--r--indra/llaudio/lllistener.h78
-rw-r--r--indra/llaudio/lllistener_ds3d.h74
-rw-r--r--indra/llaudio/lllistener_fmod.cpp131
-rw-r--r--indra/llaudio/lllistener_fmod.h64
-rw-r--r--indra/llaudio/lllistener_openal.cpp116
-rw-r--r--indra/llaudio/lllistener_openal.h64
-rw-r--r--indra/llaudio/llstreamingaudio.h56
-rw-r--r--indra/llaudio/llstreamingaudio_fmod.cpp362
-rw-r--r--indra/llaudio/llstreamingaudio_fmod.h68
-rw-r--r--indra/llaudio/llvorbisencode.cpp505
-rw-r--r--indra/llaudio/llvorbisencode.h53
-rw-r--r--indra/llaudio/llwindgen.h136
-rw-r--r--indra/llcharacter/llbvhloader.cpp161
-rw-r--r--indra/llcharacter/llbvhloader.h51
-rw-r--r--indra/llcharacter/llcharacter.cpp4
-rw-r--r--indra/llcharacter/llcharacter.h12
-rw-r--r--indra/llcharacter/lljoint.h2
-rw-r--r--indra/llcharacter/lljointstate.h2
-rw-r--r--indra/llcharacter/llkeyframemotionparam.cpp7
-rw-r--r--indra/llcharacter/llmotioncontroller.cpp4
-rw-r--r--indra/llcharacter/llmotioncontroller.h6
-rw-r--r--indra/llcharacter/llmultigesture.cpp65
-rw-r--r--indra/llcharacter/llmultigesture.h16
-rw-r--r--indra/llcharacter/llpose.cpp4
-rw-r--r--indra/llcharacter/llpose.h6
-rw-r--r--indra/llcharacter/llvisualparam.h22
-rw-r--r--indra/llcommon/CMakeLists.txt40
-rw-r--r--indra/llcommon/is_approx_equal_fraction.h23
-rw-r--r--indra/llcommon/linden_common.h18
-rw-r--r--indra/llcommon/llallocator.cpp140
-rw-r--r--indra/llcommon/llallocator.h63
-rw-r--r--indra/llcommon/llallocator_heap_profile.cpp149
-rw-r--r--indra/llcommon/llallocator_heap_profile.h77
-rw-r--r--indra/llcommon/llapp.h5
-rw-r--r--indra/llcommon/llassettype.cpp14
-rw-r--r--indra/llcommon/llassettype.h1
-rw-r--r--indra/llcommon/llboost.h15
-rw-r--r--indra/llcommon/llcommon.cpp2
-rw-r--r--indra/llcommon/llcommon.h3
-rw-r--r--indra/llcommon/lldate.cpp58
-rw-r--r--indra/llcommon/lldate.h4
-rw-r--r--indra/llcommon/lldeleteutils.h53
-rw-r--r--indra/llcommon/lldependencies.h3
-rwxr-xr-xindra/llcommon/lldoubledispatch.h332
-rw-r--r--indra/llcommon/llerror.cpp17
-rw-r--r--indra/llcommon/llerrorcontrol.h16
-rw-r--r--indra/llcommon/llerrorthread.cpp2
-rw-r--r--indra/llcommon/llevent.h2
-rw-r--r--indra/llcommon/llevents.h11
-rw-r--r--indra/llcommon/llfasttimer.h374
-rw-r--r--indra/llcommon/llfixedbuffer.cpp13
-rw-r--r--indra/llcommon/llfixedbuffer.h22
-rw-r--r--indra/llcommon/llinstancetracker.h121
-rw-r--r--indra/llcommon/llmd5.cpp1
-rw-r--r--indra/llcommon/llmemory.cpp208
-rw-r--r--indra/llcommon/llmemory.h429
-rw-r--r--indra/llcommon/llmemtype.cpp237
-rw-r--r--indra/llcommon/llmemtype.h300
-rw-r--r--indra/llcommon/llmetrics.cpp2
-rw-r--r--indra/llcommon/lloptioninterface.cpp39
-rw-r--r--indra/llcommon/lloptioninterface.h46
-rw-r--r--indra/llcommon/llpointer.h177
-rw-r--r--indra/llcommon/llpreprocessor.h4
-rw-r--r--indra/llcommon/llprocesslauncher.cpp344
-rw-r--r--indra/llcommon/llprocesslauncher.h85
-rw-r--r--indra/llcommon/llptrto.cpp108
-rw-r--r--indra/llcommon/llptrto.h93
-rw-r--r--indra/llcommon/llqueuedthread.cpp2
-rw-r--r--indra/llcommon/llrefcount.cpp49
-rw-r--r--indra/llcommon/llrefcount.h79
-rw-r--r--indra/llcommon/llsafehandle.h167
-rw-r--r--indra/llcommon/llsd.cpp18
-rw-r--r--indra/llcommon/llsdserialize.cpp2
-rw-r--r--indra/llcommon/llsdserialize.h3
-rw-r--r--indra/llcommon/llsdutil.cpp9
-rw-r--r--indra/llcommon/llsdutil.h1
-rw-r--r--indra/llcommon/llsecondlifeurls.cpp34
-rw-r--r--indra/llcommon/llsecondlifeurls.h13
-rw-r--r--indra/llcommon/llsingleton.h165
-rw-r--r--indra/llcommon/llstacktrace.cpp141
-rw-r--r--indra/llcommon/llstacktrace.h44
-rw-r--r--indra/llcommon/llstat.cpp42
-rw-r--r--indra/llcommon/llstat.h25
-rw-r--r--indra/llcommon/llstring.cpp79
-rw-r--r--indra/llcommon/llstring.h364
-rw-r--r--indra/llcommon/llthread.h1
-rw-r--r--indra/llcommon/lltimer.cpp9
-rw-r--r--indra/llcommon/lltimer.h9
-rw-r--r--indra/llcommon/lltreeiterators.h711
-rw-r--r--indra/llcommon/llversionviewer.h8
-rw-r--r--indra/llcommon/tests/llallocator_heap_profile_test.cpp150
-rw-r--r--indra/llcommon/tests/llallocator_test.cpp86
-rw-r--r--indra/llcommon/tests/llmemtype_test.cpp123
-rwxr-xr-xindra/llcrashlogger/llcrashlogger.cpp1
-rw-r--r--indra/llimage/llimage.cpp14
-rw-r--r--indra/llimage/llimage.h5
-rw-r--r--indra/llimage/llimagedxt.h1
-rw-r--r--indra/llimage/llimagej2c.cpp6
-rw-r--r--indra/llimage/llimagetga.cpp4
-rw-r--r--indra/llimage/llimageworker.h1
-rw-r--r--indra/llimagej2coj/llimagej2coj.cpp2
-rw-r--r--indra/llinventory/lleconomy.h2
-rw-r--r--indra/llinventory/llinventory.cpp110
-rw-r--r--indra/llinventory/llinventory.h14
-rw-r--r--indra/llinventory/llinventorytype.cpp1
-rw-r--r--indra/llinventory/llinventorytype.h7
-rw-r--r--indra/llinventory/lllandmark.cpp22
-rw-r--r--indra/llinventory/lllandmark.h25
-rw-r--r--indra/llinventory/llnotecard.h2
-rw-r--r--indra/llinventory/llparcel.cpp130
-rw-r--r--indra/llinventory/llparcel.h32
-rw-r--r--indra/llinventory/llpermissions.cpp63
-rw-r--r--indra/llinventory/llpermissions.h9
-rw-r--r--indra/llinventory/llpermissionsflags.h3
-rw-r--r--indra/llinventory/llsaleinfo.cpp34
-rw-r--r--indra/llinventory/llsaleinfo.h3
-rw-r--r--indra/llmath/CMakeLists.txt2
-rw-r--r--indra/llmath/llbbox.cpp160
-rw-r--r--indra/llmath/llbbox.h103
-rw-r--r--indra/llmath/llbboxlocal.h3
-rw-r--r--indra/llmath/llmath.h4
-rw-r--r--indra/llmath/lloctree.h10
-rw-r--r--indra/llmath/llrect.h50
-rw-r--r--indra/llmath/llsdutil_math.cpp5
-rw-r--r--indra/llmath/llvolume.cpp8
-rw-r--r--indra/llmath/llvolume.h12
-rw-r--r--indra/llmath/llvolumemgr.h6
-rw-r--r--indra/llmath/v3color.cpp36
-rw-r--r--indra/llmath/v3color.h1
-rw-r--r--indra/llmath/v3dmath.h8
-rw-r--r--indra/llmath/v3math.cpp6
-rw-r--r--indra/llmath/v3math.h4
-rw-r--r--indra/llmath/v4color.cpp70
-rw-r--r--indra/llmath/v4color.h24
-rw-r--r--indra/llmath/v4coloru.h14
-rw-r--r--indra/llmath/xform.h2
-rw-r--r--indra/llmessage/CMakeLists.txt17
-rw-r--r--indra/llmessage/llares.h3
-rw-r--r--indra/llmessage/llassetstorage.cpp12
-rw-r--r--indra/llmessage/llassetstorage.h6
-rw-r--r--indra/llmessage/llcachename.cpp409
-rw-r--r--indra/llmessage/llcachename.h26
-rw-r--r--indra/llmessage/llcurl.cpp4
-rw-r--r--indra/llmessage/llcurl.h2
-rw-r--r--indra/llmessage/llhttpassetstorage.cpp2
-rw-r--r--indra/llmessage/llhttpassetstorage.h2
-rw-r--r--indra/llmessage/llhttpclientadapter.cpp7
-rw-r--r--indra/llmessage/llhttpclientadapter.h9
-rw-r--r--indra/llmessage/llhttpclientinterface.h7
-rw-r--r--indra/llmessage/llhttpnode.cpp18
-rw-r--r--indra/llmessage/llhttpnode.h14
-rw-r--r--indra/llmessage/llhttpnodeadapter.h15
-rw-r--r--indra/llmessage/llinstantmessage.cpp2
-rw-r--r--indra/llmessage/llinstantmessage.h3
-rw-r--r--indra/llmessage/lliohttpserver.cpp1
-rw-r--r--indra/llmessage/llmessagesenderinterface.h7
-rw-r--r--indra/llmessage/llpumpio.cpp4
-rw-r--r--indra/llmessage/llregionpresenceverifier.cpp25
-rw-r--r--indra/llmessage/llregionpresenceverifier.h26
-rw-r--r--indra/llmessage/llsdappservices.cpp4
-rw-r--r--indra/llmessage/llsdhttpserver.cpp4
-rw-r--r--indra/llmessage/llsdmessage.cpp4
-rw-r--r--indra/llmessage/llsdmessage.h2
-rw-r--r--indra/llmessage/llstoredmessage.cpp2
-rw-r--r--indra/llmessage/llstoredmessage.h2
-rw-r--r--indra/llmessage/lltemplatemessagedispatcher.cpp17
-rw-r--r--indra/llmessage/lltemplatemessagedispatcher.h17
-rw-r--r--indra/llmessage/lltemplatemessagereader.cpp4
-rw-r--r--indra/llmessage/lltrustedmessageservice.cpp17
-rw-r--r--indra/llmessage/lltrustedmessageservice.h17
-rw-r--r--indra/llmessage/message.cpp3
-rw-r--r--indra/llmessage/message.h2
-rw-r--r--indra/llmessage/message_prehash.cpp2
-rw-r--r--indra/llmessage/tests/commtest.h23
-rw-r--r--indra/llmessage/tests/llcurl_stub.cpp14
-rw-r--r--indra/llmessage/tests/llhttpclientadapter_test.cpp7
-rw-r--r--indra/llmessage/tests/lltemplatemessagedispatcher_test.cpp17
-rw-r--r--indra/llmessage/tests/lltesthttpclientadapter.cpp2
-rw-r--r--indra/llmessage/tests/lltesthttpclientadapter.h2
-rw-r--r--indra/llmessage/tests/lltestmessagesender.cpp2
-rw-r--r--indra/llmessage/tests/lltestmessagesender.h2
-rw-r--r--indra/llmessage/tests/lltrustedmessageservice_test.cpp17
-rw-r--r--indra/llmessage/tests/networkio.h23
-rw-r--r--indra/llplugin/CMakeLists.txt55
-rw-r--r--indra/llplugin/llpluginclassmedia.cpp1042
-rw-r--r--indra/llplugin/llpluginclassmedia.h333
-rw-r--r--indra/llplugin/llpluginclassmediaowner.h79
-rw-r--r--indra/llplugin/llplugininstance.cpp140
-rw-r--r--indra/llplugin/llplugininstance.h88
-rw-r--r--indra/llplugin/llpluginmessage.cpp249
-rw-r--r--indra/llplugin/llpluginmessage.h123
-rw-r--r--indra/llplugin/llpluginmessageclasses.h56
-rw-r--r--indra/llplugin/llpluginmessagepipe.cpp315
-rw-r--r--indra/llplugin/llpluginmessagepipe.h91
-rw-r--r--indra/llplugin/llpluginprocesschild.cpp466
-rw-r--r--indra/llplugin/llpluginprocesschild.h108
-rw-r--r--indra/llplugin/llpluginprocessparent.cpp658
-rw-r--r--indra/llplugin/llpluginprocessparent.h147
-rw-r--r--indra/llplugin/llpluginsharedmemory.cpp495
-rw-r--r--indra/llplugin/llpluginsharedmemory.h79
-rw-r--r--indra/llplugin/slplugin/CMakeLists.txt55
-rw-r--r--indra/llplugin/slplugin/slplugin.cpp243
-rw-r--r--indra/llplugin/slplugin/slplugin_info.plist12
-rw-r--r--indra/llprimitive/llmaterialtable.cpp11
-rw-r--r--indra/llprimitive/llmaterialtable.h2
-rw-r--r--indra/llprimitive/llprimitive.cpp2
-rw-r--r--indra/llprimitive/llprimitive.h2
-rw-r--r--indra/llprimitive/llprimtexturelist.cpp7
-rw-r--r--indra/llprimitive/llprimtexturelist.h7
-rw-r--r--indra/llprimitive/tests/llmessagesystem_stub.cpp42
-rw-r--r--indra/llprimitive/tests/llprimitive_test.cpp214
-rw-r--r--indra/llrender/CMakeLists.txt6
-rw-r--r--indra/llrender/llfontbitmapcache.cpp7
-rw-r--r--indra/llrender/llfontbitmapcache.h9
-rw-r--r--indra/llrender/llfontfreetype.cpp644
-rw-r--r--indra/llrender/llfontfreetype.h380
-rw-r--r--indra/llrender/llfontgl.cpp1169
-rw-r--r--indra/llrender/llfontgl.h219
-rw-r--r--indra/llrender/llfontregistry.cpp77
-rw-r--r--indra/llrender/llfontregistry.h15
-rw-r--r--indra/llrender/llgl.cpp201
-rw-r--r--indra/llrender/llgl.h9
-rw-r--r--indra/llrender/llglslshader.cpp10
-rw-r--r--indra/llrender/llimagegl.cpp156
-rw-r--r--indra/llrender/llimagegl.h57
-rw-r--r--indra/llrender/llrender.cpp84
-rw-r--r--indra/llrender/llrender.h5
-rw-r--r--indra/llrender/llrendertarget.cpp13
-rw-r--r--indra/llrender/llrendertarget.h4
-rw-r--r--indra/llrender/lltexture.cpp37
-rw-r--r--indra/llrender/lltexture.h77
-rw-r--r--indra/llrender/llvertexbuffer.cpp136
-rw-r--r--indra/llrender/llvertexbuffer.h1
-rw-r--r--indra/llui/CMakeLists.txt59
-rw-r--r--indra/llui/llbutton.cpp964
-rw-r--r--indra/llui/llbutton.h275
-rw-r--r--indra/llui/llcallbackmap.h19
-rw-r--r--indra/llui/llcheckboxctrl.cpp281
-rw-r--r--indra/llui/llcheckboxctrl.h68
-rw-r--r--indra/llui/llclipboard.cpp6
-rw-r--r--indra/llui/llclipboard.h1
-rw-r--r--indra/llui/llcombobox.cpp664
-rw-r--r--indra/llui/llcombobox.h133
-rw-r--r--indra/llui/llconsole.cpp393
-rw-r--r--indra/llui/llconsole.h163
-rw-r--r--indra/llui/llcontainerview.cpp302
-rw-r--r--indra/llui/llcontainerview.h100
-rw-r--r--indra/llui/lldraghandle.cpp122
-rw-r--r--indra/llui/lldraghandle.h45
-rw-r--r--indra/llui/llf32uictrl.cpp57
-rw-r--r--indra/llui/llf32uictrl.h83
-rw-r--r--indra/llui/llfiltereditor.cpp116
-rw-r--r--indra/llui/llfiltereditor.h87
-rw-r--r--indra/llui/llfloater.cpp1815
-rw-r--r--indra/llui/llfloater.h341
-rw-r--r--indra/llui/llfloaterreg.cpp440
-rw-r--r--indra/llui/llfloaterreg.h153
-rw-r--r--indra/llui/llflyoutbutton.cpp82
-rw-r--r--indra/llui/llflyoutbutton.h74
-rw-r--r--indra/llui/llfocusmgr.cpp186
-rw-r--r--indra/llui/llfocusmgr.h62
-rw-r--r--indra/llui/llfunctorregistry.h2
-rw-r--r--indra/llui/llhandle.h171
-rw-r--r--indra/llui/lliconctrl.cpp136
-rw-r--r--indra/llui/lliconctrl.h35
-rw-r--r--indra/llui/llkeywords.cpp37
-rw-r--r--indra/llui/llkeywords.h7
-rw-r--r--indra/llui/lllayoutstack.cpp742
-rw-r--r--indra/llui/lllayoutstack.h107
-rw-r--r--indra/llui/lllazyvalue.h88
-rw-r--r--indra/llui/lllineeditor.cpp833
-rw-r--r--indra/llui/lllineeditor.h186
-rw-r--r--indra/llui/llmenugl.cpp3217
-rw-r--r--indra/llui/llmenugl.h669
-rw-r--r--indra/llui/llmodaldialog.cpp77
-rw-r--r--indra/llui/llmodaldialog.h18
-rw-r--r--indra/llui/llmultifloater.cpp503
-rw-r--r--indra/llui/llmultifloater.h106
-rw-r--r--indra/llui/llmultislider.cpp221
-rw-r--r--indra/llui/llmultislider.h99
-rw-r--r--indra/llui/llmultisliderctrl.cpp397
-rw-r--r--indra/llui/llmultisliderctrl.h79
-rw-r--r--indra/llui/llnotifications.cpp200
-rw-r--r--indra/llui/llnotifications.h125
-rw-r--r--indra/llui/llpanel.cpp1358
-rw-r--r--indra/llui/llpanel.h217
-rw-r--r--indra/llui/llprogressbar.cpp130
-rw-r--r--indra/llui/llprogressbar.h39
-rw-r--r--indra/llui/llradiogroup.cpp252
-rw-r--r--indra/llui/llradiogroup.h84
-rw-r--r--indra/llui/llresizebar.cpp37
-rw-r--r--indra/llui/llresizebar.h26
-rw-r--r--indra/llui/llresizehandle.cpp59
-rw-r--r--indra/llui/llresizehandle.h18
-rw-r--r--indra/llui/llresmgr.cpp147
-rw-r--r--indra/llui/llresmgr.h25
-rw-r--r--indra/llui/llrngwriter.cpp315
-rw-r--r--indra/llui/llrngwriter.h69
-rw-r--r--indra/llui/llscrollbar.cpp287
-rw-r--r--indra/llui/llscrollbar.h83
-rw-r--r--indra/llui/llscrollcontainer.cpp577
-rw-r--r--indra/llui/llscrollcontainer.h68
-rw-r--r--indra/llui/llscrollingpanellist.cpp83
-rw-r--r--indra/llui/llscrollingpanellist.h33
-rw-r--r--indra/llui/llscrolllistcell.cpp418
-rw-r--r--indra/llui/llscrolllistcell.h222
-rw-r--r--indra/llui/llscrolllistcolumn.cpp328
-rw-r--r--indra/llui/llscrolllistcolumn.h191
-rw-r--r--indra/llui/llscrolllistctrl.cpp1978
-rw-r--r--indra/llui/llscrolllistctrl.h444
-rw-r--r--indra/llui/llscrolllistitem.cpp157
-rw-r--r--indra/llui/llscrolllistitem.h129
-rw-r--r--indra/llui/llsdparam.cpp158
-rw-r--r--indra/llui/llsdparam.h107
-rw-r--r--indra/llui/llsearcheditor.cpp98
-rw-r--r--indra/llui/llsearcheditor.h91
-rw-r--r--indra/llui/llslider.cpp197
-rw-r--r--indra/llui/llslider.h90
-rw-r--r--indra/llui/llsliderctrl.cpp343
-rw-r--r--indra/llui/llsliderctrl.h126
-rw-r--r--indra/llui/llspinctrl.cpp385
-rw-r--r--indra/llui/llspinctrl.h78
-rw-r--r--indra/llui/llstatbar.cpp293
-rw-r--r--indra/llui/llstatbar.h108
-rw-r--r--indra/llui/llstatgraph.cpp163
-rw-r--r--indra/llui/llstatgraph.h76
-rw-r--r--indra/llui/llstatview.cpp71
-rw-r--r--indra/llui/llstatview.h72
-rw-r--r--indra/llui/llstyle.cpp125
-rw-r--r--indra/llui/llstyle.h73
-rw-r--r--indra/llui/lltabcontainer.cpp891
-rw-r--r--indra/llui/lltabcontainer.h142
-rw-r--r--indra/llui/lltextbox.cpp258
-rw-r--r--indra/llui/lltextbox.h75
-rw-r--r--indra/llui/lltexteditor.cpp3347
-rw-r--r--indra/llui/lltexteditor.h487
-rw-r--r--indra/llui/lltextparser.cpp55
-rw-r--r--indra/llui/lltextparser.h34
-rw-r--r--indra/llui/lltransutil.cpp67
-rw-r--r--indra/llui/lltransutil.h51
-rw-r--r--indra/llui/llui.cpp435
-rw-r--r--indra/llui/llui.h630
-rw-r--r--indra/llui/lluicolortable.cpp294
-rw-r--r--indra/llui/lluicolortable.h83
-rw-r--r--indra/llui/lluictrl.cpp529
-rw-r--r--indra/llui/lluictrl.h245
-rw-r--r--indra/llui/lluictrlfactory.cpp507
-rw-r--r--indra/llui/lluictrlfactory.h381
-rw-r--r--indra/llui/lluifwd.h1
-rw-r--r--indra/llui/lluiimage.cpp166
-rw-r--r--indra/llui/lluiimage.h116
-rw-r--r--indra/llui/lluistring.cpp20
-rw-r--r--indra/llui/llview.cpp1420
-rw-r--r--indra/llui/llview.h397
-rw-r--r--indra/llui/llviewborder.cpp149
-rw-r--r--indra/llui/llviewborder.h57
-rw-r--r--indra/llui/llviewmodel.cpp163
-rw-r--r--indra/llui/llviewmodel.h219
-rw-r--r--indra/llui/llviewquery.h2
-rw-r--r--indra/llvfs/lldir.cpp78
-rw-r--r--indra/llvfs/lldir.h41
-rw-r--r--indra/llvfs/lldir_linux.cpp24
-rw-r--r--indra/llvfs/lldir_linux.h6
-rw-r--r--indra/llvfs/lldir_mac.cpp51
-rw-r--r--indra/llvfs/lldir_mac.h6
-rw-r--r--indra/llvfs/lldir_solaris.cpp10
-rw-r--r--indra/llvfs/lldir_solaris.h3
-rw-r--r--indra/llvfs/lldir_win32.cpp34
-rw-r--r--indra/llvfs/lldir_win32.h6
-rw-r--r--indra/llvfs/lllfsthread.h2
-rwxr-xr-xindra/llvfs/llpidlock.cpp7
-rwxr-xr-xindra/llvfs/llpidlock.h7
-rw-r--r--indra/llvfs/llvfile.cpp6
-rw-r--r--indra/llvfs/llvfs.cpp2
-rw-r--r--indra/llwindow/CMakeLists.txt21
-rw-r--r--indra/llwindow/lldxhardware.cpp1
-rw-r--r--indra/llwindow/llkeyboard.cpp2
-rw-r--r--indra/llwindow/llkeyboardmacosx.cpp2
-rw-r--r--indra/llwindow/llkeyboardsdl.cpp2
-rw-r--r--indra/llwindow/llkeyboardwin32.cpp10
-rw-r--r--indra/llwindow/llpreeditor.h2
-rw-r--r--indra/llwindow/llwindow.cpp233
-rw-r--r--indra/llwindow/llwindow.h83
-rw-r--r--indra/llwindow/llwindowcallbacks.cpp201
-rw-r--r--indra/llwindow/llwindowcallbacks.h85
-rw-r--r--indra/llwindow/llwindowheadless.cpp6
-rw-r--r--indra/llwindow/llwindowheadless.h9
-rw-r--r--indra/llwindow/llwindowmacosx.cpp27
-rw-r--r--indra/llwindow/llwindowmacosx.h6
-rw-r--r--indra/llwindow/llwindowmesaheadless.cpp5
-rw-r--r--indra/llwindow/llwindowmesaheadless.h3
-rw-r--r--indra/llwindow/llwindowsdl.cpp27
-rw-r--r--indra/llwindow/llwindowsdl.h6
-rw-r--r--indra/llwindow/llwindowwin32.cpp141
-rw-r--r--indra/llwindow/llwindowwin32.h4
-rw-r--r--indra/llxml/CMakeLists.txt3
-rw-r--r--indra/llxml/llcontrol.cpp711
-rw-r--r--indra/llxml/llcontrol.h289
-rw-r--r--indra/llxml/llcontrolgroupreader.h73
-rw-r--r--indra/llxml/llxmlnode.cpp288
-rw-r--r--indra/llxml/llxmlnode.h33
-rw-r--r--indra/llxuixml/CMakeLists.txt45
-rw-r--r--indra/llxuixml/llinitparam.cpp524
-rw-r--r--indra/llxuixml/llinitparam.h1823
-rw-r--r--indra/llxuixml/llregistry.h347
-rw-r--r--indra/llxuixml/lltrans.cpp196
-rw-r--r--indra/llxuixml/lltrans.h119
-rw-r--r--indra/llxuixml/lluicolor.cpp71
-rw-r--r--indra/llxuixml/lluicolor.h45
-rw-r--r--indra/llxuixml/llxuiparser.cpp968
-rw-r--r--indra/llxuixml/llxuiparser.h174
-rw-r--r--indra/lscript/lscript_compile/lscript_tree.cpp18
-rw-r--r--indra/lscript/lscript_execute.h2
-rw-r--r--indra/lscript/lscript_execute/lscript_readlso.cpp4
-rw-r--r--indra/lscript/lscript_library.h8
-rw-r--r--indra/lscript/lscript_library/lscript_library.cpp782
-rw-r--r--indra/media_plugins/CMakeLists.txt11
-rw-r--r--indra/media_plugins/base/CMakeLists.txt41
-rw-r--r--indra/media_plugins/base/media_plugin_base.cpp154
-rw-r--r--indra/media_plugins/base/media_plugin_base.exp1
-rw-r--r--indra/media_plugins/base/media_plugin_base.h111
-rw-r--r--indra/media_plugins/gstreamer010/CMakeLists.txt71
-rw-r--r--indra/media_plugins/gstreamer010/llmediaimplgstreamer.h57
-rw-r--r--indra/media_plugins/gstreamer010/llmediaimplgstreamer_syms.cpp171
-rw-r--r--indra/media_plugins/gstreamer010/llmediaimplgstreamer_syms.h78
-rw-r--r--indra/media_plugins/gstreamer010/llmediaimplgstreamer_syms_raw.inc51
-rw-r--r--indra/media_plugins/gstreamer010/llmediaimplgstreamer_syms_rawv.inc5
-rw-r--r--indra/media_plugins/gstreamer010/llmediaimplgstreamertriviallogging.h53
-rw-r--r--indra/media_plugins/gstreamer010/llmediaimplgstreamervidplug.cpp532
-rw-r--r--indra/media_plugins/gstreamer010/llmediaimplgstreamervidplug.h109
-rw-r--r--indra/media_plugins/gstreamer010/media_plugin_gstreamer010.cpp1204
-rw-r--r--indra/media_plugins/quicktime/CMakeLists.txt83
-rw-r--r--indra/media_plugins/quicktime/media_plugin_quicktime.cpp984
-rw-r--r--indra/media_plugins/webkit/CMakeLists.txt74
-rw-r--r--indra/media_plugins/webkit/media_plugin_webkit.cpp792
-rw-r--r--indra/newview/CMakeLists.txt416
-rw-r--r--indra/newview/English.lproj/InfoPlist.strings4
-rw-r--r--indra/newview/Info-SecondLife.plist2
-rw-r--r--indra/newview/app_settings/cmd_line.xml58
-rw-r--r--indra/newview/app_settings/foldertypes.xml74
-rw-r--r--indra/newview/app_settings/ignorable_dialogs.xml291
-rw-r--r--indra/newview/app_settings/settings.xml3866
-rw-r--r--indra/newview/app_settings/settings_files.xml61
-rw-r--r--indra/newview/app_settings/settings_per_account.xml23
-rw-r--r--indra/newview/app_settings/std_bump.ini30
-rw-r--r--indra/newview/build_win32_appConfig.py58
-rw-r--r--indra/newview/character/avatar_lad.xml109
-rw-r--r--indra/newview/character/checkerboard.tgabin0 -> 16428 bytes
-rwxr-xr-xindra/newview/character/invisible_head.tgabin0 -> 140793 bytes
-rw-r--r--indra/newview/gpu_table.txt8
-rw-r--r--indra/newview/installers/windows/installer_template.nsi3
-rw-r--r--indra/newview/linux_tools/client-readme.txt10
-rwxr-xr-xindra/newview/linux_tools/handle_secondlifeprotocol.sh2
-rwxr-xr-xindra/newview/linux_tools/install.sh106
-rwxr-xr-xindra/newview/linux_tools/refresh_desktop_app_entry.sh36
-rwxr-xr-xindra/newview/linux_tools/register_secondlifeprotocol.sh4
-rwxr-xr-xindra/newview/linux_tools/wrapper.sh8
-rw-r--r--indra/newview/llagent.cpp1949
-rw-r--r--indra/newview/llagent.h1682
-rw-r--r--indra/newview/llagentaccess.cpp52
-rw-r--r--indra/newview/llagentaccess.h32
-rw-r--r--indra/newview/llagentlanguage.h2
-rw-r--r--indra/newview/llagentpilot.cpp9
-rw-r--r--indra/newview/llagentpilot.h1
-rw-r--r--indra/newview/llagentui.cpp179
-rw-r--r--indra/newview/llagentui.h57
-rw-r--r--indra/newview/llagentwearables.cpp1910
-rw-r--r--indra/newview/llagentwearables.h253
-rw-r--r--indra/newview/llappviewer.cpp664
-rw-r--r--indra/newview/llappviewer.h44
-rw-r--r--indra/newview/llappviewerlinux.cpp4
-rw-r--r--indra/newview/llappviewermacosx.cpp6
-rw-r--r--indra/newview/llappviewerwin32.cpp24
-rw-r--r--indra/newview/llassetuploadresponders.cpp259
-rw-r--r--indra/newview/llassetuploadresponders.h1
-rw-r--r--indra/newview/llaudiosourcevo.h2
-rw-r--r--indra/newview/llavataractions.cpp291
-rw-r--r--indra/newview/llavataractions.h93
-rw-r--r--indra/newview/llavatariconctrl.cpp294
-rw-r--r--indra/newview/llavatariconctrl.h100
-rw-r--r--indra/newview/llavatarlist.cpp291
-rw-r--r--indra/newview/llavatarlist.h78
-rw-r--r--indra/newview/llavatarlistitem.cpp274
-rw-r--r--indra/newview/llavatarlistitem.h104
-rw-r--r--indra/newview/llavatarpropertiesprocessor.cpp442
-rw-r--r--indra/newview/llavatarpropertiesprocessor.h208
-rw-r--r--indra/newview/llbottomtray.cpp191
-rw-r--r--indra/newview/llbottomtray.h91
-rw-r--r--indra/newview/llbreadcrumbview.cpp37
-rw-r--r--indra/newview/llbreadcrumbview.h36
-rw-r--r--indra/newview/llcallingcard.cpp44
-rw-r--r--indra/newview/llcallingcard.h14
-rw-r--r--indra/newview/llcapabilitylistener.cpp1
-rw-r--r--indra/newview/llcapabilitylistener.h1
-rw-r--r--indra/newview/llcaphttpsender.cpp3
-rw-r--r--indra/newview/llchannelmanager.cpp229
-rw-r--r--indra/newview/llchannelmanager.h124
-rw-r--r--indra/newview/llchatbar.cpp180
-rw-r--r--indra/newview/llchatbar.h5
-rw-r--r--indra/newview/llchatitemscontainerctrl.cpp554
-rw-r--r--indra/newview/llchatitemscontainerctrl.h154
-rw-r--r--indra/newview/llchatmsgbox.cpp389
-rw-r--r--indra/newview/llchatmsgbox.h160
-rw-r--r--indra/newview/llchiclet.cpp1184
-rw-r--r--indra/newview/llchiclet.h730
-rw-r--r--indra/newview/llclassifiedstatsresponder.cpp1
-rw-r--r--indra/newview/llclassifiedstatsresponder.h1
-rw-r--r--indra/newview/llcloud.cpp1
-rw-r--r--indra/newview/llcloud.h2
-rw-r--r--indra/newview/llcolorswatch.cpp158
-rw-r--r--indra/newview/llcolorswatch.h61
-rw-r--r--indra/newview/llcommandhandler.cpp6
-rw-r--r--indra/newview/llcommandhandler.h10
-rw-r--r--indra/newview/llcompilequeue.cpp257
-rw-r--r--indra/newview/llcompilequeue.h65
-rw-r--r--indra/newview/llcurrencyuimanager.cpp4
-rw-r--r--indra/newview/lldebugmessagebox.cpp136
-rw-r--r--indra/newview/lldebugmessagebox.h5
-rw-r--r--indra/newview/lldebugview.cpp63
-rw-r--r--indra/newview/lldebugview.h14
-rw-r--r--indra/newview/lldirpicker.cpp1
-rw-r--r--indra/newview/lldrawable.cpp15
-rw-r--r--indra/newview/lldrawable.h12
-rw-r--r--indra/newview/lldrawpool.cpp19
-rw-r--r--indra/newview/lldrawpool.h22
-rw-r--r--indra/newview/lldrawpoolalpha.cpp19
-rw-r--r--indra/newview/lldrawpoolavatar.cpp47
-rw-r--r--indra/newview/lldrawpoolavatar.h2
-rw-r--r--indra/newview/lldrawpoolbump.cpp103
-rw-r--r--indra/newview/lldrawpoolbump.h16
-rw-r--r--indra/newview/lldrawpoolsimple.cpp29
-rw-r--r--indra/newview/lldrawpoolsky.cpp3
-rw-r--r--indra/newview/lldrawpoolterrain.cpp93
-rw-r--r--indra/newview/lldrawpoolterrain.h16
-rw-r--r--indra/newview/lldrawpooltree.cpp26
-rw-r--r--indra/newview/lldrawpooltree.h8
-rw-r--r--indra/newview/lldrawpoolwater.cpp40
-rw-r--r--indra/newview/lldrawpoolwater.h10
-rw-r--r--indra/newview/lldrawpoolwlsky.cpp23
-rw-r--r--indra/newview/lldrawpoolwlsky.h8
-rw-r--r--indra/newview/lldynamictexture.cpp117
-rw-r--r--indra/newview/lldynamictexture.h46
-rw-r--r--indra/newview/llemote.cpp1
-rw-r--r--indra/newview/lleventnotifier.cpp12
-rw-r--r--indra/newview/lleventpoll.h3
-rw-r--r--indra/newview/llface.cpp37
-rw-r--r--indra/newview/llface.h19
-rw-r--r--indra/newview/llfasttimerview.cpp1138
-rw-r--r--indra/newview/llfasttimerview.h43
-rw-r--r--indra/newview/llfavoritesbar.cpp801
-rw-r--r--indra/newview/llfavoritesbar.h101
-rw-r--r--indra/newview/llfeaturemanager.cpp3
-rw-r--r--indra/newview/llfeaturemanager.h1
-rw-r--r--indra/newview/llfilepicker.cpp8
-rw-r--r--indra/newview/llfirstuse.cpp70
-rw-r--r--indra/newview/llfirstuse.h2
-rw-r--r--indra/newview/llflexibleobject.cpp6
-rw-r--r--indra/newview/llflexibleobject.h1
-rw-r--r--indra/newview/llfloaterabout.cpp171
-rw-r--r--indra/newview/llfloaterabout.h13
-rw-r--r--indra/newview/llfloateranimpreview.cpp206
-rw-r--r--indra/newview/llfloateranimpreview.h21
-rw-r--r--indra/newview/llfloaterauction.cpp45
-rw-r--r--indra/newview/llfloaterauction.h19
-rw-r--r--indra/newview/llfloateravatarpicker.cpp158
-rw-r--r--indra/newview/llfloateravatarpicker.h15
-rw-r--r--indra/newview/llfloateravatartextures.cpp25
-rw-r--r--indra/newview/llfloateravatartextures.h4
-rw-r--r--indra/newview/llfloaterbeacons.cpp48
-rw-r--r--indra/newview/llfloaterbeacons.h10
-rw-r--r--indra/newview/llfloaterbuildoptions.cpp48
-rw-r--r--indra/newview/llfloaterbuildoptions.h15
-rw-r--r--indra/newview/llfloaterbulkpermission.cpp61
-rw-r--r--indra/newview/llfloaterbulkpermission.h19
-rw-r--r--indra/newview/llfloaterbump.cpp62
-rw-r--r--indra/newview/llfloaterbump.h15
-rw-r--r--indra/newview/llfloaterbuy.cpp119
-rw-r--r--indra/newview/llfloaterbuy.h15
-rw-r--r--indra/newview/llfloaterbuycontents.cpp88
-rw-r--r--indra/newview/llfloaterbuycontents.h15
-rw-r--r--indra/newview/llfloaterbuycurrency.cpp106
-rw-r--r--indra/newview/llfloaterbuycurrency.h4
-rw-r--r--indra/newview/llfloaterbuyland.cpp284
-rw-r--r--indra/newview/llfloaterbuyland.h5
-rw-r--r--indra/newview/llfloatercamera.cpp335
-rw-r--r--indra/newview/llfloatercamera.h87
-rw-r--r--indra/newview/llfloaterchat.cpp230
-rw-r--r--indra/newview/llfloaterchat.h39
-rw-r--r--indra/newview/llfloaterchatterbox.cpp136
-rw-r--r--indra/newview/llfloaterchatterbox.h104
-rw-r--r--indra/newview/llfloatercolorpicker.cpp264
-rw-r--r--indra/newview/llfloatercolorpicker.h12
-rw-r--r--indra/newview/llfloaterdaycycle.cpp200
-rw-r--r--indra/newview/llfloaterdaycycle.h56
-rw-r--r--indra/newview/llfloaterenvsettings.cpp185
-rw-r--r--indra/newview/llfloaterenvsettings.h41
-rw-r--r--indra/newview/llfloaterevent.cpp131
-rw-r--r--indra/newview/llfloaterfonttest.cpp25
-rw-r--r--indra/newview/llfloaterfonttest.h15
-rw-r--r--indra/newview/llfloaterfriends.cpp243
-rw-r--r--indra/newview/llfloaterfriends.h16
-rw-r--r--indra/newview/llfloatergesture.cpp228
-rw-r--r--indra/newview/llfloatergesture.h22
-rw-r--r--indra/newview/llfloatergodtools.cpp449
-rw-r--r--indra/newview/llfloatergodtools.h73
-rw-r--r--indra/newview/llfloatergroupinvite.cpp41
-rw-r--r--indra/newview/llfloatergroupinvite.h5
-rw-r--r--indra/newview/llfloatergroups.cpp156
-rw-r--r--indra/newview/llfloatergroups.h16
-rw-r--r--indra/newview/llfloaterhandler.cpp6
-rw-r--r--indra/newview/llfloaterhandler.h2
-rw-r--r--indra/newview/llfloaterhardwaresettings.cpp79
-rw-r--r--indra/newview/llfloaterhardwaresettings.h20
-rw-r--r--indra/newview/llfloaterhud.cpp83
-rw-r--r--indra/newview/llfloaterhud.h16
-rw-r--r--indra/newview/llfloaterimagepreview.cpp43
-rw-r--r--indra/newview/llfloaterimagepreview.h24
-rw-r--r--indra/newview/llfloaterinspect.cpp121
-rw-r--r--indra/newview/llfloaterinspect.h24
-rw-r--r--indra/newview/llfloaterinventory.cpp1885
-rw-r--r--indra/newview/llfloaterinventory.h362
-rw-r--r--indra/newview/llfloaterjoystick.cpp60
-rw-r--r--indra/newview/llfloaterjoystick.h15
-rw-r--r--indra/newview/llfloaterlagmeter.cpp126
-rw-r--r--indra/newview/llfloaterlagmeter.h12
-rw-r--r--indra/newview/llfloaterland.cpp264
-rw-r--r--indra/newview/llfloaterland.h28
-rw-r--r--indra/newview/llfloaterlandholdings.cpp165
-rw-r--r--indra/newview/llfloaterlandholdings.h14
-rw-r--r--indra/newview/llfloatermap.cpp178
-rw-r--r--indra/newview/llfloatermap.h44
-rw-r--r--indra/newview/llfloatermediabrowser.cpp398
-rw-r--r--indra/newview/llfloatermediabrowser.h99
-rw-r--r--indra/newview/llfloatermemleak.cpp162
-rw-r--r--indra/newview/llfloatermemleak.h31
-rw-r--r--indra/newview/llfloaternamedesc.cpp78
-rw-r--r--indra/newview/llfloaternamedesc.h19
-rw-r--r--indra/newview/llfloaternotificationsconsole.cpp59
-rw-r--r--indra/newview/llfloaternotificationsconsole.h12
-rw-r--r--indra/newview/llfloateropenobject.cpp102
-rw-r--r--indra/newview/llfloateropenobject.h21
-rw-r--r--indra/newview/llfloaterparcel.cpp60
-rw-r--r--indra/newview/llfloaterparcel.h8
-rw-r--r--indra/newview/llfloaterperms.cpp51
-rw-r--r--indra/newview/llfloaterperms.h14
-rw-r--r--indra/newview/llfloaterpostcard.cpp85
-rw-r--r--indra/newview/llfloaterpostcard.h15
-rw-r--r--indra/newview/llfloaterpostprocess.cpp83
-rw-r--r--indra/newview/llfloaterpostprocess.h24
-rw-r--r--indra/newview/llfloaterpreference.cpp1695
-rw-r--r--indra/newview/llfloaterpreference.h160
-rw-r--r--indra/newview/llfloaterproperties.cpp310
-rw-r--r--indra/newview/llfloaterproperties.h46
-rw-r--r--indra/newview/llfloaterregioninfo.cpp169
-rw-r--r--indra/newview/llfloaterregioninfo.h28
-rw-r--r--indra/newview/llfloaterreporter.cpp441
-rw-r--r--indra/newview/llfloaterreporter.h19
-rw-r--r--indra/newview/llfloaterscriptdebug.cpp155
-rw-r--r--indra/newview/llfloaterscriptdebug.h25
-rw-r--r--indra/newview/llfloatersellland.cpp113
-rw-r--r--indra/newview/llfloatersellland.h6
-rw-r--r--indra/newview/llfloatersettingsdebug.cpp143
-rw-r--r--indra/newview/llfloatersettingsdebug.h24
-rw-r--r--indra/newview/llfloatersnapshot.cpp188
-rw-r--r--indra/newview/llfloatersnapshot.h28
-rw-r--r--indra/newview/llfloatertelehub.cpp118
-rw-r--r--indra/newview/llfloatertelehub.h23
-rw-r--r--indra/newview/llfloatertestlistview.cpp77
-rw-r--r--indra/newview/llfloatertestlistview.h64
-rw-r--r--indra/newview/llfloatertools.cpp538
-rw-r--r--indra/newview/llfloatertools.h51
-rw-r--r--indra/newview/llfloatertopobjects.cpp164
-rw-r--r--indra/newview/llfloatertopobjects.h31
-rw-r--r--indra/newview/llfloatertos.cpp103
-rw-r--r--indra/newview/llfloatertos.h25
-rw-r--r--indra/newview/llfloateruipreview.cpp1642
-rw-r--r--indra/newview/llfloateruipreview.h174
-rw-r--r--indra/newview/llfloaterurldisplay.cpp4
-rw-r--r--indra/newview/llfloaterurldisplay.h8
-rw-r--r--indra/newview/llfloaterurlentry.cpp38
-rw-r--r--indra/newview/llfloaterurlentry.h6
-rw-r--r--indra/newview/llfloatervoicedevicesettings.cpp35
-rw-r--r--indra/newview/llfloatervoicedevicesettings.h25
-rw-r--r--indra/newview/llfloaterwater.cpp246
-rw-r--r--indra/newview/llfloaterwater.h79
-rw-r--r--indra/newview/llfloaterwindlight.cpp357
-rw-r--r--indra/newview/llfloaterwindlight.h67
-rw-r--r--indra/newview/llfloaterworldmap.cpp447
-rw-r--r--indra/newview/llfloaterworldmap.h58
-rw-r--r--indra/newview/llfolderview.cpp3543
-rw-r--r--indra/newview/llfolderview.h741
-rw-r--r--indra/newview/llfoldervieweventlistener.h101
-rw-r--r--indra/newview/llfolderviewitem.cpp2489
-rw-r--r--indra/newview/llfolderviewitem.h528
-rw-r--r--indra/newview/llfriendcard.cpp425
-rw-r--r--indra/newview/llfriendcard.h143
-rw-r--r--indra/newview/llgesturemgr.cpp65
-rw-r--r--indra/newview/llgesturemgr.h9
-rw-r--r--indra/newview/llglsandbox.cpp124
-rw-r--r--indra/newview/llgroupactions.cpp283
-rw-r--r--indra/newview/llgroupactions.h103
-rw-r--r--indra/newview/llgrouplist.cpp90
-rw-r--r--indra/newview/llgrouplist.h54
-rw-r--r--indra/newview/llgroupmgr.cpp19
-rw-r--r--indra/newview/llhomelocationresponder.cpp4
-rw-r--r--indra/newview/llhomelocationresponder.h2
-rw-r--r--indra/newview/llhudeffect.cpp1
-rw-r--r--indra/newview/llhudeffect.h3
-rw-r--r--indra/newview/llhudeffectbeam.cpp1
-rw-r--r--indra/newview/llhudeffectlookat.cpp4
-rw-r--r--indra/newview/llhudeffectpointat.h1
-rw-r--r--indra/newview/llhudeffecttrail.cpp3
-rw-r--r--indra/newview/llhudicon.cpp10
-rw-r--r--indra/newview/llhudicon.h6
-rw-r--r--indra/newview/llhudmanager.cpp8
-rw-r--r--indra/newview/llhudmanager.h2
-rw-r--r--indra/newview/llhudobject.cpp4
-rw-r--r--indra/newview/llhudobject.h2
-rw-r--r--indra/newview/llhudrender.cpp28
-rw-r--r--indra/newview/llhudrender.h2
-rw-r--r--indra/newview/llhudtext.cpp60
-rw-r--r--indra/newview/llhudtext.h2
-rw-r--r--indra/newview/llhudview.cpp18
-rw-r--r--indra/newview/llhudview.h2
-rw-r--r--indra/newview/llimhandler.cpp127
-rw-r--r--indra/newview/llimpanel.cpp979
-rw-r--r--indra/newview/llimpanel.h96
-rw-r--r--indra/newview/llimview.cpp1019
-rw-r--r--indra/newview/llimview.h104
-rw-r--r--indra/newview/llinspectavatar.cpp127
-rw-r--r--indra/newview/llinspectavatar.h80
-rw-r--r--indra/newview/llinventorybridge.cpp2452
-rw-r--r--indra/newview/llinventorybridge.h351
-rw-r--r--indra/newview/llinventoryfilter.cpp664
-rw-r--r--indra/newview/llinventoryfilter.h151
-rw-r--r--indra/newview/llinventorymodel.cpp381
-rw-r--r--indra/newview/llinventorymodel.h100
-rw-r--r--indra/newview/lljoystickbutton.cpp193
-rw-r--r--indra/newview/lljoystickbutton.h78
-rw-r--r--indra/newview/lllandmarkactions.cpp299
-rw-r--r--indra/newview/lllandmarkactions.h116
-rw-r--r--indra/newview/lllandmarklist.cpp61
-rw-r--r--indra/newview/lllandmarklist.h13
-rw-r--r--indra/newview/lllistbrowser.cpp37
-rw-r--r--indra/newview/lllistbrowser.h36
-rw-r--r--indra/newview/lllistview.cpp73
-rw-r--r--indra/newview/lllistview.h66
-rw-r--r--indra/newview/lllocaltextureobject.cpp149
-rw-r--r--indra/newview/lllocaltextureobject.h85
-rw-r--r--indra/newview/lllocationhistory.cpp204
-rw-r--r--indra/newview/lllocationhistory.h76
-rw-r--r--indra/newview/lllocationinputctrl.cpp688
-rw-r--r--indra/newview/lllocationinputctrl.h140
-rw-r--r--indra/newview/lllogchat.cpp29
-rw-r--r--indra/newview/llloginhandler.cpp12
-rw-r--r--indra/newview/llloginhandler.h2
-rw-r--r--indra/newview/lllookshistorypanel.h72
-rw-r--r--indra/newview/llmanip.cpp59
-rw-r--r--indra/newview/llmaniprotate.cpp48
-rw-r--r--indra/newview/llmanipscale.cpp14
-rw-r--r--indra/newview/llmaniptranslate.cpp24
-rw-r--r--indra/newview/llmediactrl.cpp937
-rw-r--r--indra/newview/llmediactrl.h182
-rw-r--r--indra/newview/llmemoryview.cpp204
-rw-r--r--indra/newview/llmemoryview.h22
-rw-r--r--indra/newview/llmenucommands.cpp58
-rw-r--r--indra/newview/llmenucommands.h6
-rw-r--r--indra/newview/llmetricperformancetester.cpp258
-rw-r--r--indra/newview/llmetricperformancetester.h159
-rw-r--r--indra/newview/llmimetypes.cpp24
-rw-r--r--indra/newview/llmimetypes.h6
-rw-r--r--indra/newview/llmorphview.cpp14
-rw-r--r--indra/newview/llmorphview.h10
-rw-r--r--indra/newview/llmoveview.cpp540
-rw-r--r--indra/newview/llmoveview.h112
-rw-r--r--indra/newview/llmutelist.cpp33
-rw-r--r--indra/newview/llnamebox.cpp18
-rw-r--r--indra/newview/llnamebox.h17
-rw-r--r--indra/newview/llnameeditor.cpp63
-rw-r--r--indra/newview/llnameeditor.h31
-rw-r--r--indra/newview/llnamelistctrl.cpp329
-rw-r--r--indra/newview/llnamelistctrl.h76
-rw-r--r--indra/newview/llnavigationbar.cpp648
-rw-r--r--indra/newview/llnavigationbar.h111
-rw-r--r--indra/newview/llnearbychat.cpp486
-rw-r--r--indra/newview/llnearbychat.h97
-rw-r--r--indra/newview/llnearbychatbar.cpp639
-rw-r--r--indra/newview/llnearbychatbar.h118
-rw-r--r--indra/newview/llnearbychathandler.cpp129
-rw-r--r--indra/newview/llnearbychathandler.h59
-rw-r--r--indra/newview/llnetmap.cpp425
-rw-r--r--indra/newview/llnetmap.h110
-rw-r--r--indra/newview/llnotificationalerthandler.cpp117
-rw-r--r--indra/newview/llnotificationgrouphandler.cpp118
-rw-r--r--indra/newview/llnotificationhandler.h199
-rw-r--r--indra/newview/llnotificationmanager.cpp130
-rw-r--r--indra/newview/llnotificationmanager.h79
-rw-r--r--indra/newview/lloutputmonitorctrl.cpp207
-rw-r--r--indra/newview/lloutputmonitorctrl.h103
-rw-r--r--indra/newview/lloverlaybar.cpp50
-rw-r--r--indra/newview/lloverlaybar.h2
-rw-r--r--indra/newview/llpanelappearancetab.h65
-rw-r--r--indra/newview/llpanelavatar.cpp2299
-rw-r--r--indra/newview/llpanelavatar.h440
-rw-r--r--indra/newview/llpanelavatartag.cpp129
-rw-r--r--indra/newview/llpanelavatartag.h93
-rw-r--r--indra/newview/llpanelclassified.cpp102
-rw-r--r--indra/newview/llpanelcontents.cpp60
-rw-r--r--indra/newview/llpanelcontents.h2
-rw-r--r--indra/newview/llpanelface.cpp102
-rw-r--r--indra/newview/llpanelface.h23
-rw-r--r--indra/newview/llpanelgroup.cpp660
-rw-r--r--indra/newview/llpanelgroup.h110
-rw-r--r--indra/newview/llpanelgroupgeneral.cpp273
-rw-r--r--indra/newview/llpanelgroupgeneral.h15
-rw-r--r--indra/newview/llpanelgroupinvite.cpp51
-rw-r--r--indra/newview/llpanelgroupinvite.h2
-rw-r--r--indra/newview/llpanelgrouplandmoney.cpp412
-rw-r--r--indra/newview/llpanelgrouplandmoney.h10
-rw-r--r--indra/newview/llpanelgroupnotices.cpp173
-rw-r--r--indra/newview/llpanelgroupnotices.h9
-rw-r--r--indra/newview/llpanelgrouproles.cpp325
-rw-r--r--indra/newview/llpanelgrouproles.h51
-rw-r--r--indra/newview/llpanelimcontrolpanel.cpp113
-rw-r--r--indra/newview/llpanelimcontrolpanel.h87
-rw-r--r--indra/newview/llpanelland.cpp7
-rw-r--r--indra/newview/llpanelland.h2
-rw-r--r--indra/newview/llpanellandaudio.cpp192
-rw-r--r--indra/newview/llpanellandaudio.h62
-rw-r--r--indra/newview/llpanellandmarks.cpp280
-rw-r--r--indra/newview/llpanellandmarks.h66
-rw-r--r--indra/newview/llpanellandmedia.cpp152
-rw-r--r--indra/newview/llpanellandmedia.h23
-rw-r--r--indra/newview/llpanellogin.cpp168
-rw-r--r--indra/newview/llpanellogin.h15
-rw-r--r--indra/newview/llpanelobject.cpp79
-rw-r--r--indra/newview/llpanelobject.h14
-rw-r--r--indra/newview/llpanelpeople.cpp952
-rw-r--r--indra/newview/llpanelpeople.h149
-rw-r--r--indra/newview/llpanelpermissions.cpp182
-rw-r--r--indra/newview/llpanelpermissions.h14
-rw-r--r--indra/newview/llpanelpick.cpp668
-rw-r--r--indra/newview/llpanelpick.h127
-rw-r--r--indra/newview/llpanelpicks.cpp603
-rw-r--r--indra/newview/llpanelpicks.h185
-rw-r--r--indra/newview/llpanelplace.cpp291
-rw-r--r--indra/newview/llpanelplace.h13
-rw-r--r--indra/newview/llpanelplaceinfo.cpp584
-rw-r--r--indra/newview/llpanelplaceinfo.h150
-rw-r--r--indra/newview/llpanelplaces.cpp827
-rw-r--r--indra/newview/llpanelplaces.h128
-rw-r--r--indra/newview/llpanelplacestab.cpp87
-rw-r--r--indra/newview/llpanelplacestab.h66
-rw-r--r--indra/newview/llpanelprofile.cpp178
-rw-r--r--indra/newview/llpanelprofile.h88
-rw-r--r--indra/newview/llpanelprofileview.cpp96
-rw-r--r--indra/newview/llpanelprofileview.h68
-rw-r--r--indra/newview/llpanelteleporthistory.cpp234
-rw-r--r--indra/newview/llpanelteleporthistory.h73
-rw-r--r--indra/newview/llpanelvolume.cpp29
-rw-r--r--indra/newview/llpanelvolume.h10
-rw-r--r--indra/newview/llparcelselection.h3
-rw-r--r--indra/newview/llpreview.cpp315
-rw-r--r--indra/newview/llpreview.h84
-rw-r--r--indra/newview/llpreviewanim.cpp77
-rw-r--r--indra/newview/llpreviewanim.h13
-rw-r--r--indra/newview/llpreviewgesture.cpp287
-rw-r--r--indra/newview/llpreviewgesture.h34
-rw-r--r--indra/newview/llpreviewnotecard.cpp173
-rw-r--r--indra/newview/llpreviewnotecard.h20
-rw-r--r--indra/newview/llpreviewscript.cpp847
-rw-r--r--indra/newview/llpreviewscript.h96
-rw-r--r--indra/newview/llpreviewsound.cpp40
-rw-r--r--indra/newview/llpreviewsound.h7
-rw-r--r--indra/newview/llpreviewtexture.cpp207
-rw-r--r--indra/newview/llpreviewtexture.h31
-rw-r--r--indra/newview/llprogressview.cpp18
-rw-r--r--indra/newview/llprogressview.h2
-rw-r--r--indra/newview/llrecentpeople.cpp69
-rw-r--r--indra/newview/llrecentpeople.h101
-rw-r--r--indra/newview/llremoteparcelrequest.cpp128
-rw-r--r--indra/newview/llremoteparcelrequest.h64
-rw-r--r--indra/newview/llrootview.h51
-rw-r--r--indra/newview/llsavedsettingsglue.cpp30
-rw-r--r--indra/newview/llsavedsettingsglue.h10
-rw-r--r--indra/newview/llscreenchannel.cpp551
-rw-r--r--indra/newview/llscreenchannel.h216
-rw-r--r--indra/newview/llselectmgr.cpp208
-rw-r--r--indra/newview/llselectmgr.h21
-rw-r--r--indra/newview/llsidetray.cpp687
-rw-r--r--indra/newview/llsidetray.h252
-rw-r--r--indra/newview/llsidetraypanelcontainer.cpp93
-rw-r--r--indra/newview/llsidetraypanelcontainer.h95
-rw-r--r--indra/newview/llsky.cpp1
-rw-r--r--indra/newview/llslurl.cpp145
-rw-r--r--indra/newview/llslurl.h103
-rw-r--r--indra/newview/llspatialpartition.cpp35
-rw-r--r--indra/newview/llspatialpartition.h9
-rw-r--r--indra/newview/llsplitbutton.cpp275
-rw-r--r--indra/newview/llsplitbutton.h112
-rw-r--r--indra/newview/llsprite.cpp2
-rw-r--r--indra/newview/llsprite.h4
-rw-r--r--indra/newview/llstartup.cpp597
-rw-r--r--indra/newview/llstartup.h8
-rw-r--r--indra/newview/llstatusbar.cpp592
-rw-r--r--indra/newview/llstatusbar.h49
-rw-r--r--indra/newview/llstylemap.cpp74
-rw-r--r--indra/newview/llstylemap.h16
-rw-r--r--indra/newview/llsurface.cpp30
-rw-r--r--indra/newview/llsurface.h11
-rw-r--r--indra/newview/llsurfacepatch.h2
-rw-r--r--indra/newview/llsyswellitem.cpp109
-rw-r--r--indra/newview/llsyswellitem.h90
-rw-r--r--indra/newview/llsyswellwindow.cpp213
-rw-r--r--indra/newview/llsyswellwindow.h92
-rw-r--r--indra/newview/llteleporthistory.cpp199
-rw-r--r--indra/newview/llteleporthistory.h237
-rw-r--r--indra/newview/llteleporthistorystorage.cpp164
-rw-r--r--indra/newview/llteleporthistorystorage.h108
-rw-r--r--indra/newview/lltexglobalcolor.cpp150
-rw-r--r--indra/newview/lltexglobalcolor.h86
-rw-r--r--indra/newview/lltexlayer.cpp1637
-rw-r--r--indra/newview/lltexlayer.h581
-rw-r--r--indra/newview/lltexlayerparams.cpp541
-rw-r--r--indra/newview/lltexlayerparams.h180
-rw-r--r--indra/newview/lltexturecache.cpp2
-rw-r--r--indra/newview/lltexturectrl.cpp578
-rw-r--r--indra/newview/lltexturectrl.h76
-rw-r--r--indra/newview/lltexturefetch.cpp29
-rw-r--r--indra/newview/lltexturefetch.h3
-rw-r--r--indra/newview/lltextureview.cpp145
-rw-r--r--indra/newview/lltextureview.h14
-rw-r--r--indra/newview/lltoast.cpp294
-rw-r--r--indra/newview/lltoast.h170
-rw-r--r--indra/newview/lltoastalertpanel.cpp474
-rw-r--r--indra/newview/lltoastalertpanel.h122
-rw-r--r--indra/newview/lltoastgroupnotifypanel.cpp209
-rw-r--r--indra/newview/lltoastgroupnotifypanel.h83
-rw-r--r--indra/newview/lltoastimpanel.cpp94
-rw-r--r--indra/newview/lltoastimpanel.h79
-rw-r--r--indra/newview/lltoastnotifypanel.cpp432
-rw-r--r--indra/newview/lltoastnotifypanel.h86
-rw-r--r--indra/newview/lltoastpanel.cpp53
-rw-r--r--indra/newview/lltoastpanel.h58
-rw-r--r--indra/newview/lltool.cpp2
-rw-r--r--indra/newview/lltoolbar.cpp292
-rw-r--r--indra/newview/lltoolbar.h21
-rw-r--r--indra/newview/lltoolbrush.cpp2
-rw-r--r--indra/newview/lltoolcomp.cpp13
-rw-r--r--indra/newview/lltoolcomp.h1
-rw-r--r--indra/newview/lltooldraganddrop.cpp85
-rw-r--r--indra/newview/lltoolface.cpp8
-rw-r--r--indra/newview/lltoolfocus.cpp16
-rw-r--r--indra/newview/lltoolgrab.cpp19
-rw-r--r--indra/newview/lltoolgrab.h2
-rw-r--r--indra/newview/lltoolgun.cpp18
-rw-r--r--indra/newview/lltoolgun.h2
-rw-r--r--indra/newview/lltoolindividual.cpp5
-rw-r--r--indra/newview/lltoolmgr.cpp110
-rw-r--r--indra/newview/lltoolmgr.h8
-rw-r--r--indra/newview/lltoolmorph.cpp35
-rw-r--r--indra/newview/lltoolmorph.h17
-rw-r--r--indra/newview/lltoolobjpicker.cpp5
-rw-r--r--indra/newview/lltoolpie.cpp478
-rw-r--r--indra/newview/lltoolpie.h11
-rw-r--r--indra/newview/lltoolpipette.cpp24
-rw-r--r--indra/newview/lltoolpipette.h13
-rw-r--r--indra/newview/lltoolplacer.cpp102
-rw-r--r--indra/newview/lltoolplacer.h39
-rw-r--r--indra/newview/lltoolselect.cpp8
-rw-r--r--indra/newview/lltoolselectland.cpp10
-rw-r--r--indra/newview/lltoolselectrect.cpp3
-rw-r--r--indra/newview/lltoolview.cpp4
-rw-r--r--indra/newview/lltracker.cpp23
-rw-r--r--indra/newview/lltracker.h2
-rw-r--r--indra/newview/lluploaddialog.cpp17
-rw-r--r--indra/newview/llurldispatcher.cpp181
-rw-r--r--indra/newview/llurldispatcher.h15
-rw-r--r--indra/newview/llurllineeditorctrl.cpp97
-rw-r--r--indra/newview/llurllineeditorctrl.h100
-rw-r--r--indra/newview/llviewchildren.cpp8
-rw-r--r--indra/newview/llviewerassetstorage.h1
-rw-r--r--indra/newview/llvieweraudio.cpp3
-rw-r--r--indra/newview/llviewercamera.cpp122
-rw-r--r--indra/newview/llviewercamera.h4
-rw-r--r--indra/newview/llviewercontrol.cpp394
-rw-r--r--indra/newview/llviewercontrol.h111
-rw-r--r--indra/newview/llviewerdisplay.cpp129
-rw-r--r--indra/newview/llviewerfloaterreg.cpp250
-rw-r--r--indra/newview/llviewerfloaterreg.h (renamed from indra/newview/llfloaterevent.h)33
-rw-r--r--indra/newview/llviewergesture.cpp8
-rw-r--r--indra/newview/llviewerinventory.cpp458
-rw-r--r--indra/newview/llviewerinventory.h45
-rw-r--r--indra/newview/llviewerjointattachment.h16
-rw-r--r--indra/newview/llviewerjointmesh.cpp22
-rw-r--r--indra/newview/llviewerjointmesh.h8
-rw-r--r--indra/newview/llviewerkeyboard.cpp65
-rw-r--r--indra/newview/llviewermedia.cpp1413
-rw-r--r--indra/newview/llviewermedia.h204
-rw-r--r--indra/newview/llviewermedia_streamingaudio.cpp167
-rw-r--r--indra/newview/llviewermedia_streamingaudio.h69
-rw-r--r--indra/newview/llviewermediafocus.cpp355
-rw-r--r--indra/newview/llviewermediafocus.h90
-rw-r--r--indra/newview/llviewermediaobserver.h71
-rw-r--r--indra/newview/llviewermenu.cpp5280
-rw-r--r--indra/newview/llviewermenu.h55
-rw-r--r--indra/newview/llviewermenufile.cpp134
-rw-r--r--indra/newview/llviewermessage.cpp381
-rw-r--r--indra/newview/llviewermessage.h7
-rw-r--r--indra/newview/llviewernetwork.cpp2
-rw-r--r--indra/newview/llviewerobject.cpp131
-rw-r--r--indra/newview/llviewerobject.h16
-rw-r--r--indra/newview/llviewerobjectlist.cpp37
-rw-r--r--indra/newview/llviewerobjectlist.h15
-rw-r--r--indra/newview/llviewerparcelmedia.cpp347
-rw-r--r--indra/newview/llviewerparcelmedia.h31
-rw-r--r--indra/newview/llviewerparcelmediaautoplay.cpp8
-rw-r--r--indra/newview/llviewerparcelmediaautoplay.h1
-rw-r--r--indra/newview/llviewerparcelmgr.cpp160
-rw-r--r--indra/newview/llviewerparcelmgr.h38
-rw-r--r--indra/newview/llviewerparceloverlay.cpp49
-rw-r--r--indra/newview/llviewerparceloverlay.h6
-rw-r--r--indra/newview/llviewerpartsim.cpp6
-rw-r--r--indra/newview/llviewerpartsim.h10
-rw-r--r--indra/newview/llviewerpartsource.cpp16
-rw-r--r--indra/newview/llviewerpartsource.h11
-rw-r--r--indra/newview/llviewerprecompiledheaders.h30
-rw-r--r--indra/newview/llviewerregion.cpp9
-rw-r--r--indra/newview/llviewerregion.h4
-rw-r--r--indra/newview/llviewerstats.cpp125
-rw-r--r--indra/newview/llviewerstats.h23
-rw-r--r--indra/newview/llviewertexteditor.cpp940
-rw-r--r--indra/newview/llviewertexteditor.h38
-rw-r--r--indra/newview/llviewertexture.cpp2386
-rw-r--r--indra/newview/llviewertexture.h672
-rw-r--r--indra/newview/llviewertexturelist.cpp1513
-rw-r--r--indra/newview/llviewertexturelist.h243
-rw-r--r--indra/newview/llviewervisualparam.cpp14
-rw-r--r--indra/newview/llviewervisualparam.h2
-rw-r--r--indra/newview/llviewerwindow.cpp1709
-rw-r--r--indra/newview/llviewerwindow.h72
-rw-r--r--indra/newview/llvlcomposition.cpp22
-rw-r--r--indra/newview/llvlcomposition.h6
-rw-r--r--indra/newview/llvlmanager.cpp1
-rw-r--r--indra/newview/llvoavatar.cpp3341
-rw-r--r--indra/newview/llvoavatar.h1328
-rw-r--r--indra/newview/llvoavatardefines.cpp265
-rw-r--r--indra/newview/llvoavatardefines.h183
-rw-r--r--indra/newview/llvoavatarself.cpp2044
-rw-r--r--indra/newview/llvoavatarself.h314
-rw-r--r--indra/newview/llvoclouds.cpp10
-rw-r--r--indra/newview/llvoclouds.h2
-rw-r--r--indra/newview/llvograss.cpp18
-rw-r--r--indra/newview/llvograss.h2
-rw-r--r--indra/newview/llvoground.cpp1
-rw-r--r--indra/newview/llvoground.h2
-rw-r--r--indra/newview/llvoiceclient.cpp165
-rw-r--r--indra/newview/llvoiceclient.h10
-rw-r--r--indra/newview/llvoicevisualizer.cpp33
-rw-r--r--indra/newview/llvoicevisualizer.h2
-rw-r--r--indra/newview/llvopartgroup.cpp10
-rw-r--r--indra/newview/llvosky.cpp41
-rw-r--r--indra/newview/llvosky.h16
-rw-r--r--indra/newview/llvosurfacepatch.cpp6
-rw-r--r--indra/newview/llvotextbubble.cpp11
-rw-r--r--indra/newview/llvotree.cpp12
-rw-r--r--indra/newview/llvotree.h6
-rw-r--r--indra/newview/llvotreenew.h4
-rw-r--r--indra/newview/llvovolume.cpp106
-rw-r--r--indra/newview/llvovolume.h10
-rw-r--r--indra/newview/llvowater.cpp7
-rw-r--r--indra/newview/llvowater.h2
-rw-r--r--indra/newview/llvowlsky.cpp4
-rw-r--r--indra/newview/llwatchdog.h3
-rw-r--r--indra/newview/llwaterparammanager.cpp10
-rw-r--r--indra/newview/llwaterparamset.cpp2
-rw-r--r--indra/newview/llwearable.cpp325
-rw-r--r--indra/newview/llwearable.h109
-rw-r--r--indra/newview/llwearablelist.cpp110
-rw-r--r--indra/newview/llwearablelist.h30
-rw-r--r--indra/newview/llweb.cpp36
-rw-r--r--indra/newview/llweb.h7
-rw-r--r--indra/newview/llwind.cpp1
-rw-r--r--indra/newview/llwldaycycle.cpp3
-rw-r--r--indra/newview/llwldaycycle.h2
-rw-r--r--indra/newview/llwlparammanager.cpp22
-rw-r--r--indra/newview/llworld.cpp11
-rw-r--r--indra/newview/llworld.h8
-rw-r--r--indra/newview/llworldmap.cpp40
-rw-r--r--indra/newview/llworldmap.h15
-rw-r--r--indra/newview/llworldmapview.cpp150
-rw-r--r--indra/newview/llworldmapview.h10
-rw-r--r--indra/newview/macview_Prefix.h4
-rw-r--r--indra/newview/pipeline.cpp261
-rw-r--r--indra/newview/pipeline.h44
-rw-r--r--indra/newview/res/bitmap2.bmpbin0 -> 25118 bytes
-rw-r--r--indra/newview/res/install_icon.BMPbin0 -> 262198 bytes
-rw-r--r--indra/newview/res/loginbackground.bmpbin0 -> 336054 bytes
-rw-r--r--indra/newview/res/uninstall_icon.BMPbin0 -> 262198 bytes
-rw-r--r--indra/newview/res/viewerRes.rc10
-rw-r--r--indra/newview/skins/default/colors.xml677
-rw-r--r--indra/newview/skins/default/textures/bottomtray/DownArrow.pngbin0 -> 139 bytes
-rw-r--r--indra/newview/skins/default/textures/bottomtray/Unread_IM.pngbin0 -> 297 bytes
-rw-r--r--indra/newview/skins/default/textures/bottomtray/VoicePTT_Lvl1.pngbin0 -> 557 bytes
-rw-r--r--indra/newview/skins/default/textures/bottomtray/VoicePTT_Lvl2.pngbin0 -> 663 bytes
-rw-r--r--indra/newview/skins/default/textures/bottomtray/VoicePTT_Lvl3.pngbin0 -> 607 bytes
-rw-r--r--indra/newview/skins/default/textures/bottomtray/VoicePTT_Off.pngbin0 -> 461 bytes
-rw-r--r--indra/newview/skins/default/textures/bottomtray/VoicePTT_On.pngbin0 -> 451 bytes
-rw-r--r--indra/newview/skins/default/textures/containers/Accordion_ArrowClosed_Off.pngbin0 -> 175 bytes
-rw-r--r--indra/newview/skins/default/textures/containers/Accordion_ArrowClosed_Over.pngbin0 -> 170 bytes
-rw-r--r--indra/newview/skins/default/textures/containers/Accordion_ArrowClosed_Press.pngbin0 -> 175 bytes
-rw-r--r--indra/newview/skins/default/textures/containers/Accordion_ArrowOpened_Off.pngbin0 -> 169 bytes
-rw-r--r--indra/newview/skins/default/textures/containers/Accordion_ArrowOpened_Over.pngbin0 -> 162 bytes
-rw-r--r--indra/newview/skins/default/textures/containers/Accordion_ArrowOpened_Press.pngbin0 -> 169 bytes
-rw-r--r--indra/newview/skins/default/textures/containers/Accordion_Off.pngbin0 -> 239 bytes
-rw-r--r--indra/newview/skins/default/textures/containers/Accordion_Over.pngbin0 -> 206 bytes
-rw-r--r--indra/newview/skins/default/textures/containers/Accordion_Press.pngbin0 -> 200 bytes
-rw-r--r--indra/newview/skins/default/textures/containers/Container.pngbin0 -> 673 bytes
-rw-r--r--indra/newview/skins/default/textures/containers/TabTop_Left_Off.pngbin0 -> 339 bytes
-rw-r--r--indra/newview/skins/default/textures/containers/TabTop_Left_Over.pngbin0 -> 337 bytes
-rw-r--r--indra/newview/skins/default/textures/containers/TabTop_Left_Selected.pngbin0 -> 458 bytes
-rw-r--r--indra/newview/skins/default/textures/containers/TabTop_Middle_Off.pngbin0 -> 258 bytes
-rw-r--r--indra/newview/skins/default/textures/containers/TabTop_Middle_Over.pngbin0 -> 285 bytes
-rw-r--r--indra/newview/skins/default/textures/containers/TabTop_Middle_Selected.pngbin0 -> 367 bytes
-rw-r--r--indra/newview/skins/default/textures/containers/TabTop_Right_Off.pngbin0 -> 357 bytes
-rw-r--r--indra/newview/skins/default/textures/containers/TabTop_Right_Over.pngbin0 -> 362 bytes
-rw-r--r--indra/newview/skins/default/textures/containers/TabTop_Right_Selected.pngbin0 -> 474 bytes
-rw-r--r--indra/newview/skins/default/textures/containers/Toolbar_Left_Off.pngbin0 -> 306 bytes
-rw-r--r--indra/newview/skins/default/textures/containers/Toolbar_Left_Over.pngbin0 -> 310 bytes
-rw-r--r--indra/newview/skins/default/textures/containers/Toolbar_Left_Selected.pngbin0 -> 380 bytes
-rw-r--r--indra/newview/skins/default/textures/containers/Toolbar_Middle_Off.pngbin0 -> 224 bytes
-rw-r--r--indra/newview/skins/default/textures/containers/Toolbar_Middle_Over.pngbin0 -> 228 bytes
-rw-r--r--indra/newview/skins/default/textures/containers/Toolbar_Middle_Selected.pngbin0 -> 296 bytes
-rw-r--r--indra/newview/skins/default/textures/containers/Toolbar_Right_Off.pngbin0 -> 302 bytes
-rw-r--r--indra/newview/skins/default/textures/containers/Toolbar_Right_Over.pngbin0 -> 297 bytes
-rw-r--r--indra/newview/skins/default/textures/containers/Toolbar_Right_Selected.pngbin0 -> 377 bytes
-rw-r--r--indra/newview/skins/default/textures/icons/AddItem_Off.pngbin0 -> 184 bytes
-rw-r--r--indra/newview/skins/default/textures/icons/AddItem_Over.pngbin0 -> 165 bytes
-rw-r--r--indra/newview/skins/default/textures/icons/AddItem_Press.pngbin0 -> 181 bytes
-rw-r--r--indra/newview/skins/default/textures/icons/BackArrow_Off.pngbin0 -> 227 bytes
-rw-r--r--indra/newview/skins/default/textures/icons/BackArrow_Over.pngbin0 -> 214 bytes
-rw-r--r--indra/newview/skins/default/textures/icons/ForwardArrow_Off.pngbin0 -> 220 bytes
-rw-r--r--indra/newview/skins/default/textures/icons/ForwardArrow_Press.pngbin0 -> 220 bytes
-rw-r--r--indra/newview/skins/default/textures/icons/Info.pngbin0 -> 351 bytes
-rw-r--r--indra/newview/skins/default/textures/icons/OptionsMenu_Off.pngbin0 -> 336 bytes
-rw-r--r--indra/newview/skins/default/textures/icons/OptionsMenu_Over.pngbin0 -> 277 bytes
-rw-r--r--indra/newview/skins/default/textures/icons/OptionsMenu_Press.pngbin0 -> 318 bytes
-rw-r--r--indra/newview/skins/default/textures/icons/TrashItem_Off.pngbin0 -> 201 bytes
-rw-r--r--indra/newview/skins/default/textures/icons/TrashItem_Over.pngbin0 -> 201 bytes
-rw-r--r--indra/newview/skins/default/textures/icons/TrashItem_Press.pngbin0 -> 201 bytes
-rw-r--r--indra/newview/skins/default/textures/icons/VoicePTT_Lvl1.pngbin0 -> 557 bytes
-rw-r--r--indra/newview/skins/default/textures/icons/VoicePTT_Lvl2.pngbin0 -> 663 bytes
-rw-r--r--indra/newview/skins/default/textures/icons/VoicePTT_Lvl3.pngbin0 -> 607 bytes
-rw-r--r--indra/newview/skins/default/textures/icons/VoicePTT_Off.pngbin0 -> 461 bytes
-rw-r--r--indra/newview/skins/default/textures/icons/VoicePTT_On.pngbin0 -> 451 bytes
-rw-r--r--indra/newview/skins/default/textures/image_edit_icon.tgabin0 -> 3116 bytes
-rw-r--r--indra/newview/skins/default/textures/jump_left_in.tgabin0 -> 812 bytes
-rw-r--r--indra/newview/skins/default/textures/jump_left_out.tgabin0 -> 812 bytes
-rw-r--r--indra/newview/skins/default/textures/jump_right_in.tgabin0 -> 812 bytes
-rw-r--r--indra/newview/skins/default/textures/jump_right_out.tgabin0 -> 812 bytes
-rw-r--r--indra/newview/skins/default/textures/menu_separator.pngbin0 -> 2831 bytes
-rw-r--r--indra/newview/skins/default/textures/navbar/Arrow_Left_Off.pngbin0 -> 382 bytes
-rw-r--r--indra/newview/skins/default/textures/navbar/Arrow_Left_Over.pngbin0 -> 381 bytes
-rw-r--r--indra/newview/skins/default/textures/navbar/Arrow_Right_Off.pngbin0 -> 380 bytes
-rw-r--r--indra/newview/skins/default/textures/navbar/Arrow_Right_Over.pngbin0 -> 379 bytes
-rw-r--r--indra/newview/skins/default/textures/navbar/Favorite_Star_Active.pngbin0 -> 704 bytes
-rw-r--r--indra/newview/skins/default/textures/navbar/Favorite_Star_Off.pngbin0 -> 444 bytes
-rw-r--r--indra/newview/skins/default/textures/navbar/Favorite_Star_Over.pngbin0 -> 445 bytes
-rw-r--r--indra/newview/skins/default/textures/navbar/Favorite_Star_Press.pngbin0 -> 616 bytes
-rw-r--r--indra/newview/skins/default/textures/navbar/FileMenu_Divider.pngbin0 -> 116 bytes
-rw-r--r--indra/newview/skins/default/textures/navbar/Help_Over.pngbin0 -> 348 bytes
-rw-r--r--indra/newview/skins/default/textures/navbar/Help_Press.pngbin0 -> 384 bytes
-rw-r--r--indra/newview/skins/default/textures/navbar/Home_Off.pngbin0 -> 379 bytes
-rw-r--r--indra/newview/skins/default/textures/navbar/Home_Over.pngbin0 -> 330 bytes
-rw-r--r--indra/newview/skins/default/textures/navbar/Info_Off.pngbin0 -> 608 bytes
-rw-r--r--indra/newview/skins/default/textures/navbar/Info_Over.pngbin0 -> 622 bytes
-rw-r--r--indra/newview/skins/default/textures/navbar/Info_Press.pngbin0 -> 605 bytes
-rw-r--r--indra/newview/skins/default/textures/navbar/NavBar_BG.pngbin0 -> 210 bytes
-rw-r--r--indra/newview/skins/default/textures/navbar/Row_Selection.pngbin0 -> 231 bytes
-rw-r--r--indra/newview/skins/default/textures/navbar/Search.pngbin0 -> 467 bytes
-rw-r--r--indra/newview/skins/default/textures/quick_tips/avatar_free_mode.pngbin0 -> 1447 bytes
-rw-r--r--indra/newview/skins/default/textures/quick_tips/camera_free_mode.pngbin0 -> 2267 bytes
-rw-r--r--indra/newview/skins/default/textures/quick_tips/camera_orbit_mode.pngbin0 -> 2381 bytes
-rw-r--r--indra/newview/skins/default/textures/quick_tips/camera_pan_mode.pngbin0 -> 2418 bytes
-rw-r--r--indra/newview/skins/default/textures/quick_tips/camera_preset_front_view.pngbin0 -> 2365 bytes
-rw-r--r--indra/newview/skins/default/textures/quick_tips/camera_preset_group_view.pngbin0 -> 2595 bytes
-rw-r--r--indra/newview/skins/default/textures/quick_tips/camera_preset_rear_view.pngbin0 -> 2221 bytes
-rw-r--r--indra/newview/skins/default/textures/quick_tips/move_fly_first.pngbin0 -> 1528 bytes
-rw-r--r--indra/newview/skins/default/textures/quick_tips/move_fly_second.pngbin0 -> 2128 bytes
-rw-r--r--indra/newview/skins/default/textures/quick_tips/move_run_first.pngbin0 -> 1554 bytes
-rw-r--r--indra/newview/skins/default/textures/quick_tips/move_run_second.pngbin0 -> 2534 bytes
-rw-r--r--indra/newview/skins/default/textures/quick_tips/move_walk_first.pngbin0 -> 2106 bytes
-rw-r--r--indra/newview/skins/default/textures/quick_tips/move_walk_second.pngbin0 -> 3108 bytes
-rw-r--r--indra/newview/skins/default/textures/show_btn.tgabin0 -> 3884 bytes
-rw-r--r--indra/newview/skins/default/textures/show_btn_selected.tgabin0 -> 3884 bytes
-rw-r--r--indra/newview/skins/default/textures/taskpanel/TabIcon_Appearance_Off.pngbin0 -> 808 bytes
-rw-r--r--indra/newview/skins/default/textures/taskpanel/TabIcon_Appearance_Selected.pngbin0 -> 835 bytes
-rw-r--r--indra/newview/skins/default/textures/taskpanel/TabIcon_Close_Off.pngbin0 -> 305 bytes
-rw-r--r--indra/newview/skins/default/textures/taskpanel/TabIcon_Home_Off.pngbin0 -> 228 bytes
-rw-r--r--indra/newview/skins/default/textures/taskpanel/TabIcon_Home_Selected.pngbin0 -> 291 bytes
-rw-r--r--indra/newview/skins/default/textures/taskpanel/TabIcon_Me_Off.pngbin0 -> 307 bytes
-rw-r--r--indra/newview/skins/default/textures/taskpanel/TabIcon_Me_Selected.pngbin0 -> 452 bytes
-rw-r--r--indra/newview/skins/default/textures/taskpanel/TabIcon_Open_Off.pngbin0 -> 294 bytes
-rw-r--r--indra/newview/skins/default/textures/taskpanel/TabIcon_People_Off.pngbin0 -> 361 bytes
-rw-r--r--indra/newview/skins/default/textures/taskpanel/TabIcon_People_Selected.pngbin0 -> 599 bytes
-rw-r--r--indra/newview/skins/default/textures/taskpanel/TabIcon_Places_Off.pngbin0 -> 350 bytes
-rw-r--r--indra/newview/skins/default/textures/taskpanel/TabIcon_Places_Selected.pngbin0 -> 476 bytes
-rw-r--r--indra/newview/skins/default/textures/taskpanel/TabIcon_Things_Off.pngbin0 -> 223 bytes
-rw-r--r--indra/newview/skins/default/textures/taskpanel/TabIcon_Things_Selected.pngbin0 -> 297 bytes
-rw-r--r--indra/newview/skins/default/textures/taskpanel/TaskPanel_Tab_Off.pngbin0 -> 219 bytes
-rw-r--r--indra/newview/skins/default/textures/taskpanel/TaskPanel_Tab_Selected.pngbin0 -> 325 bytes
-rw-r--r--indra/newview/skins/default/textures/textures.xml605
-rw-r--r--indra/newview/skins/default/textures/transparent.j2cbin0 -> 172 bytes
-rw-r--r--indra/newview/skins/default/textures/voice_meter_dot.j2cbin0 -> 499 bytes
-rw-r--r--indra/newview/skins/default/textures/voice_meter_rings.j2cbin0 -> 2518 bytes
-rw-r--r--indra/newview/skins/default/textures/widgets/Arrow_Down.pngbin0 -> 3066 bytes
-rw-r--r--indra/newview/skins/default/textures/widgets/Arrow_Up.pngbin0 -> 363 bytes
-rw-r--r--indra/newview/skins/default/textures/widgets/Checkbox_Disabled.pngbin0 -> 306 bytes
-rw-r--r--indra/newview/skins/default/textures/widgets/Checkbox_Off.pngbin0 -> 322 bytes
-rw-r--r--indra/newview/skins/default/textures/widgets/Checkbox_On.pngbin0 -> 577 bytes
-rw-r--r--indra/newview/skins/default/textures/widgets/Checkbox_On_Disabled.pngbin0 -> 558 bytes
-rw-r--r--indra/newview/skins/default/textures/widgets/Checkbox_On_Over.pngbin0 -> 547 bytes
-rw-r--r--indra/newview/skins/default/textures/widgets/Checkbox_On_Press.pngbin0 -> 612 bytes
-rw-r--r--indra/newview/skins/default/textures/widgets/Checkbox_Over.pngbin0 -> 318 bytes
-rw-r--r--indra/newview/skins/default/textures/widgets/Checkbox_Press.pngbin0 -> 373 bytes
-rw-r--r--indra/newview/skins/default/textures/widgets/ComboButton_Disabled.pngbin0 -> 450 bytes
-rw-r--r--indra/newview/skins/default/textures/widgets/ComboButton_Off.pngbin0 -> 470 bytes
-rw-r--r--indra/newview/skins/default/textures/widgets/ComboButton_On.pngbin0 -> 486 bytes
-rw-r--r--indra/newview/skins/default/textures/widgets/ComboButton_Selected.pngbin0 -> 539 bytes
-rw-r--r--indra/newview/skins/default/textures/widgets/DisclosureArrow_Closed_Over.pngbin0 -> 164 bytes
-rw-r--r--indra/newview/skins/default/textures/widgets/DisclosureArrow_Opened_Off.pngbin0 -> 173 bytes
-rw-r--r--indra/newview/skins/default/textures/widgets/DisclosureArrow_Opened_Over.pngbin0 -> 165 bytes
-rw-r--r--indra/newview/skins/default/textures/widgets/DropDown_Disabled.pngbin0 -> 600 bytes
-rw-r--r--indra/newview/skins/default/textures/widgets/DropDown_Off.pngbin0 -> 603 bytes
-rw-r--r--indra/newview/skins/default/textures/widgets/DropDown_On.pngbin0 -> 638 bytes
-rw-r--r--indra/newview/skins/default/textures/widgets/DropDown_Press.pngbin0 -> 679 bytes
-rw-r--r--indra/newview/skins/default/textures/widgets/ListItem_Over.pngbin0 -> 244 bytes
-rw-r--r--indra/newview/skins/default/textures/widgets/ListItem_Select.pngbin0 -> 251 bytes
-rw-r--r--indra/newview/skins/default/textures/widgets/ProgressBar.pngbin0 -> 220 bytes
-rw-r--r--indra/newview/skins/default/textures/widgets/ProgressTrack.pngbin0 -> 192 bytes
-rw-r--r--indra/newview/skins/default/textures/widgets/PushButton_Disabled.pngbin0 -> 461 bytes
-rw-r--r--indra/newview/skins/default/textures/widgets/PushButton_Off.pngbin0 -> 464 bytes
-rw-r--r--indra/newview/skins/default/textures/widgets/PushButton_On.pngbin0 -> 490 bytes
-rw-r--r--indra/newview/skins/default/textures/widgets/PushButton_On_Over.pngbin0 -> 498 bytes
-rw-r--r--indra/newview/skins/default/textures/widgets/PushButton_On_Selected.pngbin0 -> 572 bytes
-rw-r--r--indra/newview/skins/default/textures/widgets/PushButton_Over.pngbin0 -> 457 bytes
-rw-r--r--indra/newview/skins/default/textures/widgets/PushButton_Press.pngbin0 -> 520 bytes
-rw-r--r--indra/newview/skins/default/textures/widgets/PushButton_Selected.pngbin0 -> 520 bytes
-rw-r--r--indra/newview/skins/default/textures/widgets/PushButton_Selected_Disabled.pngbin0 -> 490 bytes
-rw-r--r--indra/newview/skins/default/textures/widgets/PushButton_Selected_Over.pngbin0 -> 498 bytes
-rw-r--r--indra/newview/skins/default/textures/widgets/PushButton_Selected_Press.pngbin0 -> 572 bytes
-rw-r--r--indra/newview/skins/default/textures/widgets/RadioButton_Disabled.pngbin0 -> 541 bytes
-rw-r--r--indra/newview/skins/default/textures/widgets/RadioButton_Off.pngbin0 -> 563 bytes
-rw-r--r--indra/newview/skins/default/textures/widgets/RadioButton_On.pngbin0 -> 627 bytes
-rw-r--r--indra/newview/skins/default/textures/widgets/RadioButton_On_Disabled.pngbin0 -> 605 bytes
-rw-r--r--indra/newview/skins/default/textures/widgets/RadioButton_On_Over.pngbin0 -> 635 bytes
-rw-r--r--indra/newview/skins/default/textures/widgets/RadioButton_On_Press.pngbin0 -> 641 bytes
-rw-r--r--indra/newview/skins/default/textures/widgets/RadioButton_Over.pngbin0 -> 575 bytes
-rw-r--r--indra/newview/skins/default/textures/widgets/RadioButton_Press.pngbin0 -> 589 bytes
-rw-r--r--indra/newview/skins/default/textures/widgets/ScrollArrow_Down.pngbin0 -> 239 bytes
-rw-r--r--indra/newview/skins/default/textures/widgets/ScrollArrow_Down_Over.pngbin0 -> 257 bytes
-rw-r--r--indra/newview/skins/default/textures/widgets/ScrollArrow_Left.pngbin0 -> 271 bytes
-rw-r--r--indra/newview/skins/default/textures/widgets/ScrollArrow_Left_Over.pngbin0 -> 295 bytes
-rw-r--r--indra/newview/skins/default/textures/widgets/ScrollArrow_Right.pngbin0 -> 260 bytes
-rw-r--r--indra/newview/skins/default/textures/widgets/ScrollArrow_Right_Over.pngbin0 -> 283 bytes
-rw-r--r--indra/newview/skins/default/textures/widgets/ScrollArrow_Up.pngbin0 -> 262 bytes
-rw-r--r--indra/newview/skins/default/textures/widgets/ScrollArrow_Up_Over.pngbin0 -> 276 bytes
-rw-r--r--indra/newview/skins/default/textures/widgets/ScrollThumb_Horiz.pngbin0 -> 364 bytes
-rw-r--r--indra/newview/skins/default/textures/widgets/ScrollThumb_Horiz_Over.pngbin0 -> 311 bytes
-rw-r--r--indra/newview/skins/default/textures/widgets/ScrollThumb_Vert.pngbin0 -> 323 bytes
-rw-r--r--indra/newview/skins/default/textures/widgets/ScrollThumb_Vert_Over.pngbin0 -> 311 bytes
-rw-r--r--indra/newview/skins/default/textures/widgets/ScrollTrack_Horiz.pngbin0 -> 153 bytes
-rw-r--r--indra/newview/skins/default/textures/widgets/ScrollTrack_Vert.pngbin0 -> 150 bytes
-rw-r--r--indra/newview/skins/default/textures/widgets/SegmentedBtn_Left_Disabled.pngbin0 -> 378 bytes
-rw-r--r--indra/newview/skins/default/textures/widgets/SegmentedBtn_Left_Off.pngbin0 -> 386 bytes
-rw-r--r--indra/newview/skins/default/textures/widgets/SegmentedBtn_Left_On.pngbin0 -> 404 bytes
-rw-r--r--indra/newview/skins/default/textures/widgets/SegmentedBtn_Left_On_Disabled.pngbin0 -> 404 bytes
-rw-r--r--indra/newview/skins/default/textures/widgets/SegmentedBtn_Left_On_Over.pngbin0 -> 394 bytes
-rw-r--r--indra/newview/skins/default/textures/widgets/SegmentedBtn_Left_On_Selected.pngbin0 -> 495 bytes
-rw-r--r--indra/newview/skins/default/textures/widgets/SegmentedBtn_Left_Over.pngbin0 -> 384 bytes
-rw-r--r--indra/newview/skins/default/textures/widgets/SegmentedBtn_Left_Press.pngbin0 -> 455 bytes
-rw-r--r--indra/newview/skins/default/textures/widgets/SegmentedBtn_Left_Selected.pngbin0 -> 455 bytes
-rw-r--r--indra/newview/skins/default/textures/widgets/SegmentedBtn_Left_Selected_Disabled.pngbin0 -> 404 bytes
-rw-r--r--indra/newview/skins/default/textures/widgets/SegmentedBtn_Left_Selected_Over.pngbin0 -> 394 bytes
-rw-r--r--indra/newview/skins/default/textures/widgets/SegmentedBtn_Left_Selected_Press.pngbin0 -> 495 bytes
-rw-r--r--indra/newview/skins/default/textures/widgets/SegmentedBtn_Middle_Disabled.pngbin0 -> 277 bytes
-rw-r--r--indra/newview/skins/default/textures/widgets/SegmentedBtn_Middle_On.pngbin0 -> 308 bytes
-rw-r--r--indra/newview/skins/default/textures/widgets/SegmentedBtn_Middle_On_Over.pngbin0 -> 300 bytes
-rw-r--r--indra/newview/skins/default/textures/widgets/SegmentedBtn_Middle_On_Press.pngbin0 -> 393 bytes
-rw-r--r--indra/newview/skins/default/textures/widgets/SegmentedBtn_Middle_Over.pngbin0 -> 286 bytes
-rw-r--r--indra/newview/skins/default/textures/widgets/SegmentedBtn_Middle_Selected.pngbin0 -> 359 bytes
-rw-r--r--indra/newview/skins/default/textures/widgets/SegmentedBtn_Middle_Selected_Disabled.pngbin0 -> 308 bytes
-rw-r--r--indra/newview/skins/default/textures/widgets/SegmentedBtn_Middle_Selected_Over.pngbin0 -> 300 bytes
-rw-r--r--indra/newview/skins/default/textures/widgets/SegmentedBtn_Middle_Selected_Press.pngbin0 -> 393 bytes
-rw-r--r--indra/newview/skins/default/textures/widgets/SegmentedBtn_Right_Disabled.pngbin0 -> 380 bytes
-rw-r--r--indra/newview/skins/default/textures/widgets/SegmentedBtn_Right_Off.pngbin0 -> 391 bytes
-rw-r--r--indra/newview/skins/default/textures/widgets/SegmentedBtn_Right_On.pngbin0 -> 420 bytes
-rw-r--r--indra/newview/skins/default/textures/widgets/SegmentedBtn_Right_On_Over.pngbin0 -> 416 bytes
-rw-r--r--indra/newview/skins/default/textures/widgets/SegmentedBtn_Right_On_Selected.pngbin0 -> 502 bytes
-rw-r--r--indra/newview/skins/default/textures/widgets/SegmentedBtn_Right_Over.pngbin0 -> 398 bytes
-rw-r--r--indra/newview/skins/default/textures/widgets/SegmentedBtn_Right_Press.pngbin0 -> 459 bytes
-rw-r--r--indra/newview/skins/default/textures/widgets/SegmentedBtn_Right_Selected.pngbin0 -> 459 bytes
-rw-r--r--indra/newview/skins/default/textures/widgets/SegmentedBtn_Right_Selected_Disabled.pngbin0 -> 420 bytes
-rw-r--r--indra/newview/skins/default/textures/widgets/SegmentedBtn_Right_Selected_Over.pngbin0 -> 416 bytes
-rw-r--r--indra/newview/skins/default/textures/widgets/SegmentedBtn_Right_Selected_Press.pngbin0 -> 502 bytes
-rw-r--r--indra/newview/skins/default/textures/widgets/SliderThumb_Disabled.pngbin0 -> 475 bytes
-rw-r--r--indra/newview/skins/default/textures/widgets/SliderThumb_Off.pngbin0 -> 475 bytes
-rw-r--r--indra/newview/skins/default/textures/widgets/SliderThumb_Over.pngbin0 -> 482 bytes
-rw-r--r--indra/newview/skins/default/textures/widgets/SliderThumb_Press.pngbin0 -> 470 bytes
-rw-r--r--indra/newview/skins/default/textures/widgets/SliderTrack_Horiz.pngbin0 -> 225 bytes
-rw-r--r--indra/newview/skins/default/textures/widgets/SliderTrack_Vert.pngbin0 -> 232 bytes
-rw-r--r--indra/newview/skins/default/textures/widgets/Stepper_Down_Off.pngbin0 -> 300 bytes
-rw-r--r--indra/newview/skins/default/textures/widgets/Stepper_Down_Over.pngbin0 -> 310 bytes
-rw-r--r--indra/newview/skins/default/textures/widgets/Stepper_Down_Press.pngbin0 -> 343 bytes
-rw-r--r--indra/newview/skins/default/textures/widgets/Stepper_Up_Off.pngbin0 -> 315 bytes
-rw-r--r--indra/newview/skins/default/textures/widgets/Stepper_Up_Over.pngbin0 -> 314 bytes
-rw-r--r--indra/newview/skins/default/textures/widgets/Stepper_Up_Press.pngbin0 -> 384 bytes
-rw-r--r--indra/newview/skins/default/textures/widgets/TextField_Active.pngbin0 -> 225 bytes
-rw-r--r--indra/newview/skins/default/textures/widgets/TextField_Disabled.pngbin0 -> 225 bytes
-rw-r--r--indra/newview/skins/default/textures/widgets/TextField_Off.pngbin0 -> 224 bytes
-rw-r--r--indra/newview/skins/default/textures/widgets/TextField_Search_Active.pngbin0 -> 923 bytes
-rw-r--r--indra/newview/skins/default/textures/widgets/TextField_Search_Disabled.pngbin0 -> 943 bytes
-rw-r--r--indra/newview/skins/default/textures/widgets/TextField_Search_Off.pngbin0 -> 958 bytes
-rw-r--r--indra/newview/skins/default/textures/windows/Flyout.pngbin0 -> 820 bytes
-rw-r--r--indra/newview/skins/default/textures/windows/Flyout_Pointer.pngbin0 -> 236 bytes
-rw-r--r--indra/newview/skins/default/textures/windows/Icon_Close_Foreground.pngbin0 -> 263 bytes
-rw-r--r--indra/newview/skins/default/textures/windows/Icon_Close_Press.pngbin0 -> 263 bytes
-rw-r--r--indra/newview/skins/default/textures/windows/Icon_Close_Toast.pngbin0 -> 460 bytes
-rw-r--r--indra/newview/skins/default/textures/windows/Icon_Dock_Foreground.pngbin0 -> 263 bytes
-rw-r--r--indra/newview/skins/default/textures/windows/Icon_Dock_Press.pngbin0 -> 263 bytes
-rw-r--r--indra/newview/skins/default/textures/windows/Icon_Gear_Background.pngbin0 -> 373 bytes
-rw-r--r--indra/newview/skins/default/textures/windows/Icon_Gear_Foreground.pngbin0 -> 373 bytes
-rw-r--r--indra/newview/skins/default/textures/windows/Icon_Gear_Over.pngbin0 -> 279 bytes
-rw-r--r--indra/newview/skins/default/textures/windows/Icon_Gear_Press.pngbin0 -> 396 bytes
-rw-r--r--indra/newview/skins/default/textures/windows/Icon_Undock_Foreground.pngbin0 -> 268 bytes
-rw-r--r--indra/newview/skins/default/textures/windows/Icon_Undock_Press.pngbin0 -> 267 bytes
-rw-r--r--indra/newview/skins/default/textures/windows/Resize_Corner.pngbin0 -> 137 bytes
-rw-r--r--indra/newview/skins/default/textures/windows/Toast_CloseBtn.pngbin0 -> 471 bytes
-rw-r--r--indra/newview/skins/default/textures/windows/Toast_Over.pngbin0 -> 400 bytes
-rw-r--r--indra/newview/skins/default/textures/windows/Window_Background.pngbin0 -> 950 bytes
-rw-r--r--indra/newview/skins/default/textures/windows/Window_Foreground.pngbin0 -> 959 bytes
-rw-r--r--indra/newview/skins/default/textures/world/NoEntryLines.pngbin0 -> 3523 bytes
-rw-r--r--indra/newview/skins/default/textures/world/NoEntryPassLines.pngbin0 -> 1267 bytes
-rw-r--r--indra/newview/skins/default/xui/da/floater_about.xml2
-rw-r--r--indra/newview/skins/default/xui/da/floater_about_land.xml76
-rw-r--r--indra/newview/skins/default/xui/da/floater_animation_preview.xml148
-rw-r--r--indra/newview/skins/default/xui/da/floater_buy_land.xml12
-rw-r--r--indra/newview/skins/default/xui/da/floater_customize.xml8
-rw-r--r--indra/newview/skins/default/xui/da/floater_hardware_settings.xml20
-rw-r--r--indra/newview/skins/default/xui/da/floater_image_preview.xml40
-rw-r--r--indra/newview/skins/default/xui/da/floater_inventory_item_properties.xml8
-rw-r--r--indra/newview/skins/default/xui/da/floater_postcard.xml2
-rw-r--r--indra/newview/skins/default/xui/da/floater_preview_gesture.xml8
-rw-r--r--indra/newview/skins/default/xui/da/floater_report_abuse.xml144
-rw-r--r--indra/newview/skins/default/xui/da/floater_sell_land.xml20
-rw-r--r--indra/newview/skins/default/xui/da/floater_settings_debug.xml8
-rw-r--r--indra/newview/skins/default/xui/da/floater_snapshot.xml108
-rw-r--r--indra/newview/skins/default/xui/da/floater_tools.xml306
-rw-r--r--indra/newview/skins/default/xui/da/floater_tos.xml2
-rw-r--r--indra/newview/skins/default/xui/da/floater_world_map.xml10
-rw-r--r--indra/newview/skins/default/xui/da/language_settings.xml55
-rw-r--r--indra/newview/skins/default/xui/da/menu_login.xml4
-rw-r--r--indra/newview/skins/default/xui/da/menu_viewer.xml8
-rw-r--r--indra/newview/skins/default/xui/da/notifications.xml33
-rw-r--r--indra/newview/skins/default/xui/da/panel_login.xml12
-rw-r--r--indra/newview/skins/default/xui/da/panel_preferences_chat.xml12
-rw-r--r--indra/newview/skins/default/xui/da/panel_preferences_general.xml95
-rw-r--r--indra/newview/skins/default/xui/da/panel_preferences_graphics1.xml68
-rw-r--r--indra/newview/skins/default/xui/da/panel_status_bar.xml6
-rw-r--r--indra/newview/skins/default/xui/da/strings.xml2
-rw-r--r--indra/newview/skins/default/xui/de/floater_about.xml2
-rw-r--r--indra/newview/skins/default/xui/de/floater_animation_preview.xml148
-rw-r--r--indra/newview/skins/default/xui/de/floater_buy_land.xml12
-rw-r--r--indra/newview/skins/default/xui/de/floater_god_tools.xml24
-rw-r--r--indra/newview/skins/default/xui/de/floater_hardware_settings.xml20
-rw-r--r--indra/newview/skins/default/xui/de/floater_image_preview.xml40
-rw-r--r--indra/newview/skins/default/xui/de/floater_inventory_item_properties.xml8
-rw-r--r--indra/newview/skins/default/xui/de/floater_postcard.xml2
-rw-r--r--indra/newview/skins/default/xui/de/floater_preview_gesture.xml8
-rw-r--r--indra/newview/skins/default/xui/de/floater_report_abuse.xml144
-rw-r--r--indra/newview/skins/default/xui/de/floater_sell_land.xml20
-rw-r--r--indra/newview/skins/default/xui/de/floater_settings_debug.xml8
-rw-r--r--indra/newview/skins/default/xui/de/floater_sound_preview.xml16
-rw-r--r--indra/newview/skins/default/xui/de/floater_tools.xml630
-rw-r--r--indra/newview/skins/default/xui/de/floater_tos.xml10
-rw-r--r--indra/newview/skins/default/xui/de/floater_world_map.xml10
-rw-r--r--indra/newview/skins/default/xui/de/language_settings.xml55
-rw-r--r--indra/newview/skins/default/xui/de/menu_login.xml4
-rw-r--r--indra/newview/skins/default/xui/de/menu_viewer.xml4
-rw-r--r--indra/newview/skins/default/xui/de/notifications.xml88
-rw-r--r--indra/newview/skins/default/xui/de/panel_group_general.xml85
-rw-r--r--indra/newview/skins/default/xui/de/panel_group_land_money.xml86
-rw-r--r--indra/newview/skins/default/xui/de/panel_group_notices.xml80
-rw-r--r--indra/newview/skins/default/xui/de/panel_group_roles.xml163
-rw-r--r--indra/newview/skins/default/xui/de/panel_login.xml12
-rw-r--r--indra/newview/skins/default/xui/de/panel_preferences_chat.xml12
-rw-r--r--indra/newview/skins/default/xui/de/panel_preferences_graphics1.xml68
-rw-r--r--indra/newview/skins/default/xui/de/panel_status_bar.xml4
-rw-r--r--indra/newview/skins/default/xui/en/accordion_drag.xml8
-rw-r--r--indra/newview/skins/default/xui/en/accordion_parent.xml7
-rw-r--r--indra/newview/skins/default/xui/en/favorites_bar_button.xml19
-rw-r--r--indra/newview/skins/default/xui/en/floater_aaa.xml22
-rw-r--r--indra/newview/skins/default/xui/en/floater_about.xml121
-rw-r--r--indra/newview/skins/default/xui/en/floater_about_land.xml2196
-rw-r--r--indra/newview/skins/default/xui/en/floater_activeim.xml30
-rw-r--r--indra/newview/skins/default/xui/en/floater_animation_preview.xml512
-rw-r--r--indra/newview/skins/default/xui/en/floater_auction.xml68
-rw-r--r--indra/newview/skins/default/xui/en/floater_avatar_picker.xml208
-rw-r--r--indra/newview/skins/default/xui/en/floater_avatar_textures.xml211
-rw-r--r--indra/newview/skins/default/xui/en/floater_beacons.xml108
-rw-r--r--indra/newview/skins/default/xui/en/floater_build_options.xml71
-rw-r--r--indra/newview/skins/default/xui/en/floater_bulk_perms.xml334
-rw-r--r--indra/newview/skins/default/xui/en/floater_bumps.xml47
-rw-r--r--indra/newview/skins/default/xui/en/floater_buy_contents.xml94
-rw-r--r--indra/newview/skins/default/xui/en/floater_buy_currency.xml295
-rw-r--r--indra/newview/skins/default/xui/en/floater_buy_land.xml707
-rw-r--r--indra/newview/skins/default/xui/en/floater_buy_object.xml109
-rw-r--r--indra/newview/skins/default/xui/en/floater_camera.xml142
-rw-r--r--indra/newview/skins/default/xui/en/floater_choose_group.xml49
-rw-r--r--indra/newview/skins/default/xui/en/floater_color_picker.xml225
-rw-r--r--indra/newview/skins/default/xui/en/floater_critical.xml57
-rw-r--r--indra/newview/skins/default/xui/en/floater_customize.xml3564
-rw-r--r--indra/newview/skins/default/xui/en/floater_day_cycle_options.xml613
-rw-r--r--indra/newview/skins/default/xui/en/floater_device_settings.xml16
-rw-r--r--indra/newview/skins/default/xui/en/floater_env_settings.xml165
-rw-r--r--indra/newview/skins/default/xui/en/floater_first_time_tip.xml20
-rw-r--r--indra/newview/skins/default/xui/en/floater_font_test.xml336
-rw-r--r--indra/newview/skins/default/xui/en/floater_gesture.xml92
-rw-r--r--indra/newview/skins/default/xui/en/floater_god_tools.xml798
-rw-r--r--indra/newview/skins/default/xui/en/floater_hardware_settings.xml162
-rw-r--r--indra/newview/skins/default/xui/en/floater_hud.xml22
-rw-r--r--indra/newview/skins/default/xui/en/floater_im.xml78
-rw-r--r--indra/newview/skins/default/xui/en/floater_im_session.xml66
-rw-r--r--indra/newview/skins/default/xui/en/floater_image_preview.xml135
-rw-r--r--indra/newview/skins/default/xui/en/floater_incoming_call.xml71
-rw-r--r--indra/newview/skins/default/xui/en/floater_inspect.xml72
-rw-r--r--indra/newview/skins/default/xui/en/floater_inventory.xml424
-rw-r--r--indra/newview/skins/default/xui/en/floater_inventory_item_properties.xml455
-rw-r--r--indra/newview/skins/default/xui/en/floater_inventory_view_finder.xml281
-rw-r--r--indra/newview/skins/default/xui/en/floater_joystick.xml862
-rw-r--r--indra/newview/skins/default/xui/en/floater_lagmeter.xml346
-rw-r--r--indra/newview/skins/default/xui/en/floater_land_holdings.xml168
-rw-r--r--indra/newview/skins/default/xui/en/floater_live_lsleditor.xml71
-rw-r--r--indra/newview/skins/default/xui/en/floater_lsl_guide.xml62
-rw-r--r--indra/newview/skins/default/xui/en/floater_map.xml172
-rw-r--r--indra/newview/skins/default/xui/en/floater_media_browser.xml235
-rw-r--r--indra/newview/skins/default/xui/en/floater_mem_leaking.xml128
-rw-r--r--indra/newview/skins/default/xui/en/floater_moveview.xml184
-rw-r--r--indra/newview/skins/default/xui/en/floater_mute_object.xml55
-rw-r--r--indra/newview/skins/default/xui/en/floater_my_friends.xml41
-rw-r--r--indra/newview/skins/default/xui/en/floater_nearby_chat.xml49
-rw-r--r--indra/newview/skins/default/xui/en/floater_notification.xml36
-rw-r--r--indra/newview/skins/default/xui/en/floater_notifications_console.xml40
-rw-r--r--indra/newview/skins/default/xui/en/floater_openobject.xml63
-rw-r--r--indra/newview/skins/default/xui/en/floater_pay.xml129
-rw-r--r--indra/newview/skins/default/xui/en/floater_pay_object.xml174
-rw-r--r--indra/newview/skins/default/xui/en/floater_perm_prefs.xml120
-rw-r--r--indra/newview/skins/default/xui/en/floater_post_process.xml420
-rw-r--r--indra/newview/skins/default/xui/en/floater_postcard.xml157
-rw-r--r--indra/newview/skins/default/xui/en/floater_preferences.xml105
-rw-r--r--indra/newview/skins/default/xui/en/floater_preview_animation.xml59
-rw-r--r--indra/newview/skins/default/xui/en/floater_preview_classified.xml22
-rw-r--r--indra/newview/skins/default/xui/en/floater_preview_event.xml22
-rw-r--r--indra/newview/skins/default/xui/en/floater_preview_gesture.xml171
-rw-r--r--indra/newview/skins/default/xui/en/floater_preview_gesture_info.xml173
-rw-r--r--indra/newview/skins/default/xui/en/floater_preview_gesture_shortcut.xml86
-rw-r--r--indra/newview/skins/default/xui/en/floater_preview_gesture_steps.xml148
-rw-r--r--indra/newview/skins/default/xui/en/floater_preview_notecard.xml93
-rw-r--r--indra/newview/skins/default/xui/en/floater_preview_sound.xml61
-rw-r--r--indra/newview/skins/default/xui/en/floater_preview_texture.xml74
-rw-r--r--indra/newview/skins/default/xui/en/floater_region_info.xml18
-rw-r--r--indra/newview/skins/default/xui/en/floater_report_abuse.xml493
-rw-r--r--indra/newview/skins/default/xui/en/floater_script_debug.xml19
-rw-r--r--indra/newview/skins/default/xui/en/floater_script_debug_panel.xml20
-rw-r--r--indra/newview/skins/default/xui/en/floater_script_preview.xml62
-rw-r--r--indra/newview/skins/default/xui/en/floater_script_queue.xml49
-rw-r--r--indra/newview/skins/default/xui/en/floater_script_search.xml90
-rw-r--r--indra/newview/skins/default/xui/en/floater_select_key.xml32
-rw-r--r--indra/newview/skins/default/xui/en/floater_sell_land.xml326
-rw-r--r--indra/newview/skins/default/xui/en/floater_settings_debug.xml137
-rw-r--r--indra/newview/skins/default/xui/en/floater_snapshot.xml394
-rw-r--r--indra/newview/skins/default/xui/en/floater_sound_preview.xml74
-rw-r--r--indra/newview/skins/default/xui/en/floater_statistics.xml10
-rw-r--r--indra/newview/skins/default/xui/en/floater_stats.xml692
-rw-r--r--indra/newview/skins/default/xui/en/floater_sys_well.xml40
-rw-r--r--indra/newview/skins/default/xui/en/floater_telehub.xml132
-rw-r--r--indra/newview/skins/default/xui/en/floater_test_button.xml111
-rw-r--r--indra/newview/skins/default/xui/en/floater_test_checkbox.xml72
-rw-r--r--indra/newview/skins/default/xui/en/floater_test_combobox.xml155
-rw-r--r--indra/newview/skins/default/xui/en/floater_test_layout.xml88
-rw-r--r--indra/newview/skins/default/xui/en/floater_test_line_editor.xml64
-rw-r--r--indra/newview/skins/default/xui/en/floater_test_list_view.xml31
-rw-r--r--indra/newview/skins/default/xui/en/floater_test_navigation_bar.xml17
-rw-r--r--indra/newview/skins/default/xui/en/floater_test_radiogroup.xml81
-rw-r--r--indra/newview/skins/default/xui/en/floater_test_slider.xml77
-rw-r--r--indra/newview/skins/default/xui/en/floater_test_spinner.xml93
-rw-r--r--indra/newview/skins/default/xui/en/floater_test_textbox.xml129
-rw-r--r--indra/newview/skins/default/xui/en/floater_test_widgets.xml345
-rw-r--r--indra/newview/skins/default/xui/en/floater_texture_ctrl.xml149
-rw-r--r--indra/newview/skins/default/xui/en/floater_tools.xml2902
-rw-r--r--indra/newview/skins/default/xui/en/floater_top_objects.xml250
-rw-r--r--indra/newview/skins/default/xui/en/floater_tos.xml80
-rw-r--r--indra/newview/skins/default/xui/en/floater_ui_preview.xml392
-rw-r--r--indra/newview/skins/default/xui/en/floater_url_entry.xml73
-rw-r--r--indra/newview/skins/default/xui/en/floater_water.xml656
-rw-r--r--indra/newview/skins/default/xui/en/floater_wearable_save_as.xml58
-rw-r--r--indra/newview/skins/default/xui/en/floater_windlight_options.xml1487
-rw-r--r--indra/newview/skins/default/xui/en/floater_world_map.xml576
-rw-r--r--indra/newview/skins/default/xui/en/fonts.xml120
-rw-r--r--indra/newview/skins/default/xui/en/inspect_avatar.xml84
-rw-r--r--indra/newview/skins/default/xui/en/language_settings.xml55
-rw-r--r--indra/newview/skins/default/xui/en/menu_avatar_icon.xml43
-rw-r--r--indra/newview/skins/default/xui/en/menu_favorites.xml71
-rw-r--r--indra/newview/skins/default/xui/en/menu_group_plus.xml11
-rw-r--r--indra/newview/skins/default/xui/en/menu_hide_navbar.xml33
-rw-r--r--indra/newview/skins/default/xui/en/menu_imchiclet_group.xml27
-rw-r--r--indra/newview/skins/default/xui/en/menu_imchiclet_p2p.xml35
-rw-r--r--indra/newview/skins/default/xui/en/menu_inventory.xml619
-rw-r--r--indra/newview/skins/default/xui/en/menu_landmark.xml32
-rw-r--r--indra/newview/skins/default/xui/en/menu_login.xml129
-rw-r--r--indra/newview/skins/default/xui/en/menu_mini_map.xml57
-rw-r--r--indra/newview/skins/default/xui/en/menu_navbar.xml90
-rw-r--r--indra/newview/skins/default/xui/en/menu_nearby_chat.xml39
-rw-r--r--indra/newview/skins/default/xui/en/menu_people_friends_view_sort.xml18
-rw-r--r--indra/newview/skins/default/xui/en/menu_people_nearby_view_sort.xml18
-rw-r--r--indra/newview/skins/default/xui/en/menu_people_recent_view_sort.xml15
-rw-r--r--indra/newview/skins/default/xui/en/menu_picks.xml46
-rw-r--r--indra/newview/skins/default/xui/en/menu_place.xml46
-rw-r--r--indra/newview/skins/default/xui/en/menu_slurl.xml37
-rw-r--r--indra/newview/skins/default/xui/en/menu_viewer.xml3390
-rw-r--r--indra/newview/skins/default/xui/en/mime_types.xml442
-rw-r--r--indra/newview/skins/default/xui/en/notifications.xml6571
-rw-r--r--indra/newview/skins/default/xui/en/panel_activeim_row.xml47
-rw-r--r--indra/newview/skins/default/xui/en/panel_audio_device.xml153
-rw-r--r--indra/newview/skins/default/xui/en/panel_avatar_list_item.xml65
-rw-r--r--indra/newview/skins/default/xui/en/panel_avatar_tag.xml71
-rw-r--r--indra/newview/skins/default/xui/en/panel_bars.xml69
-rw-r--r--indra/newview/skins/default/xui/en/panel_bottomtray.xml328
-rw-r--r--indra/newview/skins/default/xui/en/panel_chat_item.xml38
-rw-r--r--indra/newview/skins/default/xui/en/panel_classified.xml138
-rw-r--r--indra/newview/skins/default/xui/en/panel_edit_pick.xml194
-rw-r--r--indra/newview/skins/default/xui/en/panel_edit_profile.xml413
-rw-r--r--indra/newview/skins/default/xui/en/panel_friends.xml124
-rw-r--r--indra/newview/skins/default/xui/en/panel_group_control_panel.xml31
-rw-r--r--indra/newview/skins/default/xui/en/panel_group_general.xml218
-rw-r--r--indra/newview/skins/default/xui/en/panel_group_info_sidetray.xml118
-rw-r--r--indra/newview/skins/default/xui/en/panel_group_invite.xml106
-rw-r--r--indra/newview/skins/default/xui/en/panel_group_land_money.xml372
-rw-r--r--indra/newview/skins/default/xui/en/panel_group_notices.xml384
-rw-r--r--indra/newview/skins/default/xui/en/panel_group_notify.xml33
-rw-r--r--indra/newview/skins/default/xui/en/panel_group_roles.xml797
-rw-r--r--indra/newview/skins/default/xui/en/panel_groups.xml111
-rw-r--r--indra/newview/skins/default/xui/en/panel_hud.xml10
-rw-r--r--indra/newview/skins/default/xui/en/panel_im_control_panel.xml32
-rw-r--r--indra/newview/skins/default/xui/en/panel_instant_message.xml80
-rw-r--r--indra/newview/skins/default/xui/en/panel_landmarks.xml34
-rw-r--r--indra/newview/skins/default/xui/en/panel_login.xml225
-rw-r--r--indra/newview/skins/default/xui/en/panel_navigation_bar.xml138
-rw-r--r--indra/newview/skins/default/xui/en/panel_nearby_chat.xml27
-rw-r--r--indra/newview/skins/default/xui/en/panel_nearby_chat_bar.xml51
-rw-r--r--indra/newview/skins/default/xui/en/panel_notes.xml144
-rw-r--r--indra/newview/skins/default/xui/en/panel_notifications_channel.xml77
-rw-r--r--indra/newview/skins/default/xui/en/panel_people.xml524
-rw-r--r--indra/newview/skins/default/xui/en/panel_pick_info.xml173
-rw-r--r--indra/newview/skins/default/xui/en/panel_pick_list_item.xml57
-rw-r--r--indra/newview/skins/default/xui/en/panel_picks.xml112
-rw-r--r--indra/newview/skins/default/xui/en/panel_places.xml137
-rw-r--r--indra/newview/skins/default/xui/en/panel_preferences_advanced.xml217
-rw-r--r--indra/newview/skins/default/xui/en/panel_preferences_chat.xml289
-rw-r--r--indra/newview/skins/default/xui/en/panel_preferences_general.xml310
-rw-r--r--indra/newview/skins/default/xui/en/panel_preferences_graphics1.xml848
-rw-r--r--indra/newview/skins/default/xui/en/panel_profile.xml383
-rw-r--r--indra/newview/skins/default/xui/en/panel_profile_view.xml72
-rw-r--r--indra/newview/skins/default/xui/en/panel_progress.xml133
-rw-r--r--indra/newview/skins/default/xui/en/panel_region_covenant.xml333
-rw-r--r--indra/newview/skins/default/xui/en/panel_region_debug.xml279
-rw-r--r--indra/newview/skins/default/xui/en/panel_region_estate.xml531
-rw-r--r--indra/newview/skins/default/xui/en/panel_region_general.xml356
-rw-r--r--indra/newview/skins/default/xui/en/panel_region_terrain.xml239
-rw-r--r--indra/newview/skins/default/xui/en/panel_region_texture.xml347
-rw-r--r--indra/newview/skins/default/xui/en/panel_script_ed.xml192
-rw-r--r--indra/newview/skins/default/xui/en/panel_scrolling_param.xml92
-rw-r--r--indra/newview/skins/default/xui/en/panel_side_tray.xml118
-rw-r--r--indra/newview/skins/default/xui/en/panel_side_tray_tab_caption.xml21
-rw-r--r--indra/newview/skins/default/xui/en/panel_sidetray_home_tab.xml203
-rw-r--r--indra/newview/skins/default/xui/en/panel_stand_stop_flying.xml30
-rw-r--r--indra/newview/skins/default/xui/en/panel_status_bar.xml210
-rw-r--r--indra/newview/skins/default/xui/en/panel_sys_well_item.xml65
-rw-r--r--indra/newview/skins/default/xui/en/panel_teleport_history.xml12
-rw-r--r--indra/newview/skins/default/xui/en/panel_toast.xml72
-rw-r--r--indra/newview/skins/default/xui/en/panel_world_map.xml128
-rw-r--r--indra/newview/skins/default/xui/en/role_actions.xml187
-rw-r--r--indra/newview/skins/default/xui/en/strings.xml1334
-rw-r--r--indra/newview/skins/default/xui/en/teleport_strings.xml77
-rw-r--r--indra/newview/skins/default/xui/en/widgets/button.xml17
-rw-r--r--indra/newview/skins/default/xui/en/widgets/check_box.xml19
-rw-r--r--indra/newview/skins/default/xui/en/widgets/color_swatch.xml8
-rw-r--r--indra/newview/skins/default/xui/en/widgets/combo_box.xml27
-rw-r--r--indra/newview/skins/default/xui/en/widgets/drop_down.xml20
-rw-r--r--indra/newview/skins/default/xui/en/widgets/filter_editor.xml8
-rw-r--r--indra/newview/skins/default/xui/en/widgets/flyout_button.xml12
-rw-r--r--indra/newview/skins/default/xui/en/widgets/gesture_combo_box.xml30
-rw-r--r--indra/newview/skins/default/xui/en/widgets/icon.xml7
-rw-r--r--indra/newview/skins/default/xui/en/widgets/line_editor.xml19
-rw-r--r--indra/newview/skins/default/xui/en/widgets/list_view.xml6
-rw-r--r--indra/newview/skins/default/xui/en/widgets/location_input.xml54
-rw-r--r--indra/newview/skins/default/xui/en/widgets/menu.xml7
-rw-r--r--indra/newview/skins/default/xui/en/widgets/menu_item_call.xml6
-rw-r--r--indra/newview/skins/default/xui/en/widgets/menu_item_check.xml6
-rw-r--r--indra/newview/skins/default/xui/en/widgets/menu_item_separator.xml6
-rw-r--r--indra/newview/skins/default/xui/en/widgets/multi_slider.xml6
-rw-r--r--indra/newview/skins/default/xui/en/widgets/multi_slider_bar.xml10
-rw-r--r--indra/newview/skins/default/xui/en/widgets/name_editor.xml2
-rw-r--r--indra/newview/skins/default/xui/en/widgets/output_monitor.xml9
-rw-r--r--indra/newview/skins/default/xui/en/widgets/panel.xml5
-rw-r--r--indra/newview/skins/default/xui/en/widgets/progress_bar.xml12
-rw-r--r--indra/newview/skins/default/xui/en/widgets/radio_group.xml6
-rw-r--r--indra/newview/skins/default/xui/en/widgets/radio_item.xml12
-rw-r--r--indra/newview/skins/default/xui/en/widgets/scroll_bar.xml25
-rw-r--r--indra/newview/skins/default/xui/en/widgets/scroll_container.xml5
-rw-r--r--indra/newview/skins/default/xui/en/widgets/scroll_list.xml16
-rw-r--r--indra/newview/skins/default/xui/en/widgets/search_editor.xml15
-rw-r--r--indra/newview/skins/default/xui/en/widgets/side_tray.xml8
-rw-r--r--indra/newview/skins/default/xui/en/widgets/simple_text_editor.xml23
-rw-r--r--indra/newview/skins/default/xui/en/widgets/slider.xml16
-rw-r--r--indra/newview/skins/default/xui/en/widgets/slider_bar.xml9
-rw-r--r--indra/newview/skins/default/xui/en/widgets/spinner.xml16
-rw-r--r--indra/newview/skins/default/xui/en/widgets/split_button.xml24
-rw-r--r--indra/newview/skins/default/xui/en/widgets/tab_container.xml9
-rw-r--r--indra/newview/skins/default/xui/en/widgets/text.xml16
-rw-r--r--indra/newview/skins/default/xui/en/widgets/text_editor.xml4
-rw-r--r--indra/newview/skins/default/xui/en/widgets/texture_picker.xml9
-rw-r--r--indra/newview/skins/default/xui/en/widgets/view_border.xml8
-rw-r--r--indra/newview/skins/default/xui/en/widgets/web_browser.xml2
-rw-r--r--indra/newview/skins/default/xui/en/xui_version.xml4
-rw-r--r--indra/newview/skins/default/xui/es/floater_about.xml2
-rw-r--r--indra/newview/skins/default/xui/es/floater_animation_preview.xml148
-rw-r--r--indra/newview/skins/default/xui/es/floater_buy_land.xml12
-rw-r--r--indra/newview/skins/default/xui/es/floater_customize.xml8
-rw-r--r--indra/newview/skins/default/xui/es/floater_god_tools.xml24
-rw-r--r--indra/newview/skins/default/xui/es/floater_hardware_settings.xml20
-rw-r--r--indra/newview/skins/default/xui/es/floater_image_preview.xml40
-rw-r--r--indra/newview/skins/default/xui/es/floater_inventory_item_properties.xml8
-rw-r--r--indra/newview/skins/default/xui/es/floater_joystick.xml4
-rw-r--r--indra/newview/skins/default/xui/es/floater_postcard.xml4
-rw-r--r--indra/newview/skins/default/xui/es/floater_preview_gesture.xml8
-rw-r--r--indra/newview/skins/default/xui/es/floater_report_abuse.xml144
-rw-r--r--indra/newview/skins/default/xui/es/floater_sell_land.xml20
-rw-r--r--indra/newview/skins/default/xui/es/floater_settings_debug.xml8
-rw-r--r--indra/newview/skins/default/xui/es/floater_snapshot.xml116
-rw-r--r--indra/newview/skins/default/xui/es/floater_tos.xml2
-rw-r--r--indra/newview/skins/default/xui/es/floater_world_map.xml8
-rw-r--r--indra/newview/skins/default/xui/es/language_settings.xml55
-rw-r--r--indra/newview/skins/default/xui/es/menu_inventory.xml4
-rw-r--r--indra/newview/skins/default/xui/es/menu_login.xml4
-rw-r--r--indra/newview/skins/default/xui/es/menu_viewer.xml4
-rw-r--r--indra/newview/skins/default/xui/es/notifications.xml85
-rw-r--r--indra/newview/skins/default/xui/es/panel_login.xml12
-rw-r--r--indra/newview/skins/default/xui/es/panel_preferences_chat.xml12
-rw-r--r--indra/newview/skins/default/xui/es/panel_preferences_graphics1.xml68
-rw-r--r--indra/newview/skins/default/xui/es/panel_status_bar.xml4
-rw-r--r--indra/newview/skins/default/xui/es/role_actions.xml2
-rw-r--r--indra/newview/skins/default/xui/es/strings.xml3
-rw-r--r--indra/newview/skins/default/xui/fr/floater_about.xml2
-rw-r--r--indra/newview/skins/default/xui/fr/floater_animation_preview.xml148
-rw-r--r--indra/newview/skins/default/xui/fr/floater_auction.xml8
-rw-r--r--indra/newview/skins/default/xui/fr/floater_buy_land.xml12
-rw-r--r--indra/newview/skins/default/xui/fr/floater_god_tools.xml24
-rw-r--r--indra/newview/skins/default/xui/fr/floater_hardware_settings.xml20
-rw-r--r--indra/newview/skins/default/xui/fr/floater_image_preview.xml40
-rw-r--r--indra/newview/skins/default/xui/fr/floater_inventory_item_properties.xml8
-rw-r--r--indra/newview/skins/default/xui/fr/floater_postcard.xml4
-rw-r--r--indra/newview/skins/default/xui/fr/floater_preview_gesture.xml8
-rw-r--r--indra/newview/skins/default/xui/fr/floater_sell_land.xml20
-rw-r--r--indra/newview/skins/default/xui/fr/floater_settings_debug.xml8
-rw-r--r--indra/newview/skins/default/xui/fr/floater_snapshot.xml120
-rw-r--r--indra/newview/skins/default/xui/fr/floater_sound_preview.xml16
-rw-r--r--indra/newview/skins/default/xui/fr/floater_tools.xml244
-rw-r--r--indra/newview/skins/default/xui/fr/floater_tos.xml10
-rw-r--r--indra/newview/skins/default/xui/fr/floater_world_map.xml10
-rw-r--r--indra/newview/skins/default/xui/fr/language_settings.xml55
-rw-r--r--indra/newview/skins/default/xui/fr/menu_login.xml4
-rw-r--r--indra/newview/skins/default/xui/fr/menu_viewer.xml18
-rw-r--r--indra/newview/skins/default/xui/fr/notifications.xml85
-rw-r--r--indra/newview/skins/default/xui/fr/panel_login.xml16
-rw-r--r--indra/newview/skins/default/xui/fr/panel_preferences_chat.xml12
-rw-r--r--indra/newview/skins/default/xui/fr/panel_preferences_graphics1.xml68
-rw-r--r--indra/newview/skins/default/xui/fr/panel_status_bar.xml4
-rw-r--r--indra/newview/skins/default/xui/it/floater_about.xml2
-rw-r--r--indra/newview/skins/default/xui/it/floater_animation_preview.xml148
-rw-r--r--indra/newview/skins/default/xui/it/floater_buy_land.xml12
-rw-r--r--indra/newview/skins/default/xui/it/floater_customize.xml8
-rw-r--r--indra/newview/skins/default/xui/it/floater_hardware_settings.xml20
-rw-r--r--indra/newview/skins/default/xui/it/floater_image_preview.xml40
-rw-r--r--indra/newview/skins/default/xui/it/floater_inventory_item_properties.xml8
-rw-r--r--indra/newview/skins/default/xui/it/floater_postcard.xml4
-rw-r--r--indra/newview/skins/default/xui/it/floater_preview_gesture.xml8
-rw-r--r--indra/newview/skins/default/xui/it/floater_report_abuse.xml144
-rw-r--r--indra/newview/skins/default/xui/it/floater_sell_land.xml20
-rw-r--r--indra/newview/skins/default/xui/it/floater_settings_debug.xml8
-rw-r--r--indra/newview/skins/default/xui/it/floater_snapshot.xml116
-rw-r--r--indra/newview/skins/default/xui/it/floater_tools.xml2
-rw-r--r--indra/newview/skins/default/xui/it/floater_tos.xml2
-rw-r--r--indra/newview/skins/default/xui/it/floater_world_map.xml10
-rw-r--r--indra/newview/skins/default/xui/it/language_settings.xml55
-rw-r--r--indra/newview/skins/default/xui/it/menu_login.xml4
-rw-r--r--indra/newview/skins/default/xui/it/menu_viewer.xml4
-rw-r--r--indra/newview/skins/default/xui/it/notifications.xml93
-rw-r--r--indra/newview/skins/default/xui/it/panel_preferences_chat.xml12
-rw-r--r--indra/newview/skins/default/xui/it/panel_preferences_graphics1.xml68
-rw-r--r--indra/newview/skins/default/xui/it/panel_status_bar.xml4
-rw-r--r--indra/newview/skins/default/xui/it/strings.xml2
-rw-r--r--indra/newview/skins/default/xui/ja/floater_about.xml2
-rw-r--r--indra/newview/skins/default/xui/ja/floater_animation_preview.xml148
-rw-r--r--indra/newview/skins/default/xui/ja/floater_buy_land.xml12
-rw-r--r--indra/newview/skins/default/xui/ja/floater_hardware_settings.xml20
-rw-r--r--indra/newview/skins/default/xui/ja/floater_image_preview.xml40
-rw-r--r--indra/newview/skins/default/xui/ja/floater_inventory_item_properties.xml8
-rw-r--r--indra/newview/skins/default/xui/ja/floater_postcard.xml2
-rw-r--r--indra/newview/skins/default/xui/ja/floater_preview_gesture.xml8
-rw-r--r--indra/newview/skins/default/xui/ja/floater_sell_land.xml12
-rw-r--r--indra/newview/skins/default/xui/ja/floater_settings_debug.xml8
-rw-r--r--indra/newview/skins/default/xui/ja/floater_snapshot.xml120
-rw-r--r--indra/newview/skins/default/xui/ja/floater_sound_preview.xml16
-rw-r--r--indra/newview/skins/default/xui/ja/floater_tools.xml244
-rw-r--r--indra/newview/skins/default/xui/ja/floater_tos.xml8
-rw-r--r--indra/newview/skins/default/xui/ja/floater_world_map.xml10
-rw-r--r--indra/newview/skins/default/xui/ja/language_settings.xml55
-rw-r--r--indra/newview/skins/default/xui/ja/menu_login.xml4
-rw-r--r--indra/newview/skins/default/xui/ja/menu_viewer.xml4
-rw-r--r--indra/newview/skins/default/xui/ja/notifications.xml93
-rw-r--r--indra/newview/skins/default/xui/ja/panel_login.xml12
-rw-r--r--indra/newview/skins/default/xui/ja/panel_preferences_chat.xml12
-rw-r--r--indra/newview/skins/default/xui/ja/panel_preferences_graphics1.xml68
-rw-r--r--indra/newview/skins/default/xui/ja/panel_status_bar.xml4
-rw-r--r--indra/newview/skins/default/xui/nl/floater_about.xml2
-rw-r--r--indra/newview/skins/default/xui/nl/floater_buy_land.xml12
-rw-r--r--indra/newview/skins/default/xui/nl/floater_customize.xml8
-rw-r--r--indra/newview/skins/default/xui/nl/floater_postcard.xml2
-rw-r--r--indra/newview/skins/default/xui/nl/floater_report_abuse.xml144
-rw-r--r--indra/newview/skins/default/xui/nl/floater_sell_land.xml20
-rw-r--r--indra/newview/skins/default/xui/nl/floater_snapshot.xml116
-rw-r--r--indra/newview/skins/default/xui/nl/floater_tos.xml2
-rw-r--r--indra/newview/skins/default/xui/nl/floater_world_map.xml10
-rw-r--r--indra/newview/skins/default/xui/nl/language_settings.xml55
-rw-r--r--indra/newview/skins/default/xui/nl/menu_inventory.xml4
-rw-r--r--indra/newview/skins/default/xui/nl/menu_login.xml4
-rw-r--r--indra/newview/skins/default/xui/nl/menu_viewer.xml4
-rw-r--r--indra/newview/skins/default/xui/nl/notifications.xml89
-rw-r--r--indra/newview/skins/default/xui/nl/panel_login.xml12
-rw-r--r--indra/newview/skins/default/xui/nl/panel_status_bar.xml4
-rw-r--r--indra/newview/skins/default/xui/nl/strings.xml3
-rwxr-xr-xindra/newview/skins/default/xui/pl/floater_about.xml2
-rwxr-xr-xindra/newview/skins/default/xui/pl/floater_buy_land.xml12
-rwxr-xr-xindra/newview/skins/default/xui/pl/floater_god_tools.xml30
-rwxr-xr-xindra/newview/skins/default/xui/pl/floater_hardware_settings.xml20
-rwxr-xr-xindra/newview/skins/default/xui/pl/floater_image_preview.xml40
-rwxr-xr-xindra/newview/skins/default/xui/pl/floater_inventory_item_properties.xml8
-rwxr-xr-xindra/newview/skins/default/xui/pl/floater_postcard.xml4
-rwxr-xr-xindra/newview/skins/default/xui/pl/floater_preview_gesture.xml8
-rwxr-xr-xindra/newview/skins/default/xui/pl/floater_report_abuse.xml144
-rwxr-xr-xindra/newview/skins/default/xui/pl/floater_sell_land.xml20
-rwxr-xr-xindra/newview/skins/default/xui/pl/floater_settings_debug.xml8
-rwxr-xr-xindra/newview/skins/default/xui/pl/floater_snapshot.xml120
-rwxr-xr-xindra/newview/skins/default/xui/pl/floater_tos.xml2
-rwxr-xr-xindra/newview/skins/default/xui/pl/floater_world_map.xml10
-rw-r--r--indra/newview/skins/default/xui/pl/language_settings.xml55
-rwxr-xr-xindra/newview/skins/default/xui/pl/menu_login.xml4
-rwxr-xr-xindra/newview/skins/default/xui/pl/menu_viewer.xml6
-rw-r--r--indra/newview/skins/default/xui/pl/notifications.xml119
-rwxr-xr-xindra/newview/skins/default/xui/pl/panel_login.xml14
-rwxr-xr-xindra/newview/skins/default/xui/pl/panel_preferences_chat.xml12
-rwxr-xr-xindra/newview/skins/default/xui/pl/panel_preferences_graphics1.xml68
-rwxr-xr-xindra/newview/skins/default/xui/pl/panel_status_bar.xml4
-rwxr-xr-xindra/newview/skins/default/xui/pl/strings.xml3
-rw-r--r--indra/newview/skins/default/xui/pt/floater_about.xml2
-rw-r--r--indra/newview/skins/default/xui/pt/floater_animation_preview.xml148
-rw-r--r--indra/newview/skins/default/xui/pt/floater_buy_land.xml12
-rw-r--r--indra/newview/skins/default/xui/pt/floater_customize.xml8
-rw-r--r--indra/newview/skins/default/xui/pt/floater_god_tools.xml24
-rw-r--r--indra/newview/skins/default/xui/pt/floater_hardware_settings.xml20
-rw-r--r--indra/newview/skins/default/xui/pt/floater_image_preview.xml40
-rw-r--r--indra/newview/skins/default/xui/pt/floater_inventory_item_properties.xml8
-rw-r--r--indra/newview/skins/default/xui/pt/floater_postcard.xml4
-rw-r--r--indra/newview/skins/default/xui/pt/floater_preview_gesture.xml8
-rw-r--r--indra/newview/skins/default/xui/pt/floater_report_abuse.xml144
-rw-r--r--indra/newview/skins/default/xui/pt/floater_sell_land.xml20
-rw-r--r--indra/newview/skins/default/xui/pt/floater_settings_debug.xml8
-rw-r--r--indra/newview/skins/default/xui/pt/floater_snapshot.xml120
-rw-r--r--indra/newview/skins/default/xui/pt/floater_tos.xml2
-rw-r--r--indra/newview/skins/default/xui/pt/floater_world_map.xml10
-rw-r--r--indra/newview/skins/default/xui/pt/language_settings.xml55
-rw-r--r--indra/newview/skins/default/xui/pt/menu_login.xml4
-rw-r--r--indra/newview/skins/default/xui/pt/menu_viewer.xml4
-rw-r--r--indra/newview/skins/default/xui/pt/notifications.xml93
-rw-r--r--indra/newview/skins/default/xui/pt/panel_login.xml12
-rw-r--r--indra/newview/skins/default/xui/pt/panel_preferences_chat.xml12
-rw-r--r--indra/newview/skins/default/xui/pt/panel_preferences_graphics1.xml72
-rw-r--r--indra/newview/skins/default/xui/pt/panel_status_bar.xml4
-rw-r--r--indra/newview/skins/paths.xml2
-rw-r--r--indra/newview/tests/llagentaccess_test.cpp137
-rwxr-xr-xindra/newview/viewer_manifest.py124
-rw-r--r--indra/test/CMakeLists.txt8
-rwxr-xr-xindra/test/lldoubledispatch_tut.cpp245
-rw-r--r--indra/test/llhttpclient_tut.cpp4
-rw-r--r--indra/test/llhttpdate_tut.cpp3
-rw-r--r--indra/test/llpermissions_tut.cpp11
-rw-r--r--indra/test/llsaleinfo_tut.cpp15
-rw-r--r--indra/test/llscriptresource_tut.cpp7
-rw-r--r--indra/test/lltimestampcache_tut.cpp7
-rw-r--r--indra/test/lltranscode_tut.cpp7
-rw-r--r--indra/test/test.h5
-rw-r--r--indra/test_apps/llplugintest/CMakeLists.txt342
-rw-r--r--indra/test_apps/llplugintest/bookmarks.txt28
-rw-r--r--indra/test_apps/llplugintest/llmediaplugintest.cpp2145
-rw-r--r--indra/test_apps/llplugintest/llmediaplugintest.h200
-rw-r--r--indra/win_crash_logger/CMakeLists.txt1
-rw-r--r--install.xml152
1855 files changed, 193945 insertions, 66826 deletions
diff --git a/doc/contributions.txt b/doc/contributions.txt
index 28c41debe7..c18d3eb171 100644
--- a/doc/contributions.txt
+++ b/doc/contributions.txt
@@ -44,6 +44,7 @@ Aleric Inglewood
VWR-10001
VWR-10759
VWR-10837
+ VWR-13996
Ales Beaumont
VWR-9352
Alissa Sabre
@@ -275,6 +276,9 @@ Jacek Antonelli
VWR-597
VWR-2054
VWR-2448
+ VWR-2896
+ VWR-2947
+ VWR-2948
VWR-3605
JB Kraft
VWR-5283
diff --git a/etc/message.xml b/etc/message.xml
index b26a4812a8..7ad392d0b5 100644
--- a/etc/message.xml
+++ b/etc/message.xml
@@ -377,7 +377,23 @@
<key>trusted-sender</key>
<boolean>true</boolean>
</map>
+
+ <key>ParcelMediaURLFilter</key>
+ <map>
+ <key>flavor</key>
+ <string>llsd</string>
+ <key>trusted-sender</key>
+ <boolean>false</boolean>
+ </map>
+ <key>ParcelNavigateMedia</key>
+ <map>
+ <key>flavor</key>
+ <string>llsd</string>
+ <key>trusted-sender</key>
+ <boolean>false</boolean>
+ </map>
+
<key>ParcelObjectOwnersReply</key>
<map>
<key>flavor</key>
diff --git a/indra/CMakeLists.txt b/indra/CMakeLists.txt
index 7f4c2c33c1..9418dbf271 100644
--- a/indra/CMakeLists.txt
+++ b/indra/CMakeLists.txt
@@ -1,3 +1,4 @@
+
# -*- cmake -*-
# cmake_minimum_required should appear before any
@@ -42,7 +43,6 @@ add_subdirectory(${LIBS_OPEN_PREFIX}llimage)
add_subdirectory(${LIBS_OPEN_PREFIX}llimagej2coj)
add_subdirectory(${LIBS_OPEN_PREFIX}llinventory)
add_subdirectory(${LIBS_OPEN_PREFIX}llmath)
-add_subdirectory(${LIBS_OPEN_PREFIX}llmedia)
add_subdirectory(${LIBS_OPEN_PREFIX}llmessage)
add_subdirectory(${LIBS_OPEN_PREFIX}llprimitive)
add_subdirectory(${LIBS_OPEN_PREFIX}llrender)
@@ -63,11 +63,22 @@ endif (WINDOWS AND EXISTS ${LIBS_CLOSED_DIR}copy_win_scripts)
add_custom_target(viewer)
if (VIEWER)
add_subdirectory(${LIBS_OPEN_PREFIX}llcrashlogger)
+ add_subdirectory(${LIBS_OPEN_PREFIX}llplugin)
add_subdirectory(${LIBS_OPEN_PREFIX}llui)
+ add_subdirectory(${LIBS_OPEN_PREFIX}llxuixml)
+
+ # viewer media plugins
+ add_subdirectory(${LIBS_OPEN_PREFIX}media_plugins)
+
+ # llplugin testbed code (is this the right way to include it?)
+ if (NOT LINUX)
+ add_subdirectory(${VIEWER_PREFIX}test_apps/llplugintest)
+ endif (NOT LINUX)
if (LINUX)
add_subdirectory(${VIEWER_PREFIX}linux_crash_logger)
- add_dependencies(viewer linux-crash-logger-strip-target)
+ add_subdirectory(${VIEWER_PREFIX}linux_updater)
+ add_dependencies(viewer linux-crash-logger-strip-target linux-updater)
elseif (DARWIN)
add_subdirectory(${VIEWER_PREFIX}mac_crash_logger)
add_subdirectory(${VIEWER_PREFIX}mac_updater)
@@ -110,3 +121,7 @@ if (SERVER)
add_subdirectory(${SERVER_PREFIX}tools)
endif (WINDOWS)
endif (SERVER)
+
+# Define after the custom viewer and server targets are created so individual
+# apps can add themselves as dependencies
+add_subdirectory(${INTEGRATION_TESTS_PREFIX}integration_tests)
diff --git a/indra/cmake/00-Common.cmake b/indra/cmake/00-Common.cmake
index ad7529ea0a..2a70263446 100644
--- a/indra/cmake/00-Common.cmake
+++ b/indra/cmake/00-Common.cmake
@@ -192,7 +192,7 @@ endif (DARWIN)
if (LINUX OR DARWIN)
- set(GCC_WARNINGS "-Wall -Wno-sign-compare -Wno-trigraphs -Wno-non-virtual-dtor")
+ set(GCC_WARNINGS "-Wall -Wno-sign-compare -Wno-trigraphs -Wno-non-virtual-dtor -Woverloaded-virtual")
if (NOT GCC_DISABLE_FATAL_WARNINGS)
set(GCC_WARNINGS "${GCC_WARNINGS} -Werror")
@@ -227,7 +227,6 @@ else (STANDALONE)
glib-2.0
gstreamer-0.10
gtk-2.0
- llfreetype2
pango-1.0
)
endif (STANDALONE)
diff --git a/indra/cmake/CMakeLists.txt b/indra/cmake/CMakeLists.txt
index 658441dab1..3ce393b659 100644
--- a/indra/cmake/CMakeLists.txt
+++ b/indra/cmake/CMakeLists.txt
@@ -34,7 +34,7 @@ set(cmake_SOURCE_FILES
FindXmlRpcEpi.cmake
FMOD.cmake
FreeType.cmake
- GStreamer.cmake
+ GStreamer010Plugin.cmake
GooglePerfTools.cmake
JPEG.cmake
LLAddBuildTest.cmake
@@ -48,8 +48,8 @@ set(cmake_SOURCE_FILES
LLInventory.cmake
LLKDU.cmake
LLMath.cmake
- LLMedia.cmake
LLMessage.cmake
+ LLPlugin.cmake
LLPrimitive.cmake
LLRender.cmake
LLScene.cmake
@@ -60,7 +60,6 @@ set(cmake_SOURCE_FILES
LScript.cmake
Linking.cmake
MonoEmbed.cmake
- Mozlib.cmake
MySQL.cmake
NDOF.cmake
OPENAL.cmake
@@ -70,7 +69,6 @@ set(cmake_SOURCE_FILES
PNG.cmake
Python.cmake
Prebuilt.cmake
- QuickTime.cmake
RunBuildTest.cmake
TemplateCheck.cmake
Tut.cmake
diff --git a/indra/cmake/GStreamer010Plugin.cmake b/indra/cmake/GStreamer010Plugin.cmake
new file mode 100644
index 0000000000..0d334837d4
--- /dev/null
+++ b/indra/cmake/GStreamer010Plugin.cmake
@@ -0,0 +1,39 @@
+# -*- cmake -*-
+include(Prebuilt)
+
+if (STANDALONE)
+ include(FindPkgConfig)
+
+ pkg_check_modules(GSTREAMER010 REQUIRED gstreamer-0.10)
+ pkg_check_modules(GSTREAMER010_PLUGINS_BASE REQUIRED gstreamer-plugins-base-0.10)
+elseif (LINUX)
+ use_prebuilt_binary(gstreamer)
+ # possible libxml should have its own .cmake file instead
+ use_prebuilt_binary(libxml)
+ set(GSTREAMER010_FOUND ON FORCE BOOL)
+ set(GSTREAMER010_PLUGINS_BASE_FOUND ON FORCE BOOL)
+ set(GSTREAMER010_INCLUDE_DIRS
+ ${LIBS_PREBUILT_DIR}/${LL_ARCH_DIR}/include/gstreamer-0.10
+ ${LIBS_PREBUILT_DIR}/${LL_ARCH_DIR}/include/glib-2.0
+ ${LIBS_PREBUILT_DIR}/${LL_ARCH_DIR}/include/libxml2
+ )
+ # We don't need to explicitly link against gstreamer itself, because
+ # LLMediaImplGStreamer probes for the system's copy at runtime.
+ set(GSTREAMER010_LIBRARIES
+ gobject-2.0
+ gmodule-2.0
+ dl
+ gthread-2.0
+ rt
+ glib-2.0
+ )
+endif (STANDALONE)
+
+if (GSTREAMER010_FOUND AND GSTREAMER010_PLUGINS_BASE_FOUND)
+ set(GSTREAMER010 ON CACHE BOOL "Build with GStreamer-0.10 streaming media support.")
+endif (GSTREAMER010_FOUND AND GSTREAMER010_PLUGINS_BASE_FOUND)
+
+if (GSTREAMER010)
+ add_definitions(-DLL_GSTREAMER010_ENABLED=1)
+endif (GSTREAMER010)
+
diff --git a/indra/cmake/Glui.cmake b/indra/cmake/Glui.cmake
new file mode 100644
index 0000000000..f62a56856c
--- /dev/null
+++ b/indra/cmake/Glui.cmake
@@ -0,0 +1,28 @@
+# -*- cmake -*-
+include(Linking)
+include(Prebuilt)
+
+if (STANDALONE)
+ set(GLUI OFF CACHE BOOL
+ "GLUI support for the llplugin/llmedia test apps.")
+else (STANDALONE)
+ use_prebuilt_binary(glui)
+ set(GLUI ON CACHE BOOL
+ "GLUI support for the llplugin/llmedia test apps.")
+endif (STANDALONE)
+
+if (LINUX)
+ set(GLUI ON CACHE BOOL
+ "llplugin media apps HACK for Linux.")
+endif (LINUX)
+
+if (DARWIN OR LINUX)
+ set(GLUI_LIBRARY
+ glui)
+endif (DARWIN OR LINUX)
+
+if (WINDOWS)
+ set(GLUI_LIBRARY
+ debug glui32.lib
+ optimized glui32.lib)
+endif (WINDOWS)
diff --git a/indra/cmake/Glut.cmake b/indra/cmake/Glut.cmake
new file mode 100644
index 0000000000..314da30652
--- /dev/null
+++ b/indra/cmake/Glut.cmake
@@ -0,0 +1,19 @@
+# -*- cmake -*-
+include(Linking)
+include(Prebuilt)
+
+if (WINDOWS)
+ use_prebuilt_binary(freeglut)
+ set(GLUT_LIBRARY
+ debug freeglut_static.lib
+ optimized freeglut_static.lib)
+endif (WINDOWS)
+
+if (LINUX)
+ FIND_LIBRARY(GLUT_LIBRARY glut)
+endif (LINUX)
+
+if (DARWIN)
+ include(CMakeFindFrameworks)
+ find_library(GLUT_LIBRARY GLUT)
+endif (DARWIN)
diff --git a/indra/cmake/GooglePerfTools.cmake b/indra/cmake/GooglePerfTools.cmake
index aff65cb53e..355ecb58f0 100644
--- a/indra/cmake/GooglePerfTools.cmake
+++ b/indra/cmake/GooglePerfTools.cmake
@@ -6,9 +6,11 @@ if (STANDALONE)
else (STANDALONE)
use_prebuilt_binary(google)
if (WINDOWS)
+ use_prebuilt_binary(google-perftools)
set(TCMALLOC_LIBRARIES
debug libtcmalloc_minimal-debug
- optimized libtcmalloc_minimal-debug)
+ optimized libtcmalloc_minimal)
+ set(GOOGLE_PERFTOOLS_FOUND "YES")
endif (WINDOWS)
if (LINUX)
set(TCMALLOC_LIBRARIES tcmalloc)
@@ -27,6 +29,10 @@ endif (GOOGLE_PERFTOOLS_FOUND)
# XXX Disable temporarily, until we have compilation issues on 64-bit
# Etch sorted.
set(USE_GOOGLE_PERFTOOLS OFF)
+if (WINDOWS)
+ # *TODO -reenable this once we get server usage sorted out
+ #set(USE_GOOGLE_PERFTOOLS ON)
+endif (WINDOWS)
if (USE_GOOGLE_PERFTOOLS)
set(TCMALLOC_FLAG -DLL_USE_TCMALLOC=1)
diff --git a/indra/cmake/LLAddBuildTest.cmake b/indra/cmake/LLAddBuildTest.cmake
index 4da0824120..373ad4d4e9 100644
--- a/indra/cmake/LLAddBuildTest.cmake
+++ b/indra/cmake/LLAddBuildTest.cmake
@@ -157,3 +157,79 @@ INCLUDE(GoogleMock)
ADD_DEPENDENCIES(${project} ${project}_tests)
ENDMACRO(LL_ADD_PROJECT_UNIT_TESTS)
+FUNCTION(LL_ADD_INTEGRATION_TEST
+ testname
+ additional_source_files
+ library_dependencies
+# variable args
+ )
+ if(TEST_DEBUG)
+ message(STATUS "Adding INTEGRATION_TEST_${testname} - debug output is on")
+ endif(TEST_DEBUG)
+
+ SET(source_files
+ tests/${testname}_test.cpp
+ ${CMAKE_SOURCE_DIR}/test/test.cpp
+ ${CMAKE_SOURCE_DIR}/test/lltut.cpp
+ ${additional_source_files}
+ )
+
+ SET(libraries
+ ${library_dependencies}
+ ${PTHREAD_LIBRARY}
+ )
+
+ # Add test executable build target
+ if(TEST_DEBUG)
+ message(STATUS "ADD_EXECUTABLE(INTEGRATION_TEST_${testname} ${source_files})")
+ endif(TEST_DEBUG)
+ ADD_EXECUTABLE(INTEGRATION_TEST_${testname} ${source_files})
+
+ # Add link deps to the executable
+ if(TEST_DEBUG)
+ message(STATUS "TARGET_LINK_LIBRARIES(INTEGRATION_TEST_${testname} ${libraries})")
+ endif(TEST_DEBUG)
+ TARGET_LINK_LIBRARIES(INTEGRATION_TEST_${testname} ${libraries})
+
+ # Create the test running command
+ SET(test_command ${ARGN})
+ GET_TARGET_PROPERTY(TEST_EXE INTEGRATION_TEST_${testname} LOCATION)
+ LIST(FIND test_command "{}" test_exe_pos)
+ IF(test_exe_pos LESS 0)
+ # The {} marker means "the full pathname of the test executable."
+ # test_exe_pos -1 means we didn't find it -- so append the test executable
+ # name to $ARGN, the variable part of the arg list. This is convenient
+ # shorthand for both straightforward execution of the test program (empty
+ # $ARGN) and for running a "wrapper" program of some kind accepting the
+ # pathname of the test program as the last of its args. You need specify
+ # {} only if the test program's pathname isn't the last argument in the
+ # desired command line.
+ LIST(APPEND test_command "${TEST_EXE}")
+ ELSE (test_exe_pos LESS 0)
+ # Found {} marker at test_exe_pos. Remove the {}...
+ LIST(REMOVE_AT test_command test_exe_pos)
+ # ...and replace it with the actual name of the test executable.
+ LIST(INSERT test_command test_exe_pos "${TEST_EXE}")
+ ENDIF (test_exe_pos LESS 0)
+
+ SET(TEST_SCRIPT_CMD
+ ${CMAKE_COMMAND}
+ -DLD_LIBRARY_PATH=${ARCH_PREBUILT_DIRS}:/usr/lib
+ -DTEST_CMD:STRING="${test_command}"
+ -P ${CMAKE_SOURCE_DIR}/cmake/RunBuildTest.cmake
+ )
+
+ if(TEST_DEBUG)
+ message(STATUS "TEST_SCRIPT_CMD: ${TEST_SCRIPT_CMD}")
+ endif(TEST_DEBUG)
+
+ ADD_CUSTOM_COMMAND(
+ TARGET INTEGRATION_TEST_${testname}
+ POST_BUILD
+ COMMAND ${TEST_SCRIPT_CMD}
+ )
+
+ # Use CTEST? Not sure how to yet...
+ # ADD_TEST(INTEGRATION_TEST_RUNNER_${testname} ${TEST_SCRIPT_CMD})
+
+ENDFUNCTION(LL_ADD_INTEGRATION_TEST) \ No newline at end of file
diff --git a/indra/cmake/LLCommon.cmake b/indra/cmake/LLCommon.cmake
index 410766e4f9..ef202dd879 100644
--- a/indra/cmake/LLCommon.cmake
+++ b/indra/cmake/LLCommon.cmake
@@ -4,6 +4,7 @@ include(APR)
include(Boost)
include(EXPAT)
include(ZLIB)
+include(GooglePerfTools)
set(LLCOMMON_INCLUDE_DIRS
${LIBS_OPEN_DIR}/llcommon
@@ -13,3 +14,6 @@ set(LLCOMMON_INCLUDE_DIRS
)
set(LLCOMMON_LIBRARIES llcommon)
+
+add_definitions(${TCMALLOC_FLAG})
+
diff --git a/indra/cmake/LLPlugin.cmake b/indra/cmake/LLPlugin.cmake
new file mode 100644
index 0000000000..9722f16c3c
--- /dev/null
+++ b/indra/cmake/LLPlugin.cmake
@@ -0,0 +1,8 @@
+# -*- cmake -*-
+
+
+set(LLPLUGIN_INCLUDE_DIRS
+ ${LIBS_OPEN_DIR}/llplugin
+ )
+
+set(LLPLUGIN_LIBRARIES llplugin)
diff --git a/indra/cmake/LLXUIXML.cmake b/indra/cmake/LLXUIXML.cmake
new file mode 100644
index 0000000000..b8bfe48c77
--- /dev/null
+++ b/indra/cmake/LLXUIXML.cmake
@@ -0,0 +1,7 @@
+# -*- cmake -*-
+
+set(LLXUIXML_INCLUDE_DIRS
+ ${LIBS_OPEN_DIR}/llxuixml
+ )
+
+set(LLXUIXML_LIBRARIES llxuixml)
diff --git a/indra/cmake/Linking.cmake b/indra/cmake/Linking.cmake
index 2bddb95178..eaa8a6dc29 100644
--- a/indra/cmake/Linking.cmake
+++ b/indra/cmake/Linking.cmake
@@ -42,6 +42,7 @@ if (WINDOWS)
wldap32
gdi32
user32
+ dbghelp
)
else (WINDOWS)
set(WINDOWS_LIBRARIES "")
diff --git a/indra/cmake/MediaPluginBase.cmake b/indra/cmake/MediaPluginBase.cmake
new file mode 100644
index 0000000000..2be035b641
--- /dev/null
+++ b/indra/cmake/MediaPluginBase.cmake
@@ -0,0 +1,8 @@
+# -*- cmake -*-
+
+
+set(MEDIA_PLUGIN_BASE_INCLUDE_DIRS
+ ${LIBS_OPEN_DIR}/media_plugins/base/
+ )
+
+set(MEDIA_PLUGIN_BASE_LIBRARIES media_plugin_base)
diff --git a/indra/cmake/PluginAPI.cmake b/indra/cmake/PluginAPI.cmake
new file mode 100644
index 0000000000..d1649e8248
--- /dev/null
+++ b/indra/cmake/PluginAPI.cmake
@@ -0,0 +1,16 @@
+# -*- cmake -*-
+
+if (WINDOWS)
+ set(PLUGIN_API_WINDOWS_LIBRARIES
+ wsock32
+ ws2_32
+ psapi
+ netapi32
+ advapi32
+ user32
+ )
+else (WINDOWS)
+ set(PLUGIN_API_WINDOWS_LIBRARIES "")
+endif (WINDOWS)
+
+
diff --git a/indra/cmake/QuickTimePlugin.cmake b/indra/cmake/QuickTimePlugin.cmake
new file mode 100644
index 0000000000..8afd8f304c
--- /dev/null
+++ b/indra/cmake/QuickTimePlugin.cmake
@@ -0,0 +1,46 @@
+# -*- cmake -*-
+
+if(INSTALL_PROPRIETARY)
+ include(Prebuilt)
+ use_prebuilt_binary(quicktime)
+endif(INSTALL_PROPRIETARY)
+
+if (DARWIN)
+ include(CMakeFindFrameworks)
+ find_library(QUICKTIME_LIBRARY QuickTime)
+elseif (WINDOWS)
+ set(QUICKTIME_SDK_DIR "$ENV{PROGRAMFILES}/QuickTime SDK"
+ CACHE PATH "Location of the QuickTime SDK.")
+
+ find_library(DEBUG_QUICKTIME_LIBRARY qtmlclient
+ PATHS
+ ${ARCH_PREBUILT_DIRS_DEBUG}
+ "${QUICKTIME_SDK_DIR}\\libraries"
+ )
+
+ find_library(RELEASE_QUICKTIME_LIBRARY qtmlclient
+ PATHS
+ ${ARCH_PREBUILT_DIRS_RELEASE}
+ "${QUICKTIME_SDK_DIR}\\libraries"
+ )
+
+ if (DEBUG_QUICKTIME_LIBRARY AND RELEASE_QUICKTIME_LIBRARY)
+ set(QUICKTIME_LIBRARY
+ optimized ${RELEASE_QUICKTIME_LIBRARY}
+ debug ${DEBUG_QUICKTIME_LIBRARY}
+ )
+
+ endif (DEBUG_QUICKTIME_LIBRARY AND RELEASE_QUICKTIME_LIBRARY)
+
+ include_directories(
+ ${LIBS_PREBUILT_DIR}/${LL_ARCH_DIR}/include/quicktime
+ "${QUICKTIME_SDK_DIR}\\CIncludes"
+ )
+endif (DARWIN)
+
+mark_as_advanced(QUICKTIME_LIBRARY)
+
+if (QUICKTIME_LIBRARY)
+ set(QUICKTIME ON CACHE BOOL "Build with QuickTime streaming media support.")
+endif (QUICKTIME_LIBRARY)
+
diff --git a/indra/cmake/Variables.cmake b/indra/cmake/Variables.cmake
index 75b66a85da..6559051b5a 100644
--- a/indra/cmake/Variables.cmake
+++ b/indra/cmake/Variables.cmake
@@ -23,6 +23,7 @@ set(LIBS_SERVER_PREFIX)
set(SCRIPTS_PREFIX ../scripts)
set(SERVER_PREFIX)
set(VIEWER_PREFIX)
+set(INTEGRATION_TESTS_PREFIX)
set(LIBS_CLOSED_DIR ${CMAKE_SOURCE_DIR}/${LIBS_CLOSED_PREFIX})
set(LIBS_OPEN_DIR ${CMAKE_SOURCE_DIR}/${LIBS_OPEN_PREFIX})
diff --git a/indra/cmake/WebKitLibPlugin.cmake b/indra/cmake/WebKitLibPlugin.cmake
new file mode 100644
index 0000000000..9ec23e80ca
--- /dev/null
+++ b/indra/cmake/WebKitLibPlugin.cmake
@@ -0,0 +1,63 @@
+# -*- cmake -*-
+include(Linking)
+include(Prebuilt)
+
+if (STANDALONE)
+ set(WEBKITLIBPLUGIN OFF CACHE BOOL
+ "WEBKITLIBPLUGIN support for the llplugin/llmedia test apps.")
+else (STANDALONE)
+ use_prebuilt_binary(llqtwebkit)
+ set(WEBKITLIBPLUGIN ON CACHE BOOL
+ "WEBKITLIBPLUGIN support for the llplugin/llmedia test apps.")
+endif (STANDALONE)
+
+if (WINDOWS)
+ set(WEBKIT_PLUGIN_LIBRARIES
+ debug llqtwebkitd
+ debug QtWebKitd4
+ debug QtOpenGLd4
+ debug QtNetworkd4
+ debug QtGuid4
+ debug QtCored4
+ debug qtmaind
+ optimized llqtwebkit
+ optimized QtWebKit4
+ optimized QtOpenGL4
+ optimized QtNetwork4
+ optimized QtGui4
+ optimized QtCore4
+ optimized qtmain
+ )
+elseif (DARWIN)
+ set(WEBKIT_PLUGIN_LIBRARIES
+ optimized ${ARCH_PREBUILT_DIRS_RELEASE}/libllqtwebkit.dylib
+ debug ${ARCH_PREBUILT_DIRS_RELEASE}/libllqtwebkit.dylib
+ )
+elseif (LINUX)
+ set(WEBKIT_PLUGIN_LIBRARIES
+ llqtwebkit
+
+ qgif
+# qico
+ qjpeg
+# qpng
+# qtiff
+# qsvg
+
+# QtSvg
+ QtWebKit
+ QtOpenGL
+ QtNetwork
+ QtGui
+ QtCore
+
+ fontconfig
+ X11
+ Xrender
+ GL
+
+# sqlite3
+# Xi
+# SM
+ )
+endif (WINDOWS)
diff --git a/indra/develop.py b/indra/develop.py
index 39bb48dfa5..249b6519fc 100755
--- a/indra/develop.py
+++ b/indra/develop.py
@@ -76,6 +76,7 @@ class PlatformSetup(object):
build_type = build_types['relwithdebinfo']
standalone = 'OFF'
unattended = 'OFF'
+ universal = 'OFF'
project_name = 'SecondLife'
distcc = True
cmake_opts = []
@@ -419,7 +420,7 @@ class DarwinSetup(UnixSetup):
return 'darwin'
def arch(self):
- if self.unattended == 'ON':
+ if self.universal == 'ON':
return 'universal'
else:
return UnixSetup.arch(self)
@@ -433,11 +434,12 @@ class DarwinSetup(UnixSetup):
word_size=self.word_size,
unattended=self.unattended,
project_name=self.project_name,
- universal='',
+ universal=self.universal,
type=self.build_type.upper(),
)
- if self.unattended == 'ON':
+ if self.universal == 'ON':
args['universal'] = '-DCMAKE_OSX_ARCHITECTURES:STRING=\'i386;ppc\''
+ pass
#if simple:
# return 'cmake %(opts)s %(dir)r' % args
return ('cmake -G %(generator)r '
@@ -676,6 +678,7 @@ Options:
--standalone build standalone, without Linden prebuild libraries
--unattended build unattended, do not invoke any tools requiring
a human response
+ --universal build a universal binary on Mac OS X (unsupported)
-t | --type=NAME build type ("Debug", "Release", or "RelWithDebInfo")
-m32 | -m64 build architecture (32-bit or 64-bit)
-N | --no-distcc disable use of distcc
@@ -721,7 +724,7 @@ def main(arguments):
opts, args = getopt.getopt(
arguments,
'?hNt:p:G:m:',
- ['help', 'standalone', 'no-distcc', 'unattended', 'type=', 'incredibuild', 'generator=', 'project='])
+ ['help', 'standalone', 'no-distcc', 'unattended', 'universal', 'type=', 'incredibuild', 'generator=', 'project='])
except getopt.GetoptError, err:
print >> sys.stderr, 'Error:', err
print >> sys.stderr, """
@@ -738,6 +741,8 @@ For example: develop.py configure -DSERVER:BOOL=OFF"""
setup.standalone = 'ON'
elif o in ('--unattended',):
setup.unattended = 'ON'
+ elif o in ('--universal',):
+ setup.universal = 'ON'
elif o in ('-m',):
if a in ('32', '64'):
setup.word_size = int(a)
diff --git a/indra/integration_tests/CMakeLists.txt b/indra/integration_tests/CMakeLists.txt
new file mode 100644
index 0000000000..67e8fbf1f2
--- /dev/null
+++ b/indra/integration_tests/CMakeLists.txt
@@ -0,0 +1,3 @@
+# -*- cmake -*-
+
+add_subdirectory(llui_libtest)
diff --git a/indra/integration_tests/llui_libtest/CMakeLists.txt b/indra/integration_tests/llui_libtest/CMakeLists.txt
new file mode 100644
index 0000000000..1ccdb0f20b
--- /dev/null
+++ b/indra/integration_tests/llui_libtest/CMakeLists.txt
@@ -0,0 +1,103 @@
+# -*- cmake -*-
+
+# Only set this up for viewer builds, because the llui library is most closely
+# related to the viewer
+if (VIEWER)
+
+project (llui_libtest)
+
+include(00-Common)
+include(LLCommon)
+include(LLImage)
+include(LLImageJ2COJ) # ugh, needed for images
+include(LLMath)
+include(LLRender)
+include(LLWindow)
+include(LLUI)
+include(LLVFS) # ugh, needed for LLDir
+include(LLXML)
+include(LLXUIXML)
+include(Linking)
+# include(Tut)
+
+include_directories(
+ ${FREETYPE_INCLUDE_DIRS}
+ ${LLCOMMON_INCLUDE_DIRS}
+ ${LLIMAGE_INCLUDE_DIRS}
+ ${LLMATH_INCLUDE_DIRS}
+ ${LLRENDER_INCLUDE_DIRS}
+ ${LLUI_INCLUDE_DIRS}
+ ${LLVFS_INCLUDE_DIRS}
+ ${LLWINDOW_INCLUDE_DIRS}
+ ${LLXML_INCLUDE_DIRS}
+ ${LLXUIXML_INCLUDE_DIRS}
+ )
+
+set(llui_libtest_SOURCE_FILES
+ llui_libtest.cpp
+ llwidgetreg.cpp
+ )
+
+set(llui_libtest_HEADER_FILES
+ CMakeLists.txt
+ llui_libtest.h
+ llwidgetreg.h
+ )
+
+set_source_files_properties(${llui_libtest_HEADER_FILES}
+ PROPERTIES HEADER_FILE_ONLY TRUE)
+
+list(APPEND llui_libtest_SOURCE_FILES ${llui_libtest_HEADER_FILES})
+
+add_executable(llui_libtest ${llui_libtest_SOURCE_FILES})
+
+# Link with OS-specific libraries for LLWindow dependency
+if (DARWIN)
+ find_library(COCOA_LIBRARY Cocoa)
+ set(OS_LIBRARIES ${COCOA_LIBRARY})
+elseif (WINDOWS)
+ set(OS_LIBRARIES ${WINDOWS_LIBRARIES})
+elseif (LINUX)
+ set(OS_LIBRARIES)
+else (DARWIN)
+ message(FATAL_ERROR "unknown platform")
+endif (DARWIN)
+
+# Libraries on which this library depends, needed for Linux builds
+# Sort by high-level to low-level
+target_link_libraries(llui_libtest
+ llui
+ ${OS_LIBRARIES}
+ ${GOOGLE_PERFTOOLS_LIBRARIES}
+ )
+
+if (WINDOWS)
+ set_target_properties(llui_libtest
+ PROPERTIES
+ LINK_FLAGS "/NODEFAULTLIB:LIBCMT"
+ LINK_FLAGS_DEBUG "/NODEFAULTLIB:MSVCRT /NODEFAULTLIB:LIBCMTD"
+ )
+
+ # Copy over OpenJPEG.dll
+ # *NOTE: On Windows with VS2005, only the first comment prints
+ set(OPENJPEG_RELEASE
+ "${CMAKE_SOURCE_DIR}/../libraries/i686-win32/lib/release/openjpeg.dll")
+ add_custom_command( TARGET llui_libtest POST_BUILD
+ COMMAND ${CMAKE_COMMAND} -E copy_if_different
+ ${OPENJPEG_RELEASE} ${CMAKE_CURRENT_BINARY_DIR}
+ COMMENT "Copying OpenJPEG DLLs to binary directory"
+ )
+ set(OPENJPEG_DEBUG
+ "${CMAKE_SOURCE_DIR}/../libraries/i686-win32/lib/debug/openjpegd.dll")
+ add_custom_command( TARGET llui_libtest POST_BUILD
+ COMMAND ${CMAKE_COMMAND} -E copy_if_different
+ ${OPENJPEG_DEBUG} ${CMAKE_CURRENT_BINARY_DIR}
+ )
+endif (WINDOWS)
+
+# Ensure people working on the viewer don't break this library
+# *NOTE: This could be removed, or only built by Parabuild, if the build
+# and link times become too long. JC
+add_dependencies(viewer llui_libtest)
+
+endif (VIEWER)
diff --git a/indra/integration_tests/llui_libtest/llui_libtest.cpp b/indra/integration_tests/llui_libtest/llui_libtest.cpp
new file mode 100644
index 0000000000..3631761c93
--- /dev/null
+++ b/indra/integration_tests/llui_libtest/llui_libtest.cpp
@@ -0,0 +1,221 @@
+/**
+ * @file llui_libtest.cpp
+ * @brief Integration test for the LLUI library
+ *
+ * $LicenseInfo:firstyear=2009&license=viewergpl$
+ *
+ * Copyright (c) 2002-2009, Linden Research, Inc.
+ *
+ * Second Life Viewer Source Code
+ * The source code in this file ("Source Code") is provided by Linden Lab
+ * to you under the terms of the GNU General Public License, version 2.0
+ * ("GPL"), unless you have obtained a separate licensing agreement
+ * ("Other License"), formally executed by you and Linden Lab. Terms of
+ * the GPL can be found in doc/GPL-license.txt in this distribution, or
+ * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
+ *
+ * There are special exceptions to the terms and conditions of the GPL as
+ * it is applied to this Source Code. View the full text of the exception
+ * in the file doc/FLOSS-exception.txt in this software distribution, or
+ * online at
+ * http://secondlifegrid.net/programs/open_source/licensing/flossexception
+ *
+ * By copying, modifying or distributing this software, you acknowledge
+ * that you have read and understood your obligations described above,
+ * and agree to abide by those obligations.
+ *
+ * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+ * COMPLETENESS OR PERFORMANCE.
+ * $/LicenseInfo$
+ */
+#include "linden_common.h"
+
+#include "llui_libtest.h"
+
+// project includes
+#include "llwidgetreg.h"
+
+// linden library includes
+#include "llcontrol.h" // LLControlGroup
+#include "lldir.h"
+#include "llerrorcontrol.h"
+#include "llfloater.h"
+#include "llfontfreetype.h"
+#include "llfontgl.h"
+#include "lltransutil.h"
+#include "llui.h"
+#include "lluictrlfactory.h"
+
+#include <iostream>
+
+// *TODO: switch to using TUT
+// *TODO: teach Parabuild about this program, run automatically after full builds
+
+// I believe these must be globals, not stack variables. JC
+LLControlGroup gSavedSettings("Global"); // saved at end of session
+LLControlGroup gSavedPerAccountSettings("PerAccount"); // saved at end of session
+LLControlGroup gWarningSettings("Warnings"); // persists ignored dialogs/warnings
+
+// We can't create LLImageGL objects because we have no window or rendering
+// context. Provide enough of an LLUIImage to test the LLUI library without
+// an underlying image.
+class TestUIImage : public LLUIImage
+{
+public:
+ TestUIImage()
+ : LLUIImage( std::string(), NULL ) // NULL ImageGL, don't deref!
+ { }
+
+ /*virtual*/ S32 getWidth() const
+ {
+ return 16;
+ }
+
+ /*virtual*/ S32 getHeight() const
+ {
+ return 16;
+ }
+};
+
+
+class LLTexture ;
+// We need to supply dummy images
+class TestImageProvider : public LLImageProviderInterface
+{
+public:
+ /*virtual*/ LLPointer<LLUIImage> getUIImage(const std::string& name)
+ {
+ return makeImage();
+ }
+
+ /*virtual*/ LLPointer<LLUIImage> getUIImageByID(const LLUUID& id)
+ {
+ return makeImage();
+ }
+
+ /*virtual*/ void cleanUp()
+ {
+ }
+
+ LLPointer<LLUIImage> makeImage()
+ {
+ LLPointer<LLTexture> image_gl;
+ LLPointer<LLUIImage> image = new TestUIImage(); //LLUIImage( std::string(), image_gl);
+ mImageList.push_back(image);
+ return image;
+ }
+
+public:
+ // Unclear if we need this, hold on to one copy of each image we make
+ std::vector<LLPointer<LLUIImage> > mImageList;
+};
+TestImageProvider gTestImageProvider;
+
+static std::string get_xui_dir()
+{
+ std::string delim = gDirUtilp->getDirDelimiter();
+ return gDirUtilp->getSkinBaseDir() + delim + "default" + delim + "xui" + delim;
+}
+
+void init_llui()
+{
+ // Font lookup needs directory support
+#if LL_DARWIN
+ const char* newview_path = "../../../../newview";
+#else
+ const char* newview_path = "../../../newview";
+#endif
+ gDirUtilp->initAppDirs("SecondLife", newview_path);
+ gDirUtilp->setSkinFolder("default");
+
+ // colors are no longer stored in a LLControlGroup file
+ LLUIColorTable::instance().loadFromSettings();
+
+ std::string config_filename = gDirUtilp->getExpandedFilename(
+ LL_PATH_APP_SETTINGS, "settings.xml");
+ gSavedSettings.loadFromFile(config_filename);
+
+ // See LLAppViewer::init()
+ LLUI::settings_map_t settings;
+ settings["config"] = &gSavedSettings;
+ settings["ignores"] = &gWarningSettings;
+ settings["floater"] = &gSavedSettings;
+ settings["account"] = &gSavedPerAccountSettings;
+
+ // Don't use real images as we don't have a GL context
+ LLUI::initClass(settings, &gTestImageProvider);
+
+ const bool no_register_widgets = false;
+ LLWidgetReg::initClass( no_register_widgets );
+
+ // Unclear if this is needed
+ LLUI::setupPaths();
+ // Otherwise we get translation warnings when setting up floaters
+ // (tooltips for buttons)
+ std::set<std::string> default_args;
+ LLTransUtil::parseStrings("strings.xml", default_args);
+ LLTransUtil::parseLanguageStrings("language_settings.xml");
+ LLFontManager::initClass();
+
+ // Creating widgets apparently requires fonts to be initialized,
+ // otherwise it crashes.
+ LLFontGL::initClass(96.f, 1.f, 1.f,
+ gDirUtilp->getAppRODataDir(),
+ LLUI::getXUIPaths(),
+ false ); // don't create gl textures
+
+ LLFloaterView::Params fvparams;
+ fvparams.name("Floater View");
+ fvparams.rect( LLRect(0,480,640,0) );
+ fvparams.mouse_opaque(false);
+ fvparams.follows.flags(FOLLOWS_ALL);
+ fvparams.tab_stop(false);
+ gFloaterView = LLUICtrlFactory::create<LLFloaterView> (fvparams);
+}
+
+void export_test_floaters()
+{
+ // Convert all test floaters to new XML format
+ std::string delim = gDirUtilp->getDirDelimiter();
+ std::string xui_dir = get_xui_dir() + "en" + delim;
+ std::string filename;
+ while (gDirUtilp->getNextFileInDir(xui_dir, "floater_test_*.xml", filename, false))
+ {
+ if (filename.find("_new.xml") != std::string::npos)
+ {
+ // don't re-export other test floaters
+ continue;
+ }
+ llinfos << "Converting " << filename << llendl;
+ // Build a floater and output new attributes
+ LLXMLNodePtr output_node = new LLXMLNode();
+ LLFloater* floater = new LLFloater(LLSD());
+ LLUICtrlFactory::getInstance()->buildFloater(floater,
+ filename,
+ // FALSE, // don't open floater
+ output_node);
+ std::string out_filename = xui_dir + filename;
+ std::string::size_type extension_pos = out_filename.rfind(".xml");
+ out_filename.resize(extension_pos);
+ out_filename += "_new.xml";
+
+ llinfos << "Output: " << out_filename << llendl;
+ LLFILE* floater_file = LLFile::fopen(out_filename.c_str(), "w");
+ LLXMLNode::writeHeaderToFile(floater_file);
+ output_node->writeToFile(floater_file);
+ fclose(floater_file);
+ }
+}
+
+int main(int argc, char** argv)
+{
+ // Must init LLError for llerrs to actually cause errors.
+ LLError::initForApplication(".");
+
+ init_llui();
+
+ export_test_floaters();
+
+ return 0;
+}
diff --git a/indra/integration_tests/llui_libtest/llui_libtest.h b/indra/integration_tests/llui_libtest/llui_libtest.h
new file mode 100644
index 0000000000..a84d57dba9
--- /dev/null
+++ b/indra/integration_tests/llui_libtest/llui_libtest.h
@@ -0,0 +1,36 @@
+/**
+ * @file llui_libtest.h
+ *
+ * $LicenseInfo:firstyear=2009&license=viewergpl$
+ *
+ * Copyright (c) 2002-2009, Linden Research, Inc.
+ *
+ * Second Life Viewer Source Code
+ * The source code in this file ("Source Code") is provided by Linden Lab
+ * to you under the terms of the GNU General Public License, version 2.0
+ * ("GPL"), unless you have obtained a separate licensing agreement
+ * ("Other License"), formally executed by you and Linden Lab. Terms of
+ * the GPL can be found in doc/GPL-license.txt in this distribution, or
+ * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
+ *
+ * There are special exceptions to the terms and conditions of the GPL as
+ * it is applied to this Source Code. View the full text of the exception
+ * in the file doc/FLOSS-exception.txt in this software distribution, or
+ * online at
+ * http://secondlifegrid.net/programs/open_source/licensing/flossexception
+ *
+ * By copying, modifying or distributing this software, you acknowledge
+ * that you have read and understood your obligations described above,
+ * and agree to abide by those obligations.
+ *
+ * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+ * COMPLETENESS OR PERFORMANCE.
+ * $/LicenseInfo$
+ */
+#ifndef LLUI_LIBTEST_H
+#define LLUI_LIBTEST_H
+
+// TODO
+
+#endif
diff --git a/indra/integration_tests/llui_libtest/llwidgetreg.cpp b/indra/integration_tests/llui_libtest/llwidgetreg.cpp
new file mode 100644
index 0000000000..5a97f2aefd
--- /dev/null
+++ b/indra/integration_tests/llui_libtest/llwidgetreg.cpp
@@ -0,0 +1,108 @@
+/**
+ * @file llwidgetreg.cpp
+ *
+ * $LicenseInfo:firstyear=2009&license=viewergpl$
+ *
+ * Copyright (c) 2002-2009, Linden Research, Inc.
+ *
+ * Second Life Viewer Source Code
+ * The source code in this file ("Source Code") is provided by Linden Lab
+ * to you under the terms of the GNU General Public License, version 2.0
+ * ("GPL"), unless you have obtained a separate licensing agreement
+ * ("Other License"), formally executed by you and Linden Lab. Terms of
+ * the GPL can be found in doc/GPL-license.txt in this distribution, or
+ * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
+ *
+ * There are special exceptions to the terms and conditions of the GPL as
+ * it is applied to this Source Code. View the full text of the exception
+ * in the file doc/FLOSS-exception.txt in this software distribution, or
+ * online at
+ * http://secondlifegrid.net/programs/open_source/licensing/flossexception
+ *
+ * By copying, modifying or distributing this software, you acknowledge
+ * that you have read and understood your obligations described above,
+ * and agree to abide by those obligations.
+ *
+ * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+ * COMPLETENESS OR PERFORMANCE.
+ * $/LicenseInfo$
+ */
+#include "linden_common.h"
+
+#include "llwidgetreg.h"
+
+#include "llbutton.h"
+#include "llcheckboxctrl.h"
+#include "llcombobox.h"
+#include "llcontainerview.h"
+#include "lliconctrl.h"
+#include "llmenugl.h"
+#include "llmultislider.h"
+#include "llmultisliderctrl.h"
+#include "llprogressbar.h"
+#include "llradiogroup.h"
+#include "llsearcheditor.h"
+#include "llscrollcontainer.h"
+#include "llscrollingpanellist.h"
+#include "llscrolllistctrl.h"
+#include "llslider.h"
+#include "llsliderctrl.h"
+#include "llspinctrl.h"
+#include "llstatview.h"
+#include "lltabcontainer.h"
+#include "lltextbox.h"
+#include "lltexteditor.h"
+#include "llflyoutbutton.h"
+#include "llfiltereditor.h"
+#include "lllayoutstack.h"
+
+void LLWidgetReg::initClass(bool register_widgets)
+{
+ // Only need to register if the Windows linker has optimized away the
+ // references to the object files.
+ if (register_widgets)
+ {
+ LLDefaultChildRegistry::Register<LLButton> button("button");
+ LLDefaultChildRegistry::Register<LLCheckBoxCtrl> check_box("check_box");
+ LLDefaultChildRegistry::Register<LLComboBox> combo_box("combo_box");
+ LLDefaultChildRegistry::Register<LLFilterEditor> filter_editor("filter_editor");
+ LLDefaultChildRegistry::Register<LLFlyoutButton> flyout_button("flyout_button");
+ LLDefaultChildRegistry::Register<LLContainerView> container_view("container_view");
+ LLDefaultChildRegistry::Register<LLIconCtrl> icon("icon");
+ LLDefaultChildRegistry::Register<LLLineEditor> line_editor("line_editor");
+ LLDefaultChildRegistry::Register<LLMenuItemSeparatorGL> menu_item_separator("menu_item_separator");
+ LLDefaultChildRegistry::Register<LLMenuItemCallGL> menu_item_call_gl("menu_item_call");
+ LLDefaultChildRegistry::Register<LLMenuItemCheckGL> menu_item_check_gl("menu_item_check");
+ LLDefaultChildRegistry::Register<LLMenuGL> menu("menu");
+ LLDefaultChildRegistry::Register<LLMenuBarGL> menu_bar("menu_bar");
+ LLDefaultChildRegistry::Register<LLContextMenu> context_menu("context_menu");
+ LLDefaultChildRegistry::Register<LLMultiSlider> multi_slider_bar("multi_slider_bar");
+ LLDefaultChildRegistry::Register<LLMultiSliderCtrl> multi_slider("multi_slider");
+ LLDefaultChildRegistry::Register<LLPanel> panel("panel", &LLPanel::fromXML);
+ LLDefaultChildRegistry::Register<LLLayoutStack> layout_stack("layout_stack", &LLLayoutStack::fromXML);
+ LLDefaultChildRegistry::Register<LLProgressBar> progress_bar("progress_bar");
+ LLDefaultChildRegistry::Register<LLRadioGroup> radio_group("radio_group");
+ LLDefaultChildRegistry::Register<LLRadioCtrl> radio_item("radio_item");
+ LLDefaultChildRegistry::Register<LLSearchEditor> search_editor("search_editor");
+ LLDefaultChildRegistry::Register<LLScrollContainer> scroll_container("scroll_container");
+ LLDefaultChildRegistry::Register<LLScrollingPanelList> scrolling_panel_list("scrolling_panel_list");
+ LLDefaultChildRegistry::Register<LLScrollListCtrl> scroll_list("scroll_list");
+ LLDefaultChildRegistry::Register<LLSlider> slider_bar("slider_bar");
+ LLDefaultChildRegistry::Register<LLSliderCtrl> slider("slider");
+ LLDefaultChildRegistry::Register<LLSpinCtrl> spinner("spinner");
+ LLDefaultChildRegistry::Register<LLStatBar> stat_bar("stat_bar");
+ //LLDefaultChildRegistry::Register<LLPlaceHolderPanel> placeholder("placeholder");
+ LLDefaultChildRegistry::Register<LLTabContainer> tab_container("tab_container");
+ LLDefaultChildRegistry::Register<LLTextBox> text("text");
+ LLDefaultChildRegistry::Register<LLTextEditor> simple_text_editor("simple_text_editor");
+ LLDefaultChildRegistry::Register<LLUICtrl> ui_ctrl("ui_ctrl");
+ LLDefaultChildRegistry::Register<LLStatView> stat_view("stat_view");
+ //LLDefaultChildRegistry::Register<LLUICtrlLocate> locate("locate");
+ //LLDefaultChildRegistry::Register<LLUICtrlLocate> pad("pad");
+ LLDefaultChildRegistry::Register<LLViewBorder> view_border("view_border");
+ }
+
+ // *HACK: Usually this is registered as a viewer text editor
+ LLDefaultChildRegistry::Register<LLTextEditor> text_editor("text_editor");
+}
diff --git a/indra/integration_tests/llui_libtest/llwidgetreg.h b/indra/integration_tests/llui_libtest/llwidgetreg.h
new file mode 100644
index 0000000000..4e0bc5377a
--- /dev/null
+++ b/indra/integration_tests/llui_libtest/llwidgetreg.h
@@ -0,0 +1,43 @@
+/**
+ * @file llwidgetreg.h
+ *
+ * $LicenseInfo:firstyear=2009&license=viewergpl$
+ *
+ * Copyright (c) 2002-2009, Linden Research, Inc.
+ *
+ * Second Life Viewer Source Code
+ * The source code in this file ("Source Code") is provided by Linden Lab
+ * to you under the terms of the GNU General Public License, version 2.0
+ * ("GPL"), unless you have obtained a separate licensing agreement
+ * ("Other License"), formally executed by you and Linden Lab. Terms of
+ * the GPL can be found in doc/GPL-license.txt in this distribution, or
+ * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
+ *
+ * There are special exceptions to the terms and conditions of the GPL as
+ * it is applied to this Source Code. View the full text of the exception
+ * in the file doc/FLOSS-exception.txt in this software distribution, or
+ * online at
+ * http://secondlifegrid.net/programs/open_source/licensing/flossexception
+ *
+ * By copying, modifying or distributing this software, you acknowledge
+ * that you have read and understood your obligations described above,
+ * and agree to abide by those obligations.
+ *
+ * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+ * COMPLETENESS OR PERFORMANCE.
+ * $/LicenseInfo$
+ */
+#ifndef LLWIDGETREG_H
+#define LLWIDGETREG_H
+
+// Register all widgets with the builder registry.
+// Useful on Windows where linker discards all references to the
+// static LLDefaultChildRegistry::Register<> calls.
+class LLWidgetReg
+{
+public:
+ static void initClass(bool register_widgets);
+};
+
+#endif
diff --git a/indra/linux_updater/CMakeLists.txt b/indra/linux_updater/CMakeLists.txt
new file mode 100644
index 0000000000..9fe32ecb46
--- /dev/null
+++ b/indra/linux_updater/CMakeLists.txt
@@ -0,0 +1,58 @@
+# -*- cmake -*-
+
+project(linux_updater)
+
+include(00-Common)
+include(CURL)
+include(CARes)
+include(OpenSSL)
+include(UI)
+include(LLCommon)
+include(LLVFS)
+include(LLXML)
+include(LLXUIXML)
+include(Linking)
+
+include_directories(
+ ${LLCOMMON_INCLUDE_DIRS}
+ ${LLVFS_INCLUDE_DIRS}
+ ${LLXML_INCLUDE_DIRS}
+ ${LLXUIXML_INCLUDE_DIRS}
+ ${CURL_INCLUDE_DIRS}
+ ${CARES_INCLUDE_DIRS}
+ ${OPENSSL_INCLUDE_DIRS}
+ ${UI_INCLUDE_DIRS}
+ )
+
+set(linux_updater_SOURCE_FILES linux_updater.cpp)
+
+set(linux_updater_HEADER_FILES CMakeLists.txt)
+
+set_source_files_properties(${linux_updater_HEADER_FILES}
+ PROPERTIES HEADER_FILES_ONLY TRUE)
+
+list(APPEND linux_updater_SOURCE_FILES ${linux_updater_HEADER_FILES})
+
+add_executable(linux-updater ${linux_updater_SOURCE_FILES})
+
+target_link_libraries(linux-updater
+ ${CURL_LIBRARIES}
+ ${CARES_LIBRARIES}
+ ${OPENSSL_LIBRARIES}
+ ${CRYPTO_LIBRARIES}
+ ${UI_LIBRARIES}
+ ${LLXML_LIBRARIES}
+ ${LLXUIXML_LIBRARIES}
+ ${LLVFS_LIBRARIES}
+ ${LLCOMMON_LIBRARIES}
+ )
+
+add_custom_command(
+ OUTPUT linux-updater-stripped
+ COMMAND strip
+ ARGS --strip-debug -o linux-updater-stripped linux-updater
+ DEPENDS linux-updater
+ )
+
+add_custom_target(linux-updater-strip-target ALL
+ DEPENDS linux-updater-stripped)
diff --git a/indra/linux_updater/linux_updater.cpp b/indra/linux_updater/linux_updater.cpp
new file mode 100644
index 0000000000..b93890ab32
--- /dev/null
+++ b/indra/linux_updater/linux_updater.cpp
@@ -0,0 +1,818 @@
+/**
+ * @file linux_updater.cpp
+ * @author Kyle Ambroff <ambroff@lindenlab.com>, Tofu Linden
+ * @brief Viewer update program for unix platforms that support GTK+
+ *
+ * $LicenseInfo:firstyear=2008&license=viewergpl$
+ *
+ * Copyright (c) 2008, Linden Research, Inc.
+ *
+ * Second Life Viewer Source Code
+ * The source code in this file ("Source Code") is provided by Linden Lab
+ * to you under the terms of the GNU General Public License, version 2.0
+ * ("GPL"), unless you have obtained a separate licensing agreement
+ * ("Other License"), formally executed by you and Linden Lab. Terms of
+ * the GPL can be found in doc/GPL-license.txt in this distribution, or
+ * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
+ *
+ * There are special exceptions to the terms and conditions of the GPL as
+ * it is applied to this Source Code. View the full text of the exception
+ * in the file doc/FLOSS-exception.txt in this software distribution, or
+ * online at http://secondlifegrid.net/programs/open_source/licensing/flossexception
+ *
+ * By copying, modifying or distributing this software, you acknowledge
+ * that you have read and understood your obligations described above,
+ * and agree to abide by those obligations.
+ *
+ * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+ * COMPLETENESS OR PERFORMANCE.
+ * $/LicenseInfo$
+ */
+
+#include <unistd.h>
+#include <signal.h>
+#include <errno.h>
+
+#include "linden_common.h"
+#include "llerrorcontrol.h"
+#include "llfile.h"
+#include "lldir.h"
+#include "llxmlnode.h"
+#include "lltrans.h"
+
+#include <curl/curl.h>
+
+extern "C" {
+#include <gtk/gtk.h>
+}
+
+const guint UPDATE_PROGRESS_TIMEOUT = 100;
+const guint UPDATE_PROGRESS_TEXT_TIMEOUT = 1000;
+const guint ROTATE_IMAGE_TIMEOUT = 8000;
+
+typedef struct _updater_app_state {
+ std::string app_name;
+ std::string url;
+ std::string image_dir;
+ std::string dest_dir;
+ std::string strings_dirs;
+ std::string strings_file;
+
+ GtkWidget *window;
+ GtkWidget *progress_bar;
+ GtkWidget *image;
+
+ double progress_value;
+ bool activity_mode;
+
+ guint image_rotation_timeout_id;
+ guint progress_update_timeout_id;
+ guint update_progress_text_timeout_id;
+
+ bool failure;
+} UpdaterAppState;
+
+// List of entries from strings.xml to always replace
+static std::set<std::string> default_trans_args;
+void init_default_trans_args()
+{
+ default_trans_args.insert("SECOND_LIFE"); // World
+ default_trans_args.insert("SECOND_LIFE_VIEWER");
+ default_trans_args.insert("SECOND_LIFE_GRID");
+ default_trans_args.insert("SECOND_LIFE_SUPPORT");
+}
+
+bool translate_init(std::string comma_delim_path_list,
+ std::string base_xml_name)
+{
+ init_default_trans_args();
+
+ // extract paths string vector from comma-delimited flat string
+ std::vector<std::string> paths;
+ LLStringUtil::getTokens(comma_delim_path_list, paths); // split over ','
+
+ // suck the translation xml files into memory
+ LLXMLNodePtr root;
+ bool success = LLXMLNode::getLayeredXMLNode(base_xml_name, root, paths);
+ if (!success)
+ {
+ // couldn't load string table XML
+ return false;
+ }
+ else
+ {
+ // get those strings out of the XML
+ LLTrans::parseStrings(root, default_trans_args);
+ return true;
+ }
+}
+
+
+void updater_app_ui_init(void);
+void updater_app_quit(UpdaterAppState *app_state);
+void parse_args_and_init(int argc, char **argv, UpdaterAppState *app_state);
+std::string next_image_filename(std::string& image_path);
+void display_error(GtkWidget *parent, std::string title, std::string message);
+BOOL install_package(std::string package_file, std::string destination);
+BOOL spawn_viewer(UpdaterAppState *app_state);
+
+extern "C" {
+ void on_window_closed(GtkWidget *sender, gpointer state);
+ gpointer worker_thread_cb(gpointer *data);
+ int download_progress_cb(gpointer data, double t, double d, double utotal, double ulnow);
+ gboolean rotate_image_cb(gpointer data);
+ gboolean progress_update_timeout(gpointer data);
+ gboolean update_progress_text_timeout(gpointer data);
+}
+
+void updater_app_ui_init(UpdaterAppState *app_state)
+{
+ GtkWidget *vbox;
+ GtkWidget *summary_label;
+ GtkWidget *description_label;
+ GtkWidget *frame;
+
+ llassert(app_state != NULL);
+
+ // set up window and main container
+ std::string window_title = LLTrans::getString("UpdaterWindowTitle");
+ app_state->window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
+ gtk_window_set_title(GTK_WINDOW(app_state->window),
+ window_title.c_str());
+ gtk_window_set_resizable(GTK_WINDOW(app_state->window), FALSE);
+ gtk_window_set_position(GTK_WINDOW(app_state->window),
+ GTK_WIN_POS_CENTER_ALWAYS);
+
+ gtk_container_set_border_width(GTK_CONTAINER(app_state->window), 12);
+ g_signal_connect(G_OBJECT(app_state->window), "delete-event",
+ G_CALLBACK(on_window_closed), app_state);
+
+ vbox = gtk_vbox_new(FALSE, 6);
+ gtk_container_add(GTK_CONTAINER(app_state->window), vbox);
+
+ // set top label
+ std::ostringstream label_ostr;
+ label_ostr << "<big><b>"
+ << LLTrans::getString("UpdaterNowUpdating")
+ << "</b></big>";
+
+ summary_label = gtk_label_new(NULL);
+ gtk_label_set_use_markup(GTK_LABEL(summary_label), TRUE);
+ gtk_label_set_markup(GTK_LABEL(summary_label),
+ label_ostr.str().c_str());
+ gtk_misc_set_alignment(GTK_MISC(summary_label), 0, 0.5);
+ gtk_box_pack_start(GTK_BOX(vbox), summary_label, FALSE, FALSE, 0);
+
+ // create the description label
+ description_label = gtk_label_new(LLTrans::getString("UpdaterUpdatingDescriptive").c_str());
+ gtk_label_set_line_wrap(GTK_LABEL(description_label), TRUE);
+ gtk_misc_set_alignment(GTK_MISC(description_label), 0, 0.5);
+ gtk_box_pack_start(GTK_BOX(vbox), description_label, FALSE, FALSE, 0);
+
+ // If an image path has been set, load the background images
+ if (!app_state->image_dir.empty()) {
+ frame = gtk_frame_new(NULL);
+ gtk_frame_set_shadow_type(GTK_FRAME(frame), GTK_SHADOW_IN);
+ gtk_box_pack_start(GTK_BOX(vbox), frame, TRUE, TRUE, 0);
+
+ // load the first image
+ app_state->image = gtk_image_new_from_file
+ (next_image_filename(app_state->image_dir).c_str());
+ gtk_widget_set_size_request(app_state->image, 340, 310);
+ gtk_container_add(GTK_CONTAINER(frame), app_state->image);
+
+ // rotate the images every 5 seconds
+ app_state->image_rotation_timeout_id = g_timeout_add
+ (ROTATE_IMAGE_TIMEOUT, rotate_image_cb, app_state);
+ }
+
+ // set up progress bar, and update it roughly every 1/10 of a second
+ app_state->progress_bar = gtk_progress_bar_new();
+ gtk_progress_bar_set_text(GTK_PROGRESS_BAR(app_state->progress_bar),
+ LLTrans::getString("UpdaterProgressBarTextWithEllipses").c_str());
+ gtk_box_pack_start(GTK_BOX(vbox),
+ app_state->progress_bar, FALSE, TRUE, 0);
+ app_state->progress_update_timeout_id = g_timeout_add
+ (UPDATE_PROGRESS_TIMEOUT, progress_update_timeout, app_state);
+ app_state->update_progress_text_timeout_id = g_timeout_add
+ (UPDATE_PROGRESS_TEXT_TIMEOUT, update_progress_text_timeout, app_state);
+
+ gtk_widget_show_all(app_state->window);
+}
+
+gboolean rotate_image_cb(gpointer data)
+{
+ UpdaterAppState *app_state;
+ std::string filename;
+
+ llassert(data != NULL);
+ app_state = (UpdaterAppState *) data;
+
+ filename = next_image_filename(app_state->image_dir);
+
+ gdk_threads_enter();
+ gtk_image_set_from_file(GTK_IMAGE(app_state->image), filename.c_str());
+ gdk_threads_leave();
+
+ return TRUE;
+}
+
+std::string next_image_filename(std::string& image_path)
+{
+ std::string image_filename;
+ gDirUtilp->getNextFileInDir(image_path, "/*.jpg", image_filename, true);
+ return image_path + "/" + image_filename;
+}
+
+void on_window_closed(GtkWidget *sender, gpointer data)
+{
+ UpdaterAppState *app_state;
+
+ llassert(data != NULL);
+ app_state = (UpdaterAppState *) data;
+
+ updater_app_quit(app_state);
+}
+
+void updater_app_quit(UpdaterAppState *app_state)
+{
+ if (app_state != NULL)
+ {
+ g_source_remove(app_state->progress_update_timeout_id);
+
+ if (!app_state->image_dir.empty())
+ {
+ g_source_remove(app_state->image_rotation_timeout_id);
+ }
+ }
+
+ gtk_main_quit();
+}
+
+void display_error(GtkWidget *parent, std::string title, std::string message)
+{
+ GtkWidget *dialog;
+
+ dialog = gtk_message_dialog_new(GTK_WINDOW(parent),
+ GTK_DIALOG_DESTROY_WITH_PARENT,
+ GTK_MESSAGE_ERROR,
+ GTK_BUTTONS_OK,
+ "%s", message.c_str());
+ gtk_window_set_title(GTK_WINDOW(dialog), title.c_str());
+ gtk_dialog_run(GTK_DIALOG(dialog));
+ gtk_widget_destroy(dialog);
+}
+
+gpointer worker_thread_cb(gpointer data)
+{
+ UpdaterAppState *app_state;
+ CURL *curl;
+ CURLcode result;
+ FILE *package_file;
+ GError *error = NULL;
+ char *tmp_filename = NULL;
+ int fd;
+
+ //g_return_val_if_fail (data != NULL, NULL);
+ app_state = (UpdaterAppState *) data;
+
+ try {
+ // create temporary file to store the package.
+ fd = g_file_open_tmp
+ ("secondlife-update-XXXXXX", &tmp_filename, &error);
+ if (error != NULL)
+ {
+ llerrs << "Unable to create temporary file: "
+ << error->message
+ << llendl;
+
+ g_error_free(error);
+ throw 0;
+ }
+
+ package_file = fdopen(fd, "wb");
+ if (package_file == NULL)
+ {
+ llerrs << "Failed to create temporary file: "
+ << tmp_filename
+ << llendl;
+
+ gdk_threads_enter();
+ display_error(app_state->window,
+ LLTrans::getString("UpdaterFailDownloadTitle"),
+ LLTrans::getString("UpdaterFailUpdateDescriptive"));
+ gdk_threads_leave();
+ throw 0;
+ }
+
+ // initialize curl and start downloading the package
+ llinfos << "Downloading package: " << app_state->url << llendl;
+
+ curl = curl_easy_init();
+ if (curl == NULL)
+ {
+ llerrs << "Failed to initialize libcurl" << llendl;
+
+ gdk_threads_enter();
+ display_error(app_state->window,
+ LLTrans::getString("UpdaterFailDownloadTitle"),
+ LLTrans::getString("UpdaterFailUpdateDescriptive"));
+ gdk_threads_leave();
+ throw 0;
+ }
+
+ curl_easy_setopt(curl, CURLOPT_URL, app_state->url.c_str());
+ curl_easy_setopt(curl, CURLOPT_NOSIGNAL, TRUE);
+ curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, TRUE);
+ curl_easy_setopt(curl, CURLOPT_WRITEDATA, package_file);
+ curl_easy_setopt(curl, CURLOPT_NOPROGRESS, FALSE);
+ curl_easy_setopt(curl, CURLOPT_PROGRESSFUNCTION,
+ &download_progress_cb);
+ curl_easy_setopt(curl, CURLOPT_PROGRESSDATA, app_state);
+
+ result = curl_easy_perform(curl);
+ fclose(package_file);
+ curl_easy_cleanup(curl);
+
+ if (result)
+ {
+ llerrs << "Failed to download update: "
+ << app_state->url
+ << llendl;
+
+ gdk_threads_enter();
+ display_error(app_state->window,
+ LLTrans::getString("UpdaterFailDownloadTitle"),
+ LLTrans::getString("UpdaterFailUpdateDescriptive"));
+ gdk_threads_leave();
+
+ throw 0;
+ }
+
+ // now pulse the progres bar back and forth while the package is
+ // being unpacked
+ gdk_threads_enter();
+ std::string installing_msg = LLTrans::getString("UpdaterNowInstalling");
+ gtk_progress_bar_set_text(
+ GTK_PROGRESS_BAR(app_state->progress_bar),
+ installing_msg.c_str());
+ app_state->activity_mode = TRUE;
+ gdk_threads_leave();
+
+ // *TODO: if the destination is not writable, terminate this
+ // thread and show file chooser?
+ if (!install_package(tmp_filename, app_state->dest_dir))
+ {
+ llwarns << "Failed to install package to destination: "
+ << app_state->dest_dir
+ << llendl;
+
+ gdk_threads_enter();
+ display_error(app_state->window,
+ LLTrans::getString("UpdaterFailInstallTitle"),
+ LLTrans::getString("UpdaterFailUpdateDescriptive"));
+ //"Failed to update " + app_state->app_name,
+ gdk_threads_leave();
+ throw 0;
+ }
+
+ // try to spawn the new viewer
+ if (!spawn_viewer(app_state))
+ {
+ llwarns << "Viewer was not installed properly in : "
+ << app_state->dest_dir
+ << llendl;
+
+ gdk_threads_enter();
+ display_error(app_state->window,
+ LLTrans::getString("UpdaterFailStartTitle"),
+ LLTrans::getString("UpdaterFailUpdateDescriptive"));
+ gdk_threads_leave();
+ throw 0;
+ }
+ }
+ catch (...)
+ {
+ app_state->failure = TRUE;
+ }
+
+ // FIXME: delete package file also if delete-event is raised on window
+ if (tmp_filename != NULL)
+ {
+ if (gDirUtilp->fileExists(tmp_filename))
+ {
+ LLFile::remove(tmp_filename);
+ }
+ }
+
+ gdk_threads_enter();
+ updater_app_quit(app_state);
+ gdk_threads_leave();
+
+ return NULL;
+}
+
+
+gboolean less_anal_gspawnsync(gchar **argv,
+ gchar **stderr_output,
+ gint *child_exit_status,
+ GError **spawn_error)
+{
+ // store current SIGCHLD handler if there is one, replace with default
+ // handler to make glib happy
+ struct sigaction sigchld_backup;
+ struct sigaction sigchld_appease_glib;
+ sigchld_appease_glib.sa_handler = SIG_DFL;
+ sigemptyset(&sigchld_appease_glib.sa_mask);
+ sigchld_appease_glib.sa_flags = 0;
+ sigaction(SIGCHLD, &sigchld_appease_glib, &sigchld_backup);
+
+ gboolean rtn = g_spawn_sync(NULL,
+ argv,
+ NULL,
+ (GSpawnFlags) (G_SPAWN_STDOUT_TO_DEV_NULL),
+ NULL,
+ NULL,
+ NULL,
+ stderr_output,
+ child_exit_status,
+ spawn_error);
+
+ // restore SIGCHLD handler
+ sigaction(SIGCHLD, &sigchld_backup, NULL);
+
+ return rtn;
+}
+
+
+// perform a rename, or perform a (prompted) root rename if that fails
+int
+rename_with_sudo_fallback(const std::string& filename, const std::string& newname)
+{
+ int rtncode = ::rename(filename.c_str(), newname.c_str());
+ lldebugs << "rename result is: " << rtncode << " / " << errno << llendl;
+ if (rtncode && (EACCES == errno || EPERM == errno || EXDEV == errno))
+ {
+ llinfos << "Permission problem in rename, or moving between different mount points. Retrying as a mv under a sudo." << llendl;
+ // failed due to permissions, try again as a gksudo or kdesu mv wrapper hack
+ char *sudo_cmd = NULL;
+ sudo_cmd = g_find_program_in_path("gksudo");
+ if (!sudo_cmd)
+ {
+ sudo_cmd = g_find_program_in_path("kdesu");
+ }
+ if (sudo_cmd)
+ {
+ char *mv_cmd = NULL;
+ mv_cmd = g_find_program_in_path("mv");
+ if (mv_cmd)
+ {
+ char *src_string_copy = g_strdup(filename.c_str());
+ char *dst_string_copy = g_strdup(newname.c_str());
+ char* argv[] =
+ {
+ sudo_cmd,
+ mv_cmd,
+ src_string_copy,
+ dst_string_copy,
+ NULL
+ };
+
+ gchar *stderr_output = NULL;
+ gint child_exit_status = 0;
+ GError *spawn_error = NULL;
+ if (!less_anal_gspawnsync(argv, &stderr_output,
+ &child_exit_status, &spawn_error))
+ {
+ llwarns << "Failed to spawn child process: "
+ << spawn_error->message
+ << llendl;
+ }
+ else if (child_exit_status)
+ {
+ llwarns << "mv command failed: "
+ << (stderr_output ? stderr_output : "(no reason given)")
+ << llendl;
+ }
+ else
+ {
+ // everything looks good, clear the error code
+ rtncode = 0;
+ }
+
+ g_free(src_string_copy);
+ g_free(dst_string_copy);
+ if (spawn_error) g_error_free(spawn_error);
+ }
+ }
+ }
+ return rtncode;
+}
+
+gboolean install_package(std::string package_file, std::string destination)
+{
+ char *tar_cmd = NULL;
+ std::ostringstream command;
+
+ // Find the absolute path to the 'tar' command.
+ tar_cmd = g_find_program_in_path("tar");
+ if (!tar_cmd)
+ {
+ llerrs << "`tar' was not found in $PATH" << llendl;
+ return FALSE;
+ }
+ llinfos << "Found tar command: " << tar_cmd << llendl;
+
+ // Unpack the tarball in a temporary place first, then move it to
+ // its final destination
+ std::string tmp_dest_dir = gDirUtilp->getTempFilename();
+ if (LLFile::mkdir(tmp_dest_dir, 0744))
+ {
+ llerrs << "Failed to create directory: "
+ << destination
+ << llendl;
+
+ return FALSE;
+ }
+
+ char *package_file_string_copy = g_strdup(package_file.c_str());
+ char *tmp_dest_dir_string_copy = g_strdup(tmp_dest_dir.c_str());
+ gchar *argv[8] = {
+ tar_cmd,
+ const_cast<gchar*>("--strip"), const_cast<gchar*>("1"),
+ const_cast<gchar*>("-xjf"),
+ package_file_string_copy,
+ const_cast<gchar*>("-C"), tmp_dest_dir_string_copy,
+ NULL,
+ };
+
+ llinfos << "Untarring package: " << package_file << llendl;
+
+ // store current SIGCHLD handler if there is one, replace with default
+ // handler to make glib happy
+ struct sigaction sigchld_backup;
+ struct sigaction sigchld_appease_glib;
+ sigchld_appease_glib.sa_handler = SIG_DFL;
+ sigemptyset(&sigchld_appease_glib.sa_mask);
+ sigchld_appease_glib.sa_flags = 0;
+ sigaction(SIGCHLD, &sigchld_appease_glib, &sigchld_backup);
+
+ gchar *stderr_output = NULL;
+ gint child_exit_status = 0;
+ GError *untar_error = NULL;
+ if (!less_anal_gspawnsync(argv, &stderr_output,
+ &child_exit_status, &untar_error))
+ {
+ llwarns << "Failed to spawn child process: "
+ << untar_error->message
+ << llendl;
+ return FALSE;
+ }
+
+ if (child_exit_status)
+ {
+ llwarns << "Untar command failed: "
+ << (stderr_output ? stderr_output : "(no reason given)")
+ << llendl;
+ return FALSE;
+ }
+
+ g_free(tar_cmd);
+ g_free(package_file_string_copy);
+ g_free(tmp_dest_dir_string_copy);
+ g_free(stderr_output);
+ if (untar_error) g_error_free(untar_error);
+
+ // move the existing package out of the way if it exists
+ if (gDirUtilp->fileExists(destination))
+ {
+ std::string backup_dir = destination + ".backup";
+ int oldcounter = 1;
+ while (gDirUtilp->fileExists(backup_dir))
+ {
+ // find a foo.backup.N folder name that isn't taken yet
+ backup_dir = destination + ".backup." + llformat("%d", oldcounter);
+ ++oldcounter;
+ }
+
+ if (rename_with_sudo_fallback(destination, backup_dir))
+ {
+ llwarns << "Failed to move directory: '"
+ << destination << "' -> '" << backup_dir
+ << llendl;
+ return FALSE;
+ }
+ }
+
+ // The package has been unpacked in a staging directory, now we just
+ // need to move it to its destination.
+ if (rename_with_sudo_fallback(tmp_dest_dir, destination))
+ {
+ llwarns << "Failed to move installation to the destination: "
+ << destination
+ << llendl;
+ return FALSE;
+ }
+
+ // \0/ Success!
+ return TRUE;
+}
+
+gboolean progress_update_timeout(gpointer data)
+{
+ UpdaterAppState *app_state;
+
+ llassert(data != NULL);
+
+ app_state = (UpdaterAppState *) data;
+
+ gdk_threads_enter();
+ if (app_state->activity_mode)
+ {
+ gtk_progress_bar_pulse
+ (GTK_PROGRESS_BAR(app_state->progress_bar));
+ }
+ else
+ {
+ gtk_progress_set_value(GTK_PROGRESS(app_state->progress_bar),
+ app_state->progress_value);
+ }
+ gdk_threads_leave();
+
+ return TRUE;
+}
+
+gboolean update_progress_text_timeout(gpointer data)
+{
+ UpdaterAppState *app_state;
+
+ llassert(data != NULL);
+ app_state = (UpdaterAppState *) data;
+
+ if (app_state->activity_mode == TRUE)
+ {
+ // We no longer need this timeout, it will be removed.
+ return FALSE;
+ }
+
+ if (!app_state->progress_value)
+ {
+ return TRUE;
+ }
+
+ std::string progress_text = llformat((LLTrans::getString("UpdaterProgressBarText")+" (%.0f%%)").c_str(), app_state->progress_value);
+
+ gdk_threads_enter();
+ gtk_progress_bar_set_text(GTK_PROGRESS_BAR(app_state->progress_bar),
+ progress_text.c_str());
+ gdk_threads_leave();
+
+ return TRUE;
+}
+
+int download_progress_cb(gpointer data,
+ double t,
+ double d,
+ double utotal,
+ double ulnow)
+{
+ UpdaterAppState *app_state;
+
+ llassert(data != NULL);
+ app_state = (UpdaterAppState *) data;
+
+ if (t <= 0.0)
+ {
+ app_state->progress_value = 0;
+ }
+ else
+ {
+ app_state->progress_value = d * 100.0 / t;
+ }
+ return 0;
+}
+
+BOOL spawn_viewer(UpdaterAppState *app_state)
+{
+ llassert(app_state != NULL);
+
+ std::string cmd = app_state->dest_dir + "/secondlife";
+ GError *error = NULL;
+
+ // We want to spawn the Viewer on the same display as the updater app
+ gboolean success = gdk_spawn_command_line_on_screen
+ (gtk_widget_get_screen(app_state->window), cmd.c_str(), &error);
+
+ if (!success)
+ {
+ llwarns << "Failed to launch viewer: " << error->message
+ << llendl;
+ }
+
+ if (error) g_error_free(error);
+
+ return success;
+}
+
+void show_usage_and_exit()
+{
+ std::cout << "Usage: linux-updater --url URL --name NAME --dest PATH --stringsdir PATH1,PATH2 --stringsfile FILE"
+ << "[--image-dir PATH]"
+ << std::endl;
+ exit(1);
+}
+
+void parse_args_and_init(int argc, char **argv, UpdaterAppState *app_state)
+{
+ int i;
+
+ for (i = 1; i < argc; i++)
+ {
+ if ((!strcmp(argv[i], "--url")) && (++i < argc))
+ {
+ app_state->url = argv[i];
+ }
+ else if ((!strcmp(argv[i], "--name")) && (++i < argc))
+ {
+ app_state->app_name = argv[i];
+ }
+ else if ((!strcmp(argv[i], "--image-dir")) && (++i < argc))
+ {
+ app_state->image_dir = argv[i];
+ }
+ else if ((!strcmp(argv[i], "--dest")) && (++i < argc))
+ {
+ app_state->dest_dir = argv[i];
+ }
+ else if ((!strcmp(argv[i], "--stringsdir")) && (++i < argc))
+ {
+ app_state->strings_dirs = argv[i];
+ }
+ else if ((!strcmp(argv[i], "--stringsfile")) && (++i < argc))
+ {
+ app_state->strings_file = argv[i];
+ }
+ else
+ {
+ // show usage, an invalid option was given.
+ show_usage_and_exit();
+ }
+ }
+
+ if (app_state->app_name.empty()
+ || app_state->url.empty()
+ || app_state->dest_dir.empty())
+ {
+ show_usage_and_exit();
+ }
+
+ app_state->progress_value = 0.0;
+ app_state->activity_mode = FALSE;
+ app_state->failure = FALSE;
+
+ translate_init(app_state->strings_dirs, app_state->strings_file);
+}
+
+int main(int argc, char **argv)
+{
+ UpdaterAppState app_state;
+ GThread *worker_thread;
+
+ parse_args_and_init(argc, argv, &app_state);
+
+ // Initialize logger, and rename old log file
+ gDirUtilp->initAppDirs("SecondLife");
+ LLError::initForApplication
+ (gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS, ""));
+ std::string old_log_file = gDirUtilp->getExpandedFilename
+ (LL_PATH_LOGS, "updater.log.old");
+ std::string log_file =
+ gDirUtilp->getExpandedFilename(LL_PATH_LOGS, "updater.log");
+ LLFile::rename(log_file, old_log_file);
+ LLError::logToFile(log_file);
+
+ // initialize gthreads and gtk+
+ if (!g_thread_supported())
+ {
+ g_thread_init(NULL);
+ gdk_threads_init();
+ }
+
+ gtk_init(&argc, &argv);
+
+ // create UI
+ updater_app_ui_init(&app_state);
+
+ //llinfos << "SAMPLE TRANSLATION IS: " << LLTrans::getString("LoginInProgress") << llendl;
+
+ // create download thread
+ worker_thread = g_thread_create
+ (GThreadFunc(worker_thread_cb), &app_state, FALSE, NULL);
+
+ gdk_threads_enter();
+ gtk_main();
+ gdk_threads_leave();
+
+ return (app_state.failure == FALSE) ? 0 : 1;
+}
diff --git a/indra/llaudio/CMakeLists.txt b/indra/llaudio/CMakeLists.txt
index 235248ee73..80245fd569 100644
--- a/indra/llaudio/CMakeLists.txt
+++ b/indra/llaudio/CMakeLists.txt
@@ -4,15 +4,16 @@ project(llaudio)
include(00-Common)
include(Audio)
+include(LLAudio)
include(FMOD)
include(OPENAL)
include(LLCommon)
include(LLMath)
include(LLMessage)
include(LLVFS)
-include(LLMedia)
include_directories(
+ ${LLAUDIO_INCLUDE_DIRS}
${FMOD_INCLUDE_DIR}
${LLCOMMON_INCLUDE_DIRS}
${LLMATH_INCLUDE_DIRS}
@@ -24,42 +25,43 @@ include_directories(
${VORBIS_INCLUDE_DIRS}
${OPENAL_LIB_INCLUDE_DIRS}
${FREEAULT_LIB_INCLUDE_DIRS}
- ${LLMEDIA_INCLUDE_DIRS}
)
set(llaudio_SOURCE_FILES
- audioengine.cpp
- listener.cpp
+ llaudioengine.cpp
+ lllistener.cpp
llaudiodecodemgr.cpp
- vorbisdecode.cpp
- vorbisencode.cpp
+ llvorbisdecode.cpp
+ llvorbisencode.cpp
)
set(llaudio_HEADER_FILES
CMakeLists.txt
- audioengine.h
- listener.h
+ llaudioengine.h
+ lllistener.h
llaudiodecodemgr.h
- vorbisdecode.h
- vorbisencode.h
- windgen.h
+ llvorbisdecode.h
+ llvorbisencode.h
+ llwindgen.h
)
if (FMOD)
list(APPEND llaudio_SOURCE_FILES
- audioengine_fmod.cpp
- listener_fmod.cpp
+ llaudioengine_fmod.cpp
+ lllistener_fmod.cpp
+ llstreamingaudio_fmod.cpp
)
list(APPEND llaudio_HEADER_FILES
- audioengine_fmod.h
- listener_fmod.h
+ llaudioengine_fmod.h
+ lllistener_fmod.h
+ llstreamingaudio_fmod.h
)
if (LINUX)
if (${CXX_VERSION} MATCHES "4.[23]")
- set_source_files_properties(audioengine_fmod.cpp
+ set_source_files_properties(llaudioengine_fmod.cpp
COMPILE_FLAGS -Wno-error=write-strings)
endif (${CXX_VERSION} MATCHES "4.[23]")
endif (LINUX)
@@ -67,13 +69,13 @@ endif (FMOD)
if (OPENAL)
list(APPEND llaudio_SOURCE_FILES
- audioengine_openal.cpp
- listener_openal.cpp
+ llaudioengine_openal.cpp
+ lllistener_openal.cpp
)
list(APPEND llaudio_HEADER_FILES
- audioengine_openal.h
- listener_openal.h
+ llaudioengine_openal.h
+ lllistener_openal.h
)
endif (OPENAL)
diff --git a/indra/llaudio/llaudiodecodemgr.cpp b/indra/llaudio/llaudiodecodemgr.cpp
index 5b6db3bd87..099c4eba40 100644
--- a/indra/llaudio/llaudiodecodemgr.cpp
+++ b/indra/llaudio/llaudiodecodemgr.cpp
@@ -33,15 +33,15 @@
#include "llaudiodecodemgr.h"
-#include "vorbisdecode.h"
-#include "audioengine.h"
+#include "llvorbisdecode.h"
+#include "llaudioengine.h"
#include "lllfsthread.h"
#include "llvfile.h"
#include "llstring.h"
#include "lldir.h"
#include "llendianswizzle.h"
-#include "audioengine.h"
#include "llassetstorage.h"
+#include "llrefcount.h"
#include "vorbis/codec.h"
#include "vorbis/vorbisfile.h"
diff --git a/indra/llaudio/llaudioengine.cpp b/indra/llaudio/llaudioengine.cpp
new file mode 100644
index 0000000000..a28c94d00d
--- /dev/null
+++ b/indra/llaudio/llaudioengine.cpp
@@ -0,0 +1,1751 @@
+ /**
+ * @file audioengine.cpp
+ * @brief implementation of LLAudioEngine class abstracting the Open
+ * AL audio support
+ *
+ * $LicenseInfo:firstyear=2000&license=viewergpl$
+ *
+ * Copyright (c) 2000-2009, Linden Research, Inc.
+ *
+ * Second Life Viewer Source Code
+ * The source code in this file ("Source Code") is provided by Linden Lab
+ * to you under the terms of the GNU General Public License, version 2.0
+ * ("GPL"), unless you have obtained a separate licensing agreement
+ * ("Other License"), formally executed by you and Linden Lab. Terms of
+ * the GPL can be found in doc/GPL-license.txt in this distribution, or
+ * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
+ *
+ * There are special exceptions to the terms and conditions of the GPL as
+ * it is applied to this Source Code. View the full text of the exception
+ * in the file doc/FLOSS-exception.txt in this software distribution, or
+ * online at
+ * http://secondlifegrid.net/programs/open_source/licensing/flossexception
+ *
+ * By copying, modifying or distributing this software, you acknowledge
+ * that you have read and understood your obligations described above,
+ * and agree to abide by those obligations.
+ *
+ * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+ * COMPLETENESS OR PERFORMANCE.
+ * $/LicenseInfo$
+ */
+
+#include "linden_common.h"
+
+#include "llaudioengine.h"
+#include "llstreamingaudio.h"
+
+#include "llerror.h"
+#include "llmath.h"
+
+#include "sound_ids.h" // temporary hack for min/max distances
+
+#include "llvfs.h"
+#include "lldir.h"
+#include "llaudiodecodemgr.h"
+#include "llassetstorage.h"
+
+
+// necessary for grabbing sounds from sim (implemented in viewer)
+extern void request_sound(const LLUUID &sound_guid);
+
+LLAudioEngine* gAudiop = NULL;
+
+
+//
+// LLAudioEngine implementation
+//
+
+
+LLAudioEngine::LLAudioEngine()
+{
+ setDefaults();
+}
+
+
+LLAudioEngine::~LLAudioEngine()
+{
+}
+
+LLStreamingAudioInterface* LLAudioEngine::getStreamingAudioImpl()
+{
+ return mStreamingAudioImpl;
+}
+
+void LLAudioEngine::setStreamingAudioImpl(LLStreamingAudioInterface *impl)
+{
+ mStreamingAudioImpl = impl;
+}
+
+void LLAudioEngine::setDefaults()
+{
+ mMaxWindGain = 1.f;
+
+ mListenerp = NULL;
+
+ mMuted = false;
+ mUserData = NULL;
+
+ mLastStatus = 0;
+
+ mNumChannels = 0;
+ mEnableWind = false;
+
+ S32 i;
+ for (i = 0; i < MAX_CHANNELS; i++)
+ {
+ mChannels[i] = NULL;
+ }
+ for (i = 0; i < MAX_BUFFERS; i++)
+ {
+ mBuffers[i] = NULL;
+ }
+
+ mMasterGain = 1.f;
+ mNextWindUpdate = 0.f;
+
+ mStreamingAudioImpl = NULL;
+
+ for (U32 i = 0; i < LLAudioEngine::AUDIO_TYPE_COUNT; i++)
+ mSecondaryGain[i] = 1.0f;
+}
+
+
+bool LLAudioEngine::init(const S32 num_channels, void* userdata)
+{
+ setDefaults();
+
+ mNumChannels = num_channels;
+ mUserData = userdata;
+
+ allocateListener();
+
+ // Initialize the decode manager
+ gAudioDecodeMgrp = new LLAudioDecodeMgr;
+
+ llinfos << "LLAudioEngine::init() AudioEngine successfully initialized" << llendl;
+
+ return true;
+}
+
+
+void LLAudioEngine::shutdown()
+{
+ // Clean up decode manager
+ delete gAudioDecodeMgrp;
+ gAudioDecodeMgrp = NULL;
+
+ // Clean up wind source
+ cleanupWind();
+
+ // Clean up audio sources
+ source_map::iterator iter_src;
+ for (iter_src = mAllSources.begin(); iter_src != mAllSources.end(); iter_src++)
+ {
+ delete iter_src->second;
+ }
+
+
+ // Clean up audio data
+ data_map::iterator iter_data;
+ for (iter_data = mAllData.begin(); iter_data != mAllData.end(); iter_data++)
+ {
+ delete iter_data->second;
+ }
+
+
+ // Clean up channels
+ S32 i;
+ for (i = 0; i < MAX_CHANNELS; i++)
+ {
+ delete mChannels[i];
+ mChannels[i] = NULL;
+ }
+
+ // Clean up buffers
+ for (i = 0; i < MAX_BUFFERS; i++)
+ {
+ delete mBuffers[i];
+ mBuffers[i] = NULL;
+ }
+}
+
+
+// virtual
+void LLAudioEngine::startInternetStream(const std::string& url)
+{
+ if (mStreamingAudioImpl)
+ mStreamingAudioImpl->start(url);
+}
+
+
+// virtual
+void LLAudioEngine::stopInternetStream()
+{
+ if (mStreamingAudioImpl)
+ mStreamingAudioImpl->stop();
+}
+
+// virtual
+void LLAudioEngine::pauseInternetStream(int pause)
+{
+ if (mStreamingAudioImpl)
+ mStreamingAudioImpl->pause(pause);
+}
+
+// virtual
+void LLAudioEngine::updateInternetStream()
+{
+ if (mStreamingAudioImpl)
+ mStreamingAudioImpl->update();
+}
+
+// virtual
+int LLAudioEngine::isInternetStreamPlaying()
+{
+ if (mStreamingAudioImpl)
+ return mStreamingAudioImpl->isPlaying();
+
+ return 0; // Stopped
+}
+
+
+// virtual
+void LLAudioEngine::setInternetStreamGain(F32 vol)
+{
+ if (mStreamingAudioImpl)
+ mStreamingAudioImpl->setGain(vol);
+}
+
+// virtual
+std::string LLAudioEngine::getInternetStreamURL()
+{
+ if (mStreamingAudioImpl)
+ return mStreamingAudioImpl->getURL();
+ else return std::string();
+}
+
+
+void LLAudioEngine::updateChannels()
+{
+ S32 i;
+ for (i = 0; i < MAX_CHANNELS; i++)
+ {
+ if (mChannels[i])
+ {
+ mChannels[i]->updateBuffer();
+ mChannels[i]->update3DPosition();
+ mChannels[i]->updateLoop();
+ }
+ }
+}
+
+static const F32 default_max_decode_time = .002f; // 2 ms
+void LLAudioEngine::idle(F32 max_decode_time)
+{
+ if (max_decode_time <= 0.f)
+ {
+ max_decode_time = default_max_decode_time;
+ }
+
+ // "Update" all of our audio sources, clean up dead ones.
+ // Primarily does position updating, cleanup of unused audio sources.
+ // Also does regeneration of the current priority of each audio source.
+
+ if (getMuted())
+ {
+ setInternalGain(0.f);
+ }
+ else
+ {
+ setInternalGain(getMasterGain());
+ }
+
+ S32 i;
+ for (i = 0; i < MAX_BUFFERS; i++)
+ {
+ if (mBuffers[i])
+ {
+ mBuffers[i]->mInUse = false;
+ }
+ }
+
+ F32 max_priority = -1.f;
+ LLAudioSource *max_sourcep = NULL; // Maximum priority source without a channel
+ source_map::iterator iter;
+ for (iter = mAllSources.begin(); iter != mAllSources.end();)
+ {
+ LLAudioSource *sourcep = iter->second;
+
+ // Update this source
+ sourcep->update();
+ sourcep->updatePriority();
+
+ if (sourcep->isDone())
+ {
+ // The source is done playing, clean it up.
+ delete sourcep;
+ mAllSources.erase(iter++);
+ continue;
+ }
+
+ if (!sourcep->getChannel() && sourcep->getCurrentBuffer())
+ {
+ // We could potentially play this sound if its priority is high enough.
+ if (sourcep->getPriority() > max_priority)
+ {
+ max_priority = sourcep->getPriority();
+ max_sourcep = sourcep;
+ }
+ }
+
+ // Move on to the next source
+ iter++;
+ }
+
+ // Now, do priority-based organization of audio sources.
+ // All channels used, check priorities.
+ // Find channel with lowest priority
+ if (max_sourcep)
+ {
+ LLAudioChannel *channelp = getFreeChannel(max_priority);
+ if (channelp)
+ {
+ //llinfos << "Replacing source in channel due to priority!" << llendl;
+ max_sourcep->setChannel(channelp);
+ channelp->setSource(max_sourcep);
+ if (max_sourcep->isSyncSlave())
+ {
+ // A sync slave, it doesn't start playing until it's synced up with the master.
+ // Flag this channel as waiting for sync, and return true.
+ channelp->setWaiting(true);
+ }
+ else
+ {
+ channelp->setWaiting(false);
+ channelp->play();
+ }
+ }
+ }
+
+
+ // Do this BEFORE we update the channels
+ // Update the channels to sync up with any changes that the source made,
+ // such as changing what sound was playing.
+ updateChannels();
+
+ // Update queued sounds (switch to next queued data if the current has finished playing)
+ for (iter = mAllSources.begin(); iter != mAllSources.end(); ++iter)
+ {
+ // This is lame, instead of this I could actually iterate through all the sources
+ // attached to each channel, since only those with active channels
+ // can have anything interesting happen with their queue? (Maybe not true)
+ LLAudioSource *sourcep = iter->second;
+ if (!sourcep->mQueuedDatap)
+ {
+ // Nothing queued, so we don't care.
+ continue;
+ }
+
+ LLAudioChannel *channelp = sourcep->getChannel();
+ if (!channelp)
+ {
+ // This sound isn't playing, so we just process move the queue
+ sourcep->mCurrentDatap = sourcep->mQueuedDatap;
+ sourcep->mQueuedDatap = NULL;
+
+ // Reset the timer so the source doesn't die.
+ sourcep->mAgeTimer.reset();
+ // Make sure we have the buffer set up if we just decoded the data
+ if (sourcep->mCurrentDatap)
+ {
+ updateBufferForData(sourcep->mCurrentDatap);
+ }
+
+ // Actually play the associated data.
+ sourcep->setupChannel();
+ channelp = sourcep->getChannel();
+ if (channelp)
+ {
+ channelp->updateBuffer();
+ sourcep->getChannel()->play();
+ }
+ continue;
+ }
+ else
+ {
+ // Check to see if the current sound is done playing, or looped.
+ if (!channelp->isPlaying())
+ {
+ sourcep->mCurrentDatap = sourcep->mQueuedDatap;
+ sourcep->mQueuedDatap = NULL;
+
+ // Reset the timer so the source doesn't die.
+ sourcep->mAgeTimer.reset();
+
+ // Make sure we have the buffer set up if we just decoded the data
+ if (sourcep->mCurrentDatap)
+ {
+ updateBufferForData(sourcep->mCurrentDatap);
+ }
+
+ // Actually play the associated data.
+ sourcep->setupChannel();
+ channelp->updateBuffer();
+ sourcep->getChannel()->play();
+ }
+ else if (sourcep->isLoop())
+ {
+ // It's a loop, we need to check and see if we're done with it.
+ if (channelp->mLoopedThisFrame)
+ {
+ sourcep->mCurrentDatap = sourcep->mQueuedDatap;
+ sourcep->mQueuedDatap = NULL;
+
+ // Actually, should do a time sync so if we're a loop master/slave
+ // we don't drift away.
+ sourcep->setupChannel();
+ sourcep->getChannel()->play();
+ }
+ }
+ }
+ }
+
+ // Lame, update the channels AGAIN.
+ // Update the channels to sync up with any changes that the source made,
+ // such as changing what sound was playing.
+ updateChannels();
+
+ // Hack! For now, just use a global sync master;
+ LLAudioSource *sync_masterp = NULL;
+ LLAudioChannel *master_channelp = NULL;
+ F32 max_sm_priority = -1.f;
+ for (iter = mAllSources.begin(); iter != mAllSources.end(); ++iter)
+ {
+ LLAudioSource *sourcep = iter->second;
+ if (sourcep->isSyncMaster())
+ {
+ if (sourcep->getPriority() > max_sm_priority)
+ {
+ sync_masterp = sourcep;
+ master_channelp = sync_masterp->getChannel();
+ max_sm_priority = sourcep->getPriority();
+ }
+ }
+ }
+
+ if (master_channelp && master_channelp->mLoopedThisFrame)
+ {
+ // Synchronize loop slaves with their masters
+ // Update queued sounds (switch to next queued data if the current has finished playing)
+ for (iter = mAllSources.begin(); iter != mAllSources.end(); ++iter)
+ {
+ LLAudioSource *sourcep = iter->second;
+
+ if (!sourcep->isSyncSlave())
+ {
+ // Not a loop slave, we don't need to do anything
+ continue;
+ }
+
+ LLAudioChannel *channelp = sourcep->getChannel();
+ if (!channelp)
+ {
+ // Not playing, don't need to bother.
+ continue;
+ }
+
+ if (!channelp->isPlaying())
+ {
+ // Now we need to check if our loop master has just looped, and
+ // start playback if that's the case.
+ if (sync_masterp->getChannel())
+ {
+ channelp->playSynced(master_channelp);
+ channelp->setWaiting(false);
+ }
+ }
+ }
+ }
+
+ // Sync up everything that the audio engine needs done.
+ commitDeferredChanges();
+
+ // Flush unused buffers that are stale enough
+ for (i = 0; i < MAX_BUFFERS; i++)
+ {
+ if (mBuffers[i])
+ {
+ if (!mBuffers[i]->mInUse && mBuffers[i]->mLastUseTimer.getElapsedTimeF32() > 30.f)
+ {
+ //llinfos << "Flushing unused buffer!" << llendl;
+ mBuffers[i]->mAudioDatap->mBufferp = NULL;
+ delete mBuffers[i];
+ mBuffers[i] = NULL;
+ }
+ }
+ }
+
+
+ // Clear all of the looped flags for the channels
+ for (i = 0; i < MAX_CHANNELS; i++)
+ {
+ if (mChannels[i])
+ {
+ mChannels[i]->mLoopedThisFrame = false;
+ }
+ }
+
+ // Decode audio files
+ gAudioDecodeMgrp->processQueue(max_decode_time);
+
+ // Call this every frame, just in case we somehow
+ // missed picking it up in all the places that can add
+ // or request new data.
+ startNextTransfer();
+
+ updateInternetStream();
+}
+
+
+
+bool LLAudioEngine::updateBufferForData(LLAudioData *adp, const LLUUID &audio_uuid)
+{
+ if (!adp)
+ {
+ return false;
+ }
+
+ // Update the audio buffer first - load a sound if we have it.
+ // Note that this could potentially cause us to waste time updating buffers
+ // for sounds that actually aren't playing, although this should be mitigated
+ // by the fact that we limit the number of buffers, and we flush buffers based
+ // on priority.
+ if (!adp->getBuffer())
+ {
+ if (adp->hasDecodedData())
+ {
+ adp->load();
+ }
+ else if (adp->hasLocalData())
+ {
+ if (audio_uuid.notNull())
+ {
+ gAudioDecodeMgrp->addDecodeRequest(audio_uuid);
+ }
+ }
+ else
+ {
+ return false;
+ }
+ }
+ return true;
+}
+
+
+void LLAudioEngine::enableWind(bool enable)
+{
+ if (enable && (!mEnableWind))
+ {
+ initWind();
+ mEnableWind = enable;
+ }
+ else if (mEnableWind && (!enable))
+ {
+ mEnableWind = enable;
+ cleanupWind();
+ }
+}
+
+
+LLAudioBuffer * LLAudioEngine::getFreeBuffer()
+{
+ S32 i;
+ for (i = 0; i < MAX_BUFFERS; i++)
+ {
+ if (!mBuffers[i])
+ {
+ mBuffers[i] = createBuffer();
+ return mBuffers[i];
+ }
+ }
+
+
+ // Grab the oldest unused buffer
+ F32 max_age = -1.f;
+ S32 buffer_id = -1;
+ for (i = 0; i < MAX_BUFFERS; i++)
+ {
+ if (mBuffers[i])
+ {
+ if (!mBuffers[i]->mInUse)
+ {
+ if (mBuffers[i]->mLastUseTimer.getElapsedTimeF32() > max_age)
+ {
+ max_age = mBuffers[i]->mLastUseTimer.getElapsedTimeF32();
+ buffer_id = i;
+ }
+ }
+ }
+ }
+
+ if (buffer_id >= 0)
+ {
+ llinfos << "Taking over unused buffer " << buffer_id << llendl;
+ //llinfos << "Flushing unused buffer!" << llendl;
+ mBuffers[buffer_id]->mAudioDatap->mBufferp = NULL;
+ delete mBuffers[buffer_id];
+ mBuffers[buffer_id] = createBuffer();
+ return mBuffers[buffer_id];
+ }
+ return NULL;
+}
+
+
+LLAudioChannel * LLAudioEngine::getFreeChannel(const F32 priority)
+{
+ S32 i;
+ for (i = 0; i < mNumChannels; i++)
+ {
+ if (!mChannels[i])
+ {
+ // No channel allocated here, use it.
+ mChannels[i] = createChannel();
+ return mChannels[i];
+ }
+ else
+ {
+ // Channel is allocated but not playing right now, use it.
+ if (!mChannels[i]->isPlaying() && !mChannels[i]->isWaiting())
+ {
+ mChannels[i]->cleanup();
+ if (mChannels[i]->getSource())
+ {
+ mChannels[i]->getSource()->setChannel(NULL);
+ }
+ return mChannels[i];
+ }
+ }
+ }
+
+ // All channels used, check priorities.
+ // Find channel with lowest priority and see if we want to replace it.
+ F32 min_priority = 10000.f;
+ LLAudioChannel *min_channelp = NULL;
+
+ for (i = 0; i < mNumChannels; i++)
+ {
+ LLAudioChannel *channelp = mChannels[i];
+ LLAudioSource *sourcep = channelp->getSource();
+ if (sourcep->getPriority() < min_priority)
+ {
+ min_channelp = channelp;
+ min_priority = sourcep->getPriority();
+ }
+ }
+
+ if (min_priority > priority || !min_channelp)
+ {
+ // All playing channels have higher priority, return.
+ return NULL;
+ }
+
+ // Flush the minimum priority channel, and return it.
+ min_channelp->cleanup();
+ min_channelp->getSource()->setChannel(NULL);
+ return min_channelp;
+}
+
+
+void LLAudioEngine::cleanupBuffer(LLAudioBuffer *bufferp)
+{
+ S32 i;
+ for (i = 0; i < MAX_BUFFERS; i++)
+ {
+ if (mBuffers[i] == bufferp)
+ {
+ delete mBuffers[i];
+ mBuffers[i] = NULL;
+ }
+ }
+}
+
+
+bool LLAudioEngine::preloadSound(const LLUUID &uuid)
+{
+ gAudiop->getAudioData(uuid); // We don't care about the return value, this is just to make sure
+ // that we have an entry, which will mean that the audio engine knows about this
+
+ if (gAudioDecodeMgrp->addDecodeRequest(uuid))
+ {
+ // This means that we do have a local copy, and we're working on decoding it.
+ return true;
+ }
+
+ // At some point we need to have the audio/asset system check the static VFS
+ // before it goes off and fetches stuff from the server.
+ //llwarns << "Used internal preload for non-local sound" << llendl;
+ return false;
+}
+
+
+bool LLAudioEngine::isWindEnabled()
+{
+ return mEnableWind;
+}
+
+
+void LLAudioEngine::setMuted(bool muted)
+{
+ mMuted = muted;
+ enableWind(!mMuted);
+}
+
+
+void LLAudioEngine::setMasterGain(const F32 gain)
+{
+ mMasterGain = gain;
+ setInternalGain(gain);
+}
+
+F32 LLAudioEngine::getMasterGain()
+{
+ return mMasterGain;
+}
+
+void LLAudioEngine::setSecondaryGain(S32 type, F32 gain)
+{
+ llassert(type < LLAudioEngine::AUDIO_TYPE_COUNT);
+
+ mSecondaryGain[type] = gain;
+}
+
+F32 LLAudioEngine::getSecondaryGain(S32 type)
+{
+ return mSecondaryGain[type];
+}
+
+F32 LLAudioEngine::getInternetStreamGain()
+{
+ if (mStreamingAudioImpl)
+ return mStreamingAudioImpl->getGain();
+ else
+ return 1.0f;
+}
+
+void LLAudioEngine::setMaxWindGain(F32 gain)
+{
+ mMaxWindGain = gain;
+}
+
+
+F64 LLAudioEngine::mapWindVecToGain(LLVector3 wind_vec)
+{
+ F64 gain = 0.0;
+
+ gain = wind_vec.magVec();
+
+ if (gain)
+ {
+ if (gain > 20)
+ {
+ gain = 20;
+ }
+ gain = gain/20.0;
+ }
+
+ return (gain);
+}
+
+
+F64 LLAudioEngine::mapWindVecToPitch(LLVector3 wind_vec)
+{
+ LLVector3 listen_right;
+ F64 theta;
+
+ // Wind frame is in listener-relative coordinates
+ LLVector3 norm_wind = wind_vec;
+ norm_wind.normVec();
+ listen_right.setVec(1.0,0.0,0.0);
+
+ // measure angle between wind vec and listener right axis (on 0,PI)
+ theta = acos(norm_wind * listen_right);
+
+ // put it on 0, 1
+ theta /= F_PI;
+
+ // put it on [0, 0.5, 0]
+ if (theta > 0.5) theta = 1.0-theta;
+ if (theta < 0) theta = 0;
+
+ return (theta);
+}
+
+
+F64 LLAudioEngine::mapWindVecToPan(LLVector3 wind_vec)
+{
+ LLVector3 listen_right;
+ F64 theta;
+
+ // Wind frame is in listener-relative coordinates
+ listen_right.setVec(1.0,0.0,0.0);
+
+ LLVector3 norm_wind = wind_vec;
+ norm_wind.normVec();
+
+ // measure angle between wind vec and listener right axis (on 0,PI)
+ theta = acos(norm_wind * listen_right);
+
+ // put it on 0, 1
+ theta /= F_PI;
+
+ return (theta);
+}
+
+
+void LLAudioEngine::triggerSound(const LLUUID &audio_uuid, const LLUUID& owner_id, const F32 gain,
+ const S32 type, const LLVector3d &pos_global)
+{
+ // Create a new source (since this can't be associated with an existing source.
+ //llinfos << "Localized: " << audio_uuid << llendl;
+
+ if (mMuted)
+ {
+ return;
+ }
+
+ LLUUID source_id;
+ source_id.generate();
+
+ LLAudioSource *asp = new LLAudioSource(source_id, owner_id, gain, type);
+ gAudiop->addAudioSource(asp);
+ if (pos_global.isExactlyZero())
+ {
+ asp->setAmbient(true);
+ }
+ else
+ {
+ asp->setPositionGlobal(pos_global);
+ }
+ asp->updatePriority();
+ asp->play(audio_uuid);
+}
+
+
+void LLAudioEngine::setListenerPos(LLVector3 aVec)
+{
+ mListenerp->setPosition(aVec);
+}
+
+
+LLVector3 LLAudioEngine::getListenerPos()
+{
+ if (mListenerp)
+ {
+ return(mListenerp->getPosition());
+ }
+ else
+ {
+ return(LLVector3::zero);
+ }
+}
+
+
+void LLAudioEngine::setListenerVelocity(LLVector3 aVec)
+{
+ mListenerp->setVelocity(aVec);
+}
+
+
+void LLAudioEngine::translateListener(LLVector3 aVec)
+{
+ mListenerp->translate(aVec);
+}
+
+
+void LLAudioEngine::orientListener(LLVector3 up, LLVector3 at)
+{
+ mListenerp->orient(up, at);
+}
+
+
+void LLAudioEngine::setListener(LLVector3 pos, LLVector3 vel, LLVector3 up, LLVector3 at)
+{
+ mListenerp->set(pos,vel,up,at);
+}
+
+
+void LLAudioEngine::setDopplerFactor(F32 factor)
+{
+ if (mListenerp)
+ {
+ mListenerp->setDopplerFactor(factor);
+ }
+}
+
+
+F32 LLAudioEngine::getDopplerFactor()
+{
+ if (mListenerp)
+ {
+ return mListenerp->getDopplerFactor();
+ }
+ else
+ {
+ return 0.f;
+ }
+}
+
+
+void LLAudioEngine::setRolloffFactor(F32 factor)
+{
+ if (mListenerp)
+ {
+ mListenerp->setRolloffFactor(factor);
+ }
+}
+
+
+F32 LLAudioEngine::getRolloffFactor()
+{
+ if (mListenerp)
+ {
+ return mListenerp->getRolloffFactor();
+ }
+ else
+ {
+ return 0.f;
+ }
+}
+
+
+void LLAudioEngine::commitDeferredChanges()
+{
+ mListenerp->commitDeferredChanges();
+}
+
+
+LLAudioSource * LLAudioEngine::findAudioSource(const LLUUID &source_id)
+{
+ source_map::iterator iter;
+ iter = mAllSources.find(source_id);
+
+ if (iter == mAllSources.end())
+ {
+ return NULL;
+ }
+ else
+ {
+ return iter->second;
+ }
+}
+
+
+LLAudioData * LLAudioEngine::getAudioData(const LLUUID &audio_uuid)
+{
+ data_map::iterator iter;
+ iter = mAllData.find(audio_uuid);
+ if (iter == mAllData.end())
+ {
+ // Create the new audio data
+ LLAudioData *adp = new LLAudioData(audio_uuid);
+ mAllData[audio_uuid] = adp;
+ return adp;
+ }
+ else
+ {
+ return iter->second;
+ }
+}
+
+void LLAudioEngine::addAudioSource(LLAudioSource *asp)
+{
+ mAllSources[asp->getID()] = asp;
+}
+
+
+void LLAudioEngine::cleanupAudioSource(LLAudioSource *asp)
+{
+ source_map::iterator iter;
+ iter = mAllSources.find(asp->getID());
+ if (iter == mAllSources.end())
+ {
+ llwarns << "Cleaning up unknown audio source!" << llendl;
+ return;
+ }
+ delete asp;
+ mAllSources.erase(iter);
+}
+
+
+bool LLAudioEngine::hasDecodedFile(const LLUUID &uuid)
+{
+ std::string uuid_str;
+ uuid.toString(uuid_str);
+
+ std::string wav_path;
+ wav_path = gDirUtilp->getExpandedFilename(LL_PATH_CACHE,uuid_str);
+ wav_path += ".dsf";
+
+ if (gDirUtilp->fileExists(wav_path))
+ {
+ return true;
+ }
+ else
+ {
+ return false;
+ }
+}
+
+
+bool LLAudioEngine::hasLocalFile(const LLUUID &uuid)
+{
+ // See if it's in the VFS.
+ return gVFS->getExists(uuid, LLAssetType::AT_SOUND);
+}
+
+
+void LLAudioEngine::startNextTransfer()
+{
+ //llinfos << "LLAudioEngine::startNextTransfer()" << llendl;
+ if (mCurrentTransfer.notNull() || getMuted())
+ {
+ //llinfos << "Transfer in progress, aborting" << llendl;
+ return;
+ }
+
+ // Get the ID for the next asset that we want to transfer.
+ // Pick one in the following order:
+ LLUUID asset_id;
+ S32 i;
+ LLAudioSource *asp = NULL;
+ LLAudioData *adp = NULL;
+ data_map::iterator data_iter;
+
+ // Check all channels for currently playing sounds.
+ F32 max_pri = -1.f;
+ for (i = 0; i < MAX_CHANNELS; i++)
+ {
+ if (!mChannels[i])
+ {
+ continue;
+ }
+
+ asp = mChannels[i]->getSource();
+ if (!asp)
+ {
+ continue;
+ }
+ if (asp->getPriority() <= max_pri)
+ {
+ continue;
+ }
+
+ if (asp->getPriority() <= max_pri)
+ {
+ continue;
+ }
+
+ adp = asp->getCurrentData();
+ if (!adp)
+ {
+ continue;
+ }
+
+ if (!adp->hasLocalData() && adp->hasValidData())
+ {
+ asset_id = adp->getID();
+ max_pri = asp->getPriority();
+ }
+ }
+
+ // Check all channels for currently queued sounds.
+ if (asset_id.isNull())
+ {
+ max_pri = -1.f;
+ for (i = 0; i < MAX_CHANNELS; i++)
+ {
+ if (!mChannels[i])
+ {
+ continue;
+ }
+
+ LLAudioSource *asp;
+ asp = mChannels[i]->getSource();
+ if (!asp)
+ {
+ continue;
+ }
+
+ if (asp->getPriority() <= max_pri)
+ {
+ continue;
+ }
+
+ adp = asp->getQueuedData();
+ if (!adp)
+ {
+ continue;
+ }
+
+ if (!adp->hasLocalData() && adp->hasValidData())
+ {
+ asset_id = adp->getID();
+ max_pri = asp->getPriority();
+ }
+ }
+ }
+
+ // Check all live channels for other sounds (preloads).
+ if (asset_id.isNull())
+ {
+ max_pri = -1.f;
+ for (i = 0; i < MAX_CHANNELS; i++)
+ {
+ if (!mChannels[i])
+ {
+ continue;
+ }
+
+ LLAudioSource *asp;
+ asp = mChannels[i]->getSource();
+ if (!asp)
+ {
+ continue;
+ }
+
+ if (asp->getPriority() <= max_pri)
+ {
+ continue;
+ }
+
+
+ for (data_iter = asp->mPreloadMap.begin(); data_iter != asp->mPreloadMap.end(); data_iter++)
+ {
+ LLAudioData *adp = data_iter->second;
+ if (!adp)
+ {
+ continue;
+ }
+
+ if (!adp->hasLocalData() && adp->hasValidData())
+ {
+ asset_id = adp->getID();
+ max_pri = asp->getPriority();
+ }
+ }
+ }
+ }
+
+ // Check all sources
+ if (asset_id.isNull())
+ {
+ max_pri = -1.f;
+ source_map::iterator source_iter;
+ for (source_iter = mAllSources.begin(); source_iter != mAllSources.end(); source_iter++)
+ {
+ asp = source_iter->second;
+ if (!asp)
+ {
+ continue;
+ }
+
+ if (asp->getPriority() <= max_pri)
+ {
+ continue;
+ }
+
+ adp = asp->getCurrentData();
+ if (adp && !adp->hasLocalData() && adp->hasValidData())
+ {
+ asset_id = adp->getID();
+ max_pri = asp->getPriority();
+ continue;
+ }
+
+ adp = asp->getQueuedData();
+ if (adp && !adp->hasLocalData() && adp->hasValidData())
+ {
+ asset_id = adp->getID();
+ max_pri = asp->getPriority();
+ continue;
+ }
+
+ for (data_iter = asp->mPreloadMap.begin(); data_iter != asp->mPreloadMap.end(); data_iter++)
+ {
+ LLAudioData *adp = data_iter->second;
+ if (!adp)
+ {
+ continue;
+ }
+
+ if (!adp->hasLocalData() && adp->hasValidData())
+ {
+ asset_id = adp->getID();
+ max_pri = asp->getPriority();
+ break;
+ }
+ }
+ }
+ }
+
+ if (asset_id.notNull())
+ {
+ llinfos << "Getting asset data for: " << asset_id << llendl;
+ gAudiop->mCurrentTransfer = asset_id;
+ gAudiop->mCurrentTransferTimer.reset();
+ gAssetStorage->getAssetData(asset_id, LLAssetType::AT_SOUND,
+ assetCallback, NULL);
+ }
+ else
+ {
+ //llinfos << "No pending transfers?" << llendl;
+ }
+}
+
+
+// static
+void LLAudioEngine::assetCallback(LLVFS *vfs, const LLUUID &uuid, LLAssetType::EType type, void *user_data, S32 result_code, LLExtStat ext_status)
+{
+ if (result_code)
+ {
+ llinfos << "Boom, error in audio file transfer: " << LLAssetStorage::getErrorString( result_code ) << " (" << result_code << ")" << llendl;
+ // Need to mark data as bad to avoid constant rerequests.
+ LLAudioData *adp = gAudiop->getAudioData(uuid);
+ if (adp)
+ {
+ adp->setHasValidData(false);
+ adp->setHasLocalData(false);
+ adp->setHasDecodedData(false);
+ }
+ }
+ else
+ {
+ LLAudioData *adp = gAudiop->getAudioData(uuid);
+ if (!adp)
+ {
+ // Should never happen
+ llwarns << "Got asset callback without audio data for " << uuid << llendl;
+ }
+ else
+ {
+ adp->setHasValidData(true);
+ adp->setHasLocalData(true);
+ gAudioDecodeMgrp->addDecodeRequest(uuid);
+ }
+ }
+ gAudiop->mCurrentTransfer = LLUUID::null;
+ gAudiop->startNextTransfer();
+}
+
+
+//
+// LLAudioSource implementation
+//
+
+
+LLAudioSource::LLAudioSource(const LLUUID& id, const LLUUID& owner_id, const F32 gain, const S32 type)
+: mID(id),
+ mOwnerID(owner_id),
+ mPriority(0.f),
+ mGain(gain),
+ mType(type),
+ mAmbient(false),
+ mLoop(false),
+ mSyncMaster(false),
+ mSyncSlave(false),
+ mQueueSounds(false),
+ mPlayedOnce(false),
+ mChannelp(NULL),
+ mCurrentDatap(NULL),
+ mQueuedDatap(NULL)
+{
+}
+
+
+LLAudioSource::~LLAudioSource()
+{
+ if (mChannelp)
+ {
+ // Stop playback of this sound
+ mChannelp->setSource(NULL);
+ mChannelp = NULL;
+ }
+}
+
+
+void LLAudioSource::setChannel(LLAudioChannel *channelp)
+{
+ if (channelp == mChannelp)
+ {
+ return;
+ }
+
+ mChannelp = channelp;
+}
+
+
+void LLAudioSource::update()
+{
+ if (!getCurrentBuffer())
+ {
+ if (getCurrentData())
+ {
+ // Hack - try and load the sound. Will do this as a callback
+ // on decode later.
+ if (getCurrentData()->load())
+ {
+ play(getCurrentData()->getID());
+ }
+ }
+ }
+}
+
+void LLAudioSource::updatePriority()
+{
+ if (isAmbient())
+ {
+ mPriority = 1.f;
+ }
+ else
+ {
+ // Priority is based on distance
+ LLVector3 dist_vec;
+ dist_vec.setVec(getPositionGlobal());
+ dist_vec -= gAudiop->getListenerPos();
+ F32 dist_squared = llmax(1.f, dist_vec.magVecSquared());
+
+ mPriority = mGain / dist_squared;
+ }
+}
+
+bool LLAudioSource::setupChannel()
+{
+ LLAudioData *adp = getCurrentData();
+
+ if (!adp->getBuffer())
+ {
+ // We're not ready to play back the sound yet, so don't try and allocate a channel for it.
+ //llwarns << "Aborting, no buffer" << llendl;
+ return false;
+ }
+
+
+ if (!mChannelp)
+ {
+ // Update the priority, in case we need to push out another channel.
+ updatePriority();
+
+ setChannel(gAudiop->getFreeChannel(getPriority()));
+ }
+
+ if (!mChannelp)
+ {
+ // Ugh, we don't have any free channels.
+ // Now we have to reprioritize.
+ // For now, just don't play the sound.
+ //llwarns << "Aborting, no free channels" << llendl;
+ return false;
+ }
+
+ mChannelp->setSource(this);
+ return true;
+}
+
+
+bool LLAudioSource::play(const LLUUID &audio_uuid)
+{
+ if (audio_uuid.isNull())
+ {
+ if (getChannel())
+ {
+ getChannel()->setSource(NULL);
+ setChannel(NULL);
+ addAudioData(NULL, true);
+ }
+ }
+ // Reset our age timeout if someone attempts to play the source.
+ mAgeTimer.reset();
+
+ LLAudioData *adp = gAudiop->getAudioData(audio_uuid);
+
+ bool has_buffer = gAudiop->updateBufferForData(adp, audio_uuid);
+
+
+ addAudioData(adp);
+
+ if (!has_buffer)
+ {
+ // Don't bother trying to set up a channel or anything, we don't have an audio buffer.
+ return false;
+ }
+
+ if (!setupChannel())
+ {
+ return false;
+ }
+
+ if (isSyncSlave())
+ {
+ // A sync slave, it doesn't start playing until it's synced up with the master.
+ // Flag this channel as waiting for sync, and return true.
+ getChannel()->setWaiting(true);
+ return true;
+ }
+
+ getChannel()->play();
+ return true;
+}
+
+
+bool LLAudioSource::isDone()
+{
+ const F32 MAX_AGE = 60.f;
+ const F32 MAX_UNPLAYED_AGE = 15.f;
+
+ if (isLoop())
+ {
+ // Looped sources never die on their own.
+ return false;
+ }
+
+
+ if (hasPendingPreloads())
+ {
+ return false;
+ }
+
+ if (mQueuedDatap)
+ {
+ // Don't kill this sound if we've got something queued up to play.
+ return false;
+ }
+
+ F32 elapsed = mAgeTimer.getElapsedTimeF32();
+
+ // This is a single-play source
+ if (!mChannelp)
+ {
+ if ((elapsed > MAX_UNPLAYED_AGE) || mPlayedOnce)
+ {
+ // We don't have a channel assigned, and it's been
+ // over 5 seconds since we tried to play it. Don't bother.
+ //llinfos << "No channel assigned, source is done" << llendl;
+ return true;
+ }
+ else
+ {
+ return false;
+ }
+ }
+
+ if (mChannelp->isPlaying())
+ {
+ if (elapsed > MAX_AGE)
+ {
+ // Arbitarily cut off non-looped sounds when they're old.
+ return true;
+ }
+ else
+ {
+ // Sound is still playing and we haven't timed out, don't kill it.
+ return false;
+ }
+ }
+
+ if ((elapsed > MAX_UNPLAYED_AGE) || mPlayedOnce)
+ {
+ // The sound isn't playing back after 5 seconds or we're already done playing it, kill it.
+ return true;
+ }
+
+ return false;
+}
+
+
+void LLAudioSource::addAudioData(LLAudioData *adp, const bool set_current)
+{
+ // Only handle a single piece of audio data associated with a source right now,
+ // until I implement prefetch.
+ if (set_current)
+ {
+ if (!mCurrentDatap)
+ {
+ mCurrentDatap = adp;
+ if (mChannelp)
+ {
+ mChannelp->updateBuffer();
+ mChannelp->play();
+ }
+
+ // Make sure the audio engine knows that we want to request this sound.
+ gAudiop->startNextTransfer();
+ return;
+ }
+ else if (mQueueSounds)
+ {
+ // If we have current data, and we're queuing, put
+ // the object onto the queue.
+ if (mQueuedDatap)
+ {
+ // We only queue one sound at a time, and it's a FIFO.
+ // Don't put it onto the queue.
+ return;
+ }
+
+ if (adp == mCurrentDatap && isLoop())
+ {
+ // No point in queueing the same sound if
+ // we're looping.
+ return;
+ }
+ mQueuedDatap = adp;
+
+ // Make sure the audio engine knows that we want to request this sound.
+ gAudiop->startNextTransfer();
+ }
+ else
+ {
+ if (mCurrentDatap != adp)
+ {
+ // Right now, if we're currently playing this sound in a channel, we
+ // update the buffer that the channel's associated with
+ // and play it. This may not be the correct behavior.
+ mCurrentDatap = adp;
+ if (mChannelp)
+ {
+ mChannelp->updateBuffer();
+ mChannelp->play();
+ }
+ // Make sure the audio engine knows that we want to request this sound.
+ gAudiop->startNextTransfer();
+ }
+ }
+ }
+ else
+ {
+ // Add it to the preload list.
+ mPreloadMap[adp->getID()] = adp;
+ gAudiop->startNextTransfer();
+ }
+}
+
+
+bool LLAudioSource::hasPendingPreloads() const
+{
+ // Check to see if we've got any preloads on deck for this source
+ data_map::const_iterator iter;
+ for (iter = mPreloadMap.begin(); iter != mPreloadMap.end(); iter++)
+ {
+ LLAudioData *adp = iter->second;
+ // note: a bad UUID will forever be !hasDecodedData()
+ // but also !hasValidData(), hence the check for hasValidData()
+ if (!adp->hasDecodedData() && adp->hasValidData())
+ {
+ // This source is still waiting for a preload
+ return true;
+ }
+ }
+
+ return false;
+}
+
+
+LLAudioData * LLAudioSource::getCurrentData()
+{
+ return mCurrentDatap;
+}
+
+LLAudioData * LLAudioSource::getQueuedData()
+{
+ return mQueuedDatap;
+}
+
+LLAudioBuffer * LLAudioSource::getCurrentBuffer()
+{
+ if (!mCurrentDatap)
+ {
+ return NULL;
+ }
+
+ return mCurrentDatap->getBuffer();
+}
+
+
+
+
+//
+// LLAudioChannel implementation
+//
+
+
+LLAudioChannel::LLAudioChannel() :
+ mCurrentSourcep(NULL),
+ mCurrentBufferp(NULL),
+ mLoopedThisFrame(false),
+ mWaiting(false),
+ mSecondaryGain(1.0f)
+{
+}
+
+
+LLAudioChannel::~LLAudioChannel()
+{
+ // Need to disconnect any sources which are using this channel.
+ //llinfos << "Cleaning up audio channel" << llendl;
+ if (mCurrentSourcep)
+ {
+ mCurrentSourcep->setChannel(NULL);
+ }
+ mCurrentBufferp = NULL;
+}
+
+
+void LLAudioChannel::setSource(LLAudioSource *sourcep)
+{
+ //llinfos << this << ": setSource(" << sourcep << ")" << llendl;
+
+ if (!sourcep)
+ {
+ // Clearing the source for this channel, don't need to do anything.
+ //llinfos << "Clearing source for channel" << llendl;
+ cleanup();
+ mCurrentSourcep = NULL;
+ mWaiting = false;
+ return;
+ }
+
+ if (sourcep == mCurrentSourcep)
+ {
+ // Don't reallocate the channel, this will make FMOD goofy.
+ //llinfos << "Calling setSource with same source!" << llendl;
+ }
+
+ mCurrentSourcep = sourcep;
+
+
+ updateBuffer();
+ update3DPosition();
+}
+
+
+bool LLAudioChannel::updateBuffer()
+{
+ if (!mCurrentSourcep)
+ {
+ // This channel isn't associated with any source, nothing
+ // to be updated
+ return false;
+ }
+
+ // Initialize the channel's gain setting for this sound.
+ if(gAudiop)
+ {
+ setSecondaryGain(gAudiop->getSecondaryGain(mCurrentSourcep->getType()));
+ }
+
+ LLAudioBuffer *bufferp = mCurrentSourcep->getCurrentBuffer();
+ if (bufferp == mCurrentBufferp)
+ {
+ if (bufferp)
+ {
+ // The source hasn't changed what buffer it's playing
+ bufferp->mLastUseTimer.reset();
+ bufferp->mInUse = true;
+ }
+ return false;
+ }
+
+ //
+ // The source changed what buffer it's playing. We need to clean up
+ // the existing channel
+ //
+ cleanup();
+
+ mCurrentBufferp = bufferp;
+ if (bufferp)
+ {
+ bufferp->mLastUseTimer.reset();
+ bufferp->mInUse = true;
+ }
+
+ if (!mCurrentBufferp)
+ {
+ // There's no new buffer to be played, so we just abort.
+ return false;
+ }
+
+ return true;
+}
+
+
+
+
+//
+// LLAudioData implementation
+//
+
+
+LLAudioData::LLAudioData(const LLUUID &uuid) :
+ mID(uuid),
+ mBufferp(NULL),
+ mHasLocalData(false),
+ mHasDecodedData(false),
+ mHasValidData(true)
+{
+ if (uuid.isNull())
+ {
+ // This is a null sound.
+ return;
+ }
+
+ if (gAudiop && gAudiop->hasDecodedFile(uuid))
+ {
+ // Already have a decoded version, don't need to decode it.
+ mHasLocalData = true;
+ mHasDecodedData = true;
+ }
+ else if (gAssetStorage && gAssetStorage->hasLocalAsset(uuid, LLAssetType::AT_SOUND))
+ {
+ mHasLocalData = true;
+ }
+}
+
+
+bool LLAudioData::load()
+{
+ // For now, just assume we're going to use one buffer per audiodata.
+ if (mBufferp)
+ {
+ // We already have this sound in a buffer, don't do anything.
+ llinfos << "Already have a buffer for this sound, don't bother loading!" << llendl;
+ return true;
+ }
+
+ mBufferp = gAudiop->getFreeBuffer();
+ if (!mBufferp)
+ {
+ // No free buffers, abort.
+ llinfos << "Not able to allocate a new audio buffer, aborting." << llendl;
+ return false;
+ }
+
+ std::string uuid_str;
+ std::string wav_path;
+ mID.toString(uuid_str);
+ wav_path= gDirUtilp->getExpandedFilename(LL_PATH_CACHE,uuid_str) + ".dsf";
+
+ if (!mBufferp->loadWAV(wav_path))
+ {
+ // Hrm. Right now, let's unset the buffer, since it's empty.
+ gAudiop->cleanupBuffer(mBufferp);
+ mBufferp = NULL;
+
+ return false;
+ }
+ mBufferp->mAudioDatap = this;
+ return true;
+}
+
+
diff --git a/indra/llaudio/llaudioengine.h b/indra/llaudio/llaudioengine.h
new file mode 100644
index 0000000000..457fd93abe
--- /dev/null
+++ b/indra/llaudio/llaudioengine.h
@@ -0,0 +1,452 @@
+/**
+ * @file audioengine.h
+ * @brief Definition of LLAudioEngine base class abstracting the audio support
+ *
+ * $LicenseInfo:firstyear=2000&license=viewergpl$
+ *
+ * Copyright (c) 2000-2009, Linden Research, Inc.
+ *
+ * Second Life Viewer Source Code
+ * The source code in this file ("Source Code") is provided by Linden Lab
+ * to you under the terms of the GNU General Public License, version 2.0
+ * ("GPL"), unless you have obtained a separate licensing agreement
+ * ("Other License"), formally executed by you and Linden Lab. Terms of
+ * the GPL can be found in doc/GPL-license.txt in this distribution, or
+ * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
+ *
+ * There are special exceptions to the terms and conditions of the GPL as
+ * it is applied to this Source Code. View the full text of the exception
+ * in the file doc/FLOSS-exception.txt in this software distribution, or
+ * online at
+ * http://secondlifegrid.net/programs/open_source/licensing/flossexception
+ *
+ * By copying, modifying or distributing this software, you acknowledge
+ * that you have read and understood your obligations described above,
+ * and agree to abide by those obligations.
+ *
+ * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+ * COMPLETENESS OR PERFORMANCE.
+ * $/LicenseInfo$
+ */
+
+
+#ifndef LL_AUDIOENGINE_H
+#define LL_AUDIOENGINE_H
+
+#include <list>
+#include <map>
+
+#include "v3math.h"
+#include "v3dmath.h"
+#include "lltimer.h"
+#include "lluuid.h"
+#include "llframetimer.h"
+#include "llassettype.h"
+
+#include "lllistener.h"
+
+const F32 LL_WIND_UPDATE_INTERVAL = 0.1f;
+const F32 LL_ROLLOFF_MULTIPLIER_UNDER_WATER = 5.f; // How much sounds are weaker under water
+const F32 LL_WIND_UNDERWATER_CENTER_FREQ = 20.f;
+
+const F32 ATTACHED_OBJECT_TIMEOUT = 5.0f;
+const F32 DEFAULT_MIN_DISTANCE = 2.0f;
+
+#define MAX_CHANNELS 30
+#define MAX_BUFFERS 40 // Some extra for preloading, maybe?
+
+// This define is intended to allow us to switch from os based wav
+// file loading to vfs based wav file loading. The problem is that I
+// am unconvinced that the LLWaveFile works for loading sounds from
+// memory. So, until that is fixed up, changed, whatever, this remains
+// undefined.
+//#define USE_WAV_VFILE
+
+class LLVFS;
+
+class LLAudioSource;
+class LLAudioData;
+class LLAudioChannel;
+class LLAudioChannelOpenAL;
+class LLAudioBuffer;
+class LLStreamingAudioInterface;
+
+
+//
+// LLAudioEngine definition
+//
+
+class LLAudioEngine
+{
+ friend class LLAudioChannelOpenAL; // bleh. channel needs some listener methods.
+
+public:
+ enum LLAudioType
+ {
+ AUDIO_TYPE_NONE = 0,
+ AUDIO_TYPE_SFX = 1,
+ AUDIO_TYPE_UI = 2,
+ AUDIO_TYPE_AMBIENT = 3,
+ AUDIO_TYPE_COUNT = 4 // last
+ };
+
+ LLAudioEngine();
+ virtual ~LLAudioEngine();
+
+ // initialization/startup/shutdown
+ virtual bool init(const S32 num_channels, void *userdata);
+ virtual std::string getDriverName(bool verbose) = 0;
+ virtual void shutdown();
+
+ // Used by the mechanics of the engine
+ //virtual void processQueue(const LLUUID &sound_guid);
+ virtual void setListener(LLVector3 pos,LLVector3 vel,LLVector3 up,LLVector3 at);
+ virtual void updateWind(LLVector3 direction, F32 camera_height_above_water) = 0;
+ virtual void idle(F32 max_decode_time = 0.f);
+ virtual void updateChannels();
+
+ //
+ // "End user" functionality
+ //
+ virtual bool isWindEnabled();
+ virtual void enableWind(bool state_b);
+
+ // Use these for temporarily muting the audio system.
+ // Does not change buffers, initialization, etc. but
+ // stops playing new sounds.
+ virtual void setMuted(bool muted);
+ virtual bool getMuted() const { return mMuted; }
+#ifdef USE_PLUGIN_MEDIA
+ LLPluginClassMedia* initializeMedia(const std::string& media_type);
+#endif
+ F32 getMasterGain();
+ void setMasterGain(F32 gain);
+
+ F32 getSecondaryGain(S32 type);
+ void setSecondaryGain(S32 type, F32 gain);
+
+ F32 getInternetStreamGain();
+
+ virtual void setDopplerFactor(F32 factor);
+ virtual F32 getDopplerFactor();
+ virtual void setRolloffFactor(F32 factor);
+ virtual F32 getRolloffFactor();
+ virtual void setMaxWindGain(F32 gain);
+
+
+ // Methods actually related to setting up and removing sounds
+ // Owner ID is the owner of the object making the request
+ void triggerSound(const LLUUID &sound_id, const LLUUID& owner_id, const F32 gain,
+ const S32 type = LLAudioEngine::AUDIO_TYPE_NONE,
+ const LLVector3d &pos_global = LLVector3d::zero);
+ bool preloadSound(const LLUUID &id);
+
+ void addAudioSource(LLAudioSource *asp);
+ void cleanupAudioSource(LLAudioSource *asp);
+
+ LLAudioSource *findAudioSource(const LLUUID &source_id);
+ LLAudioData *getAudioData(const LLUUID &audio_uuid);
+
+ // Internet stream implementation manipulation
+ LLStreamingAudioInterface *getStreamingAudioImpl();
+ void setStreamingAudioImpl(LLStreamingAudioInterface *impl);
+ // Internet stream methods - these will call down into the *mStreamingAudioImpl if it exists
+ void startInternetStream(const std::string& url);
+ void stopInternetStream();
+ void pauseInternetStream(int pause);
+ void updateInternetStream(); // expected to be called often
+ int isInternetStreamPlaying();
+ // use a value from 0.0 to 1.0, inclusive
+ void setInternetStreamGain(F32 vol);
+ std::string getInternetStreamURL();
+
+ // For debugging usage
+ virtual LLVector3 getListenerPos();
+
+ LLAudioBuffer *getFreeBuffer(); // Get a free buffer, or flush an existing one if you have to.
+ LLAudioChannel *getFreeChannel(const F32 priority); // Get a free channel or flush an existing one if your priority is higher
+ void cleanupBuffer(LLAudioBuffer *bufferp);
+
+ bool hasDecodedFile(const LLUUID &uuid);
+ bool hasLocalFile(const LLUUID &uuid);
+
+ bool updateBufferForData(LLAudioData *adp, const LLUUID &audio_uuid = LLUUID::null);
+
+
+ // Asset callback when we're retrieved a sound from the asset server.
+ void startNextTransfer();
+ static void assetCallback(LLVFS *vfs, const LLUUID &uuid, LLAssetType::EType type, void *user_data, S32 result_code, LLExtStat ext_status);
+
+ friend class LLPipeline; // For debugging
+public:
+ F32 mMaxWindGain; // Hack. Public to set before fade in?
+
+protected:
+ virtual LLAudioBuffer *createBuffer() = 0;
+ virtual LLAudioChannel *createChannel() = 0;
+
+ virtual void initWind() = 0;
+ virtual void cleanupWind() = 0;
+ virtual void setInternalGain(F32 gain) = 0;
+
+ void commitDeferredChanges();
+
+ virtual void allocateListener() = 0;
+
+
+ // listener methods
+ virtual void setListenerPos(LLVector3 vec);
+ virtual void setListenerVelocity(LLVector3 vec);
+ virtual void orientListener(LLVector3 up, LLVector3 at);
+ virtual void translateListener(LLVector3 vec);
+
+
+ F64 mapWindVecToGain(LLVector3 wind_vec);
+ F64 mapWindVecToPitch(LLVector3 wind_vec);
+ F64 mapWindVecToPan(LLVector3 wind_vec);
+
+protected:
+ LLListener *mListenerp;
+
+ bool mMuted;
+ void* mUserData;
+
+ S32 mLastStatus;
+
+ S32 mNumChannels;
+ bool mEnableWind;
+
+ LLUUID mCurrentTransfer; // Audio file currently being transferred by the system
+ LLFrameTimer mCurrentTransferTimer;
+
+ // A list of all audio sources that are known to the viewer at this time.
+ // This is most likely a superset of the ones that we actually have audio
+ // data for, or are playing back.
+ typedef std::map<LLUUID, LLAudioSource *> source_map;
+ typedef std::map<LLUUID, LLAudioData *> data_map;
+
+ source_map mAllSources;
+ data_map mAllData;
+
+ LLAudioChannel *mChannels[MAX_CHANNELS];
+
+ // Buffers needs to change into a different data structure, as the number of buffers
+ // that we have active should be limited by RAM usage, not count.
+ LLAudioBuffer *mBuffers[MAX_BUFFERS];
+
+ F32 mMasterGain;
+ F32 mSecondaryGain[AUDIO_TYPE_COUNT];
+
+ F32 mNextWindUpdate;
+
+ LLFrameTimer mWindUpdateTimer;
+
+private:
+ void setDefaults();
+ LLStreamingAudioInterface *mStreamingAudioImpl;
+};
+
+
+
+
+//
+// Standard audio source. Can be derived from for special sources, such as those attached to objects.
+//
+
+
+class LLAudioSource
+{
+public:
+ // owner_id is the id of the agent responsible for making this sound
+ // play, for example, the owner of the object currently playing it
+ LLAudioSource(const LLUUID &id, const LLUUID& owner_id, const F32 gain, const S32 type = LLAudioEngine::AUDIO_TYPE_NONE);
+ virtual ~LLAudioSource();
+
+ virtual void update(); // Update this audio source
+ void updatePriority();
+
+ void preload(const LLUUID &audio_id); // Only used for preloading UI sounds, now.
+
+ void addAudioData(LLAudioData *adp, bool set_current = TRUE);
+
+ void setAmbient(const bool ambient) { mAmbient = ambient; }
+ bool isAmbient() const { return mAmbient; }
+
+ void setLoop(const bool loop) { mLoop = loop; }
+ bool isLoop() const { return mLoop; }
+
+ void setSyncMaster(const bool master) { mSyncMaster = master; }
+ bool isSyncMaster() const { return mSyncMaster; }
+
+ void setSyncSlave(const bool slave) { mSyncSlave = slave; }
+ bool isSyncSlave() const { return mSyncSlave; }
+
+ void setQueueSounds(const bool queue) { mQueueSounds = queue; }
+ bool isQueueSounds() const { return mQueueSounds; }
+
+ void setPlayedOnce(const bool played_once) { mPlayedOnce = played_once; }
+
+ void setType(S32 type) { mType = type; }
+ S32 getType() { return mType; }
+
+ void setPositionGlobal(const LLVector3d &position_global) { mPositionGlobal = position_global; }
+ LLVector3d getPositionGlobal() const { return mPositionGlobal; }
+ LLVector3 getVelocity() const { return mVelocity; }
+ F32 getPriority() const { return mPriority; }
+
+ // Gain should always be clamped between 0 and 1.
+ F32 getGain() const { return mGain; }
+ virtual void setGain(const F32 gain) { mGain = llclamp(gain, 0.f, 1.f); }
+
+ const LLUUID &getID() const { return mID; }
+ bool isDone();
+
+ LLAudioData *getCurrentData();
+ LLAudioData *getQueuedData();
+ LLAudioBuffer *getCurrentBuffer();
+
+ bool setupChannel();
+ bool play(const LLUUID &audio_id); // Start the audio source playing
+
+ bool hasPendingPreloads() const; // Has preloads that haven't been done yet
+
+ friend class LLAudioEngine;
+ friend class LLAudioChannel;
+protected:
+ void setChannel(LLAudioChannel *channelp);
+ LLAudioChannel *getChannel() const { return mChannelp; }
+
+protected:
+ LLUUID mID; // The ID of the source is that of the object if it's attached to an object.
+ LLUUID mOwnerID; // owner of the object playing the sound
+ F32 mPriority;
+ F32 mGain;
+ bool mAmbient;
+ bool mLoop;
+ bool mSyncMaster;
+ bool mSyncSlave;
+ bool mQueueSounds;
+ bool mPlayedOnce;
+ S32 mType;
+ LLVector3d mPositionGlobal;
+ LLVector3 mVelocity;
+
+ //LLAudioSource *mSyncMasterp; // If we're a slave, the source that we're synced to.
+ LLAudioChannel *mChannelp; // If we're currently playing back, this is the channel that we're assigned to.
+ LLAudioData *mCurrentDatap;
+ LLAudioData *mQueuedDatap;
+
+ typedef std::map<LLUUID, LLAudioData *> data_map;
+ data_map mPreloadMap;
+
+ LLFrameTimer mAgeTimer;
+};
+
+
+
+
+//
+// Generic metadata about a particular piece of audio data.
+// The actual data is handled by the derived LLAudioBuffer classes which are
+// derived for each audio engine.
+//
+
+
+class LLAudioData
+{
+public:
+ LLAudioData(const LLUUID &uuid);
+ bool load();
+
+ LLUUID getID() const { return mID; }
+ LLAudioBuffer *getBuffer() const { return mBufferp; }
+
+ bool hasLocalData() const { return mHasLocalData; }
+ bool hasDecodedData() const { return mHasDecodedData; }
+ bool hasValidData() const { return mHasValidData; }
+
+ void setHasLocalData(const bool hld) { mHasLocalData = hld; }
+ void setHasDecodedData(const bool hdd) { mHasDecodedData = hdd; }
+ void setHasValidData(const bool hvd) { mHasValidData = hvd; }
+
+ friend class LLAudioEngine; // Severe laziness, bad.
+
+protected:
+ LLUUID mID;
+ LLAudioBuffer *mBufferp; // If this data is being used by the audio system, a pointer to the buffer will be set here.
+ bool mHasLocalData;
+ bool mHasDecodedData;
+ bool mHasValidData;
+};
+
+
+//
+// Base class for an audio channel, i.e. a channel which is capable of playing back a sound.
+// Management of channels is done generically, methods for actually manipulating the channel
+// are derived for each audio engine.
+//
+
+
+class LLAudioChannel
+{
+public:
+ LLAudioChannel();
+ virtual ~LLAudioChannel();
+
+ virtual void setSource(LLAudioSource *sourcep);
+ LLAudioSource *getSource() const { return mCurrentSourcep; }
+
+ void setSecondaryGain(F32 gain) { mSecondaryGain = gain; }
+ F32 getSecondaryGain() { return mSecondaryGain; }
+
+ friend class LLAudioEngine;
+ friend class LLAudioSource;
+protected:
+ virtual void play() = 0;
+ virtual void playSynced(LLAudioChannel *channelp) = 0;
+ virtual void cleanup() = 0;
+ virtual bool isPlaying() = 0;
+ void setWaiting(const bool waiting) { mWaiting = waiting; }
+ bool isWaiting() const { return mWaiting; }
+
+ virtual bool updateBuffer(); // Check to see if the buffer associated with the source changed, and update if necessary.
+ virtual void update3DPosition() = 0;
+ virtual void updateLoop() = 0; // Update your loop/completion status, for use by queueing/syncing.
+protected:
+ LLAudioSource *mCurrentSourcep;
+ LLAudioBuffer *mCurrentBufferp;
+ bool mLoopedThisFrame;
+ bool mWaiting; // Waiting for sync.
+ F32 mSecondaryGain;
+};
+
+
+
+
+// Basically an interface class to the engine-specific implementation
+// of audio data that's ready for playback.
+// Will likely get more complex as we decide to do stuff like real streaming audio.
+
+
+class LLAudioBuffer
+{
+public:
+ virtual ~LLAudioBuffer() {};
+ virtual bool loadWAV(const std::string& filename) = 0;
+ virtual U32 getLength() = 0;
+
+ friend class LLAudioEngine;
+ friend class LLAudioChannel;
+ friend class LLAudioData;
+protected:
+ bool mInUse;
+ LLAudioData *mAudioDatap;
+ LLFrameTimer mLastUseTimer;
+};
+
+
+
+extern LLAudioEngine* gAudiop;
+
+#endif
diff --git a/indra/llaudio/llaudioengine_fmod.cpp b/indra/llaudio/llaudioengine_fmod.cpp
new file mode 100644
index 0000000000..7b12b62d53
--- /dev/null
+++ b/indra/llaudio/llaudioengine_fmod.cpp
@@ -0,0 +1,766 @@
+/**
+ * @file audioengine_fmod.cpp
+ * @brief Implementation of LLAudioEngine class abstracting the audio support as a FMOD 3D implementation
+ *
+ * $LicenseInfo:firstyear=2002&license=viewergpl$
+ *
+ * Copyright (c) 2002-2009, Linden Research, Inc.
+ *
+ * Second Life Viewer Source Code
+ * The source code in this file ("Source Code") is provided by Linden Lab
+ * to you under the terms of the GNU General Public License, version 2.0
+ * ("GPL"), unless you have obtained a separate licensing agreement
+ * ("Other License"), formally executed by you and Linden Lab. Terms of
+ * the GPL can be found in doc/GPL-license.txt in this distribution, or
+ * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
+ *
+ * There are special exceptions to the terms and conditions of the GPL as
+ * it is applied to this Source Code. View the full text of the exception
+ * in the file doc/FLOSS-exception.txt in this software distribution, or
+ * online at
+ * http://secondlifegrid.net/programs/open_source/licensing/flossexception
+ *
+ * By copying, modifying or distributing this software, you acknowledge
+ * that you have read and understood your obligations described above,
+ * and agree to abide by those obligations.
+ *
+ * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+ * COMPLETENESS OR PERFORMANCE.
+ * $/LicenseInfo$
+ */
+
+#include "linden_common.h"
+
+#include "llstreamingaudio.h"
+#include "llstreamingaudio_fmod.h"
+
+#include "llaudioengine_fmod.h"
+#include "lllistener_fmod.h"
+
+#include "llerror.h"
+#include "llmath.h"
+#include "llrand.h"
+
+#include "fmod.h"
+#include "fmod_errors.h"
+#include "lldir.h"
+#include "llapr.h"
+
+#include "sound_ids.h"
+
+
+extern "C" {
+ void * F_CALLBACKAPI windCallback(void *originalbuffer, void *newbuffer, int length, void* userdata);
+}
+
+FSOUND_DSPUNIT *gWindDSP = NULL;
+
+
+LLAudioEngine_FMOD::LLAudioEngine_FMOD()
+{
+ mInited = false;
+ mWindGen = NULL;
+}
+
+
+LLAudioEngine_FMOD::~LLAudioEngine_FMOD()
+{
+}
+
+
+bool LLAudioEngine_FMOD::init(const S32 num_channels, void* userdata)
+{
+ LLAudioEngine::init(num_channels, userdata);
+
+ // Reserve one extra channel for the http stream.
+ if (!FSOUND_SetMinHardwareChannels(num_channels + 1))
+ {
+ LL_WARNS("AppInit") << "FMOD::init[0](), error: " << FMOD_ErrorString(FSOUND_GetError()) << LL_ENDL;
+ }
+
+ LL_DEBUGS("AppInit") << "LLAudioEngine_FMOD::init() initializing FMOD" << LL_ENDL;
+
+ F32 version = FSOUND_GetVersion();
+ if (version < FMOD_VERSION)
+ {
+ LL_WARNS("AppInit") << "Error : You are using the wrong FMOD version (" << version
+ << ")! You should be using FMOD " << FMOD_VERSION << LL_ENDL;
+ //return false;
+ }
+
+ U32 fmod_flags = 0x0;
+
+#if LL_WINDOWS
+ // Windows needs to know which window is frontmost.
+ // This must be called before FSOUND_Init() per the FMOD docs.
+ // This could be used to let FMOD handle muting when we lose focus,
+ // but we don't actually want to do that because we want to distinguish
+ // between minimized and not-focused states.
+ if (!FSOUND_SetHWND(userdata))
+ {
+ LL_WARNS("AppInit") << "Error setting FMOD window: "
+ << FMOD_ErrorString(FSOUND_GetError()) << LL_ENDL;
+ return false;
+ }
+ // Play audio when we don't have focus.
+ // (For example, IM client on top of us.)
+ // This means we also try to play audio when minimized,
+ // so we manually handle muting in that case. JC
+ fmod_flags |= FSOUND_INIT_GLOBALFOCUS;
+#endif
+
+#if LL_LINUX
+ // initialize the FMOD engine
+
+ // This is a hack to use only FMOD's basic FPU mixer
+ // when the LL_VALGRIND environmental variable is set,
+ // otherwise valgrind will fall over on FMOD's MMX detection
+ if (getenv("LL_VALGRIND")) /*Flawfinder: ignore*/
+ {
+ LL_INFOS("AppInit") << "Pacifying valgrind in FMOD init." << LL_ENDL;
+ FSOUND_SetMixer(FSOUND_MIXER_QUALITY_FPU);
+ }
+
+ // If we don't set an output method, Linux FMOD always
+ // decides on OSS and fails otherwise. So we'll manually
+ // try ESD, then OSS, then ALSA.
+ // Why this order? See SL-13250, but in short, OSS emulated
+ // on top of ALSA is ironically more reliable than raw ALSA.
+ // Ack, and ESD has more reliable failure modes - but has worse
+ // latency - than all of them, so wins for now.
+ bool audio_ok = false;
+
+ if (!audio_ok)
+ if (NULL == getenv("LL_BAD_FMOD_ESD")) /*Flawfinder: ignore*/
+ {
+ LL_DEBUGS("AppInit") << "Trying ESD audio output..." << LL_ENDL;
+ if(FSOUND_SetOutput(FSOUND_OUTPUT_ESD) &&
+ FSOUND_Init(44100, num_channels, fmod_flags))
+ {
+ LL_DEBUGS("AppInit") << "ESD audio output initialized OKAY"
+ << LL_ENDL;
+ audio_ok = true;
+ } else {
+ LL_WARNS("AppInit") << "ESD audio output FAILED to initialize: "
+ << FMOD_ErrorString(FSOUND_GetError()) << LL_ENDL;
+ }
+ } else {
+ LL_DEBUGS("AppInit") << "ESD audio output SKIPPED" << LL_ENDL;
+ }
+
+ if (!audio_ok)
+ if (NULL == getenv("LL_BAD_FMOD_OSS")) /*Flawfinder: ignore*/
+ {
+ LL_DEBUGS("AppInit") << "Trying OSS audio output..." << LL_ENDL;
+ if(FSOUND_SetOutput(FSOUND_OUTPUT_OSS) &&
+ FSOUND_Init(44100, num_channels, fmod_flags))
+ {
+ LL_DEBUGS("AppInit") << "OSS audio output initialized OKAY" << LL_ENDL;
+ audio_ok = true;
+ } else {
+ LL_WARNS("AppInit") << "OSS audio output FAILED to initialize: "
+ << FMOD_ErrorString(FSOUND_GetError()) << LL_ENDL;
+ }
+ } else {
+ LL_DEBUGS("AppInit") << "OSS audio output SKIPPED" << LL_ENDL;
+ }
+
+ if (!audio_ok)
+ if (NULL == getenv("LL_BAD_FMOD_ALSA")) /*Flawfinder: ignore*/
+ {
+ LL_DEBUGS("AppInit") << "Trying ALSA audio output..." << LL_ENDL;
+ if(FSOUND_SetOutput(FSOUND_OUTPUT_ALSA) &&
+ FSOUND_Init(44100, num_channels, fmod_flags))
+ {
+ LL_DEBUGS("AppInit") << "ALSA audio output initialized OKAY" << LL_ENDL;
+ audio_ok = true;
+ } else {
+ LL_WARNS("AppInit") << "ALSA audio output FAILED to initialize: "
+ << FMOD_ErrorString(FSOUND_GetError()) << LL_ENDL;
+ }
+ } else {
+ LL_DEBUGS("AppInit") << "OSS audio output SKIPPED" << LL_ENDL;
+ }
+
+ if (!audio_ok)
+ {
+ LL_WARNS("AppInit") << "Overall audio init failure." << LL_ENDL;
+ return false;
+ }
+
+ // On Linux, FMOD causes a SIGPIPE for some netstream error
+ // conditions (an FMOD bug); ignore SIGPIPE so it doesn't crash us.
+ // NOW FIXED in FMOD 3.x since 2006-10-01.
+ //signal(SIGPIPE, SIG_IGN);
+
+ // We're interested in logging which output method we
+ // ended up with, for QA purposes.
+ switch (FSOUND_GetOutput())
+ {
+ case FSOUND_OUTPUT_NOSOUND: LL_DEBUGS("AppInit") << "Audio output: NoSound" << LL_ENDL; break;
+ case FSOUND_OUTPUT_OSS: LL_DEBUGS("AppInit") << "Audio output: OSS" << LL_ENDL; break;
+ case FSOUND_OUTPUT_ESD: LL_DEBUGS("AppInit") << "Audio output: ESD" << LL_ENDL; break;
+ case FSOUND_OUTPUT_ALSA: LL_DEBUGS("AppInit") << "Audio output: ALSA" << LL_ENDL; break;
+ default: LL_INFOS("AppInit") << "Audio output: Unknown!" << LL_ENDL; break;
+ };
+
+#else // LL_LINUX
+
+ // initialize the FMOD engine
+ if (!FSOUND_Init(44100, num_channels, fmod_flags))
+ {
+ LL_WARNS("AppInit") << "Error initializing FMOD: "
+ << FMOD_ErrorString(FSOUND_GetError()) << LL_ENDL;
+ return false;
+ }
+
+#endif
+
+ // set up our favourite FMOD-native streaming audio implementation if none has already been added
+ if (!getStreamingAudioImpl()) // no existing implementation added
+ setStreamingAudioImpl(new LLStreamingAudio_FMOD());
+
+ LL_DEBUGS("AppInit") << "LLAudioEngine_FMOD::init() FMOD initialized correctly" << LL_ENDL;
+
+ mInited = true;
+
+ return true;
+}
+
+
+std::string LLAudioEngine_FMOD::getDriverName(bool verbose)
+{
+ if (verbose)
+ {
+ F32 version = FSOUND_GetVersion();
+ return llformat("FMOD version %f", version);
+ }
+ else
+ {
+ return "FMOD";
+ }
+}
+
+
+void LLAudioEngine_FMOD::allocateListener(void)
+{
+ mListenerp = (LLListener *) new LLListener_FMOD();
+ if (!mListenerp)
+ {
+ llwarns << "Listener creation failed" << llendl;
+ }
+}
+
+
+void LLAudioEngine_FMOD::shutdown()
+{
+ if (gWindDSP)
+ {
+ FSOUND_DSP_SetActive(gWindDSP,false);
+ FSOUND_DSP_Free(gWindDSP);
+ }
+
+ stopInternetStream();
+
+ LLAudioEngine::shutdown();
+
+ llinfos << "LLAudioEngine_FMOD::shutdown() closing FMOD" << llendl;
+ FSOUND_Close();
+ llinfos << "LLAudioEngine_FMOD::shutdown() done closing FMOD" << llendl;
+
+ delete mListenerp;
+ mListenerp = NULL;
+}
+
+
+LLAudioBuffer * LLAudioEngine_FMOD::createBuffer()
+{
+ return new LLAudioBufferFMOD();
+}
+
+
+LLAudioChannel * LLAudioEngine_FMOD::createChannel()
+{
+ return new LLAudioChannelFMOD();
+}
+
+
+void LLAudioEngine_FMOD::initWind()
+{
+ mWindGen = new LLWindGen<MIXBUFFERFORMAT>;
+
+ if (!gWindDSP)
+ {
+ gWindDSP = FSOUND_DSP_Create(&windCallback, FSOUND_DSP_DEFAULTPRIORITY_CLEARUNIT + 20, mWindGen);
+ }
+ if (gWindDSP)
+ {
+ FSOUND_DSP_SetActive(gWindDSP, true);
+ }
+ mNextWindUpdate = 0.0;
+}
+
+
+void LLAudioEngine_FMOD::cleanupWind()
+{
+ if (gWindDSP)
+ {
+ FSOUND_DSP_SetActive(gWindDSP, false);
+ FSOUND_DSP_Free(gWindDSP);
+ gWindDSP = NULL;
+ }
+
+ delete mWindGen;
+ mWindGen = NULL;
+}
+
+
+//-----------------------------------------------------------------------
+void LLAudioEngine_FMOD::updateWind(LLVector3 wind_vec, F32 camera_height_above_water)
+{
+ LLVector3 wind_pos;
+ F64 pitch;
+ F64 center_freq;
+
+ if (!mEnableWind)
+ {
+ return;
+ }
+
+ if (mWindUpdateTimer.checkExpirationAndReset(LL_WIND_UPDATE_INTERVAL))
+ {
+
+ // wind comes in as Linden coordinate (+X = forward, +Y = left, +Z = up)
+ // need to convert this to the conventional orientation DS3D and OpenAL use
+ // where +X = right, +Y = up, +Z = backwards
+
+ wind_vec.setVec(-wind_vec.mV[1], wind_vec.mV[2], -wind_vec.mV[0]);
+
+ // cerr << "Wind update" << endl;
+
+ pitch = 1.0 + mapWindVecToPitch(wind_vec);
+ center_freq = 80.0 * pow(pitch,2.5*(mapWindVecToGain(wind_vec)+1.0));
+
+ mWindGen->mTargetFreq = (F32)center_freq;
+ mWindGen->mTargetGain = (F32)mapWindVecToGain(wind_vec) * mMaxWindGain;
+ mWindGen->mTargetPanGainR = (F32)mapWindVecToPan(wind_vec);
+ }
+}
+
+/*
+//-----------------------------------------------------------------------
+void LLAudioEngine_FMOD::setSourceMinDistance(U16 source_num, F64 distance)
+{
+ if (!mInited)
+ {
+ return;
+ }
+ if (mBuffer[source_num])
+ {
+ mMinDistance[source_num] = (F32) distance;
+ if (!FSOUND_Sample_SetMinMaxDistance(mBuffer[source_num],mMinDistance[source_num], mMaxDistance[source_num]))
+ {
+ llwarns << "FMOD::setSourceMinDistance(" << source_num << "), error: " << FMOD_ErrorString(FSOUND_GetError()) << llendl;
+ }
+ }
+}
+
+//-----------------------------------------------------------------------
+void LLAudioEngine_FMOD::setSourceMaxDistance(U16 source_num, F64 distance)
+{
+ if (!mInited)
+ {
+ return;
+ }
+ if (mBuffer[source_num])
+ {
+ mMaxDistance[source_num] = (F32) distance;
+ if (!FSOUND_Sample_SetMinMaxDistance(mBuffer[source_num],mMinDistance[source_num], mMaxDistance[source_num]))
+ {
+ llwarns << "FMOD::setSourceMaxDistance(" << source_num << "), error: " << FMOD_ErrorString(FSOUND_GetError()) << llendl;
+ }
+ }
+}
+
+//-----------------------------------------------------------------------
+void LLAudioEngine_FMOD::get3DParams(S32 source_num, S32 *volume, S32 *freq, S32 *inside, S32 *outside, LLVector3 *orient, S32 *out_volume, F32 *min_dist, F32 *max_dist)
+{
+ *volume = 0;
+ *freq = 0;
+ *inside = 0;
+ *outside = 0;
+ *orient = LLVector3::zero;
+ *out_volume = 0;
+ *min_dist = 0.f;
+ *max_dist = 0.f;
+}
+
+*/
+
+
+//-----------------------------------------------------------------------
+void LLAudioEngine_FMOD::setInternalGain(F32 gain)
+{
+ if (!mInited)
+ {
+ return;
+ }
+
+ gain = llclamp( gain, 0.0f, 1.0f );
+ FSOUND_SetSFXMasterVolume( llround( 255.0f * gain ) );
+
+ LLStreamingAudioInterface *saimpl = getStreamingAudioImpl();
+ if ( saimpl )
+ {
+ // fmod likes its streaming audio channel gain re-asserted after
+ // master volume change.
+ saimpl->setGain(saimpl->getGain());
+ }
+}
+
+//
+// LLAudioChannelFMOD implementation
+//
+
+LLAudioChannelFMOD::LLAudioChannelFMOD() : LLAudioChannel(), mChannelID(0), mLastSamplePos(0)
+{
+}
+
+
+LLAudioChannelFMOD::~LLAudioChannelFMOD()
+{
+ cleanup();
+}
+
+
+bool LLAudioChannelFMOD::updateBuffer()
+{
+ if (LLAudioChannel::updateBuffer())
+ {
+ // Base class update returned true, which means that we need to actually
+ // set up the channel for a different buffer.
+
+ LLAudioBufferFMOD *bufferp = (LLAudioBufferFMOD *)mCurrentSourcep->getCurrentBuffer();
+
+ // Grab the FMOD sample associated with the buffer
+ FSOUND_SAMPLE *samplep = bufferp->getSample();
+ if (!samplep)
+ {
+ // This is bad, there should ALWAYS be a sample associated with a legit
+ // buffer.
+ llerrs << "No FMOD sample!" << llendl;
+ return false;
+ }
+
+
+ // Actually play the sound. Start it off paused so we can do all the necessary
+ // setup.
+ mChannelID = FSOUND_PlaySoundEx(FSOUND_FREE, samplep, FSOUND_DSP_GetSFXUnit(), true);
+
+ //llinfos << "Setting up channel " << std::hex << mChannelID << std::dec << llendl;
+ }
+
+ // If we have a source for the channel, we need to update its gain.
+ if (mCurrentSourcep)
+ {
+ // SJB: warnings can spam and hurt framerate, disabling
+ if (!FSOUND_SetVolume(mChannelID, llround(getSecondaryGain() * mCurrentSourcep->getGain() * 255.0f)))
+ {
+// llwarns << "LLAudioChannelFMOD::updateBuffer error: " << FMOD_ErrorString(FSOUND_GetError()) << llendl;
+ }
+
+ if (!FSOUND_SetLoopMode(mChannelID, mCurrentSourcep->isLoop() ? FSOUND_LOOP_NORMAL : FSOUND_LOOP_OFF))
+ {
+// llwarns << "Channel " << mChannelID << "Source ID: " << mCurrentSourcep->getID()
+// << " at " << mCurrentSourcep->getPositionGlobal() << llendl;
+// llwarns << "LLAudioChannelFMOD::updateBuffer error: " << FMOD_ErrorString(FSOUND_GetError()) << llendl;
+ }
+ }
+
+ return true;
+}
+
+
+void LLAudioChannelFMOD::update3DPosition()
+{
+ if (!mChannelID)
+ {
+ // We're not actually a live channel (i.e., we're not playing back anything)
+ return;
+ }
+
+ LLAudioBufferFMOD *bufferp = (LLAudioBufferFMOD *)mCurrentBufferp;
+ if (!bufferp)
+ {
+ // We don't have a buffer associated with us (should really have been picked up
+ // by the above if.
+ return;
+ }
+
+ if (mCurrentSourcep->isAmbient())
+ {
+ // Ambient sound, don't need to do any positional updates.
+ bufferp->set3DMode(false);
+ }
+ else
+ {
+ // Localized sound. Update the position and velocity of the sound.
+ bufferp->set3DMode(true);
+
+ LLVector3 float_pos;
+ float_pos.setVec(mCurrentSourcep->getPositionGlobal());
+ if (!FSOUND_3D_SetAttributes(mChannelID, float_pos.mV, mCurrentSourcep->getVelocity().mV))
+ {
+ LL_DEBUGS("FMOD") << "LLAudioChannelFMOD::update3DPosition error: " << FMOD_ErrorString(FSOUND_GetError()) << LL_ENDL;
+ }
+ }
+}
+
+
+void LLAudioChannelFMOD::updateLoop()
+{
+ if (!mChannelID)
+ {
+ // May want to clear up the loop/sample counters.
+ return;
+ }
+
+ //
+ // Hack: We keep track of whether we looped or not by seeing when the
+ // sample position looks like it's going backwards. Not reliable; may
+ // yield false negatives.
+ //
+ U32 cur_pos = FSOUND_GetCurrentPosition(mChannelID);
+ if (cur_pos < (U32)mLastSamplePos)
+ {
+ mLoopedThisFrame = true;
+ }
+ mLastSamplePos = cur_pos;
+}
+
+
+void LLAudioChannelFMOD::cleanup()
+{
+ if (!mChannelID)
+ {
+ //llinfos << "Aborting cleanup with no channelID." << llendl;
+ return;
+ }
+
+ //llinfos << "Cleaning up channel: " << mChannelID << llendl;
+ if (!FSOUND_StopSound(mChannelID))
+ {
+ LL_DEBUGS("FMOD") << "LLAudioChannelFMOD::cleanup error: " << FMOD_ErrorString(FSOUND_GetError()) << llendl;
+ }
+
+ mCurrentBufferp = NULL;
+ mChannelID = 0;
+}
+
+
+void LLAudioChannelFMOD::play()
+{
+ if (!mChannelID)
+ {
+ llwarns << "Playing without a channelID, aborting" << llendl;
+ return;
+ }
+
+ if (!FSOUND_SetPaused(mChannelID, false))
+ {
+ llwarns << "LLAudioChannelFMOD::play error: " << FMOD_ErrorString(FSOUND_GetError()) << llendl;
+ }
+ getSource()->setPlayedOnce(true);
+}
+
+
+void LLAudioChannelFMOD::playSynced(LLAudioChannel *channelp)
+{
+ LLAudioChannelFMOD *fmod_channelp = (LLAudioChannelFMOD*)channelp;
+ if (!(fmod_channelp->mChannelID && mChannelID))
+ {
+ // Don't have channels allocated to both the master and the slave
+ return;
+ }
+
+ U32 position = FSOUND_GetCurrentPosition(fmod_channelp->mChannelID) % mCurrentBufferp->getLength();
+ // Try to match the position of our sync master
+ if (!FSOUND_SetCurrentPosition(mChannelID, position))
+ {
+ llwarns << "LLAudioChannelFMOD::playSynced unable to set current position" << llendl;
+ }
+
+ // Start us playing
+ play();
+}
+
+
+bool LLAudioChannelFMOD::isPlaying()
+{
+ if (!mChannelID)
+ {
+ return false;
+ }
+
+ return FSOUND_IsPlaying(mChannelID) && (!FSOUND_GetPaused(mChannelID));
+}
+
+
+
+//
+// LLAudioBufferFMOD implementation
+//
+
+
+LLAudioBufferFMOD::LLAudioBufferFMOD()
+{
+ mSamplep = NULL;
+}
+
+
+LLAudioBufferFMOD::~LLAudioBufferFMOD()
+{
+ if (mSamplep)
+ {
+ // Clean up the associated FMOD sample if it exists.
+ FSOUND_Sample_Free(mSamplep);
+ mSamplep = NULL;
+ }
+}
+
+
+bool LLAudioBufferFMOD::loadWAV(const std::string& filename)
+{
+ // Try to open a wav file from disk. This will eventually go away, as we don't
+ // really want to block doing this.
+ if (filename.empty())
+ {
+ // invalid filename, abort.
+ return false;
+ }
+
+ if (!LLAPRFile::isExist(filename, NULL, LL_APR_RPB))
+ {
+ // File not found, abort.
+ return false;
+ }
+
+ if (mSamplep)
+ {
+ // If there's already something loaded in this buffer, clean it up.
+ FSOUND_Sample_Free(mSamplep);
+ mSamplep = NULL;
+ }
+
+ // Load up the wav file into an fmod sample
+#if LL_WINDOWS
+ // MikeS. - Loading the sound file manually and then handing it over to FMOD,
+ // since FMOD uses posix IO internally,
+ // which doesn't work with unicode file paths.
+ LLFILE* sound_file = LLFile::fopen(filename,"rb"); /* Flawfinder: ignore */
+ if (sound_file)
+ {
+ fseek(sound_file,0,SEEK_END);
+ U32 file_length = ftell(sound_file); //Find the length of the file by seeking to the end and getting the offset
+ size_t read_count;
+ fseek(sound_file,0,SEEK_SET); //Seek back to the beginning
+ char* buffer = new char[file_length];
+ llassert(buffer);
+ read_count = fread((void*)buffer,file_length,1,sound_file);//Load it..
+ if(ferror(sound_file)==0 && (read_count == 1)){//No read error, and we got 1 chunk of our size...
+ unsigned int mode_flags = FSOUND_LOOP_NORMAL | FSOUND_LOADMEMORY;
+ //FSOUND_16BITS | FSOUND_MONO | FSOUND_LOADMEMORY | FSOUND_LOOP_NORMAL;
+ mSamplep = FSOUND_Sample_Load(FSOUND_UNMANAGED, buffer, mode_flags , 0, file_length);
+ }
+ delete[] buffer;
+ fclose(sound_file);
+ }
+#else
+ mSamplep = FSOUND_Sample_Load(FSOUND_UNMANAGED, filename.c_str(), FSOUND_LOOP_NORMAL, 0, 0);
+#endif
+
+ if (!mSamplep)
+ {
+ // We failed to load the file for some reason.
+ llwarns << "Could not load data '" << filename << "': "
+ << FMOD_ErrorString(FSOUND_GetError()) << llendl;
+
+ //
+ // If we EVER want to load wav files provided by end users, we need
+ // to rethink this!
+ //
+ // file is probably corrupt - remove it.
+ LLFile::remove(filename);
+ return false;
+ }
+
+ // Everything went well, return true
+ return true;
+}
+
+
+U32 LLAudioBufferFMOD::getLength()
+{
+ if (!mSamplep)
+ {
+ return 0;
+ }
+
+ return FSOUND_Sample_GetLength(mSamplep);
+}
+
+
+void LLAudioBufferFMOD::set3DMode(bool use3d)
+{
+ U16 current_mode = FSOUND_Sample_GetMode(mSamplep);
+
+ if (use3d)
+ {
+ if (!FSOUND_Sample_SetMode(mSamplep, (current_mode & (~FSOUND_2D))))
+ {
+ llwarns << "LLAudioBufferFMOD::set3DMode error: " << FMOD_ErrorString(FSOUND_GetError()) << llendl;
+ }
+ }
+ else
+ {
+ if (!FSOUND_Sample_SetMode(mSamplep, current_mode | FSOUND_2D))
+ {
+ llwarns << "LLAudioBufferFMOD::set3DMode error: " << FMOD_ErrorString(FSOUND_GetError()) << llendl;
+ }
+ }
+}
+
+
+void * F_CALLBACKAPI windCallback(void *originalbuffer, void *newbuffer, int length, void* userdata)
+{
+ // originalbuffer = fmod's original mixbuffer.
+ // newbuffer = the buffer passed from the previous DSP unit.
+ // length = length in samples at this mix time.
+ // param = user parameter passed through in FSOUND_DSP_Create.
+ //
+ // modify the buffer in some fashion
+
+ LLWindGen<LLAudioEngine_FMOD::MIXBUFFERFORMAT> *windgen =
+ (LLWindGen<LLAudioEngine_FMOD::MIXBUFFERFORMAT> *)userdata;
+ U8 stride;
+
+#if LL_DARWIN
+ stride = sizeof(LLAudioEngine_FMOD::MIXBUFFERFORMAT);
+#else
+ int mixertype = FSOUND_GetMixer();
+ if (mixertype == FSOUND_MIXER_BLENDMODE ||
+ mixertype == FSOUND_MIXER_QUALITY_FPU)
+ {
+ stride = 4;
+ }
+ else
+ {
+ stride = 2;
+ }
+#endif
+
+ newbuffer = windgen->windGenerate((LLAudioEngine_FMOD::MIXBUFFERFORMAT *)newbuffer, length, stride);
+
+ return newbuffer;
+}
diff --git a/indra/llaudio/llaudioengine_fmod.h b/indra/llaudio/llaudioengine_fmod.h
new file mode 100644
index 0000000000..3968657cba
--- /dev/null
+++ b/indra/llaudio/llaudioengine_fmod.h
@@ -0,0 +1,129 @@
+/**
+ * @file audioengine_fmod.h
+ * @brief Definition of LLAudioEngine class abstracting the audio
+ * support as a FMOD 3D implementation
+ *
+ * $LicenseInfo:firstyear=2002&license=viewergpl$
+ *
+ * Copyright (c) 2002-2009, Linden Research, Inc.
+ *
+ * Second Life Viewer Source Code
+ * The source code in this file ("Source Code") is provided by Linden Lab
+ * to you under the terms of the GNU General Public License, version 2.0
+ * ("GPL"), unless you have obtained a separate licensing agreement
+ * ("Other License"), formally executed by you and Linden Lab. Terms of
+ * the GPL can be found in doc/GPL-license.txt in this distribution, or
+ * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
+ *
+ * There are special exceptions to the terms and conditions of the GPL as
+ * it is applied to this Source Code. View the full text of the exception
+ * in the file doc/FLOSS-exception.txt in this software distribution, or
+ * online at
+ * http://secondlifegrid.net/programs/open_source/licensing/flossexception
+ *
+ * By copying, modifying or distributing this software, you acknowledge
+ * that you have read and understood your obligations described above,
+ * and agree to abide by those obligations.
+ *
+ * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+ * COMPLETENESS OR PERFORMANCE.
+ * $/LicenseInfo$
+ */
+
+#ifndef LL_AUDIOENGINE_FMOD_H
+#define LL_AUDIOENGINE_FMOD_H
+
+#include "llaudioengine.h"
+#include "lllistener_fmod.h"
+#include "llwindgen.h"
+
+#include "fmod.h"
+
+class LLAudioStreamManagerFMOD;
+
+class LLAudioEngine_FMOD : public LLAudioEngine
+{
+public:
+ LLAudioEngine_FMOD();
+ virtual ~LLAudioEngine_FMOD();
+
+ // initialization/startup/shutdown
+ virtual bool init(const S32 num_channels, void *user_data);
+ virtual std::string getDriverName(bool verbose);
+ virtual void allocateListener();
+
+ virtual void shutdown();
+
+ /*virtual*/ void initWind();
+ /*virtual*/ void cleanupWind();
+
+ /*virtual*/void updateWind(LLVector3 direction, F32 camera_height_above_water);
+
+#if LL_DARWIN
+ typedef S32 MIXBUFFERFORMAT;
+#else
+ typedef S16 MIXBUFFERFORMAT;
+#endif
+
+protected:
+ /*virtual*/ LLAudioBuffer *createBuffer(); // Get a free buffer, or flush an existing one if you have to.
+ /*virtual*/ LLAudioChannel *createChannel(); // Create a new audio channel.
+
+ /*virtual*/ void setInternalGain(F32 gain);
+protected:
+ static signed char F_CALLBACKAPI callbackMetaData(char* name, char* value, void* userdata);
+
+ //F32 mMinDistance[MAX_BUFFERS];
+ //F32 mMaxDistance[MAX_BUFFERS];
+
+ bool mInited;
+
+ // On Windows, userdata is the HWND of the application window.
+ void* mUserData;
+
+ LLWindGen<MIXBUFFERFORMAT> *mWindGen;
+};
+
+
+class LLAudioChannelFMOD : public LLAudioChannel
+{
+public:
+ LLAudioChannelFMOD();
+ virtual ~LLAudioChannelFMOD();
+
+protected:
+ /*virtual*/ void play();
+ /*virtual*/ void playSynced(LLAudioChannel *channelp);
+ /*virtual*/ void cleanup();
+ /*virtual*/ bool isPlaying();
+
+ /*virtual*/ bool updateBuffer();
+ /*virtual*/ void update3DPosition();
+ /*virtual*/ void updateLoop();
+
+protected:
+ int mChannelID;
+ S32 mLastSamplePos;
+};
+
+
+class LLAudioBufferFMOD : public LLAudioBuffer
+{
+public:
+ LLAudioBufferFMOD();
+ virtual ~LLAudioBufferFMOD();
+
+ /*virtual*/ bool loadWAV(const std::string& filename);
+ /*virtual*/ U32 getLength();
+ friend class LLAudioChannelFMOD;
+
+ void set3DMode(bool use3d);
+protected:
+ FSOUND_SAMPLE *getSample() { return mSamplep; }
+protected:
+ FSOUND_SAMPLE *mSamplep;
+};
+
+
+#endif // LL_AUDIOENGINE_FMOD_H
diff --git a/indra/llaudio/llaudioengine_openal.cpp b/indra/llaudio/llaudioengine_openal.cpp
new file mode 100644
index 0000000000..a5982ccbd6
--- /dev/null
+++ b/indra/llaudio/llaudioengine_openal.cpp
@@ -0,0 +1,546 @@
+/**
+ * @file audioengine_openal.cpp
+ * @brief implementation of audio engine using OpenAL
+ * support as a OpenAL 3D implementation
+ *
+ * $LicenseInfo:firstyear=2002&license=viewergpl$
+ *
+ * Copyright (c) 2002-2009, Linden Research, Inc.
+ *
+ * Second Life Viewer Source Code
+ * The source code in this file ("Source Code") is provided by Linden Lab
+ * to you under the terms of the GNU General Public License, version 2.0
+ * ("GPL"), unless you have obtained a separate licensing agreement
+ * ("Other License"), formally executed by you and Linden Lab. Terms of
+ * the GPL can be found in doc/GPL-license.txt in this distribution, or
+ * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
+ *
+ * There are special exceptions to the terms and conditions of the GPL as
+ * it is applied to this Source Code. View the full text of the exception
+ * in the file doc/FLOSS-exception.txt in this software distribution, or
+ * online at
+ * http://secondlifegrid.net/programs/open_source/licensing/flossexception
+ *
+ * By copying, modifying or distributing this software, you acknowledge
+ * that you have read and understood your obligations described above,
+ * and agree to abide by those obligations.
+ *
+ * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+ * COMPLETENESS OR PERFORMANCE.
+ * $/LicenseInfo$
+ */
+
+#include "linden_common.h"
+#include "lldir.h"
+
+#include "llaudioengine_openal.h"
+#include "lllistener_openal.h"
+
+
+LLAudioEngine_OpenAL::LLAudioEngine_OpenAL()
+ :
+ mWindGen(NULL),
+ mWindBuf(NULL),
+ mWindBufFreq(0),
+ mWindBufSamples(0),
+ mWindBufBytes(0),
+ mWindSource(AL_NONE),
+ mNumEmptyWindALBuffers(MAX_NUM_WIND_BUFFERS)
+{
+}
+
+// virtual
+LLAudioEngine_OpenAL::~LLAudioEngine_OpenAL()
+{
+}
+
+// virtual
+bool LLAudioEngine_OpenAL::init(const S32 num_channels, void* userdata)
+{
+ mWindGen = NULL;
+ LLAudioEngine::init(num_channels, userdata);
+
+ if(!alutInit(NULL, NULL))
+ {
+ llwarns << "LLAudioEngine_OpenAL::init() ALUT initialization failed: " << alutGetErrorString (alutGetError ()) << llendl;
+ return false;
+ }
+
+ llinfos << "LLAudioEngine_OpenAL::init() OpenAL successfully initialized" << llendl;
+
+ llinfos << "OpenAL version: "
+ << ll_safe_string(alGetString(AL_VERSION)) << llendl;
+ llinfos << "OpenAL vendor: "
+ << ll_safe_string(alGetString(AL_VENDOR)) << llendl;
+ llinfos << "OpenAL renderer: "
+ << ll_safe_string(alGetString(AL_RENDERER)) << llendl;
+
+ ALint major = alutGetMajorVersion ();
+ ALint minor = alutGetMinorVersion ();
+ llinfos << "ALUT version: " << major << "." << minor << llendl;
+
+ ALCdevice *device = alcGetContextsDevice(alcGetCurrentContext());
+
+ alcGetIntegerv(device, ALC_MAJOR_VERSION, 1, &major);
+ alcGetIntegerv(device, ALC_MAJOR_VERSION, 1, &minor);
+ llinfos << "ALC version: " << major << "." << minor << llendl;
+
+ llinfos << "ALC default device: "
+ << ll_safe_string(alcGetString(device,
+ ALC_DEFAULT_DEVICE_SPECIFIER))
+ << llendl;
+
+ return true;
+}
+
+// virtual
+std::string LLAudioEngine_OpenAL::getDriverName(bool verbose)
+{
+ ALCdevice *device = alcGetContextsDevice(alcGetCurrentContext());
+ std::ostringstream version;
+
+ version <<
+ "OpenAL";
+
+ if (verbose)
+ {
+ version <<
+ ", version " <<
+ ll_safe_string(alGetString(AL_VERSION)) <<
+ " / " <<
+ ll_safe_string(alGetString(AL_VENDOR)) <<
+ " / " <<
+ ll_safe_string(alGetString(AL_RENDERER));
+
+ if (device)
+ version <<
+ ": " <<
+ ll_safe_string(alcGetString(device,
+ ALC_DEFAULT_DEVICE_SPECIFIER));
+ }
+
+ return version.str();
+}
+
+// virtual
+void LLAudioEngine_OpenAL::allocateListener()
+{
+ mListenerp = (LLListener *) new LLListener_OpenAL();
+ if(!mListenerp)
+ {
+ llwarns << "LLAudioEngine_OpenAL::allocateListener() Listener creation failed" << llendl;
+ }
+}
+
+// virtual
+void LLAudioEngine_OpenAL::shutdown()
+{
+ llinfos << "About to LLAudioEngine::shutdown()" << llendl;
+ LLAudioEngine::shutdown();
+
+ llinfos << "About to alutExit()" << llendl;
+ if(!alutExit())
+ {
+ llwarns << "Nuts." << llendl;
+ llwarns << "LLAudioEngine_OpenAL::shutdown() ALUT shutdown failed: " << alutGetErrorString (alutGetError ()) << llendl;
+ }
+
+ llinfos << "LLAudioEngine_OpenAL::shutdown() OpenAL successfully shut down" << llendl;
+
+ delete mListenerp;
+ mListenerp = NULL;
+}
+
+LLAudioBuffer *LLAudioEngine_OpenAL::createBuffer()
+{
+ return new LLAudioBufferOpenAL();
+}
+
+LLAudioChannel *LLAudioEngine_OpenAL::createChannel()
+{
+ return new LLAudioChannelOpenAL();
+}
+
+void LLAudioEngine_OpenAL::setInternalGain(F32 gain)
+{
+ //llinfos << "LLAudioEngine_OpenAL::setInternalGain() Gain: " << gain << llendl;
+ alListenerf(AL_GAIN, gain);
+}
+
+LLAudioChannelOpenAL::LLAudioChannelOpenAL()
+ :
+ mALSource(AL_NONE),
+ mLastSamplePos(0)
+{
+ alGenSources(1, &mALSource);
+}
+
+LLAudioChannelOpenAL::~LLAudioChannelOpenAL()
+{
+ cleanup();
+ alDeleteSources(1, &mALSource);
+}
+
+void LLAudioChannelOpenAL::cleanup()
+{
+ alSourceStop(mALSource);
+ mCurrentBufferp = NULL;
+}
+
+void LLAudioChannelOpenAL::play()
+{
+ if (mALSource == AL_NONE)
+ {
+ llwarns << "Playing without a mALSource, aborting" << llendl;
+ return;
+ }
+
+ if(!isPlaying())
+ {
+ alSourcePlay(mALSource);
+ getSource()->setPlayedOnce(true);
+ }
+}
+
+void LLAudioChannelOpenAL::playSynced(LLAudioChannel *channelp)
+{
+ if (channelp)
+ {
+ LLAudioChannelOpenAL *masterchannelp =
+ (LLAudioChannelOpenAL*)channelp;
+ if (mALSource != AL_NONE &&
+ masterchannelp->mALSource != AL_NONE)
+ {
+ // we have channels allocated to master and slave
+ ALfloat master_offset;
+ alGetSourcef(masterchannelp->mALSource, AL_SEC_OFFSET,
+ &master_offset);
+
+ llinfos << "Syncing with master at " << master_offset
+ << "sec" << llendl;
+ // *TODO: detect when this fails, maybe use AL_SAMPLE_
+ alSourcef(mALSource, AL_SEC_OFFSET, master_offset);
+ }
+ }
+ play();
+}
+
+bool LLAudioChannelOpenAL::isPlaying()
+{
+ if (mALSource != AL_NONE)
+ {
+ ALint state;
+ alGetSourcei(mALSource, AL_SOURCE_STATE, &state);
+ if(state == AL_PLAYING)
+ {
+ return true;
+ }
+ }
+
+ return false;
+}
+
+bool LLAudioChannelOpenAL::updateBuffer()
+{
+ if (LLAudioChannel::updateBuffer())
+ {
+ // Base class update returned true, which means that we need to actually
+ // set up the source for a different buffer.
+ LLAudioBufferOpenAL *bufferp = (LLAudioBufferOpenAL *)mCurrentSourcep->getCurrentBuffer();
+ ALuint buffer = bufferp->getBuffer();
+ alSourcei(mALSource, AL_BUFFER, buffer);
+ mLastSamplePos = 0;
+ }
+
+ if (mCurrentSourcep)
+ {
+ alSourcef(mALSource, AL_GAIN,
+ mCurrentSourcep->getGain() * getSecondaryGain());
+ alSourcei(mALSource, AL_LOOPING,
+ mCurrentSourcep->isLoop() ? AL_TRUE : AL_FALSE);
+ alSourcef(mALSource, AL_ROLLOFF_FACTOR,
+ gAudiop->mListenerp->getRolloffFactor());
+ }
+
+ return true;
+}
+
+
+void LLAudioChannelOpenAL::updateLoop()
+{
+ if (mALSource == AL_NONE)
+ {
+ return;
+ }
+
+ // Hack: We keep track of whether we looped or not by seeing when the
+ // sample position looks like it's going backwards. Not reliable; may
+ // yield false negatives.
+ //
+ ALint cur_pos;
+ alGetSourcei(mALSource, AL_SAMPLE_OFFSET, &cur_pos);
+ if (cur_pos < mLastSamplePos)
+ {
+ mLoopedThisFrame = true;
+ }
+ mLastSamplePos = cur_pos;
+}
+
+
+void LLAudioChannelOpenAL::update3DPosition()
+{
+ if(!mCurrentSourcep)
+ {
+ return;
+ }
+ if (mCurrentSourcep->isAmbient())
+ {
+ alSource3f(mALSource, AL_POSITION, 0.0, 0.0, 0.0);
+ alSource3f(mALSource, AL_VELOCITY, 0.0, 0.0, 0.0);
+ alSourcei (mALSource, AL_SOURCE_RELATIVE, AL_TRUE);
+ } else {
+ LLVector3 float_pos;
+ float_pos.setVec(mCurrentSourcep->getPositionGlobal());
+ alSourcefv(mALSource, AL_POSITION, float_pos.mV);
+ alSourcefv(mALSource, AL_VELOCITY, mCurrentSourcep->getVelocity().mV);
+ alSourcei (mALSource, AL_SOURCE_RELATIVE, AL_FALSE);
+ }
+
+ alSourcef(mALSource, AL_GAIN, mCurrentSourcep->getGain() * getSecondaryGain());
+}
+
+LLAudioBufferOpenAL::LLAudioBufferOpenAL()
+{
+ mALBuffer = AL_NONE;
+}
+
+LLAudioBufferOpenAL::~LLAudioBufferOpenAL()
+{
+ cleanup();
+}
+
+void LLAudioBufferOpenAL::cleanup()
+{
+ if(mALBuffer != AL_NONE)
+ {
+ alDeleteBuffers(1, &mALBuffer);
+ mALBuffer = AL_NONE;
+ }
+}
+
+bool LLAudioBufferOpenAL::loadWAV(const std::string& filename)
+{
+ cleanup();
+ mALBuffer = alutCreateBufferFromFile(filename.c_str());
+ if(mALBuffer == AL_NONE)
+ {
+ ALenum error = alutGetError();
+ if (gDirUtilp->fileExists(filename))
+ {
+ llwarns <<
+ "LLAudioBufferOpenAL::loadWAV() Error loading "
+ << filename
+ << " " << alutGetErrorString(error) << llendl;
+ }
+ else
+ {
+ // It's common for the file to not actually exist.
+ lldebugs <<
+ "LLAudioBufferOpenAL::loadWAV() Error loading "
+ << filename
+ << " " << alutGetErrorString(error) << llendl;
+ }
+ return false;
+ }
+
+ return true;
+}
+
+U32 LLAudioBufferOpenAL::getLength()
+{
+ if(mALBuffer == AL_NONE)
+ {
+ return 0;
+ }
+ ALint length;
+ alGetBufferi(mALBuffer, AL_SIZE, &length);
+ return length / 2; // convert size in bytes to size in (16-bit) samples
+}
+
+// ------------
+
+void LLAudioEngine_OpenAL::initWind()
+{
+ ALenum error;
+ llinfos << "LLAudioEngine_OpenAL::initWind() start" << llendl;
+
+ mNumEmptyWindALBuffers = MAX_NUM_WIND_BUFFERS;
+
+ alGetError(); /* clear error */
+
+ alGenSources(1,&mWindSource);
+
+ if((error=alGetError()) != AL_NO_ERROR)
+ {
+ llwarns << "LLAudioEngine_OpenAL::initWind() Error creating wind sources: "<<error<<llendl;
+ }
+
+ mWindGen = new LLWindGen<WIND_SAMPLE_T>;
+
+ mWindBufFreq = mWindGen->getInputSamplingRate();
+ mWindBufSamples = llceil(mWindBufFreq * WIND_BUFFER_SIZE_SEC);
+ mWindBufBytes = mWindBufSamples * 2 /*stereo*/ * sizeof(WIND_SAMPLE_T);
+
+ mWindBuf = new WIND_SAMPLE_T [mWindBufSamples * 2 /*stereo*/];
+
+ if(mWindBuf==NULL)
+ {
+ llerrs << "LLAudioEngine_OpenAL::initWind() Error creating wind memory buffer" << llendl;
+ mEnableWind=false;
+ }
+
+ llinfos << "LLAudioEngine_OpenAL::initWind() done" << llendl;
+}
+
+void LLAudioEngine_OpenAL::cleanupWind()
+{
+ llinfos << "LLAudioEngine_OpenAL::cleanupWind()" << llendl;
+
+ if (mWindSource != AL_NONE)
+ {
+ // detach and delete all outstanding buffers on the wind source
+ alSourceStop(mWindSource);
+ ALint processed;
+ alGetSourcei(mWindSource, AL_BUFFERS_PROCESSED, &processed);
+ while (processed--)
+ {
+ ALuint buffer = AL_NONE;
+ alSourceUnqueueBuffers(mWindSource, 1, &buffer);
+ alDeleteBuffers(1, &buffer);
+ }
+
+ // delete the wind source itself
+ alDeleteSources(1, &mWindSource);
+
+ mWindSource = AL_NONE;
+ }
+
+ delete[] mWindBuf;
+ mWindBuf = NULL;
+
+ delete mWindGen;
+ mWindGen = NULL;
+}
+
+void LLAudioEngine_OpenAL::updateWind(LLVector3 wind_vec, F32 camera_altitude)
+{
+ LLVector3 wind_pos;
+ F64 pitch;
+ F64 center_freq;
+ ALenum error;
+
+ if (!mEnableWind)
+ return;
+
+ if(!mWindBuf)
+ return;
+
+ if (mWindUpdateTimer.checkExpirationAndReset(LL_WIND_UPDATE_INTERVAL))
+ {
+
+ // wind comes in as Linden coordinate (+X = forward, +Y = left, +Z = up)
+ // need to convert this to the conventional orientation DS3D and OpenAL use
+ // where +X = right, +Y = up, +Z = backwards
+
+ wind_vec.setVec(-wind_vec.mV[1], wind_vec.mV[2], -wind_vec.mV[0]);
+
+ pitch = 1.0 + mapWindVecToPitch(wind_vec);
+ center_freq = 80.0 * pow(pitch,2.5*(mapWindVecToGain(wind_vec)+1.0));
+
+ mWindGen->mTargetFreq = (F32)center_freq;
+ mWindGen->mTargetGain = (F32)mapWindVecToGain(wind_vec) * mMaxWindGain;
+ mWindGen->mTargetPanGainR = (F32)mapWindVecToPan(wind_vec);
+
+ alSourcei(mWindSource, AL_LOOPING, AL_FALSE);
+ alSource3f(mWindSource, AL_POSITION, 0.0, 0.0, 0.0);
+ alSource3f(mWindSource, AL_VELOCITY, 0.0, 0.0, 0.0);
+ alSourcef(mWindSource, AL_ROLLOFF_FACTOR, 0.0);
+ alSourcei(mWindSource, AL_SOURCE_RELATIVE, AL_TRUE);
+ }
+
+ // ok lets make a wind buffer now
+
+ ALint processed, queued, unprocessed;
+ alGetSourcei(mWindSource, AL_BUFFERS_PROCESSED, &processed);
+ alGetSourcei(mWindSource, AL_BUFFERS_QUEUED, &queued);
+ unprocessed = queued - processed;
+
+ // ensure that there are always at least 3x as many filled buffers
+ // queued as we managed to empty since last time.
+ mNumEmptyWindALBuffers = llmin(mNumEmptyWindALBuffers + processed * 3 - unprocessed, MAX_NUM_WIND_BUFFERS-unprocessed);
+ mNumEmptyWindALBuffers = llmax(mNumEmptyWindALBuffers, 0);
+
+ //llinfos << "mNumEmptyWindALBuffers: " << mNumEmptyWindALBuffers <<" (" << unprocessed << ":" << processed << ")" << llendl;
+
+ while(processed--) // unqueue old buffers
+ {
+ ALuint buffer;
+ ALenum error;
+ alGetError(); /* clear error */
+ alSourceUnqueueBuffers(mWindSource, 1, &buffer);
+ error = alGetError();
+ if(error != AL_NO_ERROR)
+ {
+ llwarns << "LLAudioEngine_OpenAL::updateWind() error swapping (unqueuing) buffers" << llendl;
+ }
+ else
+ {
+ alDeleteBuffers(1, &buffer);
+ }
+ }
+
+ unprocessed += mNumEmptyWindALBuffers;
+ while (mNumEmptyWindALBuffers > 0) // fill+queue new buffers
+ {
+ ALuint buffer;
+ alGetError(); /* clear error */
+ alGenBuffers(1,&buffer);
+ if((error=alGetError()) != AL_NO_ERROR)
+ {
+ llwarns << "LLAudioEngine_OpenAL::initWind() Error creating wind buffer: " << error << llendl;
+ break;
+ }
+
+ alBufferData(buffer,
+ AL_FORMAT_STEREO16,
+ mWindGen->windGenerate(mWindBuf,
+ mWindBufSamples, 2),
+ mWindBufBytes,
+ mWindBufFreq);
+ error = alGetError();
+ if(error != AL_NO_ERROR)
+ {
+ llwarns << "LLAudioEngine_OpenAL::updateWind() error swapping (bufferdata) buffers" << llendl;
+ }
+
+ alSourceQueueBuffers(mWindSource, 1, &buffer);
+ error = alGetError();
+ if(error != AL_NO_ERROR)
+ {
+ llwarns << "LLAudioEngine_OpenAL::updateWind() error swapping (queuing) buffers" << llendl;
+ }
+
+ --mNumEmptyWindALBuffers;
+ }
+
+ ALint playing;
+ alGetSourcei(mWindSource, AL_SOURCE_STATE, &playing);
+ if(playing != AL_PLAYING)
+ {
+ alSourcePlay(mWindSource);
+
+ lldebugs << "Wind had stopped - probably ran out of buffers - restarting: " << (unprocessed+mNumEmptyWindALBuffers) << " now queued." << llendl;
+ }
+}
+
diff --git a/indra/llaudio/llaudioengine_openal.h b/indra/llaudio/llaudioengine_openal.h
new file mode 100644
index 0000000000..5aca03e195
--- /dev/null
+++ b/indra/llaudio/llaudioengine_openal.h
@@ -0,0 +1,114 @@
+/**
+ * @file audioengine_openal.cpp
+ * @brief implementation of audio engine using OpenAL
+ * support as a OpenAL 3D implementation
+ *
+ *
+ * $LicenseInfo:firstyear=2002&license=viewergpl$
+ *
+ * Copyright (c) 2002-2009, Linden Research, Inc.
+ *
+ * Second Life Viewer Source Code
+ * The source code in this file ("Source Code") is provided by Linden Lab
+ * to you under the terms of the GNU General Public License, version 2.0
+ * ("GPL"), unless you have obtained a separate licensing agreement
+ * ("Other License"), formally executed by you and Linden Lab. Terms of
+ * the GPL can be found in doc/GPL-license.txt in this distribution, or
+ * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
+ *
+ * There are special exceptions to the terms and conditions of the GPL as
+ * it is applied to this Source Code. View the full text of the exception
+ * in the file doc/FLOSS-exception.txt in this software distribution, or
+ * online at
+ * http://secondlifegrid.net/programs/open_source/licensing/flossexception
+ *
+ * By copying, modifying or distributing this software, you acknowledge
+ * that you have read and understood your obligations described above,
+ * and agree to abide by those obligations.
+ *
+ * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+ * COMPLETENESS OR PERFORMANCE.
+ * $/LicenseInfo$
+ */
+
+
+#ifndef LL_AUDIOENGINE_OPENAL_H
+#define LL_AUDIOENGINE_OPENAL_H
+
+#include "llaudioengine.h"
+#include "lllistener_openal.h"
+#include "llwindgen.h"
+
+class LLAudioEngine_OpenAL : public LLAudioEngine
+{
+ public:
+ LLAudioEngine_OpenAL();
+ virtual ~LLAudioEngine_OpenAL();
+
+ virtual bool init(const S32 num_channels, void *user_data);
+ virtual std::string getDriverName(bool verbose);
+ virtual void allocateListener();
+
+ virtual void shutdown();
+
+ void setInternalGain(F32 gain);
+
+ LLAudioBuffer* createBuffer();
+ LLAudioChannel* createChannel();
+
+ /*virtual*/ void initWind();
+ /*virtual*/ void cleanupWind();
+ /*virtual*/ void updateWind(LLVector3 direction, F32 camera_altitude);
+
+ private:
+ void * windDSP(void *newbuffer, int length);
+ typedef S16 WIND_SAMPLE_T;
+ LLWindGen<WIND_SAMPLE_T> *mWindGen;
+ S16 *mWindBuf;
+ U32 mWindBufFreq;
+ U32 mWindBufSamples;
+ U32 mWindBufBytes;
+ ALuint mWindSource;
+ int mNumEmptyWindALBuffers;
+
+ static const int MAX_NUM_WIND_BUFFERS = 80;
+ static const float WIND_BUFFER_SIZE_SEC = 0.05f; // 1/20th sec
+};
+
+class LLAudioChannelOpenAL : public LLAudioChannel
+{
+ public:
+ LLAudioChannelOpenAL();
+ virtual ~LLAudioChannelOpenAL();
+ protected:
+ /*virtual*/ void play();
+ /*virtual*/ void playSynced(LLAudioChannel *channelp);
+ /*virtual*/ void cleanup();
+ /*virtual*/ bool isPlaying();
+
+ /*virtual*/ bool updateBuffer();
+ /*virtual*/ void update3DPosition();
+ /*virtual*/ void updateLoop();
+
+ ALuint mALSource;
+ ALint mLastSamplePos;
+};
+
+class LLAudioBufferOpenAL : public LLAudioBuffer{
+ public:
+ LLAudioBufferOpenAL();
+ virtual ~LLAudioBufferOpenAL();
+
+ bool loadWAV(const std::string& filename);
+ U32 getLength();
+
+ friend class LLAudioChannelOpenAL;
+ protected:
+ void cleanup();
+ ALuint getBuffer() {return mALBuffer;}
+
+ ALuint mALBuffer;
+};
+
+#endif
diff --git a/indra/llaudio/lllistener.cpp b/indra/llaudio/lllistener.cpp
new file mode 100644
index 0000000000..846c6bccb5
--- /dev/null
+++ b/indra/llaudio/lllistener.cpp
@@ -0,0 +1,142 @@
+/**
+ * @file listener.cpp
+ * @brief Implementation of LISTENER class abstracting the audio support
+ *
+ * $LicenseInfo:firstyear=2000&license=viewergpl$
+ *
+ * Copyright (c) 2000-2009, Linden Research, Inc.
+ *
+ * Second Life Viewer Source Code
+ * The source code in this file ("Source Code") is provided by Linden Lab
+ * to you under the terms of the GNU General Public License, version 2.0
+ * ("GPL"), unless you have obtained a separate licensing agreement
+ * ("Other License"), formally executed by you and Linden Lab. Terms of
+ * the GPL can be found in doc/GPL-license.txt in this distribution, or
+ * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
+ *
+ * There are special exceptions to the terms and conditions of the GPL as
+ * it is applied to this Source Code. View the full text of the exception
+ * in the file doc/FLOSS-exception.txt in this software distribution, or
+ * online at
+ * http://secondlifegrid.net/programs/open_source/licensing/flossexception
+ *
+ * By copying, modifying or distributing this software, you acknowledge
+ * that you have read and understood your obligations described above,
+ * and agree to abide by those obligations.
+ *
+ * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+ * COMPLETENESS OR PERFORMANCE.
+ * $/LicenseInfo$
+ */
+
+#include "linden_common.h"
+
+#include "lllistener.h"
+
+#define DEFAULT_AT 0.0f,0.0f,-1.0f
+#define DEFAULT_UP 0.0f,1.0f,0.0f
+
+//-----------------------------------------------------------------------
+// constructor
+//-----------------------------------------------------------------------
+LLListener::LLListener()
+{
+ init();
+}
+
+//-----------------------------------------------------------------------
+LLListener::~LLListener()
+{
+}
+
+//-----------------------------------------------------------------------
+void LLListener::init(void)
+{
+ mPosition.zeroVec();
+ mListenAt.setVec(DEFAULT_AT);
+ mListenUp.setVec(DEFAULT_UP);
+ mVelocity.zeroVec();
+}
+
+//-----------------------------------------------------------------------
+void LLListener::translate(LLVector3 offset)
+{
+ mPosition += offset;
+}
+
+//-----------------------------------------------------------------------
+void LLListener::setPosition(LLVector3 pos)
+{
+ mPosition = pos;
+}
+
+//-----------------------------------------------------------------------
+LLVector3 LLListener::getPosition(void)
+{
+ return(mPosition);
+}
+
+//-----------------------------------------------------------------------
+LLVector3 LLListener::getAt(void)
+{
+ return(mListenAt);
+}
+
+//-----------------------------------------------------------------------
+LLVector3 LLListener::getUp(void)
+{
+ return(mListenUp);
+}
+
+//-----------------------------------------------------------------------
+void LLListener::setVelocity(LLVector3 vel)
+{
+ mVelocity = vel;
+}
+
+//-----------------------------------------------------------------------
+void LLListener::orient(LLVector3 up, LLVector3 at)
+{
+ mListenUp = up;
+ mListenAt = at;
+}
+
+//-----------------------------------------------------------------------
+void LLListener::set(LLVector3 pos, LLVector3 vel, LLVector3 up, LLVector3 at)
+{
+ mPosition = pos;
+ mVelocity = vel;
+
+ setPosition(pos);
+ setVelocity(vel);
+ orient(up,at);
+}
+
+//-----------------------------------------------------------------------
+void LLListener::setDopplerFactor(F32 factor)
+{
+}
+
+//-----------------------------------------------------------------------
+F32 LLListener::getDopplerFactor()
+{
+ return (1.f);
+}
+
+//-----------------------------------------------------------------------
+void LLListener::setRolloffFactor(F32 factor)
+{
+}
+
+//-----------------------------------------------------------------------
+F32 LLListener::getRolloffFactor()
+{
+ return (1.f);
+}
+
+//-----------------------------------------------------------------------
+void LLListener::commitDeferredChanges()
+{
+}
+
diff --git a/indra/llaudio/lllistener.h b/indra/llaudio/lllistener.h
new file mode 100644
index 0000000000..e94fbe853f
--- /dev/null
+++ b/indra/llaudio/lllistener.h
@@ -0,0 +1,78 @@
+/**
+ * @file listener.h
+ * @brief Description of LISTENER base class abstracting the audio support.
+ *
+ * $LicenseInfo:firstyear=2000&license=viewergpl$
+ *
+ * Copyright (c) 2000-2009, Linden Research, Inc.
+ *
+ * Second Life Viewer Source Code
+ * The source code in this file ("Source Code") is provided by Linden Lab
+ * to you under the terms of the GNU General Public License, version 2.0
+ * ("GPL"), unless you have obtained a separate licensing agreement
+ * ("Other License"), formally executed by you and Linden Lab. Terms of
+ * the GPL can be found in doc/GPL-license.txt in this distribution, or
+ * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
+ *
+ * There are special exceptions to the terms and conditions of the GPL as
+ * it is applied to this Source Code. View the full text of the exception
+ * in the file doc/FLOSS-exception.txt in this software distribution, or
+ * online at
+ * http://secondlifegrid.net/programs/open_source/licensing/flossexception
+ *
+ * By copying, modifying or distributing this software, you acknowledge
+ * that you have read and understood your obligations described above,
+ * and agree to abide by those obligations.
+ *
+ * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+ * COMPLETENESS OR PERFORMANCE.
+ * $/LicenseInfo$
+ */
+
+#ifndef LL_LISTENER_H
+#define LL_LISTENER_H
+
+#include "v3math.h"
+
+class LLListener
+{
+ private:
+ protected:
+ LLVector3 mPosition;
+ LLVector3 mVelocity;
+ LLVector3 mListenAt;
+ LLVector3 mListenUp;
+
+ public:
+
+ private:
+ protected:
+ public:
+ LLListener();
+ virtual ~LLListener();
+ virtual void init();
+
+ virtual void set(LLVector3 pos, LLVector3 vel, LLVector3 up, LLVector3 at);
+
+ virtual void setPosition(LLVector3 pos);
+ virtual void setVelocity(LLVector3 vel);
+
+ virtual void orient(LLVector3 up, LLVector3 at);
+ virtual void translate(LLVector3 offset);
+
+ virtual void setDopplerFactor(F32 factor);
+ virtual void setRolloffFactor(F32 factor);
+
+ virtual LLVector3 getPosition();
+ virtual LLVector3 getAt();
+ virtual LLVector3 getUp();
+
+ virtual F32 getDopplerFactor();
+ virtual F32 getRolloffFactor();
+
+ virtual void commitDeferredChanges();
+};
+
+#endif
+
diff --git a/indra/llaudio/lllistener_ds3d.h b/indra/llaudio/lllistener_ds3d.h
new file mode 100644
index 0000000000..1ff9c170c4
--- /dev/null
+++ b/indra/llaudio/lllistener_ds3d.h
@@ -0,0 +1,74 @@
+/**
+ * @file listener_ds3d.h
+ * @brief Description of LISTENER class abstracting the audio support
+ * as a DirectSound 3D implementation (windows only)
+ *
+ * $LicenseInfo:firstyear=2000&license=viewergpl$
+ *
+ * Copyright (c) 2000-2009, Linden Research, Inc.
+ *
+ * Second Life Viewer Source Code
+ * The source code in this file ("Source Code") is provided by Linden Lab
+ * to you under the terms of the GNU General Public License, version 2.0
+ * ("GPL"), unless you have obtained a separate licensing agreement
+ * ("Other License"), formally executed by you and Linden Lab. Terms of
+ * the GPL can be found in doc/GPL-license.txt in this distribution, or
+ * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
+ *
+ * There are special exceptions to the terms and conditions of the GPL as
+ * it is applied to this Source Code. View the full text of the exception
+ * in the file doc/FLOSS-exception.txt in this software distribution, or
+ * online at
+ * http://secondlifegrid.net/programs/open_source/licensing/flossexception
+ *
+ * By copying, modifying or distributing this software, you acknowledge
+ * that you have read and understood your obligations described above,
+ * and agree to abide by those obligations.
+ *
+ * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+ * COMPLETENESS OR PERFORMANCE.
+ * $/LicenseInfo$
+ */
+
+#ifndef LL_LISTENER_DS3D_H
+#define LL_LISTENER_DS3D_H
+
+#include "lllistener.h"
+
+#include <dmusici.h>
+#include <dsound.h>
+#include <ks.h>
+
+class LLListener_DS3D : public LLListener
+{
+ private:
+ protected:
+ IDirectSound3DListener8 *m3DListener;
+ public:
+
+ private:
+ protected:
+ public:
+ LLListener_DS3D();
+ virtual ~LLListener_DS3D();
+ virtual void init();
+
+ virtual void setDS3DLPtr (IDirectSound3DListener8 *listener_p);
+
+ virtual void translate(LLVector3 offset);
+ virtual void setPosition(LLVector3 pos);
+ virtual void setVelocity(LLVector3 vel);
+ virtual void orient(LLVector3 up, LLVector3 at);
+
+ virtual void setDopplerFactor(F32 factor);
+ virtual F32 getDopplerFactor();
+ virtual void setRolloffFactor(F32 factor);
+ virtual F32 getRolloffFactor();
+
+ virtual void commitDeferredChanges();
+};
+
+#endif
+
+
diff --git a/indra/llaudio/lllistener_fmod.cpp b/indra/llaudio/lllistener_fmod.cpp
new file mode 100644
index 0000000000..57ad461b02
--- /dev/null
+++ b/indra/llaudio/lllistener_fmod.cpp
@@ -0,0 +1,131 @@
+/**
+ * @file listener_fmod.cpp
+ * @brief implementation of LISTENER class abstracting the audio
+ * support as a FMOD 3D implementation (windows only)
+ *
+ * $LicenseInfo:firstyear=2002&license=viewergpl$
+ *
+ * Copyright (c) 2002-2009, Linden Research, Inc.
+ *
+ * Second Life Viewer Source Code
+ * The source code in this file ("Source Code") is provided by Linden Lab
+ * to you under the terms of the GNU General Public License, version 2.0
+ * ("GPL"), unless you have obtained a separate licensing agreement
+ * ("Other License"), formally executed by you and Linden Lab. Terms of
+ * the GPL can be found in doc/GPL-license.txt in this distribution, or
+ * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
+ *
+ * There are special exceptions to the terms and conditions of the GPL as
+ * it is applied to this Source Code. View the full text of the exception
+ * in the file doc/FLOSS-exception.txt in this software distribution, or
+ * online at
+ * http://secondlifegrid.net/programs/open_source/licensing/flossexception
+ *
+ * By copying, modifying or distributing this software, you acknowledge
+ * that you have read and understood your obligations described above,
+ * and agree to abide by those obligations.
+ *
+ * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+ * COMPLETENESS OR PERFORMANCE.
+ * $/LicenseInfo$
+ */
+
+#include "linden_common.h"
+#include "llaudioengine.h"
+#include "lllistener_fmod.h"
+#include "fmod.h"
+
+//-----------------------------------------------------------------------
+// constructor
+//-----------------------------------------------------------------------
+LLListener_FMOD::LLListener_FMOD()
+{
+ init();
+}
+
+//-----------------------------------------------------------------------
+LLListener_FMOD::~LLListener_FMOD()
+{
+}
+
+//-----------------------------------------------------------------------
+void LLListener_FMOD::init(void)
+{
+ // do inherited
+ LLListener::init();
+ mDopplerFactor = 1.0f;
+ mRolloffFactor = 1.0f;
+}
+
+//-----------------------------------------------------------------------
+void LLListener_FMOD::translate(LLVector3 offset)
+{
+ LLListener::translate(offset);
+
+ FSOUND_3D_Listener_SetAttributes(mPosition.mV, NULL, mListenAt.mV[0],mListenAt.mV[1],mListenAt.mV[2], mListenUp.mV[0],mListenUp.mV[1],mListenUp.mV[2]);
+}
+
+//-----------------------------------------------------------------------
+void LLListener_FMOD::setPosition(LLVector3 pos)
+{
+ LLListener::setPosition(pos);
+
+ FSOUND_3D_Listener_SetAttributes(pos.mV, NULL, mListenAt.mV[0],mListenAt.mV[1],mListenAt.mV[2], mListenUp.mV[0],mListenUp.mV[1],mListenUp.mV[2]);
+}
+
+//-----------------------------------------------------------------------
+void LLListener_FMOD::setVelocity(LLVector3 vel)
+{
+ LLListener::setVelocity(vel);
+
+ FSOUND_3D_Listener_SetAttributes(NULL, vel.mV, mListenAt.mV[0],mListenAt.mV[1],mListenAt.mV[2], mListenUp.mV[0],mListenUp.mV[1],mListenUp.mV[2]);
+}
+
+//-----------------------------------------------------------------------
+void LLListener_FMOD::orient(LLVector3 up, LLVector3 at)
+{
+ LLListener::orient(up, at);
+
+ // Welcome to the transition between right and left
+ // (coordinate systems, that is)
+ // Leaving the at vector alone results in a L/R reversal
+ // since DX is left-handed and we (LL, OpenGL, OpenAL) are right-handed
+ at = -at;
+
+ FSOUND_3D_Listener_SetAttributes(NULL, NULL, at.mV[0],at.mV[1],at.mV[2], up.mV[0],up.mV[1],up.mV[2]);
+}
+
+//-----------------------------------------------------------------------
+void LLListener_FMOD::commitDeferredChanges()
+{
+ FSOUND_Update();
+}
+
+
+void LLListener_FMOD::setRolloffFactor(F32 factor)
+{
+ mRolloffFactor = factor;
+ FSOUND_3D_SetRolloffFactor(factor);
+}
+
+
+F32 LLListener_FMOD::getRolloffFactor()
+{
+ return mRolloffFactor;
+}
+
+
+void LLListener_FMOD::setDopplerFactor(F32 factor)
+{
+ mDopplerFactor = factor;
+ FSOUND_3D_SetDopplerFactor(factor);
+}
+
+
+F32 LLListener_FMOD::getDopplerFactor()
+{
+ return mDopplerFactor;
+}
+
+
diff --git a/indra/llaudio/lllistener_fmod.h b/indra/llaudio/lllistener_fmod.h
new file mode 100644
index 0000000000..5a48ec8b68
--- /dev/null
+++ b/indra/llaudio/lllistener_fmod.h
@@ -0,0 +1,64 @@
+/**
+ * @file listener_fmod.h
+ * @brief Description of LISTENER class abstracting the audio support
+ * as an FMOD 3D implementation (windows and Linux)
+ *
+ * $LicenseInfo:firstyear=2002&license=viewergpl$
+ *
+ * Copyright (c) 2002-2009, Linden Research, Inc.
+ *
+ * Second Life Viewer Source Code
+ * The source code in this file ("Source Code") is provided by Linden Lab
+ * to you under the terms of the GNU General Public License, version 2.0
+ * ("GPL"), unless you have obtained a separate licensing agreement
+ * ("Other License"), formally executed by you and Linden Lab. Terms of
+ * the GPL can be found in doc/GPL-license.txt in this distribution, or
+ * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
+ *
+ * There are special exceptions to the terms and conditions of the GPL as
+ * it is applied to this Source Code. View the full text of the exception
+ * in the file doc/FLOSS-exception.txt in this software distribution, or
+ * online at
+ * http://secondlifegrid.net/programs/open_source/licensing/flossexception
+ *
+ * By copying, modifying or distributing this software, you acknowledge
+ * that you have read and understood your obligations described above,
+ * and agree to abide by those obligations.
+ *
+ * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+ * COMPLETENESS OR PERFORMANCE.
+ * $/LicenseInfo$
+ */
+
+#ifndef LL_LISTENER_FMOD_H
+#define LL_LISTENER_FMOD_H
+
+#include "lllistener.h"
+
+class LLListener_FMOD : public LLListener
+{
+ public:
+ LLListener_FMOD();
+ virtual ~LLListener_FMOD();
+ virtual void init();
+
+ virtual void translate(LLVector3 offset);
+ virtual void setPosition(LLVector3 pos);
+ virtual void setVelocity(LLVector3 vel);
+ virtual void orient(LLVector3 up, LLVector3 at);
+ virtual void commitDeferredChanges();
+
+ virtual void setDopplerFactor(F32 factor);
+ virtual F32 getDopplerFactor();
+ virtual void setRolloffFactor(F32 factor);
+ virtual F32 getRolloffFactor();
+
+ protected:
+ F32 mDopplerFactor;
+ F32 mRolloffFactor;
+};
+
+#endif
+
+
diff --git a/indra/llaudio/lllistener_openal.cpp b/indra/llaudio/lllistener_openal.cpp
new file mode 100644
index 0000000000..a96ebd5dba
--- /dev/null
+++ b/indra/llaudio/lllistener_openal.cpp
@@ -0,0 +1,116 @@
+/**
+ * @file audioengine_openal.cpp
+ * @brief implementation of audio engine using OpenAL
+ * support as a OpenAL 3D implementation
+ *
+ * $LicenseInfo:firstyear=2002&license=viewergpl$
+ *
+ * Copyright (c) 2002-2009, Linden Research, Inc.
+ *
+ * Second Life Viewer Source Code
+ * The source code in this file ("Source Code") is provided by Linden Lab
+ * to you under the terms of the GNU General Public License, version 2.0
+ * ("GPL"), unless you have obtained a separate licensing agreement
+ * ("Other License"), formally executed by you and Linden Lab. Terms of
+ * the GPL can be found in doc/GPL-license.txt in this distribution, or
+ * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
+ *
+ * There are special exceptions to the terms and conditions of the GPL as
+ * it is applied to this Source Code. View the full text of the exception
+ * in the file doc/FLOSS-exception.txt in this software distribution, or
+ * online at
+ * http://secondlifegrid.net/programs/open_source/licensing/flossexception
+ *
+ * By copying, modifying or distributing this software, you acknowledge
+ * that you have read and understood your obligations described above,
+ * and agree to abide by those obligations.
+ *
+ * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+ * COMPLETENESS OR PERFORMANCE.
+ * $/LicenseInfo$
+ */
+
+#include "linden_common.h"
+#include "llaudioengine.h"
+
+#include "lllistener_openal.h"
+
+LLListener_OpenAL::LLListener_OpenAL()
+{
+ init();
+}
+
+LLListener_OpenAL::~LLListener_OpenAL()
+{
+}
+
+void LLListener_OpenAL::translate(LLVector3 offset)
+{
+ //llinfos << "LLListener_OpenAL::translate() : " << offset << llendl;
+ LLListener::translate(offset);
+}
+
+void LLListener_OpenAL::setPosition(LLVector3 pos)
+{
+ //llinfos << "LLListener_OpenAL::setPosition() : " << pos << llendl;
+ LLListener::setPosition(pos);
+}
+
+void LLListener_OpenAL::setVelocity(LLVector3 vel)
+{
+ LLListener::setVelocity(vel);
+}
+
+void LLListener_OpenAL::orient(LLVector3 up, LLVector3 at)
+{
+ //llinfos << "LLListener_OpenAL::orient() up: " << up << " at: " << at << llendl;
+ LLListener::orient(up, at);
+}
+
+void LLListener_OpenAL::commitDeferredChanges()
+{
+ ALfloat orientation[6];
+ orientation[0] = mListenAt.mV[0];
+ orientation[1] = mListenAt.mV[1];
+ orientation[2] = mListenAt.mV[2];
+ orientation[3] = mListenUp.mV[0];
+ orientation[4] = mListenUp.mV[1];
+ orientation[5] = mListenUp.mV[2];
+
+ ALfloat velocity[3];
+ velocity[0] = mVelocity.mV[0];
+ velocity[1] = mVelocity.mV[1];
+ velocity[2] = mVelocity.mV[2];
+
+ alListenerfv(AL_ORIENTATION, orientation);
+ alListenerfv(AL_POSITION, mPosition.mV);
+ alListenerfv(AL_VELOCITY, velocity);
+}
+
+void LLListener_OpenAL::setDopplerFactor(F32 factor)
+{
+ //llinfos << "LLListener_OpenAL::setDopplerFactor() : " << factor << llendl;
+ alDopplerFactor(factor);
+}
+
+F32 LLListener_OpenAL::getDopplerFactor()
+{
+ ALfloat factor;
+ factor = alGetFloat(AL_DOPPLER_FACTOR);
+ //llinfos << "LLListener_OpenAL::getDopplerFactor() : " << factor << llendl;
+ return factor;
+}
+
+
+void LLListener_OpenAL::setRolloffFactor(F32 factor)
+{
+ mRolloffFactor = factor;
+}
+
+F32 LLListener_OpenAL::getRolloffFactor()
+{
+ return mRolloffFactor;
+}
+
+
diff --git a/indra/llaudio/lllistener_openal.h b/indra/llaudio/lllistener_openal.h
new file mode 100644
index 0000000000..0dfeea5c90
--- /dev/null
+++ b/indra/llaudio/lllistener_openal.h
@@ -0,0 +1,64 @@
+/**
+ * @file listener_openal.h
+ * @brief Description of LISTENER class abstracting the audio support
+ * as an OpenAL implementation
+ *
+ * $LicenseInfo:firstyear=2000&license=viewergpl$
+ *
+ * Copyright (c) 2000-2009, Linden Research, Inc.
+ *
+ * Second Life Viewer Source Code
+ * The source code in this file ("Source Code") is provided by Linden Lab
+ * to you under the terms of the GNU General Public License, version 2.0
+ * ("GPL"), unless you have obtained a separate licensing agreement
+ * ("Other License"), formally executed by you and Linden Lab. Terms of
+ * the GPL can be found in doc/GPL-license.txt in this distribution, or
+ * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
+ *
+ * There are special exceptions to the terms and conditions of the GPL as
+ * it is applied to this Source Code. View the full text of the exception
+ * in the file doc/FLOSS-exception.txt in this software distribution, or
+ * online at
+ * http://secondlifegrid.net/programs/open_source/licensing/flossexception
+ *
+ * By copying, modifying or distributing this software, you acknowledge
+ * that you have read and understood your obligations described above,
+ * and agree to abide by those obligations.
+ *
+ * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+ * COMPLETENESS OR PERFORMANCE.
+ * $/LicenseInfo$
+ */
+
+#ifndef LL_LISTENER_OPENAL_H
+#define LL_LISTENER_OPENAL_H
+
+#include "lllistener.h"
+
+#include "AL/al.h"
+#include "AL/alut.h"
+
+class LLListener_OpenAL : public LLListener
+{
+ public:
+ LLListener_OpenAL();
+ virtual ~LLListener_OpenAL();
+
+ virtual void translate(LLVector3 offset);
+ virtual void setPosition(LLVector3 pos);
+ virtual void setVelocity(LLVector3 vel);
+ virtual void orient(LLVector3 up, LLVector3 at);
+ virtual void commitDeferredChanges();
+
+ virtual void setDopplerFactor(F32 factor);
+ virtual F32 getDopplerFactor();
+ virtual void setRolloffFactor(F32 factor);
+ virtual F32 getRolloffFactor();
+
+ protected:
+ F32 mRolloffFactor;
+};
+
+#endif
+
diff --git a/indra/llaudio/llstreamingaudio.h b/indra/llaudio/llstreamingaudio.h
new file mode 100644
index 0000000000..aa89e6a177
--- /dev/null
+++ b/indra/llaudio/llstreamingaudio.h
@@ -0,0 +1,56 @@
+/**
+ * @file streamingaudio.h
+ * @author Tofu Linden
+ * @brief Definition of LLStreamingAudioInterface base class abstracting the streaming audio interface
+ *
+ * $LicenseInfo:firstyear=2009&license=viewergpl$
+ *
+ * Copyright (c) 2009, Linden Research, Inc.
+ *
+ * Second Life Viewer Source Code
+ * The source code in this file ("Source Code") is provided by Linden Lab
+ * to you under the terms of the GNU General Public License, version 2.0
+ * ("GPL"), unless you have obtained a separate licensing agreement
+ * ("Other License"), formally executed by you and Linden Lab. Terms of
+ * the GPL can be found in doc/GPL-license.txt in this distribution, or
+ * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
+ *
+ * There are special exceptions to the terms and conditions of the GPL as
+ * it is applied to this Source Code. View the full text of the exception
+ * in the file doc/FLOSS-exception.txt in this software distribution, or
+ * online at
+ * http://secondlifegrid.net/programs/open_source/licensing/flossexception
+ *
+ * By copying, modifying or distributing this software, you acknowledge
+ * that you have read and understood your obligations described above,
+ * and agree to abide by those obligations.
+ *
+ * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+ * COMPLETENESS OR PERFORMANCE.
+ * $/LicenseInfo$
+ */
+
+#ifndef LL_STREAMINGAUDIO_H
+#define LL_STREAMINGAUDIO_H
+
+#include "stdtypes.h" // from llcommon
+
+// Entirely abstract. Based exactly on the historic API.
+class LLStreamingAudioInterface
+{
+ public:
+ virtual ~LLStreamingAudioInterface() {}
+
+ virtual void start(const std::string& url) = 0;
+ virtual void stop() = 0;
+ virtual void pause(int pause) = 0;
+ virtual void update() = 0;
+ virtual int isPlaying() = 0;
+ // use a value from 0.0 to 1.0, inclusive
+ virtual void setGain(F32 vol) = 0;
+ virtual F32 getGain() = 0;
+ virtual std::string getURL() = 0;
+};
+
+#endif // LL_STREAMINGAUDIO_H
diff --git a/indra/llaudio/llstreamingaudio_fmod.cpp b/indra/llaudio/llstreamingaudio_fmod.cpp
new file mode 100644
index 0000000000..a71a87203c
--- /dev/null
+++ b/indra/llaudio/llstreamingaudio_fmod.cpp
@@ -0,0 +1,362 @@
+/**
+ * @file streamingaudio_fmod.cpp
+ * @brief LLStreamingAudio_FMOD implementation
+ *
+ * $LicenseInfo:firstyear=2009&license=viewergpl$
+ *
+ * Copyright (c) 2009, Linden Research, Inc.
+ *
+ * Second Life Viewer Source Code
+ * The source code in this file ("Source Code") is provided by Linden Lab
+ * to you under the terms of the GNU General Public License, version 2.0
+ * ("GPL"), unless you have obtained a separate licensing agreement
+ * ("Other License"), formally executed by you and Linden Lab. Terms of
+ * the GPL can be found in doc/GPL-license.txt in this distribution, or
+ * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
+ *
+ * There are special exceptions to the terms and conditions of the GPL as
+ * it is applied to this Source Code. View the full text of the exception
+ * in the file doc/FLOSS-exception.txt in this software distribution, or
+ * online at
+ * http://secondlifegrid.net/programs/open_source/licensing/flossexception
+ *
+ * By copying, modifying or distributing this software, you acknowledge
+ * that you have read and understood your obligations described above,
+ * and agree to abide by those obligations.
+ *
+ * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+ * COMPLETENESS OR PERFORMANCE.
+ * $/LicenseInfo$
+ */
+
+#include "linden_common.h"
+
+#include "llmath.h"
+
+#include "fmod.h"
+#include "fmod_errors.h"
+
+#include "llstreamingaudio_fmod.h"
+
+
+class LLAudioStreamManagerFMOD
+{
+public:
+ LLAudioStreamManagerFMOD(const std::string& url);
+ int startStream();
+ bool stopStream(); // Returns true if the stream was successfully stopped.
+ bool ready();
+
+ const std::string& getURL() { return mInternetStreamURL; }
+
+ int getOpenState();
+protected:
+ FSOUND_STREAM* mInternetStream;
+ bool mReady;
+
+ std::string mInternetStreamURL;
+};
+
+
+
+//---------------------------------------------------------------------------
+// Internet Streaming
+//---------------------------------------------------------------------------
+LLStreamingAudio_FMOD::LLStreamingAudio_FMOD() :
+ mCurrentInternetStreamp(NULL),
+ mFMODInternetStreamChannel(-1),
+ mGain(1.0f)
+{
+ // Number of milliseconds of audio to buffer for the audio card.
+ // Must be larger than the usual Second Life frame stutter time.
+ FSOUND_Stream_SetBufferSize(200);
+
+ // Here's where we set the size of the network buffer and some buffering
+ // parameters. In this case we want a network buffer of 16k, we want it
+ // to prebuffer 40% of that when we first connect, and we want it
+ // to rebuffer 80% of that whenever we encounter a buffer underrun.
+
+ // Leave the net buffer properties at the default.
+ //FSOUND_Stream_Net_SetBufferProperties(20000, 40, 80);
+}
+
+
+LLStreamingAudio_FMOD::~LLStreamingAudio_FMOD()
+{
+ // nothing interesting/safe to do.
+}
+
+
+void LLStreamingAudio_FMOD::start(const std::string& url)
+{
+ //if (!mInited)
+ //{
+ // llwarns << "startInternetStream before audio initialized" << llendl;
+ // return;
+ //}
+
+ // "stop" stream but don't clear url, etc. in case url == mInternetStreamURL
+ stop();
+
+ if (!url.empty())
+ {
+ llinfos << "Starting internet stream: " << url << llendl;
+ mCurrentInternetStreamp = new LLAudioStreamManagerFMOD(url);
+ mURL = url;
+ }
+ else
+ {
+ llinfos << "Set internet stream to null" << llendl;
+ mURL.clear();
+ }
+}
+
+
+void LLStreamingAudio_FMOD::update()
+{
+ // Kill dead internet streams, if possible
+ std::list<LLAudioStreamManagerFMOD *>::iterator iter;
+ for (iter = mDeadStreams.begin(); iter != mDeadStreams.end();)
+ {
+ LLAudioStreamManagerFMOD *streamp = *iter;
+ if (streamp->stopStream())
+ {
+ llinfos << "Closed dead stream" << llendl;
+ delete streamp;
+ mDeadStreams.erase(iter++);
+ }
+ else
+ {
+ iter++;
+ }
+ }
+
+ // Don't do anything if there are no streams playing
+ if (!mCurrentInternetStreamp)
+ {
+ return;
+ }
+
+ int open_state = mCurrentInternetStreamp->getOpenState();
+
+ if (!open_state)
+ {
+ // Stream is live
+
+ // start the stream if it's ready
+ if (mFMODInternetStreamChannel < 0)
+ {
+ mFMODInternetStreamChannel = mCurrentInternetStreamp->startStream();
+
+ if (mFMODInternetStreamChannel != -1)
+ {
+ // Reset volume to previously set volume
+ setGain(getGain());
+ FSOUND_SetPaused(mFMODInternetStreamChannel, false);
+ }
+ }
+ }
+
+ switch(open_state)
+ {
+ default:
+ case 0:
+ // success
+ break;
+ case -1:
+ // stream handle is invalid
+ llwarns << "InternetStream - invalid handle" << llendl;
+ stop();
+ return;
+ case -2:
+ // opening
+ break;
+ case -3:
+ // failed to open, file not found, perhaps
+ llwarns << "InternetSteam - failed to open" << llendl;
+ stop();
+ return;
+ case -4:
+ // connecting
+ break;
+ case -5:
+ // buffering
+ break;
+ }
+
+}
+
+void LLStreamingAudio_FMOD::stop()
+{
+ if (mFMODInternetStreamChannel != -1)
+ {
+ FSOUND_SetPaused(mFMODInternetStreamChannel, true);
+ FSOUND_SetPriority(mFMODInternetStreamChannel, 0);
+ mFMODInternetStreamChannel = -1;
+ }
+
+ if (mCurrentInternetStreamp)
+ {
+ llinfos << "Stopping internet stream: " << mCurrentInternetStreamp->getURL() << llendl;
+ if (mCurrentInternetStreamp->stopStream())
+ {
+ delete mCurrentInternetStreamp;
+ }
+ else
+ {
+ llwarns << "Pushing stream to dead list: " << mCurrentInternetStreamp->getURL() << llendl;
+ mDeadStreams.push_back(mCurrentInternetStreamp);
+ }
+ mCurrentInternetStreamp = NULL;
+ //mURL.clear();
+ }
+}
+
+void LLStreamingAudio_FMOD::pause(int pauseopt)
+{
+ if (pauseopt < 0)
+ {
+ pauseopt = mCurrentInternetStreamp ? 1 : 0;
+ }
+
+ if (pauseopt)
+ {
+ if (mCurrentInternetStreamp)
+ {
+ stop();
+ }
+ }
+ else
+ {
+ start(getURL());
+ }
+}
+
+
+// A stream is "playing" if it has been requested to start. That
+// doesn't necessarily mean audio is coming out of the speakers.
+int LLStreamingAudio_FMOD::isPlaying()
+{
+ if (mCurrentInternetStreamp)
+ {
+ return 1; // Active and playing
+ }
+ else if (!mURL.empty())
+ {
+ return 2; // "Paused"
+ }
+ else
+ {
+ return 0;
+ }
+}
+
+
+F32 LLStreamingAudio_FMOD::getGain()
+{
+ return mGain;
+}
+
+
+std::string LLStreamingAudio_FMOD::getURL()
+{
+ return mURL;
+}
+
+
+void LLStreamingAudio_FMOD::setGain(F32 vol)
+{
+ mGain = vol;
+
+ if (mFMODInternetStreamChannel != -1)
+ {
+ vol = llclamp(vol, 0.f, 1.f);
+ int vol_int = llround(vol * 255.f);
+ FSOUND_SetVolumeAbsolute(mFMODInternetStreamChannel, vol_int);
+ }
+}
+
+
+///////////////////////////////////////////////////////
+// manager of possibly-multiple internet audio streams
+
+LLAudioStreamManagerFMOD::LLAudioStreamManagerFMOD(const std::string& url) :
+ mInternetStream(NULL),
+ mReady(false)
+{
+ mInternetStreamURL = url;
+ mInternetStream = FSOUND_Stream_Open(url.c_str(), FSOUND_NORMAL | FSOUND_NONBLOCKING, 0, 0);
+ if (!mInternetStream)
+ {
+ llwarns << "Couldn't open fmod stream, error "
+ << FMOD_ErrorString(FSOUND_GetError())
+ << llendl;
+ mReady = false;
+ return;
+ }
+
+ mReady = true;
+}
+
+int LLAudioStreamManagerFMOD::startStream()
+{
+ // We need a live and opened stream before we try and play it.
+ if (!mInternetStream || getOpenState())
+ {
+ llwarns << "No internet stream to start playing!" << llendl;
+ return -1;
+ }
+
+ // Make sure the stream is set to 2D mode.
+ FSOUND_Stream_SetMode(mInternetStream, FSOUND_2D);
+
+ return FSOUND_Stream_PlayEx(FSOUND_FREE, mInternetStream, NULL, true);
+}
+
+bool LLAudioStreamManagerFMOD::stopStream()
+{
+ if (mInternetStream)
+ {
+ int read_percent = 0;
+ int status = 0;
+ int bitrate = 0;
+ unsigned int flags = 0x0;
+ FSOUND_Stream_Net_GetStatus(mInternetStream, &status, &read_percent, &bitrate, &flags);
+
+ bool close = true;
+ switch (status)
+ {
+ case FSOUND_STREAM_NET_CONNECTING:
+ close = false;
+ break;
+ case FSOUND_STREAM_NET_NOTCONNECTED:
+ case FSOUND_STREAM_NET_BUFFERING:
+ case FSOUND_STREAM_NET_READY:
+ case FSOUND_STREAM_NET_ERROR:
+ default:
+ close = true;
+ }
+
+ if (close)
+ {
+ FSOUND_Stream_Close(mInternetStream);
+ mInternetStream = NULL;
+ return true;
+ }
+ else
+ {
+ return false;
+ }
+ }
+ else
+ {
+ return true;
+ }
+}
+
+int LLAudioStreamManagerFMOD::getOpenState()
+{
+ int open_state = FSOUND_Stream_GetOpenState(mInternetStream);
+ return open_state;
+}
diff --git a/indra/llaudio/llstreamingaudio_fmod.h b/indra/llaudio/llstreamingaudio_fmod.h
new file mode 100644
index 0000000000..968ab53a0b
--- /dev/null
+++ b/indra/llaudio/llstreamingaudio_fmod.h
@@ -0,0 +1,68 @@
+/**
+ * @file streamingaudio_fmod.h
+ * @author Tofu Linden
+ * @brief Definition of LLStreamingAudio_FMOD implementation
+ *
+ * $LicenseInfo:firstyear=2009&license=viewergpl$
+ *
+ * Copyright (c) 2009, Linden Research, Inc.
+ *
+ * Second Life Viewer Source Code
+ * The source code in this file ("Source Code") is provided by Linden Lab
+ * to you under the terms of the GNU General Public License, version 2.0
+ * ("GPL"), unless you have obtained a separate licensing agreement
+ * ("Other License"), formally executed by you and Linden Lab. Terms of
+ * the GPL can be found in doc/GPL-license.txt in this distribution, or
+ * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
+ *
+ * There are special exceptions to the terms and conditions of the GPL as
+ * it is applied to this Source Code. View the full text of the exception
+ * in the file doc/FLOSS-exception.txt in this software distribution, or
+ * online at
+ * http://secondlifegrid.net/programs/open_source/licensing/flossexception
+ *
+ * By copying, modifying or distributing this software, you acknowledge
+ * that you have read and understood your obligations described above,
+ * and agree to abide by those obligations.
+ *
+ * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+ * COMPLETENESS OR PERFORMANCE.
+ * $/LicenseInfo$
+ */
+
+#ifndef LL_STREAMINGAUDIO_FMOD_H
+#define LL_STREAMINGAUDIO_FMOD_H
+
+#include "stdtypes.h" // from llcommon
+
+#include "llstreamingaudio.h"
+
+class LLAudioStreamManagerFMOD;
+
+class LLStreamingAudio_FMOD : public LLStreamingAudioInterface
+{
+ public:
+ LLStreamingAudio_FMOD();
+ /*virtual*/ ~LLStreamingAudio_FMOD();
+
+ /*virtual*/ void start(const std::string& url);
+ /*virtual*/ void stop();
+ /*virtual*/ void pause(int pause);
+ /*virtual*/ void update();
+ /*virtual*/ int isPlaying();
+ /*virtual*/ void setGain(F32 vol);
+ /*virtual*/ F32 getGain();
+ /*virtual*/ std::string getURL();
+
+private:
+ LLAudioStreamManagerFMOD *mCurrentInternetStreamp;
+ int mFMODInternetStreamChannel;
+ std::list<LLAudioStreamManagerFMOD *> mDeadStreams;
+
+ std::string mURL;
+ F32 mGain;
+};
+
+
+#endif // LL_STREAMINGAUDIO_FMOD_H
diff --git a/indra/llaudio/llvorbisencode.cpp b/indra/llaudio/llvorbisencode.cpp
new file mode 100644
index 0000000000..8ee082a245
--- /dev/null
+++ b/indra/llaudio/llvorbisencode.cpp
@@ -0,0 +1,505 @@
+/**
+ * @file vorbisencode.cpp
+ * @brief Vorbis encoding routine routine for Indra.
+ *
+ * $LicenseInfo:firstyear=2000&license=viewergpl$
+ *
+ * Copyright (c) 2000-2009, Linden Research, Inc.
+ *
+ * Second Life Viewer Source Code
+ * The source code in this file ("Source Code") is provided by Linden Lab
+ * to you under the terms of the GNU General Public License, version 2.0
+ * ("GPL"), unless you have obtained a separate licensing agreement
+ * ("Other License"), formally executed by you and Linden Lab. Terms of
+ * the GPL can be found in doc/GPL-license.txt in this distribution, or
+ * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
+ *
+ * There are special exceptions to the terms and conditions of the GPL as
+ * it is applied to this Source Code. View the full text of the exception
+ * in the file doc/FLOSS-exception.txt in this software distribution, or
+ * online at
+ * http://secondlifegrid.net/programs/open_source/licensing/flossexception
+ *
+ * By copying, modifying or distributing this software, you acknowledge
+ * that you have read and understood your obligations described above,
+ * and agree to abide by those obligations.
+ *
+ * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+ * COMPLETENESS OR PERFORMANCE.
+ * $/LicenseInfo$
+ */
+
+#include "linden_common.h"
+
+#include "vorbis/vorbisenc.h"
+
+#include "llvorbisencode.h"
+#include "llerror.h"
+#include "llrand.h"
+#include "llmath.h"
+#include "llapr.h"
+
+//#if LL_DARWIN
+// MBW -- XXX -- Getting rid of SecondLifeVorbis for now -- no fmod means no name collisions.
+#if 0
+#include "VorbisFramework.h"
+
+#define vorbis_analysis mac_vorbis_analysis
+#define vorbis_analysis_headerout mac_vorbis_analysis_headerout
+#define vorbis_analysis_init mac_vorbis_analysis_init
+#define vorbis_encode_ctl mac_vorbis_encode_ctl
+#define vorbis_encode_setup_init mac_vorbis_encode_setup_init
+#define vorbis_encode_setup_managed mac_vorbis_encode_setup_managed
+
+#define vorbis_info_init mac_vorbis_info_init
+#define vorbis_info_clear mac_vorbis_info_clear
+#define vorbis_comment_init mac_vorbis_comment_init
+#define vorbis_comment_clear mac_vorbis_comment_clear
+#define vorbis_block_init mac_vorbis_block_init
+#define vorbis_block_clear mac_vorbis_block_clear
+#define vorbis_dsp_clear mac_vorbis_dsp_clear
+#define vorbis_analysis_buffer mac_vorbis_analysis_buffer
+#define vorbis_analysis_wrote mac_vorbis_analysis_wrote
+#define vorbis_analysis_blockout mac_vorbis_analysis_blockout
+
+#define ogg_stream_packetin mac_ogg_stream_packetin
+#define ogg_stream_init mac_ogg_stream_init
+#define ogg_stream_flush mac_ogg_stream_flush
+#define ogg_stream_pageout mac_ogg_stream_pageout
+#define ogg_page_eos mac_ogg_page_eos
+#define ogg_stream_clear mac_ogg_stream_clear
+
+#endif
+
+S32 check_for_invalid_wav_formats(const std::string& in_fname, std::string& error_msg)
+{
+ U16 num_channels = 0;
+ U32 sample_rate = 0;
+ U32 bits_per_sample = 0;
+ U32 physical_file_size = 0;
+ U32 chunk_length = 0;
+ U32 raw_data_length = 0;
+ U32 bytes_per_sec = 0;
+ BOOL uncompressed_pcm = FALSE;
+
+ unsigned char wav_header[44]; /*Flawfinder: ignore*/
+
+ error_msg.clear();
+
+ //********************************
+ LLAPRFile infile ;
+ infile.open(in_fname,LL_APR_RB);
+ //********************************
+ if (!infile.getFileHandle())
+ {
+ error_msg = "CannotUploadSoundFile";
+ return(LLVORBISENC_SOURCE_OPEN_ERR);
+ }
+
+ infile.read(wav_header, 44);
+ physical_file_size = infile.seek(APR_END,0);
+
+ if (strncmp((char *)&(wav_header[0]),"RIFF",4))
+ {
+ error_msg = "SoundFileNotRIFF";
+ return(LLVORBISENC_WAV_FORMAT_ERR);
+ }
+
+ if (strncmp((char *)&(wav_header[8]),"WAVE",4))
+ {
+ error_msg = "SoundFileNotRIFF";
+ return(LLVORBISENC_WAV_FORMAT_ERR);
+ }
+
+ // parse the chunks
+
+ U32 file_pos = 12; // start at the first chunk (usually fmt but not always)
+
+ while ((file_pos + 8)< physical_file_size)
+ {
+ infile.seek(APR_SET,file_pos);
+ infile.read(wav_header, 44);
+
+ chunk_length = ((U32) wav_header[7] << 24)
+ + ((U32) wav_header[6] << 16)
+ + ((U32) wav_header[5] << 8)
+ + wav_header[4];
+
+// llinfos << "chunk found: '" << wav_header[0] << wav_header[1] << wav_header[2] << wav_header[3] << "'" << llendl;
+
+ if (!(strncmp((char *)&(wav_header[0]),"fmt ",4)))
+ {
+ if ((wav_header[8] == 0x01) && (wav_header[9] == 0x00))
+ {
+ uncompressed_pcm = TRUE;
+ }
+ num_channels = ((U16) wav_header[11] << 8) + wav_header[10];
+ sample_rate = ((U32) wav_header[15] << 24)
+ + ((U32) wav_header[14] << 16)
+ + ((U32) wav_header[13] << 8)
+ + wav_header[12];
+ bits_per_sample = ((U16) wav_header[23] << 8) + wav_header[22];
+ bytes_per_sec = ((U32) wav_header[19] << 24)
+ + ((U32) wav_header[18] << 16)
+ + ((U32) wav_header[17] << 8)
+ + wav_header[16];
+ }
+ else if (!(strncmp((char *)&(wav_header[0]),"data",4)))
+ {
+ raw_data_length = chunk_length;
+ }
+ file_pos += (chunk_length + 8);
+ chunk_length = 0;
+ }
+ //****************
+ infile.close();
+ //****************
+
+ if (!uncompressed_pcm)
+ {
+ error_msg = "SoundFileNotPCM";
+ return(LLVORBISENC_PCM_FORMAT_ERR);
+ }
+
+ if ((num_channels < 1) || (num_channels > 2))
+ {
+ error_msg = "SoundFileInvalidChannelCount";
+ return(LLVORBISENC_MULTICHANNEL_ERR);
+ }
+
+ if (sample_rate != 44100)
+ {
+ error_msg = "SoundFileInvalidSampleRate";
+ return(LLVORBISENC_UNSUPPORTED_SAMPLE_RATE);
+ }
+
+ if ((bits_per_sample != 16) && (bits_per_sample != 8))
+ {
+ error_msg = "SoundFileInvalidWordSize";
+ return(LLVORBISENC_UNSUPPORTED_WORD_SIZE);
+ }
+
+ if (!raw_data_length)
+ {
+ error_msg = "SoundFileInvalidHeader";
+ return(LLVORBISENC_CLIP_TOO_LONG);
+ }
+
+ F32 clip_length = (F32)raw_data_length/(F32)bytes_per_sec;
+
+ if (clip_length > 10.0f)
+ {
+ error_msg = "SoundFileInvalidTooLong";
+ return(LLVORBISENC_CLIP_TOO_LONG);
+ }
+
+ return(LLVORBISENC_NOERR);
+}
+
+S32 encode_vorbis_file(const std::string& in_fname, const std::string& out_fname)
+{
+#define READ_BUFFER 1024
+ unsigned char readbuffer[READ_BUFFER*4+44]; /* out of the data segment, not the stack */ /*Flawfinder: ignore*/
+
+ ogg_stream_state os; /* take physical pages, weld into a logical stream of packets */
+ ogg_page og; /* one Ogg bitstream page. Vorbis packets are inside */
+ ogg_packet op; /* one raw packet of data for decode */
+
+ vorbis_info vi; /* struct that stores all the static vorbis bitstream settings */
+ vorbis_comment vc; /* struct that stores all the user comments */
+
+ vorbis_dsp_state vd; /* central working state for the packet->PCM decoder */
+ vorbis_block vb; /* local working space for packet->PCM decode */
+
+ int eos=0;
+ int result;
+
+ U16 num_channels = 0;
+ U32 sample_rate = 0;
+ U32 bits_per_sample = 0;
+
+ S32 format_error = 0;
+ std::string error_msg;
+ if ((format_error = check_for_invalid_wav_formats(in_fname, error_msg)))
+ {
+ llwarns << error_msg << ": " << in_fname << llendl;
+ return(format_error);
+ }
+
+#if 1
+ unsigned char wav_header[44]; /*Flawfinder: ignore*/
+
+ S32 data_left = 0;
+
+ LLAPRFile infile ;
+ infile.open(in_fname,LL_APR_RB);
+ if (!infile.getFileHandle())
+ {
+ llwarns << "Couldn't open temporary ogg file for writing: " << in_fname
+ << llendl;
+ return(LLVORBISENC_SOURCE_OPEN_ERR);
+ }
+
+ LLAPRFile outfile ;
+ outfile.open(out_fname,LL_APR_WPB);
+ if (!outfile.getFileHandle())
+ {
+ llwarns << "Couldn't open upload sound file for reading: " << in_fname
+ << llendl;
+ return(LLVORBISENC_DEST_OPEN_ERR);
+ }
+
+ // parse the chunks
+ U32 chunk_length = 0;
+ U32 file_pos = 12; // start at the first chunk (usually fmt but not always)
+
+ while (infile.eof() != APR_EOF)
+ {
+ infile.seek(APR_SET,file_pos);
+ infile.read(wav_header, 44);
+
+ chunk_length = ((U32) wav_header[7] << 24)
+ + ((U32) wav_header[6] << 16)
+ + ((U32) wav_header[5] << 8)
+ + wav_header[4];
+
+// llinfos << "chunk found: '" << wav_header[0] << wav_header[1] << wav_header[2] << wav_header[3] << "'" << llendl;
+
+ if (!(strncmp((char *)&(wav_header[0]),"fmt ",4)))
+ {
+ num_channels = ((U16) wav_header[11] << 8) + wav_header[10];
+ sample_rate = ((U32) wav_header[15] << 24)
+ + ((U32) wav_header[14] << 16)
+ + ((U32) wav_header[13] << 8)
+ + wav_header[12];
+ bits_per_sample = ((U16) wav_header[23] << 8) + wav_header[22];
+ }
+ else if (!(strncmp((char *)&(wav_header[0]),"data",4)))
+ {
+ infile.seek(APR_SET,file_pos+8);
+ // leave the file pointer at the beginning of the data chunk data
+ data_left = chunk_length;
+ break;
+ }
+ file_pos += (chunk_length + 8);
+ chunk_length = 0;
+ }
+
+
+ /********** Encode setup ************/
+
+ /* choose an encoding mode */
+ /* (mode 0: 44kHz stereo uncoupled, roughly 128kbps VBR) */
+ vorbis_info_init(&vi);
+
+ // always encode to mono
+
+ // SL-52913 & SL-53779 determined this quality level to be our 'good
+ // enough' general-purpose quality level with a nice low bitrate.
+ // Equivalent to oggenc -q0.5
+ F32 quality = 0.05f;
+// quality = (bitrate==128000 ? 0.4f : 0.1);
+
+// if (vorbis_encode_init(&vi, /* num_channels */ 1 ,sample_rate, -1, bitrate, -1))
+ if (vorbis_encode_init_vbr(&vi, /* num_channels */ 1 ,sample_rate, quality))
+// if (vorbis_encode_setup_managed(&vi,1,sample_rate,-1,bitrate,-1) ||
+// vorbis_encode_ctl(&vi,OV_ECTL_RATEMANAGE_AVG,NULL) ||
+// vorbis_encode_setup_init(&vi))
+ {
+ llwarns << "unable to initialize vorbis codec at quality " << quality << llendl;
+ // llwarns << "unable to initialize vorbis codec at bitrate " << bitrate << llendl;
+ return(LLVORBISENC_DEST_OPEN_ERR);
+ }
+
+ /* add a comment */
+ vorbis_comment_init(&vc);
+// vorbis_comment_add(&vc,"Linden");
+
+ /* set up the analysis state and auxiliary encoding storage */
+ vorbis_analysis_init(&vd,&vi);
+ vorbis_block_init(&vd,&vb);
+
+ /* set up our packet->stream encoder */
+ /* pick a random serial number; that way we can more likely build
+ chained streams just by concatenation */
+ ogg_stream_init(&os, ll_rand());
+
+ /* Vorbis streams begin with three headers; the initial header (with
+ most of the codec setup parameters) which is mandated by the Ogg
+ bitstream spec. The second header holds any comment fields. The
+ third header holds the bitstream codebook. We merely need to
+ make the headers, then pass them to libvorbis one at a time;
+ libvorbis handles the additional Ogg bitstream constraints */
+
+ {
+ ogg_packet header;
+ ogg_packet header_comm;
+ ogg_packet header_code;
+
+ vorbis_analysis_headerout(&vd,&vc,&header,&header_comm,&header_code);
+ ogg_stream_packetin(&os,&header); /* automatically placed in its own
+ page */
+ ogg_stream_packetin(&os,&header_comm);
+ ogg_stream_packetin(&os,&header_code);
+
+ /* We don't have to write out here, but doing so makes streaming
+ * much easier, so we do, flushing ALL pages. This ensures the actual
+ * audio data will start on a new page
+ */
+ while(!eos){
+ int result=ogg_stream_flush(&os,&og);
+ if(result==0)break;
+ outfile.write(og.header, og.header_len);
+ outfile.write(og.body, og.body_len);
+ }
+
+ }
+
+
+ while(!eos)
+ {
+ long bytes_per_sample = bits_per_sample/8;
+
+ long bytes=(long)infile.read(readbuffer,llclamp((S32)(READ_BUFFER*num_channels*bytes_per_sample),0,data_left)); /* stereo hardwired here */
+
+ if (bytes==0)
+ {
+ /* end of file. this can be done implicitly in the mainline,
+ but it's easier to see here in non-clever fashion.
+ Tell the library we're at end of stream so that it can handle
+ the last frame and mark end of stream in the output properly */
+
+ vorbis_analysis_wrote(&vd,0);
+// eos = 1;
+
+ }
+ else
+ {
+ long i;
+ long samples;
+ int temp;
+
+ data_left -= bytes;
+ /* data to encode */
+
+ /* expose the buffer to submit data */
+ float **buffer=vorbis_analysis_buffer(&vd,READ_BUFFER);
+
+ i = 0;
+ samples = bytes / (num_channels * bytes_per_sample);
+
+ if (num_channels == 2)
+ {
+ if (bytes_per_sample == 2)
+ {
+ /* uninterleave samples */
+ for(i=0; i<samples ;i++)
+ {
+ temp = ((signed char *)readbuffer)[i*4+1]; /*Flawfinder: ignore*/
+ temp += ((signed char *)readbuffer)[i*4+3]; /*Flawfinder: ignore*/
+ temp <<= 8;
+ temp += readbuffer[i*4];
+ temp += readbuffer[i*4+2];
+
+ buffer[0][i] = ((float)temp) / 65536.f;
+ }
+ }
+ else // presume it's 1 byte per which is unsigned (F#@%ing wav "standard")
+ {
+ /* uninterleave samples */
+ for(i=0; i<samples ;i++)
+ {
+ temp = readbuffer[i*2+0];
+ temp += readbuffer[i*2+1];
+ temp -= 256;
+ buffer[0][i] = ((float)temp) / 256.f;
+ }
+ }
+ }
+ else if (num_channels == 1)
+ {
+ if (bytes_per_sample == 2)
+ {
+ for(i=0; i < samples ;i++)
+ {
+ temp = ((signed char*)readbuffer)[i*2+1];
+ temp <<= 8;
+ temp += readbuffer[i*2];
+ buffer[0][i] = ((float)temp) / 32768.f;
+ }
+ }
+ else // presume it's 1 byte per which is unsigned (F#@%ing wav "standard")
+ {
+ for(i=0; i < samples ;i++)
+ {
+ temp = readbuffer[i];
+ temp -= 128;
+ buffer[0][i] = ((float)temp) / 128.f;
+ }
+ }
+ }
+
+ /* tell the library how much we actually submitted */
+ vorbis_analysis_wrote(&vd,i);
+ }
+
+ /* vorbis does some data preanalysis, then divvies up blocks for
+ more involved (potentially parallel) processing. Get a single
+ block for encoding now */
+ while(vorbis_analysis_blockout(&vd,&vb)==1)
+ {
+
+ /* analysis */
+ /* Do the main analysis, creating a packet */
+ vorbis_analysis(&vb, NULL);
+ vorbis_bitrate_addblock(&vb);
+
+ while(vorbis_bitrate_flushpacket(&vd, &op))
+ {
+
+ /* weld the packet into the bitstream */
+ ogg_stream_packetin(&os,&op);
+
+ /* write out pages (if any) */
+ while(!eos)
+ {
+ result = ogg_stream_pageout(&os,&og);
+
+ if(result==0)
+ break;
+
+ outfile.write(og.header, og.header_len);
+ outfile.write(og.body, og.body_len);
+
+ /* this could be set above, but for illustrative purposes, I do
+ it here (to show that vorbis does know where the stream ends) */
+
+ if(ogg_page_eos(&og))
+ eos=1;
+
+ }
+ }
+ }
+ }
+
+
+
+ /* clean up and exit. vorbis_info_clear() must be called last */
+
+ ogg_stream_clear(&os);
+ vorbis_block_clear(&vb);
+ vorbis_dsp_clear(&vd);
+ vorbis_comment_clear(&vc);
+ vorbis_info_clear(&vi);
+
+ /* ogg_page and ogg_packet structs always point to storage in
+ libvorbis. They're never freed or manipulated directly */
+
+// fprintf(stderr,"Vorbis encoding: Done.\n");
+ llinfos << "Vorbis encoding: Done." << llendl;
+
+#endif
+ return(LLVORBISENC_NOERR);
+
+}
diff --git a/indra/llaudio/llvorbisencode.h b/indra/llaudio/llvorbisencode.h
new file mode 100644
index 0000000000..ff5ce3a053
--- /dev/null
+++ b/indra/llaudio/llvorbisencode.h
@@ -0,0 +1,53 @@
+/**
+ * @file vorbisencode.h
+ * @brief Vorbis encoding routine routine for Indra.
+ *
+ * $LicenseInfo:firstyear=2000&license=viewergpl$
+ *
+ * Copyright (c) 2000-2009, Linden Research, Inc.
+ *
+ * Second Life Viewer Source Code
+ * The source code in this file ("Source Code") is provided by Linden Lab
+ * to you under the terms of the GNU General Public License, version 2.0
+ * ("GPL"), unless you have obtained a separate licensing agreement
+ * ("Other License"), formally executed by you and Linden Lab. Terms of
+ * the GPL can be found in doc/GPL-license.txt in this distribution, or
+ * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
+ *
+ * There are special exceptions to the terms and conditions of the GPL as
+ * it is applied to this Source Code. View the full text of the exception
+ * in the file doc/FLOSS-exception.txt in this software distribution, or
+ * online at
+ * http://secondlifegrid.net/programs/open_source/licensing/flossexception
+ *
+ * By copying, modifying or distributing this software, you acknowledge
+ * that you have read and understood your obligations described above,
+ * and agree to abide by those obligations.
+ *
+ * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+ * COMPLETENESS OR PERFORMANCE.
+ * $/LicenseInfo$
+ */
+
+#ifndef LL_VORBISENCODE_H
+#define LL_VORBISENCODE_H
+
+const S32 LLVORBISENC_NOERR = 0; // no error
+const S32 LLVORBISENC_SOURCE_OPEN_ERR = 1; // error opening source
+const S32 LLVORBISENC_DEST_OPEN_ERR = 2; // error opening destination
+const S32 LLVORBISENC_WAV_FORMAT_ERR = 3; // not a WAV
+const S32 LLVORBISENC_PCM_FORMAT_ERR = 4; // not a PCM
+const S32 LLVORBISENC_MONO_ERR = 5; // can't do mono
+const S32 LLVORBISENC_STEREO_ERR = 6; // can't do stereo
+const S32 LLVORBISENC_MULTICHANNEL_ERR = 7; // can't do stereo
+const S32 LLVORBISENC_UNSUPPORTED_SAMPLE_RATE = 8; // unsupported sample rate
+const S32 LLVORBISENC_UNSUPPORTED_WORD_SIZE = 9; // unsupported word size
+const S32 LLVORBISENC_CLIP_TOO_LONG = 10; // source file is too long
+
+
+S32 check_for_invalid_wav_formats(const std::string& in_fname, std::string& error_msg);
+S32 encode_vorbis_file(const std::string& in_fname, const std::string& out_fname);
+
+#endif
+
diff --git a/indra/llaudio/llwindgen.h b/indra/llaudio/llwindgen.h
new file mode 100644
index 0000000000..847bfa6e9d
--- /dev/null
+++ b/indra/llaudio/llwindgen.h
@@ -0,0 +1,136 @@
+/**
+ * @file windgen.h
+ * @brief Templated wind noise generation
+ *
+ * $LicenseInfo:firstyear=2002&license=viewergpl$
+ *
+ * Copyright (c) 2002-2009, Linden Research, Inc.
+ *
+ * Second Life Viewer Source Code
+ * The source code in this file ("Source Code") is provided by Linden Lab
+ * to you under the terms of the GNU General Public License, version 2.0
+ * ("GPL"), unless you have obtained a separate licensing agreement
+ * ("Other License"), formally executed by you and Linden Lab. Terms of
+ * the GPL can be found in doc/GPL-license.txt in this distribution, or
+ * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
+ *
+ * There are special exceptions to the terms and conditions of the GPL as
+ * it is applied to this Source Code. View the full text of the exception
+ * in the file doc/FLOSS-exception.txt in this software distribution, or
+ * online at
+ * http://secondlifegrid.net/programs/open_source/licensing/flossexception
+ *
+ * By copying, modifying or distributing this software, you acknowledge
+ * that you have read and understood your obligations described above,
+ * and agree to abide by those obligations.
+ *
+ * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+ * COMPLETENESS OR PERFORMANCE.
+ * $/LicenseInfo$
+ */
+#ifndef WINDGEN_H
+#define WINDGEN_H
+
+#include "llcommon.h"
+#include "llrand.h"
+
+template <class MIXBUFFERFORMAT_T>
+class LLWindGen
+{
+public:
+ LLWindGen() :
+ mTargetGain(0.f),
+ mTargetFreq(100.f),
+ mTargetPanGainR(0.5f),
+ mbuf0(0.0),
+ mbuf1(0.0),
+ mbuf2(0.0),
+ mbuf3(0.0),
+ mbuf4(0.0),
+ mbuf5(0.0),
+ mY0(0.0),
+ mY1(0.0),
+ mCurrentGain(0.f),
+ mCurrentFreq(100.f),
+ mCurrentPanGainR(0.5f) {};
+
+ static const U32 getInputSamplingRate() {return mInputSamplingRate;}
+
+ // newbuffer = the buffer passed from the previous DSP unit.
+ // numsamples = length in samples-per-channel at this mix time.
+ // stride = number of bytes between start of each sample.
+ // NOTE: generates L/R interleaved stereo
+ MIXBUFFERFORMAT_T* windGenerate(MIXBUFFERFORMAT_T *newbuffer, int numsamples, int stride)
+ {
+ U8 *cursamplep = (U8*)newbuffer;
+
+ double bandwidth = 50.0F;
+ double a0,b1,b2;
+
+ // calculate resonant filter coeffs
+ b2 = exp(-(F_TWO_PI) * (bandwidth / mInputSamplingRate));
+
+ while (numsamples--)
+ {
+ mCurrentFreq = (float)((0.999 * mCurrentFreq) + (0.001 * mTargetFreq));
+ mCurrentGain = (float)((0.999 * mCurrentGain) + (0.001 * mTargetGain));
+ mCurrentPanGainR = (float)((0.999 * mCurrentPanGainR) + (0.001 * mTargetPanGainR));
+ b1 = (-4.0 * b2) / (1.0 + b2) * cos(F_TWO_PI * (mCurrentFreq / mInputSamplingRate));
+ a0 = (1.0 - b2) * sqrt(1.0 - (b1 * b1) / (4.0 * b2));
+ double nextSample;
+
+ // start with white noise
+ nextSample = ll_frand(2.0f) - 1.0f;
+
+ // apply pinking filter
+ mbuf0 = 0.997f * mbuf0 + 0.0126502f * nextSample;
+ mbuf1 = 0.985f * mbuf1 + 0.0139083f * nextSample;
+ mbuf2 = 0.950f * mbuf2 + 0.0205439f * nextSample;
+ mbuf3 = 0.850f * mbuf3 + 0.0387225f * nextSample;
+ mbuf4 = 0.620f * mbuf4 + 0.0465932f * nextSample;
+ mbuf5 = 0.250f * mbuf5 + 0.1093477f * nextSample;
+
+ nextSample = mbuf0 + mbuf1 + mbuf2 + mbuf3 + mbuf4 + mbuf5;
+
+ // do a resonant filter on the noise
+ nextSample = (double)( a0 * nextSample - b1 * mY0 - b2 * mY1 );
+ mY1 = mY0;
+ mY0 = nextSample;
+
+ nextSample *= mCurrentGain;
+
+ MIXBUFFERFORMAT_T sample;
+
+ sample = llfloor(((F32)nextSample*32768.f*(1.0f - mCurrentPanGainR))+0.5f);
+ *(MIXBUFFERFORMAT_T*)cursamplep = llclamp(sample, (MIXBUFFERFORMAT_T)-32768, (MIXBUFFERFORMAT_T)32767);
+ cursamplep += stride;
+
+ sample = llfloor(((F32)nextSample*32768.f*mCurrentPanGainR)+0.5f);
+ *(MIXBUFFERFORMAT_T*)cursamplep = llclamp(sample, (MIXBUFFERFORMAT_T)-32768, (MIXBUFFERFORMAT_T)32767);
+ cursamplep += stride;
+ }
+
+ return newbuffer;
+ }
+
+ F32 mTargetGain;
+ F32 mTargetFreq;
+ F32 mTargetPanGainR;
+
+private:
+ static const U32 mInputSamplingRate = 44100;
+ F64 mbuf0;
+ F64 mbuf1;
+ F64 mbuf2;
+ F64 mbuf3;
+ F64 mbuf4;
+ F64 mbuf5;
+ F64 mY0;
+ F64 mY1;
+ F32 mCurrentGain;
+ F32 mCurrentFreq;
+ F32 mCurrentPanGainR;
+};
+
+#endif
diff --git a/indra/llcharacter/llbvhloader.cpp b/indra/llcharacter/llbvhloader.cpp
index e1f8ce53fb..24391eb8f3 100644
--- a/indra/llcharacter/llbvhloader.cpp
+++ b/indra/llcharacter/llbvhloader.cpp
@@ -56,7 +56,7 @@ const F32 ROTATION_MOTION_THRESHOLD = 0.001f;
char gInFile[1024]; /* Flawfinder: ignore */
char gOutFile[1024]; /* Flawfinder: ignore */
-
+/*
//------------------------------------------------------------------------
// Status Codes
//------------------------------------------------------------------------
@@ -91,7 +91,7 @@ const char *LLBVHLoader::ST_NO_XLT_EASEIN = "Can't get easeIn values.";
const char *LLBVHLoader::ST_NO_XLT_EASEOUT = "Can't get easeOut values.";
const char *LLBVHLoader::ST_NO_XLT_HAND = "Can't get hand morph value.";
const char *LLBVHLoader::ST_NO_XLT_EMOTE = "Can't read emote name.";
-
+*/
//------------------------------------------------------------------------
// find_next_whitespace()
//------------------------------------------------------------------------
@@ -124,7 +124,9 @@ LLQuaternion::Order bvhStringToOrder( char *str )
//-----------------------------------------------------------------------------
// LLBVHLoader()
//-----------------------------------------------------------------------------
-LLBVHLoader::LLBVHLoader(const char* buffer)
+
+/*
+ LLBVHLoader::LLBVHLoader(const char* buffer)
{
reset();
@@ -144,7 +146,7 @@ LLBVHLoader::LLBVHLoader(const char* buffer)
}
}
- char error_text[128]; /* Flawfinder: ignore */
+ char error_text[128]; // Flawfinder: ignore
S32 error_line;
mStatus = loadBVHFile(buffer, error_text, error_line);
if (mStatus != LLBVHLoader::ST_OK)
@@ -158,6 +160,49 @@ LLBVHLoader::LLBVHLoader(const char* buffer)
mInitialized = TRUE;
}
+*/
+LLBVHLoader::LLBVHLoader(const char* buffer, ELoadStatus &loadStatus, S32 &errorLine)
+{
+ reset();
+ errorLine = 0;
+ mStatus = loadTranslationTable("anim.ini");
+ loadStatus = mStatus;
+ llinfos<<"Load Status 00 : "<< loadStatus << llendl;
+ if (mStatus == E_ST_NO_XLT_FILE)
+ {
+ //llwarns << "NOTE: No translation table found." << llendl;
+ loadStatus = mStatus;
+ return;
+ }
+ else
+ {
+ if (mStatus != E_ST_OK)
+ {
+ //llwarns << "ERROR: [line: " << getLineNumber() << "] " << mStatus << llendl;
+ errorLine = getLineNumber();
+ loadStatus = mStatus;
+ return;
+ }
+ }
+
+ char error_text[128]; /* Flawfinder: ignore */
+ S32 error_line;
+ mStatus = loadBVHFile(buffer, error_text, error_line);
+
+ if (mStatus != E_ST_OK)
+ {
+ //llwarns << "ERROR: [line: " << getLineNumber() << "] " << mStatus << llendl;
+ loadStatus = mStatus;
+ errorLine = getLineNumber();
+ return;
+ }
+
+ applyTranslations();
+ optimize();
+
+ mInitialized = TRUE;
+}
+
LLBVHLoader::~LLBVHLoader()
{
@@ -167,7 +212,7 @@ LLBVHLoader::~LLBVHLoader()
//------------------------------------------------------------------------
// LLBVHLoader::loadTranslationTable()
//------------------------------------------------------------------------
-LLBVHLoader::Status LLBVHLoader::loadTranslationTable(const char *fileName)
+ELoadStatus LLBVHLoader::loadTranslationTable(const char *fileName)
{
mLineNumber = 0;
mTranslations.clear();
@@ -182,7 +227,7 @@ LLBVHLoader::Status LLBVHLoader::loadTranslationTable(const char *fileName)
infile.open(path, LL_APR_R);
apr_file_t *fp = infile.getFileHandle();
if (!fp)
- return ST_NO_XLT_FILE;
+ return E_ST_NO_XLT_FILE;
llinfos << "NOTE: Loading translation table: " << fileName << llendl;
@@ -194,9 +239,9 @@ LLBVHLoader::Status LLBVHLoader::loadTranslationTable(const char *fileName)
// load header
//--------------------------------------------------------------------
if ( ! getLine(fp) )
- return ST_EOF;
+ return E_ST_EOF;
if ( strncmp(mLine, "Translations 1.0", 16) )
- return ST_NO_XLT_HEADER;
+ return E_ST_NO_XLT_HEADER;
//--------------------------------------------------------------------
// load data one line at a time
@@ -222,7 +267,7 @@ LLBVHLoader::Status LLBVHLoader::loadTranslationTable(const char *fileName)
{
char name[128]; /* Flawfinder: ignore */
if ( sscanf(mLine, " [%127[^]]", name) != 1 )
- return ST_NO_XLT_NAME;
+ return E_ST_NO_XLT_NAME;
if (strcmp(name, "GLOBALS")==0)
{
@@ -245,7 +290,7 @@ LLBVHLoader::Status LLBVHLoader::loadTranslationTable(const char *fileName)
{
char emote_str[1024]; /* Flawfinder: ignore */
if ( sscanf(mLine, " %*s = %1023s", emote_str) != 1 ) /* Flawfinder: ignore */
- return ST_NO_XLT_EMOTE;
+ return E_ST_NO_XLT_EMOTE;
mEmoteName.assign( emote_str );
// llinfos << "NOTE: Emote: " << mEmoteName.c_str() << llendl;
@@ -260,7 +305,7 @@ LLBVHLoader::Status LLBVHLoader::loadTranslationTable(const char *fileName)
{
S32 priority;
if ( sscanf(mLine, " %*s = %d", &priority) != 1 )
- return ST_NO_XLT_PRIORITY;
+ return E_ST_NO_XLT_PRIORITY;
mPriority = priority;
// llinfos << "NOTE: Priority: " << mPriority << llendl;
@@ -288,7 +333,7 @@ LLBVHLoader::Status LLBVHLoader::loadTranslationTable(const char *fileName)
}
else
{
- return ST_NO_XLT_LOOP;
+ return E_ST_NO_XLT_LOOP;
}
mLoopInPoint = loop_in * mDuration;
@@ -305,7 +350,7 @@ LLBVHLoader::Status LLBVHLoader::loadTranslationTable(const char *fileName)
F32 duration;
char type[128]; /* Flawfinder: ignore */
if ( sscanf(mLine, " %*s = %f %127s", &duration, type) != 2 ) /* Flawfinder: ignore */
- return ST_NO_XLT_EASEIN;
+ return E_ST_NO_XLT_EASEIN;
mEaseIn = duration;
continue;
@@ -319,7 +364,7 @@ LLBVHLoader::Status LLBVHLoader::loadTranslationTable(const char *fileName)
F32 duration;
char type[128]; /* Flawfinder: ignore */
if ( sscanf(mLine, " %*s = %f %127s", &duration, type) != 2 ) /* Flawfinder: ignore */
- return ST_NO_XLT_EASEOUT;
+ return E_ST_NO_XLT_EASEOUT;
mEaseOut = duration;
continue;
@@ -332,7 +377,7 @@ LLBVHLoader::Status LLBVHLoader::loadTranslationTable(const char *fileName)
{
S32 handMorph;
if (sscanf(mLine, " %*s = %d", &handMorph) != 1)
- return ST_NO_XLT_HAND;
+ return E_ST_NO_XLT_HAND;
mHand = handMorph;
continue;
@@ -380,7 +425,7 @@ LLBVHLoader::Status LLBVHLoader::loadTranslationTable(const char *fileName)
&constraint.mTargetOffset.mV[VY],
&constraint.mTargetOffset.mV[VZ]) != 13)
{
- return ST_NO_CONSTRAINT;
+ return E_ST_NO_CONSTRAINT;
}
}
else
@@ -440,7 +485,7 @@ LLBVHLoader::Status LLBVHLoader::loadTranslationTable(const char *fileName)
&constraint.mTargetOffset.mV[VY],
&constraint.mTargetOffset.mV[VZ]) != 13)
{
- return ST_NO_CONSTRAINT;
+ return E_ST_NO_CONSTRAINT;
}
}
else
@@ -463,7 +508,7 @@ LLBVHLoader::Status LLBVHLoader::loadTranslationTable(const char *fileName)
// at this point there must be a valid trans pointer
//----------------------------------------------------------------
if ( ! trans )
- return ST_NO_XLT_NAME;
+ return E_ST_NO_XLT_NAME;
//----------------------------------------------------------------
// check for ignore flag
@@ -472,7 +517,7 @@ LLBVHLoader::Status LLBVHLoader::loadTranslationTable(const char *fileName)
{
char trueFalse[128]; /* Flawfinder: ignore */
if ( sscanf(mLine, " %*s = %127s", trueFalse) != 1 ) /* Flawfinder: ignore */
- return ST_NO_XLT_IGNORE;
+ return E_ST_NO_XLT_IGNORE;
trans->mIgnore = (LLStringUtil::compareInsensitive(trueFalse, "true")==0);
continue;
@@ -497,12 +542,12 @@ LLBVHLoader::Status LLBVHLoader::loadTranslationTable(const char *fileName)
}
else
{
- return ST_NO_XLT_RELATIVE;
+ return E_ST_NO_XLT_RELATIVE;
}
}
else
{
- return ST_NO_XLT_RELATIVE;
+ return E_ST_NO_XLT_RELATIVE;
}
continue;
@@ -523,12 +568,12 @@ LLBVHLoader::Status LLBVHLoader::loadTranslationTable(const char *fileName)
}
else
{
- return ST_NO_XLT_RELATIVE;
+ return E_ST_NO_XLT_RELATIVE;
}
}
else
{
- return ST_NO_XLT_RELATIVE;
+ return E_ST_NO_XLT_RELATIVE;
}
continue;
@@ -541,7 +586,7 @@ LLBVHLoader::Status LLBVHLoader::loadTranslationTable(const char *fileName)
{
char outName[128]; /* Flawfinder: ignore */
if ( sscanf(mLine, " %*s = %127s", outName) != 1 ) /* Flawfinder: ignore */
- return ST_NO_XLT_OUTNAME;
+ return E_ST_NO_XLT_OUTNAME;
trans->mOutName = outName;
continue;
@@ -557,7 +602,7 @@ LLBVHLoader::Status LLBVHLoader::loadTranslationTable(const char *fileName)
&fm.mMatrix[0][0], &fm.mMatrix[0][1], &fm.mMatrix[0][2],
&fm.mMatrix[1][0], &fm.mMatrix[1][1], &fm.mMatrix[1][2],
&fm.mMatrix[2][0], &fm.mMatrix[2][1], &fm.mMatrix[2][2] ) != 9 )
- return ST_NO_XLT_MATRIX;
+ return E_ST_NO_XLT_MATRIX;
trans->mFrameMatrix = fm;
continue;
@@ -573,7 +618,7 @@ LLBVHLoader::Status LLBVHLoader::loadTranslationTable(const char *fileName)
&om.mMatrix[0][0], &om.mMatrix[0][1], &om.mMatrix[0][2],
&om.mMatrix[1][0], &om.mMatrix[1][1], &om.mMatrix[1][2],
&om.mMatrix[2][0], &om.mMatrix[2][1], &om.mMatrix[2][2] ) != 9 )
- return ST_NO_XLT_MATRIX;
+ return E_ST_NO_XLT_MATRIX;
trans->mOffsetMatrix = om;
continue;
@@ -586,7 +631,7 @@ LLBVHLoader::Status LLBVHLoader::loadTranslationTable(const char *fileName)
{
char mergeParentName[128]; /* Flawfinder: ignore */
if ( sscanf(mLine, " %*s = %127s", mergeParentName) != 1 ) /* Flawfinder: ignore */
- return ST_NO_XLT_MERGEPARENT;
+ return E_ST_NO_XLT_MERGEPARENT;
trans->mMergeParentName = mergeParentName;
continue;
@@ -599,7 +644,7 @@ LLBVHLoader::Status LLBVHLoader::loadTranslationTable(const char *fileName)
{
char mergeChildName[128]; /* Flawfinder: ignore */
if ( sscanf(mLine, " %*s = %127s", mergeChildName) != 1 ) /* Flawfinder: ignore */
- return ST_NO_XLT_MERGECHILD;
+ return E_ST_NO_XLT_MERGECHILD;
trans->mMergeChildName = mergeChildName;
continue;
@@ -612,7 +657,7 @@ LLBVHLoader::Status LLBVHLoader::loadTranslationTable(const char *fileName)
{
S32 priority;
if ( sscanf(mLine, " %*s = %d", &priority) != 1 )
- return ST_NO_XLT_PRIORITY;
+ return E_ST_NO_XLT_PRIORITY;
trans->mPriorityModifier = priority;
continue;
@@ -621,14 +666,14 @@ LLBVHLoader::Status LLBVHLoader::loadTranslationTable(const char *fileName)
}
infile.close() ;
- return ST_OK;
+ return E_ST_OK;
}
//------------------------------------------------------------------------
// LLBVHLoader::loadBVHFile()
//------------------------------------------------------------------------
-LLBVHLoader::Status LLBVHLoader::loadBVHFile(const char *buffer, char* error_text, S32 &err_line)
+ELoadStatus LLBVHLoader::loadBVHFile(const char *buffer, char* error_text, S32 &err_line)
{
std::string line;
@@ -650,14 +695,14 @@ LLBVHLoader::Status LLBVHLoader::loadBVHFile(const char *buffer, char* error_tex
// consume hierarchy
//--------------------------------------------------------------------
if (iter == tokens.end())
- return ST_EOF;
+ return E_ST_EOF;
line = (*(iter++));
err_line++;
if ( !strstr(line.c_str(), "HIERARCHY") )
{
// llinfos << line << llendl;
- return ST_NO_HIER;
+ return E_ST_NO_HIER;
}
//--------------------------------------------------------------------
@@ -669,7 +714,7 @@ LLBVHLoader::Status LLBVHLoader::loadBVHFile(const char *buffer, char* error_tex
// get next line
//----------------------------------------------------------------
if (iter == tokens.end())
- return ST_EOF;
+ return E_ST_EOF;
line = (*(iter++));
err_line++;
@@ -719,7 +764,7 @@ LLBVHLoader::Status LLBVHLoader::loadBVHFile(const char *buffer, char* error_tex
else
{
strncpy(error_text, line.c_str(), 127); /* Flawfinder: ignore */
- return ST_NO_JOINT;
+ return E_ST_NO_JOINT;
}
//----------------------------------------------------------------
@@ -729,7 +774,7 @@ LLBVHLoader::Status LLBVHLoader::loadBVHFile(const char *buffer, char* error_tex
if ( sscanf(line.c_str(), "%*s %79s", jointName) != 1 ) /* Flawfinder: ignore */
{
strncpy(error_text, line.c_str(), 127); /* Flawfinder: ignore */
- return ST_NO_NAME;
+ return E_ST_NO_NAME;
}
//----------------------------------------------------------------
@@ -754,7 +799,7 @@ LLBVHLoader::Status LLBVHLoader::loadBVHFile(const char *buffer, char* error_tex
//----------------------------------------------------------------
if (iter == tokens.end())
{
- return ST_EOF;
+ return E_ST_EOF;
}
line = (*(iter++));
err_line++;
@@ -765,7 +810,7 @@ LLBVHLoader::Status LLBVHLoader::loadBVHFile(const char *buffer, char* error_tex
if ( !strstr(line.c_str(), "{") )
{
strncpy(error_text, line.c_str(), 127); /*Flawfinder: ignore*/
- return ST_NO_OFFSET;
+ return E_ST_NO_OFFSET;
}
else
{
@@ -777,7 +822,7 @@ LLBVHLoader::Status LLBVHLoader::loadBVHFile(const char *buffer, char* error_tex
//----------------------------------------------------------------
if (iter == tokens.end())
{
- return ST_EOF;
+ return E_ST_EOF;
}
line = (*(iter++));
err_line++;
@@ -788,7 +833,7 @@ LLBVHLoader::Status LLBVHLoader::loadBVHFile(const char *buffer, char* error_tex
if ( !strstr(line.c_str(), "OFFSET") )
{
strncpy(error_text, line.c_str(), 127); /*Flawfinder: ignore*/
- return ST_NO_OFFSET;
+ return E_ST_NO_OFFSET;
}
//----------------------------------------------------------------
@@ -796,7 +841,7 @@ LLBVHLoader::Status LLBVHLoader::loadBVHFile(const char *buffer, char* error_tex
//----------------------------------------------------------------
if (iter == tokens.end())
{
- return ST_EOF;
+ return E_ST_EOF;
}
line = (*(iter++));
err_line++;
@@ -807,7 +852,7 @@ LLBVHLoader::Status LLBVHLoader::loadBVHFile(const char *buffer, char* error_tex
if ( !strstr(line.c_str(), "CHANNELS") )
{
strncpy(error_text, line.c_str(), 127); /*Flawfinder: ignore*/
- return ST_NO_CHANNELS;
+ return E_ST_NO_CHANNELS;
}
//----------------------------------------------------------------
@@ -820,14 +865,14 @@ LLBVHLoader::Status LLBVHLoader::loadBVHFile(const char *buffer, char* error_tex
if (!p)
{
strncpy(error_text, line.c_str(), 127); /*Flawfinder: ignore*/
- return ST_NO_ROTATION;
+ return E_ST_NO_ROTATION;
}
const char axis = *(p - 1);
if ((axis != 'X') && (axis != 'Y') && (axis != 'Z'))
{
strncpy(error_text, line.c_str(), 127); /*Flawfinder: ignore*/
- return ST_NO_AXIS;
+ return E_ST_NO_AXIS;
}
joint->mOrder[i] = axis;
@@ -842,7 +887,7 @@ LLBVHLoader::Status LLBVHLoader::loadBVHFile(const char *buffer, char* error_tex
if ( !strstr(line.c_str(), "MOTION") )
{
strncpy(error_text, line.c_str(), 127); /*Flawfinder: ignore*/
- return ST_NO_MOTION;
+ return E_ST_NO_MOTION;
}
//--------------------------------------------------------------------
@@ -850,7 +895,7 @@ LLBVHLoader::Status LLBVHLoader::loadBVHFile(const char *buffer, char* error_tex
//--------------------------------------------------------------------
if (iter == tokens.end())
{
- return ST_EOF;
+ return E_ST_EOF;
}
line = (*(iter++));
err_line++;
@@ -858,13 +903,13 @@ LLBVHLoader::Status LLBVHLoader::loadBVHFile(const char *buffer, char* error_tex
if ( !strstr(line.c_str(), "Frames:") )
{
strncpy(error_text, line.c_str(), 127); /*Flawfinder: ignore*/
- return ST_NO_FRAMES;
+ return E_ST_NO_FRAMES;
}
if ( sscanf(line.c_str(), "Frames: %d", &mNumFrames) != 1 )
{
strncpy(error_text, line.c_str(), 127); /*Flawfinder: ignore*/
- return ST_NO_FRAMES;
+ return E_ST_NO_FRAMES;
}
//--------------------------------------------------------------------
@@ -872,7 +917,7 @@ LLBVHLoader::Status LLBVHLoader::loadBVHFile(const char *buffer, char* error_tex
//--------------------------------------------------------------------
if (iter == tokens.end())
{
- return ST_EOF;
+ return E_ST_EOF;
}
line = (*(iter++));
err_line++;
@@ -880,13 +925,13 @@ LLBVHLoader::Status LLBVHLoader::loadBVHFile(const char *buffer, char* error_tex
if ( !strstr(line.c_str(), "Frame Time:") )
{
strncpy(error_text, line.c_str(), 127); /*Flawfinder: ignore*/
- return ST_NO_FRAME_TIME;
+ return E_ST_NO_FRAME_TIME;
}
if ( sscanf(line.c_str(), "Frame Time: %f", &mFrameTime) != 1 )
{
strncpy(error_text, line.c_str(), 127); /*Flawfinder: ignore*/
- return ST_NO_FRAME_TIME;
+ return E_ST_NO_FRAME_TIME;
}
mDuration = (F32)mNumFrames * mFrameTime;
@@ -903,7 +948,7 @@ LLBVHLoader::Status LLBVHLoader::loadBVHFile(const char *buffer, char* error_tex
// get next line
if (iter == tokens.end())
{
- return ST_EOF;
+ return E_ST_EOF;
}
line = (*(iter++));
err_line++;
@@ -922,7 +967,7 @@ LLBVHLoader::Status LLBVHLoader::loadBVHFile(const char *buffer, char* error_tex
if ( sscanf(p, "%f %f %f", key.mPos, key.mPos+1, key.mPos+2) != 3 )
{
strncpy(error_text, line.c_str(), 127); /*Flawfinder: ignore*/
- return ST_NO_POS;
+ return E_ST_NO_POS;
}
}
@@ -931,19 +976,19 @@ LLBVHLoader::Status LLBVHLoader::loadBVHFile(const char *buffer, char* error_tex
if (!p)
{
strncpy(error_text, line.c_str(), 127); /*Flawfinder: ignore*/
- return ST_NO_ROT;
+ return E_ST_NO_ROT;
}
p = find_next_whitespace(++p);
if (!p)
{
strncpy(error_text, line.c_str(), 127); /*Flawfinder: ignore*/
- return ST_NO_ROT;
+ return E_ST_NO_ROT;
}
p = find_next_whitespace(++p);
if (!p)
{
strncpy(error_text, line.c_str(), 127); /*Flawfinder: ignore*/
- return ST_NO_ROT;
+ return E_ST_NO_ROT;
}
// get 3 rot values for joint
@@ -951,7 +996,7 @@ LLBVHLoader::Status LLBVHLoader::loadBVHFile(const char *buffer, char* error_tex
if ( sscanf(p, " %f %f %f", rot, rot+1, rot+2) != 3 )
{
strncpy(error_text, line.c_str(), 127); /*Flawfinder: ignore*/
- return ST_NO_ROT;
+ return E_ST_NO_ROT;
}
p++;
@@ -962,7 +1007,7 @@ LLBVHLoader::Status LLBVHLoader::loadBVHFile(const char *buffer, char* error_tex
}
}
- return ST_OK;
+ return E_ST_OK;
}
diff --git a/indra/llcharacter/llbvhloader.h b/indra/llcharacter/llbvhloader.h
index 6937b9d835..ecdfc95478 100644
--- a/indra/llcharacter/llbvhloader.h
+++ b/indra/llcharacter/llbvhloader.h
@@ -184,6 +184,41 @@ public:
S32 mPriorityModifier;
};
+typedef enum e_load_status
+ {
+ E_ST_OK,
+ E_ST_EOF,
+ E_ST_NO_CONSTRAINT,
+ E_ST_NO_FILE,
+ E_ST_NO_HIER,
+ E_ST_NO_JOINT,
+ E_ST_NO_NAME,
+ E_ST_NO_OFFSET,
+ E_ST_NO_CHANNELS,
+ E_ST_NO_ROTATION,
+ E_ST_NO_AXIS,
+ E_ST_NO_MOTION,
+ E_ST_NO_FRAMES,
+ E_ST_NO_FRAME_TIME,
+ E_ST_NO_POS,
+ E_ST_NO_ROT,
+ E_ST_NO_XLT_FILE,
+ E_ST_NO_XLT_HEADER,
+ E_ST_NO_XLT_NAME,
+ E_ST_NO_XLT_IGNORE,
+ E_ST_NO_XLT_RELATIVE,
+ E_ST_NO_XLT_OUTNAME,
+ E_ST_NO_XLT_MATRIX,
+ E_ST_NO_XLT_MERGECHILD,
+ E_ST_NO_XLT_MERGEPARENT,
+ E_ST_NO_XLT_PRIORITY,
+ E_ST_NO_XLT_LOOP,
+ E_ST_NO_XLT_EASEIN,
+ E_ST_NO_XLT_EASEOUT,
+ E_ST_NO_XLT_HAND,
+ E_ST_NO_XLT_EMOTE
+ } ELoadStatus;
+
//------------------------------------------------------------------------
// TranslationMap
//------------------------------------------------------------------------
@@ -194,9 +229,11 @@ class LLBVHLoader
friend class LLKeyframeMotion;
public:
// Constructor
- LLBVHLoader(const char* buffer);
+// LLBVHLoader(const char* buffer);
+ LLBVHLoader(const char* buffer, ELoadStatus &loadStatus, S32 &errorLine);
~LLBVHLoader();
-
+
+/*
// Status Codes
typedef const char *Status;
static const char *ST_OK;
@@ -230,13 +267,13 @@ public:
static const char *ST_NO_XLT_EASEOUT;
static const char *ST_NO_XLT_HAND;
static const char *ST_NO_XLT_EMOTE;
-
+*/
// Loads the specified translation table.
- Status loadTranslationTable(const char *fileName);
+ ELoadStatus loadTranslationTable(const char *fileName);
// Load the specified BVH file.
// Returns status code.
- Status loadBVHFile(const char *buffer, char *error_text, S32 &error_line);
+ ELoadStatus loadBVHFile(const char *buffer, char *error_text, S32 &error_line);
// Applies translations to BVH data loaded.
void applyTranslations();
@@ -260,7 +297,7 @@ public:
BOOL isInitialized() { return mInitialized; }
- Status getStatus() { return mStatus; }
+ ELoadStatus getStatus() { return mStatus; }
protected:
// Consumes one line of input from file.
@@ -287,7 +324,7 @@ protected:
std::string mEmoteName;
BOOL mInitialized;
- Status mStatus;
+ ELoadStatus mStatus;
// computed values
F32 mDuration;
};
diff --git a/indra/llcharacter/llcharacter.cpp b/indra/llcharacter/llcharacter.cpp
index 6633c65317..20ff7bab34 100644
--- a/indra/llcharacter/llcharacter.cpp
+++ b/indra/llcharacter/llcharacter.cpp
@@ -180,9 +180,11 @@ void LLCharacter::requestStopMotion( LLMotion* motion)
//-----------------------------------------------------------------------------
// updateMotions()
//-----------------------------------------------------------------------------
+static LLFastTimer::DeclareTimer FTM_UPDATE_ANIMATION("Update Animation");
+
void LLCharacter::updateMotions(e_update_t update_type)
{
- LLFastTimer t(LLFastTimer::FTM_UPDATE_ANIMATION);
+ LLFastTimer t(FTM_UPDATE_ANIMATION);
if (update_type == HIDDEN_UPDATE)
{
mMotionController.updateMotionsMinimal();
diff --git a/indra/llcharacter/llcharacter.h b/indra/llcharacter/llcharacter.h
index 0112788884..cd8f9e63fb 100644
--- a/indra/llcharacter/llcharacter.h
+++ b/indra/llcharacter/llcharacter.h
@@ -42,7 +42,7 @@
#include "llmotioncontroller.h"
#include "llvisualparam.h"
#include "string_table.h"
-#include "llmemory.h"
+#include "llpointer.h"
#include "llthread.h"
class LLPolyMesh;
@@ -169,7 +169,7 @@ public:
void updateMotions(e_update_t update_type);
LLAnimPauseRequest requestPause();
- BOOL areAnimationsPaused() { return mMotionController.isPaused(); }
+ BOOL areAnimationsPaused() const { return mMotionController.isPaused(); }
void setAnimTimeFactor(F32 factor) { mMotionController.setTimeFactor(factor); }
void setTimeStep(F32 time_step) { mMotionController.setTimeStep(time_step); }
@@ -231,9 +231,9 @@ public:
return (mCurIterator++)->second;
}
- LLVisualParam* getVisualParam(S32 id)
+ LLVisualParam* getVisualParam(S32 id) const
{
- VisualParamIndexMap_t::iterator iter = mVisualParamIndexMap.find(id);
+ VisualParamIndexMap_t::const_iterator iter = mVisualParamIndexMap.find(id);
return (iter == mVisualParamIndexMap.end()) ? 0 : iter->second;
}
S32 getVisualParamID(LLVisualParam *id)
@@ -246,11 +246,11 @@ public:
}
return 0;
}
- S32 getVisualParamCount() { return (S32)mVisualParamIndexMap.size(); }
+ S32 getVisualParamCount() const { return (S32)mVisualParamIndexMap.size(); }
LLVisualParam* getVisualParam(const char *name);
- ESex getSex() { return mSex; }
+ ESex getSex() const { return mSex; }
void setSex( ESex sex ) { mSex = sex; }
U32 getAppearanceSerialNum() const { return mAppearanceSerialNum; }
diff --git a/indra/llcharacter/lljoint.h b/indra/llcharacter/lljoint.h
index b1a0b74f85..0473d1599a 100644
--- a/indra/llcharacter/lljoint.h
+++ b/indra/llcharacter/lljoint.h
@@ -174,7 +174,7 @@ public:
void clampRotation(LLQuaternion old_rot, LLQuaternion new_rot);
- virtual BOOL isAnimatable() { return TRUE; }
+ virtual BOOL isAnimatable() const { return TRUE; }
S32 getJointNum() const { return mJointNum; }
void setJointNum(S32 joint_num) { mJointNum = joint_num; }
diff --git a/indra/llcharacter/lljointstate.h b/indra/llcharacter/lljointstate.h
index 16ad0e1200..e40cf2673f 100644
--- a/indra/llcharacter/lljointstate.h
+++ b/indra/llcharacter/lljointstate.h
@@ -37,7 +37,7 @@
// Header Files
//-----------------------------------------------------------------------------
#include "lljoint.h"
-#include "llmemory.h"
+#include "llrefcount.h"
//-----------------------------------------------------------------------------
// class LLJointState
diff --git a/indra/llcharacter/llkeyframemotionparam.cpp b/indra/llcharacter/llkeyframemotionparam.cpp
index 622405a5e1..c4333fc0fd 100644
--- a/indra/llcharacter/llkeyframemotionparam.cpp
+++ b/indra/llcharacter/llkeyframemotionparam.cpp
@@ -347,8 +347,11 @@ BOOL LLKeyframeMotionParam::loadMotions()
// Load named file by concatenating the character prefix with the motion name.
// Load data into a buffer to be parsed.
//-------------------------------------------------------------------------
- std::string path = gDirUtilp->getExpandedFilename(LL_PATH_MOTIONS,mCharacter->getAnimationPrefix())
- + "_" + getName() + ".llp";
+ //std::string path = gDirUtilp->getExpandedFilename(LL_PATH_MOTIONS,mCharacter->getAnimationPrefix())
+ // + "_" + getName() + ".llp";
+ //RN: deprecated unused reference to "motion" directory
+ std::string path;
+
//-------------------------------------------------------------------------
// open the file
diff --git a/indra/llcharacter/llmotioncontroller.cpp b/indra/llcharacter/llmotioncontroller.cpp
index 006d2b5f62..bb9625b2bd 100644
--- a/indra/llcharacter/llmotioncontroller.cpp
+++ b/indra/llcharacter/llmotioncontroller.cpp
@@ -1019,9 +1019,9 @@ bool LLMotionController::isMotionLoading(LLMotion* motion)
//-----------------------------------------------------------------------------
// findMotion()
//-----------------------------------------------------------------------------
-LLMotion* LLMotionController::findMotion(const LLUUID& id)
+LLMotion* LLMotionController::findMotion(const LLUUID& id) const
{
- motion_map_t::iterator iter = mAllMotions.find(id);
+ motion_map_t::const_iterator iter = mAllMotions.find(id);
if(iter == mAllMotions.end())
{
return NULL;
diff --git a/indra/llcharacter/llmotioncontroller.h b/indra/llcharacter/llmotioncontroller.h
index 9271483a25..5c3ec223cb 100644
--- a/indra/llcharacter/llmotioncontroller.h
+++ b/indra/llcharacter/llmotioncontroller.h
@@ -153,12 +153,12 @@ public:
// pause and continue all motions
void pauseAllMotions();
void unpauseAllMotions();
- BOOL isPaused() { return mPaused; }
+ BOOL isPaused() const { return mPaused; }
void setTimeStep(F32 step);
void setTimeFactor(F32 time_factor);
- F32 getTimeFactor() { return mTimeFactor; }
+ F32 getTimeFactor() const { return mTimeFactor; }
motion_list_t& getActiveMotions() { return mActiveMotions; }
@@ -167,7 +167,7 @@ public:
//protected:
bool isMotionActive( LLMotion *motion );
bool isMotionLoading( LLMotion *motion );
- LLMotion *findMotion( const LLUUID& id );
+ LLMotion *findMotion( const LLUUID& id ) const;
protected:
// internal operations act on motion instances directly
diff --git a/indra/llcharacter/llmultigesture.cpp b/indra/llcharacter/llmultigesture.cpp
index 7fe21dbc93..05d1bc0cd9 100644
--- a/indra/llcharacter/llmultigesture.cpp
+++ b/indra/llcharacter/llmultigesture.cpp
@@ -50,6 +50,7 @@ const S32 GESTURE_VERSION = 2;
LLMultiGesture::LLMultiGesture()
: mKey(),
mMask(),
+ mName(),
mTrigger(),
mReplaceText(),
mSteps(),
@@ -243,7 +244,7 @@ void LLMultiGesture::dump()
//---------------------------------------------------------------------------
LLGestureStepAnimation::LLGestureStepAnimation()
: LLGestureStep(),
- mAnimName("None"),
+ mAnimName("None"),
mAnimAssetID(),
mFlags(0x0)
{ }
@@ -292,20 +293,27 @@ BOOL LLGestureStepAnimation::deserialize(LLDataPacker& dp)
dp.unpackU32(mFlags, "flags");
return TRUE;
}
-
-std::string LLGestureStepAnimation::getLabel() const
+// *TODO: Translate
+std::vector<std::string> LLGestureStepAnimation::getLabel() const
{
- std::string label;
+ std::vector<std::string> strings;
+
+// std::string label;
if (mFlags & ANIM_FLAG_STOP)
{
- label = "Stop Animation: ";
+ strings.push_back( "AnimFlagStop");
+
+// label = "Stop Animation: ";
}
else
{
- label = "Start Animation: ";
+ strings.push_back( "AnimFlagStart");
+
+// label = "Start Animation: ";
}
- label += mAnimName;
- return label;
+ strings.push_back( mAnimName);
+// label += mAnimName;
+ return strings;
}
void LLGestureStepAnimation::dump()
@@ -359,12 +367,15 @@ BOOL LLGestureStepSound::deserialize(LLDataPacker& dp)
dp.unpackU32(mFlags, "flags");
return TRUE;
}
-
-std::string LLGestureStepSound::getLabel() const
+// *TODO: Translate
+std::vector<std::string> LLGestureStepSound::getLabel() const
{
- std::string label("Sound: ");
- label += mSoundName;
- return label;
+ std::vector<std::string> strings;
+ strings.push_back( "Sound");
+ strings.push_back( mSoundName);
+// std::string label("Sound: ");
+// label += mSoundName;
+ return strings;
}
void LLGestureStepSound::dump()
@@ -414,12 +425,13 @@ BOOL LLGestureStepChat::deserialize(LLDataPacker& dp)
dp.unpackU32(mFlags, "flags");
return TRUE;
}
-
-std::string LLGestureStepChat::getLabel() const
+// *TODO: Translate
+std::vector<std::string> LLGestureStepChat::getLabel() const
{
- std::string label("Chat: ");
- label += mChatText;
- return label;
+ std::vector<std::string> strings;
+ strings.push_back("Chat");
+ strings.push_back(mChatText);
+ return strings;
}
void LLGestureStepChat::dump()
@@ -467,22 +479,27 @@ BOOL LLGestureStepWait::deserialize(LLDataPacker& dp)
dp.unpackU32(mFlags, "flags");
return TRUE;
}
-
-std::string LLGestureStepWait::getLabel() const
+// *TODO: Translate
+std::vector<std::string> LLGestureStepWait::getLabel() const
{
- std::string label("--- Wait: ");
+ std::vector<std::string> strings;
+ strings.push_back( "Wait" );
+
+// std::string label("--- Wait: ");
if (mFlags & WAIT_FLAG_TIME)
{
char buffer[64]; /* Flawfinder: ignore */
snprintf(buffer, sizeof(buffer), "%.1f seconds", (double)mWaitSeconds); /* Flawfinder: ignore */
- label += buffer;
+ strings.push_back(buffer);
+// label += buffer;
}
else if (mFlags & WAIT_FLAG_ALL_ANIM)
{
- label += "until animations are done";
+ strings.push_back("until animations are done");
+ // label += "until animations are done";
}
- return label;
+ return strings;
}
diff --git a/indra/llcharacter/llmultigesture.h b/indra/llcharacter/llmultigesture.h
index eb15f600ca..fdcf32dc67 100644
--- a/indra/llcharacter/llmultigesture.h
+++ b/indra/llcharacter/llmultigesture.h
@@ -65,11 +65,13 @@ protected:
const LLMultiGesture& operator=(const LLMultiGesture& rhs);
public:
- // name is stored at asset level
- // desc is stored at asset level
KEY mKey;
MASK mMask;
+ // This name can be empty if the inventory item is not around and
+ // the gesture manager has not yet set the name
+ std::string mName;
+
// String, like "/foo" or "hello" that makes it play
std::string mTrigger;
@@ -130,7 +132,7 @@ public:
virtual EStepType getType() = 0;
// Return a user-readable label for this step
- virtual std::string getLabel() const = 0;
+ virtual std::vector<std::string> getLabel() const = 0;
virtual S32 getMaxSerialSize() const = 0;
virtual BOOL serialize(LLDataPacker& dp) const = 0;
@@ -152,7 +154,7 @@ public:
virtual EStepType getType() { return STEP_ANIMATION; }
- virtual std::string getLabel() const;
+ virtual std::vector<std::string> getLabel() const;
virtual S32 getMaxSerialSize() const;
virtual BOOL serialize(LLDataPacker& dp) const;
@@ -175,7 +177,7 @@ public:
virtual EStepType getType() { return STEP_SOUND; }
- virtual std::string getLabel() const;
+ virtual std::vector<std::string> getLabel() const;
virtual S32 getMaxSerialSize() const;
virtual BOOL serialize(LLDataPacker& dp) const;
@@ -198,7 +200,7 @@ public:
virtual EStepType getType() { return STEP_CHAT; }
- virtual std::string getLabel() const;
+ virtual std::vector<std::string> getLabel() const;
virtual S32 getMaxSerialSize() const;
virtual BOOL serialize(LLDataPacker& dp) const;
@@ -223,7 +225,7 @@ public:
virtual EStepType getType() { return STEP_WAIT; }
- virtual std::string getLabel() const;
+ virtual std::vector<std::string> getLabel() const;
virtual S32 getMaxSerialSize() const;
virtual BOOL serialize(LLDataPacker& dp) const;
diff --git a/indra/llcharacter/llpose.cpp b/indra/llcharacter/llpose.cpp
index 93255d702c..dd4880dbb9 100644
--- a/indra/llcharacter/llpose.cpp
+++ b/indra/llcharacter/llpose.cpp
@@ -516,9 +516,9 @@ BOOL LLPoseBlender::addMotion(LLMotion* motion)
void LLPoseBlender::blendAndApply()
{
for (blender_list_t::iterator iter = mActiveBlenders.begin();
- iter != mActiveBlenders.end(); ++iter)
+ iter != mActiveBlenders.end(); )
{
- LLJointStateBlender* jsbp = *iter;
+ LLJointStateBlender* jsbp = *iter++;
jsbp->blendJointStates();
}
diff --git a/indra/llcharacter/llpose.h b/indra/llcharacter/llpose.h
index 5698f21614..2b976b219d 100644
--- a/indra/llcharacter/llpose.h
+++ b/indra/llcharacter/llpose.h
@@ -36,12 +36,14 @@
//-----------------------------------------------------------------------------
// Header Files
//-----------------------------------------------------------------------------
-#include <string>
-#include "llmap.h"
#include "lljointstate.h"
#include "lljoint.h"
+#include "llmap.h"
+#include "llpointer.h"
+
#include <map>
+#include <string>
//-----------------------------------------------------------------------------
diff --git a/indra/llcharacter/llvisualparam.h b/indra/llcharacter/llvisualparam.h
index 3a0c1bbc77..25c41e8509 100644
--- a/indra/llcharacter/llvisualparam.h
+++ b/indra/llcharacter/llvisualparam.h
@@ -112,7 +112,7 @@ public:
virtual void stopAnimating(BOOL set_by_user);
// Interface methods
- S32 getID() { return mID; }
+ S32 getID() const { return mID; }
void setID(S32 id) { llassert(!mInfo); mID = id; }
const std::string& getName() const { return mInfo->mName; }
@@ -124,22 +124,22 @@ public:
void setMaxDisplayName(const std::string& s) { mInfo->mMaxName = s; }
void setMinDisplayName(const std::string& s) { mInfo->mMinName = s; }
- EVisualParamGroup getGroup() { return mInfo->mGroup; }
- F32 getMinWeight() { return mInfo->mMinWeight; }
- F32 getMaxWeight() { return mInfo->mMaxWeight; }
- F32 getDefaultWeight() { return mInfo->mDefaultWeight; }
- ESex getSex() { return mInfo->mSex; }
+ EVisualParamGroup getGroup() const { return mInfo->mGroup; }
+ F32 getMinWeight() const { return mInfo->mMinWeight; }
+ F32 getMaxWeight() const { return mInfo->mMaxWeight; }
+ F32 getDefaultWeight() const { return mInfo->mDefaultWeight; }
+ ESex getSex() const { return mInfo->mSex; }
- F32 getWeight() { return mIsAnimating ? mTargetWeight : mCurWeight; }
- F32 getCurrentWeight() { return mCurWeight; }
- F32 getLastWeight() { return mLastWeight; }
- BOOL isAnimating() { return mIsAnimating; }
+ F32 getWeight() const { return mIsAnimating ? mTargetWeight : mCurWeight; }
+ F32 getCurrentWeight() const { return mCurWeight; }
+ F32 getLastWeight() const { return mLastWeight; }
+ BOOL isAnimating() const { return mIsAnimating; }
LLVisualParam* getNextParam() { return mNext; }
void setNextParam( LLVisualParam *next );
virtual void setAnimating(BOOL is_animating) { mIsAnimating = is_animating; }
- BOOL getAnimating() { return mIsAnimating; }
+ BOOL getAnimating() const { return mIsAnimating; }
protected:
F32 mCurWeight; // current weight
diff --git a/indra/llcommon/CMakeLists.txt b/indra/llcommon/CMakeLists.txt
index 7bfcd43684..a93623d24e 100644
--- a/indra/llcommon/CMakeLists.txt
+++ b/indra/llcommon/CMakeLists.txt
@@ -3,7 +3,9 @@
project(llcommon)
include(00-Common)
+include(LLAddBuildTest)
include(LLCommon)
+include(Boost)
include_directories(
${EXPAT_INCLUDE_DIRS}
@@ -11,7 +13,14 @@ include_directories(
${ZLIB_INCLUDE_DIRS}
)
+# add_executable(lltreeiterators lltreeiterators.cpp)
+#
+# target_link_libraries(lltreeiterators
+# ${LLCOMMON_LIBRARIES})
+
set(llcommon_SOURCE_FILES
+ llallocator.cpp
+ llallocator_heap_profile.cpp
llapp.cpp
llapr.cpp
llassettype.cpp
@@ -40,11 +49,16 @@ set(llcommon_SOURCE_FILES
llmd5.cpp
llmemory.cpp
llmemorystream.cpp
+ llmemtype.cpp
llmetrics.cpp
llmortician.cpp
+ lloptioninterface.cpp
+ llptrto.cpp
+ llprocesslauncher.cpp
llprocessor.cpp
llqueuedthread.cpp
llrand.cpp
+ llrefcount.cpp
llrun.cpp
llsd.cpp
llsdserialize.cpp
@@ -52,6 +66,7 @@ set(llcommon_SOURCE_FILES
llsdutil.cpp
llsecondlifeurls.cpp
llstat.cpp
+ llstacktrace.cpp
llstreamtools.cpp
llstring.cpp
llstringtable.cpp
@@ -78,6 +93,8 @@ set(llcommon_HEADER_FILES
indra_constants.h
linden_common.h
linked_lists.h
+ llallocator.h
+ llallocator_heap_profile.h
llagentconstants.h
llapp.h
llapr.h
@@ -98,9 +115,11 @@ set(llcommon_HEADER_FILES
lldate.h
lldefs.h
lldependencies.h
+ lldeleteutils.h
lldepthstack.h
lldictionary.h
lldlinked.h
+ lldoubledispatch.h
lldqueueptr.h
llendianswizzle.h
llenum.h
@@ -122,6 +141,7 @@ set(llcommon_HEADER_FILES
llheartbeat.h
llhttpstatuscodes.h
llindexedqueue.h
+ llinstancetracker.h
llkeythrottle.h
lllazy.h
lllinkedqueue.h
@@ -138,23 +158,32 @@ set(llcommon_HEADER_FILES
llmetrics.h
llmortician.h
llnametable.h
+ lloptioninterface.h
+ llpointer.h
llpreprocessor.h
llpriqueuemap.h
+ llprocesslauncher.h
llprocessor.h
llptrskiplist.h
llptrskipmap.h
+ llptrto.h
llqueuedthread.h
llrand.h
+ llrefcount.h
llrun.h
+ llrefcount.h
+ llsafehandle.h
llsd.h
llsdserialize.h
llsdserialize_xml.h
llsdutil.h
llsecondlifeurls.h
llsimplehash.h
+ llsingleton.h
llskiplist.h
llskipmap.h
llstack.h
+ llstacktrace.h
llstat.h
llstatenums.h
llstl.h
@@ -165,6 +194,7 @@ set(llcommon_HEADER_FILES
llsys.h
llthread.h
lltimer.h
+ lltreeiterators.h
lluri.h
lluuid.h
lluuidhashmap.h
@@ -200,6 +230,8 @@ target_link_libraries(
${APR_LIBRARIES}
${EXPAT_LIBRARIES}
${ZLIB_LIBRARIES}
+ ${BOOST_PROGRAM_OPTIONS_LIBRARY}
+ ${BOOST_REGEX_LIBRARY}
)
include(LLAddBuildTest)
@@ -209,3 +241,11 @@ SET(llcommon_TEST_SOURCE_FILES
)
LL_ADD_PROJECT_UNIT_TESTS(llcommon "${llcommon_TEST_SOURCE_FILES}")
+#set(TEST_DEBUG on)
+set(test_libs llcommon ${LLCOMMON_LIBRARIES} ${WINDOWS_LIBRARIES})
+LL_ADD_INTEGRATION_TEST(lllazy lllazy.cpp "${test_libs}")
+
+# *TODO - reenable these once tcmalloc libs no longer break the build.
+#ADD_BUILD_TEST(llallocator llcommon)
+#ADD_BUILD_TEST(llallocator_heap_profile llcommon)
+#ADD_BUILD_TEST(llmemtype llcommon)
diff --git a/indra/llcommon/is_approx_equal_fraction.h b/indra/llcommon/is_approx_equal_fraction.h
index f95b148590..d369fbc5b3 100644
--- a/indra/llcommon/is_approx_equal_fraction.h
+++ b/indra/llcommon/is_approx_equal_fraction.h
@@ -7,7 +7,30 @@
* making llcommon depend on llmath.
*
* $LicenseInfo:firstyear=2009&license=viewergpl$
+ *
* Copyright (c) 2009, Linden Research, Inc.
+ *
+ * Second Life Viewer Source Code
+ * The source code in this file ("Source Code") is provided by Linden Lab
+ * to you under the terms of the GNU General Public License, version 2.0
+ * ("GPL"), unless you have obtained a separate licensing agreement
+ * ("Other License"), formally executed by you and Linden Lab. Terms of
+ * the GPL can be found in doc/GPL-license.txt in this distribution, or
+ * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
+ *
+ * There are special exceptions to the terms and conditions of the GPL as
+ * it is applied to this Source Code. View the full text of the exception
+ * in the file doc/FLOSS-exception.txt in this software distribution, or
+ * online at
+ * http://secondlifegrid.net/programs/open_source/licensing/flossexception
+ *
+ * By copying, modifying or distributing this software, you acknowledge
+ * that you have read and understood your obligations described above,
+ * and agree to abide by those obligations.
+ *
+ * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+ * COMPLETENESS OR PERFORMANCE.
* $/LicenseInfo$
*/
diff --git a/indra/llcommon/linden_common.h b/indra/llcommon/linden_common.h
index f9d5877ab2..9adf24a492 100644
--- a/indra/llcommon/linden_common.h
+++ b/indra/llcommon/linden_common.h
@@ -33,6 +33,11 @@
#ifndef LL_LINDEN_COMMON_H
#define LL_LINDEN_COMMON_H
+// *NOTE: Please keep includes here to a minimum!
+//
+// Files included here are included in every library .cpp file and
+// are not precompiled.
+
#if defined(LL_WINDOWS) && defined(_DEBUG)
# if _MSC_VER >= 1400 // Visual C++ 2005 or later
# define _CRTDBG_MAP_ALLOC
@@ -51,23 +56,22 @@
#include <cstdio>
#include <cstdlib>
#include <ctime>
-#include <iostream>
-#include <fstream>
+#include <iosfwd>
-// Work Microsoft compiler warnings
+// Work around Microsoft compiler warnings in STL headers
#ifdef LL_WINDOWS
#pragma warning (disable : 4702) // unreachable code
#pragma warning (disable : 4244) // conversion from time_t to S32
#endif // LL_WINDOWS
-#include <algorithm>
#include <list>
#include <map>
#include <vector>
#include <string>
#ifdef LL_WINDOWS
-#pragma warning (3 : 4702) // we like level 3, not 4
+// Reenable warnings we disabled above
+#pragma warning (3 : 4702) // unreachable code, we like level 3, not 4
// level 4 warnings that we need to disable:
#pragma warning (disable : 4100) // unreferenced formal parameter
#pragma warning (disable : 4127) // conditional expression is constant (e.g. while(1) )
@@ -78,6 +82,7 @@
#endif // LL_WINDOWS
// Linden only libs in alpha-order other than stdtypes.h
+// *NOTE: Please keep includes here to a minimum, see above.
#include "stdtypes.h"
#include "lldefs.h"
#include "llerror.h"
@@ -85,8 +90,5 @@
#include "llfasttimer.h"
#include "llfile.h"
#include "llformat.h"
-#include "llstring.h"
-#include "llsys.h"
-#include "lltimer.h"
#endif
diff --git a/indra/llcommon/llallocator.cpp b/indra/llcommon/llallocator.cpp
new file mode 100644
index 0000000000..eed9d1e7db
--- /dev/null
+++ b/indra/llcommon/llallocator.cpp
@@ -0,0 +1,140 @@
+/**
+ * @file llallocator.cpp
+ * @brief Implementation of the LLAllocator class.
+ *
+ * $LicenseInfo:firstyear=2009&license=viewergpl$
+ *
+ * Copyright (c) 2009-2009, Linden Research, Inc.
+ *
+ * Second Life Viewer Source Code
+ * The source code in this file ("Source Code") is provided by Linden Lab
+ * to you under the terms of the GNU General Public License, version 2.0
+ * ("GPL"), unless you have obtained a separate licensing agreement
+ * ("Other License"), formally executed by you and Linden Lab. Terms of
+ * the GPL can be found in doc/GPL-license.txt in this distribution, or
+ * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
+ *
+ * There are special exceptions to the terms and conditions of the GPL as
+ * it is applied to this Source Code. View the full text of the exception
+ * in the file doc/FLOSS-exception.txt in this software distribution, or
+ * online at
+ * http://secondlifegrid.net/programs/open_source/licensing/flossexception
+ *
+ * By copying, modifying or distributing this software, you acknowledge
+ * that you have read and understood your obligations described above,
+ * and agree to abide by those obligations.
+ *
+ * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+ * COMPLETENESS OR PERFORMANCE.
+ * $/LicenseInfo$
+ */
+
+#include "linden_common.h"
+#include "llallocator.h"
+
+#if LL_USE_TCMALLOC
+
+#include "google/heap-profiler.h"
+#include "google/commandlineflags_public.h"
+
+DECLARE_bool(heap_profile_use_stack_trace);
+//DECLARE_double(tcmalloc_release_rate);
+
+// static
+void LLAllocator::pushMemType(S32 type)
+{
+ if(isProfiling())
+ {
+ PushMemType(type);
+ }
+}
+
+// static
+S32 LLAllocator::popMemType()
+{
+ if (isProfiling())
+ {
+ return PopMemType();
+ }
+ else
+ {
+ return -1;
+ }
+}
+
+void LLAllocator::setProfilingEnabled(bool should_enable)
+{
+ // NULL disables dumping to disk
+ static char const * const PREFIX = NULL;
+ if(should_enable)
+ {
+ HeapProfilerSetUseStackTrace(false);
+ HeapProfilerStart(PREFIX);
+ }
+ else
+ {
+ HeapProfilerStop();
+ }
+}
+
+// static
+bool LLAllocator::isProfiling()
+{
+ return IsHeapProfilerRunning();
+}
+
+std::string LLAllocator::getRawProfile()
+{
+ // *TODO - fix google-perftools to accept an buffer to avoid this
+ // malloc-copy-free cycle.
+ char * buffer = GetHeapProfile();
+ std::string ret = buffer;
+ free(buffer);
+ return ret;
+}
+
+#else // LL_USE_TCMALLOC
+
+//
+// stub implementations for when tcmalloc is disabled
+//
+
+// static
+void LLAllocator::pushMemType(S32 type)
+{
+}
+
+// static
+S32 LLAllocator::popMemType()
+{
+ return -1;
+}
+
+void LLAllocator::setProfilingEnabled(bool should_enable)
+{
+}
+
+// static
+bool LLAllocator::isProfiling()
+{
+ return false;
+}
+
+std::string LLAllocator::getRawProfile()
+{
+ return std::string();
+}
+
+#endif // LL_USE_TCMALLOC
+
+LLAllocatorHeapProfile const & LLAllocator::getProfile()
+{
+ mProf.mLines.clear();
+
+ // *TODO - avoid making all these extra copies of things...
+ std::string prof_text = getRawProfile();
+ //std::cout << prof_text << std::endl;
+ mProf.parse(prof_text);
+ return mProf;
+}
diff --git a/indra/llcommon/llallocator.h b/indra/llcommon/llallocator.h
new file mode 100644
index 0000000000..2b70fee0b8
--- /dev/null
+++ b/indra/llcommon/llallocator.h
@@ -0,0 +1,63 @@
+/**
+ * @file llallocator.h
+ * @brief Declaration of the LLAllocator class.
+ *
+ * $LicenseInfo:firstyear=2009&license=viewergpl$
+ *
+ * Copyright (c) 2009-2009, Linden Research, Inc.
+ *
+ * Second Life Viewer Source Code
+ * The source code in this file ("Source Code") is provided by Linden Lab
+ * to you under the terms of the GNU General Public License, version 2.0
+ * ("GPL"), unless you have obtained a separate licensing agreement
+ * ("Other License"), formally executed by you and Linden Lab. Terms of
+ * the GPL can be found in doc/GPL-license.txt in this distribution, or
+ * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
+ *
+ * There are special exceptions to the terms and conditions of the GPL as
+ * it is applied to this Source Code. View the full text of the exception
+ * in the file doc/FLOSS-exception.txt in this software distribution, or
+ * online at
+ * http://secondlifegrid.net/programs/open_source/licensing/flossexception
+ *
+ * By copying, modifying or distributing this software, you acknowledge
+ * that you have read and understood your obligations described above,
+ * and agree to abide by those obligations.
+ *
+ * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+ * COMPLETENESS OR PERFORMANCE.
+ * $/LicenseInfo$
+ */
+
+#ifndef LL_LLALLOCATOR_H
+#define LL_LLALLOCATOR_H
+
+#include <string>
+
+#include "llmemtype.h"
+#include "llallocator_heap_profile.h"
+
+class LLAllocator {
+ friend class LLMemoryView;
+ friend class LLMemType;
+
+private:
+ static void pushMemType(S32 type);
+ static S32 popMemType();
+
+public:
+ void setProfilingEnabled(bool should_enable);
+
+ static bool isProfiling();
+
+ LLAllocatorHeapProfile const & getProfile();
+
+private:
+ std::string getRawProfile();
+
+private:
+ LLAllocatorHeapProfile mProf;
+};
+
+#endif // LL_LLALLOCATOR_H
diff --git a/indra/llcommon/llallocator_heap_profile.cpp b/indra/llcommon/llallocator_heap_profile.cpp
new file mode 100644
index 0000000000..d82ee9ed81
--- /dev/null
+++ b/indra/llcommon/llallocator_heap_profile.cpp
@@ -0,0 +1,149 @@
+/**
+ * @file llallocator_heap_profile.cpp
+ * @brief Implementation of the parser for tcmalloc heap profile data.
+ * @author Brad Kittenbrink
+ *
+ * $LicenseInfo:firstyear=2009&license=viewergpl$
+ *
+ * Copyright (c) 2009-2009, Linden Research, Inc.
+ *
+ * Second Life Viewer Source Code
+ * The source code in this file ("Source Code") is provided by Linden Lab
+ * to you under the terms of the GNU General Public License, version 2.0
+ * ("GPL"), unless you have obtained a separate licensing agreement
+ * ("Other License"), formally executed by you and Linden Lab. Terms of
+ * the GPL can be found in doc/GPL-license.txt in this distribution, or
+ * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
+ *
+ * There are special exceptions to the terms and conditions of the GPL as
+ * it is applied to this Source Code. View the full text of the exception
+ * in the file doc/FLOSS-exception.txt in this software distribution, or
+ * online at
+ * http://secondlifegrid.net/programs/open_source/licensing/flossexception
+ *
+ * By copying, modifying or distributing this software, you acknowledge
+ * that you have read and understood your obligations described above,
+ * and agree to abide by those obligations.
+ *
+ * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+ * COMPLETENESS OR PERFORMANCE.
+ * $/LicenseInfo$
+ */
+
+#include "linden_common.h"
+#include "llallocator_heap_profile.h"
+
+#if LL_MSVC
+// disable warning about boost::lexical_cast returning uninitialized data
+// when it fails to parse the string
+#pragma warning (disable:4701)
+#endif
+
+#include <boost/algorithm/string/split.hpp>
+#include <boost/bind.hpp>
+#include <boost/lexical_cast.hpp>
+#include <boost/range/iterator_range.hpp>
+
+static const std::string HEAP_PROFILE_MAGIC_STR = "heap profile:";
+
+static bool is_separator(char c)
+{
+ return isspace(c) || c == '[' || c == ']' || c == ':';
+}
+
+void LLAllocatorHeapProfile::parse(std::string const & prof_text)
+{
+ // a typedef for handling a token in the string buffer
+ // it's a begin/end pair of string::const_iterators
+ typedef boost::iterator_range<std::string::const_iterator> range_t;
+
+ mLines.clear();
+
+ if(prof_text.compare(0, HEAP_PROFILE_MAGIC_STR.length(), HEAP_PROFILE_MAGIC_STR) != 0)
+ {
+ // *TODO - determine if there should be some better error state than
+ // mLines being empty. -brad
+ llwarns << "invalid heap profile data passed into parser." << llendl;
+ return;
+ }
+
+ std::vector< range_t > prof_lines;
+
+ std::string::const_iterator prof_begin = prof_text.begin() + HEAP_PROFILE_MAGIC_STR.length();
+
+ range_t prof_range(prof_begin, prof_text.end());
+ boost::algorithm::split(prof_lines,
+ prof_range,
+ boost::bind(std::equal_to<llwchar>(), '\n', _1));
+
+ std::vector< range_t >::const_iterator i;
+ for(i = prof_lines.begin(); i != prof_lines.end() && !i->empty(); ++i)
+ {
+ range_t const & line_text = *i;
+
+ std::vector<range_t> line_elems;
+
+ boost::algorithm::split(line_elems,
+ line_text,
+ is_separator);
+
+ std::vector< range_t >::iterator j;
+ j = line_elems.begin();
+
+ while(j != line_elems.end() && j->empty()) { ++j; } // skip any separator tokens
+ llassert_always(j != line_elems.end());
+ U32 live_count = boost::lexical_cast<U32>(*j);
+ ++j;
+
+ while(j != line_elems.end() && j->empty()) { ++j; } // skip any separator tokens
+ llassert_always(j != line_elems.end());
+ U64 live_size = boost::lexical_cast<U64>(*j);
+ ++j;
+
+ while(j != line_elems.end() && j->empty()) { ++j; } // skip any separator tokens
+ llassert_always(j != line_elems.end());
+ U32 tot_count = boost::lexical_cast<U32>(*j);
+ ++j;
+
+ while(j != line_elems.end() && j->empty()) { ++j; } // skip any separator tokens
+ llassert_always(j != line_elems.end());
+ U64 tot_size = boost::lexical_cast<U64>(*j);
+ ++j;
+
+ while(j != line_elems.end() && j->empty()) { ++j; } // skip any separator tokens
+ llassert_always(j != line_elems.end());
+ ++j; // skip the '@'
+
+ mLines.push_back(line(live_count, live_size, tot_count, tot_size));
+ line & current_line = mLines.back();
+
+ for(; j != line_elems.end(); ++j)
+ {
+ if(!j->empty()) {
+ U32 marker = boost::lexical_cast<U32>(*j);
+ current_line.mTrace.push_back(marker);
+ }
+ }
+ }
+
+ // *TODO - parse MAPPED_LIBRARIES section here if we're ever interested in it
+}
+
+void LLAllocatorHeapProfile::dump(std::ostream & out) const
+{
+ lines_t::const_iterator i;
+ for(i = mLines.begin(); i != mLines.end(); ++i)
+ {
+ out << i->mLiveCount << ": " << i->mLiveSize << '[' << i->mTotalCount << ": " << i->mTotalSize << "] @";
+
+ stack_trace::const_iterator j;
+ for(j = i->mTrace.begin(); j != i->mTrace.end(); ++j)
+ {
+ out << ' ' << *j;
+ }
+ out << '\n';
+ }
+ out.flush();
+}
+
diff --git a/indra/llcommon/llallocator_heap_profile.h b/indra/llcommon/llallocator_heap_profile.h
new file mode 100644
index 0000000000..19758df544
--- /dev/null
+++ b/indra/llcommon/llallocator_heap_profile.h
@@ -0,0 +1,77 @@
+/**
+ * @file llallocator_heap_profile.h
+ * @brief Declaration of the parser for tcmalloc heap profile data.
+ * @author Brad Kittenbrink
+ *
+ * $LicenseInfo:firstyear=2009&license=viewergpl$
+ *
+ * Copyright (c) 2009-2009, Linden Research, Inc.
+ *
+ * Second Life Viewer Source Code
+ * The source code in this file ("Source Code") is provided by Linden Lab
+ * to you under the terms of the GNU General Public License, version 2.0
+ * ("GPL"), unless you have obtained a separate licensing agreement
+ * ("Other License"), formally executed by you and Linden Lab. Terms of
+ * the GPL can be found in doc/GPL-license.txt in this distribution, or
+ * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
+ *
+ * There are special exceptions to the terms and conditions of the GPL as
+ * it is applied to this Source Code. View the full text of the exception
+ * in the file doc/FLOSS-exception.txt in this software distribution, or
+ * online at
+ * http://secondlifegrid.net/programs/open_source/licensing/flossexception
+ *
+ * By copying, modifying or distributing this software, you acknowledge
+ * that you have read and understood your obligations described above,
+ * and agree to abide by those obligations.
+ *
+ * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+ * COMPLETENESS OR PERFORMANCE.
+ * $/LicenseInfo$
+ */
+
+#ifndef LL_LLALLOCATOR_HEAP_PROFILE_H
+#define LL_LLALLOCATOR_HEAP_PROFILE_H
+
+#include "stdtypes.h"
+
+#include <map>
+#include <vector>
+
+class LLAllocatorHeapProfile
+{
+public:
+ typedef int stack_marker;
+
+ typedef std::vector<stack_marker> stack_trace;
+
+ struct line {
+ line(U32 live_count, U64 live_size, U32 tot_count, U64 tot_size) :
+ mLiveSize(live_size),
+ mTotalSize(tot_size),
+ mLiveCount(live_count),
+ mTotalCount(tot_count)
+ {
+ }
+ U64 mLiveSize, mTotalSize;
+ U32 mLiveCount, mTotalCount;
+ stack_trace mTrace;
+ };
+
+ typedef std::vector<line> lines_t;
+
+ LLAllocatorHeapProfile()
+ {
+ }
+
+ void parse(std::string const & prof_text);
+
+ void dump(std::ostream & out) const;
+
+public:
+ lines_t mLines;
+};
+
+
+#endif // LL_LLALLOCATOR_HEAP_PROFILE_H
diff --git a/indra/llcommon/llapp.h b/indra/llcommon/llapp.h
index cc60ba0b80..e32a293f1c 100644
--- a/indra/llcommon/llapp.h
+++ b/indra/llcommon/llapp.h
@@ -37,6 +37,7 @@
#include "llapr.h"
#include "llrun.h"
#include "llsd.h"
+#include "lloptioninterface.h"
// Forward declarations
class LLErrorThread;
@@ -61,7 +62,7 @@ public:
};
#endif
-class LLApp
+class LLApp : public LLOptionInterface
{
friend class LLErrorThread;
public:
@@ -110,7 +111,7 @@ public:
* @param name The name of the option.
* @return Returns the option data.
*/
- LLSD getOption(const std::string& name) const;
+ virtual LLSD getOption(const std::string& name) const;
/**
* @brief Parse command line options and insert them into
diff --git a/indra/llcommon/llassettype.cpp b/indra/llcommon/llassettype.cpp
index b852e4c00f..6d4043b8e0 100644
--- a/indra/llcommon/llassettype.cpp
+++ b/indra/llcommon/llassettype.cpp
@@ -35,6 +35,7 @@
#include "llassettype.h"
#include "lldictionary.h"
#include "llmemory.h"
+#include "llsingleton.h"
///----------------------------------------------------------------------------
/// Class LLAssetType
@@ -100,7 +101,7 @@ LLAssetDictionary::LLAssetDictionary()
addEntry(LLAssetType::AT_IMAGE_TGA, new AssetEntry("IMAGE_TGA", "img_tga", "targa image", "Uncompressed Images", DAD_NONE, FALSE, TRUE));
addEntry(LLAssetType::AT_IMAGE_JPEG, new AssetEntry("IMAGE_JPEG", "jpeg", "jpeg image", "Uncompressed Images", DAD_NONE, FALSE, TRUE));
addEntry(LLAssetType::AT_ANIMATION, new AssetEntry("ANIMATION", "animatn", "animation", "Animations", DAD_ANIMATION, FALSE, TRUE));
- addEntry(LLAssetType::AT_GESTURE, new AssetEntry("GESTURE", "gesture", "gesture", "Gestures", DAD_GESTURE, FALSE, TRUE));
+ addEntry(LLAssetType::AT_GESTURE, new AssetEntry("GESTURE", "gesture", "gesture", "Gestures", DAD_GESTURE, TRUE, TRUE));
addEntry(LLAssetType::AT_SIMSTATE, new AssetEntry("SIMSTATE", "simstate", "simstate", "New Folder", DAD_NONE, FALSE, TRUE));
addEntry(LLAssetType::AT_FAVORITE, new AssetEntry("FAVORITE", "favorite", "favorite", "favorite", DAD_NONE, FALSE, TRUE));
@@ -115,7 +116,7 @@ LLAssetDictionary::LLAssetDictionary()
}
addEntry(LLAssetType::AT_CURRENT_OUTFIT, new AssetEntry("CURRENT", "current", "current outfit", "Current Outfit", DAD_CATEGORY, FALSE, TRUE));
- addEntry(LLAssetType::AT_OUTFIT, new AssetEntry("OUTFIT", "outfit", "outfit", "Outfit", DAD_CATEGORY, TRUE, FALSE));
+ addEntry(LLAssetType::AT_OUTFIT, new AssetEntry("OUTFIT", "outfit", "outfit", "New Outfit", DAD_CATEGORY, TRUE, FALSE));
addEntry(LLAssetType::AT_MY_OUTFITS, new AssetEntry("MY_OUTFITS", "my_otfts", "my outfits", "My Outfits", DAD_CATEGORY, FALSE, TRUE));
addEntry(LLAssetType::AT_NONE, new AssetEntry("NONE", "-1", NULL, "New Folder", DAD_NONE, FALSE, FALSE));
@@ -281,6 +282,15 @@ bool LLAssetType::lookupIsProtectedCategoryType(EType asset_type)
return true;
}
+// static
+bool LLAssetType::lookupIsEnsembleCategoryType(EType asset_type)
+{
+ return (asset_type >= AT_FOLDER_ENSEMBLE_START &&
+ asset_type <= AT_FOLDER_ENSEMBLE_END);
+ }
+ return true;
+}
+
// static. Generate a good default description
void LLAssetType::generateDescriptionFor(LLAssetType::EType asset_type,
diff --git a/indra/llcommon/llassettype.h b/indra/llcommon/llassettype.h
index 5c30c8354f..880b7a19b5 100644
--- a/indra/llcommon/llassettype.h
+++ b/indra/llcommon/llassettype.h
@@ -187,6 +187,7 @@ public:
static const char* lookupCategoryName(EType asset_type);
static bool lookupIsProtectedCategoryType(EType asset_type);
+ static bool lookupIsEnsembleCategoryType(EType asset_type);
/* TODO: Change return types from "const char *" to "const std::string &".
This is fairly straightforward, but requires changing some calls to use .c_str().
diff --git a/indra/llcommon/llboost.h b/indra/llcommon/llboost.h
index 4df9dbf3bd..c2bde3a097 100644
--- a/indra/llcommon/llboost.h
+++ b/indra/llcommon/llboost.h
@@ -46,4 +46,19 @@
*/
typedef boost::tokenizer<boost::char_separator<char> > boost_tokenizer;
+// Useful combiner for boost signals that return a bool (e.g. validation)
+// returns false if any of the callbacks return false
+struct boost_boolean_combiner
+{
+ typedef bool result_type;
+ template<typename InputIterator>
+ bool operator()(InputIterator first, InputIterator last) const
+ {
+ bool res = true;
+ while (first != last)
+ res &= *first++;
+ return res;
+ }
+};
+
#endif // LL_LLBOOST_H
diff --git a/indra/llcommon/llcommon.cpp b/indra/llcommon/llcommon.cpp
index 2cbb71855f..36a0018995 100644
--- a/indra/llcommon/llcommon.cpp
+++ b/indra/llcommon/llcommon.cpp
@@ -32,6 +32,8 @@
#include "linden_common.h"
#include "llcommon.h"
+
+#include "llmemory.h"
#include "llthread.h"
//static
diff --git a/indra/llcommon/llcommon.h b/indra/llcommon/llcommon.h
index 5f77988336..a1808e8a6c 100644
--- a/indra/llcommon/llcommon.h
+++ b/indra/llcommon/llcommon.h
@@ -32,9 +32,8 @@
#ifndef LL_COMMON_H
#define LL_COMMON_H
-#include "llmemory.h"
+// *TODO: remove these?
#include "llapr.h"
-// #include "llframecallbackmanager.h"
#include "lltimer.h"
#include "llfile.h"
diff --git a/indra/llcommon/lldate.cpp b/indra/llcommon/lldate.cpp
index 41a3af398f..7bc9e16bc9 100644
--- a/indra/llcommon/lldate.cpp
+++ b/indra/llcommon/lldate.cpp
@@ -38,10 +38,13 @@
#include "apr_time.h"
#include <time.h>
+#include <locale>
+#include <string>
#include <iomanip>
#include <sstream>
#include "lltimer.h"
+#include "llstring.h"
static const F64 DATE_EPOCH = 0.0;
@@ -88,45 +91,36 @@ std::string LLDate::asString() const
// is one of the standards used and the prefered format
std::string LLDate::asRFC1123() const
{
- std::ostringstream stream;
- toHTTPDateStream(stream);
- return stream.str();
+ return toHTTPDateString (std::string ("%A, %d %b %Y %H:%M:%S GMT"));
}
-void LLDate::toHTTPDateStream(std::ostream& s) const
+std::string LLDate::toHTTPDateString (std::string fmt) const
{
- // http://apr.apache.org/docs/apr/0.9/group__apr__time.html
- apr_time_t time = (apr_time_t)(mSecondsSinceEpoch * LL_APR_USEC_PER_SEC);
+ std::ostringstream stream;
+ time_t locSeconds = (time_t) mSecondsSinceEpoch;
+ struct tm * gmt = gmtime (&locSeconds);
- apr_time_exp_t exp_time ; //Apache time module
+ stream.imbue (std::locale(LLStringUtil::getLocale().c_str()));
+ toHTTPDateStream (stream, gmt, fmt);
+ return stream.str();
+}
- if (apr_time_exp_gmt(&exp_time, time) != APR_SUCCESS)
- {
- // Return Epoch UTC date
- s << "Thursday, 01 Jan 1970 00:00:00 GMT" ;
- return;
- }
+std::string LLDate::toHTTPDateString (tm * gmt, std::string fmt)
+{
+ std::ostringstream stream;
+ stream.imbue (std::locale(LLStringUtil::getLocale().c_str()));
+ toHTTPDateStream (stream, gmt, fmt);
+ return stream.str();
+}
- s << std::dec << std::setfill('0');
-#if( LL_WINDOWS || __GNUC__ > 2)
- s << std::right ;
-#else
- s.setf(ios::right);
-#endif
- std::string day = weekdays[exp_time.tm_wday];
- std::string month = months[exp_time.tm_mon];
-
- s << std::setw(day.length()) << (day)
- << ", " << std::setw(2) << (exp_time.tm_mday)
- << ' ' << std::setw(month.length()) << (month)
- << ' ' << std::setw(4) << (exp_time.tm_year + 1900)
- << ' ' << std::setw(2) << (exp_time.tm_hour)
- << ':' << std::setw(2) << (exp_time.tm_min)
- << ':' << std::setw(2) << (exp_time.tm_sec)
- << " GMT";
+void LLDate::toHTTPDateStream(std::ostream& s, tm * gmt, std::string fmt)
+{
+ using namespace std;
- // RFC 1123 date does not use microseconds
- //llinfos << "Date in RFC 1123 format is " << s << llendl;
+ const char * pBeg = fmt.c_str();
+ const char * pEnd = pBeg + fmt.length();
+ const time_put<char>& tp = use_facet<time_put<char> >(s.getloc());
+ tp.put (s, s, s.fill(), gmt, pBeg, pEnd);
}
void LLDate::toStream(std::ostream& s) const
diff --git a/indra/llcommon/lldate.h b/indra/llcommon/lldate.h
index 7cc9c8aceb..23d3b900f8 100644
--- a/indra/llcommon/lldate.h
+++ b/indra/llcommon/lldate.h
@@ -84,7 +84,9 @@ public:
std::string asString() const;
std::string asRFC1123() const;
void toStream(std::ostream&) const;
- void toHTTPDateStream(std::ostream&) const;
+ std::string toHTTPDateString (std::string fmt) const;
+ static std::string toHTTPDateString (tm * gmt, std::string fmt);
+ static void toHTTPDateStream(std::ostream&, tm *, std::string);
/**
* @brief Set the date from an ISO-8601 string.
*
diff --git a/indra/llcommon/lldeleteutils.h b/indra/llcommon/lldeleteutils.h
new file mode 100644
index 0000000000..d6a0945e46
--- /dev/null
+++ b/indra/llcommon/lldeleteutils.h
@@ -0,0 +1,53 @@
+/**
+ * @file lldeleteutils.h
+ * @brief Utility functions to simplify some common pointer-munging idioms.
+ *
+ * $LicenseInfo:firstyear=2009&license=viewergpl$
+ *
+ * Copyright (c) 2009, Linden Research, Inc.
+ *
+ * Second Life Viewer Source Code
+ * The source code in this file ("Source Code") is provided by Linden Lab
+ * to you under the terms of the GNU General Public License, version 2.0
+ * ("GPL"), unless you have obtained a separate licensing agreement
+ * ("Other License"), formally executed by you and Linden Lab. Terms of
+ * the GPL can be found in doc/GPL-license.txt in this distribution, or
+ * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
+ *
+ * There are special exceptions to the terms and conditions of the GPL as
+ * it is applied to this Source Code. View the full text of the exception
+ * in the file doc/FLOSS-exception.txt in this software distribution, or
+ * online at
+ * http://secondlifegrid.net/programs/open_source/licensing/flossexception
+ *
+ * By copying, modifying or distributing this software, you acknowledge
+ * that you have read and understood your obligations described above,
+ * and agree to abide by those obligations.
+ *
+ * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+ * COMPLETENESS OR PERFORMANCE.
+ * $/LicenseInfo$
+ */
+#ifndef LL_DELETE_UTILS_H
+#define LL_DELETE_UTILS_H
+
+// Simple utility functions to eventually replace the common 2-line
+// idiom scattered throughout the viewer codebase. Note that where
+// possible we would rather be using smart pointers of some sort.
+
+template <class T>
+inline void deleteAndClear(T*& ptr)
+{
+ delete ptr;
+ ptr = NULL;
+}
+
+template <class T>
+inline void deleteAndClearArray(T*& array_ptr)
+{
+ delete[] array_ptr;
+ array_ptr = NULL;
+}
+
+#endif
diff --git a/indra/llcommon/lldependencies.h b/indra/llcommon/lldependencies.h
index bd4bd7c96a..82f53c6e17 100644
--- a/indra/llcommon/lldependencies.h
+++ b/indra/llcommon/lldependencies.h
@@ -581,6 +581,8 @@ public:
return sorted_range(begin, end);
}
+ using LLDependenciesBase::describe; // unhide virtual std::string describe(bool full=true) const;
+
/// Override base-class describe() with actual implementation
virtual std::ostream& describe(std::ostream& out, bool full=true) const
{
@@ -597,6 +599,7 @@ public:
return out;
}
+
/// describe() helper: report a DepNodeEntry
static std::ostream& describe(std::ostream& out, std::string& sep,
const DepNodeMapEntry& entry, bool full)
diff --git a/indra/llcommon/lldoubledispatch.h b/indra/llcommon/lldoubledispatch.h
new file mode 100755
index 0000000000..60678d44fb
--- /dev/null
+++ b/indra/llcommon/lldoubledispatch.h
@@ -0,0 +1,332 @@
+/**
+ * @file lldoubledispatch.h
+ * @author Nat Goodspeed
+ * @date 2008-11-11
+ * @brief function calls virtual on more than one parameter
+ *
+ * $LicenseInfo:firstyear=2008&license=viewergpl$
+ *
+ * Copyright (c) 2008-2009, Linden Research, Inc.
+ *
+ * Second Life Viewer Source Code
+ * The source code in this file ("Source Code") is provided by Linden Lab
+ * to you under the terms of the GNU General Public License, version 2.0
+ * ("GPL"), unless you have obtained a separate licensing agreement
+ * ("Other License"), formally executed by you and Linden Lab. Terms of
+ * the GPL can be found in doc/GPL-license.txt in this distribution, or
+ * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
+ *
+ * There are special exceptions to the terms and conditions of the GPL as
+ * it is applied to this Source Code. View the full text of the exception
+ * in the file doc/FLOSS-exception.txt in this software distribution, or
+ * online at
+ * http://secondlifegrid.net/programs/open_source/licensing/flossexception
+ *
+ * By copying, modifying or distributing this software, you acknowledge
+ * that you have read and understood your obligations described above,
+ * and agree to abide by those obligations.
+ *
+ * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+ * COMPLETENESS OR PERFORMANCE.
+ * $/LicenseInfo$
+ */
+
+#if ! defined(LL_LLDOUBLEDISPATCH_H)
+#define LL_LLDOUBLEDISPATCH_H
+
+#include <list>
+#include <boost/shared_ptr.hpp>
+#include <boost/function.hpp>
+#include <boost/bind.hpp>
+#include <boost/ref.hpp>
+
+/**
+ * This class supports function calls which are virtual on the dynamic type of
+ * more than one parameter. Specifically, we address a limited but useful
+ * subset of that problem: function calls which accept two parameters, and
+ * select which particular function to call depending on the dynamic type of
+ * both.
+ *
+ * Scott Meyers, in More Effective C++ (Item 31), talks about some of the perils
+ * and pitfalls lurking down this pathway. He discusses and dismisses the
+ * straightforward approaches of using single-dispatch virtual functions twice,
+ * and of using a family of single-dispatch virtual functions which each examine
+ * RTTI for their other parameter. He advocates using a registry in which you
+ * look up the actual types of both parameters (he uses the classes' string names,
+ * via typeid(param).name()) to obtain a pointer to a free (non-member) function
+ * that will accept this pair of parameters.
+ *
+ * He does point out that his approach doesn't handle inheritance. If you have a
+ * registry entry for SpaceShip, and you have in hand a MilitaryShip (subclass of
+ * SpaceShip) and an Asteroid, you'd like to call the function appropriate for
+ * SpaceShips and Asteroids -- but alas, his lookup fails because the class name
+ * for your MilitaryShip subclass isn't in the registry.
+ *
+ * This class extends his idea to build a registry whose entries can examine the
+ * dynamic type of the parameter in a more flexible way -- using dynamic_cast<>
+ * -- thereby supporting inheritance relationships.
+ *
+ * Of course we must allow for the ambiguity this permits. We choose to use a
+ * sequence container rather than a map, and require that the client code
+ * specify the order in which dispatch-table entries should be searched. The
+ * result resembles the semantics of the catch clauses for a try/catch block:
+ * you must code catch clauses in decreasing order of specificity, because if
+ * you catch ErrorBaseClass before you catch ErrorSubclass, then any
+ * ErrorSubclass exceptions thrown by the protected code will always match
+ * ErrorBaseClass, and you will never reach your catch(ErrorSubclass) clause.
+ *
+ * So, in a similar way, if you have a specific routine to process
+ * MilitaryShip and Asteroid, you'd better place that in the table @em before
+ * your more general routine that processes SpaceShip and Asteroid, or else
+ * the MilitaryShip variant will never be called.
+ *
+ * @todo This implementation doesn't attempt to deal with
+ * <tt>const</tt>-correctness of arguments. Our container stores templated
+ * objects into which the specific parameter types have been "frozen." But to
+ * store all these in the same container, they are all instances of a base
+ * class with a virtual invocation method. Naturally the base-class virtual
+ * method definition cannot know the <tt>const</tt>-ness of the particular
+ * types with which its template subclass is instantiated.
+ *
+ * One is tempted to suggest four different virtual methods, one for each
+ * combination of @c const and non-<tt>const</tt> arguments. Then the client
+ * will select the particular virtual method that best fits the
+ * <tt>const</tt>-ness of the arguments in hand. The trouble with that idea is
+ * that in order to instantiate the subclass instance, we must compile all
+ * four of its virtual method overrides, which means we must be prepared to
+ * pass all four combinations of @c const and non-<tt>const</tt> arguments to
+ * the registered callable. That only works when the registered callable
+ * accepts both parameters as @c const.
+ *
+ * Of course the virtual method overrides could use @c const_cast to force
+ * them to compile correctly regardless of the <tt>const</tt>-ness of the
+ * registered callable's parameter declarations. But if we're going to force
+ * the issue with @c const_cast anyway, why bother with the four different
+ * virtual methods? Why not just require canonical parameter
+ * <tt>const</tt>-ness for any callables used with this mechanism?
+ *
+ * We therefore require that your callable accept both params as
+ * non-<tt>const</tt>. (This is more general than @c const: you can perform @c
+ * const operations on a non-<tt>const</tt> parameter, but you can't perform
+ * non-<tt>const</tt> operations on a @c const parameter.)
+ *
+ * For ease of use, though, our invocation method accepts both params as @c
+ * const. Again, you can pass a non-<tt>const</tt> object to a @c const param,
+ * but not the other way around. We take care of the @c const_cast for you.
+ */
+// LLDoubleDispatch is a template because we have to assume that all parameter
+// types are subclasses of some common base class -- but we don't have to
+// impose that base class on client code. Instead, we let IT tell US the
+// common parameter base class.
+template<class ReturnType, class ParamBaseType>
+class LLDoubleDispatch
+{
+ typedef LLDoubleDispatch<ReturnType, ParamBaseType> self_type;
+
+public:
+ LLDoubleDispatch() {}
+
+ /**
+ * Call the first matching entry. If there's no registered Functor
+ * appropriate for this pair of parameter types, this call will do
+ * @em nothing! (If you want notification in this case, simply add a new
+ * Functor for (ParamBaseType&, ParamBaseType&) at the end of the table.
+ * The two base-class entries should match anything that isn't matched by
+ * any more specific entry.)
+ *
+ * See note in class documentation about <tt>const</tt>-correctness.
+ */
+ inline
+ ReturnType operator()(const ParamBaseType& param1, const ParamBaseType& param2) const;
+
+ // Borrow a trick from Alexandrescu: use a Type class to "wrap" a type
+ // for purposes of passing the type itself into a template method.
+ template<typename T>
+ struct Type {};
+
+ /**
+ * Add a new Entry for a given @a Functor. As mentioned above, the order
+ * in which you add these entries is very important.
+ *
+ * If you want symmetrical entries -- that is, if a B and an A can call
+ * the same Functor as an A and a B -- then pass @c true for the last
+ * parameter, and we'll add a (B, A) entry as well as an (A, B) entry. But
+ * your @a Functor can still be written to expect exactly the pair of types
+ * you've explicitly specified, because the Entry with the reversed params
+ * will call a special thunk that swaps params before calling your @a
+ * Functor.
+ */
+ template<typename Type1, typename Type2, class Functor>
+ void add(const Type<Type1>& t1, const Type<Type2>& t2, Functor func, bool symmetrical=false)
+ {
+ insert(t1, t2, func);
+ if (symmetrical)
+ {
+ // Use boost::bind() to construct a param-swapping thunk. Don't
+ // forget to reverse the parameters too.
+ insert(t2, t1, boost::bind(func, _2, _1));
+ }
+ }
+
+ /**
+ * Add a new Entry for a given @a Functor, explicitly passing instances of
+ * the Functor's leaf param types to help us figure out where to insert.
+ * Because it can use RTTI, this add() method isn't order-sensitive like
+ * the other one.
+ *
+ * If you want symmetrical entries -- that is, if a B and an A can call
+ * the same Functor as an A and a B -- then pass @c true for the last
+ * parameter, and we'll add a (B, A) entry as well as an (A, B) entry. But
+ * your @a Functor can still be written to expect exactly the pair of types
+ * you've explicitly specified, because the Entry with the reversed params
+ * will call a special thunk that swaps params before calling your @a
+ * Functor.
+ */
+ template <typename Type1, typename Type2, class Functor>
+ void add(const Type1& prototype1, const Type2& prototype2, Functor func, bool symmetrical=false)
+ {
+ // Because we expect our caller to pass leaf param types, we can just
+ // perform an ordinary search to find the first matching iterator. If
+ // we find an existing Entry that matches both params, either the
+ // param types are the same, or the existing Entry uses the base class
+ // for one or both params, and the new Entry must precede that. Assume
+ // our client won't register two callables with exactly the SAME set
+ // of types; in that case we'll insert the new one before any earlier
+ // ones, meaning the last one registered will "win." Note that if
+ // find() doesn't find any matching Entry, it will return end(),
+ // meaning the new Entry will be last, which is fine.
+ typename DispatchTable::iterator insertion = find(prototype1, prototype2);
+ insert(Type<Type1>(), Type<Type2>(), func, insertion);
+ if (symmetrical)
+ {
+ insert(Type<Type2>(), Type<Type1>(), boost::bind(func, _2, _1), insertion);
+ }
+ }
+
+ /**
+ * Add a new Entry for a given @a Functor, specifying the Functor's leaf
+ * param types as explicit template arguments. This will instantiate
+ * temporary objects of each of these types, which requires that they have
+ * a lightweight default constructor.
+ *
+ * If you want symmetrical entries -- that is, if a B and an A can call
+ * the same Functor as an A and a B -- then pass @c true for the last
+ * parameter, and we'll add a (B, A) entry as well as an (A, B) entry. But
+ * your @a Functor can still be written to expect exactly the pair of types
+ * you've explicitly specified, because the Entry with the reversed params
+ * will call a special thunk that swaps params before calling your @a
+ * Functor.
+ */
+ template <typename Type1, typename Type2, class Functor>
+ void add(Functor func, bool symmetrical=false)
+ {
+ // This is a convenience wrapper for the add() variant taking explicit
+ // instances.
+ add(Type1(), Type2(), func, symmetrical);
+ }
+
+private:
+ /// This is the base class for each entry in our dispatch table.
+ struct EntryBase
+ {
+ virtual ~EntryBase() {}
+ virtual bool matches(const ParamBaseType& param1, const ParamBaseType& param2) const = 0;
+ virtual ReturnType operator()(ParamBaseType& param1, ParamBaseType& param2) const = 0;
+ };
+
+ /// Here's the template subclass that actually creates each entry.
+ template<typename Type1, typename Type2, class Functor>
+ class Entry: public EntryBase
+ {
+ public:
+ Entry(Functor func): mFunc(func) {}
+ /// Is this entry appropriate for these arguments?
+ virtual bool matches(const ParamBaseType& param1, const ParamBaseType& param2) const
+ {
+ return (dynamic_cast<const Type1*>(&param1) &&
+ dynamic_cast<const Type2*>(&param2));
+ }
+ /// invocation
+ virtual ReturnType operator()(ParamBaseType& param1, ParamBaseType& param2) const
+ {
+ // We perform the downcast so callable can accept leaf param
+ // types, instead of accepting ParamBaseType and downcasting
+ // explicitly.
+ return mFunc(dynamic_cast<Type1&>(param1), dynamic_cast<Type2&>(param2));
+ }
+ private:
+ /// Bind whatever function or function object the instantiator passed.
+ Functor mFunc;
+ };
+
+ /// shared_ptr manages Entry lifespan for us
+ typedef boost::shared_ptr<EntryBase> EntryPtr;
+ /// use a @c list to make it easy to insert
+ typedef std::list<EntryPtr> DispatchTable;
+ DispatchTable mDispatch;
+
+ /// Look up the location of the first matching entry.
+ typename DispatchTable::const_iterator find(const ParamBaseType& param1, const ParamBaseType& param2) const
+ {
+ // We assert that it's safe to call the non-const find() method on a
+ // const LLDoubleDispatch instance. Cast away the const-ness of 'this'.
+ return const_cast<self_type*>(this)->find(param1, param2);
+ }
+
+ /// Look up the location of the first matching entry.
+ typename DispatchTable::iterator find(const ParamBaseType& param1, const ParamBaseType& param2)
+ {
+ return std::find_if(mDispatch.begin(), mDispatch.end(),
+ boost::bind(&EntryBase::matches, _1,
+ boost::ref(param1), boost::ref(param2)));
+ }
+
+ /// Look up the first matching entry.
+ EntryPtr lookup(const ParamBaseType& param1, const ParamBaseType& param2) const
+ {
+ typename DispatchTable::const_iterator found = find(param1, param2);
+ if (found != mDispatch.end())
+ {
+ // Dereferencing the list iterator gets us an EntryPtr
+ return *found;
+ }
+ // not found
+ return EntryPtr();
+ }
+
+ // Break out the actual insert operation so the public add() template
+ // function can avoid calling itself recursively. See add() comments.
+ template<typename Type1, typename Type2, class Functor>
+ void insert(const Type<Type1>& param1, const Type<Type2>& param2, Functor func)
+ {
+ insert(param1, param2, func, mDispatch.end());
+ }
+
+ // Break out the actual insert operation so the public add() template
+ // function can avoid calling itself recursively. See add() comments.
+ template<typename Type1, typename Type2, class Functor>
+ void insert(const Type<Type1>&, const Type<Type2>&, Functor func,
+ typename DispatchTable::iterator where)
+ {
+ mDispatch.insert(where, EntryPtr(new Entry<Type1, Type2, Functor>(func)));
+ }
+
+ /// Don't implement the copy ctor. Everyone will be happier if the
+ /// LLDoubleDispatch object isn't copied.
+ LLDoubleDispatch(const LLDoubleDispatch& src);
+};
+
+template <class ReturnType, class ParamBaseType>
+ReturnType LLDoubleDispatch<ReturnType, ParamBaseType>::operator()(const ParamBaseType& param1,
+ const ParamBaseType& param2) const
+{
+ EntryPtr found = lookup(param1, param2);
+ if (found.get() == 0)
+ return ReturnType(); // bogus return value
+
+ // otherwise, call the Functor we found
+ return (*found)(const_cast<ParamBaseType&>(param1), const_cast<ParamBaseType&>(param2));
+}
+
+#endif /* ! defined(LL_LLDOUBLEDISPATCH_H) */
diff --git a/indra/llcommon/llerror.cpp b/indra/llcommon/llerror.cpp
index 8102eddb18..77c0c2294a 100644
--- a/indra/llcommon/llerror.cpp
+++ b/indra/llcommon/llerror.cpp
@@ -53,12 +53,11 @@
#include "llapp.h"
#include "llapr.h"
#include "llfile.h"
-#include "llfixedbuffer.h"
#include "lllivefile.h"
#include "llsd.h"
#include "llsdserialize.h"
#include "llstl.h"
-
+#include "lltimer.h"
namespace {
#if !LL_WINDOWS
@@ -192,16 +191,16 @@ namespace {
class RecordToFixedBuffer : public LLError::Recorder
{
public:
- RecordToFixedBuffer(LLFixedBuffer& buffer) : mBuffer(buffer) { }
+ RecordToFixedBuffer(LLLineBuffer* buffer) : mBuffer(buffer) { }
virtual void recordMessage(LLError::ELevel level,
- const std::string& message)
+ const std::string& message)
{
- mBuffer.addLine(message);
+ mBuffer->addLine(message);
}
private:
- LLFixedBuffer& mBuffer;
+ LLLineBuffer* mBuffer;
};
#if LL_WINDOWS
@@ -209,7 +208,7 @@ namespace {
{
public:
virtual void recordMessage(LLError::ELevel level,
- const std::string& message)
+ const std::string& message)
{
llutf16string utf16str =
wstring_to_utf16str(utf8str_to_wstring(message));
@@ -792,7 +791,7 @@ namespace LLError
addRecorder(f);
}
- void logToFixedBuffer(LLFixedBuffer* fixedBuffer)
+ void logToFixedBuffer(LLLineBuffer* fixedBuffer)
{
LLError::Settings& s = LLError::Settings::get();
@@ -805,7 +804,7 @@ namespace LLError
return;
}
- s.fixedBufferRecorder = new RecordToFixedBuffer(*fixedBuffer);
+ s.fixedBufferRecorder = new RecordToFixedBuffer(fixedBuffer);
addRecorder(s.fixedBufferRecorder);
}
diff --git a/indra/llcommon/llerrorcontrol.h b/indra/llcommon/llerrorcontrol.h
index c9424f8a5e..fab0a1ef9f 100644
--- a/indra/llcommon/llerrorcontrol.h
+++ b/indra/llcommon/llerrorcontrol.h
@@ -38,7 +38,6 @@
#include "boost/function.hpp"
#include <string>
-class LLFixedBuffer;
class LLSD;
/*
@@ -49,6 +48,18 @@ class LLSD;
These implementations are in llerror.cpp.
*/
+// Line buffer interface
+class LLLineBuffer
+{
+public:
+ LLLineBuffer() {};
+ virtual ~LLLineBuffer() {};
+
+ virtual void clear() = 0; // Clear the buffer, and reset it.
+
+ virtual void addLine(const std::string& utf8line) = 0;
+};
+
namespace LLError
{
@@ -73,6 +84,7 @@ namespace LLError
void setFunctionLevel(const std::string& function_name, LLError::ELevel);
void setClassLevel(const std::string& class_name, LLError::ELevel);
void setFileLevel(const std::string& file_name, LLError::ELevel);
+ void setTagLevel(const std::string& file_name, LLError::ELevel);
void configure(const LLSD&);
// the LLSD can configure all of the settings
@@ -143,7 +155,7 @@ namespace LLError
// each error message is passed to each recorder via recordMessage()
void logToFile(const std::string& filename);
- void logToFixedBuffer(LLFixedBuffer*);
+ void logToFixedBuffer(LLLineBuffer*);
// Utilities to add recorders for logging to a file or a fixed buffer
// A second call to the same function will remove the logger added
// with the first.
diff --git a/indra/llcommon/llerrorthread.cpp b/indra/llcommon/llerrorthread.cpp
index 4c779c58c8..f0e46ae78d 100644
--- a/indra/llcommon/llerrorthread.cpp
+++ b/indra/llcommon/llerrorthread.cpp
@@ -31,7 +31,9 @@
#include "linden_common.h"
#include "llerrorthread.h"
+
#include "llapp.h"
+#include "lltimer.h" // ms_sleep()
LLErrorThread::LLErrorThread()
: LLThread("Error"),
diff --git a/indra/llcommon/llevent.h b/indra/llcommon/llevent.h
index a74ddbd091..2cc8577219 100644
--- a/indra/llcommon/llevent.h
+++ b/indra/llcommon/llevent.h
@@ -35,7 +35,7 @@
#define LL_EVENT_H
#include "llsd.h"
-#include "llmemory.h"
+#include "llpointer.h"
#include "llthread.h"
namespace LLOldEvents
diff --git a/indra/llcommon/llevents.h b/indra/llcommon/llevents.h
index f70d532e4c..240adcdd41 100644
--- a/indra/llcommon/llevents.h
+++ b/indra/llcommon/llevents.h
@@ -22,7 +22,16 @@
#include <list>
#include <deque>
#include <stdexcept>
+#if LL_WINDOWS
+ #pragma warning (push)
+ #pragma warning (disable : 4263) // boost::signals2::expired_slot::what() has const mismatch
+ #pragma warning (disable : 4264)
+#endif
#include <boost/signals2.hpp>
+#if LL_WINDOWS
+ #pragma warning (pop)
+#endif
+
#include <boost/bind.hpp>
#include <boost/shared_ptr.hpp>
#include <boost/enable_shared_from_this.hpp>
@@ -38,7 +47,7 @@
#include <boost/function.hpp>
#include <boost/static_assert.hpp>
#include "llsd.h"
-#include "llmemory.h"
+#include "llsingleton.h"
#include "lldependencies.h"
// override this to allow binding free functions with more parameters
diff --git a/indra/llcommon/llfasttimer.h b/indra/llcommon/llfasttimer.h
index 94b51119e4..0d89353dee 100644
--- a/indra/llcommon/llfasttimer.h
+++ b/indra/llcommon/llfasttimer.h
@@ -30,229 +30,215 @@
* $/LicenseInfo$
*/
-#ifndef LL_LLFASTTIMER_H
-#define LL_LLFASTTIMER_H
+#ifndef LL_FASTTIMER_H
+#define LL_FASTTIMER_H
+
+#include "llinstancetracker.h"
#define FAST_TIMER_ON 1
U64 get_cpu_clock_count();
+class LLMutex;
+
+#include <queue>
+#include "llsd.h"
+
+
class LLFastTimer
{
public:
- enum EFastTimerType
+ // stores a "named" timer instance to be reused via multiple LLFastTimer stack instances
+ class NamedTimer
+ : public LLInstanceTracker<NamedTimer>
{
- // high level
- FTM_FRAME,
- FTM_UPDATE,
- FTM_RENDER,
- FTM_SWAP,
- FTM_CLIENT_COPY,
- FTM_IDLE,
- FTM_SLEEP,
-
- // common messaging components
- FTM_PUMP,
- FTM_CURL,
-
- // common simulation components
- FTM_UPDATE_ANIMATION,
- FTM_UPDATE_TERRAIN,
- FTM_UPDATE_PRIMITIVES,
- FTM_UPDATE_PARTICLES,
- FTM_SIMULATE_PARTICLES,
- FTM_UPDATE_SKY,
- FTM_UPDATE_TEXTURES,
- FTM_UPDATE_WLPARAM,
- FTM_UPDATE_WATER,
- FTM_UPDATE_CLOUDS,
- FTM_UPDATE_GRASS,
- FTM_UPDATE_TREE,
- FTM_UPDATE_AVATAR,
-
- // common render components
- FTM_SHADOW_GEOMETRY,
- FTM_SHADOW_RENDER,
- FTM_SHADOW_TERRAIN,
- FTM_SHADOW_AVATAR,
- FTM_SHADOW_SIMPLE,
- FTM_SHADOW_ALPHA,
- FTM_SHADOW_TREE,
-
- FTM_RENDER_GEOMETRY,
- FTM_RENDER_TERRAIN,
- FTM_RENDER_SIMPLE,
- FTM_RENDER_FULLBRIGHT,
- FTM_RENDER_GLOW,
- FTM_RENDER_GRASS,
- FTM_RENDER_INVISIBLE,
- FTM_RENDER_SHINY,
- FTM_RENDER_BUMP,
- FTM_RENDER_TREES,
- FTM_RENDER_CHARACTERS,
- FTM_RENDER_OCCLUSION,
- FTM_RENDER_ALPHA,
- FTM_RENDER_CLOUDS,
- FTM_RENDER_HUD,
- FTM_RENDER_PARTICLES,
- FTM_RENDER_WATER,
- FTM_RENDER_WL_SKY,
- FTM_RENDER_FAKE_VBO_UPDATE,
- FTM_RENDER_TIMER,
- FTM_RENDER_UI,
- FTM_RENDER_BLOOM,
- FTM_RENDER_BLOOM_FBO,
- FTM_RENDER_FONTS,
-
- // newview specific
- FTM_MESSAGES,
- FTM_MOUSEHANDLER,
- FTM_KEYHANDLER,
- FTM_REBUILD,
- FTM_STATESORT,
- FTM_STATESORT_DRAWABLE,
- FTM_STATESORT_POSTSORT,
- FTM_REBUILD_VBO,
- FTM_REBUILD_VOLUME_VB,
- FTM_REBUILD_BRIDGE_VB,
- FTM_REBUILD_HUD_VB,
- FTM_REBUILD_TERRAIN_VB,
- FTM_REBUILD_WATER_VB,
- FTM_REBUILD_TREE_VB,
- FTM_REBUILD_PARTICLE_VB,
- FTM_REBUILD_CLOUD_VB,
- FTM_REBUILD_GRASS_VB,
- FTM_REBUILD_NONE_VB,
- FTM_REBUILD_OCCLUSION_VB,
- FTM_POOLS,
- FTM_POOLRENDER,
- FTM_IDLE_CB,
- FTM_WORLD_UPDATE,
- FTM_UPDATE_MOVE,
- FTM_OCTREE_BALANCE,
- FTM_UPDATE_LIGHTS,
- FTM_CULL,
- FTM_CULL_REBOUND,
- FTM_FRUSTUM_CULL,
- FTM_GEO_UPDATE,
- FTM_GEO_RESERVE,
- FTM_GEO_LIGHT,
- FTM_GEO_SHADOW,
- FTM_GEO_SKY,
- FTM_GEN_VOLUME,
- FTM_GEN_TRIANGLES,
- FTM_GEN_FLEX,
- FTM_AUDIO_UPDATE,
- FTM_RESET_DRAWORDER,
- FTM_OBJECTLIST_UPDATE,
- FTM_AVATAR_UPDATE,
- FTM_JOINT_UPDATE,
- FTM_ATTACHMENT_UPDATE,
- FTM_LOD_UPDATE,
- FTM_REGION_UPDATE,
- FTM_CLEANUP,
- FTM_NETWORK,
- FTM_IDLE_NETWORK,
- FTM_CREATE_OBJECT,
- FTM_LOAD_AVATAR,
- FTM_PROCESS_MESSAGES,
- FTM_PROCESS_OBJECTS,
- FTM_PROCESS_IMAGES,
- FTM_IMAGE_UPDATE,
- FTM_IMAGE_CREATE,
- FTM_IMAGE_DECODE,
- FTM_IMAGE_MARK_DIRTY,
- FTM_PIPELINE,
- FTM_VFILE_WAIT,
- FTM_FLEXIBLE_UPDATE,
- FTM_OCCLUSION_READBACK,
- FTM_HUD_EFFECTS,
- FTM_HUD_UPDATE,
- FTM_INVENTORY,
- FTM_AUTO_SELECT,
- FTM_ARRANGE,
- FTM_FILTER,
- FTM_REFRESH,
- FTM_SORT,
- FTM_PICK,
-
- // Temp
- FTM_TEMP1,
- FTM_TEMP2,
- FTM_TEMP3,
- FTM_TEMP4,
- FTM_TEMP5,
- FTM_TEMP6,
- FTM_TEMP7,
- FTM_TEMP8,
-
- FTM_OTHER, // Special, used by display code
+ public:
+ ~NamedTimer();
+
+ enum { HISTORY_NUM = 60 };
+
+ const std::string& getName() { return mName; }
+ NamedTimer* getParent() { return mParent; }
+ void setParent(NamedTimer* parent);
+ S32 getDepth();
+ std::string getToolTip(S32 history_index = -1);
+
+ typedef std::vector<NamedTimer*>::const_iterator child_const_iter;
+ child_const_iter beginChildren();
+ child_const_iter endChildren();
+ std::vector<NamedTimer*>& getChildren();
+
+ void setCollapsed(bool collapsed) { mCollapsed = collapsed; }
+ bool getCollapsed() const { return mCollapsed; }
+
+ U64 getCountAverage() const { return mCountAverage; }
+ U64 getCallAverage() const { return mCallAverage; }
+
+ U64 getHistoricalCount(S32 history_index = 0) const;
+ U64 getHistoricalCalls(S32 history_index = 0) const;
+
+ static NamedTimer& getRootNamedTimer();
+
+ struct FrameState
+ {
+ FrameState(NamedTimer* timerp);
+
+ U64 mSelfTimeCounter;
+ U64 mLastStartTime; // most recent time when this timer was started
+ U32 mCalls;
+ FrameState* mParent; // info for caller timer
+ FrameState* mLastCaller; // used to bootstrap tree construction
+ NamedTimer* mTimer;
+ U16 mActiveCount; // number of timers with this ID active on stack
+ bool mMoveUpTree; // needs to be moved up the tree of timers at the end of frame
+ };
+
+ FrameState& getFrameStateFast() const
+ {
+ return (*sTimerInfos)[mFrameStateIndex];
+ }
+
+ S32 getFrameStateIndex() const { return mFrameStateIndex; }
+
+ FrameState& getFrameState() const;
+
+
+ private:
+ friend class LLFastTimer;
+ friend class NamedTimerFactory;
+
+ //
+ // methods
+ //
+ NamedTimer(const std::string& name);
+ // recursive call to gather total time from children
+ static void accumulateTimings();
+
+ // called once per frame by LLFastTimer
+ static void processFrame();
+
+ static void buildHierarchy();
+ static void resetFrame();
+ static void reset();
+
+ typedef std::vector<FrameState> info_list_t;
+ static info_list_t& getFrameStateList();
+ static void createFrameStateList(); // must call before any call to getFrameStateList()
- FTM_NUM_TYPES
+ //
+ // members
+ //
+ S32 mFrameStateIndex;
+
+ std::string mName;
+
+ U64 mTotalTimeCounter;
+
+ U64 mCountAverage;
+ U64 mCallAverage;
+
+ U64* mCountHistory;
+ U64* mCallHistory;
+
+ // tree structure
+ NamedTimer* mParent; // NamedTimer of caller(parent)
+ std::vector<NamedTimer*> mChildren;
+ bool mCollapsed; // don't show children
+ bool mNeedsSorting; // sort children whenever child added
+
+ static info_list_t* sTimerInfos;
};
- enum { FTM_HISTORY_NUM = 60 };
- enum { FTM_MAX_DEPTH = 64 };
-
+
+ // used to statically declare a new named timer
+ class DeclareTimer
+ {
+ public:
+ DeclareTimer(const std::string& name, bool open);
+ DeclareTimer(const std::string& name);
+
+ // convertable to NamedTimer::FrameState for convenient usage of LLFastTimer(declared_timer)
+ operator NamedTimer::FrameState&() { return mNamedTimer.getFrameStateFast(); }
+ private:
+ NamedTimer& mNamedTimer;
+ };
+
+
public:
- static LLFastTimer::EFastTimerType sCurType;
+ enum RootTimerMarker { ROOT };
+
+ static LLMutex* sLogLock;
+ static std::queue<LLSD> sLogQueue;
+ static BOOL sLog;
+ static BOOL sMetricLog;
+
+ LLFastTimer(RootTimerMarker);
- LLFastTimer(EFastTimerType type)
+ LLFastTimer(NamedTimer::FrameState& timer)
+ : mFrameState(&timer)
{
#if FAST_TIMER_ON
- mType = type;
- sCurType = type;
- // These don't get counted, because they use CPU clockticks
- //gTimerBins[gCurTimerBin]++;
- //LLTimer::sNumTimerCalls++;
+ NamedTimer::FrameState* frame_state = mFrameState;
+ frame_state->mLastStartTime = get_cpu_clock_count();
+ mStartSelfTime = frame_state->mLastStartTime;
- U64 cpu_clocks = get_cpu_clock_count();
-
- sStart[sCurDepth] = cpu_clocks;
- sCurDepth++;
+ frame_state->mActiveCount++;
+ frame_state->mCalls++;
+ // keep current parent as long as it is active when we are
+ frame_state->mMoveUpTree |= (frame_state->mParent->mActiveCount == 0);
+
+ mLastTimer = sCurTimer;
+ sCurTimer = this;
#endif
- };
+ }
+
~LLFastTimer()
{
#if FAST_TIMER_ON
- U64 end,delta;
- int i;
-
- // These don't get counted, because they use CPU clockticks
- //gTimerBins[gCurTimerBin]++;
- //LLTimer::sNumTimerCalls++;
- end = get_cpu_clock_count();
-
- sCurDepth--;
- delta = end - sStart[sCurDepth];
- sCounter[mType] += delta;
- sCalls[mType]++;
- // Subtract delta from parents
- for (i=0; i<sCurDepth; i++)
- sStart[i] += delta;
+ NamedTimer::FrameState* frame_state = mFrameState;
+ U64 cur_time = get_cpu_clock_count();
+ frame_state->mSelfTimeCounter += cur_time - mStartSelfTime;
+
+ frame_state->mActiveCount--;
+ LLFastTimer* last_timer = mLastTimer;
+ sCurTimer = last_timer;
+
+ // store last caller to bootstrap tree creation
+ frame_state->mLastCaller = last_timer->mFrameState;
+
+ // we are only tracking self time, so subtract our total time delta from parents
+ U64 total_time = cur_time - frame_state->mLastStartTime;
+ last_timer->mStartSelfTime += total_time;
#endif
}
+
+ // call this once a frame to reset timers
+ static void nextFrame();
+
+ // call this to reset timer hierarchy, averages, etc.
static void reset();
+
static U64 countsPerSecond();
+ static S32 getLastFrameIndex() { return sLastFrameIndex; }
+ static S32 getCurFrameIndex() { return sCurFrameIndex; }
+
+ static void writeLog(std::ostream& os);
+ static const NamedTimer* getTimerByName(const std::string& name);
public:
- static int sCurDepth;
- static U64 sStart[FTM_MAX_DEPTH];
- static U64 sCounter[FTM_NUM_TYPES];
- static U64 sCalls[FTM_NUM_TYPES];
- static U64 sCountAverage[FTM_NUM_TYPES];
- static U64 sCallAverage[FTM_NUM_TYPES];
- static U64 sCountHistory[FTM_HISTORY_NUM][FTM_NUM_TYPES];
- static U64 sCallHistory[FTM_HISTORY_NUM][FTM_NUM_TYPES];
- static S32 sCurFrameIndex;
- static S32 sLastFrameIndex;
- static int sPauseHistory;
- static int sResetHistory;
- static F64 sCPUClockFrequency;
+ static bool sPauseHistory;
+ static bool sResetHistory;
private:
- EFastTimerType mType;
-};
+ typedef std::vector<LLFastTimer*> timer_stack_t;
+ static LLFastTimer* sCurTimer;
+ static S32 sCurFrameIndex;
+ static S32 sLastFrameIndex;
+ static F64 sCPUClockFrequency;
+ U64 mStartSelfTime; // start time + time of all child timers
+ NamedTimer::FrameState* mFrameState;
+ LLFastTimer* mLastTimer;
+};
#endif // LL_LLFASTTIMER_H
diff --git a/indra/llcommon/llfixedbuffer.cpp b/indra/llcommon/llfixedbuffer.cpp
index e9d6029378..1f6a06c247 100644
--- a/indra/llcommon/llfixedbuffer.cpp
+++ b/indra/llcommon/llfixedbuffer.cpp
@@ -32,20 +32,21 @@
#include "llfixedbuffer.h"
+////////////////////////////////////////////////////////////////////////////
+
LLFixedBuffer::LLFixedBuffer(const U32 max_lines)
- : mMutex(NULL)
+ : LLLineBuffer(),
+ mMaxLines(max_lines),
+ mMutex(NULL)
{
- mMaxLines = max_lines;
mTimer.reset();
}
-
LLFixedBuffer::~LLFixedBuffer()
{
clear();
}
-
void LLFixedBuffer::clear()
{
mMutex.lock() ;
@@ -61,10 +62,10 @@ void LLFixedBuffer::clear()
void LLFixedBuffer::addLine(const std::string& utf8line)
{
LLWString wstring = utf8str_to_wstring(utf8line);
- LLFixedBuffer::addLine(wstring);
+ addWLine(wstring);
}
-void LLFixedBuffer::addLine(const LLWString& line)
+void LLFixedBuffer::addWLine(const LLWString& line)
{
if (line.empty())
{
diff --git a/indra/llcommon/llfixedbuffer.h b/indra/llcommon/llfixedbuffer.h
index 992a024df1..01b46d327a 100644
--- a/indra/llcommon/llfixedbuffer.h
+++ b/indra/llcommon/llfixedbuffer.h
@@ -38,14 +38,14 @@
#include <string>
#include "llstring.h"
#include "llthread.h"
+#include "llerrorcontrol.h"
-// Fixed size buffer for console output and other things.
-
-class LLFixedBuffer
+// fixed buffer implementation
+class LLFixedBuffer : public LLLineBuffer
{
public:
LLFixedBuffer(const U32 max_lines = 20);
- virtual ~LLFixedBuffer();
+ ~LLFixedBuffer();
LLTimer mTimer;
U32 mMaxLines;
@@ -53,22 +53,18 @@ public:
std::deque<F32> mAddTimes;
std::deque<S32> mLineLengths;
- void clear(); // Clear the buffer, and reset it.
+ /*virtual*/ void clear(); // Clear the buffer, and reset it.
- //do not make these two "virtual"
- void addLine(const std::string& utf8line);
- void addLine(const LLWString& line);
+ /*virtual*/ void addLine(const std::string& utf8line);
- // Get lines currently in the buffer, up to max_size chars, max_length lines
- char *getLines(U32 max_size = 0, U32 max_length = 0);
void setMaxLines(S32 max_lines);
+
protected:
- virtual void removeExtraLines();
+ void removeExtraLines();
+ void addWLine(const LLWString& line);
protected:
LLMutex mMutex ;
};
-const U32 FIXED_BUF_MAX_LINE_LEN = 255; // Not including termnating 0
-
#endif //LL_FIXED_BUFFER_H
diff --git a/indra/llcommon/llinstancetracker.h b/indra/llcommon/llinstancetracker.h
new file mode 100644
index 0000000000..ea50acbbc5
--- /dev/null
+++ b/indra/llcommon/llinstancetracker.h
@@ -0,0 +1,121 @@
+/**
+ * @file llinstancetracker.h
+ * @brief LLInstanceTracker is a mixin class that automatically tracks object
+ * instances with or without an associated key
+ *
+ * $LicenseInfo:firstyear=2000&license=viewergpl$
+ *
+ * Copyright (c) 2000-2009, Linden Research, Inc.
+ *
+ * Second Life Viewer Source Code
+ * The source code in this file ("Source Code") is provided by Linden Lab
+ * to you under the terms of the GNU General Public License, version 2.0
+ * ("GPL"), unless you have obtained a separate licensing agreement
+ * ("Other License"), formally executed by you and Linden Lab. Terms of
+ * the GPL can be found in doc/GPL-license.txt in this distribution, or
+ * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
+ *
+ * There are special exceptions to the terms and conditions of the GPL as
+ * it is applied to this Source Code. View the full text of the exception
+ * in the file doc/FLOSS-exception.txt in this software distribution, or
+ * online at
+ * http://secondlifegrid.net/programs/open_source/licensing/flossexception
+ *
+ * By copying, modifying or distributing this software, you acknowledge
+ * that you have read and understood your obligations described above,
+ * and agree to abide by those obligations.
+ *
+ * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+ * COMPLETENESS OR PERFORMANCE.
+ * $/LicenseInfo$
+ */
+
+#ifndef LL_LLINSTANCETRACKER_H
+#define LL_LLINSTANCETRACKER_H
+
+#include <map>
+
+#include "string_table.h"
+#include <boost/utility.hpp>
+
+// This mix-in class adds support for tracking all instances of the specified class parameter T
+// The (optional) key associates a value of type KEY with a given instance of T, for quick lookup
+// If KEY is not provided, then instances are stored in a simple set
+// *NOTE: see explicit specialization below for default KEY==T* case
+template<typename T, typename KEY = T*>
+class LLInstanceTracker : boost::noncopyable
+{
+public:
+ typedef typename std::map<KEY, T*>::iterator instance_iter;
+ typedef typename std::map<KEY, T*>::const_iterator instance_const_iter;
+
+ static T* getInstance(const KEY& k) { instance_iter found = getMap().find(k); return (found == getMap().end()) ? NULL : found->second; }
+
+ static instance_iter beginInstances() { return getMap().begin(); }
+ static instance_iter endInstances() { return getMap().end(); }
+ static S32 instanceCount() { return getMap().size(); }
+protected:
+ LLInstanceTracker(KEY key) { add(key); }
+ virtual ~LLInstanceTracker() { remove(); }
+ virtual void setKey(KEY key) { remove(); add(key); }
+ virtual const KEY& getKey() const { return mKey; }
+
+private:
+ void add(KEY key)
+ {
+ mKey = key;
+ getMap()[key] = static_cast<T*>(this);
+ }
+ void remove() { getMap().erase(mKey); }
+
+ static std::map<KEY, T*>& getMap()
+ {
+ if (! sInstances)
+ {
+ sInstances = new std::map<KEY, T*>;
+ }
+ return *sInstances;
+ }
+
+private:
+
+ KEY mKey;
+ static std::map<KEY, T*>* sInstances;
+};
+
+// explicit specialization for default case where KEY is T*
+// use a simple std::set<T*>
+template<typename T>
+class LLInstanceTracker<T, T*>
+{
+public:
+ typedef typename std::set<T*>::iterator instance_iter;
+ typedef typename std::set<T*>::const_iterator instance_const_iter;
+
+ static instance_iter beginInstances() { return getSet().begin(); }
+ static instance_iter endInstances() { return getSet().end(); }
+ static S32 instanceCount() { return getSet().size(); }
+
+protected:
+ LLInstanceTracker() { getSet().insert(static_cast<T*>(this)); }
+ virtual ~LLInstanceTracker() { getSet().erase(static_cast<T*>(this)); }
+
+ LLInstanceTracker(const LLInstanceTracker& other) { getSet().insert(static_cast<T*>(this)); }
+
+ static std::set<T*>& getSet() // called after getReady() but before go()
+ {
+ if (! sInstances)
+ {
+ sInstances = new std::set<T*>;
+ }
+ return *sInstances;
+ }
+
+ static std::set<T*>* sInstances;
+};
+
+template <typename T, typename KEY> std::map<KEY, T*>* LLInstanceTracker<T, KEY>::sInstances = NULL;
+template <typename T> std::set<T*>* LLInstanceTracker<T, T*>::sInstances = NULL;
+
+#endif
diff --git a/indra/llcommon/llmd5.cpp b/indra/llcommon/llmd5.cpp
index 14b4f9f4b0..da9cb94e13 100644
--- a/indra/llcommon/llmd5.cpp
+++ b/indra/llcommon/llmd5.cpp
@@ -83,6 +83,7 @@ documentation and/or software.
#include "llmd5.h"
#include <cassert>
+#include <iostream> // cerr
// how many bytes to grab at a time when checking files
const int LLMD5::BLOCK_LEN = 4096;
diff --git a/indra/llcommon/llmemory.cpp b/indra/llcommon/llmemory.cpp
index a6de3d2d69..2a8015e26d 100644
--- a/indra/llcommon/llmemory.cpp
+++ b/indra/llcommon/llmemory.cpp
@@ -44,7 +44,6 @@
#endif
#include "llmemory.h"
-#include "llmemtype.h"
//----------------------------------------------------------------------------
@@ -74,162 +73,6 @@ void LLMemory::freeReserve()
reserveMem = NULL;
}
-
-//----------------------------------------------------------------------------
-
-//static
-#if MEM_TRACK_TYPE
-S32 LLMemType::sCurDepth = 0;
-S32 LLMemType::sCurType = LLMemType::MTYPE_INIT;
-S32 LLMemType::sType[LLMemType::MTYPE_MAX_DEPTH];
-S32 LLMemType::sMemCount[LLMemType::MTYPE_NUM_TYPES] = { 0 };
-S32 LLMemType::sMaxMemCount[LLMemType::MTYPE_NUM_TYPES] = { 0 };
-S32 LLMemType::sNewCount[LLMemType::MTYPE_NUM_TYPES] = { 0 };
-S32 LLMemType::sOverheadMem = 0;
-
-const char* LLMemType::sTypeDesc[LLMemType::MTYPE_NUM_TYPES] =
-{
- "INIT",
- "STARTUP",
- "MAIN",
-
- "IMAGEBASE",
- "IMAGERAW",
- "IMAGEFORMATTED",
-
- "APPFMTIMAGE",
- "APPRAWIMAGE",
- "APPAUXRAWIMAGE",
-
- "DRAWABLE",
- "OBJECT",
- "PIPELINE",
- "AVATAR",
- "PARTICLES",
- "REGIONS",
- "INVENTORY",
- "ANIMATION",
- "NETWORK",
- "PHYSICS",
- "INTERESTLIST",
-
- "SCRIPT",
- "SCRIPT_RUN",
- "SCRIPT_BYTECODE",
-
- "IO_PUMP",
- "IO_TCP",
- "IO_BUFFER",
- "IO_HTTP_SERVER"
- "IO_SD_SERVER",
- "IO_SD_CLIENT",
- "IO_URL_REQUEST",
-
- "TEMP1",
- "TEMP2",
- "TEMP3",
- "TEMP4",
- "TEMP5",
- "TEMP6",
- "TEMP7",
- "TEMP8",
- "TEMP9"
-};
-
-#endif
-S32 LLMemType::sTotalMem = 0;
-S32 LLMemType::sMaxTotalMem = 0;
-
-//static
-void LLMemType::printMem()
-{
- S32 misc_mem = sTotalMem;
-#if MEM_TRACK_TYPE
- for (S32 i=0; i<MTYPE_NUM_TYPES; i++)
- {
- if (sMemCount[i])
- {
- llinfos << llformat("MEM: % 20s %03d MB (%03d MB) in %06d News",sTypeDesc[i],sMemCount[i]>>20,sMaxMemCount[i]>>20, sNewCount[i]) << llendl;
- }
- misc_mem -= sMemCount[i];
- }
-#endif
- llinfos << llformat("MEM: % 20s %03d MB","MISC",misc_mem>>20) << llendl;
- llinfos << llformat("MEM: % 20s %03d MB (Max=%d MB)","TOTAL",sTotalMem>>20,sMaxTotalMem>>20) << llendl;
-}
-
-#if MEM_TRACK_MEM
-
-void* ll_allocate (size_t size)
-{
- if (size == 0)
- {
- llwarns << "Null allocation" << llendl;
- }
-
- size = (size+3)&~3;
- S32 alloc_size = size + 4;
-#if MEM_TRACK_TYPE
- alloc_size += 4;
-#endif
- char* p = (char*)malloc(alloc_size);
- if (p == NULL)
- {
- LLMemory::freeReserve();
- llerrs << "Out of memory Error" << llendl;
- }
- LLMemType::sTotalMem += size;
- LLMemType::sMaxTotalMem = llmax(LLMemType::sTotalMem, LLMemType::sMaxTotalMem);
- LLMemType::sOverheadMem += 4;
- *(size_t*)p = size;
- p += 4;
-#if MEM_TRACK_TYPE
- if (LLMemType::sCurType < 0 || LLMemType::sCurType >= LLMemType::MTYPE_NUM_TYPES)
- {
- llerrs << "Memory Type Error: new" << llendl;
- }
- LLMemType::sOverheadMem += 4;
- *(S32*)p = LLMemType::sCurType;
- p += 4;
- LLMemType::sMemCount[LLMemType::sCurType] += size;
- if (LLMemType::sMemCount[LLMemType::sCurType] > LLMemType::sMaxMemCount[LLMemType::sCurType])
- {
- LLMemType::sMaxMemCount[LLMemType::sCurType] = LLMemType::sMemCount[LLMemType::sCurType];
- }
- LLMemType::sNewCount[LLMemType::sCurType]++;
-#endif
- return (void*)p;
-}
-
-void ll_release (void *pin)
-{
- if (!pin)
- {
- return;
- }
- char* p = (char*)pin;
-#if MEM_TRACK_TYPE
- p -= 4;
- S32 type = *(S32*)p;
- if (type < 0 || type >= LLMemType::MTYPE_NUM_TYPES)
- {
- llerrs << "Memory Type Error: delete" << llendl;
- }
-#endif
- p -= 4;
- S32 size = *(size_t*)p;
- LLMemType::sOverheadMem -= 4;
-#if MEM_TRACK_TYPE
- LLMemType::sMemCount[type] -= size;
- LLMemType::sOverheadMem -= 4;
- LLMemType::sNewCount[type]--;
-#endif
- LLMemType::sTotalMem -= size;
- free(p);
-}
-
-#else
-
void* ll_allocate (size_t size)
{
if (size == 0)
@@ -250,52 +93,11 @@ void ll_release (void *p)
free(p);
}
-#endif
-
-#if MEM_TRACK_MEM
-
-void* operator new (size_t size)
-{
- return ll_allocate(size);
-}
-
-void* operator new[] (size_t size)
-{
- return ll_allocate(size);
-}
-
-void operator delete (void *p)
-{
- ll_release(p);
-}
-
-void operator delete[] (void *p)
-{
- ll_release(p);
-}
-
-#endif
-
-//----------------------------------------------------------------------------
-
-LLRefCount::LLRefCount() :
- mRef(0)
-{
-}
-
-LLRefCount::~LLRefCount()
-{
- if (mRef != 0)
- {
- llerrs << "deleting non-zero reference" << llendl;
- }
-}
-
//----------------------------------------------------------------------------
#if defined(LL_WINDOWS)
-U64 getCurrentRSS()
+U64 LLMemory::getCurrentRSS()
{
HANDLE self = GetCurrentProcess();
PROCESS_MEMORY_COUNTERS counters;
@@ -333,7 +135,7 @@ U64 getCurrentRSS()
// }
// }
-U64 getCurrentRSS()
+U64 LLMemory::getCurrentRSS()
{
U64 residentSize = 0;
task_basic_info_data_t basicInfo;
@@ -357,7 +159,7 @@ U64 getCurrentRSS()
#elif defined(LL_LINUX)
-U64 getCurrentRSS()
+U64 LLMemory::getCurrentRSS()
{
static const char statPath[] = "/proc/self/stat";
LLFILE *fp = LLFile::fopen(statPath, "r");
@@ -396,7 +198,7 @@ bail:
#define _STRUCTURED_PROC 1
#include <sys/procfs.h>
-U64 getCurrentRSS()
+U64 LLMemory::getCurrentRSS()
{
char path [LL_MAX_PATH]; /* Flawfinder: ignore */
@@ -419,7 +221,7 @@ U64 getCurrentRSS()
}
#else
-U64 getCurrentRSS()
+U64 LLMemory::getCurrentRSS()
{
return 0;
}
diff --git a/indra/llcommon/llmemory.h b/indra/llcommon/llmemory.h
index b5c0711484..f41da37ba6 100644
--- a/indra/llcommon/llmemory.h
+++ b/indra/llcommon/llmemory.h
@@ -29,21 +29,17 @@
* COMPLETENESS OR PERFORMANCE.
* $/LicenseInfo$
*/
-#ifndef LL_MEMORY_H
-#define LL_MEMORY_H
+#ifndef LLMEMORY_H
+#define LLMEMORY_H
-#include <new>
-#include <cstdlib>
-#include "llerror.h"
extern S32 gTotalDAlloc;
extern S32 gTotalDAUse;
extern S32 gDACount;
-const U32 LLREFCOUNT_SENTINEL_VALUE = 0xAAAAAAAA;
-
-//----------------------------------------------------------------------------
+extern void* ll_allocate (size_t size);
+extern void ll_release (void *p);
class LLMemory
{
@@ -51,422 +47,19 @@ public:
static void initClass();
static void cleanupClass();
static void freeReserve();
+ // Return the resident set size of the current process, in bytes.
+ // Return value is zero if not known.
+ static U64 getCurrentRSS();
private:
static char* reserveMem;
};
-//----------------------------------------------------------------------------
-// RefCount objects should generally only be accessed by way of LLPointer<>'s
-// NOTE: LLPointer<LLFoo> x = new LLFoo(); MAY NOT BE THREAD SAFE
-// if LLFoo::LLFoo() does anything like put itself in an update queue.
-// The queue may get accessed before it gets assigned to x.
-// The correct implementation is:
-// LLPointer<LLFoo> x = new LLFoo; // constructor does not do anything interesting
-// x->instantiate(); // does stuff like place x into an update queue
-
-// see llthread.h for LLThreadSafeRefCount
-
-//----------------------------------------------------------------------------
-
-class LLRefCount
-{
-protected:
- LLRefCount(const LLRefCount&); // not implemented
-private:
- LLRefCount&operator=(const LLRefCount&); // not implemented
-
-protected:
- virtual ~LLRefCount(); // use unref()
-
-public:
- LLRefCount();
-
- void ref()
- {
- mRef++;
- }
-
- S32 unref()
- {
- llassert(mRef >= 1);
- if (0 == --mRef)
- {
- delete this;
- return 0;
- }
- return mRef;
- }
-
- S32 getNumRefs() const
- {
- return mRef;
- }
-
-private:
- S32 mRef;
-};
-
-//----------------------------------------------------------------------------
-
-// Note: relies on Type having ref() and unref() methods
-template <class Type> class LLPointer
-{
-public:
-
- LLPointer() :
- mPointer(NULL)
- {
- }
-
- LLPointer(Type* ptr) :
- mPointer(ptr)
- {
- ref();
- }
-
- LLPointer(const LLPointer<Type>& ptr) :
- mPointer(ptr.mPointer)
- {
- ref();
- }
-
- // support conversion up the type hierarchy. See Item 45 in Effective C++, 3rd Ed.
- template<typename Subclass>
- LLPointer(const LLPointer<Subclass>& ptr) :
- mPointer(ptr.get())
- {
- ref();
- }
-
- ~LLPointer()
- {
- unref();
- }
-
- Type* get() const { return mPointer; }
- const Type* operator->() const { return mPointer; }
- Type* operator->() { return mPointer; }
- const Type& operator*() const { return *mPointer; }
- Type& operator*() { return *mPointer; }
-
- operator BOOL() const { return (mPointer != NULL); }
- operator bool() const { return (mPointer != NULL); }
- bool operator!() const { return (mPointer == NULL); }
- bool isNull() const { return (mPointer == NULL); }
- bool notNull() const { return (mPointer != NULL); }
-
- operator Type*() const { return mPointer; }
- operator const Type*() const { return mPointer; }
- bool operator !=(Type* ptr) const { return (mPointer != ptr); }
- bool operator ==(Type* ptr) const { return (mPointer == ptr); }
- bool operator ==(const LLPointer<Type>& ptr) const { return (mPointer == ptr.mPointer); }
- bool operator < (const LLPointer<Type>& ptr) const { return (mPointer < ptr.mPointer); }
- bool operator > (const LLPointer<Type>& ptr) const { return (mPointer > ptr.mPointer); }
-
- LLPointer<Type>& operator =(Type* ptr)
- {
- if( mPointer != ptr )
- {
- unref();
- mPointer = ptr;
- ref();
- }
-
- return *this;
- }
-
- LLPointer<Type>& operator =(const LLPointer<Type>& ptr)
- {
- if( mPointer != ptr.mPointer )
- {
- unref();
- mPointer = ptr.mPointer;
- ref();
- }
- return *this;
- }
-
- // support assignment up the type hierarchy. See Item 45 in Effective C++, 3rd Ed.
- template<typename Subclass>
- LLPointer<Type>& operator =(const LLPointer<Subclass>& ptr)
- {
- if( mPointer != ptr.get() )
- {
- unref();
- mPointer = ptr.get();
- ref();
- }
- return *this;
- }
-
- // Just exchange the pointers, which will not change the reference counts.
- static void swap(LLPointer<Type>& a, LLPointer<Type>& b)
- {
- Type* temp = a.mPointer;
- a.mPointer = b.mPointer;
- b.mPointer = temp;
- }
-
-protected:
- void ref()
- {
- if (mPointer)
- {
- mPointer->ref();
- }
- }
-
- void unref()
- {
- if (mPointer)
- {
- Type *tempp = mPointer;
- mPointer = NULL;
- tempp->unref();
- if (mPointer != NULL)
- {
- llwarns << "Unreference did assignment to non-NULL because of destructor" << llendl;
- unref();
- }
- }
- }
-
-protected:
- Type* mPointer;
-};
-
-//template <class Type>
-//class LLPointerTraits
-//{
-// static Type* null();
-//};
-//
-// Expands LLPointer to return a pointer to a special instance of class Type instead of NULL.
-// This is useful in instances where operations on NULL pointers are semantically safe and/or
-// when error checking occurs at a different granularity or in a different part of the code
-// than when referencing an object via a LLSafeHandle.
-//
-
-template <class Type>
-class LLSafeHandle
-{
-public:
- LLSafeHandle() :
- mPointer(NULL)
- {
- }
-
- LLSafeHandle(Type* ptr) :
- mPointer(NULL)
- {
- assign(ptr);
- }
-
- LLSafeHandle(const LLSafeHandle<Type>& ptr) :
- mPointer(NULL)
- {
- assign(ptr.mPointer);
- }
-
- // support conversion up the type hierarchy. See Item 45 in Effective C++, 3rd Ed.
- template<typename Subclass>
- LLSafeHandle(const LLSafeHandle<Subclass>& ptr) :
- mPointer(NULL)
- {
- assign(ptr.get());
- }
-
- ~LLSafeHandle()
- {
- unref();
- }
-
- const Type* operator->() const { return nonNull(mPointer); }
- Type* operator->() { return nonNull(mPointer); }
-
- Type* get() const { return mPointer; }
- // we disallow these operations as they expose our null objects to direct manipulation
- // and bypass the reference counting semantics
- //const Type& operator*() const { return *nonNull(mPointer); }
- //Type& operator*() { return *nonNull(mPointer); }
-
- operator BOOL() const { return mPointer != NULL; }
- operator bool() const { return mPointer != NULL; }
- bool operator!() const { return mPointer == NULL; }
- bool isNull() const { return mPointer == NULL; }
- bool notNull() const { return mPointer != NULL; }
-
-
- operator Type*() const { return mPointer; }
- operator const Type*() const { return mPointer; }
- bool operator !=(Type* ptr) const { return (mPointer != ptr); }
- bool operator ==(Type* ptr) const { return (mPointer == ptr); }
- bool operator ==(const LLSafeHandle<Type>& ptr) const { return (mPointer == ptr.mPointer); }
- bool operator < (const LLSafeHandle<Type>& ptr) const { return (mPointer < ptr.mPointer); }
- bool operator > (const LLSafeHandle<Type>& ptr) const { return (mPointer > ptr.mPointer); }
-
- LLSafeHandle<Type>& operator =(Type* ptr)
- {
- assign(ptr);
- return *this;
- }
-
- LLSafeHandle<Type>& operator =(const LLSafeHandle<Type>& ptr)
- {
- assign(ptr.mPointer);
- return *this;
- }
-
- // support assignment up the type hierarchy. See Item 45 in Effective C++, 3rd Ed.
- template<typename Subclass>
- LLSafeHandle<Type>& operator =(const LLSafeHandle<Subclass>& ptr)
- {
- assign(ptr.get());
- return *this;
- }
-
-public:
- typedef Type* (*NullFunc)();
- static const NullFunc sNullFunc;
-
-protected:
- void ref()
- {
- if (mPointer)
- {
- mPointer->ref();
- }
- }
-
- void unref()
- {
- if (mPointer)
- {
- Type *tempp = mPointer;
- mPointer = NULL;
- tempp->unref();
- if (mPointer != NULL)
- {
- llwarns << "Unreference did assignment to non-NULL because of destructor" << llendl;
- unref();
- }
- }
- }
-
- void assign(Type* ptr)
- {
- if( mPointer != ptr )
- {
- unref();
- mPointer = ptr;
- ref();
- }
- }
-
- static Type* nonNull(Type* ptr)
- {
- return ptr == NULL ? sNullFunc() : ptr;
- }
-
-protected:
- Type* mPointer;
-};
-
-// LLInitializedPointer is just a pointer with a default constructor that initializes it to NULL
-// NOT a smart pointer like LLPointer<>
-// Useful for example in std::map<int,LLInitializedPointer<LLFoo> >
-// (std::map uses the default constructor for creating new entries)
-template <typename T> class LLInitializedPointer
-{
-public:
- LLInitializedPointer() : mPointer(NULL) {}
- ~LLInitializedPointer() { delete mPointer; }
-
- const T* operator->() const { return mPointer; }
- T* operator->() { return mPointer; }
- const T& operator*() const { return *mPointer; }
- T& operator*() { return *mPointer; }
- operator const T*() const { return mPointer; }
- operator T*() { return mPointer; }
- T* operator=(T* x) { return (mPointer = x); }
- operator bool() const { return mPointer != NULL; }
- bool operator!() const { return mPointer == NULL; }
- bool operator==(T* rhs) { return mPointer == rhs; }
- bool operator==(const LLInitializedPointer<T>* rhs) { return mPointer == rhs.mPointer; }
-
-protected:
- T* mPointer;
-};
-
-//----------------------------------------------------------------------------
+// LLRefCount moved to llrefcount.h
-// LLSingleton implements the getInstance() method part of the Singleton
-// pattern. It can't make the derived class constructors protected, though, so
-// you have to do that yourself.
-//
-// There are two ways to use LLSingleton. The first way is to inherit from it
-// while using the typename that you'd like to be static as the template
-// parameter, like so:
-//
-// class Foo: public LLSingleton<Foo>{};
-//
-// Foo& instance = Foo::instance();
-//
-// The second way is to use the singleton class directly, without inheritance:
-//
-// typedef LLSingleton<Foo> FooSingleton;
-//
-// Foo& instance = FooSingleton::instance();
-//
-// In this case, the class being managed as a singleton needs to provide an
-// initSingleton() method since the LLSingleton virtual method won't be
-// available
-//
-// As currently written, it is not thread-safe.
-template <typename T>
-class LLSingleton
-{
-public:
- virtual ~LLSingleton() {}
-#ifdef LL_MSVC7
-// workaround for VC7 compiler bug
-// adapted from http://www.codeproject.com/KB/tips/VC2003MeyersSingletonBug.aspx
-// our version doesn't introduce a nested struct so that you can still declare LLSingleton<MyClass>
-// a friend and hide your constructor
- static T* getInstance()
- {
- LLSingleton<T> singleton;
- return singleton.vsHack();
- }
-
- T* vsHack()
-#else
- static T* getInstance()
-#endif
- {
- static T instance;
- static bool needs_init = true;
- if (needs_init)
- {
- needs_init = false;
- instance.initSingleton();
- }
- return &instance;
- }
-
- static T& instance()
- {
- return *getInstance();
- }
-
-private:
- virtual void initSingleton() {}
-};
+// LLPointer moved to llpointer.h
-//----------------------------------------------------------------------------
+// LLSafeHandle moved to llsafehandle.h
-// Return the resident set size of the current process, in bytes.
-// Return value is zero if not known.
-U64 getCurrentRSS();
+// LLSingleton moved to llsingleton.h
#endif
diff --git a/indra/llcommon/llmemtype.cpp b/indra/llcommon/llmemtype.cpp
new file mode 100644
index 0000000000..4e33439711
--- /dev/null
+++ b/indra/llcommon/llmemtype.cpp
@@ -0,0 +1,237 @@
+/**
+ * @file llmemtype.cpp
+ * @brief Simple memory allocation/deallocation tracking stuff here
+ *
+ * $LicenseInfo:firstyear=2002&license=viewergpl$
+ *
+ * Copyright (c) 2002-2009, Linden Research, Inc.
+ *
+ * Second Life Viewer Source Code
+ * The source code in this file ("Source Code") is provided by Linden Lab
+ * to you under the terms of the GNU General Public License, version 2.0
+ * ("GPL"), unless you have obtained a separate licensing agreement
+ * ("Other License"), formally executed by you and Linden Lab. Terms of
+ * the GPL can be found in doc/GPL-license.txt in this distribution, or
+ * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
+ *
+ * There are special exceptions to the terms and conditions of the GPL as
+ * it is applied to this Source Code. View the full text of the exception
+ * in the file doc/FLOSS-exception.txt in this software distribution, or
+ * online at
+ * http://secondlifegrid.net/programs/open_source/licensing/flossexception
+ *
+ * By copying, modifying or distributing this software, you acknowledge
+ * that you have read and understood your obligations described above,
+ * and agree to abide by those obligations.
+ *
+ * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+ * COMPLETENESS OR PERFORMANCE.
+ * $/LicenseInfo$
+ */
+
+#include "llmemtype.h"
+#include "llallocator.h"
+
+std::vector<char const *> LLMemType::DeclareMemType::mNameList;
+
+LLMemType::DeclareMemType LLMemType::MTYPE_INIT("Init");
+LLMemType::DeclareMemType LLMemType::MTYPE_STARTUP("Startup");
+LLMemType::DeclareMemType LLMemType::MTYPE_MAIN("Main");
+LLMemType::DeclareMemType LLMemType::MTYPE_FRAME("Frame");
+
+LLMemType::DeclareMemType LLMemType::MTYPE_GATHER_INPUT("GatherInput");
+LLMemType::DeclareMemType LLMemType::MTYPE_JOY_KEY("JoyKey");
+
+LLMemType::DeclareMemType LLMemType::MTYPE_IDLE("Idle");
+LLMemType::DeclareMemType LLMemType::MTYPE_IDLE_PUMP("IdlePump");
+LLMemType::DeclareMemType LLMemType::MTYPE_IDLE_NETWORK("IdleNetwork");
+LLMemType::DeclareMemType LLMemType::MTYPE_IDLE_UPDATE_REGIONS("IdleUpdateRegions");
+LLMemType::DeclareMemType LLMemType::MTYPE_IDLE_UPDATE_VIEWER_REGION("IdleUpdateViewerRegion");
+LLMemType::DeclareMemType LLMemType::MTYPE_IDLE_UPDATE_SURFACE("IdleUpdateSurface");
+LLMemType::DeclareMemType LLMemType::MTYPE_IDLE_UPDATE_PARCEL_OVERLAY("IdleUpdateParcelOverlay");
+LLMemType::DeclareMemType LLMemType::MTYPE_IDLE_AUDIO("IdleAudio");
+
+LLMemType::DeclareMemType LLMemType::MTYPE_CACHE_PROCESS_PENDING("CacheProcessPending");
+LLMemType::DeclareMemType LLMemType::MTYPE_CACHE_PROCESS_PENDING_ASKS("CacheProcessPendingAsks");
+LLMemType::DeclareMemType LLMemType::MTYPE_CACHE_PROCESS_PENDING_REPLIES("CacheProcessPendingReplies");
+
+LLMemType::DeclareMemType LLMemType::MTYPE_MESSAGE_CHECK_ALL("MessageCheckAll");
+LLMemType::DeclareMemType LLMemType::MTYPE_MESSAGE_PROCESS_ACKS("MessageProcessAcks");
+
+LLMemType::DeclareMemType LLMemType::MTYPE_RENDER("Render");
+LLMemType::DeclareMemType LLMemType::MTYPE_SLEEP("Sleep");
+
+LLMemType::DeclareMemType LLMemType::MTYPE_NETWORK("Network");
+LLMemType::DeclareMemType LLMemType::MTYPE_PHYSICS("Physics");
+LLMemType::DeclareMemType LLMemType::MTYPE_INTERESTLIST("InterestList");
+
+LLMemType::DeclareMemType LLMemType::MTYPE_IMAGEBASE("ImageBase");
+LLMemType::DeclareMemType LLMemType::MTYPE_IMAGERAW("ImageRaw");
+LLMemType::DeclareMemType LLMemType::MTYPE_IMAGEFORMATTED("ImageFormatted");
+
+LLMemType::DeclareMemType LLMemType::MTYPE_APPFMTIMAGE("AppFmtImage");
+LLMemType::DeclareMemType LLMemType::MTYPE_APPRAWIMAGE("AppRawImage");
+LLMemType::DeclareMemType LLMemType::MTYPE_APPAUXRAWIMAGE("AppAuxRawImage");
+
+LLMemType::DeclareMemType LLMemType::MTYPE_DRAWABLE("Drawable");
+
+LLMemType::DeclareMemType LLMemType::MTYPE_OBJECT("Object");
+LLMemType::DeclareMemType LLMemType::MTYPE_OBJECT_PROCESS_UPDATE("ObjectProcessUpdate");
+LLMemType::DeclareMemType LLMemType::MTYPE_OBJECT_PROCESS_UPDATE_CORE("ObjectProcessUpdateCore");
+
+LLMemType::DeclareMemType LLMemType::MTYPE_DISPLAY("Display");
+LLMemType::DeclareMemType LLMemType::MTYPE_DISPLAY_UPDATE("DisplayUpdate");
+LLMemType::DeclareMemType LLMemType::MTYPE_DISPLAY_UPDATE_CAMERA("DisplayUpdateCam");
+LLMemType::DeclareMemType LLMemType::MTYPE_DISPLAY_UPDATE_GEOM("DisplayUpdateGeom");
+LLMemType::DeclareMemType LLMemType::MTYPE_DISPLAY_SWAP("DisplaySwap");
+LLMemType::DeclareMemType LLMemType::MTYPE_DISPLAY_UPDATE_HUD("DisplayUpdateHud");
+LLMemType::DeclareMemType LLMemType::MTYPE_DISPLAY_GEN_REFLECTION("DisplayGenRefl");
+LLMemType::DeclareMemType LLMemType::MTYPE_DISPLAY_IMAGE_UPDATE("DisplayImageUpdate");
+LLMemType::DeclareMemType LLMemType::MTYPE_DISPLAY_STATE_SORT("DisplayStateSort");
+LLMemType::DeclareMemType LLMemType::MTYPE_DISPLAY_SKY("DisplaySky");
+LLMemType::DeclareMemType LLMemType::MTYPE_DISPLAY_RENDER_GEOM("DisplayRenderGeom");
+LLMemType::DeclareMemType LLMemType::MTYPE_DISPLAY_RENDER_FLUSH("DisplayRenderFlush");
+LLMemType::DeclareMemType LLMemType::MTYPE_DISPLAY_RENDER_UI("DisplayRenderUI");
+LLMemType::DeclareMemType LLMemType::MTYPE_DISPLAY_RENDER_ATTACHMENTS("DisplayRenderAttach");
+
+LLMemType::DeclareMemType LLMemType::MTYPE_VERTEX_DATA("VertexData");
+LLMemType::DeclareMemType LLMemType::MTYPE_VERTEX_CONSTRUCTOR("VertexConstr");
+LLMemType::DeclareMemType LLMemType::MTYPE_VERTEX_DESTRUCTOR("VertexDestr");
+LLMemType::DeclareMemType LLMemType::MTYPE_VERTEX_CREATE_VERTICES("VertexCreateVerts");
+LLMemType::DeclareMemType LLMemType::MTYPE_VERTEX_CREATE_INDICES("VertexCreateIndices");
+LLMemType::DeclareMemType LLMemType::MTYPE_VERTEX_DESTROY_BUFFER("VertexDestroyBuff");
+LLMemType::DeclareMemType LLMemType::MTYPE_VERTEX_DESTROY_INDICES("VertexDestroyIndices");
+LLMemType::DeclareMemType LLMemType::MTYPE_VERTEX_UPDATE_VERTS("VertexUpdateVerts");
+LLMemType::DeclareMemType LLMemType::MTYPE_VERTEX_UPDATE_INDICES("VertexUpdateIndices");
+LLMemType::DeclareMemType LLMemType::MTYPE_VERTEX_ALLOCATE_BUFFER("VertexAllocateBuffer");
+LLMemType::DeclareMemType LLMemType::MTYPE_VERTEX_RESIZE_BUFFER("VertexResizeBuffer");
+LLMemType::DeclareMemType LLMemType::MTYPE_VERTEX_MAP_BUFFER("VertexMapBuffer");
+LLMemType::DeclareMemType LLMemType::MTYPE_VERTEX_MAP_BUFFER_VERTICES("VertexMapBufferVerts");
+LLMemType::DeclareMemType LLMemType::MTYPE_VERTEX_MAP_BUFFER_INDICES("VertexMapBufferIndices");
+LLMemType::DeclareMemType LLMemType::MTYPE_VERTEX_UNMAP_BUFFER("VertexUnmapBuffer");
+LLMemType::DeclareMemType LLMemType::MTYPE_VERTEX_SET_STRIDE("VertexSetStride");
+LLMemType::DeclareMemType LLMemType::MTYPE_VERTEX_SET_BUFFER("VertexSetBuffer");
+LLMemType::DeclareMemType LLMemType::MTYPE_VERTEX_SETUP_VERTEX_BUFFER("VertexSetupVertBuff");
+LLMemType::DeclareMemType LLMemType::MTYPE_VERTEX_CLEANUP_CLASS("VertexCleanupClass");
+
+LLMemType::DeclareMemType LLMemType::MTYPE_SPACE_PARTITION("SpacePartition");
+
+LLMemType::DeclareMemType LLMemType::MTYPE_PIPELINE("Pipeline");
+LLMemType::DeclareMemType LLMemType::MTYPE_PIPELINE_INIT("PipelineInit");
+LLMemType::DeclareMemType LLMemType::MTYPE_PIPELINE_CREATE_BUFFERS("PipelineCreateBuffs");
+LLMemType::DeclareMemType LLMemType::MTYPE_PIPELINE_RESTORE_GL("PipelineRestroGL");
+LLMemType::DeclareMemType LLMemType::MTYPE_PIPELINE_UNLOAD_SHADERS("PipelineUnloadShaders");
+LLMemType::DeclareMemType LLMemType::MTYPE_PIPELINE_LIGHTING_DETAIL("PipelineLightingDetail");
+LLMemType::DeclareMemType LLMemType::MTYPE_PIPELINE_GET_POOL_TYPE("PipelineGetPoolType");
+LLMemType::DeclareMemType LLMemType::MTYPE_PIPELINE_ADD_POOL("PipelineAddPool");
+LLMemType::DeclareMemType LLMemType::MTYPE_PIPELINE_ALLOCATE_DRAWABLE("PipelineAllocDrawable");
+LLMemType::DeclareMemType LLMemType::MTYPE_PIPELINE_ADD_OBJECT("PipelineAddObj");
+LLMemType::DeclareMemType LLMemType::MTYPE_PIPELINE_CREATE_OBJECTS("PipelineCreateObjs");
+LLMemType::DeclareMemType LLMemType::MTYPE_PIPELINE_UPDATE_MOVE("PipelineUpdateMove");
+LLMemType::DeclareMemType LLMemType::MTYPE_PIPELINE_UPDATE_GEOM("PipelineUpdateGeom");
+LLMemType::DeclareMemType LLMemType::MTYPE_PIPELINE_MARK_VISIBLE("PipelineMarkVisible");
+LLMemType::DeclareMemType LLMemType::MTYPE_PIPELINE_MARK_MOVED("PipelineMarkMoved");
+LLMemType::DeclareMemType LLMemType::MTYPE_PIPELINE_MARK_SHIFT("PipelineMarkShift");
+LLMemType::DeclareMemType LLMemType::MTYPE_PIPELINE_SHIFT_OBJECTS("PipelineShiftObjs");
+LLMemType::DeclareMemType LLMemType::MTYPE_PIPELINE_MARK_TEXTURED("PipelineMarkTextured");
+LLMemType::DeclareMemType LLMemType::MTYPE_PIPELINE_MARK_REBUILD("PipelineMarkRebuild");
+LLMemType::DeclareMemType LLMemType::MTYPE_PIPELINE_UPDATE_CULL("PipelineUpdateCull");
+LLMemType::DeclareMemType LLMemType::MTYPE_PIPELINE_STATE_SORT("PipelineStateSort");
+LLMemType::DeclareMemType LLMemType::MTYPE_PIPELINE_POST_SORT("PipelinePostSort");
+
+LLMemType::DeclareMemType LLMemType::MTYPE_PIPELINE_RENDER_HUD_ELS("PipelineHudEls");
+LLMemType::DeclareMemType LLMemType::MTYPE_PIPELINE_RENDER_HL("PipelineRenderHL");
+LLMemType::DeclareMemType LLMemType::MTYPE_PIPELINE_RENDER_GEOM("PipelineRenderGeom");
+LLMemType::DeclareMemType LLMemType::MTYPE_PIPELINE_RENDER_GEOM_DEFFERRED("PipelineRenderGeomDef");
+LLMemType::DeclareMemType LLMemType::MTYPE_PIPELINE_RENDER_GEOM_POST_DEF("PipelineRenderGeomPostDef");
+LLMemType::DeclareMemType LLMemType::MTYPE_PIPELINE_RENDER_GEOM_SHADOW("PipelineRenderGeomShadow");
+LLMemType::DeclareMemType LLMemType::MTYPE_PIPELINE_RENDER_SELECT("PipelineRenderSelect");
+LLMemType::DeclareMemType LLMemType::MTYPE_PIPELINE_REBUILD_POOLS("PipelineRebuildPools");
+LLMemType::DeclareMemType LLMemType::MTYPE_PIPELINE_QUICK_LOOKUP("PipelineQuickLookup");
+LLMemType::DeclareMemType LLMemType::MTYPE_PIPELINE_RENDER_OBJECTS("PipelineRenderObjs");
+LLMemType::DeclareMemType LLMemType::MTYPE_PIPELINE_GENERATE_IMPOSTOR("PipelineGenImpostors");
+LLMemType::DeclareMemType LLMemType::MTYPE_PIPELINE_RENDER_BLOOM("PipelineRenderBloom");
+
+LLMemType::DeclareMemType LLMemType::MTYPE_UPKEEP_POOLS("UpkeepPools");
+
+LLMemType::DeclareMemType LLMemType::MTYPE_AVATAR("Avatar");
+LLMemType::DeclareMemType LLMemType::MTYPE_AVATAR_MESH("AvatarMesh");
+LLMemType::DeclareMemType LLMemType::MTYPE_PARTICLES("Particles");
+LLMemType::DeclareMemType LLMemType::MTYPE_REGIONS("Regions");
+
+LLMemType::DeclareMemType LLMemType::MTYPE_INVENTORY("Inventory");
+LLMemType::DeclareMemType LLMemType::MTYPE_INVENTORY_DRAW("InventoryDraw");
+LLMemType::DeclareMemType LLMemType::MTYPE_INVENTORY_BUILD_NEW_VIEWS("InventoryBuildNewViews");
+LLMemType::DeclareMemType LLMemType::MTYPE_INVENTORY_DO_FOLDER("InventoryDoFolder");
+LLMemType::DeclareMemType LLMemType::MTYPE_INVENTORY_POST_BUILD("InventoryPostBuild");
+LLMemType::DeclareMemType LLMemType::MTYPE_INVENTORY_FROM_XML("InventoryFromXML");
+LLMemType::DeclareMemType LLMemType::MTYPE_INVENTORY_CREATE_NEW_ITEM("InventoryCreateNewItem");
+LLMemType::DeclareMemType LLMemType::MTYPE_INVENTORY_VIEW_INIT("InventoryViewInit");
+LLMemType::DeclareMemType LLMemType::MTYPE_INVENTORY_VIEW_SHOW("InventoryViewShow");
+LLMemType::DeclareMemType LLMemType::MTYPE_INVENTORY_VIEW_TOGGLE("InventoryViewToggle");
+
+LLMemType::DeclareMemType LLMemType::MTYPE_ANIMATION("Animation");
+LLMemType::DeclareMemType LLMemType::MTYPE_VOLUME("Volume");
+LLMemType::DeclareMemType LLMemType::MTYPE_PRIMITIVE("Primitive");
+
+LLMemType::DeclareMemType LLMemType::MTYPE_SCRIPT("Script");
+LLMemType::DeclareMemType LLMemType::MTYPE_SCRIPT_RUN("ScriptRun");
+LLMemType::DeclareMemType LLMemType::MTYPE_SCRIPT_BYTECODE("ScriptByteCode");
+
+LLMemType::DeclareMemType LLMemType::MTYPE_IO_PUMP("IoPump");
+LLMemType::DeclareMemType LLMemType::MTYPE_IO_TCP("IoTCP");
+LLMemType::DeclareMemType LLMemType::MTYPE_IO_BUFFER("IoBuffer");
+LLMemType::DeclareMemType LLMemType::MTYPE_IO_HTTP_SERVER("IoHttpServer");
+LLMemType::DeclareMemType LLMemType::MTYPE_IO_SD_SERVER("IoSDServer");
+LLMemType::DeclareMemType LLMemType::MTYPE_IO_SD_CLIENT("IoSDClient");
+LLMemType::DeclareMemType LLMemType::MTYPE_IO_URL_REQUEST("IOUrlRequest");
+
+LLMemType::DeclareMemType LLMemType::MTYPE_DIRECTX_INIT("DirectXInit");
+
+LLMemType::DeclareMemType LLMemType::MTYPE_TEMP1("Temp1");
+LLMemType::DeclareMemType LLMemType::MTYPE_TEMP2("Temp2");
+LLMemType::DeclareMemType LLMemType::MTYPE_TEMP3("Temp3");
+LLMemType::DeclareMemType LLMemType::MTYPE_TEMP4("Temp4");
+LLMemType::DeclareMemType LLMemType::MTYPE_TEMP5("Temp5");
+LLMemType::DeclareMemType LLMemType::MTYPE_TEMP6("Temp6");
+LLMemType::DeclareMemType LLMemType::MTYPE_TEMP7("Temp7");
+LLMemType::DeclareMemType LLMemType::MTYPE_TEMP8("Temp8");
+LLMemType::DeclareMemType LLMemType::MTYPE_TEMP9("Temp9");
+
+LLMemType::DeclareMemType LLMemType::MTYPE_OTHER("Other");
+
+
+LLMemType::DeclareMemType::DeclareMemType(char const * st)
+{
+ mID = (S32)mNameList.size();
+ mName = st;
+
+ mNameList.push_back(mName);
+}
+
+LLMemType::DeclareMemType::~DeclareMemType()
+{
+}
+
+LLMemType::LLMemType(LLMemType::DeclareMemType& dt)
+{
+ mTypeIndex = dt.mID;
+ LLAllocator::pushMemType(dt.mID);
+}
+
+LLMemType::~LLMemType()
+{
+ LLAllocator::popMemType();
+}
+
+char const * LLMemType::getNameFromID(S32 id)
+{
+ if (id < 0 || id >= (S32)DeclareMemType::mNameList.size())
+ {
+ return "INVALID";
+ }
+
+ return DeclareMemType::mNameList[id];
+}
+
diff --git a/indra/llcommon/llmemtype.h b/indra/llcommon/llmemtype.h
index a9ebc2062f..12310fcdb4 100644
--- a/indra/llcommon/llmemtype.h
+++ b/indra/llcommon/llmemtype.h
@@ -36,128 +36,210 @@
//----------------------------------------------------------------------------
//----------------------------------------------------------------------------
-class LLMemType;
-
-extern void* ll_allocate (size_t size);
-extern void ll_release (void *p);
+//----------------------------------------------------------------------------
-#define MEM_TRACK_MEM 0
-#define MEM_TRACK_TYPE (1 && MEM_TRACK_MEM)
+#include "linden_common.h"
+//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+// WARNING: Never commit with MEM_TRACK_MEM == 1
+//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+#define MEM_TRACK_MEM (0 && LL_WINDOWS)
-#if MEM_TRACK_TYPE
-#define MEM_DUMP_DATA 1
-#define MEM_TYPE_NEW(T) \
-static void* operator new(size_t s) { LLMemType mt(T); return ll_allocate(s); } \
-static void operator delete(void* p) { ll_release(p); }
+#include <vector>
-#else
#define MEM_TYPE_NEW(T)
-#endif // MEM_TRACK_TYPE
-
-
-//----------------------------------------------------------------------------
class LLMemType
{
public:
- // Also update sTypeDesc in llmemory.cpp
- enum EMemType
- {
- MTYPE_INIT,
- MTYPE_STARTUP,
- MTYPE_MAIN,
- MTYPE_IMAGEBASE,
- MTYPE_IMAGERAW,
- MTYPE_IMAGEFORMATTED,
-
- MTYPE_APPFMTIMAGE,
- MTYPE_APPRAWIMAGE,
- MTYPE_APPAUXRAWIMAGE,
-
- MTYPE_DRAWABLE,
- MTYPE_OBJECT,
- MTYPE_VERTEX_DATA,
- MTYPE_SPACE_PARTITION,
- MTYPE_PIPELINE,
- MTYPE_AVATAR,
- MTYPE_AVATAR_MESH,
- MTYPE_PARTICLES,
- MTYPE_REGIONS,
- MTYPE_INVENTORY,
- MTYPE_ANIMATION,
- MTYPE_VOLUME,
- MTYPE_PRIMITIVE,
-
- MTYPE_NETWORK,
- MTYPE_PHYSICS,
- MTYPE_INTERESTLIST,
-
- MTYPE_SCRIPT,
- MTYPE_SCRIPT_RUN,
- MTYPE_SCRIPT_BYTECODE,
-
- MTYPE_IO_PUMP,
- MTYPE_IO_TCP,
- MTYPE_IO_BUFFER,
- MTYPE_IO_HTTP_SERVER,
- MTYPE_IO_SD_SERVER,
- MTYPE_IO_SD_CLIENT,
- MTYPE_IO_URL_REQUEST,
-
- MTYPE_TEMP1,
- MTYPE_TEMP2,
- MTYPE_TEMP3,
- MTYPE_TEMP4,
- MTYPE_TEMP5,
- MTYPE_TEMP6,
- MTYPE_TEMP7,
- MTYPE_TEMP8,
- MTYPE_TEMP9,
-
- MTYPE_OTHER, // Special, used by display code
+ // class we'll initialize all instances of as
+ // static members of MemType. Then use
+ // to construct any new mem type.
+ class DeclareMemType
+ {
+ public:
+ DeclareMemType(char const * st);
+ ~DeclareMemType();
+
+ S32 mID;
+ char const * mName;
- MTYPE_NUM_TYPES
+ // array so we can map an index ID to Name
+ static std::vector<char const *> mNameList;
};
- enum { MTYPE_MAX_DEPTH = 64 };
-
-public:
- LLMemType(EMemType type)
- {
-#if MEM_TRACK_TYPE
- if (type < 0 || type >= MTYPE_NUM_TYPES)
- llerrs << "LLMemType error" << llendl;
- if (sCurDepth < 0 || sCurDepth >= MTYPE_MAX_DEPTH)
- llerrs << "LLMemType error" << llendl;
- sType[sCurDepth] = sCurType;
- sCurDepth++;
- sCurType = type;
-#endif
- }
- ~LLMemType()
- {
-#if MEM_TRACK_TYPE
- sCurDepth--;
- sCurType = sType[sCurDepth];
-#endif
- }
- static void reset();
- static void printMem();
+ LLMemType(DeclareMemType& dt);
+ ~LLMemType();
+
+ static char const * getNameFromID(S32 id);
+
+ static DeclareMemType MTYPE_INIT;
+ static DeclareMemType MTYPE_STARTUP;
+ static DeclareMemType MTYPE_MAIN;
+ static DeclareMemType MTYPE_FRAME;
+
+ static DeclareMemType MTYPE_GATHER_INPUT;
+ static DeclareMemType MTYPE_JOY_KEY;
+
+ static DeclareMemType MTYPE_IDLE;
+ static DeclareMemType MTYPE_IDLE_PUMP;
+ static DeclareMemType MTYPE_IDLE_NETWORK;
+ static DeclareMemType MTYPE_IDLE_UPDATE_REGIONS;
+ static DeclareMemType MTYPE_IDLE_UPDATE_VIEWER_REGION;
+ static DeclareMemType MTYPE_IDLE_UPDATE_SURFACE;
+ static DeclareMemType MTYPE_IDLE_UPDATE_PARCEL_OVERLAY;
+ static DeclareMemType MTYPE_IDLE_AUDIO;
+
+ static DeclareMemType MTYPE_CACHE_PROCESS_PENDING;
+ static DeclareMemType MTYPE_CACHE_PROCESS_PENDING_ASKS;
+ static DeclareMemType MTYPE_CACHE_PROCESS_PENDING_REPLIES;
+
+ static DeclareMemType MTYPE_MESSAGE_CHECK_ALL;
+ static DeclareMemType MTYPE_MESSAGE_PROCESS_ACKS;
+
+ static DeclareMemType MTYPE_RENDER;
+ static DeclareMemType MTYPE_SLEEP;
+
+ static DeclareMemType MTYPE_NETWORK;
+ static DeclareMemType MTYPE_PHYSICS;
+ static DeclareMemType MTYPE_INTERESTLIST;
+
+ static DeclareMemType MTYPE_IMAGEBASE;
+ static DeclareMemType MTYPE_IMAGERAW;
+ static DeclareMemType MTYPE_IMAGEFORMATTED;
-public:
-#if MEM_TRACK_TYPE
- static S32 sCurDepth;
- static S32 sCurType;
- static S32 sType[MTYPE_MAX_DEPTH];
- static S32 sMemCount[MTYPE_NUM_TYPES];
- static S32 sMaxMemCount[MTYPE_NUM_TYPES];
- static S32 sNewCount[MTYPE_NUM_TYPES];
- static S32 sOverheadMem;
- static const char* sTypeDesc[MTYPE_NUM_TYPES];
-#endif
- static S32 sTotalMem;
- static S32 sMaxTotalMem;
+ static DeclareMemType MTYPE_APPFMTIMAGE;
+ static DeclareMemType MTYPE_APPRAWIMAGE;
+ static DeclareMemType MTYPE_APPAUXRAWIMAGE;
+
+ static DeclareMemType MTYPE_DRAWABLE;
+
+ static DeclareMemType MTYPE_OBJECT;
+ static DeclareMemType MTYPE_OBJECT_PROCESS_UPDATE;
+ static DeclareMemType MTYPE_OBJECT_PROCESS_UPDATE_CORE;
+
+ static DeclareMemType MTYPE_DISPLAY;
+ static DeclareMemType MTYPE_DISPLAY_UPDATE;
+ static DeclareMemType MTYPE_DISPLAY_UPDATE_CAMERA;
+ static DeclareMemType MTYPE_DISPLAY_UPDATE_GEOM;
+ static DeclareMemType MTYPE_DISPLAY_SWAP;
+ static DeclareMemType MTYPE_DISPLAY_UPDATE_HUD;
+ static DeclareMemType MTYPE_DISPLAY_GEN_REFLECTION;
+ static DeclareMemType MTYPE_DISPLAY_IMAGE_UPDATE;
+ static DeclareMemType MTYPE_DISPLAY_STATE_SORT;
+ static DeclareMemType MTYPE_DISPLAY_SKY;
+ static DeclareMemType MTYPE_DISPLAY_RENDER_GEOM;
+ static DeclareMemType MTYPE_DISPLAY_RENDER_FLUSH;
+ static DeclareMemType MTYPE_DISPLAY_RENDER_UI;
+ static DeclareMemType MTYPE_DISPLAY_RENDER_ATTACHMENTS;
+
+ static DeclareMemType MTYPE_VERTEX_DATA;
+ static DeclareMemType MTYPE_VERTEX_CONSTRUCTOR;
+ static DeclareMemType MTYPE_VERTEX_DESTRUCTOR;
+ static DeclareMemType MTYPE_VERTEX_CREATE_VERTICES;
+ static DeclareMemType MTYPE_VERTEX_CREATE_INDICES;
+ static DeclareMemType MTYPE_VERTEX_DESTROY_BUFFER;
+ static DeclareMemType MTYPE_VERTEX_DESTROY_INDICES;
+ static DeclareMemType MTYPE_VERTEX_UPDATE_VERTS;
+ static DeclareMemType MTYPE_VERTEX_UPDATE_INDICES;
+ static DeclareMemType MTYPE_VERTEX_ALLOCATE_BUFFER;
+ static DeclareMemType MTYPE_VERTEX_RESIZE_BUFFER;
+ static DeclareMemType MTYPE_VERTEX_MAP_BUFFER;
+ static DeclareMemType MTYPE_VERTEX_MAP_BUFFER_VERTICES;
+ static DeclareMemType MTYPE_VERTEX_MAP_BUFFER_INDICES;
+ static DeclareMemType MTYPE_VERTEX_UNMAP_BUFFER;
+ static DeclareMemType MTYPE_VERTEX_SET_STRIDE;
+ static DeclareMemType MTYPE_VERTEX_SET_BUFFER;
+ static DeclareMemType MTYPE_VERTEX_SETUP_VERTEX_BUFFER;
+ static DeclareMemType MTYPE_VERTEX_CLEANUP_CLASS;
+
+ static DeclareMemType MTYPE_SPACE_PARTITION;
+
+ static DeclareMemType MTYPE_PIPELINE;
+ static DeclareMemType MTYPE_PIPELINE_INIT;
+ static DeclareMemType MTYPE_PIPELINE_CREATE_BUFFERS;
+ static DeclareMemType MTYPE_PIPELINE_RESTORE_GL;
+ static DeclareMemType MTYPE_PIPELINE_UNLOAD_SHADERS;
+ static DeclareMemType MTYPE_PIPELINE_LIGHTING_DETAIL;
+ static DeclareMemType MTYPE_PIPELINE_GET_POOL_TYPE;
+ static DeclareMemType MTYPE_PIPELINE_ADD_POOL;
+ static DeclareMemType MTYPE_PIPELINE_ALLOCATE_DRAWABLE;
+ static DeclareMemType MTYPE_PIPELINE_ADD_OBJECT;
+ static DeclareMemType MTYPE_PIPELINE_CREATE_OBJECTS;
+ static DeclareMemType MTYPE_PIPELINE_UPDATE_MOVE;
+ static DeclareMemType MTYPE_PIPELINE_UPDATE_GEOM;
+ static DeclareMemType MTYPE_PIPELINE_MARK_VISIBLE;
+ static DeclareMemType MTYPE_PIPELINE_MARK_MOVED;
+ static DeclareMemType MTYPE_PIPELINE_MARK_SHIFT;
+ static DeclareMemType MTYPE_PIPELINE_SHIFT_OBJECTS;
+ static DeclareMemType MTYPE_PIPELINE_MARK_TEXTURED;
+ static DeclareMemType MTYPE_PIPELINE_MARK_REBUILD;
+ static DeclareMemType MTYPE_PIPELINE_UPDATE_CULL;
+ static DeclareMemType MTYPE_PIPELINE_STATE_SORT;
+ static DeclareMemType MTYPE_PIPELINE_POST_SORT;
+
+ static DeclareMemType MTYPE_PIPELINE_RENDER_HUD_ELS;
+ static DeclareMemType MTYPE_PIPELINE_RENDER_HL;
+ static DeclareMemType MTYPE_PIPELINE_RENDER_GEOM;
+ static DeclareMemType MTYPE_PIPELINE_RENDER_GEOM_DEFFERRED;
+ static DeclareMemType MTYPE_PIPELINE_RENDER_GEOM_POST_DEF;
+ static DeclareMemType MTYPE_PIPELINE_RENDER_GEOM_SHADOW;
+ static DeclareMemType MTYPE_PIPELINE_RENDER_SELECT;
+ static DeclareMemType MTYPE_PIPELINE_REBUILD_POOLS;
+ static DeclareMemType MTYPE_PIPELINE_QUICK_LOOKUP;
+ static DeclareMemType MTYPE_PIPELINE_RENDER_OBJECTS;
+ static DeclareMemType MTYPE_PIPELINE_GENERATE_IMPOSTOR;
+ static DeclareMemType MTYPE_PIPELINE_RENDER_BLOOM;
+
+ static DeclareMemType MTYPE_UPKEEP_POOLS;
+
+ static DeclareMemType MTYPE_AVATAR;
+ static DeclareMemType MTYPE_AVATAR_MESH;
+ static DeclareMemType MTYPE_PARTICLES;
+ static DeclareMemType MTYPE_REGIONS;
+
+ static DeclareMemType MTYPE_INVENTORY;
+ static DeclareMemType MTYPE_INVENTORY_DRAW;
+ static DeclareMemType MTYPE_INVENTORY_BUILD_NEW_VIEWS;
+ static DeclareMemType MTYPE_INVENTORY_DO_FOLDER;
+ static DeclareMemType MTYPE_INVENTORY_POST_BUILD;
+ static DeclareMemType MTYPE_INVENTORY_FROM_XML;
+ static DeclareMemType MTYPE_INVENTORY_CREATE_NEW_ITEM;
+ static DeclareMemType MTYPE_INVENTORY_VIEW_INIT;
+ static DeclareMemType MTYPE_INVENTORY_VIEW_SHOW;
+ static DeclareMemType MTYPE_INVENTORY_VIEW_TOGGLE;
+
+ static DeclareMemType MTYPE_ANIMATION;
+ static DeclareMemType MTYPE_VOLUME;
+ static DeclareMemType MTYPE_PRIMITIVE;
+
+ static DeclareMemType MTYPE_SCRIPT;
+ static DeclareMemType MTYPE_SCRIPT_RUN;
+ static DeclareMemType MTYPE_SCRIPT_BYTECODE;
+
+ static DeclareMemType MTYPE_IO_PUMP;
+ static DeclareMemType MTYPE_IO_TCP;
+ static DeclareMemType MTYPE_IO_BUFFER;
+ static DeclareMemType MTYPE_IO_HTTP_SERVER;
+ static DeclareMemType MTYPE_IO_SD_SERVER;
+ static DeclareMemType MTYPE_IO_SD_CLIENT;
+ static DeclareMemType MTYPE_IO_URL_REQUEST;
+
+ static DeclareMemType MTYPE_DIRECTX_INIT;
+
+ static DeclareMemType MTYPE_TEMP1;
+ static DeclareMemType MTYPE_TEMP2;
+ static DeclareMemType MTYPE_TEMP3;
+ static DeclareMemType MTYPE_TEMP4;
+ static DeclareMemType MTYPE_TEMP5;
+ static DeclareMemType MTYPE_TEMP6;
+ static DeclareMemType MTYPE_TEMP7;
+ static DeclareMemType MTYPE_TEMP8;
+ static DeclareMemType MTYPE_TEMP9;
+
+ static DeclareMemType MTYPE_OTHER; // Special; used by display code
+
+ S32 mTypeIndex;
};
//----------------------------------------------------------------------------
diff --git a/indra/llcommon/llmetrics.cpp b/indra/llcommon/llmetrics.cpp
index 8db3284c42..30e5d435ae 100644
--- a/indra/llcommon/llmetrics.cpp
+++ b/indra/llcommon/llmetrics.cpp
@@ -71,7 +71,7 @@ void LLMetricsImpl::recordEventDetails(const std::string& location,
metrics["location"] = location;
metrics["stats"] = stats;
- llinfos << "LLMETRICS: " << LLSDNotationStreamer(metrics) << llendl;
+ llinfos << "LLMETRICS: " << (LLSDNotationStreamer(metrics)) << llendl;
}
// Store this:
diff --git a/indra/llcommon/lloptioninterface.cpp b/indra/llcommon/lloptioninterface.cpp
new file mode 100644
index 0000000000..68c1ff1c41
--- /dev/null
+++ b/indra/llcommon/lloptioninterface.cpp
@@ -0,0 +1,39 @@
+/**
+ * @file lloptioninterface.cpp
+ * @brief
+ *
+ * $LicenseInfo:firstyear=2009&license=viewergpl$
+ *
+ * Copyright (c) 2009, Linden Research, Inc.
+ *
+ * Second Life Viewer Source Code
+ * The source code in this file ("Source Code") is provided by Linden Lab
+ * to you under the terms of the GNU General Public License, version 2.0
+ * ("GPL"), unless you have obtained a separate licensing agreement
+ * ("Other License"), formally executed by you and Linden Lab. Terms of
+ * the GPL can be found in doc/GPL-license.txt in this distribution, or
+ * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
+ *
+ * There are special exceptions to the terms and conditions of the GPL as
+ * it is applied to this Source Code. View the full text of the exception
+ * in the file doc/FLOSS-exception.txt in this software distribution, or
+ * online at
+ * http://secondlifegrid.net/programs/open_source/licensing/flossexception
+ *
+ * By copying, modifying or distributing this software, you acknowledge
+ * that you have read and understood your obligations described above,
+ * and agree to abide by those obligations.
+ *
+ * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+ * COMPLETENESS OR PERFORMANCE.
+ * $/LicenseInfo$
+ */
+
+#include "lloptioninterface.h"
+
+
+LLOptionInterface::~LLOptionInterface()
+{
+
+}
diff --git a/indra/llcommon/lloptioninterface.h b/indra/llcommon/lloptioninterface.h
new file mode 100644
index 0000000000..4faf95f5e1
--- /dev/null
+++ b/indra/llcommon/lloptioninterface.h
@@ -0,0 +1,46 @@
+/**
+ * @file lloptioninterface.h
+ * @brief
+ *
+ * $LicenseInfo:firstyear=2009&license=viewergpl$
+ *
+ * Copyright (c) 2009, Linden Research, Inc.
+ *
+ * Second Life Viewer Source Code
+ * The source code in this file ("Source Code") is provided by Linden Lab
+ * to you under the terms of the GNU General Public License, version 2.0
+ * ("GPL"), unless you have obtained a separate licensing agreement
+ * ("Other License"), formally executed by you and Linden Lab. Terms of
+ * the GPL can be found in doc/GPL-license.txt in this distribution, or
+ * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
+ *
+ * There are special exceptions to the terms and conditions of the GPL as
+ * it is applied to this Source Code. View the full text of the exception
+ * in the file doc/FLOSS-exception.txt in this software distribution, or
+ * online at
+ * http://secondlifegrid.net/programs/open_source/licensing/flossexception
+ *
+ * By copying, modifying or distributing this software, you acknowledge
+ * that you have read and understood your obligations described above,
+ * and agree to abide by those obligations.
+ *
+ * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+ * COMPLETENESS OR PERFORMANCE.
+ * $/LicenseInfo$
+ */
+
+#ifndef LL_LLOPTIONINTERFACE_H
+#define LL_LLOPTIONINTERFACE_H
+
+#include "linden_common.h"
+
+class LLSD;
+class LLOptionInterface
+{
+public:
+ virtual ~LLOptionInterface() = 0;
+ virtual LLSD getOption(const std::string& name) const = 0;
+};
+
+#endif
diff --git a/indra/llcommon/llpointer.h b/indra/llcommon/llpointer.h
new file mode 100644
index 0000000000..2c37eadcc6
--- /dev/null
+++ b/indra/llcommon/llpointer.h
@@ -0,0 +1,177 @@
+/**
+ * @file llpointer.h
+ * @brief A reference-counted pointer for objects derived from LLRefCount
+ *
+ * $LicenseInfo:firstyear=2002&license=viewergpl$
+ *
+ * Copyright (c) 2002-2009, Linden Research, Inc.
+ *
+ * Second Life Viewer Source Code
+ * The source code in this file ("Source Code") is provided by Linden Lab
+ * to you under the terms of the GNU General Public License, version 2.0
+ * ("GPL"), unless you have obtained a separate licensing agreement
+ * ("Other License"), formally executed by you and Linden Lab. Terms of
+ * the GPL can be found in doc/GPL-license.txt in this distribution, or
+ * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
+ *
+ * There are special exceptions to the terms and conditions of the GPL as
+ * it is applied to this Source Code. View the full text of the exception
+ * in the file doc/FLOSS-exception.txt in this software distribution, or
+ * online at
+ * http://secondlifegrid.net/programs/open_source/licensing/flossexception
+ *
+ * By copying, modifying or distributing this software, you acknowledge
+ * that you have read and understood your obligations described above,
+ * and agree to abide by those obligations.
+ *
+ * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+ * COMPLETENESS OR PERFORMANCE.
+ * $/LicenseInfo$
+ */
+#ifndef LLPOINTER_H
+#define LLPOINTER_H
+
+#include "llerror.h" // *TODO: consider eliminating this
+
+//----------------------------------------------------------------------------
+// RefCount objects should generally only be accessed by way of LLPointer<>'s
+// NOTE: LLPointer<LLFoo> x = new LLFoo(); MAY NOT BE THREAD SAFE
+// if LLFoo::LLFoo() does anything like put itself in an update queue.
+// The queue may get accessed before it gets assigned to x.
+// The correct implementation is:
+// LLPointer<LLFoo> x = new LLFoo; // constructor does not do anything interesting
+// x->instantiate(); // does stuff like place x into an update queue
+
+// see llthread.h for LLThreadSafeRefCount
+
+//----------------------------------------------------------------------------
+
+// Note: relies on Type having ref() and unref() methods
+template <class Type> class LLPointer
+{
+public:
+
+ LLPointer() :
+ mPointer(NULL)
+ {
+ }
+
+ LLPointer(Type* ptr) :
+ mPointer(ptr)
+ {
+ ref();
+ }
+
+ LLPointer(const LLPointer<Type>& ptr) :
+ mPointer(ptr.mPointer)
+ {
+ ref();
+ }
+
+ // support conversion up the type hierarchy. See Item 45 in Effective C++, 3rd Ed.
+ template<typename Subclass>
+ LLPointer(const LLPointer<Subclass>& ptr) :
+ mPointer(ptr.get())
+ {
+ ref();
+ }
+
+ ~LLPointer()
+ {
+ unref();
+ }
+
+ Type* get() const { return mPointer; }
+ const Type* operator->() const { return mPointer; }
+ Type* operator->() { return mPointer; }
+ const Type& operator*() const { return *mPointer; }
+ Type& operator*() { return *mPointer; }
+
+ operator BOOL() const { return (mPointer != NULL); }
+ operator bool() const { return (mPointer != NULL); }
+ bool operator!() const { return (mPointer == NULL); }
+ bool isNull() const { return (mPointer == NULL); }
+ bool notNull() const { return (mPointer != NULL); }
+
+ operator Type*() const { return mPointer; }
+ operator const Type*() const { return mPointer; }
+ bool operator !=(Type* ptr) const { return (mPointer != ptr); }
+ bool operator ==(Type* ptr) const { return (mPointer == ptr); }
+ bool operator ==(const LLPointer<Type>& ptr) const { return (mPointer == ptr.mPointer); }
+ bool operator < (const LLPointer<Type>& ptr) const { return (mPointer < ptr.mPointer); }
+ bool operator > (const LLPointer<Type>& ptr) const { return (mPointer > ptr.mPointer); }
+
+ LLPointer<Type>& operator =(Type* ptr)
+ {
+ if( mPointer != ptr )
+ {
+ unref();
+ mPointer = ptr;
+ ref();
+ }
+
+ return *this;
+ }
+
+ LLPointer<Type>& operator =(const LLPointer<Type>& ptr)
+ {
+ if( mPointer != ptr.mPointer )
+ {
+ unref();
+ mPointer = ptr.mPointer;
+ ref();
+ }
+ return *this;
+ }
+
+ // support assignment up the type hierarchy. See Item 45 in Effective C++, 3rd Ed.
+ template<typename Subclass>
+ LLPointer<Type>& operator =(const LLPointer<Subclass>& ptr)
+ {
+ if( mPointer != ptr.get() )
+ {
+ unref();
+ mPointer = ptr.get();
+ ref();
+ }
+ return *this;
+ }
+
+ // Just exchange the pointers, which will not change the reference counts.
+ static void swap(LLPointer<Type>& a, LLPointer<Type>& b)
+ {
+ Type* temp = a.mPointer;
+ a.mPointer = b.mPointer;
+ b.mPointer = temp;
+ }
+
+protected:
+ void ref()
+ {
+ if (mPointer)
+ {
+ mPointer->ref();
+ }
+ }
+
+ void unref()
+ {
+ if (mPointer)
+ {
+ Type *tempp = mPointer;
+ mPointer = NULL;
+ tempp->unref();
+ if (mPointer != NULL)
+ {
+ llwarns << "Unreference did assignment to non-NULL because of destructor" << llendl;
+ unref();
+ }
+ }
+ }
+
+protected:
+ Type* mPointer;
+};
+
+#endif
diff --git a/indra/llcommon/llpreprocessor.h b/indra/llcommon/llpreprocessor.h
index 2e4fd4787a..4401be1679 100644
--- a/indra/llcommon/llpreprocessor.h
+++ b/indra/llcommon/llpreprocessor.h
@@ -127,8 +127,10 @@ using snprintf_hack::snprintf;
#pragma warning( 3 : 4702 ) // "unreachable code" Treat this as level 3, not level 4.
#pragma warning( 3 : 4189 ) // "local variable initialized but not referenced" Treat this as level 3, not level 4.
//#pragma warning( 3 : 4018 ) // "signed/unsigned mismatch" Treat this as level 3, not level 4.
+#pragma warning( 3 : 4263 ) // 'function' : member function does not override any base class virtual member function
+#pragma warning( 3 : 4264 ) // "'virtual_function' : no override available for virtual member function from base 'class'; function is hidden"
#pragma warning( 3 : 4265 ) // "class has virtual functions, but destructor is not virtual"
-#pragma warning( disable : 4786 ) // silly MS warning deep inside their <map> include file
+#pragma warning( 3 : 4266 ) // 'function' : no override available for virtual member function from base 'type'; function is hidden
#pragma warning( disable : 4284 ) // silly MS warning deep inside their <map> include file
#pragma warning( disable : 4503 ) // 'decorated name length exceeded, name was truncated'. Does not seem to affect compilation.
#pragma warning( disable : 4800 ) // 'BOOL' : forcing value to bool 'true' or 'false' (performance warning)
diff --git a/indra/llcommon/llprocesslauncher.cpp b/indra/llcommon/llprocesslauncher.cpp
new file mode 100644
index 0000000000..f0315e92eb
--- /dev/null
+++ b/indra/llcommon/llprocesslauncher.cpp
@@ -0,0 +1,344 @@
+/**
+ * @file llprocesslauncher.cpp
+ * @brief Utility class for launching, terminating, and tracking the state of processes.
+ *
+ * $LicenseInfo:firstyear=2008&license=viewergpl$
+ *
+ * Copyright (c) 2008, Linden Research, Inc.
+ *
+ * Second Life Viewer Source Code
+ * The source code in this file ("Source Code") is provided by Linden Lab
+ * to you under the terms of the GNU General Public License, version 2.0
+ * ("GPL"), unless you have obtained a separate licensing agreement
+ * ("Other License"), formally executed by you and Linden Lab. Terms of
+ * the GPL can be found in doc/GPL-license.txt in this distribution, or
+ * online at http://secondlife.com/developers/opensource/gplv2
+ *
+ * There are special exceptions to the terms and conditions of the GPL as
+ * it is applied to this Source Code. View the full text of the exception
+ * in the file doc/FLOSS-exception.txt in this software distribution, or
+ * online at http://secondlife.com/developers/opensource/flossexception
+ *
+ * By copying, modifying or distributing this software, you acknowledge
+ * that you have read and understood your obligations described above,
+ * and agree to abide by those obligations.
+ *
+ * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+ * COMPLETENESS OR PERFORMANCE.
+ * $/LicenseInfo$
+ */
+
+#include "linden_common.h"
+
+#include "llprocesslauncher.h"
+
+#include <iostream>
+#if LL_DARWIN || LL_LINUX
+// not required or present on Win32
+#include <sys/wait.h>
+#endif
+
+LLProcessLauncher::LLProcessLauncher()
+{
+#if LL_WINDOWS
+ mProcessHandle = 0;
+#else
+ mProcessID = 0;
+#endif
+}
+
+LLProcessLauncher::~LLProcessLauncher()
+{
+ kill();
+}
+
+void LLProcessLauncher::setExecutable(const std::string &executable)
+{
+ mExecutable = executable;
+}
+
+void LLProcessLauncher::setWorkingDirectory(const std::string &dir)
+{
+ mWorkingDir = dir;
+}
+
+void LLProcessLauncher::clearArguments()
+{
+ mLaunchArguments.clear();
+}
+
+void LLProcessLauncher::addArgument(const std::string &arg)
+{
+ mLaunchArguments.push_back(arg);
+}
+
+void LLProcessLauncher::addArgument(const char *arg)
+{
+ mLaunchArguments.push_back(std::string(arg));
+}
+
+#if LL_WINDOWS
+
+int LLProcessLauncher::launch(void)
+{
+ // If there was already a process associated with this object, kill it.
+ kill();
+ orphan();
+
+ int result = 0;
+
+ PROCESS_INFORMATION pinfo;
+ STARTUPINFOA sinfo;
+ memset(&sinfo, 0, sizeof(sinfo));
+
+ std::string args = mExecutable;
+ for(int i = 0; i < (int)mLaunchArguments.size(); i++)
+ {
+ args += " ";
+ args += mLaunchArguments[i];
+ }
+
+ // So retarded. Windows requires that the second parameter to CreateProcessA be a writable (non-const) string...
+ char *args2 = new char[args.size() + 1];
+ strcpy(args2, args.c_str());
+
+ if( ! CreateProcessA( NULL, args2, NULL, NULL, FALSE, 0, NULL, NULL, &sinfo, &pinfo ) )
+ {
+ // TODO: do better than returning the OS-specific error code on failure...
+ result = GetLastError();
+ if(result == 0)
+ {
+ // Make absolutely certain we return a non-zero value on failure.
+ result = -1;
+ }
+ }
+ else
+ {
+ // foo = pinfo.dwProcessId; // get your pid here if you want to use it later on
+ // CloseHandle(pinfo.hProcess); // stops leaks - nothing else
+ mProcessHandle = pinfo.hProcess;
+ CloseHandle(pinfo.hThread); // stops leaks - nothing else
+ }
+
+ delete[] args2;
+
+ return result;
+}
+
+bool LLProcessLauncher::isRunning(void)
+{
+ if(mProcessHandle != 0)
+ {
+ DWORD waitresult = WaitForSingleObject(mProcessHandle, 0);
+ if(waitresult == WAIT_OBJECT_0)
+ {
+ // the process has completed.
+ mProcessHandle = 0;
+ }
+ }
+
+ return (mProcessHandle != 0);
+}
+bool LLProcessLauncher::kill(void)
+{
+ bool result = true;
+
+ if(mProcessHandle != 0)
+ {
+ TerminateProcess(mProcessHandle,0);
+
+ if(isRunning())
+ {
+ result = false;
+ }
+ }
+
+ return result;
+}
+
+void LLProcessLauncher::orphan(void)
+{
+ // Forget about the process
+ mProcessHandle = 0;
+}
+
+// static
+void LLProcessLauncher::reap(void)
+{
+ // No actions necessary on Windows.
+}
+
+#else // Mac and linux
+
+#include <signal.h>
+#include <fcntl.h>
+#include <errno.h>
+
+static std::list<pid_t> sZombies;
+
+// Attempt to reap a process ID -- returns true if the process has exited and been reaped, false otherwise.
+static bool reap_pid(pid_t pid)
+{
+ bool result = false;
+
+ pid_t wait_result = ::waitpid(pid, NULL, WNOHANG);
+ if(wait_result == pid)
+ {
+ result = true;
+ }
+ else if(wait_result == -1)
+ {
+ if(errno == ECHILD)
+ {
+ // No such process -- this may mean we're ignoring SIGCHILD.
+ result = true;
+ }
+ }
+
+ return result;
+}
+
+int LLProcessLauncher::launch(void)
+{
+ // If there was already a process associated with this object, kill it.
+ kill();
+ orphan();
+
+ int result = 0;
+ int current_wd = -1;
+
+ // create an argv vector for the child process
+ const char ** fake_argv = new const char *[mLaunchArguments.size() + 2]; // 1 for the executable path, 1 for the NULL terminator
+
+ int i = 0;
+
+ // add the executable path
+ fake_argv[i++] = mExecutable.c_str();
+
+ // and any arguments
+ for(int j=0; j < mLaunchArguments.size(); j++)
+ fake_argv[i++] = mLaunchArguments[j].c_str();
+
+ // terminate with a null pointer
+ fake_argv[i] = NULL;
+
+ if(!mWorkingDir.empty())
+ {
+ // save the current working directory
+ current_wd = ::open(".", O_RDONLY);
+
+ // and change to the one the child will be executed in
+ if (::chdir(mWorkingDir.c_str()))
+ {
+ // chdir failed
+ }
+ }
+
+ // flush all buffers before the child inherits them
+ ::fflush(NULL);
+
+ pid_t id = vfork();
+ if(id == 0)
+ {
+ // child process
+
+ ::execv(mExecutable.c_str(), (char * const *)fake_argv);
+
+ // If we reach this point, the exec failed.
+ // Use _exit() instead of exit() per the vfork man page.
+ _exit(0);
+ }
+
+ // parent process
+
+ if(current_wd >= 0)
+ {
+ // restore the previous working directory
+ if (::fchdir(current_wd))
+ {
+ // chdir failed
+ }
+ ::close(current_wd);
+ }
+
+ delete[] fake_argv;
+
+ mProcessID = id;
+
+ // At this point, the child process will have been created (since that's how vfork works -- the child borrowed our execution context until it forked)
+ // If the process doesn't exist at this point, the exec failed.
+ if(!isRunning())
+ {
+ result = -1;
+ }
+
+ return result;
+}
+
+bool LLProcessLauncher::isRunning(void)
+{
+ if(mProcessID != 0)
+ {
+ // Check whether the process has exited, and reap it if it has.
+ if(reap_pid(mProcessID))
+ {
+ // the process has exited.
+ mProcessID = 0;
+ }
+ }
+
+ return (mProcessID != 0);
+}
+
+bool LLProcessLauncher::kill(void)
+{
+ bool result = true;
+
+ if(mProcessID != 0)
+ {
+ // Try to kill the process. We'll do approximately the same thing whether the kill returns an error or not, so we ignore the result.
+ (void)::kill(mProcessID, SIGTERM);
+
+ // This will have the side-effect of reaping the zombie if the process has exited.
+ if(isRunning())
+ {
+ result = false;
+ }
+ }
+
+ return result;
+}
+
+void LLProcessLauncher::orphan(void)
+{
+ // Disassociate the process from this object
+ if(mProcessID != 0)
+ {
+ // We may still need to reap the process's zombie eventually
+ sZombies.push_back(mProcessID);
+
+ mProcessID = 0;
+ }
+}
+
+// static
+void LLProcessLauncher::reap(void)
+{
+ // Attempt to real all saved process ID's.
+
+ std::list<pid_t>::iterator iter = sZombies.begin();
+ while(iter != sZombies.end())
+ {
+ if(reap_pid(*iter))
+ {
+ iter = sZombies.erase(iter);
+ }
+ else
+ {
+ iter++;
+ }
+ }
+}
+
+#endif
diff --git a/indra/llcommon/llprocesslauncher.h b/indra/llcommon/llprocesslauncher.h
new file mode 100644
index 0000000000..a1b8e22691
--- /dev/null
+++ b/indra/llcommon/llprocesslauncher.h
@@ -0,0 +1,85 @@
+/**
+ * @file llprocesslauncher.h
+ * @brief Utility class for launching, terminating, and tracking the state of processes.
+ *
+ * $LicenseInfo:firstyear=2008&license=viewergpl$
+ *
+ * Copyright (c) 2008, Linden Research, Inc.
+ *
+ * Second Life Viewer Source Code
+ * The source code in this file ("Source Code") is provided by Linden Lab
+ * to you under the terms of the GNU General Public License, version 2.0
+ * ("GPL"), unless you have obtained a separate licensing agreement
+ * ("Other License"), formally executed by you and Linden Lab. Terms of
+ * the GPL can be found in doc/GPL-license.txt in this distribution, or
+ * online at http://secondlife.com/developers/opensource/gplv2
+ *
+ * There are special exceptions to the terms and conditions of the GPL as
+ * it is applied to this Source Code. View the full text of the exception
+ * in the file doc/FLOSS-exception.txt in this software distribution, or
+ * online at http://secondlife.com/developers/opensource/flossexception
+ *
+ * By copying, modifying or distributing this software, you acknowledge
+ * that you have read and understood your obligations described above,
+ * and agree to abide by those obligations.
+ *
+ * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+ * COMPLETENESS OR PERFORMANCE.
+ * $/LicenseInfo$
+ */
+
+#ifndef LL_LLPROCESSLAUNCHER_H
+#define LL_LLPROCESSLAUNCHER_H
+
+#if LL_WINDOWS
+#include <windows.h>
+#endif
+
+
+/*
+ LLProcessLauncher handles launching external processes with specified command line arguments.
+ It also keeps track of whether the process is still running, and can kill it if required.
+*/
+
+class LLProcessLauncher
+{
+ LOG_CLASS(LLProcessLauncher);
+public:
+ LLProcessLauncher();
+ virtual ~LLProcessLauncher();
+
+ void setExecutable(const std::string &executable);
+ void setWorkingDirectory(const std::string &dir);
+
+ void clearArguments();
+ void addArgument(const std::string &arg);
+ void addArgument(const char *arg);
+
+ int launch(void);
+ bool isRunning(void);
+
+ // Attempt to kill the process -- returns true if the process is no longer running when it returns.
+ // Note that even if this returns false, the process may exit some time after it's called.
+ bool kill(void);
+
+ // Use this if you want the external process to continue execution after the LLProcessLauncher instance controlling it is deleted.
+ // Normally, the destructor will attempt to kill the process and wait for termination.
+ // This should only be used if the viewer is about to exit -- otherwise, the child process will become a zombie after it exits.
+ void orphan(void);
+
+ // This needs to be called periodically on Mac/Linux to clean up zombie processes.
+ static void reap(void);
+private:
+ std::string mExecutable;
+ std::string mWorkingDir;
+ std::vector<std::string> mLaunchArguments;
+
+#if LL_WINDOWS
+ HANDLE mProcessHandle;
+#else
+ pid_t mProcessID;
+#endif
+};
+
+#endif // LL_LLPROCESSLAUNCHER_H
diff --git a/indra/llcommon/llptrto.cpp b/indra/llcommon/llptrto.cpp
new file mode 100644
index 0000000000..ce93f09489
--- /dev/null
+++ b/indra/llcommon/llptrto.cpp
@@ -0,0 +1,108 @@
+/**
+ * @file llptrto.cpp
+ * @author Nat Goodspeed
+ * @date 2008-08-20
+ * @brief Test for llptrto.h
+ *
+ * $LicenseInfo:firstyear=2008&license=viewergpl$
+ *
+ * Copyright (c) 2008-2009, Linden Research, Inc.
+ *
+ * Second Life Viewer Source Code
+ * The source code in this file ("Source Code") is provided by Linden Lab
+ * to you under the terms of the GNU General Public License, version 2.0
+ * ("GPL"), unless you have obtained a separate licensing agreement
+ * ("Other License"), formally executed by you and Linden Lab. Terms of
+ * the GPL can be found in doc/GPL-license.txt in this distribution, or
+ * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
+ *
+ * There are special exceptions to the terms and conditions of the GPL as
+ * it is applied to this Source Code. View the full text of the exception
+ * in the file doc/FLOSS-exception.txt in this software distribution, or
+ * online at
+ * http://secondlifegrid.net/programs/open_source/licensing/flossexception
+ *
+ * By copying, modifying or distributing this software, you acknowledge
+ * that you have read and understood your obligations described above,
+ * and agree to abide by those obligations.
+ *
+ * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+ * COMPLETENESS OR PERFORMANCE.
+ * $/LicenseInfo$
+ */
+
+// Precompiled header
+#include "linden_common.h"
+// associated header
+#include "llptrto.h"
+// STL headers
+// std headers
+// external library headers
+#include <boost/type_traits/is_same.hpp>
+#include <boost/static_assert.hpp>
+// other Linden headers
+#include "llmemory.h"
+
+// a refcounted class
+class RCFoo: public LLRefCount
+{
+public:
+ RCFoo() {}
+};
+
+// a refcounted subclass
+class RCSubFoo: public RCFoo
+{
+public:
+ RCSubFoo() {}
+};
+
+// a refcounted class using the other refcount base class
+class TSRCFoo: public LLThreadSafeRefCount
+{
+public:
+ TSRCFoo() {}
+};
+
+// a non-refcounted class
+class Bar
+{
+public:
+ Bar() {}
+};
+
+// a non-refcounted subclass
+class SubBar: public Bar
+{
+public:
+ SubBar() {}
+};
+
+int main(int argc, char *argv[])
+{
+ // test LLPtrTo<>
+ BOOST_STATIC_ASSERT((boost::is_same<LLPtrTo<RCFoo>::type, LLPointer<RCFoo> >::value));
+ BOOST_STATIC_ASSERT((boost::is_same<LLPtrTo<RCSubFoo>::type, LLPointer<RCSubFoo> >::value));
+ BOOST_STATIC_ASSERT((boost::is_same<LLPtrTo<TSRCFoo>::type, LLPointer<TSRCFoo> >::value));
+ BOOST_STATIC_ASSERT((boost::is_same<LLPtrTo<Bar>::type, Bar*>::value));
+ BOOST_STATIC_ASSERT((boost::is_same<LLPtrTo<SubBar>::type, SubBar*>::value));
+ BOOST_STATIC_ASSERT((boost::is_same<LLPtrTo<int>::type, int*>::value));
+
+ // Test LLRemovePointer<>. Note that we remove both pointer variants from
+ // each kind of type, regardless of whether the variant makes sense.
+ BOOST_STATIC_ASSERT((boost::is_same<LLRemovePointer<RCFoo*>::type, RCFoo>::value));
+ BOOST_STATIC_ASSERT((boost::is_same<LLRemovePointer< LLPointer<RCFoo> >::type, RCFoo>::value));
+ BOOST_STATIC_ASSERT((boost::is_same<LLRemovePointer<RCSubFoo*>::type, RCSubFoo>::value));
+ BOOST_STATIC_ASSERT((boost::is_same<LLRemovePointer< LLPointer<RCSubFoo> >::type, RCSubFoo>::value));
+ BOOST_STATIC_ASSERT((boost::is_same<LLRemovePointer<TSRCFoo*>::type, TSRCFoo>::value));
+ BOOST_STATIC_ASSERT((boost::is_same<LLRemovePointer< LLPointer<TSRCFoo> >::type, TSRCFoo>::value));
+ BOOST_STATIC_ASSERT((boost::is_same<LLRemovePointer<Bar*>::type, Bar>::value));
+ BOOST_STATIC_ASSERT((boost::is_same<LLRemovePointer< LLPointer<Bar> >::type, Bar>::value));
+ BOOST_STATIC_ASSERT((boost::is_same<LLRemovePointer<SubBar*>::type, SubBar>::value));
+ BOOST_STATIC_ASSERT((boost::is_same<LLRemovePointer< LLPointer<SubBar> >::type, SubBar>::value));
+ BOOST_STATIC_ASSERT((boost::is_same<LLRemovePointer<int*>::type, int>::value));
+ BOOST_STATIC_ASSERT((boost::is_same<LLRemovePointer< LLPointer<int> >::type, int>::value));
+
+ return 0;
+}
diff --git a/indra/llcommon/llptrto.h b/indra/llcommon/llptrto.h
new file mode 100644
index 0000000000..74c117a7f6
--- /dev/null
+++ b/indra/llcommon/llptrto.h
@@ -0,0 +1,93 @@
+/**
+ * @file llptrto.h
+ * @author Nat Goodspeed
+ * @date 2008-08-19
+ * @brief LLPtrTo<TARGET> is a template helper to pick either TARGET* or -- when
+ * TARGET is a subclass of LLRefCount or LLThreadSafeRefCount --
+ * LLPointer<TARGET>. LLPtrTo<> chooses whichever pointer type is best.
+ *
+ * $LicenseInfo:firstyear=2008&license=viewergpl$
+ *
+ * Copyright (c) 2008-2009, Linden Research, Inc.
+ *
+ * Second Life Viewer Source Code
+ * The source code in this file ("Source Code") is provided by Linden Lab
+ * to you under the terms of the GNU General Public License, version 2.0
+ * ("GPL"), unless you have obtained a separate licensing agreement
+ * ("Other License"), formally executed by you and Linden Lab. Terms of
+ * the GPL can be found in doc/GPL-license.txt in this distribution, or
+ * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
+ *
+ * There are special exceptions to the terms and conditions of the GPL as
+ * it is applied to this Source Code. View the full text of the exception
+ * in the file doc/FLOSS-exception.txt in this software distribution, or
+ * online at
+ * http://secondlifegrid.net/programs/open_source/licensing/flossexception
+ *
+ * By copying, modifying or distributing this software, you acknowledge
+ * that you have read and understood your obligations described above,
+ * and agree to abide by those obligations.
+ *
+ * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+ * COMPLETENESS OR PERFORMANCE.
+ * $/LicenseInfo$
+ */
+
+#if ! defined(LL_LLPTRTO_H)
+#define LL_LLPTRTO_H
+
+#include "llpointer.h"
+#include "llrefcount.h" // LLRefCount
+#include "llthread.h" // LLThreadSafeRefCount
+#include <boost/type_traits/is_base_of.hpp>
+#include <boost/type_traits/remove_pointer.hpp>
+#include <boost/utility/enable_if.hpp>
+
+/**
+ * LLPtrTo<TARGET>::type is either of two things:
+ *
+ * * When TARGET is a subclass of either LLRefCount or LLThreadSafeRefCount,
+ * LLPtrTo<TARGET>::type is LLPointer<TARGET>.
+ * * Otherwise, LLPtrTo<TARGET>::type is TARGET*.
+ *
+ * This way, a class template can use LLPtrTo<TARGET>::type to select an
+ * appropriate pointer type to store.
+ */
+template <class T, class ENABLE=void>
+struct LLPtrTo
+{
+ typedef T* type;
+};
+
+/// specialize for subclasses of LLRefCount
+template <class T>
+struct LLPtrTo<T, typename boost::enable_if< boost::is_base_of<LLRefCount, T> >::type>
+{
+ typedef LLPointer<T> type;
+};
+
+/// specialize for subclasses of LLThreadSafeRefCount
+template <class T>
+struct LLPtrTo<T, typename boost::enable_if< boost::is_base_of<LLThreadSafeRefCount, T> >::type>
+{
+ typedef LLPointer<T> type;
+};
+
+/**
+ * LLRemovePointer<PTRTYPE>::type gets you the underlying (pointee) type.
+ */
+template <typename PTRTYPE>
+struct LLRemovePointer
+{
+ typedef typename boost::remove_pointer<PTRTYPE>::type type;
+};
+
+/// specialize for LLPointer<SOMECLASS>
+template <typename SOMECLASS>
+struct LLRemovePointer< LLPointer<SOMECLASS> >
+{
+ typedef SOMECLASS type;
+};
+
+#endif /* ! defined(LL_LLPTRTO_H) */
diff --git a/indra/llcommon/llqueuedthread.cpp b/indra/llcommon/llqueuedthread.cpp
index cd53e701d2..3db5c36545 100644
--- a/indra/llcommon/llqueuedthread.cpp
+++ b/indra/llcommon/llqueuedthread.cpp
@@ -31,7 +31,9 @@
#include "linden_common.h"
#include "llqueuedthread.h"
+
#include "llstl.h"
+#include "lltimer.h" // ms_sleep()
//============================================================================
diff --git a/indra/llcommon/llrefcount.cpp b/indra/llcommon/llrefcount.cpp
new file mode 100644
index 0000000000..33b6875fb0
--- /dev/null
+++ b/indra/llcommon/llrefcount.cpp
@@ -0,0 +1,49 @@
+/**
+ * @file llrefcount.cpp
+ * @brief Base class for reference counted objects for use with LLPointer
+ *
+ * $LicenseInfo:firstyear=2002&license=viewergpl$
+ *
+ * Copyright (c) 2002-2009, Linden Research, Inc.
+ *
+ * Second Life Viewer Source Code
+ * The source code in this file ("Source Code") is provided by Linden Lab
+ * to you under the terms of the GNU General Public License, version 2.0
+ * ("GPL"), unless you have obtained a separate licensing agreement
+ * ("Other License"), formally executed by you and Linden Lab. Terms of
+ * the GPL can be found in doc/GPL-license.txt in this distribution, or
+ * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
+ *
+ * There are special exceptions to the terms and conditions of the GPL as
+ * it is applied to this Source Code. View the full text of the exception
+ * in the file doc/FLOSS-exception.txt in this software distribution, or
+ * online at
+ * http://secondlifegrid.net/programs/open_source/licensing/flossexception
+ *
+ * By copying, modifying or distributing this software, you acknowledge
+ * that you have read and understood your obligations described above,
+ * and agree to abide by those obligations.
+ *
+ * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+ * COMPLETENESS OR PERFORMANCE.
+ * $/LicenseInfo$
+ */
+#include "linden_common.h"
+
+#include "llrefcount.h"
+
+#include "llerror.h"
+
+LLRefCount::LLRefCount() :
+ mRef(0)
+{
+}
+
+LLRefCount::~LLRefCount()
+{
+ if (mRef != 0)
+ {
+ llerrs << "deleting non-zero reference" << llendl;
+ }
+}
diff --git a/indra/llcommon/llrefcount.h b/indra/llcommon/llrefcount.h
new file mode 100644
index 0000000000..d3597b454c
--- /dev/null
+++ b/indra/llcommon/llrefcount.h
@@ -0,0 +1,79 @@
+/**
+ * @file llrefcount.h
+ * @brief Base class for reference counted objects for use with LLPointer
+ *
+ * $LicenseInfo:firstyear=2002&license=viewergpl$
+ *
+ * Copyright (c) 2002-2009, Linden Research, Inc.
+ *
+ * Second Life Viewer Source Code
+ * The source code in this file ("Source Code") is provided by Linden Lab
+ * to you under the terms of the GNU General Public License, version 2.0
+ * ("GPL"), unless you have obtained a separate licensing agreement
+ * ("Other License"), formally executed by you and Linden Lab. Terms of
+ * the GPL can be found in doc/GPL-license.txt in this distribution, or
+ * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
+ *
+ * There are special exceptions to the terms and conditions of the GPL as
+ * it is applied to this Source Code. View the full text of the exception
+ * in the file doc/FLOSS-exception.txt in this software distribution, or
+ * online at
+ * http://secondlifegrid.net/programs/open_source/licensing/flossexception
+ *
+ * By copying, modifying or distributing this software, you acknowledge
+ * that you have read and understood your obligations described above,
+ * and agree to abide by those obligations.
+ *
+ * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+ * COMPLETENESS OR PERFORMANCE.
+ * $/LicenseInfo$
+ */
+#ifndef LLREFCOUNT_H
+#define LLREFCOUNT_H
+
+#include <boost/noncopyable.hpp>
+
+//----------------------------------------------------------------------------
+// RefCount objects should generally only be accessed by way of LLPointer<>'s
+// see llthread.h for LLThreadSafeRefCount
+//----------------------------------------------------------------------------
+
+class LLRefCount
+{
+protected:
+ LLRefCount(const LLRefCount& other); // no implementation
+private:
+ LLRefCount& operator=(const LLRefCount&); // no implementation
+protected:
+ virtual ~LLRefCount(); // use unref()
+
+public:
+ LLRefCount();
+
+ void ref()
+ {
+ mRef++;
+ }
+
+ S32 unref()
+ {
+ llassert(mRef >= 1);
+ if (0 == --mRef)
+ {
+ delete this;
+ return 0;
+ }
+ return mRef;
+ }
+
+ S32 getNumRefs() const
+ {
+ return mRef;
+ }
+
+private:
+ S32 mRef;
+};
+
+#endif
diff --git a/indra/llcommon/llsafehandle.h b/indra/llcommon/llsafehandle.h
new file mode 100644
index 0000000000..1f7c682fd1
--- /dev/null
+++ b/indra/llcommon/llsafehandle.h
@@ -0,0 +1,167 @@
+/**
+ * @file llsafehandle.h
+ * @brief Reference-counted object where Object() is valid, not NULL.
+ *
+ * $LicenseInfo:firstyear=2002&license=viewergpl$
+ *
+ * Copyright (c) 2002-2009, Linden Research, Inc.
+ *
+ * Second Life Viewer Source Code
+ * The source code in this file ("Source Code") is provided by Linden Lab
+ * to you under the terms of the GNU General Public License, version 2.0
+ * ("GPL"), unless you have obtained a separate licensing agreement
+ * ("Other License"), formally executed by you and Linden Lab. Terms of
+ * the GPL can be found in doc/GPL-license.txt in this distribution, or
+ * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
+ *
+ * There are special exceptions to the terms and conditions of the GPL as
+ * it is applied to this Source Code. View the full text of the exception
+ * in the file doc/FLOSS-exception.txt in this software distribution, or
+ * online at
+ * http://secondlifegrid.net/programs/open_source/licensing/flossexception
+ *
+ * By copying, modifying or distributing this software, you acknowledge
+ * that you have read and understood your obligations described above,
+ * and agree to abide by those obligations.
+ *
+ * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+ * COMPLETENESS OR PERFORMANCE.
+ * $/LicenseInfo$
+ */
+#ifndef LLSAFEHANDLE_H
+#define LLSAFEHANDLE_H
+
+#include "llerror.h" // *TODO: consider eliminating this
+
+// Expands LLPointer to return a pointer to a special instance of class Type instead of NULL.
+// This is useful in instances where operations on NULL pointers are semantically safe and/or
+// when error checking occurs at a different granularity or in a different part of the code
+// than when referencing an object via a LLSafeHandle.
+
+template <class Type>
+class LLSafeHandle
+{
+public:
+ LLSafeHandle() :
+ mPointer(NULL)
+ {
+ }
+
+ LLSafeHandle(Type* ptr) :
+ mPointer(NULL)
+ {
+ assign(ptr);
+ }
+
+ LLSafeHandle(const LLSafeHandle<Type>& ptr) :
+ mPointer(NULL)
+ {
+ assign(ptr.mPointer);
+ }
+
+ // support conversion up the type hierarchy. See Item 45 in Effective C++, 3rd Ed.
+ template<typename Subclass>
+ LLSafeHandle(const LLSafeHandle<Subclass>& ptr) :
+ mPointer(NULL)
+ {
+ assign(ptr.get());
+ }
+
+ ~LLSafeHandle()
+ {
+ unref();
+ }
+
+ const Type* operator->() const { return nonNull(mPointer); }
+ Type* operator->() { return nonNull(mPointer); }
+
+ Type* get() const { return mPointer; }
+ // we disallow these operations as they expose our null objects to direct manipulation
+ // and bypass the reference counting semantics
+ //const Type& operator*() const { return *nonNull(mPointer); }
+ //Type& operator*() { return *nonNull(mPointer); }
+
+ operator BOOL() const { return mPointer != NULL; }
+ operator bool() const { return mPointer != NULL; }
+ bool operator!() const { return mPointer == NULL; }
+ bool isNull() const { return mPointer == NULL; }
+ bool notNull() const { return mPointer != NULL; }
+
+
+ operator Type*() const { return mPointer; }
+ operator const Type*() const { return mPointer; }
+ bool operator !=(Type* ptr) const { return (mPointer != ptr); }
+ bool operator ==(Type* ptr) const { return (mPointer == ptr); }
+ bool operator ==(const LLSafeHandle<Type>& ptr) const { return (mPointer == ptr.mPointer); }
+ bool operator < (const LLSafeHandle<Type>& ptr) const { return (mPointer < ptr.mPointer); }
+ bool operator > (const LLSafeHandle<Type>& ptr) const { return (mPointer > ptr.mPointer); }
+
+ LLSafeHandle<Type>& operator =(Type* ptr)
+ {
+ assign(ptr);
+ return *this;
+ }
+
+ LLSafeHandle<Type>& operator =(const LLSafeHandle<Type>& ptr)
+ {
+ assign(ptr.mPointer);
+ return *this;
+ }
+
+ // support assignment up the type hierarchy. See Item 45 in Effective C++, 3rd Ed.
+ template<typename Subclass>
+ LLSafeHandle<Type>& operator =(const LLSafeHandle<Subclass>& ptr)
+ {
+ assign(ptr.get());
+ return *this;
+ }
+
+public:
+ typedef Type* (*NullFunc)();
+ static const NullFunc sNullFunc;
+
+protected:
+ void ref()
+ {
+ if (mPointer)
+ {
+ mPointer->ref();
+ }
+ }
+
+ void unref()
+ {
+ if (mPointer)
+ {
+ Type *tempp = mPointer;
+ mPointer = NULL;
+ tempp->unref();
+ if (mPointer != NULL)
+ {
+ llwarns << "Unreference did assignment to non-NULL because of destructor" << llendl;
+ unref();
+ }
+ }
+ }
+
+ void assign(Type* ptr)
+ {
+ if( mPointer != ptr )
+ {
+ unref();
+ mPointer = ptr;
+ ref();
+ }
+ }
+
+ static Type* nonNull(Type* ptr)
+ {
+ return ptr == NULL ? sNullFunc() : ptr;
+ }
+
+protected:
+ Type* mPointer;
+};
+
+#endif
diff --git a/indra/llcommon/llsd.cpp b/indra/llcommon/llsd.cpp
index 2cc94c2914..9140ebb3f3 100644
--- a/indra/llcommon/llsd.cpp
+++ b/indra/llcommon/llsd.cpp
@@ -162,6 +162,7 @@ namespace
virtual LLSD::Type type() const { return T; }
+ using LLSD::Impl::assign; // Unhiding base class virtuals...
virtual void assign(LLSD::Impl*& var, DataRef value) {
if (shared())
{
@@ -349,6 +350,10 @@ namespace
virtual LLSD::Boolean asBoolean() const { return !mData.empty(); }
virtual bool has(const LLSD::String&) const;
+
+ using LLSD::Impl::get; // Unhiding get(LLSD::Integer)
+ using LLSD::Impl::erase; // Unhiding erase(LLSD::Integer)
+ using LLSD::Impl::ref; // Unhiding ref(LLSD::Integer)
virtual LLSD get(const LLSD::String&) const;
LLSD& insert(const LLSD::String& k, const LLSD& v);
virtual void erase(const LLSD::String&);
@@ -439,6 +444,9 @@ namespace
virtual LLSD::Boolean asBoolean() const { return !mData.empty(); }
+ using LLSD::Impl::get; // Unhiding get(LLSD::String)
+ using LLSD::Impl::erase; // Unhiding erase(LLSD::String)
+ using LLSD::Impl::ref; // Unhiding ref(LLSD::String)
virtual int size() const;
virtual LLSD get(LLSD::Integer) const;
void set(LLSD::Integer, const LLSD&);
@@ -811,9 +819,15 @@ static const char *llsd_dump(const LLSD &llsd, bool useXMLFormat)
{
std::ostringstream out;
if (useXMLFormat)
- out << LLSDXMLStreamer(llsd);
+ {
+ LLSDXMLStreamer xml_streamer(llsd);
+ out << xml_streamer;
+ }
else
- out << LLSDNotationStreamer(llsd);
+ {
+ LLSDNotationStreamer notation_streamer(llsd);
+ out << notation_streamer;
+ }
out_string = out.str();
}
int len = out_string.length();
diff --git a/indra/llcommon/llsdserialize.cpp b/indra/llcommon/llsdserialize.cpp
index 7a66d70d3f..cf337be161 100644
--- a/indra/llcommon/llsdserialize.cpp
+++ b/indra/llcommon/llsdserialize.cpp
@@ -34,7 +34,7 @@
#include "linden_common.h"
#include "llsdserialize.h"
-#include "llmemory.h"
+#include "llpointer.h"
#include "llstreamtools.h" // for fullread
#include <iostream>
diff --git a/indra/llcommon/llsdserialize.h b/indra/llcommon/llsdserialize.h
index bb38b75d8f..7463d1e5dd 100644
--- a/indra/llcommon/llsdserialize.h
+++ b/indra/llcommon/llsdserialize.h
@@ -36,8 +36,9 @@
#define LL_LLSDSERIALIZE_H
#include <iosfwd>
+#include "llpointer.h"
+#include "llrefcount.h"
#include "llsd.h"
-#include "llmemory.h"
/**
* @class LLSDParser
diff --git a/indra/llcommon/llsdutil.cpp b/indra/llcommon/llsdutil.cpp
index aa0e0f3696..0202a033c3 100644
--- a/indra/llcommon/llsdutil.cpp
+++ b/indra/llcommon/llsdutil.cpp
@@ -171,6 +171,15 @@ char* ll_print_sd(const LLSD& sd)
return buffer;
}
+char* ll_pretty_print_sd_ptr(const LLSD* sd)
+{
+ if (sd)
+ {
+ return ll_pretty_print_sd(*sd);
+ }
+ return NULL;
+}
+
char* ll_pretty_print_sd(const LLSD& sd)
{
const U32 bufferSize = 10 * 1024;
diff --git a/indra/llcommon/llsdutil.h b/indra/llcommon/llsdutil.h
index b67ad521ea..501600f1d9 100644
--- a/indra/llcommon/llsdutil.h
+++ b/indra/llcommon/llsdutil.h
@@ -89,6 +89,7 @@ LLSD ll_binary_from_string(const LLSD& sd);
char* ll_print_sd(const LLSD& sd);
// Serializes sd to static buffer and returns pointer, using "pretty printing" mode.
+char* ll_pretty_print_sd_ptr(const LLSD* sd);
char* ll_pretty_print_sd(const LLSD& sd);
//compares the structure of an LLSD to a template LLSD and stores the
diff --git a/indra/llcommon/llsecondlifeurls.cpp b/indra/llcommon/llsecondlifeurls.cpp
index 36d8e8870f..6323d9d36b 100644
--- a/indra/llcommon/llsecondlifeurls.cpp
+++ b/indra/llcommon/llsecondlifeurls.cpp
@@ -32,57 +32,59 @@
#include "linden_common.h"
#include "llsecondlifeurls.h"
-
+/*
const std::string CREATE_ACCOUNT_URL (
"http://secondlife.com/registration/");
const std::string MANAGE_ACCOUNT (
- "http://secondlife.com/account/");
+ "http://secondlife.com/account/"); // *TODO: NOT USED
const std::string AUCTION_URL (
"http://secondlife.com/auctions/auction-detail.php?id=");
const std::string EVENTS_URL (
"http://secondlife.com/events/");
-
+*/
const std::string TIER_UP_URL (
- "http://secondlife.com/app/landtier");
+ "http://secondlife.com/app/landtier"); // *TODO: Translate (simulator)
+const std::string DIRECTX_9_URL (
+ "http://secondlife.com/support/"); // *TODO: NOT USED
+/*
const std::string LAND_URL (
- "http://secondlife.com/app/landtier");
+ "http://secondlife.com/app/landtier"); // *TODO: NOT USED
const std::string UPGRADE_TO_PREMIUM_URL (
- "http://secondlife.com/app/upgrade/");
-
-const std::string DIRECTX_9_URL (
- "http://secondlife.com/support/");
+ "http://secondlife.com/app/upgrade/"); // *TODO: NOT USED
const std::string AMD_AGP_URL (
- "http://secondlife.com/support/");
+ "http://secondlife.com/support/"); // *TODO: NOT USED
const std::string VIA_URL (
- "http://secondlife.com/support/");
+ "http://secondlife.com/support/"); // *TODO: NOT USED
const std::string SUPPORT_URL (
"http://secondlife.com/support/");
const std::string INTEL_CHIPSET_URL (
- "http://secondlife.com/support/");
+ "http://secondlife.com/support/"); // *TODO: NOT USED
const std::string SIS_CHIPSET_URL (
- "http://secondlife.com/support/");
+ "http://secondlife.com/support/"); // *TODO: NOT USED
const std::string BLOGS_URL (
- "http://blog.secondlife.com/");
+ "http://blog.secondlife.com/"); // *TODO: NOT USED
const std::string BUY_CURRENCY_URL (
"http://secondlife.com/app/currency/");
const std::string LSL_DOC_URL (
- "http://secondlife.com/app/lsldoc/");
+ "http://secondlife.com/app/lsldoc/"); // *TODO: NOT USED
const std::string SL_KB_URL (
- "http://secondlife.com/knowledgebase/");
+ "http://secondlife.com/knowledgebase/"); // *TODO: NOT USED
const std::string RELEASE_NOTES_BASE_URL (
"http://secondlife.com/app/releasenotes/");
+*/
+
diff --git a/indra/llcommon/llsecondlifeurls.h b/indra/llcommon/llsecondlifeurls.h
index 9fd75c363b..a2e5f0b9c6 100644
--- a/indra/llcommon/llsecondlifeurls.h
+++ b/indra/llcommon/llsecondlifeurls.h
@@ -32,7 +32,7 @@
#ifndef LL_LLSECONDLIFEURLS_H
#define LL_LLSECONDLIFEURLS_H
-
+/*
// Account registration web page
extern const std::string CREATE_ACCOUNT_URL;
@@ -42,18 +42,21 @@ extern const std::string MANAGE_ACCOUNT;
extern const std::string AUCTION_URL;
extern const std::string EVENTS_URL;
-
+*/
// Tier up to a new land level.
extern const std::string TIER_UP_URL;
+
// Tier up to a new land level.
extern const std::string LAND_URL;
+// How to get DirectX 9
+extern const std::string DIRECTX_9_URL;
+
+/*
// Upgrade from basic membership to premium membership
extern const std::string UPGRADE_TO_PREMIUM_URL;
-// How to get DirectX 9
-extern const std::string DIRECTX_9_URL;
// Out of date VIA chipset
extern const std::string VIA_URL;
@@ -75,5 +78,5 @@ extern const std::string SL_KB_URL;
// Release Notes Redirect URL for Server and Viewer
extern const std::string RELEASE_NOTES_BASE_URL;
-
+*/
#endif
diff --git a/indra/llcommon/llsingleton.h b/indra/llcommon/llsingleton.h
new file mode 100644
index 0000000000..2e7d845bf7
--- /dev/null
+++ b/indra/llcommon/llsingleton.h
@@ -0,0 +1,165 @@
+/**
+ * @file llsingleton.h
+ *
+ * $LicenseInfo:firstyear=2002&license=viewergpl$
+ *
+ * Copyright (c) 2002-2009, Linden Research, Inc.
+ *
+ * Second Life Viewer Source Code
+ * The source code in this file ("Source Code") is provided by Linden Lab
+ * to you under the terms of the GNU General Public License, version 2.0
+ * ("GPL"), unless you have obtained a separate licensing agreement
+ * ("Other License"), formally executed by you and Linden Lab. Terms of
+ * the GPL can be found in doc/GPL-license.txt in this distribution, or
+ * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
+ *
+ * There are special exceptions to the terms and conditions of the GPL as
+ * it is applied to this Source Code. View the full text of the exception
+ * in the file doc/FLOSS-exception.txt in this software distribution, or
+ * online at
+ * http://secondlifegrid.net/programs/open_source/licensing/flossexception
+ *
+ * By copying, modifying or distributing this software, you acknowledge
+ * that you have read and understood your obligations described above,
+ * and agree to abide by those obligations.
+ *
+ * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+ * COMPLETENESS OR PERFORMANCE.
+ * $/LicenseInfo$
+ */
+#ifndef LLSINGLETON_H
+#define LLSINGLETON_H
+
+#include "llerror.h" // *TODO: eliminate this
+
+#include <boost/noncopyable.hpp>
+
+// LLSingleton implements the getInstance() method part of the Singleton
+// pattern. It can't make the derived class constructors protected, though, so
+// you have to do that yourself.
+//
+// There are two ways to use LLSingleton. The first way is to inherit from it
+// while using the typename that you'd like to be static as the template
+// parameter, like so:
+//
+// class Foo: public LLSingleton<Foo>{};
+//
+// Foo& instance = Foo::instance();
+//
+// The second way is to use the singleton class directly, without inheritance:
+//
+// typedef LLSingleton<Foo> FooSingleton;
+//
+// Foo& instance = FooSingleton::instance();
+//
+// In this case, the class being managed as a singleton needs to provide an
+// initSingleton() method since the LLSingleton virtual method won't be
+// available
+//
+// As currently written, it is not thread-safe.
+
+template <typename DERIVED_TYPE>
+class LLSingleton : private boost::noncopyable
+{
+
+private:
+ typedef enum e_init_state
+ {
+ UNINITIALIZED,
+ CONSTRUCTING,
+ INITIALIZING,
+ INITIALIZED,
+ DELETED
+ } EInitState;
+
+ static void deleteSingleton()
+ {
+ delete getData().mSingletonInstance;
+ getData().mSingletonInstance = NULL;
+ }
+
+ // stores pointer to singleton instance
+ // and tracks initialization state of singleton
+ struct SingletonInstanceData
+ {
+ EInitState mInitState;
+ DERIVED_TYPE* mSingletonInstance;
+
+ SingletonInstanceData()
+ : mSingletonInstance(NULL),
+ mInitState(UNINITIALIZED)
+ {}
+
+ ~SingletonInstanceData()
+ {
+ deleteSingleton();
+ }
+ };
+
+public:
+ virtual ~LLSingleton()
+ {
+ SingletonInstanceData& data = getData();
+ data.mSingletonInstance = NULL;
+ data.mInitState = DELETED;
+ }
+
+ static SingletonInstanceData& getData()
+ {
+ static SingletonInstanceData data;
+ return data;
+ }
+
+ static DERIVED_TYPE* getInstance()
+ {
+ SingletonInstanceData& data = getData();
+
+ if (data.mInitState == CONSTRUCTING)
+ {
+ llerrs << "Tried to access singleton " << typeid(DERIVED_TYPE).name() << " from singleton constructor!" << llendl;
+ }
+
+ if (data.mInitState == DELETED)
+ {
+ llwarns << "Trying to access deleted singleton " << typeid(DERIVED_TYPE).name() << " creating new instance" << llendl;
+ }
+
+ if (!data.mSingletonInstance)
+ {
+ data.mInitState = CONSTRUCTING;
+ data.mSingletonInstance = new DERIVED_TYPE();
+ data.mInitState = INITIALIZING;
+ data.mSingletonInstance->initSingleton();
+ data.mInitState = INITIALIZED;
+ }
+
+ return data.mSingletonInstance;
+ }
+
+ // Reference version of getInstance()
+ // Preferred over getInstance() as it disallows checking for NULL
+ static DERIVED_TYPE& instance()
+ {
+ return *getInstance();
+ }
+
+ // Has this singleton been created uet?
+ // Use this to avoid accessing singletons before the can safely be constructed
+ static bool instanceExists()
+ {
+ return getData().mInitState == INITIALIZED;
+ }
+
+ // Has this singleton already been deleted?
+ // Use this to avoid accessing singletons from a static object's destructor
+ static bool destroyed()
+ {
+ return getData().mInitState == DELETED;
+ }
+
+private:
+ virtual void initSingleton() {}
+};
+
+#endif
diff --git a/indra/llcommon/llstacktrace.cpp b/indra/llcommon/llstacktrace.cpp
new file mode 100644
index 0000000000..4be91b5b11
--- /dev/null
+++ b/indra/llcommon/llstacktrace.cpp
@@ -0,0 +1,141 @@
+/**
+ * @file llstacktrace.cpp
+ * @brief stack tracing functionality
+ *
+ * $LicenseInfo:firstyear=2001&license=viewergpl$
+ *
+ * Copyright (c) 2001-2009, Linden Research, Inc.
+ *
+ * Second Life Viewer Source Code
+ * The source code in this file ("Source Code") is provided by Linden Lab
+ * to you under the terms of the GNU General Public License, version 2.0
+ * ("GPL"), unless you have obtained a separate licensing agreement
+ * ("Other License"), formally executed by you and Linden Lab. Terms of
+ * the GPL can be found in doc/GPL-license.txt in this distribution, or
+ * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
+ *
+ * There are special exceptions to the terms and conditions of the GPL as
+ * it is applied to this Source Code. View the full text of the exception
+ * in the file doc/FLOSS-exception.txt in this software distribution, or
+ * online at
+ * http://secondlifegrid.net/programs/open_source/licensing/flossexception
+ *
+ * By copying, modifying or distributing this software, you acknowledge
+ * that you have read and understood your obligations described above,
+ * and agree to abide by those obligations.
+ *
+ * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+ * COMPLETENESS OR PERFORMANCE.
+ * $/LicenseInfo$
+ */
+
+#include "llstacktrace.h"
+
+#ifdef LL_WINDOWS
+
+#include <iostream>
+#include <sstream>
+
+#include "windows.h"
+#include "Dbghelp.h"
+
+typedef USHORT NTAPI RtlCaptureStackBackTrace_Function(
+ IN ULONG frames_to_skip,
+ IN ULONG frames_to_capture,
+ OUT PVOID *backtrace,
+ OUT PULONG backtrace_hash);
+
+static RtlCaptureStackBackTrace_Function* const RtlCaptureStackBackTrace_fn =
+ (RtlCaptureStackBackTrace_Function*)
+ GetProcAddress(GetModuleHandleA("ntdll.dll"), "RtlCaptureStackBackTrace");
+
+bool ll_get_stack_trace(std::vector<std::string>& lines)
+{
+ const S32 MAX_STACK_DEPTH = 32;
+ const S32 STRING_NAME_LENGTH = 200;
+ const S32 FRAME_SKIP = 2;
+ static BOOL symbolsLoaded = false;
+ static BOOL firstCall = true;
+
+ HANDLE hProc = GetCurrentProcess();
+
+ // load the symbols if they're not loaded
+ if(!symbolsLoaded && firstCall)
+ {
+ symbolsLoaded = SymInitialize(hProc, NULL, true);
+ firstCall = false;
+ }
+
+ // if loaded, get the call stack
+ if(symbolsLoaded)
+ {
+ // create the frames to hold the addresses
+ void* frames[MAX_STACK_DEPTH];
+ memset(frames, 0, sizeof(void*)*MAX_STACK_DEPTH);
+ S32 depth = 0;
+
+ // get the addresses
+ depth = RtlCaptureStackBackTrace_fn(FRAME_SKIP, MAX_STACK_DEPTH, frames, NULL);
+
+ IMAGEHLP_LINE64 line;
+ memset(&line, 0, sizeof(IMAGEHLP_LINE64));
+ line.SizeOfStruct = sizeof(IMAGEHLP_LINE64);
+
+ // create something to hold address info
+ PIMAGEHLP_SYMBOL64 pSym;
+ pSym = (PIMAGEHLP_SYMBOL64)malloc(sizeof(IMAGEHLP_SYMBOL64) + STRING_NAME_LENGTH);
+ memset(pSym, 0, sizeof(IMAGEHLP_SYMBOL64) + STRING_NAME_LENGTH);
+ pSym->MaxNameLength = STRING_NAME_LENGTH;
+ pSym->SizeOfStruct = sizeof(IMAGEHLP_SYMBOL64);
+
+ // get address info for each address frame
+ // and store
+ for(S32 i=0; i < depth; i++)
+ {
+ std::stringstream stack_line;
+ BOOL ret;
+
+ DWORD64 addr = (DWORD64)frames[i];
+ ret = SymGetSymFromAddr64(hProc, addr, 0, pSym);
+ if(ret)
+ {
+ stack_line << pSym->Name << " ";
+ }
+
+ DWORD dummy;
+ ret = SymGetLineFromAddr64(hProc, addr, &dummy, &line);
+ if(ret)
+ {
+ std::string file_name = line.FileName;
+ std::string::size_type index = file_name.rfind("\\");
+ stack_line << file_name.substr(index + 1, file_name.size()) << ":" << line.LineNumber;
+ }
+
+ lines.push_back(stack_line.str());
+ }
+
+ free(pSym);
+
+ // TODO: figure out a way to cleanup symbol loading
+ // Not hugely necessary, however.
+ //SymCleanup(hProc);
+ return true;
+ }
+ else
+ {
+ lines.push_back("Stack Trace Failed. PDB symbol info not loaded");
+ }
+
+ return false;
+}
+
+#else
+
+bool ll_get_stack_trace(std::vector<std::string>& lines)
+{
+ return false;
+}
+
+#endif
+
diff --git a/indra/llcommon/llstacktrace.h b/indra/llcommon/llstacktrace.h
new file mode 100644
index 0000000000..609b934a97
--- /dev/null
+++ b/indra/llcommon/llstacktrace.h
@@ -0,0 +1,44 @@
+/**
+ * @file llstacktrace.h
+ * @brief stack trace functions
+ *
+ * $LicenseInfo:firstyear=2001&license=viewergpl$
+ *
+ * Copyright (c) 2001-2009, Linden Research, Inc.
+ *
+ * Second Life Viewer Source Code
+ * The source code in this file ("Source Code") is provided by Linden Lab
+ * to you under the terms of the GNU General Public License, version 2.0
+ * ("GPL"), unless you have obtained a separate licensing agreement
+ * ("Other License"), formally executed by you and Linden Lab. Terms of
+ * the GPL can be found in doc/GPL-license.txt in this distribution, or
+ * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
+ *
+ * There are special exceptions to the terms and conditions of the GPL as
+ * it is applied to this Source Code. View the full text of the exception
+ * in the file doc/FLOSS-exception.txt in this software distribution, or
+ * online at
+ * http://secondlifegrid.net/programs/open_source/licensing/flossexception
+ *
+ * By copying, modifying or distributing this software, you acknowledge
+ * that you have read and understood your obligations described above,
+ * and agree to abide by those obligations.
+ *
+ * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+ * COMPLETENESS OR PERFORMANCE.
+ * $/LicenseInfo$
+ */
+
+
+#ifndef LL_LLSTACKTRACE_H
+#define LL_LLSTACKTRACE_H
+
+#include "stdtypes.h"
+#include <vector>
+#include <string>
+
+bool ll_get_stack_trace(std::vector<std::string>& lines);
+
+#endif
+
diff --git a/indra/llcommon/llstat.cpp b/indra/llcommon/llstat.cpp
index e650f911b7..0bd2609f4a 100644
--- a/indra/llcommon/llstat.cpp
+++ b/indra/llcommon/llstat.cpp
@@ -46,6 +46,7 @@
S32 LLPerfBlock::sStatsFlags = LLPerfBlock::LLSTATS_NO_OPTIONAL_STATS; // Control what is being recorded
LLPerfBlock::stat_map_t LLPerfBlock::sStatMap; // Map full path string to LLStatTime objects, tracks all active objects
std::string LLPerfBlock::sCurrentStatPath = ""; // Something like "/total_time/physics/physics step"
+LLStat::stat_map_t LLStat::sStatList;
//------------------------------------------------------------------------
// Live config file to trigger stats logging
@@ -754,28 +755,48 @@ void LLPerfBlock::addStatsToLLSDandReset( LLSD & stats,
LLTimer LLStat::sTimer;
LLFrameTimer LLStat::sFrameTimer;
-LLStat::LLStat(const U32 num_bins, const BOOL use_frame_timer)
+void LLStat::init()
{
- llassert(num_bins > 0);
- U32 i;
- mUseFrameTimer = use_frame_timer;
+ llassert(mNumBins > 0);
mNumValues = 0;
mLastValue = 0.f;
mLastTime = 0.f;
- mNumBins = num_bins;
mCurBin = (mNumBins-1);
mNextBin = 0;
mBins = new F32[mNumBins];
mBeginTime = new F64[mNumBins];
mTime = new F64[mNumBins];
mDT = new F32[mNumBins];
- for (i = 0; i < mNumBins; i++)
+ for (U32 i = 0; i < mNumBins; i++)
{
mBins[i] = 0.f;
mBeginTime[i] = 0.0;
mTime[i] = 0.0;
mDT[i] = 0.f;
}
+
+ if (!mName.empty())
+ {
+ stat_map_t::iterator iter = sStatList.find(mName);
+ if (iter != sStatList.end())
+ llwarns << "LLStat with duplicate name: " << mName << llendl;
+ sStatList.insert(std::make_pair(mName, this));
+ }
+}
+
+LLStat::LLStat(const U32 num_bins, const BOOL use_frame_timer)
+ : mUseFrameTimer(use_frame_timer),
+ mNumBins(num_bins)
+{
+ init();
+}
+
+LLStat::LLStat(std::string name, U32 num_bins, BOOL use_frame_timer)
+ : mUseFrameTimer(use_frame_timer),
+ mNumBins(num_bins),
+ mName(name)
+{
+ init();
}
LLStat::~LLStat()
@@ -784,6 +805,15 @@ LLStat::~LLStat()
delete[] mBeginTime;
delete[] mTime;
delete[] mDT;
+
+ if (!mName.empty())
+ {
+ // handle multiple entries with the same name
+ stat_map_t::iterator iter = sStatList.find(mName);
+ while (iter != sStatList.end() && iter->second != this)
+ ++iter;
+ sStatList.erase(iter);
+ }
}
void LLStat::reset()
diff --git a/indra/llcommon/llstat.h b/indra/llcommon/llstat.h
index e2e904bb06..76aa3963f4 100644
--- a/indra/llcommon/llstat.h
+++ b/indra/llcommon/llstat.h
@@ -267,8 +267,15 @@ private:
// ----------------------------------------------------------------------------
class LLStat
{
+private:
+ typedef std::multimap<std::string, LLStat*> stat_map_t;
+ static stat_map_t sStatList;
+
+ void init();
+
public:
- LLStat(const U32 num_bins = 32, BOOL use_frame_timer = FALSE);
+ LLStat(U32 num_bins = 32, BOOL use_frame_timer = FALSE);
+ LLStat(std::string name, U32 num_bins = 32, BOOL use_frame_timer = FALSE);
~LLStat();
void reset();
@@ -331,8 +338,22 @@ private:
F32 *mDT;
S32 mCurBin;
S32 mNextBin;
+
+ std::string mName;
+
static LLTimer sTimer;
static LLFrameTimer sFrameTimer;
+
+public:
+ static LLStat* getStat(const std::string& name)
+ {
+ // return the first stat that matches 'name'
+ stat_map_t::iterator iter = sStatList.find(name);
+ if (iter != sStatList.end())
+ return iter->second;
+ else
+ return NULL;
+ }
};
-
+
#endif // LL_STAT_
diff --git a/indra/llcommon/llstring.cpp b/indra/llcommon/llstring.cpp
index 1f653c159c..d7da40d645 100644
--- a/indra/llcommon/llstring.cpp
+++ b/indra/llcommon/llstring.cpp
@@ -42,6 +42,9 @@
#include <winnls.h> // for WideCharToMultiByte
#endif
+LLFastTimer::DeclareTimer STRING_LOCALIZATION("String Localization");
+
+
std::string ll_safe_string(const char* in)
{
if(in) return std::string(in);
@@ -71,6 +74,24 @@ U8 hex_as_nybble(char hex)
return 0; // uh - oh, not hex any more...
}
+bool iswindividual(llwchar elem)
+{
+ U32 cur_char = (U32)elem;
+ bool result = false;
+ if (0x2E80<= cur_char && cur_char <= 0x9FFF)
+ {
+ result = true;
+ }
+ else if (0xAC00<= cur_char && cur_char <= 0xD7A0 )
+ {
+ result = true;
+ }
+ else if (0xF900<= cur_char && cur_char <= 0xFA60 )
+ {
+ result = true;
+ }
+ return result;
+}
bool _read_file_into_string(std::string& str, const std::string& filename)
{
@@ -650,6 +671,11 @@ std::string ll_convert_wide_to_string(const wchar_t* in)
}
#endif // LL_WINDOWS
+long LLStringOps::sltOffset;
+long LLStringOps::localTimeOffset;
+bool LLStringOps::daylightSavings;
+std::map<std::string, std::string> LLStringOps::datetimeToCodes;
+
S32 LLStringOps::collate(const llwchar* a, const llwchar* b)
{
#if LL_WINDOWS
@@ -661,6 +687,59 @@ S32 LLStringOps::collate(const llwchar* a, const llwchar* b)
#endif
}
+void LLStringOps::setupDatetimeInfo (bool daylight)
+{
+ time_t nowT, localT, gmtT;
+ struct tm * tmpT;
+
+ nowT = time (NULL);
+
+ tmpT = localtime (&nowT);
+ localT = mktime (tmpT);
+
+ tmpT = gmtime (&nowT);
+ gmtT = mktime (tmpT);
+
+ localTimeOffset = (long) (gmtT - localT);
+
+
+ daylightSavings = daylight;
+ sltOffset = (daylightSavings? 7 : 8 ) * 60 * 60;
+
+ datetimeToCodes["wkday"] = "%a"; // Thu
+ datetimeToCodes["weekday"] = "%A"; // Thursday
+ datetimeToCodes["year4"] = "%Y"; // 2009
+ datetimeToCodes["year"] = "%Y"; // 2009
+ datetimeToCodes["year2"] = "%y"; // 09
+ datetimeToCodes["mth"] = "%b"; // Aug
+ datetimeToCodes["month"] = "%B"; // August
+ datetimeToCodes["mthnum"] = "%m"; // 08
+ datetimeToCodes["day"] = "%d"; // 31
+ datetimeToCodes["hour24"] = "%H"; // 14
+ datetimeToCodes["hour"] = "%H"; // 14
+ datetimeToCodes["hour12"] = "%I"; // 02
+ datetimeToCodes["min"] = "%M"; // 59
+ datetimeToCodes["ampm"] = "%p"; // AM
+ datetimeToCodes["second"] = "%S"; // 59
+ datetimeToCodes["timezone"] = "%Z"; // PST
+}
+
+std::string LLStringOps::getDatetimeCode (std::string key)
+{
+ std::map<std::string, std::string>::iterator iter;
+
+ iter = datetimeToCodes.find (key);
+ if (iter != datetimeToCodes.end())
+ {
+ return iter->second;
+ }
+ else
+ {
+ return std::string("");
+ }
+}
+
+
namespace LLStringFn
{
// NOTE - this restricts output to ascii
diff --git a/indra/llcommon/llstring.h b/indra/llcommon/llstring.h
index 6ba665b8d2..c6dcdd6d12 100644
--- a/indra/llcommon/llstring.h
+++ b/indra/llcommon/llstring.h
@@ -34,6 +34,11 @@
#define LL_LLSTRING_H
#include <string>
+#include <locale>
+#include <iomanip>
+#include <boost/regex.hpp>
+#include "llsd.h"
+#include "llfasttimer.h"
#if LL_LINUX || LL_SOLARIS
#include <wctype.h>
@@ -145,6 +150,12 @@ struct char_traits<U16>
class LLStringOps
{
+private:
+ static long sltOffset;
+ static long localTimeOffset;
+ static bool daylightSavings;
+ static std::map<std::string, std::string> datetimeToCodes;
+
public:
static char toUpper(char elem) { return toupper((unsigned char)elem); }
static llwchar toUpper(llwchar elem) { return towupper(elem); }
@@ -172,6 +183,12 @@ public:
static S32 collate(const char* a, const char* b) { return strcoll(a, b); }
static S32 collate(const llwchar* a, const llwchar* b);
+
+ static void setupDatetimeInfo (bool daylight);
+ static long getSltOffset (void) {return sltOffset;}
+ static long getLocalTimeOffset (void) {return localTimeOffset;}
+ static bool getDaylightSavings (void) {return daylightSavings;}
+ static std::string getDatetimeCode (std::string key);
};
/**
@@ -201,6 +218,9 @@ private:
template <class T>
class LLStringUtilBase
{
+private:
+ static std::string sLocale;
+
public:
typedef typename std::basic_string<T>::size_type size_type;
@@ -211,7 +231,15 @@ public:
static std::basic_string<T> null;
typedef std::map<LLFormatMapString, LLFormatMapString> format_map_t;
- static S32 format(std::basic_string<T>& s, const format_map_t& fmt_map);
+ static void getTokens (std::basic_string<T> input, std::vector<std::basic_string<T> >& tokens);
+ static void formatNumber(std::basic_string<T>& numStr, std::basic_string<T> decimals);
+ static bool formatDatetime(std::basic_string<T>& replacement, std::basic_string<T> token, std::basic_string<T> param, S32 secFromEpoch);
+ static S32 format(std::basic_string<T>& s, const format_map_t& substitutions);
+ static S32 format(std::basic_string<T>& s, const LLSD& substitutions);
+ static bool simpleReplacement(std::basic_string<T>& replacement, std::basic_string<T> token, const format_map_t& substitutions);
+ static bool simpleReplacement(std::basic_string<T>& replacement, std::basic_string<T> token, const LLSD& substitutions);
+ static void setLocale (std::string inLocale) {sLocale = inLocale;};
+ static std::string getLocale (void) {return sLocale;};
static bool isValidIndex(const std::basic_string<T>& string, size_type i)
{
@@ -253,7 +281,8 @@ public:
static void replaceTabsWithSpaces( std::basic_string<T>& string, size_type spaces_per_tab );
static void replaceNonstandardASCII( std::basic_string<T>& string, T replacement );
static void replaceChar( std::basic_string<T>& string, T target, T replacement );
-
+ static void replaceString( std::basic_string<T>& string, std::basic_string<T> target, std::basic_string<T> replacement );
+
static BOOL containsNonprintable(const std::basic_string<T>& string);
static void stripNonprintable(std::basic_string<T>& string);
@@ -310,6 +339,9 @@ public:
// Copies src into dst at a given offset.
static void copyInto(std::basic_string<T>& dst, const std::basic_string<T>& src, size_type offset);
+ static bool isPartOfWord(T c) { return (c == (T)'_') || LLStringOps::isAlnum(c); }
+
+
#ifdef _DEBUG
static void testHarness();
#endif
@@ -317,6 +349,7 @@ public:
};
template<class T> std::basic_string<T> LLStringUtilBase<T>::null;
+template<class T> std::string LLStringUtilBase<T>::sLocale;
typedef LLStringUtilBase<char> LLStringUtil;
typedef LLStringUtilBase<llwchar> LLWStringUtil;
@@ -378,6 +411,7 @@ U8 hex_as_nybble(char hex);
* @return Returns true on success. If false, str is unmodified.
*/
bool _read_file_into_string(std::string& str, const std::string& filename);
+bool iswindividual(llwchar elem);
/**
* Unicode support
@@ -564,63 +598,302 @@ namespace LLStringFn
////////////////////////////////////////////////////////////
-// LLStringBase::format()
-//
-// This function takes a string 's' and a map 'fmt_map' of strings-to-strings.
-// All occurances of strings in 's' from the left-hand side of 'fmt_map' are
-// then replaced with the corresponding right-hand side of 'fmt_map', non-
-// recursively. The function returns the number of substitutions made.
+//static
+template<class T>
+void LLStringUtilBase<T>::getTokens (std::basic_string<T> input, std::vector<std::basic_string<T> >& tokens)
+{
+ const std::basic_string<T> delims (",");
+ std::basic_string<T> currToken;
+ size_type begIdx, endIdx;
+
+ begIdx = input.find_first_not_of (delims);
+ while (begIdx != std::basic_string<T>::npos)
+ {
+ endIdx = input.find_first_of (delims, begIdx);
+ if (endIdx == std::basic_string<T>::npos)
+ {
+ endIdx = input.length();
+ }
+
+ currToken = input.substr(begIdx, endIdx - begIdx);
+ trim (currToken);
+ tokens.push_back(currToken);
+ begIdx = input.find_first_not_of (delims, endIdx);
+ }
+}
+
+extern LLFastTimer::DeclareTimer STRING_LOCALIZATION;
// static
template<class T>
-S32 LLStringUtilBase<T>::format(std::basic_string<T>& s, const format_map_t& fmt_map)
+S32 LLStringUtilBase<T>::format(std::basic_string<T>& s, const format_map_t& substitutions)
{
- typedef typename std::basic_string<T>::size_type string_size_type_t;
- string_size_type_t scanstart = 0;
+ LLFastTimer ft(STRING_LOCALIZATION);
S32 res = 0;
- // Look for the first match of any keyword, replace that keyword,
- // repeat from the end of the replacement string. This avoids
- // accidentally performing substitution on a substituted string.
- while (1)
+ std::basic_ostringstream<T> output;
+ // match strings like [NAME,number,3]
+ const boost::regex key("\\[((\\s)*([0-9_A-Za-z]+)((\\s)*,(\\s)*[0-9_A-Za-z\\s]*){0,2}(\\s)*)]");
+
+
+ typename std::basic_string<T>::const_iterator start = s.begin();
+ typename std::basic_string<T>::const_iterator end = s.end();
+ boost::smatch match;
+
+
+ while (boost::regex_search(start, end, match, key, boost::match_default))
{
- string_size_type_t first_match_pos = scanstart;
- string_size_type_t first_match_str_length = 0;
- std::basic_string<T> first_match_str_replacement;
+ bool found_replacement = false;
+ std::vector<std::basic_string<T> > tokens;
+ std::basic_string<T> replacement;
+
+ getTokens (std::basic_string<T>(match[1].first, match[1].second), tokens);
- for (format_map_t::const_iterator iter = fmt_map.begin();
- iter != fmt_map.end();
- ++iter)
+ if (tokens.size() == 1)
{
- string_size_type_t n = s.find(iter->first, scanstart);
- if (n != std::basic_string<T>::npos &&
- (n < first_match_pos ||
- 0 == first_match_str_length))
+ found_replacement = simpleReplacement (replacement, tokens[0], substitutions);
+ }
+ else if (tokens[1] == "number")
+ {
+ std::basic_string<T> param = "0";
+
+ if (tokens.size() > 2) param = tokens[2];
+ found_replacement = simpleReplacement (replacement, tokens[0], substitutions);
+ if (found_replacement) formatNumber (replacement, param);
+ }
+ else if (tokens[1] == "datetime")
+ {
+ std::basic_string<T> param;
+ if (tokens.size() > 2) param = tokens[2];
+
+ format_map_t::const_iterator iter = substitutions.find("datetime");
+ if (iter != substitutions.end())
{
- first_match_pos = n;
- first_match_str_length = iter->first.length();
- first_match_str_replacement = iter->second;
+ S32 secFromEpoch = 0;
+ BOOL r = LLStringUtil::convertToS32(iter->second, secFromEpoch);
+ if (r)
+ {
+ found_replacement = formatDatetime(replacement, tokens[0], param, secFromEpoch);
+ }
}
}
- if (0 == first_match_str_length)
+ if (found_replacement)
{
- // no more keys found to substitute from this point
- // in the string forward.
- break;
+ output << std::basic_string<T>(start, match[0].first) << replacement;
+ res++;
}
else
{
- s.erase(first_match_pos, first_match_str_length);
- s.insert(first_match_pos, first_match_str_replacement);
- scanstart = first_match_pos +
- first_match_str_replacement.length();
- ++res;
+ // we had no replacement, so leave the string we searched for so that it gets noticed by QA
+ // "hello [NAME_NOT_FOUND]" is output
+ output << std::basic_string<T>(start, match[0].second);
}
+
+ // update search position
+ start = match[0].second;
}
+ // send the remainder of the string (with no further matches for bracketed names)
+ output << std::basic_string<T>(start, end);
+ s = output.str();
return res;
}
+//static
+template<class T>
+S32 LLStringUtilBase<T>::format(std::basic_string<T>& s, const LLSD& substitutions)
+{
+ LLFastTimer ft(STRING_LOCALIZATION);
+
+ S32 res = 0;
+
+ if (!substitutions.isMap())
+ {
+ return res;
+ }
+
+ std::basic_ostringstream<T> output;
+ // match strings like [NAME,number,3]
+ const boost::regex key("\\[((\\s)*([0-9_A-Za-z]+)((\\s)*,(\\s)*[0-9_A-Za-z\\s]*){0,2}(\\s)*)]");
+
+
+ typename std::basic_string<T>::const_iterator start = s.begin();
+ typename std::basic_string<T>::const_iterator end = s.end();
+ boost::smatch match;
+
+
+ while (boost::regex_search(start, end, match, key, boost::match_default))
+ {
+ bool found_replacement = false;
+ std::vector<std::basic_string<T> > tokens;
+ std::basic_string<T> replacement;
+
+ getTokens (std::basic_string<T>(match[1].first, match[1].second), tokens);
+
+ if (tokens.size() == 1)
+ {
+ found_replacement = simpleReplacement (replacement, tokens[0], substitutions);
+ }
+ else if (tokens[1] == "number")
+ {
+ std::basic_string<T> param = "0";
+
+ if (tokens.size() > 2) param = tokens[2];
+ found_replacement = simpleReplacement (replacement, tokens[0], substitutions);
+ if (found_replacement) formatNumber (replacement, param);
+ }
+ else if (tokens[1] == "datetime")
+ {
+ std::basic_string<T> param;
+ if (tokens.size() > 2) param = tokens[2];
+
+ S32 secFromEpoch = (S32) substitutions["datetime"].asInteger();
+ found_replacement = formatDatetime (replacement, tokens[0], param, secFromEpoch);
+ }
+
+ if (found_replacement)
+ {
+ output << std::basic_string<T>(start, match[0].first) << replacement;
+ res++;
+ }
+ else
+ {
+ // we had no replacement, so leave the string we searched for so that it gets noticed by QA
+ // "hello [NAME_NOT_FOUND]" is output
+ output << std::basic_string<T>(start, match[0].second);
+ }
+
+ // update search position
+ start = match[0].second;
+ }
+ // send the remainder of the string (with no further matches for bracketed names)
+ output << std::basic_string<T>(start, end);
+ s = output.str();
+ return res;
+}
+
+// static
+template<class T>
+bool LLStringUtilBase<T>::simpleReplacement(std::basic_string<T> &replacement, std::basic_string<T> token, const format_map_t& substitutions)
+{
+ // see if we have a replacement for the bracketed string (without the brackets)
+ // test first using has() because if we just look up with operator[] we get back an
+ // empty string even if the value is missing. We want to distinguish between
+ // missing replacements and deliberately empty replacement strings.
+ format_map_t::const_iterator iter = substitutions.find(token);
+ if (iter != substitutions.end())
+ {
+ replacement = iter->second;
+ return true;
+ }
+ // if not, see if there's one WITH brackets
+ iter = substitutions.find(std::basic_string<T>("[" + token + "]"));
+ if (iter != substitutions.end())
+ {
+ replacement = iter->second;
+ return true;
+ }
+
+ return false;
+}
+
+// static
+template<class T>
+bool LLStringUtilBase<T>::simpleReplacement(std::basic_string<T> &replacement, std::basic_string<T> token, const LLSD& substitutions)
+{
+ // see if we have a replacement for the bracketed string (without the brackets)
+ // test first using has() because if we just look up with operator[] we get back an
+ // empty string even if the value is missing. We want to distinguish between
+ // missing replacements and deliberately empty replacement strings.
+ if (substitutions.has(token))
+ {
+ replacement = substitutions[token].asString();
+ return true;
+ }
+ // if not, see if there's one WITH brackets
+ else if (substitutions.has(std::basic_string<T>("[" + token + "]")))
+ {
+ replacement = substitutions[std::basic_string<T>("[" + token + "]")].asString();
+ return true;
+ }
+
+ return false;
+}
+
+// static
+template<class T>
+void LLStringUtilBase<T>::formatNumber(std::basic_string<T>& numStr, std::basic_string<T> decimals)
+{
+ typedef typename std::basic_string<T>::size_type string_size_type_t;
+ std::basic_stringstream<T> strStream;
+ S32 intDecimals = 0;
+
+ convertToS32 (decimals, intDecimals);
+ if (!sLocale.empty())
+ {
+ strStream.imbue (std::locale(sLocale.c_str()));
+ }
+
+ if (!intDecimals)
+ {
+ S32 intStr;
+
+ if (convertToS32(numStr, intStr))
+ {
+ strStream << intStr;
+ numStr = strStream.str();
+ }
+ }
+ else
+ {
+ F32 floatStr;
+
+ if (convertToF32(numStr, floatStr))
+ {
+ strStream << std::fixed << std::showpoint << std::setprecision(intDecimals) << floatStr;
+ numStr = strStream.str();
+ }
+ }
+}
+
+// static
+template<class T>
+bool LLStringUtilBase<T>::formatDatetime(std::basic_string<T>& replacement, std::basic_string<T> token,
+ std::basic_string<T> param, S32 secFromEpoch)
+{
+ if (param == "local") // local
+ {
+ secFromEpoch -= LLStringOps::getLocalTimeOffset();
+ }
+ else if (param != "utc") // slt
+ {
+ secFromEpoch -= LLStringOps::getSltOffset();
+ }
+
+ // if never fell into those two ifs above, param must be utc
+ if (secFromEpoch < 0) secFromEpoch = 0;
+
+ LLDate * datetime = new LLDate((F64)secFromEpoch);
+ std::string code = LLStringOps::getDatetimeCode (token);
+
+ // special case to handle timezone
+ if (code == "%Z") {
+ if (param == "utc") replacement = "GMT";
+ else if (param != "local") replacement = LLStringOps::getDaylightSavings()? "PDT" : "PST";
+ return true;
+ }
+
+ replacement = datetime->toHTTPDateString(code);
+ if (code.empty())
+ {
+ return false;
+ }
+ else
+ {
+ return true;
+ }
+}
+
// static
template<class T>
S32 LLStringUtilBase<T>::compareStrings(const T* lhs, const T* rhs)
@@ -917,11 +1190,22 @@ template<class T>
void LLStringUtilBase<T>::replaceChar( std::basic_string<T>& string, T target, T replacement )
{
size_type found_pos = 0;
- for (found_pos = string.find(target, found_pos);
- found_pos != std::basic_string<T>::npos;
- found_pos = string.find(target, found_pos))
+ while( (found_pos = string.find(target, found_pos)) != std::basic_string<T>::npos )
{
string[found_pos] = replacement;
+ found_pos++; // avoid infinite defeat if target == replacement
+ }
+}
+
+//static
+template<class T>
+void LLStringUtilBase<T>::replaceString( std::basic_string<T>& string, std::basic_string<T> target, std::basic_string<T> replacement )
+{
+ size_type found_pos = 0;
+ while( (found_pos = string.find(target, found_pos)) != std::basic_string<T>::npos )
+ {
+ string.replace( found_pos, target.length(), replacement );
+ found_pos += replacement.length(); // avoid infinite defeat if replacement contains target
}
}
diff --git a/indra/llcommon/llthread.h b/indra/llcommon/llthread.h
index c8c9fd4eec..f25339f48d 100644
--- a/indra/llcommon/llthread.h
+++ b/indra/llcommon/llthread.h
@@ -35,7 +35,6 @@
#include "llapr.h"
#include "llapp.h"
-#include "llmemory.h"
#include "apr_thread_cond.h"
diff --git a/indra/llcommon/lltimer.cpp b/indra/llcommon/lltimer.cpp
index fa6efaf38e..ea5b0c03ef 100644
--- a/indra/llcommon/lltimer.cpp
+++ b/indra/llcommon/lltimer.cpp
@@ -561,32 +561,27 @@ void secondsToTimecodeString(F32 current_time, std::string& tcstring)
//
//////////////////////////////////////////////////////////////////////////////
-std::list<LLEventTimer*> LLEventTimer::sActiveList;
-
LLEventTimer::LLEventTimer(F32 period)
: mEventTimer()
{
mPeriod = period;
- sActiveList.push_back(this);
}
LLEventTimer::LLEventTimer(const LLDate& time)
: mEventTimer()
{
mPeriod = (F32)(time.secondsSinceEpoch() - LLDate::now().secondsSinceEpoch());
- sActiveList.push_back(this);
}
-LLEventTimer::~LLEventTimer()
+LLEventTimer::~LLEventTimer()
{
- sActiveList.remove(this);
}
void LLEventTimer::updateClass()
{
std::list<LLEventTimer*> completed_timers;
- for (std::list<LLEventTimer*>::iterator iter = sActiveList.begin(); iter != sActiveList.end(); )
+ for (instance_iter iter = beginInstances(); iter != endInstances(); )
{
LLEventTimer* timer = *iter++;
F32 et = timer->mEventTimer.getElapsedTimeF32();
diff --git a/indra/llcommon/lltimer.h b/indra/llcommon/lltimer.h
index e2cf1c7689..0319bec45b 100644
--- a/indra/llcommon/lltimer.h
+++ b/indra/llcommon/lltimer.h
@@ -40,6 +40,7 @@
#include "stdtypes.h"
#include "lldate.h"
+#include "llinstancetracker.h"
#include <string>
#include <list>
@@ -171,13 +172,13 @@ void microsecondsToTimecodeString(U64 current_time, std::string& tcstring);
void secondsToTimecodeString(F32 current_time, std::string& tcstring);
// class for scheduling a function to be called at a given frequency (approximate, inprecise)
-class LLEventTimer
+class LLEventTimer : protected LLInstanceTracker<LLEventTimer>
{
public:
LLEventTimer(F32 period); // period is the amount of time between each call to tick() in seconds
LLEventTimer(const LLDate& time);
virtual ~LLEventTimer();
-
+
//function to be called at the supplied frequency
// Normally return FALSE; TRUE will delete the timer after the function returns.
virtual BOOL tick() = 0;
@@ -187,10 +188,6 @@ public:
protected:
LLTimer mEventTimer;
F32 mPeriod;
-
-private:
- //list of active timers
- static std::list<LLEventTimer*> sActiveList; // TODO should this be a vector
};
#endif
diff --git a/indra/llcommon/lltreeiterators.h b/indra/llcommon/lltreeiterators.h
new file mode 100644
index 0000000000..c946566e84
--- /dev/null
+++ b/indra/llcommon/lltreeiterators.h
@@ -0,0 +1,711 @@
+/**
+ * @file lltreeiterators.h
+ * @author Nat Goodspeed
+ * @date 2008-08-19
+ * @brief This file defines iterators useful for traversing arbitrary node
+ * classes, potentially polymorphic, linked into strict tree
+ * structures.
+ *
+ * Dereferencing any one of these iterators actually yields a @em
+ * pointer to the node in question. For example, given an
+ * LLLinkedIter<MyNode> <tt>li</tt>, <tt>*li</tt> gets you a pointer
+ * to MyNode, and <tt>**li</tt> gets you the MyNode instance itself.
+ * More commonly, instead of writing <tt>li->member</tt>, you write
+ * <tt>(*li)->member</tt> -- as you would if you were traversing an
+ * STL container of MyNode pointers.
+ *
+ * It would certainly be possible to build these iterators so that
+ * <tt>*iterator</tt> would return a reference to the node itself
+ * rather than a pointer to the node, and for many purposes it would
+ * even be more convenient. However, that would be insufficiently
+ * flexible. If you want to use an iterator range to (e.g.) initialize
+ * a std::vector collecting results -- you rarely want to actually @em
+ * copy the nodes in question. You're much more likely to want to copy
+ * <i>pointers to</i> the traversed nodes. Hence these iterators
+ * produce pointers.
+ *
+ * Though you specify the actual NODE class as the template parameter,
+ * these iterators internally use LLPtrTo<> to discover whether to
+ * store and return an LLPointer<NODE> or a simple NODE*.
+ *
+ * By strict tree structures, we mean that each child must have
+ * exactly one parent. This forbids a child claiming any ancestor as a
+ * child of its own. Child nodes with multiple parents will be visited
+ * once for each parent. Cycles in the graph will result in either an
+ * infinite loop or an out-of-memory crash. You Have Been Warned.
+ *
+ * $LicenseInfo:firstyear=2008&license=viewergpl$
+ *
+ * Copyright (c) 2008-2009, Linden Research, Inc.
+ *
+ * Second Life Viewer Source Code
+ * The source code in this file ("Source Code") is provided by Linden Lab
+ * to you under the terms of the GNU General Public License, version 2.0
+ * ("GPL"), unless you have obtained a separate licensing agreement
+ * ("Other License"), formally executed by you and Linden Lab. Terms of
+ * the GPL can be found in doc/GPL-license.txt in this distribution, or
+ * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
+ *
+ * There are special exceptions to the terms and conditions of the GPL as
+ * it is applied to this Source Code. View the full text of the exception
+ * in the file doc/FLOSS-exception.txt in this software distribution, or
+ * online at
+ * http://secondlifegrid.net/programs/open_source/licensing/flossexception
+ *
+ * By copying, modifying or distributing this software, you acknowledge
+ * that you have read and understood your obligations described above,
+ * and agree to abide by those obligations.
+ *
+ * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+ * COMPLETENESS OR PERFORMANCE.
+ * $/LicenseInfo$
+ */
+
+#if ! defined(LL_LLTREEITERATORS_H)
+#define LL_LLTREEITERATORS_H
+
+#include "llptrto.h"
+#include <vector>
+#include <deque>
+#include <boost/iterator/iterator_facade.hpp>
+#include <boost/function.hpp>
+#include <boost/static_assert.hpp>
+
+namespace LLTreeIter
+{
+ /// Discriminator between LLTreeUpIter and LLTreeDownIter
+ enum RootIter { UP, DOWN };
+ /// Discriminator between LLTreeDFSIter, LLTreeDFSPostIter and LLTreeBFSIter
+ enum WalkIter { DFS_PRE, DFS_POST, BFS };
+}
+
+/**
+ * LLBaseIter defines some machinery common to all these iterators. We use
+ * boost::iterator_facade to define the iterator boilerplate: the conventional
+ * operators and methods necessary to implement a standards-conforming
+ * iterator. That allows us to specify the actual iterator semantics in terms
+ * of equal(), dereference() and increment() methods.
+ */
+template <class SELFTYPE, class NODE>
+class LLBaseIter: public boost::iterator_facade<SELFTYPE,
+ // use pointer type as the
+ // reference type
+ typename LLPtrTo<NODE>::type,
+ boost::forward_traversal_tag>
+{
+protected:
+ /// LLPtrTo<NODE>::type is either NODE* or LLPointer<NODE>, as appropriate
+ typedef typename LLPtrTo<NODE>::type ptr_type;
+ /// function that advances from this node to next accepts a node pointer
+ /// and returns another
+ typedef boost::function<ptr_type(const ptr_type&)> func_type;
+ typedef SELFTYPE self_type;
+};
+
+/// Functor returning NULL, suitable for an end-iterator's 'next' functor
+template <class NODE>
+typename LLPtrTo<NODE>::type LLNullNextFunctor(const typename LLPtrTo<NODE>::type&)
+{
+ return typename LLPtrTo<NODE>::type();
+}
+
+/**
+ * LLLinkedIter is an iterator over an intrusive singly-linked list. The
+ * beginning of the list is represented by LLLinkedIter(list head); the end is
+ * represented by LLLinkedIter().
+ *
+ * The begin LLLinkedIter must be instantiated with a functor to extract the
+ * 'next' pointer from the current node. Supposing that the link pointer is @c
+ * public, something like:
+ *
+ * @code
+ * NODE* mNext;
+ * @endcode
+ *
+ * you can use (e.g.) <tt>boost::bind(&NODE::mNext, _1)</tt> for the purpose.
+ * Alternatively, you can bind whatever accessor method is normally used to
+ * advance to the next node, e.g. for:
+ *
+ * @code
+ * NODE* next() const;
+ * @endcode
+ *
+ * you can use <tt>boost::bind(&NODE::next, _1)</tt>.
+ */
+template <class NODE>
+class LLLinkedIter: public LLBaseIter<LLLinkedIter<NODE>, NODE>
+{
+ typedef LLBaseIter<LLLinkedIter<NODE>, NODE> super;
+protected:
+ /// some methods need to return a reference to self
+ typedef typename super::self_type self_type;
+ typedef typename super::ptr_type ptr_type;
+ typedef typename super::func_type func_type;
+public:
+ /// Instantiate an LLLinkedIter to start a range, or to end a range before
+ /// a particular list entry. Pass a functor to extract the 'next' pointer
+ /// from the current node.
+ LLLinkedIter(const ptr_type& entry, const func_type& nextfunc):
+ mCurrent(entry),
+ mNextFunc(nextfunc)
+ {}
+ /// Instantiate an LLLinkedIter to end a range at the end of the list
+ LLLinkedIter():
+ mCurrent(),
+ mNextFunc(LLNullNextFunctor<NODE>)
+ {}
+
+private:
+ /// leverage boost::iterator_facade
+ friend class boost::iterator_core_access;
+
+ /// advance
+ void increment()
+ {
+ mCurrent = mNextFunc(mCurrent);
+ }
+ /// equality
+ bool equal(const self_type& that) const { return this->mCurrent == that.mCurrent; }
+ /// dereference
+ ptr_type& dereference() const { return const_cast<ptr_type&>(mCurrent); }
+
+ ptr_type mCurrent;
+ func_type mNextFunc;
+};
+
+/**
+ * LLTreeUpIter walks from the node in hand to the root of the tree. The term
+ * "up" is applied to a tree visualized with the root at the top.
+ *
+ * LLTreeUpIter is an alias for LLLinkedIter, since any linked tree that you
+ * can navigate that way at all contains parent pointers.
+ */
+template <class NODE>
+class LLTreeUpIter: public LLLinkedIter<NODE>
+{
+ typedef LLLinkedIter<NODE> super;
+public:
+ /// Instantiate an LLTreeUpIter to start from a particular tree node, or
+ /// to end a parent traversal before reaching a particular ancestor. Pass
+ /// a functor to extract the 'parent' pointer from the current node.
+ LLTreeUpIter(const typename super::ptr_type& node,
+ const typename super::func_type& parentfunc):
+ super(node, parentfunc)
+ {}
+ /// Instantiate an LLTreeUpIter to end a range at the root of the tree
+ LLTreeUpIter():
+ super()
+ {}
+};
+
+/**
+ * LLTreeDownIter walks from the root of the tree to the node in hand. The
+ * term "down" is applied to a tree visualized with the root at the top.
+ *
+ * Though you instantiate the begin() LLTreeDownIter with a pointer to some
+ * node at an arbitrary location in the tree, the root will be the first node
+ * you dereference and the passed node will be the last node you dereference.
+ *
+ * On construction, LLTreeDownIter walks from the current node to the root,
+ * capturing the path. Then in use, it replays that walk in reverse. As with
+ * all traversals of interesting data structures, it is actively dangerous to
+ * modify the tree during an LLTreeDownIter walk.
+ */
+template <class NODE>
+class LLTreeDownIter: public LLBaseIter<LLTreeDownIter<NODE>, NODE>
+{
+ typedef LLBaseIter<LLTreeDownIter<NODE>, NODE> super;
+ typedef typename super::self_type self_type;
+protected:
+ typedef typename super::ptr_type ptr_type;
+ typedef typename super::func_type func_type;
+private:
+ typedef std::vector<ptr_type> list_type;
+public:
+ /// Instantiate an LLTreeDownIter to end at a particular tree node. Pass a
+ /// functor to extract the 'parent' pointer from the current node.
+ LLTreeDownIter(const ptr_type& node,
+ const func_type& parentfunc)
+ {
+ for (ptr_type n = node; n; n = parentfunc(n))
+ mParents.push_back(n);
+ }
+ /// Instantiate an LLTreeDownIter representing "here", the end of the loop
+ LLTreeDownIter() {}
+
+private:
+ /// leverage boost::iterator_facade
+ friend class boost::iterator_core_access;
+
+ /// advance
+ void increment()
+ {
+ mParents.pop_back();
+ }
+ /// equality
+ bool equal(const self_type& that) const { return this->mParents == that.mParents; }
+ /// implement dereference/indirection operators
+ ptr_type& dereference() const { return const_cast<ptr_type&>(mParents.back()); }
+
+ list_type mParents;
+};
+
+/**
+ * When you want to select between LLTreeUpIter and LLTreeDownIter with a
+ * compile-time discriminator, use LLTreeRootIter with an LLTreeIter::RootIter
+ * template arg.
+ */
+template <LLTreeIter::RootIter DISCRIM, class NODE>
+class LLTreeRootIter
+{
+ enum { use_a_valid_LLTreeIter_RootIter_value = false };
+public:
+ /// Bogus constructors for default (unrecognized discriminator) case
+ template <typename TYPE1, typename TYPE2>
+ LLTreeRootIter(TYPE1, TYPE2)
+ {
+ BOOST_STATIC_ASSERT(use_a_valid_LLTreeIter_RootIter_value);
+ }
+ LLTreeRootIter()
+ {
+ BOOST_STATIC_ASSERT(use_a_valid_LLTreeIter_RootIter_value);
+ }
+};
+
+/// Specialize for LLTreeIter::UP
+template <class NODE>
+class LLTreeRootIter<LLTreeIter::UP, NODE>: public LLTreeUpIter<NODE>
+{
+ typedef LLTreeUpIter<NODE> super;
+public:
+ /// forward begin ctor
+ LLTreeRootIter(const typename super::ptr_type& node,
+ const typename super::func_type& parentfunc):
+ super(node, parentfunc)
+ {}
+ /// forward end ctor
+ LLTreeRootIter():
+ super()
+ {}
+};
+
+/// Specialize for LLTreeIter::DOWN
+template <class NODE>
+class LLTreeRootIter<LLTreeIter::DOWN, NODE>: public LLTreeDownIter<NODE>
+{
+ typedef LLTreeDownIter<NODE> super;
+public:
+ /// forward begin ctor
+ LLTreeRootIter(const typename super::ptr_type& node,
+ const typename super::func_type& parentfunc):
+ super(node, parentfunc)
+ {}
+ /// forward end ctor
+ LLTreeRootIter():
+ super()
+ {}
+};
+
+/**
+ * Instantiated with a tree node, typically the root, LLTreeDFSIter "flattens"
+ * a depth-first tree walk through that node and all its descendants.
+ *
+ * The begin() LLTreeDFSIter must be instantiated with functors to obtain from
+ * a given node begin() and end() iterators for that node's children. For this
+ * reason, you must specify the type of the node's child iterator as an
+ * additional template parameter.
+ *
+ * Specifically, the begin functor must return an iterator whose dereferenced
+ * value is a @em pointer to a child tree node. For instance, if each node
+ * tracks its children in an STL container of node* pointers, you can simply
+ * return that container's begin() iterator.
+ *
+ * Alternatively, if a node tracks its children with a classic linked list,
+ * write a functor returning LLLinkedIter<NODE>.
+ *
+ * The end() LLTreeDFSIter must, of course, match the begin() iterator's
+ * template parameters, but is constructed without runtime parameters.
+ */
+template <class NODE, typename CHILDITER>
+class LLTreeDFSIter: public LLBaseIter<LLTreeDFSIter<NODE, CHILDITER>, NODE>
+{
+ typedef LLBaseIter<LLTreeDFSIter<NODE, CHILDITER>, NODE> super;
+ typedef typename super::self_type self_type;
+protected:
+ typedef typename super::ptr_type ptr_type;
+ // The func_type is different for this: from a NODE pointer, we must
+ // obtain a CHILDITER.
+ typedef boost::function<CHILDITER(const ptr_type&)> func_type;
+private:
+ typedef std::vector<ptr_type> list_type;
+public:
+ /// Instantiate an LLTreeDFSIter to start a depth-first walk. Pass
+ /// functors to extract the 'child begin' and 'child end' iterators from
+ /// each node.
+ LLTreeDFSIter(const ptr_type& node, const func_type& beginfunc, const func_type& endfunc):
+ mBeginFunc(beginfunc),
+ mEndFunc(endfunc),
+ mSkipChildren(false)
+ {
+ // Only push back this node if it's non-NULL!
+ if (node)
+ mPending.push_back(node);
+ }
+ /// Instantiate an LLTreeDFSIter to mark the end of the walk
+ LLTreeDFSIter() {}
+
+ /// flags iterator logic to skip traversing children of current node on next increment
+ void skipDescendants(bool skip = true) { mSkipChildren = skip; }
+
+private:
+ /// leverage boost::iterator_facade
+ friend class boost::iterator_core_access;
+
+ /// advance
+ /// This implementation is due to http://en.wikipedia.org/wiki/Depth-first_search
+ void increment()
+ {
+ // Capture the node we were just looking at
+ ptr_type current = mPending.back();
+ // Remove it from mPending so we don't process it again later
+ mPending.pop_back();
+ if (!mSkipChildren)
+ {
+ // Add all its children to mPending
+ addChildren(current);
+ }
+ // reset flag after each step
+ mSkipChildren = false;
+ }
+ /// equality
+ bool equal(const self_type& that) const { return this->mPending == that.mPending; }
+ /// implement dereference/indirection operators
+ ptr_type& dereference() const { return const_cast<ptr_type&>(mPending.back()); }
+
+ /// Add the direct children of the specified node to mPending
+ void addChildren(const ptr_type& node)
+ {
+ // If we just use push_back() for each child in turn, we'll end up
+ // processing children in reverse order. We don't want to assume
+ // CHILDITER is reversible: some of the linked trees we'll be
+ // processing manage their children using singly-linked lists. So
+ // figure out how many children there are, grow mPending by that size
+ // and reverse-copy the children into the new space.
+ CHILDITER chi = mBeginFunc(node), chend = mEndFunc(node);
+ // grow mPending by the number of children
+ mPending.resize(mPending.size() + std::distance(chi, chend));
+ // reverse-copy the children into the newly-expanded space
+ std::copy(chi, chend, mPending.rbegin());
+ }
+
+ /// list of the nodes yet to be processed
+ list_type mPending;
+ /// functor to extract begin() child iterator
+ func_type mBeginFunc;
+ /// functor to extract end() child iterator
+ func_type mEndFunc;
+ /// flag which controls traversal of children (skip children of current node if true)
+ bool mSkipChildren;
+};
+
+/**
+ * Instantiated with a tree node, typically the root, LLTreeDFSPostIter
+ * "flattens" a depth-first tree walk through that node and all its
+ * descendants. Whereas LLTreeDFSIter visits each node before visiting any of
+ * its children, LLTreeDFSPostIter visits all of a node's children before
+ * visiting the node itself.
+ *
+ * The begin() LLTreeDFSPostIter must be instantiated with functors to obtain
+ * from a given node begin() and end() iterators for that node's children. For
+ * this reason, you must specify the type of the node's child iterator as an
+ * additional template parameter.
+ *
+ * Specifically, the begin functor must return an iterator whose dereferenced
+ * value is a @em pointer to a child tree node. For instance, if each node
+ * tracks its children in an STL container of node* pointers, you can simply
+ * return that container's begin() iterator.
+ *
+ * Alternatively, if a node tracks its children with a classic linked list,
+ * write a functor returning LLLinkedIter<NODE>.
+ *
+ * The end() LLTreeDFSPostIter must, of course, match the begin() iterator's
+ * template parameters, but is constructed without runtime parameters.
+ */
+template <class NODE, typename CHILDITER>
+class LLTreeDFSPostIter: public LLBaseIter<LLTreeDFSPostIter<NODE, CHILDITER>, NODE>
+{
+ typedef LLBaseIter<LLTreeDFSPostIter<NODE, CHILDITER>, NODE> super;
+ typedef typename super::self_type self_type;
+protected:
+ typedef typename super::ptr_type ptr_type;
+ // The func_type is different for this: from a NODE pointer, we must
+ // obtain a CHILDITER.
+ typedef boost::function<CHILDITER(const ptr_type&)> func_type;
+private:
+ // Upon reaching a given node in our pending list, we need to know whether
+ // we've already pushed that node's children, so we must associate a bool
+ // with each node pointer.
+ typedef std::vector< std::pair<ptr_type, bool> > list_type;
+public:
+ /// Instantiate an LLTreeDFSPostIter to start a depth-first walk. Pass
+ /// functors to extract the 'child begin' and 'child end' iterators from
+ /// each node.
+ LLTreeDFSPostIter(const ptr_type& node, const func_type& beginfunc, const func_type& endfunc):
+ mBeginFunc(beginfunc),
+ mEndFunc(endfunc),
+ mSkipAncestors(false)
+ {
+ if (! node)
+ return;
+ mPending.push_back(typename list_type::value_type(node, false));
+ makeCurrent();
+ }
+ /// Instantiate an LLTreeDFSPostIter to mark the end of the walk
+ LLTreeDFSPostIter() {}
+
+ /// flags iterator logic to skip traversing ancestors of current node on next increment
+ void skipAncestors(bool skip = true) { mSkipAncestors = skip; }
+
+private:
+ /// leverage boost::iterator_facade
+ friend class boost::iterator_core_access;
+
+ /// advance
+ /// This implementation is due to http://en.wikipedia.org/wiki/Depth-first_search
+ void increment()
+ {
+ // Pop the previous current node
+ mPending.pop_back();
+ makeCurrent();
+ }
+ /// equality
+ bool equal(const self_type& that) const { return this->mPending == that.mPending; }
+ /// implement dereference/indirection operators
+ ptr_type& dereference() const { return const_cast<ptr_type&>(mPending.back().first); }
+
+ struct isOpen
+ {
+ bool operator()(const typename list_type::value_type& item)
+ {
+ return item.second;
+ }
+ };
+
+ /// Call this each time we change mPending.back() -- that is, every time
+ /// we're about to change the value returned by dereference(). If we
+ /// haven't yet pushed the new node's children, do so now.
+ void makeCurrent()
+ {
+ if (mSkipAncestors)
+ {
+ mPending.erase(std::remove_if(mPending.begin(), mPending.end(), isOpen()), mPending.end());
+ mSkipAncestors = false;
+ }
+
+ // Once we've popped the last node, this becomes a no-op.
+ if (mPending.empty())
+ return;
+ // Here mPending.back() holds the node pointer we're proposing to
+ // dereference next. Have we pushed that node's children yet?
+ if (mPending.back().second)
+ return; // if so, it's okay to visit this node now
+ // We haven't yet pushed this node's children. Do so now. Remember
+ // that we did -- while the node in question is still back().
+ mPending.back().second = true;
+ addChildren(mPending.back().first);
+ // Now, because we've just changed mPending.back(), make that new node
+ // current.
+ makeCurrent();
+ }
+
+ /// Add the direct children of the specified node to mPending
+ void addChildren(const ptr_type& node)
+ {
+ // If we just use push_back() for each child in turn, we'll end up
+ // processing children in reverse order. We don't want to assume
+ // CHILDITER is reversible: some of the linked trees we'll be
+ // processing manage their children using singly-linked lists. So
+ // figure out how many children there are, grow mPending by that size
+ // and reverse-copy the children into the new space.
+ CHILDITER chi = mBeginFunc(node), chend = mEndFunc(node);
+ // grow mPending by the number of children
+ mPending.resize(mPending.size() + std::distance(chi, chend));
+ // Reverse-copy the children into the newly-expanded space. We can't
+ // just use std::copy() because the source is a ptr_type, whereas the
+ // dest is a pair of (ptr_type, bool).
+ for (typename list_type::reverse_iterator pi = mPending.rbegin(); chi != chend; ++chi, ++pi)
+ {
+ pi->first = *chi; // copy the child pointer
+ pi->second = false; // we haven't yet pushed this child's chldren
+ }
+ }
+
+ /// list of the nodes yet to be processed
+ list_type mPending;
+ /// functor to extract begin() child iterator
+ func_type mBeginFunc;
+ /// functor to extract end() child iterator
+ func_type mEndFunc;
+ /// flags logic to skip traversal of ancestors of current node
+ bool mSkipAncestors;
+};
+
+/**
+ * Instantiated with a tree node, typically the root, LLTreeBFSIter "flattens"
+ * a breadth-first tree walk through that node and all its descendants.
+ *
+ * The begin() LLTreeBFSIter must be instantiated with functors to obtain from
+ * a given node the begin() and end() iterators of that node's children. For
+ * this reason, you must specify the type of the node's child iterator as an
+ * additional template parameter.
+ *
+ * Specifically, the begin functor must return an iterator whose dereferenced
+ * value is a @em pointer to a child tree node. For instance, if each node
+ * tracks its children in an STL container of node* pointers, you can simply
+ * return that container's begin() iterator.
+ *
+ * Alternatively, if a node tracks its children with a classic linked list,
+ * write a functor returning LLLinkedIter<NODE>.
+ *
+ * The end() LLTreeBFSIter must, of course, match the begin() iterator's
+ * template parameters, but is constructed without runtime parameters.
+ */
+template <class NODE, typename CHILDITER>
+class LLTreeBFSIter: public LLBaseIter<LLTreeBFSIter<NODE, CHILDITER>, NODE>
+{
+ typedef LLBaseIter<LLTreeBFSIter<NODE, CHILDITER>, NODE> super;
+ typedef typename super::self_type self_type;
+protected:
+ typedef typename super::ptr_type ptr_type;
+ // The func_type is different for this: from a NODE pointer, we must
+ // obtain a CHILDITER.
+ typedef boost::function<CHILDITER(const ptr_type&)> func_type;
+private:
+ // We need a FIFO queue rather than a LIFO stack. Use a deque rather than
+ // a vector, since vector can't implement pop_front() efficiently.
+ typedef std::deque<ptr_type> list_type;
+public:
+ /// Instantiate an LLTreeBFSIter to start a depth-first walk. Pass
+ /// functors to extract the 'child begin' and 'child end' iterators from
+ /// each node.
+ LLTreeBFSIter(const ptr_type& node, const func_type& beginfunc, const func_type& endfunc):
+ mBeginFunc(beginfunc),
+ mEndFunc(endfunc)
+ {
+ if (node)
+ mPending.push_back(node);
+ }
+ /// Instantiate an LLTreeBFSIter to mark the end of the walk
+ LLTreeBFSIter() {}
+
+private:
+ /// leverage boost::iterator_facade
+ friend class boost::iterator_core_access;
+
+ /// advance
+ /// This implementation is due to http://en.wikipedia.org/wiki/Breadth-first_search
+ void increment()
+ {
+ // Capture the node we were just looking at
+ ptr_type current = mPending.front();
+ // Remove it from mPending so we don't process it again later
+ mPending.pop_front();
+ // Add all its children to mPending
+ CHILDITER chend = mEndFunc(current);
+ for (CHILDITER chi = mBeginFunc(current); chi != chend; ++chi)
+ mPending.push_back(*chi);
+ }
+ /// equality
+ bool equal(const self_type& that) const { return this->mPending == that.mPending; }
+ /// implement dereference/indirection operators
+ ptr_type& dereference() const { return const_cast<ptr_type&>(mPending.front()); }
+
+ /// list of the nodes yet to be processed
+ list_type mPending;
+ /// functor to extract begin() child iterator
+ func_type mBeginFunc;
+ /// functor to extract end() child iterator
+ func_type mEndFunc;
+};
+
+/**
+ * When you want to select between LLTreeDFSIter, LLTreeDFSPostIter and
+ * LLTreeBFSIter with a compile-time discriminator, use LLTreeWalkIter with an
+ * LLTreeIter::WalkIter template arg.
+ */
+template <LLTreeIter::WalkIter DISCRIM, class NODE, typename CHILDITER>
+class LLTreeWalkIter
+{
+ enum { use_a_valid_LLTreeIter_WalkIter_value = false };
+public:
+ /// Bogus constructors for default (unrecognized discriminator) case
+ template <typename TYPE1, typename TYPE2>
+ LLTreeWalkIter(TYPE1, TYPE2)
+ {
+ BOOST_STATIC_ASSERT(use_a_valid_LLTreeIter_WalkIter_value);
+ }
+ LLTreeWalkIter()
+ {
+ BOOST_STATIC_ASSERT(use_a_valid_LLTreeIter_WalkIter_value);
+ }
+};
+
+/// Specialize for LLTreeIter::DFS_PRE
+template <class NODE, typename CHILDITER>
+class LLTreeWalkIter<LLTreeIter::DFS_PRE, NODE, CHILDITER>:
+ public LLTreeDFSIter<NODE, CHILDITER>
+{
+ typedef LLTreeDFSIter<NODE, CHILDITER> super;
+public:
+ /// forward begin ctor
+ LLTreeWalkIter(const typename super::ptr_type& node,
+ const typename super::func_type& beginfunc,
+ const typename super::func_type& endfunc):
+ super(node, beginfunc, endfunc)
+ {}
+ /// forward end ctor
+ LLTreeWalkIter():
+ super()
+ {}
+};
+
+/// Specialize for LLTreeIter::DFS_POST
+template <class NODE, typename CHILDITER>
+class LLTreeWalkIter<LLTreeIter::DFS_POST, NODE, CHILDITER>:
+ public LLTreeDFSPostIter<NODE, CHILDITER>
+{
+ typedef LLTreeDFSPostIter<NODE, CHILDITER> super;
+public:
+ /// forward begin ctor
+ LLTreeWalkIter(const typename super::ptr_type& node,
+ const typename super::func_type& beginfunc,
+ const typename super::func_type& endfunc):
+ super(node, beginfunc, endfunc)
+ {}
+ /// forward end ctor
+ LLTreeWalkIter():
+ super()
+ {}
+};
+
+/// Specialize for LLTreeIter::BFS
+template <class NODE, typename CHILDITER>
+class LLTreeWalkIter<LLTreeIter::BFS, NODE, CHILDITER>:
+ public LLTreeBFSIter<NODE, CHILDITER>
+{
+ typedef LLTreeBFSIter<NODE, CHILDITER> super;
+public:
+ /// forward begin ctor
+ LLTreeWalkIter(const typename super::ptr_type& node,
+ const typename super::func_type& beginfunc,
+ const typename super::func_type& endfunc):
+ super(node, beginfunc, endfunc)
+ {}
+ /// forward end ctor
+ LLTreeWalkIter():
+ super()
+ {}
+};
+
+#endif /* ! defined(LL_LLTREEITERATORS_H) */
diff --git a/indra/llcommon/llversionviewer.h b/indra/llcommon/llversionviewer.h
index 7e623d47d6..45810a101d 100644
--- a/indra/llcommon/llversionviewer.h
+++ b/indra/llcommon/llversionviewer.h
@@ -33,11 +33,11 @@
#ifndef LL_LLVERSIONVIEWER_H
#define LL_LLVERSIONVIEWER_H
-const S32 LL_VERSION_MAJOR = 1;
-const S32 LL_VERSION_MINOR = 24;
-const S32 LL_VERSION_PATCH = 4;
+const S32 LL_VERSION_MAJOR = 2;
+const S32 LL_VERSION_MINOR = 0;
+const S32 LL_VERSION_PATCH = 0;
const S32 LL_VERSION_BUILD = 0;
-const char * const LL_CHANNEL = "Second Life Release";
+const char * const LL_CHANNEL = "Second Life 2009";
#endif
diff --git a/indra/llcommon/tests/llallocator_heap_profile_test.cpp b/indra/llcommon/tests/llallocator_heap_profile_test.cpp
new file mode 100644
index 0000000000..7369fdc8bc
--- /dev/null
+++ b/indra/llcommon/tests/llallocator_heap_profile_test.cpp
@@ -0,0 +1,150 @@
+/**
+ * @file llallocator_heap_profile_test.cpp
+ * @author Brad Kittenbrink
+ * @date 2008-02-
+ * @brief Test for llallocator_heap_profile.cpp.
+ *
+ * $LicenseInfo:firstyear=2009&license=viewergpl$
+ *
+ * Copyright (c) 2009-2009, Linden Research, Inc.
+ *
+ * Second Life Viewer Source Code
+ * The source code in this file ("Source Code") is provided by Linden Lab
+ * to you under the terms of the GNU General Public License, version 2.0
+ * ("GPL"), unless you have obtained a separate licensing agreement
+ * ("Other License"), formally executed by you and Linden Lab. Terms of
+ * the GPL can be found in doc/GPL-license.txt in this distribution, or
+ * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
+ *
+ * There are special exceptions to the terms and conditions of the GPL as
+ * it is applied to this Source Code. View the full text of the exception
+ * in the file doc/FLOSS-exception.txt in this software distribution, or
+ * online at
+ * http://secondlifegrid.net/programs/open_source/licensing/flossexception
+ *
+ * By copying, modifying or distributing this software, you acknowledge
+ * that you have read and understood your obligations described above,
+ * and agree to abide by those obligations.
+ *
+ * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+ * COMPLETENESS OR PERFORMANCE.
+ * $/LicenseInfo$
+ */
+
+#include "../llallocator_heap_profile.h"
+#include "../test/lltut.h"
+
+namespace tut
+{
+ struct llallocator_heap_profile_data
+ {
+ LLAllocatorHeapProfile prof;
+
+ static char const * const sample_win_profile;
+ // *TODO - get test output from mac/linux tcmalloc
+ static char const * const sample_mac_profile;
+ static char const * const sample_lin_profile;
+
+ static char const * const crash_testcase;
+ };
+ typedef test_group<llallocator_heap_profile_data> factory;
+ typedef factory::object object;
+}
+namespace
+{
+ tut::factory llallocator_heap_profile_test_factory("LLAllocatorHeapProfile");
+}
+
+namespace tut
+{
+ template<> template<>
+ void object::test<1>()
+ {
+ prof.parse(sample_win_profile);
+
+ ensure_equals("count lines", prof.mLines.size() , 5);
+ ensure_equals("alloc counts", prof.mLines[0].mLiveCount, 2131854U);
+ ensure_equals("alloc counts", prof.mLines[0].mLiveSize, 2245710106ULL);
+ ensure_equals("alloc counts", prof.mLines[0].mTotalCount, 14069198U);
+ ensure_equals("alloc counts", prof.mLines[0].mTotalSize, 4295177308ULL);
+ ensure_equals("count markers", prof.mLines[0].mTrace.size(), 0);
+ ensure_equals("count markers", prof.mLines[1].mTrace.size(), 0);
+ ensure_equals("count markers", prof.mLines[2].mTrace.size(), 4);
+ ensure_equals("count markers", prof.mLines[3].mTrace.size(), 6);
+ ensure_equals("count markers", prof.mLines[4].mTrace.size(), 7);
+
+ //prof.dump(std::cout);
+ }
+
+ template<> template<>
+ void object::test<2>()
+ {
+ prof.parse(crash_testcase);
+
+ ensure_equals("count lines", prof.mLines.size(), 2);
+ ensure_equals("alloc counts", prof.mLines[0].mLiveCount, 3U);
+ ensure_equals("alloc counts", prof.mLines[0].mLiveSize, 1049652ULL);
+ ensure_equals("alloc counts", prof.mLines[0].mTotalCount, 8U);
+ ensure_equals("alloc counts", prof.mLines[0].mTotalSize, 1049748ULL);
+ ensure_equals("count markers", prof.mLines[0].mTrace.size(), 0);
+ ensure_equals("count markers", prof.mLines[1].mTrace.size(), 0);
+
+ //prof.dump(std::cout);
+ }
+
+ template<> template<>
+ void object::test<3>()
+ {
+ // test that we don't crash on edge case data
+ prof.parse("");
+ ensure("emtpy on error", prof.mLines.empty());
+
+ prof.parse("heap profile:");
+ ensure("emtpy on error", prof.mLines.empty());
+ }
+
+char const * const llallocator_heap_profile_data::sample_win_profile =
+"heap profile: 2131854: 2245710106 [14069198: 4295177308] @\n"
+"308592: 1073398388 [966564: 1280998739] @\n"
+"462651: 375969538 [1177377: 753561247] @ 2 3 6 1\n"
+"314744: 206611283 [2008722: 570934755] @ 2 3 3 7 21 32\n"
+"277152: 82862770 [621961: 168503640] @ 2 3 3 7 21 32 87\n"
+"\n"
+"MAPPED_LIBRARIES:\n"
+"00400000-02681000 r-xp 00000000 00:00 0 c:\\proj\\tcmalloc-eval-9\\indra\\build-vc80\\newview\\RelWithDebInfo\\secondlife-bin.exe\n"
+"77280000-773a7000 r-xp 00000000 00:00 0 C:\\Windows\\system32\\ntdll.dll\n"
+"76df0000-76ecb000 r-xp 00000000 00:00 0 C:\\Windows\\system32\\kernel32.dll\n"
+"76000000-76073000 r-xp 00000000 00:00 0 C:\\Windows\\system32\\comdlg32.dll\n"
+"75ee0000-75f8a000 r-xp 00000000 00:00 0 C:\\Windows\\system32\\msvcrt.dll\n"
+"76c30000-76c88000 r-xp 00000000 00:00 0 C:\\Windows\\system32\\SHLWAPI.dll\n"
+"75f90000-75fdb000 r-xp 00000000 00:00 0 C:\\Windows\\system32\\GDI32.dll\n"
+"77420000-774bd000 r-xp 00000000 00:00 0 C:\\Windows\\system32\\USER32.dll\n"
+"75e10000-75ed6000 r-xp 00000000 00:00 0 C:\\Windows\\system32\\ADVAPI32.dll\n"
+"75b00000-75bc2000 r-xp 00000000 00:00 0 C:\\Windows\\system32\\RPCRT4.dll\n"
+"72ca0000-72d25000 r-xp 00000000 00:00 0 C:\\Windows\\WinSxS\\x86_microsoft.windows.common-controls_6595b64144ccf1df_5.82.6001.18000_none_886786f450a74a05\\COMCTL32.dll\n"
+"76120000-76c30000 r-xp 00000000 00:00 0 C:\\Windows\\system32\\SHELL32.dll\n"
+"71ce0000-71d13000 r-xp 00000000 00:00 0 C:\\Windows\\system32\\DINPUT8.dll\n";
+
+
+char const * const llallocator_heap_profile_data::crash_testcase =
+"heap profile: 3: 1049652 [ 8: 1049748] @\n"
+" 3: 1049652 [ 8: 1049748] @\n"
+"\n"
+"MAPPED_LIBRARIES:\n"
+"00400000-004d5000 r-xp 00000000 00:00 0 c:\\code\\linden\\tcmalloc\\indra\\build-vc80\\llcommon\\RelWithDebInfo\\llallocator_test.exe\n"
+"7c900000-7c9af000 r-xp 00000000 00:00 0 C:\\WINDOWS\\system32\\ntdll.dll\n"
+"7c800000-7c8f6000 r-xp 00000000 00:00 0 C:\\WINDOWS\\system32\\kernel32.dll\n"
+"77dd0000-77e6b000 r-xp 00000000 00:00 0 C:\\WINDOWS\\system32\\ADVAPI32.dll\n"
+"77e70000-77f02000 r-xp 00000000 00:00 0 C:\\WINDOWS\\system32\\RPCRT4.dll\n"
+"77fe0000-77ff1000 r-xp 00000000 00:00 0 C:\\WINDOWS\\system32\\Secur32.dll\n"
+"71ab0000-71ac7000 r-xp 00000000 00:00 0 C:\\WINDOWS\\system32\\WS2_32.dll\n"
+"77c10000-77c68000 r-xp 00000000 00:00 0 C:\\WINDOWS\\system32\\msvcrt.dll\n"
+"71aa0000-71aa8000 r-xp 00000000 00:00 0 C:\\WINDOWS\\system32\\WS2HELP.dll\n"
+"76bf0000-76bfb000 r-xp 00000000 00:00 0 C:\\WINDOWS\\system32\\PSAPI.DLL\n"
+"5b860000-5b8b5000 r-xp 00000000 00:00 0 C:\\WINDOWS\\system32\\NETAPI32.dll\n"
+"10000000-10041000 r-xp 00000000 00:00 0 c:\\code\\linden\\tcmalloc\\indra\\build-vc80\\llcommon\\RelWithDebInfo\\libtcmalloc_minimal.dll\n"
+"7c420000-7c4a7000 r-xp 00000000 00:00 0 C:\\WINDOWS\\WinSxS\\x86_Microsoft.VC80.CRT_1fc8b3b9a1e18e3b_8.0.50727.1433_x-ww_5cf844d2\\MSVCP80.dll\n"
+"78130000-781cb000 r-xp 00000000 00:00 0 C:\\WINDOWS\\WinSxS\\x86_Microsoft.VC80.CRT_1fc8b3b9a1e18e3b_8.0.50727.1433_x-ww_5cf844d2\\MSVCR80.dll\n";
+
+}
diff --git a/indra/llcommon/tests/llallocator_test.cpp b/indra/llcommon/tests/llallocator_test.cpp
new file mode 100644
index 0000000000..9db95f4273
--- /dev/null
+++ b/indra/llcommon/tests/llallocator_test.cpp
@@ -0,0 +1,86 @@
+/**
+ * @file llallocator_test.cpp
+ * @author Brad Kittenbrink
+ * @date 2008-02-
+ * @brief Test for llallocator.cpp.
+ *
+ * $LicenseInfo:firstyear=2009&license=viewergpl$
+ *
+ * Copyright (c) 2009-2009, Linden Research, Inc.
+ *
+ * Second Life Viewer Source Code
+ * The source code in this file ("Source Code") is provided by Linden Lab
+ * to you under the terms of the GNU General Public License, version 2.0
+ * ("GPL"), unless you have obtained a separate licensing agreement
+ * ("Other License"), formally executed by you and Linden Lab. Terms of
+ * the GPL can be found in doc/GPL-license.txt in this distribution, or
+ * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
+ *
+ * There are special exceptions to the terms and conditions of the GPL as
+ * it is applied to this Source Code. View the full text of the exception
+ * in the file doc/FLOSS-exception.txt in this software distribution, or
+ * online at
+ * http://secondlifegrid.net/programs/open_source/licensing/flossexception
+ *
+ * By copying, modifying or distributing this software, you acknowledge
+ * that you have read and understood your obligations described above,
+ * and agree to abide by those obligations.
+ *
+ * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+ * COMPLETENESS OR PERFORMANCE.
+ * $/LicenseInfo$
+ */
+
+#include "../llallocator.h"
+#include "../test/lltut.h"
+
+namespace tut
+{
+ struct llallocator_data
+ {
+ LLAllocator llallocator;
+ };
+ typedef test_group<llallocator_data> factory;
+ typedef factory::object object;
+}
+namespace
+{
+ tut::factory llallocator_test_factory("LLAllocator");
+}
+
+namespace tut
+{
+ template<> template<>
+ void object::test<1>()
+ {
+ llallocator.setProfilingEnabled(false);
+ ensure("Profiler disable", !llallocator.isProfiling());
+ }
+
+#if LL_USE_TCMALLOC
+ template<> template<>
+ void object::test<2>()
+ {
+ llallocator.setProfilingEnabled(true);
+ ensure("Profiler enable", llallocator.isProfiling());
+ }
+
+ template <> template <>
+ void object::test<3>()
+ {
+ llallocator.setProfilingEnabled(true);
+
+ char * test_alloc = new char[1024];
+
+ llallocator.getProfile();
+
+ delete [] test_alloc;
+
+ llallocator.getProfile();
+
+ // *NOTE - this test isn't ensuring anything right now other than no
+ // exceptions are thrown.
+ }
+#endif // LL_USE_TCMALLOC
+};
diff --git a/indra/llcommon/tests/llmemtype_test.cpp b/indra/llcommon/tests/llmemtype_test.cpp
new file mode 100644
index 0000000000..6cc5ce01ce
--- /dev/null
+++ b/indra/llcommon/tests/llmemtype_test.cpp
@@ -0,0 +1,123 @@
+/**
+ * @file llmemtype_test.cpp
+ * @author Palmer Truelson
+ * @date 2008-03-
+ * @brief Test for llmemtype.cpp.
+ *
+ * $LicenseInfo:firstyear=2009&license=viewergpl$
+ *
+ * Copyright (c) 2009-2009, Linden Research, Inc.
+ *
+ * Second Life Viewer Source Code
+ * The source code in this file ("Source Code") is provided by Linden Lab
+ * to you under the terms of the GNU General Public License, version 2.0
+ * ("GPL"), unless you have obtained a separate licensing agreement
+ * ("Other License"), formally executed by you and Linden Lab. Terms of
+ * the GPL can be found in doc/GPL-license.txt in this distribution, or
+ * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
+ *
+ * There are special exceptions to the terms and conditions of the GPL as
+ * it is applied to this Source Code. View the full text of the exception
+ * in the file doc/FLOSS-exception.txt in this software distribution, or
+ * online at
+ * http://secondlifegrid.net/programs/open_source/licensing/flossexception
+ *
+ * By copying, modifying or distributing this software, you acknowledge
+ * that you have read and understood your obligations described above,
+ * and agree to abide by those obligations.
+ *
+ * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+ * COMPLETENESS OR PERFORMANCE.
+ * $/LicenseInfo$
+ */
+
+#include "../llmemtype.h"
+#include "../test/lltut.h"
+#include "../llallocator.h"
+
+
+#include <stack>
+
+std::stack<S32> memTypeStack;
+
+void LLAllocator::pushMemType(S32 i)
+{
+ memTypeStack.push(i);
+}
+
+S32 LLAllocator::popMemType(void)
+{
+ S32 ret = memTypeStack.top();
+ memTypeStack.pop();
+ return ret;
+}
+
+namespace tut
+{
+ struct llmemtype_data
+ {
+ };
+
+ typedef test_group<llmemtype_data> factory;
+ typedef factory::object object;
+}
+namespace
+{
+ tut::factory llmemtype_test_factory("LLMemType");
+}
+
+namespace tut
+{
+ template<> template<>
+ void object::test<1>()
+ {
+ ensure("Simplest test ever", true);
+ }
+
+ // test with no scripts
+ template<> template<>
+ void object::test<2>()
+ {
+ {
+ LLMemType m1(LLMemType::MTYPE_INIT);
+ }
+ ensure("Test that you can construct and destruct the mem type");
+ }
+
+ // test creation and stack testing
+ template<> template<>
+ void object::test<3>()
+ {
+ {
+ ensure("Test that creation and destruction properly inc/dec the stack");
+ ensure_equals(memTypeStack.size(), 0);
+ {
+ LLMemType m1(LLMemType::MTYPE_INIT);
+ ensure_equals(memTypeStack.size(), 1);
+ LLMemType m2(LLMemType::MTYPE_STARTUP);
+ ensure_equals(memTypeStack.size(), 2);
+ }
+ ensure_equals(memTypeStack.size(), 0);
+ }
+ }
+
+ // test with no scripts
+ template<> template<>
+ void object::test<4>()
+ {
+ // catch the begining and end
+ std::string test_name = LLMemType::getNameFromID(LLMemType::MTYPE_INIT.mID);
+ ensure_equals("Init name", test_name, "Init");
+
+ std::string test_name2 = LLMemType::getNameFromID(LLMemType::MTYPE_VOLUME.mID);
+ ensure_equals("Volume name", test_name2, "Volume");
+
+ std::string test_name3 = LLMemType::getNameFromID(LLMemType::MTYPE_OTHER.mID);
+ ensure_equals("Other name", test_name3, "Other");
+
+ std::string test_name4 = LLMemType::getNameFromID(-1);
+ ensure_equals("Invalid name", test_name4, "INVALID");
+ }
+
+};
diff --git a/indra/llcrashlogger/llcrashlogger.cpp b/indra/llcrashlogger/llcrashlogger.cpp
index d83d9d18bf..c1022c1195 100755
--- a/indra/llcrashlogger/llcrashlogger.cpp
+++ b/indra/llcrashlogger/llcrashlogger.cpp
@@ -86,6 +86,7 @@ void LLCrashLoggerText::updateApplication(const std::string& message)
LLCrashLogger::LLCrashLogger() :
mCrashBehavior(CRASH_BEHAVIOR_ASK),
mCrashInPreviousExec(false),
+ mCrashSettings("CrashSettings"),
mSentCrashLogs(false),
mCrashHost("")
{
diff --git a/indra/llimage/llimage.cpp b/indra/llimage/llimage.cpp
index 93ddc65f32..488f3bf78d 100644
--- a/indra/llimage/llimage.cpp
+++ b/indra/llimage/llimage.cpp
@@ -152,7 +152,7 @@ void LLImageBase::deleteData()
// virtual
U8* LLImageBase::allocateData(S32 size)
{
- LLMemType mt1((LLMemType::EMemType)mMemType);
+ LLMemType mt1(mMemType);
if (size < 0)
{
@@ -188,7 +188,7 @@ U8* LLImageBase::allocateData(S32 size)
// virtual
U8* LLImageBase::reallocateData(S32 size)
{
- LLMemType mt1((LLMemType::EMemType)mMemType);
+ LLMemType mt1(mMemType);
U8 *new_datap = new U8[size];
if (!new_datap)
{
@@ -332,7 +332,7 @@ BOOL LLImageRaw::resize(U16 width, U16 height, S8 components)
U8 * LLImageRaw::getSubImage(U32 x_pos, U32 y_pos, U32 width, U32 height) const
{
- LLMemType mt1((LLMemType::EMemType)mMemType);
+ LLMemType mt1(mMemType);
U8 *data = new U8[width*height*getComponents()];
// Should do some simple bounds checking
@@ -415,7 +415,7 @@ void LLImageRaw::clear(U8 r, U8 g, U8 b, U8 a)
// Reverses the order of the rows in the image
void LLImageRaw::verticalFlip()
{
- LLMemType mt1((LLMemType::EMemType)mMemType);
+ LLMemType mt1(mMemType);
S32 row_bytes = getWidth() * getComponents();
llassert(row_bytes > 0);
std::vector<U8> line_buffer(row_bytes);
@@ -548,7 +548,7 @@ void LLImageRaw::composite( LLImageRaw* src )
// Src and dst can be any size. Src has 4 components. Dst has 3 components.
void LLImageRaw::compositeScaled4onto3(LLImageRaw* src)
{
- LLMemType mt1((LLMemType::EMemType)mMemType);
+ LLMemType mt1(mMemType);
llinfos << "compositeScaled4onto3" << llendl;
LLImageRaw* dst = this; // Just for clarity.
@@ -787,7 +787,7 @@ void LLImageRaw::copyUnscaled3onto4( LLImageRaw* src )
// Src and dst can be any size. Src and dst have same number of components.
void LLImageRaw::copyScaled( LLImageRaw* src )
{
- LLMemType mt1((LLMemType::EMemType)mMemType);
+ LLMemType mt1(mMemType);
LLImageRaw* dst = this; // Just for clarity.
llassert_always( (1 == src->getComponents()) || (3 == src->getComponents()) || (4 == src->getComponents()) );
@@ -819,7 +819,7 @@ void LLImageRaw::copyScaled( LLImageRaw* src )
BOOL LLImageRaw::scale( S32 new_width, S32 new_height, BOOL scale_image_data )
{
- LLMemType mt1((LLMemType::EMemType)mMemType);
+ LLMemType mt1(mMemType);
llassert((1 == getComponents()) || (3 == getComponents()) || (4 == getComponents()) );
S32 old_width = getWidth();
diff --git a/indra/llimage/llimage.h b/indra/llimage/llimage.h
index bd609b638c..8108553107 100644
--- a/indra/llimage/llimage.h
+++ b/indra/llimage/llimage.h
@@ -35,8 +35,9 @@
#include "lluuid.h"
#include "llstring.h"
-#include "llmemory.h"
+//#include "llmemory.h"
#include "llthread.h"
+#include "llmemtype.h"
const S32 MIN_IMAGE_MIP = 2; // 4x4, only used for expand/contract power of 2
const S32 MAX_IMAGE_MIP = 11; // 2048x2048
@@ -155,7 +156,7 @@ private:
BOOL mBadBufferAllocation ;
public:
- S16 mMemType; // debug
+ LLMemType::DeclareMemType& mMemType; // debug
static BOOL sSizeOverride;
};
diff --git a/indra/llimage/llimagedxt.h b/indra/llimage/llimagedxt.h
index bc2d6522d2..1a297536b4 100644
--- a/indra/llimage/llimagedxt.h
+++ b/indra/llimage/llimagedxt.h
@@ -33,6 +33,7 @@
#define LL_LLIMAGEDXT_H
#include "llimage.h"
+#include "llpointer.h"
// This class decodes and encodes LL DXT files (which may unclude uncompressed RGB or RGBA mipped data)
diff --git a/indra/llimage/llimagej2c.cpp b/indra/llimage/llimagej2c.cpp
index 900652d06d..2352c8edd7 100644
--- a/indra/llimage/llimagej2c.cpp
+++ b/indra/llimage/llimagej2c.cpp
@@ -285,7 +285,7 @@ BOOL LLImageJ2C::decode(LLImageRaw *raw_imagep, F32 decode_time)
BOOL LLImageJ2C::decodeChannels(LLImageRaw *raw_imagep, F32 decode_time, S32 first_channel, S32 max_channel_count )
{
- LLMemType mt1((LLMemType::EMemType)mMemType);
+ LLMemType mt1(mMemType);
BOOL res = TRUE;
@@ -335,7 +335,7 @@ BOOL LLImageJ2C::encode(const LLImageRaw *raw_imagep, F32 encode_time)
BOOL LLImageJ2C::encode(const LLImageRaw *raw_imagep, const char* comment_text, F32 encode_time)
{
- LLMemType mt1((LLMemType::EMemType)mMemType);
+ LLMemType mt1(mMemType);
resetLastError();
BOOL res = mImpl->encodeImpl(*this, *raw_imagep, comment_text, encode_time, mReversible);
if (!mLastError.empty())
@@ -504,7 +504,7 @@ BOOL LLImageJ2C::loadAndValidate(const std::string &filename)
BOOL LLImageJ2C::validate(U8 *data, U32 file_size)
{
- LLMemType mt1((LLMemType::EMemType)mMemType);
+ LLMemType mt1(mMemType);
resetLastError();
diff --git a/indra/llimage/llimagetga.cpp b/indra/llimage/llimagetga.cpp
index a6721bfa0f..d8f8003593 100644
--- a/indra/llimage/llimagetga.cpp
+++ b/indra/llimage/llimagetga.cpp
@@ -31,10 +31,12 @@
#include "linden_common.h"
-#include "lldir.h"
#include "llimagetga.h"
+
+#include "lldir.h"
#include "llerror.h"
#include "llmath.h"
+#include "llpointer.h"
// For expanding 5-bit pixel values to 8-bit with best rounding
// static
diff --git a/indra/llimage/llimageworker.h b/indra/llimage/llimageworker.h
index 879fcf5565..0d66695d6e 100644
--- a/indra/llimage/llimageworker.h
+++ b/indra/llimage/llimageworker.h
@@ -34,6 +34,7 @@
#define LL_LLIMAGEWORKER_H
#include "llimage.h"
+#include "llpointer.h"
#include "llworkerthread.h"
class LLImageWorker : public LLWorkerClass
diff --git a/indra/llimagej2coj/llimagej2coj.cpp b/indra/llimagej2coj/llimagej2coj.cpp
index be6b6c817b..ec6264dcf5 100644
--- a/indra/llimagej2coj/llimagej2coj.cpp
+++ b/indra/llimagej2coj/llimagej2coj.cpp
@@ -37,7 +37,7 @@
#include "openjpeg.h"
#include "lltimer.h"
-#include "llmemory.h"
+//#include "llmemory.h"
const char* fallbackEngineInfoLLImageJ2CImpl()
{
diff --git a/indra/llinventory/lleconomy.h b/indra/llinventory/lleconomy.h
index 2e2adc4d45..e480085453 100644
--- a/indra/llinventory/lleconomy.h
+++ b/indra/llinventory/lleconomy.h
@@ -32,7 +32,7 @@
#ifndef LL_LLECONOMY_H
#define LL_LLECONOMY_H
-#include "llmemory.h"
+#include "llsingleton.h"
class LLMessageSystem;
class LLVector3;
diff --git a/indra/llinventory/llinventory.cpp b/indra/llinventory/llinventory.cpp
index 76de357e2b..5d3fbe5128 100644
--- a/indra/llinventory/llinventory.cpp
+++ b/indra/llinventory/llinventory.cpp
@@ -133,6 +133,11 @@ LLAssetType::EType LLInventoryObject::getActualType() const
return mType;
}
+BOOL LLInventoryObject::getIsLinkType() const
+{
+ return LLAssetType::lookupIsLinkType(mType);
+}
+
// See LLInventoryItem override.
// virtual
const LLUUID& LLInventoryObject::getLinkedUUID() const
@@ -1170,109 +1175,8 @@ fail:
}
-LLXMLNode *LLInventoryItem::exportFileXML(BOOL include_asset_key) const
-{
- LLMemType m1(LLMemType::MTYPE_INVENTORY);
- LLXMLNode *ret = new LLXMLNode("item", FALSE);
-
- ret->createChild("uuid", TRUE)->setUUIDValue(1, &mUUID);
- ret->createChild("parent_uuid", TRUE)->setUUIDValue(1, &mParentUUID);
-
- mPermissions.exportFileXML()->setParent(ret);
-
- // Check for permissions to see the asset id, and if so write it
- // out as an asset id. Otherwise, apply our cheesy encryption.
- if(include_asset_key)
- {
- U32 mask = mPermissions.getMaskBase();
- if(((mask & PERM_ITEM_UNRESTRICTED) == PERM_ITEM_UNRESTRICTED)
- || (mAssetUUID.isNull()))
- {
- ret->createChild("asset_id", FALSE)->setUUIDValue(1, &mAssetUUID);
- }
- else
- {
- LLUUID shadow_id(mAssetUUID);
- LLXORCipher cipher(MAGIC_ID.mData, UUID_BYTES);
- cipher.encrypt(shadow_id.mData, UUID_BYTES);
-
- ret->createChild("shadow_id", FALSE)->setUUIDValue(1, &shadow_id);
- }
- }
-
- std::string type_str = LLAssetType::lookup(mType);
- std::string inv_type_str = LLInventoryType::lookup(mInventoryType);
-
- ret->createChild("asset_type", FALSE)->setStringValue(type_str);
- ret->createChild("inventory_type", FALSE)->setStringValue(inv_type_str);
- S32 tmp_flags = (S32) mFlags;
- ret->createChild("flags", FALSE)->setByteValue(4, (U8*)(&tmp_flags), LLXMLNode::ENCODING_HEX);
-
- mSaleInfo.exportFileXML()->setParent(ret);
-
- std::string temp;
- temp.assign(mName);
- ret->createChild("name", FALSE)->setStringValue(temp);
- temp.assign(mDescription);
- ret->createChild("description", FALSE)->setStringValue(temp);
- S32 date = mCreationDate;
- ret->createChild("creation_date", FALSE)->setIntValue(1, &date);
-
- return ret;
-}
-
-BOOL LLInventoryItem::importXML(LLXMLNode* node)
-{
- BOOL success = FALSE;
- if (node)
- {
- success = TRUE;
- LLXMLNodePtr sub_node;
- if (node->getChild("uuid", sub_node))
- success = (1 == sub_node->getUUIDValue(1, &mUUID));
- if (node->getChild("parent_uuid", sub_node))
- success = success && (1 == sub_node->getUUIDValue(1, &mParentUUID));
- if (node->getChild("permissions", sub_node))
- success = success && mPermissions.importXML(sub_node);
- if (node->getChild("asset_id", sub_node))
- success = success && (1 == sub_node->getUUIDValue(1, &mAssetUUID));
- if (node->getChild("shadow_id", sub_node))
- {
- success = success && (1 == sub_node->getUUIDValue(1, &mAssetUUID));
- LLXORCipher cipher(MAGIC_ID.mData, UUID_BYTES);
- cipher.decrypt(mAssetUUID.mData, UUID_BYTES);
- }
- if (node->getChild("asset_type", sub_node))
- mType = LLAssetType::lookup(sub_node->getValue());
- if (node->getChild("inventory_type", sub_node))
- mInventoryType = LLInventoryType::lookup(sub_node->getValue());
- if (node->getChild("flags", sub_node))
- {
- S32 tmp_flags = 0;
- success = success && (1 == sub_node->getIntValue(1, &tmp_flags));
- mFlags = (U32) tmp_flags;
- }
- if (node->getChild("sale_info", sub_node))
- success = success && mSaleInfo.importXML(sub_node);
- if (node->getChild("name", sub_node))
- mName = sub_node->getValue();
- if (node->getChild("description", sub_node))
- mDescription = sub_node->getValue();
- if (node->getChild("creation_date", sub_node))
- {
- S32 date = 0;
- success = success && (1 == sub_node->getIntValue(1, &date));
- mCreationDate = date;
- }
-
- if (!success)
- {
- lldebugs << "LLInventory::importXML() failed for node named '"
- << node->getName() << "'" << llendl;
- }
- }
- return success;
-}
+// Deleted LLInventoryItem::exportFileXML() and LLInventoryItem::importXML()
+// because I can't find any non-test code references to it. 2009-05-04 JC
S32 LLInventoryItem::packBinaryBucket(U8* bin_bucket, LLPermissions* perm_override) const
{
diff --git a/indra/llinventory/llinventory.h b/indra/llinventory/llinventory.h
index 08e3958533..b953e91309 100644
--- a/indra/llinventory/llinventory.h
+++ b/indra/llinventory/llinventory.h
@@ -40,6 +40,7 @@
#include "llinventorytype.h"
#include "llmemtype.h"
#include "llpermissions.h"
+#include "llrefcount.h"
#include "llsaleinfo.h"
#include "llsd.h"
#include "lluuid.h"
@@ -92,11 +93,14 @@ public:
virtual const LLUUID& getUUID() const;
const LLUUID& getParentUUID() const;
virtual const LLUUID& getLinkedUUID() const; // get the inventoryID that this item points to, else this item's inventoryID
-
virtual const std::string& getName() const;
virtual LLAssetType::EType getType() const;
LLAssetType::EType getActualType() const; // bypasses indirection for linked items
+ virtual const std::string& getName() const;
+ virtual LLAssetType::EType getType() const;
+ LLAssetType::EType getActualType() const; // bypasses indirection for linked items
+ BOOL getIsLinkType() const;
// mutators - will not call updateServer();
void setUUID(const LLUUID& new_uuid);
void rename(const std::string& new_name);
@@ -219,6 +223,7 @@ protected:
~LLInventoryItem(); // ref counted
public:
+
MEM_TYPE_NEW(LLMemType::MTYPE_INVENTORY);
LLInventoryItem(const LLUUID& uuid,
const LLUUID& parent_uuid,
@@ -265,6 +270,10 @@ public:
// Check for changes in permissions masks and sale info
// and set the corresponding bits in mFlags
void accumulatePermissionSlamBits(const LLInventoryItem& old_item);
+
+ // This is currently only used in the Viewer to handle calling cards
+ // where the creator is actually used to store the target.
+ void setCreator(const LLUUID& creator) { mPermissions.setCreator(creator); }
// Put this inventory item onto the current outgoing mesage. It
// assumes you have already called nextBlock().
@@ -281,9 +290,6 @@ public:
virtual BOOL importLegacyStream(std::istream& input_stream);
virtual BOOL exportLegacyStream(std::ostream& output_stream, BOOL include_asset_key = TRUE) const;
- virtual LLXMLNode *exportFileXML(BOOL include_asset_key = TRUE) const;
- BOOL importXML(LLXMLNode* node);
-
// helper functions
// pack all information needed to reconstruct this item into the given binary bucket.
diff --git a/indra/llinventory/llinventorytype.cpp b/indra/llinventory/llinventorytype.cpp
index 866d6722a0..a445466b26 100644
--- a/indra/llinventory/llinventorytype.cpp
+++ b/indra/llinventory/llinventorytype.cpp
@@ -35,6 +35,7 @@
#include "llinventorytype.h"
#include "lldictionary.h"
#include "llmemory.h"
+#include "llsingleton.h"
static const std::string empty_string;
diff --git a/indra/llinventory/llinventorytype.h b/indra/llinventory/llinventorytype.h
index 8961ff96e7..14b28bfe4b 100644
--- a/indra/llinventory/llinventorytype.h
+++ b/indra/llinventory/llinventorytype.h
@@ -92,11 +92,10 @@ private:
~LLInventoryType( void );
};
-// helper function which returns true if inventory type and asset type
+// helper function that returns true if inventory type and asset type
// are potentially compatible. For example, an attachment must be an
// object, but a wearable can be a bodypart or clothing asset.
-bool inventory_and_asset_types_match(
- LLInventoryType::EType inventory_type,
- LLAssetType::EType asset_type);
+bool inventory_and_asset_types_match(LLInventoryType::EType inventory_type,
+ LLAssetType::EType asset_type);
#endif
diff --git a/indra/llinventory/lllandmark.cpp b/indra/llinventory/lllandmark.cpp
index 13a63bc7d6..83b6392ca8 100644
--- a/indra/llinventory/lllandmark.cpp
+++ b/indra/llinventory/lllandmark.cpp
@@ -40,7 +40,7 @@
std::pair<LLUUID, U64> LLLandmark::mLocalRegion;
LLLandmark::region_map_t LLLandmark::mRegions;
-LLLandmark::region_callback_t LLLandmark::mRegionCallback;
+LLLandmark::region_callback_map_t LLLandmark::sRegionCallbackMap;
LLLandmark::LLLandmark() :
mGlobalPositionKnown(false)
@@ -177,7 +177,7 @@ void LLLandmark::requestRegionHandle(
LLMessageSystem* msg,
const LLHost& upstream_host,
const LLUUID& region_id,
- LLRegionHandleCallback* callback)
+ region_handle_callback_t callback)
{
if(region_id.isNull())
{
@@ -186,7 +186,7 @@ void LLLandmark::requestRegionHandle(
if(callback)
{
const U64 U64_ZERO = 0;
- callback->dataReady(region_id, U64_ZERO);
+ callback(region_id, U64_ZERO);
}
}
else
@@ -196,7 +196,7 @@ void LLLandmark::requestRegionHandle(
lldebugs << "requestRegionHandle: local" << llendl;
if(callback)
{
- callback->dataReady(region_id, mLocalRegion.second);
+ callback(region_id, mLocalRegion.second);
}
}
else
@@ -207,8 +207,8 @@ void LLLandmark::requestRegionHandle(
lldebugs << "requestRegionHandle: upstream" << llendl;
if(callback)
{
- region_callback_t::value_type vt(region_id, callback);
- mRegionCallback.insert(vt);
+ region_callback_map_t::value_type vt(region_id, callback);
+ sRegionCallbackMap.insert(vt);
}
lldebugs << "Landmark requesting information about: "
<< region_id << llendl;
@@ -221,7 +221,7 @@ void LLLandmark::requestRegionHandle(
{
// we have the answer locally - just call the callack.
lldebugs << "requestRegionHandle: ready" << llendl;
- callback->dataReady(region_id, (*it).second.mRegionHandle);
+ callback(region_id, (*it).second.mRegionHandle);
}
}
}
@@ -259,11 +259,11 @@ void LLLandmark::processRegionIDAndHandle(LLMessageSystem* msg, void**)
#endif
// make all the callbacks here.
- region_callback_t::iterator it;
- while((it = mRegionCallback.find(region_id)) != mRegionCallback.end())
+ region_callback_map_t::iterator it;
+ while((it = sRegionCallbackMap.find(region_id)) != sRegionCallbackMap.end())
{
- (*it).second->dataReady(region_id, info.mRegionHandle);
- mRegionCallback.erase(it);
+ (*it).second(region_id, info.mRegionHandle);
+ sRegionCallbackMap.erase(it);
}
}
diff --git a/indra/llinventory/lllandmark.h b/indra/llinventory/lllandmark.h
index cb0c11ab87..feaf1a0e9c 100644
--- a/indra/llinventory/lllandmark.h
+++ b/indra/llinventory/lllandmark.h
@@ -35,6 +35,7 @@
#define LL_LLLANDMARK_H
#include <map>
+#include <boost/function.hpp>
#include "llframetimer.h"
#include "lluuid.h"
#include "v3dmath.h"
@@ -42,24 +43,12 @@
class LLMessageSystem;
class LLHost;
-// virutal base class used for calling back interested parties when a
-// region handle comes back.
-class LLRegionHandleCallback
-{
-public:
- LLRegionHandleCallback() {}
- virtual ~LLRegionHandleCallback() {}
- virtual bool dataReady(
- const LLUUID& region_id,
- const U64& region_handle)
- {
- return true;
- }
-};
-
class LLLandmark
{
public:
+ // for calling back interested parties when a region handle comes back.
+ typedef boost::function<void(const LLUUID& region_id, const U64& region_handle)> region_handle_callback_t;
+
~LLLandmark() {}
// returns true if the position is known.
@@ -90,7 +79,7 @@ public:
LLMessageSystem* msg,
const LLHost& upstream_host,
const LLUUID& region_id,
- LLRegionHandleCallback* callback);
+ region_handle_callback_t callback);
// Call this method to create a lookup for this region. This
// simplifies a lot of the code.
@@ -118,8 +107,8 @@ private:
static std::pair<LLUUID, U64> mLocalRegion;
typedef std::map<LLUUID, CacheInfo> region_map_t;
static region_map_t mRegions;
- typedef std::multimap<LLUUID, LLRegionHandleCallback*> region_callback_t;
- static region_callback_t mRegionCallback;
+ typedef std::multimap<LLUUID, region_handle_callback_t> region_callback_map_t;
+ static region_callback_map_t sRegionCallbackMap;
};
#endif
diff --git a/indra/llinventory/llnotecard.h b/indra/llinventory/llnotecard.h
index b903f1fdb0..092ab2ce35 100644
--- a/indra/llinventory/llnotecard.h
+++ b/indra/llinventory/llnotecard.h
@@ -33,7 +33,7 @@
#ifndef LL_NOTECARD_H
#define LL_NOTECARD_H
-#include "llmemory.h"
+#include "llpointer.h"
#include "llinventory.h"
class LLNotecard
diff --git a/indra/llinventory/llparcel.cpp b/indra/llinventory/llparcel.cpp
index a0b27c788f..e48690908e 100644
--- a/indra/llinventory/llparcel.cpp
+++ b/indra/llinventory/llparcel.cpp
@@ -85,13 +85,13 @@ static const std::string PARCEL_CATEGORY_UI_STRING[LLParcel::C_COUNT + 1] =
"None",
"Linden Location",
"Adult",
- "Arts & Culture",
+ "Arts and Culture",
"Business",
"Educational",
"Gaming",
"Hangout",
"Newcomer Friendly",
- "Parks & Nature",
+ "Parks and Nature",
"Residential",
"Shopping",
"Stage",
@@ -199,6 +199,12 @@ void LLParcel::init(const LLUUID &owner_id,
mObscureMusic = 1;
mMediaWidth = 0;
mMediaHeight = 0;
+ setMediaCurrentURL(LLStringUtil::null);
+ mMediaURLFilterEnable = FALSE;
+ mMediaURLFilterList = LLSD::emptyArray();
+ mMediaAllowNavigate = TRUE;
+ mMediaURLTimeout = 0.0f;
+ mMediaPreventCameraZoom = FALSE;
mGroupID.setNull();
@@ -314,6 +320,56 @@ void LLParcel::setMediaHeight(S32 height)
{
mMediaHeight = height;
}
+
+void LLParcel::setMediaCurrentURL(const std::string& url)
+{
+ mMediaCurrentURL = url;
+ // The escaping here must match the escaping in the database
+ // abstraction layer if it's ever added.
+ // This should really filter the url in some way. Other than
+ // simply requiring non-printable.
+ LLStringFn::replace_nonprintable_in_ascii(mMediaCurrentURL, LL_UNKNOWN_CHAR);
+
+}
+
+void LLParcel::setMediaURLResetTimer(F32 time)
+{
+ mMediaResetTimer.start();
+ mMediaResetTimer.setTimerExpirySec(time);
+}
+
+void LLParcel::setMediaURLFilterList(LLSD list)
+{
+ // sanity check LLSD
+ // must be array of strings
+ if (!list.isArray())
+ {
+ return;
+ }
+
+ for (S32 i = 0; i < list.size(); i++)
+ {
+ if (!list[i].isString())
+ return;
+ }
+
+ // can't be too big
+ const S32 MAX_SIZE = 50;
+ if (list.size() > MAX_SIZE)
+ {
+ LLSD new_list = LLSD::emptyArray();
+
+ for (S32 i = 0; i < llmin(list.size(), MAX_SIZE); i++)
+ {
+ new_list.append(list[i]);
+ }
+
+ list = new_list;
+ }
+
+ mMediaURLFilterList = list;
+}
+
// virtual
void LLParcel::setLocalID(S32 local_id)
{
@@ -568,6 +624,34 @@ BOOL LLParcel::importAccessEntry(std::istream& input_stream, LLAccessEntry* entr
return input_stream.good();
}
+BOOL LLParcel::importMediaURLFilter(std::istream& input_stream, std::string& url)
+{
+ skip_to_end_of_next_keyword("{", input_stream);
+
+ while(input_stream.good())
+ {
+ skip_comments_and_emptyspace(input_stream);
+ std::string line, keyword, value;
+ get_line(line, input_stream, MAX_STRING);
+ get_keyword_and_value(keyword, value, line);
+
+ if ("}" == keyword)
+ {
+ break;
+ }
+ else if ("url" == keyword)
+ {
+ url = value;
+ }
+ else
+ {
+ llwarns << "Unknown keyword in parcel media url filter section: <"
+ << keyword << ">" << llendl;
+ }
+ }
+ return input_stream.good();
+}
+
// Assumes we are in a block "ParcelData"
void LLParcel::packMessage(LLMessageSystem* msg)
{
@@ -593,6 +677,7 @@ void LLParcel::packMessage(LLMessageSystem* msg)
// Assumes we are in a block "ParcelData"
void LLParcel::packMessage(LLSD& msg)
{
+ // used in the viewer, the sim uses it's own packer
msg["local_id"] = getLocalID();
msg["parcel_flags"] = ll_sd_from_U32(getParcelFlags());
msg["sale_price"] = getSalePrice();
@@ -606,9 +691,15 @@ void LLParcel::packMessage(LLSD& msg)
msg["media_height"] = getMediaHeight();
msg["auto_scale"] = getMediaAutoScale();
msg["media_loop"] = getMediaLoop();
+ msg["media_current_url"] = getMediaCurrentURL();
msg["obscure_media"] = getObscureMedia();
msg["obscure_music"] = getObscureMusic();
msg["media_id"] = getMediaID();
+ msg["media_allow_navigate"] = getMediaAllowNavigate();
+ msg["media_prevent_camera_zoom"] = getMediaPreventCameraZoom();
+ msg["media_url_timeout"] = getMediaURLTimeout();
+ msg["media_url_filter_enable"] = getMediaURLFilterEnable();
+ msg["media_url_filter_list"] = getMediaURLFilterList();
msg["group_id"] = getGroupID();
msg["pass_price"] = mPassPrice;
msg["pass_hours"] = mPassHours;
@@ -678,6 +769,21 @@ void LLParcel::unpackMessage(LLMessageSystem* msg)
mObscureMedia = true;
mObscureMusic = true;
}
+
+ if(msg->getNumberOfBlocks("MediaLinkSharing") > 0)
+ {
+ msg->getString("MediaLinkSharing", "MediaCurrentURL", buffer);
+ setMediaCurrentURL(buffer);
+ msg->getU8 ( "MediaLinkSharing", "MediaAllowNavigate", mMediaAllowNavigate );
+ msg->getU8 ( "MediaLinkSharing", "MediaURLFilterEnable", mMediaURLFilterEnable );
+ msg->getU8 ( "MediaLinkSharing", "MediaPreventCameraZoom", mMediaPreventCameraZoom );
+ msg->getF32( "MediaLinkSharing", "MediaURLTimeout", mMediaURLTimeout);
+ }
+ else
+ {
+ setMediaCurrentURL(LLStringUtil::null);
+ }
+
}
void LLParcel::packAccessEntries(LLMessageSystem* msg,
@@ -994,6 +1100,20 @@ BOOL LLParcel::isSaleTimerExpired(const U64& time)
return expired;
}
+BOOL LLParcel::isMediaResetTimerExpired(const U64& time)
+{
+ if (mMediaResetTimer.getStarted() == FALSE)
+ {
+ return FALSE;
+ }
+ BOOL expired = mMediaResetTimer.checkExpirationAndReset(0.0);
+ if (expired)
+ {
+ mMediaResetTimer.stop();
+ }
+ return expired;
+}
+
void LLParcel::startSale(const LLUUID& buyer_id, BOOL is_buyer_group)
{
@@ -1117,6 +1237,12 @@ void LLParcel::clearParcel()
mObscureMusic = 1;
mMediaWidth = 0;
mMediaHeight = 0;
+ setMediaCurrentURL(LLStringUtil::null);
+ setMediaURLFilterList(LLSD::emptyArray());
+ setMediaURLFilterEnable(FALSE);
+ setMediaAllowNavigate(TRUE);
+ setMediaPreventCameraZoom(FALSE);
+ setMediaURLTimeout(0.0f);
setMusicURL(LLStringUtil::null);
setInEscrow(FALSE);
setAuthorizedBuyerID(LLUUID::null);
diff --git a/indra/llinventory/llparcel.h b/indra/llinventory/llparcel.h
index 5a865d27ba..2a9a596912 100644
--- a/indra/llinventory/llparcel.h
+++ b/indra/llinventory/llparcel.h
@@ -38,6 +38,7 @@
#include "lluuid.h"
#include "llparcelflags.h"
#include "llpermissions.h"
+#include "lltimer.h"
#include "v3math.h"
@@ -247,6 +248,14 @@ public:
void setObscureMusic( U8 flagIn ) { mObscureMusic = flagIn; }
void setMediaWidth(S32 width);
void setMediaHeight(S32 height);
+ void setMediaCurrentURL(const std::string& url);
+ void setMediaURLFilterEnable(U8 enable) { mMediaURLFilterEnable = enable; }
+ void setMediaURLFilterList(LLSD list);
+ void setMediaAllowNavigate(U8 enable) { mMediaAllowNavigate = enable; }
+ void setMediaURLTimeout(F32 timeout) { mMediaURLTimeout = timeout; }
+ void setMediaPreventCameraZoom(U8 enable) { mMediaPreventCameraZoom = enable; }
+
+ void setMediaURLResetTimer(F32 time);
virtual void setLocalID(S32 local_id);
// blow away all the extra crap lurking in parcels, including urls, access lists, etc
@@ -299,7 +308,8 @@ public:
// BOOL importStream(std::istream& input_stream);
BOOL importAccessEntry(std::istream& input_stream, LLAccessEntry* entry);
-// BOOL exportStream(std::ostream& output_stream);
+ BOOL importMediaURLFilter(std::istream& input_stream, std::string& url);
+ // BOOL exportStream(std::ostream& output_stream);
void packMessage(LLMessageSystem* msg);
void packMessage(LLSD& msg);
@@ -341,8 +351,15 @@ public:
S32 getMediaHeight() const { return mMediaHeight; }
U8 getMediaAutoScale() const { return mMediaAutoScale; }
U8 getMediaLoop() const { return mMediaLoop; }
+ const std::string& getMediaCurrentURL() const { return mMediaCurrentURL; }
U8 getObscureMedia() const { return mObscureMedia; }
U8 getObscureMusic() const { return mObscureMusic; }
+ U8 getMediaURLFilterEnable() const { return mMediaURLFilterEnable; }
+ LLSD getMediaURLFilterList() const { return mMediaURLFilterList; }
+ U8 getMediaAllowNavigate() const { return mMediaAllowNavigate; }
+ F32 getMediaURLTimeout() const { return mMediaURLTimeout; }
+ U8 getMediaPreventCameraZoom() const { return mMediaPreventCameraZoom; }
+
S32 getLocalID() const { return mLocalID; }
const LLUUID& getOwnerID() const { return mOwnerID; }
const LLUUID& getGroupID() const { return mGroupID; }
@@ -413,6 +430,10 @@ public:
void completeSale(U32& type, U8& flags, LLUUID& to_id);
void clearSale();
+
+ BOOL isMediaResetTimerExpired(const U64& time);
+
+
// more accessors
U32 getParcelFlags() const { return mParcelFlags; }
@@ -591,6 +612,8 @@ protected:
LLVector3 mUserLookAt;
ELandingType mLandingType;
LLTimer mSaleTimerExpires;
+ LLTimer mMediaResetTimer;
+
S32 mGraceExtension;
// This value is non-zero if there is an auction associated with
@@ -618,9 +641,15 @@ protected:
S32 mMediaHeight;
U8 mMediaAutoScale;
U8 mMediaLoop;
+ std::string mMediaCurrentURL;
U8 mObscureMedia;
U8 mObscureMusic;
LLUUID mMediaID;
+ U8 mMediaURLFilterEnable;
+ LLSD mMediaURLFilterList;
+ U8 mMediaAllowNavigate;
+ U8 mMediaPreventCameraZoom;
+ F32 mMediaURLTimeout;
S32 mPassPrice;
F32 mPassHours;
LLVector3 mAABBMin;
@@ -650,6 +679,7 @@ public:
std::map<LLUUID,LLAccessEntry> mBanList;
std::map<LLUUID,LLAccessEntry> mTempBanList;
std::map<LLUUID,LLAccessEntry> mTempAccessList;
+
};
diff --git a/indra/llinventory/llpermissions.cpp b/indra/llinventory/llpermissions.cpp
index 036231ccf8..d2e5034734 100644
--- a/indra/llinventory/llpermissions.cpp
+++ b/indra/llinventory/llpermissions.cpp
@@ -853,67 +853,8 @@ BOOL LLPermissions::exportLegacyStream(std::ostream& output_stream) const
return TRUE;
}
-
-LLXMLNode *LLPermissions::exportFileXML() const
-{
- LLXMLNode *ret = new LLXMLNode("permissions", FALSE);
-
- ret->createChild("group_owned", TRUE)->setBoolValue(mIsGroupOwned);
-
- ret->createChild("base_mask", FALSE)->setByteValue(4, (U8*)&mMaskBase, LLXMLNode::ENCODING_HEX);
- ret->createChild("owner_mask", FALSE)->setByteValue(4, (U8*)&mMaskOwner, LLXMLNode::ENCODING_HEX);
- ret->createChild("group_mask", FALSE)->setByteValue(4, (U8*)&mMaskGroup, LLXMLNode::ENCODING_HEX);
- ret->createChild("everyone_mask", FALSE)->setByteValue(4, (U8*)&mMaskEveryone, LLXMLNode::ENCODING_HEX);
- ret->createChild("next_owner_mask", FALSE)->setByteValue(4, (U8*)&mMaskNextOwner, LLXMLNode::ENCODING_HEX);
-
- ret->createChild("creator_id", FALSE)->setUUIDValue(1, &mCreator);
- ret->createChild("owner_id", FALSE)->setUUIDValue(1, &mOwner);
- ret->createChild("last_owner_id", FALSE)->setUUIDValue(1, &mLastOwner);
- ret->createChild("group_id", FALSE)->setUUIDValue(1, &mGroup);
-
- return ret;
-}
-
-bool LLPermissions::importXML(LLXMLNode* node)
-{
- bool success = false;
- if (node)
- {
- success = true;
- LLXMLNodePtr sub_node;
- if (node->getChild("base_mask", sub_node))
- success = success && (4 == sub_node->getByteValue(4, (U8*)&mMaskBase));
- if (node->getChild("owner_mask", sub_node))
- success = success && (4 == sub_node->getByteValue(4, (U8*)&mMaskOwner));
- if (node->getChild("group_mask", sub_node))
- success = success && (4 == sub_node->getByteValue(4, (U8*)&mMaskGroup));
- if (node->getChild("everyone_mask", sub_node))
- success = success && (4 == sub_node->getByteValue(4, (U8*)&mMaskEveryone));
- if (node->getChild("next_owner_mask", sub_node))
- success = success && (4 == sub_node->getByteValue(4, (U8*)&mMaskNextOwner));
-
- if (node->getChild("creator_id", sub_node))
- success = success && (1 == sub_node->getUUIDValue(1, &mCreator));
- if (node->getChild("owner_id", sub_node))
- success = success && (1 == sub_node->getUUIDValue(1, &mOwner));
- if (node->getChild("last_owner_id", sub_node))
- success = success && (1 == sub_node->getUUIDValue(1, &mLastOwner));
- if (node->getChild("group_id", sub_node))
- success = success && (1 == sub_node->getUUIDValue(1, &mGroup));
- if (node->getChild("group_owned", sub_node))
- {
- BOOL tmpbool = FALSE;
- success = success && (1 == sub_node->getBoolValue(1, &tmpbool));
- mIsGroupOwned = (bool)tmpbool;
- }
- if (!success)
- {
- lldebugs << "LLPermissions::importXML() failed for node named '"
- << node->getName() << "'" << llendl;
- }
- }
- return success;
-}
+// Deleted LLPermissions::exportFileXML() and LLPermissions::importXML()
+// because I can't find any non-test code references to it. 2009-05-04 JC
bool LLPermissions::operator==(const LLPermissions &rhs) const
{
diff --git a/indra/llinventory/llpermissions.h b/indra/llinventory/llpermissions.h
index f03045e265..d5a0881c8f 100644
--- a/indra/llinventory/llpermissions.h
+++ b/indra/llinventory/llpermissions.h
@@ -256,7 +256,11 @@ public:
BOOL setGroupBits( const LLUUID& agent, const LLUUID& group, BOOL set, PermissionMask bits);
BOOL setEveryoneBits(const LLUUID& agent, const LLUUID& group, BOOL set, PermissionMask bits);
BOOL setNextOwnerBits(const LLUUID& agent, const LLUUID& group, BOOL set, PermissionMask bits);
-
+
+ // This is currently only used in the Viewer to handle calling cards
+ // where the creator is actually used to store the target. Use with care.
+ void setCreator(const LLUUID& creator) { mCreator = creator; }
+
//
// METHODS
//
@@ -321,9 +325,6 @@ public:
BOOL importLegacyStream(std::istream& input_stream);
BOOL exportLegacyStream(std::ostream& output_stream) const;
- LLXMLNode *exportFileXML() const;
- bool importXML(LLXMLNode* node);
-
bool operator==(const LLPermissions &rhs) const;
bool operator!=(const LLPermissions &rhs) const;
diff --git a/indra/llinventory/llpermissionsflags.h b/indra/llinventory/llpermissionsflags.h
index afa2adbd90..f810929d68 100644
--- a/indra/llinventory/llpermissionsflags.h
+++ b/indra/llinventory/llpermissionsflags.h
@@ -32,9 +32,6 @@
#ifndef LL_LLPERMISSIONSFLAGS_H
#define LL_LLPERMISSIONSFLAGS_H
-// llpermissionsflags.h
-// Copyright 2002, Linden Research, Inc.
-//
// Flags for various permissions bits.
// Shared between viewer and simulator.
diff --git a/indra/llinventory/llsaleinfo.cpp b/indra/llinventory/llsaleinfo.cpp
index b7afb28adf..930901f309 100644
--- a/indra/llinventory/llsaleinfo.cpp
+++ b/indra/llinventory/llsaleinfo.cpp
@@ -135,38 +135,8 @@ bool LLSaleInfo::fromLLSD(const LLSD& sd, BOOL& has_perm_mask, U32& perm_mask)
return true;
}
-LLXMLNode *LLSaleInfo::exportFileXML() const
-{
- LLXMLNode *ret = new LLXMLNode("sale_info", FALSE);
- std::string type_str = ll_safe_string( lookup(mSaleType));
- ret->createChild("type", TRUE)->setStringValue(1, &type_str);
- ret->createChild("price", TRUE)->setIntValue(1, &mSalePrice);
- return ret;
-}
-
-BOOL LLSaleInfo::importXML(LLXMLNode* node)
-{
- BOOL success = FALSE;
- if (node)
- {
- success = TRUE;
- LLXMLNodePtr sub_node;
- if (node->getChild("type", sub_node))
- {
- mSaleType = lookup(sub_node->getValue().c_str());
- }
- if (node->getChild("price", sub_node))
- {
- success &= (1 == sub_node->getIntValue(1, &mSalePrice));
- }
- if (!success)
- {
- lldebugs << "LLSaleInfo::importXML() failed for node named '"
- << node->getName() << "'" << llendl;
- }
- }
- return success;
-}
+// Deleted LLSaleInfo::exportFileXML() and LLSaleInfo::importXML()
+// because I can't find any non-test code references to it. 2009-05-04 JC
BOOL LLSaleInfo::importFile(LLFILE* fp, BOOL& has_perm_mask, U32& perm_mask)
{
diff --git a/indra/llinventory/llsaleinfo.h b/indra/llinventory/llsaleinfo.h
index d546c49fd7..3461a128be 100644
--- a/indra/llinventory/llsaleinfo.h
+++ b/indra/llinventory/llsaleinfo.h
@@ -101,9 +101,6 @@ public:
bool fromLLSD(const LLSD& sd, BOOL& has_perm_mask, U32& perm_mask);
BOOL importLegacyStream(std::istream& input_stream, BOOL& has_perm_mask, U32& perm_mask);
- LLXMLNode *exportFileXML() const;
- BOOL importXML(LLXMLNode* node);
-
LLSD packMessage() const;
void unpackMessage(LLSD sales);
diff --git a/indra/llmath/CMakeLists.txt b/indra/llmath/CMakeLists.txt
index 075d3b3af0..d287a5063a 100644
--- a/indra/llmath/CMakeLists.txt
+++ b/indra/llmath/CMakeLists.txt
@@ -10,6 +10,7 @@ include_directories(
)
set(llmath_SOURCE_FILES
+ llbbox.cpp
llbboxlocal.cpp
llcamera.cpp
llcoordframe.cpp
@@ -39,6 +40,7 @@ set(llmath_HEADER_FILES
camera.h
coordframe.h
+ llbbox.h
llbboxlocal.h
llcamera.h
llcoord.h
diff --git a/indra/llmath/llbbox.cpp b/indra/llmath/llbbox.cpp
new file mode 100644
index 0000000000..acf93a2a38
--- /dev/null
+++ b/indra/llmath/llbbox.cpp
@@ -0,0 +1,160 @@
+/**
+ * @file llbbox.cpp
+ * @brief General purpose bounding box class (Not axis aligned)
+ *
+ * $LicenseInfo:firstyear=2001&license=viewergpl$
+ *
+ * Copyright (c) 2001-2009, Linden Research, Inc.
+ *
+ * Second Life Viewer Source Code
+ * The source code in this file ("Source Code") is provided by Linden Lab
+ * to you under the terms of the GNU General Public License, version 2.0
+ * ("GPL"), unless you have obtained a separate licensing agreement
+ * ("Other License"), formally executed by you and Linden Lab. Terms of
+ * the GPL can be found in doc/GPL-license.txt in this distribution, or
+ * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
+ *
+ * There are special exceptions to the terms and conditions of the GPL as
+ * it is applied to this Source Code. View the full text of the exception
+ * in the file doc/FLOSS-exception.txt in this software distribution, or
+ * online at
+ * http://secondlifegrid.net/programs/open_source/licensing/flossexception
+ *
+ * By copying, modifying or distributing this software, you acknowledge
+ * that you have read and understood your obligations described above,
+ * and agree to abide by those obligations.
+ *
+ * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+ * COMPLETENESS OR PERFORMANCE.
+ * $/LicenseInfo$
+ */
+
+// self include
+#include "llbbox.h"
+
+// library includes
+#include "m4math.h"
+
+void LLBBox::addPointLocal(const LLVector3& p)
+{
+ if (mEmpty)
+ {
+ mMinLocal = p;
+ mMaxLocal = p;
+ mEmpty = FALSE;
+ }
+ else
+ {
+ mMinLocal.mV[VX] = llmin( p.mV[VX], mMinLocal.mV[VX] );
+ mMinLocal.mV[VY] = llmin( p.mV[VY], mMinLocal.mV[VY] );
+ mMinLocal.mV[VZ] = llmin( p.mV[VZ], mMinLocal.mV[VZ] );
+ mMaxLocal.mV[VX] = llmax( p.mV[VX], mMaxLocal.mV[VX] );
+ mMaxLocal.mV[VY] = llmax( p.mV[VY], mMaxLocal.mV[VY] );
+ mMaxLocal.mV[VZ] = llmax( p.mV[VZ], mMaxLocal.mV[VZ] );
+ }
+}
+
+void LLBBox::addPointAgent( LLVector3 p)
+{
+ p -= mPosAgent;
+ p.rotVec( ~mRotation );
+ addPointLocal( p );
+}
+
+
+void LLBBox::addBBoxAgent(const LLBBox& b)
+{
+ if (mEmpty)
+ {
+ mPosAgent = b.mPosAgent;
+ mRotation = b.mRotation;
+ mMinLocal.clearVec();
+ mMaxLocal.clearVec();
+ }
+ LLVector3 vertex[8];
+ vertex[0].setVec( b.mMinLocal.mV[VX], b.mMinLocal.mV[VY], b.mMinLocal.mV[VZ] );
+ vertex[1].setVec( b.mMinLocal.mV[VX], b.mMinLocal.mV[VY], b.mMaxLocal.mV[VZ] );
+ vertex[2].setVec( b.mMinLocal.mV[VX], b.mMaxLocal.mV[VY], b.mMinLocal.mV[VZ] );
+ vertex[3].setVec( b.mMinLocal.mV[VX], b.mMaxLocal.mV[VY], b.mMaxLocal.mV[VZ] );
+ vertex[4].setVec( b.mMaxLocal.mV[VX], b.mMinLocal.mV[VY], b.mMinLocal.mV[VZ] );
+ vertex[5].setVec( b.mMaxLocal.mV[VX], b.mMinLocal.mV[VY], b.mMaxLocal.mV[VZ] );
+ vertex[6].setVec( b.mMaxLocal.mV[VX], b.mMaxLocal.mV[VY], b.mMinLocal.mV[VZ] );
+ vertex[7].setVec( b.mMaxLocal.mV[VX], b.mMaxLocal.mV[VY], b.mMaxLocal.mV[VZ] );
+
+ LLMatrix4 m( b.mRotation );
+ m.translate( b.mPosAgent );
+ m.translate( -mPosAgent );
+ m.rotate( ~mRotation );
+
+ for( S32 i=0; i<8; i++ )
+ {
+ addPointLocal( vertex[i] * m );
+ }
+}
+
+
+void LLBBox::expand( F32 delta )
+{
+ mMinLocal.mV[VX] -= delta;
+ mMinLocal.mV[VY] -= delta;
+ mMinLocal.mV[VZ] -= delta;
+ mMaxLocal.mV[VX] += delta;
+ mMaxLocal.mV[VY] += delta;
+ mMaxLocal.mV[VZ] += delta;
+}
+
+LLVector3 LLBBox::localToAgent(const LLVector3& v) const
+{
+ LLMatrix4 m( mRotation );
+ m.translate( mPosAgent );
+ return v * m;
+}
+
+LLVector3 LLBBox::agentToLocal(const LLVector3& v) const
+{
+ LLMatrix4 m;
+ m.translate( -mPosAgent );
+ m.rotate( ~mRotation ); // inverse rotation
+ return v * m;
+}
+
+LLVector3 LLBBox::localToAgentBasis(const LLVector3& v) const
+{
+ LLMatrix4 m( mRotation );
+ return v * m;
+}
+
+LLVector3 LLBBox::agentToLocalBasis(const LLVector3& v) const
+{
+ LLMatrix4 m( ~mRotation ); // inverse rotation
+ return v * m;
+}
+
+BOOL LLBBox::containsPointLocal(const LLVector3& p) const
+{
+ if ( (p.mV[VX] < mMinLocal.mV[VX])
+ ||(p.mV[VX] > mMaxLocal.mV[VX])
+ ||(p.mV[VY] < mMinLocal.mV[VY])
+ ||(p.mV[VY] > mMaxLocal.mV[VY])
+ ||(p.mV[VZ] < mMinLocal.mV[VZ])
+ ||(p.mV[VZ] > mMaxLocal.mV[VZ]))
+ {
+ return FALSE;
+ }
+ return TRUE;
+}
+
+BOOL LLBBox::containsPointAgent(const LLVector3& p) const
+{
+ LLVector3 point_local = agentToLocal(p);
+ return containsPointLocal(point_local);
+}
+
+
+/*
+LLBBox operator*(const LLBBox &a, const LLMatrix4 &b)
+{
+ return LLBBox( a.mMin * b, a.mMax * b );
+}
+*/
diff --git a/indra/llmath/llbbox.h b/indra/llmath/llbbox.h
new file mode 100644
index 0000000000..cd29551b01
--- /dev/null
+++ b/indra/llmath/llbbox.h
@@ -0,0 +1,103 @@
+/**
+ * @file llbbox.h
+ * @brief General purpose bounding box class
+ *
+ * $LicenseInfo:firstyear=2001&license=viewergpl$
+ *
+ * Copyright (c) 2001-2009, Linden Research, Inc.
+ *
+ * Second Life Viewer Source Code
+ * The source code in this file ("Source Code") is provided by Linden Lab
+ * to you under the terms of the GNU General Public License, version 2.0
+ * ("GPL"), unless you have obtained a separate licensing agreement
+ * ("Other License"), formally executed by you and Linden Lab. Terms of
+ * the GPL can be found in doc/GPL-license.txt in this distribution, or
+ * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
+ *
+ * There are special exceptions to the terms and conditions of the GPL as
+ * it is applied to this Source Code. View the full text of the exception
+ * in the file doc/FLOSS-exception.txt in this software distribution, or
+ * online at
+ * http://secondlifegrid.net/programs/open_source/licensing/flossexception
+ *
+ * By copying, modifying or distributing this software, you acknowledge
+ * that you have read and understood your obligations described above,
+ * and agree to abide by those obligations.
+ *
+ * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+ * COMPLETENESS OR PERFORMANCE.
+ * $/LicenseInfo$
+ */
+
+#ifndef LL_BBOX_H
+#define LL_BBOX_H
+
+#include "v3math.h"
+#include "llquaternion.h"
+
+// Note: "local space" for an LLBBox is defined relative to agent space in terms of
+// a translation followed by a rotation. There is no scale term since the LLBBox's min and
+// max are not necessarily symetrical and define their own extents.
+
+class LLBBox
+{
+public:
+ LLBBox() {mEmpty = TRUE;}
+ LLBBox( const LLVector3& pos_agent,
+ const LLQuaternion& rot,
+ const LLVector3& min_local,
+ const LLVector3& max_local )
+ :
+ mMinLocal( min_local ), mMaxLocal( max_local ), mPosAgent(pos_agent), mRotation( rot), mEmpty( TRUE )
+ {}
+
+ // Default copy constructor is OK.
+
+ const LLVector3& getPositionAgent() const { return mPosAgent; }
+ const LLQuaternion& getRotation() const { return mRotation; }
+
+ const LLVector3& getMinLocal() const { return mMinLocal; }
+ void setMinLocal( const LLVector3& min ) { mMinLocal = min; }
+
+ const LLVector3& getMaxLocal() const { return mMaxLocal; }
+ void setMaxLocal( const LLVector3& max ) { mMaxLocal = max; }
+
+ LLVector3 getCenterLocal() const { return (mMaxLocal - mMinLocal) * 0.5f + mMinLocal; }
+ LLVector3 getCenterAgent() const { return localToAgent( getCenterLocal() ); }
+
+ LLVector3 getExtentLocal() const { return mMaxLocal - mMinLocal; }
+
+ BOOL containsPointLocal(const LLVector3& p) const;
+ BOOL containsPointAgent(const LLVector3& p) const;
+
+ void addPointAgent(LLVector3 p);
+ void addBBoxAgent(const LLBBox& b);
+
+ void addPointLocal(const LLVector3& p);
+ void addBBoxLocal(const LLBBox& b) { addPointLocal( b.mMinLocal ); addPointLocal( b.mMaxLocal ); }
+
+ void expand( F32 delta );
+
+ LLVector3 localToAgent( const LLVector3& v ) const;
+ LLVector3 agentToLocal( const LLVector3& v ) const;
+
+ // Changes rotation but not position
+ LLVector3 localToAgentBasis(const LLVector3& v) const;
+ LLVector3 agentToLocalBasis(const LLVector3& v) const;
+
+
+// friend LLBBox operator*(const LLBBox& a, const LLMatrix4& b);
+
+private:
+ LLVector3 mMinLocal;
+ LLVector3 mMaxLocal;
+ LLVector3 mPosAgent; // Position relative to Agent's Region
+ LLQuaternion mRotation;
+ BOOL mEmpty; // Nothing has been added to this bbox yet
+};
+
+//LLBBox operator*(const LLBBox &a, const LLMatrix4 &b);
+
+
+#endif // LL_BBOX_H
diff --git a/indra/llmath/llbboxlocal.h b/indra/llmath/llbboxlocal.h
index d69028e3aa..0d1e5a3ae5 100644
--- a/indra/llmath/llbboxlocal.h
+++ b/indra/llmath/llbboxlocal.h
@@ -53,9 +53,6 @@ public:
LLVector3 getCenter() const { return (mMax - mMin) * 0.5f + mMin; }
LLVector3 getExtent() const { return mMax - mMin; }
- BOOL containsPoint(const LLVector3& p) const;
- BOOL intersects(const LLBBoxLocal& b) const;
-
void addPoint(const LLVector3& p);
void addBBox(const LLBBoxLocal& b) { addPoint( b.mMin ); addPoint( b.mMax ); }
diff --git a/indra/llmath/llmath.h b/indra/llmath/llmath.h
index 66451b1a27..f85c4f39f4 100644
--- a/indra/llmath/llmath.h
+++ b/indra/llmath/llmath.h
@@ -36,8 +36,8 @@
#include <cmath>
#include <cstdlib>
#include "lldefs.h"
-#include "llstl.h" // *TODO: Remove when LLString is gone
-#include "llstring.h" // *TODO: Remove when LLString is gone
+//#include "llstl.h" // *TODO: Remove when LLString is gone
+//#include "llstring.h" // *TODO: Remove when LLString is gone
// lltut.h uses is_approx_equal_fraction(). This was moved to its own header
// file in llcommon so we can use lltut.h for llcommon tests without making
// llcommon depend on llmath.
diff --git a/indra/llmath/lloctree.h b/indra/llmath/lloctree.h
index bced84cb1c..ba8776690a 100644
--- a/indra/llmath/lloctree.h
+++ b/indra/llmath/lloctree.h
@@ -65,11 +65,10 @@ public:
};
template <class T>
-class LLOctreeTraveler : public LLTreeTraveler<T>
+class LLOctreeTraveler
{
public:
- virtual void traverse(const LLTreeNode<T>* node);
- virtual void visit(const LLTreeNode<T>* state) { }
+ virtual void traverse(const LLOctreeNode<T>* node);
virtual void visit(const LLOctreeNode<T>* branch) = 0;
};
@@ -700,19 +699,16 @@ public:
}
};
-
//========================
// LLOctreeTraveler
//========================
template <class T>
-void LLOctreeTraveler<T>::traverse(const LLTreeNode<T>* tree_node)
+void LLOctreeTraveler<T>::traverse(const LLOctreeNode<T>* node)
{
- const LLOctreeNode<T>* node = (const LLOctreeNode<T>*) tree_node;
node->accept(this);
for (U32 i = 0; i < node->getChildCount(); i++)
{
traverse(node->getChild(i));
}
}
-
#endif
diff --git a/indra/llmath/llrect.h b/indra/llmath/llrect.h
index 9eb58dbbe9..c03a331aff 100644
--- a/indra/llmath/llrect.h
+++ b/indra/llmath/llrect.h
@@ -64,23 +64,17 @@ public:
mLeft(left), mTop(top), mRight(right), mBottom(bottom)
{}
- LLRectBase(const LLSD& sd)
+ explicit LLRectBase(const LLSD& sd)
{
setValue(sd);
}
- const LLRectBase& operator=(const LLSD& sd)
- {
- setValue(sd);
- return *this;
- }
-
void setValue(const LLSD& sd)
{
- mLeft = sd[0].asInteger();
- mTop = sd[1].asInteger();
- mRight = sd[2].asInteger();
- mBottom = sd[3].asInteger();
+ mLeft = (Type)sd[0].asInteger();
+ mTop = (Type)sd[1].asInteger();
+ mRight = (Type)sd[2].asInteger();
+ mBottom = (Type)sd[3].asInteger();
}
LLSD getValue() const
@@ -147,10 +141,20 @@ public:
// Note: Does NOT follow GL_QUAD conventions: the top and right edges ARE considered part of the rect
// returns TRUE if any part of rect is is inside this LLRect
- BOOL rectInRect(const LLRectBase* rect) const
+ BOOL overlaps(const LLRectBase& rect) const
+ {
+ return !(mLeft > rect.mRight
+ || mRight < rect.mLeft
+ || mBottom > rect.mTop
+ || mTop < rect.mBottom);
+ }
+
+ BOOL contains(const LLRectBase& rect) const
{
- return mLeft <= rect->mRight && rect->mLeft <= mRight &&
- mBottom <= rect->mTop && rect->mBottom <= mTop ;
+ return mLeft <= rect.mLeft
+ && mRight >= rect.mRight
+ && mBottom <= rect.mBottom
+ && mTop >= rect.mTop;
}
LLRectBase& set(Type left, Type top, Type right, Type bottom)
@@ -229,26 +233,25 @@ public:
return mLeft <= mRight && mBottom <= mTop;
}
- bool isNull() const
+ bool isEmpty() const
{
return mLeft == mRight || mBottom == mTop;
}
- bool notNull() const
+ bool notEmpty() const
{
- return !isNull();
+ return !isEmpty();
}
- LLRectBase& unionWith(const LLRectBase &other)
+ void unionWith(const LLRectBase &other)
{
mLeft = llmin(mLeft, other.mLeft);
mRight = llmax(mRight, other.mRight);
mBottom = llmin(mBottom, other.mBottom);
mTop = llmax(mTop, other.mTop);
- return *this;
}
- LLRectBase& intersectWith(const LLRectBase &other)
+ void intersectWith(const LLRectBase &other)
{
mLeft = llmax(mLeft, other.mLeft);
mRight = llmin(mRight, other.mRight);
@@ -262,7 +265,6 @@ public:
{
mBottom = mTop;
}
- return *this;
}
friend std::ostream &operator<<(std::ostream &s, const LLRectBase &rect)
@@ -271,8 +273,8 @@ public:
<< " W " << rect.getWidth() << " H " << rect.getHeight() << " }";
return s;
}
-
- bool operator==(const LLRectBase &b)
+
+ bool operator==(const LLRectBase &b) const
{
return ((mLeft == b.mLeft) &&
(mTop == b.mTop) &&
@@ -280,7 +282,7 @@ public:
(mBottom == b.mBottom));
}
- bool operator!=(const LLRectBase &b)
+ bool operator!=(const LLRectBase &b) const
{
return ((mLeft != b.mLeft) ||
(mTop != b.mTop) ||
diff --git a/indra/llmath/llsdutil_math.cpp b/indra/llmath/llsdutil_math.cpp
index 073cb2e3bd..c5176681ce 100644
--- a/indra/llmath/llsdutil_math.cpp
+++ b/indra/llmath/llsdutil_math.cpp
@@ -165,9 +165,6 @@ LLSD ll_sd_from_color4(const LLColor4& c)
LLColor4 ll_color4_from_sd(const LLSD& sd)
{
LLColor4 c;
- c.mV[0] = (F32)sd[0].asReal();
- c.mV[1] = (F32)sd[1].asReal();
- c.mV[2] = (F32)sd[2].asReal();
- c.mV[3] = (F32)sd[3].asReal();
+ c.setValue(sd);
return c;
}
diff --git a/indra/llmath/llvolume.cpp b/indra/llmath/llvolume.cpp
index 1250f539f5..a0357a32cc 100644
--- a/indra/llmath/llvolume.cpp
+++ b/indra/llmath/llvolume.cpp
@@ -3370,7 +3370,8 @@ void LLVolume::generateSilhouetteVertices(std::vector<LLVector3> &vertices,
std::vector<S32> &segments,
const LLVector3& obj_cam_vec,
const LLMatrix4& mat,
- const LLMatrix3& norm_mat)
+ const LLMatrix3& norm_mat,
+ S32 face_mask)
{
LLMemType m1(LLMemType::MTYPE_VOLUME);
@@ -3378,12 +3379,17 @@ void LLVolume::generateSilhouetteVertices(std::vector<LLVector3> &vertices,
normals.clear();
segments.clear();
+ S32 cur_index = 0;
//for each face
for (face_list_t::iterator iter = mVolumeFaces.begin();
iter != mVolumeFaces.end(); ++iter)
{
const LLVolumeFace& face = *iter;
+ if (!(face_mask & (0x1 << cur_index++)))
+ {
+ continue;
+ }
if (face.mTypeMask & (LLVolumeFace::CAP_MASK)) {
}
diff --git a/indra/llmath/llvolume.h b/indra/llmath/llvolume.h
index e55fe52c91..871b334452 100644
--- a/indra/llmath/llvolume.h
+++ b/indra/llmath/llvolume.h
@@ -52,7 +52,7 @@ class LLVolume;
#include "llquaternion.h"
#include "llstrider.h"
#include "v4coloru.h"
-#include "llmemory.h"
+#include "llrefcount.h"
#include "llfile.h"
//============================================================================
@@ -902,9 +902,13 @@ public:
// returns number of triangle indeces required for path/profile mesh
S32 getNumTriangleIndices() const;
- void generateSilhouetteVertices(std::vector<LLVector3> &vertices, std::vector<LLVector3> &normals, std::vector<S32> &segments, const LLVector3& view_vec,
- const LLMatrix4& mat,
- const LLMatrix3& norm_mat);
+ void generateSilhouetteVertices(std::vector<LLVector3> &vertices,
+ std::vector<LLVector3> &normals,
+ std::vector<S32> &segments,
+ const LLVector3& view_vec,
+ const LLMatrix4& mat,
+ const LLMatrix3& norm_mat,
+ S32 face_index);
//get the face index of the face that intersects with the given line segment at the point
//closest to start. Moves end to the point of intersection. Returns -1 if no intersection.
diff --git a/indra/llmath/llvolumemgr.h b/indra/llmath/llvolumemgr.h
index e10ad94dba..a78ea76a1a 100644
--- a/indra/llmath/llvolumemgr.h
+++ b/indra/llmath/llvolumemgr.h
@@ -36,7 +36,7 @@
#include <map>
#include "llvolume.h"
-#include "llmemory.h"
+#include "llpointer.h"
#include "llthread.h"
class LLVolumeParams;
@@ -92,8 +92,8 @@ public:
// whatever calls getVolume() never owns the LLVolume* and
// cannot keep references for long since it may be deleted
// later. For best results hold it in an LLPointer<LLVolume>.
- LLVolume *refVolume(const LLVolumeParams &volume_params, const S32 detail);
- void unrefVolume(LLVolume *volumep);
+ virtual LLVolume *refVolume(const LLVolumeParams &volume_params, const S32 detail);
+ virtual void unrefVolume(LLVolume *volumep);
void dump();
diff --git a/indra/llmath/v3color.cpp b/indra/llmath/v3color.cpp
index fa7b61cd75..e76607a91f 100644
--- a/indra/llmath/v3color.cpp
+++ b/indra/llmath/v3color.cpp
@@ -75,6 +75,42 @@ std::ostream& operator<<(std::ostream& s, const LLColor3 &a)
return s;
}
+static F32 hueToRgb ( F32 val1In, F32 val2In, F32 valHUeIn )
+{
+ if ( valHUeIn < 0.0f ) valHUeIn += 1.0f;
+ if ( valHUeIn > 1.0f ) valHUeIn -= 1.0f;
+ if ( ( 6.0f * valHUeIn ) < 1.0f ) return ( val1In + ( val2In - val1In ) * 6.0f * valHUeIn );
+ if ( ( 2.0f * valHUeIn ) < 1.0f ) return ( val2In );
+ if ( ( 3.0f * valHUeIn ) < 2.0f ) return ( val1In + ( val2In - val1In ) * ( ( 2.0f / 3.0f ) - valHUeIn ) * 6.0f );
+ return ( val1In );
+}
+
+void LLColor3::setHSL ( F32 hValIn, F32 sValIn, F32 lValIn)
+{
+ if ( sValIn < 0.00001f )
+ {
+ mV[VRED] = lValIn;
+ mV[VGREEN] = lValIn;
+ mV[VBLUE] = lValIn;
+ }
+ else
+ {
+ F32 interVal1;
+ F32 interVal2;
+
+ if ( lValIn < 0.5f )
+ interVal2 = lValIn * ( 1.0f + sValIn );
+ else
+ interVal2 = ( lValIn + sValIn ) - ( sValIn * lValIn );
+
+ interVal1 = 2.0f * lValIn - interVal2;
+
+ mV[VRED] = hueToRgb ( interVal1, interVal2, hValIn + ( 1.f / 3.f ) );
+ mV[VGREEN] = hueToRgb ( interVal1, interVal2, hValIn );
+ mV[VBLUE] = hueToRgb ( interVal1, interVal2, hValIn - ( 1.f / 3.f ) );
+ }
+}
+
void LLColor3::calcHSL(F32* hue, F32* saturation, F32* luminance) const
{
F32 var_R = mV[VRED];
diff --git a/indra/llmath/v3color.h b/indra/llmath/v3color.h
index 179687a32e..1915d80502 100644
--- a/indra/llmath/v3color.h
+++ b/indra/llmath/v3color.h
@@ -79,6 +79,7 @@ public:
mV[2] = (F32) sd[2].asReal();;
}
+ void setHSL(F32 hue, F32 saturation, F32 luminance);
void calcHSL(F32* hue, F32* saturation, F32* luminance) const;
const LLColor3& setToBlack(); // Clears LLColor3 to (0, 0, 0)
diff --git a/indra/llmath/v3dmath.h b/indra/llmath/v3dmath.h
index a99bf5b4a6..6ab31e8a41 100644
--- a/indra/llmath/v3dmath.h
+++ b/indra/llmath/v3dmath.h
@@ -53,7 +53,7 @@ class LLVector3d
inline LLVector3d(const F64 x, const F64 y, const F64 z); // Initializes LLVector3d to (x. y, z)
inline explicit LLVector3d(const F64 *vec); // Initializes LLVector3d to (vec[0]. vec[1], vec[2])
inline explicit LLVector3d(const LLVector3 &vec);
- LLVector3d(const LLSD& sd)
+ explicit LLVector3d(const LLSD& sd)
{
setValue(sd);
}
@@ -65,12 +65,6 @@ class LLVector3d
mdV[2] = sd[2].asReal();
}
- const LLVector3d& operator=(const LLSD& sd)
- {
- setValue(sd);
- return *this;
- }
-
LLSD getValue() const
{
LLSD ret;
diff --git a/indra/llmath/v3math.cpp b/indra/llmath/v3math.cpp
index 101e9d075a..f392ac448b 100644
--- a/indra/llmath/v3math.cpp
+++ b/indra/llmath/v3math.cpp
@@ -314,12 +314,6 @@ void LLVector3::setValue(const LLSD& sd)
mV[2] = (F32) sd[2].asReal();
}
-const LLVector3& LLVector3::operator=(const LLSD& sd)
-{
- setValue(sd);
- return *this;
-}
-
const LLVector3& operator*=(LLVector3 &a, const LLQuaternion &rot)
{
const F32 rw = - rot.mQ[VX] * a.mV[VX] - rot.mQ[VY] * a.mV[VY] - rot.mQ[VZ] * a.mV[VZ];
diff --git a/indra/llmath/v3math.h b/indra/llmath/v3math.h
index 7f96800e21..805d7e6384 100644
--- a/indra/llmath/v3math.h
+++ b/indra/llmath/v3math.h
@@ -67,14 +67,12 @@ class LLVector3
explicit LLVector3(const LLVector2 &vec); // Initializes LLVector3 to (vec[0]. vec[1], 0)
explicit LLVector3(const LLVector3d &vec); // Initializes LLVector3 to (vec[0]. vec[1], vec[2])
explicit LLVector3(const LLVector4 &vec); // Initializes LLVector4 to (vec[0]. vec[1], vec[2])
- LLVector3(const LLSD& sd);
+ explicit LLVector3(const LLSD& sd);
LLSD getValue() const;
void setValue(const LLSD& sd);
- const LLVector3& operator=(const LLSD& sd);
-
inline BOOL isFinite() const; // checks to see if all values of LLVector3 are finite
BOOL clamp(F32 min, F32 max); // Clamps all values to (min,max), returns TRUE if data changed
BOOL clampLength( F32 length_limit ); // Scales vector to limit length to a value
diff --git a/indra/llmath/v4color.cpp b/indra/llmath/v4color.cpp
index 0cbfce07c9..219b06ec74 100644
--- a/indra/llmath/v4color.cpp
+++ b/indra/llmath/v4color.cpp
@@ -227,6 +227,40 @@ const LLColor4& LLColor4::setVec(const LLColor3 &vec, F32 a)
return (*this);
}
+void LLColor4::setValue(const LLSD& sd)
+{
+#if 0
+ // Clamping on setValue from LLSD is inconsistent with other set behavior
+ F32 val;
+ bool out_of_range = false;
+ val = sd[0].asReal();
+ mV[0] = llclamp(val, 0.f, 1.f);
+ out_of_range = mV[0] != val;
+
+ val = sd[1].asReal();
+ mV[1] = llclamp(val, 0.f, 1.f);
+ out_of_range |= mV[1] != val;
+
+ val = sd[2].asReal();
+ mV[2] = llclamp(val, 0.f, 1.f);
+ out_of_range |= mV[2] != val;
+
+ val = sd[3].asReal();
+ mV[3] = llclamp(val, 0.f, 1.f);
+ out_of_range |= mV[3] != val;
+
+ if (out_of_range)
+ {
+ llwarns << "LLSD color value out of range!" << llendl;
+ }
+#else
+ mV[0] = (F32) sd[0].asReal();
+ mV[1] = (F32) sd[1].asReal();
+ mV[2] = (F32) sd[2].asReal();
+ mV[3] = (F32) sd[3].asReal();
+#endif
+}
+
const LLColor4& LLColor4::operator=(const LLColor3 &a)
{
mV[VX] = a.mV[VX];
@@ -271,6 +305,42 @@ LLColor4 vec3to4(const LLColor3 &vec)
return temp;
}
+static F32 hueToRgb ( F32 val1In, F32 val2In, F32 valHUeIn )
+{
+ if ( valHUeIn < 0.0f ) valHUeIn += 1.0f;
+ if ( valHUeIn > 1.0f ) valHUeIn -= 1.0f;
+ if ( ( 6.0f * valHUeIn ) < 1.0f ) return ( val1In + ( val2In - val1In ) * 6.0f * valHUeIn );
+ if ( ( 2.0f * valHUeIn ) < 1.0f ) return ( val2In );
+ if ( ( 3.0f * valHUeIn ) < 2.0f ) return ( val1In + ( val2In - val1In ) * ( ( 2.0f / 3.0f ) - valHUeIn ) * 6.0f );
+ return ( val1In );
+}
+
+void LLColor4::setHSL ( F32 hValIn, F32 sValIn, F32 lValIn)
+{
+ if ( sValIn < 0.00001f )
+ {
+ mV[VRED] = lValIn;
+ mV[VGREEN] = lValIn;
+ mV[VBLUE] = lValIn;
+ }
+ else
+ {
+ F32 interVal1;
+ F32 interVal2;
+
+ if ( lValIn < 0.5f )
+ interVal2 = lValIn * ( 1.0f + sValIn );
+ else
+ interVal2 = ( lValIn + sValIn ) - ( sValIn * lValIn );
+
+ interVal1 = 2.0f * lValIn - interVal2;
+
+ mV[VRED] = hueToRgb ( interVal1, interVal2, hValIn + ( 1.f / 3.f ) );
+ mV[VGREEN] = hueToRgb ( interVal1, interVal2, hValIn );
+ mV[VBLUE] = hueToRgb ( interVal1, interVal2, hValIn - ( 1.f / 3.f ) );
+ }
+}
+
void LLColor4::calcHSL(F32* hue, F32* saturation, F32* luminance) const
{
F32 var_R = mV[VRED];
diff --git a/indra/llmath/v4color.h b/indra/llmath/v4color.h
index 785b47dd37..d6fbdec61e 100644
--- a/indra/llmath/v4color.h
+++ b/indra/llmath/v4color.h
@@ -58,7 +58,7 @@ class LLColor4
LLColor4(U32 clr); // Initializes LLColor4 to (r=clr>>24, etc))
LLColor4(const F32 *vec); // Initializes LLColor4 to (vec[0]. vec[1], vec[2], 1)
LLColor4(const LLColor3 &vec, F32 a = 1.f); // Initializes LLColor4 to (vec, a)
- LLColor4(const LLSD& sd);
+ explicit LLColor4(const LLSD& sd);
explicit LLColor4(const LLColor4U& color4u); // "explicit" to avoid automatic conversion
explicit LLColor4(const LLVector4& vector4); // "explicit" to avoid automatic conversion
@@ -72,14 +72,9 @@ class LLColor4
return ret;
}
- void setValue(const LLSD& sd)
- {
- mV[0] = (F32) sd[0].asReal();
- mV[1] = (F32) sd[1].asReal();
- mV[2] = (F32) sd[2].asReal();
- mV[3] = (F32) sd[3].asReal();
- }
+ void setValue(const LLSD& sd);
+ void setHSL(F32 hue, F32 saturation, F32 luminance);
void calcHSL(F32* hue, F32* saturation, F32* luminance) const;
const LLColor4& setToBlack(); // zero LLColor4 to (0, 0, 0, 1)
@@ -118,7 +113,6 @@ class LLColor4
F32 &operator[](int idx) { return mV[idx]; }
const LLColor4& operator=(const LLColor3 &a); // Assigns vec3 to vec4 and returns vec4
- const LLColor4& operator=(const LLSD& sd);
friend std::ostream& operator<<(std::ostream& s, const LLColor4 &a); // Print a
friend LLColor4 operator+(const LLColor4 &a, const LLColor4 &b); // Return vector a + b
@@ -249,7 +243,7 @@ inline LLColor4::LLColor4(void)
inline LLColor4::LLColor4(const LLSD& sd)
{
- *this = sd;
+ this->setValue(sd);
}
inline LLColor4::LLColor4(F32 r, F32 g, F32 b)
@@ -639,15 +633,5 @@ void LLColor4::clamp()
}
}
-inline const LLColor4& LLColor4::operator=(const LLSD& sd)
-{
- mV[0] = (F32) sd[0].asReal();
- mV[1] = (F32) sd[1].asReal();
- mV[2] = (F32) sd[2].asReal();
- mV[3] = (F32) sd[3].asReal();
-
- return *this;
-}
-
#endif
diff --git a/indra/llmath/v4coloru.h b/indra/llmath/v4coloru.h
index 082d0efbb1..4ec5a345eb 100644
--- a/indra/llmath/v4coloru.h
+++ b/indra/llmath/v4coloru.h
@@ -66,7 +66,7 @@ public:
LLColor4U(U8 r, U8 g, U8 b); // Initializes LLColor4U to (r, g, b, 1)
LLColor4U(U8 r, U8 g, U8 b, U8 a); // Initializes LLColor4U to (r. g, b, a)
LLColor4U(const U8 *vec); // Initializes LLColor4U to (vec[0]. vec[1], vec[2], 1)
- LLColor4U(const LLSD& sd)
+ explicit LLColor4U(const LLSD& sd)
{
setValue(sd);
}
@@ -79,12 +79,6 @@ public:
mV[3] = sd[3].asInteger();
}
- const LLColor4U& operator=(const LLSD& sd)
- {
- setValue(sd);
- return *this;
- }
-
LLSD getValue() const
{
LLSD ret;
@@ -138,6 +132,12 @@ public:
static BOOL parseColor4U(const std::string& buf, LLColor4U* value);
+ // conversion
+ operator const LLColor4() const
+ {
+ return LLColor4(*this);
+ }
+
static LLColor4U white;
static LLColor4U black;
static LLColor4U red;
diff --git a/indra/llmath/xform.h b/indra/llmath/xform.h
index d3be28f41d..5b7b1900bc 100644
--- a/indra/llmath/xform.h
+++ b/indra/llmath/xform.h
@@ -173,7 +173,7 @@ BOOL LLXform::setParent(LLXform* parent)
{
if (cur_par == this)
{
- llwarns << "LLXform::setParent Creating loop when setting parent!" << llendl;
+ //llwarns << "LLXform::setParent Creating loop when setting parent!" << llendl;
return FALSE;
}
cur_par = cur_par->mParent;
diff --git a/indra/llmessage/CMakeLists.txt b/indra/llmessage/CMakeLists.txt
index 81e518cf6e..4eb4a72ae7 100644
--- a/indra/llmessage/CMakeLists.txt
+++ b/indra/llmessage/CMakeLists.txt
@@ -223,6 +223,23 @@ IF (NOT LINUX AND VIEWER)
lltemplatemessagedispatcher.cpp
llregionpresenceverifier.cpp
)
+# set(TEST_DEBUG on)
+ set(test_libs
+ ${LLMESSAGE_LIBRARIES}
+ ${WINDOWS_LIBRARIES}
+ ${LLVFS_LIBRARIES}
+ ${LLMATH_LIBRARIES}
+ ${LLCOMMON_LIBRARIES}
+ )
+
+ LL_ADD_INTEGRATION_TEST(
+ llsdmessage
+ "llsdmessage.cpp"
+ "${test_libs}"
+ ${PYTHON_EXECUTABLE}
+ "${CMAKE_CURRENT_SOURCE_DIR}/tests/test_llsdmessage_peer.py"
+ )
+
LL_ADD_PROJECT_UNIT_TESTS(llmessage "${llmessage_TEST_SOURCE_FILES}")
# Commented out - see rationale at bottom of newview's build file + poppy 2009-06-05
diff --git a/indra/llmessage/llares.h b/indra/llmessage/llares.h
index 96d7f6dd31..c709a08499 100644
--- a/indra/llmessage/llares.h
+++ b/indra/llmessage/llares.h
@@ -45,7 +45,8 @@
# include <ares/ares.h>
#endif
-#include "llmemory.h"
+#include "llpointer.h"
+#include "llrefcount.h"
#include "lluri.h"
class LLQueryResponder;
diff --git a/indra/llmessage/llassetstorage.cpp b/indra/llmessage/llassetstorage.cpp
index 2966b602d7..b3087bcc3f 100644
--- a/indra/llmessage/llassetstorage.cpp
+++ b/indra/llmessage/llassetstorage.cpp
@@ -1025,12 +1025,12 @@ LLSD LLAssetStorage::getPendingDetails(LLAssetStorage::ERequestType rt,
{
const request_list_t* requests = getRequestList(rt);
LLSD sd;
- sd["requests"] = getPendingDetails(requests, asset_type, detail_prefix);
+ sd["requests"] = getPendingDetailsImpl(requests, asset_type, detail_prefix);
return sd;
}
// virtual
-LLSD LLAssetStorage::getPendingDetails(const LLAssetStorage::request_list_t* requests,
+LLSD LLAssetStorage::getPendingDetailsImpl(const LLAssetStorage::request_list_t* requests,
LLAssetType::EType asset_type,
const std::string& detail_prefix) const
{
@@ -1113,11 +1113,11 @@ LLSD LLAssetStorage::getPendingRequest(LLAssetStorage::ERequestType rt,
const LLUUID& asset_id) const
{
const request_list_t* requests = getRequestList(rt);
- return getPendingRequest(requests, asset_type, asset_id);
+ return getPendingRequestImpl(requests, asset_type, asset_id);
}
// virtual
-LLSD LLAssetStorage::getPendingRequest(const LLAssetStorage::request_list_t* requests,
+LLSD LLAssetStorage::getPendingRequestImpl(const LLAssetStorage::request_list_t* requests,
LLAssetType::EType asset_type,
const LLUUID& asset_id) const
{
@@ -1136,7 +1136,7 @@ bool LLAssetStorage::deletePendingRequest(LLAssetStorage::ERequestType rt,
const LLUUID& asset_id)
{
request_list_t* requests = getRequestList(rt);
- if (deletePendingRequest(requests, asset_type, asset_id))
+ if (deletePendingRequestImpl(requests, asset_type, asset_id))
{
llinfos << "Asset " << getRequestName(rt) << " request for "
<< asset_id << "." << LLAssetType::lookup(asset_type)
@@ -1147,7 +1147,7 @@ bool LLAssetStorage::deletePendingRequest(LLAssetStorage::ERequestType rt,
}
// virtual
-bool LLAssetStorage::deletePendingRequest(LLAssetStorage::request_list_t* requests,
+bool LLAssetStorage::deletePendingRequestImpl(LLAssetStorage::request_list_t* requests,
LLAssetType::EType asset_type,
const LLUUID& asset_id)
{
diff --git a/indra/llmessage/llassetstorage.h b/indra/llmessage/llassetstorage.h
index f01ee6a8e8..56adbd5ccf 100644
--- a/indra/llmessage/llassetstorage.h
+++ b/indra/llmessage/llassetstorage.h
@@ -306,15 +306,15 @@ public:
void markAssetToxic( const LLUUID& uuid );
protected:
- virtual LLSD getPendingDetails(const request_list_t* requests,
+ virtual LLSD getPendingDetailsImpl(const request_list_t* requests,
LLAssetType::EType asset_type,
const std::string& detail_prefix) const;
- virtual LLSD getPendingRequest(const request_list_t* requests,
+ virtual LLSD getPendingRequestImpl(const request_list_t* requests,
LLAssetType::EType asset_type,
const LLUUID& asset_id) const;
- virtual bool deletePendingRequest(request_list_t* requests,
+ virtual bool deletePendingRequestImpl(request_list_t* requests,
LLAssetType::EType asset_type,
const LLUUID& asset_id);
diff --git a/indra/llmessage/llcachename.cpp b/indra/llmessage/llcachename.cpp
index 82186fc503..a4304596de 100644
--- a/indra/llmessage/llcachename.cpp
+++ b/indra/llmessage/llcachename.cpp
@@ -42,11 +42,7 @@
#include "llsdserialize.h"
#include "lluuid.h"
#include "message.h"
-
-// Constants
-static const std::string CN_WAITING("(Loading...)"); // *TODO: translate
-static const std::string CN_NOBODY("(nobody)"); // *TODO: translate
-static const std::string CN_NONE("(none)"); // *TODO: translate
+#include "llmemtype.h"
// llsd serialization constants
static const std::string AGENTS("agents");
@@ -65,6 +61,7 @@ const S32 CN_FILE_VERSION = 2;
// Globals
LLCacheName* gCacheName = NULL;
+std::map<std::string, std::string> LLCacheName::sCacheName;
/// ---------------------------------------------------------------------------
/// class LLCacheNameEntry
@@ -76,13 +73,11 @@ public:
LLCacheNameEntry();
public:
- bool isUnknown() { return (mFirstName.empty()
- || mFirstName == std::string("(???)")); };
-
- bool mIsGroup; // true if this is a group ID/name
- U32 mCreateTime; // unix time_t
- std::string mFirstName; // Doubles as the group name
- std::string mLastName; // Will be "" for groups
+ bool mIsGroup;
+ U32 mCreateTime; // unix time_t
+ std::string mFirstName;
+ std::string mLastName;
+ std::string mGroupName;
};
LLCacheNameEntry::LLCacheNameEntry()
@@ -94,17 +89,19 @@ class PendingReply
{
public:
LLUUID mID;
- LLCacheNameCallback mCallback;
+ LLCacheNameSignal mSignal;
LLHost mHost;
- void* mData;
- PendingReply(const LLUUID& id, LLCacheNameCallback callback, void* data = NULL)
- : mID(id), mCallback(callback), mData(data)
- { }
-
+
PendingReply(const LLUUID& id, const LLHost& host)
- : mID(id), mCallback(0), mHost(host)
- { }
-
+ : mID(id), mHost(host)
+ {
+ }
+
+ boost::signals2::connection setCallback(const LLCacheNameCallback& cb)
+ {
+ return mSignal.connect(cb);
+ }
+
void done() { mID.setNull(); }
bool isDone() const { return mID.isNull() != FALSE; }
};
@@ -164,7 +161,7 @@ void ReplySender::send(const LLUUID& id,
mMsg->addUUIDFast(_PREHASH_ID, id);
if(mCurrIsGroup)
{
- mMsg->addStringFast(_PREHASH_GroupName, entry.mFirstName);
+ mMsg->addStringFast(_PREHASH_GroupName, entry.mGroupName);
}
else
{
@@ -189,10 +186,9 @@ void ReplySender::flush()
typedef std::set<LLUUID> AskQueue;
-typedef std::vector<PendingReply> ReplyQueue;
+typedef std::list<PendingReply*> ReplyQueue;
typedef std::map<LLUUID,U32> PendingQueue;
typedef std::map<LLUUID, LLCacheNameEntry*> Cache;
-typedef std::vector<LLCacheNameCallback> Observers;
class LLCacheName::Impl
{
@@ -213,18 +209,20 @@ public:
ReplyQueue mReplyQueue;
// requests awaiting replies from us
- Observers mObservers;
+ LLCacheNameSignal mSignal;
LLFrameTimer mProcessTimer;
Impl(LLMessageSystem* msg);
~Impl();
-
+
+ boost::signals2::connection addPending(const LLUUID& id, const LLCacheNameCallback& callback);
+ void addPending(const LLUUID& id, const LLHost& host);
+
void processPendingAsks();
void processPendingReplies();
void sendRequest(const char* msg_name, const AskQueue& queue);
bool isRequestPending(const LLUUID& id);
- void makeNameRequestForID(const LLUUID& id, bool isGroup, LLHost & fromHost);
// Message system callbacks.
void processUUIDRequest(LLMessageSystem* msg, bool isGroup);
@@ -234,8 +232,6 @@ public:
static void handleUUIDNameReply(LLMessageSystem* msg, void** userdata);
static void handleUUIDGroupNameRequest(LLMessageSystem* msg, void** userdata);
static void handleUUIDGroupNameReply(LLMessageSystem* msg, void** userdata);
-
- void notifyObservers(const LLUUID& id, const std::string& first, const std::string& last, BOOL group);
};
@@ -250,6 +246,9 @@ LLCacheName::LLCacheName(LLMessageSystem* msg)
LLCacheName::LLCacheName(LLMessageSystem* msg, const LLHost& upstream_host)
: impl(* new Impl(msg))
{
+ sCacheName["waiting"] = "(Loading...)";
+ sCacheName["nobody"] = "(nobody)";
+ sCacheName["none"] = "(none)";
setUpstream(upstream_host);
}
@@ -275,52 +274,31 @@ LLCacheName::Impl::Impl(LLMessageSystem* msg)
LLCacheName::Impl::~Impl()
{
for_each(mCache.begin(), mCache.end(), DeletePairedPointer());
+ for_each(mReplyQueue.begin(), mReplyQueue.end(), DeletePointer());
}
-
-void LLCacheName::setUpstream(const LLHost& upstream_host)
+boost::signals2::connection LLCacheName::Impl::addPending(const LLUUID& id, const LLCacheNameCallback& callback)
{
- impl.mUpstreamHost = upstream_host;
+ PendingReply* reply = new PendingReply(id, LLHost());
+ boost::signals2::connection res = reply->setCallback(callback);
+ mReplyQueue.push_back(reply);
+ return res;
}
-void LLCacheName::addObserver(LLCacheNameCallback callback)
+void LLCacheName::Impl::addPending(const LLUUID& id, const LLHost& host)
{
- impl.mObservers.push_back(callback);
+ PendingReply* reply = new PendingReply(id, host);
+ mReplyQueue.push_back(reply);
}
-void LLCacheName::removeObserver(LLCacheNameCallback callback)
+void LLCacheName::setUpstream(const LLHost& upstream_host)
{
- Observers::iterator it = impl.mObservers.begin();
- Observers::iterator end = impl.mObservers.end();
-
- for ( ; it != end; ++it)
- {
- const LLCacheNameCallback& cb = (*it);
- if (cb == callback)
- {
- impl.mObservers.erase(it);
- return;
- }
- }
+ impl.mUpstreamHost = upstream_host;
}
-void LLCacheName::cancelCallback(const LLUUID& id, LLCacheNameCallback callback, void* user_data)
+boost::signals2::connection LLCacheName::addObserver(const LLCacheNameCallback& callback)
{
- ReplyQueue::iterator it = impl.mReplyQueue.begin();
- ReplyQueue::iterator end = impl.mReplyQueue.end();
-
- for(; it != end; ++it)
- {
- const PendingReply& reply = (*it);
-
- if ((callback == reply.mCallback)
- && (id == reply.mID)
- && (user_data == reply.mData) )
- {
- impl.mReplyQueue.erase(it);
- return;
- }
- }
+ return impl.mSignal.connect(callback);
}
void LLCacheName::importFile(LLFILE* fp)
@@ -392,7 +370,6 @@ void LLCacheName::importFile(LLFILE* fp)
entry->mCreateTime = create_time;
entry->mFirstName = firstname;
entry->mLastName = lastname;
- //llinfos << "Adding entry from file for " << entry->mFirstName << " " << entry->mLastName << ", id " << id << llendl;
impl.mCache[id] = entry;
count++;
@@ -429,7 +406,6 @@ bool LLCacheName::importFile(std::istream& istr)
entry->mCreateTime = ctime;
entry->mFirstName = agent[FIRST].asString();
entry->mLastName = agent[LAST].asString();
- //llinfos << "Adding name entry from XML file for " << entry->mFirstName << " " << entry->mLastName << ", id " << id << llendl;
impl.mCache[id] = entry;
++count;
@@ -450,9 +426,7 @@ bool LLCacheName::importFile(std::istream& istr)
LLCacheNameEntry* entry = new LLCacheNameEntry();
entry->mIsGroup = true;
entry->mCreateTime = ctime;
- entry->mFirstName = group[NAME].asString();
- entry->mLastName = "";
- //llinfos << "Adding group entry from XML file for " << entry->mFirstName << " " << entry->mLastName << ", id " << id << llendl;
+ entry->mGroupName = group[NAME].asString();
impl.mCache[id] = entry;
++count;
}
@@ -470,37 +444,37 @@ void LLCacheName::exportFile(std::ostream& ostr)
// Only write entries for which we have valid data.
LLCacheNameEntry* entry = iter->second;
if(!entry
- || entry->isUnknown())
- { // No entry, or user or group name is unknown
+ || (std::string::npos != entry->mFirstName.find('?'))
+ || (std::string::npos != entry->mGroupName.find('?')))
+ {
continue;
}
// store it
LLUUID id = iter->first;
std::string id_str = id.asString();
- if(entry->mIsGroup)
- { // Save group name and ID
- data[GROUPS][id_str][NAME] = entry->mFirstName;
- data[GROUPS][id_str][CTIME] = (S32)entry->mCreateTime;
- }
- else if(!entry->mLastName.empty())
- { // Save user names and ID
+ if(!entry->mFirstName.empty() && !entry->mLastName.empty())
+ {
data[AGENTS][id_str][FIRST] = entry->mFirstName;
data[AGENTS][id_str][LAST] = entry->mLastName;
data[AGENTS][id_str][CTIME] = (S32)entry->mCreateTime;
}
+ else if(entry->mIsGroup && !entry->mGroupName.empty())
+ {
+ data[GROUPS][id_str][NAME] = entry->mGroupName;
+ data[GROUPS][id_str][CTIME] = (S32)entry->mCreateTime;
+ }
}
LLSDSerialize::toPrettyXML(data, ostr);
}
-// DO NOT CALL THIS FOR GROUP NAMES
BOOL LLCacheName::getName(const LLUUID& id, std::string& first, std::string& last)
{
if(id.isNull())
{
- first = CN_NOBODY;
+ first = sCacheName["nobody"];
last.clear();
return FALSE;
}
@@ -514,15 +488,23 @@ BOOL LLCacheName::getName(const LLUUID& id, std::string& first, std::string& las
}
else
{
- first = CN_WAITING;
+ first = sCacheName["waiting"];
last.clear();
if (!impl.isRequestPending(id))
{
- //llinfos << "**** adding name req for " << id << llendl;
impl.mAskNameQueue.insert(id);
}
+ return FALSE;
}
- return FALSE;
+
+}
+// static
+void LLCacheName::LocalizeCacheName(std::string key, std::string value)
+{
+ if (key!="" && value!= "" )
+ sCacheName[key]=value;
+ else
+ llwarns<< " Error localizing cache key " << key << " To "<< value<<llendl;
}
BOOL LLCacheName::getFullName(const LLUUID& id, std::string& fullname)
@@ -537,12 +519,12 @@ BOOL LLCacheName::getGroupName(const LLUUID& id, std::string& group)
{
if(id.isNull())
{
- group = CN_NONE;
+ group = sCacheName["none"];
return FALSE;
}
LLCacheNameEntry* entry = get_ptr_in_map(impl.mCache,id);
- if (entry && entry->mFirstName.empty())
+ if (entry && entry->mGroupName.empty())
{
// COUNTER-HACK to combat James' HACK in exportFile()...
// this group name was loaded from a name cache that did not
@@ -553,12 +535,12 @@ BOOL LLCacheName::getGroupName(const LLUUID& id, std::string& group)
if (entry)
{
- group = entry->mFirstName;
+ group = entry->mGroupName;
return TRUE;
}
else
{
- group = CN_WAITING;
+ group = sCacheName["waiting"];
if (!impl.isRequestPending(id))
{
impl.mAskGroupQueue.insert(id);
@@ -566,22 +548,39 @@ BOOL LLCacheName::getGroupName(const LLUUID& id, std::string& group)
return FALSE;
}
}
-
-// TODO: Make the cache name callback take a SINGLE std::string,
-// not a separate first and last name.
-void LLCacheName::getNameFromUUID(const LLUUID& id, BOOL is_group, LLCacheNameCallback callback, void* user_data)
+// This is a little bit kludgy. LLCacheNameCallback is a slot instead of a function pointer.
+// The reason it is a slot is so that the legacy get() function below can bind an old callback
+// and pass it as a slot. The reason it isn't a boost::function is so that trackable behavior
+// deson't get lost. As a result, we have to bind the slot to a signal to call it, even when
+// we call it immediately. -Steve
+// NOTE: Even though passing first and last name is a bit of extra overhead, it eliminates the
+// potential need for any parsing should any code need to handle first and last name independently.
+boost::signals2::connection LLCacheName::get(const LLUUID& id, BOOL is_group, const LLCacheNameCallback& callback)
{
+ boost::signals2::connection res;
+
if(id.isNull())
{
- callback(id, CN_NOBODY, "", is_group, user_data);
- return;
+ LLCacheNameSignal signal;
+ signal.connect(callback);
+ signal(id, sCacheName["nobody"], "", is_group);
+ return res;
}
LLCacheNameEntry* entry = get_ptr_in_map(impl.mCache, id );
if (entry)
{
- // id found in map therefore we can call the callback immediately. mLastName will be empty for groups
- callback(id, entry->mFirstName, entry->mLastName, entry->mIsGroup, user_data);
+ LLCacheNameSignal signal;
+ signal.connect(callback);
+ // id found in map therefore we can call the callback immediately.
+ if (entry->mIsGroup)
+ {
+ signal(id, entry->mGroupName, "", entry->mIsGroup);
+ }
+ else
+ {
+ signal(id, entry->mFirstName, entry->mLastName, entry->mIsGroup);
+ }
}
else
{
@@ -590,23 +589,26 @@ void LLCacheName::getNameFromUUID(const LLUUID& id, BOOL is_group, LLCacheNameCa
{
if (is_group)
{
- //llinfos << "Group queued for " << id << llendl;
impl.mAskGroupQueue.insert(id);
}
else
{
- //llinfos << "Name queued for " << id << llendl;
impl.mAskNameQueue.insert(id);
}
}
-
- // There may be multiple replies for the same ID request
- impl.mReplyQueue.push_back(PendingReply(id, callback, user_data));
+ res = impl.addPending(id, callback);
}
+ return res;
+}
+
+boost::signals2::connection LLCacheName::get(const LLUUID& id, BOOL is_group, old_callback_t callback, void* user_data)
+{
+ return get(id, is_group, boost::bind(callback, _1, _2, _3, _4, user_data));
}
void LLCacheName::processPending()
{
+ LLMemType mt_pp(LLMemType::MTYPE_CACHE_PROCESS_PENDING);
const F32 SECS_BETWEEN_PROCESS = 0.1f;
if(!impl.mProcessTimer.checkExpirationAndReset(SECS_BETWEEN_PROCESS))
{
@@ -665,7 +667,7 @@ void LLCacheName::dump()
{
llinfos
<< iter->first << " = (group) "
- << entry->mFirstName
+ << entry->mGroupName
<< " @ " << entry->mCreateTime
<< llendl;
}
@@ -688,18 +690,19 @@ void LLCacheName::dumpStats()
<< " AskGroup=" << impl.mAskGroupQueue.size()
<< " Pending=" << impl.mPendingQueue.size()
<< " Reply=" << impl.mReplyQueue.size()
- << " Observers=" << impl.mObservers.size()
+// << " Observers=" << impl.mSignal.size()
<< llendl;
}
//static
std::string LLCacheName::getDefaultName()
{
- return CN_WAITING;
+ return sCacheName["waiting"];
}
void LLCacheName::Impl::processPendingAsks()
{
+ LLMemType mt_ppa(LLMemType::MTYPE_CACHE_PROCESS_PENDING_ASKS);
sendRequest(_PREHASH_UUIDNameRequest, mAskNameQueue);
sendRequest(_PREHASH_UUIDGroupNameRequest, mAskGroupQueue);
mAskNameQueue.clear();
@@ -708,40 +711,50 @@ void LLCacheName::Impl::processPendingAsks()
void LLCacheName::Impl::processPendingReplies()
{
- ReplyQueue::iterator it = mReplyQueue.begin();
- ReplyQueue::iterator end = mReplyQueue.end();
-
+ LLMemType mt_ppr(LLMemType::MTYPE_CACHE_PROCESS_PENDING_REPLIES);
// First call all the callbacks, because they might send messages.
- for(; it != end; ++it)
+ for(ReplyQueue::iterator it = mReplyQueue.begin(); it != mReplyQueue.end(); ++it)
{
- LLCacheNameEntry* entry = get_ptr_in_map(mCache, it->mID);
+ PendingReply* reply = *it;
+ LLCacheNameEntry* entry = get_ptr_in_map(mCache, reply->mID);
if(!entry) continue;
- if (it->mCallback)
+ if (!entry->mIsGroup)
+ {
+ (reply->mSignal)(reply->mID, entry->mFirstName, entry->mLastName, FALSE);
+ }
+ else
{
- (it->mCallback)(it->mID, entry->mFirstName, entry->mLastName, entry->mIsGroup, it->mData);
+ (reply->mSignal)(reply->mID, entry->mGroupName, "", TRUE);
}
}
// Forward on all replies, if needed.
ReplySender sender(mMsg);
- for (it = mReplyQueue.begin(); it != end; ++it)
+ for(ReplyQueue::iterator it = mReplyQueue.begin(); it != mReplyQueue.end(); ++it)
{
- LLCacheNameEntry* entry = get_ptr_in_map(mCache, it->mID);
+ PendingReply* reply = *it;
+ LLCacheNameEntry* entry = get_ptr_in_map(mCache, reply->mID);
if(!entry) continue;
- if (it->mHost.isOk())
+ if (reply->mHost.isOk())
{
- sender.send(it->mID, *entry, it->mHost);
+ sender.send(reply->mID, *entry, reply->mHost);
}
- it->done();
+ reply->done();
+ }
+
+ for(ReplyQueue::iterator it = mReplyQueue.begin(); it != mReplyQueue.end(); )
+ {
+ ReplyQueue::iterator curit = it++;
+ PendingReply* reply = *curit;
+ if (reply->isDone())
+ {
+ delete reply;
+ mReplyQueue.erase(curit);
+ }
}
-
- mReplyQueue.erase(
- remove_if(mReplyQueue.begin(), mReplyQueue.end(),
- std::mem_fun_ref(&PendingReply::isDone)),
- mReplyQueue.end());
}
@@ -762,12 +775,10 @@ void LLCacheName::Impl::sendRequest(
if(start_new_message)
{
start_new_message = false;
- //llinfos << "newMessageFast : " << msg_name << llendl;
mMsg->newMessageFast(msg_name);
}
mMsg->nextBlockFast(_PREHASH_UUIDNameBlock);
mMsg->addUUIDFast(_PREHASH_ID, (*it));
- //llinfos << " asking for ID: " << (*it) << llendl;
if(mMsg->isSendFullFast(_PREHASH_UUIDNameBlock))
{
@@ -781,18 +792,6 @@ void LLCacheName::Impl::sendRequest(
}
}
-void LLCacheName::Impl::notifyObservers(const LLUUID& id,
- const std::string& first, const std::string& last, BOOL is_group)
-{
- for (Observers::const_iterator i = mObservers.begin(),
- end = mObservers.end();
- i != end;
- ++i)
- {
- (**i)(id, first, last, is_group, NULL);
- }
-}
-
bool LLCacheName::Impl::isRequestPending(const LLUUID& id)
{
U32 now = (U32)time(NULL);
@@ -833,102 +832,38 @@ void LLCacheName::Impl::processUUIDRequest(LLMessageSystem* msg, bool isGroup)
{
if (isGroup != entry->mIsGroup)
{
- if (entry->isUnknown())
- {
- Cache::iterator doomediter = mCache.find(id);
- if (doomediter != mCache.end())
- { // Kill existing unknown entry
- llwarns << "LLCacheName - Asked for "
- << (isGroup ? "group" : "user") << " name, "
- << "but found unknown "
- << (entry->mIsGroup ? "group" : "user")
- << " entry for: " << id
- << ", deleting bad entry"
- << llendl;
-
- delete entry;
- entry = NULL;
- mCache.erase(doomediter);
-
- // Request it with (hopefully) the correct type
- makeNameRequestForID(id,isGroup,fromHost);
- }
- }
- else if (isGroup)
- {
- llwarns << "LLCacheName - Asked for group name, but found user: "
- << id
- << " named "
- << entry->mFirstName << " " << entry->mLastName
- << llendl;
- }
- else
- {
- llwarns << "LLCacheName - Asked for user name, but found group: "
- << id
- << " named "
- << entry->mFirstName
- << llendl;
- }
+ llwarns << "LLCacheName - Asked for "
+ << (isGroup ? "group" : "user") << " name, "
+ << "but found "
+ << (entry->mIsGroup ? "group" : "user")
+ << ": " << id << llendl;
}
else
{
// ...it's in the cache, so send it as the reply
sender.send(id, *entry, fromHost);
-
- /*
+ }
+ }
+ else
+ {
+ if (!isRequestPending(id))
+ {
if (isGroup)
{
- llinfos << "Group ID " << id
- << " name " << entry->mFirstName
- << " was already in cache" << llendl;
+ mAskGroupQueue.insert(id);
}
else
{
- llinfos << "Agent ID " << id
- << " name " << entry->mFirstName << " " << entry->mLastName
- << " was already in cache" << llendl;
+ mAskNameQueue.insert(id);
}
- */
}
- }
- else
- { /*
- if (isGroup)
- {
- llinfos << "Group ID " << id << " is not in cache" << llendl;
- }
- else
- {
- llinfos << "Agent ID " << id << " is not in cache" << llendl;
- }
- */
- makeNameRequestForID(id,isGroup,fromHost);
+
+ addPending(id, fromHost);
}
}
}
-void LLCacheName::Impl::makeNameRequestForID(const LLUUID& id, bool isGroup, LLHost & fromHost)
-{
- if (!isRequestPending(id))
- {
- if (isGroup)
- {
- //llinfos << "Adding group request for " << id << llendl;
- mAskGroupQueue.insert(id);
- }
- else
- {
- //llinfos << "Adding name request for " << id << llendl;
- mAskNameQueue.insert(id);
- }
- }
-
- // There may be multiple replys for the same ID request
- mReplyQueue.push_back(PendingReply(id, fromHost));
-}
-
void LLCacheName::Impl::processUUIDReply(LLMessageSystem* msg, bool isGroup)
{
@@ -938,53 +873,35 @@ void LLCacheName::Impl::processUUIDReply(LLMessageSystem* msg, bool isGroup)
LLUUID id;
msg->getUUIDFast(_PREHASH_UUIDNameBlock, _PREHASH_ID, id, i);
LLCacheNameEntry* entry = get_ptr_in_map(mCache, id);
- bool add_new_entry_to_cache = false;
if (!entry)
{
entry = new LLCacheNameEntry;
- add_new_entry_to_cache = true;
+ mCache[id] = entry;
}
- // Remove ID from pending queue
mPendingQueue.erase(id);
- std::string first_name;
- std::string last_name;
- if (isGroup)
- { // Group
- msg->getStringFast(_PREHASH_UUIDNameBlock, _PREHASH_GroupName, first_name, i);
- LLStringFn::replace_ascii_controlchars(first_name, LL_UNKNOWN_CHAR);
+ entry->mIsGroup = isGroup;
+ entry->mCreateTime = (U32)time(NULL);
+ if (!isGroup)
+ {
+ msg->getStringFast(_PREHASH_UUIDNameBlock, _PREHASH_FirstName, entry->mFirstName, i);
+ msg->getStringFast(_PREHASH_UUIDNameBlock, _PREHASH_LastName, entry->mLastName, i);
}
else
- { // User
- msg->getStringFast(_PREHASH_UUIDNameBlock, _PREHASH_FirstName, first_name, i);
- msg->getStringFast(_PREHASH_UUIDNameBlock, _PREHASH_LastName, last_name, i);
- }
-
- if (!add_new_entry_to_cache &&
- (entry->mFirstName != first_name ||
- entry->mLastName != last_name ||
- entry->mIsGroup != isGroup))
- { // Hmmm, we already had an different entry for this ID. Let's see what happened...
- llwarns << "Replacing existing entry in name cache for id " << id
- << " first name was " << entry->mFirstName << ", now " << first_name
- << " last name was " << entry->mLastName << ", now " << last_name
- << " group flag was " << (S32) entry->mIsGroup << ", now " << (S32) isGroup
- << llendl;
+ { // is group
+ msg->getStringFast(_PREHASH_UUIDNameBlock, _PREHASH_GroupName, entry->mGroupName, i);
+ LLStringFn::replace_ascii_controlchars(entry->mGroupName, LL_UNKNOWN_CHAR);
}
- entry->mFirstName = first_name;
- entry->mLastName = last_name;
- entry->mIsGroup = isGroup;
- entry->mCreateTime = (U32)time(NULL);
-
- if (add_new_entry_to_cache)
+ if (!isGroup)
{
- //llinfos << "Adding entry for " << entry->mFirstName << " " << entry->mLastName << ", id " << id << llendl;
- mCache[id] = entry;
+ mSignal(id, entry->mFirstName, entry->mLastName, FALSE);
+ }
+ else
+ {
+ mSignal(id, entry->mGroupName, "", TRUE);
}
-
- notifyObservers(id, entry->mFirstName, entry->mLastName, isGroup);
}
}
diff --git a/indra/llmessage/llcachename.h b/indra/llmessage/llcachename.h
index bfa116ad4a..c044b3d80d 100644
--- a/indra/llmessage/llcachename.h
+++ b/indra/llmessage/llcachename.h
@@ -33,12 +33,22 @@
#ifndef LL_LLCACHENAME_H
#define LL_LLCACHENAME_H
+#include <boost/bind.hpp>
+#include <boost/signals2.hpp>
+
class LLMessageSystem;
class LLHost;
class LLUUID;
-// agent_id/group_id, first_name, last_name, is_group, user_data
-typedef void (*LLCacheNameCallback)(const LLUUID&, const std::string&, const std::string&, BOOL, void*);
+
+typedef boost::signals2::signal<void (const LLUUID& id,
+ const std::string& first_name,
+ const std::string& last_name,
+ BOOL is_group)> LLCacheNameSignal;
+typedef LLCacheNameSignal::slot_type LLCacheNameCallback;
+
+// Old callback with user data for compatability
+typedef void (*old_callback_t)(const LLUUID&, const std::string&, const std::string&, BOOL, void*);
// Here's the theory:
// If you request a name that isn't in the cache, it returns "waiting"
@@ -59,10 +69,7 @@ public:
// for simulators, this is the data server
void setUpstream(const LLHost& upstream_host);
- void addObserver(LLCacheNameCallback callback);
- void removeObserver(LLCacheNameCallback callback);
-
- void cancelCallback(const LLUUID& id, LLCacheNameCallback callback, void* user_data = NULL);
+ boost::signals2::connection addObserver(const LLCacheNameCallback& callback);
// janky old format. Remove after a while. Phoenix. 2008-01-30
void importFile(LLFILE* fp);
@@ -89,8 +96,10 @@ public:
// If the data is currently available, may call the callback immediatly
// otherwise, will request the data, and will call the callback when
// available. There is no garuntee the callback will ever be called.
- void getNameFromUUID(const LLUUID& id, BOOL is_group, LLCacheNameCallback callback, void* user_data = NULL);
+ boost::signals2::connection get(const LLUUID& id, BOOL is_group, const LLCacheNameCallback& callback);
+ // LEGACY
+ boost::signals2::connection get(const LLUUID& id, BOOL is_group, old_callback_t callback, void* user_data);
// This method needs to be called from time to time to send out
// requests.
void processPending();
@@ -103,7 +112,8 @@ public:
void dumpStats(); // Dumps the sizes of the cache and associated queues.
static std::string getDefaultName();
-
+ static void LocalizeCacheName(std::string key, std::string value);
+ static std::map<std::string, std::string> sCacheName;
private:
class Impl;
diff --git a/indra/llmessage/llcurl.cpp b/indra/llmessage/llcurl.cpp
index 1a432cd7df..a4af8e989b 100644
--- a/indra/llmessage/llcurl.cpp
+++ b/indra/llmessage/llcurl.cpp
@@ -120,7 +120,7 @@ LLCurl::Responder::~Responder()
}
// virtual
-void LLCurl::Responder::error(
+void LLCurl::Responder::errorWithContent(
U32 status,
const std::string& reason,
const LLSD&)
@@ -161,7 +161,7 @@ void LLCurl::Responder::completed(U32 status, const std::string& reason, const L
}
else
{
- error(status, reason, content);
+ errorWithContent(status, reason, content);
}
}
diff --git a/indra/llmessage/llcurl.h b/indra/llmessage/llcurl.h
index ff63904c91..fbd3077cbf 100644
--- a/indra/llmessage/llcurl.h
+++ b/indra/llmessage/llcurl.h
@@ -85,7 +85,7 @@ public:
return((200 <= status) && (status < 300));
}
- virtual void error(
+ virtual void errorWithContent(
U32 status,
const std::string& reason,
const LLSD& content);
diff --git a/indra/llmessage/llhttpassetstorage.cpp b/indra/llmessage/llhttpassetstorage.cpp
index dfdad59e2a..49dbdbd56d 100644
--- a/indra/llmessage/llhttpassetstorage.cpp
+++ b/indra/llmessage/llhttpassetstorage.cpp
@@ -626,7 +626,7 @@ LLSD LLHTTPAssetStorage::getPendingRequest(LLAssetStorage::ERequestType rt,
const request_list_t* running = getRunningList(rt);
if (running)
{
- LLSD sd = LLAssetStorage::getPendingRequest(running, asset_type, asset_id);
+ LLSD sd = LLAssetStorage::getPendingRequestImpl(running, asset_type, asset_id);
if (sd)
{
sd["is_running"] = true;
diff --git a/indra/llmessage/llhttpassetstorage.h b/indra/llmessage/llhttpassetstorage.h
index 5786c5df32..231437dad4 100644
--- a/indra/llmessage/llhttpassetstorage.h
+++ b/indra/llmessage/llhttpassetstorage.h
@@ -62,6 +62,8 @@ public:
virtual ~LLHTTPAssetStorage();
+ using LLAssetStorage::storeAssetData; // Unhiding virtuals...
+
virtual void storeAssetData(
const LLUUID& uuid,
LLAssetType::EType atype,
diff --git a/indra/llmessage/llhttpclientadapter.cpp b/indra/llmessage/llhttpclientadapter.cpp
index 5236a52164..9d3c83f828 100644
--- a/indra/llmessage/llhttpclientadapter.cpp
+++ b/indra/llmessage/llhttpclientadapter.cpp
@@ -4,7 +4,7 @@
*
* $LicenseInfo:firstyear=2009&license=viewergpl$
*
- * Copyright (c) 2001-2009, Linden Research, Inc.
+ * Copyright (c) 2009, Linden Research, Inc.
*
* Second Life Viewer Source Code
* The source code in this file ("Source Code") is provided by Linden Lab
@@ -12,12 +12,13 @@
* ("GPL"), unless you have obtained a separate licensing agreement
* ("Other License"), formally executed by you and Linden Lab. Terms of
* the GPL can be found in doc/GPL-license.txt in this distribution, or
- * online at http://secondlife.com/developers/opensource/gplv2
+ * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
*
* There are special exceptions to the terms and conditions of the GPL as
* it is applied to this Source Code. View the full text of the exception
* in the file doc/FLOSS-exception.txt in this software distribution, or
- * online at http://secondlife.com/developers/opensource/flossexception
+ * online at
+ * http://secondlifegrid.net/programs/open_source/licensing/flossexception
*
* By copying, modifying or distributing this software, you acknowledge
* that you have read and understood your obligations described above,
diff --git a/indra/llmessage/llhttpclientadapter.h b/indra/llmessage/llhttpclientadapter.h
index c489dca32d..a205a2f260 100644
--- a/indra/llmessage/llhttpclientadapter.h
+++ b/indra/llmessage/llhttpclientadapter.h
@@ -4,7 +4,7 @@
*
* $LicenseInfo:firstyear=2008&license=viewergpl$
*
- * Copyright (c) 2001-2008, Linden Research, Inc.
+ * Copyright (c) 2008-2009, Linden Research, Inc.
*
* Second Life Viewer Source Code
* The source code in this file ("Source Code") is provided by Linden Lab
@@ -12,12 +12,13 @@
* ("GPL"), unless you have obtained a separate licensing agreement
* ("Other License"), formally executed by you and Linden Lab. Terms of
* the GPL can be found in doc/GPL-license.txt in this distribution, or
- * online at http://secondlife.com/developers/opensource/gplv2
+ * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
*
* There are special exceptions to the terms and conditions of the GPL as
* it is applied to this Source Code. View the full text of the exception
* in the file doc/FLOSS-exception.txt in this software distribution, or
- * online at http://secondlife.com/developers/opensource/flossexception
+ * online at
+ * http://secondlifegrid.net/programs/open_source/licensing/flossexception
*
* By copying, modifying or distributing this software, you acknowledge
* that you have read and understood your obligations described above,
@@ -33,7 +34,7 @@
#define LL_HTTPCLIENTADAPTER_H
#include "llhttpclientinterface.h"
-#include "llmemory.h" // LLSingleton<>
+#include "llsingleton.h" // LLSingleton<>
class LLHTTPClientAdapter : public LLHTTPClientInterface, public LLSingleton<LLHTTPClientAdapter>
{
diff --git a/indra/llmessage/llhttpclientinterface.h b/indra/llmessage/llhttpclientinterface.h
index 61826cc4b4..085a59cf27 100644
--- a/indra/llmessage/llhttpclientinterface.h
+++ b/indra/llmessage/llhttpclientinterface.h
@@ -4,7 +4,7 @@
*
* $LicenseInfo:firstyear=2008&license=viewergpl$
*
- * Copyright (c) 2001-2008, Linden Research, Inc.
+ * Copyright (c) 2008-2009, Linden Research, Inc.
*
* Second Life Viewer Source Code
* The source code in this file ("Source Code") is provided by Linden Lab
@@ -12,12 +12,13 @@
* ("GPL"), unless you have obtained a separate licensing agreement
* ("Other License"), formally executed by you and Linden Lab. Terms of
* the GPL can be found in doc/GPL-license.txt in this distribution, or
- * online at http://secondlife.com/developers/opensource/gplv2
+ * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
*
* There are special exceptions to the terms and conditions of the GPL as
* it is applied to this Source Code. View the full text of the exception
* in the file doc/FLOSS-exception.txt in this software distribution, or
- * online at http://secondlife.com/developers/opensource/flossexception
+ * online at
+ * http://secondlifegrid.net/programs/open_source/licensing/flossexception
*
* By copying, modifying or distributing this software, you acknowledge
* that you have read and understood your obligations described above,
diff --git a/indra/llmessage/llhttpnode.cpp b/indra/llmessage/llhttpnode.cpp
index 2ba900a533..440b91fcfa 100644
--- a/indra/llmessage/llhttpnode.cpp
+++ b/indra/llmessage/llhttpnode.cpp
@@ -98,19 +98,19 @@ namespace {
}
// virtual
-LLSD LLHTTPNode::get() const
+LLSD LLHTTPNode::simpleGet() const
{
throw NotImplemented();
}
// virtual
-LLSD LLHTTPNode::put(const LLSD& input) const
+LLSD LLHTTPNode::simplePut(const LLSD& input) const
{
throw NotImplemented();
}
// virtual
-LLSD LLHTTPNode::post(const LLSD& input) const
+LLSD LLHTTPNode::simplePost(const LLSD& input) const
{
throw NotImplemented();
}
@@ -121,7 +121,7 @@ void LLHTTPNode::get(LLHTTPNode::ResponsePtr response, const LLSD& context) cons
{
try
{
- response->result(get());
+ response->result(simpleGet());
}
catch (NotImplemented)
{
@@ -134,7 +134,7 @@ void LLHTTPNode::put(LLHTTPNode::ResponsePtr response, const LLSD& context, cons
{
try
{
- response->result(put(input));
+ response->result(simplePut(input));
}
catch (NotImplemented)
{
@@ -147,7 +147,7 @@ void LLHTTPNode::post(LLHTTPNode::ResponsePtr response, const LLSD& context, con
{
try
{
- response->result(post(input));
+ response->result(simplePost(input));
}
catch (NotImplemented)
{
@@ -160,7 +160,7 @@ void LLHTTPNode::del(LLHTTPNode::ResponsePtr response, const LLSD& context) cons
{
try
{
- response->result(del(context));
+ response->result(simpleDel(context));
}
catch (NotImplemented)
{
@@ -170,7 +170,7 @@ void LLHTTPNode::del(LLHTTPNode::ResponsePtr response, const LLSD& context) cons
}
// virtual
-LLSD LLHTTPNode::del(const LLSD&) const
+LLSD LLHTTPNode::simpleDel(const LLSD&) const
{
throw NotImplemented();
}
@@ -388,7 +388,7 @@ LLHTTPNode::Response::~Response()
{
}
-void LLHTTPNode::Response::status(S32 code)
+void LLHTTPNode::Response::statusUnknownError(S32 code)
{
status(code, "Unknown Error");
}
diff --git a/indra/llmessage/llhttpnode.h b/indra/llmessage/llhttpnode.h
index 17ffd66e8f..915aacb7cc 100644
--- a/indra/llmessage/llhttpnode.h
+++ b/indra/llmessage/llhttpnode.h
@@ -33,7 +33,8 @@
#ifndef LL_LLHTTPNODE_H
#define LL_LLHTTPNODE_H
-#include "llmemory.h"
+#include "llpointer.h"
+#include "llrefcount.h"
#include "llsd.h"
class LLChainIOFactory;
@@ -83,10 +84,10 @@ public:
//@{
public:
- virtual LLSD get() const;
- virtual LLSD put(const LLSD& input) const;
- virtual LLSD post(const LLSD& input) const;
- virtual LLSD del(const LLSD& context) const;
+ virtual LLSD simpleGet() const;
+ virtual LLSD simplePut(const LLSD& input) const;
+ virtual LLSD simplePost(const LLSD& input) const;
+ virtual LLSD simpleDel(const LLSD& context) const;
/**
* @brief Abstract Base Class declaring Response interface.
@@ -116,7 +117,7 @@ public:
/**
* @brief Return no body, just status code and 'UNKNOWN ERROR'.
*/
- virtual void status(S32 code);
+ virtual void statusUnknownError(S32 code);
virtual void notFound(const std::string& message);
virtual void notFound();
@@ -292,6 +293,7 @@ public:
void result(const LLSD& result);
void extendedResult(S32 code, const std::string& body, const LLSD& headers);
+
void status(S32 code, const std::string& message);
void print(std::ostream& out) const;
diff --git a/indra/llmessage/llhttpnodeadapter.h b/indra/llmessage/llhttpnodeadapter.h
index 08b5664162..7c3e9d81d1 100644
--- a/indra/llmessage/llhttpnodeadapter.h
+++ b/indra/llmessage/llhttpnodeadapter.h
@@ -3,26 +3,27 @@
* @brief Declaration of llhttpnode adapter classes
*
* $LicenseInfo:firstyear=2009&license=viewergpl$
- *
+ *
* Copyright (c) 2009, Linden Research, Inc.
- *
+ *
* Second Life Viewer Source Code
* The source code in this file ("Source Code") is provided by Linden Lab
* to you under the terms of the GNU General Public License, version 2.0
* ("GPL"), unless you have obtained a separate licensing agreement
* ("Other License"), formally executed by you and Linden Lab. Terms of
* the GPL can be found in doc/GPL-license.txt in this distribution, or
- * online at http://secondlife.com/developers/opensource/gplv2
- *
+ * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
+ *
* There are special exceptions to the terms and conditions of the GPL as
* it is applied to this Source Code. View the full text of the exception
* in the file doc/FLOSS-exception.txt in this software distribution, or
- * online at http://secondlife.com/developers/opensource/flossexception
- *
+ * online at
+ * http://secondlifegrid.net/programs/open_source/licensing/flossexception
+ *
* By copying, modifying or distributing this software, you acknowledge
* that you have read and understood your obligations described above,
* and agree to abide by those obligations.
- *
+ *
* ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
* COMPLETENESS OR PERFORMANCE.
diff --git a/indra/llmessage/llinstantmessage.cpp b/indra/llmessage/llinstantmessage.cpp
index 3205ddfaeb..7c63625004 100644
--- a/indra/llmessage/llinstantmessage.cpp
+++ b/indra/llmessage/llinstantmessage.cpp
@@ -41,7 +41,7 @@
#include "llsd.h"
#include "llsdserialize.h"
#include "llsdutil.h"
-#include "llmemory.h"
+#include "llpointer.h"
#include "message.h"
#include "message.h"
diff --git a/indra/llmessage/llinstantmessage.h b/indra/llmessage/llinstantmessage.h
index 9ce6a10c80..272e753f3c 100644
--- a/indra/llmessage/llinstantmessage.h
+++ b/indra/llmessage/llinstantmessage.h
@@ -36,7 +36,8 @@
#include "llhost.h"
#include "lluuid.h"
#include "llsd.h"
-#include "llmemory.h"
+#include "llrefcount.h"
+#include "llpointer.h"
#include "v3math.h"
class LLMessageSystem;
diff --git a/indra/llmessage/lliohttpserver.cpp b/indra/llmessage/lliohttpserver.cpp
index ce815cc85b..97134bd336 100644
--- a/indra/llmessage/lliohttpserver.cpp
+++ b/indra/llmessage/lliohttpserver.cpp
@@ -105,6 +105,7 @@ private:
// from LLHTTPNode::Response
virtual void result(const LLSD&);
virtual void extendedResult(S32 code, const std::string& body, const LLSD& headers);
+
virtual void status(S32 code, const std::string& message);
void nullPipe();
diff --git a/indra/llmessage/llmessagesenderinterface.h b/indra/llmessage/llmessagesenderinterface.h
index d98d891563..af6733fa05 100644
--- a/indra/llmessage/llmessagesenderinterface.h
+++ b/indra/llmessage/llmessagesenderinterface.h
@@ -4,7 +4,7 @@
*
* $LicenseInfo:firstyear=2008&license=viewergpl$
*
- * Copyright (c) 2001-2008, Linden Research, Inc.
+ * Copyright (c) 2008-2009, Linden Research, Inc.
*
* Second Life Viewer Source Code
* The source code in this file ("Source Code") is provided by Linden Lab
@@ -12,12 +12,13 @@
* ("GPL"), unless you have obtained a separate licensing agreement
* ("Other License"), formally executed by you and Linden Lab. Terms of
* the GPL can be found in doc/GPL-license.txt in this distribution, or
- * online at http://secondlife.com/developers/opensource/gplv2
+ * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
*
* There are special exceptions to the terms and conditions of the GPL as
* it is applied to this Source Code. View the full text of the exception
* in the file doc/FLOSS-exception.txt in this software distribution, or
- * online at http://secondlife.com/developers/opensource/flossexception
+ * online at
+ * http://secondlifegrid.net/programs/open_source/licensing/flossexception
*
* By copying, modifying or distributing this software, you acknowledge
* that you have read and understood your obligations described above,
diff --git a/indra/llmessage/llpumpio.cpp b/indra/llmessage/llpumpio.cpp
index 3e3f0b37a7..5e9dfd81fa 100644
--- a/indra/llmessage/llpumpio.cpp
+++ b/indra/llmessage/llpumpio.cpp
@@ -444,11 +444,13 @@ void LLPumpIO::pump()
pump(DEFAULT_POLL_TIMEOUT);
}
+static LLFastTimer::DeclareTimer FTM_PUMP("Pump");
+
//timeout is in microseconds
void LLPumpIO::pump(const S32& poll_timeout)
{
LLMemType m1(LLMemType::MTYPE_IO_PUMP);
- LLFastTimer t1(LLFastTimer::FTM_PUMP);
+ LLFastTimer t1(FTM_PUMP);
//llinfos << "LLPumpIO::pump()" << llendl;
// Run any pending runners.
diff --git a/indra/llmessage/llregionpresenceverifier.cpp b/indra/llmessage/llregionpresenceverifier.cpp
index 08c12f90da..4faad4468b 100644
--- a/indra/llmessage/llregionpresenceverifier.cpp
+++ b/indra/llmessage/llregionpresenceverifier.cpp
@@ -4,14 +4,25 @@
*
* $LicenseInfo:firstyear=2008&license=viewergpl$
*
- * Copyright (c) 2008, Linden Research, Inc.
+ * Copyright (c) 2008-2009, Linden Research, Inc.
*
- * The following source code is PROPRIETARY AND CONFIDENTIAL. Use of
- * this source code is governed by the Linden Lab Source Code Disclosure
- * Agreement ("Agreement") previously entered between you and Linden
- * Lab. By accessing, using, copying, modifying or distributing this
- * software, you acknowledge that you have been informed of your
- * obligations under the Agreement and agree to abide by those obligations.
+ * Second Life Viewer Source Code
+ * The source code in this file ("Source Code") is provided by Linden Lab
+ * to you under the terms of the GNU General Public License, version 2.0
+ * ("GPL"), unless you have obtained a separate licensing agreement
+ * ("Other License"), formally executed by you and Linden Lab. Terms of
+ * the GPL can be found in doc/GPL-license.txt in this distribution, or
+ * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
+ *
+ * There are special exceptions to the terms and conditions of the GPL as
+ * it is applied to this Source Code. View the full text of the exception
+ * in the file doc/FLOSS-exception.txt in this software distribution, or
+ * online at
+ * http://secondlifegrid.net/programs/open_source/licensing/flossexception
+ *
+ * By copying, modifying or distributing this software, you acknowledge
+ * that you have read and understood your obligations described above,
+ * and agree to abide by those obligations.
*
* ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
diff --git a/indra/llmessage/llregionpresenceverifier.h b/indra/llmessage/llregionpresenceverifier.h
index f11eeef50c..f57a62a731 100644
--- a/indra/llmessage/llregionpresenceverifier.h
+++ b/indra/llmessage/llregionpresenceverifier.h
@@ -4,14 +4,25 @@
*
* $LicenseInfo:firstyear=2008&license=viewergpl$
*
- * Copyright (c) 2008, Linden Research, Inc.
+ * Copyright (c) 2008-2009, Linden Research, Inc.
*
- * The following source code is PROPRIETARY AND CONFIDENTIAL. Use of
- * this source code is governed by the Linden Lab Source Code Disclosure
- * Agreement ("Agreement") previously entered between you and Linden
- * Lab. By accessing, using, copying, modifying or distributing this
- * software, you acknowledge that you have been informed of your
- * obligations under the Agreement and agree to abide by those obligations.
+ * Second Life Viewer Source Code
+ * The source code in this file ("Source Code") is provided by Linden Lab
+ * to you under the terms of the GNU General Public License, version 2.0
+ * ("GPL"), unless you have obtained a separate licensing agreement
+ * ("Other License"), formally executed by you and Linden Lab. Terms of
+ * the GPL can be found in doc/GPL-license.txt in this distribution, or
+ * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
+ *
+ * There are special exceptions to the terms and conditions of the GPL as
+ * it is applied to this Source Code. View the full text of the exception
+ * in the file doc/FLOSS-exception.txt in this software distribution, or
+ * online at
+ * http://secondlifegrid.net/programs/open_source/licensing/flossexception
+ *
+ * By copying, modifying or distributing this software, you acknowledge
+ * that you have read and understood your obligations described above,
+ * and agree to abide by those obligations.
*
* ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
@@ -72,6 +83,7 @@ public:
const LLSD& content, S32 retry_count);
virtual ~VerifiedDestinationResponder();
virtual void result(const LLSD& content);
+
virtual void error(U32 status, const std::string& reason);
private:
diff --git a/indra/llmessage/llsdappservices.cpp b/indra/llmessage/llsdappservices.cpp
index dc135c51b2..b87c0cd6b7 100644
--- a/indra/llmessage/llsdappservices.cpp
+++ b/indra/llmessage/llsdappservices.cpp
@@ -56,7 +56,7 @@ public:
desc.source(__FILE__, __LINE__);
}
- virtual LLSD get() const
+ virtual LLSD simpleGet() const
{
LLSD result;
LLApp* app = LLApp::instance();
@@ -82,7 +82,7 @@ public:
desc.source(__FILE__, __LINE__);
}
- virtual LLSD get() const
+ virtual LLSD simpleGet() const
{
return LLApp::instance()->getOptionData(
LLApp::PRIORITY_RUNTIME_OVERRIDE);
diff --git a/indra/llmessage/llsdhttpserver.cpp b/indra/llmessage/llsdhttpserver.cpp
index 00fc170c59..704c375ffc 100644
--- a/indra/llmessage/llsdhttpserver.cpp
+++ b/indra/llmessage/llsdhttpserver.cpp
@@ -62,7 +62,7 @@ public:
desc.source(__FILE__, __LINE__);
}
- virtual LLSD get() const
+ virtual LLSD simpleGet() const
{
LLSD result = "hello";
return result;
@@ -86,7 +86,7 @@ public:
desc.source(__FILE__, __LINE__);
}
- virtual LLSD post(const LLSD& params) const
+ virtual LLSD simplePost(const LLSD& params) const
{
return params;
}
diff --git a/indra/llmessage/llsdmessage.cpp b/indra/llmessage/llsdmessage.cpp
index f663268466..9967a6197f 100644
--- a/indra/llmessage/llsdmessage.cpp
+++ b/indra/llmessage/llsdmessage.cpp
@@ -91,7 +91,7 @@ void LLSDMessage::EventResponder::result(const LLSD& data)
}
}
-void LLSDMessage::EventResponder::error(U32 status, const std::string& reason, const LLSD& content)
+void LLSDMessage::EventResponder::errorWithContent(U32 status, const std::string& reason, const LLSD& content)
{
// If our caller passed an empty errorPump name, they're not
// listening: "default error handling is acceptable." Only post to an
@@ -135,7 +135,7 @@ bool LLSDMessage::ResponderAdapter::listener(const LLSD& payload, bool success)
}
else
{
- mResponder->error(payload["status"].asInteger(), payload["reason"], payload["content"]);
+ mResponder->errorWithContent(payload["status"].asInteger(), payload["reason"], payload["content"]);
}
/*---------------- MUST BE LAST STATEMENT BEFORE RETURN ----------------*/
diff --git a/indra/llmessage/llsdmessage.h b/indra/llmessage/llsdmessage.h
index 8ae9451243..65503756a8 100644
--- a/indra/llmessage/llsdmessage.h
+++ b/indra/llmessage/llsdmessage.h
@@ -131,7 +131,7 @@ private:
{}
virtual void result(const LLSD& data);
- virtual void error(U32 status, const std::string& reason, const LLSD& content);
+ virtual void errorWithContent(U32 status, const std::string& reason, const LLSD& content);
private:
LLEventPumps& mPumps;
diff --git a/indra/llmessage/llstoredmessage.cpp b/indra/llmessage/llstoredmessage.cpp
index da6d1c84a8..d6b2f45d04 100644
--- a/indra/llmessage/llstoredmessage.cpp
+++ b/indra/llmessage/llstoredmessage.cpp
@@ -4,7 +4,7 @@
*
* $LicenseInfo:firstyear=2009&license=viewergpl$
*
- * Copyright (c) 2001-2009, Linden Research, Inc.
+ * Copyright (c) 2009, Linden Research, Inc.
*
* Second Life Viewer Source Code
* The source code in this file ("Source Code") is provided by Linden Lab
diff --git a/indra/llmessage/llstoredmessage.h b/indra/llmessage/llstoredmessage.h
index 6a27698b03..359e4c5aea 100644
--- a/indra/llmessage/llstoredmessage.h
+++ b/indra/llmessage/llstoredmessage.h
@@ -4,7 +4,7 @@
*
* $LicenseInfo:firstyear=2009&license=viewergpl$
*
- * Copyright (c) 2001-2009, Linden Research, Inc.
+ * Copyright (c) 2009, Linden Research, Inc.
*
* Second Life Viewer Source Code
* The source code in this file ("Source Code") is provided by Linden Lab
diff --git a/indra/llmessage/lltemplatemessagedispatcher.cpp b/indra/llmessage/lltemplatemessagedispatcher.cpp
index 3bbf3a058d..ab1beb362b 100644
--- a/indra/llmessage/lltemplatemessagedispatcher.cpp
+++ b/indra/llmessage/lltemplatemessagedispatcher.cpp
@@ -3,26 +3,27 @@
* @brief LLTemplateMessageDispatcher class
*
* $LicenseInfo:firstyear=2009&license=viewergpl$
- *
- * Copyright (c) 2001-2009, Linden Research, Inc.
- *
+ *
+ * Copyright (c) 2009, Linden Research, Inc.
+ *
* Second Life Viewer Source Code
* The source code in this file ("Source Code") is provided by Linden Lab
* to you under the terms of the GNU General Public License, version 2.0
* ("GPL"), unless you have obtained a separate licensing agreement
* ("Other License"), formally executed by you and Linden Lab. Terms of
* the GPL can be found in doc/GPL-license.txt in this distribution, or
- * online at http://secondlife.com/developers/opensource/gplv2
- *
+ * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
+ *
* There are special exceptions to the terms and conditions of the GPL as
* it is applied to this Source Code. View the full text of the exception
* in the file doc/FLOSS-exception.txt in this software distribution, or
- * online at http://secondlife.com/developers/opensource/flossexception
- *
+ * online at
+ * http://secondlifegrid.net/programs/open_source/licensing/flossexception
+ *
* By copying, modifying or distributing this software, you acknowledge
* that you have read and understood your obligations described above,
* and agree to abide by those obligations.
- *
+ *
* ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
* COMPLETENESS OR PERFORMANCE.
diff --git a/indra/llmessage/lltemplatemessagedispatcher.h b/indra/llmessage/lltemplatemessagedispatcher.h
index b1e74f47bb..fa861e4e42 100644
--- a/indra/llmessage/lltemplatemessagedispatcher.h
+++ b/indra/llmessage/lltemplatemessagedispatcher.h
@@ -3,26 +3,27 @@
* @brief LLTemplateMessageDispatcher class
*
* $LicenseInfo:firstyear=2009&license=viewergpl$
- *
- * Copyright (c) 2001-2009, Linden Research, Inc.
- *
+ *
+ * Copyright (c) 2009, Linden Research, Inc.
+ *
* Second Life Viewer Source Code
* The source code in this file ("Source Code") is provided by Linden Lab
* to you under the terms of the GNU General Public License, version 2.0
* ("GPL"), unless you have obtained a separate licensing agreement
* ("Other License"), formally executed by you and Linden Lab. Terms of
* the GPL can be found in doc/GPL-license.txt in this distribution, or
- * online at http://secondlife.com/developers/opensource/gplv2
- *
+ * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
+ *
* There are special exceptions to the terms and conditions of the GPL as
* it is applied to this Source Code. View the full text of the exception
* in the file doc/FLOSS-exception.txt in this software distribution, or
- * online at http://secondlife.com/developers/opensource/flossexception
- *
+ * online at
+ * http://secondlifegrid.net/programs/open_source/licensing/flossexception
+ *
* By copying, modifying or distributing this software, you acknowledge
* that you have read and understood your obligations described above,
* and agree to abide by those obligations.
- *
+ *
* ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
* COMPLETENESS OR PERFORMANCE.
diff --git a/indra/llmessage/lltemplatemessagereader.cpp b/indra/llmessage/lltemplatemessagereader.cpp
index 80ea6ce96b..8c9eb7ed42 100644
--- a/indra/llmessage/lltemplatemessagereader.cpp
+++ b/indra/llmessage/lltemplatemessagereader.cpp
@@ -531,6 +531,8 @@ void LLTemplateMessageReader::logRanOffEndOfPacket( const LLHost& host, const S3
gMessageSystem->callExceptionFunc(MX_RAN_OFF_END_OF_PACKET);
}
+static LLFastTimer::DeclareTimer FTM_PROCESS_MESSAGES("Process Messages");
+
// decode a given message
BOOL LLTemplateMessageReader::decodeData(const U8* buffer, const LLHost& sender )
{
@@ -714,7 +716,7 @@ BOOL LLTemplateMessageReader::decodeData(const U8* buffer, const LLHost& sender
}
{
- LLFastTimer t(LLFastTimer::FTM_PROCESS_MESSAGES);
+ LLFastTimer t(FTM_PROCESS_MESSAGES);
if( !mCurrentRMessageTemplate->callHandlerFunc(gMessageSystem) )
{
llwarns << "Message from " << sender << " with no handler function received: " << mCurrentRMessageTemplate->mName << llendl;
diff --git a/indra/llmessage/lltrustedmessageservice.cpp b/indra/llmessage/lltrustedmessageservice.cpp
index c1a6c437a7..505ece57b0 100644
--- a/indra/llmessage/lltrustedmessageservice.cpp
+++ b/indra/llmessage/lltrustedmessageservice.cpp
@@ -3,26 +3,27 @@
* @brief LLTrustedMessageService implementation
*
* $LicenseInfo:firstyear=2009&license=viewergpl$
- *
- * Copyright (c) 2001-2009, Linden Research, Inc.
- *
+ *
+ * Copyright (c) 2009, Linden Research, Inc.
+ *
* Second Life Viewer Source Code
* The source code in this file ("Source Code") is provided by Linden Lab
* to you under the terms of the GNU General Public License, version 2.0
* ("GPL"), unless you have obtained a separate licensing agreement
* ("Other License"), formally executed by you and Linden Lab. Terms of
* the GPL can be found in doc/GPL-license.txt in this distribution, or
- * online at http://secondlife.com/developers/opensource/gplv2
- *
+ * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
+ *
* There are special exceptions to the terms and conditions of the GPL as
* it is applied to this Source Code. View the full text of the exception
* in the file doc/FLOSS-exception.txt in this software distribution, or
- * online at http://secondlife.com/developers/opensource/flossexception
- *
+ * online at
+ * http://secondlifegrid.net/programs/open_source/licensing/flossexception
+ *
* By copying, modifying or distributing this software, you acknowledge
* that you have read and understood your obligations described above,
* and agree to abide by those obligations.
- *
+ *
* ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
* COMPLETENESS OR PERFORMANCE.
diff --git a/indra/llmessage/lltrustedmessageservice.h b/indra/llmessage/lltrustedmessageservice.h
index bc824565f1..dc37702471 100644
--- a/indra/llmessage/lltrustedmessageservice.h
+++ b/indra/llmessage/lltrustedmessageservice.h
@@ -3,26 +3,27 @@
* @brief LLTrustedMessageService class
*
* $LicenseInfo:firstyear=2009&license=viewergpl$
- *
- * Copyright (c) 2001-2009, Linden Research, Inc.
- *
+ *
+ * Copyright (c) 2009, Linden Research, Inc.
+ *
* Second Life Viewer Source Code
* The source code in this file ("Source Code") is provided by Linden Lab
* to you under the terms of the GNU General Public License, version 2.0
* ("GPL"), unless you have obtained a separate licensing agreement
* ("Other License"), formally executed by you and Linden Lab. Terms of
* the GPL can be found in doc/GPL-license.txt in this distribution, or
- * online at http://secondlife.com/developers/opensource/gplv2
- *
+ * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
+ *
* There are special exceptions to the terms and conditions of the GPL as
* it is applied to this Source Code. View the full text of the exception
* in the file doc/FLOSS-exception.txt in this software distribution, or
- * online at http://secondlife.com/developers/opensource/flossexception
- *
+ * online at
+ * http://secondlifegrid.net/programs/open_source/licensing/flossexception
+ *
* By copying, modifying or distributing this software, you acknowledge
* that you have read and understood your obligations described above,
* and agree to abide by those obligations.
- *
+ *
* ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
* COMPLETENESS OR PERFORMANCE.
diff --git a/indra/llmessage/message.cpp b/indra/llmessage/message.cpp
index 78af35bf65..e56d818d65 100644
--- a/indra/llmessage/message.cpp
+++ b/indra/llmessage/message.cpp
@@ -86,6 +86,7 @@
#include "v3math.h"
#include "v4math.h"
#include "lltransfertargetvfile.h"
+#include "llmemtype.h"
// Constants
//const char* MESSAGE_LOG_FILENAME = "message.log";
@@ -794,6 +795,7 @@ S32 LLMessageSystem::getReceiveBytes() const
void LLMessageSystem::processAcks()
{
+ LLMemType mt_pa(LLMemType::MTYPE_MESSAGE_PROCESS_ACKS);
F64 mt_sec = getMessageTimeSeconds();
{
gTransferManager.updateTransfers();
@@ -4020,6 +4022,7 @@ void LLMessageSystem::setTimeDecodesSpamThreshold( F32 seconds )
// TODO: babbage: move gServicePump in to LLMessageSystem?
bool LLMessageSystem::checkAllMessages(S64 frame_count, LLPumpIO* http_pump)
{
+ LLMemType mt_cam(LLMemType::MTYPE_MESSAGE_CHECK_ALL);
if(checkMessages(frame_count))
{
return true;
diff --git a/indra/llmessage/message.h b/indra/llmessage/message.h
index 0f3576732d..27482ca1af 100644
--- a/indra/llmessage/message.h
+++ b/indra/llmessage/message.h
@@ -59,10 +59,10 @@
#include "llhttpclient.h"
#include "llhttpnode.h"
#include "llpacketack.h"
+#include "llsingleton.h"
#include "message_prehash.h"
#include "llstl.h"
#include "llmsgvariabletype.h"
-#include "llmsgvariabletype.h"
#include "llmessagesenderinterface.h"
#include "llstoredmessage.h"
diff --git a/indra/llmessage/message_prehash.cpp b/indra/llmessage/message_prehash.cpp
index 30af58e430..9e3986f257 100644
--- a/indra/llmessage/message_prehash.cpp
+++ b/indra/llmessage/message_prehash.cpp
@@ -406,7 +406,7 @@ char* _PREHASH_GlobalX = LLMessageStringTable::getInstance()->getString("GlobalX
char* _PREHASH_GlobalY = LLMessageStringTable::getInstance()->getString("GlobalY");
char* _PREHASH_CopyRotates = LLMessageStringTable::getInstance()->getString("CopyRotates");
char* _PREHASH_KickUserAck = LLMessageStringTable::getInstance()->getString("KickUserAck");
-char* _PREHASH_TopPick = LLMessageStringTable::getInstance()->getString("TopPick");
+char* _PREHASH_TopPick = LLMessageStringTable::getInstance()->getString("TopPick"); //legacy var need to be deleted -angela
char* _PREHASH_SessionID = LLMessageStringTable::getInstance()->getString("SessionID");
char* _PREHASH_GlobalZ = LLMessageStringTable::getInstance()->getString("GlobalZ");
char* _PREHASH_DeclineFriendship = LLMessageStringTable::getInstance()->getString("DeclineFriendship");
diff --git a/indra/llmessage/tests/commtest.h b/indra/llmessage/tests/commtest.h
index 7360230451..cf1461ed2b 100644
--- a/indra/llmessage/tests/commtest.h
+++ b/indra/llmessage/tests/commtest.h
@@ -5,7 +5,30 @@
* @brief
*
* $LicenseInfo:firstyear=2009&license=viewergpl$
+ *
* Copyright (c) 2009, Linden Research, Inc.
+ *
+ * Second Life Viewer Source Code
+ * The source code in this file ("Source Code") is provided by Linden Lab
+ * to you under the terms of the GNU General Public License, version 2.0
+ * ("GPL"), unless you have obtained a separate licensing agreement
+ * ("Other License"), formally executed by you and Linden Lab. Terms of
+ * the GPL can be found in doc/GPL-license.txt in this distribution, or
+ * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
+ *
+ * There are special exceptions to the terms and conditions of the GPL as
+ * it is applied to this Source Code. View the full text of the exception
+ * in the file doc/FLOSS-exception.txt in this software distribution, or
+ * online at
+ * http://secondlifegrid.net/programs/open_source/licensing/flossexception
+ *
+ * By copying, modifying or distributing this software, you acknowledge
+ * that you have read and understood your obligations described above,
+ * and agree to abide by those obligations.
+ *
+ * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+ * COMPLETENESS OR PERFORMANCE.
* $/LicenseInfo$
*/
diff --git a/indra/llmessage/tests/llcurl_stub.cpp b/indra/llmessage/tests/llcurl_stub.cpp
index 93653e345e..5dc5932fde 100644
--- a/indra/llmessage/tests/llcurl_stub.cpp
+++ b/indra/llmessage/tests/llcurl_stub.cpp
@@ -3,16 +3,16 @@
* @brief stub class to allow unit testing
*
* $LicenseInfo:firstyear=2008&license=viewergpl$
- *
- * Copyright (c) 2008, Linden Research, Inc.
- *
+ *
+ * Copyright (c) 2008-2009, Linden Research, Inc.
+ *
* The following source code is PROPRIETARY AND CONFIDENTIAL. Use of
* this source code is governed by the Linden Lab Source Code Disclosure
- * Agreement ("Agreement") { }
+ * Agreement ("Agreement") previously entered between you and Linden
* Lab. By accessing, using, copying, modifying or distributing this
* software, you acknowledge that you have been informed of your
* obligations under the Agreement and agree to abide by those obligations.
- *
+ *
* ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
* COMPLETENESS OR PERFORMANCE.
@@ -34,7 +34,7 @@ void LLCurl::Responder::completed(U32 status, std::basic_string<char, std::char_
}
else
{
- error(status, reason, mContent);
+ errorWithContent(status, reason, mContent);
}
}
@@ -51,7 +51,7 @@ void LLCurl::Responder::completedRaw(unsigned,
{
}
-void LLCurl::Responder::error(unsigned,
+void LLCurl::Responder::errorWithContent(unsigned,
std::basic_string<char, std::char_traits<char>, std::allocator<char> > const&,
LLSD const&)
{
diff --git a/indra/llmessage/tests/llhttpclientadapter_test.cpp b/indra/llmessage/tests/llhttpclientadapter_test.cpp
index bde76db08b..250fa100b6 100644
--- a/indra/llmessage/tests/llhttpclientadapter_test.cpp
+++ b/indra/llmessage/tests/llhttpclientadapter_test.cpp
@@ -4,7 +4,7 @@
*
* $LicenseInfo:firstyear=2008&license=viewergpl$
*
- * Copyright (c) 2001-2008, Linden Research, Inc.
+ * Copyright (c) 2008-2009, Linden Research, Inc.
*
* Second Life Viewer Source Code
* The source code in this file ("Source Code") is provided by Linden Lab
@@ -12,12 +12,13 @@
* ("GPL"), unless you have obtained a separate licensing agreement
* ("Other License"), formally executed by you and Linden Lab. Terms of
* the GPL can be found in doc/GPL-license.txt in this distribution, or
- * online at http://secondlife.com/developers/opensource/gplv2
+ * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
*
* There are special exceptions to the terms and conditions of the GPL as
* it is applied to this Source Code. View the full text of the exception
* in the file doc/FLOSS-exception.txt in this software distribution, or
- * online at http://secondlife.com/developers/opensource/flossexception
+ * online at
+ * http://secondlifegrid.net/programs/open_source/licensing/flossexception
*
* By copying, modifying or distributing this software, you acknowledge
* that you have read and understood your obligations described above,
diff --git a/indra/llmessage/tests/lltemplatemessagedispatcher_test.cpp b/indra/llmessage/tests/lltemplatemessagedispatcher_test.cpp
index a6f5659352..d57f17f270 100644
--- a/indra/llmessage/tests/lltemplatemessagedispatcher_test.cpp
+++ b/indra/llmessage/tests/lltemplatemessagedispatcher_test.cpp
@@ -3,26 +3,27 @@
* @brief LLTrustedMessageService unit tests
*
* $LicenseInfo:firstyear=2009&license=viewergpl$
- *
- * Copyright (c) 2001-2009, Linden Research, Inc.
- *
+ *
+ * Copyright (c) 2009, Linden Research, Inc.
+ *
* Second Life Viewer Source Code
* The source code in this file ("Source Code") is provided by Linden Lab
* to you under the terms of the GNU General Public License, version 2.0
* ("GPL"), unless you have obtained a separate licensing agreement
* ("Other License"), formally executed by you and Linden Lab. Terms of
* the GPL can be found in doc/GPL-license.txt in this distribution, or
- * online at http://secondlife.com/developers/opensource/gplv2
- *
+ * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
+ *
* There are special exceptions to the terms and conditions of the GPL as
* it is applied to this Source Code. View the full text of the exception
* in the file doc/FLOSS-exception.txt in this software distribution, or
- * online at http://secondlife.com/developers/opensource/flossexception
- *
+ * online at
+ * http://secondlifegrid.net/programs/open_source/licensing/flossexception
+ *
* By copying, modifying or distributing this software, you acknowledge
* that you have read and understood your obligations described above,
* and agree to abide by those obligations.
- *
+ *
* ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
* COMPLETENESS OR PERFORMANCE.
diff --git a/indra/llmessage/tests/lltesthttpclientadapter.cpp b/indra/llmessage/tests/lltesthttpclientadapter.cpp
index 41ce36f345..0cea4b57c2 100644
--- a/indra/llmessage/tests/lltesthttpclientadapter.cpp
+++ b/indra/llmessage/tests/lltesthttpclientadapter.cpp
@@ -4,7 +4,7 @@
*
* $LicenseInfo:firstyear=2008&license=viewergpl$
*
- * Copyright (c) 2008, Linden Research, Inc.
+ * Copyright (c) 2008-2009, Linden Research, Inc.
*
* The following source code is PROPRIETARY AND CONFIDENTIAL. Use of
* this source code is governed by the Linden Lab Source Code Disclosure
diff --git a/indra/llmessage/tests/lltesthttpclientadapter.h b/indra/llmessage/tests/lltesthttpclientadapter.h
index cd93bcc8c1..6f252e8510 100644
--- a/indra/llmessage/tests/lltesthttpclientadapter.h
+++ b/indra/llmessage/tests/lltesthttpclientadapter.h
@@ -4,7 +4,7 @@
*
* $LicenseInfo:firstyear=2008&license=viewergpl$
*
- * Copyright (c) 2008, Linden Research, Inc.
+ * Copyright (c) 2008-2009, Linden Research, Inc.
*
* The following source code is PROPRIETARY AND CONFIDENTIAL. Use of
* this source code is governed by the Linden Lab Source Code Disclosure
diff --git a/indra/llmessage/tests/lltestmessagesender.cpp b/indra/llmessage/tests/lltestmessagesender.cpp
index 240813a4a3..3d1876ec36 100644
--- a/indra/llmessage/tests/lltestmessagesender.cpp
+++ b/indra/llmessage/tests/lltestmessagesender.cpp
@@ -4,7 +4,7 @@
*
* $LicenseInfo:firstyear=2008&license=viewergpl$
*
- * Copyright (c) 2008, Linden Research, Inc.
+ * Copyright (c) 2008-2009, Linden Research, Inc.
*
* The following source code is PROPRIETARY AND CONFIDENTIAL. Use of
* this source code is governed by the Linden Lab Source Code Disclosure
diff --git a/indra/llmessage/tests/lltestmessagesender.h b/indra/llmessage/tests/lltestmessagesender.h
index 00641d1913..d3aaee8f69 100644
--- a/indra/llmessage/tests/lltestmessagesender.h
+++ b/indra/llmessage/tests/lltestmessagesender.h
@@ -4,7 +4,7 @@
*
* $LicenseInfo:firstyear=2008&license=viewergpl$
*
- * Copyright (c) 2008, Linden Research, Inc.
+ * Copyright (c) 2008-2009, Linden Research, Inc.
*
* The following source code is PROPRIETARY AND CONFIDENTIAL. Use of
* this source code is governed by the Linden Lab Source Code Disclosure
diff --git a/indra/llmessage/tests/lltrustedmessageservice_test.cpp b/indra/llmessage/tests/lltrustedmessageservice_test.cpp
index 44595391df..0a3da4b467 100644
--- a/indra/llmessage/tests/lltrustedmessageservice_test.cpp
+++ b/indra/llmessage/tests/lltrustedmessageservice_test.cpp
@@ -3,26 +3,27 @@
* @brief LLTrustedMessageService unit tests
*
* $LicenseInfo:firstyear=2009&license=viewergpl$
- *
- * Copyright (c) 2001-2009, Linden Research, Inc.
- *
+ *
+ * Copyright (c) 2009, Linden Research, Inc.
+ *
* Second Life Viewer Source Code
* The source code in this file ("Source Code") is provided by Linden Lab
* to you under the terms of the GNU General Public License, version 2.0
* ("GPL"), unless you have obtained a separate licensing agreement
* ("Other License"), formally executed by you and Linden Lab. Terms of
* the GPL can be found in doc/GPL-license.txt in this distribution, or
- * online at http://secondlife.com/developers/opensource/gplv2
- *
+ * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
+ *
* There are special exceptions to the terms and conditions of the GPL as
* it is applied to this Source Code. View the full text of the exception
* in the file doc/FLOSS-exception.txt in this software distribution, or
- * online at http://secondlife.com/developers/opensource/flossexception
- *
+ * online at
+ * http://secondlifegrid.net/programs/open_source/licensing/flossexception
+ *
* By copying, modifying or distributing this software, you acknowledge
* that you have read and understood your obligations described above,
* and agree to abide by those obligations.
- *
+ *
* ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
* COMPLETENESS OR PERFORMANCE.
diff --git a/indra/llmessage/tests/networkio.h b/indra/llmessage/tests/networkio.h
index 11c5cc07fc..0ebe369ea2 100644
--- a/indra/llmessage/tests/networkio.h
+++ b/indra/llmessage/tests/networkio.h
@@ -5,7 +5,30 @@
* @brief
*
* $LicenseInfo:firstyear=2009&license=viewergpl$
+ *
* Copyright (c) 2009, Linden Research, Inc.
+ *
+ * Second Life Viewer Source Code
+ * The source code in this file ("Source Code") is provided by Linden Lab
+ * to you under the terms of the GNU General Public License, version 2.0
+ * ("GPL"), unless you have obtained a separate licensing agreement
+ * ("Other License"), formally executed by you and Linden Lab. Terms of
+ * the GPL can be found in doc/GPL-license.txt in this distribution, or
+ * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
+ *
+ * There are special exceptions to the terms and conditions of the GPL as
+ * it is applied to this Source Code. View the full text of the exception
+ * in the file doc/FLOSS-exception.txt in this software distribution, or
+ * online at
+ * http://secondlifegrid.net/programs/open_source/licensing/flossexception
+ *
+ * By copying, modifying or distributing this software, you acknowledge
+ * that you have read and understood your obligations described above,
+ * and agree to abide by those obligations.
+ *
+ * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+ * COMPLETENESS OR PERFORMANCE.
* $/LicenseInfo$
*/
diff --git a/indra/llplugin/CMakeLists.txt b/indra/llplugin/CMakeLists.txt
new file mode 100644
index 0000000000..6706775d4f
--- /dev/null
+++ b/indra/llplugin/CMakeLists.txt
@@ -0,0 +1,55 @@
+# -*- cmake -*-
+
+project(llplugin)
+
+include(00-Common)
+include(LLCommon)
+include(LLImage)
+include(LLMath)
+include(LLMessage)
+include(LLRender)
+include(LLXML)
+include(LLWindow)
+
+include_directories(
+ ${LLCOMMON_INCLUDE_DIRS}
+ ${LLIMAGE_INCLUDE_DIRS}
+ ${LLMATH_INCLUDE_DIRS}
+ ${LLMESSAGE_INCLUDE_DIRS}
+ ${LLRENDER_INCLUDE_DIRS}
+ ${LLXML_INCLUDE_DIRS}
+ ${LLWINDOW_INCLUDE_DIRS}
+ )
+
+set(llplugin_SOURCE_FILES
+ llpluginclassmedia.cpp
+ llplugininstance.cpp
+ llpluginmessage.cpp
+ llpluginmessagepipe.cpp
+ llpluginprocesschild.cpp
+ llpluginprocessparent.cpp
+ llpluginsharedmemory.cpp
+ )
+
+set(llplugin_HEADER_FILES
+ CMakeLists.txt
+
+ llpluginclassmedia.h
+ llpluginclassmediaowner.h
+ llplugininstance.h
+ llpluginmessage.h
+ llpluginmessageclasses.h
+ llpluginmessagepipe.h
+ llpluginprocesschild.h
+ llpluginprocessparent.h
+ llpluginsharedmemory.h
+ )
+
+set_source_files_properties(${llplugin_HEADER_FILES}
+ PROPERTIES HEADER_FILE_ONLY TRUE)
+
+list(APPEND llplugin_SOURCE_FILES ${llplugin_HEADER_FILES})
+
+add_library (llplugin ${llplugin_SOURCE_FILES})
+
+add_subdirectory(slplugin)
diff --git a/indra/llplugin/llpluginclassmedia.cpp b/indra/llplugin/llpluginclassmedia.cpp
new file mode 100644
index 0000000000..54f153d182
--- /dev/null
+++ b/indra/llplugin/llpluginclassmedia.cpp
@@ -0,0 +1,1042 @@
+/**
+ * @file llpluginclassmedia.cpp
+ * @brief LLPluginClassMedia handles a plugin which knows about the "media" message class.
+ *
+ * $LicenseInfo:firstyear=2008&license=viewergpl$
+ *
+ * Copyright (c) 2008, Linden Research, Inc.
+ *
+ * Second Life Viewer Source Code
+ * The source code in this file ("Source Code") is provided by Linden Lab
+ * to you under the terms of the GNU General Public License, version 2.0
+ * ("GPL"), unless you have obtained a separate licensing agreement
+ * ("Other License"), formally executed by you and Linden Lab. Terms of
+ * the GPL can be found in doc/GPL-license.txt in this distribution, or
+ * online at http://secondlife.com/developers/opensource/gplv2
+ *
+ * There are special exceptions to the terms and conditions of the GPL as
+ * it is applied to this Source Code. View the full text of the exception
+ * in the file doc/FLOSS-exception.txt in this software distribution, or
+ * online at http://secondlife.com/developers/opensource/flossexception
+ *
+ * By copying, modifying or distributing this software, you acknowledge
+ * that you have read and understood your obligations described above,
+ * and agree to abide by those obligations.
+ *
+ * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+ * COMPLETENESS OR PERFORMANCE.
+ * $/LicenseInfo$
+ */
+
+#include "linden_common.h"
+#include "indra_constants.h"
+
+#include "llpluginclassmedia.h"
+#include "llpluginmessageclasses.h"
+
+static int LOW_PRIORITY_TEXTURE_SIZE_DEFAULT = 256;
+
+static int nextPowerOf2( int value )
+{
+ int next_power_of_2 = 1;
+ while ( next_power_of_2 < value )
+ {
+ next_power_of_2 <<= 1;
+ }
+
+ return next_power_of_2;
+}
+
+LLPluginClassMedia::LLPluginClassMedia(LLPluginClassMediaOwner *owner)
+{
+ mOwner = owner;
+ mPlugin = NULL;
+ reset();
+}
+
+
+LLPluginClassMedia::~LLPluginClassMedia()
+{
+ reset();
+}
+
+bool LLPluginClassMedia::init(const std::string &launcher_filename, const std::string &plugin_filename)
+{
+ LL_DEBUGS("Plugin") << "launcher: " << launcher_filename << LL_ENDL;
+ LL_DEBUGS("Plugin") << "plugin: " << plugin_filename << LL_ENDL;
+
+ mPlugin = new LLPluginProcessParent(this);
+ mPlugin->setSleepTime(mSleepTime);
+ mPlugin->init(launcher_filename, plugin_filename);
+
+ return true;
+}
+
+
+void LLPluginClassMedia::reset()
+{
+ if(mPlugin != NULL)
+ {
+ delete mPlugin;
+ mPlugin = NULL;
+ }
+
+ mTextureParamsReceived = false;
+ mRequestedTextureDepth = 0;
+ mRequestedTextureInternalFormat = 0;
+ mRequestedTextureFormat = 0;
+ mRequestedTextureType = 0;
+ mRequestedTextureSwapBytes = false;
+ mRequestedTextureCoordsOpenGL = false;
+ mTextureSharedMemorySize = 0;
+ mTextureSharedMemoryName.clear();
+ mDefaultMediaWidth = 0;
+ mDefaultMediaHeight = 0;
+ mNaturalMediaWidth = 0;
+ mNaturalMediaHeight = 0;
+ mSetMediaWidth = -1;
+ mSetMediaHeight = -1;
+ mRequestedMediaWidth = 0;
+ mRequestedMediaHeight = 0;
+ mTextureWidth = 0;
+ mTextureHeight = 0;
+ mMediaWidth = 0;
+ mMediaHeight = 0;
+ mDirtyRect = LLRect::null;
+ mAutoScaleMedia = false;
+ mRequestedVolume = 1.0f;
+ mPriority = PRIORITY_NORMAL;
+ mLowPrioritySizeLimit = LOW_PRIORITY_TEXTURE_SIZE_DEFAULT;
+ mAllowDownsample = false;
+ mPadding = 0;
+ mStatus = LLPluginClassMediaOwner::MEDIA_NONE;
+ mSleepTime = 1.0f / 100.0f;
+ mCanCut = false;
+ mCanCopy = false;
+ mCanPaste = false;
+ mMediaName.clear();
+ mMediaDescription.clear();
+
+ // media_browser class
+ mNavigateURI.clear();
+ mNavigateResultCode = -1;
+ mNavigateResultString.clear();
+ mHistoryBackAvailable = false;
+ mHistoryForwardAvailable = false;
+ mStatusText.clear();
+ mProgressPercent = 0;
+
+ // media_time class
+ mCurrentTime = 0.0f;
+ mDuration = 0.0f;
+ mCurrentRate = 0.0f;
+}
+
+void LLPluginClassMedia::idle(void)
+{
+ if(mPlugin)
+ {
+ mPlugin->idle();
+ }
+
+ if((mMediaWidth == -1) || (!mTextureParamsReceived) || (mPlugin == NULL))
+ {
+ // Can't process a size change at this time
+ }
+ else if((mRequestedMediaWidth != mMediaWidth) || (mRequestedMediaHeight != mMediaHeight))
+ {
+ // Calculate the correct size for the media texture
+ mRequestedTextureHeight = mRequestedMediaHeight;
+ if(mPadding < 0)
+ {
+ // negative values indicate the plugin wants a power of 2
+ mRequestedTextureWidth = nextPowerOf2(mRequestedMediaWidth);
+ }
+ else
+ {
+ mRequestedTextureWidth = mRequestedMediaWidth;
+
+ if(mPadding > 1)
+ {
+ // Pad up to a multiple of the specified number of bytes per row
+ int rowbytes = mRequestedTextureWidth * mRequestedTextureDepth;
+ int pad = rowbytes % mPadding;
+ if(pad != 0)
+ {
+ rowbytes += mPadding - pad;
+ }
+
+ if(rowbytes % mRequestedTextureDepth == 0)
+ {
+ mRequestedTextureWidth = rowbytes / mRequestedTextureDepth;
+ }
+ else
+ {
+ LL_WARNS("Plugin") << "Unable to pad texture width, padding size " << mPadding << "is not a multiple of pixel size " << mRequestedTextureDepth << LL_ENDL;
+ }
+ }
+ }
+
+
+ // Size change has been requested but not initiated yet.
+ size_t newsize = mRequestedTextureWidth * mRequestedTextureHeight * mRequestedTextureDepth;
+
+ // Add an extra line for padding, just in case.
+ newsize += mRequestedTextureWidth * mRequestedTextureDepth;
+
+ if(newsize != mTextureSharedMemorySize)
+ {
+ if(!mTextureSharedMemoryName.empty())
+ {
+ // Tell the plugin to remove the old memory segment
+ mPlugin->removeSharedMemory(mTextureSharedMemoryName);
+ mTextureSharedMemoryName.clear();
+ }
+
+ mTextureSharedMemorySize = newsize;
+ mTextureSharedMemoryName = mPlugin->addSharedMemory(mTextureSharedMemorySize);
+ if(!mTextureSharedMemoryName.empty())
+ {
+ void *addr = mPlugin->getSharedMemoryAddress(mTextureSharedMemoryName);
+
+ // clear texture memory to avoid random screen visual fuzz from uninitialized texture data
+ memset( addr, 0x00, newsize );
+
+ // We could do this to force an update, but textureValid() will still be returning false until the first roundtrip to the plugin,
+ // so it may not be worthwhile.
+ // mDirtyRect.setOriginAndSize(0, 0, mRequestedMediaWidth, mRequestedMediaHeight);
+ }
+ }
+
+ // This is our local indicator that a change is in progress.
+ mTextureWidth = -1;
+ mTextureHeight = -1;
+ mMediaWidth = -1;
+ mMediaHeight = -1;
+
+ // This invalidates any existing dirty rect.
+ resetDirty();
+
+ // Send a size change message to the plugin
+ {
+ LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "size_change");
+ message.setValue("name", mTextureSharedMemoryName);
+ message.setValueS32("width", mRequestedMediaWidth);
+ message.setValueS32("height", mRequestedMediaHeight);
+ message.setValueS32("texture_width", mRequestedTextureWidth);
+ message.setValueS32("texture_height", mRequestedTextureHeight);
+ mPlugin->sendMessage(message); // DO NOT just use sendMessage() here -- we want this to jump ahead of the queue.
+
+ LL_DEBUGS("Plugin") << "Sending size_change" << LL_ENDL;
+ }
+ }
+
+ if(mPlugin && mPlugin->isRunning())
+ {
+ // Send queued messages
+ while(!mSendQueue.empty())
+ {
+ LLPluginMessage message = mSendQueue.front();
+ mSendQueue.pop();
+ mPlugin->sendMessage(message);
+ }
+ }
+}
+
+int LLPluginClassMedia::getTextureWidth() const
+{
+ return nextPowerOf2(mTextureWidth);
+}
+
+int LLPluginClassMedia::getTextureHeight() const
+{
+ return nextPowerOf2(mTextureHeight);
+}
+
+unsigned char* LLPluginClassMedia::getBitsData()
+{
+ unsigned char *result = NULL;
+ if((mPlugin != NULL) && !mTextureSharedMemoryName.empty())
+ {
+ result = (unsigned char*)mPlugin->getSharedMemoryAddress(mTextureSharedMemoryName);
+ }
+ return result;
+}
+
+void LLPluginClassMedia::setSize(int width, int height)
+{
+ mSetMediaWidth = width;
+ mSetMediaHeight = height;
+
+ setSizeInternal();
+}
+
+void LLPluginClassMedia::setSizeInternal(void)
+{
+ if((mSetMediaWidth > 0) && (mSetMediaHeight > 0))
+ {
+ mRequestedMediaWidth = mSetMediaWidth;
+ mRequestedMediaHeight = mSetMediaHeight;
+ }
+ else
+ {
+ mRequestedMediaWidth = mDefaultMediaWidth;
+ mRequestedMediaHeight = mDefaultMediaHeight;
+ }
+
+ if(mAllowDownsample)
+ {
+ switch(mPriority)
+ {
+ case PRIORITY_LOW:
+ // Reduce maximum texture dimension to (or below) mLowPrioritySizeLimit
+ while((mRequestedMediaWidth > mLowPrioritySizeLimit) || (mRequestedMediaHeight > mLowPrioritySizeLimit))
+ {
+ mRequestedMediaWidth /= 2;
+ mRequestedMediaHeight /= 2;
+ }
+ break;
+
+ default:
+ // Don't adjust texture size
+ break;
+ }
+ }
+
+ if(mAutoScaleMedia)
+ {
+ mRequestedMediaWidth = nextPowerOf2(mRequestedMediaWidth);
+ mRequestedMediaHeight = nextPowerOf2(mRequestedMediaHeight);
+ }
+}
+
+void LLPluginClassMedia::setAutoScale(bool auto_scale)
+{
+ if(auto_scale != mAutoScaleMedia)
+ {
+ mAutoScaleMedia = auto_scale;
+ setSizeInternal();
+ }
+}
+
+bool LLPluginClassMedia::textureValid(void)
+{
+ if(
+ !mTextureParamsReceived ||
+ mTextureWidth <= 0 ||
+ mTextureHeight <= 0 ||
+ mMediaWidth <= 0 ||
+ mMediaHeight <= 0 ||
+ mRequestedMediaWidth != mMediaWidth ||
+ mRequestedMediaHeight != mMediaHeight ||
+ getBitsData() == NULL
+ )
+ return false;
+
+ return true;
+}
+
+bool LLPluginClassMedia::getDirty(LLRect *dirty_rect)
+{
+ bool result = !mDirtyRect.isEmpty();
+
+ if(dirty_rect != NULL)
+ {
+ *dirty_rect = mDirtyRect;
+ }
+
+ return result;
+}
+
+void LLPluginClassMedia::resetDirty(void)
+{
+ mDirtyRect = LLRect::null;
+}
+
+std::string LLPluginClassMedia::translateModifiers(MASK modifiers)
+{
+ std::string result;
+
+
+ if(modifiers & MASK_CONTROL)
+ {
+ result += "control|";
+ }
+
+ if(modifiers & MASK_ALT)
+ {
+ result += "alt|";
+ }
+
+ if(modifiers & MASK_SHIFT)
+ {
+ result += "shift|";
+ }
+
+ // TODO: should I deal with platform differences here or in callers?
+ // TODO: how do we deal with the Mac "command" key?
+/*
+ if(modifiers & MASK_SOMETHING)
+ {
+ result += "meta|";
+ }
+*/
+ return result;
+}
+
+void LLPluginClassMedia::mouseEvent(EMouseEventType type, int x, int y, MASK modifiers)
+{
+ LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "mouse_event");
+ std::string temp;
+ switch(type)
+ {
+ case MOUSE_EVENT_DOWN: temp = "down"; break;
+ case MOUSE_EVENT_UP: temp = "up"; break;
+ case MOUSE_EVENT_MOVE: temp = "move"; break;
+ case MOUSE_EVENT_DOUBLE_CLICK: temp = "double_click"; break;
+ }
+ message.setValue("event", temp);
+
+ message.setValueS32("x", x);
+
+ // Incoming coordinates are OpenGL-style ((0,0) = lower left), so flip them here if the plugin has requested it.
+ if(!mRequestedTextureCoordsOpenGL)
+ {
+ // TODO: Should I use mMediaHeight or mRequestedMediaHeight here?
+ y = mMediaHeight - y;
+ }
+ message.setValueS32("y", y);
+
+ message.setValue("modifiers", translateModifiers(modifiers));
+
+ sendMessage(message);
+}
+
+bool LLPluginClassMedia::keyEvent(EKeyEventType type, int key_code, MASK modifiers)
+{
+ bool result = true;
+
+ // FIXME:
+ // HACK: we don't have an easy way to tell if the plugin is going to handle a particular keycode.
+ // For now, return false for the ones the webkit plugin won't handle properly.
+
+ switch(key_code)
+ {
+ case KEY_BACKSPACE:
+ case KEY_TAB:
+ case KEY_RETURN:
+ case KEY_PAD_RETURN:
+ case KEY_SHIFT:
+ case KEY_CONTROL:
+ case KEY_ALT:
+ case KEY_CAPSLOCK:
+ case KEY_ESCAPE:
+ case KEY_PAGE_UP:
+ case KEY_PAGE_DOWN:
+ case KEY_END:
+ case KEY_HOME:
+ case KEY_LEFT:
+ case KEY_UP:
+ case KEY_RIGHT:
+ case KEY_DOWN:
+ case KEY_INSERT:
+ case KEY_DELETE:
+ // These will be handled
+ break;
+
+ default:
+ // regular ASCII characters will also be handled
+ if(key_code >= KEY_SPECIAL)
+ {
+ // Other "special" codes will not work properly.
+ result = false;
+ }
+ break;
+ }
+
+ if(result)
+ {
+ LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "key_event");
+ std::string temp;
+ switch(type)
+ {
+ case KEY_EVENT_DOWN: temp = "down"; break;
+ case KEY_EVENT_UP: temp = "up"; break;
+ case KEY_EVENT_REPEAT: temp = "repeat"; break;
+ }
+ message.setValue("event", temp);
+
+ message.setValueS32("key", key_code);
+
+ message.setValue("modifiers", translateModifiers(modifiers));
+
+ sendMessage(message);
+ }
+
+ return result;
+}
+
+void LLPluginClassMedia::scrollEvent(int x, int y, MASK modifiers)
+{
+ LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "scroll_event");
+
+ message.setValueS32("x", x);
+ message.setValueS32("y", y);
+ message.setValue("modifiers", translateModifiers(modifiers));
+
+ sendMessage(message);
+}
+
+bool LLPluginClassMedia::textInput(const std::string &text)
+{
+ LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "text_event");
+
+ message.setValue("text", text);
+
+ sendMessage(message);
+
+ return true;
+}
+
+void LLPluginClassMedia::loadURI(const std::string &uri)
+{
+ LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "load_uri");
+
+ message.setValue("uri", uri);
+
+ sendMessage(message);
+}
+
+void LLPluginClassMedia::setPriority(EPriority priority)
+{
+ if(mPriority != priority)
+ {
+ mPriority = priority;
+
+ LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "set_priority");
+
+ std::string priority_string;
+ switch(priority)
+ {
+ case PRIORITY_STOPPED:
+ priority_string = "stopped";
+ mSleepTime = 1.0f;
+ break;
+ case PRIORITY_HIDDEN:
+ priority_string = "hidden";
+ mSleepTime = 1.0f;
+ break;
+ case PRIORITY_LOW:
+ priority_string = "low";
+ mSleepTime = 1.0f / 50.0f;
+ break;
+ case PRIORITY_NORMAL:
+ priority_string = "normal";
+ mSleepTime = 1.0f / 100.0f;
+ break;
+ case PRIORITY_HIGH:
+ priority_string = "high";
+ mSleepTime = 1.0f / 100.0f;
+ break;
+ }
+
+ message.setValue("priority", priority_string);
+
+ sendMessage(message);
+
+ if(mPlugin)
+ {
+ mPlugin->setSleepTime(mSleepTime);
+ }
+
+ // This may affect the calculated size, so recalculate it here.
+ setSizeInternal();
+ }
+}
+
+void LLPluginClassMedia::setLowPrioritySizeLimit(int size)
+{
+ if(mLowPrioritySizeLimit != size)
+ {
+ mLowPrioritySizeLimit = size;
+
+ // This may affect the calculated size, so recalculate it here.
+ setSizeInternal();
+ }
+}
+
+
+void LLPluginClassMedia::cut()
+{
+ LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "edit_cut");
+ sendMessage(message);
+}
+
+void LLPluginClassMedia::copy()
+{
+ LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "edit_copy");
+ sendMessage(message);
+}
+
+void LLPluginClassMedia::paste()
+{
+ LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "edit_paste");
+ sendMessage(message);
+}
+
+/* virtual */
+void LLPluginClassMedia::receivePluginMessage(const LLPluginMessage &message)
+{
+ std::string message_class = message.getClass();
+
+ if(message_class == LLPLUGIN_MESSAGE_CLASS_MEDIA)
+ {
+ std::string message_name = message.getName();
+ if(message_name == "texture_params")
+ {
+ mRequestedTextureDepth = message.getValueS32("depth");
+ mRequestedTextureInternalFormat = message.getValueU32("internalformat");
+ mRequestedTextureFormat = message.getValueU32("format");
+ mRequestedTextureType = message.getValueU32("type");
+ mRequestedTextureSwapBytes = message.getValueBoolean("swap_bytes");
+ mRequestedTextureCoordsOpenGL = message.getValueBoolean("coords_opengl");
+
+ // These two are optional, and will default to 0 if they're not specified.
+ mDefaultMediaWidth = message.getValueS32("default_width");
+ mDefaultMediaHeight = message.getValueS32("default_height");
+
+ mAllowDownsample = message.getValueBoolean("allow_downsample");
+ mPadding = message.getValueS32("padding");
+
+ setSizeInternal();
+
+ mTextureParamsReceived = true;
+ }
+ else if(message_name == "updated")
+ {
+ if(message.hasValue("left"))
+ {
+ LLRect newDirtyRect;
+ newDirtyRect.mLeft = message.getValueS32("left");
+ newDirtyRect.mTop = message.getValueS32("top");
+ newDirtyRect.mRight = message.getValueS32("right");
+ newDirtyRect.mBottom = message.getValueS32("bottom");
+
+ // The plugin is likely to have top and bottom switched, due to vertical flip and OpenGL coordinate confusion.
+ // If they're backwards, swap them.
+ if(newDirtyRect.mTop < newDirtyRect.mBottom)
+ {
+ S32 temp = newDirtyRect.mTop;
+ newDirtyRect.mTop = newDirtyRect.mBottom;
+ newDirtyRect.mBottom = temp;
+ }
+
+ if(mDirtyRect.isEmpty())
+ {
+ mDirtyRect = newDirtyRect;
+ }
+ else
+ {
+ mDirtyRect.unionWith(newDirtyRect);
+ }
+
+ LL_DEBUGS("Plugin") << "adjusted incoming rect is: ("
+ << newDirtyRect.mLeft << ", "
+ << newDirtyRect.mTop << ", "
+ << newDirtyRect.mRight << ", "
+ << newDirtyRect.mBottom << "), new dirty rect is: ("
+ << mDirtyRect.mLeft << ", "
+ << mDirtyRect.mTop << ", "
+ << mDirtyRect.mRight << ", "
+ << mDirtyRect.mBottom << ")"
+ << LL_ENDL;
+
+ mediaEvent(LLPluginClassMediaOwner::MEDIA_EVENT_CONTENT_UPDATED);
+ }
+
+
+ bool time_duration_updated = false;
+
+ if(message.hasValue("current_time"))
+ {
+ mCurrentTime = message.getValueReal("current_time");
+ time_duration_updated = true;
+ }
+ if(message.hasValue("duration"))
+ {
+ mDuration = message.getValueReal("duration");
+ time_duration_updated = true;
+ }
+
+ if(message.hasValue("current_rate"))
+ {
+ mCurrentRate = message.getValueReal("current_rate");
+ }
+
+ if(time_duration_updated)
+ {
+ mediaEvent(LLPluginClassMediaOwner::MEDIA_EVENT_TIME_DURATION_UPDATED);
+ }
+
+ }
+ else if(message_name == "media_status")
+ {
+ std::string status = message.getValue("status");
+
+ LL_DEBUGS("Plugin") << "Status changed to: " << status << LL_ENDL;
+
+ if(status == "loading")
+ {
+ mStatus = LLPluginClassMediaOwner::MEDIA_LOADING;
+ }
+ else if(status == "loaded")
+ {
+ mStatus = LLPluginClassMediaOwner::MEDIA_LOADED;
+ }
+ else if(status == "error")
+ {
+ mStatus = LLPluginClassMediaOwner::MEDIA_ERROR;
+ }
+ else if(status == "playing")
+ {
+ mStatus = LLPluginClassMediaOwner::MEDIA_PLAYING;
+ }
+ else if(status == "paused")
+ {
+ mStatus = LLPluginClassMediaOwner::MEDIA_PAUSED;
+ }
+ else
+ {
+ // empty string or any unknown string
+ mStatus = LLPluginClassMediaOwner::MEDIA_NONE;
+ }
+ }
+ else if(message_name == "size_change_request")
+ {
+ S32 width = message.getValueS32("width");
+ S32 height = message.getValueS32("height");
+ std::string name = message.getValue("name");
+
+ // TODO: check that name matches?
+ mNaturalMediaWidth = width;
+ mNaturalMediaHeight = height;
+
+ setSize(width, height);
+ }
+ else if(message_name == "size_change_response")
+ {
+ std::string name = message.getValue("name");
+
+ // TODO: check that name matches?
+
+ mTextureWidth = message.getValueS32("texture_width");
+ mTextureHeight = message.getValueS32("texture_height");
+ mMediaWidth = message.getValueS32("width");
+ mMediaHeight = message.getValueS32("height");
+
+ // This invalidates any existing dirty rect.
+ resetDirty();
+
+ // TODO: should we verify that the plugin sent back the right values?
+ // Two size changes in a row may cause them to not match, due to queueing, etc.
+
+ mediaEvent(LLPluginClassMediaOwner::MEDIA_EVENT_SIZE_CHANGED);
+ }
+ else if(message_name == "cursor_changed")
+ {
+ mCursorName = message.getValue("name");
+
+ mediaEvent(LLPluginClassMediaOwner::MEDIA_EVENT_CURSOR_CHANGED);
+ }
+ else if(message_name == "edit_state")
+ {
+ if(message.hasValue("cut"))
+ {
+ mCanCut = message.getValueBoolean("cut");
+ }
+ if(message.hasValue("copy"))
+ {
+ mCanCopy = message.getValueBoolean("copy");
+ }
+ if(message.hasValue("paste"))
+ {
+ mCanPaste = message.getValueBoolean("paste");
+ }
+ }
+ else
+ {
+ LL_WARNS("Plugin") << "Unknown " << message_name << " class message: " << message_name << LL_ENDL;
+ }
+ }
+ else if(message_class == LLPLUGIN_MESSAGE_CLASS_MEDIA_BROWSER)
+ {
+ std::string message_name = message.getName();
+ if(message_name == "navigate_begin")
+ {
+ mNavigateURI = message.getValue("uri");
+ mediaEvent(LLPluginClassMediaOwner::MEDIA_EVENT_NAVIGATE_BEGIN);
+ }
+ else if(message_name == "navigate_complete")
+ {
+ mNavigateURI = message.getValue("uri");
+ mNavigateResultCode = message.getValueS32("result_code");
+ mNavigateResultString = message.getValue("result_string");
+ mHistoryBackAvailable = message.getValueBoolean("history_back_available");
+ mHistoryForwardAvailable = message.getValueBoolean("history_forward_available");
+
+ mediaEvent(LLPluginClassMediaOwner::MEDIA_EVENT_NAVIGATE_COMPLETE);
+ }
+ else if(message_name == "progress")
+ {
+ mProgressPercent = message.getValueS32("percent");
+ mediaEvent(LLPluginClassMediaOwner::MEDIA_EVENT_PROGRESS_UPDATED);
+ }
+ else if(message_name == "status_text")
+ {
+ mStatusText = message.getValue("status");
+ mediaEvent(LLPluginClassMediaOwner::MEDIA_EVENT_STATUS_TEXT_CHANGED);
+ }
+ else if(message_name == "location_changed")
+ {
+ mLocation = message.getValue("uri");
+ mediaEvent(LLPluginClassMediaOwner::MEDIA_EVENT_LOCATION_CHANGED);
+ }
+ else if(message_name == "click_href")
+ {
+ mClickURL = message.getValue("uri");
+ mClickTarget = message.getValue("target");
+ mediaEvent(LLPluginClassMediaOwner::MEDIA_EVENT_CLICK_LINK_HREF);
+ }
+ else if(message_name == "click_nofollow")
+ {
+ mClickURL = message.getValue("uri");
+ mClickTarget.clear();
+ mediaEvent(LLPluginClassMediaOwner::MEDIA_EVENT_CLICK_LINK_NOFOLLOW);
+ }
+ else
+ {
+ LL_WARNS("Plugin") << "Unknown " << message_name << " class message: " << message_name << LL_ENDL;
+ }
+ }
+ else if(message_class == LLPLUGIN_MESSAGE_CLASS_MEDIA_TIME)
+ {
+ std::string message_name = message.getName();
+
+ // This class hasn't defined any incoming messages yet.
+// if(message_name == "message_name")
+// {
+// }
+// else
+ {
+ LL_WARNS("Plugin") << "Unknown " << message_name << " class message: " << message_name << LL_ENDL;
+ }
+ }
+
+}
+
+/* virtual */
+void LLPluginClassMedia::pluginDied()
+{
+ mediaEvent(LLPluginClassMediaOwner::MEDIA_EVENT_PLUGIN_FAILED);
+}
+
+void LLPluginClassMedia::mediaEvent(LLPluginClassMediaOwner::EMediaEvent event)
+{
+ if(mOwner)
+ {
+ mOwner->handleMediaEvent(this, event);
+ }
+}
+
+void LLPluginClassMedia::sendMessage(const LLPluginMessage &message)
+{
+ if(mPlugin && mPlugin->isRunning())
+ {
+ mPlugin->sendMessage(message);
+ }
+ else
+ {
+ // The plugin isn't set up yet -- queue this message to be sent after initialization.
+ mSendQueue.push(message);
+ }
+}
+
+////////////////////////////////////////////////////////////
+// MARK: media_browser class functions
+bool LLPluginClassMedia::pluginSupportsMediaBrowser(void)
+{
+ std::string version = mPlugin->getMessageClassVersion(LLPLUGIN_MESSAGE_CLASS_MEDIA_BROWSER);
+ return !version.empty();
+}
+
+void LLPluginClassMedia::focus(bool focused)
+{
+ LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA_BROWSER, "focus");
+
+ message.setValueBoolean("focused", focused);
+
+ sendMessage(message);
+}
+
+void LLPluginClassMedia::clear_cache()
+{
+ LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA_BROWSER, "clear_cache");
+ sendMessage(message);
+}
+
+void LLPluginClassMedia::clear_cookies()
+{
+ LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA_BROWSER, "clear_cookies");
+ sendMessage(message);
+}
+
+void LLPluginClassMedia::enable_cookies(bool enable)
+{
+ LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA_BROWSER, "enable_cookies");
+ sendMessage(message);
+}
+
+void LLPluginClassMedia::proxy_setup(bool enable, const std::string &host, int port)
+{
+ LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA_BROWSER, "proxy_setup");
+
+ message.setValueBoolean("enable", enable);
+ message.setValue("host", host);
+ message.setValueS32("port", port);
+
+ sendMessage(message);
+}
+
+void LLPluginClassMedia::browse_stop()
+{
+ LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA_BROWSER, "browse_stop");
+ sendMessage(message);
+}
+
+void LLPluginClassMedia::browse_reload(bool ignore_cache)
+{
+ LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA_BROWSER, "browse_reload");
+
+ message.setValueBoolean("ignore_cache", ignore_cache);
+
+ sendMessage(message);
+}
+
+void LLPluginClassMedia::browse_forward()
+{
+ LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA_BROWSER, "browse_forward");
+ sendMessage(message);
+}
+
+void LLPluginClassMedia::browse_back()
+{
+ LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA_BROWSER, "browse_back");
+ sendMessage(message);
+}
+
+void LLPluginClassMedia::set_status_redirect(int code, const std::string &url)
+{
+ LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA_BROWSER, "set_status_redirect");
+
+ message.setValueS32("code", code);
+ message.setValue("url", url);
+
+ sendMessage(message);
+}
+
+void LLPluginClassMedia::setBrowserUserAgent(const std::string& user_agent)
+{
+ LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA_BROWSER, "set_user_agent");
+
+ message.setValue("user_agent", user_agent);
+
+ sendMessage(message);
+}
+
+void LLPluginClassMedia::crashPlugin()
+{
+ LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_INTERNAL, "crash");
+
+ sendMessage(message);
+}
+
+void LLPluginClassMedia::hangPlugin()
+{
+ LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_INTERNAL, "hang");
+
+ sendMessage(message);
+}
+
+
+////////////////////////////////////////////////////////////
+// MARK: media_time class functions
+bool LLPluginClassMedia::pluginSupportsMediaTime(void)
+{
+ std::string version = mPlugin->getMessageClassVersion(LLPLUGIN_MESSAGE_CLASS_MEDIA_TIME);
+ return !version.empty();
+}
+
+void LLPluginClassMedia::stop()
+{
+ LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA_TIME, "stop");
+ sendMessage(message);
+}
+
+void LLPluginClassMedia::start(float rate)
+{
+ LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA_TIME, "start");
+
+ message.setValueReal("rate", rate);
+
+ sendMessage(message);
+}
+
+void LLPluginClassMedia::pause()
+{
+ LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA_TIME, "pause");
+ sendMessage(message);
+}
+
+void LLPluginClassMedia::seek(float time)
+{
+ LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA_TIME, "seek");
+
+ message.setValueReal("time", time);
+
+ sendMessage(message);
+}
+
+void LLPluginClassMedia::setLoop(bool loop)
+{
+ LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA_TIME, "set_loop");
+
+ message.setValueBoolean("loop", loop);
+
+ sendMessage(message);
+}
+
+void LLPluginClassMedia::setVolume(float volume)
+{
+ if(volume != mRequestedVolume)
+ {
+ mRequestedVolume = volume;
+
+ LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA_TIME, "set_volume");
+
+ message.setValueReal("volume", volume);
+
+ sendMessage(message);
+ }
+}
+
+void LLPluginClassMedia::initializeUrlHistory(const LLSD& url_history)
+{
+ // Send URL history to plugin
+ LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA_BROWSER, "init_history");
+ message.setValueLLSD("history", url_history);
+ sendMessage(message);
+
+ LL_DEBUGS("Plugin") << "Sending history" << LL_ENDL;
+}
+
diff --git a/indra/llplugin/llpluginclassmedia.h b/indra/llplugin/llpluginclassmedia.h
new file mode 100644
index 0000000000..7a8586fe2f
--- /dev/null
+++ b/indra/llplugin/llpluginclassmedia.h
@@ -0,0 +1,333 @@
+/**
+ * @file llpluginclassmedia.h
+ * @brief LLPluginClassMedia handles interaction with a plugin which knows about the "media" message class.
+ *
+ * $LicenseInfo:firstyear=2008&license=viewergpl$
+ *
+ * Copyright (c) 2008, Linden Research, Inc.
+ *
+ * Second Life Viewer Source Code
+ * The source code in this file ("Source Code") is provided by Linden Lab
+ * to you under the terms of the GNU General Public License, version 2.0
+ * ("GPL"), unless you have obtained a separate licensing agreement
+ * ("Other License"), formally executed by you and Linden Lab. Terms of
+ * the GPL can be found in doc/GPL-license.txt in this distribution, or
+ * online at http://secondlife.com/developers/opensource/gplv2
+ *
+ * There are special exceptions to the terms and conditions of the GPL as
+ * it is applied to this Source Code. View the full text of the exception
+ * in the file doc/FLOSS-exception.txt in this software distribution, or
+ * online at http://secondlife.com/developers/opensource/flossexception
+ *
+ * By copying, modifying or distributing this software, you acknowledge
+ * that you have read and understood your obligations described above,
+ * and agree to abide by those obligations.
+ *
+ * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+ * COMPLETENESS OR PERFORMANCE.
+ * $/LicenseInfo$
+ */
+
+#ifndef LL_LLPLUGINCLASSMEDIA_H
+#define LL_LLPLUGINCLASSMEDIA_H
+
+#include "llgl.h"
+#include "llpluginprocessparent.h"
+#include "llrect.h"
+#include "llpluginclassmediaowner.h"
+#include <queue>
+
+
+class LLPluginClassMedia : public LLPluginProcessParentOwner
+{
+ LOG_CLASS(LLPluginClassMedia);
+public:
+ LLPluginClassMedia(LLPluginClassMediaOwner *owner);
+ virtual ~LLPluginClassMedia();
+
+ // local initialization, called by the media manager when creating a source
+ virtual bool init(const std::string &launcher_filename, const std::string &plugin_filename);
+
+ // undoes everything init() didm called by the media manager when destroying a source
+ virtual void reset();
+
+ void idle(void);
+
+ // All of these may return 0 or an actual valid value.
+ // Callers need to check the return for 0, and not use the values in that case.
+ int getWidth() const { return (mMediaWidth > 0) ? mMediaWidth : 0; };
+ int getHeight() const { return (mMediaHeight > 0) ? mMediaHeight : 0; };
+ int getNaturalWidth() const { return mNaturalMediaWidth; };
+ int getNaturalHeight() const { return mNaturalMediaHeight; };
+ int getSetWidth() const { return mSetMediaWidth; };
+ int getSetHeight() const { return mSetMediaHeight; };
+ int getBitsWidth() const { return (mTextureWidth > 0) ? mTextureWidth : 0; };
+ int getBitsHeight() const { return (mTextureHeight > 0) ? mTextureHeight : 0; };
+ int getTextureWidth() const;
+ int getTextureHeight() const;
+
+ // This may return NULL. Callers need to check for and handle this case.
+ unsigned char* getBitsData();
+
+ // gets the format details of the texture data
+ // These may return 0 if they haven't been set up yet. The caller needs to detect this case.
+ int getTextureDepth() const { return mRequestedTextureDepth; };
+ int getTextureFormatInternal() const { return mRequestedTextureInternalFormat; };
+ int getTextureFormatPrimary() const { return mRequestedTextureFormat; };
+ int getTextureFormatType() const { return mRequestedTextureType; };
+ bool getTextureFormatSwapBytes() const { return mRequestedTextureSwapBytes; };
+ bool getTextureCoordsOpenGL() const { return mRequestedTextureCoordsOpenGL; };
+
+ void setSize(int width, int height);
+ void setAutoScale(bool auto_scale);
+
+ // Returns true if all of the texture parameters (depth, format, size, and texture size) are set up and consistent.
+ // This will initially be false, and will also be false for some time after setSize while the resize is processed.
+ // Note that if this returns true, it is safe to use all the get() functions above without checking for invalid return values
+ // until you call idle() again.
+ bool textureValid(void);
+
+ bool getDirty(LLRect *dirty_rect = NULL);
+ void resetDirty(void);
+
+ typedef enum
+ {
+ MOUSE_EVENT_DOWN,
+ MOUSE_EVENT_UP,
+ MOUSE_EVENT_MOVE,
+ MOUSE_EVENT_DOUBLE_CLICK
+ }EMouseEventType;
+
+ void mouseEvent(EMouseEventType type, int x, int y, MASK modifiers);
+
+ typedef enum
+ {
+ KEY_EVENT_DOWN,
+ KEY_EVENT_UP,
+ KEY_EVENT_REPEAT
+ }EKeyEventType;
+
+ bool keyEvent(EKeyEventType type, int key_code, MASK modifiers);
+
+ void scrollEvent(int x, int y, MASK modifiers);
+
+ // Text may be unicode (utf8 encoded)
+ bool textInput(const std::string &text);
+
+ void loadURI(const std::string &uri);
+
+ // "Loading" means uninitialized or any state prior to fully running (processing commands)
+ bool isPluginLoading(void) { return mPlugin?mPlugin->isLoading():false; };
+
+ // "Running" means the steady state -- i.e. processing messages
+ bool isPluginRunning(void) { return mPlugin?mPlugin->isRunning():false; };
+
+ // "Exited" means any regular or error state after "Running" (plugin may have crashed or exited normally)
+ bool isPluginExited(void) { return mPlugin?mPlugin->isDone():false; };
+
+ std::string getPluginVersion() { return mPlugin?mPlugin->getPluginVersion():std::string(""); };
+
+ bool getDisableTimeout() { return mPlugin?mPlugin->getDisableTimeout():false; };
+ void setDisableTimeout(bool disable) { if(mPlugin) mPlugin->setDisableTimeout(disable); };
+
+ // Inherited from LLPluginProcessParentOwner
+ /* virtual */ void receivePluginMessage(const LLPluginMessage &message);
+ /* virtual */ void pluginDied();
+
+
+ typedef enum
+ {
+ PRIORITY_STOPPED, // media is not playing, shouldn't need to update at all.
+ PRIORITY_HIDDEN, // media is not being displayed or is out of view, don't need to do graphic updates, but may still update audio, playhead, etc.
+ PRIORITY_LOW, // media is in the far distance, may be rendered at reduced size
+ PRIORITY_NORMAL, // normal (default) priority
+ PRIORITY_HIGH // media has user focus and/or is taking up most of the screen
+ }EPriority;
+
+ void setPriority(EPriority priority);
+ void setLowPrioritySizeLimit(int size);
+
+ // Valid after a MEDIA_EVENT_CURSOR_CHANGED event
+ std::string getCursorName() const { return mCursorName; };
+
+ LLPluginClassMediaOwner::EMediaStatus getStatus() const { return mStatus; }
+
+ void cut();
+ bool canCut() const { return mCanCut; };
+
+ void copy();
+ bool canCopy() const { return mCanCopy; };
+
+ void paste();
+ bool canPaste() const { return mCanPaste; };
+
+ ///////////////////////////////////
+ // media browser class functions
+ bool pluginSupportsMediaBrowser(void);
+
+ void focus(bool focused);
+ void clear_cache();
+ void clear_cookies();
+ void enable_cookies(bool enable);
+ void proxy_setup(bool enable, const std::string &host = LLStringUtil::null, int port = 0);
+ void browse_stop();
+ void browse_reload(bool ignore_cache = false);
+ void browse_forward();
+ void browse_back();
+ void set_status_redirect(int code, const std::string &url);
+ void setBrowserUserAgent(const std::string& user_agent);
+
+ // This is valid after MEDIA_EVENT_NAVIGATE_BEGIN or MEDIA_EVENT_NAVIGATE_COMPLETE
+ std::string getNavigateURI() const { return mNavigateURI; };
+
+ // These are valid after MEDIA_EVENT_NAVIGATE_COMPLETE
+ S32 getNavigateResultCode() const { return mNavigateResultCode; };
+ std::string getNavigateResultString() const { return mNavigateResultString; };
+ bool getHistoryBackAvailable() const { return mHistoryBackAvailable; };
+ bool getHistoryForwardAvailable() const { return mHistoryForwardAvailable; };
+
+ // This is valid after MEDIA_EVENT_PROGRESS_UPDATED
+ int getProgressPercent() const { return mProgressPercent; };
+
+ // This is valid after MEDIA_EVENT_STATUS_TEXT_CHANGED
+ std::string getStatusText() const { return mStatusText; };
+
+ // This is valid after MEDIA_EVENT_LOCATION_CHANGED
+ std::string getLocation() const { return mLocation; };
+
+ // This is valid after MEDIA_EVENT_CLICK_LINK_HREF or MEDIA_EVENT_CLICK_LINK_NOFOLLOW
+ std::string getClickURL() const { return mClickURL; };
+
+ // This is valid after MEDIA_EVENT_CLICK_LINK_HREF
+ std::string getClickTarget() const { return mClickTarget; };
+
+ std::string getMediaName() const { return mMediaName; };
+ std::string getMediaDescription() const { return mMediaDescription; };
+
+ // Crash the plugin. If you use this outside of a testbed, you will be punished.
+ void crashPlugin();
+
+ // Hang the plugin. If you use this outside of a testbed, you will be punished.
+ void hangPlugin();
+
+ ///////////////////////////////////
+ // media time class functions
+ bool pluginSupportsMediaTime(void);
+ void stop();
+ void start(float rate = 0.0f);
+ void pause();
+ void seek(float time);
+ void setLoop(bool loop);
+ void setVolume(float volume);
+
+ F64 getCurrentTime(void) const { return mCurrentTime; };
+ F64 getDuration(void) const { return mDuration; };
+ F64 getCurrentPlayRate(void) { return mCurrentRate; };
+
+ // Initialize the URL history of the plugin by sending
+ // "init_history" message
+ void initializeUrlHistory(const LLSD& url_history);
+
+protected:
+ LLPluginClassMediaOwner *mOwner;
+
+ // Notify this object's owner that an event has occurred.
+ void mediaEvent(LLPluginClassMediaOwner::EMediaEvent event);
+
+ void sendMessage(const LLPluginMessage &message); // Send message internally, either queueing or sending directly.
+ std::queue<LLPluginMessage> mSendQueue; // Used to queue messages while the plugin initializes.
+
+ void setSizeInternal(void);
+
+ bool mTextureParamsReceived; // the mRequestedTexture* fields are only valid when this is true
+ S32 mRequestedTextureDepth;
+ LLGLenum mRequestedTextureInternalFormat;
+ LLGLenum mRequestedTextureFormat;
+ LLGLenum mRequestedTextureType;
+ bool mRequestedTextureSwapBytes;
+ bool mRequestedTextureCoordsOpenGL;
+
+ std::string mTextureSharedMemoryName;
+ size_t mTextureSharedMemorySize;
+
+ // True to scale requested media up to the full size of the texture (i.e. next power of two)
+ bool mAutoScaleMedia;
+
+ // default media size for the plugin, from the texture_params message.
+ int mDefaultMediaWidth;
+ int mDefaultMediaHeight;
+
+ // Size that has been requested by the plugin itself
+ int mNaturalMediaWidth;
+ int mNaturalMediaHeight;
+
+ // Size that has been requested with setSize()
+ int mSetMediaWidth;
+ int mSetMediaHeight;
+
+ // Actual media size being set (may be affected by auto-scale)
+ int mRequestedMediaWidth;
+ int mRequestedMediaHeight;
+
+ // Texture size calculated from actual media size
+ int mRequestedTextureWidth;
+ int mRequestedTextureHeight;
+
+ // Size that the plugin has acknowledged
+ int mTextureWidth;
+ int mTextureHeight;
+ int mMediaWidth;
+ int mMediaHeight;
+
+ float mRequestedVolume;
+
+ // Priority of this media stream
+ EPriority mPriority;
+ int mLowPrioritySizeLimit;
+
+ bool mAllowDownsample;
+ int mPadding;
+
+
+ LLPluginProcessParent *mPlugin;
+
+ LLRect mDirtyRect;
+
+ std::string translateModifiers(MASK modifiers);
+
+ std::string mCursorName;
+
+ LLPluginClassMediaOwner::EMediaStatus mStatus;
+
+ F64 mSleepTime;
+
+ bool mCanCut;
+ bool mCanCopy;
+ bool mCanPaste;
+
+ std::string mMediaName;
+ std::string mMediaDescription;
+
+ /////////////////////////////////////////
+ // media_browser class
+ std::string mNavigateURI;
+ S32 mNavigateResultCode;
+ std::string mNavigateResultString;
+ bool mHistoryBackAvailable;
+ bool mHistoryForwardAvailable;
+ std::string mStatusText;
+ int mProgressPercent;
+ std::string mLocation;
+ std::string mClickURL;
+ std::string mClickTarget;
+
+ /////////////////////////////////////////
+ // media_time class
+ F64 mCurrentTime;
+ F64 mDuration;
+ F64 mCurrentRate;
+
+};
+
+#endif // LL_LLPLUGINCLASSMEDIA_H
diff --git a/indra/llplugin/llpluginclassmediaowner.h b/indra/llplugin/llpluginclassmediaowner.h
new file mode 100644
index 0000000000..3ae176cbeb
--- /dev/null
+++ b/indra/llplugin/llpluginclassmediaowner.h
@@ -0,0 +1,79 @@
+/**
+ * @file llpluginclassmediaowner.h
+ * @brief LLPluginClassMedia handles interaction with a plugin which knows about the "media" message class.
+ *
+ * $LicenseInfo:firstyear=2008&license=viewergpl$
+ *
+ * Copyright (c) 2008, Linden Research, Inc.
+ *
+ * Second Life Viewer Source Code
+ * The source code in this file ("Source Code") is provided by Linden Lab
+ * to you under the terms of the GNU General Public License, version 2.0
+ * ("GPL"), unless you have obtained a separate licensing agreement
+ * ("Other License"), formally executed by you and Linden Lab. Terms of
+ * the GPL can be found in doc/GPL-license.txt in this distribution, or
+ * online at http://secondlife.com/developers/opensource/gplv2
+ *
+ * There are special exceptions to the terms and conditions of the GPL as
+ * it is applied to this Source Code. View the full text of the exception
+ * in the file doc/FLOSS-exception.txt in this software distribution, or
+ * online at http://secondlife.com/developers/opensource/flossexception
+ *
+ * By copying, modifying or distributing this software, you acknowledge
+ * that you have read and understood your obligations described above,
+ * and agree to abide by those obligations.
+ *
+ * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+ * COMPLETENESS OR PERFORMANCE.
+ * $/LicenseInfo$
+ */
+
+#ifndef LL_LLPLUGINCLASSMEDIAOWNER_H
+#define LL_LLPLUGINCLASSMEDIAOWNER_H
+
+#include "llgl.h"
+#include "llpluginprocessparent.h"
+#include "llrect.h"
+#include <queue>
+
+class LLPluginClassMedia;
+
+class LLPluginClassMediaOwner
+{
+public:
+ typedef enum
+ {
+ MEDIA_EVENT_CONTENT_UPDATED, // contents/dirty rect have updated
+ MEDIA_EVENT_TIME_DURATION_UPDATED, // current time and/or duration have updated
+ MEDIA_EVENT_SIZE_CHANGED, // media size has changed
+ MEDIA_EVENT_CURSOR_CHANGED, // plugin has requested a cursor change
+
+ MEDIA_EVENT_NAVIGATE_BEGIN, // browser has begun navigation
+ MEDIA_EVENT_NAVIGATE_COMPLETE, // browser has finished navigation
+ MEDIA_EVENT_PROGRESS_UPDATED, // browser has updated loading progress
+ MEDIA_EVENT_STATUS_TEXT_CHANGED, // browser has updated the status text
+ MEDIA_EVENT_LOCATION_CHANGED, // browser location (URL) has changed (maybe due to internal navagation/frames/etc)
+ MEDIA_EVENT_CLICK_LINK_HREF, // I'm not entirely sure what the semantics of these two are
+ MEDIA_EVENT_CLICK_LINK_NOFOLLOW,
+
+ MEDIA_EVENT_PLUGIN_FAILED // The plugin failed to launch or died unexpectedly
+
+ } EMediaEvent;
+
+ typedef enum
+ {
+ MEDIA_NONE, // Uninitialized -- no useful state
+ MEDIA_LOADING, // loading or navigating
+ MEDIA_LOADED, // navigation/preroll complete
+ MEDIA_ERROR, // navigation/preroll failed
+ MEDIA_PLAYING, // playing (only for time-based media)
+ MEDIA_PAUSED, // paused (only for time-based media)
+
+ } EMediaStatus;
+
+ virtual ~LLPluginClassMediaOwner() {};
+ virtual void handleMediaEvent(LLPluginClassMedia* /*self*/, EMediaEvent /*event*/) {};
+};
+
+#endif // LL_LLPLUGINCLASSMEDIAOWNER_H
diff --git a/indra/llplugin/llplugininstance.cpp b/indra/llplugin/llplugininstance.cpp
new file mode 100644
index 0000000000..58fb792d0d
--- /dev/null
+++ b/indra/llplugin/llplugininstance.cpp
@@ -0,0 +1,140 @@
+/**
+ * @file llplugininstance.cpp
+ * @brief LLPluginInstance handles loading the dynamic library of a plugin and setting up its entry points for message passing.
+ *
+ * $LicenseInfo:firstyear=2008&license=viewergpl$
+ *
+ * Copyright (c) 2008, Linden Research, Inc.
+ *
+ * Second Life Viewer Source Code
+ * The source code in this file ("Source Code") is provided by Linden Lab
+ * to you under the terms of the GNU General Public License, version 2.0
+ * ("GPL"), unless you have obtained a separate licensing agreement
+ * ("Other License"), formally executed by you and Linden Lab. Terms of
+ * the GPL can be found in doc/GPL-license.txt in this distribution, or
+ * online at http://secondlife.com/developers/opensource/gplv2
+ *
+ * There are special exceptions to the terms and conditions of the GPL as
+ * it is applied to this Source Code. View the full text of the exception
+ * in the file doc/FLOSS-exception.txt in this software distribution, or
+ * online at http://secondlife.com/developers/opensource/flossexception
+ *
+ * By copying, modifying or distributing this software, you acknowledge
+ * that you have read and understood your obligations described above,
+ * and agree to abide by those obligations.
+ *
+ * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+ * COMPLETENESS OR PERFORMANCE.
+ * $/LicenseInfo$
+ */
+
+#include "linden_common.h"
+
+#include "llplugininstance.h"
+
+#include "llapr.h"
+
+//virtual
+LLPluginInstanceMessageListener::~LLPluginInstanceMessageListener()
+{
+}
+
+const char *LLPluginInstance::PLUGIN_INIT_FUNCTION_NAME = "LLPluginInitEntryPoint";
+
+LLPluginInstance::LLPluginInstance(LLPluginInstanceMessageListener *owner) :
+ mDSOHandle(NULL),
+ mPluginUserData(NULL),
+ mPluginSendMessageFunction(NULL)
+{
+ mOwner = owner;
+}
+
+LLPluginInstance::~LLPluginInstance()
+{
+ if(mDSOHandle != NULL)
+ {
+ apr_dso_unload(mDSOHandle);
+ mDSOHandle = NULL;
+ }
+}
+
+int LLPluginInstance::load(std::string &plugin_file)
+{
+ pluginInitFunction init_function = NULL;
+
+ int result = apr_dso_load(&mDSOHandle,
+ plugin_file.c_str(),
+ gAPRPoolp);
+ if(result != APR_SUCCESS)
+ {
+ char buf[1024];
+ apr_dso_error(mDSOHandle, buf, sizeof(buf));
+
+ LL_WARNS("Plugin") << "apr_dso_load of " << plugin_file << " failed with error " << result << " , additional info string: " << buf << LL_ENDL;
+
+ }
+
+ if(result == APR_SUCCESS)
+ {
+ result = apr_dso_sym((apr_dso_handle_sym_t*)&init_function,
+ mDSOHandle,
+ PLUGIN_INIT_FUNCTION_NAME);
+
+ if(result != APR_SUCCESS)
+ {
+ LL_WARNS("Plugin") << "apr_dso_sym failed with error " << result << LL_ENDL;
+ }
+ }
+
+ if(result == APR_SUCCESS)
+ {
+ result = init_function(staticReceiveMessage, (void*)this, &mPluginSendMessageFunction, &mPluginUserData);
+
+ if(result != APR_SUCCESS)
+ {
+ LL_WARNS("Plugin") << "call to init function failed with error " << result << LL_ENDL;
+ }
+ }
+
+ return (int)result;
+}
+
+void LLPluginInstance::sendMessage(const std::string &message)
+{
+ if(mPluginSendMessageFunction)
+ {
+ LL_DEBUGS("Plugin") << "sending message to plugin: \"" << message << "\"" << LL_ENDL;
+ mPluginSendMessageFunction(message.c_str(), &mPluginUserData);
+ }
+ else
+ {
+ LL_WARNS("Plugin") << "dropping message: \"" << message << "\"" << LL_ENDL;
+ }
+}
+
+void LLPluginInstance::idle(void)
+{
+}
+
+// static
+void LLPluginInstance::staticReceiveMessage(const char *message_string, void **user_data)
+{
+ // TODO: validate that the user_data argument is still a valid LLPluginInstance pointer
+ // we could also use a key that's looked up in a map (instead of a direct pointer) for safety, but that's probably overkill
+ LLPluginInstance *self = (LLPluginInstance*)*user_data;
+ self->receiveMessage(message_string);
+}
+
+void LLPluginInstance::receiveMessage(const char *message_string)
+{
+ if(mOwner)
+ {
+ LL_DEBUGS("Plugin") << "processing incoming message: \"" << message_string << "\"" << LL_ENDL;
+ mOwner->receivePluginMessage(message_string);
+ }
+ else
+ {
+ LL_WARNS("Plugin") << "dropping incoming message: \"" << message_string << "\"" << LL_ENDL;
+ }
+}
diff --git a/indra/llplugin/llplugininstance.h b/indra/llplugin/llplugininstance.h
new file mode 100644
index 0000000000..ba569df10c
--- /dev/null
+++ b/indra/llplugin/llplugininstance.h
@@ -0,0 +1,88 @@
+/**
+ * @file llplugininstance.h
+ * @brief LLPluginInstance handles loading the dynamic library of a plugin and setting up its entry points for message passing.
+ *
+ * $LicenseInfo:firstyear=2008&license=viewergpl$
+ *
+ * Copyright (c) 2008, Linden Research, Inc.
+ *
+ * Second Life Viewer Source Code
+ * The source code in this file ("Source Code") is provided by Linden Lab
+ * to you under the terms of the GNU General Public License, version 2.0
+ * ("GPL"), unless you have obtained a separate licensing agreement
+ * ("Other License"), formally executed by you and Linden Lab. Terms of
+ * the GPL can be found in doc/GPL-license.txt in this distribution, or
+ * online at http://secondlife.com/developers/opensource/gplv2
+ *
+ * There are special exceptions to the terms and conditions of the GPL as
+ * it is applied to this Source Code. View the full text of the exception
+ * in the file doc/FLOSS-exception.txt in this software distribution, or
+ * online at http://secondlife.com/developers/opensource/flossexception
+ *
+ * By copying, modifying or distributing this software, you acknowledge
+ * that you have read and understood your obligations described above,
+ * and agree to abide by those obligations.
+ *
+ * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+ * COMPLETENESS OR PERFORMANCE.
+ * $/LicenseInfo$
+ */
+
+#ifndef LL_LLPLUGININSTANCE_H
+#define LL_LLPLUGININSTANCE_H
+
+#include "llstring.h"
+#include "llapr.h"
+
+#include "apr_dso.h"
+
+class LLPluginInstanceMessageListener
+{
+public:
+ virtual ~LLPluginInstanceMessageListener();
+ virtual void receivePluginMessage(const std::string &message) = 0;
+};
+
+class LLPluginInstance
+{
+ LOG_CLASS(LLPluginInstance);
+public:
+ LLPluginInstance(LLPluginInstanceMessageListener *owner);
+ virtual ~LLPluginInstance();
+
+ // Load a plugin dll/dylib/so
+ // Returns 0 if successful, APR error code or error code returned from the plugin's init function on failure.
+ int load(std::string &plugin_file);
+
+ // Sends a message to the plugin.
+ void sendMessage(const std::string &message);
+
+ // send_count is the maximum number of message to process from the send queue. If negative, it will drain the queue completely.
+ // The receive queue is always drained completely.
+ // Returns the total number of messages processed from both queues.
+ void idle(void);
+
+ // this is the signature of the "send a message" function.
+ // message_string is a null-terminated C string
+ // user_data is the opaque reference that the callee supplied during setup.
+ typedef void (*sendMessageFunction) (const char *message_string, void **user_data);
+
+ // signature of the plugin init function
+ typedef int (*pluginInitFunction) (sendMessageFunction host_send_func, void *host_user_data, sendMessageFunction *plugin_send_func, void **plugin_user_data);
+
+ static const char *PLUGIN_INIT_FUNCTION_NAME;
+
+private:
+ static void staticReceiveMessage(const char *message_string, void **user_data);
+ void receiveMessage(const char *message_string);
+
+ apr_dso_handle_t *mDSOHandle;
+
+ void *mPluginUserData;
+ sendMessageFunction mPluginSendMessageFunction;
+
+ LLPluginInstanceMessageListener *mOwner;
+};
+
+#endif // LL_LLPLUGININSTANCE_H
diff --git a/indra/llplugin/llpluginmessage.cpp b/indra/llplugin/llpluginmessage.cpp
new file mode 100644
index 0000000000..bfabc5b7ca
--- /dev/null
+++ b/indra/llplugin/llpluginmessage.cpp
@@ -0,0 +1,249 @@
+/**
+ * @file llpluginmessage.cpp
+ * @brief LLPluginMessage encapsulates the serialization/deserialization of messages passed to and from plugins.
+ *
+ * $LicenseInfo:firstyear=2008&license=viewergpl$
+ *
+ * Copyright (c) 2008, Linden Research, Inc.
+ *
+ * Second Life Viewer Source Code
+ * The source code in this file ("Source Code") is provided by Linden Lab
+ * to you under the terms of the GNU General Public License, version 2.0
+ * ("GPL"), unless you have obtained a separate licensing agreement
+ * ("Other License"), formally executed by you and Linden Lab. Terms of
+ * the GPL can be found in doc/GPL-license.txt in this distribution, or
+ * online at http://secondlife.com/developers/opensource/gplv2
+ *
+ * There are special exceptions to the terms and conditions of the GPL as
+ * it is applied to this Source Code. View the full text of the exception
+ * in the file doc/FLOSS-exception.txt in this software distribution, or
+ * online at http://secondlife.com/developers/opensource/flossexception
+ *
+ * By copying, modifying or distributing this software, you acknowledge
+ * that you have read and understood your obligations described above,
+ * and agree to abide by those obligations.
+ *
+ * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+ * COMPLETENESS OR PERFORMANCE.
+ * $/LicenseInfo$
+ */
+
+#include "linden_common.h"
+
+#include "llpluginmessage.h"
+#include "llsdserialize.h"
+
+LLPluginMessage::LLPluginMessage()
+{
+}
+
+LLPluginMessage::LLPluginMessage(const std::string &message_class, const std::string &message_name)
+{
+ setMessage(message_class, message_name);
+}
+
+
+LLPluginMessage::~LLPluginMessage()
+{
+}
+
+void LLPluginMessage::clear()
+{
+ mMessage = LLSD::emptyMap();
+ mMessage["params"] = LLSD::emptyMap();
+}
+
+void LLPluginMessage::setMessage(const std::string &message_class, const std::string &message_name)
+{
+ clear();
+ mMessage["class"] = message_class;
+ mMessage["name"] = message_name;
+}
+
+void LLPluginMessage::setValue(const std::string &key, const std::string &value)
+{
+ mMessage["params"][key] = value;
+}
+
+void LLPluginMessage::setValueLLSD(const std::string &key, const LLSD &value)
+{
+ mMessage["params"][key] = value;
+}
+
+void LLPluginMessage::setValueS32(const std::string &key, S32 value)
+{
+ mMessage["params"][key] = value;
+}
+
+void LLPluginMessage::setValueU32(const std::string &key, U32 value)
+{
+ std::stringstream temp;
+ temp << "0x" << std::hex << value;
+ setValue(key, temp.str());
+}
+
+void LLPluginMessage::setValueBoolean(const std::string &key, bool value)
+{
+ mMessage["params"][key] = value;
+}
+
+void LLPluginMessage::setValueReal(const std::string &key, F64 value)
+{
+ mMessage["params"][key] = value;
+}
+
+std::string LLPluginMessage::getClass(void) const
+{
+ return mMessage["class"];
+}
+
+std::string LLPluginMessage::getName(void) const
+{
+ return mMessage["name"];
+}
+
+bool LLPluginMessage::hasValue(const std::string &key) const
+{
+ bool result = false;
+
+ if(mMessage["params"].has(key))
+ {
+ result = true;
+ }
+
+ return result;
+}
+
+std::string LLPluginMessage::getValue(const std::string &key) const
+{
+ std::string result;
+
+ if(mMessage["params"].has(key))
+ {
+ result = mMessage["params"][key].asString();
+ }
+
+ return result;
+}
+
+LLSD LLPluginMessage::getValueLLSD(const std::string &key) const
+{
+ LLSD result;
+
+ if(mMessage["params"].has(key))
+ {
+ result = mMessage["params"][key];
+ }
+
+ return result;
+}
+
+S32 LLPluginMessage::getValueS32(const std::string &key) const
+{
+ S32 result = 0;
+
+ if(mMessage["params"].has(key))
+ {
+ result = mMessage["params"][key].asInteger();
+ }
+
+ return result;
+}
+
+U32 LLPluginMessage::getValueU32(const std::string &key) const
+{
+ U32 result = 0;
+
+ if(mMessage["params"].has(key))
+ {
+ std::string value = mMessage["params"][key].asString();
+
+ result = (U32)strtoul(value.c_str(), NULL, 16);
+ }
+
+ return result;
+}
+
+bool LLPluginMessage::getValueBoolean(const std::string &key) const
+{
+ bool result = false;
+
+ if(mMessage["params"].has(key))
+ {
+ result = mMessage["params"][key].asBoolean();
+ }
+
+ return result;
+}
+
+F64 LLPluginMessage::getValueReal(const std::string &key) const
+{
+ F64 result = 0.0f;
+
+ if(mMessage["params"].has(key))
+ {
+ result = mMessage["params"][key].asReal();
+ }
+
+ return result;
+}
+
+std::string LLPluginMessage::generate(void) const
+{
+ std::ostringstream result;
+
+ // Pretty XML may be slightly easier to deal with while debugging...
+// LLSDSerialize::toXML(mMessage, result);
+ LLSDSerialize::toPrettyXML(mMessage, result);
+
+ return result.str();
+}
+
+
+int LLPluginMessage::parse(const std::string &message)
+{
+ // clear any previous state
+ clear();
+
+ std::istringstream input(message);
+
+ S32 parse_result = LLSDSerialize::fromXML(mMessage, input);
+
+ return (int)parse_result;
+}
+
+
+LLPluginMessageListener::~LLPluginMessageListener()
+{
+ // TODO: should listeners have a way to ensure they're removed from dispatcher lists when deleted?
+}
+
+
+LLPluginMessageDispatcher::~LLPluginMessageDispatcher()
+{
+
+}
+
+void LLPluginMessageDispatcher::addPluginMessageListener(LLPluginMessageListener *listener)
+{
+ mListeners.insert(listener);
+}
+
+void LLPluginMessageDispatcher::removePluginMessageListener(LLPluginMessageListener *listener)
+{
+ mListeners.erase(listener);
+}
+
+void LLPluginMessageDispatcher::dispatchPluginMessage(const LLPluginMessage &message)
+{
+ for (listener_set_t::iterator it = mListeners.begin();
+ it != mListeners.end();
+ )
+ {
+ LLPluginMessageListener* listener = *it;
+ listener->receivePluginMessage(message);
+ // In case something deleted an entry.
+ it = mListeners.upper_bound(listener);
+ }
+}
diff --git a/indra/llplugin/llpluginmessage.h b/indra/llplugin/llpluginmessage.h
new file mode 100644
index 0000000000..a17ec4bb98
--- /dev/null
+++ b/indra/llplugin/llpluginmessage.h
@@ -0,0 +1,123 @@
+/**
+ * @file llpluginmessage.h
+ * @brief LLPluginMessage encapsulates the serialization/deserialization of messages passed to and from plugins.
+ *
+ * $LicenseInfo:firstyear=2008&license=viewergpl$
+ *
+ * Copyright (c) 2008, Linden Research, Inc.
+ *
+ * Second Life Viewer Source Code
+ * The source code in this file ("Source Code") is provided by Linden Lab
+ * to you under the terms of the GNU General Public License, version 2.0
+ * ("GPL"), unless you have obtained a separate licensing agreement
+ * ("Other License"), formally executed by you and Linden Lab. Terms of
+ * the GPL can be found in doc/GPL-license.txt in this distribution, or
+ * online at http://secondlife.com/developers/opensource/gplv2
+ *
+ * There are special exceptions to the terms and conditions of the GPL as
+ * it is applied to this Source Code. View the full text of the exception
+ * in the file doc/FLOSS-exception.txt in this software distribution, or
+ * online at http://secondlife.com/developers/opensource/flossexception
+ *
+ * By copying, modifying or distributing this software, you acknowledge
+ * that you have read and understood your obligations described above,
+ * and agree to abide by those obligations.
+ *
+ * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+ * COMPLETENESS OR PERFORMANCE.
+ * $/LicenseInfo$
+ */
+
+#ifndef LL_LLPLUGINMESSAGE_H
+#define LL_LLPLUGINMESSAGE_H
+
+#include "llsd.h"
+
+
+class LLPluginMessage
+{
+ LOG_CLASS(LLPluginMessage);
+public:
+ LLPluginMessage();
+ LLPluginMessage(const std::string &message_class, const std::string &message_name);
+ ~LLPluginMessage();
+
+ // reset all internal state
+ void clear(void);
+
+ // Sets the message class and name
+ // Also has the side-effect of clearing any key/value pairs in the message.
+ void setMessage(const std::string &message_class, const std::string &message_name);
+
+ // Sets a key/value pair in the message
+ void setValue(const std::string &key, const std::string &value);
+ void setValueLLSD(const std::string &key, const LLSD &value);
+ void setValueS32(const std::string &key, S32 value);
+ void setValueU32(const std::string &key, U32 value);
+ void setValueBoolean(const std::string &key, bool value);
+ void setValueReal(const std::string &key, F64 value);
+
+ std::string getClass(void) const;
+ std::string getName(void) const;
+
+ // Returns true if the specified key exists in this message (useful for optional parameters)
+ bool hasValue(const std::string &key) const;
+
+ // get the value of a particular key as a string. If the key doesn't exist in the message, an empty string will be returned.
+ std::string getValue(const std::string &key) const;
+
+ // get the value of a particular key as LLSD. If the key doesn't exist in the message, a null LLSD will be returned.
+ LLSD getValueLLSD(const std::string &key) const;
+
+ // get the value of a key as a S32. If the value wasn't set as a S32, behavior is undefined.
+ S32 getValueS32(const std::string &key) const;
+
+ // get the value of a key as a U32. Since there isn't an LLSD type for this, we use a hexadecimal string instead.
+ U32 getValueU32(const std::string &key) const;
+
+ // get the value of a key as a Boolean.
+ bool getValueBoolean(const std::string &key) const;
+
+ // get the value of a key as a float.
+ F64 getValueReal(const std::string &key) const;
+
+ // Flatten the message into a string
+ std::string generate(void) const;
+
+ // Parse an incoming message into component parts
+ // (this clears out all existing state before starting the parse)
+ // Returns -1 on failure, otherwise returns the number of key/value pairs in the message.
+ int parse(const std::string &message);
+
+
+private:
+
+ LLSD mMessage;
+
+};
+
+class LLPluginMessageListener
+{
+public:
+ virtual ~LLPluginMessageListener();
+ virtual void receivePluginMessage(const LLPluginMessage &message) = 0;
+
+};
+
+class LLPluginMessageDispatcher
+{
+public:
+ virtual ~LLPluginMessageDispatcher();
+
+ void addPluginMessageListener(LLPluginMessageListener *);
+ void removePluginMessageListener(LLPluginMessageListener *);
+protected:
+ void dispatchPluginMessage(const LLPluginMessage &message);
+
+ typedef std::set<LLPluginMessageListener*> listener_set_t;
+ listener_set_t mListeners;
+};
+
+
+#endif // LL_LLPLUGINMESSAGE_H
diff --git a/indra/llplugin/llpluginmessageclasses.h b/indra/llplugin/llpluginmessageclasses.h
new file mode 100644
index 0000000000..927fcf2eb2
--- /dev/null
+++ b/indra/llplugin/llpluginmessageclasses.h
@@ -0,0 +1,56 @@
+/**
+ * @file llpluginmessageclasses.h
+ * @brief This file defines the versions of existing message classes for LLPluginMessage.
+ *
+ * $LicenseInfo:firstyear=2008&license=viewergpl$
+ *
+ * Copyright (c) 2008, Linden Research, Inc.
+ *
+ * Second Life Viewer Source Code
+ * The source code in this file ("Source Code") is provided by Linden Lab
+ * to you under the terms of the GNU General Public License, version 2.0
+ * ("GPL"), unless you have obtained a separate licensing agreement
+ * ("Other License"), formally executed by you and Linden Lab. Terms of
+ * the GPL can be found in doc/GPL-license.txt in this distribution, or
+ * online at http://secondlife.com/developers/opensource/gplv2
+ *
+ * There are special exceptions to the terms and conditions of the GPL as
+ * it is applied to this Source Code. View the full text of the exception
+ * in the file doc/FLOSS-exception.txt in this software distribution, or
+ * online at http://secondlife.com/developers/opensource/flossexception
+ *
+ * By copying, modifying or distributing this software, you acknowledge
+ * that you have read and understood your obligations described above,
+ * and agree to abide by those obligations.
+ *
+ * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+ * COMPLETENESS OR PERFORMANCE.
+ * $/LicenseInfo$
+ */
+
+#ifndef LL_LLPLUGINMESSAGECLASSES_H
+#define LL_LLPLUGINMESSAGECLASSES_H
+
+// Version strings for each plugin message class.
+// Backwards-compatible changes (i.e. changes which only add new messges) should increment the minor version (i.e. "1.0" -> "1.1").
+// Non-backwards-compatible changes (which delete messages or change their semantics) should increment the major version (i.e. "1.1" -> "2.0").
+// Plugins will supply the set of message classes they understand, with version numbers, as part of their init_response message.
+// The contents and semantics of the base:init message must NEVER change in a non-backwards-compatible way, as a special case.
+
+#define LLPLUGIN_MESSAGE_CLASS_INTERNAL "internal"
+#define LLPLUGIN_MESSAGE_CLASS_INTERNAL_VERSION "1.0"
+
+#define LLPLUGIN_MESSAGE_CLASS_BASE "base"
+#define LLPLUGIN_MESSAGE_CLASS_BASE_VERSION "1.0"
+
+#define LLPLUGIN_MESSAGE_CLASS_MEDIA "media"
+#define LLPLUGIN_MESSAGE_CLASS_MEDIA_VERSION "1.0"
+
+#define LLPLUGIN_MESSAGE_CLASS_MEDIA_BROWSER "media_browser"
+#define LLPLUGIN_MESSAGE_CLASS_MEDIA_BROWSER_VERSION "1.0"
+
+#define LLPLUGIN_MESSAGE_CLASS_MEDIA_TIME "media_time"
+#define LLPLUGIN_MESSAGE_CLASS_MEDIA_TIME_VERSION "1.0"
+
+#endif // LL_LLPLUGINMESSAGECLASSES_H
diff --git a/indra/llplugin/llpluginmessagepipe.cpp b/indra/llplugin/llpluginmessagepipe.cpp
new file mode 100644
index 0000000000..31ea138912
--- /dev/null
+++ b/indra/llplugin/llpluginmessagepipe.cpp
@@ -0,0 +1,315 @@
+/**
+ * @file llpluginmessagepipe.cpp
+ * @brief Classes that implement connections from the plugin system to pipes/pumps.
+ *
+ * $LicenseInfo:firstyear=2008&license=viewergpl$
+ *
+ * Copyright (c) 2008, Linden Research, Inc.
+ *
+ * Second Life Viewer Source Code
+ * The source code in this file ("Source Code") is provided by Linden Lab
+ * to you under the terms of the GNU General Public License, version 2.0
+ * ("GPL"), unless you have obtained a separate licensing agreement
+ * ("Other License"), formally executed by you and Linden Lab. Terms of
+ * the GPL can be found in doc/GPL-license.txt in this distribution, or
+ * online at http://secondlife.com/developers/opensource/gplv2
+ *
+ * There are special exceptions to the terms and conditions of the GPL as
+ * it is applied to this Source Code. View the full text of the exception
+ * in the file doc/FLOSS-exception.txt in this software distribution, or
+ * online at http://secondlife.com/developers/opensource/flossexception
+ *
+ * By copying, modifying or distributing this software, you acknowledge
+ * that you have read and understood your obligations described above,
+ * and agree to abide by those obligations.
+ *
+ * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+ * COMPLETENESS OR PERFORMANCE.
+ * $/LicenseInfo$
+ */
+
+#include "linden_common.h"
+
+#include "llpluginmessagepipe.h"
+#include "llbufferstream.h"
+
+#include "llapr.h"
+
+static const char MESSAGE_DELIMITER = '\0';
+
+LLPluginMessagePipeOwner::LLPluginMessagePipeOwner() :
+ mMessagePipe(NULL),
+ mSocketError(APR_SUCCESS)
+{
+}
+
+// virtual
+LLPluginMessagePipeOwner::~LLPluginMessagePipeOwner()
+{
+ killMessagePipe();
+}
+
+// virtual
+apr_status_t LLPluginMessagePipeOwner::socketError(apr_status_t error)
+{
+ mSocketError = error;
+ return error;
+};
+
+//virtual
+void LLPluginMessagePipeOwner::setMessagePipe(LLPluginMessagePipe *read_pipe)
+{
+ // Save a reference to this pipe
+ mMessagePipe = read_pipe;
+}
+
+bool LLPluginMessagePipeOwner::canSendMessage(void)
+{
+ return (mMessagePipe != NULL);
+}
+
+bool LLPluginMessagePipeOwner::writeMessageRaw(const std::string &message)
+{
+ bool result = true;
+ if(mMessagePipe != NULL)
+ {
+ result = mMessagePipe->addMessage(message);
+ }
+ else
+ {
+ LL_WARNS("Plugin") << "dropping message: " << message << LL_ENDL;
+ result = false;
+ }
+
+ return result;
+}
+
+void LLPluginMessagePipeOwner::killMessagePipe(void)
+{
+ if(mMessagePipe != NULL)
+ {
+ delete mMessagePipe;
+ mMessagePipe = NULL;
+ }
+}
+
+LLPluginMessagePipe::LLPluginMessagePipe(LLPluginMessagePipeOwner *owner, LLSocket::ptr_t socket)
+{
+ mOwner = owner;
+ mOwner->setMessagePipe(this);
+ mSocket = socket;
+}
+
+LLPluginMessagePipe::~LLPluginMessagePipe()
+{
+ if(mOwner != NULL)
+ {
+ mOwner->setMessagePipe(NULL);
+ }
+}
+
+bool LLPluginMessagePipe::addMessage(const std::string &message)
+{
+ // queue the message for later output
+ mOutput += message;
+ mOutput += MESSAGE_DELIMITER; // message separator
+
+ return true;
+}
+
+void LLPluginMessagePipe::clearOwner(void)
+{
+ // The owner is done with this pipe. The next call to process_impl should send any remaining data and exit.
+ mOwner = NULL;
+}
+
+void LLPluginMessagePipe::setSocketTimeout(apr_interval_time_t timeout_usec)
+{
+ // We never want to sleep forever, so force negative timeouts to become non-blocking.
+
+ // according to this page: http://dev.ariel-networks.com/apr/apr-tutorial/html/apr-tutorial-13.html
+ // blocking/non-blocking with apr sockets is somewhat non-portable.
+
+ if(timeout_usec <= 0)
+ {
+ // Make the socket non-blocking
+ apr_socket_opt_set(mSocket->getSocket(), APR_SO_NONBLOCK, 1);
+ apr_socket_timeout_set(mSocket->getSocket(), 0);
+ }
+ else
+ {
+ // Make the socket blocking-with-timeout
+ apr_socket_opt_set(mSocket->getSocket(), APR_SO_NONBLOCK, 1);
+ apr_socket_timeout_set(mSocket->getSocket(), timeout_usec);
+ }
+}
+
+bool LLPluginMessagePipe::pump(F64 timeout)
+{
+ bool result = true;
+
+ if(mSocket)
+ {
+ apr_status_t status;
+ apr_size_t size;
+
+ if(!mOutput.empty())
+ {
+ // write any outgoing messages
+ size = (apr_size_t)mOutput.size();
+
+ setSocketTimeout(0);
+
+// LL_INFOS("Plugin") << "before apr_socket_send, size = " << size << LL_ENDL;
+
+ status = apr_socket_send(
+ mSocket->getSocket(),
+ (const char*)mOutput.data(),
+ &size);
+
+// LL_INFOS("Plugin") << "after apr_socket_send, size = " << size << LL_ENDL;
+
+ if(status == APR_SUCCESS)
+ {
+ // success
+ mOutput = mOutput.substr(size);
+ }
+ else if(APR_STATUS_IS_EAGAIN(status))
+ {
+ // Socket buffer is full...
+ // remove the written part from the buffer and try again later.
+ mOutput = mOutput.substr(size);
+ }
+ else
+ {
+ // some other error
+ // Treat this as fatal.
+ ll_apr_warn_status(status);
+
+ if(mOwner)
+ {
+ mOwner->socketError(status);
+ }
+ result = false;
+ }
+ }
+
+ // FIXME: For some reason, the apr timeout stuff isn't working properly on windows.
+ // Until such time as we figure out why, don't try to use the socket timeout -- just sleep here instead.
+#if LL_WINDOWS
+ if(result)
+ {
+ if(timeout != 0.0f)
+ {
+ ms_sleep((int)(timeout * 1000.0f));
+ timeout = 0.0f;
+ }
+ }
+#endif
+
+ // Check for incoming messages
+ if(result)
+ {
+ char input_buf[1024];
+ apr_size_t request_size;
+
+ // Start out by reading one byte, so that any data received will wake us up.
+ request_size = 1;
+
+ // and use the timeout so we'll sleep if no data is available.
+ setSocketTimeout((apr_interval_time_t)(timeout * 1000000));
+
+ while(1)
+ {
+ size = request_size;
+
+// LL_INFOS("Plugin") << "before apr_socket_recv, size = " << size << LL_ENDL;
+
+ status = apr_socket_recv(
+ mSocket->getSocket(),
+ input_buf,
+ &size);
+
+// LL_INFOS("Plugin") << "after apr_socket_recv, size = " << size << LL_ENDL;
+
+ if(size > 0)
+ mInput.append(input_buf, size);
+
+ if(status == APR_SUCCESS)
+ {
+// llinfos << "success, read " << size << llendl;
+
+ if(size != request_size)
+ {
+ // This was a short read, so we're done.
+ break;
+ }
+ }
+ else if(APR_STATUS_IS_TIMEUP(status))
+ {
+// llinfos << "TIMEUP, read " << size << llendl;
+
+ // Timeout was hit. Since the initial read is 1 byte, this should never be a partial read.
+ break;
+ }
+ else if(APR_STATUS_IS_EAGAIN(status))
+ {
+// llinfos << "EAGAIN, read " << size << llendl;
+
+ // We've been doing partial reads, and we're done now.
+ break;
+ }
+ else
+ {
+ // some other error
+ // Treat this as fatal.
+ ll_apr_warn_status(status);
+
+ if(mOwner)
+ {
+ mOwner->socketError(status);
+ }
+ result = false;
+ break;
+ }
+
+ // Second and subsequent reads should not use the timeout
+ setSocketTimeout(0);
+ // and should try to fill the input buffer
+ request_size = sizeof(input_buf);
+ }
+
+ processInput();
+ }
+ }
+
+ if(!result)
+ {
+ // If we got an error, we're done.
+ LL_INFOS("Plugin") << "Error from socket, cleaning up." << LL_ENDL;
+ delete this;
+ }
+
+ return result;
+}
+
+void LLPluginMessagePipe::processInput(void)
+{
+ // Look for input delimiter(s) in the input buffer.
+ int start = 0;
+ int delim;
+ while((delim = mInput.find(MESSAGE_DELIMITER, start)) != std::string::npos)
+ {
+ // Let the owner process this message
+ mOwner->receiveMessageRaw(mInput.substr(start, delim - start));
+
+ start = delim + 1;
+ }
+
+ // Remove delivered messages from the input buffer.
+ if(start != 0)
+ mInput = mInput.substr(start);
+
+}
+
diff --git a/indra/llplugin/llpluginmessagepipe.h b/indra/llplugin/llpluginmessagepipe.h
new file mode 100644
index 0000000000..4eb6575bd4
--- /dev/null
+++ b/indra/llplugin/llpluginmessagepipe.h
@@ -0,0 +1,91 @@
+/**
+ * @file llpluginmessagepipe.h
+ * @brief Classes that implement connections from the plugin system to pipes/pumps.
+ *
+ * $LicenseInfo:firstyear=2008&license=viewergpl$
+ *
+ * Copyright (c) 2008, Linden Research, Inc.
+ *
+ * Second Life Viewer Source Code
+ * The source code in this file ("Source Code") is provided by Linden Lab
+ * to you under the terms of the GNU General Public License, version 2.0
+ * ("GPL"), unless you have obtained a separate licensing agreement
+ * ("Other License"), formally executed by you and Linden Lab. Terms of
+ * the GPL can be found in doc/GPL-license.txt in this distribution, or
+ * online at http://secondlife.com/developers/opensource/gplv2
+ *
+ * There are special exceptions to the terms and conditions of the GPL as
+ * it is applied to this Source Code. View the full text of the exception
+ * in the file doc/FLOSS-exception.txt in this software distribution, or
+ * online at http://secondlife.com/developers/opensource/flossexception
+ *
+ * By copying, modifying or distributing this software, you acknowledge
+ * that you have read and understood your obligations described above,
+ * and agree to abide by those obligations.
+ *
+ * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+ * COMPLETENESS OR PERFORMANCE.
+ * $/LicenseInfo$
+ */
+
+#ifndef LL_LLPLUGINMESSAGEPIPE_H
+#define LL_LLPLUGINMESSAGEPIPE_H
+
+#include "lliosocket.h"
+
+class LLPluginMessagePipe;
+
+// Inherit from this to be able to receive messages from the LLPluginMessagePipe
+class LLPluginMessagePipeOwner
+{
+ LOG_CLASS(LLPluginMessagePipeOwner);
+public:
+ LLPluginMessagePipeOwner();
+ virtual ~LLPluginMessagePipeOwner();
+ // called with incoming messages
+ virtual void receiveMessageRaw(const std::string &message) = 0;
+ // called when the socket has an error
+ virtual apr_status_t socketError(apr_status_t error);
+
+ // called from LLPluginMessagePipe to manage the connection with LLPluginMessagePipeOwner -- do not use!
+ virtual void setMessagePipe(LLPluginMessagePipe *message_pipe) ;
+
+protected:
+ // returns false if writeMessageRaw() would drop the message
+ bool canSendMessage(void);
+ // call this to send a message over the pipe
+ bool writeMessageRaw(const std::string &message);
+ // call this to close the pipe
+ void killMessagePipe(void);
+
+ LLPluginMessagePipe *mMessagePipe;
+ apr_status_t mSocketError;
+};
+
+class LLPluginMessagePipe
+{
+ LOG_CLASS(LLPluginMessagePipe);
+public:
+ LLPluginMessagePipe(LLPluginMessagePipeOwner *owner, LLSocket::ptr_t socket);
+ virtual ~LLPluginMessagePipe();
+
+ bool addMessage(const std::string &message);
+ void clearOwner(void);
+
+ bool pump(F64 timeout = 0.0f);
+
+protected:
+ void processInput(void);
+
+ // used internally by pump()
+ void setSocketTimeout(apr_interval_time_t timeout_usec);
+
+ std::string mInput;
+ std::string mOutput;
+
+ LLPluginMessagePipeOwner *mOwner;
+ LLSocket::ptr_t mSocket;
+};
+
+#endif // LL_LLPLUGINMESSAGE_H
diff --git a/indra/llplugin/llpluginprocesschild.cpp b/indra/llplugin/llpluginprocesschild.cpp
new file mode 100644
index 0000000000..293dea6fe1
--- /dev/null
+++ b/indra/llplugin/llpluginprocesschild.cpp
@@ -0,0 +1,466 @@
+/**
+ * @file llpluginprocesschild.cpp
+ * @brief LLPluginProcessChild handles the child side of the external-process plugin API.
+ *
+ * $LicenseInfo:firstyear=2008&license=viewergpl$
+ *
+ * Copyright (c) 2008, Linden Research, Inc.
+ *
+ * Second Life Viewer Source Code
+ * The source code in this file ("Source Code") is provided by Linden Lab
+ * to you under the terms of the GNU General Public License, version 2.0
+ * ("GPL"), unless you have obtained a separate licensing agreement
+ * ("Other License"), formally executed by you and Linden Lab. Terms of
+ * the GPL can be found in doc/GPL-license.txt in this distribution, or
+ * online at http://secondlife.com/developers/opensource/gplv2
+ *
+ * There are special exceptions to the terms and conditions of the GPL as
+ * it is applied to this Source Code. View the full text of the exception
+ * in the file doc/FLOSS-exception.txt in this software distribution, or
+ * online at http://secondlife.com/developers/opensource/flossexception
+ *
+ * By copying, modifying or distributing this software, you acknowledge
+ * that you have read and understood your obligations described above,
+ * and agree to abide by those obligations.
+ *
+ * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+ * COMPLETENESS OR PERFORMANCE.
+ * $/LicenseInfo$
+ */
+
+#include "linden_common.h"
+
+#include "llpluginprocesschild.h"
+#include "llplugininstance.h"
+#include "llpluginmessagepipe.h"
+#include "llpluginmessageclasses.h"
+
+static const F32 HEARTBEAT_SECONDS = 1.0f;
+
+LLPluginProcessChild::LLPluginProcessChild()
+{
+ mInstance = NULL;
+ mSocket = LLSocket::create(gAPRPoolp, LLSocket::STREAM_TCP);
+ mSleepTime = 1.0f / 100.0f; // default: send idle messages at 100Hz
+}
+
+LLPluginProcessChild::~LLPluginProcessChild()
+{
+ if(mInstance != NULL)
+ {
+ sendMessageToPlugin(LLPluginMessage("base", "cleanup"));
+ delete mInstance;
+ mInstance = NULL;
+ }
+}
+
+void LLPluginProcessChild::killSockets(void)
+{
+ killMessagePipe();
+ mSocket.reset();
+}
+
+void LLPluginProcessChild::init(U32 launcher_port)
+{
+ mLauncherHost = LLHost("127.0.0.1", launcher_port);
+ setState(STATE_INITIALIZED);
+}
+
+void LLPluginProcessChild::idle(void)
+{
+ bool idle_again;
+ do
+ {
+ if(mSocketError != APR_SUCCESS)
+ {
+ LL_INFOS("Plugin") << "message pipe is in error state, moving to STATE_ERROR"<< LL_ENDL;
+ setState(STATE_ERROR);
+ }
+
+ if((mState > STATE_INITIALIZED) && (mMessagePipe == NULL))
+ {
+ // The pipe has been closed -- we're done.
+ // TODO: This could be slightly more subtle, but I'm not sure it needs to be.
+ LL_INFOS("Plugin") << "message pipe went away, moving to STATE_ERROR"<< LL_ENDL;
+ setState(STATE_ERROR);
+ }
+
+ // If a state needs to go directly to another state (as a performance enhancement), it can set idle_again to true after calling setState().
+ // USE THIS CAREFULLY, since it can starve other code. Specifically make sure there's no way to get into a closed cycle and never return.
+ // When in doubt, don't do it.
+ idle_again = false;
+
+ if(mInstance != NULL)
+ {
+ // Provide some time to the plugin
+ mInstance->idle();
+ }
+
+ switch(mState)
+ {
+ case STATE_UNINITIALIZED:
+ break;
+
+ case STATE_INITIALIZED:
+ if(mSocket->blockingConnect(mLauncherHost))
+ {
+ // This automatically sets mMessagePipe
+ new LLPluginMessagePipe(this, mSocket);
+
+ setState(STATE_CONNECTED);
+ }
+ else
+ {
+ // connect failed
+ setState(STATE_ERROR);
+ }
+ break;
+
+ case STATE_CONNECTED:
+ sendMessageToParent(LLPluginMessage(LLPLUGIN_MESSAGE_CLASS_INTERNAL, "hello"));
+ setState(STATE_PLUGIN_LOADING);
+ break;
+
+ case STATE_PLUGIN_LOADING:
+ if(!mPluginFile.empty())
+ {
+ mInstance = new LLPluginInstance(this);
+ if(mInstance->load(mPluginFile) == 0)
+ {
+ mHeartbeat.start();
+ mHeartbeat.setTimerExpirySec(HEARTBEAT_SECONDS);
+ setState(STATE_PLUGIN_LOADED);
+ }
+ else
+ {
+ setState(STATE_ERROR);
+ }
+ }
+ break;
+
+ case STATE_PLUGIN_LOADED:
+ setState(STATE_PLUGIN_INITIALIZING);
+ sendMessageToPlugin(LLPluginMessage("base", "init"));
+ break;
+
+ case STATE_PLUGIN_INITIALIZING:
+ // waiting for init_response...
+ break;
+
+ case STATE_RUNNING:
+ if(mInstance != NULL)
+ {
+ // Provide some time to the plugin
+ LLPluginMessage message("base", "idle");
+ message.setValueReal("time", mSleepTime);
+ sendMessageToPlugin(message);
+
+ mInstance->idle();
+
+ if(mHeartbeat.checkExpirationAndReset(HEARTBEAT_SECONDS))
+ {
+ // This just proves that we're not stuck down inside the plugin code.
+ sendMessageToParent(LLPluginMessage(LLPLUGIN_MESSAGE_CLASS_INTERNAL, "heartbeat"));
+ }
+ }
+ // receivePluginMessage will transition to STATE_UNLOADING
+ break;
+
+ case STATE_UNLOADING:
+ if(mInstance != NULL)
+ {
+ sendMessageToPlugin(LLPluginMessage("base", "cleanup"));
+ delete mInstance;
+ mInstance = NULL;
+ }
+ setState(STATE_UNLOADED);
+ break;
+
+ case STATE_UNLOADED:
+ killSockets();
+ setState(STATE_DONE);
+ break;
+
+ case STATE_ERROR:
+ // Close the socket to the launcher
+ killSockets();
+ // TODO: Where do we go from here? Just exit()?
+ setState(STATE_DONE);
+ break;
+
+ case STATE_DONE:
+ // just sit here.
+ break;
+ }
+
+ } while (idle_again);
+}
+
+void LLPluginProcessChild::sleep(F64 seconds)
+{
+ if(mMessagePipe)
+ {
+ mMessagePipe->pump(seconds);
+ }
+ else
+ {
+ ms_sleep((int)(seconds * 1000.0f));
+ }
+}
+
+void LLPluginProcessChild::pump(void)
+{
+ if(mMessagePipe)
+ {
+ mMessagePipe->pump(0.0f);
+ }
+ else
+ {
+ // Should we warn here?
+ }
+}
+
+
+bool LLPluginProcessChild::isRunning(void)
+{
+ bool result = false;
+
+ if(mState == STATE_RUNNING)
+ result = true;
+
+ return result;
+}
+
+bool LLPluginProcessChild::isDone(void)
+{
+ bool result = false;
+
+ switch(mState)
+ {
+ case STATE_DONE:
+ result = true;
+ break;
+ default:
+ break;
+ }
+
+ return result;
+}
+
+void LLPluginProcessChild::sendMessageToPlugin(const LLPluginMessage &message)
+{
+ std::string buffer = message.generate();
+
+ LL_DEBUGS("Plugin") << "Sending to plugin: " << buffer << LL_ENDL;
+
+ mInstance->sendMessage(buffer);
+}
+
+void LLPluginProcessChild::sendMessageToParent(const LLPluginMessage &message)
+{
+ std::string buffer = message.generate();
+
+ LL_DEBUGS("Plugin") << "Sending to parent: " << buffer << LL_ENDL;
+
+ writeMessageRaw(buffer);
+}
+
+void LLPluginProcessChild::receiveMessageRaw(const std::string &message)
+{
+ // Incoming message from the TCP Socket
+
+ LL_DEBUGS("Plugin") << "Received from parent: " << message << LL_ENDL;
+
+ bool passMessage = true;
+
+ // FIXME: how should we handle queueing here?
+
+ {
+ // Decode this message
+ LLPluginMessage parsed;
+ parsed.parse(message);
+
+ std::string message_class = parsed.getClass();
+ if(message_class == LLPLUGIN_MESSAGE_CLASS_INTERNAL)
+ {
+ passMessage = false;
+
+ std::string message_name = parsed.getName();
+ if(message_name == "load_plugin")
+ {
+ mPluginFile = parsed.getValue("file");
+ }
+ else if(message_name == "shm_add")
+ {
+ std::string name = parsed.getValue("name");
+ size_t size = (size_t)parsed.getValueS32("size");
+
+ sharedMemoryRegionsType::iterator iter = mSharedMemoryRegions.find(name);
+ if(iter != mSharedMemoryRegions.end())
+ {
+ // Need to remove the old region first
+ LL_WARNS("Plugin") << "Adding a duplicate shared memory segment!" << LL_ENDL;
+ }
+ else
+ {
+ // This is a new region
+ LLPluginSharedMemory *region = new LLPluginSharedMemory;
+ if(region->attach(name, size))
+ {
+ mSharedMemoryRegions.insert(sharedMemoryRegionsType::value_type(name, region));
+
+ std::stringstream addr;
+ addr << region->getMappedAddress();
+
+ // Send the add notification to the plugin
+ LLPluginMessage message("base", "shm_added");
+ message.setValue("name", name);
+ message.setValueS32("size", (S32)size);
+ // shm address is split into 2x32bit values because LLSD doesn't serialize 64bit values and we need to support 64-bit addressing.
+ void * address = region->getMappedAddress();
+ U32 address_lo = (U32)address;
+ U32 address_hi = (U32)(U64(address) / (U64(1)<<31));
+ message.setValueU32("address", address_lo);
+ message.setValueU32("address_1", address_hi);
+ sendMessageToPlugin(message);
+
+ // and send the response to the parent
+ message.setMessage(LLPLUGIN_MESSAGE_CLASS_INTERNAL, "shm_add_response");
+ message.setValue("name", name);
+ sendMessageToParent(message);
+ }
+ else
+ {
+ LL_WARNS("Plugin") << "Couldn't create a shared memory segment!" << LL_ENDL;
+ }
+ }
+
+ }
+ else if(message_name == "shm_remove")
+ {
+ std::string name = parsed.getValue("name");
+ sharedMemoryRegionsType::iterator iter = mSharedMemoryRegions.find(name);
+ if(iter != mSharedMemoryRegions.end())
+ {
+ // forward the remove request to the plugin -- its response will trigger us to detach the segment.
+ LLPluginMessage message("base", "shm_remove");
+ message.setValue("name", name);
+ sendMessageToPlugin(message);
+ }
+ else
+ {
+ LL_WARNS("Plugin") << "shm_remove for unknown memory segment!" << LL_ENDL;
+ }
+ }
+ else if(message_name == "sleep_time")
+ {
+ mSleepTime = parsed.getValueReal("time");
+ }
+ else if(message_name == "crash")
+ {
+ // Crash the plugin
+ LL_ERRS("Plugin") << "Plugin crash requested." << LL_ENDL;
+ }
+ else if(message_name == "hang")
+ {
+ // Hang the plugin
+ LL_WARNS("Plugin") << "Plugin hang requested." << LL_ENDL;
+ while(1)
+ {
+ // wheeeeeeeee......
+ }
+ }
+ else
+ {
+ LL_WARNS("Plugin") << "Unknown internal message from parent: " << message_name << LL_ENDL;
+ }
+ }
+ }
+
+ if(passMessage && mInstance != NULL)
+ {
+ mInstance->sendMessage(message);
+ }
+}
+
+/* virtual */
+void LLPluginProcessChild::receivePluginMessage(const std::string &message)
+{
+ LL_DEBUGS("Plugin") << "Received from plugin: " << message << LL_ENDL;
+
+ // Incoming message from the plugin instance
+ bool passMessage = true;
+
+ // FIXME: how should we handle queueing here?
+
+ // Intercept certain base messages (responses to ones sent by this class)
+ {
+ // Decode this message
+ LLPluginMessage parsed;
+ parsed.parse(message);
+ std::string message_class = parsed.getClass();
+ if(message_class == "base")
+ {
+ std::string message_name = parsed.getName();
+ if(message_name == "init_response")
+ {
+ // The plugin has finished initializing.
+ setState(STATE_RUNNING);
+
+ // Don't pass this message up to the parent
+ passMessage = false;
+
+ LLPluginMessage new_message(LLPLUGIN_MESSAGE_CLASS_INTERNAL, "load_plugin_response");
+ LLSD versions = parsed.getValueLLSD("versions");
+ new_message.setValueLLSD("versions", versions);
+
+ if(parsed.hasValue("plugin_version"))
+ {
+ std::string plugin_version = parsed.getValue("plugin_version");
+ new_message.setValueLLSD("plugin_version", plugin_version);
+ }
+
+ // Let the parent know it's loaded and initialized.
+ sendMessageToParent(new_message);
+ }
+ else if(message_name == "shm_remove_response")
+ {
+ // Don't pass this message up to the parent
+ passMessage = false;
+
+ std::string name = parsed.getValue("name");
+ sharedMemoryRegionsType::iterator iter = mSharedMemoryRegions.find(name);
+ if(iter != mSharedMemoryRegions.end())
+ {
+ // detach the shared memory region
+ iter->second->detach();
+
+ // and remove it from our map
+ mSharedMemoryRegions.erase(iter);
+
+ // Finally, send the response to the parent.
+ LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_INTERNAL, "shm_remove_response");
+ message.setValue("name", name);
+ sendMessageToParent(message);
+ }
+ else
+ {
+ LL_WARNS("Plugin") << "shm_remove_response for unknown memory segment!" << LL_ENDL;
+ }
+ }
+ }
+ }
+
+ if(passMessage)
+ {
+ writeMessageRaw(message);
+ }
+}
+
+
+void LLPluginProcessChild::setState(EState state)
+{
+ LL_DEBUGS("Plugin") << "setting state to " << state << LL_ENDL;
+ mState = state;
+};
diff --git a/indra/llplugin/llpluginprocesschild.h b/indra/llplugin/llpluginprocesschild.h
new file mode 100644
index 0000000000..f92905e8bd
--- /dev/null
+++ b/indra/llplugin/llpluginprocesschild.h
@@ -0,0 +1,108 @@
+/**
+ * @file llpluginprocesschild.h
+ * @brief LLPluginProcessChild handles the child side of the external-process plugin API.
+ *
+ * $LicenseInfo:firstyear=2008&license=viewergpl$
+ *
+ * Copyright (c) 2008, Linden Research, Inc.
+ *
+ * Second Life Viewer Source Code
+ * The source code in this file ("Source Code") is provided by Linden Lab
+ * to you under the terms of the GNU General Public License, version 2.0
+ * ("GPL"), unless you have obtained a separate licensing agreement
+ * ("Other License"), formally executed by you and Linden Lab. Terms of
+ * the GPL can be found in doc/GPL-license.txt in this distribution, or
+ * online at http://secondlife.com/developers/opensource/gplv2
+ *
+ * There are special exceptions to the terms and conditions of the GPL as
+ * it is applied to this Source Code. View the full text of the exception
+ * in the file doc/FLOSS-exception.txt in this software distribution, or
+ * online at http://secondlife.com/developers/opensource/flossexception
+ *
+ * By copying, modifying or distributing this software, you acknowledge
+ * that you have read and understood your obligations described above,
+ * and agree to abide by those obligations.
+ *
+ * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+ * COMPLETENESS OR PERFORMANCE.
+ * $/LicenseInfo$
+ */
+
+#ifndef LL_LLPLUGINPROCESSCHILD_H
+#define LL_LLPLUGINPROCESSCHILD_H
+
+#include "llpluginmessage.h"
+#include "llpluginmessagepipe.h"
+#include "llplugininstance.h"
+#include "llhost.h"
+#include "llpluginsharedmemory.h"
+
+class LLPluginInstance;
+
+class LLPluginProcessChild: public LLPluginMessagePipeOwner, public LLPluginInstanceMessageListener
+{
+ LOG_CLASS(LLPluginProcessChild);
+public:
+ LLPluginProcessChild();
+ ~LLPluginProcessChild();
+
+ void init(U32 launcher_port);
+ void idle(void);
+ void sleep(F64 seconds);
+ void pump();
+
+ // returns true if the plugin is in the steady state (processing messages)
+ bool isRunning(void);
+
+ // returns true if the plugin is unloaded or we're in an unrecoverable error state.
+ bool isDone(void);
+
+ void killSockets(void);
+
+ F64 getSleepTime(void) const { return mSleepTime; };
+
+ void sendMessageToPlugin(const LLPluginMessage &message);
+ void sendMessageToParent(const LLPluginMessage &message);
+
+ // Inherited from LLPluginMessagePipeOwner
+ /* virtual */ void receiveMessageRaw(const std::string &message);
+
+ // Inherited from LLPluginInstanceMessageListener
+ /* virtual */ void receivePluginMessage(const std::string &message);
+
+private:
+
+ enum EState
+ {
+ STATE_UNINITIALIZED,
+ STATE_INITIALIZED, // init() has been called
+ STATE_CONNECTED, // connected back to launcher
+ STATE_PLUGIN_LOADING, // plugin library needs to be loaded
+ STATE_PLUGIN_LOADED, // plugin library has been loaded
+ STATE_PLUGIN_INITIALIZING, // plugin is processing init message
+ STATE_RUNNING, // steady state (processing messages)
+ STATE_UNLOADING, // plugin has sent shutdown_response and needs to be unloaded
+ STATE_UNLOADED, // plugin has been unloaded
+ STATE_ERROR, // generic bailout state
+ STATE_DONE // state machine will sit in this state after either error or normal termination.
+ };
+ EState mState;
+ void setState(EState state);
+
+ LLHost mLauncherHost;
+ LLSocket::ptr_t mSocket;
+
+ std::string mPluginFile;
+
+ LLPluginInstance *mInstance;
+
+ typedef std::map<std::string, LLPluginSharedMemory*> sharedMemoryRegionsType;
+ sharedMemoryRegionsType mSharedMemoryRegions;
+
+ LLTimer mHeartbeat;
+ F64 mSleepTime;
+
+};
+
+#endif // LL_LLPLUGINPROCESSCHILD_H
diff --git a/indra/llplugin/llpluginprocessparent.cpp b/indra/llplugin/llpluginprocessparent.cpp
new file mode 100644
index 0000000000..f18a117dde
--- /dev/null
+++ b/indra/llplugin/llpluginprocessparent.cpp
@@ -0,0 +1,658 @@
+/**
+ * @file llpluginprocessparent.cpp
+ * @brief LLPluginProcessParent handles the parent side of the external-process plugin API.
+ *
+ * $LicenseInfo:firstyear=2008&license=viewergpl$
+ *
+ * Copyright (c) 2008, Linden Research, Inc.
+ *
+ * Second Life Viewer Source Code
+ * The source code in this file ("Source Code") is provided by Linden Lab
+ * to you under the terms of the GNU General Public License, version 2.0
+ * ("GPL"), unless you have obtained a separate licensing agreement
+ * ("Other License"), formally executed by you and Linden Lab. Terms of
+ * the GPL can be found in doc/GPL-license.txt in this distribution, or
+ * online at http://secondlife.com/developers/opensource/gplv2
+ *
+ * There are special exceptions to the terms and conditions of the GPL as
+ * it is applied to this Source Code. View the full text of the exception
+ * in the file doc/FLOSS-exception.txt in this software distribution, or
+ * online at http://secondlife.com/developers/opensource/flossexception
+ *
+ * By copying, modifying or distributing this software, you acknowledge
+ * that you have read and understood your obligations described above,
+ * and agree to abide by those obligations.
+ *
+ * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+ * COMPLETENESS OR PERFORMANCE.
+ * $/LicenseInfo$
+ */
+
+#include "linden_common.h"
+
+#include "llpluginprocessparent.h"
+#include "llpluginmessagepipe.h"
+#include "llpluginmessageclasses.h"
+
+#include "llapr.h"
+
+// If we don't receive a heartbeat in this many seconds, we declare the plugin locked up.
+static const F32 PLUGIN_LOCKED_UP_SECONDS = 10.0f;
+
+// Somewhat longer timeout for initial launch.
+static const F32 PLUGIN_LAUNCH_SECONDS = 20.0f;
+
+//virtual
+LLPluginProcessParentOwner::~LLPluginProcessParentOwner()
+{
+
+}
+
+LLPluginProcessParent::LLPluginProcessParent(LLPluginProcessParentOwner *owner)
+{
+ mOwner = owner;
+ mBoundPort = 0;
+ mState = STATE_UNINITIALIZED;
+ mDisableTimeout = false;
+}
+
+LLPluginProcessParent::~LLPluginProcessParent()
+{
+ LL_DEBUGS("Plugin") << "destructor" << LL_ENDL;
+
+ // Destroy any remaining shared memory regions
+ sharedMemoryRegionsType::iterator iter;
+ while((iter = mSharedMemoryRegions.begin()) != mSharedMemoryRegions.end())
+ {
+ // destroy the shared memory region
+ iter->second->destroy();
+
+ // and remove it from our map
+ mSharedMemoryRegions.erase(iter);
+ }
+
+ mProcess.kill();
+ killSockets();
+}
+
+void LLPluginProcessParent::killSockets(void)
+{
+ killMessagePipe();
+ mListenSocket.reset();
+ mSocket.reset();
+}
+
+void LLPluginProcessParent::init(const std::string &launcher_filename, const std::string &plugin_filename)
+{
+ mProcess.setExecutable(launcher_filename);
+ mPluginFile = plugin_filename;
+
+ setState(STATE_INITIALIZED);
+}
+
+bool LLPluginProcessParent::accept()
+{
+ bool result = false;
+
+ apr_status_t status = APR_EGENERAL;
+ apr_socket_t *new_socket = NULL;
+
+ status = apr_socket_accept(
+ &new_socket,
+ mListenSocket->getSocket(),
+ gAPRPoolp);
+
+
+ if(status == APR_SUCCESS)
+ {
+// llinfos << "SUCCESS" << llendl;
+ // Success. Create a message pipe on the new socket
+
+ // we MUST create a new pool for the LLSocket, since it will take ownership of it and delete it in its destructor!
+ apr_pool_t* new_pool = NULL;
+ status = apr_pool_create(&new_pool, gAPRPoolp);
+
+ mSocket = LLSocket::create(new_socket, new_pool);
+ new LLPluginMessagePipe(this, mSocket);
+
+ result = true;
+ }
+ else if(APR_STATUS_IS_EAGAIN(status))
+ {
+// llinfos << "EAGAIN" << llendl;
+
+ // No incoming connections. This is not an error.
+ status = APR_SUCCESS;
+ }
+ else
+ {
+// llinfos << "Error:" << llendl;
+ ll_apr_warn_status(status);
+
+ // Some other error.
+ setState(STATE_ERROR);
+ }
+
+ return result;
+}
+
+void LLPluginProcessParent::idle(void)
+{
+ bool idle_again;
+
+ do
+ {
+ // Give time to network processing
+ if(mMessagePipe)
+ {
+ if(!mMessagePipe->pump())
+ {
+// LL_WARNS("Plugin") << "Message pipe hit an error state" << LL_ENDL;
+ setState(STATE_ERROR);
+ }
+ }
+
+ if((mSocketError != APR_SUCCESS) && (mState < STATE_ERROR))
+ {
+ // The socket is in an error state -- the plugin is gone.
+ LL_WARNS("Plugin") << "Socket hit an error state (" << mSocketError << ")" << LL_ENDL;
+ setState(STATE_ERROR);
+ }
+
+ // If a state needs to go directly to another state (as a performance enhancement), it can set idle_again to true after calling setState().
+ // USE THIS CAREFULLY, since it can starve other code. Specifically make sure there's no way to get into a closed cycle and never return.
+ // When in doubt, don't do it.
+ idle_again = false;
+ switch(mState)
+ {
+ case STATE_UNINITIALIZED:
+ break;
+
+ case STATE_INITIALIZED:
+ {
+
+ apr_status_t status = APR_SUCCESS;
+ apr_sockaddr_t* addr = NULL;
+ mListenSocket = LLSocket::create(gAPRPoolp, LLSocket::STREAM_TCP);
+ mBoundPort = 0;
+
+ // This code is based on parts of LLSocket::create() in lliosocket.cpp.
+
+ status = apr_sockaddr_info_get(
+ &addr,
+ "127.0.0.1",
+ APR_INET,
+ 0, // port 0 = ephemeral ("find me a port")
+ 0,
+ gAPRPoolp);
+
+ if(ll_apr_warn_status(status))
+ {
+ killSockets();
+ setState(STATE_ERROR);
+ break;
+ }
+
+ // This allows us to reuse the address on quick down/up. This is unlikely to create problems.
+ ll_apr_warn_status(apr_socket_opt_set(mListenSocket->getSocket(), APR_SO_REUSEADDR, 1));
+
+ status = apr_socket_bind(mListenSocket->getSocket(), addr);
+ if(ll_apr_warn_status(status))
+ {
+ killSockets();
+ setState(STATE_ERROR);
+ break;
+ }
+
+ // Get the actual port the socket was bound to
+ {
+ apr_sockaddr_t* bound_addr = NULL;
+ if(ll_apr_warn_status(apr_socket_addr_get(&bound_addr, APR_LOCAL, mListenSocket->getSocket())))
+ {
+ killSockets();
+ setState(STATE_ERROR);
+ break;
+ }
+ mBoundPort = bound_addr->port;
+
+ if(mBoundPort == 0)
+ {
+ LL_WARNS("Plugin") << "Bound port number unknown, bailing out." << LL_ENDL;
+
+ killSockets();
+ setState(STATE_ERROR);
+ break;
+ }
+ }
+
+ LL_DEBUGS("Plugin") << "Bound tcp socket to port: " << addr->port << LL_ENDL;
+
+ // Make the listen socket non-blocking
+ status = apr_socket_opt_set(mListenSocket->getSocket(), APR_SO_NONBLOCK, 1);
+ if(ll_apr_warn_status(status))
+ {
+ killSockets();
+ setState(STATE_ERROR);
+ break;
+ }
+
+ apr_socket_timeout_set(mListenSocket->getSocket(), 0);
+ if(ll_apr_warn_status(status))
+ {
+ killSockets();
+ setState(STATE_ERROR);
+ break;
+ }
+
+ // If it's a stream based socket, we need to tell the OS
+ // to keep a queue of incoming connections for ACCEPT.
+ status = apr_socket_listen(
+ mListenSocket->getSocket(),
+ 10); // FIXME: Magic number for queue size
+
+ if(ll_apr_warn_status(status))
+ {
+ killSockets();
+ setState(STATE_ERROR);
+ break;
+ }
+
+ // If we got here, we're listening.
+ setState(STATE_LISTENING);
+ }
+ break;
+
+ case STATE_LISTENING:
+ {
+ // Launch the plugin process.
+
+ // Only argument to the launcher is the port number we're listening on
+ std::stringstream stream;
+ stream << mBoundPort;
+ mProcess.addArgument(stream.str());
+ if(mProcess.launch() != 0)
+ {
+ setState(STATE_ERROR);
+ }
+ else
+ {
+ // This will allow us to time out if the process never starts.
+ mHeartbeat.start();
+ mHeartbeat.setTimerExpirySec(PLUGIN_LAUNCH_SECONDS);
+ setState(STATE_LAUNCHED);
+ }
+ }
+ break;
+
+ case STATE_LAUNCHED:
+ // waiting for the plugin to connect
+ if(pluginLockedUpOrQuit())
+ {
+ setState(STATE_ERROR);
+ }
+ else
+ {
+ // Check for the incoming connection.
+ if(accept())
+ {
+ // Stop listening on the server port
+ mListenSocket.reset();
+ setState(STATE_CONNECTED);
+ }
+ }
+ break;
+
+ case STATE_CONNECTED:
+ // waiting for hello message from the plugin
+
+ if(pluginLockedUpOrQuit())
+ {
+ setState(STATE_ERROR);
+ }
+ break;
+
+ case STATE_HELLO:
+ LL_DEBUGS("Plugin") << "received hello message" << llendl;
+
+ // Send the message to load the plugin
+ {
+ LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_INTERNAL, "load_plugin");
+ message.setValue("file", mPluginFile);
+ sendMessage(message);
+ }
+
+ setState(STATE_LOADING);
+ break;
+
+ case STATE_LOADING:
+ // The load_plugin_response message will kick us from here into STATE_RUNNING
+ if(pluginLockedUpOrQuit())
+ {
+ setState(STATE_ERROR);
+ }
+ break;
+
+ case STATE_RUNNING:
+ if(pluginLockedUpOrQuit())
+ {
+ setState(STATE_ERROR);
+ }
+ break;
+
+ case STATE_EXITING:
+ if(!mProcess.isRunning())
+ {
+ setState(STATE_CLEANUP);
+ }
+ else if(pluginLockedUp())
+ {
+ LL_WARNS("Plugin") << "timeout in exiting state, bailing out" << llendl;
+ setState(STATE_ERROR);
+ }
+ break;
+
+ case STATE_ERROR:
+ if(mOwner != NULL)
+ {
+ mOwner->pluginDied();
+ }
+ setState(STATE_CLEANUP);
+ break;
+
+ case STATE_CLEANUP:
+ mProcess.kill();
+ killSockets();
+ setState(STATE_DONE);
+ break;
+
+
+ case STATE_DONE:
+ // just sit here.
+ break;
+
+ }
+
+ } while (idle_again);
+}
+
+bool LLPluginProcessParent::isLoading(void)
+{
+ bool result = false;
+
+ if(mState <= STATE_LOADING)
+ result = true;
+
+ return result;
+}
+
+bool LLPluginProcessParent::isRunning(void)
+{
+ bool result = false;
+
+ if(mState == STATE_RUNNING)
+ result = true;
+
+ return result;
+}
+
+bool LLPluginProcessParent::isDone(void)
+{
+ bool result = false;
+
+ if(mState == STATE_DONE)
+ result = true;
+
+ return result;
+}
+
+void LLPluginProcessParent::setSleepTime(F64 sleep_time, bool force_send)
+{
+ if(force_send || (sleep_time != mSleepTime))
+ {
+ // Cache the time locally
+ mSleepTime = sleep_time;
+
+ if(canSendMessage())
+ {
+ // and send to the plugin.
+ LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_INTERNAL, "sleep_time");
+ message.setValueReal("time", mSleepTime);
+ sendMessage(message);
+ }
+ else
+ {
+ // Too early to send -- the load_plugin_response message will trigger us to send mSleepTime later.
+ }
+ }
+}
+
+void LLPluginProcessParent::sendMessage(const LLPluginMessage &message)
+{
+
+ std::string buffer = message.generate();
+ LL_DEBUGS("Plugin") << "Sending: " << buffer << LL_ENDL;
+ writeMessageRaw(buffer);
+}
+
+
+void LLPluginProcessParent::receiveMessageRaw(const std::string &message)
+{
+ LL_DEBUGS("Plugin") << "Received: " << message << LL_ENDL;
+
+ // FIXME: should this go into a queue instead?
+
+ LLPluginMessage parsed;
+ if(parsed.parse(message) != -1)
+ {
+ receiveMessage(parsed);
+ }
+}
+
+void LLPluginProcessParent::receiveMessage(const LLPluginMessage &message)
+{
+ std::string message_class = message.getClass();
+ if(message_class == LLPLUGIN_MESSAGE_CLASS_INTERNAL)
+ {
+ // internal messages should be handled here
+ std::string message_name = message.getName();
+ if(message_name == "hello")
+ {
+ if(mState == STATE_CONNECTED)
+ {
+ // Plugin host has launched. Tell it which plugin to load.
+ setState(STATE_HELLO);
+ }
+ else
+ {
+ LL_WARNS("Plugin") << "received hello message in wrong state -- bailing out" << LL_ENDL;
+ setState(STATE_ERROR);
+ }
+
+ }
+ else if(message_name == "load_plugin_response")
+ {
+ if(mState == STATE_LOADING)
+ {
+ // Plugin has been loaded.
+
+ // Check which message classes/versions the plugin supports.
+ // TODO: check against current versions
+ // TODO: kill plugin on major mismatches?
+ mMessageClassVersions = message.getValueLLSD("versions");
+ LLSD::map_iterator iter;
+ for(iter = mMessageClassVersions.beginMap(); iter != mMessageClassVersions.endMap(); iter++)
+ {
+ LL_INFOS("Plugin") << "message class: " << iter->first << " -> version: " << iter->second.asString() << LL_ENDL;
+ }
+
+ mPluginVersionString = message.getValue("plugin_version");
+
+ // Send initial sleep time
+ setSleepTime(mSleepTime, true);
+
+ setState(STATE_RUNNING);
+ }
+ else
+ {
+ LL_WARNS("Plugin") << "received load_plugin_response message in wrong state -- bailing out" << LL_ENDL;
+ setState(STATE_ERROR);
+ }
+ }
+ else if(message_name == "heartbeat")
+ {
+ // this resets our timer.
+ mHeartbeat.setTimerExpirySec(PLUGIN_LOCKED_UP_SECONDS);
+ }
+ else if(message_name == "shm_add_response")
+ {
+ // Nothing to do here.
+ }
+ else if(message_name == "shm_remove_response")
+ {
+ std::string name = message.getValue("name");
+ sharedMemoryRegionsType::iterator iter = mSharedMemoryRegions.find(name);
+
+ if(iter != mSharedMemoryRegions.end())
+ {
+ // destroy the shared memory region
+ iter->second->destroy();
+
+ // and remove it from our map
+ mSharedMemoryRegions.erase(iter);
+ }
+ }
+ else
+ {
+ LL_WARNS("Plugin") << "Unknown internal message from child: " << message_name << LL_ENDL;
+ }
+ }
+ else
+ {
+ if(mOwner != NULL)
+ {
+ mOwner->receivePluginMessage(message);
+ }
+ }
+}
+
+std::string LLPluginProcessParent::addSharedMemory(size_t size)
+{
+ std::string name;
+
+ LLPluginSharedMemory *region = new LLPluginSharedMemory;
+
+ // This is a new region
+ if(region->create(size))
+ {
+ name = region->getName();
+
+ mSharedMemoryRegions.insert(sharedMemoryRegionsType::value_type(name, region));
+
+ LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_INTERNAL, "shm_add");
+ message.setValue("name", name);
+ message.setValueS32("size", (S32)size);
+ sendMessage(message);
+ }
+ else
+ {
+ LL_WARNS("Plugin") << "Couldn't create a shared memory segment!" << LL_ENDL;
+
+ // Don't leak
+ delete region;
+ }
+
+ return name;
+}
+
+void LLPluginProcessParent::removeSharedMemory(const std::string &name)
+{
+ sharedMemoryRegionsType::iterator iter = mSharedMemoryRegions.find(name);
+
+ if(iter != mSharedMemoryRegions.end())
+ {
+ // This segment exists. Send the message to the child to unmap it. The response will cause the parent to unmap our end.
+ LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_INTERNAL, "shm_remove");
+ message.setValue("name", name);
+ sendMessage(message);
+ }
+ else
+ {
+ LL_WARNS("Plugin") << "Request to remove an unknown shared memory segment." << LL_ENDL;
+ }
+}
+size_t LLPluginProcessParent::getSharedMemorySize(const std::string &name)
+{
+ size_t result = 0;
+
+ sharedMemoryRegionsType::iterator iter = mSharedMemoryRegions.find(name);
+ if(iter != mSharedMemoryRegions.end())
+ {
+ result = iter->second->getSize();
+ }
+
+ return result;
+}
+void *LLPluginProcessParent::getSharedMemoryAddress(const std::string &name)
+{
+ void *result = NULL;
+
+ sharedMemoryRegionsType::iterator iter = mSharedMemoryRegions.find(name);
+ if(iter != mSharedMemoryRegions.end())
+ {
+ result = iter->second->getMappedAddress();
+ }
+
+ return result;
+}
+
+std::string LLPluginProcessParent::getMessageClassVersion(const std::string &message_class)
+{
+ std::string result;
+
+ if(mMessageClassVersions.has(message_class))
+ {
+ result = mMessageClassVersions[message_class].asString();
+ }
+
+ return result;
+}
+
+std::string LLPluginProcessParent::getPluginVersion(void)
+{
+ return mPluginVersionString;
+}
+
+void LLPluginProcessParent::setState(EState state)
+{
+ LL_DEBUGS("Plugin") << "setting state to " << state << LL_ENDL;
+ mState = state;
+};
+
+bool LLPluginProcessParent::pluginLockedUpOrQuit()
+{
+ bool result = false;
+
+ if(!mDisableTimeout)
+ {
+ if(!mProcess.isRunning())
+ {
+ LL_WARNS("Plugin") << "child exited" << llendl;
+ result = true;
+ }
+ else if(pluginLockedUp())
+ {
+ LL_WARNS("Plugin") << "timeout" << llendl;
+ result = true;
+ }
+ }
+
+ return result;
+}
+
+bool LLPluginProcessParent::pluginLockedUp()
+{
+ // If the timer has expired, the plugin has locked up.
+ return mHeartbeat.hasExpired();
+}
+
diff --git a/indra/llplugin/llpluginprocessparent.h b/indra/llplugin/llpluginprocessparent.h
new file mode 100644
index 0000000000..545eb85c9a
--- /dev/null
+++ b/indra/llplugin/llpluginprocessparent.h
@@ -0,0 +1,147 @@
+/**
+ * @file llpluginprocessparent.h
+ * @brief LLPluginProcessParent handles the parent side of the external-process plugin API.
+ *
+ * $LicenseInfo:firstyear=2008&license=viewergpl$
+ *
+ * Copyright (c) 2008, Linden Research, Inc.
+ *
+ * Second Life Viewer Source Code
+ * The source code in this file ("Source Code") is provided by Linden Lab
+ * to you under the terms of the GNU General Public License, version 2.0
+ * ("GPL"), unless you have obtained a separate licensing agreement
+ * ("Other License"), formally executed by you and Linden Lab. Terms of
+ * the GPL can be found in doc/GPL-license.txt in this distribution, or
+ * online at http://secondlife.com/developers/opensource/gplv2
+ *
+ * There are special exceptions to the terms and conditions of the GPL as
+ * it is applied to this Source Code. View the full text of the exception
+ * in the file doc/FLOSS-exception.txt in this software distribution, or
+ * online at http://secondlife.com/developers/opensource/flossexception
+ *
+ * By copying, modifying or distributing this software, you acknowledge
+ * that you have read and understood your obligations described above,
+ * and agree to abide by those obligations.
+ *
+ * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+ * COMPLETENESS OR PERFORMANCE.
+ * $/LicenseInfo$
+ */
+
+#ifndef LL_LLPLUGINPROCESSPARENT_H
+#define LL_LLPLUGINPROCESSPARENT_H
+
+#include "llprocesslauncher.h"
+#include "llpluginmessage.h"
+#include "llpluginmessagepipe.h"
+#include "llpluginsharedmemory.h"
+
+#include "lliosocket.h"
+
+class LLPluginProcessParentOwner
+{
+public:
+ virtual ~LLPluginProcessParentOwner();
+ virtual void receivePluginMessage(const LLPluginMessage &message) = 0;
+ // This will only be called when the plugin has died unexpectedly
+ virtual void pluginDied() {};
+};
+
+class LLPluginProcessParent : public LLPluginMessagePipeOwner
+{
+ LOG_CLASS(LLPluginProcessParent);
+public:
+ LLPluginProcessParent(LLPluginProcessParentOwner *owner);
+ ~LLPluginProcessParent();
+
+ void init(const std::string &launcher_filename, const std::string &plugin_filename);
+ void idle(void);
+
+ // returns true if the plugin is on its way to steady state
+ bool isLoading(void);
+
+ // returns true if the plugin is in the steady state (processing messages)
+ bool isRunning(void);
+
+ // returns true if the process has exited or we've had a fatal error
+ bool isDone(void);
+
+ void killSockets(void);
+
+ void setSleepTime(F64 sleep_time, bool force_send = false);
+ F64 getSleepTime(void) const { return mSleepTime; };
+
+ void sendMessage(const LLPluginMessage &message);
+
+ void receiveMessage(const LLPluginMessage &message);
+
+ // Inherited from LLPluginMessagePipeOwner
+ void receiveMessageRaw(const std::string &message);
+
+ // This adds a memory segment shared with the client, generating a name for the segment. The name generated is guaranteed to be unique on the host.
+ // The caller must call removeSharedMemory first (and wait until getSharedMemorySize returns 0 for the indicated name) before re-adding a segment with the same name.
+ std::string addSharedMemory(size_t size);
+ // Negotiates for the removal of a shared memory segment. It is the caller's responsibility to ensure that nothing touches the memory
+ // after this has been called, since the segment will be unmapped shortly thereafter.
+ void removeSharedMemory(const std::string &name);
+ size_t getSharedMemorySize(const std::string &name);
+ void *getSharedMemoryAddress(const std::string &name);
+
+ // Returns the version string the plugin indicated for the message class, or an empty string if that class wasn't in the list.
+ std::string getMessageClassVersion(const std::string &message_class);
+
+ std::string getPluginVersion(void);
+
+ bool getDisableTimeout() { return mDisableTimeout; };
+ void setDisableTimeout(bool disable) { mDisableTimeout = disable; };
+
+private:
+
+ enum EState
+ {
+ STATE_UNINITIALIZED,
+ STATE_INITIALIZED, // init() has been called
+ STATE_LISTENING, // listening for incoming connection
+ STATE_LAUNCHED, // process has been launched
+ STATE_CONNECTED, // process has connected
+ STATE_HELLO, // first message from the plugin process has been received
+ STATE_LOADING, // process has been asked to load the plugin
+ STATE_RUNNING, //
+ STATE_ERROR, // generic bailout state
+ STATE_CLEANUP, // clean everything up
+ STATE_EXITING, // Tried to kill process, waiting for it to exit
+ STATE_DONE //
+
+ };
+ EState mState;
+ void setState(EState state);
+
+ bool pluginLockedUp();
+ bool pluginLockedUpOrQuit();
+
+ bool accept();
+
+ LLSocket::ptr_t mListenSocket;
+ LLSocket::ptr_t mSocket;
+ U32 mBoundPort;
+
+ LLProcessLauncher mProcess;
+
+ std::string mPluginFile;
+
+ LLPluginProcessParentOwner *mOwner;
+
+ typedef std::map<std::string, LLPluginSharedMemory*> sharedMemoryRegionsType;
+ sharedMemoryRegionsType mSharedMemoryRegions;
+
+ LLSD mMessageClassVersions;
+ std::string mPluginVersionString;
+
+ LLTimer mHeartbeat;
+ F64 mSleepTime;
+
+ bool mDisableTimeout;
+};
+
+#endif // LL_LLPLUGINPROCESSPARENT_H
diff --git a/indra/llplugin/llpluginsharedmemory.cpp b/indra/llplugin/llpluginsharedmemory.cpp
new file mode 100644
index 0000000000..ce8b8e3e09
--- /dev/null
+++ b/indra/llplugin/llpluginsharedmemory.cpp
@@ -0,0 +1,495 @@
+/**
+ * @file llpluginsharedmemory.cpp
+ * @brief LLPluginSharedMemory manages a shared memory segment for use by the LLPlugin API.
+ *
+ * $LicenseInfo:firstyear=2008&license=viewergpl$
+ *
+ * Copyright (c) 2008, Linden Research, Inc.
+ *
+ * Second Life Viewer Source Code
+ * The source code in this file ("Source Code") is provided by Linden Lab
+ * to you under the terms of the GNU General Public License, version 2.0
+ * ("GPL"), unless you have obtained a separate licensing agreement
+ * ("Other License"), formally executed by you and Linden Lab. Terms of
+ * the GPL can be found in doc/GPL-license.txt in this distribution, or
+ * online at http://secondlife.com/developers/opensource/gplv2
+ *
+ * There are special exceptions to the terms and conditions of the GPL as
+ * it is applied to this Source Code. View the full text of the exception
+ * in the file doc/FLOSS-exception.txt in this software distribution, or
+ * online at http://secondlife.com/developers/opensource/flossexception
+ *
+ * By copying, modifying or distributing this software, you acknowledge
+ * that you have read and understood your obligations described above,
+ * and agree to abide by those obligations.
+ *
+ * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+ * COMPLETENESS OR PERFORMANCE.
+ * $/LicenseInfo$
+ */
+
+#include "linden_common.h"
+
+#include "llpluginsharedmemory.h"
+
+// on Mac and Linux, we use the native shm_open/mmap interface by using
+// #define USE_SHM_OPEN_SHARED_MEMORY 1
+// in the appropriate sections below.
+
+// For Windows, use:
+// #define USE_WIN32_SHARED_MEMORY 1
+
+// If we ever want to fall back to the apr implementation for a platform, use:
+// #define USE_APR_SHARED_MEMORY 1
+
+#if LL_WINDOWS
+// #define USE_APR_SHARED_MEMORY 1
+ #define USE_WIN32_SHARED_MEMORY 1
+#elif LL_DARWIN
+ #define USE_SHM_OPEN_SHARED_MEMORY 1
+#elif LL_LINUX
+ #define USE_SHM_OPEN_SHARED_MEMORY 1
+#endif
+
+
+// FIXME: This path thing is evil and unacceptable.
+#if LL_WINDOWS
+ #define APR_SHARED_MEMORY_PREFIX_STRING "C:\\LLPlugin_"
+ // Apparnently using the "Global\\" prefix here only works from administrative accounts under Vista.
+ // Other options I've seen referenced are "Local\\" and "Session\\".
+ #define WIN32_SHARED_MEMORY_PREFIX_STRING "Local\\LL_"
+#else
+ // mac and linux
+ #define APR_SHARED_MEMORY_PREFIX_STRING "/tmp/LLPlugin_"
+ #define SHM_OPEN_SHARED_MEMORY_PREFIX_STRING "/LL"
+#endif
+
+#if USE_APR_SHARED_MEMORY
+ #include "llapr.h"
+ #include "apr_shm.h"
+#elif USE_SHM_OPEN_SHARED_MEMORY
+ #include <sys/fcntl.h>
+ #include <sys/mman.h>
+ #include <errno.h>
+#elif USE_WIN32_SHARED_MEMORY
+#include <windows.h>
+#endif // USE_APR_SHARED_MEMORY
+
+
+int LLPluginSharedMemory::sSegmentNumber = 0;
+
+std::string LLPluginSharedMemory::createName(void)
+{
+ std::stringstream newname;
+
+#if LL_WINDOWS
+ newname << GetCurrentProcessId();
+#else // LL_WINDOWS
+ newname << getpid();
+#endif // LL_WINDOWS
+
+ newname << "_" << sSegmentNumber++;
+
+ return newname.str();
+}
+
+class LLPluginSharedMemoryPlatformImpl
+{
+public:
+ LLPluginSharedMemoryPlatformImpl();
+ ~LLPluginSharedMemoryPlatformImpl();
+
+#if USE_APR_SHARED_MEMORY
+ apr_shm_t* mAprSharedMemory;
+#elif USE_SHM_OPEN_SHARED_MEMORY
+ int mSharedMemoryFD;
+#elif USE_WIN32_SHARED_MEMORY
+ HANDLE mMapFile;
+#endif
+
+};
+
+LLPluginSharedMemory::LLPluginSharedMemory()
+{
+ mSize = 0;
+ mMappedAddress = NULL;
+ mNeedsDestroy = false;
+
+ mImpl = new LLPluginSharedMemoryPlatformImpl;
+}
+
+LLPluginSharedMemory::~LLPluginSharedMemory()
+{
+ if(mNeedsDestroy)
+ destroy();
+ else
+ detach();
+
+ unlink();
+
+ delete mImpl;
+}
+
+#if USE_APR_SHARED_MEMORY
+// MARK: apr implementation
+
+LLPluginSharedMemoryPlatformImpl::LLPluginSharedMemoryPlatformImpl()
+{
+ mAprSharedMemory = NULL;
+}
+
+LLPluginSharedMemoryPlatformImpl::~LLPluginSharedMemoryPlatformImpl()
+{
+
+}
+
+bool LLPluginSharedMemory::map(void)
+{
+ mMappedAddress = apr_shm_baseaddr_get(mImpl->mAprSharedMemory);
+ if(mMappedAddress == NULL)
+ {
+ return false;
+ }
+
+ return true;
+}
+
+bool LLPluginSharedMemory::unmap(void)
+{
+ // This is a no-op under apr.
+ return true;
+}
+
+bool LLPluginSharedMemory::close(void)
+{
+ // This is a no-op under apr.
+ return true;
+}
+
+bool LLPluginSharedMemory::unlink(void)
+{
+ // This is a no-op under apr.
+ return true;
+}
+
+
+bool LLPluginSharedMemory::create(size_t size)
+{
+ mName = APR_SHARED_MEMORY_PREFIX_STRING;
+ mName += createName();
+ mSize = size;
+
+ apr_status_t status = apr_shm_create( &(mImpl->mAprSharedMemory), mSize, mName.c_str(), gAPRPoolp );
+
+ if(ll_apr_warn_status(status))
+ {
+ return false;
+ }
+
+ mNeedsDestroy = true;
+
+ return map();
+}
+
+bool LLPluginSharedMemory::destroy(void)
+{
+ if(mImpl->mAprSharedMemory)
+ {
+ apr_status_t status = apr_shm_destroy(mImpl->mAprSharedMemory);
+ if(ll_apr_warn_status(status))
+ {
+ // TODO: Is this a fatal error? I think not...
+ }
+ mImpl->mAprSharedMemory = NULL;
+ }
+
+ return true;
+}
+
+bool LLPluginSharedMemory::attach(const std::string &name, size_t size)
+{
+ mName = name;
+ mSize = size;
+
+ apr_status_t status = apr_shm_attach( &(mImpl->mAprSharedMemory), mName.c_str(), gAPRPoolp );
+
+ if(ll_apr_warn_status(status))
+ {
+ return false;
+ }
+
+ return map();
+}
+
+
+bool LLPluginSharedMemory::detach(void)
+{
+ if(mImpl->mAprSharedMemory)
+ {
+ apr_status_t status = apr_shm_detach(mImpl->mAprSharedMemory);
+ if(ll_apr_warn_status(status))
+ {
+ // TODO: Is this a fatal error? I think not...
+ }
+ mImpl->mAprSharedMemory = NULL;
+ }
+
+ return true;
+}
+
+
+#elif USE_SHM_OPEN_SHARED_MEMORY
+// MARK: shm_open/mmap implementation
+
+LLPluginSharedMemoryPlatformImpl::LLPluginSharedMemoryPlatformImpl()
+{
+ mSharedMemoryFD = -1;
+}
+
+LLPluginSharedMemoryPlatformImpl::~LLPluginSharedMemoryPlatformImpl()
+{
+}
+
+bool LLPluginSharedMemory::map(void)
+{
+ mMappedAddress = ::mmap(NULL, mSize, PROT_READ | PROT_WRITE, MAP_SHARED, mImpl->mSharedMemoryFD, 0);
+ if(mMappedAddress == NULL)
+ {
+ return false;
+ }
+
+ LL_DEBUGS("Plugin") << "memory mapped at " << mMappedAddress << LL_ENDL;
+
+ return true;
+}
+
+bool LLPluginSharedMemory::unmap(void)
+{
+ if(mMappedAddress != NULL)
+ {
+ LL_DEBUGS("Plugin") << "calling munmap(" << mMappedAddress << ", " << mSize << ")" << LL_ENDL;
+ if(::munmap(mMappedAddress, mSize) == -1)
+ {
+ // TODO: Is this a fatal error? I think not...
+ }
+
+ mMappedAddress = NULL;
+ }
+
+ return true;
+}
+
+bool LLPluginSharedMemory::close(void)
+{
+ if(mImpl->mSharedMemoryFD != -1)
+ {
+ LL_DEBUGS("Plugin") << "calling close(" << mImpl->mSharedMemoryFD << ")" << LL_ENDL;
+ if(::close(mImpl->mSharedMemoryFD) == -1)
+ {
+ // TODO: Is this a fatal error? I think not...
+ }
+
+ mImpl->mSharedMemoryFD = -1;
+ }
+ return true;
+}
+
+bool LLPluginSharedMemory::unlink(void)
+{
+ if(!mName.empty())
+ {
+ if(::shm_unlink(mName.c_str()) == -1)
+ {
+ return false;
+ }
+ }
+
+ return true;
+}
+
+
+bool LLPluginSharedMemory::create(size_t size)
+{
+ mName = SHM_OPEN_SHARED_MEMORY_PREFIX_STRING;
+ mName += createName();
+ mSize = size;
+
+ // Preemptive unlink, just in case something didn't get cleaned up.
+ unlink();
+
+ mImpl->mSharedMemoryFD = ::shm_open(mName.c_str(), O_CREAT | O_RDWR, S_IRUSR | S_IWUSR);
+ if(mImpl->mSharedMemoryFD == -1)
+ {
+ return false;
+ }
+
+ mNeedsDestroy = true;
+
+ if(::ftruncate(mImpl->mSharedMemoryFD, mSize) == -1)
+ {
+ return false;
+ }
+
+
+ return map();
+}
+
+bool LLPluginSharedMemory::destroy(void)
+{
+ unmap();
+ close();
+
+ return true;
+}
+
+
+bool LLPluginSharedMemory::attach(const std::string &name, size_t size)
+{
+ mName = name;
+ mSize = size;
+
+ mImpl->mSharedMemoryFD = ::shm_open(mName.c_str(), O_RDWR, S_IRUSR | S_IWUSR);
+ if(mImpl->mSharedMemoryFD == -1)
+ {
+ return false;
+ }
+
+ // unlink here so the segment will be cleaned up automatically after the last close.
+ unlink();
+
+ return map();
+}
+
+bool LLPluginSharedMemory::detach(void)
+{
+ unmap();
+ close();
+ return true;
+}
+
+#elif USE_WIN32_SHARED_MEMORY
+// MARK: Win32 CreateFileMapping-based implementation
+
+// Reference: http://msdn.microsoft.com/en-us/library/aa366551(VS.85).aspx
+
+LLPluginSharedMemoryPlatformImpl::LLPluginSharedMemoryPlatformImpl()
+{
+ mMapFile = NULL;
+}
+
+LLPluginSharedMemoryPlatformImpl::~LLPluginSharedMemoryPlatformImpl()
+{
+
+}
+
+bool LLPluginSharedMemory::map(void)
+{
+ mMappedAddress = MapViewOfFile(
+ mImpl->mMapFile, // handle to map object
+ FILE_MAP_ALL_ACCESS, // read/write permission
+ 0,
+ 0,
+ mSize);
+
+ if(mMappedAddress == NULL)
+ {
+ LL_WARNS("Plugin") << "MapViewOfFile failed: " << GetLastError() << LL_ENDL;
+ return false;
+ }
+
+ LL_DEBUGS("Plugin") << "memory mapped at " << mMappedAddress << LL_ENDL;
+
+ return true;
+}
+
+bool LLPluginSharedMemory::unmap(void)
+{
+ if(mMappedAddress != NULL)
+ {
+ UnmapViewOfFile(mMappedAddress);
+ mMappedAddress = NULL;
+ }
+
+ return true;
+}
+
+bool LLPluginSharedMemory::close(void)
+{
+ if(mImpl->mMapFile != NULL)
+ {
+ CloseHandle(mImpl->mMapFile);
+ mImpl->mMapFile = NULL;
+ }
+
+ return true;
+}
+
+bool LLPluginSharedMemory::unlink(void)
+{
+ // This is a no-op on Windows.
+ return true;
+}
+
+
+bool LLPluginSharedMemory::create(size_t size)
+{
+ mName = WIN32_SHARED_MEMORY_PREFIX_STRING;
+ mName += createName();
+ mSize = size;
+
+ mImpl->mMapFile = CreateFileMappingA(
+ INVALID_HANDLE_VALUE, // use paging file
+ NULL, // default security
+ PAGE_READWRITE, // read/write access
+ 0, // max. object size
+ mSize, // buffer size
+ mName.c_str()); // name of mapping object
+
+ if(mImpl->mMapFile == NULL)
+ {
+ LL_WARNS("Plugin") << "CreateFileMapping failed: " << GetLastError() << LL_ENDL;
+ return false;
+ }
+
+ mNeedsDestroy = true;
+
+ return map();
+}
+
+bool LLPluginSharedMemory::destroy(void)
+{
+ unmap();
+ close();
+ return true;
+}
+
+bool LLPluginSharedMemory::attach(const std::string &name, size_t size)
+{
+ mName = name;
+ mSize = size;
+
+ mImpl->mMapFile = OpenFileMappingA(
+ FILE_MAP_ALL_ACCESS, // read/write access
+ FALSE, // do not inherit the name
+ mName.c_str()); // name of mapping object
+
+ if(mImpl->mMapFile == NULL)
+ {
+ LL_WARNS("Plugin") << "OpenFileMapping failed: " << GetLastError() << LL_ENDL;
+ return false;
+ }
+
+ return map();
+}
+
+bool LLPluginSharedMemory::detach(void)
+{
+ unmap();
+ close();
+ return true;
+}
+
+
+
+#endif
diff --git a/indra/llplugin/llpluginsharedmemory.h b/indra/llplugin/llpluginsharedmemory.h
new file mode 100644
index 0000000000..a4613b9a54
--- /dev/null
+++ b/indra/llplugin/llpluginsharedmemory.h
@@ -0,0 +1,79 @@
+/**
+ * @file llpluginsharedmemory.h
+ * @brief LLPluginSharedMemory manages a shared memory segment for use by the LLPlugin API.
+ *
+ * $LicenseInfo:firstyear=2008&license=viewergpl$
+ *
+ * Copyright (c) 2008, Linden Research, Inc.
+ *
+ * Second Life Viewer Source Code
+ * The source code in this file ("Source Code") is provided by Linden Lab
+ * to you under the terms of the GNU General Public License, version 2.0
+ * ("GPL"), unless you have obtained a separate licensing agreement
+ * ("Other License"), formally executed by you and Linden Lab. Terms of
+ * the GPL can be found in doc/GPL-license.txt in this distribution, or
+ * online at http://secondlife.com/developers/opensource/gplv2
+ *
+ * There are special exceptions to the terms and conditions of the GPL as
+ * it is applied to this Source Code. View the full text of the exception
+ * in the file doc/FLOSS-exception.txt in this software distribution, or
+ * online at http://secondlife.com/developers/opensource/flossexception
+ *
+ * By copying, modifying or distributing this software, you acknowledge
+ * that you have read and understood your obligations described above,
+ * and agree to abide by those obligations.
+ *
+ * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+ * COMPLETENESS OR PERFORMANCE.
+ * $/LicenseInfo$
+ */
+
+#ifndef LL_LLPLUGINSHAREDMEMORY_H
+#define LL_LLPLUGINSHAREDMEMORY_H
+
+class LLPluginSharedMemoryPlatformImpl;
+
+class LLPluginSharedMemory
+{
+ LOG_CLASS(LLPluginSharedMemory);
+public:
+ LLPluginSharedMemory();
+ ~LLPluginSharedMemory();
+
+ // Parent will use create/destroy, child will use attach/detach.
+ // Message transactions will ensure child attaches after parent creates and detaches before parent destroys.
+
+ // create() implicitly creates a name for the segment which is guaranteed to be unique on the host at the current time.
+ bool create(size_t size);
+ bool destroy(void);
+
+ bool attach(const std::string &name, size_t size);
+ bool detach(void);
+
+ bool isMapped(void) const { return (mMappedAddress != NULL); };
+ void *getMappedAddress(void) const { return mMappedAddress; };
+ size_t getSize(void) const { return mSize; };
+ std::string getName() const { return mName; };
+
+private:
+ bool map(void);
+ bool unmap(void);
+ bool close(void);
+ bool unlink(void);
+
+ std::string mName;
+ size_t mSize;
+ void *mMappedAddress;
+ bool mNeedsDestroy;
+
+ LLPluginSharedMemoryPlatformImpl *mImpl;
+
+ static int sSegmentNumber;
+ static std::string createName();
+
+};
+
+
+
+#endif // LL_LLPLUGINSHAREDMEMORY_H
diff --git a/indra/llplugin/slplugin/CMakeLists.txt b/indra/llplugin/slplugin/CMakeLists.txt
new file mode 100644
index 0000000000..4a7d670c23
--- /dev/null
+++ b/indra/llplugin/slplugin/CMakeLists.txt
@@ -0,0 +1,55 @@
+project(SLPlugin)
+
+include(00-Common)
+include(LLCommon)
+include(LLPlugin)
+include(Linking)
+include(PluginAPI)
+include(LLMessage)
+
+include_directories(
+ ${LLPLUGIN_INCLUDE_DIRS}
+ ${LLMESSAGE_INCLUDE_DIRS}
+ ${LLCOMMON_INCLUDE_DIRS}
+)
+
+if (DARWIN)
+ include(CMakeFindFrameworks)
+ find_library(CARBON_LIBRARY Carbon)
+endif (DARWIN)
+
+
+### SLPlugin
+
+set(SLPlugin_SOURCE_FILES
+ slplugin.cpp
+ )
+
+add_executable(SLPlugin
+ WIN32
+ ${SLPlugin_SOURCE_FILES}
+)
+
+target_link_libraries(SLPlugin
+ ${LLPLUGIN_LIBRARIES}
+ ${LLMESSAGE_LIBRARIES}
+ ${LLCOMMON_LIBRARIES}
+ ${PLUGIN_API_WINDOWS_LIBRARIES}
+)
+
+add_dependencies(SLPlugin
+ ${LLPLUGIN_LIBRARIES}
+ ${LLMESSAGE_LIBRARIES}
+ ${LLCOMMON_LIBRARIES}
+)
+
+if (DARWIN)
+ # Mac version needs to link against carbon, and also needs an embedded plist (to set LSBackgroundOnly)
+ target_link_libraries(SLPlugin ${CARBON_LIBRARY})
+ set_target_properties(
+ SLPlugin
+ PROPERTIES
+ LINK_FLAGS "-Wl,-sectcreate,__TEXT,__info_plist,${CMAKE_CURRENT_SOURCE_DIR}/slplugin_info.plist"
+ )
+endif (DARWIN)
+
diff --git a/indra/llplugin/slplugin/slplugin.cpp b/indra/llplugin/slplugin/slplugin.cpp
new file mode 100644
index 0000000000..005e427572
--- /dev/null
+++ b/indra/llplugin/slplugin/slplugin.cpp
@@ -0,0 +1,243 @@
+/**
+ * @file slplugin.cpp
+ * @brief Loader shell for plugins, intended to be launched by the plugin host application, which directly loads a plugin dynamic library.
+ *
+ * $LicenseInfo:firstyear=2008&license=viewergpl$
+ *
+ * Copyright (c) 2008, Linden Research, Inc.
+ *
+ * Second Life Viewer Source Code
+ * The source code in this file ("Source Code") is provided by Linden Lab
+ * to you under the terms of the GNU General Public License, version 2.0
+ * ("GPL"), unless you have obtained a separate licensing agreement
+ * ("Other License"), formally executed by you and Linden Lab. Terms of
+ * the GPL can be found in doc/GPL-license.txt in this distribution, or
+ * online at http://secondlife.com/developers/opensource/gplv2
+ *
+ * There are special exceptions to the terms and conditions of the GPL as
+ * it is applied to this Source Code. View the full text of the exception
+ * in the file doc/FLOSS-exception.txt in this software distribution, or
+ * online at http://secondlife.com/developers/opensource/flossexception
+ *
+ * By copying, modifying or distributing this software, you acknowledge
+ * that you have read and understood your obligations described above,
+ * and agree to abide by those obligations.
+ *
+ * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+ * COMPLETENESS OR PERFORMANCE.
+ * $/LicenseInfo$
+ */
+
+
+#include "linden_common.h"
+
+#include "llpluginprocesschild.h"
+#include "llpluginmessage.h"
+#include "llerrorcontrol.h"
+#include "llapr.h"
+#include "llstring.h"
+
+#if LL_DARWIN
+ #include <Carbon/Carbon.h>
+#endif
+
+#if LL_DARWIN || LL_LINUX
+ #include <signal.h>
+#endif
+
+/*
+ On Mac OS, since we call WaitNextEvent, this process will show up in the dock unless we set the LSBackgroundOnly flag in the Info.plist.
+
+ Normally non-bundled binaries don't have an info.plist file, but it's possible to embed one in the binary by adding this to the linker flags:
+
+ -sectcreate __TEXT __info_plist /path/to/slplugin_info.plist
+
+ which means adding this to the gcc flags:
+
+ -Wl,-sectcreate,__TEXT,__info_plist,/path/to/slplugin_info.plist
+
+*/
+
+#if LL_DARWIN || LL_LINUX
+// Signal handlers to make crashes not show an OS dialog...
+static void crash_handler(int sig)
+{
+ // Just exit cleanly.
+ // TODO: add our own crash reporting
+ _exit(1);
+}
+#endif
+
+#if LL_WINDOWS
+#include <windows.h>
+////////////////////////////////////////////////////////////////////////////////
+// Our exception handler - will probably just exit and the host application
+// will miss the heartbeat and log the error in the usual fashion.
+LONG WINAPI myWin32ExceptionHandler( struct _EXCEPTION_POINTERS* exception_infop )
+{
+ //std::cerr << "This plugin (" << __FILE__ << ") - ";
+ //std::cerr << "intercepted an unhandled exception and will exit immediately." << std::endl;
+
+ // TODO: replace exception handler before we exit?
+ return EXCEPTION_EXECUTE_HANDLER;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// Hook our exception handler and replace the system one
+void initExceptionHandler()
+{
+ LPTOP_LEVEL_EXCEPTION_FILTER prev_filter;
+
+ // save old exception handler in case we need to restore it at the end
+ prev_filter = SetUnhandledExceptionFilter( myWin32ExceptionHandler );
+}
+
+bool checkExceptionHandler()
+{
+ bool ok = true;
+ LPTOP_LEVEL_EXCEPTION_FILTER prev_filter;
+ prev_filter = SetUnhandledExceptionFilter(myWin32ExceptionHandler);
+
+ if (prev_filter != myWin32ExceptionHandler)
+ {
+ LL_WARNS("AppInit") << "Our exception handler (" << (void *)myWin32ExceptionHandler << ") replaced with " << prev_filter << "!" << LL_ENDL;
+ ok = false;
+ }
+
+ if (prev_filter == NULL)
+ {
+ ok = FALSE;
+ if (myWin32ExceptionHandler == NULL)
+ {
+ LL_WARNS("AppInit") << "Exception handler uninitialized." << LL_ENDL;
+ }
+ else
+ {
+ LL_WARNS("AppInit") << "Our exception handler (" << (void *)myWin32ExceptionHandler << ") replaced with NULL!" << LL_ENDL;
+ }
+ }
+
+ return ok;
+}
+#endif
+
+// If this application on Windows platform is a console application, a console is always
+// created which is bad. Making it a Windows "application" via CMake settings but not
+// adding any code to explicitly create windows does the right thing.
+#if LL_WINDOWS
+int APIENTRY WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow )
+#else
+int main(int argc, char **argv)
+#endif
+{
+ ll_init_apr();
+
+ // Set up llerror logging
+ {
+ LLError::initForApplication(".");
+ LLError::setDefaultLevel(LLError::LEVEL_INFO);
+// LLError::setTagLevel("Plugin", LLError::LEVEL_DEBUG);
+// LLError::logToFile("slplugin.log");
+ }
+
+#if LL_WINDOWS
+ if( strlen( lpCmdLine ) == 0 )
+ {
+ LL_ERRS("slplugin") << "usage: " << "SLPlugin" << " launcher_port" << LL_ENDL;
+ };
+
+ U32 port = 0;
+ if(!LLStringUtil::convertToU32(lpCmdLine, port))
+ {
+ LL_ERRS("slplugin") << "port number must be numeric" << LL_ENDL;
+ };
+
+ // Insert our exception handler into the system so this plugin doesn't
+ // display a crash message if something bad happens. The host app will
+ // see the missing heartbeat and log appropriately.
+ initExceptionHandler();
+#elif LL_DARWIN || LL_LINUX
+ if(argc < 2)
+ {
+ LL_ERRS("slplugin") << "usage: " << argv[0] << " launcher_port" << LL_ENDL;
+ }
+
+ U32 port = 0;
+ if(!LLStringUtil::convertToU32(argv[1], port))
+ {
+ LL_ERRS("slplugin") << "port number must be numeric" << LL_ENDL;
+ }
+
+ // Catch signals that most kinds of crashes will generate, and exit cleanly so the system crash dialog isn't shown.
+ signal(SIGILL, &crash_handler); // illegal instruction
+# if LL_DARWIN
+ signal(SIGEMT, &crash_handler); // emulate instruction executed
+# endif // LL_DARWIN
+ signal(SIGFPE, &crash_handler); // floating-point exception
+ signal(SIGBUS, &crash_handler); // bus error
+ signal(SIGSEGV, &crash_handler); // segmentation violation
+ signal(SIGSYS, &crash_handler); // non-existent system call invoked
+#endif
+
+ LLPluginProcessChild *plugin = new LLPluginProcessChild();
+
+ plugin->init(port);
+
+ LLTimer timer;
+ timer.start();
+
+#if LL_WINDOWS
+ checkExceptionHandler();
+#endif
+
+ while(!plugin->isDone())
+ {
+ timer.reset();
+ plugin->idle();
+#if LL_DARWIN
+ {
+ // Some plugins (webkit at least) will want an event loop. This qualifies.
+ EventRecord evt;
+ WaitNextEvent(0, &evt, 0, NULL);
+ }
+#endif
+ F64 elapsed = timer.getElapsedTimeF64();
+ F64 remaining = plugin->getSleepTime() - elapsed;
+
+ if(remaining <= 0.0f)
+ {
+ // We've already used our full allotment.
+// LL_INFOS("slplugin") << "elapsed = " << elapsed * 1000.0f << " ms, remaining = " << remaining * 1000.0f << " ms, not sleeping" << LL_ENDL;
+
+ // Still need to service the network...
+ plugin->pump();
+ }
+ else
+ {
+
+// LL_INFOS("slplugin") << "elapsed = " << elapsed * 1000.0f << " ms, remaining = " << remaining * 1000.0f << " ms, sleeping for " << remaining * 1000.0f << " ms" << LL_ENDL;
+// timer.reset();
+
+ // This also services the network as needed.
+ plugin->sleep(remaining);
+
+// LL_INFOS("slplugin") << "slept for "<< timer.getElapsedTimeF64() * 1000.0f << " ms" << LL_ENDL;
+ }
+
+#if LL_WINDOWS
+ // More agressive checking of interfering exception handlers.
+ // Doesn't appear to be required so far - even for plugins
+ // that do crash with a single call to the intercept
+ // exception handler such as QuickTime.
+ //checkExceptionHandler();
+#endif
+ }
+
+ delete plugin;
+
+ ll_cleanup_apr();
+
+ return 0;
+}
+
diff --git a/indra/llplugin/slplugin/slplugin_info.plist b/indra/llplugin/slplugin/slplugin_info.plist
new file mode 100644
index 0000000000..b1daf87424
--- /dev/null
+++ b/indra/llplugin/slplugin/slplugin_info.plist
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+ <key>CFBundleDevelopmentRegion</key>
+ <string>English</string>
+ <key>CFBundleInfoDictionaryVersion</key>
+ <string>6.0</string>
+ <key>LSBackgroundOnly</key>
+ <true/>
+</dict>
+</plist>
diff --git a/indra/llprimitive/llmaterialtable.cpp b/indra/llprimitive/llmaterialtable.cpp
index 4c22203eb9..18787c47c5 100644
--- a/indra/llprimitive/llmaterialtable.cpp
+++ b/indra/llprimitive/llmaterialtable.cpp
@@ -124,6 +124,17 @@ LLMaterialTable::~LLMaterialTable()
mMaterialInfoList.clear();
}
+void LLMaterialTable::initTableTransNames(std::map<std::string, std::string> namemap)
+{
+ for (info_list_t::iterator iter = mMaterialInfoList.begin();
+ iter != mMaterialInfoList.end(); ++iter)
+ {
+ LLMaterialInfo *infop = *iter;
+ std::string name = infop->mName;
+ infop->mName = namemap[name];
+ }
+}
+
void LLMaterialTable::initBasicTable()
{
// *TODO: Translate
diff --git a/indra/llprimitive/llmaterialtable.h b/indra/llprimitive/llmaterialtable.h
index ca9017abd0..2c0b046fa7 100644
--- a/indra/llprimitive/llmaterialtable.h
+++ b/indra/llprimitive/llmaterialtable.h
@@ -147,6 +147,8 @@ public:
void initBasicTable();
+ void initTableTransNames(std::map<std::string, std::string> namemap);
+
BOOL add(U8 mcode, const std::string& name, const LLUUID &uuid);
BOOL addCollisionSound(U8 mcode, U8 mcode2, const LLUUID &uuid);
BOOL addSlidingSound(U8 mcode, U8 mcode2, const LLUUID &uuid);
diff --git a/indra/llprimitive/llprimitive.cpp b/indra/llprimitive/llprimitive.cpp
index 7b755a7d17..2177f5c365 100644
--- a/indra/llprimitive/llprimitive.cpp
+++ b/indra/llprimitive/llprimitive.cpp
@@ -132,7 +132,7 @@ void LLPrimitive::setVolumeManager( LLVolumeMgr* volume_manager )
{
if ( !volume_manager || sVolumeManager )
{
- llerrs << "Unable to set LLPrimitive::sVolumeManager to NULL" << llendl;
+ llerrs << "LLPrimitive::sVolumeManager attempting to be set to NULL or it already has been set." << llendl;
}
sVolumeManager = volume_manager;
}
diff --git a/indra/llprimitive/llprimitive.h b/indra/llprimitive/llprimitive.h
index 01389a0e04..53095cc925 100644
--- a/indra/llprimitive/llprimitive.h
+++ b/indra/llprimitive/llprimitive.h
@@ -37,7 +37,7 @@
#include "v3math.h"
#include "xform.h"
#include "message.h"
-#include "llmemory.h"
+#include "llpointer.h"
#include "llvolume.h"
#include "lltextureentry.h"
#include "llprimtexturelist.h"
diff --git a/indra/llprimitive/llprimtexturelist.cpp b/indra/llprimitive/llprimtexturelist.cpp
index b02d4c50bd..1c7de95975 100644
--- a/indra/llprimitive/llprimtexturelist.cpp
+++ b/indra/llprimitive/llprimtexturelist.cpp
@@ -4,7 +4,7 @@
*
* $LicenseInfo:firstyear=2008&license=viewergpl$
*
- * Copyright (c) 2008-2007, Linden Research, Inc.
+ * Copyright (c) 2008-2009, Linden Research, Inc.
*
* Second Life Viewer Source Code
* The source code in this file ("Source Code") is provided by Linden Lab
@@ -12,12 +12,13 @@
* ("GPL"), unless you have obtained a separate licensing agreement
* ("Other License"), formally executed by you and Linden Lab. Terms of
* the GPL can be found in doc/GPL-license.txt in this distribution, or
- * online at http://secondlife.com/developers/opensource/gplv2
+ * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
*
* There are special exceptions to the terms and conditions of the GPL as
* it is applied to this Source Code. View the full text of the exception
* in the file doc/FLOSS-exception.txt in this software distribution, or
- * online at http://secondlife.com/developers/opensource/flossexception
+ * online at
+ * http://secondlifegrid.net/programs/open_source/licensing/flossexception
*
* By copying, modifying or distributing this software, you acknowledge
* that you have read and understood your obligations described above,
diff --git a/indra/llprimitive/llprimtexturelist.h b/indra/llprimitive/llprimtexturelist.h
index 61285bd1bf..6254878b99 100644
--- a/indra/llprimitive/llprimtexturelist.h
+++ b/indra/llprimitive/llprimtexturelist.h
@@ -4,7 +4,7 @@
*
* $LicenseInfo:firstyear=2008&license=viewergpl$
*
- * Copyright (c) 2008-2007, Linden Research, Inc.
+ * Copyright (c) 2008-2009, Linden Research, Inc.
*
* Second Life Viewer Source Code
* The source code in this file ("Source Code") is provided by Linden Lab
@@ -12,12 +12,13 @@
* ("GPL"), unless you have obtained a separate licensing agreement
* ("Other License"), formally executed by you and Linden Lab. Terms of
* the GPL can be found in doc/GPL-license.txt in this distribution, or
- * online at http://secondlife.com/developers/opensource/gplv2
+ * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
*
* There are special exceptions to the terms and conditions of the GPL as
* it is applied to this Source Code. View the full text of the exception
* in the file doc/FLOSS-exception.txt in this software distribution, or
- * online at http://secondlife.com/developers/opensource/flossexception
+ * online at
+ * http://secondlifegrid.net/programs/open_source/licensing/flossexception
*
* By copying, modifying or distributing this software, you acknowledge
* that you have read and understood your obligations described above,
diff --git a/indra/llprimitive/tests/llmessagesystem_stub.cpp b/indra/llprimitive/tests/llmessagesystem_stub.cpp
new file mode 100644
index 0000000000..62504be3b0
--- /dev/null
+++ b/indra/llprimitive/tests/llmessagesystem_stub.cpp
@@ -0,0 +1,42 @@
+/**
+ * @file llmessagesystem_stub.cpp
+ * @brief stub class to allow unit testing
+ *
+ * $LicenseInfo:firstyear=2008&license=internal$
+ *
+ * Copyright (c) 2008, Linden Research, Inc.
+ *
+ * The following source code is PROPRIETARY AND CONFIDENTIAL. Use of
+ * this source code is governed by the Linden Lab Source Code Disclosure
+ * Agreement ("Agreement") { }
+ * Lab. By accessing, using, copying, modifying or distributing this
+ * software, you acknowledge that you have been informed of your
+ * obligations under the Agreement and agree to abide by those obligations.
+ *
+ * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+ * COMPLETENESS OR PERFORMANCE.
+ * $/LicenseInfo$
+ */
+#include "linden_common.h"
+
+char * _PREHASH_TextureEntry;
+
+S32 LLMessageSystem::getSizeFast(char const*, char const*) const
+{
+ return 0;
+}
+
+S32 LLMessageSystem::getSizeFast(char const*, int, char const*) const
+{
+ return 0;
+}
+
+void LLMessageSystem::getBinaryDataFast(char const*, char const*, void*, int, int, int)
+{
+}
+
+void LLMessageSystem::addBinaryDataFast(char const*, void const*, int)
+{
+}
+
diff --git a/indra/llprimitive/tests/llprimitive_test.cpp b/indra/llprimitive/tests/llprimitive_test.cpp
new file mode 100644
index 0000000000..1805a9e968
--- /dev/null
+++ b/indra/llprimitive/tests/llprimitive_test.cpp
@@ -0,0 +1,214 @@
+/**
+ * @file llprimitive_test.cpp
+ * @brief llprimitive tests
+ *
+ * $LicenseInfo:firstyear=2001&license=viewergpl$
+ * Copyright (c) 2001-2009, Linden Research, Inc.
+ * $/LicenseInfo$
+ */
+
+#include "linden_common.h"
+
+#include "../test/lltut.h"
+
+#include "../llprimitive.h"
+
+#include "../../llmath/llvolumemgr.h"
+
+class DummyVolumeMgr : public LLVolumeMgr
+{
+public:
+ DummyVolumeMgr() : LLVolumeMgr(), mVolumeTest(NULL), mCurrDetailTest(0) {}
+ ~DummyVolumeMgr()
+ {
+ }
+
+
+ virtual LLVolume *refVolume(const LLVolumeParams &volume_params, const S32 detail)
+ {
+ if (mVolumeTest.isNull() || volume_params != mCurrParamsTest || detail != mCurrDetailTest)
+ {
+ F32 volume_detail = LLVolumeLODGroup::getVolumeScaleFromDetail(detail);
+ mVolumeTest = new LLVolume(volume_params, volume_detail, FALSE, FALSE);
+ mCurrParamsTest = volume_params;
+ mCurrDetailTest = detail;
+ return mVolumeTest;
+ }
+ else
+ {
+ return mVolumeTest;
+ }
+ }
+
+ virtual void unrefVolume(LLVolume *volumep)
+ {
+ if (mVolumeTest == volumep)
+ {
+ mVolumeTest = NULL;
+ }
+ }
+
+private:
+ LLPointer<LLVolume> mVolumeTest;
+ LLVolumeParams mCurrParamsTest;
+ S32 mCurrDetailTest;
+};
+
+class PRIMITIVE_TEST_SETUP
+{
+public:
+ PRIMITIVE_TEST_SETUP()
+ {
+ volume_manager_test = new DummyVolumeMgr();
+ LLPrimitive::setVolumeManager(volume_manager_test);
+ }
+
+ ~PRIMITIVE_TEST_SETUP()
+ {
+ LLPrimitive::cleanupVolumeManager();
+ }
+ DummyVolumeMgr * volume_manager_test;
+};
+
+namespace tut
+{
+ struct llprimitive
+ {
+ PRIMITIVE_TEST_SETUP setup_class;
+ };
+
+ typedef test_group<llprimitive> llprimitive_t;
+ typedef llprimitive_t::object llprimitive_object_t;
+ tut::llprimitive_t tut_llprimitive("llprimitive");
+
+ template<> template<>
+ void llprimitive_object_t::test<1>()
+ {
+ set_test_name("Test LLPrimitive Instantiation");
+ LLPrimitive test;
+ }
+
+ template<> template<>
+ void llprimitive_object_t::test<2>()
+ {
+ set_test_name("Test LLPrimitive PCode setter and getter.");
+ LLPrimitive test;
+ ensure_equals(test.getPCode(), 0);
+ LLPCode code = 1;
+ test.setPCode(code);
+ ensure_equals(test.getPCode(), code);
+ }
+
+ template<> template<>
+ void llprimitive_object_t::test<3>()
+ {
+ set_test_name("Test llprimitive constructor and initer.");
+ LLPCode code = 1;
+ LLPrimitive primitive;
+ primitive.init_primitive(code);
+ ensure_equals(primitive.getPCode(), code);
+ }
+
+ template<> template<>
+ void llprimitive_object_t::test<4>()
+ {
+ set_test_name("Test Static llprimitive constructor and initer.");
+ LLPCode code = 1;
+ LLPrimitive * primitive = LLPrimitive::createPrimitive(code);
+ ensure(primitive != NULL);
+ ensure_equals(primitive->getPCode(), code);
+ }
+
+ template<> template<>
+ void llprimitive_object_t::test<5>()
+ {
+ set_test_name("Test setVolume creation of new unique volume.");
+ LLPrimitive primitive;
+ LLVolumeParams params;
+
+ // Make sure volume starts off null
+ ensure(primitive.getVolume() == NULL);
+
+ // Make sure we have no texture entries before setting the volume
+ ensure_equals(primitive.getNumTEs(), 0);
+
+ // Test that GEOMETRY has not been flagged as changed.
+ ensure(!primitive.isChanged(LLXform::GEOMETRY));
+
+ // Make sure setVolume returns true
+ ensure(primitive.setVolume(params, 0, true) == TRUE);
+ LLVolume* new_volume = primitive.getVolume();
+
+ // make sure new volume was actually created
+ ensure(new_volume != NULL);
+
+ // Make sure that now that we've set the volume we have texture entries
+ ensure_not_equals(primitive.getNumTEs(), 0);
+
+ // Make sure that the number of texture entries equals the number of faces in the volume (should be 6)
+ ensure_equals(new_volume->getNumFaces(), 6);
+ ensure_equals(primitive.getNumTEs(), new_volume->getNumFaces());
+
+ // Test that GEOMETRY has been flagged as changed.
+ ensure(primitive.isChanged(LLXform::GEOMETRY));
+
+ // Run it twice to make sure it doesn't create a different one if params are the same
+ ensure(primitive.setVolume(params, 0, true) == FALSE);
+ ensure(new_volume == primitive.getVolume());
+
+ // Change the param definition and try setting it again.
+ params.setRevolutions(4);
+ ensure(primitive.setVolume(params, 0, true) == TRUE);
+
+ // Ensure that we now have a different volume
+ ensure(new_volume != primitive.getVolume());
+ }
+
+ template<> template<>
+ void llprimitive_object_t::test<6>()
+ {
+ set_test_name("Test setVolume creation of new NOT-unique volume.");
+ LLPrimitive primitive;
+ LLVolumeParams params;
+
+ // Make sure volume starts off null
+ ensure(primitive.getVolume() == NULL);
+
+ // Make sure we have no texture entries before setting the volume
+ ensure_equals(primitive.getNumTEs(), 0);
+
+ // Test that GEOMETRY has not been flagged as changed.
+ ensure(!primitive.isChanged(LLXform::GEOMETRY));
+
+ // Make sure setVolume returns true
+ ensure(primitive.setVolume(params, 0, false) == TRUE);
+
+ LLVolume* new_volume = primitive.getVolume();
+
+ // make sure new volume was actually created
+ ensure(new_volume != NULL);
+
+ // Make sure that now that we've set the volume we have texture entries
+ ensure_not_equals(primitive.getNumTEs(), 0);
+
+ // Make sure that the number of texture entries equals the number of faces in the volume (should be 6)
+ ensure_equals(new_volume->getNumFaces(), 6);
+ ensure_equals(primitive.getNumTEs(), new_volume->getNumFaces());
+
+ // Test that GEOMETRY has been flagged as changed.
+ ensure(primitive.isChanged(LLXform::GEOMETRY));
+
+ // Run it twice to make sure it doesn't create a different one if params are the same
+ ensure(primitive.setVolume(params, 0, false) == FALSE);
+ ensure(new_volume == primitive.getVolume());
+
+ // Change the param definition and try setting it again.
+ params.setRevolutions(4);
+ ensure(primitive.setVolume(params, 0, false) == TRUE);
+
+ // Ensure that we now have a different volume
+ ensure(new_volume != primitive.getVolume());
+ }
+}
+
+#include "llmessagesystem_stub.cpp"
diff --git a/indra/llrender/CMakeLists.txt b/indra/llrender/CMakeLists.txt
index 0bb835970f..aac650bec9 100644
--- a/indra/llrender/CMakeLists.txt
+++ b/indra/llrender/CMakeLists.txt
@@ -26,7 +26,7 @@ include_directories(
set(llrender_SOURCE_FILES
llcubemap.cpp
- llfont.cpp
+ llfontfreetype.cpp
llfontgl.cpp
llfontbitmapcache.cpp
llfontregistry.cpp
@@ -36,6 +36,7 @@ set(llrender_SOURCE_FILES
llpostprocess.cpp
llrendersphere.cpp
llshadermgr.cpp
+ lltexture.cpp
llvertexbuffer.cpp
)
@@ -44,7 +45,7 @@ set(llrender_HEADER_FILES
llcubemap.h
llfontgl.h
- llfont.h
+ llfontfreetype.h
llfontbitmapcache.h
llfontregistry.h
llgl.h
@@ -58,6 +59,7 @@ set(llrender_HEADER_FILES
llrender.h
llrendersphere.h
llshadermgr.h
+ lltexture.h
llvertexbuffer.h
)
diff --git a/indra/llrender/llfontbitmapcache.cpp b/indra/llrender/llfontbitmapcache.cpp
index f6321b0534..052510e6ed 100644
--- a/indra/llrender/llfontbitmapcache.cpp
+++ b/indra/llrender/llfontbitmapcache.cpp
@@ -4,7 +4,7 @@
*
* $LicenseInfo:firstyear=2008&license=viewergpl$
*
- * Copyright (c) 2008, Linden Research, Inc.
+ * Copyright (c) 2008-2009, Linden Research, Inc.
*
* Second Life Viewer Source Code
* The source code in this file ("Source Code") is provided by Linden Lab
@@ -12,12 +12,13 @@
* ("GPL"), unless you have obtained a separate licensing agreement
* ("Other License"), formally executed by you and Linden Lab. Terms of
* the GPL can be found in doc/GPL-license.txt in this distribution, or
- * online at http://secondlife.com/developers/opensource/gplv2
+ * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
*
* There are special exceptions to the terms and conditions of the GPL as
* it is applied to this Source Code. View the full text of the exception
* in the file doc/FLOSS-exception.txt in this software distribution, or
- * online at http://secondlife.com/developers/opensource/flossexception
+ * online at
+ * http://secondlifegrid.net/programs/open_source/licensing/flossexception
*
* By copying, modifying or distributing this software, you acknowledge
* that you have read and understood your obligations described above,
diff --git a/indra/llrender/llfontbitmapcache.h b/indra/llrender/llfontbitmapcache.h
index e5c09f8826..4a57052b91 100644
--- a/indra/llrender/llfontbitmapcache.h
+++ b/indra/llrender/llfontbitmapcache.h
@@ -4,7 +4,7 @@
*
* $LicenseInfo:firstyear=2008&license=viewergpl$
*
- * Copyright (c) 2008, Linden Research, Inc.
+ * Copyright (c) 2008-2009, Linden Research, Inc.
*
* Second Life Viewer Source Code
* The source code in this file ("Source Code") is provided by Linden Lab
@@ -12,12 +12,13 @@
* ("GPL"), unless you have obtained a separate licensing agreement
* ("Other License"), formally executed by you and Linden Lab. Terms of
* the GPL can be found in doc/GPL-license.txt in this distribution, or
- * online at http://secondlife.com/developers/opensource/gplv2
+ * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
*
* There are special exceptions to the terms and conditions of the GPL as
* it is applied to this Source Code. View the full text of the exception
* in the file doc/FLOSS-exception.txt in this software distribution, or
- * online at http://secondlife.com/developers/opensource/flossexception
+ * online at
+ * http://secondlifegrid.net/programs/open_source/licensing/flossexception
*
* By copying, modifying or distributing this software, you acknowledge
* that you have read and understood your obligations described above,
@@ -35,7 +36,7 @@
#include <vector>
// Maintain a collection of bitmaps containing rendered glyphs.
-// Generalizes the single-bitmap logic from LLFont and LLFontGL.
+// Generalizes the single-bitmap logic from LLFontFreetype and LLFontGL.
class LLFontBitmapCache: public LLRefCount
{
public:
diff --git a/indra/llrender/llfontfreetype.cpp b/indra/llrender/llfontfreetype.cpp
new file mode 100644
index 0000000000..0be6bedbee
--- /dev/null
+++ b/indra/llrender/llfontfreetype.cpp
@@ -0,0 +1,644 @@
+/**
+ * @file llfontfreetype.cpp
+ * @brief Freetype font library wrapper
+ *
+ * $LicenseInfo:firstyear=2002&license=viewergpl$
+ *
+ * Copyright (c) 2002-2009, Linden Research, Inc.
+ *
+ * Second Life Viewer Source Code
+ * The source code in this file ("Source Code") is provided by Linden Lab
+ * to you under the terms of the GNU General Public License, version 2.0
+ * ("GPL"), unless you have obtained a separate licensing agreement
+ * ("Other License"), formally executed by you and Linden Lab. Terms of
+ * the GPL can be found in doc/GPL-license.txt in this distribution, or
+ * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
+ *
+ * There are special exceptions to the terms and conditions of the GPL as
+ * it is applied to this Source Code. View the full text of the exception
+ * in the file doc/FLOSS-exception.txt in this software distribution, or
+ * online at
+ * http://secondlifegrid.net/programs/open_source/licensing/flossexception
+ *
+ * By copying, modifying or distributing this software, you acknowledge
+ * that you have read and understood your obligations described above,
+ * and agree to abide by those obligations.
+ *
+ * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+ * COMPLETENESS OR PERFORMANCE.
+ * $/LicenseInfo$
+ */
+
+#include "linden_common.h"
+
+#include "llfontfreetype.h"
+#include "llfontgl.h"
+
+// Freetype stuff
+#include <ft2build.h>
+
+// For some reason, this won't work if it's not wrapped in the ifdef
+#ifdef FT_FREETYPE_H
+#include FT_FREETYPE_H
+#endif
+
+#include "llerror.h"
+#include "llimage.h"
+//#include "llimagej2c.h"
+#include "llmath.h" // Linden math
+#include "llstring.h"
+//#include "imdebug.h"
+#include "llfontbitmapcache.h"
+#include "llgl.h"
+
+FT_Render_Mode gFontRenderMode = FT_RENDER_MODE_NORMAL;
+
+LLFontManager *gFontManagerp = NULL;
+
+FT_Library gFTLibrary = NULL;
+
+//static
+void LLFontManager::initClass()
+{
+ gFontManagerp = new LLFontManager;
+}
+
+//static
+void LLFontManager::cleanupClass()
+{
+ delete gFontManagerp;
+ gFontManagerp = NULL;
+}
+
+LLFontManager::LLFontManager()
+{
+ int error;
+ error = FT_Init_FreeType(&gFTLibrary);
+ if (error)
+ {
+ // Clean up freetype libs.
+ llerrs << "Freetype initialization failure!" << llendl;
+ FT_Done_FreeType(gFTLibrary);
+ }
+}
+
+LLFontManager::~LLFontManager()
+{
+ FT_Done_FreeType(gFTLibrary);
+}
+
+
+LLFontGlyphInfo::LLFontGlyphInfo(U32 index)
+: mGlyphIndex(index),
+ mXBitmapOffset(0), // Offset to the origin in the bitmap
+ mYBitmapOffset(0), // Offset to the origin in the bitmap
+ mXBearing(0), // Distance from baseline to left in pixels
+ mYBearing(0), // Distance from baseline to top in pixels
+ mWidth(0), // In pixels
+ mHeight(0), // In pixels
+ mXAdvance(0.f), // In pixels
+ mYAdvance(0.f), // In pixels
+ mIsRendered(FALSE),
+ mMetricsValid(FALSE)
+{
+}
+
+LLFontFreetype::LLFontFreetype()
+: mFontBitmapCachep(new LLFontBitmapCache),
+ mValid(FALSE),
+ mAscender(0.f),
+ mDescender(0.f),
+ mLineHeight(0.f),
+ mIsFallback(FALSE),
+ mFTFace(NULL),
+ mRenderGlyphCount(0),
+ mAddGlyphCount(0),
+ mPointSize(0)
+{
+}
+
+
+LLFontFreetype::~LLFontFreetype()
+{
+ // Clean up freetype libs.
+ if (mFTFace)
+ FT_Done_Face(mFTFace);
+ mFTFace = NULL;
+
+ // Delete glyph info
+ std::for_each(mCharGlyphInfoMap.begin(), mCharGlyphInfoMap.end(), DeletePairedPointer());
+
+ // mFontBitmapCachep will be cleaned up by LLPointer destructor.
+ // mFallbackFonts cleaned up by LLPointer destructor
+}
+
+BOOL LLFontFreetype::loadFace(const std::string& filename, F32 point_size, F32 vert_dpi, F32 horz_dpi, S32 components, BOOL is_fallback)
+{
+ // Don't leak face objects. This is also needed to deal with
+ // changed font file names.
+ if (mFTFace)
+ {
+ FT_Done_Face(mFTFace);
+ mFTFace = NULL;
+ }
+
+ int error;
+
+ error = FT_New_Face( gFTLibrary,
+ filename.c_str(),
+ 0,
+ &mFTFace );
+
+ if (error)
+ {
+ return FALSE;
+ }
+
+ mIsFallback = is_fallback;
+ F32 pixels_per_em = (point_size / 72.f)*vert_dpi; // Size in inches * dpi
+
+ error = FT_Set_Char_Size(mFTFace, /* handle to face object */
+ 0, /* char_width in 1/64th of points */
+ (S32)(point_size*64), /* char_height in 1/64th of points */
+ (U32)horz_dpi, /* horizontal device resolution */
+ (U32)vert_dpi); /* vertical device resolution */
+
+ if (error)
+ {
+ // Clean up freetype libs.
+ FT_Done_Face(mFTFace);
+ mFTFace = NULL;
+ return FALSE;
+ }
+
+ F32 y_max, y_min, x_max, x_min;
+ F32 ems_per_unit = 1.f/ mFTFace->units_per_EM;
+ F32 pixels_per_unit = pixels_per_em * ems_per_unit;
+
+ // Get size of bbox in pixels
+ y_max = mFTFace->bbox.yMax * pixels_per_unit;
+ y_min = mFTFace->bbox.yMin * pixels_per_unit;
+ x_max = mFTFace->bbox.xMax * pixels_per_unit;
+ x_min = mFTFace->bbox.xMin * pixels_per_unit;
+ mAscender = mFTFace->ascender * pixels_per_unit;
+ mDescender = -mFTFace->descender * pixels_per_unit;
+ mLineHeight = mFTFace->height * pixels_per_unit;
+
+ S32 max_char_width = llround(0.5f + (x_max - x_min));
+ S32 max_char_height = llround(0.5f + (y_max - y_min));
+
+ mFontBitmapCachep->init(components, max_char_width, max_char_height);
+
+ if (!mFTFace->charmap)
+ {
+ //llinfos << " no unicode encoding, set whatever encoding there is..." << llendl;
+ FT_Set_Charmap(mFTFace, mFTFace->charmaps[0]);
+ }
+
+ if (!mIsFallback)
+ {
+ // Add the default glyph
+ addGlyph(0, 0);
+ }
+
+ mName = filename;
+ mPointSize = point_size;
+
+ mStyle = LLFontGL::NORMAL;
+ if(mFTFace->style_flags & FT_STYLE_FLAG_BOLD)
+ {
+ mStyle |= LLFontGL::BOLD;
+ mStyle &= ~LLFontGL::NORMAL;
+ }
+
+ if(mFTFace->style_flags & FT_STYLE_FLAG_ITALIC)
+ {
+ mStyle |= LLFontGL::ITALIC;
+ mStyle &= ~LLFontGL::NORMAL;
+ }
+
+ return TRUE;
+}
+
+void LLFontFreetype::setFallbackFonts(const font_vector_t &font)
+{
+ mFallbackFonts = font;
+}
+
+const LLFontFreetype::font_vector_t &LLFontFreetype::getFallbackFonts() const
+{
+ return mFallbackFonts;
+}
+
+F32 LLFontFreetype::getLineHeight() const
+{
+ return mLineHeight;
+}
+
+F32 LLFontFreetype::getAscenderHeight() const
+{
+ return mAscender;
+}
+
+F32 LLFontFreetype::getDescenderHeight() const
+{
+ return mDescender;
+}
+
+F32 LLFontFreetype::getXAdvance(llwchar wch) const
+{
+ if (mFTFace == NULL)
+ return 0.0;
+
+ //llassert(!mIsFallback);
+ U32 glyph_index;
+
+ // Return existing info only if it is current
+ LLFontGlyphInfo* gi = getGlyphInfo(wch);
+ if (gi && gi->mMetricsValid)
+ {
+ return gi->mXAdvance;
+ }
+
+ const LLFontFreetype* fontp = this;
+
+ // Initialize char to glyph map
+ glyph_index = FT_Get_Char_Index(mFTFace, wch);
+ if (glyph_index == 0)
+ {
+ font_vector_t::const_iterator iter;
+ for(iter = mFallbackFonts.begin(); (iter != mFallbackFonts.end()) && (glyph_index == 0); iter++)
+ {
+ glyph_index = FT_Get_Char_Index((*iter)->mFTFace, wch);
+ if(glyph_index)
+ {
+ fontp = *iter;
+ }
+ }
+ }
+
+ if (glyph_index)
+ {
+ // This font has this glyph
+ fontp->renderGlyph(glyph_index);
+
+ // Create the entry if it's not there
+ char_glyph_info_map_t::iterator iter2 = mCharGlyphInfoMap.find(wch);
+ if (iter2 == mCharGlyphInfoMap.end())
+ {
+ gi = new LLFontGlyphInfo(glyph_index);
+ insertGlyphInfo(wch, gi);
+ }
+ else
+ {
+ gi = iter2->second;
+ }
+
+ gi->mWidth = fontp->mFTFace->glyph->bitmap.width;
+ gi->mHeight = fontp->mFTFace->glyph->bitmap.rows;
+
+ // Convert these from 26.6 units to float pixels.
+ gi->mXAdvance = fontp->mFTFace->glyph->advance.x / 64.f;
+ gi->mYAdvance = fontp->mFTFace->glyph->advance.y / 64.f;
+ gi->mMetricsValid = TRUE;
+ return gi->mXAdvance;
+ }
+ else
+ {
+ gi = get_if_there(mCharGlyphInfoMap, (llwchar)0, (LLFontGlyphInfo*)NULL);
+ if (gi)
+ {
+ return gi->mXAdvance;
+ }
+ }
+
+ // Last ditch fallback - no glyphs defined at all.
+ return (F32)mFontBitmapCachep->getMaxCharWidth();
+}
+
+F32 LLFontFreetype::getXKerning(llwchar char_left, llwchar char_right) const
+{
+ if (mFTFace == NULL)
+ return 0.0;
+
+ //llassert(!mIsFallback);
+ LLFontGlyphInfo* left_glyph_info = get_if_there(mCharGlyphInfoMap, char_left, (LLFontGlyphInfo*)NULL);
+ U32 left_glyph = left_glyph_info ? left_glyph_info->mGlyphIndex : 0;
+ // Kern this puppy.
+ LLFontGlyphInfo* right_glyph_info = get_if_there(mCharGlyphInfoMap, char_right, (LLFontGlyphInfo*)NULL);
+ U32 right_glyph = right_glyph_info ? right_glyph_info->mGlyphIndex : 0;
+
+ FT_Vector delta;
+
+ llverify(!FT_Get_Kerning(mFTFace, left_glyph, right_glyph, ft_kerning_unfitted, &delta));
+
+ return delta.x*(1.f/64.f);
+}
+
+BOOL LLFontFreetype::hasGlyph(llwchar wch) const
+{
+ llassert(!mIsFallback);
+ const LLFontGlyphInfo* gi = getGlyphInfo(wch);
+ if (gi && gi->mIsRendered)
+ {
+ return TRUE;
+ }
+ else
+ {
+ return FALSE;
+ }
+}
+
+BOOL LLFontFreetype::addChar(llwchar wch) const
+{
+ if (mFTFace == NULL)
+ return FALSE;
+
+ llassert(!mIsFallback);
+ //lldebugs << "Adding new glyph for " << wch << " to font" << llendl;
+
+ FT_UInt glyph_index;
+
+ // Initialize char to glyph map
+ glyph_index = FT_Get_Char_Index(mFTFace, wch);
+ if (glyph_index == 0)
+ {
+ //llinfos << "Trying to add glyph from fallback font!" << llendl
+ font_vector_t::const_iterator iter;
+ for(iter = mFallbackFonts.begin(); iter != mFallbackFonts.end(); iter++)
+ {
+ glyph_index = FT_Get_Char_Index((*iter)->mFTFace, wch);
+ if (glyph_index)
+ {
+ addGlyphFromFont(*iter, wch, glyph_index);
+ return TRUE;
+ }
+ }
+ }
+
+ char_glyph_info_map_t::iterator iter = mCharGlyphInfoMap.find(wch);
+ if (iter == mCharGlyphInfoMap.end() || !(iter->second->mIsRendered))
+ {
+ BOOL result = addGlyph(wch, glyph_index);
+ return result;
+ }
+ return FALSE;
+}
+
+BOOL LLFontFreetype::addGlyph(llwchar wch, U32 glyph_index) const
+{
+ return addGlyphFromFont(this, wch, glyph_index);
+}
+
+BOOL LLFontFreetype::addGlyphFromFont(const LLFontFreetype *fontp, llwchar wch, U32 glyph_index) const
+{
+ if (mFTFace == NULL)
+ return FALSE;
+
+ llassert(!mIsFallback);
+ fontp->renderGlyph(glyph_index);
+ S32 width = fontp->mFTFace->glyph->bitmap.width;
+ S32 height = fontp->mFTFace->glyph->bitmap.rows;
+
+ S32 pos_x, pos_y;
+ S32 bitmap_num;
+ mFontBitmapCachep->nextOpenPos(width, pos_x, pos_y, bitmap_num);
+ mAddGlyphCount++;
+
+ LLFontGlyphInfo* gi = new LLFontGlyphInfo(glyph_index);
+ gi->mXBitmapOffset = pos_x;
+ gi->mYBitmapOffset = pos_y;
+ gi->mBitmapNum = bitmap_num;
+ gi->mWidth = width;
+ gi->mHeight = height;
+ gi->mXBearing = fontp->mFTFace->glyph->bitmap_left;
+ gi->mYBearing = fontp->mFTFace->glyph->bitmap_top;
+ // Convert these from 26.6 units to float pixels.
+ gi->mXAdvance = fontp->mFTFace->glyph->advance.x / 64.f;
+ gi->mYAdvance = fontp->mFTFace->glyph->advance.y / 64.f;
+ gi->mIsRendered = TRUE;
+ gi->mMetricsValid = TRUE;
+
+ insertGlyphInfo(wch, gi);
+
+ llassert(fontp->mFTFace->glyph->bitmap.pixel_mode == FT_PIXEL_MODE_MONO
+ || fontp->mFTFace->glyph->bitmap.pixel_mode == FT_PIXEL_MODE_GRAY);
+
+ if (fontp->mFTFace->glyph->bitmap.pixel_mode == FT_PIXEL_MODE_MONO
+ || fontp->mFTFace->glyph->bitmap.pixel_mode == FT_PIXEL_MODE_GRAY)
+ {
+ U8 *buffer_data = fontp->mFTFace->glyph->bitmap.buffer;
+ S32 buffer_row_stride = fontp->mFTFace->glyph->bitmap.pitch;
+ U8 *tmp_graydata = NULL;
+
+ if (fontp->mFTFace->glyph->bitmap.pixel_mode
+ == FT_PIXEL_MODE_MONO)
+ {
+ // need to expand 1-bit bitmap to 8-bit graymap.
+ tmp_graydata = new U8[width * height];
+ S32 xpos, ypos;
+ for (ypos = 0; ypos < height; ++ypos)
+ {
+ S32 bm_row_offset = buffer_row_stride * ypos;
+ for (xpos = 0; xpos < width; ++xpos)
+ {
+ U32 bm_col_offsetbyte = xpos / 8;
+ U32 bm_col_offsetbit = 7 - (xpos % 8);
+ U32 bit =
+ !!(buffer_data[bm_row_offset
+ + bm_col_offsetbyte
+ ] & (1 << bm_col_offsetbit) );
+ tmp_graydata[width*ypos + xpos] =
+ 255 * bit;
+ }
+ }
+ // use newly-built graymap.
+ buffer_data = tmp_graydata;
+ buffer_row_stride = width;
+ }
+
+ switch (mFontBitmapCachep->getNumComponents())
+ {
+ case 1:
+ mFontBitmapCachep->getImageRaw(bitmap_num)->setSubImage(pos_x,
+ pos_y,
+ width,
+ height,
+ buffer_data,
+ buffer_row_stride,
+ TRUE);
+ break;
+ case 2:
+ setSubImageLuminanceAlpha(pos_x,
+ pos_y,
+ bitmap_num,
+ width,
+ height,
+ buffer_data,
+ buffer_row_stride);
+ break;
+ default:
+ break;
+ }
+
+ if (tmp_graydata)
+ delete[] tmp_graydata;
+ } else {
+ // we don't know how to handle this pixel format from FreeType;
+ // omit it from the font-image.
+ }
+
+ return TRUE;
+}
+
+LLFontGlyphInfo* LLFontFreetype::getGlyphInfo(llwchar wch) const
+{
+ char_glyph_info_map_t::iterator iter = mCharGlyphInfoMap.find(wch);
+ if (iter != mCharGlyphInfoMap.end())
+ {
+ return iter->second;
+ }
+ return NULL;
+}
+
+void LLFontFreetype::insertGlyphInfo(llwchar wch, LLFontGlyphInfo* gi) const
+{
+ char_glyph_info_map_t::iterator iter = mCharGlyphInfoMap.find(wch);
+ if (iter != mCharGlyphInfoMap.end())
+ {
+ delete iter->second;
+ iter->second = gi;
+ }
+ else
+ {
+ mCharGlyphInfoMap[wch] = gi;
+ }
+}
+
+void LLFontFreetype::renderGlyph(U32 glyph_index) const
+{
+ if (mFTFace == NULL)
+ return;
+
+ int error = FT_Load_Glyph(mFTFace, glyph_index, FT_LOAD_DEFAULT );
+ llassert(!error);
+
+ error = FT_Render_Glyph(mFTFace->glyph, gFontRenderMode);
+
+ mRenderGlyphCount++;
+
+ llassert(!error);
+}
+
+void LLFontFreetype::reset(F32 vert_dpi, F32 horz_dpi)
+{
+ if (!mIsFallback)
+ {
+ // This is the head of the list - need to rebuild ourself and all fallbacks.
+ loadFace(mName, mPointSize, vert_dpi ,horz_dpi, mFontBitmapCachep->getNumComponents(), mIsFallback);
+
+ if (mFallbackFonts.empty())
+ {
+ llwarns << "LLFontGL::reset(), no fallback fonts present" << llendl;
+ }
+ else
+ {
+ for(font_vector_t::iterator it = mFallbackFonts.begin();
+ it != mFallbackFonts.end();
+ ++it)
+ {
+ (*it)->reset(vert_dpi, horz_dpi);
+ }
+ }
+ }
+ resetBitmapCache();
+}
+
+void LLFontFreetype::resetBitmapCache()
+{
+ // Iterate through glyphs and clear the mIsRendered flag
+ for (char_glyph_info_map_t::iterator iter = mCharGlyphInfoMap.begin();
+ iter != mCharGlyphInfoMap.end(); ++iter)
+ {
+ iter->second->mIsRendered = FALSE;
+ //FIXME: this is only strictly necessary when resetting the entire font,
+ //not just flushing the bitmap
+ iter->second->mMetricsValid = FALSE;
+ }
+ mFontBitmapCachep->reset();
+
+ // Add the empty glyph`5
+ addGlyph(0, 0);
+}
+
+void LLFontFreetype::destroyGL()
+{
+ mFontBitmapCachep->destroyGL();
+}
+
+BOOL LLFontFreetype::getIsFallback() const
+{
+ return mIsFallback;
+}
+
+const std::string &LLFontFreetype::getName() const
+{
+ return mName;
+}
+
+F32 LLFontFreetype::getPointSize() const
+{
+ return mPointSize;
+}
+
+const LLPointer<LLFontBitmapCache> LLFontFreetype::getFontBitmapCache() const
+{
+ return mFontBitmapCachep;
+}
+
+void LLFontFreetype::setStyle(U8 style)
+{
+ mStyle = style;
+}
+
+U8 LLFontFreetype::getStyle() const
+{
+ return mStyle;
+}
+
+void LLFontFreetype::setSubImageLuminanceAlpha(U32 x, U32 y, U32 bitmap_num, U32 width, U32 height, U8 *data, S32 stride) const
+{
+ LLImageRaw *image_raw = mFontBitmapCachep->getImageRaw(bitmap_num);
+
+ llassert(!mIsFallback);
+ llassert(image_raw && (image_raw->getComponents() == 2));
+
+
+ U8 *target = image_raw->getData();
+
+ if (!data)
+ {
+ return;
+ }
+
+ if (0 == stride)
+ stride = width;
+
+ U32 i, j;
+ U32 to_offset;
+ U32 from_offset;
+ U32 target_width = image_raw->getWidth();
+ for (i = 0; i < height; i++)
+ {
+ to_offset = (y + i)*target_width + x;
+ from_offset = (height - 1 - i)*stride;
+ for (j = 0; j < width; j++)
+ {
+ *(target + to_offset*2 + 1) = *(data + from_offset);
+ to_offset++;
+ from_offset++;
+ }
+ }
+}
+
diff --git a/indra/llrender/llfontfreetype.h b/indra/llrender/llfontfreetype.h
new file mode 100644
index 0000000000..0520ef2cd6
--- /dev/null
+++ b/indra/llrender/llfontfreetype.h
@@ -0,0 +1,380 @@
+/**
+ * @file llfontfreetype.h
+ * @brief Font library wrapper
+ *
+ * $LicenseInfo:firstyear=2002&license=viewergpl$
+ *
+ * Copyright (c) 2002-2009, Linden Research, Inc.
+ *
+ * Second Life Viewer Source Code
+ * The source code in this file ("Source Code") is provided by Linden Lab
+ * to you under the terms of the GNU General Public License, version 2.0
+ * ("GPL"), unless you have obtained a separate licensing agreement
+ * ("Other License"), formally executed by you and Linden Lab. Terms of
+ * the GPL can be found in doc/GPL-license.txt in this distribution, or
+ * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
+ *
+ * There are special exceptions to the terms and conditions of the GPL as
+ * it is applied to this Source Code. View the full text of the exception
+ * in the file doc/FLOSS-exception.txt in this software distribution, or
+ * online at
+ * http://secondlifegrid.net/programs/open_source/licensing/flossexception
+ *
+ * By copying, modifying or distributing this software, you acknowledge
+ * that you have read and understood your obligations described above,
+ * and agree to abide by those obligations.
+ *
+ * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+ * COMPLETENESS OR PERFORMANCE.
+ * $/LicenseInfo$
+ */
+
+#ifndef LL_LLFONTFREETYPE_H
+#define LL_LLFONTFREETYPE_H
+
+#include <map>
+#include "llpointer.h"
+#include "llstl.h"
+
+#include "llimagegl.h"
+#include "llfontbitmapcache.h"
+
+// Hack. FT_Face is just a typedef for a pointer to a struct,
+// but there's no simple forward declarations file for FreeType,
+// and the main include file is 200K.
+// We'll forward declare the struct here. JC
+struct FT_FaceRec_;
+typedef struct FT_FaceRec_* LLFT_Face;
+
+class LLFontManager
+{
+public:
+ static void initClass();
+ static void cleanupClass();
+
+private:
+ LLFontManager();
+ ~LLFontManager();
+};
+
+class LLFontGlyphInfo
+{
+public:
+ LLFontGlyphInfo(U32 index);
+
+ U32 mGlyphIndex;
+
+ // Metrics
+ S32 mWidth; // In pixels
+ S32 mHeight; // In pixels
+ F32 mXAdvance; // In pixels
+ F32 mYAdvance; // In pixels
+ BOOL mMetricsValid; // We have up-to-date metrics for this glyph
+
+ // Information for actually rendering
+ BOOL mIsRendered; // We actually have rendered this glyph
+ S32 mXBitmapOffset; // Offset to the origin in the bitmap
+ S32 mYBitmapOffset; // Offset to the origin in the bitmap
+ S32 mXBearing; // Distance from baseline to left in pixels
+ S32 mYBearing; // Distance from baseline to top in pixels
+ S32 mBitmapNum; // Which bitmap in the bitmap cache contains this glyph
+};
+
+extern LLFontManager *gFontManagerp;
+
+class LLFontFreetype : public LLRefCount
+{
+public:
+ LLFontFreetype();
+ ~LLFontFreetype();
+
+ // is_fallback should be true for fallback fonts that aren't used
+ // to render directly (Unicode backup, primarily)
+ BOOL loadFace(const std::string& filename, F32 point_size, F32 vert_dpi, F32 horz_dpi, S32 components, BOOL is_fallback);
+
+ typedef std::vector<LLPointer<LLFontFreetype> > font_vector_t;
+
+ void setFallbackFonts(const font_vector_t &font);
+ const font_vector_t &getFallbackFonts() const;
+
+ // Global font metrics - in units of pixels
+ F32 getLineHeight() const;
+ F32 getAscenderHeight() const;
+ F32 getDescenderHeight() const;
+
+
+// For a lowercase "g":
+//
+// ------------------------------
+// ^ ^
+// | |
+// xxx x |Ascender
+// x x v |
+// --------- xxxx-------------- Baseline
+// ^ x |
+// | Descender x |
+// v xxxx |LineHeight
+// ----------------------- |
+// v
+// ------------------------------
+
+ enum
+ {
+ FIRST_CHAR = 32,
+ NUM_CHARS = 127 - 32,
+ LAST_CHAR_BASIC = 127,
+
+ // Need full 8-bit ascii range for spanish
+ NUM_CHARS_FULL = 255 - 32,
+ LAST_CHAR_FULL = 255
+ };
+
+ F32 getXAdvance(llwchar wc) const;
+ F32 getXKerning(llwchar char_left, llwchar char_right) const; // Get the kerning between the two characters
+
+ BOOL hasGlyph(llwchar wch) const; // Has a glyph for this character
+ BOOL addChar(llwchar wch) const; // Add a new character to the font if necessary
+ BOOL addGlyph(llwchar wch, U32 glyph_index) const; // Add a new glyph to the existing font
+ BOOL addGlyphFromFont(const LLFontFreetype *fontp, llwchar wch, U32 glyph_index) const; // Add a glyph from this font to the other (returns the glyph_index, 0 if not found)
+
+ LLFontGlyphInfo* getGlyphInfo(llwchar wch) const;
+
+ void insertGlyphInfo(llwchar wch, LLFontGlyphInfo* gi) const;
+ void renderGlyph(U32 glyph_index) const;
+
+ void reset(F32 vert_dpi, F32 horz_dpi);
+ void resetBitmapCache();
+
+ void destroyGL();
+
+ BOOL getIsFallback() const;
+
+ const std::string& getName() const;
+
+ F32 getPointSize() const;
+
+ const LLPointer<LLFontBitmapCache> getFontBitmapCache() const;
+
+ void setStyle(U8 style);
+ U8 getStyle() const;
+
+private:
+ void setSubImageLuminanceAlpha(U32 x, U32 y, U32 bitmap_num, U32 width, U32 height, U8 *data, S32 stride = 0) const;
+
+ std::string mName;
+
+ U8 mStyle;
+
+ F32 mPointSize;
+ F32 mAscender;
+ F32 mDescender;
+ F32 mLineHeight;
+
+ LLFT_Face mFTFace;
+
+ BOOL mIsFallback;
+ font_vector_t mFallbackFonts; // A list of fallback fonts to look for glyphs in (for Unicode chars)
+
+ BOOL mValid;
+
+ typedef std::map<llwchar, LLFontGlyphInfo*> char_glyph_info_map_t;
+ mutable char_glyph_info_map_t mCharGlyphInfoMap; // Information about glyph location in bitmap
+
+ mutable LLPointer<LLFontBitmapCache> mFontBitmapCachep;
+
+ mutable S32 mRenderGlyphCount;
+ mutable S32 mAddGlyphCount;
+};
+
+#endif // LL_FONTFREETYPE_H
+/**
+ * @file llfontfreetype.h
+ * @brief Font library wrapper
+ *
+ * $LicenseInfo:firstyear=2002&license=viewergpl$
+ *
+ * Copyright (c) 2002-2009, Linden Research, Inc.
+ *
+ * Second Life Viewer Source Code
+ * The source code in this file ("Source Code") is provided by Linden Lab
+ * to you under the terms of the GNU General Public License, version 2.0
+ * ("GPL"), unless you have obtained a separate licensing agreement
+ * ("Other License"), formally executed by you and Linden Lab. Terms of
+ * the GPL can be found in doc/GPL-license.txt in this distribution, or
+ * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
+ *
+ * There are special exceptions to the terms and conditions of the GPL as
+ * it is applied to this Source Code. View the full text of the exception
+ * in the file doc/FLOSS-exception.txt in this software distribution, or
+ * online at
+ * http://secondlifegrid.net/programs/open_source/licensing/flossexception
+ *
+ * By copying, modifying or distributing this software, you acknowledge
+ * that you have read and understood your obligations described above,
+ * and agree to abide by those obligations.
+ *
+ * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+ * COMPLETENESS OR PERFORMANCE.
+ * $/LicenseInfo$
+ */
+
+#ifndef LL_LLFONTFREETYPE_H
+#define LL_LLFONTFREETYPE_H
+
+#include <map>
+#include "llpointer.h"
+#include "llstl.h"
+
+#include "llimagegl.h"
+#include "llfontbitmapcache.h"
+
+// Hack. FT_Face is just a typedef for a pointer to a struct,
+// but there's no simple forward declarations file for FreeType,
+// and the main include file is 200K.
+// We'll forward declare the struct here. JC
+struct FT_FaceRec_;
+typedef struct FT_FaceRec_* LLFT_Face;
+
+class LLFontManager
+{
+public:
+ static void initClass();
+ static void cleanupClass();
+
+private:
+ LLFontManager();
+ ~LLFontManager();
+};
+
+class LLFontGlyphInfo
+{
+public:
+ LLFontGlyphInfo(U32 index);
+
+ U32 mGlyphIndex;
+
+ // Metrics
+ S32 mWidth; // In pixels
+ S32 mHeight; // In pixels
+ F32 mXAdvance; // In pixels
+ F32 mYAdvance; // In pixels
+ BOOL mMetricsValid; // We have up-to-date metrics for this glyph
+
+ // Information for actually rendering
+ BOOL mIsRendered; // We actually have rendered this glyph
+ S32 mXBitmapOffset; // Offset to the origin in the bitmap
+ S32 mYBitmapOffset; // Offset to the origin in the bitmap
+ S32 mXBearing; // Distance from baseline to left in pixels
+ S32 mYBearing; // Distance from baseline to top in pixels
+ S32 mBitmapNum; // Which bitmap in the bitmap cache contains this glyph
+};
+
+extern LLFontManager *gFontManagerp;
+
+class LLFontFreetype : public LLRefCount
+{
+public:
+ LLFontFreetype();
+ ~LLFontFreetype();
+
+ // is_fallback should be true for fallback fonts that aren't used
+ // to render directly (Unicode backup, primarily)
+ BOOL loadFace(const std::string& filename, F32 point_size, F32 vert_dpi, F32 horz_dpi, S32 components, BOOL is_fallback);
+
+ typedef std::vector<LLPointer<LLFontFreetype> > font_vector_t;
+
+ void setFallbackFonts(const font_vector_t &font);
+ const font_vector_t &getFallbackFonts() const;
+
+ // Global font metrics - in units of pixels
+ F32 getLineHeight() const;
+ F32 getAscenderHeight() const;
+ F32 getDescenderHeight() const;
+
+
+// For a lowercase "g":
+//
+// ------------------------------
+// ^ ^
+// | |
+// xxx x |Ascender
+// x x v |
+// --------- xxxx-------------- Baseline
+// ^ x |
+// | Descender x |
+// v xxxx |LineHeight
+// ----------------------- |
+// v
+// ------------------------------
+
+ enum
+ {
+ FIRST_CHAR = 32,
+ NUM_CHARS = 127 - 32,
+ LAST_CHAR_BASIC = 127,
+
+ // Need full 8-bit ascii range for spanish
+ NUM_CHARS_FULL = 255 - 32,
+ LAST_CHAR_FULL = 255
+ };
+
+ F32 getXAdvance(llwchar wc) const;
+ F32 getXKerning(llwchar char_left, llwchar char_right) const; // Get the kerning between the two characters
+
+ BOOL hasGlyph(llwchar wch) const; // Has a glyph for this character
+ BOOL addChar(llwchar wch) const; // Add a new character to the font if necessary
+ BOOL addGlyph(llwchar wch, U32 glyph_index) const; // Add a new glyph to the existing font
+ BOOL addGlyphFromFont(const LLFontFreetype *fontp, llwchar wch, U32 glyph_index) const; // Add a glyph from this font to the other (returns the glyph_index, 0 if not found)
+
+ LLFontGlyphInfo* getGlyphInfo(llwchar wch) const;
+
+ void insertGlyphInfo(llwchar wch, LLFontGlyphInfo* gi) const;
+ void renderGlyph(U32 glyph_index) const;
+
+ void reset(F32 vert_dpi, F32 horz_dpi);
+ void resetBitmapCache();
+
+ void destroyGL();
+
+ BOOL getIsFallback() const;
+
+ const std::string& getName() const;
+
+ F32 getPointSize() const;
+
+ const LLPointer<LLFontBitmapCache> getFontBitmapCache() const;
+
+ void setStyle(U8 style);
+ U8 getStyle() const;
+
+private:
+ void setSubImageLuminanceAlpha(U32 x, U32 y, U32 bitmap_num, U32 width, U32 height, U8 *data, S32 stride = 0) const;
+
+ std::string mName;
+
+ U8 mStyle;
+
+ F32 mPointSize;
+ F32 mAscender;
+ F32 mDescender;
+ F32 mLineHeight;
+
+ LLFT_Face mFTFace;
+
+ BOOL mIsFallback;
+ font_vector_t mFallbackFonts; // A list of fallback fonts to look for glyphs in (for Unicode chars)
+
+ BOOL mValid;
+
+ typedef std::map<llwchar, LLFontGlyphInfo*> char_glyph_info_map_t;
+ mutable char_glyph_info_map_t mCharGlyphInfoMap; // Information about glyph location in bitmap
+
+ mutable LLPointer<LLFontBitmapCache> mFontBitmapCachep;
+
+ mutable S32 mRenderGlyphCount;
+ mutable S32 mAddGlyphCount;
+};
+
+#endif // LL_FONTFREETYPE_H
diff --git a/indra/llrender/llfontgl.cpp b/indra/llrender/llfontgl.cpp
index beecb6b7c1..d76b23248d 100644
--- a/indra/llrender/llfontgl.cpp
+++ b/indra/llrender/llfontgl.cpp
@@ -32,16 +32,21 @@
#include "linden_common.h"
-#include <boost/tokenizer.hpp>
-
-#include "llfont.h"
#include "llfontgl.h"
+
+// Linden library includes
+#include "llfontfreetype.h"
#include "llfontbitmapcache.h"
#include "llfontregistry.h"
#include "llgl.h"
+#include "llimagegl.h"
#include "llrender.h"
-#include "v4color.h"
#include "llstl.h"
+#include "v4color.h"
+#include "lltexture.h"
+
+// Third party library includes
+#include <boost/tokenizer.hpp>
const S32 BOLD_OFFSET = 1;
@@ -68,320 +73,52 @@ const F32 PIXEL_CORRECTION_DISTANCE = 0.01f;
const F32 PAD_UVY = 0.5f; // half of vertical padding between glyphs in the glyph texture
const F32 DROP_SHADOW_SOFT_STRENGTH = 0.3f;
-F32 llfont_round_x(F32 x)
+static F32 llfont_round_x(F32 x)
{
//return llfloor((x-LLFontGL::sCurOrigin.mX)/LLFontGL::sScaleX+0.5f)*LLFontGL::sScaleX+LLFontGL::sCurOrigin.mX;
//return llfloor(x/LLFontGL::sScaleX+0.5f)*LLFontGL::sScaleY;
return x;
}
-F32 llfont_round_y(F32 y)
+static F32 llfont_round_y(F32 y)
{
//return llfloor((y-LLFontGL::sCurOrigin.mY)/LLFontGL::sScaleY+0.5f)*LLFontGL::sScaleY+LLFontGL::sCurOrigin.mY;
//return llfloor(y+0.5f);
return y;
}
-// static
-U8 LLFontGL::getStyleFromString(const std::string &style)
-{
- S32 ret = 0;
- if (style.find("NORMAL") != style.npos)
- {
- ret |= NORMAL;
- }
- if (style.find("BOLD") != style.npos)
- {
- ret |= BOLD;
- }
- if (style.find("ITALIC") != style.npos)
- {
- ret |= ITALIC;
- }
- if (style.find("UNDERLINE") != style.npos)
- {
- ret |= UNDERLINE;
- }
- if (style.find("SHADOW") != style.npos)
- {
- ret |= DROP_SHADOW;
- }
- if (style.find("SOFT_SHADOW") != style.npos)
- {
- ret |= DROP_SHADOW_SOFT;
- }
- return ret;
-}
-
LLFontGL::LLFontGL()
- : LLFont()
-{
- clearEmbeddedChars();
-}
-
-LLFontGL::LLFontGL(const LLFontGL &source)
{
- llerrs << "Not implemented!" << llendl;
}
LLFontGL::~LLFontGL()
{
- clearEmbeddedChars();
}
void LLFontGL::reset()
{
- if (!mIsFallback)
- {
- // This is the head of the list - need to rebuild ourself and all fallbacks.
- loadFace(mName,mPointSize,sVertDPI,sHorizDPI,mFontBitmapCachep->getNumComponents(),mIsFallback);
- if (mFallbackFontp==NULL)
- {
- llwarns << "LLFontGL::reset(), no fallback fonts present" << llendl;
- }
- else
- {
- for (LLFontList::iterator it = mFallbackFontp->begin();
- it != mFallbackFontp->end();
- ++it)
- {
- (*it)->reset();
- }
- }
- }
- resetBitmapCache();
-}
-
-// static
-std::string LLFontGL::getFontPathSystem()
-{
- std::string system_path;
-
- // Try to figure out where the system's font files are stored.
- char *system_root = NULL;
-#if LL_WINDOWS
- system_root = getenv("SystemRoot"); /* Flawfinder: ignore */
- if (!system_root)
- {
- llwarns << "SystemRoot not found, attempting to load fonts from default path." << llendl;
- }
-#endif
-
- if (system_root)
- {
- system_path = llformat("%s/fonts/", system_root);
- }
- else
- {
-#if LL_WINDOWS
- // HACK for windows 98/Me
- system_path = "/WINDOWS/FONTS/";
-#elif LL_DARWIN
- // HACK for Mac OS X
- system_path = "/System/Library/Fonts/";
-#endif
- }
- return system_path;
-}
-
-
-// static
-std::string LLFontGL::getFontPathLocal()
-{
- std::string local_path;
-
- // Backup files if we can't load from system fonts directory.
- // We could store this in an end-user writable directory to allow
- // end users to switch fonts.
- if (LLFontGL::sAppDir.length())
- {
- // use specified application dir to look for fonts
- local_path = LLFontGL::sAppDir + "/fonts/";
- }
- else
- {
- // assume working directory is executable directory
- local_path = "./fonts/";
- }
- return local_path;
-}
-
-bool findOrCreateFont(LLFontGL*& fontp, const LLFontDescriptor& desc)
-{
- // Don't delete existing fonts, if any, here, because they've
- // already been deleted by LLFontRegistry::clear()
- fontp = LLFontGL::getFont(desc);
- return (fontp != NULL);
-}
-
-// static
-BOOL LLFontGL::initDefaultFonts(F32 screen_dpi, F32 x_scale, F32 y_scale,
- const std::string& app_dir,
- const std::vector<std::string>& xui_paths)
-{
- bool succ = true;
- sVertDPI = (F32)llfloor(screen_dpi * y_scale);
- sHorizDPI = (F32)llfloor(screen_dpi * x_scale);
- sScaleX = x_scale;
- sScaleY = y_scale;
- sAppDir = app_dir;
-
- // Font registry init
- if (!sFontRegistry)
- {
- sFontRegistry = new LLFontRegistry(xui_paths);
- sFontRegistry->parseFontInfo("fonts.xml");
- }
- else
- {
- sFontRegistry->reset();
- }
-
- // Force standard fonts to get generated up front.
- // This is primarily for error detection purposes.
- succ &= (NULL != getFontSansSerifSmall());
- succ &= (NULL != getFontSansSerif());
- succ &= (NULL != getFontSansSerifBig());
- succ &= (NULL != getFontSansSerifHuge());
- succ &= (NULL != getFontSansSerifBold());
- succ &= (NULL != getFontMonospace());
- succ &= (NULL != getFontExtChar());
-
- return succ;
-}
-
-
-
-// static
-void LLFontGL::destroyDefaultFonts()
-{
- // Remove the actual fonts.
- delete sFontRegistry;
- sFontRegistry = NULL;
-}
-
-//static
-void LLFontGL::destroyAllGL()
-{
- if (sFontRegistry)
- {
- sFontRegistry->destroyGL();
- }
+ mFontFreetype->reset(sVertDPI, sHorizDPI);
}
void LLFontGL::destroyGL()
{
- mFontBitmapCachep->destroyGL();
+ mFontFreetype->destroyGL();
}
-
-
-LLFontGL &LLFontGL::operator=(const LLFontGL &source)
+BOOL LLFontGL::loadFace(const std::string& filename, F32 point_size, F32 vert_dpi, F32 horz_dpi, S32 components, BOOL is_fallback)
{
- llerrs << "Not implemented" << llendl;
- return *this;
-}
-
-BOOL LLFontGL::loadFace(const std::string& filename,
- const F32 point_size, const F32 vert_dpi, const F32 horz_dpi,
- const S32 components, BOOL is_fallback)
-{
- if (!LLFont::loadFace(filename, point_size, vert_dpi, horz_dpi, components, is_fallback))
+ if(mFontFreetype == reinterpret_cast<LLFontFreetype*>(NULL))
{
- return FALSE;
+ mFontFreetype = new LLFontFreetype;
}
- return TRUE;
-}
-//static
-LLFontGL* LLFontGL::getFontMonospace()
-{
- return getFont(LLFontDescriptor("Monospace","Monospace",0));
+ return mFontFreetype->loadFace(filename, point_size, vert_dpi, horz_dpi, components, is_fallback);
}
-//static
-LLFontGL* LLFontGL::getFontSansSerifSmall()
-{
- return getFont(LLFontDescriptor("SansSerif","Small",0));
-}
+static LLFastTimer::DeclareTimer FTM_RENDER_FONTS("Fonts");
-//static
-LLFontGL* LLFontGL::getFontSansSerif()
-{
- return getFont(LLFontDescriptor("SansSerif","Medium",0));
-}
-
-//static
-LLFontGL* LLFontGL::getFontSansSerifBig()
-{
- return getFont(LLFontDescriptor("SansSerif","Large",0));
-}
-
-//static
-LLFontGL* LLFontGL::getFontSansSerifHuge()
-{
- return getFont(LLFontDescriptor("SansSerif","Huge",0));
-}
-
-//static
-LLFontGL* LLFontGL::getFontSansSerifBold()
-{
- return getFont(LLFontDescriptor("SansSerif","Medium",BOLD));
-}
-
-//static
-LLFontGL* LLFontGL::getFontExtChar()
-{
- return getFontSansSerif();
-}
-
-//static
-LLFontGL* LLFontGL::getFont(const LLFontDescriptor& desc)
-{
- return sFontRegistry->getFont(desc);
-}
-
-BOOL LLFontGL::addChar(const llwchar wch) const
-{
- if (!LLFont::addChar(wch))
- {
- return FALSE;
- }
-
- stop_glerror();
-
- LLFontGlyphInfo *glyph_info = getGlyphInfo(wch);
- U32 bitmap_num = glyph_info->mBitmapNum;
- LLImageGL *image_gl = mFontBitmapCachep->getImageGL(bitmap_num);
- LLImageRaw *image_raw = mFontBitmapCachep->getImageRaw(bitmap_num);
- image_gl->setSubImage(image_raw, 0, 0, image_gl->getWidth(), image_gl->getHeight());
- return TRUE;
-}
-
-
-S32 LLFontGL::renderUTF8(const std::string &text, const S32 offset,
- const F32 x, const F32 y,
- const LLColor4 &color,
- const HAlign halign, const VAlign valign,
- U8 style,
- const S32 max_chars, const S32 max_pixels,
- F32* right_x,
- BOOL use_ellipses) const
-{
- LLWString wstr = utf8str_to_wstring(text);
- return render(wstr, offset, x, y, color, halign, valign, style, max_chars, max_pixels, right_x, FALSE, use_ellipses);
-}
-
-S32 LLFontGL::render(const LLWString &wstr,
- const S32 begin_offset,
- const F32 x, const F32 y,
- const LLColor4 &color,
- const HAlign halign, const VAlign valign,
- U8 style,
- const S32 max_chars, S32 max_pixels,
- F32* right_x,
- BOOL use_embedded,
- BOOL use_ellipses) const
+S32 LLFontGL::render(const LLWString &wstr, S32 begin_offset, F32 x, F32 y, const LLColor4 &color, HAlign halign, VAlign valign, U8 style,
+ ShadowType shadow, S32 max_chars, S32 max_pixels, F32* right_x, BOOL use_ellipses) const
{
if(!sDisplayFont) //do not display texts
{
@@ -397,18 +134,19 @@ S32 LLFontGL::render(const LLWString &wstr,
S32 scaled_max_pixels = max_pixels == S32_MAX ? S32_MAX : llceil((F32)max_pixels * sScaleX);
- // Strip off any style bits that are already accounted for by the font.
- style = style & (~getFontDesc().getStyle());
+ // determine which style flags need to be added programmatically by striping off the
+ // style bits that are drawn by the underlying Freetype font
+ U8 style_to_add = (style | mFontDescriptor.getStyle()) & ~mFontFreetype->getStyle();
F32 drop_shadow_strength = 0.f;
- if (style & (DROP_SHADOW | DROP_SHADOW_SOFT))
+ if (shadow != NO_SHADOW)
{
F32 luminance;
color.calcHSL(NULL, NULL, &luminance);
drop_shadow_strength = clamp_rescale(luminance, 0.35f, 0.6f, 0.f, 1.f);
if (luminance < 0.35f)
{
- style = style & ~(DROP_SHADOW | DROP_SHADOW_SOFT);
+ shadow = NO_SHADOW;
}
}
@@ -421,7 +159,7 @@ S32 LLFontGL::render(const LLWString &wstr,
F32 pixel_offset_y = llround((F32)sCurOrigin.mY) - (sCurOrigin.mY);
gGL.translatef(-pixel_offset_x, -pixel_offset_y, 0.f);
- LLFastTimer t(LLFastTimer::FTM_RENDER_FONTS);
+ LLFastTimer t(FTM_RENDER_FONTS);
gGL.color4fv( color.mV );
@@ -450,13 +188,13 @@ S32 LLFontGL::render(const LLWString &wstr,
switch (valign)
{
case TOP:
- cur_y -= mAscender;
+ cur_y -= mFontFreetype->getAscenderHeight();
break;
case BOTTOM:
- cur_y += mDescender;
+ cur_y += mFontFreetype->getDescenderHeight();
break;
case VCENTER:
- cur_y -= ((mAscender - mDescender)/2.f);
+ cur_y -= ((mFontFreetype->getAscenderHeight() - mFontFreetype->getDescenderHeight())/2.f);
break;
case BASELINE:
// Baseline, do nothing.
@@ -484,14 +222,16 @@ S32 LLFontGL::render(const LLWString &wstr,
F32 start_x = cur_x;
- F32 inv_width = 1.f / mFontBitmapCachep->getBitmapWidth();
- F32 inv_height = 1.f / mFontBitmapCachep->getBitmapHeight();
+ const LLFontBitmapCache* font_bitmap_cache = mFontFreetype->getFontBitmapCache();
+
+ F32 inv_width = 1.f / font_bitmap_cache->getBitmapWidth();
+ F32 inv_height = 1.f / font_bitmap_cache->getBitmapHeight();
- const S32 LAST_CHARACTER = LLFont::LAST_CHAR_FULL;
+ const S32 LAST_CHARACTER = LLFontFreetype::LAST_CHAR_FULL;
BOOL draw_ellipses = FALSE;
- if (use_ellipses && halign == LEFT)
+ if (use_ellipses)
{
// check for too long of a string
if (getWidthF32(wstr.c_str(), 0, max_chars) * sScaleX > scaled_max_pixels)
@@ -511,135 +251,69 @@ S32 LLFontGL::render(const LLWString &wstr,
{
llwchar wch = wstr[i];
- // Handle embedded characters first, if they're enabled.
- // Embedded characters are a hack for notecards
- const embedded_data_t* ext_data = use_embedded ? getEmbeddedCharData(wch) : NULL;
- if (ext_data)
+ if (!mFontFreetype->hasGlyph(wch))
{
- LLImageGL* ext_image = ext_data->mImage;
- const LLWString& label = ext_data->mLabel;
-
- F32 ext_height = (F32)ext_image->getHeight() * sScaleY;
-
- F32 ext_width = (F32)ext_image->getWidth() * sScaleX;
- F32 ext_advance = (EXT_X_BEARING * sScaleX) + ext_width;
-
- if (!label.empty())
- {
- ext_advance += (EXT_X_BEARING + getFontExtChar()->getWidthF32( label.c_str() )) * sScaleX;
- }
-
- if (start_x + scaled_max_pixels < cur_x + ext_advance)
- {
- // Not enough room for this character.
- break;
- }
-
- if (last_bound_texture != ext_image)
- {
- gGL.getTexUnit(0)->bind(ext_image);
- last_bound_texture = ext_image;
- }
-
- // snap origin to whole screen pixel
- const F32 ext_x = (F32)llround(cur_render_x + (EXT_X_BEARING * sScaleX));
- const F32 ext_y = (F32)llround(cur_render_y + (EXT_Y_BEARING * sScaleY + mAscender - mLineHeight));
-
- LLRectf uv_rect(0.f, 1.f, 1.f, 0.f);
- LLRectf screen_rect(ext_x, ext_y + ext_height, ext_x + ext_width, ext_y);
- drawGlyph(screen_rect, uv_rect, LLColor4::white, style, drop_shadow_strength);
-
- if (!label.empty())
- {
- gGL.pushMatrix();
- //glLoadIdentity();
- //gGL.translatef(sCurOrigin.mX, sCurOrigin.mY, 0.0f);
- //glScalef(sScaleX, sScaleY, 1.f);
- getFontExtChar()->render(label, 0,
- /*llfloor*/((ext_x + (F32)ext_image->getWidth() + EXT_X_BEARING) / sScaleX),
- /*llfloor*/(cur_y / sScaleY),
- color,
- halign, BASELINE, NORMAL, S32_MAX, S32_MAX, NULL,
- TRUE );
- gGL.popMatrix();
- }
-
- gGL.color4fv(color.mV);
+ addChar(wch);
+ }
- chars_drawn++;
- cur_x += ext_advance;
- if (((i + 1) < length) && wstr[i+1])
- {
- cur_x += EXT_KERNING * sScaleX;
- }
- cur_render_x = cur_x;
+ const LLFontGlyphInfo* fgi= mFontFreetype->getGlyphInfo(wch);
+ if (!fgi)
+ {
+ llerrs << "Missing Glyph Info" << llendl;
+ break;
}
- else
+ // Per-glyph bitmap texture.
+ LLImageGL *image_gl = mFontFreetype->getFontBitmapCache()->getImageGL(fgi->mBitmapNum);
+ if (last_bound_texture != image_gl)
{
- if (!hasGlyph(wch))
- {
- addChar(wch);
- }
-
- const LLFontGlyphInfo* fgi= getGlyphInfo(wch);
- if (!fgi)
- {
- llerrs << "Missing Glyph Info" << llendl;
- break;
- }
- // Per-glyph bitmap texture.
- LLImageGL *image_gl = mFontBitmapCachep->getImageGL(fgi->mBitmapNum);
- if (last_bound_texture != image_gl)
- {
- gGL.getTexUnit(0)->bind(image_gl);
- last_bound_texture = image_gl;
- }
-
- if ((start_x + scaled_max_pixels) < (cur_x + fgi->mXBearing + fgi->mWidth))
- {
- // Not enough room for this character.
- break;
- }
-
- // Draw the text at the appropriate location
- //Specify vertices and texture coordinates
- LLRectf uv_rect((fgi->mXBitmapOffset) * inv_width,
- (fgi->mYBitmapOffset + fgi->mHeight + PAD_UVY) * inv_height,
- (fgi->mXBitmapOffset + fgi->mWidth) * inv_width,
- (fgi->mYBitmapOffset - PAD_UVY) * inv_height);
- // snap glyph origin to whole screen pixel
- LLRectf screen_rect(llround(cur_render_x + (F32)fgi->mXBearing),
- llround(cur_render_y + (F32)fgi->mYBearing),
- llround(cur_render_x + (F32)fgi->mXBearing) + (F32)fgi->mWidth,
- llround(cur_render_y + (F32)fgi->mYBearing) - (F32)fgi->mHeight);
-
- drawGlyph(screen_rect, uv_rect, color, style, drop_shadow_strength);
+ gGL.getTexUnit(0)->bind(image_gl);
+ last_bound_texture = image_gl;
+ }
- chars_drawn++;
- cur_x += fgi->mXAdvance;
- cur_y += fgi->mYAdvance;
+ if ((start_x + scaled_max_pixels) < (cur_x + fgi->mXBearing + fgi->mWidth))
+ {
+ // Not enough room for this character.
+ break;
+ }
- llwchar next_char = wstr[i+1];
- if (next_char && (next_char < LAST_CHARACTER))
+ // Draw the text at the appropriate location
+ //Specify vertices and texture coordinates
+ LLRectf uv_rect((fgi->mXBitmapOffset) * inv_width,
+ (fgi->mYBitmapOffset + fgi->mHeight + PAD_UVY) * inv_height,
+ (fgi->mXBitmapOffset + fgi->mWidth) * inv_width,
+ (fgi->mYBitmapOffset - PAD_UVY) * inv_height);
+ // snap glyph origin to whole screen pixel
+ LLRectf screen_rect(llround(cur_render_x + (F32)fgi->mXBearing),
+ llround(cur_render_y + (F32)fgi->mYBearing),
+ llround(cur_render_x + (F32)fgi->mXBearing) + (F32)fgi->mWidth,
+ llround(cur_render_y + (F32)fgi->mYBearing) - (F32)fgi->mHeight);
+
+ drawGlyph(screen_rect, uv_rect, color, style_to_add, shadow, drop_shadow_strength);
+
+ chars_drawn++;
+ cur_x += fgi->mXAdvance;
+ cur_y += fgi->mYAdvance;
+
+ llwchar next_char = wstr[i+1];
+ if (next_char && (next_char < LAST_CHARACTER))
+ {
+ // Kern this puppy.
+ if (!mFontFreetype->hasGlyph(next_char))
{
- // Kern this puppy.
- if (!hasGlyph(next_char))
- {
- addChar(next_char);
- }
- cur_x += getXKerning(wch, next_char);
+ addChar(next_char);
}
+ cur_x += mFontFreetype->getXKerning(wch, next_char);
+ }
- // Round after kerning.
- // Must do this to cur_x, not just to cur_render_x, otherwise you
- // will squish sub-pixel kerned characters too close together.
- // For example, "CCCCC" looks bad.
- cur_x = (F32)llfloor(cur_x + 0.5f);
- //cur_y = (F32)llfloor(cur_y + 0.5f);
+ // Round after kerning.
+ // Must do this to cur_x, not just to cur_render_x, otherwise you
+ // will squish sub-pixel kerned characters too close together.
+ // For example, "CCCCC" looks bad.
+ cur_x = (F32)llfloor(cur_x + 0.5f);
+ //cur_y = (F32)llfloor(cur_y + 0.5f);
- cur_render_x = cur_x;
- cur_render_y = cur_y;
- }
+ cur_render_x = cur_x;
+ cur_render_y = cur_y;
}
if (right_x)
@@ -647,18 +321,20 @@ S32 LLFontGL::render(const LLWString &wstr,
*right_x = cur_x / sScaleX;
}
- if (style & UNDERLINE)
+ if (style_to_add & UNDERLINE)
{
+ F32 descender = mFontFreetype->getDescenderHeight();
+
gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
gGL.begin(LLRender::LINES);
- gGL.vertex2f(start_x, cur_y - (mDescender));
- gGL.vertex2f(cur_x, cur_y - (mDescender));
+ gGL.vertex2f(start_x, cur_y - (descender));
+ gGL.vertex2f(cur_x, cur_y - (descender));
gGL.end();
}
- // *FIX: get this working in all alignment cases, etc.
if (draw_ellipses)
{
+
// recursively render ellipses at end of string
// we've already reserved enough room
gGL.pushMatrix();
@@ -670,7 +346,8 @@ S32 LLFontGL::render(const LLWString &wstr,
cur_x / sScaleX, (F32)y,
color,
LEFT, valign,
- style,
+ style_to_add,
+ shadow,
S32_MAX, max_pixels,
right_x,
FALSE);
@@ -682,6 +359,41 @@ S32 LLFontGL::render(const LLWString &wstr,
return chars_drawn;
}
+S32 LLFontGL::render(const LLWString &text, S32 begin_offset, F32 x, F32 y, const LLColor4 &color) const
+{
+ return render(text, begin_offset, x, y, color, LEFT, BASELINE, NORMAL, NO_SHADOW, S32_MAX, S32_MAX, NULL, FALSE);
+}
+
+S32 LLFontGL::renderUTF8(const std::string &text, S32 begin_offset, F32 x, F32 y, const LLColor4 &color, HAlign halign, VAlign valign, U8 style, ShadowType shadow, S32 max_chars, S32 max_pixels, F32* right_x, BOOL use_ellipses) const
+{
+ return render(utf8str_to_wstring(text), begin_offset, x, y, color, halign, valign, style, shadow, max_chars, max_pixels, right_x, use_ellipses);
+}
+
+S32 LLFontGL::renderUTF8(const std::string &text, S32 begin_offset, S32 x, S32 y, const LLColor4 &color) const
+{
+ return renderUTF8(text, begin_offset, (F32)x, (F32)y, color, LEFT, BASELINE, NORMAL, NO_SHADOW, S32_MAX, S32_MAX, NULL, FALSE);
+}
+
+S32 LLFontGL::renderUTF8(const std::string &text, S32 begin_offset, S32 x, S32 y, const LLColor4 &color, HAlign halign, VAlign valign, U8 style, ShadowType shadow) const
+{
+ return renderUTF8(text, begin_offset, (F32)x, (F32)y, color, halign, valign, style, shadow, S32_MAX, S32_MAX, NULL, FALSE);
+}
+
+// font metrics - override for LLFontFreetype that returns units of virtual pixels
+F32 LLFontGL::getLineHeight() const
+{
+ return (F32)llround(mFontFreetype->getLineHeight() / sScaleY);
+}
+
+F32 LLFontGL::getAscenderHeight() const
+{
+ return (F32)llround(mFontFreetype->getAscenderHeight() / sScaleY);
+}
+
+F32 LLFontGL::getDescenderHeight() const
+{
+ return (F32)llround(mFontFreetype->getDescenderHeight() / sScaleY);
+}
S32 LLFontGL::getWidth(const std::string& utf8text) const
{
@@ -694,15 +406,15 @@ S32 LLFontGL::getWidth(const llwchar* wchars) const
return getWidth(wchars, 0, S32_MAX);
}
-S32 LLFontGL::getWidth(const std::string& utf8text, const S32 begin_offset, const S32 max_chars) const
+S32 LLFontGL::getWidth(const std::string& utf8text, S32 begin_offset, S32 max_chars) const
{
LLWString wtext = utf8str_to_wstring(utf8text);
return getWidth(wtext.c_str(), begin_offset, max_chars);
}
-S32 LLFontGL::getWidth(const llwchar* wchars, const S32 begin_offset, const S32 max_chars, BOOL use_embedded) const
+S32 LLFontGL::getWidth(const llwchar* wchars, S32 begin_offset, S32 max_chars) const
{
- F32 width = getWidthF32(wchars, begin_offset, max_chars, use_embedded);
+ F32 width = getWidthF32(wchars, begin_offset, max_chars);
return llround(width);
}
@@ -717,48 +429,35 @@ F32 LLFontGL::getWidthF32(const llwchar* wchars) const
return getWidthF32(wchars, 0, S32_MAX);
}
-F32 LLFontGL::getWidthF32(const std::string& utf8text, const S32 begin_offset, const S32 max_chars ) const
+F32 LLFontGL::getWidthF32(const std::string& utf8text, S32 begin_offset, S32 max_chars ) const
{
LLWString wtext = utf8str_to_wstring(utf8text);
return getWidthF32(wtext.c_str(), begin_offset, max_chars);
}
-F32 LLFontGL::getWidthF32(const llwchar* wchars, const S32 begin_offset, const S32 max_chars, BOOL use_embedded) const
+F32 LLFontGL::getWidthF32(const llwchar* wchars, S32 begin_offset, S32 max_chars) const
{
- const S32 LAST_CHARACTER = LLFont::LAST_CHAR_FULL;
+ const S32 LAST_CHARACTER = LLFontFreetype::LAST_CHAR_FULL;
F32 cur_x = 0;
const S32 max_index = begin_offset + max_chars;
for (S32 i = begin_offset; i < max_index; i++)
{
- const llwchar wch = wchars[i];
+ llwchar wch = wchars[i];
if (wch == 0)
{
break; // done
}
- const embedded_data_t* ext_data = use_embedded ? getEmbeddedCharData(wch) : NULL;
- if (ext_data)
- {
- // Handle crappy embedded hack
- cur_x += getEmbeddedCharAdvance(ext_data);
- if( ((i+1) < max_chars) && (i+1 < max_index))
- {
- cur_x += EXT_KERNING * sScaleX;
- }
- }
- else
- {
- cur_x += getXAdvance(wch);
- llwchar next_char = wchars[i+1];
+ cur_x += mFontFreetype->getXAdvance(wch);
+ llwchar next_char = wchars[i+1];
- if (((i + 1) < max_chars)
- && next_char
- && (next_char < LAST_CHARACTER))
- {
- // Kern this puppy.
- cur_x += getXKerning(wch, next_char);
- }
+ if (((i + 1) < begin_offset + max_chars)
+ && next_char
+ && (next_char < LAST_CHARACTER))
+ {
+ // Kern this puppy.
+ cur_x += mFontFreetype->getXKerning(wch, next_char);
}
// Round after kerning.
cur_x = (F32)llfloor(cur_x + 0.5f);
@@ -767,12 +466,8 @@ F32 LLFontGL::getWidthF32(const llwchar* wchars, const S32 begin_offset, const S
return cur_x / sScaleX;
}
-
-
// Returns the max number of complete characters from text (up to max_chars) that can be drawn in max_pixels
-S32 LLFontGL::maxDrawableChars(const llwchar* wchars, F32 max_pixels, S32 max_chars,
- BOOL end_on_word_boundary, const BOOL use_embedded,
- F32* drawn_pixels) const
+S32 LLFontGL::maxDrawableChars(const llwchar* wchars, F32 max_pixels, S32 max_chars, BOOL end_on_word_boundary) const
{
if (!wchars || !wchars[0] || max_chars == 0)
{
@@ -802,68 +497,51 @@ S32 LLFontGL::maxDrawableChars(const llwchar* wchars, F32 max_pixels, S32 max_ch
break;
}
- const embedded_data_t* ext_data = use_embedded ? getEmbeddedCharData(wch) : NULL;
- if (ext_data)
- {
- if (in_word)
- {
- in_word = FALSE;
- }
- else
- {
- start_of_last_word = i;
- }
- cur_x += getEmbeddedCharAdvance(ext_data);
-
- if (scaled_max_pixels < cur_x)
- {
- clip = TRUE;
- break;
- }
-
- if (((i+1) < max_chars) && wchars[i+1])
- {
- cur_x += EXT_KERNING * sScaleX;
- }
-
- if( scaled_max_pixels < cur_x )
- {
- clip = TRUE;
- break;
- }
- }
- else
+ if (in_word)
{
- if (in_word)
+ if (iswspace(wch))
{
- if (iswspace(wch))
+ if(wch !=(0x00A0))
{
in_word = FALSE;
}
}
- else
+ if (iswindividual(wch))
{
- start_of_last_word = i;
- if (!iswspace(wch))
+ if (iswpunct(wchars[i+1]))
+ {
+ in_word=TRUE;
+ }
+ else
{
- in_word = TRUE;
+ in_word=FALSE;
+ start_of_last_word = i;
}
}
-
- cur_x += getXAdvance(wch);
-
- if (scaled_max_pixels < cur_x)
+ }
+ else
+ {
+ start_of_last_word = i;
+ if (!iswspace(wch)||!iswindividual(wch))
{
- clip = TRUE;
- break;
+ in_word = TRUE;
}
+ }
- if (((i+1) < max_chars) && wchars[i+1])
- {
- // Kern this puppy.
- cur_x += getXKerning(wch, wchars[i+1]);
- }
+ cur_x += mFontFreetype->getXAdvance(wch);
+
+ if (scaled_max_pixels < cur_x)
+ {
+ clip = TRUE;
+ break;
}
+
+ if (((i+1) < max_chars) && wchars[i+1])
+ {
+ // Kern this puppy.
+ cur_x += mFontFreetype->getXKerning(wch, wchars[i+1]);
+ }
+
// Round after kerning.
cur_x = (F32)llfloor(cur_x + 0.5f);
drawn_x = cur_x;
@@ -873,14 +551,9 @@ S32 LLFontGL::maxDrawableChars(const llwchar* wchars, F32 max_pixels, S32 max_ch
{
i = start_of_last_word;
}
- if (drawn_pixels)
- {
- *drawn_pixels = drawn_x;
- }
return i;
}
-
S32 LLFontGL::firstDrawableChar(const llwchar* wchars, F32 max_pixels, S32 text_len, S32 start_pos, S32 max_chars) const
{
if (!wchars || !wchars[0] || max_chars == 0)
@@ -898,8 +571,7 @@ S32 LLFontGL::firstDrawableChar(const llwchar* wchars, F32 max_pixels, S32 text_
{
llwchar wch = wchars[i];
- const embedded_data_t* ext_data = getEmbeddedCharData(wch);
- F32 char_width = ext_data ? getEmbeddedCharAdvance(ext_data) : getXAdvance(wch);
+ F32 char_width = mFontFreetype->getXAdvance(wch);
if( scaled_max_pixels < (total_width + char_width) )
{
@@ -917,7 +589,7 @@ S32 LLFontGL::firstDrawableChar(const llwchar* wchars, F32 max_pixels, S32 text_
if ( i > 0 )
{
// kerning
- total_width += ext_data ? (EXT_KERNING * sScaleX) : getXKerning(wchars[i-1], wch);
+ total_width += mFontFreetype->getXKerning(wchars[i-1], wch);
}
// Round after kerning.
@@ -927,8 +599,7 @@ S32 LLFontGL::firstDrawableChar(const llwchar* wchars, F32 max_pixels, S32 text_
return start_pos - drawable_chars;
}
-
-S32 LLFontGL::charFromPixelOffset(const llwchar* wchars, const S32 begin_offset, F32 target_x, F32 max_pixels, S32 max_chars, BOOL round, BOOL use_embedded) const
+S32 LLFontGL::charFromPixelOffset(const llwchar* wchars, S32 begin_offset, F32 target_x, F32 max_pixels, S32 max_chars, BOOL round) const
{
if (!wchars || !wchars[0] || max_chars == 0)
{
@@ -936,7 +607,6 @@ S32 LLFontGL::charFromPixelOffset(const llwchar* wchars, const S32 begin_offset,
}
F32 cur_x = 0;
- S32 pos = 0;
target_x *= sScaleX;
@@ -945,149 +615,364 @@ S32 LLFontGL::charFromPixelOffset(const llwchar* wchars, const S32 begin_offset,
F32 scaled_max_pixels = max_pixels * sScaleX;
- for (S32 i = begin_offset; (i < max_index); i++)
+ S32 pos;
+ for (pos = begin_offset; pos < max_index; pos++)
{
- llwchar wch = wchars[i];
+ llwchar wch = wchars[pos];
if (!wch)
{
break; // done
}
- const embedded_data_t* ext_data = use_embedded ? getEmbeddedCharData(wch) : NULL;
- if (ext_data)
- {
- F32 ext_advance = getEmbeddedCharAdvance(ext_data);
-
- if (round)
- {
- // Note: if the mouse is on the left half of the character, the pick is to the character's left
- // If it's on the right half, the pick is to the right.
- if (target_x < cur_x + ext_advance/2)
- {
- break;
- }
- }
- else
- {
- if (target_x < cur_x + ext_advance)
- {
- break;
- }
- }
+ F32 char_width = mFontFreetype->getXAdvance(wch);
- if (scaled_max_pixels < cur_x + ext_advance)
+ if (round)
+ {
+ // Note: if the mouse is on the left half of the character, the pick is to the character's left
+ // If it's on the right half, the pick is to the right.
+ if (target_x < cur_x + char_width*0.5f)
{
break;
}
+ }
+ else if (target_x < cur_x + char_width)
+ {
+ break;
+ }
- pos++;
- cur_x += ext_advance;
-
- if (((i + 1) < max_index)
- && (wchars[(i + 1)]))
- {
- cur_x += EXT_KERNING * sScaleX;
- }
- // Round after kerning.
- cur_x = (F32)llfloor(cur_x + 0.5f);
+ if (scaled_max_pixels < cur_x + char_width)
+ {
+ break;
}
- else
+
+ cur_x += char_width;
+
+ if (((pos + 1) < max_index)
+ && (wchars[(pos + 1)]))
{
- F32 char_width = getXAdvance(wch);
+ llwchar next_char = wchars[pos + 1];
+ // Kern this puppy.
+ cur_x += mFontFreetype->getXKerning(wch, next_char);
+ }
- if (round)
- {
- // Note: if the mouse is on the left half of the character, the pick is to the character's left
- // If it's on the right half, the pick is to the right.
- if (target_x < cur_x + char_width*0.5f)
- {
- break;
- }
- }
- else if (target_x < cur_x + char_width)
- {
- break;
- }
+ // Round after kerning.
+ cur_x = (F32)llfloor(cur_x + 0.5f);
+ }
- if (scaled_max_pixels < cur_x + char_width)
- {
- break;
- }
+ return llmin(max_chars, pos - begin_offset);
+}
- pos++;
- cur_x += char_width;
+BOOL LLFontGL::addChar(llwchar wch) const
+{
+ if (!mFontFreetype->addChar(wch))
+ {
+ return FALSE;
+ }
- if (((i + 1) < max_index)
- && (wchars[(i + 1)]))
- {
- llwchar next_char = wchars[i + 1];
- // Kern this puppy.
- cur_x += getXKerning(wch, next_char);
- }
+ stop_glerror();
- // Round after kerning.
- cur_x = (F32)llfloor(cur_x + 0.5f);
- }
+ LLFontGlyphInfo *glyph_info = mFontFreetype->getGlyphInfo(wch);
+ U32 bitmap_num = glyph_info->mBitmapNum;
+
+ const LLFontBitmapCache* font_bitmap_cache = mFontFreetype->getFontBitmapCache();
+ LLImageGL *image_gl = font_bitmap_cache->getImageGL(bitmap_num);
+ LLImageRaw *image_raw = font_bitmap_cache->getImageRaw(bitmap_num);
+ image_gl->setSubImage(image_raw, 0, 0, image_gl->getWidth(), image_gl->getHeight());
+ return TRUE;
+}
+
+const LLFontDescriptor& LLFontGL::getFontDesc() const
+{
+ return mFontDescriptor;
+}
+
+// static
+void LLFontGL::initClass(F32 screen_dpi, F32 x_scale, F32 y_scale, const std::string& app_dir, const std::vector<std::string>& xui_paths, bool create_gl_textures)
+{
+ sVertDPI = (F32)llfloor(screen_dpi * y_scale);
+ sHorizDPI = (F32)llfloor(screen_dpi * x_scale);
+ sScaleX = x_scale;
+ sScaleY = y_scale;
+ sAppDir = app_dir;
+
+ // Font registry init
+ if (!sFontRegistry)
+ {
+ sFontRegistry = new LLFontRegistry(xui_paths, create_gl_textures);
+ sFontRegistry->parseFontInfo("fonts.xml");
}
+ else
+ {
+ sFontRegistry->reset();
+ }
+}
- return pos;
+// Force standard fonts to get generated up front.
+// This is primarily for error detection purposes.
+// Don't do this during initClass because it can be slow and we want to get
+// the viewer window on screen first. JC
+// static
+bool LLFontGL::loadDefaultFonts()
+{
+ bool succ = true;
+ succ &= (NULL != getFontSansSerifSmall());
+ succ &= (NULL != getFontSansSerif());
+ succ &= (NULL != getFontSansSerifBig());
+ succ &= (NULL != getFontSansSerifHuge());
+ succ &= (NULL != getFontSansSerifBold());
+ succ &= (NULL != getFontMonospace());
+ succ &= (NULL != getFontExtChar());
+ return succ;
}
+// static
+void LLFontGL::destroyDefaultFonts()
+{
+ // Remove the actual fonts.
+ delete sFontRegistry;
+ sFontRegistry = NULL;
+}
+
+//static
+void LLFontGL::destroyAllGL()
+{
+ if (sFontRegistry)
+ {
+ sFontRegistry->destroyGL();
+ }
+}
-const LLFontGL::embedded_data_t* LLFontGL::getEmbeddedCharData(const llwchar wch) const
+// static
+U8 LLFontGL::getStyleFromString(const std::string &style)
{
- // Handle crappy embedded hack
- embedded_map_t::const_iterator iter = mEmbeddedChars.find(wch);
- if (iter != mEmbeddedChars.end())
+ S32 ret = 0;
+ if (style.find("NORMAL") != style.npos)
+ {
+ ret |= NORMAL;
+ }
+ if (style.find("BOLD") != style.npos)
{
- return iter->second;
+ ret |= BOLD;
+ }
+ if (style.find("ITALIC") != style.npos)
+ {
+ ret |= ITALIC;
}
- return NULL;
+ if (style.find("UNDERLINE") != style.npos)
+ {
+ ret |= UNDERLINE;
+ }
+ return ret;
}
+// static
+std::string LLFontGL::nameFromFont(const LLFontGL* fontp)
+{
+ return fontp->mFontDescriptor.getName();
+}
-F32 LLFontGL::getEmbeddedCharAdvance(const embedded_data_t* ext_data) const
+// static
+std::string LLFontGL::nameFromHAlign(LLFontGL::HAlign align)
{
- const LLWString& label = ext_data->mLabel;
- LLImageGL* ext_image = ext_data->mImage;
+ if (align == LEFT) return std::string("left");
+ else if (align == RIGHT) return std::string("right");
+ else if (align == HCENTER) return std::string("center");
+ else return std::string();
+}
- F32 ext_width = (F32)ext_image->getWidth();
- if( !label.empty() )
+// static
+LLFontGL::HAlign LLFontGL::hAlignFromName(const std::string& name)
+{
+ LLFontGL::HAlign gl_hfont_align = LLFontGL::LEFT;
+ if (name == "left")
{
- ext_width += (EXT_X_BEARING + getFontExtChar()->getWidthF32(label.c_str())) * sScaleX;
+ gl_hfont_align = LLFontGL::LEFT;
}
+ else if (name == "right")
+ {
+ gl_hfont_align = LLFontGL::RIGHT;
+ }
+ else if (name == "center")
+ {
+ gl_hfont_align = LLFontGL::HCENTER;
+ }
+ //else leave left
+ return gl_hfont_align;
+}
- return (EXT_X_BEARING * sScaleX) + ext_width;
+// static
+std::string LLFontGL::nameFromVAlign(LLFontGL::VAlign align)
+{
+ if (align == TOP) return std::string("top");
+ else if (align == VCENTER) return std::string("center");
+ else if (align == BASELINE) return std::string("baseline");
+ else if (align == BOTTOM) return std::string("bottom");
+ else return std::string();
}
+// static
+LLFontGL::VAlign LLFontGL::vAlignFromName(const std::string& name)
+{
+ LLFontGL::VAlign gl_vfont_align = LLFontGL::BASELINE;
+ if (name == "top")
+ {
+ gl_vfont_align = LLFontGL::TOP;
+ }
+ else if (name == "center")
+ {
+ gl_vfont_align = LLFontGL::VCENTER;
+ }
+ else if (name == "baseline")
+ {
+ gl_vfont_align = LLFontGL::BASELINE;
+ }
+ else if (name == "bottom")
+ {
+ gl_vfont_align = LLFontGL::BOTTOM;
+ }
+ //else leave baseline
+ return gl_vfont_align;
+}
-void LLFontGL::clearEmbeddedChars()
+//static
+LLFontGL* LLFontGL::getFontMonospace()
{
- for_each(mEmbeddedChars.begin(), mEmbeddedChars.end(), DeletePairedPointer());
- mEmbeddedChars.clear();
+ return getFont(LLFontDescriptor("Monospace","Monospace",0));
}
-void LLFontGL::addEmbeddedChar( llwchar wc, LLImageGL* image, const std::string& label ) const
+//static
+LLFontGL* LLFontGL::getFontSansSerifSmall()
{
- LLWString wlabel = utf8str_to_wstring(label);
- addEmbeddedChar(wc, image, wlabel);
+ return getFont(LLFontDescriptor("SansSerif","Small",0));
}
-void LLFontGL::addEmbeddedChar( llwchar wc, LLImageGL* image, const LLWString& wlabel ) const
+//static
+LLFontGL* LLFontGL::getFontSansSerif()
+{
+ return getFont(LLFontDescriptor("SansSerif","Medium",0));
+}
+
+//static
+LLFontGL* LLFontGL::getFontSansSerifBig()
+{
+ return getFont(LLFontDescriptor("SansSerif","Large",0));
+}
+
+//static
+LLFontGL* LLFontGL::getFontSansSerifHuge()
+{
+ return getFont(LLFontDescriptor("SansSerif","Huge",0));
+}
+
+//static
+LLFontGL* LLFontGL::getFontSansSerifBold()
+{
+ return getFont(LLFontDescriptor("SansSerif","Medium",BOLD));
+}
+
+//static
+LLFontGL* LLFontGL::getFontExtChar()
{
- embedded_data_t* ext_data = new embedded_data_t(image, wlabel);
- mEmbeddedChars[wc] = ext_data;
+ return getFontSansSerif();
}
-void LLFontGL::removeEmbeddedChar( llwchar wc ) const
+//static
+LLFontGL* LLFontGL::getFont(const LLFontDescriptor& desc)
+{
+ return sFontRegistry->getFont(desc);
+}
+
+//static
+LLFontGL* LLFontGL::getFontByName(const std::string& name)
{
- embedded_map_t::iterator iter = mEmbeddedChars.find(wc);
- if (iter != mEmbeddedChars.end())
+ // check for most common fonts first
+ if (name == "SANSSERIF")
{
- delete iter->second;
- mEmbeddedChars.erase(wc);
+ return getFontSansSerif();
+ }
+ else if (name == "SANSSERIF_SMALL")
+ {
+ return getFontSansSerifSmall();
+ }
+ else if (name == "SANSSERIF_BIG")
+ {
+ return getFontSansSerifBig();
+ }
+ else if (name == "SMALL" || name == "OCRA")
+ {
+ // *BUG: Should this be "MONOSPACE"? Do we use "OCRA" anymore?
+ // Does "SMALL" mean "SERIF"?
+ return getFontMonospace();
+ }
+ else
+ {
+ return NULL;
}
}
+// static
+std::string LLFontGL::getFontPathSystem()
+{
+ std::string system_path;
+
+ // Try to figure out where the system's font files are stored.
+ char *system_root = NULL;
+#if LL_WINDOWS
+ system_root = getenv("SystemRoot"); /* Flawfinder: ignore */
+ if (!system_root)
+ {
+ llwarns << "SystemRoot not found, attempting to load fonts from default path." << llendl;
+ }
+#endif
+
+ if (system_root)
+ {
+ system_path = llformat("%s/fonts/", system_root);
+ }
+ else
+ {
+#if LL_WINDOWS
+ // HACK for windows 98/Me
+ system_path = "/WINDOWS/FONTS/";
+#elif LL_DARWIN
+ // HACK for Mac OS X
+ system_path = "/System/Library/Fonts/";
+#endif
+ }
+ return system_path;
+}
+
+
+// static
+std::string LLFontGL::getFontPathLocal()
+{
+ std::string local_path;
+
+ // Backup files if we can't load from system fonts directory.
+ // We could store this in an end-user writable directory to allow
+ // end users to switch fonts.
+ if (LLFontGL::sAppDir.length())
+ {
+ // use specified application dir to look for fonts
+ local_path = LLFontGL::sAppDir + "/fonts/";
+ }
+ else
+ {
+ // assume working directory is executable directory
+ local_path = "./fonts/";
+ }
+ return local_path;
+}
+
+LLFontGL::LLFontGL(const LLFontGL &source)
+{
+ llerrs << "Not implemented!" << llendl;
+}
+
+LLFontGL &LLFontGL::operator=(const LLFontGL &source)
+{
+ llerrs << "Not implemented" << llendl;
+ return *this;
+}
void LLFontGL::renderQuad(const LLRectf& screen_rect, const LLRectf& uv_rect, F32 slant_amt) const
{
@@ -1108,10 +993,10 @@ void LLFontGL::renderQuad(const LLRectf& screen_rect, const LLRectf& uv_rect, F3
llfont_round_y(screen_rect.mBottom));
}
-void LLFontGL::drawGlyph(const LLRectf& screen_rect, const LLRectf& uv_rect, const LLColor4& color, U8 style, F32 drop_shadow_strength) const
+void LLFontGL::drawGlyph(const LLRectf& screen_rect, const LLRectf& uv_rect, const LLColor4& color, U8 style, ShadowType shadow, F32 drop_shadow_strength) const
{
F32 slant_offset;
- slant_offset = ((style & ITALIC) ? ( -mAscender * 0.2f) : 0.f);
+ slant_offset = ((style & ITALIC) ? ( -mFontFreetype->getAscenderHeight() * 0.2f) : 0.f);
gGL.begin(LLRender::QUADS);
{
@@ -1128,7 +1013,7 @@ void LLFontGL::drawGlyph(const LLRectf& screen_rect, const LLRectf& uv_rect, con
renderQuad(screen_rect_offset, uv_rect, slant_offset);
}
}
- else if (style & DROP_SHADOW_SOFT)
+ else if (shadow == DROP_SHADOW_SOFT)
{
LLColor4 shadow_color = LLFontGL::sShadowColor;
shadow_color.mV[VALPHA] = color.mV[VALPHA] * drop_shadow_strength * DROP_SHADOW_SOFT_STRENGTH;
@@ -1161,7 +1046,7 @@ void LLFontGL::drawGlyph(const LLRectf& screen_rect, const LLRectf& uv_rect, con
gGL.color4fv(color.mV);
renderQuad(screen_rect, uv_rect, slant_offset);
}
- else if (style & DROP_SHADOW)
+ else if (shadow == DROP_SHADOW)
{
LLColor4 shadow_color = LLFontGL::sShadowColor;
shadow_color.mV[VALPHA] = color.mV[VALPHA] * drop_shadow_strength;
@@ -1181,71 +1066,3 @@ void LLFontGL::drawGlyph(const LLRectf& screen_rect, const LLRectf& uv_rect, con
}
gGL.end();
}
-
-std::string LLFontGL::nameFromFont(const LLFontGL* fontp)
-{
- return fontp->getFontDesc().getName();
-}
-
-// static
-std::string LLFontGL::nameFromHAlign(LLFontGL::HAlign align)
-{
- if (align == LEFT) return std::string("left");
- else if (align == RIGHT) return std::string("right");
- else if (align == HCENTER) return std::string("center");
- else return std::string();
-}
-
-// static
-LLFontGL::HAlign LLFontGL::hAlignFromName(const std::string& name)
-{
- LLFontGL::HAlign gl_hfont_align = LLFontGL::LEFT;
- if (name == "left")
- {
- gl_hfont_align = LLFontGL::LEFT;
- }
- else if (name == "right")
- {
- gl_hfont_align = LLFontGL::RIGHT;
- }
- else if (name == "center")
- {
- gl_hfont_align = LLFontGL::HCENTER;
- }
- //else leave left
- return gl_hfont_align;
-}
-
-// static
-std::string LLFontGL::nameFromVAlign(LLFontGL::VAlign align)
-{
- if (align == TOP) return std::string("top");
- else if (align == VCENTER) return std::string("center");
- else if (align == BASELINE) return std::string("baseline");
- else if (align == BOTTOM) return std::string("bottom");
- else return std::string();
-}
-
-// static
-LLFontGL::VAlign LLFontGL::vAlignFromName(const std::string& name)
-{
- LLFontGL::VAlign gl_vfont_align = LLFontGL::BASELINE;
- if (name == "top")
- {
- gl_vfont_align = LLFontGL::TOP;
- }
- else if (name == "center")
- {
- gl_vfont_align = LLFontGL::VCENTER;
- }
- else if (name == "baseline")
- {
- gl_vfont_align = LLFontGL::BASELINE;
- }
- else if (name == "bottom")
- {
- gl_vfont_align = LLFontGL::BOTTOM;
- }
- //else leave baseline
- return gl_vfont_align;
-}
diff --git a/indra/llrender/llfontgl.h b/indra/llrender/llfontgl.h
index 6cb1727ff4..af8e0909af 100644
--- a/indra/llrender/llfontgl.h
+++ b/indra/llrender/llfontgl.h
@@ -34,23 +34,22 @@
#ifndef LL_LLFONTGL_H
#define LL_LLFONTGL_H
-#include "llfont.h"
-#include "llimagegl.h"
-#include "v2math.h"
#include "llcoord.h"
-#include "llrect.h"
-
#include "llfontregistry.h"
+#include "llimagegl.h"
+#include "llpointer.h"
+#include "llrect.h"
+#include "v2math.h"
class LLColor4;
-
// Key used to request a font.
class LLFontDescriptor;
+class LLFontFreetype;
// Structure used to store previously requested fonts.
class LLFontRegistry;
-class LLFontGL : public LLFont
+class LLFontGL
{
public:
enum HAlign
@@ -73,131 +72,81 @@ public:
enum StyleFlags
{
// text style to render. May be combined (these are bit flags)
+ // TODO:: Maybe change the value to 0x01 << 0 for 1 0x01 << 1 for 2, 0x01 << 2 for 4
NORMAL = 0,
BOLD = 1,
ITALIC = 2,
- UNDERLINE = 4,
- DROP_SHADOW = 8,
- DROP_SHADOW_SOFT = 16
+ UNDERLINE = 4
+ };
+
+ enum ShadowType
+ {
+ NO_SHADOW,
+ DROP_SHADOW,
+ DROP_SHADOW_SOFT
};
-
- // Takes a string with potentially several flags, i.e. "NORMAL|BOLD|ITALIC"
- static U8 getStyleFromString(const std::string &style);
LLFontGL();
- LLFontGL(const LLFontGL &source);
~LLFontGL();
- void init(); // Internal init, or reinitialization
- void reset(); // Reset a font after GL cleanup. ONLY works on an already loaded font.
-
- LLFontGL &operator=(const LLFontGL &source);
- static BOOL initDefaultFonts(F32 screen_dpi, F32 x_scale, F32 y_scale,
- const std::string& app_dir,
- const std::vector<std::string>& xui_paths);
+ void reset(); // Reset a font after GL cleanup. ONLY works on an already loaded font.
- static void destroyDefaultFonts();
- static void destroyAllGL();
void destroyGL();
- /* virtual*/ BOOL loadFace(const std::string& filename,
- const F32 point_size, const F32 vert_dpi, const F32 horz_dpi,
- const S32 components, BOOL is_fallback);
+ BOOL loadFace(const std::string& filename, F32 point_size, const F32 vert_dpi, const F32 horz_dpi, const S32 components, BOOL is_fallback);
+ S32 render(const LLWString &text, S32 begin_offset, F32 x, F32 y, const LLColor4 &color, HAlign halign = LEFT, VAlign valign = BASELINE, U8 style = NORMAL,
+ ShadowType shadow = NO_SHADOW, S32 max_chars = S32_MAX, S32 max_pixels = S32_MAX, F32* right_x=NULL, BOOL use_ellipses = FALSE) const;
+ S32 render(const LLWString &text, S32 begin_offset, F32 x, F32 y, const LLColor4 &color) const;
- S32 renderUTF8(const std::string &text, const S32 begin_offset,
- S32 x, S32 y,
- const LLColor4 &color) const
- {
- return renderUTF8(text, begin_offset, (F32)x, (F32)y, color,
- LEFT, BASELINE, NORMAL,
- S32_MAX, S32_MAX, NULL, FALSE);
- }
-
- S32 renderUTF8(const std::string &text, const S32 begin_offset,
- S32 x, S32 y,
- const LLColor4 &color,
- HAlign halign, VAlign valign, U8 style = NORMAL) const
- {
- return renderUTF8(text, begin_offset, (F32)x, (F32)y, color,
- halign, valign, style,
- S32_MAX, S32_MAX, NULL, FALSE);
- }
-
// renderUTF8 does a conversion, so is slower!
- S32 renderUTF8(const std::string &text,
- S32 begin_offset,
- F32 x, F32 y,
- const LLColor4 &color,
- HAlign halign,
- VAlign valign,
- U8 style,
- S32 max_chars,
- S32 max_pixels,
- F32* right_x,
- BOOL use_ellipses) const;
-
- S32 render(const LLWString &text, const S32 begin_offset,
- F32 x, F32 y,
- const LLColor4 &color) const
- {
- return render(text, begin_offset, x, y, color,
- LEFT, BASELINE, NORMAL,
- S32_MAX, S32_MAX, NULL, FALSE, FALSE);
- }
-
+ S32 renderUTF8(const std::string &text, S32 begin_offset, F32 x, F32 y, const LLColor4 &color, HAlign halign, VAlign valign, U8 style, ShadowType shadow, S32 max_chars, S32 max_pixels, F32* right_x, BOOL use_ellipses) const;
+ S32 renderUTF8(const std::string &text, S32 begin_offset, S32 x, S32 y, const LLColor4 &color) const;
+ S32 renderUTF8(const std::string &text, S32 begin_offset, S32 x, S32 y, const LLColor4 &color, HAlign halign, VAlign valign, U8 style = NORMAL, ShadowType shadow = NO_SHADOW) const;
- S32 render(const LLWString &text,
- S32 begin_offset,
- F32 x, F32 y,
- const LLColor4 &color,
- HAlign halign = LEFT,
- VAlign valign = BASELINE,
- U8 style = NORMAL,
- S32 max_chars = S32_MAX,
- S32 max_pixels = S32_MAX,
- F32* right_x=NULL,
- BOOL use_embedded = FALSE,
- BOOL use_ellipses = FALSE) const;
-
- // font metrics - override for LLFont that returns units of virtual pixels
- /*virtual*/ F32 getLineHeight() const { return (F32)llround(mLineHeight / sScaleY); }
- /*virtual*/ F32 getAscenderHeight() const { return (F32)llround(mAscender / sScaleY); }
- /*virtual*/ F32 getDescenderHeight() const { return (F32)llround(mDescender / sScaleY); }
-
- virtual S32 getWidth(const std::string& utf8text) const;
- virtual S32 getWidth(const llwchar* wchars) const;
- virtual S32 getWidth(const std::string& utf8text, const S32 offset, const S32 max_chars ) const;
- virtual S32 getWidth(const llwchar* wchars, const S32 offset, const S32 max_chars, BOOL use_embedded = FALSE) const;
+ // font metrics - override for LLFontFreetype that returns units of virtual pixels
+ F32 getLineHeight() const;
+ F32 getAscenderHeight() const;
+ F32 getDescenderHeight() const;
+
+ S32 getWidth(const std::string& utf8text) const;
+ S32 getWidth(const llwchar* wchars) const;
+ S32 getWidth(const std::string& utf8text, S32 offset, S32 max_chars ) const;
+ S32 getWidth(const llwchar* wchars, S32 offset, S32 max_chars) const;
- virtual F32 getWidthF32(const std::string& utf8text) const;
- virtual F32 getWidthF32(const llwchar* wchars) const;
- virtual F32 getWidthF32(const std::string& text, const S32 offset, const S32 max_chars ) const;
- virtual F32 getWidthF32(const llwchar* wchars, const S32 offset, const S32 max_chars, BOOL use_embedded = FALSE ) const;
+ F32 getWidthF32(const std::string& utf8text) const;
+ F32 getWidthF32(const llwchar* wchars) const;
+ F32 getWidthF32(const std::string& text, S32 offset, S32 max_chars ) const;
+ F32 getWidthF32(const llwchar* wchars, S32 offset, S32 max_chars) const;
// The following are called often, frequently with large buffers, so do not use a string interface
// Returns the max number of complete characters from text (up to max_chars) that can be drawn in max_pixels
- virtual S32 maxDrawableChars(const llwchar* wchars, F32 max_pixels, S32 max_chars = S32_MAX,
- BOOL end_on_word_boundary = FALSE, const BOOL use_embedded = FALSE,
- F32* drawn_pixels = NULL) const;
+ S32 maxDrawableChars(const llwchar* wchars, F32 max_pixels, S32 max_chars = S32_MAX, BOOL end_on_word_boundary = FALSE) const;
// Returns the index of the first complete characters from text that can be drawn in max_pixels
// given that the character at start_pos should be the last character (or as close to last as possible).
- virtual S32 firstDrawableChar(const llwchar* wchars, F32 max_pixels, S32 text_len, S32 start_pos=S32_MAX, S32 max_chars = S32_MAX) const;
+ S32 firstDrawableChar(const llwchar* wchars, F32 max_pixels, S32 text_len, S32 start_pos=S32_MAX, S32 max_chars = S32_MAX) const;
// Returns the index of the character closest to pixel position x (ignoring text to the right of max_pixels and max_chars)
- virtual S32 charFromPixelOffset(const llwchar* wchars, const S32 char_offset,
- F32 x, F32 max_pixels=F32_MAX, S32 max_chars = S32_MAX,
- BOOL round = TRUE, BOOL use_embedded = FALSE) const;
+ S32 charFromPixelOffset(const llwchar* wchars, S32 char_offset, F32 x, F32 max_pixels=F32_MAX, S32 max_chars = S32_MAX, BOOL round = TRUE) const;
+
+ BOOL addChar(const llwchar wch) const;
+ const LLFontDescriptor& getFontDesc() const;
- LLImageGL *getImageGL() const;
- void addEmbeddedChar( llwchar wc, LLImageGL* image, const std::string& label) const;
- void addEmbeddedChar( llwchar wc, LLImageGL* image, const LLWString& label) const;
- void removeEmbeddedChar( llwchar wc ) const;
+ static void initClass(F32 screen_dpi, F32 x_scale, F32 y_scale, const std::string& app_dir, const std::vector<std::string>& xui_paths, bool create_gl_textures = true);
+
+ // Load sans-serif, sans-serif-small, etc.
+ // Slow, requires multiple seconds to load fonts.
+ static bool loadDefaultFonts();
+ static void destroyDefaultFonts();
+ static void destroyAllGL();
+
+ // Takes a string with potentially several flags, i.e. "NORMAL|BOLD|ITALIC"
+ static U8 getStyleFromString(const std::string &style);
static std::string nameFromFont(const LLFontGL* fontp);
@@ -207,28 +156,7 @@ public:
static std::string nameFromVAlign(LLFontGL::VAlign align);
static LLFontGL::VAlign vAlignFromName(const std::string& name);
- static void setFontDisplay(BOOL flag) { sDisplayFont = flag ; }
-
-protected:
- struct embedded_data_t
- {
- embedded_data_t(LLImageGL* image, const LLWString& label) : mImage(image), mLabel(label) {}
- LLPointer<LLImageGL> mImage;
- LLWString mLabel;
- };
- const embedded_data_t* getEmbeddedCharData(const llwchar wch) const;
- F32 getEmbeddedCharAdvance(const embedded_data_t* ext_data) const;
- void clearEmbeddedChars();
- void renderQuad(const LLRectf& screen_rect, const LLRectf& uv_rect, F32 slant_amt) const;
- void drawGlyph(const LLRectf& screen_rect, const LLRectf& uv_rect, const LLColor4& color, U8 style, F32 drop_shadow_fade) const;
-
-public:
- static F32 sVertDPI;
- static F32 sHorizDPI;
- static F32 sScaleX;
- static F32 sScaleY;
- static BOOL sDisplayFont ;
- static std::string sAppDir; // For loading fonts
+ static void setFontDisplay(BOOL flag) { sDisplayFont = flag; }
static LLFontGL* getFontMonospace();
static LLFontGL* getFontSansSerifSmall();
@@ -238,33 +166,40 @@ public:
static LLFontGL* getFontSansSerifBold();
static LLFontGL* getFontExtChar();
static LLFontGL* getFont(const LLFontDescriptor& desc);
+ // Use with legacy names like "SANSSERIF_SMALL" or "OCRA"
+ static LLFontGL* getFontByName(const std::string& name);
+
+ static std::string getFontPathLocal();
+ static std::string getFontPathSystem();
+
+ static LLCoordFont sCurOrigin;
+ static std::vector<LLCoordFont> sOriginStack;
static LLColor4 sShadowColor;
+ static F32 sVertDPI;
+ static F32 sHorizDPI;
+ static F32 sScaleX;
+ static F32 sScaleY;
+ static BOOL sDisplayFont ;
+ static std::string sAppDir; // For loading fonts
+
+private:
+ friend class LLFontRegistry;
friend class LLTextBillboard;
friend class LLHUDText;
-protected:
- /*virtual*/ BOOL addChar(const llwchar wch) const;
+ LLFontGL(const LLFontGL &source);
+ LLFontGL &operator=(const LLFontGL &source);
-protected:
- typedef std::map<llwchar,embedded_data_t*> embedded_map_t;
- mutable embedded_map_t mEmbeddedChars;
-
- LLFontDescriptor mFontDesc;
+ LLFontDescriptor mFontDescriptor;
+ LLPointer<LLFontFreetype> mFontFreetype;
+
+ void renderQuad(const LLRectf& screen_rect, const LLRectf& uv_rect, F32 slant_amt) const;
+ void drawGlyph(const LLRectf& screen_rect, const LLRectf& uv_rect, const LLColor4& color, U8 style, ShadowType shadow, F32 drop_shadow_fade) const;
// Registry holds all instantiated fonts.
static LLFontRegistry* sFontRegistry;
-
-public:
- static std::string getFontPathLocal();
- static std::string getFontPathSystem();
-
- static LLCoordFont sCurOrigin;
- static std::vector<LLCoordFont> sOriginStack;
-
- const LLFontDescriptor &getFontDesc() const { return mFontDesc; }
- void setFontDesc(const LLFontDescriptor& font_desc) { mFontDesc = font_desc; }
};
#endif
diff --git a/indra/llrender/llfontregistry.cpp b/indra/llrender/llfontregistry.cpp
index 9b5bc5d0af..99f364a589 100644
--- a/indra/llrender/llfontregistry.cpp
+++ b/indra/llrender/llfontregistry.cpp
@@ -5,7 +5,7 @@
*
* $LicenseInfo:firstyear=2008&license=viewergpl$
*
- * Copyright (c) 2008, Linden Research, Inc.
+ * Copyright (c) 2008-2009, Linden Research, Inc.
*
* Second Life Viewer Source Code
* The source code in this file ("Source Code") is provided by Linden Lab
@@ -13,12 +13,13 @@
* ("GPL"), unless you have obtained a separate licensing agreement
* ("Other License"), formally executed by you and Linden Lab. Terms of
* the GPL can be found in doc/GPL-license.txt in this distribution, or
- * online at http://secondlife.com/developers/opensource/gplv2
+ * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
*
* There are special exceptions to the terms and conditions of the GPL as
* it is applied to this Source Code. View the full text of the exception
* in the file doc/FLOSS-exception.txt in this software distribution, or
- * online at http://secondlife.com/developers/opensource/flossexception
+ * online at
+ * http://secondlifegrid.net/programs/open_source/licensing/flossexception
*
* By copying, modifying or distributing this software, you acknowledge
* that you have read and understood your obligations described above,
@@ -32,8 +33,9 @@
#include "linden_common.h"
#include "llgl.h"
-#include "llfontregistry.h"
+#include "llfontfreetype.h"
#include "llfontgl.h"
+#include "llfontregistry.h"
#include <boost/tokenizer.hpp>
#include "llcontrol.h"
#include "lldir.h"
@@ -103,7 +105,7 @@ bool removeSubString(std::string& str, const std::string& substr)
size_t pos = str.find(substr);
if (pos != string::npos)
{
- str.replace(pos,substr.length(),(const char *)NULL, 0);
+ str.erase(pos);
return true;
}
return false;
@@ -167,7 +169,9 @@ LLFontDescriptor LLFontDescriptor::normalize() const
return LLFontDescriptor(new_name,new_size,new_style,getFileNames());
}
-LLFontRegistry::LLFontRegistry(const string_vec_t& xui_paths)
+LLFontRegistry::LLFontRegistry(const string_vec_t& xui_paths,
+ bool create_gl_textures)
+: mCreateGLTextures(create_gl_textures)
{
// Propagate this down from LLUICtrlFactory so LLRender doesn't
// need an upstream dependency on LLUI.
@@ -215,8 +219,8 @@ bool LLFontRegistry::parseFontInfo(const std::string& xml_filename)
success = success || init_succ;
}
}
- if (success)
- dump();
+ //if (success)
+ // dump();
return success;
}
@@ -379,7 +383,14 @@ LLFontGL *LLFontRegistry::createFont(const LLFontDescriptor& desc)
if (it != mFontMap.end())
{
llinfos << "-- matching font exists: " << nearest_exact_desc.getName() << " size " << nearest_exact_desc.getSize() << " style " << ((S32) nearest_exact_desc.getStyle()) << llendl;
- return it->second;
+
+ // copying underlying Freetype font, and storing in LLFontGL with requested font descriptor
+ LLFontGL *font = new LLFontGL;
+ font->mFontDescriptor = desc;
+ font->mFontFreetype = it->second->mFontFreetype;
+ mFontMap[desc] = font;
+
+ return font;
}
// Build list of font names to look for.
@@ -407,10 +418,11 @@ LLFontGL *LLFontRegistry::createFont(const LLFontDescriptor& desc)
llwarns << "createFont failed, no file names specified" << llendl;
return NULL;
}
- LLFontList *fontlistp = new LLFontList;
+
+ LLFontFreetype::font_vector_t fontlist;
LLFontGL *result = NULL;
- // Snarf all fonts we can into fontlistp. First will get pulled
+ // Snarf all fonts we can into fontlist. First will get pulled
// off the list and become the "head" font, set to non-fallback.
// Rest will consitute the fallback list.
BOOL is_first_found = TRUE;
@@ -426,7 +438,9 @@ LLFontGL *LLFontRegistry::createFont(const LLFontDescriptor& desc)
{
LLFontGL *fontp = new LLFontGL;
std::string font_path = local_path + *file_name_it;
- BOOL is_fallback = !is_first_found;
+ // *HACK: Fallback fonts don't render, so we can use that to suppress
+ // creation of OpenGL textures for test apps. JC
+ BOOL is_fallback = !is_first_found || !mCreateGLTextures;
F32 extra_scale = (is_fallback)?fallback_scale:1.0;
if (!fontp->loadFace(font_path, extra_scale * point_size,
LLFontGL::sVertDPI, LLFontGL::sHorizDPI, 2, is_fallback))
@@ -450,23 +464,27 @@ LLFontGL *LLFontRegistry::createFont(const LLFontDescriptor& desc)
is_first_found = false;
}
else
- fontlistp->addAtEnd(fontp);
+ {
+ fontlist.push_back(fontp->mFontFreetype);
+ }
}
}
- if (result && !fontlistp->empty())
+
+ if (result && !fontlist.empty())
{
- result->setFallbackFont(fontlistp);
+ result->mFontFreetype->setFallbackFonts(fontlist);
}
- norm_desc.setStyle(match_desc->getStyle());
if (result)
- result->setFontDesc(norm_desc);
-
- if (!result)
+ {
+ result->mFontDescriptor = desc;
+ }
+ else
{
llwarns << "createFont failed in some way" << llendl;
}
- mFontMap[norm_desc] = result;
+
+ mFontMap[desc] = result;
return result;
}
@@ -506,21 +524,19 @@ void LLFontRegistry::destroyGL()
}
}
-LLFontGL *LLFontRegistry::getFont(const LLFontDescriptor& orig_desc)
+LLFontGL *LLFontRegistry::getFont(const LLFontDescriptor& desc)
{
- LLFontDescriptor norm_desc = orig_desc.normalize();
-
- font_reg_map_t::iterator it = mFontMap.find(norm_desc);
+ font_reg_map_t::iterator it = mFontMap.find(desc);
if (it != mFontMap.end())
return it->second;
else
{
- LLFontGL *fontp = createFont(orig_desc);
+ LLFontGL *fontp = createFont(desc);
if (!fontp)
{
- llwarns << "getFont failed, name " << orig_desc.getName()
- <<" style=[" << ((S32) orig_desc.getStyle()) << "]"
- << " size=[" << orig_desc.getSize() << "]" << llendl;
+ llwarns << "getFont failed, name " << desc.getName()
+ <<" style=[" << ((S32) desc.getStyle()) << "]"
+ << " size=[" << desc.getSize() << "]" << llendl;
}
return fontp;
}
@@ -648,3 +664,8 @@ void LLFontRegistry::dump()
}
}
}
+
+const string_vec_t& LLFontRegistry::getUltimateFallbackList() const
+{
+ return mUltimateFallbackList;
+}
diff --git a/indra/llrender/llfontregistry.h b/indra/llrender/llfontregistry.h
index ed775eeed0..4da4ca48bb 100644
--- a/indra/llrender/llfontregistry.h
+++ b/indra/llrender/llfontregistry.h
@@ -5,7 +5,7 @@
*
* $LicenseInfo:firstyear=2008&license=viewergpl$
*
- * Copyright (c) 2008, Linden Research, Inc.
+ * Copyright (c) 2008-2009, Linden Research, Inc.
*
* Second Life Viewer Source Code
* The source code in this file ("Source Code") is provided by Linden Lab
@@ -13,12 +13,13 @@
* ("GPL"), unless you have obtained a separate licensing agreement
* ("Other License"), formally executed by you and Linden Lab. Terms of
* the GPL can be found in doc/GPL-license.txt in this distribution, or
- * online at http://secondlife.com/developers/opensource/gplv2
+ * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
*
* There are special exceptions to the terms and conditions of the GPL as
* it is applied to this Source Code. View the full text of the exception
* in the file doc/FLOSS-exception.txt in this software distribution, or
- * online at http://secondlife.com/developers/opensource/flossexception
+ * online at
+ * http://secondlifegrid.net/programs/open_source/licensing/flossexception
*
* By copying, modifying or distributing this software, you acknowledge
* that you have read and understood your obligations described above,
@@ -70,7 +71,10 @@ private:
class LLFontRegistry
{
public:
- LLFontRegistry(const string_vec_t& xui_paths);
+ // create_gl_textures - set to false for test apps with no OpenGL window,
+ // such as llui_libtest
+ LLFontRegistry(const string_vec_t& xui_paths,
+ bool create_gl_textures);
~LLFontRegistry();
// Load standard font info from XML file(s).
@@ -94,7 +98,7 @@ public:
void dump();
- const string_vec_t& getUltimateFallbackList() const { return mUltimateFallbackList; }
+ const string_vec_t& getUltimateFallbackList() const;
private:
LLFontGL *createFont(const LLFontDescriptor& desc);
@@ -108,6 +112,7 @@ private:
string_vec_t mUltimateFallbackList;
string_vec_t mXUIPaths;
+ bool mCreateGLTextures;
};
#endif // LL_LLFONTREGISTRY_H
diff --git a/indra/llrender/llgl.cpp b/indra/llrender/llgl.cpp
index 61194c4ecf..7e1df0e565 100644
--- a/indra/llrender/llgl.cpp
+++ b/indra/llrender/llgl.cpp
@@ -45,10 +45,13 @@
#include "llrender.h"
#include "llerror.h"
+#include "llerrorcontrol.h"
#include "llquaternion.h"
#include "llmath.h"
#include "m4math.h"
#include "llstring.h"
+#include "llmemtype.h"
+#include "llstacktrace.h"
#include "llglheaders.h"
@@ -56,9 +59,49 @@
//#define GL_STATE_VERIFY
#endif
+
+BOOL gDebugSession = FALSE;
BOOL gDebugGL = FALSE;
BOOL gClothRipple = FALSE;
BOOL gNoRender = FALSE;
+
+std::ofstream gFailLog;
+
+void ll_init_fail_log(std::string filename)
+{
+ gFailLog.open(filename.c_str());
+}
+
+
+void ll_fail(std::string msg)
+{
+
+ if (gDebugSession)
+ {
+ std::vector<std::string> lines;
+
+ gFailLog << LLError::utcTime() << " " << msg << std::endl;
+
+ gFailLog << "Stack Trace:" << std::endl;
+
+ ll_get_stack_trace(lines);
+
+ for(size_t i = 0; i < lines.size(); ++i)
+ {
+ gFailLog << lines[i] << std::endl;
+ }
+
+ gFailLog << "End of Stack Trace." << std::endl << std::endl;
+
+ gFailLog.flush();
+ }
+};
+
+void ll_close_fail_log()
+{
+ gFailLog.close();
+}
+
LLMatrix4 gGLObliqueProjectionInverse;
#define LL_GL_NAME_POOLING 0
@@ -596,6 +639,7 @@ void LLGLManager::initExtensions()
mHasShaderObjects = FALSE;
mHasVertexShader = FALSE;
mHasFragmentShader = FALSE;
+ mHasTextureRectangle = FALSE;
#else // LL_MESA_HEADLESS
mHasMultitexture = glh_init_extensions("GL_ARB_multitexture");
mHasMipMapGeneration = glh_init_extensions("GL_SGIS_generate_mipmap");
@@ -612,6 +656,7 @@ void LLGLManager::initExtensions()
&& ExtensionExists("GL_EXT_packed_depth_stencil", gGLHExts.mSysExts);
mHasFramebufferMultisample = mHasFramebufferObject && ExtensionExists("GL_EXT_framebuffer_multisample", gGLHExts.mSysExts);
mHasDrawBuffers = ExtensionExists("GL_ARB_draw_buffers", gGLHExts.mSysExts);
+ mHasTextureRectangle = ExtensionExists("GL_ARB_texture_rectangle", gGLHExts.mSysExts);
#if !LL_DARWIN
mHasPointParameters = !mIsATI && ExtensionExists("GL_ARB_point_parameters", gGLHExts.mSysExts);
#endif
@@ -685,6 +730,7 @@ void LLGLManager::initExtensions()
if (strchr(blacklist,'q')) mHasFramebufferObject = FALSE;//S
if (strchr(blacklist,'r')) mHasDrawBuffers = FALSE;//S
if (strchr(blacklist,'s')) mHasFramebufferMultisample = FALSE;
+ if (strchr(blacklist,'t')) mHasTextureRectangle = FALSE;
}
#endif // LL_LINUX || LL_SOLARIS
@@ -971,6 +1017,7 @@ void assert_glerror()
{
return;
}
+
if (!gGLManager.mInited)
{
LL_ERRS("RenderInit") << "GL not initialized" << LL_ENDL;
@@ -988,12 +1035,22 @@ void assert_glerror()
{
LL_WARNS("RenderState") << "GL Error:" << error<< LL_ENDL;
LL_WARNS("RenderState") << "GL Error String:" << gl_error_msg << LL_ENDL;
+
+ if (gDebugSession)
+ {
+ gFailLog << "GL Error:" << gl_error_msg << std::endl;
+ }
}
else
{
// gluErrorString returns NULL for some extensions' error codes.
// you'll probably have to grep for the number in glext.h.
LL_WARNS("RenderState") << "GL Error: UNKNOWN 0x" << std::hex << error << std::dec << LL_ENDL;
+
+ if (gDebugSession)
+ {
+ gFailLog << "GL Error: UNKNOWN 0x" << std::hex << error << std::dec << std::endl;
+ }
}
error = glGetError();
#endif
@@ -1001,7 +1058,14 @@ void assert_glerror()
if (quit)
{
- llerrs << "One or more unhandled GL errors." << llendl;
+ if (gDebugSession)
+ {
+ ll_fail("assert_glerror failed");
+ }
+ else
+ {
+ llerrs << "One or more unhandled GL errors." << llendl;
+ }
}
}
@@ -1087,9 +1151,19 @@ void LLGLState::checkStates(const std::string& msg)
glGetIntegerv(GL_BLEND_SRC, &src);
glGetIntegerv(GL_BLEND_DST, &dst);
+ BOOL error = FALSE;
+
if (src != GL_SRC_ALPHA || dst != GL_ONE_MINUS_SRC_ALPHA)
{
- LL_GL_ERRS << "Blend function corrupted: " << std::hex << src << " " << std::hex << dst << " " << msg << std::dec << LL_ENDL;
+ if (gDebugSession)
+ {
+ gFailLog << "Blend function corrupted: " << std::hex << src << " " << std::hex << dst << " " << msg << std::dec << std::endl;
+ error = TRUE;
+ }
+ else
+ {
+ LL_GL_ERRS << "Blend function corrupted: " << std::hex << src << " " << std::hex << dst << " " << msg << std::dec << LL_ENDL;
+ }
}
for (std::map<LLGLenum, LLGLboolean>::iterator iter = sStateMap.begin();
@@ -1101,10 +1175,22 @@ void LLGLState::checkStates(const std::string& msg)
if(cur_state != gl_state)
{
dumpStates();
- LL_GL_ERRS << llformat("LLGLState error. State: 0x%04x",state) << LL_ENDL;
+ if (gDebugSession)
+ {
+ gFailLog << llformat("LLGLState error. State: 0x%04x",state) << std::endl;
+ error = TRUE;
+ }
+ else
+ {
+ LL_GL_ERRS << llformat("LLGLState error. State: 0x%04x",state) << LL_ENDL;
+ }
}
}
+ if (error)
+ {
+ ll_fail("LLGLState::checkStates failed.");
+ }
stop_glerror();
}
@@ -1115,9 +1201,12 @@ void LLGLState::checkTextureChannels(const std::string& msg)
return;
}
+ stop_glerror();
+
GLint activeTexture;
glGetIntegerv(GL_ACTIVE_TEXTURE_ARB, &activeTexture);
-
+ stop_glerror();
+
BOOL error = FALSE;
if (activeTexture == GL_TEXTURE0_ARB)
@@ -1125,15 +1214,22 @@ void LLGLState::checkTextureChannels(const std::string& msg)
GLint tex_env_mode = 0;
glGetTexEnviv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, &tex_env_mode);
+ stop_glerror();
+
if (tex_env_mode != GL_MODULATE)
{
error = TRUE;
LL_WARNS("RenderState") << "GL_TEXTURE_ENV_MODE invalid: " << std::hex << tex_env_mode << std::dec << LL_ENDL;
+ if (gDebugSession)
+ {
+ gFailLog << "GL_TEXTURE_ENV_MODE invalid: " << std::hex << tex_env_mode << std::dec << std::endl;
+ }
}
}
- GLint maxTextureUnits;
+ GLint maxTextureUnits = 0;
glGetIntegerv(GL_MAX_TEXTURE_UNITS_ARB, &maxTextureUnits);
+ stop_glerror();
static const char* label[] =
{
@@ -1169,30 +1265,48 @@ void LLGLState::checkTextureChannels(const std::string& msg)
{
gGL.getTexUnit(i)->activate();
glClientActiveTextureARB(GL_TEXTURE0_ARB+i);
-
+ stop_glerror();
glGetIntegerv(GL_TEXTURE_STACK_DEPTH, &stackDepth);
+ stop_glerror();
if (stackDepth != 1)
{
error = TRUE;
LL_WARNS("RenderState") << "Texture matrix stack corrupted." << LL_ENDL;
+
+ if (gDebugSession)
+ {
+ gFailLog << "Texture matrix stack corrupted." << std::endl;
+ }
}
glGetFloatv(GL_TEXTURE_MATRIX, (GLfloat*) matrix.mMatrix);
+ stop_glerror();
if (matrix != identity)
{
error = TRUE;
LL_WARNS("RenderState") << "Texture matrix in channel " << i << " corrupt." << LL_ENDL;
+ if (gDebugSession)
+ {
+ gFailLog << "Texture matrix in channel " << i << " corrupt." << std::endl;
+ }
}
- for (S32 j = (i == 0 ? 1 : 0); j < 9; j++)
+
+ for (S32 j = (i == 0 ? 1 : 0);
+ j < (gGLManager.mHasTextureRectangle ? 9 : 8); j++)
{
if (glIsEnabled(value[j]))
{
error = TRUE;
LL_WARNS("RenderState") << "Texture channel " << i << " still has " << label[j] << " enabled." << LL_ENDL;
+ if (gDebugSession)
+ {
+ gFailLog << "Texture channel " << i << " still has " << label[j] << " enabled." << std::endl;
+ }
}
+ stop_glerror();
}
glh::matrix4f mat;
@@ -1200,20 +1314,33 @@ void LLGLState::checkTextureChannels(const std::string& msg)
identity.identity();
glGetFloatv(GL_TEXTURE_MATRIX, mat.m);
+ stop_glerror();
if (mat != identity)
{
error = TRUE;
LL_WARNS("RenderState") << "Texture matrix " << i << " is not identity." << LL_ENDL;
+ if (gDebugSession)
+ {
+ gFailLog << "Texture matrix " << i << " is not identity." << std::endl;
+ }
}
}
gGL.getTexUnit(0)->activate();
glClientActiveTextureARB(GL_TEXTURE0_ARB);
+ stop_glerror();
if (error)
{
- LL_GL_ERRS << "GL texture state corruption detected. " << msg << LL_ENDL;
+ if (gDebugSession)
+ {
+ ll_fail("LLGLState::checkTextureChannels failed.");
+ }
+ else
+ {
+ LL_GL_ERRS << "GL texture state corruption detected. " << msg << LL_ENDL;
+ }
}
}
@@ -1233,6 +1360,10 @@ void LLGLState::checkClientArrays(const std::string& msg, U32 data_mask)
if (active_texture != GL_TEXTURE0_ARB)
{
llwarns << "Client active texture corrupted: " << active_texture << llendl;
+ if (gDebugSession)
+ {
+ gFailLog << "Client active texture corrupted: " << active_texture << std::endl;
+ }
error = TRUE;
}
@@ -1240,6 +1371,10 @@ void LLGLState::checkClientArrays(const std::string& msg, U32 data_mask)
if (active_texture != GL_TEXTURE0_ARB)
{
llwarns << "Active texture corrupted: " << active_texture << llendl;
+ if (gDebugSession)
+ {
+ gFailLog << "Active texture corrupted: " << active_texture << std::endl;
+ }
error = TRUE;
}
@@ -1276,6 +1411,10 @@ void LLGLState::checkClientArrays(const std::string& msg, U32 data_mask)
{
error = TRUE;
LL_WARNS("RenderState") << "GL still has " << label[j] << " enabled." << LL_ENDL;
+ if (gDebugSession)
+ {
+ gFailLog << "GL still has " << label[j] << " enabled." << std::endl;
+ }
}
}
else
@@ -1284,6 +1423,10 @@ void LLGLState::checkClientArrays(const std::string& msg, U32 data_mask)
{
error = TRUE;
LL_WARNS("RenderState") << "GL does not have " << label[j] << " enabled." << LL_ENDL;
+ if (gDebugSession)
+ {
+ gFailLog << "GL does not have " << label[j] << " enabled." << std::endl;
+ }
}
}
}
@@ -1296,6 +1439,10 @@ void LLGLState::checkClientArrays(const std::string& msg, U32 data_mask)
{
error = TRUE;
LL_WARNS("RenderState") << "GL still has GL_TEXTURE_COORD_ARRAY enabled on channel 1." << LL_ENDL;
+ if (gDebugSession)
+ {
+ gFailLog << "GL still has GL_TEXTURE_COORD_ARRAY enabled on channel 1." << std::endl;
+ }
}
}
else
@@ -1304,6 +1451,10 @@ void LLGLState::checkClientArrays(const std::string& msg, U32 data_mask)
{
error = TRUE;
LL_WARNS("RenderState") << "GL does not have GL_TEXTURE_COORD_ARRAY enabled on channel 1." << LL_ENDL;
+ if (gDebugSession)
+ {
+ gFailLog << "GL does not have GL_TEXTURE_COORD_ARRAY enabled on channel 1." << std::endl;
+ }
}
}
@@ -1313,6 +1464,10 @@ void LLGLState::checkClientArrays(const std::string& msg, U32 data_mask)
{
error = TRUE;
LL_WARNS("RenderState") << "GL still has GL_TEXTURE_2D enabled on channel 1." << LL_ENDL;
+ if (gDebugSession)
+ {
+ gFailLog << "GL still has GL_TEXTURE_2D enabled on channel 1." << std::endl;
+ }
}
}
else
@@ -1321,6 +1476,10 @@ void LLGLState::checkClientArrays(const std::string& msg, U32 data_mask)
{
error = TRUE;
LL_WARNS("RenderState") << "GL does not have GL_TEXTURE_2D enabled on channel 1." << LL_ENDL;
+ if (gDebugSession)
+ {
+ gFailLog << "GL does not have GL_TEXTURE_2D enabled on channel 1." << std::endl;
+ }
}
}
@@ -1339,13 +1498,24 @@ void LLGLState::checkClientArrays(const std::string& msg, U32 data_mask)
{
error = TRUE;
LL_WARNS("RenderState") << "GL still has vertex attrib array " << i << " enabled." << LL_ENDL;
+ if (gDebugSession)
+ {
+ gFailLog << "GL still has vertex attrib array " << i << " enabled." << std::endl;
+ }
}
}
}
if (error)
{
- LL_GL_ERRS << "GL client array corruption detected. " << msg << LL_ENDL;
+ if (gDebugSession)
+ {
+ ll_fail("LLGLState::checkClientArrays failed.");
+ }
+ else
+ {
+ LL_GL_ERRS << "GL client array corruption detected. " << msg << LL_ENDL;
+ }
}
}
@@ -1396,7 +1566,17 @@ LLGLState::~LLGLState()
{
if (gDebugGL)
{
- llassert_always(sStateMap[mState] == glIsEnabled(mState));
+ if (!gDebugSession)
+ {
+ llassert_always(sStateMap[mState] == glIsEnabled(mState));
+ }
+ else
+ {
+ if (sStateMap[mState] != glIsEnabled(mState))
+ {
+ ll_fail("GL enabled state does not match expected");
+ }
+ }
}
if (mIsEnabled != mWasEnabled)
@@ -1708,6 +1888,7 @@ void LLGLNamePool::release(GLuint name)
//static
void LLGLNamePool::upkeepPools()
{
+ LLMemType mt(LLMemType::MTYPE_UPKEEP_POOLS);
for (pool_list_t::iterator iter = sInstances.begin(); iter != sInstances.end(); ++iter)
{
LLGLNamePool* pool = *iter;
diff --git a/indra/llrender/llgl.h b/indra/llrender/llgl.h
index 00ff1e2f53..34dd982259 100644
--- a/indra/llrender/llgl.h
+++ b/indra/llrender/llgl.h
@@ -50,9 +50,17 @@
#include "glh/glh_linear.h"
extern BOOL gDebugGL;
+extern BOOL gDebugSession;
+extern std::ofstream gFailLog;
#define LL_GL_ERRS LL_ERRS("RenderState")
+void ll_init_fail_log(std::string filename);
+
+void ll_fail(std::string msg);
+
+void ll_close_fail_log();
+
class LLSD;
// Manage GL extensions...
@@ -88,6 +96,7 @@ public:
BOOL mHasOcclusionQuery;
BOOL mHasPointParameters;
BOOL mHasDrawBuffers;
+ BOOL mHasTextureRectangle;
// Other extensions.
BOOL mHasAnisotropic;
diff --git a/indra/llrender/llglslshader.cpp b/indra/llrender/llglslshader.cpp
index 9e34144658..830617063b 100644
--- a/indra/llrender/llglslshader.cpp
+++ b/indra/llrender/llglslshader.cpp
@@ -408,7 +408,15 @@ S32 LLGLSLShader::disableTexture(S32 uniform, LLTexUnit::eTextureType mode)
{
if (gDebugGL && gGL.getTexUnit(index)->getCurrType() != mode)
{
- llerrs << "Texture channel " << index << " texture type corrupted." << llendl;
+ if (gDebugSession)
+ {
+ gFailLog << "Texture channel " << index << " texture type corrupted." << std::endl;
+ ll_fail("LLGLSLShader::disableTexture failed");
+ }
+ else
+ {
+ llerrs << "Texture channel " << index << " texture type corrupted." << llendl;
+ }
}
gGL.getTexUnit(index)->disable();
}
diff --git a/indra/llrender/llimagegl.cpp b/indra/llrender/llimagegl.cpp
index d1efb119c6..9d2cd4867a 100644
--- a/indra/llrender/llimagegl.cpp
+++ b/indra/llrender/llimagegl.cpp
@@ -46,7 +46,6 @@
//----------------------------------------------------------------------------
-
const F32 MIN_TEXTURE_LIFETIME = 10.f;
//statics
@@ -61,8 +60,9 @@ S32 LLImageGL::sCount = 0;
BOOL LLImageGL::sGlobalUseAnisotropic = FALSE;
F32 LLImageGL::sLastFrameTime = 0.f;
-
+LLImageGL* LLImageGL::sDefaultGLTexture = NULL ;
std::set<LLImageGL*> LLImageGL::sImageList;
+
//**************************************************************************************
//below are functions for debug use
//do not delete them even though they are not currently being used.
@@ -87,9 +87,18 @@ void LLImageGL::checkTexSize() const
{
GLint texname;
glGetIntegerv(GL_TEXTURE_BINDING_2D, &texname);
+ BOOL error = FALSE;
if (texname != mTexName)
{
- llerrs << "Invalid texture bound!" << llendl;
+ error = TRUE;
+ if (gDebugSession)
+ {
+ gFailLog << "Invalid texture bound!" << std::endl;
+ }
+ else
+ {
+ llerrs << "Invalid texture bound!" << llendl;
+ }
}
stop_glerror() ;
LLGLint x = 0, y = 0 ;
@@ -102,7 +111,20 @@ void LLImageGL::checkTexSize() const
}
if(x != (mWidth >> mCurrentDiscardLevel) || y != (mHeight >> mCurrentDiscardLevel))
{
- llerrs << "wrong texture size and discard level!" << llendl ;
+ error = TRUE;
+ if (gDebugSession)
+ {
+ gFailLog << "wrong texture size and discard level!" << std::endl;
+ }
+ else
+ {
+ llerrs << "wrong texture size and discard level!" << llendl ;
+ }
+ }
+
+ if (error)
+ {
+ ll_fail("LLImageGL::checkTexSize failed.");
}
}
}
@@ -241,6 +263,7 @@ void LLImageGL::restoreGL()
//----------------------------------------------------------------------------
+//for server side use only.
//static
BOOL LLImageGL::create(LLPointer<LLImageGL>& dest, BOOL usemipmaps)
{
@@ -248,12 +271,14 @@ BOOL LLImageGL::create(LLPointer<LLImageGL>& dest, BOOL usemipmaps)
return TRUE;
}
+//for server side use only.
BOOL LLImageGL::create(LLPointer<LLImageGL>& dest, U32 width, U32 height, U8 components, BOOL usemipmaps)
{
dest = new LLImageGL(width, height, components, usemipmaps);
return TRUE;
}
+//for server side use only.
BOOL LLImageGL::create(LLPointer<LLImageGL>& dest, const LLImageRaw* imageraw, BOOL usemipmaps)
{
dest = new LLImageGL(imageraw, usemipmaps);
@@ -308,7 +333,6 @@ void LLImageGL::init(BOOL usemipmaps)
#endif
mPickMask = NULL;
- mTextureState = NO_DELETE ;
mTextureMemory = 0;
mLastBindTime = 0.f;
@@ -328,8 +352,7 @@ void LLImageGL::init(BOOL usemipmaps)
mComponents = 0;
mMaxDiscardLevel = MAX_DISCARD_LEVEL;
- mCurrentDiscardLevel = -1;
- mDontDiscard = FALSE;
+ mCurrentDiscardLevel = -1;
mFormatInternal = -1;
mFormatPrimary = (LLGLenum) 0;
@@ -339,6 +362,7 @@ void LLImageGL::init(BOOL usemipmaps)
mGLTextureCreated = FALSE ;
mIsMask = FALSE;
+ mNeedsAlphaAndPickMask = TRUE ;
}
void LLImageGL::cleanup()
@@ -439,7 +463,7 @@ void LLImageGL::dump()
//----------------------------------------------------------------------------
-void LLImageGL::updateBindStats(void) const
+BOOL LLImageGL::updateBindStats(S32 tex_mem) const
{
if (mTexName != 0)
{
@@ -451,28 +475,18 @@ void LLImageGL::updateBindStats(void) const
{
// we haven't accounted for this texture yet this frame
sUniqueCount++;
- updateBoundTexMem(mTextureMemory);
+ updateBoundTexMem(tex_mem);
mLastBindTime = sLastFrameTime;
+
+ return TRUE ;
}
}
+ return FALSE ;
}
-//virtual
-bool LLImageGL::bindError(const S32 stage) const
+F32 LLImageGL::getTimePassedSinceLastBound()
{
- return false;
-}
-
-//virtual
-bool LLImageGL::bindDefaultImage(const S32 stage) const
-{
- return false;
-}
-
-//virtual
-void LLImageGL::forceImmediateUpdate()
-{
- return ;
+ return sLastFrameTime - mLastBindTime ;
}
void LLImageGL::setExplicitFormat( LLGLint internal_format, LLGLenum primary_format, LLGLenum type_format, BOOL swap_bytes )
@@ -502,7 +516,6 @@ void LLImageGL::setImage(const LLImageRaw* imageraw)
void LLImageGL::setImage(const U8* data_in, BOOL data_hasmips)
{
-// LLFastTimer t1(LLFastTimer::FTM_TEMP1);
llpushcallstacks ;
bool is_compressed = false;
if (mFormatPrimary >= GL_COMPRESSED_RGBA_S3TC_DXT1_EXT && mFormatPrimary <= GL_COMPRESSED_RGBA_S3TC_DXT5_EXT)
@@ -510,12 +523,10 @@ void LLImageGL::setImage(const U8* data_in, BOOL data_hasmips)
is_compressed = true;
}
-// LLFastTimer t2(LLFastTimer::FTM_TEMP2);
gGL.getTexUnit(0)->bind(this);
if (mUseMipMaps)
{
-// LLFastTimer t2(LLFastTimer::FTM_TEMP3);
if (data_hasmips)
{
// NOTE: data_in points to largest image; smaller images
@@ -532,14 +543,13 @@ void LLImageGL::setImage(const U8* data_in, BOOL data_hasmips)
}
if (is_compressed)
{
-// LLFastTimer t2(LLFastTimer::FTM_TEMP4);
S32 tex_size = dataFormatBytes(mFormatPrimary, w, h);
glCompressedTexImage2DARB(mTarget, gl_level, mFormatPrimary, w, h, 0, tex_size, (GLvoid *)data_in);
stop_glerror();
}
else
{
-// LLFastTimer t2(LLFastTimer::FTM_TEMP4);
+// LLFastTimer t2(FTM_TEMP4);
if(mFormatSwapBytes)
{
@@ -572,7 +582,7 @@ void LLImageGL::setImage(const U8* data_in, BOOL data_hasmips)
glTexParameteri(LLTexUnit::getInternalType(mBindTarget), GL_GENERATE_MIPMAP_SGIS, TRUE);
stop_glerror();
{
-// LLFastTimer t2(LLFastTimer::FTM_TEMP4);
+// LLFastTimer t2(FTM_TEMP4);
if(mFormatSwapBytes)
{
@@ -632,7 +642,7 @@ void LLImageGL::setImage(const U8* data_in, BOOL data_hasmips)
}
llassert(w > 0 && h > 0 && cur_mip_data);
{
-// LLFastTimer t1(LLFastTimer::FTM_TEMP4);
+// LLFastTimer t1(FTM_TEMP4);
if(mFormatSwapBytes)
{
glPixelStorei(GL_UNPACK_SWAP_BYTES, 1);
@@ -680,7 +690,6 @@ void LLImageGL::setImage(const U8* data_in, BOOL data_hasmips)
}
else
{
-// LLFastTimer t2(LLFastTimer::FTM_TEMP5);
S32 w = getWidth();
S32 h = getHeight();
if (is_compressed)
@@ -719,7 +728,7 @@ void LLImageGL::setImage(const U8* data_in, BOOL data_hasmips)
llpushcallstacks ;
}
-BOOL LLImageGL::setSubImage(const U8* datap, S32 data_width, S32 data_height, S32 x_pos, S32 y_pos, S32 width, S32 height)
+BOOL LLImageGL::setSubImage(const U8* datap, S32 data_width, S32 data_height, S32 x_pos, S32 y_pos, S32 width, S32 height, BOOL force_fast_update)
{
llpushcallstacks ;
if (!width || !height)
@@ -737,7 +746,8 @@ BOOL LLImageGL::setSubImage(const U8* datap, S32 data_width, S32 data_height, S3
return FALSE;
}
- if (x_pos == 0 && y_pos == 0 && width == getWidth() && height == getHeight() && data_width == width && data_height == height)
+ // HACK: allow the caller to explicitly force the fast path (i.e. using glTexSubImage2D here instead of calling setImage) even when updating the full texture.
+ if (!force_fast_update && x_pos == 0 && y_pos == 0 && width == getWidth() && height == getHeight() && data_width == width && data_height == height)
{
setImage(datap, FALSE);
}
@@ -814,9 +824,9 @@ BOOL LLImageGL::setSubImage(const U8* datap, S32 data_width, S32 data_height, S3
return TRUE;
}
-BOOL LLImageGL::setSubImage(const LLImageRaw* imageraw, S32 x_pos, S32 y_pos, S32 width, S32 height)
+BOOL LLImageGL::setSubImage(const LLImageRaw* imageraw, S32 x_pos, S32 y_pos, S32 width, S32 height, BOOL force_fast_update)
{
- return setSubImage(imageraw->getData(), imageraw->getWidth(), imageraw->getHeight(), x_pos, y_pos, width, height);
+ return setSubImage(imageraw->getData(), imageraw->getWidth(), imageraw->getHeight(), x_pos, y_pos, width, height, force_fast_update);
}
// Copy sub image from frame buffer
@@ -975,7 +985,6 @@ BOOL LLImageGL::createGLTexture(S32 discard_level, const U8* data_in, BOOL data_
LLImageGL::generateTextures(1, &mTexName);
stop_glerror();
{
-// LLFastTimer t1(LLFastTimer::FTM_TEMP6);
llverify(gGL.getTexUnit(0)->bind(this));
glTexParameteri(LLTexUnit::getInternalType(mBindTarget), GL_TEXTURE_BASE_LEVEL, 0);
glTexParameteri(LLTexUnit::getInternalType(mBindTarget), GL_TEXTURE_MAX_LEVEL, mMaxDiscardLevel-discard_level);
@@ -1020,7 +1029,6 @@ BOOL LLImageGL::createGLTexture(S32 discard_level, const U8* data_in, BOOL data_
mTextureMemory = getMipBytes(discard_level);
sGlobalTextureMemoryInBytes += mTextureMemory;
- setActive() ;
// mark this as bound at this point, so we don't throw it out immediately
mLastBindTime = sLastFrameTime;
@@ -1036,12 +1044,7 @@ BOOL LLImageGL::setDiscardLevel(S32 discard_level)
discard_level = llclamp(discard_level, 0, (S32)mMaxDiscardLevel);
- if (mDontDiscard)
- {
- // don't discard!
- return FALSE;
- }
- else if (discard_level == mCurrentDiscardLevel)
+ if (discard_level == mCurrentDiscardLevel)
{
// nothing to do
return FALSE;
@@ -1096,7 +1099,7 @@ BOOL LLImageGL::isValidForSculpt(S32 discard_level, S32 image_width, S32 image_h
return glwidth >= image_width && glheight >= image_height && (GL_RGB8 == glcomponents || GL_RGBA8 == glcomponents) ;
}
-BOOL LLImageGL::readBackRaw(S32 discard_level, LLImageRaw* imageraw, bool compressed_ok)
+BOOL LLImageGL::readBackRaw(S32 discard_level, LLImageRaw* imageraw, bool compressed_ok) const
{
llpushcallstacks ;
if (discard_level < 0)
@@ -1223,8 +1226,7 @@ void LLImageGL::destroyGLTexture()
sGlobalTextureMemoryInBytes -= mTextureMemory;
mTextureMemory = 0;
- LLImageGL::deleteTextures(1, &mTexName);
- mTextureState = DELETED ;
+ LLImageGL::deleteTextures(1, &mTexName);
mTexName = 0;
mCurrentDiscardLevel = -1 ; //invalidate mCurrentDiscardLevel.
mGLTextureCreated = FALSE ;
@@ -1351,6 +1353,11 @@ void LLImageGL::setTarget(const LLGLenum target, const LLTexUnit::eTextureType b
void LLImageGL::analyzeAlpha(const void* data_in, S32 w, S32 h)
{
+ if(!mNeedsAlphaAndPickMask)
+ {
+ return ;
+ }
+
if (mFormatType != GL_UNSIGNED_BYTE)
{
llwarns << "Cannot analyze alpha for image with format type " << std::hex << mFormatType << std::dec << llendl;
@@ -1377,7 +1384,6 @@ void LLImageGL::analyzeAlpha(const void* data_in, S32 w, S32 h)
stride = 4;
break;
default:
- llwarns << "Cannot analyze alpha of image with primary format " << std::hex << mFormatPrimary << std::dec << llendl;
return;
}
@@ -1409,60 +1415,14 @@ void LLImageGL::analyzeAlpha(const void* data_in, S32 w, S32 h)
}
}
-BOOL LLImageGL::isDeleted()
-{
- return mTextureState == DELETED ;
-}
-
-BOOL LLImageGL::isInactive()
-{
- return mTextureState == INACTIVE ;
-}
-
-BOOL LLImageGL::isDeletionCandidate()
-{
- return mTextureState == DELETION_CANDIDATE ;
-}
-
-void LLImageGL::setDeletionCandidate()
-{
- if(mTexName && (mTextureState == INACTIVE))
- {
- mTextureState = DELETION_CANDIDATE ;
- }
-}
-
-void LLImageGL::forceActive()
-{
- mTextureState = ACTIVE ;
-}
-
-void LLImageGL::setActive()
-{
- if(mTextureState != NO_DELETE)
- {
- mTextureState = ACTIVE ;
- }
-}
-
-//set the texture inactive
-void LLImageGL::setInactive()
+//----------------------------------------------------------------------------
+void LLImageGL::updatePickMask(S32 width, S32 height, const U8* data_in)
{
- if(mTexName && (mTextureState == ACTIVE) && !getBoundRecently())
+ if(!mNeedsAlphaAndPickMask)
{
- mTextureState = INACTIVE ;
+ return ;
}
-}
-
-//set the texture to stay in memory
-void LLImageGL::setNoDelete()
-{
- mTextureState = NO_DELETE ;
-}
-//----------------------------------------------------------------------------
-void LLImageGL::updatePickMask(S32 width, S32 height, const U8* data_in)
-{
if (mFormatType != GL_UNSIGNED_BYTE ||
mFormatPrimary != GL_RGBA)
{
diff --git a/indra/llrender/llimagegl.h b/indra/llrender/llimagegl.h
index 2f08a5a2cc..987a1dc538 100644
--- a/indra/llrender/llimagegl.h
+++ b/indra/llrender/llimagegl.h
@@ -37,7 +37,8 @@
#include "llimage.h"
#include "llgltypes.h"
-#include "llmemory.h"
+#include "llpointer.h"
+#include "llrefcount.h"
#include "v2math.h"
#include "llrender.h"
@@ -56,7 +57,8 @@ public:
static S32 dataFormatBytes(S32 dataformat, S32 width, S32 height);
static S32 dataFormatComponents(S32 dataformat);
- void updateBindStats(void) const;
+ BOOL updateBindStats(S32 tex_mem) const ;
+ F32 getTimePassedSinceLastBound();
// needs to be called every frame
static void updateStats(F32 current_time);
@@ -69,13 +71,14 @@ public:
static S32 updateBoundTexMem(const S32 delta);
static bool checkSize(S32 width, S32 height);
-
+
+ //for server side use only.
// Not currently necessary for LLImageGL, but required in some derived classes,
// so include for compatability
static BOOL create(LLPointer<LLImageGL>& dest, BOOL usemipmaps = TRUE);
static BOOL create(LLPointer<LLImageGL>& dest, U32 width, U32 height, U8 components, BOOL usemipmaps = TRUE);
static BOOL create(LLPointer<LLImageGL>& dest, const LLImageRaw* imageraw, BOOL usemipmaps = TRUE);
-
+
public:
LLImageGL(BOOL usemipmaps = TRUE);
LLImageGL(U32 width, U32 height, U8 components, BOOL usemipmaps = TRUE);
@@ -88,11 +91,9 @@ protected:
public:
virtual void dump(); // debugging info to llinfos
- virtual bool bindError(const S32 stage = 0) const;
- virtual bool bindDefaultImage(const S32 stage = 0) const;
- virtual void forceImmediateUpdate() ;
-
+
void setSize(S32 width, S32 height, S32 ncomponents);
+ void setComponents(S32 ncomponents) { mComponents = (S8)ncomponents ;}
// These 3 functions currently wrap glGenTextures(), glDeleteTextures(), and glTexImage2D()
// for tracking purposes and will be deprecated in the future
@@ -105,16 +106,15 @@ public:
BOOL createGLTexture(S32 discard_level, const U8* data, BOOL data_hasmips = FALSE, S32 usename = 0);
void setImage(const LLImageRaw* imageraw);
void setImage(const U8* data_in, BOOL data_hasmips = FALSE);
- BOOL setSubImage(const LLImageRaw* imageraw, S32 x_pos, S32 y_pos, S32 width, S32 height);
- BOOL setSubImage(const U8* datap, S32 data_width, S32 data_height, S32 x_pos, S32 y_pos, S32 width, S32 height);
+ BOOL setSubImage(const LLImageRaw* imageraw, S32 x_pos, S32 y_pos, S32 width, S32 height, BOOL force_fast_update = FALSE);
+ BOOL setSubImage(const U8* datap, S32 data_width, S32 data_height, S32 x_pos, S32 y_pos, S32 width, S32 height, BOOL force_fast_update = FALSE);
BOOL setSubImageFromFrameBuffer(S32 fb_x, S32 fb_y, S32 x_pos, S32 y_pos, S32 width, S32 height);
BOOL setDiscardLevel(S32 discard_level);
// Read back a raw image for this discard level, if it exists
- BOOL readBackRaw(S32 discard_level, LLImageRaw* imageraw, bool compressed_ok);
+ BOOL readBackRaw(S32 discard_level, LLImageRaw* imageraw, bool compressed_ok) const;
void destroyGLTexture();
void setExplicitFormat(LLGLint internal_format, LLGLenum primary_format, LLGLenum type_format = 0, BOOL swap_bytes = FALSE);
- void dontDiscard() { mDontDiscard = 1; mTextureState = NO_DELETE; }
S32 getDiscardLevel() const { return mCurrentDiscardLevel; }
S32 getMaxDiscardLevel() const { return mMaxDiscardLevel; }
@@ -143,9 +143,7 @@ public:
void setGLTextureCreated (bool initialized) { mGLTextureCreated = initialized; }
BOOL getUseMipMaps() const { return mUseMipMaps; }
- void setUseMipMaps(BOOL usemips) { mUseMipMaps = usemips; }
- BOOL getUseDiscard() const { return mUseMipMaps && !mDontDiscard; }
- BOOL getDontDiscard() const { return mDontDiscard; }
+ void setUseMipMaps(BOOL usemips) { mUseMipMaps = usemips; }
BOOL isValidForSculpt(S32 discard_level, S32 image_width, S32 image_height, S32 ncomponents) ;
@@ -166,19 +164,10 @@ public:
void setFilteringOption(LLTexUnit::eTextureFilterOptions option);
LLTexUnit::eTextureFilterOptions getFilteringOption(void) const { return mFilterOption; }
- BOOL isDeleted() ;
- BOOL isInactive() ;
- BOOL isDeletionCandidate();
- void setDeletionCandidate() ;
- void setInactive() ;
- void setActive() ;
- void forceActive() ;
- void setNoDelete() ;
-
-protected:
void init(BOOL usemipmaps);
virtual void cleanup(); // Clean up the LLImageGL so it can be reinitialized. Be careful when using this in derived class destructors
+ void setNeedsAlphaAndPickMask(BOOL need_mask) {mNeedsAlphaAndPickMask = need_mask;}
public:
// Various GL/Rendering options
S32 mTextureMemory;
@@ -192,6 +181,7 @@ private:
S8 mAutoGenMips;
BOOL mIsMask;
+ BOOL mNeedsAlphaAndPickMask;
bool mGLTextureCreated ;
LLGLuint mTexName;
@@ -208,28 +198,15 @@ protected:
S8 mComponents;
S8 mMaxDiscardLevel;
- S8 mDontDiscard; // Keep full res version of this image (for UI, etc)
-
+
bool mTexOptionsDirty;
LLTexUnit::eTextureAddressMode mAddressMode; // Defaults to TAM_WRAP
LLTexUnit::eTextureFilterOptions mFilterOption; // Defaults to TFO_TRILINEAR
-
LLGLint mFormatInternal; // = GL internalformat
LLGLenum mFormatPrimary; // = GL format (pixel data format)
LLGLenum mFormatType;
BOOL mFormatSwapBytes;// if true, use glPixelStorei(GL_UNPACK_SWAP_BYTES, 1)
-
-protected:
- typedef enum
- {
- DELETED = 0, //removed from memory
- DELETION_CANDIDATE, //ready to be removed from memory
- INACTIVE, //not be used for the last certain period (i.e., 30 seconds).
- ACTIVE, //just being used, can become inactive if not being used for a certain time (10 seconds).
- NO_DELETE = 99 //stay in memory, can not be removed.
- } LLGLTexureState;
- LLGLTexureState mTextureState ;
// STATICS
public:
@@ -247,6 +224,8 @@ public:
static U32 sBindCount; // Tracks number of texture binds for current frame
static U32 sUniqueCount; // Tracks number of unique texture binds for current frame
static BOOL sGlobalUseAnisotropic;
+ static LLImageGL* sDefaultGLTexture ;
+
#if DEBUG_MISS
BOOL mMissed; // Missed on last bind?
BOOL getMissed() const { return mMissed; };
diff --git a/indra/llrender/llrender.cpp b/indra/llrender/llrender.cpp
index 6bb217a9c2..d577daf3f4 100644
--- a/indra/llrender/llrender.cpp
+++ b/indra/llrender/llrender.cpp
@@ -38,6 +38,7 @@
#include "llcubemap.h"
#include "llimagegl.h"
#include "llrendertarget.h"
+#include "lltexture.h"
LLRender gGL;
@@ -177,20 +178,21 @@ void LLTexUnit::disable(void)
}
}
-bool LLTexUnit::bind(LLImageGL* texture, bool forceBind)
+bool LLTexUnit::bind(LLTexture* texture, bool forceBind)
{
stop_glerror();
if (mIndex < 0) return false;
gGL.flush();
- if (texture == NULL)
+ LLImageGL* gl_tex = NULL ;
+ if (texture == NULL || !(gl_tex = texture->getGLTexture()))
{
llwarns << "NULL LLTexUnit::bind texture" << llendl;
return false;
}
-
- if (!texture->getTexName()) //if texture does not exist
+
+ if (!gl_tex->getTexName()) //if texture does not exist
{
//if deleted, will re-generate it immediately
texture->forceImmediateUpdate() ;
@@ -198,14 +200,57 @@ bool LLTexUnit::bind(LLImageGL* texture, bool forceBind)
return texture->bindDefaultImage(mIndex);
}
+ if ((mCurrTexture != gl_tex->getTexName()) || forceBind)
+ {
+ activate();
+ enable(gl_tex->getTarget());
+ mCurrTexture = gl_tex->getTexName();
+ glBindTexture(sGLTextureType[gl_tex->getTarget()], mCurrTexture);
+ if(gl_tex->updateBindStats(gl_tex->mTextureMemory))
+ {
+ texture->setActive() ;
+ texture->updateBindStatsForTester() ;
+ }
+ mHasMipMaps = gl_tex->mHasMipMaps;
+ if (gl_tex->mTexOptionsDirty)
+ {
+ gl_tex->mTexOptionsDirty = false;
+ setTextureAddressMode(gl_tex->mAddressMode);
+ setTextureFilteringOption(gl_tex->mFilterOption);
+ }
+ }
+ return true;
+}
+
+bool LLTexUnit::bind(LLImageGL* texture, bool forceBind)
+{
+ stop_glerror();
+ if (mIndex < 0) return false;
+
+ if(!texture)
+ {
+ llwarns << "NULL LLTexUnit::bind texture" << llendl;
+ return false;
+ }
+
+ if(!texture->getTexName())
+ {
+ if(LLImageGL::sDefaultGLTexture && LLImageGL::sDefaultGLTexture->getTexName())
+ {
+ return bind(LLImageGL::sDefaultGLTexture) ;
+ }
+ return false ;
+ }
+
+ gGL.flush();
+
if ((mCurrTexture != texture->getTexName()) || forceBind)
{
activate();
enable(texture->getTarget());
mCurrTexture = texture->getTexName();
glBindTexture(sGLTextureType[texture->getTarget()], mCurrTexture);
- texture->updateBindStats();
- texture->setActive() ;
+ texture->updateBindStats(texture->mTextureMemory);
mHasMipMaps = texture->mHasMipMaps;
if (texture->mTexOptionsDirty)
{
@@ -238,7 +283,7 @@ bool LLTexUnit::bind(LLCubeMap* cubeMap)
mCurrTexture = cubeMap->mImages[0]->getTexName();
glBindTexture(GL_TEXTURE_CUBE_MAP_ARB, mCurrTexture);
mHasMipMaps = cubeMap->mImages[0]->mHasMipMaps;
- cubeMap->mImages[0]->updateBindStats();
+ cubeMap->mImages[0]->updateBindStats(cubeMap->mImages[0]->mTextureMemory);
if (cubeMap->mImages[0]->mTexOptionsDirty)
{
cubeMap->mImages[0]->mTexOptionsDirty = false;
@@ -279,15 +324,21 @@ bool LLTexUnit::bind(LLRenderTarget* renderTarget, bool bindDepth)
bool LLTexUnit::bindManual(eTextureType type, U32 texture, bool hasMips)
{
- if (mIndex < 0 || mCurrTexture == texture) return false;
+ if (mIndex < 0)
+ {
+ return false;
+ }
- gGL.flush();
-
- activate();
- enable(type);
- mCurrTexture = texture;
- glBindTexture(sGLTextureType[type], texture);
- mHasMipMaps = hasMips;
+ if(mCurrTexture != texture)
+ {
+ gGL.flush();
+
+ activate();
+ enable(type);
+ mCurrTexture = texture;
+ glBindTexture(sGLTextureType[type], texture);
+ mHasMipMaps = hasMips;
+ }
return true;
}
@@ -785,6 +836,9 @@ void LLRender::setSceneBlendType(eBlendType type)
case BT_MULT:
glBlendFunc(GL_DST_COLOR, GL_ZERO);
break;
+ case BT_MULT_ALPHA:
+ glBlendFunc(GL_DST_ALPHA, GL_ZERO);
+ break;
case BT_MULT_X2:
glBlendFunc(GL_DST_COLOR, GL_SRC_COLOR);
break;
diff --git a/indra/llrender/llrender.h b/indra/llrender/llrender.h
index 437c715c2f..74f87f6d40 100644
--- a/indra/llrender/llrender.h
+++ b/indra/llrender/llrender.h
@@ -44,13 +44,14 @@
#include "v3math.h"
#include "v4coloru.h"
#include "llstrider.h"
-#include "llmemory.h"
+#include "llpointer.h"
#include "llglheaders.h"
class LLVertexBuffer;
class LLCubeMap;
class LLImageGL;
class LLRenderTarget;
+class LLTexture ;
class LLTexUnit
{
@@ -149,6 +150,7 @@ public:
// Binds the LLImageGL to this texture unit
// (automatically enables the unit for the LLImageGL's texture type)
bool bind(LLImageGL* texture, bool forceBind = false);
+ bool bind(LLTexture* texture, bool forceBind = false);
// Binds a cubemap to this texture unit
// (automatically enables the texture unit for cubemaps)
@@ -252,6 +254,7 @@ public:
BT_ADD,
BT_ADD_WITH_ALPHA, // Additive blend modulated by the fragment's alpha.
BT_MULT,
+ BT_MULT_ALPHA,
BT_MULT_X2,
BT_REPLACE
} eBlendType;
diff --git a/indra/llrender/llrendertarget.cpp b/indra/llrender/llrendertarget.cpp
index b7f31779ca..dc052851ca 100644
--- a/indra/llrender/llrendertarget.cpp
+++ b/indra/llrender/llrendertarget.cpp
@@ -36,6 +36,9 @@
#include "llrender.h"
#include "llgl.h"
+LLRenderTarget* LLRenderTarget::sBoundTarget = NULL;
+
+
void check_framebuffer_status()
{
@@ -46,11 +49,9 @@ void check_framebuffer_status()
{
case GL_FRAMEBUFFER_COMPLETE_EXT:
break;
- case GL_FRAMEBUFFER_UNSUPPORTED_EXT:
- llerrs << "WTF?" << llendl;
- break;
default:
- llerrs << "WTF?" << llendl;
+ ll_fail("check_framebuffer_status failed");
+ break;
}
}
}
@@ -273,6 +274,7 @@ void LLRenderTarget::release()
}
mSampleBuffer = NULL;
+ sBoundTarget = NULL;
}
void LLRenderTarget::bindTarget()
@@ -311,6 +313,7 @@ void LLRenderTarget::bindTarget()
}
glViewport(0, 0, mResX, mResY);
+ sBoundTarget = this;
}
// static
@@ -320,6 +323,7 @@ void LLRenderTarget::unbindTarget()
{
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
}
+ sBoundTarget = NULL;
}
void LLRenderTarget::clear(U32 mask_in)
@@ -532,6 +536,7 @@ void LLMultisampleBuffer::bindTarget(LLRenderTarget* ref)
glViewport(0, 0, mResX, mResY);
+ sBoundTarget = this;
}
void LLMultisampleBuffer::allocate(U32 resx, U32 resy, U32 color_fmt, BOOL depth, BOOL stencil, LLTexUnit::eTextureType usage, BOOL use_fbo )
diff --git a/indra/llrender/llrendertarget.h b/indra/llrender/llrendertarget.h
index d5d809b791..98b608f834 100644
--- a/indra/llrender/llrendertarget.h
+++ b/indra/llrender/llrendertarget.h
@@ -140,6 +140,8 @@ public:
//one renderable attachment (i.e. color buffer, depth buffer).
BOOL isComplete() const;
+ static LLRenderTarget* getCurrentBoundTarget() { return sBoundTarget; }
+
protected:
friend class LLMultisampleBuffer;
U32 mResX;
@@ -153,6 +155,8 @@ protected:
LLTexUnit::eTextureType mUsage;
U32 mSamples;
LLMultisampleBuffer* mSampleBuffer;
+
+ static LLRenderTarget* sBoundTarget;
};
diff --git a/indra/llrender/lltexture.cpp b/indra/llrender/lltexture.cpp
new file mode 100644
index 0000000000..156ffb953c
--- /dev/null
+++ b/indra/llrender/lltexture.cpp
@@ -0,0 +1,37 @@
+/**
+ * @file lltexture.cpp
+ *
+ * $LicenseInfo:firstyear=2000&license=viewergpl$
+ *
+ * Copyright (c) 2000-2009, Linden Research, Inc.
+ *
+ * Second Life Viewer Source Code
+ * The source code in this file ("Source Code") is provided by Linden Lab
+ * to you under the terms of the GNU General Public License, version 2.0
+ * ("GPL"), unless you have obtained a separate licensing agreement
+ * ("Other License"), formally executed by you and Linden Lab. Terms of
+ * the GPL can be found in doc/GPL-license.txt in this distribution, or
+ * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
+ *
+ * There are special exceptions to the terms and conditions of the GPL as
+ * it is applied to this Source Code. View the full text of the exception
+ * in the file doc/FLOSS-exception.txt in this software distribution, or
+ * online at
+ * http://secondlifegrid.net/programs/open_source/licensing/flossexception
+ *
+ * By copying, modifying or distributing this software, you acknowledge
+ * that you have read and understood your obligations described above,
+ * and agree to abide by those obligations.
+ *
+ * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+ * COMPLETENESS OR PERFORMANCE.
+ * $/LicenseInfo$
+ */
+#include "linden_common.h"
+#include "lltexture.h"
+
+//virtual
+LLTexture::~LLTexture()
+{
+}
diff --git a/indra/llrender/lltexture.h b/indra/llrender/lltexture.h
new file mode 100644
index 0000000000..c18917b663
--- /dev/null
+++ b/indra/llrender/lltexture.h
@@ -0,0 +1,77 @@
+/**
+ * @file lltexture.h
+ * @brief LLTexture definition
+ *
+ * This class acts as a wrapper for OpenGL calls.
+ * The goal of this class is to minimize the number of api calls due to legacy rendering
+ * code, to define an interface for a multiple rendering API abstraction of the UI
+ * rendering, and to abstract out direct rendering calls in a way that is cleaner and easier to maintain.
+ *
+ * $LicenseInfo:firstyear=2001&license=viewergpl$
+ *
+ * Copyright (c) 2001-2009, Linden Research, Inc.
+ *
+ * Second Life Viewer Source Code
+ * The source code in this file ("Source Code") is provided by Linden Lab
+ * to you under the terms of the GNU General Public License, version 2.0
+ * ("GPL"), unless you have obtained a separate licensing agreement
+ * ("Other License"), formally executed by you and Linden Lab. Terms of
+ * the GPL can be found in doc/GPL-license.txt in this distribution, or
+ * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
+ *
+ * There are special exceptions to the terms and conditions of the GPL as
+ * it is applied to this Source Code. View the full text of the exception
+ * in the file doc/FLOSS-exception.txt in this software distribution, or
+ * online at
+ * http://secondlifegrid.net/programs/open_source/licensing/flossexception
+ *
+ * By copying, modifying or distributing this software, you acknowledge
+ * that you have read and understood your obligations described above,
+ * and agree to abide by those obligations.
+ *
+ * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+ * COMPLETENESS OR PERFORMANCE.
+ * $/LicenseInfo$
+ */
+
+#ifndef LL_TEXTURE_H
+#define LL_TEXTURE_H
+
+#include "llrefcount.h"
+class LLImageGL ;
+class LLTexUnit ;
+class LLFontGL ;
+
+//
+//this is an abstract class as the parent for the class LLViewerTexture
+//through the following virtual functions, the class LLViewerTexture can be reached from /llrender.
+//
+class LLTexture : public LLRefCount
+{
+ friend class LLTexUnit ;
+ friend class LLFontGL ;
+
+protected:
+ virtual ~LLTexture();
+
+public:
+ LLTexture(){}
+
+ //
+ //interfaces to access LLViewerTexture
+ //
+ virtual bool bindDefaultImage(const S32 stage = 0) const = 0 ;
+ virtual void forceImmediateUpdate() = 0 ;
+ virtual void setActive() = 0 ;
+ virtual S32 getWidth(S32 discard_level = -1) const = 0 ;
+ virtual S32 getHeight(S32 discard_level = -1) const = 0 ;
+
+private:
+ //note: do not make this function public.
+ virtual LLImageGL* getGLTexture() const = 0 ;
+
+ virtual void updateBindStatsForTester() = 0 ;
+};
+#endif
+
diff --git a/indra/llrender/llvertexbuffer.cpp b/indra/llrender/llvertexbuffer.cpp
index 5d88ea464d..db4189dfea 100644
--- a/indra/llrender/llvertexbuffer.cpp
+++ b/indra/llrender/llvertexbuffer.cpp
@@ -37,7 +37,6 @@
#include "llvertexbuffer.h"
// #include "llrender.h"
#include "llglheaders.h"
-#include "llmemory.h"
#include "llmemtype.h"
#include "llrender.h"
@@ -117,6 +116,7 @@ void LLVertexBuffer::setupClientArrays(U32 data_mask)
GL_COLOR_ARRAY,
};
+ BOOL error = FALSE;
for (U32 i = 0; i < 4; ++i)
{
if (sLastMask & mask[i])
@@ -129,7 +129,15 @@ void LLVertexBuffer::setupClientArrays(U32 data_mask)
{ //needs to be enabled, make sure it was (DEBUG TEMPORARY)
if (i > 0 && !glIsEnabled(array[i]))
{
- llerrs << "Bad client state! " << array[i] << " disabled." << llendl;
+ if (gDebugSession)
+ {
+ error = TRUE;
+ gFailLog << "Bad client state! " << array[i] << " disabled." << std::endl;
+ }
+ else
+ {
+ llerrs << "Bad client state! " << array[i] << " disabled." << llendl;
+ }
}
}
}
@@ -141,11 +149,24 @@ void LLVertexBuffer::setupClientArrays(U32 data_mask)
}
else if (gDebugGL && glIsEnabled(array[i]))
{ //needs to be disabled, make sure it was (DEBUG TEMPORARY)
- llerrs << "Bad client state! " << array[i] << " enabled." << llendl;
+ if (gDebugSession)
+ {
+ error = TRUE;
+ gFailLog << "Bad client state! " << array[i] << " enabled." << std::endl;
+ }
+ else
+ {
+ llerrs << "Bad client state! " << array[i] << " enabled." << llendl;
+ }
}
}
}
+ if (error)
+ {
+ ll_fail("LLVertexBuffer::setupClientArrays failed");
+ }
+
U32 map_tc[] =
{
MAP_TEXCOORD1,
@@ -315,7 +336,7 @@ void LLVertexBuffer::unbind()
//static
void LLVertexBuffer::cleanupClass()
{
- LLMemType mt(LLMemType::MTYPE_VERTEX_DATA);
+ LLMemType mt2(LLMemType::MTYPE_VERTEX_CLEANUP_CLASS);
unbind();
clientCopy(); // deletes GL buffers
}
@@ -342,7 +363,7 @@ LLVertexBuffer::LLVertexBuffer(U32 typemask, S32 usage) :
mResized(FALSE),
mDynamicSize(FALSE)
{
- LLMemType mt(LLMemType::MTYPE_VERTEX_DATA);
+ LLMemType mt2(LLMemType::MTYPE_VERTEX_CONSTRUCTOR);
if (!sEnableVBOs)
{
mUsage = 0 ;
@@ -379,7 +400,7 @@ S32 LLVertexBuffer::calcStride(const U32& typemask, S32* offsets)
//virtual
LLVertexBuffer::~LLVertexBuffer()
{
- LLMemType mt(LLMemType::MTYPE_VERTEX_DATA);
+ LLMemType mt2(LLMemType::MTYPE_VERTEX_DESTRUCTOR);
destroyGLBuffer();
destroyGLIndices();
sCount--;
@@ -459,8 +480,8 @@ void LLVertexBuffer::releaseIndices()
void LLVertexBuffer::createGLBuffer()
{
- LLMemType mt(LLMemType::MTYPE_VERTEX_DATA);
-
+ LLMemType mt2(LLMemType::MTYPE_VERTEX_CREATE_VERTICES);
+
U32 size = getSize();
if (mGLBuffer)
{
@@ -491,7 +512,7 @@ void LLVertexBuffer::createGLBuffer()
void LLVertexBuffer::createGLIndices()
{
- LLMemType mt(LLMemType::MTYPE_VERTEX_DATA);
+ LLMemType mt2(LLMemType::MTYPE_VERTEX_CREATE_INDICES);
U32 size = getIndicesSize();
if (mGLIndices)
@@ -523,7 +544,7 @@ void LLVertexBuffer::createGLIndices()
void LLVertexBuffer::destroyGLBuffer()
{
- LLMemType mt(LLMemType::MTYPE_VERTEX_DATA);
+ LLMemType mt2(LLMemType::MTYPE_VERTEX_DESTROY_BUFFER);
if (mGLBuffer)
{
if (useVBOs())
@@ -550,7 +571,7 @@ void LLVertexBuffer::destroyGLBuffer()
void LLVertexBuffer::destroyGLIndices()
{
- LLMemType mt(LLMemType::MTYPE_VERTEX_DATA);
+ LLMemType mt2(LLMemType::MTYPE_VERTEX_DESTROY_INDICES);
if (mGLIndices)
{
if (useVBOs())
@@ -577,7 +598,7 @@ void LLVertexBuffer::destroyGLIndices()
void LLVertexBuffer::updateNumVerts(S32 nverts)
{
- LLMemType mt(LLMemType::MTYPE_VERTEX_DATA);
+ LLMemType mt2(LLMemType::MTYPE_VERTEX_UPDATE_VERTS);
if (nverts >= 65535)
{
@@ -606,7 +627,7 @@ void LLVertexBuffer::updateNumVerts(S32 nverts)
void LLVertexBuffer::updateNumIndices(S32 nindices)
{
- LLMemType mt(LLMemType::MTYPE_VERTEX_DATA);
+ LLMemType mt2(LLMemType::MTYPE_VERTEX_UPDATE_INDICES);
mRequestedNumIndices = nindices;
if (!mDynamicSize)
{
@@ -627,7 +648,7 @@ void LLVertexBuffer::updateNumIndices(S32 nindices)
void LLVertexBuffer::allocateBuffer(S32 nverts, S32 nindices, bool create)
{
- LLMemType mt(LLMemType::MTYPE_VERTEX_DATA);
+ LLMemType mt2(LLMemType::MTYPE_VERTEX_ALLOCATE_BUFFER);
updateNumVerts(nverts);
updateNumIndices(nindices);
@@ -650,7 +671,7 @@ void LLVertexBuffer::resizeBuffer(S32 newnverts, S32 newnindices)
mRequestedNumVerts = newnverts;
mRequestedNumIndices = newnindices;
- LLMemType mt(LLMemType::MTYPE_VERTEX_DATA);
+ LLMemType mt2(LLMemType::MTYPE_VERTEX_RESIZE_BUFFER);
mDynamicSize = TRUE;
if (mUsage == GL_STATIC_DRAW_ARB)
{ //always delete/allocate static buffers on resize
@@ -779,7 +800,7 @@ BOOL LLVertexBuffer::useVBOs() const
// Map for data access
U8* LLVertexBuffer::mapBuffer(S32 access)
{
- LLMemType mt(LLMemType::MTYPE_VERTEX_DATA);
+ LLMemType mt2(LLMemType::MTYPE_VERTEX_MAP_BUFFER);
if (mFinal)
{
llerrs << "LLVertexBuffer::mapBuffer() called on a finalized buffer." << llendl;
@@ -791,13 +812,19 @@ U8* LLVertexBuffer::mapBuffer(S32 access)
if (!mLocked && useVBOs())
{
- setBuffer(0);
- mLocked = TRUE;
- stop_glerror();
- mMappedData = (U8*) glMapBufferARB(GL_ARRAY_BUFFER_ARB, GL_WRITE_ONLY_ARB);
- stop_glerror();
- mMappedIndexData = (U8*) glMapBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, GL_WRITE_ONLY_ARB);
- stop_glerror();
+ {
+ LLMemType mt_v(LLMemType::MTYPE_VERTEX_MAP_BUFFER_VERTICES);
+ setBuffer(0);
+ mLocked = TRUE;
+ stop_glerror();
+ mMappedData = (U8*) glMapBufferARB(GL_ARRAY_BUFFER_ARB, GL_WRITE_ONLY_ARB);
+ stop_glerror();
+ }
+ {
+ LLMemType mt_v(LLMemType::MTYPE_VERTEX_MAP_BUFFER_INDICES);
+ mMappedIndexData = (U8*) glMapBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, GL_WRITE_ONLY_ARB);
+ stop_glerror();
+ }
if (!mMappedData)
{
@@ -840,7 +867,7 @@ U8* LLVertexBuffer::mapBuffer(S32 access)
void LLVertexBuffer::unmapBuffer()
{
- LLMemType mt(LLMemType::MTYPE_VERTEX_DATA);
+ LLMemType mt2(LLMemType::MTYPE_VERTEX_UNMAP_BUFFER);
if (mMappedData || mMappedIndexData)
{
if (useVBOs() && mLocked)
@@ -962,7 +989,7 @@ bool LLVertexBuffer::getClothWeightStrider(LLStrider<LLVector4>& strider, S32 in
void LLVertexBuffer::setStride(S32 type, S32 new_stride)
{
- LLMemType mt(LLMemType::MTYPE_VERTEX_DATA);
+ LLMemType mt2(LLMemType::MTYPE_VERTEX_SET_STRIDE);
if (mNumVerts)
{
llerrs << "LLVertexBuffer::setOffset called with mNumVerts = " << mNumVerts << llendl;
@@ -984,7 +1011,7 @@ void LLVertexBuffer::setStride(S32 type, S32 new_stride)
// Set for rendering
void LLVertexBuffer::setBuffer(U32 data_mask)
{
- LLMemType mt(LLMemType::MTYPE_VERTEX_DATA);
+ LLMemType mt2(LLMemType::MTYPE_VERTEX_SET_BUFFER);
//set up pointers if the data mask is different ...
BOOL setup = (sLastMask != data_mask);
@@ -1016,19 +1043,36 @@ void LLVertexBuffer::setBuffer(U32 data_mask)
sIBOActive = TRUE;
}
+ BOOL error = FALSE;
if (gDebugGL)
{
GLint buff;
glGetIntegerv(GL_ARRAY_BUFFER_BINDING_ARB, &buff);
if ((GLuint)buff != mGLBuffer)
{
- llerrs << "Invalid GL vertex buffer bound: " << buff << llendl;
+ if (gDebugSession)
+ {
+ error = TRUE;
+ gFailLog << "Invalid GL vertex buffer bound: " << buff << std::endl;
+ }
+ else
+ {
+ llerrs << "Invalid GL vertex buffer bound: " << buff << llendl;
+ }
}
glGetIntegerv(GL_ELEMENT_ARRAY_BUFFER_BINDING_ARB, &buff);
if ((GLuint)buff != mGLIndices)
{
- llerrs << "Invalid GL index buffer bound: " << buff << llendl;
+ if (gDebugSession)
+ {
+ error = TRUE;
+ gFailLog << "Invalid GL index buffer bound: " << buff << std::endl;
+ }
+ else
+ {
+ llerrs << "Invalid GL index buffer bound: " << buff << llendl;
+ }
}
}
@@ -1040,13 +1084,29 @@ void LLVertexBuffer::setBuffer(U32 data_mask)
glGetIntegerv(GL_ARRAY_BUFFER_BINDING_ARB, &buff);
if ((GLuint)buff != mGLBuffer)
{
- llerrs << "Invalid GL vertex buffer bound: " << buff << llendl;
+ if (gDebugSession)
+ {
+ error = TRUE;
+ gFailLog << "Invalid GL vertex buffer bound: " << std::endl;
+ }
+ else
+ {
+ llerrs << "Invalid GL vertex buffer bound: " << buff << llendl;
+ }
}
glGetIntegerv(GL_ELEMENT_ARRAY_BUFFER_BINDING_ARB, &buff);
if ((GLuint)buff != mGLIndices)
{
- llerrs << "Invalid GL index buffer bound: " << buff << llendl;
+ if (gDebugSession)
+ {
+ error = TRUE;
+ gFailLog << "Invalid GL index buffer bound: "<< std::endl;
+ }
+ else
+ {
+ llerrs << "Invalid GL index buffer bound: " << buff << llendl;
+ }
}
}
@@ -1068,10 +1128,22 @@ void LLVertexBuffer::setBuffer(U32 data_mask)
if (data_mask != 0)
{
- llerrs << "Buffer set for rendering before being filled after resize." << llendl;
+ if (gDebugSession)
+ {
+ error = TRUE;
+ gFailLog << "Buffer set for rendering before being filled after resize." << std::endl;
+ }
+ else
+ {
+ llerrs << "Buffer set for rendering before being filled after resize." << llendl;
+ }
}
}
+ if (error)
+ {
+ ll_fail("LLVertexBuffer::mapBuffer failed");
+ }
unmapBuffer();
}
else
@@ -1122,7 +1194,7 @@ void LLVertexBuffer::setBuffer(U32 data_mask)
// virtual (default)
void LLVertexBuffer::setupVertexBuffer(U32 data_mask) const
{
- LLMemType mt(LLMemType::MTYPE_VERTEX_DATA);
+ LLMemType mt2(LLMemType::MTYPE_VERTEX_SETUP_VERTEX_BUFFER);
stop_glerror();
U8* base = useVBOs() ? NULL : mMappedData;
S32 stride = mStride;
diff --git a/indra/llrender/llvertexbuffer.h b/indra/llrender/llvertexbuffer.h
index aad948e17f..b785a22976 100644
--- a/indra/llrender/llvertexbuffer.h
+++ b/indra/llrender/llvertexbuffer.h
@@ -39,7 +39,6 @@
#include "v4math.h"
#include "v4coloru.h"
#include "llstrider.h"
-#include "llmemory.h"
#include "llrender.h"
#include <set>
#include <vector>
diff --git a/indra/llui/CMakeLists.txt b/indra/llui/CMakeLists.txt
index 5de8dc76af..8b0fcc68c4 100644
--- a/indra/llui/CMakeLists.txt
+++ b/indra/llui/CMakeLists.txt
@@ -3,7 +3,6 @@
project(llui)
include(00-Common)
-include(LLAudio)
include(LLCommon)
include(LLImage)
include(LLMath)
@@ -12,9 +11,9 @@ include(LLRender)
include(LLWindow)
include(LLVFS)
include(LLXML)
+include(LLXUIXML)
include_directories(
- ${LLAUDIO_INCLUDE_DIRS}
${LLCOMMON_INCLUDE_DIRS}
${LLIMAGE_INCLUDE_DIRS}
${LLMATH_INCLUDE_DIRS}
@@ -23,6 +22,7 @@ include_directories(
${LLWINDOW_INCLUDE_DIRS}
${LLVFS_INCLUDE_DIRS}
${LLXML_INCLUDE_DIRS}
+ ${LLXUIXML_INCLUDE_DIRS}
)
set(llui_SOURCE_FILES
@@ -31,17 +31,26 @@ set(llui_SOURCE_FILES
llcheckboxctrl.cpp
llclipboard.cpp
llcombobox.cpp
+ llconsole.cpp
+ llcontainerview.cpp
llctrlselectioninterface.cpp
lldraghandle.cpp
lleditmenuhandler.cpp
+ llf32uictrl.cpp
+ llfiltereditor.cpp
llfloater.cpp
+ llfloaterreg.cpp
+ llflyoutbutton.cpp
llfocusmgr.cpp
llfunctorregistry.cpp
lliconctrl.cpp
llkeywords.cpp
+ lllayoutstack.cpp
lllineeditor.cpp
+ lllink.cpp
llmenugl.cpp
llmodaldialog.cpp
+ llmultifloater.cpp
llmultislider.cpp
llmultisliderctrl.cpp
llnotifications.cpp
@@ -51,27 +60,37 @@ set(llui_SOURCE_FILES
llresizebar.cpp
llresizehandle.cpp
llresmgr.cpp
- llrootview.cpp
+ llrngwriter.cpp
llscrollbar.cpp
llscrollcontainer.cpp
llscrollingpanellist.cpp
+ llscrolllistcell.cpp
+ llscrolllistcolumn.cpp
llscrolllistctrl.cpp
+ llscrolllistitem.cpp
+ llsdparam.cpp
+ llsearcheditor.cpp
llslider.cpp
llsliderctrl.cpp
llspinctrl.cpp
+ llstatbar.cpp
+ llstatgraph.cpp
+ llstatview.cpp
llstyle.cpp
lltabcontainer.cpp
- lltabcontainervertical.cpp
lltextbox.cpp
lltexteditor.cpp
lltextparser.cpp
+ lltransutil.cpp
llui.cpp
+ lluicolortable.cpp
lluictrl.cpp
lluictrlfactory.cpp
+ lluiimage.cpp
lluistring.cpp
- lluitrans.cpp
llundo.cpp
llviewborder.cpp
+ llviewmodel.cpp
llview.cpp
llviewquery.cpp
)
@@ -85,19 +104,29 @@ set(llui_HEADER_FILES
llcheckboxctrl.h
llclipboard.h
llcombobox.h
+ llconsole.h
+ llcontainerview.h
llctrlselectioninterface.h
lldraghandle.h
lleditmenuhandler.h
+ llf32uictrl.h
+ llfiltereditor.h
llfloater.h
+ llfloaterreg.h
+ llflyoutbutton.h
llfocusmgr.h
llfunctorregistry.h
+ llhandle.h
llhtmlhelp.h
lliconctrl.h
llkeywords.h
+ lllayoutstack.h
+ lllazyvalue.h
lllineeditor.h
- llmemberlistener.h
+ lllink.h
llmenugl.h
llmodaldialog.h
+ llmultifloater.h
llmultisliderctrl.h
llmultislider.h
llnotifications.h
@@ -107,30 +136,39 @@ set(llui_HEADER_FILES
llresizebar.h
llresizehandle.h
llresmgr.h
- llrootview.h
+ llrngwriter.h
+ llsearcheditor.h
llscrollbar.h
llscrollcontainer.h
llscrollingpanellist.h
+ llscrolllistcell.h
+ llscrolllistcolumn.h
llscrolllistctrl.h
+ llscrolllistitem.h
+ llsdparam.h
llsliderctrl.h
llslider.h
llspinctrl.h
+ llstatbar.h
+ llstatgraph.h
+ llstatview.h
llstyle.h
lltabcontainer.h
- lltabcontainervertical.h
lltextbox.h
lltexteditor.h
lltextparser.h
+ lltransutil.h
+ lluicolortable.h
lluiconstants.h
lluictrlfactory.h
lluictrl.h
lluifwd.h
llui.h
+ lluiimage.h
lluistring.h
- lluitrans.h
- lluixmltags.h
llundo.h
llviewborder.h
+ llviewmodel.h
llview.h
llviewquery.h
)
@@ -148,6 +186,7 @@ target_link_libraries(llui
llwindow
llimage
llvfs # ugh, just for LLDir
+ llxuixml
llxml
llcommon # must be after llimage, llwindow, llrender
llmath
diff --git a/indra/llui/llbutton.cpp b/indra/llui/llbutton.cpp
index 2c2c1c25d8..98e8c9a988 100644
--- a/indra/llui/llbutton.cpp
+++ b/indra/llui/llbutton.cpp
@@ -45,183 +45,194 @@
#include "lluiconstants.h"
#include "llresmgr.h"
#include "llcriticaldamp.h"
+#include "llfloater.h"
+#include "llfloaterreg.h"
#include "llfocusmgr.h"
#include "llwindow.h"
#include "llrender.h"
+#include "lluictrlfactory.h"
-static LLRegisterWidget<LLButton> r("button");
+static LLDefaultChildRegistry::Register<LLButton> r("button");
// globals loaded from settings.xml
-S32 LLBUTTON_ORIG_H_PAD = 6; // Pre-zoomable UI
S32 LLBUTTON_H_PAD = 0;
S32 LLBUTTON_V_PAD = 0;
S32 BTN_HEIGHT_SMALL= 0;
S32 BTN_HEIGHT = 0;
-S32 BTN_GRID = 12;
-S32 BORDER_SIZE = 1;
-
-LLButton::LLButton( const std::string& name, const LLRect& rect, const std::string& control_name, void (*click_callback)(void*), void *callback_data)
-: LLUICtrl(name, rect, TRUE, NULL, NULL),
- mClickedCallback( click_callback ),
- mMouseDownCallback( NULL ),
- mMouseUpCallback( NULL ),
- mHeldDownCallback( NULL ),
- mGLFont( NULL ),
- mMouseDownFrame( 0 ),
- mHeldDownDelay( 0.5f ), // seconds until held-down callback is called
- mHeldDownFrameDelay( 0 ),
- mImageUnselected( NULL ),
- mImageSelected( NULL ),
- mImageHoverSelected( NULL ),
- mImageHoverUnselected( NULL ),
- mImageDisabled( NULL ),
- mImageDisabledSelected( NULL ),
- mToggleState( FALSE ),
- mIsToggle( FALSE ),
- mScaleImage( TRUE ),
- mDropShadowedText( TRUE ),
- mBorderEnabled( FALSE ),
- mFlashing( FALSE ),
- mHAlign( LLFontGL::HCENTER ),
- mLeftHPad( LLBUTTON_H_PAD ),
- mRightHPad( LLBUTTON_H_PAD ),
- mHoverGlowStrength(0.15f),
- mCurGlowStrength(0.f),
- mNeedsHighlight(FALSE),
- mCommitOnReturn(TRUE),
- mImagep( NULL )
+LLButton::Params::Params()
+: label_selected("label_selected"), // requires is_toggle true
+ label_shadow("label_shadow", true),
+ auto_resize("auto_resize", false),
+ use_ellipses("use_ellipses", false),
+ image_unselected("image_unselected"),
+ image_selected("image_selected"),
+ image_hover_selected("image_hover_selected"),
+ image_hover_unselected("image_hover_unselected"),
+ image_disabled_selected("image_disabled_selected"),
+ image_disabled("image_disabled"),
+ image_pressed("image_pressed"),
+ image_pressed_selected("image_pressed_selected"),
+ image_overlay("image_overlay"),
+ image_overlay_alignment("image_overlay_alignment", std::string("center")),
+ label_color("label_color"),
+ label_color_selected("label_color_selected"), // requires is_toggle true
+ label_color_disabled("label_color_disabled"),
+ label_color_disabled_selected("label_color_disabled_selected"),
+ highlight_color("highlight_color"),
+ image_color("image_color"),
+ image_color_disabled("image_color_disabled"),
+ image_overlay_color("image_overlay_color", LLColor4::white),
+ flash_color("flash_color"),
+ pad_right("pad_right", LLUI::sSettingGroups["config"]->getS32("ButtonHPad")),
+ pad_left("pad_left", LLUI::sSettingGroups["config"]->getS32("ButtonHPad")),
+ click_callback("click_callback"),
+ mouse_down_callback("mouse_down_callback"),
+ mouse_up_callback("mouse_up_callback"),
+ mouse_held_callback("mouse_held_callback"),
+ is_toggle("is_toggle", false),
+ scale_image("scale_image", true),
+ help_url("help_url"),
+ hover_glow_amount("hover_glow_amount"),
+ commit_on_return("commit_on_return", true),
+ picture_style("picture_style", false)
{
- mUnselectedLabel = name;
- mSelectedLabel = name;
-
- setImageUnselected(std::string("button_enabled_32x128.tga"));
- setImageSelected(std::string("button_enabled_selected_32x128.tga"));
- setImageDisabled(std::string("button_disabled_32x128.tga"));
- setImageDisabledSelected(std::string("button_disabled_32x128.tga"));
-
- mImageColor = LLUI::sColorsGroup->getColor( "ButtonImageColor" );
- mDisabledImageColor = LLUI::sColorsGroup->getColor( "ButtonImageColor" );
-
- init(click_callback, callback_data, NULL, control_name);
+ addSynonym(is_toggle, "toggle");
+ held_down_delay.seconds = 0.5f;
+ initial_value.set(LLSD(false), false);
}
-LLButton::LLButton(const std::string& name, const LLRect& rect,
- const std::string &unselected_image_name,
- const std::string &selected_image_name,
- const std::string& control_name,
- void (*click_callback)(void*),
- void *callback_data,
- const LLFontGL *font,
- const std::string& unselected_label,
- const std::string& selected_label )
-: LLUICtrl(name, rect, TRUE, NULL, NULL),
- mClickedCallback( click_callback ),
- mMouseDownCallback( NULL ),
- mMouseUpCallback( NULL ),
- mHeldDownCallback( NULL ),
- mGLFont( NULL ),
- mMouseDownFrame( 0 ),
- mHeldDownDelay( 0.5f ), // seconds until held-down callback is called
- mHeldDownFrameDelay( 0 ),
- mImageUnselected( NULL ),
- mImageSelected( NULL ),
- mImageHoverSelected( NULL ),
- mImageHoverUnselected( NULL ),
- mImageDisabled( NULL ),
- mImageDisabledSelected( NULL ),
- mToggleState( FALSE ),
- mIsToggle( FALSE ),
- mScaleImage( TRUE ),
- mDropShadowedText( TRUE ),
+LLButton::LLButton(const LLButton::Params& p)
+: LLUICtrl(p),
+ mMouseDownFrame(0),
+ mMouseHeldDownCount(0),
mBorderEnabled( FALSE ),
mFlashing( FALSE ),
- mHAlign( LLFontGL::HCENTER ),
- mLeftHPad( LLBUTTON_H_PAD ),
- mRightHPad( LLBUTTON_H_PAD ),
- mHoverGlowStrength(0.25f),
mCurGlowStrength(0.f),
mNeedsHighlight(FALSE),
- mCommitOnReturn(TRUE),
- mImagep( NULL )
+ mUnselectedLabel(p.label()),
+ mSelectedLabel(p.label_selected()),
+ mGLFont(p.font),
+ mHeldDownDelay(p.held_down_delay.seconds), // seconds until held-down callback is called
+ mHeldDownFrameDelay(p.held_down_delay.frames),
+ mImageUnselected(p.image_unselected),
+ mImageSelected(p.image_selected),
+ mImageDisabled(p.image_disabled),
+ mImageDisabledSelected(p.image_disabled_selected),
+ mImagePressed(p.image_pressed),
+ mImagePressedSelected(p.image_pressed_selected),
+ mImageHoverSelected(p.image_hover_selected),
+ mImageHoverUnselected(p.image_hover_unselected),
+ mUnselectedLabelColor(p.label_color()),
+ mSelectedLabelColor(p.label_color_selected()),
+ mDisabledLabelColor(p.label_color_disabled()),
+ mDisabledSelectedLabelColor(p.label_color_disabled_selected()),
+ mHighlightColor(p.highlight_color()),
+ mImageColor(p.image_color()),
+ mFlashBgColor(p.flash_color()),
+ mDisabledImageColor(p.image_color_disabled()),
+ mImageOverlay(p.image_overlay()),
+ mImageOverlayColor(p.image_overlay_color()),
+ mImageOverlayAlignment(LLFontGL::hAlignFromName(p.image_overlay_alignment)),
+ mIsToggle(p.is_toggle),
+ mScaleImage(p.scale_image),
+ mDropShadowedText(p.label_shadow),
+ mAutoResize(p.auto_resize),
+ mUseEllipses( p.use_ellipses ),
+ mHAlign(p.font_halign),
+ mLeftHPad(p.pad_left),
+ mRightHPad(p.pad_right),
+ mHoverGlowStrength(p.hover_glow_amount),
+ mCommitOnReturn(p.commit_on_return),
+ mFadeWhenDisabled(FALSE)
{
- mUnselectedLabel = unselected_label;
- mSelectedLabel = selected_label;
+ static LLUICachedControl<S32> llbutton_orig_h_pad ("UIButtonOrigHPad", 0);
+ static Params default_params(LLUICtrlFactory::getDefaultParams<LLButton>());
- // by default, disabled color is same as enabled
- mImageColor = LLUI::sColorsGroup->getColor( "ButtonImageColor" );
- mDisabledImageColor = LLUI::sColorsGroup->getColor( "ButtonImageColor" );
+ //if we aren't a picture_style button set label as name if not provided
+ if (!p.picture_style.isProvided() || !p.picture_style)
+ {
+ if (!p.label.isProvided())
+ {
+ mUnselectedLabel = p.name();
+ }
+ if (!p.label_selected.isProvided())
+ {
+ mSelectedLabel = mUnselectedLabel.getString();
+ }
+ }
- if( unselected_image_name != "" )
+ // Hack to make sure there is space for at least one character
+ if (getRect().getWidth() - (mRightHPad + mLeftHPad) < mGLFont->getWidth(std::string(" ")))
{
- // user-specified image - don't use fixed borders unless requested
- setImageUnselected(unselected_image_name);
- setImageDisabled(unselected_image_name);
-
- mDisabledImageColor.mV[VALPHA] = 0.5f;
- mScaleImage = FALSE;
+ // Use old defaults
+ mLeftHPad = llbutton_orig_h_pad;
+ mRightHPad = llbutton_orig_h_pad;
}
- else
+
+ mMouseDownTimer.stop();
+
+ if (p.help_url.isProvided())
{
- setImageUnselected(std::string("button_enabled_32x128.tga"));
- setImageDisabled(std::string("button_disabled_32x128.tga"));
+ setHelpURLCallback(p.help_url);
}
- if( selected_image_name != "" )
+ // if custom unselected button image provided...
+ if (p.image_unselected != default_params.image_unselected)
{
- // user-specified image - don't use fixed borders unless requested
- setImageSelected(selected_image_name);
- setImageDisabledSelected(selected_image_name);
+ //...fade it out for disabled image by default...
+ if (p.image_disabled() == default_params.image_disabled() )
+ {
+ mImageDisabled = p.image_unselected;
+ mFadeWhenDisabled = TRUE;
+ }
- mDisabledImageColor.mV[VALPHA] = 0.5f;
- mScaleImage = FALSE;
+ if (p.image_pressed_selected == default_params.image_pressed_selected)
+ {
+ mImagePressedSelected = mImageUnselected;
+ }
}
- else
+
+ // if custom selected button image provided...
+ if (p.image_selected != default_params.image_selected)
{
- setImageSelected(std::string("button_enabled_selected_32x128.tga"));
- setImageDisabledSelected(std::string("button_disabled_32x128.tga"));
- }
+ //...fade it out for disabled image by default...
+ if (p.image_disabled_selected() == default_params.image_disabled_selected())
+ {
+ mImageDisabledSelected = p.image_selected;
+ mFadeWhenDisabled = TRUE;
+ }
- init(click_callback, callback_data, font, control_name);
-}
+ if (p.image_pressed == default_params.image_pressed)
+ {
+ mImagePressed = mImageSelected;
+ }
+ }
-void LLButton::init(void (*click_callback)(void*), void *callback_data, const LLFontGL* font, const std::string& control_name)
-{
- mGLFont = ( font ? font : LLFontGL::getFontSansSerif());
+ if (!p.image_pressed.isProvided())
+ {
+ mImagePressed = mImageSelected;
+ }
- // Hack to make sure there is space for at least one character
- if (getRect().getWidth() - (mRightHPad + mLeftHPad) < mGLFont->getWidth(std::string(" ")))
+ if (!p.image_pressed_selected.isProvided())
{
- // Use old defaults
- mLeftHPad = LLBUTTON_ORIG_H_PAD;
- mRightHPad = LLBUTTON_ORIG_H_PAD;
+ mImagePressedSelected = mImageUnselected;
}
- mCallbackUserData = callback_data;
- mMouseDownTimer.stop();
-
- setControlName(control_name, NULL);
-
- mUnselectedLabelColor = ( LLUI::sColorsGroup->getColor( "ButtonLabelColor" ) );
- mSelectedLabelColor = ( LLUI::sColorsGroup->getColor( "ButtonLabelSelectedColor" ) );
- mDisabledLabelColor = ( LLUI::sColorsGroup->getColor( "ButtonLabelDisabledColor" ) );
- mDisabledSelectedLabelColor = ( LLUI::sColorsGroup->getColor( "ButtonLabelSelectedDisabledColor" ) );
- mHighlightColor = ( LLUI::sColorsGroup->getColor( "ButtonUnselectedFgColor" ) );
- mUnselectedBgColor = ( LLUI::sColorsGroup->getColor( "ButtonUnselectedBgColor" ) );
- mSelectedBgColor = ( LLUI::sColorsGroup->getColor( "ButtonSelectedBgColor" ) );
- mFlashBgColor = ( LLUI::sColorsGroup->getColor( "ButtonFlashBgColor" ) );
-
- mImageOverlayAlignment = LLFontGL::HCENTER;
- mImageOverlayColor = LLColor4::white;
-}
-
-LLButton::~LLButton()
-{
- if( hasMouseCapture() )
+ if (mImageUnselected.isNull())
{
- gFocusMgr.setMouseCapture( NULL );
+ llwarns << "Button: " << getName() << " with no image!" << llendl;
}
+
+ if (p.click_callback.isProvided())
+ initCommitCallback(p.click_callback, mCommitSignal); // alias -> commit_callback
+ if (p.mouse_down_callback.isProvided())
+ initCommitCallback(p.mouse_down_callback, mMouseDownSignal);
+ if (p.mouse_up_callback.isProvided())
+ initCommitCallback(p.mouse_up_callback, mMouseUpSignal);
+ if (p.mouse_held_callback.isProvided())
+ initCommitCallback(p.mouse_held_callback, mHeldDownSignal);
}
// HACK: Committing a button is the same as instantly clicking it.
@@ -229,19 +240,12 @@ LLButton::~LLButton()
void LLButton::onCommit()
{
// WARNING: Sometimes clicking a button destroys the floater or
- // panel containing it. Therefore we need to call mClickedCallback
+ // panel containing it. Therefore we need to call LLUICtrl::onCommit()
// LAST, otherwise this becomes deleted memory.
- LLUICtrl::onCommit();
- if (mMouseDownCallback)
- {
- (*mMouseDownCallback)(mCallbackUserData);
- }
+ mMouseDownSignal(this, LLSD());
- if (mMouseUpCallback)
- {
- (*mMouseUpCallback)(mCallbackUserData);
- }
+ mMouseUpSignal(this, LLSD());
if (getSoundFlags() & MOUSE_DOWN)
{
@@ -259,14 +263,50 @@ void LLButton::onCommit()
}
// do this last, as it can result in destroying this button
- if (mClickedCallback)
- {
- (*mClickedCallback)( mCallbackUserData );
- }
+ LLUICtrl::onCommit();
+}
+
+boost::signals2::connection LLButton::setClickedCallback( const commit_signal_t::slot_type& cb )
+{
+ return mCommitSignal.connect(cb);
+}
+boost::signals2::connection LLButton::setMouseDownCallback( const commit_signal_t::slot_type& cb )
+{
+ return mMouseDownSignal.connect(cb);
+}
+boost::signals2::connection LLButton::setMouseUpCallback( const commit_signal_t::slot_type& cb )
+{
+ return mMouseUpSignal.connect(cb);
+}
+boost::signals2::connection LLButton::setHeldDownCallback( const commit_signal_t::slot_type& cb )
+{
+ return mHeldDownSignal.connect(cb);
}
+// *TODO: Deprecate (for backwards compatability only)
+boost::signals2::connection LLButton::setClickedCallback( button_callback_t cb, void* data )
+{
+ return setClickedCallback(boost::bind(cb, data));
+}
+boost::signals2::connection LLButton::setMouseDownCallback( button_callback_t cb, void* data )
+{
+ return setMouseDownCallback(boost::bind(cb, data));
+}
+boost::signals2::connection LLButton::setMouseUpCallback( button_callback_t cb, void* data )
+{
+ return setMouseUpCallback(boost::bind(cb, data));
+}
+boost::signals2::connection LLButton::setHeldDownCallback( button_callback_t cb, void* data )
+{
+ return setHeldDownCallback(boost::bind(cb, data));
+}
+BOOL LLButton::postBuild()
+{
+ autoResize();
+ return TRUE;
+}
BOOL LLButton::handleUnicodeCharHere(llwchar uni_char)
{
BOOL handled = FALSE;
@@ -278,10 +318,8 @@ BOOL LLButton::handleUnicodeCharHere(llwchar uni_char)
toggleState();
}
- if (mClickedCallback)
- {
- (*mClickedCallback)( mCallbackUserData );
- }
+ LLUICtrl::onCommit();
+
handled = TRUE;
}
return handled;
@@ -299,10 +337,7 @@ BOOL LLButton::handleKeyHere(KEY key, MASK mask )
handled = TRUE;
- if (mClickedCallback)
- {
- (*mClickedCallback)( mCallbackUserData );
- }
+ LLUICtrl::onCommit();
}
return handled;
}
@@ -310,27 +345,27 @@ BOOL LLButton::handleKeyHere(KEY key, MASK mask )
BOOL LLButton::handleMouseDown(S32 x, S32 y, MASK mask)
{
- // Route future Mouse messages here preemptively. (Release on mouse up.)
- gFocusMgr.setMouseCapture( this );
-
- if (hasTabStop() && !getIsChrome())
+ if (!childrenHandleMouseDown(x, y, mask))
{
- setFocus(TRUE);
- }
+ // Route future Mouse messages here preemptively. (Release on mouse up.)
+ gFocusMgr.setMouseCapture( this );
- if (mMouseDownCallback)
- {
- (*mMouseDownCallback)(mCallbackUserData);
- }
+ if (hasTabStop() && !getIsChrome())
+ {
+ setFocus(TRUE);
+ }
- mMouseDownTimer.start();
- mMouseDownFrame = (S32) LLFrameTimer::getFrameCount();
-
- if (getSoundFlags() & MOUSE_DOWN)
- {
- make_ui_sound("UISndClick");
- }
+ mMouseDownSignal(this, LLSD());
+ mMouseDownTimer.start();
+ mMouseDownFrame = (S32) LLFrameTimer::getFrameCount();
+ mMouseHeldDownCount = 0;
+
+ if (getSoundFlags() & MOUSE_DOWN)
+ {
+ make_ui_sound("UISndClick");
+ }
+ }
return TRUE;
}
@@ -344,13 +379,9 @@ BOOL LLButton::handleMouseUp(S32 x, S32 y, MASK mask)
gFocusMgr.setMouseCapture( NULL );
// Regardless of where mouseup occurs, handle callback
- if (mMouseUpCallback)
- {
- (*mMouseUpCallback)(mCallbackUserData);
- }
+ mMouseUpSignal(this, LLSD());
- mMouseDownTimer.stop();
- mMouseDownTimer.reset();
+ resetMouseDownTimer();
// DO THIS AT THE VERY END to allow the button to be destroyed as a result of being clicked.
// If mouseup in the widget, it's been clicked
@@ -366,38 +397,97 @@ BOOL LLButton::handleMouseUp(S32 x, S32 y, MASK mask)
toggleState();
}
- if (mClickedCallback)
- {
- (*mClickedCallback)( mCallbackUserData );
- }
+ LLUICtrl::onCommit();
}
}
+ else
+ {
+ childrenHandleMouseUp(x, y, mask);
+ }
return TRUE;
}
-
-BOOL LLButton::handleHover(S32 x, S32 y, MASK mask)
+BOOL LLButton::handleRightMouseDown(S32 x, S32 y, MASK mask)
{
- LLMouseHandler* other_captor = gFocusMgr.getMouseCapture();
- mNeedsHighlight = other_captor == NULL ||
- other_captor == this ||
- // this following bit is to support modal dialogs
- (other_captor->isView() && hasAncestor((LLView*)other_captor));
-
- if (mMouseDownTimer.getStarted() && NULL != mHeldDownCallback)
+ if (!childrenHandleRightMouseDown(x, y, mask))
{
- F32 elapsed = getHeldDownTime();
- if( mHeldDownDelay <= elapsed && mHeldDownFrameDelay <= (S32)LLFrameTimer::getFrameCount() - mMouseDownFrame)
+ // Route future Mouse messages here preemptively. (Release on mouse up.)
+ gFocusMgr.setMouseCapture( this );
+
+ if (hasTabStop() && !getIsChrome())
{
- mHeldDownCallback( mCallbackUserData );
+ setFocus(TRUE);
}
+
+// if (pointInView(x, y))
+// {
+// }
}
+ // send the mouse down signal
+ LLUICtrl::handleRightMouseDown(x,y,mask);
+ // *TODO: Return result of LLUICtrl call above? Should defer to base class
+ // but this might change the mouse handling of existing buttons in a bad way
+ // if they are not mouse opaque.
+ return TRUE;
+}
+BOOL LLButton::handleRightMouseUp(S32 x, S32 y, MASK mask)
+{
// We only handle the click if the click both started and ended within us
- getWindow()->setCursor(UI_CURSOR_ARROW);
- lldebugst(LLERR_USER_INPUT) << "hover handled by " << getName() << llendl;
+ if( hasMouseCapture() )
+ {
+ // Always release the mouse
+ gFocusMgr.setMouseCapture( NULL );
+// if (pointInView(x, y))
+// {
+// mRightMouseUpSignal(this, x,y,mask);
+// }
+ }
+ else
+ {
+ childrenHandleRightMouseUp(x, y, mask);
+ }
+ // send the mouse up signal
+ LLUICtrl::handleRightMouseUp(x,y,mask);
+ // *TODO: Return result of LLUICtrl call above? Should defer to base class
+ // but this might change the mouse handling of existing buttons in a bad way.
+ // if they are not mouse opaque.
+ return TRUE;
+}
+
+
+void LLButton::onMouseEnter(S32 x, S32 y, MASK mask)
+{
+ if (isInEnabledChain())
+ mNeedsHighlight = TRUE;
+}
+
+void LLButton::onMouseLeave(S32 x, S32 y, MASK mask)
+{
+ mNeedsHighlight = FALSE;
+}
+
+BOOL LLButton::handleHover(S32 x, S32 y, MASK mask)
+{
+ if (!childrenHandleHover(x, y, mask))
+ {
+ if (mMouseDownTimer.getStarted())
+ {
+ F32 elapsed = getHeldDownTime();
+ if( mHeldDownDelay <= elapsed && mHeldDownFrameDelay <= (S32)LLFrameTimer::getFrameCount() - mMouseDownFrame)
+ {
+ LLSD param;
+ param["count"] = mMouseHeldDownCount++;
+ mHeldDownSignal(this, param);
+ }
+ }
+
+ // We only handle the click if the click both started and ended within us
+ getWindow()->setCursor(UI_CURSOR_ARROW);
+ lldebugst(LLERR_USER_INPUT) << "hover handled by " << getName() << llendl;
+ }
return TRUE;
}
@@ -405,16 +495,19 @@ BOOL LLButton::handleHover(S32 x, S32 y, MASK mask)
// virtual
void LLButton::draw()
{
- BOOL flash = FALSE;
+ bool flash = FALSE;
+ static LLUICachedControl<F32> button_flash_rate("ButtonFlashRate", 0);
+ static LLUICachedControl<S32> button_flash_count("ButtonFlashCount", 0);
+
if( mFlashing )
{
F32 elapsed = mFlashingTimer.getElapsedTimeF32();
- S32 flash_count = S32(elapsed * LLUI::sConfigGroup->getF32("ButtonFlashRate") * 2.f);
+ S32 flash_count = S32(elapsed * button_flash_rate * 2.f);
// flash on or off?
- flash = (flash_count % 2 == 0) || flash_count > S32((F32)LLUI::sConfigGroup->getS32("ButtonFlashCount") * 2.f);
+ flash = (flash_count % 2 == 0) || flash_count > S32((F32)button_flash_count * 2.f);
}
- BOOL pressed_by_keyboard = FALSE;
+ bool pressed_by_keyboard = FALSE;
if (hasFocus())
{
pressed_by_keyboard = gKeyboard->getKeyDown(' ') || (mCommitOnReturn && gKeyboard->getKeyDown(KEY_RETURN));
@@ -425,24 +518,31 @@ void LLButton::draw()
S32 local_mouse_y;
LLUI::getCursorPositionLocal(this, &local_mouse_x, &local_mouse_y);
- BOOL pressed = pressed_by_keyboard
- || (hasMouseCapture() && pointInView(local_mouse_x, local_mouse_y))
- || mToggleState;
+ bool enabled = isInEnabledChain();
+
+ bool pressed = pressed_by_keyboard
+ || (hasMouseCapture() && pointInView(local_mouse_x, local_mouse_y));
+ bool selected = getToggleState();
- BOOL use_glow_effect = FALSE;
+ bool use_glow_effect = FALSE;
LLColor4 glow_color = LLColor4::white;
LLRender::eBlendType glow_type = LLRender::BT_ADD_WITH_ALPHA;
- if ( mNeedsHighlight )
+ LLUIImage* imagep = NULL;
+ if (pressed)
{
- if (pressed)
+ imagep = selected ? mImagePressedSelected : mImagePressed;
+ }
+ else if ( mNeedsHighlight )
+ {
+ if (selected)
{
if (mImageHoverSelected)
{
- mImagep = mImageHoverSelected;
+ imagep = mImageHoverSelected;
}
else
{
- mImagep = mImageSelected;
+ imagep = mImageSelected;
use_glow_effect = TRUE;
}
}
@@ -450,32 +550,18 @@ void LLButton::draw()
{
if (mImageHoverUnselected)
{
- mImagep = mImageHoverUnselected;
+ imagep = mImageHoverUnselected;
}
else
{
- mImagep = mImageUnselected;
+ imagep = mImageUnselected;
use_glow_effect = TRUE;
}
}
}
- else if ( pressed )
+ else
{
- mImagep = mImageSelected;
- }
- else
- {
- mImagep = mImageUnselected;
- }
-
- if (mFlashing)
- {
- use_glow_effect = TRUE;
- glow_type = LLRender::BT_ALPHA; // blend the glow
- if (mNeedsHighlight) // highlighted AND flashing
- glow_color = (glow_color*0.5f + mFlashBgColor*0.5f) % 2.0f; // average between flash and highlight colour, with sum of the opacity
- else
- glow_color = mFlashBgColor;
+ imagep = selected ? mImageSelected : mImageUnselected;
}
// Override if more data is available
@@ -485,19 +571,31 @@ void LLButton::draw()
// disabled but checked
if (!mImageDisabledSelected.isNull()
&&
- ( (getEnabled() && getTentative())
- || (!getEnabled() && pressed ) ) )
+ ( (enabled && getTentative())
+ || (!enabled && selected ) ) )
{
- mImagep = mImageDisabledSelected;
+ imagep = mImageDisabledSelected;
}
else if (!mImageDisabled.isNull()
- && !getEnabled()
- && !pressed)
+ && !enabled
+ && !selected)
{
- mImagep = mImageDisabled;
+ imagep = mImageDisabled;
}
- if (mNeedsHighlight && !mImagep)
+ if (mFlashing)
+ {
+ LLColor4 flash_color = mFlashBgColor.get();
+ use_glow_effect = TRUE;
+ glow_type = LLRender::BT_ALPHA; // blend the glow
+
+ if (mNeedsHighlight) // highlighted AND flashing
+ glow_color = (glow_color*0.5f + flash_color*0.5f) % 2.0f; // average between flash and highlight colour, with sum of the opacity
+ else
+ glow_color = flash_color;
+ }
+
+ if (mNeedsHighlight && !imagep)
{
use_glow_effect = TRUE;
}
@@ -506,60 +604,46 @@ void LLButton::draw()
LLColor4 label_color;
// label changes when button state changes, not when pressed
- if ( getEnabled() )
+ if ( enabled )
{
- if ( mToggleState )
+ if ( getToggleState() )
{
- label_color = mSelectedLabelColor;
+ label_color = mSelectedLabelColor.get();
}
else
{
- label_color = mUnselectedLabelColor;
+ label_color = mUnselectedLabelColor.get();
}
}
else
{
- if ( mToggleState )
+ if ( getToggleState() )
{
- label_color = mDisabledSelectedLabelColor;
+ label_color = mDisabledSelectedLabelColor.get();
}
else
{
- label_color = mDisabledLabelColor;
+ label_color = mDisabledLabelColor.get();
}
}
// Unselected label assignments
LLWString label;
- if( mToggleState )
+ if( getToggleState() )
{
- if( getEnabled() || mDisabledSelectedLabel.empty() )
- {
- label = mSelectedLabel;
- }
- else
- {
- label = mDisabledSelectedLabel;
- }
+ label = mSelectedLabel;
}
else
{
- if( getEnabled() || mDisabledLabel.empty() )
- {
- label = mUnselectedLabel;
- }
- else
- {
- label = mDisabledLabel;
- }
+ label = mUnselectedLabel;
}
// overlay with keyboard focus border
if (hasFocus())
{
F32 lerp_amt = gFocusMgr.getFocusFlashAmt();
- drawBorder(gFocusMgr.getFocusColor(), llround(lerp(1.f, 3.f, lerp_amt)));
+ drawBorder(imagep, gFocusMgr.getFocusColor(), llround(lerp(1.f, 3.f, lerp_amt)));
}
if (use_glow_effect)
@@ -576,25 +660,27 @@ void LLButton::draw()
// Draw button image, if available.
// Otherwise draw basic rectangular button.
- if (mImagep.notNull())
+ if (imagep != NULL)
{
+ // apply automatic 50% alpha fade to disabled image
+ LLColor4 disabled_color = mFadeWhenDisabled ? mDisabledImageColor.get() % 0.5f : mDisabledImageColor.get();
if ( mScaleImage)
{
- mImagep->draw(getLocalRect(), getEnabled() ? mImageColor : mDisabledImageColor );
+ imagep->draw(getLocalRect(), enabled ? mImageColor.get() : disabled_color );
if (mCurGlowStrength > 0.01f)
{
gGL.setSceneBlendType(glow_type);
- mImagep->drawSolid(0, 0, getRect().getWidth(), getRect().getHeight(), glow_color % mCurGlowStrength);
+ imagep->drawSolid(0, 0, getRect().getWidth(), getRect().getHeight(), glow_color % mCurGlowStrength);
gGL.setSceneBlendType(LLRender::BT_ALPHA);
}
}
else
{
- mImagep->draw(0, 0, getEnabled() ? mImageColor : mDisabledImageColor );
+ imagep->draw(0, 0, enabled ? mImageColor.get() : disabled_color );
if (mCurGlowStrength > 0.01f)
{
gGL.setSceneBlendType(glow_type);
- mImagep->drawSolid(0, 0, glow_color % mCurGlowStrength);
+ imagep->drawSolid(0, 0, glow_color % mCurGlowStrength);
gGL.setSceneBlendType(LLRender::BT_ALPHA);
}
}
@@ -602,7 +688,7 @@ void LLButton::draw()
else
{
// no image
- llwarns << "No image for button " << getName() << llendl;
+ lldebugs << "No image for button " << getName() << llendl;
// draw it in pink so we can find it
gl_rect_2d(0, getRect().getHeight(), getRect().getWidth(), 0, LLColor4::pink1, FALSE);
}
@@ -634,8 +720,8 @@ void LLButton::draw()
}
// fade out overlay images on disabled buttons
- LLColor4 overlay_color = mImageOverlayColor;
- if (!getEnabled())
+ LLColor4 overlay_color = mImageOverlayColor.get();
+ if (!enabled)
{
overlay_color.mV[VALPHA] = 0.5f;
}
@@ -704,52 +790,49 @@ void LLButton::draw()
x++;
}
+ // *NOTE: mantipov: before mUseEllipses is implemented in EXT-279 U32_MAX has been passed as
+ // max_chars.
+ // LLFontGL::render expects S32 max_chars variable but process in a separate way -1 value.
+ // Due to U32_MAX is equal to S32 -1 value I have rest this value for non-ellipses mode.
+ // Not sure if it is really needed. Probably S32_MAX should be always passed as max_chars.
mGLFont->render(label, 0, (F32)x, (F32)(LLBUTTON_V_PAD + y_offset),
label_color,
mHAlign, LLFontGL::BOTTOM,
- mDropShadowedText ? LLFontGL::DROP_SHADOW_SOFT : LLFontGL::NORMAL,
- U32_MAX, text_width,
- NULL, FALSE, FALSE);
- }
-
- if (sDebugRects
- || (LLView::sEditingUI && this == LLView::sEditingUIView))
- {
- drawDebugRect();
+ LLFontGL::NORMAL,
+ mDropShadowedText ? LLFontGL::DROP_SHADOW_SOFT : LLFontGL::NO_SHADOW,
+ S32_MAX, text_width,
+ NULL, mUseEllipses);
}
- // reset hover status for next frame
- mNeedsHighlight = FALSE;
+ LLUICtrl::draw();
}
-void LLButton::drawBorder(const LLColor4& color, S32 size)
+void LLButton::drawBorder(LLUIImage* imagep, const LLColor4& color, S32 size)
{
+ if (imagep == NULL) return;
if (mScaleImage)
{
- mImagep->drawBorder(getLocalRect(), color, size);
+ imagep->drawBorder(getLocalRect(), color, size);
}
else
{
- mImagep->drawBorder(0, 0, color, size);
+ imagep->drawBorder(0, 0, color, size);
}
}
-void LLButton::setClickedCallback(void (*cb)(void*), void* userdata)
+BOOL LLButton::getToggleState() const
{
- mClickedCallback = cb;
- if (userdata)
- {
- mCallbackUserData = userdata;
- }
+ return getValue().asBoolean();
}
-
void LLButton::setToggleState(BOOL b)
{
- if( b != mToggleState )
+ if( b != getToggleState() )
{
setControlValue(b); // will fire LLControlVariable callbacks (if any)
- mToggleState = b; // may or may not be redundant
+ setValue(b); // may or may not be redundant
+ // Unselected label assignments
+ autoResize();
}
}
@@ -764,19 +847,11 @@ void LLButton::setFlashing( BOOL b )
BOOL LLButton::toggleState()
-{
- setToggleState( !mToggleState );
- return mToggleState;
-}
-
-void LLButton::setValue(const LLSD& value )
{
- mToggleState = value.asBoolean();
-}
+ bool flipped = ! getToggleState();
+ setToggleState(flipped);
-LLSD LLButton::getValue() const
-{
- return mToggleState == TRUE;
+ return flipped;
}
void LLButton::setLabel( const LLStringExplicit& label )
@@ -803,26 +878,48 @@ void LLButton::setLabelSelected( const LLStringExplicit& label )
mSelectedLabel = label;
}
-void LLButton::setDisabledLabel( const LLStringExplicit& label )
+void LLButton::setImageUnselected(LLPointer<LLUIImage> image)
{
- mDisabledLabel = label;
+ mImageUnselected = image;
+ if (mImageUnselected.isNull())
+ {
+ llwarns << "Setting default button image for: " << getName() << " to NULL" << llendl;
+ }
}
-void LLButton::setDisabledSelectedLabel( const LLStringExplicit& label )
+void LLButton::autoResize()
{
- mDisabledSelectedLabel = label;
+ LLUIString label;
+ if(getToggleState())
+ {
+ label = mSelectedLabel;
+ }
+ else
+ {
+ label = mUnselectedLabel;
+ }
+ resize(label);
}
-void LLButton::setImageUnselected(LLPointer<LLUIImage> image)
+void LLButton::resize(LLUIString label)
{
- mImageUnselected = image;
+ // get label length
+ S32 label_width = mGLFont->getWidth(label.getString());
+ // get current btn length
+ S32 btn_width =getRect().getWidth();
+ // check if it need resize
+ if (mAutoResize == TRUE)
+ {
+ if (btn_width - (mRightHPad + mLeftHPad) < label_width)
+ {
+ setRect(LLRect( getRect().mLeft, getRect().mTop, getRect().mLeft + label_width + mLeftHPad + mRightHPad , getRect().mBottom));
+ }
+ }
}
-
void LLButton::setImages( const std::string &image_name, const std::string &selected_name )
{
- setImageUnselected(image_name);
- setImageSelected(selected_name);
-
+ setImageUnselected(LLUI::getUIImage(image_name));
+ setImageSelected(LLUI::getUIImage(selected_name));
}
void LLButton::setImageSelected(LLPointer<LLUIImage> image)
@@ -840,26 +937,29 @@ void LLButton::setColor(const LLColor4& color)
setImageColor(color);
}
+void LLButton::setAlpha(F32 alpha)
+{
+ LLColor4 temp = mImageColor.get();
+ temp.setAlpha(alpha);
+ mImageColor.set(temp);
+
+ temp = mDisabledImageColor.get();
+ temp.setAlpha(alpha * 0.5f);
+ mDisabledImageColor.set(temp);
+}
void LLButton::setImageDisabled(LLPointer<LLUIImage> image)
{
mImageDisabled = image;
mDisabledImageColor = mImageColor;
- mDisabledImageColor.mV[VALPHA] *= 0.5f;
+ mFadeWhenDisabled = TRUE;
}
void LLButton::setImageDisabledSelected(LLPointer<LLUIImage> image)
{
mImageDisabledSelected = image;
mDisabledImageColor = mImageColor;
- mDisabledImageColor.mV[VALPHA] *= 0.5f;
-}
-
-void LLButton::setDisabledImages( const std::string &image_name, const std::string &selected_name, const LLColor4& c )
-{
- setImageDisabled(image_name);
- setImageDisabledSelected(selected_name);
- mDisabledImageColor = c;
+ mFadeWhenDisabled = TRUE;
}
void LLButton::setImageHoverSelected(LLPointer<LLUIImage> image)
@@ -867,24 +967,11 @@ void LLButton::setImageHoverSelected(LLPointer<LLUIImage> image)
mImageHoverSelected = image;
}
-void LLButton::setDisabledImages( const std::string &image_name, const std::string &selected_name)
-{
- LLColor4 clr = mImageColor;
- clr.mV[VALPHA] *= .5f;
- setDisabledImages( image_name, selected_name, clr );
-}
-
void LLButton::setImageHoverUnselected(LLPointer<LLUIImage> image)
{
mImageHoverUnselected = image;
}
-void LLButton::setHoverImages( const std::string& image_name, const std::string& selected_name )
-{
- setImageHoverUnselected(image_name);
- setImageHoverSelected(selected_name);
-}
-
void LLButton::setImageOverlay(const std::string& image_name, LLFontGL::HAlign alignment, const LLColor4& color)
{
if (image_name.empty())
@@ -899,11 +986,9 @@ void LLButton::setImageOverlay(const std::string& image_name, LLFontGL::HAlign a
}
}
-
void LLButton::onMouseCaptureLost()
{
- mMouseDownTimer.stop();
- mMouseDownTimer.reset();
+ resetMouseDownTimer();
}
//-------------------------------------------------------------------------
@@ -924,42 +1009,6 @@ S32 round_up(S32 grid, S32 value)
}
}
-void LLButton::setImageUnselected(const std::string &image_name)
-{
- setImageUnselected(LLUI::getUIImage(image_name));
- mImageUnselectedName = image_name;
-}
-
-void LLButton::setImageSelected(const std::string &image_name)
-{
- setImageSelected(LLUI::getUIImage(image_name));
- mImageSelectedName = image_name;
-}
-
-void LLButton::setImageHoverSelected(const std::string &image_name)
-{
- setImageHoverSelected(LLUI::getUIImage(image_name));
- mImageHoverSelectedName = image_name;
-}
-
-void LLButton::setImageHoverUnselected(const std::string &image_name)
-{
- setImageHoverUnselected(LLUI::getUIImage(image_name));
- mImageHoverUnselectedName = image_name;
-}
-
-void LLButton::setImageDisabled(const std::string &image_name)
-{
- setImageDisabled(LLUI::getUIImage(image_name));
- mImageDisabledName = image_name;
-}
-
-void LLButton::setImageDisabledSelected(const std::string &image_name)
-{
- setImageDisabledSelected(LLUI::getUIImage(image_name));
- mImageDisabledSelectedName = image_name;
-}
-
void LLButton::addImageAttributeToXML(LLXMLNodePtr node,
const std::string& image_name,
const LLUUID& image_id,
@@ -975,28 +1024,6 @@ void LLButton::addImageAttributeToXML(LLXMLNodePtr node,
}
}
-// virtual
-LLXMLNodePtr LLButton::getXML(bool save_children) const
-{
- LLXMLNodePtr node = LLUICtrl::getXML();
-
- node->createChild("label", TRUE)->setStringValue(getLabelUnselected());
- node->createChild("label_selected", TRUE)->setStringValue(getLabelSelected());
- node->createChild("font", TRUE)->setStringValue(LLFontGL::nameFromFont(mGLFont));
- node->createChild("halign", TRUE)->setStringValue(LLFontGL::nameFromHAlign(mHAlign));
-
- addImageAttributeToXML(node,mImageUnselectedName,mImageUnselectedID,std::string("image_unselected"));
- addImageAttributeToXML(node,mImageSelectedName,mImageSelectedID,std::string("image_selected"));
- addImageAttributeToXML(node,mImageHoverSelectedName,mImageHoverSelectedID,std::string("image_hover_selected"));
- addImageAttributeToXML(node,mImageHoverUnselectedName,mImageHoverUnselectedID,std::string("image_hover_unselected"));
- addImageAttributeToXML(node,mImageDisabledName,mImageDisabledID,std::string("image_disabled"));
- addImageAttributeToXML(node,mImageDisabledSelectedName,mImageDisabledSelectedID,std::string("image_disabled_selected"));
-
- node->createChild("scale_image", TRUE)->setBoolValue(mScaleImage);
-
- return node;
-}
-
void clicked_help(void* data)
{
LLButton* self = (LLButton*)data;
@@ -1010,114 +1037,53 @@ void clicked_help(void* data)
LLUI::sHtmlHelp->show(self->getHelpURL());
}
-// static
-LLView* LLButton::fromXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFactory *factory)
+void LLButton::setHelpURLCallback(const std::string &help_url)
{
- std::string name("button");
- node->getAttributeString("name", name);
-
- std::string label = name;
- node->getAttributeString("label", label);
-
- std::string label_selected = label;
- node->getAttributeString("label_selected", label_selected);
-
- LLFontGL* font = selectFont(node);
-
- std::string image_unselected;
- if (node->hasAttribute("image_unselected")) node->getAttributeString("image_unselected",image_unselected);
-
- std::string image_selected;
- if (node->hasAttribute("image_selected")) node->getAttributeString("image_selected",image_selected);
-
- std::string image_hover_selected;
- if (node->hasAttribute("image_hover_selected")) node->getAttributeString("image_hover_selected",image_hover_selected);
-
- std::string image_hover_unselected;
- if (node->hasAttribute("image_hover_unselected")) node->getAttributeString("image_hover_unselected",image_hover_unselected);
-
- std::string image_disabled_selected;
- if (node->hasAttribute("image_disabled_selected")) node->getAttributeString("image_disabled_selected",image_disabled_selected);
-
- std::string image_disabled;
- if (node->hasAttribute("image_disabled")) node->getAttributeString("image_disabled",image_disabled);
-
- std::string image_overlay;
- node->getAttributeString("image_overlay", image_overlay);
-
- LLFontGL::HAlign image_overlay_alignment = LLFontGL::HCENTER;
- std::string image_overlay_alignment_string;
- if (node->hasAttribute("image_overlay_alignment"))
- {
- node->getAttributeString("image_overlay_alignment", image_overlay_alignment_string);
- image_overlay_alignment = LLFontGL::hAlignFromName(image_overlay_alignment_string);
- }
-
-
- LLButton *button = new LLButton(name,
- LLRect(),
- image_unselected,
- image_selected,
- LLStringUtil::null,
- NULL,
- parent,
- font,
- label,
- label_selected);
-
- node->getAttributeS32("pad_right", button->mRightHPad);
- node->getAttributeS32("pad_left", button->mLeftHPad);
+ mHelpURL = help_url;
+ setClickedCallback(clicked_help,this);
+}
- BOOL is_toggle = button->getIsToggle();
- node->getAttributeBOOL("toggle", is_toggle);
- button->setIsToggle(is_toggle);
+// static
+void LLButton::toggleFloaterAndSetToggleState(LLUICtrl* ctrl, const LLSD& sdname)
+{
+ bool floater_vis = LLFloaterReg::toggleInstance(sdname.asString());
+ LLButton* button = dynamic_cast<LLButton*>(ctrl);
+ if (button)
+ button->setToggleState(floater_vis);
+}
- if(image_hover_selected != LLStringUtil::null) button->setImageHoverSelected(image_hover_selected);
-
- if(image_hover_unselected != LLStringUtil::null) button->setImageHoverUnselected(image_hover_unselected);
-
- if(image_disabled_selected != LLStringUtil::null) button->setImageDisabledSelected(image_disabled_selected );
-
- if(image_disabled != LLStringUtil::null) button->setImageDisabled(image_disabled);
-
- if(image_overlay != LLStringUtil::null) button->setImageOverlay(image_overlay, image_overlay_alignment);
+// static
+// Gets called once
+void LLButton::setFloaterToggle(LLUICtrl* ctrl, const LLSD& sdname)
+{
+ LLButton* button = dynamic_cast<LLButton*>(ctrl);
+ if (!button)
+ return;
+ // Get the visibility control name for the floater
+ std::string vis_control_name = LLFloaterReg::declareVisibilityControl(sdname.asString());
+ // Set the button control value (toggle state) to the floater visibility control (Sets the value as well)
+ button->setControlVariable(LLUI::sSettingGroups["floater"]->getControl(vis_control_name));
+ // Set the clicked callback to toggle the floater
+ button->setClickedCallback(boost::bind(&LLFloaterReg::toggleFloaterInstance, sdname));
+}
- if (node->hasAttribute("halign"))
- {
- LLFontGL::HAlign halign = selectFontHAlign(node);
- button->setHAlign(halign);
- }
+void LLButton::resetMouseDownTimer()
+{
+ mMouseDownTimer.stop();
+ mMouseDownTimer.reset();
+}
- if (node->hasAttribute("scale_image"))
- {
- BOOL needsScale = FALSE;
- node->getAttributeBOOL("scale_image",needsScale);
- button->setScaleImage( needsScale );
- }
- if(label.empty())
- {
- button->setLabelUnselected(node->getTextContents());
- }
- if (label_selected.empty())
- {
- button->setLabelSelected(node->getTextContents());
- }
-
- if (node->hasAttribute("help_url"))
+// *TODO: Remove this function after the initial XUI XML re-export pass.
+// static
+void LLButton::setupParamsForExport(Params& p, LLView* parent)
+{
+ std::string label = p.label;
+ if (label.empty())
{
- std::string help_url;
- node->getAttributeString("help_url",help_url);
- button->setHelpURLCallback(help_url);
+ //if our label is empty this is a picture style button
+ p.picture_style = true;
}
- button->initFromXML(node, parent);
-
- return button;
-}
-
-void LLButton::setHelpURLCallback(const std::string &help_url)
-{
- mHelpURL = help_url;
- setClickedCallback(clicked_help,this);
+ LLUICtrl::setupParamsForExport(p, parent);
}
diff --git a/indra/llui/llbutton.h b/indra/llui/llbutton.h
index 724b77541a..e51cd443fa 100644
--- a/indra/llui/llbutton.h
+++ b/indra/llui/llbutton.h
@@ -39,7 +39,7 @@
#include "v4color.h"
#include "llframetimer.h"
#include "llfontgl.h"
-#include "llimage.h"
+#include "lluiimage.h"
#include "lluistring.h"
//
@@ -53,9 +53,6 @@ extern S32 LLBUTTON_V_PAD;
extern S32 BTN_HEIGHT_SMALL;
extern S32 BTN_HEIGHT;
-// All button widths should be rounded up to this size
-extern S32 BTN_GRID;
-
//
// Helpful functions
//
@@ -72,55 +69,112 @@ class LLButton
: public LLUICtrl
{
public:
- // simple button with text label
- LLButton(const std::string& name, const LLRect &rect, const std::string& control_name = std::string(),
- void (*on_click)(void*) = NULL, void *data = NULL);
-
- LLButton(const std::string& name, const LLRect& rect,
- const std::string &unselected_image,
- const std::string &selected_image,
- const std::string& control_name,
- void (*click_callback)(void*),
- void *callback_data = NULL,
- const LLFontGL* mGLFont = NULL,
- const std::string& unselected_label = LLStringUtil::null,
- const std::string& selected_label = LLStringUtil::null );
-
- virtual ~LLButton();
- void init(void (*click_callback)(void*), void *callback_data, const LLFontGL* font, const std::string& control_name);
-
+ struct Params
+ : public LLInitParam::Block<Params, LLUICtrl::Params>
+ {
+ // text label
+ Optional<std::string> label_selected;
+ Optional<bool> label_shadow;
+ Optional<bool> auto_resize;
+ Optional<bool> use_ellipses;
+
+ // images
+ Optional<LLUIImage*> image_unselected,
+ image_selected,
+ image_hover_selected,
+ image_hover_unselected,
+ image_disabled_selected,
+ image_disabled,
+ image_pressed,
+ image_pressed_selected,
+ image_overlay;
+
+ Optional<std::string> image_overlay_alignment;
+
+ // colors
+ Optional<LLUIColor> label_color,
+ label_color_selected,
+ label_color_disabled,
+ label_color_disabled_selected,
+ highlight_color,
+ image_color,
+ image_color_disabled,
+ image_overlay_color,
+ flash_color;
+
+ // layout
+ Optional<S32> pad_right;
+ Optional<S32> pad_left;
+
+ // callbacks
+ Optional<CommitCallbackParam> click_callback, // alias -> commit_callback
+ mouse_down_callback,
+ mouse_up_callback,
+ mouse_held_callback;
+
+ // misc
+ Optional<bool> is_toggle,
+ scale_image,
+ commit_on_return,
+ picture_style; //if true, don't display label
+
+ Optional<std::string> help_url;
+ Optional<F32> hover_glow_amount;
+ Optional<TimeIntervalParam> held_down_delay;
+
+ Params();
+ };
+protected:
+ friend class LLUICtrlFactory;
+ LLButton(const Params&);
+
+public:
+ // For backward compatability only
+ typedef boost::function<void(void*)> button_callback_t;
+
void addImageAttributeToXML(LLXMLNodePtr node, const std::string& imageName,
const LLUUID& imageID,const std::string& xmlTagName) const;
- virtual LLXMLNodePtr getXML(bool save_children = true) const;
- static LLView* fromXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFactory *factory);
-
virtual BOOL handleUnicodeCharHere(llwchar uni_char);
virtual BOOL handleKeyHere(KEY key, MASK mask);
virtual BOOL handleMouseDown(S32 x, S32 y, MASK mask);
virtual BOOL handleMouseUp(S32 x, S32 y, MASK mask);
virtual BOOL handleHover(S32 x, S32 y, MASK mask);
+ virtual BOOL handleRightMouseDown(S32 x, S32 y, MASK mask);
+ virtual BOOL handleRightMouseUp(S32 x, S32 y, MASK mask);
virtual void draw();
+ /*virtual*/ BOOL postBuild();
+ virtual void onMouseEnter(S32 x, S32 y, MASK mask);
+ virtual void onMouseLeave(S32 x, S32 y, MASK mask);
virtual void onMouseCaptureLost();
virtual void onCommit();
void setUnselectedLabelColor( const LLColor4& c ) { mUnselectedLabelColor = c; }
void setSelectedLabelColor( const LLColor4& c ) { mSelectedLabelColor = c; }
+ void setUseEllipses( BOOL use_ellipses ) { mUseEllipses = use_ellipses; }
- void setClickedCallback( void (*cb)(void *data), void* data = NULL ); // mouse down and up within button
- void setMouseDownCallback( void (*cb)(void *data) ) { mMouseDownCallback = cb; } // mouse down within button
- void setMouseUpCallback( void (*cb)(void *data) ) { mMouseUpCallback = cb; } // mouse up, EVEN IF NOT IN BUTTON
- void setHeldDownCallback( void (*cb)(void *data) ) { mHeldDownCallback = cb; } // Mouse button held down and in button
- void setHeldDownDelay( F32 seconds, S32 frames = 0) { mHeldDownDelay = seconds; mHeldDownFrameDelay = frames; }
+ boost::signals2::connection setClickedCallback( const commit_signal_t::slot_type& cb ); // mouse down and up within button
+ boost::signals2::connection setMouseDownCallback( const commit_signal_t::slot_type& cb );
+ boost::signals2::connection setMouseUpCallback( const commit_signal_t::slot_type& cb ); // mouse up, EVEN IF NOT IN BUTTON
+ // Passes a 'count' parameter in the commit param payload, i.e. param["count"])
+ boost::signals2::connection setHeldDownCallback( const commit_signal_t::slot_type& cb ); // Mouse button held down and in button
+
+
+ // *TODO: Deprecate (for backwards compatability only)
+ boost::signals2::connection setClickedCallback( button_callback_t cb, void* data );
+ boost::signals2::connection setMouseDownCallback( button_callback_t cb, void* data );
+ boost::signals2::connection setMouseUpCallback( button_callback_t cb, void* data );
+ boost::signals2::connection setHeldDownCallback( button_callback_t cb, void* data );
+
+ void setHeldDownDelay( F32 seconds, S32 frames = 0) { mHeldDownDelay = seconds; mHeldDownFrameDelay = frames; }
+
F32 getHeldDownTime() const { return mMouseDownTimer.getElapsedTimeF32(); }
- BOOL getIsToggle() const { return mIsToggle; }
- void setIsToggle(BOOL is_toggle) { mIsToggle = is_toggle; }
BOOL toggleState();
- BOOL getToggleState() const { return mToggleState; }
+ BOOL getToggleState() const;
void setToggleState(BOOL b);
void setFlashing( BOOL b );
@@ -136,31 +190,24 @@ public:
void setImageColor(const std::string& color_control);
void setImageColor(const LLColor4& c);
- virtual void setColor(const LLColor4& c);
+ /*virtual*/ void setColor(const LLColor4& c);
+ /*virtual*/ void setAlpha(F32 alpha);
void setImages(const std::string &image_name, const std::string &selected_name);
- void setDisabledImages(const std::string &image_name, const std::string &selected_name);
- void setDisabledImages(const std::string &image_name, const std::string &selected_name, const LLColor4& c);
- void setHoverImages(const std::string &image_name, const std::string &selected_name);
-
void setDisabledImageColor(const LLColor4& c) { mDisabledImageColor = c; }
void setDisabledSelectedLabelColor( const LLColor4& c ) { mDisabledSelectedLabelColor = c; }
void setImageOverlay(const std::string& image_name, LLFontGL::HAlign alignment = LLFontGL::HCENTER, const LLColor4& color = LLColor4::white);
LLPointer<LLUIImage> getImageOverlay() { return mImageOverlay; }
-
-
- virtual void setValue(const LLSD& value );
- virtual LLSD getValue() const;
+ void autoResize(); // resize with label of current btn state
+ void resize(LLUIString label); // resize with label input
void setLabel( const LLStringExplicit& label);
virtual BOOL setLabelArg( const std::string& key, const LLStringExplicit& text );
void setLabelUnselected(const LLStringExplicit& label);
void setLabelSelected(const LLStringExplicit& label);
- void setDisabledLabel(const LLStringExplicit& disabled_label);
- void setDisabledSelectedLabel(const LLStringExplicit& disabled_label);
void setDisabledLabelColor( const LLColor4& c ) { mDisabledLabelColor = c; }
void setFont(const LLFontGL *font)
@@ -172,19 +219,8 @@ public:
void setBorderEnabled(BOOL b) { mBorderEnabled = b; }
- static void onHeldDown(void *userdata); // to be called by gIdleCallbacks
-
void setHoverGlowStrength(F32 strength) { mHoverGlowStrength = strength; }
- void setImageUnselected(const std::string &image_name);
- const std::string& getImageUnselectedName() const { return mImageUnselectedName; }
- void setImageSelected(const std::string &image_name);
- const std::string& getImageSelectedName() const { return mImageSelectedName; }
- void setImageHoverSelected(const std::string &image_name);
- void setImageHoverUnselected(const std::string &image_name);
- void setImageDisabled(const std::string &image_name);
- void setImageDisabledSelected(const std::string &image_name);
-
void setImageUnselected(LLPointer<LLUIImage> image);
void setImageSelected(LLPointer<LLUIImage> image);
void setImageHoverSelected(LLPointer<LLUIImage> image);
@@ -198,106 +234,91 @@ public:
void setHelpURLCallback(const std::string &help_url);
const std::string& getHelpURL() const { return mHelpURL; }
+ static void onHeldDown(void *userdata); // to be called by gIdleCallbacks
+ static void toggleFloaterAndSetToggleState(LLUICtrl* ctrl, const LLSD& sdname);
+ static void setFloaterToggle(LLUICtrl* ctrl, const LLSD& sdname);
+
protected:
-
- virtual void drawBorder(const LLColor4& color, S32 size);
-
- void setImageUnselectedID(const LLUUID &image_id);
- const LLUUID& getImageUnselectedID() const { return mImageUnselectedID; }
- void setImageSelectedID(const LLUUID &image_id);
- const LLUUID& getImageSelectedID() const { return mImageSelectedID; }
- void setImageHoverSelectedID(const LLUUID &image_id);
- void setImageHoverUnselectedID(const LLUUID &image_id);
- void setImageDisabledID(const LLUUID &image_id);
- void setImageDisabledSelectedID(const LLUUID &image_id);
const LLPointer<LLUIImage>& getImageUnselected() const { return mImageUnselected; }
const LLPointer<LLUIImage>& getImageSelected() const { return mImageSelected; }
LLFrameTimer mMouseDownTimer;
+ // If the label is empty, set the picture_style attribute
+ static void setupParamsForExport(Params& p, LLView* parent);
private:
+ void drawBorder(LLUIImage* imagep, const LLColor4& color, S32 size);
+ void resetMouseDownTimer();
- void (*mClickedCallback)(void* data );
- void (*mMouseDownCallback)(void *data);
- void (*mMouseUpCallback)(void *data);
- void (*mHeldDownCallback)(void *data);
-
- const LLFontGL *mGLFont;
+private:
+ commit_signal_t mMouseDownSignal;
+ commit_signal_t mMouseUpSignal;
+ commit_signal_t mHeldDownSignal;
- S32 mMouseDownFrame;
- F32 mHeldDownDelay; // seconds, after which held-down callbacks get called
- S32 mHeldDownFrameDelay; // frames, after which held-down callbacks get called
-
- LLPointer<LLUIImage> mImageOverlay;
- LLFontGL::HAlign mImageOverlayAlignment;
- LLColor4 mImageOverlayColor;
-
- LLPointer<LLUIImage> mImageUnselected;
- LLUIString mUnselectedLabel;
- LLColor4 mUnselectedLabelColor;
+ const LLFontGL* mGLFont;
+
+ S32 mMouseDownFrame;
+ S32 mMouseHeldDownCount; // Counter for parameter passed to held-down callback
+ F32 mHeldDownDelay; // seconds, after which held-down callbacks get called
+ S32 mHeldDownFrameDelay; // frames, after which held-down callbacks get called
- LLPointer<LLUIImage> mImageSelected;
- LLUIString mSelectedLabel;
- LLColor4 mSelectedLabelColor;
+ LLPointer<LLUIImage> mImageOverlay;
+ LLFontGL::HAlign mImageOverlayAlignment;
+ LLUIColor mImageOverlayColor;
- LLPointer<LLUIImage> mImageHoverSelected;
+ LLPointer<LLUIImage> mImageUnselected;
+ LLUIString mUnselectedLabel;
+ LLUIColor mUnselectedLabelColor;
- LLPointer<LLUIImage> mImageHoverUnselected;
+ LLPointer<LLUIImage> mImageSelected;
+ LLUIString mSelectedLabel;
+ LLUIColor mSelectedLabelColor;
- LLPointer<LLUIImage> mImageDisabled;
- LLUIString mDisabledLabel;
- LLColor4 mDisabledLabelColor;
+ LLPointer<LLUIImage> mImageHoverSelected;
- LLPointer<LLUIImage> mImageDisabledSelected;
- LLUIString mDisabledSelectedLabel;
- LLColor4 mDisabledSelectedLabelColor;
+ LLPointer<LLUIImage> mImageHoverUnselected;
- LLUUID mImageUnselectedID;
- LLUUID mImageSelectedID;
- LLUUID mImageHoverSelectedID;
- LLUUID mImageHoverUnselectedID;
- LLUUID mImageDisabledID;
- LLUUID mImageDisabledSelectedID;
- std::string mImageUnselectedName;
- std::string mImageSelectedName;
- std::string mImageHoverSelectedName;
- std::string mImageHoverUnselectedName;
- std::string mImageDisabledName;
- std::string mImageDisabledSelectedName;
+ LLPointer<LLUIImage> mImageDisabled;
+ LLUIColor mDisabledLabelColor;
- LLColor4 mHighlightColor;
- LLColor4 mUnselectedBgColor;
- LLColor4 mSelectedBgColor;
- LLColor4 mFlashBgColor;
+ LLPointer<LLUIImage> mImageDisabledSelected;
+ LLUIString mDisabledSelectedLabel;
+ LLUIColor mDisabledSelectedLabelColor;
- LLColor4 mImageColor;
- LLColor4 mDisabledImageColor;
+ LLPointer<LLUIImage> mImagePressed;
+ LLPointer<LLUIImage> mImagePressedSelected;
- BOOL mIsToggle;
- BOOL mToggleState;
- BOOL mScaleImage;
+ LLUIColor mHighlightColor;
+ LLUIColor mFlashBgColor;
- BOOL mDropShadowedText;
+ LLUIColor mImageColor;
+ LLUIColor mDisabledImageColor;
- BOOL mBorderEnabled;
+ BOOL mIsToggle;
+ BOOL mScaleImage;
- BOOL mFlashing;
+ BOOL mDropShadowedText;
+ BOOL mAutoResize;
+ BOOL mUseEllipses;
+ BOOL mBorderEnabled;
- LLFontGL::HAlign mHAlign;
- S32 mLeftHPad;
- S32 mRightHPad;
+ BOOL mFlashing;
- F32 mHoverGlowStrength;
- F32 mCurGlowStrength;
+ LLFontGL::HAlign mHAlign;
+ S32 mLeftHPad;
+ S32 mRightHPad;
- BOOL mNeedsHighlight;
- BOOL mCommitOnReturn;
+ F32 mHoverGlowStrength;
+ F32 mCurGlowStrength;
- std::string mHelpURL;
+ BOOL mNeedsHighlight;
+ BOOL mCommitOnReturn;
+ BOOL mFadeWhenDisabled;
- LLPointer<LLUIImage> mImagep;
+ std::string mHelpURL;
- LLFrameTimer mFlashingTimer;
+ LLFrameTimer mFlashingTimer;
};
+
#endif // LL_LLBUTTON_H
diff --git a/indra/llui/llcallbackmap.h b/indra/llui/llcallbackmap.h
index eadb9c98f3..97b1e2fc50 100644
--- a/indra/llui/llcallbackmap.h
+++ b/indra/llui/llcallbackmap.h
@@ -30,11 +30,11 @@
* $/LicenseInfo$
*/
-#ifndef LL_CALLBACK_MAP_H
-#define LL_CALLBACK_MAP_H
+#ifndef LLCALLBACKMAP_H
+#define LLCALLBACKMAP_H
#include <map>
-#include "llstring.h"
+#include <string>
class LLCallbackMap
{
@@ -45,12 +45,19 @@ public:
typedef std::map<std::string, LLCallbackMap> map_t;
typedef map_t::iterator map_iter_t;
typedef map_t::const_iterator map_const_iter_t;
-
+
+ template <class T>
+ static void* buildPanel(void* data)
+ {
+ T* panel = new T();
+ return (void*)panel;
+ }
+
LLCallbackMap() : mCallback(NULL), mData(NULL) { }
- LLCallbackMap(callback_t callback, void* data) : mCallback(callback), mData(data) { }
+ LLCallbackMap(callback_t callback, void* data = NULL) : mCallback(callback), mData(data) { }
callback_t mCallback;
void* mData;
};
-#endif // LL_CALLBACK_MAP_H
+#endif // LLCALLBACKMAP_H
diff --git a/indra/llui/llcheckboxctrl.cpp b/indra/llui/llcheckboxctrl.cpp
index eda9467d87..455b17ffc7 100644
--- a/indra/llui/llcheckboxctrl.cpp
+++ b/indra/llui/llcheckboxctrl.cpp
@@ -31,7 +31,6 @@
*/
// The mutants are coming!
-
#include "linden_common.h"
#include "llcheckboxctrl.h"
@@ -49,101 +48,86 @@
const U32 MAX_STRING_LENGTH = 10;
-static LLRegisterWidget<LLCheckBoxCtrl> r("check_box");
-
-
-LLCheckBoxCtrl::LLCheckBoxCtrl(const std::string& name, const LLRect& rect,
- const std::string& label,
- const LLFontGL* font,
- void (*commit_callback)(LLUICtrl* ctrl, void* userdata),
- void* callback_user_data,
- BOOL initial_value,
- BOOL use_radio_style,
- const std::string& control_which)
-: LLUICtrl(name, rect, TRUE, commit_callback, callback_user_data, FOLLOWS_LEFT | FOLLOWS_TOP),
- mTextEnabledColor( LLUI::sColorsGroup->getColor( "LabelTextColor" ) ),
- mTextDisabledColor( LLUI::sColorsGroup->getColor( "LabelDisabledColor" ) ),
- mRadioStyle( use_radio_style ),
- mInitialValue( initial_value ),
- mSetValue( initial_value )
+static LLDefaultChildRegistry::Register<LLCheckBoxCtrl> r("check_box");
+
+LLCheckBoxCtrl::Params::Params()
+: text_enabled_color("text_enabled_color"),
+ text_disabled_color("text_disabled_color"),
+ initial_value("initial_value", false),
+ label_text("label_text"),
+ check_button("check_button"),
+ radio_style("radio_style")
+{}
+
+
+LLCheckBoxCtrl::LLCheckBoxCtrl(const LLCheckBoxCtrl::Params& p)
+: LLUICtrl(p),
+ mTextEnabledColor(p.text_enabled_color()),
+ mTextDisabledColor(p.text_disabled_color()),
+ mFont(p.font())
{
- if (font)
- {
- mFont = font;
- }
- else
- {
- mFont = LLFontGL::getFontSansSerifSmall();
- }
+ mViewModel->setValue(LLSD(p.initial_value));
+ mViewModel->resetDirty();
+ static LLUICachedControl<S32> llcheckboxctrl_spacing ("UICheckboxctrlSpacing", 0);
+ static LLUICachedControl<S32> llcheckboxctrl_hpad ("UICheckboxctrlHPad", 0);
+ static LLUICachedControl<S32> llcheckboxctrl_vpad ("UICheckboxctrlVPad", 0);
+ static LLUICachedControl<S32> llcheckboxctrl_btn_size ("UICheckboxctrlBtnSize", 0);
// must be big enough to hold all children
setUseBoundingRect(TRUE);
- mKeyboardFocusOnClick = TRUE;
-
// Label (add a little space to make sure text actually renders)
const S32 FUDGE = 10;
- S32 text_width = mFont->getWidth( label ) + FUDGE;
+ S32 text_width = mFont->getWidth( p.label ) + FUDGE;
S32 text_height = llround(mFont->getLineHeight());
LLRect label_rect;
label_rect.setOriginAndSize(
- LLCHECKBOXCTRL_HPAD + LLCHECKBOXCTRL_BTN_SIZE + LLCHECKBOXCTRL_SPACING,
- LLCHECKBOXCTRL_VPAD + 1, // padding to get better alignment
- text_width + LLCHECKBOXCTRL_HPAD,
+ llcheckboxctrl_hpad + llcheckboxctrl_btn_size + llcheckboxctrl_spacing,
+ llcheckboxctrl_vpad + 1, // padding to get better alignment
+ text_width + llcheckboxctrl_hpad,
text_height );
// *HACK Get rid of this with SL-55508...
// this allows blank check boxes and radio boxes for now
- std::string local_label = label;
+ std::string local_label = p.label;
if(local_label.empty())
{
local_label = " ";
}
- mLabel = new LLTextBox( std::string("CheckboxCtrl Label"), label_rect, local_label, mFont );
- mLabel->setFollowsLeft();
- mLabel->setFollowsBottom();
+ LLTextBox::Params tbparams = p.label_text;
+ tbparams.rect(label_rect);
+ tbparams.text(local_label);
+ if (p.font.isProvided())
+ {
+ tbparams.font(p.font);
+ }
+ mLabel = LLUICtrlFactory::create<LLTextBox> (tbparams);
+
addChild(mLabel);
// Button
// Note: button cover the label by extending all the way to the right.
LLRect btn_rect;
btn_rect.setOriginAndSize(
- LLCHECKBOXCTRL_HPAD,
- LLCHECKBOXCTRL_VPAD,
- LLCHECKBOXCTRL_BTN_SIZE + LLCHECKBOXCTRL_SPACING + text_width + LLCHECKBOXCTRL_HPAD,
- llmax( text_height, LLCHECKBOXCTRL_BTN_SIZE ) + LLCHECKBOXCTRL_VPAD);
+ llcheckboxctrl_hpad,
+ llcheckboxctrl_vpad,
+ llcheckboxctrl_btn_size + llcheckboxctrl_spacing + text_width + llcheckboxctrl_hpad,
+ llmax( text_height, llcheckboxctrl_btn_size() ) + llcheckboxctrl_vpad);
std::string active_true_id, active_false_id;
std::string inactive_true_id, inactive_false_id;
- if (mRadioStyle)
- {
- active_true_id = "UIImgRadioActiveSelectedUUID";
- active_false_id = "UIImgRadioActiveUUID";
- inactive_true_id = "UIImgRadioInactiveSelectedUUID";
- inactive_false_id = "UIImgRadioInactiveUUID";
- mButton = new LLButton(std::string("Radio control button"), btn_rect,
- active_false_id, active_true_id, control_which,
- &LLCheckBoxCtrl::onButtonPress, this, LLFontGL::getFontSansSerif() );
- mButton->setDisabledImages( inactive_false_id, inactive_true_id );
- mButton->setHoverGlowStrength(0.35f);
- }
- else
- {
- active_false_id = "UIImgCheckboxActiveUUID";
- active_true_id = "UIImgCheckboxActiveSelectedUUID";
- inactive_true_id = "UIImgCheckboxInactiveSelectedUUID";
- inactive_false_id = "UIImgCheckboxInactiveUUID";
- mButton = new LLButton(std::string("Checkbox control button"), btn_rect,
- active_false_id, active_true_id, control_which,
- &LLCheckBoxCtrl::onButtonPress, this, LLFontGL::getFontSansSerif() );
- mButton->setDisabledImages( inactive_false_id, inactive_true_id );
- mButton->setHoverGlowStrength(0.35f);
- }
- mButton->setIsToggle(TRUE);
- mButton->setToggleState( initial_value );
- mButton->setFollowsLeft();
- mButton->setFollowsBottom();
- mButton->setCommitOnReturn(FALSE);
+
+ LLButton::Params params = p.check_button;
+ params.rect(btn_rect);
+ //params.control_name(p.control_name);
+ params.click_callback.function(boost::bind(&LLCheckBoxCtrl::onButtonPress, this, _2));
+ params.commit_on_return(false);
+ // Checkboxes only allow boolean initial values, but buttons can
+ // take any LLSD.
+ params.initial_value(LLSD(p.initial_value));
+ params.follows.flags(FOLLOWS_LEFT | FOLLOWS_BOTTOM);
+
+ mButton = LLUICtrlFactory::create<LLButton>(params);
addChild(mButton);
}
@@ -154,24 +138,14 @@ LLCheckBoxCtrl::~LLCheckBoxCtrl()
// static
-void LLCheckBoxCtrl::onButtonPress( void *userdata )
+void LLCheckBoxCtrl::onButtonPress( const LLSD& data )
{
- LLCheckBoxCtrl* self = (LLCheckBoxCtrl*) userdata;
-
- if (self->mRadioStyle)
- {
- self->setValue(TRUE);
- }
-
- self->setControlValue(self->getValue());
- // HACK: because buttons don't normally commit
- self->onCommit();
+ //if (mRadioStyle)
+ //{
+ // setValue(TRUE);
+ //}
- if (self->mKeyboardFocusOnClick)
- {
- self->setFocus( TRUE );
- self->onFocusReceived();
- }
+ onCommit();
}
void LLCheckBoxCtrl::onCommit()
@@ -179,6 +153,7 @@ void LLCheckBoxCtrl::onCommit()
if( getEnabled() )
{
setTentative(FALSE);
+ setControlValue(getValue());
LLUICtrl::onCommit();
}
}
@@ -186,7 +161,15 @@ void LLCheckBoxCtrl::onCommit()
void LLCheckBoxCtrl::setEnabled(BOOL b)
{
LLView::setEnabled(b);
- mButton->setEnabled(b);
+
+ if (b)
+ {
+ mLabel->setColor( mTextEnabledColor.get() );
+ }
+ else
+ {
+ mLabel->setColor( mTextDisabledColor.get() );
+ }
}
void LLCheckBoxCtrl::clear()
@@ -197,43 +180,33 @@ void LLCheckBoxCtrl::clear()
void LLCheckBoxCtrl::reshape(S32 width, S32 height, BOOL called_from_parent)
{
//stretch or shrink bounding rectangle of label when rebuilding UI at new scale
+ static LLUICachedControl<S32> llcheckboxctrl_spacing ("UICheckboxctrlSpacing", 0);
+ static LLUICachedControl<S32> llcheckboxctrl_hpad ("UICheckboxctrlHPad", 0);
+ static LLUICachedControl<S32> llcheckboxctrl_vpad ("UICheckboxctrlVPad", 0);
+ static LLUICachedControl<S32> llcheckboxctrl_btn_size ("UICheckboxctrlBtnSize", 0);
+
const S32 FUDGE = 10;
S32 text_width = mFont->getWidth( mLabel->getText() ) + FUDGE;
S32 text_height = llround(mFont->getLineHeight());
LLRect label_rect;
label_rect.setOriginAndSize(
- LLCHECKBOXCTRL_HPAD + LLCHECKBOXCTRL_BTN_SIZE + LLCHECKBOXCTRL_SPACING,
- LLCHECKBOXCTRL_VPAD,
+ llcheckboxctrl_hpad + llcheckboxctrl_btn_size + llcheckboxctrl_spacing,
+ llcheckboxctrl_vpad,
text_width,
text_height );
mLabel->setRect(label_rect);
LLRect btn_rect;
btn_rect.setOriginAndSize(
- LLCHECKBOXCTRL_HPAD,
- LLCHECKBOXCTRL_VPAD,
- LLCHECKBOXCTRL_BTN_SIZE + LLCHECKBOXCTRL_SPACING + text_width,
- llmax( text_height, LLCHECKBOXCTRL_BTN_SIZE ) );
+ llcheckboxctrl_hpad,
+ llcheckboxctrl_vpad,
+ llcheckboxctrl_btn_size + llcheckboxctrl_spacing + text_width,
+ llmax( text_height, llcheckboxctrl_btn_size() ) );
mButton->setRect( btn_rect );
LLUICtrl::reshape(width, height, called_from_parent);
}
-void LLCheckBoxCtrl::draw()
-{
- if (getEnabled())
- {
- mLabel->setColor( mTextEnabledColor );
- }
- else
- {
- mLabel->setColor( mTextDisabledColor );
- }
-
- // Draw children
- LLUICtrl::draw();
-}
-
//virtual
void LLCheckBoxCtrl::setValue(const LLSD& value )
{
@@ -246,6 +219,18 @@ LLSD LLCheckBoxCtrl::getValue() const
return mButton->getValue();
}
+//virtual
+void LLCheckBoxCtrl::setTentative(BOOL b)
+{
+ mButton->setTentative(b);
+}
+
+//virtual
+BOOL LLCheckBoxCtrl::getTentative() const
+{
+ return mButton->getTentative();
+}
+
void LLCheckBoxCtrl::setLabel( const LLStringExplicit& label )
{
mLabel->setText( label );
@@ -264,12 +249,6 @@ BOOL LLCheckBoxCtrl::setLabelArg( const std::string& key, const LLStringExplicit
return res;
}
-//virtual
-std::string LLCheckBoxCtrl::getControlName() const
-{
- return mButton->getControlName();
-}
-
// virtual
void LLCheckBoxCtrl::setControlName(const std::string& control_name, LLView* context)
{
@@ -282,7 +261,7 @@ BOOL LLCheckBoxCtrl::isDirty() const
{
if ( mButton )
{
- return (mSetValue != mButton->getToggleState());
+ return mButton->isDirty();
}
return FALSE; // Shouldn't get here
}
@@ -293,78 +272,6 @@ void LLCheckBoxCtrl::resetDirty()
{
if ( mButton )
{
- mSetValue = mButton->getToggleState();
- }
-}
-
-
-
-// virtual
-LLXMLNodePtr LLCheckBoxCtrl::getXML(bool save_children) const
-{
- LLXMLNodePtr node = LLUICtrl::getXML();
-
- node->createChild("label", TRUE)->setStringValue(mLabel->getText());
-
- std::string control_name = mButton->getControlName();
-
- node->createChild("initial_value", TRUE)->setBoolValue(mInitialValue);
-
- node->createChild("font", TRUE)->setStringValue(LLFontGL::nameFromFont(mFont));
-
- node->createChild("radio_style", TRUE)->setBoolValue(mRadioStyle);
-
- return node;
-}
-
-// static
-LLView* LLCheckBoxCtrl::fromXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFactory *factory)
-{
- std::string name("checkbox");
- node->getAttributeString("name", name);
-
- std::string label("");
- node->getAttributeString("label", label);
-
- LLFontGL* font = LLView::selectFont(node);
-
- BOOL radio_style = FALSE;
- node->getAttributeBOOL("radio_style", radio_style);
-
- LLUICtrlCallback callback = NULL;
-
- if (label.empty())
- {
- label.assign(node->getTextContents());
+ mButton->resetDirty();
}
-
- LLRect rect;
- createRect(node, rect, parent, LLRect());
-
- LLCheckBoxCtrl* checkbox = new LLCheckboxCtrl(name,
- rect,
- label,
- font,
- callback,
- NULL,
- FALSE,
- radio_style); // if true, draw radio button style icons
-
- BOOL initial_value = checkbox->getValue().asBoolean();
- node->getAttributeBOOL("initial_value", initial_value);
-
- LLColor4 color;
- color = LLUI::sColorsGroup->getColor( "LabelTextColor" );
- LLUICtrlFactory::getAttributeColor(node,"text_enabled_color", color);
- checkbox->setEnabledColor(color);
-
- color = LLUI::sColorsGroup->getColor( "LabelDisabledColor" );
- LLUICtrlFactory::getAttributeColor(node,"text_disabled_color", color);
- checkbox->setDisabledColor(color);
-
- checkbox->setValue(initial_value);
-
- checkbox->initFromXML(node, parent);
-
- return checkbox;
}
diff --git a/indra/llui/llcheckboxctrl.h b/indra/llui/llcheckboxctrl.h
index ff867f5193..2f8e8fdd23 100644
--- a/indra/llui/llcheckboxctrl.h
+++ b/indra/llui/llcheckboxctrl.h
@@ -33,24 +33,14 @@
#ifndef LL_LLCHECKBOXCTRL_H
#define LL_LLCHECKBOXCTRL_H
-
-#include "stdtypes.h"
#include "lluictrl.h"
#include "llbutton.h"
+#include "lltextbox.h"
#include "v4color.h"
-#include "llrect.h"
//
// Constants
//
-const S32 LLCHECKBOXCTRL_BTN_SIZE = 13;
-const S32 LLCHECKBOXCTRL_VPAD = 2;
-const S32 LLCHECKBOXCTRL_HPAD = 2;
-const S32 LLCHECKBOXCTRL_SPACING = 5;
-const S32 LLCHECKBOXCTRL_HEIGHT = 16;
-
-// Deprecated, don't use.
-#define CHECKBOXCTRL_HEIGHT LLCHECKBOXCTRL_HEIGHT
const BOOL RADIO_STYLE = TRUE;
const BOOL CHECK_STYLE = FALSE;
@@ -59,30 +49,38 @@ const BOOL CHECK_STYLE = FALSE;
// Classes
//
class LLFontGL;
-class LLTextBox;
class LLViewBorder;
class LLCheckBoxCtrl
: public LLUICtrl
{
public:
- LLCheckBoxCtrl(const std::string& name, const LLRect& rect, const std::string& label,
- const LLFontGL* font = NULL,
- void (*commit_callback)(LLUICtrl*, void*) = NULL,
- void* callback_userdata = NULL,
- BOOL initial_value = FALSE,
- BOOL use_radio_style = FALSE, // if true, draw radio button style icons
- const std::string& control_which = LLStringUtil::null);
+ struct Params
+ : public LLInitParam::Block<Params, LLUICtrl::Params>
+ {
+ Optional<LLUIColor> text_enabled_color;
+ Optional<LLUIColor> text_disabled_color;
+ Optional<bool> initial_value; // override LLUICtrl initial_value
+
+ Optional<LLTextBox::Params> label_text;
+ Optional<LLButton::Params> check_button;
+
+ Ignored radio_style;
+
+ Params();
+ };
+
virtual ~LLCheckBoxCtrl();
- // LLView interface
+protected:
+ LLCheckBoxCtrl(const Params&);
+ friend class LLUICtrlFactory;
- virtual LLXMLNodePtr getXML(bool save_children = true) const;
- static LLView* fromXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFactory *factory);
+public:
+ // LLView interface
virtual void setEnabled( BOOL b );
- virtual void draw();
virtual void reshape(S32 width, S32 height, BOOL called_from_parent = TRUE);
// LLUICtrl interface
@@ -91,8 +89,8 @@ public:
BOOL get() { return (BOOL)getValue().asBoolean(); }
void set(BOOL value) { setValue(value); }
- virtual void setTentative(BOOL b) { mButton->setTentative(b); }
- virtual BOOL getTentative() const { return mButton->getTentative(); }
+ virtual void setTentative(BOOL b);
+ virtual BOOL getTentative() const;
virtual BOOL setLabelArg( const std::string& key, const LLStringExplicit& text );
@@ -108,10 +106,11 @@ public:
void setLabel( const LLStringExplicit& label );
std::string getLabel() const;
+ void setFont( const LLFontGL* font ) { mFont = font; }
+
virtual void setControlName(const std::string& control_name, LLView* context);
- virtual std::string getControlName() const;
- static void onButtonPress(void *userdata);
+ void onButtonPress(const LLSD& data);
virtual BOOL isDirty() const; // Returns TRUE if the user has modified this control.
virtual void resetDirty(); // Clear dirty state
@@ -121,19 +120,10 @@ protected:
LLButton* mButton;
LLTextBox* mLabel;
const LLFontGL* mFont;
- LLColor4 mTextEnabledColor;
- LLColor4 mTextDisabledColor;
- BOOL mRadioStyle;
- BOOL mInitialValue; // Value set in constructor
- BOOL mSetValue; // Value set programmatically
- BOOL mKeyboardFocusOnClick;
- LLViewBorder* mBorder;
-};
-
-// HACK: fix old capitalization problem
-//typedef LLCheckBoxCtrl LLCheckboxCtrl;
-#define LLCheckboxCtrl LLCheckBoxCtrl
+ LLUIColor mTextEnabledColor;
+ LLUIColor mTextDisabledColor;
+};
#endif // LL_LLCHECKBOXCTRL_H
diff --git a/indra/llui/llclipboard.cpp b/indra/llui/llclipboard.cpp
index 2cb8197a67..cbd4cb380f 100644
--- a/indra/llui/llclipboard.cpp
+++ b/indra/llui/llclipboard.cpp
@@ -61,6 +61,12 @@ void LLClipboard::copyFromSubstring(const LLWString &src, S32 pos, S32 len, cons
LLView::getWindow()->copyTextToClipboard( mString );
}
+void LLClipboard::copyFromString(const LLWString &src, const LLUUID& source_id )
+{
+ mSourceID = source_id;
+ mString = src;
+ LLView::getWindow()->copyTextToClipboard( mString );
+}
const LLWString& LLClipboard::getPasteWString( LLUUID* source_id )
{
diff --git a/indra/llui/llclipboard.h b/indra/llui/llclipboard.h
index 034a7a6aeb..d7ffeb33e0 100644
--- a/indra/llui/llclipboard.h
+++ b/indra/llui/llclipboard.h
@@ -50,6 +50,7 @@ public:
(i.e. X11/Linux). */
void copyFromSubstring(const LLWString &copy_from, S32 pos, S32 len, const LLUUID& source_id = LLUUID::null );
+ void copyFromString(const LLWString &copy_from, const LLUUID& source_id = LLUUID::null );
BOOL canPasteString() const;
const LLWString& getPasteWString(LLUUID* source_id = NULL);
diff --git a/indra/llui/llcombobox.cpp b/indra/llui/llcombobox.cpp
index 28a05c13f5..ac56d15d1b 100644
--- a/indra/llui/llcombobox.cpp
+++ b/indra/llui/llcombobox.cpp
@@ -48,173 +48,140 @@
#include "llwindow.h"
#include "llfloater.h"
#include "llscrollbar.h"
+#include "llscrolllistcell.h"
+#include "llscrolllistitem.h"
#include "llcontrol.h"
#include "llfocusmgr.h"
#include "lllineeditor.h"
#include "v2math.h"
+#include "lluictrlfactory.h"
// Globals
S32 LLCOMBOBOX_HEIGHT = 0;
S32 LLCOMBOBOX_WIDTH = 0;
S32 MAX_COMBO_WIDTH = 500;
-static LLRegisterWidget<LLComboBox> r1("combo_box");
+static LLDefaultChildRegistry::Register<LLComboBox> register_combo_box("combo_box");
-LLComboBox::LLComboBox( const std::string& name, const LLRect &rect, const std::string& label,
- void (*commit_callback)(LLUICtrl*,void*),
- void *callback_userdata
- )
-: LLUICtrl(name, rect, TRUE, commit_callback, callback_userdata,
- FOLLOWS_LEFT | FOLLOWS_TOP),
- mTextEntry(NULL),
- mArrowImage(NULL),
- mAllowTextEntry(FALSE),
- mMaxChars(20),
- mTextEntryTentative(TRUE),
- mListPosition(BELOW),
- mPrearrangeCallback( NULL ),
- mTextEntryCallback( NULL ),
- mLabel(label)
+void LLComboBox::PreferredPositionValues::declareValues()
{
- // Always use text box
- // Text label button
- mButton = new LLButton(mLabel,
- LLRect(),
- LLStringUtil::null,
- NULL, this);
- mButton->setImageUnselected(std::string("square_btn_32x128.tga"));
- mButton->setImageSelected(std::string("square_btn_selected_32x128.tga"));
- mButton->setImageDisabled(std::string("square_btn_32x128.tga"));
- mButton->setImageDisabledSelected(std::string("square_btn_selected_32x128.tga"));
- mButton->setScaleImage(TRUE);
-
- mButton->setMouseDownCallback(onButtonDown);
- mButton->setFont(LLFontGL::getFontSansSerifSmall());
- mButton->setFollows(FOLLOWS_LEFT | FOLLOWS_BOTTOM | FOLLOWS_RIGHT);
- mButton->setHAlign( LLFontGL::LEFT );
- mButton->setRightHPad(2);
- addChild(mButton);
-
- // disallow multiple selection
- mList = new LLScrollListCtrl(std::string("ComboBox"), LLRect(),
- &LLComboBox::onItemSelected, this, FALSE);
- mList->setVisible(FALSE);
- mList->setBgWriteableColor( LLColor4(1,1,1,1) );
- mList->setCommitOnKeyboardMovement(FALSE);
- addChild(mList);
-
- mArrowImage = LLUI::sImageProvider->getUIImage("combobox_arrow.tga");
- mButton->setImageOverlay("combobox_arrow.tga", LLFontGL::RIGHT);
-
- updateLayout();
+ declare("above", ABOVE);
+ declare("below", BELOW);
}
-
-LLComboBox::~LLComboBox()
+LLComboBox::ItemParams::ItemParams()
+: label("label")
{
- // children automatically deleted, including mMenu, mButton
}
-// virtual
-LLXMLNodePtr LLComboBox::getXML(bool save_children) const
-{
- LLXMLNodePtr node = LLUICtrl::getXML();
- // Attributes
+LLComboBox::Params::Params()
+: allow_text_entry("allow_text_entry", false),
+ show_text_as_tentative("show_text_as_tentative", true),
+ max_chars("max_chars", 20),
+ list_position("list_position", BELOW),
+ items("item"),
+ combo_button("combo_button"),
+ combo_list("combo_list"),
+ combo_editor("combo_editor"),
+ drop_down_button("drop_down_button")
+{
+ addSynonym(items, "combo_item");
+}
- node->createChild("allow_text_entry", TRUE)->setBoolValue(mAllowTextEntry);
- node->createChild("max_chars", TRUE)->setIntValue(mMaxChars);
+LLComboBox::LLComboBox(const LLComboBox::Params& p)
+: LLUICtrl(p),
+ mTextEntry(NULL),
+ mTextEntryTentative(p.show_text_as_tentative),
+ mHasAutocompletedText(false),
+ mAllowTextEntry(p.allow_text_entry),
+ mMaxChars(p.max_chars),
+ mPrearrangeCallback(p.prearrange_callback()),
+ mTextEntryCallback(p.text_entry_callback()),
+ mSelectionCallback(p.selection_callback()),
+ mListPosition(p.list_position),
+ mLastSelectedIndex(-1)
+{
+ // Text label button
- // Contents
+ LLButton::Params button_params = (mAllowTextEntry ? p.combo_button : p.drop_down_button);
+ button_params.mouse_down_callback.function(boost::bind(&LLComboBox::onButtonDown, this));
+ button_params.follows.flags(FOLLOWS_LEFT|FOLLOWS_BOTTOM|FOLLOWS_RIGHT);
+ button_params.rect(p.rect);
- std::vector<LLScrollListItem*> data_list = mList->getAllData();
- std::vector<LLScrollListItem*>::iterator data_itor;
- for (data_itor = data_list.begin(); data_itor != data_list.end(); ++data_itor)
+ if(mAllowTextEntry)
{
- LLScrollListItem* item = *data_itor;
- LLScrollListCell* cell = item->getColumn(0);
- if (cell)
- {
- LLXMLNodePtr item_node = node->createChild("combo_item", FALSE);
- LLSD value = item->getValue();
- item_node->createChild("value", TRUE)->setStringValue(value.asString());
- item_node->createChild("enabled", TRUE)->setBoolValue(item->getEnabled());
- item_node->setStringValue(cell->getValue().asString());
- }
+ button_params.pad_right(2);
}
- return node;
-}
+ mArrowImage = button_params.image_unselected;
-// static
-LLView* LLComboBox::fromXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFactory *factory)
-{
- std::string name("combo_box");
- node->getAttributeString("name", name);
+ mButton = LLUICtrlFactory::create<LLButton>(button_params);
- std::string label("");
- node->getAttributeString("label", label);
+
+ if(mAllowTextEntry)
+ {
+ //redo to compensate for button hack that leaves space for a character
+ //unless it is a "minimal combobox"(drop down)
+ mButton->setRightHPad(2);
+ }
+ addChild(mButton);
- LLRect rect;
- createRect(node, rect, parent, LLRect());
+ LLScrollListCtrl::Params params = p.combo_list;
+ params.name("ComboBox");
+ params.commit_callback.function(boost::bind(&LLComboBox::onItemSelected, this, _2));
+ params.visible(false);
+ params.commit_on_keyboard_movement(false);
- BOOL allow_text_entry = FALSE;
- node->getAttributeBOOL("allow_text_entry", allow_text_entry);
+ mList = LLUICtrlFactory::create<LLScrollListCtrl>(params);
+ addChild(mList);
- S32 max_chars = 20;
- node->getAttributeS32("max_chars", max_chars);
+ for (LLInitParam::ParamIterator<ItemParams>::const_iterator it = p.items().begin();
+ it != p.items().end();
+ ++it)
+ {
+ LLScrollListItem::Params item_params = *it;
+ if (it->label.isProvided())
+ {
+ item_params.columns.add().value(it->label());
+ }
- LLUICtrlCallback callback = NULL;
+ mList->addRow(item_params);
+ }
- LLComboBox* combo_box = new LLComboBox(name,
- rect,
- label,
- callback,
- NULL);
- combo_box->setAllowTextEntry(allow_text_entry, max_chars);
+ createLineEditor(p);
- combo_box->initFromXML(node, parent);
+ setTopLostCallback(boost::bind(&LLComboBox::hideList, this));
+}
- const std::string& contents = node->getValue();
+void LLComboBox::initFromParams(const LLComboBox::Params& p)
+{
+ LLUICtrl::initFromParams(p);
- if (contents.find_first_not_of(" \n\t") != contents.npos)
- {
- llerrs << "Legacy combo box item format used! Please convert to <combo_item> tags!" << llendl;
- }
- else
+ if (!acceptsTextInput() && mLabel.empty())
{
- LLXMLNodePtr child;
- for (child = node->getFirstChild(); child.notNull(); child = child->getNextSibling())
- {
- if (child->hasName("combo_item"))
- {
- std::string label = child->getTextContents();
-
- std::string value = label;
- child->getAttributeString("value", value);
-
- combo_box->add(label, LLSD(value) );
- }
- }
+ selectFirstItem();
}
+}
- // if providing user text entry or descriptive label
- // don't select an item under the hood
- if (!combo_box->acceptsTextInput() && combo_box->mLabel.empty())
+// virtual
+BOOL LLComboBox::postBuild()
+{
+ if (mControlVariable)
{
- combo_box->selectFirstItem();
+ setValue(mControlVariable->getValue()); // selects the appropriate item
}
-
- return combo_box;
+ return TRUE;
}
-void LLComboBox::setEnabled(BOOL enabled)
+
+LLComboBox::~LLComboBox()
{
- LLView::setEnabled(enabled);
- mButton->setEnabled(enabled);
+ // children automatically deleted, including mMenu, mButton
}
+
void LLComboBox::clear()
{
if (mTextEntry)
@@ -223,9 +190,8 @@ void LLComboBox::clear()
}
mButton->setLabelSelected(LLStringUtil::null);
mButton->setLabelUnselected(LLStringUtil::null);
- mButton->setDisabledLabel(LLStringUtil::null);
- mButton->setDisabledSelectedLabel(LLStringUtil::null);
mList->deselectAllItems();
+ mLastSelectedIndex = -1;
}
void LLComboBox::onCommit()
@@ -237,6 +203,7 @@ void LLComboBox::onCommit()
mTextEntry->setValue(getSimple());
mTextEntry->setTentative(FALSE);
}
+ setControlValue(getValue());
LLUICtrl::onCommit();
}
@@ -330,6 +297,7 @@ BOOL LLComboBox::setSimple(const LLStringExplicit& name)
if (found)
{
setLabel(name);
+ mLastSelectedIndex = mList->getFirstSelectedIndex();
}
return found;
@@ -346,6 +314,7 @@ void LLComboBox::setValue(const LLSD& value)
{
setLabel( mList->getSelectedItemLabel() );
}
+ mLastSelectedIndex = mList->getFirstSelectedIndex();
}
}
@@ -393,6 +362,7 @@ void LLComboBox::setLabel(const LLStringExplicit& name)
if (mList->selectItemByLabel(name, FALSE))
{
mTextEntry->setTentative(FALSE);
+ mLastSelectedIndex = mList->getFirstSelectedIndex();
}
else
{
@@ -402,10 +372,7 @@ void LLComboBox::setLabel(const LLStringExplicit& name)
if (!mAllowTextEntry)
{
- mButton->setLabelUnselected(name);
- mButton->setLabelSelected(name);
- mButton->setDisabledLabel(name);
- mButton->setDisabledSelectedLabel(name);
+ mButton->setLabel(name);
}
}
@@ -421,6 +388,7 @@ BOOL LLComboBox::remove(const std::string& name)
{
mList->deleteSingleItem(mList->getItemIndex(item));
}
+ mLastSelectedIndex = mList->getFirstSelectedIndex();
}
return found;
@@ -431,6 +399,7 @@ BOOL LLComboBox::remove(S32 index)
if (index < mList->getItemCount())
{
mList->deleteSingleItem(index);
+ setLabel(mList->getSelectedItemLabel());
return TRUE;
}
return FALSE;
@@ -448,41 +417,31 @@ void LLComboBox::onFocusLost()
LLUICtrl::onFocusLost();
}
-void LLComboBox::onLostTop()
-{
- hideList();
-}
-
-
void LLComboBox::setButtonVisible(BOOL visible)
{
+ static LLUICachedControl<S32> drop_shadow_button ("DropShadowButton", 0);
+
mButton->setVisible(visible);
if (mTextEntry)
{
LLRect text_entry_rect(0, getRect().getHeight(), getRect().getWidth(), 0);
if (visible)
{
- text_entry_rect.mRight -= llmax(8,mArrowImage->getWidth()) + 2 * LLUI::sConfigGroup->getS32("DropShadowButton");
+ S32 arrow_width = mArrowImage ? mArrowImage->getWidth() : 0;
+ text_entry_rect.mRight -= llmax(8,arrow_width) + 2 * drop_shadow_button;
}
//mTextEntry->setRect(text_entry_rect);
mTextEntry->reshape(text_entry_rect.getWidth(), text_entry_rect.getHeight(), TRUE);
}
}
-void LLComboBox::draw()
-{
- mButton->setEnabled(getEnabled() /*&& !mList->isEmpty()*/);
-
- // Draw children normally
- LLUICtrl::draw();
-}
-
BOOL LLComboBox::setCurrentByIndex( S32 index )
{
BOOL found = mList->selectNthItem( index );
if (found)
{
setLabel(mList->getSelectedItemLabel());
+ mLastSelectedIndex = index;
}
return found;
}
@@ -498,54 +457,48 @@ S32 LLComboBox::getCurrentIndex() const
}
-void LLComboBox::updateLayout()
+void LLComboBox::createLineEditor(const LLComboBox::Params& p)
{
+ static LLUICachedControl<S32> drop_shadow_button ("DropShadowButton", 0);
LLRect rect = getLocalRect();
if (mAllowTextEntry)
{
- S32 shadow_size = LLUI::sConfigGroup->getS32("DropShadowButton");
- mButton->setRect(LLRect( getRect().getWidth() - llmax(8,mArrowImage->getWidth()) - 2 * shadow_size,
+ S32 arrow_width = mArrowImage ? mArrowImage->getWidth() : 0;
+ S32 shadow_size = drop_shadow_button;
+ mButton->setRect(LLRect( getRect().getWidth() - llmax(8,arrow_width) - 2 * shadow_size,
rect.mTop, rect.mRight, rect.mBottom));
mButton->setTabStop(FALSE);
+ mButton->setHAlign(LLFontGL::HCENTER);
- if (!mTextEntry)
- {
- LLRect text_entry_rect(0, getRect().getHeight(), getRect().getWidth(), 0);
- text_entry_rect.mRight -= llmax(8,mArrowImage->getWidth()) + 2 * LLUI::sConfigGroup->getS32("DropShadowButton");
- // clear label on button
- std::string cur_label = mButton->getLabelSelected();
- mTextEntry = new LLLineEditor(std::string("combo_text_entry"),
- text_entry_rect,
- LLStringUtil::null,
- LLFontGL::getFontSansSerifSmall(),
- mMaxChars,
- onTextCommit,
- onTextEntry,
- NULL,
- this);
- mTextEntry->setSelectAllonFocusReceived(TRUE);
- mTextEntry->setHandleEditKeysDirectly(TRUE);
- mTextEntry->setCommitOnFocusLost(FALSE);
- mTextEntry->setText(cur_label);
- mTextEntry->setIgnoreTab(TRUE);
- mTextEntry->setFollowsAll();
- addChild(mTextEntry);
- }
- else
- {
- mTextEntry->setVisible(TRUE);
- mTextEntry->setMaxTextLength(mMaxChars);
- }
+ LLRect text_entry_rect(0, getRect().getHeight(), getRect().getWidth(), 0);
+ text_entry_rect.mRight -= llmax(8,arrow_width) + 2 * drop_shadow_button;
+ // clear label on button
+ std::string cur_label = mButton->getLabelSelected();
+ LLLineEditor::Params params = p.combo_editor;
+ params.rect(text_entry_rect);
+ params.default_text(LLStringUtil::null);
+ params.max_length_bytes(mMaxChars);
+ params.commit_callback.function(boost::bind(&LLComboBox::onTextCommit, this, _2));
+ params.keystroke_callback(boost::bind(&LLComboBox::onTextEntry, this, _1));
+ params.focus_lost_callback(NULL);
+ params.handle_edit_keys_directly(true);
+ params.commit_on_focus_lost(false);
+ params.follows.flags(FOLLOWS_ALL);
+ mTextEntry = LLUICtrlFactory::create<LLLineEditor> (params);
+ mTextEntry->setText(cur_label);
+ mTextEntry->setIgnoreTab(TRUE);
+ addChild(mTextEntry);
// clear label on button
setLabel(LLStringUtil::null);
mButton->setFollows(FOLLOWS_BOTTOM | FOLLOWS_TOP | FOLLOWS_RIGHT);
}
- else if (!mAllowTextEntry)
+ else
{
mButton->setRect(rect);
mButton->setTabStop(TRUE);
+ mButton->setHAlign(LLFontGL::LEFT);
if (mTextEntry)
{
@@ -664,91 +617,91 @@ void LLComboBox::showList()
void LLComboBox::hideList()
{
- //*HACK: store the original value explicitly somewhere, not just in label
- std::string orig_selection = mAllowTextEntry ? mTextEntry->getText() : mButton->getLabelSelected();
-
- // assert selection in list
- mList->selectItemByLabel(orig_selection, FALSE);
+ if (mList->getVisible())
+ {
+ // assert selection in list
+ mList->selectNthItem(mLastSelectedIndex);
- mButton->setToggleState(FALSE);
- mList->setVisible(FALSE);
- mList->highlightNthItem(-1);
+ mButton->setToggleState(FALSE);
+ mList->setVisible(FALSE);
+ mList->mouseOverHighlightNthItem(-1);
- setUseBoundingRect(FALSE);
- if( gFocusMgr.getTopCtrl() == this )
- {
- gFocusMgr.setTopCtrl(NULL);
+ setUseBoundingRect(FALSE);
+ if( gFocusMgr.getTopCtrl() == this )
+ {
+ gFocusMgr.setTopCtrl(NULL);
+ }
}
}
-//------------------------------------------------------------------
-// static functions
-//------------------------------------------------------------------
-
-// static
-void LLComboBox::onButtonDown(void *userdata)
+void LLComboBox::onButtonDown()
{
- LLComboBox *self = (LLComboBox *)userdata;
-
- if (!self->mList->getVisible())
+ if (!mList->getVisible())
{
- LLScrollListItem* last_selected_item = self->mList->getLastSelectedItem();
- if (last_selected_item)
- {
- // highlight the original selection before potentially selecting a new item
- self->mList->highlightNthItem(self->mList->getItemIndex(last_selected_item));
- }
+ // this might change selection, so do it first
+ prearrangeList();
- if( self->mPrearrangeCallback )
+ // highlight the last selected item from the original selection before potentially selecting a new item
+ // as visual cue to original value of combo box
+ LLScrollListItem* last_selected_item = mList->getLastSelectedItem();
+ if (last_selected_item)
{
- self->mPrearrangeCallback( self, self->mCallbackUserData );
+ mList->mouseOverHighlightNthItem(mList->getItemIndex(last_selected_item));
}
- if (self->mList->getItemCount() != 0)
+ if (mList->getItemCount() != 0)
{
- self->showList();
+ showList();
}
- self->setFocus( TRUE );
+ setFocus( TRUE );
// pass mouse capture on to list if button is depressed
- if (self->mButton->hasMouseCapture())
+ if (mButton->hasMouseCapture())
{
- gFocusMgr.setMouseCapture(self->mList);
+ gFocusMgr.setMouseCapture(mList);
}
}
else
{
- self->hideList();
+ hideList();
}
}
-// static
-void LLComboBox::onItemSelected(LLUICtrl* item, void *userdata)
-{
- // Note: item is the LLScrollListCtrl
- LLComboBox *self = (LLComboBox *) userdata;
- const std::string name = self->mList->getSelectedItemLabel();
+//------------------------------------------------------------------
+// static functions
+//------------------------------------------------------------------
+
+void LLComboBox::onItemSelected(const LLSD& data)
+{
+ const std::string name = mList->getSelectedItemLabel();
- S32 cur_id = self->getCurrentIndex();
+ S32 cur_id = getCurrentIndex();
+ mLastSelectedIndex = cur_id;
if (cur_id != -1)
{
- self->setLabel(name);
+ setLabel(name);
- if (self->mAllowTextEntry)
+ if (mAllowTextEntry)
{
- gFocusMgr.setKeyboardFocus(self->mTextEntry);
- self->mTextEntry->selectAll();
+ gFocusMgr.setKeyboardFocus(mTextEntry);
+ mTextEntry->selectAll();
}
}
// hiding the list reasserts the old value stored in the text editor/dropdown button
- self->hideList();
+ hideList();
// commit does the reverse, asserting the value in the list
- self->onCommit();
+ onCommit();
+
+ // call the callback if it exists
+ if(mSelectionCallback)
+ {
+ mSelectionCallback(this, data);
+ }
}
BOOL LLComboBox::handleToolTip(S32 x, S32 y, std::string& msg, LLRect* sticky_rect_screen)
@@ -778,12 +731,7 @@ BOOL LLComboBox::handleToolTip(S32 x, S32 y, std::string& msg, LLRect* sticky_re
msg = tool_tip;
// Convert rect local to screen coordinates
- localPointToScreen(
- 0, 0,
- &(sticky_rect_screen->mLeft), &(sticky_rect_screen->mBottom) );
- localPointToScreen(
- getRect().getWidth(), getRect().getHeight(),
- &(sticky_rect_screen->mRight), &(sticky_rect_screen->mTop) );
+ *sticky_rect_screen = calcScreenRect();
}
return TRUE;
}
@@ -804,7 +752,7 @@ BOOL LLComboBox::handleKeyHere(KEY key, MASK mask)
if (last_selected_item)
{
// highlight the original selection before potentially selecting a new item
- mList->highlightNthItem(mList->getItemIndex(last_selected_item));
+ mList->mouseOverHighlightNthItem(mList->getItemIndex(last_selected_item));
}
result = mList->handleKeyHere(key, mask);
@@ -838,7 +786,7 @@ BOOL LLComboBox::handleUnicodeCharHere(llwchar uni_char)
if (last_selected_item)
{
// highlight the original selection before potentially selecting a new item
- mList->highlightNthItem(mList->getItemIndex(last_selected_item));
+ mList->mouseOverHighlightNthItem(mList->getItemIndex(last_selected_item));
}
result = mList->handleUnicodeCharHere(uni_char);
if (mList->getLastSelectedItem() != last_selected_item)
@@ -850,46 +798,37 @@ BOOL LLComboBox::handleUnicodeCharHere(llwchar uni_char)
return result;
}
-void LLComboBox::setAllowTextEntry(BOOL allow, S32 max_chars, BOOL set_tentative)
-{
- mAllowTextEntry = allow;
- mTextEntryTentative = set_tentative;
- mMaxChars = max_chars;
-
- updateLayout();
-}
-
void LLComboBox::setTextEntry(const LLStringExplicit& text)
{
if (mTextEntry)
{
mTextEntry->setText(text);
+ mHasAutocompletedText = FALSE;
updateSelection();
}
}
-//static
-void LLComboBox::onTextEntry(LLLineEditor* line_editor, void* user_data)
+void LLComboBox::onTextEntry(LLLineEditor* line_editor)
{
- LLComboBox* self = (LLComboBox*)user_data;
-
- if (self->mTextEntryCallback)
+ if (mTextEntryCallback != NULL)
{
- (*self->mTextEntryCallback)(line_editor, self->mCallbackUserData);
+ (mTextEntryCallback)(line_editor, LLSD());
}
KEY key = gKeyboard->currentKey();
if (key == KEY_BACKSPACE ||
key == KEY_DELETE)
{
- if (self->mList->selectItemByLabel(line_editor->getText(), FALSE))
+ if (mList->selectItemByLabel(line_editor->getText(), FALSE))
{
line_editor->setTentative(FALSE);
+ mLastSelectedIndex = mList->getFirstSelectedIndex();
}
else
{
- line_editor->setTentative(self->mTextEntryTentative);
- self->mList->deselectAllItems();
+ line_editor->setTentative(mTextEntryTentative);
+ mList->deselectAllItems();
+ mLastSelectedIndex = -1;
}
return;
}
@@ -902,17 +841,14 @@ void LLComboBox::onTextEntry(LLLineEditor* line_editor, void* user_data)
if (key == KEY_DOWN)
{
- self->setCurrentByIndex(llmin(self->getItemCount() - 1, self->getCurrentIndex() + 1));
- if (!self->mList->getVisible())
+ setCurrentByIndex(llmin(getItemCount() - 1, getCurrentIndex() + 1));
+ if (!mList->getVisible())
{
- if( self->mPrearrangeCallback )
- {
- self->mPrearrangeCallback( self, self->mCallbackUserData );
- }
+ prearrangeList();
- if (self->mList->getItemCount() != 0)
+ if (mList->getItemCount() != 0)
{
- self->showList();
+ showList();
}
}
line_editor->selectAll();
@@ -920,17 +856,14 @@ void LLComboBox::onTextEntry(LLLineEditor* line_editor, void* user_data)
}
else if (key == KEY_UP)
{
- self->setCurrentByIndex(llmax(0, self->getCurrentIndex() - 1));
- if (!self->mList->getVisible())
+ setCurrentByIndex(llmax(0, getCurrentIndex() - 1));
+ if (!mList->getVisible())
{
- if( self->mPrearrangeCallback )
- {
- self->mPrearrangeCallback( self, self->mCallbackUserData );
- }
+ prearrangeList();
- if (self->mList->getItemCount() != 0)
+ if (mList->getItemCount() != 0)
{
- self->showList();
+ showList();
}
}
line_editor->selectAll();
@@ -939,7 +872,7 @@ void LLComboBox::onTextEntry(LLLineEditor* line_editor, void* user_data)
else
{
// RN: presumably text entry
- self->updateSelection();
+ updateSelection();
}
}
@@ -948,7 +881,7 @@ void LLComboBox::updateSelection()
LLWString left_wstring = mTextEntry->getWText().substr(0, mTextEntry->getCursor());
// user-entered portion of string, based on assumption that any selected
// text was a result of auto-completion
- LLWString user_wstring = mTextEntry->hasSelection() ? left_wstring : mTextEntry->getWText();
+ LLWString user_wstring = mHasAutocompletedText ? left_wstring : mTextEntry->getWText();
std::string full_string = mTextEntry->getText();
// go ahead and arrange drop down list on first typed character, even
@@ -956,23 +889,15 @@ void LLComboBox::updateSelection()
// callback to populate content
if( mTextEntry->getWText().size() == 1 )
{
- if (mPrearrangeCallback)
- {
- mPrearrangeCallback( this, mCallbackUserData );
- }
+ prearrangeList(mTextEntry->getText());
}
if (mList->selectItemByLabel(full_string, FALSE))
{
mTextEntry->setTentative(FALSE);
+ mLastSelectedIndex = mList->getFirstSelectedIndex();
}
- else if (!mList->selectItemByPrefix(left_wstring, FALSE))
- {
- mList->deselectAllItems();
- mTextEntry->setText(wstring_to_utf8str(user_wstring));
- mTextEntry->setTentative(mTextEntryTentative);
- }
- else
+ else if (mList->selectItemByPrefix(left_wstring, FALSE))
{
LLWString selected_item = utf8str_to_wstring(mList->getSelectedItemLabel());
LLWString wtext = left_wstring + selected_item.substr(left_wstring.size(), selected_item.size());
@@ -980,17 +905,25 @@ void LLComboBox::updateSelection()
mTextEntry->setSelection(left_wstring.size(), mTextEntry->getWText().size());
mTextEntry->endSelection();
mTextEntry->setTentative(FALSE);
+ mHasAutocompletedText = TRUE;
+ mLastSelectedIndex = mList->getFirstSelectedIndex();
+ }
+ else // no matching items found
+ {
+ mList->deselectAllItems();
+ mTextEntry->setText(wstring_to_utf8str(user_wstring)); // removes text added by autocompletion
+ mTextEntry->setTentative(mTextEntryTentative);
+ mHasAutocompletedText = FALSE;
+ mLastSelectedIndex = -1;
}
}
-//static
-void LLComboBox::onTextCommit(LLUICtrl* caller, void* user_data)
+void LLComboBox::onTextCommit(const LLSD& data)
{
- LLComboBox* self = (LLComboBox*)user_data;
- std::string text = self->mTextEntry->getText();
- self->setSimple(text);
- self->onCommit();
- self->mTextEntry->selectAll();
+ std::string text = mTextEntry->getText();
+ setSimple(text);
+ onCommit();
+ mTextEntry->selectAll();
}
void LLComboBox::setFocus(BOOL b)
@@ -1007,6 +940,14 @@ void LLComboBox::setFocus(BOOL b)
}
}
+void LLComboBox::prearrangeList(std::string filter)
+{
+ if (mPrearrangeCallback)
+ {
+ mPrearrangeCallback(this, LLSD(filter));
+ }
+}
+
//============================================================================
// LLCtrlListInterface functions
@@ -1061,6 +1002,7 @@ BOOL LLComboBox::setCurrentByID(const LLUUID& id)
if (found)
{
setLabel(mList->getSelectedItemLabel());
+ mLastSelectedIndex = mList->getFirstSelectedIndex();
}
return found;
@@ -1114,155 +1056,3 @@ BOOL LLComboBox::selectItemRange( S32 first, S32 last )
{
return mList->selectItemRange(first, last);
}
-
-
-//
-// LLFlyoutButton
-//
-
-static LLRegisterWidget<LLFlyoutButton> r2("flyout_button");
-
-const S32 FLYOUT_BUTTON_ARROW_WIDTH = 24;
-
-LLFlyoutButton::LLFlyoutButton(
- const std::string& name,
- const LLRect &rect,
- const std::string& label,
- void (*commit_callback)(LLUICtrl*, void*) ,
- void *callback_userdata)
-: LLComboBox(name, rect, LLStringUtil::null, commit_callback, callback_userdata),
- mToggleState(FALSE),
- mActionButton(NULL)
-{
- // Always use text box
- // Text label button
- mActionButton = new LLButton(label,
- LLRect(), LLStringUtil::null, NULL, this);
- mActionButton->setScaleImage(TRUE);
-
- mActionButton->setClickedCallback(onActionButtonClick);
- mActionButton->setFollowsAll();
- mActionButton->setHAlign( LLFontGL::HCENTER );
- mActionButton->setLabel(label);
- addChild(mActionButton);
-
- mActionButtonImage = LLUI::getUIImage("flyout_btn_left.tga");
- mExpanderButtonImage = LLUI::getUIImage("flyout_btn_right.tga");
- mActionButtonImageSelected = LLUI::getUIImage("flyout_btn_left_selected.tga");
- mExpanderButtonImageSelected = LLUI::getUIImage("flyout_btn_right_selected.tga");
- mActionButtonImageDisabled = LLUI::getUIImage("flyout_btn_left_disabled.tga");
- mExpanderButtonImageDisabled = LLUI::getUIImage("flyout_btn_right_disabled.tga");
-
- mActionButton->setImageSelected(mActionButtonImageSelected);
- mActionButton->setImageUnselected(mActionButtonImage);
- mActionButton->setImageDisabled(mActionButtonImageDisabled);
- mActionButton->setImageDisabledSelected(LLPointer<LLUIImage>(NULL));
-
- mButton->setImageSelected(mExpanderButtonImageSelected);
- mButton->setImageUnselected(mExpanderButtonImage);
- mButton->setImageDisabled(mExpanderButtonImageDisabled);
- mButton->setImageDisabledSelected(LLPointer<LLUIImage>(NULL));
- mButton->setRightHPad(6);
-
- updateLayout();
-}
-
-//static
-LLView* LLFlyoutButton::fromXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFactory *factory)
-{
- std::string name = "flyout_button";
- node->getAttributeString("name", name);
-
- std::string label("");
- node->getAttributeString("label", label);
-
- LLRect rect;
- createRect(node, rect, parent, LLRect());
-
- LLUICtrlCallback callback = NULL;
-
- LLFlyoutButton* flyout_button = new LLFlyoutButton(name,
- rect,
- label,
- callback,
- NULL);
-
- std::string list_position;
- node->getAttributeString("list_position", list_position);
- if (list_position == "below")
- {
- flyout_button->mListPosition = BELOW;
- }
- else if (list_position == "above")
- {
- flyout_button->mListPosition = ABOVE;
- }
-
-
- flyout_button->initFromXML(node, parent);
-
- LLXMLNodePtr child;
- for (child = node->getFirstChild(); child.notNull(); child = child->getNextSibling())
- {
- if (child->hasName("flyout_button_item"))
- {
- std::string label = child->getTextContents();
-
- std::string value = label;
- child->getAttributeString("value", value);
-
- flyout_button->add(label, LLSD(value) );
- }
- }
-
- flyout_button->updateLayout();
-
- return flyout_button;
-}
-
-void LLFlyoutButton::updateLayout()
-{
- LLComboBox::updateLayout();
-
- mButton->setOrigin(getRect().getWidth() - FLYOUT_BUTTON_ARROW_WIDTH, 0);
- mButton->reshape(FLYOUT_BUTTON_ARROW_WIDTH, getRect().getHeight());
- mButton->setFollows(FOLLOWS_RIGHT | FOLLOWS_TOP | FOLLOWS_BOTTOM);
- mButton->setTabStop(FALSE);
- mButton->setImageOverlay(mListPosition == BELOW ? "down_arrow.tga" : "up_arrow.tga", LLFontGL::RIGHT);
-
- mActionButton->setOrigin(0, 0);
- mActionButton->reshape(getRect().getWidth() - FLYOUT_BUTTON_ARROW_WIDTH, getRect().getHeight());
-}
-
-//static
-void LLFlyoutButton::onActionButtonClick(void *user_data)
-{
- LLFlyoutButton* buttonp = (LLFlyoutButton*)user_data;
- // remember last list selection?
- buttonp->mList->deselect();
- buttonp->onCommit();
-}
-
-void LLFlyoutButton::draw()
-{
- mActionButton->setToggleState(mToggleState);
- mButton->setToggleState(mToggleState);
-
- //FIXME: this should be an attribute of comboboxes, whether they have a distinct label or
- // the label reflects the last selected item, for now we have to manually remove the label
- mButton->setLabel(LLStringUtil::null);
- LLComboBox::draw();
-}
-
-void LLFlyoutButton::setEnabled(BOOL enabled)
-{
- mActionButton->setEnabled(enabled);
- LLComboBox::setEnabled(enabled);
-}
-
-
-void LLFlyoutButton::setToggleState(BOOL state)
-{
- mToggleState = state;
-}
-
diff --git a/indra/llui/llcombobox.h b/indra/llui/llcombobox.h
index 33e1baa748..4becda195f 100644
--- a/indra/llui/llcombobox.h
+++ b/indra/llui/llcombobox.h
@@ -39,16 +39,14 @@
#include "llbutton.h"
#include "lluictrl.h"
#include "llctrlselectioninterface.h"
-#include "llimagegl.h"
#include "llrect.h"
+#include "llscrolllistctrl.h"
+#include "lllineeditor.h"
+#include <boost/function.hpp>
// Classes
class LLFontGL;
-class LLButton;
-class LLSquareButton;
-class LLScrollListCtrl;
-class LLLineEditor;
class LLViewBorder;
extern S32 LLCOMBOBOX_HEIGHT;
@@ -57,32 +55,62 @@ extern S32 LLCOMBOBOX_WIDTH;
class LLComboBox
: public LLUICtrl, public LLCtrlListInterface
{
-public:
+public:
typedef enum e_preferred_position
{
ABOVE,
BELOW
} EPreferredPosition;
- LLComboBox(
- const std::string& name,
- const LLRect &rect,
- const std::string& label,
- void (*commit_callback)(LLUICtrl*, void*) = NULL,
- void *callback_userdata = NULL
- );
- virtual ~LLComboBox();
+ struct PreferredPositionValues : public LLInitParam::TypeValuesHelper<EPreferredPosition, PreferredPositionValues>
+ {
+ static void declareValues();
+ };
- // LLView interface
- virtual LLXMLNodePtr getXML(bool save_children = true) const;
- static LLView* fromXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFactory *factory);
+ struct ItemParams : public LLInitParam::Block<ItemParams, LLScrollListItem::Params>
+ {
+ Optional<std::string> label;
+ ItemParams();
+ };
- virtual void draw();
- virtual void onFocusLost();
- virtual void onLostTop();
+ struct Params
+ : public LLInitParam::Block<Params, LLUICtrl::Params>
+ {
+ Optional<bool> allow_text_entry,
+ show_text_as_tentative;
+ Optional<S32> max_chars;
+ Optional<commit_callback_t> prearrange_callback,
+ text_entry_callback,
+ selection_callback;
+
+ Optional<EPreferredPosition, PreferredPositionValues> list_position;
+
+ // components
+ Optional<LLButton::Params> combo_button;
+ Optional<LLScrollListCtrl::Params> combo_list;
+ Optional<LLLineEditor::Params> combo_editor;
+
+ Optional<LLButton::Params> drop_down_button;
- virtual void setEnabled(BOOL enabled);
+ Multiple<ItemParams> items;
+
+ Params();
+ };
+
+
+ virtual ~LLComboBox();
+ /*virtual*/ BOOL postBuild();
+
+protected:
+ friend class LLUICtrlFactory;
+ LLComboBox(const Params&);
+ void initFromParams(const Params&);
+ void prearrangeList(std::string filter = "");
+
+public:
+ // LLView interface
+ virtual void onFocusLost();
virtual BOOL handleToolTip(S32 x, S32 y, std::string& msg, LLRect* sticky_rect);
virtual BOOL handleKeyHere(KEY key, MASK mask);
@@ -105,7 +133,6 @@ public:
// items, this is just the label.
virtual LLSD getValue() const;
- void setAllowTextEntry(BOOL allow, S32 max_chars = 50, BOOL make_tentative = TRUE);
void setTextEntry(const LLStringExplicit& text);
LLScrollListItem* add(const std::string& name, EAddPosition pos = ADD_BOTTOM, BOOL enabled = TRUE); // add item "name" to menu
@@ -134,7 +161,7 @@ public:
BOOL setCurrentByIndex( S32 index );
S32 getCurrentIndex() const;
- virtual void updateLayout();
+ void createLineEditor(const Params&);
//========================================================================
LLCtrlSelectionInterface* getSelectionInterface() { return (LLCtrlSelectionInterface*)this; };
@@ -170,66 +197,38 @@ public:
void* getCurrentUserdata();
- void setPrearrangeCallback( void (*cb)(LLUICtrl*,void*) ) { mPrearrangeCallback = cb; }
- void setTextEntryCallback( void (*cb)(LLLineEditor*, void*) ) { mTextEntryCallback = cb; }
+ void setPrearrangeCallback( commit_callback_t cb ) { mPrearrangeCallback = cb; }
+ void setTextEntryCallback( commit_callback_t cb ) { mTextEntryCallback = cb; }
+ void setSelectionCallback( commit_callback_t cb ) { mSelectionCallback = cb; }
void setButtonVisible(BOOL visible);
- static void onButtonDown(void *userdata);
- static void onItemSelected(LLUICtrl* item, void *userdata);
- static void onTextEntry(LLLineEditor* line_editor, void* user_data);
- static void onTextCommit(LLUICtrl* caller, void* user_data);
+ void onButtonDown();
+ void onItemSelected(const LLSD& data);
+ void onTextCommit(const LLSD& data);
void updateSelection();
virtual void showList();
virtual void hideList();
-
+
+ virtual void onTextEntry(LLLineEditor* line_editor);
+
protected:
LLButton* mButton;
+ LLLineEditor* mTextEntry;
LLScrollListCtrl* mList;
EPreferredPosition mListPosition;
LLPointer<LLUIImage> mArrowImage;
- std::string mLabel;
+ LLUIString mLabel;
+ BOOL mHasAutocompletedText;
private:
- S32 mButtonPadding;
- LLLineEditor* mTextEntry;
BOOL mAllowTextEntry;
S32 mMaxChars;
BOOL mTextEntryTentative;
- void (*mPrearrangeCallback)(LLUICtrl*,void*);
- void (*mTextEntryCallback)(LLLineEditor*, void*);
-};
-
-class LLFlyoutButton : public LLComboBox
-{
-public:
- LLFlyoutButton(
- const std::string& name,
- const LLRect &rect,
- const std::string& label,
- void (*commit_callback)(LLUICtrl*, void*) = NULL,
- void *callback_userdata = NULL);
-
- virtual void updateLayout();
- virtual void draw();
- virtual void setEnabled(BOOL enabled);
-
- void setToggleState(BOOL state);
-
- static LLView* fromXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFactory *factory);
- static void onActionButtonClick(void *userdata);
- static void onSelectAction(LLUICtrl* ctrl, void *userdata);
-
-protected:
- LLButton* mActionButton;
- LLPointer<LLUIImage> mActionButtonImage;
- LLPointer<LLUIImage> mExpanderButtonImage;
- LLPointer<LLUIImage> mActionButtonImageSelected;
- LLPointer<LLUIImage> mExpanderButtonImageSelected;
- LLPointer<LLUIImage> mActionButtonImageDisabled;
- LLPointer<LLUIImage> mExpanderButtonImageDisabled;
- BOOL mToggleState;
+ commit_callback_t mPrearrangeCallback;
+ commit_callback_t mTextEntryCallback;
+ commit_callback_t mSelectionCallback;
+ S32 mLastSelectedIndex;
};
-
#endif
diff --git a/indra/llui/llconsole.cpp b/indra/llui/llconsole.cpp
new file mode 100644
index 0000000000..1e8b8a5537
--- /dev/null
+++ b/indra/llui/llconsole.cpp
@@ -0,0 +1,393 @@
+/**
+ * @file llconsole.cpp
+ * @brief a scrolling console output device
+ *
+ * $LicenseInfo:firstyear=2001&license=viewergpl$
+ *
+ * Copyright (c) 2001-2009, Linden Research, Inc.
+ *
+ * Second Life Viewer Source Code
+ * The source code in this file ("Source Code") is provided by Linden Lab
+ * to you under the terms of the GNU General Public License, version 2.0
+ * ("GPL"), unless you have obtained a separate licensing agreement
+ * ("Other License"), formally executed by you and Linden Lab. Terms of
+ * the GPL can be found in doc/GPL-license.txt in this distribution, or
+ * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
+ *
+ * There are special exceptions to the terms and conditions of the GPL as
+ * it is applied to this Source Code. View the full text of the exception
+ * in the file doc/FLOSS-exception.txt in this software distribution, or
+ * online at
+ * http://secondlifegrid.net/programs/open_source/licensing/flossexception
+ *
+ * By copying, modifying or distributing this software, you acknowledge
+ * that you have read and understood your obligations described above,
+ * and agree to abide by those obligations.
+ *
+ * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+ * COMPLETENESS OR PERFORMANCE.
+ * $/LicenseInfo$
+ */
+
+//#include "llviewerprecompiledheaders.h"
+#include "linden_common.h"
+
+#include "llconsole.h"
+
+// linden library includes
+#include "llmath.h"
+//#include "llviewercontrol.h"
+#include "llcriticaldamp.h"
+#include "llfontgl.h"
+#include "llgl.h"
+#include "llui.h"
+#include "lluiimage.h"
+//#include "llviewerimage.h"
+//#include "llviewerimagelist.h"
+//#include "llviewerwindow.h"
+#include "llsd.h"
+#include "llfontgl.h"
+#include "llmath.h"
+
+//#include "llstartup.h"
+
+// Used for LCD display
+extern void AddNewDebugConsoleToLCD(const LLWString &newLine);
+
+LLConsole* gConsole = NULL; // Created and destroyed in LLViewerWindow.
+
+const F32 FADE_DURATION = 2.f;
+const S32 MIN_CONSOLE_WIDTH = 200;
+
+LLConsole::LLConsole(const LLConsole::Params& p)
+: LLView(p),
+ LLFixedBuffer(p.max_lines),
+ mLinePersistTime(p.persist_time), // seconds
+ mFont(p.font)
+{
+ if (p.font_size_index.isProvided())
+ {
+ setFontSize(p.font_size_index);
+ }
+ mFadeTime = mLinePersistTime - FADE_DURATION;
+ setMaxLines(LLUI::sSettingGroups["config"]->getS32("ConsoleMaxLines"));
+}
+
+void LLConsole::setLinePersistTime(F32 seconds)
+{
+ mLinePersistTime = seconds;
+ mFadeTime = mLinePersistTime - FADE_DURATION;
+}
+
+void LLConsole::reshape(S32 width, S32 height, BOOL called_from_parent)
+{
+ S32 new_width = llmax(50, llmin(getRect().getWidth(), width));
+ S32 new_height = llmax(llfloor(mFont->getLineHeight()) + 15, llmin(getRect().getHeight(), height));
+
+ if ( mConsoleWidth == new_width
+ && mConsoleHeight == new_height )
+ {
+ return;
+ }
+
+ mConsoleWidth = new_width;
+ mConsoleHeight= new_height;
+
+ LLView::reshape(new_width, new_height, called_from_parent);
+
+ for(paragraph_t::iterator paragraph_it = mParagraphs.begin(); paragraph_it != mParagraphs.end(); paragraph_it++)
+ {
+ (*paragraph_it).updateLines((F32)getRect().getWidth(), mFont, true);
+ }
+}
+
+void LLConsole::setFontSize(S32 size_index)
+{
+ if (-1 == size_index)
+ {
+ mFont = LLFontGL::getFontMonospace();
+ }
+ else if (0 == size_index)
+ {
+ mFont = LLFontGL::getFontSansSerif();
+ }
+ else if (1 == size_index)
+ {
+ mFont = LLFontGL::getFontSansSerifBig();
+ }
+ else
+ {
+ mFont = LLFontGL::getFontSansSerifHuge();
+ }
+
+ for(paragraph_t::iterator paragraph_it = mParagraphs.begin(); paragraph_it != mParagraphs.end(); paragraph_it++)
+ {
+ (*paragraph_it).updateLines((F32)getRect().getWidth(), mFont, true);
+ }
+}
+
+void LLConsole::draw()
+{
+ LLGLSUIDefault gls_ui;
+
+ // skip lines added more than mLinePersistTime ago
+ F32 cur_time = mTimer.getElapsedTimeF32();
+
+ F32 skip_time = cur_time - mLinePersistTime;
+ F32 fade_time = cur_time - mFadeTime;
+
+ if (mParagraphs.empty()) //No text to draw.
+ {
+ return;
+ }
+
+ U32 num_lines=0;
+
+ paragraph_t::reverse_iterator paragraph_it;
+ paragraph_it = mParagraphs.rbegin();
+ U32 paragraph_num=mParagraphs.size();
+
+ while (!mParagraphs.empty() && paragraph_it != mParagraphs.rend())
+ {
+ num_lines += (*paragraph_it).mLines.size();
+ if(num_lines > mMaxLines
+ || ( (mLinePersistTime > (F32)0.f) && ((*paragraph_it).mAddTime - skip_time)/(mLinePersistTime - mFadeTime) <= (F32)0.f))
+ { //All lines above here are done. Lose them.
+ for (U32 i=0;i<paragraph_num;i++)
+ {
+ if (!mParagraphs.empty())
+ mParagraphs.pop_front();
+ }
+ break;
+ }
+ paragraph_num--;
+ paragraph_it++;
+ }
+
+ if (mParagraphs.empty())
+ {
+ return;
+ }
+
+ // draw remaining lines
+ F32 y_pos = 0.f;
+
+ LLUIImagePtr imagep = LLUI::getUIImage("rounded_square.tga");
+
+// F32 console_opacity = llclamp(gSavedSettings.getF32("ConsoleBackgroundOpacity"), 0.f, 1.f);
+ F32 console_opacity = llclamp(LLUI::sSettingGroups["config"]->getF32("ConsoleBackgroundOpacity"), 0.f, 1.f);
+// LLColor4 color = LLUIColorTable::instance().getColor("ConsoleBackground");
+ LLColor4 color = LLUIColorTable::instance().getColor("ConsoleBackground");
+ color.mV[VALPHA] *= console_opacity;
+
+ F32 line_height = mFont->getLineHeight();
+
+ for(paragraph_it = mParagraphs.rbegin(); paragraph_it != mParagraphs.rend(); paragraph_it++)
+ {
+ S32 target_height = llfloor( (*paragraph_it).mLines.size() * line_height + 8);
+ S32 target_width = llfloor( (*paragraph_it).mMaxWidth +15);
+
+ y_pos += ((*paragraph_it).mLines.size()) * line_height;
+ imagep->drawSolid(-14, (S32)(y_pos + line_height - target_height), target_width, target_height, color);
+
+ F32 y_off=0;
+
+ F32 alpha;
+
+ if ((mLinePersistTime > 0.f) && ((*paragraph_it).mAddTime < fade_time))
+ {
+ alpha = ((*paragraph_it).mAddTime - skip_time)/(mLinePersistTime - mFadeTime);
+ }
+ else
+ {
+ alpha = 1.0f;
+ }
+
+ if( alpha > 0.f )
+ {
+ for (lines_t::iterator line_it=(*paragraph_it).mLines.begin();
+ line_it != (*paragraph_it).mLines.end();
+ line_it ++)
+ {
+ for (line_color_segments_t::iterator seg_it = (*line_it).mLineColorSegments.begin();
+ seg_it != (*line_it).mLineColorSegments.end();
+ seg_it++)
+ {
+ mFont->render((*seg_it).mText, 0, (*seg_it).mXPosition - 8, y_pos - y_off,
+ LLColor4(
+ (*seg_it).mColor.mV[VRED],
+ (*seg_it).mColor.mV[VGREEN],
+ (*seg_it).mColor.mV[VBLUE],
+ (*seg_it).mColor.mV[VALPHA]*alpha),
+ LLFontGL::LEFT,
+ LLFontGL::BASELINE,
+ LLFontGL::NORMAL,
+ LLFontGL::DROP_SHADOW,
+ S32_MAX,
+ target_width
+ );
+ }
+ y_off += line_height;
+ }
+ }
+ y_pos += 8;
+ }
+}
+
+void LLConsole::addLine(const std::string& utf8line)
+{
+ LLWString wline = utf8str_to_wstring(utf8line);
+ addLine(wline, 0.f, LLColor4(1.f, 1.f, 1.f, 1.f));
+}
+
+void LLConsole::addLine(const LLWString& wline)
+{
+ addLine(wline, 0.f, LLColor4(1.f, 1.f, 1.f, 1.f));
+}
+
+void LLConsole::addLine(const std::string& utf8line, F32 size, const LLColor4 &color)
+{
+ LLWString wline = utf8str_to_wstring(utf8line);
+ addLine(wline, size, color);
+}
+
+//Generate highlight color segments for this paragraph. Pass in default color of paragraph.
+void LLConsole::Paragraph::makeParagraphColorSegments (const LLColor4 &color)
+{
+ LLSD paragraph_color_segments;
+ LLColor4 lcolor=color;
+
+ paragraph_color_segments[0]["text"] =wstring_to_utf8str(mParagraphText);
+ LLSD color_sd = color.getValue();
+ paragraph_color_segments[0]["color"]=color_sd;
+
+ for(LLSD::array_const_iterator color_segment_it = paragraph_color_segments.beginArray();
+ color_segment_it != paragraph_color_segments.endArray();
+ ++color_segment_it)
+ {
+ LLSD color_llsd = (*color_segment_it)["color"];
+ std::string color_str = (*color_segment_it)["text"].asString();
+
+ ParagraphColorSegment color_segment;
+
+ color_segment.mColor.setValue(color_llsd);
+ color_segment.mNumChars = color_str.length();
+
+ mParagraphColorSegments.push_back(color_segment);
+ }
+}
+
+//Called when a paragraph is added to the console or window is resized.
+void LLConsole::Paragraph::updateLines(F32 screen_width, const LLFontGL* font, bool force_resize)
+{
+ if ( !force_resize )
+ {
+ if ( mMaxWidth >= 0.0f
+ && mMaxWidth < screen_width )
+ {
+ return; //No resize required.
+ }
+ }
+
+ screen_width = screen_width - 30; //Margin for small windows.
+
+ if ( mParagraphText.empty()
+ || mParagraphColorSegments.empty()
+ || font == NULL)
+ {
+ return; //Not enough info to complete.
+ }
+
+ mLines.clear(); //Chuck everything.
+ mMaxWidth = 0.0f;
+
+ paragraph_color_segments_t::iterator current_color = mParagraphColorSegments.begin();
+ U32 current_color_length = (*current_color).mNumChars;
+
+ S32 paragraph_offset = 0; //Offset into the paragraph text.
+
+ // Wrap lines that are longer than the view is wide.
+ while( paragraph_offset < (S32)mParagraphText.length() )
+ {
+ S32 skip_chars; // skip '\n'
+ // Figure out if a word-wrapped line fits here.
+ LLWString::size_type line_end = mParagraphText.find_first_of(llwchar('\n'), paragraph_offset);
+ if (line_end != LLWString::npos)
+ {
+ skip_chars = 1; // skip '\n'
+ }
+ else
+ {
+ line_end = mParagraphText.size();
+ skip_chars = 0;
+ }
+
+ U32 drawable = font->maxDrawableChars(mParagraphText.c_str()+paragraph_offset, screen_width, line_end - paragraph_offset, TRUE);
+
+ if (drawable != 0)
+ {
+ F32 x_position = 0; //Screen X position of text.
+
+ mMaxWidth = llmax( mMaxWidth, (F32)font->getWidth( mParagraphText.substr( paragraph_offset, drawable ).c_str() ) );
+ Line line;
+
+ U32 left_to_draw = drawable;
+ U32 drawn = 0;
+
+ while (left_to_draw >= current_color_length
+ && current_color != mParagraphColorSegments.end() )
+ {
+ LLWString color_text = mParagraphText.substr( paragraph_offset + drawn, current_color_length );
+ line.mLineColorSegments.push_back( LineColorSegment( color_text, //Append segment to line.
+ (*current_color).mColor,
+ x_position ) );
+
+ x_position += font->getWidth( color_text.c_str() ); //Set up next screen position.
+
+ drawn += current_color_length;
+ left_to_draw -= current_color_length;
+
+ current_color++; //Goto next paragraph color record.
+
+ if (current_color != mParagraphColorSegments.end())
+ {
+ current_color_length = (*current_color).mNumChars;
+ }
+ }
+
+ if (left_to_draw > 0 && current_color != mParagraphColorSegments.end() )
+ {
+ LLWString color_text = mParagraphText.substr( paragraph_offset + drawn, left_to_draw );
+
+ line.mLineColorSegments.push_back( LineColorSegment( color_text, //Append segment to line.
+ (*current_color).mColor,
+ x_position ) );
+
+ current_color_length -= left_to_draw;
+ }
+ mLines.push_back(line); //Append line to paragraph line list.
+ }
+ paragraph_offset += (drawable + skip_chars);
+ }
+}
+
+//Pass in the string and the default color for this block of text.
+LLConsole::Paragraph::Paragraph (LLWString str, const LLColor4 &color, F32 add_time, const LLFontGL* font, F32 screen_width)
+ : mParagraphText(str), mAddTime(add_time), mMaxWidth(-1)
+{
+ makeParagraphColorSegments(color);
+ updateLines( screen_width, font );
+}
+
+void LLConsole::addLine(const LLWString& wline, F32 size, const LLColor4 &color)
+{
+ Paragraph paragraph(wline, color, mTimer.getElapsedTimeF32(), mFont, (F32)getRect().getWidth() );
+
+ mParagraphs.push_back ( paragraph );
+
+#if LL_WINDOWS && LL_LCD_COMPILE
+ // add to LCD screen
+ AddNewDebugConsoleToLCD(wline);
+#endif
+}
diff --git a/indra/llui/llconsole.h b/indra/llui/llconsole.h
new file mode 100644
index 0000000000..56e1614948
--- /dev/null
+++ b/indra/llui/llconsole.h
@@ -0,0 +1,163 @@
+/**
+ * @file llconsole.h
+ * @brief a simple console-style output device
+ *
+ * $LicenseInfo:firstyear=2001&license=viewergpl$
+ *
+ * Copyright (c) 2001-2009, Linden Research, Inc.
+ *
+ * Second Life Viewer Source Code
+ * The source code in this file ("Source Code") is provided by Linden Lab
+ * to you under the terms of the GNU General Public License, version 2.0
+ * ("GPL"), unless you have obtained a separate licensing agreement
+ * ("Other License"), formally executed by you and Linden Lab. Terms of
+ * the GPL can be found in doc/GPL-license.txt in this distribution, or
+ * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
+ *
+ * There are special exceptions to the terms and conditions of the GPL as
+ * it is applied to this Source Code. View the full text of the exception
+ * in the file doc/FLOSS-exception.txt in this software distribution, or
+ * online at
+ * http://secondlifegrid.net/programs/open_source/licensing/flossexception
+ *
+ * By copying, modifying or distributing this software, you acknowledge
+ * that you have read and understood your obligations described above,
+ * and agree to abide by those obligations.
+ *
+ * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+ * COMPLETENESS OR PERFORMANCE.
+ * $/LicenseInfo$
+ */
+
+#ifndef LL_LLCONSOLE_H
+#define LL_LLCONSOLE_H
+
+#include "llfixedbuffer.h"
+#include "llview.h"
+#include "v4color.h"
+#include <deque>
+
+class LLFontGL;
+class LLSD;
+
+class LLConsole : public LLFixedBuffer, public LLView
+{
+public:
+ typedef enum e_font_size
+ {
+ MONOSPACE = -1,
+ SMALL = 0,
+ BIG = 1
+ } EFontSize;
+
+ struct Params : public LLInitParam::Block<Params, LLView::Params>
+ {
+ Optional<U32> max_lines;
+ Optional<F32> persist_time;
+ Optional<S32> font_size_index;
+ Params()
+ : max_lines("max_lines", LLUI::sSettingGroups["config"]->getS32("ConsoleMaxLines")),
+ persist_time("persist_time", 0.f), // forever
+ font_size_index("font_size_index")
+ {
+ mouse_opaque(false);
+ }
+ };
+protected:
+ LLConsole(const Params&);
+ friend class LLUICtrlFactory;
+
+public:
+ //A paragraph color segment defines the color of text in a line
+ //of text that was received for console display. It has no
+ //notion of line wraps, screen position, or the text it contains.
+ //It is only the number of characters that are a color and the
+ //color.
+ struct ParagraphColorSegment
+ {
+ S32 mNumChars;
+ LLColor4 mColor;
+ };
+
+ //A line color segment is a chunk of text, the color associated
+ //with it, and the X Position it was calculated to begin at
+ //on the screen. X Positions are re-calculated if the
+ //screen changes size.
+ class LineColorSegment
+ {
+ public:
+ LineColorSegment(LLWString text, LLColor4 color, F32 xpos) : mText(text), mColor(color), mXPosition(xpos) {}
+ public:
+ LLWString mText;
+ LLColor4 mColor;
+ F32 mXPosition;
+ };
+
+ typedef std::list<LineColorSegment> line_color_segments_t;
+
+ //A line is composed of one or more color segments.
+ class Line
+ {
+ public:
+ line_color_segments_t mLineColorSegments;
+ };
+
+ typedef std::list<Line> lines_t;
+ typedef std::list<ParagraphColorSegment> paragraph_color_segments_t;
+
+ //A paragraph is a processed element containing the entire text of the
+ //message (used for recalculating positions on screen resize)
+ //The time this message was added to the console output
+ //The visual screen width of the longest line in this block
+ //And a list of one or more lines which are used to display this message.
+ class Paragraph
+ {
+ public:
+ Paragraph (LLWString str, const LLColor4 &color, F32 add_time, const LLFontGL* font, F32 screen_width);
+ void makeParagraphColorSegments ( const LLColor4 &color);
+ void updateLines ( F32 screen_width, const LLFontGL* font, bool force_resize=false );
+ public:
+ LLWString mParagraphText; //The entire text of the paragraph
+ paragraph_color_segments_t mParagraphColorSegments;
+ F32 mAddTime; //Time this paragraph was added to the display.
+ F32 mMaxWidth; //Width of the widest line of text in this paragraph.
+ lines_t mLines;
+
+ };
+
+ //The console contains a deque of paragraphs which represent the individual messages.
+ typedef std::deque<Paragraph> paragraph_t;
+ paragraph_t mParagraphs;
+
+ ~LLConsole(){};
+
+ // each line lasts this long after being added
+ void setLinePersistTime(F32 seconds);
+
+ void reshape(S32 width, S32 height, BOOL called_from_parent = TRUE);
+
+ // -1 = monospace, 0 means small, font size = 1 means big
+ void setFontSize(S32 size_index);
+
+ void addLine(const std::string& utf8line, F32 size, const LLColor4 &color);
+ void addLine(const LLWString& wline, F32 size, const LLColor4 &color);
+
+ // Overrides
+ /*virtual*/ void draw();
+ /*virtual*/ void addLine(const std::string& utf8line);
+ /*virtual*/ void addLine(const LLWString& line);
+private:
+ F32 mLinePersistTime; // Age at which to stop drawing.
+ F32 mFadeTime; // Age at which to start fading
+ const LLFontGL* mFont;
+ S32 mLastBoxHeight;
+ S32 mLastBoxWidth;
+ S32 mConsoleWidth;
+ S32 mConsoleHeight;
+
+};
+
+extern LLConsole* gConsole;
+
+#endif
diff --git a/indra/llui/llcontainerview.cpp b/indra/llui/llcontainerview.cpp
new file mode 100644
index 0000000000..51ef80f4b9
--- /dev/null
+++ b/indra/llui/llcontainerview.cpp
@@ -0,0 +1,302 @@
+/**
+ * @file llcontainerview.cpp
+ * @brief Container for all statistics info
+ *
+ * $LicenseInfo:firstyear=2001&license=viewergpl$
+ *
+ * Copyright (c) 2001-2009, Linden Research, Inc.
+ *
+ * Second Life Viewer Source Code
+ * The source code in this file ("Source Code") is provided by Linden Lab
+ * to you under the terms of the GNU General Public License, version 2.0
+ * ("GPL"), unless you have obtained a separate licensing agreement
+ * ("Other License"), formally executed by you and Linden Lab. Terms of
+ * the GPL can be found in doc/GPL-license.txt in this distribution, or
+ * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
+ *
+ * There are special exceptions to the terms and conditions of the GPL as
+ * it is applied to this Source Code. View the full text of the exception
+ * in the file doc/FLOSS-exception.txt in this software distribution, or
+ * online at
+ * http://secondlifegrid.net/programs/open_source/licensing/flossexception
+ *
+ * By copying, modifying or distributing this software, you acknowledge
+ * that you have read and understood your obligations described above,
+ * and agree to abide by those obligations.
+ *
+ * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+ * COMPLETENESS OR PERFORMANCE.
+ * $/LicenseInfo$
+ */
+
+#include "linden_common.h"
+
+#include "llcontainerview.h"
+
+#include "llerror.h"
+#include "llfontgl.h"
+#include "llgl.h"
+#include "llui.h"
+#include "llstring.h"
+#include "llscrollcontainer.h"
+#include "lluictrlfactory.h"
+
+static LLDefaultChildRegistry::Register<LLContainerView> r1("container_view");
+
+#include "llpanel.h"
+#include "llstatview.h"
+static ContainerViewRegistry::Register<LLStatView> r2("stat_view");
+static ContainerViewRegistry::Register<LLPanel> r3("panel", &LLPanel::fromXML);
+
+LLContainerView::LLContainerView(const LLContainerView::Params& p)
+: LLView(p),
+ mShowLabel(p.show_label),
+ mLabel(p.label),
+ mDisplayChildren(p.display_children)
+{
+ mCollapsible = TRUE;
+ mScrollContainer = NULL;
+}
+
+LLContainerView::~LLContainerView()
+{
+ // Children all cleaned up by default view destructor.
+}
+
+BOOL LLContainerView::postBuild()
+{
+ setDisplayChildren(mDisplayChildren);
+ reshape(getRect().getWidth(), getRect().getHeight(), FALSE);
+ return TRUE;
+}
+
+bool LLContainerView::addChild(LLView* child, S32 tab_group)
+{
+ bool res = LLView::addChild(child, tab_group);
+ if (res)
+ {
+ sendChildToBack(child);
+ }
+ return res;
+}
+
+BOOL LLContainerView::handleMouseDown(S32 x, S32 y, MASK mask)
+{
+ BOOL handled = FALSE;
+ if (mDisplayChildren)
+ {
+ handled = (LLView::childrenHandleMouseDown(x, y, mask) != NULL);
+ }
+ if (!handled)
+ {
+ if( mCollapsible && mShowLabel && (y >= getRect().getHeight() - 10) )
+ {
+ setDisplayChildren(!mDisplayChildren);
+ reshape(getRect().getWidth(), getRect().getHeight(), FALSE);
+ handled = TRUE;
+ }
+ }
+ return handled;
+}
+
+BOOL LLContainerView::handleMouseUp(S32 x, S32 y, MASK mask)
+{
+ BOOL handled = FALSE;
+ if (mDisplayChildren)
+ {
+ handled = (LLView::childrenHandleMouseUp(x, y, mask) != NULL);
+ }
+ return handled;
+}
+
+
+void LLContainerView::draw()
+{
+ {
+ gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
+
+ gl_rect_2d(0, getRect().getHeight(), getRect().getWidth(), 0, LLColor4(0.f, 0.f, 0.f, 0.25f));
+ }
+
+ // Draw the label
+ if (mShowLabel)
+ {
+ LLFontGL::getFontMonospace()->renderUTF8(
+ mLabel, 0, 2, getRect().getHeight() - 2, LLColor4(1,1,1,1), LLFontGL::LEFT, LLFontGL::TOP);
+ }
+
+ LLView::draw();
+}
+
+
+void LLContainerView::reshape(S32 width, S32 height, BOOL called_from_parent)
+{
+ LLRect scroller_rect;
+ scroller_rect.setOriginAndSize(0, 0, width, height);
+
+ if (mScrollContainer)
+ {
+ scroller_rect = mScrollContainer->getContentWindowRect();
+ }
+ else
+ {
+ // if we're uncontained - make height as small as possible
+ scroller_rect.mTop = 0;
+ }
+
+ arrange(scroller_rect.getWidth(), scroller_rect.getHeight(), called_from_parent);
+
+ // sometimes, after layout, our container will change size (scrollbars popping in and out)
+ // if so, attempt another layout
+ if (mScrollContainer)
+ {
+ LLRect new_container_rect = mScrollContainer->getContentWindowRect();
+
+ if ((new_container_rect.getWidth() != scroller_rect.getWidth()) ||
+ (new_container_rect.getHeight() != scroller_rect.getHeight())) // the container size has changed, attempt to arrange again
+ {
+ arrange(new_container_rect.getWidth(), new_container_rect.getHeight(), called_from_parent);
+ }
+ }
+}
+
+void LLContainerView::arrange(S32 width, S32 height, BOOL called_from_parent)
+{
+ // Determine the sizes and locations of all contained views
+ S32 total_height = 0;
+ S32 top, left, right, bottom;
+ //LLView *childp;
+
+ // These will be used for the children
+ left = 4;
+ top = getRect().getHeight() - 4;
+ right = width - 2;
+ bottom = top;
+
+ // Leave some space for the top label/grab handle
+ if (mShowLabel)
+ {
+ total_height += 20;
+ }
+
+ if (mDisplayChildren)
+ {
+ // Determine total height
+ U32 child_height = 0;
+ for (child_list_const_iter_t child_iter = getChildList()->begin();
+ child_iter != getChildList()->end(); ++child_iter)
+ {
+ LLView *childp = *child_iter;
+ if (!childp->getVisible())
+ {
+ llwarns << "Incorrect visibility!" << llendl;
+ }
+ LLRect child_rect = childp->getRequiredRect();
+ child_height += child_rect.getHeight();
+ child_height += 2;
+ }
+ total_height += child_height;
+ }
+
+ if (total_height < height)
+ total_height = height;
+
+ if (followsTop())
+ {
+ // HACK: casting away const. Should use setRect or some helper function instead.
+ const_cast<LLRect&>(getRect()).mBottom = getRect().mTop - total_height;
+ }
+ else
+ {
+ // HACK: casting away const. Should use setRect or some helper function instead.
+ const_cast<LLRect&>(getRect()).mTop = getRect().mBottom + total_height;
+ }
+ // HACK: casting away const. Should use setRect or some helper function instead.
+ const_cast<LLRect&>(getRect()).mRight = getRect().mLeft + width;
+
+ top = total_height;
+ if (mShowLabel)
+ {
+ top -= 20;
+ }
+
+ bottom = top;
+
+ if (mDisplayChildren)
+ {
+ // Iterate through all children, and put in container from top down.
+ for (child_list_const_iter_t child_iter = getChildList()->begin();
+ child_iter != getChildList()->end(); ++child_iter)
+ {
+ LLView *childp = *child_iter;
+ LLRect child_rect = childp->getRequiredRect();
+ bottom -= child_rect.getHeight();
+ LLRect r(left, bottom + child_rect.getHeight(), right, bottom);
+ childp->setRect(r);
+ childp->reshape(right - left, top - bottom);
+ top = bottom - 2;
+ bottom = top;
+ }
+ }
+
+ if (!called_from_parent)
+ {
+ if (getParent())
+ {
+ getParent()->reshape(getParent()->getRect().getWidth(), getParent()->getRect().getHeight(), FALSE);
+ }
+ }
+
+}
+
+LLRect LLContainerView::getRequiredRect()
+{
+ LLRect req_rect;
+ //LLView *childp;
+ U32 total_height = 0;
+
+ // Determine the sizes and locations of all contained views
+
+ // Leave some space for the top label/grab handle
+
+ if (mShowLabel)
+ {
+ total_height = 20;
+ }
+
+
+ if (mDisplayChildren)
+ {
+ // Determine total height
+ U32 child_height = 0;
+ for (child_list_const_iter_t child_iter = getChildList()->begin();
+ child_iter != getChildList()->end(); ++child_iter)
+ {
+ LLView *childp = *child_iter;
+ LLRect child_rect = childp->getRequiredRect();
+ child_height += child_rect.getHeight();
+ child_height += 2;
+ }
+
+ total_height += child_height;
+ }
+ req_rect.mTop = total_height;
+ return req_rect;
+}
+
+void LLContainerView::setLabel(const std::string& label)
+{
+ mLabel = label;
+}
+
+void LLContainerView::setDisplayChildren(const BOOL displayChildren)
+{
+ mDisplayChildren = displayChildren;
+ for (child_list_const_iter_t child_iter = getChildList()->begin();
+ child_iter != getChildList()->end(); ++child_iter)
+ {
+ LLView *childp = *child_iter;
+ childp->setVisible(mDisplayChildren);
+ }
+}
diff --git a/indra/llui/llcontainerview.h b/indra/llui/llcontainerview.h
new file mode 100644
index 0000000000..74e38e18bc
--- /dev/null
+++ b/indra/llui/llcontainerview.h
@@ -0,0 +1,100 @@
+/**
+ * @file llcontainerview.h
+ * @brief Container for all statistics info.
+ *
+ * $LicenseInfo:firstyear=2001&license=viewergpl$
+ *
+ * Copyright (c) 2001-2009, Linden Research, Inc.
+ *
+ * Second Life Viewer Source Code
+ * The source code in this file ("Source Code") is provided by Linden Lab
+ * to you under the terms of the GNU General Public License, version 2.0
+ * ("GPL"), unless you have obtained a separate licensing agreement
+ * ("Other License"), formally executed by you and Linden Lab. Terms of
+ * the GPL can be found in doc/GPL-license.txt in this distribution, or
+ * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
+ *
+ * There are special exceptions to the terms and conditions of the GPL as
+ * it is applied to this Source Code. View the full text of the exception
+ * in the file doc/FLOSS-exception.txt in this software distribution, or
+ * online at
+ * http://secondlifegrid.net/programs/open_source/licensing/flossexception
+ *
+ * By copying, modifying or distributing this software, you acknowledge
+ * that you have read and understood your obligations described above,
+ * and agree to abide by those obligations.
+ *
+ * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+ * COMPLETENESS OR PERFORMANCE.
+ * $/LicenseInfo$
+ */
+
+#ifndef LL_LLCONTAINERVIEW_H
+#define LL_LLCONTAINERVIEW_H
+
+#include "stdtypes.h"
+#include "lltextbox.h"
+#include "llstatbar.h"
+#include "llview.h"
+
+class LLScrollContainer;
+
+struct ContainerViewRegistry : public LLChildRegistry<ContainerViewRegistry>
+{};
+
+class LLContainerView : public LLView
+{
+public:
+ struct Params : public LLInitParam::Block<Params, LLView::Params>
+ {
+ Optional<std::string> label;
+ Optional<bool> show_label;
+ Optional<bool> display_children;
+ Params()
+ : label("label"),
+ show_label("show_label", FALSE),
+ display_children("display_children", TRUE)
+ {
+ mouse_opaque(false);
+ }
+ };
+
+ // my valid children are stored in this registry
+ typedef ContainerViewRegistry child_registry_t;
+
+protected:
+ LLContainerView(const Params& p);
+ friend class LLUICtrlFactory;
+public:
+ ~LLContainerView();
+
+ /*virtual*/ BOOL postBuild();
+ /*virtual*/ bool addChild(LLView* view, S32 tab_group = 0);
+
+ /*virtual*/ BOOL handleMouseDown(S32 x, S32 y, MASK mask);
+ /*virtual*/ BOOL handleMouseUp(S32 x, S32 y, MASK mask);
+
+ /*virtual*/ void draw();
+ /*virtual*/ void reshape(S32 width, S32 height, BOOL called_from_parent = TRUE);
+ /*virtual*/ LLRect getRequiredRect(); // Return the height of this object, given the set options.
+
+ void setLabel(const std::string& label);
+ void showLabel(BOOL show) { mShowLabel = show; }
+ void setDisplayChildren(const BOOL displayChildren);
+ BOOL getDisplayChildren() { return mDisplayChildren; }
+ void setScrollContainer(LLScrollContainer* scroll) {mScrollContainer = scroll;}
+
+ private:
+ LLScrollContainer* mScrollContainer;
+ void arrange(S32 width, S32 height, BOOL called_from_parent = TRUE);
+ BOOL mShowLabel;
+
+protected:
+ BOOL mDisplayChildren;
+ std::string mLabel;
+public:
+ BOOL mCollapsible;
+
+};
+#endif // LL_CONTAINERVIEW_
diff --git a/indra/llui/lldraghandle.cpp b/indra/llui/lldraghandle.cpp
index 6c92ea1ff7..6e8e37ded3 100644
--- a/indra/llui/lldraghandle.cpp
+++ b/indra/llui/lldraghandle.cpp
@@ -43,10 +43,10 @@
#include "llmenugl.h"
#include "lltextbox.h"
#include "llcontrol.h"
-#include "llresmgr.h"
#include "llfontgl.h"
#include "llwindow.h"
#include "llfocusmgr.h"
+#include "lluictrlfactory.h"
const S32 LEADING_PAD = 5;
const S32 TITLE_PAD = 8;
@@ -56,21 +56,33 @@ const S32 RIGHT_PAD = BORDER_PAD + 32; // HACK: space for close btn and minimize
S32 LLDragHandle::sSnapMargin = 5;
-LLDragHandle::LLDragHandle( const std::string& name, const LLRect& rect, const std::string& title )
-: LLView( name, rect, TRUE ),
+LLDragHandle::LLDragHandle(const LLDragHandle::Params& p)
+: LLView(p),
mDragLastScreenX( 0 ),
mDragLastScreenY( 0 ),
mLastMouseScreenX( 0 ),
mLastMouseScreenY( 0 ),
- mDragHighlightColor( LLUI::sColorsGroup->getColor( "DefaultHighlightLight" ) ),
- mDragShadowColor( LLUI::sColorsGroup->getColor( "DefaultShadowDark" ) ),
mTitleBox( NULL ),
mMaxTitleWidth( 0 ),
- mForeground( TRUE )
+ mForeground( TRUE ),
+ mDragHighlightColor(p.drag_highlight_color()),
+ mDragShadowColor(p.drag_shadow_color())
+
+{
+ static LLUICachedControl<S32> snap_margin ("SnapMargin", 0);
+ sSnapMargin = snap_margin;
+}
+
+LLDragHandle::~LLDragHandle()
{
- sSnapMargin = LLUI::sConfigGroup->getS32("SnapMargin");
+ removeChild(mTitleBox);
+ delete mTitleBox;
+}
- setSaveToXML(false);
+void LLDragHandle::initFromParams(const LLDragHandle::Params& p)
+{
+ LLView::initFromParams(p);
+ setTitle( p.label );
}
void LLDragHandle::setTitleVisible(BOOL visible)
@@ -81,58 +93,47 @@ void LLDragHandle::setTitleVisible(BOOL visible)
}
}
-void LLDragHandle::setTitleBox(LLTextBox* titlebox)
-{
+void LLDragHandleTop::setTitle(const std::string& title)
+{
+ std::string trimmed_title = title;
+ LLStringUtil::trim(trimmed_title);
+
if( mTitleBox )
{
- removeChild(mTitleBox);
- delete mTitleBox;
+ mTitleBox->setText(trimmed_title);
}
- mTitleBox = titlebox;
- if(mTitleBox)
+ else
{
+ const LLFontGL* font = LLFontGL::getFontSansSerif();
+ LLTextBox::Params params;
+ params.name("Drag Handle Title");
+ params.rect(getRect());
+ params.text(trimmed_title);
+ params.font(font);
+ params.follows.flags(FOLLOWS_TOP | FOLLOWS_LEFT | FOLLOWS_RIGHT);
+ params.font_shadow(LLFontGL::DROP_SHADOW_SOFT);
+ mTitleBox = LLUICtrlFactory::create<LLTextBox> (params);
addChild( mTitleBox );
}
-}
-
-LLDragHandleTop::LLDragHandleTop(const std::string& name, const LLRect &rect, const std::string& title)
-: LLDragHandle(name, rect, title)
-{
- setFollowsAll();
- setTitle( title );
-}
-
-LLDragHandleLeft::LLDragHandleLeft(const std::string& name, const LLRect &rect, const std::string& title)
-: LLDragHandle(name, rect, title)
-{
- setFollowsAll();
- setTitle( title );
-}
-
-void LLDragHandleTop::setTitle(const std::string& title)
-{
- std::string trimmed_title = title;
- LLStringUtil::trim(trimmed_title);
-
- const LLFontGL* font = LLResMgr::getInstance()->getRes( LLFONT_SANSSERIF );
- LLTextBox* titlebox = new LLTextBox( std::string("Drag Handle Title"), getRect(), trimmed_title, font );
- titlebox->setFollows(FOLLOWS_TOP | FOLLOWS_LEFT | FOLLOWS_RIGHT);
- titlebox->setFontStyle(LLFontGL::DROP_SHADOW_SOFT);
- setTitleBox(titlebox);
reshapeTitleBox();
}
const std::string& LLDragHandleTop::getTitle() const
{
- return getTitleBox() == NULL ? LLStringUtil::null : getTitleBox()->getText();
+ return mTitleBox == NULL ? LLStringUtil::null : mTitleBox->getText();
}
void LLDragHandleLeft::setTitle(const std::string& )
{
- setTitleBox(NULL);
+ if( mTitleBox )
+ {
+ removeChild(mTitleBox);
+ delete mTitleBox;
+ mTitleBox = NULL;
+ }
/* no title on left edge */
}
@@ -184,9 +185,9 @@ void LLDragHandleTop::draw()
*/
// Colorize the text to match the frontmost state
- if (getTitleBox())
+ if (mTitleBox)
{
- getTitleBox()->setEnabled(getForeground());
+ mTitleBox->setEnabled(getForeground());
}
LLView::draw();
@@ -229,9 +230,9 @@ void LLDragHandleLeft::draw()
*/
// Colorize the text to match the frontmost state
- if (getTitleBox())
+ if (mTitleBox)
{
- getTitleBox()->setEnabled(getForeground());
+ mTitleBox->setEnabled(getForeground());
}
LLView::draw();
@@ -239,12 +240,12 @@ void LLDragHandleLeft::draw()
void LLDragHandleTop::reshapeTitleBox()
{
- if( ! getTitleBox())
+ if( ! mTitleBox)
{
return;
}
- const LLFontGL* font = LLResMgr::getInstance()->getRes( LLFONT_SANSSERIF );
- S32 title_width = font->getWidth( getTitleBox()->getText() ) + TITLE_PAD;
+ const LLFontGL* font = LLFontGL::getFontSansSerif();
+ S32 title_width = font->getWidth( mTitleBox->getText() ) + TITLE_PAD;
if (getMaxTitleWidth() > 0)
title_width = llmin(title_width, getMaxTitleWidth());
S32 title_height = llround(font->getLineHeight());
@@ -255,7 +256,7 @@ void LLDragHandleTop::reshapeTitleBox()
getRect().getWidth() - LEFT_PAD - RIGHT_PAD,
title_height);
- getTitleBox()->setRect( title_rect );
+ mTitleBox->setRect( title_rect );
}
void LLDragHandleTop::reshape(S32 width, S32 height, BOOL called_from_parent)
@@ -316,6 +317,23 @@ BOOL LLDragHandle::handleHover(S32 x, S32 y, MASK mask)
S32 delta_x = screen_x - mDragLastScreenX;
S32 delta_y = screen_y - mDragLastScreenY;
+ // if dragging a docked floater we want to undock
+ if (((LLFloater*)getParent())->isDocked())
+ {
+ const S32 SLOP = 12;
+
+ if (delta_y <= -SLOP ||
+ delta_y >= SLOP)
+ {
+ ((LLFloater*)getParent())->setDocked(false, false);
+ return TRUE;
+ }
+ else
+ {
+ return FALSE;
+ }
+ }
+
LLRect original_rect = getParent()->getRect();
LLRect translated_rect = getParent()->getRect();
translated_rect.translate(delta_x, delta_y);
@@ -337,14 +355,14 @@ BOOL LLDragHandle::handleHover(S32 x, S32 y, MASK mask)
LLView* snap_view = getParent()->findSnapRect(new_rect, mouse_dir, SNAP_PARENT_AND_SIBLINGS, sSnapMargin);
- getParent()->snappedTo(snap_view);
+ getParent()->setSnappedTo(snap_view);
delta_x = new_rect.mLeft - pre_snap_x;
delta_y = new_rect.mBottom - pre_snap_y;
translated_rect.translate(delta_x, delta_y);
// restore original rect so delta are detected, then call user reshape method to handle snapped floaters, etc
getParent()->setRect(original_rect);
- getParent()->userSetShape(translated_rect);
+ getParent()->setShape(translated_rect, true);
mDragLastScreenX += delta_x;
mDragLastScreenY += delta_y;
diff --git a/indra/llui/lldraghandle.h b/indra/llui/lldraghandle.h
index 9eb3e55a6c..88ec1d21f8 100644
--- a/indra/llui/lldraghandle.h
+++ b/indra/llui/lldraghandle.h
@@ -45,8 +45,25 @@ class LLTextBox;
class LLDragHandle : public LLView
{
public:
- LLDragHandle(const std::string& name, const LLRect& rect, const std::string& title );
- virtual ~LLDragHandle() { setTitleBox(NULL); }
+ struct Params
+ : public LLInitParam::Block<Params, LLView::Params>
+ {
+ Optional<std::string> label;
+ Optional<LLUIColor> drag_highlight_color;
+ Optional<LLUIColor> drag_shadow_color;
+
+ Params()
+ : label("label"),
+ drag_highlight_color("drag_highlight_color", LLUIColorTable::instance().getColor("DefaultHighlightLight")),
+ drag_shadow_color("drag_shadow_color", LLUIColorTable::instance().getColor("DefaultShadowDark"))
+ {
+ mouse_opaque(true);
+ follows.flags(FOLLOWS_ALL);
+ }
+ };
+ void initFromParams(const Params&);
+
+ virtual ~LLDragHandle();
virtual void setValue(const LLSD& value);
@@ -64,18 +81,20 @@ public:
virtual BOOL handleMouseUp(S32 x, S32 y, MASK mask);
protected:
- LLTextBox* getTitleBox() const { return mTitleBox; }
- void setTitleBox(LLTextBox*);
-
+ LLDragHandle(const Params&);
+ friend class LLUICtrlFactory;
+
+protected:
+ LLTextBox* mTitleBox;
+
private:
S32 mDragLastScreenX;
S32 mDragLastScreenY;
S32 mLastMouseScreenX;
S32 mLastMouseScreenY;
LLCoordGL mLastMouseDir;
- LLColor4 mDragHighlightColor;
- LLColor4 mDragShadowColor;
- LLTextBox* mTitleBox;
+ LLUIColor mDragHighlightColor;
+ LLUIColor mDragShadowColor;
S32 mMaxTitleWidth;
BOOL mForeground;
@@ -88,9 +107,10 @@ private:
class LLDragHandleTop
: public LLDragHandle
{
+protected:
+ LLDragHandleTop(const Params& p) : LLDragHandle(p) {}
+ friend class LLUICtrlFactory;
public:
- LLDragHandleTop(const std::string& name, const LLRect& rect, const std::string& title );
-
virtual void setTitle( const std::string& title );
virtual const std::string& getTitle() const;
virtual void draw();
@@ -105,9 +125,10 @@ private:
class LLDragHandleLeft
: public LLDragHandle
{
+protected:
+ LLDragHandleLeft(const Params& p) : LLDragHandle(p) {}
+ friend class LLUICtrlFactory;
public:
- LLDragHandleLeft(const std::string& name, const LLRect& rect, const std::string& title );
-
virtual void setTitle( const std::string& title );
virtual const std::string& getTitle() const;
virtual void draw();
diff --git a/indra/llui/llf32uictrl.cpp b/indra/llui/llf32uictrl.cpp
new file mode 100644
index 0000000000..0978005b78
--- /dev/null
+++ b/indra/llui/llf32uictrl.cpp
@@ -0,0 +1,57 @@
+/**
+ * @file llf32uictrl.cpp
+ * @author Nat Goodspeed
+ * @date 2008-09-08
+ * @brief Implementation for llf32uictrl.
+ *
+ * $LicenseInfo:firstyear=2008&license=viewergpl$
+ *
+ * Copyright (c) 2008-2009, Linden Research, Inc.
+ *
+ * Second Life Viewer Source Code
+ * The source code in this file ("Source Code") is provided by Linden Lab
+ * to you under the terms of the GNU General Public License, version 2.0
+ * ("GPL"), unless you have obtained a separate licensing agreement
+ * ("Other License"), formally executed by you and Linden Lab. Terms of
+ * the GPL can be found in doc/GPL-license.txt in this distribution, or
+ * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
+ *
+ * There are special exceptions to the terms and conditions of the GPL as
+ * it is applied to this Source Code. View the full text of the exception
+ * in the file doc/FLOSS-exception.txt in this software distribution, or
+ * online at
+ * http://secondlifegrid.net/programs/open_source/licensing/flossexception
+ *
+ * By copying, modifying or distributing this software, you acknowledge
+ * that you have read and understood your obligations described above,
+ * and agree to abide by those obligations.
+ *
+ * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+ * COMPLETENESS OR PERFORMANCE.
+ * $/LicenseInfo$
+ */
+
+// Precompiled header
+#include "linden_common.h"
+// associated header
+#include "llf32uictrl.h"
+// STL headers
+// std headers
+// external library headers
+// other Linden headers
+
+LLF32UICtrl::LLF32UICtrl(const Params& p)
+: LLUICtrl(p),
+ mInitialValue(p.initial_value().asReal()),
+ mMinValue(p.min_value),
+ mMaxValue(p.max_value),
+ mIncrement(p.increment)
+{
+ mViewModel->setValue(p.initial_value);
+}
+
+F32 LLF32UICtrl::getValueF32() const
+{
+ return mViewModel->getValue().asReal();
+}
diff --git a/indra/llui/llf32uictrl.h b/indra/llui/llf32uictrl.h
new file mode 100644
index 0000000000..0a54fe761b
--- /dev/null
+++ b/indra/llui/llf32uictrl.h
@@ -0,0 +1,83 @@
+/**
+ * @file llf32uictrl.h
+ * @author Nat Goodspeed
+ * @date 2008-09-08
+ * @brief Base class for float-valued LLUICtrl widgets
+ *
+ * $LicenseInfo:firstyear=2008&license=viewergpl$
+ *
+ * Copyright (c) 2008-2009, Linden Research, Inc.
+ *
+ * Second Life Viewer Source Code
+ * The source code in this file ("Source Code") is provided by Linden Lab
+ * to you under the terms of the GNU General Public License, version 2.0
+ * ("GPL"), unless you have obtained a separate licensing agreement
+ * ("Other License"), formally executed by you and Linden Lab. Terms of
+ * the GPL can be found in doc/GPL-license.txt in this distribution, or
+ * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
+ *
+ * There are special exceptions to the terms and conditions of the GPL as
+ * it is applied to this Source Code. View the full text of the exception
+ * in the file doc/FLOSS-exception.txt in this software distribution, or
+ * online at
+ * http://secondlifegrid.net/programs/open_source/licensing/flossexception
+ *
+ * By copying, modifying or distributing this software, you acknowledge
+ * that you have read and understood your obligations described above,
+ * and agree to abide by those obligations.
+ *
+ * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+ * COMPLETENESS OR PERFORMANCE.
+ * $/LicenseInfo$
+ */
+
+#if ! defined(LL_LLF32UICTRL_H)
+#define LL_LLF32UICTRL_H
+
+#include "lluictrl.h"
+
+class LLF32UICtrl: public LLUICtrl
+{
+public:
+ struct Params: public LLInitParam::Block<Params, LLUICtrl::Params>
+ {
+ Optional<F32> min_value,
+ max_value,
+ increment;
+
+ Params()
+ : min_value("min_val", 0.f),
+ max_value("max_val", 1.f),
+ increment("increment", 0.1f)
+ {}
+ };
+
+protected:
+ LLF32UICtrl(const Params& p);
+
+public:
+ virtual F32 getValueF32() const;
+
+ virtual void setValue(const LLSD& value ) { mViewModel->setValue(value); }
+ virtual LLSD getValue() const { return LLSD(getValueF32()); }
+
+ virtual void setMinValue(const LLSD& min_value) { setMinValue((F32)min_value.asReal()); }
+ virtual void setMaxValue(const LLSD& max_value) { setMaxValue((F32)max_value.asReal()); }
+
+ virtual F32 getInitialValue() const { return mInitialValue; }
+ virtual F32 getMinValue() const { return mMinValue; }
+ virtual F32 getMaxValue() const { return mMaxValue; }
+ virtual F32 getIncrement() const { return mIncrement; }
+ virtual void setMinValue(F32 min_value) { mMinValue = min_value; }
+ virtual void setMaxValue(F32 max_value) { mMaxValue = max_value; }
+ virtual void setIncrement(F32 increment) { mIncrement = increment;}
+
+protected:
+ F32 mInitialValue;
+ F32 mMinValue;
+ F32 mMaxValue;
+ F32 mIncrement;
+};
+
+#endif /* ! defined(LL_LLF32UICTRL_H) */
diff --git a/indra/llui/llfiltereditor.cpp b/indra/llui/llfiltereditor.cpp
new file mode 100644
index 0000000000..7d6a4007a2
--- /dev/null
+++ b/indra/llui/llfiltereditor.cpp
@@ -0,0 +1,116 @@
+/**
+ * @file llfiltereditor.cpp
+ * @brief LLFilterEditor implementation
+ *
+ * $LicenseInfo:firstyear=2001&license=viewergpl$
+ *
+ * Copyright (c) 2001-2009, Linden Research, Inc.
+ *
+ * Second Life Viewer Source Code
+ * The source code in this file ("Source Code") is provided by Linden Lab
+ * to you under the terms of the GNU General Public License, version 2.0
+ * ("GPL"), unless you have obtained a separate licensing agreement
+ * ("Other License"), formally executed by you and Linden Lab. Terms of
+ * the GPL can be found in doc/GPL-license.txt in this distribution, or
+ * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
+ *
+ * There are special exceptions to the terms and conditions of the GPL as
+ * it is applied to this Source Code. View the full text of the exception
+ * in the file doc/FLOSS-exception.txt in this software distribution, or
+ * online at
+ * http://secondlifegrid.net/programs/open_source/licensing/flossexception
+ *
+ * By copying, modifying or distributing this software, you acknowledge
+ * that you have read and understood your obligations described above,
+ * and agree to abide by those obligations.
+ *
+ * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+ * COMPLETENESS OR PERFORMANCE.
+ * $/LicenseInfo$
+ */
+
+// Text editor widget to let users enter a single line.
+
+#include "linden_common.h"
+
+#include "llfiltereditor.h"
+
+LLFilterEditor::LLFilterEditor(const LLFilterEditor::Params& p)
+: LLUICtrl(p)
+{
+ LLLineEditor::Params line_editor_p(p);
+ line_editor_p.name("filter edit box");
+ line_editor_p.rect(getLocalRect());
+ line_editor_p.follows.flags(FOLLOWS_ALL);
+ line_editor_p.text_pad_right(getRect().getHeight());
+ line_editor_p.keystroke_callback(boost::bind(&LLUICtrl::onCommit, this));
+
+ mFilterEditor = LLUICtrlFactory::create<LLLineEditor>(line_editor_p);
+ addChild(mFilterEditor);
+
+ S32 btn_width = getRect().getHeight(); // button is square, and as tall as search editor
+ LLRect clear_btn_rect(getRect().getWidth() - btn_width, getRect().getHeight(), getRect().getWidth(), 0);
+ LLButton::Params button_params(p.clear_filter_button);
+ button_params.name(std::string("clear filter"));
+ button_params.rect(clear_btn_rect) ;
+ button_params.follows.flags(FOLLOWS_RIGHT|FOLLOWS_TOP);
+ button_params.tab_stop(false);
+ button_params.click_callback.function(boost::bind(&LLFilterEditor::onClearFilter, this, _2));
+
+ mClearFilterButton = LLUICtrlFactory::create<LLButton>(button_params);
+ mFilterEditor->addChild(mClearFilterButton);
+}
+
+//virtual
+void LLFilterEditor::setValue(const LLSD& value )
+{
+ mFilterEditor->setValue(value);
+}
+
+//virtual
+LLSD LLFilterEditor::getValue() const
+{
+ return mFilterEditor->getValue();
+}
+
+//virtual
+BOOL LLFilterEditor::setTextArg( const std::string& key, const LLStringExplicit& text )
+{
+ return mFilterEditor->setTextArg(key, text);
+}
+
+//virtual
+BOOL LLFilterEditor::setLabelArg( const std::string& key, const LLStringExplicit& text )
+{
+ return mFilterEditor->setLabelArg(key, text);
+}
+
+//virtual
+void LLFilterEditor::setLabel( const LLStringExplicit &new_label )
+{
+ mFilterEditor->setLabel(new_label);
+}
+
+//virtual
+void LLFilterEditor::clear()
+{
+ if (mFilterEditor)
+ {
+ mFilterEditor->clear();
+ }
+}
+
+void LLFilterEditor::draw()
+{
+ mClearFilterButton->setVisible(!mFilterEditor->getWText().empty());
+
+ LLUICtrl::draw();
+}
+
+void LLFilterEditor::onClearFilter(const LLSD& data)
+{
+ setText(LLStringUtil::null);
+ onCommit();
+}
+
diff --git a/indra/llui/llfiltereditor.h b/indra/llui/llfiltereditor.h
new file mode 100644
index 0000000000..fceb82af8d
--- /dev/null
+++ b/indra/llui/llfiltereditor.h
@@ -0,0 +1,87 @@
+/**
+ * @file llfiltereditor.h
+ * @brief Text editor widget that represents a filter operation
+ *
+ * Features:
+ * Text entry of a single line (text, delete, left and right arrow, insert, return).
+ * Callbacks either on every keystroke or just on the return key.
+ * Focus (allow multiple text entry widgets)
+ * Clipboard (cut, copy, and paste)
+ * Horizontal scrolling to allow strings longer than widget size allows
+ * Pre-validation (limit which keys can be used)
+ * Optional line history so previous entries can be recalled by CTRL UP/DOWN
+ *
+ * $LicenseInfo:firstyear=2001&license=viewergpl$
+ *
+ * Copyright (c) 2001-2009, Linden Research, Inc.
+ *
+ * Second Life Viewer Source Code
+ * The source code in this file ("Source Code") is provided by Linden Lab
+ * to you under the terms of the GNU General Public License, version 2.0
+ * ("GPL"), unless you have obtained a separate licensing agreement
+ * ("Other License"), formally executed by you and Linden Lab. Terms of
+ * the GPL can be found in doc/GPL-license.txt in this distribution, or
+ * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
+ *
+ * There are special exceptions to the terms and conditions of the GPL as
+ * it is applied to this Source Code. View the full text of the exception
+ * in the file doc/FLOSS-exception.txt in this software distribution, or
+ * online at
+ * http://secondlifegrid.net/programs/open_source/licensing/flossexception
+ *
+ * By copying, modifying or distributing this software, you acknowledge
+ * that you have read and understood your obligations described above,
+ * and agree to abide by those obligations.
+ *
+ * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+ * COMPLETENESS OR PERFORMANCE.
+ * $/LicenseInfo$
+ */
+
+#ifndef LL_FILTEREDITOR_H
+#define LL_FILTEREDITOR_H
+
+#include "lllineeditor.h"
+#include "llbutton.h"
+
+class LLFilterEditor : public LLUICtrl
+{
+public:
+ struct Params : public LLInitParam::Block<Params, LLLineEditor::Params>
+ {
+ Optional<LLButton::Params> clear_filter_button;
+
+ Params()
+ : clear_filter_button("clear_filter_button")
+ {
+ name = "filter_editor";
+ }
+ };
+
+protected:
+ LLFilterEditor(const Params&);
+ friend class LLUICtrlFactory;
+public:
+ virtual ~LLFilterEditor() {}
+
+ /*virtual*/ void draw();
+
+ void setText(const LLStringExplicit &new_text) { mFilterEditor->setText(new_text); }
+
+ // LLUICtrl interface
+ virtual void setValue(const LLSD& value );
+ virtual LLSD getValue() const;
+ virtual BOOL setTextArg( const std::string& key, const LLStringExplicit& text );
+ virtual BOOL setLabelArg( const std::string& key, const LLStringExplicit& text );
+ virtual void setLabel( const LLStringExplicit &new_label );
+ virtual void clear();
+
+private:
+ void onClearFilter(const LLSD& data);
+
+ LLLineEditor* mFilterEditor;
+ LLButton* mClearFilterButton;
+};
+
+#endif // LL_FILTEREDITOR_H
diff --git a/indra/llui/llfloater.cpp b/indra/llui/llfloater.cpp
index 21f8f6e5f7..ca3829e1bd 100644
--- a/indra/llui/llfloater.cpp
+++ b/indra/llui/llfloater.cpp
@@ -43,11 +43,13 @@
#include "llbutton.h"
#include "llcheckboxctrl.h"
#include "lldraghandle.h"
+#include "llfloaterreg.h"
#include "llfocusmgr.h"
#include "llresizebar.h"
#include "llresizehandle.h"
#include "llkeyboard.h"
#include "llmenugl.h" // MENU_BAR_HEIGHT
+#include "llmodaldialog.h"
#include "lltextbox.h"
#include "llresmgr.h"
#include "llui.h"
@@ -56,37 +58,45 @@
#include "llcontrol.h"
#include "lltabcontainer.h"
#include "v2math.h"
+#include "lltrans.h"
+#include "llmultifloater.h"
-const S32 MINIMIZED_WIDTH = 160;
-const S32 CLOSE_BOX_FROM_TOP = 1;
// use this to control "jumping" behavior when Ctrl-Tabbing
const S32 TABBED_FLOATER_OFFSET = 0;
std::string LLFloater::sButtonActiveImageNames[BUTTON_COUNT] =
{
- "UIImgBtnCloseActiveUUID", //BUTTON_CLOSE
- "UIImgBtnRestoreActiveUUID", //BUTTON_RESTORE
- "UIImgBtnMinimizeActiveUUID", //BUTTON_MINIMIZE
- "UIImgBtnTearOffActiveUUID", //BUTTON_TEAR_OFF
- "UIImgBtnCloseActiveUUID", //BUTTON_EDIT
+ "Icon_Close_Foreground", //BUTTON_CLOSE
+ "restore.tga", //BUTTON_RESTORE
+ "minimize.tga", //BUTTON_MINIMIZE
+ "tearoffbox.tga", //BUTTON_TEAR_OFF
+ "closebox.tga", //BUTTON_EDIT
+ "Icon_Dock_Foreground",
+ "Icon_Undock_Foreground"
};
-std::string LLFloater::sButtonInactiveImageNames[BUTTON_COUNT] =
-{
- "UIImgBtnCloseInactiveUUID", //BUTTON_CLOSE
- "UIImgBtnRestoreInactiveUUID", //BUTTON_RESTORE
- "UIImgBtnMinimizeInactiveUUID", //BUTTON_MINIMIZE
- "UIImgBtnTearOffInactiveUUID", //BUTTON_TEAR_OFF
- "UIImgBtnCloseInactiveUUID", //BUTTON_EDIT
+// Empty string means programmatic glow effect, achieved by
+// not setting explicit image.
+std::string LLFloater::sButtonHoveredImageNames[BUTTON_COUNT] =
+{
+ "", //BUTTON_CLOSE
+ "restore_pressed.tga", //BUTTON_RESTORE
+ "minimize_pressed.tga", //BUTTON_MINIMIZE
+ "tearoff_pressed.tga", //BUTTON_TEAR_OFF
+ "close_in_blue.tga", //BUTTON_EDIT
+ "", //BUTTON_DOCK
+ "", //BUTTON_UNDOCK
};
std::string LLFloater::sButtonPressedImageNames[BUTTON_COUNT] =
{
- "UIImgBtnClosePressedUUID", //BUTTON_CLOSE
- "UIImgBtnRestorePressedUUID", //BUTTON_RESTORE
- "UIImgBtnMinimizePressedUUID", //BUTTON_MINIMIZE
- "UIImgBtnTearOffPressedUUID", //BUTTON_TEAR_OFF
- "UIImgBtnClosePressedUUID", //BUTTON_EDIT
+ "Icon_Close_Press", //BUTTON_CLOSE
+ "restore_pressed.tga", //BUTTON_RESTORE
+ "minimize_pressed.tga", //BUTTON_MINIMIZE
+ "tearoff_pressed.tga", //BUTTON_TEAR_OFF
+ "close_in_blue.tga", //BUTTON_EDIT
+ "Icon_Dock_Press",
+ "Icon_Undock_Press"
};
std::string LLFloater::sButtonNames[BUTTON_COUNT] =
@@ -96,19 +106,25 @@ std::string LLFloater::sButtonNames[BUTTON_COUNT] =
"llfloater_minimize_btn", //BUTTON_MINIMIZE
"llfloater_tear_off_btn", //BUTTON_TEAR_OFF
"llfloater_edit_btn", //BUTTON_EDIT
+ "llfloater_dock_btn",
+ "llfloater_undock_btn"
};
-std::string LLFloater::sButtonToolTips[BUTTON_COUNT] =
+std::string LLFloater::sButtonToolTips[BUTTON_COUNT];
+
+std::string LLFloater::sButtonToolTipsIndex[BUTTON_COUNT]=
{
#ifdef LL_DARWIN
- "Close (Cmd-W)", //BUTTON_CLOSE
+ "BUTTON_CLOSE_DARWIN", //"Close (Cmd-W)", //BUTTON_CLOSE
#else
- "Close (Ctrl-W)", //BUTTON_CLOSE
+ "BUTTON_CLOSE_WIN", //"Close (Ctrl-W)", //BUTTON_CLOSE
#endif
- "Restore", //BUTTON_RESTORE
- "Minimize", //BUTTON_MINIMIZE
- "Tear Off", //BUTTON_TEAR_OFF
- "Edit", //BUTTON_EDIT
+ "BUTTON_RESTORE", //"Restore", //BUTTON_RESTORE
+ "BUTTON_MINIMIZE", //"Minimize", //BUTTON_MINIMIZE
+ "BUTTON_TEAR_OFF", //"Tear Off", //BUTTON_TEAR_OFF
+ "BUTTON_EDIT", //"Edit", //BUTTON_EDIT
+ "BUTTON_DOCK",
+ "BUTTON_UNDOCK"
};
LLFloater::click_callback LLFloater::sButtonCallbacks[BUTTON_COUNT] =
@@ -118,306 +134,205 @@ LLFloater::click_callback LLFloater::sButtonCallbacks[BUTTON_COUNT] =
LLFloater::onClickMinimize, //BUTTON_MINIMIZE
LLFloater::onClickTearOff, //BUTTON_TEAR_OFF
LLFloater::onClickEdit, //BUTTON_EDIT
+ LLFloater::onClickDock,
+ LLFloater::onClickDock
};
LLMultiFloater* LLFloater::sHostp = NULL;
-BOOL LLFloater::sEditModeEnabled;
+BOOL LLFloater::sEditModeEnabled = FALSE;
+BOOL LLFloater::sQuitting = FALSE; // Flag to prevent storing visibility controls while quitting
LLFloater::handle_map_t LLFloater::sFloaterMap;
LLFloaterView* gFloaterView = NULL;
-LLFloater::LLFloater() :
- //FIXME: we should initialize *all* member variables here
- LLPanel(), mAutoFocus(TRUE),
- mResizable(FALSE),
- mDragOnLeft(FALSE),
- mMinWidth(0),
- mMinHeight(0)
-{
- // automatically take focus when opened
- mAutoFocus = TRUE;
- for (S32 i = 0; i < BUTTON_COUNT; i++)
- {
- mButtonsEnabled[i] = FALSE;
- mButtons[i] = NULL;
- }
- for (S32 i = 0; i < 4; i++)
- {
- mResizeBar[i] = NULL;
- mResizeHandle[i] = NULL;
- }
- mDragHandle = NULL;
- mHandle.bind(this);
- mNotificationContext = new LLFloaterNotificationContext(getHandle());
+//static
+bool LLFloater::KeyCompare::compare(const LLSD& a, const LLSD& b)
+{
+ if (a.type() != b.type())
+ {
+ //llerrs << "Mismatched LLSD types: (" << a << ") mismatches (" << b << ")" << llendl;
+ return false;
+ }
+ else if (a.isUndefined())
+ return false;
+ else if (a.isInteger())
+ return a.asInteger() < b.asInteger();
+ else if (a.isReal())
+ return a.asReal() < b.asReal();
+ else if (a.isString())
+ return a.asString() < b.asString();
+ else if (a.isUUID())
+ return a.asUUID() < b.asUUID();
+ else if (a.isDate())
+ return a.asDate() < b.asDate();
+ else if (a.isURI())
+ return a.asString() < b.asString(); // compare URIs as strings
+ else if (a.isBoolean())
+ return a.asBoolean() < b.asBoolean();
+ else
+ return false; // no valid operation for Binary
+}
+
+bool LLFloater::KeyCompare::equate(const LLSD& a, const LLSD& b)
+{
+ if (a.type() != b.type())
+ {
+ //llerrs << "Mismatched LLSD types: (" << a << ") mismatches (" << b << ")" << llendl;
+ return false;
+ }
+ else if (a.isUndefined())
+ return true;
+ else if (a.isInteger())
+ return a.asInteger() == b.asInteger();
+ else if (a.isReal())
+ return a.asReal() == b.asReal();
+ else if (a.isString())
+ return a.asString() == b.asString();
+ else if (a.isUUID())
+ return a.asUUID() == b.asUUID();
+ else if (a.isDate())
+ return a.asDate() == b.asDate();
+ else if (a.isURI())
+ return a.asString() == b.asString(); // compare URIs as strings
+ else if (a.isBoolean())
+ return a.asBoolean() == b.asBoolean();
+ else
+ return false; // no valid operation for Binary
}
-LLFloater::LLFloater(const std::string& name)
-: LLPanel(name), mAutoFocus(TRUE) // automatically take focus when opened
+//************************************
+
+LLFloater::Params::Params()
+: title("title"),
+ short_title("short_title"),
+ single_instance("single_instance", false),
+ auto_tile("auto_tile", false),
+ can_resize("can_resize", false),
+ can_minimize("can_minimize", true),
+ can_close("can_close", true),
+ can_drag_on_left("can_drag_on_left", false),
+ can_tear_off("can_tear_off", true),
+ save_rect("save_rect", false),
+ save_visibility("save_visibility", false),
+ open_callback("open_callback"),
+ close_callback("close_callback"),
+ can_dock("can_dock", false)
{
- for (S32 i = 0; i < BUTTON_COUNT; i++)
- {
- mButtonsEnabled[i] = FALSE;
- mButtons[i] = NULL;
- }
- for (S32 i = 0; i < 4; i++)
- {
- mResizeBar[i] = NULL;
- mResizeHandle[i] = NULL;
- }
- std::string title; // null string
- initFloater(title, FALSE, DEFAULT_MIN_WIDTH, DEFAULT_MIN_HEIGHT, FALSE, TRUE, TRUE); // defaults
+ name = "floater";
+ // defaults that differ from LLPanel:
+ background_visible = true;
+ visible = false;
}
-LLFloater::LLFloater(const std::string& name, const LLRect& rect, const std::string& title,
- BOOL resizable,
- S32 min_width,
- S32 min_height,
- BOOL drag_on_left,
- BOOL minimizable,
- BOOL close_btn,
- BOOL bordered)
-: LLPanel(name, rect, bordered), mAutoFocus(TRUE) // automatically take focus when opened
+//static
+const LLFloater::Params& LLFloater::getDefaultParams()
{
- for (S32 i = 0; i < BUTTON_COUNT; i++)
- {
- mButtonsEnabled[i] = FALSE;
- mButtons[i] = NULL;
- }
- for (S32 i = 0; i < 4; i++)
- {
- mResizeBar[i] = NULL;
- mResizeHandle[i] = NULL;
- }
- initFloater( title, resizable, min_width, min_height, drag_on_left, minimizable, close_btn);
+ return LLUICtrlFactory::getDefaultParams<LLFloater>();
}
-LLFloater::LLFloater(const std::string& name, const std::string& rect_control, const std::string& title,
- BOOL resizable,
- S32 min_width,
- S32 min_height,
- BOOL drag_on_left,
- BOOL minimizable,
- BOOL close_btn,
- BOOL bordered)
-: LLPanel(name, rect_control, bordered), mAutoFocus(TRUE) // automatically take focus when opened
+//static
+void LLFloater::initClass()
{
+ // translate tooltips for floater buttons
for (S32 i = 0; i < BUTTON_COUNT; i++)
{
- mButtonsEnabled[i] = FALSE;
- mButtons[i] = NULL;
- }
- for (S32 i = 0; i < 4; i++)
- {
- mResizeBar[i] = NULL;
- mResizeHandle[i] = NULL;
- }
- initFloater( title, resizable, min_width, min_height, drag_on_left, minimizable, close_btn);
-}
-
-
-// Note: Floaters constructed from XML call init() twice!
-void LLFloater::initFloater(const std::string& title,
- BOOL resizable, S32 min_width, S32 min_height,
- BOOL drag_on_left, BOOL minimizable, BOOL close_btn)
-{
+ sButtonToolTips[i] = LLTrans::getString( sButtonToolTipsIndex[i] );
+ }
+}
+
+LLFloater::LLFloater(const LLSD& key, const LLFloater::Params& p)
+ : LLPanel(),
+ mDragHandle(NULL),
+ mTitle(p.title),
+ mShortTitle(p.short_title),
+ mSingleInstance(p.single_instance),
+ mKey(key),
+ mAutoTile(p.auto_tile),
+ mCanTearOff(p.can_tear_off),
+ mCanMinimize(p.can_minimize),
+ mCanClose(p.can_close),
+ mDragOnLeft(p.can_drag_on_left),
+ mResizable(p.can_resize),
+ mMinWidth(p.min_width),
+ mMinHeight(p.min_height),
+ mMinimized(FALSE),
+ mForeground(FALSE),
+ mFirstLook(TRUE),
+ mEditing(FALSE),
+ mButtonScale(1.0f),
+ mAutoFocus(TRUE), // automatically take focus when opened
+ mCanDock(false),
+ mDocked(false),
+ mHasBeenDraggedWhileMinimized(FALSE),
+ mPreviousMinimizedBottom(0),
+ mPreviousMinimizedLeft(0),
+ mNotificationContext(NULL)
+{
+ static LLUIColor default_background_color = LLUIColorTable::instance().getColor("FloaterDefaultBackgroundColor");
+ static LLUIColor focus_background_color = LLUIColorTable::instance().getColor("FloaterFocusBackgroundColor");
+
mHandle.bind(this);
mNotificationContext = new LLFloaterNotificationContext(getHandle());
-
- // Init function can be called more than once, so clear out old data.
- for (S32 i = 0; i < BUTTON_COUNT; i++)
- {
- mButtonsEnabled[i] = FALSE;
- if (mButtons[i] != NULL)
- {
- removeChild(mButtons[i]);
- delete mButtons[i];
- mButtons[i] = NULL;
- }
- }
- mButtonScale = 1.f;
-
- //sjb: Thia is a bit of a hack:
- BOOL need_border = hasBorder();
- // remove the border since deleteAllChildren() will also delete the border (but not clear mBorder)
- removeBorder();
- // this will delete mBorder too
- deleteAllChildren();
- // add the border back if we want it
- if (need_border)
- {
- addBorder();
- }
-
- // chrome floaters don't take focus at all
- setFocusRoot(!getIsChrome());
-
- // Reset cached pointers
- mDragHandle = NULL;
- for (S32 i = 0; i < 4; i++)
- {
- mResizeBar[i] = NULL;
- mResizeHandle[i] = NULL;
- }
- mCanTearOff = TRUE;
- mEditing = FALSE;
+ mBgColorAlpha = default_background_color;
+ mBgColorOpaque = focus_background_color;
// Clicks stop here.
setMouseOpaque(TRUE);
-
- mFirstLook = TRUE;
- mForeground = FALSE;
- mDragOnLeft = drag_on_left == TRUE;
-
+
// Floaters always draw their background, unlike every other panel.
setBackgroundVisible(TRUE);
// Floaters start not minimized. When minimized, they save their
// prior rectangle to be used on restore.
- mMinimized = FALSE;
mExpandedRect.set(0,0,0,0);
- S32 close_pad; // space to the right of close box
- S32 close_box_size; // For layout purposes, how big is the close box?
- if (close_btn)
- {
- close_box_size = LLFLOATER_CLOSE_BOX_SIZE;
- close_pad = 0;
- }
- else
- {
- close_box_size = 0;
- close_pad = 0;
- }
-
- S32 minimize_box_size;
- S32 minimize_pad;
- if (minimizable && !drag_on_left)
- {
- minimize_box_size = LLFLOATER_CLOSE_BOX_SIZE;
- minimize_pad = 0;
- }
- else
- {
- minimize_box_size = 0;
- minimize_pad = 0;
- }
-
- // Drag Handle
- // Add first so it's in the background.
-// const S32 drag_pad = 2;
- if (drag_on_left)
+ for (S32 i = 0; i < BUTTON_COUNT; i++)
{
- LLRect drag_handle_rect;
- drag_handle_rect.setOriginAndSize(
- 0, 0,
- DRAG_HANDLE_WIDTH,
- getRect().getHeight() - LLPANEL_BORDER_WIDTH - close_box_size);
- mDragHandle = new LLDragHandleLeft(std::string("drag"), drag_handle_rect, title );
+ mButtonsEnabled[i] = FALSE;
+ mButtons[i] = NULL;
}
- else // drag on top
+ for (S32 i = 0; i < 4; i++)
{
- LLRect drag_handle_rect( 0, getRect().getHeight(), getRect().getWidth(), 0 );
- mDragHandle = new LLDragHandleTop( std::string("Drag Handle"), drag_handle_rect, title );
+ mResizeBar[i] = NULL;
+ mResizeHandle[i] = NULL;
}
- addChild(mDragHandle);
-
- // Resize Handle
- mResizable = resizable;
- mMinWidth = min_width;
- mMinHeight = min_height;
+
+ initFromParams(p);
+
+ // chrome floaters don't take focus at all
+ setFocusRoot(!getIsChrome());
- if( mResizable )
- {
- // Resize bars (sides)
- const S32 RESIZE_BAR_THICKNESS = 3;
- mResizeBar[LLResizeBar::LEFT] = new LLResizeBar(
- std::string("resizebar_left"),
- this,
- LLRect( 0, getRect().getHeight(), RESIZE_BAR_THICKNESS, 0),
- min_width, S32_MAX, LLResizeBar::LEFT );
- addChild( mResizeBar[0] );
-
- mResizeBar[LLResizeBar::TOP] = new LLResizeBar(
- std::string("resizebar_top"),
- this,
- LLRect( 0, getRect().getHeight(), getRect().getWidth(), getRect().getHeight() - RESIZE_BAR_THICKNESS),
- min_height, S32_MAX, LLResizeBar::TOP );
- addChild( mResizeBar[1] );
-
- mResizeBar[LLResizeBar::RIGHT] = new LLResizeBar(
- std::string("resizebar_right"),
- this,
- LLRect( getRect().getWidth() - RESIZE_BAR_THICKNESS, getRect().getHeight(), getRect().getWidth(), 0),
- min_width, S32_MAX, LLResizeBar::RIGHT );
- addChild( mResizeBar[2] );
-
- mResizeBar[LLResizeBar::BOTTOM] = new LLResizeBar(
- std::string("resizebar_bottom"),
- this,
- LLRect( 0, RESIZE_BAR_THICKNESS, getRect().getWidth(), 0),
- min_height, S32_MAX, LLResizeBar::BOTTOM );
- addChild( mResizeBar[3] );
-
-
- // Resize handles (corners)
- mResizeHandle[0] = new LLResizeHandle(
- std::string("Resize Handle"),
- LLRect( getRect().getWidth() - RESIZE_HANDLE_WIDTH, RESIZE_HANDLE_HEIGHT, getRect().getWidth(), 0),
- min_width,
- min_height,
- LLResizeHandle::RIGHT_BOTTOM);
- addChild(mResizeHandle[0]);
-
- mResizeHandle[1] = new LLResizeHandle(
- std::string("resize"),
- LLRect( getRect().getWidth() - RESIZE_HANDLE_WIDTH, getRect().getHeight(), getRect().getWidth(), getRect().getHeight() - RESIZE_HANDLE_HEIGHT),
- min_width,
- min_height,
- LLResizeHandle::RIGHT_TOP );
- addChild(mResizeHandle[1]);
-
- mResizeHandle[2] = new LLResizeHandle( std::string("resize"),
- LLRect( 0, RESIZE_HANDLE_HEIGHT, RESIZE_HANDLE_WIDTH, 0 ),
- min_width,
- min_height,
- LLResizeHandle::LEFT_BOTTOM );
- addChild(mResizeHandle[2]);
+ initFloater();
+}
- mResizeHandle[3] = new LLResizeHandle( std::string("resize"),
- LLRect( 0, getRect().getHeight(), RESIZE_HANDLE_WIDTH, getRect().getHeight() - RESIZE_HANDLE_HEIGHT ),
- min_width,
- min_height,
- LLResizeHandle::LEFT_TOP );
- addChild(mResizeHandle[3]);
- }
+// Note: Floaters constructed from XML call init() twice!
+void LLFloater::initFloater()
+{
+ addDragHandle();
+
+ addResizeCtrls();
// Close button.
- if (close_btn)
+ if (mCanClose)
{
mButtonsEnabled[BUTTON_CLOSE] = TRUE;
}
// Minimize button only for top draggers
- if ( !drag_on_left && minimizable )
+ if ( !mDragOnLeft && mCanMinimize )
{
mButtonsEnabled[BUTTON_MINIMIZE] = TRUE;
}
- // Keep track of whether this window has ever been dragged while it
- // was minimized. If it has, we'll remember its position for the
- // next time it's minimized.
- mHasBeenDraggedWhileMinimized = FALSE;
- mPreviousMinimizedLeft = 0;
- mPreviousMinimizedBottom = 0;
+ if(mCanDock)
+ {
+ mButtonsEnabled[BUTTON_DOCK] = TRUE;
+ }
buildButtons();
- // JC - Don't do this here, because many floaters first construct themselves,
- // then show themselves. Put it in setVisibleAndFrontmost.
- // make_ui_sound("UISndWindowOpen");
-
- // RN: floaters are created in the invisible state
+ // Floaters are created in the invisible state
setVisible(FALSE);
// add self to handle->floater map
@@ -429,19 +344,137 @@ void LLFloater::initFloater(const std::string& title,
}
}
+void LLFloater::addDragHandle()
+{
+ static LLUICachedControl<S32> floater_close_box_size ("UIFloaterCloseBoxSize", 0);
+ S32 close_box_size = mCanClose ? floater_close_box_size : 0;
+
+ if (!mDragHandle)
+ {
+ if (mDragOnLeft)
+ {
+ LLDragHandleLeft::Params p;
+ p.name("drag");
+ p.follows.flags(FOLLOWS_ALL);
+ p.label(mTitle);
+ mDragHandle = LLUICtrlFactory::create<LLDragHandleLeft>(p);
+ }
+ else // drag on top
+ {
+ LLDragHandleTop::Params p;
+ p.name("Drag Handle");
+ p.follows.flags(FOLLOWS_ALL);
+ p.label(mTitle);
+ mDragHandle = LLUICtrlFactory::create<LLDragHandleTop>(p);
+ }
+ addChild(mDragHandle);
+ }
+ LLRect rect;
+ if (mDragOnLeft)
+ {
+ rect.setLeftTopAndSize(0, 0, DRAG_HANDLE_WIDTH, getRect().getHeight() - LLPANEL_BORDER_WIDTH - close_box_size);
+ }
+ else // drag on top
+ {
+ rect = getLocalRect();
+ }
+ mDragHandle->setRect(rect);
+ updateButtons();
+ applyTitle();
+}
+
+void LLFloater::addResizeCtrls()
+{
+ for (S32 i = 0; i < 4; i++)
+ {
+ if (mResizeBar[i])
+ {
+ removeChild(mResizeBar[i]);
+ delete mResizeBar[i];
+ mResizeBar[i] = NULL;
+ }
+ if (mResizeHandle[i])
+ {
+ removeChild(mResizeHandle[i]);
+ delete mResizeHandle[i];
+ mResizeHandle[i] = NULL;
+ }
+ }
+ if( !mResizable )
+ {
+ return;
+ }
+
+ // Resize bars (sides)
+ const S32 RESIZE_BAR_THICKNESS = 3;
+ LLResizeBar::Params p;
+ p.name("resizebar_left");
+ p.resizing_view(this);
+ p.rect(LLRect( 0, getRect().getHeight(), RESIZE_BAR_THICKNESS, 0));
+ p.min_size(mMinWidth);
+ p.side(LLResizeBar::LEFT);
+ mResizeBar[LLResizeBar::LEFT] = LLUICtrlFactory::create<LLResizeBar>(p);
+ addChild( mResizeBar[LLResizeBar::LEFT] );
+
+ p.name("resizebar_top");
+ p.rect(LLRect( 0, getRect().getHeight(), getRect().getWidth(), getRect().getHeight() - RESIZE_BAR_THICKNESS));
+ p.min_size(mMinHeight);
+ p.side(LLResizeBar::TOP);
+
+ mResizeBar[LLResizeBar::TOP] = LLUICtrlFactory::create<LLResizeBar>(p);
+ addChild( mResizeBar[LLResizeBar::TOP] );
+
+ p.name("resizebar_right");
+ p.rect(LLRect(getRect().getWidth() - RESIZE_BAR_THICKNESS, getRect().getHeight(), getRect().getWidth(), 0));
+ p.min_size(mMinWidth);
+ p.side(LLResizeBar::RIGHT);
+
+ mResizeBar[LLResizeBar::RIGHT] = LLUICtrlFactory::create<LLResizeBar>(p);
+ addChild( mResizeBar[LLResizeBar::RIGHT] );
+
+ p.name("resizebar_bottom");
+ p.rect(LLRect(0, RESIZE_BAR_THICKNESS, getRect().getWidth(), 0));
+ p.min_size(mMinHeight);
+ p.side(LLResizeBar::BOTTOM);
+ mResizeBar[LLResizeBar::BOTTOM] = LLUICtrlFactory::create<LLResizeBar>(p);
+ addChild( mResizeBar[LLResizeBar::BOTTOM] );
+
+ // Resize handles (corners)
+ LLResizeHandle::Params handle_p;
+ // handles must not be mouse-opaque, otherwise they block hover events
+ // to other buttons like the close box. JC
+ handle_p.mouse_opaque(false);
+ handle_p.rect(LLRect( getRect().getWidth() - RESIZE_HANDLE_WIDTH, RESIZE_HANDLE_HEIGHT, getRect().getWidth(), 0));
+ handle_p.min_width(mMinWidth);
+ handle_p.min_height(mMinHeight);
+ handle_p.corner(LLResizeHandle::RIGHT_BOTTOM);
+ mResizeHandle[0] = LLUICtrlFactory::create<LLResizeHandle>(handle_p);
+ addChild(mResizeHandle[0]);
+
+ handle_p.rect(LLRect( getRect().getWidth() - RESIZE_HANDLE_WIDTH, getRect().getHeight(), getRect().getWidth(), getRect().getHeight() - RESIZE_HANDLE_HEIGHT));
+ handle_p.corner(LLResizeHandle::RIGHT_TOP);
+ mResizeHandle[1] = LLUICtrlFactory::create<LLResizeHandle>(handle_p);
+ addChild(mResizeHandle[1]);
+
+ handle_p.rect(LLRect( 0, RESIZE_HANDLE_HEIGHT, RESIZE_HANDLE_WIDTH, 0 ));
+ handle_p.corner(LLResizeHandle::LEFT_BOTTOM);
+ mResizeHandle[2] = LLUICtrlFactory::create<LLResizeHandle>(handle_p);
+ addChild(mResizeHandle[2]);
+
+ handle_p.rect(LLRect( 0, getRect().getHeight(), RESIZE_HANDLE_WIDTH, getRect().getHeight() - RESIZE_HANDLE_HEIGHT ));
+ handle_p.corner(LLResizeHandle::LEFT_TOP);
+ mResizeHandle[3] = LLUICtrlFactory::create<LLResizeHandle>(handle_p);
+ addChild(mResizeHandle[3]);
+}
+
// virtual
LLFloater::~LLFloater()
{
+ LLFloaterReg::removeInstance(mInstanceName, mKey);
+
delete mNotificationContext;
mNotificationContext = NULL;
- control_map_t::iterator itor;
- for (itor = mFloaterControls.begin(); itor != mFloaterControls.end(); ++itor)
- {
- delete itor->second;
- }
- mFloaterControls.clear();
-
//// am I not hosted by another floater?
//if (mHostHandle.isDead())
//{
@@ -469,12 +502,31 @@ LLFloater::~LLFloater()
delete mResizeBar[i];
delete mResizeHandle[i];
}
+
+ storeRectControl();
+ setVisible(false); // We're not visible if we're destroyed
+ storeVisibilityControl();
}
+void LLFloater::storeRectControl()
+{
+ if( mRectControl.size() > 1 )
+ {
+ LLUI::sSettingGroups["floater"]->setRect( mRectControl, getRect() );
+ }
+}
+
+void LLFloater::storeVisibilityControl()
+{
+ if( !sQuitting && mVisibilityControl.size() > 1 )
+ {
+ LLUI::sSettingGroups["floater"]->setBOOL( mVisibilityControl, getVisible() );
+ }
+}
void LLFloater::setVisible( BOOL visible )
{
- LLPanel::setVisible(visible);
+ LLPanel::setVisible(visible); // calls handleVisibilityChange()
if( visible && mFirstLook )
{
mFirstLook = FALSE;
@@ -504,10 +556,25 @@ void LLFloater::setVisible( BOOL visible )
}
++dependent_it;
}
+
+ storeVisibilityControl();
+}
+
+// virtual
+void LLFloater::handleVisibilityChange ( BOOL new_visibility )
+{
+ if (new_visibility)
+ {
+ if (getHost())
+ getHost()->setFloaterFlashing(this, FALSE);
+ }
+ LLPanel::handleVisibilityChange ( new_visibility );
}
-void LLFloater::open() /* Flawfinder: ignore */
+void LLFloater::openFloater(const LLSD& key)
{
+ mKey = key; // in case we need to open ourselves again
+
if (getSoundFlags() != SILENT
// don't play open sound for hosted (tabbed) windows
&& !getHost()
@@ -525,9 +592,11 @@ void LLFloater::open() /* Flawfinder: ignore */
// only select tabs if window they are hosted in is visible
getFloaterHost()->addFloater(this, getFloaterHost()->getVisible());
}
- else if (getHost() != NULL)
+
+ if (getHost() != NULL)
{
- // already hosted
+ getHost()->setMinimized(FALSE);
+ getHost()->setVisibleAndFrontmost(mAutoFocus);
getHost()->showFloater(this);
}
else
@@ -536,11 +605,17 @@ void LLFloater::open() /* Flawfinder: ignore */
setVisibleAndFrontmost(mAutoFocus);
}
- onOpen();
+ mOpenSignal(this, key);
+ onOpen(key);
}
-void LLFloater::close(bool app_quitting)
+void LLFloater::closeFloater(bool app_quitting)
{
+ if (app_quitting)
+ {
+ LLFloater::sQuitting = true;
+ }
+
// Always unminimize before trying to close.
// Most of the time the user will never see this state.
setMinimized(FALSE);
@@ -570,7 +645,7 @@ void LLFloater::close(bool app_quitting)
if (floaterp)
{
++dependent_it;
- floaterp->close();
+ floaterp->closeFloater(app_quitting);
}
else
{
@@ -597,9 +672,28 @@ void LLFloater::close(bool app_quitting)
}
}
}
-
- // Let floater do cleanup.
- onClose(app_quitting);
+
+ // Close callback
+ mCloseSignal(this, LLSD(app_quitting));
+
+ // Hide or Destroy
+ if (mSingleInstance)
+ {
+ // Hide the instance
+ if (getHost())
+ {
+ getHost()->setVisible(FALSE);
+ }
+ else
+ {
+ setVisible(FALSE);
+ }
+ }
+ else
+ {
+ setVisible(FALSE); // hide before destroying (so handleVisibilityChange() gets called)
+ destroy();
+ }
}
}
@@ -607,6 +701,7 @@ void LLFloater::close(bool app_quitting)
void LLFloater::reshape(S32 width, S32 height, BOOL called_from_parent)
{
LLPanel::reshape(width, height, called_from_parent);
+ storeRectControl();
}
void LLFloater::releaseFocus()
@@ -616,10 +711,7 @@ void LLFloater::releaseFocus()
gFocusMgr.setTopCtrl(NULL);
}
- if( gFocusMgr.childHasKeyboardFocus( this ) )
- {
- gFocusMgr.setKeyboardFocus(NULL);
- }
+ setFocus(FALSE);
if( gFocusMgr.childHasMouseCapture( this ) )
{
@@ -664,15 +756,23 @@ void LLFloater::center()
centerWithin(gFloaterView->getRect());
}
+LLMultiFloater* LLFloater::getHost()
+{
+ return (LLMultiFloater*)mHostHandle.get();
+}
+
void LLFloater::applyRectControl()
{
- if (!getRectControl().empty())
+ if (mRectControl.size() > 1)
{
- const LLRect& rect = LLUI::sConfigGroup->getRect(getRectControl());
- translate( rect.mLeft - getRect().mLeft, rect.mBottom - getRect().mBottom);
- if (mResizable)
+ const LLRect& rect = LLUI::sSettingGroups["floater"]->getRect(mRectControl);
+ if (rect.getWidth() > 0 && rect.getHeight() > 0)
{
- reshape(llmax(mMinWidth, rect.getWidth()), llmax(mMinHeight, rect.getHeight()));
+ translate( rect.mLeft - getRect().mLeft, rect.mBottom - getRect().mBottom);
+ if (mResizable)
+ {
+ reshape(llmax(mMinWidth, rect.getWidth()), llmax(mMinHeight, rect.getHeight()));
+ }
}
}
}
@@ -763,7 +863,7 @@ BOOL LLFloater::canSnapTo(const LLView* other_view)
return LLPanel::canSnapTo(other_view);
}
-void LLFloater::snappedTo(const LLView* snap_view)
+void LLFloater::setSnappedTo(const LLView* snap_view)
{
if (!snap_view || snap_view == getParent())
{
@@ -778,10 +878,10 @@ void LLFloater::snappedTo(const LLView* snap_view)
}
}
-void LLFloater::userSetShape(const LLRect& new_rect)
+void LLFloater::handleReshape(const LLRect& new_rect, bool by_user)
{
const LLRect old_rect = getRect();
- LLView::userSetShape(new_rect);
+ LLView::handleReshape(new_rect, by_user);
// if not minimized, adjust all snapped dependents to new shape
if (!isMinimized())
@@ -816,7 +916,7 @@ void LLFloater::userSetShape(const LLRect& new_rect)
delta_y += new_rect.mBottom - old_rect.mBottom;
dependent_rect.translate(delta_x, delta_y);
- floaterp->userSetShape(dependent_rect);
+ floaterp->setShape(dependent_rect, by_user);
}
}
}
@@ -834,6 +934,9 @@ void LLFloater::userSetShape(const LLRect& new_rect)
void LLFloater::setMinimized(BOOL minimize)
{
+ static LLUICachedControl<S32> floater_header_size ("UIFloaterHeaderSize", 0);
+ static LLUICachedControl<S32> minimized_width ("UIMinimizedWidth", 0);
+
if (minimize == mMinimized) return;
if (minimize)
@@ -902,7 +1005,7 @@ void LLFloater::setMinimized(BOOL minimize)
mMinimized = TRUE;
// Reshape *after* setting mMinimized
- reshape( MINIMIZED_WIDTH, LLFLOATER_HEADER_SIZE, TRUE);
+ reshape( minimized_width, floater_header_size, TRUE);
}
else
{
@@ -968,7 +1071,7 @@ void LLFloater::setFocus( BOOL b )
}
LLUICtrl* last_focus = gFocusMgr.getLastFocusForGroup(this);
// a descendent already has focus
- BOOL child_had_focus = gFocusMgr.childHasKeyboardFocus(this);
+ BOOL child_had_focus = hasFocus();
// give focus to first valid descendent
LLPanel::setFocus(b);
@@ -996,6 +1099,13 @@ void LLFloater::setFocus( BOOL b )
}
// virtual
+void LLFloater::setRect(const LLRect &rect)
+{
+ LLPanel::setRect(rect);
+ addDragHandle(); // re-add drag handle, sized based on rect
+}
+
+// virtual
void LLFloater::setIsChrome(BOOL is_chrome)
{
// chrome floaters don't take focus at all
@@ -1253,6 +1363,36 @@ void LLFloater::setFrontmost(BOOL take_focus)
}
}
+void LLFloater::setCanDock(bool b)
+{
+ if(b != mCanDock)
+ {
+ mCanDock = b;
+ if(mCanDock)
+ {
+ mButtonsEnabled[BUTTON_DOCK] = !mDocked;
+ mButtonsEnabled[BUTTON_UNDOCK] = mDocked;
+ }
+ else
+ {
+ mButtonsEnabled[BUTTON_DOCK] = FALSE;
+ mButtonsEnabled[BUTTON_UNDOCK] = FALSE;
+ }
+ }
+ updateButtons();
+}
+
+void LLFloater::setDocked(bool docked, bool pop_on_undock)
+{
+ if(docked != mDocked && mCanDock)
+ {
+ mDocked = docked;
+ mButtonsEnabled[BUTTON_DOCK] = !mDocked;
+ mButtonsEnabled[BUTTON_UNDOCK] = mDocked;
+ updateButtons();
+ }
+}
+
//static
void LLFloater::setEditModeEnabled(BOOL enable)
{
@@ -1276,19 +1416,18 @@ void LLFloater::setEditModeEnabled(BOOL enable)
// static
-void LLFloater::onClickMinimize(void *userdata)
+void LLFloater::onClickMinimize(LLFloater* self)
{
- LLFloater* self = (LLFloater*) userdata;
- if (!self) return;
-
+ if (!self)
+ return;
self->setMinimized( !self->isMinimized() );
}
-void LLFloater::onClickTearOff(void *userdata)
+void LLFloater::onClickTearOff(LLFloater* self)
{
- LLFloater* self = (LLFloater*) userdata;
- if (!self) return;
-
+ static LLUICachedControl<S32> floater_header_size ("UIFloaterHeaderSize", 0);
+ if (!self)
+ return;
LLMultiFloater* host_floater = self->getHost();
if (host_floater) //Tear off
{
@@ -1297,12 +1436,12 @@ void LLFloater::onClickTearOff(void *userdata)
// reparent to floater view
gFloaterView->addChild(self);
- self->open(); /* Flawfinder: ignore */
+ self->openFloater(self->getKey());
// only force position for floaters that don't have that data saved
- if (self->getRectControl().empty())
+ if (self->mRectControl.size() <= 1)
{
- new_rect.setLeftTopAndSize(host_floater->getRect().mLeft + 5, host_floater->getRect().mTop - LLFLOATER_HEADER_SIZE - 5, self->getRect().getWidth(), self->getRect().getHeight());
+ new_rect.setLeftTopAndSize(host_floater->getRect().mLeft + 5, host_floater->getRect().mTop - floater_header_size - 5, self->getRect().getWidth(), self->getRect().getHeight());
self->setRect(new_rect);
}
gFloaterView->adjustToFitScreen(self, FALSE);
@@ -1317,20 +1456,28 @@ void LLFloater::onClickTearOff(void *userdata)
self->setMinimized(FALSE); // to reenable minimize button if it was minimized
new_host->showFloater(self);
// make sure host is visible
- new_host->open();
+ new_host->openFloater(new_host->getKey());
}
}
}
// static
-void LLFloater::onClickEdit(void *userdata)
+void LLFloater::onClickEdit(LLFloater* self)
{
- LLFloater* self = (LLFloater*) userdata;
- if (!self) return;
-
+ if (!self)
+ return;
self->mEditing = self->mEditing ? FALSE : TRUE;
}
+// static
+void LLFloater::onClickDock(LLFloater* self)
+{
+ if(self && self->mCanDock)
+ {
+ self->setDocked(!self->mDocked, true);
+ }
+}
+
// static
LLFloater* LLFloater::getClosableFloaterFromFocus()
{
@@ -1373,7 +1520,7 @@ void LLFloater::closeFocusedFloater()
LLFloater* floater_to_close = LLFloater::getClosableFloaterFromFocus();
if(floater_to_close)
{
- floater_to_close->close();
+ floater_to_close->closeFloater();
}
// if nothing took focus after closing focused floater
@@ -1388,12 +1535,11 @@ void LLFloater::closeFocusedFloater()
// static
-void LLFloater::onClickClose( void* userdata )
+void LLFloater::onClickClose( LLFloater* self )
{
- LLFloater* self = (LLFloater*) userdata;
- if (!self) return;
-
- self->close();
+ if (!self)
+ return;
+ self->closeFloater(false);
}
@@ -1408,8 +1554,11 @@ void LLFloater::draw()
S32 right = getRect().getWidth() - LLPANEL_BORDER_WIDTH;
S32 bottom = LLPANEL_BORDER_WIDTH;
- LLColor4 shadow_color = LLUI::sColorsGroup->getColor("ColorDropShadow");
- F32 shadow_offset = (F32)LLUI::sConfigGroup->getS32("DropShadowFloater");
+ static LLUICachedControl<S32> shadow_offset_S32 ("DropShadowFloater", 0);
+ static LLUIColor shadow_color_cached = LLUIColorTable::instance().getColor("ColorDropShadow");
+ LLColor4 shadow_color = shadow_color_cached;
+ F32 shadow_offset = (F32)shadow_offset_S32;
+
if (!isBackgroundOpaque())
{
shadow_offset *= 0.2f;
@@ -1422,20 +1571,21 @@ void LLFloater::draw()
// No transparent windows in simple UI
if (isBackgroundOpaque())
{
- gl_rect_2d( left, top, right, bottom, getBackgroundColor() );
+ gl_rect_2d( left, top, right, bottom, mBgColorOpaque );
}
else
{
- gl_rect_2d( left, top, right, bottom, getTransparentColor() );
+ gl_rect_2d( left, top, right, bottom, mBgColorAlpha );
}
if(gFocusMgr.childHasKeyboardFocus(this) && !getIsChrome() && !getCurrentTitle().empty())
{
+ static LLUIColor titlebar_focus_color = LLUIColorTable::instance().getColor("TitleBarFocusColor");
// draw highlight on title bar to indicate focus. RDW
- const LLFontGL* font = LLResMgr::getInstance()->getRes( LLFONT_SANSSERIF );
+ const LLFontGL* font = LLFontGL::getFontSansSerif();
LLRect r = getRect();
gl_rect_2d_offset_local(0, r.getHeight(), r.getWidth(), r.getHeight() - (S32)font->getLineHeight() - 1,
- LLUI::sColorsGroup->getColor("TitleBarFocusColor"), 0, TRUE);
+ titlebar_focus_color, 0, TRUE);
}
}
@@ -1445,9 +1595,9 @@ void LLFloater::draw()
{
if (hasFocus() && getDefaultButton()->getEnabled())
{
- LLUICtrl* focus_ctrl = gFocusMgr.getKeyboardFocus();
+ LLFocusableElement* focus_ctrl = gFocusMgr.getKeyboardFocus();
// is this button a direct descendent and not a nested widget (e.g. checkbox)?
- BOOL focus_is_child_button = dynamic_cast<LLButton*>(focus_ctrl) != NULL && focus_ctrl->getParent() == this;
+ BOOL focus_is_child_button = dynamic_cast<LLButton*>(focus_ctrl) != NULL && dynamic_cast<LLButton*>(focus_ctrl)->getParent() == this;
// only enable default button when current focus is not a button
getDefaultButton()->setBorderEnabled(!focus_is_child_button);
}
@@ -1467,7 +1617,7 @@ void LLFloater::draw()
else
{
// draw children
- LLView* focused_child = gFocusMgr.getKeyboardFocus();
+ LLView* focused_child = dynamic_cast<LLView*>(gFocusMgr.getKeyboardFocus());
BOOL focused_child_visible = FALSE;
if (focused_child && focused_child->getParent() == this)
{
@@ -1489,8 +1639,10 @@ void LLFloater::draw()
{
// add in a border to improve spacialized visual aclarity ;)
// use lines instead of gl_rect_2d so we can round the edges as per james' recommendation
+ static LLUIColor focus_border_color = LLUIColorTable::instance().getColor("FloaterFocusBorderColor");
+ static LLUIColor unfocus_border_color = LLUIColorTable::instance().getColor("FloaterUnfocusBorderColor");
LLUI::setLineWidth(1.5f);
- LLColor4 outlineColor = gFocusMgr.childHasKeyboardFocus(this) ? LLUI::sColorsGroup->getColor("FloaterFocusBorderColor") : LLUI::sColorsGroup->getColor("FloaterUnfocusBorderColor");
+ LLColor4 outlineColor = gFocusMgr.childHasKeyboardFocus(this) ? focus_border_color : unfocus_border_color;
gl_rect_2d_offset_local(0, getRect().getHeight() + 1, getRect().getWidth() + 1, 0, outlineColor, -LLPANEL_BORDER_WIDTH, FALSE);
LLUI::setLineWidth(1.f);
}
@@ -1511,6 +1663,7 @@ void LLFloater::setCanMinimize(BOOL can_minimize)
{
// if removing minimize/restore button programmatically,
// go ahead and unminimize floater
+ mCanMinimize = can_minimize;
if (!can_minimize)
{
setMinimized(FALSE);
@@ -1524,6 +1677,7 @@ void LLFloater::setCanMinimize(BOOL can_minimize)
void LLFloater::setCanClose(BOOL can_close)
{
+ mCanClose = can_close;
mButtonsEnabled[BUTTON_CLOSE] = can_close;
updateButtons();
@@ -1538,83 +1692,10 @@ void LLFloater::setCanTearOff(BOOL can_tear_off)
}
-void LLFloater::setCanResize(BOOL can_resize)
+void LLFloater::setCanResize(BOOL can_resize)
{
- if (mResizable && !can_resize)
- {
- for (S32 i = 0; i < 4; i++)
- {
- removeChild(mResizeBar[i], TRUE);
- mResizeBar[i] = NULL;
-
- removeChild(mResizeHandle[i], TRUE);
- mResizeHandle[i] = NULL;
- }
- }
- else if (!mResizable && can_resize)
- {
- // Resize bars (sides)
- const S32 RESIZE_BAR_THICKNESS = 3;
- mResizeBar[0] = new LLResizeBar(
- std::string("resizebar_left"),
- this,
- LLRect( 0, getRect().getHeight(), RESIZE_BAR_THICKNESS, 0),
- mMinWidth, S32_MAX, LLResizeBar::LEFT );
- addChild( mResizeBar[0] );
-
- mResizeBar[1] = new LLResizeBar(
- std::string("resizebar_top"),
- this,
- LLRect( 0, getRect().getHeight(), getRect().getWidth(), getRect().getHeight() - RESIZE_BAR_THICKNESS),
- mMinHeight, S32_MAX, LLResizeBar::TOP );
- addChild( mResizeBar[1] );
-
- mResizeBar[2] = new LLResizeBar(
- std::string("resizebar_right"),
- this,
- LLRect( getRect().getWidth() - RESIZE_BAR_THICKNESS, getRect().getHeight(), getRect().getWidth(), 0),
- mMinWidth, S32_MAX, LLResizeBar::RIGHT );
- addChild( mResizeBar[2] );
-
- mResizeBar[3] = new LLResizeBar(
- std::string("resizebar_bottom"),
- this,
- LLRect( 0, RESIZE_BAR_THICKNESS, getRect().getWidth(), 0),
- mMinHeight, S32_MAX, LLResizeBar::BOTTOM );
- addChild( mResizeBar[3] );
-
-
- // Resize handles (corners)
- mResizeHandle[0] = new LLResizeHandle(
- std::string("Resize Handle"),
- LLRect( getRect().getWidth() - RESIZE_HANDLE_WIDTH, RESIZE_HANDLE_HEIGHT, getRect().getWidth(), 0),
- mMinWidth,
- mMinHeight,
- LLResizeHandle::RIGHT_BOTTOM);
- addChild(mResizeHandle[0]);
-
- mResizeHandle[1] = new LLResizeHandle( std::string("resize"),
- LLRect( getRect().getWidth() - RESIZE_HANDLE_WIDTH, getRect().getHeight(), getRect().getWidth(), getRect().getHeight() - RESIZE_HANDLE_HEIGHT),
- mMinWidth,
- mMinHeight,
- LLResizeHandle::RIGHT_TOP );
- addChild(mResizeHandle[1]);
-
- mResizeHandle[2] = new LLResizeHandle( std::string("resize"),
- LLRect( 0, RESIZE_HANDLE_HEIGHT, RESIZE_HANDLE_WIDTH, 0 ),
- mMinWidth,
- mMinHeight,
- LLResizeHandle::LEFT_BOTTOM );
- addChild(mResizeHandle[2]);
-
- mResizeHandle[3] = new LLResizeHandle( std::string("resize"),
- LLRect( 0, getRect().getHeight(), RESIZE_HANDLE_WIDTH, getRect().getHeight() - RESIZE_HANDLE_HEIGHT ),
- mMinWidth,
- mMinHeight,
- LLResizeHandle::LEFT_TOP );
- addChild(mResizeHandle[3]);
- }
mResizable = can_resize;
+ addResizeCtrls();
}
void LLFloater::setCanDrag(BOOL can_drag)
@@ -1633,6 +1714,8 @@ void LLFloater::setCanDrag(BOOL can_drag)
void LLFloater::updateButtons()
{
+ static LLUICachedControl<S32> floater_close_box_size ("UIFloaterCloseBoxSize", 0);
+ static LLUICachedControl<S32> close_box_from_top ("UICloseBoxFromTop", 0);
S32 button_count = 0;
for (S32 i = 0; i < BUTTON_COUNT; i++)
{
@@ -1652,17 +1735,17 @@ void LLFloater::updateButtons()
{
btn_rect.setLeftTopAndSize(
LLPANEL_BORDER_WIDTH,
- getRect().getHeight() - CLOSE_BOX_FROM_TOP - (LLFLOATER_CLOSE_BOX_SIZE + 1) * button_count,
- llround((F32)LLFLOATER_CLOSE_BOX_SIZE * mButtonScale),
- llround((F32)LLFLOATER_CLOSE_BOX_SIZE * mButtonScale));
+ getRect().getHeight() - close_box_from_top - (floater_close_box_size + 1) * button_count,
+ llround((F32)floater_close_box_size * mButtonScale),
+ llround((F32)floater_close_box_size * mButtonScale));
}
else
{
btn_rect.setLeftTopAndSize(
- getRect().getWidth() - LLPANEL_BORDER_WIDTH - (LLFLOATER_CLOSE_BOX_SIZE + 1) * button_count,
- getRect().getHeight() - CLOSE_BOX_FROM_TOP,
- llround((F32)LLFLOATER_CLOSE_BOX_SIZE * mButtonScale),
- llround((F32)LLFLOATER_CLOSE_BOX_SIZE * mButtonScale));
+ getRect().getWidth() - LLPANEL_BORDER_WIDTH - (floater_close_box_size + 1) * button_count,
+ getRect().getHeight() - close_box_from_top,
+ llround((F32)floater_close_box_size * mButtonScale),
+ llround((F32)floater_close_box_size * mButtonScale));
}
mButtons[i]->setRect(btn_rect);
@@ -1676,50 +1759,66 @@ void LLFloater::updateButtons()
}
}
if (mDragHandle)
- mDragHandle->setMaxTitleWidth(getRect().getWidth() - (button_count * (LLFLOATER_CLOSE_BOX_SIZE + 1)));
+ mDragHandle->setMaxTitleWidth(getRect().getWidth() - (button_count * (floater_close_box_size + 1)));
}
void LLFloater::buildButtons()
{
+ static LLUICachedControl<S32> floater_close_box_size ("UIFloaterCloseBoxSize", 0);
+ static LLUICachedControl<S32> close_box_from_top ("UICloseBoxFromTop", 0);
for (S32 i = 0; i < BUTTON_COUNT; i++)
{
+ if (mButtons[i])
+ {
+ removeChild(mButtons[i]);
+ delete mButtons[i];
+ mButtons[i] = NULL;
+ }
+
LLRect btn_rect;
if (mDragOnLeft)
{
btn_rect.setLeftTopAndSize(
LLPANEL_BORDER_WIDTH,
- getRect().getHeight() - CLOSE_BOX_FROM_TOP - (LLFLOATER_CLOSE_BOX_SIZE + 1) * (i + 1),
- llround(LLFLOATER_CLOSE_BOX_SIZE * mButtonScale),
- llround(LLFLOATER_CLOSE_BOX_SIZE * mButtonScale));
+ getRect().getHeight() - close_box_from_top - (floater_close_box_size + 1) * (i + 1),
+ llround(floater_close_box_size * mButtonScale),
+ llround(floater_close_box_size * mButtonScale));
}
else
{
btn_rect.setLeftTopAndSize(
- getRect().getWidth() - LLPANEL_BORDER_WIDTH - (LLFLOATER_CLOSE_BOX_SIZE + 1) * (i + 1),
- getRect().getHeight() - CLOSE_BOX_FROM_TOP,
- llround(LLFLOATER_CLOSE_BOX_SIZE * mButtonScale),
- llround(LLFLOATER_CLOSE_BOX_SIZE * mButtonScale));
- }
-
- LLButton* buttonp = new LLButton(
- sButtonNames[i],
- btn_rect,
- sButtonActiveImageNames[i],
- sButtonPressedImageNames[i],
- LLStringUtil::null,
- sButtonCallbacks[i],
- this,
- LLFontGL::getFontSansSerif());
-
- buttonp->setTabStop(FALSE);
- buttonp->setFollowsTop();
- buttonp->setFollowsRight();
- buttonp->setToolTip( sButtonToolTips[i] );
- buttonp->setImageColor(LLUI::sColorsGroup->getColor("FloaterButtonImageColor"));
- buttonp->setHoverImages(sButtonPressedImageNames[i],
- sButtonPressedImageNames[i]);
- buttonp->setScaleImage(TRUE);
- buttonp->setSaveToXML(false);
+ getRect().getWidth() - LLPANEL_BORDER_WIDTH - (floater_close_box_size + 1) * (i + 1),
+ getRect().getHeight() - close_box_from_top,
+ llround(floater_close_box_size * mButtonScale),
+ llround(floater_close_box_size * mButtonScale));
+ }
+
+ LLButton::Params p;
+ p.name(sButtonNames[i]);
+ p.rect(btn_rect);
+ p.label("");
+ p.image_unselected.name(sButtonActiveImageNames[i]);
+ // Selected, no matter if hovered or not, is "pressed"
+ p.image_selected.name(sButtonPressedImageNames[i]);
+ p.image_hover_selected.name(sButtonPressedImageNames[i]);
+ // Empty string means programmatic glow effect, achieved by
+ // not setting explicit image.
+ if (sButtonHoveredImageNames[i].empty())
+ {
+ // These icons are really small, need glow amount increased
+ p.hover_glow_amount( 0.22f );
+ }
+ else
+ {
+ p.image_hover_unselected.name(sButtonHoveredImageNames[i]);
+ }
+ p.click_callback.function(boost::bind(sButtonCallbacks[i], this));
+ p.tab_stop(false);
+ p.follows.flags(FOLLOWS_TOP|FOLLOWS_RIGHT);
+ p.tool_tip(sButtonToolTips[i]);
+ p.scale_image(true);
+
+ LLButton* buttonp = LLUICtrlFactory::create<LLButton>(p);
addChild(buttonp);
mButtons[i] = buttonp;
}
@@ -1730,13 +1829,12 @@ void LLFloater::buildButtons()
/////////////////////////////////////////////////////
// LLFloaterView
-LLFloaterView::LLFloaterView( const std::string& name, const LLRect& rect )
-: LLUICtrl( name, rect, FALSE, NULL, NULL, FOLLOWS_ALL ),
+LLFloaterView::LLFloaterView (const Params& p)
+: LLUICtrl (p),
mFocusCycleMode(FALSE),
mSnapOffsetBottom(0)
+ ,mSnapOffsetRight(0)
{
- setTabStop(FALSE);
- resetStartingFloaterPosition();
}
// By default, adjust vertical.
@@ -1830,69 +1928,6 @@ void LLFloaterView::restoreAll()
}
-void LLFloaterView::getNewFloaterPosition(S32* left,S32* top)
-{
- // Workaround: mRect may change between when this object is created and the first time it is used.
- static BOOL first = TRUE;
- if( first )
- {
- resetStartingFloaterPosition();
- first = FALSE;
- }
-
- const S32 FLOATER_PAD = 16;
- LLCoordWindow window_size;
- getWindow()->getSize(&window_size);
- LLRect full_window(0, window_size.mY, window_size.mX, 0);
- LLRect floater_creation_rect(
- 160,
- full_window.getHeight() - 2 * MENU_BAR_HEIGHT,
- full_window.getWidth() * 2 / 3,
- 130 );
- floater_creation_rect.stretch( -FLOATER_PAD );
-
- *left = mNextLeft;
- *top = mNextTop;
-
- const S32 STEP = 25;
- S32 bottom = floater_creation_rect.mBottom + 2 * STEP;
- S32 right = floater_creation_rect.mRight - 4 * STEP;
-
- mNextTop -= STEP;
- mNextLeft += STEP;
-
- if( (mNextTop < bottom ) || (mNextLeft > right) )
- {
- mColumn++;
- mNextTop = floater_creation_rect.mTop;
- mNextLeft = STEP * mColumn;
-
- if( (mNextTop < bottom) || (mNextLeft > right) )
- {
- // Advancing the column didn't work, so start back at the beginning
- resetStartingFloaterPosition();
- }
- }
-}
-
-void LLFloaterView::resetStartingFloaterPosition()
-{
- const S32 FLOATER_PAD = 16;
- LLCoordWindow window_size;
- getWindow()->getSize(&window_size);
- LLRect full_window(0, window_size.mY, window_size.mX, 0);
- LLRect floater_creation_rect(
- 160,
- full_window.getHeight() - 2 * MENU_BAR_HEIGHT,
- full_window.getWidth() * 2 / 3,
- 130 );
- floater_creation_rect.stretch( -FLOATER_PAD );
-
- mNextLeft = floater_creation_rect.mLeft;
- mNextTop = floater_creation_rect.mTop;
- mColumn = 0;
-}
-
LLRect LLFloaterView::findNeighboringPosition( LLFloater* reference_floater, LLFloater* neighbor )
{
LLRect base_rect = reference_floater->getRect();
@@ -1910,7 +1945,7 @@ LLRect LLFloaterView::findNeighboringPosition( LLFloater* reference_floater, LLF
if (sibling &&
sibling != neighbor &&
sibling->getVisible() &&
- expanded_base_rect.rectInRect(&sibling->getRect()))
+ expanded_base_rect.overlaps(sibling->getRect()))
{
base_rect.unionWith(sibling->getRect());
}
@@ -2104,15 +2139,17 @@ void LLFloaterView::focusFrontFloater()
void LLFloaterView::getMinimizePosition(S32 *left, S32 *bottom)
{
+ static LLUICachedControl<S32> floater_header_size ("UIFloaterHeaderSize", 0);
+ static LLUICachedControl<S32> minimized_width ("UIMinimizedWidth", 0);
S32 col = 0;
LLRect snap_rect_local = getLocalSnapRect();
for(S32 row = snap_rect_local.mBottom;
- row < snap_rect_local.getHeight() - LLFLOATER_HEADER_SIZE;
- row += LLFLOATER_HEADER_SIZE ) //loop rows
+ row < snap_rect_local.getHeight() - floater_header_size;
+ row += floater_header_size ) //loop rows
{
for(col = snap_rect_local.mLeft;
- col < snap_rect_local.getWidth() - MINIMIZED_WIDTH;
- col += MINIMIZED_WIDTH)
+ col < snap_rect_local.getWidth() - minimized_width;
+ col += minimized_width)
{
bool foundGap = TRUE;
for(child_list_const_iter_t child_it = getChildList()->begin();
@@ -2124,10 +2161,10 @@ void LLFloaterView::getMinimizePosition(S32 *left, S32 *bottom)
if(floater->isMinimized())
{
LLRect r = floater->getRect();
- if((r.mBottom < (row + LLFLOATER_HEADER_SIZE))
- && (r.mBottom > (row - LLFLOATER_HEADER_SIZE))
- && (r.mLeft < (col + MINIMIZED_WIDTH))
- && (r.mLeft > (col - MINIMIZED_WIDTH)))
+ if((r.mBottom < (row + floater_header_size))
+ && (r.mBottom > (row - floater_header_size))
+ && (r.mLeft < (col + minimized_width))
+ && (r.mLeft > (col - minimized_width)))
{
// needs the check for off grid. can't drag,
// but window resize makes them off
@@ -2179,7 +2216,7 @@ void LLFloaterView::closeAllChildren(bool app_quitting)
// dialogs to appear.
if (floaterp->canClose() && !floaterp->isDead())
{
- floaterp->close(app_quitting);
+ floaterp->closeFloater(app_quitting);
}
}
}
@@ -2202,14 +2239,13 @@ BOOL LLFloaterView::allChildrenClosed()
return true;
}
-
void LLFloaterView::refresh()
{
// Constrain children to be entirely on the screen
for ( child_list_const_iter_t child_it = getChildList()->begin(); child_it != getChildList()->end(); ++child_it)
{
- LLFloater* floaterp = (LLFloater*)*child_it;
- if( floaterp->getVisible() )
+ LLFloater* floaterp = dynamic_cast<LLFloater*>(*child_it);
+ if (floaterp && floaterp->getVisible() )
{
// minimized floaters are kept fully onscreen
adjustToFitScreen(floaterp, !floaterp->isMinimized());
@@ -2229,7 +2265,8 @@ void LLFloaterView::adjustToFitScreen(LLFloater* floater, BOOL allow_partial_out
// convert to local coordinate frame
LLRect snap_rect_local = getLocalSnapRect();
- if( floater->isResizable() )
+ // only automatically resize non-minimized, resizable floaters
+ if( floater->isResizable() && !floater->isMinimized() )
{
LLRect view_rect = floater->getRect();
S32 old_width = view_rect.getWidth();
@@ -2302,11 +2339,12 @@ LLRect LLFloaterView::getSnapRect() const
{
LLRect snap_rect = getRect();
snap_rect.mBottom += mSnapOffsetBottom;
+ snap_rect.mRight -= mSnapOffsetRight;
return snap_rect;
}
-LLFloater *LLFloaterView::getFocusedFloater()
+LLFloater *LLFloaterView::getFocusedFloater() const
{
for ( child_list_const_iter_t child_it = getChildList()->begin(); child_it != getChildList()->end(); ++child_it)
{
@@ -2319,7 +2357,7 @@ LLFloater *LLFloaterView::getFocusedFloater()
return NULL;
}
-LLFloater *LLFloaterView::getFrontmost()
+LLFloater *LLFloaterView::getFrontmost() const
{
for ( child_list_const_iter_t child_it = getChildList()->begin(); child_it != getChildList()->end(); ++child_it)
{
@@ -2332,7 +2370,7 @@ LLFloater *LLFloaterView::getFrontmost()
return NULL;
}
-LLFloater *LLFloaterView::getBackmost()
+LLFloater *LLFloaterView::getBackmost() const
{
LLFloater* back_most = NULL;
for ( child_list_const_iter_t child_it = getChildList()->begin(); child_it != getChildList()->end(); ++child_it)
@@ -2348,18 +2386,51 @@ LLFloater *LLFloaterView::getBackmost()
void LLFloaterView::syncFloaterTabOrder()
{
- // bring focused floater to front
- for ( child_list_const_reverse_iter_t child_it = getChildList()->rbegin(); child_it != getChildList()->rend(); ++child_it)
+ // look for a visible modal dialog, starting from first (should be only one)
+ LLModalDialog* modal_dialog = NULL;
+ for ( child_list_const_iter_t child_it = getChildList()->begin(); child_it != getChildList()->end(); ++child_it)
{
- LLFloater* floaterp = (LLFloater*)*child_it;
- if (gFocusMgr.childHasKeyboardFocus(floaterp))
+ LLModalDialog* dialog = dynamic_cast<LLModalDialog*>(*child_it);
+ if (dialog && dialog->isModal() && dialog->getVisible())
{
- bringToFront(floaterp, FALSE);
+ modal_dialog = dialog;
break;
}
}
- // then sync draw order to tab order
+ if (modal_dialog)
+ {
+ // If we have a visible modal dialog, make sure that it has focus
+ if( gFocusMgr.getTopCtrl() != modal_dialog )
+ {
+ gFocusMgr.setTopCtrl( modal_dialog );
+ }
+
+ if( !gFocusMgr.childHasKeyboardFocus( modal_dialog ) )
+ {
+ modal_dialog->setFocus(TRUE);
+ }
+
+ if( !gFocusMgr.childHasMouseCapture( modal_dialog ) )
+ {
+ gFocusMgr.setMouseCapture( modal_dialog );
+ }
+ }
+ else
+ {
+ // otherwise, make sure the focused floater is in the front of the child list
+ for ( child_list_const_reverse_iter_t child_it = getChildList()->rbegin(); child_it != getChildList()->rend(); ++child_it)
+ {
+ LLFloater* floaterp = (LLFloater*)*child_it;
+ if (gFocusMgr.childHasKeyboardFocus(floaterp))
+ {
+ bringToFront(floaterp, FALSE);
+ break;
+ }
+ }
+ }
+
+ // sync draw order to tab order
for ( child_list_const_reverse_iter_t child_it = getChildList()->rbegin(); child_it != getChildList()->rend(); ++child_it)
{
LLFloater* floaterp = (LLFloater*)*child_it;
@@ -2367,7 +2438,7 @@ void LLFloaterView::syncFloaterTabOrder()
}
}
-LLFloater* LLFloaterView::getParentFloater(LLView* viewp)
+LLFloater* LLFloaterView::getParentFloater(LLView* viewp) const
{
LLView* parentp = viewp->getParent();
@@ -2426,641 +2497,149 @@ void LLFloaterView::popVisibleAll(const skip_list_t& skip_list)
}
}
-//
-// LLMultiFloater
-//
-
-LLMultiFloater::LLMultiFloater() :
- mTabContainer(NULL),
- mTabPos(LLTabContainer::TOP),
- mAutoResize(TRUE),
- mOrigMinWidth(0),
- mOrigMinHeight(0)
-{
-
-}
-
-LLMultiFloater::LLMultiFloater(LLTabContainer::TabPosition tab_pos) :
- mTabContainer(NULL),
- mTabPos(tab_pos),
- mAutoResize(TRUE),
- mOrigMinWidth(0),
- mOrigMinHeight(0)
-{
-
-}
-
-LLMultiFloater::LLMultiFloater(const std::string &name) :
- LLFloater(name),
- mTabContainer(NULL),
- mTabPos(LLTabContainer::TOP),
- mAutoResize(FALSE),
- mOrigMinWidth(0),
- mOrigMinHeight(0)
-{
-}
-
-LLMultiFloater::LLMultiFloater(
- const std::string& name,
- const LLRect& rect,
- LLTabContainer::TabPosition tab_pos,
- BOOL auto_resize) :
- LLFloater(name, rect, name),
- mTabContainer(NULL),
- mTabPos(LLTabContainer::TOP),
- mAutoResize(auto_resize),
- mOrigMinWidth(0),
- mOrigMinHeight(0)
-{
- mTabContainer = new LLTabContainer(std::string("Preview Tabs"),
- LLRect(LLPANEL_BORDER_WIDTH, getRect().getHeight() - LLFLOATER_HEADER_SIZE, getRect().getWidth() - LLPANEL_BORDER_WIDTH, 0),
- mTabPos,
- FALSE,
- FALSE);
- mTabContainer->setFollowsAll();
- if (isResizable())
- {
- mTabContainer->setRightTabBtnOffset(RESIZE_HANDLE_WIDTH);
- }
-
- addChild(mTabContainer);
-}
-
-LLMultiFloater::LLMultiFloater(
- const std::string& name,
- const std::string& rect_control,
- LLTabContainer::TabPosition tab_pos,
- BOOL auto_resize) :
- LLFloater(name, rect_control, name),
- mTabContainer(NULL),
- mTabPos(tab_pos),
- mAutoResize(auto_resize),
- mOrigMinWidth(0),
- mOrigMinHeight(0)
-{
- mTabContainer = new LLTabContainer(std::string("Preview Tabs"),
- LLRect(LLPANEL_BORDER_WIDTH, getRect().getHeight() - LLFLOATER_HEADER_SIZE, getRect().getWidth() - LLPANEL_BORDER_WIDTH, 0),
- mTabPos,
- FALSE,
- FALSE);
- mTabContainer->setFollowsAll();
- if (isResizable() && mTabPos == LLTabContainer::BOTTOM)
- {
- mTabContainer->setRightTabBtnOffset(RESIZE_HANDLE_WIDTH);
- }
-
- addChild(mTabContainer);
-
-}
-
-
-void LLMultiFloater::open() /* Flawfinder: ignore */
-{
- if (mTabContainer->getTabCount() > 0)
- {
- LLFloater::open(); /* Flawfinder: ignore */
- }
- else
- {
- // for now, don't allow multifloaters
- // without any child floaters
- close();
- }
-}
-
-void LLMultiFloater::onClose(bool app_quitting)
-{
- if(closeAllFloaters() == TRUE)
- {
- LLFloater::onClose(app_quitting);
- }//else not all tabs could be closed...
-}
-
-void LLMultiFloater::draw()
-{
- if (mTabContainer->getTabCount() == 0)
- {
- //RN: could this potentially crash in draw hierarchy?
- close();
- }
- else
- {
- for (S32 i = 0; i < mTabContainer->getTabCount(); i++)
- {
- LLFloater* floaterp = (LLFloater*)mTabContainer->getPanelByIndex(i);
- if (floaterp->getShortTitle() != mTabContainer->getPanelTitle(i))
- {
- mTabContainer->setPanelTitle(i, floaterp->getShortTitle());
- }
- }
- LLFloater::draw();
- }
-}
-
-BOOL LLMultiFloater::closeAllFloaters()
-{
- S32 tabToClose = 0;
- S32 lastTabCount = mTabContainer->getTabCount();
- while (tabToClose < mTabContainer->getTabCount())
- {
- LLFloater* first_floater = (LLFloater*)mTabContainer->getPanelByIndex(tabToClose);
- first_floater->close();
- if(lastTabCount == mTabContainer->getTabCount())
- {
- //Tab did not actually close, possibly due to a pending Save Confirmation dialog..
- //so try and close the next one in the list...
- tabToClose++;
- }else
- {
- //Tab closed ok.
- lastTabCount = mTabContainer->getTabCount();
- }
- }
- if( mTabContainer->getTabCount() != 0 )
- return FALSE; // Couldn't close all the tabs (pending save dialog?) so return FALSE.
- return TRUE; //else all tabs were successfully closed...
-}
-
-void LLMultiFloater::growToFit(S32 content_width, S32 content_height)
-{
- S32 new_width = llmax(getRect().getWidth(), content_width + LLPANEL_BORDER_WIDTH * 2);
- S32 new_height = llmax(getRect().getHeight(), content_height + LLFLOATER_HEADER_SIZE + TABCNTR_HEADER_HEIGHT);
-
- if (isMinimized())
- {
- LLRect newrect;
- newrect.setLeftTopAndSize(getExpandedRect().mLeft, getExpandedRect().mTop, new_width, new_height);
- setExpandedRect(newrect);
- }
- else
- {
- S32 old_height = getRect().getHeight();
- reshape(new_width, new_height);
- // keep top left corner in same position
- translate(0, old_height - new_height);
- }
-}
-
-/**
- void addFloater(LLFloater* floaterp, BOOL select_added_floater)
-
- Adds the LLFloater pointed to by floaterp to this.
- If floaterp is already hosted by this, then it is re-added to get
- new titles, etc.
- If select_added_floater is true, the LLFloater pointed to by floaterp will
- become the selected tab in this
-
- Affects: mTabContainer, floaterp
-**/
-void LLMultiFloater::addFloater(LLFloater* floaterp, BOOL select_added_floater, LLTabContainer::eInsertionPoint insertion_point)
-{
- if (!floaterp)
- {
- return;
- }
-
- if (!mTabContainer)
- {
- llerrs << "Tab Container used without having been initialized." << llendl;
- return;
- }
-
- if (floaterp->getHost() == this)
- {
- // already hosted by me, remove
- // do this so we get updated title, etc.
- mFloaterDataMap.erase(floaterp->getHandle());
- mTabContainer->removeTabPanel(floaterp);
- }
- else if (floaterp->getHost())
- {
- // floaterp is hosted by somebody else and
- // this is adding it, so remove it from it's old host
- floaterp->getHost()->removeFloater(floaterp);
- }
- else if (floaterp->getParent() == gFloaterView)
- {
- // rehost preview floater as child panel
- gFloaterView->removeChild(floaterp);
- }
-
- // store original configuration
- LLFloaterData floater_data;
- floater_data.mWidth = floaterp->getRect().getWidth();
- floater_data.mHeight = floaterp->getRect().getHeight();
- floater_data.mCanMinimize = floaterp->isMinimizeable();
- floater_data.mCanResize = floaterp->isResizable();
-
- // remove minimize and close buttons
- floaterp->setCanMinimize(FALSE);
- floaterp->setCanResize(FALSE);
- floaterp->setCanDrag(FALSE);
- floaterp->storeRectControl();
- // avoid double rendering of floater background (makes it more opaque)
- floaterp->setBackgroundVisible(FALSE);
-
- if (mAutoResize)
- {
- growToFit(floater_data.mWidth, floater_data.mHeight);
- }
-
- //add the panel, add it to proper maps
- mTabContainer->addTabPanel(floaterp, floaterp->getShortTitle(), FALSE, onTabSelected, this, 0, FALSE, insertion_point);
- mFloaterDataMap[floaterp->getHandle()] = floater_data;
-
- updateResizeLimits();
-
- if ( select_added_floater )
- {
- mTabContainer->selectTabPanel(floaterp);
- }
- else
- {
- // reassert visible tab (hiding new floater if necessary)
- mTabContainer->selectTab(mTabContainer->getCurrentPanelIndex());
- }
-
- floaterp->setHost(this);
- if (isMinimized())
- {
- floaterp->setVisible(FALSE);
- }
-}
-
-/**
- BOOL selectFloater(LLFloater* floaterp)
-
- If the LLFloater pointed to by floaterp is hosted by this,
- then its tab is selected and returns true. Otherwise returns false.
-
- Affects: mTabContainer
-**/
-BOOL LLMultiFloater::selectFloater(LLFloater* floaterp)
-{
- return mTabContainer->selectTabPanel(floaterp);
-}
-
-// virtual
-void LLMultiFloater::selectNextFloater()
+void LLFloater::setInstanceName(const std::string& name)
{
- mTabContainer->selectNextTab();
-}
-
-// virtual
-void LLMultiFloater::selectPrevFloater()
-{
- mTabContainer->selectPrevTab();
-}
-
-void LLMultiFloater::showFloater(LLFloater* floaterp)
-{
- // we won't select a panel that already is selected
- // it is hard to do this internally to tab container
- // as tab selection is handled via index and the tab at a given
- // index might have changed
- if (floaterp != mTabContainer->getCurrentPanel() &&
- !mTabContainer->selectTabPanel(floaterp))
- {
- addFloater(floaterp, TRUE);
- }
-}
-
-void LLMultiFloater::removeFloater(LLFloater* floaterp)
-{
- if ( floaterp->getHost() != this )
+ if (name == mInstanceName)
return;
-
- floater_data_map_t::iterator found_data_it = mFloaterDataMap.find(floaterp->getHandle());
- if (found_data_it != mFloaterDataMap.end())
+ llassert_always(mInstanceName.empty());
+ mInstanceName = name;
+ if (!mInstanceName.empty())
{
- LLFloaterData& floater_data = found_data_it->second;
- floaterp->setCanMinimize(floater_data.mCanMinimize);
- if (!floater_data.mCanResize)
+ // save_rect and save_visibility only apply to registered floaters
+ if (!mRectControl.empty())
{
- // restore original size
- floaterp->reshape(floater_data.mWidth, floater_data.mHeight);
+ mRectControl = LLFloaterReg::declareRectControl(mInstanceName);
}
- floaterp->setCanResize(floater_data.mCanResize);
- mFloaterDataMap.erase(found_data_it);
- }
- mTabContainer->removeTabPanel(floaterp);
- floaterp->setBackgroundVisible(TRUE);
- floaterp->setCanDrag(TRUE);
- floaterp->setHost(NULL);
- floaterp->applyRectControl();
-
- updateResizeLimits();
-
- tabOpen((LLFloater*)mTabContainer->getCurrentPanel(), false);
-}
-
-void LLMultiFloater::tabOpen(LLFloater* opened_floater, bool from_click)
-{
- // default implementation does nothing
-}
-
-void LLMultiFloater::tabClose()
-{
- if (mTabContainer->getTabCount() == 0)
- {
- // no more children, close myself
- close();
- }
-}
-
-void LLMultiFloater::setVisible(BOOL visible)
-{
- // *FIX: shouldn't have to do this, fix adding to minimized multifloater
- LLFloater::setVisible(visible);
-
- if (mTabContainer)
- {
- LLPanel* cur_floaterp = mTabContainer->getCurrentPanel();
-
- if (cur_floaterp)
- {
- cur_floaterp->setVisible(visible);
- }
-
- // if no tab selected, and we're being shown,
- // select last tab to be added
- if (visible && !cur_floaterp)
- {
- mTabContainer->selectLastTab();
- }
- }
-}
-
-BOOL LLMultiFloater::handleKeyHere(KEY key, MASK mask)
-{
- if (key == 'W' && mask == MASK_CONTROL)
- {
- LLFloater* floater = getActiveFloater();
- // is user closeable and is system closeable
- if (floater && floater->canClose() && floater->isCloseable())
+ if (!mVisibilityControl.empty())
{
- floater->close();
+ mVisibilityControl = LLFloaterReg::declareVisibilityControl(mInstanceName);
}
- return TRUE;
}
-
- return LLFloater::handleKeyHere(key, mask);
-}
-
-LLFloater* LLMultiFloater::getActiveFloater()
-{
- return (LLFloater*)mTabContainer->getCurrentPanel();
-}
-
-S32 LLMultiFloater::getFloaterCount()
-{
- return mTabContainer->getTabCount();
-}
-
-/**
- BOOL isFloaterFlashing(LLFloater* floaterp)
-
- Returns true if the LLFloater pointed to by floaterp
- is currently in a flashing state and is hosted by this.
- False otherwise.
-
- Requires: floaterp != NULL
-**/
-BOOL LLMultiFloater::isFloaterFlashing(LLFloater* floaterp)
-{
- if ( floaterp && floaterp->getHost() == this )
- return mTabContainer->getTabPanelFlashing(floaterp);
-
- return FALSE;
}
-/**
- BOOL setFloaterFlashing(LLFloater* floaterp, BOOL flashing)
-
- Sets the current flashing state of the LLFloater pointed
- to by floaterp to be the BOOL flashing if the LLFloater pointed
- to by floaterp is hosted by this.
-
- Requires: floaterp != NULL
-**/
-void LLMultiFloater::setFloaterFlashing(LLFloater* floaterp, BOOL flashing)
+void LLFloater::setKey(const LLSD& newkey)
{
- if ( floaterp && floaterp->getHost() == this )
- mTabContainer->setTabPanelFlashing(floaterp, flashing);
+ // Note: We don't have to do anything special with registration when we change keys
+ mKey = newkey;
}
//static
-void LLMultiFloater::onTabSelected(void* userdata, bool from_click)
+void LLFloater::setupParamsForExport(Params& p, LLView* parent)
{
- LLMultiFloater* floaterp = (LLMultiFloater*)userdata;
+ // Do rectangle munging to topleft layout first
+ LLPanel::setupParamsForExport(p, parent);
- floaterp->tabOpen((LLFloater*)floaterp->mTabContainer->getCurrentPanel(), from_click);
-}
+ // Copy the rectangle out to apply layout constraints
+ LLRect rect = p.rect;
-void LLMultiFloater::setCanResize(BOOL can_resize)
-{
- LLFloater::setCanResize(can_resize);
- if (isResizable() && mTabContainer->getTabPosition() == LLTabContainer::BOTTOM)
- {
- mTabContainer->setRightTabBtnOffset(RESIZE_HANDLE_WIDTH);
- }
- else
- {
- mTabContainer->setRightTabBtnOffset(0);
- }
-}
+ // Null out other settings
+ p.rect.left.setProvided(false);
+ p.rect.top.setProvided(false);
+ p.rect.right.setProvided(false);
+ p.rect.bottom.setProvided(false);
-BOOL LLMultiFloater::postBuild()
-{
- // remember any original xml minimum size
- getResizeLimits(&mOrigMinWidth, &mOrigMinHeight);
+ // Explicitly set width/height
+ p.rect.width.set( rect.getWidth(), true );
+ p.rect.height.set( rect.getHeight(), true );
- if (mTabContainer)
+ // If you can't resize this floater, don't export min_height
+ // and min_width
+ bool can_resize = p.can_resize;
+ if (!can_resize)
{
- return TRUE;
+ p.min_height.setProvided(false);
+ p.min_width.setProvided(false);
}
-
- requires<LLTabContainer>("Preview Tabs");
- if (checkRequirements())
- {
- mTabContainer = getChild<LLTabContainer>("Preview Tabs");
- return TRUE;
- }
-
- return FALSE;
}
-void LLMultiFloater::updateResizeLimits()
-{
- // initialize minimum size constraint to the original xml values.
- S32 new_min_width = mOrigMinWidth;
- S32 new_min_height = mOrigMinHeight;
- // possibly increase minimum size constraint due to children's minimums.
- for (S32 tab_idx = 0; tab_idx < mTabContainer->getTabCount(); ++tab_idx)
- {
- LLFloater* floaterp = (LLFloater*)mTabContainer->getPanelByIndex(tab_idx);
- if (floaterp)
- {
- new_min_width = llmax(new_min_width, floaterp->getMinWidth() + LLPANEL_BORDER_WIDTH * 2);
- new_min_height = llmax(new_min_height, floaterp->getMinHeight() + LLFLOATER_HEADER_SIZE + TABCNTR_HEADER_HEIGHT);
- }
- }
- setResizeLimits(new_min_width, new_min_height);
-
- S32 cur_height = getRect().getHeight();
- S32 new_width = llmax(getRect().getWidth(), new_min_width);
- S32 new_height = llmax(getRect().getHeight(), new_min_height);
-
- if (isMinimized())
- {
- const LLRect& expanded = getExpandedRect();
- LLRect newrect;
- newrect.setLeftTopAndSize(expanded.mLeft, expanded.mTop, llmax(expanded.getWidth(), new_width), llmax(expanded.getHeight(), new_height));
- setExpandedRect(newrect);
- }
- else
- {
- reshape(new_width, new_height);
-
- // make sure upper left corner doesn't move
- translate(0, cur_height - getRect().getHeight());
-
- // make sure this window is visible on screen when it has been modified
- // (tab added, etc)
- gFloaterView->adjustToFitScreen(this, TRUE);
- }
-}
-
-// virtual
-LLXMLNodePtr LLFloater::getXML(bool save_children) const
+void LLFloater::initFromParams(const LLFloater::Params& p)
{
- LLXMLNodePtr node = LLPanel::getXML();
+ // control_name, tab_stop, focus_lost_callback, initial_value, rect, enabled, visible
+ LLPanel::initFromParams(p);
- node->createChild("title", TRUE)->setStringValue(getCurrentTitle());
-
- node->createChild("can_resize", TRUE)->setBoolValue(isResizable());
-
- node->createChild("can_minimize", TRUE)->setBoolValue(isMinimizeable());
-
- node->createChild("can_close", TRUE)->setBoolValue(isCloseable());
-
- node->createChild("can_drag_on_left", TRUE)->setBoolValue(isDragOnLeft());
-
- node->createChild("min_width", TRUE)->setIntValue(getMinWidth());
-
- node->createChild("min_height", TRUE)->setIntValue(getMinHeight());
+ mTitle = p.title;
+ mShortTitle = p.short_title;
+ applyTitle();
- node->createChild("can_tear_off", TRUE)->setBoolValue(mCanTearOff);
+ setCanTearOff(p.can_tear_off);
+ setCanMinimize(p.can_minimize);
+ setCanClose(p.can_close);
+ setCanDock(p.can_dock);
- return node;
-}
+ mDragOnLeft = p.can_drag_on_left;
+ mResizable = p.can_resize;
+ mMinWidth = p.min_width;
+ mMinHeight = p.min_height;
+ mSingleInstance = p.single_instance;
+ mAutoTile = p.auto_tile;
-// static
-LLView* LLFloater::fromXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFactory *factory)
-{
- std::string name("floater");
- node->getAttributeString("name", name);
-
- LLFloater *floaterp = new LLFloater(name);
-
- std::string filename;
- node->getAttributeString("filename", filename);
-
- if (filename.empty())
+ if (p.save_rect)
{
- // Load from node
- floaterp->initFloaterXML(node, parent, factory);
+ mRectControl = "t"; // flag to build mRectControl name once mInstanceName is set
}
- else
+ if (p.save_visibility)
{
- // Load from file
- factory->buildFloater(floaterp, filename);
+ mVisibilityControl = "t"; // flag to build mVisibilityControl name once mInstanceName is set
}
-
- return floaterp;
+
+ // open callback
+ if (p.open_callback.isProvided())
+ initCommitCallback(p.open_callback, mOpenSignal);
+ // close callback
+ if (p.close_callback.isProvided())
+ initCommitCallback(p.close_callback, mCloseSignal);
}
-void LLFloater::initFloaterXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFactory *factory, BOOL open) /* Flawfinder: ignore */
-{
- std::string name(getName());
- std::string title(getCurrentTitle());
- std::string short_title(getShortTitle());
- std::string rect_control("");
- BOOL resizable = isResizable();
- S32 min_width = getMinWidth();
- S32 min_height = getMinHeight();
- BOOL drag_on_left = isDragOnLeft();
- BOOL minimizable = isMinimizeable();
- BOOL close_btn = isCloseable();
- LLRect rect;
+LLFastTimer::DeclareTimer POST_BUILD("Floater Post Build");
- node->getAttributeString("name", name);
- node->getAttributeString("title", title);
- node->getAttributeString("short_title", short_title);
- node->getAttributeString("rect_control", rect_control);
- node->getAttributeBOOL("can_resize", resizable);
- node->getAttributeBOOL("can_minimize", minimizable);
- node->getAttributeBOOL("can_close", close_btn);
- node->getAttributeBOOL("can_drag_on_left", drag_on_left);
- node->getAttributeS32("min_width", min_width);
- node->getAttributeS32("min_height", min_height);
+void LLFloater::initFloaterXML(LLXMLNodePtr node, LLView *parent, LLXMLNodePtr output_node)
+{
+ Params params(LLUICtrlFactory::getDefaultParams<LLFloater>());
+ LLXUIParser::instance().readXUI(node, params);
- if (! rect_control.empty())
+ if (output_node)
{
- setRectControl(rect_control);
+ Params output_params(params);
+ setupParamsForExport(output_params, parent);
+ Params default_params(LLUICtrlFactory::getDefaultParams<LLFloater>());
+ output_node->setName(node->getName()->mString);
+ LLXUIParser::instance().writeXUI(
+ output_node, output_params, &default_params);
}
- createRect(node, rect, parent, LLRect());
-
- setRect(rect);
- setName(name);
+ setupParams(params, parent);
+ initFromParams(params);
- initFloater(title,
- resizable,
- min_width,
- min_height,
- drag_on_left,
- minimizable,
- close_btn);
-
- setTitle(title);
- applyTitle ();
-
- setShortTitle(short_title);
-
- BOOL can_tear_off;
- if (node->getAttributeBOOL("can_tear_off", can_tear_off))
- {
- setCanTearOff(can_tear_off);
- }
+ initFloater();
- initFromXML(node, parent);
-
LLMultiFloater* last_host = LLFloater::getFloaterHost();
if (node->hasName("multi_floater"))
{
LLFloater::setFloaterHost((LLMultiFloater*) this);
}
- initChildrenXML(node, factory);
+ LLUICtrlFactory::createChildren(this, node, child_registry_t::instance(), output_node);
if (node->hasName("multi_floater"))
{
LLFloater::setFloaterHost(last_host);
}
+
+ BOOL result;
+ {
+ LLFastTimer ft(POST_BUILD);
- BOOL result = postBuild();
+ result = postBuild();
+ }
if (!result)
{
- llerrs << "Failed to construct floater " << name << llendl;
+ llerrs << "Failed to construct floater " << getName() << llendl;
}
- applyRectControl();
- if (open) /* Flawfinder: ignore */
- {
- this->open(); /* Flawfinder: ignore */
- }
+ applyRectControl(); // If we have a saved rect control, apply it
+ gFloaterView->adjustToFitScreen(this, FALSE); // Floaters loaded from XML should all fit on screen
moveResizeHandlesToFront();
}
+
diff --git a/indra/llui/llfloater.h b/indra/llui/llfloater.h
index 0e3d148b09..ee066317e0 100644
--- a/indra/llui/llfloater.h
+++ b/indra/llui/llfloater.h
@@ -39,7 +39,6 @@
#include "llpanel.h"
#include "lluuid.h"
-#include "lltabcontainer.h"
#include "llnotifications.h"
#include <set>
@@ -50,17 +49,10 @@ class LLButton;
class LLMultiFloater;
class LLFloater;
-const S32 LLFLOATER_VPAD = 6;
-const S32 LLFLOATER_HPAD = 6;
-const S32 LLFLOATER_CLOSE_BOX_SIZE = 16;
-const S32 LLFLOATER_HEADER_SIZE = 18;
const BOOL RESIZE_YES = TRUE;
const BOOL RESIZE_NO = FALSE;
-const S32 DEFAULT_MIN_WIDTH = 100;
-const S32 DEFAULT_MIN_HEIGHT = 100;
-
const BOOL DRAG_ON_TOP = FALSE;
const BOOL DRAG_ON_LEFT = TRUE;
@@ -87,64 +79,86 @@ private:
LLHandle<LLFloater> mFloaterHandle;
};
-
class LLFloater : public LLPanel
{
friend class LLFloaterView;
+friend class LLFloaterReg;
+friend class LLMultiFloater;
public:
+ struct KeyCompare
+ {
+ static bool compare(const LLSD& a, const LLSD& b);
+ static bool equate(const LLSD& a, const LLSD& b);
+ bool operator()(const LLSD& a, const LLSD& b) const
+ {
+ return compare(a, b);
+ }
+ };
+
enum EFloaterButtons
{
- BUTTON_CLOSE,
+ BUTTON_CLOSE = 0,
BUTTON_RESTORE,
BUTTON_MINIMIZE,
BUTTON_TEAR_OFF,
BUTTON_EDIT,
+ BUTTON_DOCK,
+ BUTTON_UNDOCK,
BUTTON_COUNT
};
- LLFloater();
- LLFloater(const std::string& name); //simple constructor for data-driven initialization
- LLFloater( const std::string& name, const LLRect& rect, const std::string& title,
- BOOL resizable = FALSE,
- S32 min_width = DEFAULT_MIN_WIDTH,
- S32 min_height = DEFAULT_MIN_HEIGHT,
- BOOL drag_on_left = FALSE,
- BOOL minimizable = TRUE,
- BOOL close_btn = TRUE,
- BOOL bordered = BORDER_NO);
-
- LLFloater( const std::string& name, const std::string& rect_control, const std::string& title,
- BOOL resizable = FALSE,
- S32 min_width = DEFAULT_MIN_WIDTH,
- S32 min_height = DEFAULT_MIN_HEIGHT,
- BOOL drag_on_left = FALSE,
- BOOL minimizable = TRUE,
- BOOL close_btn = TRUE,
- BOOL bordered = BORDER_NO);
+ struct Params
+ : public LLInitParam::Block<Params, LLPanel::Params>
+ {
+ Optional<std::string> title,
+ short_title;
+
+ Optional<bool> single_instance,
+ auto_tile,
+ can_resize,
+ can_minimize,
+ can_close,
+ can_drag_on_left,
+ can_tear_off,
+ save_rect,
+ save_visibility,
+ can_dock;
+
+ Optional<CommitCallbackParam> open_callback,
+ close_callback;
+
+ Params();
+ };
+
+ // use this to avoid creating your own default LLFloater::Param instance
+ static const Params& getDefaultParams();
+
+ // Load translations for tooltips for standard buttons
+ static void initClass();
+
+ LLFloater(const LLSD& key, const Params& params = getDefaultParams());
virtual ~LLFloater();
- virtual LLXMLNodePtr getXML(bool save_children = true) const;
- static LLView* fromXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFactory *factory);
- void initFloaterXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFactory *factory, BOOL open = TRUE);
+ // Don't export top/left for rect, only height/width
+ static void setupParamsForExport(Params& p, LLView* parent);
+
+ void initFromParams(const LLFloater::Params& p);
+ void initFloaterXML(LLXMLNodePtr node, LLView *parent, LLXMLNodePtr output_node = NULL);
- /*virtual*/ void userSetShape(const LLRect& new_rect);
+ /*virtual*/ void handleReshape(const LLRect& new_rect, bool by_user = false);
/*virtual*/ BOOL canSnapTo(const LLView* other_view);
- /*virtual*/ void snappedTo(const LLView* snap_view);
+ /*virtual*/ void setSnappedTo(const LLView* snap_view);
/*virtual*/ void setFocus( BOOL b );
/*virtual*/ void setIsChrome(BOOL is_chrome);
+ /*virtual*/ void setRect(const LLRect &rect);
- // Can be called multiple times to reset floater parameters.
- // Deletes all children of the floater.
- virtual void initFloater(const std::string& title, BOOL resizable,
- S32 min_width, S32 min_height, BOOL drag_on_left,
- BOOL minimizable, BOOL close_btn);
+ void initFloater();
- virtual void open(); /* Flawfinder: ignore */
+ void openFloater(const LLSD& key = LLSD());
// If allowed, close the floater cleanly, releasing focus.
- // app_quitting is passed to onClose() below.
- virtual void close(bool app_quitting = false);
+ void closeFloater(bool app_quitting = false);
/*virtual*/ void reshape(S32 width, S32 height, BOOL called_from_parent = TRUE);
@@ -153,11 +167,8 @@ public:
// moves to center of gFloaterView
void center();
- // applies rectangle stored in mRectControl, if any
- void applyRectControl();
-
- LLMultiFloater* getHost() { return (LLMultiFloater*)mHostHandle.get(); }
+ LLMultiFloater* getHost();
void applyTitle();
const std::string& getCurrentTitle() const;
@@ -185,9 +196,8 @@ public:
void setResizeLimits( S32 min_width, S32 min_height );
void getResizeLimits( S32* min_width, S32* min_height ) { *min_width = mMinWidth; *min_height = mMinHeight; }
- bool isMinimizeable() const{ return mButtonsEnabled[BUTTON_MINIMIZE]; }
- // Does this window have a close button, NOT can we close it right now.
- bool isCloseable() const{ return (mButtonsEnabled[BUTTON_CLOSE]); }
+ bool isMinimizeable() const{ return mCanMinimize; }
+ bool isCloseable() const{ return mCanClose; }
bool isDragOnLeft() const{ return mDragOnLeft; }
S32 getMinWidth() const{ return mMinWidth; }
S32 getMinHeight() const{ return mMinHeight; }
@@ -197,21 +207,19 @@ public:
virtual BOOL handleDoubleClick(S32 x, S32 y, MASK mask);
virtual BOOL handleMiddleMouseDown(S32 x, S32 y, MASK mask);
virtual void draw();
-
- virtual void onOpen() {}
-
- // Call destroy() to free memory, or setVisible(FALSE) to keep it
- // If app_quitting, you might not want to save your visibility.
- // Defaults to destroy().
- virtual void onClose(bool app_quitting) { destroy(); }
+
+ // *TODO: Eliminate this in favor of mOpenSignal
+ virtual void onOpen(const LLSD& key) {}
// This cannot be "const" until all derived floater canClose()
// methods are const as well. JC
virtual BOOL canClose() { return TRUE; }
- virtual void setVisible(BOOL visible);
+ /*virtual*/ void setVisible(BOOL visible); // do not override
+ /*virtual*/ void handleVisibilityChange ( BOOL new_visibility ); // do not override
+
void setFrontmost(BOOL take_focus = TRUE);
-
+
// Defaults to false.
virtual BOOL canSaveAs() const { return FALSE; }
@@ -222,6 +230,16 @@ public:
LLHandle<LLFloater> getSnapTarget() const { return mSnappedTo; }
LLHandle<LLFloater> getHandle() const { return mHandle; }
+ const LLSD& getKey() { return mKey; }
+ BOOL matchesKey(const LLSD& key) { return mSingleInstance || KeyCompare::equate(key, mKey); }
+
+ const std::string& getInstanceName() { return mInstanceName; }
+
+ bool isDockable() const { return mCanDock; }
+ void setCanDock(bool b);
+
+ bool isDocked() const { return mDocked; }
+ virtual void setDocked(bool docked, bool pop_on_undock = true);
// Return a closeable floater, if any, given the current focus.
static LLFloater* getClosableFloaterFromFocus();
@@ -235,62 +253,89 @@ public:
return LLNotification::Params(name).context(mNotificationContext);
}
- static void onClickClose(void *userdata);
- static void onClickMinimize(void *userdata);
- static void onClickTearOff(void *userdata);
- static void onClickEdit(void *userdata);
+ static void onClickClose(LLFloater* floater);
+ static void onClickMinimize(LLFloater* floater);
+ static void onClickTearOff(LLFloater* floater);
+ static void onClickEdit(LLFloater* floater);
+ static void onClickDock(LLFloater* floater);
static void setFloaterHost(LLMultiFloater* hostp) {sHostp = hostp; }
static void setEditModeEnabled(BOOL enable);
static BOOL getEditModeEnabled() { return sEditModeEnabled; }
- static LLMultiFloater* getFloaterHost() {return sHostp; }
-
+ static LLMultiFloater* getFloaterHost() {return sHostp; }
+
protected:
+ void setRectControl(const std::string& rectname) { mRectControl = rectname; };
+ void applyRectControl();
+ void storeRectControl();
+ void storeVisibilityControl();
+
+ void setKey(const LLSD& key);
+ void setInstanceName(const std::string& name);
+
virtual void bringToFront(S32 x, S32 y);
virtual void setVisibleAndFrontmost(BOOL take_focus=TRUE);
- void setExpandedRect(const LLRect& rect) { mExpandedRect = rect; } // size when not minimized
+ void setExpandedRect(const LLRect& rect) { mExpandedRect = rect; } // size when not minimized
const LLRect& getExpandedRect() const { return mExpandedRect; }
void setAutoFocus(BOOL focus) { mAutoFocus = focus; } // whether to automatically take focus when opened
LLDragHandle* getDragHandle() const { return mDragHandle; }
- void destroy() { die(); } // Don't call this directly. You probably want to call close(). JC
+ void destroy() { die(); } // Don't call this directly. You probably want to call closeFloater()
private:
-
void setForeground(BOOL b); // called only by floaterview
void cleanupHandles(); // remove handles to dead floaters
void createMinimizeButton();
void updateButtons();
void buildButtons();
BOOL offerClickToButton(S32 x, S32 y, MASK mask, EFloaterButtons index);
+ void addResizeCtrls();
+ void addDragHandle();
+
+protected:
+ std::string mRectControl;
+ std::string mVisibilityControl;
+ commit_signal_t mOpenSignal; // Called when floater is opened, passes mKey
+ commit_signal_t mCloseSignal; // Called when floater is closed, passes app_qitting as LLSD()
+ LLSD mKey; // Key used for retrieving instances; set (for now) by LLFLoaterReg
- LLRect mExpandedRect;
LLDragHandle* mDragHandle;
LLResizeBar* mResizeBar[4];
LLResizeHandle* mResizeHandle[4];
- LLButton *mMinimizeButton;
+
+private:
+ LLRect mExpandedRect;
+
+ LLUIString mTitle;
+ LLUIString mShortTitle;
+
+ BOOL mSingleInstance; // TRUE if there is only ever one instance of the floater
+ std::string mInstanceName; // Store the instance name so we can remove ourselves from the list
+ BOOL mAutoTile; // TRUE if placement of new instances tiles
+
BOOL mCanTearOff;
+ BOOL mCanMinimize;
+ BOOL mCanClose;
+ BOOL mDragOnLeft;
+ BOOL mResizable;
+
+ S32 mMinWidth;
+ S32 mMinHeight;
+
BOOL mMinimized;
BOOL mForeground;
LLHandle<LLFloater> mDependeeHandle;
- std::string mTitle;
- std::string mShortTitle;
+
BOOL mFirstLook; // TRUE if the _next_ time this floater is visible will be the first time in the session that it is visible.
-
- BOOL mResizable;
- S32 mMinWidth;
- S32 mMinHeight;
-
BOOL mEditing;
typedef std::set<LLHandle<LLFloater> > handle_set_t;
typedef std::set<LLHandle<LLFloater> >::iterator handle_set_iter_t;
handle_set_t mDependents;
- bool mDragOnLeft;
BOOL mButtonsEnabled[BUTTON_COUNT];
LLButton* mButtons[BUTTON_COUNT];
@@ -301,14 +346,21 @@ private:
LLHandle<LLFloater> mHostHandle;
LLHandle<LLFloater> mLastHostHandle;
+ bool mCanDock;
+ bool mDocked;
+
static LLMultiFloater* sHostp;
static BOOL sEditModeEnabled;
+ static BOOL sQuitting;
static std::string sButtonActiveImageNames[BUTTON_COUNT];
- static std::string sButtonInactiveImageNames[BUTTON_COUNT];
+ // Images to use when cursor hovered over an enabled button
+ static std::string sButtonHoveredImageNames[BUTTON_COUNT];
static std::string sButtonPressedImageNames[BUTTON_COUNT];
static std::string sButtonNames[BUTTON_COUNT];
static std::string sButtonToolTips[BUTTON_COUNT];
- typedef void (*click_callback)(void *);
+ static std::string sButtonToolTipsIndex[BUTTON_COUNT];
+
+ typedef void(*click_callback)(LLFloater*);
static click_callback sButtonCallbacks[BUTTON_COUNT];
typedef std::map<LLHandle<LLFloater>, LLFloater*> handle_map_t;
@@ -320,29 +372,33 @@ private:
BOOL mHasBeenDraggedWhileMinimized;
S32 mPreviousMinimizedBottom;
S32 mPreviousMinimizedLeft;
-
+
+ LLColor4 mBgColorAlpha;
+ LLColor4 mBgColorOpaque;
+
LLFloaterNotificationContext* mNotificationContext;
LLRootHandle<LLFloater> mHandle;
};
+
/////////////////////////////////////////////////////////////
// LLFloaterView
// Parent of all floating panels
class LLFloaterView : public LLUICtrl
{
-public:
- LLFloaterView( const std::string& name, const LLRect& rect );
+protected:
+ LLFloaterView (const Params& p);
+ friend class LLUICtrlFactory;
+public:
/*virtual*/ void reshape(S32 width, S32 height, BOOL called_from_parent = TRUE);
void reshapeFloater(S32 width, S32 height, BOOL called_from_parent, BOOL adjust_vertical);
/*virtual*/ void draw();
/*virtual*/ LLRect getSnapRect() const;
- void refresh();
+ /*virtual*/ void refresh();
- void getNewFloaterPosition( S32* left, S32* top );
- void resetStartingFloaterPosition();
LLRect findNeighboringPosition( LLFloater* reference_floater, LLFloater* neighbor );
// Given a child of gFloaterView, make sure this view can fit entirely onscreen.
@@ -365,10 +421,10 @@ public:
void closeAllChildren(bool app_quitting);
BOOL allChildrenClosed();
- LLFloater* getFrontmost();
- LLFloater* getBackmost();
- LLFloater* getParentFloater(LLView* viewp);
- LLFloater* getFocusedFloater();
+ LLFloater* getFrontmost() const;
+ LLFloater* getBackmost() const;
+ LLFloater* getParentFloater(LLView* viewp) const;
+ LLFloater* getFocusedFloater() const;
void syncFloaterTabOrder();
// Returns z order of child provided. 0 is closest, larger numbers
@@ -377,6 +433,7 @@ public:
S32 getZOrder(LLFloater* child);
void setSnapOffsetBottom(S32 offset) { mSnapOffsetBottom = offset; }
+ void setSnapOffsetRight(S32 offset) { mSnapOffsetRight = offset; }
private:
S32 mColumn;
@@ -384,110 +441,12 @@ private:
S32 mNextTop;
BOOL mFocusCycleMode;
S32 mSnapOffsetBottom;
+ S32 mSnapOffsetRight;
};
-// https://wiki.lindenlab.com/mediawiki/index.php?title=LLMultiFloater&oldid=81376
-class LLMultiFloater : public LLFloater
-{
-public:
- LLMultiFloater();
- LLMultiFloater(LLTabContainer::TabPosition tab_pos);
- LLMultiFloater(const std::string& name);
- LLMultiFloater(const std::string& name, const LLRect& rect, LLTabContainer::TabPosition tab_pos = LLTabContainer::TOP, BOOL auto_resize = TRUE);
- LLMultiFloater(const std::string& name, const std::string& rect_control, LLTabContainer::TabPosition tab_pos = LLTabContainer::TOP, BOOL auto_resize = TRUE);
- virtual ~LLMultiFloater() {};
-
- virtual BOOL postBuild();
- /*virtual*/ void open(); /* Flawfinder: ignore */
- /*virtual*/ void onClose(bool app_quitting);
- /*virtual*/ void draw();
- /*virtual*/ void setVisible(BOOL visible);
- /*virtual*/ BOOL handleKeyHere(KEY key, MASK mask);
-
- virtual void setCanResize(BOOL can_resize);
- virtual void growToFit(S32 content_width, S32 content_height);
- virtual void addFloater(LLFloater* floaterp, BOOL select_added_floater, LLTabContainer::eInsertionPoint insertion_point = LLTabContainer::END);
-
- virtual void showFloater(LLFloater* floaterp);
- virtual void removeFloater(LLFloater* floaterp);
-
- virtual void tabOpen(LLFloater* opened_floater, bool from_click);
- virtual void tabClose();
-
- virtual BOOL selectFloater(LLFloater* floaterp);
- virtual void selectNextFloater();
- virtual void selectPrevFloater();
-
- virtual LLFloater* getActiveFloater();
- virtual BOOL isFloaterFlashing(LLFloater* floaterp);
- virtual S32 getFloaterCount();
-
- virtual void setFloaterFlashing(LLFloater* floaterp, BOOL flashing);
- virtual BOOL closeAllFloaters(); //Returns FALSE if the floater could not be closed due to pending confirmation dialogs
- void setTabContainer(LLTabContainer* tab_container) { if (!mTabContainer) mTabContainer = tab_container; }
- static void onTabSelected(void* userdata, bool);
-
- virtual void updateResizeLimits();
-
-protected:
- struct LLFloaterData
- {
- S32 mWidth;
- S32 mHeight;
- BOOL mCanMinimize;
- BOOL mCanResize;
- };
-
- LLTabContainer* mTabContainer;
-
- typedef std::map<LLHandle<LLFloater>, LLFloaterData> floater_data_map_t;
- floater_data_map_t mFloaterDataMap;
-
- LLTabContainer::TabPosition mTabPos;
- BOOL mAutoResize;
- S32 mOrigMinWidth, mOrigMinHeight; // logically const but initialized late
-};
-
-// visibility policy specialized for floaters
-template<>
-class VisibilityPolicy<LLFloater>
-{
-public:
- // visibility methods
- static bool visible(LLFloater* instance, const LLSD& key)
- {
- if (instance)
- {
- return !instance->isMinimized() && instance->isInVisibleChain();
- }
- return FALSE;
- }
-
- static void show(LLFloater* instance, const LLSD& key)
- {
- if (instance)
- {
- instance->open();
- if (instance->getHost())
- {
- instance->getHost()->open();
- }
- }
- }
-
- static void hide(LLFloater* instance, const LLSD& key)
- {
- if (instance) instance->close();
- }
-};
-
-
-// singleton implementation for floaters (provides visibility policy)
-// https://wiki.lindenlab.com/mediawiki/index.php?title=LLFloaterSingleton&oldid=164990
-
-template <class T> class LLFloaterSingleton : public LLUISingleton<T, VisibilityPolicy<LLFloater> >
-{
-};
+//
+// Globals
+//
extern LLFloaterView* gFloaterView;
diff --git a/indra/llui/llfloaterreg.cpp b/indra/llui/llfloaterreg.cpp
new file mode 100644
index 0000000000..a63b1b085c
--- /dev/null
+++ b/indra/llui/llfloaterreg.cpp
@@ -0,0 +1,440 @@
+/**
+ * @file llfloaterreg.cpp
+ * @brief LLFloaterReg Floater Registration Class
+ *
+ * $LicenseInfo:firstyear=2002&license=viewergpl$
+ *
+ * Copyright (c) 2002-2009, Linden Research, Inc.
+ *
+ * Second Life Viewer Source Code
+ * The source code in this file ("Source Code") is provided by Linden Lab
+ * to you under the terms of the GNU General Public License, version 2.0
+ * ("GPL"), unless you have obtained a separate licensing agreement
+ * ("Other License"), formally executed by you and Linden Lab. Terms of
+ * the GPL can be found in doc/GPL-license.txt in this distribution, or
+ * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
+ *
+ * There are special exceptions to the terms and conditions of the GPL as
+ * it is applied to this Source Code. View the full text of the exception
+ * in the file doc/FLOSS-exception.txt in this software distribution, or
+ * online at
+ * http://secondlifegrid.net/programs/open_source/licensing/flossexception
+ *
+ * By copying, modifying or distributing this software, you acknowledge
+ * that you have read and understood your obligations described above,
+ * and agree to abide by those obligations.
+ *
+ * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+ * COMPLETENESS OR PERFORMANCE.
+ * $/LicenseInfo$
+ */
+
+#include "linden_common.h"
+
+#include "llfloaterreg.h"
+
+#include "llfloater.h"
+#include "llmultifloater.h"
+
+//*******************************************************
+
+//static
+LLFloaterReg::instance_list_t LLFloaterReg::sNullInstanceList;
+LLFloaterReg::instance_map_t LLFloaterReg::sInstanceMap;
+LLFloaterReg::build_map_t LLFloaterReg::sBuildMap;
+std::map<std::string,std::string> LLFloaterReg::sGroupMap;
+
+//*******************************************************
+
+//static
+void LLFloaterReg::add(const std::string& name, const std::string& filename, const LLFloaterBuildFunc& func, const std::string& groupname)
+{
+ sBuildMap[name].mFunc = func;
+ sBuildMap[name].mFile = filename;
+ sGroupMap[name] = groupname.empty() ? name : groupname;
+ sGroupMap[groupname] = groupname; // for referencing directly by group name
+}
+
+//static
+LLRect LLFloaterReg::getFloaterRect(const std::string& name)
+{
+ LLRect rect;
+ const std::string& groupname = sGroupMap[name];
+ if (!groupname.empty())
+ {
+ instance_list_t& list = sInstanceMap[groupname];
+ if (!list.empty())
+ {
+ static LLUICachedControl<S32> floater_offset ("UIFloaterOffset", 16);
+ LLFloater* last_floater = list.back();
+ if (last_floater->getHost())
+ {
+ rect = last_floater->getHost()->getRect();
+ }
+ else
+ {
+ rect = last_floater->getRect();
+ }
+ rect.translate(floater_offset, -floater_offset);
+ }
+ }
+ return rect;
+}
+
+//static
+LLFloater* LLFloaterReg::findInstance(const std::string& name, const LLSD& key)
+{
+ LLFloater* res = NULL;
+ const std::string& groupname = sGroupMap[name];
+ if (!groupname.empty())
+ {
+ instance_list_t& list = sInstanceMap[groupname];
+ for (instance_list_t::iterator iter = list.begin(); iter != list.end(); ++iter)
+ {
+ LLFloater* inst = *iter;
+ if (inst->matchesKey(key))
+ {
+ res = inst;
+ break;
+ }
+ }
+ }
+ return res;
+}
+
+//static
+LLFloater* LLFloaterReg::getInstance(const std::string& name, const LLSD& key)
+{
+ LLFloater* res = findInstance(name, key);
+ if (!res)
+ {
+ const LLFloaterBuildFunc& build_func = sBuildMap[name].mFunc;
+ const std::string& xui_file = sBuildMap[name].mFile;
+ if (build_func)
+ {
+ const std::string& groupname = sGroupMap[name];
+ if (!groupname.empty())
+ {
+ instance_list_t& list = sInstanceMap[groupname];
+ int index = list.size();
+
+ res = build_func(key);
+
+ LLUICtrlFactory::getInstance()->buildFloater(res, xui_file, NULL);
+
+ // Note: key should eventually be a non optional LLFloater arg; for now, set mKey to be safe
+ res->mKey = key;
+ res->setInstanceName(name);
+ res->applyRectControl(); // Can't apply rect control until setting instance name
+ if (res->mAutoTile && !res->getHost() && index > 0)
+ {
+ const LLRect& cur_rect = res->getRect();
+ LLRect next_rect = getFloaterRect(groupname);
+ next_rect.setLeftTopAndSize(next_rect.mLeft, next_rect.mTop, cur_rect.getWidth(), cur_rect.getHeight());
+ res->setRect(next_rect);
+ res->setRectControl(LLStringUtil::null); // don't save rect of tiled floaters
+ gFloaterView->adjustToFitScreen(res, true);
+ }
+ else
+ {
+ gFloaterView->adjustToFitScreen(res, false);
+ }
+ list.push_back(res);
+ }
+ }
+ if (!res)
+ {
+ llwarns << "Floater type: '" << name << "' not registered." << llendl;
+ }
+ }
+ return res;
+}
+
+//static
+LLFloater* LLFloaterReg::removeInstance(const std::string& name, const LLSD& key)
+{
+ LLFloater* res = NULL;
+ const std::string& groupname = sGroupMap[name];
+ if (!groupname.empty())
+ {
+ instance_list_t& list = sInstanceMap[groupname];
+ for (instance_list_t::iterator iter = list.begin(); iter != list.end(); ++iter)
+ {
+ LLFloater* inst = *iter;
+ if (inst->matchesKey(key))
+ {
+ res = inst;
+ list.erase(iter);
+ break;
+ }
+ }
+ }
+ return res;
+}
+
+//static
+// returns true if the instance existed
+bool LLFloaterReg::destroyInstance(const std::string& name, const LLSD& key)
+{
+ LLFloater* inst = removeInstance(name, key);
+ if (inst)
+ {
+ delete inst;
+ return true;
+ }
+ else
+ {
+ return false;
+ }
+}
+
+// Iterators
+//static
+LLFloaterReg::const_instance_list_t& LLFloaterReg::getFloaterList(const std::string& name)
+{
+ instance_map_t::iterator iter = sInstanceMap.find(name);
+ if (iter != sInstanceMap.end())
+ {
+ return iter->second;
+ }
+ else
+ {
+ return sNullInstanceList;
+ }
+}
+
+// Visibility Management
+
+//static
+LLFloater* LLFloaterReg::showInstance(const std::string& name, const LLSD& key, BOOL focus)
+{
+ LLFloater* instance = getInstance(name, key);
+ if (instance)
+ {
+ instance->openFloater(key);
+ if (focus)
+ instance->setFocus(TRUE);
+ }
+ return instance;
+}
+
+//static
+// returns true if the instance exists
+bool LLFloaterReg::hideInstance(const std::string& name, const LLSD& key)
+{
+ LLFloater* instance = findInstance(name, key);
+ if (instance)
+ {
+ // When toggling *visibility*, close the host instead of the floater when hosted
+ if (instance->getHost())
+ instance->getHost()->closeFloater();
+ else
+ instance->closeFloater();
+ return true;
+ }
+ else
+ {
+ return false;
+ }
+}
+
+//static
+// returns true if the instance is visible when completed
+bool LLFloaterReg::toggleInstance(const std::string& name, const LLSD& key)
+{
+ LLFloater* instance = findInstance(name, key);
+ if (instance && !instance->isMinimized() && instance->isInVisibleChain())
+ {
+ // When toggling *visibility*, close the host instead of the floater when hosted
+ if (instance->getHost())
+ instance->getHost()->closeFloater();
+ else
+ instance->closeFloater();
+ return false;
+ }
+ else
+ {
+ return showInstance(name, key, TRUE) ? true : false;
+ }
+}
+
+//static
+// returns true if the instance exists and is visible
+bool LLFloaterReg::instanceVisible(const std::string& name, const LLSD& key)
+{
+ LLFloater* instance = findInstance(name, key);
+ if (instance && !instance->isMinimized() && instance->isInVisibleChain())
+ {
+ return true;
+ }
+ else
+ {
+ return false;
+ }
+}
+
+//static
+void LLFloaterReg::showInitialVisibleInstances()
+{
+ // Iterate through alll registered instance names and show any with a save visible state
+ for (build_map_t::iterator iter = sBuildMap.begin(); iter != sBuildMap.end(); ++iter)
+ {
+ const std::string& name = iter->first;
+ std::string controlname = getVisibilityControlName(name);
+ if (LLUI::sSettingGroups["floater"]->controlExists(controlname))
+ {
+ BOOL isvis = LLUI::sSettingGroups["floater"]->getBOOL(controlname);
+ if (isvis)
+ {
+ showInstance(name, LLSD()); // keyed floaters shouldn't set save_vis to true
+ }
+ }
+ }
+}
+
+//static
+void LLFloaterReg::hideVisibleInstances(const std::set<std::string>& exceptions)
+{
+ // Iterate through alll active instances and hide them
+ for (instance_map_t::iterator iter = sInstanceMap.begin(); iter != sInstanceMap.end(); ++iter)
+ {
+ const std::string& name = iter->first;
+ if (exceptions.find(name) != exceptions.end())
+ continue;
+ instance_list_t& list = iter->second;
+ for (instance_list_t::iterator iter = list.begin(); iter != list.end(); ++iter)
+ {
+ LLFloater* floater = *iter;
+ floater->pushVisible(FALSE);
+ }
+ }
+}
+
+//static
+void LLFloaterReg::restoreVisibleInstances()
+{
+ // Iterate through all active instances and restore visibility
+ for (instance_map_t::iterator iter = sInstanceMap.begin(); iter != sInstanceMap.end(); ++iter)
+ {
+ instance_list_t& list = iter->second;
+ for (instance_list_t::iterator iter = list.begin(); iter != list.end(); ++iter)
+ {
+ LLFloater* floater = *iter;
+ floater->popVisible();
+ }
+ }
+}
+
+//static
+std::string LLFloaterReg::getRectControlName(const std::string& name)
+{
+ std::string res = std::string("floater_rect_") + name;
+ LLStringUtil::replaceChar( res, ' ', '_' );
+ return res;
+}
+
+//static
+std::string LLFloaterReg::declareRectControl(const std::string& name)
+{
+ std::string controlname = getRectControlName(name);
+ LLUI::sSettingGroups["floater"]->declareRect(controlname, LLRect(),
+ llformat("Window Position and Size for %s", name.c_str()),
+ TRUE);
+ return controlname;
+}
+
+//static
+std::string LLFloaterReg::getVisibilityControlName(const std::string& name)
+{
+ std::string res = std::string("floater_vis_") + name;
+ LLStringUtil::replaceChar( res, ' ', '_' );
+ return res;
+}
+
+//static
+std::string LLFloaterReg::declareVisibilityControl(const std::string& name)
+{
+ std::string controlname = getVisibilityControlName(name);
+ LLUI::sSettingGroups["floater"]->declareBOOL(controlname, FALSE,
+ llformat("Window Visibility for %s", name.c_str()),
+ TRUE);
+ return controlname;
+}
+
+//static
+void LLFloaterReg::registerControlVariables()
+{
+ // Iterate through alll registered instance names and register rect and visibility control variables
+ for (build_map_t::iterator iter = sBuildMap.begin(); iter != sBuildMap.end(); ++iter)
+ {
+ const std::string& name = iter->first;
+ if (LLUI::sSettingGroups["floater"]->controlExists(getRectControlName(name)))
+ {
+ declareRectControl(name);
+ }
+ if (LLUI::sSettingGroups["floater"]->controlExists(getVisibilityControlName(name)))
+ {
+ declareVisibilityControl(name);
+ }
+ }
+}
+
+// Callbacks
+
+// static
+// Call once (i.e use for init callbacks)
+void LLFloaterReg::initUICtrlToFloaterVisibilityControl(LLUICtrl* ctrl, const LLSD& sdname)
+{
+ // Get the visibility control name for the floater
+ std::string vis_control_name = LLFloaterReg::declareVisibilityControl(sdname.asString());
+ // Set the control value to the floater visibility control (Sets the value as well)
+ ctrl->setControlVariable(LLUI::sSettingGroups["floater"]->getControl(vis_control_name));
+}
+
+// callback args may use "floatername.key" format
+static void parse_name_key(std::string& name, LLSD& key)
+{
+ std::string instname = name;
+ std::size_t dotpos = instname.find(".");
+ if (dotpos != std::string::npos)
+ {
+ name = instname.substr(0, dotpos);
+ key = LLSD(instname.substr(dotpos+1, std::string::npos));
+ }
+}
+
+//static
+void LLFloaterReg::showFloaterInstance(const LLSD& sdname)
+{
+ LLSD key;
+ std::string name = sdname.asString();
+ parse_name_key(name, key);
+ showInstance(name, key, TRUE);
+}
+//static
+void LLFloaterReg::hideFloaterInstance(const LLSD& sdname)
+{
+ LLSD key;
+ std::string name = sdname.asString();
+ parse_name_key(name, key);
+ hideInstance(name, key);
+}
+//static
+void LLFloaterReg::toggleFloaterInstance(const LLSD& sdname)
+{
+ LLSD key;
+ std::string name = sdname.asString();
+ parse_name_key(name, key);
+ toggleInstance(name, key);
+}
+
+//static
+bool LLFloaterReg::floaterInstanceVisible(const LLSD& sdname)
+{
+ LLSD key;
+ std::string name = sdname.asString();
+ parse_name_key(name, key);
+ return instanceVisible(name, key);
+}
+
diff --git a/indra/llui/llfloaterreg.h b/indra/llui/llfloaterreg.h
new file mode 100644
index 0000000000..7edac43c96
--- /dev/null
+++ b/indra/llui/llfloaterreg.h
@@ -0,0 +1,153 @@
+/**
+ * @file llfloaterreg.h
+ * @brief LLFloaterReg Floater Registration Class
+ *
+ * $LicenseInfo:firstyear=2002&license=viewergpl$
+ *
+ * Copyright (c) 2002-2009, Linden Research, Inc.
+ *
+ * Second Life Viewer Source Code
+ * The source code in this file ("Source Code") is provided by Linden Lab
+ * to you under the terms of the GNU General Public License, version 2.0
+ * ("GPL"), unless you have obtained a separate licensing agreement
+ * ("Other License"), formally executed by you and Linden Lab. Terms of
+ * the GPL can be found in doc/GPL-license.txt in this distribution, or
+ * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
+ *
+ * There are special exceptions to the terms and conditions of the GPL as
+ * it is applied to this Source Code. View the full text of the exception
+ * in the file doc/FLOSS-exception.txt in this software distribution, or
+ * online at
+ * http://secondlifegrid.net/programs/open_source/licensing/flossexception
+ *
+ * By copying, modifying or distributing this software, you acknowledge
+ * that you have read and understood your obligations described above,
+ * and agree to abide by those obligations.
+ *
+ * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+ * COMPLETENESS OR PERFORMANCE.
+ * $/LicenseInfo$
+ */
+#ifndef LLFLOATERREG_H
+#define LLFLOATERREG_H
+
+/// llcommon
+#include "llboost.h"
+#include "llrect.h"
+#include "llstl.h"
+#include "llsd.h"
+
+/// llui
+#include "lluictrl.h"
+
+#include <boost/function.hpp>
+
+//*******************************************************
+//
+// Floater Class Registry
+//
+
+class LLFloater;
+
+typedef boost::function<LLFloater* (const LLSD& key)> LLFloaterBuildFunc;
+
+class LLFloaterReg
+{
+public:
+ // We use a list of LLFloater's instead of a set for two reasons:
+ // 1) With a list we have a predictable ordering, useful for finding the last opened floater of a given type.
+ // 2) We can change the key of a floater without altering the list.
+ typedef std::list<LLFloater*> instance_list_t;
+ typedef const instance_list_t const_instance_list_t;
+ typedef std::map<std::string, instance_list_t> instance_map_t;
+
+ struct BuildData
+ {
+ LLFloaterBuildFunc mFunc;
+ std::string mFile;
+ };
+ typedef std::map<std::string, BuildData> build_map_t;
+
+private:
+ static instance_list_t sNullInstanceList;
+ static instance_map_t sInstanceMap;
+ static build_map_t sBuildMap;
+ static std::map<std::string,std::string> sGroupMap;
+
+public:
+ // Registration
+
+ // usage: LLFloaterClassRegistry::add("foo", (LLFloaterBuildFunc)&LLFloaterClassRegistry::build<LLFloaterFoo>);
+ template <class T>
+ static LLFloater* build(const LLSD& key)
+ {
+ T* floater = new T(key);
+ return floater;
+ }
+
+ static void add(const std::string& name, const std::string& file, const LLFloaterBuildFunc& func,
+ const std::string& groupname = LLStringUtil::null);
+
+ // Helpers
+ static LLRect getFloaterRect(const std::string& name);
+
+ // Find / get (create) / remove / destroy
+ static LLFloater* findInstance(const std::string& name, const LLSD& key = LLSD());
+ static LLFloater* getInstance(const std::string& name, const LLSD& key = LLSD());
+ static LLFloater* removeInstance(const std::string& name, const LLSD& key = LLSD());
+ static bool destroyInstance(const std::string& name, const LLSD& key = LLSD());
+
+ // Iterators
+ static const_instance_list_t& getFloaterList(const std::string& name);
+
+ // Visibility Management
+ // return NULL if instance not found or can't create instance (no builder)
+ static LLFloater* showInstance(const std::string& name, const LLSD& key = LLSD(), BOOL focus = FALSE);
+ // Close a floater (may destroy or set invisible)
+ // return false if can't find instance
+ static bool hideInstance(const std::string& name, const LLSD& key = LLSD());
+ // return true if instance is visible:
+ static bool toggleInstance(const std::string& name, const LLSD& key = LLSD());
+ static bool instanceVisible(const std::string& name, const LLSD& key = LLSD());
+
+ static void showInitialVisibleInstances();
+ static void hideVisibleInstances(const std::set<std::string>& exceptions = std::set<std::string>());
+ static void restoreVisibleInstances();
+
+ // Control Variables
+ static std::string getRectControlName(const std::string& name);
+ static std::string declareRectControl(const std::string& name);
+ static std::string getVisibilityControlName(const std::string& name);
+ static std::string declareVisibilityControl(const std::string& name);
+ static void registerControlVariables();
+
+ // Callback wrappers
+ static void initUICtrlToFloaterVisibilityControl(LLUICtrl* ctrl, const LLSD& sdname);
+ static void showFloaterInstance(const LLSD& sdname);
+ static void hideFloaterInstance(const LLSD& sdname);
+ static void toggleFloaterInstance(const LLSD& sdname);
+ static bool floaterInstanceVisible(const LLSD& sdname);
+
+ // Typed find / get / show
+ template <class T>
+ static T* findTypedInstance(const std::string& name, const LLSD& key = LLSD())
+ {
+ return dynamic_cast<T*>(findInstance(name, key));
+ }
+
+ template <class T>
+ static T* getTypedInstance(const std::string& name, const LLSD& key = LLSD())
+ {
+ return dynamic_cast<T*>(getInstance(name, key));
+ }
+
+ template <class T>
+ static T* showTypedInstance(const std::string& name, const LLSD& key = LLSD(), BOOL focus = FALSE)
+ {
+ return dynamic_cast<T*>(showInstance(name, key, focus));
+ }
+
+};
+
+#endif
diff --git a/indra/llui/llflyoutbutton.cpp b/indra/llui/llflyoutbutton.cpp
new file mode 100644
index 0000000000..3483bac782
--- /dev/null
+++ b/indra/llui/llflyoutbutton.cpp
@@ -0,0 +1,82 @@
+/**
+ * @file llflyoutbutton.cpp
+ * @brief LLFlyoutButton base class
+ *
+ * $LicenseInfo:firstyear=2001&license=viewergpl$
+ *
+ * Copyright (c) 2001-2009, Linden Research, Inc.
+ *
+ * Second Life Viewer Source Code
+ * The source code in this file ("Source Code") is provided by Linden Lab
+ * to you under the terms of the GNU General Public License, version 2.0
+ * ("GPL"), unless you have obtained a separate licensing agreement
+ * ("Other License"), formally executed by you and Linden Lab. Terms of
+ * the GPL can be found in doc/GPL-license.txt in this distribution, or
+ * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
+ *
+ * There are special exceptions to the terms and conditions of the GPL as
+ * it is applied to this Source Code. View the full text of the exception
+ * in the file doc/FLOSS-exception.txt in this software distribution, or
+ * online at
+ * http://secondlifegrid.net/programs/open_source/licensing/flossexception
+ *
+ * By copying, modifying or distributing this software, you acknowledge
+ * that you have read and understood your obligations described above,
+ * and agree to abide by those obligations.
+ *
+ * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+ * COMPLETENESS OR PERFORMANCE.
+ * $/LicenseInfo$
+ */
+
+#include "linden_common.h"
+
+// file includes
+#include "llflyoutbutton.h"
+
+//static LLDefaultChildRegistry::Register<LLFlyoutButton> r2("flyout_button");
+
+const S32 FLYOUT_BUTTON_ARROW_WIDTH = 24;
+
+LLFlyoutButton::LLFlyoutButton(const Params& p)
+: LLComboBox(p),
+ mToggleState(FALSE),
+ mActionButton(NULL)
+{
+ // Always use text box
+ // Text label button
+ LLButton::Params bp(p.action_button);
+ bp.name(p.label);
+ bp.rect.left(0).bottom(0).width(getRect().getWidth() - FLYOUT_BUTTON_ARROW_WIDTH).height(getRect().getHeight());
+ bp.click_callback.function(boost::bind(&LLFlyoutButton::onActionButtonClick, this, _2));
+ bp.follows.flags(FOLLOWS_ALL);
+
+ mActionButton = LLUICtrlFactory::create<LLButton>(bp);
+ addChild(mActionButton);
+}
+
+void LLFlyoutButton::onActionButtonClick(const LLSD& data)
+{
+ // remember last list selection?
+ mList->deselect();
+ onCommit();
+}
+
+void LLFlyoutButton::draw()
+{
+ mActionButton->setToggleState(mToggleState);
+ mButton->setToggleState(mToggleState);
+
+ //FIXME: this should be an attribute of comboboxes, whether they have a distinct label or
+ // the label reflects the last selected item, for now we have to manually remove the label
+ setLabel(LLStringUtil::null);
+ LLComboBox::draw();
+}
+
+void LLFlyoutButton::setToggleState(BOOL state)
+{
+ mToggleState = state;
+}
+
+
diff --git a/indra/llui/llflyoutbutton.h b/indra/llui/llflyoutbutton.h
new file mode 100644
index 0000000000..d8c0f1a50d
--- /dev/null
+++ b/indra/llui/llflyoutbutton.h
@@ -0,0 +1,74 @@
+/**
+ * @file llflyoutbutton.h
+ * @brief LLFlyoutButton base class
+ *
+ * $LicenseInfo:firstyear=2001&license=viewergpl$
+ *
+ * Copyright (c) 2001-2009, Linden Research, Inc.
+ *
+ * Second Life Viewer Source Code
+ * The source code in this file ("Source Code") is provided by Linden Lab
+ * to you under the terms of the GNU General Public License, version 2.0
+ * ("GPL"), unless you have obtained a separate licensing agreement
+ * ("Other License"), formally executed by you and Linden Lab. Terms of
+ * the GPL can be found in doc/GPL-license.txt in this distribution, or
+ * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
+ *
+ * There are special exceptions to the terms and conditions of the GPL as
+ * it is applied to this Source Code. View the full text of the exception
+ * in the file doc/FLOSS-exception.txt in this software distribution, or
+ * online at
+ * http://secondlifegrid.net/programs/open_source/licensing/flossexception
+ *
+ * By copying, modifying or distributing this software, you acknowledge
+ * that you have read and understood your obligations described above,
+ * and agree to abide by those obligations.
+ *
+ * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+ * COMPLETENESS OR PERFORMANCE.
+ * $/LicenseInfo$
+ */
+
+// A control that displays the name of the chosen item, which when clicked
+// shows a scrolling box of choices.
+
+#ifndef LL_LLFLYOUTBUTTON_H
+#define LL_LLFLYOUTBUTTON_H
+
+#include "llcombobox.h"
+
+// Classes
+
+class LLFlyoutButton : public LLComboBox
+{
+public:
+ struct Params : public LLInitParam::Block<Params, LLComboBox::Params>
+ {
+ Optional<LLButton::Params> action_button;
+ Deprecated allow_text_entry;
+
+ Params()
+ : action_button("action_button"),
+ allow_text_entry("allow_text_entry")
+ {
+ LLComboBox::Params::allow_text_entry = false;
+ }
+
+ };
+protected:
+ LLFlyoutButton(const Params&);
+ friend class LLUICtrlFactory;
+public:
+ virtual void draw();
+
+ void setToggleState(BOOL state);
+
+ void onActionButtonClick(const LLSD& data);
+
+protected:
+ LLButton* mActionButton;
+ BOOL mToggleState;
+};
+
+#endif // LL_LLFLYOUTBUTTON_H
diff --git a/indra/llui/llfocusmgr.cpp b/indra/llui/llfocusmgr.cpp
index 661ffdd467..60ddbc6cb3 100644
--- a/indra/llui/llfocusmgr.cpp
+++ b/indra/llui/llfocusmgr.cpp
@@ -38,6 +38,77 @@
const F32 FOCUS_FADE_TIME = 0.3f;
+// NOTE: the LLFocusableElement implementation has been moved here from lluictrl.cpp.
+
+LLFocusableElement::LLFocusableElement()
+: mFocusLostCallback(NULL),
+ mFocusReceivedCallback(NULL),
+ mFocusChangedCallback(NULL),
+ mTopLostCallback(NULL),
+ mFocusCallbackUserData(NULL)
+{
+}
+
+// virtual
+BOOL LLFocusableElement::handleKey(KEY key, MASK mask, BOOL called_from_parent)
+{
+ return FALSE;
+}
+
+// virtual
+BOOL LLFocusableElement::handleUnicodeChar(llwchar uni_char, BOOL called_from_parent)
+{
+ return FALSE;
+}
+
+// virtual
+LLFocusableElement::~LLFocusableElement()
+{
+}
+
+void LLFocusableElement::onFocusReceived()
+{
+ if( mFocusReceivedCallback )
+ {
+ mFocusReceivedCallback( this, mFocusCallbackUserData );
+ }
+ if( mFocusChangedCallback )
+ {
+ mFocusChangedCallback( this, mFocusCallbackUserData );
+ }
+}
+
+void LLFocusableElement::onFocusLost()
+{
+ if( mFocusLostCallback )
+ {
+ mFocusLostCallback( this, mFocusCallbackUserData );
+ }
+
+ if( mFocusChangedCallback )
+ {
+ mFocusChangedCallback( this, mFocusCallbackUserData );
+ }
+}
+
+void LLFocusableElement::onTopLost()
+{
+ if (mTopLostCallback)
+ {
+ mTopLostCallback(this, mFocusCallbackUserData);
+ }
+}
+
+BOOL LLFocusableElement::hasFocus() const
+{
+ return gFocusMgr.getKeyboardFocus() == this;
+}
+
+void LLFocusableElement::setFocus(BOOL b)
+{
+}
+
+
LLFocusMgr gFocusMgr;
LLFocusMgr::LLFocusMgr()
@@ -49,7 +120,6 @@ LLFocusMgr::LLFocusMgr()
mDefaultKeyboardFocus( NULL ),
mKeystrokesOnly(FALSE),
mTopCtrl( NULL ),
- mFocusWeight(0.f),
mAppHasFocus(TRUE) // Macs don't seem to notify us that we've gotten focus, so default to true
#ifdef _DEBUG
, mMouseCaptorName("none")
@@ -87,19 +157,25 @@ void LLFocusMgr::releaseFocusIfNeeded( const LLView* view )
}
-void LLFocusMgr::setKeyboardFocus(LLUICtrl* new_focus, BOOL lock, BOOL keystrokes_only)
+void LLFocusMgr::setKeyboardFocus(LLFocusableElement* new_focus, BOOL lock, BOOL keystrokes_only)
{
+ // notes if keyboard focus is changed again (by onFocusLost/onFocusReceived)
+ // making the rest of our processing unnecessary since it will already be
+ // handled by the recursive call
+ static bool focus_dirty;
+ focus_dirty = false;
+
if (mLockedView &&
(new_focus == NULL ||
- (new_focus != mLockedView && !new_focus->hasAncestor(mLockedView))))
+ (new_focus != mLockedView
+ && dynamic_cast<LLView*>(new_focus)
+ && !dynamic_cast<LLView*>(new_focus)->hasAncestor(mLockedView))))
{
// don't allow focus to go to anything that is not the locked focus
// or one of its descendants
return;
}
- //llinfos << "Keyboard focus handled by " << (new_focus ? new_focus->getName() : "nothing") << llendl;
-
mKeystrokesOnly = keystrokes_only;
if( new_focus != mKeyboardFocus )
@@ -107,21 +183,65 @@ void LLFocusMgr::setKeyboardFocus(LLUICtrl* new_focus, BOOL lock, BOOL keystroke
mLastKeyboardFocus = mKeyboardFocus;
mKeyboardFocus = new_focus;
- if( mLastKeyboardFocus )
+ // list of the focus and it's ancestors
+ view_handle_list_t old_focus_list = mCachedKeyboardFocusList;
+ view_handle_list_t new_focus_list;
+
+ // walk up the tree to root and add all views to the new_focus_list
+ for (LLView* ctrl = dynamic_cast<LLView*>(mKeyboardFocus); ctrl && ctrl != LLUI::getRootView(); ctrl = ctrl->getParent())
+ {
+ if (ctrl)
+ {
+ new_focus_list.push_back(ctrl->getHandle());
+ }
+ }
+
+ // remove all common ancestors since their focus is unchanged
+ while (!new_focus_list.empty() &&
+ !old_focus_list.empty() &&
+ new_focus_list.back() == old_focus_list.back())
{
- mLastKeyboardFocus->onFocusLost();
+ new_focus_list.pop_back();
+ old_focus_list.pop_back();
+ }
+
+ // walk up the old focus branch calling onFocusLost
+ // we bubble up the tree to release focus, and back down to add
+ for (view_handle_list_t::iterator old_focus_iter = old_focus_list.begin();
+ old_focus_iter != old_focus_list.end() && !focus_dirty;
+ old_focus_iter++)
+ {
+ LLView* old_focus_view = old_focus_iter->get();
+ if (old_focus_view)
+ {
+ mCachedKeyboardFocusList.pop_front();
+ old_focus_view->onFocusLost();
+ }
}
- // clear out any existing flash
- if (new_focus)
+ // walk down the new focus branch calling onFocusReceived
+ for (view_handle_list_t::reverse_iterator new_focus_riter = new_focus_list.rbegin();
+ new_focus_riter != new_focus_list.rend() && !focus_dirty;
+ new_focus_riter++)
+ {
+ LLView* new_focus_view = new_focus_riter->get();
+ if (new_focus_view)
+ {
+ mCachedKeyboardFocusList.push_front(new_focus_view->getHandle());
+ new_focus_view->onFocusReceived();
+ }
+ }
+
+ // if focus was changed as part of an onFocusLost or onFocusReceived call
+ // stop iterating on current list since it is now invalid
+ if (focus_dirty)
{
- mFocusWeight = 0.f;
- new_focus->onFocusReceived();
+ return;
}
- mFocusTimer.reset();
#ifdef _DEBUG
- mKeyboardFocusName = new_focus ? new_focus->getName() : std::string("none");
+ LLUICtrl* focus_ctrl = dynamic_cast<LLUICtrl*>(new_focus);
+ mKeyboardFocusName = focus_ctrl ? focus_ctrl->getName() : std::string("none");
#endif
// If we've got a default keyboard focus, and the caller is
@@ -131,8 +251,8 @@ void LLFocusMgr::setKeyboardFocus(LLUICtrl* new_focus, BOOL lock, BOOL keystroke
mDefaultKeyboardFocus->setFocus(TRUE);
}
- LLView* focus_subtree = mKeyboardFocus;
- LLView* viewp = mKeyboardFocus;
+ LLView* focus_subtree = dynamic_cast<LLView*>(mKeyboardFocus);
+ LLView* viewp = dynamic_cast<LLView*>(mKeyboardFocus);
// find root-most focus root
while(viewp)
{
@@ -146,7 +266,8 @@ void LLFocusMgr::setKeyboardFocus(LLUICtrl* new_focus, BOOL lock, BOOL keystroke
if (focus_subtree)
{
- mFocusHistory[focus_subtree->getHandle()] = mKeyboardFocus ? mKeyboardFocus->getHandle() : LLHandle<LLView>();
+ LLView* focused_view = dynamic_cast<LLView*>(mKeyboardFocus);
+ mFocusHistory[focus_subtree->getHandle()] = focused_view ? focused_view->getHandle() : LLHandle<LLView>();
}
}
@@ -154,13 +275,15 @@ void LLFocusMgr::setKeyboardFocus(LLUICtrl* new_focus, BOOL lock, BOOL keystroke
{
lockFocus();
}
+
+ focus_dirty = true;
}
// Returns TRUE is parent or any descedent of parent has keyboard focus.
BOOL LLFocusMgr::childHasKeyboardFocus(const LLView* parent ) const
{
- LLView* focus_view = mKeyboardFocus;
+ LLView* focus_view = dynamic_cast<LLView*>(mKeyboardFocus);
while( focus_view )
{
if( focus_view == parent )
@@ -190,7 +313,7 @@ BOOL LLFocusMgr::childHasMouseCapture( const LLView* parent ) const
return FALSE;
}
-void LLFocusMgr::removeKeyboardFocusWithoutCallback( const LLView* focus )
+void LLFocusMgr::removeKeyboardFocusWithoutCallback( const LLFocusableElement* focus )
{
// should be ok to unlock here, as you have to know the locked view
// in order to unlock it
@@ -220,24 +343,19 @@ void LLFocusMgr::setMouseCapture( LLMouseHandler* new_captor )
{
LLMouseHandler* old_captor = mMouseCaptor;
mMouseCaptor = new_captor;
- /*
- if (new_captor)
+
+ if (LLView::sDebugMouseHandling)
{
- if ( new_captor->getName() == "Stickto")
+ if (new_captor)
{
llinfos << "New mouse captor: " << new_captor->getName() << llendl;
}
else
{
- llinfos << "New mouse captor: " << new_captor->getName() << llendl;
+ llinfos << "New mouse captor: NULL" << llendl;
}
}
- else
- {
- llinfos << "New mouse captor: NULL" << llendl;
- }
- */
-
+
if( old_captor )
{
old_captor->onMouseCaptureLost();
@@ -295,7 +413,7 @@ void LLFocusMgr::setTopCtrl( LLUICtrl* new_top )
if (old_top)
{
- old_top->onLostTop();
+ old_top->onTopLost();
}
}
}
@@ -313,7 +431,7 @@ void LLFocusMgr::removeTopCtrlWithoutCallback( const LLUICtrl* top_view )
void LLFocusMgr::lockFocus()
{
- mLockedView = mKeyboardFocus;
+ mLockedView = dynamic_cast<LLUICtrl*>(mKeyboardFocus);
}
void LLFocusMgr::unlockFocus()
@@ -323,12 +441,13 @@ void LLFocusMgr::unlockFocus()
F32 LLFocusMgr::getFocusFlashAmt() const
{
- return clamp_rescale(getFocusTime(), 0.f, FOCUS_FADE_TIME, mFocusWeight, 0.f);
+ return clamp_rescale(mFocusFlashTimer.getElapsedTimeF32(), 0.f, FOCUS_FADE_TIME, 1.f, 0.f);
}
LLColor4 LLFocusMgr::getFocusColor() const
{
- LLColor4 focus_color = lerp(LLUI::sColorsGroup->getColor( "FocusColor" ), LLColor4::white, getFocusFlashAmt());
+ static LLUIColor focus_color_cached = LLUIColorTable::instance().getColor("FocusColor");
+ LLColor4 focus_color = lerp(focus_color_cached, LLColor4::white, getFocusFlashAmt());
// de-emphasize keyboard focus when app has lost focus (to avoid typing into wrong window problem)
if (!mAppHasFocus)
{
@@ -339,8 +458,7 @@ LLColor4 LLFocusMgr::getFocusColor() const
void LLFocusMgr::triggerFocusFlash()
{
- mFocusTimer.reset();
- mFocusWeight = 1.f;
+ mFocusFlashTimer.reset();
}
void LLFocusMgr::setAppHasFocus(BOOL focus)
diff --git a/indra/llui/llfocusmgr.h b/indra/llui/llfocusmgr.h
index aaeb25a870..d0adadd6d3 100644
--- a/indra/llui/llfocusmgr.h
+++ b/indra/llui/llfocusmgr.h
@@ -37,10 +37,44 @@
#include "llstring.h"
#include "llframetimer.h"
-#include "llview.h"
+#include "llui.h"
class LLUICtrl;
class LLMouseHandler;
+class LLView;
+
+// NOTE: the LLFocusableElement class declaration has been moved here from lluictrl.h.
+class LLFocusableElement
+{
+ friend class LLFocusMgr; // allow access to focus change handlers
+public:
+ LLFocusableElement();
+ virtual ~LLFocusableElement();
+
+ virtual void setFocus( BOOL b );
+ virtual BOOL hasFocus() const;
+
+ typedef boost::function<void(LLFocusableElement*, void*)> focus_callback_t;
+ void setFocusLostCallback(focus_callback_t cb, void* user_data = NULL) { mFocusLostCallback = cb; mFocusCallbackUserData = user_data; }
+ void setFocusReceivedCallback(focus_callback_t cb, void* user_data = NULL) { mFocusReceivedCallback = cb; mFocusCallbackUserData = user_data; }
+ void setFocusChangedCallback(focus_callback_t cb, void* user_data = NULL ) { mFocusChangedCallback = cb; mFocusCallbackUserData = user_data; }
+ void setTopLostCallback(focus_callback_t cb, void* user_data = NULL ) { mTopLostCallback = cb; mFocusCallbackUserData = user_data; }
+
+ // These were brought up the hierarchy from LLView so that we don't have to use dynamic_cast when dealing with keyboard focus.
+ virtual BOOL handleKey(KEY key, MASK mask, BOOL called_from_parent);
+ virtual BOOL handleUnicodeChar(llwchar uni_char, BOOL called_from_parent);
+
+protected:
+ virtual void onFocusReceived();
+ virtual void onFocusLost();
+ virtual void onTopLost(); // called when registered as top ctrl and user clicks elsewhere
+ focus_callback_t mFocusLostCallback;
+ focus_callback_t mFocusReceivedCallback;
+ focus_callback_t mFocusChangedCallback;
+ focus_callback_t mTopLostCallback;
+ void* mFocusCallbackUserData;
+};
+
class LLFocusMgr
{
@@ -55,15 +89,14 @@ public:
BOOL childHasMouseCapture( const LLView* parent ) const;
// Keyboard Focus
- void setKeyboardFocus(LLUICtrl* new_focus, BOOL lock = FALSE, BOOL keystrokes_only = FALSE); // new_focus = NULL to release the focus.
- LLUICtrl* getKeyboardFocus() const { return mKeyboardFocus; }
- LLUICtrl* getLastKeyboardFocus() const { return mLastKeyboardFocus; }
+ void setKeyboardFocus(LLFocusableElement* new_focus, BOOL lock = FALSE, BOOL keystrokes_only = FALSE); // new_focus = NULL to release the focus.
+ LLFocusableElement* getKeyboardFocus() const { return mKeyboardFocus; }
+ LLFocusableElement* getLastKeyboardFocus() const { return mLastKeyboardFocus; }
BOOL childHasKeyboardFocus( const LLView* parent ) const;
- void removeKeyboardFocusWithoutCallback( const LLView* focus );
+ void removeKeyboardFocusWithoutCallback( const LLFocusableElement* focus );
BOOL getKeystrokesOnly() { return mKeystrokesOnly; }
void setKeystrokesOnly(BOOL keystrokes_only) { mKeystrokesOnly = keystrokes_only; }
- F32 getFocusTime() const { return mFocusTimer.getElapsedTimeF32(); }
F32 getFocusFlashAmt() const;
S32 getFocusFlashWidth() const { return llround(lerp(1.f, 3.f, getFocusFlashAmt())); }
LLColor4 getFocusColor() const;
@@ -75,8 +108,8 @@ public:
// If setKeyboardFocus(NULL) is called, and there is a non-NULL default
// keyboard focus view, focus goes there. JC
- void setDefaultKeyboardFocus(LLUICtrl* default_focus) { mDefaultKeyboardFocus = default_focus; }
- LLUICtrl* getDefaultKeyboardFocus() const { return mDefaultKeyboardFocus; }
+ void setDefaultKeyboardFocus(LLFocusableElement* default_focus) { mDefaultKeyboardFocus = default_focus; }
+ LLFocusableElement* getDefaultKeyboardFocus() const { return mDefaultKeyboardFocus; }
// Top View
@@ -98,16 +131,19 @@ private:
LLMouseHandler* mMouseCaptor; // Mouse events are premptively routed to this object
// Keyboard Focus
- LLUICtrl* mKeyboardFocus; // Keyboard events are preemptively routed to this object
- LLUICtrl* mLastKeyboardFocus; // who last had focus
- LLUICtrl* mDefaultKeyboardFocus;
+ LLFocusableElement* mKeyboardFocus; // Keyboard events are preemptively routed to this object
+ LLFocusableElement* mLastKeyboardFocus; // who last had focus
+ LLFocusableElement* mDefaultKeyboardFocus;
BOOL mKeystrokesOnly;
+
+ // caching list of keyboard focus ancestors for calling onFocusReceived and onFocusLost
+ typedef std::list<LLHandle<LLView> > view_handle_list_t;
+ view_handle_list_t mCachedKeyboardFocusList;
// Top View
LLUICtrl* mTopCtrl;
- LLFrameTimer mFocusTimer;
- F32 mFocusWeight;
+ LLFrameTimer mFocusFlashTimer;
BOOL mAppHasFocus;
diff --git a/indra/llui/llfunctorregistry.h b/indra/llui/llfunctorregistry.h
index 8864f7af15..2c0bcc6012 100644
--- a/indra/llui/llfunctorregistry.h
+++ b/indra/llui/llfunctorregistry.h
@@ -40,7 +40,7 @@
#include <boost/function.hpp>
#include "llsd.h"
-#include "llmemory.h"
+#include "llsingleton.h"
/**
* @class LLFunctorRegistry
diff --git a/indra/llui/llhandle.h b/indra/llui/llhandle.h
new file mode 100644
index 0000000000..10a7fd4544
--- /dev/null
+++ b/indra/llui/llhandle.h
@@ -0,0 +1,171 @@
+/**
+* @file llhandle.h
+* @brief "Handle" to an object (usually a floater) whose lifetime you don't
+* control.
+*
+* $LicenseInfo:firstyear=2001&license=viewergpl$
+*
+* Copyright (c) 2001-2009, Linden Research, Inc.
+*
+* Second Life Viewer Source Code
+* The source code in this file ("Source Code") is provided by Linden Lab
+* to you under the terms of the GNU General Public License, version 2.0
+* ("GPL"), unless you have obtained a separate licensing agreement
+* ("Other License"), formally executed by you and Linden Lab. Terms of
+* the GPL can be found in doc/GPL-license.txt in this distribution, or
+* online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
+*
+* There are special exceptions to the terms and conditions of the GPL as
+* it is applied to this Source Code. View the full text of the exception
+* in the file doc/FLOSS-exception.txt in this software distribution, or
+* online at
+* http://secondlifegrid.net/programs/open_source/licensing/flossexception
+*
+* By copying, modifying or distributing this software, you acknowledge
+* that you have read and understood your obligations described above,
+* and agree to abide by those obligations.
+*
+* ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+* COMPLETENESS OR PERFORMANCE.
+* $/LicenseInfo$
+*/
+#ifndef LLHANDLE_H
+#define LLHANDLE_H
+
+#include "llpointer.h"
+
+template <typename T>
+class LLTombStone : public LLRefCount
+{
+public:
+ LLTombStone(T* target = NULL) : mTarget(target) {}
+
+ void setTarget(T* target) { mTarget = target; }
+ T* getTarget() const { return mTarget; }
+private:
+ T* mTarget;
+};
+
+// LLHandles are used to refer to objects whose lifetime you do not control or influence.
+// Calling get() on a handle will return a pointer to the referenced object or NULL,
+// if the object no longer exists. Note that during the lifetime of the returned pointer,
+// you are assuming that the object will not be deleted by any action you perform,
+// or any other thread, as normal when using pointers, so avoid using that pointer outside of
+// the local code block.
+//
+// https://wiki.lindenlab.com/mediawiki/index.php?title=LLHandle&oldid=79669
+
+template <typename T>
+class LLHandle
+{
+public:
+ LLHandle() : mTombStone(sDefaultTombStone) {}
+ const LLHandle<T>& operator =(const LLHandle<T>& other)
+ {
+ mTombStone = other.mTombStone;
+ return *this;
+ }
+
+ bool isDead() const
+ {
+ return mTombStone->getTarget() == NULL;
+ }
+
+ void markDead()
+ {
+ mTombStone = sDefaultTombStone;
+ }
+
+ T* get() const
+ {
+ return mTombStone->getTarget();
+ }
+
+ friend bool operator== (const LLHandle<T>& lhs, const LLHandle<T>& rhs)
+ {
+ return lhs.mTombStone == rhs.mTombStone;
+ }
+ friend bool operator!= (const LLHandle<T>& lhs, const LLHandle<T>& rhs)
+ {
+ return !(lhs == rhs);
+ }
+ friend bool operator< (const LLHandle<T>& lhs, const LLHandle<T>& rhs)
+ {
+ return lhs.mTombStone < rhs.mTombStone;
+ }
+ friend bool operator> (const LLHandle<T>& lhs, const LLHandle<T>& rhs)
+ {
+ return lhs.mTombStone > rhs.mTombStone;
+ }
+protected:
+
+protected:
+ LLPointer<LLTombStone<T> > mTombStone;
+
+private:
+ static LLPointer<LLTombStone<T> > sDefaultTombStone;
+};
+
+// initialize static "empty" tombstone pointer
+template <typename T> LLPointer<LLTombStone<T> > LLHandle<T>::sDefaultTombStone = new LLTombStone<T>();
+
+
+template <typename T>
+class LLRootHandle : public LLHandle<T>
+{
+public:
+ LLRootHandle(T* object) { bind(object); }
+ LLRootHandle() {};
+ ~LLRootHandle() { unbind(); }
+
+ // this is redundant, since a LLRootHandle *is* an LLHandle
+ LLHandle<T> getHandle() { return LLHandle<T>(*this); }
+
+ void bind(T* object)
+ {
+ // unbind existing tombstone
+ if (LLHandle<T>::mTombStone.notNull())
+ {
+ if (LLHandle<T>::mTombStone->getTarget() == object) return;
+ LLHandle<T>::mTombStone->setTarget(NULL);
+ }
+ // tombstone reference counted, so no paired delete
+ LLHandle<T>::mTombStone = new LLTombStone<T>(object);
+ }
+
+ void unbind()
+ {
+ LLHandle<T>::mTombStone->setTarget(NULL);
+ }
+
+ //don't allow copying of root handles, since there should only be one
+private:
+ LLRootHandle(const LLRootHandle& other) {};
+};
+
+// Use this as a mixin for simple classes that need handles and when you don't
+// want handles at multiple points of the inheritance hierarchy
+template <typename T>
+class LLHandleProvider
+{
+protected:
+ typedef LLHandle<T> handle_type_t;
+ LLHandleProvider()
+ {
+ // provided here to enforce T deriving from LLHandleProvider<T>
+ }
+
+ LLHandle<T> getHandle()
+ {
+ // perform lazy binding to avoid small tombstone allocations for handle
+ // providers whose handles are never referenced
+ mHandle.bind(static_cast<T*>(this));
+ return mHandle;
+ }
+
+private:
+ LLRootHandle<T> mHandle;
+};
+
+#endif
diff --git a/indra/llui/lliconctrl.cpp b/indra/llui/lliconctrl.cpp
index cb3b2a3a62..673c742e7a 100644
--- a/indra/llui/lliconctrl.cpp
+++ b/indra/llui/lliconctrl.cpp
@@ -40,65 +40,33 @@
#include "llcontrol.h"
#include "llui.h"
#include "lluictrlfactory.h"
+#include "lluiimage.h"
-const F32 RESOLUTION_BUMP = 1.f;
+static LLDefaultChildRegistry::Register<LLIconCtrl> r("icon");
-static LLRegisterWidget<LLIconCtrl> r("icon");
-
-LLIconCtrl::LLIconCtrl(const std::string& name, const LLRect &rect, const LLUUID &image_id)
-: LLUICtrl(name,
- rect,
- FALSE, // mouse opaque
- NULL, NULL,
- FOLLOWS_LEFT | FOLLOWS_TOP),
- mColor( LLColor4::white )
-{
- setImage( image_id );
- setTabStop(FALSE);
-}
-
-LLIconCtrl::LLIconCtrl(const std::string& name, const LLRect &rect, const std::string &image_name)
-: LLUICtrl(name,
- rect,
- FALSE, // mouse opaque
- NULL, NULL,
- FOLLOWS_LEFT | FOLLOWS_TOP),
- mColor( LLColor4::white ),
- mImageName(image_name)
+LLIconCtrl::Params::Params()
+: image("image_name"),
+ color("color"),
+ scale_image("scale_image")
{
- setImage( image_name );
- setTabStop(FALSE);
+ tab_stop = false;
+ mouse_opaque = false;
}
-
-LLIconCtrl::~LLIconCtrl()
-{
- mImagep = NULL;
-}
-
-
-void LLIconCtrl::setImage(const std::string& image_name)
+LLIconCtrl::LLIconCtrl(const LLIconCtrl::Params& p)
+: LLUICtrl(p),
+ mColor(p.color()),
+ mImagep(p.image)
{
- //RN: support UUIDs masquerading as strings
- if (LLUUID::validate(image_name))
+ if (mImagep.notNull())
{
- mImageID = LLUUID(image_name);
-
- setImage(mImageID);
- }
- else
- {
- mImageName = image_name;
- mImagep = LLUI::sImageProvider->getUIImage(image_name);
- mImageID.setNull();
+ LLUICtrl::setValue(mImagep->getName());
}
}
-void LLIconCtrl::setImage(const LLUUID& image_id)
+LLIconCtrl::~LLIconCtrl()
{
- mImageName.clear();
- mImagep = LLUI::sImageProvider->getUIImageByID(image_id);
- mImageID = image_id;
+ mImagep = NULL;
}
@@ -106,69 +74,45 @@ void LLIconCtrl::draw()
{
if( mImagep.notNull() )
{
- mImagep->draw(getLocalRect(), mColor );
+ mImagep->draw(getLocalRect(), mColor.get() );
}
LLUICtrl::draw();
}
+// virtual
+void LLIconCtrl::setAlpha(F32 alpha)
+{
+ LLColor4 temp = mColor.get();
+ temp.setAlpha(alpha);
+ mColor.set(temp);
+}
+
// virtual
+// value might be a string or a UUID
void LLIconCtrl::setValue(const LLSD& value )
{
- if (value.isUUID())
+ LLSD tvalue(value);
+ if (value.isString() && LLUUID::validate(value.asString()))
{
- setImage(value.asUUID());
+ //RN: support UUIDs masquerading as strings
+ tvalue = LLSD(LLUUID(value.asString()));
}
- else
+ LLUICtrl::setValue(tvalue);
+ if (tvalue.isUUID())
{
- setImage(value.asString());
+ mImagep = LLUI::getUIImageByID(tvalue.asUUID());
}
-}
-
-// virtual
-LLSD LLIconCtrl::getValue() const
-{
- LLSD ret = getImage();
- return ret;
-}
-
-// virtual
-LLXMLNodePtr LLIconCtrl::getXML(bool save_children) const
-{
- LLXMLNodePtr node = LLUICtrl::getXML();
-
- if (mImageName != "")
+ else
{
- node->createChild("image_name", TRUE)->setStringValue(mImageName);
+ mImagep = LLUI::getUIImage(tvalue.asString());
}
-
- node->createChild("color", TRUE)->setFloatValue(4, mColor.mV);
-
- return node;
}
-LLView* LLIconCtrl::fromXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFactory *factory)
+std::string LLIconCtrl::getImageName() const
{
- std::string name("icon");
- node->getAttributeString("name", name);
-
- LLRect rect;
- createRect(node, rect, parent, LLRect());
-
- std::string image_name;
- if (node->hasAttribute("image_name"))
- {
- node->getAttributeString("image_name", image_name);
- }
-
- LLColor4 color(LLColor4::white);
- LLUICtrlFactory::getAttributeColor(node,"color", color);
-
- LLIconCtrl* icon = new LLIconCtrl(name, rect, image_name);
-
- icon->setColor(color);
-
- icon->initFromXML(node, parent);
-
- return icon;
+ if (getValue().isString())
+ return getValue().asString();
+ else
+ return std::string();
}
diff --git a/indra/llui/lliconctrl.h b/indra/llui/lliconctrl.h
index 50778cf226..aceb70b9d5 100644
--- a/indra/llui/lliconctrl.h
+++ b/indra/llui/lliconctrl.h
@@ -37,7 +37,6 @@
#include "v4color.h"
#include "lluictrl.h"
#include "stdenums.h"
-#include "llimagegl.h"
class LLTextBox;
class LLUICtrlFactory;
@@ -45,35 +44,39 @@ class LLUICtrlFactory;
//
// Classes
//
+
+//
class LLIconCtrl
: public LLUICtrl
{
public:
- LLIconCtrl(const std::string& name, const LLRect &rect, const LLUUID &image_id);
- LLIconCtrl(const std::string& name, const LLRect &rect, const std::string &image_name);
+ struct Params : public LLInitParam::Block<Params, LLUICtrl::Params>
+ {
+ Optional<LLUIImage*> image;
+ Optional<LLUIColor> color;
+ Ignored scale_image;
+ Params();
+ };
+protected:
+ LLIconCtrl(const Params&);
+ friend class LLUICtrlFactory;
+public:
virtual ~LLIconCtrl();
// llview overrides
virtual void draw();
- void setImage(const std::string& image_name);
- void setImage(const LLUUID& image_name);
- const LLUUID &getImage() const { return mImageID; }
- std::string getImageName() const { return mImageName; }
-
- // Takes a UUID, wraps get/setImage
+ // lluictrl overrides
virtual void setValue(const LLSD& value );
- virtual LLSD getValue() const;
- void setColor(const LLColor4& color) { mColor = color; }
+ std::string getImageName() const;
+
+ /*virtual*/ void setAlpha(F32 alpha);
- virtual LLXMLNodePtr getXML(bool save_children = true) const;
- static LLView* fromXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFactory *factory);
+ void setColor(const LLColor4& color) { mColor = color; }
private:
- LLColor4 mColor;
- std::string mImageName;
- LLUUID mImageID;
+ LLUIColor mColor;
LLPointer<LLUIImage> mImagep;
};
diff --git a/indra/llui/llkeywords.cpp b/indra/llui/llkeywords.cpp
index 51ef3dbacf..ede32084d0 100644
--- a/indra/llui/llkeywords.cpp
+++ b/indra/llui/llkeywords.cpp
@@ -223,19 +223,21 @@ LLColor3 LLKeywords::readColor( const std::string& s )
{
F32 r, g, b;
r = g = b = 0.0f;
- S32 read = sscanf(s.c_str(), "%f, %f, %f]", &r, &g, &b );
- if( read != 3 ) /* Flawfinder: ignore */
+ S32 values_read = sscanf(s.c_str(), "%f, %f, %f]", &r, &g, &b );
+ if( values_read != 3 )
{
llinfos << " poorly formed color in keyword file" << llendl;
}
return LLColor3( r, g, b );
}
+LLFastTimer::DeclareTimer FTM_SYNTAX_COLORING("Syntax Coloring");
+
// Walk through a string, applying the rules specified by the keyword token list and
// create a list of color segments.
-void LLKeywords::findSegments(std::vector<LLTextSegment *>* seg_list, const LLWString& wtext, const LLColor4 &defaultColor)
+void LLKeywords::findSegments(std::vector<LLTextSegmentPtr>* seg_list, const LLWString& wtext, const LLColor4 &defaultColor, LLTextEditor& editor)
{
- std::for_each(seg_list->begin(), seg_list->end(), DeletePointer());
+ LLFastTimer ft(FTM_SYNTAX_COLORING);
seg_list->clear();
if( wtext.empty() )
@@ -243,9 +245,9 @@ void LLKeywords::findSegments(std::vector<LLTextSegment *>* seg_list, const LLWS
return;
}
- S32 text_len = wtext.size();
+ S32 text_len = wtext.size() + 1;
- seg_list->push_back( new LLTextSegment( LLColor3(defaultColor), 0, text_len ) );
+ seg_list->push_back( new LLNormalTextSegment( defaultColor, 0, text_len, editor ) );
const llwchar* base = wtext.c_str();
const llwchar* cur = base;
@@ -296,9 +298,9 @@ void LLKeywords::findSegments(std::vector<LLTextSegment *>* seg_list, const LLWS
}
S32 seg_end = cur - base;
- LLTextSegment* text_segment = new LLTextSegment( cur_token->getColor(), seg_start, seg_end );
+ LLTextSegmentPtr text_segment = new LLNormalTextSegment( cur_token->getColor(), seg_start, seg_end, editor );
text_segment->setToken( cur_token );
- insertSegment( seg_list, text_segment, text_len, defaultColor);
+ insertSegment( seg_list, text_segment, text_len, defaultColor, editor);
line_done = TRUE; // to break out of second loop.
break;
}
@@ -405,9 +407,9 @@ void LLKeywords::findSegments(std::vector<LLTextSegment *>* seg_list, const LLWS
}
- LLTextSegment* text_segment = new LLTextSegment( cur_delimiter->getColor(), seg_start, seg_end );
+ LLTextSegmentPtr text_segment = new LLNormalTextSegment( cur_delimiter->getColor(), seg_start, seg_end, editor );
text_segment->setToken( cur_delimiter );
- insertSegment( seg_list, text_segment, text_len, defaultColor);
+ insertSegment( seg_list, text_segment, text_len, defaultColor, editor);
// Note: we don't increment cur, since the end of one delimited seg may be immediately
// followed by the start of another one.
@@ -438,9 +440,9 @@ void LLKeywords::findSegments(std::vector<LLTextSegment *>* seg_list, const LLWS
// llinfos << "Seg: [" << word.c_str() << "]" << llendl;
- LLTextSegment* text_segment = new LLTextSegment( cur_token->getColor(), seg_start, seg_end );
+ LLTextSegmentPtr text_segment = new LLNormalTextSegment( cur_token->getColor(), seg_start, seg_end, editor );
text_segment->setToken( cur_token );
- insertSegment( seg_list, text_segment, text_len, defaultColor);
+ insertSegment( seg_list, text_segment, text_len, defaultColor, editor);
}
cur += seg_len;
continue;
@@ -455,25 +457,24 @@ void LLKeywords::findSegments(std::vector<LLTextSegment *>* seg_list, const LLWS
}
}
-void LLKeywords::insertSegment(std::vector<LLTextSegment*>* seg_list, LLTextSegment* new_segment, S32 text_len, const LLColor4 &defaultColor )
+void LLKeywords::insertSegment(std::vector<LLTextSegmentPtr>* seg_list, LLTextSegmentPtr new_segment, S32 text_len, const LLColor4 &defaultColor, LLTextEditor& editor )
{
- LLTextSegment* last = seg_list->back();
+ LLTextSegmentPtr last = seg_list->back();
S32 new_seg_end = new_segment->getEnd();
if( new_segment->getStart() == last->getStart() )
{
- *last = *new_segment;
- delete new_segment;
+ seg_list->pop_back();
}
else
{
last->setEnd( new_segment->getStart() );
- seg_list->push_back( new_segment );
}
+ seg_list->push_back( new_segment );
if( new_seg_end < text_len )
{
- seg_list->push_back( new LLTextSegment( defaultColor, new_seg_end, text_len ) );
+ seg_list->push_back( new LLNormalTextSegment( defaultColor, new_seg_end, text_len, editor ) );
}
}
diff --git a/indra/llui/llkeywords.h b/indra/llui/llkeywords.h
index 38f5e993c2..53377869ca 100644
--- a/indra/llui/llkeywords.h
+++ b/indra/llui/llkeywords.h
@@ -39,9 +39,10 @@
#include <map>
#include <list>
#include <deque>
+#include "llpointer.h"
class LLTextSegment;
-
+typedef LLPointer<LLTextSegment> LLTextSegmentPtr;
class LLKeywordToken
{
@@ -84,7 +85,7 @@ public:
BOOL loadFromFile(const std::string& filename);
BOOL isLoaded() const { return mLoaded; }
- void findSegments(std::vector<LLTextSegment *> *seg_list, const LLWString& text, const LLColor4 &defaultColor );
+ void findSegments(std::vector<LLTextSegmentPtr> *seg_list, const LLWString& text, const LLColor4 &defaultColor, class LLTextEditor& editor );
// Add the token as described
void addToken(LLKeywordToken::TOKEN_TYPE type,
@@ -103,7 +104,7 @@ public:
private:
LLColor3 readColor(const std::string& s);
- void insertSegment(std::vector<LLTextSegment *> *seg_list, LLTextSegment* new_segment, S32 text_len, const LLColor4 &defaultColor);
+ void insertSegment(std::vector<LLTextSegmentPtr> *seg_list, LLTextSegmentPtr new_segment, S32 text_len, const LLColor4 &defaultColor, class LLTextEditor& editor);
BOOL mLoaded;
word_token_map_t mWordTokenMap;
diff --git a/indra/llui/lllayoutstack.cpp b/indra/llui/lllayoutstack.cpp
new file mode 100644
index 0000000000..f98edec1f3
--- /dev/null
+++ b/indra/llui/lllayoutstack.cpp
@@ -0,0 +1,742 @@
+/**
+ * @file lllayoutstack.cpp
+ * @brief LLLayout class - dynamic stacking of UI elements
+ *
+ * $LicenseInfo:firstyear=2001&license=viewergpl$
+ *
+ * Copyright (c) 2001-2009, Linden Research, Inc.
+ *
+ * Second Life Viewer Source Code
+ * The source code in this file ("Source Code") is provided by Linden Lab
+ * to you under the terms of the GNU General Public License, version 2.0
+ * ("GPL"), unless you have obtained a separate licensing agreement
+ * ("Other License"), formally executed by you and Linden Lab. Terms of
+ * the GPL can be found in doc/GPL-license.txt in this distribution, or
+ * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
+ *
+ * There are special exceptions to the terms and conditions of the GPL as
+ * it is applied to this Source Code. View the full text of the exception
+ * in the file doc/FLOSS-exception.txt in this software distribution, or
+ * online at
+ * http://secondlifegrid.net/programs/open_source/licensing/flossexception
+ *
+ * By copying, modifying or distributing this software, you acknowledge
+ * that you have read and understood your obligations described above,
+ * and agree to abide by those obligations.
+ *
+ * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+ * COMPLETENESS OR PERFORMANCE.
+ * $/LicenseInfo$
+ */
+
+// Opaque view with a background and a border. Can contain LLUICtrls.
+
+#include "linden_common.h"
+
+#include "lllayoutstack.h"
+#include "llresizebar.h"
+#include "llcriticaldamp.h"
+
+static LLDefaultChildRegistry::Register<LLLayoutStack> register_layout_stack("layout_stack", &LLLayoutStack::fromXML);
+
+
+//
+// LLLayoutStack
+//
+struct LLLayoutStack::LayoutPanel
+{
+ LayoutPanel(LLPanel* panelp, ELayoutOrientation orientation, S32 min_width, S32 min_height, BOOL auto_resize, BOOL user_resize) : mPanel(panelp),
+ mMinWidth(min_width),
+ mMinHeight(min_height),
+ mAutoResize(auto_resize),
+ mUserResize(user_resize),
+ mOrientation(orientation),
+ mCollapsed(FALSE),
+ mCollapseAmt(0.f),
+ mVisibleAmt(1.f), // default to fully visible
+ mResizeBar(NULL)
+ {
+ LLResizeBar::Side side = (orientation == HORIZONTAL) ? LLResizeBar::RIGHT : LLResizeBar::BOTTOM;
+ LLRect resize_bar_rect = panelp->getRect();
+
+ S32 min_dim;
+ if (orientation == HORIZONTAL)
+ {
+ min_dim = mMinHeight;
+ }
+ else
+ {
+ min_dim = mMinWidth;
+ }
+ LLResizeBar::Params p;
+ p.name("resize");
+ p.resizing_view(mPanel);
+ p.min_size(min_dim);
+ p.side(side);
+ p.snapping_enabled(false);
+ mResizeBar = LLUICtrlFactory::create<LLResizeBar>(p);
+ // panels initialized as hidden should not start out partially visible
+ if (!mPanel->getVisible())
+ {
+ mVisibleAmt = 0.f;
+ }
+ }
+
+ ~LayoutPanel()
+ {
+ // probably not necessary, but...
+ delete mResizeBar;
+ mResizeBar = NULL;
+ }
+
+ F32 getCollapseFactor()
+ {
+ if (mOrientation == HORIZONTAL)
+ {
+ F32 collapse_amt =
+ clamp_rescale(mCollapseAmt, 0.f, 1.f, 1.f, (F32)mMinWidth / (F32)llmax(1, mPanel->getRect().getWidth()));
+ return mVisibleAmt * collapse_amt;
+ }
+ else
+ {
+ F32 collapse_amt =
+ clamp_rescale(mCollapseAmt, 0.f, 1.f, 1.f, llmin(1.f, (F32)mMinHeight / (F32)llmax(1, mPanel->getRect().getHeight())));
+ return mVisibleAmt * collapse_amt;
+ }
+ }
+
+ LLPanel* mPanel;
+ S32 mMinWidth;
+ S32 mMinHeight;
+ BOOL mAutoResize;
+ BOOL mUserResize;
+ BOOL mCollapsed;
+ LLResizeBar* mResizeBar;
+ ELayoutOrientation mOrientation;
+ F32 mVisibleAmt;
+ F32 mCollapseAmt;
+};
+
+LLLayoutStack::Params::Params()
+: orientation("orientation", std::string("vertical")),
+ animate("animate", true),
+ clip("clip", true),
+ border_size("border_size", LLCachedControl<S32>(*LLUI::sSettingGroups["config"], "UIResizeBarHeight", 0))
+{
+ name="stack";
+}
+
+LLLayoutStack::LLLayoutStack(const LLLayoutStack::Params& p)
+: LLView(p),
+ mMinWidth(0),
+ mMinHeight(0),
+ mPanelSpacing(p.border_size),
+ mOrientation((p.orientation() == "vertical") ? VERTICAL : HORIZONTAL),
+ mAnimate(p.animate),
+ mClip(p.clip)
+{}
+
+LLLayoutStack::~LLLayoutStack()
+{
+ e_panel_list_t panels = mPanels; // copy list of panel pointers
+ mPanels.clear(); // clear so that removeChild() calls don't cause trouble
+ std::for_each(panels.begin(), panels.end(), DeletePointer());
+}
+
+void LLLayoutStack::draw()
+{
+ updateLayout();
+
+ e_panel_list_t::iterator panel_it;
+ for (panel_it = mPanels.begin(); panel_it != mPanels.end(); ++panel_it)
+ {
+ // clip to layout rectangle, not bounding rectangle
+ LLRect clip_rect = (*panel_it)->mPanel->getRect();
+ // scale clipping rectangle by visible amount
+ if (mOrientation == HORIZONTAL)
+ {
+ clip_rect.mRight = clip_rect.mLeft + llround((F32)clip_rect.getWidth() * (*panel_it)->getCollapseFactor());
+ }
+ else
+ {
+ clip_rect.mBottom = clip_rect.mTop - llround((F32)clip_rect.getHeight() * (*panel_it)->getCollapseFactor());
+ }
+
+ LLPanel* panelp = (*panel_it)->mPanel;
+
+ LLLocalClipRect clip(clip_rect, mClip);
+ // only force drawing invisible children if visible amount is non-zero
+ drawChild(panelp, 0, 0, !clip_rect.isEmpty());
+ }
+}
+
+void LLLayoutStack::removeChild(LLView* view)
+{
+ LayoutPanel* embedded_panelp = findEmbeddedPanel(dynamic_cast<LLPanel*>(view));
+
+ if (embedded_panelp)
+ {
+ mPanels.erase(std::find(mPanels.begin(), mPanels.end(), embedded_panelp));
+ delete embedded_panelp;
+ }
+
+ // need to update resizebars
+
+ calcMinExtents();
+
+ LLView::removeChild(view);
+}
+
+BOOL LLLayoutStack::postBuild()
+{
+ updateLayout();
+ return TRUE;
+}
+
+static void get_attribute_s32_and_write(LLXMLNodePtr node,
+ const char* name,
+ S32 *value,
+ S32 default_value,
+ LLXMLNodePtr output_child)
+{
+ BOOL has_attr = node->getAttributeS32(name, *value);
+ if (has_attr && *value != default_value && output_child)
+ {
+ // create an attribute child node
+ LLXMLNodePtr child_attr = output_child->createChild(name, TRUE);
+ child_attr->setIntValue(*value);
+ }
+}
+
+static void get_attribute_bool_and_write(LLXMLNodePtr node,
+ const char* name,
+ BOOL *value,
+ BOOL default_value,
+ LLXMLNodePtr output_child)
+{
+ BOOL has_attr = node->getAttributeBOOL(name, *value);
+ if (has_attr && *value != default_value && output_child)
+ {
+ LLXMLNodePtr child_attr = output_child->createChild(name, TRUE);
+ child_attr->setBoolValue(*value);
+ }
+}
+//static
+LLView* LLLayoutStack::fromXML(LLXMLNodePtr node, LLView *parent, LLXMLNodePtr output_node)
+{
+ LLLayoutStack::Params p(LLUICtrlFactory::getDefaultParams<LLLayoutStack>());
+ LLXUIParser::instance().readXUI(node, p);
+
+ // Export must happen before setupParams() mungles rectangles and before
+ // this item gets added to parent (otherwise screws up last_child_rect
+ // logic). JC
+ if (output_node)
+ {
+ Params output_params(p);
+ setupParamsForExport(output_params, parent);
+ LLLayoutStack::Params default_params(LLUICtrlFactory::getDefaultParams<LLLayoutStack>());
+ output_node->setName(node->getName()->mString);
+ LLXUIParser::instance().writeXUI(
+ output_node, output_params, &default_params);
+ }
+
+ setupParams(p, parent);
+ LLLayoutStack* layout_stackp = LLUICtrlFactory::create<LLLayoutStack>(p);
+
+ if (parent && layout_stackp)
+ {
+ S32 tab_group = p.tab_group.isProvided() ? p.tab_group() : parent->getLastTabGroup();
+
+ parent->addChild(layout_stackp, tab_group);
+ }
+
+ for (LLXMLNodePtr child_node = node->getFirstChild(); child_node.notNull(); child_node = child_node->getNextSibling())
+ {
+ const S32 DEFAULT_MIN_WIDTH = 0;
+ const S32 DEFAULT_MIN_HEIGHT = 0;
+ const BOOL DEFAULT_AUTO_RESIZE = TRUE;
+
+ S32 min_width = DEFAULT_MIN_WIDTH;
+ S32 min_height = DEFAULT_MIN_HEIGHT;
+ BOOL auto_resize = DEFAULT_AUTO_RESIZE;
+
+ LLXMLNodePtr output_child;
+ if (output_node)
+ {
+ output_child = output_node->createChild("", FALSE);
+ }
+
+ // Layout stack allows child nodes to acquire additional attributes,
+ // such as "min_width" in: <button label="Foo" min_width="100"/>
+ // If these attributes exist and have non-default values, write them
+ // to the output node.
+ get_attribute_s32_and_write(child_node, "min_width", &min_width,
+ DEFAULT_MIN_WIDTH, output_child);
+ get_attribute_s32_and_write(child_node, "min_height", &min_height,
+ DEFAULT_MIN_HEIGHT, output_child);
+ get_attribute_bool_and_write(child_node, "auto_resize", &auto_resize,
+ DEFAULT_AUTO_RESIZE, output_child);
+
+ if (child_node->hasName("layout_panel"))
+ {
+ BOOL user_resize = TRUE;
+ get_attribute_bool_and_write(child_node, "user_resize", &user_resize,
+ TRUE, output_child);
+ LLPanel* panelp = (LLPanel*)LLPanel::fromXML(child_node, layout_stackp, output_child);
+ if (panelp)
+ {
+ panelp->setFollowsNone();
+ layout_stackp->addPanel(panelp, min_width, min_height, auto_resize, user_resize);
+ }
+ }
+ else
+ {
+ BOOL user_resize = FALSE;
+ get_attribute_bool_and_write(child_node, "user_resize", &user_resize,
+ FALSE, output_child);
+
+ LLPanel::Params p;
+ LLPanel* panelp = LLUICtrlFactory::create<LLPanel>(p);
+ LLView* new_child = LLUICtrlFactory::getInstance()->createFromXML(child_node, panelp, LLStringUtil::null, LLPanel::child_registry_t::instance(), output_child);
+ if (new_child)
+ {
+ // put child in new embedded panel
+ layout_stackp->addPanel(panelp, min_width, min_height, auto_resize, user_resize);
+ // resize panel to contain widget and move widget to be contained in panel
+ panelp->setRect(new_child->getRect());
+ new_child->setOrigin(0, 0);
+ }
+ else
+ {
+ panelp->die();
+ }
+ }
+
+ if (output_child && !output_child->mChildren && output_child->mAttributes.empty() && output_child->getValue().empty())
+ {
+ output_node->deleteChild(output_child);
+ }
+ }
+
+ if (!layout_stackp->postBuild())
+ {
+ delete layout_stackp;
+ return NULL;
+ }
+
+ return layout_stackp;
+}
+
+S32 LLLayoutStack::getDefaultHeight(S32 cur_height)
+{
+ // if we are spanning our children (crude upward propagation of size)
+ // then don't enforce our size on our children
+ if (mOrientation == HORIZONTAL)
+ {
+ cur_height = llmax(mMinHeight, getRect().getHeight());
+ }
+
+ return cur_height;
+}
+
+S32 LLLayoutStack::getDefaultWidth(S32 cur_width)
+{
+ // if we are spanning our children (crude upward propagation of size)
+ // then don't enforce our size on our children
+ if (mOrientation == VERTICAL)
+ {
+ cur_width = llmax(mMinWidth, getRect().getWidth());
+ }
+
+ return cur_width;
+}
+
+void LLLayoutStack::addPanel(LLPanel* panel, S32 min_width, S32 min_height, BOOL auto_resize, BOOL user_resize, EAnimate animate, S32 index)
+{
+ // panel starts off invisible (collapsed)
+ if (animate == ANIMATE)
+ {
+ panel->setVisible(FALSE);
+ }
+ LayoutPanel* embedded_panel = new LayoutPanel(panel, mOrientation, min_width, min_height, auto_resize, user_resize);
+
+ mPanels.insert(mPanels.begin() + llclamp(index, 0, (S32)mPanels.size()), embedded_panel);
+
+ if (panel->getParent() != this)
+ {
+ addChild(panel);
+ }
+ addChild(embedded_panel->mResizeBar);
+
+ // bring all resize bars to the front so that they are clickable even over the panels
+ // with a bit of overlap
+ for (e_panel_list_t::iterator panel_it = mPanels.begin(); panel_it != mPanels.end(); ++panel_it)
+ {
+ LLResizeBar* resize_barp = (*panel_it)->mResizeBar;
+ sendChildToFront(resize_barp);
+ }
+
+ // start expanding panel animation
+ if (animate == ANIMATE)
+ {
+ panel->setVisible(TRUE);
+ }
+}
+
+void LLLayoutStack::removePanel(LLPanel* panel)
+{
+ removeChild(panel);
+}
+
+void LLLayoutStack::collapsePanel(LLPanel* panel, BOOL collapsed)
+{
+ LayoutPanel* panel_container = findEmbeddedPanel(panel);
+ if (!panel_container) return;
+
+ panel_container->mCollapsed = collapsed;
+}
+
+void LLLayoutStack::updateLayout(BOOL force_resize)
+{
+ static LLUICachedControl<S32> resize_bar_overlap ("UIResizeBarOverlap", 0);
+ calcMinExtents();
+
+ // calculate current extents
+ S32 total_width = 0;
+ S32 total_height = 0;
+
+ const F32 ANIM_OPEN_TIME = 0.02f;
+ const F32 ANIM_CLOSE_TIME = 0.03f;
+
+ e_panel_list_t::iterator panel_it;
+ for (panel_it = mPanels.begin(); panel_it != mPanels.end(); ++panel_it)
+ {
+ LLPanel* panelp = (*panel_it)->mPanel;
+ if (panelp->getVisible())
+ {
+ if (mAnimate)
+ {
+ (*panel_it)->mVisibleAmt = lerp((*panel_it)->mVisibleAmt, 1.f, LLCriticalDamp::getInterpolant(ANIM_OPEN_TIME));
+ if ((*panel_it)->mVisibleAmt > 0.99f)
+ {
+ (*panel_it)->mVisibleAmt = 1.f;
+ }
+ }
+ else
+ {
+ (*panel_it)->mVisibleAmt = 1.f;
+ }
+ }
+ else // not visible
+ {
+ if (mAnimate)
+ {
+ (*panel_it)->mVisibleAmt = lerp((*panel_it)->mVisibleAmt, 0.f, LLCriticalDamp::getInterpolant(ANIM_CLOSE_TIME));
+ if ((*panel_it)->mVisibleAmt < 0.001f)
+ {
+ (*panel_it)->mVisibleAmt = 0.f;
+ }
+ }
+ else
+ {
+ (*panel_it)->mVisibleAmt = 0.f;
+ }
+ }
+
+ if ((*panel_it)->mCollapsed)
+ {
+ (*panel_it)->mCollapseAmt = lerp((*panel_it)->mCollapseAmt, 1.f, LLCriticalDamp::getInterpolant(ANIM_CLOSE_TIME));
+ }
+ else
+ {
+ (*panel_it)->mCollapseAmt = lerp((*panel_it)->mCollapseAmt, 0.f, LLCriticalDamp::getInterpolant(ANIM_CLOSE_TIME));
+ }
+
+ if (mOrientation == HORIZONTAL)
+ {
+ // enforce minimize size constraint by default
+ if (panelp->getRect().getWidth() < (*panel_it)->mMinWidth)
+ {
+ panelp->reshape((*panel_it)->mMinWidth, panelp->getRect().getHeight());
+ }
+ total_width += llround(panelp->getRect().getWidth() * (*panel_it)->getCollapseFactor());
+ // want n-1 panel gaps for n panels
+ if (panel_it != mPanels.begin())
+ {
+ total_width += mPanelSpacing;
+ }
+ }
+ else //VERTICAL
+ {
+ // enforce minimize size constraint by default
+ if (panelp->getRect().getHeight() < (*panel_it)->mMinHeight)
+ {
+ panelp->reshape(panelp->getRect().getWidth(), (*panel_it)->mMinHeight);
+ }
+ total_height += llround(panelp->getRect().getHeight() * (*panel_it)->getCollapseFactor());
+ if (panel_it != mPanels.begin())
+ {
+ total_height += mPanelSpacing;
+ }
+ }
+ }
+
+ S32 num_resizable_panels = 0;
+ S32 shrink_headroom_available = 0;
+ S32 shrink_headroom_total = 0;
+ for (panel_it = mPanels.begin(); panel_it != mPanels.end(); ++panel_it)
+ {
+ // panels that are not fully visible do not count towards shrink headroom
+ if ((*panel_it)->getCollapseFactor() < 1.f)
+ {
+ continue;
+ }
+
+ // if currently resizing a panel or the panel is flagged as not automatically resizing
+ // only track total available headroom, but don't use it for automatic resize logic
+ if ((*panel_it)->mResizeBar->hasMouseCapture()
+ || (!(*panel_it)->mAutoResize
+ && !force_resize))
+ {
+ if (mOrientation == HORIZONTAL)
+ {
+ shrink_headroom_total += (*panel_it)->mPanel->getRect().getWidth() - (*panel_it)->mMinWidth;
+ }
+ else //VERTICAL
+ {
+ shrink_headroom_total += (*panel_it)->mPanel->getRect().getHeight() - (*panel_it)->mMinHeight;
+ }
+ }
+ else
+ {
+ num_resizable_panels++;
+ if (mOrientation == HORIZONTAL)
+ {
+ shrink_headroom_available += (*panel_it)->mPanel->getRect().getWidth() - (*panel_it)->mMinWidth;
+ shrink_headroom_total += (*panel_it)->mPanel->getRect().getWidth() - (*panel_it)->mMinWidth;
+ }
+ else //VERTICAL
+ {
+ shrink_headroom_available += (*panel_it)->mPanel->getRect().getHeight() - (*panel_it)->mMinHeight;
+ shrink_headroom_total += (*panel_it)->mPanel->getRect().getHeight() - (*panel_it)->mMinHeight;
+ }
+ }
+ }
+
+ // calculate how many pixels need to be distributed among layout panels
+ // positive means panels need to grow, negative means shrink
+ S32 pixels_to_distribute;
+ if (mOrientation == HORIZONTAL)
+ {
+ pixels_to_distribute = getRect().getWidth() - total_width;
+ }
+ else //VERTICAL
+ {
+ pixels_to_distribute = getRect().getHeight() - total_height;
+ }
+
+ // now we distribute the pixels...
+ S32 cur_x = 0;
+ S32 cur_y = getRect().getHeight();
+
+ for (panel_it = mPanels.begin(); panel_it != mPanels.end(); ++panel_it)
+ {
+ LLPanel* panelp = (*panel_it)->mPanel;
+
+ S32 cur_width = panelp->getRect().getWidth();
+ S32 cur_height = panelp->getRect().getHeight();
+ S32 new_width = llmax((*panel_it)->mMinWidth, cur_width);
+ S32 new_height = llmax((*panel_it)->mMinHeight, cur_height);
+
+ S32 delta_size = 0;
+
+ // if panel can automatically resize (not animating, and resize flag set)...
+ if ((*panel_it)->getCollapseFactor() == 1.f
+ && (force_resize || (*panel_it)->mAutoResize)
+ && !(*panel_it)->mResizeBar->hasMouseCapture())
+ {
+ if (mOrientation == HORIZONTAL)
+ {
+ // if we're shrinking
+ if (pixels_to_distribute < 0)
+ {
+ // shrink proportionally to amount over minimum
+ // so we can do this in one pass
+ delta_size = (shrink_headroom_available > 0) ? llround((F32)pixels_to_distribute * ((F32)(cur_width - (*panel_it)->mMinWidth) / (F32)shrink_headroom_available)) : 0;
+ shrink_headroom_available -= (cur_width - (*panel_it)->mMinWidth);
+ }
+ else
+ {
+ // grow all elements equally
+ delta_size = llround((F32)pixels_to_distribute / (F32)num_resizable_panels);
+ num_resizable_panels--;
+ }
+ pixels_to_distribute -= delta_size;
+ new_width = llmax((*panel_it)->mMinWidth, cur_width + delta_size);
+ }
+ else
+ {
+ new_width = getDefaultWidth(new_width);
+ }
+
+ if (mOrientation == VERTICAL)
+ {
+ if (pixels_to_distribute < 0)
+ {
+ // shrink proportionally to amount over minimum
+ // so we can do this in one pass
+ delta_size = (shrink_headroom_available > 0) ? llround((F32)pixels_to_distribute * ((F32)(cur_height - (*panel_it)->mMinHeight) / (F32)shrink_headroom_available)) : 0;
+ shrink_headroom_available -= (cur_height - (*panel_it)->mMinHeight);
+ }
+ else
+ {
+ delta_size = llround((F32)pixels_to_distribute / (F32)num_resizable_panels);
+ num_resizable_panels--;
+ }
+ pixels_to_distribute -= delta_size;
+ new_height = llmax((*panel_it)->mMinHeight, cur_height + delta_size);
+ }
+ else
+ {
+ new_height = getDefaultHeight(new_height);
+ }
+ }
+ else
+ {
+ if (mOrientation == HORIZONTAL)
+ {
+ new_height = getDefaultHeight(new_height);
+ }
+ else // VERTICAL
+ {
+ new_width = getDefaultWidth(new_width);
+ }
+ }
+
+ // adjust running headroom count based on new sizes
+ shrink_headroom_total += delta_size;
+
+ panelp->reshape(new_width, new_height);
+ panelp->setOrigin(cur_x, cur_y - new_height);
+
+ LLRect panel_rect = panelp->getRect();
+ LLRect resize_bar_rect = panel_rect;
+ if (mOrientation == HORIZONTAL)
+ {
+ resize_bar_rect.mLeft = panel_rect.mRight - resize_bar_overlap;
+ resize_bar_rect.mRight = panel_rect.mRight + mPanelSpacing + resize_bar_overlap;
+ }
+ else
+ {
+ resize_bar_rect.mTop = panel_rect.mBottom + resize_bar_overlap;
+ resize_bar_rect.mBottom = panel_rect.mBottom - mPanelSpacing - resize_bar_overlap;
+ }
+ (*panel_it)->mResizeBar->setRect(resize_bar_rect);
+
+ if (mOrientation == HORIZONTAL)
+ {
+ cur_x += llround(new_width * (*panel_it)->getCollapseFactor()) + mPanelSpacing;
+ }
+ else //VERTICAL
+ {
+ cur_y -= llround(new_height * (*panel_it)->getCollapseFactor()) + mPanelSpacing;
+ }
+ }
+
+ // update resize bars with new limits
+ LLResizeBar* last_resize_bar = NULL;
+ for (panel_it = mPanels.begin(); panel_it != mPanels.end(); ++panel_it)
+ {
+ LLPanel* panelp = (*panel_it)->mPanel;
+
+ if (mOrientation == HORIZONTAL)
+ {
+ (*panel_it)->mResizeBar->setResizeLimits(
+ (*panel_it)->mMinWidth,
+ (*panel_it)->mMinWidth + shrink_headroom_total);
+ }
+ else //VERTICAL
+ {
+ (*panel_it)->mResizeBar->setResizeLimits(
+ (*panel_it)->mMinHeight,
+ (*panel_it)->mMinHeight + shrink_headroom_total);
+ }
+
+ // toggle resize bars based on panel visibility, resizability, etc
+ BOOL resize_bar_enabled = panelp->getVisible() && (*panel_it)->mUserResize;
+ (*panel_it)->mResizeBar->setVisible(resize_bar_enabled);
+
+ if (resize_bar_enabled)
+ {
+ last_resize_bar = (*panel_it)->mResizeBar;
+ }
+ }
+
+ // hide last resize bar as there is nothing past it
+ // resize bars need to be in between two resizable panels
+ if (last_resize_bar)
+ {
+ last_resize_bar->setVisible(FALSE);
+ }
+
+ // not enough room to fit existing contents
+ if (force_resize == FALSE
+ // layout did not complete by reaching target position
+ && ((mOrientation == VERTICAL && cur_y != -mPanelSpacing)
+ || (mOrientation == HORIZONTAL && cur_x != getRect().getWidth() + mPanelSpacing)))
+ {
+ // do another layout pass with all stacked elements contributing
+ // even those that don't usually resize
+ llassert_always(force_resize == FALSE);
+ updateLayout(TRUE);
+ }
+} // end LLLayoutStack::updateLayout
+
+
+LLLayoutStack::LayoutPanel* LLLayoutStack::findEmbeddedPanel(LLPanel* panelp) const
+{
+ if (!panelp) return NULL;
+
+ e_panel_list_t::const_iterator panel_it;
+ for (panel_it = mPanels.begin(); panel_it != mPanels.end(); ++panel_it)
+ {
+ if ((*panel_it)->mPanel == panelp)
+ {
+ return *panel_it;
+ }
+ }
+ return NULL;
+}
+
+// Compute sum of min_width or min_height of children
+void LLLayoutStack::calcMinExtents()
+{
+ mMinWidth = 0;
+ mMinHeight = 0;
+
+ e_panel_list_t::iterator panel_it;
+ for (panel_it = mPanels.begin(); panel_it != mPanels.end(); ++panel_it)
+ {
+ if (mOrientation == HORIZONTAL)
+ {
+ mMinHeight = llmax( mMinHeight,
+ (*panel_it)->mMinHeight);
+ mMinWidth += (*panel_it)->mMinWidth;
+ if (panel_it != mPanels.begin())
+ {
+ mMinWidth += mPanelSpacing;
+ }
+ }
+ else //VERTICAL
+ {
+ mMinWidth = llmax( mMinWidth,
+ (*panel_it)->mMinWidth);
+ mMinHeight += (*panel_it)->mMinHeight;
+ if (panel_it != mPanels.begin())
+ {
+ mMinHeight += mPanelSpacing;
+ }
+ }
+ }
+}
diff --git a/indra/llui/lllayoutstack.h b/indra/llui/lllayoutstack.h
new file mode 100644
index 0000000000..9459b9990c
--- /dev/null
+++ b/indra/llui/lllayoutstack.h
@@ -0,0 +1,107 @@
+/**
+ * @file lllayoutstack.h
+ * @author Richard Nelson
+ * @brief LLLayout class - dynamic stacking of UI elements
+ *
+ * $LicenseInfo:firstyear=2001&license=viewergpl$
+ *
+ * Copyright (c) 2001-2009, Linden Research, Inc.
+ *
+ * Second Life Viewer Source Code
+ * The source code in this file ("Source Code") is provided by Linden Lab
+ * to you under the terms of the GNU General Public License, version 2.0
+ * ("GPL"), unless you have obtained a separate licensing agreement
+ * ("Other License"), formally executed by you and Linden Lab. Terms of
+ * the GPL can be found in doc/GPL-license.txt in this distribution, or
+ * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
+ *
+ * There are special exceptions to the terms and conditions of the GPL as
+ * it is applied to this Source Code. View the full text of the exception
+ * in the file doc/FLOSS-exception.txt in this software distribution, or
+ * online at
+ * http://secondlifegrid.net/programs/open_source/licensing/flossexception
+ *
+ * By copying, modifying or distributing this software, you acknowledge
+ * that you have read and understood your obligations described above,
+ * and agree to abide by those obligations.
+ *
+ * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+ * COMPLETENESS OR PERFORMANCE.
+ * $/LicenseInfo$
+ */
+
+#ifndef LL_LLLAYOUTSTACK_H
+#define LL_LLLAYOUTSTACK_H
+
+#include "llpanel.h"
+
+class LLLayoutStack : public LLView
+{
+public:
+ struct Params : public LLInitParam::Block<Params, LLView::Params>
+ {
+ Optional<std::string> orientation;
+ Optional<S32> border_size;
+ Optional<bool> animate;
+ Optional<bool> clip;
+ // mMinWidth and mMinHeight are calculated, not set in XML
+
+ Params();
+ };
+
+ typedef enum e_layout_orientation
+ {
+ HORIZONTAL,
+ VERTICAL
+ } ELayoutOrientation;
+
+ virtual ~LLLayoutStack();
+
+ /*virtual*/ void draw();
+ /*virtual*/ void removeChild(LLView*);
+ /*virtual*/ BOOL postBuild();
+
+ static LLView* fromXML(LLXMLNodePtr node, LLView *parent, LLXMLNodePtr output_node = NULL);
+
+ S32 getMinWidth() const { return mMinWidth; }
+ S32 getMinHeight() const { return mMinHeight; }
+
+ typedef enum e_animate
+ {
+ NO_ANIMATE,
+ ANIMATE
+ } EAnimate;
+
+ void addPanel(LLPanel* panel, S32 min_width, S32 min_height, BOOL auto_resize, BOOL user_resize, EAnimate animate = NO_ANIMATE, S32 index = S32_MAX);
+ void removePanel(LLPanel* panel);
+ void collapsePanel(LLPanel* panel, BOOL collapsed = TRUE);
+ S32 getNumPanels() { return mPanels.size(); }
+
+protected:
+ LLLayoutStack(const Params&);
+ friend class LLUICtrlFactory;
+
+private:
+ struct LayoutPanel;
+
+ void updateLayout(BOOL force_resize = FALSE);
+ void calcMinExtents();
+ S32 getDefaultHeight(S32 cur_height);
+ S32 getDefaultWidth(S32 cur_width);
+
+ const ELayoutOrientation mOrientation;
+
+ typedef std::vector<LayoutPanel*> e_panel_list_t;
+ e_panel_list_t mPanels;
+ LayoutPanel* findEmbeddedPanel(LLPanel* panelp) const;
+
+ S32 mMinWidth; // calculated by calcMinExtents
+ S32 mMinHeight; // calculated by calcMinExtents
+ S32 mPanelSpacing;
+
+ bool mAnimate;
+ bool mClip;
+}; // end class LLLayoutStack
+
+#endif
diff --git a/indra/llui/lllazyvalue.h b/indra/llui/lllazyvalue.h
new file mode 100644
index 0000000000..cf45214628
--- /dev/null
+++ b/indra/llui/lllazyvalue.h
@@ -0,0 +1,88 @@
+/**
+ * @file lllazyvalue.h
+ * @brief generic functor/value abstraction for lazy evaluation of a value
+ * parsing construction parameters from xml and LLSD
+ *
+ * $LicenseInfo:firstyear=2008&license=viewergpl$
+ *
+ * Copyright (c) 2008-2009, Linden Research, Inc.
+ *
+ * Second Life Viewer Source Code
+ * The source code in this file ("Source Code") is provided by Linden Lab
+ * to you under the terms of the GNU General Public License, version 2.0
+ * ("GPL"), unless you have obtained a separate licensing agreement
+ * ("Other License"), formally executed by you and Linden Lab. Terms of
+ * the GPL can be found in doc/GPL-license.txt in this distribution, or
+ * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
+ *
+ * There are special exceptions to the terms and conditions of the GPL as
+ * it is applied to this Source Code. View the full text of the exception
+ * in the file doc/FLOSS-exception.txt in this software distribution, or
+ * online at
+ * http://secondlifegrid.net/programs/open_source/licensing/flossexception
+ *
+ * By copying, modifying or distributing this software, you acknowledge
+ * that you have read and understood your obligations described above,
+ * and agree to abide by those obligations.
+ *
+ * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+ * COMPLETENESS OR PERFORMANCE.
+ * $/LicenseInfo$
+ */
+
+#ifndef LL_LAZY_VALUE_H
+#define LL_LAZY_VALUE_H
+
+#include <boost/function.hpp>
+
+// Holds on to a value of type T *or* calls a functor to generate a value of type T
+template<typename T>
+class LLLazyValue
+{
+public:
+ typedef typename boost::add_reference<typename boost::add_const<T>::type>::type T_const_ref;
+ typedef typename boost::function<T_const_ref (void)> function_type;
+
+public:
+ LLLazyValue(const function_type& value)
+ : mValueGetter(value)
+ {}
+ LLLazyValue(T_const_ref value)
+ : mValue(value)
+ {}
+ LLLazyValue()
+ : mValue()
+ {}
+
+ void set(const LLLazyValue& val)
+ {
+ mValueGetter = val.mValueGetter;
+ }
+
+ void set(T_const_ref val)
+ {
+ mValue = val;
+ mValueGetter = NULL;
+ }
+
+ T_const_ref get() const
+ {
+ if (!mValueGetter.empty())
+ {
+ return mValueGetter();
+ }
+ return mValue;
+ }
+
+ bool isUsingFunction() const
+ {
+ return mValueGetter != NULL;
+ }
+
+private:
+ function_type mValueGetter;
+ T mValue;
+};
+
+#endif // LL_LAZY_VALUE_H
diff --git a/indra/llui/lllineeditor.cpp b/indra/llui/lllineeditor.cpp
index 964254d93f..5435b9ffbf 100644
--- a/indra/llui/lllineeditor.cpp
+++ b/indra/llui/lllineeditor.cpp
@@ -37,7 +37,6 @@
#include "lllineeditor.h"
#include "lltexteditor.h"
-#include "audioengine.h"
#include "llmath.h"
#include "llfontgl.h"
#include "llgl.h"
@@ -64,79 +63,108 @@
// Constants
//
-const S32 UI_LINEEDITOR_CURSOR_THICKNESS = 2;
-const S32 UI_LINEEDITOR_H_PAD = 2;
-const S32 UI_LINEEDITOR_V_PAD = 1;
const F32 CURSOR_FLASH_DELAY = 1.0f; // in seconds
const S32 SCROLL_INCREMENT_ADD = 0; // make space for typing
const S32 SCROLL_INCREMENT_DEL = 4; // make space for baskspacing
const F32 AUTO_SCROLL_TIME = 0.05f;
+const F32 TRIPLE_CLICK_INTERVAL = 0.3f; // delay between double and triple click. *TODO: make this equal to the double click interval?
-const F32 PREEDIT_MARKER_BRIGHTNESS = 0.4f;
-const S32 PREEDIT_MARKER_GAP = 1;
-const S32 PREEDIT_MARKER_POSITION = 2;
-const S32 PREEDIT_MARKER_THICKNESS = 1;
-const F32 PREEDIT_STANDOUT_BRIGHTNESS = 0.6f;
-const S32 PREEDIT_STANDOUT_GAP = 1;
-const S32 PREEDIT_STANDOUT_POSITION = 2;
-const S32 PREEDIT_STANDOUT_THICKNESS = 2;
-
-static LLRegisterWidget<LLLineEditor> r1("line_editor");
-
-/* static */ LLPointer<LLUIImage> LLLineEditor::sImage;
+static LLDefaultChildRegistry::Register<LLLineEditor> r1("line_editor");
//
// Member functions
//
-
-LLLineEditor::LLLineEditor(const std::string& name, const LLRect& rect,
- const std::string& default_text, const LLFontGL* font,
- S32 max_length_bytes,
- void (*commit_callback)(LLUICtrl* caller, void* user_data ),
- void (*keystroke_callback)(LLLineEditor* caller, void* user_data ),
- void (*focus_lost_callback)(LLFocusableElement* caller, void* user_data ),
- void* userdata,
- LLLinePrevalidateFunc prevalidate_func,
- LLViewBorder::EBevel border_bevel,
- LLViewBorder::EStyle border_style,
- S32 border_thickness)
- :
- LLUICtrl( name, rect, TRUE, commit_callback, userdata, FOLLOWS_TOP | FOLLOWS_LEFT ),
- mMaxLengthBytes(max_length_bytes),
- mCursorPos( 0 ),
- mScrollHPos( 0 ),
- mTextPadLeft(0),
- mTextPadRight(0),
- mCommitOnFocusLost( TRUE ),
- mRevertOnEsc( TRUE ),
- mKeystrokeCallback( keystroke_callback ),
- mIsSelecting( FALSE ),
- mSelectionStart( 0 ),
- mSelectionEnd( 0 ),
- mLastSelectionX(-1),
- mLastSelectionY(-1),
- mLastSelectionStart(-1),
- mLastSelectionEnd(-1),
- mPrevalidateFunc( prevalidate_func ),
- mCursorColor( LLUI::sColorsGroup->getColor( "TextCursorColor" ) ),
- mFgColor( LLUI::sColorsGroup->getColor( "TextFgColor" ) ),
- mReadOnlyFgColor( LLUI::sColorsGroup->getColor( "TextFgReadOnlyColor" ) ),
- mTentativeFgColor( LLUI::sColorsGroup->getColor( "TextFgTentativeColor" ) ),
- mWriteableBgColor( LLUI::sColorsGroup->getColor( "TextBgWriteableColor" ) ),
- mReadOnlyBgColor( LLUI::sColorsGroup->getColor( "TextBgReadOnlyColor" ) ),
- mFocusBgColor( LLUI::sColorsGroup->getColor( "TextBgFocusColor" ) ),
- mBorderThickness( border_thickness ),
- mIgnoreArrowKeys( FALSE ),
- mIgnoreTab( TRUE ),
- mDrawAsterixes( FALSE ),
- mHandleEditKeysDirectly( FALSE ),
- mSelectAllonFocusReceived( FALSE ),
- mPassDelete(FALSE),
- mReadOnly(FALSE),
- mImage( sImage ),
- mReplaceNewlinesWithSpaces( TRUE )
-{
- llassert( max_length_bytes > 0 );
+
+void LLLineEditor::PrevalidateNamedFuncs::declareValues()
+{
+ declare("ascii", LLLineEditor::prevalidateASCII);
+ declare("float", LLLineEditor::prevalidateFloat);
+ declare("int", LLLineEditor::prevalidateInt);
+ declare("positive_s32", LLLineEditor::prevalidatePositiveS32);
+ declare("non_negative_s32", LLLineEditor::prevalidateNonNegativeS32);
+ declare("alpha_num", LLLineEditor::prevalidateAlphaNum);
+ declare("alpha_num_space", LLLineEditor::prevalidateAlphaNumSpace);
+ declare("printable_not_pipe", LLLineEditor::prevalidatePrintableNotPipe);
+ declare("printable_no_space", LLLineEditor::prevalidatePrintableNoSpace);
+}
+
+LLLineEditor::Params::Params()
+: max_length_bytes("max_length", 254),
+ keystroke_callback("keystroke_callback"),
+ prevalidate_callback("prevalidate_callback"),
+ background_image("background_image"),
+ background_image_disabled("background_image_disabled"),
+ background_image_focused("background_image_focused"),
+ select_on_focus("select_on_focus", false),
+ handle_edit_keys_directly("handle_edit_keys_directly", false),
+ commit_on_focus_lost("commit_on_focus_lost", true),
+ ignore_tab("ignore_tab", true),
+ cursor_color("cursor_color"),
+ text_color("text_color"),
+ text_readonly_color("text_readonly_color"),
+ text_tentative_color("text_tentative_color"),
+ highlight_color("highlight_color"),
+ preedit_bg_color("preedit_bg_color"),
+ border(""),
+ is_unicode("is_unicode"),
+ drop_shadow_visible("drop_shadow_visible"),
+ border_drop_shadow_visible("border_drop_shadow_visible"),
+ bg_visible("bg_visible"),
+ text_pad_left("text_pad_left"),
+ text_pad_right("text_pad_right"),
+ default_text("default_text")
+{
+ mouse_opaque = true;
+ addSynonym(select_on_focus, "select_all_on_focus_received");
+ addSynonym(border, "border");
+ addSynonym(label, "watermark_text");
+}
+
+LLLineEditor::LLLineEditor(const LLLineEditor::Params& p)
+: LLUICtrl(p),
+ mMaxLengthBytes(p.max_length_bytes),
+ mCursorPos( 0 ),
+ mScrollHPos( 0 ),
+ mTextPadLeft(p.text_pad_left),
+ mTextPadRight(p.text_pad_right),
+ mMinHPixels(0), // computed in updateTextPadding() below
+ mMaxHPixels(0), // computed in updateTextPadding() below
+ mCommitOnFocusLost( p.commit_on_focus_lost ),
+ mRevertOnEsc( TRUE ),
+ mKeystrokeCallback( p.keystroke_callback() ),
+ mIsSelecting( FALSE ),
+ mSelectionStart( 0 ),
+ mSelectionEnd( 0 ),
+ mLastSelectionX(-1),
+ mLastSelectionY(-1),
+ mLastSelectionStart(-1),
+ mLastSelectionEnd(-1),
+ mBorderThickness( 0 ),
+ mIgnoreArrowKeys( FALSE ),
+ mIgnoreTab( p.ignore_tab ),
+ mDrawAsterixes( FALSE ),
+ mHandleEditKeysDirectly(p.handle_edit_keys_directly),
+ mSelectAllonFocusReceived( p.select_on_focus ),
+ mPassDelete(FALSE),
+ mReadOnly(FALSE),
+ mBgImage( p.background_image ),
+ mBgImageDisabled( p.background_image_disabled ),
+ mBgImageFocused( p.background_image_focused ),
+ mReplaceNewlinesWithSpaces( TRUE ),
+ mLabel(p.label),
+ mCursorColor(p.cursor_color()),
+ mFgColor(p.text_color()),
+ mReadOnlyFgColor(p.text_readonly_color()),
+ mTentativeFgColor(p.text_tentative_color()),
+ mHighlightColor(p.highlight_color()),
+ mPreeditBgColor(p.preedit_bg_color()),
+ mGLFont(p.font)
+{
+ llassert( mMaxLengthBytes > 0 );
+
+ mScrollTimer.reset();
+ mTripleClickTimer.reset();
+ setText(p.default_text());
// line history support:
// - initialize line history list
@@ -146,40 +174,24 @@ LLLineEditor::LLLineEditor(const std::string& name, const LLRect& rect,
// - reset current history line pointer
mCurrentHistoryLine = 0;
- if (font)
- {
- mGLFont = font;
- }
- else
- {
- mGLFont = LLFontGL::getFontSansSerifSmall();
- }
-
- setFocusLostCallback(focus_lost_callback);
-
- setTextPadding(0, 0);
-
- mScrollTimer.reset();
+ LLRect border_rect(getLocalRect());
+ // adjust for gl line drawing glitch
+ border_rect.mTop -= 1;
+ border_rect.mRight -=1;
+ LLViewBorder::Params border_p(p.border);
+ border_p.rect = border_rect;
+ border_p.follows.flags = FOLLOWS_ALL;
+ border_p.bevel_style = LLViewBorder::BEVEL_IN;
+ mBorder = LLUICtrlFactory::create<LLViewBorder>(border_p);
+ addChild( mBorder );
- setText(default_text);
-
+ // clamp text padding to current editor size
+ updateTextPadding();
setCursor(mText.length());
- // Scalable UI somehow made these rectangles off-by-one.
- // I don't know why. JC
- LLRect border_rect(0, getRect().getHeight()-1, getRect().getWidth()-1, 0);
- mBorder = new LLViewBorder( std::string("line ed border"), border_rect, border_bevel, border_style, mBorderThickness );
- addChild( mBorder );
- mBorder->setFollows(FOLLOWS_LEFT|FOLLOWS_RIGHT|FOLLOWS_TOP|FOLLOWS_BOTTOM);
-
- if( ! sImage)
- {
- sImage = LLUI::getUIImage("sm_rounded_corners_simple.tga");
- }
- mImage = sImage;
+ setPrevalidate(p.prevalidate_callback());
}
-
-
+
LLLineEditor::~LLLineEditor()
{
mCommitOnFocusLost = FALSE;
@@ -222,15 +234,44 @@ void LLLineEditor::onFocusLost()
LLUICtrl::onFocusLost();
}
+// virtual
void LLLineEditor::onCommit()
{
// put current line into the line history
updateHistory();
+ setControlValue(getValue());
LLUICtrl::onCommit();
selectAll();
}
+// Returns TRUE if user changed value at all
+// virtual
+BOOL LLLineEditor::isDirty() const
+{
+ return mText.getString() != mPrevText;
+}
+
+// Clear dirty state
+// virtual
+void LLLineEditor::resetDirty()
+{
+ mPrevText = mText.getString();
+}
+
+// assumes UTF8 text
+// virtual
+void LLLineEditor::setValue(const LLSD& value )
+{
+ setText(value.asString());
+}
+
+//virtual
+LLSD LLLineEditor::getValue() const
+{
+ return LLSD(getText());
+}
+
// line history support
void LLLineEditor::updateHistory()
@@ -255,7 +296,7 @@ void LLLineEditor::updateHistory()
void LLLineEditor::reshape(S32 width, S32 height, BOOL called_from_parent)
{
LLUICtrl::reshape(width, height, called_from_parent);
- setTextPadding(mTextPadLeft, mTextPadRight); // For clamping side-effect.
+ updateTextPadding(); // For clamping side-effect.
setCursor(mCursorPos); // For clamping side-effect.
}
@@ -273,12 +314,11 @@ void LLLineEditor::setMaxTextLength(S32 max_text_length)
mMaxLengthBytes = max_len;
}
-void LLLineEditor::setTextPadding(S32 left, S32 right)
+void LLLineEditor::updateTextPadding()
{
- mTextPadLeft = llclamp(left, 0, getRect().getWidth());
- mTextPadRight = llclamp(right, 0, getRect().getWidth());
- mMinHPixels = UI_LINEEDITOR_H_PAD + mTextPadLeft;
- mMaxHPixels = getRect().getWidth() - mMinHPixels - mTextPadRight;
+ static LLUICachedControl<S32> line_editor_hpad ("UILineEditorHPad", 0);
+ mMinHPixels = line_editor_hpad + llclamp(mTextPadLeft, 0, getRect().getWidth());;
+ mMaxHPixels = getRect().getWidth() - mMinHPixels - llclamp(mTextPadRight, 0, getRect().getWidth());
}
@@ -362,7 +402,7 @@ void LLLineEditor::setCursor( S32 pos )
{
S32 width_chars_to_left = mGLFont->getWidth(mText.getWString().c_str(), 0, mScrollHPos);
S32 last_visible_char = mGLFont->maxDrawableChars(mText.getWString().c_str(), llmax(0.f, (F32)(mMaxHPixels - mMinHPixels + width_chars_to_left)));
- S32 min_scroll = mGLFont->firstDrawableChar(mText.getWString().c_str(), (F32)(mMaxHPixels - mMinHPixels - UI_LINEEDITOR_CURSOR_THICKNESS - UI_LINEEDITOR_H_PAD), mText.length(), getCursor());
+ S32 min_scroll = mGLFont->firstDrawableChar(mText.getWString().c_str(), (F32)(mMaxHPixels - mMinHPixels), mText.length(), getCursor());
if (old_cursor_pos == last_visible_char)
{
mScrollHPos = llmin(mText.length(), llmax(min_scroll, mScrollHPos + SCROLL_INCREMENT_ADD));
@@ -439,6 +479,7 @@ void LLLineEditor::selectAll()
BOOL LLLineEditor::handleDoubleClick(S32 x, S32 y, MASK mask)
{
setFocus( TRUE );
+ mTripleClickTimer.setTimerExpirySec(TRIPLE_CLICK_INTERVAL);
if (mSelectionEnd == 0 && mSelectionStart == mText.length())
{
@@ -452,19 +493,19 @@ BOOL LLLineEditor::handleDoubleClick(S32 x, S32 y, MASK mask)
BOOL doSelectAll = TRUE;
// Select the word we're on
- if( LLTextEditor::isPartOfWord( wtext[mCursorPos] ) )
+ if( LLWStringUtil::isPartOfWord( wtext[mCursorPos] ) )
{
S32 old_selection_start = mLastSelectionStart;
S32 old_selection_end = mLastSelectionEnd;
// Select word the cursor is over
- while ((mCursorPos > 0) && LLTextEditor::isPartOfWord( wtext[mCursorPos-1] ))
+ while ((mCursorPos > 0) && LLWStringUtil::isPartOfWord( wtext[mCursorPos-1] ))
{ // Find the start of the word
mCursorPos--;
}
startSelection();
- while ((mCursorPos < (S32)wtext.length()) && LLTextEditor::isPartOfWord( wtext[mCursorPos] ) )
+ while ((mCursorPos < (S32)wtext.length()) && LLWStringUtil::isPartOfWord( wtext[mCursorPos] ) )
{ // Find the end of the word
mCursorPos++;
}
@@ -555,14 +596,25 @@ BOOL LLLineEditor::handleMouseDown(S32 x, S32 y, MASK mask)
}
else
{
- // Save selection for word/line selecting on double-click
- mLastSelectionStart = mSelectionStart;
- mLastSelectionEnd = mSelectionEnd;
+ if (mTripleClickTimer.hasExpired())
+ {
+ // Save selection for word/line selecting on double-click
+ mLastSelectionStart = mSelectionStart;
+ mLastSelectionEnd = mSelectionEnd;
- // Move cursor and deselect for regular click
- setCursorAtLocalPos( x );
- deselect();
- startSelection();
+ // Move cursor and deselect for regular click
+ setCursorAtLocalPos( x );
+ deselect();
+ startSelection();
+ }
+ else // handle triple click
+ {
+ selectAll();
+ // We don't want handleMouseUp() to "finish" the selection (and thereby
+ // set mSelectionEnd to where the mouse is), so we finish the selection
+ // here.
+ mIsSelecting = FALSE;
+ }
}
gFocusMgr.setMouseCapture( this );
@@ -570,6 +622,8 @@ BOOL LLLineEditor::handleMouseDown(S32 x, S32 y, MASK mask)
// delay cursor flashing
mKeystrokeTimer.reset();
+
+ mMouseDownSignal(this,x,y,mask);
return TRUE;
}
@@ -683,7 +737,9 @@ BOOL LLLineEditor::handleMouseUp(S32 x, S32 y, MASK mask)
// take selection to 'primary' clipboard
updatePrimary();
}
-
+
+ // We won't call LLUICtrl::handleMouseUp to avoid double calls of childrenHandleMouseUp().Just invoke the signal manually.
+ mMouseUpSignal(this,x,y, mask);
return handled;
}
@@ -783,7 +839,7 @@ S32 LLLineEditor::prevWordPos(S32 cursorPos) const
{
cursorPos--;
}
- while( (cursorPos > 0) && LLTextEditor::isPartOfWord( wtext[cursorPos-1] ) )
+ while( (cursorPos > 0) && LLWStringUtil::isPartOfWord( wtext[cursorPos-1] ) )
{
cursorPos--;
}
@@ -793,7 +849,7 @@ S32 LLLineEditor::prevWordPos(S32 cursorPos) const
S32 LLLineEditor::nextWordPos(S32 cursorPos) const
{
const LLWString& wtext = mText.getWString();
- while( (cursorPos < getLength()) && LLTextEditor::isPartOfWord( wtext[cursorPos] ) )
+ while( (cursorPos < getLength()) && LLWStringUtil::isPartOfWord( wtext[cursorPos] ) )
{
cursorPos++;
}
@@ -936,7 +992,7 @@ void LLLineEditor::cut()
else
if( mKeystrokeCallback )
{
- mKeystrokeCallback( this, mCallbackUserData );
+ mKeystrokeCallback( this );
}
}
}
@@ -1057,7 +1113,7 @@ void LLLineEditor::pasteHelper(bool is_primary)
else
if( mKeystrokeCallback )
{
- mKeystrokeCallback( this, mCallbackUserData );
+ mKeystrokeCallback( this );
}
}
}
@@ -1370,7 +1426,7 @@ BOOL LLLineEditor::handleKeyHere(KEY key, MASK mask )
{
if (mKeystrokeCallback)
{
- mKeystrokeCallback(this, mCallbackUserData);
+ mKeystrokeCallback(this);
}
}
}
@@ -1420,7 +1476,7 @@ BOOL LLLineEditor::handleUnicodeCharHere(llwchar uni_char)
{
// HACK! The only usage of this callback doesn't do anything with the character.
// We'll have to do something about this if something ever changes! - Doug
- mKeystrokeCallback( this, mCallbackUserData );
+ mKeystrokeCallback( this );
}
}
}
@@ -1461,16 +1517,53 @@ void LLLineEditor::doDelete()
{
if( mKeystrokeCallback )
{
- mKeystrokeCallback( this, mCallbackUserData );
+ mKeystrokeCallback( this );
}
}
}
}
+void LLLineEditor::drawBackground()
+{
+ bool has_focus = hasFocus();
+ LLUIImage* image;
+ if ( mReadOnly )
+ {
+ image = mBgImageDisabled;
+ }
+ else if ( has_focus )
+ {
+ image = mBgImageFocused;
+ }
+ else
+ {
+ image = mBgImage;
+ }
+
+ // optionally draw programmatic border
+ if (has_focus)
+ {
+ image->drawBorder(0, 0, getRect().getWidth(), getRect().getHeight(),
+ gFocusMgr.getFocusColor(),
+ gFocusMgr.getFocusFlashWidth());
+ }
+ image->draw(getLocalRect());
+}
+
void LLLineEditor::draw()
{
S32 text_len = mText.length();
+ static LLUICachedControl<S32> lineeditor_cursor_thickness ("UILineEditorCursorThickness", 0);
+ static LLUICachedControl<S32> lineeditor_v_pad ("UILineEditorVPad", 0);
+ static LLUICachedControl<F32> preedit_marker_brightness ("UIPreeditMarkerBrightness", 0);
+ static LLUICachedControl<S32> preedit_marker_gap ("UIPreeditMarkerGap", 0);
+ static LLUICachedControl<S32> preedit_marker_position ("UIPreeditMarkerPosition", 0);
+ static LLUICachedControl<S32> preedit_marker_thickness ("UIPreeditMarkerThickness", 0);
+ static LLUICachedControl<F32> preedit_standout_brightness ("UIPreeditStandoutBrightness", 0);
+ static LLUICachedControl<S32> preedit_standout_gap ("UIPreeditStandoutGap", 0);
+ static LLUICachedControl<S32> preedit_standout_position ("UIPreeditStandoutPosition", 0);
+ static LLUICachedControl<S32> preedit_standout_thickness ("UIPreeditStandoutThickness", 0);
std::string saved_text;
if (mDrawAsterixes)
@@ -1488,37 +1581,12 @@ void LLLineEditor::draw()
LLRect background( 0, getRect().getHeight(), getRect().getWidth(), 0 );
background.stretch( -mBorderThickness );
- LLColor4 bg_color = mReadOnlyBgColor;
-
-#if 0 // for when we're ready for image art.
- if( hasFocus())
- {
- mImage->drawBorder(0, 0, getRect().getWidth(), getRect().getHeight(), gFocusMgr.getFocusColor(), gFocusMgr.getFocusFlashWidth());
- }
- mImage->draw(getLocalRect(), mReadOnly ? mReadOnlyBgColor : mWriteableBgColor );
-#else // the old programmer art.
- // drawing solids requires texturing be disabled
- {
- gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
- // draw background for text
- if( !mReadOnly )
- {
- if( gFocusMgr.getKeyboardFocus() == this )
- {
- bg_color = mFocusBgColor;
- }
- else
- {
- bg_color = mWriteableBgColor;
- }
- }
- gl_rect_2d(background, bg_color);
- }
-#endif
-
+ drawBackground();
+
// draw text
- S32 cursor_bottom = background.mBottom + 1;
+ // With viewer-2 art files, input region is 2 pixels up
+ S32 cursor_bottom = background.mBottom + 2;
S32 cursor_top = background.mTop - 1;
LLColor4 text_color;
@@ -1526,18 +1594,18 @@ void LLLineEditor::draw()
{
if (!getTentative())
{
- text_color = mFgColor;
+ text_color = mFgColor.get();
}
else
{
- text_color = mTentativeFgColor;
+ text_color = mTentativeFgColor.get();
}
}
else
{
- text_color = mReadOnlyFgColor;
+ text_color = mReadOnlyFgColor.get();
}
- LLColor4 label_color = mTentativeFgColor;
+ LLColor4 label_color = mTentativeFgColor.get();
if (hasPreeditString())
{
@@ -1556,19 +1624,21 @@ void LLLineEditor::draw()
}
if (mPreeditStandouts[i])
{
- gl_rect_2d(preedit_pixels_left + PREEDIT_STANDOUT_GAP,
- background.mBottom + PREEDIT_STANDOUT_POSITION,
- preedit_pixels_right - PREEDIT_STANDOUT_GAP - 1,
- background.mBottom + PREEDIT_STANDOUT_POSITION - PREEDIT_STANDOUT_THICKNESS,
- (text_color * PREEDIT_STANDOUT_BRIGHTNESS + bg_color * (1 - PREEDIT_STANDOUT_BRIGHTNESS)).setAlpha(1.0f));
+ gl_rect_2d(preedit_pixels_left + preedit_standout_gap,
+ background.mBottom + preedit_standout_position,
+ preedit_pixels_right - preedit_standout_gap - 1,
+ background.mBottom + preedit_standout_position - preedit_standout_thickness,
+ (text_color * preedit_standout_brightness
+ + mPreeditBgColor * (1 - preedit_standout_brightness)).setAlpha(1.0f));
}
else
{
- gl_rect_2d(preedit_pixels_left + PREEDIT_MARKER_GAP,
- background.mBottom + PREEDIT_MARKER_POSITION,
- preedit_pixels_right - PREEDIT_MARKER_GAP - 1,
- background.mBottom + PREEDIT_MARKER_POSITION - PREEDIT_MARKER_THICKNESS,
- (text_color * PREEDIT_MARKER_BRIGHTNESS + bg_color * (1 - PREEDIT_MARKER_BRIGHTNESS)).setAlpha(1.0f));
+ gl_rect_2d(preedit_pixels_left + preedit_marker_gap,
+ background.mBottom + preedit_marker_position,
+ preedit_pixels_right - preedit_marker_gap - 1,
+ background.mBottom + preedit_marker_position - preedit_marker_thickness,
+ (text_color * preedit_marker_brightness
+ + mPreeditBgColor * (1 - preedit_marker_brightness)).setAlpha(1.0f));
}
}
}
@@ -1576,7 +1646,7 @@ void LLLineEditor::draw()
S32 rendered_text = 0;
F32 rendered_pixels_right = (F32)mMinHPixels;
- F32 text_bottom = (F32)background.mBottom + (F32)UI_LINEEDITOR_V_PAD;
+ F32 text_bottom = (F32)background.mBottom + (F32)lineeditor_v_pad;
if( (gFocusMgr.getKeyboardFocus() == this) && hasSelection() )
{
@@ -1601,7 +1671,8 @@ void LLLineEditor::draw()
rendered_pixels_right, text_bottom,
text_color,
LLFontGL::LEFT, LLFontGL::BOTTOM,
- LLFontGL::NORMAL,
+ 0,
+ LLFontGL::NO_SHADOW,
select_left - mScrollHPos,
mMaxHPixels - llround(rendered_pixels_right),
&rendered_pixels_right);
@@ -1609,7 +1680,7 @@ void LLLineEditor::draw()
if( (rendered_pixels_right < (F32)mMaxHPixels) && (rendered_text < text_len) )
{
- LLColor4 color(1.f - bg_color.mV[0], 1.f - bg_color.mV[1], 1.f - bg_color.mV[2], 1.f);
+ LLColor4 color = mHighlightColor;
// selected middle
S32 width = mGLFont->getWidth(mText.getWString().c_str(), mScrollHPos + rendered_text, select_right - mScrollHPos - rendered_text);
width = llmin(width, mMaxHPixels - llround(rendered_pixels_right));
@@ -1620,7 +1691,8 @@ void LLLineEditor::draw()
rendered_pixels_right, text_bottom,
LLColor4( 1.f - text_color.mV[0], 1.f - text_color.mV[1], 1.f - text_color.mV[2], 1 ),
LLFontGL::LEFT, LLFontGL::BOTTOM,
- LLFontGL::NORMAL,
+ 0,
+ LLFontGL::NO_SHADOW,
select_right - mScrollHPos - rendered_text,
mMaxHPixels - llround(rendered_pixels_right),
&rendered_pixels_right);
@@ -1634,7 +1706,8 @@ void LLLineEditor::draw()
rendered_pixels_right, text_bottom,
text_color,
LLFontGL::LEFT, LLFontGL::BOTTOM,
- LLFontGL::NORMAL,
+ 0,
+ LLFontGL::NO_SHADOW,
S32_MAX,
mMaxHPixels - llround(rendered_pixels_right),
&rendered_pixels_right);
@@ -1647,28 +1720,29 @@ void LLLineEditor::draw()
rendered_pixels_right, text_bottom,
text_color,
LLFontGL::LEFT, LLFontGL::BOTTOM,
- LLFontGL::NORMAL,
+ 0,
+ LLFontGL::NO_SHADOW,
S32_MAX,
mMaxHPixels - llround(rendered_pixels_right),
&rendered_pixels_right);
}
-#if 0 // for when we're ready for image art.
+#if 1 // for when we're ready for image art.
mBorder->setVisible(FALSE); // no more programmatic art.
#endif
// If we're editing...
- if( gFocusMgr.getKeyboardFocus() == this)
+ if( hasFocus())
{
//mBorder->setVisible(TRUE); // ok, programmer art just this once.
// (Flash the cursor every half second)
- if (gShowTextEditCursor && !mReadOnly)
+ if (!mReadOnly && gFocusMgr.getAppHasFocus())
{
F32 elapsed = mKeystrokeTimer.getElapsedTimeF32();
if( (elapsed < CURSOR_FLASH_DELAY ) || (S32(elapsed * 2) & 1) )
{
S32 cursor_left = findPixelNearestPos();
- cursor_left -= UI_LINEEDITOR_CURSOR_THICKNESS / 2;
- S32 cursor_right = cursor_left + UI_LINEEDITOR_CURSOR_THICKNESS;
+ cursor_left -= lineeditor_cursor_thickness / 2;
+ S32 cursor_right = cursor_left + lineeditor_cursor_thickness;
if (LL_KIM_OVERWRITE == gKeyboard->getInsertMode() && !hasSelection())
{
const LLWString space(utf8str_to_wstring(std::string(" ")));
@@ -1681,17 +1755,18 @@ void LLLineEditor::draw()
cursor_right, cursor_bottom, text_color);
if (LL_KIM_OVERWRITE == gKeyboard->getInsertMode() && !hasSelection())
{
- mGLFont->render(mText, getCursor(), (F32)(cursor_left + UI_LINEEDITOR_CURSOR_THICKNESS / 2), text_bottom,
+ mGLFont->render(mText, getCursor(), (F32)(cursor_left + lineeditor_cursor_thickness / 2), text_bottom,
LLColor4( 1.f - text_color.mV[0], 1.f - text_color.mV[1], 1.f - text_color.mV[2], 1 ),
LLFontGL::LEFT, LLFontGL::BOTTOM,
- LLFontGL::NORMAL,
+ 0,
+ LLFontGL::NO_SHADOW,
1);
}
// Make sure the IME is in the right place
S32 pixels_after_scroll = findPixelNearestPos(); // RCalculcate for IME position
- LLRect screen_pos = getScreenRect();
- LLCoordGL ime_pos( screen_pos.mLeft + pixels_after_scroll, screen_pos.mTop - UI_LINEEDITOR_V_PAD );
+ LLRect screen_pos = calcScreenRect();
+ LLCoordGL ime_pos( screen_pos.mLeft + pixels_after_scroll, screen_pos.mTop - lineeditor_v_pad );
ime_pos.mX = (S32) (ime_pos.mX * LLUI::sGLScaleFactor.mV[VX]);
ime_pos.mY = (S32) (ime_pos.mY * LLUI::sGLScaleFactor.mV[VY]);
@@ -1709,7 +1784,8 @@ void LLLineEditor::draw()
label_color,
LLFontGL::LEFT,
LLFontGL::BOTTOM,
- LLFontGL::NORMAL,
+ 0,
+ LLFontGL::NO_SHADOW,
S32_MAX,
mMaxHPixels - llround(rendered_pixels_right),
&rendered_pixels_right, FALSE);
@@ -1733,7 +1809,8 @@ void LLLineEditor::draw()
label_color,
LLFontGL::LEFT,
LLFontGL::BOTTOM,
- LLFontGL::NORMAL,
+ 0,
+ LLFontGL::NO_SHADOW,
S32_MAX,
mMaxHPixels - llround(rendered_pixels_right),
&rendered_pixels_right, FALSE);
@@ -1849,7 +1926,7 @@ void LLLineEditor::setRect(const LLRect& rect)
}
}
-void LLLineEditor::setPrevalidate(BOOL (*func)(const LLWString &))
+void LLLineEditor::setPrevalidate(LLLinePrevalidateFunc func)
{
mPrevalidateFunc = func;
updateAllowingLanguageInput();
@@ -2169,244 +2246,11 @@ void LLLineEditor::setSelectAllonFocusReceived(BOOL b)
}
-void LLLineEditor::setKeystrokeCallback(void (*keystroke_callback)(LLLineEditor* caller, void* user_data))
+void LLLineEditor::setKeystrokeCallback(callback_t callback, void* user_data)
{
- mKeystrokeCallback = keystroke_callback;
+ mKeystrokeCallback = boost::bind(callback, _1, user_data);
}
-// virtual
-LLXMLNodePtr LLLineEditor::getXML(bool save_children) const
-{
- LLXMLNodePtr node = LLUICtrl::getXML();
-
- node->createChild("max_length", TRUE)->setIntValue(mMaxLengthBytes);
-
- node->createChild("font", TRUE)->setStringValue(LLFontGL::nameFromFont(mGLFont));
-
- if (mBorder)
- {
- std::string bevel;
- switch(mBorder->getBevel())
- {
- default:
- case LLViewBorder::BEVEL_NONE: bevel = "none"; break;
- case LLViewBorder::BEVEL_IN: bevel = "in"; break;
- case LLViewBorder::BEVEL_OUT: bevel = "out"; break;
- case LLViewBorder::BEVEL_BRIGHT:bevel = "bright"; break;
- }
- node->createChild("bevel_style", TRUE)->setStringValue(bevel);
-
- std::string style;
- switch(mBorder->getStyle())
- {
- default:
- case LLViewBorder::STYLE_LINE: style = "line"; break;
- case LLViewBorder::STYLE_TEXTURE: style = "texture"; break;
- }
- node->createChild("border_style", TRUE)->setStringValue(style);
-
- node->createChild("border_thickness", TRUE)->setIntValue(mBorder->getBorderWidth());
- }
-
- if (!mLabel.empty())
- {
- node->createChild("label", TRUE)->setStringValue(mLabel.getString());
- }
-
- node->createChild("select_all_on_focus_received", TRUE)->setBoolValue(mSelectAllonFocusReceived);
-
- node->createChild("handle_edit_keys_directly", TRUE)->setBoolValue(mHandleEditKeysDirectly );
-
- addColorXML(node, mCursorColor, "cursor_color", "TextCursorColor");
- addColorXML(node, mFgColor, "text_color", "TextFgColor");
- addColorXML(node, mReadOnlyFgColor, "text_readonly_color", "TextFgReadOnlyColor");
- addColorXML(node, mTentativeFgColor, "text_tentative_color", "TextFgTentativeColor");
- addColorXML(node, mReadOnlyBgColor, "bg_readonly_color", "TextBgReadOnlyColor");
- addColorXML(node, mWriteableBgColor, "bg_writeable_color", "TextBgWriteableColor");
- addColorXML(node, mFocusBgColor, "bg_focus_color", "TextBgFocusColor");
-
- node->createChild("select_on_focus", TRUE)->setBoolValue(mSelectAllonFocusReceived );
-
- return node;
-}
-
-// static
-LLView* LLLineEditor::fromXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFactory *factory)
-{
- std::string name("line_editor");
- node->getAttributeString("name", name);
-
- LLRect rect;
- createRect(node, rect, parent, LLRect());
-
- S32 max_text_length = 128;
- node->getAttributeS32("max_length", max_text_length);
-
- LLFontGL* font = LLView::selectFont(node);
-
- std::string text = node->getTextContents().substr(0, max_text_length - 1);
-
- LLViewBorder::EBevel bevel_style = LLViewBorder::BEVEL_IN;
- LLViewBorder::getBevelFromAttribute(node, bevel_style);
-
- LLViewBorder::EStyle border_style = LLViewBorder::STYLE_LINE;
- std::string border_string;
- node->getAttributeString("border_style", border_string);
- LLStringUtil::toLower(border_string);
-
- if (border_string == "texture")
- {
- border_style = LLViewBorder::STYLE_TEXTURE;
- }
-
- S32 border_thickness = 1;
- node->getAttributeS32("border_thickness", border_thickness);
-
- LLUICtrlCallback commit_callback = NULL;
-
- LLLineEditor* line_editor = new LLLineEditor(name,
- rect,
- text,
- font,
- max_text_length,
- commit_callback,
- NULL,
- NULL,
- NULL,
- NULL,
- bevel_style,
- border_style,
- border_thickness);
-
- std::string label;
- if(node->getAttributeString("label", label))
- {
- line_editor->setLabel(label);
- }
- BOOL select_all_on_focus_received = FALSE;
- if (node->getAttributeBOOL("select_all_on_focus_received", select_all_on_focus_received))
- {
- line_editor->setSelectAllonFocusReceived(select_all_on_focus_received);
- }
- BOOL handle_edit_keys_directly = FALSE;
- if (node->getAttributeBOOL("handle_edit_keys_directly", handle_edit_keys_directly))
- {
- line_editor->setHandleEditKeysDirectly(handle_edit_keys_directly);
- }
- BOOL commit_on_focus_lost = TRUE;
- if (node->getAttributeBOOL("commit_on_focus_lost", commit_on_focus_lost))
- {
- line_editor->setCommitOnFocusLost(commit_on_focus_lost);
- }
-
- line_editor->setColorParameters(node);
-
- if(node->hasAttribute("select_on_focus"))
- {
- BOOL selectall = FALSE;
- node->getAttributeBOOL("select_on_focus", selectall);
- line_editor->setSelectAllonFocusReceived(selectall);
- }
-
- std::string prevalidate;
- if(node->getAttributeString("prevalidate", prevalidate))
- {
- LLStringUtil::toLower(prevalidate);
-
- if ("ascii" == prevalidate)
- {
- line_editor->setPrevalidate( LLLineEditor::prevalidateASCII );
- }
- else if ("float" == prevalidate)
- {
- line_editor->setPrevalidate( LLLineEditor::prevalidateFloat );
- }
- else if ("int" == prevalidate)
- {
- line_editor->setPrevalidate( LLLineEditor::prevalidateInt );
- }
- else if ("positive_s32" == prevalidate)
- {
- line_editor->setPrevalidate( LLLineEditor::prevalidatePositiveS32 );
- }
- else if ("non_negative_s32" == prevalidate)
- {
- line_editor->setPrevalidate( LLLineEditor::prevalidateNonNegativeS32 );
- }
- else if ("alpha_num" == prevalidate)
- {
- line_editor->setPrevalidate( LLLineEditor::prevalidateAlphaNum );
- }
- else if ("alpha_num_space" == prevalidate)
- {
- line_editor->setPrevalidate( LLLineEditor::prevalidateAlphaNumSpace );
- }
- else if ("printable_not_pipe" == prevalidate)
- {
- line_editor->setPrevalidate( LLLineEditor::prevalidatePrintableNotPipe );
- }
- else if ("printable_no_space" == prevalidate)
- {
- line_editor->setPrevalidate( LLLineEditor::prevalidatePrintableNoSpace );
- }
- }
-
- line_editor->initFromXML(node, parent);
-
- return line_editor;
-}
-
-//static
-void LLLineEditor::cleanupLineEditor()
-{
- sImage = NULL;
-}
-
-/* static */
-LLPointer<LLUIImage> LLLineEditor::parseImage(std::string name, LLXMLNodePtr from, LLPointer<LLUIImage> def)
-{
- std::string xml_name;
- if (from->hasAttribute(name.c_str())) from->getAttributeString(name.c_str(), xml_name);
- if (xml_name == LLStringUtil::null) return def;
- LLPointer<LLUIImage> image = LLUI::getUIImage(xml_name);
- return image.isNull() ? def : image;
-}
-
-void LLLineEditor::setColorParameters(LLXMLNodePtr node)
-{
- // overrides default image if supplied.
- mImage = parseImage(std::string("image"), node, mImage);
-
- LLColor4 color;
- if (LLUICtrlFactory::getAttributeColor(node,"cursor_color", color))
- {
- setCursorColor(color);
- }
- if(node->hasAttribute("text_color"))
- {
- LLUICtrlFactory::getAttributeColor(node,"text_color", color);
- setFgColor(color);
- }
- if(node->hasAttribute("text_readonly_color"))
- {
- LLUICtrlFactory::getAttributeColor(node,"text_readonly_color", color);
- setReadOnlyFgColor(color);
- }
- if (LLUICtrlFactory::getAttributeColor(node,"text_tentative_color", color))
- {
- setTentativeFgColor(color);
- }
- if(node->hasAttribute("bg_readonly_color"))
- {
- LLUICtrlFactory::getAttributeColor(node,"bg_readonly_color", color);
- setReadOnlyBgColor(color);
- }
- if(node->hasAttribute("bg_writeable_color"))
- {
- LLUICtrlFactory::getAttributeColor(node,"bg_writeable_color", color);
- setWriteableBgColor(color);
- }
-}
BOOL LLLineEditor::setTextArg( const std::string& key, const LLStringExplicit& text )
{
@@ -2429,13 +2273,19 @@ void LLLineEditor::updateAllowingLanguageInput()
// fine on 1.15.0.2, since all prevalidate func reject any
// non-ASCII characters. I'm not sure on future versions,
// however...
+ LLWindow* window = getWindow();
+ if (!window)
+ {
+ // test app, no window available
+ return;
+ }
if (hasFocus() && !mReadOnly && !mDrawAsterixes && mPrevalidateFunc == NULL)
{
- getWindow()->allowLanguageTextInput(this, TRUE);
+ window->allowLanguageTextInput(this, TRUE);
}
else
{
- getWindow()->allowLanguageTextInput(this, FALSE);
+ window->allowLanguageTextInput(this, FALSE);
}
}
@@ -2513,7 +2363,7 @@ void LLLineEditor::updatePreedit(const LLWString &preedit_string,
mKeystrokeTimer.reset();
if( mKeystrokeCallback )
{
- mKeystrokeCallback( this, mCallbackUserData );
+ mKeystrokeCallback( this );
}
}
@@ -2656,146 +2506,19 @@ LLWString LLLineEditor::getConvertedText() const
return text;
}
-static LLRegisterWidget<LLSearchEditor> r2("search_editor");
-
-
-LLSearchEditor::LLSearchEditor(const std::string& name,
- const LLRect& rect,
- S32 max_length_bytes,
- void (*search_callback)(const std::string& search_string, void* user_data),
- void* userdata)
- :
- LLUICtrl(name, rect, TRUE, NULL, userdata),
- mSearchCallback(search_callback)
-{
- LLRect search_edit_rect(0, getRect().getHeight(), getRect().getWidth(), 0);
- mSearchEdit = new LLLineEditor(std::string("search edit"),
- search_edit_rect,
- LLStringUtil::null,
- NULL,
- max_length_bytes,
- NULL,
- onSearchEdit,
- NULL,
- this);
-
- mSearchEdit->setFollowsAll();
- mSearchEdit->setSelectAllonFocusReceived(TRUE);
-
- addChild(mSearchEdit);
-
- S32 btn_width = rect.getHeight(); // button is square, and as tall as search editor
- LLRect clear_btn_rect(rect.getWidth() - btn_width, rect.getHeight(), rect.getWidth(), 0);
- mClearSearchButton = new LLButton(std::string("clear search"),
- clear_btn_rect,
- std::string("icn_clear_lineeditor.tga"),
- std::string("UIImgBtnCloseInactiveUUID"),
- LLStringUtil::null,
- onClearSearch,
- this,
- NULL,
- LLStringUtil::null);
- mClearSearchButton->setFollowsRight();
- mClearSearchButton->setFollowsTop();
- mClearSearchButton->setImageColor(LLUI::sColorsGroup->getColor("TextFgTentativeColor"));
- mClearSearchButton->setTabStop(FALSE);
- mSearchEdit->addChild(mClearSearchButton);
-
- mSearchEdit->setTextPadding(0, btn_width);
-}
-
-
-//virtual
-void LLSearchEditor::setValue(const LLSD& value )
-{
- mSearchEdit->setValue(value);
-}
-
-//virtual
-LLSD LLSearchEditor::getValue() const
+namespace LLInitParam
{
- return mSearchEdit->getValue();
-}
-
-//virtual
-BOOL LLSearchEditor::setTextArg( const std::string& key, const LLStringExplicit& text )
-{
- return mSearchEdit->setTextArg(key, text);
-}
-
-//virtual
-BOOL LLSearchEditor::setLabelArg( const std::string& key, const LLStringExplicit& text )
-{
- return mSearchEdit->setLabelArg(key, text);
-}
-
-//virtual
-void LLSearchEditor::clear()
-{
- if (mSearchEdit)
+ template<>
+ bool ParamCompare<LLLinePrevalidateFunc>::equals(const LLLinePrevalidateFunc &a, const LLLinePrevalidateFunc &b)
{
- mSearchEdit->clear();
+ return false;
}
-}
-
-void LLSearchEditor::draw()
-{
- mClearSearchButton->setVisible(!mSearchEdit->getWText().empty());
-
- LLUICtrl::draw();
-}
-
-
-//static
-void LLSearchEditor::onSearchEdit(LLLineEditor* caller, void* user_data )
-{
- LLSearchEditor* search_editor = (LLSearchEditor*)user_data;
- if (search_editor->mSearchCallback)
- {
- search_editor->mSearchCallback(caller->getText(), search_editor->mCallbackUserData);
- }
-}
-
-//static
-void LLSearchEditor::onClearSearch(void* user_data)
-{
- LLSearchEditor* search_editor = (LLSearchEditor*)user_data;
- search_editor->setText(LLStringUtil::null);
- if (search_editor->mSearchCallback)
+ template<>
+ bool ParamCompare<boost::function<void (LLLineEditor *)> >::equals(
+ const boost::function<void (LLLineEditor *)> &a,
+ const boost::function<void (LLLineEditor *)> &b)
{
- search_editor->mSearchCallback(LLStringUtil::null, search_editor->mCallbackUserData);
+ return false;
}
}
-
-// static
-LLView* LLSearchEditor::fromXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFactory *factory)
-{
- std::string name("search_editor");
- node->getAttributeString("name", name);
-
- LLRect rect;
- createRect(node, rect, parent, LLRect());
-
- S32 max_text_length = 128;
- node->getAttributeS32("max_length", max_text_length);
-
- std::string text = node->getValue().substr(0, max_text_length - 1);
-
- LLSearchEditor* search_editor = new LLSearchEditor(name,
- rect,
- max_text_length,
- NULL, NULL);
-
- std::string label;
- if(node->getAttributeString("label", label))
- {
- search_editor->mSearchEdit->setLabel(label);
- }
-
- search_editor->setText(text);
-
- search_editor->initFromXML(node, parent);
-
- return search_editor;
-}
diff --git a/indra/llui/lllineeditor.h b/indra/llui/lllineeditor.h
index fc5fcc5b90..0986ce5a87 100644
--- a/indra/llui/lllineeditor.h
+++ b/indra/llui/lllineeditor.h
@@ -51,39 +51,72 @@
#include "llviewborder.h"
#include "llpreeditor.h"
+#include <boost/function.hpp>
class LLFontGL;
class LLLineEditorRollback;
class LLButton;
-typedef BOOL (*LLLinePrevalidateFunc)(const LLWString &wstr);
-
+typedef boost::function<BOOL (const LLWString &wstr)> LLLinePrevalidateFunc;
class LLLineEditor
: public LLUICtrl, public LLEditMenuHandler, protected LLPreeditor
{
-
public:
- LLLineEditor(const std::string& name,
- const LLRect& rect,
- const std::string& default_text = LLStringUtil::null,
- const LLFontGL* glfont = NULL,
- S32 max_length_bytes = 254,
- void (*commit_callback)(LLUICtrl* caller, void* user_data) = NULL,
- void (*keystroke_callback)(LLLineEditor* caller, void* user_data) = NULL,
- void (*focus_lost_callback)(LLFocusableElement* caller, void* user_data) = NULL,
- void* userdata = NULL,
- LLLinePrevalidateFunc prevalidate_func = NULL,
- LLViewBorder::EBevel border_bevel = LLViewBorder::BEVEL_IN,
- LLViewBorder::EStyle border_style = LLViewBorder::STYLE_LINE,
- S32 border_thickness = 1);
- virtual ~LLLineEditor();
+ struct PrevalidateNamedFuncs
+ : public LLInitParam::TypeValuesHelper<LLLinePrevalidateFunc, PrevalidateNamedFuncs>
- virtual LLXMLNodePtr getXML(bool save_children = true) const;
- void setColorParameters(LLXMLNodePtr node);
- static LLView* fromXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFactory *factory);
- static void cleanupLineEditor();
+ {
+ static void declareValues();
+ };
+
+ typedef boost::function<void (LLLineEditor* caller)> keystroke_callback_t;
+
+ struct Params : public LLInitParam::Block<Params, LLUICtrl::Params>
+ {
+ Optional<std::string> default_text;
+ Optional<S32> max_length_bytes;
+
+ Optional<keystroke_callback_t> keystroke_callback;
+
+ Optional<LLLinePrevalidateFunc, PrevalidateNamedFuncs> prevalidate_callback;
+
+ Optional<LLViewBorder::Params> border;
+
+ Optional<LLUIImage*> background_image,
+ background_image_disabled,
+ background_image_focused;
+
+ Optional<bool> select_on_focus,
+ handle_edit_keys_directly,
+ commit_on_focus_lost,
+ ignore_tab;
+
+ // colors
+ Optional<LLUIColor> cursor_color,
+ text_color,
+ text_readonly_color,
+ text_tentative_color,
+ highlight_color,
+ preedit_bg_color;
+
+ Optional<S32> text_pad_left,
+ text_pad_right;
+
+ Ignored is_unicode,
+ drop_shadow_visible,
+ border_drop_shadow_visible,
+ bg_visible;
+
+ Params();
+ };
+protected:
+ LLLineEditor(const Params&);
+ friend class LLUICtrlFactory;
+ friend class LLFloaterEditUI;
+public:
+ virtual ~LLLineEditor();
// mousehandler overrides
/*virtual*/ BOOL handleMouseDown(S32 x, S32 y, MASK mask);
@@ -131,12 +164,12 @@ public:
virtual void setRect(const LLRect& rect);
virtual BOOL acceptsTextInput() const;
virtual void onCommit();
- virtual BOOL isDirty() const { return mText.getString() != mPrevText; } // Returns TRUE if user changed value at all
- virtual void resetDirty() { mPrevText = mText.getString(); } // Clear dirty state
+ virtual BOOL isDirty() const; // Returns TRUE if user changed value at all
+ virtual void resetDirty(); // Clear dirty state
// assumes UTF8 text
- virtual void setValue(const LLSD& value ) { setText(value.asString()); }
- virtual LLSD getValue() const { return LLSD(getText()); }
+ virtual void setValue(const LLSD& value );
+ virtual LLSD getValue() const;
virtual BOOL setTextArg( const std::string& key, const LLStringExplicit& text );
virtual BOOL setLabelArg( const std::string& key, const LLStringExplicit& text );
@@ -144,7 +177,7 @@ public:
void setText(const LLStringExplicit &new_text);
const std::string& getText() const { return mText.getString(); }
- const LLWString& getWText() const { return mText.getWString(); }
+ LLWString getWText() const { return mText.getWString(); }
LLWString getConvertedText() const; // trimmed text with paragraphs converted to newlines
S32 getLength() const { return mText.length(); }
@@ -160,21 +193,15 @@ public:
void setRevertOnEsc( BOOL b ) { mRevertOnEsc = b; }
void setCursorColor(const LLColor4& c) { mCursorColor = c; }
- const LLColor4& getCursorColor() const { return mCursorColor; }
+ const LLColor4& getCursorColor() const { return mCursorColor.get(); }
void setFgColor( const LLColor4& c ) { mFgColor = c; }
void setReadOnlyFgColor( const LLColor4& c ) { mReadOnlyFgColor = c; }
void setTentativeFgColor(const LLColor4& c) { mTentativeFgColor = c; }
- void setWriteableBgColor( const LLColor4& c ) { mWriteableBgColor = c; }
- void setReadOnlyBgColor( const LLColor4& c ) { mReadOnlyBgColor = c; }
- void setFocusBgColor(const LLColor4& c) { mFocusBgColor = c; }
- const LLColor4& getFgColor() const { return mFgColor; }
- const LLColor4& getReadOnlyFgColor() const { return mReadOnlyFgColor; }
- const LLColor4& getTentativeFgColor() const { return mTentativeFgColor; }
- const LLColor4& getWriteableBgColor() const { return mWriteableBgColor; }
- const LLColor4& getReadOnlyBgColor() const { return mReadOnlyBgColor; }
- const LLColor4& getFocusBgColor() const { return mFocusBgColor; }
+ const LLColor4& getFgColor() const { return mFgColor.get(); }
+ const LLColor4& getReadOnlyFgColor() const { return mReadOnlyFgColor.get(); }
+ const LLColor4& getTentativeFgColor() const { return mTentativeFgColor.get(); }
void setIgnoreArrowKeys(BOOL b) { mIgnoreArrowKeys = b; }
void setIgnoreTab(BOOL b) { mIgnoreTab = b; }
@@ -193,14 +220,14 @@ public:
void setHandleEditKeysDirectly( BOOL b ) { mHandleEditKeysDirectly = b; }
void setSelectAllonFocusReceived(BOOL b);
-
- void setKeystrokeCallback(void (*keystroke_callback)(LLLineEditor* caller, void* user_data));
+
+ typedef boost::function<void (LLLineEditor* caller, void* user_data)> callback_t;
+ void setKeystrokeCallback(callback_t callback, void* user_data);
void setMaxTextLength(S32 max_text_length);
- void setTextPadding(S32 left, S32 right); // Used to specify room for children before or after text.
// Prevalidation controls which keystrokes can affect the editor
- void setPrevalidate( BOOL (*func)(const LLWString &) );
+ void setPrevalidate( LLLinePrevalidateFunc func );
static BOOL prevalidateFloat(const LLWString &str );
static BOOL prevalidateInt(const LLWString &str );
static BOOL prevalidatePositiveS32(const LLWString &str);
@@ -233,6 +260,10 @@ private:
BOOL handleSelectionKey(KEY key, MASK mask);
BOOL handleControlKey(KEY key, MASK mask);
S32 handleCommitKey(KEY key, MASK mask);
+ void updateTextPadding();
+
+ // Draw the background image depending on enabled/focused state.
+ void drawBackground();
//
// private data members
@@ -273,7 +304,7 @@ protected:
BOOL mCommitOnFocusLost;
BOOL mRevertOnEsc;
- void (*mKeystrokeCallback)( LLLineEditor* caller, void* userdata );
+ keystroke_callback_t mKeystrokeCallback;
BOOL mIsSelecting; // Selection for clipboard operations
S32 mSelectionStart;
@@ -283,18 +314,17 @@ protected:
S32 mLastSelectionStart;
S32 mLastSelectionEnd;
- S32 (*mPrevalidateFunc)(const LLWString &str);
+ LLLinePrevalidateFunc mPrevalidateFunc;
LLFrameTimer mKeystrokeTimer;
+ LLTimer mTripleClickTimer;
- LLColor4 mCursorColor;
-
- LLColor4 mFgColor;
- LLColor4 mReadOnlyFgColor;
- LLColor4 mTentativeFgColor;
- LLColor4 mWriteableBgColor;
- LLColor4 mReadOnlyBgColor;
- LLColor4 mFocusBgColor;
+ LLUIColor mCursorColor;
+ LLUIColor mFgColor;
+ LLUIColor mReadOnlyFgColor;
+ LLUIColor mTentativeFgColor;
+ LLUIColor mHighlightColor; // background for selected text
+ LLUIColor mPreeditBgColor; // preedit marker background color
S32 mBorderThickness;
@@ -314,13 +344,10 @@ protected:
LLPreeditor::standouts_t mPreeditStandouts;
private:
- // Utility on top of LLUI::getUIImage, looks up a named image in a given XML node and returns it if possible
- // or returns a given default image if anything in the process fails.
- static LLPointer<LLUIImage> parseImage(std::string name, LLXMLNodePtr from, LLPointer<LLUIImage> def);
- // Global instance used as default for member instance below.
- static LLPointer<LLUIImage> sImage;
// Instances that by default point to the statics but can be overidden in XML.
- LLPointer<LLUIImage> mImage;
+ LLPointer<LLUIImage> mBgImage;
+ LLPointer<LLUIImage> mBgImageDisabled;
+ LLPointer<LLUIImage> mBgImageFocused;
BOOL mReplaceNewlinesWithSpaces; // if false, will replace pasted newlines with paragraph symbol.
@@ -364,44 +391,15 @@ private:
}; // end class LLLineEditor
-
-/*
- * @brief A line editor with a button to clear it and a callback to call on every edit event.
- */
-class LLSearchEditor : public LLUICtrl
+namespace LLInitParam
{
-public:
- LLSearchEditor(const std::string& name,
- const LLRect& rect,
- S32 max_length_bytes,
- void (*search_callback)(const std::string& search_string, void* user_data),
- void* userdata);
-
- virtual ~LLSearchEditor() {}
-
- /*virtual*/ void draw();
-
- static LLView* fromXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFactory *factory);
-
- void setText(const LLStringExplicit &new_text) { mSearchEdit->setText(new_text); }
-
- void setSearchCallback(void (*search_callback)(const std::string& search_string, void* user_data), void* data) { mSearchCallback = search_callback; mCallbackUserData = data; }
-
- // LLUICtrl interface
- virtual void setValue(const LLSD& value );
- virtual LLSD getValue() const;
- virtual BOOL setTextArg( const std::string& key, const LLStringExplicit& text );
- virtual BOOL setLabelArg( const std::string& key, const LLStringExplicit& text );
- virtual void clear();
-
-private:
- static void onSearchEdit(LLLineEditor* caller, void* user_data );
- static void onClearSearch(void* user_data);
-
- LLLineEditor* mSearchEdit;
- class LLButton* mClearSearchButton;
- void (*mSearchCallback)(const std::string& search_string, void* user_data);
-
-};
+ template<>
+ bool ParamCompare<LLLinePrevalidateFunc>::equals(
+ const LLLinePrevalidateFunc &a, const LLLinePrevalidateFunc &b);
+
+ template<>
+ bool ParamCompare<boost::function<void (LLLineEditor *)> >::equals(
+ const boost::function<void (LLLineEditor *)> &a, const boost::function<void (LLLineEditor *)> &b);
+}
#endif // LL_LINEEDITOR_
diff --git a/indra/llui/llmenugl.cpp b/indra/llui/llmenugl.cpp
index a8d06643ff..d6dfe6c198 100644
--- a/indra/llui/llmenugl.cpp
+++ b/indra/llui/llmenugl.cpp
@@ -49,26 +49,22 @@
#include "llmath.h"
#include "llrender.h"
#include "llfocusmgr.h"
-#include "llfont.h"
#include "llcoord.h"
#include "llwindow.h"
#include "llcriticaldamp.h"
#include "lluictrlfactory.h"
+#include "llbutton.h"
#include "llfontgl.h"
#include "llresmgr.h"
#include "llui.h"
-#include "lluitrans.h"
-
#include "llstl.h"
#include "v2math.h"
#include <set>
#include <boost/tokenizer.hpp>
-using namespace LLOldEvents;
-
// static
LLMenuHolderGL *LLMenuGL::sMenuContainer = NULL;
@@ -80,7 +76,6 @@ S32 MENU_BAR_WIDTH = 0;
///============================================================================
const std::string SEPARATOR_NAME("separator");
-const std::string TEAROFF_SEPARATOR_LABEL( "~~~~~~~~~~~" );
const std::string SEPARATOR_LABEL( "-----------" );
const std::string VERTICAL_SEPARATOR_LABEL( "|" );
@@ -94,7 +89,6 @@ const U32 RIGHT_PAD_PIXELS = 2;
const U32 RIGHT_WIDTH_PIXELS = 15;
const U32 RIGHT_PLAIN_PIXELS = RIGHT_PAD_PIXELS + RIGHT_WIDTH_PIXELS;
-const U32 ACCEL_PAD_PIXELS = 10;
const U32 PLAIN_PAD_PIXELS = LEFT_PAD_PIXELS + LEFT_WIDTH_PIXELS + RIGHT_PAD_PIXELS + RIGHT_WIDTH_PIXELS;
const U32 BRIEF_PAD_PIXELS = 2;
@@ -112,12 +106,6 @@ const F32 MAX_MOUSE_SLOPE_SUB_MENU = 0.9f;
const S32 PIE_GESTURE_ACTIVATE_DISTANCE = 10;
-LLColor4 LLMenuItemGL::sEnabledColor( 0.0f, 0.0f, 0.0f, 1.0f );
-LLColor4 LLMenuItemGL::sDisabledColor( 0.5f, 0.5f, 0.5f, 1.0f );
-LLColor4 LLMenuItemGL::sHighlightBackground( 0.0f, 0.0f, 0.7f, 1.0f );
-LLColor4 LLMenuItemGL::sHighlightForeground( 1.0f, 1.0f, 1.0f, 1.0f );
-
-LLColor4 LLMenuGL::sDefaultBackgroundColor( 0.25f, 0.25f, 0.25f, 0.75f );
BOOL LLMenuGL::sKeyboardMode = FALSE;
LLHandle<LLView> LLMenuHolderGL::sItemLastSelectedHandle;
@@ -130,72 +118,84 @@ const F32 PIE_SHRINK_TIME = 0.2f; // time of transition between unbounded and bo
const F32 ACTIVATE_HIGHLIGHT_TIME = 0.3f;
+static MenuRegistry::Register<LLMenuItemSeparatorGL> register_separator("menu_item_separator");
+static MenuRegistry::Register<LLMenuItemCallGL> register_menu_item_call("menu_item_call");
+static MenuRegistry::Register<LLMenuItemCheckGL> register_menu_item_check("menu_item_check");
+static MenuRegistry::Register<LLMenuGL> register_menu("menu");
+
+static LLDefaultChildRegistry::Register<LLMenuGL> register_menu_default("menu");
+
+
+
///============================================================================
/// Class LLMenuItemGL
///============================================================================
-
// Default constructor
-LLMenuItemGL::LLMenuItemGL( const std::string& name, const std::string& label, KEY key, MASK mask ) :
- LLView( name, TRUE ),
- mJumpKey(KEY_NONE),
- mAcceleratorKey( key ),
- mAcceleratorMask( mask ),
+LLMenuItemGL::LLMenuItemGL(const LLMenuItemGL::Params& p)
+: LLUICtrl(p),
+ mJumpKey(p.jump_key),
mAllowKeyRepeat(FALSE),
mHighlight( FALSE ),
mGotHover( FALSE ),
mBriefItem( FALSE ),
- mFont( LLFontGL::getFontSansSerif() ),
- mStyle(LLFontGL::NORMAL),
- mDrawTextDisabled( FALSE )
+ mDrawTextDisabled( FALSE ),
+ mFont(p.font),
+ mAcceleratorKey(KEY_NONE),
+ mAcceleratorMask(MASK_NONE),
+ mLabel(p.label.isProvided() ? p.label() : p.name()),
+ mEnabledColor(p.enabled_color()),
+ mDisabledColor(p.disabled_color()),
+ mHighlightBackground(p.highlight_bg_color()),
+ mHighlightForeground(p.highlight_fg_color())
{
- setLabel( label );
-}
-
-// virtual
-LLXMLNodePtr LLMenuItemGL::getXML(bool save_children) const
-{
- LLXMLNodePtr node = LLView::getXML();
-
- node->createChild("type", TRUE)->setStringValue(getType());
-
- node->createChild("label", TRUE)->setStringValue(mLabel);
-
- if (mAcceleratorKey != KEY_NONE)
+#ifdef LL_DARWIN
+ // See if this Mac accelerator should really use the ctrl key and not get mapped to cmd
+ BOOL useMacCtrl = p.use_mac_ctrl;
+#endif // LL_DARWIN
+
+ std::string shortcut = p.shortcut;
+ if (shortcut.find("control") != shortcut.npos)
{
- std::stringstream out;
- if (mAcceleratorMask & MASK_CONTROL)
- {
- out << "control|";
- }
- if (mAcceleratorMask & MASK_ALT)
- {
- out << "alt|";
- }
- if (mAcceleratorMask & MASK_SHIFT)
- {
- out << "shift|";
- }
- out << LLKeyboard::stringFromKey(mAcceleratorKey);
-
- node->createChild("shortcut", TRUE)->setStringValue(out.str());
-
#ifdef LL_DARWIN
- // Write in special tag if this key is really a ctrl combination on the Mac
- if (mAcceleratorMask & MASK_MAC_CONTROL)
+ if ( useMacCtrl )
{
- node->createChild("useMacCtrl", TRUE)->setBoolValue( TRUE );
+ mAcceleratorMask |= MASK_MAC_CONTROL;
}
#endif // LL_DARWIN
+ mAcceleratorMask |= MASK_CONTROL;
}
+ if (shortcut.find("alt") != shortcut.npos)
+ {
+ mAcceleratorMask |= MASK_ALT;
+ }
+ if (shortcut.find("shift") != shortcut.npos)
+ {
+ mAcceleratorMask |= MASK_SHIFT;
+ }
+ S32 pipe_pos = shortcut.rfind("|");
+ std::string key_str = shortcut.substr(pipe_pos+1);
+
+ LLKeyboard::keyFromString(key_str, &mAcceleratorKey);
- return node;
+ LL_DEBUGS("HotKeys") << "Process short cut key: shortcut: " << shortcut
+ << ", key str: " << key_str
+ << ", accelerator mask: " << mAcceleratorMask
+ << ", accelerator key: " << mAcceleratorKey
+ << LL_ENDL;
}
+//virtual
+void LLMenuItemGL::setValue(const LLSD& value)
+{
+ setLabel(value.asString());
+}
+
+//virtual
BOOL LLMenuItemGL::handleAcceleratorKey(KEY key, MASK mask)
{
if( getEnabled() && (!gKeyboard->getKeyRepeated(key) || mAllowKeyRepeat) && (key == mAcceleratorKey) && (mask == (mAcceleratorMask & MASK_NORMALKEYS)) )
{
- doIt();
+ onCommit();
return TRUE;
}
return FALSE;
@@ -208,6 +208,26 @@ BOOL LLMenuItemGL::handleHover(S32 x, S32 y, MASK mask)
return TRUE;
}
+//virtual
+BOOL LLMenuItemGL::handleRightMouseDown(S32 x, S32 y, MASK mask)
+{
+ return LLUICtrl::handleRightMouseDown(x,y,mask);
+}
+
+//virtual
+BOOL LLMenuItemGL::handleRightMouseUp(S32 x, S32 y, MASK mask)
+{
+ // If this event came from a right-click context menu spawn,
+ // process as a left-click to allow menu items to be hit
+ if (LLMenuHolderGL::sContextMenuSpawnPos.mX != S32_MAX
+ || LLMenuHolderGL::sContextMenuSpawnPos.mY != S32_MAX)
+ {
+ BOOL handled = handleMouseUp(x, y, mask);
+ return handled;
+ }
+ return LLUICtrl::handleRightMouseUp(x,y,mask);
+}
+
// This function checks to see if the accelerator key is already in use;
// if not, it will be added to the list
BOOL LLMenuItemGL::addToAcceleratorList(std::list <LLKeyBinding*> *listp)
@@ -271,24 +291,24 @@ void LLMenuItemGL::appendAcceleratorString( std::string& st ) const
{
if ( mAcceleratorMask & MASK_MAC_CONTROL )
{
- st.append( LLUITrans::getString("accel-mac-control") );
+ st.append( "Ctrl-" );
}
else
{
- st.append( LLUITrans::getString("accel-mac-command") ); // Symbol would be "\xE2\x8C\x98"
+ st.append( "Cmd-" ); // Symbol would be "\xE2\x8C\x98"
}
}
if( mAcceleratorMask & MASK_ALT )
- st.append( LLUITrans::getString("accel-mac-option") ); // Symbol would be "\xE2\x8C\xA5"
+ st.append( "Opt-" ); // Symbol would be "\xE2\x8C\xA5"
if( mAcceleratorMask & MASK_SHIFT )
- st.append( LLUITrans::getString("accel-mac-shift") ); // Symbol would be "\xE2\x8C\xA7"
+ st.append( "Shift-" ); // Symbol would be "\xE2\x8C\xA7"
#else
if( mAcceleratorMask & MASK_CONTROL )
- st.append( LLUITrans::getString("accel-win-control") );
+ st.append( "Ctrl-" );
if( mAcceleratorMask & MASK_ALT )
- st.append( LLUITrans::getString("accel-win-alt") );
+ st.append( "Alt-" );
if( mAcceleratorMask & MASK_SHIFT )
- st.append( LLUITrans::getString("accel-win-shift") );
+ st.append( "Shift-" );
#endif
std::string keystr = LLKeyboard::stringFromKey( mAcceleratorKey );
@@ -298,6 +318,7 @@ void LLMenuItemGL::appendAcceleratorString( std::string& st ) const
st.append( " " );
}
st.append( keystr );
+ LL_DEBUGS("HotKeys") << "appendAcceleratorString: " << st << LL_ENDL;
}
void LLMenuItemGL::setJumpKey(KEY key)
@@ -312,9 +333,20 @@ U32 LLMenuItemGL::getNominalHeight( void ) const
return llround(mFont->getLineHeight()) + MENU_ITEM_PADDING;
}
+//virtual
+void LLMenuItemGL::setBriefItem(BOOL brief)
+{
+ mBriefItem = brief;
+}
+
+//virtual
+BOOL LLMenuItemGL::isBriefItem() const
+{
+ return mBriefItem;
+}
// Get the parent menu for this item
-LLMenuGL* LLMenuItemGL::getMenu()
+LLMenuGL* LLMenuItemGL::getMenu() const
{
return (LLMenuGL*) getParent();
}
@@ -338,7 +370,7 @@ U32 LLMenuItemGL::getNominalWidth( void ) const
if( KEY_NONE != mAcceleratorKey )
{
- width += ACCEL_PAD_PIXELS;
+ width += getMenu()->getShortcutPad();
std::string temp;
appendAcceleratorString( temp );
width += mFont->getWidth( temp );
@@ -356,7 +388,7 @@ void LLMenuItemGL::buildDrawLabel( void )
mDrawAccelLabel = st;
}
-void LLMenuItemGL::doIt( void )
+void LLMenuItemGL::onCommit( void )
{
// close all open menus by default
// if parent menu is actually visible (and we are not triggering menu item via accelerator)
@@ -365,6 +397,8 @@ void LLMenuItemGL::doIt( void )
{
LLMenuGL::sMenuContainer->hideMenus();
}
+
+ LLUICtrl::onCommit();
}
// set the hover status (called by it's menu)
@@ -404,7 +438,7 @@ BOOL LLMenuItemGL::handleKeyHere( KEY key, MASK mask )
// switch to keyboard navigation mode
LLMenuGL::setKeyboardMode(TRUE);
- doIt();
+ onCommit();
return TRUE;
}
}
@@ -412,25 +446,30 @@ BOOL LLMenuItemGL::handleKeyHere( KEY key, MASK mask )
return FALSE;
}
-BOOL LLMenuItemGL::handleMouseUp( S32 x, S32 y, MASK )
+BOOL LLMenuItemGL::handleMouseUp( S32 x, S32 y, MASK mask)
{
// switch to mouse navigation mode
LLMenuGL::setKeyboardMode(FALSE);
- doIt();
+ onCommit();
make_ui_sound("UISndClickRelease");
- return TRUE;
+ return LLView::handleMouseUp(x, y, mask);
}
-BOOL LLMenuItemGL::handleMouseDown( S32 x, S32 y, MASK )
+BOOL LLMenuItemGL::handleMouseDown( S32 x, S32 y, MASK mask)
{
// switch to mouse navigation mode
LLMenuGL::setKeyboardMode(FALSE);
setHighlight(TRUE);
- return TRUE;
+ return LLView::handleMouseDown(x, y, mask);
}
+BOOL LLMenuItemGL::handleScrollWheel( S32 x, S32 y, S32 clicks )
+{
+ // If the menu is scrollable let it handle the wheel event.
+ return !getMenu()->isScrollable();
+}
void LLMenuItemGL::draw( void )
{
@@ -441,55 +480,58 @@ void LLMenuItemGL::draw( void )
// let disabled items be highlighted, just don't draw them as such
if( getEnabled() && getHighlight() && !mBriefItem)
{
- gGL.color4fv( sHighlightBackground.mV );
+ int debug_count = 0;
+ if (dynamic_cast<LLMenuItemCallGL*>(this))
+ debug_count++;
+ gGL.color4fv( mHighlightBackground.get().mV );
gl_rect_2d( 0, getRect().getHeight(), getRect().getWidth(), 0 );
}
LLColor4 color;
- U8 font_style = mStyle;
+ LLFontGL::ShadowType shadow_style = LLFontGL::NO_SHADOW;
if (getEnabled() && !mDrawTextDisabled )
{
- font_style |= LLFontGL::DROP_SHADOW_SOFT;
+ shadow_style = LLFontGL::DROP_SHADOW_SOFT;
}
if ( getEnabled() && getHighlight() )
{
- color = sHighlightForeground;
+ color = mHighlightForeground.get();
}
else if( getEnabled() && !mDrawTextDisabled )
{
- color = sEnabledColor;
+ color = mEnabledColor.get();
}
else
{
- color = sDisabledColor;
+ color = mDisabledColor.get();
}
// Draw the text on top.
if (mBriefItem)
{
mFont->render( mLabel, 0, BRIEF_PAD_PIXELS / 2, 0, color,
- LLFontGL::LEFT, LLFontGL::BOTTOM, font_style );
+ LLFontGL::LEFT, LLFontGL::BOTTOM, LLFontGL::NORMAL, shadow_style );
}
else
{
if( !mDrawBoolLabel.empty() )
{
mFont->render( mDrawBoolLabel.getWString(), 0, (F32)LEFT_PAD_PIXELS, ((F32)MENU_ITEM_PADDING / 2.f) + 1.f, color,
- LLFontGL::LEFT, LLFontGL::BOTTOM, font_style, S32_MAX, S32_MAX, NULL, FALSE );
+ LLFontGL::LEFT, LLFontGL::BOTTOM, LLFontGL::NORMAL, shadow_style, S32_MAX, S32_MAX, NULL, FALSE );
}
mFont->render( mLabel.getWString(), 0, (F32)LEFT_PLAIN_PIXELS, ((F32)MENU_ITEM_PADDING / 2.f) + 1.f, color,
- LLFontGL::LEFT, LLFontGL::BOTTOM, font_style, S32_MAX, S32_MAX, NULL, FALSE );
+ LLFontGL::LEFT, LLFontGL::BOTTOM, LLFontGL::NORMAL, shadow_style, S32_MAX, S32_MAX, NULL, FALSE );
if( !mDrawAccelLabel.empty() )
{
mFont->render( mDrawAccelLabel.getWString(), 0, (F32)getRect().mRight - (F32)RIGHT_PLAIN_PIXELS, ((F32)MENU_ITEM_PADDING / 2.f) + 1.f, color,
- LLFontGL::RIGHT, LLFontGL::BOTTOM, font_style, S32_MAX, S32_MAX, NULL, FALSE );
+ LLFontGL::RIGHT, LLFontGL::BOTTOM, LLFontGL::NORMAL, shadow_style, S32_MAX, S32_MAX, NULL, FALSE );
}
if( !mDrawBranchLabel.empty() )
{
mFont->render( mDrawBranchLabel.getWString(), 0, (F32)getRect().mRight - (F32)RIGHT_PAD_PIXELS, ((F32)MENU_ITEM_PADDING / 2.f) + 1.f, color,
- LLFontGL::RIGHT, LLFontGL::BOTTOM, font_style, S32_MAX, S32_MAX, NULL, FALSE );
+ LLFontGL::RIGHT, LLFontGL::BOTTOM, LLFontGL::NORMAL, shadow_style, S32_MAX, S32_MAX, NULL, FALSE );
}
}
@@ -517,38 +559,40 @@ BOOL LLMenuItemGL::setLabelArg( const std::string& key, const LLStringExplicit&
return TRUE;
}
+void LLMenuItemGL::handleVisibilityChange(BOOL new_visibility)
+{
+ if (getMenu())
+ {
+ getMenu()->needsArrange();
+ }
+ LLView::handleVisibilityChange(new_visibility);
+}
+
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Class LLMenuItemSeparatorGL
//
// This class represents a separator.
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-class LLMenuItemSeparatorGL : public LLMenuItemGL
+LLMenuItemSeparatorGL::Params::Params()
{
-public:
- LLMenuItemSeparatorGL( const std::string &name = SEPARATOR_NAME );
-
- virtual std::string getType() const { return "separator"; }
-
- // doIt() - do the primary funcationality of the menu item.
- virtual void doIt( void ) {}
-
- virtual void draw( void );
- virtual BOOL handleMouseDown(S32 x, S32 y, MASK mask);
- virtual BOOL handleMouseUp(S32 x, S32 y, MASK mask);
- virtual BOOL handleHover(S32 x, S32 y, MASK mask);
+ name = "separator";
+ label = SEPARATOR_LABEL;
+}
- virtual U32 getNominalHeight( void ) const { return SEPARATOR_HEIGHT_PIXELS; }
-};
+LLMenuItemSeparatorGL::LLMenuItemSeparatorGL(const LLMenuItemSeparatorGL::Params& p) :
+ LLMenuItemGL( p )
+{
+}
-LLMenuItemSeparatorGL::LLMenuItemSeparatorGL( const std::string &name ) :
- LLMenuItemGL( name, SEPARATOR_LABEL )
+//virtual
+U32 LLMenuItemSeparatorGL::getNominalHeight( void ) const
{
+ return SEPARATOR_HEIGHT_PIXELS;
}
void LLMenuItemSeparatorGL::draw( void )
{
- gGL.color4fv( getDisabledColor().mV );
+ gGL.color4fv( mDisabledColor.get().mV );
const S32 y = getRect().getHeight() / 2;
const S32 PAD = 6;
gl_line_2d( PAD, y, getRect().getWidth() - PAD, y );
@@ -559,11 +603,13 @@ BOOL LLMenuItemSeparatorGL::handleMouseDown(S32 x, S32 y, MASK mask)
LLMenuGL* parent_menu = getMenu();
if (y > getRect().getHeight() / 2)
{
- return parent_menu->handleMouseDown(x + getRect().mLeft, getRect().mTop + 1, mask);
+ LLView* prev_menu_item = parent_menu->findPrevSibling(this);
+ return prev_menu_item ? prev_menu_item->handleMouseDown(x, prev_menu_item->getRect().getHeight(), mask) : FALSE;
}
else
{
- return parent_menu->handleMouseDown(x + getRect().mLeft, getRect().mBottom - 1, mask);
+ LLView* next_menu_item = parent_menu->findNextSibling(this);
+ return next_menu_item ? next_menu_item->handleMouseDown(x, 0, mask) : FALSE;
}
}
@@ -572,11 +618,13 @@ BOOL LLMenuItemSeparatorGL::handleMouseUp(S32 x, S32 y, MASK mask)
LLMenuGL* parent_menu = getMenu();
if (y > getRect().getHeight() / 2)
{
- return parent_menu->handleMouseUp(x + getRect().mLeft, getRect().mTop + 1, mask);
+ LLView* prev_menu_item = parent_menu->findPrevSibling(this);
+ return prev_menu_item ? prev_menu_item->handleMouseUp(x, prev_menu_item->getRect().getHeight(), mask) : FALSE;
}
else
{
- return parent_menu->handleMouseUp(x + getRect().mLeft, getRect().mBottom - 1, mask);
+ LLView* next_menu_item = parent_menu->findNextSibling(this);
+ return next_menu_item ? next_menu_item->handleMouseUp(x, 0, mask) : FALSE;
}
}
@@ -595,7 +643,6 @@ BOOL LLMenuItemSeparatorGL::handleHover(S32 x, S32 y, MASK mask)
}
}
-
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Class LLMenuItemVerticalSeparatorGL
//
@@ -619,19 +666,19 @@ LLMenuItemVerticalSeparatorGL::LLMenuItemVerticalSeparatorGL( void )
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Class LLMenuItemTearOffGL
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-LLMenuItemTearOffGL::LLMenuItemTearOffGL(LLHandle<LLFloater> parent_floater_handle) :
- LLMenuItemGL(std::string("tear off"), TEAROFF_SEPARATOR_LABEL),
- mParentHandle(parent_floater_handle)
+LLMenuItemTearOffGL::LLMenuItemTearOffGL(const LLMenuItemTearOffGL::Params& p)
+: LLMenuItemGL(p),
+ mParentHandle(p.parent_floater_handle)
{
}
-void LLMenuItemTearOffGL::doIt()
+void LLMenuItemTearOffGL::onCommit()
{
if (getMenu()->getTornOff())
{
LLTearOffMenu* torn_off_menu = (LLTearOffMenu*)(getMenu()->getParent());
- torn_off_menu->close();
+ torn_off_menu->closeFloater();
}
else
{
@@ -641,7 +688,7 @@ void LLMenuItemTearOffGL::doIt()
getMenu()->highlightNextItem(this);
}
- getMenu()->arrange();
+ getMenu()->needsArrange();
LLFloater* parent_floater = mParentHandle.get();
LLFloater* tear_off_menu = LLTearOffMenu::create(getMenu());
@@ -658,7 +705,7 @@ void LLMenuItemTearOffGL::doIt()
tear_off_menu->setFocus(TRUE);
}
}
- LLMenuItemGL::doIt();
+ LLMenuItemGL::onCommit();
}
void LLMenuItemTearOffGL::draw()
@@ -666,17 +713,17 @@ void LLMenuItemTearOffGL::draw()
// disabled items can be highlighted, but shouldn't render as such
if( getEnabled() && getHighlight() && !isBriefItem())
{
- gGL.color4fv( getHighlightBGColor().mV );
+ gGL.color4fv( mHighlightBackground.get().mV );
gl_rect_2d( 0, getRect().getHeight(), getRect().getWidth(), 0 );
}
if (getEnabled())
{
- gGL.color4fv( getEnabledColor().mV );
+ gGL.color4fv( mEnabledColor.get().mV );
}
else
{
- gGL.color4fv( getDisabledColor().mV );
+ gGL.color4fv( mDisabledColor.get().mV );
}
const S32 y = getRect().getHeight() / 3;
const S32 PAD = 6;
@@ -699,11 +746,16 @@ U32 LLMenuItemTearOffGL::getNominalHeight( void ) const
class LLMenuItemBlankGL : public LLMenuItemGL
{
public:
- LLMenuItemBlankGL( void ) : LLMenuItemGL( LLStringUtil::null, LLStringUtil::null )
+ struct Params : public LLInitParam::Block<Params, LLMenuItemGL::Params>
{
- setEnabled(FALSE);
- }
- virtual void doIt( void ) {}
+ Params()
+ {
+ name="";
+ enabled = false;
+ }
+ };
+ LLMenuItemBlankGL( const Params& p ) : LLMenuItemGL( p )
+ {}
virtual void draw( void ) {}
};
@@ -712,238 +764,116 @@ public:
/// Class LLMenuItemCallGL
///============================================================================
-LLMenuItemCallGL::LLMenuItemCallGL( const std::string& name,
- const std::string& label,
- menu_callback clicked_cb,
- enabled_callback enabled_cb,
- void* user_data,
- KEY key, MASK mask,
- BOOL enabled,
- on_disabled_callback on_disabled_cb) :
- LLMenuItemGL( name, label, key, mask ),
- mCallback( clicked_cb ),
- mEnabledCallback( enabled_cb ),
- mLabelCallback(NULL),
- mUserData( user_data ),
- mOnDisabledCallback(on_disabled_cb)
-{
- if(!enabled) setEnabled(FALSE);
-}
-
-LLMenuItemCallGL::LLMenuItemCallGL( const std::string& name,
- menu_callback clicked_cb,
- enabled_callback enabled_cb,
- void* user_data,
- KEY key, MASK mask,
- BOOL enabled,
- on_disabled_callback on_disabled_cb) :
- LLMenuItemGL( name, name, key, mask ),
- mCallback( clicked_cb ),
- mEnabledCallback( enabled_cb ),
- mLabelCallback(NULL),
- mUserData( user_data ),
- mOnDisabledCallback(on_disabled_cb)
-{
- if(!enabled) setEnabled(FALSE);
-}
-
-LLMenuItemCallGL::LLMenuItemCallGL(const std::string& name,
- const std::string& label,
- menu_callback clicked_cb,
- enabled_callback enabled_cb,
- label_callback label_cb,
- void* user_data,
- KEY key, MASK mask,
- BOOL enabled,
- on_disabled_callback on_disabled_cb) :
- LLMenuItemGL(name, label, key, mask),
- mCallback(clicked_cb),
- mEnabledCallback(enabled_cb),
- mLabelCallback(label_cb),
- mUserData(user_data),
- mOnDisabledCallback(on_disabled_cb)
-{
- if(!enabled) setEnabled(FALSE);
-}
-
-LLMenuItemCallGL::LLMenuItemCallGL(const std::string& name,
- menu_callback clicked_cb,
- enabled_callback enabled_cb,
- label_callback label_cb,
- void* user_data,
- KEY key, MASK mask,
- BOOL enabled,
- on_disabled_callback on_disabled_cb) :
- LLMenuItemGL(name, name, key, mask),
- mCallback(clicked_cb),
- mEnabledCallback(enabled_cb),
- mLabelCallback(label_cb),
- mUserData(user_data),
- mOnDisabledCallback(on_disabled_cb)
-{
- if(!enabled) setEnabled(FALSE);
-}
-
-void LLMenuItemCallGL::setEnabledControl(std::string enabled_control, LLView *context)
-{
- // Register new listener
- if (!enabled_control.empty())
- {
- LLControlVariable *control = context->findControl(enabled_control);
- if (!control)
- {
- context->addBoolControl(enabled_control, getEnabled());
- control = context->findControl(enabled_control);
- llassert_always(control);
- }
- control->getSignal()->connect(boost::bind(&LLView::controlListener, _1, getHandle(), std::string("enabled")));
- setEnabled(control->getValue());
- }
-}
-
-void LLMenuItemCallGL::setVisibleControl(std::string visible_control, LLView *context)
+LLMenuItemCallGL::LLMenuItemCallGL(const LLMenuItemCallGL::Params& p)
+: LLMenuItemGL(p)
{
- // Register new listener
- if (!visible_control.empty())
- {
- LLControlVariable *control = context->findControl(visible_control);
- if (!control)
- {
- context->addBoolControl(visible_control, getVisible());
- control = context->findControl(visible_control);
- llassert_always(control);
- }
- control->getSignal()->connect(boost::bind(&LLView::controlListener, _1, getHandle(), std::string("visible")));
- setVisible(control->getValue());
- }
}
-// virtual
-LLXMLNodePtr LLMenuItemCallGL::getXML(bool save_children) const
+void LLMenuItemCallGL::initFromParams(const Params& p)
{
- LLXMLNodePtr node = LLMenuItemGL::getXML();
-
- // Contents
-
- std::vector<LLListenerEntry> listeners = mDispatcher->getListeners();
- std::vector<LLListenerEntry>::iterator itor;
- for (itor = listeners.begin(); itor != listeners.end(); ++itor)
+ if (p.on_enable.isProvided())
{
- std::string listener_name = findEventListener((LLSimpleListener*)itor->listener);
- if (!listener_name.empty())
+ initEnableCallback(p.on_enable, mEnableSignal);
+ // Set the enabled control variable (for backwards compatability)
+ if (p.on_enable.control_name.isProvided() && !p.on_enable.control_name().empty())
{
- LLXMLNodePtr child_node = node->createChild("on_click", FALSE);
- child_node->createChild("function", TRUE)->setStringValue(listener_name);
- child_node->createChild("filter", TRUE)->setStringValue(itor->filter.asString());
- child_node->createChild("userdata", TRUE)->setStringValue(itor->userdata.asString());
+ LLControlVariable* control = findControl(p.on_enable.control_name());
+ if (control)
+ setEnabledControlVariable(control);
}
}
-
- return node;
+ if (p.on_click.isProvided())
+ initCommitCallback(p.on_click, mCommitSignal);
+
+ LLUICtrl::initFromParams(p);
}
-// doIt() - Call the callback provided
-void LLMenuItemCallGL::doIt( void )
+void LLMenuItemCallGL::onCommit( void )
{
// RN: menu item can be deleted in callback, so beware
getMenu()->setItemLastSelected( this );
+
+ LLMenuItemGL::onCommit();
+}
- if( mCallback )
+void LLMenuItemCallGL::updateEnabled( void )
+{
+ if (mEnableSignal.num_slots() > 0)
{
- mCallback( mUserData );
+ bool enabled = mEnableSignal(this, LLSD());
+ if (mEnabledControlVariable)
+ {
+ if (!enabled)
+ mEnabledControlVariable->set(false); // callback overrides control variable; this will call setEnabled()
+ }
+ else
+ {
+ setEnabled(enabled);
+ }
}
- LLPointer<LLEvent> fired_event = new LLEvent(this);
- fireEvent(fired_event, "on_click");
- LLMenuItemGL::doIt();
}
void LLMenuItemCallGL::buildDrawLabel( void )
{
- LLPointer<LLEvent> fired_event = new LLEvent(this);
- fireEvent(fired_event, "on_build");
- if( mEnabledCallback )
- {
- setEnabled( mEnabledCallback( mUserData ) );
- }
- if(mLabelCallback)
- {
- std::string label;
- mLabelCallback(label, mUserData);
- mLabel = label;
- }
+ updateEnabled();
LLMenuItemGL::buildDrawLabel();
}
+BOOL LLMenuItemCallGL::handleKeyHere( KEY key, MASK mask )
+{
+ return LLMenuItemGL::handleKeyHere(key, mask);
+}
+
BOOL LLMenuItemCallGL::handleAcceleratorKey( KEY key, MASK mask )
{
- if( (!gKeyboard->getKeyRepeated(key) || getAllowKeyRepeat()) && (key == mAcceleratorKey) && (mask == (mAcceleratorMask & MASK_NORMALKEYS)) )
+ if( (!gKeyboard->getKeyRepeated(key) || getAllowKeyRepeat()) && (key == mAcceleratorKey) && (mask == (mAcceleratorMask & MASK_NORMALKEYS)) )
{
- LLPointer<LLEvent> fired_event = new LLEvent(this);
- fireEvent(fired_event, "on_build");
- if( mEnabledCallback )
- {
- setEnabled( mEnabledCallback( mUserData ) );
- }
- if( !getEnabled() )
+ updateEnabled();
+ if (getEnabled())
{
- if( mOnDisabledCallback )
- {
- mOnDisabledCallback( mUserData );
- }
+ onCommit();
+ return TRUE;
}
}
- return LLMenuItemGL::handleAcceleratorKey(key, mask);
+ return FALSE;
}
+// handleRightMouseUp moved into base class LLMenuItemGL so clicks are
+// handled for all menu item types
+
///============================================================================
/// Class LLMenuItemCheckGL
///============================================================================
-
-LLMenuItemCheckGL::LLMenuItemCheckGL ( const std::string& name,
- const std::string& label,
- menu_callback clicked_cb,
- enabled_callback enabled_cb,
- check_callback check_cb,
- void* user_data,
- KEY key, MASK mask ) :
- LLMenuItemCallGL( name, label, clicked_cb, enabled_cb, user_data, key, mask ),
- mCheckCallback( check_cb ),
- mChecked(FALSE)
+LLMenuItemCheckGL::LLMenuItemCheckGL (const LLMenuItemCheckGL::Params& p)
+: LLMenuItemCallGL(p)
{
}
-LLMenuItemCheckGL::LLMenuItemCheckGL ( const std::string& name,
- menu_callback clicked_cb,
- enabled_callback enabled_cb,
- check_callback check_cb,
- void* user_data,
- KEY key, MASK mask ) :
- LLMenuItemCallGL( name, name, clicked_cb, enabled_cb, user_data, key, mask ),
- mCheckCallback( check_cb ),
- mChecked(FALSE)
+void LLMenuItemCheckGL::initFromParams(const Params& p)
{
+ if (p.on_check.isProvided())
+ {
+ initEnableCallback(p.on_check, mCheckSignal);
+ // Set the control name (for backwards compatability)
+ if (p.on_check.control_name.isProvided() && !p.on_check.control_name().empty())
+ {
+ setControlName(p.on_check.control_name());
+ }
+ }
+
+ LLMenuItemCallGL::initFromParams(p);
}
-LLMenuItemCheckGL::LLMenuItemCheckGL ( const std::string& name,
- const std::string& label,
- menu_callback clicked_cb,
- enabled_callback enabled_cb,
- std::string control_name,
- LLView *context,
- void* user_data,
- KEY key, MASK mask ) :
- LLMenuItemCallGL( name, label, clicked_cb, enabled_cb, user_data, key, mask ),
- mCheckCallback( NULL ),
- mChecked(FALSE)
+void LLMenuItemCheckGL::onCommit( void )
{
- setControlName(control_name, context);
+ LLMenuItemCallGL::onCommit();
}
//virtual
void LLMenuItemCheckGL::setValue(const LLSD& value)
{
- mChecked = value.asBoolean();
- if(mChecked)
+ LLUICtrl::setValue(value);
+ if(value.asBoolean())
{
mDrawBoolLabel = BOOLEAN_TRUE_PREFIX;
}
@@ -953,34 +883,21 @@ void LLMenuItemCheckGL::setValue(const LLSD& value)
}
}
-void LLMenuItemCheckGL::setCheckedControl(std::string checked_control, LLView *context)
-{
- // Register new listener
- if (!checked_control.empty())
- {
- LLControlVariable *control = context->findControl(checked_control);
- if (!control)
- {
- context->addBoolControl(checked_control, mChecked);
- control = context->findControl(checked_control);
- llassert_always(control);
- }
- control->getSignal()->connect(boost::bind(&LLView::controlListener, _1, getHandle(), std::string("value")));
- mChecked = control->getValue();
- }
-}
-
-// virtual
-LLXMLNodePtr LLMenuItemCheckGL::getXML(bool save_children) const
-{
- LLXMLNodePtr node = LLMenuItemCallGL::getXML();
- return node;
-}
-
// called to rebuild the draw label
void LLMenuItemCheckGL::buildDrawLabel( void )
{
- if(mChecked || (mCheckCallback && mCheckCallback( getUserData() ) ) )
+ // Note: mCheckSignal() returns true if no callbacks are set
+ bool checked = mCheckSignal(this, LLSD());
+ if (mControlVariable)
+ {
+ if (!checked)
+ setControlValue(false); // callback overrides control variable; this will call setValue()
+ }
+ else
+ {
+ setValue(checked);
+ }
+ if(getValue().asBoolean())
{
mDrawBoolLabel = BOOLEAN_TRUE_PREFIX;
}
@@ -991,95 +908,59 @@ void LLMenuItemCheckGL::buildDrawLabel( void )
LLMenuItemCallGL::buildDrawLabel();
}
-
///============================================================================
-/// Class LLMenuItemToggleGL
+/// Class LLMenuItemBranchGL
///============================================================================
-
-LLMenuItemToggleGL::LLMenuItemToggleGL( const std::string& name, const std::string& label, BOOL* toggle,
- KEY key, MASK mask ) :
- LLMenuItemGL( name, label, key, mask ),
- mToggle( toggle )
+LLMenuItemBranchGL::LLMenuItemBranchGL(const LLMenuItemBranchGL::Params& p)
+ : LLMenuItemGL(p)
{
-}
-
-LLMenuItemToggleGL::LLMenuItemToggleGL( const std::string& name, BOOL* toggle,
- KEY key, MASK mask ) :
- LLMenuItemGL( name, name, key, mask ),
- mToggle( toggle )
-{
-}
-
-
-// called to rebuild the draw label
-void LLMenuItemToggleGL::buildDrawLabel( void )
-{
- if( *mToggle )
- {
- mDrawBoolLabel = BOOLEAN_TRUE_PREFIX;
- }
- else
+ LLMenuGL* branch = p.branch;
+ if (branch)
{
- mDrawBoolLabel.clear();
+ mBranchHandle = branch->getHandle();
+ branch->setVisible(FALSE);
+ branch->setParentMenuItem(this);
}
- mDrawAccelLabel.clear();
- std::string st = mDrawAccelLabel;
- appendAcceleratorString( st );
- mDrawAccelLabel = st;
}
-// doIt() - do the primary funcationality of the menu item.
-void LLMenuItemToggleGL::doIt( void )
+LLMenuItemBranchGL::~LLMenuItemBranchGL()
{
- getMenu()->setItemLastSelected( this );
- //llinfos << "LLMenuItemToggleGL::doIt " << mLabel.c_str() << llendl;
- *mToggle = !(*mToggle);
- buildDrawLabel();
- LLMenuItemGL::doIt();
+ LLView::deleteViewByHandle(mBranchHandle);
}
-
-LLMenuItemBranchGL::LLMenuItemBranchGL( const std::string& name, const std::string& label, LLHandle<LLView> branch,
- KEY key, MASK mask ) :
- LLMenuItemGL( name, label, key, mask ),
- mBranch( branch )
+// virtual
+LLView* LLMenuItemBranchGL::getChildView(const std::string& name, BOOL recurse) const
{
- if(!dynamic_cast<LLMenuGL*>(branch.get()))
+ LLMenuGL* branch = getBranch();
+ if (branch)
{
- llerrs << "Non-menu handle passed as branch reference." << llendl;
- }
+ if (branch->getName() == name)
+ {
+ return branch;
+ }
- if(getBranch())
- {
- getBranch()->setVisible( FALSE );
- getBranch()->setParentMenuItem(this);
+ // Always recurse on branches
+ return branch->getChildView(name, recurse);
}
-}
-LLMenuItemBranchGL::~LLMenuItemBranchGL()
-{
- LLView::deleteViewByHandle(mBranch);
+ return LLView::getChildView(name, recurse);
}
-// virtual
-LLView* LLMenuItemBranchGL::getChildView(const std::string& name, BOOL recurse, BOOL create_if_missing) const
+LLView* LLMenuItemBranchGL::findChildView(const std::string& name, BOOL recurse) const
{
- // richard: this is redundant with parent, remove
- if (getBranch())
+ LLMenuGL* branch = getBranch();
+ if (branch)
{
- if(getBranch()->getName() == name)
+ if (branch->getName() == name)
{
- return getBranch();
+ return branch;
}
// Always recurse on branches
- LLView* child = getBranch()->getChildView(name, recurse, FALSE);
- if(child)
- {
- return child;
- }
+ return branch->findChildView(name, recurse);
}
- return LLView::getChildView(name, recurse, create_if_missing);;
+
+ return LLView::findChildView(name, recurse);
}
// virtual
@@ -1088,49 +969,35 @@ BOOL LLMenuItemBranchGL::handleMouseUp(S32 x, S32 y, MASK mask)
// switch to mouse navigation mode
LLMenuGL::setKeyboardMode(FALSE);
- doIt();
+ onCommit();
make_ui_sound("UISndClickRelease");
return TRUE;
}
BOOL LLMenuItemBranchGL::handleAcceleratorKey(KEY key, MASK mask)
{
- if(getBranch())
- {
- return getBranch()->handleAcceleratorKey(key, mask);
- }
- return FALSE;
-}
-
-// virtual
-LLXMLNodePtr LLMenuItemBranchGL::getXML(bool save_children) const
-{
- if (getBranch())
- {
- return getBranch()->getXML();
- }
-
- return LLMenuItemGL::getXML();
+ return getBranch() && getBranch()->handleAcceleratorKey(key, mask);
}
-
// This function checks to see if the accelerator key is already in use;
// if not, it will be added to the list
BOOL LLMenuItemBranchGL::addToAcceleratorList(std::list<LLKeyBinding*> *listp)
{
- if(getBranch())
- {
- U32 item_count = getBranch()->getItemCount();
- LLMenuItemGL *item;
+ LLMenuGL* branch = getBranch();
+ if (!branch)
+ return FALSE;
- while (item_count--)
+ U32 item_count = branch->getItemCount();
+ LLMenuItemGL *item;
+
+ while (item_count--)
+ {
+ if ((item = branch->getItem(item_count)))
{
- if ((item = getBranch()->getItem(item_count)))
- {
- return item->addToAcceleratorList(listp);
- }
+ return item->addToAcceleratorList(listp);
}
}
+
return FALSE;
}
@@ -1145,23 +1012,24 @@ void LLMenuItemBranchGL::buildDrawLabel( void )
mDrawBranchLabel = BRANCH_SUFFIX;
}
-// doIt() - do the primary functionality of the menu item.
-void LLMenuItemBranchGL::doIt( void )
+void LLMenuItemBranchGL::onCommit( void )
{
openMenu();
// keyboard navigation automatically propagates highlight to sub-menu
// to facilitate fast menu control via jump keys
- if (getBranch() && LLMenuGL::getKeyboardMode() && !getBranch()->getHighlightedItem())
+ if (LLMenuGL::getKeyboardMode() && getBranch()&& !getBranch()->getHighlightedItem())
{
getBranch()->highlightNextItem(NULL);
}
+
+ LLUICtrl::onCommit();
}
BOOL LLMenuItemBranchGL::handleKey(KEY key, MASK mask, BOOL called_from_parent)
{
BOOL handled = FALSE;
- if (called_from_parent && getBranch())
+ if (getBranch() && called_from_parent)
{
handled = getBranch()->handleKey(key, mask, called_from_parent);
}
@@ -1177,7 +1045,7 @@ BOOL LLMenuItemBranchGL::handleKey(KEY key, MASK mask, BOOL called_from_parent)
BOOL LLMenuItemBranchGL::handleUnicodeChar(llwchar uni_char, BOOL called_from_parent)
{
BOOL handled = FALSE;
- if (called_from_parent && getBranch())
+ if (getBranch() && called_from_parent)
{
handled = getBranch()->handleUnicodeChar(uni_char, TRUE);
}
@@ -1193,21 +1061,21 @@ BOOL LLMenuItemBranchGL::handleUnicodeChar(llwchar uni_char, BOOL called_from_pa
void LLMenuItemBranchGL::setHighlight( BOOL highlight )
{
- if (highlight == getHighlight()) return;
+ if (highlight == getHighlight())
+ return;
- if(!getBranch())
- {
+ LLMenuGL* branch = getBranch();
+ if (!branch)
return;
- }
- BOOL auto_open = getEnabled() && (!getBranch()->getVisible() || getBranch()->getTornOff());
+ BOOL auto_open = getEnabled() && (!branch->getVisible() || branch->getTornOff());
// torn off menus don't open sub menus on hover unless they have focus
if (getMenu()->getTornOff() && !((LLFloater*)getMenu()->getParent())->hasFocus())
{
auto_open = FALSE;
}
// don't auto open torn off sub-menus (need to explicitly active menu item to give them focus)
- if (getBranch()->getTornOff())
+ if (branch->getTornOff())
{
auto_open = FALSE;
}
@@ -1221,14 +1089,14 @@ void LLMenuItemBranchGL::setHighlight( BOOL highlight )
}
else
{
- if (getBranch()->getTornOff())
+ if (branch->getTornOff())
{
- ((LLFloater*)getBranch()->getParent())->setFocus(FALSE);
- getBranch()->clearHoverItem();
+ ((LLFloater*)branch->getParent())->setFocus(FALSE);
+ branch->clearHoverItem();
}
else
{
- getBranch()->setVisible( FALSE );
+ branch->setVisible( FALSE );
}
}
}
@@ -1251,26 +1119,30 @@ void LLMenuItemBranchGL::updateBranchParent(LLView* parentp)
}
}
-void LLMenuItemBranchGL::onVisibilityChange( BOOL new_visibility )
+void LLMenuItemBranchGL::handleVisibilityChange( BOOL new_visibility )
{
if (new_visibility == FALSE && getBranch() && !getBranch()->getTornOff())
{
getBranch()->setVisible(FALSE);
}
- LLMenuItemGL::onVisibilityChange(new_visibility);
+ LLMenuItemGL::handleVisibilityChange(new_visibility);
}
BOOL LLMenuItemBranchGL::handleKeyHere( KEY key, MASK mask )
{
- if (getMenu()->getVisible() && getBranch() && getBranch()->getVisible() && key == KEY_LEFT)
+ LLMenuGL* branch = getBranch();
+ if (!branch)
+ return LLMenuItemGL::handleKeyHere(key, mask);
+
+ if (getMenu()->getVisible() && branch->getVisible() && key == KEY_LEFT)
{
// switch to keyboard navigation mode
LLMenuGL::setKeyboardMode(TRUE);
- BOOL handled = getBranch()->clearHoverItem();
- if (getBranch()->getTornOff())
+ BOOL handled = branch->clearHoverItem();
+ if (branch->getTornOff())
{
- ((LLFloater*)getBranch()->getParent())->setFocus(FALSE);
+ ((LLFloater*)branch->getParent())->setFocus(FALSE);
}
if (handled && getMenu()->getTornOff())
{
@@ -1281,12 +1153,12 @@ BOOL LLMenuItemBranchGL::handleKeyHere( KEY key, MASK mask )
if (getHighlight() &&
getMenu()->isOpen() &&
- key == KEY_RIGHT && getBranch() && !getBranch()->getHighlightedItem())
+ key == KEY_RIGHT && !branch->getHighlightedItem())
{
// switch to keyboard navigation mode
LLMenuGL::setKeyboardMode(TRUE);
- LLMenuItemGL* itemp = getBranch()->highlightNextItem(NULL);
+ LLMenuItemGL* itemp = branch->highlightNextItem(NULL);
if (itemp)
{
return TRUE;
@@ -1296,41 +1168,55 @@ BOOL LLMenuItemBranchGL::handleKeyHere( KEY key, MASK mask )
return LLMenuItemGL::handleKeyHere(key, mask);
}
+//virtual
+BOOL LLMenuItemBranchGL::isActive() const
+{
+ return isOpen() && getBranch() && getBranch()->getHighlightedItem();
+}
+
+//virtual
+BOOL LLMenuItemBranchGL::isOpen() const
+{
+ return getBranch() && getBranch()->isOpen();
+}
+
void LLMenuItemBranchGL::openMenu()
{
- if(!getBranch()) return;
+ LLMenuGL* branch = getBranch();
+ if (!branch)
+ return;
- if (getBranch()->getTornOff())
+ if (branch->getTornOff())
{
- gFloaterView->bringToFront((LLFloater*)getBranch()->getParent());
+ gFloaterView->bringToFront((LLFloater*)branch->getParent());
// this might not be necessary, as torn off branches don't get focus and hence no highligth
- getBranch()->highlightNextItem(NULL);
+ branch->highlightNextItem(NULL);
}
- else if( !getBranch()->getVisible() )
+ else if( !branch->getVisible() )
{
// get valid rectangle for menus
const LLRect menu_region_rect = LLMenuGL::sMenuContainer->getMenuRect();
- getBranch()->arrange();
+ branch->arrange();
- LLRect rect = getBranch()->getRect();
+ LLRect rect = branch->getRect();
// calculate root-view relative position for branch menu
S32 left = getRect().mRight;
S32 top = getRect().mTop - getRect().mBottom;
- localPointToOtherView(left, top, &left, &top, getBranch()->getParent());
+ localPointToOtherView(left, top, &left, &top, branch->getParent());
rect.setLeftTopAndSize( left, top,
rect.getWidth(), rect.getHeight() );
- if (getBranch()->getCanTearOff())
+ if (branch->getCanTearOff())
{
rect.translate(0, TEAROFF_SEPARATOR_HEIGHT_PIXELS);
}
- getBranch()->setRect( rect );
+ branch->setRect( rect );
S32 x = 0;
S32 y = 0;
- getBranch()->localPointToOtherView( 0, 0, &x, &y, getBranch()->getParent() );
+ branch->localPointToOtherView( 0, 0, &x, &y, branch->getParent() );
S32 delta_x = 0;
S32 delta_y = 0;
if( y < menu_region_rect.mBottom )
@@ -1344,9 +1230,9 @@ void LLMenuItemBranchGL::openMenu()
// move sub-menu over to left side
delta_x = llmax(-x, (-1 * (rect.getWidth() + getRect().getWidth())));
}
- getBranch()->translate( delta_x, delta_y );
- getBranch()->setVisible( TRUE );
- getBranch()->getParent()->sendChildToFront(getBranch());
+ branch->translate( delta_x, delta_y );
+ branch->setVisible( TRUE );
+ branch->getParent()->sendChildToFront(branch);
}
}
@@ -1363,10 +1249,7 @@ class LLMenuItemBranchDownGL : public LLMenuItemBranchGL
protected:
public:
- LLMenuItemBranchDownGL( const std::string& name, const std::string& label, LLHandle<LLView> branch,
- KEY key = KEY_NONE, MASK mask = MASK_NONE );
-
- virtual std::string getType() const { return "menu"; }
+ LLMenuItemBranchDownGL( const Params& );
// returns the normal width of this control in pixels - this is
// used for calculating the widest item, as well as for horizontal
@@ -1394,11 +1277,8 @@ public:
virtual BOOL handleAcceleratorKey(KEY key, MASK mask);
};
-LLMenuItemBranchDownGL::LLMenuItemBranchDownGL( const std::string& name,
- const std::string& label,
- LLHandle<LLView> branch,
- KEY key, MASK mask ) :
- LLMenuItemBranchGL( name, label, branch, key, mask )
+LLMenuItemBranchDownGL::LLMenuItemBranchDownGL( const Params& p) :
+ LLMenuItemBranchGL(p)
{
}
@@ -1473,20 +1353,26 @@ void LLMenuItemBranchDownGL::openMenu( void )
// set the hover status (called by it's menu)
void LLMenuItemBranchDownGL::setHighlight( BOOL highlight )
{
- if (highlight == getHighlight()) return;
+ if (highlight == getHighlight())
+ return;
//NOTE: Purposely calling all the way to the base to bypass auto-open.
LLMenuItemGL::setHighlight(highlight);
+
+ LLMenuGL* branch = getBranch();
+ if (!branch)
+ return;
+
if( !highlight)
{
- if (getBranch()->getTornOff())
+ if (branch->getTornOff())
{
- ((LLFloater*)getBranch()->getParent())->setFocus(FALSE);
- getBranch()->clearHoverItem();
+ ((LLFloater*)branch->getParent())->setFocus(FALSE);
+ branch->clearHoverItem();
}
else
{
- getBranch()->setVisible( FALSE );
+ branch->setVisible( FALSE );
}
}
}
@@ -1503,7 +1389,7 @@ BOOL LLMenuItemBranchDownGL::handleMouseDown( S32 x, S32 y, MASK mask )
{
// switch to mouse control mode
LLMenuGL::setKeyboardMode(FALSE);
- doIt();
+ onCommit();
make_ui_sound("UISndClick");
return TRUE;
}
@@ -1542,7 +1428,7 @@ BOOL LLMenuItemBranchDownGL::handleKeyHere(KEY key, MASK mask)
// open new menu only if previous menu was open
if (itemp && itemp->getEnabled() && menu_open)
{
- itemp->doIt();
+ itemp->onCommit();
}
return TRUE;
@@ -1556,7 +1442,7 @@ BOOL LLMenuItemBranchDownGL::handleKeyHere(KEY key, MASK mask)
// open new menu only if previous menu was open
if (itemp && itemp->getEnabled() && menu_open)
{
- itemp->doIt();
+ itemp->onCommit();
}
return TRUE;
@@ -1568,7 +1454,7 @@ BOOL LLMenuItemBranchDownGL::handleKeyHere(KEY key, MASK mask)
if (!isActive())
{
- doIt();
+ onCommit();
}
getBranch()->highlightNextItem(NULL);
return TRUE;
@@ -1580,7 +1466,7 @@ BOOL LLMenuItemBranchDownGL::handleKeyHere(KEY key, MASK mask)
if (!isActive())
{
- doIt();
+ onCommit();
}
getBranch()->highlightPrevItem(NULL);
return TRUE;
@@ -1600,31 +1486,31 @@ void LLMenuItemBranchDownGL::draw( void )
if( getHighlight() )
{
- gGL.color4fv( getHighlightBGColor().mV );
+ gGL.color4fv( mHighlightBackground.get().mV );
gl_rect_2d( 0, getRect().getHeight(), getRect().getWidth(), 0 );
}
- U8 font_style = getFontStyle();
+ LLFontGL::ShadowType shadow_style = LLFontGL::NO_SHADOW;
if (getEnabled() && !getDrawTextDisabled() )
{
- font_style |= LLFontGL::DROP_SHADOW_SOFT;
+ shadow_style = LLFontGL::DROP_SHADOW_SOFT;
}
LLColor4 color;
if (getHighlight())
{
- color = getHighlightFGColor();
+ color = mHighlightForeground.get();
}
else if( getEnabled() )
{
- color = getEnabledColor();
+ color = mEnabledColor.get();
}
else
{
- color = getDisabledColor();
+ color = mDisabledColor.get();
}
getFont()->render( mLabel.getWString(), 0, (F32)getRect().getWidth() / 2.f, (F32)LABEL_BOTTOM_PAD_PIXELS, color,
- LLFontGL::HCENTER, LLFontGL::BOTTOM, font_style );
+ LLFontGL::HCENTER, LLFontGL::BOTTOM, LLFontGL::NORMAL, shadow_style );
// underline navigation key only when keyboard navigation has been initiated
@@ -1647,22 +1533,118 @@ void LLMenuItemBranchDownGL::draw( void )
setHover(FALSE);
}
+
+class LLMenuScrollItem : public LLMenuItemCallGL
+{
+public:
+ enum EArrowType
+ {
+ ARROW_DOWN,
+ ARROW_UP
+ };
+ struct ArrowTypes : public LLInitParam::TypeValuesHelper<EArrowType, ArrowTypes>
+ {
+ static void declareValues()
+ {
+ declare("up", ARROW_UP);
+ declare("down", ARROW_DOWN);
+ }
+ };
+
+ struct Params : public LLInitParam::Block<Params, LLMenuItemCallGL::Params>
+ {
+ Optional<EArrowType, ArrowTypes> arrow_type;
+ Optional<CommitCallbackParam> scroll_callback;
+ };
+
+protected:
+ LLMenuScrollItem(const Params&);
+ friend class LLUICtrlFactory;
+
+public:
+ /*virtual*/ void draw();
+ /*virtual*/ void reshape(S32 width, S32 height, BOOL called_from_parent);
+ /*virtual*/ void setEnabled(BOOL enabled);
+ virtual void onCommit( void );
+
+private:
+ LLButton* mArrowBtn;
+};
+
+LLMenuScrollItem::LLMenuScrollItem(const Params& p)
+: LLMenuItemCallGL(p)
+{
+ std::string icon;
+ if (p.arrow_type.isProvided() && p.arrow_type == ARROW_UP)
+ {
+ icon = "arrow_up.tga";
+ }
+ else
+ {
+ icon = "arrow_down.tga";
+ }
+
+ LLButton::Params bparams;
+ bparams.label("");
+ bparams.label_selected("");
+ bparams.mouse_opaque(true);
+ bparams.scale_image(false);
+ bparams.click_callback(p.scroll_callback);
+ bparams.mouse_held_callback(p.scroll_callback);
+ bparams.follows.flags(FOLLOWS_ALL);
+ std::string background = "transparent.j2c";
+ bparams.image_unselected.name(background);
+ bparams.image_disabled.name(background);
+ bparams.image_selected.name(background);
+ bparams.image_hover_selected.name(background);
+ bparams.image_disabled_selected.name(background);
+ bparams.image_hover_unselected.name(background);
+ bparams.image_overlay.name(icon);
+
+ mArrowBtn = LLUICtrlFactory::create<LLButton>(bparams);
+ addChild(mArrowBtn);
+}
+
+/*virtual*/
+void LLMenuScrollItem::draw()
+{
+ LLUICtrl::draw();
+}
+
+/*virtual*/
+void LLMenuScrollItem::reshape(S32 width, S32 height, BOOL called_from_parent)
+{
+ mArrowBtn->reshape(width, height, called_from_parent);
+ LLView::reshape(width, height, called_from_parent);
+}
+
+/*virtual*/
+void LLMenuScrollItem::setEnabled(BOOL enabled)
+{
+ mArrowBtn->setEnabled(enabled);
+ LLView::setEnabled(enabled);
+}
+
+void LLMenuScrollItem::onCommit( void )
+{
+ LLUICtrl::onCommit();
+}
+
///============================================================================
/// Class LLMenuGL
///============================================================================
-static LLRegisterWidget<LLMenuGL> r1("menu");
-
-// Default constructor
-LLMenuGL::LLMenuGL( const std::string& name, const std::string& label, LLHandle<LLFloater> parent_floater_handle )
-: LLUICtrl( name, LLRect(), FALSE, NULL, NULL ),
- mBackgroundColor( sDefaultBackgroundColor ),
- mBgVisible( TRUE ),
- mParentMenuItem( NULL ),
- mLabel( label ),
- mDropShadowed( TRUE ),
- mHorizontalLayout( FALSE ),
- mKeepFixedSize( FALSE ),
+LLMenuGL::LLMenuGL(const LLMenuGL::Params& p)
+: LLUICtrl(p),
+ mBackgroundColor( p.bg_color() ),
+ mBgVisible( p.bg_visible ),
+ mDropShadowed( p.drop_shadow ),
+ mHorizontalLayout( p.horizontal_layout ),
+ mScrollable(mHorizontalLayout ? FALSE : p.scrollable), // Scrolling is supported only for vertical layout
+ mMaxScrollableItems(p.max_scrollable_items),
+ mPreferredWidth(p.preferred_width),
+ mKeepFixedSize( p.keep_fixed_size ),
+ mLabel (p.label),
mLastMouseX(0),
mLastMouseY(0),
mMouseVelX(0),
@@ -1670,38 +1652,41 @@ LLMenuGL::LLMenuGL( const std::string& name, const std::string& label, LLHandle<
mTornOff(FALSE),
mTearOffItem(NULL),
mSpilloverBranch(NULL),
+ mFirstVisibleItem(NULL),
+ mArrowUpItem(NULL),
+ mArrowDownItem(NULL),
mSpilloverMenu(NULL),
- mParentFloaterHandle(parent_floater_handle),
- mJumpKey(KEY_NONE)
+ mJumpKey(p.jump_key),
+ mCreateJumpKeys(p.create_jump_keys),
+ mParentFloaterHandle(p.parent_floater),
+ mNeedsArrange(FALSE),
+ mShortcutPad(p.shortcut_pad)
{
+ typedef boost::tokenizer<boost::char_separator<char> > tokenizer;
+ boost::char_separator<char> sep("_");
+ tokenizer tokens(p.label(), sep);
+ tokenizer::iterator token_iter;
+
+ S32 token_count = 0;
+ std::string new_menu_label;
+ for( token_iter = tokens.begin(); token_iter != tokens.end(); ++token_iter)
+ {
+ new_menu_label += (*token_iter);
+ if (token_count > 0)
+ {
+ setJumpKey((*token_iter).c_str()[0]);
+ }
+ ++token_count;
+ }
+ setLabel(new_menu_label);
+
mFadeTimer.stop();
- setCanTearOff(TRUE, parent_floater_handle);
- setTabStop(FALSE);
-}
-
-LLMenuGL::LLMenuGL( const std::string& label, LLHandle<LLFloater> parent_floater_handle )
-: LLUICtrl( label, LLRect(), FALSE, NULL, NULL ),
- mBackgroundColor( sDefaultBackgroundColor ),
- mBgVisible( TRUE ),
- mParentMenuItem( NULL ),
- mLabel( label ),
- mDropShadowed( TRUE ),
- mHorizontalLayout( FALSE ),
- mKeepFixedSize( FALSE ),
- mLastMouseX(0),
- mLastMouseY(0),
- mMouseVelX(0),
- mMouseVelY(0),
- mTornOff(FALSE),
- mTearOffItem(NULL),
- mSpilloverBranch(NULL),
- mSpilloverMenu(NULL),
- mParentFloaterHandle(parent_floater_handle),
- mJumpKey(KEY_NONE)
+}
+
+void LLMenuGL::initFromParams(const LLMenuGL::Params& p)
{
- mFadeTimer.stop();
- setCanTearOff(TRUE, parent_floater_handle);
- setTabStop(FALSE);
+ LLUICtrl::initFromParams(p);
+ setCanTearOff(p.can_tear_off, p.parent_floater);
}
// Destroys the object
@@ -1717,10 +1702,10 @@ void LLMenuGL::setCanTearOff(BOOL tear_off, LLHandle<LLFloater> parent_floater_h
{
if (tear_off && mTearOffItem == NULL)
{
- mTearOffItem = new LLMenuItemTearOffGL(parent_floater_handle);
- mItems.insert(mItems.begin(), mTearOffItem);
- addChildAtEnd(mTearOffItem);
- arrange();
+ LLMenuItemTearOffGL::Params p;
+ p.parent_floater_handle = parent_floater_handle;
+ mTearOffItem = LLUICtrlFactory::create<LLMenuItemTearOffGL>(p);
+ addChildInBack(mTearOffItem);
}
else if (!tear_off && mTearOffItem != NULL)
{
@@ -1728,313 +1713,45 @@ void LLMenuGL::setCanTearOff(BOOL tear_off, LLHandle<LLFloater> parent_floater_h
removeChild(mTearOffItem);
delete mTearOffItem;
mTearOffItem = NULL;
- arrange();
+ needsArrange();
}
}
-// virtual
-LLXMLNodePtr LLMenuGL::getXML(bool save_children) const
+bool LLMenuGL::addChild(LLView* view, S32 tab_group)
{
- LLXMLNodePtr node = LLView::getXML();
-
- // Attributes
-
- node->createChild("opaque", TRUE)->setBoolValue(mBgVisible);
-
- node->createChild("drop_shadow", TRUE)->setBoolValue(mDropShadowed);
-
- node->createChild("tear_off", TRUE)->setBoolValue((mTearOffItem != NULL));
-
- if (mBgVisible)
+ if (LLMenuGL* menup = dynamic_cast<LLMenuGL*>(view))
{
- // TomY TODO: this should save out the color control name
- node->createChild("color", TRUE)->setFloatValue(4, mBackgroundColor.mV);
+ appendMenu(menup);
+ return true;
}
-
- // Contents
- item_list_t::const_iterator item_iter;
- for (item_iter = mItems.begin(); item_iter != mItems.end(); ++item_iter)
+ else if (LLMenuItemGL* itemp = dynamic_cast<LLMenuItemGL*>(view))
{
- LLView* child = (*item_iter);
- LLMenuItemGL* item = (LLMenuItemGL*)child;
-
- LLXMLNodePtr child_node = item->getXML();
-
- node->addChild(child_node);
+ append(itemp);
+ return true;
}
-
- return node;
+ return false;
}
-void LLMenuGL::parseChildXML(LLXMLNodePtr child, LLView *parent, LLUICtrlFactory *factory)
+void LLMenuGL::removeChild( LLView* ctrl)
{
- if (child->hasName(LL_MENU_GL_TAG))
+ // previously a dynamic_cast with if statement to check validity
+ // unfortunately removeChild is called by ~LLView, and at that point the
+ // object being deleted is no longer a LLMenuItemGL so a dynamic_cast will fail
+ LLMenuItemGL* itemp = static_cast<LLMenuItemGL*>(ctrl);
+
+ item_list_t::iterator found_it = std::find(mItems.begin(), mItems.end(), (itemp));
+ if (found_it != mItems.end())
{
- // SUBMENU
- LLMenuGL *submenu = (LLMenuGL*)LLMenuGL::fromXML(child, parent, factory);
- appendMenu(submenu);
- if (LLMenuGL::sMenuContainer != NULL)
- {
- submenu->updateParent(LLMenuGL::sMenuContainer);
- }
- else
- {
- submenu->updateParent(parent);
- }
+ mItems.erase(found_it);
}
- else if (child->hasName(LL_MENU_ITEM_CALL_GL_TAG) ||
- child->hasName(LL_MENU_ITEM_CHECK_GL_TAG) ||
- child->hasName(LL_MENU_ITEM_SEPARATOR_GL_TAG))
- {
- LLMenuItemGL *item = NULL;
-
- std::string type;
- std::string item_name;
- std::string source_label;
- std::string item_label;
- KEY jump_key = KEY_NONE;
-
- child->getAttributeString("type", type);
- child->getAttributeString("name", item_name);
- child->getAttributeString("label", source_label);
-
- // parse jump key out of label
- typedef boost::tokenizer<boost::char_separator<char> > tokenizer;
- boost::char_separator<char> sep("_");
- tokenizer tokens(source_label, sep);
- tokenizer::iterator token_iter;
- S32 token_count = 0;
- for( token_iter = tokens.begin(); token_iter != tokens.end(); ++token_iter)
- {
- item_label += (*token_iter);
- if (token_count > 0)
- {
- jump_key = (*token_iter).c_str()[0];
- }
- ++token_count;
- }
+ return LLUICtrl::removeChild(ctrl);
+}
- if (child->hasName(LL_MENU_ITEM_SEPARATOR_GL_TAG))
- {
- appendSeparator(item_name);
- }
- else
- {
- // ITEM
- if (child->hasName(LL_MENU_ITEM_CALL_GL_TAG) ||
- child->hasName(LL_MENU_ITEM_CHECK_GL_TAG))
- {
- MASK mask = 0;
-
-#ifdef LL_DARWIN
- // See if this Mac accelerator should really use the ctrl key and not get mapped to cmd
- BOOL useMacCtrl = FALSE;
- child->getAttributeBOOL("useMacCtrl", useMacCtrl);
-#endif // LL_DARWIN
-
- std::string shortcut;
- child->getAttributeString("shortcut", shortcut);
- if (shortcut.find("control") != shortcut.npos)
- {
-#ifdef LL_DARWIN
- if ( useMacCtrl )
- {
- mask |= MASK_MAC_CONTROL;
- }
-#endif // LL_DARWIN
- mask |= MASK_CONTROL;
- }
- if (shortcut.find("alt") != shortcut.npos)
- {
- mask |= MASK_ALT;
- }
- if (shortcut.find("shift") != shortcut.npos)
- {
- mask |= MASK_SHIFT;
- }
- S32 pipe_pos = shortcut.rfind("|");
- std::string key_str = shortcut.substr(pipe_pos+1);
-
- KEY key = KEY_NONE;
- LLKeyboard::keyFromString(key_str, &key);
-
- LLMenuItemCallGL *new_item;
- LLXMLNodePtr call_child;
-
- if (child->hasName(LL_MENU_ITEM_CHECK_GL_TAG))
- {
- std::string control_name;
- child->getAttributeString("control_name", control_name);
-
- new_item = new LLMenuItemCheckGL(item_name, item_label, 0, 0, control_name, parent, 0, key, mask);
-
- for (call_child = child->getFirstChild(); call_child.notNull(); call_child = call_child->getNextSibling())
- {
- if (call_child->hasName("on_check"))
- {
- std::string callback_name;
- std::string control_name;
- if (call_child->hasAttribute("function"))
- {
- call_child->getAttributeString("function", callback_name);
-
- control_name = callback_name;
-
- std::string callback_data = item_name;
- if (call_child->hasAttribute("userdata"))
- {
- call_child->getAttributeString("userdata", callback_data);
- if (!callback_data.empty())
- {
- control_name = llformat("%s(%s)", callback_name.c_str(), callback_data.c_str());
- }
- }
-
- LLSD userdata;
- userdata["control"] = control_name;
- userdata["data"] = callback_data;
-
- LLSimpleListener* callback = parent->getListenerByName(callback_name);
-
- if (!callback) continue;
-
- new_item->addListener(callback, "on_build", userdata);
- }
- else if (call_child->hasAttribute("control"))
- {
- call_child->getAttributeString("control", control_name);
- }
- else
- {
- continue;
- }
- LLControlVariable *control = parent->findControl(control_name);
- if (!control)
- {
- parent->addBoolControl(control_name, FALSE);
- }
- ((LLMenuItemCheckGL*)new_item)->setCheckedControl(control_name, parent);
- }
- }
- }
- else
- {
- new_item = new LLMenuItemCallGL(item_name, item_label, 0, 0, 0, 0, key, mask);
- }
-
- for (call_child = child->getFirstChild(); call_child.notNull(); call_child = call_child->getNextSibling())
- {
- if (call_child->hasName("on_click"))
- {
- std::string callback_name;
- call_child->getAttributeString("function", callback_name);
-
- std::string callback_data = item_name;
- if (call_child->hasAttribute("userdata"))
- {
- call_child->getAttributeString("userdata", callback_data);
- }
-
- LLSimpleListener* callback = parent->getListenerByName(callback_name);
-
- if (!callback) continue;
-
- new_item->addListener(callback, "on_click", callback_data);
- }
- if (call_child->hasName("on_enable"))
- {
- std::string callback_name;
- std::string control_name;
- if (call_child->hasAttribute("function"))
- {
- call_child->getAttributeString("function", callback_name);
-
- control_name = callback_name;
-
- std::string callback_data;
- if (call_child->hasAttribute("userdata"))
- {
- call_child->getAttributeString("userdata", callback_data);
- if (!callback_data.empty())
- {
- control_name = llformat("%s(%s)", callback_name.c_str(), callback_data.c_str());
- }
- }
-
- LLSD userdata;
- userdata["control"] = control_name;
- userdata["data"] = callback_data;
-
- LLSimpleListener* callback = parent->getListenerByName(callback_name);
-
- if (!callback) continue;
-
- new_item->addListener(callback, "on_build", userdata);
- }
- else if (call_child->hasAttribute("control"))
- {
- call_child->getAttributeString("control", control_name);
- }
- else
- {
- continue;
- }
- new_item->setEnabledControl(control_name, parent);
- }
- if (call_child->hasName("on_visible"))
- {
- std::string callback_name;
- std::string control_name;
- if (call_child->hasAttribute("function"))
- {
- call_child->getAttributeString("function", callback_name);
-
- control_name = callback_name;
-
- std::string callback_data;
- if (call_child->hasAttribute("userdata"))
- {
- call_child->getAttributeString("userdata", callback_data);
- if (!callback_data.empty())
- {
- control_name = llformat("%s(%s)", callback_name.c_str(), callback_data.c_str());
- }
- }
-
- LLSD userdata;
- userdata["control"] = control_name;
- userdata["data"] = callback_data;
-
- LLSimpleListener* callback = parent->getListenerByName(callback_name);
-
- if (!callback) continue;
-
- new_item->addListener(callback, "on_build", userdata);
- }
- else if (call_child->hasAttribute("control"))
- {
- call_child->getAttributeString("control", control_name);
- }
- else
- {
- continue;
- }
- new_item->setVisibleControl(control_name, parent);
- }
- }
- item = new_item;
- item->setLabel(item_label);
- if (jump_key != KEY_NONE)
- item->setJumpKey(jump_key);
- }
-
- if (item != NULL)
- {
- append(item);
- }
- }
- }
+BOOL LLMenuGL::postBuild()
+{
+ createJumpKeys();
+ return LLUICtrl::postBuild();
}
// are we the childmost active menu and hence our jump keys should be enabled?
@@ -2081,77 +1798,88 @@ BOOL LLMenuGL::isOpen()
return getVisible();
}
}
-// static
-LLView* LLMenuGL::fromXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFactory *factory)
-{
- std::string name("menu");
- node->getAttributeString("name", name);
-
- std::string label = name;
- node->getAttributeString("label", label);
-
- // parse jump key out of label
- std::string new_menu_label;
- typedef boost::tokenizer<boost::char_separator<char> > tokenizer;
- boost::char_separator<char> sep("_");
- tokenizer tokens(label, sep);
- tokenizer::iterator token_iter;
+void LLMenuGL::scrollItemsUp()
+{
+ // Slowing down the items scrolling when arrow button is held
+ if (mScrollItemsTimer.hasExpired() && NULL != mFirstVisibleItem)
+ {
+ mScrollItemsTimer.setTimerExpirySec(.033f);
+ }
+ else
+ {
+ return;
+ }
- KEY jump_key = KEY_NONE;
- S32 token_count = 0;
- for( token_iter = tokens.begin(); token_iter != tokens.end(); ++token_iter)
+ item_list_t::iterator cur_item_iter;
+ item_list_t::iterator prev_item_iter;
+ for (cur_item_iter = mItems.begin(), prev_item_iter = mItems.begin(); cur_item_iter != mItems.end(); cur_item_iter++)
{
- new_menu_label += (*token_iter);
- if (token_count > 0)
+ if( (*cur_item_iter) == mFirstVisibleItem)
{
- jump_key = (*token_iter).c_str()[0];
+ break;
+ }
+ if ((*cur_item_iter)->getVisible())
+ {
+ prev_item_iter = cur_item_iter;
}
- ++token_count;
}
- BOOL opaque = FALSE;
- node->getAttributeBOOL("opaque", opaque);
-
- LLMenuGL *menu = new LLMenuGL(name, new_menu_label);
-
- menu->setJumpKey(jump_key);
-
- BOOL tear_off = FALSE;
- node->getAttributeBOOL("tear_off", tear_off);
- menu->setCanTearOff(tear_off);
+ if ((*prev_item_iter)->getVisible())
+ {
+ mFirstVisibleItem = *prev_item_iter;
+ }
+
+ mNeedsArrange = TRUE;
+ arrangeAndClear();
+}
- if (node->hasAttribute("drop_shadow"))
+void LLMenuGL::scrollItemsDown()
+{
+ // Slowing down the items scrolling when arrow button is held
+ if (mScrollItemsTimer.hasExpired())
{
- BOOL drop_shadow = FALSE;
- node->getAttributeBOOL("drop_shadow", drop_shadow);
- menu->setDropShadowed(drop_shadow);
+ mScrollItemsTimer.setTimerExpirySec(.033f);
+ }
+ else
+ {
+ return;
+ }
+
+ if (NULL == mFirstVisibleItem)
+ {
+ mFirstVisibleItem = *mItems.begin();
}
- menu->setBackgroundVisible(opaque);
- LLColor4 color(0,0,0,1);
- if (opaque && LLUICtrlFactory::getAttributeColor(node,"color", color))
+ item_list_t::iterator cur_item_iter;
+
+ for (cur_item_iter = mItems.begin(); cur_item_iter != mItems.end(); cur_item_iter++)
{
- menu->setBackgroundColor(color);
+ if( (*cur_item_iter) == mFirstVisibleItem)
+ {
+ break;
+ }
}
- BOOL create_jump_keys = FALSE;
- node->getAttributeBOOL("create_jump_keys", create_jump_keys);
+ item_list_t::iterator next_item_iter;
- LLXMLNodePtr child;
- for (child = node->getFirstChild(); child.notNull(); child = child->getNextSibling())
+ for (next_item_iter = ++cur_item_iter; next_item_iter != mItems.end(); next_item_iter++)
{
- menu->parseChildXML(child, parent, factory);
+ if( (*next_item_iter)->getVisible())
+ {
+ break;
+ }
}
- if (create_jump_keys)
+ if ((*next_item_iter)->getVisible())
{
- menu->createJumpKeys();
+ mFirstVisibleItem = *next_item_iter;
}
- return menu;
+
+ mNeedsArrange = TRUE;
+ arrangeAndClear();
}
-
// rearrange the child rects so they fit the shape of the menu.
void LLMenuGL::arrange( void )
{
@@ -2169,11 +1897,27 @@ void LLMenuGL::arrange( void )
// torn off menus are not constrained to the size of the screen
U32 max_width = getTornOff() ? U32_MAX : menu_region_rect.getWidth();
- U32 max_height = getTornOff() ? U32_MAX : menu_region_rect.getHeight();
+ U32 max_height = U32_MAX;
+ if (!getTornOff())
+ {
+ max_height = getRect().mTop - menu_region_rect.mBottom;
+ if (menu_region_rect.mTop - getRect().mTop > (S32)max_height)
+ {
+ max_height = menu_region_rect.mTop - getRect().mTop;
+ }
+ }
+
// *FIX: create the item first and then ask for its dimensions?
- S32 spillover_item_width = PLAIN_PAD_PIXELS + LLFontGL::getFontSansSerif()->getWidth( std::string("More") );
+ S32 spillover_item_width = PLAIN_PAD_PIXELS + LLFontGL::getFontSansSerif()->getWidth( std::string("More") ); // *TODO: Translate
S32 spillover_item_height = llround(LLFontGL::getFontSansSerif()->getLineHeight()) + MENU_ITEM_PADDING;
+ // Scrolling support
+ item_list_t::iterator first_visible_item_iter;
+ item_list_t::iterator first_hidden_item_iter = mItems.end();
+ S32 height_before_first_visible_item = -1;
+ S32 visible_items_height = 0;
+ U32 scrollable_items_cnt = 0;
+
if (mHorizontalLayout)
{
item_list_t::iterator item_iter;
@@ -2182,26 +1926,27 @@ void LLMenuGL::arrange( void )
if ((*item_iter)->getVisible())
{
if (!getTornOff()
- && item_iter != mItems.begin() // Don't spillover the first item!
+ && *item_iter != mSpilloverBranch
&& width + (*item_iter)->getNominalWidth() > max_width - spillover_item_width)
{
// no room for any more items
createSpilloverBranch();
- item_list_t::iterator spillover_iter;
- for (spillover_iter = item_iter; spillover_iter != mItems.end(); ++spillover_iter)
+ std::vector<LLMenuItemGL*> items_to_remove;
+ std::copy(item_iter, mItems.end(), std::back_inserter(items_to_remove));
+ std::vector<LLMenuItemGL*>::iterator spillover_iter;
+ for (spillover_iter= items_to_remove.begin(); spillover_iter != items_to_remove.end(); ++spillover_iter)
{
LLMenuItemGL* itemp = (*spillover_iter);
removeChild(itemp);
- mSpilloverMenu->appendNoArrange(itemp); // *NOTE:Mani Favor addChild() in merge with skinning
+ mSpilloverMenu->addChild(itemp);
}
- mSpilloverMenu->arrange(); // *NOTE: Mani Remove line in merge with skinning/viewer2.0 branch
- mSpilloverMenu->updateParent(LLMenuGL::sMenuContainer); // *NOTE: Mani Remove line in merge with skinning/viewer2.0 branch
- mItems.erase(item_iter, mItems.end());
- mItems.push_back(mSpilloverBranch);
+
addChild(mSpilloverBranch);
+
height = llmax(height, mSpilloverBranch->getNominalHeight());
width += mSpilloverBranch->getNominalWidth();
+
break;
}
else
@@ -2216,31 +1961,35 @@ void LLMenuGL::arrange( void )
else
{
item_list_t::iterator item_iter;
+
for (item_iter = mItems.begin(); item_iter != mItems.end(); ++item_iter)
{
if ((*item_iter)->getVisible())
{
if (!getTornOff()
- && item_iter != mItems.begin() // Don't spillover the first item!
+ && !mScrollable
+ && *item_iter != mSpilloverBranch
&& height + (*item_iter)->getNominalHeight() > max_height - spillover_item_height)
{
// no room for any more items
createSpilloverBranch();
- item_list_t::iterator spillover_iter;
- for (spillover_iter= item_iter; spillover_iter != mItems.end(); ++spillover_iter)
+ std::vector<LLMenuItemGL*> items_to_remove;
+ std::copy(item_iter, mItems.end(), std::back_inserter(items_to_remove));
+ std::vector<LLMenuItemGL*>::iterator spillover_iter;
+ for (spillover_iter= items_to_remove.begin(); spillover_iter != items_to_remove.end(); ++spillover_iter)
{
LLMenuItemGL* itemp = (*spillover_iter);
removeChild(itemp);
- mSpilloverMenu->appendNoArrange(itemp); // *NOTE:Mani Favor addChild() in merge with skinning
+ mSpilloverMenu->addChild(itemp);
}
- mSpilloverMenu->arrange(); // *NOTE: Mani Remove line in merge with skinning/viewer2.0 branch
- mSpilloverMenu->updateParent(LLMenuGL::sMenuContainer); // *NOTE: Mani Remove line in merge with skinning/viewer2.0 branch
- mItems.erase(item_iter, mItems.end());
- mItems.push_back(mSpilloverBranch);
+
+
addChild(mSpilloverBranch);
+
height += mSpilloverBranch->getNominalHeight();
width = llmax( width, mSpilloverBranch->getNominalWidth() );
+
break;
}
else
@@ -2249,19 +1998,173 @@ void LLMenuGL::arrange( void )
height += (*item_iter)->getNominalHeight();
width = llmax( width, (*item_iter)->getNominalWidth() );
}
+
+ if (mScrollable)
+ {
+ // Determining visible items boundaries
+ if (NULL == mFirstVisibleItem)
+ {
+ mFirstVisibleItem = *item_iter;
+ }
+
+ if (*item_iter == mFirstVisibleItem)
+ {
+ height_before_first_visible_item = height - (*item_iter)->getNominalHeight();
+ first_visible_item_iter = item_iter;
+ scrollable_items_cnt = 0;
+ }
+
+ if (-1 != height_before_first_visible_item && 0 == visible_items_height &&
+ (++scrollable_items_cnt > mMaxScrollableItems ||
+ height - height_before_first_visible_item > max_height - spillover_item_height * 2 ))
+ {
+ first_hidden_item_iter = item_iter;
+ visible_items_height = height - height_before_first_visible_item - (*item_iter)->getNominalHeight();
+ scrollable_items_cnt--;
+ }
+ }
}
}
- }
- setRect(LLRect(getRect().mLeft, getRect().mBottom + height, getRect().mLeft + width, getRect().mBottom));
+ if (mPreferredWidth < U32_MAX)
+ width = llmin(mPreferredWidth, max_width);
+
+ if (mScrollable)
+ {
+ S32 max_items_height = max_height - spillover_item_height * 2;
+
+ if (visible_items_height == 0)
+ visible_items_height = height - height_before_first_visible_item;
+
+ // Fix mFirstVisibleItem value, if it doesn't allow to display all items, that can fit
+ if (visible_items_height < max_items_height && scrollable_items_cnt < mMaxScrollableItems)
+ {
+ item_list_t::iterator tmp_iter(first_visible_item_iter);
+ while (visible_items_height < max_items_height &&
+ scrollable_items_cnt < mMaxScrollableItems &&
+ first_visible_item_iter != mItems.begin())
+ {
+ if ((*first_visible_item_iter)->getVisible())
+ {
+ // It keeps visible item, after first_visible_item_iter
+ tmp_iter = first_visible_item_iter;
+ }
+
+ first_visible_item_iter--;
+
+ if ((*first_visible_item_iter)->getVisible())
+ {
+ visible_items_height += (*first_visible_item_iter)->getNominalHeight();
+ height_before_first_visible_item -= (*first_visible_item_iter)->getNominalHeight();
+ scrollable_items_cnt++;
+ }
+ }
+
+ // Roll back one item, that doesn't fit
+ if (visible_items_height > max_items_height)
+ {
+ visible_items_height -= (*first_visible_item_iter)->getNominalHeight();
+ height_before_first_visible_item += (*first_visible_item_iter)->getNominalHeight();
+ scrollable_items_cnt--;
+ first_visible_item_iter = tmp_iter;
+ }
+ if (!(*first_visible_item_iter)->getVisible())
+ {
+ first_visible_item_iter = tmp_iter;
+ }
+
+ mFirstVisibleItem = *first_visible_item_iter;
+ }
+ }
+ }
S32 cur_height = (S32)llmin(max_height, height);
+
+ if (mScrollable &&
+ (height_before_first_visible_item > MENU_ITEM_PADDING ||
+ height_before_first_visible_item + visible_items_height < (S32)height))
+ {
+ // Reserving 2 extra slots for arrow items
+ cur_height = visible_items_height + spillover_item_height * 2;
+ }
+
+ setRect(LLRect(getRect().mLeft, getRect().mTop, getRect().mLeft + width, getRect().mTop - cur_height));
+
S32 cur_width = 0;
+ S32 offset = 0;
+ if (mScrollable)
+ {
+ // No space for all items, creating arrow items
+ if (height_before_first_visible_item > MENU_ITEM_PADDING ||
+ height_before_first_visible_item + visible_items_height < (S32)height)
+ {
+ if (NULL == mArrowUpItem)
+ {
+ LLMenuScrollItem::Params item_params;
+ item_params.name(ARROW_UP);
+ item_params.arrow_type(LLMenuScrollItem::ARROW_UP);
+ item_params.scroll_callback.function(boost::bind(&LLMenuGL::scrollItemsUp, this));
+
+ mArrowUpItem = LLUICtrlFactory::create<LLMenuScrollItem>(item_params);
+ LLUICtrl::addChild(mArrowUpItem);
+
+ }
+ if (NULL == mArrowDownItem)
+ {
+ LLMenuScrollItem::Params item_params;
+ item_params.name(ARROW_DOWN);
+ item_params.arrow_type(LLMenuScrollItem::ARROW_DOWN);
+ item_params.scroll_callback.function(boost::bind(&LLMenuGL::scrollItemsDown, this));
+
+ mArrowDownItem = LLUICtrlFactory::create<LLMenuScrollItem>(item_params);
+ LLUICtrl::addChild(mArrowDownItem);
+ }
+
+ LLRect rect;
+ mArrowUpItem->setRect(rect.setLeftTopAndSize( 0, cur_height, width, mArrowUpItem->getNominalHeight()));
+ mArrowUpItem->setVisible(TRUE);
+ mArrowUpItem->setEnabled(height_before_first_visible_item > MENU_ITEM_PADDING);
+ mArrowUpItem->reshape(width, mArrowUpItem->getNominalHeight());
+ mArrowDownItem->setRect(rect.setLeftTopAndSize( 0, mArrowDownItem->getNominalHeight(), width, mArrowDownItem->getNominalHeight()));
+ mArrowDownItem->setVisible(TRUE);
+ mArrowDownItem->setEnabled(height_before_first_visible_item + visible_items_height < (S32)height);
+ mArrowDownItem->reshape(width, mArrowDownItem->getNominalHeight());
+
+ cur_height -= mArrowUpItem->getNominalHeight();
+
+ offset = menu_region_rect.mRight; // This moves items behind visible area
+ }
+ else
+ {
+ if (NULL != mArrowUpItem)
+ {
+ mArrowUpItem->setVisible(FALSE);
+ }
+ if (NULL != mArrowDownItem)
+ {
+ mArrowDownItem->setVisible(FALSE);
+ }
+ }
+
+ }
+
item_list_t::iterator item_iter;
for (item_iter = mItems.begin(); item_iter != mItems.end(); ++item_iter)
{
if ((*item_iter)->getVisible())
{
+ if (mScrollable)
+ {
+ if (item_iter == first_visible_item_iter)
+ {
+ offset = 0;
+ }
+ else if (item_iter == first_hidden_item_iter)
+ {
+ offset = menu_region_rect.mRight; // This moves items behind visible area
+ }
+ }
+
// setup item rect to hold label
LLRect rect;
if (mHorizontalLayout)
@@ -2271,8 +2174,11 @@ void LLMenuGL::arrange( void )
}
else
{
- rect.setLeftTopAndSize( 0, cur_height, width, (*item_iter)->getNominalHeight());
- cur_height -= (*item_iter)->getNominalHeight();
+ rect.setLeftTopAndSize( 0 + offset, cur_height, width, (*item_iter)->getNominalHeight());
+ if (offset == 0)
+ {
+ cur_height -= (*item_iter)->getNominalHeight();
+ }
}
(*item_iter)->setRect( rect );
(*item_iter)->buildDrawLabel();
@@ -2285,6 +2191,15 @@ void LLMenuGL::arrange( void )
}
}
+void LLMenuGL::arrangeAndClear( void )
+{
+ if (mNeedsArrange)
+ {
+ arrange();
+ mNeedsArrange = FALSE;
+ }
+}
+
void LLMenuGL::createSpilloverBranch()
{
if (!mSpilloverBranch)
@@ -2293,14 +2208,24 @@ void LLMenuGL::createSpilloverBranch()
delete mSpilloverMenu;
// technically, you can't tear off spillover menus, but we're passing the handle
// along just to be safe
- mSpilloverMenu = new LLMenuGL(std::string("More"), std::string("More"), mParentFloaterHandle);
+ LLMenuGL::Params p;
+ p.name("More");
+ p.label("More"); // *TODO: Translate
+ p.parent_floater(mParentFloaterHandle);
+ p.bg_color(mBackgroundColor);
+ p.bg_visible(true);
+ p.can_tear_off(false);
+ mSpilloverMenu = new LLMenuGL(p);
mSpilloverMenu->updateParent(LLMenuGL::sMenuContainer);
- // Inherit colors
- mSpilloverMenu->setBackgroundColor( mBackgroundColor );
- mSpilloverMenu->setCanTearOff(FALSE);
- mSpilloverBranch = new LLMenuItemBranchGL(std::string("More"), std::string("More"), mSpilloverMenu->getHandle());
- mSpilloverBranch->setFontStyle(LLFontGL::ITALIC);
+ LLMenuItemBranchGL::Params branch_params;
+ branch_params.name = "More";
+ branch_params.label = "More"; // *TODO: Translate
+ branch_params.branch = mSpilloverMenu;
+ branch_params.font.style = "italic";
+
+
+ mSpilloverBranch = LLUICtrlFactory::create<LLMenuItemBranchGL>(branch_params);
}
}
@@ -2311,25 +2236,15 @@ void LLMenuGL::cleanupSpilloverBranch()
// head-recursion to propagate items back up to root menu
mSpilloverMenu->cleanupSpilloverBranch();
- removeChild(mSpilloverBranch);
-
- item_list_t::iterator found_iter = std::find(mItems.begin(), mItems.end(), mSpilloverBranch);
- if (found_iter != mItems.end())
- {
- mItems.erase(found_iter);
- }
-
// pop off spillover items
while (mSpilloverMenu->getItemCount())
{
LLMenuItemGL* itemp = mSpilloverMenu->getItem(0);
mSpilloverMenu->removeChild(itemp);
- mSpilloverMenu->mItems.erase(mSpilloverMenu->mItems.begin());
// put them at the end of our own list
- mItems.push_back(itemp);
addChild(itemp);
}
-
+
// Delete the branch, and since the branch will delete the menu,
// set the menu* to null.
delete mSpilloverBranch;
@@ -2340,6 +2255,9 @@ void LLMenuGL::cleanupSpilloverBranch()
void LLMenuGL::createJumpKeys()
{
+ if (!mCreateJumpKeys) return;
+ mCreateJumpKeys = FALSE;
+
mJumpKeys.clear();
std::set<std::string> unique_words;
@@ -2440,16 +2358,18 @@ void LLMenuGL::empty( void )
cleanupSpilloverBranch();
mItems.clear();
+ mFirstVisibleItem = NULL;
+ mArrowUpItem = NULL;
+ mArrowDownItem = NULL;
deleteAllChildren();
-
}
// Adjust rectangle of the menu
void LLMenuGL::setLeftAndBottom(S32 left, S32 bottom)
{
setRect(LLRect(left, getRect().mTop, getRect().mRight, bottom));
- arrange();
+ needsArrange();
}
BOOL LLMenuGL::handleJumpKey(KEY key)
@@ -2462,12 +2382,9 @@ BOOL LLMenuGL::handleJumpKey(KEY key)
// switch to keyboard navigation mode
LLMenuGL::setKeyboardMode(TRUE);
- // force highlight to close old menus and any open sub-menus
-
- //clearHoverItem();
// force highlight to close old menus and open and sub-menus
found_it->second->setHighlight(TRUE);
- found_it->second->doIt();
+ found_it->second->onCommit();
}
// if we are navigating the menus, we need to eat the keystroke
@@ -2479,30 +2396,18 @@ BOOL LLMenuGL::handleJumpKey(KEY key)
// Add the menu item to this menu.
BOOL LLMenuGL::append( LLMenuItemGL* item )
{
+ if (!item) return FALSE;
mItems.push_back( item );
- addChild( item );
- arrange();
- return TRUE;
-}
-
-// *NOTE:Mani - appendNoArrange() should be removed when merging to skinning/viewer2.0
-// Its added as a fix to a viewer 1.23 bug that has already been address by skinning work.
-BOOL LLMenuGL::appendNoArrange( LLMenuItemGL* item )
-{
- mItems.push_back( item );
- addChild( item );
+ LLUICtrl::addChild(item);
+ needsArrange();
return TRUE;
}
// add a separator to this menu
-BOOL LLMenuGL::appendSeparator( const std::string &separator_name )
+BOOL LLMenuGL::addSeparator()
{
- LLMenuItemGL* separator;
- if (separator_name.empty())
- separator = new LLMenuItemSeparatorGL(std::string("separator"));
- else
- separator = new LLMenuItemSeparatorGL(separator_name);
- return append( separator );
+ LLMenuItemGL* separator = new LLMenuItemSeparatorGL();
+ return addChild(separator);
}
// add a menu - this will create a cascading menu
@@ -2515,14 +2420,22 @@ BOOL LLMenuGL::appendMenu( LLMenuGL* menu )
}
BOOL success = TRUE;
- LLMenuItemBranchGL* branch = NULL;
- branch = new LLMenuItemBranchGL( menu->getName(), menu->getLabel(), menu->getHandle() );
- branch->setJumpKey(menu->getJumpKey());
+ LLMenuItemBranchGL::Params p;
+ p.name = menu->getName();
+ p.label = menu->getLabel();
+ p.branch = menu;
+ p.jump_key = menu->getJumpKey();
+ p.enabled_color=LLUIColorTable::instance().getColor("MenuItemEnabledColor");
+ p.disabled_color=LLUIColorTable::instance().getColor("MenuItemDisabledColor");
+ p.highlight_bg_color=LLUIColorTable::instance().getColor("MenuItemHighlightBgColor");
+ p.highlight_fg_color=LLUIColorTable::instance().getColor("MenuItemHighlightFgColor");
+
+ LLMenuItemBranchGL* branch = LLUICtrlFactory::create<LLMenuItemBranchGL>(p);
success &= append( branch );
// Inherit colors
menu->setBackgroundColor( mBackgroundColor );
-
+ menu->updateParent(LLMenuGL::sMenuContainer);
return success;
}
@@ -2560,6 +2473,7 @@ void LLMenuGL::setItemVisible( const std::string& name, BOOL visible )
if( (*item_iter)->getName() == name )
{
(*item_iter)->setVisible( visible );
+ needsArrange();
break;
}
}
@@ -2572,7 +2486,7 @@ void LLMenuGL::setItemLastSelected(LLMenuItemGL* item)
LLMenuHolderGL::setActivatedItem(item);
}
- // fix the checkmarks
+ // update enabled and checkmark status
item->buildDrawLabel();
}
@@ -2670,7 +2584,7 @@ LLMenuItemGL* LLMenuGL::highlightNextItem(LLMenuItemGL* cur_item, BOOL skip_disa
while(1)
{
// skip separators and disabled/invisible items
- if ((*next_item_iter)->getEnabled() && (*next_item_iter)->getVisible() && (*next_item_iter)->getType() != SEPARATOR_NAME)
+ if ((*next_item_iter)->getEnabled() && (*next_item_iter)->getVisible() && !dynamic_cast<LLMenuItemSeparatorGL*>(*next_item_iter))
{
if (cur_item)
{
@@ -2777,7 +2691,10 @@ void LLMenuGL::updateParent(LLView* parentp)
{
getParent()->removeChild(this);
}
- parentp->addChild(this);
+ if (parentp)
+ {
+ parentp->addChild(this);
+ }
item_list_t::iterator item_iter;
for (item_iter = mItems.begin(); item_iter != mItems.end(); ++item_iter)
{
@@ -2880,29 +2797,59 @@ BOOL LLMenuGL::handleHover( S32 x, S32 y, MASK mask )
}
}
getWindow()->setCursor(UI_CURSOR_ARROW);
+
+ // *HACK Release the mouse capture
+ // This is done to release the mouse after the Navigation Bar "Back" or "Forward" button
+ // drop-down menu is shown. Otherwise any other view won't be able to handle mouse events
+ // until the user chooses one of the drop-down menu items.
+
+ return TRUE;
+}
+
+BOOL LLMenuGL::handleScrollWheel( S32 x, S32 y, S32 clicks )
+{
+ if (!mScrollable)
+ return blockMouseEvent(x, y);
+
+ if( clicks > 0 )
+ {
+ while( clicks-- )
+ scrollItemsDown();
+ }
+ else
+ {
+ while( clicks++ )
+ scrollItemsUp();
+ }
+
return TRUE;
}
void LLMenuGL::draw( void )
{
+ if (mNeedsArrange)
+ {
+ arrange();
+ mNeedsArrange = FALSE;
+ }
if (mDropShadowed && !mTornOff)
{
+ static LLUICachedControl<S32> drop_shadow_floater ("DropShadowFloater", 0);
+ static LLUIColor color_drop_shadow = LLUIColorTable::instance().getColor("ColorDropShadow");
gl_drop_shadow(0, getRect().getHeight(), getRect().getWidth(), 0,
- LLUI::sColorsGroup->getColor("ColorDropShadow"),
- LLUI::sConfigGroup->getS32("DropShadowFloater") );
+ color_drop_shadow, drop_shadow_floater );
}
- LLColor4 bg_color = mBackgroundColor;
-
if( mBgVisible )
{
- gl_rect_2d( 0, getRect().getHeight(), getRect().getWidth(), 0, mBackgroundColor );
+ gl_rect_2d( 0, getRect().getHeight(), getRect().getWidth(), 0, mBackgroundColor.get() );
}
LLView::draw();
}
-void LLMenuGL::drawBackground(LLMenuItemGL* itemp, LLColor4& color)
+void LLMenuGL::drawBackground(LLMenuItemGL* itemp, F32 alpha)
{
+ LLColor4 color = itemp->getHighlightBgColor() % alpha;
gGL.color4fv( color.mV );
LLRect item_rect = itemp->getRect();
gl_rect_2d( 0, item_rect.getHeight(), item_rect.getWidth(), 0);
@@ -2931,9 +2878,9 @@ void LLMenuGL::setVisible(BOOL visible)
}
}
-LLMenuGL* LLMenuGL::getChildMenuByName(const std::string& name, BOOL recurse) const
+LLMenuGL* LLMenuGL::findChildMenuByName(const std::string& name, BOOL recurse) const
{
- LLView* view = getChildView(name, recurse, FALSE);
+ LLView* view = findChildView(name, recurse);
if (view)
{
LLMenuItemBranchGL* branch = dynamic_cast<LLMenuItemBranchGL*>(view);
@@ -2972,9 +2919,19 @@ void hide_top_view( LLView* view )
}
+// x and y are the desired location for the popup, NOT necessarily the
+// mouse location
// static
void LLMenuGL::showPopup(LLView* spawning_view, LLMenuGL* menu, S32 x, S32 y)
{
+ // Save click point for detecting cursor moves before mouse-up.
+ // Must be in local coords to compare with mouseUp events.
+ // If the mouse doesn't move, the menu will stay open ala the Mac.
+ // See also LLContextMenu::show()
+ S32 mouse_x, mouse_y;
+ LLUI::getCursorPositionLocal(menu->getParent(), &mouse_x, &mouse_y);
+ LLMenuHolderGL::sContextMenuSpawnPos.set(mouse_x,mouse_y);
+
const LLRect menu_region_rect = LLMenuGL::sMenuContainer->getMenuRect();
const S32 HPAD = 2;
@@ -2985,23 +2942,27 @@ void LLMenuGL::showPopup(LLView* spawning_view, LLMenuGL* menu, S32 x, S32 y)
spawning_view->localPointToOtherView(left, top, &left, &top, menu->getParent());
rect.setLeftTopAndSize( left, top,
rect.getWidth(), rect.getHeight() );
-
-
- //rect.setLeftTopAndSize(x + HPAD, y, rect.getWidth(), rect.getHeight());
menu->setRect( rect );
+ // Resetting scrolling position
+ if (menu->isScrollable())
+ {
+ menu->mFirstVisibleItem = NULL;
+ menu->needsArrange();
+ }
+ menu->arrangeAndClear(); // Fix menu rect if needed.
+ rect = menu->getRect();
+
+ // Adjust context menu to fit onscreen
S32 bottom;
left = rect.mLeft;
bottom = rect.mBottom;
- //menu->getParent()->localPointToScreen( rect.mLeft, rect.mBottom,
- // &left, &bottom );
S32 delta_x = 0;
S32 delta_y = 0;
if( bottom < menu_region_rect.mBottom )
{
// At this point, we need to move the context menu to the
// other side of the mouse.
- //delta_y = menu_region_rect.mBottom - bottom;
delta_y = (rect.getHeight() + 2 * HPAD);
}
@@ -3009,7 +2970,6 @@ void LLMenuGL::showPopup(LLView* spawning_view, LLMenuGL* menu, S32 x, S32 y)
{
// At this point, we need to move the context menu to the
// other side of the mouse.
- //delta_x = (window_width - rect.getWidth()) - x;
delta_x = -(rect.getWidth() + 2 * HPAD);
}
menu->translate( delta_x, delta_y );
@@ -3017,794 +2977,16 @@ void LLMenuGL::showPopup(LLView* spawning_view, LLMenuGL* menu, S32 x, S32 y)
menu->getParent()->sendChildToFront(menu);
}
-//-----------------------------------------------------------------------------
-// class LLPieMenuBranch
-// A branch to another pie menu
-//-----------------------------------------------------------------------------
-class LLPieMenuBranch : public LLMenuItemGL
-{
-public:
- LLPieMenuBranch(const std::string& name, const std::string& label, LLPieMenu* branch);
-
- // called to rebuild the draw label
- virtual void buildDrawLabel( void );
-
- // doIt() - do the primary funcationality of the menu item.
- virtual void doIt( void );
-
- LLPieMenu* getBranch() { return mBranch; }
-
-protected:
- LLPieMenu* mBranch;
-};
-
-LLPieMenuBranch::LLPieMenuBranch(const std::string& name,
- const std::string& label,
- LLPieMenu* branch)
-: LLMenuItemGL( name, label, KEY_NONE, MASK_NONE ),
- mBranch( branch )
-{
- mBranch->hide(FALSE);
- mBranch->setParentMenuItem(this);
-}
-
-// called to rebuild the draw label
-void LLPieMenuBranch::buildDrawLabel( void )
-{
- {
- // default enablement is this -- if any of the subitems are
- // enabled, this item is enabled. JC
- U32 sub_count = mBranch->getItemCount();
- U32 i;
- BOOL any_enabled = FALSE;
- for (i = 0; i < sub_count; i++)
- {
- LLMenuItemGL* item = mBranch->getItem(i);
- item->buildDrawLabel();
- if (item->getEnabled() && !item->getDrawTextDisabled() )
- {
- any_enabled = TRUE;
- break;
- }
- }
- setDrawTextDisabled(!any_enabled);
- setEnabled(TRUE);
- }
-
- mDrawAccelLabel.clear();
- std::string st = mDrawAccelLabel;
- appendAcceleratorString( st );
- mDrawAccelLabel = st;
-
- // No special branch suffix
- mDrawBranchLabel.clear();
-}
-
-// doIt() - do the primary funcationality of the menu item.
-void LLPieMenuBranch::doIt( void )
-{
- LLPieMenu *parent = (LLPieMenu *)getParent();
-
- LLRect rect = parent->getRect();
- S32 center_x;
- S32 center_y;
- parent->localPointToScreen(rect.getWidth() / 2, rect.getHeight() / 2, &center_x, &center_y);
-
- parent->hide(FALSE);
- mBranch->show( center_x, center_y, FALSE );
-}
-
-//-----------------------------------------------------------------------------
-// class LLPieMenu
-// A circular menu of items, icons, etc.
-//-----------------------------------------------------------------------------
-LLPieMenu::LLPieMenu(const std::string& name, const std::string& label)
-: LLMenuGL(name, label),
- mFirstMouseDown(FALSE),
- mUseInfiniteRadius(FALSE),
- mHoverItem(NULL),
- mHoverThisFrame(FALSE),
- mHoveredAnyItem(FALSE),
- mOuterRingAlpha(1.f),
- mCurRadius(0.f),
- mRightMouseDown(FALSE)
-{
- LLMenuGL::setVisible(FALSE);
- setCanTearOff(FALSE);
-}
-
-LLPieMenu::LLPieMenu(const std::string& name)
-: LLMenuGL(name, name),
- mFirstMouseDown(FALSE),
- mUseInfiniteRadius(FALSE),
- mHoverItem(NULL),
- mHoverThisFrame(FALSE),
- mHoveredAnyItem(FALSE),
- mOuterRingAlpha(1.f),
- mCurRadius(0.f),
- mRightMouseDown(FALSE)
-{
- LLMenuGL::setVisible(FALSE);
- setCanTearOff(FALSE);
-}
-
-
-void LLPieMenu::initXML(LLXMLNodePtr node, LLView *context, LLUICtrlFactory *factory)
-{
- LLXMLNodePtr child;
- for (child = node->getFirstChild(); child.notNull(); child = child->getNextSibling())
- {
- if (child->hasName(LL_PIE_MENU_TAG))
- {
- // SUBMENU
- std::string name("menu");
- child->getAttributeString("name", name);
- std::string label(name);
- child->getAttributeString("label", label);
-
- LLPieMenu *submenu = new LLPieMenu(name, label);
- appendPieMenu(submenu);
- submenu->initXML(child, context, factory);
- }
- else
- {
- parseChildXML(child, context, factory);
- }
- }
-}
-
-// virtual
-void LLPieMenu::setVisible(BOOL visible)
-{
- if (!visible)
- {
- hide(FALSE);
- }
-}
-
-BOOL LLPieMenu::handleHover( S32 x, S32 y, MASK mask )
-{
- // This is mostly copied from the llview class, but it continues
- // the hover handle code after a hover handler has been found.
- BOOL handled = FALSE;
-
- // If we got a hover event, we've already moved the cursor
- // for any menu shifts, so subsequent mouseup messages will be in the
- // correct position. No need to correct them.
- //mShiftHoriz = 0;
- //mShiftVert = 0;
-
- // release mouse capture after short period of visibility if we're using a finite boundary
- // so that right click outside of boundary will trigger new pie menu
- if (hasMouseCapture() &&
- !mRightMouseDown &&
- mShrinkBorderTimer.getStarted() &&
- mShrinkBorderTimer.getElapsedTimeF32() >= PIE_SHRINK_TIME)
- {
- gFocusMgr.setMouseCapture(NULL);
- mUseInfiniteRadius = FALSE;
- }
-
- LLMenuItemGL *item = pieItemFromXY( x, y );
-
- if (item && item->getEnabled())
- {
- getWindow()->setCursor(UI_CURSOR_ARROW);
- lldebugst(LLERR_USER_INPUT) << "hover handled by " << getName() << llendl;
- handled = TRUE;
-
- if (item != mHoverItem)
- {
- if (mHoverItem)
- {
- mHoverItem->setHighlight( FALSE );
- }
- mHoverItem = item;
- mHoverItem->setHighlight( TRUE );
-
- switch(pieItemIndexFromXY(x, y))
- {
- case 0:
- make_ui_sound("UISndPieMenuSliceHighlight0");
- break;
- case 1:
- make_ui_sound("UISndPieMenuSliceHighlight1");
- break;
- case 2:
- make_ui_sound("UISndPieMenuSliceHighlight2");
- break;
- case 3:
- make_ui_sound("UISndPieMenuSliceHighlight3");
- break;
- case 4:
- make_ui_sound("UISndPieMenuSliceHighlight4");
- break;
- case 5:
- make_ui_sound("UISndPieMenuSliceHighlight5");
- break;
- case 6:
- make_ui_sound("UISndPieMenuSliceHighlight6");
- break;
- case 7:
- make_ui_sound("UISndPieMenuSliceHighlight7");
- break;
- default:
- make_ui_sound("UISndPieMenuSliceHighlight0");
- break;
- }
- }
- mHoveredAnyItem = TRUE;
- }
- else
- {
- // clear out our selection
- if (mHoverItem)
- {
- mHoverItem->setHighlight(FALSE);
- mHoverItem = NULL;
- }
- }
-
- if( !handled && pointInView( x, y ) )
- {
- getWindow()->setCursor(UI_CURSOR_ARROW);
- lldebugst(LLERR_USER_INPUT) << "hover handled by " << getName() << llendl;
- handled = TRUE;
- }
-
- mHoverThisFrame = TRUE;
-
- return handled;
-}
-
-BOOL LLPieMenu::handleMouseDown( S32 x, S32 y, MASK mask )
-{
- BOOL handled = FALSE;
- // The click was somewhere within our rectangle
- LLMenuItemGL *item = pieItemFromXY( x, y );
-
- if (item)
- {
- // lie to the item about where the click happened
- // to make sure it's within the item's rectangle
- handled = item->handleMouseDown( 0, 0, mask );
- }
- else if (!mRightMouseDown)
- {
- // call hidemenus to make sure transient selections get cleared
- ((LLMenuHolderGL*)getParent())->hideMenus();
- }
-
- // always handle mouse down as mouse up will close open menus
- return handled;
-}
-
-BOOL LLPieMenu::handleRightMouseDown(S32 x, S32 y, MASK mask)
-{
- BOOL handled = FALSE;
-
- mRightMouseDown = TRUE;
-
- // The click was somewhere within our rectangle
- LLMenuItemGL *item = pieItemFromXY( x, y );
- S32 delta_x = x /*+ mShiftHoriz*/ - getLocalRect().getCenterX();
- S32 delta_y = y /*+ mShiftVert*/ - getLocalRect().getCenterY();
- BOOL clicked_in_pie = ((delta_x * delta_x) + (delta_y * delta_y) < mCurRadius*mCurRadius) || mUseInfiniteRadius;
-
- // grab mouse if right clicking anywhere within pie (even deadzone in middle), to detect drag outside of pie
- if (clicked_in_pie)
- {
- // capture mouse cursor as if on initial menu show
- gFocusMgr.setMouseCapture(this);
- mShrinkBorderTimer.stop();
- mUseInfiniteRadius = TRUE;
- handled = TRUE;
- }
-
- if (item)
- {
- // lie to the item about where the click happened
- // to make sure it's within the item's rectangle
- if (item->handleMouseDown( 0, 0, mask ))
- {
- handled = TRUE;
- }
- }
-
- return handled;
-}
-
-BOOL LLPieMenu::handleRightMouseUp( S32 x, S32 y, MASK mask )
-{
- // release mouse capture when right mouse button released, and we're past the shrink time
- if (mShrinkBorderTimer.getStarted() &&
- mShrinkBorderTimer.getElapsedTimeF32() > PIE_SHRINK_TIME)
- {
- mUseInfiniteRadius = FALSE;
- gFocusMgr.setMouseCapture(NULL);
- }
-
- S32 delta_x = x /*+ mShiftHoriz*/ - getLocalRect().getCenterX();
- S32 delta_y = y /*+ mShiftVert*/ - getLocalRect().getCenterY();
- if (!mHoveredAnyItem && !mFirstMouseDown && (delta_x * delta_x) + (delta_y * delta_y) < PIE_CENTER_SIZE * PIE_CENTER_SIZE)
- {
- // user released right mouse button in middle of pie, interpret this as closing the menu
- sMenuContainer->hideMenus();
- return TRUE;
- }
-
-
- BOOL result = handleMouseUp( x, y, mask );
- mRightMouseDown = FALSE;
- mHoveredAnyItem = FALSE;
-
- return result;
-}
-
-BOOL LLPieMenu::handleMouseUp( S32 x, S32 y, MASK mask )
-{
- BOOL handled = FALSE;
-
- // The click was somewhere within our rectangle
- LLMenuItemGL *item = pieItemFromXY( x, y );
-
- if (item)
- {
- // lie to the item about where the click happened
- // to make sure it's within the item's rectangle
- if (item->getEnabled())
- {
- handled = item->handleMouseUp( 0, 0, mask );
- hide(TRUE);
- }
- }
- else if (!mRightMouseDown)
- {
- // call hidemenus to make sure transient selections get cleared
- ((LLMenuHolderGL*)getParent())->hideMenus();
- }
-
- if (handled)
- {
- make_ui_sound("UISndClickRelease");
- }
-
- if (!handled && !mUseInfiniteRadius)
- {
- // call hidemenus to make sure transient selections get cleared
- sMenuContainer->hideMenus();
- }
-
- if (mFirstMouseDown)
- {
- make_ui_sound("UISndPieMenuAppear");
- mFirstMouseDown = FALSE;
- }
-
- // *FIX: is this necessary?
- if (!mShrinkBorderTimer.getStarted())
- {
- mShrinkBorderTimer.start();
- }
-
- return handled;
-}
-
-
-// virtual
-void LLPieMenu::draw()
-{
- // clear hover if mouse moved away
- if (!mHoverThisFrame && mHoverItem)
- {
- mHoverItem->setHighlight(FALSE);
- mHoverItem = NULL;
- }
-
- F32 width = (F32) getRect().getWidth();
- F32 height = (F32) getRect().getHeight();
- mCurRadius = PIE_SCALE_FACTOR * llmax( width/2, height/2 );
-
- mOuterRingAlpha = mUseInfiniteRadius ? 0.f : 1.f;
- if (mShrinkBorderTimer.getStarted())
- {
- mOuterRingAlpha = clamp_rescale(mShrinkBorderTimer.getElapsedTimeF32(), 0.f, PIE_SHRINK_TIME, 0.f, 1.f);
- mCurRadius *= clamp_rescale(mShrinkBorderTimer.getElapsedTimeF32(), 0.f, PIE_SHRINK_TIME, 1.f, 1.f / PIE_SCALE_FACTOR);
- }
-
- // correct for non-square pixels
- F32 center_x = width/2;
- F32 center_y = height/2;
- S32 steps = 100;
-
- gGL.pushMatrix();
- {
- gGL.translatef(center_x, center_y, 0.f);
-
- F32 line_width = LLUI::sConfigGroup->getF32("PieMenuLineWidth");
- LLColor4 line_color = LLUI::sColorsGroup->getColor("PieMenuLineColor");
- LLColor4 bg_color = LLUI::sColorsGroup->getColor("PieMenuBgColor");
- LLColor4 selected_color = LLUI::sColorsGroup->getColor("PieMenuSelectedColor");
-
- // main body
- LLColor4 outer_color = bg_color;
- outer_color.mV[VALPHA] *= mOuterRingAlpha;
- gl_washer_2d( mCurRadius, (F32) PIE_CENTER_SIZE, steps, bg_color, outer_color );
-
- // selected wedge
- item_list_t::iterator item_iter;
- S32 i = 0;
- for (item_iter = mItems.begin(); item_iter != mItems.end(); ++item_iter)
- {
- if ((*item_iter)->getHighlight())
- {
- F32 arc_size = F_PI * 0.25f;
-
- F32 start_radians = (i * arc_size) - (arc_size * 0.5f);
- F32 end_radians = start_radians + arc_size;
-
- LLColor4 outer_color = selected_color;
- outer_color.mV[VALPHA] *= mOuterRingAlpha;
- gl_washer_segment_2d( mCurRadius, (F32)PIE_CENTER_SIZE, start_radians, end_radians, steps / 8, selected_color, outer_color );
- }
- i++;
- }
-
- LLUI::setLineWidth( line_width );
-
- // inner lines
- outer_color = line_color;
- outer_color.mV[VALPHA] *= mOuterRingAlpha;
- gl_washer_spokes_2d( mCurRadius, (F32)PIE_CENTER_SIZE, 8, line_color, outer_color );
-
- // inner circle
- gGL.color4fv( line_color.mV );
- gl_circle_2d( 0, 0, (F32)PIE_CENTER_SIZE, steps, FALSE );
-
- // outer circle
- gGL.color4fv( outer_color.mV );
- gl_circle_2d( 0, 0, mCurRadius, steps, FALSE );
-
- LLUI::setLineWidth(1.0f);
- }
- gGL.popMatrix();
-
- mHoverThisFrame = FALSE;
-
- LLView::draw();
-}
-
-void LLPieMenu::drawBackground(LLMenuItemGL* itemp, LLColor4& color)
-{
- F32 width = (F32) getRect().getWidth();
- F32 height = (F32) getRect().getHeight();
- F32 center_x = width/2;
- F32 center_y = height/2;
- S32 steps = 100;
-
- gGL.color4fv( color.mV );
- gGL.pushMatrix();
- {
- gGL.translatef(center_x - itemp->getRect().mLeft, center_y - itemp->getRect().mBottom, 0.f);
-
- item_list_t::iterator item_iter;
- S32 i = 0;
- for (item_iter = mItems.begin(); item_iter != mItems.end(); ++item_iter)
- {
- if ((*item_iter) == itemp)
- {
- F32 arc_size = F_PI * 0.25f;
-
- F32 start_radians = (i * arc_size) - (arc_size * 0.5f);
- F32 end_radians = start_radians + arc_size;
-
- LLColor4 outer_color = color;
- outer_color.mV[VALPHA] *= mOuterRingAlpha;
- gl_washer_segment_2d( mCurRadius, (F32)PIE_CENTER_SIZE, start_radians, end_radians, steps / 8, color, outer_color );
- }
- i++;
- }
- }
- gGL.popMatrix();
-}
-
-// virtual
-BOOL LLPieMenu::append(LLMenuItemGL *item)
-{
- item->setBriefItem(TRUE);
- item->setFont( LLFontGL::getFontSansSerifSmall() );
- return LLMenuGL::append(item);
-}
-
-// virtual
-BOOL LLPieMenu::appendSeparator(const std::string &separator_name)
-{
- LLMenuItemGL* separator = new LLMenuItemBlankGL();
- separator->setFont( LLFontGL::getFontSansSerifSmall() );
- return append( separator );
-}
-
-
-BOOL LLPieMenu::appendPieMenu(LLPieMenu *menu)
-{
- if (menu == this)
- {
- llerrs << "Can't attach a pie menu to itself" << llendl;
- }
- LLPieMenuBranch *item;
- item = new LLPieMenuBranch(menu->getName(), menu->getLabel(), menu);
- getParent()->addChild(item->getBranch());
- item->setFont( LLFontGL::getFontSansSerifSmall() );
- return append( item );
-}
-
-// virtual
-void LLPieMenu::arrange()
-{
- const S32 rect_height = 190;
- const S32 rect_width = 190;
-
- // all divide by 6
- const S32 CARD_X = 60;
- const S32 DIAG_X = 48;
- const S32 CARD_Y = 76;
- const S32 DIAG_Y = 42;
-
- const S32 ITEM_CENTER_X[] = { CARD_X, DIAG_X, 0, -DIAG_X, -CARD_X, -DIAG_X, 0, DIAG_X };
- const S32 ITEM_CENTER_Y[] = { 0, DIAG_Y, CARD_Y, DIAG_Y, 0, -DIAG_Y, -CARD_Y, -DIAG_Y };
-
- LLRect rect;
-
- S32 font_height = 0;
- if( mItems.size() )
- {
- font_height = (*mItems.begin())->getNominalHeight();
- }
- S32 item_width = 0;
-
-// F32 sin_delta = OO_SQRT2; // sin(45 deg)
-// F32 cos_delta = OO_SQRT2; // cos(45 deg)
-
- // TODO: Compute actual bounding rect for menu
-
- // HACK: casting away const. Should use setRect or some helper function instead.
- const_cast<LLRect&>(getRect()).setOriginAndSize(getRect().mLeft, getRect().mBottom, rect_width, rect_height );
-
- // place items around a circle, with item 0 at positive X,
- // rotating counter-clockwise
- item_list_t::iterator item_iter;
- S32 i = 0;
- for (item_iter = mItems.begin(); item_iter != mItems.end(); ++item_iter)
- {
- LLMenuItemGL *item = *item_iter;
-
- item_width = item->getNominalWidth();
-
- // Put in the right place around a circle centered at 0,0
- rect.setCenterAndSize(ITEM_CENTER_X[i],
- ITEM_CENTER_Y[i],
- item_width, font_height );
-
- // Correct for the actual rectangle size
- rect.translate( rect_width/2, rect_height/2 );
-
- item->setRect( rect );
-
- // Make sure enablement is correct
- item->buildDrawLabel();
- i++;
- }
-}
-
-LLMenuItemGL *LLPieMenu::pieItemFromXY(S32 x, S32 y)
-{
- // We might have shifted this menu on draw. If so, we need
- // to shift over mouseup events until we get a hover event.
- //x += mShiftHoriz;
- //y += mShiftVert;
-
- // An arc of the pie menu is 45 degrees
- const F32 ARC_DEG = 45.f;
- S32 delta_x = x - getRect().getWidth() / 2;
- S32 delta_y = y - getRect().getHeight() / 2;
-
- // circle safe zone in the center
- S32 dist_squared = delta_x*delta_x + delta_y*delta_y;
- if (dist_squared < PIE_CENTER_SIZE*PIE_CENTER_SIZE)
- {
- return NULL;
- }
-
- // infinite radius is only used with right clicks
- S32 radius = llmax( getRect().getWidth()/2, getRect().getHeight()/2 );
- if (!(mUseInfiniteRadius && mRightMouseDown) && dist_squared > radius * radius)
- {
- return NULL;
- }
-
- F32 angle = RAD_TO_DEG * (F32) atan2((F32)delta_y, (F32)delta_x);
-
- // rotate marks CCW so that east = [0, ARC_DEG) instead of
- // [-ARC_DEG/2, ARC_DEG/2)
- angle += ARC_DEG / 2.f;
-
- // make sure we're only using positive angles
- if (angle < 0.f) angle += 360.f;
-
- S32 which = S32( angle / ARC_DEG );
-
- if (0 <= which && which < (S32)mItems.size() )
- {
- item_list_t::iterator item_iter;
- for (item_iter = mItems.begin(); item_iter != mItems.end(); ++item_iter)
- {
- if (which == 0)
- {
- return (*item_iter);
- }
- which--;
- }
- }
-
- return NULL;
-}
-
-S32 LLPieMenu::pieItemIndexFromXY(S32 x, S32 y)
-{
- // An arc of the pie menu is 45 degrees
- const F32 ARC_DEG = 45.f;
- // correct for non-square pixels
- S32 delta_x = x - getRect().getWidth() / 2;
- S32 delta_y = y - getRect().getHeight() / 2;
-
- // circle safe zone in the center
- if (delta_x*delta_x + delta_y*delta_y < PIE_CENTER_SIZE*PIE_CENTER_SIZE)
- {
- return -1;
- }
-
- F32 angle = RAD_TO_DEG * (F32) atan2((F32)delta_y, (F32)delta_x);
-
- // rotate marks CCW so that east = [0, ARC_DEG) instead of
- // [-ARC_DEG/2, ARC_DEG/2)
- angle += ARC_DEG / 2.f;
-
- // make sure we're only using positive angles
- if (angle < 0.f) angle += 360.f;
-
- S32 which = S32( angle / ARC_DEG );
- return which;
-}
-
-void LLPieMenu::show(S32 x, S32 y, BOOL mouse_down)
-{
- S32 width = getRect().getWidth();
- S32 height = getRect().getHeight();
-
- const LLRect menu_region_rect = LLMenuGL::sMenuContainer->getMenuRect();
-
- LLView* parent_view = getParent();
- BOOL moved = FALSE;
-
- S32 local_x, local_y;
- parent_view->screenPointToLocal(x, y, &local_x, &local_y);
-
- // HACK: casting away const. Should use setRect or some helper function instead.
- const_cast<LLRect&>(getRect()).setCenterAndSize(local_x, local_y, width, height);
- arrange();
-
- // Adjust the pie rectangle to keep it on screen
- if (getRect().mLeft < menu_region_rect.mLeft)
- {
- //mShiftHoriz = menu_region_rect.mLeft - getRect().mLeft;
- //getRect().translate( mShiftHoriz, 0 );
- // HACK: casting away const. Should use setRect or some helper function instead.
- const_cast<LLRect&>(getRect()).translate( menu_region_rect.mLeft - getRect().mLeft, 0 );
- moved = TRUE;
- }
-
- if (getRect().mRight > menu_region_rect.mRight)
- {
- //mShiftHoriz = menu_region_rect.mRight - getRect().mRight;
- //getRect().translate( mShiftHoriz, 0);
- // HACK: casting away const. Should use setRect or some helper function instead.
- const_cast<LLRect&>(getRect()).translate( menu_region_rect.mRight - getRect().mRight, 0 );
- moved = TRUE;
- }
-
- if (getRect().mBottom < menu_region_rect.mBottom)
- {
- //mShiftVert = menu_region_rect.mBottom - getRect().mBottom;
- //getRect().translate( 0, mShiftVert );
- // HACK: casting away const. Should use setRect or some helper function instead.
- const_cast<LLRect&>(getRect()).translate( 0, menu_region_rect.mBottom - getRect().mBottom );
- moved = TRUE;
- }
-
-
- if (getRect().mTop > menu_region_rect.mTop)
- {
- //mShiftVert = menu_region_rect.mTop - getRect().mTop;
- //getRect().translate( 0, mShiftVert );
- // HACK: casting away const. Should use setRect or some helper function instead.
- const_cast<LLRect&>(getRect()).translate( 0, menu_region_rect.mTop - getRect().mTop );
- moved = TRUE;
- }
-
- // If we had to relocate the pie menu, put the cursor in the
- // center of its rectangle
- if (moved)
- {
- LLCoordGL center;
- center.mX = (getRect().mLeft + getRect().mRight) / 2;
- center.mY = (getRect().mTop + getRect().mBottom) / 2;
-
- LLUI::setCursorPositionLocal(getParent(), center.mX, center.mY);
- }
-
- // *FIX: what happens when mouse buttons reversed?
- mRightMouseDown = mouse_down;
- mFirstMouseDown = mouse_down;
- mUseInfiniteRadius = TRUE;
- mHoveredAnyItem = FALSE;
-
- if (!mFirstMouseDown)
- {
- make_ui_sound("UISndPieMenuAppear");
- }
-
- LLView::setVisible(TRUE);
-
- // we want all mouse events in case user does quick right click again off of pie menu
- // rectangle, to support gestural menu traversal
- gFocusMgr.setMouseCapture(this);
-
- if (mouse_down)
- {
- mShrinkBorderTimer.stop();
- }
- else
- {
- mShrinkBorderTimer.start();
- }
-}
-
-void LLPieMenu::hide(BOOL item_selected)
-{
- if (!getVisible()) return;
-
- if (mHoverItem)
- {
- mHoverItem->setHighlight( FALSE );
- mHoverItem = NULL;
- }
-
- make_ui_sound("UISndPieMenuHide");
-
- mFirstMouseDown = FALSE;
- mRightMouseDown = FALSE;
- mUseInfiniteRadius = FALSE;
- mHoveredAnyItem = FALSE;
-
- LLView::setVisible(FALSE);
-
- gFocusMgr.setMouseCapture(NULL);
-}
-
///============================================================================
/// Class LLMenuBarGL
///============================================================================
-static LLRegisterWidget<LLMenuBarGL> r2("menu_bar");
+static LLDefaultChildRegistry::Register<LLMenuBarGL> r2("menu_bar");
-// Default constructor
-LLMenuBarGL::LLMenuBarGL( const std::string& name ) : LLMenuGL ( name, name )
-{
- mHorizontalLayout = TRUE;
- setCanTearOff(FALSE);
- mKeepFixedSize = TRUE;
- mAltKeyTrigger = FALSE;
-}
+LLMenuBarGL::LLMenuBarGL( const Params& p )
+: LLMenuGL(p),
+ mAltKeyTrigger(FALSE)
+{}
// Default destructor
LLMenuBarGL::~LLMenuBarGL()
@@ -3813,108 +2995,6 @@ LLMenuBarGL::~LLMenuBarGL()
mAccelerators.clear();
}
-// virtual
-LLXMLNodePtr LLMenuBarGL::getXML(bool save_children) const
-{
- // Sorty of hacky: reparent items to this and then back at the end of the export
- LLView *orig_parent = NULL;
- item_list_t::const_iterator item_iter;
- for (item_iter = mItems.begin(); item_iter != mItems.end(); ++item_iter)
- {
- LLMenuItemGL* child = *item_iter;
- LLMenuItemBranchGL* branch = (LLMenuItemBranchGL*)child;
- LLMenuGL *menu = branch->getBranch();
- orig_parent = menu->getParent();
- menu->updateParent((LLView *)this);
- }
-
- LLXMLNodePtr node = LLMenuGL::getXML();
-
- for (item_iter = mItems.begin(); item_iter != mItems.end(); ++item_iter)
- {
- LLMenuItemGL* child = *item_iter;
- LLMenuItemBranchGL* branch = (LLMenuItemBranchGL*)child;
- LLMenuGL *menu = branch->getBranch();
- menu->updateParent(orig_parent);
- }
-
- return node;
-}
-
-LLView* LLMenuBarGL::fromXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFactory *factory)
-{
- std::string name("menu");
- node->getAttributeString("name", name);
-
- BOOL opaque = FALSE;
- node->getAttributeBOOL("opaque", opaque);
-
- LLMenuBarGL *menubar = new LLMenuBarGL(name);
-
- LLHandle<LLFloater> parent_handle;
- LLFloater* parent_floater = dynamic_cast<LLFloater*>(parent);
- if (parent_floater)
- {
- parent_handle = parent_floater->getHandle();
- }
-
- // We need to have the rect early so that it's around when building
- // the menu items
- LLRect view_rect;
- createRect(node, view_rect, parent, menubar->getRequiredRect());
- menubar->setRect(view_rect);
-
- if (node->hasAttribute("drop_shadow"))
- {
- BOOL drop_shadow = FALSE;
- node->getAttributeBOOL("drop_shadow", drop_shadow);
- menubar->setDropShadowed(drop_shadow);
- }
-
- menubar->setBackgroundVisible(opaque);
- LLColor4 color(0,0,0,0);
- if (opaque && LLUICtrlFactory::getAttributeColor(node,"color", color))
- {
- menubar->setBackgroundColor(color);
- }
-
- LLXMLNodePtr child;
- for (child = node->getFirstChild(); child.notNull(); child = child->getNextSibling())
- {
- if (child->hasName("menu"))
- {
- LLMenuGL *menu = (LLMenuGL*)LLMenuGL::fromXML(child, parent, factory);
- // because of lazy initialization, have to disable tear off functionality
- // and then re-enable with proper parent handle
- if (menu->getCanTearOff())
- {
- menu->setCanTearOff(FALSE);
- menu->setCanTearOff(TRUE, parent_handle);
- }
- menubar->appendMenu(menu);
- if (LLMenuGL::sMenuContainer != NULL)
- {
- menu->updateParent(LLMenuGL::sMenuContainer);
- }
- else
- {
- menu->updateParent(parent);
- }
- }
- }
-
- menubar->initFromXML(node, parent);
-
- BOOL create_jump_keys = FALSE;
- node->getAttributeBOOL("create_jump_keys", create_jump_keys);
- if (create_jump_keys)
- {
- menubar->createJumpKeys();
- }
-
- return menubar;
-}
-
BOOL LLMenuBarGL::handleAcceleratorKey(KEY key, MASK mask)
{
if (getHighlightedItem() && mask == MASK_NONE)
@@ -3951,7 +3031,8 @@ BOOL LLMenuBarGL::handleAcceleratorKey(KEY key, MASK mask)
BOOL LLMenuBarGL::handleKeyHere(KEY key, MASK mask)
{
- if(key == KEY_ALT && !gKeyboard->getKeyRepeated(key) && LLUI::sConfigGroup->getBOOL("UseAltKeyForMenus"))
+ static LLUICachedControl<bool> use_altkey_for_menus ("UseAltKeyForMenus", 0);
+ if(key == KEY_ALT && !gKeyboard->getKeyRepeated(key) && use_altkey_for_menus)
{
mAltKeyTrigger = TRUE;
}
@@ -3984,7 +3065,7 @@ BOOL LLMenuBarGL::handleJumpKey(KEY key)
LLMenuGL::setKeyboardMode(TRUE);
found_it->second->setHighlight(TRUE);
- found_it->second->doIt();
+ found_it->second->onCommit();
}
return TRUE;
}
@@ -4001,19 +3082,6 @@ BOOL LLMenuBarGL::handleMouseDown(S32 x, S32 y, MASK mask)
return LLMenuGL::handleMouseDown(x, y, mask);
}
-BOOL LLMenuBarGL::handleRightMouseDown(S32 x, S32 y, MASK mask)
-{
- // clicks on menu bar closes existing menus from other contexts but leave
- // own menu open so that we get toggle behavior
- if (!getHighlightedItem() || !getHighlightedItem()->isActive())
- {
- LLMenuGL::sMenuContainer->hideMenus();
- }
-
- return LLMenuGL::handleMouseDown(x, y, mask);
-}
-
-
void LLMenuBarGL::draw()
{
LLMenuItemGL* itemp = getHighlightedItem();
@@ -4031,6 +3099,7 @@ void LLMenuBarGL::draw()
LLMenuGL::draw();
}
+
void LLMenuBarGL::checkMenuTrigger()
{
// has the ALT key been pressed and subsequently released?
@@ -4038,7 +3107,8 @@ void LLMenuBarGL::checkMenuTrigger()
{
// if alt key was released quickly, treat it as a menu access key
// otherwise it was probably an Alt-zoom or similar action
- if (gKeyboard->getKeyElapsedTime(KEY_ALT) <= LLUI::sConfigGroup->getF32("MenuAccessKeyTime") ||
+ static LLUICachedControl<F32> menu_access_key_time ("MenuAccessKeyTime", 0);
+ if (gKeyboard->getKeyElapsedTime(KEY_ALT) <= menu_access_key_time ||
gKeyboard->getKeyElapsedFrameCount(KEY_ALT) < 2)
{
if (getHighlightedItem())
@@ -4107,7 +3177,7 @@ S32 LLMenuBarGL::getRightmostMenuEdge()
}
// add a vertical separator to this menu
-BOOL LLMenuBarGL::appendSeparator( const std::string &separator_name )
+BOOL LLMenuBarGL::addSeparator()
{
LLMenuItemGL* separator = new LLMenuItemVerticalSeparatorGL();
return append( separator );
@@ -4124,11 +3194,23 @@ BOOL LLMenuBarGL::appendMenu( LLMenuGL* menu )
BOOL success = TRUE;
- LLMenuItemBranchGL* branch = NULL;
- branch = new LLMenuItemBranchDownGL( menu->getName(), menu->getLabel(), menu->getHandle());
+ // *TODO: Hack! Fix this
+ LLMenuItemBranchDownGL::Params p;
+ p.name = menu->getName();
+ p.label = menu->getLabel();
+ p.visible = menu->getVisible();
+ p.branch = menu;
+ p.enabled_color=LLUIColorTable::instance().getColor("MenuItemEnabledColor");
+ p.disabled_color=LLUIColorTable::instance().getColor("MenuItemDisabledColor");
+ p.highlight_bg_color=LLUIColorTable::instance().getColor("MenuItemHighlightBgColor");
+ p.highlight_fg_color=LLUIColorTable::instance().getColor("MenuItemHighlightFgColor");
+
+ LLMenuItemBranchDownGL* branch = LLUICtrlFactory::create<LLMenuItemBranchDownGL>(p);
success &= branch->addToAcceleratorList(&mAccelerators);
success &= append( branch );
branch->setJumpKey(branch->getJumpKey());
+ menu->updateParent(LLMenuGL::sMenuContainer);
+
return success;
}
@@ -4174,7 +3256,7 @@ BOOL LLMenuBarGL::handleHover( S32 x, S32 y, MASK mask )
handled = TRUE;
if (active_menu && active_menu != viewp)
{
- ((LLMenuItemGL*)viewp)->doIt();
+ ((LLMenuItemGL*)viewp)->onCommit();
LLMenuGL::setKeyboardMode(FALSE);
}
LLMenuGL::setKeyboardMode(FALSE);
@@ -4205,23 +3287,17 @@ BOOL LLMenuBarGL::handleHover( S32 x, S32 y, MASK mask )
///============================================================================
/// Class LLMenuHolderGL
///============================================================================
+LLCoordGL LLMenuHolderGL::sContextMenuSpawnPos(S32_MAX, S32_MAX);
+
LLMenuHolderGL::LLMenuHolderGL()
- : LLPanel(std::string("Menu Holder"))
+ : LLPanel()
{
+ setName("Menu Holder");
setMouseOpaque(FALSE);
sItemActivationTimer.stop();
mCanHide = TRUE;
}
-LLMenuHolderGL::LLMenuHolderGL(const std::string& name, const LLRect& rect, BOOL mouse_opaque, U32 follows)
-: LLPanel(name, rect, FALSE)
-{
- setMouseOpaque(mouse_opaque);
- sItemActivationTimer.stop();
- mCanHide = TRUE;
-}
-
-
void LLMenuHolderGL::draw()
{
LLView::draw();
@@ -4236,16 +3312,11 @@ void LLMenuHolderGL::draw()
selecteditem->localRectToOtherView(selecteditem->getLocalRect(), &item_rect, this);
F32 interpolant = sItemActivationTimer.getElapsedTimeF32() / ACTIVATE_HIGHLIGHT_TIME;
- F32 alpha = lerp(LLMenuItemGL::getHighlightBGColor().mV[VALPHA], 0.f, interpolant);
- LLColor4 bg_color(LLMenuItemGL::getHighlightBGColor().mV[VRED],
- LLMenuItemGL::getHighlightBGColor().mV[VGREEN],
- LLMenuItemGL::getHighlightBGColor().mV[VBLUE],
- alpha);
LLUI::pushMatrix();
{
LLUI::translate((F32)item_rect.mLeft, (F32)item_rect.mBottom, 0.f);
- selecteditem->getMenu()->drawBackground(selecteditem, bg_color);
+ selecteditem->getMenu()->drawBackground(selecteditem, interpolant);
selecteditem->draw();
}
LLUI::popMatrix();
@@ -4274,6 +3345,32 @@ BOOL LLMenuHolderGL::handleRightMouseDown( S32 x, S32 y, MASK mask )
return handled;
}
+// This occurs when you mouse-down to spawn a context menu, hold the button
+// down, move off the menu, then mouse-up. We want this to close the menu.
+BOOL LLMenuHolderGL::handleRightMouseUp( S32 x, S32 y, MASK mask )
+{
+ const S32 SLOP = 2;
+ S32 spawn_dx = (x - sContextMenuSpawnPos.mX);
+ S32 spawn_dy = (y - sContextMenuSpawnPos.mY);
+ if (-SLOP <= spawn_dx && spawn_dx <= SLOP
+ && -SLOP <= spawn_dy && spawn_dy <= SLOP)
+ {
+ // we're still inside the slop region from spawning this menu
+ // so interpret the mouse-up as a single-click to show and leave on
+ // screen
+ sContextMenuSpawnPos.set(S32_MAX, S32_MAX);
+ return TRUE;
+ }
+
+ BOOL handled = LLView::childrenHandleRightMouseUp(x, y, mask) != NULL;
+ if (!handled)
+ {
+ // clicked off of menu, hide them all
+ hideMenus();
+ }
+ return handled;
+}
+
void LLMenuHolderGL::reshape(S32 width, S32 height, BOOL called_from_parent)
{
if (width != getRect().getWidth() || height != getRect().getHeight())
@@ -4336,17 +3433,22 @@ void LLMenuHolderGL::setActivatedItem(LLMenuItemGL* item)
/// Class LLTearOffMenu
///============================================================================
LLTearOffMenu::LLTearOffMenu(LLMenuGL* menup) :
- LLFloater(menup->getName(), LLRect(0, 100, 100, 0), menup->getLabel(), FALSE, DEFAULT_MIN_WIDTH, DEFAULT_MIN_HEIGHT, FALSE, FALSE)
+ LLFloater(LLSD())
{
+ static LLUICachedControl<S32> floater_header_size ("UIFloaterHeaderSize", 0);
+
+ setName(menup->getName());
+ setTitle(menup->getLabel());
+ setCanMinimize(FALSE);
// flag menu as being torn off
menup->setTornOff(TRUE);
// update menu layout as torn off menu (no spillover menus)
- menup->arrange();
+ menup->needsArrange();
LLRect rect;
menup->localRectToOtherView(LLRect(-1, menup->getRect().getHeight(), menup->getRect().getWidth() + 3, 0), &rect, gFloaterView);
// make sure this floater is big enough for menu
- mTargetHeight = (F32)(rect.getHeight() + LLFLOATER_HEADER_SIZE + 5);
+ mTargetHeight = (F32)(rect.getHeight() + floater_header_size + 5);
reshape(rect.getWidth(), rect.getHeight());
setRect(rect);
@@ -4362,13 +3464,21 @@ LLTearOffMenu::LLTearOffMenu(LLMenuGL* menup) :
// highlight first item (tear off item will be disabled)
mMenu->highlightNextItem(NULL);
+
+ // Can't do this in postBuild() because that is only called for floaters
+ // constructed from XML.
+ mCloseSignal.connect(boost::bind(&LLTearOffMenu::closeTearOff, this));
}
+LLTearOffMenu::~LLTearOffMenu()
+{
+}
void LLTearOffMenu::draw()
{
+ static LLUICachedControl<S32> floater_header_size ("UIFloaterHeaderSize", 0);
mMenu->setBackgroundVisible(isBackgroundOpaque());
- mMenu->arrange();
+ mMenu->needsArrange();
if (getRect().getHeight() != mTargetHeight)
{
@@ -4378,8 +3488,8 @@ void LLTearOffMenu::draw()
else
{
// when in stasis, remain big enough to hold menu contents
- mTargetHeight = (F32)(mMenu->getRect().getHeight() + LLFLOATER_HEADER_SIZE + 4);
- reshape(mMenu->getRect().getWidth() + 3, mMenu->getRect().getHeight() + LLFLOATER_HEADER_SIZE + 5);
+ mTargetHeight = (F32)(mMenu->getRect().getHeight() + floater_header_size + 4);
+ reshape(mMenu->getRect().getWidth() + 3, mMenu->getRect().getHeight() + floater_header_size + 5);
}
LLFloater::draw();
}
@@ -4457,12 +3567,12 @@ LLTearOffMenu* LLTearOffMenu::create(LLMenuGL* menup)
LLTearOffMenu* tearoffp = new LLTearOffMenu(menup);
// keep onscreen
gFloaterView->adjustToFitScreen(tearoffp, FALSE);
- tearoffp->open(); /* Flawfinder: ignore */
+ tearoffp->openFloater(LLSD());
return tearoffp;
}
-void LLTearOffMenu::onClose(bool app_quitting)
+void LLTearOffMenu::closeTearOff()
{
removeChild(mMenu);
mOldParent->addChild(mMenu);
@@ -4472,6 +3582,337 @@ void LLTearOffMenu::onClose(bool app_quitting)
mMenu->setVisible(FALSE);
mMenu->setTornOff(FALSE);
mMenu->setDropShadowed(TRUE);
- destroy();
+}
+
+
+//-----------------------------------------------------------------------------
+// class LLContextMenuBranch
+// A branch to another context menu
+//-----------------------------------------------------------------------------
+class LLContextMenuBranch : public LLMenuItemGL
+{
+public:
+ struct Params : public LLInitParam::Block<Params, LLMenuItemGL::Params>
+ {
+ Mandatory<LLContextMenu*> branch;
+ };
+
+ LLContextMenuBranch(const Params&);
+
+ // called to rebuild the draw label
+ virtual void buildDrawLabel( void );
+
+ // onCommit() - do the primary funcationality of the menu item.
+ virtual void onCommit( void );
+
+ LLContextMenu* getBranch() { return mBranch; }
+ void setHighlight( BOOL highlight );
+
+protected:
+ void showSubMenu();
+
+ LLContextMenu* mBranch;
+};
+
+LLContextMenuBranch::LLContextMenuBranch(const LLContextMenuBranch::Params& p)
+: LLMenuItemGL(p),
+ mBranch( p.branch )
+{
+ mBranch->hide();
+ mBranch->setParentMenuItem(this);
+}
+
+// called to rebuild the draw label
+void LLContextMenuBranch::buildDrawLabel( void )
+{
+ {
+ // default enablement is this -- if any of the subitems are
+ // enabled, this item is enabled. JC
+ U32 sub_count = mBranch->getItemCount();
+ U32 i;
+ BOOL any_enabled = FALSE;
+ for (i = 0; i < sub_count; i++)
+ {
+ LLMenuItemGL* item = mBranch->getItem(i);
+ item->buildDrawLabel();
+ if (item->getEnabled() && !item->getDrawTextDisabled() )
+ {
+ any_enabled = TRUE;
+ break;
+ }
+ }
+ setDrawTextDisabled(!any_enabled);
+ setEnabled(TRUE);
+ }
+
+ mDrawAccelLabel.clear();
+ std::string st = mDrawAccelLabel;
+ appendAcceleratorString( st );
+ mDrawAccelLabel = st;
+
+ // No special branch suffix
+ mDrawBranchLabel.clear();
+}
+
+void LLContextMenuBranch::showSubMenu()
+{
+ S32 center_x;
+ S32 center_y;
+ localPointToScreen(getRect().getWidth(), getRect().getHeight() , &center_x, &center_y);
+ mBranch->show( center_x, center_y);
+}
+
+// onCommit() - do the primary funcationality of the menu item.
+void LLContextMenuBranch::onCommit( void )
+{
+ showSubMenu();
+
+}
+void LLContextMenuBranch::setHighlight( BOOL highlight )
+{
+ if (highlight == getHighlight()) return;
+ LLMenuItemGL::setHighlight(highlight);
+ if( highlight )
+ {
+ showSubMenu();
+ }
+ else
+ {
+ mBranch->hide();
+ }
+}
+
+
+///////////////////////////////////////////////////////////////////////////////////////////////////////////
+//-----------------------------------------------------------------------------
+// class LLContextMenu
+// A context menu
+//-----------------------------------------------------------------------------
+static LLDefaultChildRegistry::Register<LLContextMenu> context_menu_register("context_menu");
+static MenuRegistry::Register<LLContextMenu> context_menu_register2("context_menu");
+
+
+LLContextMenu::LLContextMenu(const Params& p)
+: LLMenuGL(p),
+ mHoveredAnyItem(FALSE),
+ mHoverItem(NULL)
+{
+ //setBackgroundVisible(TRUE);
+}
+
+void LLContextMenu::setVisible(BOOL visible)
+{
+ if (!visible)
+ hide();
+}
+
+// Takes cursor position in screen space?
+void LLContextMenu::show(S32 x, S32 y)
+{
+ // Save click point for detecting cursor moves before mouse-up.
+ // Must be in local coords to compare with mouseUp events.
+ // If the mouse doesn't move, the menu will stay open ala the Mac.
+ // See also LLMenuGL::showPopup()
+ LLMenuHolderGL::sContextMenuSpawnPos.set(x,y);
+
+ arrangeAndClear();
+
+ S32 width = getRect().getWidth();
+ S32 height = getRect().getHeight();
+ const LLRect menu_region_rect = LLMenuGL::sMenuContainer->getMenuRect();
+ LLView* parent_view = getParent();
+
+ // Open upwards if menu extends past bottom
+ if (y - height < menu_region_rect.mBottom)
+ {
+ if (getParentMenuItem()) // Adjust if this is a submenu
+ {
+ y += height - getParentMenuItem()->getNominalHeight();
+ }
+ else
+ {
+ y += height;
+ }
+ }
+
+ // Open out to the left if menu extends past right edge
+ if (x + width > menu_region_rect.mRight)
+ {
+ if (getParentMenuItem())
+ {
+ x -= getParentMenuItem()->getRect().getWidth() + width;
+ }
+ else
+ {
+ x -= width;
+ }
+ }
+
+ S32 local_x, local_y;
+ parent_view->screenPointToLocal(x, y, &local_x, &local_y);
+
+ LLRect rect;
+ rect.setLeftTopAndSize(local_x, local_y, width, height);
+ setRect(rect);
+ arrange();
+
+ LLView::setVisible(TRUE);
+}
+
+void LLContextMenu::hide()
+{
+ if (!getVisible()) return;
+
+ LLView::setVisible(FALSE);
+
+ if (mHoverItem)
+ {
+ mHoverItem->setHighlight( FALSE );
+ }
+ mHoverItem = NULL;
+}
+
+
+BOOL LLContextMenu::handleHover( S32 x, S32 y, MASK mask )
+{
+ LLMenuGL::handleHover(x,y,mask);
+
+ BOOL handled = FALSE;
+
+ LLMenuItemGL *item = getHighlightedItem();
+
+ if (item && item->getEnabled())
+ {
+ getWindow()->setCursor(UI_CURSOR_ARROW);
+ handled = TRUE;
+
+ if (item != mHoverItem)
+ {
+ if (mHoverItem)
+ {
+ mHoverItem->setHighlight( FALSE );
+ }
+ mHoverItem = item;
+ mHoverItem->setHighlight( TRUE );
+ }
+ mHoveredAnyItem = TRUE;
+ }
+ else
+ {
+ // clear out our selection
+ if (mHoverItem)
+ {
+ mHoverItem->setHighlight(FALSE);
+ mHoverItem = NULL;
+ }
+ }
+
+ if( !handled && pointInView( x, y ) )
+ {
+ getWindow()->setCursor(UI_CURSOR_ARROW);
+ handled = TRUE;
+ }
+
+ return handled;
+}
+
+// handleMouseDown and handleMouseUp are handled by LLMenuGL
+
+
+BOOL LLContextMenu::handleRightMouseDown(S32 x, S32 y, MASK mask)
+{
+ BOOL handled = FALSE;
+
+ // The click was somewhere within our rectangle
+ LLMenuItemGL *item = getHighlightedItem();
+
+ S32 local_x = x - getRect().mLeft;
+ S32 local_y = y - getRect().mBottom;
+
+ BOOL clicked_in_menu = pointInView(local_x, local_y) ;
+
+ // grab mouse if right clicking anywhere within pie (even deadzone in middle), to detect drag outside of pie
+ if (clicked_in_menu)
+ {
+ // capture mouse cursor as if on initial menu show
+ handled = TRUE;
+ }
+
+ if (item)
+ {
+ // lie to the item about where the click happened
+ // to make sure it's within the item's rectangle
+ if (item->handleMouseDown( 0, 0, mask ))
+ {
+ handled = TRUE;
+ }
+ }
+
+ return handled;
+}
+
+BOOL LLContextMenu::handleRightMouseUp( S32 x, S32 y, MASK mask )
+{
+ S32 local_x = x - getRect().mLeft;
+ S32 local_y = y - getRect().mBottom;
+
+ if (!mHoveredAnyItem && !pointInView(local_x, local_y))
+ {
+ sMenuContainer->hideMenus();
+ return TRUE;
+ }
+
+
+ BOOL result = handleMouseUp( x, y, mask );
+ mHoveredAnyItem = FALSE;
+
+ return result;
+}
+
+void LLContextMenu::draw()
+{
+ LLMenuGL::draw();
+}
+
+BOOL LLContextMenu::appendContextSubMenu(LLContextMenu *menu)
+{
+
+ if (menu == this)
+ {
+ llerrs << "Can't attach a context menu to itself" << llendl;
+ }
+
+ LLContextMenuBranch *item;
+ LLContextMenuBranch::Params p;
+ p.name = menu->getName();
+ p.label = menu->getLabel();
+ p.branch = menu;
+ p.enabled_color=LLUIColorTable::instance().getColor("MenuItemEnabledColor");
+ p.disabled_color=LLUIColorTable::instance().getColor("MenuItemDisabledColor");
+ p.highlight_bg_color=LLUIColorTable::instance().getColor("MenuItemHighlightBgColor");
+ p.highlight_fg_color=LLUIColorTable::instance().getColor("MenuItemHighlightFgColor");
+
+ item = LLUICtrlFactory::create<LLContextMenuBranch>(p);
+ LLMenuGL::sMenuContainer->addChild(item->getBranch());
+ item->setFont( LLFontGL::getFontSansSerifSmall() );
+
+ return append( item );
+}
+
+bool LLContextMenu::addChild(LLView* view, S32 tab_group)
+{
+ LLContextMenu* context = dynamic_cast<LLContextMenu*>(view);
+ if (context)
+ return appendContextSubMenu(context);
+
+ LLMenuItemSeparatorGL* separator = dynamic_cast<LLMenuItemSeparatorGL*>(view);
+ if (separator)
+ return append(separator);
+
+ LLMenuItemGL* item = dynamic_cast<LLMenuItemGL*>(view);
+ if (item)
+ return append(item);
+
+ return false;
}
diff --git a/indra/llui/llmenugl.h b/indra/llui/llmenugl.h
index e62402d617..0bf6301f93 100644
--- a/indra/llui/llmenugl.h
+++ b/indra/llui/llmenugl.h
@@ -38,85 +38,99 @@
#include "llstring.h"
#include "v4color.h"
#include "llframetimer.h"
-#include "llevent.h"
#include "llkeyboard.h"
#include "llfloater.h"
#include "lluistring.h"
#include "llview.h"
-
+#include <boost/function.hpp>
extern S32 MENU_BAR_HEIGHT;
extern S32 MENU_BAR_WIDTH;
-// These callbacks are used by the LLMenuItemCallGL and LLMenuItemCheckGL
-// classes during their work.
-typedef void (*menu_callback)(void*);
-
-// These callbacks are used by the LLMenuItemCallGL
-// classes during their work.
-typedef void (*on_disabled_callback)(void*);
-
-// This callback is used by the LLMenuItemCallGL and LLMenuItemCheckGL
-// to determine if the current menu is enabled.
-typedef BOOL (*enabled_callback)(void*);
-
-// This callback is used by LLMenuItemCheckGL to determine it's
-// 'checked' state.
-typedef BOOL (*check_callback)(void*);
-
-// This callback is potentially used by LLMenuItemCallGL. If provided,
-// this function is called whenever it's time to determine the label's
-// contents. Put the contents of the label in the provided parameter.
-typedef void (*label_callback)(std::string&,void*);
-
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Class LLMenuItemGL
//
// The LLMenuItemGL represents a single menu item in a menu.
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-class LLMenuItemGL : public LLView
+class LLMenuItemGL : public LLUICtrl
{
public:
- // static functions to control the global color scheme.
- static void setEnabledColor( const LLColor4& color ) { sEnabledColor = color; }
- static const LLColor4& getEnabledColor() { return sEnabledColor; }
- static void setDisabledColor( const LLColor4& color ) { sDisabledColor = color; }
- static const LLColor4& getDisabledColor() { return sDisabledColor; }
- static void setHighlightBGColor( const LLColor4& color ) { sHighlightBackground = color; }
- static const LLColor4& getHighlightBGColor() { return sHighlightBackground; }
- static void setHighlightFGColor( const LLColor4& color ) { sHighlightForeground = color; }
- static const LLColor4& getHighlightFGColor() { return sHighlightForeground; }
-
- LLMenuItemGL( const std::string& name, const std::string& label, KEY key = KEY_NONE, MASK = MASK_NONE );
- virtual ~LLMenuItemGL() {};
-
- virtual void setValue(const LLSD& value) { setLabel(value.asString()); }
+ struct Params : public LLInitParam::Block<Params, LLUICtrl::Params>
+ {
+ Optional<std::string> shortcut;
+ Optional<KEY> jump_key;
+ Optional<bool> use_mac_ctrl;
+
+ Ignored rect,
+ left,
+ top,
+ right,
+ bottom,
+ width,
+ height,
+ bottom_delta,
+ left_delta;
+
+ Optional<LLUIColor> enabled_color,
+ disabled_color,
+ highlight_bg_color,
+ highlight_fg_color;
+
+
+ Params()
+ : shortcut("shortcut"),
+ jump_key("jump_key", KEY_NONE),
+ use_mac_ctrl("use_mac_ctrl", false),
+ rect("rect"),
+ left("left"),
+ top("top"),
+ right("right"),
+ bottom("bottom"),
+ width("width"),
+ height("height"),
+ bottom_delta("bottom_delta"),
+ left_delta("left_delta"),
+ enabled_color("enabled_color"),
+ disabled_color("disabled_color"),
+ highlight_bg_color("highlight_bg_color"),
+ highlight_fg_color("highlight_fg_color")
+ {
+ mouse_opaque = true;
+ }
+ };
- virtual LLXMLNodePtr getXML(bool save_children = true) const;
-
- virtual std::string getType() const { return "item"; }
+protected:
+ LLMenuItemGL(const Params&);
+ friend class LLUICtrlFactory;
+public:
+ // LLView overrides
+ /*virtual*/ void handleVisibilityChange(BOOL new_visibility);
+ /*virtual*/ BOOL handleHover(S32 x, S32 y, MASK mask);
+ /*virtual*/ BOOL handleRightMouseDown(S32 x, S32 y, MASK mask);
+ /*virtual*/ BOOL handleRightMouseUp(S32 x, S32 y, MASK mask);
- virtual BOOL handleHover(S32 x, S32 y, MASK mask);
+ // LLUICtrl overrides
+ /*virtual*/ void setValue(const LLSD& value);
virtual BOOL handleAcceleratorKey(KEY key, MASK mask);
+ LLColor4 getHighlightBgColor() { return mHighlightBackground.get(); }
+
void setJumpKey(KEY key);
KEY getJumpKey() const { return mJumpKey; }
// set the font used by this item.
void setFont(const LLFontGL* font) { mFont = font; }
const LLFontGL* getFont() const { return mFont; }
- void setFontStyle(U8 style) { mStyle = style; }
- U8 getFontStyle() const { return mStyle; }
// returns the height in pixels for the current font.
virtual U32 getNominalHeight( void ) const;
// Marks item as not needing space for check marks or accelerator keys
- virtual void setBriefItem(BOOL brief) { mBriefItem = brief; }
- virtual BOOL isBriefItem() const { return mBriefItem; }
+ virtual void setBriefItem(BOOL brief);
+ virtual BOOL isBriefItem() const;
virtual BOOL addToAcceleratorList(std::list<LLKeyBinding*> *listp);
void setAllowKeyRepeat(BOOL allow) { mAllowKeyRepeat = allow; }
@@ -128,7 +142,7 @@ public:
virtual BOOL setLabelArg( const std::string& key, const LLStringExplicit& text );
// Get the parent menu for this item
- virtual class LLMenuGL* getMenu();
+ virtual class LLMenuGL* getMenu() const;
// returns the normal width of this control in pixels - this is
// used for calculating the widest item, as well as for horizontal
@@ -140,7 +154,7 @@ public:
// lead to visual errors if the state of the object changes
// without the knowledge of the menu item. For example, if a
// boolean being watched is changed outside of the menu item's
- // doIt() function, the draw buffer will not be updated and will
+ // onCommit() function, the draw buffer will not be updated and will
// reflect the wrong value. If this ever becomes an issue, there
// are ways to fix this.
// Returns the enabled state of the item.
@@ -149,8 +163,7 @@ public:
// for branching menu items, bring sub menus up to root level of menu hierarchy
virtual void updateBranchParent( LLView* parentp ){};
- // doIt() - do the primary funcationality of the menu item.
- virtual void doIt( void );
+ virtual void onCommit( void );
virtual void setHighlight( BOOL highlight );
virtual BOOL getHighlight() const { return mHighlight; }
@@ -167,6 +180,7 @@ public:
virtual BOOL handleKeyHere( KEY key, MASK mask );
virtual BOOL handleMouseDown( S32 x, S32 y, MASK mask );
virtual BOOL handleMouseUp( S32 x, S32 y, MASK mask );
+ virtual BOOL handleScrollWheel( S32 x, S32 y, S32 clicks );
virtual void draw( void );
BOOL getHover() const { return mGotHover; }
@@ -180,7 +194,10 @@ protected:
// This function appends the character string representation of
// the current accelerator key and mask to the provided string.
void appendAcceleratorString( std::string& st ) const;
-
+
+ void initMenuEnableCallback(const EnableCallbackParam& cb, enable_signal_t& sig);
+
+protected:
KEY mAcceleratorKey;
MASK mAcceleratorMask;
// mLabel contains the actual label specified by the user.
@@ -193,13 +210,13 @@ protected:
LLUIString mDrawAccelLabel;
LLUIString mDrawBranchLabel;
+ LLUIColor mEnabledColor;
+ LLUIColor mDisabledColor;
+ LLUIColor mHighlightBackground;
+ LLUIColor mHighlightForeground;
+
BOOL mHighlight;
private:
- static LLColor4 sEnabledColor;
- static LLColor4 sDisabledColor;
- static LLColor4 sHighlightBackground;
- static LLColor4 sHighlightForeground;
-
// Keyboard and mouse variables
BOOL mAllowKeyRepeat;
BOOL mGotHover;
@@ -210,12 +227,32 @@ private:
// Font for this item
const LLFontGL* mFont;
- U8 mStyle;
BOOL mDrawTextDisabled;
KEY mJumpKey;
};
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+// Class LLMenuItemSeparatorGL
+//
+// This class represents a separator.
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+class LLMenuItemSeparatorGL : public LLMenuItemGL
+{
+public:
+ struct Params : public LLInitParam::Block<Params, LLMenuItemGL::Params>
+ {
+ Params();
+ };
+ LLMenuItemSeparatorGL(const LLMenuItemSeparatorGL::Params& p = LLMenuItemSeparatorGL::Params());
+
+ /*virtual*/ void draw( void );
+ /*virtual*/ BOOL handleMouseDown(S32 x, S32 y, MASK mask);
+ /*virtual*/ BOOL handleMouseUp(S32 x, S32 y, MASK mask);
+ /*virtual*/ BOOL handleHover(S32 x, S32 y, MASK mask);
+
+ /*virtual*/ U32 getNominalHeight( void ) const;
+};
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Class LLMenuItemCallGL
@@ -224,78 +261,49 @@ private:
// calls a user defined callback.
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-class LLMenuItemCallGL : public LLMenuItemGL, public LLOldEvents::LLObservable
+class LLMenuItemCallGL : public LLMenuItemGL
{
public:
- // normal constructor
- LLMenuItemCallGL( const std::string& name,
- menu_callback clicked_cb,
- enabled_callback enabled_cb = NULL,
- void* user_data = NULL,
- KEY key = KEY_NONE, MASK mask = MASK_NONE,
- BOOL enabled = TRUE,
- on_disabled_callback on_disabled_cb = NULL);
- LLMenuItemCallGL( const std::string& name,
- const std::string& label,
- menu_callback clicked_cb,
- enabled_callback enabled_cb = NULL,
- void* user_data = NULL,
- KEY key = KEY_NONE, MASK mask = MASK_NONE,
- BOOL enabled = TRUE,
- on_disabled_callback on_disabled_cb = NULL);
-
- // constructor for when you want to trap the arrange method.
- LLMenuItemCallGL( const std::string& name,
- const std::string& label,
- menu_callback clicked_cb,
- enabled_callback enabled_cb,
- label_callback label_cb,
- void* user_data,
- KEY key = KEY_NONE, MASK mask = MASK_NONE,
- BOOL enabled = TRUE,
- on_disabled_callback on_disabled_c = NULL);
- LLMenuItemCallGL( const std::string& name,
- menu_callback clicked_cb,
- enabled_callback enabled_cb,
- label_callback label_cb,
- void* user_data,
- KEY key = KEY_NONE, MASK mask = MASK_NONE,
- BOOL enabled = TRUE,
- on_disabled_callback on_disabled_c = NULL);
- virtual LLXMLNodePtr getXML(bool save_children = true) const;
-
- virtual std::string getType() const { return "call"; }
-
-
- void setEnabledControl(std::string enabled_control, LLView *context);
- void setVisibleControl(std::string enabled_control, LLView *context);
-
- void setMenuCallback(menu_callback callback, void* data) { mCallback = callback; mUserData = data; };
- menu_callback getMenuCallback() const { return mCallback; }
-
- void setEnabledCallback(enabled_callback callback) { mEnabledCallback = callback; };
-
- void setUserData(void *userdata) { mUserData = userdata; }
- void* getUserData() const { return mUserData; }
+ struct Params : public LLInitParam::Block<Params, LLMenuItemGL::Params>
+ {
+ Optional<EnableCallbackParam > on_enable;
+ Optional<CommitCallbackParam > on_click;
+ Params()
+ : on_enable("on_enable"),
+ on_click("on_click")
+ {}
+ };
+protected:
+ LLMenuItemCallGL(const Params&);
+ friend class LLUICtrlFactory;
+ void updateEnabled( void );
+public:
+ void initFromParams(const Params& p);
+
// called to rebuild the draw label
virtual void buildDrawLabel( void );
- // doIt() - do the primary funcationality of the menu item.
- virtual void doIt( void );
+ virtual void onCommit( void );
virtual BOOL handleAcceleratorKey(KEY key, MASK mask);
-
+ virtual BOOL handleKeyHere(KEY key, MASK mask);
+
//virtual void draw();
+
+ boost::signals2::connection setClickCallback( const commit_signal_t::slot_type& cb )
+ {
+ return setCommitCallback(cb);
+ }
+
+ boost::signals2::connection setEnableCallback( const enable_signal_t::slot_type& cb )
+ {
+ return mEnableSignal.connect(cb);
+ }
-
+
private:
- menu_callback mCallback;
- // mEnabledCallback should return TRUE if the item should be enabled
- enabled_callback mEnabledCallback;
- label_callback mLabelCallback;
- void* mUserData;
- on_disabled_callback mOnDisabledCallback;
+ enable_signal_t mEnableSignal;
};
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -312,78 +320,37 @@ class LLMenuItemCheckGL
: public LLMenuItemCallGL
{
public:
- LLMenuItemCheckGL( const std::string& name,
- const std::string& label,
- menu_callback callback,
- enabled_callback enabled_cb,
- check_callback check,
- void* user_data,
- KEY key = KEY_NONE, MASK mask = MASK_NONE );
- LLMenuItemCheckGL( const std::string& name,
- menu_callback callback,
- enabled_callback enabled_cb,
- check_callback check,
- void* user_data,
- KEY key = KEY_NONE, MASK mask = MASK_NONE );
- LLMenuItemCheckGL( const std::string& name,
- const std::string& label,
- menu_callback callback,
- enabled_callback enabled_cb,
- std::string control_name,
- LLView *context,
- void* user_data,
- KEY key = KEY_NONE, MASK mask = MASK_NONE );
- virtual LLXMLNodePtr getXML(bool save_children = true) const;
-
- void setCheckedControl(std::string checked_control, LLView *context);
+ struct Params : public LLInitParam::Block<Params, LLMenuItemCallGL::Params>
+ {
+ Optional<EnableCallbackParam > on_check;
+ Params()
+ : on_check("on_check")
+ {}
+ };
- virtual void setValue(const LLSD& value);
-
- virtual std::string getType() const { return "check"; }
-
- // called to rebuild the draw label
- virtual void buildDrawLabel( void );
-
-private:
- check_callback mCheckCallback;
- BOOL mChecked;
-};
-
-
-//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-// Class LLMenuItemToggleGL
-//
-// The LLMenuItemToggleGL is a menu item that wraps around a user
-// specified and controlled boolean.
-//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-class LLMenuItemToggleGL : public LLMenuItemGL
-{
+protected:
+ LLMenuItemCheckGL(const Params&);
+ friend class LLUICtrlFactory;
public:
- LLMenuItemToggleGL( const std::string& name, const std::string& label,
- BOOL* toggle,
- KEY key = KEY_NONE, MASK mask = MASK_NONE );
-
- LLMenuItemToggleGL( const std::string& name,
- BOOL* toggle,
- KEY key = KEY_NONE, MASK mask = MASK_NONE );
+
+ void initFromParams(const Params& p);
- virtual std::string getType() const { return "toggle"; }
+ virtual void onCommit( void );
+
+ virtual void setValue(const LLSD& value);
// called to rebuild the draw label
virtual void buildDrawLabel( void );
-
- // doIt() - do the primary funcationality of the menu item.
- virtual void doIt( void );
-
- // LLView Functionality
- //virtual void draw( void );
-
+
+ boost::signals2::connection setCheckCallback( const enable_signal_t::slot_type& cb )
+ {
+ return mCheckSignal.connect(cb);
+ }
+
private:
- BOOL* mToggle;
+ enable_signal_t mCheckSignal;
};
-
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Class LLMenuGL
//
@@ -395,33 +362,81 @@ private:
// it in the appendMenu() method.
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+// child widget registry
+struct MenuRegistry : public LLChildRegistry<MenuRegistry>
+{};
+
+
class LLMenuGL
: public LLUICtrl
-// TODO: The menu and menu item classes share a great deal of functionality and perhaps should be united.
-// I think it may make the most sense to make LLMenuGL be a subclass of LLMenuItemGL. -MG
{
+public:
+ struct Params : public LLInitParam::Block<Params, LLUICtrl::Params>
+ {
+ Optional<LLHandle<LLFloater> > parent_floater;
+ Optional<KEY> jump_key;
+ Optional<bool> horizontal_layout,
+ can_tear_off,
+ drop_shadow,
+ bg_visible,
+ create_jump_keys,
+ keep_fixed_size,
+ scrollable;
+ Optional<U32> max_scrollable_items;
+ Optional<U32> preferred_width;
+ Optional<LLUIColor> bg_color;
+ Optional<S32> shortcut_pad;
+
+ Params()
+ : jump_key("jump_key", KEY_NONE),
+ horizontal_layout("horizontal_layout"),
+ can_tear_off("tear_off", false),
+ drop_shadow("drop_shadow", true),
+ bg_visible("bg_visible", true),
+ create_jump_keys("create_jump_keys", false),
+ bg_color("bg_color", LLUIColorTable::instance().getColor( "MenuDefaultBgColor" )),
+ scrollable("scrollable", false),
+ max_scrollable_items("max_scrollable_items", U32_MAX),
+ preferred_width("preferred_width", U32_MAX),
+ shortcut_pad("shortcut_pad")
+
+ {
+ addSynonym(bg_visible, "opaque");
+ addSynonym(bg_color, "color");
+
+ name = "menu";
+ }
+ };
+
+ // my valid children are contained in MenuRegistry
+ typedef MenuRegistry child_registry_t;
+
+ void initFromParams(const Params&);
+
+protected:
+ LLMenuGL(const LLMenuGL::Params& p);
+ friend class LLUICtrlFactory;
// let branching menu items use my protected traversal methods
friend class LLMenuItemBranchGL;
public:
- LLMenuGL( const std::string& name, const std::string& label, LLHandle<LLFloater> parent_floater = LLHandle<LLFloater>());
- LLMenuGL( const std::string& label, LLHandle<LLFloater> parent_floater = LLHandle<LLFloater>() );
virtual ~LLMenuGL( void );
- virtual LLXMLNodePtr getXML(bool save_children = true) const;
- static LLView* fromXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFactory *factory);
-
- void parseChildXML(LLXMLNodePtr child, LLView *parent, LLUICtrlFactory *factory);
+ void parseChildXML(LLXMLNodePtr child, LLView* parent);
// LLView Functionality
- virtual BOOL handleUnicodeCharHere( llwchar uni_char );
- virtual BOOL handleHover( S32 x, S32 y, MASK mask );
- virtual void draw( void );
- virtual void drawBackground(LLMenuItemGL* itemp, LLColor4& color);
- virtual void setVisible(BOOL visible);
+ /*virtual*/ BOOL handleUnicodeCharHere( llwchar uni_char );
+ /*virtual*/ BOOL handleHover( S32 x, S32 y, MASK mask );
+ /*virtual*/ BOOL handleScrollWheel( S32 x, S32 y, S32 clicks );
+ /*virtual*/ void draw( void );
+ /*virtual*/ void drawBackground(LLMenuItemGL* itemp, F32 alpha);
+ /*virtual*/ void setVisible(BOOL visible);
+ /*virtual*/ bool addChild(LLView* view, S32 tab_group = 0);
+ /*virtual*/ void removeChild( LLView* ctrl);
+ /*virtual*/ BOOL postBuild();
virtual BOOL handleAcceleratorKey(KEY key, MASK mask);
- LLMenuGL* getChildMenuByName(const std::string& name, BOOL recurse) const;
+ LLMenuGL* findChildMenuByName(const std::string& name, BOOL recurse) const;
BOOL clearHoverItem();
@@ -430,24 +445,13 @@ public:
void setLabel(const LLStringExplicit& label) { mLabel = label; }
// background colors
- static void setDefaultBackgroundColor( const LLColor4& color ) { sDefaultBackgroundColor = color; }
- void setBackgroundColor( const LLColor4& color ) { mBackgroundColor = color; }
- const LLColor4& getBackgroundColor() const { return mBackgroundColor; }
+ void setBackgroundColor( const LLUIColor& color ) { mBackgroundColor = color; }
+ const LLUIColor& getBackgroundColor() const { return mBackgroundColor; }
void setBackgroundVisible( BOOL b ) { mBgVisible = b; }
void setCanTearOff(BOOL tear_off, LLHandle<LLFloater> parent_floater_handle = LLHandle<LLFloater>());
- // Add the menu item to this menu.
- virtual BOOL append( LLMenuItemGL* item );
-
- // *NOTE:Mani - appendNoArrange() should be removed when merging to skinning/viewer2.0
- // Its added as a fix to a viewer 1.23 bug that has already been address by skinning work.
- virtual BOOL appendNoArrange( LLMenuItemGL* item );
-
// add a separator to this menu
- virtual BOOL appendSeparator( const std::string &separator_name = LLStringUtil::null );
-
- // add a menu - this will create a cascading menu
- virtual BOOL appendMenu( LLMenuGL* menu );
+ virtual BOOL addSeparator();
// for branching menu items, bring sub menus up to root level of menu hierarchy
virtual void updateParent( LLView* parentp );
@@ -471,19 +475,17 @@ public:
virtual BOOL isOpen();
+ void needsArrange() { mNeedsArrange = TRUE; }
// Shape this menu to fit the current state of the children, and
// adjust the child rects to fit. This is called automatically
// when you add items. *FIX: We may need to deal with visibility
// arrangement.
virtual void arrange( void );
+ void arrangeAndClear( void );
// remove all items on the menu
void empty( void );
- // Rearrange the components, and do the right thing if the menu doesn't
- // fit in the bounds.
- // virtual void arrangeWithBounds(LLRect bounds);
-
void setItemLastSelected(LLMenuItemGL* item); // must be in menu
U32 getItemCount(); // number of menu items
LLMenuItemGL* getItem(S32 number); // 0 = first item
@@ -495,17 +497,14 @@ public:
void buildDrawLabels();
void createJumpKeys();
- // Show popup in global screen space based on last mouse location.
- static void showPopup(LLMenuGL* menu);
-
// Show popup at a specific location.
static void showPopup(LLView* spawning_view, LLMenuGL* menu, S32 x, S32 y);
// Whether to drop shadow menu bar
void setDropShadowed( const BOOL shadowed );
- void setParentMenuItem( LLMenuItemGL* parent_menu_item ) { mParentMenuItem = parent_menu_item; }
- LLMenuItemGL* getParentMenuItem() const { return mParentMenuItem; }
+ void setParentMenuItem( LLMenuItemGL* parent_menu_item ) { mParentMenuItem = parent_menu_item->getHandle(); }
+ LLMenuItemGL* getParentMenuItem() const { return dynamic_cast<LLMenuItemGL*>(mParentMenuItem.get()); }
void setTornOff(BOOL torn_off);
BOOL getTornOff() { return mTornOff; }
@@ -518,41 +517,64 @@ public:
static void setKeyboardMode(BOOL mode) { sKeyboardMode = mode; }
static BOOL getKeyboardMode() { return sKeyboardMode; }
+ S32 getShortcutPad() { return mShortcutPad; }
+
+ void scrollItemsUp();
+ void scrollItemsDown();
+ BOOL isScrollable() const { return mScrollable; }
+
static class LLMenuHolderGL* sMenuContainer;
protected:
void createSpilloverBranch();
void cleanupSpilloverBranch();
+ // Add the menu item to this menu.
+ virtual BOOL append( LLMenuItemGL* item );
+
+ // add a menu - this will create a cascading menu
+ virtual BOOL appendMenu( LLMenuGL* menu );
// TODO: create accessor methods for these?
typedef std::list< LLMenuItemGL* > item_list_t;
item_list_t mItems;
+ LLMenuItemGL*mFirstVisibleItem;
+ LLMenuItemGL *mArrowUpItem, *mArrowDownItem;
+
typedef std::map<KEY, LLMenuItemGL*> navigation_key_map_t;
navigation_key_map_t mJumpKeys;
S32 mLastMouseX;
S32 mLastMouseY;
S32 mMouseVelX;
S32 mMouseVelY;
+ U32 mMaxScrollableItems;
+ U32 mPreferredWidth;
BOOL mHorizontalLayout;
+ BOOL mScrollable;
BOOL mKeepFixedSize;
+ BOOL mNeedsArrange;
private:
+
+
static LLColor4 sDefaultBackgroundColor;
static BOOL sKeyboardMode;
- LLColor4 mBackgroundColor;
+ LLUIColor mBackgroundColor;
BOOL mBgVisible;
- LLMenuItemGL* mParentMenuItem;
+ LLHandle<LLView> mParentMenuItem;
LLUIString mLabel;
BOOL mDropShadowed; // Whether to drop shadow
BOOL mHasSelection;
LLFrameTimer mFadeTimer;
+ LLTimer mScrollItemsTimer;
BOOL mTornOff;
class LLMenuItemTearOffGL* mTearOffItem;
class LLMenuItemBranchGL* mSpilloverBranch;
LLMenuGL* mSpilloverMenu;
LLHandle<LLFloater> mParentFloaterHandle;
KEY mJumpKey;
+ BOOL mCreateJumpKeys;
+ S32 mShortcutPad;
}; // end class LLMenuGL
@@ -567,15 +589,17 @@ private:
class LLMenuItemBranchGL : public LLMenuItemGL
{
public:
- LLMenuItemBranchGL( const std::string& name, const std::string& label, LLHandle<LLView> branch,
- KEY key = KEY_NONE, MASK mask = MASK_NONE );
+ struct Params : public LLInitParam::Block<Params, LLMenuItemGL::Params>
+ {
+ Optional<LLMenuGL*> branch;
+ };
+protected:
+ LLMenuItemBranchGL(const Params&);
+ friend class LLUICtrlFactory;
+public:
virtual ~LLMenuItemBranchGL();
-
- virtual LLXMLNodePtr getXML(bool save_children = true) const;
-
- virtual std::string getType() const { return "menu"; }
-
+
virtual BOOL handleMouseUp(S32 x, S32 y, MASK mask);
virtual BOOL handleAcceleratorKey(KEY key, MASK mask);
@@ -586,8 +610,7 @@ public:
// called to rebuild the draw label
virtual void buildDrawLabel( void );
- // doIt() - do the primary funcationality of the menu item.
- virtual void doIt( void );
+ virtual void onCommit( void );
virtual BOOL handleKey(KEY key, MASK mask, BOOL called_from_parent);
virtual BOOL handleUnicodeChar(llwchar uni_char, BOOL called_from_parent);
@@ -598,90 +621,79 @@ public:
virtual BOOL handleKeyHere(KEY key, MASK mask);
- virtual BOOL isActive() const { return isOpen() && getBranch()->getHighlightedItem(); }
+ virtual BOOL isActive() const;
- virtual BOOL isOpen() const { return getBranch() && getBranch()->isOpen(); }
+ virtual BOOL isOpen() const;
- LLMenuGL *getBranch() const { return (LLMenuGL*)(mBranch.get()); }
+ LLMenuGL* getBranch() const { return (LLMenuGL*)mBranchHandle.get(); }
virtual void updateBranchParent( LLView* parentp );
// LLView Functionality
- virtual void onVisibilityChange( BOOL curVisibilityIn );
+ virtual void handleVisibilityChange( BOOL curVisibilityIn );
virtual void draw();
- virtual void setEnabledSubMenus(BOOL enabled) { if(getBranch()) getBranch()->setEnabledSubMenus(enabled); }
+ virtual void setEnabledSubMenus(BOOL enabled) { if (getBranch()) getBranch()->setEnabledSubMenus(enabled); }
virtual void openMenu();
- virtual LLView* getChildView(const std::string& name, BOOL recurse = TRUE, BOOL create_if_missing = TRUE) const;
+ virtual LLView* getChildView(const std::string& name, BOOL recurse = TRUE) const;
+ virtual LLView* findChildView(const std::string& name, BOOL recurse = TRUE) const;
private:
- LLHandle<LLView> mBranch;
+ LLHandle<LLView> mBranchHandle;
}; // end class LLMenuItemBranchGL
-
//-----------------------------------------------------------------------------
-// class LLPieMenu
-// A circular menu of items, icons, etc.
+// class LLContextMenu
+// A context menu
//-----------------------------------------------------------------------------
-class LLPieMenu
+class LLContextMenu
: public LLMenuGL
{
public:
- LLPieMenu(const std::string& name, const std::string& label);
- LLPieMenu(const std::string& name);
- virtual ~LLPieMenu() {}
+ struct Params : public LLInitParam::Block<Params, LLMenuGL::Params>
+ {
+ Params()
+ {
+ visible = false;
+ }
+ };
- void initXML(LLXMLNodePtr node, LLView *context, LLUICtrlFactory *factory);
+protected:
+ LLContextMenu(const Params& p);
+ friend class LLUICtrlFactory;
+
+public:
+ virtual ~LLContextMenu() {}
// LLView Functionality
// can't set visibility directly, must call show or hide
- virtual void setVisible(BOOL visible);
+ virtual void setVisible (BOOL visible);
- virtual BOOL handleHover( S32 x, S32 y, MASK mask );
- virtual BOOL handleMouseDown( S32 x, S32 y, MASK mask );
- virtual BOOL handleRightMouseDown(S32 x, S32 y, MASK mask);
- virtual BOOL handleRightMouseUp( S32 x, S32 y, MASK mask );
- virtual BOOL handleMouseUp( S32 x, S32 y, MASK mask );
- virtual void draw();
- virtual void drawBackground(LLMenuItemGL* itemp, LLColor4& color);
-
- virtual BOOL append(LLMenuItemGL* item);
- virtual BOOL appendSeparator( const std::string &separator_name = LLStringUtil::null );
+ virtual void draw ();
+
+ virtual void show (S32 x, S32 y);
+ virtual void hide ();
- BOOL appendPieMenu(LLPieMenu *menu);
+ virtual BOOL handleHover ( S32 x, S32 y, MASK mask );
+ virtual BOOL handleRightMouseDown( S32 x, S32 y, MASK mask );
+ virtual BOOL handleRightMouseUp ( S32 x, S32 y, MASK mask );
- virtual void arrange( void );
+ virtual bool addChild (LLView* view, S32 tab_group = 0);
- // Display the menu centered on this point on the screen.
- void show(S32 x, S32 y, BOOL mouse_down);
- void hide(BOOL item_selected);
+ BOOL appendContextSubMenu(LLContextMenu *menu);
-private:
- LLMenuItemGL *pieItemFromXY(S32 x, S32 y);
- S32 pieItemIndexFromXY(S32 x, S32 y);
-
- // These cause menu items to be spuriously selected by right-clicks
- // near the window edge at low frame rates. I don't think they are
- // needed unless you shift the menu position in the draw() function. JC
- //S32 mShiftHoriz; // non-zero if menu had to shift this frame
- //S32 mShiftVert; // non-zero if menu had to shift this frame
- BOOL mFirstMouseDown; // true from show until mouse up
- BOOL mUseInfiniteRadius; // allow picking pie menu items anywhere outside of center circle
- LLMenuItemGL* mHoverItem;
- BOOL mHoverThisFrame;
+protected:
BOOL mHoveredAnyItem;
- LLFrameTimer mShrinkBorderTimer;
- F32 mOuterRingAlpha; // for rendering pie menus as both bounded and unbounded
- F32 mCurRadius;
- BOOL mRightMouseDown;
+ LLMenuItemGL* mHoverItem;
};
+
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Class LLMenuBarGL
//
@@ -691,28 +703,30 @@ private:
class LLMenuBarGL : public LLMenuGL
{
public:
- LLMenuBarGL( const std::string& name );
+ struct Params : public LLInitParam::Block<Params, LLMenuGL::Params>
+ {
+ Params()
+ {
+ can_tear_off = false;
+ keep_fixed_size = true;
+ horizontal_layout = true;
+ visible = true;
+ drop_shadow = false;
+ }
+ };
+ LLMenuBarGL( const Params& p );
virtual ~LLMenuBarGL();
- virtual LLXMLNodePtr getXML(bool save_children = true) const;
- static LLView* fromXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFactory *factory);
- virtual BOOL handleAcceleratorKey(KEY key, MASK mask);
- virtual BOOL handleKeyHere(KEY key, MASK mask);
- virtual BOOL handleJumpKey(KEY key);
- virtual BOOL handleMouseDown(S32 x, S32 y, MASK mask);
- virtual BOOL handleRightMouseDown(S32 x, S32 y, MASK mask);
+ /*virtual*/ BOOL handleAcceleratorKey(KEY key, MASK mask);
+ /*virtual*/ BOOL handleKeyHere(KEY key, MASK mask);
+ /*virtual*/ BOOL handleJumpKey(KEY key);
+ /*virtual*/ BOOL handleMouseDown(S32 x, S32 y, MASK mask);
- // rearrange the child rects so they fit the shape of the menu
- // bar.
- virtual void arrange( void );
- virtual void draw();
- virtual BOOL jumpKeysActive();
+ /*virtual*/ void draw();
+ /*virtual*/ BOOL jumpKeysActive();
// add a vertical separator to this menu
- virtual BOOL appendSeparator( const std::string &separator_name = LLStringUtil::null );
-
- // add a menu - this will create a drop down menu.
- virtual BOOL appendMenu( LLMenuGL* menu );
+ virtual BOOL addSeparator();
// LLView Functionality
virtual BOOL handleHover( S32 x, S32 y, MASK mask );
@@ -723,6 +737,12 @@ public:
void resetMenuTrigger() { mAltKeyTrigger = FALSE; }
private:
+ // add a menu - this will create a drop down menu.
+ virtual BOOL appendMenu( LLMenuGL* menu );
+ // rearrange the child rects so they fit the shape of the menu
+ // bar.
+ virtual void arrange( void );
+
void checkMenuTrigger();
std::list <LLKeyBinding*> mAccelerators;
@@ -738,7 +758,6 @@ class LLMenuHolderGL : public LLPanel
{
public:
LLMenuHolderGL();
- LLMenuHolderGL(const std::string& name, const LLRect& rect, BOOL mouse_opaque, U32 follows = FOLLOWS_NONE);
virtual ~LLMenuHolderGL() {}
virtual BOOL hideMenus();
@@ -750,11 +769,18 @@ public:
virtual BOOL handleMouseDown( S32 x, S32 y, MASK mask );
virtual BOOL handleRightMouseDown( S32 x, S32 y, MASK mask );
+ // Close context menus on right mouse up not handled by menus.
+ /*virtual*/ BOOL handleRightMouseUp( S32 x, S32 y, MASK mask );
+
virtual const LLRect getMenuRect() const { return getLocalRect(); }
virtual BOOL hasVisibleMenu() const;
static void setActivatedItem(LLMenuItemGL* item);
+ // Need to detect if mouse-up after context menu spawn has moved.
+ // If not, need to keep the menu up.
+ static LLCoordGL sContextMenuSpawnPos;
+
private:
static LLHandle<LLView> sItemLastSelectedHandle;
static LLFrameTimer sItemActivationTimer;
@@ -772,8 +798,8 @@ class LLTearOffMenu : public LLFloater
{
public:
static LLTearOffMenu* create(LLMenuGL* menup);
- virtual ~LLTearOffMenu() {}
- virtual void onClose(bool app_quitting);
+ virtual ~LLTearOffMenu();
+
virtual void draw(void);
virtual void onFocusReceived();
virtual void onFocusLost();
@@ -783,7 +809,9 @@ public:
private:
LLTearOffMenu(LLMenuGL* menup);
-
+
+ void closeTearOff();
+
LLView* mOldParent;
LLMenuGL* mMenu;
F32 mTargetHeight;
@@ -798,11 +826,19 @@ private:
class LLMenuItemTearOffGL : public LLMenuItemGL
{
public:
- LLMenuItemTearOffGL( LLHandle<LLFloater> parent_floater_handle = LLHandle<LLFloater>());
-
- virtual std::string getType() const { return "tearoff_menu"; }
-
- virtual void doIt(void);
+ struct Params : public LLInitParam::Block<Params, LLMenuItemGL::Params>
+ {
+ Optional<LLHandle<LLFloater> > parent_floater_handle;
+ Params()
+ {
+ name = "tear off";
+ label = "~~~~~~~~~~~";
+ }
+ };
+
+ LLMenuItemTearOffGL( const Params& );
+
+ virtual void onCommit(void);
virtual void draw(void);
virtual U32 getNominalHeight() const;
@@ -824,4 +860,31 @@ private:
LLEditMenuHandlerMgr() {};
};
+
+// *TODO: Eliminate
+// For backwards compatability only; generally just use boost::bind
+class view_listener_t : public boost::signals2::trackable
+{
+public:
+ virtual bool handleEvent(const LLSD& userdata) = 0;
+ virtual ~view_listener_t() {}
+
+ static void addEnable(view_listener_t* listener, const std::string& name)
+ {
+ LLUICtrl::EnableCallbackRegistry::currentRegistrar().add(name, boost::bind(&view_listener_t::handleEvent, listener, _2));
+ }
+
+ static void addCommit(view_listener_t* listener, const std::string& name)
+ {
+ LLUICtrl::CommitCallbackRegistry::currentRegistrar().add(name, boost::bind(&view_listener_t::handleEvent, listener, _2));
+ }
+
+ static void addMenu(view_listener_t* listener, const std::string& name)
+ {
+ // For now, add to both click and enable registries
+ addEnable(listener, name);
+ addCommit(listener, name);
+ }
+};
+
#endif // LL_LLMENUGL_H
diff --git a/indra/llui/llmodaldialog.cpp b/indra/llui/llmodaldialog.cpp
index 1662ff7db6..f77ec5f4c7 100644
--- a/indra/llui/llmodaldialog.cpp
+++ b/indra/llui/llmodaldialog.cpp
@@ -44,22 +44,20 @@
// static
std::list<LLModalDialog*> LLModalDialog::sModalStack;
-LLModalDialog::LLModalDialog( const std::string& title, S32 width, S32 height, BOOL modal )
- : LLFloater( std::string("modal container"),
- LLRect( 0, height, width, 0 ),
- title,
- FALSE, // resizable
- DEFAULT_MIN_WIDTH, DEFAULT_MIN_HEIGHT,
- FALSE, // drag_on_left
- modal ? FALSE : TRUE, // minimizable
- modal ? FALSE : TRUE, // close button
- TRUE), // bordered
+LLModalDialog::LLModalDialog( const LLSD& key, BOOL modal )
+ : LLFloater(key),
mModal( modal )
{
+ if (modal)
+ {
+ setCanMinimize(FALSE);
+ setCanClose(FALSE);
+ }
setVisible( FALSE );
setBackgroundVisible(TRUE);
setBackgroundOpaque(TRUE);
centerOnScreen(); // default position
+ mCloseSignal.connect(boost::bind(&LLModalDialog::stopModal, this));
}
LLModalDialog::~LLModalDialog()
@@ -69,15 +67,27 @@ LLModalDialog::~LLModalDialog()
{
gFocusMgr.unlockFocus();
}
+
+ std::list<LLModalDialog*>::iterator iter = std::find(sModalStack.begin(), sModalStack.end(), this);
+ if (iter != sModalStack.end())
+ {
+ llerrs << "Attempt to delete dialog while still in sModalStack!" << llendl;
+ }
+}
+
+// virtual
+BOOL LLModalDialog::postBuild()
+{
+ return LLFloater::postBuild();
}
// virtual
-void LLModalDialog::open() /* Flawfinder: ignore */
+void LLModalDialog::openFloater(const LLSD& key)
{
// SJB: Hack! Make sure we don't ever host a modal dialog
LLMultiFloater* thost = LLFloater::getFloaterHost();
LLFloater::setFloaterHost(NULL);
- LLFloater::open();
+ LLFloater::openFloater(key);
LLFloater::setFloaterHost(thost);
}
@@ -87,7 +97,8 @@ void LLModalDialog::reshape(S32 width, S32 height, BOOL called_from_parent)
centerOnScreen();
}
-void LLModalDialog::startModal()
+// virtual
+void LLModalDialog::onOpen(const LLSD& key)
{
if (mModal)
{
@@ -105,8 +116,6 @@ void LLModalDialog::startModal()
sModalStack.push_front( this );
}
-
- setVisible( TRUE );
}
void LLModalDialog::stopModal()
@@ -229,48 +238,25 @@ BOOL LLModalDialog::handleKeyHere(KEY key, MASK mask )
BOOL enough_time_elapsed = mVisibleTime.getElapsedTimeF32() > 1.0f;
if (enough_time_elapsed && key == KEY_ESCAPE)
{
- close();
+ closeFloater();
return TRUE;
}
return FALSE;
}
}
-void LLModalDialog::onClose(bool app_quitting)
-{
- stopModal();
- LLFloater::onClose(app_quitting);
-}
-
// virtual
void LLModalDialog::draw()
{
- LLColor4 shadow_color = LLUI::sColorsGroup->getColor("ColorDropShadow");
- S32 shadow_lines = LLUI::sConfigGroup->getS32("DropShadowFloater");
+ static LLUIColor shadow_color = LLUIColorTable::instance().getColor("ColorDropShadow");
+ static LLUICachedControl<S32> shadow_lines ("DropShadowFloater", 0);
gl_drop_shadow( 0, getRect().getHeight(), getRect().getWidth(), 0,
shadow_color, shadow_lines);
LLFloater::draw();
-
- if (mModal)
- {
- // If we've lost focus to a non-child, get it back ASAP.
- if( gFocusMgr.getTopCtrl() != this )
- {
- gFocusMgr.setTopCtrl( this );
- }
-
- if( !gFocusMgr.childHasKeyboardFocus( this ) )
- {
- setFocus(TRUE);
- }
-
- if( !gFocusMgr.childHasMouseCapture( this ) )
- {
- gFocusMgr.setMouseCapture( this );
- }
- }
+
+ // Focus retrieval moved to LLFloaterView::refresh()
}
void LLModalDialog::centerOnScreen()
@@ -291,10 +277,7 @@ void LLModalDialog::onAppFocusLost()
gFocusMgr.setMouseCapture( NULL );
}
- if( gFocusMgr.childHasKeyboardFocus( instance ) )
- {
- gFocusMgr.setKeyboardFocus( NULL );
- }
+ instance->setFocus(FALSE);
}
}
diff --git a/indra/llui/llmodaldialog.h b/indra/llui/llmodaldialog.h
index f6abd0a7ac..9d716a1880 100644
--- a/indra/llui/llmodaldialog.h
+++ b/indra/llui/llmodaldialog.h
@@ -45,16 +45,16 @@ class LLModalDialog;
class LLModalDialog : public LLFloater
{
public:
- LLModalDialog( const std::string& title, S32 width, S32 height, BOOL modal = true );
+ LLModalDialog( const LLSD& key, BOOL modal = true );
/*virtual*/ ~LLModalDialog();
-
- /*virtual*/ void open(); /* Flawfinder: ignore */
+
+ /*virtual*/ BOOL postBuild();
+
+ /*virtual*/ void openFloater(const LLSD& key = LLSD());
+ /*virtual*/ void onOpen(const LLSD& key);
/*virtual*/ void reshape(S32 width, S32 height, BOOL called_from_parent = TRUE);
- /*virtual*/ void startModal();
- /*virtual*/ void stopModal();
-
/*virtual*/ BOOL handleMouseDown(S32 x, S32 y, MASK mask);
/*virtual*/ BOOL handleMouseUp(S32 x, S32 y, MASK mask);
/*virtual*/ BOOL handleHover(S32 x, S32 y, MASK mask);
@@ -63,12 +63,11 @@ public:
/*virtual*/ BOOL handleRightMouseDown(S32 x, S32 y, MASK mask);
/*virtual*/ BOOL handleKeyHere(KEY key, MASK mask );
- /*virtual*/ void onClose(bool app_quitting);
-
/*virtual*/ void setVisible(BOOL visible);
/*virtual*/ void draw();
- BOOL isModal() const { return mModal; }
+ BOOL isModal() const { return mModal; }
+ void stopModal();
static void onAppFocusLost();
static void onAppFocusGained();
@@ -79,6 +78,7 @@ protected:
void centerOnScreen();
private:
+
LLFrameTimer mVisibleTime;
const BOOL mModal;
diff --git a/indra/llui/llmultifloater.cpp b/indra/llui/llmultifloater.cpp
new file mode 100644
index 0000000000..e8ce1a8d97
--- /dev/null
+++ b/indra/llui/llmultifloater.cpp
@@ -0,0 +1,503 @@
+/**
+ * @file llmultifloater.cpp
+ * @brief LLFloater that hosts other floaters
+ *
+ * $LicenseInfo:firstyear=2002&license=viewergpl$
+ *
+ * Copyright (c) 2002-2009, Linden Research, Inc.
+ *
+ * Second Life Viewer Source Code
+ * The source code in this file ("Source Code") is provided by Linden Lab
+ * to you under the terms of the GNU General Public License, version 2.0
+ * ("GPL"), unless you have obtained a separate licensing agreement
+ * ("Other License"), formally executed by you and Linden Lab. Terms of
+ * the GPL can be found in doc/GPL-license.txt in this distribution, or
+ * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
+ *
+ * There are special exceptions to the terms and conditions of the GPL as
+ * it is applied to this Source Code. View the full text of the exception
+ * in the file doc/FLOSS-exception.txt in this software distribution, or
+ * online at
+ * http://secondlifegrid.net/programs/open_source/licensing/flossexception
+ *
+ * By copying, modifying or distributing this software, you acknowledge
+ * that you have read and understood your obligations described above,
+ * and agree to abide by those obligations.
+ *
+ * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+ * COMPLETENESS OR PERFORMANCE.
+ * $/LicenseInfo$
+ */
+
+// Floating "windows" within the GL display, like the inventory floater,
+// mini-map floater, etc.
+
+#include "linden_common.h"
+
+#include "llmultifloater.h"
+#include "llresizehandle.h"
+
+//
+// LLMultiFloater
+//
+
+LLMultiFloater::LLMultiFloater(const LLSD& key, const LLFloater::Params& params)
+ : LLFloater(key),
+ mTabContainer(NULL),
+ mTabPos(LLTabContainer::TOP),
+ mAutoResize(TRUE),
+ mOrigMinWidth(0),
+ mOrigMinHeight(0)
+{
+}
+
+void LLMultiFloater::buildTabContainer()
+{
+ static LLUICachedControl<S32> floater_header_size ("UIFloaterHeaderSize", 0);
+
+ LLTabContainer::Params p;
+ p.name(std::string("Preview Tabs"));
+ p.rect(LLRect(LLPANEL_BORDER_WIDTH, getRect().getHeight() - floater_header_size, getRect().getWidth() - LLPANEL_BORDER_WIDTH, 0));
+ p.tab_position(mTabPos);
+ p.follows.flags(FOLLOWS_ALL);
+ p.commit_callback.function(boost::bind(&LLMultiFloater::onTabSelected, this));
+
+ mTabContainer = LLUICtrlFactory::create<LLTabContainer>(p);
+ addChild(mTabContainer);
+
+ if (isResizable())
+ {
+ mTabContainer->setRightTabBtnOffset(RESIZE_HANDLE_WIDTH);
+ }
+}
+
+void LLMultiFloater::onOpen(const LLSD& key)
+{
+// if (mTabContainer->getTabCount() <= 0)
+// {
+// // for now, don't allow multifloaters
+// // without any child floaters
+// closeFloater();
+// }
+}
+
+void LLMultiFloater::draw()
+{
+ if (mTabContainer->getTabCount() == 0)
+ {
+ //RN: could this potentially crash in draw hierarchy?
+ closeFloater();
+ }
+ else
+ {
+ for (S32 i = 0; i < mTabContainer->getTabCount(); i++)
+ {
+ LLFloater* floaterp = (LLFloater*)mTabContainer->getPanelByIndex(i);
+ if (floaterp->getShortTitle() != mTabContainer->getPanelTitle(i))
+ {
+ mTabContainer->setPanelTitle(i, floaterp->getShortTitle());
+ }
+ }
+ LLFloater::draw();
+ }
+}
+
+BOOL LLMultiFloater::closeAllFloaters()
+{
+ S32 tabToClose = 0;
+ S32 lastTabCount = mTabContainer->getTabCount();
+ while (tabToClose < mTabContainer->getTabCount())
+ {
+ LLFloater* first_floater = (LLFloater*)mTabContainer->getPanelByIndex(tabToClose);
+ first_floater->closeFloater();
+ if(lastTabCount == mTabContainer->getTabCount())
+ {
+ //Tab did not actually close, possibly due to a pending Save Confirmation dialog..
+ //so try and close the next one in the list...
+ tabToClose++;
+ }
+ else
+ {
+ //Tab closed ok.
+ lastTabCount = mTabContainer->getTabCount();
+ }
+ }
+ if( mTabContainer->getTabCount() != 0 )
+ return FALSE; // Couldn't close all the tabs (pending save dialog?) so return FALSE.
+ return TRUE; //else all tabs were successfully closed...
+}
+
+void LLMultiFloater::growToFit(S32 content_width, S32 content_height)
+{
+ static LLUICachedControl<S32> tabcntr_close_btn_size ("UITabCntrCloseBtnSize", 0);
+ static LLUICachedControl<S32> floater_header_size ("UIFloaterHeaderSize", 0);
+ S32 tabcntr_header_height = LLPANEL_BORDER_WIDTH + tabcntr_close_btn_size;
+ S32 new_width = llmax(getRect().getWidth(), content_width + LLPANEL_BORDER_WIDTH * 2);
+ S32 new_height = llmax(getRect().getHeight(), content_height + floater_header_size + tabcntr_header_height);
+
+ if (isMinimized())
+ {
+ LLRect newrect;
+ newrect.setLeftTopAndSize(getExpandedRect().mLeft, getExpandedRect().mTop, new_width, new_height);
+ setExpandedRect(newrect);
+ }
+ else
+ {
+ S32 old_height = getRect().getHeight();
+ reshape(new_width, new_height);
+ // keep top left corner in same position
+ translate(0, old_height - new_height);
+ }
+}
+
+/**
+ void addFloater(LLFloater* floaterp, BOOL select_added_floater)
+
+ Adds the LLFloater pointed to by floaterp to this.
+ If floaterp is already hosted by this, then it is re-added to get
+ new titles, etc.
+ If select_added_floater is true, the LLFloater pointed to by floaterp will
+ become the selected tab in this
+
+ Affects: mTabContainer, floaterp
+**/
+void LLMultiFloater::addFloater(LLFloater* floaterp, BOOL select_added_floater, LLTabContainer::eInsertionPoint insertion_point)
+{
+ if (!floaterp)
+ {
+ return;
+ }
+
+ if (!mTabContainer)
+ {
+ llerrs << "Tab Container used without having been initialized." << llendl;
+ return;
+ }
+
+ if (floaterp->getHost() == this)
+ {
+ // already hosted by me, remove
+ // do this so we get updated title, etc.
+ mFloaterDataMap.erase(floaterp->getHandle());
+ mTabContainer->removeTabPanel(floaterp);
+ }
+ else if (floaterp->getHost())
+ {
+ // floaterp is hosted by somebody else and
+ // this is adding it, so remove it from it's old host
+ floaterp->getHost()->removeFloater(floaterp);
+ }
+ else if (floaterp->getParent() == gFloaterView)
+ {
+ // rehost preview floater as child panel
+ gFloaterView->removeChild(floaterp);
+ }
+
+ // store original configuration
+ LLFloaterData floater_data;
+ floater_data.mWidth = floaterp->getRect().getWidth();
+ floater_data.mHeight = floaterp->getRect().getHeight();
+ floater_data.mCanMinimize = floaterp->isMinimizeable();
+ floater_data.mCanResize = floaterp->isResizable();
+
+ // remove minimize and close buttons
+ floaterp->setCanMinimize(FALSE);
+ floaterp->setCanResize(FALSE);
+ floaterp->setCanDrag(FALSE);
+ floaterp->storeRectControl();
+ // avoid double rendering of floater background (makes it more opaque)
+ floaterp->setBackgroundVisible(FALSE);
+
+ if (mAutoResize)
+ {
+ growToFit(floater_data.mWidth, floater_data.mHeight);
+ }
+
+ //add the panel, add it to proper maps
+ mTabContainer->addTabPanel(
+ LLTabContainer::TabPanelParams()
+ .panel(floaterp)
+ .label(floaterp->getShortTitle())
+ .insert_at(insertion_point));
+ mFloaterDataMap[floaterp->getHandle()] = floater_data;
+
+ updateResizeLimits();
+
+ if ( select_added_floater )
+ {
+ mTabContainer->selectTabPanel(floaterp);
+ }
+ else
+ {
+ // reassert visible tab (hiding new floater if necessary)
+ mTabContainer->selectTab(mTabContainer->getCurrentPanelIndex());
+ }
+
+ floaterp->setHost(this);
+ if (isMinimized())
+ {
+ floaterp->setVisible(FALSE);
+ }
+
+ // Tabs sometimes overlap resize handle
+ moveResizeHandlesToFront();
+}
+
+/**
+ BOOL selectFloater(LLFloater* floaterp)
+
+ If the LLFloater pointed to by floaterp is hosted by this,
+ then its tab is selected and returns true. Otherwise returns false.
+
+ Affects: mTabContainer
+**/
+BOOL LLMultiFloater::selectFloater(LLFloater* floaterp)
+{
+ return mTabContainer->selectTabPanel(floaterp);
+}
+
+// virtual
+void LLMultiFloater::selectNextFloater()
+{
+ mTabContainer->selectNextTab();
+}
+
+// virtual
+void LLMultiFloater::selectPrevFloater()
+{
+ mTabContainer->selectPrevTab();
+}
+
+void LLMultiFloater::showFloater(LLFloater* floaterp, LLTabContainer::eInsertionPoint insertion_point)
+{
+ if(!floaterp) return;
+ // we won't select a panel that already is selected
+ // it is hard to do this internally to tab container
+ // as tab selection is handled via index and the tab at a given
+ // index might have changed
+ if (floaterp != mTabContainer->getCurrentPanel() &&
+ !mTabContainer->selectTabPanel(floaterp))
+ {
+ addFloater(floaterp, TRUE, insertion_point);
+ }
+}
+
+void LLMultiFloater::removeFloater(LLFloater* floaterp)
+{
+ if (!floaterp || floaterp->getHost() != this )
+ return;
+
+ floater_data_map_t::iterator found_data_it = mFloaterDataMap.find(floaterp->getHandle());
+ if (found_data_it != mFloaterDataMap.end())
+ {
+ LLFloaterData& floater_data = found_data_it->second;
+ floaterp->setCanMinimize(floater_data.mCanMinimize);
+ if (!floater_data.mCanResize)
+ {
+ // restore original size
+ floaterp->reshape(floater_data.mWidth, floater_data.mHeight);
+ }
+ floaterp->setCanResize(floater_data.mCanResize);
+ mFloaterDataMap.erase(found_data_it);
+ }
+ mTabContainer->removeTabPanel(floaterp);
+ floaterp->setBackgroundVisible(TRUE);
+ floaterp->setCanDrag(TRUE);
+ floaterp->setHost(NULL);
+ floaterp->applyRectControl();
+
+ updateResizeLimits();
+
+ tabOpen((LLFloater*)mTabContainer->getCurrentPanel(), false);
+}
+
+void LLMultiFloater::tabOpen(LLFloater* opened_floater, bool from_click)
+{
+ // default implementation does nothing
+}
+
+void LLMultiFloater::tabClose()
+{
+ if (mTabContainer->getTabCount() == 0)
+ {
+ // no more children, close myself
+ closeFloater();
+ }
+}
+
+void LLMultiFloater::setVisible(BOOL visible)
+{
+ // *FIX: shouldn't have to do this, fix adding to minimized multifloater
+ LLFloater::setVisible(visible);
+
+ if (mTabContainer)
+ {
+ LLPanel* cur_floaterp = mTabContainer->getCurrentPanel();
+
+ if (cur_floaterp)
+ {
+ cur_floaterp->setVisible(visible);
+ }
+
+ // if no tab selected, and we're being shown,
+ // select last tab to be added
+ if (visible && !cur_floaterp)
+ {
+ mTabContainer->selectLastTab();
+ }
+ }
+}
+
+BOOL LLMultiFloater::handleKeyHere(KEY key, MASK mask)
+{
+ if (key == 'W' && mask == MASK_CONTROL)
+ {
+ LLFloater* floater = getActiveFloater();
+ // is user closeable and is system closeable
+ if (floater && floater->canClose() && floater->isCloseable())
+ {
+ floater->closeFloater();
+ }
+ return TRUE;
+ }
+
+ return LLFloater::handleKeyHere(key, mask);
+}
+
+bool LLMultiFloater::addChild(LLView* child, S32 tab_group)
+{
+ LLTabContainer* tab_container = dynamic_cast<LLTabContainer*>(child);
+ if (tab_container)
+ {
+ // store pointer to tab container
+ setTabContainer(tab_container);
+ }
+
+ // then go ahead and add child as usual
+ return LLFloater::addChild(child, tab_group);
+}
+
+LLFloater* LLMultiFloater::getActiveFloater()
+{
+ return (LLFloater*)mTabContainer->getCurrentPanel();
+}
+
+S32 LLMultiFloater::getFloaterCount()
+{
+ return mTabContainer->getTabCount();
+}
+
+/**
+ BOOL isFloaterFlashing(LLFloater* floaterp)
+
+ Returns true if the LLFloater pointed to by floaterp
+ is currently in a flashing state and is hosted by this.
+ False otherwise.
+
+ Requires: floaterp != NULL
+**/
+BOOL LLMultiFloater::isFloaterFlashing(LLFloater* floaterp)
+{
+ if ( floaterp && floaterp->getHost() == this )
+ return mTabContainer->getTabPanelFlashing(floaterp);
+
+ return FALSE;
+}
+
+/**
+ BOOL setFloaterFlashing(LLFloater* floaterp, BOOL flashing)
+
+ Sets the current flashing state of the LLFloater pointed
+ to by floaterp to be the BOOL flashing if the LLFloater pointed
+ to by floaterp is hosted by this.
+
+ Requires: floaterp != NULL
+**/
+void LLMultiFloater::setFloaterFlashing(LLFloater* floaterp, BOOL flashing)
+{
+ if ( floaterp && floaterp->getHost() == this )
+ mTabContainer->setTabPanelFlashing(floaterp, flashing);
+}
+
+void LLMultiFloater::onTabSelected()
+{
+ LLFloater* floaterp = dynamic_cast<LLFloater*>(mTabContainer->getCurrentPanel());
+ if (floaterp)
+ {
+ tabOpen(floaterp, true);
+ }
+}
+
+void LLMultiFloater::setCanResize(BOOL can_resize)
+{
+ LLFloater::setCanResize(can_resize);
+ if (isResizable() && mTabContainer->getTabPosition() == LLTabContainer::BOTTOM)
+ {
+ mTabContainer->setRightTabBtnOffset(RESIZE_HANDLE_WIDTH);
+ }
+ else
+ {
+ mTabContainer->setRightTabBtnOffset(0);
+ }
+}
+
+BOOL LLMultiFloater::postBuild()
+{
+ mCloseSignal.connect(boost::bind(&LLMultiFloater::closeAllFloaters, this));
+
+ // remember any original xml minimum size
+ getResizeLimits(&mOrigMinWidth, &mOrigMinHeight);
+
+ if (mTabContainer)
+ {
+ return TRUE;
+ }
+
+ mTabContainer = getChild<LLTabContainer>("Preview Tabs");
+ return TRUE;
+}
+
+void LLMultiFloater::updateResizeLimits()
+{
+ static LLUICachedControl<S32> tabcntr_close_btn_size ("UITabCntrCloseBtnSize", 0);
+ static LLUICachedControl<S32> floater_header_size ("UIFloaterHeaderSize", 0);
+ S32 tabcntr_header_height = LLPANEL_BORDER_WIDTH + tabcntr_close_btn_size;
+ // initialize minimum size constraint to the original xml values.
+ S32 new_min_width = mOrigMinWidth;
+ S32 new_min_height = mOrigMinHeight;
+ // possibly increase minimum size constraint due to children's minimums.
+ for (S32 tab_idx = 0; tab_idx < mTabContainer->getTabCount(); ++tab_idx)
+ {
+ LLFloater* floaterp = (LLFloater*)mTabContainer->getPanelByIndex(tab_idx);
+ if (floaterp)
+ {
+ new_min_width = llmax(new_min_width, floaterp->getMinWidth() + LLPANEL_BORDER_WIDTH * 2);
+ new_min_height = llmax(new_min_height, floaterp->getMinHeight() + floater_header_size + tabcntr_header_height);
+ }
+ }
+ setResizeLimits(new_min_width, new_min_height);
+
+ S32 cur_height = getRect().getHeight();
+ S32 new_width = llmax(getRect().getWidth(), new_min_width);
+ S32 new_height = llmax(getRect().getHeight(), new_min_height);
+
+ if (isMinimized())
+ {
+ const LLRect& expanded = getExpandedRect();
+ LLRect newrect;
+ newrect.setLeftTopAndSize(expanded.mLeft, expanded.mTop, llmax(expanded.getWidth(), new_width), llmax(expanded.getHeight(), new_height));
+ setExpandedRect(newrect);
+ }
+ else
+ {
+ reshape(new_width, new_height);
+
+ // make sure upper left corner doesn't move
+ translate(0, cur_height - getRect().getHeight());
+
+ // make sure this window is visible on screen when it has been modified
+ // (tab added, etc)
+ gFloaterView->adjustToFitScreen(this, TRUE);
+ }
+}
diff --git a/indra/llui/llmultifloater.h b/indra/llui/llmultifloater.h
new file mode 100644
index 0000000000..bbf2c56fe7
--- /dev/null
+++ b/indra/llui/llmultifloater.h
@@ -0,0 +1,106 @@
+/**
+ * @file llmultifloater.h
+ * @brief LLFloater that hosts other floaters
+ *
+ * $LicenseInfo:firstyear=2002&license=viewergpl$
+ *
+ * Copyright (c) 2002-2009, Linden Research, Inc.
+ *
+ * Second Life Viewer Source Code
+ * The source code in this file ("Source Code") is provided by Linden Lab
+ * to you under the terms of the GNU General Public License, version 2.0
+ * ("GPL"), unless you have obtained a separate licensing agreement
+ * ("Other License"), formally executed by you and Linden Lab. Terms of
+ * the GPL can be found in doc/GPL-license.txt in this distribution, or
+ * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
+ *
+ * There are special exceptions to the terms and conditions of the GPL as
+ * it is applied to this Source Code. View the full text of the exception
+ * in the file doc/FLOSS-exception.txt in this software distribution, or
+ * online at
+ * http://secondlifegrid.net/programs/open_source/licensing/flossexception
+ *
+ * By copying, modifying or distributing this software, you acknowledge
+ * that you have read and understood your obligations described above,
+ * and agree to abide by those obligations.
+ *
+ * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+ * COMPLETENESS OR PERFORMANCE.
+ * $/LicenseInfo$
+ */
+
+// Floating "windows" within the GL display, like the inventory floater,
+// mini-map floater, etc.
+
+
+#ifndef LL_MULTI_FLOATER_H
+#define LL_MULTI_FLOATER_H
+
+#include "llfloater.h"
+#include "lltabcontainer.h" // for LLTabContainer::eInsertionPoint
+
+// https://wiki.lindenlab.com/mediawiki/index.php?title=LLMultiFloater&oldid=81376
+class LLMultiFloater : public LLFloater
+{
+public:
+ LLMultiFloater(const LLSD& key, const Params& params = getDefaultParams());
+ virtual ~LLMultiFloater() {};
+
+ void buildTabContainer();
+
+ virtual BOOL postBuild();
+ /*virtual*/ void onOpen(const LLSD& key);
+ /*virtual*/ void draw();
+ /*virtual*/ void setVisible(BOOL visible);
+ /*virtual*/ BOOL handleKeyHere(KEY key, MASK mask);
+ /*virtual*/ bool addChild(LLView* view, S32 tab_group = 0);
+
+ virtual void setCanResize(BOOL can_resize);
+ virtual void growToFit(S32 content_width, S32 content_height);
+ virtual void addFloater(LLFloater* floaterp, BOOL select_added_floater, LLTabContainer::eInsertionPoint insertion_point = LLTabContainer::END);
+
+ virtual void showFloater(LLFloater* floaterp, LLTabContainer::eInsertionPoint insertion_point = LLTabContainer::END);
+ virtual void removeFloater(LLFloater* floaterp);
+
+ virtual void tabOpen(LLFloater* opened_floater, bool from_click);
+ virtual void tabClose();
+
+ virtual BOOL selectFloater(LLFloater* floaterp);
+ virtual void selectNextFloater();
+ virtual void selectPrevFloater();
+
+ virtual LLFloater* getActiveFloater();
+ virtual BOOL isFloaterFlashing(LLFloater* floaterp);
+ virtual S32 getFloaterCount();
+
+ virtual void setFloaterFlashing(LLFloater* floaterp, BOOL flashing);
+ virtual BOOL closeAllFloaters(); //Returns FALSE if the floater could not be closed due to pending confirmation dialogs
+ void setTabContainer(LLTabContainer* tab_container) { if (!mTabContainer) mTabContainer = tab_container; }
+ void onTabSelected();
+
+ virtual void updateResizeLimits();
+
+protected:
+ struct LLFloaterData
+ {
+ S32 mWidth;
+ S32 mHeight;
+ BOOL mCanMinimize;
+ BOOL mCanResize;
+ };
+
+ LLTabContainer* mTabContainer;
+
+ typedef std::map<LLHandle<LLFloater>, LLFloaterData> floater_data_map_t;
+ floater_data_map_t mFloaterDataMap;
+
+ LLTabContainer::TabPosition mTabPos;
+ BOOL mAutoResize;
+ S32 mOrigMinWidth, mOrigMinHeight; // logically const but initialized late
+};
+
+#endif // LL_MULTI_FLOATER_H
+
+
+
diff --git a/indra/llui/llmultislider.cpp b/indra/llui/llmultislider.cpp
index c1487be553..68e496aed1 100644
--- a/indra/llui/llmultislider.cpp
+++ b/indra/llui/llmultislider.cpp
@@ -40,65 +40,59 @@
#include "llfocusmgr.h"
#include "llkeyboard.h" // for the MASK constants
#include "llcontrol.h"
-#include "llimagegl.h"
+#include "lluictrlfactory.h"
#include <sstream>
-static LLRegisterWidget<LLMultiSlider> r("multi_slider_bar");
+static LLDefaultChildRegistry::Register<LLMultiSlider> r("multi_slider_bar");
-const S32 MULTI_THUMB_WIDTH = 8;
-const S32 MULTI_TRACK_HEIGHT = 6;
const F32 FLOAT_THRESHOLD = 0.00001f;
-const S32 EXTRA_TRIANGLE_WIDTH = 2;
-const S32 EXTRA_TRIANGLE_HEIGHT = -2;
S32 LLMultiSlider::mNameCounter = 0;
-LLMultiSlider::LLMultiSlider(
- const std::string& name,
- const LLRect& rect,
- void (*on_commit_callback)(LLUICtrl* ctrl, void* userdata),
- void* callback_userdata,
- F32 initial_value,
- F32 min_value,
- F32 max_value,
- F32 increment,
- S32 max_sliders,
- BOOL allow_overlap,
- BOOL draw_track,
- BOOL use_triangle,
- const std::string& control_name)
- :
- LLUICtrl( name, rect, TRUE, on_commit_callback, callback_userdata,
- FOLLOWS_LEFT | FOLLOWS_TOP),
-
- mInitialValue( initial_value ),
- mMinValue( min_value ),
- mMaxValue( max_value ),
- mIncrement( increment ),
- mMaxNumSliders(max_sliders),
- mAllowOverlap(allow_overlap),
- mDrawTrack(draw_track),
- mUseTriangle(use_triangle),
+LLMultiSlider::Params::Params()
+: max_sliders("max_sliders", 1),
+ allow_overlap("allow_overlap", false),
+ draw_track("draw_track", true),
+ use_triangle("use_triangle", false),
+ track_color("track_color"),
+ thumb_disabled_color("thumb_disabled_color"),
+ thumb_outline_color("thumb_outline_color"),
+ thumb_center_color("thumb_center_color"),
+ thumb_center_selected_color("thumb_center_selected_color"),
+ triangle_color("triangle_color"),
+ mouse_down_callback("mouse_down_callback"),
+ mouse_up_callback("mouse_up_callback"),
+ thumb_width("thumb_width")
+{
+ name = "multi_slider_bar";
+ mouse_opaque(true);
+ follows.flags(FOLLOWS_LEFT | FOLLOWS_TOP);
+}
+
+LLMultiSlider::LLMultiSlider(const LLMultiSlider::Params& p)
+: LLF32UICtrl(p),
mMouseOffset( 0 ),
- mDragStartThumbRect( 0, getRect().getHeight(), MULTI_THUMB_WIDTH, 0 ),
- mTrackColor( LLUI::sColorsGroup->getColor( "MultiSliderTrackColor" ) ),
- mThumbOutlineColor( LLUI::sColorsGroup->getColor( "MultiSliderThumbOutlineColor" ) ),
- mThumbCenterColor( LLUI::sColorsGroup->getColor( "MultiSliderThumbCenterColor" ) ),
- mThumbCenterSelectedColor( LLUI::sColorsGroup->getColor( "MultiSliderThumbCenterSelectedColor" ) ),
- mDisabledThumbColor(LLUI::sColorsGroup->getColor( "MultiSliderDisabledThumbColor" ) ),
- mTriangleColor(LLUI::sColorsGroup->getColor( "MultiSliderTriangleColor" ) ),
- mMouseDownCallback( NULL ),
- mMouseUpCallback( NULL )
+ mDragStartThumbRect( 0, getRect().getHeight(), p.thumb_width, 0 ),
+ mMaxNumSliders(p.max_sliders),
+ mAllowOverlap(p.allow_overlap),
+ mDrawTrack(p.draw_track),
+ mUseTriangle(p.use_triangle),
+ mTrackColor(p.track_color()),
+ mThumbOutlineColor(p.thumb_outline_color()),
+ mThumbCenterColor(p.thumb_center_color()),
+ mThumbCenterSelectedColor(p.thumb_center_selected_color()),
+ mDisabledThumbColor(p.thumb_disabled_color()),
+ mTriangleColor(p.triangle_color()),
+ mThumbWidth(p.thumb_width)
{
mValue.emptyMap();
mCurSlider = LLStringUtil::null;
-
- // properly handle setting the starting thumb rect
- // do it this way to handle both the operating-on-settings
- // and standalone ways of using this
- setControlName(control_name, NULL);
- setValue(getValue());
+
+ if (p.mouse_down_callback.isProvided())
+ initCommitCallback(p.mouse_down_callback, mMouseDownSignal);
+ if (p.mouse_up_callback.isProvided())
+ initCommitCallback(p.mouse_up_callback, mMouseUpSignal);
}
void LLMultiSlider::setSliderValue(const std::string& name, F32 value, BOOL from_event)
@@ -152,12 +146,12 @@ void LLMultiSlider::setSliderValue(const std::string& name, F32 value, BOOL from
F32 t = (newValue - mMinValue) / (mMaxValue - mMinValue);
- S32 left_edge = MULTI_THUMB_WIDTH/2;
- S32 right_edge = getRect().getWidth() - (MULTI_THUMB_WIDTH/2);
+ S32 left_edge = mThumbWidth/2;
+ S32 right_edge = getRect().getWidth() - (mThumbWidth/2);
S32 x = left_edge + S32( t * (right_edge - left_edge) );
- mThumbRects[name].mLeft = x - (MULTI_THUMB_WIDTH/2);
- mThumbRects[name].mRight = x + (MULTI_THUMB_WIDTH/2);
+ mThumbRects[name].mLeft = x - (mThumbWidth/2);
+ mThumbRects[name].mRight = x + (mThumbWidth/2);
}
void LLMultiSlider::setValue(const LLSD& value)
@@ -211,7 +205,7 @@ const std::string& LLMultiSlider::addSlider(F32 val)
}
// add a new thumb rect
- mThumbRects[newName.str()] = LLRect( 0, getRect().getHeight(), MULTI_THUMB_WIDTH, 0 );
+ mThumbRects[newName.str()] = LLRect( 0, getRect().getHeight(), mThumbWidth, 0 );
// add the value and set the current slider to this one
mValue.insert(newName.str(), initVal);
@@ -295,15 +289,15 @@ void LLMultiSlider::clear()
deleteCurSlider();
}
- LLUICtrl::clear();
+ LLF32UICtrl::clear();
}
BOOL LLMultiSlider::handleHover(S32 x, S32 y, MASK mask)
{
if( gFocusMgr.getMouseCapture() == this )
{
- S32 left_edge = MULTI_THUMB_WIDTH/2;
- S32 right_edge = getRect().getWidth() - (MULTI_THUMB_WIDTH/2);
+ S32 left_edge = mThumbWidth/2;
+ S32 right_edge = getRect().getWidth() - (mThumbWidth/2);
x += mMouseOffset;
x = llclamp( x, left_edge, right_edge );
@@ -331,10 +325,8 @@ BOOL LLMultiSlider::handleMouseUp(S32 x, S32 y, MASK mask)
{
gFocusMgr.setMouseCapture( NULL );
- if( mMouseUpCallback )
- {
- mMouseUpCallback( this, mCallbackUserData );
- }
+ mMouseUpSignal( this, LLSD() );
+
handled = TRUE;
make_ui_sound("UISndClickRelease");
}
@@ -353,10 +345,7 @@ BOOL LLMultiSlider::handleMouseDown(S32 x, S32 y, MASK mask)
{
setFocus(TRUE);
}
- if( mMouseDownCallback )
- {
- mMouseDownCallback( this, mCallbackUserData );
- }
+ mMouseDownSignal( this, LLSD() );
if (MASK_CONTROL & mask) // if CTRL is modifying
{
@@ -379,7 +368,7 @@ BOOL LLMultiSlider::handleMouseDown(S32 x, S32 y, MASK mask)
// Find the offset of the actual mouse location from the center of the thumb.
if (mThumbRects[mCurSlider].pointInRect(x,y))
{
- mMouseOffset = (mThumbRects[mCurSlider].mLeft + MULTI_THUMB_WIDTH/2) - x;
+ mMouseOffset = (mThumbRects[mCurSlider].mLeft + mThumbWidth/2) - x;
}
else
{
@@ -424,6 +413,8 @@ BOOL LLMultiSlider::handleKeyHere(KEY key, MASK mask)
void LLMultiSlider::draw()
{
+ static LLUICachedControl<S32> extra_triangle_height ("UIExtraTriangleHeight", 0);
+ static LLUICachedControl<S32> extra_triangle_width ("UIExtraTriangleWidth", 0);
LLColor4 curThumbColor;
std::map<std::string, LLRect>::iterator mIt;
@@ -439,16 +430,17 @@ void LLMultiSlider::draw()
F32 opacity = getEnabled() ? 1.f : 0.3f;
// Track
- LLUIImagePtr thumb_imagep = LLUI::sImageProvider->getUIImage("rounded_square.tga");
+ LLUIImagePtr thumb_imagep = LLUI::getUIImage("rounded_square.tga");
- S32 height_offset = (getRect().getHeight() - MULTI_TRACK_HEIGHT) / 2;
+ static LLUICachedControl<S32> multi_track_height ("UIMultiTrackHeight", 0);
+ S32 height_offset = (getRect().getHeight() - multi_track_height) / 2;
LLRect track_rect(0, getRect().getHeight() - height_offset, getRect().getWidth(), height_offset );
if(mDrawTrack)
{
track_rect.stretch(-1);
- thumb_imagep->draw(track_rect, mTrackColor % opacity);
+ thumb_imagep->draw(track_rect, mTrackColor.get() % opacity);
}
// if we're supposed to use a drawn triangle
@@ -458,13 +450,13 @@ void LLMultiSlider::draw()
for(mIt = mThumbRects.begin(); mIt != mThumbRects.end(); mIt++) {
gl_triangle_2d(
- mIt->second.mLeft - EXTRA_TRIANGLE_WIDTH,
- mIt->second.mTop + EXTRA_TRIANGLE_HEIGHT,
- mIt->second.mRight + EXTRA_TRIANGLE_WIDTH,
- mIt->second.mTop + EXTRA_TRIANGLE_HEIGHT,
+ mIt->second.mLeft - extra_triangle_width,
+ mIt->second.mTop + extra_triangle_height,
+ mIt->second.mRight + extra_triangle_width,
+ mIt->second.mTop + extra_triangle_height,
mIt->second.mLeft + mIt->second.getWidth() / 2,
- mIt->second.mBottom - EXTRA_TRIANGLE_HEIGHT,
- mTriangleColor, TRUE);
+ mIt->second.mBottom - extra_triangle_height,
+ mTriangleColor.get(), TRUE);
}
}
else if (!thumb_imagep)
@@ -474,7 +466,7 @@ void LLMultiSlider::draw()
for(mIt = mThumbRects.begin(); mIt != mThumbRects.end(); mIt++) {
// choose the color
- curThumbColor = mThumbCenterColor;
+ curThumbColor = mThumbCenterColor.get();
if(mIt->first == mCurSlider) {
curSldrIt = mIt;
@@ -488,19 +480,19 @@ void LLMultiSlider::draw()
// now draw the current slider
if(curSldrIt != mThumbRects.end()) {
- gl_rect_2d(curSldrIt->second, mThumbCenterSelectedColor, TRUE);
+ gl_rect_2d(curSldrIt->second, mThumbCenterSelectedColor.get(), TRUE);
}
// and draw the drag start
if (gFocusMgr.getMouseCapture() == this)
{
- gl_rect_2d(mDragStartThumbRect, mThumbCenterColor % opacity, FALSE);
+ gl_rect_2d(mDragStartThumbRect, mThumbCenterColor.get() % opacity, FALSE);
}
}
else if( gFocusMgr.getMouseCapture() == this )
{
// draw drag start
- thumb_imagep->drawSolid(mDragStartThumbRect, mThumbCenterColor % 0.3f);
+ thumb_imagep->drawSolid(mDragStartThumbRect, mThumbCenterColor.get() % 0.3f);
// draw the highlight
if (hasFocus())
@@ -513,7 +505,7 @@ void LLMultiSlider::draw()
for(mIt = mThumbRects.begin(); mIt != mThumbRects.end(); mIt++)
{
// choose the color
- curThumbColor = mThumbCenterColor;
+ curThumbColor = mThumbCenterColor.get();
if(mIt->first == mCurSlider)
{
// don't draw now, draw last
@@ -528,7 +520,7 @@ void LLMultiSlider::draw()
// draw cur slider last
if(curSldrIt != mThumbRects.end())
{
- thumb_imagep->drawSolid(curSldrIt->second, mThumbCenterSelectedColor);
+ thumb_imagep->drawSolid(curSldrIt->second, mThumbCenterSelectedColor.get());
}
}
@@ -546,7 +538,7 @@ void LLMultiSlider::draw()
{
// choose the color
- curThumbColor = mThumbCenterColor;
+ curThumbColor = mThumbCenterColor.get();
if(mIt->first == mCurSlider)
{
curSldrIt = mIt;
@@ -559,74 +551,9 @@ void LLMultiSlider::draw()
if(curSldrIt != mThumbRects.end())
{
- thumb_imagep->drawSolid(curSldrIt->second, mThumbCenterSelectedColor % opacity);
+ thumb_imagep->drawSolid(curSldrIt->second, mThumbCenterSelectedColor.get() % opacity);
}
}
- LLUICtrl::draw();
-}
-
-// virtual
-LLXMLNodePtr LLMultiSlider::getXML(bool save_children) const
-{
- LLXMLNodePtr node = LLUICtrl::getXML();
-
- node->createChild("initial_val", TRUE)->setFloatValue(getInitialValue());
- node->createChild("min_val", TRUE)->setFloatValue(getMinValue());
- node->createChild("max_val", TRUE)->setFloatValue(getMaxValue());
- node->createChild("increment", TRUE)->setFloatValue(getIncrement());
-
- return node;
-}
-
-
-//static
-LLView* LLMultiSlider::fromXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFactory *factory)
-{
- std::string name("multi_slider_bar");
- node->getAttributeString("name", name);
-
- LLRect rect;
- createRect(node, rect, parent, LLRect());
-
- F32 initial_value = 0.f;
- node->getAttributeF32("initial_val", initial_value);
-
- F32 min_value = 0.f;
- node->getAttributeF32("min_val", min_value);
-
- F32 max_value = 1.f;
- node->getAttributeF32("max_val", max_value);
-
- F32 increment = 0.1f;
- node->getAttributeF32("increment", increment);
-
- S32 max_sliders = 1;
- node->getAttributeS32("max_sliders", max_sliders);
-
- BOOL allow_overlap = FALSE;
- node->getAttributeBOOL("allow_overlap", allow_overlap);
-
- BOOL draw_track = TRUE;
- node->getAttributeBOOL("draw_track", draw_track);
-
- BOOL use_triangle = FALSE;
- node->getAttributeBOOL("use_triangle", use_triangle);
-
- LLMultiSlider* multiSlider = new LLMultiSlider(name,
- rect,
- NULL,
- NULL,
- initial_value,
- min_value,
- max_value,
- increment,
- max_sliders,
- allow_overlap,
- draw_track,
- use_triangle);
-
- multiSlider->initFromXML(node, parent);
-
- return multiSlider;
+ LLF32UICtrl::draw();
}
diff --git a/indra/llui/llmultislider.h b/indra/llui/llmultislider.h
index cdbdb597f9..da633cc1cd 100644
--- a/indra/llui/llmultislider.h
+++ b/indra/llui/llmultislider.h
@@ -33,32 +33,40 @@
#ifndef LL_MULTI_SLIDER_H
#define LL_MULTI_SLIDER_H
-#include "lluictrl.h"
+#include "llf32uictrl.h"
#include "v4color.h"
class LLUICtrlFactory;
-class LLMultiSlider : public LLUICtrl
+class LLMultiSlider : public LLF32UICtrl
{
public:
- LLMultiSlider(
- const std::string& name,
- const LLRect& rect,
- void (*on_commit_callback)(LLUICtrl* ctrl, void* userdata),
- void* callback_userdata,
- F32 initial_value,
- F32 min_value,
- F32 max_value,
- F32 increment,
- S32 max_sliders,
- BOOL allow_overlap,
- BOOL draw_track,
- BOOL use_triangle,
- const std::string& control_name = LLStringUtil::null );
-
- virtual LLXMLNodePtr getXML(bool save_children = true) const;
- static LLView* fromXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFactory *factory);
+ struct Params : public LLInitParam::Block<Params, LLF32UICtrl::Params>
+ {
+ Optional<S32> max_sliders;
+ Optional<bool> allow_overlap,
+ draw_track,
+ use_triangle;
+
+ Optional<LLUIColor> track_color,
+ thumb_disabled_color,
+ thumb_outline_color,
+ thumb_center_color,
+ thumb_center_selected_color,
+ triangle_color;
+
+ Optional<CommitCallbackParam> mouse_down_callback,
+ mouse_up_callback;
+ Optional<S32> thumb_width;
+
+ Params();
+ };
+
+protected:
+ LLMultiSlider(const Params&);
+ friend class LLUICtrlFactory;
+public:
void setSliderValue(const std::string& name, F32 value, BOOL from_event = FALSE);
F32 getSliderValue(const std::string& name) const;
@@ -67,41 +75,27 @@ public:
void setCurSlider(const std::string& name);
void setCurSliderValue(F32 val, BOOL from_event = false) { setSliderValue(mCurSlider, val, from_event); }
- virtual void setValue(const LLSD& value);
- virtual LLSD getValue() const { return mValue; }
-
- virtual void setMinValue(LLSD min_value) { setMinValue((F32)min_value.asReal()); }
- virtual void setMaxValue(LLSD max_value) { setMaxValue((F32)max_value.asReal()); }
+ /*virtual*/ void setValue(const LLSD& value);
+ /*virtual*/ LLSD getValue() const { return mValue; }
- F32 getInitialValue() const { return mInitialValue; }
- F32 getMinValue() const { return mMinValue; }
- F32 getMaxValue() const { return mMaxValue; }
- F32 getIncrement() const { return mIncrement; }
- void setMinValue(F32 min_value) { mMinValue = min_value; }
- void setMaxValue(F32 max_value) { mMaxValue = max_value; }
- void setIncrement(F32 increment) { mIncrement = increment; }
- void setMouseDownCallback( void (*cb)(LLUICtrl* ctrl, void* userdata) ) { mMouseDownCallback = cb; }
- void setMouseUpCallback( void (*cb)(LLUICtrl* ctrl, void* userdata) ) { mMouseUpCallback = cb; }
+ boost::signals2::connection setMouseDownCallback( const commit_signal_t::slot_type& cb ) { return mMouseDownSignal.connect(cb); }
+ boost::signals2::connection setMouseUpCallback( const commit_signal_t::slot_type& cb ) { return mMouseUpSignal.connect(cb); }
- bool findUnusedValue(F32& initVal);
+ bool findUnusedValue(F32& initVal);
const std::string& addSlider();
const std::string& addSlider(F32 val);
void deleteSlider(const std::string& name);
void deleteCurSlider() { deleteSlider(mCurSlider); }
void clear();
- virtual BOOL handleHover(S32 x, S32 y, MASK mask);
- virtual BOOL handleMouseUp(S32 x, S32 y, MASK mask);
- virtual BOOL handleMouseDown(S32 x, S32 y, MASK mask);
- virtual BOOL handleKeyHere(KEY key, MASK mask);
- virtual void draw();
+ /*virtual*/ BOOL handleHover(S32 x, S32 y, MASK mask);
+ /*virtual*/ BOOL handleMouseUp(S32 x, S32 y, MASK mask);
+ /*virtual*/ BOOL handleMouseDown(S32 x, S32 y, MASK mask);
+ /*virtual*/ BOOL handleKeyHere(KEY key, MASK mask);
+ /*virtual*/ void draw();
protected:
LLSD mValue;
- F32 mInitialValue;
- F32 mMinValue;
- F32 mMaxValue;
- F32 mIncrement;
std::string mCurSlider;
static S32 mNameCounter;
@@ -112,17 +106,18 @@ protected:
S32 mMouseOffset;
LLRect mDragStartThumbRect;
+ S32 mThumbWidth;
std::map<std::string, LLRect> mThumbRects;
- LLColor4 mTrackColor;
- LLColor4 mThumbOutlineColor;
- LLColor4 mThumbCenterColor;
- LLColor4 mThumbCenterSelectedColor;
- LLColor4 mDisabledThumbColor;
- LLColor4 mTriangleColor;
+ LLUIColor mTrackColor;
+ LLUIColor mThumbOutlineColor;
+ LLUIColor mThumbCenterColor;
+ LLUIColor mThumbCenterSelectedColor;
+ LLUIColor mDisabledThumbColor;
+ LLUIColor mTriangleColor;
- void (*mMouseDownCallback)(LLUICtrl* ctrl, void* userdata);
- void (*mMouseUpCallback)(LLUICtrl* ctrl, void* userdata);
+ commit_signal_t mMouseDownSignal;
+ commit_signal_t mMouseUpSignal;
};
-#endif // LL_LLSLIDER_H
+#endif // LL_MULTI_SLIDER_H
diff --git a/indra/llui/llmultisliderctrl.cpp b/indra/llui/llmultisliderctrl.cpp
index 8bcf9f9b76..01a3b5fdc7 100644
--- a/indra/llui/llmultisliderctrl.cpp
+++ b/indra/llui/llmultisliderctrl.cpp
@@ -34,9 +34,6 @@
#include "llmultisliderctrl.h"
-#include "audioengine.h"
-#include "sound_ids.h"
-
#include "llmath.h"
#include "llfontgl.h"
#include "llgl.h"
@@ -50,90 +47,100 @@
#include "llcontrol.h"
#include "llfocusmgr.h"
#include "llresmgr.h"
+#include "lluictrlfactory.h"
-static LLRegisterWidget<LLMultiSliderCtrl> r("multi_slider");
+static LLDefaultChildRegistry::Register<LLMultiSliderCtrl> r("multi_slider");
const U32 MAX_STRING_LENGTH = 10;
-
+LLMultiSliderCtrl::Params::Params()
+: text_width("text_width"),
+ label_width("label_width"),
+ show_text("show_text", true),
+ can_edit_text("can_edit_text", false),
+ max_sliders("max_sliders", 1),
+ allow_overlap("allow_overlap", false),
+ draw_track("draw_track", true),
+ use_triangle("use_triangle", false),
+ decimal_digits("decimal_digits", 3),
+ text_color("text_color"),
+ text_disabled_color("text_disabled_color"),
+ mouse_down_callback("mouse_down_callback"),
+ mouse_up_callback("mouse_up_callback")
+{
+ mouse_opaque = true;
+}
-LLMultiSliderCtrl::LLMultiSliderCtrl(const std::string& name, const LLRect& rect,
- const std::string& label,
- const LLFontGL* font,
- S32 label_width,
- S32 text_left,
- BOOL show_text,
- BOOL can_edit_text,
- void (*commit_callback)(LLUICtrl*, void*),
- void* callback_user_data,
- F32 initial_value, F32 min_value, F32 max_value, F32 increment,
- S32 max_sliders, BOOL allow_overlap,
- BOOL draw_track,
- BOOL use_triangle,
- const std::string& control_which)
- : LLUICtrl(name, rect, TRUE, commit_callback, callback_user_data ),
- mFont(font),
- mShowText( show_text ),
- mCanEditText( can_edit_text ),
- mPrecision( 3 ),
- mLabelBox( NULL ),
- mLabelWidth( label_width ),
-
- mEditor( NULL ),
- mTextBox( NULL ),
- mTextEnabledColor( LLUI::sColorsGroup->getColor( "LabelTextColor" ) ),
- mTextDisabledColor( LLUI::sColorsGroup->getColor( "LabelDisabledColor" ) ),
- mSliderMouseUpCallback( NULL ),
- mSliderMouseDownCallback( NULL )
+LLMultiSliderCtrl::LLMultiSliderCtrl(const LLMultiSliderCtrl::Params& p)
+: LLF32UICtrl(p),
+ mLabelBox( NULL ),
+ mEditor( NULL ),
+ mTextBox( NULL ),
+ mTextEnabledColor(p.text_color()),
+ mTextDisabledColor(p.text_disabled_color())
{
+ static LLUICachedControl<S32> multi_sliderctrl_spacing ("UIMultiSliderctrlSpacing", 0);
+
S32 top = getRect().getHeight();
S32 bottom = 0;
S32 left = 0;
+ S32 label_width = p.label_width;
+ S32 text_width = p.text_width;
+
// Label
- if( !label.empty() )
+ if( !p.label().empty() )
{
- if (label_width == 0)
+ if (p.label_width == 0)
{
- label_width = font->getWidth(label);
+ label_width = p.font()->getWidth(p.label);
}
LLRect label_rect( left, top, label_width, bottom );
- mLabelBox = new LLTextBox( std::string("MultiSliderCtrl Label"), label_rect, label, font );
+ LLTextBox::Params params;
+ params.name("MultiSliderCtrl Label");
+ params.rect(label_rect);
+ params.text(p.label);
+ params.font(p.font);
+ mLabelBox = LLUICtrlFactory::create<LLTextBox> (params);
addChild(mLabelBox);
}
S32 slider_right = getRect().getWidth();
- if( show_text )
- {
- slider_right = text_left - MULTI_SLIDERCTRL_SPACING;
- }
- S32 slider_left = label_width ? label_width + MULTI_SLIDERCTRL_SPACING : 0;
- LLRect slider_rect( slider_left, top, slider_right, bottom );
- mMultiSlider = new LLMultiSlider(
- std::string("multi_slider"),
- slider_rect,
- LLMultiSliderCtrl::onSliderCommit, this,
- initial_value, min_value, max_value, increment,
- max_sliders, allow_overlap, draw_track,
- use_triangle,
- control_which );
- addChild( mMultiSlider );
- mCurValue = mMultiSlider->getCurSliderValue();
-
- if( show_text )
+ if (p.show_text)
{
+ if (!p.text_width.isProvided())
+ {
+ text_width = 0;
+ // calculate the size of the text box (log max_value is number of digits - 1 so plus 1)
+ if ( p.max_value() )
+ text_width = p.font()->getWidth(std::string("0")) * ( static_cast < S32 > ( log10 ( p.max_value ) ) + p.decimal_digits + 1 );
+
+ if ( p.increment < 1.0f )
+ text_width += p.font()->getWidth(std::string(".")); // (mostly) take account of decimal point in value
+
+ if ( p.min_value < 0.0f || p.max_value < 0.0f )
+ text_width += p.font()->getWidth(std::string("-")); // (mostly) take account of minus sign
+
+ // padding to make things look nicer
+ text_width += 8;
+ }
+ S32 text_left = getRect().getWidth() - text_width;
+
+ slider_right = text_left - multi_sliderctrl_spacing;
+
LLRect text_rect( text_left, top, getRect().getWidth(), bottom );
- if( can_edit_text )
+ if( p.can_edit_text )
{
- mEditor = new LLLineEditor( std::string("MultiSliderCtrl Editor"), text_rect,
- LLStringUtil::null, font,
- MAX_STRING_LENGTH,
- &LLMultiSliderCtrl::onEditorCommit, NULL, NULL, this,
- &LLLineEditor::prevalidateFloat );
- mEditor->setFollowsLeft();
- mEditor->setFollowsBottom();
+ LLLineEditor::Params params;
+ params.name("MultiSliderCtrl Editor");
+ params.rect(text_rect);
+ params.font(p.font);
+ params.max_length_bytes(MAX_STRING_LENGTH);
+ params.commit_callback.function(LLMultiSliderCtrl::onEditorCommit);
+ params.prevalidate_callback(&LLLineEditor::prevalidateFloat);
+ params.follows.flags(FOLLOWS_LEFT | FOLLOWS_BOTTOM);
+ mEditor = LLUICtrlFactory::create<LLLineEditor> (params);
mEditor->setFocusReceivedCallback( &LLMultiSliderCtrl::onEditorGainFocus );
- mEditor->setIgnoreTab(TRUE);
// don't do this, as selecting the entire text is single clicking in some cases
// and double clicking in others
//mEditor->setSelectAllonFocusReceived(TRUE);
@@ -141,13 +148,37 @@ LLMultiSliderCtrl::LLMultiSliderCtrl(const std::string& name, const LLRect& rect
}
else
{
- mTextBox = new LLTextBox( std::string("MultiSliderCtrl Text"), text_rect, LLStringUtil::null, font);
- mTextBox->setFollowsLeft();
- mTextBox->setFollowsBottom();
+ LLTextBox::Params params;
+ params.name("MultiSliderCtrl Text");
+ params.rect(text_rect);
+ params.font(p.font);
+ params.follows.flags(FOLLOWS_LEFT | FOLLOWS_BOTTOM);
+ mTextBox = LLUICtrlFactory::create<LLTextBox> (params);
addChild(mTextBox);
}
}
+ S32 slider_left = label_width ? label_width + multi_sliderctrl_spacing : 0;
+ LLRect slider_rect( slider_left, top, slider_right, bottom );
+ LLMultiSlider::Params params;
+ params.rect(slider_rect);
+ params.commit_callback.function( LLMultiSliderCtrl::onSliderCommit );
+ params.mouse_down_callback( p.mouse_down_callback );
+ params.mouse_up_callback( p.mouse_up_callback );
+ params.initial_value(p.initial_value());
+ params.min_value(p.min_value);
+ params.max_value(p.max_value);
+ params.increment(p.increment);
+ params.max_sliders(p.max_sliders);
+ params.allow_overlap(p.allow_overlap);
+ params.draw_track(p.draw_track);
+ params.use_triangle(p.use_triangle);
+ params.control_name(p.control_name);
+ mMultiSlider = LLUICtrlFactory::create<LLMultiSlider> (params);
+ addChild( mMultiSlider );
+ mCurValue = mMultiSlider->getCurSliderValue();
+
+
updateText();
}
@@ -203,7 +234,8 @@ BOOL LLMultiSliderCtrl::setLabelArg( const std::string& key, const LLStringExpli
S32 delta = rect.mRight - prev_right;
rect = mMultiSlider->getRect();
S32 left = rect.mLeft + delta;
- left = llclamp(left, 0, rect.mRight-MULTI_SLIDERCTRL_SPACING);
+ static LLUICachedControl<S32> multi_slider_ctrl_spacing ("UIMultiSliderctrlSpacing", 0);
+ left = llclamp(left, 0, rect.mRight - multi_slider_ctrl_spacing);
rect.mLeft = left;
mMultiSlider->setRect(rect);
}
@@ -294,11 +326,12 @@ void LLMultiSliderCtrl::updateText()
}
// static
-void LLMultiSliderCtrl::onEditorCommit( LLUICtrl* caller, void *userdata )
+void LLMultiSliderCtrl::onEditorCommit( LLUICtrl* ctrl, const LLSD& userdata)
{
- LLMultiSliderCtrl* self = (LLMultiSliderCtrl*) userdata;
- llassert( caller == self->mEditor );
-
+ LLMultiSliderCtrl* self = dynamic_cast<LLMultiSliderCtrl*>(ctrl);
+ if (!ctrl)
+ return;
+
BOOL success = FALSE;
F32 val = self->mCurValue;
F32 saved_val = self->mCurValue;
@@ -310,17 +343,9 @@ void LLMultiSliderCtrl::onEditorCommit( LLUICtrl* caller, void *userdata )
val = (F32) atof( text.c_str() );
if( self->mMultiSlider->getMinValue() <= val && val <= self->mMultiSlider->getMaxValue() )
{
- if( self->mValidateCallback )
- {
- self->setCurSliderValue( val ); // set the value temporarily so that the callback can retrieve it.
- if( self->mValidateCallback( self, self->mCallbackUserData ) )
- {
- success = TRUE;
- }
- }
- else
+ self->setCurSliderValue( val ); // set the value temporarily so that the callback can retrieve it.
+ if( self->mValidateSignal( self, val ) )
{
- self->setCurSliderValue( val );
success = TRUE;
}
}
@@ -342,26 +367,19 @@ void LLMultiSliderCtrl::onEditorCommit( LLUICtrl* caller, void *userdata )
}
// static
-void LLMultiSliderCtrl::onSliderCommit( LLUICtrl* caller, void *userdata )
+void LLMultiSliderCtrl::onSliderCommit(LLUICtrl* ctrl, const LLSD& userdata)
{
- LLMultiSliderCtrl* self = (LLMultiSliderCtrl*) userdata;
- //llassert( caller == self->mSlider );
-
+ LLMultiSliderCtrl* self = dynamic_cast<LLMultiSliderCtrl*>(ctrl);
+ if (!self)
+ return;
+
BOOL success = FALSE;
F32 saved_val = self->mCurValue;
F32 new_val = self->mMultiSlider->getCurSliderValue();
- if( self->mValidateCallback )
+ self->mCurValue = new_val; // set the value temporarily so that the callback can retrieve it.
+ if( self->mValidateSignal( self, new_val ) )
{
- self->mCurValue = new_val; // set the value temporarily so that the callback can retrieve it.
- if( self->mValidateCallback( self, self->mCallbackUserData ) )
- {
- success = TRUE;
- }
- }
- else
- {
- self->mCurValue = new_val;
success = TRUE;
}
@@ -382,11 +400,11 @@ void LLMultiSliderCtrl::onSliderCommit( LLUICtrl* caller, void *userdata )
void LLMultiSliderCtrl::setEnabled(BOOL b)
{
- LLUICtrl::setEnabled( b );
+ LLF32UICtrl::setEnabled( b );
if( mLabelBox )
{
- mLabelBox->setColor( b ? mTextEnabledColor : mTextDisabledColor );
+ mLabelBox->setColor( b ? mTextEnabledColor.get() : mTextDisabledColor.get() );
}
mMultiSlider->setEnabled( b );
@@ -398,7 +416,7 @@ void LLMultiSliderCtrl::setEnabled(BOOL b)
if( mTextBox )
{
- mTextBox->setColor( b ? mTextEnabledColor : mTextDisabledColor );
+ mTextBox->setColor( b ? mTextEnabledColor.get() : mTextDisabledColor.get() );
}
}
@@ -409,7 +427,7 @@ void LLMultiSliderCtrl::setTentative(BOOL b)
{
mEditor->setTentative(b);
}
- LLUICtrl::setTentative(b);
+ LLF32UICtrl::setTentative(b);
}
@@ -422,7 +440,8 @@ void LLMultiSliderCtrl::onCommit()
mEditor->setTentative(FALSE);
}
- LLUICtrl::onCommit();
+ setControlValue(getValueF32());
+ LLF32UICtrl::onCommit();
}
@@ -438,37 +457,14 @@ void LLMultiSliderCtrl::setPrecision(S32 precision)
updateText();
}
-void LLMultiSliderCtrl::setSliderMouseDownCallback( void (*slider_mousedown_callback)(LLUICtrl* caller, void* userdata) )
+boost::signals2::connection LLMultiSliderCtrl::setSliderMouseDownCallback( const commit_signal_t::slot_type& cb )
{
- mSliderMouseDownCallback = slider_mousedown_callback;
- mMultiSlider->setMouseDownCallback( LLMultiSliderCtrl::onSliderMouseDown );
+ return mMultiSlider->setMouseDownCallback( cb );
}
-// static
-void LLMultiSliderCtrl::onSliderMouseDown(LLUICtrl* caller, void* userdata)
+boost::signals2::connection LLMultiSliderCtrl::setSliderMouseUpCallback( const commit_signal_t::slot_type& cb )
{
- LLMultiSliderCtrl* self = (LLMultiSliderCtrl*) userdata;
- if( self->mSliderMouseDownCallback )
- {
- self->mSliderMouseDownCallback( self, self->mCallbackUserData );
- }
-}
-
-
-void LLMultiSliderCtrl::setSliderMouseUpCallback( void (*slider_mouseup_callback)(LLUICtrl* caller, void* userdata) )
-{
- mSliderMouseUpCallback = slider_mouseup_callback;
- mMultiSlider->setMouseUpCallback( LLMultiSliderCtrl::onSliderMouseUp );
-}
-
-// static
-void LLMultiSliderCtrl::onSliderMouseUp(LLUICtrl* caller, void* userdata)
-{
- LLMultiSliderCtrl* self = (LLMultiSliderCtrl*) userdata;
- if( self->mSliderMouseUpCallback )
- {
- self->mSliderMouseUpCallback( self, self->mCallbackUserData );
- }
+ return mMultiSlider->setMouseUpCallback( cb );
}
void LLMultiSliderCtrl::onTabInto()
@@ -484,154 +480,9 @@ void LLMultiSliderCtrl::reportInvalidData()
make_ui_sound("UISndBadKeystroke");
}
-//virtual
-std::string LLMultiSliderCtrl::getControlName() const
-{
- return mMultiSlider->getControlName();
-}
-
// virtual
void LLMultiSliderCtrl::setControlName(const std::string& control_name, LLView* context)
{
mMultiSlider->setControlName(control_name, context);
}
-// virtual
-LLXMLNodePtr LLMultiSliderCtrl::getXML(bool save_children) const
-{
- LLXMLNodePtr node = LLUICtrl::getXML();
-
- node->createChild("show_text", TRUE)->setBoolValue(mShowText);
-
- node->createChild("can_edit_text", TRUE)->setBoolValue(mCanEditText);
-
- node->createChild("decimal_digits", TRUE)->setIntValue(mPrecision);
-
- if (mLabelBox)
- {
- node->createChild("label", TRUE)->setStringValue(mLabelBox->getText());
- }
-
- // TomY TODO: Do we really want to export the transient state of the slider?
- node->createChild("value", TRUE)->setFloatValue(mCurValue);
-
- if (mMultiSlider)
- {
- node->createChild("initial_val", TRUE)->setFloatValue(mMultiSlider->getInitialValue());
- node->createChild("min_val", TRUE)->setFloatValue(mMultiSlider->getMinValue());
- node->createChild("max_val", TRUE)->setFloatValue(mMultiSlider->getMaxValue());
- node->createChild("increment", TRUE)->setFloatValue(mMultiSlider->getIncrement());
- }
- addColorXML(node, mTextEnabledColor, "text_enabled_color", "LabelTextColor");
- addColorXML(node, mTextDisabledColor, "text_disabled_color", "LabelDisabledColor");
-
- return node;
-}
-
-LLView* LLMultiSliderCtrl::fromXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFactory *factory)
-{
- std::string name("multi_slider");
- node->getAttributeString("name", name);
-
- std::string label;
- node->getAttributeString("label", label);
-
- LLRect rect;
- createRect(node, rect, parent, LLRect());
-
- LLFontGL* font = LLView::selectFont(node);
-
- // HACK: Font might not be specified.
- if (!font)
- {
- font = LLFontGL::getFontSansSerifSmall();
- }
-
- S32 label_width = 0;
- node->getAttributeS32("label_width", label_width);
-
- BOOL show_text = TRUE;
- node->getAttributeBOOL("show_text", show_text);
-
- BOOL can_edit_text = FALSE;
- node->getAttributeBOOL("can_edit_text", can_edit_text);
-
- BOOL allow_overlap = FALSE;
- node->getAttributeBOOL("allow_overlap", allow_overlap);
-
- BOOL draw_track = TRUE;
- node->getAttributeBOOL("draw_track", draw_track);
-
- BOOL use_triangle = FALSE;
- node->getAttributeBOOL("use_triangle", use_triangle);
-
- F32 initial_value = 0.f;
- node->getAttributeF32("initial_val", initial_value);
-
- F32 min_value = 0.f;
- node->getAttributeF32("min_val", min_value);
-
- F32 max_value = 1.f;
- node->getAttributeF32("max_val", max_value);
-
- F32 increment = 0.1f;
- node->getAttributeF32("increment", increment);
-
- U32 precision = 3;
- node->getAttributeU32("decimal_digits", precision);
-
- S32 max_sliders = 1;
- node->getAttributeS32("max_sliders", max_sliders);
-
-
- S32 text_left = 0;
- if (show_text)
- {
- // calculate the size of the text box (log max_value is number of digits - 1 so plus 1)
- if ( max_value )
- text_left = font->getWidth(std::string("0")) * ( static_cast < S32 > ( log10 ( max_value ) ) + precision + 1 );
-
- if ( increment < 1.0f )
- text_left += font->getWidth(std::string(".")); // (mostly) take account of decimal point in value
-
- if ( min_value < 0.0f || max_value < 0.0f )
- text_left += font->getWidth(std::string("-")); // (mostly) take account of minus sign
-
- // padding to make things look nicer
- text_left += 8;
- }
-
- LLUICtrlCallback callback = NULL;
-
- if (label.empty())
- {
- label.assign(node->getTextContents());
- }
-
- LLMultiSliderCtrl* slider = new LLMultiSliderCtrl(name,
- rect,
- label,
- font,
- label_width,
- rect.getWidth() - text_left,
- show_text,
- can_edit_text,
- callback,
- NULL,
- initial_value,
- min_value,
- max_value,
- increment,
- max_sliders,
- allow_overlap,
- draw_track,
- use_triangle);
-
- slider->setPrecision(precision);
-
- slider->initFromXML(node, parent);
-
- slider->updateText();
-
- return slider;
-}
diff --git a/indra/llui/llmultisliderctrl.h b/indra/llui/llmultisliderctrl.h
index b62b5ec323..16d07541f2 100644
--- a/indra/llui/llmultisliderctrl.h
+++ b/indra/llui/llmultisliderctrl.h
@@ -33,17 +33,12 @@
#ifndef LL_MULTI_SLIDERCTRL_H
#define LL_MULTI_SLIDERCTRL_H
-#include "lluictrl.h"
+#include "llf32uictrl.h"
#include "v4color.h"
#include "llmultislider.h"
#include "lltextbox.h"
#include "llrect.h"
-//
-// Constants
-//
-const S32 MULTI_SLIDERCTRL_SPACING = 4; // space between label, slider, and text
-const S32 MULTI_SLIDERCTRL_HEIGHT = 16;
//
// Classes
@@ -53,27 +48,35 @@ class LLLineEditor;
class LLSlider;
-class LLMultiSliderCtrl : public LLUICtrl
+class LLMultiSliderCtrl : public LLF32UICtrl
{
public:
- LLMultiSliderCtrl(const std::string& name,
- const LLRect& rect,
- const std::string& label,
- const LLFontGL* font,
- S32 slider_left,
- S32 text_left,
- BOOL show_text,
- BOOL can_edit_text,
- void (*commit_callback)(LLUICtrl*, void*),
- void* callback_userdata,
- F32 initial_value, F32 min_value, F32 max_value, F32 increment,
- S32 max_sliders, BOOL allow_overlap, BOOL draw_track,
- BOOL use_triangle,
- const std::string& control_which = LLStringUtil::null );
-
+ struct Params : public LLInitParam::Block<Params, LLF32UICtrl::Params>
+ {
+ Optional<S32> label_width,
+ text_width;
+ Optional<bool> show_text,
+ can_edit_text;
+ Optional<S32> decimal_digits;
+ Optional<S32> max_sliders;
+ Optional<bool> allow_overlap,
+ draw_track,
+ use_triangle;
+
+ Optional<LLUIColor> text_color,
+ text_disabled_color;
+
+ Optional<CommitCallbackParam> mouse_down_callback,
+ mouse_up_callback;
+
+ Params();
+ };
+
+protected:
+ LLMultiSliderCtrl(const Params&);
+ friend class LLUICtrlFactory;
+public:
virtual ~LLMultiSliderCtrl();
- virtual LLXMLNodePtr getXML(bool save_children = true) const;
- static LLView* fromXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFactory *factory);
F32 getSliderValue(const std::string& name) const;
void setSliderValue(const std::string& name, F32 v, BOOL from_event = FALSE);
@@ -87,8 +90,8 @@ public:
void setCurSlider(const std::string& name);
void setCurSliderValue(F32 val, BOOL from_event = false) { setSliderValue(mMultiSlider->getCurSlider(), val, from_event); }
- virtual void setMinValue(LLSD min_value) { setMinValue((F32)min_value.asReal()); }
- virtual void setMaxValue(LLSD max_value) { setMaxValue((F32)max_value.asReal()); }
+ virtual void setMinValue(const LLSD& min_value) { setMinValue((F32)min_value.asReal()); }
+ virtual void setMaxValue(const LLSD& max_value) { setMaxValue((F32)max_value.asReal()); }
BOOL isMouseHeldDown();
@@ -105,15 +108,15 @@ public:
void deleteSlider(const std::string& name);
void deleteCurSlider() { deleteSlider(mMultiSlider->getCurSlider()); }
- F32 getMinValue() { return mMultiSlider->getMinValue(); }
- F32 getMaxValue() { return mMultiSlider->getMaxValue(); }
+ F32 getMinValue() const { return mMultiSlider->getMinValue(); }
+ F32 getMaxValue() const { return mMultiSlider->getMaxValue(); }
void setLabel(const std::string& label) { if (mLabelBox) mLabelBox->setText(label); }
void setLabelColor(const LLColor4& c) { mTextEnabledColor = c; }
void setDisabledLabelColor(const LLColor4& c) { mTextDisabledColor = c; }
- void setSliderMouseDownCallback( void (*slider_mousedown_callback)(LLUICtrl* caller, void* userdata) );
- void setSliderMouseUpCallback( void (*slider_mouseup_callback)(LLUICtrl* caller, void* userdata) );
+ boost::signals2::connection setSliderMouseDownCallback( const commit_signal_t::slot_type& cb );
+ boost::signals2::connection setSliderMouseUpCallback( const commit_signal_t::slot_type& cb );
virtual void onTabInto();
@@ -121,13 +124,10 @@ public:
virtual void onCommit(); // mark not tentative, then commit
virtual void setControlName(const std::string& control_name, LLView* context);
- virtual std::string getControlName() const;
- static void onSliderCommit(LLUICtrl* caller, void* userdata);
- static void onSliderMouseDown(LLUICtrl* caller,void* userdata);
- static void onSliderMouseUp(LLUICtrl* caller,void* userdata);
-
- static void onEditorCommit(LLUICtrl* caller, void* userdata);
+ static void onSliderCommit(LLUICtrl* caller, const LLSD& userdata);
+
+ static void onEditorCommit(LLUICtrl* ctrl, const LLSD& userdata);
static void onEditorGainFocus(LLFocusableElement* caller, void *userdata);
static void onEditorChangeFocus(LLUICtrl* caller, S32 direction, void *userdata);
@@ -149,11 +149,8 @@ private:
LLLineEditor* mEditor;
LLTextBox* mTextBox;
- LLColor4 mTextEnabledColor;
- LLColor4 mTextDisabledColor;
-
- void (*mSliderMouseUpCallback)( LLUICtrl* ctrl, void* userdata );
- void (*mSliderMouseDownCallback)( LLUICtrl* ctrl, void* userdata );
+ LLUIColor mTextEnabledColor;
+ LLUIColor mTextDisabledColor;
};
#endif // LL_MULTI_SLIDERCTRL_H
diff --git a/indra/llui/llnotifications.cpp b/indra/llui/llnotifications.cpp
index fe1ea95070..9845b7e2ce 100644
--- a/indra/llui/llnotifications.cpp
+++ b/indra/llui/llnotifications.cpp
@@ -31,11 +31,14 @@
*/
#include "linden_common.h"
+
+#include "llnotifications.h"
+
+#include "lluictrl.h"
#include "lluictrlfactory.h"
#include "lldir.h"
#include "llsdserialize.h"
-
-#include "llnotifications.h"
+#include "lltrans.h"
#include <algorithm>
#include <boost/regex.hpp>
@@ -157,11 +160,17 @@ private:
bool filterIgnoredNotifications(LLNotificationPtr notification)
{
+ // filter everything if we are to ignore ALL
+ if(LLNotifications::instance().getIgnoreAllNotifications())
+ {
+ return false;
+ }
+
LLNotificationFormPtr form = notification->getForm();
// Check to see if the user wants to ignore this alert
if (form->getIgnoreType() != LLNotificationForm::IGNORE_NO)
{
- return LLUI::sConfigGroup->getWarning(notification->getName());
+ return LLUI::sSettingGroups["ignores"]->getBOOL(notification->getName());
}
return true;
@@ -182,7 +191,7 @@ bool handleIgnoredNotification(const LLSD& payload)
response = pNotif->getResponseTemplate(LLNotification::WITH_DEFAULT_BUTTON);
break;
case LLNotificationForm::IGNORE_WITH_LAST_RESPONSE:
- response = LLUI::sIgnoresGroup->getLLSD("Default" + pNotif->getName());
+ response = LLUI::sSettingGroups["ignores"]->getLLSD("Default" + pNotif->getName());
break;
case LLNotificationForm::IGNORE_SHOW_AGAIN:
break;
@@ -228,7 +237,7 @@ LLNotificationForm::LLNotificationForm(const std::string& name, const LLXMLNodeP
LLSD item_entry;
std::string element_name = child->getName()->mString;
- if (element_name == "ignore")
+ if (element_name == "ignore" )
{
bool save_option = false;
child->getAttribute_bool("save_option", save_option);
@@ -240,10 +249,11 @@ LLNotificationForm::LLNotificationForm(const std::string& name, const LLXMLNodeP
{
// remember last option chosen by user and automatically respond with that in the future
mIgnore = IGNORE_WITH_LAST_RESPONSE;
- LLUI::sIgnoresGroup->declareLLSD(std::string("Default") + name, "", std::string("Default response for notification " + name));
+ LLUI::sSettingGroups["ignores"]->declareLLSD(std::string("Default") + name, "", std::string("Default response for notification " + name));
}
child->getAttributeString("text", mIgnoreMsg);
- LLUI::sIgnoresGroup->addWarning(name);
+ BOOL show_notification = TRUE;
+ LLUI::sSettingGroups["ignores"]->declareBOOL(name, show_notification, "Ignore notification with this name", TRUE);
}
else
{
@@ -339,13 +349,13 @@ void LLNotificationForm::formatElements(const LLSD& substitutions)
if ((*it).has("text"))
{
std::string text = (*it)["text"].asString();
- text = LLNotification::format(text, substitutions);
+ LLStringUtil::format(text, substitutions);
(*it)["text"] = text;
}
if ((*it)["type"].asString() == "text" && (*it).has("value"))
{
std::string value = (*it)["value"].asString();
- value = LLNotification::format(value, substitutions);
+ LLStringUtil::format(value, substitutions);
(*it)["value"] = value;
}
}
@@ -366,6 +376,7 @@ LLNotificationTemplate::LLNotificationTemplate() :
mExpireSeconds(0),
mExpireOption(-1),
mURLOption(-1),
+ mURLOpenExternally(-1),
mUnique(false),
mPriority(NOTIFICATION_PRIORITY_NORMAL)
{
@@ -373,17 +384,28 @@ LLNotificationTemplate::LLNotificationTemplate() :
}
LLNotification::LLNotification(const LLNotification::Params& p) :
- mTimestamp(p.timestamp),
+ mTimestamp(p.time_stamp),
mSubstitutions(p.substitutions),
mPayload(p.payload),
mExpiresAt(0),
- mResponseFunctorName(p.functor_name),
- mTemporaryResponder(p.mTemporaryResponder),
+ mTemporaryResponder(false),
mRespondedTo(false),
mPriority(p.priority),
mCancelled(false),
mIgnored(false)
{
+ if (p.functor.name.isChosen())
+ {
+ mResponseFunctorName = p.functor.name;
+ }
+ else if (p.functor.function.isChosen())
+ {
+ mResponseFunctorName = LLUUID::generateNewID().asString();
+ LLNotificationFunctorRegistry::instance().registerFunctor(mResponseFunctorName, p.functor.function());
+
+ mTemporaryResponder = true;
+ }
+
mId.generate();
init(p.name, p.form_elements);
}
@@ -540,10 +562,11 @@ void LLNotification::respond(const LLSD& response)
if (mForm->getIgnoreType() != LLNotificationForm::IGNORE_NO)
{
- LLUI::sIgnoresGroup->setWarning(getName(), !mIgnored);
+ BOOL show_notification = mIgnored ? FALSE : TRUE;
+ LLUI::sSettingGroups["ignores"]->setBOOL(getName(), show_notification);
if (mIgnored && mForm->getIgnoreType() == LLNotificationForm::IGNORE_WITH_LAST_RESPONSE)
{
- LLUI::sIgnoresGroup->setLLSD("Default" + getName(), response);
+ LLUI::sSettingGroups["ignores"]->setLLSD("Default" + getName(), response);
}
}
@@ -601,8 +624,12 @@ void LLNotification::init(const std::string& template_name, const LLSD& form_ele
if (!mTemplatep) return;
// add default substitutions
- // TODO: change this to read from the translatable strings file!
- mSubstitutions["SECOND_LIFE"] = "Second Life";
+ const LLStringUtil::format_map_t& default_args = LLTrans::getDefaultArgs();
+ for (LLStringUtil::format_map_t::const_iterator iter = default_args.begin();
+ iter != default_args.end(); ++iter)
+ {
+ mSubstitutions[iter->first] = iter->second;
+ }
mSubstitutions["_URL"] = getURL();
mSubstitutions["_NAME"] = template_name;
// TODO: something like this so that a missing alert is sensible:
@@ -636,64 +663,6 @@ std::string LLNotification::summarize() const
return s;
}
-//static
-std::string LLNotification::format(const std::string& s, const LLSD& substitutions)
-{
- if (!substitutions.isMap())
- {
- return s;
- }
-
- std::ostringstream output;
- // match strings like [NAME]
- const boost::regex key("\\[([0-9_A-Z]+)]");
-
- std::string::const_iterator start = s.begin();
- std::string::const_iterator end = s.end();
- boost::smatch match;
-
- while (boost::regex_search(start, end, match, key, boost::match_default))
- {
- bool found_replacement = false;
- std::string replacement;
-
- // see if we have a replacement for the bracketed string (without the brackets)
- // test first using has() because if we just look up with operator[] we get back an
- // empty string even if the value is missing. We want to distinguish between
- // missing replacements and deliberately empty replacement strings.
- if (substitutions.has(std::string(match[1].first, match[1].second)))
- {
- replacement = substitutions[std::string(match[1].first, match[1].second)].asString();
- found_replacement = true;
- }
- // if not, see if there's one WITH brackets
- else if (substitutions.has(std::string(match[0].first, match[0].second)))
- {
- replacement = substitutions[std::string(match[0].first, match[0].second)].asString();
- found_replacement = true;
- }
-
- if (found_replacement)
- {
- // found a replacement
- // "hello world" is output
- output << std::string(start, match[0].first) << replacement;
- }
- else
- {
- // we had no replacement, so leave the string we searched for so that it gets noticed by QA
- // "hello [NAME_NOT_FOUND]" is output
- output << std::string(start, match[0].second);
- }
-
- // update search position
- start = match[0].second;
- }
- // send the remainder of the string (with no further matches for bracketed names)
- output << std::string(start, end);
- return output.str();
-}
-
std::string LLNotification::getMessage() const
{
// all our callers cache this result, so it gives us more flexibility
@@ -701,15 +670,27 @@ std::string LLNotification::getMessage() const
// cache it in the notification
if (!mTemplatep)
return std::string();
- return format(mTemplatep->mMessage, mSubstitutions);
+
+ std::string message = mTemplatep->mMessage;
+ LLStringUtil::format(message, mSubstitutions);
+ return message;
}
std::string LLNotification::getLabel() const
{
- return (mTemplatep ? format(mTemplatep->mLabel, mSubstitutions) : "");
+ std::string label = mTemplatep->mLabel;
+ LLStringUtil::format(label, mSubstitutions);
+ return (mTemplatep ? label : "");
}
-
+std::string LLNotification::getURL() const
+{
+ if (!mTemplatep)
+ return std::string();
+ std::string url = mTemplatep->mURL;
+ LLStringUtil::format(url, mSubstitutions);
+ return (mTemplatep ? url : "");
+}
// =========================================================
// LLNotificationChannel implementation
@@ -729,6 +710,15 @@ LLBoundListener LLNotificationChannelBase::connectChangedImpl(const LLEventListe
return mChanged.connect(slot);
}
+LLBoundListener LLNotificationChannelBase::connectAtFrontChangedImpl(const LLEventListener& slot)
+{
+ for (LLNotificationSet::iterator it = mItems.begin(); it != mItems.end(); ++it)
+ {
+ slot(LLSD().insert("sigtype", "load").insert("id", (*it)->id()));
+ }
+ return mChanged.connect(slot, boost::signals2::at_front);
+}
+
LLBoundListener LLNotificationChannelBase::connectPassedFilterImpl(const LLEventListener& slot)
{
// these two filters only fire for notifications added after the current one, because
@@ -950,8 +940,10 @@ std::string LLNotificationChannel::summarize()
// LLNotifications implementation
// ---
LLNotifications::LLNotifications() : LLNotificationChannelBase(LLNotificationFilters::includeEverything,
- LLNotificationComparators::orderByUUID())
+ LLNotificationComparators::orderByUUID()),
+ mIgnoreAllNotifications(false)
{
+ LLUICtrl::CommitCallbackRegistry::currentRegistrar().add("Notification.Show", boost::bind(&LLNotifications::addFromCallback, this, _2));
}
@@ -1093,17 +1085,17 @@ void LLNotifications::createDefaultChannels()
// connect action methods to these channels
LLNotifications::instance().getChannel("Expiration")->
connectChanged(boost::bind(&LLNotifications::expirationHandler, this, _1));
+ // uniqueHandler slot should be added as first slot of the signal due to
+ // usage LLStopWhenHandled combiner in LLStandardSignal
LLNotifications::instance().getChannel("Unique")->
- connectChanged(boost::bind(&LLNotifications::uniqueHandler, this, _1));
- LLNotifications::instance().getChannel("Unique")->
- connectFailedFilter(boost::bind(&LLNotifications::failedUniquenessTest, this, _1));
+ connectAtFrontChanged(boost::bind(&LLNotifications::uniqueHandler, this, _1));
+// failedUniquenessTest slot isn't necessary
+// LLNotifications::instance().getChannel("Unique")->
+// connectFailedFilter(boost::bind(&LLNotifications::failedUniquenessTest, this, _1));
LLNotifications::instance().getChannel("Ignore")->
connectFailedFilter(&handleIgnoredNotification);
}
-static std::string sStringSkipNextTime("Skip this dialog next time");
-static std::string sStringAlwaysChoose("Always choose this option");
-
bool LLNotifications::addTemplate(const std::string &name,
LLNotificationTemplatePtr theTemplate)
{
@@ -1324,8 +1316,17 @@ bool LLNotifications::loadTemplates()
item->getAttributeString("sound", sound);
if (!sound.empty())
{
- // TODO: test for bad sound effect name / missing effect
- pTemplate->mSoundEffect = LLUUID(LLUI::sConfigGroup->getString(sound.c_str()));
+ // test for bad sound effect name / missing effect
+ if (LLUI::sSettingGroups["config"]->controlExists(sound))
+ {
+ pTemplate->mSoundEffect =
+ LLUUID(LLUI::sSettingGroups["config"]->getString(sound));
+ }
+ else
+ {
+ llwarns << "Unknown sound effect control name " << sound
+ << llendl;
+ }
}
for (LLXMLNodePtr child = item->getFirstChild();
@@ -1338,6 +1339,7 @@ bool LLNotifications::loadTemplates()
{
pTemplate->mURL = child->getTextContents();
child->getAttributeU32("option", pTemplate->mURLOption);
+ child->getAttributeU32("openexternally", pTemplate->mURLOpenExternally);
}
if (child->hasName("unique"))
@@ -1377,12 +1379,20 @@ bool LLNotifications::loadTemplates()
return true;
}
+// Add a simple notification (from XUI)
+void LLNotifications::addFromCallback(const LLSD& name)
+{
+ add(LLNotification::Params().name(name.asString()));
+}
+
// we provide a couple of simple add notification functions so that it's reasonable to create notifications in one line
LLNotificationPtr LLNotifications::add(const std::string& name,
const LLSD& substitutions,
const LLSD& payload)
{
- return add(LLNotification::Params(name).substitutions(substitutions).payload(payload));
+ LLNotification::Params::Functor functor_p;
+ functor_p.name = name;
+ return add(LLNotification::Params().name(name).substitutions(substitutions).payload(payload).functor(functor_p));
}
LLNotificationPtr LLNotifications::add(const std::string& name,
@@ -1390,7 +1400,9 @@ LLNotificationPtr LLNotifications::add(const std::string& name,
const LLSD& payload,
const std::string& functor_name)
{
- return add(LLNotification::Params(name).substitutions(substitutions).payload(payload).functor_name(functor_name));
+ LLNotification::Params::Functor functor_p;
+ functor_p.name = functor_name;
+ return add(LLNotification::Params().name(name).substitutions(substitutions).payload(payload).functor(functor_p));
}
LLNotificationPtr LLNotifications::add(const std::string& name,
@@ -1398,7 +1410,9 @@ LLNotificationPtr LLNotifications::add(const std::string& name,
const LLSD& payload,
LLNotificationFunctorRegistry::ResponseFunctor functor)
{
- return add(LLNotification::Params(name).substitutions(substitutions).payload(payload).functor(functor));
+ LLNotification::Params::Functor functor_p;
+ functor_p.function = functor;
+ return add(LLNotification::Params().name(name).substitutions(substitutions).payload(payload).functor(functor_p));
}
// generalized add function that takes a parameter block object for more complex instantiations
@@ -1478,6 +1492,14 @@ std::string LLNotifications::getGlobalString(const std::string& key) const
}
}
+void LLNotifications::setIgnoreAllNotifications(bool setting)
+{
+ mIgnoreAllNotifications = setting;
+}
+bool LLNotifications::getIgnoreAllNotifications()
+{
+ return mIgnoreAllNotifications;
+}
// ---
// END OF LLNotifications implementation
diff --git a/indra/llui/llnotifications.h b/indra/llui/llnotifications.h
index d01296c89e..19895c3293 100644
--- a/indra/llui/llnotifications.h
+++ b/indra/llui/llnotifications.h
@@ -100,7 +100,9 @@
// and we need this to manage the notification callbacks
#include "llevents.h"
#include "llfunctorregistry.h"
-#include "llui.h"
+#include "llpointer.h"
+#include "llinitparam.h"
+#include "llxmlnode.h"
class LLNotification;
typedef boost::shared_ptr<LLNotification> LLNotificationPtr;
@@ -157,7 +159,8 @@ public:
LLNotificationForm();
LLNotificationForm(const LLSD& sd);
- LLNotificationForm(const std::string& name, const LLXMLNodePtr xml_node);
+ LLNotificationForm(const std::string& name,
+ const LLPointer<LLXMLNode> xml_node);
LLSD asLLSD() const;
@@ -235,6 +238,11 @@ struct LLNotificationTemplate
// that URL. Obsolete this and eliminate the buttons for affected
// messages when we allow clickable URLs in the UI
U32 mURLOption;
+
+ U32 mURLOpenExternally;
+ //This is a flag that tells if the url needs to open externally dispite
+ //what the user setting is.
+
// does this notification persist across sessions? if so, it will be
// serialized to disk on first receipt and read on startup
bool mPersist;
@@ -277,42 +285,53 @@ friend class LLNotifications;
public:
// parameter object used to instantiate a new notification
- class Params : public LLParamBlock<Params>
+ struct Params : public LLInitParam::Block<Params>
{
friend class LLNotification;
- public:
- Params(const std::string& _name)
- : name(_name),
- mTemporaryResponder(false),
- functor_name(_name),
- priority(NOTIFICATION_PRIORITY_UNSPECIFIED),
- timestamp(LLDate::now())
+
+ Mandatory<std::string> name;
+
+ // optional
+ Optional<LLSD> substitutions;
+ Optional<LLSD> payload;
+ Optional<ENotificationPriority> priority;
+ Optional<LLSD> form_elements;
+ Optional<LLDate> time_stamp;
+ Optional<LLNotificationContext*> context;
+
+ struct Functor : public LLInitParam::Choice<Functor>
{
+ Alternative<std::string> name;
+ Alternative<LLNotificationFunctorRegistry::ResponseFunctor> function;
+
+ Functor()
+ : name("functor_name"),
+ function("functor")
+ {}
+ };
+ Optional<Functor> functor;
+
+ Params()
+ : name("name"),
+ priority("priority", NOTIFICATION_PRIORITY_UNSPECIFIED),
+ time_stamp("time_stamp"),
+ payload("payload"),
+ form_elements("form_elements")
+ {
+ time_stamp = LLDate::now();
}
- // pseudo-param
- Params& functor(LLNotificationFunctorRegistry::ResponseFunctor f)
- {
- functor_name = LLUUID::generateNewID().asString();
- LLNotificationFunctorRegistry::instance().registerFunctor(functor_name, f);
-
- mTemporaryResponder = true;
- return *this;
+ Params(const std::string& _name)
+ : name("name"),
+ priority("priority", NOTIFICATION_PRIORITY_UNSPECIFIED),
+ time_stamp("time_stamp"),
+ payload("payload"),
+ form_elements("form_elements")
+ {
+ functor.name = _name;
+ name = _name;
+ time_stamp = LLDate::now();
}
-
- LLMandatoryParam<std::string> name;
-
- // optional
- LLOptionalParam<LLSD> substitutions;
- LLOptionalParam<LLSD> payload;
- LLOptionalParam<ENotificationPriority> priority;
- LLOptionalParam<LLSD> form_elements;
- LLOptionalParam<LLDate> timestamp;
- LLOptionalParam<LLNotificationContext*> context;
- LLOptionalParam<std::string> functor_name;
-
- private:
- bool mTemporaryResponder;
};
private:
@@ -365,10 +384,6 @@ public:
// constructor from a saved notification
LLNotification(const LLSD& sd);
- // This is a string formatter for substituting into the message directly
- // from LLSD without going through the hopefully-to-be-obsoleted LLString
- static std::string format(const std::string& text, const LLSD& substitutions);
-
void setResponseFunctor(std::string const &responseFunctorName);
typedef enum e_response_template_type
@@ -460,16 +475,21 @@ public:
std::string getMessage() const;
std::string getLabel() const;
- std::string getURL() const
- {
- return (mTemplatep ? mTemplatep->mURL : "");
- }
+ std::string getURL() const;
+// {
+// return (mTemplatep ? mTemplatep->mURL : "");
+// }
S32 getURLOption() const
{
return (mTemplatep ? mTemplatep->mURLOption : -1);
}
-
+
+ S32 getURLOpenExternally() const
+ {
+ return(mTemplatep? mTemplatep->mURLOpenExternally : -1);
+ }
+
const LLNotificationFormPtr getForm();
const LLDate getExpiration() const
@@ -675,6 +695,14 @@ public:
this,
_1));
}
+ template <typename LISTENER>
+ LLBoundListener connectAtFrontChanged(const LISTENER& slot)
+ {
+ return LLEventDetail::visit_and_connect(slot,
+ boost::bind(&LLNotificationChannelBase::connectAtFrontChangedImpl,
+ this,
+ _1));
+ }
template <typename LISTENER>
LLBoundListener connectPassedFilter(const LISTENER& slot)
{
@@ -700,6 +728,7 @@ public:
protected:
LLBoundListener connectChangedImpl(const LLEventListener& slot);
+ LLBoundListener connectAtFrontChangedImpl(const LLEventListener& slot);
LLBoundListener connectPassedFilterImpl(const LLEventListener& slot);
LLBoundListener connectFailedFilterImpl(const LLEventListener& slot);
@@ -797,8 +826,11 @@ public:
// load notification descriptions from file;
// OK to call more than once because it will reload
bool loadTemplates();
- LLXMLNodePtr checkForXMLTemplate(LLXMLNodePtr item);
-
+ LLPointer<class LLXMLNode> checkForXMLTemplate(LLPointer<class LLXMLNode> item);
+
+ // Add a simple notification (from XUI)
+ void addFromCallback(const LLSD& name);
+
// we provide a collection of simple add notification functions so that it's reasonable to create notifications in one line
LLNotificationPtr add(const std::string& name,
const LLSD& substitutions = LLSD(),
@@ -853,6 +885,9 @@ public:
std::string getGlobalString(const std::string& key) const;
+ void setIgnoreAllNotifications(bool ignore);
+ bool getIgnoreAllNotifications();
+
private:
// we're a singleton, so we don't have a public constructor
LLNotifications();
@@ -874,13 +909,15 @@ private:
std::string mFileName;
- typedef std::map<std::string, LLXMLNodePtr> XMLTemplateMap;
+ typedef std::map<std::string, LLPointer<class LLXMLNode> > XMLTemplateMap;
XMLTemplateMap mXmlTemplates;
LLNotificationMap mUniqueNotifications;
typedef std::map<std::string, std::string> GlobalStringMap;
GlobalStringMap mGlobalStrings;
+
+ bool mIgnoreAllNotifications;
};
diff --git a/indra/llui/llpanel.cpp b/indra/llui/llpanel.cpp
index 28780c7adb..c81be6086a 100644
--- a/indra/llui/llpanel.cpp
+++ b/indra/llui/llpanel.cpp
@@ -43,6 +43,7 @@
#include "llerror.h"
#include "lltimer.h"
+#include "llbutton.h"
#include "llmenugl.h"
//#include "llstatusbar.h"
#include "llui.h"
@@ -53,75 +54,62 @@
#include "lluictrl.h"
#include "lluictrlfactory.h"
#include "llviewborder.h"
-#include "llbutton.h"
-
-// LLLayoutStack
-#include "llresizebar.h"
-#include "llcriticaldamp.h"
-
-const S32 RESIZE_BAR_OVERLAP = 1;
-const S32 RESIZE_BAR_HEIGHT = 3;
+#include "lltabcontainer.h"
-static LLRegisterWidget<LLPanel> r1("panel");
+static LLDefaultChildRegistry::Register<LLPanel> r1("panel", &LLPanel::fromXML);
-void LLPanel::init()
-{
- // mRectControl
- mBgColorAlpha = LLUI::sColorsGroup->getColor( "DefaultBackgroundColor" );
- mBgColorOpaque = LLUI::sColorsGroup->getColor( "FocusBackgroundColor" );
- mDefaultBtnHighlight = LLUI::sColorsGroup->getColor( "DefaultHighlightLight" );
- mBgVisible = FALSE;
- mBgOpaque = FALSE;
- mBorder = NULL;
- mDefaultBtn = NULL;
- setIsChrome(FALSE); //is this a decorator to a live window or a form?
- mLastTabGroup = 0;
-
- mPanelHandle.bind(this);
- setTabStop(FALSE);
-}
+LLPanel::LocalizedString::LocalizedString()
+: name("name"),
+ value("value")
+{}
-LLPanel::LLPanel()
-: mRectControl()
-{
- init();
- setName(std::string("panel"));
+const LLPanel::Params& LLPanel::getDefaultParams()
+{
+ return LLUICtrlFactory::getDefaultParams<LLPanel>();
}
-LLPanel::LLPanel(const std::string& name)
-: LLUICtrl(name, LLRect(0, 0, 0, 0), TRUE, NULL, NULL),
- mRectControl()
+LLPanel::Params::Params()
+: has_border("border", false),
+ border(""),
+ bg_opaque_color("bg_opaque_color"),
+ bg_alpha_color("bg_alpha_color"),
+ background_visible("background_visible", false),
+ background_opaque("background_opaque", false),
+ min_width("min_width", 100),
+ min_height("min_height", 100),
+ strings("string"),
+ filename("filename"),
+ class_name("class"),
+ visible_callback("visible_callback")
{
- init();
+ name = "panel";
+ addSynonym(background_visible, "bg_visible");
+ addSynonym(has_border, "border_visible");
+ addSynonym(label, "title");
}
-LLPanel::LLPanel(const std::string& name, const LLRect& rect, BOOL bordered)
-: LLUICtrl(name, rect, TRUE, NULL, NULL),
- mRectControl()
+LLPanel::LLPanel(const LLPanel::Params& p)
+: LLUICtrl(p),
+ mBgColorAlpha(p.bg_alpha_color().get()),
+ mBgColorOpaque(p.bg_opaque_color().get()),
+ mBgVisible(p.background_visible),
+ mBgOpaque(p.background_opaque),
+ mDefaultBtn(NULL),
+ mBorder(NULL),
+ mLabel(p.label),
+ mCommitCallbackRegistrar(false),
+ mEnableCallbackRegistrar(false),
+ mXMLFilename("")
{
- init();
- if (bordered)
- {
- addBorder();
- }
-}
+ setIsChrome(FALSE);
-
-LLPanel::LLPanel(const std::string& name, const std::string& rect_control, BOOL bordered)
-: LLUICtrl(name, LLUI::sConfigGroup->getRect(rect_control), TRUE, NULL, NULL),
- mRectControl( rect_control )
-{
- init();
- if (bordered)
+ if (p.has_border)
{
- addBorder();
+ addBorder(p.border);
}
-}
-
-LLPanel::~LLPanel()
-{
- storeRectControl();
+
+ mPanelHandle.bind(this);
}
// virtual
@@ -130,27 +118,31 @@ BOOL LLPanel::isPanel() const
return TRUE;
}
-// virtual
-BOOL LLPanel::postBuild()
-{
- return TRUE;
-}
-
-void LLPanel::addBorder(LLViewBorder::EBevel border_bevel,
- LLViewBorder::EStyle border_style, S32 border_thickness)
+void LLPanel::addBorder(LLViewBorder::Params p)
{
removeBorder();
- mBorder = new LLViewBorder( std::string("panel border"),
- LLRect(0, getRect().getHeight(), getRect().getWidth(), 0),
- border_bevel, border_style, border_thickness );
- mBorder->setSaveToXML(false);
+ p.rect = getLocalRect();
+
+ mBorder = LLUICtrlFactory::create<LLViewBorder>(p);
addChild( mBorder );
}
+void LLPanel::addBorder()
+{
+ LLViewBorder::Params p;
+ p.border_thickness(LLPANEL_BORDER_WIDTH);
+ addBorder(p);
+}
+
+
void LLPanel::removeBorder()
{
- delete mBorder;
- mBorder = NULL;
+ if (mBorder)
+ {
+ removeChild(mBorder);
+ delete mBorder;
+ mBorder = NULL;
+ }
}
@@ -203,18 +195,19 @@ void LLPanel::draw()
LLView::draw();
}
-void LLPanel::updateDefaultBtn()
+/*virtual*/
+void LLPanel::setAlpha(F32 alpha)
{
- // This method does not call LLView::draw() so callers will need
- // to take care of that themselves at the appropriate place in
- // their rendering sequence
+ mBgColorOpaque.setAlpha(alpha);
+}
+void LLPanel::updateDefaultBtn()
+{
if( mDefaultBtn)
{
if (gFocusMgr.childHasKeyboardFocus( this ) && mDefaultBtn->getEnabled())
{
- LLUICtrl* focus_ctrl = gFocusMgr.getKeyboardFocus();
- LLButton* buttonp = dynamic_cast<LLButton*>(focus_ctrl);
+ LLButton* buttonp = dynamic_cast<LLButton*>(gFocusMgr.getKeyboardFocus());
BOOL focus_is_child_button = buttonp && buttonp->getCommitOnReturn();
// only enable default button when current focus is not a return-capturing button
mDefaultBtn->setBorderEnabled(!focus_is_child_button);
@@ -258,30 +251,16 @@ void LLPanel::setDefaultBtn(const std::string& id)
}
}
-void LLPanel::addCtrl( LLUICtrl* ctrl, S32 tab_group)
-{
- mLastTabGroup = tab_group;
-
- LLView::addCtrl(ctrl, tab_group);
-}
-
-void LLPanel::addCtrlAtEnd( LLUICtrl* ctrl, S32 tab_group)
-{
- mLastTabGroup = tab_group;
-
- LLView::addCtrlAtEnd(ctrl, tab_group);
-}
-
BOOL LLPanel::handleKeyHere( KEY key, MASK mask )
{
BOOL handled = FALSE;
- LLUICtrl* cur_focus = gFocusMgr.getKeyboardFocus();
+ LLUICtrl* cur_focus = dynamic_cast<LLUICtrl*>(gFocusMgr.getKeyboardFocus());
// handle user hitting ESC to defocus
if (key == KEY_ESCAPE)
{
- gFocusMgr.setKeyboardFocus(NULL);
+ setFocus(FALSE);
return TRUE;
}
else if( (mask == MASK_SHIFT) && (KEY_TAB == key))
@@ -308,29 +287,26 @@ BOOL LLPanel::handleKeyHere( KEY key, MASK mask )
}
}
}
-
- // If we have a default button, click it when
- // return is pressed, unless current focus is a return-capturing button
- // in which case *that* button will handle the return key
- LLButton* focused_button = dynamic_cast<LLButton*>(cur_focus);
- if (cur_focus && !(focused_button && focused_button->getCommitOnReturn()))
+
+ // If RETURN was pressed and something has focus, call onCommit()
+ if (!handled && cur_focus && key == KEY_RETURN && mask == MASK_NONE)
{
- // RETURN key means hit default button in this case
- if (key == KEY_RETURN && mask == MASK_NONE
- && mDefaultBtn != NULL
- && mDefaultBtn->getVisible()
- && mDefaultBtn->getEnabled())
+ LLButton* focused_button = dynamic_cast<LLButton*>(cur_focus);
+ if (focused_button && focused_button->getCommitOnReturn())
+ {
+ // current focus is a return-capturing button,
+ // let *that* button handle the return key
+ handled = FALSE;
+ }
+ else if (mDefaultBtn && mDefaultBtn->getVisible() && mDefaultBtn->getEnabled())
{
+ // If we have a default button, click it when return is pressed
mDefaultBtn->onCommit();
handled = TRUE;
}
- }
-
- if (key == KEY_RETURN && mask == MASK_NONE)
- {
- // set keyboard focus to self to trigger commitOnFocusLost behavior on current ctrl
- if (cur_focus && cur_focus->acceptsTextInput())
+ else if (cur_focus->acceptsTextInput())
{
+ // call onCommit for text input handling control
cur_focus->onCommit();
handled = TRUE;
}
@@ -339,55 +315,24 @@ BOOL LLPanel::handleKeyHere( KEY key, MASK mask )
return handled;
}
-BOOL LLPanel::checkRequirements()
+void LLPanel::handleVisibilityChange ( BOOL new_visibility )
{
- if (!mRequirementsError.empty())
- {
- LLSD args;
- args["COMPONENTS"] = mRequirementsError;
- args["FLOATER"] = getName();
-
- llwarns << getName() << " failed requirements check on: \n"
- << mRequirementsError << llendl;
-
- LLNotifications::instance().add(LLNotification::Params("FailedRequirementsCheck").payload(args));
- mRequirementsError.clear();
- return FALSE;
- }
-
- return TRUE;
+ LLUICtrl::handleVisibilityChange ( new_visibility );
+ mVisibleSignal(this, LLSD(new_visibility) ); // Pass BOOL as LLSD
}
void LLPanel::setFocus(BOOL b)
{
- if( b )
+ if( b && !hasFocus())
{
- if (!gFocusMgr.childHasKeyboardFocus(this))
- {
- //refresh();
- if (!focusFirstItem())
- {
- LLUICtrl::setFocus(TRUE);
- }
- onFocusReceived();
- }
+ // give ourselves focus preemptively, to avoid infinite loop
+ LLUICtrl::setFocus(TRUE);
+ // then try to pass to first valid child
+ focusFirstItem();
}
else
{
- if( this == gFocusMgr.getKeyboardFocus() )
- {
- gFocusMgr.setKeyboardFocus( NULL );
- }
- else
- {
- //RN: why is this here?
- LLView::ctrl_list_t ctrls = getCtrlList();
- for (LLView::ctrl_list_t::iterator ctrl_it = ctrls.begin(); ctrl_it != ctrls.end(); ++ctrl_it)
- {
- LLUICtrl* ctrl = *ctrl_it;
- ctrl->setFocus( FALSE );
- }
- }
+ LLUICtrl::setFocus(b);
}
}
@@ -399,191 +344,198 @@ void LLPanel::setBorderVisible(BOOL b)
}
}
-// virtual
-LLXMLNodePtr LLPanel::getXML(bool save_children) const
-{
- LLXMLNodePtr node = LLView::getXML();
+LLFastTimer::DeclareTimer FTM_PANEL_CONSTRUCTION("Panel Construction");
- if (mBorder && mBorder->getVisible())
- {
- node->createChild("border", TRUE)->setBoolValue(TRUE);
- }
+LLView* LLPanel::fromXML(LLXMLNodePtr node, LLView* parent, LLXMLNodePtr output_node)
+{
+ std::string name("panel");
+ node->getAttributeString("name", name);
- if (!mRectControl.empty())
- {
- node->createChild("rect_control", TRUE)->setStringValue(mRectControl);
- }
+ std::string class_attr;
+ node->getAttributeString("class", class_attr);
- if (!mLabel.empty())
- {
- node->createChild("label", TRUE)->setStringValue(mLabel);
- }
-
- if (save_children)
+ LLPanel* panelp = NULL;
+
{
- LLView::child_list_const_reverse_iter_t rit;
- for (rit = getChildList()->rbegin(); rit != getChildList()->rend(); ++rit)
+ LLFastTimer timer(FTM_PANEL_CONSTRUCTION);
+
+ if(!class_attr.empty())
{
- LLView* childp = *rit;
-
- if (childp->getSaveToXML())
+ panelp = LLRegisterPanelClass::instance().createPanelClass(class_attr);
+ if (!panelp)
{
- LLXMLNodePtr xml_node = childp->getXML();
-
- node->addChild(xml_node);
+ llwarns << "Panel class \"" << class_attr << "\" not registered." << llendl;
}
}
- }
- return node;
-}
-
-LLView* LLPanel::fromXML(LLXMLNodePtr node, LLView* parent, LLUICtrlFactory *factory)
-{
- std::string name("panel");
- node->getAttributeString("name", name);
+ if (!panelp)
+ {
+ panelp = LLUICtrlFactory::getInstance()->createFactoryPanel(name);
+ }
- LLPanel* panelp = factory->createFactoryPanel(name);
- // Fall back on a default panel, if there was no special factory.
- if (!panelp)
+ }
+ // factory panels may have registered their own factory maps
+ if (!panelp->getFactoryMap().empty())
{
- LLRect rect;
- createRect(node, rect, parent, LLRect());
- // create a new panel without a border, by default
- panelp = new LLPanel(name, rect, FALSE);
- panelp->initPanelXML(node, parent, factory);
- // preserve panel's width and height, but override the location
- const LLRect& panelrect = panelp->getRect();
- S32 w = panelrect.getWidth();
- S32 h = panelrect.getHeight();
- rect.setLeftTopAndSize(rect.mLeft, rect.mTop, w, h);
- panelp->setRect(rect);
+ LLUICtrlFactory::instance().pushFactoryFunctions(&panelp->getFactoryMap());
}
- else
+ // for local registry callbacks; define in constructor, referenced in XUI or postBuild
+ panelp->mCommitCallbackRegistrar.pushScope();
+ panelp->mEnableCallbackRegistrar.pushScope();
+
+ panelp->initPanelXML(node, parent, output_node);
+
+ panelp->mCommitCallbackRegistrar.popScope();
+ panelp->mEnableCallbackRegistrar.popScope();
+
+ if (panelp && !panelp->getFactoryMap().empty())
{
- panelp->initPanelXML(node, parent, factory);
+ LLUICtrlFactory::instance().popFactoryFunctions();
}
return panelp;
}
-BOOL LLPanel::initPanelXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFactory *factory)
+void LLPanel::initFromParams(const LLPanel::Params& p)
{
- std::string name = getName();
- node->getAttributeString("name", name);
- setName(name);
-
- setPanelParameters(node, parent);
+ //setting these here since panel constructor not called with params
+ //and LLView::initFromParams will use them to set visible and enabled
+ setVisible(p.visible);
+ setEnabled(p.enabled);
- initChildrenXML(node, factory);
-
- std::string xml_filename;
- node->getAttributeString("filename", xml_filename);
+ // control_name, tab_stop, focus_lost_callback, initial_value, rect, enabled, visible
+ LLUICtrl::initFromParams(p);
+
+ // visible callback
+ if (p.visible_callback.isProvided())
+ initCommitCallback(p.visible_callback, mVisibleSignal);
+
+ for (LLInitParam::ParamIterator<LocalizedString>::const_iterator it = p.strings().begin();
+ it != p.strings().end();
+ ++it)
+ {
+ mUIStrings[it->name] = it->value;
+ }
- BOOL didPost;
+ setLabel(p.label());
+ setShape(p.rect);
+ parseFollowsFlags(p);
- if (!xml_filename.empty())
+ setToolTip(p.tool_tip());
+ setSaveToXML(p.from_xui);
+
+ mHoverCursor = getCursorFromString(p.hover_cursor);
+
+ if (p.has_border)
{
- didPost = factory->buildPanel(this, xml_filename, NULL);
-
- LLRect new_rect = getRect();
- // override rectangle with embedding parameters as provided
- createRect(node, new_rect, parent);
- setOrigin(new_rect.mLeft, new_rect.mBottom);
- reshape(new_rect.getWidth(), new_rect.getHeight());
- // optionally override follows flags from including nodes
- parseFollowsFlags(node);
+ addBorder(p.border);
}
- else
+ // let constructors set this value if not provided
+ if (p.use_bounding_rect.isProvided())
{
- didPost = FALSE;
+ setUseBoundingRect(p.use_bounding_rect);
}
+ setDefaultTabGroup(p.default_tab_group);
+ setMouseOpaque(p.mouse_opaque);
+
+ setBackgroundVisible(p.background_visible);
+ setBackgroundOpaque(p.background_opaque);
+ setBackgroundColor(p.bg_opaque_color().get());
+ setTransparentColor(p.bg_alpha_color().get());
- if (!didPost)
- {
- postBuild();
- didPost = TRUE;
- }
-
- return didPost;
}
-void LLPanel::initChildrenXML(LLXMLNodePtr node, LLUICtrlFactory* factory)
+static LLFastTimer::DeclareTimer FTM_PANEL_SETUP("Panel Setup");
+static LLFastTimer::DeclareTimer FTM_EXTERNAL_PANEL_LOAD("Load Extern Panel Reference");
+static LLFastTimer::DeclareTimer FTM_PANEL_POSTBUILD("Panel PostBuild");
+
+BOOL LLPanel::initPanelXML(LLXMLNodePtr node, LLView *parent, LLXMLNodePtr output_node)
{
- LLXMLNodePtr child;
- for (child = node->getFirstChild(); child.notNull(); child = child->getNextSibling())
+ const LLPanel::Params& default_params(LLUICtrlFactory::getDefaultParams<LLPanel>());
+ Params params(default_params);
+
{
- // look for string declarations for programmatic text
- if (child->hasName("string"))
+ LLFastTimer timer(FTM_PANEL_SETUP);
+
+ LLXMLNodePtr referenced_xml;
+ std::string xml_filename = mXMLFilename;
+
+ // if the panel didn't provide a filename, check the node
+ if (xml_filename.empty())
{
- std::string string_name;
- child->getAttributeString("name", string_name);
- if (!string_name.empty())
- {
- mUIStrings[string_name] = child->getTextContents();
- }
+ node->getAttributeString("filename", xml_filename);
}
- else
+
+ if (!xml_filename.empty())
{
- factory->createWidget(this, child);
- }
- }
-}
+ LLFastTimer timer(FTM_EXTERNAL_PANEL_LOAD);
+ if (output_node)
+ {
+ //if we are exporting, we want to export the current xml
+ //not the referenced xml
+ LLXUIParser::instance().readXUI(node, params);
+ Params output_params(params);
+ setupParamsForExport(output_params, parent);
+ output_node->setName(node->getName()->mString);
+ LLXUIParser::instance().writeXUI(
+ output_node, output_params, &default_params);
+ return TRUE;
+ }
+
+ if (!LLUICtrlFactory::getLayeredXMLNode(xml_filename, referenced_xml))
+ {
+ llwarns << "Couldn't parse panel from: " << xml_filename << llendl;
-void LLPanel::setPanelParameters(LLXMLNodePtr node, LLView* parent)
-{
- /////// Rect, follows, tool_tip, enabled, visible attributes ///////
- initFromXML(node, parent);
+ return FALSE;
+ }
- /////// Border attributes ///////
- BOOL border = mBorder != NULL;
- node->getAttributeBOOL("border", border);
- if (border)
- {
- LLViewBorder::EBevel bevel_style = LLViewBorder::BEVEL_OUT;
- LLViewBorder::getBevelFromAttribute(node, bevel_style);
+ LLXUIParser::instance().readXUI(referenced_xml, params);
+
+ // add children using dimensions from referenced xml for consistent layout
+ setShape(params.rect);
+ LLUICtrlFactory::createChildren(this, referenced_xml, child_registry_t::instance());
+ }
- LLViewBorder::EStyle border_style = LLViewBorder::STYLE_LINE;
- std::string border_string;
- node->getAttributeString("border_style", border_string);
- LLStringUtil::toLower(border_string);
+ LLXUIParser::instance().readXUI(node, params);
- if (border_string == "texture")
+ if (output_node)
{
- border_style = LLViewBorder::STYLE_TEXTURE;
+ Params output_params(params);
+ setupParamsForExport(output_params, parent);
+ output_node->setName(node->getName()->mString);
+ LLXUIParser::instance().writeXUI(
+ output_node, output_params, &default_params);
+ }
+
+ setupParams(params, parent);
+ {
+ LLFastTimer timer(FTM_PANEL_CONSTRUCTION);
+ initFromParams(params);
}
- S32 border_thickness = LLPANEL_BORDER_WIDTH;
- node->getAttributeS32("border_thickness", border_thickness);
+ // add children
+ LLUICtrlFactory::createChildren(this, node, child_registry_t::instance(), output_node);
- addBorder(bevel_style, border_style, border_thickness);
- }
- else
- {
- removeBorder();
+ // Connect to parent after children are built, because tab containers
+ // do a reshape() on their child panels, which requires that the children
+ // be built/added. JC
+ if (parent)
+ {
+ S32 tab_group = params.tab_group.isProvided() ? params.tab_group() : -1;
+ parent->addChild(this, tab_group);
+ }
+
+ {
+ LLFastTimer timer(FTM_PANEL_POSTBUILD);
+ postBuild();
+ }
}
+ return TRUE;
+}
- /////// Background attributes ///////
- BOOL background_visible = mBgVisible;
- node->getAttributeBOOL("background_visible", background_visible);
- setBackgroundVisible(background_visible);
-
- BOOL background_opaque = mBgOpaque;
- node->getAttributeBOOL("background_opaque", background_opaque);
- setBackgroundOpaque(background_opaque);
-
- LLColor4 color;
- color = mBgColorOpaque;
- LLUICtrlFactory::getAttributeColor(node,"bg_opaque_color", color);
- setBackgroundColor(color);
-
- color = mBgColorAlpha;
- LLUICtrlFactory::getAttributeColor(node,"bg_alpha_color", color);
- setTransparentColor(color);
-
- std::string label = getLabel();
- node->getAttributeString("label", label);
- setLabel(label);
+bool LLPanel::hasString(const std::string& name)
+{
+ return mUIStrings.find(name) != mUIStrings.end();
}
std::string LLPanel::getString(const std::string& name, const LLStringUtil::format_map_t& args) const
@@ -597,9 +549,7 @@ std::string LLPanel::getString(const std::string& name, const LLStringUtil::form
return formatted_string.getString();
}
std::string err_str("Failed to find string " + name + " in panel " + getName()); //*TODO: Translate
- // *TODO: once the QAR-369 ui-cleanup work on settings is in we need to change the following line to be
- //if(LLUI::sConfigGroup->getBOOL("QAMode"))
- if(LLUI::sQAMode)
+ if(LLUI::sSettingGroups["config"]->getBOOL("QAMode"))
{
llerrs << err_str << llendl;
}
@@ -618,7 +568,7 @@ std::string LLPanel::getString(const std::string& name) const
return found_it->second;
}
std::string err_str("Failed to find string " + name + " in panel " + getName()); //*TODO: Translate
- if(LLUI::sQAMode)
+ if(LLUI::sSettingGroups["config"]->getBOOL("QAMode"))
{
llerrs << err_str << llendl;
}
@@ -632,7 +582,7 @@ std::string LLPanel::getString(const std::string& name) const
void LLPanel::childSetVisible(const std::string& id, bool visible)
{
- LLView* child = getChild<LLView>(id);
+ LLView* child = findChild<LLView>(id);
if (child)
{
child->setVisible(visible);
@@ -641,7 +591,7 @@ void LLPanel::childSetVisible(const std::string& id, bool visible)
bool LLPanel::childIsVisible(const std::string& id) const
{
- LLView* child = getChild<LLView>(id);
+ LLView* child = findChild<LLView>(id);
if (child)
{
return (bool)child->getVisible();
@@ -651,7 +601,7 @@ bool LLPanel::childIsVisible(const std::string& id) const
void LLPanel::childSetEnabled(const std::string& id, bool enabled)
{
- LLView* child = getChild<LLView>(id);
+ LLView* child = findChild<LLView>(id);
if (child)
{
child->setEnabled(enabled);
@@ -660,7 +610,7 @@ void LLPanel::childSetEnabled(const std::string& id, bool enabled)
void LLPanel::childSetTentative(const std::string& id, bool tentative)
{
- LLView* child = getChild<LLView>(id);
+ LLView* child = findChild<LLView>(id);
if (child)
{
child->setTentative(tentative);
@@ -669,7 +619,7 @@ void LLPanel::childSetTentative(const std::string& id, bool tentative)
bool LLPanel::childIsEnabled(const std::string& id) const
{
- LLView* child = getChild<LLView>(id);
+ LLView* child = findChild<LLView>(id);
if (child)
{
return (bool)child->getEnabled();
@@ -680,7 +630,7 @@ bool LLPanel::childIsEnabled(const std::string& id) const
void LLPanel::childSetToolTip(const std::string& id, const std::string& msg)
{
- LLView* child = getChild<LLView>(id);
+ LLView* child = findChild<LLView>(id);
if (child)
{
child->setToolTip(msg);
@@ -689,7 +639,7 @@ void LLPanel::childSetToolTip(const std::string& id, const std::string& msg)
void LLPanel::childSetRect(const std::string& id, const LLRect& rect)
{
- LLView* child = getChild<LLView>(id);
+ LLView* child = findChild<LLView>(id);
if (child)
{
child->setRect(rect);
@@ -698,7 +648,7 @@ void LLPanel::childSetRect(const std::string& id, const LLRect& rect)
bool LLPanel::childGetRect(const std::string& id, LLRect& rect) const
{
- LLView* child = getChild<LLView>(id);
+ LLView* child = findChild<LLView>(id);
if (child)
{
rect = child->getRect();
@@ -709,7 +659,7 @@ bool LLPanel::childGetRect(const std::string& id, LLRect& rect) const
void LLPanel::childSetFocus(const std::string& id, BOOL focus)
{
- LLUICtrl* child = getChild<LLUICtrl>(id, true);
+ LLUICtrl* child = findChild<LLUICtrl>(id);
if (child)
{
child->setFocus(focus);
@@ -718,81 +668,59 @@ void LLPanel::childSetFocus(const std::string& id, BOOL focus)
BOOL LLPanel::childHasFocus(const std::string& id)
{
- LLUICtrl* child = getChild<LLUICtrl>(id, true);
+ LLUICtrl* child = findChild<LLUICtrl>(id);
if (child)
{
return child->hasFocus();
}
else
{
- childNotFound(id);
return FALSE;
}
}
-
-void LLPanel::childSetFocusChangedCallback(const std::string& id, void (*cb)(LLFocusableElement*, void*), void* user_data)
-{
- LLUICtrl* child = getChild<LLUICtrl>(id, true);
- if (child)
- {
- child->setFocusChangedCallback(cb, user_data);
- }
-}
-
-void LLPanel::childSetCommitCallback(const std::string& id, void (*cb)(LLUICtrl*, void*), void *userdata )
-{
- LLUICtrl* child = getChild<LLUICtrl>(id, true);
- if (child)
- {
- child->setCommitCallback(cb);
- child->setCallbackUserData(userdata);
- }
-}
-
-void LLPanel::childSetDoubleClickCallback(const std::string& id, void (*cb)(void*), void *userdata )
+// *TODO: Deprecate; for backwards compatability only:
+// Prefer getChild<LLUICtrl>("foo")->setCommitCallback(boost:bind(...)),
+// which takes a generic slot. Or use mCommitCallbackRegistrar.add() with
+// a named callback and reference it in XML.
+void LLPanel::childSetCommitCallback(const std::string& id, boost::function<void (LLUICtrl*,void*)> cb, void* data)
{
- LLUICtrl* child = getChild<LLUICtrl>(id, true);
+ LLUICtrl* child = findChild<LLUICtrl>(id);
if (child)
{
- child->setDoubleClickCallback(cb);
- if (userdata)
- {
- child->setCallbackUserData(userdata);
- }
+ child->setCommitCallback(boost::bind(cb, child, data));
}
}
-void LLPanel::childSetValidate(const std::string& id, BOOL (*cb)(LLUICtrl*, void*))
+void LLPanel::childSetValidate(const std::string& id, boost::function<bool (const LLSD& data)> cb)
{
- LLUICtrl* child = getChild<LLUICtrl>(id, true);
+ LLUICtrl* child = findChild<LLUICtrl>(id);
if (child)
{
child->setValidateBeforeCommit(cb);
}
}
-void LLPanel::childSetUserData(const std::string& id, void* userdata)
+void LLPanel::childSetColor(const std::string& id, const LLColor4& color)
{
- LLUICtrl* child = getChild<LLUICtrl>(id, true);
+ LLUICtrl* child = findChild<LLUICtrl>(id);
if (child)
{
- child->setCallbackUserData(userdata);
+ child->setColor(color);
}
}
-
-void LLPanel::childSetColor(const std::string& id, const LLColor4& color)
+void LLPanel::childSetAlpha(const std::string& id, F32 alpha)
{
LLUICtrl* child = getChild<LLUICtrl>(id, true);
if (child)
{
- child->setColor(color);
+ child->setAlpha(alpha);
}
}
LLCtrlSelectionInterface* LLPanel::childGetSelectionInterface(const std::string& id) const
{
- LLUICtrl* child = getChild<LLUICtrl>(id, true);
+ LLUICtrl* child = findChild<LLUICtrl>(id);
if (child)
{
return child->getSelectionInterface();
@@ -802,7 +730,7 @@ LLCtrlSelectionInterface* LLPanel::childGetSelectionInterface(const std::string&
LLCtrlListInterface* LLPanel::childGetListInterface(const std::string& id) const
{
- LLUICtrl* child = getChild<LLUICtrl>(id, true);
+ LLUICtrl* child = findChild<LLUICtrl>(id);
if (child)
{
return child->getListInterface();
@@ -812,7 +740,7 @@ LLCtrlListInterface* LLPanel::childGetListInterface(const std::string& id) const
LLCtrlScrollInterface* LLPanel::childGetScrollInterface(const std::string& id) const
{
- LLUICtrl* child = getChild<LLUICtrl>(id, true);
+ LLUICtrl* child = findChild<LLUICtrl>(id);
if (child)
{
return child->getScrollInterface();
@@ -822,7 +750,7 @@ LLCtrlScrollInterface* LLPanel::childGetScrollInterface(const std::string& id) c
void LLPanel::childSetValue(const std::string& id, LLSD value)
{
- LLView* child = getChild<LLView>(id, true);
+ LLUICtrl* child = findChild<LLUICtrl>(id);
if (child)
{
child->setValue(value);
@@ -831,7 +759,7 @@ void LLPanel::childSetValue(const std::string& id, LLSD value)
LLSD LLPanel::childGetValue(const std::string& id) const
{
- LLView* child = getChild<LLView>(id, true);
+ LLUICtrl* child = findChild<LLUICtrl>(id);
if (child)
{
return child->getValue();
@@ -842,7 +770,7 @@ LLSD LLPanel::childGetValue(const std::string& id) const
BOOL LLPanel::childSetTextArg(const std::string& id, const std::string& key, const LLStringExplicit& text)
{
- LLUICtrl* child = getChild<LLUICtrl>(id, true);
+ LLUICtrl* child = findChild<LLUICtrl>(id);
if (child)
{
return child->setTextArg(key, text);
@@ -852,7 +780,7 @@ BOOL LLPanel::childSetTextArg(const std::string& id, const std::string& key, con
BOOL LLPanel::childSetLabelArg(const std::string& id, const std::string& key, const LLStringExplicit& text)
{
- LLView* child = getChild<LLView>(id);
+ LLView* child = findChild<LLView>(id);
if (child)
{
return child->setLabelArg(key, text);
@@ -862,7 +790,7 @@ BOOL LLPanel::childSetLabelArg(const std::string& id, const std::string& key, co
BOOL LLPanel::childSetToolTipArg(const std::string& id, const std::string& key, const LLStringExplicit& text)
{
- LLView* child = getChildView(id, true, FALSE);
+ LLView* child = findChild<LLView>(id);
if (child)
{
return child->setToolTipArg(key, text);
@@ -870,27 +798,9 @@ BOOL LLPanel::childSetToolTipArg(const std::string& id, const std::string& key,
return FALSE;
}
-void LLPanel::childSetMinValue(const std::string& id, LLSD min_value)
-{
- LLUICtrl* child = getChild<LLUICtrl>(id, true);
- if (child)
- {
- child->setMinValue(min_value);
- }
-}
-
-void LLPanel::childSetMaxValue(const std::string& id, LLSD max_value)
-{
- LLUICtrl* child = getChild<LLUICtrl>(id, true);
- if (child)
- {
- child->setMaxValue(max_value);
- }
-}
-
void LLPanel::childShowTab(const std::string& id, const std::string& tabname, bool visible)
{
- LLTabContainer* child = getChild<LLTabContainer>(id);
+ LLTabContainer* child = findChild<LLTabContainer>(id);
if (child)
{
child->selectTabByName(tabname);
@@ -899,7 +809,7 @@ void LLPanel::childShowTab(const std::string& id, const std::string& tabname, bo
LLPanel *LLPanel::childGetVisibleTab(const std::string& id) const
{
- LLTabContainer* child = getChild<LLTabContainer>(id);
+ LLTabContainer* child = findChild<LLTabContainer>(id);
if (child)
{
return child->getCurrentPanel();
@@ -907,40 +817,9 @@ LLPanel *LLPanel::childGetVisibleTab(const std::string& id) const
return NULL;
}
-void LLPanel::childSetTabChangeCallback(const std::string& id, const std::string& tabname, void (*on_tab_clicked)(void*, bool), void *userdata, void (*on_precommit)(void*,bool))
-{
- LLTabContainer* child = getChild<LLTabContainer>(id);
- if (child)
- {
- LLPanel *panel = child->getPanelByName(tabname);
- if (panel)
- {
- child->setTabChangeCallback(panel, on_tab_clicked);
- child->setTabUserData(panel, userdata);
- if (on_precommit)
- {
- child->setTabPrecommitChangeCallback(panel, on_precommit);
- }
- }
- }
-}
-
-void LLPanel::childSetKeystrokeCallback(const std::string& id, void (*keystroke_callback)(LLLineEditor* caller, void* user_data), void *user_data)
-{
- LLLineEditor* child = getChild<LLLineEditor>(id);
- if (child)
- {
- child->setKeystrokeCallback(keystroke_callback);
- if (user_data)
- {
- child->setCallbackUserData(user_data);
- }
- }
-}
-
void LLPanel::childSetPrevalidate(const std::string& id, BOOL (*func)(const LLWString &) )
{
- LLLineEditor* child = getChild<LLLineEditor>(id);
+ LLLineEditor* child = findChild<LLLineEditor>(id);
if (child)
{
child->setPrevalidate(func);
@@ -949,7 +828,7 @@ void LLPanel::childSetPrevalidate(const std::string& id, BOOL (*func)(const LLWS
void LLPanel::childSetWrappedText(const std::string& id, const std::string& text, bool visible)
{
- LLTextBox* child = getChild<LLTextBox>(id);
+ LLTextBox* child = findChild<LLTextBox>(id);
if (child)
{
child->setVisible(visible);
@@ -957,692 +836,29 @@ void LLPanel::childSetWrappedText(const std::string& id, const std::string& text
}
}
-void LLPanel::childSetAction(const std::string& id, void(*function)(void*), void* value)
+void LLPanel::childSetAction(const std::string& id, boost::function<void(void*)> function, void* value)
{
- LLButton* button = getChild<LLButton>(id);
+ LLButton* button = findChild<LLButton>(id);
if (button)
{
- button->setClickedCallback(function, value);
+ button->setClickedCallback(boost::bind(function, value));
}
}
-void LLPanel::childSetActionTextbox(const std::string& id, void(*function)(void*), void* value)
+void LLPanel::childSetActionTextbox(const std::string& id, boost::function<void(void*)> function, void* value)
{
- LLTextBox* textbox = getChild<LLTextBox>(id);
+ LLTextBox* textbox = findChild<LLTextBox>(id);
if (textbox)
{
- textbox->setClickedCallback(function, value);
+ textbox->setClickedCallback(boost::bind(function, value));
}
}
void LLPanel::childSetControlName(const std::string& id, const std::string& control_name)
{
- LLView* view = getChild<LLView>(id);
+ LLUICtrl* view = findChild<LLUICtrl>(id);
if (view)
{
view->setControlName(control_name, NULL);
}
}
-
-//virtual
-LLView* LLPanel::getChildView(const std::string& name, BOOL recurse, BOOL create_if_missing) const
-{
- // just get child, don't try to create a dummy one
- LLView* view = LLUICtrl::getChildView(name, recurse, FALSE);
- if (!view && !recurse)
- {
- childNotFound(name);
- }
- if (!view && create_if_missing)
- {
- view = createDummyWidget<LLView>(name);
- }
- return view;
-}
-
-void LLPanel::childNotFound(const std::string& id) const
-{
- if (mExpectedMembers.find(id) == mExpectedMembers.end())
- {
- mNewExpectedMembers.insert(id);
- }
-}
-
-void LLPanel::childDisplayNotFound()
-{
- if (mNewExpectedMembers.empty())
- {
- return;
- }
- std::string msg;
- expected_members_list_t::iterator itor;
- for (itor=mNewExpectedMembers.begin(); itor!=mNewExpectedMembers.end(); ++itor)
- {
- msg.append(*itor);
- msg.append("\n");
- mExpectedMembers.insert(*itor);
- }
- mNewExpectedMembers.clear();
- LLSD args;
- args["CONTROLS"] = msg;
- LLNotifications::instance().add("FloaterNotFound", args);
-}
-
-void LLPanel::storeRectControl()
-{
- if( !mRectControl.empty() )
- {
- LLUI::sConfigGroup->setRect( mRectControl, getRect() );
- }
-}
-
-
-//
-// LLLayoutStack
-//
-struct LLLayoutStack::LLEmbeddedPanel
-{
- LLEmbeddedPanel(LLPanel* panelp, eLayoutOrientation orientation, S32 min_width, S32 min_height, BOOL auto_resize, BOOL user_resize) :
- mPanel(panelp),
- mMinWidth(min_width),
- mMinHeight(min_height),
- mAutoResize(auto_resize),
- mUserResize(user_resize),
- mOrientation(orientation),
- mCollapsed(FALSE),
- mCollapseAmt(0.f),
- mVisibleAmt(1.f) // default to fully visible
- {
- LLResizeBar::Side side = (orientation == HORIZONTAL) ? LLResizeBar::RIGHT : LLResizeBar::BOTTOM;
- LLRect resize_bar_rect = panelp->getRect();
-
- S32 min_dim;
- if (orientation == HORIZONTAL)
- {
- min_dim = mMinHeight;
- }
- else
- {
- min_dim = mMinWidth;
- }
- mResizeBar = new LLResizeBar(std::string("resizer"), mPanel, LLRect(), min_dim, S32_MAX, side);
- mResizeBar->setEnableSnapping(FALSE);
- // panels initialized as hidden should not start out partially visible
- if (!mPanel->getVisible())
- {
- mVisibleAmt = 0.f;
- }
- }
-
- ~LLEmbeddedPanel()
- {
- // probably not necessary, but...
- delete mResizeBar;
- mResizeBar = NULL;
- }
-
- F32 getCollapseFactor()
- {
- if (mOrientation == HORIZONTAL)
- {
- F32 collapse_amt =
- clamp_rescale(mCollapseAmt, 0.f, 1.f, 1.f, (F32)mMinWidth / (F32)llmax(1, mPanel->getRect().getWidth()));
- return mVisibleAmt * collapse_amt;
- }
- else
- {
- F32 collapse_amt =
- clamp_rescale(mCollapseAmt, 0.f, 1.f, 1.f, llmin(1.f, (F32)mMinHeight / (F32)llmax(1, mPanel->getRect().getHeight())));
- return mVisibleAmt * collapse_amt;
- }
- }
-
- LLPanel* mPanel;
- S32 mMinWidth;
- S32 mMinHeight;
- BOOL mAutoResize;
- BOOL mUserResize;
- BOOL mCollapsed;
- LLResizeBar* mResizeBar;
- eLayoutOrientation mOrientation;
- F32 mVisibleAmt;
- F32 mCollapseAmt;
-};
-
-static LLRegisterWidget<LLLayoutStack> r2("layout_stack");
-
-LLLayoutStack::LLLayoutStack(eLayoutOrientation orientation) :
- mOrientation(orientation),
- mMinWidth(0),
- mMinHeight(0),
- mPanelSpacing(RESIZE_BAR_HEIGHT)
-{
-}
-
-LLLayoutStack::~LLLayoutStack()
-{
- std::for_each(mPanels.begin(), mPanels.end(), DeletePointer());
-}
-
-void LLLayoutStack::draw()
-{
- updateLayout();
-
- e_panel_list_t::iterator panel_it;
- for (panel_it = mPanels.begin(); panel_it != mPanels.end(); ++panel_it)
- {
- // clip to layout rectangle, not bounding rectangle
- LLRect clip_rect = (*panel_it)->mPanel->getRect();
- // scale clipping rectangle by visible amount
- if (mOrientation == HORIZONTAL)
- {
- clip_rect.mRight = clip_rect.mLeft + llround((F32)clip_rect.getWidth() * (*panel_it)->getCollapseFactor());
- }
- else
- {
- clip_rect.mBottom = clip_rect.mTop - llround((F32)clip_rect.getHeight() * (*panel_it)->getCollapseFactor());
- }
-
- LLPanel* panelp = (*panel_it)->mPanel;
-
- LLLocalClipRect clip(clip_rect);
- // only force drawing invisible children if visible amount is non-zero
- drawChild(panelp, 0, 0, !clip_rect.isNull());
- }
-}
-
-void LLLayoutStack::removeCtrl(LLUICtrl* ctrl)
-{
- LLEmbeddedPanel* embedded_panelp = findEmbeddedPanel((LLPanel*)ctrl);
-
- if (embedded_panelp)
- {
- mPanels.erase(std::find(mPanels.begin(), mPanels.end(), embedded_panelp));
- delete embedded_panelp;
- }
-
- // need to update resizebars
-
- calcMinExtents();
-
- LLView::removeCtrl(ctrl);
-}
-
-LLXMLNodePtr LLLayoutStack::getXML(bool save_children) const
-{
- LLXMLNodePtr node = LLView::getXML();
- return node;
-}
-
-//static
-LLView* LLLayoutStack::fromXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFactory *factory)
-{
- std::string orientation_string("vertical");
- node->getAttributeString("orientation", orientation_string);
-
- eLayoutOrientation orientation = VERTICAL;
-
- if (orientation_string == "horizontal")
- {
- orientation = HORIZONTAL;
- }
- else if (orientation_string == "vertical")
- {
- orientation = VERTICAL;
- }
- else
- {
- llwarns << "Unknown orientation " << orientation_string << ", using vertical" << llendl;
- }
-
- LLLayoutStack* layout_stackp = new LLLayoutStack(orientation);
-
- node->getAttributeS32("border_size", layout_stackp->mPanelSpacing);
- // don't allow negative spacing values
- layout_stackp->mPanelSpacing = llmax(layout_stackp->mPanelSpacing, 0);
-
- std::string name("stack");
- node->getAttributeString("name", name);
-
- layout_stackp->setName(name);
- layout_stackp->initFromXML(node, parent);
-
- LLXMLNodePtr child;
- for (child = node->getFirstChild(); child.notNull(); child = child->getNextSibling())
- {
- S32 min_width = 0;
- S32 min_height = 0;
- BOOL auto_resize = TRUE;
-
- child->getAttributeS32("min_width", min_width);
- child->getAttributeS32("min_height", min_height);
- child->getAttributeBOOL("auto_resize", auto_resize);
-
- if (child->hasName("layout_panel"))
- {
- BOOL user_resize = TRUE;
- child->getAttributeBOOL("user_resize", user_resize);
- LLPanel* panelp = (LLPanel*)LLPanel::fromXML(child, layout_stackp, factory);
- if (panelp)
- {
- panelp->setFollowsNone();
- layout_stackp->addPanel(panelp, min_width, min_height, auto_resize, user_resize);
- }
- }
- else
- {
- BOOL user_resize = FALSE;
- child->getAttributeBOOL("user_resize", user_resize);
-
- LLPanel* panelp = new LLPanel(std::string("auto_panel"));
- LLView* new_child = factory->createWidget(panelp, child);
- if (new_child)
- {
- // put child in new embedded panel
- layout_stackp->addPanel(panelp, min_width, min_height, auto_resize, user_resize);
- // resize panel to contain widget and move widget to be contained in panel
- panelp->setRect(new_child->getRect());
- new_child->setOrigin(0, 0);
- }
- else
- {
- panelp->die();
- }
- }
- }
- layout_stackp->updateLayout();
-
- return layout_stackp;
-}
-
-S32 LLLayoutStack::getDefaultHeight(S32 cur_height)
-{
- // if we are spanning our children (crude upward propagation of size)
- // then don't enforce our size on our children
- if (mOrientation == HORIZONTAL)
- {
- cur_height = llmax(mMinHeight, getRect().getHeight());
- }
-
- return cur_height;
-}
-
-S32 LLLayoutStack::getDefaultWidth(S32 cur_width)
-{
- // if we are spanning our children (crude upward propagation of size)
- // then don't enforce our size on our children
- if (mOrientation == VERTICAL)
- {
- cur_width = llmax(mMinWidth, getRect().getWidth());
- }
-
- return cur_width;
-}
-
-void LLLayoutStack::addPanel(LLPanel* panel, S32 min_width, S32 min_height, BOOL auto_resize, BOOL user_resize, EAnimate animate, S32 index)
-{
- // panel starts off invisible (collapsed)
- if (animate == ANIMATE)
- {
- panel->setVisible(FALSE);
- }
- LLEmbeddedPanel* embedded_panel = new LLEmbeddedPanel(panel, mOrientation, min_width, min_height, auto_resize, user_resize);
-
- mPanels.insert(mPanels.begin() + llclamp(index, 0, (S32)mPanels.size()), embedded_panel);
-
- addChild(panel);
- addChild(embedded_panel->mResizeBar);
-
- // bring all resize bars to the front so that they are clickable even over the panels
- // with a bit of overlap
- for (e_panel_list_t::iterator panel_it = mPanels.begin(); panel_it != mPanels.end(); ++panel_it)
- {
- LLResizeBar* resize_barp = (*panel_it)->mResizeBar;
- sendChildToFront(resize_barp);
- }
-
- // start expanding panel animation
- if (animate == ANIMATE)
- {
- panel->setVisible(TRUE);
- }
-}
-
-void LLLayoutStack::removePanel(LLPanel* panel)
-{
- removeChild(panel);
-}
-
-void LLLayoutStack::collapsePanel(LLPanel* panel, BOOL collapsed)
-{
- LLEmbeddedPanel* panel_container = findEmbeddedPanel(panel);
- if (!panel_container) return;
-
- panel_container->mCollapsed = collapsed;
-}
-
-void LLLayoutStack::updateLayout(BOOL force_resize)
-{
- calcMinExtents();
-
- // calculate current extents
- S32 total_width = 0;
- S32 total_height = 0;
-
- const F32 ANIM_OPEN_TIME = 0.02f;
- const F32 ANIM_CLOSE_TIME = 0.03f;
-
- e_panel_list_t::iterator panel_it;
- for (panel_it = mPanels.begin(); panel_it != mPanels.end(); ++panel_it)
- {
- LLPanel* panelp = (*panel_it)->mPanel;
- if (panelp->getVisible())
- {
- (*panel_it)->mVisibleAmt = lerp((*panel_it)->mVisibleAmt, 1.f, LLCriticalDamp::getInterpolant(ANIM_OPEN_TIME));
- if ((*panel_it)->mVisibleAmt > 0.99f)
- {
- (*panel_it)->mVisibleAmt = 1.f;
- }
- }
- else // not visible
- {
- (*panel_it)->mVisibleAmt = lerp((*panel_it)->mVisibleAmt, 0.f, LLCriticalDamp::getInterpolant(ANIM_CLOSE_TIME));
- if ((*panel_it)->mVisibleAmt < 0.001f)
- {
- (*panel_it)->mVisibleAmt = 0.f;
- }
- }
-
- if ((*panel_it)->mCollapsed)
- {
- (*panel_it)->mCollapseAmt = lerp((*panel_it)->mCollapseAmt, 1.f, LLCriticalDamp::getInterpolant(ANIM_CLOSE_TIME));
- }
- else
- {
- (*panel_it)->mCollapseAmt = lerp((*panel_it)->mCollapseAmt, 0.f, LLCriticalDamp::getInterpolant(ANIM_CLOSE_TIME));
- }
-
- if (mOrientation == HORIZONTAL)
- {
- // enforce minimize size constraint by default
- if (panelp->getRect().getWidth() < (*panel_it)->mMinWidth)
- {
- panelp->reshape((*panel_it)->mMinWidth, panelp->getRect().getHeight());
- }
- total_width += llround(panelp->getRect().getWidth() * (*panel_it)->getCollapseFactor());
- // want n-1 panel gaps for n panels
- if (panel_it != mPanels.begin())
- {
- total_width += mPanelSpacing;
- }
- }
- else //VERTICAL
- {
- // enforce minimize size constraint by default
- if (panelp->getRect().getHeight() < (*panel_it)->mMinHeight)
- {
- panelp->reshape(panelp->getRect().getWidth(), (*panel_it)->mMinHeight);
- }
- total_height += llround(panelp->getRect().getHeight() * (*panel_it)->getCollapseFactor());
- if (panel_it != mPanels.begin())
- {
- total_height += mPanelSpacing;
- }
- }
- }
-
- S32 num_resizable_panels = 0;
- S32 shrink_headroom_available = 0;
- S32 shrink_headroom_total = 0;
- for (panel_it = mPanels.begin(); panel_it != mPanels.end(); ++panel_it)
- {
- // panels that are not fully visible do not count towards shrink headroom
- if ((*panel_it)->getCollapseFactor() < 1.f)
- {
- continue;
- }
-
- // if currently resizing a panel or the panel is flagged as not automatically resizing
- // only track total available headroom, but don't use it for automatic resize logic
- if ((*panel_it)->mResizeBar->hasMouseCapture()
- || (!(*panel_it)->mAutoResize
- && !force_resize))
- {
- if (mOrientation == HORIZONTAL)
- {
- shrink_headroom_total += (*panel_it)->mPanel->getRect().getWidth() - (*panel_it)->mMinWidth;
- }
- else //VERTICAL
- {
- shrink_headroom_total += (*panel_it)->mPanel->getRect().getHeight() - (*panel_it)->mMinHeight;
- }
- }
- else
- {
- num_resizable_panels++;
- if (mOrientation == HORIZONTAL)
- {
- shrink_headroom_available += (*panel_it)->mPanel->getRect().getWidth() - (*panel_it)->mMinWidth;
- shrink_headroom_total += (*panel_it)->mPanel->getRect().getWidth() - (*panel_it)->mMinWidth;
- }
- else //VERTICAL
- {
- shrink_headroom_available += (*panel_it)->mPanel->getRect().getHeight() - (*panel_it)->mMinHeight;
- shrink_headroom_total += (*panel_it)->mPanel->getRect().getHeight() - (*panel_it)->mMinHeight;
- }
- }
- }
-
- // calculate how many pixels need to be distributed among layout panels
- // positive means panels need to grow, negative means shrink
- S32 pixels_to_distribute;
- if (mOrientation == HORIZONTAL)
- {
- pixels_to_distribute = getRect().getWidth() - total_width;
- }
- else //VERTICAL
- {
- pixels_to_distribute = getRect().getHeight() - total_height;
- }
-
- // now we distribute the pixels...
- S32 cur_x = 0;
- S32 cur_y = getRect().getHeight();
-
- for (panel_it = mPanels.begin(); panel_it != mPanels.end(); ++panel_it)
- {
- LLPanel* panelp = (*panel_it)->mPanel;
-
- S32 cur_width = panelp->getRect().getWidth();
- S32 cur_height = panelp->getRect().getHeight();
- S32 new_width = llmax((*panel_it)->mMinWidth, cur_width);
- S32 new_height = llmax((*panel_it)->mMinHeight, cur_height);
-
- S32 delta_size = 0;
-
- // if panel can automatically resize (not animating, and resize flag set)...
- if ((*panel_it)->getCollapseFactor() == 1.f
- && (force_resize || (*panel_it)->mAutoResize)
- && !(*panel_it)->mResizeBar->hasMouseCapture())
- {
- if (mOrientation == HORIZONTAL)
- {
- // if we're shrinking
- if (pixels_to_distribute < 0)
- {
- // shrink proportionally to amount over minimum
- // so we can do this in one pass
- delta_size = (shrink_headroom_available > 0) ? llround((F32)pixels_to_distribute * ((F32)(cur_width - (*panel_it)->mMinWidth) / (F32)shrink_headroom_available)) : 0;
- shrink_headroom_available -= (cur_width - (*panel_it)->mMinWidth);
- }
- else
- {
- // grow all elements equally
- delta_size = llround((F32)pixels_to_distribute / (F32)num_resizable_panels);
- num_resizable_panels--;
- }
- pixels_to_distribute -= delta_size;
- new_width = llmax((*panel_it)->mMinWidth, cur_width + delta_size);
- }
- else
- {
- new_width = getDefaultWidth(new_width);
- }
-
- if (mOrientation == VERTICAL)
- {
- if (pixels_to_distribute < 0)
- {
- // shrink proportionally to amount over minimum
- // so we can do this in one pass
- delta_size = (shrink_headroom_available > 0) ? llround((F32)pixels_to_distribute * ((F32)(cur_height - (*panel_it)->mMinHeight) / (F32)shrink_headroom_available)) : 0;
- shrink_headroom_available -= (cur_height - (*panel_it)->mMinHeight);
- }
- else
- {
- delta_size = llround((F32)pixels_to_distribute / (F32)num_resizable_panels);
- num_resizable_panels--;
- }
- pixels_to_distribute -= delta_size;
- new_height = llmax((*panel_it)->mMinHeight, cur_height + delta_size);
- }
- else
- {
- new_height = getDefaultHeight(new_height);
- }
- }
- else
- {
- if (mOrientation == HORIZONTAL)
- {
- new_height = getDefaultHeight(new_height);
- }
- else // VERTICAL
- {
- new_width = getDefaultWidth(new_width);
- }
- }
-
- // adjust running headroom count based on new sizes
- shrink_headroom_total += delta_size;
-
- panelp->reshape(new_width, new_height);
- panelp->setOrigin(cur_x, cur_y - new_height);
-
- LLRect panel_rect = panelp->getRect();
- LLRect resize_bar_rect = panel_rect;
- if (mOrientation == HORIZONTAL)
- {
- resize_bar_rect.mLeft = panel_rect.mRight - RESIZE_BAR_OVERLAP;
- resize_bar_rect.mRight = panel_rect.mRight + mPanelSpacing + RESIZE_BAR_OVERLAP;
- }
- else
- {
- resize_bar_rect.mTop = panel_rect.mBottom + RESIZE_BAR_OVERLAP;
- resize_bar_rect.mBottom = panel_rect.mBottom - mPanelSpacing - RESIZE_BAR_OVERLAP;
- }
- (*panel_it)->mResizeBar->setRect(resize_bar_rect);
-
- if (mOrientation == HORIZONTAL)
- {
- cur_x += llround(new_width * (*panel_it)->getCollapseFactor()) + mPanelSpacing;
- }
- else //VERTICAL
- {
- cur_y -= llround(new_height * (*panel_it)->getCollapseFactor()) + mPanelSpacing;
- }
- }
-
- // update resize bars with new limits
- LLResizeBar* last_resize_bar = NULL;
- for (panel_it = mPanels.begin(); panel_it != mPanels.end(); ++panel_it)
- {
- LLPanel* panelp = (*panel_it)->mPanel;
-
- if (mOrientation == HORIZONTAL)
- {
- (*panel_it)->mResizeBar->setResizeLimits(
- (*panel_it)->mMinWidth,
- (*panel_it)->mMinWidth + shrink_headroom_total);
- }
- else //VERTICAL
- {
- (*panel_it)->mResizeBar->setResizeLimits(
- (*panel_it)->mMinHeight,
- (*panel_it)->mMinHeight + shrink_headroom_total);
- }
-
- // toggle resize bars based on panel visibility, resizability, etc
- BOOL resize_bar_enabled = panelp->getVisible() && (*panel_it)->mUserResize;
- (*panel_it)->mResizeBar->setVisible(resize_bar_enabled);
-
- if (resize_bar_enabled)
- {
- last_resize_bar = (*panel_it)->mResizeBar;
- }
- }
-
- // hide last resize bar as there is nothing past it
- // resize bars need to be in between two resizable panels
- if (last_resize_bar)
- {
- last_resize_bar->setVisible(FALSE);
- }
-
- // not enough room to fit existing contents
- if (force_resize == FALSE
- // layout did not complete by reaching target position
- && ((mOrientation == VERTICAL && cur_y != -mPanelSpacing)
- || (mOrientation == HORIZONTAL && cur_x != getRect().getWidth() + mPanelSpacing)))
- {
- // do another layout pass with all stacked elements contributing
- // even those that don't usually resize
- llassert_always(force_resize == FALSE);
- updateLayout(TRUE);
- }
-} // end LLLayoutStack::updateLayout
-
-
-LLLayoutStack::LLEmbeddedPanel* LLLayoutStack::findEmbeddedPanel(LLPanel* panelp) const
-{
- e_panel_list_t::const_iterator panel_it;
- for (panel_it = mPanels.begin(); panel_it != mPanels.end(); ++panel_it)
- {
- if ((*panel_it)->mPanel == panelp)
- {
- return *panel_it;
- }
- }
- return NULL;
-}
-
-void LLLayoutStack::calcMinExtents()
-{
- mMinWidth = 0;
- mMinHeight = 0;
-
- e_panel_list_t::iterator panel_it;
- for (panel_it = mPanels.begin(); panel_it != mPanels.end(); ++panel_it)
- {
- if (mOrientation == HORIZONTAL)
- {
- mMinHeight = llmax( mMinHeight,
- (*panel_it)->mMinHeight);
- mMinWidth += (*panel_it)->mMinWidth;
- if (panel_it != mPanels.begin())
- {
- mMinWidth += mPanelSpacing;
- }
- }
- else //VERTICAL
- {
- mMinWidth = llmax( mMinWidth,
- (*panel_it)->mMinWidth);
- mMinHeight += (*panel_it)->mMinHeight;
- if (panel_it != mPanels.begin())
- {
- mMinHeight += mPanelSpacing;
- }
- }
- }
-}
diff --git a/indra/llui/llpanel.h b/indra/llui/llpanel.h
index a7c9579030..3f1d1fdc5d 100644
--- a/indra/llui/llpanel.h
+++ b/indra/llui/llpanel.h
@@ -37,12 +37,9 @@
#include "llcallbackmap.h"
#include "lluictrl.h"
-#include "llbutton.h"
-#include "lllineeditor.h"
#include "llviewborder.h"
#include "lluistring.h"
#include "v4color.h"
-#include "llevents.h"
#include <list>
#include <queue>
@@ -50,6 +47,7 @@ const S32 LLPANEL_BORDER_WIDTH = 1;
const BOOL BORDER_YES = TRUE;
const BOOL BORDER_NO = FALSE;
+class LLButton;
/*
* General purpose concrete view base class.
@@ -57,62 +55,79 @@ const BOOL BORDER_NO = FALSE;
* With or without border,
* Can contain LLUICtrls.
*/
-class LLPanel : public LLUICtrl, public LLEventTrackable
+class LLPanel : public LLUICtrl
{
public:
+ struct LocalizedString : public LLInitParam::Block<LocalizedString>
+ {
+ Mandatory<std::string> name;
+ Mandatory<std::string> value;
+
+ LocalizedString();
+ };
+
+ struct Params
+ : public LLInitParam::Block<Params, LLUICtrl::Params>
+ {
+ Optional<bool> has_border;
+ Optional<LLViewBorder::Params> border;
+
+ Optional<LLUIColor> bg_opaque_color,
+ bg_alpha_color;
+
+ Optional<bool> background_visible,
+ background_opaque;
+
+ Optional<S32> min_width,
+ min_height;
+
+ Optional<std::string> filename;
+ Optional<std::string> class_name;
+
+ Multiple<LocalizedString> strings;
+
+ Optional<CommitCallbackParam> visible_callback;
+
+ Params();
+ };
- // minimal constructor for data-driven initialization
- LLPanel();
- LLPanel(const std::string& name);
+ // valid children for LLPanel are stored in this registry
+ typedef LLDefaultChildRegistry child_registry_t;
- // Position and size not saved
- LLPanel(const std::string& name, const LLRect& rect, BOOL bordered = TRUE);
+protected:
+ friend class LLUICtrlFactory;
+ // RN: for some reason you can't just use LLUICtrlFactory::getDefaultParams as a default argument in VC8
+ static const LLPanel::Params& getDefaultParams();
- // Position and size are saved to rect_control
- LLPanel(const std::string& name, const std::string& rect_control, BOOL bordered = TRUE);
+ // Panels can get constructed directly
+ LLPanel(const LLPanel::Params& params = getDefaultParams());
- /*virtual*/ ~LLPanel();
+public:
+// LLPanel(const std::string& name, const LLRect& rect = LLRect(), BOOL bordered = TRUE);
+ /*virtual*/ ~LLPanel() {}
// LLView interface
/*virtual*/ BOOL isPanel() const;
/*virtual*/ void draw();
/*virtual*/ BOOL handleKeyHere( KEY key, MASK mask );
- /*virtual*/ LLXMLNodePtr getXML(bool save_children = true) const;
- // Override to set not found list:
- virtual LLView* getChildView(const std::string& name, BOOL recurse = TRUE, BOOL create_if_missing = TRUE) const;
+ /*virtual*/ void handleVisibilityChange ( BOOL new_visibility );
// From LLFocusableElement
/*virtual*/ void setFocus( BOOL b );
+ virtual void setAlpha(F32 alpha);
+
// New virtuals
virtual void refresh(); // called in setFocus()
- virtual BOOL postBuild();
virtual void clearCtrls(); // overridden in LLPanelObject and LLPanelVolume
// Border controls
- void addBorder( LLViewBorder::EBevel border_bevel = LLViewBorder::BEVEL_OUT,
- LLViewBorder::EStyle border_style = LLViewBorder::STYLE_LINE,
- S32 border_thickness = LLPANEL_BORDER_WIDTH );
+ void addBorder( LLViewBorder::Params p);
+ void addBorder();
void removeBorder();
BOOL hasBorder() const { return mBorder != NULL; }
void setBorderVisible( BOOL b );
- template <class T> void requires(const std::string& name)
- {
- // check for widget with matching type and name
- if (LLView::getChild<T>(name) == NULL)
- {
- mRequirementsError += name + "\n";
- }
- }
-
- // requires LLView by default
- void requires(const std::string& name)
- {
- requires<LLView>(name);
- }
- BOOL checkRequirements();
-
void setBackgroundColor( const LLColor4& color ) { mBgColorOpaque = color; }
const LLColor4& getBackgroundColor() const { return mBgColorOpaque; }
void setTransparentColor(const LLColor4& color) { mBgColorAlpha = color; }
@@ -127,22 +142,20 @@ public:
void setLabel(const LLStringExplicit& label) { mLabel = label; }
std::string getLabel() const { return mLabel; }
- void setRectControl(const std::string& rect_control) { mRectControl.assign(rect_control); }
- const std::string& getRectControl() const { return mRectControl; }
- void storeRectControl();
-
void setCtrlsEnabled(BOOL b);
- LLHandle<LLPanel> getHandle() const { return mPanelHandle; }
- S32 getLastTabGroup() const { return mLastTabGroup; }
+ LLHandle<LLPanel> getHandle() const { return mPanelHandle; }
const LLCallbackMap::map_t& getFactoryMap() const { return mFactoryMap; }
-
- BOOL initPanelXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFactory *factory);
- void initChildrenXML(LLXMLNodePtr node, LLUICtrlFactory* factory);
- void setPanelParameters(LLXMLNodePtr node, LLView *parentp);
-
+
+ CommitCallbackRegistry::ScopedRegistrar& getCommitCallbackRegistrar() { return mCommitCallbackRegistrar; }
+ EnableCallbackRegistry::ScopedRegistrar& getEnableCallbackRegistrar() { return mEnableCallbackRegistrar; }
+
+ void initFromParams(const Params& p);
+ BOOL initPanelXML(LLXMLNodePtr node, LLView *parent, LLXMLNodePtr output_node = NULL);
+
+ bool hasString(const std::string& name);
std::string getString(const std::string& name, const LLStringUtil::format_map_t& args) const;
std::string getString(const std::string& name) const;
@@ -167,14 +180,17 @@ public:
// LLUICtrl
void childSetFocus(const std::string& id, BOOL focus = TRUE);
BOOL childHasFocus(const std::string& id);
- void childSetFocusChangedCallback(const std::string& id, void (*cb)(LLFocusableElement*, void*), void* user_data = NULL);
- void childSetCommitCallback(const std::string& id, void (*cb)(LLUICtrl*, void*), void* userdata = NULL );
- void childSetDoubleClickCallback(const std::string& id, void (*cb)(void*), void* userdata = NULL );
- void childSetValidate(const std::string& id, BOOL (*cb)(LLUICtrl*, void*) );
- void childSetUserData(const std::string& id, void* userdata);
+ // *TODO: Deprecate; for backwards compatability only:
+ // Prefer getChild<LLUICtrl>("foo")->setCommitCallback(boost:bind(...)),
+ // which takes a generic slot. Or use mCommitCallbackRegistrar.add() with
+ // a named callback and reference it in XML.
+ void childSetCommitCallback(const std::string& id, boost::function<void (LLUICtrl*,void*)> cb, void* data);
+
+ void childSetValidate(const std::string& id, boost::function<bool (const LLSD& data)> cb );
void childSetColor(const std::string& id, const LLColor4& color);
+ void childSetAlpha(const std::string& id, F32 alpha);
LLCtrlSelectionInterface* childGetSelectionInterface(const std::string& id) const;
LLCtrlListInterface* childGetListInterface(const std::string& id) const;
@@ -190,124 +206,67 @@ public:
BOOL childSetLabelArg(const std::string& id, const std::string& key, const LLStringExplicit& text);
BOOL childSetToolTipArg(const std::string& id, const std::string& key, const LLStringExplicit& text);
- // LLSlider / LLMultiSlider / LLSpinCtrl
- void childSetMinValue(const std::string& id, LLSD min_value);
- void childSetMaxValue(const std::string& id, LLSD max_value);
-
// LLTabContainer
void childShowTab(const std::string& id, const std::string& tabname, bool visible = true);
LLPanel *childGetVisibleTab(const std::string& id) const;
- void childSetTabChangeCallback(const std::string& id, const std::string& tabname, void (*on_tab_clicked)(void*, bool), void *userdata, void (*on_precommit)(void*,bool) = NULL);
// LLTextBox
void childSetWrappedText(const std::string& id, const std::string& text, bool visible = true);
// LLTextBox/LLTextEditor/LLLineEditor
void childSetText(const std::string& id, const LLStringExplicit& text) { childSetValue(id, LLSD(text)); }
+
+ // *NOTE: Does not return text from <string> tags, use getString()
std::string childGetText(const std::string& id) const { return childGetValue(id).asString(); }
// LLLineEditor
- void childSetKeystrokeCallback(const std::string& id, void (*keystroke_callback)(LLLineEditor* caller, void* user_data), void *user_data);
void childSetPrevalidate(const std::string& id, BOOL (*func)(const LLWString &) );
// LLButton
- void childSetAction(const std::string& id, void(*function)(void*), void* value);
- void childSetActionTextbox(const std::string& id, void(*function)(void*), void* value = NULL);
+ void childSetAction(const std::string& id, boost::function<void(void*)> function, void* value = NULL);
+
+ // LLTextBox
+ void childSetActionTextbox(const std::string& id, boost::function<void(void*)> function, void* value = NULL);
+
void childSetControlName(const std::string& id, const std::string& control_name);
- // Error reporting
- void childNotFound(const std::string& id) const;
- void childDisplayNotFound();
+ static LLView* fromXML(LLXMLNodePtr node, LLView *parent, LLXMLNodePtr output_node = NULL);
+
+ //call onOpen to let panel know when it's about to be shown or activated
+ virtual void onOpen(const LLSD& key) {}
- static LLView* fromXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFactory *factory);
+ void setXMLFilename(std::string filename) { mXMLFilename = filename; };
protected:
// Override to set not found list
LLButton* getDefaultButton() { return mDefaultBtn; }
LLCallbackMap::map_t mFactoryMap;
-
+ CommitCallbackRegistry::ScopedRegistrar mCommitCallbackRegistrar;
+ EnableCallbackRegistry::ScopedRegistrar mEnableCallbackRegistrar;
+
+ commit_signal_t mVisibleSignal; // Called when visibility changes, passes new visibility as LLSD()
+
private:
- // common construction logic
- void init();
-
- // From LLView
- virtual void addCtrl( LLUICtrl* ctrl, S32 tab_group );
- virtual void addCtrlAtEnd( LLUICtrl* ctrl, S32 tab_group);
-
// Unified error reporting for the child* functions
typedef std::set<std::string> expected_members_list_t;
mutable expected_members_list_t mExpectedMembers;
mutable expected_members_list_t mNewExpectedMembers;
- std::string mRectControl;
LLColor4 mBgColorAlpha;
LLColor4 mBgColorOpaque;
- LLColor4 mDefaultBtnHighlight;
BOOL mBgVisible;
BOOL mBgOpaque;
LLViewBorder* mBorder;
LLButton* mDefaultBtn;
- std::string mLabel;
- S32 mLastTabGroup;
+ LLUIString mLabel;
LLRootHandle<LLPanel> mPanelHandle;
typedef std::map<std::string, std::string> ui_string_map_t;
ui_string_map_t mUIStrings;
- std::string mRequirementsError;
-
-}; // end class LLPanel
-
-
-class LLLayoutStack : public LLView
-{
-public:
- typedef enum e_layout_orientation
- {
- HORIZONTAL,
- VERTICAL
- } eLayoutOrientation;
-
- LLLayoutStack(eLayoutOrientation orientation);
- virtual ~LLLayoutStack();
-
- /*virtual*/ void draw();
- /*virtual*/ LLXMLNodePtr getXML(bool save_children = true) const;
- /*virtual*/ void removeCtrl(LLUICtrl* ctrl);
-
- static LLView* fromXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFactory *factory);
-
- S32 getMinWidth() const { return mMinWidth; }
- S32 getMinHeight() const { return mMinHeight; }
+ // for setting the xml filename when building panel in context dependent cases
+ std::string mXMLFilename;
- typedef enum e_animate
- {
- NO_ANIMATE,
- ANIMATE
- } EAnimate;
-
- void addPanel(LLPanel* panel, S32 min_width, S32 min_height, BOOL auto_resize, BOOL user_resize, EAnimate animate = NO_ANIMATE, S32 index = S32_MAX);
- void removePanel(LLPanel* panel);
- void collapsePanel(LLPanel* panel, BOOL collapsed = TRUE);
- S32 getNumPanels() { return mPanels.size(); }
-
-private:
- struct LLEmbeddedPanel;
-
- void updateLayout(BOOL force_resize = FALSE);
- void calcMinExtents();
- S32 getDefaultHeight(S32 cur_height);
- S32 getDefaultWidth(S32 cur_width);
-
- const eLayoutOrientation mOrientation;
-
- typedef std::vector<LLEmbeddedPanel*> e_panel_list_t;
- e_panel_list_t mPanels;
- LLEmbeddedPanel* findEmbeddedPanel(LLPanel* panelp) const;
-
- S32 mMinWidth;
- S32 mMinHeight;
- S32 mPanelSpacing;
-}; // end class LLLayoutStack
+}; // end class LLPanel
#endif
diff --git a/indra/llui/llprogressbar.cpp b/indra/llui/llprogressbar.cpp
index 8833494af8..c8b6e814e1 100644
--- a/indra/llui/llprogressbar.cpp
+++ b/indra/llui/llprogressbar.cpp
@@ -39,31 +39,30 @@
#include "llgl.h"
#include "llui.h"
#include "llfontgl.h"
-#include "llimagegl.h"
#include "lltimer.h"
#include "llglheaders.h"
#include "llfocusmgr.h"
+#include "lluictrlfactory.h"
-static LLRegisterWidget<LLProgressBar> r("progress_bar");
+static LLDefaultChildRegistry::Register<LLProgressBar> r("progress_bar");
-LLProgressBar::LLProgressBar(const std::string& name, const LLRect &rect)
- : LLView(name, rect, FALSE),
- mImageBar( NULL ),
- mImageShadow( NULL )
-{
- mPercentDone = 0.f;
-
- // Defaults:
+LLProgressBar::Params::Params()
+: image_bar("image_bar"),
+ image_fill("image_fill"),
+ color_bar("color_bar"),
+ color_bg("color_bg")
+{}
- setImageBar("rounded_square.tga");
- setImageShadow("rounded_square_soft.tga");
- mColorBackground = LLColor4(0.3254f, 0.4000f, 0.5058f, 1.0f);
- mColorBar = LLColor4(0.5764f, 0.6627f, 0.8352f, 1.0f);
- mColorBar2 = LLColor4(0.5764f, 0.6627f, 0.8352f, 1.0f);
- mColorShadow = LLColor4(0.2000f, 0.2000f, 0.4000f, 1.0f);
-}
+LLProgressBar::LLProgressBar(const LLProgressBar::Params& p)
+: LLView(p),
+ mImageBar(p.image_bar),
+ mImageFill(p.image_fill),
+ mColorBackground(p.color_bg()),
+ mColorBar(p.color_bar()),
+ mPercentDone(0.f)
+{}
LLProgressBar::~LLProgressBar()
{
@@ -74,108 +73,19 @@ void LLProgressBar::draw()
{
static LLTimer timer;
- LLUIImagePtr shadow_imagep = LLUI::getUIImage("rounded_square_soft.tga");
LLUIImagePtr bar_fg_imagep = LLUI::getUIImage("progressbar_fill.tga");
- LLUIImagePtr bar_bg_imagep = LLUI::getUIImage("progressbar_track.tga");
- LLUIImagePtr bar_imagep = LLUI::getUIImage("rounded_square.tga");
- LLColor4 background_color = LLUI::sColorsGroup->getColor("LoginProgressBarBgColor");
- bar_bg_imagep->draw(getLocalRect(),
- background_color);
+ mImageBar->draw(getLocalRect(), mColorBackground.get());
F32 alpha = 0.5f + 0.5f*0.5f*(1.f + (F32)sin(3.f*timer.getElapsedTimeF32()));
- LLColor4 bar_color = LLUI::sColorsGroup->getColor("LoginProgressBarFgColor");
- bar_color.mV[3] = alpha;
+ LLColor4 bar_color = mColorBar.get();
+ bar_color.mV[VALPHA] *= alpha; // modulate alpha
LLRect progress_rect = getLocalRect();
progress_rect.mRight = llround(getRect().getWidth() * (mPercentDone / 100.f));
- bar_fg_imagep->draw(progress_rect);
+ mImageFill->draw(progress_rect, bar_color);
}
void LLProgressBar::setPercent(const F32 percent)
{
mPercentDone = llclamp(percent, 0.f, 100.f);
}
-
-void LLProgressBar::setImageBar( const std::string &bar_name )
-{
- mImageBar = LLUI::sImageProvider->getUIImage(bar_name)->getImage();
-}
-
-void LLProgressBar::setImageShadow(const std::string &shadow_name)
-{
- mImageShadow = LLUI::sImageProvider->getUIImage(shadow_name)->getImage();
-}
-
-void LLProgressBar::setColorBar(const LLColor4 &c)
-{
- mColorBar = c;
-}
-void LLProgressBar::setColorBar2(const LLColor4 &c)
-{
- mColorBar2 = c;
-}
-void LLProgressBar::setColorShadow(const LLColor4 &c)
-{
- mColorShadow = c;
-}
-void LLProgressBar::setColorBackground(const LLColor4 &c)
-{
- mColorBackground = c;
-}
-
-
-// static
-LLView* LLProgressBar::fromXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFactory *factory)
-{
- std::string name("progress_bar");
- node->getAttributeString("name", name);
-
- LLProgressBar *progress = new LLProgressBar(name, LLRect());
-
-
- std::string image_bar;
- if (node->hasAttribute("image_bar")) node->getAttributeString("image_bar",image_bar);
- if (image_bar != LLStringUtil::null) progress->setImageBar(image_bar);
-
-
- std::string image_shadow;
- if (node->hasAttribute("image_shadow")) node->getAttributeString("image_shadow",image_shadow);
- if (image_shadow != LLStringUtil::null) progress->setImageShadow(image_shadow);
-
-
- LLColor4 color_bar;
- if (node->hasAttribute("color_bar"))
- {
- node->getAttributeColor4("color_bar",color_bar);
- progress->setColorBar(color_bar);
- }
-
-
- LLColor4 color_bar2;
- if (node->hasAttribute("color_bar2"))
- {
- node->getAttributeColor4("color_bar2",color_bar2);
- progress->setColorBar2(color_bar2);
- }
-
-
- LLColor4 color_shadow;
- if (node->hasAttribute("color_shadow"))
- {
- node->getAttributeColor4("color_shadow",color_shadow);
- progress->setColorShadow(color_shadow);
- }
-
-
- LLColor4 color_bg;
- if (node->hasAttribute("color_bg"))
- {
- node->getAttributeColor4("color_bg",color_bg);
- progress->setColorBackground(color_bg);
- }
-
-
- progress->initFromXML(node, parent);
-
- return progress;
-}
diff --git a/indra/llui/llprogressbar.h b/indra/llui/llprogressbar.h
index 00ad61d540..b6a5b0400d 100644
--- a/indra/llui/llprogressbar.h
+++ b/indra/llui/llprogressbar.h
@@ -40,37 +40,32 @@ class LLProgressBar
: public LLView
{
public:
- LLProgressBar(const std::string& name, const LLRect &rect);
- virtual ~LLProgressBar();
-
- void setPercent(const F32 percent);
+ struct Params : public LLInitParam::Block<Params, LLView::Params>
+ {
+ Optional<LLUIImage*> image_bar,
+ image_fill;
- void setImageBar(const std::string &bar_name);
- void setImageShadow(const std::string &shadow_name);
+ Optional<LLUIColor> color_bar,
+ color_bg;
- void setColorBar(const LLColor4 &c);
- void setColorBar2(const LLColor4 &c);
- void setColorShadow(const LLColor4 &c);
- void setColorBackground(const LLColor4 &c);
+ Params();
+ };
+ LLProgressBar(const Params&);
+ virtual ~LLProgressBar();
- static LLView* fromXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFactory *factory);
+ void setPercent(const F32 percent);
/*virtual*/ void draw();
-protected:
+private:
F32 mPercentDone;
- LLPointer<LLImageGL> mImageBar;
- //LLUUID mImageBarID;
- //LLString mImageBarName;
- LLColor4 mColorBar;
- LLColor4 mColorBar2;
+ LLPointer<LLUIImage> mImageBar;
+ LLUIColor mColorBar;
- LLPointer<LLImageGL> mImageShadow;
- //LLUUID mImageShadowID;
- //LLString mImageShadowName;
- LLColor4 mColorShadow;
- LLColor4 mColorBackground;
+ LLUIColor mColorBackground;
+
+ LLPointer<LLUIImage> mImageFill;
};
#endif // LL_LLPROGRESSBAR_H
diff --git a/indra/llui/llradiogroup.cpp b/indra/llui/llradiogroup.cpp
index 33b93985d7..c66b9bde2b 100644
--- a/indra/llui/llradiogroup.cpp
+++ b/indra/llui/llradiogroup.cpp
@@ -42,63 +42,52 @@
#include "llcontrol.h"
#include "llui.h"
#include "llfocusmgr.h"
+#include "lluictrlfactory.h"
+
+static LLDefaultChildRegistry::Register<LLRadioGroup> r1("radio_group");
+
+
+static RadioGroupRegistry::Register<LLRadioCtrl> register_radio_ctrl("radio_item");
-static LLRegisterWidget<LLRadioGroup> r("radio_group");
-LLRadioGroup::LLRadioGroup(const std::string& name, const LLRect& rect,
- const std::string& control_name,
- LLUICtrlCallback callback,
- void* userdata,
- BOOL border)
-: LLUICtrl(name, rect, TRUE, callback, userdata, FOLLOWS_LEFT | FOLLOWS_TOP),
- mSelectedIndex(0)
-{
- setControlName(control_name, NULL);
- init(border);
-}
-LLRadioGroup::LLRadioGroup(const std::string& name, const LLRect& rect,
- S32 initial_index,
- LLUICtrlCallback callback,
- void* userdata,
- BOOL border) :
- LLUICtrl(name, rect, TRUE, callback, userdata, FOLLOWS_LEFT | FOLLOWS_TOP),
- mSelectedIndex(initial_index)
+LLRadioGroup::Params::Params()
+: has_border("draw_border")
{
- init(border);
+ name = "radio_group";
+ mouse_opaque = true;
+ follows.flags = FOLLOWS_LEFT | FOLLOWS_TOP;
}
-void LLRadioGroup::init(BOOL border)
-{
- if (border)
+LLRadioGroup::LLRadioGroup(const LLRadioGroup::Params& p)
+: LLUICtrl(p),
+ mFont(p.font.isProvided() ? p.font() : LLFontGL::getFontSansSerifSmall()),
+ mSelectedIndex(-1),
+ mHasBorder(p.has_border)
+{
+ if (mHasBorder)
{
- addChild( new LLViewBorder( std::string("radio group border"),
- LLRect(0, getRect().getHeight(), getRect().getWidth(), 0),
- LLViewBorder::BEVEL_NONE,
- LLViewBorder::STYLE_LINE,
- 1 ) );
+ LLViewBorder::Params params;
+ params.name("radio group border");
+ params.rect(LLRect(0, getRect().getHeight(), getRect().getWidth(), 0));
+ params.bevel_style(LLViewBorder::BEVEL_NONE);
+ LLViewBorder * vb = LLUICtrlFactory::create<LLViewBorder> (params);
+ addChild (vb);
}
- mHasBorder = border;
}
-
-
-
LLRadioGroup::~LLRadioGroup()
{
}
-
// virtual
-void LLRadioGroup::setEnabled(BOOL enabled)
+BOOL LLRadioGroup::postBuild()
{
- for (child_list_const_iter_t child_iter = getChildList()->begin();
- child_iter != getChildList()->end(); ++child_iter)
+ if (mControlVariable)
{
- LLView *child = *child_iter;
- child->setEnabled(enabled);
+ setSelectedIndex(mControlVariable->getValue().asInteger());
}
- LLView::setEnabled(enabled);
+ return TRUE;
}
void LLRadioGroup::setIndexEnabled(S32 index, BOOL enabled)
@@ -250,48 +239,52 @@ void LLRadioGroup::draw()
LLView::draw();
}
-
-// When adding a button, we need to ensure that the radio
+// When adding a child button, we need to ensure that the radio
// group gets a message when the button is clicked.
-LLRadioCtrl* LLRadioGroup::addRadioButton(const std::string& name, const std::string& label, const LLRect& rect, const LLFontGL* font )
+
+/*virtual*/
+bool LLRadioGroup::addChild(LLView* view, S32 tab_group)
{
- // Highlight will get fixed in draw method above
- LLRadioCtrl* radio = new LLRadioCtrl(name, rect, label, font,
- onClickButton, this);
- addChild(radio);
- mRadioButtons.push_back(radio);
- return radio;
+ bool res = LLView::addChild(view, tab_group);
+ if (res)
+ {
+ LLRadioCtrl* radio_ctrl = dynamic_cast<LLRadioCtrl*>(view);
+ if (radio_ctrl)
+ {
+ radio_ctrl->setFont(mFont);
+ radio_ctrl->setCommitCallback(boost::bind(&LLRadioGroup::onClickButton, this, _1));
+ mRadioButtons.push_back(radio_ctrl);
+ }
+ }
+ return res;
}
// Handle one button being clicked. All child buttons must have this
// function as their callback function.
-// static
-void LLRadioGroup::onClickButton(LLUICtrl* ui_ctrl, void* userdata)
+void LLRadioGroup::onClickButton(LLUICtrl* ctrl)
{
// llinfos << "LLRadioGroup::onClickButton" << llendl;
-
- LLRadioCtrl* clickedRadio = (LLRadioCtrl*) ui_ctrl;
- LLRadioGroup* self = (LLRadioGroup*) userdata;
-
- S32 counter = 0;
- for (button_list_t::iterator iter = self->mRadioButtons.begin();
- iter != self->mRadioButtons.end(); ++iter)
+ LLRadioCtrl* clicked_radio = dynamic_cast<LLRadioCtrl*>(ctrl);
+ if (!clicked_radio)
+ return;
+ S32 index = 0;
+ for (button_list_t::iterator iter = mRadioButtons.begin();
+ iter != mRadioButtons.end(); ++iter)
{
LLRadioCtrl* radio = *iter;
- if (radio == clickedRadio)
+ if (radio == clicked_radio)
{
- // llinfos << "clicked button " << counter << llendl;
- self->setSelectedIndex(counter);
- self->setControlValue(counter);
+ // llinfos << "clicked button " << index << llendl;
+ setSelectedIndex(index);
// BUG: Calls click callback even if button didn't actually change
- self->onCommit();
+ onCommit();
return;
}
- counter++;
+ index++;
}
llwarns << "LLRadioGroup::onClickButton - clicked button that isn't a child" << llendl;
@@ -340,107 +333,6 @@ LLSD LLRadioGroup::getValue() const
return LLSD();
}
-// virtual
-LLXMLNodePtr LLRadioGroup::getXML(bool save_children) const
-{
- LLXMLNodePtr node = LLUICtrl::getXML();
-
- // Attributes
-
- node->createChild("draw_border", TRUE)->setBoolValue(mHasBorder);
-
- // Contents
-
- for (button_list_t::const_iterator iter = mRadioButtons.begin();
- iter != mRadioButtons.end(); ++iter)
- {
- LLRadioCtrl* radio = *iter;
-
- LLXMLNodePtr child_node = radio->LLView::getXML();
- child_node->setStringValue(radio->getLabel());
- child_node->setName(std::string("radio_item"));
-
- node->addChild(child_node);
- }
-
- return node;
-}
-
-// static
-LLView* LLRadioGroup::fromXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFactory *factory)
-{
- std::string name("radio_group");
- node->getAttributeString("name", name);
-
- U32 initial_value = 0;
- node->getAttributeU32("initial_value", initial_value);
-
- BOOL draw_border = TRUE;
- node->getAttributeBOOL("draw_border", draw_border);
-
- LLRect rect;
- createRect(node, rect, parent, LLRect());
-
- LLRadioGroup* radio_group = new LLRadioGroup(name,
- rect,
- initial_value,
- NULL,
- NULL,
- draw_border);
-
- const std::string& contents = node->getValue();
-
- LLRect group_rect = radio_group->getRect();
-
- LLFontGL *font = LLView::selectFont(node);
-
- if (contents.find_first_not_of(" \n\t") != contents.npos)
- {
- // ...old school default vertical layout
- typedef boost::tokenizer<boost::char_separator<char> > tokenizer;
- boost::char_separator<char> sep("\t\n");
- tokenizer tokens(contents, sep);
- tokenizer::iterator token_iter = tokens.begin();
-
- const S32 HPAD = 4, VPAD = 4;
- S32 cur_y = group_rect.getHeight() - VPAD;
-
- while(token_iter != tokens.end())
- {
- const std::string& line = *token_iter;
- LLRect rect(HPAD, cur_y, group_rect.getWidth() - (2 * HPAD), cur_y - 15);
- cur_y -= VPAD + 15;
- radio_group->addRadioButton(std::string("radio"), line, rect, font);
- ++token_iter;
- }
- llwarns << "Legacy radio group format used! Please convert to use <radio_item> tags!" << llendl;
- }
- else
- {
- // ...per pixel layout
- LLXMLNodePtr child;
- for (child = node->getFirstChild(); child.notNull(); child = child->getNextSibling())
- {
- if (child->hasName("radio_item"))
- {
- LLRect item_rect;
- createRect(child, item_rect, radio_group, rect);
-
- std::string radioname("radio");
- child->getAttributeString("name", radioname);
- std::string item_label = child->getTextContents();
- LLRadioCtrl* radio = radio_group->addRadioButton(radioname, item_label, item_rect, font);
-
- radio->initFromXML(child, radio_group);
- }
- }
- }
-
- radio_group->initFromXML(node, parent);
-
- return radio_group;
-}
-
// LLCtrlSelectionInterface functions
BOOL LLRadioGroup::setCurrentByID( const LLUUID& id )
{
@@ -504,6 +396,22 @@ BOOL LLRadioGroup::operateOnAll(EOperation op)
return FALSE;
}
+LLRadioCtrl::LLRadioCtrl(const LLRadioCtrl::Params& p)
+ : LLCheckBoxCtrl(p)
+{
+}
+
+BOOL LLRadioCtrl::postBuild()
+{
+ // Old-style radio_item used the text contents to indicate the label,
+ // but new-style radio_item uses label attribute.
+ std::string value = getValue().asString();
+ if (!value.empty())
+ {
+ setLabel(value);
+ }
+ return TRUE;
+}
LLRadioCtrl::~LLRadioCtrl()
{
@@ -515,3 +423,19 @@ void LLRadioCtrl::setValue(const LLSD& value)
mButton->setTabStop(value.asBoolean());
}
+// *TODO: Remove this function after the initial XUI XML re-export pass.
+// static
+void LLRadioCtrl::setupParamsForExport(Params& p, LLView* parent)
+{
+ std::string label = p.label;
+ if (label.empty())
+ {
+ // We don't have a label attribute, so move the text contents
+ // stored in "value" into the label
+ std::string initial_value = p.LLUICtrl::Params::initial_value();
+ p.label = initial_value;
+ p.LLUICtrl::Params::initial_value = LLSD();
+ }
+
+ LLCheckBoxCtrl::setupParamsForExport(p, parent);
+}
diff --git a/indra/llui/llradiogroup.h b/indra/llui/llradiogroup.h
index 3410b74104..b5516307fd 100644
--- a/indra/llui/llradiogroup.h
+++ b/indra/llui/llradiogroup.h
@@ -39,23 +39,41 @@
/*
- * A checkbox control with use_radio_style == true.
+ * An invisible view containing multiple mutually exclusive toggling
+ * buttons (usually radio buttons). Automatically handles the mutex
+ * condition by highlighting only one button at a time.
*/
class LLRadioCtrl : public LLCheckBoxCtrl
{
public:
- LLRadioCtrl(const std::string& name, const LLRect& rect, const std::string& label, const LLFontGL* font = NULL,
- void (*commit_callback)(LLUICtrl*, void*) = NULL, void* callback_userdata = NULL) :
- LLCheckBoxCtrl(name, rect, label, font, commit_callback, callback_userdata, FALSE, RADIO_STYLE)
+ struct Params : public LLInitParam::Block<Params, LLCheckBoxCtrl::Params>
{
- setTabStop(FALSE);
- }
- /*virtual*/ ~LLRadioCtrl();
+ Ignored length;
+ Ignored type;
+
+ Params()
+ : length("length"),
+ type("type")
+ {}
+ };
+ /*virtual*/ ~LLRadioCtrl();
/*virtual*/ void setValue(const LLSD& value);
+
+ /*virtual*/ BOOL postBuild();
+
+ // Ensure label is in an attribute, not the contents
+ static void setupParamsForExport(Params& p, LLView* parent);
+
+protected:
+ LLRadioCtrl(const Params& p);
+ friend class LLUICtrlFactory;
};
+struct RadioGroupRegistry : public LLChildRegistry<RadioGroupRegistry>
+{};
+
/*
* An invisible view containing multiple mutually exclusive toggling
* buttons (usually radio buttons). Automatically handles the mutex
@@ -65,32 +83,30 @@ class LLRadioGroup
: public LLUICtrl, public LLCtrlSelectionInterface
{
public:
- // Build a radio group. The number (0...n-1) of the currently selected
- // element will be stored in the named control. After the control is
- // changed the callback will be called.
- LLRadioGroup(const std::string& name, const LLRect& rect,
- const std::string& control_name,
- LLUICtrlCallback callback = NULL,
- void* userdata = NULL,
- BOOL border = TRUE);
-
- // Another radio group constructor, but this one doesn't rely on
- // needing a control
- LLRadioGroup(const std::string& name, const LLRect& rect,
- S32 initial_index,
- LLUICtrlCallback callback = NULL,
- void* userdata = NULL,
- BOOL border = TRUE);
- virtual ~LLRadioGroup();
+ struct Params : public LLInitParam::Block<Params, LLUICtrl::Params>
+ {
+ Optional<bool> has_border;
+ Params();
+ };
+
+ // my valid children are stored in this registry
+ typedef RadioGroupRegistry child_registry_t;
+
+protected:
+ LLRadioGroup(const Params&);
+ friend class LLUICtrlFactory;
+public:
+ virtual ~LLRadioGroup();
+
+ virtual BOOL postBuild();
+
+ virtual bool addChild(LLView* view, S32 tab_group = 0);
+
virtual BOOL handleKeyHere(KEY key, MASK mask);
- virtual void setEnabled(BOOL enabled);
- virtual LLXMLNodePtr getXML(bool save_children = true) const;
- static LLView* fromXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFactory *factory);
void setIndexEnabled(S32 index, BOOL enabled);
-
// return the index value of the selected item
S32 getSelectedIndex() const { return mSelectedIndex; }
@@ -104,13 +120,8 @@ public:
// Draw the group, but also fix the highlighting based on the control.
void draw();
- // You must use this method to add buttons to a radio group.
- // Don't use addChild -- it won't set the callback function
- // correctly.
- LLRadioCtrl* addRadioButton(const std::string& name, const std::string& label, const LLRect& rect, const LLFontGL* font);
- LLRadioCtrl* getRadioButton(const S32& index) { return mRadioButtons[index]; }
// Update the control as needed. Userdata must be a pointer to the button.
- static void onClickButton(LLUICtrl* radio, void* userdata);
+ void onClickButton(LLUICtrl* clicked_radio);
//========================================================================
LLCtrlSelectionInterface* getSelectionInterface() { return (LLCtrlSelectionInterface*)this; };
@@ -131,9 +142,7 @@ public:
/*virtual*/ BOOL operateOnAll(EOperation op);
private:
- // protected function shared by the two constructors.
- void init(BOOL border);
-
+ const LLFontGL* mFont;
S32 mSelectedIndex;
typedef std::vector<LLRadioCtrl*> button_list_t;
button_list_t mRadioButtons;
@@ -141,5 +150,4 @@ private:
BOOL mHasBorder;
};
-
#endif
diff --git a/indra/llui/llresizebar.cpp b/indra/llui/llresizebar.cpp
index 5b9fe72e99..304ac64f31 100644
--- a/indra/llui/llresizebar.cpp
+++ b/indra/llui/llresizebar.cpp
@@ -40,22 +40,22 @@
#include "llfocusmgr.h"
#include "llwindow.h"
-LLResizeBar::LLResizeBar( const std::string& name, LLView* resizing_view, const LLRect& rect, S32 min_size, S32 max_size, Side side )
- :
- LLView( name, rect, TRUE ),
+LLResizeBar::LLResizeBar(const LLResizeBar::Params& p)
+: LLView(p),
mDragLastScreenX( 0 ),
mDragLastScreenY( 0 ),
mLastMouseScreenX( 0 ),
mLastMouseScreenY( 0 ),
- mMinSize( min_size ),
- mMaxSize( max_size ),
- mSide( side ),
- mSnappingEnabled(TRUE),
- mAllowDoubleClickSnapping(TRUE),
- mResizingView(resizing_view)
+ mMinSize( p.min_size ),
+ mMaxSize( p.max_size ),
+ mSide( p.side ),
+ mSnappingEnabled(p.snapping_enabled),
+ mAllowDoubleClickSnapping(p.allow_double_click_snapping),
+ mResizingView(p.resizing_view)
{
+ setFollowsNone();
// set up some generically good follow code.
- switch( side )
+ switch( mSide )
{
case LEFT:
setFollowsLeft();
@@ -80,8 +80,6 @@ LLResizeBar::LLResizeBar( const std::string& name, LLView* resizing_view, const
default:
break;
}
- // this is just a decorator
- setSaveToXML(FALSE);
}
@@ -185,30 +183,31 @@ BOOL LLResizeBar::handleHover(S32 x, S32 y, MASK mask)
if (mSnappingEnabled)
{
+ static LLUICachedControl<S32> snap_margin ("SnapMargin", 0);
switch( mSide )
{
case LEFT:
- snap_view = mResizingView->findSnapEdge(scaled_rect.mLeft, mouse_dir, SNAP_LEFT, SNAP_PARENT_AND_SIBLINGS, LLUI::sConfigGroup->getS32("SnapMargin"));
+ snap_view = mResizingView->findSnapEdge(scaled_rect.mLeft, mouse_dir, SNAP_LEFT, SNAP_PARENT_AND_SIBLINGS, snap_margin);
break;
case TOP:
- snap_view = mResizingView->findSnapEdge(scaled_rect.mTop, mouse_dir, SNAP_TOP, SNAP_PARENT_AND_SIBLINGS, LLUI::sConfigGroup->getS32("SnapMargin"));
+ snap_view = mResizingView->findSnapEdge(scaled_rect.mTop, mouse_dir, SNAP_TOP, SNAP_PARENT_AND_SIBLINGS, snap_margin);
break;
case RIGHT:
- snap_view = mResizingView->findSnapEdge(scaled_rect.mRight, mouse_dir, SNAP_RIGHT, SNAP_PARENT_AND_SIBLINGS, LLUI::sConfigGroup->getS32("SnapMargin"));
+ snap_view = mResizingView->findSnapEdge(scaled_rect.mRight, mouse_dir, SNAP_RIGHT, SNAP_PARENT_AND_SIBLINGS, snap_margin);
break;
case BOTTOM:
- snap_view = mResizingView->findSnapEdge(scaled_rect.mBottom, mouse_dir, SNAP_BOTTOM, SNAP_PARENT_AND_SIBLINGS, LLUI::sConfigGroup->getS32("SnapMargin"));
+ snap_view = mResizingView->findSnapEdge(scaled_rect.mBottom, mouse_dir, SNAP_BOTTOM, SNAP_PARENT_AND_SIBLINGS, snap_margin);
break;
}
}
// register "snap" behavior with snapped view
- mResizingView->snappedTo(snap_view);
+ mResizingView->setSnappedTo(snap_view);
// restore original rectangle so the appropriate changes are detected
mResizingView->setRect(orig_rect);
// change view shape as user operation
- mResizingView->userSetShape(scaled_rect);
+ mResizingView->setShape(scaled_rect, true);
// update last valid mouse cursor position based on resized view's actual size
LLRect new_rect = mResizingView->getRect();
@@ -284,7 +283,7 @@ BOOL LLResizeBar::handleDoubleClick(S32 x, S32 y, MASK mask)
break;
}
- mResizingView->userSetShape(scaled_rect);
+ mResizingView->setShape(scaled_rect, true);
}
return TRUE;
diff --git a/indra/llui/llresizebar.h b/indra/llui/llresizebar.h
index b9fc40593d..a7bc3c60f5 100644
--- a/indra/llui/llresizebar.h
+++ b/indra/llui/llresizebar.h
@@ -41,7 +41,31 @@ class LLResizeBar : public LLView
public:
enum Side { LEFT, TOP, RIGHT, BOTTOM };
- LLResizeBar(const std::string& name, LLView* resizing_view, const LLRect& rect, S32 min_size, S32 max_size, Side side );
+ struct Params : public LLInitParam::Block<Params, LLView::Params>
+ {
+ Mandatory<LLView*> resizing_view;
+ Mandatory<Side> side;
+
+ Optional<S32> min_size;
+ Optional<S32> max_size;
+ Optional<bool> snapping_enabled;
+ Optional<bool> allow_double_click_snapping;
+
+ Params()
+ : max_size("max_size", S32_MAX),
+ snapping_enabled("snapping_enabled", true),
+ resizing_view("resizing_view"),
+ side("side"),
+ allow_double_click_snapping("allow_double_click_snapping", true)
+ {
+ name = "resize_bar";
+ }
+ };
+
+protected:
+ LLResizeBar(const LLResizeBar::Params& p);
+ friend class LLUICtrlFactory;
+public:
// virtual void draw(); No appearance
virtual BOOL handleHover(S32 x, S32 y, MASK mask);
diff --git a/indra/llui/llresizehandle.cpp b/indra/llui/llresizehandle.cpp
index c5d57d8d6c..7449c339a0 100644
--- a/indra/llui/llresizehandle.cpp
+++ b/indra/llui/llresizehandle.cpp
@@ -44,37 +44,39 @@
const S32 RESIZE_BORDER_WIDTH = 3;
-LLResizeHandle::LLResizeHandle( const std::string& name, const LLRect& rect, S32 min_width, S32 min_height, ECorner corner )
- :
- LLView( name, rect, TRUE ),
+LLResizeHandle::Params::Params()
+: corner("corner"),
+ min_width("min_width"),
+ min_height("min_height")
+{
+ name = "resize_handle";
+}
+
+LLResizeHandle::LLResizeHandle(const LLResizeHandle::Params& p)
+: LLView(p),
mDragLastScreenX( 0 ),
mDragLastScreenY( 0 ),
mLastMouseScreenX( 0 ),
mLastMouseScreenY( 0 ),
mImage( NULL ),
- mMinWidth( min_width ),
- mMinHeight( min_height ),
- mCorner( corner )
+ mMinWidth( p.min_width ),
+ mMinHeight( p.min_height ),
+ mCorner( p.corner )
{
- setSaveToXML(false);
-
if( RIGHT_BOTTOM == mCorner)
{
- mImage = LLUI::sImageProvider->getUIImage("UIImgResizeBottomRightUUID");
+ mImage = LLUI::getUIImage("Resize_Corner");
}
-
- switch( mCorner )
+ switch( p.corner )
{
- case LEFT_TOP: setFollows( FOLLOWS_LEFT | FOLLOWS_TOP ); break;
- case LEFT_BOTTOM: setFollows( FOLLOWS_LEFT | FOLLOWS_BOTTOM ); break;
- case RIGHT_TOP: setFollows( FOLLOWS_RIGHT | FOLLOWS_TOP ); break;
- case RIGHT_BOTTOM: setFollows( FOLLOWS_RIGHT | FOLLOWS_BOTTOM ); break;
+ case LEFT_TOP: setFollows( FOLLOWS_LEFT | FOLLOWS_TOP ); break;
+ case LEFT_BOTTOM: setFollows( FOLLOWS_LEFT | FOLLOWS_BOTTOM ); break;
+ case RIGHT_TOP: setFollows( FOLLOWS_RIGHT | FOLLOWS_TOP ); break;
+ case RIGHT_BOTTOM: setFollows( FOLLOWS_RIGHT | FOLLOWS_BOTTOM ); break;
}
-
- // decorator object, don't serialize
- setSaveToXML(FALSE);
}
+
BOOL LLResizeHandle::handleMouseDown(S32 x, S32 y, MASK mask)
{
BOOL handled = FALSE;
@@ -205,36 +207,37 @@ BOOL LLResizeHandle::handleHover(S32 x, S32 y, MASK mask)
LLView* snap_view = NULL;
LLView* test_view = NULL;
+ static LLUICachedControl<S32> snap_margin ("SnapMargin", 0);
// now do snapping
switch(mCorner)
{
case LEFT_TOP:
- snap_view = resizing_view->findSnapEdge(scaled_rect.mLeft, mouse_dir, SNAP_LEFT, SNAP_PARENT_AND_SIBLINGS, LLUI::sConfigGroup->getS32("SnapMargin"));
- test_view = resizing_view->findSnapEdge(scaled_rect.mTop, mouse_dir, SNAP_TOP, SNAP_PARENT_AND_SIBLINGS, LLUI::sConfigGroup->getS32("SnapMargin"));
+ snap_view = resizing_view->findSnapEdge(scaled_rect.mLeft, mouse_dir, SNAP_LEFT, SNAP_PARENT_AND_SIBLINGS, snap_margin);
+ test_view = resizing_view->findSnapEdge(scaled_rect.mTop, mouse_dir, SNAP_TOP, SNAP_PARENT_AND_SIBLINGS, snap_margin);
if (!snap_view)
{
snap_view = test_view;
}
break;
case LEFT_BOTTOM:
- snap_view = resizing_view->findSnapEdge(scaled_rect.mLeft, mouse_dir, SNAP_LEFT, SNAP_PARENT_AND_SIBLINGS, LLUI::sConfigGroup->getS32("SnapMargin"));
- test_view = resizing_view->findSnapEdge(scaled_rect.mBottom, mouse_dir, SNAP_BOTTOM, SNAP_PARENT_AND_SIBLINGS, LLUI::sConfigGroup->getS32("SnapMargin"));
+ snap_view = resizing_view->findSnapEdge(scaled_rect.mLeft, mouse_dir, SNAP_LEFT, SNAP_PARENT_AND_SIBLINGS, snap_margin);
+ test_view = resizing_view->findSnapEdge(scaled_rect.mBottom, mouse_dir, SNAP_BOTTOM, SNAP_PARENT_AND_SIBLINGS, snap_margin);
if (!snap_view)
{
snap_view = test_view;
}
break;
case RIGHT_TOP:
- snap_view = resizing_view->findSnapEdge(scaled_rect.mRight, mouse_dir, SNAP_RIGHT, SNAP_PARENT_AND_SIBLINGS, LLUI::sConfigGroup->getS32("SnapMargin"));
- test_view = resizing_view->findSnapEdge(scaled_rect.mTop, mouse_dir, SNAP_TOP, SNAP_PARENT_AND_SIBLINGS, LLUI::sConfigGroup->getS32("SnapMargin"));
+ snap_view = resizing_view->findSnapEdge(scaled_rect.mRight, mouse_dir, SNAP_RIGHT, SNAP_PARENT_AND_SIBLINGS, snap_margin);
+ test_view = resizing_view->findSnapEdge(scaled_rect.mTop, mouse_dir, SNAP_TOP, SNAP_PARENT_AND_SIBLINGS, snap_margin);
if (!snap_view)
{
snap_view = test_view;
}
break;
case RIGHT_BOTTOM:
- snap_view = resizing_view->findSnapEdge(scaled_rect.mRight, mouse_dir, SNAP_RIGHT, SNAP_PARENT_AND_SIBLINGS, LLUI::sConfigGroup->getS32("SnapMargin"));
- test_view = resizing_view->findSnapEdge(scaled_rect.mBottom, mouse_dir, SNAP_BOTTOM, SNAP_PARENT_AND_SIBLINGS, LLUI::sConfigGroup->getS32("SnapMargin"));
+ snap_view = resizing_view->findSnapEdge(scaled_rect.mRight, mouse_dir, SNAP_RIGHT, SNAP_PARENT_AND_SIBLINGS, snap_margin);
+ test_view = resizing_view->findSnapEdge(scaled_rect.mBottom, mouse_dir, SNAP_BOTTOM, SNAP_PARENT_AND_SIBLINGS, snap_margin);
if (!snap_view)
{
snap_view = test_view;
@@ -243,13 +246,13 @@ BOOL LLResizeHandle::handleHover(S32 x, S32 y, MASK mask)
}
// register "snap" behavior with snapped view
- resizing_view->snappedTo(snap_view);
+ resizing_view->setSnappedTo(snap_view);
// reset parent rect
resizing_view->setRect(orig_rect);
// translate and scale to new shape
- resizing_view->userSetShape(scaled_rect);
+ resizing_view->setShape(scaled_rect, true);
// update last valid mouse cursor position based on resized view's actual size
LLRect new_rect = resizing_view->getRect();
diff --git a/indra/llui/llresizehandle.h b/indra/llui/llresizehandle.h
index 0e23d526fa..1c09cbb1bd 100644
--- a/indra/llui/llresizehandle.h
+++ b/indra/llui/llresizehandle.h
@@ -35,7 +35,6 @@
#include "stdtypes.h"
#include "llview.h"
-#include "llimagegl.h"
#include "llcoord.h"
@@ -44,9 +43,18 @@ class LLResizeHandle : public LLView
public:
enum ECorner { LEFT_TOP, LEFT_BOTTOM, RIGHT_TOP, RIGHT_BOTTOM };
-
- LLResizeHandle(const std::string& name, const LLRect& rect, S32 min_width, S32 min_height, ECorner corner = RIGHT_BOTTOM );
+ struct Params : public LLInitParam::Block<Params, LLView::Params>
+ {
+ Mandatory<ECorner> corner;
+ Optional<S32> min_width;
+ Optional<S32> min_height;
+ Params();
+ };
+protected:
+ LLResizeHandle(const LLResizeHandle::Params&);
+ friend class LLUICtrlFactory;
+public:
virtual void draw();
virtual BOOL handleHover(S32 x, S32 y, MASK mask);
virtual BOOL handleMouseDown(S32 x, S32 y, MASK mask);
@@ -68,8 +76,8 @@ private:
const ECorner mCorner;
};
-const S32 RESIZE_HANDLE_HEIGHT = 16;
-const S32 RESIZE_HANDLE_WIDTH = 16;
+const S32 RESIZE_HANDLE_HEIGHT = 11;
+const S32 RESIZE_HANDLE_WIDTH = 11;
#endif // LL_RESIZEHANDLE_H
diff --git a/indra/llui/llresmgr.cpp b/indra/llui/llresmgr.cpp
index 141b08c39d..a4e23a605b 100644
--- a/indra/llui/llresmgr.cpp
+++ b/indra/llui/llresmgr.cpp
@@ -43,106 +43,8 @@
LLResMgr::LLResMgr()
{
- U32 i;
-
- // Init values for each locale.
- // Note: This is only the most bare-bones version. In the future, load these dynamically, on demand.
-
- //////////////////////////////////////////////////////////////////////////////
- // USA
- // USA Fonts
- for( i=0; i<LLFONT_COUNT; i++ )
- {
- mUSAFonts[i] = NULL;
- }
- mUSAFonts[ LLFONT_OCRA ] = LLFontGL::getFontMonospace();
- mUSAFonts[ LLFONT_SANSSERIF ] = LLFontGL::getFontSansSerif();
- mUSAFonts[ LLFONT_SANSSERIF_SMALL ] = LLFontGL::getFontSansSerifSmall();
- mUSAFonts[ LLFONT_SANSSERIF_BIG ] = LLFontGL::getFontSansSerifBig();
- mUSAFonts[ LLFONT_SMALL ] = LLFontGL::getFontMonospace();
-/*
- // USA Strings
- for( i=0; i<LLSTR_COUNT; i++ )
- {
- mUSAStrings[i] = "";
- }
- mUSAStrings[ LLSTR_HELLO ] = "hello";
- mUSAStrings[ LLSTR_GOODBYE ] = "goodbye";
- mUSAStrings[ LLSTR_CHAT_LABEL ] = "Chat";
- mUSAStrings[ LLSTR_STATUS_LABEL ] = "Properties";
- mUSAStrings[ LLSTR_X ] = "X";
- mUSAStrings[ LLSTR_Y ] = "Y";
- mUSAStrings[ LLSTR_Z ] = "Z";
- mUSAStrings[ LLSTR_POSITION ] = "Position (meters)";
- mUSAStrings[ LLSTR_SCALE ] = "Size (meters)";
- mUSAStrings[ LLSTR_ROTATION ] = "Rotation (degrees)";
- mUSAStrings[ LLSTR_HAS_PHYSICS ] = "Has Physics";
- mUSAStrings[ LLSTR_SCRIPT ] = "Script";
- mUSAStrings[ LLSTR_HELP ] = "Help";
- mUSAStrings[ LLSTR_REMOVE ] = "Remove";
- mUSAStrings[ LLSTR_CLEAR ] = "Clear";
- mUSAStrings[ LLSTR_APPLY ] = "Apply";
- mUSAStrings[ LLSTR_CANCEL ] = "Cancel";
- mUSAStrings[ LLSTR_MATERIAL ] = "Material";
- mUSAStrings[ LLSTR_FACE ] = "Face";
- mUSAStrings[ LLSTR_TEXTURE ] = "Texture";
- mUSAStrings[ LLSTR_TEXTURE_SIZE ] = "Repeats per Face";
- mUSAStrings[ LLSTR_TEXTURE_OFFSET ] = "Offset";
- mUSAStrings[ LLSTR_TEXTURE_ROTATION ] = "Rotation (degrees)";
- mUSAStrings[ LLSTR_U ] = "U";
- mUSAStrings[ LLSTR_V ] = "V";
- mUSAStrings[ LLSTR_OWNERSHIP ] = "Ownership";
- mUSAStrings[ LLSTR_PUBLIC ] = "Public";
- mUSAStrings[ LLSTR_PRIVATE ] = "Private";
- mUSAStrings[ LLSTR_REVERT ] = "Revert";
- mUSAStrings[ LLSTR_INSERT_SAMPLE ] = "Insert Sample";
- mUSAStrings[ LLSTR_SET_TEXTURE ] = "Set Texture";
- mUSAStrings[ LLSTR_EDIT_SCRIPT ] = "Edit Script...";
- mUSAStrings[ LLSTR_MOUSELOOK_INSTRUCTIONS ] = "Press ESC to leave Mouselook.";
- mUSAStrings[ LLSTR_EDIT_FACE_INSTRUCTIONS ] = "Click on face to select part. Click and hold on a picture to look more like that. Press ESC to leave Face Edit Mode.";
- mUSAStrings[ LLSTR_CLOSE ] = "Close";
- mUSAStrings[ LLSTR_MOVE ] = "Move";
- mUSAStrings[ LLSTR_ROTATE ] = "Rotate";
- mUSAStrings[ LLSTR_RESIZE ] = "Resize";
- mUSAStrings[ LLSTR_PLACE_BOX ] = "Place Box";
- mUSAStrings[ LLSTR_PLACE_PRISM ] = "Place Prism";
- mUSAStrings[ LLSTR_PLACE_PYRAMID ] = "Place Pyramid";
- mUSAStrings[ LLSTR_PLACE_TETRAHEDRON ] = "Place Tetrahedron";
- mUSAStrings[ LLSTR_PLACE_CYLINDER ] = "Place Cylinder";
- mUSAStrings[ LLSTR_PLACE_HALF_CYLINDER ] = "Place Half-Cylinder";
- mUSAStrings[ LLSTR_PLACE_CONE ] = "Place Cone";
- mUSAStrings[ LLSTR_PLACE_HALF_CONE ] = "Place Half-Cone";
- mUSAStrings[ LLSTR_PLACE_SPHERE ] = "Place Sphere";
- mUSAStrings[ LLSTR_PLACE_HALF_SPHERE ] = "Place Half-Sphere";
- mUSAStrings[ LLSTR_PLACE_BIRD ] = "Place Bird";
- mUSAStrings[ LLSTR_PLACE_SNAKE ] = "Place Silly Snake";
- mUSAStrings[ LLSTR_PLACE_ROCK ] = "Place Rock";
- mUSAStrings[ LLSTR_PLACE_TREE ] = "Place Tree";
- mUSAStrings[ LLSTR_PLACE_GRASS ] = "Place Grass";
- mUSAStrings[ LLSTR_MODIFY_LAND ] = "Modify Land";
-*/
- //////////////////////////////////////////////////////////////////////////////
- // UK
- // The Brits are a lot like us Americans, so initially assume we're the same and only code the exceptions.
-
- // UK Fonts
- for( i=0; i<LLFONT_COUNT; i++ )
- {
- mUKFonts[i] = mUSAFonts[i];
- }
-/*
- // UK Strings
- for( i=0; i<LLSTR_COUNT; i++ )
- {
- mUKStrings[i] = mUSAStrings[i];
- }
- mUKStrings[ LLSTR_HELLO ] = "hullo";
- mUKStrings[ LLSTR_GOODBYE ] = "cheerio";
-*/
- //////////////////////////////////////////////////////////////////////////////
// Set default
setLocale( LLLOCALE_USA );
-
}
@@ -151,9 +53,9 @@ void LLResMgr::setLocale( LLLOCALE_ID locale_id )
mLocale = locale_id;
//RN: for now, use normal 'C' locale for everything but specific UI input/output routines
- switch( locale_id )
- {
- case LLLOCALE_USA:
+// switch( locale_id )
+// {
+// case LLLOCALE_USA:
//#if LL_WINDOWS
// // Windows doesn't use ISO country codes.
// llinfos << "Setting locale to " << setlocale( LC_ALL, "english-usa" ) << llendl;
@@ -161,11 +63,8 @@ void LLResMgr::setLocale( LLLOCALE_ID locale_id )
// // posix version should work everywhere else.
// llinfos << "Setting locale to " << setlocale( LC_ALL, "en_US" ) << llendl;
//#endif
-
-// mStrings = mUSAStrings;
- mFonts = mUSAFonts;
- break;
- case LLLOCALE_UK:
+// break;
+// case LLLOCALE_UK:
//#if LL_WINDOWS
// // Windows doesn't use ISO country codes.
// llinfos << "Setting locale to " << setlocale( LC_ALL, "english-uk" ) << llendl;
@@ -173,15 +72,12 @@ void LLResMgr::setLocale( LLLOCALE_ID locale_id )
// // posix version should work everywhere else.
// llinfos << "Setting locale to " << setlocale( LC_ALL, "en_GB" ) << llendl;
//#endif
-
-// mStrings = mUKStrings;
- mFonts = mUKFonts;
- break;
- default:
- llassert(0);
- setLocale(LLLOCALE_USA);
- break;
- }
+// break;
+// default:
+// llassert(0);
+// setLocale(LLLOCALE_USA);
+// break;
+// }
}
char LLResMgr::getDecimalPoint() const
@@ -418,27 +314,6 @@ void LLResMgr::getIntegerString( std::string& output, S32 input ) const
}
}
-const std::string LLFONT_ID_NAMES[] =
-{
- std::string("OCRA"),
- std::string("SANSSERIF"),
- std::string("SANSSERIF_SMALL"),
- std::string("SANSSERIF_BIG"),
- std::string("SMALL"),
-};
-
-const LLFontGL* LLResMgr::getRes( std::string font_id ) const
-{
- for (S32 i=0; i<LLFONT_COUNT; ++i)
- {
- if (LLFONT_ID_NAMES[i] == font_id)
- {
- return getRes((LLFONT_ID)i);
- }
- }
- return NULL;
-}
-
#if LL_WINDOWS
const std::string LLLocale::USER_LOCALE("English_United States.1252");// = LLStringUtil::null;
const std::string LLLocale::SYSTEM_LOCALE("English_United States.1252");
diff --git a/indra/llui/llresmgr.h b/indra/llui/llresmgr.h
index d54505c503..c8fa340990 100644
--- a/indra/llui/llresmgr.h
+++ b/indra/llui/llresmgr.h
@@ -37,7 +37,7 @@
#include "locale.h"
#include "stdtypes.h"
#include "llstring.h"
-#include "llmemory.h"
+#include "llsingleton.h"
enum LLLOCALE_ID
{
@@ -46,18 +46,6 @@ enum LLLOCALE_ID
LLLOCALE_COUNT // Number of values in this enum. Keep at end.
};
-enum LLFONT_ID
-{
- LLFONT_OCRA,
- LLFONT_SANSSERIF,
- LLFONT_SANSSERIF_SMALL,
- LLFONT_SANSSERIF_BIG,
- LLFONT_SMALL,
- LLFONT_COUNT // Number of values in this enum. Keep at end.
-};
-
-class LLFontGL;
-
class LLResMgr : public LLSingleton<LLResMgr>
{
public:
@@ -74,20 +62,9 @@ public:
std::string getMonetaryString( S32 input ) const;
void getIntegerString( std::string& output, S32 input ) const;
-// const char* getRes( LLSTR_ID string_id ) const { return mStrings[ string_id ]; }
- const LLFontGL* getRes( LLFONT_ID font_id ) const { return mFonts[ font_id ]; }
- const LLFontGL* getRes( std::string font_id ) const;
private:
LLLOCALE_ID mLocale;
-// const char** mStrings;
- const LLFontGL** mFonts;
-
-// const char* mUSAStrings[LLSTR_COUNT];
- const LLFontGL* mUSAFonts[LLFONT_COUNT];
-
-// const char* mUKStrings[LLSTR_COUNT];
- const LLFontGL* mUKFonts[LLFONT_COUNT];
};
class LLLocale
diff --git a/indra/llui/llrngwriter.cpp b/indra/llui/llrngwriter.cpp
new file mode 100644
index 0000000000..cf23e3af15
--- /dev/null
+++ b/indra/llui/llrngwriter.cpp
@@ -0,0 +1,315 @@
+/**
+ * @file llrngwriter.cpp
+ * @brief Generates Relax NG schema from param blocks
+ *
+ * $LicenseInfo:firstyear=2003&license=viewergpl$
+ *
+ * Copyright (c) 2003-2009, Linden Research, Inc.
+ *
+ * Second Life Viewer Source Code
+ * The source code in this file ("Source Code") is provided by Linden Lab
+ * to you under the terms of the GNU General Public License, version 2.0
+ * ("GPL"), unless you have obtained a separate licensing agreement
+ * ("Other License"), formally executed by you and Linden Lab. Terms of
+ * the GPL can be found in doc/GPL-license.txt in this distribution, or
+ * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
+ *
+ * There are special exceptions to the terms and conditions of the GPL as
+ * it is applied to this Source Code. View the full text of the exception
+ * in the file doc/FLOSS-exception.txt in this software distribution, or
+ * online at
+ * http://secondlifegrid.net/programs/open_source/licensing/flossexception
+ *
+ * By copying, modifying or distributing this software, you acknowledge
+ * that you have read and understood your obligations described above,
+ * and agree to abide by those obligations.
+ *
+ * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+ * COMPLETENESS OR PERFORMANCE.
+ * $/LicenseInfo$
+ */
+
+#include "linden_common.h"
+
+#include "llrngwriter.h"
+#include "lluicolor.h"
+#include "lluictrlfactory.h"
+
+//
+// LLRNGWriter - writes Relax NG schema files based on a param block
+//
+LLRNGWriter::LLRNGWriter()
+{
+ // register various callbacks for inspecting the contents of a param block
+ registerInspectFunc<bool>(boost::bind(&LLRNGWriter::writeAttribute, this, "boolean", _1, _2, _3, _4));
+ registerInspectFunc<std::string>(boost::bind(&LLRNGWriter::writeAttribute, this, "string", _1, _2, _3, _4));
+ registerInspectFunc<U8>(boost::bind(&LLRNGWriter::writeAttribute, this, "unsignedByte", _1, _2, _3, _4));
+ registerInspectFunc<S8>(boost::bind(&LLRNGWriter::writeAttribute, this, "signedByte", _1, _2, _3, _4));
+ registerInspectFunc<U16>(boost::bind(&LLRNGWriter::writeAttribute, this, "unsignedShort", _1, _2, _3, _4));
+ registerInspectFunc<S16>(boost::bind(&LLRNGWriter::writeAttribute, this, "signedShort", _1, _2, _3, _4));
+ registerInspectFunc<U32>(boost::bind(&LLRNGWriter::writeAttribute, this, "unsignedInt", _1, _2, _3, _4));
+ registerInspectFunc<S32>(boost::bind(&LLRNGWriter::writeAttribute, this, "integer", _1, _2, _3, _4));
+ registerInspectFunc<F32>(boost::bind(&LLRNGWriter::writeAttribute, this, "float", _1, _2, _3, _4));
+ registerInspectFunc<F64>(boost::bind(&LLRNGWriter::writeAttribute, this, "double", _1, _2, _3, _4));
+ registerInspectFunc<LLColor4>(boost::bind(&LLRNGWriter::writeAttribute, this, "string", _1, _2, _3, _4));
+ registerInspectFunc<LLUIColor>(boost::bind(&LLRNGWriter::writeAttribute, this, "string", _1, _2, _3, _4));
+ registerInspectFunc<LLUUID>(boost::bind(&LLRNGWriter::writeAttribute, this, "string", _1, _2, _3, _4));
+ registerInspectFunc<LLSD>(boost::bind(&LLRNGWriter::writeAttribute, this, "string", _1, _2, _3, _4));
+}
+
+void LLRNGWriter::writeRNG(const std::string& type_name, LLXMLNodePtr node, const LLInitParam::BaseBlock& block, const std::string& xml_namespace)
+{
+ mGrammarNode = node;
+ mGrammarNode->setName("grammar");
+ mGrammarNode->createChild("xmlns", true)->setStringValue("http://relaxng.org/ns/structure/1.0");
+ mGrammarNode->createChild("datatypeLibrary", true)->setStringValue("http://www.w3.org/2001/XMLSchema-datatypes");
+ mGrammarNode->createChild("ns", true)->setStringValue(xml_namespace);
+
+ node = mGrammarNode->createChild("start", false);
+ node = node->createChild("ref", false);
+ node->createChild("name", true)->setStringValue(type_name);
+
+ addDefinition(type_name, block);
+}
+
+void LLRNGWriter::addDefinition(const std::string& type_name, const LLInitParam::BaseBlock& block)
+{
+ if (mDefinedElements.find(type_name) != mDefinedElements.end()) return;
+ mDefinedElements.insert(type_name);
+
+ LLXMLNodePtr node = mGrammarNode->createChild("define", false);
+ node->createChild("name", true)->setStringValue(type_name);
+
+ mElementNode = node->createChild("element", false);
+ mElementNode->createChild("name", true)->setStringValue(type_name);
+ mChildrenNode = mElementNode->createChild("zeroOrMore", false)->createChild("choice", false);
+
+ mAttributesWritten.first = mElementNode;
+ mAttributesWritten.second.clear();
+ mElementsWritten.clear();
+
+ block.inspectBlock(*this);
+
+ // add includes for all possible children
+ const std::type_info* type = *LLWidgetTypeRegistry::instance().getValue(type_name);
+ const widget_registry_t* widget_registryp = LLChildRegistryRegistry::instance().getValue(type);
+
+ // add include declarations for all valid children
+ for (widget_registry_t::Registrar::registry_map_t::const_iterator it = widget_registryp->currentRegistrar().beginItems();
+ it != widget_registryp->currentRegistrar().endItems();
+ ++it)
+ {
+ std::string child_name = it->first;
+ if (child_name == type_name)
+ {
+ continue;
+ }
+
+ LLXMLNodePtr old_element_node = mElementNode;
+ LLXMLNodePtr old_child_node = mChildrenNode;
+ addDefinition(child_name, (*LLDefaultParamBlockRegistry::instance().getValue(type))());
+ mElementNode = old_element_node;
+ mChildrenNode = old_child_node;
+
+ mChildrenNode->createChild("ref", false)->createChild("name", true)->setStringValue(child_name);
+ }
+
+ if (mChildrenNode->mChildren.isNull())
+ {
+ // remove unused children node
+ mChildrenNode->mParent->mParent->deleteChild(mChildrenNode->mParent);
+ }
+}
+
+void LLRNGWriter::writeAttribute(const std::string& type, const Parser::name_stack_t& stack, S32 min_count, S32 max_count, const std::vector<std::string>* possible_values)
+{
+ if (max_count == 0) return;
+
+ name_stack_t non_empty_names;
+ std::string attribute_name;
+ for (name_stack_t::const_iterator it = stack.begin();
+ it != stack.end();
+ ++it)
+ {
+ const std::string& name = it->first;
+ if (!name.empty())
+ {
+ non_empty_names.push_back(*it);
+ }
+ }
+
+ if (non_empty_names.empty()) return;
+
+ for (name_stack_t::const_iterator it = non_empty_names.begin();
+ it != non_empty_names.end();
+ ++it)
+ {
+ if (!attribute_name.empty())
+ {
+ attribute_name += ".";
+ }
+ attribute_name += it->first;
+ }
+
+ // singular attribute, e.g. <foo bar="1"/>
+ if (non_empty_names.size() == 1 && max_count == 1)
+ {
+ if (mAttributesWritten.second.find(attribute_name) == mAttributesWritten.second.end())
+ {
+ LLXMLNodePtr node = createCardinalityNode(mElementNode, min_count, max_count)->createChild("attribute", false);
+ node->createChild("name", true)->setStringValue(attribute_name);
+ node->createChild("data", false)->createChild("type", true)->setStringValue(type);
+
+ mAttributesWritten.second.insert(attribute_name);
+ }
+ }
+ // compound attribute
+ else
+ {
+ std::string element_name;
+
+ // traverse all but last element, leaving that as an attribute name
+ name_stack_t::const_iterator end_it = non_empty_names.end();
+ end_it--;
+
+ for (name_stack_t::const_iterator it = non_empty_names.begin();
+ it != end_it;
+ ++it)
+ {
+ if (it != non_empty_names.begin())
+ {
+ element_name += ".";
+ }
+ element_name += it->first;
+ }
+
+ elements_map_t::iterator found_it = mElementsWritten.find(element_name);
+ // <choice>
+ // <group>
+ // <optional>
+ // <attribute name="foo.bar"><data type="string"/></attribute>
+ // </optional>
+ // <optional>
+ // <attribute name="foo.baz"><data type="integer"/></attribute>
+ // </optional>
+ // </group>
+ // <element name="foo">
+ // <optional>
+ // <attribute name="bar"><data type="string"/></attribute>
+ // </optional>
+ // <optional>
+ // <attribute name="baz"><data type="string"/></attribute>
+ // </optional>
+ // </element>
+ // <element name="outer.foo">
+ // <ref name="foo"/>
+ // </element>
+ // </choice>
+
+ if (found_it != mElementsWritten.end())
+ {
+ // reuse existing element
+ LLXMLNodePtr choice_node = found_it->second.first;
+
+ // attribute with this name not already written?
+ if (found_it->second.second.find(attribute_name) == found_it->second.second.end())
+ {
+ // append to <group>
+ LLXMLNodePtr node = choice_node->mChildren->head;
+ node = createCardinalityNode(node, min_count, max_count)->createChild("attribute", false);
+ node->createChild("name", true)->setStringValue(attribute_name);
+ addTypeNode(node, type, possible_values);
+
+ // append to <element>
+ node = choice_node->mChildren->head->mNext->mChildren->head;
+ node = createCardinalityNode(node, min_count, max_count)->createChild("attribute", false);
+ node->createChild("name", true)->setStringValue(non_empty_names.back().first);
+ addTypeNode(node, type, possible_values);
+
+ // append to <element>
+ //node = choice_node->mChildren->head->mNext->mNext->mChildren->head;
+ //node = createCardinalityNode(node, min_count, max_count)->createChild("attribute", false);
+ //node->createChild("name", true)->setStringValue(non_empty_names.back().first);
+ //addTypeNode(node, type, possible_values);
+
+ found_it->second.second.insert(attribute_name);
+ }
+ }
+ else
+ {
+ LLXMLNodePtr choice_node = mElementNode->createChild("choice", false);
+
+ LLXMLNodePtr node = choice_node->createChild("group", false);
+ node = createCardinalityNode(node, min_count, max_count)->createChild("attribute", false);
+ node->createChild("name", true)->setStringValue(attribute_name);
+ addTypeNode(node, type, possible_values);
+
+ node = choice_node->createChild("optional", false);
+ node = node->createChild("element", false);
+ node->createChild("name", true)->setStringValue(element_name);
+ node = createCardinalityNode(node, min_count, max_count)->createChild("attribute", false);
+ node->createChild("name", true)->setStringValue(non_empty_names.back().first);
+ addTypeNode(node, type, possible_values);
+
+ //node = choice_node->createChild("optional", false);
+ //node = node->createChild("element", false);
+ //node->createChild("name", true)->setStringValue(mDefinitionName + "." + element_name);
+ //node = createCardinalityNode(node, min_count, max_count)->createChild("attribute", false);
+ //node->createChild("name", true)->setStringValue(non_empty_names.back().first);
+ //addTypeNode(node, type, possible_values);
+
+ attribute_data_t& attribute_data = mElementsWritten[element_name];
+ attribute_data.first = choice_node;
+ attribute_data.second.insert(attribute_name);
+ }
+ }
+}
+
+void LLRNGWriter::addTypeNode(LLXMLNodePtr parent_node, const std::string& type, const std::vector<std::string>* possible_values)
+{
+ if (possible_values)
+ {
+ LLXMLNodePtr enum_node = parent_node->createChild("choice", false);
+ for (std::vector<std::string>::const_iterator it = possible_values->begin();
+ it != possible_values->end();
+ ++it)
+ {
+ enum_node->createChild("value", false)->setStringValue(*it);
+ }
+ }
+ else
+ {
+ parent_node->createChild("data", false)->createChild("type", true)->setStringValue(type);
+ }
+}
+
+LLXMLNodePtr LLRNGWriter::createCardinalityNode(LLXMLNodePtr parent_node, S32 min_count, S32 max_count)
+{
+ // unlinked by default, meaning this attribute is forbidden
+ LLXMLNodePtr count_node = new LLXMLNode();
+ if (min_count == 0)
+ {
+ if (max_count == 1)
+ {
+ count_node = parent_node->createChild("optional", false);
+ }
+ else if (max_count > 1)
+ {
+ count_node = parent_node->createChild("zeroOrMore", false);
+ }
+ }
+ else if (min_count >= 1)
+ {
+ if (max_count == 1 && min_count == 1)
+ {
+ // just add raw element, will count as 1 and only 1
+ count_node = parent_node;
+ }
+ else
+ {
+ count_node = parent_node->createChild("oneOrMore", false);
+ }
+ }
+ return count_node;
+}
diff --git a/indra/llui/llrngwriter.h b/indra/llui/llrngwriter.h
new file mode 100644
index 0000000000..66807577b5
--- /dev/null
+++ b/indra/llui/llrngwriter.h
@@ -0,0 +1,69 @@
+/**
+ * @file llrngwriter.h
+ * @brief Generates Relax NG schema files from a param block
+ *
+ * $LicenseInfo:firstyear=2003&license=viewergpl$
+ *
+ * Copyright (c) 2003-2009, Linden Research, Inc.
+ *
+ * Second Life Viewer Source Code
+ * The source code in this file ("Source Code") is provided by Linden Lab
+ * to you under the terms of the GNU General Public License, version 2.0
+ * ("GPL"), unless you have obtained a separate licensing agreement
+ * ("Other License"), formally executed by you and Linden Lab. Terms of
+ * the GPL can be found in doc/GPL-license.txt in this distribution, or
+ * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
+ *
+ * There are special exceptions to the terms and conditions of the GPL as
+ * it is applied to this Source Code. View the full text of the exception
+ * in the file doc/FLOSS-exception.txt in this software distribution, or
+ * online at
+ * http://secondlifegrid.net/programs/open_source/licensing/flossexception
+ *
+ * By copying, modifying or distributing this software, you acknowledge
+ * that you have read and understood your obligations described above,
+ * and agree to abide by those obligations.
+ *
+ * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+ * COMPLETENESS OR PERFORMANCE.
+ * $/LicenseInfo$
+ */
+
+#ifndef LLRNGWRITER_H
+#define LLRNGWRITER_H
+
+#include "llinitparam.h"
+#include "llxmlnode.h"
+
+class LLRNGWriter : public LLInitParam::Parser
+{
+ LOG_CLASS(LLRNGWriter);
+public:
+ void writeRNG(const std::string& name, LLXMLNodePtr node, const LLInitParam::BaseBlock& block, const std::string& xml_namespace);
+ void addDefinition(const std::string& type_name, const LLInitParam::BaseBlock& block);
+
+ /*virtual*/ std::string getCurrentElementName() { return LLStringUtil::null; }
+
+ LLRNGWriter();
+
+private:
+ LLXMLNodePtr createCardinalityNode(LLXMLNodePtr parent_node, S32 min_count, S32 max_count);
+ void addTypeNode(LLXMLNodePtr parent_node, const std::string& type, const std::vector<std::string>* possible_values);
+
+ void writeAttribute(const std::string& type, const Parser::name_stack_t&, S32 min_count, S32 max_count, const std::vector<std::string>* possible_values);
+ LLXMLNodePtr mElementNode;
+ LLXMLNodePtr mChildrenNode;
+ LLXMLNodePtr mGrammarNode;
+ std::string mDefinitionName;
+
+ typedef std::pair<LLXMLNodePtr, std::set<std::string> > attribute_data_t;
+ typedef std::map<std::string, attribute_data_t> elements_map_t;
+ typedef std::set<std::string> defined_elements_t;
+
+ defined_elements_t mDefinedElements;
+ attribute_data_t mAttributesWritten;
+ elements_map_t mElementsWritten;
+};
+
+#endif //LLRNGWRITER_H
diff --git a/indra/llui/llscrollbar.cpp b/indra/llui/llscrollbar.cpp
index 65086d833d..b46915b379 100644
--- a/indra/llui/llscrollbar.cpp
+++ b/indra/llui/llscrollbar.cpp
@@ -46,101 +46,90 @@
#include "llwindow.h"
#include "llcontrol.h"
#include "llrender.h"
+#include "lluictrlfactory.h"
+
+static LLDefaultChildRegistry::Register<LLScrollbar> register_scrollbar("scroll_bar");
+
+LLScrollbar::Params::Params()
+: orientation ("orientation", HORIZONTAL),
+ doc_size ("doc_size", 0),
+ doc_pos ("doc_pos", 0),
+ page_size ("page_size", 0),
+ step_size ("step_size", 1),
+ thumb_image_vertical("thumb_image_vertical"),
+ thumb_image_horizontal("thumb_image_horizontal"),
+ track_image_vertical("track_image_vertical"),
+ track_image_horizontal("track_image_horizontal"),
+ track_color("track_color"),
+ thumb_color("thumb_color"),
+ thickness("thickness"),
+ up_button("up_button"),
+ down_button("down_button"),
+ left_button("left_button"),
+ right_button("right_button")
+{
+ tab_stop = false;
+}
-LLScrollbar::LLScrollbar(
- const std::string& name, LLRect rect,
- LLScrollbar::ORIENTATION orientation,
- S32 doc_size, S32 doc_pos, S32 page_size,
- void (*change_callback)( S32 new_pos, LLScrollbar* self, void* userdata ),
- void* callback_user_data,
- S32 step_size)
-: LLUICtrl( name, rect, TRUE, NULL, NULL ),
-
- mChangeCallback( change_callback ),
- mCallbackUserData( callback_user_data ),
- mOrientation( orientation ),
- mDocSize( doc_size ),
- mDocPos( doc_pos ),
- mPageSize( page_size ),
- mStepSize( step_size ),
+LLScrollbar::LLScrollbar(const Params & p)
+: LLUICtrl(p),
+ mChangeCallback( p.change_callback() ),
+ mOrientation( p.orientation ),
+ mDocSize( p.doc_size ),
+ mDocPos( p.doc_pos ),
+ mPageSize( p.page_size ),
+ mStepSize( p.step_size ),
mDocChanged(FALSE),
mDragStartX( 0 ),
mDragStartY( 0 ),
mHoverGlowStrength(0.15f),
mCurGlowStrength(0.f),
- mTrackColor( LLUI::sColorsGroup->getColor("ScrollbarTrackColor") ),
- mThumbColor ( LLUI::sColorsGroup->getColor("ScrollbarThumbColor") ),
- mHighlightColor ( LLUI::sColorsGroup->getColor("DefaultHighlightLight") ),
- mShadowColor ( LLUI::sColorsGroup->getColor("DefaultShadowLight") ),
+ mTrackColor( p.track_color() ),
+ mThumbColor ( p.thumb_color() ),
mOnScrollEndCallback( NULL ),
- mOnScrollEndData( NULL )
+ mOnScrollEndData( NULL ),
+ mThumbImageV(p.thumb_image_vertical),
+ mThumbImageH(p.thumb_image_horizontal),
+ mTrackImageV(p.track_image_vertical),
+ mTrackImageH(p.track_image_horizontal),
+ mThickness(p.thickness.isProvided() ? p.thickness : LLUI::sSettingGroups["config"]->getS32("UIScrollbarSize"))
{
- //llassert( 0 <= mDocSize );
- //llassert( 0 <= mDocPos && mDocPos <= mDocSize );
-
- setTabStop(FALSE);
updateThumbRect();
// Page up and page down buttons
LLRect line_up_rect;
- std::string line_up_img;
- std::string line_up_selected_img;
- std::string line_down_img;
- std::string line_down_selected_img;
-
LLRect line_down_rect;
- if( LLScrollbar::VERTICAL == mOrientation )
+ if( VERTICAL == mOrientation )
{
- line_up_rect.setLeftTopAndSize( 0, getRect().getHeight(), SCROLLBAR_SIZE, SCROLLBAR_SIZE );
- line_up_img="UIImgBtnScrollUpOutUUID";
- line_up_selected_img="UIImgBtnScrollUpInUUID";
-
- line_down_rect.setOriginAndSize( 0, 0, SCROLLBAR_SIZE, SCROLLBAR_SIZE );
- line_down_img="UIImgBtnScrollDownOutUUID";
- line_down_selected_img="UIImgBtnScrollDownInUUID";
+ line_up_rect.setLeftTopAndSize( 0, getRect().getHeight(), mThickness, mThickness );
+ line_down_rect.setOriginAndSize( 0, 0, mThickness, mThickness );
}
- else
+ else // HORIZONTAL
{
- // Horizontal
- line_up_rect.setOriginAndSize( 0, 0, SCROLLBAR_SIZE, SCROLLBAR_SIZE );
- line_up_img="UIImgBtnScrollLeftOutUUID";
- line_up_selected_img="UIImgBtnScrollLeftInUUID";
-
- line_down_rect.setOriginAndSize( getRect().getWidth() - SCROLLBAR_SIZE, 0, SCROLLBAR_SIZE, SCROLLBAR_SIZE );
- line_down_img="UIImgBtnScrollRightOutUUID";
- line_down_selected_img="UIImgBtnScrollRightInUUID";
+ line_up_rect.setOriginAndSize( 0, 0, mThickness, mThickness );
+ line_down_rect.setOriginAndSize( getRect().getWidth() - mThickness, 0, mThickness, mThickness );
}
- LLButton* line_up_btn = new LLButton(std::string("Line Up"), line_up_rect,
- line_up_img, line_up_selected_img, LLStringUtil::null,
- &LLScrollbar::onLineUpBtnPressed, this, LLFontGL::getFontSansSerif() );
- if( LLScrollbar::VERTICAL == mOrientation )
- {
- line_up_btn->setFollowsRight();
- line_up_btn->setFollowsTop();
- }
- else
- {
- // horizontal
- line_up_btn->setFollowsLeft();
- line_up_btn->setFollowsBottom();
- }
- line_up_btn->setHeldDownCallback( &LLScrollbar::onLineUpBtnPressed );
- line_up_btn->setTabStop(FALSE);
- line_up_btn->setScaleImage(TRUE);
-
- addChild(line_up_btn);
-
- LLButton* line_down_btn = new LLButton(std::string("Line Down"), line_down_rect,
- line_down_img, line_down_selected_img, LLStringUtil::null,
- &LLScrollbar::onLineDownBtnPressed, this, LLFontGL::getFontSansSerif() );
- line_down_btn->setFollowsRight();
- line_down_btn->setFollowsBottom();
- line_down_btn->setHeldDownCallback( &LLScrollbar::onLineDownBtnPressed );
- line_down_btn->setTabStop(FALSE);
- line_down_btn->setScaleImage(TRUE);
- addChild(line_down_btn);
+ LLButton::Params up_btn(mOrientation == VERTICAL ? p.up_button : p.left_button);
+ up_btn.name(std::string("Line Up"));
+ up_btn.rect(line_up_rect);
+ up_btn.click_callback.function(boost::bind(&LLScrollbar::onLineUpBtnPressed, this, _2));
+ up_btn.mouse_held_callback.function(boost::bind(&LLScrollbar::onLineUpBtnPressed, this, _2));
+ up_btn.tab_stop(false);
+ up_btn.follows.flags = (mOrientation == VERTICAL ? (FOLLOWS_RIGHT | FOLLOWS_TOP) : (FOLLOWS_LEFT | FOLLOWS_BOTTOM));
+
+ addChild(LLUICtrlFactory::create<LLButton>(up_btn));
+
+ LLButton::Params down_btn(mOrientation == VERTICAL ? p.down_button : p.right_button);
+ down_btn.name(std::string("Line Down"));
+ down_btn.rect(line_down_rect);
+ down_btn.follows.flags(FOLLOWS_RIGHT|FOLLOWS_BOTTOM);
+ down_btn.click_callback.function(boost::bind(&LLScrollbar::onLineDownBtnPressed, this, _2));
+ down_btn.mouse_held_callback.function(boost::bind(&LLScrollbar::onLineDownBtnPressed, this, _2));
+ down_btn.tab_stop(false);
+
+ addChild(LLUICtrlFactory::create<LLButton>(down_btn));
}
@@ -168,7 +157,7 @@ void LLScrollbar::setDocPos(S32 pos, BOOL update_thumb)
if( mChangeCallback )
{
- mChangeCallback( mDocPos, this, mCallbackUserData );
+ mChangeCallback( mDocPos, this );
}
if( update_thumb )
@@ -221,7 +210,7 @@ void LLScrollbar::updateThumbRect()
const S32 THUMB_MIN_LENGTH = 16;
S32 window_length = (mOrientation == LLScrollbar::HORIZONTAL) ? getRect().getWidth() : getRect().getHeight();
- S32 thumb_bg_length = llmax(0, window_length - 2 * SCROLLBAR_SIZE);
+ S32 thumb_bg_length = llmax(0, window_length - 2 * mThickness);
S32 visible_lines = llmin( mDocSize, mPageSize );
S32 thumb_length = mDocSize ? llmin(llmax( visible_lines * thumb_bg_length / mDocSize, THUMB_MIN_LENGTH), thumb_bg_length) : thumb_bg_length;
@@ -229,24 +218,24 @@ void LLScrollbar::updateThumbRect()
if( mOrientation == LLScrollbar::VERTICAL )
{
- S32 thumb_start_max = thumb_bg_length + SCROLLBAR_SIZE;
- S32 thumb_start_min = SCROLLBAR_SIZE + THUMB_MIN_LENGTH;
+ S32 thumb_start_max = thumb_bg_length + mThickness;
+ S32 thumb_start_min = mThickness + THUMB_MIN_LENGTH;
S32 thumb_start = variable_lines ? llmin( llmax(thumb_start_max - (mDocPos * (thumb_bg_length - thumb_length)) / variable_lines, thumb_start_min), thumb_start_max ) : thumb_start_max;
mThumbRect.mLeft = 0;
mThumbRect.mTop = thumb_start;
- mThumbRect.mRight = SCROLLBAR_SIZE;
+ mThumbRect.mRight = mThickness;
mThumbRect.mBottom = thumb_start - thumb_length;
}
else
{
// Horizontal
- S32 thumb_start_max = thumb_bg_length + SCROLLBAR_SIZE - thumb_length;
- S32 thumb_start_min = SCROLLBAR_SIZE;
+ S32 thumb_start_max = thumb_bg_length + mThickness - thumb_length;
+ S32 thumb_start_min = mThickness;
S32 thumb_start = variable_lines ? llmin(llmax( thumb_start_min + (mDocPos * (thumb_bg_length - thumb_length)) / variable_lines, thumb_start_min), thumb_start_max ) : thumb_start_min;
mThumbRect.mLeft = thumb_start;
- mThumbRect.mTop = SCROLLBAR_SIZE;
+ mThumbRect.mTop = mThickness;
mThumbRect.mRight = thumb_start + thumb_length;
mThumbRect.mBottom = 0;
}
@@ -318,21 +307,21 @@ BOOL LLScrollbar::handleHover(S32 x, S32 y, MASK mask)
// S32 old_pos = mThumbRect.mTop;
S32 delta_pixels = y - mDragStartY;
- if( mOrigRect.mBottom + delta_pixels < SCROLLBAR_SIZE )
+ if( mOrigRect.mBottom + delta_pixels < mThickness )
{
- delta_pixels = SCROLLBAR_SIZE - mOrigRect.mBottom - 1;
+ delta_pixels = mThickness - mOrigRect.mBottom - 1;
}
else
- if( mOrigRect.mTop + delta_pixels > height - SCROLLBAR_SIZE )
+ if( mOrigRect.mTop + delta_pixels > height - mThickness )
{
- delta_pixels = height - SCROLLBAR_SIZE - mOrigRect.mTop + 1;
+ delta_pixels = height - mThickness - mOrigRect.mTop + 1;
}
mThumbRect.mTop = mOrigRect.mTop + delta_pixels;
mThumbRect.mBottom = mOrigRect.mBottom + delta_pixels;
S32 thumb_length = mThumbRect.getHeight();
- S32 thumb_track_length = height - 2 * SCROLLBAR_SIZE;
+ S32 thumb_track_length = height - 2 * mThickness;
if( delta_pixels != mLastDelta || mDocChanged)
@@ -343,7 +332,7 @@ BOOL LLScrollbar::handleHover(S32 x, S32 y, MASK mask)
{
S32 variable_lines = getDocPosMax();
S32 pos = mThumbRect.mTop;
- F32 ratio = F32(pos - SCROLLBAR_SIZE - thumb_length) / usable_track_length;
+ F32 ratio = F32(pos - mThickness - thumb_length) / usable_track_length;
S32 new_pos = llclamp( S32(variable_lines - ratio * variable_lines + 0.5f), 0, variable_lines );
// Note: we do not call updateThumbRect() here. Instead we let the thumb and the document go slightly
@@ -362,21 +351,21 @@ BOOL LLScrollbar::handleHover(S32 x, S32 y, MASK mask)
S32 delta_pixels = x - mDragStartX;
- if( mOrigRect.mLeft + delta_pixels < SCROLLBAR_SIZE )
+ if( mOrigRect.mLeft + delta_pixels < mThickness )
{
- delta_pixels = SCROLLBAR_SIZE - mOrigRect.mLeft - 1;
+ delta_pixels = mThickness - mOrigRect.mLeft - 1;
}
else
- if( mOrigRect.mRight + delta_pixels > width - SCROLLBAR_SIZE )
+ if( mOrigRect.mRight + delta_pixels > width - mThickness )
{
- delta_pixels = width - SCROLLBAR_SIZE - mOrigRect.mRight + 1;
+ delta_pixels = width - mThickness - mOrigRect.mRight + 1;
}
mThumbRect.mLeft = mOrigRect.mLeft + delta_pixels;
mThumbRect.mRight = mOrigRect.mRight + delta_pixels;
S32 thumb_length = mThumbRect.getWidth();
- S32 thumb_track_length = width - 2 * SCROLLBAR_SIZE;
+ S32 thumb_track_length = width - 2 * mThickness;
if( delta_pixels != mLastDelta || mDocChanged)
{
@@ -386,7 +375,7 @@ BOOL LLScrollbar::handleHover(S32 x, S32 y, MASK mask)
{
S32 variable_lines = getDocPosMax();
S32 pos = mThumbRect.mLeft;
- F32 ratio = F32(pos - SCROLLBAR_SIZE) / usable_track_length;
+ F32 ratio = F32(pos - mThickness) / usable_track_length;
S32 new_pos = llclamp( S32(ratio * variable_lines + 0.5f), 0, variable_lines);
@@ -405,7 +394,7 @@ BOOL LLScrollbar::handleHover(S32 x, S32 y, MASK mask)
}
else
{
- handled = childrenHandleMouseUp( x, y, mask ) != NULL;
+ handled = childrenHandleHover( x, y, mask ) != NULL;
}
// Opaque
@@ -475,14 +464,14 @@ void LLScrollbar::reshape(S32 width, S32 height, BOOL called_from_parent)
if (mOrientation == VERTICAL)
{
- up_button->reshape(up_button->getRect().getWidth(), llmin(getRect().getHeight() / 2, SCROLLBAR_SIZE));
- down_button->reshape(down_button->getRect().getWidth(), llmin(getRect().getHeight() / 2, SCROLLBAR_SIZE));
+ up_button->reshape(up_button->getRect().getWidth(), llmin(getRect().getHeight() / 2, mThickness));
+ down_button->reshape(down_button->getRect().getWidth(), llmin(getRect().getHeight() / 2, mThickness));
up_button->setOrigin(up_button->getRect().mLeft, getRect().getHeight() - up_button->getRect().getHeight());
}
else
{
- up_button->reshape(llmin(getRect().getWidth() / 2, SCROLLBAR_SIZE), up_button->getRect().getHeight());
- down_button->reshape(llmin(getRect().getWidth() / 2, SCROLLBAR_SIZE), down_button->getRect().getHeight());
+ up_button->reshape(llmin(getRect().getWidth() / 2, mThickness), up_button->getRect().getHeight());
+ down_button->reshape(llmin(getRect().getWidth() / 2, mThickness), down_button->getRect().getHeight());
down_button->setOrigin(getRect().getWidth() - down_button->getRect().getWidth(), down_button->getRect().mBottom);
}
updateThumbRect();
@@ -507,46 +496,67 @@ void LLScrollbar::draw()
mCurGlowStrength = lerp(mCurGlowStrength, 0.f, LLCriticalDamp::getInterpolant(0.05f));
}
-
// Draw background and thumb.
- LLUIImage* rounded_rect_imagep = LLUI::sImageProvider->getUIImage("rounded_square.tga");
-
- if (!rounded_rect_imagep)
+ if ( ( mOrientation == VERTICAL&&(mThumbImageV.isNull() || mThumbImageH.isNull()) )
+ || (mOrientation == HORIZONTAL&&(mTrackImageH.isNull() || mTrackImageV.isNull()) ))
{
- gl_rect_2d(mOrientation == HORIZONTAL ? SCROLLBAR_SIZE : 0,
- mOrientation == VERTICAL ? getRect().getHeight() - 2 * SCROLLBAR_SIZE : getRect().getHeight(),
- mOrientation == HORIZONTAL ? getRect().getWidth() - 2 * SCROLLBAR_SIZE : getRect().getWidth(),
- mOrientation == VERTICAL ? SCROLLBAR_SIZE : 0, mTrackColor, TRUE);
+ gl_rect_2d(mOrientation == HORIZONTAL ? mThickness : 0,
+ mOrientation == VERTICAL ? getRect().getHeight() - 2 * mThickness : getRect().getHeight(),
+ mOrientation == HORIZONTAL ? getRect().getWidth() - 2 * mThickness : getRect().getWidth(),
+ mOrientation == VERTICAL ? mThickness : 0, mTrackColor.get(), TRUE);
- gl_rect_2d(mThumbRect, mThumbColor, TRUE);
+ gl_rect_2d(mThumbRect, mThumbColor.get(), TRUE);
}
else
{
- // Background
- rounded_rect_imagep->drawSolid(mOrientation == HORIZONTAL ? SCROLLBAR_SIZE : 0,
- mOrientation == VERTICAL ? SCROLLBAR_SIZE : 0,
- mOrientation == HORIZONTAL ? getRect().getWidth() - 2 * SCROLLBAR_SIZE : getRect().getWidth(),
- mOrientation == VERTICAL ? getRect().getHeight() - 2 * SCROLLBAR_SIZE : getRect().getHeight(),
- mTrackColor);
-
// Thumb
LLRect outline_rect = mThumbRect;
outline_rect.stretch(2);
-
- if (gFocusMgr.getKeyboardFocus() == this)
+ // Background
+
+ if(mOrientation == HORIZONTAL)
{
- rounded_rect_imagep->draw(outline_rect, gFocusMgr.getFocusColor());
+ mTrackImageH->drawSolid(mThickness //S32 x
+ , 0 //S32 y
+ , getRect().getWidth() - 2 * mThickness //S32 width
+ , getRect().getHeight() //S32 height
+ , mTrackColor.get()); //const LLColor4& color
+
+ if (gFocusMgr.getKeyboardFocus() == this)
+ {
+ mTrackImageH->draw(outline_rect, gFocusMgr.getFocusColor());
+ }
+
+ mThumbImageH->draw(mThumbRect, mThumbColor.get());
+ if (mCurGlowStrength > 0.01f)
+ {
+ gGL.setSceneBlendType(LLRender::BT_ADD_WITH_ALPHA);
+ mThumbImageH->drawSolid(mThumbRect, LLColor4(1.f, 1.f, 1.f, mCurGlowStrength));
+ gGL.setSceneBlendType(LLRender::BT_ALPHA);
+ }
+
}
-
- rounded_rect_imagep->draw(mThumbRect, mThumbColor);
- if (mCurGlowStrength > 0.01f)
+ else if(mOrientation == VERTICAL)
{
- gGL.setSceneBlendType(LLRender::BT_ADD_WITH_ALPHA);
- rounded_rect_imagep->drawSolid(mThumbRect, LLColor4(1.f, 1.f, 1.f, mCurGlowStrength));
- gGL.setSceneBlendType(LLRender::BT_ALPHA);
+ mTrackImageV->drawSolid( 0 //S32 x
+ , mThickness //S32 y
+ , getRect().getWidth() //S32 width
+ , getRect().getHeight() - 2 * mThickness //S32 height
+ , mTrackColor.get()); //const LLColor4& color
+ if (gFocusMgr.getKeyboardFocus() == this)
+ {
+ mTrackImageV->draw(outline_rect, gFocusMgr.getFocusColor());
+ }
+
+ mThumbImageV->draw(mThumbRect, mThumbColor.get());
+ if (mCurGlowStrength > 0.01f)
+ {
+ gGL.setSceneBlendType(LLRender::BT_ADD_WITH_ALPHA);
+ mThumbImageV->drawSolid(mThumbRect, LLColor4(1.f, 1.f, 1.f, mCurGlowStrength));
+ gGL.setSceneBlendType(LLRender::BT_ALPHA);
+ }
}
-
}
BOOL was_scrolled_to_bottom = (getDocPos() == getDocPosMax());
@@ -625,19 +635,24 @@ void LLScrollbar::pageDown(S32 overlap)
}
}
-// static
-void LLScrollbar::onLineUpBtnPressed( void* userdata )
+void LLScrollbar::onLineUpBtnPressed( const LLSD& data )
{
- LLScrollbar* self = (LLScrollbar*) userdata;
-
- self->changeLine( - self->mStepSize, TRUE );
+ changeLine( -mStepSize, TRUE );
}
-// static
-void LLScrollbar::onLineDownBtnPressed( void* userdata )
+void LLScrollbar::onLineDownBtnPressed( const LLSD& data )
{
- LLScrollbar* self = (LLScrollbar*) userdata;
- self->changeLine( self->mStepSize, TRUE );
+ changeLine( mStepSize, TRUE );
}
+namespace LLInitParam
+{
+ template<>
+ bool ParamCompare<boost::function<void (S32, LLScrollbar*)> >::equals(
+ const boost::function<void (S32, LLScrollbar*)> &a,
+ const boost::function<void (S32, LLScrollbar*)> &b)
+ {
+ return false;
+ }
+}
diff --git a/indra/llui/llscrollbar.h b/indra/llui/llscrollbar.h
index 0bbf8662aa..30d906e04c 100644
--- a/indra/llui/llscrollbar.h
+++ b/indra/llui/llscrollbar.h
@@ -36,12 +36,7 @@
#include "stdtypes.h"
#include "lluictrl.h"
#include "v4color.h"
-
-//
-// Constants
-//
-const S32 SCROLLBAR_SIZE = 16;
-
+#include "llbutton.h"
//
// Classes
@@ -50,15 +45,43 @@ class LLScrollbar
: public LLUICtrl
{
public:
- enum ORIENTATION { HORIZONTAL, VERTICAL };
- LLScrollbar(const std::string& name, LLRect rect,
- ORIENTATION orientation,
- S32 doc_size, S32 doc_pos, S32 page_size,
- void(*change_callback)( S32 new_pos, LLScrollbar* self, void* userdata ),
- void* callback_user_data = NULL,
- S32 step_size = 1);
+ enum ORIENTATION { HORIZONTAL, VERTICAL };
+
+ typedef boost::function<void (S32, LLScrollbar*)> callback_t;
+ struct Params
+ : public LLInitParam::Block<Params, LLUICtrl::Params>
+ {
+ Mandatory<ORIENTATION> orientation;
+ Mandatory<S32> doc_size;
+ Mandatory<S32> doc_pos;
+ Mandatory<S32> page_size;
+
+ Optional<callback_t> change_callback;
+ Optional<S32> step_size;
+ Optional<S32> thickness;
+
+ Optional<LLUIImage*> thumb_image_vertical,
+ thumb_image_horizontal,
+ track_image_horizontal,
+ track_image_vertical;
+
+ Optional<LLUIColor> track_color,
+ thumb_color;
+
+ Optional<LLButton::Params> up_button;
+ Optional<LLButton::Params> down_button;
+ Optional<LLButton::Params> left_button;
+ Optional<LLButton::Params> right_button;
+
+ Params();
+ };
+
+protected:
+ LLScrollbar (const Params & p);
+ friend class LLUICtrlFactory;
+public:
virtual ~LLScrollbar();
virtual void setValue(const LLSD& value);
@@ -101,22 +124,14 @@ public:
void pageUp(S32 overlap);
void pageDown(S32 overlap);
- static void onLineUpBtnPressed(void* userdata);
- static void onLineDownBtnPressed(void* userdata);
-
- void setTrackColor( const LLColor4& color ) { mTrackColor = color; }
- void setThumbColor( const LLColor4& color ) { mThumbColor = color; }
- void setHighlightColor( const LLColor4& color ) { mHighlightColor = color; }
- void setShadowColor( const LLColor4& color ) { mShadowColor = color; }
-
- void setOnScrollEndCallback(void (*callback)(void*), void* userdata) { mOnScrollEndCallback = callback; mOnScrollEndData = userdata;}
+ void onLineUpBtnPressed(const LLSD& data);
+ void onLineDownBtnPressed(const LLSD& data);
private:
void updateThumbRect();
void changeLine(S32 delta, BOOL update_thumb );
- void (*mChangeCallback)( S32 new_pos, LLScrollbar* self, void* userdata );
- void* mCallbackUserData;
+ callback_t mChangeCallback;
const ORIENTATION mOrientation;
S32 mDocSize; // Size of the document that the scrollbar is modeling. Units depend on the user. 0 <= mDocSize.
@@ -134,16 +149,26 @@ private:
LLRect mOrigRect;
S32 mLastDelta;
- LLColor4 mTrackColor;
- LLColor4 mThumbColor;
- LLColor4 mFocusColor;
- LLColor4 mHighlightColor;
- LLColor4 mShadowColor;
+ LLUIColor mTrackColor;
+ LLUIColor mThumbColor;
+
+ LLUIImagePtr mThumbImageV;
+ LLUIImagePtr mThumbImageH;
+ LLUIImagePtr mTrackImageV;
+ LLUIImagePtr mTrackImageH;
+
+ S32 mThickness;
void (*mOnScrollEndCallback)(void*);
void *mOnScrollEndData;
};
+namespace LLInitParam
+{
+ template<>
+ bool ParamCompare<boost::function<void (S32, LLScrollbar*)> >::equals(
+ const boost::function<void (S32, LLScrollbar*)> &a, const boost::function<void (S32, LLScrollbar*)> &b);
+}
#endif // LL_SCROLLBAR_H
diff --git a/indra/llui/llscrollcontainer.cpp b/indra/llui/llscrollcontainer.cpp
index cf03259879..13f862f3af 100644
--- a/indra/llui/llscrollcontainer.cpp
+++ b/indra/llui/llscrollcontainer.cpp
@@ -1,6 +1,6 @@
/**
* @file llscrollcontainer.cpp
- * @brief LLScrollableContainerView base class
+ * @brief LLScrollContainer base class
*
* $LicenseInfo:firstyear=2001&license=viewergpl$
*
@@ -33,8 +33,12 @@
#include "linden_common.h"
-#include "llrender.h"
#include "llscrollcontainer.h"
+
+#include "llrender.h"
+#include "llcontainerview.h"
+// #include "llfolderview.h"
+#include "llscrollingpanellist.h"
#include "llscrollbar.h"
#include "llui.h"
#include "llkeyboard.h"
@@ -42,6 +46,7 @@
#include "llfocusmgr.h"
#include "llframetimer.h"
#include "lluictrlfactory.h"
+#include "llpanel.h"
#include "llfontgl.h"
///----------------------------------------------------------------------------
@@ -50,103 +55,94 @@
static const S32 HORIZONTAL_MULTIPLE = 8;
static const S32 VERTICAL_MULTIPLE = 16;
-static const F32 MIN_AUTO_SCROLL_RATE = 120.f;
-static const F32 MAX_AUTO_SCROLL_RATE = 500.f;
static const F32 AUTO_SCROLL_RATE_ACCEL = 120.f;
///----------------------------------------------------------------------------
-/// Class LLScrollableContainerView
+/// Class LLScrollContainer
///----------------------------------------------------------------------------
-static LLRegisterWidget<LLScrollableContainerView> r("scroll_container");
-
-// Default constructor
-LLScrollableContainerView::LLScrollableContainerView( const std::string& name,
- const LLRect& rect,
- LLView* scrolled_view,
- BOOL is_opaque,
- const LLColor4& bg_color ) :
- LLUICtrl( name, rect, FALSE, NULL, NULL ),
- mScrolledView( scrolled_view ),
- mIsOpaque( is_opaque ),
- mBackgroundColor( bg_color ),
- mReserveScrollCorner( FALSE ),
- mAutoScrolling( FALSE ),
- mAutoScrollRate( 0.f )
+static LLDefaultChildRegistry::Register<LLScrollContainer> r("scroll_container");
+
+#include "llscrollingpanellist.h"
+#include "llcontainerview.h"
+#include "llpanel.h"
+static ScrollContainerRegistry::Register<LLScrollingPanelList> r1("scrolling_panel_list");
+static ScrollContainerRegistry::Register<LLContainerView> r2("container_view");
+static ScrollContainerRegistry::Register<LLPanel> r3("panel", &LLPanel::fromXML);
+
+LLScrollContainer::Params::Params()
+: is_opaque("opaque"),
+ bg_color("color"),
+ border_visible("border_visible"),
+ min_auto_scroll_rate("min_auto_scroll_rate", 100),
+ max_auto_scroll_rate("max_auto_scroll_rate", 1000),
+ reserve_scroll_corner("reserve_scroll_corner", false)
{
- if( mScrolledView )
- {
- addChild( mScrolledView );
- }
-
- init();
+ name = "scroll_container";
+ mouse_opaque(true);
+ tab_stop(false);
}
-// LLUICtrl constructor
-LLScrollableContainerView::LLScrollableContainerView( const std::string& name, const LLRect& rect,
- LLUICtrl* scrolled_ctrl, BOOL is_opaque,
- const LLColor4& bg_color) :
- LLUICtrl( name, rect, FALSE, NULL, NULL ),
- mScrolledView( scrolled_ctrl ),
- mIsOpaque( is_opaque ),
- mBackgroundColor( bg_color ),
- mReserveScrollCorner( FALSE ),
- mAutoScrolling( FALSE ),
- mAutoScrollRate( 0.f )
-{
- if( scrolled_ctrl )
- {
- addChild( scrolled_ctrl );
- }
-
- init();
-}
-void LLScrollableContainerView::init()
+// Default constructor
+LLScrollContainer::LLScrollContainer(const LLScrollContainer::Params& p)
+: LLUICtrl(p),
+ mAutoScrolling( FALSE ),
+ mAutoScrollRate( 0.f ),
+ mBackgroundColor(p.bg_color()),
+ mIsOpaque(p.is_opaque),
+ mReserveScrollCorner(p.reserve_scroll_corner),
+ mMinAutoScrollRate(p.min_auto_scroll_rate),
+ mMaxAutoScrollRate(p.max_auto_scroll_rate),
+ mScrolledView(NULL)
{
+ static LLUICachedControl<S32> scrollbar_size ("UIScrollbarSize", 0);
LLRect border_rect( 0, getRect().getHeight(), getRect().getWidth(), 0 );
- mBorder = new LLViewBorder( std::string("scroll border"), border_rect, LLViewBorder::BEVEL_IN );
- addChild( mBorder );
+ LLViewBorder::Params params;
+ params.name("scroll border");
+ params.rect(border_rect);
+ params.visible(p.border_visible);
+ params.bevel_style(LLViewBorder::BEVEL_IN);
+ mBorder = LLUICtrlFactory::create<LLViewBorder> (params);
+ LLView::addChild( mBorder );
mInnerRect.set( 0, getRect().getHeight(), getRect().getWidth(), 0 );
mInnerRect.stretch( -mBorder->getBorderWidth() );
LLRect vertical_scroll_rect = mInnerRect;
- vertical_scroll_rect.mLeft = vertical_scroll_rect.mRight - SCROLLBAR_SIZE;
- mScrollbar[VERTICAL] = new LLScrollbar( std::string("scrollable vertical"),
- vertical_scroll_rect,
- LLScrollbar::VERTICAL,
- mInnerRect.getHeight(),
- 0,
- mInnerRect.getHeight(),
- NULL, this,
- VERTICAL_MULTIPLE);
- addChild( mScrollbar[VERTICAL] );
- mScrollbar[VERTICAL]->setVisible( FALSE );
- mScrollbar[VERTICAL]->setFollowsRight();
- mScrollbar[VERTICAL]->setFollowsTop();
- mScrollbar[VERTICAL]->setFollowsBottom();
+ vertical_scroll_rect.mLeft = vertical_scroll_rect.mRight - scrollbar_size;
+ LLScrollbar::Params sbparams;
+ sbparams.name("scrollable vertical");
+ sbparams.rect(vertical_scroll_rect);
+ sbparams.orientation(LLScrollbar::VERTICAL);
+ sbparams.doc_size(mInnerRect.getHeight());
+ sbparams.doc_pos(0);
+ sbparams.page_size(mInnerRect.getHeight());
+ sbparams.step_size(VERTICAL_MULTIPLE);
+ sbparams.follows.flags(FOLLOWS_RIGHT | FOLLOWS_TOP | FOLLOWS_BOTTOM);
+ sbparams.visible(false);
+ sbparams.change_callback(p.scroll_callback);
+ mScrollbar[VERTICAL] = LLUICtrlFactory::create<LLScrollbar> (sbparams);
+ LLView::addChild( mScrollbar[VERTICAL] );
LLRect horizontal_scroll_rect = mInnerRect;
- horizontal_scroll_rect.mTop = horizontal_scroll_rect.mBottom + SCROLLBAR_SIZE;
- mScrollbar[HORIZONTAL] = new LLScrollbar( std::string("scrollable horizontal"),
- horizontal_scroll_rect,
- LLScrollbar::HORIZONTAL,
- mInnerRect.getWidth(),
- 0,
- mInnerRect.getWidth(),
- NULL, this,
- HORIZONTAL_MULTIPLE);
- addChild( mScrollbar[HORIZONTAL] );
- mScrollbar[HORIZONTAL]->setVisible( FALSE );
- mScrollbar[HORIZONTAL]->setFollowsLeft();
- mScrollbar[HORIZONTAL]->setFollowsRight();
-
- setTabStop(FALSE);
+ horizontal_scroll_rect.mTop = horizontal_scroll_rect.mBottom + scrollbar_size;
+ sbparams.name("scrollable horizontal");
+ sbparams.rect(horizontal_scroll_rect);
+ sbparams.orientation(LLScrollbar::HORIZONTAL);
+ sbparams.doc_size(mInnerRect.getWidth());
+ sbparams.doc_pos(0);
+ sbparams.page_size(mInnerRect.getWidth());
+ sbparams.step_size(VERTICAL_MULTIPLE);
+ sbparams.visible(false);
+ sbparams.follows.flags(FOLLOWS_LEFT | FOLLOWS_RIGHT);
+ sbparams.change_callback(p.scroll_callback);
+ mScrollbar[HORIZONTAL] = LLUICtrlFactory::create<LLScrollbar> (sbparams);
+ LLView::addChild( mScrollbar[HORIZONTAL] );
}
// Destroys the object
-LLScrollableContainerView::~LLScrollableContainerView( void )
+LLScrollContainer::~LLScrollContainer( void )
{
// mScrolledView and mScrollbar are child views, so the LLView
// destructor takes care of memory deallocation.
@@ -159,9 +155,9 @@ LLScrollableContainerView::~LLScrollableContainerView( void )
// internal scrollbar handlers
// virtual
-void LLScrollableContainerView::scrollHorizontal( S32 new_pos )
+void LLScrollContainer::scrollHorizontal( S32 new_pos )
{
- //llinfos << "LLScrollableContainerView::scrollHorizontal()" << llendl;
+ //llinfos << "LLScrollContainer::scrollHorizontal()" << llendl;
if( mScrolledView )
{
LLRect doc_rect = mScrolledView->getRect();
@@ -171,9 +167,9 @@ void LLScrollableContainerView::scrollHorizontal( S32 new_pos )
}
// virtual
-void LLScrollableContainerView::scrollVertical( S32 new_pos )
+void LLScrollContainer::scrollVertical( S32 new_pos )
{
- // llinfos << "LLScrollableContainerView::scrollVertical() " << new_pos << llendl;
+ // llinfos << "LLScrollContainer::scrollVertical() " << new_pos << llendl;
if( mScrolledView )
{
LLRect doc_rect = mScrolledView->getRect();
@@ -183,12 +179,12 @@ void LLScrollableContainerView::scrollVertical( S32 new_pos )
}
// LLView functionality
-void LLScrollableContainerView::reshape(S32 width, S32 height,
+void LLScrollContainer::reshape(S32 width, S32 height,
BOOL called_from_parent)
{
LLUICtrl::reshape( width, height, called_from_parent );
- mInnerRect.set( 0, getRect().getHeight(), getRect().getWidth(), 0 );
+ mInnerRect = getLocalRect();
mInnerRect.stretch( -mBorder->getBorderWidth() );
if (mScrolledView)
@@ -199,22 +195,33 @@ void LLScrollableContainerView::reshape(S32 width, S32 height,
S32 visible_height = 0;
BOOL show_v_scrollbar = FALSE;
BOOL show_h_scrollbar = FALSE;
- calcVisibleSize( scrolled_rect, &visible_width, &visible_height, &show_h_scrollbar, &show_v_scrollbar );
+ calcVisibleSize( &visible_width, &visible_height, &show_h_scrollbar, &show_v_scrollbar );
mScrollbar[VERTICAL]->setDocSize( scrolled_rect.getHeight() );
mScrollbar[VERTICAL]->setPageSize( visible_height );
mScrollbar[HORIZONTAL]->setDocSize( scrolled_rect.getWidth() );
mScrollbar[HORIZONTAL]->setPageSize( visible_width );
+ updateScroll();
}
}
-BOOL LLScrollableContainerView::handleKeyHere(KEY key, MASK mask)
+BOOL LLScrollContainer::handleKeyHere(KEY key, MASK mask)
{
+ // allow scrolled view to handle keystrokes in case it delegated keyboard focus
+ // to the scroll container.
+ // NOTE: this should not recurse indefinitely as handleKeyHere
+ // should not propagate to parent controls, so mScrolledView should *not*
+ // call LLScrollContainer::handleKeyHere in turn
+ if (mScrolledView && mScrolledView->handleKeyHere(key, mask))
+ {
+ return TRUE;
+ }
for( S32 i = 0; i < SCROLLBAR_COUNT; i++ )
{
if( mScrollbar[i]->handleKeyHere(key, mask) )
{
+ updateScroll();
return TRUE;
}
}
@@ -222,7 +229,7 @@ BOOL LLScrollableContainerView::handleKeyHere(KEY key, MASK mask)
return FALSE;
}
-BOOL LLScrollableContainerView::handleScrollWheel( S32 x, S32 y, S32 clicks )
+BOOL LLScrollContainer::handleScrollWheel( S32 x, S32 y, S32 clicks )
{
for( S32 i = 0; i < SCROLLBAR_COUNT; i++ )
{
@@ -231,6 +238,7 @@ BOOL LLScrollableContainerView::handleScrollWheel( S32 x, S32 y, S32 clicks )
// Pretend the mouse is over the scrollbar
if( mScrollbar[i]->handleScrollWheel( 0, 0, clicks ) )
{
+ updateScroll();
return TRUE;
}
}
@@ -239,139 +247,103 @@ BOOL LLScrollableContainerView::handleScrollWheel( S32 x, S32 y, S32 clicks )
return TRUE;
}
-BOOL LLScrollableContainerView::needsToScroll(S32 x, S32 y, LLScrollableContainerView::SCROLL_ORIENTATION axis) const
-{
- if(mScrollbar[axis]->getVisible())
- {
- LLRect inner_rect_local( 0, mInnerRect.getHeight(), mInnerRect.getWidth(), 0 );
- const S32 AUTOSCROLL_SIZE = 10;
- if(mScrollbar[axis]->getVisible())
- {
- inner_rect_local.mRight -= SCROLLBAR_SIZE;
- inner_rect_local.mTop += AUTOSCROLL_SIZE;
- inner_rect_local.mBottom = inner_rect_local.mTop - AUTOSCROLL_SIZE;
- }
- if( inner_rect_local.pointInRect( x, y ) && (mScrollbar[axis]->getDocPos() > 0) )
- {
- return TRUE;
- }
-
- }
- return FALSE;
-}
-
-BOOL LLScrollableContainerView::handleDragAndDrop(S32 x, S32 y, MASK mask,
+BOOL LLScrollContainer::handleDragAndDrop(S32 x, S32 y, MASK mask,
BOOL drop,
EDragAndDropType cargo_type,
void* cargo_data,
EAcceptance* accept,
std::string& tooltip_msg)
{
+ static LLUICachedControl<S32> scrollbar_size ("UIScrollbarSize", 0);
// Scroll folder view if needed. Never accepts a drag or drop.
*accept = ACCEPT_NO;
- BOOL handled = FALSE;
+ BOOL handled = autoScroll(x, y);
+
+ if( !handled )
+ {
+ handled = childrenHandleDragAndDrop(x, y, mask, drop, cargo_type,
+ cargo_data, accept, tooltip_msg) != NULL;
+ }
+
+ return TRUE;
+}
+
+bool LLScrollContainer::autoScroll(S32 x, S32 y)
+{
+ static LLUICachedControl<S32> scrollbar_size ("UIScrollbarSize", 0);
+
+ bool scrolling = false;
if( mScrollbar[HORIZONTAL]->getVisible() || mScrollbar[VERTICAL]->getVisible() )
{
- const S32 AUTOSCROLL_SIZE = 10;
- S32 auto_scroll_speed = llround(mAutoScrollRate * LLFrameTimer::getFrameDeltaTimeF32());
-
+ LLRect screen_local_extents;
+ screenRectToLocal(getRootView()->getLocalRect(), &screen_local_extents);
+
LLRect inner_rect_local( 0, mInnerRect.getHeight(), mInnerRect.getWidth(), 0 );
if( mScrollbar[HORIZONTAL]->getVisible() )
{
- inner_rect_local.mBottom += SCROLLBAR_SIZE;
+ inner_rect_local.mBottom += scrollbar_size;
}
if( mScrollbar[VERTICAL]->getVisible() )
{
- inner_rect_local.mRight -= SCROLLBAR_SIZE;
+ inner_rect_local.mRight -= scrollbar_size;
}
+ // clip rect against root view
+ inner_rect_local.intersectWith(screen_local_extents);
+
+ S32 auto_scroll_speed = llround(mAutoScrollRate * LLFrameTimer::getFrameDeltaTimeF32());
+ // autoscroll region should take up no more than one third of visible scroller area
+ S32 auto_scroll_region_width = llmin(inner_rect_local.getWidth() / 3, 10);
+ S32 auto_scroll_region_height = llmin(inner_rect_local.getHeight() / 3, 10);
+
if( mScrollbar[HORIZONTAL]->getVisible() )
{
- LLRect left_scroll_rect = inner_rect_local;
- left_scroll_rect.mRight = AUTOSCROLL_SIZE;
+ LLRect left_scroll_rect = screen_local_extents;
+ left_scroll_rect.mRight = inner_rect_local.mLeft + auto_scroll_region_width;
if( left_scroll_rect.pointInRect( x, y ) && (mScrollbar[HORIZONTAL]->getDocPos() > 0) )
{
mScrollbar[HORIZONTAL]->setDocPos( mScrollbar[HORIZONTAL]->getDocPos() - auto_scroll_speed );
mAutoScrolling = TRUE;
- handled = TRUE;
+ scrolling = true;
}
- LLRect right_scroll_rect = inner_rect_local;
- right_scroll_rect.mLeft = inner_rect_local.mRight - AUTOSCROLL_SIZE;
+ LLRect right_scroll_rect = screen_local_extents;
+ right_scroll_rect.mLeft = inner_rect_local.mRight - auto_scroll_region_width;
if( right_scroll_rect.pointInRect( x, y ) && (mScrollbar[HORIZONTAL]->getDocPos() < mScrollbar[HORIZONTAL]->getDocPosMax()) )
{
mScrollbar[HORIZONTAL]->setDocPos( mScrollbar[HORIZONTAL]->getDocPos() + auto_scroll_speed );
mAutoScrolling = TRUE;
- handled = TRUE;
+ scrolling = true;
}
}
if( mScrollbar[VERTICAL]->getVisible() )
{
- LLRect bottom_scroll_rect = inner_rect_local;
- bottom_scroll_rect.mTop = AUTOSCROLL_SIZE + bottom_scroll_rect.mBottom;
+ LLRect bottom_scroll_rect = screen_local_extents;
+ bottom_scroll_rect.mTop = inner_rect_local.mBottom + auto_scroll_region_height;
if( bottom_scroll_rect.pointInRect( x, y ) && (mScrollbar[VERTICAL]->getDocPos() < mScrollbar[VERTICAL]->getDocPosMax()) )
{
mScrollbar[VERTICAL]->setDocPos( mScrollbar[VERTICAL]->getDocPos() + auto_scroll_speed );
mAutoScrolling = TRUE;
- handled = TRUE;
+ scrolling = true;
}
- LLRect top_scroll_rect = inner_rect_local;
- top_scroll_rect.mBottom = inner_rect_local.mTop - AUTOSCROLL_SIZE;
+ LLRect top_scroll_rect = screen_local_extents;
+ top_scroll_rect.mBottom = inner_rect_local.mTop - auto_scroll_region_height;
if( top_scroll_rect.pointInRect( x, y ) && (mScrollbar[VERTICAL]->getDocPos() > 0) )
{
mScrollbar[VERTICAL]->setDocPos( mScrollbar[VERTICAL]->getDocPos() - auto_scroll_speed );
mAutoScrolling = TRUE;
- handled = TRUE;
+ scrolling = true;
}
}
}
-
- if( !handled )
- {
- handled = childrenHandleDragAndDrop(x, y, mask, drop, cargo_type,
- cargo_data, accept, tooltip_msg) != NULL;
- }
-
- return TRUE;
+ return scrolling;
}
-
-BOOL LLScrollableContainerView::handleToolTip(S32 x, S32 y, std::string& msg, LLRect* sticky_rect)
-{
- S32 local_x, local_y;
- for( S32 i = 0; i < SCROLLBAR_COUNT; i++ )
- {
- local_x = x - mScrollbar[i]->getRect().mLeft;
- local_y = y - mScrollbar[i]->getRect().mBottom;
- if( mScrollbar[i]->handleToolTip(local_x, local_y, msg, sticky_rect) )
- {
- return TRUE;
- }
- }
- // Handle 'child' view.
- if( mScrolledView )
- {
- local_x = x - mScrolledView->getRect().mLeft;
- local_y = y - mScrolledView->getRect().mBottom;
- if( mScrolledView->handleToolTip(local_x, local_y, msg, sticky_rect) )
- {
- return TRUE;
- }
- }
-
- // Opaque
- return TRUE;
-}
-
-void LLScrollableContainerView::calcVisibleSize( S32 *visible_width, S32 *visible_height, BOOL* show_h_scrollbar, BOOL* show_v_scrollbar ) const
-{
- const LLRect& rect = mScrolledView->getRect();
- calcVisibleSize(rect, visible_width, visible_height, show_h_scrollbar, show_v_scrollbar);
-}
-
-void LLScrollableContainerView::calcVisibleSize( const LLRect& doc_rect, S32 *visible_width, S32 *visible_height, BOOL* show_h_scrollbar, BOOL* show_v_scrollbar ) const
+void LLScrollContainer::calcVisibleSize( S32 *visible_width, S32 *visible_height, BOOL* show_h_scrollbar, BOOL* show_v_scrollbar ) const
{
+ const LLRect& doc_rect = getScrolledViewRect();
+ static LLUICachedControl<S32> scrollbar_size ("UIScrollbarSize", 0);
S32 doc_width = doc_rect.getWidth();
S32 doc_height = doc_rect.getHeight();
@@ -382,43 +354,45 @@ void LLScrollableContainerView::calcVisibleSize( const LLRect& doc_rect, S32 *vi
if( *visible_height < doc_height )
{
*show_v_scrollbar = TRUE;
- *visible_width -= SCROLLBAR_SIZE;
+ *visible_width -= scrollbar_size;
}
*show_h_scrollbar = FALSE;
if( *visible_width < doc_width )
{
*show_h_scrollbar = TRUE;
- *visible_height -= SCROLLBAR_SIZE;
+ *visible_height -= scrollbar_size;
// Must retest now that visible_height has changed
if( !*show_v_scrollbar && (*visible_height < doc_height) )
{
*show_v_scrollbar = TRUE;
- *visible_width -= SCROLLBAR_SIZE;
+ *visible_width -= scrollbar_size;
}
}
}
+
-void LLScrollableContainerView::draw()
+void LLScrollContainer::draw()
{
+ static LLUICachedControl<S32> scrollbar_size ("UIScrollbarSize", 0);
if (mAutoScrolling)
{
// add acceleration to autoscroll
- mAutoScrollRate = llmin(mAutoScrollRate + (LLFrameTimer::getFrameDeltaTimeF32() * AUTO_SCROLL_RATE_ACCEL), MAX_AUTO_SCROLL_RATE);
+ mAutoScrollRate = llmin(mAutoScrollRate + (LLFrameTimer::getFrameDeltaTimeF32() * AUTO_SCROLL_RATE_ACCEL), mMaxAutoScrollRate);
}
else
{
- // reset to minimum
- mAutoScrollRate = MIN_AUTO_SCROLL_RATE;
+ // reset to minimum for next time
+ mAutoScrollRate = mMinAutoScrollRate;
}
- // clear this flag to be set on next call to handleDragAndDrop
+ // clear this flag to be set on next call to autoScroll
mAutoScrolling = FALSE;
// auto-focus when scrollbar active
// this allows us to capture user intent (i.e. stop automatically scrolling the view/etc)
- if (!gFocusMgr.childHasKeyboardFocus(this) &&
- (mScrollbar[VERTICAL]->hasMouseCapture() || mScrollbar[HORIZONTAL]->hasMouseCapture()))
+ if (!hasFocus()
+ && (mScrollbar[VERTICAL]->hasMouseCapture() || mScrollbar[HORIZONTAL]->hasMouseCapture()))
{
focusFirstItem();
}
@@ -427,7 +401,7 @@ void LLScrollableContainerView::draw()
if( mIsOpaque )
{
gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
- gGL.color4fv( mBackgroundColor.mV );
+ gGL.color4fv( mBackgroundColor.get().mV );
gl_rect_2d( mInnerRect );
}
@@ -445,12 +419,12 @@ void LLScrollableContainerView::draw()
S32 visible_height = 0;
BOOL show_v_scrollbar = FALSE;
BOOL show_h_scrollbar = FALSE;
- calcVisibleSize( mScrolledView->getRect(), &visible_width, &visible_height, &show_h_scrollbar, &show_v_scrollbar );
+ calcVisibleSize( &visible_width, &visible_height, &show_h_scrollbar, &show_v_scrollbar );
LLLocalClipRect clip(LLRect(mInnerRect.mLeft,
- mInnerRect.mBottom + (show_h_scrollbar ? SCROLLBAR_SIZE : 0) + visible_height,
+ mInnerRect.mBottom + (show_h_scrollbar ? scrollbar_size : 0) + visible_height,
visible_width,
- mInnerRect.mBottom + (show_h_scrollbar ? SCROLLBAR_SIZE : 0)
+ mInnerRect.mBottom + (show_h_scrollbar ? scrollbar_size : 0)
));
drawChild(mScrolledView);
}
@@ -487,10 +461,39 @@ void LLScrollableContainerView::draw()
drawDebugRect();
}
+ //// *HACK: also draw debug rectangles around currently-being-edited LLView, and any elements that are being highlighted by GUI preview code (see LLFloaterUIPreview)
+ //std::set<LLView*>::iterator iter = std::find(sPreviewHighlightedElements.begin(), sPreviewHighlightedElements.end(), this);
+ //if ((sEditingUI && this == sEditingUIView) || (iter != sPreviewHighlightedElements.end() && sDrawPreviewHighlights))
+ //{
+ // drawDebugRect();
+ //}
+
} // end draw
-void LLScrollableContainerView::updateScroll()
+bool LLScrollContainer::addChild(LLView* view, S32 tab_group)
{
+ if (!mScrolledView)
+ {
+ // Use the first panel or container as the scrollable view (bit of a hack)
+ mScrolledView = view;
+ }
+
+ bool ret_val = LLView::addChild(view, tab_group);
+
+ //bring the scrollbars to the front
+ sendChildToFront( mScrollbar[HORIZONTAL] );
+ sendChildToFront( mScrollbar[VERTICAL] );
+
+ return ret_val;
+}
+
+void LLScrollContainer::updateScroll()
+{
+ if (!mScrolledView)
+ {
+ return;
+ }
+ static LLUICachedControl<S32> scrollbar_size ("UIScrollbarSize", 0);
LLRect doc_rect = mScrolledView->getRect();
S32 doc_width = doc_rect.getWidth();
S32 doc_height = doc_rect.getHeight();
@@ -498,7 +501,7 @@ void LLScrollableContainerView::updateScroll()
S32 visible_height = 0;
BOOL show_v_scrollbar = FALSE;
BOOL show_h_scrollbar = FALSE;
- calcVisibleSize( doc_rect, &visible_width, &visible_height, &show_h_scrollbar, &show_v_scrollbar );
+ calcVisibleSize( &visible_width, &visible_height, &show_h_scrollbar, &show_v_scrollbar );
S32 border_width = mBorder->getBorderWidth();
if( show_v_scrollbar )
@@ -514,15 +517,15 @@ void LLScrollableContainerView::updateScroll()
S32 v_scrollbar_height = visible_height;
if( !show_h_scrollbar && mReserveScrollCorner )
{
- v_scrollbar_height -= SCROLLBAR_SIZE;
+ v_scrollbar_height -= scrollbar_size;
}
- mScrollbar[VERTICAL]->reshape( SCROLLBAR_SIZE, v_scrollbar_height, TRUE );
+ mScrollbar[VERTICAL]->reshape( scrollbar_size, v_scrollbar_height, TRUE );
// Make room for the horizontal scrollbar (or not)
S32 v_scrollbar_offset = 0;
if( show_h_scrollbar || mReserveScrollCorner )
{
- v_scrollbar_offset = SCROLLBAR_SIZE;
+ v_scrollbar_offset = scrollbar_size;
}
LLRect r = mScrollbar[VERTICAL]->getRect();
r.translate( 0, mInnerRect.mBottom - r.mBottom + v_scrollbar_offset );
@@ -552,9 +555,9 @@ void LLScrollableContainerView::updateScroll()
S32 h_scrollbar_width = visible_width;
if( !show_v_scrollbar && mReserveScrollCorner )
{
- h_scrollbar_width -= SCROLLBAR_SIZE;
+ h_scrollbar_width -= scrollbar_size;
}
- mScrollbar[HORIZONTAL]->reshape( h_scrollbar_width, SCROLLBAR_SIZE, TRUE );
+ mScrollbar[HORIZONTAL]->reshape( h_scrollbar_width, scrollbar_size, TRUE );
}
else
{
@@ -571,102 +574,108 @@ void LLScrollableContainerView::updateScroll()
mScrollbar[VERTICAL]->setPageSize( visible_height );
} // end updateScroll
-void LLScrollableContainerView::setBorderVisible(BOOL b)
+void LLScrollContainer::setBorderVisible(BOOL b)
{
mBorder->setVisible( b );
}
-// Scroll so that as much of rect as possible is showing (where rect is defined in the space of scroller view, not scrolled)
-void LLScrollableContainerView::scrollToShowRect(const LLRect& rect, const LLCoordGL& desired_offset)
+LLRect LLScrollContainer::getVisibleContentRect()
{
- if (!mScrolledView)
- {
- llwarns << "LLScrollableContainerView::scrollToShowRect with no view!" << llendl;
- return;
- }
+ updateScroll();
+ LLRect visible_rect = getContentWindowRect();
+ LLRect contents_rect = mScrolledView->getRect();
+ visible_rect.translate(-contents_rect.mLeft, -contents_rect.mBottom);
+ return visible_rect;
+}
+LLRect LLScrollContainer::getContentWindowRect() const
+{
+ LLRect scroller_view_rect;
S32 visible_width = 0;
S32 visible_height = 0;
- BOOL show_v_scrollbar = FALSE;
BOOL show_h_scrollbar = FALSE;
- const LLRect& scrolled_rect = mScrolledView->getRect();
- calcVisibleSize( scrolled_rect, &visible_width, &visible_height, &show_h_scrollbar, &show_v_scrollbar );
-
- // can't be so far left that right side of rect goes off screen, or so far right that left side does
- S32 horiz_offset = llclamp(desired_offset.mX, llmin(0, -visible_width + rect.getWidth()), 0);
- // can't be so high that bottom of rect goes off screen, or so low that top does
- S32 vert_offset = llclamp(desired_offset.mY, 0, llmax(0, visible_height - rect.getHeight()));
-
- // Vertical
- // 1. First make sure the top is visible
- // 2. Then, if possible without hiding the top, make the bottom visible.
- S32 vert_pos = mScrollbar[VERTICAL]->getDocPos();
-
- // find scrollbar position to get top of rect on screen (scrolling up)
- S32 top_offset = scrolled_rect.mTop - rect.mTop - vert_offset;
- // find scrollbar position to get bottom of rect on screen (scrolling down)
- S32 bottom_offset = vert_offset == 0 ? scrolled_rect.mTop - rect.mBottom - visible_height : top_offset;
- // scroll up far enough to see top or scroll down just enough if item is bigger than visual area
- if( vert_pos >= top_offset || visible_height < rect.getHeight())
- {
- vert_pos = top_offset;
- }
- // else scroll down far enough to see bottom
- else
- if( vert_pos <= bottom_offset )
+ BOOL show_v_scrollbar = FALSE;
+ calcVisibleSize( &visible_width, &visible_height, &show_h_scrollbar, &show_v_scrollbar );
+ S32 border_width = mBorder->getBorderWidth();
+ scroller_view_rect.setOriginAndSize(border_width,
+ show_h_scrollbar ? mScrollbar[HORIZONTAL]->getRect().mTop : border_width,
+ visible_width,
+ visible_height);
+ return scroller_view_rect;
+}
+
+// rect is in document coordinates, constraint is in display coordinates relative to content window rect
+void LLScrollContainer::scrollToShowRect(const LLRect& rect, const LLRect& constraint)
+{
+ if (!mScrolledView)
{
- vert_pos = bottom_offset;
+ llwarns << "LLScrollContainer::scrollToShowRect with no view!" << llendl;
+ return;
}
+ LLRect content_window_rect = getContentWindowRect();
+ // get document rect
+ LLRect scrolled_rect = mScrolledView->getRect();
+
+ // shrink target rect to fit within constraint region, biasing towards top left
+ LLRect rect_to_constrain = rect;
+ rect_to_constrain.mBottom = llmax(rect_to_constrain.mBottom, rect_to_constrain.mTop - constraint.getHeight());
+ rect_to_constrain.mRight = llmin(rect_to_constrain.mRight, rect_to_constrain.mLeft + constraint.getWidth());
+
+ // calculate allowable positions for scroller window in document coordinates
+ LLRect allowable_scroll_rect(rect_to_constrain.mRight - constraint.mRight,
+ rect_to_constrain.mBottom - constraint.mBottom,
+ rect_to_constrain.mLeft - constraint.mLeft,
+ rect_to_constrain.mTop - constraint.mTop);
+
+ // translate from allowable region for lower left corner to upper left corner
+ allowable_scroll_rect.translate(0, content_window_rect.getHeight());
+
+ S32 vert_pos = llclamp(mScrollbar[VERTICAL]->getDocPos(),
+ mScrollbar[VERTICAL]->getDocSize() - allowable_scroll_rect.mTop, // min vertical scroll
+ mScrollbar[VERTICAL]->getDocSize() - allowable_scroll_rect.mBottom); // max vertical scroll
+
mScrollbar[VERTICAL]->setDocSize( scrolled_rect.getHeight() );
- mScrollbar[VERTICAL]->setPageSize( visible_height );
+ mScrollbar[VERTICAL]->setPageSize( content_window_rect.getHeight() );
mScrollbar[VERTICAL]->setDocPos( vert_pos );
- // Horizontal
- // 1. First make sure left side is visible
- // 2. Then, if possible without hiding the left side, make the right side visible.
- S32 horiz_pos = mScrollbar[HORIZONTAL]->getDocPos();
- S32 left_offset = rect.mLeft - scrolled_rect.mLeft + horiz_offset;
- S32 right_offset = horiz_offset == 0 ? rect.mRight - scrolled_rect.mLeft - visible_width : left_offset;
+ S32 horizontal_pos = llclamp(mScrollbar[HORIZONTAL]->getDocPos(),
+ allowable_scroll_rect.mLeft,
+ allowable_scroll_rect.mRight);
- if( horiz_pos >= left_offset || visible_width < rect.getWidth() )
- {
- horiz_pos = left_offset;
- }
- else if( horiz_pos <= right_offset )
- {
- horiz_pos = right_offset;
- }
-
mScrollbar[HORIZONTAL]->setDocSize( scrolled_rect.getWidth() );
- mScrollbar[HORIZONTAL]->setPageSize( visible_width );
- mScrollbar[HORIZONTAL]->setDocPos( horiz_pos );
+ mScrollbar[HORIZONTAL]->setPageSize( content_window_rect.getWidth() );
+ mScrollbar[HORIZONTAL]->setDocPos( horizontal_pos );
// propagate scroll to document
updateScroll();
}
-void LLScrollableContainerView::pageUp(S32 overlap)
+void LLScrollContainer::pageUp(S32 overlap)
{
mScrollbar[VERTICAL]->pageUp(overlap);
+ updateScroll();
}
-void LLScrollableContainerView::pageDown(S32 overlap)
+void LLScrollContainer::pageDown(S32 overlap)
{
mScrollbar[VERTICAL]->pageDown(overlap);
+ updateScroll();
}
-void LLScrollableContainerView::goToTop()
+void LLScrollContainer::goToTop()
{
mScrollbar[VERTICAL]->setDocPos(0);
+ updateScroll();
}
-void LLScrollableContainerView::goToBottom()
+void LLScrollContainer::goToBottom()
{
mScrollbar[VERTICAL]->setDocPos(mScrollbar[VERTICAL]->getDocSize());
+ updateScroll();
}
-S32 LLScrollableContainerView::getBorderWidth() const
+S32 LLScrollContainer::getBorderWidth() const
{
if (mBorder)
{
@@ -676,73 +685,3 @@ S32 LLScrollableContainerView::getBorderWidth() const
return 0;
}
-// virtual
-LLXMLNodePtr LLScrollableContainerView::getXML(bool save_children) const
-{
- LLXMLNodePtr node = LLView::getXML();
-
- // Attributes
-
- node->createChild("opaque", TRUE)->setBoolValue(mIsOpaque);
-
- if (mIsOpaque)
- {
- node->createChild("color", TRUE)->setFloatValue(4, mBackgroundColor.mV);
- }
-
- // Contents
-
- LLXMLNodePtr child_node = mScrolledView->getXML();
-
- node->addChild(child_node);
-
- return node;
-}
-
-LLView* LLScrollableContainerView::fromXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFactory *factory)
-{
- std::string name("scroll_container");
- node->getAttributeString("name", name);
-
- LLRect rect;
- createRect(node, rect, parent, LLRect());
-
- BOOL opaque = FALSE;
- node->getAttributeBOOL("opaque", opaque);
-
- LLColor4 color(0,0,0,0);
- LLUICtrlFactory::getAttributeColor(node,"color", color);
-
- // Create the scroll view
- LLScrollableContainerView *ret = new LLScrollableContainerView(name, rect, (LLPanel*)NULL, opaque, color);
-
- LLPanel* panelp = NULL;
-
- // Find a child panel to add
- LLXMLNodePtr child;
- for (child = node->getFirstChild(); child.notNull(); child = child->getNextSibling())
- {
- LLView *control = factory->createCtrlWidget(panelp, child);
- if (control && control->isPanel())
- {
- if (panelp)
- {
- llinfos << "Warning! Attempting to put multiple panels into a scrollable container view!" << llendl;
- delete control;
- }
- else
- {
- panelp = (LLPanel*)control;
- }
- }
- }
-
- if (panelp == NULL)
- {
- panelp = new LLPanel(std::string("dummy"), LLRect::null, FALSE);
- }
-
- ret->mScrolledView = panelp;
-
- return ret;
-}
diff --git a/indra/llui/llscrollcontainer.h b/indra/llui/llscrollcontainer.h
index 70fc9087d7..8385bca02f 100644
--- a/indra/llui/llscrollcontainer.h
+++ b/indra/llui/llscrollcontainer.h
@@ -1,6 +1,6 @@
/**
* @file llscrollcontainer.h
- * @brief LLScrollableContainerView class header file.
+ * @brief LLScrollContainer class header file.
*
* $LicenseInfo:firstyear=2001&license=viewergpl$
*
@@ -53,40 +53,58 @@ class LLUICtrlFactory;
* the width and height of the view you're scrolling.
*
*****************************************************************************/
-class LLScrollableContainerView : public LLUICtrl
+
+struct ScrollContainerRegistry : public LLChildRegistry<ScrollContainerRegistry>
+{};
+
+class LLScrollContainer : public LLUICtrl
{
public:
// Note: vertical comes before horizontal because vertical
// scrollbars have priority for mouse and keyboard events.
enum SCROLL_ORIENTATION { VERTICAL, HORIZONTAL, SCROLLBAR_COUNT };
- LLScrollableContainerView( const std::string& name, const LLRect& rect,
- LLView* scrolled_view, BOOL is_opaque = FALSE,
- const LLColor4& bg_color = LLColor4(0,0,0,0) );
- LLScrollableContainerView( const std::string& name, const LLRect& rect,
- LLUICtrl* scrolled_ctrl, BOOL is_opaque = FALSE,
- const LLColor4& bg_color = LLColor4(0,0,0,0) );
- virtual ~LLScrollableContainerView( void );
-
- void setScrolledView(LLView* view) { mScrolledView = view; }
+ struct Params : public LLInitParam::Block<Params, LLUICtrl::Params>
+ {
+ Optional<bool> is_opaque,
+ reserve_scroll_corner,
+ border_visible;
+ Optional<F32> min_auto_scroll_rate,
+ max_auto_scroll_rate;
+ Optional<LLUIColor> bg_color;
+ Optional<LLScrollbar::callback_t> scroll_callback;
+
+ Params();
+ };
+
+ // my valid children are stored in this registry
+ typedef ScrollContainerRegistry child_registry_t;
+
+protected:
+ LLScrollContainer(const Params&);
+ friend class LLUICtrlFactory;
+public:
+ virtual ~LLScrollContainer( void );
- virtual void setValue(const LLSD& value) { mInnerRect.setValue(value); }
+ virtual void setValue(const LLSD& value) { mInnerRect.setValue(value); }
- void calcVisibleSize( S32 *visible_width, S32 *visible_height, BOOL* show_h_scrollbar, BOOL* show_v_scrollbar ) const;
- void calcVisibleSize( const LLRect& doc_rect, S32 *visible_width, S32 *visible_height, BOOL* show_h_scrollbar, BOOL* show_v_scrollbar ) const;
void setBorderVisible( BOOL b );
- void scrollToShowRect( const LLRect& rect, const LLCoordGL& desired_offset );
+ void scrollToShowRect( const LLRect& rect, const LLRect& constraint);
+ void scrollToShowRect( const LLRect& rect) { scrollToShowRect(rect, LLRect(0, mInnerRect.getHeight(), mInnerRect.getWidth(), 0)); }
+
void setReserveScrollCorner( BOOL b ) { mReserveScrollCorner = b; }
- const LLRect& getScrolledViewRect() const { return mScrolledView->getRect(); }
+ LLRect getVisibleContentRect();
+ LLRect getContentWindowRect() const;
+ const LLRect& getScrolledViewRect() const { return mScrolledView ? mScrolledView->getRect() : LLRect::null; }
void pageUp(S32 overlap = 0);
void pageDown(S32 overlap = 0);
void goToTop();
void goToBottom();
+ bool isAtTop() { return mScrollbar[VERTICAL]->isAtBeginning(); }
+ bool isAtBottom() { return mScrollbar[VERTICAL]->isAtEnd(); }
S32 getBorderWidth() const;
- BOOL needsToScroll(S32 x, S32 y, SCROLL_ORIENTATION axis) const;
-
// LLView functionality
virtual void reshape(S32 width, S32 height, BOOL called_from_parent = TRUE);
virtual BOOL handleKeyHere(KEY key, MASK mask);
@@ -97,30 +115,30 @@ public:
EAcceptance* accept,
std::string& tooltip_msg);
- virtual BOOL handleToolTip(S32 x, S32 y, std::string& msg, LLRect* sticky_rect);
virtual void draw();
-
- virtual LLXMLNodePtr getXML(bool save_children = true) const;
- static LLView* fromXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFactory *factory);
+ virtual bool addChild(LLView* view, S32 tab_group = 0);
+
+ bool autoScroll(S32 x, S32 y);
private:
- void init();
-
// internal scrollbar handlers
virtual void scrollHorizontal( S32 new_pos );
virtual void scrollVertical( S32 new_pos );
void updateScroll();
+ void calcVisibleSize( S32 *visible_width, S32 *visible_height, BOOL* show_h_scrollbar, BOOL* show_v_scrollbar ) const;
LLScrollbar* mScrollbar[SCROLLBAR_COUNT];
LLView* mScrolledView;
S32 mSize;
BOOL mIsOpaque;
- LLColor4 mBackgroundColor;
+ LLUIColor mBackgroundColor;
LLRect mInnerRect;
LLViewBorder* mBorder;
BOOL mReserveScrollCorner;
BOOL mAutoScrolling;
F32 mAutoScrollRate;
+ F32 mMinAutoScrollRate;
+ F32 mMaxAutoScrollRate;
};
diff --git a/indra/llui/llscrollingpanellist.cpp b/indra/llui/llscrollingpanellist.cpp
index 05d0c6f753..13fbe1d576 100644
--- a/indra/llui/llscrollingpanellist.cpp
+++ b/indra/llui/llscrollingpanellist.cpp
@@ -35,7 +35,7 @@
#include "llscrollingpanellist.h"
-static LLRegisterWidget<LLScrollingPanelList> r("scrolling_panel_list");
+static LLDefaultChildRegistry::Register<LLScrollingPanelList> r("scrolling_panel_list");
/////////////////////////////////////////////////////////////////////
@@ -52,9 +52,69 @@ void LLScrollingPanelList::clearPanels()
void LLScrollingPanelList::addPanel( LLScrollingPanel* panel )
{
- addChildAtEnd( panel );
+ addChildInBack( panel );
mPanelList.push_front( panel );
-
+
+ // Resize this view
+ S32 total_height = 0;
+ S32 max_width = 0;
+ S32 cur_gap = 0;
+ for (std::deque<LLScrollingPanel*>::iterator iter = mPanelList.begin();
+ iter != mPanelList.end(); ++iter)
+ {
+ LLScrollingPanel *childp = *iter;
+ total_height += childp->getRect().getHeight() + cur_gap;
+ max_width = llmax( max_width, childp->getRect().getWidth() );
+ cur_gap = GAP_BETWEEN_PANELS;
+ }
+ reshape( max_width, total_height, FALSE );
+
+ // Reposition each of the child views
+ S32 cur_y = total_height;
+ for (std::deque<LLScrollingPanel*>::iterator iter = mPanelList.begin();
+ iter != mPanelList.end(); ++iter)
+ {
+ LLScrollingPanel *childp = *iter;
+ cur_y -= childp->getRect().getHeight();
+ childp->translate( -childp->getRect().mLeft, cur_y - childp->getRect().mBottom);
+ cur_y -= GAP_BETWEEN_PANELS;
+ }
+}
+
+void LLScrollingPanelList::removePanel(LLScrollingPanel* panel)
+{
+ U32 index = 0;
+ LLScrollingPanelList::panel_list_t::const_iterator iter;
+
+ if (!mPanelList.empty())
+ {
+ for (iter = mPanelList.begin(); iter != mPanelList.end(); ++iter, ++index)
+ {
+ if (*iter == panel)
+ {
+ break;
+ }
+ }
+ if(iter != mPanelList.end())
+ {
+ removePanel(index);
+ }
+ }
+}
+
+void LLScrollingPanelList::removePanel( U32 panel_index )
+{
+ if ( mPanelList.empty() || panel_index >= mPanelList.size() )
+ {
+ llwarns << "Panel index " << panel_index << " is out of range!" << llendl;
+ return;
+ }
+ else
+ {
+ removeChild( mPanelList.at(panel_index) );
+ mPanelList.erase( mPanelList.begin() + panel_index );
+ }
+
const S32 GAP_BETWEEN_PANELS = 6;
// Resize this view
@@ -82,7 +142,7 @@ void LLScrollingPanelList::addPanel( LLScrollingPanel* panel )
cur_y -= GAP_BETWEEN_PANELS;
}
}
-
+
void LLScrollingPanelList::updatePanels(BOOL allow_modify)
{
for (std::deque<LLScrollingPanel*>::iterator iter = mPanelList.begin();
@@ -138,18 +198,3 @@ void LLScrollingPanelList::draw()
LLUICtrl::draw();
}
-
-// static
-LLView* LLScrollingPanelList::fromXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFactory *factory)
-{
- std::string name("scrolling_panel_list");
- node->getAttributeString("name", name);
-
- LLRect rect;
- createRect(node, rect, parent, LLRect());
-
- LLScrollingPanelList* scrolling_panel_list = new LLScrollingPanelList(name, rect);
- scrolling_panel_list->initFromXML(node, parent);
- return scrolling_panel_list;
-}
-
diff --git a/indra/llui/llscrollingpanellist.h b/indra/llui/llscrollingpanellist.h
index b9d730978f..9da15822d0 100644
--- a/indra/llui/llscrollingpanellist.h
+++ b/indra/llui/llscrollingpanellist.h
@@ -29,6 +29,9 @@
* $/LicenseInfo$
*/
+#ifndef LL_LLSCROLLINGPANELLIST_H
+#define LL_LLSCROLLINGPANELLIST_H
+
#include <vector>
#include "llui.h"
@@ -42,7 +45,7 @@
class LLScrollingPanel : public LLPanel
{
public:
- LLScrollingPanel(const std::string& name, const LLRect& rect) : LLPanel(name, rect) { }
+ LLScrollingPanel(const LLPanel::Params& params) : LLPanel(params) {}
virtual void updatePanel(BOOL allow_modify) = 0;
};
@@ -53,23 +56,37 @@ public:
class LLScrollingPanelList : public LLUICtrl
{
public:
- LLScrollingPanelList(const std::string& name, const LLRect& rect)
- : LLUICtrl(name, rect, TRUE, NULL, NULL, FOLLOWS_LEFT | FOLLOWS_BOTTOM ) {}
+ struct Params : public LLInitParam::Block<Params, LLUICtrl::Params>
+ {
+ Params()
+ {
+ name = "scrolling_panel_list";
+ follows.flags = FOLLOWS_LEFT | FOLLOWS_BOTTOM;
+ }
+ };
+ LLScrollingPanelList(const Params& p)
+ : LLUICtrl(p)
+ {}
+
+ static const S32 GAP_BETWEEN_PANELS = 6;
+
+ typedef std::deque<LLScrollingPanel*> panel_list_t;
virtual void setValue(const LLSD& value) {};
- virtual LLXMLNodePtr getXML(bool save_children) const { return LLUICtrl::getXML(); }
-
virtual void draw();
void clearPanels();
void addPanel( LLScrollingPanel* panel );
+ void removePanel( LLScrollingPanel* panel );
+ void removePanel( U32 panel_index );
void updatePanels(BOOL allow_modify);
+ const panel_list_t& getPanelList() { return mPanelList; }
- static LLView* fromXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFactory *factory);
-
private:
void updatePanelVisiblilty();
- std::deque<LLScrollingPanel*> mPanelList;
+ panel_list_t mPanelList;
};
+
+#endif //LL_LLSCROLLINGPANELLIST_H
diff --git a/indra/llui/llscrolllistcell.cpp b/indra/llui/llscrolllistcell.cpp
new file mode 100644
index 0000000000..e28da91305
--- /dev/null
+++ b/indra/llui/llscrolllistcell.cpp
@@ -0,0 +1,418 @@
+/**
+ * @file llscrolllistcell.cpp
+ * @brief Scroll lists are composed of rows (items), each of which
+ * contains columns (cells).
+ *
+ * $LicenseInfo:firstyear=2007&license=viewergpl$
+ *
+ * Copyright (c) 2007-2009, Linden Research, Inc.
+ *
+ * Second Life Viewer Source Code
+ * The source code in this file ("Source Code") is provided by Linden Lab
+ * to you under the terms of the GNU General Public License, version 2.0
+ * ("GPL"), unless you have obtained a separate licensing agreement
+ * ("Other License"), formally executed by you and Linden Lab. Terms of
+ * the GPL can be found in doc/GPL-license.txt in this distribution, or
+ * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
+ *
+ * There are special exceptions to the terms and conditions of the GPL as
+ * it is applied to this Source Code. View the full text of the exception
+ * in the file doc/FLOSS-exception.txt in this software distribution, or
+ * online at
+ * http://secondlifegrid.net/programs/open_source/licensing/flossexception
+ *
+ * By copying, modifying or distributing this software, you acknowledge
+ * that you have read and understood your obligations described above,
+ * and agree to abide by those obligations.
+ *
+ * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+ * COMPLETENESS OR PERFORMANCE.
+ * $/LicenseInfo$
+ */
+
+#include "linden_common.h"
+
+#include "llscrolllistcell.h"
+
+#include "llcheckboxctrl.h"
+#include "llui.h" // LLUIImage
+#include "lluictrlfactory.h"
+
+//static
+LLScrollListCell* LLScrollListCell::create(const LLScrollListCell::Params& cell_p)
+{
+ LLScrollListCell* cell = NULL;
+
+ if (cell_p.type() == "icon")
+ {
+ cell = new LLScrollListIcon(cell_p);
+ }
+ else if (cell_p.type() == "checkbox")
+ {
+ cell = new LLScrollListCheck(cell_p);
+ }
+ else if (cell_p.type() == "date")
+ {
+ cell = new LLScrollListDate(cell_p);
+ }
+ else // default is "text"
+ {
+ cell = new LLScrollListText(cell_p);
+ }
+
+ if (cell_p.value.isProvided())
+ {
+ cell->setValue(cell_p.value);
+ }
+
+ return cell;
+}
+
+
+LLScrollListCell::LLScrollListCell(const LLScrollListCell::Params& p)
+: mWidth(p.width)
+{}
+
+// virtual
+const LLSD LLScrollListCell::getValue() const
+{
+ return LLStringUtil::null;
+}
+
+//
+// LLScrollListIcon
+//
+LLScrollListIcon::LLScrollListIcon(const LLScrollListCell::Params& p)
+: LLScrollListCell(p),
+ mIcon(LLUI::getUIImage(p.value().asString())),
+ mColor(p.color),
+ mAlignment(p.font_halign)
+{}
+
+LLScrollListIcon::~LLScrollListIcon()
+{
+}
+
+/*virtual*/
+S32 LLScrollListIcon::getHeight() const
+{ return mIcon ? mIcon->getHeight() : 0; }
+
+/*virtual*/
+const LLSD LLScrollListIcon::getValue() const
+{ return mIcon.isNull() ? LLStringUtil::null : mIcon->getName(); }
+
+void LLScrollListIcon::setValue(const LLSD& value)
+{
+ if (value.isUUID())
+ {
+ // don't use default image specified by LLUUID::null, use no image in that case
+ LLUUID image_id = value.asUUID();
+ mIcon = image_id.notNull() ? LLUI::getUIImageByID(image_id) : LLUIImagePtr(NULL);
+ }
+ else
+ {
+ std::string value_string = value.asString();
+ if (LLUUID::validate(value_string))
+ {
+ setValue(LLUUID(value_string));
+ }
+ else if (!value_string.empty())
+ {
+ mIcon = LLUI::getUIImage(value.asString());
+ }
+ else
+ {
+ mIcon = NULL;
+ }
+ }
+}
+
+
+void LLScrollListIcon::setColor(const LLColor4& color)
+{
+ mColor = color;
+}
+
+S32 LLScrollListIcon::getWidth() const
+{
+ // if no specified fix width, use width of icon
+ if (LLScrollListCell::getWidth() == 0 && mIcon.notNull())
+ {
+ return mIcon->getWidth();
+ }
+ return LLScrollListCell::getWidth();
+}
+
+
+void LLScrollListIcon::draw(const LLColor4& color, const LLColor4& highlight_color) const
+{
+ if (mIcon)
+ {
+ switch(mAlignment)
+ {
+ case LLFontGL::LEFT:
+ mIcon->draw(0, 0, mColor);
+ break;
+ case LLFontGL::RIGHT:
+ mIcon->draw(getWidth() - mIcon->getWidth(), 0, mColor);
+ break;
+ case LLFontGL::HCENTER:
+ mIcon->draw((getWidth() - mIcon->getWidth()) / 2, 0, mColor);
+ break;
+ default:
+ break;
+ }
+ }
+}
+
+//
+// LLScrollListText
+//
+U32 LLScrollListText::sCount = 0;
+
+LLScrollListText::LLScrollListText(const LLScrollListCell::Params& p)
+: LLScrollListCell(p),
+ mText(p.value().asString()),
+ mFont(p.font),
+ mColor(p.color),
+ mUseColor(p.color.isProvided()),
+ mFontAlignment(p.font_halign),
+ mVisible(p.visible),
+ mHighlightCount( 0 ),
+ mHighlightOffset( 0 )
+{
+ sCount++;
+
+ // initialize rounded rect image
+ if (!mRoundedRectImage)
+ {
+ mRoundedRectImage = LLUI::getUIImage("rounded_square.tga");
+ }
+}
+
+//virtual
+void LLScrollListText::highlightText(S32 offset, S32 num_chars)
+{
+ mHighlightOffset = offset;
+ mHighlightCount = num_chars;
+}
+
+//virtual
+BOOL LLScrollListText::isText() const
+{
+ return TRUE;
+}
+
+//virtual
+BOOL LLScrollListText::getVisible() const
+{
+ return mVisible;
+}
+
+//virtual
+S32 LLScrollListText::getHeight() const
+{
+ return llround(mFont->getLineHeight());
+}
+
+
+LLScrollListText::~LLScrollListText()
+{
+ sCount--;
+}
+
+S32 LLScrollListText::getContentWidth() const
+{
+ return mFont->getWidth(mText.getString());
+}
+
+
+void LLScrollListText::setColor(const LLColor4& color)
+{
+ mColor = color;
+ mUseColor = TRUE;
+}
+
+void LLScrollListText::setText(const LLStringExplicit& text)
+{
+ mText = text;
+}
+
+void LLScrollListText::setFontStyle(const U8 font_style)
+{
+ LLFontDescriptor new_desc(mFont->getFontDesc());
+ new_desc.setStyle(font_style);
+ mFont = LLFontGL::getFont(new_desc);
+}
+
+//virtual
+void LLScrollListText::setValue(const LLSD& text)
+{
+ setText(text.asString());
+}
+
+//virtual
+const LLSD LLScrollListText::getValue() const
+{
+ return LLSD(mText.getString());
+}
+
+
+void LLScrollListText::draw(const LLColor4& color, const LLColor4& highlight_color) const
+{
+ LLColor4 display_color;
+ if (mUseColor)
+ {
+ display_color = mColor;
+ }
+ else
+ {
+ display_color = color;
+ }
+
+ if (mHighlightCount > 0)
+ {
+ S32 left = 0;
+ switch(mFontAlignment)
+ {
+ case LLFontGL::LEFT:
+ left = mFont->getWidth(mText.getString(), 0, mHighlightOffset);
+ break;
+ case LLFontGL::RIGHT:
+ left = getWidth() - mFont->getWidth(mText.getString(), mHighlightOffset, S32_MAX);
+ break;
+ case LLFontGL::HCENTER:
+ left = (getWidth() - mFont->getWidth(mText.getString())) / 2;
+ break;
+ }
+ LLRect highlight_rect(left - 2,
+ llround(mFont->getLineHeight()) + 1,
+ left + mFont->getWidth(mText.getString(), mHighlightOffset, mHighlightCount) + 1,
+ 1);
+ mRoundedRectImage->draw(highlight_rect, highlight_color);
+ }
+
+ // Try to draw the entire string
+ F32 right_x;
+ U32 string_chars = mText.length();
+ F32 start_x = 0.f;
+ switch(mFontAlignment)
+ {
+ case LLFontGL::LEFT:
+ start_x = 0.f;
+ break;
+ case LLFontGL::RIGHT:
+ start_x = (F32)getWidth();
+ break;
+ case LLFontGL::HCENTER:
+ start_x = (F32)getWidth() * 0.5f;
+ break;
+ }
+ mFont->render(mText.getWString(), 0,
+ start_x, 2.f,
+ display_color,
+ mFontAlignment,
+ LLFontGL::BOTTOM,
+ 0,
+ LLFontGL::NO_SHADOW,
+ string_chars,
+ getWidth(),
+ &right_x,
+ TRUE);
+}
+
+//
+// LLScrollListCheck
+//
+LLScrollListCheck::LLScrollListCheck(const LLScrollListCell::Params& p)
+: LLScrollListCell(p)
+{
+ LLCheckBoxCtrl::Params checkbox_p;
+ checkbox_p.name("checkbox");
+ checkbox_p.rect.left(0).bottom(0).width(p.width).height(p.width);
+ checkbox_p.enabled(p.enabled);
+ checkbox_p.initial_value(p.value());
+
+ mCheckBox = LLUICtrlFactory::create<LLCheckBoxCtrl>(checkbox_p);
+
+ LLRect rect(mCheckBox->getRect());
+ if (p.width)
+ {
+ rect.mRight = rect.mLeft + p.width;
+ mCheckBox->setRect(rect);
+ setWidth(p.width);
+ }
+ else
+ {
+ setWidth(rect.getWidth()); //check_box->getWidth();
+ }
+
+ mCheckBox->setColor(p.color);
+}
+
+
+LLScrollListCheck::~LLScrollListCheck()
+{
+ delete mCheckBox;
+ mCheckBox = NULL;
+}
+
+void LLScrollListCheck::draw(const LLColor4& color, const LLColor4& highlight_color) const
+{
+ mCheckBox->draw();
+}
+
+BOOL LLScrollListCheck::handleClick()
+{
+ if (mCheckBox->getEnabled())
+ {
+ mCheckBox->toggle();
+ }
+ // don't change selection when clicking on embedded checkbox
+ return TRUE;
+}
+
+/*virtual*/
+const LLSD LLScrollListCheck::getValue() const
+{
+ return mCheckBox->getValue();
+}
+
+/*virtual*/
+void LLScrollListCheck::setValue(const LLSD& value)
+{
+ mCheckBox->setValue(value);
+}
+
+/*virtual*/
+void LLScrollListCheck::onCommit()
+{
+ mCheckBox->onCommit();
+}
+
+/*virtual*/
+void LLScrollListCheck::setEnabled(BOOL enable)
+{
+ mCheckBox->setEnabled(enable);
+}
+
+//
+// LLScrollListDate
+//
+
+LLScrollListDate::LLScrollListDate( const LLScrollListCell::Params& p)
+: LLScrollListText(p),
+ mDate(p.value().asDate())
+{}
+
+void LLScrollListDate::setValue(const LLSD& value)
+{
+ mDate = value.asDate();
+ LLScrollListText::setValue(mDate.asRFC1123());
+}
+
+const LLSD LLScrollListDate::getValue() const
+{
+ return mDate;
+}
diff --git a/indra/llui/llscrolllistcell.h b/indra/llui/llscrolllistcell.h
new file mode 100644
index 0000000000..9d3fa65f64
--- /dev/null
+++ b/indra/llui/llscrolllistcell.h
@@ -0,0 +1,222 @@
+/**
+ * @file llscrolllistcell.h
+ * @brief Scroll lists are composed of rows (items), each of which
+ * contains columns (cells).
+ *
+ * $LicenseInfo:firstyear=2007&license=viewergpl$
+ *
+ * Copyright (c) 2007-2009, Linden Research, Inc.
+ *
+ * Second Life Viewer Source Code
+ * The source code in this file ("Source Code") is provided by Linden Lab
+ * to you under the terms of the GNU General Public License, version 2.0
+ * ("GPL"), unless you have obtained a separate licensing agreement
+ * ("Other License"), formally executed by you and Linden Lab. Terms of
+ * the GPL can be found in doc/GPL-license.txt in this distribution, or
+ * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
+ *
+ * There are special exceptions to the terms and conditions of the GPL as
+ * it is applied to this Source Code. View the full text of the exception
+ * in the file doc/FLOSS-exception.txt in this software distribution, or
+ * online at
+ * http://secondlifegrid.net/programs/open_source/licensing/flossexception
+ *
+ * By copying, modifying or distributing this software, you acknowledge
+ * that you have read and understood your obligations described above,
+ * and agree to abide by those obligations.
+ *
+ * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+ * COMPLETENESS OR PERFORMANCE.
+ * $/LicenseInfo$
+ */
+
+#ifndef LLSCROLLLISTCELL_H
+#define LLSCROLLLISTCELL_H
+
+#include "llfontgl.h" // HAlign
+#include "llpointer.h" // LLPointer<>
+#include "lluistring.h"
+#include "v4color.h"
+#include "llui.h"
+
+class LLCheckBoxCtrl;
+class LLSD;
+class LLUIImage;
+
+/*
+ * Represents a cell in a scrollable table.
+ *
+ * Sub-classes must return height and other properties
+ * though width accessors are implemented by the base class.
+ * It is therefore important for sub-class constructors to call
+ * setWidth() with realistic values.
+ */
+class LLScrollListCell
+{
+public:
+ struct Params : public LLInitParam::Block<Params>
+ {
+ Optional<std::string> type,
+ column;
+
+ Optional<S32> width;
+ Optional<bool> enabled,
+ visible;
+
+ Optional<void*> userdata;
+ Optional<LLSD> value;
+
+ Optional<const LLFontGL*> font;
+ Optional<LLColor4> font_color;
+ Optional<LLFontGL::HAlign> font_halign;
+
+ Optional<LLColor4> color;
+
+ Params()
+ : type("type", "text"),
+ column("column"),
+ width("width"),
+ enabled("enabled", true),
+ visible("visible", true),
+ value("value"),
+ font("font", LLFontGL::getFontSansSerifSmall()),
+ font_color("font_color", LLColor4::black),
+ color("color", LLColor4::white),
+ font_halign("halign", LLFontGL::LEFT)
+ {
+ addSynonym(column, "name");
+ addSynonym(font_color, "font-color");
+ }
+ };
+
+ static LLScrollListCell* create(const Params&);
+
+ LLScrollListCell(const LLScrollListCell::Params&);
+ virtual ~LLScrollListCell() {};
+ virtual void draw(const LLColor4& color, const LLColor4& highlight_color) const = 0; // truncate to given width, if possible
+ virtual S32 getWidth() const {return mWidth;}
+ virtual S32 getContentWidth() const { return 0; }
+ virtual S32 getHeight() const = 0;
+ virtual const LLSD getValue() const;
+ virtual void setValue(const LLSD& value) { }
+ virtual BOOL getVisible() const { return TRUE; }
+ virtual void setWidth(S32 width) { mWidth = width; }
+ virtual void highlightText(S32 offset, S32 num_chars) {}
+ virtual BOOL isText() const = 0;
+ virtual void setColor(const LLColor4&) {}
+ virtual void onCommit() {};
+
+ virtual BOOL handleClick() { return FALSE; }
+ virtual void setEnabled(BOOL enable) { }
+
+private:
+ S32 mWidth;
+};
+
+class LLScrollListSpacer : public LLScrollListCell
+{
+public:
+ LLScrollListSpacer(const LLScrollListCell::Params& p) : LLScrollListCell(p) {}
+ /*virtual*/ ~LLScrollListSpacer() {};
+ /*virtual*/ void draw(const LLColor4& color, const LLColor4& highlight_color) const {}
+ /*virtual*/ S32 getHeight() const { return 0; }
+ /*virtual*/ BOOL isText() const { return FALSE; }
+};
+
+/*
+ * Cell displaying a text label.
+ */
+class LLScrollListText : public LLScrollListCell
+{
+public:
+ LLScrollListText(const LLScrollListCell::Params&);
+ /*virtual*/ ~LLScrollListText();
+
+ /*virtual*/ void draw(const LLColor4& color, const LLColor4& highlight_color) const;
+ /*virtual*/ S32 getContentWidth() const;
+ /*virtual*/ S32 getHeight() const;
+ /*virtual*/ void setValue(const LLSD& value);
+ /*virtual*/ const LLSD getValue() const;
+ /*virtual*/ BOOL getVisible() const;
+ /*virtual*/ void highlightText(S32 offset, S32 num_chars);
+
+ /*virtual*/ void setColor(const LLColor4&);
+ /*virtual*/ BOOL isText() const;
+
+ void setText(const LLStringExplicit& text);
+ void setFontStyle(const U8 font_style);
+
+private:
+ LLUIString mText;
+ const LLFontGL* mFont;
+ LLColor4 mColor;
+ U8 mUseColor;
+ LLFontGL::HAlign mFontAlignment;
+ BOOL mVisible;
+ S32 mHighlightCount;
+ S32 mHighlightOffset;
+
+ LLPointer<LLUIImage> mRoundedRectImage;
+
+ static U32 sCount;
+};
+
+/*
+ * Cell displaying an image.
+ */
+class LLScrollListIcon : public LLScrollListCell
+{
+public:
+ LLScrollListIcon(const LLScrollListCell::Params& p);
+ /*virtual*/ ~LLScrollListIcon();
+ /*virtual*/ void draw(const LLColor4& color, const LLColor4& highlight_color) const;
+ /*virtual*/ S32 getWidth() const;
+ /*virtual*/ S32 getHeight() const;
+ /*virtual*/ const LLSD getValue() const;
+ /*virtual*/ void setColor(const LLColor4&);
+ /*virtual*/ BOOL isText()const { return FALSE; }
+ /*virtual*/ void setValue(const LLSD& value);
+
+private:
+ LLPointer<LLUIImage> mIcon;
+ LLColor4 mColor;
+ LLFontGL::HAlign mAlignment;
+};
+
+/*
+ * An interactive cell containing a check box.
+ */
+class LLScrollListCheck : public LLScrollListCell
+{
+public:
+ LLScrollListCheck( const LLScrollListCell::Params&);
+ /*virtual*/ ~LLScrollListCheck();
+ /*virtual*/ void draw(const LLColor4& color, const LLColor4& highlight_color) const;
+ /*virtual*/ S32 getHeight() const { return 0; }
+ /*virtual*/ const LLSD getValue() const;
+ /*virtual*/ void setValue(const LLSD& value);
+ /*virtual*/ void onCommit();
+
+ /*virtual*/ BOOL handleClick();
+ /*virtual*/ void setEnabled(BOOL enable);
+
+ LLCheckBoxCtrl* getCheckBox() { return mCheckBox; }
+ /*virtual*/ BOOL isText() const { return FALSE; }
+
+private:
+ LLCheckBoxCtrl* mCheckBox;
+};
+
+class LLScrollListDate : public LLScrollListText
+{
+public:
+ LLScrollListDate( const LLScrollListCell::Params& p );
+ virtual void setValue(const LLSD& value);
+ virtual const LLSD getValue() const;
+
+private:
+ LLDate mDate;
+};
+
+#endif
diff --git a/indra/llui/llscrolllistcolumn.cpp b/indra/llui/llscrolllistcolumn.cpp
new file mode 100644
index 0000000000..073e14386f
--- /dev/null
+++ b/indra/llui/llscrolllistcolumn.cpp
@@ -0,0 +1,328 @@
+/**
+ * @file llscrollcolumnheader.cpp
+ * @brief Scroll lists are composed of rows (items), each of which
+ * contains columns (cells).
+ *
+ * $LicenseInfo:firstyear=2007&license=viewergpl$
+ *
+ * Copyright (c) 2007-2009, Linden Research, Inc.
+ *
+ * Second Life Viewer Source Code
+ * The source code in this file ("Source Code") is provided by Linden Lab
+ * to you under the terms of the GNU General Public License, version 2.0
+ * ("GPL"), unless you have obtained a separate licensing agreement
+ * ("Other License"), formally executed by you and Linden Lab. Terms of
+ * the GPL can be found in doc/GPL-license.txt in this distribution, or
+ * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
+ *
+ * There are special exceptions to the terms and conditions of the GPL as
+ * it is applied to this Source Code. View the full text of the exception
+ * in the file doc/FLOSS-exception.txt in this software distribution, or
+ * online at
+ * http://secondlifegrid.net/programs/open_source/licensing/flossexception
+ *
+ * By copying, modifying or distributing this software, you acknowledge
+ * that you have read and understood your obligations described above,
+ * and agree to abide by those obligations.
+ *
+ * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+ * COMPLETENESS OR PERFORMANCE.
+ * $/LicenseInfo$
+ */
+
+#include "linden_common.h"
+
+#include "llscrolllistcolumn.h"
+
+#include "llbutton.h"
+#include "llresizebar.h"
+#include "llscrolllistcell.h"
+#include "llscrolllistctrl.h"
+#include "llscrolllistitem.h"
+#include "lluictrlfactory.h"
+
+const S32 MIN_COLUMN_WIDTH = 20;
+
+//---------------------------------------------------------------------------
+// LLScrollColumnHeader
+//---------------------------------------------------------------------------
+
+LLScrollColumnHeader::LLScrollColumnHeader(const LLScrollColumnHeader::Params& p)
+: LLButton(p), // use combobox params to steal images
+ mColumn(p.column),
+ mHasResizableElement(FALSE)
+{
+ setClickedCallback(boost::bind(&LLScrollColumnHeader::onClick, this, _2));
+
+ // resize handles on left and right
+ const S32 RESIZE_BAR_THICKNESS = 3;
+ LLResizeBar::Params resize_bar_p;
+ resize_bar_p.resizing_view(this);
+ resize_bar_p.rect(LLRect(getRect().getWidth() - RESIZE_BAR_THICKNESS, getRect().getHeight(), getRect().getWidth(), 0));
+ resize_bar_p.min_size(MIN_COLUMN_WIDTH);
+ resize_bar_p.side(LLResizeBar::RIGHT);
+ resize_bar_p.enabled(false);
+ mResizeBar = LLUICtrlFactory::create<LLResizeBar>(resize_bar_p);
+ addChild(mResizeBar);
+}
+
+LLScrollColumnHeader::~LLScrollColumnHeader()
+{}
+
+void LLScrollColumnHeader::draw()
+{
+ std::string sort_column = mColumn->mParentCtrl->getSortColumnName();
+ BOOL draw_arrow = !mColumn->mLabel.empty()
+ && mColumn->mParentCtrl->isSorted()
+ // check for indirect sorting column as well as column's sorting name
+ && (sort_column == mColumn->mSortingColumn || sort_column == mColumn->mName);
+
+ BOOL is_ascending = mColumn->mParentCtrl->getSortAscending();
+ setImageOverlay(is_ascending ? "up_arrow.tga" : "down_arrow.tga", LLFontGL::RIGHT, draw_arrow ? LLColor4::white : LLColor4::transparent);
+
+ // Draw children
+ LLButton::draw();
+}
+
+BOOL LLScrollColumnHeader::handleDoubleClick(S32 x, S32 y, MASK mask)
+{
+ if (canResize() && mResizeBar->getRect().pointInRect(x, y))
+ {
+ // reshape column to max content width
+ LLRect column_rect = getRect();
+ column_rect.mRight = column_rect.mLeft + mColumn->mMaxContentWidth;
+ setShape(column_rect, true);
+ }
+ else
+ {
+ onClick(LLSD());
+ }
+ return TRUE;
+}
+
+void LLScrollColumnHeader::onClick(const LLSD& data)
+{
+ if (mColumn)
+ {
+ LLScrollListCtrl::onClickColumn(mColumn);
+ }
+}
+
+LLView* LLScrollColumnHeader::findSnapEdge(S32& new_edge_val, const LLCoordGL& mouse_dir, ESnapEdge snap_edge, ESnapType snap_type, S32 threshold, S32 padding)
+{
+ // this logic assumes dragging on right
+ llassert(snap_edge == SNAP_RIGHT);
+
+ // use higher snap threshold for column headers
+ threshold = llmin(threshold, 10);
+
+ LLRect snap_rect = getSnapRect();
+
+ S32 snap_delta = mColumn->mMaxContentWidth - snap_rect.getWidth();
+
+ // x coord growing means column growing, so same signs mean we're going in right direction
+ if (llabs(snap_delta) <= threshold && mouse_dir.mX * snap_delta > 0 )
+ {
+ new_edge_val = snap_rect.mRight + snap_delta;
+ }
+ else
+ {
+ LLScrollListColumn* next_column = mColumn->mParentCtrl->getColumn(mColumn->mIndex + 1);
+ while (next_column)
+ {
+ if (next_column->mHeader)
+ {
+ snap_delta = (next_column->mHeader->getSnapRect().mRight - next_column->mMaxContentWidth) - snap_rect.mRight;
+ if (llabs(snap_delta) <= threshold && mouse_dir.mX * snap_delta > 0 )
+ {
+ new_edge_val = snap_rect.mRight + snap_delta;
+ }
+ break;
+ }
+ next_column = mColumn->mParentCtrl->getColumn(next_column->mIndex + 1);
+ }
+ }
+
+ return this;
+}
+
+void LLScrollColumnHeader::handleReshape(const LLRect& new_rect, bool by_user)
+{
+ S32 new_width = new_rect.getWidth();
+ S32 delta_width = new_width - (getRect().getWidth() /*+ mColumn->mParentCtrl->getColumnPadding()*/);
+
+ if (delta_width != 0)
+ {
+ S32 remaining_width = -delta_width;
+ S32 col;
+ for (col = mColumn->mIndex + 1; col < mColumn->mParentCtrl->getNumColumns(); col++)
+ {
+ LLScrollListColumn* columnp = mColumn->mParentCtrl->getColumn(col);
+ if (!columnp) continue;
+
+ if (columnp->mHeader && columnp->mHeader->canResize())
+ {
+ // how many pixels in width can this column afford to give up?
+ S32 resize_buffer_amt = llmax(0, columnp->getWidth() - MIN_COLUMN_WIDTH);
+
+ // user shrinking column, need to add width to other columns
+ if (delta_width < 0)
+ {
+ if (columnp->getWidth() > 0)
+ {
+ // statically sized column, give all remaining width to this column
+ columnp->setWidth(columnp->getWidth() + remaining_width);
+ if (columnp->mRelWidth > 0.f)
+ {
+ columnp->mRelWidth = (F32)columnp->getWidth() / (F32)mColumn->mParentCtrl->getItemListRect().getWidth();
+ }
+ // all padding went to this widget, we're done
+ break;
+ }
+ }
+ else
+ {
+ // user growing column, need to take width from other columns
+ remaining_width += resize_buffer_amt;
+
+ if (columnp->getWidth() > 0)
+ {
+ columnp->setWidth(columnp->getWidth() - llmin(columnp->getWidth() - MIN_COLUMN_WIDTH, delta_width));
+ if (columnp->mRelWidth > 0.f)
+ {
+ columnp->mRelWidth = (F32)columnp->getWidth() / (F32)mColumn->mParentCtrl->getItemListRect().getWidth();
+ }
+ }
+
+ if (remaining_width >= 0)
+ {
+ // width sucked up from neighboring columns, done
+ break;
+ }
+ }
+ }
+ }
+
+ // clamp resize amount to maximum that can be absorbed by other columns
+ if (delta_width > 0)
+ {
+ delta_width += llmin(remaining_width, 0);
+ }
+
+ // propagate constrained delta_width to new width for this column
+ new_width = getRect().getWidth() + delta_width - mColumn->mParentCtrl->getColumnPadding();
+
+ // use requested width
+ mColumn->setWidth(new_width);
+
+ // update proportional spacing
+ if (mColumn->mRelWidth > 0.f)
+ {
+ mColumn->mRelWidth = (F32)new_width / (F32)mColumn->mParentCtrl->getItemListRect().getWidth();
+ }
+
+ // tell scroll list to layout columns again
+ // do immediate update to get proper feedback to resize handle
+ // which needs to know how far the resize actually went
+ mColumn->mParentCtrl->updateColumns();
+ }
+}
+
+void LLScrollColumnHeader::setHasResizableElement(BOOL resizable)
+{
+ if (mHasResizableElement != resizable)
+ {
+ mColumn->mParentCtrl->dirtyColumns();
+ mHasResizableElement = resizable;
+ }
+}
+
+void LLScrollColumnHeader::updateResizeBars()
+{
+ S32 num_resizable_columns = 0;
+ S32 col;
+ for (col = 0; col < mColumn->mParentCtrl->getNumColumns(); col++)
+ {
+ LLScrollListColumn* columnp = mColumn->mParentCtrl->getColumn(col);
+ if (columnp->mHeader && columnp->mHeader->canResize())
+ {
+ num_resizable_columns++;
+ }
+ }
+
+ S32 num_resizers_enabled = 0;
+
+ // now enable/disable resize handles on resizable columns if we have at least two
+ for (col = 0; col < mColumn->mParentCtrl->getNumColumns(); col++)
+ {
+ LLScrollListColumn* columnp = mColumn->mParentCtrl->getColumn(col);
+ if (!columnp->mHeader) continue;
+ BOOL enable = num_resizable_columns >= 2 && num_resizers_enabled < (num_resizable_columns - 1) && columnp->mHeader->canResize();
+ columnp->mHeader->enableResizeBar(enable);
+ if (enable)
+ {
+ num_resizers_enabled++;
+ }
+ }
+}
+
+void LLScrollColumnHeader::enableResizeBar(BOOL enable)
+{
+ mResizeBar->setEnabled(enable);
+}
+
+BOOL LLScrollColumnHeader::canResize()
+{
+ return getVisible() && (mHasResizableElement || mColumn->mDynamicWidth);
+}
+
+void LLScrollListColumn::SortNames::declareValues()
+{
+ declare("ascending", LLScrollListColumn::ASCENDING);
+ declare("descending", LLScrollListColumn::DESCENDING);
+}
+
+//
+// LLScrollListColumn
+//
+//static
+const LLScrollListColumn::Params& LLScrollListColumn::getDefaultParams()
+{
+ return LLUICtrlFactory::getDefaultParams<LLScrollListColumn>();
+}
+
+
+LLScrollListColumn::LLScrollListColumn(const Params& p, LLScrollListCtrl* parent)
+: mWidth(0),
+ mIndex (-1),
+ mParentCtrl(parent),
+ mName(p.name),
+ mLabel(p.header.label),
+ mHeader(NULL),
+ mMaxContentWidth(0),
+ mDynamicWidth(p.width.dynamic_width),
+ mRelWidth(p.width.relative_width),
+ mFontAlignment(p.halign),
+ mSortingColumn(p.sort_column)
+{
+ if (p.sort_ascending.isProvided())
+ {
+ mSortDirection = p.sort_ascending() ? ASCENDING : DESCENDING;
+ }
+ else
+ {
+ mSortDirection = p.sort_direction;
+ }
+
+ setWidth(p.width.pixel_width);
+}
+
+void LLScrollListColumn::setWidth(S32 width)
+{
+ if (!mDynamicWidth && mRelWidth <= 0.f)
+ {
+ mParentCtrl->updateStaticColumnWidth(this, width);
+ }
+ mWidth = width;
+}
diff --git a/indra/llui/llscrolllistcolumn.h b/indra/llui/llscrolllistcolumn.h
new file mode 100644
index 0000000000..23318fd7c4
--- /dev/null
+++ b/indra/llui/llscrolllistcolumn.h
@@ -0,0 +1,191 @@
+/**
+ * @file llscrollcolumnheader.h
+ * @brief Scroll lists are composed of rows (items), each of which
+ * contains columns (cells).
+ *
+ * $LicenseInfo:firstyear=2007&license=viewergpl$
+ *
+ * Copyright (c) 2007-2009, Linden Research, Inc.
+ *
+ * Second Life Viewer Source Code
+ * The source code in this file ("Source Code") is provided by Linden Lab
+ * to you under the terms of the GNU General Public License, version 2.0
+ * ("GPL"), unless you have obtained a separate licensing agreement
+ * ("Other License"), formally executed by you and Linden Lab. Terms of
+ * the GPL can be found in doc/GPL-license.txt in this distribution, or
+ * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
+ *
+ * There are special exceptions to the terms and conditions of the GPL as
+ * it is applied to this Source Code. View the full text of the exception
+ * in the file doc/FLOSS-exception.txt in this software distribution, or
+ * online at
+ * http://secondlifegrid.net/programs/open_source/licensing/flossexception
+ *
+ * By copying, modifying or distributing this software, you acknowledge
+ * that you have read and understood your obligations described above,
+ * and agree to abide by those obligations.
+ *
+ * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+ * COMPLETENESS OR PERFORMANCE.
+ * $/LicenseInfo$
+ */
+
+#ifndef LLSCROLLLISTCOLUMN_H
+#define LLSCROLLLISTCOLUMN_H
+
+#include "llrect.h"
+#include "lluistring.h"
+#include "llbutton.h"
+#include "llinitparam.h"
+
+class LLScrollListColumn;
+class LLResizeBar;
+class LLScrollListCtrl;
+
+class LLScrollColumnHeader : public LLButton
+{
+public:
+ struct Params : public LLInitParam::Block<Params, LLButton::Params>
+ {
+ Mandatory<LLScrollListColumn*> column;
+
+ Params()
+ : column("column")
+ {
+ name = "column_header";
+ image_unselected.name("square_btn_32x128.tga");
+ image_selected.name("square_btn_selected_32x128.tga");
+ image_disabled.name("square_btn_32x128.tga");
+ image_disabled_selected.name("square_btn_selected_32x128.tga");
+ image_overlay.name("combobox_arrow.tga");
+ image_overlay_alignment("right");
+ font_halign = LLFontGL::LEFT;
+ tab_stop(false);
+ scale_image(true);
+ }
+ };
+ LLScrollColumnHeader(const Params&);
+ ~LLScrollColumnHeader();
+
+ /*virtual*/ void draw();
+ /*virtual*/ BOOL handleDoubleClick(S32 x, S32 y, MASK mask);
+
+ /*virtual*/ LLView* findSnapEdge(S32& new_edge_val, const LLCoordGL& mouse_dir, ESnapEdge snap_edge, ESnapType snap_type, S32 threshold, S32 padding);
+ /*virtual*/ void handleReshape(const LLRect& new_rect, bool by_user = false);
+
+ LLScrollListColumn* getColumn() { return mColumn; }
+ void setHasResizableElement(BOOL resizable);
+ void updateResizeBars();
+ BOOL canResize();
+ void enableResizeBar(BOOL enable);
+
+ void onClick(const LLSD& data);
+
+private:
+ LLScrollListColumn* mColumn;
+ LLResizeBar* mResizeBar;
+ BOOL mHasResizableElement;
+};
+
+/*
+ * A simple data class describing a column within a scroll list.
+ */
+class LLScrollListColumn
+{
+public:
+ typedef enum e_sort_direction
+ {
+ DESCENDING,
+ ASCENDING
+ } ESortDirection;
+
+ struct SortNames
+ : public LLInitParam::TypeValuesHelper<LLScrollListColumn::ESortDirection, SortNames>
+ {
+ static void declareValues();
+ };
+
+ struct Params : public LLInitParam::Block<Params>
+ {
+ Optional<std::string> name,
+ tool_tip;
+ Optional<std::string> sort_column;
+ Optional<ESortDirection, SortNames> sort_direction;
+ Optional<bool> sort_ascending;
+
+ struct Width : public LLInitParam::Choice<Width>
+ {
+ Alternative<bool> dynamic_width;
+ Alternative<S32> pixel_width;
+ Alternative<F32> relative_width;
+
+ Width()
+ : dynamic_width("dynamic_width", false),
+ pixel_width("width"),
+ relative_width("relative_width", -1.f)
+ {
+ addSynonym(relative_width, "relwidth");
+ }
+ };
+ Optional<Width> width;
+
+ // either an image or label is used in column header
+ struct Header : public LLInitParam::Choice<Header>
+ {
+ Alternative<std::string> label;
+ Alternative<LLUIImage*> image;
+
+ Header()
+ : label("label"),
+ image("image")
+ {}
+ };
+ Optional<Header> header;
+
+ Optional<LLFontGL::HAlign> halign;
+
+ Params()
+ : name("name"),
+ tool_tip("tool_tip"),
+ sort_column("sort_column"),
+ sort_direction("sort_direction"),
+ sort_ascending("sort_ascending", true),
+ halign("halign", LLFontGL::LEFT)
+ {
+ // default choice to "dynamic_width"
+ width.dynamic_width = true;
+
+ addSynonym(sort_column, "sort");
+ }
+ };
+
+ static const Params& getDefaultParams();
+
+ //NOTE: this is default constructible so we can store it in a map.
+ LLScrollListColumn(const Params& p = getDefaultParams(), LLScrollListCtrl* = NULL);
+
+ void setWidth(S32 width);
+ S32 getWidth() const { return mWidth; }
+
+public:
+ // Public data is fine so long as this remains a simple struct-like data class.
+ // If it ever gets any smarter than that, these should all become private
+ // with protected or public accessor methods added as needed. -MG
+ std::string mName;
+ std::string mSortingColumn;
+ ESortDirection mSortDirection;
+ LLUIString mLabel;
+ F32 mRelWidth;
+ BOOL mDynamicWidth;
+ S32 mMaxContentWidth;
+ S32 mIndex;
+ LLScrollListCtrl* mParentCtrl;
+ LLScrollColumnHeader* mHeader;
+ LLFontGL::HAlign mFontAlignment;
+
+private:
+ S32 mWidth;
+};
+
+#endif
diff --git a/indra/llui/llscrolllistctrl.cpp b/indra/llui/llscrolllistctrl.cpp
index 5dd4e2d0ee..637642cdcd 100644
--- a/indra/llui/llscrolllistctrl.cpp
+++ b/indra/llui/llscrolllistctrl.cpp
@@ -1,6 +1,7 @@
/**
* @file llscrolllistctrl.cpp
- * @brief LLScrollListCtrl base class
+ * @brief Scroll lists are composed of rows (items), each of which
+ * contains columns (cells).
*
* $LicenseInfo:firstyear=2001&license=viewergpl$
*
@@ -30,34 +31,34 @@
* $/LicenseInfo$
*/
-#include <algorithm>
-
#include "linden_common.h"
-#include "llstl.h"
-#include "llboost.h"
#include "llscrolllistctrl.h"
-#include "indra_constants.h"
+#include <algorithm>
+
+#include "llstl.h"
+#include "llboost.h"
+//#include "indra_constants.h"
#include "llcheckboxctrl.h"
#include "llclipboard.h"
#include "llfocusmgr.h"
-#include "llrender.h"
+//#include "llrender.h"
#include "llresmgr.h"
#include "llscrollbar.h"
+#include "llscrolllistcell.h"
#include "llstring.h"
#include "llui.h"
#include "lluictrlfactory.h"
#include "llwindow.h"
#include "llcontrol.h"
#include "llkeyboard.h"
-#include "llresizebar.h"
-
-const S32 MIN_COLUMN_WIDTH = 20;
-const S32 LIST_SNAP_PADDING = 5;
+#include "llviewborder.h"
+#include "lltextbox.h"
+#include "llsdparam.h"
-static LLRegisterWidget<LLScrollListCtrl> r("scroll_list");
+static LLDefaultChildRegistry::Register<LLScrollListCtrl> r("scroll_list");
// local structures & classes.
struct SortScrollListItem
@@ -96,510 +97,89 @@ struct SortScrollListItem
const sort_order_t& mSortOrders;
};
-
-//
-// LLScrollListIcon
-//
-LLScrollListIcon::LLScrollListIcon(LLUIImagePtr icon, S32 width)
- : LLScrollListCell(width),
- mIcon(icon),
- mColor(LLColor4::white)
-{
-}
-
-LLScrollListIcon::LLScrollListIcon(const LLSD& value, S32 width)
- : LLScrollListCell(width),
- mColor(LLColor4::white)
-{
- setValue(value);
-}
-
-
-LLScrollListIcon::~LLScrollListIcon()
-{
-}
-
-void LLScrollListIcon::setValue(const LLSD& value)
-{
- if (value.isUUID())
- {
- // don't use default image specified by LLUUID::null, use no image in that case
- LLUUID image_id = value.asUUID();
- mIcon = image_id.notNull() ? LLUI::sImageProvider->getUIImageByID(image_id) : LLUIImagePtr(NULL);
- }
- else
- {
- std::string value_string = value.asString();
- if (LLUUID::validate(value_string))
- {
- setValue(LLUUID(value_string));
- }
- else if (!value_string.empty())
- {
- mIcon = LLUI::getUIImage(value.asString());
- }
- else
- {
- mIcon = NULL;
- }
- }
-}
-
-
-void LLScrollListIcon::setColor(const LLColor4& color)
-{
- mColor = color;
-}
-
-S32 LLScrollListIcon::getWidth() const
-{
- // if no specified fix width, use width of icon
- if (LLScrollListCell::getWidth() == 0 && mIcon.notNull())
- {
- return mIcon->getWidth();
- }
- return LLScrollListCell::getWidth();
-}
-
-
-void LLScrollListIcon::draw(const LLColor4& color, const LLColor4& highlight_color) const
-{
- if (mIcon)
- {
- mIcon->draw(0, 0, mColor);
- }
-}
-
-//
-// LLScrollListCheck
-//
-LLScrollListCheck::LLScrollListCheck(LLCheckBoxCtrl* check_box, S32 width)
-{
- mCheckBox = check_box;
- LLRect rect(mCheckBox->getRect());
- if (width)
- {
-
- rect.mRight = rect.mLeft + width;
- mCheckBox->setRect(rect);
- setWidth(width);
- }
- else
- {
- setWidth(rect.getWidth()); //check_box->getWidth();
- }
-}
-
-LLScrollListCheck::~LLScrollListCheck()
-{
- delete mCheckBox;
-}
-
-void LLScrollListCheck::draw(const LLColor4& color, const LLColor4& highlight_color) const
-{
- mCheckBox->draw();
-}
-
-BOOL LLScrollListCheck::handleClick()
-{
- if (mCheckBox->getEnabled())
- {
- mCheckBox->toggle();
- }
- // don't change selection when clicking on embedded checkbox
- return TRUE;
-}
-
-//
-// LLScrollListSeparator
-//
-LLScrollListSeparator::LLScrollListSeparator(S32 width) : LLScrollListCell(width)
-{
-}
-
-//virtual
-S32 LLScrollListSeparator::getHeight() const
-{
- return 5;
-}
-
-
-void LLScrollListSeparator::draw(const LLColor4& color, const LLColor4& highlight_color) const
-{
- //*FIXME: use dynamic item heights and make separators narrow, and inactive
- gl_line_2d(5, 8, llmax(5, getWidth() - 5), 8, color);
-}
-
-//
-// LLScrollListText
-//
-U32 LLScrollListText::sCount = 0;
-
-LLScrollListText::LLScrollListText( const std::string& text, const LLFontGL* font, S32 width, U8 font_style, LLFontGL::HAlign font_alignment, LLColor4& color, BOOL use_color, BOOL visible)
-: LLScrollListCell(width),
- mText( text ),
- mFont( font ),
- mColor(color),
- mUseColor(use_color),
- mFontStyle( font_style ),
- mFontAlignment( font_alignment ),
- mVisible( visible ),
- mHighlightCount( 0 ),
- mHighlightOffset( 0 )
-{
- sCount++;
-
- // initialize rounded rect image
- if (!mRoundedRectImage)
- {
- mRoundedRectImage = LLUI::sImageProvider->getUIImage("rounded_square.tga");
- }
-}
-//virtual
-void LLScrollListText::highlightText(S32 offset, S32 num_chars)
-{
- mHighlightOffset = offset;
- mHighlightCount = num_chars;
-}
-
-//virtual
-BOOL LLScrollListText::isText() const
-{
- return TRUE;
-}
-
-//virtual
-BOOL LLScrollListText::getVisible() const
-{
- return mVisible;
-}
-
-//virtual
-S32 LLScrollListText::getHeight() const
-{
- return llround(mFont->getLineHeight());
-}
-
-
-LLScrollListText::~LLScrollListText()
-{
- sCount--;
-}
-
-S32 LLScrollListText::getContentWidth() const
-{
- return mFont->getWidth(mText.getString());
-}
-
-
-void LLScrollListText::setColor(const LLColor4& color)
-{
- mColor = color;
- mUseColor = TRUE;
-}
-
-void LLScrollListText::setText(const LLStringExplicit& text)
-{
- mText = text;
-}
-
-//virtual
-void LLScrollListText::setValue(const LLSD& text)
-{
- setText(text.asString());
-}
-
-//virtual
-const LLSD LLScrollListText::getValue() const
-{
- return LLSD(mText.getString());
-}
-
-
-void LLScrollListText::draw(const LLColor4& color, const LLColor4& highlight_color) const
-{
- LLColor4 display_color;
- if (mUseColor)
- {
- display_color = mColor;
- }
- else
- {
- display_color = color;
- }
-
- if (mHighlightCount > 0)
- {
- S32 left = 0;
- switch(mFontAlignment)
- {
- case LLFontGL::LEFT:
- left = mFont->getWidth(mText.getString(), 0, mHighlightOffset);
- break;
- case LLFontGL::RIGHT:
- left = getWidth() - mFont->getWidth(mText.getString(), mHighlightOffset, S32_MAX);
- break;
- case LLFontGL::HCENTER:
- left = (getWidth() - mFont->getWidth(mText.getString())) / 2;
- break;
- }
- LLRect highlight_rect(left - 2,
- llround(mFont->getLineHeight()) + 1,
- left + mFont->getWidth(mText.getString(), mHighlightOffset, mHighlightCount) + 1,
- 1);
- mRoundedRectImage->draw(highlight_rect, highlight_color);
- }
-
- // Try to draw the entire string
- F32 right_x;
- U32 string_chars = mText.length();
- F32 start_x = 0.f;
- switch(mFontAlignment)
- {
- case LLFontGL::LEFT:
- start_x = 0.f;
- break;
- case LLFontGL::RIGHT:
- start_x = (F32)getWidth();
- break;
- case LLFontGL::HCENTER:
- start_x = (F32)getWidth() * 0.5f;
- break;
- }
- mFont->render(mText.getWString(), 0,
- start_x, 2.f,
- display_color,
- mFontAlignment,
- LLFontGL::BOTTOM,
- mFontStyle,
- string_chars,
- getWidth(),
- &right_x,
- FALSE,
- TRUE);
-}
-
-LLScrollListDate::LLScrollListDate( const LLDate& date, const LLFontGL* font, S32 width, U8 font_style, LLFontGL::HAlign font_alignment, LLColor4& color, BOOL use_color, BOOL visible)
-: LLScrollListText(date.asRFC1123(), font, width, font_style, font_alignment, color, use_color, visible),
- mDate(date)
-{
-}
-
-void LLScrollListDate::setValue(const LLSD& value)
-{
- mDate = value.asDate();
- LLScrollListText::setValue(mDate.asRFC1123());
-}
-
-const LLSD LLScrollListDate::getValue() const
-{
- return mDate;
-}
-
-LLScrollListItem::~LLScrollListItem()
-{
- std::for_each(mColumns.begin(), mColumns.end(), DeletePointer());
-}
-
-void LLScrollListItem::setNumColumns(S32 columns)
-{
- S32 prev_columns = mColumns.size();
- if (columns < prev_columns)
- {
- std::for_each(mColumns.begin()+columns, mColumns.end(), DeletePointer());
- }
-
- mColumns.resize(columns);
-
- for (S32 col = prev_columns; col < columns; ++col)
- {
- mColumns[col] = NULL;
- }
-}
-
-void LLScrollListItem::setColumn( S32 column, LLScrollListCell *cell )
-{
- if (column < (S32)mColumns.size())
- {
- delete mColumns[column];
- mColumns[column] = cell;
- }
- else
- {
- llerrs << "LLScrollListItem::setColumn: bad column: " << column << llendl;
- }
-}
-
-std::string LLScrollListItem::getContentsCSV() const
-{
- std::string ret;
-
- S32 count = getNumColumns();
- for (S32 i=0; i<count; ++i)
- {
- ret += getColumn(i)->getValue().asString();
- if (i < count-1)
- {
- ret += ", ";
- }
- }
-
- return ret;
-}
-
-void LLScrollListItem::draw(const LLRect& rect, const LLColor4& fg_color, const LLColor4& bg_color, const LLColor4& highlight_color, S32 column_padding)
-{
- // draw background rect
- LLRect bg_rect = rect;
- {
- gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
- gGL.color4fv(bg_color.mV);
- gl_rect_2d( bg_rect );
- }
-
- S32 cur_x = rect.mLeft;
- S32 num_cols = getNumColumns();
- S32 cur_col = 0;
-
- for (LLScrollListCell* cell = getColumn(0); cur_col < num_cols; cell = getColumn(++cur_col))
- {
- // Two ways a cell could be hidden
- if (cell->getWidth() < 0
- || !cell->getVisible()) continue;
-
- LLUI::pushMatrix();
- {
- LLUI::translate((F32) cur_x, (F32) rect.mBottom, 0.0f);
-
- cell->draw( fg_color, highlight_color );
- }
- LLUI::popMatrix();
-
- cur_x += cell->getWidth() + column_padding;
- }
-}
-
-
-void LLScrollListItem::setEnabled(BOOL b)
-{
- mEnabled = b;
-}
-
-//---------------------------------------------------------------------------
-// LLScrollListItemComment
-//---------------------------------------------------------------------------
-LLScrollListItemComment::LLScrollListItemComment(const std::string& comment_string, const LLColor4& color)
-: LLScrollListItem(FALSE),
- mColor(color)
-{
- addColumn( comment_string, LLResMgr::getInstance()->getRes( LLFONT_SANSSERIF_SMALL ) );
-}
-
-void LLScrollListItemComment::draw(const LLRect& rect, const LLColor4& fg_color, const LLColor4& bg_color, const LLColor4& highlight_color, S32 column_padding)
-{
- LLScrollListCell* cell = getColumn(0);
- if (cell)
- {
- // Two ways a cell could be hidden
- if (cell->getWidth() < 0
- || !cell->getVisible()) return;
-
- LLUI::pushMatrix();
- {
- LLUI::translate((F32)rect.mLeft, (F32)rect.mBottom, 0.0f);
-
- // force first cell to be width of entire item
- cell->setWidth(rect.getWidth());
- cell->draw( mColor, highlight_color );
- }
- LLUI::popMatrix();
- }
-}
-
-//---------------------------------------------------------------------------
-// LLScrollListItemSeparator
-//---------------------------------------------------------------------------
-LLScrollListItemSeparator::LLScrollListItemSeparator()
-: LLScrollListItem(FALSE)
-{
- LLScrollListSeparator* cell = new LLScrollListSeparator(0);
- setNumColumns(1);
- setColumn(0, cell);
-}
-
-void LLScrollListItemSeparator::draw(const LLRect& rect, const LLColor4& fg_color, const LLColor4& bg_color, const LLColor4& highlight_color, S32 column_padding)
-{
- //TODO* move LLScrollListSeparator::draw into here and get rid of it
- LLScrollListCell* cell = getColumn(0);
- if (cell)
- {
- // Two ways a cell could be hidden
- if (cell->getWidth() < 0
- || !cell->getVisible()) return;
-
- LLUI::pushMatrix();
- {
- LLUI::translate((F32)rect.mLeft, (F32)rect.mBottom, 0.0f);
-
- // force first cell to be width of entire item
- cell->setWidth(rect.getWidth());
- cell->draw( fg_color, highlight_color );
- }
- LLUI::popMatrix();
- }
-}
-
//---------------------------------------------------------------------------
// LLScrollListCtrl
//---------------------------------------------------------------------------
-LLScrollListCtrl::LLScrollListCtrl(const std::string& name, const LLRect& rect,
- void (*commit_callback)(LLUICtrl* ctrl, void* userdata),
- void* callback_user_data,
- BOOL allow_multiple_selection,
- BOOL show_border
- )
- : LLUICtrl(name, rect, TRUE, commit_callback, callback_user_data),
+LLScrollListCtrl::Contents::Contents()
+: columns("column"),
+ rows("row")
+{
+ addSynonym(columns, "columns");
+ addSynonym(rows, "rows");
+}
+
+LLScrollListCtrl::Params::Params()
+: multi_select("multi_select", false),
+ has_border("draw_border"),
+ draw_heading("draw_heading"),
+ search_column("search_column", 0),
+ sort_column("sort_column", -1),
+ sort_ascending("sort_ascending", true),
+ commit_on_keyboard_movement("commit_on_keyboard_movement", true),
+ heading_height("heading_height"),
+ background_visible("background_visible"),
+ draw_stripes("draw_stripes"),
+ column_padding("column_padding"),
+ fg_unselected_color("fg_unselected_color"),
+ fg_selected_color("fg_selected_color"),
+ bg_selected_color("bg_selected_color"),
+ fg_disable_color("fg_disable_color"),
+ bg_writeable_color("bg_writeable_color"),
+ bg_readonly_color("bg_readonly_color"),
+ bg_stripe_color("bg_stripe_color"),
+ hovered_color("hovered_color"),
+ highlighted_color("highlighted_color"),
+ contents("")
+{
+ name = "scroll_list";
+ mouse_opaque = true;
+}
+
+LLScrollListCtrl::LLScrollListCtrl(const LLScrollListCtrl::Params& p)
+: LLUICtrl(p),
mLineHeight(0),
mScrollLines(0),
mPageLines(0),
- mHeadingHeight(20),
mMaxSelectable(0),
- mAllowMultipleSelection( allow_multiple_selection ),
mAllowKeyboardMovement(TRUE),
- mCommitOnKeyboardMovement(TRUE),
+ mCommitOnKeyboardMovement(p.commit_on_keyboard_movement),
mCommitOnSelectionChange(FALSE),
mSelectionChanged(FALSE),
mNeedsScroll(FALSE),
mCanSelect(TRUE),
- mDisplayColumnHeaders(FALSE),
mColumnsDirty(FALSE),
mMaxItemCount(INT_MAX),
mMaxContentWidth(0),
- mBackgroundVisible( TRUE ),
- mDrawStripes(TRUE),
- mBgWriteableColor( LLUI::sColorsGroup->getColor( "ScrollBgWriteableColor" ) ),
- mBgReadOnlyColor( LLUI::sColorsGroup->getColor( "ScrollBgReadOnlyColor" ) ),
- mBgSelectedColor( LLUI::sColorsGroup->getColor("ScrollSelectedBGColor") ),
- mBgStripeColor( LLUI::sColorsGroup->getColor("ScrollBGStripeColor") ),
- mFgSelectedColor( LLUI::sColorsGroup->getColor("ScrollSelectedFGColor") ),
- mFgUnselectedColor( LLUI::sColorsGroup->getColor("ScrollUnselectedColor") ),
- mFgDisabledColor( LLUI::sColorsGroup->getColor("ScrollDisabledColor") ),
- mHighlightedColor( LLUI::sColorsGroup->getColor("ScrollHighlightedColor") ),
mBorderThickness( 2 ),
mOnDoubleClickCallback( NULL ),
mOnMaximumSelectCallback( NULL ),
mOnSortChangedCallback( NULL ),
mHighlightedItem(-1),
mBorder(NULL),
- mSearchColumn(0),
mNumDynamicWidthColumns(0),
mTotalStaticColumnWidth(0),
mTotalColumnPadding(0),
- mSorted(TRUE),
+ mSorted(false),
mDirty(FALSE),
mOriginalSelection(-1),
- mDrewSelected(FALSE)
+ mLastSelected(NULL),
+ mHeadingHeight(p.heading_height),
+ mAllowMultipleSelection(p.multi_select),
+ mDisplayColumnHeaders(p.draw_heading),
+ mBackgroundVisible(p.background_visible),
+ mDrawStripes(p.draw_stripes),
+ mBgWriteableColor(p.bg_writeable_color()),
+ mBgReadOnlyColor(p.bg_readonly_color()),
+ mBgSelectedColor(p.bg_selected_color()),
+ mBgStripeColor(p.bg_stripe_color()),
+ mFgSelectedColor(p.fg_selected_color()),
+ mFgUnselectedColor(p.fg_unselected_color()),
+ mFgDisabledColor(p.fg_disable_color()),
+ mHighlightedColor(p.highlighted_color()),
+ mHoveredColor(p.hovered_color()),
+ mSearchColumn(p.search_column),
+ mColumnPadding(p.column_padding)
{
mItemListRect.setOriginAndSize(
mBorderThickness,
@@ -612,37 +192,73 @@ LLScrollListCtrl::LLScrollListCtrl(const std::string& name, const LLRect& rect,
mPageLines = mLineHeight? (mItemListRect.getHeight()) / mLineHeight : 0;
// Init the scrollbar
+ static LLUICachedControl<S32> scrollbar_size ("UIScrollbarSize", 0);
+
LLRect scroll_rect;
scroll_rect.setOriginAndSize(
- getRect().getWidth() - mBorderThickness - SCROLLBAR_SIZE,
+ getRect().getWidth() - mBorderThickness - scrollbar_size,
mItemListRect.mBottom,
- SCROLLBAR_SIZE,
+ scrollbar_size,
mItemListRect.getHeight());
- mScrollbar = new LLScrollbar( std::string("Scrollbar"), scroll_rect,
- LLScrollbar::VERTICAL,
- getItemCount(),
- mScrollLines,
- mPageLines,
- &LLScrollListCtrl::onScrollChange, this );
- mScrollbar->setFollowsRight();
- mScrollbar->setFollowsTop();
- mScrollbar->setFollowsBottom();
- mScrollbar->setEnabled( TRUE );
- // scrollbar is visible only when needed
- mScrollbar->setVisible(FALSE);
+
+ LLScrollbar::Params sbparams;
+ sbparams.name("Scrollbar");
+ sbparams.rect(scroll_rect);
+ sbparams.orientation(LLScrollbar::VERTICAL);
+ sbparams.doc_size(getItemCount());
+ sbparams.doc_pos(mScrollLines);
+ sbparams.page_size(mPageLines);
+ sbparams.change_callback(boost::bind(&LLScrollListCtrl::onScrollChange, this, _1, _2));
+ sbparams.follows.flags(FOLLOWS_RIGHT | FOLLOWS_TOP | FOLLOWS_BOTTOM);
+ sbparams.visible(false);
+ mScrollbar = LLUICtrlFactory::create<LLScrollbar> (sbparams);
addChild(mScrollbar);
// Border
- if (show_border)
- {
- LLRect border_rect( 0, getRect().getHeight(), getRect().getWidth(), 0 );
- mBorder = new LLViewBorder( std::string("dlg border"), border_rect, LLViewBorder::BEVEL_IN, LLViewBorder::STYLE_LINE, 1 );
+ if (p.has_border)
+ {
+ LLRect border_rect = getLocalRect();
+ LLViewBorder::Params params;
+ params.name("dig border");
+ params.rect(border_rect);
+ params.bevel_style(LLViewBorder::BEVEL_IN);
+ mBorder = LLUICtrlFactory::create<LLViewBorder> (params);
addChild(mBorder);
}
- mColumnPadding = 5;
+ // set border *after* rect is fully initialized
+ if (mBorder)
+ {
+ mBorder->setRect(getLocalRect());
+ mBorder->reshape(getRect().getWidth(), getRect().getHeight());
+ }
- mLastSelected = NULL;
+ if (p.sort_column >= 0)
+ {
+ sortByColumnIndex(p.sort_column, p.sort_ascending);
+ }
+
+
+ for (LLInitParam::ParamIterator<LLScrollListColumn::Params>::const_iterator row_it = p.contents.columns().begin();
+ row_it != p.contents.columns().end();
+ ++row_it)
+ {
+ addColumn(*row_it);
+ }
+
+ for (LLInitParam::ParamIterator<LLScrollListItem::Params>::const_iterator row_it = p.contents.rows().begin();
+ row_it != p.contents.rows().end();
+ ++row_it)
+ {
+ addRow(*row_it);
+ }
+
+ LLTextBox::Params text_p;
+ text_p.name("comment_text");
+ text_p.border_visible(false);
+ text_p.rect(mItemListRect);
+ text_p.follows.flags(FOLLOWS_ALL);
+ addChild(LLUICtrlFactory::create<LLTextBox>(text_p));
}
S32 LLScrollListCtrl::getSearchColumn()
@@ -666,6 +282,18 @@ S32 LLScrollListCtrl::getSearchColumn()
}
return llclamp(mSearchColumn, 0, getNumColumns());
}
+/*virtual*/
+bool LLScrollListCtrl::preProcessChildNode(LLXMLNodePtr child)
+{
+ if (child->hasName("column") || child->hasName("row"))
+ {
+ return true; // skip
+ }
+ else
+ {
+ return false;
+ }
+}
LLScrollListCtrl::~LLScrollListCtrl()
{
@@ -746,6 +374,10 @@ std::vector<LLScrollListItem*> LLScrollListCtrl::getAllSelected() const
S32 LLScrollListCtrl::getFirstSelectedIndex() const
{
S32 CurSelectedIndex = 0;
+
+ // make sure sort is up to date before returning an index
+ updateSort();
+
item_list::const_iterator iter;
for (iter = mItemList.begin(); iter != mItemList.end(); iter++)
{
@@ -818,6 +450,7 @@ void LLScrollListCtrl::reshape( S32 width, S32 height, BOOL called_from_parent )
void LLScrollListCtrl::updateLayout()
{
+ static LLUICachedControl<S32> scrollbar_size ("UIScrollbarSize", 0);
// reserve room for column headers, if needed
S32 heading_size = (mDisplayColumnHeaders ? mHeadingHeight : 0);
mItemListRect.setOriginAndSize(
@@ -826,22 +459,19 @@ void LLScrollListCtrl::updateLayout()
getRect().getWidth() - 2 * mBorderThickness,
getRect().getHeight() - (2 * mBorderThickness ) - heading_size );
+ getChildView("comment_text")->setShape(mItemListRect);
+
// how many lines of content in a single "page"
mPageLines = mLineHeight? mItemListRect.getHeight() / mLineHeight : 0;
BOOL scrollbar_visible = getItemCount() > mPageLines;
if (scrollbar_visible)
{
// provide space on the right for scrollbar
- mItemListRect.mRight = getRect().getWidth() - mBorderThickness - SCROLLBAR_SIZE;
+ mItemListRect.mRight = getRect().getWidth() - mBorderThickness - scrollbar_size;
}
- // don't allow scrolling off bottom
- if (mScrollLines + mPageLines > getItemCount())
- {
- setScrollPos(llmax(0, getItemCount() - mPageLines));
- }
-
- mScrollbar->reshape(SCROLLBAR_SIZE, mItemListRect.getHeight() + (mDisplayColumnHeaders ? mHeadingHeight : 0));
+ mScrollbar->setOrigin(getRect().getWidth() - mBorderThickness - scrollbar_size, mItemListRect.mBottom);
+ mScrollbar->reshape(scrollbar_size, mItemListRect.getHeight() + (mDisplayColumnHeaders ? mHeadingHeight : 0));
mScrollbar->setPageSize( mPageLines );
mScrollbar->setDocSize( getItemCount() );
mScrollbar->setVisible(scrollbar_visible);
@@ -881,7 +511,7 @@ BOOL LLScrollListCtrl::addItem( LLScrollListItem* item, EAddPosition pos, BOOL r
{
case ADD_TOP:
mItemList.push_front(item);
- setSorted(FALSE);
+ setNeedsSort();
break;
case ADD_SORTED:
@@ -898,29 +528,29 @@ BOOL LLScrollListCtrl::addItem( LLScrollListItem* item, EAddPosition pos, BOOL r
// ADD_SORTED just sorts by first column...
// this might not match user sort criteria, so flag list as being in unsorted state
- setSorted(FALSE);
+ setNeedsSort();
break;
}
case ADD_BOTTOM:
mItemList.push_back(item);
- setSorted(FALSE);
+ setNeedsSort();
break;
default:
llassert(0);
mItemList.push_back(item);
- setSorted(FALSE);
+ setNeedsSort();
break;
}
// create new column on demand
if (mColumns.empty() && requires_column)
{
- LLSD new_column;
- new_column["name"] = "default_column";
- new_column["label"] = "";
- new_column["dynamicwidth"] = TRUE;
- addColumn(new_column);
+ LLScrollListColumn::Params col_params;
+ col_params.name = "default_column";
+ col_params.header.label = "";
+ col_params.width.dynamic_width = true;
+ addColumn(col_params);
}
updateLineHeightInsert(item);
@@ -1017,7 +647,7 @@ void LLScrollListCtrl::updateColumns()
// update column headers
std::vector<LLScrollListColumn*>::iterator column_ordered_it;
S32 left = mItemListRect.mLeft;
- LLColumnHeader* last_header = NULL;
+ LLScrollColumnHeader* last_header = NULL;
for (column_ordered_it = mColumnsIndexed.begin(); column_ordered_it != mColumnsIndexed.end(); ++column_ordered_it)
{
if ((*column_ordered_it)->getWidth() < 0)
@@ -1052,7 +682,7 @@ void LLScrollListCtrl::updateColumns()
}
// expand last column header we encountered to full list width
- if (last_header && last_header->canResize())
+ if (last_header)
{
S32 new_width = llmax(0, mItemListRect.mRight - last_header->getRect().mLeft);
last_header->reshape(new_width, last_header->getRect().getHeight());
@@ -1077,13 +707,6 @@ void LLScrollListCtrl::updateColumns()
}
-void LLScrollListCtrl::setDisplayHeading(BOOL display)
-{
- mDisplayColumnHeaders = display;
-
- updateLayout();
-}
-
void LLScrollListCtrl::setHeadingHeight(S32 heading_height)
{
mHeadingHeight = heading_height;
@@ -1140,6 +763,9 @@ BOOL LLScrollListCtrl::selectItemRange( S32 first_index, S32 last_index )
return FALSE;
}
+ // make sure sort is up to date
+ updateSort();
+
S32 listlen = (S32)mItemList.size();
first_index = llclamp(first_index, 0, listlen-1);
@@ -1193,6 +819,7 @@ void LLScrollListCtrl::swapWithNext(S32 index)
// At end of list, doesn't do anything
return;
}
+ updateSort();
LLScrollListItem *cur_itemp = mItemList[index];
mItemList[index] = mItemList[index + 1];
mItemList[index + 1] = cur_itemp;
@@ -1206,6 +833,7 @@ void LLScrollListCtrl::swapWithPrevious(S32 index)
// At beginning of list, don't do anything
}
+ updateSort();
LLScrollListItem *cur_itemp = mItemList[index];
mItemList[index] = mItemList[index - 1];
mItemList[index - 1] = cur_itemp;
@@ -1219,6 +847,8 @@ void LLScrollListCtrl::deleteSingleItem(S32 target_index)
return;
}
+ updateSort();
+
LLScrollListItem *itemp;
itemp = mItemList[target_index];
if (itemp == mLastSelected)
@@ -1275,7 +905,15 @@ void LLScrollListCtrl::deleteSelectedItems()
dirtyColumns();
}
-void LLScrollListCtrl::highlightNthItem(S32 target_index)
+void LLScrollListCtrl::clearHighlightedItems()
+{
+ for (item_list::iterator iter = mItemList.begin(); iter != mItemList.end(); ++iter)
+ {
+ (*iter)->setHighlighted(false);
+ }
+}
+
+void LLScrollListCtrl::mouseOverHighlightNthItem(S32 target_index)
{
if (mHighlightedItem != target_index)
{
@@ -1283,14 +921,14 @@ void LLScrollListCtrl::highlightNthItem(S32 target_index)
}
}
-S32 LLScrollListCtrl::selectMultiple( LLDynamicArray<LLUUID> ids )
+S32 LLScrollListCtrl::selectMultiple( std::vector<LLUUID> ids )
{
item_list::iterator iter;
S32 count = 0;
for (iter = mItemList.begin(); iter != mItemList.end(); iter++)
{
LLScrollListItem* item = *iter;
- LLDynamicArray<LLUUID>::iterator iditr;
+ std::vector<LLUUID>::iterator iditr;
for(iditr = ids.begin(); iditr != ids.end(); ++iditr)
{
if (item->getEnabled() && (item->getUUID() == (*iditr)))
@@ -1312,6 +950,8 @@ S32 LLScrollListCtrl::selectMultiple( LLDynamicArray<LLUUID> ids )
S32 LLScrollListCtrl::getItemIndex( LLScrollListItem* target_item ) const
{
+ updateSort();
+
S32 index = 0;
item_list::const_iterator iter;
for (iter = mItemList.begin(); iter != mItemList.end(); iter++)
@@ -1328,6 +968,8 @@ S32 LLScrollListCtrl::getItemIndex( LLScrollListItem* target_item ) const
S32 LLScrollListCtrl::getItemIndex( const LLUUID& target_id ) const
{
+ updateSort();
+
S32 index = 0;
item_list::const_iterator iter;
for (iter = mItemList.begin(); iter != mItemList.end(); iter++)
@@ -1353,6 +995,8 @@ void LLScrollListCtrl::selectPrevItem( BOOL extend_selection)
}
else
{
+ updateSort();
+
item_list::iterator iter;
for (iter = mItemList.begin(); iter != mItemList.end(); iter++)
{
@@ -1395,6 +1039,8 @@ void LLScrollListCtrl::selectNextItem( BOOL extend_selection)
}
else
{
+ updateSort();
+
item_list::reverse_iterator iter;
for (iter = mItemList.rbegin(); iter != mItemList.rend(); iter++)
{
@@ -1446,35 +1092,51 @@ void LLScrollListCtrl::deselectAllItems(BOOL no_commit_on_change)
///////////////////////////////////////////////////////////////////////////////////////////////////
// Use this to add comment text such as "Searching", which ignores column settings of list
-LLScrollListItem* LLScrollListCtrl::addCommentText(const std::string& comment_text, EAddPosition pos)
+void LLScrollListCtrl::setCommentText(const std::string& comment_text)
{
- LLScrollListItem* item = NULL;
- if (getItemCount() < mMaxItemCount)
- {
- // always draw comment text with "enabled" color
- item = new LLScrollListItemComment( comment_text, mFgUnselectedColor );
- addItem( item, pos, FALSE );
- }
- return item;
+ getChild<LLTextBox>("comment_text")->setValue(comment_text);
}
LLScrollListItem* LLScrollListCtrl::addSeparator(EAddPosition pos)
{
- LLScrollListItem* item = new LLScrollListItemSeparator();
- addItem(item, pos, FALSE);
- return item;
+ LLScrollListItem::Params separator_params;
+ separator_params.enabled(false);
+ LLScrollListCell::Params column_params;
+ column_params.type = "icon";
+ column_params.value = "menu_separator";
+ column_params.color = LLColor4(0.f, 0.f, 0.f, 0.7f);
+ column_params.font_halign = LLFontGL::HCENTER;
+ separator_params.columns.add(column_params);
+ return addRow( separator_params, pos );
}
// Selects first enabled item of the given name.
// Returns false if item not found.
+// Calls getItemByLabel in order to combine functionality
BOOL LLScrollListCtrl::selectItemByLabel(const std::string& label, BOOL case_sensitive)
{
- // ensure that no stale items are selected, even if we don't find a match
- deselectAllItems(TRUE);
- //RN: assume no empty items
- if (label.empty())
+ deselectAllItems(TRUE); // ensure that no stale items are selected, even if we don't find a match
+ LLScrollListItem* item = getItemByLabel(label, case_sensitive);
+
+ bool found = NULL != item;
+ if(found)
{
- return FALSE;
+ selectItem(item);
+ }
+
+ if (mCommitOnSelectionChange)
+ {
+ commitIfChanged();
+ }
+
+ return found;
+}
+
+LLScrollListItem* LLScrollListCtrl::getItemByLabel(const std::string& label, BOOL case_sensitive, S32 column)
+{
+ if (label.empty()) //RN: assume no empty items
+ {
+ return NULL;
}
std::string target_text = label;
@@ -1483,34 +1145,21 @@ BOOL LLScrollListCtrl::selectItemByLabel(const std::string& label, BOOL case_sen
LLStringUtil::toLower(target_text);
}
- BOOL found = FALSE;
-
item_list::iterator iter;
- S32 index = 0;
for (iter = mItemList.begin(); iter != mItemList.end(); iter++)
{
LLScrollListItem* item = *iter;
- // Only select enabled items with matching names
- std::string item_text = item->getColumn(0)->getValue().asString();
+ std::string item_text = item->getColumn(column)->getValue().asString(); // Only select enabled items with matching names
if (!case_sensitive)
{
LLStringUtil::toLower(item_text);
}
- BOOL select = !found && item->getEnabled() && item_text == target_text;
- if (select)
+ if(item_text == target_text)
{
- selectItem(item);
+ return item;
}
- found = found || select;
- index++;
- }
-
- if (mCommitOnSelectionChange)
- {
- commitIfChanged();
}
-
- return found;
+ return NULL;
}
@@ -1612,16 +1261,18 @@ const std::string LLScrollListCtrl::getSelectedItemLabel(S32 column) const
// "StringUUID" interface: use this when you're creating a list that contains non-unique strings each of which
// has an associated, unique UUID, and only one of which can be selected at a time.
-LLScrollListItem* LLScrollListCtrl::addStringUUIDItem(const std::string& item_text, const LLUUID& id, EAddPosition pos, BOOL enabled, S32 column_width)
+LLScrollListItem* LLScrollListCtrl::addStringUUIDItem(const std::string& item_text, const LLUUID& id, EAddPosition pos, BOOL enabled)
{
- LLScrollListItem* item = NULL;
if (getItemCount() < mMaxItemCount)
{
- item = new LLScrollListItem( enabled, NULL, id );
- item->addColumn(item_text, LLResMgr::getInstance()->getRes(LLFONT_SANSSERIF_SMALL), column_width);
- addItem( item, pos );
+ LLScrollListItem::Params item_p;
+ item_p.enabled(enabled);
+ item_p.value(id);
+ item_p.columns.add().value(item_text).type("text");
+
+ return addRow( item_p, pos );
}
- return item;
+ return NULL;
}
// Select the line or lines that match this UUID
@@ -1720,13 +1371,11 @@ void LLScrollListCtrl::drawItems()
S32 cur_y = y;
- mDrewSelected = FALSE;
-
S32 line = 0;
S32 max_columns = 0;
LLColor4 highlight_color = LLColor4::white;
- F32 type_ahead_timeout = LLUI::sConfigGroup->getF32("TypeAheadTimeout");
+ static LLUICachedControl<F32> type_ahead_timeout ("TypeAheadTimeout", 0);
highlight_color.mV[VALPHA] = clamp_rescale(mSearchTimer.getElapsedTimeF32(), type_ahead_timeout * 0.7f, type_ahead_timeout, 0.4f, 0.f);
item_list::iterator iter;
@@ -1742,11 +1391,6 @@ void LLScrollListCtrl::drawItems()
//llinfos << item_rect.getWidth() << llendl;
- if (item->getSelected())
- {
- mDrewSelected = TRUE;
- }
-
max_columns = llmax(max_columns, item->getNumColumns());
LLColor4 fg_color;
@@ -1754,27 +1398,46 @@ void LLScrollListCtrl::drawItems()
if( mScrollLines <= line && line < mScrollLines + num_page_lines )
{
- fg_color = (item->getEnabled() ? mFgUnselectedColor : mFgDisabledColor);
+ fg_color = (item->getEnabled() ? mFgUnselectedColor.get() : mFgDisabledColor.get());
if( item->getSelected() && mCanSelect)
{
- bg_color = mBgSelectedColor;
- fg_color = (item->getEnabled() ? mFgSelectedColor : mFgDisabledColor);
+ if(item->getHighlighted()) // if it's highlighted, average the colors
+ {
+ bg_color = lerp(mBgSelectedColor.get(), mHighlightedColor.get(), 0.5f);
+ }
+ else // otherwise just select-highlight it
+ {
+ bg_color = mBgSelectedColor.get();
+ }
+
+ fg_color = (item->getEnabled() ? mFgSelectedColor.get() : mFgDisabledColor.get());
}
else if (mHighlightedItem == line && mCanSelect)
{
- bg_color = mHighlightedColor;
+ if(item->getHighlighted()) // if it's highlighted, average the colors
+ {
+ bg_color = lerp(mHoveredColor.get(), mHighlightedColor.get(), 0.5f);
+ }
+ else // otherwise just hover-highlight it
+ {
+ bg_color = mHoveredColor.get();
+ }
+ }
+ else if (item->getHighlighted())
+ {
+ bg_color = mHighlightedColor.get();
}
else
{
if (mDrawStripes && (line % 2 == 0) && (max_columns > 1))
{
- bg_color = mBgStripeColor;
+ bg_color = mBgStripeColor.get();
}
}
if (!item->getEnabled())
{
- bg_color = mBgReadOnlyColor;
+ bg_color = mBgReadOnlyColor.get();
}
item->draw(item_rect, fg_color, bg_color, highlight_color, mColumnPadding);
@@ -1792,10 +1455,7 @@ void LLScrollListCtrl::draw()
LLLocalClipRect clip(getLocalRect());
// if user specifies sort, make sure it is maintained
- if (needsSorting() && !isSorted())
- {
- sortItems();
- }
+ updateSort();
if (mNeedsScroll)
{
@@ -1807,8 +1467,7 @@ void LLScrollListCtrl::draw()
if (mBackgroundVisible)
{
gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
- gGL.color4fv( getEnabled() ? mBgWriteableColor.mV : mBgReadOnlyColor.mV );
- gl_rect_2d(background);
+ gl_rect_2d(background, getEnabled() ? mBgWriteableColor.get() : mBgReadOnlyColor.get() );
}
if (mColumnsDirty)
@@ -1817,11 +1476,13 @@ void LLScrollListCtrl::draw()
mColumnsDirty = FALSE;
}
+ getChildView("comment_text")->setVisible(mItemList.empty());
+
drawItems();
if (mBorder)
{
- mBorder->setKeyboardFocusHighlight(gFocusMgr.getKeyboardFocus() == this);
+ mBorder->setKeyboardFocusHighlight(hasFocus());
}
LLUICtrl::draw();
@@ -1860,26 +1521,19 @@ BOOL LLScrollListCtrl::handleToolTip(S32 x, S32 y, std::string& msg, LLRect* sti
if (hit_cell
&& hit_cell->isText())
{
-
S32 rect_left = getColumnOffsetFromIndex(column_index) + mItemListRect.mLeft;
S32 rect_bottom = getRowOffsetFromIndex(getItemIndex(hit_item));
LLRect cell_rect;
cell_rect.setOriginAndSize(rect_left, rect_bottom, rect_left + columnp->getWidth(), mLineHeight);
// Convert rect local to screen coordinates
- localPointToScreen(
- cell_rect.mLeft, cell_rect.mBottom,
- &(sticky_rect_screen->mLeft), &(sticky_rect_screen->mBottom) );
- localPointToScreen(
- cell_rect.mRight, cell_rect.mTop,
- &(sticky_rect_screen->mRight), &(sticky_rect_screen->mTop) );
-
+ localRectToScreen(cell_rect, sticky_rect_screen);
msg = hit_cell->getValue().asString();
}
handled = TRUE;
}
// otherwise, look for a tooltip associated with this column
- LLColumnHeader* headerp = columnp->mHeader;
+ LLScrollColumnHeader* headerp = columnp->mHeader;
if (headerp && !handled)
{
headerp->handleToolTip(x, y, msg, sticky_rect_screen);
@@ -1922,7 +1576,7 @@ BOOL LLScrollListCtrl::selectItemAt(S32 x, S32 y, MASK mask)
{
if(mOnMaximumSelectCallback)
{
- mOnMaximumSelectCallback(mCallbackUserData);
+ mOnMaximumSelectCallback();
}
break;
}
@@ -1960,7 +1614,7 @@ BOOL LLScrollListCtrl::selectItemAt(S32 x, S32 y, MASK mask)
{
if(mOnMaximumSelectCallback)
{
- mOnMaximumSelectCallback(mCallbackUserData);
+ mOnMaximumSelectCallback();
}
}
}
@@ -2049,9 +1703,10 @@ BOOL LLScrollListCtrl::handleDoubleClick(S32 x, S32 y, MASK mask)
// so the scroll bars will work.
if (NULL == LLView::childrenHandleDoubleClick(x, y, mask))
{
- if( mCanSelect && mOnDoubleClickCallback )
+ // Run the callback only if an item is being double-clicked.
+ if( mCanSelect && hitItem(x, y) && mOnDoubleClickCallback )
{
- mOnDoubleClickCallback( mCallbackUserData );
+ mOnDoubleClickCallback();
}
}
}
@@ -2118,6 +1773,8 @@ LLScrollListItem* LLScrollListCtrl::hitItem( S32 x, S32 y )
// Excludes disabled items.
LLScrollListItem* hit_item = NULL;
+ updateSort();
+
LLRect item_rect;
item_rect.setLeftTopAndSize(
mItemListRect.mLeft,
@@ -2197,8 +1854,7 @@ S32 LLScrollListCtrl::getColumnOffsetFromIndex(S32 index)
S32 LLScrollListCtrl::getRowOffsetFromIndex(S32 index)
{
- S32 row_bottom = ((mItemListRect.mTop - (index - mScrollLines)) * mLineHeight)
- - mLineHeight;
+ S32 row_bottom = (mItemListRect.mTop - ((index - mScrollLines + 1) * mLineHeight) );
return row_bottom;
}
@@ -2221,11 +1877,11 @@ BOOL LLScrollListCtrl::handleHover(S32 x,S32 y,MASK mask)
LLScrollListItem* item = hitItem(x, y);
if (item)
{
- highlightNthItem(getItemIndex(item));
+ mouseOverHighlightNthItem(getItemIndex(item));
}
else
{
- highlightNthItem(-1);
+ mouseOverHighlightNthItem(-1);
}
}
@@ -2234,6 +1890,11 @@ BOOL LLScrollListCtrl::handleHover(S32 x,S32 y,MASK mask)
return handled;
}
+void LLScrollListCtrl::onMouseLeave(S32 x, S32 y, MASK mask)
+{
+ // clear mouse highlight
+ mouseOverHighlightNthItem(-1);
+}
BOOL LLScrollListCtrl::handleKeyHere(KEY key,MASK mask )
{
@@ -2378,7 +2039,8 @@ BOOL LLScrollListCtrl::handleUnicodeCharHere(llwchar uni_char)
}
// perform incremental search based on keyboard input
- if (mSearchTimer.getElapsedTimeF32() > LLUI::sConfigGroup->getF32("TypeAheadTimeout"))
+ static LLUICachedControl<F32> type_ahead_timeout ("TypeAheadTimeout", 0);
+ if (mSearchTimer.getElapsedTimeF32() > type_ahead_timeout)
{
mSearchString.clear();
}
@@ -2554,9 +2216,11 @@ BOOL LLScrollListCtrl::setSort(S32 column_idx, BOOL ascending)
LLScrollListColumn* sort_column = getColumn(column_idx);
if (!sort_column) return FALSE;
- sort_column->mSortAscending = ascending;
+ sort_column->mSortDirection = ascending ? LLScrollListColumn::ASCENDING : LLScrollListColumn::DESCENDING;
sort_column_t new_sort_column(column_idx, ascending);
+
+ setNeedsSort();
if (mSortColumns.empty())
{
@@ -2579,11 +2243,9 @@ BOOL LLScrollListCtrl::setSort(S32 column_idx, BOOL ascending)
}
// Called by scrollbar
-//static
-void LLScrollListCtrl::onScrollChange( S32 new_pos, LLScrollbar* scrollbar, void* userdata )
+void LLScrollListCtrl::onScrollChange( S32 new_pos, LLScrollbar* scrollbar )
{
- LLScrollListCtrl* self = (LLScrollListCtrl*) userdata;
- self->mScrollLines = new_pos;
+ mScrollLines = new_pos;
}
@@ -2599,21 +2261,22 @@ void LLScrollListCtrl::sortByColumn(const std::string& name, BOOL ascending)
// First column is column 0
void LLScrollListCtrl::sortByColumnIndex(U32 column, BOOL ascending)
{
- if (setSort(column, ascending))
- {
- sortItems();
- }
+ setSort(column, ascending);
+ updateSort();
}
-void LLScrollListCtrl::sortItems()
+void LLScrollListCtrl::updateSort() const
{
- // do stable sort to preserve any previous sorts
- std::stable_sort(
- mItemList.begin(),
- mItemList.end(),
- SortScrollListItem(mSortColumns));
+ if (hasSortOrder() && !isSorted())
+ {
+ // do stable sort to preserve any previous sorts
+ std::stable_sort(
+ mItemList.begin(),
+ mItemList.end(),
+ SortScrollListItem(mSortColumns));
- setSorted(TRUE);
+ mSorted = true;
+ }
}
// for one-shot sorts, does not save sort column/order
@@ -2656,7 +2319,7 @@ void LLScrollListCtrl::setScrollPos( S32 pos )
{
mScrollbar->setDocPos( pos );
- onScrollChange(mScrollbar->getDocPos(), mScrollbar, this);
+ onScrollChange(mScrollbar->getDocPos(), mScrollbar);
}
@@ -2669,10 +2332,7 @@ void LLScrollListCtrl::scrollToShowSelected()
return;
}
- if (needsSorting() && !isSorted())
- {
- sortItems();
- }
+ updateSort();
S32 index = getFirstSelectedIndex();
if (index < 0)
@@ -2706,293 +2366,6 @@ void LLScrollListCtrl::updateStaticColumnWidth(LLScrollListColumn* col, S32 new_
mTotalStaticColumnWidth += llmax(0, new_width) - llmax(0, col->getWidth());
}
-
-// virtual
-LLXMLNodePtr LLScrollListCtrl::getXML(bool save_children) const
-{
- LLXMLNodePtr node = LLUICtrl::getXML();
-
- // Attributes
-
- node->createChild("multi_select", TRUE)->setBoolValue(mAllowMultipleSelection);
-
- node->createChild("draw_border", TRUE)->setBoolValue((mBorder != NULL));
-
- node->createChild("draw_heading", TRUE)->setBoolValue(mDisplayColumnHeaders);
-
- node->createChild("background_visible", TRUE)->setBoolValue(mBackgroundVisible);
-
- node->createChild("draw_stripes", TRUE)->setBoolValue(mDrawStripes);
-
- node->createChild("column_padding", TRUE)->setIntValue(mColumnPadding);
-
- addColorXML(node, mBgWriteableColor, "bg_writeable_color", "ScrollBgWriteableColor");
- addColorXML(node, mBgReadOnlyColor, "bg_read_only_color", "ScrollBgReadOnlyColor");
- addColorXML(node, mBgSelectedColor, "bg_selected_color", "ScrollSelectedBGColor");
- addColorXML(node, mBgStripeColor, "bg_stripe_color", "ScrollBGStripeColor");
- addColorXML(node, mFgSelectedColor, "fg_selected_color", "ScrollSelectedFGColor");
- addColorXML(node, mFgUnselectedColor, "fg_unselected_color", "ScrollUnselectedColor");
- addColorXML(node, mFgDisabledColor, "fg_disable_color", "ScrollDisabledColor");
- addColorXML(node, mHighlightedColor, "highlighted_color", "ScrollHighlightedColor");
-
- // Contents
-
- std::map<std::string, LLScrollListColumn>::const_iterator itor;
- std::vector<const LLScrollListColumn*> sorted_list;
- sorted_list.resize(mColumns.size());
- for (itor = mColumns.begin(); itor != mColumns.end(); ++itor)
- {
- sorted_list[itor->second.mIndex] = &itor->second;
- }
-
- std::vector<const LLScrollListColumn*>::iterator itor2;
- for (itor2 = sorted_list.begin(); itor2 != sorted_list.end(); ++itor2)
- {
- LLXMLNodePtr child_node = node->createChild("column", FALSE);
- const LLScrollListColumn *column = *itor2;
-
- child_node->createChild("name", TRUE)->setStringValue(column->mName);
- child_node->createChild("label", TRUE)->setStringValue(column->mLabel);
- child_node->createChild("width", TRUE)->setIntValue(column->getWidth());
- }
-
- return node;
-}
-
-void LLScrollListCtrl::setScrollListParameters(LLXMLNodePtr node)
-{
- // James: This is not a good way to do colors. We need a central "UI style"
- // manager that sets the colors for ALL scroll lists, buttons, etc.
-
- LLColor4 color;
- if(node->hasAttribute("fg_unselected_color"))
- {
- LLUICtrlFactory::getAttributeColor(node,"fg_unselected_color", color);
- setFgUnselectedColor(color);
- }
- if(node->hasAttribute("fg_selected_color"))
- {
- LLUICtrlFactory::getAttributeColor(node,"fg_selected_color", color);
- setFgSelectedColor(color);
- }
- if(node->hasAttribute("bg_selected_color"))
- {
- LLUICtrlFactory::getAttributeColor(node,"bg_selected_color", color);
- setBgSelectedColor(color);
- }
- if(node->hasAttribute("fg_disable_color"))
- {
- LLUICtrlFactory::getAttributeColor(node,"fg_disable_color", color);
- setFgDisableColor(color);
- }
- if(node->hasAttribute("bg_writeable_color"))
- {
- LLUICtrlFactory::getAttributeColor(node,"bg_writeable_color", color);
- setBgWriteableColor(color);
- }
- if(node->hasAttribute("bg_read_only_color"))
- {
- LLUICtrlFactory::getAttributeColor(node,"bg_read_only_color", color);
- setReadOnlyBgColor(color);
- }
- if (LLUICtrlFactory::getAttributeColor(node,"bg_stripe_color", color))
- {
- setBgStripeColor(color);
- }
- if (LLUICtrlFactory::getAttributeColor(node,"highlighted_color", color))
- {
- setHighlightedColor(color);
- }
-
- if(node->hasAttribute("background_visible"))
- {
- BOOL background_visible;
- node->getAttributeBOOL("background_visible", background_visible);
- setBackgroundVisible(background_visible);
- }
-
- if(node->hasAttribute("draw_stripes"))
- {
- BOOL draw_stripes;
- node->getAttributeBOOL("draw_stripes", draw_stripes);
- setDrawStripes(draw_stripes);
- }
-
- if(node->hasAttribute("column_padding"))
- {
- S32 column_padding;
- node->getAttributeS32("column_padding", column_padding);
- setColumnPadding(column_padding);
- }
-}
-
-// static
-LLView* LLScrollListCtrl::fromXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFactory *factory)
-{
- std::string name("scroll_list");
- node->getAttributeString("name", name);
-
- LLRect rect;
- createRect(node, rect, parent, LLRect());
-
- BOOL multi_select = FALSE;
- node->getAttributeBOOL("multi_select", multi_select);
-
- BOOL draw_border = TRUE;
- node->getAttributeBOOL("draw_border", draw_border);
-
- BOOL draw_heading = FALSE;
- node->getAttributeBOOL("draw_heading", draw_heading);
-
- S32 search_column = 0;
- node->getAttributeS32("search_column", search_column);
-
- S32 sort_column = -1;
- node->getAttributeS32("sort_column", sort_column);
-
- BOOL sort_ascending = TRUE;
- node->getAttributeBOOL("sort_ascending", sort_ascending);
-
- LLUICtrlCallback callback = NULL;
-
- LLScrollListCtrl* scroll_list = new LLScrollListCtrl(
- name,
- rect,
- callback,
- NULL,
- multi_select,
- draw_border);
-
- scroll_list->setDisplayHeading(draw_heading);
- if (node->hasAttribute("heading_height"))
- {
- S32 heading_height;
- node->getAttributeS32("heading_height", heading_height);
- scroll_list->setHeadingHeight(heading_height);
- }
-
- scroll_list->setScrollListParameters(node);
-
- scroll_list->initFromXML(node, parent);
-
- scroll_list->setSearchColumn(search_column);
-
- LLSD columns;
- S32 index = 0;
- LLXMLNodePtr child;
- for (child = node->getFirstChild(); child.notNull(); child = child->getNextSibling())
- {
- if (child->hasName("column"))
- {
- std::string labelname("");
- child->getAttributeString("label", labelname);
-
- std::string columnname(labelname);
- child->getAttributeString("name", columnname);
-
- std::string sortname(columnname);
- child->getAttributeString("sort", sortname);
-
- BOOL sort_ascending = TRUE;
- child->getAttributeBOOL("sort_ascending", sort_ascending);
-
- std::string imagename;
- child->getAttributeString("image", imagename);
-
- BOOL columndynamicwidth = FALSE;
- child->getAttributeBOOL("dynamicwidth", columndynamicwidth);
-
- S32 columnwidth = -1;
- child->getAttributeS32("width", columnwidth);
-
- std::string tooltip;
- child->getAttributeString("tool_tip", tooltip);
-
- F32 columnrelwidth = 0.f;
- child->getAttributeF32("relwidth", columnrelwidth);
-
- LLFontGL::HAlign h_align = LLFontGL::LEFT;
- h_align = LLView::selectFontHAlign(child);
-
- columns[index]["name"] = columnname;
- columns[index]["sort"] = sortname;
- columns[index]["sort_ascending"] = sort_ascending;
- columns[index]["image"] = imagename;
- columns[index]["label"] = labelname;
- columns[index]["width"] = columnwidth;
- columns[index]["relwidth"] = columnrelwidth;
- columns[index]["dynamicwidth"] = columndynamicwidth;
- columns[index]["halign"] = (S32)h_align;
- columns[index]["tool_tip"] = tooltip;
-
- index++;
- }
- }
- scroll_list->setColumnHeadings(columns);
-
- if (sort_column >= 0)
- {
- scroll_list->sortByColumnIndex(sort_column, sort_ascending);
- }
-
- for (child = node->getFirstChild(); child.notNull(); child = child->getNextSibling())
- {
- if (child->hasName("row"))
- {
- LLUUID id;
- child->getAttributeUUID("id", id);
-
- LLSD row;
-
- row["id"] = id;
-
- S32 column_idx = 0;
- LLXMLNodePtr row_child;
- for (row_child = child->getFirstChild(); row_child.notNull(); row_child = row_child->getNextSibling())
- {
- if (row_child->hasName("column"))
- {
- std::string value = row_child->getTextContents();
-
- std::string columnname("");
- row_child->getAttributeString("name", columnname);
-
- std::string font("");
- row_child->getAttributeString("font", font);
-
- std::string font_style("");
- row_child->getAttributeString("font-style", font_style);
-
- row["columns"][column_idx]["column"] = columnname;
- row["columns"][column_idx]["value"] = value;
- row["columns"][column_idx]["font"] = font;
- row["columns"][column_idx]["font-style"] = font_style;
- column_idx++;
- }
- }
- scroll_list->addElement(row);
- }
- }
-
- std::string contents = node->getTextContents();
- if (!contents.empty())
- {
- typedef boost::tokenizer<boost::char_separator<char> > tokenizer;
- boost::char_separator<char> sep("\t\n");
- tokenizer tokens(contents, sep);
- tokenizer::iterator token_iter = tokens.begin();
-
- while(token_iter != tokens.end())
- {
- const std::string& line = *token_iter;
- scroll_list->addSimpleElement(line);
- ++token_iter;
- }
- }
-
- return scroll_list;
-}
-
// LLEditMenuHandler functions
// virtual
@@ -3068,20 +2441,27 @@ BOOL LLScrollListCtrl::canDeselect() const
void LLScrollListCtrl::addColumn(const LLSD& column, EAddPosition pos)
{
- std::string name = column["name"].asString();
+ LLScrollListColumn::Params p;
+ LLParamSDParser::instance().readSD(column, p);
+ addColumn(p, pos);
+}
+
+void LLScrollListCtrl::addColumn(const LLScrollListColumn::Params& column_params, EAddPosition pos)
+{
+ if (!column_params.validateBlock()) return;
+
+ std::string name = column_params.name;
// if no column name provided, just use ordinal as name
if (name.empty())
{
- std::ostringstream new_name;
- new_name << mColumnsIndexed.size();
- name = new_name.str();
+ name = llformat("%d", mColumnsIndexed.size());
}
+
if (mColumns.find(name) == mColumns.end())
{
// Add column
- mColumns[name] = LLScrollListColumn(column, this);
+ mColumns[name] = LLScrollListColumn(column_params, this);
LLScrollListColumn* new_column = &mColumns[name];
- new_column->mParentCtrl = this;
new_column->mIndex = mColumns.size()-1;
// Add button
@@ -3101,44 +2481,47 @@ void LLScrollListCtrl::addColumn(const LLSD& column, EAddPosition pos)
new_column->setWidth((mItemListRect.getWidth() - mTotalStaticColumnWidth - mTotalColumnPadding) / mNumDynamicWidthColumns);
}
S32 top = mItemListRect.mTop;
+
S32 left = mItemListRect.mLeft;
+ for (std::map<std::string, LLScrollListColumn>::iterator itor = mColumns.begin();
+ itor != mColumns.end();
+ ++itor)
{
- std::map<std::string, LLScrollListColumn>::iterator itor;
- for (itor = mColumns.begin(); itor != mColumns.end(); ++itor)
+ if (itor->second.mIndex < new_column->mIndex &&
+ itor->second.getWidth() > 0)
{
- if (itor->second.mIndex < new_column->mIndex &&
- itor->second.getWidth() > 0)
- {
- left += itor->second.getWidth() + mColumnPadding;
- }
+ left += itor->second.getWidth() + mColumnPadding;
}
}
- std::string button_name = "btn_" + name;
+
S32 right = left+new_column->getWidth();
if (new_column->mIndex != (S32)mColumns.size()-1)
{
right += mColumnPadding;
}
+
LLRect temp_rect = LLRect(left,top+mHeadingHeight,right,top);
- new_column->mHeader = new LLColumnHeader(button_name, temp_rect, new_column);
- if(column["image"].asString() != "")
+
+ LLScrollColumnHeader::Params params;
+ params.name = "btn_" + name;
+ params.rect = temp_rect;
+ params.column = new_column;
+ params.tool_tip = column_params.tool_tip;
+ params.tab_stop = false;
+ params.visible = mDisplayColumnHeaders;
+
+ if(column_params.header.image.isProvided())
{
- //new_column->mHeader->setScaleImage(false);
- new_column->mHeader->setImage(column["image"].asString());
+ params.image_selected = column_params.header.image;
+ params.image_unselected = column_params.header.image;
}
else
{
- new_column->mHeader->setLabel(new_column->mLabel);
- //new_column->mHeader->setLabel(new_column->mLabel);
+ params.label = column_params.header.label;
}
- new_column->mHeader->setToolTip(column["tool_tip"].asString());
-
- //RN: although it might be useful to change sort order with the keyboard,
- // mixing tab stops on child items along with the parent item is not supported yet
- new_column->mHeader->setTabStop(FALSE);
+ new_column->mHeader = LLUICtrlFactory::create<LLScrollColumnHeader>(params);
addChild(new_column->mHeader);
- new_column->mHeader->setVisible(mDisplayColumnHeaders);
sendChildToFront(mScrollbar);
}
@@ -3159,7 +2542,7 @@ void LLScrollListCtrl::onClickColumn(void *userdata)
S32 column_index = info->mIndex;
LLScrollListColumn* column = parent->mColumnsIndexed[info->mIndex];
- bool ascending = column->mSortAscending;
+ bool ascending = column->mSortDirection == LLScrollListColumn::ASCENDING;
if (column->mSortingColumn != column->mName
&& parent->mColumns.find(column->mSortingColumn) != parent->mColumns.end())
{
@@ -3178,7 +2561,7 @@ void LLScrollListCtrl::onClickColumn(void *userdata)
if (parent->mOnSortChangedCallback)
{
- parent->mOnSortChangedCallback(parent->getCallbackUserData());
+ parent->mOnSortChangedCallback();
}
}
@@ -3190,7 +2573,7 @@ std::string LLScrollListCtrl::getSortColumnName()
else return "";
}
-BOOL LLScrollListCtrl::needsSorting()
+BOOL LLScrollListCtrl::hasSortOrder() const
{
return !mSortColumns.empty();
}
@@ -3200,7 +2583,7 @@ void LLScrollListCtrl::clearColumns()
std::map<std::string, LLScrollListColumn>::iterator itor;
for (itor = mColumns.begin(); itor != mColumns.end(); ++itor)
{
- LLColumnHeader *header = itor->second.mHeader;
+ LLScrollColumnHeader *header = itor->second.mHeader;
if (header)
{
removeChild(header);
@@ -3215,13 +2598,13 @@ void LLScrollListCtrl::clearColumns()
void LLScrollListCtrl::setColumnLabel(const std::string& column, const std::string& label)
{
- std::map<std::string, LLScrollListColumn>::iterator itor = mColumns.find(column);
- if (itor != mColumns.end())
+ LLScrollListColumn* columnp = getColumn(column);
+ if (columnp)
{
- itor->second.mLabel = label;
- if (itor->second.mHeader)
+ columnp->mLabel = label;
+ if (columnp->mHeader)
{
- itor->second.mHeader->setLabel(label);
+ columnp->mHeader->setLabel(label);
}
}
}
@@ -3235,74 +2618,62 @@ LLScrollListColumn* LLScrollListCtrl::getColumn(S32 index)
return mColumnsIndexed[index];
}
-void LLScrollListCtrl::setColumnHeadings(LLSD headings)
+LLScrollListColumn* LLScrollListCtrl::getColumn(const std::string& name)
{
- mColumns.clear();
- LLSD::array_const_iterator itor;
- for (itor = headings.beginArray(); itor != headings.endArray(); ++itor)
+ column_map_t::iterator column_itor = mColumns.find(name);
+ if (column_itor != mColumns.end())
{
- addColumn(*itor);
+ return &column_itor->second;
}
+ return NULL;
}
-LLScrollListItem* LLScrollListCtrl::addElement(const LLSD& value, EAddPosition pos, void* userdata)
+
+LLScrollListItem* LLScrollListCtrl::addElement(const LLSD& element, EAddPosition pos, void* userdata)
{
- // ID
- LLSD id = value["id"];
+ LLScrollListItem::Params item_params;
+ LLParamSDParser::instance().readSD(element, item_params);
+ item_params.userdata = userdata;
+ return addRow(item_params, pos);
+}
- LLScrollListItem *new_item = new LLScrollListItem(id, userdata);
- if (value.has("enabled"))
- {
- new_item->setEnabled( value["enabled"].asBoolean() );
- }
+LLScrollListItem* LLScrollListCtrl::addRow(const LLScrollListItem::Params& item_p, EAddPosition pos)
+{
+ if (!item_p.validateBlock()) return NULL;
+ LLScrollListItem *new_item = new LLScrollListItem(item_p);
new_item->setNumColumns(mColumns.size());
// Add any columns we don't already have
- LLSD columns = value["columns"];
- LLSD::array_const_iterator itor;
- S32 col_index = 0 ;
- for (itor = columns.beginArray(); itor != columns.endArray(); ++itor)
- {
- if (itor->isUndefined())
- {
- // skip unused columns in item passed in
- continue;
- }
- std::string column = (*itor)["column"].asString();
+ S32 col_index = 0;
- LLScrollListColumn* columnp = NULL;
+ for(LLInitParam::ParamIterator<LLScrollListCell::Params>::const_iterator itor = item_p.columns().begin();
+ itor != item_p.columns().end();
+ ++itor)
+ {
+ LLScrollListCell::Params cell_p = *itor;
+ std::string column = cell_p.column;
// empty columns strings index by ordinal
if (column.empty())
{
- std::ostringstream new_name;
- new_name << col_index;
- column = new_name.str();
+ column = llformat("%d", col_index);
}
- std::map<std::string, LLScrollListColumn>::iterator column_itor;
- column_itor = mColumns.find(column);
- if (column_itor != mColumns.end())
- {
- columnp = &column_itor->second;
- }
+ LLScrollListColumn* columnp = getColumn(column);
// create new column on demand
if (!columnp)
{
- LLSD new_column;
- new_column["name"] = column;
- new_column["label"] = column;
+ LLScrollListColumn::Params new_column;
+ new_column.name = column;
+ new_column.header.label = column;
+
// if width supplied for column, use it, otherwise
// use adaptive width
- if (itor->has("width"))
- {
- new_column["width"] = (*itor)["width"];
- }
- else
+ if (cell_p.width.isProvided())
{
- new_column["dynamicwidth"] = true;
+ new_column.width.pixel_width = cell_p.width;
}
addColumn(new_column);
columnp = &mColumns[column];
@@ -3310,91 +2681,48 @@ LLScrollListItem* LLScrollListCtrl::addElement(const LLSD& value, EAddPosition p
}
S32 index = columnp->mIndex;
- S32 width = columnp->getWidth();
- LLFontGL::HAlign font_alignment = columnp->mFontAlignment;
- LLColor4 fcolor = LLColor4::black;
-
- LLSD value = (*itor)["value"];
- std::string fontname = (*itor)["font"].asString();
- std::string fontstyle = (*itor)["font-style"].asString();
- std::string type = (*itor)["type"].asString();
-
- if ((*itor).has("font-color"))
- {
- LLSD sd_color = (*itor)["font-color"];
- fcolor.setValue(sd_color);
- }
-
- BOOL has_color = (*itor).has("color");
- LLColor4 color = ((*itor)["color"]);
- BOOL enabled = !(*itor).has("enabled") || (*itor)["enabled"].asBoolean() == true;
+ cell_p.width.setIfNotProvided(columnp->getWidth());
- const LLFontGL *font = LLResMgr::getInstance()->getRes(fontname);
- if (!font)
- {
- font = LLResMgr::getInstance()->getRes( LLFONT_SANSSERIF_SMALL );
- }
- U8 font_style = LLFontGL::getStyleFromString(fontstyle);
+ LLScrollListCell* cell = LLScrollListCell::create(cell_p);
- if (type == "icon")
+ if (cell)
{
- LLScrollListIcon* cell = new LLScrollListIcon(value, width);
- if (has_color)
- {
- cell->setColor(color);
- }
new_item->setColumn(index, cell);
- }
- else if (type == "checkbox")
- {
- LLCheckBoxCtrl* ctrl = new LLCheckBoxCtrl(std::string("check"),
- LLRect(0, width, width, 0), std::string(" "));
- ctrl->setEnabled(enabled);
- ctrl->setValue(value);
- LLScrollListCheck* cell = new LLScrollListCheck(ctrl,width);
- if (has_color)
+ if (columnp->mHeader
+ && cell->isText()
+ && !cell->getValue().asString().empty())
{
- cell->setColor(color);
+ columnp->mHeader->setHasResizableElement(TRUE);
}
- new_item->setColumn(index, cell);
}
- else if (type == "separator")
- {
- LLScrollListSeparator* cell = new LLScrollListSeparator(width);
- if (has_color)
- {
- cell->setColor(color);
- }
- new_item->setColumn(index, cell);
- }
- else if (type == "date")
+
+ col_index++;
+ }
+
+ if (item_p.columns().empty())
+ {
+ if (mColumns.empty())
{
- LLScrollListDate* cell = new LLScrollListDate(value.asDate(), font, width, font_style, font_alignment);
- if (has_color)
- {
- cell->setColor(color);
- }
- new_item->setColumn(index, cell);
- if (columnp->mHeader && !value.asString().empty())
- {
- columnp->mHeader->setHasResizableElement(TRUE);
- }
+ LLScrollListColumn::Params new_column;
+ new_column.name = "0";
+
+ addColumn(new_column);
+ new_item->setNumColumns(mColumns.size());
}
- else
+
+ LLScrollListCell* cell = LLScrollListCell::create(LLScrollListCell::Params().value(item_p.value));
+ if (cell)
{
- LLScrollListText* cell = new LLScrollListText(value.asString(), font, width, font_style, font_alignment, fcolor, TRUE);
- if (has_color)
- {
- cell->setColor(color);
- }
- new_item->setColumn(index, cell);
- if (columnp->mHeader && !value.asString().empty())
+ LLScrollListColumn* columnp = &(mColumns.begin()->second);
+
+ new_item->setColumn(0, cell);
+ if (columnp->mHeader
+ && cell->isText()
+ && !cell->getValue().asString().empty())
{
columnp->mHeader->setHasResizableElement(TRUE);
}
}
-
- col_index++;
}
// add dummy cells for missing columns
@@ -3404,12 +2732,14 @@ LLScrollListItem* LLScrollListCtrl::addElement(const LLSD& value, EAddPosition p
if (new_item->getColumn(column_idx) == NULL)
{
LLScrollListColumn* column_ptr = &column_it->second;
- new_item->setColumn(column_idx, new LLScrollListText(LLStringUtil::null, LLResMgr::getInstance()->getRes( LLFONT_SANSSERIF_SMALL ), column_ptr->getWidth(), LLFontGL::NORMAL));
+ LLScrollListCell::Params cell_p;
+ cell_p.width = column_ptr->getWidth();
+
+ new_item->setColumn(column_idx, new LLScrollListSpacer(cell_p));
}
}
addItem(new_item, pos);
-
return new_item;
}
@@ -3422,14 +2752,13 @@ LLScrollListItem* LLScrollListCtrl::addSimpleElement(const std::string& value, E
entry_id = value;
}
- LLScrollListItem *new_item = new LLScrollListItem(entry_id);
-
- const LLFontGL *font = LLResMgr::getInstance()->getRes( LLFONT_SANSSERIF_SMALL );
-
- new_item->addColumn(value, font, getRect().getWidth());
-
- addItem(new_item, pos);
- return new_item;
+ LLScrollListItem::Params item_params;
+ item_params.value(entry_id);
+ item_params.columns.add()
+ .value(value)
+ .font(LLFontGL::getFontSansSerifSmall());
+
+ return addRow(item_params, pos);
}
void LLScrollListCtrl::setValue(const LLSD& value )
@@ -3530,484 +2859,3 @@ void LLScrollListCtrl::onFocusLost()
LLUICtrl::onFocusLost();
}
-LLColumnHeader::LLColumnHeader(const std::string& label, const LLRect &rect, LLScrollListColumn* column, const LLFontGL* fontp) :
- LLComboBox(label, rect, label, NULL, NULL),
- mColumn(column),
- mOrigLabel(label),
- mShowSortOptions(FALSE),
- mHasResizableElement(FALSE)
-{
- mListPosition = LLComboBox::ABOVE;
- setCommitCallback(onSelectSort);
- setCallbackUserData(this);
- mButton->setTabStop(FALSE);
- // require at least two frames between mouse down and mouse up event to capture intentional "hold" not just bad framerate
- mButton->setHeldDownDelay(LLUI::sConfigGroup->getF32("ColumnHeaderDropDownDelay"), 2);
- mButton->setHeldDownCallback(onHeldDown);
- mButton->setClickedCallback(onClick);
- mButton->setMouseDownCallback(onMouseDown);
-
- mButton->setCallbackUserData(this);
- mButton->setToolTip(label);
-
- mAscendingText = std::string("[LOW]...[HIGH](Ascending)"); // *TODO: Translate
- mDescendingText = std::string("[HIGH]...[LOW](Descending)"); // *TODO: Translate
-
- mList->reshape(llmax(mList->getRect().getWidth(), 110, getRect().getWidth()), mList->getRect().getHeight());
-
- // resize handles on left and right
- const S32 RESIZE_BAR_THICKNESS = 3;
- mResizeBar = new LLResizeBar(
- std::string("resizebar"),
- this,
- LLRect( getRect().getWidth() - RESIZE_BAR_THICKNESS, getRect().getHeight(), getRect().getWidth(), 0),
- MIN_COLUMN_WIDTH, S32_MAX, LLResizeBar::RIGHT );
- addChild(mResizeBar);
-
- mResizeBar->setEnabled(FALSE);
-}
-
-LLColumnHeader::~LLColumnHeader()
-{
-}
-
-void LLColumnHeader::draw()
-{
- BOOL draw_arrow = !mColumn->mLabel.empty() && mColumn->mParentCtrl->isSorted() && mColumn->mParentCtrl->getSortColumnName() == mColumn->mSortingColumn;
-
- BOOL is_ascending = mColumn->mParentCtrl->getSortAscending();
- mButton->setImageOverlay(is_ascending ? "up_arrow.tga" : "down_arrow.tga", LLFontGL::RIGHT, draw_arrow ? LLColor4::white : LLColor4::transparent);
- mArrowImage = mButton->getImageOverlay();
-
- //BOOL clip = getRect().mRight > mColumn->mParentCtrl->getItemListRect().getWidth();
- //LLGLEnable scissor_test(clip ? GL_SCISSOR_TEST : GL_FALSE);
-
- //LLRect column_header_local_rect(-getRect().mLeft, getRect().getHeight(), mColumn->mParentCtrl->getItemListRect().getWidth() - getRect().mLeft, 0);
- //LLUI::setScissorRegionLocal(column_header_local_rect);
-
- // Draw children
- LLComboBox::draw();
-
- if (mList->getVisible())
- {
- // sync sort order with list selection every frame
- mColumn->mParentCtrl->sortByColumn(mColumn->mSortingColumn, getCurrentIndex() == 0);
- }
-}
-
-BOOL LLColumnHeader::handleDoubleClick(S32 x, S32 y, MASK mask)
-{
- if (canResize() && mResizeBar->getRect().pointInRect(x, y))
- {
- // reshape column to max content width
- LLRect column_rect = getRect();
- column_rect.mRight = column_rect.mLeft + mColumn->mMaxContentWidth;
- userSetShape(column_rect);
- }
- else
- {
- onClick(this);
- }
- return TRUE;
-}
-
-void LLColumnHeader::setImage(const std::string &image_name)
-{
- if (mButton)
- {
- mButton->setImageSelected(image_name);
- mButton->setImageUnselected(image_name);
- }
-}
-
-//static
-void LLColumnHeader::onClick(void* user_data)
-{
- LLColumnHeader* headerp = (LLColumnHeader*)user_data;
- if (!headerp) return;
-
- LLScrollListColumn* column = headerp->mColumn;
- if (!column) return;
-
- if (headerp->mList->getVisible())
- {
- headerp->hideList();
- }
-
- LLScrollListCtrl::onClickColumn(column);
-
- // propagate new sort order to sort order list
- headerp->mList->selectNthItem(column->mParentCtrl->getSortAscending() ? 0 : 1);
-}
-
-//static
-void LLColumnHeader::onMouseDown(void* user_data)
-{
- // for now, do nothing but block the normal showList() behavior
- return;
-}
-
-//static
-void LLColumnHeader::onHeldDown(void* user_data)
-{
- LLColumnHeader* headerp = (LLColumnHeader*)user_data;
- headerp->showList();
-}
-
-void LLColumnHeader::showList()
-{
- if (mShowSortOptions)
- {
- //LLSD item_val = mColumn->mParentCtrl->getFirstData()->getValue();
- mOrigLabel = mButton->getLabelSelected();
-
- // move sort column over to this column and do initial sort
- mColumn->mParentCtrl->sortByColumn(mColumn->mSortingColumn, mColumn->mParentCtrl->getSortAscending());
-
- std::string low_item_text;
- std::string high_item_text;
-
- LLScrollListItem* itemp = mColumn->mParentCtrl->getFirstData();
- if (itemp)
- {
- LLScrollListCell* cell = itemp->getColumn(mColumn->mIndex);
- if (cell && cell->isText())
- {
- if (mColumn->mParentCtrl->getSortAscending())
- {
- low_item_text = cell->getValue().asString();
- }
- else
- {
- high_item_text = cell->getValue().asString();
- }
- }
- }
-
- itemp = mColumn->mParentCtrl->getLastData();
- if (itemp)
- {
- LLScrollListCell* cell = itemp->getColumn(mColumn->mIndex);
- if (cell && cell->isText())
- {
- if (mColumn->mParentCtrl->getSortAscending())
- {
- high_item_text = cell->getValue().asString();
- }
- else
- {
- low_item_text = cell->getValue().asString();
- }
- }
- }
-
- LLStringUtil::truncate(low_item_text, 3);
- LLStringUtil::truncate(high_item_text, 3);
-
- std::string ascending_string;
- std::string descending_string;
-
- if (low_item_text.empty() || high_item_text.empty())
- {
- ascending_string = "Ascending";
- descending_string = "Descending";
- }
- else
- {
- mAscendingText.setArg("[LOW]", low_item_text);
- mAscendingText.setArg("[HIGH]", high_item_text);
- mDescendingText.setArg("[LOW]", low_item_text);
- mDescendingText.setArg("[HIGH]", high_item_text);
- ascending_string = mAscendingText.getString();
- descending_string = mDescendingText.getString();
- }
-
- S32 text_width = LLFontGL::getFontSansSerifSmall()->getWidth(ascending_string);
- text_width = llmax(text_width, LLFontGL::getFontSansSerifSmall()->getWidth(descending_string)) + 10;
- text_width = llmax(text_width, getRect().getWidth() - 30);
-
- mList->getColumn(0)->setWidth(text_width);
- ((LLScrollListText*)mList->getFirstData()->getColumn(0))->setText(ascending_string);
- ((LLScrollListText*)mList->getLastData()->getColumn(0))->setText(descending_string);
-
- mList->reshape(llmax(text_width + 30, 110, getRect().getWidth()), mList->getRect().getHeight());
-
- LLComboBox::showList();
- }
-}
-
-//static
-void LLColumnHeader::onSelectSort(LLUICtrl* ctrl, void* user_data)
-{
- LLColumnHeader* headerp = (LLColumnHeader*)user_data;
- if (!headerp) return;
-
- LLScrollListColumn* column = headerp->mColumn;
- if (!column) return;
- LLScrollListCtrl *parent = column->mParentCtrl;
- if (!parent) return;
-
- if (headerp->getCurrentIndex() == 0)
- {
- // ascending
- parent->sortByColumn(column->mSortingColumn, TRUE);
- }
- else
- {
- // descending
- parent->sortByColumn(column->mSortingColumn, FALSE);
- }
-
- // restore original column header
- headerp->setLabel(headerp->mOrigLabel);
-}
-
-LLView* LLColumnHeader::findSnapEdge(S32& new_edge_val, const LLCoordGL& mouse_dir, ESnapEdge snap_edge, ESnapType snap_type, S32 threshold, S32 padding)
-{
- // this logic assumes dragging on right
- llassert(snap_edge == SNAP_RIGHT);
-
- // use higher snap threshold for column headers
- threshold = llmin(threshold, 10);
-
- LLRect snap_rect = getSnapRect();
-
- S32 snap_delta = mColumn->mMaxContentWidth - snap_rect.getWidth();
-
- // x coord growing means column growing, so same signs mean we're going in right direction
- if (llabs(snap_delta) <= threshold && mouse_dir.mX * snap_delta > 0 )
- {
- new_edge_val = snap_rect.mRight + snap_delta;
- }
- else
- {
- LLScrollListColumn* next_column = mColumn->mParentCtrl->getColumn(mColumn->mIndex + 1);
- while (next_column)
- {
- if (next_column->mHeader)
- {
- snap_delta = (next_column->mHeader->getSnapRect().mRight - next_column->mMaxContentWidth) - snap_rect.mRight;
- if (llabs(snap_delta) <= threshold && mouse_dir.mX * snap_delta > 0 )
- {
- new_edge_val = snap_rect.mRight + snap_delta;
- }
- break;
- }
- next_column = mColumn->mParentCtrl->getColumn(next_column->mIndex + 1);
- }
- }
-
- return this;
-}
-
-void LLColumnHeader::userSetShape(const LLRect& new_rect)
-{
- S32 new_width = new_rect.getWidth();
- S32 delta_width = new_width - (getRect().getWidth() /*+ mColumn->mParentCtrl->getColumnPadding()*/);
-
- if (delta_width != 0)
- {
- S32 remaining_width = -delta_width;
- S32 col;
- for (col = mColumn->mIndex + 1; col < mColumn->mParentCtrl->getNumColumns(); col++)
- {
- LLScrollListColumn* columnp = mColumn->mParentCtrl->getColumn(col);
- if (!columnp) continue;
-
- if (columnp->mHeader && columnp->mHeader->canResize())
- {
- // how many pixels in width can this column afford to give up?
- S32 resize_buffer_amt = llmax(0, columnp->getWidth() - MIN_COLUMN_WIDTH);
-
- // user shrinking column, need to add width to other columns
- if (delta_width < 0)
- {
- if (/*!columnp->mDynamicWidth && */columnp->getWidth() > 0)
- {
- // statically sized column, give all remaining width to this column
- columnp->setWidth(columnp->getWidth() + remaining_width);
- if (columnp->mRelWidth > 0.f)
- {
- columnp->mRelWidth = (F32)columnp->getWidth() / (F32)mColumn->mParentCtrl->getItemListRect().getWidth();
- }
- // all padding went to this widget, we're done
- break;
- }
- }
- else
- {
- // user growing column, need to take width from other columns
- remaining_width += resize_buffer_amt;
-
- if (/*!columnp->mDynamicWidth && */columnp->getWidth() > 0)
- {
- columnp->setWidth(columnp->getWidth() - llmin(columnp->getWidth() - MIN_COLUMN_WIDTH, delta_width));
- if (columnp->mRelWidth > 0.f)
- {
- columnp->mRelWidth = (F32)columnp->getWidth() / (F32)mColumn->mParentCtrl->getItemListRect().getWidth();
- }
- }
-
- if (remaining_width >= 0)
- {
- // width sucked up from neighboring columns, done
- break;
- }
- }
- }
- }
-
- // clamp resize amount to maximum that can be absorbed by other columns
- if (delta_width > 0)
- {
- delta_width += llmin(remaining_width, 0);
- }
-
- // propagate constrained delta_width to new width for this column
- new_width = getRect().getWidth() + delta_width - mColumn->mParentCtrl->getColumnPadding();
-
- // use requested width
- mColumn->setWidth(new_width);
-
- // update proportional spacing
- if (mColumn->mRelWidth > 0.f)
- {
- mColumn->mRelWidth = (F32)new_width / (F32)mColumn->mParentCtrl->getItemListRect().getWidth();
- }
-
- // tell scroll list to layout columns again
- // do immediate update to get proper feedback to resize handle
- // which needs to know how far the resize actually went
- mColumn->mParentCtrl->updateColumns();
- }
-}
-
-void LLColumnHeader::setHasResizableElement(BOOL resizable)
-{
- // for now, dynamically spaced columns can't be resized
-// if (mColumn->mDynamicWidth) return;
-
- if (mHasResizableElement != resizable)
- {
- mColumn->mParentCtrl->dirtyColumns();
- mHasResizableElement = resizable;
- }
-}
-
-void LLColumnHeader::updateResizeBars()
-{
- S32 num_resizable_columns = 0;
- S32 col;
- for (col = 0; col < mColumn->mParentCtrl->getNumColumns(); col++)
- {
- LLScrollListColumn* columnp = mColumn->mParentCtrl->getColumn(col);
- if (columnp->mHeader && columnp->mHeader->canResize())
- {
- num_resizable_columns++;
- }
- }
-
- S32 num_resizers_enabled = 0;
-
- // now enable/disable resize handles on resizable columns if we have at least two
- for (col = 0; col < mColumn->mParentCtrl->getNumColumns(); col++)
- {
- LLScrollListColumn* columnp = mColumn->mParentCtrl->getColumn(col);
- if (!columnp->mHeader) continue;
- BOOL enable = num_resizable_columns >= 2 && num_resizers_enabled < (num_resizable_columns - 1) && columnp->mHeader->canResize();
- columnp->mHeader->enableResizeBar(enable);
- if (enable)
- {
- num_resizers_enabled++;
- }
- }
-}
-
-void LLColumnHeader::enableResizeBar(BOOL enable)
-{
- // for now, dynamically spaced columns can't be resized
- //if (!mColumn->mDynamicWidth)
- {
- mResizeBar->setEnabled(enable);
- }
-}
-
-BOOL LLColumnHeader::canResize()
-{
- return getVisible() && (mHasResizableElement || mColumn->mDynamicWidth);
-}
-
-void LLScrollListColumn::setWidth(S32 width)
-{
- if (!mDynamicWidth && mRelWidth <= 0.f)
- {
- mParentCtrl->updateStaticColumnWidth(this, width);
- }
- mWidth = width;
-}
-
-// Default constructor
-LLScrollListColumn::LLScrollListColumn() :
- mName(),
- mSortingColumn(),
- mSortAscending(TRUE),
- mLabel(),
- mWidth(-1),
- mRelWidth(-1.0),
- mDynamicWidth(FALSE),
- mMaxContentWidth(0),
- mIndex(-1),
- mParentCtrl(NULL),
- mHeader(NULL),
- mFontAlignment(LLFontGL::LEFT)
-{ }
-
-LLScrollListColumn::LLScrollListColumn(const LLSD &sd, LLScrollListCtrl* parent) :
- mWidth(0),
- mIndex (-1),
- mParentCtrl(parent),
- mHeader(NULL),
- mMaxContentWidth(0),
- mDynamicWidth(FALSE),
- mRelWidth(-1.f)
-{
- mName = sd.get("name").asString();
- mSortingColumn = mName;
- if (sd.has("sort"))
- {
- mSortingColumn = sd.get("sort").asString();
- }
- mSortAscending = TRUE;
- if (sd.has("sort_ascending"))
- {
- mSortAscending = sd.get("sort_ascending").asBoolean();
- }
- mLabel = sd.get("label").asString();
- if (sd.has("relwidth") && (F32)sd.get("relwidth").asReal() > 0)
- {
- mRelWidth = (F32)sd.get("relwidth").asReal();
- if (mRelWidth < 0) mRelWidth = 0;
- if (mRelWidth > 1) mRelWidth = 1;
- mDynamicWidth = FALSE;
- }
- else if(sd.has("dynamicwidth") && (BOOL)sd.get("dynamicwidth").asBoolean() == TRUE)
- {
- mDynamicWidth = TRUE;
- mRelWidth = -1;
- }
- else
- {
-
- setWidth(sd.get("width").asInteger());
- }
-
- if (sd.has("halign"))
- {
- mFontAlignment = (LLFontGL::HAlign)llclamp(sd.get("halign").asInteger(), (S32)LLFontGL::LEFT, (S32)LLFontGL::HCENTER);
- }
- else
- {
- mFontAlignment = LLFontGL::LEFT;
- }
-
-}
diff --git a/indra/llui/llscrolllistctrl.h b/indra/llui/llscrolllistctrl.h
index 72d8894afa..253a58ab73 100644
--- a/indra/llui/llscrolllistctrl.h
+++ b/indra/llui/llscrolllistctrl.h
@@ -1,5 +1,8 @@
/**
* @file llscrolllistctrl.h
+ * @brief A scrolling list of items. This is the one you want to use
+ * in UI code. LLScrollListCell, LLScrollListItem, etc. are utility
+ * classes.
*
* $LicenseInfo:firstyear=2001&license=viewergpl$
*
@@ -37,346 +40,108 @@
#include "lluictrl.h"
#include "llctrlselectioninterface.h"
-#include "lldarray.h"
+//#include "lldarray.h"
#include "llfontgl.h"
#include "llui.h"
-#include "llstring.h"
-#include "llimagegl.h"
+#include "llstring.h" // LLWString
#include "lleditmenuhandler.h"
#include "llframetimer.h"
-#include "llcheckboxctrl.h"
-#include "llcombobox.h"
+
#include "llscrollbar.h"
-#include "llresizebar.h"
#include "lldate.h"
+#include "llscrolllistitem.h"
+#include "llscrolllistcolumn.h"
-/*
- * Represents a cell in a scrollable table.
- *
- * Sub-classes must return height and other properties
- * though width accessors are implemented by the base class.
- * It is therefore important for sub-class constructors to call
- * setWidth() with realistic values.
- */
-class LLScrollListCell
-{
-public:
- LLScrollListCell(S32 width = 0) : mWidth(width) {};
- virtual ~LLScrollListCell() {};
- virtual void draw(const LLColor4& color, const LLColor4& highlight_color) const = 0; // truncate to given width, if possible
- virtual S32 getWidth() const {return mWidth;}
- virtual S32 getContentWidth() const { return 0; }
- virtual S32 getHeight() const = 0;
- virtual const LLSD getValue() const { return LLStringUtil::null; }
- virtual void setValue(const LLSD& value) { }
- virtual BOOL getVisible() const { return TRUE; }
- virtual void setWidth(S32 width) { mWidth = width; }
- virtual void highlightText(S32 offset, S32 num_chars) {}
- virtual BOOL isText() const = 0;
- virtual void setColor(const LLColor4&) {}
- virtual void onCommit() {};
-
- virtual BOOL handleClick() { return FALSE; }
- virtual void setEnabled(BOOL enable) { }
-
-private:
- S32 mWidth;
-};
-
-/*
- * Draws a horizontal line.
- */
-class LLScrollListSeparator : public LLScrollListCell
-{
-public:
- LLScrollListSeparator(S32 width);
- virtual ~LLScrollListSeparator() {};
- virtual void draw(const LLColor4& color, const LLColor4& highlight_color) const; // truncate to given width, if possible
- virtual S32 getHeight() const;
- virtual BOOL isText() const { return FALSE; }
-};
-
-/*
- * Cell displaying a text label.
- */
-class LLScrollListText : public LLScrollListCell
-{
-public:
- LLScrollListText( const std::string& text, const LLFontGL* font, S32 width = 0, U8 font_style = LLFontGL::NORMAL, LLFontGL::HAlign font_alignment = LLFontGL::LEFT, LLColor4& color = LLColor4::black, BOOL use_color = FALSE, BOOL visible = TRUE);
- /*virtual*/ ~LLScrollListText();
-
- virtual void draw(const LLColor4& color, const LLColor4& highlight_color) const;
- virtual S32 getContentWidth() const;
- virtual S32 getHeight() const;
- virtual void setValue(const LLSD& value);
- virtual const LLSD getValue() const;
- virtual BOOL getVisible() const;
- virtual void highlightText(S32 offset, S32 num_chars);
-
- virtual void setColor(const LLColor4&);
- virtual BOOL isText() const;
-
- void setText(const LLStringExplicit& text);
- void setFontStyle(const U8 font_style) { mFontStyle = font_style; }
-
-private:
- LLUIString mText;
- const LLFontGL* mFont;
- LLColor4 mColor;
- U8 mUseColor;
- U8 mFontStyle;
- LLFontGL::HAlign mFontAlignment;
- BOOL mVisible;
- S32 mHighlightCount;
- S32 mHighlightOffset;
-
- LLPointer<LLUIImage> mRoundedRectImage;
-
- static U32 sCount;
-};
-
-
-class LLScrollListDate : public LLScrollListText
-{
-public:
- LLScrollListDate( const LLDate& date, const LLFontGL* font, S32 width=0, U8 font_style = LLFontGL::NORMAL, LLFontGL::HAlign font_alignment = LLFontGL::LEFT, LLColor4& color = LLColor4::black, BOOL use_color = FALSE, BOOL visible = TRUE);
- virtual void setValue(const LLSD& value);
- virtual const LLSD getValue() const;
-
-private:
- LLDate mDate;
-};
-
-/*
- * Cell displaying an image.
- */
-class LLScrollListIcon : public LLScrollListCell
-{
-public:
- LLScrollListIcon( LLUIImagePtr icon, S32 width = 0);
- LLScrollListIcon(const LLSD& value, S32 width = 0);
- /*virtual*/ ~LLScrollListIcon();
- virtual void draw(const LLColor4& color, const LLColor4& highlight_color) const;
- virtual S32 getWidth() const;
- virtual S32 getHeight() const { return mIcon ? mIcon->getHeight() : 0; }
- virtual const LLSD getValue() const { return mIcon.isNull() ? LLStringUtil::null : mIcon->getName(); }
- virtual void setColor(const LLColor4&);
- virtual BOOL isText()const { return FALSE; }
- virtual void setValue(const LLSD& value);
-
-private:
- LLUIImagePtr mIcon;
- LLColor4 mColor;
-};
-
-/*
- * An interactive cell containing a check box.
- */
-class LLScrollListCheck : public LLScrollListCell
-{
-public:
- LLScrollListCheck( LLCheckBoxCtrl* check_box, S32 width = 0);
- /*virtual*/ ~LLScrollListCheck();
- virtual void draw(const LLColor4& color, const LLColor4& highlight_color) const;
- virtual S32 getHeight() const { return 0; }
- virtual const LLSD getValue() const { return mCheckBox->getValue(); }
- virtual void setValue(const LLSD& value) { mCheckBox->setValue(value); }
- virtual void onCommit() { mCheckBox->onCommit(); }
-
- virtual BOOL handleClick();
- virtual void setEnabled(BOOL enable) { mCheckBox->setEnabled(enable); }
-
- LLCheckBoxCtrl* getCheckBox() { return mCheckBox; }
- virtual BOOL isText() const { return FALSE; }
-
-private:
- LLCheckBoxCtrl* mCheckBox;
-};
-
-/*
- * A simple data class describing a column within a scroll list.
- */
-class LLScrollListColumn
-{
-public:
- LLScrollListColumn();
- LLScrollListColumn(const LLSD &sd, LLScrollListCtrl* parent);
-
- void setWidth(S32 width);
- S32 getWidth() const { return mWidth; }
-
- // Public data is fine so long as this remains a simple struct-like data class.
- // If it ever gets any smarter than that, these should all become private
- // with protected or public accessor methods added as needed. -MG
- std::string mName;
- std::string mSortingColumn;
- BOOL mSortAscending;
- std::string mLabel;
- F32 mRelWidth;
- BOOL mDynamicWidth;
- S32 mMaxContentWidth;
- S32 mIndex;
- LLScrollListCtrl* mParentCtrl;
- class LLColumnHeader* mHeader;
- LLFontGL::HAlign mFontAlignment;
+class LLScrollListCell;
+class LLTextBox;
-private:
- S32 mWidth;
-
-};
-
-class LLColumnHeader : public LLComboBox
-{
-public:
- LLColumnHeader(const std::string& label, const LLRect &rect, LLScrollListColumn* column, const LLFontGL *font = NULL);
- ~LLColumnHeader();
-
- /*virtual*/ void draw();
- /*virtual*/ BOOL handleDoubleClick(S32 x, S32 y, MASK mask);
-
- /*virtual*/ void showList();
- /*virtual*/ LLView* findSnapEdge(S32& new_edge_val, const LLCoordGL& mouse_dir, ESnapEdge snap_edge, ESnapType snap_type, S32 threshold, S32 padding);
- /*virtual*/ void userSetShape(const LLRect& new_rect);
-
- void setImage(const std::string &image_name);
- LLScrollListColumn* getColumn() { return mColumn; }
- void setHasResizableElement(BOOL resizable);
- void updateResizeBars();
- BOOL canResize();
- void enableResizeBar(BOOL enable);
- std::string getLabel() { return mOrigLabel; }
-
- static void onSelectSort(LLUICtrl* ctrl, void* user_data);
- static void onClick(void* user_data);
- static void onMouseDown(void* user_data);
- static void onHeldDown(void* user_data);
-
-private:
- LLScrollListColumn* mColumn;
- LLResizeBar* mResizeBar;
- std::string mOrigLabel;
- LLUIString mAscendingText;
- LLUIString mDescendingText;
- BOOL mShowSortOptions;
- BOOL mHasResizableElement;
-};
-
-class LLScrollListItem
+class LLScrollListCtrl : public LLUICtrl, public LLEditMenuHandler,
+ public LLCtrlListInterface, public LLCtrlScrollInterface
{
public:
- LLScrollListItem( BOOL enabled = TRUE, void* userdata = NULL, const LLUUID& uuid = LLUUID::null )
- : mSelected(FALSE), mEnabled( enabled ), mUserdata( userdata ), mItemValue( uuid ), mColumns() {}
- LLScrollListItem( LLSD item_value, void* userdata = NULL )
- : mSelected(FALSE), mEnabled( TRUE ), mUserdata( userdata ), mItemValue( item_value ), mColumns() {}
-
- virtual ~LLScrollListItem();
-
- void setSelected( BOOL b ) { mSelected = b; }
- BOOL getSelected() const { return mSelected; }
-
- void setEnabled( BOOL b );
- BOOL getEnabled() const { return mEnabled; }
-
- void setUserdata( void* userdata ) { mUserdata = userdata; }
- void* getUserdata() const { return mUserdata; }
-
- LLUUID getUUID() const { return mItemValue.asUUID(); }
- LLSD getValue() const { return mItemValue; }
+ struct Contents : public LLInitParam::Block<Contents>
+ {
+ Multiple<LLScrollListColumn::Params> columns;
+ Multiple<LLScrollListItem::Params> rows;
- // If width = 0, just use the width of the text. Otherwise override with
- // specified width in pixels.
- void addColumn( const std::string& text, const LLFontGL* font, S32 width = 0 , U8 font_style = LLFontGL::NORMAL, LLFontGL::HAlign font_alignment = LLFontGL::LEFT, BOOL visible = TRUE)
- { mColumns.push_back( new LLScrollListText(text, font, width, font_style, font_alignment, LLColor4::black, FALSE, visible) ); }
+ //Multiple<Contents> groups;
- void addColumn( LLUIImagePtr icon, S32 width = 0 )
- { mColumns.push_back( new LLScrollListIcon(icon, width) ); }
+ Contents();
+ };
- void addColumn( LLCheckBoxCtrl* check, S32 width = 0 )
- { mColumns.push_back( new LLScrollListCheck(check,width) ); }
-
- void setNumColumns(S32 columns);
-
- void setColumn( S32 column, LLScrollListCell *cell );
+ // *TODO: Add callbacks to Params
+ typedef boost::function<void (void)> callback_t;
- S32 getNumColumns() const { return mColumns.size(); }
-
- LLScrollListCell *getColumn(const S32 i) const { if (0 <= i && i < (S32)mColumns.size()) { return mColumns[i]; } return NULL; }
-
- std::string getContentsCSV() const;
-
- virtual void draw(const LLRect& rect, const LLColor4& fg_color, const LLColor4& bg_color, const LLColor4& highlight_color, S32 column_padding);
+ struct Params : public LLInitParam::Block<Params, LLUICtrl::Params>
+ {
+ // behavioral flags
+ Optional<bool> multi_select,
+ commit_on_keyboard_movement;
+
+ // display flags
+ Optional<bool> has_border,
+ draw_heading,
+ draw_stripes,
+ background_visible;
+
+ // layout
+ Optional<S32> column_padding,
+ heading_height;
+
+ // sort and search behavior
+ Optional<S32> search_column,
+ sort_column;
+ Optional<bool> sort_ascending;
+
+ // colors
+ Optional<LLUIColor> fg_unselected_color,
+ fg_selected_color,
+ bg_selected_color,
+ fg_disable_color,
+ bg_writeable_color,
+ bg_readonly_color,
+ bg_stripe_color,
+ hovered_color,
+ highlighted_color;
+
+ Optional<Contents> contents;
+
+ Params();
+ };
-private:
- BOOL mSelected;
- BOOL mEnabled;
- void* mUserdata;
- LLSD mItemValue;
- std::vector<LLScrollListCell *> mColumns;
-};
-
-/*
- * A graphical control representing a scrollable table.
- * Cells in the table can be simple text or more complicated things
- * such as icons or even interactive elements like check boxes.
- */
-class LLScrollListItemComment : public LLScrollListItem
-{
-public:
- LLScrollListItemComment(const std::string& comment_string, const LLColor4& color);
-
- /*virtual*/ void draw(const LLRect& rect, const LLColor4& fg_color, const LLColor4& bg_color, const LLColor4& highlight_color, S32 column_padding);
-private:
- LLColor4 mColor;
-};
-
-class LLScrollListItemSeparator : public LLScrollListItem
-{
-public:
- LLScrollListItemSeparator();
+protected:
+ friend class LLUICtrlFactory;
- /*virtual*/ void draw(const LLRect& rect, const LLColor4& fg_color, const LLColor4& bg_color, const LLColor4& highlight_color, S32 column_padding);
-};
+ LLScrollListCtrl(const Params&);
-class LLScrollListCtrl : public LLUICtrl, public LLEditMenuHandler,
- public LLCtrlListInterface, public LLCtrlScrollInterface
-{
public:
- LLScrollListCtrl(
- const std::string& name,
- const LLRect& rect,
- void (*commit_callback)(LLUICtrl*, void*),
- void* callback_userdata,
- BOOL allow_multiple_selection,
- BOOL draw_border = TRUE);
-
virtual ~LLScrollListCtrl();
- virtual LLXMLNodePtr getXML(bool save_children = true) const;
- void setScrollListParameters(LLXMLNodePtr node);
- static LLView* fromXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFactory *factory);
-
S32 isEmpty() const;
void deleteAllItems() { clearRows(); }
// Sets an array of column descriptors
- void setColumnHeadings(LLSD headings);
+ void setColumnHeadings(const LLSD& headings);
void sortByColumnIndex(U32 column, BOOL ascending);
// LLCtrlListInterface functions
virtual S32 getItemCount() const;
// Adds a single column descriptor: ["name" : string, "label" : string, "width" : integer, "relwidth" : integer ]
- virtual void addColumn(const LLSD& column, EAddPosition pos = ADD_BOTTOM);
+ virtual void addColumn(const LLScrollListColumn::Params& column, EAddPosition pos = ADD_BOTTOM);
+ virtual void addColumn(const LLSD& column, EAddPosition pos = ADD_BOTTOM);
virtual void clearColumns();
virtual void setColumnLabel(const std::string& column, const std::string& label);
-
+ virtual bool preProcessChildNode(LLXMLNodePtr child);
virtual LLScrollListColumn* getColumn(S32 index);
+ virtual LLScrollListColumn* getColumn(const std::string& name);
virtual S32 getNumColumns() const { return mColumnsIndexed.size(); }
// Adds a single element, from an array of:
// "columns" => [ "column" => column name, "value" => value, "type" => type, "font" => font, "font-style" => style ], "id" => uuid
// Creates missing columns automatically.
- virtual LLScrollListItem* addElement(const LLSD& value, EAddPosition pos = ADD_BOTTOM, void* userdata = NULL);
+ virtual LLScrollListItem* addElement(const LLSD& element, EAddPosition pos = ADD_BOTTOM, void* userdata = NULL);
+ virtual LLScrollListItem* addRow(const LLScrollListItem::Params& value, EAddPosition pos = ADD_BOTTOM);
// Simple add element. Takes a single array of:
// [ "value" => value, "font" => font, "font-style" => style ]
virtual void clearRows(); // clears all elements
@@ -421,10 +186,14 @@ public:
void deleteSelectedItems();
void deselectAllItems(BOOL no_commit_on_change = FALSE); // by default, go ahead and commit on selection change
- void highlightNthItem( S32 index );
- void setDoubleClickCallback( void (*cb)(void*) ) { mOnDoubleClickCallback = cb; }
- void setMaximumSelectCallback( void (*cb)(void*) ) { mOnMaximumSelectCallback = cb; }
- void setSortChangedCallback( void (*cb)(void*) ) { mOnSortChangedCallback = cb; }
+ void clearHighlightedItems();
+ void mouseOverHighlightNthItem( S32 index );
+
+ void setDoubleClickCallback( callback_t cb ) { mOnDoubleClickCallback = cb; }
+ void setMaximumSelectCallback( callback_t cb) { mOnMaximumSelectCallback = cb; }
+ void setSortChangedCallback( callback_t cb) { mOnSortChangedCallback = cb; }
+ // Convenience function; *TODO: replace with setter above + boost::bind() in calling code
+ void setDoubleClickCallback( boost::function<void (void* userdata)> cb, void* userdata) { mOnDoubleClickCallback = boost::bind(cb, userdata); }
void swapWithNext(S32 index);
void swapWithPrevious(S32 index);
@@ -435,24 +204,24 @@ public:
S32 getItemIndex( LLScrollListItem* item ) const;
S32 getItemIndex( const LLUUID& item_id ) const;
- LLScrollListItem* addCommentText( const std::string& comment_text, EAddPosition pos = ADD_BOTTOM);
+ void setCommentText( const std::string& comment_text);
LLScrollListItem* addSeparator(EAddPosition pos);
// "Simple" interface: use this when you're creating a list that contains only unique strings, only
// one of which can be selected at a time.
virtual LLScrollListItem* addSimpleElement(const std::string& value, EAddPosition pos = ADD_BOTTOM, const LLSD& id = LLSD());
-
BOOL selectItemByLabel( const std::string& item, BOOL case_sensitive = TRUE ); // FALSE if item not found
BOOL selectItemByPrefix(const std::string& target, BOOL case_sensitive = TRUE);
BOOL selectItemByPrefix(const LLWString& target, BOOL case_sensitive = TRUE);
+ LLScrollListItem* getItemByLabel( const std::string& item, BOOL case_sensitive = TRUE, S32 column = 0 );
const std::string getSelectedItemLabel(S32 column = 0) const;
LLSD getSelectedValue();
- // DEPRECATED: Use LLSD versions of addCommentText() and getSelectedValue().
+ // DEPRECATED: Use LLSD versions of setCommentText() and getSelectedValue().
// "StringUUID" interface: use this when you're creating a list that contains non-unique strings each of which
// has an associated, unique UUID, and only one of which can be selected at a time.
- LLScrollListItem* addStringUUIDItem(const std::string& item_text, const LLUUID& id, EAddPosition pos = ADD_BOTTOM, BOOL enabled = TRUE, S32 column_width = 0);
+ LLScrollListItem* addStringUUIDItem(const std::string& item_text, const LLUUID& id, EAddPosition pos = ADD_BOTTOM, BOOL enabled = TRUE);
LLUUID getStringUUIDSelectedItem() const;
LLScrollListItem* getFirstSelected() const;
@@ -475,7 +244,8 @@ public:
void setBgStripeColor(const LLColor4& c) { mBgStripeColor = c; }
void setFgSelectedColor(const LLColor4 &c) { mFgSelectedColor = c; }
void setFgUnselectedColor(const LLColor4 &c){ mFgUnselectedColor = c; }
- void setHighlightedColor(const LLColor4 &c) { mHighlightedColor = c; }
+ void setHoveredColor(const LLColor4 &c) { mHoveredColor = c; }
+ void setHighlightedColor(const LLColor4 &c) { mHighlightedColor = c; }
void setFgDisableColor(const LLColor4 &c) { mFgDisabledColor = c; }
void setBackgroundVisible(BOOL b) { mBackgroundVisible = b; }
@@ -514,6 +284,7 @@ public:
/*virtual*/ void setFocus( BOOL b );
/*virtual*/ void onFocusReceived();
/*virtual*/ void onFocusLost();
+ /*virtual*/ void onMouseLeave(S32 x, S32 y, MASK mask);
/*virtual*/ void reshape(S32 width, S32 height, BOOL called_from_parent = TRUE);
virtual BOOL isDirty() const;
@@ -528,15 +299,14 @@ public:
LLRect getItemListRect() { return mItemListRect; }
// Used "internally" by the scroll bar.
- static void onScrollChange( S32 new_pos, LLScrollbar* src, void* userdata );
+ void onScrollChange( S32 new_pos, LLScrollbar* src );
static void onClickColumn(void *userdata);
- void updateColumns();
+ virtual void updateColumns();
void calcColumnWidths();
S32 getMaxContentWidth() { return mMaxContentWidth; }
- void setDisplayHeading(BOOL display);
void setHeadingHeight(S32 heading_height);
void setCollapseEmptyColumns(BOOL collapse);
@@ -559,15 +329,16 @@ public:
std::string getSortColumnName();
BOOL getSortAscending() { return mSortColumns.empty() ? TRUE : mSortColumns.back().second; }
- BOOL needsSorting();
+ BOOL hasSortOrder() const;
- S32 selectMultiple( LLDynamicArray<LLUUID> ids );
- void sortItems();
+ S32 selectMultiple( std::vector<LLUUID> ids );
+ // conceptually const, but mutates mItemList
+ void updateSort() const;
// sorts a list without affecting the permanent sort order (so further list insertions can be unsorted, for example)
void sortOnce(S32 column, BOOL ascending);
// manually call this whenever editing list items in place to flag need for resorting
- void setSorted(BOOL sorted) { mSorted = sorted; }
+ void setNeedsSort() { mSorted = false; }
void dirtyColumns(); // some operation has potentially affected column layout or ordering
protected:
@@ -604,10 +375,6 @@ private:
void commitIfChanged();
BOOL setSort(S32 column, BOOL ascending);
-
- S32 mCurIndex; // For get[First/Next]Data
- S32 mCurSelectedIndex; // For get[First/Next]Selected
-
S32 mLineHeight; // the max height of a single line
S32 mScrollLines; // how many lines we've scrolled down
S32 mPageLines; // max number of lines is it possible to see on the screen given mRect and mLineHeight
@@ -621,10 +388,10 @@ private:
BOOL mSelectionChanged;
BOOL mNeedsScroll;
BOOL mCanSelect;
- BOOL mDisplayColumnHeaders;
+ const BOOL mDisplayColumnHeaders;
BOOL mColumnsDirty;
- item_list mItemList;
+ mutable item_list mItemList;
LLScrollListItem *mLastSelected;
@@ -637,19 +404,20 @@ private:
BOOL mBackgroundVisible;
BOOL mDrawStripes;
- LLColor4 mBgWriteableColor;
- LLColor4 mBgReadOnlyColor;
- LLColor4 mBgSelectedColor;
- LLColor4 mBgStripeColor;
- LLColor4 mFgSelectedColor;
- LLColor4 mFgUnselectedColor;
- LLColor4 mFgDisabledColor;
- LLColor4 mHighlightedColor;
+ LLUIColor mBgWriteableColor;
+ LLUIColor mBgReadOnlyColor;
+ LLUIColor mBgSelectedColor;
+ LLUIColor mBgStripeColor;
+ LLUIColor mFgSelectedColor;
+ LLUIColor mFgUnselectedColor;
+ LLUIColor mFgDisabledColor;
+ LLUIColor mHoveredColor;
+ LLUIColor mHighlightedColor;
S32 mBorderThickness;
- void (*mOnDoubleClickCallback)(void* userdata);
- void (*mOnMaximumSelectCallback)(void* userdata );
- void (*mOnSortChangedCallback)(void* userdata);
+ callback_t mOnDoubleClickCallback;
+ callback_t mOnMaximumSelectCallback;
+ callback_t mOnSortChangedCallback;
S32 mHighlightedItem;
class LLViewBorder* mBorder;
@@ -662,7 +430,7 @@ private:
S32 mTotalStaticColumnWidth;
S32 mTotalColumnPadding;
- BOOL mSorted;
+ mutable bool mSorted;
typedef std::map<std::string, LLScrollListColumn> column_map_t;
column_map_t mColumns;
@@ -675,10 +443,6 @@ private:
typedef std::pair<S32, BOOL> sort_column_t;
std::vector<sort_column_t> mSortColumns;
-
- // HACK: Did we draw one selected item this frame?
- BOOL mDrewSelected;
}; // end class LLScrollListCtrl
-
#endif // LL_SCROLLLISTCTRL_H
diff --git a/indra/llui/llscrolllistitem.cpp b/indra/llui/llscrolllistitem.cpp
new file mode 100644
index 0000000000..2ac6925c78
--- /dev/null
+++ b/indra/llui/llscrolllistitem.cpp
@@ -0,0 +1,157 @@
+/**
+ * @file llscrolllistitem.cpp
+ * @brief Scroll lists are composed of rows (items), each of which
+ * contains columns (cells).
+ *
+ * $LicenseInfo:firstyear=2001&license=viewergpl$
+ *
+ * Copyright (c) 2001-2009, Linden Research, Inc.
+ *
+ * Second Life Viewer Source Code
+ * The source code in this file ("Source Code") is provided by Linden Lab
+ * to you under the terms of the GNU General Public License, version 2.0
+ * ("GPL"), unless you have obtained a separate licensing agreement
+ * ("Other License"), formally executed by you and Linden Lab. Terms of
+ * the GPL can be found in doc/GPL-license.txt in this distribution, or
+ * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
+ *
+ * There are special exceptions to the terms and conditions of the GPL as
+ * it is applied to this Source Code. View the full text of the exception
+ * in the file doc/FLOSS-exception.txt in this software distribution, or
+ * online at
+ * http://secondlifegrid.net/programs/open_source/licensing/flossexception
+ *
+ * By copying, modifying or distributing this software, you acknowledge
+ * that you have read and understood your obligations described above,
+ * and agree to abide by those obligations.
+ *
+ * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+ * COMPLETENESS OR PERFORMANCE.
+ * $/LicenseInfo$
+ */
+
+#include "linden_common.h"
+
+#include "llscrolllistitem.h"
+
+#include "llrect.h"
+#include "llresmgr.h" // LLFONT_SANSSERIF_SMALL
+#include "llui.h"
+
+
+//---------------------------------------------------------------------------
+// LLScrollListItem
+//---------------------------------------------------------------------------
+
+LLScrollListItem::LLScrollListItem( const Params& p )
+: mSelected(FALSE),
+ mHighlighted(FALSE),
+ mEnabled(p.enabled),
+ mUserdata(p.userdata),
+ mItemValue(p.value)
+{
+}
+
+
+LLScrollListItem::~LLScrollListItem()
+{
+ std::for_each(mColumns.begin(), mColumns.end(), DeletePointer());
+}
+
+void LLScrollListItem::addColumn(const LLScrollListCell::Params& p)
+{
+ mColumns.push_back(LLScrollListCell::create(p));
+}
+
+void LLScrollListItem::setNumColumns(S32 columns)
+{
+ S32 prev_columns = mColumns.size();
+ if (columns < prev_columns)
+ {
+ std::for_each(mColumns.begin()+columns, mColumns.end(), DeletePointer());
+ }
+
+ mColumns.resize(columns);
+
+ for (S32 col = prev_columns; col < columns; ++col)
+ {
+ mColumns[col] = NULL;
+ }
+}
+
+void LLScrollListItem::setColumn( S32 column, LLScrollListCell *cell )
+{
+ if (column < (S32)mColumns.size())
+ {
+ delete mColumns[column];
+ mColumns[column] = cell;
+ }
+ else
+ {
+ llerrs << "LLScrollListItem::setColumn: bad column: " << column << llendl;
+ }
+}
+
+
+S32 LLScrollListItem::getNumColumns() const
+{
+ return mColumns.size();
+}
+
+LLScrollListCell* LLScrollListItem::getColumn(const S32 i) const
+{
+ if (0 <= i && i < (S32)mColumns.size())
+ {
+ return mColumns[i];
+ }
+ return NULL;
+}
+
+std::string LLScrollListItem::getContentsCSV() const
+{
+ std::string ret;
+
+ S32 count = getNumColumns();
+ for (S32 i=0; i<count; ++i)
+ {
+ ret += getColumn(i)->getValue().asString();
+ if (i < count-1)
+ {
+ ret += ", ";
+ }
+ }
+
+ return ret;
+}
+
+
+void LLScrollListItem::draw(const LLRect& rect, const LLColor4& fg_color, const LLColor4& bg_color, const LLColor4& highlight_color, S32 column_padding)
+{
+ // draw background rect
+ gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
+ LLRect bg_rect = rect;
+ gl_rect_2d( bg_rect, bg_color );
+
+ S32 cur_x = rect.mLeft;
+ S32 num_cols = getNumColumns();
+ S32 cur_col = 0;
+
+ for (LLScrollListCell* cell = getColumn(0); cur_col < num_cols; cell = getColumn(++cur_col))
+ {
+ // Two ways a cell could be hidden
+ if (cell->getWidth() < 0
+ || !cell->getVisible()) continue;
+
+ LLUI::pushMatrix();
+ {
+ LLUI::translate((F32) cur_x, (F32) rect.mBottom, 0.0f);
+
+ cell->draw( fg_color, highlight_color );
+ }
+ LLUI::popMatrix();
+
+ cur_x += cell->getWidth() + column_padding;
+ }
+}
+
diff --git a/indra/llui/llscrolllistitem.h b/indra/llui/llscrolllistitem.h
new file mode 100644
index 0000000000..c2b7effbc7
--- /dev/null
+++ b/indra/llui/llscrolllistitem.h
@@ -0,0 +1,129 @@
+/**
+ * @file llscrolllistitem.h
+ * @brief Scroll lists are composed of rows (items), each of which
+ * contains columns (cells).
+ *
+ * $LicenseInfo:firstyear=2007&license=viewergpl$
+ *
+ * Copyright (c) 2007-2009, Linden Research, Inc.
+ *
+ * Second Life Viewer Source Code
+ * The source code in this file ("Source Code") is provided by Linden Lab
+ * to you under the terms of the GNU General Public License, version 2.0
+ * ("GPL"), unless you have obtained a separate licensing agreement
+ * ("Other License"), formally executed by you and Linden Lab. Terms of
+ * the GPL can be found in doc/GPL-license.txt in this distribution, or
+ * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
+ *
+ * There are special exceptions to the terms and conditions of the GPL as
+ * it is applied to this Source Code. View the full text of the exception
+ * in the file doc/FLOSS-exception.txt in this software distribution, or
+ * online at
+ * http://secondlifegrid.net/programs/open_source/licensing/flossexception
+ *
+ * By copying, modifying or distributing this software, you acknowledge
+ * that you have read and understood your obligations described above,
+ * and agree to abide by those obligations.
+ *
+ * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+ * COMPLETENESS OR PERFORMANCE.
+ * $/LicenseInfo$
+ */
+
+#ifndef LLSCROLLLISTITEM_H
+#define LLSCROLLLISTITEM_H
+
+#include "llfontgl.h" // LLFontGL::HAlign
+#include "llpointer.h" // LLPointer<>
+#include "llsd.h"
+#include "lluistring.h"
+#include "v4color.h"
+#include "llinitparam.h"
+#include "llscrolllistcell.h"
+
+#include <vector>
+
+class LLCoordGL;
+class LLCheckBoxCtrl;
+class LLResizeBar;
+class LLScrollListCtrl;
+class LLScrollColumnHeader;
+class LLUIImage;
+
+//---------------------------------------------------------------------------
+// LLScrollListItem
+//---------------------------------------------------------------------------
+class LLScrollListItem
+{
+ friend class LLScrollListCtrl;
+public:
+ struct Params : public LLInitParam::Block<Params>
+ {
+ Optional<bool> enabled;
+ Optional<void*> userdata;
+ Optional<LLSD> value;
+
+ Ignored name; // use for localization tools
+ Ignored type;
+ Ignored length;
+
+ Multiple<LLScrollListCell::Params> columns;
+
+ Params()
+ : enabled("enabled", true),
+ value("value"),
+ name("name"),
+ type("type"),
+ length("length"),
+ columns("columns")
+ {
+ addSynonym(columns, "column");
+ addSynonym(value, "id");
+ }
+ };
+
+ virtual ~LLScrollListItem();
+
+ void setSelected( BOOL b ) { mSelected = b; }
+ BOOL getSelected() const { return mSelected; }
+
+ void setEnabled( BOOL b ) { mEnabled = b; }
+ BOOL getEnabled() const { return mEnabled; }
+
+ void setHighlighted( BOOL b ) { mHighlighted = b; }
+ BOOL getHighlighted() const { return mHighlighted; }
+
+ void setUserdata( void* userdata ) { mUserdata = userdata; }
+ void* getUserdata() const { return mUserdata; }
+
+ LLUUID getUUID() const { return mItemValue.asUUID(); }
+ LLSD getValue() const { return mItemValue; }
+
+ void addColumn( const LLScrollListCell::Params& p );
+
+ void setNumColumns(S32 columns);
+
+ void setColumn( S32 column, LLScrollListCell *cell );
+
+ S32 getNumColumns() const;
+
+ LLScrollListCell *getColumn(const S32 i) const;
+
+ std::string getContentsCSV() const;
+
+ virtual void draw(const LLRect& rect, const LLColor4& fg_color, const LLColor4& bg_color, const LLColor4& highlight_color, S32 column_padding);
+
+protected:
+ LLScrollListItem( const Params& );
+
+private:
+ BOOL mSelected;
+ BOOL mHighlighted;
+ BOOL mEnabled;
+ void* mUserdata;
+ LLSD mItemValue;
+ std::vector<LLScrollListCell *> mColumns;
+};
+
+#endif
diff --git a/indra/llui/llsdparam.cpp b/indra/llui/llsdparam.cpp
new file mode 100644
index 0000000000..1b0f3c9885
--- /dev/null
+++ b/indra/llui/llsdparam.cpp
@@ -0,0 +1,158 @@
+/**
+ * @file llsdparam.cpp
+ * @brief parameter block abstraction for creating complex objects and
+ * parsing construction parameters from xml and LLSD
+ *
+ * $LicenseInfo:firstyear=2008&license=viewergpl$
+ *
+ * Copyright (c) 2008-2009, Linden Research, Inc.
+ *
+ * Second Life Viewer Source Code
+ * The source code in this file ("Source Code") is provided by Linden Lab
+ * to you under the terms of the GNU General Public License, version 2.0
+ * ("GPL"), unless you have obtained a separate licensing agreement
+ * ("Other License"), formally executed by you and Linden Lab. Terms of
+ * the GPL can be found in doc/GPL-license.txt in this distribution, or
+ * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
+ *
+ * There are special exceptions to the terms and conditions of the GPL as
+ * it is applied to this Source Code. View the full text of the exception
+ * in the file doc/FLOSS-exception.txt in this software distribution, or
+ * online at
+ * http://secondlifegrid.net/programs/open_source/licensing/flossexception
+ *
+ * By copying, modifying or distributing this software, you acknowledge
+ * that you have read and understood your obligations described above,
+ * and agree to abide by those obligations.
+ *
+ * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+ * COMPLETENESS OR PERFORMANCE.
+ * $/LicenseInfo$
+ */
+
+#include "linden_common.h"
+
+// Project includes
+#include "llsdparam.h"
+
+//
+// LLParamSDParser
+//
+LLParamSDParser::LLParamSDParser()
+{
+ using boost::bind;
+
+ registerParserFuncs<S32>(bind(&LLParamSDParser::readTypedValue<S32>, this, _1, &LLSD::asInteger),
+ bind(&LLParamSDParser::writeTypedValue<S32>, this, _1, _2));
+ registerParserFuncs<U32>(bind(&LLParamSDParser::readTypedValue<U32>, this, _1, &LLSD::asInteger),
+ bind(&LLParamSDParser::writeU32Param, this, _1, _2));
+ registerParserFuncs<F32>(bind(&LLParamSDParser::readTypedValue<F32>, this, _1, &LLSD::asReal),
+ bind(&LLParamSDParser::writeTypedValue<F32>, this, _1, _2));
+ registerParserFuncs<F64>(bind(&LLParamSDParser::readTypedValue<F64>, this, _1, &LLSD::asReal),
+ bind(&LLParamSDParser::writeTypedValue<F64>, this, _1, _2));
+ registerParserFuncs<bool>(bind(&LLParamSDParser::readTypedValue<F32>, this, _1, &LLSD::asBoolean),
+ bind(&LLParamSDParser::writeTypedValue<F32>, this, _1, _2));
+ registerParserFuncs<std::string>(bind(&LLParamSDParser::readTypedValue<std::string>, this, _1, &LLSD::asString),
+ bind(&LLParamSDParser::writeTypedValue<std::string>, this, _1, _2));
+ registerParserFuncs<LLUUID>(bind(&LLParamSDParser::readTypedValue<LLUUID>, this, _1, &LLSD::asUUID),
+ bind(&LLParamSDParser::writeTypedValue<LLUUID>, this, _1, _2));
+ registerParserFuncs<LLDate>(bind(&LLParamSDParser::readTypedValue<LLDate>, this, _1, &LLSD::asDate),
+ bind(&LLParamSDParser::writeTypedValue<LLDate>, this, _1, _2));
+ registerParserFuncs<LLURI>(bind(&LLParamSDParser::readTypedValue<LLURI>, this, _1, &LLSD::asURI),
+ bind(&LLParamSDParser::writeTypedValue<LLURI>, this, _1, _2));
+ registerParserFuncs<LLSD>(bind(&LLParamSDParser::readSDParam, this, _1),
+ bind(&LLParamSDParser::writeTypedValue<LLSD>, this, _1, _2));
+}
+
+bool LLParamSDParser::readSDParam(void* value_ptr)
+{
+ if (!mCurReadSD) return false;
+ *((LLSD*)value_ptr) = *mCurReadSD;
+ return true;
+}
+
+// special case handling of U32 due to ambiguous LLSD::assign overload
+bool LLParamSDParser::writeU32Param(const void* val_ptr, const parser_t::name_stack_t& name_stack)
+{
+ if (!mWriteSD) return false;
+
+ LLSD* sd_to_write = getSDWriteNode(name_stack);
+ if (!sd_to_write) return false;
+
+ sd_to_write->assign((S32)*((const U32*)val_ptr));
+ return true;
+}
+
+void LLParamSDParser::readSD(const LLSD& sd, LLInitParam::BaseBlock& block, bool silent)
+{
+ mCurReadSD = NULL;
+ mNameStack.clear();
+ setParseSilently(silent);
+
+ // must have named elements at top level to submit for parsing
+ if (sd.isMap())
+ {
+ readSDValues(sd, block);
+ }
+ else
+ {
+ parserWarning("Top level map required for LLSD->Block conversion");
+ }
+}
+
+void LLParamSDParser::writeSD(LLSD& sd, const LLInitParam::BaseBlock& block)
+{
+ mWriteSD = &sd;
+ block.serializeBlock(*this);
+}
+
+void LLParamSDParser::readSDValues(const LLSD& sd, LLInitParam::BaseBlock& block)
+{
+ if (sd.isMap())
+ {
+ for (LLSD::map_const_iterator it = sd.beginMap();
+ it != sd.endMap();
+ ++it)
+ {
+ mNameStack.push_back(make_pair(it->first, newParseGeneration()));
+ readSDValues(it->second, block);
+ mNameStack.pop_back();
+ }
+ }
+ else if (sd.isArray())
+ {
+ for (LLSD::array_const_iterator it = sd.beginArray();
+ it != sd.endArray();
+ ++it)
+ {
+ mNameStack.back().second = newParseGeneration();
+ readSDValues(*it, block);
+ }
+ }
+ else
+ {
+ mCurReadSD = &sd;
+ block.submitValue(mNameStack, *this);
+ }
+}
+
+/*virtual*/ std::string LLParamSDParser::getCurrentElementName()
+{
+ std::string full_name = "sd";
+ for (name_stack_t::iterator it = mNameStack.begin();
+ it != mNameStack.end();
+ ++it)
+ {
+ full_name += llformat("[%s]", it->first.c_str());
+ }
+
+ return full_name;
+}
+
+LLSD* LLParamSDParser::getSDWriteNode(const parser_t::name_stack_t& name_stack)
+{
+ //TODO: implement nested LLSD writing
+ return mWriteSD;
+}
+
diff --git a/indra/llui/llsdparam.h b/indra/llui/llsdparam.h
new file mode 100644
index 0000000000..12f28f876f
--- /dev/null
+++ b/indra/llui/llsdparam.h
@@ -0,0 +1,107 @@
+/**
+ * @file llsdparam.h
+ * @brief parameter block abstraction for creating complex objects and
+ * parsing construction parameters from xml and LLSD
+ *
+ * $LicenseInfo:firstyear=2008&license=viewergpl$
+ *
+ * Copyright (c) 2008-2009, Linden Research, Inc.
+ *
+ * Second Life Viewer Source Code
+ * The source code in this file ("Source Code") is provided by Linden Lab
+ * to you under the terms of the GNU General Public License, version 2.0
+ * ("GPL"), unless you have obtained a separate licensing agreement
+ * ("Other License"), formally executed by you and Linden Lab. Terms of
+ * the GPL can be found in doc/GPL-license.txt in this distribution, or
+ * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
+ *
+ * There are special exceptions to the terms and conditions of the GPL as
+ * it is applied to this Source Code. View the full text of the exception
+ * in the file doc/FLOSS-exception.txt in this software distribution, or
+ * online at
+ * http://secondlifegrid.net/programs/open_source/licensing/flossexception
+ *
+ * By copying, modifying or distributing this software, you acknowledge
+ * that you have read and understood your obligations described above,
+ * and agree to abide by those obligations.
+ *
+ * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+ * COMPLETENESS OR PERFORMANCE.
+ * $/LicenseInfo$
+ */
+
+#ifndef LL_LLSDPARAM_H
+#define LL_LLSDPARAM_H
+
+#include "llinitparam.h"
+
+class LLParamSDParser
+: public LLInitParam::Parser,
+ public LLSingleton<LLParamSDParser>
+{
+LOG_CLASS(LLParamSDParser);
+
+typedef LLInitParam::Parser parser_t;
+
+protected:
+ LLParamSDParser();
+ friend class LLSingleton<LLParamSDParser>;
+public:
+ void readSD(const LLSD& sd, LLInitParam::BaseBlock& block, bool silent = false);
+ void writeSD(LLSD& sd, const LLInitParam::BaseBlock& block);
+
+ /*virtual*/ std::string getCurrentElementName();
+
+private:
+ void readSDValues(const LLSD& sd, LLInitParam::BaseBlock& block);
+
+ template<typename T>
+ bool readTypedValue(void* val_ptr, boost::function<T(const LLSD&)> parser_func)
+ {
+ if (!mCurReadSD) return false;
+
+ *((T*)val_ptr) = parser_func(*mCurReadSD);
+ return true;
+ }
+
+ template<typename T>
+ bool writeTypedValue(const void* val_ptr, const parser_t::name_stack_t& name_stack)
+ {
+ if (!mWriteSD) return false;
+
+ LLSD* sd_to_write = getSDWriteNode(name_stack);
+ if (!sd_to_write) return false;
+
+ sd_to_write->assign(*((const T*)val_ptr));
+ return true;
+ }
+
+ LLSD* getSDWriteNode(const parser_t::name_stack_t& name_stack);
+
+ bool readSDParam(void* value_ptr);
+ bool writeU32Param(const void* value_ptr, const parser_t::name_stack_t& name_stack);
+
+ Parser::name_stack_t mNameStack;
+ const LLSD* mCurReadSD;
+ LLSD* mWriteSD;
+};
+
+template<typename T>
+class LLSDParamAdapter : public T
+ {
+ public:
+ LLSDParamAdapter() {}
+ LLSDParamAdapter(const LLSD& sd)
+ {
+ LLParamSDParser::instance().readSD(sd, *this);
+ }
+
+ LLSDParamAdapter(const T& val)
+ {
+ T::operator=(val);
+ }
+ };
+
+#endif // LL_LLSDPARAM_H
+
diff --git a/indra/llui/llsearcheditor.cpp b/indra/llui/llsearcheditor.cpp
new file mode 100644
index 0000000000..fbcbb55b85
--- /dev/null
+++ b/indra/llui/llsearcheditor.cpp
@@ -0,0 +1,98 @@
+/**
+ * @file llsearcheditor.cpp
+ * @brief LLSearchEditor implementation
+ *
+ * $LicenseInfo:firstyear=2001&license=viewergpl$
+ *
+ * Copyright (c) 2001-2009, Linden Research, Inc.
+ *
+ * Second Life Viewer Source Code
+ * The source code in this file ("Source Code") is provided by Linden Lab
+ * to you under the terms of the GNU General Public License, version 2.0
+ * ("GPL"), unless you have obtained a separate licensing agreement
+ * ("Other License"), formally executed by you and Linden Lab. Terms of
+ * the GPL can be found in doc/GPL-license.txt in this distribution, or
+ * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
+ *
+ * There are special exceptions to the terms and conditions of the GPL as
+ * it is applied to this Source Code. View the full text of the exception
+ * in the file doc/FLOSS-exception.txt in this software distribution, or
+ * online at
+ * http://secondlifegrid.net/programs/open_source/licensing/flossexception
+ *
+ * By copying, modifying or distributing this software, you acknowledge
+ * that you have read and understood your obligations described above,
+ * and agree to abide by those obligations.
+ *
+ * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+ * COMPLETENESS OR PERFORMANCE.
+ * $/LicenseInfo$
+ */
+
+// Text editor widget to let users enter a single line.
+
+#include "linden_common.h"
+
+#include "llsearcheditor.h"
+
+LLSearchEditor::LLSearchEditor(const LLSearchEditor::Params& p)
+: LLUICtrl(p)
+{
+ S32 btn_top = p.search_button.top_pad + p.search_button.rect.height;
+ S32 btn_right = p.search_button.rect.width + p.search_button.left_pad;
+ LLRect search_btn_rect(p.search_button.left_pad, btn_top, btn_right, p.search_button.top_pad);
+
+ LLLineEditor::Params line_editor_params(p);
+ line_editor_params.name("filter edit box");
+ line_editor_params.rect(getLocalRect());
+ line_editor_params.follows.flags(FOLLOWS_ALL);
+ line_editor_params.text_pad_left(p.text_pad_left + search_btn_rect.getWidth());
+ line_editor_params.commit_callback.function(boost::bind(&LLUICtrl::onCommit, this));
+
+ mSearchEditor = LLUICtrlFactory::create<LLLineEditor>(line_editor_params);
+ addChild(mSearchEditor);
+
+ LLButton::Params button_params(p.search_button);
+ button_params.name(std::string("clear filter"));
+ button_params.rect(search_btn_rect) ;
+ button_params.follows.flags(FOLLOWS_RIGHT|FOLLOWS_TOP);
+ button_params.tab_stop(false);
+ button_params.click_callback.function(boost::bind(&LLUICtrl::onCommit, this));
+
+ mSearchButton = LLUICtrlFactory::create<LLButton>(button_params);
+ mSearchEditor->addChild(mSearchButton);
+}
+
+//virtual
+void LLSearchEditor::setValue(const LLSD& value )
+{
+ mSearchEditor->setValue(value);
+}
+
+//virtual
+LLSD LLSearchEditor::getValue() const
+{
+ return mSearchEditor->getValue();
+}
+
+//virtual
+BOOL LLSearchEditor::setTextArg( const std::string& key, const LLStringExplicit& text )
+{
+ return mSearchEditor->setTextArg(key, text);
+}
+
+//virtual
+BOOL LLSearchEditor::setLabelArg( const std::string& key, const LLStringExplicit& text )
+{
+ return mSearchEditor->setLabelArg(key, text);
+}
+
+//virtual
+void LLSearchEditor::clear()
+{
+ if (mSearchEditor)
+ {
+ mSearchEditor->clear();
+ }
+}
diff --git a/indra/llui/llsearcheditor.h b/indra/llui/llsearcheditor.h
new file mode 100644
index 0000000000..cd2867b493
--- /dev/null
+++ b/indra/llui/llsearcheditor.h
@@ -0,0 +1,91 @@
+/**
+ * @file llsearcheditor.h
+ * @brief Text editor widget that represents a search operation
+ *
+ * Features:
+ * Text entry of a single line (text, delete, left and right arrow, insert, return).
+ * Callbacks either on every keystroke or just on the return key.
+ * Focus (allow multiple text entry widgets)
+ * Clipboard (cut, copy, and paste)
+ * Horizontal scrolling to allow strings longer than widget size allows
+ * Pre-validation (limit which keys can be used)
+ * Optional line history so previous entries can be recalled by CTRL UP/DOWN
+ *
+ * $LicenseInfo:firstyear=2001&license=viewergpl$
+ *
+ * Copyright (c) 2001-2009, Linden Research, Inc.
+ *
+ * Second Life Viewer Source Code
+ * The source code in this file ("Source Code") is provided by Linden Lab
+ * to you under the terms of the GNU General Public License, version 2.0
+ * ("GPL"), unless you have obtained a separate licensing agreement
+ * ("Other License"), formally executed by you and Linden Lab. Terms of
+ * the GPL can be found in doc/GPL-license.txt in this distribution, or
+ * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
+ *
+ * There are special exceptions to the terms and conditions of the GPL as
+ * it is applied to this Source Code. View the full text of the exception
+ * in the file doc/FLOSS-exception.txt in this software distribution, or
+ * online at
+ * http://secondlifegrid.net/programs/open_source/licensing/flossexception
+ *
+ * By copying, modifying or distributing this software, you acknowledge
+ * that you have read and understood your obligations described above,
+ * and agree to abide by those obligations.
+ *
+ * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+ * COMPLETENESS OR PERFORMANCE.
+ * $/LicenseInfo$
+ */
+
+#ifndef LL_SEARCHEDITOR_H
+#define LL_SEARCHEDITOR_H
+
+#include "lllineeditor.h"
+#include "llbutton.h"
+
+class LLSearchEditor : public LLUICtrl
+{
+public:
+ struct Params : public LLInitParam::Block<Params, LLLineEditor::Params>
+ {
+ Optional<LLButton::Params> search_button;
+
+ Params()
+ : search_button("search_button")
+ {
+ name = "search_editor";
+ }
+ };
+
+protected:
+ LLSearchEditor(const Params&);
+ friend class LLUICtrlFactory;
+
+public:
+ virtual ~LLSearchEditor() {}
+
+ void setText(const LLStringExplicit &new_text) { mSearchEditor->setText(new_text); }
+ const std::string& getText() const { return mSearchEditor->getText(); }
+
+
+ // LLUICtrl interface
+ virtual void setValue(const LLSD& value );
+ virtual LLSD getValue() const;
+ virtual BOOL setTextArg( const std::string& key, const LLStringExplicit& text );
+ virtual BOOL setLabelArg( const std::string& key, const LLStringExplicit& text );
+ virtual void clear();
+
+ void setKeystrokeCallback(LLLineEditor::callback_t callback, void* user_data)
+ {
+ if(mSearchEditor)
+ mSearchEditor->setKeystrokeCallback(callback,user_data);
+ }
+
+private:
+ LLLineEditor* mSearchEditor;
+ LLButton* mSearchButton;
+};
+
+#endif // LL_SEARCHEDITOR_H
diff --git a/indra/llui/llslider.cpp b/indra/llui/llslider.cpp
index 4dfc904581..1c394a71dd 100644
--- a/indra/llui/llslider.cpp
+++ b/indra/llui/llslider.cpp
@@ -40,54 +40,49 @@
#include "llfocusmgr.h"
#include "llkeyboard.h" // for the MASK constants
#include "llcontrol.h"
-#include "llimagegl.h"
-
-static LLRegisterWidget<LLSlider> r1("slider_bar");
-static LLRegisterWidget<LLSlider> r2("volume_slider");
-
-
-LLSlider::LLSlider(
- const std::string& name,
- const LLRect& rect,
- void (*on_commit_callback)(LLUICtrl* ctrl, void* userdata),
- void* callback_userdata,
- F32 initial_value,
- F32 min_value,
- F32 max_value,
- F32 increment,
- BOOL volume,
- const std::string& control_name)
- :
- LLUICtrl( name, rect, TRUE, on_commit_callback, callback_userdata,
- FOLLOWS_LEFT | FOLLOWS_TOP),
- mValue( initial_value ),
- mInitialValue( initial_value ),
- mMinValue( min_value ),
- mMaxValue( max_value ),
- mIncrement( increment ),
- mVolumeSlider( volume ),
- mMouseOffset( 0 ),
- mTrackColor( LLUI::sColorsGroup->getColor( "SliderTrackColor" ) ),
- mThumbOutlineColor( LLUI::sColorsGroup->getColor( "SliderThumbOutlineColor" ) ),
- mThumbCenterColor( LLUI::sColorsGroup->getColor( "SliderThumbCenterColor" ) ),
- mMouseDownCallback( NULL ),
- mMouseUpCallback( NULL )
+#include "lluictrlfactory.h"
+
+static LLDefaultChildRegistry::Register<LLSlider> r1("slider_bar");
+
+LLSlider::Params::Params()
+: track_color("track_color"),
+ thumb_outline_color("thumb_outline_color"),
+ thumb_center_color("thumb_center_color"),
+ thumb_image("thumb_image"),
+ thumb_image_pressed("thumb_image_pressed"),
+ thumb_image_disabled("thumb_image_disabled"),
+ track_image("track_image"),
+ track_highlight_image("track_highlight_image"),
+ mouse_down_callback("mouse_down_callback"),
+ mouse_up_callback("mouse_up_callback")
{
- mThumbImage = LLUI::sImageProvider->getUIImage("icn_slide-thumb_dark.tga");
- mTrackImage = LLUI::sImageProvider->getUIImage("icn_slide-groove_dark.tga");
- mTrackHighlightImage = LLUI::sImageProvider->getUIImage("icn_slide-highlight.tga");
-
- // properly handle setting the starting thumb rect
- // do it this way to handle both the operating-on-settings
- // and standalone ways of using this
- setControlName(control_name, NULL);
- setValue(getValueF32());
+ follows.flags(FOLLOWS_LEFT | FOLLOWS_TOP);
+}
+LLSlider::LLSlider(const LLSlider::Params& p)
+: LLF32UICtrl(p),
+ mMouseOffset( 0 ),
+ mTrackColor(p.track_color()),
+ mThumbOutlineColor(p.thumb_outline_color()),
+ mThumbCenterColor(p.thumb_center_color()),
+ mThumbImage(p.thumb_image),
+ mThumbImagePressed(p.thumb_image_pressed),
+ mThumbImageDisabled(p.thumb_image_disabled),
+ mTrackImage(p.track_image),
+ mTrackHighlightImage(p.track_highlight_image)
+{
+ mViewModel->setValue(p.initial_value);
updateThumbRect();
mDragStartThumbRect = mThumbRect;
+ setControlName(p.control_name, NULL);
+ setValue(getValueF32());
+
+ if (p.mouse_down_callback.isProvided())
+ initCommitCallback(p.mouse_down_callback, mMouseDownSignal);
+ if (p.mouse_up_callback.isProvided())
+ initCommitCallback(p.mouse_up_callback, mMouseUpSignal);
}
-
void LLSlider::setValue(F32 value, BOOL from_event)
{
value = llclamp( value, mMinValue, mMaxValue );
@@ -98,21 +93,22 @@ void LLSlider::setValue(F32 value, BOOL from_event)
value -= fmod(value, mIncrement);
value += mMinValue;
- if (!from_event && mValue != value)
+ if (!from_event && getValueF32() != value)
{
setControlValue(value);
}
- mValue = value;
+ LLF32UICtrl::setValue(value);
updateThumbRect();
}
void LLSlider::updateThumbRect()
{
- F32 t = (mValue - mMinValue) / (mMaxValue - mMinValue);
+ const S32 DEFAULT_THUMB_SIZE = 16;
+ F32 t = (getValueF32() - mMinValue) / (mMaxValue - mMinValue);
- S32 thumb_width = mThumbImage->getWidth();
- S32 thumb_height = mThumbImage->getHeight();
+ S32 thumb_width = mThumbImage ? mThumbImage->getWidth() : DEFAULT_THUMB_SIZE;
+ S32 thumb_height = mThumbImage ? mThumbImage->getHeight() : DEFAULT_THUMB_SIZE;
S32 left_edge = (thumb_width / 2);
S32 right_edge = getRect().getWidth() - (thumb_width / 2);
@@ -126,10 +122,10 @@ void LLSlider::updateThumbRect()
void LLSlider::setValueAndCommit(F32 value)
{
- F32 old_value = mValue;
+ F32 old_value = getValueF32();
setValue(value);
- if (mValue != old_value)
+ if (getValueF32() != old_value)
{
onCommit();
}
@@ -169,10 +165,8 @@ BOOL LLSlider::handleMouseUp(S32 x, S32 y, MASK mask)
{
gFocusMgr.setMouseCapture( NULL );
- if( mMouseUpCallback )
- {
- mMouseUpCallback( this, mCallbackUserData );
- }
+ mMouseUpSignal( this, getValueF32() );
+
handled = TRUE;
make_ui_sound("UISndClickRelease");
}
@@ -191,10 +185,7 @@ BOOL LLSlider::handleMouseDown(S32 x, S32 y, MASK mask)
{
setFocus(TRUE);
}
- if( mMouseDownCallback )
- {
- mMouseDownCallback( this, mCallbackUserData );
- }
+ mMouseDownSignal( this, getValueF32() );
if (MASK_CONTROL & mask) // if CTRL is modifying
{
@@ -256,10 +247,6 @@ void LLSlider::draw()
// drawing solids requires texturing be disabled
gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
- F32 opacity = getEnabled() ? 1.f : 0.3f;
- LLColor4 center_color = (mThumbCenterColor % opacity);
- LLColor4 track_color = (mTrackColor % opacity);
-
// Track
LLRect track_rect(mThumbImage->getWidth() / 2,
getLocalRect().getCenterY() + (mTrackImage->getHeight() / 2),
@@ -270,72 +257,38 @@ void LLSlider::draw()
mTrackHighlightImage->draw(highlight_rect);
// Thumb
- if( hasMouseCapture() )
- {
- // Show ghost where thumb was before dragging began.
- mThumbImage->draw(mDragStartThumbRect, mThumbCenterColor % 0.3f);
- }
if (hasFocus())
{
// Draw focus highlighting.
mThumbImage->drawBorder(mThumbRect, gFocusMgr.getFocusColor(), gFocusMgr.getFocusFlashWidth());
}
- // Fill in the thumb.
- mThumbImage->draw(mThumbRect, hasMouseCapture() ? mThumbOutlineColor : center_color);
+ if( hasMouseCapture() ) // currently clicking on slider
+ {
+ // Show ghost where thumb was before dragging began.
+ if (mThumbImage.notNull())
+ {
+ mThumbImage->draw(mDragStartThumbRect, mThumbCenterColor.get() % 0.3f);
+ }
+ if (mThumbImagePressed.notNull())
+ {
+ mThumbImagePressed->draw(mThumbRect, mThumbOutlineColor);
+ }
+ }
+ else if (!isInEnabledChain())
+ {
+ if (mThumbImageDisabled.notNull())
+ {
+ mThumbImageDisabled->draw(mThumbRect, mThumbCenterColor);
+ }
+ }
+ else
+ {
+ if (mThumbImage.notNull())
+ {
+ mThumbImage->draw(mThumbRect, mThumbCenterColor);
+ }
+ }
+
LLUICtrl::draw();
}
-
-// virtual
-LLXMLNodePtr LLSlider::getXML(bool save_children) const
-{
- LLXMLNodePtr node = LLUICtrl::getXML();
-
- node->createChild("initial_val", TRUE)->setFloatValue(getInitialValue());
- node->createChild("min_val", TRUE)->setFloatValue(getMinValue());
- node->createChild("max_val", TRUE)->setFloatValue(getMaxValue());
- node->createChild("increment", TRUE)->setFloatValue(getIncrement());
- node->createChild("volume", TRUE)->setBoolValue(mVolumeSlider);
-
- return node;
-}
-
-
-//static
-LLView* LLSlider::fromXML(LLXMLNodePtr node, LLView *parent, class LLUICtrlFactory *factory)
-{
- std::string name("slider_bar");
- node->getAttributeString("name", name);
-
- LLRect rect;
- createRect(node, rect, parent, LLRect());
-
- F32 initial_value = 0.f;
- node->getAttributeF32("initial_val", initial_value);
-
- F32 min_value = 0.f;
- node->getAttributeF32("min_val", min_value);
-
- F32 max_value = 1.f;
- node->getAttributeF32("max_val", max_value);
-
- F32 increment = 0.1f;
- node->getAttributeF32("increment", increment);
-
- BOOL volume = node->hasName("volume_slider") ? TRUE : FALSE;
- node->getAttributeBOOL("volume", volume);
-
- LLSlider* slider = new LLSlider(name,
- rect,
- NULL,
- NULL,
- initial_value,
- min_value,
- max_value,
- increment,
- volume);
-
- slider->initFromXML(node, parent);
-
- return slider;
-}
diff --git a/indra/llui/llslider.h b/indra/llui/llslider.h
index 154685fac1..e2a94e4d8c 100644
--- a/indra/llui/llslider.h
+++ b/indra/llui/llslider.h
@@ -33,47 +33,45 @@
#ifndef LL_LLSLIDER_H
#define LL_LLSLIDER_H
-#include "lluictrl.h"
+#include "llf32uictrl.h"
#include "v4color.h"
-class LLImageGL;
-
-class LLSlider : public LLUICtrl
+class LLSlider : public LLF32UICtrl
{
public:
- LLSlider(
- const std::string& name,
- const LLRect& rect,
- void (*on_commit_callback)(LLUICtrl* ctrl, void* userdata),
- void* callback_userdata,
- F32 initial_value,
- F32 min_value,
- F32 max_value,
- F32 increment,
- BOOL volume, //TODO: create a "volume" slider sub-class or just use image art, no? -MG
- const std::string& control_name = LLStringUtil::null );
-
- virtual LLXMLNodePtr getXML(bool save_children = true) const;
- static LLView* fromXML(LLXMLNodePtr node, LLView *parent, class LLUICtrlFactory *factory);
-
+ struct Params : public LLInitParam::Block<Params, LLF32UICtrl::Params>
+ {
+ Optional<LLUIColor> track_color,
+ thumb_outline_color,
+ thumb_center_color;
+
+ Optional<LLUIImage*> thumb_image,
+ thumb_image_pressed,
+ thumb_image_disabled,
+ track_image,
+ track_highlight_image;
+
+ Optional<CommitCallbackParam> mouse_down_callback,
+ mouse_up_callback;
+
+
+ Params();
+ };
+protected:
+ LLSlider(const Params&);
+ friend class LLUICtrlFactory;
+public:
void setValue( F32 value, BOOL from_event = FALSE );
- F32 getValueF32() const { return mValue; }
-
+ // overrides for LLF32UICtrl methods
virtual void setValue(const LLSD& value ) { setValue((F32)value.asReal(), TRUE); }
- virtual LLSD getValue() const { return LLSD(getValueF32()); }
-
- virtual void setMinValue(LLSD min_value) { setMinValue((F32)min_value.asReal()); }
- virtual void setMaxValue(LLSD max_value) { setMaxValue((F32)max_value.asReal()); }
+
+ virtual void setMinValue(const LLSD& min_value) { setMinValue((F32)min_value.asReal()); }
+ virtual void setMaxValue(const LLSD& max_value) { setMaxValue((F32)max_value.asReal()); }
+ virtual void setMinValue(F32 min_value) { LLF32UICtrl::setMinValue(min_value); updateThumbRect(); }
+ virtual void setMaxValue(F32 max_value) { LLF32UICtrl::setMaxValue(max_value); updateThumbRect(); }
- F32 getInitialValue() const { return mInitialValue; }
- F32 getMinValue() const { return mMinValue; }
- F32 getMaxValue() const { return mMaxValue; }
- F32 getIncrement() const { return mIncrement; }
- void setMinValue(F32 min_value) {mMinValue = min_value; updateThumbRect(); }
- void setMaxValue(F32 max_value) {mMaxValue = max_value; updateThumbRect(); }
- void setIncrement(F32 increment) {mIncrement = increment;}
- void setMouseDownCallback( void (*cb)(LLUICtrl* ctrl, void* userdata) ) { mMouseDownCallback = cb; }
- void setMouseUpCallback( void (*cb)(LLUICtrl* ctrl, void* userdata) ) { mMouseUpCallback = cb; }
+ boost::signals2::connection setMouseDownCallback( const commit_signal_t::slot_type& cb ) { return mMouseDownSignal.connect(cb); }
+ boost::signals2::connection setMouseUpCallback( const commit_signal_t::slot_type& cb ) { return mMouseUpSignal.connect(cb); }
virtual BOOL handleHover(S32 x, S32 y, MASK mask);
virtual BOOL handleMouseUp(S32 x, S32 y, MASK mask);
@@ -85,27 +83,23 @@ private:
void setValueAndCommit(F32 value);
void updateThumbRect();
- F32 mValue;
- F32 mInitialValue;
- F32 mMinValue;
- F32 mMaxValue;
- F32 mIncrement;
-
BOOL mVolumeSlider;
S32 mMouseOffset;
LLRect mDragStartThumbRect;
- LLUIImage* mThumbImage;
- LLUIImage* mTrackImage;
- LLUIImage* mTrackHighlightImage;
+ LLPointer<LLUIImage> mThumbImage;
+ LLPointer<LLUIImage> mThumbImagePressed;
+ LLPointer<LLUIImage> mThumbImageDisabled;
+ LLPointer<LLUIImage> mTrackImage;
+ LLPointer<LLUIImage> mTrackHighlightImage;
LLRect mThumbRect;
- LLColor4 mTrackColor;
- LLColor4 mThumbOutlineColor;
- LLColor4 mThumbCenterColor;
+ LLUIColor mTrackColor;
+ LLUIColor mThumbOutlineColor;
+ LLUIColor mThumbCenterColor;
- void (*mMouseDownCallback)(LLUICtrl* ctrl, void* userdata);
- void (*mMouseUpCallback)(LLUICtrl* ctrl, void* userdata);
+ commit_signal_t mMouseDownSignal;
+ commit_signal_t mMouseUpSignal;
};
#endif // LL_LLSLIDER_H
diff --git a/indra/llui/llsliderctrl.cpp b/indra/llui/llsliderctrl.cpp
index 31baddd7cc..15584c8dc7 100644
--- a/indra/llui/llsliderctrl.cpp
+++ b/indra/llui/llsliderctrl.cpp
@@ -34,8 +34,6 @@
#include "llsliderctrl.h"
-#include "audioengine.h"
-
#include "llmath.h"
#include "llfontgl.h"
#include "llgl.h"
@@ -49,84 +47,103 @@
#include "llcontrol.h"
#include "llfocusmgr.h"
#include "llresmgr.h"
+#include "lluictrlfactory.h"
const U32 MAX_STRING_LENGTH = 10;
-static LLRegisterWidget<LLSliderCtrl> r("slider");
-
-LLSliderCtrl::LLSliderCtrl(const std::string& name, const LLRect& rect,
- const std::string& label,
- const LLFontGL* font,
- S32 label_width,
- S32 text_left,
- BOOL show_text,
- BOOL can_edit_text,
- BOOL volume,
- void (*commit_callback)(LLUICtrl*, void*),
- void* callback_user_data,
- F32 initial_value, F32 min_value, F32 max_value, F32 increment,
- const std::string& control_which)
- : LLUICtrl(name, rect, TRUE, commit_callback, callback_user_data ),
- mFont(font),
- mShowText( show_text ),
- mCanEditText( can_edit_text ),
- mVolumeSlider( volume ),
- mPrecision( 3 ),
- mLabelBox( NULL ),
- mLabelWidth( label_width ),
- mValue( initial_value ),
- mEditor( NULL ),
- mTextBox( NULL ),
- mTextEnabledColor( LLUI::sColorsGroup->getColor( "LabelTextColor" ) ),
- mTextDisabledColor( LLUI::sColorsGroup->getColor( "LabelDisabledColor" ) ),
- mSliderMouseUpCallback( NULL ),
- mSliderMouseDownCallback( NULL )
+static LLDefaultChildRegistry::Register<LLSliderCtrl> r("slider");
+
+LLSliderCtrl::LLSliderCtrl(const LLSliderCtrl::Params& p)
+: LLF32UICtrl(p),
+ mLabelBox( NULL ),
+ mEditor( NULL ),
+ mTextBox( NULL ),
+ mFont(p.font),
+ mShowText(p.show_text),
+ mCanEditText(p.can_edit_text),
+ mPrecision(p.decimal_digits),
+ mTextEnabledColor(p.text_color()),
+ mTextDisabledColor(p.text_disabled_color())
{
S32 top = getRect().getHeight();
S32 bottom = 0;
S32 left = 0;
+ S32 label_width = p.label_width;
+ S32 text_width = p.text_width;
+
// Label
- if( !label.empty() )
+ if( !p.label().empty() )
{
- if (label_width == 0)
+ if (!p.label_width.isProvided())
{
- label_width = font->getWidth(label);
+ label_width = p.font()->getWidth(p.label);
}
LLRect label_rect( left, top, label_width, bottom );
- mLabelBox = new LLTextBox( std::string("SliderCtrl Label"), label_rect, label, font );
+ LLTextBox::Params params(p.slider_label);
+ params.rect.setIfNotProvided(label_rect);
+ params.font.setIfNotProvided(p.font);
+ params.text(p.label);
+ mLabelBox = LLUICtrlFactory::create<LLTextBox> (params);
addChild(mLabelBox);
}
+ if (p.show_text && !p.text_width.isProvided())
+ {
+ // calculate the size of the text box (log max_value is number of digits - 1 so plus 1)
+ if ( p.max_value )
+ text_width = p.font()->getWidth(std::string("0")) * ( static_cast < S32 > ( log10 ( p.max_value ) ) + p.decimal_digits + 1 );
+
+ if ( p.increment < 1.0f )
+ text_width += p.font()->getWidth(std::string(".")); // (mostly) take account of decimal point in value
+
+ if ( p.min_value < 0.0f || p.max_value < 0.0f )
+ text_width += p.font()->getWidth(std::string("-")); // (mostly) take account of minus sign
+
+ // padding to make things look nicer
+ text_width += 8;
+ }
+
+
+ S32 text_left = getRect().getWidth() - text_width;
+ static LLUICachedControl<S32> sliderctrl_spacing ("UISliderctrlSpacing", 0);
+
S32 slider_right = getRect().getWidth();
- if( show_text )
+ if( p.show_text )
{
- slider_right = text_left - SLIDERCTRL_SPACING;
+ slider_right = text_left - sliderctrl_spacing;
}
- S32 slider_left = label_width ? label_width + SLIDERCTRL_SPACING : 0;
- LLRect slider_rect( slider_left, top, slider_right, bottom );
- mSlider = new LLSlider(std::string("slider"),
- slider_rect,
- LLSliderCtrl::onSliderCommit, this,
- initial_value, min_value, max_value, increment, volume,
- control_which );
+ S32 slider_left = label_width ? label_width + sliderctrl_spacing : 0;
+ LLSlider::Params slider_p(p.slider_bar);
+ slider_p.name("slider_bar");
+ slider_p.rect.setIfNotProvided(LLRect(slider_left,top,slider_right,bottom));
+ slider_p.initial_value.setIfNotProvided(p.initial_value().asReal());
+ slider_p.min_value.setIfNotProvided(p.min_value);
+ slider_p.max_value.setIfNotProvided(p.max_value);
+ slider_p.increment.setIfNotProvided(p.increment);
+
+ slider_p.commit_callback.function(&LLSliderCtrl::onSliderCommit);
+ slider_p.control_name(p.control_name);
+ slider_p.mouse_down_callback( p.mouse_down_callback );
+ slider_p.mouse_up_callback( p.mouse_up_callback );
+ mSlider = LLUICtrlFactory::create<LLSlider> (slider_p);
+
addChild( mSlider );
- if( show_text )
+ if( p.show_text() )
{
LLRect text_rect( text_left, top, getRect().getWidth(), bottom );
- if( can_edit_text )
+ if( p.can_edit_text() )
{
- mEditor = new LLLineEditor( std::string("SliderCtrl Editor"), text_rect,
- LLStringUtil::null, font,
- MAX_STRING_LENGTH,
- &LLSliderCtrl::onEditorCommit, NULL, NULL, this,
- &LLLineEditor::prevalidateFloat );
- mEditor->setFollowsLeft();
- mEditor->setFollowsBottom();
+ LLLineEditor::Params line_p(p.value_editor);
+ line_p.rect.setIfNotProvided(text_rect);
+ line_p.font.setIfNotProvided(p.font);
+ line_p.commit_callback.function(&LLSliderCtrl::onEditorCommit);
+ line_p.prevalidate_callback(&LLLineEditor::prevalidateFloat);
+ mEditor = LLUICtrlFactory::create<LLLineEditor>(line_p);
+
mEditor->setFocusReceivedCallback( &LLSliderCtrl::onEditorGainFocus, this );
- mEditor->setIgnoreTab(TRUE);
// don't do this, as selecting the entire text is single clicking in some cases
// and double clicking in others
//mEditor->setSelectAllonFocusReceived(TRUE);
@@ -134,9 +151,10 @@ LLSliderCtrl::LLSliderCtrl(const std::string& name, const LLRect& rect,
}
else
{
- mTextBox = new LLTextBox( std::string("SliderCtrl Text"), text_rect, LLStringUtil::null, font);
- mTextBox->setFollowsLeft();
- mTextBox->setFollowsBottom();
+ LLTextBox::Params text_p(p.value_text);
+ text_p.rect.setIfNotProvided(text_rect);
+ text_p.font.setIfNotProvided(p.font);
+ mTextBox = LLUICtrlFactory::create<LLTextBox>(text_p);
addChild(mTextBox);
}
}
@@ -144,7 +162,6 @@ LLSliderCtrl::LLSliderCtrl(const std::string& name, const LLRect& rect,
updateText();
}
-
// static
void LLSliderCtrl::onEditorGainFocus( LLFocusableElement* caller, void *userdata )
{
@@ -179,7 +196,8 @@ BOOL LLSliderCtrl::setLabelArg( const std::string& key, const LLStringExplicit&
S32 delta = rect.mRight - prev_right;
rect = mSlider->getRect();
S32 left = rect.mLeft + delta;
- left = llclamp(left, 0, rect.mRight-SLIDERCTRL_SPACING);
+ static LLUICachedControl<S32> sliderctrl_spacing ("UISliderctrlSpacing", 0);
+ left = llclamp(left, 0, rect.mRight - sliderctrl_spacing);
rect.mLeft = left;
mSlider->setRect(rect);
}
@@ -224,10 +242,11 @@ void LLSliderCtrl::updateText()
}
// static
-void LLSliderCtrl::onEditorCommit( LLUICtrl* caller, void *userdata )
+void LLSliderCtrl::onEditorCommit( LLUICtrl* ctrl, const LLSD& userdata )
{
- LLSliderCtrl* self = (LLSliderCtrl*) userdata;
- llassert( caller == self->mEditor );
+ LLSliderCtrl* self = dynamic_cast<LLSliderCtrl*>(ctrl->getParent());
+ if (!self)
+ return;
BOOL success = FALSE;
F32 val = self->mValue;
@@ -240,17 +259,9 @@ void LLSliderCtrl::onEditorCommit( LLUICtrl* caller, void *userdata )
val = (F32) atof( text.c_str() );
if( self->mSlider->getMinValue() <= val && val <= self->mSlider->getMaxValue() )
{
- if( self->mValidateCallback )
+ self->setValue( val ); // set the value temporarily so that the callback can retrieve it.
+ if( self->mValidateSignal( self, val ) )
{
- self->setValue( val ); // set the value temporarily so that the callback can retrieve it.
- if( self->mValidateCallback( self, self->mCallbackUserData ) )
- {
- success = TRUE;
- }
- }
- else
- {
- self->setValue( val );
success = TRUE;
}
}
@@ -272,26 +283,19 @@ void LLSliderCtrl::onEditorCommit( LLUICtrl* caller, void *userdata )
}
// static
-void LLSliderCtrl::onSliderCommit( LLUICtrl* caller, void *userdata )
+void LLSliderCtrl::onSliderCommit( LLUICtrl* ctrl, const LLSD& userdata )
{
- LLSliderCtrl* self = (LLSliderCtrl*) userdata;
- llassert( caller == self->mSlider );
+ LLSliderCtrl* self = dynamic_cast<LLSliderCtrl*>(ctrl->getParent());
+ if (!self)
+ return;
BOOL success = FALSE;
F32 saved_val = self->mValue;
F32 new_val = self->mSlider->getValueF32();
- if( self->mValidateCallback )
+ self->mValue = new_val; // set the value temporarily so that the callback can retrieve it.
+ if( self->mValidateSignal( self, new_val ) )
{
- self->mValue = new_val; // set the value temporarily so that the callback can retrieve it.
- if( self->mValidateCallback( self, self->mCallbackUserData ) )
- {
- success = TRUE;
- }
- }
- else
- {
- self->mValue = new_val;
success = TRUE;
}
@@ -316,7 +320,7 @@ void LLSliderCtrl::setEnabled(BOOL b)
if( mLabelBox )
{
- mLabelBox->setColor( b ? mTextEnabledColor : mTextDisabledColor );
+ mLabelBox->setColor( b ? mTextEnabledColor.get() : mTextDisabledColor.get() );
}
mSlider->setEnabled( b );
@@ -328,7 +332,7 @@ void LLSliderCtrl::setEnabled(BOOL b)
if( mTextBox )
{
- mTextBox->setColor( b ? mTextEnabledColor : mTextDisabledColor );
+ mTextBox->setColor( b ? mTextEnabledColor.get() : mTextDisabledColor.get() );
}
}
@@ -339,7 +343,7 @@ void LLSliderCtrl::setTentative(BOOL b)
{
mEditor->setTentative(b);
}
- LLUICtrl::setTentative(b);
+ LLF32UICtrl::setTentative(b);
}
@@ -351,8 +355,9 @@ void LLSliderCtrl::onCommit()
{
mEditor->setTentative(FALSE);
}
-
- LLUICtrl::onCommit();
+
+ setControlValue(getValueF32());
+ LLF32UICtrl::onCommit();
}
@@ -368,37 +373,14 @@ void LLSliderCtrl::setPrecision(S32 precision)
updateText();
}
-void LLSliderCtrl::setSliderMouseDownCallback( void (*slider_mousedown_callback)(LLUICtrl* caller, void* userdata) )
-{
- mSliderMouseDownCallback = slider_mousedown_callback;
- mSlider->setMouseDownCallback( LLSliderCtrl::onSliderMouseDown );
-}
-
-// static
-void LLSliderCtrl::onSliderMouseDown(LLUICtrl* caller, void* userdata)
-{
- LLSliderCtrl* self = (LLSliderCtrl*) userdata;
- if( self->mSliderMouseDownCallback )
- {
- self->mSliderMouseDownCallback( self, self->mCallbackUserData );
- }
-}
-
-
-void LLSliderCtrl::setSliderMouseUpCallback( void (*slider_mouseup_callback)(LLUICtrl* caller, void* userdata) )
+boost::signals2::connection LLSliderCtrl::setSliderMouseDownCallback( const commit_signal_t::slot_type& cb )
{
- mSliderMouseUpCallback = slider_mouseup_callback;
- mSlider->setMouseUpCallback( LLSliderCtrl::onSliderMouseUp );
+ return mSlider->setMouseDownCallback( cb );
}
-// static
-void LLSliderCtrl::onSliderMouseUp(LLUICtrl* caller, void* userdata)
+boost::signals2::connection LLSliderCtrl::setSliderMouseUpCallback( const commit_signal_t::slot_type& cb )
{
- LLSliderCtrl* self = (LLSliderCtrl*) userdata;
- if( self->mSliderMouseUpCallback )
- {
- self->mSliderMouseUpCallback( self, self->mCallbackUserData );
- }
+ return mSlider->setMouseUpCallback( cb );
}
void LLSliderCtrl::onTabInto()
@@ -414,131 +396,4 @@ void LLSliderCtrl::reportInvalidData()
make_ui_sound("UISndBadKeystroke");
}
-// virtual
-LLXMLNodePtr LLSliderCtrl::getXML(bool save_children) const
-{
- LLXMLNodePtr node = LLUICtrl::getXML();
-
- node->createChild("show_text", TRUE)->setBoolValue(mShowText);
-
- node->createChild("can_edit_text", TRUE)->setBoolValue(mCanEditText);
-
- node->createChild("volume", TRUE)->setBoolValue(mVolumeSlider);
-
- node->createChild("decimal_digits", TRUE)->setIntValue(mPrecision);
-
- if (mLabelBox)
- {
- node->createChild("label", TRUE)->setStringValue(mLabelBox->getText());
- }
-
- // TomY TODO: Do we really want to export the transient state of the slider?
- node->createChild("value", TRUE)->setFloatValue(mValue);
-
- if (mSlider)
- {
- node->createChild("initial_val", TRUE)->setFloatValue(mSlider->getInitialValue());
- node->createChild("min_val", TRUE)->setFloatValue(mSlider->getMinValue());
- node->createChild("max_val", TRUE)->setFloatValue(mSlider->getMaxValue());
- node->createChild("increment", TRUE)->setFloatValue(mSlider->getIncrement());
- }
- addColorXML(node, mTextEnabledColor, "text_enabled_color", "LabelTextColor");
- addColorXML(node, mTextDisabledColor, "text_disabled_color", "LabelDisabledColor");
-
- return node;
-}
-
-LLView* LLSliderCtrl::fromXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFactory *factory)
-{
- std::string name("slider");
- node->getAttributeString("name", name);
-
- std::string label;
- node->getAttributeString("label", label);
-
- LLRect rect;
- createRect(node, rect, parent, LLRect());
-
- LLFontGL* font = LLView::selectFont(node);
-
- // HACK: Font might not be specified.
- if (!font)
- {
- font = LLFontGL::getFontSansSerifSmall();
- }
-
- S32 label_width = 0;
- node->getAttributeS32("label_width", label_width);
- BOOL show_text = TRUE;
- node->getAttributeBOOL("show_text", show_text);
-
- BOOL can_edit_text = FALSE;
- node->getAttributeBOOL("can_edit_text", can_edit_text);
-
- BOOL volume = FALSE;
- node->getAttributeBOOL("volume", volume);
-
- F32 initial_value = 0.f;
- node->getAttributeF32("initial_val", initial_value);
-
- F32 min_value = 0.f;
- node->getAttributeF32("min_val", min_value);
-
- F32 max_value = 1.f;
- node->getAttributeF32("max_val", max_value);
-
- F32 increment = 0.1f;
- node->getAttributeF32("increment", increment);
-
- U32 precision = 3;
- node->getAttributeU32("decimal_digits", precision);
-
- S32 text_left = 0;
- if (show_text)
- {
- // calculate the size of the text box (log max_value is number of digits - 1 so plus 1)
- if ( max_value )
- text_left = font->getWidth(std::string("0")) * ( static_cast < S32 > ( log10 ( max_value ) ) + precision + 1 );
-
- if ( increment < 1.0f )
- text_left += font->getWidth(std::string(".")); // (mostly) take account of decimal point in value
-
- if ( min_value < 0.0f || max_value < 0.0f )
- text_left += font->getWidth(std::string("-")); // (mostly) take account of minus sign
-
- // padding to make things look nicer
- text_left += 8;
- }
-
- LLUICtrlCallback callback = NULL;
-
- if (label.empty())
- {
- label.assign(node->getTextContents());
- }
-
- LLSliderCtrl* slider = new LLSliderCtrl(name,
- rect,
- label,
- font,
- label_width,
- rect.getWidth() - text_left,
- show_text,
- can_edit_text,
- volume,
- callback,
- NULL,
- initial_value,
- min_value,
- max_value,
- increment);
-
- slider->setPrecision(precision);
-
- slider->initFromXML(node, parent);
-
- slider->updateText();
-
- return slider;
-}
diff --git a/indra/llui/llsliderctrl.h b/indra/llui/llsliderctrl.h
index 272dd7ffd3..4a1574d502 100644
--- a/indra/llui/llsliderctrl.h
+++ b/indra/llui/llsliderctrl.h
@@ -38,83 +38,99 @@
#include "llslider.h"
#include "lltextbox.h"
#include "llrect.h"
+#include "lllineeditor.h"
-//
-// Constants
-//
-const S32 SLIDERCTRL_SPACING = 4; // space between label, slider, and text
-const S32 SLIDERCTRL_HEIGHT = 16;
-
-class LLSliderCtrl : public LLUICtrl
+class LLSliderCtrl : public LLF32UICtrl
{
public:
- LLSliderCtrl(const std::string& name,
- const LLRect& rect,
- const std::string& label,
- const LLFontGL* font,
- S32 slider_left,
- S32 text_left,
- BOOL show_text,
- BOOL can_edit_text,
- BOOL volume, //TODO: create a "volume" slider sub-class or just use image art, no? -MG
- void (*commit_callback)(LLUICtrl*, void*),
- void* callback_userdata,
- F32 initial_value, F32 min_value, F32 max_value, F32 increment,
- const std::string& control_which = LLStringUtil::null );
-
+ struct Params : public LLInitParam::Block<Params, LLF32UICtrl::Params>
+ {
+ Optional<S32> label_width;
+ Optional<S32> text_width;
+ Optional<bool> show_text;
+ Optional<bool> can_edit_text;
+ Optional<bool> is_volume_slider;
+ Optional<S32> decimal_digits;
+
+ Optional<LLUIColor> text_color,
+ text_disabled_color;
+
+ Optional<CommitCallbackParam> mouse_down_callback,
+ mouse_up_callback;
+
+ Optional<LLSlider::Params> slider_bar;
+ Optional<LLLineEditor::Params> value_editor;
+ Optional<LLTextBox::Params> value_text;
+ Optional<LLTextBox::Params> slider_label;
+
+ Params()
+ : text_width("text_width"),
+ label_width("label_width"),
+ show_text("show_text"),
+ can_edit_text("can_edit_text"),
+ is_volume_slider("volume"),
+ decimal_digits("decimal_digits", 3),
+ text_color("text_color"),
+ text_disabled_color("text_disabled_color"),
+ slider_bar("slider_bar"),
+ value_editor("value_editor"),
+ value_text("value_text"),
+ slider_label("slider_label"),
+ mouse_down_callback("mouse_down_callback"),
+ mouse_up_callback("mouse_up_callback")
+ {}
+ };
+protected:
+ LLSliderCtrl(const Params&);
+ friend class LLUICtrlFactory;
+public:
virtual ~LLSliderCtrl() {} // Children all cleaned up by default view destructor.
- virtual LLXMLNodePtr getXML(bool save_children = true) const;
- static LLView* fromXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFactory *factory);
-
- F32 getValueF32() const { return mSlider->getValueF32(); }
+ /*virtual*/ F32 getValueF32() const { return mSlider->getValueF32(); }
void setValue(F32 v, BOOL from_event = FALSE);
- virtual void setValue(const LLSD& value) { setValue((F32)value.asReal(), TRUE); }
- virtual LLSD getValue() const { return LLSD(getValueF32()); }
- virtual BOOL setLabelArg( const std::string& key, const LLStringExplicit& text );
-
- virtual void setMinValue(LLSD min_value) { setMinValue((F32)min_value.asReal()); }
- virtual void setMaxValue(LLSD max_value) { setMaxValue((F32)max_value.asReal()); }
+ /*virtual*/ void setValue(const LLSD& value) { setValue((F32)value.asReal(), TRUE); }
+ /*virtual*/ LLSD getValue() const { return LLSD(getValueF32()); }
+ /*virtual*/ BOOL setLabelArg( const std::string& key, const LLStringExplicit& text );
BOOL isMouseHeldDown() const { return mSlider->hasMouseCapture(); }
- virtual void setEnabled( BOOL b );
- virtual void clear();
virtual void setPrecision(S32 precision);
- void setMinValue(F32 min_value) { mSlider->setMinValue(min_value); updateText(); }
- void setMaxValue(F32 max_value) { mSlider->setMaxValue(max_value); updateText(); }
- void setIncrement(F32 increment) { mSlider->setIncrement(increment);}
- F32 getMinValue() { return mSlider->getMinValue(); }
- F32 getMaxValue() { return mSlider->getMaxValue(); }
+ /*virtual*/ void setEnabled( BOOL b );
+ /*virtual*/ void clear();
+
+ /*virtual*/ void setMinValue(const LLSD& min_value) { setMinValue((F32)min_value.asReal()); }
+ /*virtual*/ void setMaxValue(const LLSD& max_value) { setMaxValue((F32)max_value.asReal()); }
+ /*virtual*/ void setMinValue(F32 min_value) { mSlider->setMinValue(min_value); updateText(); }
+ /*virtual*/ void setMaxValue(F32 max_value) { mSlider->setMaxValue(max_value); updateText(); }
+ /*virtual*/ void setIncrement(F32 increment) { mSlider->setIncrement(increment);}
+
+ F32 getMinValue() const { return mSlider->getMinValue(); }
+ F32 getMaxValue() const { return mSlider->getMaxValue(); }
void setLabel(const LLStringExplicit& label) { if (mLabelBox) mLabelBox->setText(label); }
void setLabelColor(const LLColor4& c) { mTextEnabledColor = c; }
void setDisabledLabelColor(const LLColor4& c) { mTextDisabledColor = c; }
- void setSliderMouseDownCallback( void (*slider_mousedown_callback)(LLUICtrl* caller, void* userdata) );
- void setSliderMouseUpCallback( void (*slider_mouseup_callback)(LLUICtrl* caller, void* userdata) );
+ boost::signals2::connection setSliderMouseDownCallback( const commit_signal_t::slot_type& cb );
+ boost::signals2::connection setSliderMouseUpCallback( const commit_signal_t::slot_type& cb );
- virtual void onTabInto();
+ /*virtual*/ void onTabInto();
- virtual void setTentative(BOOL b); // marks value as tentative
- virtual void onCommit(); // mark not tentative, then commit
+ /*virtual*/ void setTentative(BOOL b); // marks value as tentative
+ /*virtual*/ void onCommit(); // mark not tentative, then commit
- virtual void setControlName(const std::string& control_name, LLView* context)
+ /*virtual*/ void setControlName(const std::string& control_name, LLView* context)
{
- LLView::setControlName(control_name, context);
+ LLUICtrl::setControlName(control_name, context);
mSlider->setControlName(control_name, context);
}
- virtual std::string getControlName() const { return mSlider->getControlName(); }
+ static void onSliderCommit(LLUICtrl* caller, const LLSD& userdata);
- static void onSliderCommit(LLUICtrl* caller, void* userdata);
- static void onSliderMouseDown(LLUICtrl* caller,void* userdata);
- static void onSliderMouseUp(LLUICtrl* caller,void* userdata);
-
- static void onEditorCommit(LLUICtrl* caller, void* userdata);
+ static void onEditorCommit(LLUICtrl* ctrl, const LLSD& userdata);
static void onEditorGainFocus(LLFocusableElement* caller, void *userdata);
static void onEditorChangeFocus(LLUICtrl* caller, S32 direction, void *userdata);
@@ -125,7 +141,6 @@ private:
const LLFontGL* mFont;
BOOL mShowText;
BOOL mCanEditText;
- BOOL mVolumeSlider;
S32 mPrecision;
LLTextBox* mLabelBox;
@@ -136,11 +151,8 @@ private:
class LLLineEditor* mEditor;
LLTextBox* mTextBox;
- LLColor4 mTextEnabledColor;
- LLColor4 mTextDisabledColor;
-
- void (*mSliderMouseUpCallback)( LLUICtrl* ctrl, void* userdata );
- void (*mSliderMouseDownCallback)( LLUICtrl* ctrl, void* userdata );
+ LLUIColor mTextEnabledColor;
+ LLUIColor mTextDisabledColor;
};
#endif // LL_LLSLIDERCTRL_H
diff --git a/indra/llui/llspinctrl.cpp b/indra/llui/llspinctrl.cpp
index c54a2cd140..3a96bc8f93 100644
--- a/indra/llui/llspinctrl.cpp
+++ b/indra/llui/llspinctrl.cpp
@@ -45,101 +45,114 @@
#include "lltextbox.h"
#include "llkeyboard.h"
#include "llmath.h"
-#include "audioengine.h"
#include "llcontrol.h"
#include "llfocusmgr.h"
#include "llresmgr.h"
+#include "lluictrlfactory.h"
const U32 MAX_STRING_LENGTH = 32;
-static LLRegisterWidget<LLSpinCtrl> r2("spinner");
-
-LLSpinCtrl::LLSpinCtrl( const std::string& name, const LLRect& rect, const std::string& label, const LLFontGL* font,
- void (*commit_callback)(LLUICtrl*, void*),
- void* callback_user_data,
- F32 initial_value, F32 min_value, F32 max_value, F32 increment,
- const std::string& control_name,
- S32 label_width)
- :
- LLUICtrl(name, rect, TRUE, commit_callback, callback_user_data, FOLLOWS_LEFT | FOLLOWS_TOP ),
- mValue( initial_value ),
- mInitialValue( initial_value ),
- mMaxValue( max_value ),
- mMinValue( min_value ),
- mIncrement( increment ),
- mPrecision( 3 ),
- mLabelBox( NULL ),
- mTextEnabledColor( LLUI::sColorsGroup->getColor( "LabelTextColor" ) ),
- mTextDisabledColor( LLUI::sColorsGroup->getColor( "LabelDisabledColor" ) ),
- mbHasBeenSet( FALSE )
+static LLDefaultChildRegistry::Register<LLSpinCtrl> r2("spinner");
+
+LLSpinCtrl::Params::Params()
+: label_width("label_width"),
+ decimal_digits("decimal_digits"),
+ allow_text_entry("allow_text_entry", true),
+ text_enabled_color("text_enabled_color"),
+ text_disabled_color("text_disabled_color"),
+ up_button("up_button"),
+ down_button("down_button")
+{}
+
+LLSpinCtrl::LLSpinCtrl(const LLSpinCtrl::Params& p)
+: LLF32UICtrl(p),
+ mLabelBox(NULL),
+ mbHasBeenSet( FALSE ),
+ mPrecision(p.decimal_digits),
+ mTextEnabledColor(p.text_enabled_color()),
+ mTextDisabledColor(p.text_disabled_color())
{
+ static LLUICachedControl<S32> spinctrl_spacing ("UISpinctrlSpacing", 0);
+ static LLUICachedControl<S32> spinctrl_btn_width ("UISpinctrlBtnWidth", 0);
+ static LLUICachedControl<S32> spinctrl_btn_height ("UISpinctrlBtnHeight", 0);
S32 top = getRect().getHeight();
- S32 bottom = top - 2 * SPINCTRL_BTN_HEIGHT;
+ S32 bottom = top - 2 * spinctrl_btn_height;
S32 centered_top = top;
S32 centered_bottom = bottom;
S32 btn_left = 0;
+ // reserve space for spinner
+ S32 label_width = llclamp(p.label_width(), 0, llmax(0, getRect().getWidth() - 40));
// Label
- if( !label.empty() )
+ if( !p.label().empty() )
{
LLRect label_rect( 0, centered_top, label_width, centered_bottom );
- mLabelBox = new LLTextBox( std::string("SpinCtrl Label"), label_rect, label, font );
+ LLTextBox::Params params;
+ params.name("SpinCtrl Label");
+ params.rect(label_rect);
+ params.text(p.label);
+ if (p.font.isProvided())
+ {
+ params.font(p.font);
+ }
+ mLabelBox = LLUICtrlFactory::create<LLTextBox> (params);
addChild(mLabelBox);
- btn_left += label_rect.mRight + SPINCTRL_SPACING;
+ btn_left += label_rect.mRight + spinctrl_spacing;
}
- S32 btn_right = btn_left + SPINCTRL_BTN_WIDTH;
+ S32 btn_right = btn_left + spinctrl_btn_width;
// Spin buttons
- LLRect up_rect( btn_left, top, btn_right, top - SPINCTRL_BTN_HEIGHT );
- std::string out_id = "UIImgBtnSpinUpOutUUID";
- std::string in_id = "UIImgBtnSpinUpInUUID";
- mUpBtn = new LLButton(std::string("SpinCtrl Up"), up_rect,
- out_id,
- in_id,
- LLStringUtil::null,
- &LLSpinCtrl::onUpBtn, this, LLFontGL::getFontSansSerif() );
- mUpBtn->setFollowsLeft();
- mUpBtn->setFollowsBottom();
- mUpBtn->setHeldDownCallback( &LLSpinCtrl::onUpBtn );
- mUpBtn->setTabStop(FALSE);
+ LLButton::Params up_button_params(p.up_button);
+ up_button_params.rect
+ .left(btn_left)
+ .top(top)
+ .right(btn_right)
+ .height(spinctrl_btn_height);
+ up_button_params.click_callback.function(boost::bind(&LLSpinCtrl::onUpBtn, this, _2));
+ up_button_params.mouse_held_callback.function(boost::bind(&LLSpinCtrl::onUpBtn, this, _2));
+
+ mUpBtn = LLUICtrlFactory::create<LLButton>(up_button_params);
addChild(mUpBtn);
- LLRect down_rect( btn_left, top - SPINCTRL_BTN_HEIGHT, btn_right, bottom );
- out_id = "UIImgBtnSpinDownOutUUID";
- in_id = "UIImgBtnSpinDownInUUID";
- mDownBtn = new LLButton(std::string("SpinCtrl Down"), down_rect,
- out_id,
- in_id,
- LLStringUtil::null,
- &LLSpinCtrl::onDownBtn, this, LLFontGL::getFontSansSerif() );
- mDownBtn->setFollowsLeft();
- mDownBtn->setFollowsBottom();
- mDownBtn->setHeldDownCallback( &LLSpinCtrl::onDownBtn );
- mDownBtn->setTabStop(FALSE);
+ LLRect down_rect( btn_left, top - spinctrl_btn_height, btn_right, bottom );
+
+ LLButton::Params down_button_params(p.down_button);
+ down_button_params.rect
+ .left(btn_left)
+ .right(btn_right)
+ .bottom(bottom)
+ .height(spinctrl_btn_height);
+ down_button_params.click_callback.function(boost::bind(&LLSpinCtrl::onDownBtn, this, _2));
+ down_button_params.mouse_held_callback.function(boost::bind(&LLSpinCtrl::onDownBtn, this, _2));
+ mDownBtn = LLUICtrlFactory::create<LLButton>(down_button_params);
addChild(mDownBtn);
LLRect editor_rect( btn_right + 1, centered_top, getRect().getWidth(), centered_bottom );
- mEditor = new LLLineEditor( std::string("SpinCtrl Editor"), editor_rect, LLStringUtil::null, font,
- MAX_STRING_LENGTH,
- &LLSpinCtrl::onEditorCommit, NULL, NULL, this,
- &LLLineEditor::prevalidateFloat );
- mEditor->setFollowsLeft();
- mEditor->setFollowsBottom();
+ LLLineEditor::Params params;
+ params.name("SpinCtrl Editor");
+ params.rect(editor_rect);
+ if (p.font.isProvided())
+ {
+ params.font(p.font);
+ }
+ params.max_length_bytes(MAX_STRING_LENGTH);
+ params.commit_callback.function((boost::bind(&LLSpinCtrl::onEditorCommit, this, _2)));
+ params.prevalidate_callback(&LLLineEditor::prevalidateFloat);
+ params.follows.flags(FOLLOWS_LEFT | FOLLOWS_BOTTOM);
+ mEditor = LLUICtrlFactory::create<LLLineEditor> (params);
mEditor->setFocusReceivedCallback( &LLSpinCtrl::onEditorGainFocus, this );
//RN: this seems to be a BAD IDEA, as it makes the editor behavior different when it has focus
// than when it doesn't. Instead, if you always have to double click to select all the text,
// it's easier to understand
//mEditor->setSelectAllonFocusReceived(TRUE);
- mEditor->setIgnoreTab(TRUE);
addChild(mEditor);
updateEditor();
setUseBoundingRect( TRUE );
}
-
F32 clamp_precision(F32 value, S32 decimal_precision)
{
// pow() isn't perfect
@@ -157,69 +170,71 @@ F32 clamp_precision(F32 value, S32 decimal_precision)
}
-// static
-void LLSpinCtrl::onUpBtn( void *userdata )
+void LLSpinCtrl::onUpBtn( const LLSD& data )
{
- LLSpinCtrl* self = (LLSpinCtrl*) userdata;
- if( self->getEnabled() )
+ if( getEnabled() )
{
- // use getValue()/setValue() to force reload from/to control
- F32 val = (F32)self->getValue().asReal() + self->mIncrement;
- val = clamp_precision(val, self->mPrecision);
- val = llmin( val, self->mMaxValue );
-
- if( self->mValidateCallback )
+ std::string text = mEditor->getText();
+ if( LLLineEditor::postvalidateFloat( text ) )
{
- F32 saved_val = (F32)self->getValue().asReal();
- self->setValue(val);
- if( !self->mValidateCallback( self, self->mCallbackUserData ) )
+
+ LLLocale locale(LLLocale::USER_LOCALE);
+ F32 cur_val = (F32) atof(text.c_str());
+
+ // use getValue()/setValue() to force reload from/to control
+ F32 val = cur_val + mIncrement;
+ val = clamp_precision(val, mPrecision);
+ val = llmin( val, mMaxValue );
+ if (val < mMinValue) val = mMinValue;
+ if (val > mMaxValue) val = mMaxValue;
+
+ F32 saved_val = (F32)getValue().asReal();
+ setValue(val);
+ if( !mValidateSignal( this, val ) )
{
- self->setValue( saved_val );
- self->reportInvalidData();
- self->updateEditor();
+ setValue( saved_val );
+ reportInvalidData();
+ updateEditor();
return;
}
- }
- else
- {
- self->setValue(val);
- }
- self->updateEditor();
- self->onCommit();
+ updateEditor();
+ onCommit();
+ }
}
}
-// static
-void LLSpinCtrl::onDownBtn( void *userdata )
+void LLSpinCtrl::onDownBtn( const LLSD& data )
{
- LLSpinCtrl* self = (LLSpinCtrl*) userdata;
-
- if( self->getEnabled() )
+ if( getEnabled() )
{
- F32 val = (F32)self->getValue().asReal() - self->mIncrement;
- val = clamp_precision(val, self->mPrecision);
- val = llmax( val, self->mMinValue );
-
- if( self->mValidateCallback )
+ std::string text = mEditor->getText();
+ if( LLLineEditor::postvalidateFloat( text ) )
{
- F32 saved_val = (F32)self->getValue().asReal();
- self->setValue(val);
- if( !self->mValidateCallback( self, self->mCallbackUserData ) )
+
+ LLLocale locale(LLLocale::USER_LOCALE);
+ F32 cur_val = (F32) atof(text.c_str());
+
+ F32 val = cur_val - mIncrement;
+ val = clamp_precision(val, mPrecision);
+ val = llmax( val, mMinValue );
+
+ if (val < mMinValue) val = mMinValue;
+ if (val > mMaxValue) val = mMaxValue;
+
+ F32 saved_val = (F32)getValue().asReal();
+ setValue(val);
+ if( !mValidateSignal( this, val ) )
{
- self->setValue( saved_val );
- self->reportInvalidData();
- self->updateEditor();
+ setValue( saved_val );
+ reportInvalidData();
+ updateEditor();
return;
}
- }
- else
- {
- self->setValue(val);
- }
- self->updateEditor();
- self->onCommit();
+ updateEditor();
+ onCommit();
+ }
}
}
@@ -235,10 +250,10 @@ void LLSpinCtrl::onEditorGainFocus( LLFocusableElement* caller, void *userdata )
void LLSpinCtrl::setValue(const LLSD& value )
{
F32 v = (F32)value.asReal();
- if (mValue != v || !mbHasBeenSet)
+ if (getValueF32() != v || !mbHasBeenSet)
{
mbHasBeenSet = TRUE;
- mValue = v;
+ LLF32UICtrl::setValue(value);
if (!mEditor->hasFocus())
{
@@ -251,10 +266,10 @@ void LLSpinCtrl::setValue(const LLSD& value )
void LLSpinCtrl::forceSetValue(const LLSD& value )
{
F32 v = (F32)value.asReal();
- if (mValue != v || !mbHasBeenSet)
+ if (getValueF32() != v || !mbHasBeenSet)
{
mbHasBeenSet = TRUE;
- mValue = v;
+ LLF32UICtrl::setValue(value);
updateEditor();
}
@@ -286,55 +301,43 @@ void LLSpinCtrl::updateEditor()
mEditor->setText( text );
}
-void LLSpinCtrl::onEditorCommit( LLUICtrl* caller, void *userdata )
+void LLSpinCtrl::onEditorCommit( const LLSD& data )
{
BOOL success = FALSE;
- LLSpinCtrl* self = (LLSpinCtrl*) userdata;
- llassert( caller == self->mEditor );
-
- std::string text = self->mEditor->getText();
+ std::string text = mEditor->getText();
if( LLLineEditor::postvalidateFloat( text ) )
{
LLLocale locale(LLLocale::USER_LOCALE);
F32 val = (F32) atof(text.c_str());
- if (val < self->mMinValue) val = self->mMinValue;
- if (val > self->mMaxValue) val = self->mMaxValue;
+ if (val < mMinValue) val = mMinValue;
+ if (val > mMaxValue) val = mMaxValue;
- if( self->mValidateCallback )
+ F32 saved_val = getValueF32();
+ setValue(val);
+ if( mValidateSignal( this, val ) )
{
- F32 saved_val = self->mValue;
- self->mValue = val;
- if( self->mValidateCallback( self, self->mCallbackUserData ) )
- {
- success = TRUE;
- self->onCommit();
- }
- else
- {
- self->mValue = saved_val;
- }
+ success = TRUE;
+ onCommit();
}
else
{
- self->mValue = val;
- self->onCommit();
- success = TRUE;
+ setValue(saved_val);
}
}
- self->updateEditor();
+ updateEditor();
if( !success )
{
- self->reportInvalidData();
+ reportInvalidData();
}
}
void LLSpinCtrl::forceEditorCommit()
{
- onEditorCommit(mEditor, this);
+ onEditorCommit( LLSD() );
}
@@ -348,6 +351,10 @@ void LLSpinCtrl::setEnabled(BOOL b)
{
LLView::setEnabled( b );
mEditor->setEnabled( b );
+ if( mLabelBox )
+ {
+ mLabelBox->setColor( b ? mTextEnabledColor.get() : mTextDisabledColor.get() );
+ }
}
@@ -368,8 +375,8 @@ BOOL LLSpinCtrl::isMouseHeldDown() const
void LLSpinCtrl::onCommit()
{
setTentative(FALSE);
- setControlValue(mValue);
- LLUICtrl::onCommit();
+ setControlValue(getValueF32());
+ LLF32UICtrl::onCommit();
}
@@ -414,29 +421,19 @@ void LLSpinCtrl::reportInvalidData()
make_ui_sound("UISndBadKeystroke");
}
-void LLSpinCtrl::draw()
-{
- if( mLabelBox )
- {
- mLabelBox->setColor( getEnabled() ? mTextEnabledColor : mTextDisabledColor );
- }
- LLUICtrl::draw();
-}
-
-
BOOL LLSpinCtrl::handleScrollWheel(S32 x, S32 y, S32 clicks)
{
if( clicks > 0 )
{
while( clicks-- )
{
- LLSpinCtrl::onDownBtn(this);
+ onDownBtn(getValue());
}
}
else
while( clicks++ )
{
- LLSpinCtrl::onUpBtn(this);
+ onUpBtn(getValue());
}
return TRUE;
@@ -456,105 +453,15 @@ BOOL LLSpinCtrl::handleKeyHere(KEY key, MASK mask)
}
if(key == KEY_UP)
{
- LLSpinCtrl::onUpBtn(this);
+ onUpBtn(getValue());
return TRUE;
}
if(key == KEY_DOWN)
{
- LLSpinCtrl::onDownBtn(this);
+ onDownBtn(getValue());
return TRUE;
}
}
return FALSE;
}
-// virtual
-LLXMLNodePtr LLSpinCtrl::getXML(bool save_children) const
-{
- LLXMLNodePtr node = LLUICtrl::getXML();
-
- node->createChild("decimal_digits", TRUE)->setIntValue(mPrecision);
-
- if (mLabelBox)
- {
- node->createChild("label", TRUE)->setStringValue(mLabelBox->getText());
-
- node->createChild("label_width", TRUE)->setIntValue(mLabelBox->getRect().getWidth());
- }
-
- node->createChild("initial_val", TRUE)->setFloatValue(mInitialValue);
-
- node->createChild("min_val", TRUE)->setFloatValue(mMinValue);
-
- node->createChild("max_val", TRUE)->setFloatValue(mMaxValue);
-
- node->createChild("increment", TRUE)->setFloatValue(mIncrement);
-
- addColorXML(node, mTextEnabledColor, "text_enabled_color", "LabelTextColor");
- addColorXML(node, mTextDisabledColor, "text_disabled_color", "LabelDisabledColor");
-
- return node;
-}
-
-LLView* LLSpinCtrl::fromXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFactory *factory)
-{
- std::string name("spinner");
- node->getAttributeString("name", name);
-
- std::string label;
- node->getAttributeString("label", label);
-
- LLRect rect;
- createRect(node, rect, parent, LLRect());
-
- LLFontGL* font = LLView::selectFont(node);
-
- F32 initial_value = 0.f;
- node->getAttributeF32("initial_val", initial_value);
-
- F32 min_value = 0.f;
- node->getAttributeF32("min_val", min_value);
-
- F32 max_value = 1.f;
- node->getAttributeF32("max_val", max_value);
-
- F32 increment = 0.1f;
- node->getAttributeF32("increment", increment);
-
- U32 precision = 3;
- node->getAttributeU32("decimal_digits", precision);
-
- S32 label_width = llmin(40, rect.getWidth() - 40);
- node->getAttributeS32("label_width", label_width);
-
- BOOL allow_text_entry = TRUE;
- node->getAttributeBOOL("allow_text_entry", allow_text_entry);
-
- LLUICtrlCallback callback = NULL;
-
- if(label.empty())
- {
- label.assign( node->getValue() );
- }
-
- LLSpinCtrl* spinner = new LLSpinCtrl(name,
- rect,
- label,
- font,
- callback,
- NULL,
- initial_value,
- min_value,
- max_value,
- increment,
- LLStringUtil::null,
- label_width);
-
- spinner->setPrecision(precision);
-
- spinner->initFromXML(node, parent);
- spinner->setAllowEdit(allow_text_entry);
-
- return spinner;
-}
-
diff --git a/indra/llui/llspinctrl.h b/indra/llui/llspinctrl.h
index dfd0eb3ac1..0e610b7741 100644
--- a/indra/llui/llspinctrl.h
+++ b/indra/llui/llspinctrl.h
@@ -35,62 +35,50 @@
#include "stdtypes.h"
-#include "lluictrl.h"
+#include "llbutton.h"
+#include "llf32uictrl.h"
#include "v4color.h"
#include "llrect.h"
-//
-// Constants
-//
-const S32 SPINCTRL_BTN_HEIGHT = 8;
-const S32 SPINCTRL_BTN_WIDTH = 16;
-const S32 SPINCTRL_SPACING = 2; // space between label right and button left
-const S32 SPINCTRL_HEIGHT = 2 * SPINCTRL_BTN_HEIGHT;
-const S32 SPINCTRL_DEFAULT_LABEL_WIDTH = 10;
-
class LLSpinCtrl
-: public LLUICtrl
+: public LLF32UICtrl
{
public:
- LLSpinCtrl(const std::string& name, const LLRect& rect,
- const std::string& label,
- const LLFontGL* font,
- void (*commit_callback)(LLUICtrl*, void*),
- void* callback_userdata,
- F32 initial_value, F32 min_value, F32 max_value, F32 increment,
- const std::string& control_name = std::string(),
- S32 label_width = SPINCTRL_DEFAULT_LABEL_WIDTH );
-
+ struct Params : public LLInitParam::Block<Params, LLF32UICtrl::Params>
+ {
+ Optional<S32> label_width;
+ Optional<U32> decimal_digits;
+ Optional<bool> allow_text_entry;
+
+ Optional<LLUIColor> text_enabled_color;
+ Optional<LLUIColor> text_disabled_color;
+
+ Optional<LLButton::Params> up_button;
+ Optional<LLButton::Params> down_button;
+
+ Params();
+ };
+protected:
+ LLSpinCtrl(const Params&);
+ friend class LLUICtrlFactory;
+public:
virtual ~LLSpinCtrl() {} // Children all cleaned up by default view destructor.
- virtual LLXMLNodePtr getXML(bool save_children = true) const;
- static LLView* fromXML(LLXMLNodePtr node, LLView *parent, class LLUICtrlFactory *factory);
-
virtual void forceSetValue(const LLSD& value ) ;
virtual void setValue(const LLSD& value );
- virtual LLSD getValue() const { return mValue; }
- F32 get() const { return (F32)getValue().asReal(); }
+ F32 get() const { return getValueF32(); }
void set(F32 value) { setValue(value); mInitialValue = value; }
- virtual void setMinValue(LLSD min_value) { setMinValue((F32)min_value.asReal()); }
- virtual void setMaxValue(LLSD max_value) { setMaxValue((F32)max_value.asReal()); }
-
BOOL isMouseHeldDown() const;
virtual void setEnabled( BOOL b );
virtual void setFocus( BOOL b );
virtual void clear();
- virtual BOOL isDirty() const { return( mValue != mInitialValue ); }
- virtual void resetDirty() { mInitialValue = mValue; }
+ virtual BOOL isDirty() const { return( getValueF32() != mInitialValue ); }
+ virtual void resetDirty() { mInitialValue = getValueF32(); }
virtual void setPrecision(S32 precision);
- virtual void setMinValue(F32 min) { mMinValue = min; }
- virtual void setMaxValue(F32 max) { mMaxValue = max; }
- virtual void setIncrement(F32 inc) { mIncrement = inc; }
- virtual F32 getMinValue() { return mMinValue ; }
- virtual F32 getMaxValue() { return mMaxValue ; }
- virtual F32 getIncrement() { return mIncrement ; }
void setLabel(const LLStringExplicit& label);
void setLabelColor(const LLColor4& c) { mTextEnabledColor = c; }
@@ -107,31 +95,23 @@ public:
virtual BOOL handleScrollWheel(S32 x,S32 y,S32 clicks);
virtual BOOL handleKeyHere(KEY key, MASK mask);
- virtual void draw();
-
- static void onEditorCommit(LLUICtrl* caller, void* userdata);
+ void onEditorCommit(const LLSD& data);
static void onEditorGainFocus(LLFocusableElement* caller, void *userdata);
static void onEditorChangeFocus(LLUICtrl* caller, S32 direction, void *userdata);
- static void onUpBtn(void *userdata);
- static void onDownBtn(void *userdata);
+ void onUpBtn(const LLSD& data);
+ void onDownBtn(const LLSD& data);
private:
void updateEditor();
void reportInvalidData();
- F32 mValue;
- F32 mInitialValue;
- F32 mMaxValue;
- F32 mMinValue;
- F32 mIncrement;
-
S32 mPrecision;
class LLTextBox* mLabelBox;
class LLLineEditor* mEditor;
- LLColor4 mTextEnabledColor;
- LLColor4 mTextDisabledColor;
+ LLUIColor mTextEnabledColor;
+ LLUIColor mTextDisabledColor;
class LLButton* mUpBtn;
class LLButton* mDownBtn;
diff --git a/indra/llui/llstatbar.cpp b/indra/llui/llstatbar.cpp
new file mode 100644
index 0000000000..bd74b285a7
--- /dev/null
+++ b/indra/llui/llstatbar.cpp
@@ -0,0 +1,293 @@
+/**
+ * @file llstatbar.cpp
+ * @brief A little map of the world with network information
+ *
+ * $LicenseInfo:firstyear=2001&license=viewergpl$
+ *
+ * Copyright (c) 2001-2009, Linden Research, Inc.
+ *
+ * Second Life Viewer Source Code
+ * The source code in this file ("Source Code") is provided by Linden Lab
+ * to you under the terms of the GNU General Public License, version 2.0
+ * ("GPL"), unless you have obtained a separate licensing agreement
+ * ("Other License"), formally executed by you and Linden Lab. Terms of
+ * the GPL can be found in doc/GPL-license.txt in this distribution, or
+ * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
+ *
+ * There are special exceptions to the terms and conditions of the GPL as
+ * it is applied to this Source Code. View the full text of the exception
+ * in the file doc/FLOSS-exception.txt in this software distribution, or
+ * online at
+ * http://secondlifegrid.net/programs/open_source/licensing/flossexception
+ *
+ * By copying, modifying or distributing this software, you acknowledge
+ * that you have read and understood your obligations described above,
+ * and agree to abide by those obligations.
+ *
+ * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+ * COMPLETENESS OR PERFORMANCE.
+ * $/LicenseInfo$
+ */
+
+//#include "llviewerprecompiledheaders.h"
+#include "linden_common.h"
+
+#include "llstatbar.h"
+
+#include "llmath.h"
+#include "llui.h"
+#include "llgl.h"
+#include "llfontgl.h"
+
+#include "llstat.h"
+#include "lluictrlfactory.h"
+
+///////////////////////////////////////////////////////////////////////////////////
+
+LLStatBar::LLStatBar(const Params& p)
+ : LLView(p),
+ mLabel(p.label),
+ mUnitLabel(p.unit_label),
+ mMinBar(p.bar_min),
+ mMaxBar(p.bar_max),
+ mStatp(LLStat::getStat(p.stat)),
+ mTickSpacing(p.tick_spacing),
+ mLabelSpacing(p.label_spacing),
+ mPrecision(p.precision),
+ mUpdatesPerSec(p.update_rate),
+ mPerSec(p.show_per_sec),
+ mDisplayBar(p.show_bar),
+ mDisplayHistory(p.show_history),
+ mDisplayMean(p.show_mean)
+{
+}
+
+BOOL LLStatBar::handleMouseDown(S32 x, S32 y, MASK mask)
+{
+ if (mDisplayBar)
+ {
+ if (mDisplayHistory)
+ {
+ mDisplayBar = FALSE;
+ mDisplayHistory = FALSE;
+ }
+ else
+ {
+ mDisplayHistory = TRUE;
+ }
+ }
+ else
+ {
+ mDisplayBar = TRUE;
+ }
+
+ LLView* parent = getParent();
+ parent->reshape(parent->getRect().getWidth(), parent->getRect().getHeight(), FALSE);
+
+ return FALSE;
+}
+
+void LLStatBar::draw()
+{
+ if (!mStatp)
+ {
+// llinfos << "No stats for statistics bar!" << llendl;
+ return;
+ }
+
+ // Get the values.
+ F32 current, min, max, mean;
+ if (mPerSec)
+ {
+ current = mStatp->getCurrentPerSec();
+ min = mStatp->getMinPerSec();
+ max = mStatp->getMaxPerSec();
+ mean = mStatp->getMeanPerSec();
+ }
+ else
+ {
+ current = mStatp->getCurrent();
+ min = mStatp->getMin();
+ max = mStatp->getMax();
+ mean = mStatp->getMean();
+ }
+
+
+ if ((mUpdatesPerSec == 0.f) || (mUpdateTimer.getElapsedTimeF32() > 1.f/mUpdatesPerSec) || (mValue == 0.f))
+ {
+ if (mDisplayMean)
+ {
+ mValue = mean;
+ }
+ else
+ {
+ mValue = current;
+ }
+ mUpdateTimer.reset();
+ }
+
+ S32 width = getRect().getWidth() - 40;
+ S32 max_width = width;
+ S32 bar_top = getRect().getHeight() - 15; // 16 pixels from top.
+ S32 bar_height = bar_top - 20;
+ S32 tick_height = 4;
+ S32 tick_width = 1;
+ S32 left, top, right, bottom;
+
+ F32 value_scale = max_width/(mMaxBar - mMinBar);
+
+ LLFontGL::getFontMonospace()->renderUTF8(mLabel, 0, 0, getRect().getHeight(), LLColor4(1.f, 1.f, 1.f, 1.f),
+ LLFontGL::LEFT, LLFontGL::TOP);
+
+ std::string value_format;
+ std::string value_str;
+ if (!mUnitLabel.empty())
+ {
+ value_format = llformat( "%%.%df%%s", mPrecision);
+ value_str = llformat( value_format.c_str(), mValue, mUnitLabel.c_str());
+ }
+ else
+ {
+ value_format = llformat( "%%.%df", mPrecision);
+ value_str = llformat( value_format.c_str(), mValue);
+ }
+
+ // Draw the value.
+ LLFontGL::getFontMonospace()->renderUTF8(value_str, 0, width, getRect().getHeight(),
+ LLColor4(1.f, 1.f, 1.f, 0.5f),
+ LLFontGL::RIGHT, LLFontGL::TOP);
+
+ value_format = llformat( "%%.%df", mPrecision);
+ if (mDisplayBar)
+ {
+ std::string tick_label;
+
+ // Draw the tick marks.
+ F32 tick_value;
+ top = bar_top;
+ bottom = bar_top - bar_height - tick_height/2;
+
+ LLGLSUIDefault gls_ui;
+ gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
+
+ for (tick_value = mMinBar; tick_value <= mMaxBar; tick_value += mTickSpacing)
+ {
+ left = llfloor((tick_value - mMinBar)*value_scale);
+ right = left + tick_width;
+ gl_rect_2d(left, top, right, bottom, LLColor4(1.f, 1.f, 1.f, 0.1f));
+ }
+
+ // Draw the tick labels (and big ticks).
+ bottom = bar_top - bar_height - tick_height;
+ for (tick_value = mMinBar; tick_value <= mMaxBar; tick_value += mLabelSpacing)
+ {
+ left = llfloor((tick_value - mMinBar)*value_scale);
+ right = left + tick_width;
+ gl_rect_2d(left, top, right, bottom, LLColor4(1.f, 1.f, 1.f, 0.25f));
+
+ tick_label = llformat( value_format.c_str(), tick_value);
+ // draw labels for the tick marks
+ LLFontGL::getFontMonospace()->renderUTF8(tick_label, 0, left - 1, bar_top - bar_height - tick_height,
+ LLColor4(1.f, 1.f, 1.f, 0.5f),
+ LLFontGL::LEFT, LLFontGL::TOP);
+ }
+
+ // Now, draw the bars
+ top = bar_top;
+ bottom = bar_top - bar_height;
+
+ // draw background bar.
+ left = 0;
+ right = width;
+ gl_rect_2d(left, top, right, bottom, LLColor4(0.f, 0.f, 0.f, 0.25f));
+
+ if (mStatp->getNumValues() == 0)
+ {
+ // No data, don't draw anything...
+ return;
+ }
+ // draw min and max
+ left = (S32) ((min - mMinBar) * value_scale);
+
+ if (left < 0)
+ {
+ left = 0;
+ llwarns << "Min:" << min << llendl;
+ }
+
+ right = (S32) ((max - mMinBar) * value_scale);
+ gl_rect_2d(left, top, right, bottom, LLColor4(1.f, 0.f, 0.f, 0.25f));
+
+ S32 num_values = mStatp->getNumValues() - 1;
+ if (mDisplayHistory)
+ {
+ S32 i;
+ for (i = 0; i < num_values; i++)
+ {
+ if (i == mStatp->getNextBin())
+ {
+ continue;
+ }
+ if (mPerSec)
+ {
+ left = (S32)((mStatp->getPrevPerSec(i) - mMinBar) * value_scale);
+ right = (S32)((mStatp->getPrevPerSec(i) - mMinBar) * value_scale) + 1;
+ gl_rect_2d(left, bottom+i+1, right, bottom+i, LLColor4(1.f, 0.f, 0.f, 1.f));
+ }
+ else
+ {
+ left = (S32)((mStatp->getPrev(i) - mMinBar) * value_scale);
+ right = (S32)((mStatp->getPrev(i) - mMinBar) * value_scale) + 1;
+ gl_rect_2d(left, bottom+i+1, right, bottom+i, LLColor4(1.f, 0.f, 0.f, 1.f));
+ }
+ }
+ }
+ else
+ {
+ // draw current
+ left = (S32) ((current - mMinBar) * value_scale) - 1;
+ right = (S32) ((current - mMinBar) * value_scale) + 1;
+ gl_rect_2d(left, top, right, bottom, LLColor4(1.f, 0.f, 0.f, 1.f));
+ }
+
+ // draw mean bar
+ top = bar_top + 2;
+ bottom = bar_top - bar_height - 2;
+ left = (S32) ((mean - mMinBar) * value_scale) - 1;
+ right = (S32) ((mean - mMinBar) * value_scale) + 1;
+ gl_rect_2d(left, top, right, bottom, LLColor4(0.f, 1.f, 0.f, 1.f));
+ }
+
+ LLView::draw();
+}
+
+void LLStatBar::setRange(F32 bar_min, F32 bar_max, F32 tick_spacing, F32 label_spacing)
+{
+ mMinBar = bar_min;
+ mMaxBar = bar_max;
+ mTickSpacing = tick_spacing;
+ mLabelSpacing = label_spacing;
+}
+
+LLRect LLStatBar::getRequiredRect()
+{
+ LLRect rect;
+
+ if (mDisplayBar)
+ {
+ if (mDisplayHistory)
+ {
+ rect.mTop = 67;
+ }
+ else
+ {
+ rect.mTop = 40;
+ }
+ }
+ else
+ {
+ rect.mTop = 14;
+ }
+ return rect;
+}
diff --git a/indra/llui/llstatbar.h b/indra/llui/llstatbar.h
new file mode 100644
index 0000000000..7de782a24f
--- /dev/null
+++ b/indra/llui/llstatbar.h
@@ -0,0 +1,108 @@
+/**
+ * @file llstatbar.h
+ * @brief A little map of the world with network information
+ *
+ * $LicenseInfo:firstyear=2001&license=viewergpl$
+ *
+ * Copyright (c) 2001-2009, Linden Research, Inc.
+ *
+ * Second Life Viewer Source Code
+ * The source code in this file ("Source Code") is provided by Linden Lab
+ * to you under the terms of the GNU General Public License, version 2.0
+ * ("GPL"), unless you have obtained a separate licensing agreement
+ * ("Other License"), formally executed by you and Linden Lab. Terms of
+ * the GPL can be found in doc/GPL-license.txt in this distribution, or
+ * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
+ *
+ * There are special exceptions to the terms and conditions of the GPL as
+ * it is applied to this Source Code. View the full text of the exception
+ * in the file doc/FLOSS-exception.txt in this software distribution, or
+ * online at
+ * http://secondlifegrid.net/programs/open_source/licensing/flossexception
+ *
+ * By copying, modifying or distributing this software, you acknowledge
+ * that you have read and understood your obligations described above,
+ * and agree to abide by those obligations.
+ *
+ * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+ * COMPLETENESS OR PERFORMANCE.
+ * $/LicenseInfo$
+ */
+
+#ifndef LL_LLSTATBAR_H
+#define LL_LLSTATBAR_H
+
+#include "llview.h"
+#include "llframetimer.h"
+
+class LLStat;
+
+class LLStatBar : public LLView
+{
+public:
+ struct Params : public LLInitParam::Block<Params, LLView::Params>
+ {
+ Optional<std::string> label;
+ Optional<std::string> unit_label;
+ Optional<F32> bar_min;
+ Optional<F32> bar_max;
+ Optional<F32> tick_spacing;
+ Optional<F32> label_spacing;
+ Optional<U32> precision;
+ Optional<F32> update_rate;
+ Optional<bool> show_per_sec;
+ Optional<bool> show_bar;
+ Optional<bool> show_history;
+ Optional<bool> show_mean;
+ Optional<std::string> stat;
+ Params()
+ : label("label"),
+ unit_label("unit_label"),
+ bar_min("bar_min", 0.0f),
+ bar_max("bar_max", 50.0f),
+ tick_spacing("tick_spacing", 10.0f),
+ label_spacing("label_spacing", 10.0f),
+ precision("precision", 0),
+ update_rate("update_rate", 5.0f),
+ show_per_sec("show_per_sec", TRUE),
+ show_bar("show_bar", TRUE),
+ show_history("show_history", FALSE),
+ show_mean("show_mean", TRUE),
+ stat("stat")
+ {
+ follows.flags(FOLLOWS_TOP | FOLLOWS_LEFT);
+ }
+ };
+ LLStatBar(const Params&);
+
+ virtual void draw();
+ virtual BOOL handleMouseDown(S32 x, S32 y, MASK mask);
+
+ void setStat(LLStat* stat) { mStatp = stat; }
+ void setRange(F32 bar_min, F32 bar_max, F32 tick_spacing, F32 label_spacing);
+ void getRange(F32& bar_min, F32& bar_max) { bar_min = mMinBar; bar_max = mMaxBar; }
+
+ /*virtual*/ LLRect getRequiredRect(); // Return the height of this object, given the set options.
+
+private:
+ F32 mMinBar;
+ F32 mMaxBar;
+ F32 mTickSpacing;
+ F32 mLabelSpacing;
+ U32 mPrecision;
+ F32 mUpdatesPerSec;
+ BOOL mPerSec; // Use the per sec stats.
+ BOOL mDisplayBar; // Display the bar graph.
+ BOOL mDisplayHistory;
+ BOOL mDisplayMean; // If true, display mean, if false, display current value
+
+ LLStat* mStatp;
+
+ LLFrameTimer mUpdateTimer;
+ LLUIString mLabel;
+ std::string mUnitLabel;
+ F32 mValue;
+};
+
+#endif
diff --git a/indra/llui/llstatgraph.cpp b/indra/llui/llstatgraph.cpp
new file mode 100644
index 0000000000..55d6b3159f
--- /dev/null
+++ b/indra/llui/llstatgraph.cpp
@@ -0,0 +1,163 @@
+/**
+ * @file llstatgraph.cpp
+ * @brief Simpler compact stat graph with tooltip
+ *
+ * $LicenseInfo:firstyear=2002&license=viewergpl$
+ *
+ * Copyright (c) 2002-2009, Linden Research, Inc.
+ *
+ * Second Life Viewer Source Code
+ * The source code in this file ("Source Code") is provided by Linden Lab
+ * to you under the terms of the GNU General Public License, version 2.0
+ * ("GPL"), unless you have obtained a separate licensing agreement
+ * ("Other License"), formally executed by you and Linden Lab. Terms of
+ * the GPL can be found in doc/GPL-license.txt in this distribution, or
+ * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
+ *
+ * There are special exceptions to the terms and conditions of the GPL as
+ * it is applied to this Source Code. View the full text of the exception
+ * in the file doc/FLOSS-exception.txt in this software distribution, or
+ * online at
+ * http://secondlifegrid.net/programs/open_source/licensing/flossexception
+ *
+ * By copying, modifying or distributing this software, you acknowledge
+ * that you have read and understood your obligations described above,
+ * and agree to abide by those obligations.
+ *
+ * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+ * COMPLETENESS OR PERFORMANCE.
+ * $/LicenseInfo$
+ */
+
+//#include "llviewerprecompiledheaders.h"
+#include "linden_common.h"
+
+#include "llstatgraph.h"
+#include "llrender.h"
+
+#include "llmath.h"
+#include "llui.h"
+#include "llstat.h"
+#include "llgl.h"
+#include "llglheaders.h"
+//#include "llviewercontrol.h"
+
+///////////////////////////////////////////////////////////////////////////////////
+
+LLStatGraph::LLStatGraph(const LLView::Params& p)
+: LLView(p)
+{
+ mStatp = NULL;
+ setToolTip(p.name());
+ mNumThresholds = 3;
+ mThresholdColors[0] = LLColor4(0.f, 1.f, 0.f, 1.f);
+ mThresholdColors[1] = LLColor4(1.f, 1.f, 0.f, 1.f);
+ mThresholdColors[2] = LLColor4(1.f, 0.f, 0.f, 1.f);
+ mThresholdColors[3] = LLColor4(1.f, 0.f, 0.f, 1.f);
+ mThresholds[0] = 50.f;
+ mThresholds[1] = 75.f;
+ mThresholds[2] = 100.f;
+ mMin = 0.f;
+ mMax = 125.f;
+ mPerSec = TRUE;
+ mValue = 0.f;
+ mPrecision = 0;
+}
+
+void LLStatGraph::draw()
+{
+ F32 range, frac;
+ range = mMax - mMin;
+ if (mStatp)
+ {
+ if (mPerSec)
+ {
+ mValue = mStatp->getMeanPerSec();
+ }
+ else
+ {
+ mValue = mStatp->getMean();
+ }
+ }
+ frac = (mValue - mMin) / range;
+ frac = llmax(0.f, frac);
+ frac = llmin(1.f, frac);
+
+ if (mUpdateTimer.getElapsedTimeF32() > 0.5f)
+ {
+ std::string format_str;
+ std::string tmp_str;
+ format_str = llformat("%%s%%.%df%%s", mPrecision);
+ tmp_str = llformat(format_str.c_str(), mLabel.c_str(), mValue, mUnits.c_str());
+ setToolTip(tmp_str);
+
+ mUpdateTimer.reset();
+ }
+
+ LLColor4 color;
+
+ S32 i;
+ for (i = 0; i < mNumThresholds - 1; i++)
+ {
+ if (mThresholds[i] > mValue)
+ {
+ break;
+ }
+ }
+
+ //gl_drop_shadow(0, getRect().getHeight(), getRect().getWidth(), 0,
+ // LLUIColorTable::instance().getColor("ColorDropShadow"),
+ // (S32) gSavedSettings.getF32("DropShadowFloater") );
+
+ color = LLUIColorTable::instance().getColor( "MenuDefaultBgColor" );
+ gGL.color4fv(color.mV);
+ gl_rect_2d(0, getRect().getHeight(), getRect().getWidth(), 0, TRUE);
+
+ gGL.color4fv(LLColor4::black.mV);
+ gl_rect_2d(0, getRect().getHeight(), getRect().getWidth(), 0, FALSE);
+
+ color = mThresholdColors[i];
+ gGL.color4fv(color.mV);
+ gl_rect_2d(1, llround(frac*getRect().getHeight()), getRect().getWidth() - 1, 0, TRUE);
+}
+
+void LLStatGraph::setValue(const LLSD& value)
+{
+ mValue = (F32)value.asReal();
+}
+
+void LLStatGraph::setMin(const F32 min)
+{
+ mMin = min;
+}
+
+void LLStatGraph::setMax(const F32 max)
+{
+ mMax = max;
+}
+
+void LLStatGraph::setStat(LLStat *statp)
+{
+ mStatp = statp;
+}
+
+void LLStatGraph::setLabel(const std::string& label)
+{
+ mLabel = label;
+}
+
+void LLStatGraph::setUnits(const std::string& units)
+{
+ mUnits = units;
+}
+
+void LLStatGraph::setPrecision(const S32 precision)
+{
+ mPrecision = precision;
+}
+
+void LLStatGraph::setThreshold(const S32 i, F32 value)
+{
+ mThresholds[i] = value;
+}
diff --git a/indra/llui/llstatgraph.h b/indra/llui/llstatgraph.h
new file mode 100644
index 0000000000..dd38050b1b
--- /dev/null
+++ b/indra/llui/llstatgraph.h
@@ -0,0 +1,76 @@
+/**
+ * @file llstatgraph.h
+ * @brief Simpler compact stat graph with tooltip
+ *
+ * $LicenseInfo:firstyear=2002&license=viewergpl$
+ *
+ * Copyright (c) 2002-2009, Linden Research, Inc.
+ *
+ * Second Life Viewer Source Code
+ * The source code in this file ("Source Code") is provided by Linden Lab
+ * to you under the terms of the GNU General Public License, version 2.0
+ * ("GPL"), unless you have obtained a separate licensing agreement
+ * ("Other License"), formally executed by you and Linden Lab. Terms of
+ * the GPL can be found in doc/GPL-license.txt in this distribution, or
+ * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
+ *
+ * There are special exceptions to the terms and conditions of the GPL as
+ * it is applied to this Source Code. View the full text of the exception
+ * in the file doc/FLOSS-exception.txt in this software distribution, or
+ * online at
+ * http://secondlifegrid.net/programs/open_source/licensing/flossexception
+ *
+ * By copying, modifying or distributing this software, you acknowledge
+ * that you have read and understood your obligations described above,
+ * and agree to abide by those obligations.
+ *
+ * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+ * COMPLETENESS OR PERFORMANCE.
+ * $/LicenseInfo$
+ */
+
+#ifndef LL_LLSTATGRAPH_H
+#define LL_LLSTATGRAPH_H
+
+#include "llview.h"
+#include "llframetimer.h"
+#include "v4color.h"
+
+class LLStat;
+
+class LLStatGraph : public LLView
+{
+public:
+ LLStatGraph(const LLView::Params&);
+
+ virtual void draw();
+
+ void setLabel(const std::string& label);
+ void setUnits(const std::string& units);
+ void setPrecision(const S32 precision);
+ void setStat(LLStat *statp);
+ void setThreshold(const S32 i, F32 value);
+ void setMin(const F32 min);
+ void setMax(const F32 max);
+
+ /*virtual*/ void setValue(const LLSD& value);
+
+ LLStat *mStatp;
+ BOOL mPerSec;
+private:
+ F32 mValue;
+
+ F32 mMin;
+ F32 mMax;
+ LLFrameTimer mUpdateTimer;
+ std::string mLabel;
+ std::string mUnits;
+ S32 mPrecision; // Num of digits of precision after dot
+
+ S32 mNumThresholds;
+ F32 mThresholds[4];
+ LLColor4 mThresholdColors[4];
+};
+
+#endif // LL_LLSTATGRAPH_H
diff --git a/indra/llui/llstatview.cpp b/indra/llui/llstatview.cpp
new file mode 100644
index 0000000000..4ba01eb441
--- /dev/null
+++ b/indra/llui/llstatview.cpp
@@ -0,0 +1,71 @@
+/**
+ * @file llstatview.cpp
+ * @brief Container for all statistics info.
+ *
+ * $LicenseInfo:firstyear=2001&license=viewergpl$
+ *
+ * Copyright (c) 2001-2009, Linden Research, Inc.
+ *
+ * Second Life Viewer Source Code
+ * The source code in this file ("Source Code") is provided by Linden Lab
+ * to you under the terms of the GNU General Public License, version 2.0
+ * ("GPL"), unless you have obtained a separate licensing agreement
+ * ("Other License"), formally executed by you and Linden Lab. Terms of
+ * the GPL can be found in doc/GPL-license.txt in this distribution, or
+ * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
+ *
+ * There are special exceptions to the terms and conditions of the GPL as
+ * it is applied to this Source Code. View the full text of the exception
+ * in the file doc/FLOSS-exception.txt in this software distribution, or
+ * online at
+ * http://secondlifegrid.net/programs/open_source/licensing/flossexception
+ *
+ * By copying, modifying or distributing this software, you acknowledge
+ * that you have read and understood your obligations described above,
+ * and agree to abide by those obligations.
+ *
+ * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+ * COMPLETENESS OR PERFORMANCE.
+ * $/LicenseInfo$
+ */
+
+#include "linden_common.h"
+
+#include "llstatview.h"
+
+#include "llerror.h"
+#include "llstatbar.h"
+#include "llfontgl.h"
+#include "llgl.h"
+#include "llui.h"
+
+#include "llstatbar.h"
+
+LLStatView::LLStatView(const LLStatView::Params& p)
+: LLContainerView(p),
+ mSetting(p.setting)
+{
+ BOOL isopen = getDisplayChildren();
+ if (mSetting.length() > 0)
+ {
+ isopen = LLUI::sSettingGroups["config"]->getBOOL(mSetting);
+ }
+ setDisplayChildren(isopen);
+}
+
+LLStatView::~LLStatView()
+{
+ // Children all cleaned up by default view destructor.
+ if (mSetting.length() > 0)
+ {
+ BOOL isopen = getDisplayChildren();
+ LLUI::sSettingGroups["config"]->setBOOL(mSetting, isopen);
+ }
+}
+
+
+static StatViewRegistry::Register<LLStatBar> r1("stat_bar");
+static StatViewRegistry::Register<LLStatView> r2("stat_view");
+
+
diff --git a/indra/llui/llstatview.h b/indra/llui/llstatview.h
new file mode 100644
index 0000000000..eee4e2b7e4
--- /dev/null
+++ b/indra/llui/llstatview.h
@@ -0,0 +1,72 @@
+/**
+ * @file llstatview.h
+ * @brief Container for all statistics info.
+ *
+ * $LicenseInfo:firstyear=2001&license=viewergpl$
+ *
+ * Copyright (c) 2001-2009, Linden Research, Inc.
+ *
+ * Second Life Viewer Source Code
+ * The source code in this file ("Source Code") is provided by Linden Lab
+ * to you under the terms of the GNU General Public License, version 2.0
+ * ("GPL"), unless you have obtained a separate licensing agreement
+ * ("Other License"), formally executed by you and Linden Lab. Terms of
+ * the GPL can be found in doc/GPL-license.txt in this distribution, or
+ * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
+ *
+ * There are special exceptions to the terms and conditions of the GPL as
+ * it is applied to this Source Code. View the full text of the exception
+ * in the file doc/FLOSS-exception.txt in this software distribution, or
+ * online at
+ * http://secondlifegrid.net/programs/open_source/licensing/flossexception
+ *
+ * By copying, modifying or distributing this software, you acknowledge
+ * that you have read and understood your obligations described above,
+ * and agree to abide by those obligations.
+ *
+ * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+ * COMPLETENESS OR PERFORMANCE.
+ * $/LicenseInfo$
+ */
+
+#ifndef LL_LLSTATVIEW_H
+#define LL_LLSTATVIEW_H
+
+#include "llstatbar.h"
+#include "llcontainerview.h"
+#include <vector>
+
+class LLStatBar;
+
+// widget registrars
+struct StatViewRegistry : public LLChildRegistry<StatViewRegistry>
+{};
+
+class LLStatView : public LLContainerView
+{
+public:
+ struct Params : public LLInitParam::Block<Params, LLContainerView::Params>
+ {
+ Optional<std::string> setting;
+ Params()
+ : setting("setting")
+ {
+ follows.flags(FOLLOWS_TOP | FOLLOWS_LEFT);
+ }
+ };
+
+ // my valid children are stored in this registry
+ typedef StatViewRegistry child_registry_t;
+
+ ~LLStatView();
+
+protected:
+ LLStatView(const Params&);
+ friend class LLUICtrlFactory;
+
+protected:
+ std::string mSetting;
+
+};
+#endif // LL_STATVIEW_
diff --git a/indra/llui/llstyle.cpp b/indra/llui/llstyle.cpp
index a716cbbaec..929a809d88 100644
--- a/indra/llui/llstyle.cpp
+++ b/indra/llui/llstyle.cpp
@@ -33,112 +33,43 @@
#include "linden_common.h"
#include "llstyle.h"
+
+#include "llfontgl.h"
#include "llstring.h"
#include "llui.h"
-//#include "llviewerimagelist.h"
-
-LLStyle::LLStyle()
+LLStyle::Params::Params()
+: visible("visible", true),
+ drop_shadow("drop_shadow", false),
+ color("color", LLColor4::black),
+ font("font", LLFontGL::getFontMonospace()),
+ image("image"),
+ link_href("href")
+{}
+
+
+LLStyle::LLStyle(const LLStyle::Params& p)
+: mVisible(p.visible),
+ mColor(p.color()),
+ mFont(p.font()),
+ mLink(p.link_href),
+ mDropShadow(p.drop_shadow),
+ mImageHeight(0),
+ mImageWidth(0),
+ mImagep(p.image())
+{}
+
+void LLStyle::setFont(const LLFontGL* font)
{
- init(TRUE, LLColor4(0,0,0,1),LLStringUtil::null);
+ mFont = font;
}
-LLStyle::LLStyle(const LLStyle &style)
-{
- if (this != &style)
- {
- init(style.isVisible(),style.getColor(),style.getFontString());
- if (style.isLink())
- {
- setLinkHREF(style.getLinkHREF());
- }
- mItalic = style.mItalic;
- mBold = style.mBold;
- mUnderline = style.mUnderline;
- mDropShadow = style.mDropShadow;
- mImageHeight = style.mImageHeight;
- mImageWidth = style.mImageWidth;
- mImagep = style.mImagep;
- mIsEmbeddedItem = style.mIsEmbeddedItem;
- }
- else
- {
- init(TRUE, LLColor4(0,0,0,1),LLStringUtil::null);
- }
-}
-LLStyle::LLStyle(BOOL is_visible, const LLColor4 &color, const std::string& font_name)
+const LLFontGL* LLStyle::getFont() const
{
- init(is_visible, color, font_name);
+ return mFont;
}
-void LLStyle::init(BOOL is_visible, const LLColor4 &color, const std::string& font_name)
-{
- mVisible = is_visible;
- mColor = color;
- setFontName(font_name);
- setLinkHREF(LLStringUtil::null);
- mItalic = FALSE;
- mBold = FALSE;
- mUnderline = FALSE;
- mDropShadow = FALSE;
- mImageHeight = 0;
- mImageWidth = 0;
- mIsEmbeddedItem = FALSE;
-}
-
-
-// Copy assignment
-LLStyle &LLStyle::operator=(const LLStyle &rhs)
-{
- if (this != &rhs)
- {
- setVisible(rhs.isVisible());
- setColor(rhs.getColor());
- this->mFontName = rhs.getFontString();
- this->mLink = rhs.getLinkHREF();
- mImagep = rhs.mImagep;
- mImageHeight = rhs.mImageHeight;
- mImageWidth = rhs.mImageWidth;
- mItalic = rhs.mItalic;
- mBold = rhs.mBold;
- mUnderline = rhs.mUnderline;
- mDropShadow = rhs.mDropShadow;
- mIsEmbeddedItem = rhs.mIsEmbeddedItem;
- }
-
- return *this;
-}
-
-
-void LLStyle::setFontName(const std::string& fontname)
-{
- mFontName = fontname;
-
- std::string fontname_lc = fontname;
- LLStringUtil::toLower(fontname_lc);
-
- mFontID = LLFONT_OCRA; // default
-
- if ((fontname_lc == "sansserif") || (fontname_lc == "sans-serif"))
- {
- mFontID = LLFONT_SANSSERIF;
- }
- else if ((fontname_lc == "serif"))
- {
- mFontID = LLFONT_SMALL;
- }
- else if ((fontname_lc == "sansserifbig"))
- {
- mFontID = LLFONT_SANSSERIF_BIG;
- }
- else if (fontname_lc == "small")
- {
- mFontID = LLFONT_SANSSERIF_SMALL;
- }
-}
-
-
void LLStyle::setLinkHREF(const std::string& href)
{
mLink = href;
@@ -166,7 +97,7 @@ LLUIImagePtr LLStyle::getImage() const
void LLStyle::setImage(const LLUUID& src)
{
- mImagep = LLUI::sImageProvider->getUIImageByID(src);
+ mImagep = LLUI::getUIImageByID(src);
}
diff --git a/indra/llui/llstyle.h b/indra/llui/llstyle.h
index 3ad379cdd9..dcf274a651 100644
--- a/indra/llui/llstyle.h
+++ b/indra/llui/llstyle.h
@@ -34,60 +34,60 @@
#define LL_LLSTYLE_H
#include "v4color.h"
-#include "llresmgr.h"
-#include "llfont.h"
#include "llui.h"
+#include "llinitparam.h"
+
+class LLFontGL;
class LLStyle : public LLRefCount
{
public:
- LLStyle();
- LLStyle(const LLStyle &style);
- LLStyle(BOOL is_visible, const LLColor4 &color, const std::string& font_name);
-
- LLStyle &operator=(const LLStyle &rhs);
-
- virtual void init (BOOL is_visible, const LLColor4 &color, const std::string& font_name);
-
- virtual const LLColor4& getColor() const { return mColor; }
- virtual void setColor(const LLColor4 &color) { mColor = color; }
-
- virtual BOOL isVisible() const;
- virtual void setVisible(BOOL is_visible);
+ struct Params : public LLInitParam::Block<Params>
+ {
+ Optional<bool> visible,
+ drop_shadow;
+ Optional<LLUIColor> color;
+ Optional<const LLFontGL*> font;
+ Optional<LLUIImage*> image;
+ Optional<std::string> link_href;
+ Params();
+ };
+ LLStyle(const Params& p = Params());
+public:
+ const LLColor4& getColor() const { return mColor; }
+ void setColor(const LLColor4 &color) { mColor = color; }
- virtual const std::string& getFontString() const { return mFontName; }
- virtual void setFontName(const std::string& fontname);
- virtual LLFONT_ID getFontID() const { return mFontID; }
+ BOOL isVisible() const;
+ void setVisible(BOOL is_visible);
- virtual const std::string& getLinkHREF() const { return mLink; }
- virtual void setLinkHREF(const std::string& href);
- virtual BOOL isLink() const;
+ void setFont(const LLFontGL* font);
+ const LLFontGL* getFont() const;
- virtual LLUIImagePtr getImage() const;
- virtual void setImage(const LLUUID& src);
+ const std::string& getLinkHREF() const { return mLink; }
+ void setLinkHREF(const std::string& href);
+ BOOL isLink() const;
- virtual BOOL isImage() const { return ((mImageWidth != 0) && (mImageHeight != 0)); }
- virtual void setImageSize(S32 width, S32 height);
+ LLUIImagePtr getImage() const;
+ void setImage(const LLUUID& src);
- BOOL getIsEmbeddedItem() const { return mIsEmbeddedItem; }
- void setIsEmbeddedItem( BOOL b ) { mIsEmbeddedItem = b; }
+ BOOL isImage() const { return ((mImageWidth != 0) && (mImageHeight != 0)); }
+ void setImageSize(S32 width, S32 height);
// inlined here to make it easier to compare to member data below. -MG
bool operator==(const LLStyle &rhs) const
{
return
- mVisible == rhs.isVisible()
- && mColor == rhs.getColor()
- && mFontName == rhs.getFontString()
- && mLink == rhs.getLinkHREF()
+ mVisible == rhs.mVisible
+ && mColor == rhs.mColor
+ && mFont == rhs.mFont
+ && mLink == rhs.mLink
&& mImagep == rhs.mImagep
&& mImageHeight == rhs.mImageHeight
&& mImageWidth == rhs.mImageWidth
&& mItalic == rhs.mItalic
&& mBold == rhs.mBold
&& mUnderline == rhs.mUnderline
- && mDropShadow == rhs.mDropShadow
- && mIsEmbeddedItem == rhs.mIsEmbeddedItem;
+ && mDropShadow == rhs.mDropShadow;
}
bool operator!=(const LLStyle& rhs) const { return !(*this == rhs); }
@@ -101,16 +101,15 @@ public:
S32 mImageHeight;
protected:
- virtual ~LLStyle() { }
+ ~LLStyle() { }
private:
BOOL mVisible;
- LLColor4 mColor;
+ LLUIColor mColor;
std::string mFontName;
- LLFONT_ID mFontID;
+ const LLFontGL* mFont; // cached for performance
std::string mLink;
LLUIImagePtr mImagep;
- BOOL mIsEmbeddedItem;
};
typedef LLPointer<LLStyle> LLStyleSP;
diff --git a/indra/llui/lltabcontainer.cpp b/indra/llui/lltabcontainer.cpp
index f4169488d4..e379954b4f 100644
--- a/indra/llui/lltabcontainer.cpp
+++ b/indra/llui/lltabcontainer.cpp
@@ -35,73 +35,140 @@
#include "llfocusmgr.h"
#include "llbutton.h"
#include "llrect.h"
-#include "llresmgr.h"
#include "llresizehandle.h"
#include "lltextbox.h"
#include "llcriticaldamp.h"
#include "lluictrlfactory.h"
-#include "lltabcontainervertical.h"
#include "llrender.h"
+#include "llfloater.h"
+
+//----------------------------------------------------------------------------
+
+// Implementation Notes:
+// - Each tab points to a LLPanel (see LLTabTuple below)
+// - When a tab is selected, the validation callback
+// (LLUICtrl::mValidateSignal) is called
+// - If the validation callback returns true (or none is provided),
+// the tab is changed and the commit callback
+// (LLUICtrl::mCommitSignal) is called
+// - Callbacks pass the LLTabContainer as the control,
+// and the NAME of the selected PANEL as the LLSD data
+
+//----------------------------------------------------------------------------
const F32 SCROLL_STEP_TIME = 0.4f;
const F32 SCROLL_DELAY_TIME = 0.5f;
-const S32 TAB_PADDING = 15;
-const S32 TABCNTR_TAB_MIN_WIDTH = 60;
-const S32 TABCNTR_VERT_TAB_MIN_WIDTH = 100;
-const S32 TABCNTR_TAB_MAX_WIDTH = 150;
-const S32 TABCNTR_TAB_PARTIAL_WIDTH = 12; // When tabs are parially obscured, how much can you still see.
-const S32 TABCNTR_TAB_HEIGHT = 16;
-const S32 TABCNTR_ARROW_BTN_SIZE = 16;
-const S32 TABCNTR_BUTTON_PANEL_OVERLAP = 1; // how many pixels the tab buttons and tab panels overlap.
-const S32 TABCNTR_TAB_H_PAD = 4;
-
-const S32 TABCNTR_CLOSE_BTN_SIZE = 16;
-const S32 TABCNTR_HEADER_HEIGHT = LLPANEL_BORDER_WIDTH + TABCNTR_CLOSE_BTN_SIZE;
-
-const S32 TABCNTRV_CLOSE_BTN_SIZE = 16;
-const S32 TABCNTRV_HEADER_HEIGHT = LLPANEL_BORDER_WIDTH + TABCNTRV_CLOSE_BTN_SIZE;
-//const S32 TABCNTRV_TAB_WIDTH = 100;
-const S32 TABCNTRV_ARROW_BTN_SIZE = 16;
-const S32 TABCNTRV_PAD = 0;
-
-static LLRegisterWidget<LLTabContainer> r("tab_container");
-
-LLTabContainer::LLTabContainer(const std::string& name, const LLRect& rect, TabPosition pos,
- BOOL bordered, BOOL is_vertical )
- :
- LLPanel(name, rect, bordered),
+
+void LLTabContainer::TabPositions::declareValues()
+{
+ declare("top", LLTabContainer::TOP);
+ declare("bottom", LLTabContainer::BOTTOM);
+ declare("left", LLTabContainer::LEFT);
+}
+
+//----------------------------------------------------------------------------
+
+// Structure used to map tab buttons to and from tab panels
+class LLTabTuple
+{
+public:
+ LLTabTuple( LLTabContainer* c, LLPanel* p, LLButton* b, LLTextBox* placeholder = NULL)
+ :
+ mTabContainer(c),
+ mTabPanel(p),
+ mButton(b),
+ mOldState(FALSE),
+ mPlaceholderText(placeholder),
+ mPadding(0)
+ {}
+
+ LLTabContainer* mTabContainer;
+ LLPanel* mTabPanel;
+ LLButton* mButton;
+ BOOL mOldState;
+ LLTextBox* mPlaceholderText;
+ S32 mPadding;
+};
+
+//----------------------------------------------------------------------------
+
+struct LLPlaceHolderPanel : public LLPanel
+{
+ // create dummy param block to register with "placeholder" nane
+ struct Params : public LLPanel::Params{};
+ LLPlaceHolderPanel(const Params& p) : LLPanel(p)
+ {}
+};
+static LLDefaultChildRegistry::Register<LLPlaceHolderPanel> r1("placeholder");
+static LLDefaultChildRegistry::Register<LLTabContainer> r2("tab_container");
+
+LLTabContainer::Params::Params()
+: tab_width("tab_width"),
+ tab_position("tab_position"),
+ tab_min_width("tab_min_width"),
+ tab_max_width("tab_max_width"),
+ hide_tabs("hide_tabs", false),
+ tab_padding_right("tab_padding_right"),
+ tab_top_image_unselected("tab_top_image_unselected"),
+ tab_top_image_selected("tab_top_image_selected"),
+ tab_bottom_image_unselected("tab_bottom_image_unselected"),
+ tab_bottom_image_selected("tab_bottom_image_selected"),
+ tab_left_image_unselected("tab_left_image_unselected"),
+ tab_left_image_selected("tab_left_image_selected")
+{
+ name(std::string("tab_container"));
+ mouse_opaque = false;
+}
+
+LLTabContainer::LLTabContainer(const LLTabContainer::Params& p)
+: LLPanel(p),
mCurrentTabIdx(-1),
- mNextTabIdx(-1),
- mTabsHidden(FALSE),
+ mTabsHidden(p.hide_tabs),
mScrolled(FALSE),
mScrollPos(0),
mScrollPosPixels(0),
mMaxScrollPos(0),
- mCloseCallback( NULL ),
- mCallbackUserdata( NULL ),
mTitleBox(NULL),
mTopBorderHeight(LLPANEL_BORDER_WIDTH),
- mTabPosition(pos),
mLockedTabCount(0),
- mMinTabWidth(TABCNTR_TAB_MIN_WIDTH),
- mMaxTabWidth(TABCNTR_TAB_MAX_WIDTH),
+ mMinTabWidth(0),
+ mMaxTabWidth(p.tab_max_width),
mPrevArrowBtn(NULL),
mNextArrowBtn(NULL),
- mIsVertical(is_vertical),
+ mIsVertical( p.tab_position == LEFT ),
// Horizontal Specific
mJumpPrevArrowBtn(NULL),
mJumpNextArrowBtn(NULL),
- mRightTabBtnOffset(0),
- mTotalTabWidth(0)
-{
- //RN: HACK to support default min width for legacy vertical tab containers
- if (mIsVertical)
+ mRightTabBtnOffset(p.tab_padding_right),
+ mTotalTabWidth(0),
+ mTabPosition(p.tab_position),
+ mImageTopUnselected(p.tab_top_image_unselected),
+ mImageTopSelected(p.tab_top_image_selected),
+ mImageBottomUnselected(p.tab_bottom_image_unselected),
+ mImageBottomSelected(p.tab_bottom_image_selected),
+ mImageLeftUnselected(p.tab_left_image_unselected),
+ mImageLeftSelected(p.tab_left_image_selected)
+{
+ static LLUICachedControl<S32> tabcntr_vert_tab_min_width ("UITabCntrVertTabMinWidth", 0);
+
+ mDragAndDropDelayTimer.stop();
+
+ if (p.tab_width.isProvided())
+ {
+ mMinTabWidth = p.tab_width;
+ }
+ else if (!mIsVertical)
{
- mMinTabWidth = TABCNTR_VERT_TAB_MIN_WIDTH;
+ mMinTabWidth = p.tab_min_width;
}
- setMouseOpaque(FALSE);
+ else
+ {
+ // *HACK: support default min width for legacy vertical
+ // tab containers
+ mMinTabWidth = tabcntr_vert_tab_min_width;
+ }
+
initButtons( );
- mDragAndDropDelayTimer.stop();
}
LLTabContainer::~LLTabContainer()
@@ -123,7 +190,7 @@ void LLTabContainer::reshape(S32 width, S32 height, BOOL called_from_parent)
}
//virtual
-LLView* LLTabContainer::getChildView(const std::string& name, BOOL recurse, BOOL create_if_missing) const
+LLView* LLTabContainer::getChildView(const std::string& name, BOOL recurse) const
{
tuple_list_t::const_iterator itor;
for (itor = mTabList.begin(); itor != mTabList.end(); ++itor)
@@ -140,26 +207,83 @@ LLView* LLTabContainer::getChildView(const std::string& name, BOOL recurse, BOOL
for (itor = mTabList.begin(); itor != mTabList.end(); ++itor)
{
LLPanel *panel = (*itor)->mTabPanel;
- LLView *child = panel->getChildView(name, recurse, FALSE);
+ LLView *child = panel->getChildView(name, recurse);
if (child)
{
return child;
}
}
}
- return LLView::getChildView(name, recurse, create_if_missing);
+ return LLView::getChildView(name, recurse);
+}
+
+//virtual
+LLView* LLTabContainer::findChildView(const std::string& name, BOOL recurse) const
+{
+ tuple_list_t::const_iterator itor;
+ for (itor = mTabList.begin(); itor != mTabList.end(); ++itor)
+ {
+ LLPanel *panel = (*itor)->mTabPanel;
+ if (panel->getName() == name)
+ {
+ return panel;
+ }
+ }
+
+ if (recurse)
+ {
+ for (itor = mTabList.begin(); itor != mTabList.end(); ++itor)
+ {
+ LLPanel *panel = (*itor)->mTabPanel;
+ LLView *child = panel->findChildView(name, recurse);
+ if (child)
+ {
+ return child;
+ }
+ }
+ }
+ return LLView::findChildView(name, recurse);
+}
+
+bool LLTabContainer::addChild(LLView* view, S32 tab_group)
+{
+ LLPanel* panelp = dynamic_cast<LLPanel*>(view);
+
+ if (panelp)
+ {
+ panelp->setSaveToXML(TRUE);
+
+ addTabPanel(TabPanelParams().panel(panelp).label(panelp->getLabel()).is_placeholder(dynamic_cast<LLPlaceHolderPanel*>(view) != NULL));
+ return true;
+ }
+ else
+ {
+ return LLUICtrl::addChild(view, tab_group);
+ }
+}
+
+BOOL LLTabContainer::postBuild()
+{
+ selectFirstTab();
+
+ return TRUE;
}
// virtual
void LLTabContainer::draw()
{
+ static LLUICachedControl<S32> tabcntrv_pad ("UITabCntrvPad", 0);
+ static LLUICachedControl<S32> tabcntrv_arrow_btn_size ("UITabCntrvArrowBtnSize", 0);
+ static LLUICachedControl<S32> tabcntr_tab_h_pad ("UITabCntrTabHPad", 0);
+ static LLUICachedControl<S32> tabcntr_arrow_btn_size ("UITabCntrArrowBtnSize", 0);
+ static LLUICachedControl<S32> tabcntr_tab_partial_width ("UITabCntrTabPartialWidth", 0);
S32 target_pixel_scroll = 0;
S32 cur_scroll_pos = getScrollPos();
if (cur_scroll_pos > 0)
{
+ S32 available_width_with_arrows = getRect().getWidth() - mRightTabBtnOffset - 2 * (LLPANEL_BORDER_WIDTH + tabcntr_arrow_btn_size + tabcntr_arrow_btn_size + 1);
if (!mIsVertical)
{
- S32 available_width_with_arrows = getRect().getWidth() - mRightTabBtnOffset - 2 * (LLPANEL_BORDER_WIDTH + TABCNTR_ARROW_BTN_SIZE + TABCNTR_ARROW_BTN_SIZE + 1);
for(tuple_list_t::iterator iter = mTabList.begin(); iter != mTabList.end(); ++iter)
{
if (cur_scroll_pos == 0)
@@ -171,26 +295,10 @@ void LLTabContainer::draw()
}
// Show part of the tab to the left of what is fully visible
- target_pixel_scroll -= TABCNTR_TAB_PARTIAL_WIDTH;
+ target_pixel_scroll -= tabcntr_tab_partial_width;
// clamp so that rightmost tab never leaves right side of screen
target_pixel_scroll = llmin(mTotalTabWidth - available_width_with_arrows, target_pixel_scroll);
}
- else
- {
- S32 available_height_with_arrows = getRect().getHeight() - getTopBorderHeight() - (LLPANEL_BORDER_WIDTH + TABCNTR_ARROW_BTN_SIZE + TABCNTR_ARROW_BTN_SIZE + 1);
- for(tuple_list_t::iterator iter = mTabList.begin(); iter != mTabList.end(); ++iter)
- {
- if (cur_scroll_pos==0)
- {
- break;
- }
- target_pixel_scroll += (*iter)->mButton->getRect().getHeight();
- cur_scroll_pos--;
- }
- S32 total_tab_height = (BTN_HEIGHT + TABCNTRV_PAD) * getTabCount() + TABCNTRV_PAD;
- // clamp so that the bottom tab never leaves bottom of panel
- target_pixel_scroll = llmin(total_tab_height - available_height_with_arrows, target_pixel_scroll);
- }
}
setScrollPosPixels((S32)lerp((F32)getScrollPosPixels(), (F32)target_pixel_scroll, LLCriticalDamp::getInterpolant(0.08f)));
@@ -207,13 +315,13 @@ void LLTabContainer::draw()
S32 left = 0, top = 0;
if (mIsVertical)
{
- top = getRect().getHeight() - getTopBorderHeight() - LLPANEL_BORDER_WIDTH - 1 - (has_scroll_arrows ? TABCNTRV_ARROW_BTN_SIZE : 0);
+ top = getRect().getHeight() - getTopBorderHeight() - LLPANEL_BORDER_WIDTH - 1 - (has_scroll_arrows ? tabcntrv_arrow_btn_size : 0);
top += getScrollPosPixels();
}
else
{
// Set the leftmost position of the tab buttons.
- left = LLPANEL_BORDER_WIDTH + (has_scroll_arrows ? (TABCNTR_ARROW_BTN_SIZE * 2) : TABCNTR_TAB_H_PAD);
+ left = LLPANEL_BORDER_WIDTH + (has_scroll_arrows ? (tabcntr_arrow_btn_size * 2) : tabcntr_tab_h_pad);
left -= getScrollPosPixels();
}
@@ -243,8 +351,8 @@ void LLTabContainer::draw()
// ...but clip them.
if (mIsVertical)
{
- clip_rect.mBottom = mNextArrowBtn->getRect().mTop + 3*TABCNTRV_PAD;
- clip_rect.mTop = mPrevArrowBtn->getRect().mBottom - 3*TABCNTRV_PAD;
+ clip_rect.mBottom = mNextArrowBtn->getRect().mTop + 3*tabcntrv_pad;
+ clip_rect.mTop = mPrevArrowBtn->getRect().mBottom - 3*tabcntrv_pad;
}
else
{
@@ -262,7 +370,7 @@ void LLTabContainer::draw()
tuple->mButton->translate( left ? left - tuple->mButton->getRect().mLeft : 0,
top ? top - tuple->mButton->getRect().mTop : 0 );
- if (top) top -= BTN_HEIGHT + TABCNTRV_PAD;
+ if (top) top -= BTN_HEIGHT + tabcntrv_pad;
if (left) left += tuple->mButton->getRect().getWidth();
if (!mIsVertical)
@@ -316,6 +424,7 @@ void LLTabContainer::draw()
// virtual
BOOL LLTabContainer::handleMouseDown( S32 x, S32 y, MASK mask )
{
+ static LLUICachedControl<S32> tabcntrv_pad ("UITabCntrvPad", 0);
BOOL handled = FALSE;
BOOL has_scroll_arrows = (getMaxScrollPos() > 0);
@@ -359,9 +468,9 @@ BOOL LLTabContainer::handleMouseDown( S32 x, S32 y, MASK mask )
if (mIsVertical)
{
tab_rect = LLRect(firsttuple->mButton->getRect().mLeft,
- has_scroll_arrows ? mPrevArrowBtn->getRect().mBottom - TABCNTRV_PAD : mPrevArrowBtn->getRect().mTop,
+ has_scroll_arrows ? mPrevArrowBtn->getRect().mBottom - tabcntrv_pad : mPrevArrowBtn->getRect().mTop,
firsttuple->mButton->getRect().mRight,
- has_scroll_arrows ? mNextArrowBtn->getRect().mTop + TABCNTRV_PAD : mNextArrowBtn->getRect().mBottom );
+ has_scroll_arrows ? mNextArrowBtn->getRect().mTop + tabcntrv_pad : mNextArrowBtn->getRect().mBottom );
}
else
{
@@ -376,7 +485,7 @@ BOOL LLTabContainer::handleMouseDown( S32 x, S32 y, MASK mask )
index = llclamp(index, 0, tab_count-1);
LLButton* tab_button = getTab(index)->mButton;
gFocusMgr.setMouseCapture(this);
- gFocusMgr.setKeyboardFocus(tab_button);
+ tab_button->setFocus(TRUE);
}
}
return handled;
@@ -483,6 +592,7 @@ BOOL LLTabContainer::handleMouseUp( S32 x, S32 y, MASK mask )
// virtual
BOOL LLTabContainer::handleToolTip( S32 x, S32 y, std::string& msg, LLRect* sticky_rect )
{
+ static LLUICachedControl<S32> tabcntrv_pad ("UITabCntrvPad", 0);
BOOL handled = LLPanel::handleToolTip( x, y, msg, sticky_rect );
if (!handled && getTabCount() > 0)
{
@@ -493,9 +603,9 @@ BOOL LLTabContainer::handleToolTip( S32 x, S32 y, std::string& msg, LLRect* stic
if (mIsVertical)
{
clip = LLRect(firsttuple->mButton->getRect().mLeft,
- has_scroll_arrows ? mPrevArrowBtn->getRect().mBottom - TABCNTRV_PAD : mPrevArrowBtn->getRect().mTop,
+ has_scroll_arrows ? mPrevArrowBtn->getRect().mBottom - tabcntrv_pad : mPrevArrowBtn->getRect().mTop,
firsttuple->mButton->getRect().mRight,
- has_scroll_arrows ? mNextArrowBtn->getRect().mTop + TABCNTRV_PAD : mNextArrowBtn->getRect().mBottom );
+ has_scroll_arrows ? mNextArrowBtn->getRect().mTop + tabcntrv_pad : mNextArrowBtn->getRect().mBottom );
}
else
{
@@ -617,14 +727,6 @@ BOOL LLTabContainer::handleKeyHere(KEY key, MASK mask)
}
// virtual
-LLXMLNodePtr LLTabContainer::getXML(bool save_children) const
-{
- LLXMLNodePtr node = LLPanel::getXML();
- node->createChild("tab_position", TRUE)->setStringValue((getTabPosition() == TOP ? "top" : "bottom"));
- return node;
-}
-
-// virtual
BOOL LLTabContainer::handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop, EDragAndDropType type, void* cargo_data, EAcceptance *accept, std::string &tooltip)
{
BOOL has_scroll_arrows = (getMaxScrollPos() > 0);
@@ -676,21 +778,33 @@ BOOL LLTabContainer::handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop, EDrag
return LLView::handleDragAndDrop(x, y, mask, drop, type, cargo_data, accept, tooltip);
}
-void LLTabContainer::addTabPanel(LLPanel* child,
- const std::string& label,
- BOOL select,
- void (*on_tab_clicked)(void*, bool),
- void* userdata,
- S32 indent,
- BOOL placeholder,
- eInsertionPoint insertion_point)
+void LLTabContainer::addTabPanel(LLPanel* panelp)
{
+ addTabPanel(TabPanelParams().panel(panelp));
+}
+
+void LLTabContainer::addTabPanel(const TabPanelParams& panel)
+{
+ LLPanel* child = panel.panel();
+ const std::string& label = panel.label.isProvided()
+ ? panel.label()
+ : panel.panel()->getLabel();
+ BOOL select = panel.select_tab();
+ S32 indent = panel.indent();
+ BOOL placeholder = panel.is_placeholder;
+ eInsertionPoint insertion_point = panel.insert_at();
+
+ static LLUICachedControl<S32> tabcntrv_pad ("UITabCntrvPad", 0);
+ static LLUICachedControl<S32> tabcntr_button_panel_overlap ("UITabCntrButtonPanelOverlap", 0);
+ static LLUICachedControl<S32> tabcntr_tab_height ("UITabCntrTabHeight", 0);
+ static LLUICachedControl<S32> tab_padding ("UITabPadding", 0);
if (child->getParent() == this)
{
// already a child of mine
return;
}
- const LLFontGL* font = LLResMgr::getInstance()->getRes( mIsVertical ? LLFONT_SANSSERIF : LLFONT_SANSSERIF_SMALL );
+ const LLFontGL* font =
+ (mIsVertical ? LLFontGL::getFontSansSerif() : LLFontGL::getFontSansSerifSmall());
// Store the original label for possible xml export.
child->setLabel(label);
@@ -700,28 +814,37 @@ void LLTabContainer::addTabPanel(LLPanel* child,
S32 button_width = mMinTabWidth;
if (!mIsVertical)
{
- button_width = llclamp(font->getWidth(trimmed_label) + TAB_PADDING, mMinTabWidth, mMaxTabWidth);
+ button_width = llclamp(font->getWidth(trimmed_label) + tab_padding, mMinTabWidth, mMaxTabWidth);
}
// Tab panel
S32 tab_panel_top;
S32 tab_panel_bottom;
- if( getTabPosition() == LLTabContainer::TOP )
+ if (!getTabsHidden())
{
- S32 tab_height = mIsVertical ? BTN_HEIGHT : TABCNTR_TAB_HEIGHT;
- tab_panel_top = getRect().getHeight() - getTopBorderHeight() - (tab_height - TABCNTR_BUTTON_PANEL_OVERLAP);
- tab_panel_bottom = LLPANEL_BORDER_WIDTH;
+ if( getTabPosition() == LLTabContainer::TOP )
+ {
+ S32 tab_height = mIsVertical ? BTN_HEIGHT : tabcntr_tab_height;
+ tab_panel_top = getRect().getHeight() - getTopBorderHeight() - (tab_height - tabcntr_button_panel_overlap);
+ tab_panel_bottom = LLPANEL_BORDER_WIDTH;
+ }
+ else
+ {
+ tab_panel_top = getRect().getHeight() - getTopBorderHeight();
+ tab_panel_bottom = (tabcntr_tab_height - tabcntr_button_panel_overlap); // Run to the edge, covering up the border
+ }
}
else
{
- tab_panel_top = getRect().getHeight() - getTopBorderHeight();
- tab_panel_bottom = (TABCNTR_TAB_HEIGHT - TABCNTR_BUTTON_PANEL_OVERLAP); // Run to the edge, covering up the border
+ //Scip tab button space if they are invisible(EXT - 576)
+ tab_panel_top = getRect().getHeight();
+ tab_panel_bottom = LLPANEL_BORDER_WIDTH;
}
-
+
LLRect tab_panel_rect;
- if (mIsVertical)
+ if (!getTabsHidden() && mIsVertical)
{
- tab_panel_rect = LLRect(mMinTabWidth + (LLPANEL_BORDER_WIDTH * 2) + TABCNTRV_PAD,
+ tab_panel_rect = LLRect(mMinTabWidth + (LLPANEL_BORDER_WIDTH * 2) + tabcntrv_pad,
getRect().getHeight() - LLPANEL_BORDER_WIDTH,
getRect().getWidth() - LLPANEL_BORDER_WIDTH,
LLPANEL_BORDER_WIDTH);
@@ -744,28 +867,28 @@ void LLTabContainer::addTabPanel(LLPanel* child,
// Tab button
LLRect btn_rect; // Note: btn_rect.mLeft is just a dummy. Will be updated in draw().
- std::string tab_img;
- std::string tab_selected_img;
+ LLUIImage* tab_img = NULL;
+ LLUIImage* tab_selected_img = NULL;
S32 tab_fudge = 1; // To make new tab art look better, nudge buttons up 1 pel
if (mIsVertical)
{
- btn_rect.setLeftTopAndSize(TABCNTRV_PAD + LLPANEL_BORDER_WIDTH + 2, // JC - Fudge factor
- (getRect().getHeight() - getTopBorderHeight() - LLPANEL_BORDER_WIDTH - 1) - ((BTN_HEIGHT + TABCNTRV_PAD) * getTabCount()),
+ btn_rect.setLeftTopAndSize(tabcntrv_pad + LLPANEL_BORDER_WIDTH + 2, // JC - Fudge factor
+ (getRect().getHeight() - getTopBorderHeight() - LLPANEL_BORDER_WIDTH - 1) - ((BTN_HEIGHT + tabcntrv_pad) * getTabCount()),
mMinTabWidth,
BTN_HEIGHT);
}
else if( getTabPosition() == LLTabContainer::TOP )
{
- btn_rect.setLeftTopAndSize( 0, getRect().getHeight() - getTopBorderHeight() + tab_fudge, button_width, TABCNTR_TAB_HEIGHT );
- tab_img = "tab_top_blue.tga";
- tab_selected_img = "tab_top_selected_blue.tga";
+ btn_rect.setLeftTopAndSize( 0, getRect().getHeight() - getTopBorderHeight() + tab_fudge, button_width, tabcntr_tab_height );
+ tab_img = mImageTopUnselected.get();
+ tab_selected_img = mImageTopSelected.get();
}
else
{
- btn_rect.setOriginAndSize( 0, 0 + tab_fudge, button_width, TABCNTR_TAB_HEIGHT );
- tab_img = "tab_bottom_blue.tga";
- tab_selected_img = "tab_bottom_selected_blue.tga";
+ btn_rect.setOriginAndSize( 0, 0 + tab_fudge, button_width, tabcntr_tab_height );
+ tab_img = mImageBottomUnselected.get();
+ tab_selected_img = mImageBottomSelected.get();
}
LLTextBox* textbox = NULL;
@@ -774,31 +897,38 @@ void LLTabContainer::addTabPanel(LLPanel* child,
if (placeholder)
{
btn_rect.translate(0, -LLBUTTON_V_PAD-2);
- textbox = new LLTextBox(trimmed_label, btn_rect, trimmed_label, font);
+ LLTextBox::Params params;
+ params.name(trimmed_label);
+ params.rect(btn_rect);
+ params.text(trimmed_label);
+ params.font(font);
+ textbox = LLUICtrlFactory::create<LLTextBox> (params);
- btn = new LLButton(LLStringUtil::null, LLRect(0,0,0,0));
+ LLButton::Params p;
+ p.name("");
+ btn = LLUICtrlFactory::create<LLButton>(p);
}
else
{
if (mIsVertical)
{
- btn = new LLButton(std::string("vert tab button"),
- btn_rect,
- LLStringUtil::null,
- LLStringUtil::null,
- LLStringUtil::null,
- &LLTabContainer::onTabBtn, NULL,
- font,
- trimmed_label, trimmed_label);
- btn->setImages(std::string("tab_left.tga"), std::string("tab_left_selected.tga"));
- btn->setScaleImage(TRUE);
- btn->setHAlign(LLFontGL::LEFT);
- btn->setFollows(FOLLOWS_TOP | FOLLOWS_LEFT);
- btn->setTabStop(FALSE);
+ LLButton::Params p;
+ p.name(std::string("vert tab button"));
+ p.rect(btn_rect);
+ p.follows.flags(FOLLOWS_TOP | FOLLOWS_LEFT);
+ p.click_callback.function(boost::bind(&LLTabContainer::onTabBtn, this, _2, child));
+ p.font(font);
+ p.label(trimmed_label);
+ p.image_unselected(mImageLeftUnselected);
+ p.image_selected(mImageLeftSelected);
+ p.scale_image(true);
+ p.font_halign = LLFontGL::LEFT;
+ p.tab_stop(false);
if (indent)
{
- btn->setLeftHPad(indent);
+ p.pad_left(indent);
}
+ btn = LLUICtrlFactory::create<LLButton>(p);
}
else
{
@@ -806,55 +936,64 @@ void LLTabContainer::addTabPanel(LLPanel* child,
tooltip += "\nAlt-Left arrow for previous tab";
tooltip += "\nAlt-Right arrow for next tab";
- btn = new LLButton(std::string(child->getName()) + " tab",
- btn_rect,
- LLStringUtil::null, LLStringUtil::null, LLStringUtil::null,
- &LLTabContainer::onTabBtn, NULL, // set userdata below
- font,
- trimmed_label, trimmed_label );
- btn->setVisible( FALSE );
- btn->setToolTip( tooltip );
- btn->setScaleImage(TRUE);
- btn->setImages(tab_img, tab_selected_img);
-
+ LLButton::Params p;
+ p.name(std::string(child->getName()) + " tab");
+ p.rect(btn_rect);
+ p.click_callback.function(boost::bind(&LLTabContainer::onTabBtn, this, _2, child));
+ p.font(font);
+ p.label(trimmed_label);
+ p.visible(false);
+ p.tool_tip(tooltip);
+ p.scale_image(true);
+ p.image_unselected(tab_img);
+ p.image_selected(tab_selected_img);
+ p.tab_stop(false);
// Try to squeeze in a bit more text
- btn->setLeftHPad( 4 );
- btn->setRightHPad( 2 );
- btn->setHAlign(LLFontGL::LEFT);
- btn->setTabStop(FALSE);
+ p.pad_left(4);
+ p.pad_right(2);
+ p.font_halign = LLFontGL::LEFT;
+ p.follows.flags = FOLLOWS_LEFT;
+ p.follows.flags = FOLLOWS_LEFT;
+
if (indent)
{
- btn->setLeftHPad(indent);
+ p.pad_left(indent);
}
if( getTabPosition() == TOP )
{
- btn->setFollowsTop();
+ p.follows.flags = p.follows.flags() | FOLLOWS_TOP;
}
else
{
- btn->setFollowsBottom();
+ p.follows.flags = p.follows.flags() | FOLLOWS_BOTTOM;
}
+
+ btn = LLUICtrlFactory::create<LLButton>(p);
}
}
- LLTabTuple* tuple = new LLTabTuple( this, child, btn, on_tab_clicked, userdata, textbox );
+ LLTabTuple* tuple = new LLTabTuple( this, child, btn, textbox );
insertTuple( tuple, insertion_point );
- if (textbox)
- {
- textbox->setSaveToXML(false);
- addChild( textbox, 0 );
- }
- if (btn)
+ //Don't add button and textbox if tab buttons are invisible(EXT - 576)
+ if (!getTabsHidden())
{
- btn->setSaveToXML(false);
- btn->setCallbackUserData( tuple );
- addChild( btn, 0 );
+ if (textbox)
+ {
+ textbox->setSaveToXML(false);
+ addChild( textbox, 0 );
+ }
+ if (btn)
+ {
+ btn->setSaveToXML(false);
+ addChild( btn, 0 );
+ }
}
+
if (child)
{
- addChild(child, 1);
+ LLUICtrl::addChild(child, 1);
}
if( select )
@@ -867,11 +1006,12 @@ void LLTabContainer::addTabPanel(LLPanel* child,
void LLTabContainer::addPlaceholder(LLPanel* child, const std::string& label)
{
- addTabPanel(child, label, FALSE, NULL, NULL, 0, TRUE);
+ addTabPanel(TabPanelParams().panel(child).label(label).is_placeholder(true));
}
void LLTabContainer::removeTabPanel(LLPanel* child)
{
+ static LLUICachedControl<S32> tabcntrv_pad ("UITabCntrvPad", 0);
if (mIsVertical)
{
// Fix-up button sizes
@@ -880,8 +1020,8 @@ void LLTabContainer::removeTabPanel(LLPanel* child)
{
LLTabTuple* tuple = *iter;
LLRect rect;
- rect.setLeftTopAndSize(TABCNTRV_PAD + LLPANEL_BORDER_WIDTH + 2, // JC - Fudge factor
- (getRect().getHeight() - LLPANEL_BORDER_WIDTH - 1) - ((BTN_HEIGHT + TABCNTRV_PAD) * (tab_count)),
+ rect.setLeftTopAndSize(tabcntrv_pad + LLPANEL_BORDER_WIDTH + 2, // JC - Fudge factor
+ (getRect().getHeight() - LLPANEL_BORDER_WIDTH - 1) - ((BTN_HEIGHT + tabcntrv_pad) * (tab_count)),
mMinTabWidth,
BTN_HEIGHT);
if (tuple->mPlaceholderText)
@@ -1044,7 +1184,7 @@ S32 LLTabContainer::getPanelIndexByTitle(const std::string& title)
return -1;
}
-LLPanel *LLTabContainer::getPanelByName(const std::string& name)
+LLPanel* LLTabContainer::getPanelByName(const std::string& name)
{
for (S32 index = 0 ; index < (S32)mTabList.size(); index++)
{
@@ -1138,42 +1278,36 @@ BOOL LLTabContainer::selectTabPanel(LLPanel* child)
BOOL LLTabContainer::selectTab(S32 which)
{
- if (which >= getTabCount()) return FALSE;
- if (which < 0) return FALSE;
-
- //if( gFocusMgr.childHasKeyboardFocus( this ) )
- //{
- // gFocusMgr.setKeyboardFocus( NULL );
- //}
+ if (which >= getTabCount() || which < 0)
+ return FALSE;
LLTabTuple* selected_tuple = getTab(which);
if (!selected_tuple)
{
return FALSE;
}
+
+ LLSD cbdata;
+ if (selected_tuple->mTabPanel)
+ cbdata = selected_tuple->mTabPanel->getName();
- if (!selected_tuple->mPrecommitChangeCallback)
+ BOOL res = FALSE;
+ if( mValidateSignal( this, cbdata ) )
{
- return setTab(which);
+ res = setTab(which);
+ if (res)
+ {
+ mCommitSignal(this, cbdata);
+ }
}
-
- mNextTabIdx = which;
- selected_tuple->mPrecommitChangeCallback(selected_tuple->mUserData, false);
- return TRUE;
+
+ return res;
}
+// private
BOOL LLTabContainer::setTab(S32 which)
{
- if (which == -1)
- {
- if (mNextTabIdx == -1)
- {
- return FALSE;
- }
- which = mNextTabIdx;
- mNextTabIdx = -1;
- }
-
+ static LLUICachedControl<S32> tabcntr_arrow_btn_size ("UITabCntrArrowBtnSize", 0);
LLTabTuple* selected_tuple = getTab(which);
if (!selected_tuple)
{
@@ -1196,7 +1330,7 @@ BOOL LLTabContainer::setTab(S32 which)
// RN: this limits tab-stops to active button only, which would require arrow keys to switch tabs
tuple->mButton->setTabStop( is_selected );
- if( is_selected && (mIsVertical || (getMaxScrollPos() > 0)))
+ if (is_selected)
{
// Make sure selected tab is within scroll region
if (mIsVertical)
@@ -1212,7 +1346,7 @@ BOOL LLTabContainer::setTab(S32 which)
is_visible = FALSE;
}
}
- else
+ else if (getMaxScrollPos() > 0)
{
if( i < getScrollPos() )
{
@@ -1220,7 +1354,7 @@ BOOL LLTabContainer::setTab(S32 which)
}
else
{
- S32 available_width_with_arrows = getRect().getWidth() - mRightTabBtnOffset - 2 * (LLPANEL_BORDER_WIDTH + TABCNTR_ARROW_BTN_SIZE + TABCNTR_ARROW_BTN_SIZE + 1);
+ S32 available_width_with_arrows = getRect().getWidth() - mRightTabBtnOffset - 2 * (LLPANEL_BORDER_WIDTH + tabcntr_arrow_btn_size + tabcntr_arrow_btn_size + 1);
S32 running_tab_width = tuple->mButton->getRect().getWidth();
S32 j = i - 1;
S32 min_scroll_pos = i;
@@ -1243,13 +1377,13 @@ BOOL LLTabContainer::setTab(S32 which)
}
is_visible = TRUE;
}
+ else
+ {
+ is_visible = TRUE;
+ }
}
i++;
}
- if( selected_tuple->mOnChangeCallback )
- {
- selected_tuple->mOnChangeCallback( selected_tuple->mUserData, false );
- }
}
if (mIsVertical && getCurrentPanelIndex() >= 0)
{
@@ -1295,6 +1429,7 @@ void LLTabContainer::setTabPanelFlashing(LLPanel* child, BOOL state )
void LLTabContainer::setTabImage(LLPanel* child, std::string image_name, const LLColor4& color)
{
+ static LLUICachedControl<S32> tab_padding ("UITabPadding", 0);
LLTabTuple* tuple = getTabByPanel(child);
if( tuple )
{
@@ -1302,7 +1437,7 @@ void LLTabContainer::setTabImage(LLPanel* child, std::string image_name, const L
if (!mIsVertical)
{
- const LLFontGL* fontp = LLResMgr::getInstance()->getRes( LLFONT_SANSSERIF_SMALL );
+ const LLFontGL* fontp = LLFontGL::getFontSansSerifSmall();
// remove current width from total tab strip width
mTotalTabWidth -= tuple->mButton->getRect().getWidth();
@@ -1313,7 +1448,7 @@ void LLTabContainer::setTabImage(LLPanel* child, std::string image_name, const L
tuple->mPadding = image_overlay_width;
tuple->mButton->setRightHPad(6);
- tuple->mButton->reshape(llclamp(fontp->getWidth(tuple->mButton->getLabelSelected()) + TAB_PADDING + tuple->mPadding, mMinTabWidth, mMaxTabWidth),
+ tuple->mButton->reshape(llclamp(fontp->getWidth(tuple->mButton->getLabelSelected()) + tab_padding + tuple->mPadding, mMinTabWidth, mMaxTabWidth),
tuple->mButton->getRect().getHeight());
// add back in button width to total tab strip width
mTotalTabWidth += tuple->mButton->getRect().getWidth();
@@ -1352,33 +1487,6 @@ S32 LLTabContainer::getTopBorderHeight() const
return mTopBorderHeight;
}
-void LLTabContainer::setTabChangeCallback(LLPanel* tab, void (*on_tab_clicked)(void*, bool))
-{
- LLTabTuple* tuplep = getTabByPanel(tab);
- if (tuplep)
- {
- tuplep->mOnChangeCallback = on_tab_clicked;
- }
-}
-
-void LLTabContainer::setTabPrecommitChangeCallback(LLPanel* tab, void (*on_precommit)(void*, bool))
-{
- LLTabTuple* tuplep = getTabByPanel(tab);
- if (tuplep)
- {
- tuplep->mPrecommitChangeCallback = on_precommit;
- }
-}
-
-void LLTabContainer::setTabUserData(LLPanel* tab, void* userdata)
-{
- LLTabTuple* tuplep = getTabByPanel(tab);
- if (tuplep)
- {
- tuplep->mUserData = userdata;
- }
-}
-
void LLTabContainer::setRightTabBtnOffset(S32 offset)
{
mNextArrowBtn->translate( -offset - mRightTabBtnOffset, 0 );
@@ -1388,13 +1496,15 @@ void LLTabContainer::setRightTabBtnOffset(S32 offset)
void LLTabContainer::setPanelTitle(S32 index, const std::string& title)
{
+ static LLUICachedControl<S32> tab_padding ("UITabPadding", 0);
+
if (index >= 0 && index < getTabCount())
{
LLTabTuple* tuple = getTab(index);
LLButton* tab_button = tuple->mButton;
- const LLFontGL* fontp = LLResMgr::getInstance()->getRes( LLFONT_SANSSERIF_SMALL );
+ const LLFontGL* fontp = LLFontGL::getFontSansSerifSmall();
mTotalTabWidth -= tab_button->getRect().getWidth();
- tab_button->reshape(llclamp(fontp->getWidth(title) + TAB_PADDING + tuple->mPadding, mMinTabWidth, mMaxTabWidth), tab_button->getRect().getHeight());
+ tab_button->reshape(llclamp(fontp->getWidth(title) + tab_padding + tuple->mPadding, mMinTabWidth, mMaxTabWidth), tab_button->getRect().getHeight());
mTotalTabWidth += tab_button->getRect().getWidth();
tab_button->setLabelSelected(title);
tab_button->setLabelUnselected(title);
@@ -1403,182 +1513,60 @@ void LLTabContainer::setPanelTitle(S32 index, const std::string& title)
}
-// static
-void LLTabContainer::onTabBtn( void* userdata )
+void LLTabContainer::onTabBtn( const LLSD& data, LLPanel* panel )
{
- LLTabTuple* tuple = (LLTabTuple*) userdata;
- LLTabContainer* self = tuple->mTabContainer;
- self->selectTabPanel( tuple->mTabPanel );
+ LLTabTuple* tuple = getTabByPanel(panel);
+ selectTabPanel( panel );
tuple->mTabPanel->setFocus(TRUE);
}
-// static
-void LLTabContainer::onCloseBtn( void* userdata )
-{
- LLTabContainer* self = (LLTabContainer*) userdata;
- if( self->mCloseCallback )
- {
- self->mCloseCallback( self->mCallbackUserdata );
- }
-}
-
-// static
-void LLTabContainer::onNextBtn( void* userdata )
+void LLTabContainer::onNextBtn( const LLSD& data )
{
- // Scroll tabs to the left
- LLTabContainer* self = (LLTabContainer*) userdata;
- if (!self->mScrolled)
+ if (!mScrolled)
{
- self->scrollNext();
+ scrollNext();
}
- self->mScrolled = FALSE;
+ mScrolled = FALSE;
}
-// static
-void LLTabContainer::onNextBtnHeld( void* userdata )
+void LLTabContainer::onNextBtnHeld( const LLSD& data )
{
- LLTabContainer* self = (LLTabContainer*) userdata;
- if (self->mScrollTimer.getElapsedTimeF32() > SCROLL_STEP_TIME)
+ if (mScrollTimer.getElapsedTimeF32() > SCROLL_STEP_TIME)
{
- self->mScrollTimer.reset();
- self->scrollNext();
- self->mScrolled = TRUE;
+ mScrollTimer.reset();
+ scrollNext();
+ mScrolled = TRUE;
}
}
-// static
-void LLTabContainer::onPrevBtn( void* userdata )
+void LLTabContainer::onPrevBtn( const LLSD& data )
{
- LLTabContainer* self = (LLTabContainer*) userdata;
- if (!self->mScrolled)
+ if (!mScrolled)
{
- self->scrollPrev();
+ scrollPrev();
}
- self->mScrolled = FALSE;
+ mScrolled = FALSE;
}
-// static
-void LLTabContainer::onJumpFirstBtn( void* userdata )
+void LLTabContainer::onJumpFirstBtn( const LLSD& data )
{
- LLTabContainer* self = (LLTabContainer*) userdata;
- self->mScrollPos = 0;
+ mScrollPos = 0;
}
-// static
-void LLTabContainer::onJumpLastBtn( void* userdata )
+void LLTabContainer::onJumpLastBtn( const LLSD& data )
{
- LLTabContainer* self = (LLTabContainer*) userdata;
- self->mScrollPos = self->mMaxScrollPos;
+ mScrollPos = mMaxScrollPos;
}
-// static
-void LLTabContainer::onPrevBtnHeld( void* userdata )
+void LLTabContainer::onPrevBtnHeld( const LLSD& data )
{
- LLTabContainer* self = (LLTabContainer*) userdata;
- if (self->mScrollTimer.getElapsedTimeF32() > SCROLL_STEP_TIME)
- {
- self->mScrollTimer.reset();
- self->scrollPrev();
- self->mScrolled = TRUE;
- }
-}
-
-// static
-LLView* LLTabContainer::fromXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFactory *factory)
-{
- std::string name("tab_container");
- node->getAttributeString("name", name);
-
- // Figure out if we are creating a vertical or horizontal tab container.
- bool is_vertical = false;
- LLTabContainer::TabPosition tab_position = LLTabContainer::TOP;
- if (node->hasAttribute("tab_position"))
+ if (mScrollTimer.getElapsedTimeF32() > SCROLL_STEP_TIME)
{
- std::string tab_position_string;
- node->getAttributeString("tab_position", tab_position_string);
- LLStringUtil::toLower(tab_position_string);
-
- if ("top" == tab_position_string)
- {
- tab_position = LLTabContainer::TOP;
- is_vertical = false;
- }
- else if ("bottom" == tab_position_string)
- {
- tab_position = LLTabContainer::BOTTOM;
- is_vertical = false;
- }
- else if ("left" == tab_position_string)
- {
- is_vertical = true;
- }
- }
- BOOL border = FALSE;
- node->getAttributeBOOL("border", border);
-
- LLTabContainer* tab_container = new LLTabContainer(name, LLRect::null, tab_position, border, is_vertical);
-
- S32 tab_min_width = tab_container->mMinTabWidth;
- if (node->hasAttribute("tab_width"))
- {
- node->getAttributeS32("tab_width", tab_min_width);
- }
- else if( node->hasAttribute("tab_min_width"))
- {
- node->getAttributeS32("tab_min_width", tab_min_width);
- }
-
- S32 tab_max_width = tab_container->mMaxTabWidth;
- if (node->hasAttribute("tab_max_width"))
- {
- node->getAttributeS32("tab_max_width", tab_max_width);
- }
-
- tab_container->setMinTabWidth(tab_min_width);
- tab_container->setMaxTabWidth(tab_max_width);
-
- BOOL hidden(tab_container->getTabsHidden());
- node->getAttributeBOOL("hide_tabs", hidden);
- tab_container->setTabsHidden(hidden);
-
- tab_container->setPanelParameters(node, parent);
-
- if (LLFloater::getFloaterHost())
- {
- LLFloater::getFloaterHost()->setTabContainer(tab_container);
- }
-
- //parent->addChild(tab_container);
-
- // Add all tab panels.
- LLXMLNodePtr child;
- for (child = node->getFirstChild(); child.notNull(); child = child->getNextSibling())
- {
- LLView *control = factory->createCtrlWidget(tab_container, child);
- if (control && control->isPanel())
- {
- LLPanel* panelp = (LLPanel*)control;
- std::string label;
- child->getAttributeString("label", label);
- if (label.empty())
- {
- label = panelp->getLabel();
- }
- BOOL placeholder = FALSE;
- child->getAttributeBOOL("placeholder", placeholder);
- tab_container->addTabPanel(panelp, label, false,
- NULL, NULL, 0, placeholder);
- }
+ mScrollTimer.reset();
+ scrollPrev();
+ mScrolled = TRUE;
}
-
- tab_container->selectFirstTab();
-
- tab_container->postBuild();
-
- tab_container->initButtons(); // now that we have the correct rect
-
- return tab_container;
}
// private
@@ -1591,99 +1579,105 @@ void LLTabContainer::initButtons()
return; // Don't have a rect yet or already got called
}
- std::string out_id;
- std::string in_id;
-
if (mIsVertical)
{
+ static LLUICachedControl<S32> tabcntrv_arrow_btn_size ("UITabCntrvArrowBtnSize", 0);
// Left and right scroll arrows (for when there are too many tabs to show all at once).
S32 btn_top = getRect().getHeight();
- S32 btn_top_lower = getRect().mBottom+TABCNTRV_ARROW_BTN_SIZE;
+ S32 btn_top_lower = getRect().mBottom+tabcntrv_arrow_btn_size;
LLRect up_arrow_btn_rect;
- up_arrow_btn_rect.setLeftTopAndSize( mMinTabWidth/2 , btn_top, TABCNTRV_ARROW_BTN_SIZE, TABCNTRV_ARROW_BTN_SIZE );
+ up_arrow_btn_rect.setLeftTopAndSize( mMinTabWidth/2 , btn_top, tabcntrv_arrow_btn_size, tabcntrv_arrow_btn_size );
LLRect down_arrow_btn_rect;
- down_arrow_btn_rect.setLeftTopAndSize( mMinTabWidth/2 , btn_top_lower, TABCNTRV_ARROW_BTN_SIZE, TABCNTRV_ARROW_BTN_SIZE );
-
- out_id = "UIImgBtnScrollUpOutUUID";
- in_id = "UIImgBtnScrollUpInUUID";
- mPrevArrowBtn = new LLButton(std::string("Up Arrow"), up_arrow_btn_rect,
- out_id, in_id, LLStringUtil::null,
- &onPrevBtn, this, NULL );
- mPrevArrowBtn->setFollowsTop();
- mPrevArrowBtn->setFollowsLeft();
-
- out_id = "UIImgBtnScrollDownOutUUID";
- in_id = "UIImgBtnScrollDownInUUID";
- mNextArrowBtn = new LLButton(std::string("Down Arrow"), down_arrow_btn_rect,
- out_id, in_id, LLStringUtil::null,
- &onNextBtn, this, NULL );
- mNextArrowBtn->setFollowsBottom();
- mNextArrowBtn->setFollowsLeft();
+ down_arrow_btn_rect.setLeftTopAndSize( mMinTabWidth/2 , btn_top_lower, tabcntrv_arrow_btn_size, tabcntrv_arrow_btn_size );
+
+ LLButton::Params prev_btn_params;
+ prev_btn_params.name(std::string("Up Arrow"));
+ prev_btn_params.rect(up_arrow_btn_rect);
+ prev_btn_params.follows.flags(FOLLOWS_TOP | FOLLOWS_LEFT);
+ prev_btn_params.image_unselected.name("scrollbutton_up_out_blue.tga");
+ prev_btn_params.image_selected.name("scrollbutton_up_in_blue.tga");
+ prev_btn_params.click_callback.function(boost::bind(&LLTabContainer::onPrevBtn, this, _2));
+ mPrevArrowBtn = LLUICtrlFactory::create<LLButton>(prev_btn_params);
+
+ LLButton::Params next_btn_params;
+ next_btn_params.name(std::string("Down Arrow"));
+ next_btn_params.rect(down_arrow_btn_rect);
+ next_btn_params.follows.flags(FOLLOWS_BOTTOM | FOLLOWS_LEFT);
+ next_btn_params.image_unselected.name("scrollbutton_down_out_blue.tga");
+ next_btn_params.image_selected.name("scrollbutton_down_in_blue.tga");
+ next_btn_params.click_callback.function(boost::bind(&LLTabContainer::onNextBtn, this, _2));
+ mNextArrowBtn = LLUICtrlFactory::create<LLButton>(next_btn_params);
}
else // Horizontal
{
+ static LLUICachedControl<S32> tabcntr_arrow_btn_size ("UITabCntrArrowBtnSize", 0);
S32 arrow_fudge = 1; // match new art better
- // tabs on bottom reserve room for resize handle (just in case)
- if (getTabPosition() == BOTTOM)
- {
- mRightTabBtnOffset = RESIZE_HANDLE_WIDTH;
- }
-
// Left and right scroll arrows (for when there are too many tabs to show all at once).
- S32 btn_top = (getTabPosition() == TOP ) ? getRect().getHeight() - getTopBorderHeight() : TABCNTR_ARROW_BTN_SIZE + 1;
+ S32 btn_top = (getTabPosition() == TOP ) ? getRect().getHeight() - getTopBorderHeight() : tabcntr_arrow_btn_size + 1;
LLRect left_arrow_btn_rect;
- left_arrow_btn_rect.setLeftTopAndSize( LLPANEL_BORDER_WIDTH+1+TABCNTR_ARROW_BTN_SIZE, btn_top + arrow_fudge, TABCNTR_ARROW_BTN_SIZE, TABCNTR_ARROW_BTN_SIZE );
+ left_arrow_btn_rect.setLeftTopAndSize( LLPANEL_BORDER_WIDTH+1+tabcntr_arrow_btn_size, btn_top + arrow_fudge, tabcntr_arrow_btn_size, tabcntr_arrow_btn_size );
LLRect jump_left_arrow_btn_rect;
- jump_left_arrow_btn_rect.setLeftTopAndSize( LLPANEL_BORDER_WIDTH+1, btn_top + arrow_fudge, TABCNTR_ARROW_BTN_SIZE, TABCNTR_ARROW_BTN_SIZE );
+ jump_left_arrow_btn_rect.setLeftTopAndSize( LLPANEL_BORDER_WIDTH+1, btn_top + arrow_fudge, tabcntr_arrow_btn_size, tabcntr_arrow_btn_size );
- S32 right_pad = TABCNTR_ARROW_BTN_SIZE + LLPANEL_BORDER_WIDTH + 1;
+ S32 right_pad = tabcntr_arrow_btn_size + LLPANEL_BORDER_WIDTH + 1;
LLRect right_arrow_btn_rect;
- right_arrow_btn_rect.setLeftTopAndSize( getRect().getWidth() - mRightTabBtnOffset - right_pad - TABCNTR_ARROW_BTN_SIZE,
+ right_arrow_btn_rect.setLeftTopAndSize( getRect().getWidth() - mRightTabBtnOffset - right_pad - tabcntr_arrow_btn_size,
btn_top + arrow_fudge,
- TABCNTR_ARROW_BTN_SIZE, TABCNTR_ARROW_BTN_SIZE );
+ tabcntr_arrow_btn_size, tabcntr_arrow_btn_size );
LLRect jump_right_arrow_btn_rect;
jump_right_arrow_btn_rect.setLeftTopAndSize( getRect().getWidth() - mRightTabBtnOffset - right_pad,
btn_top + arrow_fudge,
- TABCNTR_ARROW_BTN_SIZE, TABCNTR_ARROW_BTN_SIZE );
-
- out_id = "UIImgBtnJumpLeftOutUUID";
- in_id = "UIImgBtnJumpLeftInUUID";
- mJumpPrevArrowBtn = new LLButton(std::string("Jump Left Arrow"), jump_left_arrow_btn_rect,
- out_id, in_id, LLStringUtil::null,
- &LLTabContainer::onJumpFirstBtn, this, LLFontGL::getFontSansSerif() );
- mJumpPrevArrowBtn->setFollowsLeft();
-
- out_id = "UIImgBtnScrollLeftOutUUID";
- in_id = "UIImgBtnScrollLeftInUUID";
- mPrevArrowBtn = new LLButton(std::string("Left Arrow"), left_arrow_btn_rect,
- out_id, in_id, LLStringUtil::null,
- &LLTabContainer::onPrevBtn, this, LLFontGL::getFontSansSerif() );
- mPrevArrowBtn->setHeldDownCallback(onPrevBtnHeld);
- mPrevArrowBtn->setFollowsLeft();
-
- out_id = "UIImgBtnJumpRightOutUUID";
- in_id = "UIImgBtnJumpRightInUUID";
- mJumpNextArrowBtn = new LLButton(std::string("Jump Right Arrow"), jump_right_arrow_btn_rect,
- out_id, in_id, LLStringUtil::null,
- &LLTabContainer::onJumpLastBtn, this,
- LLFontGL::getFontSansSerif());
- mJumpNextArrowBtn->setFollowsRight();
-
- out_id = "UIImgBtnScrollRightOutUUID";
- in_id = "UIImgBtnScrollRightInUUID";
- mNextArrowBtn = new LLButton(std::string("Right Arrow"), right_arrow_btn_rect,
- out_id, in_id, LLStringUtil::null,
- &LLTabContainer::onNextBtn, this,
- LLFontGL::getFontSansSerif());
- mNextArrowBtn->setFollowsRight();
+ tabcntr_arrow_btn_size, tabcntr_arrow_btn_size );
+
+ LLButton::Params p;
+ p.name(std::string("Jump Left Arrow"));
+ p.image_unselected.name("jump_left_out.tga");
+ p.image_selected.name("jump_left_in.tga");
+ p.click_callback.function(boost::bind(&LLTabContainer::onJumpFirstBtn, this, _2));
+ p.rect(jump_left_arrow_btn_rect);
+ p.follows.flags(FOLLOWS_LEFT);
+
+ mJumpPrevArrowBtn = LLUICtrlFactory::create<LLButton>(p);
+
+ p = LLButton::Params();
+ p.name(std::string("Left Arrow"));
+ p.rect(left_arrow_btn_rect);
+ p.follows.flags(FOLLOWS_LEFT);
+ p.image_unselected.name("scrollbutton_left_out_blue.tga");
+ p.image_selected.name("scrollbutton_left_in_blue.tga");
+ p.click_callback.function(boost::bind(&LLTabContainer::onPrevBtn, this, _2));
+ p.mouse_held_callback.function(boost::bind(&LLTabContainer::onPrevBtnHeld, this, _2));
+
+ mPrevArrowBtn = LLUICtrlFactory::create<LLButton>(p);
+
+ p = LLButton::Params();
+ p.name(std::string("Jump Right Arrow"));
+ p.rect(jump_right_arrow_btn_rect);
+ p.follows.flags(FOLLOWS_RIGHT);
+ p.image_unselected.name("jump_right_out.tga");
+ p.image_selected.name("jump_right_in.tga");
+ p.click_callback.function(boost::bind(&LLTabContainer::onJumpLastBtn, this, _2));
+
+ mJumpNextArrowBtn = LLUICtrlFactory::create<LLButton>(p);
+
+ p = LLButton::Params();
+ p.name(std::string("Right Arrow"));
+ p.rect(right_arrow_btn_rect);
+ p.follows.flags(FOLLOWS_RIGHT);
+ p.image_unselected.name("scrollbutton_right_out_blue.tga");
+ p.image_selected.name("scrollbutton_right_in_blue.tga");
+ p.click_callback.function(boost::bind(&LLTabContainer::onNextBtn, this, _2));
+ p.mouse_held_callback.function(boost::bind(&LLTabContainer::onNextBtnHeld, this, _2));
+
+ mNextArrowBtn = LLUICtrlFactory::create<LLButton>(p);
if( getTabPosition() == TOP )
{
@@ -1701,12 +1695,10 @@ void LLTabContainer::initButtons()
}
}
- mPrevArrowBtn->setHeldDownCallback(onPrevBtnHeld);
mPrevArrowBtn->setSaveToXML(false);
mPrevArrowBtn->setTabStop(FALSE);
addChild(mPrevArrowBtn);
- mNextArrowBtn->setHeldDownCallback(onNextBtnHeld);
mNextArrowBtn->setSaveToXML(false);
mNextArrowBtn->setTabStop(FALSE);
addChild(mNextArrowBtn);
@@ -1729,7 +1721,17 @@ void LLTabContainer::initButtons()
setDefaultTabGroup(1);
}
-LLTabContainer::LLTabTuple* LLTabContainer::getTabByPanel(LLPanel* child)
+//this is a work around for the current LLPanel::initFromParams hack
+//so that it doesn't overwrite the default tab group.
+//will be removed when LLPanel is fixed soon.
+void LLTabContainer::initFromParams(const LLPanel::Params& p)
+{
+ LLPanel::initFromParams(p);
+
+ setDefaultTabGroup(1);
+}
+
+LLTabTuple* LLTabContainer::getTabByPanel(LLPanel* child)
{
for(tuple_list_t::iterator iter = mTabList.begin(); iter != mTabList.end(); ++iter)
{
@@ -1775,14 +1777,16 @@ void LLTabContainer::insertTuple(LLTabTuple * tuple, eInsertionPoint insertion_p
void LLTabContainer::updateMaxScrollPos()
{
+ static LLUICachedControl<S32> tabcntrv_pad ("UITabCntrvPad", 0);
BOOL no_scroll = TRUE;
if (mIsVertical)
{
- S32 tab_total_height = (BTN_HEIGHT + TABCNTRV_PAD) * getTabCount();
+ S32 tab_total_height = (BTN_HEIGHT + tabcntrv_pad) * getTabCount();
S32 available_height = getRect().getHeight() - getTopBorderHeight();
if( tab_total_height > available_height )
{
- S32 available_height_with_arrows = getRect().getHeight() - 2*(TABCNTRV_ARROW_BTN_SIZE + 3*TABCNTRV_PAD);
+ static LLUICachedControl<S32> tabcntrv_arrow_btn_size ("UITabCntrvArrowBtnSize", 0);
+ S32 available_height_with_arrows = getRect().getHeight() - 2*(tabcntrv_arrow_btn_size + 3*tabcntrv_pad);
S32 additional_needed = tab_total_height - available_height_with_arrows;
setMaxScrollPos((S32) ceil(additional_needed / float(BTN_HEIGHT) ) );
no_scroll = FALSE;
@@ -1790,16 +1794,19 @@ void LLTabContainer::updateMaxScrollPos()
}
else
{
+ static LLUICachedControl<S32> tabcntr_tab_h_pad ("UITabCntrTabHPad", 0);
+ static LLUICachedControl<S32> tabcntr_arrow_btn_size ("UITabCntrArrowBtnSize", 0);
+ static LLUICachedControl<S32> tabcntr_tab_partial_width ("UITabCntrTabPartialWidth", 0);
S32 tab_space = 0;
S32 available_space = 0;
tab_space = mTotalTabWidth;
- available_space = getRect().getWidth() - mRightTabBtnOffset - 2 * (LLPANEL_BORDER_WIDTH + TABCNTR_TAB_H_PAD);
+ available_space = getRect().getWidth() - mRightTabBtnOffset - 2 * (LLPANEL_BORDER_WIDTH + tabcntr_tab_h_pad);
if( tab_space > available_space )
{
- S32 available_width_with_arrows = getRect().getWidth() - mRightTabBtnOffset - 2 * (LLPANEL_BORDER_WIDTH + TABCNTR_ARROW_BTN_SIZE + TABCNTR_ARROW_BTN_SIZE + 1);
+ S32 available_width_with_arrows = getRect().getWidth() - mRightTabBtnOffset - 2 * (LLPANEL_BORDER_WIDTH + tabcntr_arrow_btn_size + tabcntr_arrow_btn_size + 1);
// subtract off reserved portion on left
- available_width_with_arrows -= TABCNTR_TAB_PARTIAL_WIDTH;
+ available_width_with_arrows -= tabcntr_tab_partial_width;
S32 running_tab_width = 0;
setMaxScrollPos(getTabCount());
diff --git a/indra/llui/lltabcontainer.h b/indra/llui/lltabcontainer.h
index 8117cdee9b..ebe76af966 100644
--- a/indra/llui/lltabcontainer.h
+++ b/indra/llui/lltabcontainer.h
@@ -37,7 +37,7 @@
#include "lltextbox.h"
#include "llframetimer.h"
-extern const S32 TABCNTR_HEADER_HEIGHT;
+class LLTabTuple;
class LLTabContainer : public LLPanel
{
@@ -56,8 +56,38 @@ public:
RIGHT_OF_CURRENT
} eInsertionPoint;
- LLTabContainer( const std::string& name, const LLRect& rect, TabPosition pos,
- BOOL bordered, BOOL is_vertical);
+ struct TabPositions : public LLInitParam::TypeValuesHelper<LLTabContainer::TabPosition, TabPositions>
+ {
+ static void declareValues();
+ };
+
+ struct Params
+ : public LLInitParam::Block<Params, LLPanel::Params>
+ {
+ Optional<TabPosition, TabPositions> tab_position;
+ Optional<S32> tab_width,
+ tab_min_width,
+ tab_max_width;
+ Optional<bool> hide_tabs;
+ Optional<S32> tab_padding_right;
+
+ Optional<LLUIImage*> tab_top_image_unselected,
+ tab_top_image_selected,
+ tab_bottom_image_unselected,
+ tab_bottom_image_selected,
+ tab_left_image_unselected,
+ tab_left_image_selected;
+
+ Params();
+ };
+
+protected:
+ LLTabContainer(const Params&);
+ friend class LLUICtrlFactory;
+
+public:
+ //LLTabContainer( const std::string& name, const LLRect& rect, TabPosition pos,
+ // BOOL bordered, BOOL is_vertical);
/*virtual*/ ~LLTabContainer();
@@ -74,17 +104,35 @@ public:
/*virtual*/ BOOL handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop,
EDragAndDropType type, void* cargo_data,
EAcceptance* accept, std::string& tooltip);
- /*virtual*/ LLXMLNodePtr getXML(bool save_children = true) const;
- /*virtual*/ LLView* getChildView(const std::string& name, BOOL recurse = TRUE, BOOL create_if_missing = TRUE) const;
-
- void addTabPanel(LLPanel* child,
- const std::string& label,
- BOOL select = FALSE,
- void (*on_tab_clicked)(void*, bool) = NULL,
- void* userdata = NULL,
- S32 indent = 0,
- BOOL placeholder = FALSE,
- eInsertionPoint insertion_point = END);
+ /*virtual*/ LLView* getChildView(const std::string& name, BOOL recurse = TRUE) const;
+ /*virtual*/ LLView* findChildView(const std::string& name, BOOL recurse = TRUE) const;
+ /*virtual*/ void initFromParams(const LLPanel::Params& p);
+ /*virtual*/ bool addChild(LLView* view, S32 tab_group = 0);
+ /*virtual*/ BOOL postBuild();
+
+ struct TabPanelParams : public LLInitParam::Block<TabPanelParams>
+ {
+ Mandatory<LLPanel*> panel;
+
+ Optional<std::string> label;
+ Optional<bool> select_tab,
+ is_placeholder;
+ Optional<S32> indent;
+ Optional<eInsertionPoint> insert_at;
+ Optional<void*> user_data;
+
+ TabPanelParams()
+ : panel("panel", NULL),
+ label("label"),
+ select_tab("select_tab"),
+ is_placeholder("is_placeholder"),
+ indent("indent"),
+ insert_at("insert_at", END)
+ {}
+ };
+
+ void addTabPanel(LLPanel* panel);
+ void addTabPanel(const TabPanelParams& panel);
void addPlaceholder(LLPanel* child, const std::string& label);
void removeTabPanel( LLPanel* child );
void lockTabs(S32 num_tabs = 0);
@@ -108,7 +156,6 @@ public:
BOOL selectTabPanel( LLPanel* child );
BOOL selectTab(S32 which);
BOOL selectTabByName(const std::string& title);
- BOOL setTab(S32 which);
BOOL getTabPanelFlashing(LLPanel* child);
void setTabPanelFlashing(LLPanel* child, BOOL state);
@@ -119,10 +166,6 @@ public:
void setTopBorderHeight(S32 height);
S32 getTopBorderHeight() const;
- void setTabChangeCallback(LLPanel* tab, void (*on_tab_clicked)(void*,bool));
- void setTabPrecommitChangeCallback(LLPanel* tab, void (*on_precommit)(void*, bool));
- void setTabUserData(LLPanel* tab, void* userdata);
-
void setRightTabBtnOffset( S32 offset );
void setPanelTitle(S32 index, const std::string& title);
@@ -134,51 +177,20 @@ public:
void startDragAndDropDelayTimer() { mDragAndDropDelayTimer.start(); }
- static void onCloseBtn(void* userdata);
- static void onTabBtn(void* userdata);
- static void onNextBtn(void* userdata);
- static void onNextBtnHeld(void* userdata);
- static void onPrevBtn(void* userdata);
- static void onPrevBtnHeld(void* userdata);
- static void onJumpFirstBtn( void* userdata );
- static void onJumpLastBtn( void* userdata );
-
- static LLView* fromXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFactory *factory);
+ void onTabBtn( const LLSD& data, LLPanel* panel );
+ void onNextBtn(const LLSD& data);
+ void onNextBtnHeld(const LLSD& data);
+ void onPrevBtn(const LLSD& data);
+ void onPrevBtnHeld(const LLSD& data);
+ void onJumpFirstBtn( const LLSD& data );
+ void onJumpLastBtn( const LLSD& data );
private:
- // Structure used to map tab buttons to and from tab panels
- struct LLTabTuple
- {
- LLTabTuple( LLTabContainer* c, LLPanel* p, LLButton* b,
- void (*cb)(void*,bool), void* userdata, LLTextBox* placeholder = NULL,
- void (*pcb)(void*,bool) = NULL)
- :
- mTabContainer(c),
- mTabPanel(p),
- mButton(b),
- mOnChangeCallback( cb ),
- mPrecommitChangeCallback( pcb ),
- mUserData( userdata ),
- mOldState(FALSE),
- mPlaceholderText(placeholder),
- mPadding(0)
- {}
-
- LLTabContainer* mTabContainer;
- LLPanel* mTabPanel;
- LLButton* mButton;
- void (*mOnChangeCallback)(void*, bool);
- void (*mPrecommitChangeCallback)(void*,bool); // Precommit callback gets called before tab is changed and
- // can prevent it from being changed. onChangeCallback is called
- // immediately after tab is actually changed - Nyx
- void* mUserData;
- BOOL mOldState;
- LLTextBox* mPlaceholderText;
- S32 mPadding;
- };
void initButtons();
+ BOOL setTab(S32 which);
+
LLTabTuple* getTab(S32 index) { return mTabList[index]; }
LLTabTuple* getTabByPanel(LLPanel* child);
void insertTuple(LLTabTuple * tuple, eInsertionPoint insertion_point);
@@ -207,7 +219,6 @@ private:
tuple_list_t mTabList;
S32 mCurrentTabIdx;
- S32 mNextTabIdx;
BOOL mTabsHidden;
BOOL mScrolled;
@@ -216,9 +227,6 @@ private:
S32 mScrollPosPixels;
S32 mMaxScrollPos;
- void (*mCloseCallback)(void*);
- void* mCallbackUserdata;
-
LLTextBox* mTitleBox;
S32 mTopBorderHeight;
@@ -240,7 +248,13 @@ private:
S32 mTotalTabWidth;
LLFrameTimer mDragAndDropDelayTimer;
-};
+ LLPointer<LLUIImage> mImageTopUnselected;
+ LLPointer<LLUIImage> mImageTopSelected;
+ LLPointer<LLUIImage> mImageBottomUnselected;
+ LLPointer<LLUIImage> mImageBottomSelected;
+ LLPointer<LLUIImage> mImageLeftUnselected;
+ LLPointer<LLUIImage> mImageLeftSelected;
+};
#endif // LL_TABCONTAINER_H
diff --git a/indra/llui/lltextbox.cpp b/indra/llui/lltextbox.cpp
index 89893bcf8d..96e72487b8 100644
--- a/indra/llui/lltextbox.cpp
+++ b/indra/llui/lltextbox.cpp
@@ -32,63 +32,65 @@
#include "linden_common.h"
#include "lltextbox.h"
+#include "lllink.h"
#include "lluictrlfactory.h"
#include "llfocusmgr.h"
#include "llwindow.h"
-static LLRegisterWidget<LLTextBox> r("text");
-
-LLTextBox::LLTextBox(const std::string& name, const LLRect& rect, const std::string& text,
- const LLFontGL* font, BOOL mouse_opaque)
-: LLUICtrl(name, rect, mouse_opaque, NULL, NULL, FOLLOWS_LEFT | FOLLOWS_TOP ),
- mFontGL(font ? font : LLFontGL::getFontSansSerifSmall())
-{
- initDefaults();
- setText( text );
- setTabStop(FALSE);
-}
-
-LLTextBox::LLTextBox(const std::string& name, const std::string& text, F32 max_width,
- const LLFontGL* font, BOOL mouse_opaque) :
- LLUICtrl(name, LLRect(0, 0, 1, 1), mouse_opaque, NULL, NULL, FOLLOWS_LEFT | FOLLOWS_TOP),
- mFontGL(font ? font : LLFontGL::getFontSansSerifSmall())
-{
- initDefaults();
- setWrappedText(text, max_width);
- reshapeToFitText();
- setTabStop(FALSE);
-}
-
-LLTextBox::LLTextBox(const std::string& name_and_label, const LLRect& rect) :
- LLUICtrl(name_and_label, rect, TRUE, NULL, NULL, FOLLOWS_LEFT | FOLLOWS_TOP),
- mFontGL(LLFontGL::getFontSansSerifSmall())
+static LLDefaultChildRegistry::Register<LLTextBox> r("text");
+
+//*NOTE
+// LLLink is not used in code for now, therefor Visual Studio doesn't build it.
+// "link" is registered here to force Visual Studio to build LLLink class.
+static LLDefaultChildRegistry::Register<LLLink> register_link("link");
+
+LLTextBox::Params::Params()
+: text_color("text_color"),
+ length("length"),
+ type("type"),
+ highlight_on_hover("hover", false),
+ border_visible("border_visible", false),
+ border_drop_shadow_visible("border_drop_shadow_visible", false),
+ bg_visible("bg_visible", false),
+ use_ellipses("use_ellipses"),
+ word_wrap("word_wrap", false),
+ drop_shadow_visible("drop_shadow_visible"),
+ hover_color("hover_color"),
+ disabled_color("disabled_color"),
+ background_color("background_color"),
+ border_color("border_color"),
+ v_pad("v_pad", 0),
+ h_pad("h_pad", 0),
+ line_spacing("line_spacing", 0),
+ text("text"),
+ font_shadow("font_shadow", LLFontGL::NO_SHADOW)
+{}
+
+LLTextBox::LLTextBox(const LLTextBox::Params& p)
+: LLUICtrl(p),
+ mFontGL(p.font),
+ mHoverActive( p.highlight_on_hover ),
+ mHasHover( FALSE ),
+ mBackgroundVisible( p.bg_visible ),
+ mBorderVisible( p.border_visible ),
+ mShadowType( p.font_shadow ),
+ mBorderDropShadowVisible( p.border_drop_shadow_visible ),
+ mUseEllipses( p.use_ellipses ),
+ mHPad(p.h_pad),
+ mVPad(p.v_pad),
+ mVAlign( LLFontGL::TOP ),
+ mClickedCallback(NULL),
+ mTextColor(p.text_color()),
+ mDisabledColor(p.disabled_color()),
+ mBackgroundColor(p.background_color()),
+ mBorderColor(p.border_color()),
+ mHoverColor(p.hover_color()),
+ mHAlign(p.font_halign),
+ mLineSpacing(p.line_spacing),
+ mWordWrap( p.word_wrap ),
+ mDidWordWrap(FALSE)
{
- initDefaults();
- setText( name_and_label );
- setTabStop(FALSE);
-}
-
-void LLTextBox::initDefaults()
-{
- mTextColor = LLUI::sColorsGroup->getColor("LabelTextColor");
- mDisabledColor = LLUI::sColorsGroup->getColor("LabelDisabledColor");
- mBackgroundColor = LLUI::sColorsGroup->getColor("DefaultBackgroundColor");
- mBorderColor = LLUI::sColorsGroup->getColor("DefaultHighlightLight");
- mHoverColor = LLUI::sColorsGroup->getColor( "LabelSelectedColor" );
- mHoverActive = FALSE;
- mHasHover = FALSE;
- mBackgroundVisible = FALSE;
- mBorderVisible = FALSE;
- mFontStyle = LLFontGL::DROP_SHADOW_SOFT;
- mBorderDropShadowVisible = FALSE;
- mUseEllipses = FALSE;
- mLineSpacing = 0;
- mHPad = 0;
- mVPad = 0;
- mHAlign = LLFontGL::LEFT;
- mVAlign = LLFontGL::TOP;
- mClickedCallback = NULL;
- mCallbackUserData = NULL;
+ setText( p.text() );
}
BOOL LLTextBox::handleMouseDown(S32 x, S32 y, MASK mask)
@@ -113,7 +115,6 @@ BOOL LLTextBox::handleMouseDown(S32 x, S32 y, MASK mask)
return handled;
}
-
BOOL LLTextBox::handleMouseUp(S32 x, S32 y, MASK mask)
{
BOOL handled = FALSE;
@@ -139,7 +140,7 @@ BOOL LLTextBox::handleMouseUp(S32 x, S32 y, MASK mask)
// If mouseup in the widget, it's been clicked
if (mClickedCallback)
{
- (*mClickedCallback)( mCallbackUserData );
+ mClickedCallback();
}
}
@@ -160,8 +161,15 @@ BOOL LLTextBox::handleHover(S32 x, S32 y, MASK mask)
void LLTextBox::setText(const LLStringExplicit& text)
{
- mText.assign(text);
- setLineLengths();
+ if(mWordWrap && !mDidWordWrap)
+ {
+ setWrappedText(text);
+ }
+ else
+ {
+ mText.assign(text);
+ setLineLengths();
+ }
}
void LLTextBox::setLineLengths()
@@ -193,7 +201,7 @@ void LLTextBox::setLineLengths()
void LLTextBox::setWrappedText(const LLStringExplicit& in_text, F32 max_width)
{
- if (max_width < 0.0)
+ if (max_width < 0.0f)
{
max_width = (F32)getRect().getWidth();
}
@@ -203,7 +211,8 @@ void LLTextBox::setWrappedText(const LLStringExplicit& in_text, F32 max_width)
LLWString::size_type cur = 0;;
LLWString::size_type len = wtext.size();
-
+ F32 line_height = mFontGL->getLineHeight();
+ S32 line_num = 1;
while (cur < len)
{
LLWString::size_type end = wtext.find('\n', cur);
@@ -221,6 +230,8 @@ void LLTextBox::setWrappedText(const LLStringExplicit& in_text, F32 max_width)
final_wtext.append(wtext, cur, useLen);
cur += useLen;
+ // not enough room to add any more characters
+ if (useLen == 0) break;
}
if (cur < len)
@@ -229,12 +240,22 @@ void LLTextBox::setWrappedText(const LLStringExplicit& in_text, F32 max_width)
{
cur += 1;
}
- final_wtext += '\n';
+ line_num +=1;
+ // Don't wrap the last line if the text is going to spill off
+ // the bottom of the rectangle. Assume we prefer to run off
+ // the right edge.
+ // *TODO: Is this the right behavior?
+ if((line_num-1)*line_height <= (F32)getRect().getHeight())
+ {
+ final_wtext += '\n';
+ }
}
}
-
+
+ mDidWordWrap = TRUE;
std::string final_text = wstring_to_utf8str(final_wtext);
setText(final_text);
+
}
S32 LLTextBox::getTextPixelWidth()
@@ -272,6 +293,11 @@ S32 LLTextBox::getTextPixelHeight()
return (S32)(num_lines * mFontGL->getLineHeight());
}
+void LLTextBox::setValue(const LLSD& value )
+{
+ mDidWordWrap = FALSE;
+ setText(value.asString());
+}
BOOL LLTextBox::setTextArg( const std::string& key, const LLStringExplicit& text )
{
@@ -289,8 +315,8 @@ void LLTextBox::draw()
if( mBorderDropShadowVisible )
{
- static LLColor4 color_drop_shadow = LLUI::sColorsGroup->getColor("ColorDropShadow");
- static S32 drop_shadow_tooltip = LLUI::sConfigGroup->getS32("DropShadowTooltip");
+ static LLUIColor color_drop_shadow = LLUIColorTable::instance().getColor("ColorDropShadow");
+ static LLUICachedControl<S32> drop_shadow_tooltip ("DropShadowTooltip", 0);
gl_drop_shadow(0, getRect().getHeight(), getRect().getWidth(), 0,
color_drop_shadow, drop_shadow_tooltip);
}
@@ -298,7 +324,7 @@ void LLTextBox::draw()
if (mBackgroundVisible)
{
LLRect r( 0, getRect().getHeight(), getRect().getWidth(), 0 );
- gl_rect_2d( r, mBackgroundColor );
+ gl_rect_2d( r, mBackgroundColor.get() );
}
S32 text_x = 0;
@@ -321,16 +347,16 @@ void LLTextBox::draw()
{
if(mHasHover)
{
- drawText( text_x, text_y, mHoverColor );
+ drawText( text_x, text_y, mHoverColor.get() );
}
else
{
- drawText( text_x, text_y, mTextColor );
+ drawText( text_x, text_y, mTextColor.get() );
}
}
else
{
- drawText( text_x, text_y, mDisabledColor );
+ drawText( text_x, text_y, mDisabledColor.get() );
}
if (sDebugRects)
@@ -338,6 +364,13 @@ void LLTextBox::draw()
drawDebugRect();
}
+ //// *HACK: also draw debug rectangles around currently-being-edited LLView, and any elements that are being highlighted by GUI preview code (see LLFloaterUIPreview)
+ //std::set<LLView*>::iterator iter = std::find(sPreviewHighlightedElements.begin(), sPreviewHighlightedElements.end(), this);
+ //if ((sEditingUI && this == sEditingUIView) || (iter != sPreviewHighlightedElements.end() && sDrawPreviewHighlights))
+ //{
+ // drawDebugRect();
+ //}
+
mHasHover = FALSE; // This is reset every frame.
}
@@ -354,8 +387,9 @@ void LLTextBox::drawText( S32 x, S32 y, const LLColor4& color )
{
mFontGL->render(mText.getWString(), 0, (F32)x, (F32)y, color,
mHAlign, mVAlign,
- mFontStyle,
- S32_MAX, getRect().getWidth(), NULL, TRUE, mUseEllipses);
+ 0,
+ mShadowType,
+ S32_MAX, getRect().getWidth(), NULL, mUseEllipses);
}
else
{
@@ -366,8 +400,9 @@ void LLTextBox::drawText( S32 x, S32 y, const LLColor4& color )
S32 line_length = *iter;
mFontGL->render(mText.getWString(), cur_pos, (F32)x, (F32)y, color,
mHAlign, mVAlign,
- mFontStyle,
- line_length, getRect().getWidth(), NULL, TRUE, mUseEllipses );
+ 0,
+ mShadowType,
+ line_length, getRect().getWidth(), NULL, mUseEllipses );
cur_pos += line_length + 1;
y -= llfloor(mFontGL->getLineHeight()) + mLineSpacing;
}
@@ -380,86 +415,3 @@ void LLTextBox::reshapeToFitText()
S32 height = getTextPixelHeight();
reshape( width + 2 * mHPad, height + 2 * mVPad );
}
-
-// virtual
-LLXMLNodePtr LLTextBox::getXML(bool save_children) const
-{
- LLXMLNodePtr node = LLUICtrl::getXML();
-
- // Attributes
- node->createChild("font", TRUE)->setStringValue(LLFontGL::nameFromFont(mFontGL));
- node->createChild("halign", TRUE)->setStringValue(LLFontGL::nameFromHAlign(mHAlign));
- addColorXML(node, mTextColor, "text_color", "LabelTextColor");
- addColorXML(node, mDisabledColor, "disabled_color", "LabelDisabledColor");
- addColorXML(node, mBackgroundColor, "bg_color", "DefaultBackgroundColor");
- addColorXML(node, mBorderColor, "border_color", "DefaultHighlightLight");
- node->createChild("bg_visible", TRUE)->setBoolValue(mBackgroundVisible);
- node->createChild("border_visible", TRUE)->setBoolValue(mBorderVisible);
- node->createChild("border_drop_shadow_visible", TRUE)->setBoolValue(mBorderDropShadowVisible);
- node->createChild("h_pad", TRUE)->setIntValue(mHPad);
- node->createChild("v_pad", TRUE)->setIntValue(mVPad);
-
- // Contents
- node->setStringValue(mText);
-
- return node;
-}
-
-// static
-LLView* LLTextBox::fromXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFactory *factory)
-{
- std::string name("text_box");
- node->getAttributeString("name", name);
- LLFontGL* font = LLView::selectFont(node);
-
- std::string text = node->getTextContents();
-
- LLTextBox* text_box = new LLTextBox(name,
- LLRect(),
- text,
- font,
- FALSE);
-
-
- LLFontGL::HAlign halign = LLView::selectFontHAlign(node);
- text_box->setHAlign(halign);
-
- text_box->initFromXML(node, parent);
-
- node->getAttributeS32("line_spacing", text_box->mLineSpacing);
-
- std::string font_style;
- if (node->getAttributeString("font-style", font_style))
- {
- text_box->mFontStyle = LLFontGL::getStyleFromString(font_style);
- }
-
- BOOL mouse_opaque = text_box->getMouseOpaque();
- if (node->getAttributeBOOL("mouse_opaque", mouse_opaque))
- {
- text_box->setMouseOpaque(mouse_opaque);
- }
-
- if(node->hasAttribute("text_color"))
- {
- LLColor4 color;
- LLUICtrlFactory::getAttributeColor(node, "text_color", color);
- text_box->setColor(color);
- }
-
- if(node->hasAttribute("hover_color"))
- {
- LLColor4 color;
- LLUICtrlFactory::getAttributeColor(node, "hover_color", color);
- text_box->setHoverColor(color);
- text_box->setHoverActive(true);
- }
-
- BOOL hover_active = FALSE;
- if(node->getAttributeBOOL("hover", hover_active))
- {
- text_box->setHoverActive(hover_active);
- }
-
- return text_box;
-}
diff --git a/indra/llui/lltextbox.h b/indra/llui/lltextbox.h
index 07a6aa3622..d807fe7639 100644
--- a/indra/llui/lltextbox.h
+++ b/indra/llui/lltextbox.h
@@ -43,27 +43,46 @@ class LLTextBox
: public LLUICtrl
{
public:
- // By default, follows top and left and is mouse-opaque.
- // If no text, text = name.
- // If no font, uses default system font.
- LLTextBox(const std::string& name, const LLRect& rect, const std::string& text,
- const LLFontGL* font = NULL, BOOL mouse_opaque = TRUE );
+
+ // *TODO: Add callback to Params
+ typedef boost::function<void (void)> callback_t;
+
+ struct Params : public LLInitParam::Block<Params, LLUICtrl::Params>
+ {
+ Optional<std::string> text;
- // Construct a textbox which handles word wrapping for us.
- LLTextBox(const std::string& name, const std::string& text, F32 max_width = 200,
- const LLFontGL* font = NULL, BOOL mouse_opaque = TRUE );
+ Optional<bool> highlight_on_hover,
+ border_visible,
+ border_drop_shadow_visible,
+ bg_visible,
+ use_ellipses,
+ word_wrap;
- // "Simple" constructors for text boxes that have the same name and label *TO BE DEPRECATED*
- LLTextBox(const std::string& name_and_label, const LLRect& rect);
+ Optional<LLFontGL::ShadowType> font_shadow;
- // Consolidate common member initialization
- // 20+ initializers times 3+ constructors is unmaintainable.
- void initDefaults();
+ Ignored drop_shadow_visible,
+ type,
+ length;
- virtual ~LLTextBox() {}
+ Optional<LLUIColor> text_color,
+ hover_color,
+ disabled_color,
+ background_color,
+ border_color;
+
+ Optional<S32> v_pad,
+ h_pad,
+ line_spacing;
- virtual LLXMLNodePtr getXML(bool save_children = true) const;
- static LLView* fromXML(LLXMLNodePtr node, LLView *parent, class LLUICtrlFactory *factory);
+ Params();
+ };
+
+protected:
+ LLTextBox(const Params&);
+ friend class LLUICtrlFactory;
+
+public:
+ virtual ~LLTextBox() {}
virtual void draw();
virtual void reshape(S32 width, S32 height, BOOL called_from_parent = TRUE);
@@ -81,18 +100,17 @@ public:
void setHoverActive( BOOL active ) { mHoverActive = active; }
void setText( const LLStringExplicit& text );
- void setWrappedText(const LLStringExplicit& text, F32 max_width = -1.0); // -1 means use existing control width
+ void setWrappedText(const LLStringExplicit& text, F32 max_width = -1.f); // -1 means use existing control width
void setUseEllipses( BOOL use_ellipses ) { mUseEllipses = use_ellipses; }
void setBackgroundVisible(BOOL visible) { mBackgroundVisible = visible; }
void setBorderVisible(BOOL visible) { mBorderVisible = visible; }
- void setFontStyle(U8 style) { mFontStyle = style; }
void setBorderDropshadowVisible(BOOL visible){ mBorderDropShadowVisible = visible; }
void setHPad(S32 pixels) { mHPad = pixels; }
void setVPad(S32 pixels) { mVPad = pixels; }
void setRightAlign() { mHAlign = LLFontGL::RIGHT; }
void setHAlign( LLFontGL::HAlign align ) { mHAlign = align; }
- void setClickedCallback( void (*cb)(void *data), void* data = NULL ){ mClickedCallback = cb; mCallbackUserData = data; } // mouse down and up within button
+ void setClickedCallback( boost::function<void (void*)> cb, void* userdata = NULL ){ mClickedCallback = boost::bind(cb, userdata); } // mouse down and up within button
const LLFontGL* getFont() const { return mFontGL; }
@@ -102,7 +120,7 @@ public:
S32 getTextPixelWidth();
S32 getTextPixelHeight();
- virtual void setValue(const LLSD& value ) { setText(value.asString()); }
+ virtual void setValue(const LLSD& value );
virtual LLSD getValue() const { return LLSD(getText()); }
virtual BOOL setTextArg( const std::string& key, const LLStringExplicit& text );
@@ -112,18 +130,20 @@ private:
LLUIString mText;
const LLFontGL* mFontGL;
- LLColor4 mTextColor;
- LLColor4 mDisabledColor;
- LLColor4 mBackgroundColor;
- LLColor4 mBorderColor;
- LLColor4 mHoverColor;
+ LLUIColor mTextColor;
+ LLUIColor mDisabledColor;
+ LLUIColor mBackgroundColor;
+ LLUIColor mBorderColor;
+ LLUIColor mHoverColor;
BOOL mHoverActive;
BOOL mHasHover;
BOOL mBackgroundVisible;
BOOL mBorderVisible;
+ BOOL mWordWrap;
+ BOOL mDidWordWrap;
- U8 mFontStyle; // style bit flags for font
+ LLFontGL::ShadowType mShadowType;
BOOL mBorderDropShadowVisible;
BOOL mUseEllipses;
@@ -135,8 +155,7 @@ private:
LLFontGL::VAlign mVAlign;
std::vector<S32> mLineLengthList;
- void (*mClickedCallback)(void* data );
- void* mCallbackUserData;
+ callback_t mClickedCallback;
};
#endif
diff --git a/indra/llui/lltexteditor.cpp b/indra/llui/lltexteditor.cpp
index 5e54c7a307..921041d17f 100644
--- a/indra/llui/lltexteditor.cpp
+++ b/indra/llui/lltexteditor.cpp
@@ -36,6 +36,7 @@
#include "lltexteditor.h"
+#include "llfontfreetype.h" // for LLFontFreetype::FIRST_CHAR
#include "llfontgl.h"
#include "llrender.h"
#include "llui.h"
@@ -45,7 +46,6 @@
#include "lltimer.h"
#include "llmath.h"
-#include "audioengine.h"
#include "llclipboard.h"
#include "llscrollbar.h"
#include "llstl.h"
@@ -55,54 +55,112 @@
#include "llundo.h"
#include "llviewborder.h"
#include "llcontrol.h"
-#include "llimagegl.h"
#include "llwindow.h"
#include "lltextparser.h"
+#include "llscrollcontainer.h"
+#include "llpanel.h"
+
#include <queue>
+#include "llcombobox.h"
//
// Globals
//
-static LLRegisterWidget<LLTextEditor> r("simple_text_editor");
-
-BOOL gDebugTextEditorTips = FALSE;
+static LLDefaultChildRegistry::Register<LLTextEditor> r("simple_text_editor");
//
// Constants
//
-const S32 UI_TEXTEDITOR_BUFFER_BLOCK_SIZE = 512;
-const S32 UI_TEXTEDITOR_BORDER = 1;
-const S32 UI_TEXTEDITOR_H_PAD = 4;
-const S32 UI_TEXTEDITOR_V_PAD_TOP = 4;
const S32 UI_TEXTEDITOR_LINE_NUMBER_MARGIN = 32;
const S32 UI_TEXTEDITOR_LINE_NUMBER_DIGITS = 4;
const F32 CURSOR_FLASH_DELAY = 1.0f; // in seconds
const S32 CURSOR_THICKNESS = 2;
const S32 SPACES_PER_TAB = 4;
-const F32 PREEDIT_MARKER_BRIGHTNESS = 0.4f;
-const S32 PREEDIT_MARKER_GAP = 1;
-const S32 PREEDIT_MARKER_POSITION = 2;
-const S32 PREEDIT_MARKER_THICKNESS = 1;
-const F32 PREEDIT_STANDOUT_BRIGHTNESS = 0.6f;
-const S32 PREEDIT_STANDOUT_GAP = 1;
-const S32 PREEDIT_STANDOUT_POSITION = 2;
-const S32 PREEDIT_STANDOUT_THICKNESS = 2;
+void (* LLTextEditor::sURLcallback)(const std::string&) = NULL;
+bool (* LLTextEditor::sSecondlifeURLcallback)(const std::string&) = NULL;
+bool (* LLTextEditor::sSecondlifeURLcallbackRightClick)(const std::string&) = NULL;
+
+// helper functors
+struct LLTextEditor::compare_bottom
+{
+ bool operator()(const S32& a, const LLTextEditor::line_info& b) const
+ {
+ return a > b.mBottom; // bottom of a is higher than bottom of b
+ }
-LLColor4 LLTextEditor::mLinkColor = LLColor4::blue;
-void (* LLTextEditor::mURLcallback)(const std::string&) = NULL;
-bool (* LLTextEditor::mSecondlifeURLcallback)(const std::string&) = NULL;
-bool (* LLTextEditor::mSecondlifeURLcallbackRightClick)(const std::string&) = NULL;
+ bool operator()(const LLTextEditor::line_info& a, const S32& b) const
+ {
+ return a.mBottom > b; // bottom of a is higher than bottom of b
+ }
+ bool operator()(const LLTextEditor::line_info& a, const LLTextEditor::line_info& b) const
+ {
+ return a.mBottom > b.mBottom; // bottom of a is higher than bottom of b
+ }
+
+};
+
+// helper functors
+struct LLTextEditor::compare_top
+{
+ bool operator()(const S32& a, const LLTextEditor::line_info& b) const
+ {
+ return a > b.mTop; // top of a is higher than top of b
+ }
+
+ bool operator()(const LLTextEditor::line_info& a, const S32& b) const
+ {
+ return a.mTop > b; // top of a is higher than top of b
+ }
+
+ bool operator()(const LLTextEditor::line_info& a, const LLTextEditor::line_info& b) const
+ {
+ return a.mTop > b.mTop; // top of a is higher than top of b
+ }
+};
+
+struct LLTextEditor::line_end_compare
+{
+ bool operator()(const S32& pos, const LLTextEditor::line_info& info) const
+ {
+ return (pos < info.mDocIndexEnd);
+ }
+
+ bool operator()(const LLTextEditor::line_info& info, const S32& pos) const
+ {
+ return (info.mDocIndexEnd < pos);
+ }
+
+ bool operator()(const LLTextEditor::line_info& a, const LLTextEditor::line_info& b) const
+ {
+ return (a.mDocIndexEnd < b.mDocIndexEnd);
+ }
+
+};
+
+//
+// DocumentPanel
+//
+
+class DocumentPanel : public LLPanel
+{
+public:
+ DocumentPanel(const Params&);
+};
+
+DocumentPanel::DocumentPanel(const Params& p)
+: LLPanel(p)
+{}
///////////////////////////////////////////////////////////////////
class LLTextEditor::LLTextCmdInsert : public LLTextEditor::LLTextCmd
{
public:
- LLTextCmdInsert(S32 pos, BOOL group_with_next, const LLWString &ws)
- : LLTextCmd(pos, group_with_next), mWString(ws)
+ LLTextCmdInsert(S32 pos, BOOL group_with_next, const LLWString &ws, LLTextSegmentPtr segment)
+ : LLTextCmd(pos, group_with_next, segment), mWString(ws)
{
}
virtual ~LLTextCmdInsert() {}
@@ -132,8 +190,8 @@ private:
class LLTextEditor::LLTextCmdAddChar : public LLTextEditor::LLTextCmd
{
public:
- LLTextCmdAddChar( S32 pos, BOOL group_with_next, llwchar wc)
- : LLTextCmd(pos, group_with_next), mWString(1, wc), mBlockExtensions(FALSE)
+ LLTextCmdAddChar( S32 pos, BOOL group_with_next, llwchar wc, LLTextSegmentPtr segment)
+ : LLTextCmd(pos, group_with_next, segment), mWString(1, wc), mBlockExtensions(FALSE)
{
}
virtual void blockExtensions()
@@ -142,6 +200,9 @@ public:
}
virtual BOOL canExtend(S32 pos) const
{
+ // cannot extend text with custom segments
+ if (!mSegments.empty()) return FALSE;
+
return !mBlockExtensions && (pos == getPosition() + (S32)mWString.length());
}
virtual BOOL execute( LLTextEditor* editor, S32* delta )
@@ -216,9 +277,10 @@ private:
class LLTextEditor::LLTextCmdRemove : public LLTextEditor::LLTextCmd
{
public:
- LLTextCmdRemove( S32 pos, BOOL group_with_next, S32 len ) :
+ LLTextCmdRemove( S32 pos, BOOL group_with_next, S32 len, segment_vec_t& segments ) :
LLTextCmd(pos, group_with_next), mLen(len)
{
+ std::swap(mSegments, segments);
}
virtual BOOL execute( LLTextEditor* editor, S32* delta )
{
@@ -228,7 +290,7 @@ public:
}
virtual S32 undo( LLTextEditor* editor )
{
- insert(editor, getPosition(), mWString );
+ insert(editor, getPosition(), mWString);
return getPosition() + mWString.length();
}
virtual S32 redo( LLTextEditor* editor )
@@ -243,18 +305,35 @@ private:
///////////////////////////////////////////////////////////////////
-
-LLTextEditor::LLTextEditor(
- const std::string& name,
- const LLRect& rect,
- S32 max_length, // In bytes
- const std::string &default_text,
- const LLFontGL* font,
- BOOL allow_embedded_items)
- :
- LLUICtrl( name, rect, TRUE, NULL, NULL, FOLLOWS_TOP | FOLLOWS_LEFT ),
- mTextIsUpToDate(TRUE),
- mMaxTextByteLength( max_length ),
+LLTextEditor::Params::Params()
+: default_text("default_text"),
+ max_text_length("max_length", 255),
+ read_only("read_only", false),
+ embedded_items("embedded_items", false),
+ hide_scrollbar("hide_scrollbar"),
+ hide_border("hide_border", false),
+ word_wrap("word_wrap", false),
+ ignore_tab("ignore_tab", true),
+ track_bottom("track_bottom", false),
+ handle_edit_keys_directly("handle_edit_keys_directly", false),
+ show_line_numbers("show_line_numbers", false),
+ cursor_color("cursor_color"),
+ default_color("default_color"),
+ text_color("text_color"),
+ text_readonly_color("text_readonly_color"),
+ bg_readonly_color("bg_readonly_color"),
+ bg_writeable_color("bg_writeable_color"),
+ bg_focus_color("bg_focus_color"),
+ link_color("link_color"),
+ commit_on_focus_lost("commit_on_focus_lost", false),
+ length("length"), // ignored
+ type("type"), // ignored
+ is_unicode("is_unicode")// ignored
+{}
+
+LLTextEditor::LLTextEditor(const LLTextEditor::Params& p)
+ : LLUICtrl(p, LLTextViewModelPtr(new LLTextViewModel)),
+ mMaxTextByteLength( p.max_text_length ),
mBaseDocIsPristine(TRUE),
mPristineCmd( NULL ),
mLastCmd( NULL ),
@@ -262,90 +341,108 @@ LLTextEditor::LLTextEditor(
mIsSelecting( FALSE ),
mSelectionStart( 0 ),
mSelectionEnd( 0 ),
- mScrolledToBottom( TRUE ),
- mOnScrollEndCallback( NULL ),
mOnScrollEndData( NULL ),
- mCursorColor( LLUI::sColorsGroup->getColor( "TextCursorColor" ) ),
- mFgColor( LLUI::sColorsGroup->getColor( "TextFgColor" ) ),
- mDefaultColor( LLUI::sColorsGroup->getColor( "TextDefaultColor" ) ),
- mReadOnlyFgColor( LLUI::sColorsGroup->getColor( "TextFgReadOnlyColor" ) ),
- mWriteableBgColor( LLUI::sColorsGroup->getColor( "TextBgWriteableColor" ) ),
- mReadOnlyBgColor( LLUI::sColorsGroup->getColor( "TextBgReadOnlyColor" ) ),
- mFocusBgColor( LLUI::sColorsGroup->getColor( "TextBgFocusColor" ) ),
- mReadOnly(FALSE),
- mWordWrap( FALSE ),
- mShowLineNumbers ( FALSE ),
- mTabsToNextField( TRUE ),
- mCommitOnFocusLost( FALSE ),
- mHideScrollbarForShortDocs( FALSE ),
- mTakesNonScrollClicks( TRUE ),
- mTrackBottom( FALSE ),
- mAllowEmbeddedItems( allow_embedded_items ),
- mAcceptCallingCardNames(FALSE),
- mHandleEditKeysDirectly( FALSE ),
+ mCursorColor( p.cursor_color() ),
+ mFgColor( p.text_color() ),
+ mDefaultColor( p.default_color() ),
+ mReadOnlyFgColor( p.text_readonly_color() ),
+ mWriteableBgColor( p.bg_writeable_color() ),
+ mReadOnlyBgColor( p.bg_readonly_color() ),
+ mFocusBgColor( p.bg_focus_color() ),
+ mLinkColor( p.link_color() ),
+ mReadOnly(p.read_only),
+ mWordWrap( p.word_wrap ),
+ mShowLineNumbers ( p.show_line_numbers ),
+ mCommitOnFocusLost( p.commit_on_focus_lost),
+ mTrackBottom( p.track_bottom ),
+ mAllowEmbeddedItems( p.embedded_items ),
+ mHandleEditKeysDirectly( p.handle_edit_keys_directly ),
mMouseDownX(0),
mMouseDownY(0),
mLastSelectionX(-1),
- mLastSelectionY(-1),
mReflowNeeded(FALSE),
- mScrollNeeded(FALSE)
+ mScrollNeeded(FALSE),
+ mLastSelectionY(-1),
+ mParseHTML(FALSE),
+ mParseHighlights(FALSE),
+ mTabsToNextField(p.ignore_tab),
+ mDefaultFont(p.font),
+ mScrollIndex(-1)
{
+ static LLUICachedControl<S32> scrollbar_size ("UIScrollbarSize", 0);
+
mSourceID.generate();
// reset desired x cursor position
mDesiredXPixel = -1;
- if (font)
- {
- mGLFont = font;
- }
- else
- {
- mGLFont = LLFontGL::getFontSansSerif();
- }
+ LLScrollContainer::Params scroll_params;
+ scroll_params.name = "text scroller";
+ scroll_params.rect = getLocalRect();
+ scroll_params.follows.flags = FOLLOWS_ALL;
+ scroll_params.is_opaque = false;
+ scroll_params.mouse_opaque = false;
+ scroll_params.min_auto_scroll_rate = 200;
+ scroll_params.max_auto_scroll_rate = 800;
+ mScroller = LLUICtrlFactory::create<LLScrollContainer>(scroll_params);
+ addChild(mScroller);
+
+ LLPanel::Params panel_params;
+ panel_params.name = "text_contents";
+ panel_params.rect = LLRect(0, 500, 500, 0);
+ panel_params.background_visible = true;
+ panel_params.background_opaque = true;
+ panel_params.mouse_opaque = false;
+
+ mDocumentPanel = LLUICtrlFactory::create<DocumentPanel>(panel_params);
+ mScroller->addChild(mDocumentPanel);
updateTextRect();
- S32 line_height = llround( mGLFont->getLineHeight() );
- S32 page_size = mTextRect.getHeight() / line_height;
-
- // Init the scrollbar
- LLRect scroll_rect;
- scroll_rect.setOriginAndSize(
- getRect().getWidth() - SCROLLBAR_SIZE,
- 1,
- SCROLLBAR_SIZE,
- getRect().getHeight() - 1);
- S32 lines_in_doc = getLineCount();
- mScrollbar = new LLScrollbar( std::string("Scrollbar"), scroll_rect,
- LLScrollbar::VERTICAL,
- lines_in_doc,
- 0,
- page_size,
- NULL, this );
- mScrollbar->setFollowsRight();
- mScrollbar->setFollowsTop();
- mScrollbar->setFollowsBottom();
- mScrollbar->setEnabled( TRUE );
- mScrollbar->setVisible( TRUE );
- mScrollbar->setOnScrollEndCallback(mOnScrollEndCallback, mOnScrollEndData);
- addChild(mScrollbar);
-
- mBorder = new LLViewBorder( std::string("text ed border"), LLRect(0, getRect().getHeight(), getRect().getWidth(), 0), LLViewBorder::BEVEL_IN, LLViewBorder::STYLE_LINE, UI_TEXTEDITOR_BORDER );
+ static LLUICachedControl<S32> text_editor_border ("UITextEditorBorder", 0);
+ LLViewBorder::Params params;
+ params.name = "text ed border";
+ params.rect = getLocalRect();
+ params.bevel_style = LLViewBorder::BEVEL_IN;
+ params.border_thickness = text_editor_border;
+ mBorder = LLUICtrlFactory::create<LLViewBorder> (params);
addChild( mBorder );
+ mBorder->setVisible(!p.hide_border);
- appendText(default_text, FALSE, FALSE);
-
- resetDirty(); // Update saved text state
+ createDefaultSegment();
+
+ appendText(p.default_text, FALSE, FALSE);
- mParseHTML=FALSE;
mHTML.clear();
}
+void LLTextEditor::initFromParams( const LLTextEditor::Params& p)
+{
+ resetDirty(); // Update saved text state
+ LLUICtrl::initFromParams(p);
+ // HACK: work around enabled == readonly design bug -- RN
+ // setEnabled will modify our read only status, so do this after
+ // LLUICtrl::initFromParams
+ if (p.read_only.isProvided())
+ {
+ mReadOnly = p.read_only;
+ }
+
+ if (p.commit_on_focus_lost.isProvided())
+ {
+ mCommitOnFocusLost = p.commit_on_focus_lost;
+ }
+
+ updateSegments();
+ updateAllowingLanguageInput();
+
+ // HACK: text editors always need to be enabled so that we can scroll
+ LLView::setEnabled(true);
+}
LLTextEditor::~LLTextEditor()
{
- gFocusMgr.releaseFocusIfNeeded( this ); // calls onCommit()
+ gFocusMgr.releaseFocusIfNeeded( this ); // calls onCommit() while LLTextEditor still valid
// Route menu back to the default
if( gEditMenuHandler == this )
@@ -355,130 +452,191 @@ LLTextEditor::~LLTextEditor()
// Scrollbar is deleted by LLView
mHoverSegment = NULL;
- std::for_each(mSegments.begin(), mSegments.end(), DeletePointer());
-
std::for_each(mUndoStack.begin(), mUndoStack.end(), DeletePointer());
}
-void LLTextEditor::setTrackColor( const LLColor4& color )
-{
- mScrollbar->setTrackColor(color);
-}
-
-void LLTextEditor::setThumbColor( const LLColor4& color )
-{
- mScrollbar->setThumbColor(color);
+LLTextViewModel* LLTextEditor::getViewModel() const
+{
+ return (LLTextViewModel*)mViewModel.get();
}
-void LLTextEditor::setHighlightColor( const LLColor4& color )
-{
- mScrollbar->setHighlightColor(color);
-}
+static LLFastTimer::DeclareTimer FTM_TEXT_REFLOW ("Text Reflow");
+void LLTextEditor::reflow(S32 start_index)
+{
+ if (!mReflowNeeded) return;
-void LLTextEditor::setShadowColor( const LLColor4& color )
-{
- mScrollbar->setShadowColor(color);
-}
+ LLFastTimer ft(FTM_TEXT_REFLOW);
+ static LLUICachedControl<S32> texteditor_vpad_top ("UITextEditorVPadTop", 0);
-void LLTextEditor::updateLineStartList(S32 startpos)
-{
updateSegments();
-
- bindEmbeddedChars(mGLFont);
-
- S32 seg_num = mSegments.size();
- S32 seg_idx = 0;
- S32 seg_offset = 0;
- if (!mLineStartList.empty())
+ while(mReflowNeeded)
{
- getSegmentAndOffset(startpos, &seg_idx, &seg_offset);
- line_info t(seg_idx, seg_offset);
- line_list_t::iterator iter = std::upper_bound(mLineStartList.begin(), mLineStartList.end(), t, line_info_compare());
- if (iter != mLineStartList.begin()) --iter;
- seg_idx = iter->mSegment;
- seg_offset = iter->mOffset;
- mLineStartList.erase(iter, mLineStartList.end());
- }
-
- while( seg_idx < seg_num )
- {
- mLineStartList.push_back(line_info(seg_idx,seg_offset));
- BOOL line_ended = FALSE;
- S32 start_x = mShowLineNumbers ? UI_TEXTEDITOR_LINE_NUMBER_MARGIN : 0;
- S32 line_width = start_x;
- while(!line_ended && seg_idx < seg_num)
+ bool scrolled_to_bottom = mScroller->isAtBottom();
+ mReflowNeeded = FALSE;
+
+ LLRect old_cursor_rect = getLocalRectFromDocIndex(mCursorPos);
+ bool follow_selection = mTextRect.overlaps(old_cursor_rect); // cursor is visible
+ S32 first_line = getFirstVisibleLine();
+ // if scroll anchor not on first line, update it to first character of first line
+ if (!mLineInfoList.empty()
+ && (mScrollIndex < mLineInfoList[first_line].mDocIndexStart
+ || mScrollIndex >= mLineInfoList[first_line].mDocIndexEnd))
+ {
+ mScrollIndex = mLineInfoList[first_line].mDocIndexStart;
+ }
+ LLRect first_char_rect = getLocalRectFromDocIndex(mScrollIndex);
+ //first_char_rect.intersectWith(mTextRect);
+
+ S32 cur_top = -texteditor_vpad_top;
+
+ if (getLength())
{
- LLTextSegment* segment = mSegments[seg_idx];
- S32 start_idx = segment->getStart() + seg_offset;
- S32 end_idx = start_idx;
- while (end_idx < segment->getEnd() && mWText[end_idx] != '\n')
+ segment_set_t::iterator seg_iter = mSegments.begin();
+ S32 seg_offset = 0;
+ S32 line_start_index = 0;
+ S32 text_width = mTextRect.getWidth(); // optionally reserve room for margin
+ S32 remaining_pixels = text_width;
+ LLWString text(getWText());
+ S32 line_count = 0;
+
+ // find and erase line info structs starting at start_index and going to end of document
+ if (!mLineInfoList.empty())
{
- end_idx++;
+ // find first element whose end comes after start_index
+ line_list_t::iterator iter = std::upper_bound(mLineInfoList.begin(), mLineInfoList.end(), start_index, line_end_compare());
+ line_start_index = iter->mDocIndexStart;
+ line_count = iter->mLineNum;
+ getSegmentAndOffset(iter->mDocIndexStart, &seg_iter, &seg_offset);
+ mLineInfoList.erase(iter, mLineInfoList.end());
}
- if (start_idx == end_idx)
+
+ // reserve enough space for line numbers
+ S32 line_height = mShowLineNumbers ? (S32)(LLFontGL::getFontMonospace()->getLineHeight()) : 0;
+
+ while(seg_iter != mSegments.end())
{
- if (end_idx >= segment->getEnd())
- {
- // empty segment
- seg_idx++;
- seg_offset = 0;
- }
- else
- {
- // empty line
- line_ended = TRUE;
- seg_offset++;
- }
- }
- else
- {
- const llwchar* str = mWText.c_str() + start_idx;
- S32 drawn = mGLFont->maxDrawableChars(str, (F32)abs(mTextRect.getWidth()) - line_width,
- end_idx - start_idx, mWordWrap, mAllowEmbeddedItems );
- if( 0 == drawn && line_width == start_x)
+ LLTextSegmentPtr segment = *seg_iter;
+
+ // track maximum height of any segment on this line
+ line_height = llmax(line_height, segment->getMaxHeight());
+ S32 cur_index = segment->getStart() + seg_offset;
+ // find run of text from this segment that we can display on one line
+ S32 end_index = cur_index;
+ while(end_index < segment->getEnd() && text[end_index] != '\n')
{
- // If at the beginning of a line, draw at least one character, even if it doesn't all fit.
- drawn = 1;
+ ++end_index;
}
- seg_offset += drawn;
- line_width += mGLFont->getWidth(str, 0, drawn, mAllowEmbeddedItems);
- end_idx = segment->getStart() + seg_offset;
- if (end_idx < segment->getEnd())
+
+ // ask segment how many character fit in remaining space
+ S32 max_characters = end_index - cur_index;
+ S32 character_count = segment->getNumChars(llmax(0, remaining_pixels), seg_offset, cur_index - line_start_index, max_characters);
+
+ seg_offset += character_count;
+
+ S32 last_segment_char_on_line = segment->getStart() + seg_offset;
+
+ // if we didn't finish the current segment...
+ if (last_segment_char_on_line < segment->getEnd())
{
- line_ended = TRUE;
- if (mWText[end_idx] == '\n')
+ // set up index for next line
+ // ...skip newline, we don't want to draw
+ S32 next_line_count = line_count;
+ if (text[last_segment_char_on_line] == '\n')
{
- seg_offset++; // skip newline
+ seg_offset++;
+ last_segment_char_on_line++;
+ next_line_count++;
}
+
+ // add line info and keep going
+ mLineInfoList.push_back(line_info(line_start_index, last_segment_char_on_line, cur_top, cur_top - line_height, line_count));
+
+ line_start_index = segment->getStart() + seg_offset;
+ cur_top -= line_height;
+ remaining_pixels = text_width;
+ line_height = 0;
+ line_count = next_line_count;
}
+ // ...just consumed last segment..
+ else if (++segment_set_t::iterator(seg_iter) == mSegments.end())
+ {
+ mLineInfoList.push_back(line_info(line_start_index, last_segment_char_on_line, cur_top, cur_top - line_height, line_count));
+ cur_top -= line_height;
+ break;
+ }
+ // finished a segment and there are segments remaining on this line
else
{
- // finished with segment
- seg_idx++;
+ // subtract pixels used and increment segment
+ remaining_pixels -= segment->getWidth(seg_offset, character_count);
+ ++seg_iter;
seg_offset = 0;
}
}
}
- }
-
- unbindEmbeddedChars(mGLFont);
- mScrollbar->setDocSize( getLineCount() );
+ // change mDocumentPanel document size to accomodate reflowed text
+ LLRect document_rect;
+ document_rect.setOriginAndSize(1, 1,
+ mScroller->getContentWindowRect().getWidth(),
+ llmax(mScroller->getContentWindowRect().getHeight(), -cur_top));
+ mDocumentPanel->setShape(document_rect);
- if (mHideScrollbarForShortDocs)
- {
- BOOL short_doc = (mScrollbar->getDocSize() <= mScrollbar->getPageSize());
- mScrollbar->setVisible(!short_doc);
- }
+ // after making document big enough to hold all the text, move the text to fit in the document
+ if (!mLineInfoList.empty())
+ {
+ S32 delta_pos = mDocumentPanel->getRect().getHeight() - mLineInfoList.begin()->mTop - texteditor_vpad_top;
+ // move line segments to fit new document rect
+ for (line_list_t::iterator it = mLineInfoList.begin(); it != mLineInfoList.end(); ++it)
+ {
+ it->mTop += delta_pos;
+ it->mBottom += delta_pos;
+ }
+ }
- // if scrolled to bottom, stay at bottom
- // unless user is selecting text
- // do this after updating page size
- if (mScrolledToBottom && mTrackBottom && !hasMouseCapture())
- {
- endOfDoc();
+ // calculate visible region for diplaying text
+ updateTextRect();
+
+ for (segment_set_t::iterator segment_it = mSegments.begin();
+ segment_it != mSegments.end();
+ ++segment_it)
+ {
+ LLTextSegmentPtr segmentp = *segment_it;
+ segmentp->updateLayout(*this);
+
+ }
+
+ // apply scroll constraints after reflowing text
+ if (!hasMouseCapture())
+ {
+ LLRect visible_content_rect = mScroller->getVisibleContentRect();
+ if (scrolled_to_bottom && mTrackBottom)
+ {
+ // keep bottom of text buffer visible
+ endOfDoc();
+ }
+ else if (hasSelection() && follow_selection)
+ {
+ // keep cursor in same vertical position on screen when selecting text
+ LLRect new_cursor_rect_doc = getLocalRectFromDocIndex(mCursorPos);
+ new_cursor_rect_doc.translate(visible_content_rect.mLeft, visible_content_rect.mBottom);
+ mScroller->scrollToShowRect(new_cursor_rect_doc, old_cursor_rect);
+ //llassert_always(getLocalRectFromDocIndex(mCursorPos).mBottom == old_cursor_rect.mBottom);
+ }
+ else
+ {
+ // keep first line of text visible
+ LLRect new_first_char_rect = getLocalRectFromDocIndex(mScrollIndex);
+ new_first_char_rect.translate(visible_content_rect.mLeft, visible_content_rect.mBottom);
+ mScroller->scrollToShowRect(new_first_char_rect, first_char_rect);
+ //llassert_always(getLocalRectFromDocIndex(mScrollIndex).mBottom == first_char_rect.mBottom);
+ }
+ }
}
+
+ // reset desired x cursor position
+ updateCursorXPos();
}
////////////////////////////////////////////////////////////
@@ -490,17 +648,17 @@ BOOL LLTextEditor::truncate()
BOOL did_truncate = FALSE;
// First rough check - if we're less than 1/4th the size, we're OK
- if (mWText.size() >= (size_t) (mMaxTextByteLength / 4))
+ if (getLength() >= S32(mMaxTextByteLength / 4))
{
// Have to check actual byte size
- S32 utf8_byte_size = wstring_utf8_length( mWText );
+ LLWString text(getWText());
+ S32 utf8_byte_size = wstring_utf8_length(text);
if ( utf8_byte_size > mMaxTextByteLength )
{
// Truncate safely in UTF-8
- std::string temp_utf8_text = wstring_to_utf8str( mWText );
+ std::string temp_utf8_text = wstring_to_utf8str(text);
temp_utf8_text = utf8str_truncate( temp_utf8_text, mMaxTextByteLength );
- mWText = utf8str_to_wstring( temp_utf8_text );
- mTextIsUpToDate = FALSE;
+ getViewModel()->setDisplay(utf8str_to_wstring( temp_utf8_text ));
did_truncate = TRUE;
}
}
@@ -508,40 +666,53 @@ BOOL LLTextEditor::truncate()
return did_truncate;
}
+void LLTextEditor::clearSegments()
+{
+ mHoverSegment = NULL;
+ mSegments.clear();
+}
+
void LLTextEditor::setText(const LLStringExplicit &utf8str)
{
+ clearSegments();
+
// LLStringUtil::removeCRLF(utf8str);
- mUTF8Text = utf8str_removeCRLF(utf8str);
- // mUTF8Text = utf8str;
- mWText = utf8str_to_wstring(mUTF8Text);
- mTextIsUpToDate = TRUE;
+ getViewModel()->setValue(utf8str_removeCRLF(utf8str));
truncate();
blockUndo();
- setCursorPos(0);
+ createDefaultSegment();
+
+ startOfDoc();
deselect();
needsReflow();
resetDirty();
+
+ onValueChange(0, getLength());
}
void LLTextEditor::setWText(const LLWString &wtext)
{
- mWText = wtext;
- mUTF8Text.clear();
- mTextIsUpToDate = FALSE;
+ clearSegments();
+
+ getViewModel()->setDisplay(wtext);
truncate();
blockUndo();
- setCursorPos(0);
+ createDefaultSegment();
+
+ startOfDoc();
deselect();
needsReflow();
resetDirty();
+
+ onValueChange(0, getLength());
}
// virtual
@@ -550,56 +721,13 @@ void LLTextEditor::setValue(const LLSD& value)
setText(value.asString());
}
-const std::string& LLTextEditor::getText() const
+std::string LLTextEditor::getText() const
{
- if (!mTextIsUpToDate)
+ if (mAllowEmbeddedItems)
{
- if (mAllowEmbeddedItems)
- {
- llwarns << "getText() called on text with embedded items (not supported)" << llendl;
- }
- mUTF8Text = wstring_to_utf8str(mWText);
- mTextIsUpToDate = TRUE;
- }
- return mUTF8Text;
-}
-
-// virtual
-LLSD LLTextEditor::getValue() const
-{
- return LLSD(getText());
-}
-
-void LLTextEditor::setWordWrap(BOOL b)
-{
- mWordWrap = b;
-
- setCursorPos(0);
- deselect();
-
- needsReflow();
-}
-
-
-void LLTextEditor::setBorderVisible(BOOL b)
-{
- mBorder->setVisible(b);
-}
-
-BOOL LLTextEditor::isBorderVisible() const
-{
- return mBorder->getVisible();
-}
-
-void LLTextEditor::setHideScrollbarForShortDocs(BOOL b)
-{
- mHideScrollbarForShortDocs = b;
-
- if (mHideScrollbarForShortDocs)
- {
- BOOL short_doc = (mScrollbar->getDocSize() <= mScrollbar->getPageSize());
- mScrollbar->setVisible(!short_doc);
+ llwarns << "getText() called on text with embedded items (not supported)" << llendl;
}
+ return getViewModel()->getValue().asString();
}
void LLTextEditor::selectNext(const std::string& search_text_in, BOOL case_insensitive, BOOL wrap)
@@ -624,7 +752,7 @@ void LLTextEditor::selectNext(const std::string& search_text_in, BOOL case_insen
if (selected_text == search_text)
{
// We already have this word selected, we are searching for the next.
- mCursorPos += search_text.size();
+ setCursorPos(mCursorPos + search_text.size());
}
}
@@ -687,9 +815,7 @@ BOOL LLTextEditor::replaceText(const std::string& search_text_in, const std::str
void LLTextEditor::replaceTextAll(const std::string& search_text, const std::string& replace_text, BOOL case_insensitive)
{
- S32 cur_pos = mScrollbar->getDocPos();
-
- setCursorPos(0);
+ startOfDoc();
selectNext(search_text, case_insensitive, FALSE);
BOOL replaced = TRUE;
@@ -697,24 +823,22 @@ void LLTextEditor::replaceTextAll(const std::string& search_text, const std::str
{
replaced = replaceText(search_text,replace_text, case_insensitive, FALSE);
}
-
- mScrollbar->setDocPos(cur_pos);
}
// Picks a new cursor position based on the screen size of text being drawn.
-void LLTextEditor::setCursorAtLocalPos( S32 local_x, S32 local_y, BOOL round )
+void LLTextEditor::setCursorAtLocalPos( S32 local_x, S32 local_y, bool round, bool keep_cursor_offset )
{
- setCursorPos(getCursorPosFromLocalCoord(local_x, local_y, round));
+ setCursorPos(getDocIndexFromLocalCoord(local_x, local_y, round), keep_cursor_offset);
}
S32 LLTextEditor::prevWordPos(S32 cursorPos) const
{
- const LLWString& wtext = mWText;
+ LLWString wtext(getWText());
while( (cursorPos > 0) && (wtext[cursorPos-1] == ' ') )
{
cursorPos--;
}
- while( (cursorPos > 0) && isPartOfWord( wtext[cursorPos-1] ) )
+ while( (cursorPos > 0) && LLWStringUtil::isPartOfWord( wtext[cursorPos-1] ) )
{
cursorPos--;
}
@@ -723,8 +847,8 @@ S32 LLTextEditor::prevWordPos(S32 cursorPos) const
S32 LLTextEditor::nextWordPos(S32 cursorPos) const
{
- const LLWString& wtext = mWText;
- while( (cursorPos < getLength()) && isPartOfWord( wtext[cursorPos] ) )
+ LLWString wtext(getWText());
+ while( (cursorPos < getLength()) && LLWStringUtil::isPartOfWord( wtext[cursorPos] ) )
{
cursorPos++;
}
@@ -744,154 +868,316 @@ S32 LLTextEditor::getLineStart( S32 line ) const
}
line = llclamp(line, 0, num_lines-1);
- S32 segidx = mLineStartList[line].mSegment;
- S32 segoffset = mLineStartList[line].mOffset;
- LLTextSegment* seg = mSegments[segidx];
- S32 res = seg->getStart() + segoffset;
- if (res > seg->getEnd()) llerrs << "wtf" << llendl;
- return res;
+ return mLineInfoList[line].mDocIndexStart;
+}
+
+S32 LLTextEditor::getLineHeight( S32 line ) const
+{
+ S32 num_lines = getLineCount();
+ if (num_lines == 0)
+ {
+ return 0;
+ }
+
+ line = llclamp(line, 0, num_lines-1);
+ return mLineInfoList[line].mTop - mLineInfoList[line].mBottom;
}
// Given an offset into text (pos), find the corresponding line (from the start of the doc) and an offset into the line.
-void LLTextEditor::getLineAndOffset( S32 startpos, S32* linep, S32* offsetp ) const
+void LLTextEditor::getLineAndOffset( S32 startpos, S32* linep, S32* offsetp, bool include_wordwrap) const
{
- if (mLineStartList.empty())
+ if (mLineInfoList.empty())
{
*linep = 0;
*offsetp = startpos;
}
else
{
- S32 seg_idx, seg_offset;
- getSegmentAndOffset( startpos, &seg_idx, &seg_offset );
+ line_list_t::const_iterator iter = std::upper_bound(mLineInfoList.begin(), mLineInfoList.end(), startpos, line_end_compare());
+ if (include_wordwrap)
+ {
+ *linep = iter - mLineInfoList.begin();
+ }
+ else
+ {
+ if (iter == mLineInfoList.end())
+ {
+ *linep = mLineInfoList.back().mLineNum;
+ }
+ else
+ {
+ *linep = iter->mLineNum;
+ }
+ }
+ *offsetp = startpos - iter->mDocIndexStart;
+ }
+}
- line_info tline(seg_idx, seg_offset);
- line_list_t::const_iterator iter = std::upper_bound(mLineStartList.begin(), mLineStartList.end(), tline, line_info_compare());
- if (iter != mLineStartList.begin()) --iter;
- *linep = iter - mLineStartList.begin();
- S32 line_start = mSegments[iter->mSegment]->getStart() + iter->mOffset;
- *offsetp = startpos - line_start;
+void LLTextEditor::getSegmentAndOffset( S32 startpos, segment_set_t::const_iterator* seg_iter, S32* offsetp ) const
+{
+ *seg_iter = getSegIterContaining(startpos);
+ if (*seg_iter == mSegments.end())
+ {
+ *offsetp = 0;
+ }
+ else
+ {
+ *offsetp = startpos - (**seg_iter)->getStart();
}
}
-void LLTextEditor::getSegmentAndOffset( S32 startpos, S32* segidxp, S32* offsetp ) const
+void LLTextEditor::getSegmentAndOffset( S32 startpos, segment_set_t::iterator* seg_iter, S32* offsetp )
{
- if (mSegments.empty())
+ *seg_iter = getSegIterContaining(startpos);
+ if (*seg_iter == mSegments.end())
{
- *segidxp = -1;
- *offsetp = startpos;
+ *offsetp = 0;
+ }
+ else
+ {
+ *offsetp = startpos - (**seg_iter)->getStart();
}
-
- LLTextSegment tseg(startpos);
- segment_list_t::const_iterator seg_iter;
- seg_iter = std::upper_bound(mSegments.begin(), mSegments.end(), &tseg, LLTextSegment::compare());
- if (seg_iter != mSegments.begin()) --seg_iter;
- *segidxp = seg_iter - mSegments.begin();
- *offsetp = startpos - (*seg_iter)->getStart();
}
-const LLTextSegment* LLTextEditor::getPreviousSegment() const
+const LLTextSegmentPtr LLTextEditor::getPreviousSegment() const
{
// find segment index at character to left of cursor (or rightmost edge of selection)
- S32 idx = llmax(0, getSegmentIdxAtOffset(mCursorPos) - 1);
- return idx >= 0 ? mSegments[idx] : NULL;
+ segment_set_t::const_iterator it = mSegments.lower_bound(new LLIndexSegment(mCursorPos));
+
+ if (it != mSegments.end())
+ {
+ return *it;
+ }
+ else
+ {
+ return LLTextSegmentPtr();
+ }
}
-void LLTextEditor::getSelectedSegments(std::vector<const LLTextSegment*>& segments) const
+void LLTextEditor::getSelectedSegments(LLTextEditor::segment_vec_t& segments) const
{
S32 left = hasSelection() ? llmin(mSelectionStart, mSelectionEnd) : mCursorPos;
S32 right = hasSelection() ? llmax(mSelectionStart, mSelectionEnd) : mCursorPos;
- S32 first_idx = llmax(0, getSegmentIdxAtOffset(left));
- S32 last_idx = llmax(0, first_idx, getSegmentIdxAtOffset(right));
- for (S32 idx = first_idx; idx <= last_idx; ++idx)
- {
- segments.push_back(mSegments[idx]);
- }
+ return getSegmentsInRange(segments, left, right, true);
}
-S32 LLTextEditor::getCursorPosFromLocalCoord( S32 local_x, S32 local_y, BOOL round ) const
+void LLTextEditor::getSegmentsInRange(LLTextEditor::segment_vec_t& segments_out, S32 start, S32 end, bool include_partial) const
{
- if(mShowLineNumbers)
+ segment_set_t::const_iterator first_it = getSegIterContaining(start);
+ segment_set_t::const_iterator end_it = getSegIterContaining(end - 1);
+ if (end_it != mSegments.end()) ++end_it;
+
+ for (segment_set_t::const_iterator it = first_it; it != end_it; ++it)
{
- local_x -= UI_TEXTEDITOR_LINE_NUMBER_MARGIN;
+ LLTextSegmentPtr segment = *it;
+ if (include_partial
+ || (segment->getStart() >= start
+ && segment->getEnd() <= end))
+ {
+ segments_out.push_back(segment);
+ }
}
+}
- // If round is true, if the position is on the right half of a character, the cursor
- // will be put to its right. If round is false, the cursor will always be put to the
- // character's left.
+// If round is true, if the position is on the right half of a character, the cursor
+// will be put to its right. If round is false, the cursor will always be put to the
+// character's left.
+S32 LLTextEditor::getDocIndexFromLocalCoord( S32 local_x, S32 local_y, BOOL round ) const
+{
// Figure out which line we're nearest to.
- S32 total_lines = getLineCount();
- S32 line_height = llround( mGLFont->getLineHeight() );
- S32 max_visible_lines = mTextRect.getHeight() / line_height;
- S32 scroll_lines = mScrollbar->getDocPos();
- S32 visible_lines = llmin( total_lines - scroll_lines, max_visible_lines ); // Lines currently visible
+ LLRect visible_region = mScroller->getVisibleContentRect();
+
+ // binary search for line that starts before local_y
+ line_list_t::const_iterator line_iter = std::lower_bound(mLineInfoList.begin(), mLineInfoList.end(), local_y - mTextRect.mBottom + visible_region.mBottom, compare_bottom());
- //S32 line = S32( 0.5f + ((mTextRect.mTop - local_y) / mGLFont->getLineHeight()) );
- S32 line = (mTextRect.mTop - 1 - local_y) / line_height;
- if (line >= total_lines)
+ if (line_iter == mLineInfoList.end())
{
return getLength(); // past the end
}
- line = llclamp( line, 0, visible_lines ) + scroll_lines;
+ S32 pos = getLength();
+ S32 start_x = mTextRect.mLeft;
+
+ segment_set_t::iterator line_seg_iter;
+ S32 line_seg_offset;
+ for(getSegmentAndOffset(line_iter->mDocIndexStart, &line_seg_iter, &line_seg_offset);
+ line_seg_iter != mSegments.end();
+ ++line_seg_iter, line_seg_offset = 0)
+ {
+ const LLTextSegmentPtr segmentp = *line_seg_iter;
+
+ S32 segment_line_start = segmentp->getStart() + line_seg_offset;
+ S32 segment_line_length = llmin(segmentp->getEnd(), line_iter->mDocIndexEnd - 1) - segment_line_start;
+ S32 text_width = segmentp->getWidth(line_seg_offset, segment_line_length);
+ if (local_x < start_x + text_width // cursor to left of right edge of text
+ || segmentp->getEnd() >= line_iter->mDocIndexEnd - 1) // or this segment wraps to next line
+ {
+ // Figure out which character we're nearest to.
+ S32 offset;
+ if (!segmentp->canEdit())
+ {
+ S32 segment_width = segmentp->getWidth(0, segmentp->getEnd() - segmentp->getStart());
+ if (round && local_x - start_x > segment_width / 2)
+ {
+ offset = segment_line_length;
+ }
+ else
+ {
+ offset = 0;
+ }
+ }
+ else
+ {
+ offset = segmentp->getOffset(local_x - start_x, line_seg_offset, segment_line_length, round);
+ }
+ pos = segment_line_start + offset;
+ break;
+ }
+ start_x += text_width;
+ }
- S32 line_start = getLineStart(line);
- S32 next_start = getLineStart(line+1);
- S32 line_end = (next_start != line_start) ? next_start - 1 : getLength();
+ return pos;
+}
- if(line_start == -1)
- {
- return 0;
+LLRect LLTextEditor::getLocalRectFromDocIndex(S32 pos) const
+{
+ LLRect local_rect(mTextRect);
+ local_rect.mBottom = local_rect.mTop - (S32)(mDefaultFont->getLineHeight());
+ if (mLineInfoList.empty())
+ {
+ return local_rect;
}
- else
+
+ // clamp pos to valid values
+ pos = llclamp(pos, 0, mLineInfoList.back().mDocIndexEnd - 1);
+
+
+ // find line that contains cursor
+ line_list_t::const_iterator line_iter = std::upper_bound(mLineInfoList.begin(), mLineInfoList.end(), pos, line_end_compare());
+
+ LLRect scrolled_view_rect = mScroller->getVisibleContentRect();
+ local_rect.mLeft = mTextRect.mLeft - scrolled_view_rect.mLeft;
+ local_rect.mBottom = mTextRect.mBottom + (line_iter->mBottom - scrolled_view_rect.mBottom);
+ local_rect.mTop = mTextRect.mBottom + (line_iter->mTop - scrolled_view_rect.mBottom);
+
+ segment_set_t::iterator line_seg_iter;
+ S32 line_seg_offset;
+ segment_set_t::iterator cursor_seg_iter;
+ S32 cursor_seg_offset;
+ getSegmentAndOffset(line_iter->mDocIndexStart, &line_seg_iter, &line_seg_offset);
+ getSegmentAndOffset(pos, &cursor_seg_iter, &cursor_seg_offset);
+
+ while(line_seg_iter != mSegments.end())
{
- S32 line_len = line_end - line_start;
- S32 pos;
+ const LLTextSegmentPtr segmentp = *line_seg_iter;
- if (mAllowEmbeddedItems)
+ if (line_seg_iter == cursor_seg_iter)
{
- // Figure out which character we're nearest to.
- bindEmbeddedChars(mGLFont);
- pos = mGLFont->charFromPixelOffset(mWText.c_str(), line_start,
- (F32)(local_x - mTextRect.mLeft),
- (F32)(mTextRect.getWidth()),
- line_len,
- round, TRUE);
- unbindEmbeddedChars(mGLFont);
+ // cursor advanced to right based on difference in offset of cursor to start of line
+ local_rect.mLeft += segmentp->getWidth(line_seg_offset, cursor_seg_offset - line_seg_offset);
+
+ break;
}
else
{
- pos = mGLFont->charFromPixelOffset(mWText.c_str(), line_start,
- (F32)(local_x - mTextRect.mLeft),
- (F32)mTextRect.getWidth(),
- line_len,
- round);
+ // add remainder of current text segment to cursor position
+ local_rect.mLeft += segmentp->getWidth(line_seg_offset, (segmentp->getEnd() - segmentp->getStart()) - line_seg_offset);
+ // offset will be 0 for all segments after the first
+ line_seg_offset = 0;
+ // go to next text segment on this line
+ ++line_seg_iter;
}
-
- return line_start + pos;
}
+
+ local_rect.mRight = local_rect.mLeft;
+
+ return local_rect;
+}
+
+void LLTextEditor::addDocumentChild(LLView* view)
+{
+ mDocumentPanel->addChild(view);
}
-void LLTextEditor::setCursor(S32 row, S32 column)
+void LLTextEditor::removeDocumentChild(LLView* view)
+{
+ mDocumentPanel->removeChild(view);
+}
+
+bool LLTextEditor::setCursor(S32 row, S32 column)
{
- const llwchar* doc = mWText.c_str();
- const char CR = 10;
- while(row--)
+ if (0 <= row && row < (S32)mLineInfoList.size())
{
- while (CR != *doc++);
+ S32 doc_pos = mLineInfoList[row].mDocIndexStart;
+ column = llclamp(column, 0, mLineInfoList[row].mDocIndexEnd - mLineInfoList[row].mDocIndexStart - 1);
+ doc_pos += column;
+ updateCursorXPos();
+
+ return setCursorPos(doc_pos);
}
- doc += column;
- setCursorPos(doc - mWText.c_str());
+ return false;
}
-void LLTextEditor::setCursorPos(S32 offset)
+bool LLTextEditor::setCursorPos(S32 cursor_pos, bool keep_cursor_offset)
{
- mCursorPos = llclamp(offset, 0, (S32)getLength());
+ S32 new_cursor_pos = cursor_pos;
+ if (new_cursor_pos != mCursorPos)
+ {
+ new_cursor_pos = getEditableIndex(new_cursor_pos, new_cursor_pos >= mCursorPos);
+ }
+
+ mCursorPos = llclamp(new_cursor_pos, 0, (S32)getLength());
needsScroll();
+ if (!keep_cursor_offset)
+ updateCursorXPos();
+ // did we get requested position?
+ return new_cursor_pos == cursor_pos;
+}
+
+void LLTextEditor::updateCursorXPos()
+{
// reset desired x cursor position
- mDesiredXPixel = -1;
+ mDesiredXPixel = getLocalRectFromDocIndex(mCursorPos).mLeft;
+}
+
+// constraint cursor to editable segments of document
+S32 LLTextEditor::getEditableIndex(S32 index, bool increasing_direction)
+{
+ //// always allow editable position at end of doc
+ //if (index == getLength())
+ //{
+ // return index;
+ //}
+
+ segment_set_t::iterator segment_iter;
+ S32 offset;
+ getSegmentAndOffset(index, &segment_iter, &offset);
+
+ LLTextSegmentPtr segmentp = *segment_iter;
+
+ if (segmentp->canEdit())
+ {
+ return segmentp->getStart() + offset;
+ }
+ else if (segmentp->getStart() < index && index < segmentp->getEnd())
+ {
+ // bias towards document end
+ if (increasing_direction)
+ {
+ return segmentp->getEnd();
+ }
+ // bias towards document start
+ else
+ {
+ return segmentp->getStart();
+ }
+ }
+ else
+ {
+ return index;
+ }
}
// virtual
@@ -935,7 +1221,7 @@ BOOL LLTextEditor::selectionContainsLineBreaks()
S32 left = llmin(mSelectionStart, mSelectionEnd);
S32 right = left + llabs(mSelectionStart - mSelectionEnd);
- const LLWString &wtext = mWText;
+ LLWString wtext = getWText();
for( S32 i = left; i < right; i++ )
{
if (wtext[i] == '\n')
@@ -972,7 +1258,7 @@ S32 LLTextEditor::indentLine( S32 pos, S32 spaces )
// Unindent
for(S32 i=0; i < -spaces; i++)
{
- const LLWString &wtext = mWText;
+ LLWString wtext = getWText();
if (wtext[pos] == ' ')
{
delta_spaces += remove( pos, 1, FALSE );
@@ -987,7 +1273,7 @@ void LLTextEditor::indentSelectedLines( S32 spaces )
{
if( hasSelection() )
{
- const LLWString &text = mWText;
+ LLWString text = getWText();
S32 left = llmin( mSelectionStart, mSelectionEnd );
S32 right = left + llabs( mSelectionStart - mSelectionEnd );
BOOL cursor_on_right = (mSelectionEnd > mSelectionStart);
@@ -1032,7 +1318,7 @@ void LLTextEditor::indentSelectedLines( S32 spaces )
}
right += delta_spaces;
- //text = mWText;
+ text = getWText();
// Find the next new line
while( (cur < right) && (text[cur] != '\n') )
@@ -1058,7 +1344,7 @@ void LLTextEditor::indentSelectedLines( S32 spaces )
mSelectionStart = right;
mSelectionEnd = left;
}
- mCursorPos = mSelectionEnd;
+ setCursorPos(mSelectionEnd);
}
}
@@ -1073,7 +1359,7 @@ void LLTextEditor::selectAll()
{
mSelectionStart = getLength();
mSelectionEnd = 0;
- mCursorPos = mSelectionEnd;
+ setCursorPos(mSelectionEnd);
}
@@ -1091,12 +1377,7 @@ BOOL LLTextEditor::handleToolTip(S32 x, S32 y, std::string& msg, LLRect* sticky_
}
}
- if( mSegments.empty() )
- {
- return TRUE;
- }
-
- const LLTextSegment* cur_segment = getSegmentAtLocalPos( x, y );
+ const LLTextSegmentPtr cur_segment = getSegmentAtLocalPos( x, y );
if( cur_segment )
{
BOOL has_tool_tip = FALSE;
@@ -1117,12 +1398,6 @@ BOOL LLTextEditor::handleToolTip(S32 x, S32 y, std::string& msg, LLRect* sticky_
return TRUE;
}
-BOOL LLTextEditor::handleScrollWheel(S32 x, S32 y, S32 clicks)
-{
- // Pretend the mouse is over the scrollbar
- return mScrollbar->handleScrollWheel( 0, 0, clicks );
-}
-
BOOL LLTextEditor::handleMouseDown(S32 x, S32 y, MASK mask)
{
BOOL handled = FALSE;
@@ -1130,7 +1405,7 @@ BOOL LLTextEditor::handleMouseDown(S32 x, S32 y, MASK mask)
// Let scrollbar have first dibs
handled = LLView::childrenHandleMouseDown(x, y, mask) != NULL;
- if( !handled && mTakesNonScrollClicks)
+ if( !handled )
{
if (!(mask & MASK_SHIFT))
{
@@ -1144,31 +1419,10 @@ BOOL LLTextEditor::handleMouseDown(S32 x, S32 y, MASK mask)
if (mask & MASK_SHIFT)
{
S32 old_cursor_pos = mCursorPos;
- setCursorAtLocalPos( x, y, TRUE );
+ setCursorAtLocalPos( x, y, true );
if (hasSelection())
{
- /* Mac-like behavior - extend selection towards the cursor
- if (mCursorPos < mSelectionStart
- && mCursorPos < mSelectionEnd)
- {
- // ...left of selection
- mSelectionStart = llmax(mSelectionStart, mSelectionEnd);
- mSelectionEnd = mCursorPos;
- }
- else if (mCursorPos > mSelectionStart
- && mCursorPos > mSelectionEnd)
- {
- // ...right of selection
- mSelectionStart = llmin(mSelectionStart, mSelectionEnd);
- mSelectionEnd = mCursorPos;
- }
- else
- {
- mSelectionEnd = mCursorPos;
- }
- */
- // Windows behavior
mSelectionEnd = mCursorPos;
}
else
@@ -1181,7 +1435,7 @@ BOOL LLTextEditor::handleMouseDown(S32 x, S32 y, MASK mask)
}
else
{
- setCursorAtLocalPos( x, y, TRUE );
+ setCursorAtLocalPos( x, y, true );
startSelection();
}
gFocusMgr.setMouseCapture( this );
@@ -1205,11 +1459,17 @@ BOOL LLTextEditor::handleMouseDown(S32 x, S32 y, MASK mask)
BOOL LLTextEditor::handleMiddleMouseDown(S32 x, S32 y, MASK mask)
{
- setFocus( TRUE );
- if( canPastePrimary() )
+ BOOL handled = FALSE;
+ handled = childrenHandleMiddleMouseDown(x, y, mask) != NULL;
+
+ if (!handled)
{
- setCursorAtLocalPos( x, y, TRUE );
- pastePrimary();
+ setFocus( TRUE );
+ if( canPastePrimary() )
+ {
+ setCursorAtLocalPos( x, y, true );
+ pastePrimary();
+ }
}
return TRUE;
}
@@ -1217,9 +1477,15 @@ BOOL LLTextEditor::handleMiddleMouseDown(S32 x, S32 y, MASK mask)
BOOL LLTextEditor::handleHover(S32 x, S32 y, MASK mask)
{
+ static LLUICachedControl<S32> scrollbar_size ("UIScrollbarSize", 0);
BOOL handled = FALSE;
+ if (mHoverSegment)
+ {
+ mHoverSegment->setHasMouseHover(false);
+ }
mHoverSegment = NULL;
+
if(hasMouseCapture() )
{
if( mIsSelecting )
@@ -1230,17 +1496,11 @@ BOOL LLTextEditor::handleHover(S32 x, S32 y, MASK mask)
mLastSelectionY = y;
}
- if( y > mTextRect.mTop )
- {
- mScrollbar->setDocPos( mScrollbar->getDocPos() - 1 );
- }
- else
- if( y < mTextRect.mBottom )
- {
- mScrollbar->setDocPos( mScrollbar->getDocPos() + 1 );
- }
+ mScroller->autoScroll(x, y);
- setCursorAtLocalPos( x, y, TRUE );
+ S32 clamped_x = llclamp(x, mTextRect.mLeft, mTextRect.mRight);
+ S32 clamped_y = llclamp(y, mTextRect.mBottom, mTextRect.mTop);
+ setCursorAtLocalPos( clamped_x, clamped_y, true );
mSelectionEnd = mCursorPos;
}
@@ -1262,51 +1522,43 @@ BOOL LLTextEditor::handleHover(S32 x, S32 y, MASK mask)
}
// Opaque
- if( !handled && mTakesNonScrollClicks)
+ if( !handled )
{
// Check to see if we're over an HTML-style link
- if( !mSegments.empty() )
+ LLTextSegmentPtr cur_segment = getSegmentAtLocalPos( x, y );
+ if( cur_segment )
{
- const LLTextSegment* cur_segment = getSegmentAtLocalPos( x, y );
- if( cur_segment )
+ if(cur_segment->getStyle()->isLink())
{
- if(cur_segment->getStyle()->isLink())
- {
- lldebugst(LLERR_USER_INPUT) << "hover handled by " << getName() << " (over link, inactive)" << llendl;
- getWindow()->setCursor(UI_CURSOR_HAND);
- handled = TRUE;
- }
- else
- if(cur_segment->getStyle()->getIsEmbeddedItem())
- {
- lldebugst(LLERR_USER_INPUT) << "hover handled by " << getName() << " (over embedded item, inactive)" << llendl;
- getWindow()->setCursor(UI_CURSOR_HAND);
- //getWindow()->setCursor(UI_CURSOR_ARROW);
- handled = TRUE;
- }
- mHoverSegment = cur_segment;
+ lldebugst(LLERR_USER_INPUT) << "hover handled by " << getName() << " (over link, inactive)" << llendl;
+ getWindow()->setCursor(UI_CURSOR_HAND);
+ handled = TRUE;
+ }
+ //else
+ //if(cur_segment->getStyle()->getIsEmbeddedItem())
+ //{
+ // lldebugst(LLERR_USER_INPUT) << "hover handled by " << getName() << " (over embedded item, inactive)" << llendl;
+ // getWindow()->setCursor(UI_CURSOR_HAND);
+ // //getWindow()->setCursor(UI_CURSOR_ARROW);
+ // handled = TRUE;
+ //}
+ if (mHoverSegment)
+ {
+ mHoverSegment->setHasMouseHover(false);
}
+ cur_segment->setHasMouseHover(true);
+ mHoverSegment = cur_segment;
+ mHTML = mHoverSegment->getStyle()->getLinkHREF();
}
if( !handled )
{
lldebugst(LLERR_USER_INPUT) << "hover handled by " << getName() << " (inactive)" << llendl;
- if (!mScrollbar->getVisible() || x < getRect().getWidth() - SCROLLBAR_SIZE)
- {
- getWindow()->setCursor(UI_CURSOR_IBEAM);
- }
- else
- {
- getWindow()->setCursor(UI_CURSOR_ARROW);
- }
+ getWindow()->setCursor(UI_CURSOR_IBEAM);
handled = TRUE;
}
}
- if (mOnScrollEndCallback && mOnScrollEndData && (mScrollbar->getDocPos() == mScrollbar->getDocPosMax()))
- {
- mOnScrollEndCallback(mOnScrollEndData);
- }
return handled;
}
@@ -1318,22 +1570,14 @@ BOOL LLTextEditor::handleMouseUp(S32 x, S32 y, MASK mask)
// let scrollbar have first dibs
handled = LLView::childrenHandleMouseUp(x, y, mask) != NULL;
- if( !handled && mTakesNonScrollClicks)
+ if( !handled )
{
if( mIsSelecting )
{
- // Finish selection
- if( y > mTextRect.mTop )
- {
- mScrollbar->setDocPos( mScrollbar->getDocPos() - 1 );
- }
- else
- if( y < mTextRect.mBottom )
- {
- mScrollbar->setDocPos( mScrollbar->getDocPos() + 1 );
- }
-
- setCursorAtLocalPos( x, y, TRUE );
+ mScroller->autoScroll(x, y);
+ S32 clamped_x = llclamp(x, mTextRect.mLeft, mTextRect.mRight);
+ S32 clamped_y = llclamp(y, mTextRect.mBottom, mTextRect.mTop);
+ setCursorAtLocalPos( clamped_x, clamped_y, true );
endSelection();
}
@@ -1369,25 +1613,25 @@ BOOL LLTextEditor::handleDoubleClick(S32 x, S32 y, MASK mask)
// let scrollbar have first dibs
handled = LLView::childrenHandleDoubleClick(x, y, mask) != NULL;
- if( !handled && mTakesNonScrollClicks)
+ if( !handled )
{
- setCursorAtLocalPos( x, y, FALSE );
+ setCursorAtLocalPos( x, y, false );
deselect();
- const LLWString &text = mWText;
+ LLWString text = getWText();
- if( isPartOfWord( text[mCursorPos] ) )
+ if( LLWStringUtil::isPartOfWord( text[mCursorPos] ) )
{
// Select word the cursor is over
- while ((mCursorPos > 0) && isPartOfWord(text[mCursorPos-1]))
+ while ((mCursorPos > 0) && LLWStringUtil::isPartOfWord(text[mCursorPos-1]))
{
- mCursorPos--;
+ if (!setCursorPos(mCursorPos - 1)) break;
}
startSelection();
- while ((mCursorPos < (S32)text.length()) && isPartOfWord( text[mCursorPos] ) )
+ while ((mCursorPos < (S32)text.length()) && LLWStringUtil::isPartOfWord( text[mCursorPos] ) )
{
- mCursorPos++;
+ if (!setCursorPos(mCursorPos + 1)) break;
}
mSelectionEnd = mCursorPos;
@@ -1396,7 +1640,7 @@ BOOL LLTextEditor::handleDoubleClick(S32 x, S32 y, MASK mask)
{
// Select the character the cursor is over
startSelection();
- mCursorPos++;
+ setCursorPos(mCursorPos + 1);
mSelectionEnd = mCursorPos;
}
@@ -1459,24 +1703,30 @@ S32 LLTextEditor::execute( LLTextCmd* cmd )
return delta;
}
-S32 LLTextEditor::insert(const S32 pos, const LLWString &wstr, const BOOL group_with_next_op)
+S32 LLTextEditor::insert(S32 pos, const LLWString &wstr, bool group_with_next_op, LLTextSegmentPtr segment)
{
- return execute( new LLTextCmdInsert( pos, group_with_next_op, wstr ) );
+ return execute( new LLTextCmdInsert( pos, group_with_next_op, wstr, segment ) );
}
-S32 LLTextEditor::remove(const S32 pos, const S32 length, const BOOL group_with_next_op)
+S32 LLTextEditor::remove(S32 pos, S32 length, bool group_with_next_op)
{
- return execute( new LLTextCmdRemove( pos, group_with_next_op, length ) );
+ S32 end_pos = getEditableIndex(pos + length, true);
+
+ segment_vec_t segments_to_remove;
+ // store text segments
+ getSegmentsInRange(segments_to_remove, pos, pos + length, false);
+
+ return execute( new LLTextCmdRemove( pos, group_with_next_op, end_pos - pos, segments_to_remove ) );
}
-S32 LLTextEditor::append(const LLWString &wstr, const BOOL group_with_next_op)
+S32 LLTextEditor::append(const LLWString &wstr, bool group_with_next_op, LLTextSegmentPtr segment)
{
- return insert(mWText.length(), wstr, group_with_next_op);
+ return insert(getLength(), wstr, group_with_next_op, segment);
}
S32 LLTextEditor::overwriteChar(S32 pos, llwchar wc)
{
- if ((S32)mWText.length() == pos)
+ if ((S32)getLength() == pos)
{
return addChar(pos, wc);
}
@@ -1498,7 +1748,7 @@ void LLTextEditor::removeCharOrTab()
{
S32 chars_to_remove = 1;
- const LLWString &text = mWText;
+ LLWString text = getWText();
if (text[mCursorPos - 1] == ' ')
{
// Try to remove a "tab"
@@ -1563,7 +1813,7 @@ void LLTextEditor::removeChar()
// Add a single character to the text
S32 LLTextEditor::addChar(S32 pos, llwchar wc)
{
- if ( (wstring_utf8_length( mWText ) + wchar_utf8_length( wc )) >= mMaxTextByteLength)
+ if ( (wstring_utf8_length( getWText() ) + wchar_utf8_length( wc )) >= mMaxTextByteLength)
{
make_ui_sound("UISndBadKeystroke");
return 0;
@@ -1577,7 +1827,7 @@ S32 LLTextEditor::addChar(S32 pos, llwchar wc)
}
else
{
- return execute(new LLTextCmdAddChar(pos, FALSE, wc));
+ return execute(new LLTextCmdAddChar(pos, FALSE, wc, LLTextSegmentPtr()));
}
}
@@ -1614,10 +1864,10 @@ BOOL LLTextEditor::handleSelectionKey(const KEY key, const MASK mask)
if( 0 < mCursorPos )
{
startSelection();
- mCursorPos--;
+ setCursorPos(mCursorPos - 1);
if( mask & MASK_CONTROL )
{
- mCursorPos = prevWordPos(mCursorPos);
+ setCursorPos(prevWordPos(mCursorPos));
}
mSelectionEnd = mCursorPos;
}
@@ -1627,10 +1877,10 @@ BOOL LLTextEditor::handleSelectionKey(const KEY key, const MASK mask)
if( mCursorPos < getLength() )
{
startSelection();
- mCursorPos++;
+ setCursorPos(mCursorPos + 1);
if( mask & MASK_CONTROL )
{
- mCursorPos = nextWordPos(mCursorPos);
+ setCursorPos(nextWordPos(mCursorPos));
}
mSelectionEnd = mCursorPos;
}
@@ -1652,7 +1902,7 @@ BOOL LLTextEditor::handleSelectionKey(const KEY key, const MASK mask)
startSelection();
if( mask & MASK_CONTROL )
{
- mCursorPos = 0;
+ setCursorPos(0);
}
else
{
@@ -1677,7 +1927,7 @@ BOOL LLTextEditor::handleSelectionKey(const KEY key, const MASK mask)
startSelection();
if( mask & MASK_CONTROL )
{
- mCursorPos = getLength();
+ setCursorPos(getLength());
}
else
{
@@ -1728,14 +1978,7 @@ BOOL LLTextEditor::handleNavigationKey(const KEY key, const MASK mask)
switch( key )
{
case KEY_UP:
- if (mReadOnly)
- {
- mScrollbar->setDocPos(mScrollbar->getDocPos() - 1);
- }
- else
- {
- changeLine( -1 );
- }
+ changeLine( -1 );
break;
case KEY_PAGE_UP:
@@ -1743,25 +1986,11 @@ BOOL LLTextEditor::handleNavigationKey(const KEY key, const MASK mask)
break;
case KEY_HOME:
- if (mReadOnly)
- {
- mScrollbar->setDocPos(0);
- }
- else
- {
- startOfLine();
- }
+ startOfLine();
break;
case KEY_DOWN:
- if (mReadOnly)
- {
- mScrollbar->setDocPos(mScrollbar->getDocPos() + 1);
- }
- else
- {
- changeLine( 1 );
- }
+ changeLine( 1 );
break;
case KEY_PAGE_DOWN:
@@ -1769,21 +1998,10 @@ BOOL LLTextEditor::handleNavigationKey(const KEY key, const MASK mask)
break;
case KEY_END:
- if (mReadOnly)
- {
- mScrollbar->setDocPos(mScrollbar->getDocPosMax());
- }
- else
- {
- endOfLine();
- }
+ endOfLine();
break;
case KEY_LEFT:
- if (mReadOnly)
- {
- break;
- }
if( hasSelection() )
{
setCursorPos(llmin( mCursorPos - 1, mSelectionStart, mSelectionEnd ));
@@ -1802,10 +2020,6 @@ BOOL LLTextEditor::handleNavigationKey(const KEY key, const MASK mask)
break;
case KEY_RIGHT:
- if (mReadOnly)
- {
- break;
- }
if( hasSelection() )
{
setCursorPos(llmax( mCursorPos + 1, mSelectionStart, mSelectionEnd ));
@@ -1829,10 +2043,6 @@ BOOL LLTextEditor::handleNavigationKey(const KEY key, const MASK mask)
}
}
- if (mOnScrollEndCallback && mOnScrollEndData && (mScrollbar->getDocPos() == mScrollbar->getDocPosMax()))
- {
- mOnScrollEndCallback(mOnScrollEndData);
- }
return handled;
}
@@ -1865,7 +2075,7 @@ void LLTextEditor::cut()
}
S32 left_pos = llmin( mSelectionStart, mSelectionEnd );
S32 length = llabs( mSelectionStart - mSelectionEnd );
- gClipboard.copyFromSubstring( mWText, left_pos, length, mSourceID );
+ gClipboard.copyFromSubstring( getWText(), left_pos, length, mSourceID );
deleteSelection( FALSE );
needsReflow();
@@ -1885,7 +2095,7 @@ void LLTextEditor::copy()
}
S32 left_pos = llmin( mSelectionStart, mSelectionEnd );
S32 length = llabs( mSelectionStart - mSelectionEnd );
- gClipboard.copyFromSubstring(mWText, left_pos, length, mSourceID);
+ gClipboard.copyFromSubstring(getWText(), left_pos, length, mSourceID);
}
BOOL LLTextEditor::canPaste() const
@@ -1957,7 +2167,7 @@ void LLTextEditor::pasteHelper(bool is_primary)
for( S32 i = 0; i < len; i++ )
{
llwchar wc = clean_string[i];
- if( (wc < LLFont::FIRST_CHAR) && (wc != LF) )
+ if( (wc < LLFontFreetype::FIRST_CHAR) && (wc != LF) )
{
clean_string[i] = LL_UNKNOWN_CHAR;
}
@@ -1969,7 +2179,7 @@ void LLTextEditor::pasteHelper(bool is_primary)
}
// Insert the new text into the existing text.
- setCursorPos(mCursorPos + insert(mCursorPos, clean_string, FALSE));
+ setCursorPos(mCursorPos + insert(mCursorPos, clean_string, FALSE, LLTextSegmentPtr()));
deselect();
needsReflow();
@@ -1986,7 +2196,7 @@ void LLTextEditor::copyPrimary()
}
S32 left_pos = llmin( mSelectionStart, mSelectionEnd );
S32 length = llabs( mSelectionStart - mSelectionEnd );
- gClipboard.copyFromPrimarySubstring(mWText, left_pos, length, mSourceID);
+ gClipboard.copyFromPrimarySubstring(getWText(), left_pos, length, mSourceID);
}
BOOL LLTextEditor::canPastePrimary() const
@@ -2016,7 +2226,7 @@ BOOL LLTextEditor::handleControlKey(const KEY key, const MASK mask)
if( mask & MASK_SHIFT )
{
startSelection();
- mCursorPos = 0;
+ setCursorPos(0);
mSelectionEnd = mCursorPos;
}
else
@@ -2024,7 +2234,7 @@ BOOL LLTextEditor::handleControlKey(const KEY key, const MASK mask)
// Ctrl-Home, Ctrl-Left, Ctrl-Right, Ctrl-Down
// all move the cursor as if clicking, so should deselect.
deselect();
- setCursorPos(0);
+ startOfDoc();
}
break;
@@ -2237,7 +2447,7 @@ void LLTextEditor::unindentLineBeforeCloseBrace()
{
if( mCursorPos >= 1 )
{
- const LLWString &text = mWText;
+ LLWString text = getWText();
if( ' ' == text[ mCursorPos - 1 ] )
{
removeCharOrTab();
@@ -2253,42 +2463,87 @@ BOOL LLTextEditor::handleKeyHere(KEY key, MASK mask )
BOOL return_key_hit = FALSE;
BOOL text_may_have_changed = TRUE;
- if ( gFocusMgr.getKeyboardFocus() == this )
+ // Special case for TAB. If want to move to next field, report
+ // not handled and let the parent take care of field movement.
+ if (KEY_TAB == key && mTabsToNextField)
{
- // Special case for TAB. If want to move to next field, report
- // not handled and let the parent take care of field movement.
- if (KEY_TAB == key && mTabsToNextField)
- {
- return FALSE;
- }
+ return FALSE;
+ }
+ /*
+ if (KEY_F10 == key)
+ {
+ LLComboBox::Params cp;
+ cp.name = "combo box";
+ cp.label = "my combo";
+ cp.rect.width = 100;
+ cp.rect.height = 20;
+ cp.items.add().label = "item 1";
+ cp.items.add().label = "item 2";
+ cp.items.add().label = "item 3";
+
+ appendWidget(LLUICtrlFactory::create<LLComboBox>(cp), "combo", true, false);
+ }
+ if (KEY_F11 == key)
+ {
+ LLButton::Params bp;
+ bp.name = "text button";
+ bp.label = "Click me";
+ bp.rect.width = 100;
+ bp.rect.height = 20;
+ appendWidget(LLUICtrlFactory::create<LLButton>(bp), "button", true, false);
+ }
+ */
+ if (mReadOnly)
+ {
+ handled = mScroller->handleKeyHere( key, mask );
+ }
+ else
+ {
+ // handle navigation keys ourself
handled = handleNavigationKey( key, mask );
+ }
+
+
+ if( handled )
+ {
+ text_may_have_changed = FALSE;
+ }
+
+ if( !handled )
+ {
+ handled = handleSelectionKey( key, mask );
if( handled )
{
- text_may_have_changed = FALSE;
+ selection_modified = TRUE;
}
-
- if( !handled )
+ }
+
+ if( !handled )
+ {
+ handled = handleControlKey( key, mask );
+ if( handled )
{
- handled = handleSelectionKey( key, mask );
- if( handled )
- {
- selection_modified = TRUE;
- }
+ selection_modified = TRUE;
}
-
- if( !handled )
+ }
+
+ if( !handled && mHandleEditKeysDirectly )
+ {
+ handled = handleEditKey( key, mask );
+ if( handled )
{
- handled = handleControlKey( key, mask );
- if( handled )
- {
- selection_modified = TRUE;
- }
+ selection_modified = TRUE;
+ text_may_have_changed = TRUE;
}
+ }
- if( !handled && mHandleEditKeysDirectly )
+ // Handle most keys only if the text editor is writeable.
+ if( !mReadOnly )
+ {
+ if( !handled )
{
- handled = handleEditKey( key, mask );
+ handled = handleSpecialKey( key, mask, &return_key_hit );
if( handled )
{
selection_modified = TRUE;
@@ -2296,41 +2551,27 @@ BOOL LLTextEditor::handleKeyHere(KEY key, MASK mask )
}
}
- // Handle most keys only if the text editor is writeable.
- if( !mReadOnly )
- {
- if( !handled )
- {
- handled = handleSpecialKey( key, mask, &return_key_hit );
- if( handled )
- {
- selection_modified = TRUE;
- text_may_have_changed = TRUE;
- }
- }
+ }
- }
+ if( handled )
+ {
+ resetKeystrokeTimer();
- if( handled )
+ // Most keystrokes will make the selection box go away, but not all will.
+ if( !selection_modified &&
+ KEY_SHIFT != key &&
+ KEY_CONTROL != key &&
+ KEY_ALT != key &&
+ KEY_CAPSLOCK )
{
- resetKeystrokeTimer();
-
- // Most keystrokes will make the selection box go away, but not all will.
- if( !selection_modified &&
- KEY_SHIFT != key &&
- KEY_CONTROL != key &&
- KEY_ALT != key &&
- KEY_CAPSLOCK )
- {
- deselect();
- }
+ deselect();
+ }
- if(text_may_have_changed)
- {
- needsReflow();
- }
- needsScroll();
+ if(text_may_have_changed)
+ {
+ needsReflow();
}
+ needsScroll();
}
return handled;
@@ -2346,34 +2587,31 @@ BOOL LLTextEditor::handleUnicodeCharHere(llwchar uni_char)
BOOL handled = FALSE;
- if ( gFocusMgr.getKeyboardFocus() == this )
+ // Handle most keys only if the text editor is writeable.
+ if( !mReadOnly )
{
- // Handle most keys only if the text editor is writeable.
- if( !mReadOnly )
+ if( '}' == uni_char )
{
- if( '}' == uni_char )
- {
- unindentLineBeforeCloseBrace();
- }
+ unindentLineBeforeCloseBrace();
+ }
- // TODO: KLW Add auto show of tool tip on (
- addChar( uni_char );
+ // TODO: KLW Add auto show of tool tip on (
+ addChar( uni_char );
- // Keys that add characters temporarily hide the cursor
- getWindow()->hideCursorUntilMouseMove();
+ // Keys that add characters temporarily hide the cursor
+ getWindow()->hideCursorUntilMouseMove();
- handled = TRUE;
- }
+ handled = TRUE;
+ }
- if( handled )
- {
- resetKeystrokeTimer();
+ if( handled )
+ {
+ resetKeystrokeTimer();
- // Most keystrokes will make the selection box go away, but not all will.
- deselect();
+ // Most keystrokes will make the selection box go away, but not all will.
+ deselect();
- needsReflow();
- }
+ needsReflow();
}
return handled;
@@ -2401,7 +2639,7 @@ void LLTextEditor::doDelete()
{
S32 i;
S32 chars_to_remove = 1;
- const LLWString &text = mWText;
+ LLWString text = getWText();
if( (text[ mCursorPos ] == ' ') && (mCursorPos + SPACES_PER_TAB < getLength()) )
{
// Try to remove a full tab's worth of spaces
@@ -2546,6 +2784,12 @@ void LLTextEditor::onFocusLost()
LLUICtrl::onFocusLost();
}
+void LLTextEditor::onCommit()
+{
+ setControlValue(getValue());
+ LLUICtrl::onCommit();
+}
+
void LLTextEditor::setEnabled(BOOL enabled)
{
// just treat enabled as read-only flag
@@ -2562,321 +2806,219 @@ void LLTextEditor::drawBackground()
{
S32 left = 0;
S32 top = getRect().getHeight();
- S32 right = getRect().getWidth();
S32 bottom = 0;
- LLColor4 bg_color = mReadOnly ? mReadOnlyBgColor
- : gFocusMgr.getKeyboardFocus() == this ? mFocusBgColor : mWriteableBgColor;
+ LLColor4 bg_color = mReadOnly ? mReadOnlyBgColor.get()
+ : hasFocus() ? mFocusBgColor.get() : mWriteableBgColor.get();
if( mShowLineNumbers ) {
- gl_rect_2d(left, top, UI_TEXTEDITOR_LINE_NUMBER_MARGIN, bottom, mReadOnlyBgColor ); // line number area always read-only
- gl_rect_2d(UI_TEXTEDITOR_LINE_NUMBER_MARGIN, top, right, bottom, bg_color); // body text area to the right of line numbers
+ gl_rect_2d(left, top, UI_TEXTEDITOR_LINE_NUMBER_MARGIN, bottom, mReadOnlyBgColor.get() ); // line number area always read-only
gl_rect_2d(UI_TEXTEDITOR_LINE_NUMBER_MARGIN, top, UI_TEXTEDITOR_LINE_NUMBER_MARGIN-1, bottom, LLColor4::grey3); // separator
- } else {
- gl_rect_2d(left, top, right, bottom, bg_color); // body text area
- }
-
- LLView::draw();
+ }
}
// Draws the black box behind the selected text
void LLTextEditor::drawSelectionBackground()
{
// Draw selection even if we don't have keyboard focus for search/replace
- if( hasSelection() )
+ if( hasSelection() && !mLineInfoList.empty())
{
- const LLWString &text = mWText;
- const S32 text_len = getLength();
- std::queue<S32> line_endings;
-
- S32 line_height = llround( mGLFont->getLineHeight() );
+ LLWString text = getWText();
+ std::vector<LLRect> selection_rects;
S32 selection_left = llmin( mSelectionStart, mSelectionEnd );
S32 selection_right = llmax( mSelectionStart, mSelectionEnd );
- S32 selection_left_x = mTextRect.mLeft;
- S32 selection_left_y = mTextRect.mTop - line_height;
- S32 selection_right_x = mTextRect.mRight;
- S32 selection_right_y = mTextRect.mBottom;
-
- BOOL selection_left_visible = FALSE;
- BOOL selection_right_visible = FALSE;
+ LLRect selection_rect = mTextRect;
// Skip through the lines we aren't drawing.
- S32 cur_line = mScrollbar->getDocPos();
+ LLRect content_display_rect = mScroller->getVisibleContentRect();
- S32 left_line_num = cur_line;
- S32 num_lines = getLineCount();
- S32 right_line_num = num_lines - 1;
+ // binary search for line that starts before top of visible buffer
+ line_list_t::const_iterator line_iter = std::lower_bound(mLineInfoList.begin(), mLineInfoList.end(), content_display_rect.mTop, compare_bottom());
+ line_list_t::const_iterator end_iter = std::lower_bound(mLineInfoList.begin(), mLineInfoList.end(), content_display_rect.mBottom, compare_top());
- S32 line_start = -1;
- if (cur_line >= num_lines)
- {
- return;
- }
-
- line_start = getLineStart(cur_line);
-
- S32 left_visible_pos = line_start;
- S32 right_visible_pos = line_start;
-
- S32 text_y = mTextRect.mTop - line_height;
+ bool done = false;
// Find the coordinates of the selected area
- while((cur_line < num_lines))
+ for (;line_iter != end_iter && !done; ++line_iter)
{
- S32 next_line = -1;
- S32 line_end = text_len;
-
- if ((cur_line + 1) < num_lines)
+ // is selection visible on this line?
+ if (line_iter->mDocIndexEnd > selection_left && line_iter->mDocIndexStart < selection_right)
{
- next_line = getLineStart(cur_line + 1);
- line_end = next_line;
-
- line_end = ( (line_end - line_start)==0 || text[next_line-1] == '\n' || text[next_line-1] == '\0' || text[next_line-1] == ' ' || text[next_line-1] == '\t' ) ? next_line-1 : next_line;
- }
+ segment_set_t::iterator segment_iter;
+ S32 segment_offset;
+ getSegmentAndOffset(line_iter->mDocIndexStart, &segment_iter, &segment_offset);
+
+ LLRect selection_rect;
+ selection_rect.mLeft = 0;
+ selection_rect.mRight = 0;
+ selection_rect.mBottom = line_iter->mBottom;
+ selection_rect.mTop = line_iter->mTop;
+
+ for(;segment_iter != mSegments.end(); ++segment_iter, segment_offset = 0)
+ {
+ LLTextSegmentPtr segmentp = *segment_iter;
- const llwchar* line = text.c_str() + line_start;
+ S32 segment_line_start = segmentp->getStart() + segment_offset;
+ S32 segment_line_end = llmin(segmentp->getEnd(), line_iter->mDocIndexEnd);
- if( line_start <= selection_left && selection_left <= line_end )
- {
- left_line_num = cur_line;
- selection_left_visible = TRUE;
- selection_left_x = mTextRect.mLeft + mGLFont->getWidth(line, 0, selection_left - line_start, mAllowEmbeddedItems);
- selection_left_y = text_y;
- }
- if( line_start <= selection_right && selection_right <= line_end )
- {
- right_line_num = cur_line;
- selection_right_visible = TRUE;
- selection_right_x = mTextRect.mLeft + mGLFont->getWidth(line, 0, selection_right - line_start, mAllowEmbeddedItems);
- if (selection_right == line_end)
- {
- // add empty space for "newline"
- //selection_right_x += mGLFont->getWidth("n");
- }
- selection_right_y = text_y;
- }
-
- // if selection spans end of current line...
- if (selection_left <= line_end && line_end < selection_right && selection_left != selection_right)
- {
- // extend selection slightly beyond end of line
- // to indicate selection of newline character (use "n" character to determine width)
- const LLWString nstr(utf8str_to_wstring(std::string("n")));
- line_endings.push(mTextRect.mLeft + mGLFont->getWidth(line, 0, line_end - line_start, mAllowEmbeddedItems) + mGLFont->getWidth(nstr.c_str()));
- }
-
- // move down one line
- text_y -= line_height;
+ // if selection after beginning of segment
+ if(selection_left >= segment_line_start)
+ {
+ S32 num_chars = llmin(selection_left, segment_line_end) - segment_line_start;
+ selection_rect.mLeft += segmentp->getWidth(segment_offset, num_chars);
+ }
- right_visible_pos = line_end;
- line_start = next_line;
- cur_line++;
+ // if selection spans end of current segment...
+ if (selection_right > segment_line_end)
+ {
+ // extend selection slightly beyond end of line
+ // to indicate selection of newline character (use "n" character to determine width)
+ selection_rect.mRight += segmentp->getWidth(segment_offset, segment_line_end - segment_line_start);
+ }
+ // else if selection ends on current segment...
+ else
+ {
+ S32 num_chars = selection_right - segment_line_start;
+ selection_rect.mRight += segmentp->getWidth(segment_offset, num_chars);
- if (selection_right_visible)
- {
- break;
+ break;
+ }
+ }
+ selection_rects.push_back(selection_rect);
}
}
// Draw the selection box (we're using a box instead of reversing the colors on the selected text).
- BOOL selection_visible = (left_visible_pos <= selection_right) && (selection_left <= right_visible_pos);
- if( selection_visible )
+ gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
+ const LLColor4& color = mReadOnly ? mReadOnlyBgColor.get() : mWriteableBgColor.get();
+ F32 alpha = hasFocus() ? 0.7f : 0.3f;
+ gGL.color4f( 1.f - color.mV[0], 1.f - color.mV[1], 1.f - color.mV[2], alpha );
+
+ for (std::vector<LLRect>::iterator rect_it = selection_rects.begin();
+ rect_it != selection_rects.end();
+ ++rect_it)
{
- gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
- const LLColor4& color = mReadOnly ? mReadOnlyBgColor : mWriteableBgColor;
- F32 alpha = hasFocus() ? 1.f : 0.5f;
- gGL.color4f( 1.f - color.mV[0], 1.f - color.mV[1], 1.f - color.mV[2], alpha );
- S32 margin_offset = mShowLineNumbers ? UI_TEXTEDITOR_LINE_NUMBER_MARGIN : 0;
-
- if( selection_left_y == selection_right_y )
- {
- // Draw from selection start to selection end
- gl_rect_2d( selection_left_x + margin_offset, selection_left_y + line_height + 1,
- selection_right_x + margin_offset, selection_right_y);
- }
- else
- {
- // Draw from selection start to the end of the first line
- if( mTextRect.mRight == selection_left_x )
- {
- selection_left_x -= CURSOR_THICKNESS;
- }
-
- S32 line_end = line_endings.front();
- line_endings.pop();
- gl_rect_2d( selection_left_x + margin_offset, selection_left_y + line_height + 1,
- line_end + margin_offset, selection_left_y );
-
- S32 line_num = left_line_num + 1;
- while(line_endings.size())
- {
- S32 vert_offset = -(line_num - left_line_num) * line_height;
- // Draw the block between the two lines
- gl_rect_2d( mTextRect.mLeft + margin_offset, selection_left_y + vert_offset + line_height + 1,
- line_endings.front() + margin_offset, selection_left_y + vert_offset);
- line_endings.pop();
- line_num++;
- }
-
- // Draw from the start of the last line to selection end
- if( mTextRect.mLeft == selection_right_x )
- {
- selection_right_x += CURSOR_THICKNESS;
- }
- gl_rect_2d( mTextRect.mLeft + margin_offset, selection_right_y + line_height + 1,
- selection_right_x + margin_offset, selection_right_y );
- }
+ LLRect selection_rect = *rect_it;
+ selection_rect.translate(mTextRect.mLeft - content_display_rect.mLeft, mTextRect.mBottom - content_display_rect.mBottom);
+ gl_rect_2d(selection_rect);
}
}
}
void LLTextEditor::drawCursor()
{
- if( gFocusMgr.getKeyboardFocus() == this
- && gShowTextEditCursor && !mReadOnly)
+ if( hasFocus()
+ && gFocusMgr.getAppHasFocus()
+ && !mReadOnly)
{
- const LLWString &text = mWText;
- const S32 text_len = getLength();
+ LLWString wtext = getWText();
+ const llwchar* text = wtext.c_str();
- // Skip through the lines we aren't drawing.
- S32 cur_pos = mScrollbar->getDocPos();
+ LLRect cursor_rect = getLocalRectFromDocIndex(mCursorPos);
+ cursor_rect.translate(-1, 0);
+ segment_set_t::iterator seg_it = getSegIterContaining(mCursorPos);
+
+ // take style from last segment
+ LLTextSegmentPtr segmentp;
- S32 num_lines = getLineCount();
- if (cur_pos >= num_lines)
+ if (seg_it != mSegments.end())
{
+ segmentp = *seg_it;
+ }
+ else
+ {
+ //segmentp = mSegments.back();
return;
}
- S32 line_start = getLineStart(cur_pos);
-
- F32 line_height = mGLFont->getLineHeight();
- F32 text_y = (F32)(mTextRect.mTop) - line_height;
- F32 cursor_left = 0.f;
- F32 next_char_left = 0.f;
- F32 cursor_bottom = 0.f;
- BOOL cursor_visible = FALSE;
-
- S32 line_end = 0;
- // Determine if the cursor is visible and if so what its coordinates are.
- while( (mTextRect.mBottom <= llround(text_y)) && (cur_pos < num_lines))
+ // Draw the cursor
+ // (Flash the cursor every half second starting a fixed time after the last keystroke)
+ F32 elapsed = mKeystrokeTimer.getElapsedTimeF32();
+ if( (elapsed < CURSOR_FLASH_DELAY ) || (S32(elapsed * 2) & 1) )
{
- line_end = text_len + 1;
- S32 next_line = -1;
- if ((cur_pos + 1) < num_lines)
+ if (LL_KIM_OVERWRITE == gKeyboard->getInsertMode() && !hasSelection())
{
- next_line = getLineStart(cur_pos + 1);
- line_end = next_line - 1;
+ S32 width = llmax(CURSOR_THICKNESS, segmentp->getWidth(mCursorPos - segmentp->getStart(), 1));
+ cursor_rect.mRight = cursor_rect.mLeft + width;
}
-
- const llwchar* line = text.c_str() + line_start;
-
- // Find the cursor and selection bounds
- if( line_start <= mCursorPos && mCursorPos <= line_end )
+ else
{
- cursor_visible = TRUE;
- next_char_left = (F32)mTextRect.mLeft + mGLFont->getWidthF32(line, 0, mCursorPos - line_start, mAllowEmbeddedItems );
- cursor_left = next_char_left - 1.f;
- cursor_bottom = text_y;
- break;
+ cursor_rect.mRight = cursor_rect.mLeft + CURSOR_THICKNESS;
}
+
+ gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
- // move down one line
- text_y -= line_height;
- line_start = next_line;
- cur_pos++;
- }
-
- if(mShowLineNumbers)
- {
- cursor_left += UI_TEXTEDITOR_LINE_NUMBER_MARGIN;
- }
+ gGL.color4fv( mCursorColor.get().mV );
+
+ gl_rect_2d(cursor_rect);
- // Draw the cursor
- if( cursor_visible )
- {
- // (Flash the cursor every half second starting a fixed time after the last keystroke)
- F32 elapsed = mKeystrokeTimer.getElapsedTimeF32();
- if( (elapsed < CURSOR_FLASH_DELAY ) || (S32(elapsed * 2) & 1) )
+ if (LL_KIM_OVERWRITE == gKeyboard->getInsertMode() && !hasSelection() && text[mCursorPos] != '\n')
{
- F32 cursor_top = cursor_bottom + line_height + 1.f;
- F32 cursor_right = cursor_left + (F32)CURSOR_THICKNESS;
- if (LL_KIM_OVERWRITE == gKeyboard->getInsertMode() && !hasSelection())
+ LLColor4 text_color;
+ const LLFontGL* fontp;
+ if (segmentp)
{
- cursor_left += CURSOR_THICKNESS;
- const LLWString space(utf8str_to_wstring(std::string(" ")));
- F32 spacew = mGLFont->getWidthF32(space.c_str());
- if (mCursorPos == line_end)
- {
- cursor_right = cursor_left + spacew;
- }
- else
- {
- F32 width = mGLFont->getWidthF32(text.c_str(), mCursorPos, 1, mAllowEmbeddedItems);
- cursor_right = cursor_left + llmax(spacew, width);
- }
+ text_color = segmentp->getColor();
+ fontp = segmentp->getStyle()->getFont();
}
-
- gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
-
- gGL.color4fv( mCursorColor.mV );
-
- gl_rect_2d(llfloor(cursor_left), llfloor(cursor_top),
- llfloor(cursor_right), llfloor(cursor_bottom));
-
- if (LL_KIM_OVERWRITE == gKeyboard->getInsertMode() && !hasSelection() && text[mCursorPos] != '\n')
+ else if (mReadOnly)
{
- const LLTextSegment* segmentp = getSegmentAtOffset(mCursorPos);
- LLColor4 text_color;
- if (segmentp)
- {
- text_color = segmentp->getColor();
- }
- else if (mReadOnly)
- {
- text_color = mReadOnlyFgColor;
- }
- else
- {
- text_color = mFgColor;
- }
- mGLFont->render(text, mCursorPos, next_char_left, cursor_bottom + line_height,
- LLColor4(1.f - text_color.mV[VRED], 1.f - text_color.mV[VGREEN], 1.f - text_color.mV[VBLUE], 1.f),
- LLFontGL::LEFT, LLFontGL::TOP,
- LLFontGL::NORMAL,
- 1);
+ text_color = mReadOnlyFgColor.get();
+ fontp = mDefaultFont;
}
+ else
+ {
+ text_color = mFgColor.get();
+ fontp = mDefaultFont;
+ }
+ fontp->render(text, mCursorPos, cursor_rect.mLeft, cursor_rect.mBottom,
+ LLColor4(1.f - text_color.mV[VRED], 1.f - text_color.mV[VGREEN], 1.f - text_color.mV[VBLUE], 1.f),
+ LLFontGL::LEFT, LLFontGL::BOTTOM,
+ LLFontGL::NORMAL,
+ LLFontGL::NO_SHADOW,
+ 1);
+ }
- // Make sure the IME is in the right place
- LLRect screen_pos = getScreenRect();
- LLCoordGL ime_pos( screen_pos.mLeft + llfloor(cursor_left), screen_pos.mBottom + llfloor(cursor_top) );
+ // Make sure the IME is in the right place
+ LLRect screen_pos = calcScreenRect();
+ LLCoordGL ime_pos( screen_pos.mLeft + llfloor(cursor_rect.mLeft), screen_pos.mBottom + llfloor(cursor_rect.mTop) );
- ime_pos.mX = (S32) (ime_pos.mX * LLUI::sGLScaleFactor.mV[VX]);
- ime_pos.mY = (S32) (ime_pos.mY * LLUI::sGLScaleFactor.mV[VY]);
- getWindow()->setLanguageTextInput( ime_pos );
- }
+ ime_pos.mX = (S32) (ime_pos.mX * LLUI::sGLScaleFactor.mV[VX]);
+ ime_pos.mY = (S32) (ime_pos.mY * LLUI::sGLScaleFactor.mV[VY]);
+ getWindow()->setLanguageTextInput( ime_pos );
}
}
}
void LLTextEditor::drawPreeditMarker()
{
+ static LLUICachedControl<F32> preedit_marker_brightness ("UIPreeditMarkerBrightness", 0);
+ static LLUICachedControl<S32> preedit_marker_gap ("UIPreeditMarkerGap", 0);
+ static LLUICachedControl<S32> preedit_marker_position ("UIPreeditMarkerPosition", 0);
+ static LLUICachedControl<S32> preedit_marker_thickness ("UIPreeditMarkerThickness", 0);
+ static LLUICachedControl<F32> preedit_standout_brightness ("UIPreeditStandoutBrightness", 0);
+ static LLUICachedControl<S32> preedit_standout_gap ("UIPreeditStandoutGap", 0);
+ static LLUICachedControl<S32> preedit_standout_position ("UIPreeditStandoutPosition", 0);
+ static LLUICachedControl<S32> preedit_standout_thickness ("UIPreeditStandoutThickness", 0);
+
if (!hasPreeditString())
{
return;
}
- const llwchar *text = mWText.c_str();
+ const LLWString textString(getWText());
+ const llwchar *text = textString.c_str();
const S32 text_len = getLength();
const S32 num_lines = getLineCount();
- S32 cur_line = mScrollbar->getDocPos();
+ S32 cur_line = getFirstVisibleLine();
if (cur_line >= num_lines)
{
return;
}
- const S32 line_height = llround( mGLFont->getLineHeight() );
+ const S32 line_height = llround( mDefaultFont->getLineHeight() );
S32 line_start = getLineStart(cur_line);
S32 line_y = mTextRect.mTop - line_height;
@@ -2915,33 +3057,33 @@ void LLTextEditor::drawPreeditMarker()
S32 preedit_left = mTextRect.mLeft;
if (left > line_start)
{
- preedit_left += mGLFont->getWidth(text, line_start, left - line_start, mAllowEmbeddedItems);
+ preedit_left += mDefaultFont->getWidth(text, line_start, left - line_start);
}
S32 preedit_right = mTextRect.mLeft;
if (right < line_end)
{
- preedit_right += mGLFont->getWidth(text, line_start, right - line_start, mAllowEmbeddedItems);
+ preedit_right += mDefaultFont->getWidth(text, line_start, right - line_start);
}
else
{
- preedit_right += mGLFont->getWidth(text, line_start, line_end - line_start, mAllowEmbeddedItems);
+ preedit_right += mDefaultFont->getWidth(text, line_start, line_end - line_start);
}
if (mPreeditStandouts[i])
{
- gl_rect_2d(preedit_left + PREEDIT_STANDOUT_GAP,
- line_y + PREEDIT_STANDOUT_POSITION,
- preedit_right - PREEDIT_STANDOUT_GAP - 1,
- line_y + PREEDIT_STANDOUT_POSITION - PREEDIT_STANDOUT_THICKNESS,
- (mCursorColor * PREEDIT_STANDOUT_BRIGHTNESS + mWriteableBgColor * (1 - PREEDIT_STANDOUT_BRIGHTNESS)).setAlpha(1.0f));
+ gl_rect_2d(preedit_left + preedit_standout_gap,
+ line_y + preedit_standout_position,
+ preedit_right - preedit_standout_gap - 1,
+ line_y + preedit_standout_position - preedit_standout_thickness,
+ (mCursorColor.get() * preedit_standout_brightness + mWriteableBgColor.get() * (1 - preedit_standout_brightness)).setAlpha(1.0f));
}
else
{
- gl_rect_2d(preedit_left + PREEDIT_MARKER_GAP,
- line_y + PREEDIT_MARKER_POSITION,
- preedit_right - PREEDIT_MARKER_GAP - 1,
- line_y + PREEDIT_MARKER_POSITION - PREEDIT_MARKER_THICKNESS,
- (mCursorColor * PREEDIT_MARKER_BRIGHTNESS + mWriteableBgColor * (1 - PREEDIT_MARKER_BRIGHTNESS)).setAlpha(1.0f));
+ gl_rect_2d(preedit_left + preedit_marker_gap,
+ line_y + preedit_marker_position,
+ preedit_right - preedit_marker_gap - 1,
+ line_y + preedit_marker_position - preedit_marker_thickness,
+ (mCursorColor.get() * preedit_marker_brightness + mWriteableBgColor.get() * (1 - preedit_marker_brightness)).setAlpha(1.0f));
}
}
}
@@ -2956,9 +3098,12 @@ void LLTextEditor::drawPreeditMarker()
void LLTextEditor::drawText()
{
- const LLWString &text = mWText;
+ LLWString text = getWText();
const S32 text_len = getLength();
- if( text_len <= 0 ) return;
+ if( text_len <= 0 )
+ {
+ return;
+ }
S32 selection_left = -1;
S32 selection_right = -1;
// Draw selection even if we don't have keyboard focus for search/replace
@@ -2969,37 +3114,34 @@ void LLTextEditor::drawText()
}
LLGLSUIDefault gls_ui;
-
- // There are several concepts that are important for understanding the following drawing code.
- // The document is logically a sequence of characters (stored in a LLWString).
- // Variables below with "start" or "end" in their names refer to positions or offsets into it.
- // Next there are two kinds of "line" variables to understand. Newline characters in the
- // character sequence represent logical lines. These are what get numbered and so variables
- // representing this kind of line have "num" in their names.
- // The others represent line fragments or displayed lines which the scrollbar deals with.
- // When the "show line numbers" property is turned on, we draw line numbers to the left of the
- // beginning of each logical line and not in front of wrapped "continuation" display lines. -MG
-
- S32 cur_line = mScrollbar->getDocPos(); // scrollbar counts each wrap as a new line.
+ LLRect scrolled_view_rect = mScroller->getVisibleContentRect();
+ LLRect content_rect = mScroller->getContentWindowRect();
+ S32 first_line = getFirstVisibleLine();
S32 num_lines = getLineCount();
- if (cur_line >= num_lines) return;
- S32 line_start = getLineStart(cur_line);
- S32 prev_start = getLineStart(cur_line-1);
- S32 cur_line_num = getLineForPosition(line_start); // doesn't count wraps. i.e. only counts newlines.
- S32 prev_line_num = getLineForPosition(prev_start);
- BOOL cur_line_is_continuation = cur_line_num > 0 && cur_line_num == prev_line_num;
- BOOL line_wraps = FALSE;
-
- LLTextSegment t(line_start);
- segment_list_t::iterator seg_iter;
- seg_iter = std::upper_bound(mSegments.begin(), mSegments.end(), &t, LLTextSegment::compare());
- if (seg_iter == mSegments.end() || (*seg_iter)->getStart() > line_start) --seg_iter;
- LLTextSegment* cur_segment = *seg_iter;
+ if (first_line >= num_lines)
+ {
+ return;
+ }
- S32 line_height = llround( mGLFont->getLineHeight() );
- F32 text_y = (F32)(mTextRect.mTop - line_height);
- while((mTextRect.mBottom <= text_y) && (cur_line < num_lines))
+ S32 line_start = getLineStart(first_line);
+ // find first text segment that spans top of visible portion of text buffer
+ segment_set_t::iterator seg_iter = getSegIterContaining(line_start);
+ if (seg_iter == mSegments.end())
+ {
+ return;
+ }
+
+ LLTextSegmentPtr cur_segment = *seg_iter;
+
+ for (S32 cur_line = first_line; cur_line < num_lines; cur_line++)
{
+ line_info& line = mLineInfoList[cur_line];
+
+ if ((line.mTop - scrolled_view_rect.mBottom) < mTextRect.mBottom)
+ {
+ break;
+ }
+
S32 next_start = -1;
S32 line_end = text_len;
@@ -3008,37 +3150,17 @@ void LLTextEditor::drawText()
next_start = getLineStart(cur_line + 1);
line_end = next_start;
}
- line_wraps = text[line_end-1] != '\n';
- if ( ! line_wraps )
- {
- --line_end; // don't attempt to draw the newline char.
- }
-
- F32 text_start = (F32)mTextRect.mLeft;
- F32 text_x = text_start + (mShowLineNumbers ? UI_TEXTEDITOR_LINE_NUMBER_MARGIN : 0);
-
- // draw the line numbers
- if( mShowLineNumbers && !cur_line_is_continuation)
+ if ( text[line_end-1] == '\n' )
{
- const LLFontGL *num_font = LLFontGL::getFontMonospace();
- F32 y_top = text_y + ((F32)llround(num_font->getLineHeight()) / 2);
- const LLWString ltext = utf8str_to_wstring(llformat("%*d", UI_TEXTEDITOR_LINE_NUMBER_DIGITS, cur_line_num ));
- BOOL is_cur_line = getCurrentLine() == cur_line_num;
- const U8 style = is_cur_line ? LLFontGL::BOLD : LLFontGL::NORMAL;
- const LLColor4 fg_color = is_cur_line ? mCursorColor : mReadOnlyFgColor;
- num_font->render(
- ltext, // string to draw
- 0, // begin offset
- 3., // x
- y_top, // y
- fg_color,
- LLFontGL::LEFT, // horizontal alignment
- LLFontGL::VCENTER, // vertical alignment
- style,
- S32_MAX, // max chars
- UI_TEXTEDITOR_LINE_NUMBER_MARGIN); // max pixels
+ --line_end;
}
+ LLRect text_rect(mTextRect.mLeft - scrolled_view_rect.mLeft,
+ line.mTop - scrolled_view_rect.mBottom + mTextRect.mBottom,
+ mTextRect.getWidth() - scrolled_view_rect.mLeft,
+ line.mBottom - scrolled_view_rect.mBottom + mTextRect.mBottom);
+
+ // draw a single line of text
S32 seg_start = line_start;
while( seg_start < line_end )
{
@@ -3048,192 +3170,120 @@ void LLTextEditor::drawText()
if (seg_iter == mSegments.end())
{
llwarns << "Ran off the segmentation end!" << llendl;
+
return;
}
cur_segment = *seg_iter;
}
- // Draw a segment within the line
- S32 clipped_end = llmin( line_end, cur_segment->getEnd() );
- S32 clipped_len = clipped_end - seg_start;
- if( clipped_len > 0 )
- {
- LLStyleSP style = cur_segment->getStyle();
- if ( style->isImage() && (cur_segment->getStart() >= seg_start) && (cur_segment->getStart() <= clipped_end))
- {
- S32 style_image_height = style->mImageHeight;
- S32 style_image_width = style->mImageWidth;
- LLUIImagePtr image = style->getImage();
- image->draw(llround(text_x), llround(text_y)+line_height-style_image_height,
- style_image_width, style_image_height);
- }
-
- if (cur_segment == mHoverSegment && style->getIsEmbeddedItem())
- {
- style->mUnderline = TRUE;
- }
-
- S32 left_pos = llmin( mSelectionStart, mSelectionEnd );
-
- if ( (mParseHTML) && (left_pos > seg_start) && (left_pos < clipped_end) && mIsSelecting && (mSelectionStart == mSelectionEnd) )
- {
- mHTML = style->getLinkHREF();
- }
-
- drawClippedSegment( text, seg_start, clipped_end, text_x, text_y, selection_left, selection_right, style, &text_x );
+ S32 clipped_end = llmin( line_end, cur_segment->getEnd() ) - cur_segment->getStart();
+ text_rect.mLeft = (S32)(cur_segment->draw(seg_start - cur_segment->getStart(), clipped_end, selection_left, selection_right, text_rect));
- if( text_x == text_start && mShowLineNumbers )
- {
- text_x += UI_TEXTEDITOR_LINE_NUMBER_MARGIN;
- }
-
- // Note: text_x is incremented by drawClippedSegment()
- seg_start += clipped_len;
- }
+ seg_start = clipped_end + cur_segment->getStart();
}
- // move down one line
- text_y -= (F32)line_height;
-
- if( line_wraps )
- {
- cur_line_num--;
- }
- cur_line_is_continuation = line_wraps; // so as to not not number the continuation lines
-
line_start = next_start;
- cur_line++;
- cur_line_num++;
}
}
-// Draws a single text segment, reversing the color for selection if needed.
-void LLTextEditor::drawClippedSegment(const LLWString &text, S32 seg_start, S32 seg_end, F32 x, F32 y, S32 selection_left, S32 selection_right, const LLStyleSP& style, F32* right_x )
+void LLTextEditor::drawLineNumbers()
{
- if (!style->isVisible())
- {
- return;
- }
-
- const LLFontGL* font = mGLFont;
-
- LLColor4 color = style->getColor();
+ LLGLSUIDefault gls_ui;
- if ( style->getFontString()[0] )
+ LLRect scrolled_view_rect = mScroller->getVisibleContentRect();
+ LLRect content_rect = mScroller->getContentWindowRect();
+ LLLocalClipRect clip(content_rect);
+ S32 first_line = getFirstVisibleLine();
+ S32 num_lines = getLineCount();
+ if (first_line >= num_lines)
{
- font = LLResMgr::getInstance()->getRes(style->getFontID());
+ return;
}
-
- U8 font_flags = LLFontGL::NORMAL;
- if (style->mBold)
- {
- font_flags |= LLFontGL::BOLD;
- }
- if (style->mItalic)
- {
- font_flags |= LLFontGL::ITALIC;
- }
- if (style->mUnderline)
- {
- font_flags |= LLFontGL::UNDERLINE;
- }
+ S32 cursor_line = getCurrentLine();
- if (style->getIsEmbeddedItem())
+ if (mShowLineNumbers)
{
- if (mReadOnly)
- {
- color = LLUI::sColorsGroup->getColor("TextEmbeddedItemReadOnlyColor");
- }
- else
- {
- color = LLUI::sColorsGroup->getColor("TextEmbeddedItemColor");
- }
- }
+ S32 last_line_num = -1;
- F32 y_top = y + (F32)llround(font->getLineHeight());
+ for (S32 cur_line = first_line; cur_line < num_lines; cur_line++)
+ {
+ line_info& line = mLineInfoList[cur_line];
- if( selection_left > seg_start )
- {
- // Draw normally
- S32 start = seg_start;
- S32 end = llmin( selection_left, seg_end );
- S32 length = end - start;
- font->render(text, start, x, y_top, color, LLFontGL::LEFT, LLFontGL::TOP, font_flags, length, S32_MAX, right_x, mAllowEmbeddedItems);
- }
- x = *right_x;
-
- if( (selection_left < seg_end) && (selection_right > seg_start) )
- {
- // Draw reversed
- S32 start = llmax( selection_left, seg_start );
- S32 end = llmin( selection_right, seg_end );
- S32 length = end - start;
+ if ((line.mTop - scrolled_view_rect.mBottom) < mTextRect.mBottom)
+ {
+ break;
+ }
- font->render(text, start, x, y_top,
- LLColor4( 1.f - color.mV[0], 1.f - color.mV[1], 1.f - color.mV[2], 1.f ),
- LLFontGL::LEFT, LLFontGL::TOP, font_flags, length, S32_MAX, right_x, mAllowEmbeddedItems);
- }
- x = *right_x;
- if( selection_right < seg_end )
- {
- // Draw normally
- S32 start = llmax( selection_right, seg_start );
- S32 end = seg_end;
- S32 length = end - start;
- font->render(text, start, x, y_top, color, LLFontGL::LEFT, LLFontGL::TOP, font_flags, length, S32_MAX, right_x, mAllowEmbeddedItems);
+ S32 line_bottom = line.mBottom - scrolled_view_rect.mBottom + mTextRect.mBottom;
+ // draw the line numbers
+ if(line.mLineNum != last_line_num && line.mTop <= scrolled_view_rect.mTop)
+ {
+ const LLFontGL *num_font = LLFontGL::getFontMonospace();
+ const LLWString ltext = utf8str_to_wstring(llformat("%d", line.mLineNum ));
+ BOOL is_cur_line = cursor_line == line.mLineNum;
+ const U8 style = is_cur_line ? LLFontGL::BOLD : LLFontGL::NORMAL;
+ const LLColor4 fg_color = is_cur_line ? mCursorColor : mReadOnlyFgColor;
+ num_font->render(
+ ltext, // string to draw
+ 0, // begin offset
+ UI_TEXTEDITOR_LINE_NUMBER_MARGIN - 2, // x
+ line_bottom, // y
+ fg_color,
+ LLFontGL::RIGHT, // horizontal alignment
+ LLFontGL::BOTTOM, // vertical alignment
+ style,
+ LLFontGL::NO_SHADOW,
+ S32_MAX, // max chars
+ UI_TEXTEDITOR_LINE_NUMBER_MARGIN - 2); // max pixels
+ last_line_num = line.mLineNum;
+ }
+ }
}
- }
-
+}
void LLTextEditor::draw()
{
- // do on-demand reflow
- if (mReflowNeeded)
- {
- updateLineStartList();
- mReflowNeeded = FALSE;
- }
+ // reflow if needed, on demand
+ reflow();
// then update scroll position, as cursor may have moved
- if (mScrollNeeded)
- {
- updateScrollFromCursor();
- mScrollNeeded = FALSE;
- }
+ updateScrollFromCursor();
- {
- LLLocalClipRect clip(LLRect(0, getRect().getHeight(), getRect().getWidth() - (mScrollbar->getVisible() ? SCROLLBAR_SIZE : 0), 0));
-
- bindEmbeddedChars(mGLFont);
+ LLColor4 bg_color = mReadOnly
+ ? mReadOnlyBgColor.get()
+ : hasFocus()
+ ? mFocusBgColor.get()
+ : mWriteableBgColor.get();
- drawBackground();
- drawSelectionBackground();
- drawPreeditMarker();
- drawText();
- drawCursor();
+ mDocumentPanel->setBackgroundColor(bg_color);
- unbindEmbeddedChars(mGLFont);
+ drawChildren();
+ drawBackground(); //overlays scrolling panel bg
+ drawLineNumbers();
- //RN: the decision was made to always show the orange border for keyboard focus but do not put an insertion caret
- // when in readonly mode
- mBorder->setKeyboardFocusHighlight( gFocusMgr.getKeyboardFocus() == this);// && !mReadOnly);
+ {
+ LLLocalClipRect clip(mTextRect);
+ drawSelectionBackground();
+ drawPreeditMarker();
+ drawText();
+ drawCursor();
}
-
- LLView::draw(); // Draw children (scrollbar and border)
- // remember if we are supposed to be at the bottom of the buffer
- mScrolledToBottom = isScrolledToBottom();
+ //RN: the decision was made to always show the orange border for keyboard focus but do not put an insertion caret
+ // when in readonly mode
+ mBorder->setKeyboardFocusHighlight( hasFocus() );// && !mReadOnly);
}
-void LLTextEditor::onTabInto()
+S32 LLTextEditor::getFirstVisibleLine() const
{
- // selecting all on tabInto causes users to hit tab twice and replace their text with a tab character
- // theoretically, one could selectAll if mTabsToNextField is true, but we couldn't think of a use case
- // where you'd want to select all anyway
- // preserve insertion point when returning to the editor
- //selectAll();
+ LLRect visible_region = mScroller->getVisibleContentRect();
+
+ // binary search for line that starts before top of visible buffer
+ line_list_t::const_iterator iter = std::lower_bound(mLineInfoList.begin(), mLineInfoList.end(), visible_region.mTop, compare_bottom());
+
+ return iter - mLineInfoList.begin();
}
// virtual
@@ -3302,101 +3352,62 @@ S32 LLTextEditor::getPos( S32 line, S32 offset )
void LLTextEditor::changePage( S32 delta )
{
+ const S32 PIXEL_OVERLAP_ON_PAGE_CHANGE = 10;
+ if (delta == 0) return;
+
+ //RN: use pixel heights
S32 line, offset;
getLineAndOffset( mCursorPos, &line, &offset );
- // get desired x position to remember previous position
- S32 desired_x_pixel = mDesiredXPixel;
+ LLRect cursor_rect = getLocalRectFromDocIndex(mCursorPos);
- // allow one line overlap
- S32 page_size = mScrollbar->getPageSize() - 1;
if( delta == -1 )
{
- line = llmax( line - page_size, 0);
- setCursorPos(getPos( line, offset ));
- mScrollbar->setDocPos( mScrollbar->getDocPos() - page_size );
+ mScroller->pageUp(PIXEL_OVERLAP_ON_PAGE_CHANGE);
}
else
if( delta == 1 )
{
- setCursorPos(getPos( line + page_size, offset ));
- mScrollbar->setDocPos( mScrollbar->getDocPos() + page_size );
+ mScroller->pageDown(PIXEL_OVERLAP_ON_PAGE_CHANGE);
}
- // put desired position into remember-buffer after setCursorPos()
- mDesiredXPixel = desired_x_pixel;
-
- if (mOnScrollEndCallback && mOnScrollEndData && (mScrollbar->getDocPos() == mScrollbar->getDocPosMax()))
+ if (getLocalRectFromDocIndex(mCursorPos) == cursor_rect)
+ {
+ // cursor didn't change apparent position, so move to top or bottom of document, respectively
+ if (delta < 0)
+ {
+ startOfDoc();
+ }
+ else
+ {
+ endOfDoc();
+ }
+ }
+ else
{
- mOnScrollEndCallback(mOnScrollEndData);
+ setCursorAtLocalPos(cursor_rect.getCenterX(), cursor_rect.getCenterY(), true, false);
}
}
void LLTextEditor::changeLine( S32 delta )
{
- bindEmbeddedChars(mGLFont);
-
S32 line, offset;
getLineAndOffset( mCursorPos, &line, &offset );
- S32 line_start = getLineStart(line);
-
- // set desired x position to remembered previous position
- S32 desired_x_pixel = mDesiredXPixel;
- // if remembered position was reset (thus -1), calculate new one here
- if( desired_x_pixel == -1 )
- {
- desired_x_pixel = mGLFont->getWidth(mWText.c_str(), line_start, offset, mAllowEmbeddedItems );
- }
-
- S32 new_line = 0;
+ S32 new_line = line;
if( (delta < 0) && (line > 0 ) )
{
new_line = line - 1;
}
- else
- if( (delta > 0) && (line < (getLineCount() - 1)) )
+ else if( (delta > 0) && (line < (getLineCount() - 1)) )
{
new_line = line + 1;
}
- else
- {
- unbindEmbeddedChars(mGLFont);
- return;
- }
-
- S32 num_lines = getLineCount();
- S32 new_line_start = getLineStart(new_line);
- S32 new_line_end = getLength();
- if (new_line + 1 < num_lines)
- {
- new_line_end = getLineStart(new_line + 1) - 1;
- }
-
- S32 new_line_len = new_line_end - new_line_start;
-
- S32 new_offset;
- new_offset = mGLFont->charFromPixelOffset(mWText.c_str(), new_line_start,
- (F32)desired_x_pixel,
- (F32)mTextRect.getWidth(),
- new_line_len,
- mAllowEmbeddedItems);
- setCursorPos (getPos( new_line, new_offset ));
-
- // put desired position into remember-buffer after setCursorPos()
- mDesiredXPixel = desired_x_pixel;
- unbindEmbeddedChars(mGLFont);
-}
-
-BOOL LLTextEditor::isScrolledToTop()
-{
- return mScrollbar->isAtBeginning();
-}
+ LLRect visible_region = mScroller->getVisibleContentRect();
-BOOL LLTextEditor::isScrolledToBottom()
-{
- return mScrollbar->isAtEnd();
+ S32 new_cursor_pos = getDocIndexFromLocalCoord(mDesiredXPixel, mLineInfoList[new_line].mBottom + mTextRect.mBottom - visible_region.mBottom, TRUE);
+ setCursorPos(new_cursor_pos, true);
}
@@ -3413,32 +3424,11 @@ void LLTextEditor::setCursorAndScrollToEnd()
{
deselect();
endOfDoc();
- needsScroll();
}
void LLTextEditor::getLineAndColumnForPosition( S32 position, S32* line, S32* col, BOOL include_wordwrap )
{
- if( include_wordwrap )
- {
- getLineAndOffset( mCursorPos, line, col );
- }
- else
- {
- const LLWString &text = mWText;
- S32 line_count = 0;
- S32 line_start = 0;
- S32 i;
- for( i = 0; text[i] && (i < position); i++ )
- {
- if( '\n' == text[i] )
- {
- line_start = i + 1;
- line_count++;
- }
- }
- *line = line_count;
- *col = i - line_start;
- }
+ getLineAndOffset( mCursorPos, line, col, include_wordwrap );
}
void LLTextEditor::getCurrentLineAndColumn( S32* line, S32* col, BOOL include_wordwrap )
@@ -3474,64 +3464,39 @@ void LLTextEditor::endOfLine()
}
}
-void LLTextEditor::endOfDoc()
+void LLTextEditor::startOfDoc()
{
- mScrollbar->setDocPos(mScrollbar->getDocPosMax());
- mScrolledToBottom = true;
+ setCursorPos(0);
+}
- S32 len = getLength();
- if( len )
- {
- setCursorPos(len);
- }
- if (mOnScrollEndCallback && mOnScrollEndData && (mScrollbar->getDocPos() == mScrollbar->getDocPosMax()))
- {
- mOnScrollEndCallback(mOnScrollEndData);
- }
+void LLTextEditor::endOfDoc()
+{
+ setCursorPos(getLength());
}
// Sets the scrollbar from the cursor position
void LLTextEditor::updateScrollFromCursor()
{
- mScrollbar->setDocSize( getLineCount() );
-
if (mReadOnly)
{
// no cursor in read only mode
return;
}
- S32 line, offset;
- getLineAndOffset( mCursorPos, &line, &offset );
-
- S32 page_size = mScrollbar->getPageSize();
-
- if( line < mScrollbar->getDocPos() )
+ if (!mScrollNeeded)
{
- // scroll so that the cursor is at the top of the page
- mScrollbar->setDocPos( line );
- }
- else if( line >= mScrollbar->getDocPos() + page_size - 1 )
- {
- S32 new_pos = 0;
- if( line < mScrollbar->getDocSize() - 1 )
- {
- // scroll so that the cursor is one line above the bottom of the page,
- new_pos = line - page_size + 1;
- }
- else
- {
- // if there is less than a page of text remaining, scroll so that the cursor is at the bottom
- new_pos = mScrollbar->getDocPosMax();
- }
- mScrollbar->setDocPos( new_pos );
+ return;
}
+ mScrollNeeded = FALSE;
- // Check if we've scrolled to bottom for callback if asked for callback
- if (mOnScrollEndCallback && mOnScrollEndData && (mScrollbar->getDocPos() == mScrollbar->getDocPosMax()))
- {
- mOnScrollEndCallback(mOnScrollEndData);
- }
+ S32 line, offset;
+ getLineAndOffset( mCursorPos, &line, &offset );
+
+ // scroll so that the cursor is at the top of the page
+ LLRect scroller_doc_window = mScroller->getVisibleContentRect();
+ LLRect cursor_rect_doc = getLocalRectFromDocIndex(mCursorPos);
+ cursor_rect_doc.translate(scroller_doc_window.mLeft, scroller_doc_window.mBottom);
+ mScroller->scrollToShowRect(cursor_rect_doc, LLRect(0, scroller_doc_window.getHeight() - 5, scroller_doc_window.getWidth(), 5));
}
void LLTextEditor::reshape(S32 width, S32 height, BOOL called_from_parent)
@@ -3543,13 +3508,6 @@ void LLTextEditor::reshape(S32 width, S32 height, BOOL called_from_parent)
updateTextRect();
needsReflow();
-
- // propagate shape information to scrollbar
- mScrollbar->setDocSize( getLineCount() );
-
- S32 line_height = llround( mGLFont->getLineHeight() );
- S32 page_lines = mTextRect.getHeight() / line_height;
- mScrollbar->setPageSize( page_lines );
}
void LLTextEditor::autoIndent()
@@ -3561,7 +3519,7 @@ void LLTextEditor::autoIndent()
S32 space_count = 0;
S32 i;
- const LLWString &text = mWText;
+ LLWString text = getWText();
while( ' ' == text[line_start] )
{
space_count++;
@@ -3594,7 +3552,7 @@ void LLTextEditor::insertText(const std::string &new_text)
deleteSelection(TRUE);
}
- setCursorPos(mCursorPos + insert( mCursorPos, utf8str_to_wstring(new_text), FALSE ));
+ setCursorPos(mCursorPos + insert( mCursorPos, utf8str_to_wstring(new_text), FALSE, LLTextSegmentPtr() ));
needsReflow();
@@ -3615,17 +3573,23 @@ void LLTextEditor::appendColoredText(const std::string &new_text,
highlight->parseFullLineHighlights(new_text, &lcolor);
}
- LLStyleSP style(new LLStyle);
- style->setVisible(true);
- style->setColor(lcolor);
- style->setFontName(font_name);
- appendStyledText(new_text, allow_undo, prepend_newline, style);
+ LLStyle::Params style_params;
+ style_params.color = lcolor;
+ if (font_name.empty())
+ {
+ style_params.font = mDefaultFont;
+ }
+ else
+ {
+ style_params.font.name = font_name;
+ }
+ appendStyledText(new_text, allow_undo, prepend_newline, style_params);
}
void LLTextEditor::appendStyledText(const std::string &new_text,
bool allow_undo,
bool prepend_newline,
- LLStyleSP stylep)
+ const LLStyle::Params& style_params)
{
S32 part = (S32)LLTextParser::WHOLE;
if(mParseHTML)
@@ -3635,14 +3599,10 @@ void LLTextEditor::appendStyledText(const std::string &new_text,
std::string text = new_text;
while ( findHTML(text, &start, &end) )
{
- LLStyleSP html(new LLStyle);
- html->setVisible(true);
- html->setColor(mLinkColor);
- if (stylep)
- {
- html->setFontName(stylep->getFontString());
- }
- html->mUnderline = TRUE;
+ LLStyle::Params link_params = style_params;
+ link_params.color = mLinkColor;
+ link_params.font.style = "UNDERLINE";
+ link_params.link_href = text.substr(start,end-start);
if (start > 0)
{
@@ -3656,11 +3616,10 @@ void LLTextEditor::appendStyledText(const std::string &new_text,
part = (S32)LLTextParser::MIDDLE;
}
std::string subtext=text.substr(0,start);
- appendHighlightedText(subtext,allow_undo, prepend_newline, part, stylep);
+ appendHighlightedText(subtext,allow_undo, prepend_newline, part, style_params);
}
- html->setLinkHREF(text.substr(start,end-start));
- appendText(text.substr(start, end-start),allow_undo, prepend_newline, html);
+ appendText(text.substr(start, end-start),allow_undo, prepend_newline, link_params);
if (end < (S32)text.length())
{
text = text.substr(end,text.length() - end);
@@ -3673,11 +3632,11 @@ void LLTextEditor::appendStyledText(const std::string &new_text,
}
}
if (part != (S32)LLTextParser::WHOLE) part=(S32)LLTextParser::END;
- if (end < (S32)text.length()) appendHighlightedText(text,allow_undo, prepend_newline, part, stylep);
+ if (end < (S32)text.length()) appendHighlightedText(text,allow_undo, prepend_newline, part, style_params);
}
else
{
- appendHighlightedText(new_text, allow_undo, prepend_newline, part, stylep);
+ appendHighlightedText(new_text, allow_undo, prepend_newline, part, style_params);
}
}
@@ -3685,38 +3644,40 @@ void LLTextEditor::appendHighlightedText(const std::string &new_text,
bool allow_undo,
bool prepend_newline,
S32 highlight_part,
- LLStyleSP stylep)
+ const LLStyle::Params& style_params)
{
if (mParseHighlights)
{
LLTextParser* highlight = LLTextParser::getInstance();
- if (highlight && stylep)
+ if (highlight && !style_params.isDefault())
{
- LLSD pieces = highlight->parsePartialLineHighlights(new_text, stylep->getColor(), highlight_part);
+ LLStyle::Params highlight_params = style_params;
+
+ LLSD pieces = highlight->parsePartialLineHighlights(new_text, highlight_params.color(), highlight_part);
bool lprepend=prepend_newline;
for (S32 i=0;i<pieces.size();i++)
{
LLSD color_llsd = pieces[i]["color"];
LLColor4 lcolor;
lcolor.setValue(color_llsd);
- LLStyleSP lstylep(new LLStyle(*stylep));
- lstylep->setColor(lcolor);
+ highlight_params.color = lcolor;
if (i != 0 && (pieces.size() > 1) ) lprepend=FALSE;
- appendText((std::string)pieces[i]["text"], allow_undo, lprepend, lstylep);
+ appendText((std::string)pieces[i]["text"], allow_undo, lprepend, highlight_params);
}
return;
}
}
- appendText(new_text, allow_undo, prepend_newline, stylep);
+ appendText(new_text, allow_undo, prepend_newline, style_params);
}
// Appends new text to end of document
void LLTextEditor::appendText(const std::string &new_text, bool allow_undo, bool prepend_newline,
- const LLStyleSP stylep)
+ const LLStyle::Params& stylep)
{
+ if (new_text.empty()) return;
+
// Save old state
- BOOL was_scrolled_to_bottom = (mScrollbar->getDocPos() == mScrollbar->getDocPosMax());
S32 selection_start = mSelectionStart;
S32 selection_end = mSelectionEnd;
BOOL was_selecting = mIsSelecting;
@@ -3728,49 +3689,93 @@ void LLTextEditor::appendText(const std::string &new_text, bool allow_undo, bool
setCursorPos(old_length);
+ LLWString wide_text;
+
// Add carriage return if not first line
if (getLength() != 0
&& prepend_newline)
{
- std::string final_text = "\n";
- final_text += new_text;
- append(utf8str_to_wstring(final_text), TRUE);
+ wide_text = utf8str_to_wstring(std::string("\n") + new_text);
}
else
{
- append(utf8str_to_wstring(new_text), TRUE );
+ wide_text = utf8str_to_wstring(new_text);
}
- if (stylep)
+ LLTextSegmentPtr segmentp;
+ if (!stylep.isDefault())
{
S32 segment_start = old_length;
- S32 segment_end = getLength();
- LLTextSegment* segment = new LLTextSegment(stylep, segment_start, segment_end );
- mSegments.push_back(segment);
+ S32 segment_end = old_length + wide_text.size();
+ segmentp = new LLNormalTextSegment(new LLStyle(stylep), segment_start, segment_end, *this );
}
+
+ append(wide_text, TRUE, segmentp);
needsReflow();
// Set the cursor and scroll position
- // Maintain the scroll position unless the scroll was at the end of the doc (in which
- // case, move it to the new end of the doc) or unless the user was doing actively selecting
- if( was_scrolled_to_bottom && !was_selecting )
- {
- if( selection_start != selection_end )
- {
- // maintain an existing non-active selection
- mSelectionStart = selection_start;
- mSelectionEnd = selection_end;
- }
- endOfDoc();
- }
- else if( selection_start != selection_end )
+ if( selection_start != selection_end )
{
mSelectionStart = selection_start;
mSelectionEnd = selection_end;
+ mIsSelecting = was_selecting;
+ setCursorPos(cursor_pos);
+ }
+ else if( cursor_was_at_end )
+ {
+ setCursorPos(getLength());
+ }
+ else
+ {
+ setCursorPos(cursor_pos);
+ }
+
+ if( !allow_undo )
+ {
+ blockUndo();
+ }
+}
+
+
+void LLTextEditor::appendWidget(LLView* widget, const std::string &widget_text, bool allow_undo, bool prepend_newline)
+{
+ // Save old state
+ S32 selection_start = mSelectionStart;
+ S32 selection_end = mSelectionEnd;
+ BOOL was_selecting = mIsSelecting;
+ S32 cursor_pos = mCursorPos;
+ S32 old_length = getLength();
+ BOOL cursor_was_at_end = (mCursorPos == old_length);
+
+ deselect();
+
+ setCursorPos(old_length);
+
+ LLWString widget_wide_text;
+
+ // Add carriage return if not first line
+ if (getLength() != 0
+ && prepend_newline)
+ {
+ widget_wide_text = utf8str_to_wstring(std::string("\n") + widget_text);
+ }
+ else
+ {
+ widget_wide_text = utf8str_to_wstring(widget_text);
+ }
+ LLTextSegmentPtr segment = new LLInlineViewSegment(widget, old_length, old_length + widget_text.size());
+ append(widget_wide_text, FALSE, segment);
+ needsReflow();
+
+ // Set the cursor and scroll position
+ if( selection_start != selection_end )
+ {
+ mSelectionStart = selection_start;
+ mSelectionEnd = selection_end;
mIsSelecting = was_selecting;
setCursorPos(cursor_pos);
@@ -3797,53 +3802,165 @@ void LLTextEditor::removeTextFromEnd(S32 num_chars)
remove(getLength() - num_chars, num_chars, FALSE);
S32 len = getLength();
- mCursorPos = llclamp(mCursorPos, 0, len);
+ setCursorPos (llclamp(mCursorPos, 0, len));
mSelectionStart = llclamp(mSelectionStart, 0, len);
mSelectionEnd = llclamp(mSelectionEnd, 0, len);
- pruneSegments();
-
- // pruneSegments will invalidate mLineStartList.
- updateLineStartList();
+ reflow();
needsScroll();
}
///////////////////////////////////////////////////////////////////
// Returns change in number of characters in mWText
-S32 LLTextEditor::insertStringNoUndo(const S32 pos, const LLWString &wstr)
+S32 LLTextEditor::insertStringNoUndo(S32 pos, const LLWString &wstr, LLTextEditor::segment_vec_t* segments )
{
- S32 old_len = mWText.length(); // length() returns character length
+ LLWString text(getWText());
+ S32 old_len = text.length(); // length() returns character length
S32 insert_len = wstr.length();
- mWText.insert(pos, wstr);
- mTextIsUpToDate = FALSE;
+ pos = getEditableIndex(pos, true);
+
+ segment_set_t::iterator seg_iter = getSegIterContaining(pos);
+
+ LLTextSegmentPtr default_segment;
+
+ LLTextSegmentPtr segmentp;
+ if (seg_iter != mSegments.end())
+ {
+ segmentp = *seg_iter;
+ }
+ else
+ {
+ //segmentp = mSegments.back();
+ return pos;
+ }
+
+ if (segmentp->canEdit())
+ {
+ segmentp->setEnd(segmentp->getEnd() + insert_len);
+ if (seg_iter != mSegments.end())
+ {
+ ++seg_iter;
+ }
+ }
+ else
+ {
+ // create default editable segment to hold new text
+ default_segment = new LLNormalTextSegment( getDefaultStyle(), pos, pos + insert_len, *this);
+ }
+
+ // shift remaining segments to right
+ for(;seg_iter != mSegments.end(); ++seg_iter)
+ {
+ LLTextSegmentPtr segmentp = *seg_iter;
+ segmentp->setStart(segmentp->getStart() + insert_len);
+ segmentp->setEnd(segmentp->getEnd() + insert_len);
+ }
+
+ // insert new segments
+ if (segments)
+ {
+ if (default_segment.notNull())
+ {
+ // potentially overwritten by segments passed in
+ insertSegment(default_segment);
+ }
+ for (segment_vec_t::iterator seg_iter = segments->begin();
+ seg_iter != segments->end();
+ ++seg_iter)
+ {
+ LLTextSegment* segmentp = *seg_iter;
+ insertSegment(segmentp);
+ }
+ }
+
+ text.insert(pos, wstr);
+ getViewModel()->setDisplay(text);
if ( truncate() )
{
// The user's not getting everything he's hoping for
make_ui_sound("UISndBadKeystroke");
- insert_len = mWText.length() - old_len;
+ insert_len = getLength() - old_len;
}
+ onValueChange(pos, pos + insert_len);
+
return insert_len;
}
S32 LLTextEditor::removeStringNoUndo(S32 pos, S32 length)
{
- mWText.erase(pos, length);
- mTextIsUpToDate = FALSE;
+ LLWString text(getWText());
+ segment_set_t::iterator seg_iter = getSegIterContaining(pos);
+ while(seg_iter != mSegments.end())
+ {
+ LLTextSegmentPtr segmentp = *seg_iter;
+ S32 end = pos + length;
+ if (segmentp->getStart() < pos)
+ {
+ // deleting from middle of segment
+ if (segmentp->getEnd() > end)
+ {
+ segmentp->setEnd(segmentp->getEnd() - length);
+ }
+ // truncating segment
+ else
+ {
+ segmentp->setEnd(pos);
+ }
+ }
+ else if (segmentp->getStart() < end)
+ {
+ // deleting entire segment
+ if (segmentp->getEnd() <= end)
+ {
+ // remove segment
+ segmentp->unlinkFromDocument(this);
+ segment_set_t::iterator seg_to_erase(seg_iter++);
+ mSegments.erase(seg_to_erase);
+ continue;
+ }
+ // deleting head of segment
+ else
+ {
+ segmentp->setStart(pos);
+ segmentp->setEnd(segmentp->getEnd() - length);
+ }
+ }
+ else
+ {
+ // shifting segments backward to fill deleted portion
+ segmentp->setStart(segmentp->getStart() - length);
+ segmentp->setEnd(segmentp->getEnd() - length);
+ }
+ ++seg_iter;
+ }
+
+ text.erase(pos, length);
+ getViewModel()->setDisplay(text);
+
+ // recreate default segment in case we erased everything
+ createDefaultSegment();
+
+ onValueChange(pos, pos);
+
return -length; // This will be wrong if someone calls removeStringNoUndo with an excessive length
}
S32 LLTextEditor::overwriteCharNoUndo(S32 pos, llwchar wc)
{
- if (pos > (S32)mWText.length())
+ if (pos > (S32)getLength())
{
return 0;
}
- mWText[pos] = wc;
- mTextIsUpToDate = FALSE;
+ LLWString text(getWText());
+ text[pos] = wc;
+ getViewModel()->setDisplay(text);
+
+ onValueChange(pos, pos + 1);
+
return 1;
}
@@ -3912,18 +4029,27 @@ BOOL LLTextEditor::tryToRevertToPristineState()
void LLTextEditor::updateTextRect()
{
- mTextRect.setOriginAndSize(
- UI_TEXTEDITOR_BORDER + UI_TEXTEDITOR_H_PAD,
- UI_TEXTEDITOR_BORDER,
- getRect().getWidth() - SCROLLBAR_SIZE - 2 * (UI_TEXTEDITOR_BORDER + UI_TEXTEDITOR_H_PAD),
- getRect().getHeight() - 2 * UI_TEXTEDITOR_BORDER - UI_TEXTEDITOR_V_PAD_TOP );
+ static LLUICachedControl<S32> texteditor_border ("UITextEditorBorder", 0);
+ static LLUICachedControl<S32> texteditor_h_pad ("UITextEditorHPad", 0);
+
+ LLRect old_text_rect = mTextRect;
+ mTextRect = mScroller->getContentWindowRect();
+ mTextRect.stretch(texteditor_border * -1);
+ mTextRect.mLeft += texteditor_h_pad;
+ mTextRect.mLeft += mShowLineNumbers ? UI_TEXTEDITOR_LINE_NUMBER_MARGIN : 0;
+ if (mTextRect != old_text_rect)
+ {
+ needsReflow();
+ }
}
+LLFastTimer::DeclareTimer FTM_TEXT_EDITOR_LOAD_KEYWORD("Text Editor Load Keywords");
void LLTextEditor::loadKeywords(const std::string& filename,
const std::vector<std::string>& funcs,
const std::vector<std::string>& tooltips,
const LLColor3& color)
{
+ LLFastTimer ft(FTM_TEXT_EDITOR_LOAD_KEYWORD);
if(mKeywords.loadFromFile(filename))
{
S32 count = llmin(funcs.size(), tooltips.size());
@@ -3932,133 +4058,115 @@ void LLTextEditor::loadKeywords(const std::string& filename,
std::string name = utf8str_trim(funcs[i]);
mKeywords.addToken(LLKeywordToken::WORD, name, color, tooltips[i] );
}
+ segment_vec_t segment_list;
+ mKeywords.findSegments(&segment_list, getWText(), mDefaultColor.get(), *this);
- mKeywords.findSegments( &mSegments, mWText, mDefaultColor );
-
- llassert( mSegments.front()->getStart() == 0 );
- llassert( mSegments.back()->getEnd() == getLength() );
+ mSegments.clear();
+ segment_set_t::iterator insert_it = mSegments.begin();
+ for (segment_vec_t::iterator list_it = segment_list.begin(); list_it != segment_list.end(); ++list_it)
+ {
+ insert_it = mSegments.insert(insert_it, *list_it);
+ }
}
}
-void LLTextEditor::updateSegments()
+void LLTextEditor::createDefaultSegment()
{
- if (mKeywords.isLoaded())
- {
- // HACK: No non-ascii keywords for now
- mKeywords.findSegments(&mSegments, mWText, mDefaultColor);
- }
- else if (mAllowEmbeddedItems)
- {
- findEmbeddedItemSegments();
- }
-
- // Make sure we have at least one segment
- if (mSegments.size() == 1 && mSegments[0]->getIsDefault())
- {
- delete mSegments[0];
- mSegments.clear(); // create default segment
- }
+ // ensures that there is always at least one segment
if (mSegments.empty())
{
- LLColor4& text_color = ( mReadOnly ? mReadOnlyFgColor : mFgColor );
- LLTextSegment* default_segment = new LLTextSegment( text_color, 0, mWText.length() );
- default_segment->setIsDefault(TRUE);
- mSegments.push_back(default_segment);
+ LLTextSegmentPtr default_segment = new LLNormalTextSegment( getDefaultStyle(), 0, getLength() + 1, *this);
+ mSegments.insert(default_segment);
+ default_segment->linkToDocument(this);
}
}
-// Only effective if text was removed from the end of the editor
-// *NOTE: Using this will invalidate references to mSegments from mLineStartList.
-void LLTextEditor::pruneSegments()
+LLStyleSP LLTextEditor::getDefaultStyle()
{
- S32 len = mWText.length();
- // Find and update the first valid segment
- segment_list_t::iterator iter = mSegments.end();
- while(iter != mSegments.begin())
- {
- --iter;
- LLTextSegment* seg = *iter;
- if (seg->getStart() < len)
- {
- // valid segment
- if (seg->getEnd() > len)
- {
- seg->setEnd(len);
- }
- break; // done
- }
- }
- if (iter != mSegments.end())
- {
- // erase invalid segments
- ++iter;
- std::for_each(iter, mSegments.end(), DeletePointer());
- mSegments.erase(iter, mSegments.end());
- }
- else
- {
- llwarns << "Tried to erase end of empty LLTextEditor" << llendl;
- }
+ LLColor4 text_color = ( mReadOnly ? mReadOnlyFgColor.get() : mFgColor.get() );
+ return LLStyleSP(new LLStyle(LLStyle::Params().color(text_color).font(mDefaultFont)));
}
-void LLTextEditor::findEmbeddedItemSegments()
+LLFastTimer::DeclareTimer FTM_UPDATE_TEXT_SEGMENTS("Update Text Segments");
+void LLTextEditor::updateSegments()
{
- mHoverSegment = NULL;
- std::for_each(mSegments.begin(), mSegments.end(), DeletePointer());
- mSegments.clear();
-
- BOOL found_embedded_items = FALSE;
- const LLWString &text = mWText;
- S32 idx = 0;
- while( text[idx] )
+ LLFastTimer ft(FTM_UPDATE_TEXT_SEGMENTS);
+ if (mKeywords.isLoaded())
{
- if( text[idx] >= FIRST_EMBEDDED_CHAR && text[idx] <= LAST_EMBEDDED_CHAR )
- {
- found_embedded_items = TRUE;
- break;
+ // HACK: No non-ascii keywords for now
+ segment_vec_t segment_list;
+ mKeywords.findSegments(&segment_list, getWText(), mDefaultColor.get(), *this);
+
+ mSegments.clear();
+ segment_set_t::iterator insert_it = mSegments.begin();
+ for (segment_vec_t::iterator list_it = segment_list.begin(); list_it != segment_list.end(); ++list_it)
+ {
+ insert_it = mSegments.insert(insert_it, *list_it);
}
- ++idx;
}
- if( !found_embedded_items )
+ createDefaultSegment();
+
+}
+
+void LLTextEditor::insertSegment(LLTextSegmentPtr segment_to_insert)
+{
+ if (segment_to_insert.isNull())
{
return;
}
- S32 text_len = text.length();
-
- BOOL in_text = FALSE;
-
- LLColor4& text_color = ( mReadOnly ? mReadOnlyFgColor : mFgColor );
+ segment_set_t::iterator cur_seg_iter = getSegIterContaining(segment_to_insert->getStart());
- if( idx > 0 )
+ if (cur_seg_iter == mSegments.end())
{
- mSegments.push_back( new LLTextSegment( text_color, 0, text_len ) ); // text
- in_text = TRUE;
+ mSegments.insert(segment_to_insert);
+ segment_to_insert->linkToDocument(this);
}
-
- LLStyleSP embedded_style(new LLStyle);
- embedded_style->setIsEmbeddedItem( TRUE );
-
- // Start with i just after the first embedded item
- while ( text[idx] )
+ else
{
- if( text[idx] >= FIRST_EMBEDDED_CHAR && text[idx] <= LAST_EMBEDDED_CHAR )
+ LLTextSegmentPtr cur_segmentp = *cur_seg_iter;
+ if (cur_segmentp->getStart() < segment_to_insert->getStart())
{
- if( in_text )
- {
- mSegments.back()->setEnd( idx );
- }
- mSegments.push_back( new LLTextSegment( embedded_style, idx, idx + 1 ) ); // item
- in_text = FALSE;
+ S32 old_segment_end = cur_segmentp->getEnd();
+ // split old at start point for new segment
+ cur_segmentp->setEnd(segment_to_insert->getStart());
+ // advance to next segment
+ ++cur_seg_iter;
+ // insert remainder of old segment
+ LLTextSegmentPtr remainder_segment = new LLNormalTextSegment( cur_segmentp->getStyle(), segment_to_insert->getStart(), old_segment_end, *this);
+ cur_seg_iter = mSegments.insert(cur_seg_iter, remainder_segment);
+ remainder_segment->linkToDocument(this);
+ // insert new segment before remainder of old segment
+ cur_seg_iter = mSegments.insert(cur_seg_iter, segment_to_insert);
+
+ segment_to_insert->linkToDocument(this);
+ // move to "remanider" segment and start truncation there
+ ++cur_seg_iter;
}
else
- if( !in_text )
{
- mSegments.push_back( new LLTextSegment( text_color, idx, text_len ) ); // text
- in_text = TRUE;
+ cur_seg_iter = mSegments.insert(cur_seg_iter, segment_to_insert);
+ ++cur_seg_iter;
+ segment_to_insert->linkToDocument(this);
+ }
+
+ // now delete/truncate remaining segments as necessary
+ while(cur_seg_iter != mSegments.end())
+ {
+ cur_segmentp = *cur_seg_iter;
+ if (cur_segmentp->getEnd() <= segment_to_insert->getEnd())
+ {
+ cur_segmentp->unlinkFromDocument(this);
+ segment_set_t::iterator seg_to_erase(cur_seg_iter++);
+ mSegments.erase(seg_to_erase);
+ }
+ else
+ {
+ cur_segmentp->setStart(segment_to_insert->getEnd());
+ break;
+ }
}
- ++idx;
}
}
@@ -4072,9 +4180,9 @@ BOOL LLTextEditor::handleMouseUpOverSegment(S32 x, S32 y, MASK mask)
if (mParseHTML && mHTML.length() > 0)
{
//Special handling for slurls
- if ( (mSecondlifeURLcallback!=NULL) && !(*mSecondlifeURLcallback)(mHTML) )
+ if ( (sSecondlifeURLcallback!=NULL) && !(*sSecondlifeURLcallback)(mHTML) )
{
- if (mURLcallback!=NULL) (*mURLcallback)(mHTML);
+ if (sURLcallback!=NULL) (*sURLcallback)(mHTML);
}
mHTML.clear();
}
@@ -4085,44 +4193,37 @@ BOOL LLTextEditor::handleMouseUpOverSegment(S32 x, S32 y, MASK mask)
// Finds the text segment (if any) at the give local screen position
-const LLTextSegment* LLTextEditor::getSegmentAtLocalPos( S32 x, S32 y ) const
+LLTextSegmentPtr LLTextEditor::getSegmentAtLocalPos( S32 x, S32 y )
{
// Find the cursor position at the requested local screen position
- S32 offset = getCursorPosFromLocalCoord( x, y, FALSE );
- S32 idx = getSegmentIdxAtOffset(offset);
- return idx >= 0 ? mSegments[idx] : NULL;
-}
-
-const LLTextSegment* LLTextEditor::getSegmentAtOffset(S32 offset) const
-{
- S32 idx = getSegmentIdxAtOffset(offset);
- return idx >= 0 ? mSegments[idx] : NULL;
-}
-
-S32 LLTextEditor::getSegmentIdxAtOffset(S32 offset) const
-{
- if (mSegments.empty() || offset < 0 || offset >= getLength())
+ S32 offset = getDocIndexFromLocalCoord( x, y, FALSE );
+ segment_set_t::iterator seg_iter = getSegIterContaining(offset);
+ if (seg_iter != mSegments.end())
{
- return -1;
+ return *seg_iter;
}
else
{
- S32 segidx, segoff;
- getSegmentAndOffset(offset, &segidx, &segoff);
- return segidx;
+ return LLTextSegmentPtr();
}
}
-void LLTextEditor::onMouseCaptureLost()
+LLTextEditor::segment_set_t::iterator LLTextEditor::getSegIterContaining(S32 index)
{
- endSelection();
+ segment_set_t::iterator it = mSegments.upper_bound(new LLIndexSegment(index));
+ return it;
}
-void LLTextEditor::setOnScrollEndCallback(void (*callback)(void*), void* userdata)
+LLTextEditor::segment_set_t::const_iterator LLTextEditor::getSegIterContaining(S32 index) const
+{
+ LLTextEditor::segment_set_t::const_iterator it = mSegments.upper_bound(new LLIndexSegment(index));
+ return it;
+}
+
+
+void LLTextEditor::onMouseCaptureLost()
{
- mOnScrollEndCallback = callback;
- mOnScrollEndData = userdata;
- mScrollbar->setOnScrollEndCallback(callback, userdata);
+ endSelection();
}
///////////////////////////////////////////////////////////////////
@@ -4208,7 +4309,7 @@ BOOL LLTextEditor::importBuffer(const char* buffer, S32 length )
delete[] text;
- setCursorPos(0);
+ startOfDoc();
deselect();
needsReflow();
@@ -4222,178 +4323,13 @@ BOOL LLTextEditor::exportBuffer(std::string &buffer )
outstream << "Linden text version 1\n";
outstream << "{\n";
- outstream << llformat("Text length %d\n", mWText.length() );
+ outstream << llformat("Text length %d\n", getLength() );
outstream << getText();
outstream << "}\n";
return TRUE;
}
-//////////////////////////////////////////////////////////////////////////
-// LLTextSegment
-
-LLTextSegment::LLTextSegment(S32 start) :
- mStart(start),
- mEnd(0),
- mToken(NULL),
- mIsDefault(FALSE)
-{
-}
-LLTextSegment::LLTextSegment( const LLStyleSP& style, S32 start, S32 end ) :
- mStyle( style ),
- mStart( start),
- mEnd( end ),
- mToken(NULL),
- mIsDefault(FALSE)
-{
-}
-LLTextSegment::LLTextSegment( const LLColor4& color, S32 start, S32 end, BOOL is_visible) :
- mStyle(new LLStyle(is_visible,color,LLStringUtil::null)),
- mStart( start),
- mEnd( end ),
- mToken(NULL),
- mIsDefault(FALSE)
-{
-}
-LLTextSegment::LLTextSegment( const LLColor4& color, S32 start, S32 end ) :
- mStyle(new LLStyle(TRUE, color,LLStringUtil::null )),
- mStart( start),
- mEnd( end ),
- mToken(NULL),
- mIsDefault(FALSE)
-{
-}
-LLTextSegment::LLTextSegment( const LLColor3& color, S32 start, S32 end ) :
- mStyle(new LLStyle(TRUE, color,LLStringUtil::null )),
- mStart( start),
- mEnd( end ),
- mToken(NULL),
- mIsDefault(FALSE)
-{
-}
-
-BOOL LLTextSegment::getToolTip(std::string& msg) const
-{
- if (mToken && !mToken->getToolTip().empty())
- {
- const LLWString& wmsg = mToken->getToolTip();
- msg = wstring_to_utf8str(wmsg);
- return TRUE;
- }
- return FALSE;
-}
-
-
-
-void LLTextSegment::dump() const
-{
- llinfos << "Segment [" <<
-// mColor.mV[VX] << ", " <<
-// mColor.mV[VY] << ", " <<
-// mColor.mV[VZ] << "]\t[" <<
- mStart << ", " <<
- getEnd() << "]" <<
- llendl;
-
-}
-
-// virtual
-LLXMLNodePtr LLTextEditor::getXML(bool save_children) const
-{
- LLXMLNodePtr node = LLUICtrl::getXML();
-
- // Attributes
-
- node->createChild("max_length", TRUE)->setIntValue(getMaxLength());
- node->createChild("embedded_items", TRUE)->setBoolValue(mAllowEmbeddedItems);
- node->createChild("font", TRUE)->setStringValue(LLFontGL::nameFromFont(mGLFont));
- node->createChild("word_wrap", TRUE)->setBoolValue(mWordWrap);
- node->createChild("hide_scrollbar", TRUE)->setBoolValue(mHideScrollbarForShortDocs);
-
- addColorXML(node, mCursorColor, "cursor_color", "TextCursorColor");
- addColorXML(node, mFgColor, "text_color", "TextFgColor");
- addColorXML(node, mDefaultColor, "text_default_color", "TextDefaultColor");
- addColorXML(node, mReadOnlyFgColor, "text_readonly_color", "TextFgReadOnlyColor");
- addColorXML(node, mReadOnlyBgColor, "bg_readonly_color", "TextBgReadOnlyColor");
- addColorXML(node, mWriteableBgColor, "bg_writeable_color", "TextBgWriteableColor");
- addColorXML(node, mFocusBgColor, "bg_focus_color", "TextBgFocusColor");
-
- // Contents
- node->setStringValue(getText());
-
- return node;
-}
-
-// static
-LLView* LLTextEditor::fromXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFactory *factory)
-{
- std::string name("text_editor");
- node->getAttributeString("name", name);
-
- LLRect rect;
- createRect(node, rect, parent, LLRect());
-
- U32 max_text_length = 255;
- node->getAttributeU32("max_length", max_text_length);
-
- BOOL allow_embedded_items;
- node->getAttributeBOOL("embedded_items", allow_embedded_items);
-
- LLFontGL* font = LLView::selectFont(node);
-
- std::string text = node->getTextContents().substr(0, max_text_length - 1);
-
- LLTextEditor* text_editor = new LLTextEditor(name,
- rect,
- max_text_length,
- text,
- font,
- allow_embedded_items);
-
- text_editor->setTextEditorParameters(node);
-
- BOOL hide_scrollbar = FALSE;
- node->getAttributeBOOL("hide_scrollbar",hide_scrollbar);
- text_editor->setHideScrollbarForShortDocs(hide_scrollbar);
-
- text_editor->initFromXML(node, parent);
-
- return text_editor;
-}
-
-void LLTextEditor::setTextEditorParameters(LLXMLNodePtr node)
-{
- BOOL word_wrap = FALSE;
- node->getAttributeBOOL("word_wrap", word_wrap);
- setWordWrap(word_wrap);
-
- node->getAttributeBOOL("show_line_numbers", mShowLineNumbers);
-
- node->getAttributeBOOL("track_bottom", mTrackBottom);
-
- LLColor4 color;
- if (LLUICtrlFactory::getAttributeColor(node,"cursor_color", color))
- {
- setCursorColor(color);
- }
- if(LLUICtrlFactory::getAttributeColor(node,"text_color", color))
- {
- setFgColor(color);
- }
- if(LLUICtrlFactory::getAttributeColor(node,"text_readonly_color", color))
- {
- setReadOnlyFgColor(color);
- }
- if(LLUICtrlFactory::getAttributeColor(node,"bg_readonly_color", color))
- {
- setReadOnlyBgColor(color);
- }
- if(LLUICtrlFactory::getAttributeColor(node,"bg_writeable_color", color))
- {
- setWriteableBgColor(color);
- }
-}
-
///////////////////////////////////////////////////////////////////
// Refactoring note: We may eventually want to replace this with boost::regex or
// boost::tokenizer capabilities since we've already fixed at least two JIRAs
@@ -4559,13 +4495,19 @@ BOOL LLTextEditor::findHTML(const std::string &line, S32 *begin, S32 *end) const
void LLTextEditor::updateAllowingLanguageInput()
{
+ LLWindow* window = getWindow();
+ if (!window)
+ {
+ // test app, no window available
+ return;
+ }
if (hasFocus() && !mReadOnly)
{
- getWindow()->allowLanguageTextInput(this, TRUE);
+ window->allowLanguageTextInput(this, TRUE);
}
else
{
- getWindow()->allowLanguageTextInput(this, FALSE);
+ window->allowLanguageTextInput(this, FALSE);
}
}
@@ -4586,7 +4528,7 @@ void LLTextEditor::resetPreedit()
deselect();
}
- mCursorPos = mPreeditPositions.front();
+ setCursorPos(mPreeditPositions.front());
removeStringNoUndo(mCursorPos, mPreeditPositions.back() - mCursorPos);
insertStringNoUndo(mCursorPos, mPreeditOverwrittenWString);
@@ -4670,7 +4612,7 @@ BOOL LLTextEditor::getPreeditLocation(S32 query_offset, LLCoordGL *coord, LLRect
return FALSE;
}
- const S32 first_visible_line = mScrollbar->getDocPos();
+ const S32 first_visible_line = getFirstVisibleLine();
if (query < getLineStart(first_visible_line))
{
return FALSE;
@@ -4694,12 +4636,13 @@ BOOL LLTextEditor::getPreeditLocation(S32 query_offset, LLCoordGL *coord, LLRect
current_line++;
}
- const llwchar * const text = mWText.c_str();
- const S32 line_height = llround(mGLFont->getLineHeight());
+ const LLWString textString(getWText());
+ const llwchar * const text = textString.c_str();
+ const S32 line_height = llround(mDefaultFont->getLineHeight());
if (coord)
{
- const S32 query_x = mTextRect.mLeft + mGLFont->getWidth(text, current_line_start, query - current_line_start, mAllowEmbeddedItems);
+ const S32 query_x = mTextRect.mLeft + mDefaultFont->getWidth(text, current_line_start, query - current_line_start);
const S32 query_y = mTextRect.mTop - (current_line - first_visible_line) * line_height - line_height / 2;
S32 query_screen_x, query_screen_y;
localPointToScreen(query_x, query_y, &query_screen_x, &query_screen_y);
@@ -4711,17 +4654,17 @@ BOOL LLTextEditor::getPreeditLocation(S32 query_offset, LLCoordGL *coord, LLRect
S32 preedit_left = mTextRect.mLeft;
if (preedit_left_position > current_line_start)
{
- preedit_left += mGLFont->getWidth(text, current_line_start, preedit_left_position - current_line_start, mAllowEmbeddedItems);
+ preedit_left += mDefaultFont->getWidth(text, current_line_start, preedit_left_position - current_line_start);
}
S32 preedit_right = mTextRect.mLeft;
if (preedit_right_position < current_line_end)
{
- preedit_right += mGLFont->getWidth(text, current_line_start, preedit_right_position - current_line_start, mAllowEmbeddedItems);
+ preedit_right += mDefaultFont->getWidth(text, current_line_start, preedit_right_position - current_line_start);
}
else
{
- preedit_right += mGLFont->getWidth(text, current_line_start, current_line_end - current_line_start, mAllowEmbeddedItems);
+ preedit_right += mDefaultFont->getWidth(text, current_line_start, current_line_end - current_line_start);
}
const S32 preedit_top = mTextRect.mTop - (current_line - first_visible_line) * line_height;
@@ -4772,7 +4715,7 @@ void LLTextEditor::markAsPreedit(S32 position, S32 length)
{
llwarns << "markAsPreedit invoked when hasPreeditString is true." << llendl;
}
- mPreeditWString = LLWString( mWText, position, length );
+ mPreeditWString = LLWString( getWText(), position, length );
if (length > 0)
{
mPreeditPositions.resize(2);
@@ -4798,5 +4741,267 @@ void LLTextEditor::markAsPreedit(S32 position, S32 length)
S32 LLTextEditor::getPreeditFontSize() const
{
- return llround(mGLFont->getLineHeight() * LLUI::sGLScaleFactor.mV[VY]);
+ return llround(mDefaultFont->getLineHeight() * LLUI::sGLScaleFactor.mV[VY]);
+}
+
+LLWString LLTextEditor::getWText() const
+{
+ return getViewModel()->getDisplay();
+}
+
+void LLTextEditor::onValueChange(S32 start, S32 end)
+{
+}
+
+//
+// LLTextSegment
+//
+
+LLTextSegment::~LLTextSegment()
+{}
+
+S32 LLTextSegment::getWidth(S32 first_char, S32 num_chars) const { return 0; }
+S32 LLTextSegment::getOffset(S32 segment_local_x_coord, S32 start_offset, S32 num_chars, bool round) const { return 0; }
+S32 LLTextSegment::getNumChars(S32 num_pixels, S32 segment_offset, S32 line_offset, S32 max_chars) const { return 0; }
+void LLTextSegment::updateLayout(const LLTextEditor& editor) {}
+F32 LLTextSegment::draw(S32 start, S32 end, S32 selection_start, S32 selection_end, const LLRect& draw_rect) { return draw_rect.mLeft; }
+S32 LLTextSegment::getMaxHeight() const { return 0; }
+bool LLTextSegment::canEdit() const { return false; }
+void LLTextSegment::unlinkFromDocument(LLTextEditor*) {}
+void LLTextSegment::linkToDocument(LLTextEditor*) {}
+void LLTextSegment::setHasMouseHover(bool hover) {}
+const LLColor4& LLTextSegment::getColor() const { return LLColor4::white; }
+void LLTextSegment::setColor(const LLColor4 &color) {}
+const LLStyleSP LLTextSegment::getStyle() const {static LLStyleSP sp(new LLStyle()); return sp; }
+void LLTextSegment::setStyle(const LLStyleSP &style) {}
+void LLTextSegment::setToken( LLKeywordToken* token ) {}
+LLKeywordToken* LLTextSegment::getToken() const { return NULL; }
+BOOL LLTextSegment::getToolTip( std::string& msg ) const { return FALSE; }
+void LLTextSegment::dump() const {}
+
+
+//
+// LLNormalTextSegment
+//
+
+LLNormalTextSegment::LLNormalTextSegment( const LLStyleSP& style, S32 start, S32 end, LLTextEditor& editor )
+: LLTextSegment(start, end),
+ mStyle( style ),
+ mToken(NULL),
+ mHasMouseHover(false),
+ mEditor(editor)
+{
+ mMaxHeight = llceil(mStyle->getFont()->getLineHeight());
+}
+
+LLNormalTextSegment::LLNormalTextSegment( const LLColor4& color, S32 start, S32 end, LLTextEditor& editor, BOOL is_visible)
+: LLTextSegment(start, end),
+ mToken(NULL),
+ mHasMouseHover(false),
+ mEditor(editor)
+{
+ mStyle = new LLStyle(LLStyle::Params().visible(is_visible).color(color));
+
+ mMaxHeight = llceil(mStyle->getFont()->getLineHeight());
+}
+
+F32 LLNormalTextSegment::draw(S32 start, S32 end, S32 selection_start, S32 selection_end, const LLRect& draw_rect)
+{
+ if( end - start > 0 )
+ {
+ if ( mStyle->isImage() && (start >= 0) && (end <= mEnd - mStart))
+ {
+ S32 style_image_height = mStyle->mImageHeight;
+ S32 style_image_width = mStyle->mImageWidth;
+ LLUIImagePtr image = mStyle->getImage();
+ image->draw(draw_rect.mLeft, draw_rect.mTop-style_image_height,
+ style_image_width, style_image_height);
+ }
+
+ return drawClippedSegment( getStart() + start, getStart() + end, selection_start, selection_end, draw_rect.mLeft, draw_rect.mBottom);
+ }
+ return draw_rect.mLeft;
+}
+
+// Draws a single text segment, reversing the color for selection if needed.
+F32 LLNormalTextSegment::drawClippedSegment(S32 seg_start, S32 seg_end, S32 selection_start, S32 selection_end, F32 x, F32 y)
+{
+ const LLWString &text = mEditor.getWText();
+
+ F32 right_x = x;
+ if (!mStyle->isVisible())
+ {
+ return right_x;
+ }
+
+ const LLFontGL* font = mStyle->getFont();
+
+ LLColor4 color = mStyle->getColor();
+
+ font = mStyle->getFont();
+
+ if( selection_start > seg_start )
+ {
+ // Draw normally
+ S32 start = seg_start;
+ S32 end = llmin( selection_start, seg_end );
+ S32 length = end - start;
+ font->render(text, start, x, y, color, LLFontGL::LEFT, LLFontGL::BOTTOM, 0, LLFontGL::NO_SHADOW, length, S32_MAX, &right_x, mEditor.allowsEmbeddedItems());
+ }
+ x = right_x;
+
+ if( (selection_start < seg_end) && (selection_end > seg_start) )
+ {
+ // Draw reversed
+ S32 start = llmax( selection_start, seg_start );
+ S32 end = llmin( selection_end, seg_end );
+ S32 length = end - start;
+
+ font->render(text, start, x, y,
+ LLColor4( 1.f - color.mV[0], 1.f - color.mV[1], 1.f - color.mV[2], 1.f ),
+ LLFontGL::LEFT, LLFontGL::BOTTOM, 0, LLFontGL::NO_SHADOW, length, S32_MAX, &right_x, mEditor.allowsEmbeddedItems());
+ }
+ x = right_x;
+ if( selection_end < seg_end )
+ {
+ // Draw normally
+ S32 start = llmax( selection_end, seg_start );
+ S32 end = seg_end;
+ S32 length = end - start;
+ font->render(text, start, x, y, color, LLFontGL::LEFT, LLFontGL::BOTTOM, 0, LLFontGL::NO_SHADOW, length, S32_MAX, &right_x, mEditor.allowsEmbeddedItems());
+ }
+ return right_x;
+}
+
+S32 LLNormalTextSegment::getMaxHeight() const
+{
+ return mMaxHeight;
+}
+
+BOOL LLNormalTextSegment::getToolTip(std::string& msg) const
+{
+ if (mToken && !mToken->getToolTip().empty())
+ {
+ const LLWString& wmsg = mToken->getToolTip();
+ msg = wstring_to_utf8str(wmsg);
+ return TRUE;
+ }
+ return FALSE;
+}
+
+
+S32 LLNormalTextSegment::getWidth(S32 first_char, S32 num_chars) const
+{
+ LLWString text = mEditor.getWText();
+ return mStyle->getFont()->getWidth(text.c_str(), mStart + first_char, num_chars);
+}
+
+S32 LLNormalTextSegment::getOffset(S32 segment_local_x_coord, S32 start_offset, S32 num_chars, bool round) const
+{
+ LLWString text = mEditor.getWText();
+ return mStyle->getFont()->charFromPixelOffset(text.c_str(), mStart + start_offset,
+ (F32)segment_local_x_coord,
+ F32_MAX,
+ num_chars,
+ round);
+}
+
+S32 LLNormalTextSegment::getNumChars(S32 num_pixels, S32 segment_offset, S32 line_offset, S32 max_chars) const
+{
+ LLWString text = mEditor.getWText();
+ S32 num_chars = mStyle->getFont()->maxDrawableChars(text.c_str() + segment_offset + mStart,
+ (F32)num_pixels,
+ max_chars,
+ mEditor.getWordWrap());
+
+ if (num_chars == 0
+ && line_offset == 0
+ && max_chars > 0)
+ {
+ // If at the beginning of a line, and a single character won't fit, draw it anyway
+ num_chars = 1;
+ }
+ if (mStart + segment_offset + num_chars == mEditor.getLength())
+ {
+ // include terminating NULL
+ num_chars++;
+ }
+ return num_chars;
+}
+
+void LLNormalTextSegment::dump() const
+{
+ llinfos << "Segment [" <<
+// mColor.mV[VX] << ", " <<
+// mColor.mV[VY] << ", " <<
+// mColor.mV[VZ] << "]\t[" <<
+ mStart << ", " <<
+ getEnd() << "]" <<
+ llendl;
+}
+
+//
+// LLInlineViewSegment
+//
+
+LLInlineViewSegment::LLInlineViewSegment(LLView* view, S32 start, S32 end)
+: LLTextSegment(start, end),
+ mView(view)
+{
+}
+
+LLInlineViewSegment::~LLInlineViewSegment()
+{
+ mView->die();
+}
+
+S32 LLInlineViewSegment::getWidth(S32 first_char, S32 num_chars) const
+{
+ if (first_char == 0 && num_chars == 0)
+ {
+ return 0;
+ }
+ else
+ {
+ return mView->getRect().getWidth();
+ }
+}
+
+S32 LLInlineViewSegment::getNumChars(S32 num_pixels, S32 segment_offset, S32 line_offset, S32 max_chars) const
+{
+ if (line_offset != 0 && num_pixels < mView->getRect().getWidth())
+ {
+ return 0;
+ }
+ else
+ {
+ return mEnd - mStart;
+ }
+}
+
+void LLInlineViewSegment::updateLayout(const LLTextEditor& editor)
+{
+ LLRect start_rect = editor.getLocalRectFromDocIndex(mStart);
+ LLRect doc_rect = editor.getDocumentPanel()->getRect();
+ mView->setOrigin(doc_rect.mLeft + start_rect.mLeft, doc_rect.mBottom + start_rect.mBottom);
+}
+
+F32 LLInlineViewSegment::draw(S32 start, S32 end, S32 selection_start, S32 selection_end, const LLRect& draw_rect)
+{
+ return (F32)(draw_rect.mLeft + mView->getRect().getWidth());
+}
+
+S32 LLInlineViewSegment::getMaxHeight() const
+{
+ return mView->getRect().getHeight();
+}
+
+void LLInlineViewSegment::unlinkFromDocument(LLTextEditor* editor)
+{
+ editor->removeDocumentChild(mView);
+}
+
+void LLInlineViewSegment::linkToDocument(LLTextEditor* editor)
+{
+ editor->addDocumentChild(mView);
}
diff --git a/indra/llui/lltexteditor.h b/indra/llui/lltexteditor.h
index 9291e1c436..67c67d0f67 100644
--- a/indra/llui/lltexteditor.h
+++ b/indra/llui/lltexteditor.h
@@ -43,19 +43,155 @@
#include "llstyle.h"
#include "lleditmenuhandler.h"
#include "lldarray.h"
+#include "llviewborder.h" // for params
#include "llpreeditor.h"
+#include "llcontrol.h"
class LLFontGL;
class LLScrollbar;
-class LLViewBorder;
class LLKeywordToken;
class LLTextCmd;
class LLUICtrlFactory;
+class LLScrollContainer;
+
+class LLTextSegment : public LLRefCount
+{
+public:
+ LLTextSegment(S32 start, S32 end) : mStart(start), mEnd(end){};
+ virtual ~LLTextSegment();
+
+ virtual S32 getWidth(S32 first_char, S32 num_chars) const;
+ virtual S32 getOffset(S32 segment_local_x_coord, S32 start_offset, S32 num_chars, bool round) const;
+ virtual S32 getNumChars(S32 num_pixels, S32 segment_offset, S32 line_offset, S32 max_chars) const;
+ virtual void updateLayout(const class LLTextEditor& editor);
+ virtual F32 draw(S32 start, S32 end, S32 selection_start, S32 selection_end, const LLRect& draw_rect);
+ virtual S32 getMaxHeight() const;
+ virtual bool canEdit() const;
+ virtual void unlinkFromDocument(class LLTextEditor* editor);
+ virtual void linkToDocument(class LLTextEditor* editor);
+
+ virtual void setHasMouseHover(bool hover);
+ virtual const LLColor4& getColor() const;
+ virtual void setColor(const LLColor4 &color);
+ virtual const LLStyleSP getStyle() const;
+ virtual void setStyle(const LLStyleSP &style);
+ virtual void setToken( LLKeywordToken* token );
+ virtual LLKeywordToken* getToken() const;
+ virtual BOOL getToolTip( std::string& msg ) const;
+ virtual void dump() const;
+
+ S32 getStart() const { return mStart; }
+ void setStart(S32 start) { mStart = start; }
+ S32 getEnd() const { return mEnd; }
+ void setEnd( S32 end ) { mEnd = end; }
+
+protected:
+ S32 mStart;
+ S32 mEnd;
+};
+
+class LLNormalTextSegment : public LLTextSegment
+{
+public:
+ LLNormalTextSegment( const LLStyleSP& style, S32 start, S32 end, LLTextEditor& editor );
+ LLNormalTextSegment( const LLColor4& color, S32 start, S32 end, LLTextEditor& editor, BOOL is_visible = TRUE);
+
+ /*virtual*/ S32 getWidth(S32 first_char, S32 num_chars) const;
+ /*virtual*/ S32 getOffset(S32 segment_local_x_coord, S32 start_offset, S32 num_chars, bool round) const;
+ /*virtual*/ S32 getNumChars(S32 num_pixels, S32 segment_offset, S32 line_offset, S32 max_chars) const;
+ /*virtual*/ F32 draw(S32 start, S32 end, S32 selection_start, S32 selection_end, const LLRect& draw_rect);
+ /*virtual*/ S32 getMaxHeight() const;
+ /*virtual*/ bool canEdit() const { return true; }
+ /*virtual*/ void setHasMouseHover(bool hover) { mHasMouseHover = hover; }
+ /*virtual*/ const LLColor4& getColor() const { return mStyle->getColor(); }
+ /*virtual*/ void setColor(const LLColor4 &color) { mStyle->setColor(color); }
+ /*virtual*/ const LLStyleSP getStyle() const { return mStyle; }
+ /*virtual*/ void setStyle(const LLStyleSP &style) { mStyle = style; }
+ /*virtual*/ void setToken( LLKeywordToken* token ) { mToken = token; }
+ /*virtual*/ LLKeywordToken* getToken() const { return mToken; }
+ /*virtual*/ BOOL getToolTip( std::string& msg ) const;
+ /*virtual*/ void dump() const;
+
+protected:
+ F32 drawClippedSegment(S32 seg_start, S32 seg_end, S32 selection_start, S32 selection_end, F32 x, F32 y);
+
+ class LLTextEditor& mEditor;
+ LLStyleSP mStyle;
+ S32 mMaxHeight;
+ LLKeywordToken* mToken;
+ bool mHasMouseHover;
+};
+
+typedef LLPointer<LLTextSegment> LLTextSegmentPtr;
+
+class LLInlineViewSegment : public LLTextSegment
+{
+public:
+ LLInlineViewSegment(LLView* widget, S32 start, S32 end);
+ ~LLInlineViewSegment();
+ /*virtual*/ S32 getWidth(S32 first_char, S32 num_chars) const;
+ /*virtual*/ S32 getNumChars(S32 num_pixels, S32 segment_offset, S32 line_offset, S32 max_chars) const;
+ /*virtual*/ void updateLayout(const class LLTextEditor& editor);
+ /*virtual*/ F32 draw(S32 start, S32 end, S32 selection_start, S32 selection_end, const LLRect& draw_rect);
+ /*virtuaL*/ S32 getMaxHeight() const;
+ /*virtual*/ bool canEdit() const { return false; }
+ /*virtual*/ void unlinkFromDocument(class LLTextEditor* editor);
+ /*virtual*/ void linkToDocument(class LLTextEditor* editor);
+
+private:
+ LLView* mView;
+};
+
+class LLIndexSegment : public LLTextSegment
+{
+public:
+ LLIndexSegment(S32 pos) : LLTextSegment(pos, pos) {}
+};
class LLTextEditor : public LLUICtrl, LLEditMenuHandler, protected LLPreeditor
{
public:
+ struct Params : public LLInitParam::Block<Params, LLUICtrl::Params>
+ {
+ Optional<std::string> default_text;
+ Optional<S32> max_text_length;
+
+ Optional<bool> read_only,
+ embedded_items,
+ word_wrap,
+ ignore_tab,
+ hide_border,
+ track_bottom,
+ handle_edit_keys_directly,
+ show_line_numbers,
+ commit_on_focus_lost;
+
+ //colors
+ Optional<LLUIColor> cursor_color,
+ default_color,
+ text_color,
+ text_readonly_color,
+ bg_readonly_color,
+ bg_writeable_color,
+ bg_focus_color,
+ link_color;
+
+ Optional<LLViewBorder::Params> border;
+
+ Ignored type,
+ length,
+ is_unicode,
+ hide_scrollbar;
+
+ Params();
+ };
+
+ void initFromParams(const Params&);
+protected:
+ LLTextEditor(const Params&);
+ friend class LLUICtrlFactory;
+public:
//
// Constants
//
@@ -63,18 +199,19 @@ public:
static const llwchar LAST_EMBEDDED_CHAR = 0x10ffff;
static const S32 MAX_EMBEDDED_ITEMS = LAST_EMBEDDED_CHAR - FIRST_EMBEDDED_CHAR + 1;
- LLTextEditor(const std::string& name,
- const LLRect& rect,
- S32 max_length,
- const std::string &default_text,
- const LLFontGL* glfont = NULL,
- BOOL allow_embedded_items = FALSE);
+
+ struct compare_segment_end
+ {
+ bool operator()(const LLTextSegmentPtr& a, const LLTextSegmentPtr& b) const
+ {
+ return a->getEnd() < b->getEnd();
+ }
+ };
+
+ typedef std::multiset<LLTextSegmentPtr, compare_segment_end> segment_set_t;
virtual ~LLTextEditor();
- virtual LLXMLNodePtr getXML(bool save_children = true) const;
- static LLView* fromXML(LLXMLNodePtr node, LLView *parent, class LLUICtrlFactory *factory);
- void setTextEditorParameters(LLXMLNodePtr node);
void setParseHTML(BOOL parsing) {mParseHTML=parsing;}
void setParseHighlights(BOOL parsing) {mParseHighlights=parsing;}
@@ -82,7 +219,6 @@ public:
virtual BOOL handleMouseDown(S32 x, S32 y, MASK mask);
virtual BOOL handleMouseUp(S32 x, S32 y, MASK mask);
virtual BOOL handleHover(S32 x, S32 y, MASK mask);
- virtual BOOL handleScrollWheel(S32 x, S32 y, S32 clicks);
virtual BOOL handleDoubleClick(S32 x, S32 y, MASK mask );
virtual BOOL handleMiddleMouseDown(S32 x,S32 y,MASK mask);
@@ -100,14 +236,15 @@ public:
virtual void draw();
virtual void onFocusReceived();
virtual void onFocusLost();
+ virtual void onCommit();
virtual void setEnabled(BOOL enabled);
// uictrl overrides
- virtual void onTabInto();
virtual void clear();
virtual void setFocus( BOOL b );
virtual BOOL acceptsTextInput() const;
- virtual BOOL isDirty() const { return( mLastCmd != NULL || (mPristineCmd && (mPristineCmd != mLastCmd)) ); }
+ virtual BOOL isDirty() const { return isPristine(); }
+ virtual void setValue(const LLSD& value);
// LLEditMenuHandler interface
virtual void undo();
@@ -134,9 +271,12 @@ public:
virtual void deselect();
virtual BOOL canDeselect() const;
+ virtual void onValueChange(S32 start, S32 end);
+
void selectNext(const std::string& search_text_in, BOOL case_insensitive, BOOL wrap = TRUE);
BOOL replaceText(const std::string& search_text, const std::string& replace_text, BOOL case_insensitive, BOOL wrap = TRUE);
void replaceTextAll(const std::string& search_text, const std::string& replace_text, BOOL case_insensitive);
+ BOOL hasSelection() const { return (mSelectionStart !=mSelectionEnd); }
// Undo/redo stack
void blockUndo();
@@ -145,12 +285,20 @@ public:
virtual void makePristine();
BOOL isPristine() const;
BOOL allowsEmbeddedItems() const { return mAllowEmbeddedItems; }
+ BOOL getWordWrap() { return mWordWrap; }
+ S32 getLength() const { return getWText().length(); }
+ void setReadOnly(bool read_only) { mReadOnly = read_only; }
+ bool getReadOnly() { return mReadOnly; }
+
+ //
+ // Text manipulation
+ //
// inserts text at cursor
void insertText(const std::string &text);
// appends text at end
void appendText(const std::string &wtext, bool allow_undo, bool prepend_newline,
- const LLStyleSP stylep = NULL);
+ const LLStyle::Params& style = LLStyle::Params());
void appendColoredText(const std::string &wtext, bool allow_undo,
bool prepend_newline,
@@ -159,19 +307,24 @@ public:
// if styled text starts a line, you need to prepend a newline.
void appendStyledText(const std::string &new_text, bool allow_undo,
bool prepend_newline,
- LLStyleSP stylep = NULL);
+ const LLStyle::Params& style);
void appendHighlightedText(const std::string &new_text, bool allow_undo,
bool prepend_newline, S32 highlight_part,
- LLStyleSP stylep);
-
+ const LLStyle::Params& style);
+ void appendWidget(LLView* widget, const std::string &widget_text, bool allow_undo, bool prepend_newline);
+ // Non-undoable
+ void setText(const LLStringExplicit &utf8str);
+ void setWText(const LLWString &wtext);
+
+
// Removes text from the end of document
// Does not change highlight or cursor position.
void removeTextFromEnd(S32 num_chars);
BOOL tryToRevertToPristineState();
- void setCursor(S32 row, S32 column);
- void setCursorPos(S32 offset);
+ bool setCursor(S32 row, S32 column);
+ bool setCursorPos(S32 offset, bool keep_cursor_offset = false);
void setCursorAndScrollToEnd();
void getLineAndColumnForPosition( S32 position, S32* line, S32* col, BOOL include_wordwrap );
@@ -186,95 +339,57 @@ public:
LLKeywords::keyword_iterator_t keywordsBegin() { return mKeywords.begin(); }
LLKeywords::keyword_iterator_t keywordsEnd() { return mKeywords.end(); }
- // Color support
- void setCursorColor(const LLColor4& c) { mCursorColor = c; }
- void setFgColor( const LLColor4& c ) { mFgColor = c; }
- void setTextDefaultColor( const LLColor4& c ) { mDefaultColor = c; }
- void setReadOnlyFgColor( const LLColor4& c ) { mReadOnlyFgColor = c; }
- void setWriteableBgColor( const LLColor4& c ) { mWriteableBgColor = c; }
- void setReadOnlyBgColor( const LLColor4& c ) { mReadOnlyBgColor = c; }
- void setTrackColor( const LLColor4& color );
- void setThumbColor( const LLColor4& color );
- void setHighlightColor( const LLColor4& color );
- void setShadowColor( const LLColor4& color );
-
// Hacky methods to make it into a word-wrapping, potentially scrolling,
// read-only text box.
- void setBorderVisible(BOOL b);
- BOOL isBorderVisible() const;
- void setTakesNonScrollClicks(BOOL b) { mTakesNonScrollClicks = b; }
- void setHideScrollbarForShortDocs(BOOL b);
-
- void setWordWrap( BOOL b );
- void setTabsToNextField(BOOL b) { mTabsToNextField = b; }
- BOOL tabsToNextField() const { return mTabsToNextField; }
void setCommitOnFocusLost(BOOL b) { mCommitOnFocusLost = b; }
// Hack to handle Notecards
virtual BOOL importBuffer(const char* buffer, S32 length );
virtual BOOL exportBuffer(std::string& buffer );
- // If takes focus, will take keyboard focus on click.
- void setTakesFocus(BOOL b) { mTakesFocus = b; }
+ const class DocumentPanel* getDocumentPanel() const { return mDocumentPanel; }
- void setSourceID(const LLUUID& id) { mSourceID = id; }
const LLUUID& getSourceID() const { return mSourceID; }
- void setAcceptCallingCardNames(BOOL enable) { mAcceptCallingCardNames = enable; }
- BOOL acceptsCallingCardNames() const { return mAcceptCallingCardNames; }
-
- void setHandleEditKeysDirectly( BOOL b ) { mHandleEditKeysDirectly = b; }
// Callbacks
- static void setLinkColor(LLColor4 color) { mLinkColor = color; }
static void setURLCallbacks(void (*callback1) (const std::string& url),
bool (*callback2) (const std::string& url),
bool (*callback3) (const std::string& url) )
- { mURLcallback = callback1; mSecondlifeURLcallback = callback2; mSecondlifeURLcallbackRightClick = callback3;}
-
- void setOnScrollEndCallback(void (*callback)(void*), void* userdata);
-
- // new methods
- void setValue(const LLSD& value);
- LLSD getValue() const;
+ { sURLcallback = callback1; sSecondlifeURLcallback = callback2; sSecondlifeURLcallbackRightClick = callback3;}
- const std::string& getText() const;
+ std::string getText() const;
- // Non-undoable
- void setText(const LLStringExplicit &utf8str);
- void setWText(const LLWString &wtext);
+ // Getters
+ LLWString getWText() const;
+ llwchar getWChar(S32 pos) const { return getWText()[pos]; }
+ LLWString getWSubString(S32 pos, S32 len) const { return getWText().substr(pos, len); }
- // Returns byte length limit
- S32 getMaxLength() const { return mMaxTextByteLength; }
-
- // Change cursor
- void startOfLine();
- void endOfLine();
- void endOfDoc();
+ typedef std::vector<LLTextSegmentPtr> segment_vec_t;
- BOOL isScrolledToTop();
- BOOL isScrolledToBottom();
+ const LLTextSegmentPtr getPreviousSegment() const;
+ void getSelectedSegments(segment_vec_t& segments) const;
- // Getters
- const LLWString& getWText() const { return mWText; }
- llwchar getWChar(S32 pos) const { return mWText[pos]; }
- LLWString getWSubString(S32 pos, S32 len) const { return mWText.substr(pos, len); }
-
- const LLTextSegment* getCurrentSegment() const { return getSegmentAtOffset(mCursorPos); }
- const LLTextSegment* getPreviousSegment() const;
- void getSelectedSegments(std::vector<const LLTextSegment*>& segments) const;
+ void getSegmentsInRange(segment_vec_t& segments, S32 start, S32 end, bool include_partial) const;
+ LLRect getLocalRectFromDocIndex(S32 index) const;
- static bool isPartOfWord(llwchar c) { return (c == '_') || LLStringOps::isAlnum((char)c); }
+ void addDocumentChild(LLView* view);
+ void removeDocumentChild(LLView* view);
protected:
- //
- // Methods
- //
+ // Change cursor
+ void startOfLine();
+ void endOfLine();
+ void startOfDoc();
+ void endOfDoc();
- S32 getLength() const { return mWText.length(); }
- void getSegmentAndOffset( S32 startpos, S32* segidxp, S32* offsetp ) const;
+ void getSegmentAndOffset( S32 startpos, segment_set_t::const_iterator* seg_iter, S32* offsetp ) const;
+ void getSegmentAndOffset( S32 startpos, segment_set_t::iterator* seg_iter, S32* offsetp ) ;
void drawPreeditMarker();
- void updateLineStartList(S32 startpos = 0);
+ void needsReflow() { mReflowNeeded = TRUE; }
+ void needsScroll() { mScrollNeeded = TRUE; }
+ void updateCursorXPos();
+
void updateScrollFromCursor();
void updateTextRect();
const LLRect& getTextRect() const { return mTextRect; }
@@ -283,16 +398,16 @@ protected:
BOOL truncate(); // Returns true if truncation occurs
void removeCharOrTab();
- void setCursorAtLocalPos(S32 x, S32 y, BOOL round);
- S32 getCursorPosFromLocalCoord( S32 local_x, S32 local_y, BOOL round ) const;
+ void setCursorAtLocalPos(S32 x, S32 y, bool round, bool keep_cursor_offset = false);
+ S32 getDocIndexFromLocalCoord( S32 local_x, S32 local_y, BOOL round ) const;
void indentSelectedLines( S32 spaces );
S32 indentLine( S32 pos, S32 spaces );
void unindentLineBeforeCloseBrace();
- S32 getSegmentIdxAtOffset(S32 offset) const;
- const LLTextSegment* getSegmentAtLocalPos(S32 x, S32 y) const;
- const LLTextSegment* getSegmentAtOffset(S32 offset) const;
+ LLTextSegmentPtr getSegmentAtLocalPos(S32 x, S32 y);
+ segment_set_t::iterator getSegIterContaining(S32 index);
+ segment_set_t::const_iterator getSegIterContaining(S32 index) const;
void reportBadKeystroke() { make_ui_sound("UISndBadKeystroke"); }
@@ -302,7 +417,6 @@ protected:
BOOL handleControlKey(const KEY key, const MASK mask);
BOOL handleEditKey(const KEY key, const MASK mask);
- BOOL hasSelection() const { return (mSelectionStart !=mSelectionEnd); }
BOOL selectionContainsLineBreaks();
void startSelection();
void endSelection();
@@ -311,9 +425,10 @@ protected:
S32 prevWordPos(S32 cursorPos) const;
S32 nextWordPos(S32 cursorPos) const;
- S32 getLineCount() const { return mLineStartList.size(); }
+ S32 getLineCount() const { return mLineInfoList.size(); }
S32 getLineStart( S32 line ) const;
- void getLineAndOffset(S32 pos, S32* linep, S32* offsetp) const;
+ S32 getLineHeight( S32 line ) const;
+ void getLineAndOffset(S32 pos, S32* linep, S32* offsetp, bool include_wordwrap = true) const;
S32 getPos(S32 line, S32 offset);
void changePage(S32 delta);
@@ -321,13 +436,13 @@ protected:
void autoIndent();
- void findEmbeddedItemSegments();
+ void findEmbeddedItemSegments(S32 start, S32 end);
+ void insertSegment(LLTextSegmentPtr segment_to_insert);
+
virtual BOOL handleMouseUpOverSegment(S32 x, S32 y, MASK mask);
virtual llwchar pasteEmbeddedItem(llwchar ext_char) { return ext_char; }
- virtual void bindEmbeddedChars(const LLFontGL* font) const {}
- virtual void unbindEmbeddedChars(const LLFontGL* font) const {}
S32 findHTMLToken(const std::string &line, S32 pos, BOOL reverse) const;
BOOL findHTML(const std::string &line, S32 *begin, S32 *end) const;
@@ -338,7 +453,15 @@ protected:
class LLTextCmd
{
public:
- LLTextCmd( S32 pos, BOOL group_with_next ) : mPos(pos), mGroupWithNext(group_with_next) {}
+ LLTextCmd( S32 pos, BOOL group_with_next, LLTextSegmentPtr segment = LLTextSegmentPtr() )
+ : mPos(pos),
+ mGroupWithNext(group_with_next)
+ {
+ if (segment.notNull())
+ {
+ mSegments.push_back(segment);
+ }
+ }
virtual ~LLTextCmd() {}
virtual BOOL execute(LLTextEditor* editor, S32* delta) = 0;
virtual S32 undo(LLTextEditor* editor) = 0;
@@ -349,16 +472,17 @@ protected:
virtual BOOL hasExtCharValue( llwchar value ) const { return FALSE; }
// Defined here so they can access protected LLTextEditor editing methods
- S32 insert(LLTextEditor* editor, S32 pos, const LLWString &wstr) { return editor->insertStringNoUndo( pos, wstr ); }
+ S32 insert(LLTextEditor* editor, S32 pos, const LLWString &wstr) { return editor->insertStringNoUndo( pos, wstr, &mSegments ); }
S32 remove(LLTextEditor* editor, S32 pos, S32 length) { return editor->removeStringNoUndo( pos, length ); }
S32 overwrite(LLTextEditor* editor, S32 pos, llwchar wc) { return editor->overwriteCharNoUndo(pos, wc); }
S32 getPosition() const { return mPos; }
BOOL groupWithNext() const { return mGroupWithNext; }
- private:
- const S32 mPos;
- BOOL mGroupWithNext;
+ protected:
+ const S32 mPos;
+ BOOL mGroupWithNext;
+ segment_vec_t mSegments;
};
// Here's the method that takes and applies text commands.
S32 execute(LLTextCmd* cmd);
@@ -369,12 +493,12 @@ protected:
S32 overwriteChar(S32 pos, llwchar wc);
void removeChar();
S32 removeChar(S32 pos);
- S32 insert(const S32 pos, const LLWString &wstr, const BOOL group_with_next_op);
- S32 remove(const S32 pos, const S32 length, const BOOL group_with_next_op);
- S32 append(const LLWString &wstr, const BOOL group_with_next_op);
+ S32 insert(S32 pos, const LLWString &wstr, bool group_with_next_op, LLTextSegmentPtr segment);
+ S32 remove(S32 pos, S32 length, bool group_with_next_op);
+ S32 append(const LLWString &wstr, bool group_with_next_op, LLTextSegmentPtr segment);
// Direct operations
- S32 insertStringNoUndo(S32 pos, const LLWString &wstr); // returns num of chars actually inserted
+ S32 insertStringNoUndo(S32 pos, const LLWString &wstr, segment_vec_t* segments = NULL); // returns num of chars actually inserted
S32 removeStringNoUndo(S32 pos, S32 length);
S32 overwriteCharNoUndo(S32 pos, llwchar wc);
@@ -418,54 +542,68 @@ protected:
BOOL mParseHighlights;
std::string mHTML;
- typedef std::vector<LLTextSegment *> segment_list_t;
- segment_list_t mSegments;
- const LLTextSegment* mHoverSegment;
+ segment_set_t mSegments;
+ LLTextSegmentPtr mHoverSegment;
// Scrollbar data
- class LLScrollbar* mScrollbar;
- BOOL mHideScrollbarForShortDocs;
- BOOL mTakesNonScrollClicks;
- void (*mOnScrollEndCallback)(void*);
+ class DocumentPanel* mDocumentPanel;
+ LLScrollContainer* mScroller;
+
void *mOnScrollEndData;
LLWString mPreeditWString;
LLWString mPreeditOverwrittenWString;
std::vector<S32> mPreeditPositions;
std::vector<BOOL> mPreeditStandouts;
-
+
+ S32 mScrollIndex; // index into document that controls default scroll position
+
+protected:
+ LLUIColor mCursorColor;
+ LLUIColor mFgColor;
+ LLUIColor mDefaultColor;
+ LLUIColor mReadOnlyFgColor;
+ LLUIColor mWriteableBgColor;
+ LLUIColor mReadOnlyBgColor;
+ LLUIColor mFocusBgColor;
+ LLUIColor mLinkColor;
+
+ BOOL mReadOnly;
+ BOOL mWordWrap;
+ BOOL mShowLineNumbers;
+
+ void updateSegments();
+
private:
//
// Methods
//
- void pasteHelper(bool is_primary);
+ void pasteHelper(bool is_primary);
- void updateSegments();
- void pruneSegments();
+ virtual LLTextViewModel* getViewModel() const;
+ void reflow(S32 startpos = 0);
+
+ void clearSegments();
+ void createDefaultSegment();
+ LLStyleSP getDefaultStyle();
+ S32 getEditableIndex(S32 index, bool increasing_direction);
void drawBackground();
void drawSelectionBackground();
void drawCursor();
void drawText();
- void drawClippedSegment(const LLWString &wtext, S32 seg_start, S32 seg_end, F32 x, F32 y, S32 selection_left, S32 selection_right, const LLStyleSP& color, F32* right_x);
-
- void needsReflow()
- {
- mReflowNeeded = TRUE;
- // cursor might have moved, need to scroll
- mScrollNeeded = TRUE;
- }
- void needsScroll() { mScrollNeeded = TRUE; }
+ void drawLineNumbers();
+
+ S32 getFirstVisibleLine() const;
//
// Data
//
LLKeywords mKeywords;
- static LLColor4 mLinkColor;
- static void (*mURLcallback) (const std::string& url);
- static bool (*mSecondlifeURLcallback) (const std::string& url);
- static bool (*mSecondlifeURLcallbackRightClick) (const std::string& url);
+ static void (*sURLcallback) (const std::string& url);
+ static bool (*sSecondlifeURLcallback) (const std::string& url);
+ static bool (*sSecondlifeURLcallbackRightClick) (const std::string& url);
// Concrete LLTextCmd sub-classes used by the LLTextEditor base class
class LLTextCmdInsert;
@@ -473,13 +611,9 @@ private:
class LLTextCmdOverwriteChar;
class LLTextCmdRemove;
- LLWString mWText;
- mutable std::string mUTF8Text;
- mutable BOOL mTextIsUpToDate;
-
S32 mMaxTextByteLength; // Maximum length mText is allowed to be in bytes
- const LLFontGL* mGLFont;
+ const LLFontGL* mDefaultFont;
class LLViewBorder* mBorder;
@@ -496,52 +630,36 @@ private:
// List of offsets and segment index of the start of each line. Always has at least one node (0).
struct line_info
{
- line_info(S32 segment, S32 offset) : mSegment(segment), mOffset(offset) {}
- S32 mSegment;
- S32 mOffset;
- };
- struct line_info_compare
- {
- bool operator()(const line_info& a, const line_info& b) const
- {
- if (a.mSegment < b.mSegment)
- return true;
- else if (a.mSegment > b.mSegment)
- return false;
- else
- return a.mOffset < b.mOffset;
- }
+ line_info(S32 index_start, S32 index_end, S32 top, S32 bottom, S32 line_num)
+ : mDocIndexStart(index_start),
+ mDocIndexEnd(index_end),
+ mTop(top),
+ mBottom(bottom),
+ mLineNum(line_num)
+ {}
+ S32 mDocIndexStart;
+ S32 mDocIndexEnd;
+ S32 mTop;
+ S32 mBottom;
+ S32 mLineNum; // actual line count (ignoring soft newlines due to word wrap)
};
+ struct compare_bottom;
+ struct compare_top;
+ struct line_end_compare;
typedef std::vector<line_info> line_list_t;
- line_list_t mLineStartList;
+ line_list_t mLineInfoList;
BOOL mReflowNeeded;
BOOL mScrollNeeded;
LLFrameTimer mKeystrokeTimer;
- LLColor4 mCursorColor;
-
- LLColor4 mFgColor;
- LLColor4 mDefaultColor;
- LLColor4 mReadOnlyFgColor;
- LLColor4 mWriteableBgColor;
- LLColor4 mReadOnlyBgColor;
- LLColor4 mFocusBgColor;
-
- BOOL mReadOnly;
- BOOL mWordWrap;
- BOOL mShowLineNumbers;
-
BOOL mTabsToNextField; // if true, tab moves focus to next field, else inserts spaces
BOOL mCommitOnFocusLost;
BOOL mTakesFocus;
BOOL mTrackBottom; // if true, keeps scroll position at bottom during resize
- BOOL mScrolledToBottom;
BOOL mAllowEmbeddedItems;
- BOOL mAcceptCallingCardNames;
-
LLUUID mSourceID;
// If true, the standard edit keys (Ctrl-X, Delete, etc,) are handled here
@@ -552,47 +670,4 @@ private:
}; // end class LLTextEditor
-
-class LLTextSegment
-{
-public:
- // for creating a compare value
- LLTextSegment(S32 start);
- LLTextSegment( const LLStyleSP& style, S32 start, S32 end );
- LLTextSegment( const LLColor4& color, S32 start, S32 end, BOOL is_visible);
- LLTextSegment( const LLColor4& color, S32 start, S32 end );
- LLTextSegment( const LLColor3& color, S32 start, S32 end );
-
- S32 getStart() const { return mStart; }
- S32 getEnd() const { return mEnd; }
- void setEnd( S32 end ) { mEnd = end; }
- const LLColor4& getColor() const { return mStyle->getColor(); }
- void setColor(const LLColor4 &color) { mStyle->setColor(color); }
- const LLStyleSP& getStyle() const { return mStyle; }
- void setStyle(const LLStyleSP &style) { mStyle = style; }
- void setIsDefault(BOOL b) { mIsDefault = b; }
- BOOL getIsDefault() const { return mIsDefault; }
- void setToken( LLKeywordToken* token ) { mToken = token; }
- LLKeywordToken* getToken() const { return mToken; }
- BOOL getToolTip( std::string& msg ) const;
-
- void dump() const;
-
- struct compare
- {
- bool operator()(const LLTextSegment* a, const LLTextSegment* b) const
- {
- return a->mStart < b->mStart;
- }
- };
-
-private:
- LLStyleSP mStyle;
- S32 mStart;
- S32 mEnd;
- LLKeywordToken* mToken;
- BOOL mIsDefault;
-};
-
-
#endif // LL_TEXTEDITOR_
diff --git a/indra/llui/lltextparser.cpp b/indra/llui/lltextparser.cpp
index 227d24a865..707dd0afdd 100644
--- a/indra/llui/lltextparser.cpp
+++ b/indra/llui/lltextparser.cpp
@@ -1,10 +1,9 @@
/**
- * @file lltexteditor.cpp
- * @brief LLTextEditor base class
+ * @file lltextparser.cpp
*
* $LicenseInfo:firstyear=2001&license=viewergpl$
*
- * Copyright (c) 2001-2007, Linden Research, Inc.
+ * Copyright (c) 2001-2009, Linden Research, Inc.
*
* Second Life Viewer Source Code
* The source code in this file ("Source Code") is provided by Linden Lab
@@ -12,12 +11,13 @@
* ("GPL"), unless you have obtained a separate licensing agreement
* ("Other License"), formally executed by you and Linden Lab. Terms of
* the GPL can be found in doc/GPL-license.txt in this distribution, or
- * online at http://secondlife.com/developers/opensource/gplv2
+ * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
*
* There are special exceptions to the terms and conditions of the GPL as
* it is applied to this Source Code. View the full text of the exception
* in the file doc/FLOSS-exception.txt in this software distribution, or
- * online at http://secondlife.com/developers/opensource/flossexception
+ * online at
+ * http://secondlifegrid.net/programs/open_source/licensing/flossexception
*
* By copying, modifying or distributing this software, you acknowledge
* that you have read and understood your obligations described above,
@@ -31,6 +31,8 @@
#include "linden_common.h"
+#include "lltextparser.h"
+
#include "llsd.h"
#include "llsdserialize.h"
#include "llerror.h"
@@ -39,23 +41,13 @@
#include "message.h"
#include "llmath.h"
#include "v4color.h"
-#include "audioengine.h"
-#include "llwindow.h"
#include "lldir.h"
-#include "lltextparser.h"
-//#include "lltexttospeech.h"
-
// Routines used for parsing text for TextParsers and html
LLTextParser* LLTextParser::sInstance = NULL;
//
-// Constants
-//
-const F32 SOUND_GAIN = 1.0f;
-
-//
// Member Functions
//
@@ -75,38 +67,7 @@ LLTextParser* LLTextParser::getInstance()
return sInstance;
}
-void LLTextParser::triggerAlerts(LLUUID agent_id, LLVector3d position, std::string text, LLWindow* viewer_window)
-{
-// bool spoken=FALSE;
- for (S32 i=0;i<mHighlights.size();i++)
- {
- if (findPattern(text,mHighlights[i]) >= 0 )
- {
- if(gAudiop)
- {
- if ((std::string)mHighlights[i]["sound_lluuid"] != LLUUID::null.asString())
- {
- gAudiop->triggerSound(mHighlights[i]["sound_lluuid"].asUUID(), agent_id, SOUND_GAIN, LLAudioEngine::AUDIO_TYPE_UI, position);
- }
-/*
- if (!spoken)
- {
- LLTextToSpeech* text_to_speech = NULL;
- text_to_speech = LLTextToSpeech::getInstance();
- spoken = text_to_speech->speak((LLString)mHighlights[i]["voice"],text);
- }
- */
- }
- if (mHighlights[i]["flash"])
- {
- if (viewer_window && viewer_window->getMinimized())
- {
- viewer_window->flashIcon(5.f);
- }
- }
- }
- }
-}
+// Moved triggerAlerts() to llfloaterchat.cpp to break llui/llaudio library dependency.
S32 LLTextParser::findPattern(const std::string &text, LLSD highlight)
{
diff --git a/indra/llui/lltextparser.h b/indra/llui/lltextparser.h
index 5c5c3f3301..fb1a7758b7 100644
--- a/indra/llui/lltextparser.h
+++ b/indra/llui/lltextparser.h
@@ -3,6 +3,30 @@
* @brief GUI for user-defined highlights
*
* $LicenseInfo:firstyear=2002&license=viewergpl$
+ *
+ * Copyright (c) 2002-2009, Linden Research, Inc.
+ *
+ * Second Life Viewer Source Code
+ * The source code in this file ("Source Code") is provided by Linden Lab
+ * to you under the terms of the GNU General Public License, version 2.0
+ * ("GPL"), unless you have obtained a separate licensing agreement
+ * ("Other License"), formally executed by you and Linden Lab. Terms of
+ * the GPL can be found in doc/GPL-license.txt in this distribution, or
+ * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
+ *
+ * There are special exceptions to the terms and conditions of the GPL as
+ * it is applied to this Source Code. View the full text of the exception
+ * in the file doc/FLOSS-exception.txt in this software distribution, or
+ * online at
+ * http://secondlifegrid.net/programs/open_source/licensing/flossexception
+ *
+ * By copying, modifying or distributing this software, you acknowledge
+ * that you have read and understood your obligations described above,
+ * and agree to abide by those obligations.
+ *
+ * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+ * COMPLETENESS OR PERFORMANCE.
* $/LicenseInfo$
*
*/
@@ -10,12 +34,10 @@
#ifndef LL_LLTEXTPARSER_H
#define LL_LLTEXTPARSER_H
-#include <vector>
-#include "linden_common.h"
-
#include "lltextparser.h"
-class LLSD;
+#include "llsd.h"
+
class LLUUID;
class LLVector3d;
class LLColor4;
@@ -35,13 +57,13 @@ public:
S32 findPattern(const std::string &text, LLSD highlight);
LLSD parsePartialLineHighlights(const std::string &text,const LLColor4 &color,S32 part=WHOLE, S32 index=0);
bool parseFullLineHighlights(const std::string &text, LLColor4 *color);
- void triggerAlerts(LLUUID agent_id, LLVector3d position, std::string text, LLWindow* viewer_window);
std::string getFileName();
LLSD loadFromDisk();
bool saveToDisk(LLSD highlights);
+
public:
- LLSD mHighlights;
+ LLSD mHighlights;
private:
static LLTextParser* sInstance;
};
diff --git a/indra/llui/lltransutil.cpp b/indra/llui/lltransutil.cpp
new file mode 100644
index 0000000000..eaee260c7a
--- /dev/null
+++ b/indra/llui/lltransutil.cpp
@@ -0,0 +1,67 @@
+/**
+ * @file lltrans.cpp
+ * @brief LLTrans implementation
+ *
+ * $LicenseInfo:firstyear=2000&license=viewergpl$
+ *
+ * Copyright (c) 2000-2009, Linden Research, Inc.
+ *
+ * Second Life Viewer Source Code
+ * The source code in this file ("Source Code") is provided by Linden Lab
+ * to you under the terms of the GNU General Public License, version 2.0
+ * ("GPL"), unless you have obtained a separate licensing agreement
+ * ("Other License"), formally executed by you and Linden Lab. Terms of
+ * the GPL can be found in doc/GPL-license.txt in this distribution, or
+ * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
+ *
+ * There are special exceptions to the terms and conditions of the GPL as
+ * it is applied to this Source Code. View the full text of the exception
+ * in the file doc/FLOSS-exception.txt in this software distribution, or
+ * online at
+ * http://secondlifegrid.net/programs/open_source/licensing/flossexception
+ *
+ * By copying, modifying or distributing this software, you acknowledge
+ * that you have read and understood your obligations described above,
+ * and agree to abide by those obligations.
+ *
+ * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+ * COMPLETENESS OR PERFORMANCE.
+ * $/LicenseInfo$
+ */
+
+#include "linden_common.h"
+
+#include "lltrans.h"
+#include "lluictrlfactory.h"
+
+#include "lltransutil.h"
+
+
+bool LLTransUtil::parseStrings(const std::string& xml_filename, const std::set<std::string>& default_args)
+{
+ LLXMLNodePtr root;
+ BOOL success = LLUICtrlFactory::getLayeredXMLNode(xml_filename, root);
+ if (!success)
+ {
+ llerrs << "Couldn't load string table" << llendl;
+ return false;
+ }
+
+ return LLTrans::parseStrings(root, default_args);
+}
+
+
+bool LLTransUtil::parseLanguageStrings(const std::string& xml_filename)
+{
+ LLXMLNodePtr root;
+ BOOL success = LLUICtrlFactory::getLayeredXMLNode(xml_filename, root);
+
+ if (!success)
+ {
+ llerrs << "Couldn't load string table " << xml_filename << llendl;
+ return false;
+ }
+
+ return LLTrans::parseLanguageStrings(root);
+}
diff --git a/indra/llui/lltransutil.h b/indra/llui/lltransutil.h
new file mode 100644
index 0000000000..2ddfd81361
--- /dev/null
+++ b/indra/llui/lltransutil.h
@@ -0,0 +1,51 @@
+/**
+ * @file lltransutil.h
+ * @brief LLTrans helper
+ *
+ * $LicenseInfo:firstyear=2000&license=viewergpl$
+ *
+ * Copyright (c) 2000-2009, Linden Research, Inc.
+ *
+ * Second Life Viewer Source Code
+ * The source code in this file ("Source Code") is provided by Linden Lab
+ * to you under the terms of the GNU General Public License, version 2.0
+ * ("GPL"), unless you have obtained a separate licensing agreement
+ * ("Other License"), formally executed by you and Linden Lab. Terms of
+ * the GPL can be found in doc/GPL-license.txt in this distribution, or
+ * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
+ *
+ * There are special exceptions to the terms and conditions of the GPL as
+ * it is applied to this Source Code. View the full text of the exception
+ * in the file doc/FLOSS-exception.txt in this software distribution, or
+ * online at
+ * http://secondlifegrid.net/programs/open_source/licensing/flossexception
+ *
+ * By copying, modifying or distributing this software, you acknowledge
+ * that you have read and understood your obligations described above,
+ * and agree to abide by those obligations.
+ *
+ * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+ * COMPLETENESS OR PERFORMANCE.
+ * $/LicenseInfo$
+ */
+
+#ifndef LL_TRANSUTIL_H
+#define LL_TRANSUTIL_H
+
+#include "lltrans.h"
+
+namespace LLTransUtil
+{
+ /**
+ * @brief Parses the xml file that holds the strings. Used once on startup
+ * @param xml_filename Filename to parse
+ * @param default_args Set of strings (expected to be in the file) to use as default replacement args, e.g. "SECOND_LIFE"
+ * @returns true if the file was parsed successfully, true if something went wrong
+ */
+ bool parseStrings(const std::string& xml_filename, const std::set<std::string>& default_args);
+
+ bool parseLanguageStrings(const std::string& xml_filename);
+};
+
+#endif
diff --git a/indra/llui/llui.cpp b/indra/llui/llui.cpp
index 57ce13c9c6..1d62ed93f9 100644
--- a/indra/llui/llui.cpp
+++ b/indra/llui/llui.cpp
@@ -38,45 +38,58 @@
#include <map>
// Linden library includes
-#include "audioengine.h"
#include "v2math.h"
#include "v4color.h"
#include "llrender.h"
#include "llrect.h"
-#include "llimagegl.h"
#include "lldir.h"
#include "llfontgl.h"
// Project includes
#include "llcontrol.h"
#include "llui.h"
+#include "lluicolortable.h"
#include "llview.h"
#include "lllineeditor.h"
+#include "llfloater.h"
+#include "llfloaterreg.h"
+#include "llmenugl.h"
#include "llwindow.h"
+// for registration
+#include "llfiltereditor.h"
+#include "llflyoutbutton.h"
+#include "llsearcheditor.h"
+
+// for XUIParse
+#include "llquaternion.h"
+#include <boost/tokenizer.hpp>
+
//
// Globals
//
const LLColor4 UI_VERTEX_COLOR(1.f, 1.f, 1.f, 1.f);
-// Used to hide the flashing text cursor when window doesn't have focus.
-BOOL gShowTextEditCursor = TRUE;
-
// Language for UI construction
std::map<std::string, std::string> gTranslation;
std::list<std::string> gUntranslated;
+/*static*/ LLUI::settings_map_t LLUI::sSettingGroups;
+/*static*/ LLImageProviderInterface* LLUI::sImageProvider = NULL;
+/*static*/ LLUIAudioCallback LLUI::sAudioCallback = NULL;
+/*static*/ LLVector2 LLUI::sGLScaleFactor(1.f, 1.f);
+/*static*/ LLWindow* LLUI::sWindow = NULL;
+/*static*/ LLHtmlHelp* LLUI::sHtmlHelp = NULL;
+/*static*/ LLView* LLUI::sRootView = NULL;
+/*static*/ BOOL LLUI::sShowXUINames = FALSE;
+/*static*/ std::stack<LLRect> LLScreenClipRect::sClipRectStack;
+
+/*static*/ std::vector<std::string> LLUI::sXUIPaths;
+
+// register filtereditor here
+static LLDefaultChildRegistry::Register<LLFilterEditor> register_filter_editor("filter_editor");
+static LLDefaultChildRegistry::Register<LLFlyoutButton> register_flyout_button("flyout_button");
+static LLDefaultChildRegistry::Register<LLSearchEditor> register_search_editor("search_editor");
-LLControlGroup* LLUI::sConfigGroup = NULL;
-LLControlGroup* LLUI::sIgnoresGroup = NULL;
-LLControlGroup* LLUI::sColorsGroup = NULL;
-LLImageProviderInterface* LLUI::sImageProvider = NULL;
-LLUIAudioCallback LLUI::sAudioCallback = NULL;
-LLVector2 LLUI::sGLScaleFactor(1.f, 1.f);
-LLWindow* LLUI::sWindow = NULL;
-LLHtmlHelp* LLUI::sHtmlHelp = NULL;
-BOOL LLUI::sShowXUINames = FALSE;
-std::stack<LLRect> LLScreenClipRect::sClipRectStack;
-BOOL LLUI::sQAMode = FALSE;
//
// Functions
@@ -84,18 +97,18 @@ BOOL LLUI::sQAMode = FALSE;
void make_ui_sound(const char* namep)
{
std::string name = ll_safe_string(namep);
- if (!LLUI::sConfigGroup->controlExists(name))
+ if (!LLUI::sSettingGroups["config"]->controlExists(name))
{
llwarns << "tried to make ui sound for unknown sound name: " << name << llendl;
}
else
{
- LLUUID uuid(LLUI::sConfigGroup->getString(name));
+ LLUUID uuid(LLUI::sSettingGroups["config"]->getString(name));
if (uuid.isNull())
{
- if (LLUI::sConfigGroup->getString(name) == LLUUID::null.asString())
+ if (LLUI::sSettingGroups["config"]->getString(name) == LLUUID::null.asString())
{
- if (LLUI::sConfigGroup->getBOOL("UISndDebugSpamToggle"))
+ if (LLUI::sSettingGroups["config"]->getBOOL("UISndDebugSpamToggle"))
{
llinfos << "ui sound name: " << name << " triggered but silent (null uuid)" << llendl;
}
@@ -108,7 +121,7 @@ void make_ui_sound(const char* namep)
}
else if (LLUI::sAudioCallback != NULL)
{
- if (LLUI::sConfigGroup->getBOOL("UISndDebugSpamToggle"))
+ if (LLUI::sSettingGroups["config"]->getBOOL("UISndDebugSpamToggle"))
{
llinfos << "ui sound name: " << name << llendl;
}
@@ -408,7 +421,7 @@ void gl_corners_2d(S32 left, S32 top, S32 right, S32 bottom, S32 length, F32 max
}
-void gl_draw_image( S32 x, S32 y, LLImageGL* image, const LLColor4& color, const LLRectf& uv_rect )
+void gl_draw_image( S32 x, S32 y, LLTexture* image, const LLColor4& color, const LLRectf& uv_rect )
{
if (NULL == image)
{
@@ -418,7 +431,7 @@ void gl_draw_image( S32 x, S32 y, LLImageGL* image, const LLColor4& color, const
gl_draw_scaled_rotated_image( x, y, image->getWidth(0), image->getHeight(0), 0.f, image, color, uv_rect );
}
-void gl_draw_scaled_image(S32 x, S32 y, S32 width, S32 height, LLImageGL* image, const LLColor4& color, const LLRectf& uv_rect)
+void gl_draw_scaled_image(S32 x, S32 y, S32 width, S32 height, LLTexture* image, const LLColor4& color, const LLRectf& uv_rect)
{
if (NULL == image)
{
@@ -428,7 +441,7 @@ void gl_draw_scaled_image(S32 x, S32 y, S32 width, S32 height, LLImageGL* image,
gl_draw_scaled_rotated_image( x, y, width, height, 0.f, image, color, uv_rect );
}
-void gl_draw_scaled_image_with_border(S32 x, S32 y, S32 border_width, S32 border_height, S32 width, S32 height, LLImageGL* image, const LLColor4& color, BOOL solid_color, const LLRectf& uv_rect)
+void gl_draw_scaled_image_with_border(S32 x, S32 y, S32 border_width, S32 border_height, S32 width, S32 height, LLTexture* image, const LLColor4& color, BOOL solid_color, const LLRectf& uv_rect)
{
if (NULL == image)
{
@@ -444,7 +457,7 @@ void gl_draw_scaled_image_with_border(S32 x, S32 y, S32 border_width, S32 border
gl_draw_scaled_image_with_border(x, y, width, height, image, color, solid_color, uv_rect, scale_rect);
}
-void gl_draw_scaled_image_with_border(S32 x, S32 y, S32 width, S32 height, LLImageGL* image, const LLColor4& color, BOOL solid_color, const LLRectf& uv_rect, const LLRectf& scale_rect)
+void gl_draw_scaled_image_with_border(S32 x, S32 y, S32 width, S32 height, LLTexture* image, const LLColor4& color, BOOL solid_color, const LLRectf& uv_rect, const LLRectf& scale_rect)
{
stop_glerror();
@@ -630,12 +643,12 @@ void gl_draw_scaled_image_with_border(S32 x, S32 y, S32 width, S32 height, LLIma
}
}
-void gl_draw_rotated_image(S32 x, S32 y, F32 degrees, LLImageGL* image, const LLColor4& color, const LLRectf& uv_rect)
+void gl_draw_rotated_image(S32 x, S32 y, F32 degrees, LLTexture* image, const LLColor4& color, const LLRectf& uv_rect)
{
gl_draw_scaled_rotated_image( x, y, image->getWidth(0), image->getHeight(0), degrees, image, color, uv_rect );
}
-void gl_draw_scaled_rotated_image(S32 x, S32 y, S32 width, S32 height, F32 degrees, LLImageGL* image, const LLColor4& color, const LLRectf& uv_rect)
+void gl_draw_scaled_rotated_image(S32 x, S32 y, S32 width, S32 height, F32 degrees, LLTexture* image, const LLColor4& color, const LLRectf& uv_rect)
{
if (NULL == image)
{
@@ -681,7 +694,7 @@ void gl_draw_scaled_rotated_image(S32 x, S32 y, S32 width, S32 height, F32 degre
}
-void gl_draw_scaled_image_inverted(S32 x, S32 y, S32 width, S32 height, LLImageGL* image, const LLColor4& color, const LLRectf& uv_rect)
+void gl_draw_scaled_image_inverted(S32 x, S32 y, S32 width, S32 height, LLTexture* image, const LLColor4& color, const LLRectf& uv_rect)
{
if (NULL == image)
{
@@ -1554,21 +1567,17 @@ bool handleShowXUINamesChanged(const LLSD& newvalue)
return true;
}
-void LLUI::initClass(LLControlGroup* config,
- LLControlGroup* ignores,
- LLControlGroup* colors,
+void LLUI::initClass(const settings_map_t& settings,
LLImageProviderInterface* image_provider,
LLUIAudioCallback audio_callback,
const LLVector2* scale_factor,
const std::string& language)
{
- sConfigGroup = config;
- sIgnoresGroup = ignores;
- sColorsGroup = colors;
+ sSettingGroups = settings;
- if (sConfigGroup == NULL
- || sIgnoresGroup == NULL
- || sColorsGroup == NULL)
+ if ((get_ptr_in_map(sSettingGroups, std::string("config")) == NULL) ||
+ (get_ptr_in_map(sSettingGroups, std::string("floater")) == NULL) ||
+ (get_ptr_in_map(sSettingGroups, std::string("ignores")) == NULL))
{
llerrs << "Failure to initialize configuration groups" << llendl;
}
@@ -1577,16 +1586,31 @@ void LLUI::initClass(LLControlGroup* config,
sAudioCallback = audio_callback;
sGLScaleFactor = (scale_factor == NULL) ? LLVector2(1.f, 1.f) : *scale_factor;
sWindow = NULL; // set later in startup
- LLFontGL::sShadowColor = colors->getColor("ColorDropShadow");
+ LLFontGL::sShadowColor = LLUIColorTable::instance().getColor("ColorDropShadow");
- LLUI::sShowXUINames = LLUI::sConfigGroup->getBOOL("ShowXUINames");
- LLUI::sConfigGroup->getControl("ShowXUINames")->getSignal()->connect(&handleShowXUINamesChanged);
+ static LLUICachedControl<bool> show_xui_names ("ShowXUINames", false);
+ LLUI::sShowXUINames = show_xui_names;
+ LLUI::sSettingGroups["config"]->getControl("ShowXUINames")->getSignal()->connect(boost::bind(&handleShowXUINamesChanged, _2));
+
+ // Callbacks for associating controls with floater visibilty:
+ LLUICtrl::CommitCallbackRegistry::defaultRegistrar().add("Floater.Toggle", boost::bind(&LLFloaterReg::toggleFloaterInstance, _2));
+ LLUICtrl::CommitCallbackRegistry::defaultRegistrar().add("Floater.Show", boost::bind(&LLFloaterReg::showFloaterInstance, _2));
+ LLUICtrl::CommitCallbackRegistry::defaultRegistrar().add("Floater.Hide", boost::bind(&LLFloaterReg::hideFloaterInstance, _2));
+ LLUICtrl::CommitCallbackRegistry::defaultRegistrar().add("Floater.InitToVisibilityControl", boost::bind(&LLFloaterReg::initUICtrlToFloaterVisibilityControl, _1, _2));
+
+ // Button initialization callback for toggle buttons
+ LLUICtrl::CommitCallbackRegistry::defaultRegistrar().add("Button.SetFloaterToggle", boost::bind(&LLButton::setFloaterToggle, _1, _2));
+
+ // Currently unused, but kept for reference:
+ LLUICtrl::CommitCallbackRegistry::defaultRegistrar().add("Button.ToggleFloater", boost::bind(&LLButton::toggleFloaterAndSetToggleState, _1, _2));
+
+ // Used by menus along with Floater.Toggle to display visibility as a checkmark
+ LLUICtrl::EnableCallbackRegistry::defaultRegistrar().add("Floater.Visible", boost::bind(&LLFloaterReg::floaterInstanceVisible, _2));
}
void LLUI::cleanupClass()
{
sImageProvider->cleanUp();
- LLLineEditor::cleanupLineEditor();
}
@@ -1678,27 +1702,61 @@ void LLUI::getCursorPositionLocal(const LLView* viewp, S32 *x, S32 *y)
// static
std::string LLUI::getLanguage()
{
- std::string language = "en-us";
- if (sConfigGroup)
+ std::string language = "en";
+ if (sSettingGroups["config"])
{
- language = sConfigGroup->getString("Language");
+ language = sSettingGroups["config"]->getString("Language");
if (language.empty() || language == "default")
{
- language = sConfigGroup->getString("InstallLanguage");
+ language = sSettingGroups["config"]->getString("InstallLanguage");
}
if (language.empty() || language == "default")
{
- language = sConfigGroup->getString("SystemLanguage");
+ language = sSettingGroups["config"]->getString("SystemLanguage");
}
if (language.empty() || language == "default")
{
- language = "en-us";
+ language = "en";
}
}
return language;
}
//static
+void LLUI::setupPaths()
+{
+ std::string filename = gDirUtilp->getExpandedFilename(LL_PATH_SKINS, "paths.xml");
+
+ LLXMLNodePtr root;
+ BOOL success = LLXMLNode::parseFile(filename, root, NULL);
+ sXUIPaths.clear();
+
+ if (success)
+ {
+ LLStringUtil::format_map_t path_args;
+ path_args["[LANGUAGE]"] = LLUI::getLanguage();
+
+ for (LLXMLNodePtr path = root->getFirstChild(); path.notNull(); path = path->getNextSibling())
+ {
+ std::string path_val_ui(path->getValue());
+ LLStringUtil::format(path_val_ui, path_args);
+ if (std::find(sXUIPaths.begin(), sXUIPaths.end(), path_val_ui) == sXUIPaths.end())
+ {
+ sXUIPaths.push_back(path_val_ui);
+ }
+ }
+ }
+ else // parsing failed
+ {
+ std::string slash = gDirUtilp->getDirDelimiter();
+ std::string dir = "xui" + slash + "en";
+ llwarns << "XUI::config file unable to open: " << filename << llendl;
+ sXUIPaths.push_back(dir);
+ }
+}
+
+
+//static
std::string LLUI::locateSkin(const std::string& filename)
{
std::string slash = gDirUtilp->getDirDelimiter();
@@ -1707,7 +1765,7 @@ std::string LLUI::locateSkin(const std::string& filename)
{
found_file = gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS, filename); // Should be CUSTOM_SKINS?
}
- if (sConfigGroup && sConfigGroup->controlExists("Language"))
+ if (sSettingGroups["config"] && sSettingGroups["config"]->controlExists("Language"))
{
if (!gDirUtilp->fileExists(found_file))
{
@@ -1718,7 +1776,7 @@ std::string LLUI::locateSkin(const std::string& filename)
}
if (!gDirUtilp->fileExists(found_file))
{
- std::string local_skin = "xui" + slash + "en-us" + slash + filename;
+ std::string local_skin = "xui" + slash + "en" + slash + filename;
found_file = gDirUtilp->findSkinnedFilename(local_skin);
}
if (!gDirUtilp->fileExists(found_file))
@@ -1765,10 +1823,23 @@ void LLUI::glRectToScreen(const LLRect& gl, LLRect *screen)
glPointToScreen(gl.mRight, gl.mBottom, &screen->mRight, &screen->mBottom);
}
+//static
+LLPointer<LLUIImage> LLUI::getUIImageByID(const LLUUID& image_id)
+{
+ if (sImageProvider)
+ {
+ return sImageProvider->getUIImageByID(image_id);
+ }
+ else
+ {
+ return NULL;
+ }
+}
+
//static
-LLUIImage* LLUI::getUIImage(const std::string& name)
+LLPointer<LLUIImage> LLUI::getUIImage(const std::string& name)
{
- if (!name.empty())
+ if (!name.empty() && sImageProvider)
return sImageProvider->getUIImage(name);
else
return NULL;
@@ -1780,10 +1851,20 @@ void LLUI::setHtmlHelp(LLHtmlHelp* html_help)
LLUI::sHtmlHelp = html_help;
}
-//static
-void LLUI::setQAMode(BOOL b)
+LLControlGroup& LLUI::getControlControlGroup (const std::string& controlname)
{
- LLUI::sQAMode = b;
+ for (settings_map_t::iterator itor = sSettingGroups.begin();
+ itor != sSettingGroups.end(); ++itor)
+ {
+ LLControlGroup* control_group = itor->second;
+ if(control_group != NULL)
+ {
+ if (control_group->controlExists(controlname))
+ return *control_group;
+ }
+ }
+
+ return *sSettingGroups["config"]; // default group
}
LLScreenClipRect::LLScreenClipRect(const LLRect& rect, BOOL enabled) : mScissorState(GL_SCISSOR_TEST), mEnabled(enabled)
@@ -1813,6 +1894,12 @@ void LLScreenClipRect::pushClipRect(const LLRect& rect)
{
LLRect top = sClipRectStack.top();
combined_clip_rect.intersectWith(top);
+
+ if(combined_clip_rect.isEmpty())
+ {
+ // avoid artifacts where zero area rects show up as lines
+ combined_clip_rect = LLRect::null;
+ }
}
sClipRectStack.push(combined_clip_rect);
}
@@ -1849,102 +1936,174 @@ LLLocalClipRect::LLLocalClipRect(const LLRect &rect, BOOL enabled)
{
}
-
-//
-// LLUIImage
-//
-
-LLUIImage::LLUIImage(const std::string& name, LLPointer<LLImageGL> image) :
- mName(name),
- mImage(image),
- mScaleRegion(0.f, 1.f, 1.f, 0.f),
- mClipRegion(0.f, 1.f, 1.f, 0.f),
- mUniformScaling(TRUE),
- mNoClip(TRUE)
+namespace LLInitParam
{
-}
+ TypedParam<LLUIColor >::TypedParam(BlockDescriptor& descriptor, const char* name, const LLUIColor& value, ParamDescriptor::validation_func_t func, S32 min_count, S32 max_count)
+ : super_t(descriptor, name, value, func, min_count, max_count),
+ red("red"),
+ green("green"),
+ blue("blue"),
+ alpha("alpha"),
+ control("")
+ {}
-void LLUIImage::setClipRegion(const LLRectf& region)
-{
- mClipRegion = region;
- mNoClip = mClipRegion.mLeft == 0.f
- && mClipRegion.mRight == 1.f
- && mClipRegion.mBottom == 0.f
- && mClipRegion.mTop == 1.f;
-}
+ LLUIColor TypedParam<LLUIColor>::getValueFromBlock() const
+ {
+ if (control.isProvided())
+ {
+ return LLUIColorTable::instance().getColor(control);
+ }
+ else
+ {
+ return LLColor4(red, green, blue, alpha);
+ }
+ }
-void LLUIImage::setScaleRegion(const LLRectf& region)
-{
- mScaleRegion = region;
- mUniformScaling = mScaleRegion.mLeft == 0.f
- && mScaleRegion.mRight == 1.f
- && mScaleRegion.mBottom == 0.f
- && mScaleRegion.mTop == 1.f;
-}
+ void TypeValues<LLUIColor>::declareValues()
+ {
+ declare("white", LLColor4::white);
+ declare("black", LLColor4::black);
+ declare("red", LLColor4::red);
+ declare("green", LLColor4::green);
+ declare("blue", LLColor4::blue);
+ }
-//TODO: move drawing implementation inside class
-void LLUIImage::draw(S32 x, S32 y, const LLColor4& color) const
-{
- gl_draw_image(x, y, mImage, color, mClipRegion);
-}
+ template<>
+ class ParamCompare<const LLFontGL*>
+ {
+ public:
+ static bool equals(const LLFontGL* a, const LLFontGL* b)
+ {
+ return !(a->getFontDesc() < b->getFontDesc())
+ && !(b->getFontDesc() < a->getFontDesc());
+ }
+ };
-void LLUIImage::draw(S32 x, S32 y, S32 width, S32 height, const LLColor4& color) const
-{
- if (mUniformScaling)
+ TypedParam<const LLFontGL*>::TypedParam(BlockDescriptor& descriptor, const char* name, const LLFontGL*const value, ParamDescriptor::validation_func_t func, S32 min_count, S32 max_count)
+ : super_t(descriptor, name, value, func, min_count, max_count),
+ name(""),
+ size("size"),
+ style("style")
+ {}
+
+ const LLFontGL* TypedParam<const LLFontGL*>::getValueFromBlock() const
{
- gl_draw_scaled_image(x, y, width, height, mImage, color, mClipRegion);
+ if (name.isProvided())
+ {
+ const LLFontGL* res_fontp = LLFontGL::getFontByName(name);
+ if (res_fontp)
+ {
+ return res_fontp;
+ }
+
+ U8 fontstyle = 0;
+ fontstyle = LLFontGL::getStyleFromString(style());
+ LLFontDescriptor desc(name(), size(), fontstyle);
+ const LLFontGL* fontp = LLFontGL::getFont(desc);
+ if (fontp)
+ {
+ return fontp;
+ }
+ }
+
+ // default to current value
+ return mData.mValue;
}
- else
+
+ TypedParam<LLRect>::TypedParam(BlockDescriptor& descriptor, const char* name, const LLRect& value, ParamDescriptor::validation_func_t func, S32 min_count, S32 max_count)
+ : super_t(descriptor, name, value, func, min_count, max_count),
+ left("left"),
+ top("top"),
+ right("right"),
+ bottom("bottom"),
+ width("width"),
+ height("height")
+ {}
+
+ LLRect TypedParam<LLRect>::getValueFromBlock() const
{
- gl_draw_scaled_image_with_border(
- x, y,
- width, height,
- mImage,
- color,
- FALSE,
- mClipRegion,
- mScaleRegion);
- }
-}
+ LLRect rect;
-void LLUIImage::drawSolid(S32 x, S32 y, S32 width, S32 height, const LLColor4& color) const
-{
- gl_draw_scaled_image_with_border(
- x, y,
- width, height,
- mImage,
- color,
- TRUE,
- mClipRegion,
- mScaleRegion);
-}
+ //calculate from params
+ // prefer explicit left and right
+ if (left.isProvided() && right.isProvided())
+ {
+ rect.mLeft = left;
+ rect.mRight = right;
+ }
+ // otherwise use width along with specified side, if any
+ else if (width.isProvided())
+ {
+ // only right + width provided
+ if (right.isProvided())
+ {
+ rect.mRight = right;
+ rect.mLeft = right - width;
+ }
+ else // left + width, or just width
+ {
+ rect.mLeft = left;
+ rect.mRight = left + width;
+ }
+ }
+ // just left, just right, or none
+ else
+ {
+ rect.mLeft = left;
+ rect.mRight = right;
+ }
-void LLUIImage::drawBorder(S32 x, S32 y, S32 width, S32 height, const LLColor4& color, S32 border_width) const
-{
- LLRect border_rect;
- border_rect.setOriginAndSize(x, y, width, height);
- border_rect.stretch(border_width, border_width);
- drawSolid(border_rect, color);
-}
+ // prefer explicit bottom and top
+ if (bottom.isProvided() && top.isProvided())
+ {
+ rect.mBottom = bottom;
+ rect.mTop = top;
+ }
+ // otherwise height along with specified side, if any
+ else if (height.isProvided())
+ {
+ // top + height provided
+ if (top.isProvided())
+ {
+ rect.mTop = top;
+ rect.mBottom = top - height;
+ }
+ // bottom + height or just height
+ else
+ {
+ rect.mBottom = bottom;
+ rect.mTop = bottom + height;
+ }
+ }
+ // just bottom, just top, or none
+ else
+ {
+ rect.mBottom = bottom;
+ rect.mTop = top;
+ }
+ return rect;
+ }
-S32 LLUIImage::getWidth() const
-{
- // return clipped dimensions of actual image area
- return llround((F32)mImage->getWidth(0) * mClipRegion.getWidth());
-}
+ void TypeValues<LLFontGL::HAlign>::declareValues()
+ {
+ declare("left", LLFontGL::LEFT);
+ declare("right", LLFontGL::RIGHT);
+ declare("center", LLFontGL::HCENTER);
+ }
-S32 LLUIImage::getHeight() const
-{
- // return clipped dimensions of actual image area
- return llround((F32)mImage->getHeight(0) * mClipRegion.getHeight());
-}
+ void TypeValues<LLFontGL::VAlign>::declareValues()
+ {
+ declare("top", LLFontGL::TOP);
+ declare("center", LLFontGL::VCENTER);
+ declare("baseline", LLFontGL::BASELINE);
+ declare("bottom", LLFontGL::BOTTOM);
+ }
-S32 LLUIImage::getTextureWidth() const
-{
- return mImage->getWidth(0);
+ void TypeValues<LLFontGL::ShadowType>::declareValues()
+ {
+ declare("none", LLFontGL::NO_SHADOW);
+ declare("hard", LLFontGL::DROP_SHADOW);
+ declare("soft", LLFontGL::DROP_SHADOW_SOFT);
+ }
}
-S32 LLUIImage::getTextureHeight() const
-{
- return mImage->getHeight(0);
-}
diff --git a/indra/llui/llui.h b/indra/llui/llui.h
index 6d6ce7a97c..1f9b0b2dbc 100644
--- a/indra/llui/llui.h
+++ b/indra/llui/llui.h
@@ -35,28 +35,36 @@
#ifndef LL_LLUI_H
#define LL_LLUI_H
+#include "llpointer.h" // LLPointer<>
#include "llrect.h"
#include "llcontrol.h"
-#include "llrect.h"
#include "llcoord.h"
-//#include "llhtmlhelp.h"
#include "llgl.h" // *TODO: break this dependency
#include <stack>
-//#include "llimagegl.h"
+#include "lluiimage.h" // *TODO: break this dependency, need to add #include "lluiimage.h" to all widgets that hold an Optional<LLUIImage*> in their paramblocks
+#include "llinitparam.h"
+#include "llregistry.h"
+#include "lluicolor.h"
+#include "lluicolortable.h"
#include <boost/signals2.hpp>
+#include "lllazyvalue.h"
+#include "llhandle.h" // *TODO: remove this dependency, added as a
+ // convenience when LLHandle moved to llhandle.h
// LLUIFactory
#include "llsd.h"
+// for initparam specialization
+#include "llfontgl.h"
+
class LLColor4;
class LLHtmlHelp;
-class LLImageGL;
class LLVector3;
class LLVector2;
+class LLUIImage;
class LLUUID;
class LLWindow;
class LLView;
-class LLUIImage;
// UI colors
extern const LLColor4 UI_VERTEX_COLOR;
@@ -91,14 +99,14 @@ void gl_washer_2d(F32 outer_radius, F32 inner_radius, S32 steps, const LLColor4&
void gl_washer_segment_2d(F32 outer_radius, F32 inner_radius, F32 start_radians, F32 end_radians, S32 steps, const LLColor4& inner_color, const LLColor4& outer_color);
void gl_washer_spokes_2d(F32 outer_radius, F32 inner_radius, S32 count, const LLColor4& inner_color, const LLColor4& outer_color);
-void gl_draw_image(S32 x, S32 y, LLImageGL* image, const LLColor4& color = UI_VERTEX_COLOR, const LLRectf& uv_rect = LLRectf(0.f, 1.f, 1.f, 0.f));
-void gl_draw_scaled_image(S32 x, S32 y, S32 width, S32 height, LLImageGL* image, const LLColor4& color = UI_VERTEX_COLOR, const LLRectf& uv_rect = LLRectf(0.f, 1.f, 1.f, 0.f));
-void gl_draw_rotated_image(S32 x, S32 y, F32 degrees, LLImageGL* image, const LLColor4& color = UI_VERTEX_COLOR, const LLRectf& uv_rect = LLRectf(0.f, 1.f, 1.f, 0.f));
-void gl_draw_scaled_rotated_image(S32 x, S32 y, S32 width, S32 height, F32 degrees,LLImageGL* image, const LLColor4& color = UI_VERTEX_COLOR, const LLRectf& uv_rect = LLRectf(0.f, 1.f, 1.f, 0.f));
-void gl_draw_scaled_image_with_border(S32 x, S32 y, S32 border_width, S32 border_height, S32 width, S32 height, LLImageGL* image, const LLColor4 &color, BOOL solid_color = FALSE, const LLRectf& uv_rect = LLRectf(0.f, 1.f, 1.f, 0.f));
-void gl_draw_scaled_image_with_border(S32 x, S32 y, S32 width, S32 height, LLImageGL* image, const LLColor4 &color, BOOL solid_color = FALSE, const LLRectf& uv_rect = LLRectf(0.f, 1.f, 1.f, 0.f), const LLRectf& scale_rect = LLRectf(0.f, 1.f, 1.f, 0.f));
+void gl_draw_image(S32 x, S32 y, LLTexture* image, const LLColor4& color = UI_VERTEX_COLOR, const LLRectf& uv_rect = LLRectf(0.f, 1.f, 1.f, 0.f));
+void gl_draw_scaled_image(S32 x, S32 y, S32 width, S32 height, LLTexture* image, const LLColor4& color = UI_VERTEX_COLOR, const LLRectf& uv_rect = LLRectf(0.f, 1.f, 1.f, 0.f));
+void gl_draw_rotated_image(S32 x, S32 y, F32 degrees, LLTexture* image, const LLColor4& color = UI_VERTEX_COLOR, const LLRectf& uv_rect = LLRectf(0.f, 1.f, 1.f, 0.f));
+void gl_draw_scaled_rotated_image(S32 x, S32 y, S32 width, S32 height, F32 degrees,LLTexture* image, const LLColor4& color = UI_VERTEX_COLOR, const LLRectf& uv_rect = LLRectf(0.f, 1.f, 1.f, 0.f));
+void gl_draw_scaled_image_with_border(S32 x, S32 y, S32 border_width, S32 border_height, S32 width, S32 height, LLTexture* image, const LLColor4 &color, BOOL solid_color = FALSE, const LLRectf& uv_rect = LLRectf(0.f, 1.f, 1.f, 0.f));
+void gl_draw_scaled_image_with_border(S32 x, S32 y, S32 width, S32 height, LLTexture* image, const LLColor4 &color, BOOL solid_color = FALSE, const LLRectf& uv_rect = LLRectf(0.f, 1.f, 1.f, 0.f), const LLRectf& scale_rect = LLRectf(0.f, 1.f, 1.f, 0.f));
// Flip vertical, used for LLFloaterHTML
-void gl_draw_scaled_image_inverted(S32 x, S32 y, S32 width, S32 height, LLImageGL* image, const LLColor4& color = UI_VERTEX_COLOR, const LLRectf& uv_rect = LLRectf(0.f, 1.f, 1.f, 0.f));
+void gl_draw_scaled_image_inverted(S32 x, S32 y, S32 width, S32 height, LLTexture* image, const LLColor4& color = UI_VERTEX_COLOR, const LLRectf& uv_rect = LLRectf(0.f, 1.f, 1.f, 0.f));
void gl_rect_2d_xor(S32 left, S32 top, S32 right, S32 bottom);
void gl_stippled_line_3d( const LLVector3& start, const LLVector3& end, const LLColor4& color, F32 phase = 0.f );
@@ -143,9 +151,6 @@ inline void gl_rect_2d_offset_local( const LLRect& rect, S32 pixel_offset, BOOL
gl_rect_2d_offset_local( rect.mLeft, rect.mTop, rect.mRight, rect.mBottom, pixel_offset, filled );
}
-// Used to hide the flashing text cursor when window doesn't have focus.
-extern BOOL gShowTextEditCursor;
-
class LLImageProviderInterface;
typedef void (*LLUIAudioCallback)(const LLUUID& uuid);
@@ -157,9 +162,8 @@ public:
//
// Methods
//
- static void initClass(LLControlGroup* config,
- LLControlGroup* ignores,
- LLControlGroup* colors,
+ typedef std::map<std::string, LLControlGroup*> settings_map_t;
+ static void initClass(const settings_map_t& settings,
LLImageProviderInterface* image_provider,
LLUIAudioCallback audio_callback = NULL,
const LLVector2 *scale_factor = NULL,
@@ -174,220 +178,47 @@ public:
// Return the ISO639 language name ("en", "ko", etc.) for the viewer UI.
// http://www.loc.gov/standards/iso639-2/php/code_list.php
static std::string getLanguage();
+
+ static void setupPaths();
+ static const std::vector<std::string>& getXUIPaths() { return sXUIPaths; }
+ static std::string getSkinPath() { return sXUIPaths.front(); }
+ static std::string getLocalizedSkinPath() { return sXUIPaths.back(); } //all files may not exist at the localized path
//helper functions (should probably move free standing rendering helper functions here)
+ static LLView* getRootView() { return sRootView; }
+ static void setRootView(LLView* view) { sRootView = view; }
static std::string locateSkin(const std::string& filename);
static void setCursorPositionScreen(S32 x, S32 y);
static void setCursorPositionLocal(const LLView* viewp, S32 x, S32 y);
static void getCursorPositionLocal(const LLView* viewp, S32 *x, S32 *y);
static void setScaleFactor(const LLVector2& scale_factor);
static void setLineWidth(F32 width);
- static LLUIImage* getUIImage(const std::string& name);
+ static LLPointer<LLUIImage> getUIImageByID(const LLUUID& image_id);
+ static LLPointer<LLUIImage> getUIImage(const std::string& name);
static LLVector2 getWindowSize();
static void screenPointToGL(S32 screen_x, S32 screen_y, S32 *gl_x, S32 *gl_y);
static void glPointToScreen(S32 gl_x, S32 gl_y, S32 *screen_x, S32 *screen_y);
static void screenRectToGL(const LLRect& screen, LLRect *gl);
static void glRectToScreen(const LLRect& gl, LLRect *screen);
static void setHtmlHelp(LLHtmlHelp* html_help);
-
+ // Returns the control group containing the control name, or the default group
+ static LLControlGroup& getControlControlGroup (const std::string& controlname);
+
//
// Data
//
- static LLControlGroup* sConfigGroup;
- static LLControlGroup* sIgnoresGroup;
- static LLControlGroup* sColorsGroup;
- static LLImageProviderInterface* sImageProvider;
+ static settings_map_t sSettingGroups;
static LLUIAudioCallback sAudioCallback;
static LLVector2 sGLScaleFactor;
static LLWindow* sWindow;
static BOOL sShowXUINames;
static LLHtmlHelp* sHtmlHelp;
-
- // *TODO: remove the following when QAR-369 settings clean-up work is in.
- // Also remove the call to this method which will then be obsolete.
- // Search for QAR-369 below to enable the proper accessing of this feature. -MG
- static void setQAMode(BOOL b);
- static BOOL sQAMode;
-
-};
-
-// FactoryPolicy is a static class that controls the creation and lookup of UI elements,
-// such as floaters.
-// The key parameter is used to provide a unique identifier and/or associated construction
-// parameters for a given UI instance
-//
-// Specialize this traits for different types, or provide a class with an identical interface
-// in the place of the traits parameter
-//
-// For example:
-//
-// template <>
-// class FactoryPolicy<MyClass> /* FactoryPolicy specialized for MyClass */
-// {
-// public:
-// static MyClass* findInstance(const LLSD& key = LLSD())
-// {
-// /* return instance of MyClass associated with key */
-// }
-//
-// static MyClass* createInstance(const LLSD& key = LLSD())
-// {
-// /* create new instance of MyClass using key for construction parameters */
-// }
-// }
-//
-// class MyClass : public LLUIFactory<MyClass>
-// {
-// /* uses FactoryPolicy<MyClass> by default */
-// }
-
-template <class T>
-class FactoryPolicy
-{
-public:
- // basic factory methods
- static T* findInstance(const LLSD& key); // unimplemented, provide specialiation
- static T* createInstance(const LLSD& key); // unimplemented, provide specialiation
-};
-
-// VisibilityPolicy controls the visibility of UI elements, such as floaters.
-// The key parameter is used to store the unique identifier of a given UI instance
-//
-// Specialize this traits for different types, or duplicate this interface for specific instances
-// (see above)
-
-template <class T>
-class VisibilityPolicy
-{
-public:
- // visibility methods
- static bool visible(T* instance, const LLSD& key); // unimplemented, provide specialiation
- static void show(T* instance, const LLSD& key); // unimplemented, provide specialiation
- static void hide(T* instance, const LLSD& key); // unimplemented, provide specialiation
-};
-
-// Manages generation of UI elements by LLSD, such that (generally) there is
-// a unique instance per distinct LLSD parameter
-// Class T is the instance type being managed, and the FACTORY_POLICY and VISIBILITY_POLICY
-// classes provide static methods for creating, accessing, showing and hiding the associated
-// element T
-template <class T, class FACTORY_POLICY = FactoryPolicy<T>, class VISIBILITY_POLICY = VisibilityPolicy<T> >
-class LLUIFactory
-{
-public:
- // give names to the template parameters so derived classes can refer to them
- // except this doesn't work in gcc
- typedef FACTORY_POLICY factory_policy_t;
- typedef VISIBILITY_POLICY visibility_policy_t;
-
- LLUIFactory()
- {
- }
-
- virtual ~LLUIFactory()
- {
- }
-
- // default show and hide methods
- static T* showInstance(const LLSD& key = LLSD())
- {
- T* instance = getInstance(key);
- if (instance != NULL)
- {
- VISIBILITY_POLICY::show(instance, key);
- }
- return instance;
- }
-
- static void hideInstance(const LLSD& key = LLSD())
- {
- T* instance = getInstance(key);
- if (instance != NULL)
- {
- VISIBILITY_POLICY::hide(instance, key);
- }
- }
-
- static void toggleInstance(const LLSD& key = LLSD())
- {
- if (instanceVisible(key))
- {
- hideInstance(key);
- }
- else
- {
- showInstance(key);
- }
- }
-
- static bool instanceVisible(const LLSD& key = LLSD())
- {
- T* instance = FACTORY_POLICY::findInstance(key);
- return instance != NULL && VISIBILITY_POLICY::visible(instance, key);
- }
-
- static T* getInstance(const LLSD& key = LLSD())
- {
- T* instance = FACTORY_POLICY::findInstance(key);
- if (instance == NULL)
- {
- instance = FACTORY_POLICY::createInstance(key);
- }
- return instance;
- }
-
-};
-
-
-// Creates a UI singleton by ignoring the identifying parameter
-// and always generating the same instance via the LLUIFactory interface.
-// Note that since UI elements can be destroyed by their hierarchy, this singleton
-// pattern uses a static pointer to an instance that will be re-created as needed.
-//
-// Usage Pattern:
-//
-// class LLFloaterFoo : public LLFloater, public LLUISingleton<LLFloaterFoo>
-// {
-// friend class LLUISingleton<LLFloaterFoo>;
-// private:
-// LLFloaterFoo(const LLSD& key);
-// };
-//
-// Note that LLUISingleton takes an option VisibilityPolicy parameter that defines
-// how showInstance(), hideInstance(), etc. work.
-//
-// https://wiki.lindenlab.com/mediawiki/index.php?title=LLUISingleton&oldid=79352
-
-template <class T, class VISIBILITY_POLICY = VisibilityPolicy<T> >
-class LLUISingleton: public LLUIFactory<T, LLUISingleton<T, VISIBILITY_POLICY>, VISIBILITY_POLICY>
-{
-protected:
-
- // T must derive from LLUISingleton<T>
- LLUISingleton() { sInstance = static_cast<T*>(this); }
-
- ~LLUISingleton() { sInstance = NULL; }
-
-public:
- static T* findInstance(const LLSD& key = LLSD())
- {
- return sInstance;
- }
-
- static T* createInstance(const LLSD& key = LLSD())
- {
- if (sInstance == NULL)
- {
- sInstance = new T(key);
- }
- return sInstance;
- }
-
+ static LLView* sRootView;
private:
- static T* sInstance;
+ static LLImageProviderInterface* sImageProvider;
+ static std::vector<std::string> sXUIPaths;
};
-template <class T, class U> T* LLUISingleton<T,U>::sInstance = NULL;
class LLScreenClipRect
{
@@ -413,251 +244,20 @@ public:
LLLocalClipRect(const LLRect& rect, BOOL enabled = TRUE);
};
-class LLUIImage : public LLRefCount
-{
-public:
- LLUIImage(const std::string& name, LLPointer<LLImageGL> image);
-
- void setClipRegion(const LLRectf& region);
- void setScaleRegion(const LLRectf& region);
-
- LLPointer<LLImageGL> getImage() { return mImage; }
- const LLPointer<LLImageGL>& getImage() const { return mImage; }
-
- void draw(S32 x, S32 y, S32 width, S32 height, const LLColor4& color = UI_VERTEX_COLOR) const;
- void draw(S32 x, S32 y, const LLColor4& color = UI_VERTEX_COLOR) const;
- void draw(const LLRect& rect, const LLColor4& color = UI_VERTEX_COLOR) const { draw(rect.mLeft, rect.mBottom, rect.getWidth(), rect.getHeight(), color); }
-
- void drawSolid(S32 x, S32 y, S32 width, S32 height, const LLColor4& color) const;
- void drawSolid(const LLRect& rect, const LLColor4& color) const { drawSolid(rect.mLeft, rect.mBottom, rect.getWidth(), rect.getHeight(), color); }
- void drawSolid(S32 x, S32 y, const LLColor4& color) const { drawSolid(x, y, mImage->getWidth(0), mImage->getHeight(0), color); }
-
- void drawBorder(S32 x, S32 y, S32 width, S32 height, const LLColor4& color, S32 border_width) const;
- void drawBorder(const LLRect& rect, const LLColor4& color, S32 border_width) const { drawBorder(rect.mLeft, rect.mBottom, rect.getWidth(), rect.getHeight(), color, border_width); }
- void drawBorder(S32 x, S32 y, const LLColor4& color, S32 border_width) const { drawBorder(x, y, mImage->getWidth(0), mImage->getHeight(0), color, border_width); }
-
- const std::string& getName() const { return mName; }
-
- S32 getWidth() const;
- S32 getHeight() const;
-
- // returns dimensions of underlying textures, which might not be equal to ui image portion
- S32 getTextureWidth() const;
- S32 getTextureHeight() const;
-
-protected:
- std::string mName;
- LLRectf mScaleRegion;
- LLRectf mClipRegion;
- LLPointer<LLImageGL> mImage;
- BOOL mUniformScaling;
- BOOL mNoClip;
-};
-
-typedef LLPointer<LLUIImage> LLUIImagePtr;
-
-template <typename T>
-class LLTombStone : public LLRefCount
-{
-public:
- LLTombStone(T* target = NULL) : mTarget(target) {}
-
- void setTarget(T* target) { mTarget = target; }
- T* getTarget() const { return mTarget; }
-private:
- T* mTarget;
-};
-
-// LLHandles are used to refer to objects whose lifetime you do not control or influence.
-// Calling get() on a handle will return a pointer to the referenced object or NULL,
-// if the object no longer exists. Note that during the lifetime of the returned pointer,
-// you are assuming that the object will not be deleted by any action you perform,
-// or any other thread, as normal when using pointers, so avoid using that pointer outside of
-// the local code block.
-//
-// https://wiki.lindenlab.com/mediawiki/index.php?title=LLHandle&oldid=79669
-
-template <typename T>
-class LLHandle
-{
-public:
- LLHandle() : mTombStone(sDefaultTombStone) {}
- const LLHandle<T>& operator =(const LLHandle<T>& other)
- {
- mTombStone = other.mTombStone;
- return *this;
- }
-
- bool isDead() const
- {
- return mTombStone->getTarget() == NULL;
- }
-
- void markDead()
- {
- mTombStone = sDefaultTombStone;
- }
-
- T* get() const
- {
- return mTombStone->getTarget();
- }
-
- friend bool operator== (const LLHandle<T>& lhs, const LLHandle<T>& rhs)
- {
- return lhs.mTombStone == rhs.mTombStone;
- }
- friend bool operator!= (const LLHandle<T>& lhs, const LLHandle<T>& rhs)
- {
- return !(lhs == rhs);
- }
- friend bool operator< (const LLHandle<T>& lhs, const LLHandle<T>& rhs)
- {
- return lhs.mTombStone < rhs.mTombStone;
- }
- friend bool operator> (const LLHandle<T>& lhs, const LLHandle<T>& rhs)
- {
- return lhs.mTombStone > rhs.mTombStone;
- }
-protected:
-
-protected:
- LLPointer<LLTombStone<T> > mTombStone;
-
-private:
- static LLPointer<LLTombStone<T> > sDefaultTombStone;
-};
-
-// initialize static "empty" tombstone pointer
-template <typename T> LLPointer<LLTombStone<T> > LLHandle<T>::sDefaultTombStone = new LLTombStone<T>();
-
-
-template <typename T>
-class LLRootHandle : public LLHandle<T>
-{
-public:
- LLRootHandle(T* object) { bind(object); }
- LLRootHandle() {};
- ~LLRootHandle() { unbind(); }
-
- // this is redundant, since a LLRootHandle *is* an LLHandle
- LLHandle<T> getHandle() { return LLHandle<T>(*this); }
-
- void bind(T* object)
- {
- // unbind existing tombstone
- if (LLHandle<T>::mTombStone.notNull())
- {
- if (LLHandle<T>::mTombStone->getTarget() == object) return;
- LLHandle<T>::mTombStone->setTarget(NULL);
- }
- // tombstone reference counted, so no paired delete
- LLHandle<T>::mTombStone = new LLTombStone<T>(object);
- }
-
- void unbind()
- {
- LLHandle<T>::mTombStone->setTarget(NULL);
- }
-
- //don't allow copying of root handles, since there should only be one
-private:
- LLRootHandle(const LLRootHandle& other) {};
-};
-
-// Use this as a mixin for simple classes that need handles and when you don't
-// want handles at multiple points of the inheritance hierarchy
-template <typename T>
-class LLHandleProvider
-{
-protected:
- typedef LLHandle<T> handle_type_t;
- LLHandleProvider()
- {
- // provided here to enforce T deriving from LLHandleProvider<T>
- }
-
- LLHandle<T> getHandle()
- {
- // perform lazy binding to avoid small tombstone allocations for handle
- // providers whose handles are never referenced
- mHandle.bind(static_cast<T*>(this));
- return mHandle;
- }
-
-private:
- LLRootHandle<T> mHandle;
-};
-
+// Moved all LLHandle-related code to llhandle.h
//RN: maybe this needs to moved elsewhere?
class LLImageProviderInterface
{
-public:
+protected:
LLImageProviderInterface() {};
virtual ~LLImageProviderInterface() {};
-
- virtual LLUIImagePtr getUIImage(const std::string& name) = 0;
- virtual LLUIImagePtr getUIImageByID(const LLUUID& id) = 0;
- virtual void cleanUp() = 0;
-};
-
-// This mix-in class adds support for tracking all instances of the specificed class parameter T
-// The (optional) key associates a value of type KEY with a given instance of T, for quick lookup
-// If KEY is not provided, then instances are stored in a simple list
-template<typename T, typename KEY = T*>
-class LLInstanceTracker : boost::noncopyable
-{
-public:
- typedef typename std::map<KEY, T*>::iterator instance_iter;
- typedef typename std::map<KEY, T*>::const_iterator instance_const_iter;
-
- static T* getInstance(KEY k) { instance_iter found = sInstances.find(k); return (found == sInstances.end()) ? NULL : found->second; }
-
- static instance_iter beginInstances() { return sInstances.begin(); }
- static instance_iter endInstances() { return sInstances.end(); }
- static S32 instanceCount() { return sInstances.size(); }
-protected:
- LLInstanceTracker(KEY key) { add(key); }
- virtual ~LLInstanceTracker() { remove(); }
- virtual void setKey(KEY key) { remove(); add(key); }
- virtual const KEY& getKey() const { return mKey; }
-
-private:
- void add(KEY key)
- {
- mKey = key;
- sInstances[key] = static_cast<T*>(this);
- }
- void remove() { sInstances.erase(mKey); }
-
-private:
-
- KEY mKey;
- static std::map<KEY, T*> sInstances;
-};
-
-template<typename T>
-class LLInstanceTracker<T, T*> : boost::noncopyable
-{
public:
- typedef typename std::set<T*>::iterator instance_iter;
- typedef typename std::set<T*>::const_iterator instance_const_iter;
-
- static instance_iter instancesBegin() { return sInstances.begin(); }
- static instance_iter instancesEnd() { return sInstances.end(); }
- static S32 instanceCount() { return sInstances.size(); }
-
-protected:
- LLInstanceTracker() { sInstances.insert(static_cast<T*>(this)); }
- virtual ~LLInstanceTracker() { sInstances.erase(static_cast<T*>(this)); }
-
- static std::set<T*> sInstances;
+ virtual LLPointer<LLUIImage> getUIImage(const std::string& name) = 0;
+ virtual LLPointer<LLUIImage> getUIImageByID(const LLUUID& id) = 0;
+ virtual void cleanUp() = 0;
};
-template <typename T, typename KEY> std::map<KEY, T*> LLInstanceTracker<T, KEY>::sInstances;
-template <typename T> std::set<T*> LLInstanceTracker<T, T*>::sInstances;
-
class LLCallbackRegistry
{
public:
@@ -746,93 +346,107 @@ private:
template <typename T> LLRegisterWith<LLInitClassList> LLInitClass<T>::sRegister(&T::initClass);
template <typename T> LLRegisterWith<LLDestroyClassList> LLDestroyClass<T>::sRegister(&T::destroyClass);
-
-template <typename DERIVED>
-class LLParamBlock
+// useful parameter blocks
+struct TimeIntervalParam : public LLInitParam::Choice<TimeIntervalParam>
{
-protected:
- LLParamBlock() { sBlock = (DERIVED*)this; }
+ Alternative<F32> seconds;
+ Alternative<S32> frames;
+ TimeIntervalParam()
+ : seconds("seconds"),
+ frames("frames")
+ {}
+};
- typedef typename boost::add_const<DERIVED>::type Tconst;
+template <class T>
+class LLUICachedControl : public LLCachedControl<T>
+{
+public:
+ // This constructor will declare a control if it doesn't exist in the contol group
+ LLUICachedControl(const std::string& name,
+ const T& default_value,
+ const std::string& comment = "Declared In Code")
+ : LLCachedControl<T>(LLUI::getControlControlGroup(name), name, default_value, comment)
+ {}
+
+ // This constructor will signal an error if the control doesn't exist in the control group
+ LLUICachedControl(const std::string& name)
+ : LLCachedControl<T>(LLUI::getControlControlGroup(name), name)
+ {}
+};
- template <typename T>
- class LLMandatoryParam
+namespace LLInitParam
+{
+ template<>
+ class TypedParam<LLRect>
+ : public BlockValue<LLRect>
{
+ typedef BlockValue<LLRect> super_t;
public:
- typedef typename boost::add_const<T>::type T_const;
+ Optional<S32> left,
+ top,
+ right,
+ bottom,
+ width,
+ height;
- LLMandatoryParam(T_const initial_val) : mVal(initial_val), mBlock(sBlock) {}
- LLMandatoryParam(const LLMandatoryParam<T>& other) : mVal(other.mVal) {}
+ TypedParam(BlockDescriptor& descriptor, const char* name, const LLRect& value, ParamDescriptor::validation_func_t func, S32 min_count, S32 max_count);
- DERIVED& operator ()(T_const set_value) { mVal = set_value; return *mBlock; }
- operator T() const { return mVal; }
- T operator=(T_const set_value) { mVal = set_value; return mVal; }
+ LLRect getValueFromBlock() const;
+ };
- private:
- T mVal;
- DERIVED* mBlock;
+ template<>
+ struct TypeValues<LLUIColor> : public TypeValuesHelper<LLUIColor>
+ {
+ static void declareValues();
};
- template <typename T>
- class LLOptionalParam
+ template<>
+ class TypedParam<LLUIColor>
+ : public BlockValue<LLUIColor>
{
+ typedef BlockValue<LLUIColor> super_t;
public:
- typedef typename boost::add_const<T>::type T_const;
-
- LLOptionalParam(T_const initial_val) : mVal(initial_val), mBlock(sBlock) {}
- LLOptionalParam() : mBlock(sBlock) {}
- LLOptionalParam(const LLOptionalParam<T>& other) : mVal(other.mVal) {}
-
- DERIVED& operator ()(T_const set_value) { mVal = set_value; return *mBlock; }
- operator T() const { return mVal; }
- T operator=(T_const set_value) { mVal = set_value; return mVal; }
-
- private:
- T mVal;
- DERIVED* mBlock;
+ Optional<F32> red;
+ Optional<F32> green;
+ Optional<F32> blue;
+ Optional<F32> alpha;
+ Optional<std::string> control;
+
+ TypedParam(BlockDescriptor& descriptor, const char* name, const LLUIColor& value, ParamDescriptor::validation_func_t func, S32 min_count, S32 max_count);
+ LLUIColor getValueFromBlock() const;
};
- // specialization that requires initialization for reference types
- template <typename T>
- class LLOptionalParam <T&>
+ template<>
+ class TypedParam<const LLFontGL*>
+ : public BlockValue<const LLFontGL*>
{
+ typedef BlockValue<const LLFontGL*> super_t;
public:
- typedef typename boost::add_const<T&>::type T_const;
-
- LLOptionalParam(T_const initial_val) : mVal(initial_val), mBlock(sBlock) {}
- LLOptionalParam(const LLOptionalParam<T&>& other) : mVal(other.mVal) {}
+ Optional<std::string> name;
+ Optional<std::string> size;
+ Optional<std::string> style;
- DERIVED& operator ()(T_const set_value) { mVal = set_value; return *mBlock; }
- operator T&() const { return mVal; }
- T& operator=(T_const set_value) { mVal = set_value; return mVal; }
-
- private:
- T& mVal;
- DERIVED* mBlock;
+ TypedParam(BlockDescriptor& descriptor, const char* name, const LLFontGL* const value, ParamDescriptor::validation_func_t func, S32 min_count, S32 max_count);
+ const LLFontGL* getValueFromBlock() const;
};
- // specialization that initializes pointer params to NULL
- template<typename T>
- class LLOptionalParam<T*>
+ template<>
+ struct TypeValues<LLFontGL::HAlign> : public TypeValuesHelper<LLFontGL::HAlign>
{
- public:
- typedef typename boost::add_const<T*>::type T_const;
-
- LLOptionalParam(T_const initial_val) : mVal(initial_val), mBlock(sBlock) {}
- LLOptionalParam() : mVal((T*)NULL), mBlock(sBlock) {}
- LLOptionalParam(const LLOptionalParam<T*>& other) : mVal(other.mVal) {}
-
- DERIVED& operator ()(T_const set_value) { mVal = set_value; return *mBlock; }
- operator T*() const { return mVal; }
- T* operator=(T_const set_value) { mVal = set_value; return mVal; }
- private:
- T* mVal;
- DERIVED* mBlock;
+ static void declareValues();
};
- static DERIVED* sBlock;
-};
+ template<>
+ struct TypeValues<LLFontGL::VAlign> : public TypeValuesHelper<LLFontGL::VAlign>
+ {
+ static void declareValues();
+ };
-template <typename T> T* LLParamBlock<T>::sBlock = NULL;
+ template<>
+ struct TypeValues<LLFontGL::ShadowType> : public TypeValuesHelper<LLFontGL::ShadowType>
+ {
+ static void declareValues();
+ };
+}
#endif
diff --git a/indra/llui/lluicolortable.cpp b/indra/llui/lluicolortable.cpp
new file mode 100644
index 0000000000..087a99c2b0
--- /dev/null
+++ b/indra/llui/lluicolortable.cpp
@@ -0,0 +1,294 @@
+/**
+ * @file lluicolortable.cpp
+ * @brief brief LLUIColorTable class implementation file
+ *
+ * $LicenseInfo:firstyear=2009&license=viewergpl$
+ * Copyright (c) 2009, Linden Research, Inc.
+ * $/LicenseInfo$
+ */
+
+#include "linden_common.h"
+
+#include <queue>
+
+#include "lldir.h"
+#include "llui.h"
+#include "lluicolortable.h"
+#include "lluictrlfactory.h"
+
+LLUIColorTable::ColorParams::ColorParams()
+: value("value"),
+ reference("reference")
+{
+}
+
+LLUIColorTable::ColorEntryParams::ColorEntryParams()
+: name("name"),
+ color("")
+{
+}
+
+LLUIColorTable::Params::Params()
+: color_entries("color")
+{
+}
+
+void LLUIColorTable::insertFromParams(const Params& p)
+{
+ // this map will contain all color references after the following loop
+ typedef std::map<std::string, std::string> string_string_map_t;
+ string_string_map_t unresolved_refs;
+
+ for(LLInitParam::ParamIterator<ColorEntryParams>::const_iterator it = p.color_entries().begin();
+ it != p.color_entries().end();
+ ++it)
+ {
+ ColorEntryParams color_entry = *it;
+ if(color_entry.color.value.isChosen())
+ {
+ setColor(color_entry.name, color_entry.color.value, mLoadedColors);
+ }
+ else
+ {
+ unresolved_refs.insert(string_string_map_t::value_type(color_entry.name, color_entry.color.reference));
+ }
+ }
+
+ // maintain an in order queue of visited references for better debugging of cycles
+ typedef std::queue<std::string> string_queue_t;
+ string_queue_t ref_chain;
+
+ // maintain a map of the previously visited references in the reference chain for detecting cycles
+ typedef std::map<std::string, string_string_map_t::iterator> string_color_ref_iter_map_t;
+ string_color_ref_iter_map_t visited_refs;
+
+ // loop through the unresolved color references until there are none left
+ while(!unresolved_refs.empty())
+ {
+ // we haven't visited any references yet
+ visited_refs.clear();
+
+ string_string_map_t::iterator current = unresolved_refs.begin();
+ string_string_map_t::iterator previous;
+
+ while(true)
+ {
+ if(current != unresolved_refs.end())
+ {
+ // locate the current reference in the previously visited references...
+ string_color_ref_iter_map_t::iterator visited = visited_refs.lower_bound(current->first);
+ if(visited != visited_refs.end()
+ && !(visited_refs.key_comp()(current->first, visited->first)))
+ {
+ // ...if we find the current reference in the previously visited references
+ // we know that there is a cycle
+ std::string ending_ref = current->first;
+ std::string warning("The following colors form a cycle: ");
+
+ // warn about the references in the chain and remove them from
+ // the unresolved references map because they cannot be resolved
+ for(string_color_ref_iter_map_t::iterator iter = visited_refs.begin();
+ iter != visited_refs.end();
+ ++iter)
+ {
+ if(!ref_chain.empty())
+ {
+ warning += ref_chain.front() + "->";
+ ref_chain.pop();
+ }
+ unresolved_refs.erase(iter->second);
+ }
+
+ llwarns << warning + ending_ref << llendl;
+
+ break;
+ }
+ else
+ {
+ // ...continue along the reference chain
+ ref_chain.push(current->first);
+ visited_refs.insert(visited, string_color_ref_iter_map_t::value_type(current->first, current));
+ }
+ }
+ else
+ {
+ // since this reference does not refer to another reference it must refer to an
+ // actual color, lets find it...
+ string_color_map_t::iterator color_value = mLoadedColors.find(previous->second);
+
+ if(color_value != mLoadedColors.end())
+ {
+ // ...we found the color, and we now add every reference in the reference chain
+ // to the color map
+ for(string_color_ref_iter_map_t::iterator iter = visited_refs.begin();
+ iter != visited_refs.end();
+ ++iter)
+ {
+ setColor(iter->first, color_value->second, mLoadedColors);
+ unresolved_refs.erase(iter->second);
+ }
+
+ break;
+ }
+ else
+ {
+ // ... we did not find the color which imples that the current reference
+ // references a non-existant color
+ for(string_color_ref_iter_map_t::iterator iter = visited_refs.begin();
+ iter != visited_refs.end();
+ ++iter)
+ {
+ llwarns << iter->first << " references a non-existent color" << llendl;
+ unresolved_refs.erase(iter->second);
+ }
+
+ break;
+ }
+ }
+
+ // find the next color reference in the reference chain
+ previous = current;
+ current = unresolved_refs.find(current->second);
+ }
+ }
+}
+
+void LLUIColorTable::clear()
+{
+ clearTable(mLoadedColors);
+ clearTable(mUserSetColors);
+}
+
+LLUIColor LLUIColorTable::getColor(const std::string& name, const LLColor4& default_color) const
+{
+ string_color_map_t::const_iterator iter = mUserSetColors.find(name);
+ if(iter != mUserSetColors.end())
+ {
+ return LLUIColor(&iter->second);
+ }
+
+ iter = mLoadedColors.find(name);
+ return (iter != mLoadedColors.end() ? LLUIColor(&iter->second) : LLUIColor(default_color));
+}
+
+// update user color, loaded colors are parsed on initialization
+void LLUIColorTable::setColor(const std::string& name, const LLColor4& color)
+{
+ setColor(name, color, mUserSetColors);
+}
+
+bool LLUIColorTable::loadFromSettings()
+{
+ bool result = false;
+
+ std::string default_filename = gDirUtilp->getExpandedFilename(LL_PATH_DEFAULT_SKIN, "colors.xml");
+ result |= loadFromFilename(default_filename);
+
+ std::string current_filename = gDirUtilp->getExpandedFilename(LL_PATH_TOP_SKIN, "colors.xml");
+ if(current_filename != default_filename)
+ {
+ result |= loadFromFilename(current_filename);
+ }
+
+ std::string user_filename = gDirUtilp->getExpandedFilename(LL_PATH_USER_SKIN, "colors.xml");
+ loadFromFilename(user_filename);
+
+ return result;
+}
+
+void LLUIColorTable::saveUserSettings() const
+{
+ Params params;
+
+ for(string_color_map_t::const_iterator it = mUserSetColors.begin();
+ it != mUserSetColors.end();
+ ++it)
+ {
+ ColorEntryParams color_entry;
+ color_entry.name = it->first;
+ color_entry.color.value = it->second;
+
+ params.color_entries.add(color_entry);
+ }
+
+ LLXMLNodePtr output_node = new LLXMLNode("colors", false);
+ LLXUIParser::instance().writeXUI(output_node, params);
+
+ if(!output_node->isNull())
+ {
+ const std::string& filename = gDirUtilp->getExpandedFilename(LL_PATH_USER_SKIN, "colors.xml");
+ LLFILE *fp = LLFile::fopen(filename, "w");
+
+ if(fp != NULL)
+ {
+ LLXMLNode::writeHeaderToFile(fp);
+ output_node->writeToFile(fp);
+
+ fclose(fp);
+ }
+ }
+}
+
+bool LLUIColorTable::colorExists(const std::string& color_name) const
+{
+ return ((mLoadedColors.find(color_name) != mLoadedColors.end())
+ || (mUserSetColors.find(color_name) != mUserSetColors.end()));
+}
+
+void LLUIColorTable::clearTable(string_color_map_t& table)
+{
+ for(string_color_map_t::iterator it = table.begin();
+ it != table.end();
+ ++it)
+ {
+ it->second = LLColor4::magenta;
+ }
+}
+
+// this method inserts a color into the table if it does not exist
+// if the color already exists it changes the color
+void LLUIColorTable::setColor(const std::string& name, const LLColor4& color, string_color_map_t& table)
+{
+ string_color_map_t::iterator it = table.lower_bound(name);
+ if(it != table.end()
+ && !(table.key_comp()(name, it->first)))
+ {
+ it->second = color;
+ }
+ else
+ {
+ table.insert(it, string_color_map_t::value_type(name, color));
+ }
+}
+
+bool LLUIColorTable::loadFromFilename(const std::string& filename)
+{
+ LLXMLNodePtr root;
+
+ if(!LLXMLNode::parseFile(filename, root, NULL))
+ {
+ llwarns << "Unable to parse color file " << filename << llendl;
+ return false;
+ }
+
+ if(!root->hasName("colors"))
+ {
+ llwarns << filename << " is not a valid color definition file" << llendl;
+ return false;
+ }
+
+ Params params;
+ LLXUIParser::instance().readXUI(root, params);
+
+ if(params.validateBlock())
+ {
+ insertFromParams(params);
+ }
+ else
+ {
+ llwarns << filename << " failed to load" << llendl;
+ return false;
+ }
+
+ return true;
+}
diff --git a/indra/llui/lluicolortable.h b/indra/llui/lluicolortable.h
new file mode 100644
index 0000000000..f102a573b8
--- /dev/null
+++ b/indra/llui/lluicolortable.h
@@ -0,0 +1,83 @@
+/**
+ * @file lluicolortable.h
+ * @brief brief LLUIColorTable class header file
+ *
+ * $LicenseInfo:firstyear=2009&license=viewergpl$
+ * Copyright (c) 2009, Linden Research, Inc.
+ * $/LicenseInfo$
+ */
+
+#ifndef LL_LLUICOLORTABLE_H_
+#define LL_LLUICOLORTABLE_H_
+
+#include <map>
+
+#include "llinitparam.h"
+#include "llsingleton.h"
+
+#include "v4color.h"
+
+class LLUIColor;
+
+class LLUIColorTable : public LLSingleton<LLUIColorTable>
+{
+LOG_CLASS(LLUIColorTable);
+public:
+ struct ColorParams : LLInitParam::Choice<ColorParams>
+ {
+ Alternative<LLColor4> value;
+ Alternative<std::string> reference;
+
+ ColorParams();
+ };
+
+ struct ColorEntryParams : LLInitParam::Block<ColorEntryParams>
+ {
+ Mandatory<std::string> name;
+ Mandatory<ColorParams> color;
+
+ ColorEntryParams();
+ };
+
+ struct Params : LLInitParam::Block<Params>
+ {
+ Multiple<ColorEntryParams> color_entries;
+
+ Params();
+ };
+
+ // define colors by passing in a param block that can be generated via XUI file or manually
+ void insertFromParams(const Params& p);
+
+ // reset all colors to default magenta color
+ void clear();
+
+ // color lookup
+ LLUIColor getColor(const std::string& name, const LLColor4& default_color = LLColor4::magenta) const;
+
+ // if the color is in the table, it's value is changed, otherwise it is added
+ void setColor(const std::string& name, const LLColor4& color);
+
+ // returns true if color_name exists in the table
+ bool colorExists(const std::string& color_name) const;
+
+ // loads colors from settings files
+ bool loadFromSettings();
+
+ // saves colors specified by the user to the users skin directory
+ void saveUserSettings() const;
+
+private:
+ bool loadFromFilename(const std::string& filename);
+
+ // consider using sorted vector, can be much faster
+ typedef std::map<std::string, LLColor4> string_color_map_t;
+
+ void clearTable(string_color_map_t& table);
+ void setColor(const std::string& name, const LLColor4& color, string_color_map_t& table);
+
+ string_color_map_t mLoadedColors;
+ string_color_map_t mUserSetColors;
+};
+
+#endif // LL_LLUICOLORTABLE_H
diff --git a/indra/llui/lluictrl.cpp b/indra/llui/lluictrl.cpp
index 9d97312ab0..7ff942268d 100644
--- a/indra/llui/lluictrl.cpp
+++ b/indra/llui/lluictrl.cpp
@@ -36,103 +36,237 @@
#include "lluictrl.h"
#include "llfocusmgr.h"
#include "llpanel.h"
+#include "lluictrlfactory.h"
-static LLRegisterWidget<LLUICtrl> r("ui_ctrl");
+static LLDefaultChildRegistry::Register<LLUICtrl> r("ui_ctrl");
-LLFocusableElement::LLFocusableElement()
-: mFocusLostCallback(NULL),
- mFocusReceivedCallback(NULL),
- mFocusChangedCallback(NULL),
- mFocusCallbackUserData(NULL)
+LLUICtrl::Params::Params()
+: tab_stop("tab_stop", true),
+ label("label"),
+ initial_value("value"),
+ init_callback("init_callback"),
+ commit_callback("commit_callback"),
+ validate_callback("validate_callback"),
+ mouseenter_callback("mouseenter_callback"),
+ mouseleave_callback("mouseleave_callback"),
+ control_name("control_name")
{
+ addSynonym(initial_value, "initial_value");
}
-//virtual
-LLFocusableElement::~LLFocusableElement()
+// NOTE: the LLFocusableElement implementation has been moved from here to llfocusmgr.cpp.
+
+//static
+const LLUICtrl::Params& LLUICtrl::getDefaultParams()
{
+ return LLUICtrlFactory::getDefaultParams<LLUICtrl>();
}
-void LLFocusableElement::onFocusReceived()
+
+LLUICtrl::LLUICtrl(const LLUICtrl::Params& p, const LLViewModelPtr& viewmodel)
+: LLView(p),
+ mTentative(FALSE),
+ mIsChrome(FALSE),
+ mViewModel(viewmodel),
+ mControlVariable(NULL),
+ mEnabledControlVariable(NULL),
+ mDisabledControlVariable(NULL),
+ mMakeVisibleControlVariable(NULL),
+ mMakeInvisibleControlVariable(NULL)
{
- if( mFocusReceivedCallback )
+ mUICtrlHandle.bind(this);
+}
+
+void LLUICtrl::initFromParams(const Params& p)
+{
+ LLView::initFromParams(p);
+
+ setControlName(p.control_name);
+ if(p.enabled_controls.isProvided())
+ {
+ if (p.enabled_controls.enabled.isChosen())
+ {
+ LLControlVariable* control = findControl(p.enabled_controls.enabled);
+ if (control)
+ setEnabledControlVariable(control);
+ }
+ else if(p.enabled_controls.disabled.isChosen())
+ {
+ LLControlVariable* control = findControl(p.enabled_controls.disabled);
+ if (control)
+ setDisabledControlVariable(control);
+ }
+ }
+ if(p.controls_visibility.isProvided())
{
- mFocusReceivedCallback( this, mFocusCallbackUserData );
+ if (p.controls_visibility.visible.isChosen())
+ {
+ LLControlVariable* control = findControl(p.controls_visibility.visible);
+ if (control)
+ setMakeVisibleControlVariable(control);
+ }
+ else if (p.controls_visibility.invisible.isChosen())
+ {
+ LLControlVariable* control = findControl(p.controls_visibility.invisible);
+ if (control)
+ setMakeInvisibleControlVariable(control);
+ }
}
- if( mFocusChangedCallback )
+
+ setTabStop(p.tab_stop);
+ setFocusLostCallback(p.focus_lost_callback());
+
+ if (p.initial_value.isProvided()
+ && !p.control_name.isProvided())
+ {
+ setValue(p.initial_value);
+ }
+
+ if (p.commit_callback.isProvided())
+ initCommitCallback(p.commit_callback, mCommitSignal);
+
+ if (p.validate_callback.isProvided())
+ initEnableCallback(p.validate_callback, mValidateSignal);
+
+ if (p.init_callback.isProvided())
{
- mFocusChangedCallback( this, mFocusCallbackUserData );
+ if (p.init_callback.function.isProvided())
+ {
+ p.init_callback.function()(this, p.init_callback.parameter);
+ }
+ else
+ {
+ commit_callback_t* initfunc = (CommitCallbackRegistry::getValue(p.init_callback.function_name));
+ if (initfunc)
+ {
+ (*initfunc)(this, p.init_callback.parameter);
+ }
+ }
}
+
+ if(p.mouseenter_callback.isProvided())
+ initCommitCallback(p.mouseenter_callback, mMouseEnterSignal);
+
+ if(p.mouseleave_callback.isProvided())
+ initCommitCallback(p.mouseleave_callback, mMouseLeaveSignal);
}
-void LLFocusableElement::onFocusLost()
+
+LLUICtrl::~LLUICtrl()
{
- if( mFocusLostCallback )
+ gFocusMgr.releaseFocusIfNeeded( this ); // calls onCommit()
+
+ if( gFocusMgr.getTopCtrl() == this )
{
- mFocusLostCallback( this, mFocusCallbackUserData );
+ llwarns << "UI Control holding top ctrl deleted: " << getName() << ". Top view removed." << llendl;
+ gFocusMgr.removeTopCtrlWithoutCallback( this );
}
+}
- if( mFocusChangedCallback )
+void LLUICtrl::initCommitCallback(const CommitCallbackParam& cb, commit_signal_t& sig)
+{
+ if (cb.function.isProvided())
{
- mFocusChangedCallback( this, mFocusCallbackUserData );
+ if (cb.parameter.isProvided())
+ sig.connect(boost::bind(cb.function(), _1, cb.parameter));
+ else
+ sig.connect(cb.function());
+ }
+ else
+ {
+ std::string function_name = cb.function_name;
+ commit_callback_t* func = (CommitCallbackRegistry::getValue(function_name));
+ if (func)
+ {
+ if (cb.parameter.isProvided())
+ sig.connect(boost::bind((*func), _1, cb.parameter));
+ else
+ sig.connect(*func);
+ }
+ else if (!function_name.empty())
+ {
+ llwarns << "No callback found for: '" << function_name << "' in control: " << getName() << llendl;
+ }
}
}
-BOOL LLFocusableElement::hasFocus() const
+void LLUICtrl::initEnableCallback(const EnableCallbackParam& cb, enable_signal_t& sig)
{
- return FALSE;
+ // Set the callback function
+ if (cb.function.isProvided())
+ {
+ if (cb.parameter.isProvided())
+ sig.connect(boost::bind(cb.function(), this, cb.parameter));
+ else
+ sig.connect(cb.function());
+ }
+ else
+ {
+ enable_callback_t* func = (EnableCallbackRegistry::getValue(cb.function_name));
+ if (func)
+ {
+ if (cb.parameter.isProvided())
+ sig.connect(boost::bind((*func), this, cb.parameter));
+ else
+ sig.connect(*func);
+ }
+ }
}
-void LLFocusableElement::setFocus(BOOL b)
+// virtual
+void LLUICtrl::onMouseEnter(S32 x, S32 y, MASK mask)
{
+ mMouseEnterSignal(this, getValue());
}
+// virtual
+void LLUICtrl::onMouseLeave(S32 x, S32 y, MASK mask)
+{
+ mMouseLeaveSignal(this, getValue());
+}
+//virtual
+BOOL LLUICtrl::handleMouseDown(S32 x, S32 y, MASK mask)
+{
+ BOOL handled = LLView::handleMouseDown(x,y,mask);
+ mMouseDownSignal(this,x,y,mask);
+ return handled;
+}
-LLUICtrl::LLUICtrl() :
- mCommitCallback(NULL),
- mLostTopCallback(NULL),
- mValidateCallback(NULL),
- mCallbackUserData(NULL),
- mTentative(FALSE),
- mTabStop(TRUE),
- mIsChrome(FALSE)
+//virtual
+BOOL LLUICtrl::handleMouseUp(S32 x, S32 y, MASK mask)
{
+ BOOL handled = LLView::handleMouseUp(x,y,mask);
+ mMouseUpSignal(this,x,y,mask);
+ return handled;
}
-LLUICtrl::LLUICtrl(const std::string& name, const LLRect& rect, BOOL mouse_opaque,
- void (*on_commit_callback)(LLUICtrl*, void*),
- void* callback_userdata,
- U32 reshape)
-: // can't make this automatically follow top and left, breaks lots
- // of buttons in the UI. JC 7/20/2002
- LLView( name, rect, mouse_opaque, reshape ),
- mCommitCallback( on_commit_callback) ,
- mLostTopCallback( NULL ),
- mValidateCallback( NULL ),
- mCallbackUserData( callback_userdata ),
- mTentative( FALSE ),
- mTabStop( TRUE ),
- mIsChrome(FALSE)
+//virtual
+BOOL LLUICtrl::handleRightMouseDown(S32 x, S32 y, MASK mask)
{
+ BOOL handled = LLView::handleRightMouseDown(x,y,mask);
+ mRightMouseDownSignal(this,x,y,mask);
+ return handled;
}
-LLUICtrl::~LLUICtrl()
+//virtual
+BOOL LLUICtrl::handleRightMouseUp(S32 x, S32 y, MASK mask)
{
- gFocusMgr.releaseFocusIfNeeded( this ); // calls onCommit()
+ BOOL handled = LLView::handleRightMouseUp(x,y,mask);
+ mRightMouseUpSignal(this,x,y,mask);
+ return handled;
+}
- if( gFocusMgr.getTopCtrl() == this )
- {
- llwarns << "UI Control holding top ctrl deleted: " << getName() << ". Top view removed." << llendl;
- gFocusMgr.removeTopCtrlWithoutCallback( this );
- }
+// can't tab to children of a non-tab-stop widget
+BOOL LLUICtrl::canFocusChildren() const
+{
+ return hasTabStop();
}
+
void LLUICtrl::onCommit()
{
- if( mCommitCallback )
- {
- mCommitCallback( this, mCallbackUserData );
- }
+ mCommitSignal(this, getValue());
}
//virtual
@@ -141,10 +275,170 @@ BOOL LLUICtrl::isCtrl() const
return TRUE;
}
+//virtual
+void LLUICtrl::setValue(const LLSD& value)
+{
+ mViewModel->setValue(value);
+}
+
//virtual
LLSD LLUICtrl::getValue() const
{
- return LLSD();
+ return mViewModel->getValue();
+}
+
+/// When two widgets are displaying the same data (e.g. during a skin
+/// change), share their ViewModel.
+void LLUICtrl::shareViewModelFrom(const LLUICtrl& other)
+{
+ // Because mViewModel is an LLViewModelPtr, this assignment will quietly
+ // dispose of the previous LLViewModel -- unless it's already shared by
+ // somebody else.
+ mViewModel = other.mViewModel;
+}
+
+//virtual
+LLViewModel* LLUICtrl::getViewModel() const
+{
+ return mViewModel;
+}
+
+bool LLUICtrl::setControlValue(const LLSD& value)
+{
+ if (mControlVariable)
+ {
+ mControlVariable->set(value);
+ return true;
+ }
+ return false;
+}
+
+void LLUICtrl::setControlVariable(LLControlVariable* control)
+{
+ if (mControlVariable)
+ {
+ //RN: this will happen in practice, should we try to avoid it?
+ //llwarns << "setControlName called twice on same control!" << llendl;
+ mControlConnection.disconnect(); // disconnect current signal
+ mControlVariable = NULL;
+ }
+
+ if (control)
+ {
+ mControlVariable = control;
+ mControlConnection = mControlVariable->getSignal()->connect(boost::bind(&controlListener, _2, getUICtrlHandle(), std::string("value")));
+ setValue(mControlVariable->getValue());
+ }
+}
+
+//virtual
+void LLUICtrl::setControlName(const std::string& control_name, LLView *context)
+{
+ if (context == NULL)
+ {
+ context = this;
+ }
+
+ // Register new listener
+ if (!control_name.empty())
+ {
+ LLControlVariable* control = context->findControl(control_name);
+ setControlVariable(control);
+ }
+}
+
+void LLUICtrl::setEnabledControlVariable(LLControlVariable* control)
+{
+ if (mEnabledControlVariable)
+ {
+ mEnabledControlConnection.disconnect(); // disconnect current signal
+ mEnabledControlVariable = NULL;
+ }
+ if (control)
+ {
+ mEnabledControlVariable = control;
+ mEnabledControlConnection = mEnabledControlVariable->getSignal()->connect(boost::bind(&controlListener, _2, getUICtrlHandle(), std::string("enabled")));
+ setEnabled(mEnabledControlVariable->getValue().asBoolean());
+ }
+}
+
+void LLUICtrl::setDisabledControlVariable(LLControlVariable* control)
+{
+ if (mDisabledControlVariable)
+ {
+ mDisabledControlConnection.disconnect(); // disconnect current signal
+ mDisabledControlVariable = NULL;
+ }
+ if (control)
+ {
+ mDisabledControlVariable = control;
+ mDisabledControlConnection = mDisabledControlVariable->getSignal()->connect(boost::bind(&controlListener, _2, getUICtrlHandle(), std::string("disabled")));
+ setEnabled(!(mDisabledControlVariable->getValue().asBoolean()));
+ }
+}
+
+void LLUICtrl::setMakeVisibleControlVariable(LLControlVariable* control)
+{
+ if (mMakeVisibleControlVariable)
+ {
+ mMakeVisibleControlConnection.disconnect(); // disconnect current signal
+ mMakeVisibleControlVariable = NULL;
+ }
+ if (control)
+ {
+ mMakeVisibleControlVariable = control;
+ mMakeVisibleControlConnection = mMakeVisibleControlVariable->getSignal()->connect(boost::bind(&controlListener, _2, getUICtrlHandle(), std::string("visible")));
+ setVisible(mMakeVisibleControlVariable->getValue().asBoolean());
+ }
+}
+
+void LLUICtrl::setMakeInvisibleControlVariable(LLControlVariable* control)
+{
+ if (mMakeInvisibleControlVariable)
+ {
+ mMakeInvisibleControlConnection.disconnect(); // disconnect current signal
+ mMakeInvisibleControlVariable = NULL;
+ }
+ if (control)
+ {
+ mMakeInvisibleControlVariable = control;
+ mMakeInvisibleControlConnection = mMakeInvisibleControlVariable->getSignal()->connect(boost::bind(&controlListener, _2, getUICtrlHandle(), std::string("invisible")));
+ setVisible(!(mMakeInvisibleControlVariable->getValue().asBoolean()));
+ }
+}
+// static
+bool LLUICtrl::controlListener(const LLSD& newvalue, LLHandle<LLUICtrl> handle, std::string type)
+{
+ LLUICtrl* ctrl = handle.get();
+ if (ctrl)
+ {
+ if (type == "value")
+ {
+ ctrl->setValue(newvalue);
+ return true;
+ }
+ else if (type == "enabled")
+ {
+ ctrl->setEnabled(newvalue.asBoolean());
+ return true;
+ }
+ else if(type =="disabled")
+ {
+ ctrl->setEnabled(!newvalue.asBoolean());
+ return true;
+ }
+ else if (type == "visible")
+ {
+ ctrl->setVisible(newvalue.asBoolean());
+ return true;
+ }
+ else if (type == "invisible")
+ {
+ ctrl->setVisible(!newvalue.asBoolean());
+ return true;
+ }
+ }
+ return false;
}
// virtual
@@ -212,7 +506,7 @@ void LLUICtrl::onFocusReceived()
// find first view in hierarchy above new focus that is a LLUICtrl
LLView* viewp = getParent();
- LLUICtrl* last_focus = gFocusMgr.getLastKeyboardFocus();
+ LLUICtrl* last_focus = dynamic_cast<LLUICtrl*>(gFocusMgr.getLastKeyboardFocus());
while (viewp && !viewp->isCtrl())
{
@@ -248,12 +542,10 @@ void LLUICtrl::onFocusLost()
}
}
-void LLUICtrl::onLostTop()
+void LLUICtrl::onTopLost()
{
- if (mLostTopCallback)
- {
- mLostTopCallback(this, mCallbackUserData);
- }
+ // trigger callbacks
+ LLFocusableElement::onTopLost();
}
@@ -278,12 +570,13 @@ BOOL LLUICtrl::acceptsTextInput() const
//virtual
BOOL LLUICtrl::isDirty() const
{
- return FALSE;
+ return mViewModel->isDirty();
};
//virtual
void LLUICtrl::resetDirty()
{
+ mViewModel->resetDirty();
}
// virtual
@@ -456,7 +749,8 @@ BOOL LLUICtrl::focusNextItem(BOOL text_fields_only)
{
// this assumes that this method is called on the focus root.
LLCtrlQuery query = getTabOrderQuery();
- if(text_fields_only || LLUI::sConfigGroup->getBOOL("TabToTextFieldsOnly"))
+ static LLUICachedControl<bool> tab_to_text_fields_only ("TabToTextFieldsOnly", false);
+ if(text_fields_only || tab_to_text_fields_only)
{
query.addPreFilter(LLUICtrl::LLTextInputFilter::getInstance());
}
@@ -468,7 +762,8 @@ BOOL LLUICtrl::focusPrevItem(BOOL text_fields_only)
{
// this assumes that this method is called on the focus root.
LLCtrlQuery query = getTabOrderQuery();
- if(text_fields_only || LLUI::sConfigGroup->getBOOL("TabToTextFieldsOnly"))
+ static LLUICachedControl<bool> tab_to_text_fields_only ("TabToTextFieldsOnly", false);
+ if(text_fields_only || tab_to_text_fields_only)
{
query.addPreFilter(LLUICtrl::LLTextInputFilter::getInstance());
}
@@ -492,65 +787,6 @@ LLUICtrl* LLUICtrl::findRootMostFocusRoot()
return focus_root;
}
-
-/*
-// Don't let the children handle the tool tip. Handle it here instead.
-BOOL LLUICtrl::handleToolTip(S32 x, S32 y, std::string& msg, LLRect* sticky_rect_screen)
-{
- BOOL handled = FALSE;
- if (getVisible() && pointInView( x, y ) )
- {
- if( !mToolTipMsg.empty() )
- {
- msg = mToolTipMsg;
-
- // Convert rect local to screen coordinates
- localPointToScreen(
- 0, 0,
- &(sticky_rect_screen->mLeft), &(sticky_rect_screen->mBottom) );
- localPointToScreen(
- getRect().getWidth(), getRect().getHeight(),
- &(sticky_rect_screen->mRight), &(sticky_rect_screen->mTop) );
-
- handled = TRUE;
- }
- }
-
- if (!handled)
- {
- return LLView::handleToolTip(x, y, msg, sticky_rect_screen);
- }
-
- return handled;
-}*/
-
-void LLUICtrl::initFromXML(LLXMLNodePtr node, LLView* parent)
-{
- BOOL has_tab_stop = hasTabStop();
- node->getAttributeBOOL("tab_stop", has_tab_stop);
-
- setTabStop(has_tab_stop);
-
- LLView::initFromXML(node, parent);
-}
-
-LLXMLNodePtr LLUICtrl::getXML(bool save_children) const
-{
- LLXMLNodePtr node = LLView::getXML(save_children);
- node->createChild("tab_stop", TRUE)->setBoolValue(hasTabStop());
-
- return node;
-}
-
-//static
-LLView* LLUICtrl::fromXML(LLXMLNodePtr node, LLView* parent, class LLUICtrlFactory* factory)
-{
- LLUICtrl* ctrl = new LLUICtrl();
- ctrl->initFromXML(node, parent);
- return ctrl;
-}
-
-
// Skip over any parents that are not LLUICtrl's
// Used in focus logic since only LLUICtrl elements can have focus
LLUICtrl* LLUICtrl::getParentUICtrl() const
@@ -570,6 +806,16 @@ LLUICtrl* LLUICtrl::getParentUICtrl() const
return NULL;
}
+// *TODO: Deprecate; for backwards compatability only:
+boost::signals2::connection LLUICtrl::setCommitCallback( boost::function<void (LLUICtrl*,void*)> cb, void* data)
+{
+ return setCommitCallback( boost::bind(cb, _1, data));
+}
+boost::signals2::connection LLUICtrl::setValidateBeforeCommit( boost::function<bool (const LLSD& data)> cb )
+{
+ return mValidateSignal.connect(boost::bind(cb, _2));
+}
+
// virtual
void LLUICtrl::setTentative(BOOL b)
{
@@ -583,18 +829,37 @@ BOOL LLUICtrl::getTentative() const
}
// virtual
-void LLUICtrl::setDoubleClickCallback( void (*cb)(void*) )
-{
-}
-
-// virtual
void LLUICtrl::setColor(const LLColor4& color)
{ }
// virtual
-void LLUICtrl::setMinValue(LLSD min_value)
+void LLUICtrl::setAlpha(F32 alpha)
{ }
-// virtual
-void LLUICtrl::setMaxValue(LLSD max_value)
-{ }
+
+namespace LLInitParam
+{
+ template<>
+ bool ParamCompare<LLUICtrl::commit_callback_t>::equals(
+ const LLUICtrl::commit_callback_t &a,
+ const LLUICtrl::commit_callback_t &b)
+ {
+ return false;
+ }
+
+ template<>
+ bool ParamCompare<LLUICtrl::focus_callback_t>::equals(
+ const LLUICtrl::focus_callback_t &a,
+ const LLUICtrl::focus_callback_t &b)
+ {
+ return false;
+ }
+
+ template<>
+ bool ParamCompare<LLUICtrl::enable_callback_t>::equals(
+ const LLUICtrl::enable_callback_t &a,
+ const LLUICtrl::enable_callback_t &b)
+ {
+ return false;
+ }
+}
diff --git a/indra/llui/lluictrl.h b/indra/llui/lluictrl.h
index db41af8470..3e2e1f41a1 100644
--- a/indra/llui/lluictrl.h
+++ b/indra/llui/lluictrl.h
@@ -34,57 +34,138 @@
#ifndef LL_LLUICTRL_H
#define LL_LLUICTRL_H
-#include "llview.h"
+#include "llboost.h"
#include "llrect.h"
#include "llsd.h"
+#include <boost/function.hpp>
+
+#include "llinitparam.h"
+#include "llview.h"
+#include "llviewmodel.h"
+const BOOL TAKE_FOCUS_YES = TRUE;
+const BOOL TAKE_FOCUS_NO = FALSE;
-class LLFocusableElement
+// NOTE: the LLFocusableElement class declaration has been moved from here to llfocusmgr.h.
+
+class LLUICtrl
+ : public LLView, public boost::signals2::trackable
{
- friend class LLFocusMgr; // allow access to focus change handlers
public:
- LLFocusableElement();
- virtual ~LLFocusableElement();
- virtual void setFocus( BOOL b );
- virtual BOOL hasFocus() const;
- void setFocusLostCallback(void (*cb)(LLFocusableElement* caller, void*), void* user_data = NULL) { mFocusLostCallback = cb; mFocusCallbackUserData = user_data; }
- void setFocusReceivedCallback( void (*cb)(LLFocusableElement*, void*), void* user_data = NULL) { mFocusReceivedCallback = cb; mFocusCallbackUserData = user_data; }
- void setFocusChangedCallback( void (*cb)(LLFocusableElement*, void*), void* user_data = NULL ) { mFocusChangedCallback = cb; mFocusCallbackUserData = user_data; }
+ typedef boost::function<void (LLUICtrl* ctrl, const LLSD& param)> commit_callback_t;
+ typedef boost::signals2::signal<void (LLUICtrl* ctrl, const LLSD& param)> commit_signal_t;
+ // *TODO: add xml support for this type of signal in the future
+ typedef boost::signals2::signal<void (LLUICtrl* ctrl, S32 x, S32 y, MASK mask)> mouse_signal_t;
+
+ typedef boost::function<bool (LLUICtrl* ctrl, const LLSD& param)> enable_callback_t;
+ typedef boost::signals2::signal<bool (LLUICtrl* ctrl, const LLSD& param), boost_boolean_combiner> enable_signal_t;
+
+ struct CallbackParam : public LLInitParam::Block<CallbackParam>
+ {
+ Ignored name;
-protected:
- virtual void onFocusReceived();
- virtual void onFocusLost();
- void (*mFocusLostCallback)( LLFocusableElement* caller, void* userdata );
- void (*mFocusReceivedCallback)( LLFocusableElement* ctrl, void* userdata );
- void (*mFocusChangedCallback)( LLFocusableElement* ctrl, void* userdata );
- void* mFocusCallbackUserData;
-};
+ Optional<std::string> function_name;
+ Optional<LLSD> parameter;
+
+ Optional<std::string> control_name;
+
+ CallbackParam()
+ : name("name"),
+ function_name("function"),
+ parameter("parameter"),
+ control_name("control") // Shortcut to control -> "control_name" for backwards compatability
+ {
+ addSynonym(parameter, "userdata");
+ }
+ };
+
+ struct CommitCallbackParam : public LLInitParam::Block<CommitCallbackParam, CallbackParam >
+ {
+ Optional<commit_callback_t> function;
+ };
+
+ struct EnableCallbackParam : public LLInitParam::Block<EnableCallbackParam, CallbackParam >
+ {
+ Optional<enable_callback_t> function;
+ };
+
+ struct EnableControls : public LLInitParam::Choice<EnableControls>
+ {
+ Alternative<std::string> enabled;
+ Alternative<std::string> disabled;
+
+ EnableControls()
+ : enabled("enabled_control"),
+ disabled("disabled_control")
+ {}
+ };
+ struct ControlVisibility : public LLInitParam::Choice<ControlVisibility>
+ {
+ Alternative<std::string> visible;
+ Alternative<std::string> invisible;
+
+ ControlVisibility()
+ : visible("visiblity_control"),
+ invisible("invisiblity_control")
+ {}
+ };
+ struct Params : public LLInitParam::Block<Params, LLView::Params>
+ {
+ Optional<std::string> label;
+ Optional<bool> tab_stop;
+ Optional<LLSD> initial_value;
+
+ Optional<CommitCallbackParam> init_callback,
+ commit_callback;
+ Optional<EnableCallbackParam> validate_callback;
+
+ Optional<CommitCallbackParam> mouseenter_callback;
+ Optional<CommitCallbackParam> mouseleave_callback;
+
+ Optional<focus_callback_t> focus_lost_callback;
+
+ Optional<std::string> control_name;
+ Optional<EnableControls> enabled_controls;
+ Optional<ControlVisibility> controls_visibility;
+
+ Params();
+ };
-class LLUICtrl
-: public LLView, public LLFocusableElement
-{
-public:
- typedef void (*LLUICtrlCallback)(LLUICtrl* ctrl, void* userdata);
- typedef BOOL (*LLUICtrlValidate)(LLUICtrl* ctrl, void* userdata);
-
- LLUICtrl();
- LLUICtrl( const std::string& name, const LLRect& rect, BOOL mouse_opaque,
- LLUICtrlCallback callback,
- void* callback_userdata,
- U32 reshape=FOLLOWS_NONE);
/*virtual*/ ~LLUICtrl();
+ void initFromParams(const Params& p);
+protected:
+ friend class LLUICtrlFactory;
+ static const Params& getDefaultParams();
+ LLUICtrl(const Params& p = getDefaultParams(),
+ const LLViewModelPtr& viewmodel=LLViewModelPtr(new LLViewModel));
+
+ void initCommitCallback(const CommitCallbackParam& cb, commit_signal_t& sig);
+ void initEnableCallback(const EnableCallbackParam& cb, enable_signal_t& sig);
+
+ // We need this virtual so we can override it with derived versions
+ virtual LLViewModel* getViewModel() const;
+ // We shouldn't ever need to set this directly
+ //virtual void setViewModel(const LLViewModelPtr&);
+
+public:
// LLView interface
- /*virtual*/ void initFromXML(LLXMLNodePtr node, LLView* parent);
- /*virtual*/ LLXMLNodePtr getXML(bool save_children = true) const;
/*virtual*/ BOOL setLabelArg( const std::string& key, const LLStringExplicit& text );
/*virtual*/ void onFocusReceived();
/*virtual*/ void onFocusLost();
+ /*virtual*/ void onTopLost();
/*virtual*/ BOOL isCtrl() const;
/*virtual*/ void setTentative(BOOL b);
/*virtual*/ BOOL getTentative() const;
+ /*virtual*/ void onMouseEnter(S32 x, S32 y, MASK mask);
+ /*virtual*/ void onMouseLeave(S32 x, S32 y, MASK mask);
+ /*virtual*/ BOOL canFocusChildren() const;
+ /*virtual*/ BOOL handleMouseDown(S32 x, S32 y, MASK mask);
+ /*virtual*/ BOOL handleMouseUp(S32 x, S32 y, MASK mask);
+ /*virtual*/ BOOL handleRightMouseDown(S32 x, S32 y, MASK mask);
+ /*virtual*/ BOOL handleRightMouseUp(S32 x, S32 y, MASK mask);
// From LLFocusableElement
/*virtual*/ void setFocus( BOOL b );
@@ -97,7 +178,23 @@ public:
virtual class LLCtrlListInterface* getListInterface();
virtual class LLCtrlScrollInterface* getScrollInterface();
+ bool setControlValue(const LLSD& value);
+ void setControlVariable(LLControlVariable* control);
+ virtual void setControlName(const std::string& control, LLView *context = NULL);
+
+ LLControlVariable* getControlVariable() { return mControlVariable; }
+
+ void setEnabledControlVariable(LLControlVariable* control);
+ void setDisabledControlVariable(LLControlVariable* control);
+ void setMakeVisibleControlVariable(LLControlVariable* control);
+ void setMakeInvisibleControlVariable(LLControlVariable* control);
+
+ virtual void setValue(const LLSD& value);
virtual LLSD getValue() const;
+ /// When two widgets are displaying the same data (e.g. during a skin
+ /// change), share their ViewModel.
+ virtual void shareViewModelFrom(const LLUICtrl& other);
+
virtual BOOL setTextArg( const std::string& key, const LLStringExplicit& text );
virtual void setIsChrome(BOOL is_chrome);
@@ -108,17 +205,14 @@ public:
virtual BOOL isDirty() const; // Defauls to false
virtual void resetDirty(); //Defaults to no-op
- // Call appropriate callbacks
- virtual void onLostTop(); // called when registered as top ctrl and user clicks elsewhere
+ // Call appropriate callback
virtual void onCommit();
// Default to no-op:
virtual void onTabInto();
virtual void clear();
- virtual void setDoubleClickCallback( void (*cb)(void*) );
virtual void setColor(const LLColor4& color);
- virtual void setMinValue(LLSD min_value);
- virtual void setMaxValue(LLSD max_value);
+ virtual void setAlpha(F32 alpha);
BOOL focusNextItem(BOOL text_entry_only);
BOOL focusPrevItem(BOOL text_entry_only);
@@ -126,6 +220,7 @@ public:
BOOL focusLastItem(BOOL prefer_text_fields = FALSE);
// Non Virtuals
+ LLHandle<LLUICtrl> getUICtrlHandle() const { return mUICtrlHandle; }
BOOL getIsChrome() const;
void setTabStop( BOOL b );
@@ -133,16 +228,22 @@ public:
LLUICtrl* getParentUICtrl() const;
- void* getCallbackUserData() const { return mCallbackUserData; }
- void setCallbackUserData( void* data ) { mCallbackUserData = data; }
+ boost::signals2::connection setCommitCallback( const commit_signal_t::slot_type& cb ) { return mCommitSignal.connect(cb); }
+ boost::signals2::connection setValidateCallback( const enable_signal_t::slot_type& cb ) { return mValidateSignal.connect(cb); }
+
+ boost::signals2::connection setMouseEnterCallback( const commit_signal_t::slot_type& cb ) { return mMouseEnterSignal.connect(cb); }
+ boost::signals2::connection setMouseLeaveCallback( const commit_signal_t::slot_type& cb ) { return mMouseLeaveSignal.connect(cb); }
- void setCommitCallback( void (*cb)(LLUICtrl*, void*) ) { mCommitCallback = cb; }
- void setValidateBeforeCommit( BOOL(*cb)(LLUICtrl*, void*) ) { mValidateCallback = cb; }
- void setLostTopCallback( void (*cb)(LLUICtrl*, void*) ) { mLostTopCallback = cb; }
+ boost::signals2::connection setMouseDownCallback( const mouse_signal_t::slot_type& cb ) { return mMouseDownSignal.connect(cb); }
+ boost::signals2::connection setMouseUpCallback( const mouse_signal_t::slot_type& cb ) { return mMouseUpSignal.connect(cb); }
+ boost::signals2::connection setRightMouseDownCallback( const mouse_signal_t::slot_type& cb ) { return mRightMouseDownSignal.connect(cb); }
+ boost::signals2::connection setRightMouseUpCallback( const mouse_signal_t::slot_type& cb ) { return mRightMouseUpSignal.connect(cb); }
- static LLView* fromXML(LLXMLNodePtr node, LLView* parent, class LLUICtrlFactory* factory);
+ // *TODO: Deprecate; for backwards compatability only:
+ boost::signals2::connection setCommitCallback( boost::function<void (LLUICtrl*,void*)> cb, void* data);
+ boost::signals2::connection setValidateBeforeCommit( boost::function<bool (const LLSD& data)> cb );
- LLUICtrl* findRootMostFocusRoot();
+ LLUICtrl* findRootMostFocusRoot();
class LLTextInputFilter : public LLQueryFilter, public LLSingleton<LLTextInputFilter>
{
@@ -151,22 +252,70 @@ public:
return filterResult_t(view->isCtrl() && static_cast<const LLUICtrl *>(view)->acceptsTextInput(), TRUE);
}
};
+
+ template <typename F, typename DERIVED> class CallbackRegistry : public LLRegistrySingleton<std::string, F, DERIVED >
+ {};
+ class CommitCallbackRegistry : public CallbackRegistry<commit_callback_t, CommitCallbackRegistry>{};
+ class EnableCallbackRegistry : public CallbackRegistry<enable_callback_t, EnableCallbackRegistry>{};
+
protected:
- void (*mCommitCallback)( LLUICtrl* ctrl, void* userdata );
- void (*mLostTopCallback)( LLUICtrl* ctrl, void* userdata );
- BOOL (*mValidateCallback)( LLUICtrl* ctrl, void* userdata );
+ static bool controlListener(const LLSD& newvalue, LLHandle<LLUICtrl> handle, std::string type);
- void* mCallbackUserData;
+ commit_signal_t mCommitSignal;
+ enable_signal_t mValidateSignal;
+ commit_signal_t mMouseEnterSignal;
+ commit_signal_t mMouseLeaveSignal;
+
+ mouse_signal_t mMouseDownSignal;
+ mouse_signal_t mMouseUpSignal;
+ mouse_signal_t mRightMouseDownSignal;
+ mouse_signal_t mRightMouseUpSignal;
+
+ LLViewModelPtr mViewModel;
+
+ LLControlVariable* mControlVariable;
+ boost::signals2::connection mControlConnection;
+ LLControlVariable* mEnabledControlVariable;
+ boost::signals2::connection mEnabledControlConnection;
+ LLControlVariable* mDisabledControlVariable;
+ boost::signals2::connection mDisabledControlConnection;
+ LLControlVariable* mMakeVisibleControlVariable;
+ boost::signals2::connection mMakeVisibleControlConnection;
+ LLControlVariable* mMakeInvisibleControlVariable;
+ boost::signals2::connection mMakeInvisibleControlConnection;
private:
BOOL mTabStop;
BOOL mIsChrome;
BOOL mTentative;
+ LLRootHandle<LLUICtrl> mUICtrlHandle;
class DefaultTabGroupFirstSorter;
};
+namespace LLInitParam
+{
+ template<>
+ bool ParamCompare<LLUICtrl::commit_callback_t>::equals(
+ const LLUICtrl::commit_callback_t &a,
+ const LLUICtrl::commit_callback_t &b);
+
+ template<>
+ bool ParamCompare<LLUICtrl::enable_callback_t>::equals(
+ const LLUICtrl::enable_callback_t &a,
+ const LLUICtrl::enable_callback_t &b);
+
+ template<>
+ bool ParamCompare<LLUICtrl::focus_callback_t>::equals(
+ const LLUICtrl::focus_callback_t &a,
+ const LLUICtrl::focus_callback_t &b);
+
+ template<>
+ bool ParamCompare<LLLazyValue<LLColor4> >::equals(
+ const LLLazyValue<LLColor4> &a, const LLLazyValue<LLColor4> &b);
+}
+
#endif // LL_LLUICTRL_H
diff --git a/indra/llui/lluictrlfactory.cpp b/indra/llui/lluictrlfactory.cpp
index 983cc53f69..1161101f90 100644
--- a/indra/llui/lluictrlfactory.cpp
+++ b/indra/llui/lluictrlfactory.cpp
@@ -41,73 +41,44 @@
#include "llcontrol.h"
#include "lldir.h"
#include "v4color.h"
+#include "v3dmath.h"
+#include "llquaternion.h"
// this library includes
-#include "llbutton.h"
-#include "llcheckboxctrl.h"
-//#include "llcolorswatch.h"
-#include "llcombobox.h"
-#include "llcontrol.h"
-#include "lldir.h"
-#include "llevent.h"
#include "llfloater.h"
-#include "lliconctrl.h"
-#include "lllineeditor.h"
-#include "llmenugl.h"
-#include "llradiogroup.h"
-#include "llscrollcontainer.h"
-#include "llscrollingpanellist.h"
-#include "llscrolllistctrl.h"
-#include "llslider.h"
-#include "llsliderctrl.h"
-#include "llmultislider.h"
-#include "llmultisliderctrl.h"
-#include "llspinctrl.h"
-#include "lltabcontainer.h"
-#include "lltabcontainervertical.h"
-#include "lltextbox.h"
-#include "lltexteditor.h"
-#include "llui.h"
-#include "llviewborder.h"
-
-const char XML_HEADER[] = "<?xml version=\"1.0\" encoding=\"utf-8\" standalone=\"yes\" ?>\n";
-
-const S32 HPAD = 4;
-const S32 VPAD = 4;
-const S32 FLOATER_H_MARGIN = 15;
-const S32 MIN_WIDGET_HEIGHT = 10;
-
-std::vector<std::string> LLUICtrlFactory::sXUIPaths;
+
+LLFastTimer::DeclareTimer FTM_WIDGET_CONSTRUCTION("Widget Construction");
+LLFastTimer::DeclareTimer FTM_INIT_FROM_PARAMS("Widget InitFromParams");
+LLFastTimer::DeclareTimer FTM_WIDGET_SETUP("Widget Setup");
+
+//-----------------------------------------------------------------------------
// UI Ctrl class for padding
class LLUICtrlLocate : public LLUICtrl
{
public:
- LLUICtrlLocate() : LLUICtrl(std::string("locate"), LLRect(0,0,0,0), FALSE, NULL, NULL) { setTabStop(FALSE); }
- virtual void draw() { }
-
- static LLView *fromXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFactory *factory)
+ struct Params : public LLInitParam::Block<Params, LLUICtrl::Params>
{
- std::string name("pad");
- node->getAttributeString("name", name);
+ Params()
+ {
+ name = "locate";
+ tab_stop = false;
+ }
+ };
+
+ LLUICtrlLocate(const Params& p) : LLUICtrl(p) {}
+ virtual void draw() { }
- LLUICtrlLocate *new_ctrl = new LLUICtrlLocate();
- new_ctrl->setName(name);
- new_ctrl->initFromXML(node, parent);
- return new_ctrl;
- }
};
-static LLRegisterWidget<LLUICtrlLocate> r1("locate");
-static LLRegisterWidget<LLUICtrlLocate> r2("pad");
+static LLDefaultChildRegistry::Register<LLUICtrlLocate> r1("locate");
//-----------------------------------------------------------------------------
// LLUICtrlFactory()
//-----------------------------------------------------------------------------
LLUICtrlFactory::LLUICtrlFactory()
- : mDummyPanel(NULL)
+ : mDummyPanel(NULL) // instantiated when first needed
{
- setupPaths();
}
LLUICtrlFactory::~LLUICtrlFactory()
@@ -116,141 +87,133 @@ LLUICtrlFactory::~LLUICtrlFactory()
mDummyPanel = NULL;
}
-void LLUICtrlFactory::setupPaths()
+void LLUICtrlFactory::loadWidgetTemplate(const std::string& widget_tag, LLInitParam::BaseBlock& block)
{
- std::string filename = gDirUtilp->getExpandedFilename(LL_PATH_SKINS, "paths.xml");
+ std::string filename = std::string("widgets") + gDirUtilp->getDirDelimiter() + widget_tag + ".xml";
+ LLXMLNodePtr root_node;
- LLXMLNodePtr root;
- BOOL success = LLXMLNode::parseFile(filename, root, NULL);
- sXUIPaths.clear();
-
- if (success)
+ if (LLUICtrlFactory::getLayeredXMLNode(filename, root_node))
{
- LLXMLNodePtr path;
-
- for (path = root->getFirstChild(); path.notNull(); path = path->getNextSibling())
- {
- LLUIString path_val_ui(path->getValue());
- std::string language = LLUI::getLanguage();
- path_val_ui.setArg("[LANGUAGE]", language);
-
- if (std::find(sXUIPaths.begin(), sXUIPaths.end(), path_val_ui.getString()) == sXUIPaths.end())
- {
- sXUIPaths.push_back(path_val_ui.getString());
- }
- }
+ LLXUIParser::instance().readXUI(root_node, block);
}
- else // parsing failed
- {
- std::string slash = gDirUtilp->getDirDelimiter();
- std::string dir = "xui" + slash + "en-us";
- llwarns << "XUI::config file unable to open: " << filename << llendl;
- sXUIPaths.push_back(dir);
- }
-}
-
-// static
-const std::vector<std::string>& LLUICtrlFactory::getXUIPaths()
-{
- return sXUIPaths;
}
-//-----------------------------------------------------------------------------
-// getLayeredXMLNode()
-//-----------------------------------------------------------------------------
-bool LLUICtrlFactory::getLayeredXMLNode(const std::string &xui_filename, LLXMLNodePtr& root)
+//static
+void LLUICtrlFactory::createChildren(LLView* viewp, LLXMLNodePtr node, const widget_registry_t& registry, LLXMLNodePtr output_node)
{
- std::string full_filename = gDirUtilp->findSkinnedFilename(sXUIPaths.front(), xui_filename);
- if (full_filename.empty())
- {
- llwarns << "Couldn't find UI description file: " << sXUIPaths.front() + gDirUtilp->getDirDelimiter() + xui_filename << llendl;
- return false;
- }
+ if (node.isNull()) return;
- if (!LLXMLNode::parseFile(full_filename, root, NULL))
+ for (LLXMLNodePtr child_node = node->getFirstChild(); child_node.notNull(); child_node = child_node->getNextSibling())
{
- // try filename as passed in since sometimes we load an xml file from a user-supplied path
- if (!LLXMLNode::parseFile(xui_filename, root, NULL))
+ LLXMLNodePtr outputChild;
+ if (output_node)
{
- llwarns << "Problem reading UI description file: " << xui_filename << llendl;
- return false;
+ outputChild = output_node->createChild("", FALSE);
}
- }
-
- LLXMLNodePtr updateRoot;
-
- std::vector<std::string>::const_iterator itor;
- for (itor = sXUIPaths.begin(), ++itor; itor != sXUIPaths.end(); ++itor)
- {
- std::string nodeName;
- std::string updateName;
-
- std::string layer_filename = gDirUtilp->findSkinnedFilename((*itor), xui_filename);
- if(layer_filename.empty())
+ if (!instance().createFromXML(child_node, viewp, LLStringUtil::null, registry, outputChild))
{
- // no localized version of this file, that's ok, keep looking
- continue;
+ std::string child_name = std::string(child_node->getName()->mString);
+ llwarns << "Could not create widget named " << child_node->getName()->mString << llendl;
}
- if (!LLXMLNode::parseFile(layer_filename, updateRoot, NULL))
+ if (outputChild && !outputChild->mChildren && outputChild->mAttributes.empty() && outputChild->getValue().empty())
{
- llwarns << "Problem reading localized UI description file: " << (*itor) + gDirUtilp->getDirDelimiter() + xui_filename << llendl;
- return false;
+ output_node->deleteChild(outputChild);
}
+ }
- updateRoot->getAttributeString("name", updateName);
- root->getAttributeString("name", nodeName);
+}
+
+static LLFastTimer::DeclareTimer FTM_XML_PARSE("XML Reading/Parsing");
+//-----------------------------------------------------------------------------
+// getLayeredXMLNode()
+//-----------------------------------------------------------------------------
+bool LLUICtrlFactory::getLayeredXMLNode(const std::string &xui_filename, LLXMLNodePtr& root)
+{
+ LLFastTimer timer(FTM_XML_PARSE);
+ return LLXMLNode::getLayeredXMLNode(xui_filename, root, LLUI::getXUIPaths());
+}
- if (updateName == nodeName)
- {
- LLXMLNode::updateNode(root, updateRoot);
- }
- }
- return true;
+//-----------------------------------------------------------------------------
+// getLocalizedXMLNode()
+//-----------------------------------------------------------------------------
+bool LLUICtrlFactory::getLocalizedXMLNode(const std::string &xui_filename, LLXMLNodePtr& root)
+{
+ LLFastTimer timer(FTM_XML_PARSE);
+ std::string full_filename = gDirUtilp->findSkinnedFilename(LLUI::getLocalizedSkinPath(), xui_filename);
+ if (!LLXMLNode::parseFile(full_filename, root, NULL))
+ {
+ return false;
+ }
+ else
+ {
+ return true;
+ }
}
+static LLFastTimer::DeclareTimer FTM_BUILD_FLOATERS("Build Floaters");
//-----------------------------------------------------------------------------
// buildFloater()
//-----------------------------------------------------------------------------
-void LLUICtrlFactory::buildFloater(LLFloater* floaterp, const std::string& filename,
- const LLCallbackMap::map_t* factory_map, BOOL open) /* Flawfinder: ignore */
+void LLUICtrlFactory::buildFloater(LLFloater* floaterp, const std::string& filename, LLXMLNodePtr output_node)
{
+ LLFastTimer timer(FTM_BUILD_FLOATERS);
LLXMLNodePtr root;
- if (!LLUICtrlFactory::getLayeredXMLNode(filename, root))
+ //if exporting, only load the language being exported,
+ //instead of layering localized version on top of english
+ if (output_node)
+ {
+ if (!LLUICtrlFactory::getLocalizedXMLNode(filename, root))
+ {
+ llwarns << "Couldn't parse floater from: " << LLUI::getLocalizedSkinPath() + gDirUtilp->getDirDelimiter() + filename << llendl;
+ return;
+ }
+ }
+ else if (!LLUICtrlFactory::getLayeredXMLNode(filename, root))
{
+ llwarns << "Couldn't parse floater from: " << LLUI::getSkinPath() + gDirUtilp->getDirDelimiter() + filename << llendl;
return;
}
// root must be called floater
- if( !(root->hasName("floater") || root->hasName("multi_floater") ) )
+ if( !(root->hasName("floater") || root->hasName("multi_floater")) )
{
llwarns << "Root node should be named floater in: " << filename << llendl;
return;
}
- if (factory_map)
+ lldebugs << "Building floater " << filename << llendl;
+ mFileNames.push_back(gDirUtilp->findSkinnedFilename(LLUI::getSkinPath(), filename));
{
- mFactoryStack.push_front(factory_map);
- }
-
- floaterp->initFloaterXML(root, NULL, this, open); /* Flawfinder: ignore */
+ if (!floaterp->getFactoryMap().empty())
+ {
+ mFactoryStack.push_front(&floaterp->getFactoryMap());
+ }
- if (LLUI::sShowXUINames)
- {
- floaterp->setToolTip(filename);
- }
+ // for local registry callbacks; define in constructor, referenced in XUI or postBuild
+ floaterp->getCommitCallbackRegistrar().pushScope();
+ floaterp->getEnableCallbackRegistrar().pushScope();
+
+ floaterp->initFloaterXML(root, floaterp->getParent(), output_node);
- if (factory_map)
- {
- mFactoryStack.pop_front();
+ if (LLUI::sShowXUINames)
+ {
+ floaterp->setToolTip(filename);
+ }
+
+ floaterp->getCommitCallbackRegistrar().popScope();
+ floaterp->getEnableCallbackRegistrar().popScope();
+
+ if (!floaterp->getFactoryMap().empty())
+ {
+ mFactoryStack.pop_front();
+ }
}
-
- LLHandle<LLFloater> handle = floaterp->getHandle();
- mBuiltFloaters[handle] = filename;
+ mFileNames.pop_back();
}
//-----------------------------------------------------------------------------
@@ -258,34 +221,33 @@ void LLUICtrlFactory::buildFloater(LLFloater* floaterp, const std::string& filen
//-----------------------------------------------------------------------------
S32 LLUICtrlFactory::saveToXML(LLView* viewp, const std::string& filename)
{
- llofstream out(filename);
- if (!out.good())
- {
- llwarns << "Unable to open " << filename << " for output." << llendl;
- return 1;
- }
-
- out << XML_HEADER;
-
- LLXMLNodePtr xml_node = viewp->getXML();
-
- xml_node->writeToOstream(out);
-
- out.close();
return 0;
}
+static LLFastTimer::DeclareTimer FTM_BUILD_PANELS("Build Panels");
+
//-----------------------------------------------------------------------------
// buildPanel()
//-----------------------------------------------------------------------------
-BOOL LLUICtrlFactory::buildPanel(LLPanel* panelp, const std::string& filename,
- const LLCallbackMap::map_t* factory_map)
+BOOL LLUICtrlFactory::buildPanel(LLPanel* panelp, const std::string& filename, LLXMLNodePtr output_node)
{
+ LLFastTimer timer(FTM_BUILD_PANELS);
BOOL didPost = FALSE;
LLXMLNodePtr root;
- if (!LLUICtrlFactory::getLayeredXMLNode(filename, root))
+ //if exporting, only load the language being exported,
+ //instead of layering localized version on top of english
+ if (output_node)
+ {
+ if (!LLUICtrlFactory::getLocalizedXMLNode(filename, root))
+ {
+ llwarns << "Couldn't parse panel from: " << LLUI::getLocalizedSkinPath() + gDirUtilp->getDirDelimiter() + filename << llendl;
+ return didPost;
+ }
+ }
+ else if (!LLUICtrlFactory::getLayeredXMLNode(filename, root))
{
+ llwarns << "Couldn't parse panel from: " << LLUI::getSkinPath() + gDirUtilp->getDirDelimiter() + filename << llendl;
return didPost;
}
@@ -296,167 +258,52 @@ BOOL LLUICtrlFactory::buildPanel(LLPanel* panelp, const std::string& filename,
return didPost;
}
- if (factory_map)
- {
- mFactoryStack.push_front(factory_map);
- }
-
- didPost = panelp->initPanelXML(root, NULL, this);
-
- if (LLUI::sShowXUINames)
- {
- panelp->setToolTip(filename);
- }
-
- LLHandle<LLPanel> handle = panelp->getHandle();
- mBuiltPanels[handle] = filename;
-
- if (factory_map)
- {
- mFactoryStack.pop_front();
- }
-
- return didPost;
-}
-
-//-----------------------------------------------------------------------------
-// buildMenu()
-//-----------------------------------------------------------------------------
-LLMenuGL *LLUICtrlFactory::buildMenu(const std::string &filename, LLView* parentp)
-{
- // TomY TODO: Break this function into buildMenu and buildMenuBar
- LLXMLNodePtr root;
- LLMenuGL* menu;
-
- if (!LLUICtrlFactory::getLayeredXMLNode(filename, root))
- {
- return NULL;
- }
-
- // root must be called panel
- if( !root->hasName( "menu_bar" ) && !root->hasName( "menu" ))
- {
- llwarns << "Root node should be named menu bar or menu in : " << filename << llendl;
- return NULL;
- }
-
- if (root->hasName("menu"))
- {
- menu = (LLMenuGL*)LLMenuGL::fromXML(root, parentp, this);
- }
- else
- {
- menu = (LLMenuGL*)LLMenuBarGL::fromXML(root, parentp, this);
- }
-
- if (LLUI::sShowXUINames)
- {
- menu->setToolTip(filename);
- }
-
- return menu;
-}
-
-//-----------------------------------------------------------------------------
-// buildMenu()
-//-----------------------------------------------------------------------------
-LLPieMenu *LLUICtrlFactory::buildPieMenu(const std::string &filename, LLView* parentp)
-{
- LLXMLNodePtr root;
-
- if (!LLUICtrlFactory::getLayeredXMLNode(filename, root))
- {
- return NULL;
- }
-
- // root must be called panel
- if( !root->hasName( LL_PIE_MENU_TAG ))
- {
- llwarns << "Root node should be named " << LL_PIE_MENU_TAG << " in : " << filename << llendl;
- return NULL;
- }
-
- std::string name("menu");
- root->getAttributeString("name", name);
-
- LLPieMenu *menu = new LLPieMenu(name);
- parentp->addChild(menu);
- menu->initXML(root, parentp, this);
+ lldebugs << "Building panel " << filename << llendl;
- if (LLUI::sShowXUINames)
- {
- menu->setToolTip(filename);
- }
-
- return menu;
-}
-
-//-----------------------------------------------------------------------------
-// rebuild()
-//-----------------------------------------------------------------------------
-void LLUICtrlFactory::rebuild()
-{
- built_panel_t::iterator built_panel_it;
- for (built_panel_it = mBuiltPanels.begin();
- built_panel_it != mBuiltPanels.end();
- ++built_panel_it)
+ mFileNames.push_back(gDirUtilp->findSkinnedFilename(LLUI::getSkinPath(), filename));
{
- std::string filename = built_panel_it->second;
- LLPanel* panelp = built_panel_it->first.get();
- if (!panelp)
+ if (!panelp->getFactoryMap().empty())
{
- continue;
+ mFactoryStack.push_front(&panelp->getFactoryMap());
+ }
+
+ // for local registry callbacks; define in constructor, referenced in XUI or postBuild
+ panelp->getCommitCallbackRegistrar().pushScope();
+ panelp->getEnableCallbackRegistrar().pushScope();
+
+ didPost = panelp->initPanelXML(root, NULL, output_node);
+
+ panelp->getCommitCallbackRegistrar().popScope();
+ panelp->getEnableCallbackRegistrar().popScope();
+
+ if (LLUI::sShowXUINames)
+ {
+ panelp->setToolTip(filename);
}
- llinfos << "Rebuilding UI panel " << panelp->getName()
- << " from " << filename
- << llendl;
- BOOL visible = panelp->getVisible();
- panelp->setVisible(FALSE);
- panelp->setFocus(FALSE);
- panelp->deleteAllChildren();
-
- buildPanel(panelp, filename.c_str(), &panelp->getFactoryMap());
- panelp->setVisible(visible);
- }
- built_floater_t::iterator built_floater_it;
- for (built_floater_it = mBuiltFloaters.begin();
- built_floater_it != mBuiltFloaters.end();
- ++built_floater_it)
- {
- LLFloater* floaterp = built_floater_it->first.get();
- if (!floaterp)
+ if (!panelp->getFactoryMap().empty())
{
- continue;
+ mFactoryStack.pop_front();
}
- std::string filename = built_floater_it->second;
- llinfos << "Rebuilding UI floater " << floaterp->getName()
- << " from " << filename
- << llendl;
- BOOL visible = floaterp->getVisible();
- floaterp->setVisible(FALSE);
- floaterp->setFocus(FALSE);
- floaterp->deleteAllChildren();
-
- gFloaterView->removeChild(floaterp);
- buildFloater(floaterp, filename, &floaterp->getFactoryMap());
- floaterp->setVisible(visible);
}
+ mFileNames.pop_back();
+ return didPost;
}
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
-LLView *LLUICtrlFactory::createCtrlWidget(LLPanel *parent, LLXMLNodePtr node)
+static LLFastTimer::DeclareTimer FTM_CREATE_FROM_XML("Create child widget");
+
+LLView *LLUICtrlFactory::createFromXML(LLXMLNodePtr node, LLView* parent, const std::string& filename, const widget_registry_t& registry, LLXMLNodePtr output_node)
{
+ LLFastTimer timer(FTM_CREATE_FROM_XML);
std::string ctrl_type = node->getName()->mString;
LLStringUtil::toLower(ctrl_type);
-
- LLWidgetClassRegistry::factory_func_t func = LLWidgetClassRegistry::getInstance()->getCreatorFunc(ctrl_type);
- if (func == NULL)
+ const LLWidgetCreatorFunc* funcp = registry.getValue(ctrl_type);
+ if (funcp == NULL)
{
- llwarns << "Unknown control type " << ctrl_type << llendl;
return NULL;
}
@@ -464,27 +311,17 @@ LLView *LLUICtrlFactory::createCtrlWidget(LLPanel *parent, LLXMLNodePtr node)
{
if (mDummyPanel == NULL)
{
- mDummyPanel = new LLPanel;
+ LLPanel::Params p;
+ mDummyPanel = create<LLPanel>(p);
}
parent = mDummyPanel;
}
- LLView *ctrl = func(node, parent, this);
-
- return ctrl;
-}
-
-LLView* LLUICtrlFactory::createWidget(LLPanel *parent, LLXMLNodePtr node)
-{
- LLView* view = createCtrlWidget(parent, node);
-
- S32 tab_group = parent->getLastTabGroup();
- node->getAttributeS32("tab_group", tab_group);
-
- if (view)
+ LLView *view = (*funcp)(node, parent, output_node);
+ if (LLUI::sShowXUINames && view && !filename.empty())
{
- parent->addChild(view, tab_group);
+ view->setToolTip(filename);
}
-
+
return view;
}
@@ -507,7 +344,8 @@ LLPanel* LLUICtrlFactory::createFactoryPanel(const std::string& name)
return ret;
}
}
- return NULL;
+ LLPanel::Params panel_p;
+ return create<LLPanel>(panel_p);
}
//-----------------------------------------------------------------------------
@@ -517,11 +355,11 @@ BOOL LLUICtrlFactory::getAttributeColor(LLXMLNodePtr node, const std::string& na
{
std::string colorstring;
BOOL res = node->getAttributeString(name.c_str(), colorstring);
- if (res && LLUI::sColorsGroup)
+ if (res)
{
- if (LLUI::sColorsGroup->controlExists(colorstring))
+ if (LLUIColorTable::instance().colorExists(colorstring))
{
- color.setVec(LLUI::sColorsGroup->getColor(colorstring));
+ color.setVec(LLUIColorTable::instance().getColor(colorstring));
}
else
{
@@ -539,3 +377,30 @@ BOOL LLUICtrlFactory::getAttributeColor(LLXMLNodePtr node, const std::string& na
return res;
}
+//static
+void LLUICtrlFactory::setCtrlParent(LLView* view, LLView* parent, S32 tab_group)
+{
+ if (tab_group < 0) tab_group = parent->getLastTabGroup();
+ parent->addChild(view, tab_group);
+}
+
+
+// Avoid directly using LLUI and LLDir in the template code
+//static
+std::string LLUICtrlFactory::findSkinnedFilename(const std::string& filename)
+{
+ return gDirUtilp->findSkinnedFilename(LLUI::getSkinPath(), filename);
+}
+
+void LLUICtrlFactory::pushFactoryFunctions(const LLCallbackMap::map_t* map)
+{
+ mFactoryStack.push_back(map);
+}
+
+void LLUICtrlFactory::popFactoryFunctions()
+{
+ if (!mFactoryStack.empty())
+ {
+ mFactoryStack.pop_back();
+ }
+}
diff --git a/indra/llui/lluictrlfactory.h b/indra/llui/lluictrlfactory.h
index 5e7c24efc0..e47010c316 100644
--- a/indra/llui/lluictrlfactory.h
+++ b/indra/llui/lluictrlfactory.h
@@ -33,68 +33,391 @@
#ifndef LLUICTRLFACTORY_H
#define LLUICTRLFACTORY_H
+#include "llcallbackmap.h"
+#include "llinitparam.h"
+#include "llregistry.h"
+#include "llxmlnode.h"
+#include "llfasttimer.h"
+
+#include "llxuiparser.h"
+
+#include <boost/function.hpp>
#include <iosfwd>
#include <stack>
+#include <set>
-#include "llcallbackmap.h"
-#include "llfloater.h"
-
-class LLView;
class LLPanel;
+class LLFloater;
+class LLView;
-class LLUICtrlFactory : public LLSingleton<LLUICtrlFactory>
+
+// sort functor for typeid maps
+struct LLCompareTypeID
+{
+ bool operator()(const std::type_info* lhs, const std::type_info* rhs) const
+ {
+ return lhs->before(*rhs);
+ }
+};
+
+// lookup widget constructor funcs by widget name
+template <typename DERIVED_TYPE>
+class LLChildRegistry : public LLRegistrySingleton<std::string, LLWidgetCreatorFunc, DERIVED_TYPE>
{
public:
+ typedef LLRegistrySingleton<std::string, LLWidgetCreatorFunc, DERIVED_TYPE> super_t;
+ // local static instance for registering a particular widget
+ template<typename T>
+ class Register : public super_t::StaticRegistrar
+ {
+ public:
+ // register with either the provided builder, or the generic templated builder
+ Register(const char* tag, LLWidgetCreatorFunc func = NULL);
+ };
+
+protected:
+ LLChildRegistry() {}
+};
+
+class LLDefaultChildRegistry : public LLChildRegistry<LLDefaultChildRegistry>
+{
+protected:
+ LLDefaultChildRegistry(){}
+ friend class LLSingleton<LLDefaultChildRegistry>;
+};
+
+// lookup widget name by type
+class LLWidgetNameRegistry
+: public LLRegistrySingleton<const std::type_info*, std::string, LLWidgetNameRegistry , LLCompareTypeID>
+{};
+
+// lookup factory functions for default widget instances by widget type
+typedef LLView* (*dummy_widget_creator_func_t)(const std::string&);
+class LLDefaultWidgetRegistry
+: public LLRegistrySingleton<const std::type_info*, dummy_widget_creator_func_t, LLDefaultWidgetRegistry, LLCompareTypeID>
+{};
+
+// lookup function for generating empty param block by widget type
+typedef const LLInitParam::BaseBlock& (*empty_param_block_func_t)();
+class LLDefaultParamBlockRegistry
+: public LLRegistrySingleton<const std::type_info*, empty_param_block_func_t, LLDefaultParamBlockRegistry, LLCompareTypeID>
+{};
+
+extern LLFastTimer::DeclareTimer FTM_WIDGET_SETUP;
+extern LLFastTimer::DeclareTimer FTM_WIDGET_CONSTRUCTION;
+extern LLFastTimer::DeclareTimer FTM_INIT_FROM_PARAMS;
+
+class LLUICtrlFactory : public LLSingleton<LLUICtrlFactory>
+{
+private:
+ friend class LLSingleton<LLUICtrlFactory>;
LLUICtrlFactory();
- // do not call! needs to be public so run-time can clean up the singleton
- virtual ~LLUICtrlFactory();
+ ~LLUICtrlFactory();
- void setupPaths();
+ // only partial specialization allowed in inner classes, so use extra dummy parameter
+ template <typename PARAM_BLOCK, int DUMMY>
+ class ParamDefaults : public LLSingleton<ParamDefaults<PARAM_BLOCK, DUMMY> >
+ {
+ public:
+ ParamDefaults()
+ {
+ // recursively initialize from base class param block
+ ((typename PARAM_BLOCK::base_block_t&)mPrototype).fillFrom(ParamDefaults<typename PARAM_BLOCK::base_block_t, DUMMY>::instance().get());
+ // after initializing base classes, look up template file for this param block
+ std::string* param_block_tag = LLWidgetNameRegistry::instance().getValue(&typeid(PARAM_BLOCK));
+ if (param_block_tag)
+ {
+ LLUICtrlFactory::loadWidgetTemplate(*param_block_tag, mPrototype);
+ }
+ }
- void buildFloater(LLFloater* floaterp, const std::string &filename,
- const LLCallbackMap::map_t* factory_map = NULL, BOOL open = TRUE);
- BOOL buildPanel(LLPanel* panelp, const std::string &filename,
- const LLCallbackMap::map_t* factory_map = NULL);
+ const PARAM_BLOCK& get() { return mPrototype; }
- void removePanel(LLPanel* panelp) { mBuiltPanels.erase(panelp->getHandle()); }
- void removeFloater(LLFloater* floaterp) { mBuiltFloaters.erase(floaterp->getHandle()); }
+ private:
+ PARAM_BLOCK mPrototype;
+ };
- class LLMenuGL *buildMenu(const std::string &filename, LLView* parentp);
- class LLPieMenu *buildPieMenu(const std::string &filename, LLView* parentp);
+ // base case for recursion, there are NO base classes of LLInitParam::BaseBlock
+ template<int DUMMY>
+ class ParamDefaults<LLInitParam::BaseBlock, DUMMY> : public LLSingleton<ParamDefaults<LLInitParam::BaseBlock, DUMMY> >
+ {
+ public:
+ const LLInitParam::BaseBlock& get() { return mBaseBlock; }
+ private:
+ LLInitParam::BaseBlock mBaseBlock;
+ };
+
+public:
+
+ // get default parameter block for widget of a specific type
+ template<typename T>
+ static const typename T::Params& getDefaultParams()
+ {
+ //#pragma message("Generating ParamDefaults")
+ return ParamDefaults<typename T::Params, 0>::instance().get();
+ }
+
+ void buildFloater(LLFloater* floaterp, const std::string &filename, LLXMLNodePtr output_node);
+ BOOL buildPanel(LLPanel* panelp, const std::string &filename, LLXMLNodePtr output_node = NULL);
// Does what you want for LLFloaters and LLPanels
// Returns 0 on success
S32 saveToXML(LLView* viewp, const std::string& filename);
- // Rebuilds all currently built panels.
- void rebuild();
+ std::string getCurFileName() { return mFileNames.empty() ? "" : mFileNames.back(); }
static BOOL getAttributeColor(LLXMLNodePtr node, const std::string& name, LLColor4& color);
LLPanel* createFactoryPanel(const std::string& name);
- virtual LLView* createCtrlWidget(LLPanel *parent, LLXMLNodePtr node);
- virtual LLView* createWidget(LLPanel *parent, LLXMLNodePtr node);
+ void pushFactoryFunctions(const LLCallbackMap::map_t* map);
+ void popFactoryFunctions();
+
+ template<typename T>
+ static T* create(typename T::Params& params, LLView* parent = NULL)
+ {
+ //#pragma message("Generating LLUICtrlFactory::create")
+ params.fillFrom(ParamDefaults<typename T::Params, 0>::instance().get());
+ //S32 foo = "test";
+
+ if (!params.validateBlock())
+ {
+ llwarns << getInstance()->getCurFileName() << ": Invalid parameter block for " << typeid(T).name() << llendl;
+ }
+ T* widget = new T(params);
+ widget->initFromParams(params);
+ if (parent)
+ widget->setParent(parent);
+ return widget;
+ }
+
+ LLView* createFromXML(LLXMLNodePtr node, LLView* parent, const std::string& filename, const widget_registry_t&, LLXMLNodePtr output_node );
+
+ template<typename T>
+ static T* createFromFile(const std::string &filename, LLView *parent, const widget_registry_t& registry, LLXMLNodePtr output_node = NULL)
+ {
+ //#pragma message("Generating LLUICtrlFactory::createFromFile")
+ T* widget = NULL;
+
+ std::string skinned_filename = findSkinnedFilename(filename);
+ getInstance()->mFileNames.push_back(skinned_filename);
+ {
+ LLXMLNodePtr root_node;
+
+ //if exporting, only load the language being exported,
+ //instead of layering localized version on top of english
+ if (output_node)
+ {
+ if (!LLUICtrlFactory::getLocalizedXMLNode(filename, root_node))
+ {
+ llwarns << "Couldn't parse XUI file: " << filename << llendl;
+ goto fail;
+ }
+ }
+ else if (!LLUICtrlFactory::getLayeredXMLNode(filename, root_node))
+ {
+ llwarns << "Couldn't parse XUI file: " << skinned_filename << llendl;
+ goto fail;
+ }
+
+ LLView* view = getInstance()->createFromXML(root_node, parent, filename, registry, output_node);
+ if (view)
+ {
+ widget = dynamic_cast<T*>(view);
+ // not of right type, so delete it
+ if (!widget)
+ {
+ delete view;
+ view = NULL;
+ }
+
+ }
+ }
+fail:
+ getInstance()->mFileNames.pop_back();
+ return widget;
+ }
+
+ template<class T>
+ static T* getDefaultWidget(const std::string& name)
+ {
+ dummy_widget_creator_func_t* dummy_func = LLDefaultWidgetRegistry::instance().getValue(&typeid(T));
+ return dummy_func ? dynamic_cast<T*>((*dummy_func)(name)) : NULL;
+ }
+
+ template <class T>
+ static LLView* createDefaultWidget(const std::string& name)
+ {
+ typename T::Params params;
+ params.name(name);
+
+ return create<T>(params);
+ }
+
+ template<typename T>
+ static T* defaultBuilder(LLXMLNodePtr node, LLView *parent, LLXMLNodePtr output_node)
+ {
+ LLFastTimer timer(FTM_WIDGET_SETUP);
+
+ //#pragma message("Generating LLUICtrlFactory::defaultBuilder")
+ typename T::Params params(getDefaultParams<T>());
+
+ LLXUIParser::instance().readXUI(node, params);
+
+ if (output_node)
+ {
+ // We always want to output top-left coordinates
+ typename T::Params output_params(params);
+ T::setupParamsForExport(output_params, parent);
+ // Export only the differences between this any default params
+ typename T::Params default_params(getDefaultParams<T>());
+ output_node->setName(node->getName()->mString);
+ LLXUIParser::instance().writeXUI(
+ output_node, output_params, &default_params);
+ }
+
+ // Apply layout transformations, usually munging rect
+ T::setupParams(params, parent);
+
+ if (!params.validateBlock())
+ {
+ llwarns << getInstance()->getCurFileName() << ": Invalid parameter block for " << typeid(T).name() << llendl;
+ }
+ T* widget;
+ {
+ LLFastTimer timer(FTM_WIDGET_CONSTRUCTION);
+ widget = new T(params);
+ }
+ {
+ LLFastTimer timer(FTM_INIT_FROM_PARAMS);
+ widget->initFromParams(params);
+ }
+
+ if (parent)
+ {
+ S32 tab_group = params.tab_group.isProvided() ? params.tab_group() : -1;
+ setCtrlParent(widget, parent, tab_group);
+ }
+
+ typedef typename T::child_registry_t registry_t;
+
+ createChildren(widget, node, registry_t::instance(), output_node);
+
+ if (!widget->postBuild())
+ {
+ delete widget;
+ return NULL;
+ }
+
+ return widget;
+ }
+
+ static void createChildren(LLView* viewp, LLXMLNodePtr node, const widget_registry_t&, LLXMLNodePtr output_node = NULL);
static bool getLayeredXMLNode(const std::string &filename, LLXMLNodePtr& root);
+
+ static bool getLocalizedXMLNode(const std::string &xui_filename, LLXMLNodePtr& root);
- static const std::vector<std::string>& getXUIPaths();
+ static void loadWidgetTemplate(const std::string& widget_tag, LLInitParam::BaseBlock& block);
private:
- bool getLayeredXMLNodeImpl(const std::string &filename, LLXMLNodePtr& root);
+ //static void setCtrlValue(LLView* view, LLXMLNodePtr node);
+ static void setCtrlParent(LLView* view, LLView* parent, S32 tab_group);
+
+ // Avoid directly using LLUI and LLDir in the template code
+ static std::string findSkinnedFilename(const std::string& filename);
+
+ typedef std::deque<const LLCallbackMap::map_t*> factory_stack_t;
+ factory_stack_t mFactoryStack;
+
+ LLPanel* mDummyPanel;
+ std::vector<std::string> mFileNames;
+};
- typedef std::map<LLHandle<LLPanel>, std::string> built_panel_t;
- built_panel_t mBuiltPanels;
+template<typename T>
+const LLInitParam::BaseBlock& getEmptyParamBlock()
+{
+ static typename T::Params params;
+ return params;
+}
- typedef std::map<LLHandle<LLFloater>, std::string> built_floater_t;
- built_floater_t mBuiltFloaters;
+// this is here to make gcc happy with reference to LLUICtrlFactory
+template<typename DERIVED>
+template<typename T>
+LLChildRegistry<DERIVED>::Register<T>::Register(const char* tag, LLWidgetCreatorFunc func)
+: LLChildRegistry<DERIVED>::StaticRegistrar(tag, func.empty() ? (LLWidgetCreatorFunc)&LLUICtrlFactory::defaultBuilder<T> : func)
+{
+ const std::type_info* widget_type_infop = &typeid(T);
+ // associate parameter block type with template .xml file
+ std::string* existing_tag = LLWidgetNameRegistry ::instance().getValue(&typeid(typename T::Params));
+ if (existing_tag != NULL && *existing_tag != tag)
+ {
+ // duplicate entry for T::Params
+ // try creating empty param block in derived classes that inherit T::Params
+ int* crash = 0;
+ *crash = 0;
+ }
+ LLWidgetNameRegistry ::instance().defaultRegistrar().add(&typeid(typename T::Params), tag);
+ // associate widget type with factory function
+ LLDefaultWidgetRegistry::instance().defaultRegistrar().add(widget_type_infop, &LLUICtrlFactory::createDefaultWidget<T>);
+ LLWidgetTypeRegistry::instance().defaultRegistrar().add(tag, widget_type_infop);
+ LLDefaultParamBlockRegistry::instance().defaultRegistrar().add(widget_type_infop, &getEmptyParamBlock<T>);
+ typedef typename T::child_registry_t registry_t;
+ LLChildRegistryRegistry::instance().defaultRegistrar().add(widget_type_infop, registry_t::instance());
+}
- std::deque<const LLCallbackMap::map_t*> mFactoryStack;
- static std::vector<std::string> sXUIPaths;
+typedef boost::function<LLPanel* (void)> LLPanelClassCreatorFunc;
- LLPanel* mDummyPanel;
+// local static instance for registering a particular panel class
+
+class LLRegisterPanelClass
+: public LLSingleton< LLRegisterPanelClass >
+{
+public:
+ // reigister with either the provided builder, or the generic templated builder
+ void addPanelClass(const std::string& tag,LLPanelClassCreatorFunc func)
+ {
+ mPanelClassesNames[tag] = func;
+ }
+
+ LLPanel* createPanelClass(const std::string& tag)
+ {
+ param_name_map_t::iterator iT = mPanelClassesNames.find(tag);
+ if(iT == mPanelClassesNames.end())
+ return 0;
+ return iT->second();
+ }
+ template<typename T>
+ static T* defaultPanelClassBuilder()
+ {
+ T* pT = new T();
+ return pT;
+ }
+
+private:
+ typedef std::map< std::string, LLPanelClassCreatorFunc> param_name_map_t;
+
+ param_name_map_t mPanelClassesNames;
};
+// local static instance for registering a particular panel class
+template<typename T>
+class LLRegisterPanelClassWrapper
+: public LLRegisterPanelClass
+{
+public:
+ // reigister with either the provided builder, or the generic templated builder
+ LLRegisterPanelClassWrapper(const std::string& tag);
+};
+
+
+template<typename T>
+LLRegisterPanelClassWrapper<T>::LLRegisterPanelClassWrapper(const std::string& tag)
+{
+ LLRegisterPanelClass::instance().addPanelClass(tag,&LLRegisterPanelClass::defaultPanelClassBuilder<T>);
+}
+
+
#endif //LLUICTRLFACTORY_H
diff --git a/indra/llui/lluifwd.h b/indra/llui/lluifwd.h
index 32d5c9b44f..f99bb39fdd 100644
--- a/indra/llui/lluifwd.h
+++ b/indra/llui/lluifwd.h
@@ -53,7 +53,6 @@ class LLSlider;
class LLSliderCtrl;
class LLSpinCtrl;
class LLTabContainer;
-class LLTabContainerVertical;
class LLTextBox;
class LLTextEditor;
class LLTextureCtrl;
diff --git a/indra/llui/lluiimage.cpp b/indra/llui/lluiimage.cpp
new file mode 100644
index 0000000000..ab0d65e731
--- /dev/null
+++ b/indra/llui/lluiimage.cpp
@@ -0,0 +1,166 @@
+/**
+ * @file lluiimage.cpp
+ * @brief UI implementation
+ *
+ * $LicenseInfo:firstyear=2007&license=viewergpl$
+ *
+ * Copyright (c) 2007-2009, Linden Research, Inc.
+ *
+ * Second Life Viewer Source Code
+ * The source code in this file ("Source Code") is provided by Linden Lab
+ * to you under the terms of the GNU General Public License, version 2.0
+ * ("GPL"), unless you have obtained a separate licensing agreement
+ * ("Other License"), formally executed by you and Linden Lab. Terms of
+ * the GPL can be found in doc/GPL-license.txt in this distribution, or
+ * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
+ *
+ * There are special exceptions to the terms and conditions of the GPL as
+ * it is applied to this Source Code. View the full text of the exception
+ * in the file doc/FLOSS-exception.txt in this software distribution, or
+ * online at
+ * http://secondlifegrid.net/programs/open_source/licensing/flossexception
+ *
+ * By copying, modifying or distributing this software, you acknowledge
+ * that you have read and understood your obligations described above,
+ * and agree to abide by those obligations.
+ *
+ * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+ * COMPLETENESS OR PERFORMANCE.
+ * $/LicenseInfo$
+ */
+
+// Utilities functions the user interface needs
+
+//#include "llviewerprecompiledheaders.h"
+#include "linden_common.h"
+
+// Project includes
+#include "lluiimage.h"
+#include "llui.h"
+
+LLUIImage::LLUIImage(const std::string& name, LLPointer<LLTexture> image) :
+ mName(name),
+ mImage(image),
+ mScaleRegion(0.f, 1.f, 1.f, 0.f),
+ mClipRegion(0.f, 1.f, 1.f, 0.f),
+ mUniformScaling(TRUE),
+ mNoClip(TRUE)
+{
+}
+
+LLUIImage::~LLUIImage()
+{
+}
+
+void LLUIImage::setClipRegion(const LLRectf& region)
+{
+ mClipRegion = region;
+ mNoClip = mClipRegion.mLeft == 0.f
+ && mClipRegion.mRight == 1.f
+ && mClipRegion.mBottom == 0.f
+ && mClipRegion.mTop == 1.f;
+}
+
+void LLUIImage::setScaleRegion(const LLRectf& region)
+{
+ mScaleRegion = region;
+ mUniformScaling = mScaleRegion.mLeft == 0.f
+ && mScaleRegion.mRight == 1.f
+ && mScaleRegion.mBottom == 0.f
+ && mScaleRegion.mTop == 1.f;
+}
+
+//TODO: move drawing implementation inside class
+void LLUIImage::draw(S32 x, S32 y, const LLColor4& color) const
+{
+ gl_draw_scaled_image(x, y, getWidth(), getHeight(), mImage, color, mClipRegion);
+}
+
+void LLUIImage::draw(S32 x, S32 y, S32 width, S32 height, const LLColor4& color) const
+{
+ if (mUniformScaling)
+ {
+ gl_draw_scaled_image(x, y, width, height, mImage, color, mClipRegion);
+ }
+ else
+ {
+ gl_draw_scaled_image_with_border(
+ x, y,
+ width, height,
+ mImage,
+ color,
+ FALSE,
+ mClipRegion,
+ mScaleRegion);
+ }
+}
+
+void LLUIImage::drawSolid(S32 x, S32 y, S32 width, S32 height, const LLColor4& color) const
+{
+ gl_draw_scaled_image_with_border(
+ x, y,
+ width, height,
+ mImage,
+ color,
+ TRUE,
+ mClipRegion,
+ mScaleRegion);
+}
+
+void LLUIImage::drawBorder(S32 x, S32 y, S32 width, S32 height, const LLColor4& color, S32 border_width) const
+{
+ LLRect border_rect;
+ border_rect.setOriginAndSize(x, y, width, height);
+ border_rect.stretch(border_width, border_width);
+ drawSolid(border_rect, color);
+}
+
+S32 LLUIImage::getWidth() const
+{
+ // return clipped dimensions of actual image area
+ return llround((F32)mImage->getWidth(0) * mClipRegion.getWidth());
+}
+
+S32 LLUIImage::getHeight() const
+{
+ // return clipped dimensions of actual image area
+ return llround((F32)mImage->getHeight(0) * mClipRegion.getHeight());
+}
+
+S32 LLUIImage::getTextureWidth() const
+{
+ return mImage->getWidth(0);
+}
+
+S32 LLUIImage::getTextureHeight() const
+{
+ return mImage->getHeight(0);
+}
+
+namespace LLInitParam
+{
+ LLUIImage* TypedParam<LLUIImage*>::getValueFromBlock() const
+ {
+ LLUIImage* imagep = LLUI::getUIImage(name());
+ if (!imagep)
+ {
+ // default to current value
+ imagep = mData.mValue;
+ }
+ return imagep;
+ }
+
+
+ template<>
+ bool ParamCompare<LLUIImage*>::equals(
+ LLUIImage* const &a,
+ LLUIImage* const &b)
+ {
+ // force all LLUIImages for XML UI export to be "non-default"
+ if (!a && !b)
+ return false;
+ else
+ return (a == b);
+ }
+}
diff --git a/indra/llui/lluiimage.h b/indra/llui/lluiimage.h
new file mode 100644
index 0000000000..4ec24e98dc
--- /dev/null
+++ b/indra/llui/lluiimage.h
@@ -0,0 +1,116 @@
+/**
+ * @file lluiimage.h
+ * @brief wrapper for images used in the UI that handles smart scaling, etc.
+ *
+ * $LicenseInfo:firstyear=2007&license=viewergpl$
+ *
+ * Copyright (c) 2007-2009, Linden Research, Inc.
+ *
+ * Second Life Viewer Source Code
+ * The source code in this file ("Source Code") is provided by Linden Lab
+ * to you under the terms of the GNU General Public License, version 2.0
+ * ("GPL"), unless you have obtained a separate licensing agreement
+ * ("Other License"), formally executed by you and Linden Lab. Terms of
+ * the GPL can be found in doc/GPL-license.txt in this distribution, or
+ * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
+ *
+ * There are special exceptions to the terms and conditions of the GPL as
+ * it is applied to this Source Code. View the full text of the exception
+ * in the file doc/FLOSS-exception.txt in this software distribution, or
+ * online at
+ * http://secondlifegrid.net/programs/open_source/licensing/flossexception
+ *
+ * By copying, modifying or distributing this software, you acknowledge
+ * that you have read and understood your obligations described above,
+ * and agree to abide by those obligations.
+ *
+ * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+ * COMPLETENESS OR PERFORMANCE.
+ * $/LicenseInfo$
+ */
+
+#ifndef LL_LLUIIMAGE_H
+#define LL_LLUIIMAGE_H
+
+#include "v4color.h"
+#include "llpointer.h"
+#include "llrefcount.h"
+#include "llrefcount.h"
+#include "llrect.h"
+#include <boost/function.hpp>
+#include "llinitparam.h"
+#include "lltexture.h"
+
+extern const LLColor4 UI_VERTEX_COLOR;
+
+class LLUIImage : public LLRefCount
+{
+public:
+ LLUIImage(const std::string& name, LLPointer<LLTexture> image);
+ virtual ~LLUIImage();
+
+ void setClipRegion(const LLRectf& region);
+ void setScaleRegion(const LLRectf& region);
+
+ LLPointer<LLTexture> getImage() { return mImage; }
+ const LLPointer<LLTexture>& getImage() const { return mImage; }
+
+ void draw(S32 x, S32 y, S32 width, S32 height, const LLColor4& color = UI_VERTEX_COLOR) const;
+ void draw(S32 x, S32 y, const LLColor4& color = UI_VERTEX_COLOR) const;
+ void draw(const LLRect& rect, const LLColor4& color = UI_VERTEX_COLOR) const { draw(rect.mLeft, rect.mBottom, rect.getWidth(), rect.getHeight(), color); }
+
+ void drawSolid(S32 x, S32 y, S32 width, S32 height, const LLColor4& color) const;
+ void drawSolid(const LLRect& rect, const LLColor4& color) const { drawSolid(rect.mLeft, rect.mBottom, rect.getWidth(), rect.getHeight(), color); }
+ void drawSolid(S32 x, S32 y, const LLColor4& color) const { drawSolid(x, y, getWidth(), getHeight(), color); }
+
+ void drawBorder(S32 x, S32 y, S32 width, S32 height, const LLColor4& color, S32 border_width) const;
+ void drawBorder(const LLRect& rect, const LLColor4& color, S32 border_width) const { drawBorder(rect.mLeft, rect.mBottom, rect.getWidth(), rect.getHeight(), color, border_width); }
+ void drawBorder(S32 x, S32 y, const LLColor4& color, S32 border_width) const { drawBorder(x, y, getWidth(), getHeight(), color, border_width); }
+
+ const std::string& getName() const { return mName; }
+
+ virtual S32 getWidth() const;
+ virtual S32 getHeight() const;
+
+ // returns dimensions of underlying textures, which might not be equal to ui image portion
+ S32 getTextureWidth() const;
+ S32 getTextureHeight() const;
+
+protected:
+ std::string mName;
+ LLRectf mScaleRegion;
+ LLRectf mClipRegion;
+ LLPointer<LLTexture> mImage;
+ BOOL mUniformScaling;
+ BOOL mNoClip;
+};
+
+namespace LLInitParam
+{
+ template<>
+ class TypedParam<LLUIImage*, TypeValues<LLUIImage*>, false>
+ : public BlockValue<LLUIImage*>
+ {
+ typedef boost::add_reference<boost::add_const<LLUIImage*>::type>::type T_const_ref;
+ typedef BlockValue<LLUIImage*> super_t;
+ public:
+ Optional<std::string> name;
+
+ TypedParam(BlockDescriptor& descriptor, const char* name, super_t::value_assignment_t value, ParamDescriptor::validation_func_t func, S32 min_count, S32 max_count)
+ : super_t(descriptor, name, value, func, min_count, max_count)
+ {
+ }
+
+ LLUIImage* getValueFromBlock() const;
+ };
+
+ // Need custom comparison function for our test app, which only loads
+ // LLUIImage* as NULL.
+ template<>
+ bool ParamCompare<LLUIImage*>::equals(
+ LLUIImage* const &a, LLUIImage* const &b);
+}
+
+typedef LLPointer<LLUIImage> LLUIImagePtr;
+#endif
diff --git a/indra/llui/lluistring.cpp b/indra/llui/lluistring.cpp
index 0b76b8e814..20ff71378e 100644
--- a/indra/llui/lluistring.cpp
+++ b/indra/llui/lluistring.cpp
@@ -33,9 +33,12 @@
#include "linden_common.h"
#include "lluistring.h"
#include "llsd.h"
+#include "lltrans.h"
const LLStringUtil::format_map_t LLUIString::sNullArgs;
+LLFastTimer::DeclareTimer FTM_UI_STRING("UI String");
+
LLUIString::LLUIString(const std::string& instring, const LLStringUtil::format_map_t& args)
: mOrig(instring),
@@ -58,6 +61,8 @@ void LLUIString::setArgList(const LLStringUtil::format_map_t& args)
void LLUIString::setArgs(const LLSD& sd)
{
+ LLFastTimer timer(FTM_UI_STRING);
+
if (!sd.isMap()) return;
for(LLSD::map_const_iterator sd_it = sd.beginMap();
sd_it != sd.endMap();
@@ -111,7 +116,20 @@ void LLUIString::clear()
void LLUIString::format()
{
+ LLFastTimer timer(FTM_UI_STRING);
+
+ // optimize for empty strings (don't attempt string replacement)
+ if (mOrig.empty())
+ {
+ mResult.clear();
+ mWResult.clear();
+ return;
+ }
mResult = mOrig;
- LLStringUtil::format(mResult, mArgs);
+
+ // get the defailt args + local args
+ LLStringUtil::format_map_t combined_args = LLTrans::getDefaultArgs();
+ combined_args.insert(mArgs.begin(), mArgs.end());
+ LLStringUtil::format(mResult, combined_args);
mWResult = utf8str_to_wstring(mResult);
}
diff --git a/indra/llui/llview.cpp b/indra/llui/llview.cpp
index 31788da117..4770807ac7 100644
--- a/indra/llui/llview.cpp
+++ b/indra/llui/llview.cpp
@@ -56,19 +56,18 @@
#include "lltexteditor.h"
#include "lltextbox.h"
-using namespace LLOldEvents;
-
-//HACK: this allows you to instantiate LLView from xml with "<view/>" which we don't want
-static LLRegisterWidget<LLView> r("view");
-
BOOL LLView::sDebugRects = FALSE;
BOOL LLView::sDebugKeys = FALSE;
S32 LLView::sDepth = 0;
BOOL LLView::sDebugMouseHandling = FALSE;
std::string LLView::sMouseHandlerMessage;
-BOOL LLView::sEditingUI = FALSE;
+//BOOL LLView::sEditingUI = FALSE;
BOOL LLView::sForceReshape = FALSE;
-LLView* LLView::sEditingUIView = NULL;
+//LLView* LLView::sEditingUIView = NULL;
+std::set<LLView*> LLView::sPreviewHighlightedElements;
+BOOL LLView::sHighlightingDiffs = FALSE;
+LLView* LLView::sPreviewClickedElement = NULL;
+BOOL LLView::sDrawPreviewHighlights = FALSE;
S32 LLView::sLastLeftXML = S32_MIN;
S32 LLView::sLastBottomXML = S32_MIN;
@@ -76,77 +75,79 @@ S32 LLView::sLastBottomXML = S32_MIN;
BOOL LLView::sIsDrawing = FALSE;
#endif
-LLView::LLView() :
+static LLDefaultChildRegistry::Register<LLView> r("view");
+
+LLView::Params::Params()
+: name("name", std::string("unnamed")),
+ enabled("enabled", true),
+ visible("visible", true),
+ mouse_opaque("mouse_opaque", true),
+ follows("follows"),
+ hover_cursor("hover_cursor", "UI_CURSOR_ARROW"),
+ use_bounding_rect("use_bounding_rect", false),
+ tab_group("tab_group", 0),
+ default_tab_group("default_tab_group"),
+ tool_tip("tool_tip"),
+ sound_flags("sound_flags", MOUSE_UP),
+ font("font", LLFontGL::getFontSansSerif()),
+ font_halign("halign"),
+ font_valign("valign"),
+ layout("layout"),
+ rect("rect"),
+ bottom_delta("bottom_delta", S32_MAX),
+ top_pad("top_pad"),
+ top_delta("top_delta", S32_MAX),
+ left_pad("left_pad"),
+ left_delta("left_delta", S32_MAX),
+ center_horiz("center_horiz", false),
+ center_vert("center_vert", false),
+ from_xui("from_xui", false),
+ user_resize("user_resize"),
+ auto_resize("auto_resize"),
+ needs_translate("translate"),
+ xmlns("xmlns"),
+ xmlns_xsi("xmlns:xsi"),
+ xsi_schemaLocation("xsi:schemaLocation"),
+ xsi_type("xsi:type")
+
+{
+ addSynonym(rect, "");
+}
+
+LLView::LLView(const LLView::Params& p)
+: mName(p.name),
mParentView(NULL),
mReshapeFlags(FOLLOWS_NONE),
- mDefaultTabGroup(0),
- mEnabled(TRUE),
- mMouseOpaque(TRUE),
- mSoundFlags(MOUSE_UP), // default to only make sound on mouse up
- mSaveToXML(TRUE),
+ mSaveToXML(p.from_xui),
mIsFocusRoot(FALSE),
- mLastVisible(TRUE),
- mUseBoundingRect(FALSE),
- mVisible(TRUE),
+ mLastVisible(FALSE),
mNextInsertionOrdinal(0),
- mHoverCursor(UI_CURSOR_ARROW)
-{
-}
-
-LLView::LLView(const std::string& name, BOOL mouse_opaque) :
- mParentView(NULL),
- mName(name),
- mReshapeFlags(FOLLOWS_NONE),
- mDefaultTabGroup(0),
- mEnabled(TRUE),
- mMouseOpaque(mouse_opaque),
- mSoundFlags(MOUSE_UP), // default to only make sound on mouse up
- mSaveToXML(TRUE),
- mIsFocusRoot(FALSE),
- mLastVisible(TRUE),
- mUseBoundingRect(FALSE),
- mVisible(TRUE),
- mNextInsertionOrdinal(0),
- mHoverCursor(UI_CURSOR_ARROW)
-{
-}
-
-
-LLView::LLView(
- const std::string& name, const LLRect& rect, BOOL mouse_opaque, U32 reshape) :
- mParentView(NULL),
- mName(name),
- mRect(rect),
- mBoundingRect(rect),
- mReshapeFlags(reshape),
- mDefaultTabGroup(0),
- mEnabled(TRUE),
- mMouseOpaque(mouse_opaque),
- mSoundFlags(MOUSE_UP), // default to only make sound on mouse up
- mSaveToXML(TRUE),
- mIsFocusRoot(FALSE),
- mLastVisible(TRUE),
- mUseBoundingRect(FALSE),
- mVisible(TRUE),
- mNextInsertionOrdinal(0),
- mHoverCursor(UI_CURSOR_ARROW)
+ mHoverCursor(getCursorFromString(p.hover_cursor)),
+ mEnabled(p.enabled),
+ mVisible(p.visible),
+ mMouseOpaque(p.mouse_opaque),
+ mSoundFlags(p.sound_flags),
+ mUseBoundingRect(p.use_bounding_rect),
+ mDefaultTabGroup(p.default_tab_group),
+ mLastTabGroup(0),
+ mToolTipMsg((LLStringExplicit)p.tool_tip()),
+ mDefaultWidgets(NULL)
{
+ // create rect first, as this will supply initial follows flags
+ setShape(p.rect);
+ parseFollowsFlags(p);
}
-
LLView::~LLView()
{
//llinfos << "Deleting view " << mName << ":" << (void*) this << llendl;
// llassert(LLView::sIsDrawing == FALSE);
- if( gFocusMgr.getKeyboardFocus() == this )
- {
- llwarns << "View holding keyboard focus deleted: " << getName() << ". Keyboard focus removed." << llendl;
- gFocusMgr.removeKeyboardFocusWithoutCallback( this );
- }
-
+
+// llassert_always(sDepth == 0); // avoid deleting views while drawing! It can subtly break list iterators
+
if( hasMouseCapture() )
{
- llwarns << "View holding mouse capture deleted: " << getName() << ". Mouse capture removed." << llendl;
+ //llwarns << "View holding mouse capture deleted: " << getName() << ". Mouse capture removed." << llendl;
gFocusMgr.removeMouseCaptureWithoutCallback( this );
}
@@ -157,16 +158,13 @@ LLView::~LLView()
mParentView->removeChild(this);
}
- dispatch_list_t::iterator itor;
- for (itor = mDispatchList.begin(); itor != mDispatchList.end(); ++itor)
+ if (mDefaultWidgets)
{
- (*itor).second->clearDispatchers();
+ std::for_each(mDefaultWidgets->begin(), mDefaultWidgets->end(),
+ DeletePairedPointer());
+ delete mDefaultWidgets;
+ mDefaultWidgets = NULL;
}
-
- std::for_each(mFloaterControls.begin(), mFloaterControls.end(),
- DeletePairedPointer());
- std::for_each(mDummyWidgets.begin(), mDummyWidgets.end(),
- DeletePairedPointer());
}
// virtual
@@ -187,7 +185,6 @@ BOOL LLView::isPanel() const
return FALSE;
}
-// virtual
void LLView::setToolTip(const LLStringExplicit& msg)
{
mToolTipMsg = msg;
@@ -234,19 +231,31 @@ const std::string& LLView::getName() const
void LLView::sendChildToFront(LLView* child)
{
+// llassert_always(sDepth == 0); // Avoid re-ordering while drawing; it can cause subtle iterator bugs
if (child && child->getParent() == this)
{
- mChildList.remove( child );
- mChildList.push_front(child);
+ // minor optimization, but more importantly,
+ // won't temporarily create an empty list
+ if (child != mChildList.front())
+ {
+ mChildList.remove( child );
+ mChildList.push_front(child);
+ }
}
}
void LLView::sendChildToBack(LLView* child)
{
+// llassert_always(sDepth == 0); // Avoid re-ordering while drawing; it can cause subtle iterator bugs
if (child && child->getParent() == this)
{
- mChildList.remove( child );
- mChildList.push_back(child);
+ // minor optimization, but more importantly,
+ // won't temporarily create an empty list
+ if (child != mChildList.back())
+ {
+ mChildList.remove( child );
+ mChildList.push_back(child);
+ }
}
}
@@ -266,12 +275,18 @@ void LLView::moveChildToBackOfTabGroup(LLUICtrl* child)
}
}
-void LLView::addChild(LLView* child, S32 tab_group)
+// virtual
+bool LLView::addChild(LLView* child, S32 tab_group)
{
+ if (!child)
+ {
+ return false;
+ }
if (mParentView == child)
{
llerrs << "Adding view " << child->getName() << " as child of itself" << llendl;
}
+
// remove from current parent
if (child->mParentView)
{
@@ -284,55 +299,46 @@ void LLView::addChild(LLView* child, S32 tab_group)
// add to ctrl list if is LLUICtrl
if (child->isCtrl())
{
- // controls are stored in reverse order from render order
- addCtrlAtEnd((LLUICtrl*) child, tab_group);
+ LLUICtrl* ctrl = static_cast<LLUICtrl*>(child);
+ mCtrlOrder.insert(tab_order_pair_t(ctrl,
+ tab_order_t(tab_group, mNextInsertionOrdinal)));
+
+ mNextInsertionOrdinal++;
}
child->mParentView = this;
updateBoundingRect();
+ mLastTabGroup = tab_group;
+ return true;
}
-void LLView::addChildAtEnd(LLView* child, S32 tab_group)
+bool LLView::addChildInBack(LLView* child, S32 tab_group)
{
- if (mParentView == child)
+ if(addChild(child, tab_group))
{
- llerrs << "Adding view " << child->getName() << " as child of itself" << llendl;
- }
- // remove from current parent
- if (child->mParentView)
- {
- child->mParentView->removeChild(child);
+ sendChildToBack(child);
+ return true;
}
- // add to back of child list
- mChildList.push_back(child);
-
- // add to ctrl list if is LLUICtrl
- if (child->isCtrl())
- {
- // controls are stored in reverse order from render order
- addCtrl((LLUICtrl*) child, tab_group);
- }
-
- child->mParentView = this;
- updateBoundingRect();
+ return false;
}
// remove the specified child from the view, and set it's parent to NULL.
-void LLView::removeChild(LLView* child, BOOL deleteIt)
+void LLView::removeChild(LLView* child)
{
+ //llassert_always(sDepth == 0); // Avoid re-ordering while drawing; it can cause subtle iterator bugs
if (child->mParentView == this)
{
mChildList.remove( child );
child->mParentView = NULL;
if (child->isCtrl())
{
- removeCtrl((LLUICtrl*)child);
- }
- if (deleteIt)
- {
- delete child;
+ child_tab_order_t::iterator found = mCtrlOrder.find(static_cast<LLUICtrl*>(child));
+ if(found != mCtrlOrder.end())
+ {
+ mCtrlOrder.erase(found);
+ }
}
}
else
@@ -342,28 +348,6 @@ void LLView::removeChild(LLView* child, BOOL deleteIt)
updateBoundingRect();
}
-void LLView::addCtrlAtEnd(LLUICtrl* ctrl, S32 tab_group)
-{
- mCtrlOrder.insert(tab_order_pair_t(ctrl,
- tab_order_t(tab_group, mNextInsertionOrdinal++)));
-}
-
-void LLView::addCtrl( LLUICtrl* ctrl, S32 tab_group)
-{
- // add to front of list by using negative ordinal, which monotonically increases
- mCtrlOrder.insert(tab_order_pair_t(ctrl,
- tab_order_t(tab_group, -1 * mNextInsertionOrdinal++)));
-}
-
-void LLView::removeCtrl(LLUICtrl* ctrl)
-{
- child_tab_order_t::iterator found = mCtrlOrder.find(ctrl);
- if(found != mCtrlOrder.end())
- {
- mCtrlOrder.erase(found);
- }
-}
-
LLView::ctrl_list_t LLView::getCtrlList() const
{
ctrl_list_t controls;
@@ -413,32 +397,28 @@ bool LLCompareByTabOrder::operator() (const LLView* const a, const LLView* const
return (a_score == b_score) ? a < b : a_score < b_score;
}
-BOOL LLView::isInVisibleChain() const
+bool LLView::trueToRoot(const boost::function<bool (const LLView*)>& predicate) const
{
const LLView* cur_view = this;
while(cur_view)
{
- if (!cur_view->getVisible())
+ if(!predicate(cur_view))
{
- return FALSE;
+ return false;
}
cur_view = cur_view->getParent();
}
- return TRUE;
+ return true;
+}
+
+BOOL LLView::isInVisibleChain() const
+{
+ return trueToRoot(&LLView::getVisible);
}
BOOL LLView::isInEnabledChain() const
{
- const LLView* cur_view = this;
- while(cur_view)
- {
- if (!cur_view->getEnabled())
- {
- return FALSE;
- }
- cur_view = cur_view->getParent();
- }
- return TRUE;
+ return trueToRoot(&LLView::getEnabled);
}
// virtual
@@ -619,14 +599,14 @@ void LLView::setVisible(BOOL visible)
if (!getParent() || getParent()->isInVisibleChain())
{
// tell all children of this view that the visibility may have changed
- onVisibilityChange( visible );
+ handleVisibilityChange( visible );
}
updateBoundingRect();
}
}
// virtual
-void LLView::onVisibilityChange ( BOOL new_visibility )
+void LLView::handleVisibilityChange ( BOOL new_visibility )
{
for ( child_list_iter_t child_it = mChildList.begin(); child_it != mChildList.end(); ++child_it)
{
@@ -634,7 +614,7 @@ void LLView::onVisibilityChange ( BOOL new_visibility )
// only views that are themselves visible will have their overall visibility affected by their ancestors
if (viewp->getVisible())
{
- viewp->onVisibilityChange ( new_visibility );
+ viewp->handleVisibilityChange ( new_visibility );
}
}
}
@@ -653,7 +633,7 @@ BOOL LLView::canSnapTo(const LLView* other_view)
}
// virtual
-void LLView::snappedTo(const LLView* snap_view)
+void LLView::setSnappedTo(const LLView* snap_view)
{
}
@@ -671,6 +651,17 @@ BOOL LLView::handleHover(S32 x, S32 y, MASK mask)
return handled;
}
+void LLView::onMouseEnter(S32 x, S32 y, MASK mask)
+{
+ //llinfos << "Mouse entered " << getName() << llendl;
+}
+
+void LLView::onMouseLeave(S32 x, S32 y, MASK mask)
+{
+ //llinfos << "Mouse left " << getName() << llendl;
+}
+
+
std::string LLView::getShowNamesToolTip()
{
LLView* view = getParent();
@@ -731,32 +722,27 @@ BOOL LLView::handleToolTip(S32 x, S32 y, std::string& msg, LLRect* sticky_rect_s
// get our own tooltip
tool_tip = mToolTipMsg.getString();
- if (
- LLUI::sShowXUINames
+
+ if (LLUI::sShowXUINames
&& (tool_tip.find(".xml", 0) == std::string::npos)
&& (mName.find("Drag", 0) == std::string::npos))
{
tool_tip = getShowNamesToolTip();
}
- BOOL show_names_text_box = LLUI::sShowXUINames && dynamic_cast<LLTextBox*>(this) != NULL;
+ if(!tool_tip.empty())
+ {
+ msg = tool_tip;
+ // Convert rect local to screen coordinates
+ *sticky_rect_screen = calcScreenRect();
+ }
// don't allow any siblings to handle this event
// even if we don't have a tooltip
- if (blockMouseEvent(x, y) || show_names_text_box)
+ if (getMouseOpaque() ||
+ (!tool_tip.empty() &&
+ (!LLUI::sShowXUINames || dynamic_cast<LLTextBox*>(this))))
{
- if(!tool_tip.empty())
- {
- msg = tool_tip;
-
- // Convert rect local to screen coordinates
- localPointToScreen(
- 0, 0,
- &(sticky_rect_screen->mLeft), &(sticky_rect_screen->mBottom) );
- localPointToScreen(
- mRect.getWidth(), mRect.getHeight(),
- &(sticky_rect_screen->mRight), &(sticky_rect_screen->mTop) );
- }
handled = TRUE;
}
@@ -922,22 +908,22 @@ BOOL LLView::handleMouseDown(S32 x, S32 y, MASK mask)
handled_view = this;
}
- // HACK If we're editing UI, select the leaf view that ate the click.
- if (sEditingUI && handled_view)
- {
- // need to find leaf views, big hack
- LLButton* buttonp = dynamic_cast<LLButton*>(handled_view);
- LLLineEditor* line_editorp = dynamic_cast<LLLineEditor*>(handled_view);
- LLTextEditor* text_editorp = dynamic_cast<LLTextEditor*>(handled_view);
- LLTextBox* text_boxp = dynamic_cast<LLTextBox*>(handled_view);
- if (buttonp
- || line_editorp
- || text_editorp
- || text_boxp)
- {
- sEditingUIView = handled_view;
- }
- }
+ //// HACK If we're editing UI, select the leaf view that ate the click.
+ //if (sEditingUI && handled_view)
+ //{
+ // // need to find leaf views, big hack
+ // LLButton* buttonp = dynamic_cast<LLButton*>(handled_view);
+ // LLLineEditor* line_editorp = dynamic_cast<LLLineEditor*>(handled_view);
+ // LLTextEditor* text_editorp = dynamic_cast<LLTextEditor*>(handled_view);
+ // LLTextBox* text_boxp = dynamic_cast<LLTextBox*>(handled_view);
+ // if (buttonp
+ // || line_editorp
+ // || text_editorp
+ // || text_boxp)
+ // {
+ // sEditingUIView = handled_view;
+ // }
+ //}
return handled;
}
@@ -955,16 +941,11 @@ BOOL LLView::handleDoubleClick(S32 x, S32 y, MASK mask)
BOOL LLView::handleScrollWheel(S32 x, S32 y, S32 clicks)
{
- BOOL handled = FALSE;
if( getVisible() && getEnabled() )
{
- handled = childrenHandleScrollWheel( x, y, clicks ) != NULL;
- if( !handled && blockMouseEvent(x, y) )
- {
- handled = TRUE;
- }
+ return childrenHandleScrollWheel( x, y, clicks ) != NULL;
}
- return handled;
+ return FALSE;
}
BOOL LLView::handleRightMouseDown(S32 x, S32 y, MASK mask)
@@ -1163,6 +1144,7 @@ LLView* LLView::childrenHandleRightMouseDown(S32 x, S32 y, MASK mask)
{
sMouseHandlerMessage = std::string("->") + viewp->mName + sMouseHandlerMessage;
}
+
handled_view = viewp;
break;
}
@@ -1313,6 +1295,11 @@ LLView* LLView::childrenHandleMiddleMouseUp(S32 x, S32 y, MASK mask)
void LLView::draw()
{
+ drawChildren();
+}
+
+void LLView::drawChildren()
+{
if (sDebugRects)
{
drawDebugRect();
@@ -1325,55 +1312,46 @@ void LLView::draw()
}
}
- LLRect rootRect = getRootView()->getRect();
- LLRect screenRect;
-
- // draw focused control on top of everything else
- LLView* focus_view = gFocusMgr.getKeyboardFocus();
- if (focus_view && focus_view->getParent() != this)
+ if (!mChildList.empty())
{
- focus_view = NULL;
- }
+ LLRect rootRect = getRootView()->getRect();
+ LLRect screenRect;
- ++sDepth;
- for (child_list_reverse_iter_t child_iter = mChildList.rbegin(); child_iter != mChildList.rend(); ++child_iter)
- {
- LLView *viewp = *child_iter;
+ ++sDepth;
- if (viewp->getVisible() && viewp != focus_view && viewp->getRect().isValid())
+ for (child_list_reverse_iter_t child_iter = mChildList.rbegin(); child_iter != mChildList.rend();) // ++child_iter)
{
- // Only draw views that are within the root view
- localRectToScreen(viewp->getRect(),&screenRect);
- if ( rootRect.rectInRect(&screenRect) )
+ child_list_reverse_iter_t child = child_iter++;
+ LLView *viewp = *child;
+
+ if (viewp->getVisible() && viewp->getRect().isValid())
{
- glMatrixMode(GL_MODELVIEW);
- LLUI::pushMatrix();
+ // Only draw views that are within the root view
+ localRectToScreen(viewp->getRect(),&screenRect);
+ if ( rootRect.overlaps(screenRect) )
{
- LLUI::translate((F32)viewp->getRect().mLeft, (F32)viewp->getRect().mBottom, 0.f);
- viewp->draw();
+ glMatrixMode(GL_MODELVIEW);
+ LLUI::pushMatrix();
+ {
+ LLUI::translate((F32)viewp->getRect().mLeft, (F32)viewp->getRect().mBottom, 0.f);
+ viewp->draw();
+ }
+ LLUI::popMatrix();
}
- LLUI::popMatrix();
}
- }
-
- }
- --sDepth;
- if (focus_view && focus_view->getVisible())
- {
- drawChild(focus_view);
+ }
+ --sDepth;
}
- // HACK
- if (sEditingUI && this == sEditingUIView)
- {
- drawDebugRect();
- }
+ gGL.getTexUnit(0)->disable();
}
//Draw a box for debugging.
void LLView::drawDebugRect()
{
+ std::set<LLView*>::iterator preview_iter = std::find(sPreviewHighlightedElements.begin(), sPreviewHighlightedElements.end(), this); // figure out if it's a previewed element
+
LLUI::pushMatrix();
{
// drawing solids requires texturing be disabled
@@ -1388,9 +1366,21 @@ void LLView::drawDebugRect()
// draw red rectangle for the border
LLColor4 border_color(0.f, 0.f, 0.f, 1.f);
- if (sEditingUI)
+ //if (sEditingUI)
+ //{
+ // border_color.mV[0] = 1.f;
+ //}
+ if(preview_iter != sPreviewHighlightedElements.end())
{
- border_color.mV[0] = 1.f;
+ if(LLView::sPreviewClickedElement && this == sPreviewClickedElement)
+ {
+ border_color = LLColor4::red;
+ }
+ else
+ {
+ static LLUIColor scroll_highlighted_color = LLUIColorTable::instance().getColor("ScrollHighlightedColor");
+ border_color = scroll_highlighted_color;
+ }
}
else
{
@@ -1413,8 +1403,8 @@ void LLView::drawDebugRect()
gGL.vertex2i(0, debug_rect.getHeight() - 1);
gGL.end();
- // Draw the name if it's not a leaf node
- if (mChildList.size() && !sEditingUI)
+ // Draw the name if it's not a leaf node or not in editing or preview mode
+ if (mChildList.size() && preview_iter == sPreviewHighlightedElements.end())
{
//char temp[256];
S32 x, y;
@@ -1424,7 +1414,7 @@ void LLView::drawDebugRect()
std::string debug_text = llformat("%s (%d x %d)", getName().c_str(),
debug_rect.getWidth(), debug_rect.getHeight());
LLFontGL::getFontSansSerifSmall()->renderUTF8(debug_text, 0, (F32)x, (F32)y, border_color,
- LLFontGL::HCENTER, LLFontGL::BASELINE, LLFontGL::NORMAL,
+ LLFontGL::HCENTER, LLFontGL::BASELINE, LLFontGL::NORMAL, LLFontGL::NO_SHADOW,
S32_MAX, S32_MAX, NULL, FALSE);
}
}
@@ -1549,7 +1539,7 @@ void LLView::updateBoundingRect()
LLRect child_bounding_rect = childp->getBoundingRect();
- if (local_bounding_rect.isNull())
+ if (local_bounding_rect.isEmpty())
{
// start out with bounding rect equal to first visible child's bounding rect
local_bounding_rect = child_bounding_rect;
@@ -1557,7 +1547,7 @@ void LLView::updateBoundingRect()
else
{
// accumulate non-null children rectangles
- if (!child_bounding_rect.isNull())
+ if (!child_bounding_rect.isEmpty())
{
local_bounding_rect.unionWith(child_bounding_rect);
}
@@ -1580,15 +1570,28 @@ void LLView::updateBoundingRect()
}
}
-LLRect LLView::getScreenRect() const
+LLRect LLView::calcScreenRect() const
{
- // *FIX: check for one-off error
LLRect screen_rect;
localPointToScreen(0, 0, &screen_rect.mLeft, &screen_rect.mBottom);
localPointToScreen(getRect().getWidth(), getRect().getHeight(), &screen_rect.mRight, &screen_rect.mTop);
return screen_rect;
}
+LLRect LLView::calcScreenBoundingRect() const
+{
+ LLRect screen_rect;
+ // get bounding rect, if used
+ LLRect bounding_rect = mUseBoundingRect ? mBoundingRect : mRect;
+
+ // convert to local coordinates, as defined by mRect
+ bounding_rect.translate(-mRect.mLeft, -mRect.mBottom);
+
+ localPointToScreen(bounding_rect.mLeft, bounding_rect.mBottom, &screen_rect.mLeft, &screen_rect.mBottom);
+ localPointToScreen(bounding_rect.mRight, bounding_rect.mTop, &screen_rect.mRight, &screen_rect.mTop);
+ return screen_rect;
+}
+
LLRect LLView::getLocalBoundingRect() const
{
LLRect local_bounding_rect = getBoundingRect();
@@ -1635,7 +1638,7 @@ BOOL LLView::hasAncestor(const LLView* parentp) const
BOOL LLView::childHasKeyboardFocus( const std::string& childname ) const
{
- LLView *child = getChildView(childname, TRUE, FALSE);
+ LLView *child = findChildView(childname, TRUE);
if (child)
{
return gFocusMgr.childHasKeyboardFocus(child);
@@ -1650,13 +1653,27 @@ BOOL LLView::childHasKeyboardFocus( const std::string& childname ) const
BOOL LLView::hasChild(const std::string& childname, BOOL recurse) const
{
- return getChildView(childname, recurse, FALSE) != NULL;
+ return findChildView(childname, recurse) != NULL;
}
//-----------------------------------------------------------------------------
// getChildView()
//-----------------------------------------------------------------------------
-LLView* LLView::getChildView(const std::string& name, BOOL recurse, BOOL create_if_missing) const
+LLView* LLView::getChildView(const std::string& name, BOOL recurse) const
+{
+ LLView* child = findChildView(name, recurse);
+ if (!child)
+ {
+ child = getDefaultWidget<LLView>(name);
+ if (!child)
+ {
+ child = LLUICtrlFactory::createDefaultWidget<LLView>(name);
+ }
+ }
+ return child;
+}
+
+LLView* LLView::findChildView(const std::string& name, BOOL recurse) const
{
//richard: should we allow empty names?
//if(name.empty())
@@ -1677,18 +1694,13 @@ LLView* LLView::getChildView(const std::string& name, BOOL recurse, BOOL create_
for ( child_it = mChildList.begin(); child_it != mChildList.end(); ++child_it)
{
LLView* childp = *child_it;
- LLView* viewp = childp->getChildView(name, recurse, FALSE);
+ LLView* viewp = childp->findChildView(name, recurse);
if ( viewp )
{
return viewp;
}
}
}
-
- if (create_if_missing)
- {
- return createDummyWidget<LLView>(name);
- }
return NULL;
}
@@ -1776,12 +1788,32 @@ LLView* LLView::getRootView()
return view;
}
-BOOL LLView::deleteViewByHandle(LLHandle<LLView> handle)
+LLView* LLView::findPrevSibling(LLView* child)
+{
+ child_list_t::iterator prev_it = std::find(mChildList.begin(), mChildList.end(), child);
+ if (prev_it != mChildList.end() && prev_it != mChildList.begin())
+ {
+ return *(--prev_it);
+ }
+ return NULL;
+}
+
+LLView* LLView::findNextSibling(LLView* child)
+{
+ child_list_t::iterator next_it = std::find(mChildList.begin(), mChildList.end(), child);
+ if (next_it != mChildList.end())
+ {
+ next_it++;
+ }
+
+ return (next_it != mChildList.end()) ? *next_it : NULL;
+}
+
+void LLView::deleteViewByHandle(LLHandle<LLView> handle)
{
LLView* viewp = handle.get();
delete viewp;
- return viewp != NULL;
}
@@ -1942,132 +1974,6 @@ BOOL LLView::localRectToOtherView( const LLRect& local, LLRect* other, LLView* o
return FALSE;
}
-// virtual
-LLXMLNodePtr LLView::getXML(bool save_children) const
-{
- //FIXME: need to provide actual derived type tag, probably outside this method
- LLXMLNodePtr node = new LLXMLNode("view", FALSE);
-
- node->createChild("name", TRUE)->setStringValue(getName());
- node->createChild("width", TRUE)->setIntValue(getRect().getWidth());
- node->createChild("height", TRUE)->setIntValue(getRect().getHeight());
-
- LLView* parent = getParent();
- S32 left = getRect().mLeft;
- S32 bottom = getRect().mBottom;
- if (parent) bottom -= parent->getRect().getHeight();
-
- node->createChild("left", TRUE)->setIntValue(left);
- node->createChild("bottom", TRUE)->setIntValue(bottom);
-
- U32 follows_flags = getFollows();
- if (follows_flags)
- {
- std::stringstream buffer;
- bool pipe = false;
- if (followsLeft())
- {
- buffer << "left";
- pipe = true;
- }
- if (followsTop())
- {
- if (pipe) buffer << "|";
- buffer << "top";
- pipe = true;
- }
- if (followsRight())
- {
- if (pipe) buffer << "|";
- buffer << "right";
- pipe = true;
- }
- if (followsBottom())
- {
- if (pipe) buffer << "|";
- buffer << "bottom";
- }
- node->createChild("follows", TRUE)->setStringValue(buffer.str());
- }
- // Export all widgets as enabled and visible - code must disable.
- node->createChild("mouse_opaque", TRUE)->setBoolValue(mMouseOpaque );
- if (!mToolTipMsg.getString().empty())
- {
- node->createChild("tool_tip", TRUE)->setStringValue(mToolTipMsg.getString());
- }
- if (mSoundFlags != MOUSE_UP)
- {
- node->createChild("sound_flags", TRUE)->setIntValue((S32)mSoundFlags);
- }
-
- node->createChild("enabled", TRUE)->setBoolValue(getEnabled());
-
- if (!mControlName.empty())
- {
- node->createChild("control_name", TRUE)->setStringValue(mControlName);
- }
- return node;
-}
-
-//static
-LLView* LLView::fromXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFactory *factory)
-{
- LLView* viewp = new LLView();
- viewp->initFromXML(node, parent);
- return viewp;
-}
-
-// static
-void LLView::addColorXML(LLXMLNodePtr node, const LLColor4& color,
- const char* xml_name, const char* control_name)
-{
- if (color != LLUI::sColorsGroup->getColor(ll_safe_string(control_name)))
- {
- node->createChild(xml_name, TRUE)->setFloatValue(4, color.mV);
- }
-}
-
-//static
-std::string LLView::escapeXML(const std::string& xml, std::string& indent)
-{
- std::string ret = indent + "\"" + LLXMLNode::escapeXML(xml);
-
- //replace every newline with a close quote, new line, indent, open quote
- size_t index = ret.size()-1;
- size_t fnd;
-
- while ((fnd = ret.rfind("\n", index)) != std::string::npos)
- {
- ret.replace(fnd, 1, "\"\n" + indent + "\"");
- index = fnd-1;
- }
-
- //append close quote
- ret.append("\"");
-
- return ret;
-}
-
-// static
-LLWString LLView::escapeXML(const LLWString& xml)
-{
- LLWString out;
- for (LLWString::size_type i = 0; i < xml.size(); ++i)
- {
- llwchar c = xml[i];
- switch(c)
- {
- case '"': out.append(utf8string_to_wstring("&quot;")); break;
- case '\'': out.append(utf8string_to_wstring("&apos;")); break;
- case '&': out.append(utf8string_to_wstring("&amp;")); break;
- case '<': out.append(utf8string_to_wstring("&lt;")); break;
- case '>': out.append(utf8string_to_wstring("&gt;")); break;
- default: out.push_back(c); break;
- }
- }
- return out;
-}
-
// static
const LLCtrlQuery & LLView::getTabOrderQuery()
{
@@ -2104,7 +2010,12 @@ const LLCtrlQuery & LLView::getFocusRootsQuery()
}
-void LLView::userSetShape(const LLRect& new_rect)
+void LLView::setShape(const LLRect& new_rect, bool by_user)
+{
+ handleReshape(new_rect, by_user);
+}
+
+void LLView::handleReshape(const LLRect& new_rect, bool by_user)
{
reshape(new_rect.getWidth(), new_rect.getHeight());
translate(new_rect.mLeft - getRect().mLeft, new_rect.mBottom - getRect().mBottom);
@@ -2352,560 +2263,475 @@ LLView* LLView::findSnapEdge(S32& new_edge_val, const LLCoordGL& mouse_dir, ESna
// Listener dispatch functions
//-----------------------------------------------------------------------------
-void LLView::registerEventListener(std::string name, LLSimpleListener* function)
-{
- mDispatchList.insert(std::pair<std::string, LLSimpleListener*>(name, function));
-}
-void LLView::deregisterEventListener(std::string name)
-{
- dispatch_list_t::iterator itor = mDispatchList.find(name);
- if (itor != mDispatchList.end())
- {
- mDispatchList.erase(itor);
- }
-}
-
-std::string LLView::findEventListener(LLSimpleListener *listener) const
+LLControlVariable *LLView::findControl(const std::string& name)
{
- dispatch_list_t::const_iterator itor;
- for (itor = mDispatchList.begin(); itor != mDispatchList.end(); ++itor)
+ // parse the name to locate which group it belongs to
+ std::size_t key_pos= name.find(".");
+ if(key_pos!= std::string::npos )
{
- if (itor->second == listener)
+ std::string control_group_key = name.substr(0, key_pos);
+ LLControlVariable* control;
+ // check if it's in the control group that name indicated
+ if(LLUI::sSettingGroups[control_group_key])
{
- return itor->first;
+ control = LLUI::sSettingGroups[control_group_key]->getControl(name);
+ if (control)
+ {
+ return control;
+ }
}
}
- if (mParentView)
- {
- return mParentView->findEventListener(listener);
- }
- return LLStringUtil::null;
+
+ LLControlGroup& control_group = LLUI::getControlControlGroup(name);
+ return control_group.getControl(name);
}
-LLSimpleListener* LLView::getListenerByName(const std::string& callback_name)
+const S32 FLOATER_H_MARGIN = 15;
+const S32 MIN_WIDGET_HEIGHT = 10;
+const S32 VPAD = 4;
+
+void LLView::initFromParams(const LLView::Params& params)
{
- LLSimpleListener* callback = NULL;
- dispatch_list_t::iterator itor = mDispatchList.find(callback_name);
- if (itor != mDispatchList.end())
- {
- callback = itor->second;
- }
- else if (mParentView)
+ LLRect required_rect = getRequiredRect();
+
+ S32 width = llmax(getRect().getWidth(), required_rect.getWidth());
+ S32 height = llmax(getRect().getHeight(), required_rect.getHeight());
+
+ reshape(width, height);
+
+ // call virtual methods with most recent data
+ // use getters because these values might not come through parameter block
+ setEnabled(getEnabled());
+ setVisible(getVisible());
+
+ if (!params.name().empty())
{
- callback = mParentView->getListenerByName(callback_name);
+ setName(params.name());
}
- return callback;
+
+ mLayout = params.layout();
}
-LLControlVariable *LLView::findControl(const std::string& name)
+void LLView::parseFollowsFlags(const LLView::Params& params)
{
- control_map_t::iterator itor = mFloaterControls.find(name);
- if (itor != mFloaterControls.end())
+ // preserve follows flags set by code if user did not override
+ if (!params.follows.isProvided())
{
- return itor->second;
+ return;
}
- if (mParentView)
+
+ // interpret either string or bitfield version of follows
+ if (params.follows.string.isChosen())
{
- return mParentView->findControl(name);
- }
- return LLUI::sConfigGroup->getControl(name);
-}
+ setFollows(FOLLOWS_NONE);
-const S32 FLOATER_H_MARGIN = 15;
-const S32 MIN_WIDGET_HEIGHT = 10;
-const S32 VPAD = 4;
+ std::string follows = params.follows.string;
-// static
-U32 LLView::createRect(LLXMLNodePtr node, LLRect &rect, LLView* parent_view, const LLRect &required_rect)
-{
- U32 follows = 0;
- S32 x = rect.mLeft;
- S32 y = rect.mBottom;
- S32 w = rect.getWidth();
- S32 h = rect.getHeight();
+ typedef boost::tokenizer<boost::char_separator<char> > tokenizer;
+ boost::char_separator<char> sep("|");
+ tokenizer tokens(follows, sep);
+ tokenizer::iterator token_iter = tokens.begin();
- U32 last_x = 0;
- U32 last_y = 0;
- if (parent_view)
- {
- last_y = parent_view->getRect().getHeight();
- child_list_t::const_iterator itor = parent_view->getChildList()->begin();
- if (itor != parent_view->getChildList()->end())
+ while(token_iter != tokens.end())
{
- LLView *last_view = (*itor);
- if (last_view->getSaveToXML())
+ const std::string& token_str = *token_iter;
+ if (token_str == "left")
+ {
+ setFollowsLeft();
+ }
+ else if (token_str == "right")
+ {
+ setFollowsRight();
+ }
+ else if (token_str == "top")
+ {
+ setFollowsTop();
+ }
+ else if (token_str == "bottom")
{
- last_x = last_view->getRect().mLeft;
- last_y = last_view->getRect().mBottom;
+ setFollowsBottom();
}
+ else if (token_str == "all")
+ {
+ setFollowsAll();
+ }
+ ++token_iter;
}
}
-
- std::string rect_control;
- node->getAttributeString("rect_control", rect_control);
- if (! rect_control.empty())
+ else if (params.follows.flags.isChosen())
{
- LLRect rect = LLUI::sConfigGroup->getRect(rect_control);
- x = rect.mLeft;
- y = rect.mBottom;
- w = rect.getWidth();
- h = rect.getHeight();
- }
-
- if (node->hasAttribute("left"))
- {
- node->getAttributeS32("left", x);
- }
- if (node->hasAttribute("bottom"))
- {
- node->getAttributeS32("bottom", y);
+ setFollows(params.follows.flags);
}
+}
- // Make your width the width of the containing
- // view if you don't specify a width.
- if (parent_view)
- {
- if(w == 0)
- {
- w = llmax(required_rect.getWidth(), parent_view->getRect().getWidth() - (FLOATER_H_MARGIN) - x);
- }
- if(h == 0)
- {
- h = llmax(MIN_WIDGET_HEIGHT, required_rect.getHeight());
+// static
+//LLFontGL::HAlign LLView::selectFontHAlign(LLXMLNodePtr node)
+//{
+// LLFontGL::HAlign gl_hfont_align = LLFontGL::LEFT;
+//
+// if (node->hasAttribute("halign"))
+// {
+// std::string horizontal_align_name;
+// node->getAttributeString("halign", horizontal_align_name);
+// gl_hfont_align = LLFontGL::hAlignFromName(horizontal_align_name);
+// }
+// return gl_hfont_align;
+//}
+
+// Return the rectangle of the last-constructed child,
+// if present and a first-class widget (eg, not a close box or drag handle)
+// Returns true if found
+static bool get_last_child_rect(LLView* parent, LLRect *rect)
+{
+ if (!parent) return false;
+
+ LLView::child_list_t::const_iterator itor =
+ parent->getChildList()->begin();
+ for (;itor != parent->getChildList()->end(); ++itor)
+ {
+ LLView *last_view = (*itor);
+ if (last_view->getSaveToXML())
+ {
+ *rect = last_view->getRect();
+ return true;
}
}
+ return false;
+}
- if (node->hasAttribute("width"))
- {
- node->getAttributeS32("width", w);
- }
- if (node->hasAttribute("height"))
+//static
+void LLView::setupParams(LLView::Params& p, LLView* parent)
+{
+ const S32 VPAD = 4;
+ const S32 MIN_WIDGET_HEIGHT = 10;
+
+ p.from_xui(true);
+
+ // *NOTE: This will confuse export of floater/panel coordinates unless
+ // the default is also "topleft". JC
+ if (p.layout().empty() && parent)
{
- node->getAttributeS32("height", h);
+ p.layout = parent->getLayout();
}
- if (parent_view)
+ if (parent)
{
- if (node->hasAttribute("left_delta"))
+ LLRect parent_rect = parent->getLocalRect();
+ // overwrite uninitialized rect params, using context
+ LLRect last_rect = parent->getLocalRect();
+
+ bool layout_topleft = (p.layout() == "topleft");
+ if (layout_topleft)
{
- S32 left_delta = 0;
- node->getAttributeS32("left_delta", left_delta);
- x = last_x + left_delta;
+ //invert top to bottom
+ if (p.rect.top.isProvided()) p.rect.top = parent_rect.getHeight() - p.rect.top;
+ if (p.rect.bottom.isProvided()) p.rect.bottom = parent_rect.getHeight() - p.rect.bottom;
}
- else if (node->hasAttribute("left") && node->hasAttribute("right"))
- {
- // compute width based on left and right
- S32 right = 0;
- node->getAttributeS32("right", right);
- if (right < 0)
- {
- right = parent_view->getRect().getWidth() + right;
- }
- w = right - x;
- }
- else if (node->hasAttribute("left"))
+
+ // convert negative or centered coordinates to parent relative values
+ // Note: some of this logic matches the logic in TypedParam<LLRect>::getValueFromBlock()
+
+ if (p.center_horiz)
{
- if (x < 0)
+ if (p.rect.left.isProvided() && p.rect.right.isProvided())
{
- x = parent_view->getRect().getWidth() + x;
- follows |= FOLLOWS_RIGHT;
+ S32 width = p.rect.right - p.rect.left;
+ width = llmax(width, 0);
+ S32 offset = parent_rect.getWidth()/2 - width/2;
+ p.rect.left = p.rect.left + offset;
+ p.rect.right = p.rect.right + offset;
}
else
{
- follows |= FOLLOWS_LEFT;
+ p.rect.left = p.rect.left + parent_rect.getWidth()/2 - p.rect.width/2;
}
}
- else if (node->hasAttribute("width") && node->hasAttribute("right"))
+ else
+ {
+ if (p.rect.left < 0) p.rect.left = p.rect.left + parent_rect.getWidth();
+ if (p.rect.right < 0) p.rect.right = p.rect.right + parent_rect.getWidth();
+ }
+ if (p.center_vert)
{
- S32 right = 0;
- node->getAttributeS32("right", right);
- if (right < 0)
+ if (p.rect.bottom.isProvided() && p.rect.top.isProvided())
{
- right = parent_view->getRect().getWidth() + right;
+ S32 height = p.rect.top - p.rect.bottom;
+ height = llmax(height, 0);
+ S32 offset = parent_rect.getHeight()/2 - height/2;
+ p.rect.bottom = p.rect.bottom + offset;
+ p.rect.top = p.rect.top + offset;
+ }
+ else
+ {
+ p.rect.bottom = p.rect.bottom + parent_rect.getHeight()/2 - p.rect.height/2;
}
- x = right - w;
}
else
{
- // left not specified, same as last
- x = last_x;
+ if (p.rect.bottom < 0) p.rect.bottom = p.rect.bottom + parent_rect.getHeight();
+ if (p.rect.top < 0) p.rect.top = p.rect.top + parent_rect.getHeight();
}
- if (node->hasAttribute("bottom_delta"))
+
+ // DEPRECATE: automatically fall back to height of MIN_WIDGET_HEIGHT pixels
+ if (!p.rect.height.isProvided() && !p.rect.top.isProvided())
{
- S32 bottom_delta = 0;
- node->getAttributeS32("bottom_delta", bottom_delta);
- y = last_y + bottom_delta;
+ p.rect.height = MIN_WIDGET_HEIGHT;
}
- else if (node->hasAttribute("top"))
+
+ last_rect.translate(0, last_rect.getHeight());
+
+ // If there was a recently constructed child, use its rectangle
+ get_last_child_rect(parent, &last_rect);
+
+ if (layout_topleft)
{
- // compute height based on top
- S32 top = 0;
- node->getAttributeS32("top", top);
- if (top < 0)
+ p.bottom_delta.setIfNotProvided(0, false);
+
+ // Invert the sense of bottom_delta for topleft layout
+ if (p.bottom_delta.isProvided())
{
- top = parent_view->getRect().getHeight() + top;
+ p.bottom_delta = -p.bottom_delta;
}
- h = top - y;
- }
- else if (node->hasAttribute("bottom"))
- {
- if (y < 0)
+ else if (p.top_pad.isProvided())
{
- y = parent_view->getRect().getHeight() + y;
- follows |= FOLLOWS_TOP;
+ p.bottom_delta = -(p.rect.height + p.top_pad);
}
- else
+ else if (p.top_delta.isProvided())
{
- follows |= FOLLOWS_BOTTOM;
+ p.bottom_delta =
+ -(p.top_delta + p.rect.height - last_rect.getHeight());
}
- }
- else
- {
- // if bottom not specified, generate automatically
- if (last_y == 0)
+ else if (!p.bottom_delta.isProvided()
+ && !p.left_delta.isProvided()
+ && !p.top_pad.isProvided()
+ && !p.left_pad.isProvided())
{
- // treat first child as "bottom"
- y = parent_view->getRect().getHeight() - (h + VPAD);
- follows |= FOLLOWS_TOP;
+ // set default position is just below last rect
+ p.bottom_delta.set(-(p.rect.height + VPAD), false);
}
- else
+
+ // default to same left edge
+ p.left_delta.setIfNotProvided(0, false);
+ if (p.left_pad.isProvided())
{
- // treat subsequent children as "bottom_delta"
- y = last_y - (h + VPAD);
+ // left_pad is based on prior widget's right edge
+ p.left_delta.set(p.left_pad + last_rect.getWidth(), false);
}
+
+ last_rect.translate(p.left_delta, p.bottom_delta);
+ }
+ else
+ {
+ // set default position is just below last rect
+ p.bottom_delta.setIfNotProvided(-(p.rect.height + VPAD), false);
+ p.left_delta.setIfNotProvided(0, false);
+ last_rect.translate(p.left_delta, p.bottom_delta);
}
- }
- else
- {
- x = llmax(x, 0);
- y = llmax(y, 0);
- follows = FOLLOWS_LEFT | FOLLOWS_TOP;
- }
- rect.setOriginAndSize(x, y, w, h);
-
- return follows;
-}
-
-void LLView::initFromXML(LLXMLNodePtr node, LLView* parent)
-{
- // create rect first, as this will supply initial follows flags
- LLRect view_rect;
- U32 follows_flags = createRect(node, view_rect, parent, getRequiredRect());
- // call reshape in case there are any child elements that need to be layed out
- reshape(view_rect.getWidth(), view_rect.getHeight());
- setRect(view_rect);
- setFollows(follows_flags);
- parseFollowsFlags(node);
+ // this handles case where *both* x and x_delta are provided
+ // ignore x in favor of default x + x_delta
+ if (p.bottom_delta.isProvided()) p.rect.bottom.set(0, false);
+ if (p.left_delta.isProvided()) p.rect.left.set(0, false);
- if (node->hasAttribute("control_name"))
- {
- std::string control_name;
- node->getAttributeString("control_name", control_name);
- setControlName(control_name, NULL);
- }
-
- if (node->hasAttribute("tool_tip"))
- {
- std::string tool_tip_msg;
- node->getAttributeString("tool_tip", tool_tip_msg);
- setToolTip(tool_tip_msg);
+ // selectively apply rectangle defaults, making sure that
+ // params are not flagged as having been "provided"
+ // as rect params are overconstrained and rely on provided flags
+ p.rect.left.setIfNotProvided(last_rect.mLeft, false);
+ p.rect.bottom.setIfNotProvided(last_rect.mBottom, false);
+ p.rect.top.setIfNotProvided(last_rect.mTop, false);
+ p.rect.right.setIfNotProvided(last_rect.mRight, false);
+ p.rect.width.setIfNotProvided(last_rect.getWidth(), false);
+ p.rect.height.setIfNotProvided(last_rect.getHeight(), false);
}
+}
- if (node->hasAttribute("enabled"))
- {
- BOOL enabled;
- node->getAttributeBOOL("enabled", enabled);
- setEnabled(enabled);
- }
-
- if (node->hasAttribute("visible"))
+static S32 invert_vertical(S32 y, LLView* parent)
+{
+ if (y < 0)
{
- BOOL visible;
- node->getAttributeBOOL("visible", visible);
- setVisible(visible);
+ // already based on top-left, just invert
+ return -y;
}
-
- if (node->hasAttribute("hover_cursor"))
+ else if (parent)
{
- std::string cursor_string;
- node->getAttributeString("hover_cursor", cursor_string);
- mHoverCursor = getCursorFromString(cursor_string);
+ // use parent to flip coordinate
+ S32 parent_height = parent->getRect().getHeight();
+ return parent_height - y;
}
-
- node->getAttributeBOOL("use_bounding_rect", mUseBoundingRect);
- node->getAttributeBOOL("mouse_opaque", mMouseOpaque);
-
- node->getAttributeS32("default_tab_group", mDefaultTabGroup);
-
- reshape(view_rect.getWidth(), view_rect.getHeight());
-}
-
-void LLView::parseFollowsFlags(LLXMLNodePtr node)
-{
- if (node->hasAttribute("follows"))
+ else
{
- setFollowsNone();
-
- std::string follows;
- node->getAttributeString("follows", follows);
-
- typedef boost::tokenizer<boost::char_separator<char> > tokenizer;
- boost::char_separator<char> sep("|");
- tokenizer tokens(follows, sep);
- tokenizer::iterator token_iter = tokens.begin();
-
- while(token_iter != tokens.end())
- {
- const std::string& token_str = *token_iter;
- if (token_str == "left")
+ llwarns << "Attempting to convert layout to top-left with no parent" << llendl;
+ return y;
+ }
+}
+
+// Assumes that input is in bottom-left coordinates, hence must call
+// _before_ convert_coords_to_top_left().
+static void convert_to_relative_layout(LLView::Params& p, LLView* parent)
+{
+ // Use setupParams to get the final widget rectangle
+ // according to our wacky layout rules.
+ LLView::Params final = p;
+ LLView::setupParams(final, parent);
+ // Must actually extract the rectangle to get consistent
+ // right = left+width, top = bottom+height
+ LLRect final_rect = final.rect;
+
+ // We prefer to write out top edge instead of bottom, regardless
+ // of whether we use relative positioning
+ bool converted_top = false;
+
+ // Look for a last rectangle
+ LLRect last_rect;
+ if (get_last_child_rect(parent, &last_rect))
+ {
+ // ...we have a previous widget to compare to
+ const S32 EDGE_THRESHOLD_PIXELS = 4;
+ S32 left_pad = final_rect.mLeft - last_rect.mRight;
+ S32 left_delta = final_rect.mLeft - last_rect.mLeft;
+ S32 top_pad = final_rect.mTop - last_rect.mBottom;
+ S32 top_delta = final_rect.mTop - last_rect.mTop;
+ // If my left edge is almost the same, or my top edge is
+ // almost the same...
+ if (llabs(left_delta) <= EDGE_THRESHOLD_PIXELS
+ || llabs(top_delta) <= EDGE_THRESHOLD_PIXELS)
+ {
+ // ...use relative positioning
+ // prefer top_pad if widgets are stacking vertically
+ // (coordinate system is still bottom-left here)
+ if (top_pad < 0)
{
- setFollowsLeft();
+ p.top_pad = top_pad;
+ p.top_delta.setProvided(false);
}
- else if (token_str == "right")
- {
- setFollowsRight();
- }
- else if (token_str == "top")
+ else
{
- setFollowsTop();
+ p.top_pad.setProvided(false);
+ p.top_delta = top_delta;
}
- else if (token_str == "bottom")
+ // null out other vertical specifiers
+ p.rect.top.setProvided(false);
+ p.rect.bottom.setProvided(false);
+ p.bottom_delta.setProvided(false);
+ converted_top = true;
+
+ // prefer left_pad if widgets are stacking horizontally
+ if (left_pad > 0)
{
- setFollowsBottom();
+ p.left_pad = left_pad;
+ p.left_delta.setProvided(false);
}
- else if (token_str == "all")
+ else
{
- setFollowsAll();
+ p.left_pad.setProvided(false);
+ p.left_delta = left_delta;
}
- ++token_iter;
+ p.rect.left.setProvided(false);
+ p.rect.right.setProvided(false);
}
}
-}
-
-// static
-LLFontGL* LLView::selectFont(LLXMLNodePtr node)
-{
- std::string font_name, font_size, font_style;
- U8 style = 0;
-
- if (node->hasAttribute("font"))
- {
- node->getAttributeString("font", font_name);
- }
-
- if (node->hasAttribute("font_size"))
- {
- node->getAttributeString("font_size", font_size);
- }
- if (node->hasAttribute("font_style"))
+ if (!converted_top)
{
- node->getAttributeString("font_style", font_style);
- style = LLFontGL::getStyleFromString(font_style);
+ // ...this is the first widget, or one that wasn't aligned
+ // prefer top/left specification
+ p.rect.top = final_rect.mTop;
+ p.rect.bottom.setProvided(false);
+ p.bottom_delta.setProvided(false);
+ p.top_pad.setProvided(false);
+ p.top_delta.setProvided(false);
}
-
- if (node->hasAttribute("font-style"))
- {
- node->getAttributeString("font-style", font_style);
- style = LLFontGL::getStyleFromString(font_style);
- }
-
- if (font_name.empty())
- return NULL;
-
- LLFontDescriptor desc(font_name, font_size, style);
- LLFontGL* gl_font = LLFontGL::getFont(desc);
-
- return gl_font;
}
-// static
-LLFontGL::HAlign LLView::selectFontHAlign(LLXMLNodePtr node)
+static void convert_coords_to_top_left(LLView::Params& p, LLView* parent)
{
- LLFontGL::HAlign gl_hfont_align = LLFontGL::LEFT;
-
- if (node->hasAttribute("halign"))
+ // Convert the coordinate system to be top-left based.
+ if (p.rect.top.isProvided())
{
- std::string horizontal_align_name;
- node->getAttributeString("halign", horizontal_align_name);
- gl_hfont_align = LLFontGL::hAlignFromName(horizontal_align_name);
+ p.rect.top = invert_vertical(p.rect.top, parent);
}
- return gl_hfont_align;
-}
-
-// static
-LLFontGL::VAlign LLView::selectFontVAlign(LLXMLNodePtr node)
-{
- LLFontGL::VAlign gl_vfont_align = LLFontGL::BASELINE;
-
- if (node->hasAttribute("valign"))
+ if (p.rect.bottom.isProvided())
{
- std::string vert_align_name;
- node->getAttributeString("valign", vert_align_name);
- gl_vfont_align = LLFontGL::vAlignFromName(vert_align_name);
+ p.rect.bottom = invert_vertical(p.rect.bottom, parent);
}
- return gl_vfont_align;
-}
-
-// static
-LLFontGL::StyleFlags LLView::selectFontStyle(LLXMLNodePtr node)
-{
- LLFontGL::StyleFlags gl_font_style = LLFontGL::NORMAL;
-
- if (node->hasAttribute("style"))
+ if (p.top_pad.isProvided())
{
- std::string style_flags_name;
- node->getAttributeString("style", style_flags_name);
-
- if (style_flags_name == "normal")
- {
- gl_font_style = LLFontGL::NORMAL;
- }
- else if (style_flags_name == "bold")
- {
- gl_font_style = LLFontGL::BOLD;
- }
- else if (style_flags_name == "italic")
- {
- gl_font_style = LLFontGL::ITALIC;
- }
- else if (style_flags_name == "underline")
- {
- gl_font_style = LLFontGL::UNDERLINE;
- }
- //else leave left
+ p.top_pad = -p.top_pad;
}
- return gl_font_style;
-}
-
-bool LLView::setControlValue(const LLSD& value)
-{
- std::string ctrlname = getControlName();
- if (!ctrlname.empty())
+ if (p.top_delta.isProvided())
{
- LLUI::sConfigGroup->setValue(ctrlname, value);
- return true;
+ p.top_delta = -p.top_delta;
}
- return false;
-}
-
-//virtual
-void LLView::setControlName(const std::string& control_name, LLView *context)
-{
- if (context == NULL)
+ if (p.bottom_delta.isProvided())
{
- context = this;
+ p.bottom_delta = -p.bottom_delta;
}
+ p.layout = "topleft";
+}
- if (!mControlName.empty())
- {
- llwarns << "setControlName called twice on same control!" << llendl;
- mControlConnection.disconnect(); // disconnect current signal
- mControlName.clear();
- }
-
- // Register new listener
- if (!control_name.empty())
+//static
+void LLView::setupParamsForExport(Params& p, LLView* parent)
+{
+ // Don't convert if already top-left based
+ if (p.layout() == "topleft")
{
- LLControlVariable *control = context->findControl(control_name);
- if (control)
- {
- mControlName = control_name;
- mControlConnection = control->getSignal()->connect(boost::bind(&controlListener, _1, getHandle(), std::string("value")));
- setValue(control->getValue());
- }
+ return;
}
-}
-// static
-bool LLView::controlListener(const LLSD& newvalue, LLHandle<LLView> handle, std::string type)
-{
- LLView* view = handle.get();
- if (view)
+ // heuristic: Many of our floaters and panels were bulk-exported.
+ // These specify exactly bottom/left and height/width.
+ // Others were done by hand using bottom_delta and/or left_delta.
+ // Some rely on not specifying left to mean align with left edge.
+ // Try to convert both to use relative layout, but using top-left
+ // coordinates.
+ // Avoid rectangles where top/bottom/left/right was specified.
+ if (p.rect.height.isProvided() && p.rect.width.isProvided())
{
- if (type == "value")
+ if (p.rect.bottom.isProvided() && p.rect.left.isProvided())
{
- view->setValue(newvalue);
- return true;
+ // standard bulk export, convert it
+ convert_to_relative_layout(p, parent);
}
- else if (type == "enabled")
+ else if (p.rect.bottom.isProvided() && p.left_delta.isProvided())
{
- view->setEnabled(newvalue.asBoolean());
- return true;
+ // hand layout with left_delta
+ convert_to_relative_layout(p, parent);
}
- else if (type == "visible")
+ else if (p.bottom_delta.isProvided())
{
- view->setVisible(newvalue.asBoolean());
- return true;
+ // hand layout with bottom_delta
+ // don't check for p.rect.left or p.left_delta because sometimes
+ // this layout doesn't set it for widgets that are left-aligned
+ convert_to_relative_layout(p, parent);
}
}
- return false;
-}
-
-void LLView::addBoolControl(const std::string& name, bool initial_value)
-{
- mFloaterControls[name] = new LLControlVariable(name, TYPE_BOOLEAN, initial_value, std::string("Internal floater control"));
-}
-
-LLControlVariable *LLView::getControl(const std::string& name)
-{
- control_map_t::iterator itor = mFloaterControls.find(name);
- if (itor != mFloaterControls.end())
- {
- return itor->second;
- }
- return NULL;
-}
-
-//virtual
-void LLView::setValue(const LLSD& value)
-{
-}
-
-//virtual
-LLSD LLView::getValue() const
-{
- return LLSD();
-}
-
-LLView* LLView::createWidget(LLXMLNodePtr xml_node) const
-{
- // forward requests to ui ctrl factory
- return LLUICtrlFactory::getInstance()->createCtrlWidget(NULL, xml_node);
-}
-
-//
-// LLWidgetClassRegistry
-//
-LLWidgetClassRegistry::LLWidgetClassRegistry()
-{
+ convert_coords_to_top_left(p, parent);
}
-void LLWidgetClassRegistry::registerCtrl(const std::string& tag, LLWidgetClassRegistry::factory_func_t function)
+LLView::tree_iterator_t LLView::beginTree()
{
- std::string lower_case_tag = tag;
- LLStringUtil::toLower(lower_case_tag);
-
- mCreatorFunctions[lower_case_tag] = function;
+ return tree_iterator_t(this,
+ boost::bind(boost::mem_fn(&LLView::beginChild), _1),
+ boost::bind(boost::mem_fn(&LLView::endChild), _1));
}
-BOOL LLWidgetClassRegistry::isTagRegistered(const std::string &tag)
+LLView::tree_iterator_t LLView::endTree()
{
- return mCreatorFunctions.find(tag) != mCreatorFunctions.end();
+ // an empty iterator is an "end" iterator
+ return tree_iterator_t();
}
-LLWidgetClassRegistry::factory_func_t LLWidgetClassRegistry::getCreatorFunc(const std::string& ctrl_type)
-{
- factory_map_t::const_iterator found_it = mCreatorFunctions.find(ctrl_type);
- if (found_it == mCreatorFunctions.end())
+// only create maps on demand, as they incur heap allocation/deallocation cost
+// when a view is constructed/deconstructed
+LLView::default_widget_map_t& LLView::getDefaultWidgetMap() const
+{
+ if (!mDefaultWidgets)
{
- return NULL;
+ mDefaultWidgets = new default_widget_map_t();
}
- return found_it->second;
+ return *mDefaultWidgets;
}
-
diff --git a/indra/llui/llview.h b/indra/llui/llview.h
index 721fe99f4a..ecc6bf47da 100644
--- a/indra/llui/llview.h
+++ b/indra/llui/llview.h
@@ -37,6 +37,7 @@
// the HUD or a dialog box or a button. It can also contain sub-views
// and child widgets
+#include "stdtypes.h"
#include "llcoord.h"
#include "llfontgl.h"
#include "llmortician.h"
@@ -47,12 +48,15 @@
#include "llrect.h"
#include "llui.h"
#include "lluistring.h"
-#include "lluixmltags.h"
#include "llviewquery.h"
-#include "llxmlnode.h"
#include "stdenums.h"
#include "lluistring.h"
#include "llcursortypes.h"
+#include "lluictrlfactory.h"
+#include "lltreeiterators.h"
+#include "llfocusmgr.h"
+
+#include <list>
const U32 FOLLOWS_NONE = 0x00;
const U32 FOLLOWS_LEFT = 0x01;
@@ -75,9 +79,6 @@ virtual BOOL isPanel();
LLPanel
virtual void setRect(const LLRect &rect);
LLLineEditor
-virtual void addCtrl( LLUICtrl* ctrl, S32 tab_group);
-virtual void addCtrlAtEnd( LLUICtrl* ctrl, S32 tab_group);
-virtual void removeCtrl( LLUICtrl* ctrl);
LLPanel
virtual BOOL canFocusChildren() const { return TRUE; }
LLFolderView
@@ -93,7 +94,7 @@ virtual void setEnabled(BOOL enabled) { mEnabled = enabled; }
LLCheckBoxCtrl, LLComboBox, LLLineEditor, LLMenuGL, LLRadioGroup, etc
virtual BOOL setLabelArg( const std::string& key, const LLStringExplicit& text ) { return FALSE; }
LLUICtrl, LLButton, LLCheckBoxCtrl, LLLineEditor, LLMenuGL, LLSliderCtrl
-virtual void onVisibilityChange ( BOOL curVisibilityIn );
+virtual void handleVisibilityChange ( BOOL curVisibilityIn );
LLMenuGL
virtual LLRect getSnapRect() const { return mRect; } *TODO: Make non virtual
LLFloater
@@ -103,7 +104,7 @@ virtual void reshape(S32 width, S32 height, BOOL called_from_parent = TRUE);
LLUICtrl, et. al.
virtual void translate( S32 x, S32 y );
LLMenuGL
-virtual void userSetShape(const LLRect& new_rect);
+virtual void setShape(const LLRect& new_rect, bool by_user);
LLFloater, LLScrollLIstVtrl
virtual LLView* findSnapRect(LLRect& new_rect, const LLCoordGL& mouse_dir, LLView::ESnapType snap_type, S32 threshold, S32 padding = 0);
virtual LLView* findSnapEdge(S32& new_edge_val, const LLCoordGL& mouse_dir, ESnapEdge snap_edge, ESnapType snap_type, S32 threshold, S32 padding = 0);
@@ -122,24 +123,14 @@ virtual void draw();
*
*
-virtual LLXMLNodePtr getXML(bool save_children = true) const;
- *
-virtual void initFromXML(LLXMLNodePtr node, LLView* parent);
- *
virtual void onFocusLost() {}
LLUICtrl, LLScrollListCtrl, LLMenuGL, LLLineEditor, LLComboBox
virtual void onFocusReceived() {}
LLUICtrl, LLTextEditor, LLScrollListVtrl, LLMenuGL, LLLineEditor
virtual LLView* getChildView(const std::string& name, BOOL recurse = TRUE, BOOL create_if_missing = TRUE) const;
LLTabContainer, LLPanel, LLMenuGL
-virtual void setControlName(const std::string& control, LLView *context);
- LLSliderCtrl, LLCheckBoxCtrl
-virtual std::string getControlName() const { return mControlName; }
- LLSliderCtrl, LLCheckBoxCtrl
virtual bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata);
LLMenuItem
-virtual void setValue(const LLSD& value);
- *
protected:
virtual BOOL handleKeyHere(KEY key, MASK mask);
@@ -148,68 +139,84 @@ virtual BOOL handleUnicodeCharHere(llwchar uni_char);
*
*/
-class LLUICtrlFactory;
+class LLViewWidgetRegistry : public LLChildRegistry<LLViewWidgetRegistry>
+{};
-// maps xml strings to widget classes
-class LLWidgetClassRegistry : public LLSingleton<LLWidgetClassRegistry>
+class LLView : public LLMouseHandler, public LLMortician, public LLFocusableElement
{
- friend class LLSingleton<LLWidgetClassRegistry>;
public:
- typedef LLView* (*factory_func_t)(LLXMLNodePtr node, LLView *parent, LLUICtrlFactory *factory);
- typedef std::map<std::string, factory_func_t> factory_map_t;
-
- void registerCtrl(const std::string& xml_tag, factory_func_t function);
- BOOL isTagRegistered(const std::string& xml_tag);
- factory_func_t getCreatorFunc(const std::string& xml_tag);
-
- // get (first) xml tag for a given class
- template <class T> std::string getTag()
+ struct Follows : public LLInitParam::Choice<Follows>
{
- factory_map_t::iterator it;
- for(it = mCreatorFunctions.begin(); it != mCreatorFunctions.end(); ++it)
- {
- if (it->second == T::fromXML)
- {
- return it->first;
- }
- }
-
- return "";
- }
+ Alternative<std::string> string;
+ Alternative<U32> flags;
-private:
- LLWidgetClassRegistry();
- virtual ~LLWidgetClassRegistry() {};
+ Follows()
+ : string(""),
+ flags("flags", FOLLOWS_LEFT | FOLLOWS_TOP)
+ {}
+ };
- typedef std::set<std::string> ctrl_name_set_t;
- ctrl_name_set_t mUICtrlNames;
+ struct Params : public LLInitParam::Block<Params>
+ {
+ Mandatory<std::string> name;
+
+ Optional<bool> enabled,
+ visible,
+ mouse_opaque,
+ use_bounding_rect;
+
+ Optional<S32> tab_group,
+ default_tab_group;
+ Optional<std::string> tool_tip;
+
+ Optional<S32> sound_flags;
+ Optional<bool> from_xui;
+ Optional<Follows> follows;
+ Optional<std::string> hover_cursor;
+
+ // font params
+ Optional<const LLFontGL*> font;
+ Optional<LLFontGL::HAlign> font_halign;
+ Optional<LLFontGL::VAlign> font_valign;
+
+ Optional<std::string> layout;
+ Optional<LLRect> rect;
+ // Historical bottom-left layout used bottom_delta and left_delta
+ // for relative positioning. New layout "topleft" prefers specifying
+ // based on top edge.
+ Optional<S32> bottom_delta, // deprecated
+ top_pad, // from last bottom to my top
+ top_delta, // from last top to my top
+ left_pad, // from last right to my left
+ left_delta; // from last left to my left
+
+ Optional<bool> center_horiz,
+ center_vert;
+
+ // these are nested attributes for LLLayoutPanel
+ //FIXME: get parent context involved in parsing traversal
+ Ignored user_resize,
+ auto_resize,
+ needs_translate,
+ xmlns,
+ xmlns_xsi,
+ xsi_schemaLocation,
+ xsi_type;
+
+ Params();
+ };
- // map of xml tags to widget creator functions
- factory_map_t mCreatorFunctions;
-};
+ typedef LLViewWidgetRegistry child_registry_t;
-template<class T>
-class LLRegisterWidget
-{
-public:
- LLRegisterWidget(const std::string& tag)
- {
- LLWidgetClassRegistry* registry = LLWidgetClassRegistry::getInstance();
- if (registry->isTagRegistered(tag))
- {
- //error!
- llerrs << "Widget named " << tag << " already registered!" << llendl;
- }
- else
- {
- registry->registerCtrl(tag, T::fromXML);
- }
- }
-};
+ void initFromParams(const LLView::Params&);
-class LLView : public LLMouseHandler, public LLMortician
-{
+protected:
+ LLView(const LLView::Params&);
+ friend class LLUICtrlFactory;
+private:
+ // widgets in general are not copyable
+ LLView(const LLView& other) {};
public:
#if LL_DEBUG
static BOOL sIsDrawing;
@@ -253,10 +260,6 @@ public:
typedef child_tab_order_t::reverse_iterator child_tab_order_reverse_iter_t;
typedef child_tab_order_t::const_reverse_iterator child_tab_order_const_reverse_iter_t;
- LLView();
- LLView(const std::string& name, BOOL mouse_opaque);
- LLView(const std::string& name, const LLRect& rect, BOOL mouse_opaque, U32 follows=FOLLOWS_NONE);
-
virtual ~LLView();
// Hack to support LLFocusMgr (from LLMouseHandler)
@@ -300,15 +303,19 @@ public:
void sendChildToBack(LLView* child);
void moveChildToFrontOfTabGroup(LLUICtrl* child);
void moveChildToBackOfTabGroup(LLUICtrl* child);
+
+ virtual bool addChild(LLView* view, S32 tab_group = 0);
+
+ // implemented in terms of addChild()
+ bool addChildInBack(LLView* view, S32 tab_group = 0);
- void addChild(LLView* view, S32 tab_group = 0);
- void addChildAtEnd(LLView* view, S32 tab_group = 0);
// remove the specified child from the view, and set it's parent to NULL.
- void removeChild(LLView* view, BOOL deleteIt = FALSE);
+ virtual void removeChild(LLView* view);
+
+ // helper function for lluictrlfactory.h create<> template
+ void setParent(LLView* parent) { if (parent) parent->addChild(this); }
- virtual void addCtrl( LLUICtrl* ctrl, S32 tab_group);
- virtual void addCtrlAtEnd( LLUICtrl* ctrl, S32 tab_group);
- virtual void removeCtrl( LLUICtrl* ctrl);
+ virtual BOOL postBuild() { return TRUE; }
child_tab_order_t getCtrlOrder() const { return mCtrlOrder; }
ctrl_list_t getCtrlList() const;
@@ -316,7 +323,9 @@ public:
void setDefaultTabGroup(S32 d) { mDefaultTabGroup = d; }
S32 getDefaultTabGroup() const { return mDefaultTabGroup; }
+ S32 getLastTabGroup() { return mLastTabGroup; }
+ bool trueToRoot(const boost::function<bool (const LLView*)>& predicate) const;
BOOL isInVisibleChain() const;
BOOL isInEnabledChain() const;
@@ -344,10 +353,10 @@ public:
virtual BOOL setLabelArg( const std::string& key, const LLStringExplicit& text );
- virtual void onVisibilityChange ( BOOL curVisibilityIn );
+ virtual void handleVisibilityChange ( BOOL new_visibility );
void pushVisible(BOOL visible) { mLastVisible = mVisible; setVisible(visible); }
- void popVisible() { setVisible(mLastVisible); mLastVisible = TRUE; }
+ void popVisible() { setVisible(mLastVisible); }
LLHandle<LLView> getHandle() { mHandle.bind(this); return mHandle; }
@@ -361,11 +370,14 @@ public:
const LLRect& getRect() const { return mRect; }
const LLRect& getBoundingRect() const { return mBoundingRect; }
LLRect getLocalBoundingRect() const;
- LLRect getScreenRect() const;
+ LLRect calcScreenRect() const;
+ LLRect calcScreenBoundingRect() const;
LLRect getLocalRect() const;
virtual LLRect getSnapRect() const;
LLRect getLocalSnapRect() const;
+ std::string getLayout() { return mLayout; }
+
// Override and return required size for this object. 0 for width/height means don't care.
virtual LLRect getRequiredRect();
void updateBoundingRect();
@@ -373,12 +385,17 @@ public:
LLView* getRootView();
LLView* getParent() const { return mParentView; }
LLView* getFirstChild() const { return (mChildList.empty()) ? NULL : *(mChildList.begin()); }
+ LLView* findPrevSibling(LLView* child);
+ LLView* findNextSibling(LLView* child);
S32 getChildCount() const { return (S32)mChildList.size(); }
template<class _Pr3> void sortChildren(_Pr3 _Pred) { mChildList.sort(_Pred); }
BOOL hasAncestor(const LLView* parentp) const;
BOOL hasChild(const std::string& childname, BOOL recurse = FALSE) const;
BOOL childHasKeyboardFocus( const std::string& childname ) const;
-
+
+ typedef LLTreeDFSIter<LLView, child_list_const_iter_t> tree_iterator_t;
+ tree_iterator_t beginTree();
+ tree_iterator_t endTree();
//
// UTILITIES
@@ -391,38 +408,36 @@ public:
BOOL translateIntoRect( const LLRect& constraint, BOOL allow_partial_outside );
void centerWithin(const LLRect& bounds);
- virtual void userSetShape(const LLRect& new_rect);
+ void setShape(const LLRect& new_rect, bool by_user = false);
virtual LLView* findSnapRect(LLRect& new_rect, const LLCoordGL& mouse_dir, LLView::ESnapType snap_type, S32 threshold, S32 padding = 0);
virtual LLView* findSnapEdge(S32& new_edge_val, const LLCoordGL& mouse_dir, ESnapEdge snap_edge, ESnapType snap_type, S32 threshold, S32 padding = 0);
-
virtual BOOL canSnapTo(const LLView* other_view);
+ virtual void setSnappedTo(const LLView* snap_view);
- virtual void snappedTo(const LLView* snap_view);
+ // inherited from LLFocusableElement
+ /* virtual */ BOOL handleKey(KEY key, MASK mask, BOOL called_from_parent);
+ /* virtual */ BOOL handleUnicodeChar(llwchar uni_char, BOOL called_from_parent);
- virtual BOOL handleKey(KEY key, MASK mask, BOOL called_from_parent);
- virtual BOOL handleUnicodeChar(llwchar uni_char, BOOL called_from_parent);
virtual BOOL handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop,
EDragAndDropType cargo_type,
void* cargo_data,
EAcceptance* accept,
std::string& tooltip_msg);
- std::string getShowNamesToolTip();
+ virtual std::string getShowNamesToolTip();
virtual void draw();
+ void drawChildren();
- virtual LLXMLNodePtr getXML(bool save_children = true) const;
- //FIXME: make LLView non-instantiable from XML
- static LLView* fromXML(LLXMLNodePtr node, LLView *parent, class LLUICtrlFactory *factory);
- virtual void initFromXML(LLXMLNodePtr node, LLView* parent);
- void parseFollowsFlags(LLXMLNodePtr node);
+ void parseFollowsFlags(const LLView::Params& params);
// Some widgets, like close box buttons, don't need to be saved
BOOL getSaveToXML() const { return mSaveToXML; }
void setSaveToXML(BOOL b) { mSaveToXML = b; }
- virtual void onFocusLost();
- virtual void onFocusReceived();
+ // inherited from LLFocusableElement
+ /* virtual */ void onFocusLost();
+ /* virtual */ void onFocusReceived();
typedef enum e_hit_test_type
{
@@ -440,25 +455,16 @@ public:
void screenRectToLocal( const LLRect& screen, LLRect* local ) const;
void localRectToScreen( const LLRect& local, LLRect* screen ) const;
- // Listener dispatching functions (Dispatcher deletes pointers to listeners on deregistration or destruction)
- LLOldEvents::LLSimpleListener* getListenerByName(const std::string& callback_name);
- void registerEventListener(std::string name, LLOldEvents::LLSimpleListener* function);
- void deregisterEventListener(std::string name);
- std::string findEventListener(LLOldEvents::LLSimpleListener *listener) const;
- void addListenerToControl(LLOldEvents::LLEventDispatcher *observer, const std::string& name, LLSD filter, LLSD userdata);
-
- void addBoolControl(const std::string& name, bool initial_value);
- LLControlVariable *getControl(const std::string& name);
LLControlVariable *findControl(const std::string& name);
- bool setControlValue(const LLSD& value);
- virtual void setControlName(const std::string& control, LLView *context);
- virtual std::string getControlName() const { return mControlName; }
+ // Moved setValue(), getValue(), setControlValue(), setControlName(),
+ // controlListener() to LLUICtrl because an LLView is NOT assumed to
+ // contain a value. If that's what you want, use LLUICtrl instead.
// virtual bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata);
- virtual void setValue(const LLSD& value);
- virtual LLSD getValue() const;
const child_list_t* getChildList() const { return &mChildList; }
+ const child_list_const_iter_t beginChild() { return mChildList.begin(); }
+ const child_list_const_iter_t endChild() { return mChildList.end(); }
// LLMouseHandler functions
// Default behavior is to pass events to children
@@ -479,99 +485,43 @@ public:
/*virtual*/ void screenPointToLocal(S32 screen_x, S32 screen_y, S32* local_x, S32* local_y) const;
/*virtual*/ void localPointToScreen(S32 local_x, S32 local_y, S32* screen_x, S32* screen_y) const;
- template <class T> T* getChild(const std::string& name, BOOL recurse = TRUE, BOOL create_if_missing = TRUE) const
+ // view-specific handlers
+ virtual void onMouseEnter(S32 x, S32 y, MASK mask);
+ virtual void onMouseLeave(S32 x, S32 y, MASK mask);
+
+
+ template <class T> T* findChild(const std::string& name, BOOL recurse = TRUE) const
{
- LLView* child = getChildView(name, recurse, FALSE);
+ LLView* child = findChildView(name, recurse);
T* result = dynamic_cast<T*>(child);
- if (!result)
- {
- // did we find *something* with that name?
- if (child)
- {
- llwarns << "Found child named " << name << " but of wrong type " << typeid(child).name() << ", expecting " << typeid(T).name() << llendl;
- }
- if (create_if_missing)
- {
- // create dummy widget instance here
- result = createDummyWidget<T>(name);
- }
- }
return result;
}
+ template <class T> T* getChild(const std::string& name, BOOL recurse = TRUE) const;
+
template <class T> T& getChildRef(const std::string& name, BOOL recurse = TRUE) const
{
- return *getChild<T>(name, recurse, TRUE);
+ return *getChild<T>(name, recurse);
}
- virtual LLView* getChildView(const std::string& name, BOOL recurse = TRUE, BOOL create_if_missing = TRUE) const;
+ virtual LLView* getChildView(const std::string& name, BOOL recurse = TRUE) const;
+ virtual LLView* findChildView(const std::string& name, BOOL recurse = TRUE) const;
- template <class T> T* createDummyWidget(const std::string& name) const
+ template <class T> T* getDefaultWidget(const std::string& name) const
{
- T* widget = getDummyWidget<T>(name);
- if (!widget)
- {
- // get xml tag name corresponding to requested widget type (e.g. "button")
- std::string xml_tag = LLWidgetClassRegistry::getInstance()->getTag<T>();
- if (xml_tag.empty())
- {
- llwarns << "No xml tag registered for this class " << llendl;
- return NULL;
- }
- // create dummy xml node (<button name="foo"/>)
- LLXMLNodePtr new_node_ptr = new LLXMLNode(xml_tag.c_str(), FALSE);
- new_node_ptr->createChild("name", TRUE)->setStringValue(name);
-
- widget = dynamic_cast<T*>(createWidget(new_node_ptr));
- if (widget)
- {
- // need non-const to update private dummy widget cache
- llwarns << "Making dummy " << xml_tag << " named " << name << " in " << getName() << llendl;
- mDummyWidgets.insert(std::make_pair(name, widget));
- }
- else
- {
- // dynamic cast will fail if T::fromXML only registered for base class
- llwarns << "Failed to create dummy widget of requested type " << llendl;
- return NULL;
- }
- }
- return widget;
- }
-
- template <class T> T* getDummyWidget(const std::string& name) const
- {
- dummy_widget_map_t::const_iterator found_it = mDummyWidgets.find(name);
- if (found_it == mDummyWidgets.end())
+ default_widget_map_t::const_iterator found_it = getDefaultWidgetMap().find(name);
+ if (found_it == getDefaultWidgetMap().end())
{
return NULL;
}
return dynamic_cast<T*>(found_it->second);
}
- LLView* createWidget(LLXMLNodePtr xml_node) const;
-
-
+ //////////////////////////////////////////////
// statics
- static U32 createRect(LLXMLNodePtr node, LLRect &rect, LLView* parent_view, const LLRect &required_rect = LLRect());
-
- static LLFontGL* selectFont(LLXMLNodePtr node);
- static LLFontGL::HAlign selectFontHAlign(LLXMLNodePtr node);
- static LLFontGL::VAlign selectFontVAlign(LLXMLNodePtr node);
- static LLFontGL::StyleFlags selectFontStyle(LLXMLNodePtr node);
-
-
- // Only saves color if different from default setting.
- static void addColorXML(LLXMLNodePtr node, const LLColor4& color,
- const char* xml_name, const char* control_name);
- // Escapes " (quot) ' (apos) & (amp) < (lt) > (gt)
- //static std::string escapeXML(const std::string& xml);
- static LLWString escapeXML(const LLWString& xml);
+ //////////////////////////////////////////////
+ //static LLFontGL::HAlign selectFontHAlign(LLXMLNodePtr node);
- //same as above, but wraps multiple lines in quotes and prepends
- //indent as leading white space on each line
- static std::string escapeXML(const std::string& xml, std::string& indent);
-
// focuses the item in the list after the currently-focused item, wrapping if necessary
static BOOL focusNext(LLView::child_list_t & result);
// focuses the item in the list before the currently-focused item, wrapping if necessary
@@ -582,14 +532,24 @@ public:
// return query for iterating over focus roots in tab order
static const LLCtrlQuery & getFocusRootsQuery();
- static BOOL deleteViewByHandle(LLHandle<LLView> handle);
+ static void deleteViewByHandle(LLHandle<LLView> handle);
static LLWindow* getWindow(void) { return LLUI::sWindow; }
+ // Set up params after XML load before calling new(),
+ // usually to adjust layout.
+ static void setupParams(Params& p, LLView* parent);
+
+ // For re-export of floaters and panels, convert the coordinate system
+ // to be top-left based.
+ static void setupParamsForExport(Params& p, LLView* parent);
-protected:
+ //virtual BOOL addChildFromParam(const LLInitParam::BaseBlock& params) { return TRUE; }
virtual BOOL handleKeyHere(KEY key, MASK mask);
virtual BOOL handleUnicodeCharHere(llwchar uni_char);
+ virtual void handleReshape(const LLRect& rect, bool by_user);
+
+protected:
void drawDebugRect();
void drawChild(LLView* childp, S32 x_offset = 0, S32 y_offset = 0, BOOL force_draw = FALSE);
@@ -612,11 +572,8 @@ protected:
LLView* childrenHandleRightMouseDown(S32 x, S32 y, MASK mask);
LLView* childrenHandleRightMouseUp(S32 x, S32 y, MASK mask);
- static bool controlListener(const LLSD& newvalue, LLHandle<LLView> handle, std::string type);
-
- typedef std::map<std::string, LLControlVariable*> control_map_t;
- control_map_t mFloaterControls;
-
+ ECursorType mHoverCursor;
+
private:
LLView* mParentView;
child_list_t mChildList;
@@ -625,11 +582,13 @@ private:
// location in pixels, relative to surrounding structure, bottom,left=0,0
LLRect mRect;
LLRect mBoundingRect;
+ std::string mLayout;
U32 mReshapeFlags;
child_tab_order_t mCtrlOrder;
S32 mDefaultTabGroup;
+ S32 mLastTabGroup;
BOOL mEnabled; // Enabled means "accepts input that has an effect on the state of the application."
// A disabled view, for example, may still have a scrollbar that responds to mouse events.
@@ -651,18 +610,12 @@ private:
static LLWindow* sWindow; // All root views must know about their window.
- typedef std::map<std::string, LLPointer<LLOldEvents::LLSimpleListener> > dispatch_list_t;
- dispatch_list_t mDispatchList;
+ typedef std::map<std::string, LLView*> default_widget_map_t;
+ // allocate this map no demand, as it is rarely needed
+ mutable default_widget_map_t* mDefaultWidgets;
- std::string mControlName;
+ default_widget_map_t& getDefaultWidgetMap() const;
- typedef std::map<std::string, LLView*> dummy_widget_map_t;
- mutable dummy_widget_map_t mDummyWidgets;
-
- boost::signals2::connection mControlConnection;
-
- ECursorType mHoverCursor;
-
public:
static BOOL sDebugRects; // Draw debug rects behind everything.
static BOOL sDebugKeys;
@@ -670,8 +623,12 @@ public:
static BOOL sDebugMouseHandling;
static std::string sMouseHandlerMessage;
static S32 sSelectID;
- static BOOL sEditingUI;
- static LLView* sEditingUIView;
+// static BOOL sEditingUI;
+// static LLView* sEditingUIView;
+ static std::set<LLView*> sPreviewHighlightedElements; // DEV-16869
+ static BOOL sHighlightingDiffs; // DEV-16869
+ static LLView* sPreviewClickedElement; // DEV-16869
+ static BOOL sDrawPreviewHighlights;
static S32 sLastLeftXML;
static S32 sLastBottomXML;
static BOOL sForceReshape;
@@ -688,5 +645,39 @@ private:
LLView::child_tab_order_t mTabOrder;
};
+template <class T> T* LLView::getChild(const std::string& name, BOOL recurse) const
+{
+ LLView* child = findChildView(name, recurse);
+ T* result = dynamic_cast<T*>(child);
+ if (!result)
+ {
+ // did we find *something* with that name?
+ if (child)
+ {
+ llwarns << "Found child named " << name << " but of wrong type " << typeid(child).name() << ", expecting " << typeid(T*).name() << llendl;
+ }
+ result = getDefaultWidget<T>(name);
+ if (!result)
+ {
+ result = LLUICtrlFactory::getDefaultWidget<T>(name);
+
+ if (result)
+ {
+ // *NOTE: You cannot call mFoo = getChild<LLFoo>("bar")
+ // in a floater or panel constructor. The widgets will not
+ // be ready. Instead, put it in postBuild().
+ llwarns << "Making dummy " << typeid(T).name() << " named \"" << name << "\" in " << getName() << llendl;
+ }
+ else
+ {
+ llwarns << "Failed to create dummy " << typeid(T).name() << llendl;
+ return NULL;
+ }
+
+ getDefaultWidgetMap()[name] = result;
+ }
+ }
+ return result;
+}
#endif //LL_LLVIEW_H
diff --git a/indra/llui/llviewborder.cpp b/indra/llui/llviewborder.cpp
index d4a9e9d1bf..f41c98f7b3 100644
--- a/indra/llui/llviewborder.cpp
+++ b/indra/llui/llviewborder.cpp
@@ -33,25 +33,54 @@
#include "llviewborder.h"
#include "llrender.h"
#include "llfocusmgr.h"
+#include "lluictrlfactory.h"
-static LLRegisterWidget<LLViewBorder> r("view_border");
-
-LLViewBorder::LLViewBorder( const std::string& name, const LLRect& rect, EBevel bevel, EStyle style, S32 width )
- :
- LLView( name, rect, FALSE ),
- mBevel( bevel ),
- mStyle( style ),
- mHighlightLight( LLUI::sColorsGroup->getColor( "DefaultHighlightLight" ) ),
- mHighlightDark( LLUI::sColorsGroup->getColor( "DefaultHighlightDark" ) ),
- mShadowLight( LLUI::sColorsGroup->getColor( "DefaultShadowLight" ) ),
- mShadowDark( LLUI::sColorsGroup->getColor( "DefaultShadowDark" ) ),
- mBorderWidth( width ),
- mTexture( NULL ),
- mHasKeyboardFocus( FALSE )
+static LLDefaultChildRegistry::Register<LLViewBorder> r("view_border");
+
+void LLViewBorder::BevelValues::declareValues()
+{
+ declare("in", LLViewBorder::BEVEL_IN);
+ declare("out", LLViewBorder::BEVEL_OUT);
+ declare("bright", LLViewBorder::BEVEL_BRIGHT);
+ declare("none", LLViewBorder::BEVEL_NONE);
+}
+
+void LLViewBorder::StyleValues::declareValues()
{
- setFollowsAll();
+ declare("line", LLViewBorder::STYLE_LINE);
+ declare("texture", LLViewBorder::STYLE_TEXTURE);
}
+LLViewBorder::Params::Params()
+: bevel_style("bevel_style", BEVEL_OUT),
+ render_style("border_style", STYLE_LINE),
+ border_thickness("border_thickness"),
+ highlight_light_color("highlight_light_color"),
+ highlight_dark_color("highlight_dark_color"),
+ shadow_light_color("shadow_light_color"),
+ shadow_dark_color("shadow_dark_color")
+{
+ addSynonym(border_thickness, "thickness");
+ addSynonym(render_style, "style");
+ name = "view_border";
+ mouse_opaque = false;
+ follows.flags = FOLLOWS_ALL;
+}
+
+
+LLViewBorder::LLViewBorder(const LLViewBorder::Params& p)
+: LLView(p),
+ mTexture( NULL ),
+ mHasKeyboardFocus( FALSE ),
+ mBorderWidth(p.border_thickness),
+ mHighlightLight(p.highlight_light_color()),
+ mHighlightDark(p.highlight_dark_color()),
+ mShadowLight(p.shadow_light_color()),
+ mShadowDark(p.shadow_dark_color()),
+ mBevel(p.bevel_style),
+ mStyle(p.render_style)
+{}
+
void LLViewBorder::setColors( const LLColor4& shadow_dark, const LLColor4& highlight_light )
{
mShadowDark = shadow_dark;
@@ -69,7 +98,7 @@ void LLViewBorder::setColorsExtended( const LLColor4& shadow_light, const LLColo
void LLViewBorder::setTexture( const LLUUID &image_id )
{
- mTexture = LLUI::sImageProvider->getUIImageByID(image_id);
+ mTexture = LLUI::getUIImageByID(image_id);
}
@@ -105,26 +134,24 @@ void LLViewBorder::draw()
}
}
- // draw the children
- LLView::draw();
-
+ drawChildren();
}
void LLViewBorder::drawOnePixelLines()
{
gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
- LLColor4 top_color = mHighlightLight;
- LLColor4 bottom_color = mHighlightLight;
+ LLColor4 top_color = mHighlightLight.get();
+ LLColor4 bottom_color = mHighlightLight.get();
switch( mBevel )
{
case BEVEL_OUT:
- top_color = mHighlightLight;
- bottom_color = mShadowDark;
+ top_color = mHighlightLight.get();
+ bottom_color = mShadowDark.get();
break;
case BEVEL_IN:
- top_color = mShadowDark;
- bottom_color = mHighlightLight;
+ top_color = mShadowDark.get();
+ bottom_color = mHighlightLight.get();
break;
case BEVEL_NONE:
// use defaults
@@ -163,31 +190,36 @@ void LLViewBorder::drawTwoPixelLines()
LLColor4 focus_color = gFocusMgr.getFocusColor();
- F32* top_in_color = mShadowDark.mV;
- F32* top_out_color = mShadowDark.mV;
- F32* bottom_in_color = mShadowDark.mV;
- F32* bottom_out_color = mShadowDark.mV;
+ LLColor4 top_in_color;
+ LLColor4 top_out_color;
+ LLColor4 bottom_in_color;
+ LLColor4 bottom_out_color;
+
switch( mBevel )
{
case BEVEL_OUT:
- top_in_color = mHighlightLight.mV;
- top_out_color = mHighlightDark.mV;
- bottom_in_color = mShadowLight.mV;
- bottom_out_color = mShadowDark.mV;
+ top_in_color = mHighlightLight.get();
+ top_out_color = mHighlightDark.get();
+ bottom_in_color = mShadowLight.get();
+ bottom_out_color = mShadowDark.get();
break;
case BEVEL_IN:
- top_in_color = mShadowDark.mV;
- top_out_color = mShadowLight.mV;
- bottom_in_color = mHighlightDark.mV;
- bottom_out_color = mHighlightLight.mV;
+ top_in_color = mShadowDark.get();
+ top_out_color = mShadowLight.get();
+ bottom_in_color = mHighlightDark.get();
+ bottom_out_color = mHighlightLight.get();
break;
case BEVEL_BRIGHT:
- top_in_color = mHighlightLight.mV;
- top_out_color = mHighlightLight.mV;
- bottom_in_color = mHighlightLight.mV;
- bottom_out_color = mHighlightLight.mV;
+ top_in_color = mHighlightLight.get();
+ top_out_color = mHighlightLight.get();
+ bottom_in_color = mHighlightLight.get();
+ bottom_out_color = mHighlightLight.get();
break;
case BEVEL_NONE:
+ top_in_color = mShadowDark.get();
+ top_out_color = mShadowDark.get();
+ bottom_in_color = mShadowDark.get();
+ bottom_out_color = mShadowDark.get();
// use defaults
break;
default:
@@ -196,8 +228,8 @@ void LLViewBorder::drawTwoPixelLines()
if( mHasKeyboardFocus )
{
- top_out_color = focus_color.mV;
- bottom_out_color = focus_color.mV;
+ top_out_color = focus_color;
+ bottom_out_color = focus_color;
}
S32 left = 0;
@@ -206,19 +238,19 @@ void LLViewBorder::drawTwoPixelLines()
S32 bottom = 0;
// draw borders
- gGL.color3fv( top_out_color );
+ gGL.color3fv( top_out_color.mV );
gl_line_2d(left, bottom, left, top-1);
gl_line_2d(left, top-1, right, top-1);
- gGL.color3fv( top_in_color );
+ gGL.color3fv( top_in_color.mV );
gl_line_2d(left+1, bottom+1, left+1, top-2);
gl_line_2d(left+1, top-2, right-1, top-2);
- gGL.color3fv( bottom_out_color );
+ gGL.color3fv( bottom_out_color.mV );
gl_line_2d(right-1, top-1, right-1, bottom);
gl_line_2d(left, bottom, right, bottom);
- gGL.color3fv( bottom_in_color );
+ gGL.color3fv( bottom_in_color.mV );
gl_line_2d(right-2, top-2, right-2, bottom+1);
gl_line_2d(left+1, bottom+1, right-1, bottom+1);
}
@@ -302,26 +334,3 @@ BOOL LLViewBorder::getBevelFromAttribute(LLXMLNodePtr node, LLViewBorder::EBevel
return FALSE;
}
-
-// static
-LLView* LLViewBorder::fromXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFactory *factory)
-{
- std::string name("view_border");
- node->getAttributeString("name", name);
-
- LLViewBorder::EBevel bevel_style = LLViewBorder::BEVEL_IN;
- getBevelFromAttribute(node, bevel_style);
-
- S32 border_thickness = 1;
- node->getAttributeS32("border_thickness", border_thickness);
-
- LLViewBorder* border = new LLViewBorder(name,
- LLRect(),
- bevel_style,
- LLViewBorder::STYLE_LINE,
- border_thickness);
-
- border->initFromXML(node, parent);
-
- return border;
-}
diff --git a/indra/llui/llviewborder.h b/indra/llui/llviewborder.h
index a40e6534a8..92fd569325 100644
--- a/indra/llui/llviewborder.h
+++ b/indra/llui/llviewborder.h
@@ -35,15 +35,41 @@
#include "llview.h"
-
class LLViewBorder : public LLView
{
public:
- enum EBevel { BEVEL_IN, BEVEL_OUT, BEVEL_BRIGHT, BEVEL_NONE };
- enum EStyle { STYLE_LINE, STYLE_TEXTURE };
-
- LLViewBorder( const std::string& name, const LLRect& rect, EBevel bevel = BEVEL_OUT, EStyle style = STYLE_LINE, S32 width = 1 );
-
+ typedef enum e_bevel { BEVEL_IN, BEVEL_OUT, BEVEL_BRIGHT, BEVEL_NONE } EBevel ;
+ typedef enum e_style { STYLE_LINE, STYLE_TEXTURE } EStyle;
+
+ struct BevelValues
+ : public LLInitParam::TypeValuesHelper<LLViewBorder::EBevel, BevelValues>
+ {
+ static void declareValues();
+ };
+
+ struct StyleValues
+ : public LLInitParam::TypeValuesHelper<LLViewBorder::EStyle, StyleValues>
+ {
+ static void declareValues();
+ };
+
+ struct Params : public LLInitParam::Block<Params, LLView::Params>
+ {
+ Optional<EBevel, BevelValues> bevel_style;
+ Optional<EStyle, StyleValues> render_style;
+ Optional<S32> border_thickness;
+
+ Optional<LLUIColor> highlight_light_color,
+ highlight_dark_color,
+ shadow_light_color,
+ shadow_dark_color;
+
+ Params();
+ };
+protected:
+ LLViewBorder(const Params&);
+ friend class LLUICtrlFactory;
+public:
virtual void setValue(const LLSD& val) { setRect(LLRect(val)); }
virtual BOOL isCtrl() const { return FALSE; }
@@ -51,7 +77,6 @@ public:
// llview functionality
virtual void draw();
- static LLView* fromXML(LLXMLNodePtr node, LLView *parent, class LLUICtrlFactory *factory);
static BOOL getBevelFromAttribute(LLXMLNodePtr node, LLViewBorder::EBevel& bevel_style);
void setBorderWidth(S32 width) { mBorderWidth = width; }
@@ -63,8 +88,8 @@ public:
const LLColor4& highlight_light, const LLColor4& highlight_dark );
void setTexture( const class LLUUID &image_id );
- LLColor4 getHighlightLight() {return mHighlightLight;}
- LLColor4 getShadowDark() {return mHighlightDark;}
+ LLColor4 getHighlightLight() {return mHighlightLight.get();}
+ LLColor4 getShadowDark() {return mHighlightDark.get();}
EStyle getStyle() const { return mStyle; }
@@ -77,14 +102,14 @@ private:
void drawTextureTrapezoid( F32 degrees, S32 width, S32 length, F32 start_x, F32 start_y );
EBevel mBevel;
- const EStyle mStyle;
- LLColor4 mHighlightLight;
- LLColor4 mHighlightDark;
- LLColor4 mShadowLight;
- LLColor4 mShadowDark;
- LLColor4 mBackgroundColor;
+ EStyle mStyle;
+ LLUIColor mHighlightLight;
+ LLUIColor mHighlightDark;
+ LLUIColor mShadowLight;
+ LLUIColor mShadowDark;
+ LLUIColor mBackgroundColor;
S32 mBorderWidth;
- LLUIImagePtr mTexture;
+ LLPointer<LLUIImage> mTexture;
BOOL mHasKeyboardFocus;
};
diff --git a/indra/llui/llviewmodel.cpp b/indra/llui/llviewmodel.cpp
new file mode 100644
index 0000000000..4107289e85
--- /dev/null
+++ b/indra/llui/llviewmodel.cpp
@@ -0,0 +1,163 @@
+/**
+ * @file llviewmodel.cpp
+ * @author Nat Goodspeed
+ * @date 2008-08-08
+ * @brief Implementation for llviewmodel.
+ *
+ * $LicenseInfo:firstyear=2008&license=viewergpl$
+ *
+ * Copyright (c) 2008-2009, Linden Research, Inc.
+ *
+ * Second Life Viewer Source Code
+ * The source code in this file ("Source Code") is provided by Linden Lab
+ * to you under the terms of the GNU General Public License, version 2.0
+ * ("GPL"), unless you have obtained a separate licensing agreement
+ * ("Other License"), formally executed by you and Linden Lab. Terms of
+ * the GPL can be found in doc/GPL-license.txt in this distribution, or
+ * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
+ *
+ * There are special exceptions to the terms and conditions of the GPL as
+ * it is applied to this Source Code. View the full text of the exception
+ * in the file doc/FLOSS-exception.txt in this software distribution, or
+ * online at
+ * http://secondlifegrid.net/programs/open_source/licensing/flossexception
+ *
+ * By copying, modifying or distributing this software, you acknowledge
+ * that you have read and understood your obligations described above,
+ * and agree to abide by those obligations.
+ *
+ * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+ * COMPLETENESS OR PERFORMANCE.
+ * $/LicenseInfo$
+ */
+
+// Precompiled header
+#include "linden_common.h"
+// associated header
+#include "llviewmodel.h"
+// STL headers
+// std headers
+// external library headers
+// other Linden headers
+
+///
+LLViewModel::LLViewModel()
+ : mDirty(false)
+{
+}
+
+/// Instantiate an LLViewModel with an existing data value
+LLViewModel::LLViewModel(const LLSD& value)
+ : mDirty(false)
+{
+ setValue(value);
+}
+
+/// Update the stored value
+void LLViewModel::setValue(const LLSD& value)
+{
+ mValue = value;
+ mDirty = true;
+}
+
+LLSD LLViewModel::getValue() const
+{
+ return mValue;
+}
+
+////////////////////////////////////////////////////////////////////////////
+
+///
+LLTextViewModel::LLTextViewModel()
+ : LLViewModel(false),
+ mUpdateFromDisplay(false)
+{
+}
+
+/// Instantiate an LLViewModel with an existing data value
+LLTextViewModel::LLTextViewModel(const LLSD& value)
+ : LLViewModel(value),
+ mUpdateFromDisplay(false)
+{
+}
+
+/// Update the stored value
+void LLTextViewModel::setValue(const LLSD& value)
+{
+ LLViewModel::setValue(value);
+ mDisplay = utf8str_to_wstring(value.asString());
+ // mDisplay and mValue agree
+ mUpdateFromDisplay = false;
+}
+
+void LLTextViewModel::setDisplay(const LLWString& value)
+{
+ // This is the strange way to alter the value. Normally we'd setValue()
+ // and do the utf8str_to_wstring() to get the corresponding mDisplay
+ // value. But a text editor might want to edit the display string
+ // directly, then convert back to UTF8 on commit.
+ mDisplay = value;
+ mDirty = true;
+ // Don't immediately convert to UTF8 -- do it lazily -- we expect many
+ // more setDisplay() calls than getValue() calls. Just flag that it needs
+ // doing.
+ mUpdateFromDisplay = true;
+}
+
+LLSD LLTextViewModel::getValue() const
+{
+ // Has anyone called setDisplay() since the last setValue()? If so, have
+ // to convert mDisplay back to UTF8.
+ if (mUpdateFromDisplay)
+ {
+ // The fact that we're lazily updating fields in this object should be
+ // transparent to clients, which is why this method is left
+ // conventionally const. Nor do we particularly want to make these
+ // members mutable. Just cast away constness in this one place.
+ LLTextViewModel* nthis = const_cast<LLTextViewModel*>(this);
+ nthis->mUpdateFromDisplay = false;
+ nthis->mValue = wstring_to_utf8str(mDisplay);
+ }
+ return LLViewModel::getValue();
+}
+
+
+////////////////////////////////////////////////////////////////////////////
+
+LLListViewModel::LLListViewModel(const LLSD& values)
+ : LLViewModel()
+{
+}
+
+void LLListViewModel::addColumn(const LLSD& column, EAddPosition pos)
+{
+}
+
+void LLListViewModel::clearColumns()
+{
+}
+
+void LLListViewModel::setColumnLabel(const std::string& column, const std::string& label)
+{
+}
+
+LLScrollListItem* LLListViewModel::addElement(const LLSD& value, EAddPosition pos,
+ void* userdata)
+{
+ return NULL;
+}
+
+LLScrollListItem* LLListViewModel::addSimpleElement(const std::string& value, EAddPosition pos,
+ const LLSD& id)
+{
+ return NULL;
+}
+
+void LLListViewModel::clearRows()
+{
+}
+
+void LLListViewModel::sortByColumn(const std::string& name, bool ascending)
+{
+}
diff --git a/indra/llui/llviewmodel.h b/indra/llui/llviewmodel.h
new file mode 100644
index 0000000000..c8a9b52cca
--- /dev/null
+++ b/indra/llui/llviewmodel.h
@@ -0,0 +1,219 @@
+/**
+ * @file llviewmodel.h
+ * @author Nat Goodspeed
+ * @date 2008-08-08
+ * @brief Define "View Model" classes intended to store data values for use
+ * by LLUICtrl subclasses. The phrase is borrowed from Microsoft
+ * terminology, in which "View Model" means the storage object
+ * underlying a specific widget object -- as in our case -- rather
+ * than the business "model" object underlying the overall "view"
+ * presented by the collection of widgets.
+ *
+ * $LicenseInfo:firstyear=2008&license=viewergpl$
+ *
+ * Copyright (c) 2008-2009, Linden Research, Inc.
+ *
+ * Second Life Viewer Source Code
+ * The source code in this file ("Source Code") is provided by Linden Lab
+ * to you under the terms of the GNU General Public License, version 2.0
+ * ("GPL"), unless you have obtained a separate licensing agreement
+ * ("Other License"), formally executed by you and Linden Lab. Terms of
+ * the GPL can be found in doc/GPL-license.txt in this distribution, or
+ * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
+ *
+ * There are special exceptions to the terms and conditions of the GPL as
+ * it is applied to this Source Code. View the full text of the exception
+ * in the file doc/FLOSS-exception.txt in this software distribution, or
+ * online at
+ * http://secondlifegrid.net/programs/open_source/licensing/flossexception
+ *
+ * By copying, modifying or distributing this software, you acknowledge
+ * that you have read and understood your obligations described above,
+ * and agree to abide by those obligations.
+ *
+ * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+ * COMPLETENESS OR PERFORMANCE.
+ * $/LicenseInfo$
+ */
+
+#if ! defined(LL_LLVIEWMODEL_H)
+#define LL_LLVIEWMODEL_H
+
+#include "llpointer.h"
+#include "llsd.h"
+#include "llrefcount.h"
+#include "stdenums.h"
+#include "llstring.h"
+#include <string>
+
+class LLScrollListItem;
+
+class LLViewModel;
+class LLTextViewModel;
+class LLListViewModel;
+// Because LLViewModel is derived from LLRefCount, always pass, store
+// and return LLViewModelPtr rather than plain LLViewModel*.
+typedef LLPointer<LLViewModel> LLViewModelPtr;
+typedef LLPointer<LLTextViewModel> LLTextViewModelPtr;
+typedef LLPointer<LLListViewModel> LLListViewModelPtr;
+
+/**
+ * LLViewModel stores a scalar LLSD data item, the current display value of a
+ * scalar LLUICtrl widget. LLViewModel subclasses are used to store data
+ * collections used for aggregate widgets. LLViewModel is ref-counted because
+ * -- for multiple skins -- we may have distinct widgets sharing the same
+ * LLViewModel data. This way, the LLViewModel is quietly deleted when the
+ * last referencing widget is destroyed.
+ */
+class LLViewModel: public LLRefCount
+{
+public:
+ LLViewModel();
+ /// Instantiate an LLViewModel with an existing data value
+ LLViewModel(const LLSD& value);
+
+ /// Update the stored value
+ virtual void setValue(const LLSD& value);
+ /// Get the stored value, in appropriate type.
+ virtual LLSD getValue() const;
+
+ /// Has the value been changed since last time we checked?
+ bool isDirty() const { return mDirty; }
+ /// Once the value has been saved to a file, or otherwise consumed by the
+ /// app, we no longer need to enable the Save button
+ void resetDirty() { mDirty = false; }
+ //
+ void setDirty() { mDirty = true; }
+
+protected:
+ LLSD mValue;
+ bool mDirty;
+};
+
+/**
+ * LLTextViewModel stores a value displayed as text.
+ */
+class LLTextViewModel: public LLViewModel
+{
+public:
+ LLTextViewModel();
+ /// Instantiate an LLViewModel with an existing data value
+ LLTextViewModel(const LLSD& value);
+
+ // LLViewModel functions
+ virtual void setValue(const LLSD& value);
+ virtual LLSD getValue() const;
+
+ // New functions
+ /// Get the stored value in string form
+ LLWString getDisplay() const { return mDisplay; }
+ /**
+ * Set the display string directly (see LLTextEditor). What the user is
+ * editing is actually the LLWString value rather than the underlying
+ * UTF-8 value.
+ */
+ void setDisplay(const LLWString& value);
+
+private:
+ /// To avoid converting every widget's stored value from LLSD to LLWString
+ /// every frame, cache the converted value
+ LLWString mDisplay;
+ /// As the user edits individual characters (setDisplay()), defer
+ /// LLWString-to-UTF8 conversions until s/he's done.
+ bool mUpdateFromDisplay;
+};
+
+/**
+ * LLListViewModel stores a list of data items. The semantics are borrowed
+ * from LLScrollListCtrl.
+ */
+class LLListViewModel: public LLViewModel
+{
+public:
+ LLListViewModel() {}
+ LLListViewModel(const LLSD& values);
+
+ virtual void addColumn(const LLSD& column, EAddPosition pos = ADD_BOTTOM);
+ virtual void clearColumns();
+ virtual void setColumnLabel(const std::string& column, const std::string& label);
+ virtual LLScrollListItem* addElement(const LLSD& value, EAddPosition pos = ADD_BOTTOM,
+ void* userdata = NULL);
+ virtual LLScrollListItem* addSimpleElement(const std::string& value, EAddPosition pos,
+ const LLSD& id);
+ virtual void clearRows();
+ virtual void sortByColumn(const std::string& name, bool ascending);
+};
+
+//namespace LLViewModel
+//{
+// class Value
+// {
+// public:
+// Value(const LLSD& value = LLSD());
+//
+// LLSD getValue() const { return mValue; }
+// void setValue(const LLSD& value) { mValue = value; }
+//
+// bool isAvailable() const { return false; }
+// bool isReadOnly() const { return false; }
+//
+// bool undo() { return false; }
+// bool redo() { return false; }
+//
+// /// Has the value been changed since last time we checked?
+// bool isDirty() const { return mDirty; }
+// /// Once the value has been saved to a file, or otherwise consumed by the
+// /// app, we no longer need to enable the Save button
+// void resetDirty() { mDirty = false; }
+// //
+// void setDirty() { mDirty = true; }
+//
+// protected:
+// LLSD mValue;
+// bool mDirty;
+// };
+//
+// class Numeric : public Value
+// {
+// public:
+// Numeric(S32 value = 0);
+// Numeric(F32 value);
+//
+// F32 getPrecision();
+// F32 getMin();
+// F32 getMax();
+//
+// void increment();
+// void decrement();
+// };
+//
+// class MultipleValues : public Value
+// {
+// class Selector
+// {};
+//
+// MultipleValues();
+// virtual S32 numElements();
+// };
+//
+// class Tuple : public MultipleValues
+// {
+// Tuple(S32 size);
+// LLSD getValue(S32 which) const;
+// void setValue(S32 which, const LLSD& value);
+// };
+//
+// class List : public MultipleValues
+// {
+// List();
+//
+// void add(const ValueModel& value);
+// bool remove(const Selector& item);
+//
+// void setSortElement(const Selector& element);
+// void sort();
+// };
+//
+//};
+#endif /* ! defined(LL_LLVIEWMODEL_H) */
diff --git a/indra/llui/llviewquery.h b/indra/llui/llviewquery.h
index e87795f9a3..98d9bf8796 100644
--- a/indra/llui/llviewquery.h
+++ b/indra/llui/llviewquery.h
@@ -35,7 +35,7 @@
#include <list>
-#include "llmemory.h"
+#include "llsingleton.h"
#include "llui.h"
class LLView;
diff --git a/indra/llvfs/lldir.cpp b/indra/llvfs/lldir.cpp
index d6a6eca341..745e53c980 100644
--- a/indra/llvfs/lldir.cpp
+++ b/indra/llvfs/lldir.cpp
@@ -41,7 +41,9 @@
#endif
#include "lldir.h"
+
#include "llerror.h"
+#include "lltimer.h" // ms_sleep()
#include "lluuid.h"
#if LL_WINDOWS
@@ -125,16 +127,20 @@ S32 LLDir::deleteFilesInDir(const std::string &dirname, const std::string &mask)
}
const std::string LLDir::findFile(const std::string &filename,
- const std::string searchPath1,
- const std::string searchPath2,
- const std::string searchPath3) const
+ const std::string& searchPath1,
+ const std::string& searchPath2,
+ const std::string& searchPath3) const
{
std::vector<std::string> search_paths;
search_paths.push_back(searchPath1);
search_paths.push_back(searchPath2);
search_paths.push_back(searchPath3);
+ return findFile(filename, search_paths);
+}
- std::vector<std::string>::iterator search_path_iter;
+const std::string LLDir::findFile(const std::string& filename, const std::vector<std::string> search_paths) const
+{
+ std::vector<std::string>::const_iterator search_path_iter;
for (search_path_iter = search_paths.begin();
search_path_iter != search_paths.end();
++search_path_iter)
@@ -287,13 +293,13 @@ const std::string& LLDir::getDefaultSkinDir() const
const std::string LLDir::getSkinBaseDir() const
{
- std::string dir = getAppRODataDir();
- dir += mDirDelimiter;
- dir += "skins";
-
- return dir;
+ return mSkinBaseDir;
}
+const std::string &LLDir::getLLPluginDir() const
+{
+ return mLLPluginDir;
+}
std::string LLDir::getExpandedFilename(ELLPath location, const std::string& filename) const
{
@@ -319,19 +325,13 @@ std::string LLDir::getExpandedFilename(ELLPath location, const std::string& subd
prefix += mDirDelimiter;
prefix += "app_settings";
break;
-
+
case LL_PATH_CHARACTER:
prefix = getAppRODataDir();
prefix += mDirDelimiter;
prefix += "character";
break;
- case LL_PATH_MOTIONS:
- prefix = getAppRODataDir();
- prefix += mDirDelimiter;
- prefix += "motions";
- break;
-
case LL_PATH_HELP:
prefix = "help";
break;
@@ -372,17 +372,27 @@ std::string LLDir::getExpandedFilename(ELLPath location, const std::string& subd
prefix = getSkinDir();
break;
- case LL_PATH_SKINS:
- prefix = getAppRODataDir();
+ case LL_PATH_DEFAULT_SKIN:
+ prefix = getDefaultSkinDir();
+ break;
+
+ case LL_PATH_USER_SKIN:
+ prefix = getOSUserAppDir();
+ prefix += mDirDelimiter;
+ prefix += "user_settings";
prefix += mDirDelimiter;
prefix += "skins";
break;
- //case LL_PATH_HTML:
- // prefix = getSkinDir();
- // prefix += mDirDelimiter;
- // prefix += "html";
- // break;
+ case LL_PATH_SKINS:
+ prefix = getSkinBaseDir();
+ break;
+
+ case LL_PATH_LOCAL_ASSETS:
+ prefix = getAppRODataDir();
+ prefix += mDirDelimiter;
+ prefix += "local_assets";
+ break;
case LL_PATH_MOZILLA_PROFILE:
prefix = getOSUserAppDir();
@@ -465,6 +475,8 @@ std::string LLDir::getDirName(const std::string& filepath) const
std::string LLDir::getExtension(const std::string& filepath) const
{
+ if (filepath.empty())
+ return std::string();
std::string basename = getBaseFileName(filepath, false);
std::size_t offset = basename.find_last_of('.');
std::string exten = (offset == std::string::npos || offset == 0) ? "" : basename.substr(offset+1);
@@ -488,11 +500,14 @@ std::string LLDir::findSkinnedFilename(const std::string &subdir1, const std::st
std::string subdirs = ((subdir1.empty() ? "" : mDirDelimiter) + subdir1)
+ ((subdir2.empty() ? "" : mDirDelimiter) + subdir2);
- std::string found_file = findFile(filename,
- getUserSkinDir() + subdirs, // first look in user skin override
- getSkinDir() + subdirs, // then in current skin
- getDefaultSkinDir() + subdirs); // and last in default skin
+ std::vector<std::string> search_paths;
+
+ search_paths.push_back(getUserSkinDir() + subdirs); // first look in user skin override
+ search_paths.push_back(getSkinDir() + subdirs); // then in current skin
+ search_paths.push_back(getDefaultSkinDir() + subdirs); // then default skin
+ search_paths.push_back(getCacheDir() + subdirs); // and last in preload directory
+ std::string found_file = findFile(filename, search_paths);
return found_file;
}
@@ -597,9 +612,7 @@ void LLDir::setPerAccountChatLogsDir(const std::string &first, const std::string
void LLDir::setSkinFolder(const std::string &skin_folder)
{
- mSkinDir = getAppRODataDir();
- mSkinDir += mDirDelimiter;
- mSkinDir += "skins";
+ mSkinDir = getSkinBaseDir();
mSkinDir += mDirDelimiter;
mSkinDir += skin_folder;
@@ -613,9 +626,7 @@ void LLDir::setSkinFolder(const std::string &skin_folder)
// base skin which is used as fallback for all skinned files
// e.g. c:\program files\secondlife\skins\default
- mDefaultSkinDir = getAppRODataDir();
- mDefaultSkinDir += mDirDelimiter;
- mDefaultSkinDir += "skins";
+ mDefaultSkinDir = getSkinBaseDir();
mDefaultSkinDir += mDirDelimiter;
mDefaultSkinDir += "default";
}
@@ -660,6 +671,7 @@ void LLDir::dumpCurrentDirectories()
LL_DEBUGS2("AppInit","Directories") << " LindenUserDir: " << getLindenUserDir() << LL_ENDL;
LL_DEBUGS2("AppInit","Directories") << " TempDir: " << getTempDir() << LL_ENDL;
LL_DEBUGS2("AppInit","Directories") << " CAFile: " << getCAFile() << LL_ENDL;
+ LL_DEBUGS2("AppInit","Directories") << " SkinBaseDir: " << getSkinBaseDir() << LL_ENDL;
LL_DEBUGS2("AppInit","Directories") << " SkinDir: " << getSkinDir() << LL_ENDL;
#if LL_LIBXUL_ENABLED
diff --git a/indra/llvfs/lldir.h b/indra/llvfs/lldir.h
index 760b6512a5..6c9fea6b6a 100644
--- a/indra/llvfs/lldir.h
+++ b/indra/llvfs/lldir.h
@@ -47,17 +47,19 @@ typedef enum ELLPath
LL_PATH_PER_SL_ACCOUNT = 3,
LL_PATH_CACHE = 4,
LL_PATH_CHARACTER = 5,
- LL_PATH_MOTIONS = 6,
- LL_PATH_HELP = 7,
- LL_PATH_LOGS = 8,
- LL_PATH_TEMP = 9,
- LL_PATH_SKINS = 10,
- LL_PATH_TOP_SKIN = 11,
- LL_PATH_CHAT_LOGS = 12,
- LL_PATH_PER_ACCOUNT_CHAT_LOGS = 13,
- LL_PATH_MOZILLA_PROFILE = 14,
-// LL_PATH_HTML = 15,
+ LL_PATH_HELP = 6,
+ LL_PATH_LOGS = 7,
+ LL_PATH_TEMP = 8,
+ LL_PATH_SKINS = 9,
+ LL_PATH_TOP_SKIN = 10,
+ LL_PATH_CHAT_LOGS = 11,
+ LL_PATH_PER_ACCOUNT_CHAT_LOGS = 12,
+ LL_PATH_MOZILLA_PROFILE = 13,
+ LL_PATH_USER_SKIN = 14,
+ LL_PATH_LOCAL_ASSETS = 15,
+// LL_PATH_HTML = 16,
LL_PATH_EXECUTABLE = 16,
+ LL_PATH_DEFAULT_SKIN = 17,
LL_PATH_LAST
} ELLPath;
@@ -68,8 +70,13 @@ class LLDir
LLDir();
virtual ~LLDir();
- virtual void initAppDirs(const std::string &app_name) = 0;
- public:
+ // app_name - Usually SecondLife, used for creating settings directories
+ // in OS-specific location, such as C:\Documents and Settings
+ // app_read_only_data_dir - Usually the source code directory, used
+ // for test applications to read newview data files.
+ virtual void initAppDirs(const std::string &app_name,
+ const std::string& app_read_only_data_dir = "") = 0;
+
virtual S32 deleteFilesInDir(const std::string &dirname, const std::string &mask);
// pure virtual functions
@@ -79,7 +86,12 @@ class LLDir
virtual std::string getCurPath() = 0;
virtual BOOL fileExists(const std::string &filename) const = 0;
- const std::string findFile(const std::string &filename, const std::string searchPath1 = "", const std::string searchPath2 = "", const std::string searchPath3 = "") const;
+ const std::string findFile(const std::string& filename, const std::vector<std::string> filenames) const;
+ const std::string findFile(const std::string& filename, const std::string& searchPath1 = "", const std::string& searchPath2 = "", const std::string& searchPath3 = "") const;
+
+ virtual std::string getLLPluginLauncher() = 0; // full path and name for the plugin shell
+ virtual std::string getLLPluginFilename(std::string base_name) = 0; // full path and name to the plugin DSO for this base_name (i.e. 'FOO' -> '/bar/baz/libFOO.so')
+
const std::string &getExecutablePathAndName() const; // Full pathname of the executable
const std::string &getAppName() const; // install directory under progams/ ie "SecondLife"
const std::string &getExecutableDir() const; // Directory where the executable is located
@@ -100,6 +112,7 @@ class LLDir
const std::string &getUserSkinDir() const; // User-specified skin folder with user modifications. e.g. c:\documents and settings\username\application data\second life\skins\curskin
const std::string &getDefaultSkinDir() const; // folder for default skin. e.g. c:\program files\second life\skins\default
const std::string getSkinBaseDir() const; // folder that contains all installed skins (not user modifications). e.g. c:\program files\second life\skins
+ const std::string &getLLPluginDir() const; // Directory containing plugins and plugin shell
// Expanded filename
std::string getExpandedFilename(ELLPath location, const std::string &filename) const;
@@ -153,9 +166,11 @@ protected:
std::string mDefaultCacheDir; // default cache diretory
std::string mOSCacheDir; // operating system cache dir
std::string mDirDelimiter;
+ std::string mSkinBaseDir; // Base for skins paths.
std::string mSkinDir; // Location for current skin info.
std::string mDefaultSkinDir; // Location for default skin info.
std::string mUserSkinDir; // Location for user-modified skin info.
+ std::string mLLPluginDir; // Location for plugins and plugin shell
};
void dir_exists_or_crash(const std::string &dir_name);
diff --git a/indra/llvfs/lldir_linux.cpp b/indra/llvfs/lldir_linux.cpp
index 8ff8c5d1c6..24efcb8ae8 100644
--- a/indra/llvfs/lldir_linux.cpp
+++ b/indra/llvfs/lldir_linux.cpp
@@ -99,6 +99,7 @@ LLDir_Linux::LLDir_Linux()
#else
mAppRODataDir = tmp_str;
#endif
+ mSkinBaseDir = mAppRODataDir + mDirDelimiter + "skins";
mOSUserDir = getCurrentUserHome(tmp_str);
mOSUserAppDir = "";
mLindenUserDir = tmp_str;
@@ -128,6 +129,8 @@ LLDir_Linux::LLDir_Linux()
}
}
+ mLLPluginDir = mExecutableDir + mDirDelimiter + "llplugin";
+
// *TODO: don't use /tmp, use $HOME/.secondlife/tmp or something.
mTempDir = "/tmp";
}
@@ -139,8 +142,15 @@ LLDir_Linux::~LLDir_Linux()
// Implementation
-void LLDir_Linux::initAppDirs(const std::string &app_name)
+void LLDir_Linux::initAppDirs(const std::string &app_name,
+ const std::string& app_read_only_data_dir)
{
+ // Allow override so test apps can read newview directory
+ if (!app_read_only_data_dir.empty())
+ {
+ mAppRODataDir = app_read_only_data_dir;
+ mSkinBaseDir = mAppRODataDir + mDirDelimiter + "skins";
+ }
mAppName = app_name;
std::string upper_app_name(app_name);
@@ -370,3 +380,15 @@ BOOL LLDir_Linux::fileExists(const std::string &filename) const
}
}
+
+/*virtual*/ std::string LLDir_Linux::getLLPluginLauncher()
+{
+ return gDirUtilp->getLLPluginDir() + gDirUtilp->getDirDelimiter() +
+ "SLPlugin";
+}
+
+/*virtual*/ std::string LLDir_Linux::getLLPluginFilename(std::string base_name)
+{
+ return gDirUtilp->getLLPluginDir() + gDirUtilp->getDirDelimiter() +
+ "lib" + base_name + ".so";
+}
diff --git a/indra/llvfs/lldir_linux.h b/indra/llvfs/lldir_linux.h
index 20b408f8dc..1fec15c5c6 100644
--- a/indra/llvfs/lldir_linux.h
+++ b/indra/llvfs/lldir_linux.h
@@ -44,7 +44,8 @@ public:
LLDir_Linux();
virtual ~LLDir_Linux();
- virtual void initAppDirs(const std::string &app_name);
+ /*virtual*/ void initAppDirs(const std::string &app_name,
+ const std::string& app_read_only_data_dir);
public:
virtual std::string getCurPath();
virtual U32 countFilesInDir(const std::string &dirname, const std::string &mask);
@@ -52,6 +53,9 @@ public:
virtual void getRandomFileInDir(const std::string &dirname, const std::string &mask, std::string &fname);
/*virtual*/ BOOL fileExists(const std::string &filename) const;
+ /*virtual*/ std::string getLLPluginLauncher();
+ /*virtual*/ std::string getLLPluginFilename(std::string base_name);
+
private:
DIR *mDirp;
int mCurrentDirIndex;
diff --git a/indra/llvfs/lldir_mac.cpp b/indra/llvfs/lldir_mac.cpp
index d4dee5a02e..9be787df11 100644
--- a/indra/llvfs/lldir_mac.cpp
+++ b/indra/llvfs/lldir_mac.cpp
@@ -142,9 +142,34 @@ LLDir_Mac::LLDir_Mac()
CFURLRefToLLString(executableParentURLRef, mExecutableDir, true);
// mAppRODataDir
- CFURLRef resourcesURLRef = CFBundleCopyResourcesDirectoryURL(mainBundleRef);
+
+
+ // *NOTE: When running in a dev tree, use the copy of
+ // skins in indra/newview/ rather than in the application bundle. This
+ // mirrors Windows dev environment behavior and allows direct checkin
+ // of edited skins/xui files. JC
+
+ // MBW -- This keeps the mac application from finding other things.
+ // If this is really for skins, it should JUST apply to skins.
+
+ CFURLRef resourcesURLRef = CFBundleCopyResourcesDirectoryURL(mainBundleRef);
CFURLRefToLLString(resourcesURLRef, mAppRODataDir, true);
+ U32 indra_pos = mExecutableDir.find("/indra");
+ if (indra_pos != std::string::npos)
+ {
+ // ...we're in a dev checkout
+ mSkinBaseDir = mExecutableDir.substr(0, indra_pos)
+ + "/indra/newview/skins";
+ llinfos << "Running in dev checkout with mSkinBaseDir "
+ << mSkinBaseDir << llendl;
+ }
+ else
+ {
+ // ...normal installation running
+ mSkinBaseDir = mAppRODataDir + mDirDelimiter + "skins";
+ }
+
// mOSUserDir
error = FSFindFolder(kUserDomain, kApplicationSupportFolderType, true, &fileRef);
if (error == noErr)
@@ -190,6 +215,8 @@ LLDir_Mac::LLDir_Mac()
}
mWorkingDir = getCurPath();
+
+ mLLPluginDir = mAppRODataDir + mDirDelimiter + "llplugin";
CFRelease(executableURLRef);
executableURLRef = NULL;
@@ -203,8 +230,15 @@ LLDir_Mac::~LLDir_Mac()
// Implementation
-void LLDir_Mac::initAppDirs(const std::string &app_name)
+void LLDir_Mac::initAppDirs(const std::string &app_name,
+ const std::string& app_read_only_data_dir)
{
+ // Allow override so test apps can read newview directory
+ if (!app_read_only_data_dir.empty())
+ {
+ mAppRODataDir = app_read_only_data_dir;
+ mSkinBaseDir = mAppRODataDir + mDirDelimiter + "skins";
+ }
mCAFile = getExpandedFilename(LL_PATH_APP_SETTINGS, "CA.pem");
//dumpCurrentDirectories();
@@ -388,4 +422,17 @@ BOOL LLDir_Mac::fileExists(const std::string &filename) const
}
+/*virtual*/ std::string LLDir_Mac::getLLPluginLauncher()
+{
+ return gDirUtilp->getLLPluginDir() + gDirUtilp->getDirDelimiter() +
+ "SLPlugin";
+}
+
+/*virtual*/ std::string LLDir_Mac::getLLPluginFilename(std::string base_name)
+{
+ return gDirUtilp->getLLPluginDir() + gDirUtilp->getDirDelimiter() +
+ base_name + ".dylib";
+}
+
+
#endif // LL_DARWIN
diff --git a/indra/llvfs/lldir_mac.h b/indra/llvfs/lldir_mac.h
index 28d48a0b6a..834acc7262 100644
--- a/indra/llvfs/lldir_mac.h
+++ b/indra/llvfs/lldir_mac.h
@@ -43,7 +43,8 @@ public:
LLDir_Mac();
virtual ~LLDir_Mac();
- virtual void initAppDirs(const std::string &app_name);
+ /*virtual*/ void initAppDirs(const std::string &app_name,
+ const std::string& app_read_only_data_dir);
public:
virtual S32 deleteFilesInDir(const std::string &dirname, const std::string &mask);
virtual std::string getCurPath();
@@ -52,6 +53,9 @@ public:
virtual void getRandomFileInDir(const std::string &dirname, const std::string &ask, std::string &fname);
virtual BOOL fileExists(const std::string &filename) const;
+ /*virtual*/ std::string getLLPluginLauncher();
+ /*virtual*/ std::string getLLPluginFilename(std::string base_name);
+
private:
int mCurrentDirIndex;
int mCurrentDirCount;
diff --git a/indra/llvfs/lldir_solaris.cpp b/indra/llvfs/lldir_solaris.cpp
index 9553d923aa..a21f3ca0ab 100644
--- a/indra/llvfs/lldir_solaris.cpp
+++ b/indra/llvfs/lldir_solaris.cpp
@@ -161,6 +161,8 @@ LLDir_Solaris::LLDir_Solaris()
}
}
+ mLLPluginDir = mExecutableDir + mDirDelimiter + "llplugin";
+
// *TODO: don't use /tmp, use $HOME/.secondlife/tmp or something.
mTempDir = "/tmp";
}
@@ -172,8 +174,14 @@ LLDir_Solaris::~LLDir_Solaris()
// Implementation
-void LLDir_Solaris::initAppDirs(const std::string &app_name)
+void LLDir_Solaris::initAppDirs(const std::string &app_name,
+ const std::string& app_read_only_data_dir)
{
+ // Allow override so test apps can read newview directory
+ if (!app_read_only_data_dir.empty())
+ {
+ mAppRODataDir = app_read_only_data_dir;
+ }
mAppName = app_name;
std::string upper_app_name(app_name);
diff --git a/indra/llvfs/lldir_solaris.h b/indra/llvfs/lldir_solaris.h
index 139754ba28..1fa8348355 100644
--- a/indra/llvfs/lldir_solaris.h
+++ b/indra/llvfs/lldir_solaris.h
@@ -44,7 +44,8 @@ public:
LLDir_Solaris();
virtual ~LLDir_Solaris();
- virtual void initAppDirs(const std::string &app_name);
+ /*virtual*/ void initAppDirs(const std::string &app_name,
+ const std::string& app_read_only_data_dir);
public:
virtual std::string getCurPath();
virtual U32 countFilesInDir(const std::string &dirname, const std::string &mask);
diff --git a/indra/llvfs/lldir_win32.cpp b/indra/llvfs/lldir_win32.cpp
index 19b9bcc6ea..872f2cf1c1 100644
--- a/indra/llvfs/lldir_win32.cpp
+++ b/indra/llvfs/lldir_win32.cpp
@@ -130,6 +130,7 @@ LLDir_Win32::LLDir_Win32()
else
mAppRODataDir = mExecutableDir;
+ mSkinBaseDir = mAppRODataDir + mDirDelimiter + "skins";
// Build the default cache directory
mDefaultCacheDir = buildSLOSCacheDir();
@@ -143,6 +144,8 @@ LLDir_Win32::LLDir_Win32()
llwarns << "Couldn't create LL_PATH_CACHE dir " << mDefaultCacheDir << llendl;
}
}
+
+ mLLPluginDir = mExecutableDir + mDirDelimiter + "llplugin";
}
LLDir_Win32::~LLDir_Win32()
@@ -151,8 +154,15 @@ LLDir_Win32::~LLDir_Win32()
// Implementation
-void LLDir_Win32::initAppDirs(const std::string &app_name)
+void LLDir_Win32::initAppDirs(const std::string &app_name,
+ const std::string& app_read_only_data_dir)
{
+ // Allow override so test apps can read newview directory
+ if (!app_read_only_data_dir.empty())
+ {
+ mAppRODataDir = app_read_only_data_dir;
+ mSkinBaseDir = mAppRODataDir + mDirDelimiter + "skins";
+ }
mAppName = app_name;
mOSUserAppDir = mOSUserDir;
mOSUserAppDir += "\\";
@@ -205,7 +215,14 @@ void LLDir_Win32::initAppDirs(const std::string &app_name)
llwarns << "Couldn't create LL_PATH_MOZILLA_PROFILE dir " << getExpandedFilename(LL_PATH_MOZILLA_PROFILE,"") << llendl;
}
}
-
+ res = LLFile::mkdir(getExpandedFilename(LL_PATH_USER_SKIN,""));
+ if (res == -1)
+ {
+ if (errno != EEXIST)
+ {
+ llwarns << "Couldn't create LL_PATH_SKINS dir " << getExpandedFilename(LL_PATH_USER_SKIN,"") << llendl;
+ }
+ }
mCAFile = getExpandedFilename(LL_PATH_APP_SETTINGS, "CA.pem");
}
@@ -378,6 +395,19 @@ BOOL LLDir_Win32::fileExists(const std::string &filename) const
}
+/*virtual*/ std::string LLDir_Win32::getLLPluginLauncher()
+{
+ return gDirUtilp->getLLPluginDir() + gDirUtilp->getDirDelimiter() +
+ "SLPlugin.exe";
+}
+
+/*virtual*/ std::string LLDir_Win32::getLLPluginFilename(std::string base_name)
+{
+ return gDirUtilp->getLLPluginDir() + gDirUtilp->getDirDelimiter() +
+ base_name + ".dll";
+}
+
+
#if 0
// Utility function to get version number of a DLL
diff --git a/indra/llvfs/lldir_win32.h b/indra/llvfs/lldir_win32.h
index 8710ca50e1..c2acfa6bd4 100644
--- a/indra/llvfs/lldir_win32.h
+++ b/indra/llvfs/lldir_win32.h
@@ -41,7 +41,8 @@ public:
LLDir_Win32();
virtual ~LLDir_Win32();
- /*virtual*/ void initAppDirs(const std::string &app_name);
+ /*virtual*/ void initAppDirs(const std::string &app_name,
+ const std::string& app_read_only_data_dir);
/*virtual*/ std::string getCurPath();
/*virtual*/ U32 countFilesInDir(const std::string &dirname, const std::string &mask);
@@ -49,6 +50,9 @@ public:
/*virtual*/ void getRandomFileInDir(const std::string &dirname, const std::string &mask, std::string &fname);
/*virtual*/ BOOL fileExists(const std::string &filename) const;
+ /*virtual*/ std::string getLLPluginLauncher();
+ /*virtual*/ std::string getLLPluginFilename(std::string base_name);
+
private:
BOOL LLDir_Win32::getNextFileInDir(const llutf16string &dirname, const std::string &mask, std::string &fname, BOOL wrap);
diff --git a/indra/llvfs/lllfsthread.h b/indra/llvfs/lllfsthread.h
index 5a11cb33d7..3139693302 100644
--- a/indra/llvfs/lllfsthread.h
+++ b/indra/llvfs/lllfsthread.h
@@ -39,7 +39,7 @@
#include <set>
#include "llapr.h"
-
+#include "llpointer.h"
#include "llqueuedthread.h"
//============================================================================
diff --git a/indra/llvfs/llpidlock.cpp b/indra/llvfs/llpidlock.cpp
index 452594c7e7..315baa001d 100755
--- a/indra/llvfs/llpidlock.cpp
+++ b/indra/llvfs/llpidlock.cpp
@@ -5,7 +5,7 @@
*
* $LicenseInfo:firstyear=2007&license=viewergpl$
*
- * Copyright (c) 2007, Linden Research, Inc.
+ * Copyright (c) 2007-2009, Linden Research, Inc.
*
* Second Life Viewer Source Code
* The source code in this file ("Source Code") is provided by Linden Lab
@@ -13,12 +13,13 @@
* ("GPL"), unless you have obtained a separate licensing agreement
* ("Other License"), formally executed by you and Linden Lab. Terms of
* the GPL can be found in doc/GPL-license.txt in this distribution, or
- * online at http://secondlife.com/developers/opensource/gplv2
+ * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
*
* There are special exceptions to the terms and conditions of the GPL as
* it is applied to this Source Code. View the full text of the exception
* in the file doc/FLOSS-exception.txt in this software distribution, or
- * online at http://secondlife.com/developers/opensource/flossexception
+ * online at
+ * http://secondlifegrid.net/programs/open_source/licensing/flossexception
*
* By copying, modifying or distributing this software, you acknowledge
* that you have read and understood your obligations described above,
diff --git a/indra/llvfs/llpidlock.h b/indra/llvfs/llpidlock.h
index 44ed8caf46..42aee4dc4f 100755
--- a/indra/llvfs/llpidlock.h
+++ b/indra/llvfs/llpidlock.h
@@ -4,7 +4,7 @@
*
* $LicenseInfo:firstyear=2001&license=viewergpl$
*
- * Copyright (c) 2001-2007, Linden Research, Inc.
+ * Copyright (c) 2001-2009, Linden Research, Inc.
*
* Second Life Viewer Source Code
* The source code in this file ("Source Code") is provided by Linden Lab
@@ -12,12 +12,13 @@
* ("GPL"), unless you have obtained a separate licensing agreement
* ("Other License"), formally executed by you and Linden Lab. Terms of
* the GPL can be found in doc/GPL-license.txt in this distribution, or
- * online at http://secondlife.com/developers/opensource/gplv2
+ * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
*
* There are special exceptions to the terms and conditions of the GPL as
* it is applied to this Source Code. View the full text of the exception
* in the file doc/FLOSS-exception.txt in this software distribution, or
- * online at http://secondlife.com/developers/opensource/flossexception
+ * online at
+ * http://secondlifegrid.net/programs/open_source/licensing/flossexception
*
* By copying, modifying or distributing this software, you acknowledge
* that you have read and understood your obligations described above,
diff --git a/indra/llvfs/llvfile.cpp b/indra/llvfs/llvfile.cpp
index 6b1563bab1..5fdf41188d 100644
--- a/indra/llvfs/llvfile.cpp
+++ b/indra/llvfs/llvfile.cpp
@@ -44,6 +44,8 @@ const S32 LLVFile::WRITE = 0x00000002;
const S32 LLVFile::READ_WRITE = 0x00000003; // LLVFile::READ & LLVFile::WRITE
const S32 LLVFile::APPEND = 0x00000006; // 0x00000004 & LLVFile::WRITE
+static LLFastTimer::DeclareTimer FTM_VFILE_WAIT("VFile Wait");
+
//----------------------------------------------------------------------------
LLVFSThread* LLVFile::sVFSThread = NULL;
BOOL LLVFile::sAllocdVFSThread = FALSE;
@@ -318,7 +320,7 @@ BOOL LLVFile::setMaxSize(S32 size)
if (!mVFS->checkAvailable(size))
{
- LLFastTimer t(LLFastTimer::FTM_VFILE_WAIT);
+ LLFastTimer t(FTM_VFILE_WAIT);
S32 count = 0;
while (sVFSThread->getPending() > 1000)
{
@@ -426,7 +428,7 @@ bool LLVFile::isLocked(EVFSLock lock)
void LLVFile::waitForLock(EVFSLock lock)
{
- LLFastTimer t(LLFastTimer::FTM_VFILE_WAIT);
+ LLFastTimer t(FTM_VFILE_WAIT);
// spin until the lock clears
while (isLocked(lock))
{
diff --git a/indra/llvfs/llvfs.cpp b/indra/llvfs/llvfs.cpp
index ef8c4d6c7f..9ce1e75d06 100644
--- a/indra/llvfs/llvfs.cpp
+++ b/indra/llvfs/llvfs.cpp
@@ -46,7 +46,9 @@
#endif
#include "llvfs.h"
+
#include "llstl.h"
+#include "lltimer.h"
const S32 FILE_BLOCK_MASK = 0x000003FF; // 1024-byte blocks
const S32 VFS_CLEANUP_SIZE = 5242880; // how much space we free up in a single stroke
diff --git a/indra/llwindow/CMakeLists.txt b/indra/llwindow/CMakeLists.txt
index e1f7406287..7b1cab696f 100644
--- a/indra/llwindow/CMakeLists.txt
+++ b/indra/llwindow/CMakeLists.txt
@@ -19,7 +19,6 @@ include(LLRender)
include(LLVFS)
include(LLWindow)
include(LLXML)
-include(Mozlib)
include(UI)
include_directories(
@@ -35,13 +34,15 @@ include_directories(
set(llwindow_SOURCE_FILES
llkeyboard.cpp
llwindowheadless.cpp
+ llwindowcallbacks.cpp
)
-set(llwindows_HEADER_FILES
+set(llwindow_HEADER_FILES
CMakeLists.txt
llkeyboard.h
llwindowheadless.h
+ llwindowcallbacks.h
)
set(viewer_SOURCE_FILES
@@ -57,10 +58,12 @@ set(viewer_HEADER_FILES
# Libraries on which this library depends, needed for Linux builds
# Sort by high-level to low-level
-set(llwindow_LINK_LIBRARIES
- ${UI_LIBRARIES} # for GTK
- ${SDL_LIBRARY}
- )
+if (NOT LINUX OR VIEWER)
+ set(llwindow_LINK_LIBRARIES
+ ${UI_LIBRARIES} # for GTK
+ ${SDL_LIBRARY}
+ )
+endif (NOT LINUX OR VIEWER)
if (DARWIN)
list(APPEND llwindow_SOURCE_FILES
@@ -83,7 +86,7 @@ if (DARWIN)
)
endif (DARWIN)
-if (LINUX)
+if (LINUX AND VIEWER)
list(APPEND viewer_SOURCE_FILES
llkeyboardsdl.cpp
llwindowsdl.cpp
@@ -92,7 +95,7 @@ if (LINUX)
llkeyboardsdl.h
llwindowsdl.h
)
-endif (LINUX)
+endif (LINUX AND VIEWER)
if (WINDOWS)
list(APPEND llwindow_SOURCE_FILES
@@ -143,7 +146,7 @@ if (SERVER AND NOT WINDOWS AND NOT DARWIN)
${llwindow_SOURCE_FILES}
${server_SOURCE_FILES}
)
- # *TODO: This should probably have target_link_libraries
+ target_link_libraries (llwindowheadless ${llwindow_LINK_LIBRARIES})
endif (SERVER AND NOT WINDOWS AND NOT DARWIN)
if (llwindow_HEADER_FILES)
diff --git a/indra/llwindow/lldxhardware.cpp b/indra/llwindow/lldxhardware.cpp
index e0cb82d2be..d8058baf53 100644
--- a/indra/llwindow/lldxhardware.cpp
+++ b/indra/llwindow/lldxhardware.cpp
@@ -47,6 +47,7 @@
#include "llstring.h"
#include "llstl.h"
+#include "lltimer.h"
void (*gWriteDebug)(const char* msg) = NULL;
LLDXHardware gDXHardware;
diff --git a/indra/llwindow/llkeyboard.cpp b/indra/llwindow/llkeyboard.cpp
index 02b4ed17c2..f0f618aef1 100644
--- a/indra/llwindow/llkeyboard.cpp
+++ b/indra/llwindow/llkeyboard.cpp
@@ -34,7 +34,7 @@
#include "indra_constants.h"
#include "llkeyboard.h"
-#include "llwindow.h"
+#include "llwindowcallbacks.h"
//
diff --git a/indra/llwindow/llkeyboardmacosx.cpp b/indra/llwindow/llkeyboardmacosx.cpp
index ec82032161..f53773c393 100644
--- a/indra/llwindow/llkeyboardmacosx.cpp
+++ b/indra/llwindow/llkeyboardmacosx.cpp
@@ -34,7 +34,7 @@
#include "linden_common.h"
#include "llkeyboardmacosx.h"
-#include "llwindow.h"
+#include "llwindowcallbacks.h"
#include <Carbon/Carbon.h>
diff --git a/indra/llwindow/llkeyboardsdl.cpp b/indra/llwindow/llkeyboardsdl.cpp
index 8a6b6d6298..8a0b1de98c 100644
--- a/indra/llwindow/llkeyboardsdl.cpp
+++ b/indra/llwindow/llkeyboardsdl.cpp
@@ -34,7 +34,7 @@
#include "linden_common.h"
#include "llkeyboardsdl.h"
-#include "llwindow.h"
+#include "llwindowcallbacks.h"
#include "SDL/SDL.h"
LLKeyboardSDL::LLKeyboardSDL()
diff --git a/indra/llwindow/llkeyboardwin32.cpp b/indra/llwindow/llkeyboardwin32.cpp
index a06f19149c..ea11e0537e 100644
--- a/indra/llwindow/llkeyboardwin32.cpp
+++ b/indra/llwindow/llkeyboardwin32.cpp
@@ -34,14 +34,16 @@
#include "linden_common.h"
-#include "llkeyboardwin32.h"
-
-#include "llwindow.h"
-
#define WIN32_LEAN_AND_MEAN
#include <winsock2.h>
#include <windows.h>
+#include "llkeyboardwin32.h"
+
+#include "llwindowcallbacks.h"
+
+
+
LLKeyboardWin32::LLKeyboardWin32()
{
// Set up key mapping for windows - eventually can read this from a file?
diff --git a/indra/llwindow/llpreeditor.h b/indra/llwindow/llpreeditor.h
index 370f76cb85..dd63a98606 100644
--- a/indra/llwindow/llpreeditor.h
+++ b/indra/llwindow/llpreeditor.h
@@ -94,7 +94,7 @@ public:
// Get the contents of this preeditor as a LLWString. If there is an active preedit,
// the returned LLWString contains it.
- virtual const LLWString & getWText() const = 0;
+ virtual LLWString getWText() const = 0;
// Handle a UTF-32 char on this preeditor, i.e., add the character
// to the contents.
diff --git a/indra/llwindow/llwindow.cpp b/indra/llwindow/llwindow.cpp
index 7e412a14de..1c6c9e6e9d 100644
--- a/indra/llwindow/llwindow.cpp
+++ b/indra/llwindow/llwindow.cpp
@@ -46,14 +46,12 @@
#include "llerror.h"
#include "llkeyboard.h"
#include "linked_lists.h"
+#include "llwindowcallbacks.h"
-//static instance for default callbacks
-LLWindowCallbacks LLWindow::sDefaultCallbacks;
//
-// LLWindowCallbacks
+// Globals
//
-
LLSplashScreen *gSplashScreenp = NULL;
BOOL gDebugClicks = FALSE;
BOOL gDebugWindowProc = FALSE;
@@ -67,158 +65,6 @@ const std::string gURLProtocolWhitelist[] = { "file:", "http:", "https:" };
// Important - these lists should match - protocol to handler
const std::string gURLProtocolWhitelistHandler[] = { "http", "http", "https" };
-BOOL LLWindowCallbacks::handleTranslatedKeyDown(const KEY key, const MASK mask, BOOL repeated)
-{
- return FALSE;
-}
-
-
-BOOL LLWindowCallbacks::handleTranslatedKeyUp(const KEY key, const MASK mask)
-{
- return FALSE;
-}
-
-void LLWindowCallbacks::handleScanKey(KEY key, BOOL key_down, BOOL key_up, BOOL key_level)
-{
-}
-
-BOOL LLWindowCallbacks::handleUnicodeChar(llwchar uni_char, MASK mask)
-{
- return FALSE;
-}
-
-
-BOOL LLWindowCallbacks::handleMouseDown(LLWindow *window, const LLCoordGL pos, MASK mask)
-{
- return FALSE;
-}
-
-BOOL LLWindowCallbacks::handleMouseUp(LLWindow *window, const LLCoordGL pos, MASK mask)
-{
- return FALSE;
-}
-
-void LLWindowCallbacks::handleMouseLeave(LLWindow *window)
-{
- return;
-}
-
-BOOL LLWindowCallbacks::handleCloseRequest(LLWindow *window)
-{
- //allow the window to close
- return TRUE;
-}
-
-void LLWindowCallbacks::handleQuit(LLWindow *window)
-{
- if(LLWindowManager::destroyWindow(window) == FALSE)
- {
- llerrs << "LLWindowCallbacks::handleQuit() : Couldn't destroy window" << llendl;
- }
-}
-
-BOOL LLWindowCallbacks::handleRightMouseDown(LLWindow *window, const LLCoordGL pos, MASK mask)
-{
- return FALSE;
-}
-
-BOOL LLWindowCallbacks::handleRightMouseUp(LLWindow *window, const LLCoordGL pos, MASK mask)
-{
- return FALSE;
-}
-
-BOOL LLWindowCallbacks::handleMiddleMouseDown(LLWindow *window, const LLCoordGL pos, MASK mask)
-{
- return FALSE;
-}
-
-BOOL LLWindowCallbacks::handleMiddleMouseUp(LLWindow *window, const LLCoordGL pos, MASK mask)
-{
- return FALSE;
-}
-
-BOOL LLWindowCallbacks::handleActivate(LLWindow *window, BOOL activated)
-{
- return FALSE;
-}
-
-BOOL LLWindowCallbacks::handleActivateApp(LLWindow *window, BOOL activating)
-{
- return FALSE;
-}
-
-void LLWindowCallbacks::handleMouseMove(LLWindow *window, const LLCoordGL pos, MASK mask)
-{
-}
-
-void LLWindowCallbacks::handleScrollWheel(LLWindow *window, S32 clicks)
-{
-}
-
-void LLWindowCallbacks::handleResize(LLWindow *window, const S32 width, const S32 height)
-{
-}
-
-void LLWindowCallbacks::handleFocus(LLWindow *window)
-{
-}
-
-void LLWindowCallbacks::handleFocusLost(LLWindow *window)
-{
-}
-
-void LLWindowCallbacks::handleMenuSelect(LLWindow *window, const S32 menu_item)
-{
-}
-
-BOOL LLWindowCallbacks::handlePaint(LLWindow *window, const S32 x, const S32 y,
- const S32 width, const S32 height)
-{
- return FALSE;
-}
-
-BOOL LLWindowCallbacks::handleDoubleClick(LLWindow *window, const LLCoordGL pos, MASK mask)
-{
- return FALSE;
-}
-
-void LLWindowCallbacks::handleWindowBlock(LLWindow *window)
-{
-}
-
-void LLWindowCallbacks::handleWindowUnblock(LLWindow *window)
-{
-}
-
-void LLWindowCallbacks::handleDataCopy(LLWindow *window, S32 data_type, void *data)
-{
-}
-
-BOOL LLWindowCallbacks::handleTimerEvent(LLWindow *window)
-{
- return FALSE;
-}
-
-BOOL LLWindowCallbacks::handleDeviceChange(LLWindow *window)
-{
- return FALSE;
-}
-
-void LLWindowCallbacks::handlePingWatchdog(LLWindow *window, const char * msg)
-{
-
-}
-
-void LLWindowCallbacks::handlePauseWatchdog(LLWindow *window)
-{
-
-}
-
-void LLWindowCallbacks::handleResumeWatchdog(LLWindow *window)
-{
-
-}
-
S32 OSMessageBox(const std::string& text, const std::string& caption, U32 type)
{
@@ -257,8 +103,8 @@ S32 OSMessageBox(const std::string& text, const std::string& caption, U32 type)
// LLWindow
//
-LLWindow::LLWindow(BOOL fullscreen, U32 flags)
- : mCallbacks(&sDefaultCallbacks),
+LLWindow::LLWindow(LLWindowCallbacks* callbacks, BOOL fullscreen, U32 flags)
+ : mCallbacks(callbacks),
mPostQuit(TRUE),
mFullscreen(fullscreen),
mFullscreenWidth(0),
@@ -275,9 +121,23 @@ LLWindow::LLWindow(BOOL fullscreen, U32 flags)
mHideCursorPermanent(FALSE),
mFlags(flags),
mHighSurrogate(0)
+{ }
+
+LLWindow::~LLWindow()
+{ }
+
+//virtual
+BOOL LLWindow::isValid()
{
+ return TRUE;
}
-
+
+//virtual
+BOOL LLWindow::canDelete()
+{
+ return TRUE;
+}
+
// virtual
void LLWindow::incBusyCount()
{
@@ -293,13 +153,28 @@ void LLWindow::decBusyCount()
}
}
-void LLWindow::setCallbacks(LLWindowCallbacks *callbacks)
+//virtual
+void LLWindow::resetBusyCount()
{
- mCallbacks = callbacks;
- if (gKeyboard)
- {
- gKeyboard->setCallbacks(callbacks);
- }
+ mBusyCount = 0;
+}
+
+//virtual
+S32 LLWindow::getBusyCount() const
+{
+ return mBusyCount;
+}
+
+//virtual
+ECursorType LLWindow::getCursor() const
+{
+ return mCurrentCursor;
+}
+
+//virtual
+BOOL LLWindow::dialogColorPicker(F32 *r, F32 *g, F32 *b)
+{
+ return FALSE;
}
void *LLWindow::getMediaWindow()
@@ -462,23 +337,7 @@ void LLSplashScreen::hide()
static std::set<LLWindow*> sWindowList;
LLWindow* LLWindowManager::createWindow(
- const std::string& title,
- const std::string& name,
- LLCoordScreen upper_left,
- LLCoordScreen size,
- U32 flags,
- BOOL fullscreen,
- BOOL clearBg,
- BOOL disable_vsync,
- BOOL use_gl,
- BOOL ignore_pixel_depth)
-{
- return createWindow(
- title, name, upper_left.mX, upper_left.mY, size.mX, size.mY, flags,
- fullscreen, clearBg, disable_vsync, use_gl, ignore_pixel_depth);
-}
-
-LLWindow* LLWindowManager::createWindow(
+ LLWindowCallbacks* callbacks,
const std::string& title, const std::string& name, S32 x, S32 y, S32 width, S32 height, U32 flags,
BOOL fullscreen,
BOOL clearBg,
@@ -492,26 +351,26 @@ LLWindow* LLWindowManager::createWindow(
if (use_gl)
{
#if LL_MESA_HEADLESS
- new_window = new LLWindowMesaHeadless(
+ new_window = new LLWindowMesaHeadless(callbacks,
title, name, x, y, width, height, flags,
fullscreen, clearBg, disable_vsync, use_gl, ignore_pixel_depth);
#elif LL_SDL
- new_window = new LLWindowSDL(
+ new_window = new LLWindowSDL(callbacks,
title, x, y, width, height, flags,
fullscreen, clearBg, disable_vsync, use_gl, ignore_pixel_depth, fsaa_samples);
#elif LL_WINDOWS
- new_window = new LLWindowWin32(
+ new_window = new LLWindowWin32(callbacks,
title, name, x, y, width, height, flags,
fullscreen, clearBg, disable_vsync, use_gl, ignore_pixel_depth, fsaa_samples);
#elif LL_DARWIN
- new_window = new LLWindowMacOSX(
+ new_window = new LLWindowMacOSX(callbacks,
title, name, x, y, width, height, flags,
fullscreen, clearBg, disable_vsync, use_gl, ignore_pixel_depth, fsaa_samples);
#endif
}
else
{
- new_window = new LLWindowHeadless(
+ new_window = new LLWindowHeadless(callbacks,
title, name, x, y, width, height, flags,
fullscreen, clearBg, disable_vsync, use_gl, ignore_pixel_depth);
}
diff --git a/indra/llwindow/llwindow.h b/indra/llwindow/llwindow.h
index 8361771b66..8602225108 100644
--- a/indra/llwindow/llwindow.h
+++ b/indra/llwindow/llwindow.h
@@ -39,52 +39,8 @@
#include "llcursortypes.h"
class LLSplashScreen;
-
-class LLWindow;
-
class LLPreeditor;
-
-class LLWindowCallbacks
-{
-public:
- virtual ~LLWindowCallbacks() {}
- virtual BOOL handleTranslatedKeyDown(KEY key, MASK mask, BOOL repeated);
- virtual BOOL handleTranslatedKeyUp(KEY key, MASK mask);
- virtual void handleScanKey(KEY key, BOOL key_down, BOOL key_up, BOOL key_level);
- virtual BOOL handleUnicodeChar(llwchar uni_char, MASK mask);
-
- virtual BOOL handleMouseDown(LLWindow *window, LLCoordGL pos, MASK mask);
- virtual BOOL handleMouseUp(LLWindow *window, LLCoordGL pos, MASK mask);
- virtual void handleMouseLeave(LLWindow *window);
- // return TRUE to allow window to close, which will then cause handleQuit to be called
- virtual BOOL handleCloseRequest(LLWindow *window);
- // window is about to be destroyed, clean up your business
- virtual void handleQuit(LLWindow *window);
- virtual BOOL handleRightMouseDown(LLWindow *window, LLCoordGL pos, MASK mask);
- virtual BOOL handleRightMouseUp(LLWindow *window, LLCoordGL pos, MASK mask);
- virtual BOOL handleMiddleMouseDown(LLWindow *window, LLCoordGL pos, MASK mask);
- virtual BOOL handleMiddleMouseUp(LLWindow *window, LLCoordGL pos, MASK mask);
- virtual BOOL handleActivate(LLWindow *window, BOOL activated);
- virtual BOOL handleActivateApp(LLWindow *window, BOOL activating);
- virtual void handleMouseMove(LLWindow *window, LLCoordGL pos, MASK mask);
- virtual void handleScrollWheel(LLWindow *window, S32 clicks);
- virtual void handleResize(LLWindow *window, S32 width, S32 height);
- virtual void handleFocus(LLWindow *window);
- virtual void handleFocusLost(LLWindow *window);
- virtual void handleMenuSelect(LLWindow *window, S32 menu_item);
- virtual BOOL handlePaint(LLWindow *window, S32 x, S32 y, S32 width, S32 height);
- virtual BOOL handleDoubleClick(LLWindow *window, LLCoordGL pos, MASK mask); // double-click of left mouse button
- virtual void handleWindowBlock(LLWindow *window); // window is taking over CPU for a while
- virtual void handleWindowUnblock(LLWindow *window); // window coming back after taking over CPU for a while
- virtual void handleDataCopy(LLWindow *window, S32 data_type, void *data);
- virtual BOOL handleTimerEvent(LLWindow *window);
- virtual BOOL handleDeviceChange(LLWindow *window);
-
- virtual void handlePingWatchdog(LLWindow *window, const char * msg);
- virtual void handlePauseWatchdog(LLWindow *window);
- virtual void handleResumeWatchdog(LLWindow *window);
-
-};
+class LLWindowCallbacks;
// Refer to llwindow_test in test/common/llwindow for usage example
@@ -134,12 +90,12 @@ public:
// arrow/hour if busycount > 0.
virtual void incBusyCount();
virtual void decBusyCount();
- virtual void resetBusyCount() { mBusyCount = 0; }
- virtual S32 getBusyCount() const { return mBusyCount; }
+ virtual void resetBusyCount();
+ virtual S32 getBusyCount() const;
// Sets cursor, may set to arrow+hourglass
virtual void setCursor(ECursorType cursor) = 0;
- virtual ECursorType getCursor() const { return mCurrentCursor; }
+ virtual ECursorType getCursor() const;
virtual void captureMouse() = 0;
virtual void releaseMouse() = 0;
@@ -183,13 +139,12 @@ public:
virtual F32 getPixelAspectRatio() = 0;
virtual void setNativeAspectRatio(F32 aspect) = 0;
- void setCallbacks(LLWindowCallbacks *callbacks);
-
virtual void beforeDialog() {}; // prepare to put up an OS dialog (if special measures are required, such as in fullscreen mode)
virtual void afterDialog() {}; // undo whatever was done in beforeDialog()
-// opens system default color picker
- virtual BOOL dialog_color_picker (F32 *r, F32 *g, F32 *b) { return FALSE; };
+ // opens system default color picker, modally
+ // Returns TRUE if valid color selected
+ virtual BOOL dialogColorPicker(F32 *r, F32 *g, F32 *b);
// return a platform-specific window reference (HWND on Windows, WindowRef on the Mac, Gtk window on Linux)
virtual void *getPlatformWindow() = 0;
@@ -207,12 +162,12 @@ public:
static std::vector<std::string> getDynamicFallbackFontList();
protected:
- LLWindow(BOOL fullscreen, U32 flags);
- virtual ~LLWindow() {}
- virtual BOOL isValid() {return TRUE;}
- virtual BOOL canDelete() {return TRUE;}
-protected:
- static LLWindowCallbacks sDefaultCallbacks;
+ LLWindow(LLWindowCallbacks* callbacks, BOOL fullscreen, U32 flags);
+ virtual ~LLWindow();
+ // Defaults to true
+ virtual BOOL isValid();
+ // Defaults to true
+ virtual BOOL canDelete();
protected:
LLWindowCallbacks* mCallbacks;
@@ -294,18 +249,8 @@ const S32 OSBTN_CANCEL = 3;
class LLWindowManager
{
public:
- static LLWindow* createWindow(
- const std::string& title,
- const std::string& name,
- LLCoordScreen upper_left = LLCoordScreen(10, 10),
- LLCoordScreen size = LLCoordScreen(320, 240),
- U32 flags = 0,
- BOOL fullscreen = FALSE,
- BOOL clearBg = FALSE,
- BOOL disable_vsync = TRUE,
- BOOL use_gl = TRUE,
- BOOL ignore_pixel_depth = FALSE);
static LLWindow *createWindow(
+ LLWindowCallbacks* callbacks,
const std::string& title, const std::string& name, S32 x, S32 y, S32 width, S32 height,
U32 flags = 0,
BOOL fullscreen = FALSE,
diff --git a/indra/llwindow/llwindowcallbacks.cpp b/indra/llwindow/llwindowcallbacks.cpp
new file mode 100644
index 0000000000..72f9997149
--- /dev/null
+++ b/indra/llwindow/llwindowcallbacks.cpp
@@ -0,0 +1,201 @@
+/**
+ * @file llwindowcallbacks.cpp
+ * @brief OS event callback class
+ *
+ * $LicenseInfo:firstyear=2001&license=viewergpl$
+ *
+ * Copyright (c) 2001-2009, Linden Research, Inc.
+ *
+ * Second Life Viewer Source Code
+ * The source code in this file ("Source Code") is provided by Linden Lab
+ * to you under the terms of the GNU General Public License, version 2.0
+ * ("GPL"), unless you have obtained a separate licensing agreement
+ * ("Other License"), formally executed by you and Linden Lab. Terms of
+ * the GPL can be found in doc/GPL-license.txt in this distribution, or
+ * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
+ *
+ * There are special exceptions to the terms and conditions of the GPL as
+ * it is applied to this Source Code. View the full text of the exception
+ * in the file doc/FLOSS-exception.txt in this software distribution, or
+ * online at
+ * http://secondlifegrid.net/programs/open_source/licensing/flossexception
+ *
+ * By copying, modifying or distributing this software, you acknowledge
+ * that you have read and understood your obligations described above,
+ * and agree to abide by those obligations.
+ *
+ * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+ * COMPLETENESS OR PERFORMANCE.
+ * $/LicenseInfo$
+ */
+
+#include "linden_common.h"
+
+#include "llwindowcallbacks.h"
+
+#include "llcoord.h"
+
+//
+// LLWindowCallbacks
+//
+
+BOOL LLWindowCallbacks::handleTranslatedKeyDown(const KEY key, const MASK mask, BOOL repeated)
+{
+ return FALSE;
+}
+
+
+BOOL LLWindowCallbacks::handleTranslatedKeyUp(const KEY key, const MASK mask)
+{
+ return FALSE;
+}
+
+void LLWindowCallbacks::handleScanKey(KEY key, BOOL key_down, BOOL key_up, BOOL key_level)
+{
+}
+
+BOOL LLWindowCallbacks::handleUnicodeChar(llwchar uni_char, MASK mask)
+{
+ return FALSE;
+}
+
+
+BOOL LLWindowCallbacks::handleMouseDown(LLWindow *window, const LLCoordGL pos, MASK mask)
+{
+ return FALSE;
+}
+
+BOOL LLWindowCallbacks::handleMouseUp(LLWindow *window, const LLCoordGL pos, MASK mask)
+{
+ return FALSE;
+}
+
+void LLWindowCallbacks::handleMouseLeave(LLWindow *window)
+{
+ return;
+}
+
+BOOL LLWindowCallbacks::handleCloseRequest(LLWindow *window)
+{
+ //allow the window to close
+ return TRUE;
+}
+
+void LLWindowCallbacks::handleQuit(LLWindow *window)
+{
+}
+
+BOOL LLWindowCallbacks::handleRightMouseDown(LLWindow *window, const LLCoordGL pos, MASK mask)
+{
+ return FALSE;
+}
+
+BOOL LLWindowCallbacks::handleRightMouseUp(LLWindow *window, const LLCoordGL pos, MASK mask)
+{
+ return FALSE;
+}
+
+BOOL LLWindowCallbacks::handleMiddleMouseDown(LLWindow *window, const LLCoordGL pos, MASK mask)
+{
+ return FALSE;
+}
+
+BOOL LLWindowCallbacks::handleMiddleMouseUp(LLWindow *window, const LLCoordGL pos, MASK mask)
+{
+ return FALSE;
+}
+
+BOOL LLWindowCallbacks::handleActivate(LLWindow *window, BOOL activated)
+{
+ return FALSE;
+}
+
+BOOL LLWindowCallbacks::handleActivateApp(LLWindow *window, BOOL activating)
+{
+ return FALSE;
+}
+
+void LLWindowCallbacks::handleMouseMove(LLWindow *window, const LLCoordGL pos, MASK mask)
+{
+}
+
+void LLWindowCallbacks::handleScrollWheel(LLWindow *window, S32 clicks)
+{
+}
+
+void LLWindowCallbacks::handleResize(LLWindow *window, const S32 width, const S32 height)
+{
+}
+
+void LLWindowCallbacks::handleFocus(LLWindow *window)
+{
+}
+
+void LLWindowCallbacks::handleFocusLost(LLWindow *window)
+{
+}
+
+void LLWindowCallbacks::handleMenuSelect(LLWindow *window, const S32 menu_item)
+{
+}
+
+BOOL LLWindowCallbacks::handlePaint(LLWindow *window, const S32 x, const S32 y,
+ const S32 width, const S32 height)
+{
+ return FALSE;
+}
+
+BOOL LLWindowCallbacks::handleDoubleClick(LLWindow *window, const LLCoordGL pos, MASK mask)
+{
+ return FALSE;
+}
+
+void LLWindowCallbacks::handleWindowBlock(LLWindow *window)
+{
+}
+
+void LLWindowCallbacks::handleWindowUnblock(LLWindow *window)
+{
+}
+
+void LLWindowCallbacks::handleDataCopy(LLWindow *window, S32 data_type, void *data)
+{
+}
+
+BOOL LLWindowCallbacks::handleTimerEvent(LLWindow *window)
+{
+ return FALSE;
+}
+
+BOOL LLWindowCallbacks::handleDeviceChange(LLWindow *window)
+{
+ return FALSE;
+}
+
+void LLWindowCallbacks::handlePingWatchdog(LLWindow *window, const char * msg)
+{
+
+}
+
+void LLWindowCallbacks::handlePauseWatchdog(LLWindow *window)
+{
+
+}
+
+void LLWindowCallbacks::handleResumeWatchdog(LLWindow *window)
+{
+
+}
+
+std::string LLWindowCallbacks::translateString(const char* tag)
+{
+ return std::string();
+}
+
+//virtual
+std::string LLWindowCallbacks::translateString(const char* tag,
+ const std::map<std::string, std::string>& args)
+{
+ return std::string();
+}
diff --git a/indra/llwindow/llwindowcallbacks.h b/indra/llwindow/llwindowcallbacks.h
new file mode 100644
index 0000000000..abc66c42a2
--- /dev/null
+++ b/indra/llwindow/llwindowcallbacks.h
@@ -0,0 +1,85 @@
+/**
+ * @file llwindowcallbacks.h
+ * @brief OS event callback class
+ *
+ * $LicenseInfo:firstyear=2001&license=viewergpl$
+ *
+ * Copyright (c) 2001-2009, Linden Research, Inc.
+ *
+ * Second Life Viewer Source Code
+ * The source code in this file ("Source Code") is provided by Linden Lab
+ * to you under the terms of the GNU General Public License, version 2.0
+ * ("GPL"), unless you have obtained a separate licensing agreement
+ * ("Other License"), formally executed by you and Linden Lab. Terms of
+ * the GPL can be found in doc/GPL-license.txt in this distribution, or
+ * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
+ *
+ * There are special exceptions to the terms and conditions of the GPL as
+ * it is applied to this Source Code. View the full text of the exception
+ * in the file doc/FLOSS-exception.txt in this software distribution, or
+ * online at
+ * http://secondlifegrid.net/programs/open_source/licensing/flossexception
+ *
+ * By copying, modifying or distributing this software, you acknowledge
+ * that you have read and understood your obligations described above,
+ * and agree to abide by those obligations.
+ *
+ * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+ * COMPLETENESS OR PERFORMANCE.
+ * $/LicenseInfo$
+ */
+#ifndef LLWINDOWCALLBACKS_H
+#define LLWINDOWCALLBACKS_H
+
+class LLCoordGL;
+class LLWindow;
+
+class LLWindowCallbacks
+{
+public:
+ virtual ~LLWindowCallbacks() {}
+ virtual BOOL handleTranslatedKeyDown(KEY key, MASK mask, BOOL repeated);
+ virtual BOOL handleTranslatedKeyUp(KEY key, MASK mask);
+ virtual void handleScanKey(KEY key, BOOL key_down, BOOL key_up, BOOL key_level);
+ virtual BOOL handleUnicodeChar(llwchar uni_char, MASK mask);
+
+ virtual BOOL handleMouseDown(LLWindow *window, LLCoordGL pos, MASK mask);
+ virtual BOOL handleMouseUp(LLWindow *window, LLCoordGL pos, MASK mask);
+ virtual void handleMouseLeave(LLWindow *window);
+ // return TRUE to allow window to close, which will then cause handleQuit to be called
+ virtual BOOL handleCloseRequest(LLWindow *window);
+ // window is about to be destroyed, clean up your business
+ virtual void handleQuit(LLWindow *window);
+ virtual BOOL handleRightMouseDown(LLWindow *window, LLCoordGL pos, MASK mask);
+ virtual BOOL handleRightMouseUp(LLWindow *window, LLCoordGL pos, MASK mask);
+ virtual BOOL handleMiddleMouseDown(LLWindow *window, LLCoordGL pos, MASK mask);
+ virtual BOOL handleMiddleMouseUp(LLWindow *window, LLCoordGL pos, MASK mask);
+ virtual BOOL handleActivate(LLWindow *window, BOOL activated);
+ virtual BOOL handleActivateApp(LLWindow *window, BOOL activating);
+ virtual void handleMouseMove(LLWindow *window, LLCoordGL pos, MASK mask);
+ virtual void handleScrollWheel(LLWindow *window, S32 clicks);
+ virtual void handleResize(LLWindow *window, S32 width, S32 height);
+ virtual void handleFocus(LLWindow *window);
+ virtual void handleFocusLost(LLWindow *window);
+ virtual void handleMenuSelect(LLWindow *window, S32 menu_item);
+ virtual BOOL handlePaint(LLWindow *window, S32 x, S32 y, S32 width, S32 height);
+ virtual BOOL handleDoubleClick(LLWindow *window, LLCoordGL pos, MASK mask); // double-click of left mouse button
+ virtual void handleWindowBlock(LLWindow *window); // window is taking over CPU for a while
+ virtual void handleWindowUnblock(LLWindow *window); // window coming back after taking over CPU for a while
+ virtual void handleDataCopy(LLWindow *window, S32 data_type, void *data);
+ virtual BOOL handleTimerEvent(LLWindow *window);
+ virtual BOOL handleDeviceChange(LLWindow *window);
+
+ virtual void handlePingWatchdog(LLWindow *window, const char * msg);
+ virtual void handlePauseWatchdog(LLWindow *window);
+ virtual void handleResumeWatchdog(LLWindow *window);
+
+ // Look up a localized string, usually for an error message
+ virtual std::string translateString(const char* tag);
+ virtual std::string translateString(const char* tag,
+ const std::map<std::string, std::string>& args);
+};
+
+
+#endif
diff --git a/indra/llwindow/llwindowheadless.cpp b/indra/llwindow/llwindowheadless.cpp
index 3742846440..b4e9009321 100644
--- a/indra/llwindow/llwindowheadless.cpp
+++ b/indra/llwindow/llwindowheadless.cpp
@@ -38,10 +38,10 @@
//
// LLWindowHeadless
//
-LLWindowHeadless::LLWindowHeadless(const std::string& title, const std::string& name, S32 x, S32 y, S32 width, S32 height,
- U32 flags, BOOL fullscreen, BOOL clearBg,
+LLWindowHeadless::LLWindowHeadless(LLWindowCallbacks* callbacks, const std::string& title, const std::string& name, S32 x, S32 y, S32 width, S32 height,
+ U32 flags, BOOL fullscreen, BOOL clear_background,
BOOL disable_vsync, BOOL use_gl, BOOL ignore_pixel_depth)
- : LLWindow(fullscreen, flags)
+ : LLWindow(callbacks, fullscreen, flags)
{
}
diff --git a/indra/llwindow/llwindowheadless.h b/indra/llwindow/llwindowheadless.h
index 4353d157b5..3cffd2bbf6 100644
--- a/indra/llwindow/llwindowheadless.h
+++ b/indra/llwindow/llwindowheadless.h
@@ -94,9 +94,12 @@ public:
/*virtual*/ void *getPlatformWindow() { return 0; };
/*virtual*/ void bringToFront() {};
- LLWindowHeadless(const std::string& title, const std::string& name, S32 x, S32 y, S32 width, S32 height,
- U32 flags, BOOL fullscreen, BOOL clearBg,
- BOOL disable_vsync, BOOL use_gl, BOOL ignore_pixel_depth);
+ LLWindowHeadless(LLWindowCallbacks* callbacks,
+ const std::string& title, const std::string& name,
+ S32 x, S32 y,
+ S32 width, S32 height,
+ U32 flags, BOOL fullscreen, BOOL clear_background,
+ BOOL disable_vsync, BOOL use_gl, BOOL ignore_pixel_depth);
virtual ~LLWindowHeadless();
private:
diff --git a/indra/llwindow/llwindowmacosx.cpp b/indra/llwindow/llwindowmacosx.cpp
index 65a40dcef4..82dc5e4a13 100644
--- a/indra/llwindow/llwindowmacosx.cpp
+++ b/indra/llwindow/llwindowmacosx.cpp
@@ -32,19 +32,21 @@
#include "linden_common.h"
-#include <Carbon/Carbon.h>
-#include <OpenGL/OpenGL.h>
-
#include "llwindowmacosx.h"
+
#include "llkeyboardmacosx.h"
+#include "llwindowcallbacks.h"
+#include "llwindowmacosx-objc.h"
+#include "llpreeditor.h"
+
#include "llerror.h"
#include "llgl.h"
#include "llstring.h"
#include "lldir.h"
#include "indra_constants.h"
-#include "llwindowmacosx-objc.h"
-#include "llpreeditor.h"
+#include <Carbon/Carbon.h>
+#include <OpenGL/OpenGL.h>
extern BOOL gDebugWindowProc;
@@ -214,19 +216,27 @@ static LLWindowMacOSX *gWindowImplementation = NULL;
-LLWindowMacOSX::LLWindowMacOSX(const std::string& title, const std::string& name, S32 x, S32 y, S32 width,
+LLWindowMacOSX::LLWindowMacOSX(LLWindowCallbacks* callbacks,
+ const std::string& title, const std::string& name, S32 x, S32 y, S32 width,
S32 height, U32 flags,
BOOL fullscreen, BOOL clearBg,
BOOL disable_vsync, BOOL use_gl,
BOOL ignore_pixel_depth,
U32 fsaa_samples)
- : LLWindow(fullscreen, flags)
+ : LLWindow(NULL, fullscreen, flags)
{
+ // *HACK: During window construction we get lots of OS events for window
+ // reshape, activate, etc. that the viewer isn't ready to handle.
+ // Route them to a dummy callback structure until the end of constructor.
+ LLWindowCallbacks null_callbacks;
+ mCallbacks = &null_callbacks;
+
// Voodoo for calling cocoa from carbon (see llwindowmacosx-objc.mm).
setupCocoa();
// Initialize the keyboard
gKeyboard = new LLKeyboardMacOSX();
+ gKeyboard->setCallbacks(callbacks);
// Ignore use_gl for now, only used for drones on PC
mWindow = NULL;
@@ -315,6 +325,7 @@ LLWindowMacOSX::LLWindowMacOSX(const std::string& title, const std::string& name
setCursor( UI_CURSOR_ARROW );
}
+ mCallbacks = callbacks;
stop_glerror();
}
@@ -3202,7 +3213,7 @@ void LLWindowMacOSX::spawnWebBrowser(const std::string& escaped_url)
}
-BOOL LLWindowMacOSX::dialog_color_picker ( F32 *r, F32 *g, F32 *b)
+BOOL LLWindowMacOSX::dialogColorPicker( F32 *r, F32 *g, F32 *b)
{
BOOL retval = FALSE;
OSErr error = noErr;
diff --git a/indra/llwindow/llwindowmacosx.h b/indra/llwindow/llwindowmacosx.h
index 3886782732..17074080eb 100644
--- a/indra/llwindow/llwindowmacosx.h
+++ b/indra/llwindow/llwindowmacosx.h
@@ -35,6 +35,8 @@
#include "llwindow.h"
+#include "lltimer.h"
+
#include <Carbon/Carbon.h>
#include <AGL/agl.h>
@@ -103,7 +105,7 @@ public:
/*virtual*/ void beforeDialog();
/*virtual*/ void afterDialog();
- /*virtual*/ BOOL dialog_color_picker(F32 *r, F32 *g, F32 *b);
+ /*virtual*/ BOOL dialogColorPicker(F32 *r, F32 *g, F32 *b);
/*virtual*/ void *getPlatformWindow();
/*virtual*/ void *getMediaWindow();
@@ -116,7 +118,7 @@ public:
static std::vector<std::string> getDynamicFallbackFontList();
protected:
- LLWindowMacOSX(
+ LLWindowMacOSX(LLWindowCallbacks* callbacks,
const std::string& title, const std::string& name, int x, int y, int width, int height, U32 flags,
BOOL fullscreen, BOOL clearBg, BOOL disable_vsync, BOOL use_gl,
BOOL ignore_pixel_depth,
diff --git a/indra/llwindow/llwindowmesaheadless.cpp b/indra/llwindow/llwindowmesaheadless.cpp
index c1f9d2095e..7ee09f4a24 100644
--- a/indra/llwindow/llwindowmesaheadless.cpp
+++ b/indra/llwindow/llwindowmesaheadless.cpp
@@ -44,10 +44,11 @@ U16 *gMesaBuffer = NULL;
//
// LLWindowMesaHeadless
//
-LLWindowMesaHeadless::LLWindowMesaHeadless(const std::string& title, const std::string& name, S32 x, S32 y, S32 width, S32 height,
+LLWindowMesaHeadless::LLWindowMesaHeadless(LLWindowCallbacks* callbacks,
+ const std::string& title, const std::string& name, S32 x, S32 y, S32 width, S32 height,
U32 flags, BOOL fullscreen, BOOL clearBg,
BOOL disable_vsync, BOOL use_gl, BOOL ignore_pixel_depth)
- : LLWindow(fullscreen, flags)
+ : LLWindow(callbacks, fullscreen, flags)
{
if (use_gl)
{
diff --git a/indra/llwindow/llwindowmesaheadless.h b/indra/llwindow/llwindowmesaheadless.h
index ab562d9ffe..22e0ec126d 100644
--- a/indra/llwindow/llwindowmesaheadless.h
+++ b/indra/llwindow/llwindowmesaheadless.h
@@ -98,7 +98,8 @@ public:
/*virtual*/ void *getPlatformWindow() { return 0; };
/*virtual*/ void bringToFront() {};
- LLWindowMesaHeadless(const std::string& title, const std::string& name, S32 x, S32 y, S32 width, S32 height,
+ LLWindowMesaHeadless(LLWindowCallbacks* callbacks,
+ const std::string& title, const std::string& name, S32 x, S32 y, S32 width, S32 height,
U32 flags, BOOL fullscreen, BOOL clearBg,
BOOL disable_vsync, BOOL use_gl, BOOL ignore_pixel_depth);
~LLWindowMesaHeadless();
diff --git a/indra/llwindow/llwindowsdl.cpp b/indra/llwindow/llwindowsdl.cpp
index 24bd70d57f..ecda880c1f 100644
--- a/indra/llwindow/llwindowsdl.cpp
+++ b/indra/llwindow/llwindowsdl.cpp
@@ -36,15 +36,16 @@
#include "linden_common.h"
#include "llwindowsdl.h"
+
+#include "llwindowcallbacks.h"
#include "llkeyboardsdl.h"
+
#include "llerror.h"
#include "llgl.h"
#include "llstring.h"
#include "lldir.h"
#include "llfindlocale.h"
-#include "indra_constants.h"
-
#if LL_GTK
extern "C" {
# include "gtk/gtk.h"
@@ -187,16 +188,19 @@ Display* LLWindowSDL::get_SDL_Display(void)
#endif // LL_X11
-LLWindowSDL::LLWindowSDL(const std::string& title, S32 x, S32 y, S32 width,
+LLWindowSDL::LLWindowSDL(LLWindowCallbacks* callbacks,
+ const std::string& title, S32 x, S32 y, S32 width,
S32 height, U32 flags,
BOOL fullscreen, BOOL clearBg,
BOOL disable_vsync, BOOL use_gl,
BOOL ignore_pixel_depth, U32 fsaa_samples)
- : LLWindow(fullscreen, flags), Lock_Display(NULL),
+ : LLWindow(callbacks, fullscreen, flags),
+ Lock_Display(NULL),
Unlock_Display(NULL), mGamma(1.0f)
{
// Initialize the keyboard
gKeyboard = new LLKeyboardSDL();
+ gKeyboard->setCallbacks(callbacks);
// Note that we can't set up key-repeat until after SDL has init'd video
// Ignore use_gl for now, only used for drones on PC
@@ -1936,11 +1940,6 @@ void LLWindowSDL::setCursor(ECursorType cursor)
}
}
-ECursorType LLWindowSDL::getCursor()
-{
- return mCurrentCursor;
-}
-
void LLWindowSDL::initCursors()
{
int i;
@@ -2229,7 +2228,7 @@ static void color_changed_callback(GtkWidget *widget,
gtk_color_selection_get_current_color(colorsel, colorp);
}
-BOOL LLWindowSDL::dialog_color_picker ( F32 *r, F32 *g, F32 *b)
+BOOL LLWindowSDL::dialogColorPicker( F32 *r, F32 *g, F32 *b)
{
BOOL rtn = FALSE;
@@ -2306,7 +2305,7 @@ S32 OSMessageBoxSDL(const std::string& text, const std::string& caption, U32 typ
return 0;
}
-BOOL LLWindowSDL::dialog_color_picker ( F32 *r, F32 *g, F32 *b)
+BOOL LLWindowSDL::dialogColorPicker( F32 *r, F32 *g, F32 *b)
{
return (FALSE);
}
@@ -2363,8 +2362,10 @@ void LLWindowSDL::spawnWebBrowser(const std::string& escaped_url)
# endif // LL_X11
std::string cmd, arg;
- cmd = gDirUtilp->getAppRODataDir().c_str();
- cmd += gDirUtilp->getDirDelimiter().c_str();
+ cmd = gDirUtilp->getAppRODataDir();
+ cmd += gDirUtilp->getDirDelimiter();
+ cmd += "etc";
+ cmd += gDirUtilp->getDirDelimiter();
cmd += "launch_url.sh";
arg = escaped_url;
exec_cmd(cmd, arg);
diff --git a/indra/llwindow/llwindowsdl.h b/indra/llwindow/llwindowsdl.h
index 632d8fc1fa..dcf41291ec 100644
--- a/indra/llwindow/llwindowsdl.h
+++ b/indra/llwindow/llwindowsdl.h
@@ -36,6 +36,7 @@
// Simple Directmedia Layer (http://libsdl.org/) implementation of LLWindow class
#include "llwindow.h"
+#include "lltimer.h"
#include "SDL/SDL.h"
#include "SDL/SDL_endian.h"
@@ -76,7 +77,6 @@ public:
/*virtual*/ void hideCursorUntilMouseMove();
/*virtual*/ BOOL isCursorHidden();
/*virtual*/ void setCursor(ECursorType cursor);
- /*virtual*/ ECursorType getCursor();
/*virtual*/ void captureMouse();
/*virtual*/ void releaseMouse();
/*virtual*/ void setMouseClipping( BOOL b );
@@ -118,7 +118,7 @@ public:
/*virtual*/ void beforeDialog();
/*virtual*/ void afterDialog();
- /*virtual*/ BOOL dialog_color_picker(F32 *r, F32 *g, F32 *b);
+ /*virtual*/ BOOL dialogColorPicker(F32 *r, F32 *g, F32 *b);
/*virtual*/ void *getPlatformWindow();
/*virtual*/ void bringToFront();
@@ -147,7 +147,7 @@ public:
#endif // LL_X11
protected:
- LLWindowSDL(
+ LLWindowSDL(LLWindowCallbacks* callbacks,
const std::string& title, int x, int y, int width, int height, U32 flags,
BOOL fullscreen, BOOL clearBg, BOOL disable_vsync, BOOL use_gl,
BOOL ignore_pixel_depth, U32 fsaa_samples);
diff --git a/indra/llwindow/llwindowwin32.cpp b/indra/llwindow/llwindowwin32.cpp
index 6280868dfb..9936b24292 100644
--- a/indra/llwindow/llwindowwin32.cpp
+++ b/indra/llwindow/llwindowwin32.cpp
@@ -36,6 +36,17 @@
#include "llwindowwin32.h"
+// LLWindow library includes
+#include "llkeyboardwin32.h"
+#include "llpreeditor.h"
+#include "llwindowcallbacks.h"
+
+// Linden library includes
+#include "llerror.h"
+#include "llgl.h"
+#include "llstring.h"
+
+// System includes
#include <commdlg.h>
#include <WinUser.h>
#include <mapi.h>
@@ -49,16 +60,7 @@
#include <dinput.h>
#include <Dbt.h.>
-#include "llkeyboardwin32.h"
-#include "llerror.h"
-#include "llgl.h"
-#include "llstring.h"
-#include "lldir.h"
-
-#include "indra_constants.h"
-
-#include "llpreeditor.h"
-
+#include "llmemtype.h"
// culled from winuser.h
#ifndef WM_MOUSEWHEEL /* Added to be compatible with later SDK's */
const S32 WM_MOUSEWHEEL = 0x020A;
@@ -358,13 +360,14 @@ LLWinImm::~LLWinImm()
}
-LLWindowWin32::LLWindowWin32(const std::string& title, const std::string& name, S32 x, S32 y, S32 width,
+LLWindowWin32::LLWindowWin32(LLWindowCallbacks* callbacks,
+ const std::string& title, const std::string& name, S32 x, S32 y, S32 width,
S32 height, U32 flags,
BOOL fullscreen, BOOL clearBg,
BOOL disable_vsync, BOOL use_gl,
BOOL ignore_pixel_depth,
U32 fsaa_samples)
- : LLWindow(fullscreen, flags)
+ : LLWindow(callbacks, fullscreen, flags)
{
mFSAASamples = fsaa_samples;
mIconResource = gIconResource;
@@ -378,6 +381,7 @@ LLWindowWin32::LLWindowWin32(const std::string& title, const std::string& name,
// Initialize the keyboard
gKeyboard = new LLKeyboardWin32();
+ gKeyboard->setCallbacks(callbacks);
// Initialize (boot strap) the Language text input management,
// based on the system's (user's) default settings.
@@ -481,7 +485,8 @@ LLWindowWin32::LLWindowWin32(const std::string& title, const std::string& name,
if (!RegisterClass(&wc))
{
- OSMessageBox("RegisterClass failed", "Error", OSMB_OK);
+ OSMessageBox(mCallbacks->translateString("MBRegClassFailed"),
+ mCallbacks->translateString("MBError"), OSMB_OK);
return;
}
sIsClassRegistered = TRUE;
@@ -572,8 +577,11 @@ LLWindowWin32::LLWindowWin32(const std::string& title, const std::string& name,
mFullscreenBits = -1;
mFullscreenRefresh = -1;
- std::string error = llformat("Unable to run fullscreen at %d x %d.\nRunning in window.", width, height);
- OSMessageBox(error, "Error", OSMB_OK);
+ std::map<std::string,std::string> args;
+ args["[WIDTH]"] = llformat("%d", width);
+ args["[HEIGHT]"] = llformat ("%d", height);
+ OSMessageBox(mCallbacks->translateString("MBFullScreenErr", args),
+ mCallbacks->translateString("MBError"), OSMB_OK);
}
}
@@ -712,7 +720,9 @@ void LLWindowWin32::close()
// This causes WM_DESTROY to be sent *immediately*
if (!DestroyWindow(mWindowHandle))
{
- OSMessageBox("DestroyWindow(mWindowHandle) failed", "Shutdown Error", OSMB_OK);
+ OSMessageBox(mCallbacks->translateString("MBDestroyWinFailed"),
+ mCallbacks->translateString("MBShutdownErr"),
+ OSMB_OK);
}
mWindowHandle = NULL;
@@ -1015,14 +1025,16 @@ BOOL LLWindowWin32::switchContext(BOOL fullscreen, const LLCoordScreen &size, BO
if (!(mhDC = GetDC(mWindowHandle)))
{
close();
- OSMessageBox("Can't make GL device context", "Error", OSMB_OK);
+ OSMessageBox(mCallbacks->translateString("MBDevContextErr"),
+ mCallbacks->translateString("MBError"), OSMB_OK);
return FALSE;
}
if (!(pixel_format = ChoosePixelFormat(mhDC, &pfd)))
{
close();
- OSMessageBox("Can't find suitable pixel format", "Error", OSMB_OK);
+ OSMessageBox(mCallbacks->translateString("MBPixelFmtErr"),
+ mCallbacks->translateString("MBError"), OSMB_OK);
return FALSE;
}
@@ -1031,57 +1043,48 @@ BOOL LLWindowWin32::switchContext(BOOL fullscreen, const LLCoordScreen &size, BO
&pfd))
{
close();
- OSMessageBox("Can't get pixel format description", "Error", OSMB_OK);
+ OSMessageBox(mCallbacks->translateString("MBPixelFmtDescErr"),
+ mCallbacks->translateString("MBError"), OSMB_OK);
return FALSE;
}
if (pfd.cColorBits < 32)
{
close();
- OSMessageBox(
- "Second Life requires True Color (32-bit) to run in a window.\n"
- "Please go to Control Panels -> Display -> Settings and\n"
- "set the screen to 32-bit color.\n"
- "Alternately, if you choose to run fullscreen, Second Life\n"
- "will automatically adjust the screen each time it runs.",
- "Error",
- OSMB_OK);
+ OSMessageBox(mCallbacks->translateString("MBTrueColorWindow"),
+ mCallbacks->translateString("MBError"), OSMB_OK);
return FALSE;
}
if (pfd.cAlphaBits < 8)
{
close();
- OSMessageBox(
- "Second Life is unable to run because it can't get an 8 bit alpha\n"
- "channel. Usually this is due to video card driver issues.\n"
- "Please make sure you have the latest video card drivers installed.\n"
- "Also be sure your monitor is set to True Color (32-bit) in\n"
- "Control Panels -> Display -> Settings.\n"
- "If you continue to receive this message, contact customer service.",
- "Error",
- OSMB_OK);
+ OSMessageBox(mCallbacks->translateString("MBAlpha"),
+ mCallbacks->translateString("MBError"), OSMB_OK);
return FALSE;
}
if (!SetPixelFormat(mhDC, pixel_format, &pfd))
{
close();
- OSMessageBox("Can't set pixel format", "Error", OSMB_OK);
+ OSMessageBox(mCallbacks->translateString("MBPixelFmtSetErr"),
+ mCallbacks->translateString("MBError"), OSMB_OK);
return FALSE;
}
if (!(mhRC = wglCreateContext(mhDC)))
{
close();
- OSMessageBox("Can't create GL rendering context", "Error", OSMB_OK);
+ OSMessageBox(mCallbacks->translateString("MBGLContextErr"),
+ mCallbacks->translateString("MBError"), OSMB_OK);
return FALSE;
}
if (!wglMakeCurrent(mhDC, mhRC))
{
close();
- OSMessageBox("Can't activate GL rendering context", "Error", OSMB_OK);
+ OSMessageBox(mCallbacks->translateString("MBGLContextActErr"),
+ mCallbacks->translateString("MBError"), OSMB_OK);
return FALSE;
}
@@ -1243,14 +1246,15 @@ BOOL LLWindowWin32::switchContext(BOOL fullscreen, const LLCoordScreen &size, BO
if (!(mhDC = GetDC(mWindowHandle)))
{
close();
- OSMessageBox("Can't make GL device context", "Error", OSMB_OK);
+ OSMessageBox(mCallbacks->translateString("MBDevContextErr"), mCallbacks->translateString("MBError"), OSMB_OK);
return FALSE;
}
if (!SetPixelFormat(mhDC, pixel_format, &pfd))
{
close();
- OSMessageBox("Can't set pixel format", "Error", OSMB_OK);
+ OSMessageBox(mCallbacks->translateString("MBPixelFmtSetErr"),
+ mCallbacks->translateString("MBError"), OSMB_OK);
return FALSE;
}
@@ -1287,7 +1291,7 @@ BOOL LLWindowWin32::switchContext(BOOL fullscreen, const LLCoordScreen &size, BO
&pfd))
{
close();
- OSMessageBox("Can't get pixel format description", "Error", OSMB_OK);
+ OSMessageBox(mCallbacks->translateString("MBPixelFmtDescErr"), mCallbacks->translateString("MBError"), OSMB_OK);
return FALSE;
}
@@ -1300,57 +1304,35 @@ BOOL LLWindowWin32::switchContext(BOOL fullscreen, const LLCoordScreen &size, BO
if (pfd.cColorBits < 32 || GetDeviceCaps(mhDC, BITSPIXEL) < 32)
{
close();
- OSMessageBox(
- "Second Life requires True Color (32-bit) to run in a window.\n"
- "Please go to Control Panels -> Display -> Settings and\n"
- "set the screen to 32-bit color.\n"
- "Alternately, if you choose to run fullscreen, Second Life\n"
- "will automatically adjust the screen each time it runs.",
- "Error",
- OSMB_OK);
+ OSMessageBox(mCallbacks->translateString("MBTrueColorWindow"), mCallbacks->translateString("MBError"), OSMB_OK);
return FALSE;
}
if (pfd.cAlphaBits < 8)
{
close();
- OSMessageBox(
- "Second Life is unable to run because it can't get an 8 bit alpha\n"
- "channel. Usually this is due to video card driver issues.\n"
- "Please make sure you have the latest video card drivers installed.\n"
- "Also be sure your monitor is set to True Color (32-bit) in\n"
- "Control Panels -> Display -> Settings.\n"
- "If you continue to receive this message, contact customer service.",
- "Error",
- OSMB_OK);
+ OSMessageBox(mCallbacks->translateString("MBAlpha"), mCallbacks->translateString("MBError"), OSMB_OK);
return FALSE;
}
if (!(mhRC = wglCreateContext(mhDC)))
{
close();
- OSMessageBox("Can't create GL rendering context", "Error", OSMB_OK);
+ OSMessageBox(mCallbacks->translateString("MBGLContextErr"), mCallbacks->translateString("MBError"), OSMB_OK);
return FALSE;
}
if (!wglMakeCurrent(mhDC, mhRC))
{
close();
- OSMessageBox("Can't activate GL rendering context", "Error", OSMB_OK);
+ OSMessageBox(mCallbacks->translateString("MBGLContextActErr"), mCallbacks->translateString("MBError"), OSMB_OK);
return FALSE;
}
if (!gGLManager.initGL())
{
close();
- OSMessageBox(
- "Second Life is unable to run because your video card drivers\n"
- "did not install properly, are out of date, or are for unsupported\n"
- "hardware. Please make sure you have the latest video card drivers\n"
- "and even if you do have the latest, try reinstalling them.\n\n"
- "If you continue to receive this message, contact customer service.",
- "Error",
- OSMB_OK);
+ OSMessageBox(mCallbacks->translateString("MBVideoDrvErr"), mCallbacks->translateString("MBError"), OSMB_OK);
return FALSE;
}
@@ -1612,6 +1594,8 @@ void LLWindowWin32::gatherInput()
MSG msg;
int msg_count = 0;
+ LLMemType m1(LLMemType::MTYPE_GATHER_INPUT);
+
while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE) && msg_count < MAX_MESSAGE_PER_UPDATE)
{
mCallbacks->handlePingWatchdog(this, "Main:TranslateGatherInput");
@@ -1661,6 +1645,9 @@ void LLWindowWin32::gatherInput()
mMousePositionModified = FALSE;
}
+static LLFastTimer::DeclareTimer FTM_KEYHANDLER("Handle Keyboard");
+static LLFastTimer::DeclareTimer FTM_MOUSEHANDLER("Handle Mouse");
+
LRESULT CALLBACK LLWindowWin32::mainWindowProc(HWND h_wnd, UINT u_msg, WPARAM w_param, LPARAM l_param)
{
LLWindowWin32 *window_imp = (LLWindowWin32 *)GetWindowLong(h_wnd, GWL_USERDATA);
@@ -1894,7 +1881,7 @@ LRESULT CALLBACK LLWindowWin32::mainWindowProc(HWND h_wnd, UINT u_msg, WPARAM w_
case WM_KEYUP:
{
window_imp->mCallbacks->handlePingWatchdog(window_imp, "Main:WM_KEYUP");
- LLFastTimer t2(LLFastTimer::FTM_KEYHANDLER);
+ LLFastTimer t2(FTM_KEYHANDLER);
if (gDebugWindowProc)
{
@@ -2003,7 +1990,7 @@ LRESULT CALLBACK LLWindowWin32::mainWindowProc(HWND h_wnd, UINT u_msg, WPARAM w_
case WM_LBUTTONDOWN:
{
window_imp->mCallbacks->handlePingWatchdog(window_imp, "Main:WM_LBUTTONDOWN");
- LLFastTimer t2(LLFastTimer::FTM_MOUSEHANDLER);
+ LLFastTimer t2(FTM_MOUSEHANDLER);
if (LLWinImm::isAvailable() && window_imp->mPreeditor)
{
window_imp->interruptLanguageTextInput();
@@ -2067,7 +2054,7 @@ LRESULT CALLBACK LLWindowWin32::mainWindowProc(HWND h_wnd, UINT u_msg, WPARAM w_
case WM_LBUTTONUP:
{
window_imp->mCallbacks->handlePingWatchdog(window_imp, "Main:WM_LBUTTONUP");
- LLFastTimer t2(LLFastTimer::FTM_MOUSEHANDLER);
+ LLFastTimer t2(FTM_MOUSEHANDLER);
//if (gDebugClicks)
//{
// LL_INFOS("Window") << "WndProc left button up" << LL_ENDL;
@@ -2101,7 +2088,7 @@ LRESULT CALLBACK LLWindowWin32::mainWindowProc(HWND h_wnd, UINT u_msg, WPARAM w_
case WM_RBUTTONDOWN:
{
window_imp->mCallbacks->handlePingWatchdog(window_imp, "Main:WM_RBUTTONDOWN");
- LLFastTimer t2(LLFastTimer::FTM_MOUSEHANDLER);
+ LLFastTimer t2(FTM_MOUSEHANDLER);
if (LLWinImm::isAvailable() && window_imp->mPreeditor)
{
window_imp->interruptLanguageTextInput();
@@ -2135,7 +2122,7 @@ LRESULT CALLBACK LLWindowWin32::mainWindowProc(HWND h_wnd, UINT u_msg, WPARAM w_
case WM_RBUTTONUP:
{
window_imp->mCallbacks->handlePingWatchdog(window_imp, "Main:WM_RBUTTONUP");
- LLFastTimer t2(LLFastTimer::FTM_MOUSEHANDLER);
+ LLFastTimer t2(FTM_MOUSEHANDLER);
// Because we move the cursor position in the app, we need to query
// to find out where the cursor at the time the event is handled.
// If we don't do this, many clicks could get buffered up, and if the
@@ -2165,7 +2152,7 @@ LRESULT CALLBACK LLWindowWin32::mainWindowProc(HWND h_wnd, UINT u_msg, WPARAM w_
// case WM_MBUTTONDBLCLK:
{
window_imp->mCallbacks->handlePingWatchdog(window_imp, "Main:WM_MBUTTONDOWN");
- LLFastTimer t2(LLFastTimer::FTM_MOUSEHANDLER);
+ LLFastTimer t2(FTM_MOUSEHANDLER);
if (LLWinImm::isAvailable() && window_imp->mPreeditor)
{
window_imp->interruptLanguageTextInput();
@@ -2199,7 +2186,7 @@ LRESULT CALLBACK LLWindowWin32::mainWindowProc(HWND h_wnd, UINT u_msg, WPARAM w_
case WM_MBUTTONUP:
{
window_imp->mCallbacks->handlePingWatchdog(window_imp, "Main:WM_MBUTTONUP");
- LLFastTimer t2(LLFastTimer::FTM_MOUSEHANDLER);
+ LLFastTimer t2(FTM_MOUSEHANDLER);
// Because we move the cursor position in tllviewerhe app, we need to query
// to find out where the cursor at the time the event is handled.
// If we don't do this, many clicks could get buffered up, and if the
@@ -3030,7 +3017,7 @@ void LLWindowWin32::spawnWebBrowser(const std::string& escaped_url )
}
-BOOL LLWindowWin32::dialog_color_picker ( F32 *r, F32 *g, F32 *b )
+BOOL LLWindowWin32::dialogColorPicker( F32 *r, F32 *g, F32 *b )
{
BOOL retval = FALSE;
diff --git a/indra/llwindow/llwindowwin32.h b/indra/llwindow/llwindowwin32.h
index 237f834318..e14324c9f1 100644
--- a/indra/llwindow/llwindowwin32.h
+++ b/indra/llwindow/llwindowwin32.h
@@ -100,7 +100,7 @@ public:
/*virtual*/ F32 getPixelAspectRatio();
/*virtual*/ void setNativeAspectRatio(F32 ratio) { mOverrideAspectRatio = ratio; }
- /*virtual*/ BOOL dialog_color_picker (F32 *r, F32 *g, F32 *b );
+ /*virtual*/ BOOL dialogColorPicker(F32 *r, F32 *g, F32 *b );
/*virtual*/ void *getPlatformWindow();
/*virtual*/ void bringToFront();
@@ -115,7 +115,7 @@ public:
static std::vector<std::string> getDynamicFallbackFontList();
protected:
- LLWindowWin32(
+ LLWindowWin32(LLWindowCallbacks* callbacks,
const std::string& title, const std::string& name, int x, int y, int width, int height, U32 flags,
BOOL fullscreen, BOOL clearBg, BOOL disable_vsync, BOOL use_gl,
BOOL ignore_pixel_depth, U32 fsaa_samples);
diff --git a/indra/llxml/CMakeLists.txt b/indra/llxml/CMakeLists.txt
index c5fb44e721..3f7714f505 100644
--- a/indra/llxml/CMakeLists.txt
+++ b/indra/llxml/CMakeLists.txt
@@ -5,11 +5,13 @@ project(llxml)
include(00-Common)
include(LLCommon)
include(LLMath)
+include(LLVFS)
include(LLXML)
include_directories(
${LLCOMMON_INCLUDE_DIRS}
${LLMATH_INCLUDE_DIRS}
+ ${LLVFS_INCLUDE_DIRS}
)
set(llxml_SOURCE_FILES
@@ -38,6 +40,7 @@ add_library (llxml ${llxml_SOURCE_FILES})
# Libraries on which this library depends, needed for Linux builds
# Sort by high-level to low-level
target_link_libraries( llxml
+ llvfs
llmath
${EXPAT_LIBRARIES}
)
diff --git a/indra/llxml/llcontrol.cpp b/indra/llxml/llcontrol.cpp
index 8bd04d727c..9d0cdacb1d 100644
--- a/indra/llxml/llcontrol.cpp
+++ b/indra/llxml/llcontrol.cpp
@@ -56,6 +56,45 @@
#define CONTROL_ERRS LL_WARNS("ControlErrors")
#endif
+
+template <> eControlType get_control_type<U32>();
+template <> eControlType get_control_type<S32>();
+template <> eControlType get_control_type<F32>();
+template <> eControlType get_control_type<bool>();
+// Yay BOOL, its really an S32.
+//template <> eControlType get_control_type<BOOL> () ;
+template <> eControlType get_control_type<std::string>();
+
+template <> eControlType get_control_type<LLVector3>();
+template <> eControlType get_control_type<LLVector3d>();
+template <> eControlType get_control_type<LLRect>();
+template <> eControlType get_control_type<LLColor4>();
+template <> eControlType get_control_type<LLColor3>();
+template <> eControlType get_control_type<LLColor4U>();
+template <> eControlType get_control_type<LLSD>();
+
+template <> LLSD convert_to_llsd<U32>(const U32& in);
+template <> LLSD convert_to_llsd<LLVector3>(const LLVector3& in);
+template <> LLSD convert_to_llsd<LLVector3d>(const LLVector3d& in);
+template <> LLSD convert_to_llsd<LLRect>(const LLRect& in);
+template <> LLSD convert_to_llsd<LLColor4>(const LLColor4& in);
+template <> LLSD convert_to_llsd<LLColor3>(const LLColor3& in);
+template <> LLSD convert_to_llsd<LLColor4U>(const LLColor4U& in);
+
+template <> bool convert_from_llsd<bool>(const LLSD& sd, eControlType type, const std::string& control_name);
+template <> S32 convert_from_llsd<S32>(const LLSD& sd, eControlType type, const std::string& control_name);
+template <> U32 convert_from_llsd<U32>(const LLSD& sd, eControlType type, const std::string& control_name);
+template <> F32 convert_from_llsd<F32>(const LLSD& sd, eControlType type, const std::string& control_name);
+template <> std::string convert_from_llsd<std::string>(const LLSD& sd, eControlType type, const std::string& control_name);
+template <> LLWString convert_from_llsd<LLWString>(const LLSD& sd, eControlType type, const std::string& control_name);
+template <> LLVector3 convert_from_llsd<LLVector3>(const LLSD& sd, eControlType type, const std::string& control_name);
+template <> LLVector3d convert_from_llsd<LLVector3d>(const LLSD& sd, eControlType type, const std::string& control_name);
+template <> LLRect convert_from_llsd<LLRect>(const LLSD& sd, eControlType type, const std::string& control_name);
+template <> LLColor4 convert_from_llsd<LLColor4>(const LLSD& sd, eControlType type, const std::string& control_name);
+template <> LLColor4U convert_from_llsd<LLColor4U>(const LLSD& sd, eControlType type, const std::string& control_name);
+template <> LLColor3 convert_from_llsd<LLColor3>(const LLSD& sd, eControlType type, const std::string& control_name);
+template <> LLSD convert_from_llsd<LLSD>(const LLSD& sd, eControlType type, const std::string& control_name);
+
//this defines the current version of the settings file
const S32 CURRENT_VERSION = 101;
@@ -87,9 +126,6 @@ bool LLControlVariable::llsd_compare(const LLSD& a, const LLSD & b)
case TYPE_COL3:
result = LLColor3(a) == LLColor3(b);
break;
- case TYPE_COL4U:
- result = LLColor4U(a) == LLColor4U(b);
- break;
case TYPE_STRING:
result = a.asString() == b.asString();
break;
@@ -148,9 +184,15 @@ LLSD LLControlVariable::getComparableValue(const LLSD& value)
return storable_value;
}
-void LLControlVariable::setValue(const LLSD& value, bool saved_value)
+void LLControlVariable::setValue(const LLSD& new_value, bool saved_value)
{
- LLSD storable_value = getComparableValue(value);
+ if (mValidateSignal(this, new_value) == false)
+ {
+ // can not set new value, exit
+ return;
+ }
+
+ LLSD storable_value = getComparableValue(new_value);
bool value_changed = llsd_compare(getValue(), storable_value) == FALSE;
if(saved_value)
{
@@ -163,7 +205,7 @@ void LLControlVariable::setValue(const LLSD& value, bool saved_value)
}
else
{
- // This is a unsaved value. Its needs to reside at
+ // This is an unsaved value. Its needs to reside at
// mValues[2] (or greater). It must not affect
// the result of getSaveValue()
if (llsd_compare(mValues.back(), storable_value) == FALSE)
@@ -185,10 +227,9 @@ void LLControlVariable::setValue(const LLSD& value, bool saved_value)
}
}
-
if(value_changed)
{
- mSignal(storable_value);
+ mCommitSignal(this, storable_value);
}
}
@@ -262,7 +303,8 @@ LLPointer<LLControlVariable> LLControlGroup::getControl(const std::string& name)
////////////////////////////////////////////////////////////////////////////
-LLControlGroup::LLControlGroup()
+LLControlGroup::LLControlGroup(const std::string& name)
+: LLInstanceTracker<LLControlGroup, std::string>(name)
{
mTypeString[TYPE_U32] = "U32";
mTypeString[TYPE_S32] = "S32";
@@ -274,7 +316,6 @@ LLControlGroup::LLControlGroup()
mTypeString[TYPE_RECT] = "Rect";
mTypeString[TYPE_COL4] = "Color4";
mTypeString[TYPE_COL3] = "Color3";
- mTypeString[TYPE_COL4U] = "Color4u";
mTypeString[TYPE_LLSD] = "LLSD";
}
@@ -370,11 +411,6 @@ BOOL LLControlGroup::declareRect(const std::string& name, const LLRect &initial_
return declareControl(name, TYPE_RECT, initial_val.getValue(), comment, persist);
}
-BOOL LLControlGroup::declareColor4U(const std::string& name, const LLColor4U &initial_val, const std::string& comment, BOOL persist )
-{
- return declareControl(name, TYPE_COL4U, initial_val.getValue(), comment, persist);
-}
-
BOOL LLControlGroup::declareColor4(const std::string& name, const LLColor4 &initial_val, const std::string& comment, BOOL persist )
{
return declareControl(name, TYPE_COL4, initial_val.getValue(), comment, persist);
@@ -392,81 +428,32 @@ BOOL LLControlGroup::declareLLSD(const std::string& name, const LLSD &initial_va
BOOL LLControlGroup::getBOOL(const std::string& name)
{
- LLControlVariable* control = getControl(name);
-
- if (control && control->isType(TYPE_BOOLEAN))
- return control->get().asBoolean();
- else
- {
- CONTROL_ERRS << "Invalid BOOL control " << name << llendl;
- return FALSE;
- }
+ return (BOOL)get<bool>(name);
}
S32 LLControlGroup::getS32(const std::string& name)
{
- LLControlVariable* control = getControl(name);
-
- if (control && control->isType(TYPE_S32))
- return control->get().asInteger();
- else
- {
- CONTROL_ERRS << "Invalid S32 control " << name << llendl;
- return 0;
- }
+ return get<S32>(name);
}
U32 LLControlGroup::getU32(const std::string& name)
{
- LLControlVariable* control = getControl(name);
-
- if (control && control->isType(TYPE_U32))
- return control->get().asInteger();
- else
- {
- CONTROL_ERRS << "Invalid U32 control " << name << llendl;
- return 0;
- }
+ return get<U32>(name);
}
F32 LLControlGroup::getF32(const std::string& name)
{
- LLControlVariable* control = getControl(name);
-
- if (control && control->isType(TYPE_F32))
- return (F32) control->get().asReal();
- else
- {
- CONTROL_ERRS << "Invalid F32 control " << name << llendl;
- return 0.0f;
- }
-}
-
-std::string LLControlGroup::findString(const std::string& name)
-{
- LLControlVariable* control = getControl(name);
-
- if (control && control->isType(TYPE_STRING))
- return control->get().asString();
- return LLStringUtil::null;
+ return get<F32>(name);
}
std::string LLControlGroup::getString(const std::string& name)
{
- LLControlVariable* control = getControl(name);
-
- if (control && control->isType(TYPE_STRING))
- return control->get().asString();
- else
- {
- CONTROL_ERRS << "Invalid string control " << name << llendl;
- return LLStringUtil::null;
- }
+ return get<std::string>(name);
}
LLWString LLControlGroup::getWString(const std::string& name)
{
- return utf8str_to_wstring(getString(name));
+ return get<LLWString>(name);
}
std::string LLControlGroup::getText(const std::string& name)
@@ -479,123 +466,38 @@ std::string LLControlGroup::getText(const std::string& name)
LLVector3 LLControlGroup::getVector3(const std::string& name)
{
- LLControlVariable* control = getControl(name);
-
- if (control && control->isType(TYPE_VEC3))
- return control->get();
- else
- {
- CONTROL_ERRS << "Invalid LLVector3 control " << name << llendl;
- return LLVector3::zero;
- }
+ return get<LLVector3>(name);
}
LLVector3d LLControlGroup::getVector3d(const std::string& name)
{
- LLControlVariable* control = getControl(name);
-
- if (control && control->isType(TYPE_VEC3D))
- return control->get();
- else
- {
- CONTROL_ERRS << "Invalid LLVector3d control " << name << llendl;
- return LLVector3d::zero;
- }
+ return get<LLVector3d>(name);
}
LLRect LLControlGroup::getRect(const std::string& name)
{
- LLControlVariable* control = getControl(name);
-
- if (control && control->isType(TYPE_RECT))
- return control->get();
- else
- {
- CONTROL_ERRS << "Invalid rect control " << name << llendl;
- return LLRect::null;
- }
+ return get<LLRect>(name);
}
LLColor4 LLControlGroup::getColor(const std::string& name)
{
- ctrl_name_table_t::const_iterator i = mNameTable.find(name);
-
- if (i != mNameTable.end())
- {
- LLControlVariable* control = i->second;
-
- switch(control->mType)
- {
- case TYPE_COL4:
- {
- return LLColor4(control->get());
- }
- case TYPE_COL4U:
- {
- return LLColor4(LLColor4U(control->get()));
- }
- default:
- {
- CONTROL_ERRS << "Control " << name << " not a color" << llendl;
- return LLColor4::white;
- }
- }
- }
- else
- {
- CONTROL_ERRS << "Invalid getColor control " << name << llendl;
- return LLColor4::white;
- }
-}
-
-LLColor4U LLControlGroup::getColor4U(const std::string& name)
-{
- LLControlVariable* control = getControl(name);
-
- if (control && control->isType(TYPE_COL4U))
- return control->get();
- else
- {
- CONTROL_ERRS << "Invalid LLColor4 control " << name << llendl;
- return LLColor4U::white;
- }
+ return get<LLColor4>(name);
}
LLColor4 LLControlGroup::getColor4(const std::string& name)
{
- LLControlVariable* control = getControl(name);
-
- if (control && control->isType(TYPE_COL4))
- return control->get();
- else
- {
- CONTROL_ERRS << "Invalid LLColor4 control " << name << llendl;
- return LLColor4::white;
- }
+ return get<LLColor4>(name);
}
LLColor3 LLControlGroup::getColor3(const std::string& name)
{
- LLControlVariable* control = getControl(name);
-
- if (control && control->isType(TYPE_COL3))
- return control->get();
- else
- {
- CONTROL_ERRS << "Invalid LLColor3 control " << name << llendl;
- return LLColor3::white;
- }
+ return get<LLColor3>(name);
}
LLSD LLControlGroup::getLLSD(const std::string& name)
{
- LLControlVariable* control = getControl(name);
-
- if (control && control->isType(TYPE_LLSD))
- return control->getValue();
- CONTROL_ERRS << "Invalid LLSD control " << name << llendl;
- return LLSD();
+ return get<LLSD>(name);
}
BOOL LLControlGroup::controlExists(const std::string& name)
@@ -604,170 +506,67 @@ BOOL LLControlGroup::controlExists(const std::string& name)
return iter != mNameTable.end();
}
+
//-------------------------------------------------------------------
// Set functions
//-------------------------------------------------------------------
void LLControlGroup::setBOOL(const std::string& name, BOOL val)
{
- LLControlVariable* control = getControl(name);
-
- if (control && control->isType(TYPE_BOOLEAN))
- {
- control->set(val);
- }
- else
- {
- CONTROL_ERRS << "Invalid control " << name << llendl;
- }
+ set<bool>(name, val);
}
void LLControlGroup::setS32(const std::string& name, S32 val)
{
- LLControlVariable* control = getControl(name);
-
- if (control && control->isType(TYPE_S32))
- {
- control->set(val);
- }
- else
- {
- CONTROL_ERRS << "Invalid control " << name << llendl;
- }
+ set(name, val);
}
void LLControlGroup::setF32(const std::string& name, F32 val)
{
- LLControlVariable* control = getControl(name);
-
- if (control && control->isType(TYPE_F32))
- {
- control->set(val);
- }
- else
- {
- CONTROL_ERRS << "Invalid control " << name << llendl;
- }
+ set(name, val);
}
void LLControlGroup::setU32(const std::string& name, U32 val)
{
- LLControlVariable* control = getControl(name);
-
- if (control && control->isType(TYPE_U32))
- {
- control->set((LLSD::Integer) val);
- }
- else
- {
- CONTROL_ERRS << "Invalid control " << name << llendl;
- }
+ set(name, val);
}
void LLControlGroup::setString(const std::string& name, const std::string &val)
{
- LLControlVariable* control = getControl(name);
-
- if (control && control->isType(TYPE_STRING))
- {
- control->set(val);
- }
- else
- {
- CONTROL_ERRS << "Invalid control " << name << llendl;
- }
+ set(name, val);
}
void LLControlGroup::setVector3(const std::string& name, const LLVector3 &val)
{
- LLControlVariable* control = getControl(name);
-
- if (control && control->isType(TYPE_VEC3))
- {
- control->set(val.getValue());
- }
- else
- {
- CONTROL_ERRS << "Invalid control " << name << llendl;
- }
+ set(name, val);
}
void LLControlGroup::setVector3d(const std::string& name, const LLVector3d &val)
{
- LLControlVariable* control = getControl(name);
-
- if (control && control->isType(TYPE_VEC3D))
- {
- control->set(val.getValue());
- }
- else
- {
- CONTROL_ERRS << "Invalid control " << name << llendl;
- }
+ set(name, val);
}
void LLControlGroup::setRect(const std::string& name, const LLRect &val)
{
- LLControlVariable* control = getControl(name);
-
- if (control && control->isType(TYPE_RECT))
- {
- control->set(val.getValue());
- }
- else
- {
- CONTROL_ERRS << "Invalid rect control " << name << llendl;
- }
-}
-
-void LLControlGroup::setColor4U(const std::string& name, const LLColor4U &val)
-{
- LLControlVariable* control = getControl(name);
-
- if (control && control->isType(TYPE_COL4U))
- {
- control->set(val.getValue());
- }
- else
- {
- CONTROL_ERRS << "Invalid LLColor4 control " << name << llendl;
- }
+ set(name, val);
}
void LLControlGroup::setColor4(const std::string& name, const LLColor4 &val)
{
- LLControlVariable* control = getControl(name);
-
- if (control && control->isType(TYPE_COL4))
- {
- control->set(val.getValue());
- }
- else
- {
- CONTROL_ERRS << "Invalid LLColor4 control " << name << llendl;
- }
+ set(name, val);
}
void LLControlGroup::setLLSD(const std::string& name, const LLSD& val)
{
- LLControlVariable* control = getControl(name);
-
- if (control && control->isType(TYPE_LLSD))
- {
- setValue(name, val);
- }
- else
- {
- CONTROL_ERRS << "Invalid LLSD control " << name << llendl;
- }
+ set(name, val);
}
-void LLControlGroup::setValue(const std::string& name, const LLSD& val)
+void LLControlGroup::setUntypedValue(const std::string& name, const LLSD& val)
{
if (name.empty())
{
@@ -778,7 +577,7 @@ void LLControlGroup::setValue(const std::string& name, const LLSD& val)
if (control)
{
- control->set(val);
+ control->setValue(val);
}
else
{
@@ -786,6 +585,7 @@ void LLControlGroup::setValue(const std::string& name, const LLSD& val)
}
}
+
//---------------------------------------------------------------
// Load and save
//---------------------------------------------------------------
@@ -854,9 +654,6 @@ U32 LLControlGroup::loadFromFileLegacy(const std::string& filename, BOOL require
case TYPE_COL4:
declareColor4(name, LLColor4::white, LLStringUtil::null, NO_PERSIST);
break;
- case TYPE_COL4U:
- declareColor4U(name, LLColor4U::white, LLStringUtil::null, NO_PERSIST);
- break;
case TYPE_STRING:
default:
declareString(name, LLStringUtil::null, LLStringUtil::null, NO_PERSIST);
@@ -954,15 +751,6 @@ U32 LLControlGroup::loadFromFileLegacy(const std::string& filename, BOOL require
validitems++;
}
break;
- case TYPE_COL4U:
- {
- LLColor4U color;
-
- child_nodep->getAttributeColor4U("value", color);
- control->set(color.getValue());
- validitems++;
- }
- break;
case TYPE_COL4:
{
LLColor4 color;
@@ -1063,6 +851,7 @@ U32 LLControlGroup::loadFromFile(const std::string& filename, bool set_default_v
U32 validitems = 0;
bool hidefromsettingseditor = false;
+
for(LLSD::map_const_iterator itr = settings.beginMap(); itr != settings.endMap(); ++itr)
{
bool persist = true;
@@ -1156,55 +945,6 @@ void LLControlGroup::applyToAll(ApplyFunctor* func)
}
//============================================================================
-// First-use
-
-static std::string get_warn_name(const std::string& name)
-{
- std::string warnname = "Warn" + name;
- for (std::string::iterator iter = warnname.begin(); iter != warnname.end(); ++iter)
- {
- char c = *iter;
- if (!isalnum(c))
- {
- *iter = '_';
- }
- }
- return warnname;
-}
-
-void LLControlGroup::addWarning(const std::string& name)
-{
- // Note: may get called more than once per warning
- // (e.g. if allready loaded from a settings file),
- // but that is OK, declareBOOL will handle it
- std::string warnname = get_warn_name(name);
- std::string comment = std::string("Enables ") + name + std::string(" warning dialog");
- declareBOOL(warnname, TRUE, comment);
- mWarnings.insert(warnname);
-}
-
-BOOL LLControlGroup::getWarning(const std::string& name)
-{
- std::string warnname = get_warn_name(name);
- return getBOOL(warnname);
-}
-
-void LLControlGroup::setWarning(const std::string& name, BOOL val)
-{
- std::string warnname = get_warn_name(name);
- setBOOL(warnname, val);
-}
-
-void LLControlGroup::resetWarnings()
-{
- for (std::set<std::string>::iterator iter = mWarnings.begin();
- iter != mWarnings.end(); ++iter)
- {
- setBOOL(*iter, TRUE);
- }
-}
-
-//============================================================================
#ifdef TEST_HARNESS
void main()
@@ -1268,4 +1008,297 @@ void main()
#endif
+template <> eControlType get_control_type<U32>()
+{
+ return TYPE_U32;
+}
+
+template <> eControlType get_control_type<S32>()
+{
+ return TYPE_S32;
+}
+
+template <> eControlType get_control_type<F32>()
+{
+ return TYPE_F32;
+}
+
+template <> eControlType get_control_type<bool> ()
+{
+ return TYPE_BOOLEAN;
+}
+/*
+// Yay BOOL, its really an S32.
+template <> eControlType get_control_type<BOOL> ()
+{
+ return TYPE_BOOLEAN;
+}
+*/
+template <> eControlType get_control_type<std::string>()
+{
+ return TYPE_STRING;
+}
+
+template <> eControlType get_control_type<LLVector3>()
+{
+ return TYPE_VEC3;
+}
+
+template <> eControlType get_control_type<LLVector3d>()
+{
+ return TYPE_VEC3D;
+}
+
+template <> eControlType get_control_type<LLRect>()
+{
+ return TYPE_RECT;
+}
+
+template <> eControlType get_control_type<LLColor4>()
+{
+ return TYPE_COL4;
+}
+
+template <> eControlType get_control_type<LLColor3>()
+{
+ return TYPE_COL3;
+}
+
+template <> eControlType get_control_type<LLSD>()
+{
+ return TYPE_LLSD;
+}
+
+
+template <> LLSD convert_to_llsd<U32>(const U32& in)
+{
+ return (LLSD::Integer)in;
+}
+
+template <> LLSD convert_to_llsd<LLVector3>(const LLVector3& in)
+{
+ return in.getValue();
+}
+
+template <> LLSD convert_to_llsd<LLVector3d>(const LLVector3d& in)
+{
+ return in.getValue();
+}
+
+template <> LLSD convert_to_llsd<LLRect>(const LLRect& in)
+{
+ return in.getValue();
+}
+
+template <> LLSD convert_to_llsd<LLColor4>(const LLColor4& in)
+{
+ return in.getValue();
+}
+
+template <> LLSD convert_to_llsd<LLColor3>(const LLColor3& in)
+{
+ return in.getValue();
+}
+
+template <> LLSD convert_to_llsd<LLColor4U>(const LLColor4U& in)
+{
+ return in.getValue();
+}
+
+
+template<>
+bool convert_from_llsd<bool>(const LLSD& sd, eControlType type, const std::string& control_name)
+{
+ if (type == TYPE_BOOLEAN)
+ return sd.asBoolean();
+ else
+ {
+ CONTROL_ERRS << "Invalid BOOL value" << llendl;
+ return FALSE;
+ }
+}
+
+template<>
+S32 convert_from_llsd<S32>(const LLSD& sd, eControlType type, const std::string& control_name)
+{
+ if (type == TYPE_S32)
+ return sd.asInteger();
+ else
+ {
+ CONTROL_ERRS << "Invalid S32 value" << llendl;
+ return 0;
+ }
+}
+
+template<>
+U32 convert_from_llsd<U32>(const LLSD& sd, eControlType type, const std::string& control_name)
+{
+ if (type == TYPE_U32)
+ return sd.asInteger();
+ else
+ {
+ CONTROL_ERRS << "Invalid U32 value" << llendl;
+ return 0;
+ }
+}
+
+template<>
+F32 convert_from_llsd<F32>(const LLSD& sd, eControlType type, const std::string& control_name)
+{
+ if (type == TYPE_F32)
+ return (F32) sd.asReal();
+ else
+ {
+ CONTROL_ERRS << "Invalid F32 value" << llendl;
+ return 0.0f;
+ }
+}
+
+template<>
+std::string convert_from_llsd<std::string>(const LLSD& sd, eControlType type, const std::string& control_name)
+{
+ if (type == TYPE_STRING)
+ return sd.asString();
+ else
+ {
+ CONTROL_ERRS << "Invalid string value" << llendl;
+ return LLStringUtil::null;
+ }
+}
+
+template<>
+LLWString convert_from_llsd<LLWString>(const LLSD& sd, eControlType type, const std::string& control_name)
+{
+ return utf8str_to_wstring(convert_from_llsd<std::string>(sd, type, control_name));
+}
+
+template<>
+LLVector3 convert_from_llsd<LLVector3>(const LLSD& sd, eControlType type, const std::string& control_name)
+{
+ if (type == TYPE_VEC3)
+ return (LLVector3)sd;
+ else
+ {
+ CONTROL_ERRS << "Invalid LLVector3 value" << llendl;
+ return LLVector3::zero;
+ }
+}
+
+template<>
+LLVector3d convert_from_llsd<LLVector3d>(const LLSD& sd, eControlType type, const std::string& control_name)
+{
+ if (type == TYPE_VEC3D)
+ return (LLVector3d)sd;
+ else
+ {
+ CONTROL_ERRS << "Invalid LLVector3d value" << llendl;
+ return LLVector3d::zero;
+ }
+}
+
+template<>
+LLRect convert_from_llsd<LLRect>(const LLSD& sd, eControlType type, const std::string& control_name)
+{
+ if (type == TYPE_RECT)
+ return LLRect(sd);
+ else
+ {
+ CONTROL_ERRS << "Invalid rect value" << llendl;
+ return LLRect::null;
+ }
+}
+
+
+template<>
+LLColor4 convert_from_llsd<LLColor4>(const LLSD& sd, eControlType type, const std::string& control_name)
+{
+ if (type == TYPE_COL4)
+ {
+ LLColor4 color(sd);
+ if (color.mV[VRED] < 0.f || color.mV[VRED] > 1.f)
+ {
+ llwarns << "Color " << control_name << " value out of range " << llendl;
+ }
+ else if (color.mV[VGREEN] < 0.f || color.mV[VGREEN] > 1.f)
+ {
+ llwarns << "Color " << control_name << " value out of range " << llendl;
+ }
+ else if (color.mV[VBLUE] < 0.f || color.mV[VBLUE] > 1.f)
+ {
+ llwarns << "Color " << control_name << " value out of range " << llendl;
+ }
+ else if (color.mV[VALPHA] < 0.f || color.mV[VALPHA] > 1.f)
+ {
+ llwarns << "Color " << control_name << " value out of range " << llendl;
+ }
+
+ return LLColor4(sd);
+ }
+ else
+ {
+ CONTROL_ERRS << "Control " << control_name << " not a color" << llendl;
+ return LLColor4::white;
+ }
+}
+
+template<>
+LLColor3 convert_from_llsd<LLColor3>(const LLSD& sd, eControlType type, const std::string& control_name)
+{
+ if (type == TYPE_COL3)
+ return sd;
+ else
+ {
+ CONTROL_ERRS << "Invalid LLColor3 value" << llendl;
+ return LLColor3::white;
+ }
+}
+
+template<>
+LLSD convert_from_llsd<LLSD>(const LLSD& sd, eControlType type, const std::string& control_name)
+{
+ return sd;
+}
+
+
+#if TEST_CACHED_CONTROL
+
+#define DECL_LLCC(T, V) static LLCachedControl<T> mySetting_##T("TestCachedControl"#T, V)
+DECL_LLCC(U32, (U32)666);
+DECL_LLCC(S32, (S32)-666);
+DECL_LLCC(F32, (F32)-666.666);
+DECL_LLCC(bool, true);
+DECL_LLCC(BOOL, FALSE);
+static LLCachedControl<std::string> mySetting_string("TestCachedControlstring", "Default String Value");
+DECL_LLCC(LLVector3, LLVector3(1.0f, 2.0f, 3.0f));
+DECL_LLCC(LLVector3d, LLVector3d(6.0f, 5.0f, 4.0f));
+DECL_LLCC(LLRect, LLRect(0, 0, 100, 500));
+DECL_LLCC(LLColor4, LLColor4(0.0f, 0.5f, 1.0f));
+DECL_LLCC(LLColor3, LLColor3(1.0f, 0.f, 0.5f));
+DECL_LLCC(LLColor4U, LLColor4U(255, 200, 100, 255));
+
+LLSD test_llsd = LLSD()["testing1"] = LLSD()["testing2"];
+DECL_LLCC(LLSD, test_llsd);
+
+static LLCachedControl<std::string> test_BrowserHomePage("BrowserHomePage", "hahahahahha", "Not the real comment");
+
+void test_cached_control()
+{
+#define TEST_LLCC(T, V) if((T)mySetting_##T != V) llerrs << "Fail "#T << llendl
+ TEST_LLCC(U32, 666);
+ TEST_LLCC(S32, (S32)-666);
+ TEST_LLCC(F32, (F32)-666.666);
+ TEST_LLCC(bool, true);
+ TEST_LLCC(BOOL, FALSE);
+ if((std::string)mySetting_string != "Default String Value") llerrs << "Fail string" << llendl;
+ TEST_LLCC(LLVector3, LLVector3(1.0f, 2.0f, 3.0f));
+ TEST_LLCC(LLVector3d, LLVector3d(6.0f, 5.0f, 4.0f));
+ TEST_LLCC(LLRect, LLRect(0, 0, 100, 500));
+ TEST_LLCC(LLColor4, LLColor4(0.0f, 0.5f, 1.0f));
+ TEST_LLCC(LLColor3, LLColor3(1.0f, 0.f, 0.5f));
+ TEST_LLCC(LLColor4U, LLColor4U(255, 200, 100, 255));
+//There's no LLSD comparsion for LLCC yet. TEST_LLCC(LLSD, test_llsd);
+
+ if((std::string)test_BrowserHomePage != "http://www.secondlife.com") llerrs << "Fail BrowserHomePage" << llendl;
+}
+#endif // TEST_CACHED_CONTROL
diff --git a/indra/llxml/llcontrol.h b/indra/llxml/llcontrol.h
index a39a56aacd..7d94601568 100644
--- a/indra/llxml/llcontrol.h
+++ b/indra/llxml/llcontrol.h
@@ -33,11 +33,14 @@
#ifndef LL_LLCONTROL_H
#define LL_LLCONTROL_H
+#include "llboost.h"
#include "llevent.h"
#include "llnametable.h"
#include "llmap.h"
#include "llstring.h"
#include "llrect.h"
+#include "llrefcount.h"
+#include "llinstancetracker.h"
#include "llcontrolgroupreader.h"
@@ -53,7 +56,16 @@
#endif
#include <boost/bind.hpp>
+
+#if LL_WINDOWS
+ #pragma warning (push)
+ #pragma warning (disable : 4263) // boost::signals2::expired_slot::what() has const mismatch
+ #pragma warning (disable : 4264)
+#endif
#include <boost/signals2.hpp>
+#if LL_WINDOWS
+ #pragma warning (pop)
+#endif
#if LL_WINDOWS
# if (_MSC_VER >= 1300 && _MSC_VER < 1400)
@@ -65,7 +77,6 @@ class LLVector3;
class LLVector3d;
class LLColor4;
class LLColor3;
-class LLColor4U;
const BOOL NO_PERSIST = FALSE;
@@ -81,7 +92,6 @@ typedef enum e_control_type
TYPE_RECT,
TYPE_COL4,
TYPE_COL3,
- TYPE_COL4U,
TYPE_LLSD,
TYPE_COUNT
} eControlType;
@@ -89,7 +99,10 @@ typedef enum e_control_type
class LLControlVariable : public LLRefCount
{
friend class LLControlGroup;
- typedef boost::signals2::signal<void(const LLSD&)> signal_t;
+
+public:
+ typedef boost::signals2::signal<bool(LLControlVariable* control, const LLSD&), boost_boolean_combiner> validate_signal_t;
+ typedef boost::signals2::signal<void(LLControlVariable* control, const LLSD&)> commit_signal_t;
private:
std::string mName;
@@ -99,7 +112,8 @@ private:
bool mHideFromSettingsEditor;
std::vector<LLSD> mValues;
- signal_t mSignal;
+ commit_signal_t mCommitSignal;
+ validate_signal_t mValidateSignal;
public:
LLControlVariable(const std::string& name, eControlType type,
@@ -116,7 +130,9 @@ public:
void resetToDefault(bool fire_signal = false);
- signal_t* getSignal() { return &mSignal; }
+ commit_signal_t* getSignal() { return &mCommitSignal; } // shorthand for commit signal
+ commit_signal_t* getCommitSignal() { return &mCommitSignal; }
+ validate_signal_t* getValidateSignal() { return &mValidateSignal; }
bool isDefault() { return (mValues.size() == 1); }
bool isSaveValueDefault();
@@ -136,31 +152,55 @@ public:
void firePropertyChanged()
{
- mSignal(mValues.back());
+ mCommitSignal(this, mValues.back());
}
private:
LLSD getComparableValue(const LLSD& value);
bool llsd_compare(const LLSD& a, const LLSD & b);
-
};
+typedef LLPointer<LLControlVariable> LLControlVariablePtr;
+
+//! Helper functions for converting between static types and LLControl values
+template <class T>
+eControlType get_control_type()
+{
+ llwarns << "Usupported control type: " << typeid(T).name() << "." << llendl;
+ return TYPE_COUNT;
+}
+
+template <class T>
+LLSD convert_to_llsd(const T& in)
+{
+ // default implementation
+ return LLSD(in);
+}
+
+template <class T>
+T convert_from_llsd(const LLSD& sd, eControlType type, const std::string& control_name)
+{
+ // needs specialization
+ return T(sd);
+}
+
//const U32 STRING_CACHE_SIZE = 10000;
-class LLControlGroup : public LLControlGroupReader
+class LLControlGroup : public LLInstanceTracker<LLControlGroup, std::string>
{
protected:
- typedef std::map<std::string, LLPointer<LLControlVariable> > ctrl_name_table_t;
+ typedef std::map<std::string, LLControlVariablePtr > ctrl_name_table_t;
ctrl_name_table_t mNameTable;
- std::set<std::string> mWarnings;
std::string mTypeString[TYPE_COUNT];
eControlType typeStringToEnum(const std::string& typestr);
std::string typeEnumToString(eControlType typeenum);
public:
- LLControlGroup();
+ LLControlGroup(const std::string& name);
~LLControlGroup();
void cleanup();
- LLPointer<LLControlVariable> getControl(const std::string& name);
+ typedef LLInstanceTracker<LLControlGroup, std::string>::instance_iter instance_iter;
+
+ LLControlVariablePtr getControl(const std::string& name);
struct ApplyFunctor
{
@@ -178,33 +218,47 @@ public:
BOOL declareVec3(const std::string& name, const LLVector3 &initial_val,const std::string& comment, BOOL persist = TRUE);
BOOL declareVec3d(const std::string& name, const LLVector3d &initial_val, const std::string& comment, BOOL persist = TRUE);
BOOL declareRect(const std::string& name, const LLRect &initial_val, const std::string& comment, BOOL persist = TRUE);
- BOOL declareColor4U(const std::string& name, const LLColor4U &initial_val, const std::string& comment, BOOL persist = TRUE);
BOOL declareColor4(const std::string& name, const LLColor4 &initial_val, const std::string& comment, BOOL persist = TRUE);
BOOL declareColor3(const std::string& name, const LLColor3 &initial_val, const std::string& comment, BOOL persist = TRUE);
BOOL declareLLSD(const std::string& name, const LLSD &initial_val, const std::string& comment, BOOL persist = TRUE);
-
- std::string findString(const std::string& name);
- std::string getString(const std::string& name);
- LLWString getWString(const std::string& name);
- std::string getText(const std::string& name);
- LLVector3 getVector3(const std::string& name);
- LLVector3d getVector3d(const std::string& name);
- LLRect getRect(const std::string& name);
+ std::string getString(const std::string& name);
+ std::string getText(const std::string& name);
BOOL getBOOL(const std::string& name);
S32 getS32(const std::string& name);
F32 getF32(const std::string& name);
U32 getU32(const std::string& name);
+
+ LLWString getWString(const std::string& name);
+ LLVector3 getVector3(const std::string& name);
+ LLVector3d getVector3d(const std::string& name);
+ LLRect getRect(const std::string& name);
LLSD getLLSD(const std::string& name);
- // Note: If an LLColor4U control exists, it will cast it to the correct
- // LLColor4 for you.
LLColor4 getColor(const std::string& name);
- LLColor4U getColor4U(const std::string& name);
LLColor4 getColor4(const std::string& name);
LLColor3 getColor3(const std::string& name);
+ // generic getter
+ template<typename T> T get(const std::string& name)
+ {
+ LLControlVariable* control = getControl(name);
+ LLSD value;
+ eControlType type = TYPE_COUNT;
+
+ if (control)
+ {
+ value = control->get();
+ type = control->type();
+ }
+ else
+ {
+ llwarns << "Control " << name << " not found." << llendl;
+ }
+ return convert_from_llsd<T>(value, type, name);
+ }
+
void setBOOL(const std::string& name, BOOL val);
void setS32(const std::string& name, S32 val);
void setF32(const std::string& name, F32 val);
@@ -213,12 +267,26 @@ public:
void setVector3(const std::string& name, const LLVector3 &val);
void setVector3d(const std::string& name, const LLVector3d &val);
void setRect(const std::string& name, const LLRect &val);
- void setColor4U(const std::string& name, const LLColor4U &val);
void setColor4(const std::string& name, const LLColor4 &val);
- void setColor3(const std::string& name, const LLColor3 &val);
void setLLSD(const std::string& name, const LLSD& val);
- void setValue(const std::string& name, const LLSD& val);
+
+ // type agnostic setter that takes LLSD
+ void setUntypedValue(const std::string& name, const LLSD& val);
+
+ // generic setter
+ template<typename T> void set(const std::string& name, const T& val)
+ {
+ LLControlVariable* control = getControl(name);
+ if (control && control->isType(get_control_type<T>()))
+ {
+ control->set(convert_to_llsd(val));
+ }
+ else
+ {
+ llwarns << "Invalid control " << name << llendl;
+ }
+ }
BOOL controlExists(const std::string& name);
@@ -229,17 +297,166 @@ public:
U32 saveToFile(const std::string& filename, BOOL nondefault_only);
U32 loadFromFile(const std::string& filename, bool default_values = false);
void resetToDefaults();
+};
+
+//! Publish/Subscribe object to interact with LLControlGroups.
+
+//! Use an LLCachedControl instance to connect to a LLControlVariable
+//! without have to manually create and bind a listener to a local
+//! object.
+template <class T>
+class LLControlCache : public LLRefCount, public LLInstanceTracker<LLControlCache<T>, std::string>
+{
+public:
+ // This constructor will declare a control if it doesn't exist in the contol group
+ LLControlCache(LLControlGroup& group,
+ const std::string& name,
+ const T& default_value,
+ const std::string& comment)
+ : LLInstanceTracker<LLControlCache<T>, std::string >(name)
+ {
+ if(!group.controlExists(name))
+ {
+ if(!declareTypedControl(group, name, default_value, comment))
+ {
+ llerrs << "The control could not be created!!!" << llendl;
+ }
+ }
+
+ bindToControl(group, name);
+ }
+
+ LLControlCache(LLControlGroup& group,
+ const std::string& name)
+ : LLInstanceTracker<LLControlCache<T>, std::string >(name)
+ {
+ if(!group.controlExists(name))
+ {
+ llerrs << "Control named " << name << "not found." << llendl;
+ }
+
+ bindToControl(group, name);
+ }
+
+ ~LLControlCache()
+ {
+ }
+
+ const T& getValue() const { return mCachedValue; }
- // Ignorable Warnings
-
- // Add a config variable to be reset on resetWarnings()
- void addWarning(const std::string& name);
- BOOL getWarning(const std::string& name);
- void setWarning(const std::string& name, BOOL val);
-
- // Resets all ignorables
- void resetWarnings();
+private:
+ void bindToControl(LLControlGroup& group, const std::string& name)
+ {
+ LLControlVariablePtr controlp = group.getControl(name);
+ mType = controlp->type();
+ mCachedValue = convert_from_llsd<T>(controlp->get(), mType, name);
+
+ // Add a listener to the controls signal...
+ mConnection = controlp->getSignal()->connect(
+ boost::bind(&LLControlCache<T>::handleValueChange, this, _2)
+ );
+ mType = controlp->type();
+ }
+ bool declareTypedControl(LLControlGroup& group,
+ const std::string& name,
+ const T& default_value,
+ const std::string& comment)
+ {
+ LLSD init_value;
+ eControlType type = get_control_type<T>();
+ init_value = convert_to_llsd(default_value);
+ if(type < TYPE_COUNT)
+ {
+ group.declareControl(name, type, init_value, comment, FALSE);
+ return true;
+ }
+ return false;
+ }
+
+ bool handleValueChange(const LLSD& newvalue)
+ {
+ mCachedValue = convert_from_llsd<T>(newvalue, mType, "");
+ return true;
+ }
+
+private:
+ T mCachedValue;
+ eControlType mType;
+ boost::signals2::scoped_connection mConnection;
};
+template <typename T>
+class LLCachedControl
+{
+public:
+ LLCachedControl(LLControlGroup& group,
+ const std::string& name,
+ const T& default_value,
+ const std::string& comment = "Declared In Code")
+ {
+ mCachedControlPtr = LLControlCache<T>::getInstance(name);
+ if (mCachedControlPtr.isNull())
+ {
+ mCachedControlPtr = new LLControlCache<T>(group, name, default_value, comment);
+ }
+ }
+
+ LLCachedControl(LLControlGroup& group,
+ const std::string& name)
+ {
+ mCachedControlPtr = LLControlCache<T>::getInstance(name);
+ if (mCachedControlPtr.isNull())
+ {
+ mCachedControlPtr = new LLControlCache<T>(group, name);
+ }
+ }
+
+ operator const T&() const { return mCachedControlPtr->getValue(); }
+ operator boost::function<const T&()> () const { return boost::function<const T&()>(*this); }
+ const T& operator()() { return mCachedControlPtr->getValue(); }
+
+private:
+ LLPointer<LLControlCache<T> > mCachedControlPtr;
+};
+
+template <> eControlType get_control_type<U32>();
+template <> eControlType get_control_type<S32>();
+template <> eControlType get_control_type<F32>();
+template <> eControlType get_control_type<bool>();
+// Yay BOOL, its really an S32.
+//template <> eControlType get_control_type<BOOL> ()
+template <> eControlType get_control_type<std::string>();
+template <> eControlType get_control_type<LLVector3>();
+template <> eControlType get_control_type<LLVector3d>();
+template <> eControlType get_control_type<LLRect>();
+template <> eControlType get_control_type<LLColor4>();
+template <> eControlType get_control_type<LLColor3>();
+template <> eControlType get_control_type<LLSD>();
+
+template <> LLSD convert_to_llsd<U32>(const U32& in);
+template <> LLSD convert_to_llsd<LLVector3>(const LLVector3& in);
+template <> LLSD convert_to_llsd<LLVector3d>(const LLVector3d& in);
+template <> LLSD convert_to_llsd<LLRect>(const LLRect& in);
+template <> LLSD convert_to_llsd<LLColor4>(const LLColor4& in);
+template <> LLSD convert_to_llsd<LLColor3>(const LLColor3& in);
+
+template<> std::string convert_from_llsd<std::string>(const LLSD& sd, eControlType type, const std::string& control_name);
+template<> LLWString convert_from_llsd<LLWString>(const LLSD& sd, eControlType type, const std::string& control_name);
+template<> LLVector3 convert_from_llsd<LLVector3>(const LLSD& sd, eControlType type, const std::string& control_name);
+template<> LLVector3d convert_from_llsd<LLVector3d>(const LLSD& sd, eControlType type, const std::string& control_name);
+template<> LLRect convert_from_llsd<LLRect>(const LLSD& sd, eControlType type, const std::string& control_name);
+template<> bool convert_from_llsd<bool>(const LLSD& sd, eControlType type, const std::string& control_name);
+template<> S32 convert_from_llsd<S32>(const LLSD& sd, eControlType type, const std::string& control_name);
+template<> F32 convert_from_llsd<F32>(const LLSD& sd, eControlType type, const std::string& control_name);
+template<> U32 convert_from_llsd<U32>(const LLSD& sd, eControlType type, const std::string& control_name);
+template<> LLColor3 convert_from_llsd<LLColor3>(const LLSD& sd, eControlType type, const std::string& control_name);
+template<> LLColor4 convert_from_llsd<LLColor4>(const LLSD& sd, eControlType type, const std::string& control_name);
+template<> LLSD convert_from_llsd<LLSD>(const LLSD& sd, eControlType type, const std::string& control_name);
+
+//#define TEST_CACHED_CONTROL 1
+#ifdef TEST_CACHED_CONTROL
+void test_cached_control();
+#endif // TEST_CACHED_CONTROL
+
#endif
diff --git a/indra/llxml/llcontrolgroupreader.h b/indra/llxml/llcontrolgroupreader.h
index 960b19036e..116ea2eae0 100644
--- a/indra/llxml/llcontrolgroupreader.h
+++ b/indra/llxml/llcontrolgroupreader.h
@@ -3,7 +3,30 @@
* @brief Interface providing readonly access to LLControlGroup (intended for unit testing)
*
* $LicenseInfo:firstyear=2001&license=viewergpl$
+ *
* Copyright (c) 2001-2009, Linden Research, Inc.
+ *
+ * Second Life Viewer Source Code
+ * The source code in this file ("Source Code") is provided by Linden Lab
+ * to you under the terms of the GNU General Public License, version 2.0
+ * ("GPL"), unless you have obtained a separate licensing agreement
+ * ("Other License"), formally executed by you and Linden Lab. Terms of
+ * the GPL can be found in doc/GPL-license.txt in this distribution, or
+ * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
+ *
+ * There are special exceptions to the terms and conditions of the GPL as
+ * it is applied to this Source Code. View the full text of the exception
+ * in the file doc/FLOSS-exception.txt in this software distribution, or
+ * online at
+ * http://secondlifegrid.net/programs/open_source/licensing/flossexception
+ *
+ * By copying, modifying or distributing this software, you acknowledge
+ * that you have read and understood your obligations described above,
+ * and agree to abide by those obligations.
+ *
+ * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+ * COMPLETENESS OR PERFORMANCE.
* $/LicenseInfo$
*/
@@ -13,9 +36,11 @@
#include "stdtypes.h"
#include <string>
-// Many of the types below are commented out because for the purposes of the early testing we're doing,
-// we don't need them and we don't want to pull in all the machinery to support them.
-// But the model is here for future unit test extensions.
+#include "v3math.h"
+#include "v3dmath.h"
+#include "v3color.h"
+#include "v4color.h"
+#include "llrect.h"
class LLControlGroupReader
{
@@ -23,22 +48,32 @@ public:
LLControlGroupReader() {}
virtual ~LLControlGroupReader() {}
- virtual std::string getString(const std::string& name) = 0;
- //virtual LLWString getWString(const std::string& name) = 0;
- virtual std::string getText(const std::string& name) = 0;
- //virtual LLVector3 getVector3(const std::string& name) = 0;
- //virtual LLVector3d getVector3d(const std::string& name) = 0;
- //virtual LLRect getRect(const std::string& name) = 0;
- virtual BOOL getBOOL(const std::string& name) = 0;
- virtual S32 getS32(const std::string& name) = 0;
- virtual F32 getF32(const std::string& name) = 0;
- virtual U32 getU32(const std::string& name) = 0;
- //virtual LLSD getLLSD(const std::string& name) = 0;
-
- //virtual LLColor4 getColor(const std::string& name) = 0;
- //virtual LLColor4U getColor4U(const std::string& name) = 0;
- //virtual LLColor4 getColor4(const std::string& name) = 0;
- //virtual LLColor3 getColor3(const std::string& name) = 0;
+ virtual std::string getString(const std::string& name) { return ""; }
+ virtual LLWString getWString(const std::string& name) { return LLWString(); }
+ virtual std::string getText(const std::string& name) { return ""; }
+ virtual LLVector3 getVector3(const std::string& name) { return LLVector3(); }
+ virtual LLVector3d getVector3d(const std::string& name) { return LLVector3d(); }
+ virtual LLRect getRect(const std::string& name) { return LLRect(); }
+ virtual BOOL getBOOL(const std::string& name) { return FALSE; }
+ virtual S32 getS32(const std::string& name) { return 0; }
+ virtual F32 getF32(const std::string& name) {return 0.0f; }
+ virtual U32 getU32(const std::string& name) {return 0; }
+ virtual LLSD getLLSD(const std::string& name) { return LLSD(); }
+
+ virtual LLColor4 getColor(const std::string& name) { return LLColor4(); }
+ virtual LLColor4 getColor4(const std::string& name) { return LLColor4(); }
+ virtual LLColor3 getColor3(const std::string& name) { return LLColor3(); }
+
+ virtual void setBOOL(const std::string& name, BOOL val) {}
+ virtual void setS32(const std::string& name, S32 val) {}
+ virtual void setF32(const std::string& name, F32 val) {}
+ virtual void setU32(const std::string& name, U32 val) {}
+ virtual void setString(const std::string& name, const std::string& val) {}
+ virtual void setVector3(const std::string& name, const LLVector3 &val) {}
+ virtual void setVector3d(const std::string& name, const LLVector3d &val) {}
+ virtual void setRect(const std::string& name, const LLRect &val) {}
+ virtual void setColor4(const std::string& name, const LLColor4 &val) {}
+ virtual void setLLSD(const std::string& name, const LLSD& val) {}
};
#endif /* LL_LLCONTROLGROUPREADER_H */
diff --git a/indra/llxml/llxmlnode.cpp b/indra/llxml/llxmlnode.cpp
index 800b13573f..07cc612a0a 100644
--- a/indra/llxml/llxmlnode.cpp
+++ b/indra/llxml/llxmlnode.cpp
@@ -47,6 +47,7 @@
#include "llquaternion.h"
#include "llstring.h"
#include "lluuid.h"
+#include "lldir.h"
const S32 MAX_COLUMN_WIDTH = 80;
@@ -64,6 +65,7 @@ LLXMLNode::LLXMLNode() :
mPrecision(64),
mType(TYPE_CONTAINER),
mEncoding(ENCODING_DEFAULT),
+ mLineNumber(-1),
mParent(NULL),
mChildren(NULL),
mAttributes(),
@@ -85,6 +87,7 @@ LLXMLNode::LLXMLNode(const char* name, BOOL is_attribute) :
mPrecision(64),
mType(TYPE_CONTAINER),
mEncoding(ENCODING_DEFAULT),
+ mLineNumber(-1),
mParent(NULL),
mChildren(NULL),
mAttributes(),
@@ -106,6 +109,7 @@ LLXMLNode::LLXMLNode(LLStringTableEntry* name, BOOL is_attribute) :
mPrecision(64),
mType(TYPE_CONTAINER),
mEncoding(ENCODING_DEFAULT),
+ mLineNumber(-1),
mParent(NULL),
mChildren(NULL),
mAttributes(),
@@ -145,7 +149,7 @@ LLXMLNodePtr LLXMLNode::deepCopy()
if (mChildren.notNull())
{
for (LLXMLChildList::iterator iter = mChildren->map.begin();
- iter != mChildren->map.end(); ++iter)
+ iter != mChildren->map.end(); ++iter)
{
newnode->addChild(iter->second->deepCopy());
}
@@ -226,6 +230,10 @@ BOOL LLXMLNode::removeChild(LLXMLNode *target_child)
{
mChildren->head = target_child->mNext;
}
+ if (target_child == mChildren->tail)
+ {
+ mChildren->tail = target_child->mPrev;
+ }
LLXMLNodePtr prev = target_child->mPrev;
LLXMLNodePtr next = target_child->mNext;
@@ -294,6 +302,22 @@ void LLXMLNode::addChild(LLXMLNodePtr new_child, LLXMLNodePtr after_child)
mChildren->tail = new_child;
}
}
+ // if after_child == parent, then put new_child at beginning
+ else if (after_child == this)
+ {
+ // add to front of list
+ new_child->mNext = mChildren->head;
+ if (mChildren->head)
+ {
+ mChildren->head->mPrev = new_child;
+ mChildren->head = new_child;
+ }
+ else // no children
+ {
+ mChildren->head = new_child;
+ mChildren->tail = new_child;
+ }
+ }
else
{
if (after_child->mNext.notNull())
@@ -387,6 +411,7 @@ void XMLCALL StartXMLNode(void *userData,
{
// Create a new node
LLXMLNode *new_node_ptr = new LLXMLNode(name, FALSE);
+
LLXMLNodePtr new_node = new_node_ptr;
new_node->mID.clear();
LLXMLNodePtr ptr_new_node = new_node;
@@ -401,7 +426,8 @@ void XMLCALL StartXMLNode(void *userData,
}
new_node_ptr->mParser = parent->mParser;
-
+ new_node_ptr->setLineNumber(XML_GetCurrentLineNumber(*new_node_ptr->mParser));
+
// Set the current active node to the new node
XML_Parser *parser = parent->mParser;
XML_SetUserData(*parser, (void *)new_node_ptr);
@@ -492,6 +518,7 @@ void XMLCALL StartXMLNode(void *userData,
if (!new_node->getAttribute(attr_name.c_str(), attr_node, FALSE))
{
attr_node = new LLXMLNode(attr_name.c_str(), TRUE);
+ attr_node->setLineNumber(XML_GetCurrentLineNumber(*new_node_ptr->mParser));
}
attr_node->setValue(attr_value);
new_node->addChild(attr_node);
@@ -836,12 +863,66 @@ BOOL LLXMLNode::isFullyDefault()
}
// static
-void LLXMLNode::writeHeaderToFile(LLFILE *fOut)
+bool LLXMLNode::getLayeredXMLNode(const std::string &xui_filename, LLXMLNodePtr& root,
+ const std::vector<std::string>& paths)
{
- fprintf(fOut, "<?xml version=\"1.0\" encoding=\"utf-8\" standalone=\"yes\" ?>\n");
+ std::string full_filename = gDirUtilp->findSkinnedFilename(paths.front(), xui_filename);
+ if (full_filename.empty())
+ {
+ return false;
+ }
+
+ if (!LLXMLNode::parseFile(full_filename, root, NULL))
+ {
+ // try filename as passed in since sometimes we load an xml file from a user-supplied path
+ if (!LLXMLNode::parseFile(xui_filename, root, NULL))
+ {
+ llwarns << "Problem reading UI description file: " << xui_filename << llendl;
+ return false;
+ }
+ }
+
+ LLXMLNodePtr updateRoot;
+
+ std::vector<std::string>::const_iterator itor;
+
+ for (itor = paths.begin(), ++itor; itor != paths.end(); ++itor)
+ {
+ std::string nodeName;
+ std::string updateName;
+
+ std::string layer_filename = gDirUtilp->findSkinnedFilename((*itor), xui_filename);
+ if(layer_filename.empty())
+ {
+ // no localized version of this file, that's ok, keep looking
+ continue;
+ }
+
+ if (!LLXMLNode::parseFile(layer_filename, updateRoot, NULL))
+ {
+ llwarns << "Problem reading localized UI description file: " << (*itor) + gDirUtilp->getDirDelimiter() + xui_filename << llendl;
+ return false;
+ }
+
+ updateRoot->getAttributeString("name", updateName);
+ root->getAttributeString("name", nodeName);
+
+ if (updateName == nodeName)
+ {
+ LLXMLNode::updateNode(root, updateRoot);
+ }
+ }
+
+ return true;
}
-void LLXMLNode::writeToFile(LLFILE *fOut, const std::string& indent)
+// static
+void LLXMLNode::writeHeaderToFile(LLFILE *out_file)
+{
+ fprintf(out_file, "<?xml version=\"1.0\" encoding=\"utf-8\" standalone=\"yes\" ?>\n");
+}
+
+void LLXMLNode::writeToFile(LLFILE *out_file, const std::string& indent, bool use_type_decorations)
{
if (isFullyDefault())
{
@@ -850,15 +931,16 @@ void LLXMLNode::writeToFile(LLFILE *fOut, const std::string& indent)
}
std::ostringstream ostream;
- writeToOstream(ostream, indent);
+ writeToOstream(ostream, indent, use_type_decorations);
std::string outstring = ostream.str();
- if (fwrite(outstring.c_str(), 1, outstring.length(), fOut) != outstring.length())
+ size_t written = fwrite(outstring.c_str(), 1, outstring.length(), out_file);
+ if (written != outstring.length())
{
llwarns << "Short write" << llendl;
}
}
-void LLXMLNode::writeToOstream(std::ostream& output_stream, const std::string& indent)
+void LLXMLNode::writeToOstream(std::ostream& output_stream, const std::string& indent, bool use_type_decorations)
{
if (isFullyDefault())
{
@@ -872,84 +954,86 @@ void LLXMLNode::writeToOstream(std::ostream& output_stream, const std::string& i
BOOL has_default_length = mDefault.isNull()?FALSE:(mLength == mDefault->mLength);
// stream the name
- output_stream << indent << "<" << mName->mString;
+ output_stream << indent << "<" << mName->mString << "\n";
- // ID
- if (mID != "")
+ if (use_type_decorations)
{
- output_stream << " id=\"" << mID << "\"";
- }
+ // ID
+ if (mID != "")
+ {
+ output_stream << indent << " id=\"" << mID << "\"\n";
+ }
- // Type
- if (!has_default_type)
- {
- switch (mType)
+ // Type
+ if (!has_default_type)
{
- case TYPE_BOOLEAN:
- output_stream << " type=\"boolean\"";
- break;
- case TYPE_INTEGER:
- output_stream << " type=\"integer\"";
- break;
- case TYPE_FLOAT:
- output_stream << " type=\"float\"";
- break;
- case TYPE_STRING:
- output_stream << " type=\"string\"";
- break;
- case TYPE_UUID:
- output_stream << " type=\"uuid\"";
- break;
- case TYPE_NODEREF:
- output_stream << " type=\"noderef\"";
- break;
- default:
- // default on switch(enum) eliminates a warning on linux
- break;
- };
- }
+ switch (mType)
+ {
+ case TYPE_BOOLEAN:
+ output_stream << indent << " type=\"boolean\"\n";
+ break;
+ case TYPE_INTEGER:
+ output_stream << indent << " type=\"integer\"\n";
+ break;
+ case TYPE_FLOAT:
+ output_stream << indent << " type=\"float\"\n";
+ break;
+ case TYPE_STRING:
+ output_stream << indent << " type=\"string\"\n";
+ break;
+ case TYPE_UUID:
+ output_stream << indent << " type=\"uuid\"\n";
+ break;
+ case TYPE_NODEREF:
+ output_stream << indent << " type=\"noderef\"\n";
+ break;
+ default:
+ // default on switch(enum) eliminates a warning on linux
+ break;
+ };
+ }
- // Encoding
- if (!has_default_encoding)
- {
- switch (mEncoding)
+ // Encoding
+ if (!has_default_encoding)
{
- case ENCODING_DECIMAL:
- output_stream << " encoding=\"decimal\"";
- break;
- case ENCODING_HEX:
- output_stream << " encoding=\"hex\"";
- break;
- /*case ENCODING_BASE32:
- output_stream << " encoding=\"base32\"";
- break;*/
- default:
- // default on switch(enum) eliminates a warning on linux
- break;
- };
- }
+ switch (mEncoding)
+ {
+ case ENCODING_DECIMAL:
+ output_stream << indent << " encoding=\"decimal\"\n";
+ break;
+ case ENCODING_HEX:
+ output_stream << indent << " encoding=\"hex\"\n";
+ break;
+ /*case ENCODING_BASE32:
+ output_stream << indent << " encoding=\"base32\"\n";
+ break;*/
+ default:
+ // default on switch(enum) eliminates a warning on linux
+ break;
+ };
+ }
- // Precision
- if (!has_default_precision && (mType == TYPE_INTEGER || mType == TYPE_FLOAT))
- {
- output_stream << " precision=\"" << mPrecision << "\"";
- }
+ // Precision
+ if (!has_default_precision && (mType == TYPE_INTEGER || mType == TYPE_FLOAT))
+ {
+ output_stream << indent << " precision=\"" << mPrecision << "\"\n";
+ }
- // Version
- if (mVersionMajor > 0 || mVersionMinor > 0)
- {
- output_stream << " version=\"" << mVersionMajor << "." << mVersionMinor << "\"";
- }
+ // Version
+ if (mVersionMajor > 0 || mVersionMinor > 0)
+ {
+ output_stream << indent << " version=\"" << mVersionMajor << "." << mVersionMinor << "\"\n";
+ }
- // Array length
- if (!has_default_length && mLength > 0)
- {
- output_stream << " length=\"" << mLength << "\"";
+ // Array length
+ if (!has_default_length && mLength > 0)
+ {
+ output_stream << indent << " length=\"" << mLength << "\"\n";
+ }
}
{
// Write out attributes
- S32 col_pos = 0;
LLXMLAttribList::const_iterator attr_itr;
LLXMLAttribList::const_iterator attr_end = mAttributes.end();
for (attr_itr = mAttributes.begin(); attr_itr != attr_end; ++attr_itr)
@@ -958,12 +1042,13 @@ void LLXMLNode::writeToOstream(std::ostream& output_stream, const std::string& i
if (child->mDefault.isNull() || child->mDefault->mValue != child->mValue)
{
std::string attr = child->mName->mString;
- if (attr == "id" ||
- attr == "type" ||
- attr == "encoding" ||
- attr == "precision" ||
- attr == "version" ||
- attr == "length")
+ if (use_type_decorations
+ && (attr == "id" ||
+ attr == "type" ||
+ attr == "encoding" ||
+ attr == "precision" ||
+ attr == "version" ||
+ attr == "length"))
{
continue; // skip built-in attributes
}
@@ -971,17 +1056,14 @@ void LLXMLNode::writeToOstream(std::ostream& output_stream, const std::string& i
std::string attr_str = llformat(" %s=\"%s\"",
attr.c_str(),
escapeXML(child->mValue).c_str());
- if (col_pos + (S32)attr_str.length() > MAX_COLUMN_WIDTH)
- {
- output_stream << "\n" << indent << " ";
- col_pos = 4;
- }
- col_pos += attr_str.length();
- output_stream << attr_str;
+ output_stream << indent << attr_str << "\n";
}
}
}
+ // erase last \n before attaching final > or />
+ output_stream.seekp(-1, std::ios::cur);
+
if (mChildren.isNull() && mValue == "")
{
output_stream << " />\n";
@@ -993,16 +1075,16 @@ void LLXMLNode::writeToOstream(std::ostream& output_stream, const std::string& i
if (mChildren.notNull())
{
// stream non-attributes
- std::string next_indent = indent + "\t";
+ std::string next_indent = indent + " ";
for (LLXMLNode* child = getFirstChild(); child; child = child->getNextSibling())
{
- child->writeToOstream(output_stream, next_indent);
+ child->writeToOstream(output_stream, next_indent, use_type_decorations);
}
}
if (!mValue.empty())
{
std::string contents = getTextContents();
- output_stream << indent << "\t" << escapeXML(contents) << "\n";
+ output_stream << indent << " " << escapeXML(contents) << "\n";
}
output_stream << indent << "</" << mName->mString << ">\n";
}
@@ -2475,14 +2557,15 @@ std::string LLXMLNode::escapeXML(const std::string& xml)
return out;
}
-void LLXMLNode::setStringValue(U32 length, const std::string *array)
+void LLXMLNode::setStringValue(U32 length, const std::string *strings)
{
if (length == 0) return;
std::string new_value;
for (U32 pos=0; pos<length; ++pos)
{
- new_value.append(escapeXML(array[pos]));
+ // *NOTE: Do not escape strings here - do it on output
+ new_value.append( strings[pos] );
if (pos < length-1) new_value.append(" ");
}
@@ -3150,6 +3233,19 @@ LLXMLNodePtr LLXMLNode::getNextSibling() const
return ret;
}
+std::string LLXMLNode::getSanitizedValue() const
+{
+ if (mIsAttribute)
+ {
+ return getValue() ;
+ }
+ else
+ {
+ return getTextContents();
+ }
+}
+
+
std::string LLXMLNode::getTextContents() const
{
std::string msg;
@@ -3215,3 +3311,13 @@ std::string LLXMLNode::getTextContents() const
}
return msg;
}
+
+void LLXMLNode::setLineNumber(S32 line_number)
+{
+ mLineNumber = line_number;
+}
+
+S32 LLXMLNode::getLineNumber()
+{
+ return mLineNumber;
+}
diff --git a/indra/llxml/llxmlnode.h b/indra/llxml/llxmlnode.h
index d4e127b05c..818d774f73 100644
--- a/indra/llxml/llxmlnode.h
+++ b/indra/llxml/llxmlnode.h
@@ -44,10 +44,11 @@
#include <map>
#include "indra_constants.h"
-#include "llmemory.h"
-#include "llthread.h"
+#include "llpointer.h"
+#include "llthread.h" // LLThreadSafeRefCount
#include "llstring.h"
#include "llstringtable.h"
+#include "llfile.h"
class LLVector3;
@@ -153,9 +154,19 @@ public:
LLXMLNodePtr& node,
LLXMLNodePtr& update_node);
static LLXMLNodePtr replaceNode(LLXMLNodePtr node, LLXMLNodePtr replacement_node);
- static void writeHeaderToFile(LLFILE *fOut);
- void writeToFile(LLFILE *fOut, const std::string& indent = std::string());
- void writeToOstream(std::ostream& output_stream, const std::string& indent = std::string());
+
+ static bool getLayeredXMLNode(const std::string &xui_filename, LLXMLNodePtr& root,
+ const std::vector<std::string>& paths);
+
+
+ // Write standard XML file header:
+ // <?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+ static void writeHeaderToFile(LLFILE *out_file);
+
+ // Write XML to file with one attribute per line.
+ // XML escapes values as they are written.
+ void writeToFile(LLFILE *out_file, const std::string& indent = std::string(), bool use_type_decorations=true);
+ void writeToOstream(std::ostream& output_stream, const std::string& indent = std::string(), bool use_type_decorations=true);
// Utility
void findName(const std::string& name, LLXMLNodeList &results);
@@ -207,6 +218,7 @@ public:
U32 getLength() const { return mLength; }
U32 getPrecision() const { return mPrecision; }
const std::string& getValue() const { return mValue; }
+ std::string getSanitizedValue() const;
std::string getTextContents() const;
const LLStringTableEntry* getName() const { return mName; }
BOOL hasName(const char* name) const { return mName == gStringTable.checkStringEntry(name); }
@@ -227,6 +239,8 @@ public:
bool getAttribute(const char* name, LLXMLNodePtr& node, BOOL use_default_if_missing = TRUE);
bool getAttribute(const LLStringTableEntry* name, LLXMLNodePtr& node, BOOL use_default_if_missing = TRUE);
+ S32 getLineNumber();
+
// The following skip over attributes
LLXMLNodePtr getFirstChild() const;
LLXMLNodePtr getNextSibling() const;
@@ -262,6 +276,8 @@ public:
void setName(const std::string& name);
void setName(LLStringTableEntry* name);
+ void setLineNumber(S32 line_number);
+
// Escapes " (quot) ' (apos) & (amp) < (lt) > (gt)
static std::string escapeXML(const std::string& xml);
@@ -300,6 +316,7 @@ public:
U32 mPrecision; // The number of BITS per array item
ValueType mType; // The value type
Encoding mEncoding; // The value encoding
+ S32 mLineNumber; // line number in source file, if applicable
LLXMLNode* mParent; // The parent node
LLXMLChildrenPtr mChildren; // The child nodes
@@ -312,7 +329,11 @@ public:
protected:
LLStringTableEntry *mName; // The name of this node
- std::string mValue; // The value of this node (use getters/setters only)
+
+ // The value of this node (use getters/setters only)
+ // Values are not XML-escaped in memory
+ // They may contain " (quot) ' (apos) & (amp) < (lt) > (gt)
+ std::string mValue;
LLXMLNodePtr mDefault; // Mirror node in the default tree
diff --git a/indra/llxuixml/CMakeLists.txt b/indra/llxuixml/CMakeLists.txt
new file mode 100644
index 0000000000..daed4de6ce
--- /dev/null
+++ b/indra/llxuixml/CMakeLists.txt
@@ -0,0 +1,45 @@
+# -*- cmake -*-
+
+project(llxuixml)
+
+include(00-Common)
+include(LLCommon)
+include(LLMath)
+include(LLXML)
+
+include_directories(
+ ${LLCOMMON_INCLUDE_DIRS}
+ ${LLMATH_INCLUDE_DIRS}
+ ${LLXML_INCLUDE_DIRS}
+ )
+
+set(llxuixml_SOURCE_FILES
+ llinitparam.cpp
+ lltrans.cpp
+ lluicolor.cpp
+ llxuiparser.cpp
+ )
+
+set(llxuixml_HEADER_FILES
+ CMakeLists.txt
+
+ llinitparam.h
+ lltrans.h
+ llregistry.h
+ lluicolor.h
+ llxuiparser.h
+ )
+
+set_source_files_properties(${llxuixml_HEADER_FILES}
+ PROPERTIES HEADER_FILE_ONLY TRUE)
+
+list(APPEND llxuixml_SOURCE_FILES ${llxuixml_HEADER_FILES})
+
+add_library (llxuixml ${llxuixml_SOURCE_FILES})
+# Libraries on which this library depends, needed for Linux builds
+# Sort by high-level to low-level
+target_link_libraries(llxuixml
+ llxml
+ llcommon
+ llmath
+ )
diff --git a/indra/llxuixml/llinitparam.cpp b/indra/llxuixml/llinitparam.cpp
new file mode 100644
index 0000000000..d35e7b40f8
--- /dev/null
+++ b/indra/llxuixml/llinitparam.cpp
@@ -0,0 +1,524 @@
+/**
+ * @file llinitparam.cpp
+ * @brief parameter block abstraction for creating complex objects and
+ * parsing construction parameters from xml and LLSD
+ *
+ * $LicenseInfo:firstyear=2008&license=viewergpl$
+ *
+ * Copyright (c) 2008-2009, Linden Research, Inc.
+ *
+ * Second Life Viewer Source Code
+ * The source code in this file ("Source Code") is provided by Linden Lab
+ * to you under the terms of the GNU General Public License, version 2.0
+ * ("GPL"), unless you have obtained a separate licensing agreement
+ * ("Other License"), formally executed by you and Linden Lab. Terms of
+ * the GPL can be found in doc/GPL-license.txt in this distribution, or
+ * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
+ *
+ * There are special exceptions to the terms and conditions of the GPL as
+ * it is applied to this Source Code. View the full text of the exception
+ * in the file doc/FLOSS-exception.txt in this software distribution, or
+ * online at
+ * http://secondlifegrid.net/programs/open_source/licensing/flossexception
+ *
+ * By copying, modifying or distributing this software, you acknowledge
+ * that you have read and understood your obligations described above,
+ * and agree to abide by those obligations.
+ *
+ * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+ * COMPLETENESS OR PERFORMANCE.
+ * $/LicenseInfo$
+ */
+
+#include "linden_common.h"
+
+#include "llinitparam.h"
+
+
+namespace LLInitParam
+{
+ BlockDescriptor BaseBlock::sBlockDescriptor;
+
+ //
+ // Param
+ //
+ Param::Param(BaseBlock* enclosing_block)
+ : mIsProvided(false)
+ {
+ const U8* my_addr = reinterpret_cast<const U8*>(this);
+ const U8* block_addr = reinterpret_cast<const U8*>(enclosing_block);
+ mEnclosingBlockOffset = (S16)(block_addr - my_addr);
+ }
+
+ //
+ // Parser
+ //
+ Parser::~Parser()
+ {}
+
+ void Parser::parserWarning(const std::string& message)
+ {
+ if (mParseSilently) return;
+ llwarns << message << llendl;
+ }
+
+ void Parser::parserError(const std::string& message)
+ {
+ if (mParseSilently) return;
+ llerrs << message << llendl;
+ }
+
+
+ //
+ // BlockDescriptor
+ //
+ void BlockDescriptor::aggregateBlockData(BlockDescriptor& src_block_data)
+ {
+ mNamedParams.insert(src_block_data.mNamedParams.begin(), src_block_data.mNamedParams.end());
+ mSynonyms.insert(src_block_data.mSynonyms.begin(), src_block_data.mSynonyms.end());
+ std::copy(src_block_data.mUnnamedParams.begin(), src_block_data.mUnnamedParams.end(), std::back_inserter(mUnnamedParams));
+ std::copy(src_block_data.mValidationList.begin(), src_block_data.mValidationList.end(), std::back_inserter(mValidationList));
+ std::copy(src_block_data.mAllParams.begin(), src_block_data.mAllParams.end(), std::back_inserter(mAllParams));
+ }
+
+ //
+ // BaseBlock
+ //
+ BaseBlock::BaseBlock()
+ : mLastChangedParam(0),
+ mChangeVersion(0)
+ {}
+
+ BaseBlock::~BaseBlock()
+ {}
+
+ // called by each derived class in least to most derived order
+ void BaseBlock::init(BlockDescriptor& descriptor, BlockDescriptor& base_descriptor, size_t block_size)
+ {
+ mBlockDescriptor = &descriptor;
+
+ descriptor.mCurrentBlockPtr = this;
+ descriptor.mMaxParamOffset = block_size;
+
+ switch(descriptor.mInitializationState)
+ {
+ case BlockDescriptor::UNINITIALIZED:
+ // copy params from base class here
+ descriptor.aggregateBlockData(base_descriptor);
+
+ descriptor.mInitializationState = BlockDescriptor::INITIALIZING;
+ break;
+ case BlockDescriptor::INITIALIZING:
+ descriptor.mInitializationState = BlockDescriptor::INITIALIZED;
+ break;
+ case BlockDescriptor::INITIALIZED:
+ // nothing to do
+ break;
+ }
+ }
+
+ param_handle_t BaseBlock::getHandleFromParam(const Param* param) const
+ {
+ const U8* param_address = reinterpret_cast<const U8*>(param);
+ const U8* baseblock_address = reinterpret_cast<const U8*>(this);
+ return (param_address - baseblock_address);
+ }
+
+ bool BaseBlock::submitValue(const Parser::name_stack_t& name_stack, Parser& p, bool silent)
+ {
+ if (!deserializeBlock(p, boost::make_iterator_range(name_stack.begin(), name_stack.end())))
+ {
+ if (!silent)
+ {
+ p.parserWarning(llformat("Failed to parse parameter \"%s\"", p.getCurrentElementName().c_str()));
+ }
+ return false;
+ }
+ return true;
+ }
+
+
+ bool BaseBlock::validateBlock(bool silent) const
+ {
+ const BlockDescriptor& block_data = getBlockDescriptor();
+ for (BlockDescriptor::param_validation_list_t::const_iterator it = block_data.mValidationList.begin(); it != block_data.mValidationList.end(); ++it)
+ {
+ const Param* param = getParamFromHandle(it->first);
+ if (!it->second(param))
+ {
+ if (!silent)
+ {
+ llwarns << "Invalid param \"" << getParamName(block_data, param) << "\"" << llendl;
+ }
+ return false;
+ }
+ }
+ return true;
+ }
+
+ bool BaseBlock::serializeBlock(Parser& parser, Parser::name_stack_t name_stack, const LLInitParam::BaseBlock* diff_block) const
+ {
+ // named param is one like LLView::Params::follows
+ // unnamed param is like LLView::Params::rect - implicit
+ const BlockDescriptor& block_data = getBlockDescriptor();
+
+ for (BlockDescriptor::param_list_t::const_iterator it = block_data.mUnnamedParams.begin();
+ it != block_data.mUnnamedParams.end();
+ ++it)
+ {
+ param_handle_t param_handle = (*it)->mParamHandle;
+ const Param* param = getParamFromHandle(param_handle);
+ ParamDescriptor::serialize_func_t serialize_func = (*it)->mSerializeFunc;
+ if (serialize_func)
+ {
+ const Param* diff_param = diff_block ? diff_block->getParamFromHandle(param_handle) : NULL;
+ // each param descriptor remembers its serial number
+ // so we can inspect the same param under different names
+ // and see that it has the same number
+ (*it)->mGeneration = parser.newParseGeneration();
+ name_stack.push_back(std::make_pair("", (*it)->mGeneration));
+ serialize_func(*param, parser, name_stack, diff_param);
+ name_stack.pop_back();
+ }
+ }
+
+ for(BlockDescriptor::param_map_t::const_iterator it = block_data.mNamedParams.begin();
+ it != block_data.mNamedParams.end();
+ ++it)
+ {
+ param_handle_t param_handle = it->second->mParamHandle;
+ const Param* param = getParamFromHandle(param_handle);
+ ParamDescriptor::serialize_func_t serialize_func = it->second->mSerializeFunc;
+ if (serialize_func)
+ {
+ // Ensure this param has not already been serialized
+ // Prevents <rect> from being serialized as its own tag.
+ bool duplicate = false;
+ for (BlockDescriptor::param_list_t::const_iterator it2 = block_data.mUnnamedParams.begin();
+ it2 != block_data.mUnnamedParams.end();
+ ++it2)
+ {
+ if (param_handle == (*it2)->mParamHandle)
+ {
+ duplicate = true;
+ break;
+ }
+ }
+
+ //FIXME: for now, don't attempt to serialize values under synonyms, as current parsers
+ // don't know how to detect them
+ if (duplicate)
+ {
+ continue;
+ }
+
+ if (!duplicate)
+ {
+ it->second->mGeneration = parser.newParseGeneration();
+ }
+
+ name_stack.push_back(std::make_pair(it->first, it->second->mGeneration));
+ const Param* diff_param = diff_block ? diff_block->getParamFromHandle(param_handle) : NULL;
+ serialize_func(*param, parser, name_stack, diff_param);
+ name_stack.pop_back();
+ }
+ }
+
+ return true;
+ }
+
+ bool BaseBlock::inspectBlock(Parser& parser, Parser::name_stack_t name_stack) const
+ {
+ // named param is one like LLView::Params::follows
+ // unnamed param is like LLView::Params::rect - implicit
+ const BlockDescriptor& block_data = getBlockDescriptor();
+
+ for (BlockDescriptor::param_list_t::const_iterator it = block_data.mUnnamedParams.begin();
+ it != block_data.mUnnamedParams.end();
+ ++it)
+ {
+ param_handle_t param_handle = (*it)->mParamHandle;
+ const Param* param = getParamFromHandle(param_handle);
+ ParamDescriptor::inspect_func_t inspect_func = (*it)->mInspectFunc;
+ if (inspect_func)
+ {
+ (*it)->mGeneration = parser.newParseGeneration();
+ name_stack.push_back(std::make_pair("", (*it)->mGeneration));
+ inspect_func(*param, parser, name_stack, (*it)->mMinCount, (*it)->mMaxCount);
+ name_stack.pop_back();
+ }
+ }
+
+ for(BlockDescriptor::param_map_t::const_iterator it = block_data.mNamedParams.begin();
+ it != block_data.mNamedParams.end();
+ ++it)
+ {
+ param_handle_t param_handle = it->second->mParamHandle;
+ const Param* param = getParamFromHandle(param_handle);
+ ParamDescriptor::inspect_func_t inspect_func = it->second->mInspectFunc;
+ if (inspect_func)
+ {
+ // Ensure this param has not already been inspected
+ bool duplicate = false;
+ for (BlockDescriptor::param_list_t::const_iterator it2 = block_data.mUnnamedParams.begin();
+ it2 != block_data.mUnnamedParams.end();
+ ++it2)
+ {
+ if (param_handle == (*it2)->mParamHandle)
+ {
+ duplicate = true;
+ break;
+ }
+ }
+
+ if (!duplicate)
+ {
+ it->second->mGeneration = parser.newParseGeneration();
+ }
+ name_stack.push_back(std::make_pair(it->first, it->second->mGeneration));
+ inspect_func(*param, parser, name_stack, it->second->mMinCount, it->second->mMaxCount);
+ name_stack.pop_back();
+ }
+ }
+
+ for(BlockDescriptor::param_map_t::const_iterator it = block_data.mSynonyms.begin();
+ it != block_data.mSynonyms.end();
+ ++it)
+ {
+ param_handle_t param_handle = it->second->mParamHandle;
+ const Param* param = getParamFromHandle(param_handle);
+ ParamDescriptor::inspect_func_t inspect_func = it->second->mInspectFunc;
+ if (inspect_func)
+ {
+ // use existing serial number for param
+ name_stack.push_back(std::make_pair(it->first, it->second->mGeneration));
+ inspect_func(*param, parser, name_stack, it->second->mMinCount, it->second->mMaxCount);
+ name_stack.pop_back();
+ }
+ }
+
+ return true;
+ }
+
+ bool BaseBlock::deserializeBlock(Parser& p, Parser::name_stack_range_t name_stack)
+ {
+ BlockDescriptor& block_data = getBlockDescriptor();
+ bool names_left = !name_stack.empty();
+
+ if (names_left)
+ {
+ const std::string& top_name = name_stack.front().first;
+
+ ParamDescriptor::deserialize_func_t deserialize_func = NULL;
+ Param* paramp = NULL;
+
+ BlockDescriptor::param_map_t::iterator found_it = block_data.mNamedParams.find(top_name);
+ if (found_it != block_data.mNamedParams.end())
+ {
+ // find pointer to member parameter from offset table
+ paramp = getParamFromHandle(found_it->second->mParamHandle);
+ deserialize_func = found_it->second->mDeserializeFunc;
+ }
+ else
+ {
+ BlockDescriptor::param_map_t::iterator found_it = block_data.mSynonyms.find(top_name);
+ if (found_it != block_data.mSynonyms.end())
+ {
+ // find pointer to member parameter from offset table
+ paramp = getParamFromHandle(found_it->second->mParamHandle);
+ deserialize_func = found_it->second->mDeserializeFunc;
+ }
+ }
+
+ Parser::name_stack_range_t new_name_stack(++name_stack.begin(), name_stack.end());
+ if (deserialize_func)
+ {
+ return deserialize_func(*paramp, p, new_name_stack, name_stack.empty() ? -1 : name_stack.front().second);
+ }
+ }
+
+ // try to parse unnamed parameters, in declaration order
+ for ( BlockDescriptor::param_list_t::iterator it = block_data.mUnnamedParams.begin();
+ it != block_data.mUnnamedParams.end();
+ ++it)
+ {
+ Param* paramp = getParamFromHandle((*it)->mParamHandle);
+ ParamDescriptor::deserialize_func_t deserialize_func = (*it)->mDeserializeFunc;
+
+ if (deserialize_func && deserialize_func(*paramp, p, name_stack, name_stack.empty() ? -1 : name_stack.front().second))
+ {
+ mLastChangedParam = (*it)->mParamHandle;
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+ //static
+ void BaseBlock::addParam(BlockDescriptor& block_data, const ParamDescriptor& in_param, const char* char_name)
+ {
+ // create a copy of the paramdescriptor in allparams
+ // so other data structures can store a pointer to it
+ block_data.mAllParams.push_back(in_param);
+ ParamDescriptor& param(block_data.mAllParams.back());
+
+ std::string name(char_name);
+ if ((size_t)param.mParamHandle > block_data.mMaxParamOffset)
+ {
+ llerrs << "Attempted to register param with block defined for parent class, make sure to derive from LLInitParam::Block<YOUR_CLASS, PARAM_BLOCK_BASE_CLASS>" << llendl;
+ }
+
+ if (name.empty())
+ {
+ block_data.mUnnamedParams.push_back(&param);
+ }
+ else
+ {
+ // don't use insert, since we want to overwrite existing entries
+ block_data.mNamedParams[name] = &param;
+ }
+
+ if (param.mValidationFunc)
+ {
+ block_data.mValidationList.push_back(std::make_pair(param.mParamHandle, param.mValidationFunc));
+ }
+ }
+
+ void BaseBlock::addSynonym(Param& param, const std::string& synonym)
+ {
+ BlockDescriptor& block_data = getBlockDescriptor();
+ if (block_data.mInitializationState == BlockDescriptor::INITIALIZING)
+ {
+ param_handle_t handle = getHandleFromParam(&param);
+
+ // check for invalid derivation from a paramblock (i.e. without using
+ // Block<T, Base_Class>
+ if ((size_t)handle > block_data.mMaxParamOffset)
+ {
+ llerrs << "Attempted to register param with block defined for parent class, make sure to derive from LLInitParam::Block<YOUR_CLASS, PARAM_BLOCK_BASE_CLASS>" << llendl;
+ }
+
+ ParamDescriptor* param_descriptor = findParamDescriptor(handle);
+ if (param_descriptor)
+ {
+ if (synonym.empty())
+ {
+ block_data.mUnnamedParams.push_back(param_descriptor);
+ }
+ else
+ {
+ block_data.mSynonyms[synonym] = param_descriptor;
+ }
+ }
+ }
+ }
+
+ void BaseBlock::setLastChangedParam(const Param& last_param, bool user_provided)
+ {
+ mLastChangedParam = getHandleFromParam(&last_param);
+ mChangeVersion++;
+ }
+
+ const std::string& BaseBlock::getParamName(const BlockDescriptor& block_data, const Param* paramp) const
+ {
+ param_handle_t handle = getHandleFromParam(paramp);
+ for (BlockDescriptor::param_map_t::const_iterator it = block_data.mNamedParams.begin(); it != block_data.mNamedParams.end(); ++it)
+ {
+ if (it->second->mParamHandle == handle)
+ {
+ return it->first;
+ }
+ }
+
+ for (BlockDescriptor::param_map_t::const_iterator it = block_data.mSynonyms.begin(); it != block_data.mSynonyms.end(); ++it)
+ {
+ if (it->second->mParamHandle == handle)
+ {
+ return it->first;
+ }
+ }
+
+ return LLStringUtil::null;
+ }
+
+ ParamDescriptor* BaseBlock::findParamDescriptor(param_handle_t handle)
+ {
+ BlockDescriptor& descriptor = getBlockDescriptor();
+ BlockDescriptor::all_params_list_t::iterator end_it = descriptor.mAllParams.end();
+ for (BlockDescriptor::all_params_list_t::iterator it = descriptor.mAllParams.begin();
+ it != end_it;
+ ++it)
+ {
+ if (it->mParamHandle == handle) return &(*it);
+ }
+ return NULL;
+ }
+
+ // take all provided params from other and apply to self
+ // NOTE: this requires that "other" is of the same derived type as this
+ bool BaseBlock::overwriteFromImpl(BlockDescriptor& block_data, const BaseBlock& other)
+ {
+ bool param_changed = false;
+ BlockDescriptor::all_params_list_t::const_iterator end_it = block_data.mAllParams.end();
+ for (BlockDescriptor::all_params_list_t::const_iterator it = block_data.mAllParams.begin();
+ it != end_it;
+ ++it)
+ {
+ const Param* other_paramp = other.getParamFromHandle(it->mParamHandle);
+ ParamDescriptor::merge_func_t merge_func = it->mMergeFunc;
+ if (merge_func)
+ {
+ Param* paramp = getParamFromHandle(it->mParamHandle);
+ param_changed |= merge_func(*paramp, *other_paramp, true);
+ mLastChangedParam = it->mParamHandle;
+ }
+ }
+ return param_changed;
+ }
+
+ // take all provided params that are not already provided, and apply to self
+ bool BaseBlock::fillFromImpl(BlockDescriptor& block_data, const BaseBlock& other)
+ {
+ bool param_changed = false;
+ BlockDescriptor::all_params_list_t::const_iterator end_it = block_data.mAllParams.end();
+ for (BlockDescriptor::all_params_list_t::const_iterator it = block_data.mAllParams.begin();
+ it != end_it;
+ ++it)
+ {
+ const Param* other_paramp = other.getParamFromHandle(it->mParamHandle);
+ ParamDescriptor::merge_func_t merge_func = it->mMergeFunc;
+ if (merge_func)
+ {
+ Param* paramp = getParamFromHandle(it->mParamHandle);
+ param_changed |= merge_func(*paramp, *other_paramp, false);
+ mLastChangedParam = it->mParamHandle;
+ }
+ }
+ return param_changed;
+ }
+
+
+ template<>
+ bool ParamCompare<boost::function<void (const std::string &,void *)> >::equals(
+ const boost::function<void (const std::string &,void *)> &a,
+ const boost::function<void (const std::string &,void *)> &b)
+ {
+ return false;
+ }
+
+ template<>
+ bool ParamCompare<boost::function<void (const LLSD &,const LLSD &)> >::equals(
+ const boost::function<void (const LLSD &,const LLSD &)> &a,
+ const boost::function<void (const LLSD &,const LLSD &)> &b)
+ {
+ return false;
+ }
+
+ template<>
+ bool ParamCompare<LLSD>::equals(const LLSD &a, const LLSD &b)
+ {
+ return false;
+ }
+}
diff --git a/indra/llxuixml/llinitparam.h b/indra/llxuixml/llinitparam.h
new file mode 100644
index 0000000000..a1d0831939
--- /dev/null
+++ b/indra/llxuixml/llinitparam.h
@@ -0,0 +1,1823 @@
+/**
+ * @file llinitparam.h
+ * @brief parameter block abstraction for creating complex objects and
+ * parsing construction parameters from xml and LLSD
+ *
+ * $LicenseInfo:firstyear=2008&license=viewergpl$
+ *
+ * Copyright (c) 2008-2009, Linden Research, Inc.
+ *
+ * Second Life Viewer Source Code
+ * The source code in this file ("Source Code") is provided by Linden Lab
+ * to you under the terms of the GNU General Public License, version 2.0
+ * ("GPL"), unless you have obtained a separate licensing agreement
+ * ("Other License"), formally executed by you and Linden Lab. Terms of
+ * the GPL can be found in doc/GPL-license.txt in this distribution, or
+ * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
+ *
+ * There are special exceptions to the terms and conditions of the GPL as
+ * it is applied to this Source Code. View the full text of the exception
+ * in the file doc/FLOSS-exception.txt in this software distribution, or
+ * online at
+ * http://secondlifegrid.net/programs/open_source/licensing/flossexception
+ *
+ * By copying, modifying or distributing this software, you acknowledge
+ * that you have read and understood your obligations described above,
+ * and agree to abide by those obligations.
+ *
+ * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+ * COMPLETENESS OR PERFORMANCE.
+ * $/LicenseInfo$
+ */
+
+#ifndef LL_LLPARAM_H
+#define LL_LLPARAM_H
+
+#include <vector>
+
+#include <stddef.h>
+#include <boost/function.hpp>
+#include <boost/bind.hpp>
+#include <boost/range/iterator_range.hpp>
+#include "llregistry.h"
+#include "llmemory.h"
+
+
+namespace LLInitParam
+{
+ template <typename T>
+ class ParamCompare {
+ public:
+ static bool equals(const T &a, const T &b);
+ };
+
+ template<class T>
+ bool ParamCompare<T>::equals(const T &a, const T&b)
+ {
+ return a == b;
+ }
+
+
+ // default constructor adaptor for InitParam Values
+ // constructs default instances of the given type, returned by const reference
+ template <typename T>
+ struct DefaultInitializer
+ {
+ typedef const T& T_const_ref;
+ // return reference to a single default instance of T
+ // built-in types will be initialized to zero, default constructor otherwise
+ static T_const_ref get() { static T t = T(); return t; }
+ };
+
+ // helper functions and classes
+ typedef ptrdiff_t param_handle_t;
+
+ template <typename T>
+ class TypeValues
+ {
+ public:
+ // empty default implemenation of key cache
+ class KeyCache
+ {
+ public:
+ void setKey(const std::string& key) {}
+ std::string getKey() const { return ""; }
+ void clearKey(){}
+ };
+
+ static bool get(const std::string& name, T& value)
+ {
+ return false;
+ }
+
+ static bool empty()
+ {
+ return true;
+ }
+
+ static std::vector<std::string>* getPossibleValues() { return NULL; }
+ };
+
+ template <typename T, typename DERIVED_TYPE = TypeValues<T> >
+ class TypeValuesHelper
+ : public LLRegistrySingleton<std::string, T, DERIVED_TYPE >
+ {
+ typedef LLRegistrySingleton<std::string, T, DERIVED_TYPE> super_t;
+ typedef LLSingleton<DERIVED_TYPE> singleton_t;
+ public:
+
+ //TODO: cache key by index to save on param block size
+ class KeyCache
+ {
+ public:
+ void setKey(const std::string& key)
+ {
+ mKey = key;
+ }
+
+ void clearKey()
+ {
+ mKey = "";
+ }
+
+ std::string getKey() const
+ {
+ return mKey;
+ }
+
+ private:
+ std::string mKey;
+ };
+
+ static bool get(const std::string& name, T& value)
+ {
+ if (!singleton_t::instance().exists(name)) return false;
+
+ value = *singleton_t::instance().getValue(name);
+ return true;
+ }
+
+ static bool empty()
+ {
+ return singleton_t::instance().LLRegistry<std::string, T>::empty();
+ }
+
+ //override this to add name value pairs
+ static void declareValues() {}
+
+ void initSingleton()
+ {
+ DERIVED_TYPE::declareValues();
+ }
+
+ static const std::vector<std::string>* getPossibleValues()
+ {
+ // in order to return a pointer to a member, we lazily
+ // evaluate the result and store it in mValues here
+ if (singleton_t::instance().mValues.empty())
+ {
+ typename super_t::Registrar::registry_map_t::const_iterator it;
+ for (it = super_t::defaultRegistrar().beginItems(); it != super_t::defaultRegistrar().endItems(); ++it)
+ {
+ singleton_t::instance().mValues.push_back(it->first);
+ }
+ }
+ return &singleton_t::instance().mValues;
+ }
+
+
+ protected:
+ static void declare(const std::string& name, const T& value)
+ {
+ super_t::defaultRegistrar().add(name, value);
+ }
+
+ private:
+ std::vector<std::string> mValues;
+ };
+
+ class Parser
+ {
+ LOG_CLASS(Parser);
+
+ public:
+
+ struct CompareTypeID
+ {
+ bool operator()(const std::type_info* lhs, const std::type_info* rhs) const
+ {
+ return lhs->before(*rhs);
+ }
+ };
+
+ typedef std::vector<std::pair<std::string, S32> > name_stack_t;
+ typedef boost::iterator_range<name_stack_t::const_iterator> name_stack_range_t;
+ typedef std::vector<std::string> possible_values_t;
+
+ typedef boost::function<bool (void*)> parser_read_func_t;
+ typedef boost::function<bool (const void*, const name_stack_t&)> parser_write_func_t;
+ typedef boost::function<void (const name_stack_t&, S32, S32, const possible_values_t*)> parser_inspect_func_t;
+
+ typedef std::map<const std::type_info*, parser_read_func_t, CompareTypeID> parser_read_func_map_t;
+ typedef std::map<const std::type_info*, parser_write_func_t, CompareTypeID> parser_write_func_map_t;
+ typedef std::map<const std::type_info*, parser_inspect_func_t, CompareTypeID> parser_inspect_func_map_t;
+
+ Parser()
+ : mParseSilently(false),
+ mParseGeneration(0)
+ {}
+ virtual ~Parser();
+
+ template <typename T> bool readValue(T& param)
+ {
+ parser_read_func_map_t::iterator found_it = mParserReadFuncs.find(&typeid(T));
+ if (found_it != mParserReadFuncs.end())
+ {
+ return found_it->second((void*)&param);
+ }
+ return false;
+ }
+
+ template <typename T> bool writeValue(const T& param, const name_stack_t& name_stack)
+ {
+ parser_write_func_map_t::iterator found_it = mParserWriteFuncs.find(&typeid(T));
+ if (found_it != mParserWriteFuncs.end())
+ {
+ return found_it->second((const void*)&param, name_stack);
+ }
+ return false;
+ }
+
+ // dispatch inspection to registered inspection functions, for each parameter in a param block
+ template <typename T> bool inspectValue(const name_stack_t& name_stack, S32 min_count, S32 max_count, const possible_values_t* possible_values)
+ {
+ parser_inspect_func_map_t::iterator found_it = mParserInspectFuncs.find(&typeid(T));
+ if (found_it != mParserInspectFuncs.end())
+ {
+ found_it->second(name_stack, min_count, max_count, possible_values);
+ return true;
+ }
+ return false;
+ }
+
+ virtual std::string getCurrentElementName() = 0;
+ virtual void parserWarning(const std::string& message);
+ virtual void parserError(const std::string& message);
+ void setParseSilently(bool silent) { mParseSilently = silent; }
+ bool getParseSilently() { return mParseSilently; }
+
+ S32 getParseGeneration() { return mParseGeneration; }
+ S32 newParseGeneration() { return ++mParseGeneration; }
+
+
+ protected:
+ template <typename T>
+ void registerParserFuncs(parser_read_func_t read_func, parser_write_func_t write_func)
+ {
+ mParserReadFuncs.insert(std::make_pair(&typeid(T), read_func));
+ mParserWriteFuncs.insert(std::make_pair(&typeid(T), write_func));
+ }
+
+ template <typename T>
+ void registerInspectFunc(parser_inspect_func_t inspect_func)
+ {
+ mParserInspectFuncs.insert(std::make_pair(&typeid(T), inspect_func));
+ }
+
+ bool mParseSilently;
+
+ private:
+ parser_read_func_map_t mParserReadFuncs;
+ parser_write_func_map_t mParserWriteFuncs;
+ parser_inspect_func_map_t mParserInspectFuncs;
+ S32 mParseGeneration;
+ };
+
+ class BaseBlock;
+
+ class Param
+ {
+ public:
+ // public to allow choice blocks to clear provided flag on stale choices
+ void setProvided(bool is_provided) { mIsProvided = is_provided; }
+
+ protected:
+ bool getProvided() const { return mIsProvided; }
+
+ Param(class BaseBlock* enclosing_block);
+
+ // store pointer to enclosing block as offset to reduce space and allow for quick copying
+ BaseBlock& enclosingBlock() const
+ {
+ const U8* my_addr = reinterpret_cast<const U8*>(this);
+ // get address of enclosing BLOCK class using stored offset to enclosing BaseBlock class
+ return *const_cast<BaseBlock*>(
+ reinterpret_cast<const BaseBlock*>(my_addr + (ptrdiff_t)mEnclosingBlockOffset));
+ }
+
+ private:
+ friend class BaseBlock;
+
+ bool mIsProvided;
+ S16 mEnclosingBlockOffset;
+ };
+
+ // various callbacks and constraints associated with an individual param
+ struct ParamDescriptor
+ {
+ public:
+ typedef bool(*merge_func_t)(Param&, const Param&, bool);
+ typedef bool(*deserialize_func_t)(Param&, Parser&, const Parser::name_stack_range_t&, S32);
+ typedef void(*serialize_func_t)(const Param&, Parser&, Parser::name_stack_t&, const Param* diff_param);
+ typedef void(*inspect_func_t)(const Param&, Parser&, Parser::name_stack_t&, S32 min_count, S32 max_count);
+ typedef bool(*validation_func_t)(const Param*);
+
+ ParamDescriptor(param_handle_t p,
+ merge_func_t merge_func,
+ deserialize_func_t deserialize_func,
+ serialize_func_t serialize_func,
+ validation_func_t validation_func,
+ inspect_func_t inspect_func,
+ S32 min_count,
+ S32 max_count)
+ : mParamHandle(p),
+ mMergeFunc(merge_func),
+ mDeserializeFunc(deserialize_func),
+ mSerializeFunc(serialize_func),
+ mValidationFunc(validation_func),
+ mInspectFunc(inspect_func),
+ mMinCount(min_count),
+ mMaxCount(max_count),
+ mNumRefs(0)
+ {}
+
+ ParamDescriptor()
+ : mParamHandle(0),
+ mMergeFunc(NULL),
+ mDeserializeFunc(NULL),
+ mSerializeFunc(NULL),
+ mValidationFunc(NULL),
+ mInspectFunc(NULL),
+ mMinCount(0),
+ mMaxCount(0),
+ mGeneration(0),
+ mNumRefs(0)
+ {}
+
+ param_handle_t mParamHandle;
+
+ merge_func_t mMergeFunc;
+ deserialize_func_t mDeserializeFunc;
+ serialize_func_t mSerializeFunc;
+ inspect_func_t mInspectFunc;
+ validation_func_t mValidationFunc;
+ S32 mMinCount;
+ S32 mMaxCount;
+ S32 mGeneration;
+ S32 mNumRefs;
+ };
+
+ // each derived Block class keeps a static data structure maintaining offsets to various params
+ class BlockDescriptor
+ {
+ public:
+ BlockDescriptor()
+ : mMaxParamOffset(0),
+ mInitializationState(UNINITIALIZED)
+ {}
+
+ typedef enum e_initialization_state
+ {
+ UNINITIALIZED,
+ INITIALIZING,
+ INITIALIZED
+ } EInitializationState;
+
+ void aggregateBlockData(BlockDescriptor& src_block_data);
+
+ public:
+ typedef std::map<const std::string, ParamDescriptor*> param_map_t; // references param descriptors stored in mAllParams
+ typedef std::vector<ParamDescriptor*> param_list_t;
+
+ typedef std::list<ParamDescriptor> all_params_list_t;// references param descriptors stored in mAllParams
+ typedef std::vector<std::pair<param_handle_t, ParamDescriptor::validation_func_t> > param_validation_list_t;
+
+ param_map_t mNamedParams; // parameters with associated names
+ param_map_t mSynonyms; // parameters with alternate names
+ param_list_t mUnnamedParams; // parameters with_out_ associated names
+ param_validation_list_t mValidationList; // parameters that must be validated
+ all_params_list_t mAllParams; // all parameters, owns descriptors
+
+ size_t mMaxParamOffset;
+
+ EInitializationState mInitializationState; // whether or not static block data has been initialized
+ class BaseBlock* mCurrentBlockPtr; // pointer to block currently being constructed
+ };
+
+ class BaseBlock
+ {
+ public:
+ // this typedef identifies derived classes as being blocks
+ typedef void baseblock_base_class_t;
+ LOG_CLASS(BaseBlock);
+ friend class Param;
+
+ BaseBlock();
+ virtual ~BaseBlock();
+ bool submitValue(const Parser::name_stack_t& name_stack, Parser& p, bool silent=false);
+
+ param_handle_t getHandleFromParam(const Param* param) const;
+ bool validateBlock(bool silent = false) const;
+
+ Param* getParamFromHandle(const param_handle_t param_handle)
+ {
+ if (param_handle == 0) return NULL;
+ U8* baseblock_address = reinterpret_cast<U8*>(this);
+ return reinterpret_cast<Param*>(baseblock_address + param_handle);
+ }
+
+ const Param* getParamFromHandle(const param_handle_t param_handle) const
+ {
+ const U8* baseblock_address = reinterpret_cast<const U8*>(this);
+ return reinterpret_cast<const Param*>(baseblock_address + param_handle);
+ }
+
+ void addSynonym(Param& param, const std::string& synonym);
+
+ // Blocks can override this to do custom tracking of changes
+ virtual void setLastChangedParam(const Param& last_param, bool user_provided);
+
+ const Param* getLastChangedParam() const { return mLastChangedParam ? getParamFromHandle(mLastChangedParam) : NULL; }
+ S32 getLastChangeVersion() const { return mChangeVersion; }
+ bool isDefault() const { return mChangeVersion == 0; }
+
+ bool deserializeBlock(Parser& p, Parser::name_stack_range_t name_stack);
+ bool serializeBlock(Parser& p, Parser::name_stack_t name_stack = Parser::name_stack_t(), const BaseBlock* diff_block = NULL) const;
+ virtual bool inspectBlock(Parser& p, Parser::name_stack_t name_stack = Parser::name_stack_t()) const;
+
+ const BlockDescriptor& getBlockDescriptor() const { return *mBlockDescriptor; }
+ BlockDescriptor& getBlockDescriptor() { return *mBlockDescriptor; }
+
+ // take all provided params from other and apply to self
+ bool overwriteFrom(const BaseBlock& other)
+ {
+ return false;
+ }
+
+ // take all provided params that are not already provided, and apply to self
+ bool fillFrom(const BaseBlock& other)
+ {
+ return false;
+ }
+
+ static void addParam(BlockDescriptor& block_data, const ParamDescriptor& param, const char* name);
+ protected:
+ void init(BlockDescriptor& descriptor, BlockDescriptor& base_descriptor, size_t block_size);
+
+
+ // take all provided params from other and apply to self
+ bool overwriteFromImpl(BlockDescriptor& block_data, const BaseBlock& other);
+
+ // take all provided params that are not already provided, and apply to self
+ bool fillFromImpl(BlockDescriptor& block_data, const BaseBlock& other);
+
+ // can be updated in getters
+ mutable param_handle_t mLastChangedParam;
+ mutable S32 mChangeVersion;
+
+ BlockDescriptor* mBlockDescriptor; // most derived block descriptor
+
+ static BlockDescriptor sBlockDescriptor;
+
+ private:
+ const std::string& getParamName(const BlockDescriptor& block_data, const Param* paramp) const;
+ ParamDescriptor* findParamDescriptor(param_handle_t handle);
+ };
+
+
+ template<typename T>
+ struct ParamIterator
+ {
+ typedef typename std::vector<T>::const_iterator const_iterator;
+ typedef typename std::vector<T>::iterator iterator;
+ };
+
+ // these templates allow us to distinguish between template parameters
+ // that derive from BaseBlock and those that don't
+ // this is supposedly faster than boost::is_convertible and the ilk
+ template<typename T, typename Void = void>
+ struct is_BaseBlock
+ : boost::false_type
+ {};
+
+ template<typename T>
+ struct is_BaseBlock<T, typename T::baseblock_base_class_t>
+ : boost::true_type
+ {};
+
+ // specialize for custom parsing/decomposition of specific classes
+ // e.g. TypedParam<LLRect> has left, top, right, bottom, etc...
+ template<typename T,
+ typename NAME_VALUE_LOOKUP = TypeValues<T>,
+ bool HAS_MULTIPLE_VALUES = false,
+ typename VALUE_IS_BLOCK = typename is_BaseBlock<T>::type>
+ class TypedParam
+ : public Param
+ {
+ public:
+ typedef const T& value_const_ref_t;
+ typedef value_const_ref_t value_assignment_t;
+ typedef typename NAME_VALUE_LOOKUP::KeyCache key_cache_t;
+ typedef TypedParam<T, NAME_VALUE_LOOKUP, HAS_MULTIPLE_VALUES, VALUE_IS_BLOCK> self_t;
+
+ TypedParam(BlockDescriptor& block_descriptor, const char* name, value_assignment_t value, ParamDescriptor::validation_func_t validate_func, S32 min_count, S32 max_count)
+ : Param(block_descriptor.mCurrentBlockPtr)
+ {
+ if (block_descriptor.mInitializationState == BlockDescriptor::INITIALIZING)
+ {
+ ParamDescriptor param_descriptor(block_descriptor.mCurrentBlockPtr->getHandleFromParam(this),
+ &mergeWith,
+ &deserializeParam,
+ &serializeParam,
+ validate_func,
+ &inspectParam,
+ min_count, max_count);
+ BaseBlock::addParam(block_descriptor, param_descriptor, name);
+ }
+
+ mData.mValue = value;
+ }
+
+ bool isProvided() const { return Param::getProvided(); }
+
+ static bool deserializeParam(Param& param, Parser& parser, const Parser::name_stack_range_t& name_stack, S32 generation)
+ {
+ self_t& typed_param = static_cast<self_t&>(param);
+ // no further names in stack, attempt to parse value now
+ if (name_stack.empty())
+ {
+ if (parser.readValue<T>(typed_param.mData.mValue))
+ {
+ typed_param.setProvided(true);
+ typed_param.enclosingBlock().setLastChangedParam(param, true);
+ return true;
+ }
+
+ // try to parse a known named value
+ if(!NAME_VALUE_LOOKUP::empty())
+ {
+ // try to parse a known named value
+ std::string name;
+ if (parser.readValue<std::string>(name))
+ {
+ // try to parse a per type named value
+ if (NAME_VALUE_LOOKUP::get(name, typed_param.mData.mValue))
+ {
+ typed_param.mData.setKey(name);
+ typed_param.setProvided(true);
+ typed_param.enclosingBlock().setLastChangedParam(param, true);
+ return true;
+ }
+
+ }
+ }
+ }
+ return false;
+ }
+
+ static void serializeParam(const Param& param, Parser& parser, Parser::name_stack_t& name_stack, const Param* diff_param)
+ {
+ const self_t& typed_param = static_cast<const self_t&>(param);
+ if (!typed_param.isProvided()) return;
+
+ if (!name_stack.empty())
+ {
+ name_stack.back().second = parser.newParseGeneration();
+ }
+
+ std::string key = typed_param.mData.getKey();
+
+ // first try to write out name of name/value pair
+
+ if (!key.empty())
+ {
+ if (!diff_param || !ParamCompare<std::string>::equals(static_cast<const self_t*>(diff_param)->mData.getKey(), key))
+ {
+ if (!parser.writeValue<std::string>(key, name_stack))
+ {
+ return;
+ }
+ }
+ }
+ // then try to serialize value directly
+ else if (!diff_param || !ParamCompare<T>::equals(typed_param.get(), static_cast<const self_t*>(diff_param)->get())) {
+ if (!parser.writeValue<T>(typed_param.mData.mValue, name_stack))
+ {
+ return;
+ }
+ }
+ }
+
+ static void inspectParam(const Param& param, Parser& parser, Parser::name_stack_t& name_stack, S32 min_count, S32 max_count)
+ {
+ // tell parser about our actual type
+ parser.inspectValue<T>(name_stack, min_count, max_count, NULL);
+ // then tell it about string-based alternatives ("red", "blue", etc. for LLColor4)
+ if (NAME_VALUE_LOOKUP::getPossibleValues())
+ {
+ parser.inspectValue<std::string>(name_stack, min_count, max_count, NAME_VALUE_LOOKUP::getPossibleValues());
+ }
+ }
+
+ void set(value_assignment_t val, bool flag_as_provided = true)
+ {
+ mData.mValue = val;
+ mData.clearKey();
+ setProvided(flag_as_provided);
+ Param::enclosingBlock().setLastChangedParam(*this, flag_as_provided);
+ }
+
+ void setIfNotProvided(value_assignment_t val, bool flag_as_provided = true)
+ {
+ if (!isProvided())
+ {
+ set(val, flag_as_provided);
+ }
+ }
+
+ // implicit conversion
+ operator value_assignment_t() const { return get(); }
+ // explicit conversion
+ value_assignment_t operator()() const { return get(); }
+
+ protected:
+ value_assignment_t get() const
+ {
+ return mData.mValue;
+ }
+
+ static bool mergeWith(Param& dst, const Param& src, bool overwrite)
+ {
+ const self_t& src_typed_param = static_cast<const self_t&>(src);
+ self_t& dst_typed_param = static_cast<self_t&>(dst);
+ if (src_typed_param.isProvided()
+ && (overwrite || !dst_typed_param.isProvided()))
+ {
+ dst_typed_param.mData.clearKey();
+ dst_typed_param = src_typed_param;
+ return true;
+ }
+ return false;
+ }
+
+ struct Data : public key_cache_t
+ {
+ T mValue;
+ };
+
+ Data mData;
+ };
+
+ // parameter that is a block
+ template <typename T, typename NAME_VALUE_LOOKUP>
+ class TypedParam<T, NAME_VALUE_LOOKUP, false, boost::true_type>
+ : public T,
+ public Param
+ {
+ public:
+ typedef const T value_const_t;
+ typedef T value_t;
+ typedef value_const_t& value_const_ref_t;
+ typedef value_const_ref_t value_assignment_t;
+ typedef typename NAME_VALUE_LOOKUP::KeyCache key_cache_t;
+ typedef TypedParam<T, NAME_VALUE_LOOKUP, false, boost::true_type> self_t;
+
+ TypedParam(BlockDescriptor& block_descriptor, const char* name, value_assignment_t value, ParamDescriptor::validation_func_t validate_func, S32 min_count, S32 max_count)
+ : Param(block_descriptor.mCurrentBlockPtr),
+ T(value)
+ {
+ if (block_descriptor.mInitializationState == BlockDescriptor::INITIALIZING)
+ {
+ ParamDescriptor param_descriptor(block_descriptor.mCurrentBlockPtr->getHandleFromParam(this),
+ &mergeWith,
+ &deserializeParam,
+ &serializeParam,
+ validate_func,
+ &inspectParam,
+ min_count, max_count);
+ BaseBlock::addParam(block_descriptor, param_descriptor, name);
+ }
+ }
+
+ static bool deserializeParam(Param& param, Parser& parser, const Parser::name_stack_range_t& name_stack, S32 generation)
+ {
+ self_t& typed_param = static_cast<self_t&>(param);
+ // attempt to parse block...
+ if(typed_param.deserializeBlock(parser, name_stack))
+ {
+ typed_param.enclosingBlock().setLastChangedParam(param, true);
+ return true;
+ }
+
+ if(!NAME_VALUE_LOOKUP::empty())
+ {
+ // try to parse a known named value
+ std::string name;
+ if (parser.readValue<std::string>(name))
+ {
+ // try to parse a per type named value
+ if (NAME_VALUE_LOOKUP::get(name, typed_param))
+ {
+ typed_param.enclosingBlock().setLastChangedParam(param, true);
+ typed_param.mData.setKey(name);
+ typed_param.mData.mKeyVersion = typed_param.getLastChangeVersion();
+ return true;
+ }
+
+ }
+ }
+ return false;
+ }
+
+ static void serializeParam(const Param& param, Parser& parser, Parser::name_stack_t& name_stack, const Param* diff_param)
+ {
+ const self_t& typed_param = static_cast<const self_t&>(param);
+ if (!name_stack.empty())
+ {
+ name_stack.back().second = parser.newParseGeneration();
+ }
+
+ std::string key = typed_param.mData.getKey();
+ if (!key.empty() && typed_param.mData.mKeyVersion == typed_param.getLastChangeVersion())
+ {
+ if (!parser.writeValue<std::string>(key, name_stack))
+ {
+ return;
+ }
+ }
+ else
+ {
+ typed_param.serializeBlock(parser, name_stack, static_cast<const self_t*>(diff_param));
+ }
+ }
+
+ static void inspectParam(const Param& param, Parser& parser, Parser::name_stack_t& name_stack, S32 min_count, S32 max_count)
+ {
+ // I am a param that is also a block, so just recurse into my contents
+ const self_t& typed_param = static_cast<const self_t&>(param);
+ typed_param.inspectBlock(parser, name_stack);
+ }
+
+ // a param-that-is-a-block is provided when the user has set one of its child params
+ // *and* the block as a whole validates
+ bool isProvided() const
+ {
+ // only validate block when it hasn't already passed validation and user has supplied *some* value
+ if (Param::getProvided() && mData.mValidatedVersion < T::getLastChangeVersion())
+ {
+ // a sub-block is "provided" when it has been filled in enough to be valid
+ mData.mValidated = T::validateBlock(true);
+ mData.mValidatedVersion = T::getLastChangeVersion();
+ }
+ return Param::getProvided() && mData.mValidated;
+ }
+
+ // assign block contents to this param-that-is-a-block
+ void set(value_assignment_t val, bool flag_as_provided = true)
+ {
+ value_t::operator=(val);
+ mData.clearKey();
+ // force revalidation of block by clearing known provided version
+ // next call to isProvided() will update provision status based on validity
+ mData.mValidatedVersion = 0;
+ setProvided(flag_as_provided);
+ Param::enclosingBlock().setLastChangedParam(*this, flag_as_provided);
+ }
+
+ void setIfNotProvided(value_assignment_t val, bool flag_as_provided = true)
+ {
+ if (!isProvided())
+ {
+ set(val, flag_as_provided);
+ }
+ }
+
+ // propagate changed status up to enclosing block
+ /*virtual*/ void setLastChangedParam(const Param& last_param, bool user_provided)
+ {
+ T::setLastChangedParam(last_param, user_provided);
+ Param::enclosingBlock().setLastChangedParam(*this, user_provided);
+ if (user_provided)
+ {
+ // a child param has been explicitly changed
+ // so *some* aspect of this block is now provided
+ setProvided(true);
+ }
+ }
+
+ // implicit conversion
+ operator value_assignment_t() const { return get(); }
+ // explicit conversion
+ value_assignment_t operator()() const { return get(); }
+
+ protected:
+ value_assignment_t get() const
+ {
+ return *this;
+ }
+
+ static bool mergeWith(Param& dst, const Param& src, bool overwrite)
+ {
+ const self_t& src_typed_param = static_cast<const self_t&>(src);
+ self_t& dst_typed_param = static_cast<self_t&>(dst);
+ if (overwrite)
+ {
+ if (dst_typed_param.T::overwriteFrom(src_typed_param))
+ {
+ dst_typed_param.mData.clearKey();
+ return true;
+ }
+ }
+ else
+ {
+ if (dst_typed_param.T::fillFrom(src_typed_param))
+ {
+ dst_typed_param.mData.clearKey();
+ return true;
+ }
+ }
+ return false;
+ }
+
+ struct Data : public key_cache_t
+ {
+ S32 mKeyVersion;
+ mutable S32 mValidatedVersion;
+ mutable bool mValidated; // lazy validation flag
+
+ Data()
+ : mKeyVersion(0),
+ mValidatedVersion(0),
+ mValidated(false)
+ {}
+ };
+ Data mData;
+ };
+
+ // container of non-block parameters
+ template <typename VALUE_TYPE, typename NAME_VALUE_LOOKUP>
+ class TypedParam<VALUE_TYPE, NAME_VALUE_LOOKUP, true, boost::false_type>
+ : public Param
+ {
+ public:
+ typedef TypedParam<VALUE_TYPE, NAME_VALUE_LOOKUP, true, boost::false_type> self_t;
+ typedef typename std::vector<VALUE_TYPE> container_t;
+ typedef const container_t& value_assignment_t;
+
+ typedef VALUE_TYPE value_t;
+ typedef value_t& value_ref_t;
+ typedef const value_t& value_const_ref_t;
+
+ typedef typename NAME_VALUE_LOOKUP::KeyCache key_cache_t;
+
+ TypedParam(BlockDescriptor& block_descriptor, const char* name, value_assignment_t value, ParamDescriptor::validation_func_t validate_func, S32 min_count, S32 max_count)
+ : Param(block_descriptor.mCurrentBlockPtr),
+ mValues(value)
+ {
+ mCachedKeys.resize(mValues.size());
+ if (block_descriptor.mInitializationState == BlockDescriptor::INITIALIZING)
+ {
+ ParamDescriptor param_descriptor(block_descriptor.mCurrentBlockPtr->getHandleFromParam(this),
+ &mergeWith,
+ &deserializeParam,
+ &serializeParam,
+ validate_func,
+ &inspectParam,
+ min_count, max_count);
+ BaseBlock::addParam(block_descriptor, param_descriptor, name);
+ }
+ }
+
+ bool isProvided() const { return Param::getProvided(); }
+
+ static bool deserializeParam(Param& param, Parser& parser, const Parser::name_stack_range_t& name_stack, S32 generation)
+ {
+ self_t& typed_param = static_cast<self_t&>(param);
+ value_t value;
+ // no further names in stack, attempt to parse value now
+ if (name_stack.empty())
+ {
+ // attempt to read value directly
+ if (parser.readValue<value_t>(value))
+ {
+ typed_param.mValues.push_back(value);
+ // save an empty name/value key as a placeholder
+ typed_param.mCachedKeys.push_back(key_cache_t());
+ typed_param.enclosingBlock().setLastChangedParam(param, true);
+ typed_param.setProvided(true);
+ return true;
+ }
+
+ // try to parse a known named value
+ if(!NAME_VALUE_LOOKUP::empty())
+ {
+ // try to parse a known named value
+ std::string name;
+ if (parser.readValue<std::string>(name))
+ {
+ // try to parse a per type named value
+ if (NAME_VALUE_LOOKUP::get(name, typed_param.mValues))
+ {
+ typed_param.mValues.push_back(value);
+ typed_param.mCachedKeys.push_back(key_cache_t());
+ typed_param.mCachedKeys.back().setKey(name);
+ typed_param.enclosingBlock().setLastChangedParam(param, true);
+ typed_param.setProvided(true);
+ return true;
+ }
+
+ }
+ }
+ }
+ return false;
+ }
+
+ static void serializeParam(const Param& param, Parser& parser, Parser::name_stack_t& name_stack, const Param* diff_param)
+ {
+ const self_t& typed_param = static_cast<const self_t&>(param);
+ if (!typed_param.isProvided() || name_stack.empty()) return;
+
+ typename container_t::const_iterator it = typed_param.mValues.begin();
+ for (typename std::vector<key_cache_t>::const_iterator key_it = typed_param.mCachedKeys.begin();
+ it != typed_param.mValues.end();
+ ++key_it, ++it)
+ {
+ std::string key = key_it->get();
+ name_stack.back().second = parser.newParseGeneration();
+
+ if(!key.empty())
+ {
+ if(!parser.writeValue<std::string>(key, name_stack))
+ {
+ return;
+ }
+ }
+ // not parse via name values, write out value directly
+ else if (!parser.writeValue<VALUE_TYPE>(*it, name_stack))
+ {
+ return;
+ }
+ }
+ }
+
+ static void inspectParam(const Param& param, Parser& parser, Parser::name_stack_t& name_stack, S32 min_count, S32 max_count)
+ {
+ parser.inspectValue<VALUE_TYPE>(name_stack, min_count, max_count, NULL);
+ if (NAME_VALUE_LOOKUP::getPossibleValues())
+ {
+ parser.inspectValue<std::string>(name_stack, min_count, max_count, NAME_VALUE_LOOKUP::getPossibleValues());
+ }
+ }
+
+ void set(value_assignment_t val, bool flag_as_provided = true)
+ {
+ mValues = val;
+ mCachedKeys.clear();
+ mCachedKeys.resize(mValues.size());
+ setProvided(flag_as_provided);
+ Param::enclosingBlock().setLastChangedParam(*this, flag_as_provided);
+ }
+
+
+ void setIfNotProvided(value_assignment_t val, bool flag_as_provided = true)
+ {
+ if (!isProvided())
+ {
+ set(val, flag_as_provided);
+ }
+ }
+
+ value_ref_t add()
+ {
+ mValues.push_back(value_t());
+ mCachedKeys.push_back(key_cache_t());
+ setProvided(true);
+ return mValues.back();
+ }
+
+ void add(value_const_ref_t item)
+ {
+ mValues.push_back(item);
+ mCachedKeys.push_back(key_cache_t());
+ setProvided(true);
+ }
+
+ // implicit conversion
+ operator value_assignment_t() const { return self_t::get(); }
+ // explicit conversion
+ value_assignment_t operator()() const { return get(); }
+
+ bool hasNValidElements(S32 n) const
+ {
+ return mValues.size() >= n;
+ }
+
+ protected:
+ value_assignment_t get() const
+ {
+ return mValues;
+ }
+
+ static bool mergeWith(Param& dst, const Param& src, bool overwrite)
+ {
+ const self_t& src_typed_param = static_cast<const self_t&>(src);
+ self_t& dst_typed_param = static_cast<self_t&>(dst);
+
+ if (src_typed_param.isProvided()
+ && (overwrite || !isProvided()))
+ {
+ dst_typed_param = src_typed_param;
+ return true;
+ }
+ return false;
+ }
+
+ container_t mValues;
+ std::vector<key_cache_t> mCachedKeys;
+ };
+
+ // container of block parameters
+ template <typename VALUE_TYPE, typename NAME_VALUE_LOOKUP>
+ class TypedParam<VALUE_TYPE, NAME_VALUE_LOOKUP, true, boost::true_type>
+ : public Param
+ {
+ public:
+ typedef TypedParam<VALUE_TYPE, NAME_VALUE_LOOKUP, true, boost::true_type> self_t;
+ typedef typename std::vector<VALUE_TYPE> container_t;
+ typedef const container_t& value_assignment_t;
+
+ typedef VALUE_TYPE value_t;
+ typedef value_t& value_ref_t;
+ typedef const value_t& value_const_ref_t;
+
+ typedef typename NAME_VALUE_LOOKUP::KeyCache key_cache_t;
+
+ TypedParam(BlockDescriptor& block_descriptor, const char* name, value_assignment_t value, ParamDescriptor::validation_func_t validate_func, S32 min_count, S32 max_count)
+ : Param(block_descriptor.mCurrentBlockPtr),
+ mValues(value),
+ mLastParamGeneration(0)
+ {
+ mCachedKeys.resize(mValues.size());
+ if (block_descriptor.mInitializationState == BlockDescriptor::INITIALIZING)
+ {
+ ParamDescriptor param_descriptor(block_descriptor.mCurrentBlockPtr->getHandleFromParam(this),
+ &mergeWith,
+ &deserializeParam,
+ &serializeParam,
+ validate_func,
+ &inspectParam,
+ min_count, max_count);
+ BaseBlock::addParam(block_descriptor, param_descriptor, name);
+ }
+ }
+
+ bool isProvided() const { return Param::getProvided(); }
+
+ value_ref_t operator[](S32 index) { return mValues[index]; }
+ value_const_ref_t operator[](S32 index) const { return mValues[index]; }
+
+ static bool deserializeParam(Param& param, Parser& parser, const Parser::name_stack_range_t& name_stack, S32 generation)
+ {
+ self_t& typed_param = static_cast<self_t&>(param);
+ if (generation != typed_param.mLastParamGeneration || typed_param.mValues.empty())
+ {
+ typed_param.mValues.push_back(value_t());
+ typed_param.mCachedKeys.push_back(Data());
+ typed_param.enclosingBlock().setLastChangedParam(param, true);
+ typed_param.mLastParamGeneration = generation;
+ }
+
+ value_t& value = typed_param.mValues.back();
+
+ // attempt to parse block...
+ if(value.deserializeBlock(parser, name_stack))
+ {
+ typed_param.setProvided(true);
+ return true;
+ }
+
+ if(!NAME_VALUE_LOOKUP::empty())
+ {
+ // try to parse a known named value
+ std::string name;
+ if (parser.readValue<std::string>(name))
+ {
+ // try to parse a per type named value
+ if (NAME_VALUE_LOOKUP::get(name, value))
+ {
+ typed_param.mCachedKeys.back().setKey(name);
+ typed_param.mCachedKeys.back().mKeyVersion = value.getLastChangeVersion();
+ typed_param.enclosingBlock().setLastChangedParam(param, true);
+ typed_param.setProvided(true);
+ return true;
+ }
+
+ }
+ }
+
+ return false;
+ }
+
+ static void serializeParam(const Param& param, Parser& parser, Parser::name_stack_t& name_stack, const Param* diff_param)
+ {
+ const self_t& typed_param = static_cast<const self_t&>(param);
+ if (!typed_param.isProvided() || name_stack.empty()) return;
+
+ typename container_t::const_iterator it = typed_param.mValues.begin();
+ for (typename std::vector<Data>::const_iterator key_it = typed_param.mCachedKeys.begin();
+ it != typed_param.mValues.end();
+ ++key_it, ++it)
+ {
+ name_stack.back().second = parser.newParseGeneration();
+
+ std::string key = key_it->getKey();
+ if (!key.empty() && key_it->mKeyVersion == it->getLastChangeVersion())
+ {
+ if(!parser.writeValue<std::string>(key, name_stack))
+ {
+ return;
+ }
+ }
+ // Not parsed via named values, write out value directly
+ // NOTE: currently we don't worry about removing default values in Multiple
+ else if (!it->serializeBlock(parser, name_stack, NULL))
+ {
+ return;
+ }
+ }
+ }
+
+ static void inspectParam(const Param& param, Parser& parser, Parser::name_stack_t& name_stack, S32 min_count, S32 max_count)
+ {
+ // I am a vector of blocks, so describe my contents recursively
+ value_t().inspectBlock(parser, name_stack);
+ }
+
+ void set(value_assignment_t val, bool flag_as_provided = true)
+ {
+ mValues = val;
+ mCachedKeys.clear();
+ mCachedKeys.resize(mValues.size());
+ setProvided(flag_as_provided);
+ Param::enclosingBlock().setLastChangedParam(*this, flag_as_provided);
+ }
+
+ void setIfNotProvided(value_assignment_t val, bool flag_as_provided = true)
+ {
+ if (!isProvided())
+ {
+ set(val, flag_as_provided);
+ }
+ }
+
+ value_ref_t add()
+ {
+ mValues.push_back(value_t());
+ mCachedKeys.push_back(Data());
+ setProvided(true);
+ return mValues.back();
+ }
+
+ void add(value_const_ref_t item)
+ {
+ mValues.push_back(item);
+ mCachedKeys.push_back(Data());
+ setProvided(true);
+ }
+
+ // implicit conversion
+ operator value_assignment_t() const { return self_t::get(); }
+ // explicit conversion
+ value_assignment_t operator()() const { return get(); }
+
+ U32 numValidElements() const
+ {
+ U32 count = 0;
+ for (typename container_t::const_iterator it = mValues.begin();
+ it != mValues.end();
+ ++it)
+ {
+ if(it->validateBlock(true)) count++;
+ }
+ return count;
+ }
+
+ protected:
+ value_assignment_t get() const
+ {
+ return mValues;
+ }
+
+ static bool mergeWith(Param& dst, const Param& src, bool overwrite)
+ {
+ const self_t& src_typed_param = static_cast<const self_t&>(src);
+ self_t& dst_typed_param = static_cast<self_t&>(dst);
+
+ if (src_typed_param.isProvided()
+ && (overwrite || !dst_typed_param.isProvided()))
+ {
+ dst_typed_param = src_typed_param;
+ return true;
+ }
+ return false;
+ }
+
+ struct Data : public key_cache_t
+ {
+ S32 mKeyVersion; // version of block for which key was last valid
+
+ Data() : mKeyVersion(0) {}
+ };
+
+ container_t mValues;
+ std::vector<Data> mCachedKeys;
+
+ S32 mLastParamGeneration;
+ };
+
+ template <typename DERIVED_BLOCK>
+ class Choice : public BaseBlock
+ {
+ typedef Choice<DERIVED_BLOCK> self_t;
+ typedef Choice<DERIVED_BLOCK> enclosing_block_t;
+
+ LOG_CLASS(self_t);
+ public:
+ // take all provided params from other and apply to self
+ bool overwriteFrom(const self_t& other)
+ {
+ mCurChoice = other.mCurChoice;
+ return BaseBlock::overwriteFromImpl(sBlockDescriptor, other);
+ }
+
+ // take all provided params that are not already provided, and apply to self
+ bool fillFrom(const self_t& other)
+ {
+ return false;
+ }
+
+ // clear out old choice when param has changed
+ /*virtual*/ void setLastChangedParam(const Param& last_param, bool user_provided)
+ {
+ param_handle_t changed_param_handle = BaseBlock::getHandleFromParam(&last_param);
+ // if we have a new choice...
+ if (changed_param_handle != mCurChoice)
+ {
+ // clear provided flag on previous choice
+ Param* previous_choice = BaseBlock::getParamFromHandle(mCurChoice);
+ if (previous_choice)
+ {
+ previous_choice->setProvided(false);
+ }
+ mCurChoice = changed_param_handle;
+ }
+ BaseBlock::setLastChangedParam(last_param, user_provided);
+ }
+
+ protected:
+ Choice()
+ : mCurChoice(0)
+ {
+ BaseBlock::init(sBlockDescriptor, BaseBlock::sBlockDescriptor, sizeof(DERIVED_BLOCK));
+ }
+
+ // Alternatives are mutually exclusive wrt other Alternatives in the same block.
+ // One alternative in a block will always have isChosen() == true.
+ // At most one alternative in a block will have isProvided() == true.
+ template <typename T, typename NAME_VALUE_LOOKUP = TypeValues<T> >
+ class Alternative : public TypedParam<T, NAME_VALUE_LOOKUP, false>
+ {
+ public:
+ friend class Choice<DERIVED_BLOCK>;
+
+ typedef Alternative<T, NAME_VALUE_LOOKUP> self_t;
+ typedef TypedParam<T, NAME_VALUE_LOOKUP, false> super_t;
+ typedef typename super_t::value_assignment_t value_assignment_t;
+
+ explicit Alternative(const char* name, value_assignment_t val = DefaultInitializer<T>::get())
+ : super_t(DERIVED_BLOCK::sBlockDescriptor, name, val, NULL, 0, 1),
+ mOriginalValue(val)
+ {
+ // assign initial choice to first declared option
+ DERIVED_BLOCK* blockp = ((DERIVED_BLOCK*)DERIVED_BLOCK::sBlockDescriptor.mCurrentBlockPtr);
+ if (DERIVED_BLOCK::sBlockDescriptor.mInitializationState == BlockDescriptor::INITIALIZING
+ && blockp->mCurChoice == 0)
+ {
+ blockp->mCurChoice = Param::enclosingBlock().getHandleFromParam(this);
+ }
+ }
+
+ Alternative& operator=(value_assignment_t val)
+ {
+ super_t::set(val);
+ return *this;
+ }
+
+ void operator()(typename super_t::value_assignment_t val)
+ {
+ super_t::set(val);
+ }
+
+ operator value_assignment_t() const
+ {
+ if (static_cast<enclosing_block_t&>(Param::enclosingBlock()).getCurrentChoice() == this)
+ {
+ return super_t::get();
+ }
+ return mOriginalValue;
+ }
+
+ value_assignment_t operator()() const
+ {
+ if (static_cast<enclosing_block_t&>(Param::enclosingBlock()).getCurrentChoice() == this)
+ {
+ return super_t::get();
+ }
+ return mOriginalValue;
+ }
+
+ bool isChosen() const
+ {
+ return static_cast<enclosing_block_t&>(Param::enclosingBlock()).getCurrentChoice() == this;
+ }
+
+ private:
+ T mOriginalValue;
+ };
+
+ protected:
+ static BlockDescriptor sBlockDescriptor;
+
+ private:
+ param_handle_t mCurChoice;
+
+ const Param* getCurrentChoice() const
+ {
+ return BaseBlock::getParamFromHandle(mCurChoice);
+ }
+ };
+
+ template<typename DERIVED_BLOCK>
+ BlockDescriptor
+ Choice<DERIVED_BLOCK>::sBlockDescriptor;
+
+ //struct CardinalityConstraint
+ //{
+ // virtual std::pair<S32, S32> getRange() = 0;
+ //};
+
+ struct AnyAmount
+ {
+ static U32 minCount() { return 0; }
+ static U32 maxCount() { return U32_MAX; }
+ };
+
+ template<U32 MIN_AMOUNT>
+ struct AtLeast
+ {
+ static U32 minCount() { return MIN_AMOUNT; }
+ static U32 maxCount() { return U32_MAX; }
+ };
+
+ template<U32 MAX_AMOUNT>
+ struct AtMost
+ {
+ static U32 minCount() { return 0; }
+ static U32 maxCount() { return MAX_AMOUNT; }
+ };
+
+ template<U32 MIN_AMOUNT, U32 MAX_AMOUNT>
+ struct Between
+ {
+ static U32 minCount() { return MIN_AMOUNT; }
+ static U32 maxCount() { return MAX_AMOUNT; }
+ };
+
+ template<U32 EXACT_COUNT>
+ struct Exactly
+ {
+ static U32 minCount() { return EXACT_COUNT; }
+ static U32 maxCount() { return EXACT_COUNT; }
+ };
+
+ template <typename DERIVED_BLOCK, typename BASE_BLOCK = BaseBlock>
+ class Block
+ : public BASE_BLOCK
+ {
+ typedef Block<DERIVED_BLOCK, BASE_BLOCK> self_t;
+ typedef Block<DERIVED_BLOCK, BASE_BLOCK> block_t;
+
+ public:
+ typedef BASE_BLOCK base_block_t;
+
+ // take all provided params from other and apply to self
+ bool overwriteFrom(const self_t& other)
+ {
+ return BaseBlock::overwriteFromImpl(sBlockDescriptor, other);
+ }
+
+ // take all provided params that are not already provided, and apply to self
+ bool fillFrom(const self_t& other)
+ {
+ return BaseBlock::fillFromImpl(sBlockDescriptor, other);
+ }
+ protected:
+ Block()
+ {
+ //#pragma message("Parsing LLInitParam::Block")
+ BaseBlock::init(sBlockDescriptor, BASE_BLOCK::sBlockDescriptor, sizeof(DERIVED_BLOCK));
+ }
+
+ //
+ // Nested classes for declaring parameters
+ //
+ template <typename T, typename NAME_VALUE_LOOKUP = TypeValues<T> >
+ class Optional : public TypedParam<T, NAME_VALUE_LOOKUP, false>
+ {
+ public:
+ typedef TypedParam<T, NAME_VALUE_LOOKUP, false> super_t;
+ typedef typename super_t::value_assignment_t value_assignment_t;
+
+ explicit Optional(const char* name = "", value_assignment_t val = DefaultInitializer<T>::get())
+ : super_t(DERIVED_BLOCK::sBlockDescriptor, name, val, NULL, 0, 1)
+ {
+ //#pragma message("Parsing LLInitParam::Block::Optional")
+ }
+
+ Optional& operator=(value_assignment_t val)
+ {
+ set(val);
+ return *this;
+ }
+
+ DERIVED_BLOCK& operator()(typename super_t::value_assignment_t val)
+ {
+ super_t::set(val);
+ return static_cast<DERIVED_BLOCK&>(Param::enclosingBlock());
+ }
+ using super_t::operator();
+ };
+
+ template <typename T, typename NAME_VALUE_LOOKUP = TypeValues<T> >
+ class Mandatory : public TypedParam<T, NAME_VALUE_LOOKUP, false>
+ {
+ public:
+ typedef TypedParam<T, NAME_VALUE_LOOKUP, false> super_t;
+ typedef Mandatory<T, NAME_VALUE_LOOKUP> self_t;
+ typedef typename super_t::value_assignment_t value_assignment_t;
+
+ // mandatory parameters require a name to be parseable
+ explicit Mandatory(const char* name = "", value_assignment_t val = DefaultInitializer<T>::get())
+ : super_t(DERIVED_BLOCK::sBlockDescriptor, name, val, &validate, 1, 1)
+ {}
+
+ Mandatory& operator=(value_assignment_t val)
+ {
+ set(val);
+ return *this;
+ }
+
+ DERIVED_BLOCK& operator()(typename super_t::value_assignment_t val)
+ {
+ super_t::set(val);
+ return static_cast<DERIVED_BLOCK&>(Param::enclosingBlock());
+ }
+ using super_t::operator();
+
+ static bool validate(const Param* p)
+ {
+ // valid only if provided
+ return static_cast<const self_t*>(p)->isProvided();
+ }
+
+ };
+
+ template <typename T, typename RANGE = AnyAmount, typename NAME_VALUE_LOOKUP = TypeValues<T> >
+ class Multiple : public TypedParam<T, NAME_VALUE_LOOKUP, true>
+ {
+ public:
+ typedef TypedParam<T, NAME_VALUE_LOOKUP, true> super_t;
+ typedef Multiple<T, RANGE, NAME_VALUE_LOOKUP> self_t;
+ typedef typename super_t::container_t container_t;
+ typedef typename super_t::value_assignment_t value_assignment_t;
+ typedef typename container_t::iterator iterator;
+ typedef typename container_t::const_iterator const_iterator;
+
+ explicit Multiple(const char* name = "", value_assignment_t val = DefaultInitializer<container_t>::get())
+ : super_t(DERIVED_BLOCK::sBlockDescriptor, name, val, &validate, RANGE::minCount(), RANGE::maxCount())
+ {}
+
+ using super_t::operator();
+
+ Multiple& operator=(value_assignment_t val)
+ {
+ set(val);
+ return *this;
+ }
+
+ DERIVED_BLOCK& operator()(typename super_t::value_assignment_t val)
+ {
+ super_t::set(val);
+ return static_cast<DERIVED_BLOCK&>(Param::enclosingBlock());
+ }
+
+ static bool validate(const Param* paramp)
+ {
+ U32 num_valid = ((super_t*)paramp)->numValidElements();
+ return RANGE::minCount() <= num_valid && num_valid <= RANGE::maxCount();
+ }
+ };
+
+ class Deprecated : public Param
+ {
+ public:
+ explicit Deprecated(const char* name)
+ : Param(DERIVED_BLOCK::sBlockDescriptor.mCurrentBlockPtr)
+ {
+ BlockDescriptor& block_descriptor = DERIVED_BLOCK::sBlockDescriptor;
+ if (block_descriptor.mInitializationState == BlockDescriptor::INITIALIZING)
+ {
+ ParamDescriptor param_descriptor(block_descriptor.mCurrentBlockPtr->getHandleFromParam(this),
+ NULL,
+ &deserializeParam,
+ NULL,
+ NULL,
+ NULL,
+ 0, S32_MAX);
+ BaseBlock::addParam(block_descriptor, param_descriptor, name);
+ }
+ }
+
+ static bool deserializeParam(Param& param, Parser& parser, const Parser::name_stack_range_t& name_stack, S32 generation)
+ {
+ if (name_stack.empty())
+ {
+ //std::string message = llformat("Deprecated value %s ignored", getName().c_str());
+ //parser.parserWarning(message);
+ return true;
+ }
+
+ return false;
+ }
+ };
+
+ typedef Deprecated Ignored;
+
+ protected:
+ static BlockDescriptor sBlockDescriptor;
+ };
+
+ template<typename DERIVED_BLOCK, typename BASE_BLOCK>
+ BlockDescriptor
+ Block<DERIVED_BLOCK, BASE_BLOCK>::sBlockDescriptor;
+
+ template<typename T, typename DERIVED = TypedParam<T> >
+ class BlockValue
+ : public Block<TypedParam<T, TypeValues<T>, false> >,
+ public Param
+ {
+ public:
+ typedef BlockValue<T> self_t;
+ typedef Block<TypedParam<T, TypeValues<T>, false> > block_t;
+ typedef const T& value_const_ref_t;
+ typedef value_const_ref_t value_assignment_t;
+ typedef typename TypeValues<T>::KeyCache key_cache_t;
+
+ BlockValue(BlockDescriptor& block_descriptor, const char* name, value_assignment_t value, ParamDescriptor::validation_func_t validate_func, S32 min_count, S32 max_count)
+ : Param(block_descriptor.mCurrentBlockPtr),
+ mData(value)
+ {
+ if (block_descriptor.mInitializationState == BlockDescriptor::INITIALIZING)
+ {
+ ParamDescriptor param_descriptor(block_descriptor.mCurrentBlockPtr->getHandleFromParam(this),
+ &mergeWith,
+ &deserializeParam,
+ &serializeParam,
+ validate_func,
+ &inspectParam,
+ min_count, max_count);
+ BaseBlock::addParam(block_descriptor, param_descriptor, name);
+ }
+ }
+
+ // implicit conversion
+ operator value_assignment_t() const { return get(); }
+ // explicit conversion
+ value_assignment_t operator()() const { return get(); }
+
+ static bool deserializeParam(Param& param, Parser& parser, const Parser::name_stack_range_t& name_stack, S32 generation)
+ {
+ self_t& typed_param = static_cast<self_t&>(param);
+ // type to apply parse direct value T
+ if (name_stack.empty())
+ {
+ if(parser.readValue<T>(typed_param.mData.mValue))
+ {
+ typed_param.enclosingBlock().setLastChangedParam(param, true);
+ typed_param.setProvided(true);
+ typed_param.mData.mLastParamVersion = typed_param.BaseBlock::getLastChangeVersion();
+ return true;
+ }
+
+ if(!TypeValues<T>::empty())
+ {
+ // try to parse a known named value
+ std::string name;
+ if (parser.readValue<std::string>(name))
+ {
+ // try to parse a per type named value
+ if (TypeValues<T>::get(name, typed_param.mData.mValue))
+ {
+ typed_param.mData.setKey(name);
+ typed_param.enclosingBlock().setLastChangedParam(param, true);
+ typed_param.setProvided(true);
+ typed_param.mData.mLastParamVersion = typed_param.BaseBlock::getLastChangeVersion();
+ return true;
+ }
+ }
+ }
+ }
+
+ // fall back on parsing block components for T
+ // if we deserialized at least one component...
+ if (typed_param.BaseBlock::deserializeBlock(parser, name_stack))
+ {
+ // ...our block is provided, and considered changed
+ typed_param.enclosingBlock().setLastChangedParam(param, true);
+ typed_param.setProvided(true);
+ return true;
+ }
+ return false;
+ }
+
+ static void serializeParam(const Param& param, Parser& parser, Parser::name_stack_t& name_stack, const Param* diff_param)
+ {
+ const self_t& typed_param = static_cast<const self_t&>(param);
+
+ if (!typed_param.isProvided()) return;
+
+ std::string key = typed_param.mData.getKey();
+
+ // first try to write out name of name/value pair
+ if (!key.empty())
+ {
+ if (!diff_param || !ParamCompare<std::string>::equals(static_cast<const self_t*>(diff_param)->mData.getKey(), key))
+ {
+ if (!parser.writeValue<std::string>(key, name_stack))
+ {
+ return;
+ }
+ }
+ }
+ // then try to serialize value directly
+ else if (!diff_param || !ParamCompare<T>::equals(typed_param.get(), (static_cast<const self_t*>(diff_param))->get()))
+ {
+
+ if (parser.writeValue<T>(typed_param.mData.mValue, name_stack))
+ {
+ return;
+ }
+
+ //RN: *always* serialize provided components of BlockValue (don't pass diff_param on),
+ // since these tend to be viewed as the constructor arguments for the value T. It seems
+ // cleaner to treat the uniqueness of a BlockValue according to the generated value, and
+ // not the individual components. This way <color red="0" green="1" blue="0"/> will not
+ // be exported as <color green="1"/>, since it was probably the intent of the user to
+ // be specific about the RGB color values. This also fixes an issue where we distinguish
+ // between rect.left not being provided and rect.left being explicitly set to 0 (same as default)
+ typed_param.BaseBlock::serializeBlock(parser, name_stack, NULL);
+ }
+ }
+
+ static void inspectParam(const Param& param, Parser& parser, Parser::name_stack_t& name_stack, S32 min_count, S32 max_count)
+ {
+ // first, inspect with actual type...
+ parser.inspectValue<T>(name_stack, min_count, max_count, NULL);
+ if (TypeValues<T>::getPossibleValues())
+ {
+ //...then inspect with possible string values...
+ parser.inspectValue<std::string>(name_stack, min_count, max_count, TypeValues<T>::getPossibleValues());
+ }
+ // then recursively inspect contents...
+ const self_t& typed_param = static_cast<const self_t&>(param);
+ typed_param.inspectBlock(parser, name_stack);
+ }
+
+
+ bool isProvided() const
+ {
+ // either param value provided directly or block is sufficiently filled in
+ // if cached value is stale, regenerate from params
+ if (Param::getProvided() && mData.mLastParamVersion < BaseBlock::getLastChangeVersion())
+ {
+ if (block_t::validateBlock(true))
+ {
+ mData.mValue = static_cast<const DERIVED*>(this)->getValueFromBlock();
+ // clear stale keyword associated with old value
+ mData.clearKey();
+ mData.mLastParamVersion = BaseBlock::getLastChangeVersion();
+ return true;
+ }
+ else
+ {
+ //block value incomplete, so not considered provided
+ // will attempt to revalidate on next call to isProvided()
+ return false;
+ }
+ }
+ // either no data provided, or we have a valid value in hand
+ return Param::getProvided();
+ }
+
+ void set(value_assignment_t val, bool flag_as_provided = true)
+ {
+ Param::enclosingBlock().setLastChangedParam(*this, flag_as_provided);
+ // set param version number to be up to date, so we ignore block contents
+ mData.mLastParamVersion = BaseBlock::getLastChangeVersion();
+
+ mData.mValue = val;
+ mData.clearKey();
+ setProvided(flag_as_provided);
+ }
+
+ void setIfNotProvided(value_assignment_t val, bool flag_as_provided = true)
+ {
+ // don't override any user provided value
+ if (!isProvided())
+ {
+ set(val, flag_as_provided);
+ }
+ }
+
+ // propagate change status up to enclosing block
+ /*virtual*/ void setLastChangedParam(const Param& last_param, bool user_provided)
+ {
+ BaseBlock::setLastChangedParam(last_param, user_provided);
+ Param::enclosingBlock().setLastChangedParam(*this, user_provided);
+ if (user_provided)
+ {
+ setProvided(true); // some component provided
+ }
+ }
+
+ protected:
+ value_assignment_t get() const
+ {
+ if (mData.mLastParamVersion < BaseBlock::getLastChangeVersion() && block_t::validateBlock(true))
+ {
+ mData.mValue = static_cast<const DERIVED*>(this)->getValueFromBlock();
+ mData.clearKey();
+ mData.mLastParamVersion = BaseBlock::getLastChangeVersion();
+ }
+
+ return mData.mValue;
+ }
+
+ // mutable to allow lazy updates on get
+ struct Data : public key_cache_t
+ {
+ Data(const T& value)
+ : mValue(value),
+ mLastParamVersion(0)
+ {}
+
+ T mValue;
+ S32 mLastParamVersion;
+ };
+
+ mutable Data mData;
+
+ private:
+ static bool mergeWith(Param& dst, const Param& src, bool overwrite)
+ {
+ const self_t& src_param = static_cast<const self_t&>(src);
+ self_t& dst_typed_param = static_cast<self_t&>(dst);
+
+ if (src_param.isProvided()
+ && (overwrite || !dst_typed_param.isProvided()))
+ {
+ // assign individual parameters
+ if (overwrite)
+ {
+ dst_typed_param.BaseBlock::overwriteFromImpl(block_t::sBlockDescriptor, src_param);
+ }
+ else
+ {
+ dst_typed_param.BaseBlock::fillFromImpl(block_t::sBlockDescriptor, src_param);
+ }
+ // then copy actual value
+ dst_typed_param.mData.mValue = src_param.get();
+ dst_typed_param.mData.clearKey();
+ dst_typed_param.setProvided(true);
+ return true;
+ }
+ return false;
+ }
+ };
+
+ template<>
+ bool ParamCompare<boost::function<void (const std::string &,void *)> >::equals(
+ const boost::function<void (const std::string &,void *)> &a,
+ const boost::function<void (const std::string &,void *)> &b);
+
+ template<>
+ bool ParamCompare<boost::function<void (const LLSD &,const LLSD &)> >::equals(
+ const boost::function<void (const LLSD &,const LLSD &)> &a,
+ const boost::function<void (const LLSD &,const LLSD &)> &b);
+
+ template<>
+ bool ParamCompare<LLSD>::equals(const LLSD &a, const LLSD &b);
+}
+
+#endif // LL_LLPARAM_H
diff --git a/indra/llxuixml/llregistry.h b/indra/llxuixml/llregistry.h
new file mode 100644
index 0000000000..2c04d8c419
--- /dev/null
+++ b/indra/llxuixml/llregistry.h
@@ -0,0 +1,347 @@
+/**
+ * @file llregistry.h
+ * @brief template classes for registering name, value pairs in nested scopes, statically, etc.
+ *
+ * $LicenseInfo:firstyear=2001&license=viewergpl$
+ *
+ * Copyright (c) 2001-2009, Linden Research, Inc.
+ *
+ * Second Life Viewer Source Code
+ * The source code in this file ("Source Code") is provided by Linden Lab
+ * to you under the terms of the GNU General Public License, version 2.0
+ * ("GPL"), unless you have obtained a separate licensing agreement
+ * ("Other License"), formally executed by you and Linden Lab. Terms of
+ * the GPL can be found in doc/GPL-license.txt in this distribution, or
+ * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
+ *
+ * There are special exceptions to the terms and conditions of the GPL as
+ * it is applied to this Source Code. View the full text of the exception
+ * in the file doc/FLOSS-exception.txt in this software distribution, or
+ * online at
+ * http://secondlifegrid.net/programs/open_source/licensing/flossexception
+ *
+ * By copying, modifying or distributing this software, you acknowledge
+ * that you have read and understood your obligations described above,
+ * and agree to abide by those obligations.
+ *
+ * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+ * COMPLETENESS OR PERFORMANCE.
+ * $/LicenseInfo$
+ */
+
+#ifndef LL_LLREGISTRY_H
+#define LL_LLREGISTRY_H
+
+#include <list>
+
+#include <boost/type_traits.hpp>
+#include "llsingleton.h"
+
+template <typename T>
+class LLRegistryDefaultComparator
+{
+ bool operator()(const T& lhs, const T& rhs) { return lhs < rhs; }
+};
+
+template <typename KEY, typename VALUE, typename COMPARATOR = LLRegistryDefaultComparator<KEY> >
+class LLRegistry
+{
+public:
+ typedef LLRegistry<KEY, VALUE, COMPARATOR> registry_t;
+ typedef typename boost::add_reference<typename boost::add_const<KEY>::type>::type ref_const_key_t;
+ typedef typename boost::add_reference<typename boost::add_const<VALUE>::type>::type ref_const_value_t;
+ typedef typename boost::add_reference<VALUE>::type ref_value_t;
+ typedef typename boost::add_pointer<typename boost::add_const<VALUE>::type>::type ptr_const_value_t;
+ typedef typename boost::add_pointer<VALUE>::type ptr_value_t;
+
+ class Registrar
+ {
+ friend class LLRegistry<KEY, VALUE, COMPARATOR>;
+ public:
+ typedef typename std::map<KEY, VALUE> registry_map_t;
+
+ bool add(ref_const_key_t key, ref_const_value_t value)
+ {
+ if (mMap.insert(std::make_pair(key, value)).second == false)
+ {
+ llwarns << "Tried to register " << key << " but it was already registered!" << llendl;
+ return false;
+ }
+ return true;
+ }
+
+ void remove(ref_const_key_t key)
+ {
+ mMap.erase(key);
+ }
+
+ typename registry_map_t::const_iterator beginItems() const
+ {
+ return mMap.begin();
+ }
+
+ typename registry_map_t::const_iterator endItems() const
+ {
+ return mMap.end();
+ }
+
+ protected:
+ ptr_value_t getValue(ref_const_key_t key)
+ {
+ typename registry_map_t::iterator found_it = mMap.find(key);
+ if (found_it != mMap.end())
+ {
+ return &(found_it->second);
+ }
+ return NULL;
+ }
+
+ ptr_const_value_t getValue(ref_const_key_t key) const
+ {
+ typename registry_map_t::const_iterator found_it = mMap.find(key);
+ if (found_it != mMap.end())
+ {
+ return &(found_it->second);
+ }
+ return NULL;
+ }
+
+ // if the registry is used to store pointers, and null values are valid entries
+ // then use this function to check the existence of an entry
+ bool exists(ref_const_key_t key) const
+ {
+ return mMap.find(key) != mMap.end();
+ }
+
+ bool empty() const
+ {
+ return mMap.empty();
+ }
+
+ protected:
+ // use currentRegistrar() or defaultRegistrar()
+ Registrar() {}
+ ~Registrar() {}
+
+ private:
+ registry_map_t mMap;
+ };
+
+ typedef typename std::list<Registrar*> scope_list_t;
+ typedef typename std::list<Registrar*>::iterator scope_list_iterator_t;
+ typedef typename std::list<Registrar*>::const_iterator scope_list_const_iterator_t;
+
+ LLRegistry()
+ {}
+
+ ~LLRegistry() {}
+
+ ptr_value_t getValue(ref_const_key_t key)
+ {
+ for(scope_list_iterator_t it = mActiveScopes.begin();
+ it != mActiveScopes.end();
+ ++it)
+ {
+ ptr_value_t valuep = (*it)->getValue(key);
+ if (valuep != NULL) return valuep;
+ }
+ return mDefaultRegistrar.getValue(key);
+ }
+
+ ptr_const_value_t getValue(ref_const_key_t key) const
+ {
+ for(scope_list_const_iterator_t it = mActiveScopes.begin();
+ it != mActiveScopes.end();
+ ++it)
+ {
+ ptr_value_t valuep = (*it)->getValue(key);
+ if (valuep != NULL) return valuep;
+ }
+ return mDefaultRegistrar.getValue(key);
+ }
+
+ bool exists(ref_const_key_t key) const
+ {
+ for(scope_list_const_iterator_t it = mActiveScopes.begin();
+ it != mActiveScopes.end();
+ ++it)
+ {
+ if ((*it)->exists(key)) return true;
+ }
+
+ return mDefaultRegistrar.exists(key);
+ }
+
+ bool empty() const
+ {
+ for(scope_list_const_iterator_t it = mActiveScopes.begin();
+ it != mActiveScopes.end();
+ ++it)
+ {
+ if (!(*it)->empty()) return false;
+ }
+
+ return mDefaultRegistrar.empty();
+ }
+
+
+ Registrar& defaultRegistrar()
+ {
+ return mDefaultRegistrar;
+ }
+
+ const Registrar& defaultRegistrar() const
+ {
+ return mDefaultRegistrar;
+ }
+
+
+ Registrar& currentRegistrar()
+ {
+ if (!mActiveScopes.empty())
+ {
+ return *mActiveScopes.front();
+ }
+
+ return mDefaultRegistrar;
+ }
+
+ const Registrar& currentRegistrar() const
+ {
+ if (!mActiveScopes.empty())
+ {
+ return *mActiveScopes.front();
+ }
+
+ return mDefaultRegistrar;
+ }
+
+
+protected:
+ void addScope(Registrar* scope)
+ {
+ // newer scopes go up front
+ mActiveScopes.insert(mActiveScopes.begin(), scope);
+ }
+
+ void removeScope(Registrar* scope)
+ {
+ // O(N) but should be near the beggining and N should be small and this is safer than storing iterators
+ scope_list_iterator_t iter = std::find(mActiveScopes.begin(), mActiveScopes.end(), scope);
+ if (iter != mActiveScopes.end())
+ {
+ mActiveScopes.erase(iter);
+ }
+ }
+
+private:
+ scope_list_t mActiveScopes;
+ Registrar mDefaultRegistrar;
+};
+
+template <typename KEY, typename VALUE, typename DERIVED_TYPE, typename COMPARATOR = LLRegistryDefaultComparator<KEY> >
+class LLRegistrySingleton
+ : public LLRegistry<KEY, VALUE, COMPARATOR>,
+ public LLSingleton<DERIVED_TYPE>
+{
+ friend class LLSingleton<DERIVED_TYPE>;
+public:
+ typedef LLRegistry<KEY, VALUE, COMPARATOR> registry_t;
+ typedef const KEY& ref_const_key_t;
+ typedef const VALUE& ref_const_value_t;
+ typedef VALUE* ptr_value_t;
+ typedef const VALUE* ptr_const_value_t;
+ typedef LLSingleton<DERIVED_TYPE> singleton_t;
+
+ class ScopedRegistrar : public registry_t::Registrar
+ {
+ public:
+ ScopedRegistrar(bool push_scope = true)
+ {
+ if (push_scope)
+ {
+ pushScope();
+ }
+ }
+
+ ~ScopedRegistrar()
+ {
+ if (!singleton_t::destroyed())
+ {
+ popScope();
+ }
+ }
+
+ void pushScope()
+ {
+ singleton_t::instance().addScope(this);
+ }
+
+ void popScope()
+ {
+ singleton_t::instance().removeScope(this);
+ }
+
+ ptr_value_t getValueFromScope(ref_const_key_t key)
+ {
+ return getValue(key);
+ }
+
+ ptr_const_value_t getValueFromScope(ref_const_key_t key) const
+ {
+ return getValue(key);
+ }
+
+ private:
+ typename std::list<typename registry_t::Registrar*>::iterator mListIt;
+ };
+
+ class StaticRegistrar : public registry_t::Registrar
+ {
+ public:
+ virtual ~StaticRegistrar() {}
+ StaticRegistrar(ref_const_key_t key, ref_const_value_t value)
+ {
+ singleton_t::instance().mStaticScope->add(key, value);
+ }
+ };
+
+ // convenience functions
+ typedef typename LLRegistry<KEY, VALUE, COMPARATOR>::Registrar& ref_registrar_t;
+ static ref_registrar_t currentRegistrar()
+ {
+ return singleton_t::instance().registry_t::currentRegistrar();
+ }
+
+ static ref_registrar_t defaultRegistrar()
+ {
+ return singleton_t::instance().registry_t::defaultRegistrar();
+ }
+
+ static ptr_value_t getValue(ref_const_key_t key)
+ {
+ return singleton_t::instance().registry_t::getValue(key);
+ }
+
+protected:
+ // DERIVED_TYPE needs to derive from LLRegistrySingleton
+ LLRegistrySingleton()
+ : mStaticScope(NULL)
+ {}
+
+ virtual void initSingleton()
+ {
+ mStaticScope = new ScopedRegistrar();
+ }
+
+ virtual ~LLRegistrySingleton()
+ {
+ delete mStaticScope;
+ }
+
+private:
+ ScopedRegistrar* mStaticScope;
+};
+
+#endif
diff --git a/indra/llxuixml/lltrans.cpp b/indra/llxuixml/lltrans.cpp
new file mode 100644
index 0000000000..2efc475f57
--- /dev/null
+++ b/indra/llxuixml/lltrans.cpp
@@ -0,0 +1,196 @@
+/**
+ * @file lltrans.cpp
+ * @brief LLTrans implementation
+ *
+ * $LicenseInfo:firstyear=2000&license=viewergpl$
+ *
+ * Copyright (c) 2000-2009, Linden Research, Inc.
+ *
+ * Second Life Viewer Source Code
+ * The source code in this file ("Source Code") is provided by Linden Lab
+ * to you under the terms of the GNU General Public License, version 2.0
+ * ("GPL"), unless you have obtained a separate licensing agreement
+ * ("Other License"), formally executed by you and Linden Lab. Terms of
+ * the GPL can be found in doc/GPL-license.txt in this distribution, or
+ * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
+ *
+ * There are special exceptions to the terms and conditions of the GPL as
+ * it is applied to this Source Code. View the full text of the exception
+ * in the file doc/FLOSS-exception.txt in this software distribution, or
+ * online at
+ * http://secondlifegrid.net/programs/open_source/licensing/flossexception
+ *
+ * By copying, modifying or distributing this software, you acknowledge
+ * that you have read and understood your obligations described above,
+ * and agree to abide by those obligations.
+ *
+ * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+ * COMPLETENESS OR PERFORMANCE.
+ * $/LicenseInfo$
+ */
+
+#include "linden_common.h"
+
+#include "lltrans.h"
+
+#include "llfasttimer.h" // for call count statistics
+#include "llxuiparser.h"
+
+#include <map>
+
+LLTrans::template_map_t LLTrans::sStringTemplates;
+LLStringUtil::format_map_t LLTrans::sDefaultArgs;
+
+struct StringDef : public LLInitParam::Block<StringDef>
+{
+ Mandatory<std::string> name;
+ Mandatory<std::string> value;
+
+ StringDef()
+ : name("name"),
+ value("value")
+ {}
+};
+
+struct StringTable : public LLInitParam::Block<StringTable>
+{
+ Multiple<StringDef> strings;
+ StringTable()
+ : strings("string")
+ {}
+};
+
+//static
+bool LLTrans::parseStrings(LLXMLNodePtr &root, const std::set<std::string>& default_args)
+{
+ std::string xml_filename = "(strings file)";
+ if (!root->hasName("strings"))
+ {
+ llerrs << "Invalid root node name in " << xml_filename
+ << ": was " << root->getName() << ", expected \"strings\"" << llendl;
+ }
+
+ StringTable string_table;
+ LLXUIParser::instance().readXUI(root, string_table);
+
+ if (!string_table.validateBlock())
+ {
+ llerrs << "Problem reading strings: " << xml_filename << llendl;
+ return false;
+ }
+
+ sStringTemplates.clear();
+ sDefaultArgs.clear();
+
+ for(LLInitParam::ParamIterator<StringDef>::const_iterator it = string_table.strings().begin();
+ it != string_table.strings().end();
+ ++it)
+ {
+ LLTransTemplate xml_template(it->name, it->value);
+ sStringTemplates[xml_template.mName] = xml_template;
+
+ std::set<std::string>::const_iterator iter = default_args.find(xml_template.mName);
+ if (iter != default_args.end())
+ {
+ std::string name = *iter;
+ if (name[0] != '[')
+ name = llformat("[%s]",name.c_str());
+ sDefaultArgs[name] = xml_template.mText;
+ }
+ }
+
+ return true;
+}
+
+
+//static
+bool LLTrans::parseLanguageStrings(LLXMLNodePtr &root)
+{
+ std::string xml_filename = "(language strings file)";
+ if (!root->hasName("strings"))
+ {
+ llerrs << "Invalid root node name in " << xml_filename
+ << ": was " << root->getName() << ", expected \"strings\"" << llendl;
+ }
+
+ StringTable string_table;
+ LLXUIParser::instance().readXUI(root, string_table);
+
+ if (!string_table.validateBlock())
+ {
+ llerrs << "Problem reading strings: " << xml_filename << llendl;
+ return false;
+ }
+
+ for(LLInitParam::ParamIterator<StringDef>::const_iterator it = string_table.strings().begin();
+ it != string_table.strings().end();
+ ++it)
+ {
+ // share the same map with parseStrings() so we can search the strings using the same getString() function.- angela
+ LLTransTemplate xml_template(it->name, it->value);
+ sStringTemplates[xml_template.mName] = xml_template;
+ }
+
+ return true;
+}
+
+
+
+static LLFastTimer::DeclareTimer FTM_GET_TRANS("Translate string");
+
+//static
+std::string LLTrans::getString(const std::string &xml_desc, const LLStringUtil::format_map_t& msg_args)
+{
+ // Don't care about time as much as call count. Make sure we're not
+ // calling LLTrans::getString() in an inner loop. JC
+ LLFastTimer timer(FTM_GET_TRANS);
+
+ template_map_t::iterator iter = sStringTemplates.find(xml_desc);
+ if (iter != sStringTemplates.end())
+ {
+ std::string text = iter->second.mText;
+ LLStringUtil::format_map_t args = sDefaultArgs;
+ args.insert(msg_args.begin(), msg_args.end());
+ LLStringUtil::format(text, args);
+
+ return text;
+ }
+ else
+ {
+ LLSD args;
+ args["STRING_NAME"] = xml_desc;
+ LL_WARNS_ONCE("configuration") << "Missing String in strings.xml: [" << xml_desc << "]" << LL_ENDL;
+
+ //LLNotifications::instance().add("MissingString", args); // *TODO: resurrect
+ //return xml_desc;
+
+ return "MissingString("+xml_desc+")";
+ }
+}
+
+//static
+bool LLTrans::findString(std::string &result, const std::string &xml_desc, const LLStringUtil::format_map_t& msg_args)
+{
+ LLFastTimer timer(FTM_GET_TRANS);
+
+ template_map_t::iterator iter = sStringTemplates.find(xml_desc);
+ if (iter != sStringTemplates.end())
+ {
+ std::string text = iter->second.mText;
+ LLStringUtil::format_map_t args = sDefaultArgs;
+ args.insert(msg_args.begin(), msg_args.end());
+ LLStringUtil::format(text, args);
+ result = text;
+ return true;
+ }
+ else
+ {
+ LLSD args;
+ args["STRING_NAME"] = xml_desc;
+ LL_WARNS_ONCE("configuration") << "Missing String in strings.xml: [" << xml_desc << "]" << LL_ENDL;
+ //LLNotifications::instance().add("MissingString", args);
+
+ return false;
+ }
+}
diff --git a/indra/llxuixml/lltrans.h b/indra/llxuixml/lltrans.h
new file mode 100644
index 0000000000..340d70e434
--- /dev/null
+++ b/indra/llxuixml/lltrans.h
@@ -0,0 +1,119 @@
+/**
+ * @file lltrans.h
+ * @brief LLTrans definition
+ *
+ * $LicenseInfo:firstyear=2000&license=viewergpl$
+ *
+ * Copyright (c) 2000-2009, Linden Research, Inc.
+ *
+ * Second Life Viewer Source Code
+ * The source code in this file ("Source Code") is provided by Linden Lab
+ * to you under the terms of the GNU General Public License, version 2.0
+ * ("GPL"), unless you have obtained a separate licensing agreement
+ * ("Other License"), formally executed by you and Linden Lab. Terms of
+ * the GPL can be found in doc/GPL-license.txt in this distribution, or
+ * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
+ *
+ * There are special exceptions to the terms and conditions of the GPL as
+ * it is applied to this Source Code. View the full text of the exception
+ * in the file doc/FLOSS-exception.txt in this software distribution, or
+ * online at
+ * http://secondlifegrid.net/programs/open_source/licensing/flossexception
+ *
+ * By copying, modifying or distributing this software, you acknowledge
+ * that you have read and understood your obligations described above,
+ * and agree to abide by those obligations.
+ *
+ * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+ * COMPLETENESS OR PERFORMANCE.
+ * $/LicenseInfo$
+ */
+
+#ifndef LL_TRANS_H
+#define LL_TRANS_H
+
+#include <map>
+
+#include "llstring.h"
+#include "llxmlnode.h"
+
+/**
+ * @brief String template loaded from strings.xml
+ */
+class LLTransTemplate
+{
+public:
+ LLTransTemplate(const std::string& name = LLStringUtil::null, const std::string& text = LLStringUtil::null) : mName(name), mText(text) {}
+
+ std::string mName;
+ std::string mText;
+};
+
+/**
+ * @brief Localized strings class
+ * This class is used to retrieve translations of strings used to build larger ones, as well as
+ * strings with a general usage that don't belong to any specific floater. For example,
+ * "Owner:", "Retrieving..." used in the place of a not yet known name, etc.
+ */
+class LLTrans
+{
+public:
+ LLTrans();
+
+ /**
+ * @brief Parses the xml root that holds the strings. Used once on startup
+// *FIXME * @param xml_filename Filename to parse
+ * @param default_args Set of strings (expected to be in the file) to use as default replacement args, e.g. "SECOND_LIFE"
+ * @returns true if the file was parsed successfully, true if something went wrong
+ */
+ static bool parseStrings(LLXMLNodePtr& root, const std::set<std::string>& default_args);
+
+ static bool parseLanguageStrings(LLXMLNodePtr &root);
+
+ /**
+ * @brief Returns a translated string
+ * @param xml_desc String's description
+ * @param args A list of substrings to replace in the string
+ * @returns Translated string
+ */
+ static std::string getString(const std::string &xml_desc, const LLStringUtil::format_map_t& args);
+ static bool findString(std::string &result, const std::string &xml_desc, const LLStringUtil::format_map_t& args);
+
+ /**
+ * @brief Returns a translated string
+ * @param xml_desc String's description
+ * @returns Translated string
+ */
+ static std::string getString(const std::string &xml_desc)
+ {
+ LLStringUtil::format_map_t empty;
+ return getString(xml_desc, empty);
+ }
+
+ static bool findString(std::string &result, const std::string &xml_desc)
+ {
+ LLStringUtil::format_map_t empty;
+ return findString(result, xml_desc, empty);
+ }
+
+
+ // get the default args
+ static const LLStringUtil::format_map_t& getDefaultArgs()
+ {
+ return sDefaultArgs;
+ }
+
+ // insert default args into an arg list
+ static void getArgs(LLStringUtil::format_map_t& args)
+ {
+ args.insert(sDefaultArgs.begin(), sDefaultArgs.end());
+ }
+
+private:
+ typedef std::map<std::string, LLTransTemplate > template_map_t;
+ static template_map_t sStringTemplates;
+ static LLStringUtil::format_map_t sDefaultArgs;
+};
+
+#endif
diff --git a/indra/llxuixml/lluicolor.cpp b/indra/llxuixml/lluicolor.cpp
new file mode 100644
index 0000000000..ef0fa5d634
--- /dev/null
+++ b/indra/llxuixml/lluicolor.cpp
@@ -0,0 +1,71 @@
+/**
+ * @file lluicolor.cpp
+ * @brief brief LLUIColor class implementation file
+ *
+ * $LicenseInfo:firstyear=2009&license=viewergpl$
+ * Copyright (c) 2009, Linden Research, Inc.
+ * $/LicenseInfo$
+ */
+
+#include "lluicolor.h"
+
+LLUIColor::LLUIColor()
+ :mColorPtr(NULL)
+{
+}
+
+LLUIColor::LLUIColor(const LLColor4* color)
+ :mColorPtr(color)
+{
+}
+
+LLUIColor::LLUIColor(const LLColor4& color)
+ :mColor(color), mColorPtr(NULL)
+{
+}
+
+void LLUIColor::set(const LLColor4& color)
+{
+ mColor = color;
+ mColorPtr = NULL;
+}
+
+void LLUIColor::set(const LLColor4* color)
+{
+ mColorPtr = color;
+}
+
+const LLColor4& LLUIColor::get() const
+{
+ return (mColorPtr == NULL ? mColor : *mColorPtr);
+}
+
+LLUIColor::operator const LLColor4& () const
+{
+ return get();
+}
+
+const LLColor4& LLUIColor::operator()() const
+{
+ return get();
+}
+
+bool LLUIColor::isReference() const
+{
+ return mColorPtr != NULL;
+}
+
+namespace LLInitParam
+{
+ // used to detect equivalence with default values on export
+ template<>
+ class ParamCompare<LLUIColor>
+ {
+ public:
+ static bool equals(const LLUIColor &a, const LLUIColor &b)
+ {
+ // do not detect value equivalence, treat pointers to colors as distinct from color values
+ return (a.mColorPtr == NULL && b.mColorPtr == NULL ? a.mColor == b.mColor : a.mColorPtr == b.mColorPtr);
+ }
+ };
+}
diff --git a/indra/llxuixml/lluicolor.h b/indra/llxuixml/lluicolor.h
new file mode 100644
index 0000000000..365f61003b
--- /dev/null
+++ b/indra/llxuixml/lluicolor.h
@@ -0,0 +1,45 @@
+/**
+ * @file lluicolor.h
+ * @brief brief LLUIColor class header file
+ *
+ * $LicenseInfo:firstyear=2009&license=viewergpl$
+ * Copyright (c) 2009, Linden Research, Inc.
+ * $/LicenseInfo$
+ */
+
+#ifndef LL_LLUICOLOR_H_
+#define LL_LLUICOLOR_H_
+
+#include "v4color.h"
+
+namespace LLInitParam
+{
+ template<typename T>
+ class ParamCompare;
+}
+
+class LLUIColor
+{
+public:
+ LLUIColor();
+ LLUIColor(const LLColor4* color);
+ LLUIColor(const LLColor4& color);
+
+ void set(const LLColor4& color);
+ void set(const LLColor4* color);
+
+ const LLColor4& get() const;
+
+ operator const LLColor4& () const;
+ const LLColor4& operator()() const;
+
+ bool isReference() const;
+
+private:
+ friend class LLInitParam::ParamCompare<LLUIColor>;
+
+ const LLColor4* mColorPtr;
+ LLColor4 mColor;
+};
+
+#endif
diff --git a/indra/llxuixml/llxuiparser.cpp b/indra/llxuixml/llxuiparser.cpp
new file mode 100644
index 0000000000..e28e52fd16
--- /dev/null
+++ b/indra/llxuixml/llxuiparser.cpp
@@ -0,0 +1,968 @@
+/**
+ * @file llxuiparser.cpp
+ * @brief Utility functions for handling XUI structures in XML
+ *
+ * $LicenseInfo:firstyear=2003&license=viewergpl$
+ *
+ * Copyright (c) 2003-2009, Linden Research, Inc.
+ *
+ * Second Life Viewer Source Code
+ * The source code in this file ("Source Code") is provided by Linden Lab
+ * to you under the terms of the GNU General Public License, version 2.0
+ * ("GPL"), unless you have obtained a separate licensing agreement
+ * ("Other License"), formally executed by you and Linden Lab. Terms of
+ * the GPL can be found in doc/GPL-license.txt in this distribution, or
+ * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
+ *
+ * There are special exceptions to the terms and conditions of the GPL as
+ * it is applied to this Source Code. View the full text of the exception
+ * in the file doc/FLOSS-exception.txt in this software distribution, or
+ * online at
+ * http://secondlifegrid.net/programs/open_source/licensing/flossexception
+ *
+ * By copying, modifying or distributing this software, you acknowledge
+ * that you have read and understood your obligations described above,
+ * and agree to abide by those obligations.
+ *
+ * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+ * COMPLETENESS OR PERFORMANCE.
+ * $/LicenseInfo$
+ */
+
+#include "linden_common.h"
+
+#include "llxuiparser.h"
+
+#include <fstream>
+#include <boost/tokenizer.hpp>
+
+#include "lluicolor.h"
+
+const S32 MAX_STRING_ATTRIBUTE_SIZE = 40;
+
+//
+// LLXSDWriter
+//
+LLXSDWriter::LLXSDWriter()
+{
+ registerInspectFunc<bool>(boost::bind(&LLXSDWriter::writeAttribute, this, "xs:boolean", _1, _2, _3, _4));
+ registerInspectFunc<std::string>(boost::bind(&LLXSDWriter::writeAttribute, this, "xs:string", _1, _2, _3, _4));
+ registerInspectFunc<U8>(boost::bind(&LLXSDWriter::writeAttribute, this, "xs:unsignedByte", _1, _2, _3, _4));
+ registerInspectFunc<S8>(boost::bind(&LLXSDWriter::writeAttribute, this, "xs:signedByte", _1, _2, _3, _4));
+ registerInspectFunc<U16>(boost::bind(&LLXSDWriter::writeAttribute, this, "xs:unsignedShort", _1, _2, _3, _4));
+ registerInspectFunc<S16>(boost::bind(&LLXSDWriter::writeAttribute, this, "xs:signedShort", _1, _2, _3, _4));
+ registerInspectFunc<U32>(boost::bind(&LLXSDWriter::writeAttribute, this, "xs:unsignedInt", _1, _2, _3, _4));
+ registerInspectFunc<S32>(boost::bind(&LLXSDWriter::writeAttribute, this, "xs:integer", _1, _2, _3, _4));
+ registerInspectFunc<F32>(boost::bind(&LLXSDWriter::writeAttribute, this, "xs:float", _1, _2, _3, _4));
+ registerInspectFunc<F64>(boost::bind(&LLXSDWriter::writeAttribute, this, "xs:double", _1, _2, _3, _4));
+ registerInspectFunc<LLColor4>(boost::bind(&LLXSDWriter::writeAttribute, this, "xs:string", _1, _2, _3, _4));
+ registerInspectFunc<LLUIColor>(boost::bind(&LLXSDWriter::writeAttribute, this, "xs:string", _1, _2, _3, _4));
+ registerInspectFunc<LLUUID>(boost::bind(&LLXSDWriter::writeAttribute, this, "xs:string", _1, _2, _3, _4));
+ registerInspectFunc<LLSD>(boost::bind(&LLXSDWriter::writeAttribute, this, "xs:string", _1, _2, _3, _4));
+}
+
+void LLXSDWriter::writeXSD(const std::string& type_name, LLXMLNodePtr node, const LLInitParam::BaseBlock& block, const std::string& xml_namespace)
+{
+ mSchemaNode = node;
+ node->setName("xs:schema");
+ node->createChild("attributeFormDefault", true)->setStringValue("unqualified");
+ node->createChild("elementFormDefault", true)->setStringValue("qualified");
+ node->createChild("targetNamespace", true)->setStringValue(xml_namespace);
+ node->createChild("xmlns:xs", true)->setStringValue("http://www.w3.org/2001/XMLSchema");
+ node->createChild("xmlns", true)->setStringValue(xml_namespace);
+
+ node = node->createChild("xs:complexType", false);
+ node->createChild("name", true)->setStringValue(type_name);
+ node->createChild("mixed", true)->setStringValue("true");
+
+ mAttributeNode = node;
+ mElementNode = node->createChild("xs:choice", false);
+ mElementNode->createChild("minOccurs", true)->setStringValue("0");
+ mElementNode->createChild("maxOccurs", true)->setStringValue("unbounded");
+ block.inspectBlock(*this);
+
+ // duplicate element choices
+ LLXMLNodeList children;
+ mElementNode->getChildren("xs:element", children, FALSE);
+ for (LLXMLNodeList::iterator child_it = children.begin(); child_it != children.end(); ++child_it)
+ {
+ LLXMLNodePtr child_copy = child_it->second->deepCopy();
+ std::string child_name;
+ child_copy->getAttributeString("name", child_name);
+ child_copy->setAttributeString("name", type_name + "." + child_name);
+ mElementNode->addChild(child_copy);
+ }
+
+ LLXMLNodePtr element_declaration_node = mSchemaNode->createChild("xs:element", false);
+ element_declaration_node->createChild("name", true)->setStringValue(type_name);
+ element_declaration_node->createChild("type", true)->setStringValue(type_name);
+}
+
+void LLXSDWriter::writeAttribute(const std::string& type, const Parser::name_stack_t& stack, S32 min_count, S32 max_count, const std::vector<std::string>* possible_values)
+{
+ name_stack_t non_empty_names;
+ std::string attribute_name;
+ for (name_stack_t::const_iterator it = stack.begin();
+ it != stack.end();
+ ++it)
+ {
+ const std::string& name = it->first;
+ if (!name.empty())
+ {
+ non_empty_names.push_back(*it);
+ }
+ }
+
+ for (name_stack_t::const_iterator it = non_empty_names.begin();
+ it != non_empty_names.end();
+ ++it)
+ {
+ if (!attribute_name.empty())
+ {
+ attribute_name += ".";
+ }
+ attribute_name += it->first;
+ }
+
+ // only flag non-nested attributes as mandatory, nested attributes have variant syntax
+ // that can't be properly constrained in XSD
+ // e.g. <foo mandatory.value="bar"/> vs <foo><mandatory value="bar"/></foo>
+ bool attribute_mandatory = min_count == 1 && max_count == 1 && non_empty_names.size() == 1;
+
+ // don't bother supporting "Multiple" params as xml attributes
+ if (max_count <= 1)
+ {
+ // add compound attribute to root node
+ addAttributeToSchema(mAttributeNode, attribute_name, type, attribute_mandatory, possible_values);
+ }
+
+ // now generated nested elements for compound attributes
+ if (non_empty_names.size() > 1 && !attribute_mandatory)
+ {
+ std::string element_name;
+
+ // traverse all but last element, leaving that as an attribute name
+ name_stack_t::const_iterator end_it = non_empty_names.end();
+ end_it--;
+
+ for (name_stack_t::const_iterator it = non_empty_names.begin();
+ it != end_it;
+ ++it)
+ {
+ if (it != non_empty_names.begin())
+ {
+ element_name += ".";
+ }
+ element_name += it->first;
+ }
+
+ std::string short_attribute_name = non_empty_names.back().first;
+
+ LLXMLNodePtr complex_type_node;
+
+ // find existing element node here, starting at tail of child list
+ if (mElementNode->mChildren.notNull())
+ {
+ for(LLXMLNodePtr element = mElementNode->mChildren->tail;
+ element.notNull();
+ element = element->mPrev)
+ {
+ std::string name;
+ if(element->getAttributeString("name", name) && name == element_name)
+ {
+ complex_type_node = element->mChildren->head;
+ break;
+ }
+ }
+ }
+ //create complex_type node
+ //
+ //<xs:element
+ // maxOccurs="1"
+ // minOccurs="0"
+ // name="name">
+ // <xs:complexType>
+ // </xs:complexType>
+ //</xs:element>
+ if(complex_type_node.isNull())
+ {
+ complex_type_node = mElementNode->createChild("xs:element", false);
+
+ complex_type_node->createChild("minOccurs", true)->setIntValue(min_count);
+ complex_type_node->createChild("maxOccurs", true)->setIntValue(max_count);
+ complex_type_node->createChild("name", true)->setStringValue(element_name);
+ complex_type_node = complex_type_node->createChild("xs:complexType", false);
+ }
+
+ addAttributeToSchema(complex_type_node, short_attribute_name, type, false, possible_values);
+ }
+}
+
+void LLXSDWriter::addAttributeToSchema(LLXMLNodePtr type_declaration_node, const std::string& attribute_name, const std::string& type, bool mandatory, const std::vector<std::string>* possible_values)
+{
+ if (!attribute_name.empty())
+ {
+ LLXMLNodePtr new_enum_type_node;
+ if (possible_values != NULL)
+ {
+ // custom attribute type, for example
+ //<xs:simpleType>
+ // <xs:restriction
+ // base="xs:string">
+ // <xs:enumeration
+ // value="a" />
+ // <xs:enumeration
+ // value="b" />
+ // </xs:restriction>
+ // </xs:simpleType>
+ new_enum_type_node = new LLXMLNode("xs:simpleType", false);
+
+ LLXMLNodePtr restriction_node = new_enum_type_node->createChild("xs:restriction", false);
+ restriction_node->createChild("base", true)->setStringValue("xs:string");
+
+ for (std::vector<std::string>::const_iterator it = possible_values->begin();
+ it != possible_values->end();
+ ++it)
+ {
+ LLXMLNodePtr enum_node = restriction_node->createChild("xs:enumeration", false);
+ enum_node->createChild("value", true)->setStringValue(*it);
+ }
+ }
+
+ string_set_t& attributes_written = mAttributesWritten[type_declaration_node];
+
+ string_set_t::iterator found_it = attributes_written.lower_bound(attribute_name);
+
+ // attribute not yet declared
+ if (found_it == attributes_written.end() || attributes_written.key_comp()(attribute_name, *found_it))
+ {
+ attributes_written.insert(found_it, attribute_name);
+
+ LLXMLNodePtr attribute_node = type_declaration_node->createChild("xs:attribute", false);
+
+ // attribute name
+ attribute_node->createChild("name", true)->setStringValue(attribute_name);
+
+ if (new_enum_type_node.notNull())
+ {
+ attribute_node->addChild(new_enum_type_node);
+ }
+ else
+ {
+ // simple attribute type
+ attribute_node->createChild("type", true)->setStringValue(type);
+ }
+
+ // required or optional
+ attribute_node->createChild("use", true)->setStringValue(mandatory ? "required" : "optional");
+ }
+ // attribute exists...handle collision of same name attributes with potentially different types
+ else
+ {
+ LLXMLNodePtr attribute_declaration;
+ if (type_declaration_node.notNull())
+ {
+ for(LLXMLNodePtr node = type_declaration_node->mChildren->tail;
+ node.notNull();
+ node = node->mPrev)
+ {
+ std::string name;
+ if (node->getAttributeString("name", name) && name == attribute_name)
+ {
+ attribute_declaration = node;
+ break;
+ }
+ }
+ }
+
+ bool new_type_is_enum = new_enum_type_node.notNull();
+ bool existing_type_is_enum = !attribute_declaration->hasAttribute("type");
+
+ // either type is enum, revert to string in collision
+ // don't bother to check for enum equivalence
+ if (new_type_is_enum || existing_type_is_enum)
+ {
+ if (attribute_declaration->hasAttribute("type"))
+ {
+ attribute_declaration->setAttributeString("type", "xs:string");
+ }
+ else
+ {
+ attribute_declaration->createChild("type", true)->setStringValue("xs:string");
+ }
+ attribute_declaration->deleteChildren("xs:simpleType");
+ }
+ else
+ {
+ // check for collision of different standard types
+ std::string existing_type;
+ attribute_declaration->getAttributeString("type", existing_type);
+ // if current type is not the same as the new type, revert to strnig
+ if (existing_type != type)
+ {
+ // ...than use most general type, string
+ attribute_declaration->setAttributeString("type", "string");
+ }
+ }
+ }
+ }
+}
+
+//
+// LLXUIXSDWriter
+//
+void LLXUIXSDWriter::writeXSD(const std::string& type_name, const std::string& path, const LLInitParam::BaseBlock& block)
+{
+ std::string file_name(path);
+ file_name += type_name + ".xsd";
+ LLXMLNodePtr root_nodep = new LLXMLNode();
+
+ LLXSDWriter::writeXSD(type_name, root_nodep, block, "http://www.lindenlab.com/xui");
+
+ // add includes for all possible children
+ const std::type_info* type = *LLWidgetTypeRegistry::instance().getValue(type_name);
+ const widget_registry_t* widget_registryp = LLChildRegistryRegistry::instance().getValue(type);
+
+ // add include declarations for all valid children
+ for (widget_registry_t::Registrar::registry_map_t::const_iterator it = widget_registryp->currentRegistrar().beginItems();
+ it != widget_registryp->currentRegistrar().endItems();
+ ++it)
+ {
+ std::string widget_name = it->first;
+ if (widget_name == type_name)
+ {
+ continue;
+ }
+ LLXMLNodePtr nodep = new LLXMLNode("xs:include", false);
+ nodep->createChild("schemaLocation", true)->setStringValue(widget_name + ".xsd");
+
+ // add to front of schema
+ mSchemaNode->addChild(nodep, mSchemaNode);
+ }
+
+ // add choices for valid children
+ if (widget_registryp)
+ {
+ for (widget_registry_t::Registrar::registry_map_t::const_iterator it = widget_registryp->currentRegistrar().beginItems();
+ it != widget_registryp->currentRegistrar().endItems();
+ ++it)
+ {
+ std::string widget_name = it->first;
+ //<xs:element name="widget_name" type="widget_name">
+ LLXMLNodePtr widget_node = mElementNode->createChild("xs:element", false);
+ widget_node->createChild("name", true)->setStringValue(widget_name);
+ widget_node->createChild("type", true)->setStringValue(widget_name);
+ }
+ }
+
+ LLFILE* xsd_file = LLFile::fopen(file_name.c_str(), "w");
+ LLXMLNode::writeHeaderToFile(xsd_file);
+ root_nodep->writeToFile(xsd_file);
+ fclose(xsd_file);
+}
+
+//
+// LLXUIParser
+//
+LLXUIParser::LLXUIParser()
+: mLastWriteGeneration(-1),
+ mCurReadDepth(0)
+{
+ registerParserFuncs<bool>(boost::bind(&LLXUIParser::readBoolValue, this, _1),
+ boost::bind(&LLXUIParser::writeBoolValue, this, _1, _2));
+ registerParserFuncs<std::string>(boost::bind(&LLXUIParser::readStringValue, this, _1),
+ boost::bind(&LLXUIParser::writeStringValue, this, _1, _2));
+ registerParserFuncs<U8>(boost::bind(&LLXUIParser::readU8Value, this, _1),
+ boost::bind(&LLXUIParser::writeU8Value, this, _1, _2));
+ registerParserFuncs<S8>(boost::bind(&LLXUIParser::readS8Value, this, _1),
+ boost::bind(&LLXUIParser::writeS8Value, this, _1, _2));
+ registerParserFuncs<U16>(boost::bind(&LLXUIParser::readU16Value, this, _1),
+ boost::bind(&LLXUIParser::writeU16Value, this, _1, _2));
+ registerParserFuncs<S16>(boost::bind(&LLXUIParser::readS16Value, this, _1),
+ boost::bind(&LLXUIParser::writeS16Value, this, _1, _2));
+ registerParserFuncs<U32>(boost::bind(&LLXUIParser::readU32Value, this, _1),
+ boost::bind(&LLXUIParser::writeU32Value, this, _1, _2));
+ registerParserFuncs<S32>(boost::bind(&LLXUIParser::readS32Value, this, _1),
+ boost::bind(&LLXUIParser::writeS32Value, this, _1, _2));
+ registerParserFuncs<F32>(boost::bind(&LLXUIParser::readF32Value, this, _1),
+ boost::bind(&LLXUIParser::writeF32Value, this, _1, _2));
+ registerParserFuncs<F64>(boost::bind(&LLXUIParser::readF64Value, this, _1),
+ boost::bind(&LLXUIParser::writeF64Value, this, _1, _2));
+ registerParserFuncs<LLColor4>(boost::bind(&LLXUIParser::readColor4Value, this, _1),
+ boost::bind(&LLXUIParser::writeColor4Value, this, _1, _2));
+ registerParserFuncs<LLUIColor>(boost::bind(&LLXUIParser::readUIColorValue, this, _1),
+ boost::bind(&LLXUIParser::writeUIColorValue, this, _1, _2));
+ registerParserFuncs<LLUUID>(boost::bind(&LLXUIParser::readUUIDValue, this, _1),
+ boost::bind(&LLXUIParser::writeUUIDValue, this, _1, _2));
+ registerParserFuncs<LLSD>(boost::bind(&LLXUIParser::readSDValue, this, _1),
+ boost::bind(&LLXUIParser::writeSDValue, this, _1, _2));
+}
+
+static LLFastTimer::DeclareTimer FTM_PARSE_XUI("XUI Parsing");
+
+void LLXUIParser::readXUI(LLXMLNodePtr node, LLInitParam::BaseBlock& block, bool silent)
+{
+ LLFastTimer timer(FTM_PARSE_XUI);
+ mNameStack.clear();
+ mCurReadDepth = 0;
+ setParseSilently(silent);
+
+ if (node.isNull())
+ {
+ parserWarning("Invalid node");
+ }
+ else
+ {
+ readXUIImpl(node, std::string(node->getName()->mString), block);
+ }
+}
+
+bool LLXUIParser::readXUIImpl(LLXMLNodePtr nodep, const std::string& scope, LLInitParam::BaseBlock& block)
+{
+ typedef boost::tokenizer<boost::char_separator<char> > tokenizer;
+ boost::char_separator<char> sep(".");
+
+ bool values_parsed = false;
+
+ // submit attributes for current node
+ values_parsed |= readAttributes(nodep, block);
+
+ // treat text contents of xml node as "value" parameter
+ std::string text_contents = nodep->getSanitizedValue();
+ if (!text_contents.empty())
+ {
+ mCurReadNode = nodep;
+ mNameStack.push_back(std::make_pair(std::string("value"), newParseGeneration()));
+ // child nodes are not necessarily valid parameters (could be a child widget)
+ // so don't complain once we've recursed
+ bool silent = mCurReadDepth > 0;
+ if (!block.submitValue(mNameStack, *this, true))
+ {
+ mNameStack.pop_back();
+ block.submitValue(mNameStack, *this, silent);
+ }
+ else
+ {
+ mNameStack.pop_back();
+ }
+ }
+
+ // then traverse children
+ // child node must start with last name of parent node (our "scope")
+ // for example: "<button><button.param nested_param1="foo"><param.nested_param2 nested_param3="bar"/></button.param></button>"
+ // which equates to the following nesting:
+ // button
+ // param
+ // nested_param1
+ // nested_param2
+ // nested_param3
+ mCurReadDepth++;
+ for(LLXMLNodePtr childp = nodep->getFirstChild(); childp.notNull();)
+ {
+ std::string child_name(childp->getName()->mString);
+ S32 num_tokens_pushed = 0;
+
+ // for non "dotted" child nodes check to see if child node maps to another widget type
+ // and if not, treat as a child element of the current node
+ // e.g. <button><rect left="10"/></button> will interpret <rect> as "button.rect"
+ // since there is no widget named "rect"
+ if (child_name.find(".") == std::string::npos)
+ {
+ mNameStack.push_back(std::make_pair(child_name, newParseGeneration()));
+ num_tokens_pushed++;
+ }
+ else
+ {
+ // parse out "dotted" name into individual tokens
+ tokenizer name_tokens(child_name, sep);
+
+ tokenizer::iterator name_token_it = name_tokens.begin();
+ if(name_token_it == name_tokens.end())
+ {
+ childp = childp->getNextSibling();
+ continue;
+ }
+
+ // check for proper nesting
+ if(!scope.empty() && *name_token_it != scope)
+ {
+ childp = childp->getNextSibling();
+ continue;
+ }
+
+ // now ignore first token
+ ++name_token_it;
+
+ // copy remaining tokens on to our running token list
+ for(tokenizer::iterator token_to_push = name_token_it; token_to_push != name_tokens.end(); ++token_to_push)
+ {
+ mNameStack.push_back(std::make_pair(*token_to_push, newParseGeneration()));
+ num_tokens_pushed++;
+ }
+ }
+
+ // recurse and visit children XML nodes
+ if(readXUIImpl(childp, mNameStack.empty() ? scope : mNameStack.back().first, block))
+ {
+ // child node successfully parsed, remove from DOM
+
+ values_parsed = true;
+ LLXMLNodePtr node_to_remove = childp;
+ childp = childp->getNextSibling();
+
+ nodep->deleteChild(node_to_remove);
+ }
+ else
+ {
+ childp = childp->getNextSibling();
+ }
+
+ while(num_tokens_pushed-- > 0)
+ {
+ mNameStack.pop_back();
+ }
+ }
+ mCurReadDepth--;
+ return values_parsed;
+}
+
+bool LLXUIParser::readAttributes(LLXMLNodePtr nodep, LLInitParam::BaseBlock& block)
+{
+ typedef boost::tokenizer<boost::char_separator<char> > tokenizer;
+ boost::char_separator<char> sep(".");
+
+ bool any_parsed = false;
+
+ for(LLXMLAttribList::const_iterator attribute_it = nodep->mAttributes.begin();
+ attribute_it != nodep->mAttributes.end();
+ ++attribute_it)
+ {
+ S32 num_tokens_pushed = 0;
+ std::string attribute_name(attribute_it->first->mString);
+ mCurReadNode = attribute_it->second;
+
+ tokenizer name_tokens(attribute_name, sep);
+ // copy remaining tokens on to our running token list
+ for(tokenizer::iterator token_to_push = name_tokens.begin(); token_to_push != name_tokens.end(); ++token_to_push)
+ {
+ mNameStack.push_back(std::make_pair(*token_to_push, newParseGeneration()));
+ num_tokens_pushed++;
+ }
+
+ // child nodes are not necessarily valid attributes, so don't complain once we've recursed
+ bool silent = mCurReadDepth > 0;
+ any_parsed |= block.submitValue(mNameStack, *this, silent);
+
+ while(num_tokens_pushed-- > 0)
+ {
+ mNameStack.pop_back();
+ }
+ }
+
+ return any_parsed;
+}
+
+void LLXUIParser::writeXUI(LLXMLNodePtr node, const LLInitParam::BaseBlock &block, const LLInitParam::BaseBlock* diff_block)
+{
+ mWriteRootNode = node;
+ block.serializeBlock(*this, Parser::name_stack_t(), diff_block);
+ mOutNodes.clear();
+}
+
+// go from a stack of names to a specific XML node
+LLXMLNodePtr LLXUIParser::getNode(const name_stack_t& stack)
+{
+ name_stack_t name_stack;
+ for (name_stack_t::const_iterator it = stack.begin();
+ it != stack.end();
+ ++it)
+ {
+ if (!it->first.empty())
+ {
+ name_stack.push_back(*it);
+ }
+ }
+
+ LLXMLNodePtr out_node = mWriteRootNode;
+
+ name_stack_t::const_iterator next_it = name_stack.begin();
+ for (name_stack_t::const_iterator it = name_stack.begin();
+ it != name_stack.end();
+ it = next_it)
+ {
+ ++next_it;
+ if (it->first.empty())
+ {
+ continue;
+ }
+
+ out_nodes_t::iterator found_it = mOutNodes.lower_bound(it->second);
+
+ // node with this name not yet written
+ if (found_it == mOutNodes.end() || mOutNodes.key_comp()(found_it->first, it->second))
+ {
+ // make an attribute if we are the last element on the name stack
+ bool is_attribute = next_it == name_stack.end();
+ LLXMLNodePtr new_node = new LLXMLNode(it->first.c_str(), is_attribute);
+ out_node->addChild(new_node);
+ mOutNodes.insert(found_it, std::make_pair(it->second, new_node));
+ out_node = new_node;
+ }
+ else
+ {
+ out_node = found_it->second;
+ }
+ }
+
+ return (out_node == mWriteRootNode ? LLXMLNodePtr(NULL) : out_node);
+}
+
+
+bool LLXUIParser::readBoolValue(void* val_ptr)
+{
+ S32 value;
+ bool success = mCurReadNode->getBoolValue(1, &value);
+ *((bool*)val_ptr) = (value != FALSE);
+ return success;
+}
+
+bool LLXUIParser::writeBoolValue(const void* val_ptr, const name_stack_t& stack)
+{
+ LLXMLNodePtr node = getNode(stack);
+ if (node.notNull())
+ {
+ node->setBoolValue(*((bool*)val_ptr));
+ return true;
+ }
+ return false;
+}
+
+bool LLXUIParser::readStringValue(void* val_ptr)
+{
+ *((std::string*)val_ptr) = mCurReadNode->getSanitizedValue();
+ return true;
+}
+
+bool LLXUIParser::writeStringValue(const void* val_ptr, const name_stack_t& stack)
+{
+ LLXMLNodePtr node = getNode(stack);
+ if (node.notNull())
+ {
+ const std::string* string_val = reinterpret_cast<const std::string*>(val_ptr);
+ if (string_val->find('\n') != std::string::npos
+ || string_val->size() > MAX_STRING_ATTRIBUTE_SIZE)
+ {
+ // don't write strings with newlines into attributes
+ std::string attribute_name = node->getName()->mString;
+ LLXMLNodePtr parent_node = node->mParent;
+ parent_node->deleteChild(node);
+ // write results in text contents of node
+ if (attribute_name == "value")
+ {
+ // "value" is implicit, just write to parent
+ node = parent_node;
+ }
+ else
+ {
+ // create a child that is not an attribute, but with same name
+ node = parent_node->createChild(attribute_name.c_str(), false);
+ }
+ }
+ node->setStringValue(*string_val);
+ return true;
+ }
+ return false;
+}
+
+bool LLXUIParser::readU8Value(void* val_ptr)
+{
+ return mCurReadNode->getByteValue(1, (U8*)val_ptr);
+}
+
+bool LLXUIParser::writeU8Value(const void* val_ptr, const name_stack_t& stack)
+{
+ LLXMLNodePtr node = getNode(stack);
+ if (node.notNull())
+ {
+ node->setUnsignedValue(*((U8*)val_ptr));
+ return true;
+ }
+ return false;
+}
+
+bool LLXUIParser::readS8Value(void* val_ptr)
+{
+ S32 value;
+ if(mCurReadNode->getIntValue(1, &value))
+ {
+ *((S8*)val_ptr) = value;
+ return true;
+ }
+ return false;
+}
+
+bool LLXUIParser::writeS8Value(const void* val_ptr, const name_stack_t& stack)
+{
+ LLXMLNodePtr node = getNode(stack);
+ if (node.notNull())
+ {
+ node->setIntValue(*((S8*)val_ptr));
+ return true;
+ }
+ return false;
+}
+
+bool LLXUIParser::readU16Value(void* val_ptr)
+{
+ U32 value;
+ if(mCurReadNode->getUnsignedValue(1, &value))
+ {
+ *((U16*)val_ptr) = value;
+ return true;
+ }
+ return false;
+}
+
+bool LLXUIParser::writeU16Value(const void* val_ptr, const name_stack_t& stack)
+{
+ LLXMLNodePtr node = getNode(stack);
+ if (node.notNull())
+ {
+ node->setUnsignedValue(*((U16*)val_ptr));
+ return true;
+ }
+ return false;
+}
+
+bool LLXUIParser::readS16Value(void* val_ptr)
+{
+ S32 value;
+ if(mCurReadNode->getIntValue(1, &value))
+ {
+ *((S16*)val_ptr) = value;
+ return true;
+ }
+ return false;
+}
+
+bool LLXUIParser::writeS16Value(const void* val_ptr, const name_stack_t& stack)
+{
+ LLXMLNodePtr node = getNode(stack);
+ if (node.notNull())
+ {
+ node->setIntValue(*((S16*)val_ptr));
+ return true;
+ }
+ return false;
+}
+
+bool LLXUIParser::readU32Value(void* val_ptr)
+{
+ return mCurReadNode->getUnsignedValue(1, (U32*)val_ptr);
+}
+
+bool LLXUIParser::writeU32Value(const void* val_ptr, const name_stack_t& stack)
+{
+ LLXMLNodePtr node = getNode(stack);
+ if (node.notNull())
+ {
+ node->setUnsignedValue(*((U32*)val_ptr));
+ return true;
+ }
+ return false;
+}
+
+bool LLXUIParser::readS32Value(void* val_ptr)
+{
+ return mCurReadNode->getIntValue(1, (S32*)val_ptr);
+}
+
+bool LLXUIParser::writeS32Value(const void* val_ptr, const name_stack_t& stack)
+{
+ LLXMLNodePtr node = getNode(stack);
+ if (node.notNull())
+ {
+ node->setIntValue(*((S32*)val_ptr));
+ return true;
+ }
+ return false;
+}
+
+bool LLXUIParser::readF32Value(void* val_ptr)
+{
+ return mCurReadNode->getFloatValue(1, (F32*)val_ptr);
+}
+
+bool LLXUIParser::writeF32Value(const void* val_ptr, const name_stack_t& stack)
+{
+ LLXMLNodePtr node = getNode(stack);
+ if (node.notNull())
+ {
+ node->setFloatValue(*((F32*)val_ptr));
+ return true;
+ }
+ return false;
+}
+
+bool LLXUIParser::readF64Value(void* val_ptr)
+{
+ return mCurReadNode->getDoubleValue(1, (F64*)val_ptr);
+}
+
+bool LLXUIParser::writeF64Value(const void* val_ptr, const name_stack_t& stack)
+{
+ LLXMLNodePtr node = getNode(stack);
+ if (node.notNull())
+ {
+ node->setDoubleValue(*((F64*)val_ptr));
+ return true;
+ }
+ return false;
+}
+
+bool LLXUIParser::readColor4Value(void* val_ptr)
+{
+ LLColor4* colorp = (LLColor4*)val_ptr;
+ if(mCurReadNode->getFloatValue(4, colorp->mV) >= 3)
+ {
+ return true;
+ }
+
+ return false;
+}
+
+bool LLXUIParser::writeColor4Value(const void* val_ptr, const name_stack_t& stack)
+{
+ LLXMLNodePtr node = getNode(stack);
+ if (node.notNull())
+ {
+ LLColor4 color = *((LLColor4*)val_ptr);
+ node->setFloatValue(4, color.mV);
+ return true;
+ }
+ return false;
+}
+
+bool LLXUIParser::readUIColorValue(void* val_ptr)
+{
+ LLUIColor* param = (LLUIColor*)val_ptr;
+ LLColor4 color;
+ bool success = mCurReadNode->getFloatValue(4, color.mV) >= 3;
+ if (success)
+ {
+ param->set(color);
+ return true;
+ }
+ return false;
+}
+
+bool LLXUIParser::writeUIColorValue(const void* val_ptr, const name_stack_t& stack)
+{
+ LLXMLNodePtr node = getNode(stack);
+ if (node.notNull())
+ {
+ LLUIColor color = *((LLUIColor*)val_ptr);
+ //RN: don't write out the color that is represented by a function
+ // rely on param block exporting to get the reference to the color settings
+ if (color.isReference()) return false;
+ node->setFloatValue(4, color.get().mV);
+ return true;
+ }
+ return false;
+}
+
+bool LLXUIParser::readUUIDValue(void* val_ptr)
+{
+ LLUUID temp_id;
+ // LLUUID::set is destructive, so use temporary value
+ if (temp_id.set(mCurReadNode->getSanitizedValue()))
+ {
+ *(LLUUID*)(val_ptr) = temp_id;
+ return true;
+ }
+ return false;
+}
+
+bool LLXUIParser::writeUUIDValue(const void* val_ptr, const name_stack_t& stack)
+{
+ LLXMLNodePtr node = getNode(stack);
+ if (node.notNull())
+ {
+ node->setStringValue(((LLUUID*)val_ptr)->asString());
+ return true;
+ }
+ return false;
+}
+
+bool LLXUIParser::readSDValue(void* val_ptr)
+{
+ *((LLSD*)val_ptr) = LLSD(mCurReadNode->getSanitizedValue());
+ return true;
+}
+
+bool LLXUIParser::writeSDValue(const void* val_ptr, const name_stack_t& stack)
+{
+ LLXMLNodePtr node = getNode(stack);
+ if (node.notNull())
+ {
+ std::string string_val = ((LLSD*)val_ptr)->asString();
+ if (string_val.find('\n') != std::string::npos || string_val.size() > MAX_STRING_ATTRIBUTE_SIZE)
+ {
+ // don't write strings with newlines into attributes
+ std::string attribute_name = node->getName()->mString;
+ LLXMLNodePtr parent_node = node->mParent;
+ parent_node->deleteChild(node);
+ // write results in text contents of node
+ if (attribute_name == "value")
+ {
+ // "value" is implicit, just write to parent
+ node = parent_node;
+ }
+ else
+ {
+ node = parent_node->createChild(attribute_name.c_str(), false);
+ }
+ }
+
+ node->setStringValue(string_val);
+ return true;
+ }
+ return false;
+}
+
+/*virtual*/ std::string LLXUIParser::getCurrentElementName()
+{
+ std::string full_name;
+ for (name_stack_t::iterator it = mNameStack.begin();
+ it != mNameStack.end();
+ ++it)
+ {
+ full_name += it->first + "."; // build up dotted names: "button.param.nestedparam."
+ }
+
+ return full_name;
+}
+
+void LLXUIParser::parserWarning(const std::string& message)
+{
+#if 0 //#ifdef LL_WINDOWS
+ // use Visual Studo friendly formatting of output message for easy access to originating xml
+ llutf16string utf16str = utf8str_to_utf16str(llformat("%s(%d):\t%s", LLUICtrlFactory::getInstance()->getCurFileName().c_str(), mCurReadNode->getLineNumber(), message.c_str()).c_str());
+ utf16str += '\n';
+ OutputDebugString(utf16str.c_str());
+#else
+ Parser::parserWarning(message);
+#endif
+}
+
+void LLXUIParser::parserError(const std::string& message)
+{
+#if 0 //#ifdef LL_WINDOWS
+ llutf16string utf16str = utf8str_to_utf16str(llformat("%s(%d):\t%s", LLUICtrlFactory::getInstance()->getCurFileName().c_str(), mCurReadNode->getLineNumber(), message.c_str()).c_str());
+ utf16str += '\n';
+ OutputDebugString(utf16str.c_str());
+#else
+ Parser::parserError(message);
+#endif
+}
diff --git a/indra/llxuixml/llxuiparser.h b/indra/llxuixml/llxuiparser.h
new file mode 100644
index 0000000000..6f000f2422
--- /dev/null
+++ b/indra/llxuixml/llxuiparser.h
@@ -0,0 +1,174 @@
+/**
+ * @file llxuiparser.h
+ * @brief Utility functions for handling XUI structures in XML
+ *
+ * $LicenseInfo:firstyear=2003&license=viewergpl$
+ *
+ * Copyright (c) 2003-2009, Linden Research, Inc.
+ *
+ * Second Life Viewer Source Code
+ * The source code in this file ("Source Code") is provided by Linden Lab
+ * to you under the terms of the GNU General Public License, version 2.0
+ * ("GPL"), unless you have obtained a separate licensing agreement
+ * ("Other License"), formally executed by you and Linden Lab. Terms of
+ * the GPL can be found in doc/GPL-license.txt in this distribution, or
+ * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
+ *
+ * There are special exceptions to the terms and conditions of the GPL as
+ * it is applied to this Source Code. View the full text of the exception
+ * in the file doc/FLOSS-exception.txt in this software distribution, or
+ * online at
+ * http://secondlifegrid.net/programs/open_source/licensing/flossexception
+ *
+ * By copying, modifying or distributing this software, you acknowledge
+ * that you have read and understood your obligations described above,
+ * and agree to abide by those obligations.
+ *
+ * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+ * COMPLETENESS OR PERFORMANCE.
+ * $/LicenseInfo$
+ */
+
+#ifndef LLXUIPARSER_H
+#define LLXUIPARSER_H
+
+#include "llinitparam.h"
+#include "llxmlnode.h"
+#include "llfasttimer.h"
+#include "llregistry.h"
+
+#include <boost/function.hpp>
+#include <iosfwd>
+#include <stack>
+#include <set>
+
+
+
+class LLView;
+
+
+
+// lookup widget type by name
+class LLWidgetTypeRegistry
+: public LLRegistrySingleton<std::string, const std::type_info*, LLWidgetTypeRegistry>
+{};
+
+
+// global static instance for registering all widget types
+typedef boost::function<LLView* (LLXMLNodePtr node, LLView *parent, LLXMLNodePtr output_node)> LLWidgetCreatorFunc;
+
+typedef LLRegistry<std::string, LLWidgetCreatorFunc> widget_registry_t;
+
+class LLChildRegistryRegistry
+: public LLRegistrySingleton<const std::type_info*, widget_registry_t, LLChildRegistryRegistry>
+{};
+
+
+
+class LLXSDWriter : public LLInitParam::Parser
+{
+ LOG_CLASS(LLXSDWriter);
+public:
+ void writeXSD(const std::string& name, LLXMLNodePtr node, const LLInitParam::BaseBlock& block, const std::string& xml_namespace);
+
+ /*virtual*/ std::string getCurrentElementName() { return LLStringUtil::null; }
+
+ LLXSDWriter();
+
+protected:
+ void writeAttribute(const std::string& type, const Parser::name_stack_t&, S32 min_count, S32 max_count, const std::vector<std::string>* possible_values);
+ void addAttributeToSchema(LLXMLNodePtr nodep, const std::string& attribute_name, const std::string& type, bool mandatory, const std::vector<std::string>* possible_values);
+ LLXMLNodePtr mAttributeNode;
+ LLXMLNodePtr mElementNode;
+ LLXMLNodePtr mSchemaNode;
+
+ typedef std::set<std::string> string_set_t;
+ typedef std::map<LLXMLNodePtr, string_set_t> attributes_map_t;
+ attributes_map_t mAttributesWritten;
+};
+
+
+
+// NOTE: DOES NOT WORK YET
+// should support child widgets for XUI
+class LLXUIXSDWriter : public LLXSDWriter
+{
+public:
+ void writeXSD(const std::string& name, const std::string& path, const LLInitParam::BaseBlock& block);
+};
+
+
+
+class LLXUIParser : public LLInitParam::Parser, public LLSingleton<LLXUIParser>
+{
+LOG_CLASS(LLXUIParser);
+
+protected:
+ LLXUIParser();
+ friend class LLSingleton<LLXUIParser>;
+public:
+ typedef LLInitParam::Parser::name_stack_t name_stack_t;
+
+ /*virtual*/ std::string getCurrentElementName();
+ /*virtual*/ void parserWarning(const std::string& message);
+ /*virtual*/ void parserError(const std::string& message);
+
+ void readXUI(LLXMLNodePtr node, LLInitParam::BaseBlock& block, bool silent=false);
+ void writeXUI(LLXMLNodePtr node, const LLInitParam::BaseBlock& block, const LLInitParam::BaseBlock* diff_block = NULL);
+
+private:
+ typedef std::list<std::pair<std::string, bool> > token_list_t;
+
+ bool readXUIImpl(LLXMLNodePtr node, const std::string& scope, LLInitParam::BaseBlock& block);
+ bool readAttributes(LLXMLNodePtr nodep, LLInitParam::BaseBlock& block);
+
+ //reader helper functions
+ bool readBoolValue(void* val_ptr);
+ bool readStringValue(void* val_ptr);
+ bool readU8Value(void* val_ptr);
+ bool readS8Value(void* val_ptr);
+ bool readU16Value(void* val_ptr);
+ bool readS16Value(void* val_ptr);
+ bool readU32Value(void* val_ptr);
+ bool readS32Value(void* val_ptr);
+ bool readF32Value(void* val_ptr);
+ bool readF64Value(void* val_ptr);
+ bool readColor4Value(void* val_ptr);
+ bool readUIColorValue(void* val_ptr);
+ bool readUUIDValue(void* val_ptr);
+ bool readSDValue(void* val_ptr);
+
+ //writer helper functions
+ bool writeBoolValue(const void* val_ptr, const name_stack_t&);
+ bool writeStringValue(const void* val_ptr, const name_stack_t&);
+ bool writeU8Value(const void* val_ptr, const name_stack_t&);
+ bool writeS8Value(const void* val_ptr, const name_stack_t&);
+ bool writeU16Value(const void* val_ptr, const name_stack_t&);
+ bool writeS16Value(const void* val_ptr, const name_stack_t&);
+ bool writeU32Value(const void* val_ptr, const name_stack_t&);
+ bool writeS32Value(const void* val_ptr, const name_stack_t&);
+ bool writeF32Value(const void* val_ptr, const name_stack_t&);
+ bool writeF64Value(const void* val_ptr, const name_stack_t&);
+ bool writeColor4Value(const void* val_ptr, const name_stack_t&);
+ bool writeUIColorValue(const void* val_ptr, const name_stack_t&);
+ bool writeUUIDValue(const void* val_ptr, const name_stack_t&);
+ bool writeSDValue(const void* val_ptr, const name_stack_t&);
+
+ LLXMLNodePtr getNode(const name_stack_t& stack);
+
+private:
+ Parser::name_stack_t mNameStack;
+ LLXMLNodePtr mCurReadNode;
+ // Root of the widget XML sub-tree, for example, "line_editor"
+ LLXMLNodePtr mWriteRootNode;
+
+ typedef std::map<S32, LLXMLNodePtr> out_nodes_t;
+ out_nodes_t mOutNodes;
+ S32 mLastWriteGeneration;
+ LLXMLNodePtr mLastWrittenChild;
+ S32 mCurReadDepth;
+};
+
+
+#endif //LLXUIPARSER_H
diff --git a/indra/lscript/lscript_compile/lscript_tree.cpp b/indra/lscript/lscript_compile/lscript_tree.cpp
index 7fa115bb20..3b8bbbe805 100644
--- a/indra/lscript/lscript_compile/lscript_tree.cpp
+++ b/indra/lscript/lscript_compile/lscript_tree.cpp
@@ -10679,20 +10679,21 @@ void LLScriptScript::recurse(LLFILE *fp, S32 tabs, S32 tabsize, LSCRIPTCompilePa
{
mGlobalScope = new LLScriptScope(gScopeStringTable);
// zeroth, add library functions to global scope
- S32 i;
+ U16 function_index = 0;
const char *arg;
LLScriptScopeEntry *sentry;
- for (i = 0; i < gScriptLibrary.mNextNumber; i++)
+ for (std::vector<LLScriptLibraryFunction>::const_iterator i = gScriptLibrary.mFunctions.begin();
+ i != gScriptLibrary.mFunctions.end(); ++i)
{
// First, check to make sure this isn't a god only function, or that the viewer's agent is a god.
- if (!gScriptLibrary.mFunctions[i]->mGodOnly || mGodLike)
+ if (!i->mGodOnly || mGodLike)
{
- if (gScriptLibrary.mFunctions[i]->mReturnType)
- sentry = mGlobalScope->addEntry(gScriptLibrary.mFunctions[i]->mName, LIT_LIBRARY_FUNCTION, char2type(*gScriptLibrary.mFunctions[i]->mReturnType));
+ if (i->mReturnType)
+ sentry = mGlobalScope->addEntry(i->mName, LIT_LIBRARY_FUNCTION, char2type(*i->mReturnType));
else
- sentry = mGlobalScope->addEntry(gScriptLibrary.mFunctions[i]->mName, LIT_LIBRARY_FUNCTION, LST_NULL);
- sentry->mLibraryNumber = i;
- arg = gScriptLibrary.mFunctions[i]->mArgs;
+ sentry = mGlobalScope->addEntry(i->mName, LIT_LIBRARY_FUNCTION, LST_NULL);
+ sentry->mLibraryNumber = function_index;
+ arg = i->mArgs;
if (arg)
{
while (*arg)
@@ -10704,6 +10705,7 @@ void LLScriptScript::recurse(LLFILE *fp, S32 tabs, S32 tabsize, LSCRIPTCompilePa
}
}
}
+ function_index++;
}
// first go and collect all the global variables
if (mGlobals)
diff --git a/indra/lscript/lscript_execute.h b/indra/lscript/lscript_execute.h
index 8549482299..96855abea0 100644
--- a/indra/lscript/lscript_execute.h
+++ b/indra/lscript/lscript_execute.h
@@ -37,6 +37,8 @@
#include "linked_lists.h"
#include "lscript_library.h"
+class LLTimer;
+
// Return values for run() methods
const U32 NO_DELETE_FLAG = 0x0000;
const U32 DELETE_FLAG = 0x0001;
diff --git a/indra/lscript/lscript_execute/lscript_readlso.cpp b/indra/lscript/lscript_execute/lscript_readlso.cpp
index faf4fba0e0..2948ebca63 100644
--- a/indra/lscript/lscript_execute/lscript_readlso.cpp
+++ b/indra/lscript/lscript_execute/lscript_readlso.cpp
@@ -1579,7 +1579,7 @@ void print_calllib(LLFILE *fp, U8 *buffer, S32 &offset, S32 tabs)
lso_print_tabs(fp, tabs);
fprintf(fp, "[0x%X]\tCALLLIB ", offset++);
arg = *(buffer + offset++);
- fprintf(fp, "%d (%s)\n", (U32)arg, gScriptLibrary.mFunctions[arg]->mName);
+ fprintf(fp, "%d (%s)\n", (U32)arg, gScriptLibrary.mFunctions[arg].mName);
}
@@ -1589,6 +1589,6 @@ void print_calllib_two_byte(LLFILE *fp, U8 *buffer, S32 &offset, S32 tabs)
lso_print_tabs(fp, tabs);
fprintf(fp, "[0x%X]\tCALLLIB_TWO_BYTE ", offset++);
arg = bytestream2u16(buffer, offset);
- fprintf(fp, "%d (%s)\n", (U32)arg, gScriptLibrary.mFunctions[arg]->mName);
+ fprintf(fp, "%d (%s)\n", (U32)arg, gScriptLibrary.mFunctions[arg].mName);
}
diff --git a/indra/lscript/lscript_library.h b/indra/lscript/lscript_library.h
index fa3b06b7d9..6728d70d0a 100644
--- a/indra/lscript/lscript_library.h
+++ b/indra/lscript/lscript_library.h
@@ -44,7 +44,7 @@ class LLScriptLibData;
class LLScriptLibraryFunction
{
public:
- LLScriptLibraryFunction(F32 eu, F32 st, void (*exec_func)(LLScriptLibData *, LLScriptLibData *, const LLUUID &), const char *name, const char *ret_type, const char *args, const char *desc, BOOL god_only = FALSE);
+ LLScriptLibraryFunction(F32 eu, F32 st, void (*exec_func)(LLScriptLibData *, LLScriptLibData *, const LLUUID &), const char *name, const char *ret_type, const char *args, BOOL god_only = FALSE);
~LLScriptLibraryFunction();
F32 mEnergyUse;
@@ -53,7 +53,6 @@ public:
const char *mName;
const char *mReturnType;
const char *mArgs;
- const char *mDesc;
BOOL mGodOnly;
};
@@ -65,11 +64,10 @@ public:
void init();
- void addFunction(LLScriptLibraryFunction *func);
+ void addFunction(F32 eu, F32 st, void (*exec_func)(LLScriptLibData *, LLScriptLibData *, const LLUUID &), const char *name, const char *ret_type, const char *args, BOOL god_only = FALSE);
void assignExec(const char *name, void (*exec_func)(LLScriptLibData *, LLScriptLibData *, const LLUUID &));
- S32 mNextNumber;
- LLScriptLibraryFunction **mFunctions;
+ std::vector<LLScriptLibraryFunction> mFunctions;
};
extern LLScriptLibrary gScriptLibrary;
diff --git a/indra/lscript/lscript_library/lscript_library.cpp b/indra/lscript/lscript_library/lscript_library.cpp
index 0342c97429..0d51c27c92 100644
--- a/indra/lscript/lscript_library/lscript_library.cpp
+++ b/indra/lscript/lscript_library/lscript_library.cpp
@@ -49,20 +49,12 @@
#include "lscript_library.h"
LLScriptLibrary::LLScriptLibrary()
-: mNextNumber(0), mFunctions(NULL)
{
init();
}
LLScriptLibrary::~LLScriptLibrary()
{
- S32 i;
- for (i = 0; i < mNextNumber; i++)
- {
- delete mFunctions[i];
- mFunctions[i] = NULL;
- }
- delete [] mFunctions;
}
void dummy_func(LLScriptLibData *retval, LLScriptLibData *args, const LLUUID &id)
@@ -75,448 +67,424 @@ void LLScriptLibrary::init()
// Otherwise the bytecode numbers for each call will be wrong, and all
// existing scripts will crash.
- // energy, sleep, dummy_func, name, return type, parameters, help text, gods-only
- addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llSin", "f", "f", "float llSin(float theta)\ntheta in radians"));
- addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llCos", "f", "f", "float llCos(float theta)\ntheta in radians"));
- addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llTan", "f", "f", "float llTan(float theta)\ntheta radians"));
- addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llAtan2", "f", "ff", "float llAtan2(float y, float x)"));
- addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llSqrt", "f", "f", "float llSqrt(float val)\nreturns 0 and triggers a Math Error for imaginary results"));
- addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llPow", "f", "ff", "float llPow(float base, float exponent)\nreturns 0 and triggers Math Error for imaginary results"));
- addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llAbs", "i", "i", "integer llAbs(integer val)"));
- addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llFabs", "f", "f", "float llFabs(float val)"));
- addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llFrand", "f", "f", "float llFrand(float mag)\nreturns random number in range [0,mag)"));
- addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llFloor", "i", "f", "integer llFloor(float val)\nreturns largest integer value <= val"));
- addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llCeil", "i", "f", "integer llCeil(float val)\nreturns smallest integer value >= val"));
- addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llRound", "i", "f", "integer llRound(float val)\nreturns val rounded to the nearest integer"));
- addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llVecMag", "f", "v", "float llVecMag(vector v)\nreturns the magnitude of v"));
- addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llVecNorm", "v", "v", "vector llVecNorm(vector v)\nreturns the v normalized"));
- addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llVecDist", "f", "vv", "float llVecDist(vector v1, vector v2)\nreturns the 3D distance between v1 and v2"));
- addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llRot2Euler", "v", "q", "vector llRot2Euler(rotation q)\nreturns the Euler representation (roll, pitch, yaw) of q"));
- addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llEuler2Rot", "q", "v", "rotation llEuler2Rot(vector v)\nreturns the rotation representation of Euler Angles v"));
- addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llAxes2Rot", "q", "vvv", "rotation llAxes2Rot(vector fwd, vector left, vector up)\nreturns the rotation defined by the coordinate axes"));
- addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llRot2Fwd", "v", "q", "vector llRot2Fwd(rotation q)\nreturns the forward vector defined by q"));
- addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llRot2Left", "v", "q", "vector llRot2Left(rotation q)\nreturns the left vector defined by q"));
- addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llRot2Up", "v", "q", "vector llRot2Up(rotation q)\nreturns the up vector defined by q"));
- addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llRotBetween", "q", "vv", "rotation llRotBetween(vector v1, vector v2)\nreturns the rotation to rotate v1 to v2"));
- addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llWhisper", NULL, "is", "llWhisper(integer channel, string msg)\nwhispers msg on channel"));
- addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llSay", NULL, "is", "llSay(integer channel, string msg)\nsays msg on channel"));
- addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llShout", NULL, "is", "llShout(integer channel, string msg)\nshouts msg on channel"));
- addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llListen", "i", "isks", "integer llListen(integer channel, string name, key id, string msg)\nsets a callback for msg on channel from name and id (name, id, and/or msg can be empty) and returns an identifier that can be used to deactivate or remove the listen"));
- addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llListenControl", NULL, "ii", "llListenControl(integer number, integer active)\nmakes a listen event callback active or inactive"));
- addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llListenRemove", NULL, "i", "llListenRemove(integer number)\nremoves listen event callback number"));
- addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llSensor", NULL, "skiff", "llSensor(string name, key id, integer type, float range, float arc)\nPerforms a single scan for name and id with type (AGENT, ACTIVE, PASSIVE, and/or SCRIPTED) within range meters and arc radians of forward vector (name, id, and/or keytype can be empty or 0)"));
- addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llSensorRepeat", NULL, "skifff", "llSensorRepeat(string name, key id, integer type, float range, float arc, float rate)\nsets a callback for name and id with type (AGENT, ACTIVE, PASSIVE, and/or SCRIPTED) within range meters and arc radians of forward vector (name, id, and/or keytype can be empty or 0) and repeats every rate seconds"));
- addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llSensorRemove", NULL, NULL, "llSensorRemove()\nremoves sensor"));
- addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llDetectedName", "s", "i", "string llDetectedName(integer number)\nreturns the name of detected object number (returns empty string if number is not valid sensed object)"));
- addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llDetectedKey", "k", "i", "key llDetectedKey(integer number)\nreturns the key of detected object number (returns empty key if number is not valid sensed object)"));
- addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llDetectedOwner", "k", "i", "key llDetectedOwner(integer number)\nreturns the key of detected object's owner (returns empty key if number is not valid sensed object)"));
- addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llDetectedType", "i", "i", "integer llDetectedType(integer number)\nreturns the type (AGENT, ACTIVE, PASSIVE, SCRIPTED) of detected object (returns 0 if number is not valid sensed object)"));
- addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llDetectedPos", "v", "i", "vector llDetectedPos(integer number)\nreturns the position of detected object number (returns <0,0,0> if number is not valid sensed object)"));
- addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llDetectedVel", "v", "i", "vector llDetectedVel(integer number)\nreturns the velocity of detected object number (returns <0,0,0> if number is not valid sensed object)"));
- addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llDetectedGrab", "v", "i", "vector llDetectedGrab(integer number)\nreturns the grab offset of the user touching object (returns <0,0,0> if number is not valid sensed object)"));
- addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llDetectedRot", "q", "i", "rotation llDetectedRot(integer number)\nreturns the rotation of detected object number (returns <0,0,0,1> if number is not valid sensed object)"));
- addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llDetectedGroup", "i", "i", "integer llDetectedGroup(integer number)\nReturns TRUE if detected object is part of same group as owner"));
- addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llDetectedLinkNumber", "i", "i", "integer llDetectedLinkNumber(integer number)\nreturns the link position of the triggered event for touches and collisions only"));
- addFunction(new LLScriptLibraryFunction(0.f, 0.f, dummy_func, "llDie", NULL, NULL, "llDie()\ndeletes the object"));
- addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llGround", "f", "v", "float llGround(vector v)\nreturns the ground height below the object position + v"));
- addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llCloud", "f", "v", "float llCloud(vector v)\nreturns the cloud density at the object position + v"));
- addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llWind", "v", "v", "vector llWind(vector v)\nreturns the wind velocity at the object position + v"));
- addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llSetStatus", NULL, "ii", "llSetStatus(integer status, integer value)\nsets status (STATUS_PHYSICS, STATUS_PHANTOM, STATUS_BLOCK_GRAB,\nSTATUS_ROTATE_X, STATUS_ROTATE_Y, and/or STATUS_ROTATE_Z) to value"));
- addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llGetStatus", "i", "i", "integer llGetStatus(integer status)\ngets value of status (STATUS_PHYSICS, STATUS_PHANTOM, STATUS_BLOCK_GRAB,\nSTATUS_ROTATE_X, STATUS_ROTATE_Y, and/or STATUS_ROTATE_Z)"));
- addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llSetScale", NULL, "v", "llSetScale(vector scale)\nsets the scale"));
- addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llGetScale", "v", NULL, "vector llGetScale()\ngets the scale"));
- addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llSetColor", NULL, "vi", "llSetColor(vector color, integer face)\nsets the color"));
- addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llGetAlpha", "f", "i", "float llGetAlpha(integer face)\ngets the alpha"));
- addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llSetAlpha", NULL, "fi", "llSetAlpha(float alpha, integer face)\nsets the alpha"));
- addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llGetColor", "v", "i", "vector llGetColor(integer face)\ngets the color"));
- addFunction(new LLScriptLibraryFunction(10.f, 0.2f, dummy_func, "llSetTexture", NULL, "si", "llSetTexture(string texture, integer face)\nsets the texture of face"));
- addFunction(new LLScriptLibraryFunction(10.f, 0.2f, dummy_func, "llScaleTexture", NULL, "ffi", "llScaleTexture(float scales, float scalet, integer face)\nsets the texture s, t scales for the chosen face"));
- addFunction(new LLScriptLibraryFunction(10.f, 0.2f, dummy_func, "llOffsetTexture", NULL, "ffi", "llOffsetTexture(float offsets, float offsett, integer face)\nsets the texture s, t offsets for the chosen face"));
- addFunction(new LLScriptLibraryFunction(10.f, 0.2f, dummy_func, "llRotateTexture", NULL, "fi", "llRotateTexture(float rotation, integer face)\nsets the texture rotation for the chosen face"));
- addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llGetTexture", "s", "i", "string llGetTexture(integer face)\ngets the texture of face (if it's a texture in the object inventory, otherwise the key in a string)"));
- addFunction(new LLScriptLibraryFunction(10.f, 0.2f, dummy_func, "llSetPos", NULL, "v", "llSetPos(vector pos)\nsets the position (if the script isn't physical)"));
- addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llGetPos", "v", NULL, "vector llGetPos()\ngets the position (if the script isn't physical)"));
- addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llGetLocalPos", "v", NULL, "vector llGetLocalPos()\ngets the position relative to the root (if the script isn't physical)"));
- addFunction(new LLScriptLibraryFunction(10.f, 0.2f, dummy_func, "llSetRot", NULL, "q", "llSetRot(rotation rot)\nsets the rotation (if the script isn't physical)"));
- addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llGetRot", "q", NULL, "rotation llGetRot()\ngets the rotation (if the script isn't physical)"));
- addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llGetLocalRot", "q", NULL, "rotation llGetLocalRot()\ngets the rotation local to the root (if the script isn't physical)"));
- addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llSetForce", NULL, "vi", "llSetForce(vector force, integer local)\nsets force on object, in local coords if local == TRUE (if the script is physical)"));
- addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llGetForce", "v", NULL, "vector llGetForce()\ngets the force (if the script is physical)"));
- addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llTarget", "i", "vf", "integer llTarget(vector position, float range)\nset positions within range of position as a target and return an ID for the target"));
- addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llTargetRemove", NULL, "i", "llTargetRemove(integer number)\nremoves target number"));
- addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llRotTarget", "i", "qf", "integer llRotTarget(rotation rot, float error)\nset rotations with error of rot as a rotational target and return an ID for the rotational target"));
- addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llRotTargetRemove", NULL, "i", "llRotTargetRemove(integer number)\nremoves rotational target number"));
- addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llMoveToTarget", NULL, "vf", "llMoveToTarget(vector target, float tau)\ncritically damp to target in tau seconds (if the script is physical)"));
- addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llStopMoveToTarget", NULL, NULL, "llStopMoveToTarget()\nStops critically damped motion"));
- addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llApplyImpulse", NULL, "vi", "llApplyImpulse(vector force, integer local)\napplies impulse to object, in local coords if local == TRUE (if the script is physical)"));
- addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llApplyRotationalImpulse", NULL, "vi", "llApplyRotationalImpulse(vector force, integer local)\napplies rotational impulse to object, in local coords if local == TRUE (if the script is physical)"));
- addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llSetTorque", NULL, "vi", "llSetTorque(vector torque, integer local)\nsets the torque of object, in local coords if local == TRUE (if the script is physical)"));
- addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llGetTorque", "v", NULL, "vector llGetTorque()\ngets the torque (if the script is physical)"));
- addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llSetForceAndTorque", NULL, "vvi", "llSetForceAndTorque(vector force, vector torque, integer local)\nsets the force and torque of object, in local coords if local == TRUE (if the script is physical)"));
- addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llGetVel", "v", NULL, "vector llGetVel()\ngets the velocity"));
- addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llGetAccel", "v", NULL, "vector llGetAccel()\ngets the acceleration"));
- addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llGetOmega", "v", NULL, "vector llGetOmega()\ngets the omega"));
- addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llGetTimeOfDay", "f", "", "float llGetTimeOfDay()\ngets the time in seconds since Second Life server midnight (or since server up-time; whichever is smaller)"));
- addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llGetWallclock", "f", "", "float llGetWallclock()\ngets the time in seconds since midnight"));
- addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llGetTime", "f", NULL, "float llGetTime()\ngets the time in seconds since creation"));
- addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llResetTime", NULL, NULL, "llResetTime()\nsets the time to zero"));
- addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llGetAndResetTime", "f", NULL, "float llGetAndResetTime()\ngets the time in seconds since creation and sets the time to zero"));
- addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llSound", NULL, "sfii", "llSound(string sound, float volume, integer queue, integer loop)\nplays sound at volume and whether it should loop or not"));
- addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llPlaySound", NULL, "sf", "llPlaySound(string sound, float volume)\nplays attached sound once at volume (0.0 - 1.0)"));
- addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llLoopSound", NULL, "sf", "llLoopSound(string sound, float volume)\nplays attached sound looping indefinitely at volume (0.0 - 1.0)"));
- addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llLoopSoundMaster", NULL, "sf", "llLoopSoundMaster(string sound, float volume)\nplays attached sound looping at volume (0.0 - 1.0), declares it a sync master"));
- addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llLoopSoundSlave", NULL, "sf", "llLoopSoundSlave(string sound, float volume)\nplays attached sound looping at volume (0.0 - 1.0), synced to most audible sync master"));
- addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llPlaySoundSlave", NULL, "sf", "llPlaySoundSlave(string sound, float volume)\nplays attached sound once at volume (0.0 - 1.0), synced to next loop of most audible sync master"));
- addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llTriggerSound", NULL, "sf", "llTriggerSound(string sound, float volume)\nplays sound at volume (0.0 - 1.0), centered at but not attached to object"));
- addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llStopSound", NULL, "", "llStopSound()\nStops currently attached sound"));
- addFunction(new LLScriptLibraryFunction(10.f, 1.f, dummy_func, "llPreloadSound", NULL, "s", "llPreloadSound(string sound)\npreloads a sound on viewers within range"));
- addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llGetSubString", "s", "sii", "string llGetSubString(string src, integer start, integer end)\nreturns the indicated substring"));
- addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llDeleteSubString", "s", "sii", "string llDeleteSubString(string src, integer start, integer end)\nremoves the indicated substring and returns the result"));
- addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llInsertString", "s", "sis", "string llInsertString(string dst, integer position, string src)\ninserts src into dst at position and returns the result"));
- addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llToUpper", "s", "s", "string llToUpper(string src)\nconvert src to all upper case and returns the result"));
- addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llToLower", "s", "s", "string llToLower(string src)\nconvert src to all lower case and returns the result"));
- addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llGiveMoney", "i", "ki", "llGiveMoney(key destination, integer amount)\ntransfer amount of money from script owner to destination"));
- addFunction(new LLScriptLibraryFunction(10.f, 0.1f, dummy_func, "llMakeExplosion", NULL, "iffffsv", "llMakeExplosion(integer particles, float scale, float vel, float lifetime, float arc, string texture, vector offset)\nMake a round explosion of particles"));
- addFunction(new LLScriptLibraryFunction(10.f, 0.1f, dummy_func, "llMakeFountain", NULL, "iffffisvf", "llMakeFountain(integer particles, float scale, float vel, float lifetime, float arc, integer bounce, string texture, vector offset, float bounce_offset)\nMake a fountain of particles"));
- addFunction(new LLScriptLibraryFunction(10.f, 0.1f, dummy_func, "llMakeSmoke", NULL, "iffffsv", "llMakeSmoke(integer particles, float scale, float vel, float lifetime, float arc, string texture, vector offset)\nMake smoke like particles"));
- addFunction(new LLScriptLibraryFunction(10.f, 0.1f, dummy_func, "llMakeFire", NULL, "iffffsv", "llMakeFire(integer particles, float scale, float vel, float lifetime, float arc, string texture, vector offset)\nMake fire like particles"));
- addFunction(new LLScriptLibraryFunction(200.f, 0.1f, dummy_func, "llRezObject", NULL, "svvqi", "llRezObject(string inventory, vector pos, vector vel, rotation rot, integer param)\nInstanciate owners inventory object at pos with velocity vel and rotation rot with start parameter param"));
- addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llLookAt", NULL, "vff", "llLookAt(vector target, F32 strength, F32 damping)\nCause object name to point it's forward axis towards target"));
- addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llStopLookAt", NULL, NULL, "llStopLookAt()\nStop causing object name to point at a target"));
- addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llSetTimerEvent", NULL, "f", "llSetTimerEvent(float sec)\nCause the timer event to be triggered every sec seconds"));
- addFunction(new LLScriptLibraryFunction(0.f, 0.f, dummy_func, "llSleep", NULL, "f", "llSleep(float sec)\nPut script to sleep for sec seconds"));
- addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llGetMass", "f", NULL, "float llGetMass()\nGet the mass of task name that script is attached to"));
- addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llCollisionFilter", NULL, "ski", "llCollisionFilter(string name, key id, integer accept)\nif accept == TRUE, only accept collisions with objects name and id (either is optional), otherwise with objects not name or id"));
- addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llTakeControls", NULL, "iii", "llTakeControls(integer controls, integer accept, integer pass_on)\nTake controls from agent task has permissions for. If (accept == (controls & input)), send input to task. If pass_on send to agent also."));
- addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llReleaseControls", NULL, NULL, "llReleaseControls()\nStop taking inputs"));
- addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llAttachToAvatar", NULL, "i", "llAttachToAvatar(integer attachment)\nAttach to avatar task has permissions for at point attachment"));
- addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llDetachFromAvatar", NULL, NULL, "llDetachFromAvatar()\nDrop off of avatar"));
- addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llTakeCamera", NULL, "k", "llTakeCamera(key avatar)\nMove avatar's viewpoint to task"));
- addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llReleaseCamera", NULL, "k", "llReleaseCamera(key avatar)\nReturn camera to agent"));
- addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llGetOwner", "k", NULL, "key llGetOwner()\nReturns the owner of the task"));
- addFunction(new LLScriptLibraryFunction(10.f, 2.f, dummy_func, "llInstantMessage", NULL, "ks", "llInstantMessage(key user, string message)\nIMs message to the user"));
- addFunction(new LLScriptLibraryFunction(10.f, 20.f, dummy_func, "llEmail", NULL, "sss", "llEmail(string address, string subject, string message)\nSends email to address with subject and message"));
- addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llGetNextEmail", NULL, "ss", "llGetNextEmail(string address, string subject)\nGet the next waiting email with appropriate address and/or subject (if blank they are ignored)"));
- addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llGetKey", "k", NULL, "key llGetKey()\nGet the key for the task the script is attached to"));
- addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llSetBuoyancy", NULL, "f", "llSetBuoyancy(float buoyancy)\nSet the tasks buoyancy (0 is none, < 1.0 sinks, 1.0 floats, > 1.0 rises)"));
- addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llSetHoverHeight", NULL, "fif", "llSetHoverHeight(float height, integer water, float tau)\nCritically damps to a height (either above ground level or above the higher of land and water if water == TRUE)"));
- addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llStopHover", NULL, NULL, "llStopHover()\nStop hovering to a height"));
- addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llMinEventDelay", NULL, "f", "llMinEventDelay(float delay)\nSet the minimum time between events being handled"));
- addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llSoundPreload", NULL, "s", "llSoundPreload(string sound)\npreloads a sound on viewers within range"));
- addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llRotLookAt", NULL, "qff", "llRotLookAt(rotation target, F32 strength, F32 damping)\nCause object name to point it's forward axis towards target"));
- addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llStringLength", "i", "s", "integer llStringLength(string str)\nReturns the length of string"));
- addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llStartAnimation", NULL, "s", "llStartAnimation(string anim)\nStart animation anim for agent that owns object"));
- addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llStopAnimation", NULL, "s", "llStopAnimation(string anim)\nStop animation anim for agent that owns object"));
- addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llPointAt", NULL, "v", "llPointAt(vector pos)\nMake agent that owns object point at pos"));
- addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llStopPointAt", NULL, NULL, "llStopPointAt()\nStop agent that owns object pointing"));
- addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llTargetOmega", NULL, "vff", "llTargetOmega(vector axis, float spinrate, float gain)\nAttempt to spin at spinrate with strength gain"));
- addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llGetStartParameter", "i", NULL, "integer llGetStartParameter()\nGet's the start paramter passed to llRezObject"));
- addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llGodLikeRezObject", NULL, "kv", "llGodLikeRezObject(key inventory, vector pos)\nrez directly off of a UUID if owner has dog-bit set", TRUE));
- addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llRequestPermissions", NULL, "ki", "llRequestPermissions(key agent, integer perm)\nask agent to allow the script to do perm (NB: Debit, ownership, link, joint, and permission requests can only go to the task's owner)"));
- addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llGetPermissionsKey", "k", NULL, "key llGetPermissionsKey()\nReturn agent that permissions are enabled for. NULL_KEY if not enabled"));
- addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llGetPermissions", "i", NULL, "integer llGetPermissions()\nreturn what permissions have been enabled"));
- addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llGetLinkNumber", "i", NULL, "integer llGetLinkNumber()\nReturns what number in a link set the script is attached to (0 means no link, 1 the root, 2 for first child, &c)"));
- addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llSetLinkColor", NULL, "ivi", "llSetLinkColor(integer linknumber, vector color, integer face)\nIf a task exists in the link chain at linknumber, set face to color"));
- addFunction(new LLScriptLibraryFunction(10.f, 1.f, dummy_func, "llCreateLink", NULL, "ki", "llCreateLink(key target, integer parent)\nAttempt to link task script is attached to and target (requires permission PERMISSION_CHANGE_LINKS be set). If parent == TRUE, task script is attached to is the root"));
- addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llBreakLink", NULL, "i", "llBreakLink(integer linknum)\nDelinks the task with the given link number (requires permission PERMISSION_CHANGE_LINKS be set)"));
- addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llBreakAllLinks", NULL, NULL, "llBreakAllLinks()\nDelinks all tasks in the link set (requires permission PERMISSION_CHANGE_LINKS be set)"));
- addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llGetLinkKey", "k", "i", "key llGetLinkKey(integer linknum)\nGet the key of linknumber in link set"));
- addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llGetLinkName", "s", "i", "string llGetLinkName(integer linknum)\nGet the name of linknumber in link set"));
- addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llGetInventoryNumber", "i", "i", "integer llGetInventoryNumber(integer type)\nGet the number of items of a given type in the task's inventory.\nValid types: INVENTORY_TEXTURE, INVENTORY_SOUND, INVENTORY_OBJECT, INVENTORY_SCRIPT, INVENTORY_CLOTHING, INVENTORY_BODYPART, INVENTORY_NOTECARD, INVENTORY_LANDMARK, INVENTORY_ALL"));
- addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llGetInventoryName", "s", "ii", "string llGetInventoryName(integer type, integer number)\nGet the name of the inventory item number of type"));
- addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llSetScriptState", NULL, "si", "llSetScriptState(string name, integer run)\nControl the state of a script name."));
- addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llGetEnergy", "f", NULL, "float llGetEnergy()\nReturns how much energy is in the object as a percentage of maximum"));
- addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llGiveInventory", NULL, "ks", "llGiveInventory(key destination, string inventory)\nGive inventory to destination"));
- addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llRemoveInventory", NULL, "s", "llRemoveInventory(string inventory)\nRemove the named inventory item"));
- addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llSetText", NULL, "svf", "llSetText(string text, vector color, float alpha)\nSet text floating over object"));
- addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llWater", "f", "v", "float llWater(vector v)\nreturns the water height below the object position + v"));
- addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llPassTouches", NULL, "i", "llPassTouches(integer pass)\nif pass == TRUE, touches are passed from children on to parents (default is FALSE)"));
- addFunction(new LLScriptLibraryFunction(10.f, 0.1f, dummy_func, "llRequestAgentData", "k", "ki", "key llRequestAgentData(key id, integer data)\nRequests data about agent id. When data is available the dataserver event will be raised"));
- addFunction(new LLScriptLibraryFunction(10.f, 1.f, dummy_func, "llRequestInventoryData", "k", "s", "key llRequestInventoryData(string name)\nRequests data from object's inventory object. When data is available the dataserver event will be raised"));
- addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llSetDamage", NULL, "f", "llSetDamage(float damage)\nSets the amount of damage that will be done to an object that this task hits. Task will be killed."));
- addFunction(new LLScriptLibraryFunction(100.f, 5.f, dummy_func, "llTeleportAgentHome", NULL, "k", "llTeleportAgentHome(key id)\nTeleports agent on owner's land to agent's home location"));
- addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llModifyLand", NULL, "ii", "llModifyLand(integer action, integer size)\nModify land with action (LAND_LEVEL, LAND_RAISE, LAND_LOWER, LAND_SMOOTH, LAND_NOISE, LAND_REVERT)\non size (LAND_SMALL_BRUSH, LAND_MEDIUM_BRUSH, LAND_LARGE_BRUSH)"));
- addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llCollisionSound", NULL, "sf", "llCollisionSound(string impact_sound, float impact_volume)\nSuppress default collision sounds, replace default impact sounds with impact_sound (empty string to just suppress)"));
- addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llCollisionSprite", NULL, "s", "llCollisionSprite(string impact_sprite)\nSuppress default collision sprites, replace default impact sprite with impact_sprite (empty string to just suppress)"));
- addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llGetAnimation", "s", "k", "string llGetAnimation(key id)\nGet the currently playing locomotion animation for avatar id"));
- addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llResetScript", NULL, NULL, "llResetScript()\nResets the script"));
- addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llMessageLinked", NULL, "iisk", "llMessageLinked(integer linknum, integer num, string str, key id)\nSends num, str, and id to members of the link set (LINK_ROOT sends to root task in a linked set,\nLINK_SET sends to all tasks,\nLINK_ALL_OTHERS to all other tasks,\nLINK_ALL_CHILDREN to all children,\nLINK_THIS to the task the script it is in)"));
- addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llPushObject", NULL, "kvvi", "llPushObject(key id, vector impulse, vector ang_impulse, integer local)\nApplies impulse and ang_impulse to object id"));
- addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llPassCollisions", NULL, "i", "llPassCollisions(integer pass)\nif pass == TRUE, collisions are passed from children on to parents (default is FALSE)"));
- addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llGetScriptName", "s", NULL, "llGetScriptName()\nReturns the script name"));
- addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llGetNumberOfSides", "i", NULL, "integer llGetNumberOfSides()\nReturns the number of sides"));
- addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llAxisAngle2Rot", "q", "vf", "rotation llAxisAngle2Rot(vector axis, float angle)\nReturns the rotation generated angle about axis"));
- addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llRot2Axis", "v", "q", "vector llRot2Axis(rotation rot)\nReturns the rotation axis represented by rot"));
- addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llRot2Angle", "f", "q", "float llRot2Angle(rotation rot)\nReturns the rotation angle represented by rot"));
- addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llAcos", "f", "f", "float llAcos(float val)\nReturns the arccosine in radians of val"));
- addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llAsin", "f", "f", "float llAsin(float val)\nReturns the arcsine in radians of val"));
- addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llAngleBetween", "f", "qq", "float llAngleBetween(rotation a, rotation b)\nReturns angle between rotation a and b"));
- addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llGetInventoryKey", "k", "s", "key llGetInventoryKey(string name)\nReturns the key of the inventory name"));
- addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llAllowInventoryDrop", NULL, "i", "llAllowInventoryDrop(integer add)\nIf add == TRUE, users without permissions can still drop inventory items onto task"));
- addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llGetSunDirection", "v", NULL, "vector llGetSunDirection()\nReturns the sun direction on the simulator"));
- addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llGetTextureOffset", "v", "i", "vector llGetTextureOffset(integer side)\nReturns the texture offset of side in the x and y components of a vector"));
- addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llGetTextureScale", "v", "i", "vector llGetTextureScale(integer side)\nReturns the texture scale of side in the x and y components of a vector"));
- addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llGetTextureRot", "f", "i", "float llGetTextureRot(integer side)\nReturns the texture rotation of side"));
- addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llSubStringIndex", "i", "ss", "integer llSubStringIndex(string source, string pattern)\nFinds index in source where pattern first appears (returns -1 if not found)"));
- addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llGetOwnerKey", "k", "k", "key llGetOwnerKey(key id)\nFind the owner of id"));
- addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llGetCenterOfMass", "v", NULL, "vector llGetCenterOfMass()\nGet the object's center of mass"));
- addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llListSort", "l", "lii", "list llListSort(list src, integer stride, integer ascending)\nSort the list into blocks of stride in ascending order if ascending == TRUE. Note that sort only works between same types."));
- addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llGetListLength", "i", "l", "integer llGetListLength(list src)\nGet the number of elements in the list"));
- addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llList2Integer", "i", "li", "integer llList2Integer(list src, integer index)\nCopy the integer at index in the list"));
- addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llList2Float", "f", "li", "float llList2Float(list src, integer index)\nCopy the float at index in the list"));
- addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llList2String", "s", "li", "string llList2String(list src, integer index)\nCopy the string at index in the list"));
- addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llList2Key", "k", "li", "key llList2Key(list src, integer index)\nCopy the key at index in the list"));
- addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llList2Vector", "v", "li", "vector llList2Vector(list src, integer index)\nCopy the vector at index in the list"));
- addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llList2Rot", "q", "li", "rotation llList2Rot(list src, integer index)\nCopy the rotation at index in the list"));
- addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llList2List", "l", "lii", "list llList2List(list src, integer start, integer end)\nCopy the slice of the list from start to end"));
- addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llDeleteSubList", "l", "lii", "list llDeleteSubList(list src, integer start, integer end)\nRemove the slice from the list and return the remainder"));
- addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llGetListEntryType", "i", "li", "integer llGetListEntryType(list src, integer index)\nReturns the type of the index entry in the list\n(TYPE_INTEGER, TYPE_FLOAT, TYPE_STRING, TYPE_KEY, TYPE_VECTOR, TYPE_ROTATION, or TYPE_INVALID if index is off list)"));
- addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llList2CSV", "s", "l", "string llList2CSV(list src)\nCreate a string of comma separated values from list"));
- addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llCSV2List", "l", "s", "list llCSV2List(string src)\nCreate a list from a string of comma separated values"));
- addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llListRandomize", "l", "li", "list llListRandomize(list src, integer stride)\nReturns a randomized list of blocks of size stride"));
- addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llList2ListStrided", "l", "liii", "list llList2ListStrided(list src, integer start, integer end, integer stride)\nCopy the strided slice of the list from start to end"));
- addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llGetRegionCorner", "v", NULL, "vector llGetRegionCorner()\nReturns a vector with the south west corner x,y position of the region the object is in"));
- addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llListInsertList", "l", "lli", "list llListInsertList(list dest, list src, integer start)\nInserts src into dest at position start"));
- addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llListFindList", "i", "ll", "integer llListFindList(list src, list test)\nReturns the start of the first instance of test in src, -1 if not found"));
- addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llGetObjectName", "s", NULL, "string llGetObjectName()\nReturns the name of the object script is attached to"));
- addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llSetObjectName", NULL, "s", "llSetObjectName(string name)\nSets the objects name"));
- addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llGetDate", "s", NULL, "string llGetDate()\nGets the date as YYYY-MM-DD"));
- addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llEdgeOfWorld", "i", "vv", "integer llEdgeOfWorld(vector pos, vector dir)\nChecks to see whether the border hit by dir from pos is the edge of the world (has no neighboring simulator)"));
- addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llGetAgentInfo", "i", "k", "integer llGetAgentInfo(key id)\nGets information about agent ID.\nReturns AGENT_FLYING, AGENT_ATTACHMENTS, AGENT_SCRIPTED, AGENT_SITTING, AGENT_ON_OBJECT, AGENT_MOUSELOOK, AGENT_AWAY, AGENT_BUSY, AGENT_TYPING, AGENT_CROUCHING, AGENT_ALWAYS_RUN, AGENT_WALKING and/or AGENT_IN_AIR."));
- addFunction(new LLScriptLibraryFunction(10.f, 0.1f, dummy_func, "llAdjustSoundVolume", NULL, "f", "llAdjustSoundVolume(float volume)\nadjusts volume of attached sound (0.0 - 1.0)"));
- addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llSetSoundQueueing", NULL, "i", "llSetSoundQueueing(integer queue)\ndetermines whether attached sound calls wait for the current sound to finish (0 = no [default], nonzero = yes)"));
- addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llSetSoundRadius", NULL, "f", "llSetSoundRadius(float radius)\nestablishes a hard cut-off radius for audibility of scripted sounds (both attached and triggered)"));
- addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llKey2Name", "s", "k", "string llKey2Name(key id)\nReturns the name of the object key, iff the object is in the current simulator, otherwise the empty string"));
- addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llSetTextureAnim", NULL, "iiiifff", "llSetTextureAnim(integer mode, integer face, integer sizex, integer sizey, float start, float length, float rate)\nAnimate the texture on the specified face/faces"));
- addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llTriggerSoundLimited", NULL, "sfvv", "llTriggerSoundLimited(string sound, float volume, vector tne, vector bsw)\nplays sound at volume (0.0 - 1.0), centered at but not attached to object, limited to AABB defined by vectors top-north-east and bottom-south-west"));
- addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llEjectFromLand", NULL, "k", "llEjectFromLand(key pest)\nEjects pest from land that you own"));
- addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llParseString2List", "l", "sll", "list llParseString2List(string src, list separators, list spacers)\nBreaks src into a list, discarding separators, keeping spacers (separators and spacers must be lists of strings, maximum of 8 each)"));
- addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llOverMyLand", "i", "k", "integer llOverMyLand(key id)\nReturns TRUE if id is over land owner of object owns, FALSE otherwise"));
- addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llGetLandOwnerAt", "k", "v", "key llGetLandOwnerAt(vector pos)\nReturns the key of the land owner, NULL_KEY if public"));
- addFunction(new LLScriptLibraryFunction(10.f, 0.1f, dummy_func, "llGetNotecardLine", "k", "si", "key llGetNotecardLine(string name, integer line)\nReturns line line of notecard name via the dataserver event"));
- addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llGetAgentSize", "v", "k", "vector llGetAgentSize(key id)\nIf the agent is in the same sim as the object, returns the size of the avatar"));
- addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llSameGroup", "i", "k", "integer llSameGroup(key id)\nReturns TRUE if ID is in the same sim and has the same active group, otherwise FALSE"));
- addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llUnSit", NULL, "k", "key llUnSit(key id)\nIf agent identified by id is sitting on the object the script is attached to or is over land owned by the objects owner, the agent is forced to stand up"));
- addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llGroundSlope", "v", "v", "vector llGroundSlope(vector v)\nreturns the ground slope below the object position + v"));
- addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llGroundNormal", "v", "v", "vector llGroundNormal(vector v)\nreturns the ground normal below the object position + v"));
- addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llGroundContour", "v", "v", "vector llGroundCountour(vector v)\nreturns the ground contour below the object position + v"));
- addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llGetAttached", "i", NULL, "integer llGetAttached()\nreturns the object attachment point or 0 if not attached"));
- addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llGetFreeMemory", "i", NULL, "integer llGetFreeMemory()\nreturns the available heap space for the current script"));
- addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llGetRegionName", "s", NULL, "string llGetRegionName()\nreturns the current region name"));
- addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llGetRegionTimeDilation", "f", NULL, "float llGetRegionTimeDilation()\nreturns the current time dilation as a float between 0 and 1"));
- addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llGetRegionFPS", "f", NULL, "float llGetRegionFPS()\nreturns the mean region frames per second"));
-
- addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llParticleSystem", NULL, "l", "llParticleSystem(list rules)\nCreates a particle system based on rules. Empty list removes particle system from object.\nList format is [ rule1, data1, rule2, data2 . . . rulen, datan ]"));
- addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llGroundRepel", NULL, "fif", "llGroundRepel(float height, integer water, float tau)\nCritically damps to height if within height*0.5 of level (either above ground level or above the higher of land and water if water == TRUE)"));
- addFunction(new LLScriptLibraryFunction(10.f, 3.f, dummy_func, "llGiveInventoryList", NULL, "ksl", "llGiveInventoryList(key destination, string category, list inventory)\nGive inventory to destination in a new category"));
+ // energy, sleep, dummy_func, name, return type, parameters, gods-only
+ addFunction(10.f, 0.f, dummy_func, "llSin", "f", "f");
+ addFunction(10.f, 0.f, dummy_func, "llCos", "f", "f");
+ addFunction(10.f, 0.f, dummy_func, "llTan", "f", "f");
+ addFunction(10.f, 0.f, dummy_func, "llAtan2", "f", "ff");
+ addFunction(10.f, 0.f, dummy_func, "llSqrt", "f", "f");
+ addFunction(10.f, 0.f, dummy_func, "llPow", "f", "ff");
+ addFunction(10.f, 0.f, dummy_func, "llAbs", "i", "i");
+ addFunction(10.f, 0.f, dummy_func, "llFabs", "f", "f");
+ addFunction(10.f, 0.f, dummy_func, "llFrand", "f", "f");
+ addFunction(10.f, 0.f, dummy_func, "llFloor", "i", "f");
+ addFunction(10.f, 0.f, dummy_func, "llCeil", "i", "f");
+ addFunction(10.f, 0.f, dummy_func, "llRound", "i", "f");
+ addFunction(10.f, 0.f, dummy_func, "llVecMag", "f", "v");
+ addFunction(10.f, 0.f, dummy_func, "llVecNorm", "v", "v");
+ addFunction(10.f, 0.f, dummy_func, "llVecDist", "f", "vv");
+ addFunction(10.f, 0.f, dummy_func, "llRot2Euler", "v", "q");
+ addFunction(10.f, 0.f, dummy_func, "llEuler2Rot", "q", "v");
+ addFunction(10.f, 0.f, dummy_func, "llAxes2Rot", "q", "vvv");
+ addFunction(10.f, 0.f, dummy_func, "llRot2Fwd", "v", "q");
+ addFunction(10.f, 0.f, dummy_func, "llRot2Left", "v", "q");
+ addFunction(10.f, 0.f, dummy_func, "llRot2Up", "v", "q");
+ addFunction(10.f, 0.f, dummy_func, "llRotBetween", "q", "vv");
+ addFunction(10.f, 0.f, dummy_func, "llWhisper", NULL, "is");
+ addFunction(10.f, 0.f, dummy_func, "llSay", NULL, "is");
+ addFunction(10.f, 0.f, dummy_func, "llShout", NULL, "is");
+ addFunction(10.f, 0.f, dummy_func, "llListen", "i", "isks");
+ addFunction(10.f, 0.f, dummy_func, "llListenControl", NULL, "ii");
+ addFunction(10.f, 0.f, dummy_func, "llListenRemove", NULL, "i");
+ addFunction(10.f, 0.f, dummy_func, "llSensor", NULL, "skiff");
+ addFunction(10.f, 0.f, dummy_func, "llSensorRepeat", NULL, "skifff");
+ addFunction(10.f, 0.f, dummy_func, "llSensorRemove", NULL, NULL);
+ addFunction(10.f, 0.f, dummy_func, "llDetectedName", "s", "i");
+ addFunction(10.f, 0.f, dummy_func, "llDetectedKey", "k", "i");
+ addFunction(10.f, 0.f, dummy_func, "llDetectedOwner", "k", "i");
+ addFunction(10.f, 0.f, dummy_func, "llDetectedType", "i", "i");
+ addFunction(10.f, 0.f, dummy_func, "llDetectedPos", "v", "i");
+ addFunction(10.f, 0.f, dummy_func, "llDetectedVel", "v", "i");
+ addFunction(10.f, 0.f, dummy_func, "llDetectedGrab", "v", "i");
+ addFunction(10.f, 0.f, dummy_func, "llDetectedRot", "q", "i");
+ addFunction(10.f, 0.f, dummy_func, "llDetectedGroup", "i", "i");
+ addFunction(10.f, 0.f, dummy_func, "llDetectedLinkNumber", "i", "i");
+ addFunction(0.f, 0.f, dummy_func, "llDie", NULL, NULL);
+ addFunction(10.f, 0.f, dummy_func, "llGround", "f", "v");
+ addFunction(10.f, 0.f, dummy_func, "llCloud", "f", "v");
+ addFunction(10.f, 0.f, dummy_func, "llWind", "v", "v");
+ addFunction(10.f, 0.f, dummy_func, "llSetStatus", NULL, "ii");
+ addFunction(10.f, 0.f, dummy_func, "llGetStatus", "i", "i");
+ addFunction(10.f, 0.f, dummy_func, "llSetScale", NULL, "v");
+ addFunction(10.f, 0.f, dummy_func, "llGetScale", "v", NULL);
+ addFunction(10.f, 0.f, dummy_func, "llSetColor", NULL, "vi");
+ addFunction(10.f, 0.f, dummy_func, "llGetAlpha", "f", "i");
+ addFunction(10.f, 0.f, dummy_func, "llSetAlpha", NULL, "fi");
+ addFunction(10.f, 0.f, dummy_func, "llGetColor", "v", "i");
+ addFunction(10.f, 0.2f, dummy_func, "llSetTexture", NULL, "si");
+ addFunction(10.f, 0.2f, dummy_func, "llScaleTexture", NULL, "ffi");
+ addFunction(10.f, 0.2f, dummy_func, "llOffsetTexture", NULL, "ffi");
+ addFunction(10.f, 0.2f, dummy_func, "llRotateTexture", NULL, "fi");
+ addFunction(10.f, 0.f, dummy_func, "llGetTexture", "s", "i");
+ addFunction(10.f, 0.2f, dummy_func, "llSetPos", NULL, "v");
+ addFunction(10.f, 0.f, dummy_func, "llGetPos", "v", NULL);
+ addFunction(10.f, 0.f, dummy_func, "llGetLocalPos", "v", NULL);
+ addFunction(10.f, 0.2f, dummy_func, "llSetRot", NULL, "q");
+ addFunction(10.f, 0.f, dummy_func, "llGetRot", "q", NULL);
+ addFunction(10.f, 0.f, dummy_func, "llGetLocalRot", "q", NULL);
+ addFunction(10.f, 0.f, dummy_func, "llSetForce", NULL, "vi");
+ addFunction(10.f, 0.f, dummy_func, "llGetForce", "v", NULL);
+ addFunction(10.f, 0.f, dummy_func, "llTarget", "i", "vf");
+ addFunction(10.f, 0.f, dummy_func, "llTargetRemove", NULL, "i");
+ addFunction(10.f, 0.f, dummy_func, "llRotTarget", "i", "qf");
+ addFunction(10.f, 0.f, dummy_func, "llRotTargetRemove", NULL, "i");
+ addFunction(10.f, 0.f, dummy_func, "llMoveToTarget", NULL, "vf");
+ addFunction(10.f, 0.f, dummy_func, "llStopMoveToTarget", NULL, NULL);
+ addFunction(10.f, 0.f, dummy_func, "llApplyImpulse", NULL, "vi");
+ addFunction(10.f, 0.f, dummy_func, "llApplyRotationalImpulse", NULL, "vi");
+ addFunction(10.f, 0.f, dummy_func, "llSetTorque", NULL, "vi");
+ addFunction(10.f, 0.f, dummy_func, "llGetTorque", "v", NULL);
+ addFunction(10.f, 0.f, dummy_func, "llSetForceAndTorque", NULL, "vvi");
+ addFunction(10.f, 0.f, dummy_func, "llGetVel", "v", NULL);
+ addFunction(10.f, 0.f, dummy_func, "llGetAccel", "v", NULL);
+ addFunction(10.f, 0.f, dummy_func, "llGetOmega", "v", NULL);
+ addFunction(10.f, 0.f, dummy_func, "llGetTimeOfDay", "f", "");
+ addFunction(10.f, 0.f, dummy_func, "llGetWallclock", "f", "");
+ addFunction(10.f, 0.f, dummy_func, "llGetTime", "f", NULL);
+ addFunction(10.f, 0.f, dummy_func, "llResetTime", NULL, NULL);
+ addFunction(10.f, 0.f, dummy_func, "llGetAndResetTime", "f", NULL);
+ addFunction(10.f, 0.f, dummy_func, "llSound", NULL, "sfii");
+ addFunction(10.f, 0.f, dummy_func, "llPlaySound", NULL, "sf");
+ addFunction(10.f, 0.f, dummy_func, "llLoopSound", NULL, "sf");
+ addFunction(10.f, 0.f, dummy_func, "llLoopSoundMaster", NULL, "sf");
+ addFunction(10.f, 0.f, dummy_func, "llLoopSoundSlave", NULL, "sf");
+ addFunction(10.f, 0.f, dummy_func, "llPlaySoundSlave", NULL, "sf");
+ addFunction(10.f, 0.f, dummy_func, "llTriggerSound", NULL, "sf");
+ addFunction(10.f, 0.f, dummy_func, "llStopSound", NULL, "");
+ addFunction(10.f, 1.f, dummy_func, "llPreloadSound", NULL, "s");
+ addFunction(10.f, 0.f, dummy_func, "llGetSubString", "s", "sii");
+ addFunction(10.f, 0.f, dummy_func, "llDeleteSubString", "s", "sii");
+ addFunction(10.f, 0.f, dummy_func, "llInsertString", "s", "sis");
+ addFunction(10.f, 0.f, dummy_func, "llToUpper", "s", "s");
+ addFunction(10.f, 0.f, dummy_func, "llToLower", "s", "s");
+ addFunction(10.f, 0.f, dummy_func, "llGiveMoney", "i", "ki");
+ addFunction(10.f, 0.1f, dummy_func, "llMakeExplosion", NULL, "iffffsv");
+ addFunction(10.f, 0.1f, dummy_func, "llMakeFountain", NULL, "iffffisvf");
+ addFunction(10.f, 0.1f, dummy_func, "llMakeSmoke", NULL, "iffffsv");
+ addFunction(10.f, 0.1f, dummy_func, "llMakeFire", NULL, "iffffsv");
+ addFunction(200.f, 0.1f, dummy_func, "llRezObject", NULL, "svvqi");
+ addFunction(10.f, 0.f, dummy_func, "llLookAt", NULL, "vff");
+ addFunction(10.f, 0.f, dummy_func, "llStopLookAt", NULL, NULL);
+ addFunction(10.f, 0.f, dummy_func, "llSetTimerEvent", NULL, "f");
+ addFunction(0.f, 0.f, dummy_func, "llSleep", NULL, "f");
+ addFunction(10.f, 0.f, dummy_func, "llGetMass", "f", NULL);
+ addFunction(10.f, 0.f, dummy_func, "llCollisionFilter", NULL, "ski");
+ addFunction(10.f, 0.f, dummy_func, "llTakeControls", NULL, "iii");
+ addFunction(10.f, 0.f, dummy_func, "llReleaseControls", NULL, NULL);
+ addFunction(10.f, 0.f, dummy_func, "llAttachToAvatar", NULL, "i");
+ addFunction(10.f, 0.f, dummy_func, "llDetachFromAvatar", NULL, NULL);
+ addFunction(10.f, 0.f, dummy_func, "llTakeCamera", NULL, "k");
+ addFunction(10.f, 0.f, dummy_func, "llReleaseCamera", NULL, "k");
+ addFunction(10.f, 0.f, dummy_func, "llGetOwner", "k", NULL);
+ addFunction(10.f, 2.f, dummy_func, "llInstantMessage", NULL, "ks");
+ addFunction(10.f, 20.f, dummy_func, "llEmail", NULL, "sss");
+ addFunction(10.f, 0.f, dummy_func, "llGetNextEmail", NULL, "ss");
+ addFunction(10.f, 0.f, dummy_func, "llGetKey", "k", NULL);
+ addFunction(10.f, 0.f, dummy_func, "llSetBuoyancy", NULL, "f");
+ addFunction(10.f, 0.f, dummy_func, "llSetHoverHeight", NULL, "fif");
+ addFunction(10.f, 0.f, dummy_func, "llStopHover", NULL, NULL);
+ addFunction(10.f, 0.f, dummy_func, "llMinEventDelay", NULL, "f");
+ addFunction(10.f, 0.f, dummy_func, "llSoundPreload", NULL, "s");
+ addFunction(10.f, 0.f, dummy_func, "llRotLookAt", NULL, "qff");
+ addFunction(10.f, 0.f, dummy_func, "llStringLength", "i", "s");
+ addFunction(10.f, 0.f, dummy_func, "llStartAnimation", NULL, "s");
+ addFunction(10.f, 0.f, dummy_func, "llStopAnimation", NULL, "s");
+ addFunction(10.f, 0.f, dummy_func, "llPointAt", NULL, "v");
+ addFunction(10.f, 0.f, dummy_func, "llStopPointAt", NULL, NULL);
+ addFunction(10.f, 0.f, dummy_func, "llTargetOmega", NULL, "vff");
+ addFunction(10.f, 0.f, dummy_func, "llGetStartParameter", "i", NULL);
+ addFunction(10.f, 0.f, dummy_func, "llGodLikeRezObject", NULL, "kv", TRUE);
+ addFunction(10.f, 0.f, dummy_func, "llRequestPermissions", NULL, "ki");
+ addFunction(10.f, 0.f, dummy_func, "llGetPermissionsKey", "k", NULL);
+ addFunction(10.f, 0.f, dummy_func, "llGetPermissions", "i", NULL);
+ addFunction(10.f, 0.f, dummy_func, "llGetLinkNumber", "i", NULL);
+ addFunction(10.f, 0.f, dummy_func, "llSetLinkColor", NULL, "ivi");
+ addFunction(10.f, 1.f, dummy_func, "llCreateLink", NULL, "ki");
+ addFunction(10.f, 0.f, dummy_func, "llBreakLink", NULL, "i");
+ addFunction(10.f, 0.f, dummy_func, "llBreakAllLinks", NULL, NULL);
+ addFunction(10.f, 0.f, dummy_func, "llGetLinkKey", "k", "i");
+ addFunction(10.f, 0.f, dummy_func, "llGetLinkName", "s", "i");
+ addFunction(10.f, 0.f, dummy_func, "llGetInventoryNumber", "i", "i");
+ addFunction(10.f, 0.f, dummy_func, "llGetInventoryName", "s", "ii");
+ addFunction(10.f, 0.f, dummy_func, "llSetScriptState", NULL, "si");
+ addFunction(10.f, 0.f, dummy_func, "llGetEnergy", "f", NULL);
+ addFunction(10.f, 0.f, dummy_func, "llGiveInventory", NULL, "ks");
+ addFunction(10.f, 0.f, dummy_func, "llRemoveInventory", NULL, "s");
+ addFunction(10.f, 0.f, dummy_func, "llSetText", NULL, "svf");
+ addFunction(10.f, 0.f, dummy_func, "llWater", "f", "v");
+ addFunction(10.f, 0.f, dummy_func, "llPassTouches", NULL, "i");
+ addFunction(10.f, 0.1f, dummy_func, "llRequestAgentData", "k", "ki");
+ addFunction(10.f, 1.f, dummy_func, "llRequestInventoryData", "k", "s");
+ addFunction(10.f, 0.f, dummy_func, "llSetDamage", NULL, "f");
+ addFunction(100.f, 5.f, dummy_func, "llTeleportAgentHome", NULL, "k");
+ addFunction(10.f, 0.f, dummy_func, "llModifyLand", NULL, "ii");
+ addFunction(10.f, 0.f, dummy_func, "llCollisionSound", NULL, "sf");
+ addFunction(10.f, 0.f, dummy_func, "llCollisionSprite", NULL, "s");
+ addFunction(10.f, 0.f, dummy_func, "llGetAnimation", "s", "k");
+ addFunction(10.f, 0.f, dummy_func, "llResetScript", NULL, NULL);
+ addFunction(10.f, 0.f, dummy_func, "llMessageLinked", NULL, "iisk");
+ addFunction(10.f, 0.f, dummy_func, "llPushObject", NULL, "kvvi");
+ addFunction(10.f, 0.f, dummy_func, "llPassCollisions", NULL, "i");
+ addFunction(10.f, 0.f, dummy_func, "llGetScriptName", "s", NULL);
+ addFunction(10.f, 0.f, dummy_func, "llGetNumberOfSides", "i", NULL);
+ addFunction(10.f, 0.f, dummy_func, "llAxisAngle2Rot", "q", "vf");
+ addFunction(10.f, 0.f, dummy_func, "llRot2Axis", "v", "q");
+ addFunction(10.f, 0.f, dummy_func, "llRot2Angle", "f", "q");
+ addFunction(10.f, 0.f, dummy_func, "llAcos", "f", "f");
+ addFunction(10.f, 0.f, dummy_func, "llAsin", "f", "f");
+ addFunction(10.f, 0.f, dummy_func, "llAngleBetween", "f", "qq");
+ addFunction(10.f, 0.f, dummy_func, "llGetInventoryKey", "k", "s");
+ addFunction(10.f, 0.f, dummy_func, "llAllowInventoryDrop", NULL, "i");
+ addFunction(10.f, 0.f, dummy_func, "llGetSunDirection", "v", NULL);
+ addFunction(10.f, 0.f, dummy_func, "llGetTextureOffset", "v", "i");
+ addFunction(10.f, 0.f, dummy_func, "llGetTextureScale", "v", "i");
+ addFunction(10.f, 0.f, dummy_func, "llGetTextureRot", "f", "i");
+ addFunction(10.f, 0.f, dummy_func, "llSubStringIndex", "i", "ss");
+ addFunction(10.f, 0.f, dummy_func, "llGetOwnerKey", "k", "k");
+ addFunction(10.f, 0.f, dummy_func, "llGetCenterOfMass", "v", NULL);
+ addFunction(10.f, 0.f, dummy_func, "llListSort", "l", "lii");
+ addFunction(10.f, 0.f, dummy_func, "llGetListLength", "i", "l");
+ addFunction(10.f, 0.f, dummy_func, "llList2Integer", "i", "li");
+ addFunction(10.f, 0.f, dummy_func, "llList2Float", "f", "li");
+ addFunction(10.f, 0.f, dummy_func, "llList2String", "s", "li");
+ addFunction(10.f, 0.f, dummy_func, "llList2Key", "k", "li");
+ addFunction(10.f, 0.f, dummy_func, "llList2Vector", "v", "li");
+ addFunction(10.f, 0.f, dummy_func, "llList2Rot", "q", "li");
+ addFunction(10.f, 0.f, dummy_func, "llList2List", "l", "lii");
+ addFunction(10.f, 0.f, dummy_func, "llDeleteSubList", "l", "lii");
+ addFunction(10.f, 0.f, dummy_func, "llGetListEntryType", "i", "li");
+ addFunction(10.f, 0.f, dummy_func, "llList2CSV", "s", "l");
+ addFunction(10.f, 0.f, dummy_func, "llCSV2List", "l", "s");
+ addFunction(10.f, 0.f, dummy_func, "llListRandomize", "l", "li");
+ addFunction(10.f, 0.f, dummy_func, "llList2ListStrided", "l", "liii");
+ addFunction(10.f, 0.f, dummy_func, "llGetRegionCorner", "v", NULL);
+ addFunction(10.f, 0.f, dummy_func, "llListInsertList", "l", "lli");
+ addFunction(10.f, 0.f, dummy_func, "llListFindList", "i", "ll");
+ addFunction(10.f, 0.f, dummy_func, "llGetObjectName", "s", NULL);
+ addFunction(10.f, 0.f, dummy_func, "llSetObjectName", NULL, "s");
+ addFunction(10.f, 0.f, dummy_func, "llGetDate", "s", NULL);
+ addFunction(10.f, 0.f, dummy_func, "llEdgeOfWorld", "i", "vv");
+ addFunction(10.f, 0.f, dummy_func, "llGetAgentInfo", "i", "k");
+ addFunction(10.f, 0.1f, dummy_func, "llAdjustSoundVolume", NULL, "f");
+ addFunction(10.f, 0.f, dummy_func, "llSetSoundQueueing", NULL, "i");
+ addFunction(10.f, 0.f, dummy_func, "llSetSoundRadius", NULL, "f");
+ addFunction(10.f, 0.f, dummy_func, "llKey2Name", "s", "k");
+ addFunction(10.f, 0.f, dummy_func, "llSetTextureAnim", NULL, "iiiifff");
+ addFunction(10.f, 0.f, dummy_func, "llTriggerSoundLimited", NULL, "sfvv");
+ addFunction(10.f, 0.f, dummy_func, "llEjectFromLand", NULL, "k");
+ addFunction(10.f, 0.f, dummy_func, "llParseString2List", "l", "sll");
+ addFunction(10.f, 0.f, dummy_func, "llOverMyLand", "i", "k");
+ addFunction(10.f, 0.f, dummy_func, "llGetLandOwnerAt", "k", "v");
+ addFunction(10.f, 0.1f, dummy_func, "llGetNotecardLine", "k", "si");
+ addFunction(10.f, 0.f, dummy_func, "llGetAgentSize", "v", "k");
+ addFunction(10.f, 0.f, dummy_func, "llSameGroup", "i", "k");
+ addFunction(10.f, 0.f, dummy_func, "llUnSit", NULL, "k");
+ addFunction(10.f, 0.f, dummy_func, "llGroundSlope", "v", "v");
+ addFunction(10.f, 0.f, dummy_func, "llGroundNormal", "v", "v");
+ addFunction(10.f, 0.f, dummy_func, "llGroundContour", "v", "v");
+ addFunction(10.f, 0.f, dummy_func, "llGetAttached", "i", NULL);
+ addFunction(10.f, 0.f, dummy_func, "llGetFreeMemory", "i", NULL);
+ addFunction(10.f, 0.f, dummy_func, "llGetRegionName", "s", NULL);
+ addFunction(10.f, 0.f, dummy_func, "llGetRegionTimeDilation", "f", NULL);
+ addFunction(10.f, 0.f, dummy_func, "llGetRegionFPS", "f", NULL);
+
+ addFunction(10.f, 0.f, dummy_func, "llParticleSystem", NULL, "l");
+ addFunction(10.f, 0.f, dummy_func, "llGroundRepel", NULL, "fif");
+ addFunction(10.f, 3.f, dummy_func, "llGiveInventoryList", NULL, "ksl");
// script calls for vehicle action
- addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llSetVehicleType", NULL, "i", "llSetVehicleType(integer type)\nsets vehicle to one of the default types"));
- addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llSetVehicleFloatParam", NULL, "if", "llSetVehicleFloatParam(integer param, float value)\nsets the specified vehicle float parameter"));
- addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llSetVehicleVectorParam", NULL, "iv", "llSetVehicleVectorParam(integer param, vector vec)\nsets the specified vehicle vector parameter"));
- addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llSetVehicleRotationParam", NULL, "iq", "llSetVehicleVectorParam(integer param, rotation rot)\nsets the specified vehicle rotation parameter"));
- addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llSetVehicleFlags", NULL, "i", "llSetVehicleFlags(integer flags)\nsets the enabled bits in 'flags'"));
- addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llRemoveVehicleFlags", NULL, "i", "llRemoveVehicleFlags(integer flags)\nremoves the enabled bits in 'flags'"));
- addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llSitTarget", NULL, "vq", "llSitTarget(vector offset, rotation rot)\nSet the sit location for this object (if offset == <0,0,0> clear it)"));
- addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llAvatarOnSitTarget", "k", NULL, "key llAvatarOnSitTarget()\nIf an avatar is sitting on the sit target, return the avatar's key, NULL_KEY otherwise"));
- addFunction(new LLScriptLibraryFunction(10.f, 0.1f, dummy_func, "llAddToLandPassList", NULL, "kf", "llAddToLandPassList(key avatar, float hours)\nAdd avatar to the land pass list for hours"));
- addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llSetTouchText", NULL, "s", "llSetTouchText(string text)\nDisplays text in pie menu that acts as a touch"));
- addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llSetSitText", NULL, "s", "llSetSitText(string text)\nDisplays text rather than sit in pie menu"));
- addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llSetCameraEyeOffset", NULL, "v", "llSetCameraEyeOffset(vector offset)\nSets the camera eye offset used in this object if an avatar sits on it"));
- addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llSetCameraAtOffset", NULL, "v", "llSetCameraAtOffset(vector offset)\nSets the camera at offset used in this object if an avatar sits on it"));
-
- addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llDumpList2String", "s", "ls", "string llDumpList2String(list src, string separator)\nWrite the list out in a single string using separator between values"));
- addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llScriptDanger", "i", "v", "integer llScriptDanger(vector pos)\nReturns true if pos is over public land, sandbox land, land that doesn't allow everyone to edit and build, or land that doesn't allow outside scripts"));
- addFunction(new LLScriptLibraryFunction(10.f, 1.f, dummy_func, "llDialog", NULL, "ksli", "llDialog(key avatar, string message, list buttons, integer chat_channel\nShows a dialog box on the avatar's screen with the message.\nUp to 12 strings in the list form buttons.\nIf a button is clicked, the name is chatted on chat_channel."));
- addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llVolumeDetect", NULL, "i", "llVolumeDetect(integer detect)\nIf detect = TRUE, object becomes phantom but triggers collision_start and collision_end events\nwhen other objects start and stop interpenetrating.\nMust be applied to the root object."));
- addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llResetOtherScript", NULL, "s", "llResetOtherScript(string name)\nResets script name"));
- addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llGetScriptState", "i", "s", "integer llGetScriptState(string name)\nResets TRUE if script name is running"));
- addFunction(new LLScriptLibraryFunction(10.f, 3.f, dummy_func, "llRemoteLoadScript", NULL, "ksii", "Deprecated. Please use llRemoteLoadScriptPin instead."));
-
- addFunction(new LLScriptLibraryFunction(10.f, 0.2f, dummy_func, "llSetRemoteScriptAccessPin", NULL, "i", "llSetRemoteScriptAccessPin(integer pin)\nIf pin is set to a non-zero number, the task will accept remote script\nloads via llRemoteLoadScriptPin if it passes in the correct pin.\nOthersise, llRemoteLoadScriptPin is ignored."));
- addFunction(new LLScriptLibraryFunction(10.f, 3.f, dummy_func, "llRemoteLoadScriptPin", NULL, "ksiii", "llRemoteLoadScriptPin(key target, string name, integer pin, integer running, integer start_param)\nIf the owner of the object this script is attached can modify target,\nthey are in the same region,\nand the matching pin is used,\ncopy script name onto target,\nif running == TRUE, start the script with param."));
+ addFunction(10.f, 0.f, dummy_func, "llSetVehicleType", NULL, "i");
+ addFunction(10.f, 0.f, dummy_func, "llSetVehicleFloatParam", NULL, "if");
+ addFunction(10.f, 0.f, dummy_func, "llSetVehicleVectorParam", NULL, "iv");
+ addFunction(10.f, 0.f, dummy_func, "llSetVehicleRotationParam", NULL, "iq");
+ addFunction(10.f, 0.f, dummy_func, "llSetVehicleFlags", NULL, "i");
+ addFunction(10.f, 0.f, dummy_func, "llRemoveVehicleFlags", NULL, "i");
+ addFunction(10.f, 0.f, dummy_func, "llSitTarget", NULL, "vq");
+ addFunction(10.f, 0.f, dummy_func, "llAvatarOnSitTarget", "k", NULL);
+ addFunction(10.f, 0.1f, dummy_func, "llAddToLandPassList", NULL, "kf");
+ addFunction(10.f, 0.f, dummy_func, "llSetTouchText", NULL, "s");
+ addFunction(10.f, 0.f, dummy_func, "llSetSitText", NULL, "s");
+ addFunction(10.f, 0.f, dummy_func, "llSetCameraEyeOffset", NULL, "v");
+ addFunction(10.f, 0.f, dummy_func, "llSetCameraAtOffset", NULL, "v");
+
+ addFunction(10.f, 0.f, dummy_func, "llDumpList2String", "s", "ls");
+ addFunction(10.f, 0.f, dummy_func, "llScriptDanger", "i", "v");
+ addFunction(10.f, 1.f, dummy_func, "llDialog", NULL, "ksli");
+ addFunction(10.f, 0.f, dummy_func, "llVolumeDetect", NULL, "i");
+ addFunction(10.f, 0.f, dummy_func, "llResetOtherScript", NULL, "s");
+ addFunction(10.f, 0.f, dummy_func, "llGetScriptState", "i", "s");
+ addFunction(10.f, 3.f, dummy_func, "llRemoteLoadScript", NULL, "ksii");
+
+ addFunction(10.f, 0.2f, dummy_func, "llSetRemoteScriptAccessPin", NULL, "i");
+ addFunction(10.f, 3.f, dummy_func, "llRemoteLoadScriptPin", NULL, "ksiii");
- addFunction(new LLScriptLibraryFunction(10.f, 1.f, dummy_func, "llOpenRemoteDataChannel", NULL, NULL, "llOpenRemoteDataChannel()\nCreates a channel to listen for XML-RPC calls. Will trigger a remote_data event with channel id once it is available."));
- addFunction(new LLScriptLibraryFunction(10.f, 3.f, dummy_func, "llSendRemoteData", "k", "ksis", "key llSendRemoteData(key channel, string dest, integer idata, string sdata)\nSend an XML-RPC request to dest through channel with payload of channel (in a string), integer idata and string sdata.\nA message identifier key is returned.\nAn XML-RPC reply will trigger a remote_data event and reference the message id.\nThe message_id is returned."));
- addFunction(new LLScriptLibraryFunction(10.f, 3.f, dummy_func, "llRemoteDataReply", NULL, "kksi", "llRemoteDataReply(key channel, key message_id, string sdata, integer idata)\nSend an XML-RPC reply to message_id on channel with payload of string sdata and integer idata"));
- addFunction(new LLScriptLibraryFunction(10.f, 1.f, dummy_func, "llCloseRemoteDataChannel", NULL, "k", "llCloseRemoteDataChannel(key channel)\nCloses XML-RPC channel."));
-
- addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llMD5String", "s", "si", "string llMD5String(string src, integer nonce)\nPerforms a RSA Data Security, Inc. MD5 Message-Digest Algorithm on string with nonce. Returns a 32 character hex string."));
- addFunction(new LLScriptLibraryFunction(10.f, 0.2f, dummy_func, "llSetPrimitiveParams", NULL, "l", "llSetPrimitiveParams(list rules)\nSet primitive parameters based on rules."));
- addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llStringToBase64", "s", "s", "string llStringToBase64(string str)\nConverts a string to the Base 64 representation of the string."));
- addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llBase64ToString", "s", "s", "string llBase64ToString(string str)\nConverts a Base 64 string to a conventional string. If the conversion creates any unprintable characters, they are converted to spaces."));
- addFunction(new LLScriptLibraryFunction(10.f, 0.3f, dummy_func, "llXorBase64Strings", "s", "ss", "string llXorBase64Strings(string s1, string s2)\nDEPRECATED! Please use llXorBase64StringsCorrect instead!! Incorrectly performs an exclusive or on two Base 64 strings and returns a Base 64 string. s2 repeats if it is shorter than s1. Retained for backwards compatability."));
- addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llRemoteDataSetRegion", NULL, NULL, "llRemoteDataSetRegion()\nIf an object using remote data channels changes regions, you must call this function to reregister the remote data channels.\nYou do not need to make this call if you don't change regions."));
- addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llLog10", "f", "f", "float llLog10(float val)\nReturns the base 10 log of val if val > 0, otherwise returns 0."));
- addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llLog", "f", "f", "float llLog(float val)\nReturns the base e log of val if val > 0, otherwise returns 0."));
- addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llGetAnimationList", "l", "k", "list llGetAnimationList(key id)\nGets a list of all playing animations for avatar id"));
- addFunction(new LLScriptLibraryFunction(10.f, 2.f, dummy_func, "llSetParcelMusicURL", NULL, "s", "llSetParcelMusicURL(string url)\nSets the streaming audio URL for the parcel object is on"));
+ addFunction(10.f, 1.f, dummy_func, "llOpenRemoteDataChannel", NULL, NULL);
+ addFunction(10.f, 3.f, dummy_func, "llSendRemoteData", "k", "ksis");
+ addFunction(10.f, 3.f, dummy_func, "llRemoteDataReply", NULL, "kksi");
+ addFunction(10.f, 1.f, dummy_func, "llCloseRemoteDataChannel", NULL, "k");
+
+ addFunction(10.f, 0.f, dummy_func, "llMD5String", "s", "si");
+ addFunction(10.f, 0.2f, dummy_func, "llSetPrimitiveParams", NULL, "l");
+ addFunction(10.f, 0.f, dummy_func, "llStringToBase64", "s", "s");
+ addFunction(10.f, 0.f, dummy_func, "llBase64ToString", "s", "s");
+ addFunction(10.f, 0.3f, dummy_func, "llXorBase64Strings", "s", "ss");
+ addFunction(10.f, 0.f, dummy_func, "llRemoteDataSetRegion", NULL, NULL);
+ addFunction(10.f, 0.f, dummy_func, "llLog10", "f", "f");
+ addFunction(10.f, 0.f, dummy_func, "llLog", "f", "f");
+ addFunction(10.f, 0.f, dummy_func, "llGetAnimationList", "l", "k");
+ addFunction(10.f, 2.f, dummy_func, "llSetParcelMusicURL", NULL, "s");
- addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llGetRootPosition", "v", NULL, "vector llGetRootPosition()\nGets the global position of the root object of the object script is attached to"));
- addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llGetRootRotation", "q", NULL, "rotation llGetRootRotation()\nGets the global rotation of the root object of the object script is attached to"));
-
- addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llGetObjectDesc", "s", NULL, "string llGetObjectDesc()\nReturns the description of the object the script is attached to"));
- addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llSetObjectDesc", NULL, "s", "llSetObjectDesc(string name)\nSets the object's description"));
- addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llGetCreator", "k", NULL, "key llGetCreator()\nReturns the creator of the object"));
- addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llGetTimestamp", "s", NULL, "string llGetTimestamp()\nGets the timestamp in the format: YYYY-MM-DDThh:mm:ss.ff..fZ"));
- addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llSetLinkAlpha", NULL, "ifi", "llSetLinkAlpha(integer linknumber, float alpha, integer face)\nIf a prim exists in the link chain at linknumber, set face to alpha"));
- addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llGetNumberOfPrims", "i", NULL, "integer llGetNumberOfPrims()\nReturns the number of prims in a link set the script is attached to"));
- addFunction(new LLScriptLibraryFunction(10.f, 0.1f, dummy_func, "llGetNumberOfNotecardLines", "k", "s", "key llGetNumberOfNotecardLines(string name)\nReturns number of lines in notecard 'name' via the dataserver event (cast return value to integer)"));
-
- addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llGetBoundingBox", "l", "k", "list llGetBoundingBox(key object)\nReturns the bounding box around an object (including any linked prims) relative to the root prim, in a list: [ (vector) min_corner, (vector) max_corner ]"));
- addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llGetGeometricCenter", "v", NULL, "vector llGetGeometricCenter()\nReturns the geometric center of the linked set the script is attached to."));
- addFunction(new LLScriptLibraryFunction(10.f, 0.2f, dummy_func, "llGetPrimitiveParams", "l", "l", "list llGetPrimitiveParams(list params)\nGets primitive parameters specified in the params list."));
- addFunction(new LLScriptLibraryFunction(10.f, 0.0f, dummy_func, "llIntegerToBase64", "s", "i", "string llIntegerToBase64(integer number)\nBig endian encode of of integer as a Base64 string."));
- addFunction(new LLScriptLibraryFunction(10.f, 0.0f, dummy_func, "llBase64ToInteger", "i", "s", "integer llBase64ToInteger(string str)\nBig endian decode of a Base64 string into an integer."));
- addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llGetGMTclock", "f", "", "float llGetGMTclock()\nGets the time in seconds since midnight in GMT"));
- addFunction(new LLScriptLibraryFunction(10.f, 10.f, dummy_func, "llGetSimulatorHostname", "s", "", "string llGetSimulatorHostname()\nGets the hostname of the machine script is running on (same as string in viewer Help dialog)"));
+ addFunction(10.f, 0.f, dummy_func, "llGetRootPosition", "v", NULL);
+ addFunction(10.f, 0.f, dummy_func, "llGetRootRotation", "q", NULL);
+
+ addFunction(10.f, 0.f, dummy_func, "llGetObjectDesc", "s", NULL);
+ addFunction(10.f, 0.f, dummy_func, "llSetObjectDesc", NULL, "s");
+ addFunction(10.f, 0.f, dummy_func, "llGetCreator", "k", NULL);
+ addFunction(10.f, 0.f, dummy_func, "llGetTimestamp", "s", NULL);
+ addFunction(10.f, 0.f, dummy_func, "llSetLinkAlpha", NULL, "ifi");
+ addFunction(10.f, 0.f, dummy_func, "llGetNumberOfPrims", "i", NULL);
+ addFunction(10.f, 0.1f, dummy_func, "llGetNumberOfNotecardLines", "k", "s");
+
+ addFunction(10.f, 0.f, dummy_func, "llGetBoundingBox", "l", "k");
+ addFunction(10.f, 0.f, dummy_func, "llGetGeometricCenter", "v", NULL);
+ addFunction(10.f, 0.2f, dummy_func, "llGetPrimitiveParams", "l", "l");
+ addFunction(10.f, 0.0f, dummy_func, "llIntegerToBase64", "s", "i");
+ addFunction(10.f, 0.0f, dummy_func, "llBase64ToInteger", "i", "s");
+ addFunction(10.f, 0.f, dummy_func, "llGetGMTclock", "f", "");
+ addFunction(10.f, 10.f, dummy_func, "llGetSimulatorHostname", "s", "");
- addFunction(new LLScriptLibraryFunction(10.f, 0.2f, dummy_func, "llSetLocalRot", NULL, "q", "llSetLocalRot(rotation rot)\nsets the rotation of a child prim relative to the root prim"));
+ addFunction(10.f, 0.2f, dummy_func, "llSetLocalRot", NULL, "q");
- addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llParseStringKeepNulls", "l", "sll", "list llParseStringKeepNulls(string src, list separators, list spacers)\nBreaks src into a list, discarding separators, keeping spacers (separators and spacers must be lists of strings, maximum of 8 each), keeping any null values generated."));
- addFunction(new LLScriptLibraryFunction(200.f, 0.1f, dummy_func, "llRezAtRoot", NULL, "svvqi", "llRezAtRoot(string inventory, vector pos, vector vel, rotation rot, integer param)\nInstantiate owner's inventory object at pos with velocity vel and rotation rot with start parameter param.\nThe last selected root object's location will be set to pos"));
+ addFunction(10.f, 0.f, dummy_func, "llParseStringKeepNulls", "l", "sll");
+ addFunction(200.f, 0.1f, dummy_func, "llRezAtRoot", NULL, "svvqi");
- addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llGetObjectPermMask", "i", "i", "integer llGetObjectPermMask(integer mask)\nReturns the requested permission mask for the root object the task is attached to.", FALSE));
- addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llSetObjectPermMask", NULL, "ii", "llSetObjectPermMask(integer mask, integer value)\nSets the given permission mask to the new value on the root object the task is attached to.", TRUE));
+ addFunction(10.f, 0.f, dummy_func, "llGetObjectPermMask", "i", "i", FALSE);
+ addFunction(10.f, 0.f, dummy_func, "llSetObjectPermMask", NULL, "ii", TRUE);
- addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llGetInventoryPermMask", "i", "si", "integer llGetInventoryPermMask(string item, integer mask)\nReturns the requested permission mask for the inventory item.", FALSE));
- addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llSetInventoryPermMask", NULL, "sii", "llSetInventoryPermMask(string item, integer mask, integer value)\nSets the given permission mask to the new value on the inventory item.", TRUE));
- addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llGetInventoryCreator", "k", "s", "key llGetInventoryCreator(string item)\nReturns the key for the creator of the inventory item.", FALSE));
- addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llOwnerSay", NULL, "s", "llOwnerSay(string msg)\nsays msg to owner only (if owner in sim)"));
- addFunction(new LLScriptLibraryFunction(10.f, 1.f, dummy_func, "llRequestSimulatorData", "k", "si", "key llRequestSimulatorData(string simulator, integer data)\nRequests data about simulator. When data is available the dataserver event will be raised"));
- addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llForceMouselook", NULL, "i", "llForceMouselook(integer mouselook)\nIf mouselook is TRUE any avatar that sits on this object is forced into mouselook mode"));
- addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llGetObjectMass", "f", "k", "float llGetObjectMass(key id)\nGet the mass of the object with key id"));
- addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llListReplaceList", "l", "llii", "list llListReplaceList(list dest, list src, integer start, integer end)\nReplaces start through end of dest with src."));
- addFunction(new LLScriptLibraryFunction(10.f, 10.f, dummy_func, "llLoadURL", NULL, "kss", "llLoadURL(key avatar_id, string message, string url)\nShows dialog to avatar avatar_id offering to load web page at URL. If user clicks yes, launches their web browser."));
+ addFunction(10.f, 0.f, dummy_func, "llGetInventoryPermMask", "i", "si", FALSE);
+ addFunction(10.f, 0.f, dummy_func, "llSetInventoryPermMask", NULL, "sii", TRUE);
+ addFunction(10.f, 0.f, dummy_func, "llGetInventoryCreator", "k", "s", FALSE);
+ addFunction(10.f, 0.f, dummy_func, "llOwnerSay", NULL, "s");
+ addFunction(10.f, 1.f, dummy_func, "llRequestSimulatorData", "k", "si");
+ addFunction(10.f, 0.f, dummy_func, "llForceMouselook", NULL, "i");
+ addFunction(10.f, 0.f, dummy_func, "llGetObjectMass", "f", "k");
+ addFunction(10.f, 0.f, dummy_func, "llListReplaceList", "l", "llii");
+ addFunction(10.f, 10.f, dummy_func, "llLoadURL", NULL, "kss");
- addFunction(new LLScriptLibraryFunction(10.f, 2.f, dummy_func, "llParcelMediaCommandList", NULL, "l", "llParcelMediaCommandList(list command)\nSends a list of commands, some with arguments, to a parcel."));
- addFunction(new LLScriptLibraryFunction(10.f, 2.f, dummy_func, "llParcelMediaQuery", "l", "l", "list llParcelMediaQuery(list query)\nSends a list of queries, returns a list of results."));
+ addFunction(10.f, 2.f, dummy_func, "llParcelMediaCommandList", NULL, "l");
+ addFunction(10.f, 2.f, dummy_func, "llParcelMediaQuery", "l", "l");
- addFunction(new LLScriptLibraryFunction(10.f, 1.f, dummy_func, "llModPow", "i", "iii", "integer llModPow(integer a, integer b, integer c)\nReturns a raised to the b power, mod c. ( (a**b)%c ). b is capped at 0xFFFF (16 bits)."));
+ addFunction(10.f, 1.f, dummy_func, "llModPow", "i", "iii");
- addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llGetInventoryType", "i", "s", "integer llGetInventoryType(string name)\nReturns the type of the inventory name"));
- addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llSetPayPrice", NULL, "il", "llSetPayPrice(integer price, list quick_pay_buttons)\nSets the default amount when someone chooses to pay this object."));
- addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llGetCameraPos", "v", "", "vector llGetCameraPos()\nGets current camera position for agent task has permissions for."));
- addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llGetCameraRot", "q", "", "rotation llGetCameraRot()\nGets current camera orientation for agent task has permissions for."));
+ addFunction(10.f, 0.f, dummy_func, "llGetInventoryType", "i", "s");
+ addFunction(10.f, 0.f, dummy_func, "llSetPayPrice", NULL, "il");
+ addFunction(10.f, 0.f, dummy_func, "llGetCameraPos", "v", "");
+ addFunction(10.f, 0.f, dummy_func, "llGetCameraRot", "q", "");
- addFunction(new LLScriptLibraryFunction(10.f, 20.f, dummy_func, "llSetPrimURL", NULL, "s", "llSetPrimURL(string url)\nUpdates the URL for the web page shown on the sides of the object."));
- addFunction(new LLScriptLibraryFunction(10.f, 20.f, dummy_func, "llRefreshPrimURL", NULL, "", "llRefreshPrimURL()\nReloads the web page shown on the sides of the object."));
- addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llEscapeURL", "s", "s", "string llEscapeURL(string url)\nReturns and escaped/encoded version of url, replacing spaces with %20 etc."));
- addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llUnescapeURL", "s", "s", "string llUnescapeURL(string url)\nReturns and unescaped/unencoded version of url, replacing %20 with spaces etc."));
-
- addFunction(new LLScriptLibraryFunction(10.f, 1.f, dummy_func, "llMapDestination", NULL, "svv", "llMapDestination(string simname, vector pos, vector look_at)\nOpens world map centered on region with pos highlighted.\nOnly works for scripts attached to avatar, or during touch events.\n(NOTE: look_at currently does nothing)"));
- addFunction(new LLScriptLibraryFunction(10.f, 0.1f, dummy_func, "llAddToLandBanList", NULL, "kf", "llAddToLandBanList(key avatar, float hours)\nAdd avatar to the land ban list for hours"));
- addFunction(new LLScriptLibraryFunction(10.f, 0.1f, dummy_func, "llRemoveFromLandPassList", NULL, "k", "llRemoveFromLandPassList(key avatar)\nRemove avatar from the land pass list"));
- addFunction(new LLScriptLibraryFunction(10.f, 0.1f, dummy_func, "llRemoveFromLandBanList", NULL, "k", "llRemoveFromLandBanList(key avatar)\nRemove avatar from the land ban list"));
-
- addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llSetCameraParams", NULL, "l", "llSetCameraParams(list rules)\nSets multiple camera parameters at once.\nList format is [ rule1, data1, rule2, data2 . . . rulen, datan ]"));
- addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llClearCameraParams", NULL, NULL, "llClearCameraParams()\nResets all camera parameters to default values and turns off scripted camera control."));
+ addFunction(10.f, 20.f, dummy_func, "llSetPrimURL", NULL, "s");
+ addFunction(10.f, 20.f, dummy_func, "llRefreshPrimURL", NULL, "");
+ addFunction(10.f, 0.f, dummy_func, "llEscapeURL", "s", "s");
+ addFunction(10.f, 0.f, dummy_func, "llUnescapeURL", "s", "s");
+
+ addFunction(10.f, 1.f, dummy_func, "llMapDestination", NULL, "svv");
+ addFunction(10.f, 0.1f, dummy_func, "llAddToLandBanList", NULL, "kf");
+ addFunction(10.f, 0.1f, dummy_func, "llRemoveFromLandPassList", NULL, "k");
+ addFunction(10.f, 0.1f, dummy_func, "llRemoveFromLandBanList", NULL, "k");
+
+ addFunction(10.f, 0.f, dummy_func, "llSetCameraParams", NULL, "l");
+ addFunction(10.f, 0.f, dummy_func, "llClearCameraParams", NULL, NULL);
- addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llListStatistics", "f", "il", "float llListStatistics(integer operation, list l)\nPerform statistical aggregate functions on list l using LIST_STAT_* operations."));
- addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llGetUnixTime", "i", NULL, "integer llGetUnixTime()\nGet the number of seconds elapsed since 00:00 hours, Jan 1, 1970 UTC from the system clock."));
- addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llGetParcelFlags", "i", "v", "integer llGetParcelFlags(vector pos)\nGet the parcel flags (PARCEL_FLAG_*) for the parcel including the point pos."));
- addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llGetRegionFlags", "i", NULL, "integer llGetRegionFlags()\nGet the region flags (REGION_FLAG_*) for the region the object is in."));
- addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llXorBase64StringsCorrect", "s", "ss", "string llXorBase64StringsCorrect(string s1, string s2)\nCorrectly performs an exclusive or on two Base 64 strings and returns a Base 64 string. s2 repeats if it is shorter than s1."));
+ addFunction(10.f, 0.f, dummy_func, "llListStatistics", "f", "il");
+ addFunction(10.f, 0.f, dummy_func, "llGetUnixTime", "i", NULL);
+ addFunction(10.f, 0.f, dummy_func, "llGetParcelFlags", "i", "v");
+ addFunction(10.f, 0.f, dummy_func, "llGetRegionFlags", "i", NULL);
+ addFunction(10.f, 0.f, dummy_func, "llXorBase64StringsCorrect", "s", "ss");
- addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llHTTPRequest", "k", "sls", "llHTTPRequest(string url, list parameters, string body)\nSend an HTTP request."));
+ addFunction(10.f, 0.f, dummy_func, "llHTTPRequest", "k", "sls");
- addFunction(new LLScriptLibraryFunction(10.f, 0.1f, dummy_func, "llResetLandBanList", NULL, NULL, "llResetLandBanList()\nRemoves all residents from the land ban list."));
- addFunction(new LLScriptLibraryFunction(10.f, 0.1f, dummy_func, "llResetLandPassList", NULL, NULL, "llResetLandPassList()\nRemoves all residents from the land access/pass list."));
+ addFunction(10.f, 0.1f, dummy_func, "llResetLandBanList", NULL, NULL);
+ addFunction(10.f, 0.1f, dummy_func, "llResetLandPassList", NULL, NULL);
- addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llGetObjectPrimCount", "i", "k", "integer llGetObjectPrimCount(key object_id)\nReturns the total number of prims for an object."));
- addFunction(new LLScriptLibraryFunction(10.f, 2.0f, dummy_func, "llGetParcelPrimOwners", "l", "v", "list llGetParcelPrimOwners(vector pos)\nReturns a list of all residents who own objects on the parcel and the number of objects they own.\nRequires owner-like permissions for the parcel."));
- addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llGetParcelPrimCount", "i", "vii","integer llGetParcelPrimCount(vector pos, integer category, integer sim_wide)\nGets the number of prims on the parcel of the given category.\nCategories: PARCEL_COUNT_TOTAL, _OWNER, _GROUP, _OTHER, _SELECTED, _TEMP."));
- addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llGetParcelMaxPrims", "i", "vi","integer llGetParcelMaxPrims(vector pos, integer sim_wide)\nGets the maximum number of prims allowed on the parcel at pos."));
- addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llGetParcelDetails", "l", "vl","list llGetParcelDetails(vector pos, list params)\nGets the parcel details specified in params for the parcel at pos.\nParams is one or more of: PARCEL_DETAILS_NAME, _DESC, _OWNER, _GROUP, _AREA"));
+ addFunction(10.f, 0.f, dummy_func, "llGetObjectPrimCount", "i", "k");
+ addFunction(10.f, 2.0f, dummy_func, "llGetParcelPrimOwners", "l", "v");
+ addFunction(10.f, 0.f, dummy_func, "llGetParcelPrimCount", "i", "vii");
+ addFunction(10.f, 0.f, dummy_func, "llGetParcelMaxPrims", "i", "vi");
+ addFunction(10.f, 0.f, dummy_func, "llGetParcelDetails", "l", "vl");
- addFunction(new LLScriptLibraryFunction(10.f, 0.2f, dummy_func, "llSetLinkPrimitiveParams", NULL, "il", "llSetLinkPrimitiveParams(integer linknumber, list rules)\nSet primitive parameters for linknumber based on rules."));
- addFunction(new LLScriptLibraryFunction(10.f, 0.2f, dummy_func, "llSetLinkTexture", NULL, "isi", "llSetLinkTexture(integer link_pos, string texture, integer face)\nSets the texture of face for link_pos"));
+ addFunction(10.f, 0.2f, dummy_func, "llSetLinkPrimitiveParams", NULL, "il");
+ addFunction(10.f, 0.2f, dummy_func, "llSetLinkTexture", NULL, "isi");
- addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llStringTrim", "s", "si", "string llStringTrim(string src, integer trim_type)\nTrim leading and/or trailing spaces from a string.\nUses trim_type of STRING_TRIM, STRING_TRIM_HEAD or STRING_TRIM_TAIL."));
- addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llRegionSay", NULL, "is", "llRegionSay(integer channel, string msg)\nbroadcasts msg to entire region on channel (not 0.)"));
- addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llGetObjectDetails", "l", "kl", "list llGetObjectDetails(key id, list params)\nGets the object details specified in params for the object with key id.\nDetails are OBJECT_NAME, _DESC, _POS, _ROT, _VELOCITY, _OWNER, _GROUP, _CREATOR."));
- addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llSetClickAction", NULL, "i", "llSetClickAction(integer action)\nSets the action performed when a prim is clicked upon."));
-
- addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llGetRegionAgentCount", "i", NULL, "int llGetRegionAgentCount()\nreturns the number of agents in a region"));
- addFunction(new LLScriptLibraryFunction(10.f, 1.f, dummy_func, "llTextBox", NULL, "ksi", "llTextBox(key avatar, string message, integer chat_channel\nShows a dialog box on the avatar's screen with the message.\nA text box asks for input, and if entered the text is chatted on chat_channel."));
- addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llGetAgentLanguage", "s", "k", "string llGetAgentLanguage(key id)\nGets the agents preferred language.."));
- addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llDetectedTouchUV", "v", "i", "vector llDetectedTouchUV(integer number)\nreturns the u and v coordinates in the first two components of a vector, for a triggered touch event"));
- addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llDetectedTouchFace", "i", "i", "integer llDetectedTouchFace(integer number)\nreturns the index of the face on the object for a triggered touch event"));
- addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llDetectedTouchPos", "v", "i", "vector llDetectedTouchPos(integer number)\nreturns the position touched for a triggered touch event"));
- addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llDetectedTouchNormal", "v", "i", "vector llDetectedTouchNormal(integer number)\nreturns the surface normal for a triggered touch event"));
- addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llDetectedTouchBinormal", "v", "i", "vector llDetectedTouchBinormal(integer number)\nreturns the surface binormal for a triggered touch event"));
- addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llDetectedTouchST", "v", "i", "vector llDetectedTouchST(integer number)\nreturns the s and t coordinates in the first two components of a vector, for a triggered touch event"));
-
- addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llSHA1String", "s", "s", "string llSHA1String(string sr)\nPerforms a SHA1 security Hash. Returns a 40 character hex string."));
-
- addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llGetFreeURLs", "i", NULL, "integer llGetFreeURLs()\nreturns the available urls for the current script"));
- addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llRequestURL", "k", NULL, "key llRequestURL()\nRequests one HTTP:// url for use by this object\nTriggers an http_server event with results."));
- addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llRequestSecureURL", "k", NULL, "key llRequestSecureURL()\nRequests one HTTPS:// (SSL) url for use by this object\nTriggers an http_server event with results."));
- addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llReleaseURL", NULL, "s", "llReleaseURL(string url)\nReleases the specified URL, it will no longer be usable."));
- addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llHTTPResponse", NULL, "kis", "llHTTPResponse(key id, integer status, string body)\nResponds to request id with status and body."));
- addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llGetHTTPHeader", "s", "ks", "string llGetHTTPHeader(key id, string header)\nGet the value for header for request id."));
-
- // energy, sleep, dummy_func, name, return type, parameters, help text, gods-only
+ addFunction(10.f, 0.f, dummy_func, "llStringTrim", "s", "si");
+ addFunction(10.f, 0.f, dummy_func, "llRegionSay", NULL, "is");
+ addFunction(10.f, 0.f, dummy_func, "llGetObjectDetails", "l", "kl");
+ addFunction(10.f, 0.f, dummy_func, "llSetClickAction", NULL, "i");
+
+ addFunction(10.f, 0.f, dummy_func, "llGetRegionAgentCount", "i", NULL);
+ addFunction(10.f, 1.f, dummy_func, "llTextBox", NULL, "ksi");
+ addFunction(10.f, 0.f, dummy_func, "llGetAgentLanguage", "s", "k");
+ addFunction(10.f, 0.f, dummy_func, "llDetectedTouchUV", "v", "i");
+ addFunction(10.f, 0.f, dummy_func, "llDetectedTouchFace", "i", "i");
+ addFunction(10.f, 0.f, dummy_func, "llDetectedTouchPos", "v", "i");
+ addFunction(10.f, 0.f, dummy_func, "llDetectedTouchNormal", "v", "i");
+ addFunction(10.f, 0.f, dummy_func, "llDetectedTouchBinormal", "v", "i");
+ addFunction(10.f, 0.f, dummy_func, "llDetectedTouchST", "v", "i");
+
+ addFunction(10.f, 0.f, dummy_func, "llSHA1String", "s", "s");
+
+ addFunction(10.f, 0.f, dummy_func, "llGetFreeURLs", "i", NULL);
+ addFunction(10.f, 0.f, dummy_func, "llRequestURL", "k", NULL);
+ addFunction(10.f, 0.f, dummy_func, "llRequestSecureURL", "k", NULL);
+ addFunction(10.f, 0.f, dummy_func, "llReleaseURL", NULL, "s");
+ addFunction(10.f, 0.f, dummy_func, "llHTTPResponse", NULL, "kis");
+ addFunction(10.f, 0.f, dummy_func, "llGetHTTPHeader", "s", "ks");
+
+ // energy, sleep, dummy_func, name, return type, parameters, gods-only
// IF YOU ADD NEW SCRIPT CALLS, YOU MUST PUT THEM AT THE END OF THIS LIST.
// Otherwise the bytecode numbers for each call will be wrong, and all
// existing scripts will crash.
}
-LLScriptLibraryFunction::LLScriptLibraryFunction(F32 eu, F32 st, void (*exec_func)(LLScriptLibData *, LLScriptLibData *, const LLUUID &), const char *name, const char *ret_type, const char *args, const char *desc, BOOL god_only)
+LLScriptLibraryFunction::LLScriptLibraryFunction(F32 eu, F32 st, void (*exec_func)(LLScriptLibData *, LLScriptLibData *, const LLUUID &), const char *name, const char *ret_type, const char *args, BOOL god_only)
: mEnergyUse(eu), mSleepTime(st), mExecFunc(exec_func), mName(name), mReturnType(ret_type), mArgs(args), mGodOnly(god_only)
{
- char *mDesc_ = new char[512];
- if (mSleepTime)
- {
- snprintf( /* Flawfinder: ignore */
- mDesc_,
- 512,
- "%s\nSleeps script for %.1f seconds.",
- desc,
- mSleepTime);
- }
- else
- {
- strncpy(mDesc_, desc, 512); /* Flawfinder: ignore */
- mDesc_[511] = '\0'; // just in case.
- }
- mDesc = mDesc_;
}
LLScriptLibraryFunction::~LLScriptLibraryFunction()
{
- delete [] mDesc;
}
-void LLScriptLibrary::addFunction(LLScriptLibraryFunction *func)
+void LLScriptLibrary::addFunction(F32 eu, F32 st, void (*exec_func)(LLScriptLibData *, LLScriptLibData *, const LLUUID &), const char *name, const char *ret_type, const char *args, BOOL god_only)
{
- LLScriptLibraryFunction **temp = new LLScriptLibraryFunction*[mNextNumber + 1];
- if (mNextNumber)
- {
- memcpy( /* Flawfinder: ignore */
- temp,
- mFunctions,
- sizeof(LLScriptLibraryFunction*)*mNextNumber);
- delete [] mFunctions;
- }
- mFunctions = temp;
- mFunctions[mNextNumber] = func;
- mNextNumber++;
+ LLScriptLibraryFunction func(eu, st, exec_func, name, ret_type, args, god_only);
+ mFunctions.push_back(func);
}
void LLScriptLibrary::assignExec(const char *name, void (*exec_func)(LLScriptLibData *, LLScriptLibData *, const LLUUID &))
{
- S32 i;
- for (i = 0; i < mNextNumber; i++)
+ for (std::vector<LLScriptLibraryFunction>::iterator i = mFunctions.begin();
+ i != mFunctions.end(); ++i)
{
- if (!strcmp(name, mFunctions[i]->mName))
+ if (!strcmp(name, i->mName))
{
- mFunctions[i]->mExecFunc = exec_func;
+ i->mExecFunc = exec_func;
+ return;
}
}
+
+ llerrs << "Unknown LSL function in assignExec: " << name << llendl;
}
void LLScriptLibData::print(std::ostream &s, BOOL b_prepend_comma)
diff --git a/indra/media_plugins/CMakeLists.txt b/indra/media_plugins/CMakeLists.txt
new file mode 100644
index 0000000000..d35afd8cbd
--- /dev/null
+++ b/indra/media_plugins/CMakeLists.txt
@@ -0,0 +1,11 @@
+# -*- cmake -*-
+
+add_subdirectory(base)
+
+add_subdirectory(webkit)
+
+add_subdirectory(gstreamer010)
+
+if (WINDOWS OR DARWIN)
+ add_subdirectory(quicktime)
+endif (WINDOWS OR DARWIN)
diff --git a/indra/media_plugins/base/CMakeLists.txt b/indra/media_plugins/base/CMakeLists.txt
new file mode 100644
index 0000000000..f8d2dabc6c
--- /dev/null
+++ b/indra/media_plugins/base/CMakeLists.txt
@@ -0,0 +1,41 @@
+# -*- cmake -*-
+
+project(media_plugin_base)
+
+include(00-Common)
+include(LLCommon)
+include(LLImage)
+include(LLPlugin)
+include(LLMath)
+include(LLRender)
+include(LLWindow)
+include(Linking)
+include(PluginAPI)
+include(FindOpenGL)
+
+include_directories(
+ ${LLPLUGIN_INCLUDE_DIRS}
+ ${LLCOMMON_INCLUDE_DIRS}
+ ${LLMATH_INCLUDE_DIRS}
+ ${LLIMAGE_INCLUDE_DIRS}
+ ${LLRENDER_INCLUDE_DIRS}
+ ${LLWINDOW_INCLUDE_DIRS}
+)
+
+
+### media_plugin_base
+
+set(media_plugin_base_SOURCE_FILES
+ media_plugin_base.cpp
+)
+
+set(media_plugin_base_HEADER_FILES
+ CMakeLists.txt
+
+ media_plugin_base.h
+)
+
+add_library(media_plugin_base
+ ${media_plugin_base_SOURCE_FILES}
+)
+
diff --git a/indra/media_plugins/base/media_plugin_base.cpp b/indra/media_plugins/base/media_plugin_base.cpp
new file mode 100644
index 0000000000..0b7092fad6
--- /dev/null
+++ b/indra/media_plugins/base/media_plugin_base.cpp
@@ -0,0 +1,154 @@
+/**
+ * @file media_plugin_base.cpp
+ * @brief Media plugin base class for LLMedia API plugin system
+ *
+ * $LicenseInfo:firstyear=2008&license=viewergpl$
+ *
+ * Copyright (c) 2008, Linden Research, Inc.
+ *
+ * Second Life Viewer Source Code
+ * The source code in this file ("Source Code") is provided by Linden Lab
+ * to you under the terms of the GNU General Public License, version 2.0
+ * ("GPL"), unless you have obtained a separate licensing agreement
+ * ("Other License"), formally executed by you and Linden Lab. Terms of
+ * the GPL can be found in doc/GPL-license.txt in this distribution, or
+ * online at http://secondlife.com/developers/opensource/gplv2
+ *
+ * There are special exceptions to the terms and conditions of the GPL as
+ * it is applied to this Source Code. View the full text of the exception
+ * in the file doc/FLOSS-exception.txt in this software distribution, or
+ * online at http://secondlife.com/developers/opensource/flossexception
+ *
+ * By copying, modifying or distributing this software, you acknowledge
+ * that you have read and understood your obligations described above,
+ * and agree to abide by those obligations.
+ *
+ * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+ * COMPLETENESS OR PERFORMANCE.
+ * $/LicenseInfo$
+ */
+
+#include "linden_common.h"
+#include "media_plugin_base.h"
+
+
+// TODO: Make sure that the only symbol exported from this library is LLPluginInitEntryPoint
+////////////////////////////////////////////////////////////////////////////////
+//
+
+MediaPluginBase::MediaPluginBase(
+ LLPluginInstance::sendMessageFunction host_send_func,
+ void *host_user_data )
+{
+ mHostSendFunction = host_send_func;
+ mHostUserData = host_user_data;
+ mDeleteMe = false;
+ mPixels = 0;
+ mWidth = 0;
+ mHeight = 0;
+ mTextureWidth = 0;
+ mTextureHeight = 0;
+ mDepth = 0;
+ mStatus = STATUS_NONE;
+}
+
+std::string MediaPluginBase::statusString()
+{
+ std::string result;
+
+ switch(mStatus)
+ {
+ case STATUS_LOADING: result = "loading"; break;
+ case STATUS_LOADED: result = "loaded"; break;
+ case STATUS_ERROR: result = "error"; break;
+ case STATUS_PLAYING: result = "playing"; break;
+ case STATUS_PAUSED: result = "paused"; break;
+ default:
+ // keep the empty string
+ break;
+ }
+
+ return result;
+}
+
+void MediaPluginBase::setStatus(EStatus status)
+{
+ if(mStatus != status)
+ {
+ mStatus = status;
+ sendStatus();
+ }
+}
+
+
+void MediaPluginBase::staticReceiveMessage(const char *message_string, void **user_data)
+{
+ MediaPluginBase *self = (MediaPluginBase*)*user_data;
+
+ if(self != NULL)
+ {
+ self->receiveMessage(message_string);
+
+ // If the plugin has processed the delete message, delete it.
+ if(self->mDeleteMe)
+ {
+ delete self;
+ *user_data = NULL;
+ }
+ }
+}
+
+void MediaPluginBase::sendMessage(const LLPluginMessage &message)
+{
+ std::string output = message.generate();
+ mHostSendFunction(output.c_str(), &mHostUserData);
+}
+
+void MediaPluginBase::setDirty(int left, int top, int right, int bottom)
+{
+ LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "updated");
+
+ message.setValueS32("left", left);
+ message.setValueS32("top", top);
+ message.setValueS32("right", right);
+ message.setValueS32("bottom", bottom);
+
+ sendMessage(message);
+}
+
+void MediaPluginBase::sendStatus()
+{
+ LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "media_status");
+
+ message.setValue("status", statusString());
+
+ sendMessage(message);
+}
+
+
+#if LL_WINDOWS
+# define LLSYMEXPORT __declspec(dllexport)
+#elif LL_LINUX
+# define LLSYMEXPORT __attribute__ ((visibility("default")))
+#else
+# define LLSYMEXPORT /**/
+#endif
+
+extern "C"
+{
+ LLSYMEXPORT int LLPluginInitEntryPoint(LLPluginInstance::sendMessageFunction host_send_func, void *host_user_data, LLPluginInstance::sendMessageFunction *plugin_send_func, void **plugin_user_data);
+}
+
+LLSYMEXPORT int
+LLPluginInitEntryPoint(LLPluginInstance::sendMessageFunction host_send_func, void *host_user_data, LLPluginInstance::sendMessageFunction *plugin_send_func, void **plugin_user_data)
+{
+ return init_media_plugin(host_send_func, host_user_data, plugin_send_func, plugin_user_data);
+}
+
+#ifdef WIN32
+int WINAPI DllEntryPoint( HINSTANCE hInstance, unsigned long reason, void* params )
+{
+ return 1;
+}
+#endif
diff --git a/indra/media_plugins/base/media_plugin_base.exp b/indra/media_plugins/base/media_plugin_base.exp
new file mode 100644
index 0000000000..d7a945a1c5
--- /dev/null
+++ b/indra/media_plugins/base/media_plugin_base.exp
@@ -0,0 +1 @@
+_LLPluginInitEntryPoint \ No newline at end of file
diff --git a/indra/media_plugins/base/media_plugin_base.h b/indra/media_plugins/base/media_plugin_base.h
new file mode 100644
index 0000000000..8f600cb8d6
--- /dev/null
+++ b/indra/media_plugins/base/media_plugin_base.h
@@ -0,0 +1,111 @@
+/**
+ * @file media_plugin_base.h
+ * @brief Media plugin base class for LLMedia API plugin system
+ *
+ * $LicenseInfo:firstyear=2008&license=viewergpl$
+ *
+ * Copyright (c) 2008, Linden Research, Inc.
+ *
+ * Second Life Viewer Source Code
+ * The source code in this file ("Source Code") is provided by Linden Lab
+ * to you under the terms of the GNU General Public License, version 2.0
+ * ("GPL"), unless you have obtained a separate licensing agreement
+ * ("Other License"), formally executed by you and Linden Lab. Terms of
+ * the GPL can be found in doc/GPL-license.txt in this distribution, or
+ * online at http://secondlife.com/developers/opensource/gplv2
+ *
+ * There are special exceptions to the terms and conditions of the GPL as
+ * it is applied to this Source Code. View the full text of the exception
+ * in the file doc/FLOSS-exception.txt in this software distribution, or
+ * online at http://secondlife.com/developers/opensource/flossexception
+ *
+ * By copying, modifying or distributing this software, you acknowledge
+ * that you have read and understood your obligations described above,
+ * and agree to abide by those obligations.
+ *
+ * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+ * COMPLETENESS OR PERFORMANCE.
+ * $/LicenseInfo$
+ */
+
+#include "linden_common.h"
+
+#include "llplugininstance.h"
+#include "llpluginmessage.h"
+#include "llpluginmessageclasses.h"
+
+
+class MediaPluginBase
+{
+public:
+ MediaPluginBase(LLPluginInstance::sendMessageFunction host_send_func, void *host_user_data);
+ virtual ~MediaPluginBase() {}
+
+ virtual void receiveMessage(const char *message_string) = 0;
+
+ static void staticReceiveMessage(const char *message_string, void **user_data);
+
+protected:
+
+ typedef enum
+ {
+ STATUS_NONE,
+ STATUS_LOADING,
+ STATUS_LOADED,
+ STATUS_ERROR,
+ STATUS_PLAYING,
+ STATUS_PAUSED,
+ } EStatus;
+
+ class SharedSegmentInfo
+ {
+ public:
+ void *mAddress;
+ size_t mSize;
+ };
+
+ void sendMessage(const LLPluginMessage &message);
+ void sendStatus();
+ std::string statusString();
+ void setStatus(EStatus status);
+
+ // The quicktime plugin overrides this to add current time and duration to the message...
+ virtual void setDirty(int left, int top, int right, int bottom);
+
+ typedef std::map<std::string, SharedSegmentInfo> SharedSegmentMap;
+
+
+ LLPluginInstance::sendMessageFunction mHostSendFunction;
+ void *mHostUserData;
+ bool mDeleteMe;
+ unsigned char* mPixels;
+ std::string mTextureSegmentName;
+ int mWidth;
+ int mHeight;
+ int mTextureWidth;
+ int mTextureHeight;
+ int mDepth;
+ EStatus mStatus;
+ SharedSegmentMap mSharedSegments;
+
+};
+
+// The plugin must define this function to create its instance.
+int init_media_plugin(
+ LLPluginInstance::sendMessageFunction host_send_func,
+ void *host_user_data,
+ LLPluginInstance::sendMessageFunction *plugin_send_func,
+ void **plugin_user_data);
+
+// It should look something like this:
+/*
+{
+ MediaPluginFoo *self = new MediaPluginFoo(host_send_func, host_user_data);
+ *plugin_send_func = MediaPluginFoo::staticReceiveMessage;
+ *plugin_user_data = (void*)self;
+
+ return 0;
+}
+*/
+
diff --git a/indra/media_plugins/gstreamer010/CMakeLists.txt b/indra/media_plugins/gstreamer010/CMakeLists.txt
new file mode 100644
index 0000000000..5c0ce3ee17
--- /dev/null
+++ b/indra/media_plugins/gstreamer010/CMakeLists.txt
@@ -0,0 +1,71 @@
+# -*- cmake -*-
+
+project(media_plugin_gstreamer010)
+
+include(00-Common)
+include(LLCommon)
+include(LLImage)
+include(LLPlugin)
+include(LLMath)
+include(LLRender)
+include(LLWindow)
+include(Linking)
+include(PluginAPI)
+include(MediaPluginBase)
+include(FindOpenGL)
+
+include(GStreamer010Plugin)
+
+include_directories(
+ ${LLPLUGIN_INCLUDE_DIRS}
+ ${MEDIA_PLUGIN_BASE_INCLUDE_DIRS}
+ ${LLCOMMON_INCLUDE_DIRS}
+ ${LLMATH_INCLUDE_DIRS}
+ ${LLIMAGE_INCLUDE_DIRS}
+ ${LLRENDER_INCLUDE_DIRS}
+ ${LLWINDOW_INCLUDE_DIRS}
+ ${GSTREAMER010_INCLUDE_DIRS}
+ ${GSTREAMER010_PLUGINS_BASE_INCLUDE_DIRS}
+)
+
+### media_plugin_gstreamer010
+
+set(media_plugin_gstreamer010_SOURCE_FILES
+ media_plugin_gstreamer010.cpp
+ llmediaimplgstreamer_syms.cpp
+ llmediaimplgstreamervidplug.cpp
+ )
+
+set(media_plugin_gstreamer010_HEADER_FILES
+ llmediaimplgstreamervidplug.h
+ llmediaimplgstreamer_syms.h
+ llmediaimplgstreamertriviallogging.h
+ )
+
+if (${CXX_VERSION} MATCHES "4.[23]")
+ # Work around a bad interaction between broken gstreamer headers and
+ # g++ 4.3's increased strictness.
+ set_source_files_properties(llmediaimplgstreamervidplug.cpp PROPERTIES
+ COMPILE_FLAGS -Wno-error=write-strings)
+endif (${CXX_VERSION} MATCHES "4.[23]")
+
+add_library(media_plugin_gstreamer010
+ SHARED
+ ${media_plugin_gstreamer010_SOURCE_FILES}
+)
+
+target_link_libraries(media_plugin_gstreamer010
+ ${LLPLUGIN_LIBRARIES}
+ ${MEDIA_PLUGIN_BASE_LIBRARIES}
+ ${LLCOMMON_LIBRARIES}
+ ${PLUGIN_API_WINDOWS_LIBRARIES}
+ ${GSTREAMER010_LIBRARIES}
+)
+
+add_dependencies(media_plugin_gstreamer010
+ ${LLPLUGIN_LIBRARIES}
+ ${MEDIA_PLUGIN_BASE_LIBRARIES}
+ ${LLCOMMON_LIBRARIES}
+)
+
+
diff --git a/indra/media_plugins/gstreamer010/llmediaimplgstreamer.h b/indra/media_plugins/gstreamer010/llmediaimplgstreamer.h
new file mode 100644
index 0000000000..ef41736c18
--- /dev/null
+++ b/indra/media_plugins/gstreamer010/llmediaimplgstreamer.h
@@ -0,0 +1,57 @@
+/**
+ * @file llmediaimplgstreamer.h
+ * @author Tofu Linden
+ * @brief implementation that supports media playback via GStreamer.
+ *
+ * $LicenseInfo:firstyear=2007&license=viewergpl$
+ *
+ * Copyright (c) 2007-2009, Linden Research, Inc.
+ *
+ * Second Life Viewer Source Code
+ * The source code in this file ("Source Code") is provided by Linden Lab
+ * to you under the terms of the GNU General Public License, version 2.0
+ * ("GPL"), unless you have obtained a separate licensing agreement
+ * ("Other License"), formally executed by you and Linden Lab. Terms of
+ * the GPL can be found in doc/GPL-license.txt in this distribution, or
+ * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
+ *
+ * There are special exceptions to the terms and conditions of the GPL as
+ * it is applied to this Source Code. View the full text of the exception
+ * in the file doc/FLOSS-exception.txt in this software distribution, or
+ * online at
+ * http://secondlifegrid.net/programs/open_source/licensing/flossexception
+ *
+ * By copying, modifying or distributing this software, you acknowledge
+ * that you have read and understood your obligations described above,
+ * and agree to abide by those obligations.
+ *
+ * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+ * COMPLETENESS OR PERFORMANCE.
+ * $/LicenseInfo$
+ */
+
+// header guard
+#ifndef llmediaimplgstreamer_h
+#define llmediaimplgstreamer_h
+
+#if LL_GSTREAMER010_ENABLED
+
+extern "C" {
+#include <stdio.h>
+#include <gst/gst.h>
+
+#include "apr_pools.h"
+#include "apr_dso.h"
+}
+
+
+extern "C" {
+gboolean llmediaimplgstreamer_bus_callback (GstBus *bus,
+ GstMessage *message,
+ gpointer data);
+}
+
+#endif // LL_GSTREAMER010_ENABLED
+
+#endif // llmediaimplgstreamer_h
diff --git a/indra/media_plugins/gstreamer010/llmediaimplgstreamer_syms.cpp b/indra/media_plugins/gstreamer010/llmediaimplgstreamer_syms.cpp
new file mode 100644
index 0000000000..cc52232496
--- /dev/null
+++ b/indra/media_plugins/gstreamer010/llmediaimplgstreamer_syms.cpp
@@ -0,0 +1,171 @@
+/**
+ * @file llmediaimplgstreamer_syms.cpp
+ * @brief dynamic GStreamer symbol-grabbing code
+ *
+ * $LicenseInfo:firstyear=2007&license=viewergpl$
+ *
+ * Copyright (c) 2007-2009, Linden Research, Inc.
+ *
+ * Second Life Viewer Source Code
+ * The source code in this file ("Source Code") is provided by Linden Lab
+ * to you under the terms of the GNU General Public License, version 2.0
+ * ("GPL"), unless you have obtained a separate licensing agreement
+ * ("Other License"), formally executed by you and Linden Lab. Terms of
+ * the GPL can be found in doc/GPL-license.txt in this distribution, or
+ * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
+ *
+ * There are special exceptions to the terms and conditions of the GPL as
+ * it is applied to this Source Code. View the full text of the exception
+ * in the file doc/FLOSS-exception.txt in this software distribution, or
+ * online at
+ * http://secondlifegrid.net/programs/open_source/licensing/flossexception
+ *
+ * By copying, modifying or distributing this software, you acknowledge
+ * that you have read and understood your obligations described above,
+ * and agree to abide by those obligations.
+ *
+ * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+ * COMPLETENESS OR PERFORMANCE.
+ * $/LicenseInfo$
+ */
+
+#if LL_GSTREAMER010_ENABLED
+
+#include <string>
+
+extern "C" {
+#include <gst/gst.h>
+
+#include "apr_pools.h"
+#include "apr_dso.h"
+}
+
+#include "llmediaimplgstreamertriviallogging.h"
+
+#define LL_GST_SYM(REQ, GSTSYM, RTN, ...) RTN (*ll##GSTSYM)(__VA_ARGS__) = NULL
+#include "llmediaimplgstreamer_syms_raw.inc"
+#include "llmediaimplgstreamer_syms_rawv.inc"
+#undef LL_GST_SYM
+
+// a couple of stubs for disgusting reasons
+GstDebugCategory*
+ll_gst_debug_category_new(gchar *name, guint color, gchar *description)
+{
+ static GstDebugCategory dummy;
+ return &dummy;
+}
+void ll_gst_debug_register_funcptr(GstDebugFuncPtr func, gchar* ptrname)
+{
+}
+
+static bool sSymsGrabbed = false;
+static apr_pool_t *sSymGSTDSOMemoryPool = NULL;
+static apr_dso_handle_t *sSymGSTDSOHandleG = NULL;
+static apr_dso_handle_t *sSymGSTDSOHandleV = NULL;
+
+
+bool grab_gst_syms(std::string gst_dso_name,
+ std::string gst_dso_name_vid)
+{
+ if (sSymsGrabbed)
+ {
+ // already have grabbed good syms
+ return TRUE;
+ }
+
+ bool sym_error = false;
+ bool rtn = false;
+ apr_status_t rv;
+ apr_dso_handle_t *sSymGSTDSOHandle = NULL;
+
+#define LL_GST_SYM(REQ, GSTSYM, RTN, ...) do{rv = apr_dso_sym((apr_dso_handle_sym_t*)&ll##GSTSYM, sSymGSTDSOHandle, #GSTSYM); if (rv != APR_SUCCESS) {INFOMSG("Failed to grab symbol: %s", #GSTSYM); if (REQ) sym_error = true;} else DEBUGMSG("grabbed symbol: %s from %p", #GSTSYM, (void*)ll##GSTSYM);}while(0)
+
+ //attempt to load the shared libraries
+ apr_pool_create(&sSymGSTDSOMemoryPool, NULL);
+
+ if ( APR_SUCCESS == (rv = apr_dso_load(&sSymGSTDSOHandle,
+ gst_dso_name.c_str(),
+ sSymGSTDSOMemoryPool) ))
+ {
+ INFOMSG("Found DSO: %s", gst_dso_name.c_str());
+#include "llmediaimplgstreamer_syms_raw.inc"
+
+ if ( sSymGSTDSOHandle )
+ {
+ sSymGSTDSOHandleG = sSymGSTDSOHandle;
+ sSymGSTDSOHandle = NULL;
+ }
+
+ if ( APR_SUCCESS ==
+ (rv = apr_dso_load(&sSymGSTDSOHandle,
+ gst_dso_name_vid.c_str(),
+ sSymGSTDSOMemoryPool) ))
+ {
+ INFOMSG("Found DSO: %s", gst_dso_name_vid.c_str());
+#include "llmediaimplgstreamer_syms_rawv.inc"
+ rtn = !sym_error;
+ }
+ else
+ {
+ INFOMSG("Couldn't load DSO: %s", gst_dso_name_vid.c_str());
+ rtn = false; // failure
+ }
+ }
+ else
+ {
+ INFOMSG("Couldn't load DSO: %s", gst_dso_name.c_str());
+ rtn = false; // failure
+ }
+
+ if (sym_error)
+ {
+ WARNMSG("Failed to find necessary symbols in GStreamer libraries.");
+ }
+
+ if ( sSymGSTDSOHandle )
+ {
+ sSymGSTDSOHandleV = sSymGSTDSOHandle;
+ sSymGSTDSOHandle = NULL;
+ }
+#undef LL_GST_SYM
+
+ sSymsGrabbed = !!rtn;
+ return rtn;
+}
+
+
+void ungrab_gst_syms()
+{
+ // should be safe to call regardless of whether we've
+ // actually grabbed syms.
+
+ if ( sSymGSTDSOHandleG )
+ {
+ apr_dso_unload(sSymGSTDSOHandleG);
+ sSymGSTDSOHandleG = NULL;
+ }
+
+ if ( sSymGSTDSOHandleV )
+ {
+ apr_dso_unload(sSymGSTDSOHandleV);
+ sSymGSTDSOHandleV = NULL;
+ }
+
+ if ( sSymGSTDSOMemoryPool )
+ {
+ apr_pool_destroy(sSymGSTDSOMemoryPool);
+ sSymGSTDSOMemoryPool = NULL;
+ }
+
+ // NULL-out all of the symbols we'd grabbed
+#define LL_GST_SYM(REQ, GSTSYM, RTN, ...) do{ll##GSTSYM = NULL;}while(0)
+#include "llmediaimplgstreamer_syms_raw.inc"
+#include "llmediaimplgstreamer_syms_rawv.inc"
+#undef LL_GST_SYM
+
+ sSymsGrabbed = false;
+}
+
+
+#endif // LL_GSTREAMER010_ENABLED
diff --git a/indra/media_plugins/gstreamer010/llmediaimplgstreamer_syms.h b/indra/media_plugins/gstreamer010/llmediaimplgstreamer_syms.h
new file mode 100644
index 0000000000..ee7473d6d1
--- /dev/null
+++ b/indra/media_plugins/gstreamer010/llmediaimplgstreamer_syms.h
@@ -0,0 +1,78 @@
+/**
+ * @file llmediaimplgstreamer_syms.h
+ * @brief dynamic GStreamer symbol-grabbing code
+ *
+ * $LicenseInfo:firstyear=2007&license=viewergpl$
+ *
+ * Copyright (c) 2007-2009, Linden Research, Inc.
+ *
+ * Second Life Viewer Source Code
+ * The source code in this file ("Source Code") is provided by Linden Lab
+ * to you under the terms of the GNU General Public License, version 2.0
+ * ("GPL"), unless you have obtained a separate licensing agreement
+ * ("Other License"), formally executed by you and Linden Lab. Terms of
+ * the GPL can be found in doc/GPL-license.txt in this distribution, or
+ * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
+ *
+ * There are special exceptions to the terms and conditions of the GPL as
+ * it is applied to this Source Code. View the full text of the exception
+ * in the file doc/FLOSS-exception.txt in this software distribution, or
+ * online at
+ * http://secondlifegrid.net/programs/open_source/licensing/flossexception
+ *
+ * By copying, modifying or distributing this software, you acknowledge
+ * that you have read and understood your obligations described above,
+ * and agree to abide by those obligations.
+ *
+ * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+ * COMPLETENESS OR PERFORMANCE.
+ * $/LicenseInfo$
+ */
+
+#include "linden_common.h"
+
+#if LL_GSTREAMER010_ENABLED
+
+extern "C" {
+#include <gst/gst.h>
+}
+
+bool grab_gst_syms(std::string gst_dso_name,
+ std::string gst_dso_name_vid);
+void ungrab_gst_syms();
+
+#define LL_GST_SYM(REQ, GSTSYM, RTN, ...) extern RTN (*ll##GSTSYM)(__VA_ARGS__)
+#include "llmediaimplgstreamer_syms_raw.inc"
+#include "llmediaimplgstreamer_syms_rawv.inc"
+#undef LL_GST_SYM
+
+// regrettable hacks to give us better runtime compatibility with older systems
+#define llg_return_if_fail(COND) do{if (!(COND)) return;}while(0)
+#define llg_return_val_if_fail(COND,V) do{if (!(COND)) return V;}while(0)
+
+// regrettable hacks because GStreamer was not designed for runtime loading
+#undef GST_TYPE_MESSAGE
+#define GST_TYPE_MESSAGE (llgst_message_get_type())
+#undef GST_TYPE_OBJECT
+#define GST_TYPE_OBJECT (llgst_object_get_type())
+#undef GST_TYPE_PIPELINE
+#define GST_TYPE_PIPELINE (llgst_pipeline_get_type())
+#undef GST_TYPE_ELEMENT
+#define GST_TYPE_ELEMENT (llgst_element_get_type())
+#undef GST_TYPE_VIDEO_SINK
+#define GST_TYPE_VIDEO_SINK (llgst_video_sink_get_type())
+// more regrettable hacks to stub-out these .h-exposed GStreamer internals
+void ll_gst_debug_register_funcptr(GstDebugFuncPtr func, gchar* ptrname);
+#undef _gst_debug_register_funcptr
+#define _gst_debug_register_funcptr ll_gst_debug_register_funcptr
+GstDebugCategory* ll_gst_debug_category_new(gchar *name, guint color, gchar *description);
+#undef _gst_debug_category_new
+#define _gst_debug_category_new ll_gst_debug_category_new
+#undef __gst_debug_enabled
+#define __gst_debug_enabled (0)
+
+// more hacks
+#define LLGST_MESSAGE_TYPE_NAME(M) (llgst_message_type_get_name(GST_MESSAGE_TYPE(M)))
+
+#endif // LL_GSTREAMER010_ENABLED
diff --git a/indra/media_plugins/gstreamer010/llmediaimplgstreamer_syms_raw.inc b/indra/media_plugins/gstreamer010/llmediaimplgstreamer_syms_raw.inc
new file mode 100644
index 0000000000..b33e59363d
--- /dev/null
+++ b/indra/media_plugins/gstreamer010/llmediaimplgstreamer_syms_raw.inc
@@ -0,0 +1,51 @@
+
+// required symbols to grab
+LL_GST_SYM(true, gst_pad_peer_accept_caps, gboolean, GstPad *pad, GstCaps *caps);
+LL_GST_SYM(true, gst_buffer_new, GstBuffer*, void);
+LL_GST_SYM(true, gst_buffer_set_caps, void, GstBuffer*, GstCaps *);
+LL_GST_SYM(true, gst_structure_set_value, void, GstStructure *, const gchar *, const GValue*);
+LL_GST_SYM(true, gst_init_check, gboolean, int *argc, char **argv[], GError ** err);
+LL_GST_SYM(true, gst_message_get_type, GType, void);
+LL_GST_SYM(true, gst_message_type_get_name, const gchar*, GstMessageType type);
+LL_GST_SYM(true, gst_message_parse_error, void, GstMessage *message, GError **gerror, gchar **debug);
+LL_GST_SYM(true, gst_message_parse_warning, void, GstMessage *message, GError **gerror, gchar **debug);
+LL_GST_SYM(true, gst_message_parse_state_changed, void, GstMessage *message, GstState *oldstate, GstState *newstate, GstState *pending);
+LL_GST_SYM(true, gst_element_set_state, GstStateChangeReturn, GstElement *element, GstState state);
+LL_GST_SYM(true, gst_object_unref, void, gpointer object);
+LL_GST_SYM(true, gst_object_get_type, GType, void);
+LL_GST_SYM(true, gst_pipeline_get_type, GType, void);
+LL_GST_SYM(true, gst_pipeline_get_bus, GstBus*, GstPipeline *pipeline);
+LL_GST_SYM(true, gst_bus_add_watch, guint, GstBus * bus, GstBusFunc func, gpointer user_data);
+LL_GST_SYM(true, gst_element_factory_make, GstElement*, const gchar *factoryname, const gchar *name);
+LL_GST_SYM(true, gst_element_get_type, GType, void);
+LL_GST_SYM(true, gst_static_pad_template_get, GstPadTemplate*, GstStaticPadTemplate *pad_template);
+LL_GST_SYM(true, gst_element_class_add_pad_template, void, GstElementClass *klass, GstPadTemplate *temp);
+LL_GST_SYM(true, gst_element_class_set_details, void, GstElementClass *klass, const GstElementDetails *details);
+LL_GST_SYM(true, gst_caps_unref, void, GstCaps* caps);
+LL_GST_SYM(true, gst_caps_ref, GstCaps *, GstCaps* caps);
+//LL_GST_SYM(true, gst_caps_is_empty, gboolean, const GstCaps *caps);
+LL_GST_SYM(true, gst_caps_from_string, GstCaps *, const gchar *string);
+LL_GST_SYM(true, gst_caps_replace, void, GstCaps **caps, GstCaps *newcaps);
+LL_GST_SYM(true, gst_caps_get_structure, GstStructure *, const GstCaps *caps, guint index);
+LL_GST_SYM(true, gst_caps_copy, GstCaps *, const GstCaps * caps);
+//LL_GST_SYM(true, gst_caps_intersect, GstCaps *, const GstCaps *caps1, const GstCaps *caps2);
+LL_GST_SYM(true, gst_element_register, gboolean, GstPlugin *plugin, const gchar *name, guint rank, GType type);
+LL_GST_SYM(true, _gst_plugin_register_static, void, GstPluginDesc *desc);
+LL_GST_SYM(true, gst_structure_get_int, gboolean, const GstStructure *structure, const gchar *fieldname, gint *value);
+LL_GST_SYM(true, gst_structure_get_value, G_CONST_RETURN GValue *, const GstStructure *structure, const gchar *fieldname);
+LL_GST_SYM(true, gst_value_get_fraction_numerator, gint, const GValue *value);
+LL_GST_SYM(true, gst_value_get_fraction_denominator, gint, const GValue *value);
+LL_GST_SYM(true, gst_structure_get_name, G_CONST_RETURN gchar *, const GstStructure *structure);
+LL_GST_SYM(true, gst_element_seek, bool, GstElement *, gdouble, GstFormat, GstSeekFlags, GstSeekType, gint64, GstSeekType, gint64);
+
+// optional symbols to grab
+LL_GST_SYM(false, gst_registry_fork_set_enabled, void, gboolean enabled);
+LL_GST_SYM(false, gst_segtrap_set_enabled, void, gboolean enabled);
+LL_GST_SYM(false, gst_message_parse_buffering, void, GstMessage *message, gint *percent);
+LL_GST_SYM(false, gst_message_parse_info, void, GstMessage *message, GError **gerror, gchar **debug);
+LL_GST_SYM(false, gst_element_query_position, gboolean, GstElement *element, GstFormat *format, gint64 *cur);
+LL_GST_SYM(false, gst_version, void, guint *major, guint *minor, guint *micro, guint *nano);
+
+// GStreamer 'internal' symbols which may not be visible in some runtimes but are still used in expanded GStreamer header macros - yuck! We'll substitute our own stubs for these.
+//LL_GST_SYM(true, _gst_debug_register_funcptr, void, GstDebugFuncPtr func, gchar* ptrname);
+//LL_GST_SYM(true, _gst_debug_category_new, GstDebugCategory *, gchar *name, guint color, gchar *description);
diff --git a/indra/media_plugins/gstreamer010/llmediaimplgstreamer_syms_rawv.inc b/indra/media_plugins/gstreamer010/llmediaimplgstreamer_syms_rawv.inc
new file mode 100644
index 0000000000..14fbcb48b9
--- /dev/null
+++ b/indra/media_plugins/gstreamer010/llmediaimplgstreamer_syms_rawv.inc
@@ -0,0 +1,5 @@
+
+// required symbols to grab
+LL_GST_SYM(true, gst_video_sink_get_type, GType, void);
+
+// optional symbols to grab
diff --git a/indra/media_plugins/gstreamer010/llmediaimplgstreamertriviallogging.h b/indra/media_plugins/gstreamer010/llmediaimplgstreamertriviallogging.h
new file mode 100644
index 0000000000..e31d4a3282
--- /dev/null
+++ b/indra/media_plugins/gstreamer010/llmediaimplgstreamertriviallogging.h
@@ -0,0 +1,53 @@
+/**
+ * @file llmediaimplgstreamertriviallogging.h
+ * @brief minimal logging utilities.
+ *
+ * $LicenseInfo:firstyear=2009&license=viewergpl$
+ *
+ * Copyright (c) 2009, Linden Research, Inc.
+ *
+ * Second Life Viewer Source Code
+ * The source code in this file ("Source Code") is provided by Linden Lab
+ * to you under the terms of the GNU General Public License, version 2.0
+ * ("GPL"), unless you have obtained a separate licensing agreement
+ * ("Other License"), formally executed by you and Linden Lab. Terms of
+ * the GPL can be found in doc/GPL-license.txt in this distribution, or
+ * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
+ *
+ * There are special exceptions to the terms and conditions of the GPL as
+ * it is applied to this Source Code. View the full text of the exception
+ * in the file doc/FLOSS-exception.txt in this software distribution, or
+ * online at
+ * http://secondlifegrid.net/programs/open_source/licensing/flossexception
+ *
+ * By copying, modifying or distributing this software, you acknowledge
+ * that you have read and understood your obligations described above,
+ * and agree to abide by those obligations.
+ *
+ * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+ * COMPLETENESS OR PERFORMANCE.
+ * $/LicenseInfo$
+ */
+
+#ifndef __LLMEDIAIMPLGSTREAMERTRIVIALLOGGING_H__
+#define __LLMEDIAIMPLGSTREAMERTRIVIALLOGGING_H__
+
+#include <cstdio>
+
+/////////////////////////////////////////////////////////////////////////
+// Debug/Info/Warning macros.
+#define MSGMODULEFOO "(media plugin)"
+#define STDERRMSG(...) do{\
+ fprintf(stderr, MSGMODULEFOO " %s:%d: ", __FUNCTION__, __LINE__);\
+ fprintf(stderr, __VA_ARGS__);\
+ fputc('\n',stderr);\
+ }while(0)
+#define NULLMSG(...) do{}while(0)
+
+#define DEBUGMSG NULLMSG
+#define INFOMSG STDERRMSG
+#define WARNMSG STDERRMSG
+/////////////////////////////////////////////////////////////////////////
+
+#endif /* __LLMEDIAIMPLGSTREAMERTRIVIALLOGGING_H__ */
diff --git a/indra/media_plugins/gstreamer010/llmediaimplgstreamervidplug.cpp b/indra/media_plugins/gstreamer010/llmediaimplgstreamervidplug.cpp
new file mode 100644
index 0000000000..d8ccfaa702
--- /dev/null
+++ b/indra/media_plugins/gstreamer010/llmediaimplgstreamervidplug.cpp
@@ -0,0 +1,532 @@
+/**
+ * @file llmediaimplgstreamervidplug.h
+ * @brief Video-consuming static GStreamer plugin for gst-to-LLMediaImpl
+ *
+ * $LicenseInfo:firstyear=2007&license=viewergpl$
+ *
+ * Copyright (c) 2007-2009, Linden Research, Inc.
+ *
+ * Second Life Viewer Source Code
+ * The source code in this file ("Source Code") is provided by Linden Lab
+ * to you under the terms of the GNU General Public License, version 2.0
+ * ("GPL"), unless you have obtained a separate licensing agreement
+ * ("Other License"), formally executed by you and Linden Lab. Terms of
+ * the GPL can be found in doc/GPL-license.txt in this distribution, or
+ * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
+ *
+ * There are special exceptions to the terms and conditions of the GPL as
+ * it is applied to this Source Code. View the full text of the exception
+ * in the file doc/FLOSS-exception.txt in this software distribution, or
+ * online at
+ * http://secondlifegrid.net/programs/open_source/licensing/flossexception
+ *
+ * By copying, modifying or distributing this software, you acknowledge
+ * that you have read and understood your obligations described above,
+ * and agree to abide by those obligations.
+ *
+ * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+ * COMPLETENESS OR PERFORMANCE.
+ * $/LicenseInfo$
+ */
+
+#if LL_GSTREAMER010_ENABLED
+
+#include "linden_common.h"
+
+#include <gst/gst.h>
+#include <gst/video/video.h>
+#include <gst/video/gstvideosink.h>
+
+#include "llmediaimplgstreamer_syms.h"
+#include "llmediaimplgstreamertriviallogging.h"
+
+#include "llmediaimplgstreamervidplug.h"
+
+
+GST_DEBUG_CATEGORY_STATIC (gst_slvideo_debug);
+#define GST_CAT_DEFAULT gst_slvideo_debug
+
+
+#define SLV_SIZECAPS ", width=(int)[1,2048], height=(int)[1,2048] "
+#define SLV_ALLCAPS GST_VIDEO_CAPS_RGBx SLV_SIZECAPS
+
+static GstStaticPadTemplate sink_factory = GST_STATIC_PAD_TEMPLATE (
+ "sink",
+ GST_PAD_SINK,
+ GST_PAD_ALWAYS,
+ GST_STATIC_CAPS (SLV_ALLCAPS)
+ );
+
+GST_BOILERPLATE (GstSLVideo, gst_slvideo, GstVideoSink,
+ GST_TYPE_VIDEO_SINK);
+
+static void gst_slvideo_set_property (GObject * object, guint prop_id,
+ const GValue * value,
+ GParamSpec * pspec);
+static void gst_slvideo_get_property (GObject * object, guint prop_id,
+ GValue * value, GParamSpec * pspec);
+
+static void
+gst_slvideo_base_init (gpointer gclass)
+{
+ static GstElementDetails element_details = {
+ (gchar*)"PluginTemplate",
+ (gchar*)"Generic/PluginTemplate",
+ (gchar*)"Generic Template Element",
+ (gchar*)"Linden Lab"
+ };
+ GstElementClass *element_class = GST_ELEMENT_CLASS (gclass);
+
+ llgst_element_class_add_pad_template (element_class,
+ llgst_static_pad_template_get (&sink_factory));
+ llgst_element_class_set_details (element_class, &element_details);
+}
+
+
+static void
+gst_slvideo_finalize (GObject * object)
+{
+ GstSLVideo *slvideo;
+ slvideo = GST_SLVIDEO (object);
+ if (slvideo->caps)
+ {
+ llgst_caps_unref(slvideo->caps);
+ }
+
+ G_OBJECT_CLASS(parent_class)->finalize (object);
+}
+
+
+static GstFlowReturn
+gst_slvideo_show_frame (GstBaseSink * bsink, GstBuffer * buf)
+{
+ GstSLVideo *slvideo;
+ llg_return_val_if_fail (buf != NULL, GST_FLOW_ERROR);
+
+ slvideo = GST_SLVIDEO(bsink);
+
+#if 0
+ fprintf(stderr, "\n\ntransferring a frame of %dx%d <- %p (%d)\n\n",
+ slvideo->width, slvideo->height, GST_BUFFER_DATA(buf),
+ slvideo->format);
+#endif
+ if (GST_BUFFER_DATA(buf))
+ {
+ // copy frame and frame info into neutral territory
+ GST_OBJECT_LOCK(slvideo);
+ slvideo->retained_frame_ready = TRUE;
+ slvideo->retained_frame_width = slvideo->width;
+ slvideo->retained_frame_height = slvideo->height;
+ slvideo->retained_frame_format = slvideo->format;
+ int rowbytes =
+ SLVPixelFormatBytes[slvideo->retained_frame_format] *
+ slvideo->retained_frame_width;
+ int needbytes = rowbytes * slvideo->retained_frame_width;
+ // resize retained frame hunk only if necessary
+ if (needbytes != slvideo->retained_frame_allocbytes)
+ {
+ delete[] slvideo->retained_frame_data;
+ slvideo->retained_frame_data = new unsigned char[needbytes];
+ slvideo->retained_frame_allocbytes = needbytes;
+
+ }
+ // copy the actual frame data to neutral territory -
+ // flipped, for GL reasons
+ for (int ypos=0; ypos<slvideo->height; ++ypos)
+ {
+ memcpy(&slvideo->retained_frame_data[(slvideo->height-1-ypos)*rowbytes],
+ &(((unsigned char*)GST_BUFFER_DATA(buf))[ypos*rowbytes]),
+ rowbytes);
+ }
+ // done with the shared data
+ GST_OBJECT_UNLOCK(slvideo);
+ }
+
+ return GST_FLOW_OK;
+}
+
+
+static GstStateChangeReturn
+gst_slvideo_change_state(GstElement * element, GstStateChange transition)
+{
+ GstSLVideo *slvideo;
+ GstStateChangeReturn ret = GST_STATE_CHANGE_SUCCESS;
+
+ slvideo = GST_SLVIDEO (element);
+
+ switch (transition) {
+ case GST_STATE_CHANGE_NULL_TO_READY:
+ break;
+ case GST_STATE_CHANGE_READY_TO_PAUSED:
+ break;
+ case GST_STATE_CHANGE_PAUSED_TO_PLAYING:
+ break;
+ default:
+ break;
+ }
+
+ ret = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition);
+ if (ret == GST_STATE_CHANGE_FAILURE)
+ return ret;
+
+ switch (transition) {
+ case GST_STATE_CHANGE_PLAYING_TO_PAUSED:
+ break;
+ case GST_STATE_CHANGE_PAUSED_TO_READY:
+ slvideo->fps_n = 0;
+ slvideo->fps_d = 1;
+ GST_VIDEO_SINK_WIDTH(slvideo) = 0;
+ GST_VIDEO_SINK_HEIGHT(slvideo) = 0;
+ break;
+ case GST_STATE_CHANGE_READY_TO_NULL:
+ break;
+ default:
+ break;
+ }
+
+ return ret;
+}
+
+
+static GstCaps *
+gst_slvideo_get_caps (GstBaseSink * bsink)
+{
+ GstSLVideo *slvideo;
+ slvideo = GST_SLVIDEO(bsink);
+
+ return llgst_caps_ref (slvideo->caps);
+}
+
+
+/* this function handles the link with other elements */
+static gboolean
+gst_slvideo_set_caps (GstBaseSink * bsink, GstCaps * caps)
+{
+ GstSLVideo *filter;
+ GstStructure *structure;
+
+ GST_DEBUG ("set caps with %" GST_PTR_FORMAT, caps);
+
+ filter = GST_SLVIDEO(bsink);
+
+ int width, height;
+ gboolean ret;
+ const GValue *fps;
+ const GValue *par;
+ structure = llgst_caps_get_structure (caps, 0);
+ ret = llgst_structure_get_int (structure, "width", &width);
+ ret = ret && llgst_structure_get_int (structure, "height", &height);
+ fps = llgst_structure_get_value (structure, "framerate");
+ ret = ret && (fps != NULL);
+ par = llgst_structure_get_value (structure, "pixel-aspect-ratio");
+ if (!ret)
+ return FALSE;
+
+ INFOMSG("** filter caps set with width=%d, height=%d", width, height);
+
+ GST_OBJECT_LOCK(filter);
+
+ filter->width = width;
+ filter->height = height;
+
+ filter->fps_n = llgst_value_get_fraction_numerator(fps);
+ filter->fps_d = llgst_value_get_fraction_denominator(fps);
+ if (par)
+ {
+ filter->par_n = llgst_value_get_fraction_numerator(par);
+ filter->par_d = llgst_value_get_fraction_denominator(par);
+ }
+ else
+ {
+ filter->par_n = 1;
+ filter->par_d = 1;
+ }
+ GST_VIDEO_SINK_WIDTH(filter) = width;
+ GST_VIDEO_SINK_HEIGHT(filter) = height;
+
+ // crufty lump - we *always* accept *only* RGBX now.
+ /*
+ filter->format = SLV_PF_UNKNOWN;
+ if (0 == strcmp(llgst_structure_get_name(structure),
+ "video/x-raw-rgb"))
+ {
+ int red_mask;
+ int green_mask;
+ int blue_mask;
+ llgst_structure_get_int(structure, "red_mask", &red_mask);
+ llgst_structure_get_int(structure, "green_mask", &green_mask);
+ llgst_structure_get_int(structure, "blue_mask", &blue_mask);
+ if ((unsigned int)red_mask == 0xFF000000 &&
+ (unsigned int)green_mask == 0x00FF0000 &&
+ (unsigned int)blue_mask == 0x0000FF00)
+ {
+ filter->format = SLV_PF_RGBX;
+ //fprintf(stderr, "\n\nPIXEL FORMAT RGB\n\n");
+ } else if ((unsigned int)red_mask == 0x0000FF00 &&
+ (unsigned int)green_mask == 0x00FF0000 &&
+ (unsigned int)blue_mask == 0xFF000000)
+ {
+ filter->format = SLV_PF_BGRX;
+ //fprintf(stderr, "\n\nPIXEL FORMAT BGR\n\n");
+ }
+ }*/
+
+ filter->format = SLV_PF_RGBX;
+
+ GST_OBJECT_UNLOCK(filter);
+
+ return TRUE;
+}
+
+
+static gboolean
+gst_slvideo_start (GstBaseSink * bsink)
+{
+ GstSLVideo *slvideo;
+ gboolean ret = TRUE;
+
+ slvideo = GST_SLVIDEO(bsink);
+
+ return ret;
+}
+
+static gboolean
+gst_slvideo_stop (GstBaseSink * bsink)
+{
+ GstSLVideo *slvideo;
+ slvideo = GST_SLVIDEO(bsink);
+
+ // free-up retained frame buffer
+ GST_OBJECT_LOCK(slvideo);
+ slvideo->retained_frame_ready = FALSE;
+ delete[] slvideo->retained_frame_data;
+ slvideo->retained_frame_data = NULL;
+ slvideo->retained_frame_allocbytes = 0;
+ GST_OBJECT_UNLOCK(slvideo);
+
+ return TRUE;
+}
+
+
+static GstFlowReturn
+gst_slvideo_buffer_alloc (GstBaseSink * bsink, guint64 offset, guint size,
+ GstCaps * caps, GstBuffer ** buf)
+{
+ gint width, height;
+ GstStructure *structure = NULL;
+ GstSLVideo *slvideo;
+ slvideo = GST_SLVIDEO(bsink);
+
+ // caps == requested caps
+ // we can ignore these and reverse-negotiate our preferred dimensions with
+ // the peer if we like - we need to do this to obey dynamic resize requests
+ // flowing in from the app.
+ structure = llgst_caps_get_structure (caps, 0);
+ if (!llgst_structure_get_int(structure, "width", &width) ||
+ !llgst_structure_get_int(structure, "height", &height))
+ {
+ GST_WARNING_OBJECT (slvideo, "no width/height in caps %" GST_PTR_FORMAT, caps);
+ return GST_FLOW_NOT_NEGOTIATED;
+ }
+
+ GstBuffer *newbuf = llgst_buffer_new();
+ bool made_bufferdata_ptr = false;
+#define MAXDEPTHHACK 4
+
+ GST_OBJECT_LOCK(slvideo);
+ if (slvideo->resize_forced)
+ {
+ gint slwantwidth, slwantheight;
+ slwantwidth = slvideo->resize_try_width;
+ slwantheight = slvideo->resize_try_height;
+
+ if (slwantwidth != width ||
+ slwantheight != height)
+ {
+ // don't like requested caps, we will issue our own suggestion - copy
+ // the requested caps but substitute our own width and height and see
+ // if our peer is happy with that.
+
+ GstCaps *desired_caps;
+ GstStructure *desired_struct;
+ desired_caps = llgst_caps_copy (caps);
+ desired_struct = llgst_caps_get_structure (desired_caps, 0);
+
+ GValue value = {0};
+ g_value_init(&value, G_TYPE_INT);
+ g_value_set_int(&value, slwantwidth);
+ llgst_structure_set_value (desired_struct, "width", &value);
+ g_value_unset(&value);
+ g_value_init(&value, G_TYPE_INT);
+ g_value_set_int(&value, slwantheight);
+ llgst_structure_set_value (desired_struct, "height", &value);
+
+ if (llgst_pad_peer_accept_caps (GST_VIDEO_SINK_PAD (slvideo),
+ desired_caps))
+ {
+ // todo: re-use buffers from a pool?
+ // todo: set MALLOCDATA to null, set DATA to point straight to shm?
+
+ // peer likes our cap suggestion
+ DEBUGMSG("peer loves us :)");
+ GST_BUFFER_SIZE(newbuf) = slwantwidth * slwantheight * MAXDEPTHHACK;
+ GST_BUFFER_MALLOCDATA(newbuf) = (guint8*)g_malloc(GST_BUFFER_SIZE(newbuf));
+ GST_BUFFER_DATA(newbuf) = GST_BUFFER_MALLOCDATA(newbuf);
+ llgst_buffer_set_caps (GST_BUFFER_CAST(newbuf), desired_caps);
+
+ made_bufferdata_ptr = true;
+ } else {
+ // peer hates our cap suggestion
+ INFOMSG("peer hates us :(");
+ llgst_caps_unref(desired_caps);
+ }
+ }
+ }
+
+ if (!made_bufferdata_ptr) // need to fallback to malloc at original size
+ {
+ GST_BUFFER_SIZE(newbuf) = width * height * MAXDEPTHHACK;
+ GST_BUFFER_MALLOCDATA(newbuf) = (guint8*)g_malloc(GST_BUFFER_SIZE(newbuf));
+ GST_BUFFER_DATA(newbuf) = GST_BUFFER_MALLOCDATA(newbuf);
+ llgst_buffer_set_caps (GST_BUFFER_CAST(newbuf), caps);
+ }
+
+ GST_OBJECT_UNLOCK(slvideo);
+
+ *buf = GST_BUFFER_CAST(newbuf);
+
+ return GST_FLOW_OK;
+}
+
+
+/* initialize the plugin's class */
+static void
+gst_slvideo_class_init (GstSLVideoClass * klass)
+{
+ GObjectClass *gobject_class;
+ GstElementClass *gstelement_class;
+ GstBaseSinkClass *gstbasesink_class;
+
+ gobject_class = (GObjectClass *) klass;
+ gstelement_class = (GstElementClass *) klass;
+ gstbasesink_class = (GstBaseSinkClass *) klass;
+
+ gobject_class->finalize = gst_slvideo_finalize;
+ gobject_class->set_property = gst_slvideo_set_property;
+ gobject_class->get_property = gst_slvideo_get_property;
+
+ gstelement_class->change_state = gst_slvideo_change_state;
+
+#define LLGST_DEBUG_FUNCPTR(p) (p)
+ gstbasesink_class->get_caps = LLGST_DEBUG_FUNCPTR (gst_slvideo_get_caps);
+ gstbasesink_class->set_caps = LLGST_DEBUG_FUNCPTR( gst_slvideo_set_caps);
+ gstbasesink_class->buffer_alloc=LLGST_DEBUG_FUNCPTR(gst_slvideo_buffer_alloc);
+ //gstbasesink_class->get_times = LLGST_DEBUG_FUNCPTR (gst_slvideo_get_times);
+ gstbasesink_class->preroll = LLGST_DEBUG_FUNCPTR (gst_slvideo_show_frame);
+ gstbasesink_class->render = LLGST_DEBUG_FUNCPTR (gst_slvideo_show_frame);
+
+ gstbasesink_class->start = LLGST_DEBUG_FUNCPTR (gst_slvideo_start);
+ gstbasesink_class->stop = LLGST_DEBUG_FUNCPTR (gst_slvideo_stop);
+
+ // gstbasesink_class->unlock = LLGST_DEBUG_FUNCPTR (gst_slvideo_unlock);
+#undef LLGST_DEBUG_FUNCPTR
+}
+
+
+/* initialize the new element
+ * instantiate pads and add them to element
+ * set functions
+ * initialize structure
+ */
+static void
+gst_slvideo_init (GstSLVideo * filter,
+ GstSLVideoClass * gclass)
+{
+ filter->caps = NULL;
+ filter->width = -1;
+ filter->height = -1;
+
+ // this is the info we share with the client app
+ GST_OBJECT_LOCK(filter);
+ filter->retained_frame_ready = FALSE;
+ filter->retained_frame_data = NULL;
+ filter->retained_frame_allocbytes = 0;
+ filter->retained_frame_width = filter->width;
+ filter->retained_frame_height = filter->height;
+ filter->retained_frame_format = SLV_PF_UNKNOWN;
+ GstCaps *caps = llgst_caps_from_string (SLV_ALLCAPS);
+ llgst_caps_replace (&filter->caps, caps);
+ filter->resize_forced = false;
+ filter->resize_try_width = -1;
+ filter->resize_try_height = -1;
+ GST_OBJECT_UNLOCK(filter);
+}
+
+static void
+gst_slvideo_set_property (GObject * object, guint prop_id,
+ const GValue * value, GParamSpec * pspec)
+{
+ llg_return_if_fail (GST_IS_SLVIDEO (object));
+
+ switch (prop_id) {
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ break;
+ }
+}
+
+static void
+gst_slvideo_get_property (GObject * object, guint prop_id,
+ GValue * value, GParamSpec * pspec)
+{
+ llg_return_if_fail (GST_IS_SLVIDEO (object));
+
+ switch (prop_id) {
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ break;
+ }
+}
+
+
+/* entry point to initialize the plug-in
+ * initialize the plug-in itself
+ * register the element factories and pad templates
+ * register the features
+ */
+static gboolean
+plugin_init (GstPlugin * plugin)
+{
+ DEBUGMSG("\n\n\nPLUGIN INIT\n\n\n");
+
+ GST_DEBUG_CATEGORY_INIT (gst_slvideo_debug, (gchar*)"private-slvideo-plugin",
+ 0, (gchar*)"Second Life Video Sink");
+
+ return llgst_element_register (plugin, "private-slvideo",
+ GST_RANK_NONE, GST_TYPE_SLVIDEO);
+}
+
+/* this is the structure that gstreamer looks for to register plugins
+ */
+/* NOTE: Can't rely upon GST_PLUGIN_DEFINE_STATIC to self-register, since
+ some g++ versions buggily avoid __attribute__((constructor)) functions -
+ so we provide an explicit plugin init function.
+ */
+void gst_slvideo_init_class (void)
+{
+#define PACKAGE "packagehack"
+ // this macro quietly refers to PACKAGE internally
+ static GST_PLUGIN_DEFINE (GST_VERSION_MAJOR,
+ GST_VERSION_MINOR,
+ "private-slvideoplugin",
+ "SL Video sink plugin",
+ plugin_init, "0.1", GST_LICENSE_UNKNOWN,
+ "Second Life",
+ "http://www.secondlife.com/");
+#undef PACKAGE
+ ll_gst_plugin_register_static (&gst_plugin_desc);
+ DEBUGMSG(stderr, "\n\n\nCLASS INIT\n\n\n");
+}
+
+#endif // LL_GSTREAMER010_ENABLED
diff --git a/indra/media_plugins/gstreamer010/llmediaimplgstreamervidplug.h b/indra/media_plugins/gstreamer010/llmediaimplgstreamervidplug.h
new file mode 100644
index 0000000000..f6d55b8758
--- /dev/null
+++ b/indra/media_plugins/gstreamer010/llmediaimplgstreamervidplug.h
@@ -0,0 +1,109 @@
+/**
+ * @file llmediaimplgstreamervidplug.h
+ * @brief Video-consuming static GStreamer plugin for gst-to-LLMediaImpl
+ *
+ * $LicenseInfo:firstyear=2007&license=viewergpl$
+ *
+ * Copyright (c) 2007-2009, Linden Research, Inc.
+ *
+ * Second Life Viewer Source Code
+ * The source code in this file ("Source Code") is provided by Linden Lab
+ * to you under the terms of the GNU General Public License, version 2.0
+ * ("GPL"), unless you have obtained a separate licensing agreement
+ * ("Other License"), formally executed by you and Linden Lab. Terms of
+ * the GPL can be found in doc/GPL-license.txt in this distribution, or
+ * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
+ *
+ * There are special exceptions to the terms and conditions of the GPL as
+ * it is applied to this Source Code. View the full text of the exception
+ * in the file doc/FLOSS-exception.txt in this software distribution, or
+ * online at
+ * http://secondlifegrid.net/programs/open_source/licensing/flossexception
+ *
+ * By copying, modifying or distributing this software, you acknowledge
+ * that you have read and understood your obligations described above,
+ * and agree to abide by those obligations.
+ *
+ * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+ * COMPLETENESS OR PERFORMANCE.
+ * $/LicenseInfo$
+ */
+
+#ifndef __GST_SLVIDEO_H__
+#define __GST_SLVIDEO_H__
+
+#if LL_GSTREAMER010_ENABLED
+
+extern "C" {
+#include <gst/gst.h>
+#include <gst/video/video.h>
+#include <gst/video/gstvideosink.h>
+}
+
+G_BEGIN_DECLS
+
+/* #defines don't like whitespacey bits */
+#define GST_TYPE_SLVIDEO \
+ (gst_slvideo_get_type())
+#define GST_SLVIDEO(obj) \
+ (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_SLVIDEO,GstSLVideo))
+#define GST_SLVIDEO_CLASS(klass) \
+ (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_SLVIDEO,GstSLVideoClass))
+#define GST_IS_SLVIDEO(obj) \
+ (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_SLVIDEO))
+#define GST_IS_SLVIDEO_CLASS(klass) \
+ (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_SLVIDEO))
+
+typedef struct _GstSLVideo GstSLVideo;
+typedef struct _GstSLVideoClass GstSLVideoClass;
+
+typedef enum {
+ SLV_PF_UNKNOWN = 0,
+ SLV_PF_RGBX = 1,
+ SLV_PF_BGRX = 2,
+ SLV__END = 3
+} SLVPixelFormat;
+const int SLVPixelFormatBytes[SLV__END] = {1, 4, 4};
+
+struct _GstSLVideo
+{
+ GstVideoSink video_sink;
+
+ GstCaps *caps;
+
+ int fps_n, fps_d;
+ int par_n, par_d;
+ int height, width;
+ SLVPixelFormat format;
+
+ // SHARED WITH APPLICATION:
+ // Access to the following should be protected by GST_OBJECT_LOCK() on
+ // the GstSLVideo object, and should be totally consistent upon UNLOCK
+ // (i.e. all written at once to reflect the current retained frame info
+ // when the retained frame is updated.)
+ bool retained_frame_ready; // new frame ready since flag last reset. (*TODO: could get the writer to wait on a semaphore instead of having the reader poll, potentially making dropped frames somewhat cheaper.)
+ unsigned char* retained_frame_data;
+ int retained_frame_allocbytes;
+ int retained_frame_width, retained_frame_height;
+ SLVPixelFormat retained_frame_format;
+ // sticky resize info
+ bool resize_forced;
+ int resize_try_width;
+ int resize_try_height;
+};
+
+struct _GstSLVideoClass
+{
+ GstVideoSinkClass parent_class;
+};
+
+GType gst_slvideo_get_type (void);
+
+void gst_slvideo_init_class (void);
+
+G_END_DECLS
+
+#endif // LL_GSTREAMER010_ENABLED
+
+#endif /* __GST_SLVIDEO_H__ */
diff --git a/indra/media_plugins/gstreamer010/media_plugin_gstreamer010.cpp b/indra/media_plugins/gstreamer010/media_plugin_gstreamer010.cpp
new file mode 100644
index 0000000000..647db7a5bf
--- /dev/null
+++ b/indra/media_plugins/gstreamer010/media_plugin_gstreamer010.cpp
@@ -0,0 +1,1204 @@
+/**
+ * @file media_plugin_gstreamer010.cpp
+ * @brief GStreamer-0.10 plugin for LLMedia API plugin system
+ *
+ * $LicenseInfo:firstyear=2007&license=viewergpl$
+ *
+ * Copyright (c) 2007, Linden Research, Inc.
+ *
+ * Second Life Viewer Source Code
+ * The source code in this file ("Source Code") is provided by Linden Lab
+ * to you under the terms of the GNU General Public License, version 2.0
+ * ("GPL"), unless you have obtained a separate licensing agreement
+ * ("Other License"), formally executed by you and Linden Lab. Terms of
+ * the GPL can be found in doc/GPL-license.txt in this distribution, or
+ * online at http://secondlife.com/developers/opensource/gplv2
+ *
+ * There are special exceptions to the terms and conditions of the GPL as
+ * it is applied to this Source Code. View the full text of the exception
+ * in the file doc/FLOSS-exception.txt in this software distribution, or
+ * online at http://secondlife.com/developers/opensource/flossexception
+ *
+ * By copying, modifying or distributing this software, you acknowledge
+ * that you have read and understood your obligations described above,
+ * and agree to abide by those obligations.
+ *
+ * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+ * COMPLETENESS OR PERFORMANCE.
+ * $/LicenseInfo$
+ */
+
+#include "linden_common.h"
+
+#include "llgl.h"
+
+#include "llplugininstance.h"
+#include "llpluginmessage.h"
+#include "llpluginmessageclasses.h"
+#include "media_plugin_base.h"
+
+#if LL_GSTREAMER010_ENABLED
+
+extern "C" {
+#include <gst/gst.h>
+}
+
+#include "llmediaimplgstreamer.h"
+#include "llmediaimplgstreamertriviallogging.h"
+
+#include "llmediaimplgstreamervidplug.h"
+
+#include "llmediaimplgstreamer_syms.h"
+
+//////////////////////////////////////////////////////////////////////////////
+//
+class MediaPluginGStreamer010 : public MediaPluginBase
+{
+public:
+ MediaPluginGStreamer010(LLPluginInstance::sendMessageFunction host_send_func, void *host_user_data);
+ ~MediaPluginGStreamer010();
+
+ /* virtual */ void receiveMessage(const char *message_string);
+
+ static bool startup();
+ static bool closedown();
+
+ gboolean processGSTEvents(GstBus *bus,
+ GstMessage *message);
+
+private:
+ std::string getVersion();
+ bool navigateTo( const std::string urlIn );
+ bool seek( double time_sec );
+ bool setVolume( float volume );
+
+ // misc
+ bool pause();
+ bool stop();
+ bool play(double rate);
+ bool getTimePos(double &sec_out);
+
+ static const double MIN_LOOP_SEC = 1.0F;
+
+ bool mIsLooping;
+
+ enum ECommand {
+ COMMAND_NONE,
+ COMMAND_STOP,
+ COMMAND_PLAY,
+ COMMAND_FAST_FORWARD,
+ COMMAND_FAST_REWIND,
+ COMMAND_PAUSE,
+ COMMAND_SEEK,
+ };
+ ECommand mCommand;
+
+private:
+ bool unload();
+ bool load();
+
+ bool update(int milliseconds);
+ void mouseDown( int x, int y );
+ void mouseUp( int x, int y );
+ void mouseMove( int x, int y );
+
+ bool sizeChanged();
+
+ static bool mDoneInit;
+
+ guint mBusWatchID;
+
+ float mVolume;
+
+ int mDepth;
+
+ // media natural size
+ int mNaturalWidth;
+ int mNaturalHeight;
+ int mNaturalRowbytes;
+ // previous media natural size so we can detect changes
+ int mPreviousNaturalWidth;
+ int mPreviousNaturalHeight;
+ // desired render size from host
+ int mWidth;
+ int mHeight;
+ // padded texture size we need to write into
+ int mTextureWidth;
+ int mTextureHeight;
+
+ int mTextureFormatPrimary;
+ int mTextureFormatType;
+
+ bool mSeekWanted;
+ double mSeekDestination;
+
+ // Very GStreamer-specific
+ GMainLoop *mPump; // event pump for this media
+ GstElement *mPlaybin;
+ GstSLVideo *mVideoSink;
+};
+
+//static
+bool MediaPluginGStreamer010::mDoneInit = false;
+
+MediaPluginGStreamer010::MediaPluginGStreamer010(
+ LLPluginInstance::sendMessageFunction host_send_func,
+ void *host_user_data ) :
+ MediaPluginBase(host_send_func, host_user_data),
+ mBusWatchID ( 0 ),
+ mNaturalRowbytes ( 4 ),
+ mTextureFormatPrimary ( GL_RGBA ),
+ mTextureFormatType ( GL_UNSIGNED_INT_8_8_8_8_REV ),
+ mSeekWanted(false),
+ mSeekDestination(0.0),
+ mPump ( NULL ),
+ mPlaybin ( NULL ),
+ mVideoSink ( NULL ),
+ mCommand ( COMMAND_NONE )
+{
+ std::ostringstream str;
+ INFOMSG("MediaPluginGStreamer010 constructor - my PID=%u", U32(getpid()));
+}
+
+///////////////////////////////////////////////////////////////////////////////
+//
+//#define LL_GST_REPORT_STATE_CHANGES
+#ifdef LL_GST_REPORT_STATE_CHANGES
+static char* get_gst_state_name(GstState state)
+{
+ switch (state) {
+ case GST_STATE_VOID_PENDING: return "VOID_PENDING";
+ case GST_STATE_NULL: return "NULL";
+ case GST_STATE_READY: return "READY";
+ case GST_STATE_PAUSED: return "PAUSED";
+ case GST_STATE_PLAYING: return "PLAYING";
+ }
+ return "(unknown)";
+}
+#endif // LL_GST_REPORT_STATE_CHANGES
+
+gboolean
+MediaPluginGStreamer010::processGSTEvents(GstBus *bus,
+ GstMessage *message)
+{
+ if (!message)
+ return TRUE; // shield against GStreamer bug
+
+ if (GST_MESSAGE_TYPE(message) != GST_MESSAGE_STATE_CHANGED &&
+ GST_MESSAGE_TYPE(message) != GST_MESSAGE_BUFFERING)
+ {
+ DEBUGMSG("Got GST message type: %s",
+ LLGST_MESSAGE_TYPE_NAME (message));
+ }
+ else
+ {
+ DEBUGMSG("Got GST message type: %s",
+ LLGST_MESSAGE_TYPE_NAME (message));
+ }
+
+ switch (GST_MESSAGE_TYPE (message)) {
+ case GST_MESSAGE_BUFFERING: {
+ // NEEDS GST 0.10.11+
+ if (llgst_message_parse_buffering)
+ {
+ gint percent = 0;
+ llgst_message_parse_buffering(message, &percent);
+ DEBUGMSG("GST buffering: %d%%", percent);
+ }
+ break;
+ }
+ case GST_MESSAGE_STATE_CHANGED: {
+ GstState old_state;
+ GstState new_state;
+ GstState pending_state;
+ llgst_message_parse_state_changed(message,
+ &old_state,
+ &new_state,
+ &pending_state);
+#ifdef LL_GST_REPORT_STATE_CHANGES
+ // not generally very useful, and rather spammy.
+ DEBUGMSG("state change (old,<new>,pending): %s,<%s>,%s",
+ get_gst_state_name(old_state),
+ get_gst_state_name(new_state),
+ get_gst_state_name(pending_state));
+#endif // LL_GST_REPORT_STATE_CHANGES
+
+ switch (new_state) {
+ case GST_STATE_VOID_PENDING:
+ break;
+ case GST_STATE_NULL:
+ break;
+ case GST_STATE_READY:
+ setStatus(STATUS_LOADED);
+ break;
+ case GST_STATE_PAUSED:
+ setStatus(STATUS_PAUSED);
+ break;
+ case GST_STATE_PLAYING:
+ setStatus(STATUS_PLAYING);
+ break;
+ }
+ break;
+ }
+ case GST_MESSAGE_ERROR: {
+ GError *err = NULL;
+ gchar *debug = NULL;
+
+ llgst_message_parse_error (message, &err, &debug);
+ WARNMSG("GST error: %s", err?err->message:"(unknown)");
+ if (err)
+ g_error_free (err);
+ g_free (debug);
+
+ mCommand = COMMAND_STOP;
+
+ setStatus(STATUS_ERROR);
+
+ break;
+ }
+ case GST_MESSAGE_INFO: {
+ if (llgst_message_parse_info)
+ {
+ GError *err = NULL;
+ gchar *debug = NULL;
+
+ llgst_message_parse_info (message, &err, &debug);
+ INFOMSG("GST info: %s", err?err->message:"(unknown)");
+ if (err)
+ g_error_free (err);
+ g_free (debug);
+ }
+ break;
+ }
+ case GST_MESSAGE_WARNING: {
+ GError *err = NULL;
+ gchar *debug = NULL;
+
+ llgst_message_parse_warning (message, &err, &debug);
+ WARNMSG("GST warning: %s", err?err->message:"(unknown)");
+ if (err)
+ g_error_free (err);
+ g_free (debug);
+
+ break;
+ }
+ case GST_MESSAGE_EOS:
+ /* end-of-stream */
+ DEBUGMSG("GST end-of-stream.");
+ if (mIsLooping)
+ {
+ DEBUGMSG("looping media...");
+ double eos_pos_sec = 0.0F;
+ bool got_eos_position = getTimePos(eos_pos_sec);
+
+ if (got_eos_position && eos_pos_sec < MIN_LOOP_SEC)
+ {
+ // if we know that the movie is really short, don't
+ // loop it else it can easily become a time-hog
+ // because of GStreamer spin-up overhead
+ DEBUGMSG("really short movie (%0.3fsec) - not gonna loop this, pausing instead.", eos_pos_sec);
+ // inject a COMMAND_PAUSE
+ mCommand = COMMAND_PAUSE;
+ }
+ else
+ {
+#undef LLGST_LOOP_BY_SEEKING
+// loop with a stop-start instead of a seek, because it actually seems rather
+// faster than seeking on remote streams.
+#ifdef LLGST_LOOP_BY_SEEKING
+ // first, try looping by an explicit rewind
+ bool seeksuccess = seek(0.0);
+ if (seeksuccess)
+ {
+ play(1.0);
+ }
+ else
+#endif // LLGST_LOOP_BY_SEEKING
+ { // use clumsy stop-start to loop
+ DEBUGMSG("didn't loop by rewinding - stopping and starting instead...");
+ stop();
+ play(1.0);
+ }
+ }
+ }
+ else // not a looping media
+ {
+ // inject a COMMAND_STOP
+ mCommand = COMMAND_STOP;
+ }
+ break;
+ default:
+ /* unhandled message */
+ break;
+ }
+
+ /* we want to be notified again the next time there is a message
+ * on the bus, so return true (false means we want to stop watching
+ * for messages on the bus and our callback should not be called again)
+ */
+ return TRUE;
+}
+
+extern "C" {
+gboolean
+llmediaimplgstreamer_bus_callback (GstBus *bus,
+ GstMessage *message,
+ gpointer data)
+{
+ MediaPluginGStreamer010 *impl = (MediaPluginGStreamer010*)data;
+ return impl->processGSTEvents(bus, message);
+}
+} // extern "C"
+
+
+
+bool
+MediaPluginGStreamer010::navigateTo ( const std::string urlIn )
+{
+ if (!mDoneInit)
+ return false; // error
+
+ setStatus(STATUS_LOADING);
+
+ DEBUGMSG("Setting media URI: %s", urlIn.c_str());
+
+ mSeekWanted = false;
+
+ if (NULL == mPump ||
+ NULL == mPlaybin)
+ {
+ setStatus(STATUS_ERROR);
+ return false; // error
+ }
+
+ // set URI
+ g_object_set (G_OBJECT (mPlaybin), "uri", urlIn.c_str(), NULL);
+ //g_object_set (G_OBJECT (mPlaybin), "uri", "file:///tmp/movie", NULL);
+
+ // navigateTo implicitly plays, too.
+ play(1.0);
+
+ return true;
+}
+
+
+bool
+MediaPluginGStreamer010::update(int milliseconds)
+{
+ if (!mDoneInit)
+ return false; // error
+
+ DEBUGMSG("updating media...");
+
+ // sanity check
+ if (NULL == mPump ||
+ NULL == mPlaybin)
+ {
+ DEBUGMSG("dead media...");
+ return false;
+ }
+
+ // see if there's an outstanding seek wanted
+ if (mSeekWanted &&
+ // bleh, GST has to be happy that the movie is really truly playing
+ // or it may quietly ignore the seek (with rtsp:// at least).
+ (GST_STATE(mPlaybin) == GST_STATE_PLAYING))
+ {
+ seek(mSeekDestination);
+ mSeekWanted = false;
+ }
+
+ // *TODO: time-limit - but there isn't a lot we can do here, most
+ // time is spent in gstreamer's own opaque worker-threads. maybe
+ // we can do something sneaky like only unlock the video object
+ // for 'milliseconds' and otherwise hold the lock.
+ while (g_main_context_pending(g_main_loop_get_context(mPump)))
+ {
+ g_main_context_iteration(g_main_loop_get_context(mPump), FALSE);
+ }
+
+ // check for availability of a new frame
+
+ if (mVideoSink)
+ {
+ GST_OBJECT_LOCK(mVideoSink);
+ if (mVideoSink->retained_frame_ready)
+ {
+ DEBUGMSG("NEW FRAME READY");
+
+ if (mVideoSink->retained_frame_width != mNaturalWidth ||
+ mVideoSink->retained_frame_height != mNaturalHeight)
+ // *TODO: also check for change in format
+ {
+ // just resize container, don't consume frame
+ int neww = mVideoSink->retained_frame_width;
+ int newh = mVideoSink->retained_frame_height;
+
+ int newd = 4;
+ mTextureFormatPrimary = GL_RGBA;
+ mTextureFormatType = GL_UNSIGNED_INT_8_8_8_8_REV;
+
+ /*
+ int newd = SLVPixelFormatBytes[mVideoSink->retained_frame_format];
+ if (SLV_PF_BGRX == mVideoSink->retained_frame_format)
+ {
+ mTextureFormatPrimary = GL_BGRA;
+ mTextureFormatType = GL_UNSIGNED_INT_8_8_8_8_REV;
+ }
+ else
+ {
+ mTextureFormatPrimary = GL_RGBA;
+ mTextureFormatType = GL_UNSIGNED_INT_8_8_8_8_REV;
+ }
+ */
+
+ GST_OBJECT_UNLOCK(mVideoSink);
+
+ mNaturalRowbytes = neww * newd;
+ DEBUGMSG("video container resized to %dx%d",
+ neww, newh);
+
+ mDepth = newd;
+ mNaturalWidth = neww;
+ mNaturalHeight = newh;
+ sizeChanged();
+ return true;
+ }
+
+ if (mPixels &&
+ mNaturalHeight <= mHeight &&
+ mNaturalWidth <= mWidth &&
+ !mTextureSegmentName.empty())
+ {
+
+ // we're gonna totally consume this frame - reset 'ready' flag
+ mVideoSink->retained_frame_ready = FALSE;
+ int destination_rowbytes = mWidth * mDepth;
+ for (int row=0; row<mNaturalHeight; ++row)
+ {
+ memcpy(&mPixels
+ [destination_rowbytes * row],
+ &mVideoSink->retained_frame_data
+ [mNaturalRowbytes * row],
+ mNaturalRowbytes);
+ }
+
+ GST_OBJECT_UNLOCK(mVideoSink);
+ DEBUGMSG("NEW FRAME REALLY TRULY CONSUMED, TELLING HOST");
+
+ setDirty(0,0,mNaturalWidth,mNaturalHeight);
+ }
+ else
+ {
+ // new frame ready, but we're not ready to
+ // consume it.
+
+ GST_OBJECT_UNLOCK(mVideoSink);
+
+ DEBUGMSG("NEW FRAME not consumed, still waiting for a shm segment and/or shm resize");
+ }
+
+ return true;
+ }
+ else
+ {
+ // nothing to do yet.
+ GST_OBJECT_UNLOCK(mVideoSink);
+ return true;
+ }
+ }
+
+ return true;
+}
+
+
+void
+MediaPluginGStreamer010::mouseDown( int x, int y )
+{
+ // do nothing
+}
+
+void
+MediaPluginGStreamer010::mouseUp( int x, int y )
+{
+ // do nothing
+}
+
+void
+MediaPluginGStreamer010::mouseMove( int x, int y )
+{
+ // do nothing
+}
+
+
+bool
+MediaPluginGStreamer010::pause()
+{
+ DEBUGMSG("pausing media...");
+ // todo: error-check this?
+ llgst_element_set_state(mPlaybin, GST_STATE_PAUSED);
+ return true;
+}
+
+bool
+MediaPluginGStreamer010::stop()
+{
+ DEBUGMSG("stopping media...");
+ // todo: error-check this?
+ llgst_element_set_state(mPlaybin, GST_STATE_READY);
+ return true;
+}
+
+bool
+MediaPluginGStreamer010::play(double rate)
+{
+ // NOTE: we don't actually support non-natural rate.
+
+ DEBUGMSG("playing media... rate=%f", rate);
+ // todo: error-check this?
+ llgst_element_set_state(mPlaybin, GST_STATE_PLAYING);
+ return true;
+}
+
+bool
+MediaPluginGStreamer010::setVolume( float volume )
+{
+ // we try to only update volume as conservatively as
+ // possible, as many gst-plugins-base versions up to at least
+ // November 2008 have critical race-conditions in setting volume - sigh
+ if (mVolume == volume)
+ return true; // nothing to do, everything's fine
+
+ mVolume = volume;
+ if (mDoneInit && mPlaybin)
+ {
+ g_object_set(mPlaybin, "volume", mVolume, NULL);
+ return true;
+ }
+
+ return false;
+}
+
+bool
+MediaPluginGStreamer010::seek(double time_sec)
+{
+ bool success = false;
+ if (mDoneInit && mPlaybin)
+ {
+ success = llgst_element_seek(mPlaybin, 1.0F, GST_FORMAT_TIME,
+ GstSeekFlags(GST_SEEK_FLAG_FLUSH |
+ GST_SEEK_FLAG_KEY_UNIT),
+ GST_SEEK_TYPE_SET, gint64(time_sec*GST_SECOND),
+ GST_SEEK_TYPE_NONE, GST_CLOCK_TIME_NONE);
+ }
+ DEBUGMSG("MEDIA SEEK REQUEST to %fsec result was %d",
+ float(time_sec), int(success));
+ return success;
+}
+
+bool
+MediaPluginGStreamer010::getTimePos(double &sec_out)
+{
+ bool got_position = false;
+ if (mPlaybin)
+ {
+ gint64 pos;
+ GstFormat timefmt = GST_FORMAT_TIME;
+ got_position =
+ llgst_element_query_position &&
+ llgst_element_query_position(mPlaybin,
+ &timefmt,
+ &pos);
+ got_position = got_position
+ && (timefmt == GST_FORMAT_TIME);
+ // GStreamer may have other ideas, but we consider the current position
+ // undefined if not PLAYING or PAUSED
+ got_position = got_position &&
+ (GST_STATE(mPlaybin) == GST_STATE_PLAYING ||
+ GST_STATE(mPlaybin) == GST_STATE_PAUSED);
+ if (got_position && !GST_CLOCK_TIME_IS_VALID(pos))
+ {
+ if (GST_STATE(mPlaybin) == GST_STATE_PLAYING)
+ {
+ // if we're playing then we treat an invalid clock time
+ // as 0, for complicated reasons (insert reason here)
+ pos = 0;
+ }
+ else
+ {
+ got_position = false;
+ }
+
+ }
+ // If all the preconditions succeeded... we can trust the result.
+ if (got_position)
+ {
+ sec_out = double(pos) / double(GST_SECOND); // gst to sec
+ }
+ }
+ return got_position;
+}
+
+bool
+MediaPluginGStreamer010::load()
+{
+ if (!mDoneInit)
+ return false; // error
+
+ setStatus(STATUS_LOADING);
+
+ DEBUGMSG("setting up media...");
+
+ mIsLooping = false;
+ mVolume = 0.1234567; // minor hack to force an initial volume update
+
+ // Create a pumpable main-loop for this media
+ mPump = g_main_loop_new (NULL, FALSE);
+ if (!mPump)
+ {
+ setStatus(STATUS_ERROR);
+ return false; // error
+ }
+
+ // instantiate a playbin element to do the hard work
+ mPlaybin = llgst_element_factory_make ("playbin", "play");
+ if (!mPlaybin)
+ {
+ setStatus(STATUS_ERROR);
+ return false; // error
+ }
+
+ // get playbin's bus
+ GstBus *bus = llgst_pipeline_get_bus (GST_PIPELINE (mPlaybin));
+ if (!bus)
+ {
+ setStatus(STATUS_ERROR);
+ return false; // error
+ }
+ mBusWatchID = llgst_bus_add_watch (bus,
+ llmediaimplgstreamer_bus_callback,
+ this);
+ llgst_object_unref (bus);
+
+ if (NULL == getenv("LL_GSTREAMER_EXTERNAL")) {
+ // instantiate a custom video sink
+ mVideoSink =
+ GST_SLVIDEO(llgst_element_factory_make ("private-slvideo", "slvideo"));
+ if (!mVideoSink)
+ {
+ WARNMSG("Could not instantiate private-slvideo element.");
+ // todo: cleanup.
+ setStatus(STATUS_ERROR);
+ return false; // error
+ }
+
+ // connect the pieces
+ g_object_set(mPlaybin, "video-sink", mVideoSink, NULL);
+ }
+
+ return true;
+}
+
+bool
+MediaPluginGStreamer010::unload ()
+{
+ if (!mDoneInit)
+ return false; // error
+
+ DEBUGMSG("unloading media...");
+
+ // stop getting callbacks for this bus
+ g_source_remove(mBusWatchID);
+ mBusWatchID = 0;
+
+ if (mPlaybin)
+ {
+ llgst_element_set_state (mPlaybin, GST_STATE_NULL);
+ llgst_object_unref (GST_OBJECT (mPlaybin));
+ mPlaybin = NULL;
+ }
+
+ if (mPump)
+ {
+ g_main_loop_quit(mPump);
+ mPump = NULL;
+ }
+
+ mVideoSink = NULL;
+
+ setStatus(STATUS_NONE);
+
+ return true;
+}
+
+
+//static
+bool
+MediaPluginGStreamer010::startup()
+{
+ // first - check if GStreamer is explicitly disabled
+ if (NULL != getenv("LL_DISABLE_GSTREAMER"))
+ return false;
+
+ // only do global GStreamer initialization once.
+ if (!mDoneInit)
+ {
+ g_thread_init(NULL);
+
+ // Init the glib type system - we need it.
+ g_type_init();
+
+ // Get symbols!
+#if LL_DARWIN
+ if (! grab_gst_syms("libgstreamer-0.10.dylib",
+ "libgstvideo-0.10.dylib") )
+#elseif LL_WINDOWS
+ if (! grab_gst_syms("libgstreamer-0.10.dll",
+ "libgstvideo-0.10.dll") )
+#else // linux or other ELFy unixoid
+ if (! grab_gst_syms("libgstreamer-0.10.so.0",
+ "libgstvideo-0.10.so.0") )
+#endif
+ {
+ WARNMSG("Couldn't find suitable GStreamer 0.10 support on this system - video playback disabled.");
+ return false;
+ }
+
+ if (llgst_segtrap_set_enabled)
+ {
+ llgst_segtrap_set_enabled(FALSE);
+ }
+ else
+ {
+ WARNMSG("gst_segtrap_set_enabled() is not available; plugin crashes won't be caught.");
+ }
+
+#if LL_LINUX
+ // Gstreamer tries a fork during init, waitpid-ing on it,
+ // which conflicts with any installed SIGCHLD handler...
+ struct sigaction tmpact, oldact;
+ if (llgst_registry_fork_set_enabled) {
+ // if we can disable SIGCHLD-using forking behaviour,
+ // do it.
+ llgst_registry_fork_set_enabled(false);
+ }
+ else {
+ // else temporarily install default SIGCHLD handler
+ // while GStreamer initialises
+ tmpact.sa_handler = SIG_DFL;
+ sigemptyset( &tmpact.sa_mask );
+ tmpact.sa_flags = SA_SIGINFO;
+ sigaction(SIGCHLD, &tmpact, &oldact);
+ }
+#endif // LL_LINUX
+
+ // Protect against GStreamer resetting the locale, yuck.
+ static std::string saved_locale;
+ saved_locale = setlocale(LC_ALL, NULL);
+
+ // finally, try to initialize GStreamer!
+ GError *err = NULL;
+ gboolean init_gst_success = llgst_init_check(NULL, NULL, &err);
+
+ // restore old locale
+ setlocale(LC_ALL, saved_locale.c_str() );
+
+#if LL_LINUX
+ // restore old SIGCHLD handler
+ if (!llgst_registry_fork_set_enabled)
+ sigaction(SIGCHLD, &oldact, NULL);
+#endif // LL_LINUX
+
+ if (!init_gst_success) // fail
+ {
+ if (err)
+ {
+ WARNMSG("GST init failed: %s", err->message);
+ g_error_free(err);
+ }
+ else
+ {
+ WARNMSG("GST init failed for unspecified reason.");
+ }
+ return false;
+ }
+
+ // Init our custom plugins - only really need do this once.
+ gst_slvideo_init_class();
+
+ mDoneInit = true;
+ }
+
+ return true;
+}
+
+
+bool
+MediaPluginGStreamer010::sizeChanged()
+{
+ // the shared writing space has possibly changed size/location/whatever
+
+ // Check to see whether the movie's natural size has updated
+ if (mNaturalWidth != mPreviousNaturalWidth ||
+ mNaturalHeight != mPreviousNaturalHeight)
+ {
+ mPreviousNaturalWidth = mNaturalWidth;
+ mPreviousNaturalHeight = mNaturalHeight;
+
+ LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "size_change_request");
+ message.setValue("name", mTextureSegmentName);
+ message.setValueS32("width", mNaturalWidth);
+ message.setValueS32("height", mNaturalHeight);
+ DEBUGMSG("<--- Sending size change request to application with name: '%s' - size is %d x %d", mTextureSegmentName.c_str(), mNaturalWidth, mNaturalHeight);
+ sendMessage(message);
+ }
+
+ return true;
+}
+
+
+
+//static
+bool
+MediaPluginGStreamer010::closedown()
+{
+ if (!mDoneInit)
+ return false; // error
+
+ ungrab_gst_syms();
+
+ mDoneInit = false;
+
+ return true;
+}
+
+MediaPluginGStreamer010::~MediaPluginGStreamer010()
+{
+ DEBUGMSG("MediaPluginGStreamer010 destructor");
+
+ closedown();
+
+ DEBUGMSG("GStreamer010 closing down");
+}
+
+
+std::string
+MediaPluginGStreamer010::getVersion()
+{
+ std::string plugin_version = "GStreamer010 media plugin, GStreamer version ";
+ if (mDoneInit &&
+ llgst_version)
+ {
+ guint major, minor, micro, nano;
+ llgst_version(&major, &minor, &micro, &nano);
+ plugin_version += llformat("%u.%u.%u.%u (runtime), %u.%u.%u.%u (headers)", (unsigned int)major, (unsigned int)minor, (unsigned int)micro, (unsigned int)nano, (unsigned int)GST_VERSION_MAJOR, (unsigned int)GST_VERSION_MINOR, (unsigned int)GST_VERSION_MICRO, (unsigned int)GST_VERSION_NANO);
+ }
+ else
+ {
+ plugin_version += "(unknown)";
+ }
+ return plugin_version;
+}
+
+void MediaPluginGStreamer010::receiveMessage(const char *message_string)
+{
+ //std::cerr << "MediaPluginGStreamer010::receiveMessage: received message: \"" << message_string << "\"" << std::endl;
+
+ LLPluginMessage message_in;
+
+ if(message_in.parse(message_string) >= 0)
+ {
+ std::string message_class = message_in.getClass();
+ std::string message_name = message_in.getName();
+ if(message_class == LLPLUGIN_MESSAGE_CLASS_BASE)
+ {
+ if(message_name == "init")
+ {
+ LLPluginMessage message("base", "init_response");
+ LLSD versions = LLSD::emptyMap();
+ versions[LLPLUGIN_MESSAGE_CLASS_BASE] = LLPLUGIN_MESSAGE_CLASS_BASE_VERSION;
+ versions[LLPLUGIN_MESSAGE_CLASS_MEDIA] = LLPLUGIN_MESSAGE_CLASS_MEDIA_VERSION;
+ versions[LLPLUGIN_MESSAGE_CLASS_MEDIA_TIME] = LLPLUGIN_MESSAGE_CLASS_MEDIA_TIME_VERSION;
+ message.setValueLLSD("versions", versions);
+
+ if ( load() )
+ {
+ DEBUGMSG("GStreamer010 media instance set up");
+ }
+ else
+ {
+ WARNMSG("GStreamer010 media instance failed to set up");
+ }
+
+ message.setValue("plugin_version", getVersion());
+ sendMessage(message);
+
+ // Plugin gets to decide the texture parameters to use.
+ message.setMessage(LLPLUGIN_MESSAGE_CLASS_MEDIA, "texture_params");
+ // lame to have to decide this now, it depends on the movie. Oh well.
+ mDepth = 4;
+
+ mNaturalWidth = 1;
+ mNaturalHeight = 1;
+ mPreviousNaturalWidth = 1;
+ mPreviousNaturalHeight = 1;
+ mWidth = 1;
+ mHeight = 1;
+ mTextureWidth = 1;
+ mTextureHeight = 1;
+
+ message.setValueU32("format", GL_RGBA);
+ message.setValueU32("type", GL_UNSIGNED_INT_8_8_8_8_REV);
+
+ message.setValueS32("depth", mDepth);
+ message.setValueS32("default_width", mWidth);
+ message.setValueS32("default_height", mHeight);
+ message.setValueU32("internalformat", GL_RGBA8);
+ message.setValueBoolean("coords_opengl", true); // true == use OpenGL-style coordinates, false == (0,0) is upper left.
+ message.setValueBoolean("allow_downsample", true); // we respond with grace and performance if asked to downscale
+ sendMessage(message);
+ }
+ else if(message_name == "idle")
+ {
+ // no response is necessary here.
+ double time = message_in.getValueReal("time");
+
+ // Convert time to milliseconds for update()
+ update((int)(time * 1000.0f));
+ }
+ else if(message_name == "cleanup")
+ {
+ unload();
+ closedown();
+ }
+ else if(message_name == "shm_added")
+ {
+ SharedSegmentInfo info;
+ U64 address_lo = message_in.getValueU32("address");
+ U64 address_hi = message_in.hasValue("address_1") ? message_in.getValueU32("address_1") : 0;
+ info.mAddress = (void*)((address_lo) |
+ (address_hi * (U64(1)<<31)));
+ info.mSize = (size_t)message_in.getValueS32("size");
+ std::string name = message_in.getValue("name");
+
+ std::ostringstream str;
+ INFOMSG("MediaPluginGStreamer010::receiveMessage: shared memory added, name: %s, size: %d, address: %p", name.c_str(), int(info.mSize), info.mAddress);
+
+ mSharedSegments.insert(SharedSegmentMap::value_type(name, info));
+
+ }
+ else if(message_name == "shm_remove")
+ {
+ std::string name = message_in.getValue("name");
+
+ DEBUGMSG("MediaPluginGStreamer010::receiveMessage: shared memory remove, name = %s", name.c_str());
+
+ SharedSegmentMap::iterator iter = mSharedSegments.find(name);
+ if(iter != mSharedSegments.end())
+ {
+ if(mPixels == iter->second.mAddress)
+ {
+ // This is the currently active pixel buffer. Make sure we stop drawing to it.
+ mPixels = NULL;
+ mTextureSegmentName.clear();
+
+ // Make sure the movie decoder is no longer pointed at the shared segment.
+ sizeChanged();
+ }
+ mSharedSegments.erase(iter);
+ }
+ else
+ {
+ WARNMSG("MediaPluginGStreamer010::receiveMessage: unknown shared memory region!");
+ }
+
+ // Send the response so it can be cleaned up.
+ LLPluginMessage message("base", "shm_remove_response");
+ message.setValue("name", name);
+ sendMessage(message);
+ }
+ else
+ {
+ std::ostringstream str;
+ INFOMSG("MediaPluginGStreamer010::receiveMessage: unknown base message: %s", message_name.c_str());
+ }
+ }
+ else if(message_class == LLPLUGIN_MESSAGE_CLASS_MEDIA)
+ {
+ if(message_name == "size_change")
+ {
+ std::string name = message_in.getValue("name");
+ S32 width = message_in.getValueS32("width");
+ S32 height = message_in.getValueS32("height");
+ S32 texture_width = message_in.getValueS32("texture_width");
+ S32 texture_height = message_in.getValueS32("texture_height");
+
+ std::ostringstream str;
+ INFOMSG("---->Got size change instruction from application with shm name: %s - size is %d x %d", name.c_str(), width, height);
+
+ LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "size_change_response");
+ message.setValue("name", name);
+ message.setValueS32("width", width);
+ message.setValueS32("height", height);
+ message.setValueS32("texture_width", texture_width);
+ message.setValueS32("texture_height", texture_height);
+ sendMessage(message);
+
+ if(!name.empty())
+ {
+ // Find the shared memory region with this name
+ SharedSegmentMap::iterator iter = mSharedSegments.find(name);
+ if(iter != mSharedSegments.end())
+ {
+ INFOMSG("*** Got size change with matching shm, new size is %d x %d", width, height);
+ INFOMSG("*** Got size change with matching shm, texture size size is %d x %d", texture_width, texture_height);
+
+ mPixels = (unsigned char*)iter->second.mAddress;
+ mTextureSegmentName = name;
+ mWidth = width;
+ mHeight = height;
+
+ if (texture_width > 1 ||
+ texture_height > 1) // not a dummy size from the app, a real explicit forced size
+ {
+ INFOMSG("**** = REAL RESIZE REQUEST FROM APP");
+
+ GST_OBJECT_LOCK(mVideoSink);
+ mVideoSink->resize_forced = true;
+ mVideoSink->resize_try_width = texture_width;
+ mVideoSink->resize_try_height = texture_height;
+ GST_OBJECT_UNLOCK(mVideoSink);
+ }
+
+ mTextureWidth = texture_width;
+ mTextureHeight = texture_height;
+ }
+ }
+ }
+ else if(message_name == "load_uri")
+ {
+ std::string uri = message_in.getValue("uri");
+ navigateTo( uri );
+ sendStatus();
+ }
+ else if(message_name == "mouse_event")
+ {
+ std::string event = message_in.getValue("event");
+ S32 x = message_in.getValueS32("x");
+ S32 y = message_in.getValueS32("y");
+
+ if(event == "down")
+ {
+ mouseDown(x, y);
+ }
+ else if(event == "up")
+ {
+ mouseUp(x, y);
+ }
+ else if(event == "move")
+ {
+ mouseMove(x, y);
+ };
+ };
+ }
+ else if(message_class == LLPLUGIN_MESSAGE_CLASS_MEDIA_TIME)
+ {
+ if(message_name == "stop")
+ {
+ stop();
+ }
+ else if(message_name == "start")
+ {
+ double rate = 0.0;
+ if(message_in.hasValue("rate"))
+ {
+ rate = message_in.getValueReal("rate");
+ }
+ // NOTE: we don't actually support rate.
+ play(rate);
+ }
+ else if(message_name == "pause")
+ {
+ pause();
+ }
+ else if(message_name == "seek")
+ {
+ double time = message_in.getValueReal("time");
+ // defer the actual seek in case we haven't
+ // really truly started yet in which case there
+ // is nothing to seek upon
+ mSeekWanted = true;
+ mSeekDestination = time;
+ }
+ else if(message_name == "set_loop")
+ {
+ bool loop = message_in.getValueBoolean("loop");
+ mIsLooping = loop;
+ }
+ else if(message_name == "set_volume")
+ {
+ double volume = message_in.getValueReal("volume");
+ setVolume(volume);
+ }
+ }
+ else
+ {
+ INFOMSG("MediaPluginGStreamer010::receiveMessage: unknown message class: %s", message_class.c_str());
+ }
+ }
+}
+
+int init_media_plugin(LLPluginInstance::sendMessageFunction host_send_func, void *host_user_data, LLPluginInstance::sendMessageFunction *plugin_send_func, void **plugin_user_data)
+{
+ if (MediaPluginGStreamer010::startup())
+ {
+ MediaPluginGStreamer010 *self = new MediaPluginGStreamer010(host_send_func, host_user_data);
+ *plugin_send_func = MediaPluginGStreamer010::staticReceiveMessage;
+ *plugin_user_data = (void*)self;
+
+ return 0; // okay
+ }
+ else
+ {
+ return -1; // failed to init
+ }
+}
+
+#else // LL_GSTREAMER010_ENABLED
+
+// Stubbed-out class with constructor/destructor (necessary or windows linker
+// will just think its dead code and optimize it all out)
+class MediaPluginGStreamer010 : public MediaPluginBase
+{
+public:
+ MediaPluginGStreamer010(LLPluginInstance::sendMessageFunction host_send_func, void *host_user_data);
+ ~MediaPluginGStreamer010();
+ /* virtual */ void receiveMessage(const char *message_string);
+};
+
+MediaPluginGStreamer010::MediaPluginGStreamer010(
+ LLPluginInstance::sendMessageFunction host_send_func,
+ void *host_user_data ) :
+ MediaPluginBase(host_send_func, host_user_data)
+{
+ // no-op
+}
+
+MediaPluginGStreamer010::~MediaPluginGStreamer010()
+{
+ // no-op
+}
+
+void MediaPluginGStreamer010::receiveMessage(const char *message_string)
+{
+ // no-op
+}
+
+// We're building without GStreamer enabled. Just refuse to initialize.
+int init_media_plugin(LLPluginInstance::sendMessageFunction host_send_func, void *host_user_data, LLPluginInstance::sendMessageFunction *plugin_send_func, void **plugin_user_data)
+{
+ return -1;
+}
+
+#endif // LL_GSTREAMER010_ENABLED
diff --git a/indra/media_plugins/quicktime/CMakeLists.txt b/indra/media_plugins/quicktime/CMakeLists.txt
new file mode 100644
index 0000000000..db11c9ae21
--- /dev/null
+++ b/indra/media_plugins/quicktime/CMakeLists.txt
@@ -0,0 +1,83 @@
+# -*- cmake -*-
+
+project(media_plugin_quicktime)
+
+include(00-Common)
+include(LLCommon)
+include(LLImage)
+include(LLPlugin)
+include(LLMath)
+include(LLRender)
+include(LLWindow)
+include(Linking)
+include(PluginAPI)
+include(MediaPluginBase)
+include(FindOpenGL)
+include(QuickTimePlugin)
+
+include_directories(
+ ${LLPLUGIN_INCLUDE_DIRS}
+ ${MEDIA_PLUGIN_BASE_INCLUDE_DIRS}
+ ${LLCOMMON_INCLUDE_DIRS}
+ ${LLMATH_INCLUDE_DIRS}
+ ${LLIMAGE_INCLUDE_DIRS}
+ ${LLRENDER_INCLUDE_DIRS}
+ ${LLWINDOW_INCLUDE_DIRS}
+)
+
+if (DARWIN)
+ include(CMakeFindFrameworks)
+ find_library(CARBON_LIBRARY Carbon)
+endif (DARWIN)
+
+
+### media_plugin_quicktime
+
+set(media_plugin_quicktime_SOURCE_FILES
+ media_plugin_quicktime.cpp
+ )
+
+add_library(media_plugin_quicktime
+ SHARED
+ ${media_plugin_quicktime_SOURCE_FILES}
+)
+
+target_link_libraries(media_plugin_quicktime
+ ${LLPLUGIN_LIBRARIES}
+ ${MEDIA_PLUGIN_BASE_LIBRARIES}
+ ${LLCOMMON_LIBRARIES}
+ ${QUICKTIME_LIBRARY}
+ ${PLUGIN_API_WINDOWS_LIBRARIES}
+)
+
+add_dependencies(media_plugin_quicktime
+ ${LLPLUGIN_LIBRARIES}
+ ${MEDIA_PLUGIN_BASE_LIBRARIES}
+ ${LLCOMMON_LIBRARIES}
+)
+
+if (QUICKTIME)
+
+ add_definitions(-DLL_QUICKTIME_ENABLED=1)
+
+ if (DARWIN)
+ # Don't prepend 'lib' to the executable name, and don't embed a full path in the library's install name
+ set_target_properties(
+ media_plugin_quicktime
+ PROPERTIES
+ PREFIX ""
+ BUILD_WITH_INSTALL_RPATH 1
+ INSTALL_NAME_DIR "@executable_path"
+ LINK_FLAGS "-exported_symbols_list ${CMAKE_CURRENT_SOURCE_DIR}/../base/media_plugin_base.exp"
+ )
+
+# We use a bunch of deprecated system APIs.
+ set_source_files_properties(
+ media_plugin_quicktime.cpp PROPERTIES
+ COMPILE_FLAGS -Wno-deprecated-declarations
+ )
+ find_library(CARBON_LIBRARY Carbon)
+ target_link_libraries(media_plugin_quicktime ${CARBON_LIBRARY})
+ endif (DARWIN)
+endif (QUICKTIME)
+
diff --git a/indra/media_plugins/quicktime/media_plugin_quicktime.cpp b/indra/media_plugins/quicktime/media_plugin_quicktime.cpp
new file mode 100644
index 0000000000..e9be458960
--- /dev/null
+++ b/indra/media_plugins/quicktime/media_plugin_quicktime.cpp
@@ -0,0 +1,984 @@
+/**
+ * @file media_plugin_quicktime.cpp
+ * @brief QuickTime plugin for LLMedia API plugin system
+ *
+ * $LicenseInfo:firstyear=2008&license=viewergpl$
+ *
+ * Copyright (c) 2008, Linden Research, Inc.
+ *
+ * Second Life Viewer Source Code
+ * The source code in this file ("Source Code") is provided by Linden Lab
+ * to you under the terms of the GNU General Public License, version 2.0
+ * ("GPL"), unless you have obtained a separate licensing agreement
+ * ("Other License"), formally executed by you and Linden Lab. Terms of
+ * the GPL can be found in doc/GPL-license.txt in this distribution, or
+ * online at http://secondlife.com/developers/opensource/gplv2
+ *
+ * There are special exceptions to the terms and conditions of the GPL as
+ * it is applied to this Source Code. View the full text of the exception
+ * in the file doc/FLOSS-exception.txt in this software distribution, or
+ * online at http://secondlife.com/developers/opensource/flossexception
+ *
+ * By copying, modifying or distributing this software, you acknowledge
+ * that you have read and understood your obligations described above,
+ * and agree to abide by those obligations.
+ *
+ * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+ * COMPLETENESS OR PERFORMANCE.
+ * $/LicenseInfo$
+ */
+
+#include "linden_common.h"
+
+#include "llgl.h"
+
+#include "llplugininstance.h"
+#include "llpluginmessage.h"
+#include "llpluginmessageclasses.h"
+#include "media_plugin_base.h"
+
+#if LL_QUICKTIME_ENABLED
+
+#if defined(LL_DARWIN)
+ #include <QuickTime/QuickTime.h>
+#elif defined(LL_WINDOWS)
+ #include "MacTypes.h"
+ #include "QTML.h"
+ #include "Movies.h"
+ #include "QDoffscreen.h"
+ #include "FixMath.h"
+#endif
+
+// TODO: Make sure that the only symbol exported from this library is LLPluginInitEntryPoint
+////////////////////////////////////////////////////////////////////////////////
+//
+class MediaPluginQuickTime : public MediaPluginBase
+{
+public:
+ MediaPluginQuickTime(LLPluginInstance::sendMessageFunction host_send_func, void *host_user_data);
+ ~MediaPluginQuickTime();
+
+ /* virtual */ void receiveMessage(const char *message_string);
+
+private:
+
+ int mNaturalWidth;
+ int mNaturalHeight;
+ Movie mMovieHandle;
+ GWorldPtr mGWorldHandle;
+ ComponentInstance mMovieController;
+ int mCurVolume;
+ bool mMediaSizeChanging;
+ bool mIsLooping;
+ const int mMinWidth;
+ const int mMaxWidth;
+ const int mMinHeight;
+ const int mMaxHeight;
+ F64 mPlayRate;
+
+ enum ECommand {
+ COMMAND_NONE,
+ COMMAND_STOP,
+ COMMAND_PLAY,
+ COMMAND_FAST_FORWARD,
+ COMMAND_FAST_REWIND,
+ COMMAND_PAUSE,
+ COMMAND_SEEK,
+ };
+ ECommand mCommand;
+
+ // Override this to add current time and duration to the message
+ /*virtual*/ void setDirty(int left, int top, int right, int bottom)
+ {
+ LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "updated");
+
+ message.setValueS32("left", left);
+ message.setValueS32("top", top);
+ message.setValueS32("right", right);
+ message.setValueS32("bottom", bottom);
+
+ if(mMovieHandle)
+ {
+ message.setValueReal("current_time", getCurrentTime());
+ message.setValueReal("duration", getDuration());
+ message.setValueReal("current_rate", Fix2X(GetMovieRate(mMovieHandle)));
+ }
+
+ sendMessage(message);
+ }
+
+
+ static Rect rectFromSize(int width, int height)
+ {
+ Rect result;
+
+
+ result.left = 0;
+ result.top = 0;
+ result.right = width;
+ result.bottom = height;
+
+ return result;
+ }
+
+ Fixed getPlayRate(void)
+ {
+ Fixed result;
+ if(mPlayRate == 0.0f)
+ {
+ // Default to the movie's preferred rate
+ result = GetMoviePreferredRate(mMovieHandle);
+ if(result == 0)
+ {
+ // Don't return a 0 play rate, ever.
+ std::cerr << "Movie's preferred rate is 0, forcing to 1.0." << std::endl;
+ result = X2Fix(1.0f);
+ }
+ }
+ else
+ {
+ result = X2Fix(mPlayRate);
+ }
+
+ return result;
+ }
+
+ void load( const std::string url )
+ {
+ if ( url.empty() )
+ return;
+
+ // Stop and unload any existing movie before starting another one.
+ unload();
+
+ setStatus(STATUS_LOADING);
+
+ //In case std::string::c_str() makes a copy of the url data,
+ //make sure there is memory to hold it before allocating memory for handle.
+ //if fails, NewHandleClear(...) should return NULL.
+ const char* url_string = url.c_str() ;
+ Handle handle = NewHandleClear( ( Size )( url.length() + 1 ) );
+ if ( NULL == handle || noErr != MemError() || NULL == *handle )
+ {
+ setStatus(STATUS_ERROR);
+ return;
+ }
+
+ BlockMove( url_string, *handle, ( Size )( url.length() + 1 ) );
+
+ OSErr err = NewMovieFromDataRef( &mMovieHandle, newMovieActive | newMovieDontInteractWithUser | newMovieAsyncOK | newMovieIdleImportOK, nil, handle, URLDataHandlerSubType );
+ DisposeHandle( handle );
+ if ( noErr != err )
+ {
+ setStatus(STATUS_ERROR);
+ return;
+ };
+
+ // do pre-roll actions (typically fired for streaming movies but not always)
+ PrePrerollMovie( mMovieHandle, 0, getPlayRate(), moviePrePrerollCompleteCallback, ( void * )this );
+
+ Rect movie_rect = rectFromSize(mWidth, mHeight);
+
+ // make a new movie controller
+ mMovieController = NewMovieController( mMovieHandle, &movie_rect, mcNotVisible | mcTopLeftMovie );
+
+ // movie controller
+ MCSetActionFilterWithRefCon( mMovieController, mcActionFilterCallBack, ( long )this );
+
+ SetMoviePlayHints( mMovieHandle, hintsAllowDynamicResize, hintsAllowDynamicResize );
+
+ // function that gets called when a frame is drawn
+ SetMovieDrawingCompleteProc( mMovieHandle, movieDrawingCallWhenChanged, movieDrawingCompleteCallback, ( long )this );
+
+ setStatus(STATUS_LOADED);
+
+ sizeChanged();
+ };
+
+ bool unload()
+ {
+ if ( mMovieHandle )
+ {
+ StopMovie( mMovieHandle );
+ if ( mMovieController )
+ {
+ MCMovieChanged( mMovieController, mMovieHandle );
+ };
+ };
+
+ if ( mMovieController )
+ {
+ MCSetActionFilterWithRefCon( mMovieController, NULL, (long)this );
+ DisposeMovieController( mMovieController );
+ mMovieController = NULL;
+ };
+
+ if ( mMovieHandle )
+ {
+ SetMovieDrawingCompleteProc( mMovieHandle, movieDrawingCallWhenChanged, nil, ( long )this );
+ DisposeMovie( mMovieHandle );
+ mMovieHandle = NULL;
+ };
+
+ if ( mGWorldHandle )
+ {
+ DisposeGWorld( mGWorldHandle );
+ mGWorldHandle = NULL;
+ };
+
+ setStatus(STATUS_NONE);
+
+ return true;
+ }
+
+ bool navigateTo( const std::string url )
+ {
+ unload();
+ load( url );
+
+ return true;
+ };
+
+ bool sizeChanged()
+ {
+ if ( ! mMovieHandle )
+ return false;
+
+ // Check to see whether the movie's natural size has updated
+ {
+ int width, height;
+ getMovieNaturalSize(&width, &height);
+ if((width != 0) && (height != 0) && ((width != mNaturalWidth) || (height != mNaturalHeight)))
+ {
+ mNaturalWidth = width;
+ mNaturalHeight = height;
+
+ LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "size_change_request");
+ message.setValue("name", mTextureSegmentName);
+ message.setValueS32("width", width);
+ message.setValueS32("height", height);
+ sendMessage(message);
+ //std::cerr << "<--- Sending size change request to application with name: " << mTextureSegmentName << " - size is " << width << " x " << height << std::endl;
+ }
+ }
+
+ // sanitize destination size
+ Rect dest_rect = rectFromSize(mWidth, mHeight);
+
+ // media depth won't change
+ int depth_bits = mDepth * 8;
+ long rowbytes = mDepth * mTextureWidth;
+
+ GWorldPtr old_gworld_handle = mGWorldHandle;
+
+ if(mPixels != NULL)
+ {
+ // We have pixels. Set up a GWorld pointing at the texture.
+ OSErr result = NewGWorldFromPtr( &mGWorldHandle, depth_bits, &dest_rect, NULL, NULL, 0, (Ptr)mPixels, rowbytes);
+ if ( noErr != result )
+ {
+ // TODO: unrecoverable?? throw exception? return something?
+ return false;
+ }
+ }
+ else
+ {
+ // We don't have pixels. Create a fake GWorld we can point the movie at when it's not safe to render normally.
+ Rect tempRect = rectFromSize(1, 1);
+ OSErr result = NewGWorld( &mGWorldHandle, depth_bits, &tempRect, NULL, NULL, 0);
+ if ( noErr != result )
+ {
+ // TODO: unrecoverable?? throw exception? return something?
+ return false;
+ }
+ }
+
+ SetMovieGWorld( mMovieHandle, mGWorldHandle, GetGWorldDevice( mGWorldHandle ) );
+
+ // If the GWorld was already set up, delete it.
+ if(old_gworld_handle != NULL)
+ {
+ DisposeGWorld( old_gworld_handle );
+ }
+
+ // Set up the movie display matrix
+ {
+ // scale movie to fit rect and invert vertically to match opengl image format
+ MatrixRecord transform;
+ SetIdentityMatrix( &transform ); // transforms are additive so start from identify matrix
+ double scaleX = (double) mWidth / mNaturalWidth;
+ double scaleY = -1.0 * (double) mHeight / mNaturalHeight;
+ double centerX = mWidth / 2.0;
+ double centerY = mHeight / 2.0;
+ ScaleMatrix( &transform, X2Fix( scaleX ), X2Fix( scaleY ), X2Fix( centerX ), X2Fix( centerY ) );
+ SetMovieMatrix( mMovieHandle, &transform );
+ }
+
+ // update movie controller
+ if ( mMovieController )
+ {
+ MCSetControllerPort( mMovieController, mGWorldHandle );
+ MCPositionController( mMovieController, &dest_rect, &dest_rect,
+ mcTopLeftMovie | mcPositionDontInvalidate );
+ MCMovieChanged( mMovieController, mMovieHandle );
+ }
+
+
+ // Emit event with size change so the calling app knows about it too
+ // TODO:
+ //LLMediaEvent event( this );
+ //mEventEmitter.update( &LLMediaObserver::onMediaSizeChange, event );
+
+ return true;
+ }
+
+ static Boolean mcActionFilterCallBack( MovieController mc, short action, void *params, long ref )
+ {
+ Boolean result = false;
+
+ MediaPluginQuickTime* self = ( MediaPluginQuickTime* )ref;
+
+ switch( action )
+ {
+ // handle window resizing
+ case mcActionControllerSizeChanged:
+ // Ensure that the movie draws correctly at the new size
+ self->sizeChanged();
+ break;
+
+ // Block any movie controller actions that open URLs.
+ case mcActionLinkToURL:
+ case mcActionGetNextURL:
+ case mcActionLinkToURLExtended:
+ // Prevent the movie controller from handling the message
+ result = true;
+ break;
+
+ default:
+ break;
+ };
+
+ return result;
+ };
+
+ static OSErr movieDrawingCompleteCallback( Movie call_back_movie, long ref )
+ {
+ MediaPluginQuickTime* self = ( MediaPluginQuickTime* )ref;
+
+ // IMPORTANT: typically, a consumer who is observing this event will set a flag
+ // when this event is fired then render later. Be aware that the media stream
+ // can change during this period - dimensions, depth, format etc.
+ //LLMediaEvent event( self );
+// self->updateQuickTime();
+ // TODO ^^^
+
+ if ( self->mWidth > 0 && self->mHeight > 0 )
+ self->setDirty( 0, 0, self->mWidth, self->mHeight );
+
+ return noErr;
+ };
+
+ static void moviePrePrerollCompleteCallback( Movie movie, OSErr preroll_err, void *ref )
+ {
+ //MediaPluginQuickTime* self = ( MediaPluginQuickTime* )ref;
+
+ // TODO:
+ //LLMediaEvent event( self );
+ //self->mEventEmitter.update( &LLMediaObserver::onMediaPreroll, event );
+ };
+
+
+ void rewind()
+ {
+ GoToBeginningOfMovie( mMovieHandle );
+ MCMovieChanged( mMovieController, mMovieHandle );
+ };
+
+ bool processState()
+ {
+ if ( mCommand == COMMAND_PLAY )
+ {
+ if ( mStatus == STATUS_LOADED || mStatus == STATUS_PAUSED || mStatus == STATUS_PLAYING )
+ {
+ long state = GetMovieLoadState( mMovieHandle );
+
+ if ( state >= kMovieLoadStatePlaythroughOK )
+ {
+ // if the movie is at the end (generally because it reached it naturally)
+ // and we play is requested, jump back to the start of the movie.
+ // note: this is different from having loop flag set.
+ if ( IsMovieDone( mMovieHandle ) )
+ {
+ Fixed rate = X2Fix( 0.0 );
+ MCDoAction( mMovieController, mcActionPlay, (void*)rate );
+ rewind();
+ };
+
+ MCDoAction( mMovieController, mcActionPrerollAndPlay, (void*)getPlayRate() );
+ MCDoAction( mMovieController, mcActionSetVolume, (void*)mCurVolume );
+ setStatus(STATUS_PLAYING);
+ mCommand = COMMAND_NONE;
+ };
+ };
+ }
+ else
+ if ( mCommand == COMMAND_STOP )
+ {
+ if ( mStatus == STATUS_PLAYING || mStatus == STATUS_PAUSED )
+ {
+ if ( GetMovieLoadState( mMovieHandle ) >= kMovieLoadStatePlaythroughOK )
+ {
+ Fixed rate = X2Fix( 0.0 );
+ MCDoAction( mMovieController, mcActionPlay, (void*)rate );
+ rewind();
+
+ setStatus(STATUS_LOADED);
+ mCommand = COMMAND_NONE;
+ };
+ };
+ }
+ else
+ if ( mCommand == COMMAND_PAUSE )
+ {
+ if ( mStatus == STATUS_PLAYING )
+ {
+ if ( GetMovieLoadState( mMovieHandle ) >= kMovieLoadStatePlaythroughOK )
+ {
+ Fixed rate = X2Fix( 0.0 );
+ MCDoAction( mMovieController, mcActionPlay, (void*)rate );
+ setStatus(STATUS_PAUSED);
+ mCommand = COMMAND_NONE;
+ };
+ };
+ };
+
+ return true;
+ };
+
+ void play(F64 rate)
+ {
+ mPlayRate = rate;
+ mCommand = COMMAND_PLAY;
+ };
+
+ void stop()
+ {
+ mCommand = COMMAND_STOP;
+ };
+
+ void pause()
+ {
+ mCommand = COMMAND_PAUSE;
+ };
+
+ void getMovieNaturalSize(int *movie_width, int *movie_height)
+ {
+ Rect rect;
+
+ GetMovieNaturalBoundsRect( mMovieHandle, &rect );
+
+ int width = ( rect.right - rect.left );
+ int height = ( rect.bottom - rect.top );
+
+ // make sure width and height fall in valid range
+ if ( width < mMinWidth )
+ width = mMinWidth;
+
+ if ( width > mMaxWidth )
+ width = mMaxWidth;
+
+ if ( height < mMinHeight )
+ height = mMinHeight;
+
+ if ( height > mMaxHeight )
+ height = mMaxHeight;
+
+ // return the new rect
+ *movie_width = width;
+ *movie_height = height;
+ }
+
+ void updateQuickTime(int milliseconds)
+ {
+ if ( ! mMovieHandle )
+ return;
+
+ if ( ! mMovieController )
+ return;
+
+ // service QuickTime
+ // Calling it this way doesn't have good behavior on Windows...
+// MoviesTask( mMovieHandle, milliseconds );
+ // This was the original, but I think using both MoviesTask and MCIdle is redundant. Trying with only MCIdle.
+// MoviesTask( mMovieHandle, 0 );
+
+ MCIdle( mMovieController );
+
+ if ( ! mGWorldHandle )
+ return;
+
+ if ( mMediaSizeChanging )
+ return;
+
+ // update state machine
+ processState();
+
+ // special code for looping - need to rewind at the end of the movie
+ if ( mIsLooping )
+ {
+ // QT call to see if we are at the end - can't do with controller
+ if ( IsMovieDone( mMovieHandle ) )
+ {
+ // go back to start
+ rewind();
+
+ if ( mMovieController )
+ {
+ // kick off new play
+ MCDoAction( mMovieController, mcActionPrerollAndPlay, (void*)getPlayRate() );
+
+ // set the volume
+ MCDoAction( mMovieController, mcActionSetVolume, (void*)mCurVolume );
+ };
+ };
+ };
+ };
+
+ int getDataWidth() const
+ {
+ if ( mGWorldHandle )
+ {
+ int depth = mDepth;
+
+ if (depth < 1)
+ depth = 1;
+
+ // ALWAYS use the row bytes from the PixMap if we have a GWorld because
+ // sometimes it's not the same as mMediaDepth * mMediaWidth !
+ PixMapHandle pix_map_handle = GetGWorldPixMap( mGWorldHandle );
+ return QTGetPixMapHandleRowBytes( pix_map_handle ) / depth;
+ }
+ else
+ {
+ // TODO : return LLMediaImplCommon::getaDataWidth();
+ return 0;
+ }
+ };
+
+ void seek( F64 time )
+ {
+ if ( mMovieController )
+ {
+ TimeRecord when;
+ when.scale = GetMovieTimeScale( mMovieHandle );
+ when.base = 0;
+
+ // 'time' is in (floating point) seconds. The timebase time will be in 'units', where
+ // there are 'scale' units per second.
+ SInt64 raw_time = ( SInt64 )( time * (double)( when.scale ) );
+
+ when.value.hi = ( SInt32 )( raw_time >> 32 );
+ when.value.lo = ( SInt32 )( ( raw_time & 0x00000000FFFFFFFF ) );
+
+ MCDoAction( mMovieController, mcActionGoToTime, &when );
+ };
+ };
+
+ F64 getDuration()
+ {
+ TimeValue duration = GetMovieDuration( mMovieHandle );
+ TimeValue scale = GetMovieTimeScale( mMovieHandle );
+
+ return (F64)duration / (F64)scale;
+ };
+
+ F64 getCurrentTime()
+ {
+ TimeValue curr_time = GetMovieTime( mMovieHandle, 0 );
+ TimeValue scale = GetMovieTimeScale( mMovieHandle );
+
+ return (F64)curr_time / (F64)scale;
+ };
+
+ void setVolume( F64 volume )
+ {
+ mCurVolume = (short)(volume * ( double ) 0x100 );
+
+ if ( mMovieController )
+ {
+ MCDoAction( mMovieController, mcActionSetVolume, (void*)mCurVolume );
+ };
+ };
+
+ ////////////////////////////////////////////////////////////////////////////////
+ //
+ void update(int milliseconds = 0)
+ {
+ updateQuickTime(milliseconds);
+ };
+
+ ////////////////////////////////////////////////////////////////////////////////
+ //
+ void mouseDown( int x, int y )
+ {
+ };
+
+ ////////////////////////////////////////////////////////////////////////////////
+ //
+ void mouseUp( int x, int y )
+ {
+ };
+
+ ////////////////////////////////////////////////////////////////////////////////
+ //
+ void mouseMove( int x, int y )
+ {
+ };
+
+ ////////////////////////////////////////////////////////////////////////////////
+ //
+ void keyPress( unsigned char key )
+ {
+ };
+
+};
+
+MediaPluginQuickTime::MediaPluginQuickTime(
+ LLPluginInstance::sendMessageFunction host_send_func,
+ void *host_user_data ) :
+ MediaPluginBase(host_send_func, host_user_data),
+ mMinWidth( 0 ),
+ mMaxWidth( 2048 ),
+ mMinHeight( 0 ),
+ mMaxHeight( 2048 )
+{
+// std::cerr << "MediaPluginQuickTime constructor" << std::endl;
+
+ mNaturalWidth = -1;
+ mNaturalHeight = -1;
+ mMovieHandle = 0;
+ mGWorldHandle = 0;
+ mMovieController = 0;
+ mCurVolume = 0x99;
+ mMediaSizeChanging = false;
+ mIsLooping = false;
+ mCommand = COMMAND_NONE;
+ mPlayRate = 0.0f;
+ mStatus = STATUS_NONE;
+}
+
+MediaPluginQuickTime::~MediaPluginQuickTime()
+{
+// std::cerr << "MediaPluginQuickTime destructor" << std::endl;
+
+ ExitMovies();
+
+#ifdef LL_WINDOWS
+ TerminateQTML();
+// std::cerr << "QuickTime closing down" << std::endl;
+#endif
+}
+
+
+void MediaPluginQuickTime::receiveMessage(const char *message_string)
+{
+// std::cerr << "MediaPluginQuickTime::receiveMessage: received message: \"" << message_string << "\"" << std::endl;
+ LLPluginMessage message_in;
+
+ if(message_in.parse(message_string) >= 0)
+ {
+ std::string message_class = message_in.getClass();
+ std::string message_name = message_in.getName();
+ if(message_class == LLPLUGIN_MESSAGE_CLASS_BASE)
+ {
+ if(message_name == "init")
+ {
+ LLPluginMessage message("base", "init_response");
+ LLSD versions = LLSD::emptyMap();
+ versions[LLPLUGIN_MESSAGE_CLASS_BASE] = LLPLUGIN_MESSAGE_CLASS_BASE_VERSION;
+ versions[LLPLUGIN_MESSAGE_CLASS_MEDIA] = LLPLUGIN_MESSAGE_CLASS_MEDIA_VERSION;
+ // Normally a plugin would only specify one of these two subclasses, but this is a demo...
+// versions[LLPLUGIN_MESSAGE_CLASS_MEDIA_BROWSER] = LLPLUGIN_MESSAGE_CLASS_MEDIA_BROWSER_VERSION;
+ versions[LLPLUGIN_MESSAGE_CLASS_MEDIA_TIME] = LLPLUGIN_MESSAGE_CLASS_MEDIA_TIME_VERSION;
+ message.setValueLLSD("versions", versions);
+
+ #ifdef LL_WINDOWS
+ if ( InitializeQTML( 0L ) != noErr )
+ {
+ //TODO: If no QT on Windows, this fails - respond accordingly.
+ //return false;
+ }
+ else
+ {
+// std::cerr << "QuickTime initialized" << std::endl;
+ };
+ #endif
+
+ EnterMovies();
+
+ std::string plugin_version = "QuickTime media plugin, QuickTime version ";
+
+ long version = 0;
+ Gestalt( gestaltQuickTimeVersion, &version );
+ std::ostringstream codec( "" );
+ codec << std::hex << version << std::dec;
+ plugin_version += codec.str();
+ message.setValue("plugin_version", plugin_version);
+ sendMessage(message);
+
+ // Plugin gets to decide the texture parameters to use.
+ message.setMessage(LLPLUGIN_MESSAGE_CLASS_MEDIA, "texture_params");
+ #if defined(LL_WINDOWS)
+ // Values for Windows
+ mDepth = 3;
+ message.setValueU32("format", GL_RGB);
+ message.setValueU32("type", GL_UNSIGNED_BYTE);
+
+ // We really want to pad the texture width to a multiple of 32 bytes, but since we're using 3-byte pixels, it doesn't come out even.
+ // Padding to a multiple of 3*32 guarantees it'll divide out properly.
+ message.setValueU32("padding", 32 * 3);
+ #else
+ // Values for Mac
+ mDepth = 4;
+ message.setValueU32("format", GL_BGRA_EXT);
+ #ifdef __BIG_ENDIAN__
+ message.setValueU32("type", GL_UNSIGNED_INT_8_8_8_8_REV );
+ #else
+ message.setValueU32("type", GL_UNSIGNED_INT_8_8_8_8);
+ #endif
+
+ // Pad texture width to a multiple of 32 bytes, to line up with cache lines.
+ message.setValueU32("padding", 32);
+ #endif
+ message.setValueS32("depth", mDepth);
+ message.setValueU32("internalformat", GL_RGB);
+ message.setValueBoolean("coords_opengl", true); // true == use OpenGL-style coordinates, false == (0,0) is upper left.
+ message.setValueBoolean("allow_downsample", true);
+ sendMessage(message);
+ }
+ else if(message_name == "idle")
+ {
+ // no response is necessary here.
+ F64 time = message_in.getValueReal("time");
+
+ // Convert time to milliseconds for update()
+ update((int)(time * 1000.0f));
+ }
+ else if(message_name == "cleanup")
+ {
+ // TODO: clean up here
+ }
+ else if(message_name == "shm_added")
+ {
+ SharedSegmentInfo info;
+ U64 address_lo = message_in.getValueU32("address");
+ U64 address_hi = message_in.hasValue("address_1") ? message_in.getValueU32("address_1") : 0;
+ info.mAddress = (void*)((address_lo) |
+ (address_hi * (U64(1)<<31)));
+ info.mSize = (size_t)message_in.getValueS32("size");
+ std::string name = message_in.getValue("name");
+
+
+// std::cerr << "MediaPluginQuickTime::receiveMessage: shared memory added, name: " << name
+// << ", size: " << info.mSize
+// << ", address: " << info.mAddress
+// << std::endl;
+
+ mSharedSegments.insert(SharedSegmentMap::value_type(name, info));
+
+ }
+ else if(message_name == "shm_remove")
+ {
+ std::string name = message_in.getValue("name");
+
+// std::cerr << "MediaPluginQuickTime::receiveMessage: shared memory remove, name = " << name << std::endl;
+
+ SharedSegmentMap::iterator iter = mSharedSegments.find(name);
+ if(iter != mSharedSegments.end())
+ {
+ if(mPixels == iter->second.mAddress)
+ {
+ // This is the currently active pixel buffer. Make sure we stop drawing to it.
+ mPixels = NULL;
+ mTextureSegmentName.clear();
+
+ // Make sure the movie GWorld is no longer pointed at the shared segment.
+ sizeChanged();
+ }
+ mSharedSegments.erase(iter);
+ }
+ else
+ {
+// std::cerr << "MediaPluginQuickTime::receiveMessage: unknown shared memory region!" << std::endl;
+ }
+
+ // Send the response so it can be cleaned up.
+ LLPluginMessage message("base", "shm_remove_response");
+ message.setValue("name", name);
+ sendMessage(message);
+ }
+ else
+ {
+// std::cerr << "MediaPluginQuickTime::receiveMessage: unknown base message: " << message_name << std::endl;
+ }
+ }
+ else if(message_class == LLPLUGIN_MESSAGE_CLASS_MEDIA)
+ {
+ if(message_name == "size_change")
+ {
+ std::string name = message_in.getValue("name");
+ S32 width = message_in.getValueS32("width");
+ S32 height = message_in.getValueS32("height");
+ S32 texture_width = message_in.getValueS32("texture_width");
+ S32 texture_height = message_in.getValueS32("texture_height");
+
+ //std::cerr << "---->Got size change instruction from application with name: " << name << " - size is " << width << " x " << height << std::endl;
+
+ LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "size_change_response");
+ message.setValue("name", name);
+ message.setValueS32("width", width);
+ message.setValueS32("height", height);
+ message.setValueS32("texture_width", texture_width);
+ message.setValueS32("texture_height", texture_height);
+ sendMessage(message);
+
+ if(!name.empty())
+ {
+ // Find the shared memory region with this name
+ SharedSegmentMap::iterator iter = mSharedSegments.find(name);
+ if(iter != mSharedSegments.end())
+ {
+// std::cerr << "%%% Got size change, new size is " << width << " by " << height << std::endl;
+// std::cerr << "%%%% texture size is " << texture_width << " by " << texture_height << std::endl;
+
+ mPixels = (unsigned char*)iter->second.mAddress;
+ mTextureSegmentName = name;
+ mWidth = width;
+ mHeight = height;
+
+ mTextureWidth = texture_width;
+ mTextureHeight = texture_height;
+
+ mMediaSizeChanging = false;
+
+ sizeChanged();
+
+ update();
+ };
+ };
+ }
+ else if(message_name == "load_uri")
+ {
+ std::string uri = message_in.getValue("uri");
+ load( uri );
+ sendStatus();
+ }
+ else if(message_name == "mouse_event")
+ {
+ std::string event = message_in.getValue("event");
+ S32 x = message_in.getValueS32("x");
+ S32 y = message_in.getValueS32("y");
+
+ if(event == "down")
+ {
+ mouseDown(x, y);
+ }
+ else if(event == "up")
+ {
+ mouseUp(x, y);
+ }
+ else if(event == "move")
+ {
+ mouseMove(x, y);
+ };
+ };
+ }
+ else if(message_class == LLPLUGIN_MESSAGE_CLASS_MEDIA_TIME)
+ {
+ if(message_name == "stop")
+ {
+ stop();
+ }
+ else if(message_name == "start")
+ {
+ F64 rate = 0.0;
+ if(message_in.hasValue("rate"))
+ {
+ rate = message_in.getValueReal("rate");
+ }
+ play(rate);
+ }
+ else if(message_name == "pause")
+ {
+ pause();
+ }
+ else if(message_name == "seek")
+ {
+ F64 time = message_in.getValueReal("time");
+ seek(time);
+ }
+ else if(message_name == "set_loop")
+ {
+ bool loop = message_in.getValueBoolean("loop");
+ mIsLooping = loop;
+ }
+ else if(message_name == "set_volume")
+ {
+ F64 volume = message_in.getValueReal("volume");
+ setVolume(volume);
+ }
+ }
+ else
+ {
+// std::cerr << "MediaPluginQuickTime::receiveMessage: unknown message class: " << message_class << std::endl;
+ };
+ };
+}
+
+int init_media_plugin(LLPluginInstance::sendMessageFunction host_send_func, void *host_user_data, LLPluginInstance::sendMessageFunction *plugin_send_func, void **plugin_user_data)
+{
+ MediaPluginQuickTime *self = new MediaPluginQuickTime(host_send_func, host_user_data);
+ *plugin_send_func = MediaPluginQuickTime::staticReceiveMessage;
+ *plugin_user_data = (void*)self;
+
+ return 0;
+}
+
+#else // LL_QUICKTIME_ENABLED
+
+// Stubbed-out class with constructor/destructor (necessary or windows linker
+// will just think its dead code and optimize it all out)
+class MediaPluginQuickTime : public MediaPluginBase
+{
+public:
+ MediaPluginQuickTime(LLPluginInstance::sendMessageFunction host_send_func, void *host_user_data);
+ ~MediaPluginQuickTime();
+ /* virtual */ void receiveMessage(const char *message_string);
+};
+
+MediaPluginQuickTime::MediaPluginQuickTime(
+ LLPluginInstance::sendMessageFunction host_send_func,
+ void *host_user_data ) :
+ MediaPluginBase(host_send_func, host_user_data)
+{
+ // no-op
+}
+
+MediaPluginQuickTime::~MediaPluginQuickTime()
+{
+ // no-op
+}
+
+void MediaPluginQuickTime::receiveMessage(const char *message_string)
+{
+ // no-op
+}
+
+// We're building without quicktime enabled. Just refuse to initialize.
+int init_media_plugin(LLPluginInstance::sendMessageFunction host_send_func, void *host_user_data, LLPluginInstance::sendMessageFunction *plugin_send_func, void **plugin_user_data)
+{
+ return -1;
+}
+
+#endif // LL_QUICKTIME_ENABLED
diff --git a/indra/media_plugins/webkit/CMakeLists.txt b/indra/media_plugins/webkit/CMakeLists.txt
new file mode 100644
index 0000000000..d96477279d
--- /dev/null
+++ b/indra/media_plugins/webkit/CMakeLists.txt
@@ -0,0 +1,74 @@
+# -*- cmake -*-
+
+project(media_plugin_webkit)
+
+include(00-Common)
+include(LLCommon)
+include(LLImage)
+include(LLPlugin)
+include(LLMath)
+include(LLRender)
+include(LLWindow)
+include(Linking)
+include(PluginAPI)
+include(MediaPluginBase)
+include(FindOpenGL)
+
+include(WebKitLibPlugin)
+
+include_directories(
+ ${LLPLUGIN_INCLUDE_DIRS}
+ ${MEDIA_PLUGIN_BASE_INCLUDE_DIRS}
+ ${LLCOMMON_INCLUDE_DIRS}
+ ${LLMATH_INCLUDE_DIRS}
+ ${LLIMAGE_INCLUDE_DIRS}
+ ${LLRENDER_INCLUDE_DIRS}
+ ${LLWINDOW_INCLUDE_DIRS}
+)
+
+
+### media_plugin_webkit
+
+set(media_plugin_webkit_SOURCE_FILES
+ media_plugin_webkit.cpp
+ )
+
+add_library(media_plugin_webkit
+ SHARED
+ ${media_plugin_webkit_SOURCE_FILES}
+)
+
+target_link_libraries(media_plugin_webkit
+ ${LLPLUGIN_LIBRARIES}
+ ${MEDIA_PLUGIN_BASE_LIBRARIES}
+ ${LLCOMMON_LIBRARIES}
+ ${WEBKIT_PLUGIN_LIBRARIES}
+ ${PLUGIN_API_WINDOWS_LIBRARIES}
+)
+
+add_dependencies(media_plugin_webkit
+ ${LLPLUGIN_LIBRARIES}
+ ${MEDIA_PLUGIN_BASE_LIBRARIES}
+ ${LLCOMMON_LIBRARIES}
+)
+
+if (DARWIN)
+ # Don't prepend 'lib' to the executable name, and don't embed a full path in the library's install name
+ set_target_properties(
+ media_plugin_webkit
+ PROPERTIES
+ PREFIX ""
+ BUILD_WITH_INSTALL_RPATH 1
+ INSTALL_NAME_DIR "@executable_path"
+ LINK_FLAGS "-exported_symbols_list ${CMAKE_CURRENT_SOURCE_DIR}/../base/media_plugin_base.exp"
+ )
+
+ # copy the webkit dylib to the build directory
+ add_custom_command(
+ TARGET media_plugin_webkit POST_BUILD
+# OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/libllqtwebkit.dylib
+ COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_SOURCE_DIR}/../libraries/universal-darwin/lib_release/libllqtwebkit.dylib ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/
+ DEPENDS media_plugin_webkit ${CMAKE_SOURCE_DIR}/../libraries/universal-darwin/lib_release/libllqtwebkit.dylib
+ )
+
+endif (DARWIN) \ No newline at end of file
diff --git a/indra/media_plugins/webkit/media_plugin_webkit.cpp b/indra/media_plugins/webkit/media_plugin_webkit.cpp
new file mode 100644
index 0000000000..2928b7e6b3
--- /dev/null
+++ b/indra/media_plugins/webkit/media_plugin_webkit.cpp
@@ -0,0 +1,792 @@
+/**
+ * @file media_plugin_webkit.cpp
+ * @brief Webkit plugin for LLMedia API plugin system
+ *
+ * $LicenseInfo:firstyear=2008&license=viewergpl$
+ *
+ * Copyright (c) 2008, Linden Research, Inc.
+ *
+ * Second Life Viewer Source Code
+ * The source code in this file ("Source Code") is provided by Linden Lab
+ * to you under the terms of the GNU General Public License, version 2.0
+ * ("GPL"), unless you have obtained a separate licensing agreement
+ * ("Other License"), formally executed by you and Linden Lab. Terms of
+ * the GPL can be found in doc/GPL-license.txt in this distribution, or
+ * online at http://secondlife.com/developers/opensource/gplv2
+ *
+ * There are special exceptions to the terms and conditions of the GPL as
+ * it is applied to this Source Code. View the full text of the exception
+ * in the file doc/FLOSS-exception.txt in this software distribution, or
+ * online at http://secondlife.com/developers/opensource/flossexception
+ *
+ * By copying, modifying or distributing this software, you acknowledge
+ * that you have read and understood your obligations described above,
+ * and agree to abide by those obligations.
+ *
+ * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+ * COMPLETENESS OR PERFORMANCE.
+ * $/LicenseInfo$
+ */
+
+#include "llqtwebkit.h"
+
+#include "linden_common.h"
+#include "indra_constants.h" // for indra keyboard codes
+
+#include "llgl.h"
+
+#include "llplugininstance.h"
+#include "llpluginmessage.h"
+#include "llpluginmessageclasses.h"
+#include "media_plugin_base.h"
+
+#if LL_WINDOWS
+#include <direct.h>
+#else
+#include <unistd.h>
+#include <stdlib.h>
+#endif
+
+////////////////////////////////////////////////////////////////////////////////
+//
+class MediaPluginWebKit :
+ public MediaPluginBase,
+ public LLEmbeddedBrowserWindowObserver
+{
+public:
+ MediaPluginWebKit(LLPluginInstance::sendMessageFunction host_send_func, void *host_user_data);
+ ~MediaPluginWebKit();
+
+ /*virtual*/ void receiveMessage(const char *message_string);
+
+private:
+
+ int mBrowserWindowId;
+ bool mBrowserInitialized;
+ bool mNeedsUpdate;
+
+ bool mCanCut;
+ bool mCanCopy;
+ bool mCanPaste;
+
+ ////////////////////////////////////////////////////////////////////////////////
+ //
+ void update(int milliseconds)
+ {
+ LLQtWebKit::getInstance()->pump( milliseconds );
+
+ checkEditState();
+
+ if ( mNeedsUpdate )
+ {
+ const unsigned char* browser_pixels = LLQtWebKit::getInstance()->grabBrowserWindow( mBrowserWindowId );
+
+ unsigned int buffer_size = LLQtWebKit::getInstance()->getBrowserRowSpan( mBrowserWindowId ) * LLQtWebKit::getInstance()->getBrowserHeight( mBrowserWindowId );
+
+// std::cerr << "webkit plugin: updating" << std::endl;
+
+ // TODO: should get rid of this memcpy if possible
+ if ( mPixels && browser_pixels )
+ {
+// std::cerr << " memcopy of " << buffer_size << " bytes" << std::endl;
+ memcpy( mPixels, browser_pixels, buffer_size );
+ }
+
+ if ( mWidth > 0 && mHeight > 0 )
+ {
+// std::cerr << "Setting dirty, " << mWidth << " x " << mHeight << std::endl;
+ setDirty( 0, 0, mWidth, mHeight );
+ }
+
+ mNeedsUpdate = false;
+ };
+ };
+
+ ////////////////////////////////////////////////////////////////////////////////
+ //
+ bool initBrowser()
+ {
+ // already initialized
+ if ( mBrowserInitialized )
+ return true;
+
+ // not enough information to initialize the browser yet.
+ if ( mWidth < 0 || mHeight < 0 || mDepth < 0 ||
+ mTextureWidth < 0 || mTextureHeight < 0 )
+ {
+ return false;
+ };
+
+ // set up directories
+ char cwd[ FILENAME_MAX ]; // I *think* this is defined on all platforms we use
+ if (NULL == getcwd( cwd, FILENAME_MAX - 1 ))
+ {
+ llwarns << "Couldn't get cwd - probably too long - failing to init." << llendl;
+ return false;
+ }
+ std::string application_dir = std::string( cwd );
+ std::string component_dir = application_dir;
+ std::string profileDir = application_dir + "/" + "browser_profile"; // cross platform?
+
+ // window handle - needed on Windows and must be app window.
+#if LL_WINDOWS
+ char window_title[ MAX_PATH ];
+ GetConsoleTitleA( window_title, MAX_PATH );
+ void* native_window_handle = (void*)FindWindowA( NULL, window_title );
+#else
+ void* native_window_handle = 0;
+#endif
+
+ // main browser initialization
+ bool result = LLQtWebKit::getInstance()->init( application_dir, component_dir, profileDir, native_window_handle );
+ if ( result )
+ {
+ // create single browser window
+ mBrowserWindowId = LLQtWebKit::getInstance()->createBrowserWindow( mWidth, mHeight );
+
+#if LL_WINDOWS
+ // Enable plugins
+ LLQtWebKit::getInstance()->enablePlugins(true);
+#else
+ // Disable plugins
+ LLQtWebKit::getInstance()->enablePlugins(false);
+#endif
+
+ // tell LLQtWebKit about the size of the browser window
+ LLQtWebKit::getInstance()->setSize( mBrowserWindowId, mWidth, mHeight );
+
+ // observer events that LLQtWebKit emits
+ LLQtWebKit::getInstance()->addObserver( mBrowserWindowId, this );
+
+ // append details to agent string
+ LLQtWebKit::getInstance()->setBrowserAgentId( "LLPluginMedia Web Browser" );
+
+ // don't flip bitmap
+ LLQtWebKit::getInstance()->flipWindow( mBrowserWindowId, true );
+
+ // go to the "home page"
+ // Don't do this here -- it causes the dreaded "white flash" when loading a browser instance.
+// LLQtWebKit::getInstance()->navigateTo( mBrowserWindowId, "about:blank" );
+
+ // set flag so we don't do this again
+ mBrowserInitialized = true;
+
+ return true;
+ };
+
+ return false;
+ };
+
+ ////////////////////////////////////////////////////////////////////////////////
+ // virtual
+ void onCursorChanged(const EventType& event)
+ {
+ LLQtWebKit::ECursor llqt_cursor = (LLQtWebKit::ECursor)event.getIntValue();
+ std::string name;
+
+ switch(llqt_cursor)
+ {
+ case LLQtWebKit::C_ARROW:
+ name = "arrow";
+ break;
+ case LLQtWebKit::C_IBEAM:
+ name = "ibeam";
+ break;
+ case LLQtWebKit::C_SPLITV:
+ name = "splitv";
+ break;
+ case LLQtWebKit::C_SPLITH:
+ name = "splith";
+ break;
+ case LLQtWebKit::C_POINTINGHAND:
+ name = "hand";
+ break;
+
+ default:
+ llwarns << "Unknown cursor ID: " << (int)llqt_cursor << llendl;
+ break;
+ }
+
+ LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "cursor_changed");
+ message.setValue("name", name);
+ sendMessage(message);
+ }
+
+ ////////////////////////////////////////////////////////////////////////////////
+ // virtual
+ void onPageChanged( const EventType& event )
+ {
+ // flag that an update is required
+ mNeedsUpdate = true;
+ };
+
+ ////////////////////////////////////////////////////////////////////////////////
+ // virtual
+ void onNavigateBegin(const EventType& event)
+ {
+ LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA_BROWSER, "navigate_begin");
+ message.setValue("uri", event.getEventUri());
+ sendMessage(message);
+
+ setStatus(STATUS_LOADING);
+ }
+
+ ////////////////////////////////////////////////////////////////////////////////
+ // virtual
+ void onNavigateComplete(const EventType& event)
+ {
+ LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA_BROWSER, "navigate_complete");
+ message.setValue("uri", event.getEventUri());
+ message.setValueS32("result_code", event.getIntValue());
+ message.setValue("result_string", event.getStringValue());
+ message.setValueBoolean("history_back_available", LLQtWebKit::getInstance()->userActionIsEnabled( mBrowserWindowId, LLQtWebKit::UA_NAVIGATE_BACK));
+ message.setValueBoolean("history_forward_available", LLQtWebKit::getInstance()->userActionIsEnabled( mBrowserWindowId, LLQtWebKit::UA_NAVIGATE_FORWARD));
+ sendMessage(message);
+
+ setStatus(STATUS_LOADED);
+ }
+
+ ////////////////////////////////////////////////////////////////////////////////
+ // virtual
+ void onUpdateProgress(const EventType& event)
+ {
+ LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA_BROWSER, "progress");
+ message.setValueS32("percent", event.getIntValue());
+ sendMessage(message);
+ }
+
+ ////////////////////////////////////////////////////////////////////////////////
+ // virtual
+ void onStatusTextChange(const EventType& event)
+ {
+ LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA_BROWSER, "status_text");
+ message.setValue("status", event.getStringValue());
+ sendMessage(message);
+ }
+
+ ////////////////////////////////////////////////////////////////////////////////
+ // virtual
+ void onLocationChange(const EventType& event)
+ {
+ LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA_BROWSER, "location_changed");
+ message.setValue("uri", event.getEventUri());
+ sendMessage(message);
+ }
+
+ ////////////////////////////////////////////////////////////////////////////////
+ // virtual
+ void onClickLinkHref(const EventType& event)
+ {
+ LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA_BROWSER, "click_href");
+ message.setValue("uri", event.getStringValue());
+ message.setValue("target", event.getStringValue2());
+ sendMessage(message);
+ }
+
+ ////////////////////////////////////////////////////////////////////////////////
+ // virtual
+ void onClickLinkNoFollow(const EventType& event)
+ {
+ LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA_BROWSER, "click_nofollow");
+ message.setValue("uri", event.getStringValue());
+ sendMessage(message);
+ }
+
+ ////////////////////////////////////////////////////////////////////////////////
+ //
+ void mouseDown( int x, int y )
+ {
+ LLQtWebKit::getInstance()->mouseDown( mBrowserWindowId, x, y );
+ };
+
+ ////////////////////////////////////////////////////////////////////////////////
+ //
+ void mouseUp( int x, int y )
+ {
+ LLQtWebKit::getInstance()->mouseUp( mBrowserWindowId, x, y );
+ LLQtWebKit::getInstance()->focusBrowser( mBrowserWindowId, true );
+ checkEditState();
+ };
+
+ ////////////////////////////////////////////////////////////////////////////////
+ //
+ void mouseMove( int x, int y )
+ {
+ LLQtWebKit::getInstance()->mouseMove( mBrowserWindowId, x, y );
+ };
+
+ ////////////////////////////////////////////////////////////////////////////////
+ //
+ void keyPress( int key )
+ {
+ int llqt_key;
+
+ // The incoming values for 'key' will be the ones from indra_constants.h
+ // the outgoing values are the ones from llqtwebkit.h
+
+ switch((KEY)key)
+ {
+ // This is the list that the llqtwebkit implementation actually maps into Qt keys.
+// case KEY_XXX: llqt_key = LL_DOM_VK_CANCEL; break;
+// case KEY_XXX: llqt_key = LL_DOM_VK_HELP; break;
+ case KEY_BACKSPACE: llqt_key = LL_DOM_VK_BACK_SPACE; break;
+ case KEY_TAB: llqt_key = LL_DOM_VK_TAB; break;
+// case KEY_XXX: llqt_key = LL_DOM_VK_CLEAR; break;
+ case KEY_RETURN: llqt_key = LL_DOM_VK_RETURN; break;
+ case KEY_PAD_RETURN: llqt_key = LL_DOM_VK_ENTER; break;
+ case KEY_SHIFT: llqt_key = LL_DOM_VK_SHIFT; break;
+ case KEY_CONTROL: llqt_key = LL_DOM_VK_CONTROL; break;
+ case KEY_ALT: llqt_key = LL_DOM_VK_ALT; break;
+// case KEY_XXX: llqt_key = LL_DOM_VK_PAUSE; break;
+ case KEY_CAPSLOCK: llqt_key = LL_DOM_VK_CAPS_LOCK; break;
+ case KEY_ESCAPE: llqt_key = LL_DOM_VK_ESCAPE; break;
+ case KEY_PAGE_UP: llqt_key = LL_DOM_VK_PAGE_UP; break;
+ case KEY_PAGE_DOWN: llqt_key = LL_DOM_VK_PAGE_DOWN; break;
+ case KEY_END: llqt_key = LL_DOM_VK_END; break;
+ case KEY_HOME: llqt_key = LL_DOM_VK_HOME; break;
+ case KEY_LEFT: llqt_key = LL_DOM_VK_LEFT; break;
+ case KEY_UP: llqt_key = LL_DOM_VK_UP; break;
+ case KEY_RIGHT: llqt_key = LL_DOM_VK_RIGHT; break;
+ case KEY_DOWN: llqt_key = LL_DOM_VK_DOWN; break;
+// case KEY_XXX: llqt_key = LL_DOM_VK_PRINTSCREEN; break;
+ case KEY_INSERT: llqt_key = LL_DOM_VK_INSERT; break;
+ case KEY_DELETE: llqt_key = LL_DOM_VK_DELETE; break;
+// case KEY_XXX: llqt_key = LL_DOM_VK_CONTEXT_MENU; break;
+
+ default:
+ if(key < KEY_SPECIAL)
+ {
+ // Pass the incoming key through -- it should be regular ASCII, which should be correct for webkit.
+ llqt_key = key;
+ }
+ else
+ {
+ // Don't pass through untranslated special keys -- they'll be all wrong.
+ llqt_key = 0;
+ }
+ break;
+ }
+
+// std::cerr << "keypress, original code = 0x" << std::hex << key << ", converted code = 0x" << std::hex << llqt_key << std::dec << std::endl;
+
+ if(llqt_key != 0)
+ {
+ LLQtWebKit::getInstance()->keyPress( mBrowserWindowId, llqt_key );
+ }
+
+ checkEditState();
+ };
+
+ ////////////////////////////////////////////////////////////////////////////////
+ //
+ void unicodeInput( const std::string &utf8str )
+ {
+ LLWString wstr = utf8str_to_wstring(utf8str);
+
+ unsigned int i;
+ for(i=0; i < wstr.size(); i++)
+ {
+// std::cerr << "unicode input, code = 0x" << std::hex << (unsigned long)(wstr[i]) << std::dec << std::endl;
+
+ LLQtWebKit::getInstance()->unicodeInput(mBrowserWindowId, wstr[i]);
+ }
+
+ checkEditState();
+ };
+
+ void checkEditState(void)
+ {
+ bool can_cut = LLQtWebKit::getInstance()->userActionIsEnabled( mBrowserWindowId, LLQtWebKit::UA_EDIT_CUT);
+ bool can_copy = LLQtWebKit::getInstance()->userActionIsEnabled( mBrowserWindowId, LLQtWebKit::UA_EDIT_COPY);
+ bool can_paste = LLQtWebKit::getInstance()->userActionIsEnabled( mBrowserWindowId, LLQtWebKit::UA_EDIT_PASTE);
+
+ if((can_cut != mCanCut) || (can_copy != mCanCopy) || (can_paste != mCanPaste))
+ {
+ LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "edit_state");
+
+ if(can_cut != mCanCut)
+ {
+ mCanCut = can_cut;
+ message.setValueBoolean("cut", can_cut);
+ }
+
+ if(can_copy != mCanCopy)
+ {
+ mCanCopy = can_copy;
+ message.setValueBoolean("copy", can_copy);
+ }
+
+ if(can_paste != mCanPaste)
+ {
+ mCanPaste = can_paste;
+ message.setValueBoolean("paste", can_paste);
+ }
+
+ sendMessage(message);
+
+ }
+ }
+
+};
+
+MediaPluginWebKit::MediaPluginWebKit(LLPluginInstance::sendMessageFunction host_send_func, void *host_user_data) :
+ MediaPluginBase(host_send_func, host_user_data)
+{
+// std::cerr << "MediaPluginWebKit constructor" << std::endl;
+
+ mBrowserWindowId = 0;
+ mBrowserInitialized = false;
+ mNeedsUpdate = true;
+ mCanCut = false;
+ mCanCopy = false;
+ mCanPaste = false;
+}
+
+MediaPluginWebKit::~MediaPluginWebKit()
+{
+ // unhook observer
+ LLQtWebKit::getInstance()->remObserver( mBrowserWindowId, this );
+
+ // clean up
+ LLQtWebKit::getInstance()->reset();
+
+// std::cerr << "MediaPluginWebKit destructor" << std::endl;
+}
+
+void MediaPluginWebKit::receiveMessage(const char *message_string)
+{
+// std::cerr << "MediaPluginWebKit::receiveMessage: received message: \"" << message_string << "\"" << std::endl;
+ LLPluginMessage message_in;
+
+ if(message_in.parse(message_string) >= 0)
+ {
+ std::string message_class = message_in.getClass();
+ std::string message_name = message_in.getName();
+ if(message_class == LLPLUGIN_MESSAGE_CLASS_BASE)
+ {
+ if(message_name == "init")
+ {
+ LLPluginMessage message("base", "init_response");
+ LLSD versions = LLSD::emptyMap();
+ versions[LLPLUGIN_MESSAGE_CLASS_BASE] = LLPLUGIN_MESSAGE_CLASS_BASE_VERSION;
+ versions[LLPLUGIN_MESSAGE_CLASS_MEDIA] = LLPLUGIN_MESSAGE_CLASS_MEDIA_VERSION;
+ versions[LLPLUGIN_MESSAGE_CLASS_MEDIA_BROWSER] = LLPLUGIN_MESSAGE_CLASS_MEDIA_BROWSER_VERSION;
+ message.setValueLLSD("versions", versions);
+
+ std::string plugin_version = "Webkit media plugin, Webkit version ";
+ plugin_version += LLQtWebKit::getInstance()->getVersion();
+ message.setValue("plugin_version", plugin_version);
+ sendMessage(message);
+
+ // Plugin gets to decide the texture parameters to use.
+ mDepth = 4;
+
+ message.setMessage(LLPLUGIN_MESSAGE_CLASS_MEDIA, "texture_params");
+ message.setValueS32("default_width", 800);
+ message.setValueS32("default_height", 600);
+ message.setValueS32("depth", mDepth);
+ message.setValueU32("internalformat", GL_RGBA);
+ message.setValueU32("format", GL_RGBA);
+ message.setValueU32("type", GL_UNSIGNED_BYTE);
+ message.setValueBoolean("coords_opengl", true);
+ sendMessage(message);
+ }
+ else if(message_name == "idle")
+ {
+ // no response is necessary here.
+ F64 time = message_in.getValueReal("time");
+
+ // Convert time to milliseconds for update()
+ update((int)(time * 1000.0f));
+ }
+ else if(message_name == "cleanup")
+ {
+ // TODO: clean up here
+ }
+ else if(message_name == "shm_added")
+ {
+ SharedSegmentInfo info;
+ U64 address_lo = message_in.getValueU32("address");
+ U64 address_hi = message_in.hasValue("address_1") ? message_in.getValueU32("address_1") : 0;
+ info.mAddress = (void*)((address_lo) |
+ (address_hi * (U64(1)<<31)));
+ info.mSize = (size_t)message_in.getValueS32("size");
+ std::string name = message_in.getValue("name");
+
+
+// std::cerr << "MediaPluginWebKit::receiveMessage: shared memory added, name: " << name
+// << ", size: " << info.mSize
+// << ", address: " << info.mAddress
+// << std::endl;
+
+ mSharedSegments.insert(SharedSegmentMap::value_type(name, info));
+
+ }
+ else if(message_name == "shm_remove")
+ {
+ std::string name = message_in.getValue("name");
+
+// std::cerr << "MediaPluginWebKit::receiveMessage: shared memory remove, name = " << name << std::endl;
+
+ SharedSegmentMap::iterator iter = mSharedSegments.find(name);
+ if(iter != mSharedSegments.end())
+ {
+ if(mPixels == iter->second.mAddress)
+ {
+ // This is the currently active pixel buffer. Make sure we stop drawing to it.
+ mPixels = NULL;
+ mTextureSegmentName.clear();
+ }
+ mSharedSegments.erase(iter);
+ }
+ else
+ {
+// std::cerr << "MediaPluginWebKit::receiveMessage: unknown shared memory region!" << std::endl;
+ }
+
+ // Send the response so it can be cleaned up.
+ LLPluginMessage message("base", "shm_remove_response");
+ message.setValue("name", name);
+ sendMessage(message);
+ }
+ else
+ {
+// std::cerr << "MediaPluginWebKit::receiveMessage: unknown base message: " << message_name << std::endl;
+ }
+ }
+ else if(message_class == LLPLUGIN_MESSAGE_CLASS_MEDIA)
+ {
+ if(message_name == "size_change")
+ {
+ std::string name = message_in.getValue("name");
+ S32 width = message_in.getValueS32("width");
+ S32 height = message_in.getValueS32("height");
+ S32 texture_width = message_in.getValueS32("texture_width");
+ S32 texture_height = message_in.getValueS32("texture_height");
+
+ if(!name.empty())
+ {
+ // Find the shared memory region with this name
+ SharedSegmentMap::iterator iter = mSharedSegments.find(name);
+ if(iter != mSharedSegments.end())
+ {
+ mPixels = (unsigned char*)iter->second.mAddress;
+ mWidth = width;
+ mHeight = height;
+
+ // initialize (only gets called once)
+ initBrowser();
+
+ // size changed so tell the browser
+ LLQtWebKit::getInstance()->setSize( mBrowserWindowId, mWidth, mHeight );
+
+// std::cerr << "webkit plugin: set size to " << mWidth << " x " << mHeight
+// << ", rowspan is " << LLQtWebKit::getInstance()->getBrowserRowSpan(mBrowserWindowId) << std::endl;
+
+ S32 real_width = LLQtWebKit::getInstance()->getBrowserRowSpan(mBrowserWindowId) / LLQtWebKit::getInstance()->getBrowserDepth(mBrowserWindowId);
+
+ // The actual width the browser will be drawing to is probably smaller... let the host know by modifying texture_width in the response.
+ if(real_width <= texture_width)
+ {
+ texture_width = real_width;
+ }
+ else
+ {
+ // This won't work -- it'll be bigger than the allocated memory. This is a fatal error.
+// std::cerr << "Fatal error: browser rowbytes greater than texture width" << std::endl;
+ mDeleteMe = true;
+ return;
+ }
+
+ mTextureWidth = texture_width;
+ mTextureHeight = texture_height;
+
+ };
+ };
+
+ LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "size_change_response");
+ message.setValue("name", name);
+ message.setValueS32("width", width);
+ message.setValueS32("height", height);
+ message.setValueS32("texture_width", texture_width);
+ message.setValueS32("texture_height", texture_height);
+ sendMessage(message);
+
+ }
+ else if(message_name == "load_uri")
+ {
+ std::string uri = message_in.getValue("uri");
+
+// std::cout << "loading URI: " << uri << std::endl;
+
+ if(!uri.empty())
+ {
+ LLQtWebKit::getInstance()->navigateTo( mBrowserWindowId, uri );
+ }
+ }
+ else if(message_name == "mouse_event")
+ {
+ std::string event = message_in.getValue("event");
+ S32 x = message_in.getValueS32("x");
+ S32 y = message_in.getValueS32("y");
+ // std::string modifiers = message.getValue("modifiers");
+
+ if(event == "down")
+ {
+ mouseDown(x, y);
+ //std::cout << "Mouse down at " << x << " x " << y << std::endl;
+ }
+ else if(event == "up")
+ {
+ mouseUp(x, y);
+ //std::cout << "Mouse up at " << x << " x " << y << std::endl;
+ }
+ else if(event == "move")
+ {
+ mouseMove(x, y);
+ //std::cout << ">>>>>>>>>>>>>>>>>>>> Mouse move at " << x << " x " << y << std::endl;
+ }
+ }
+ else if(message_name == "scroll_event")
+ {
+ // S32 x = message_in.getValueS32("x");
+ S32 y = message_in.getValueS32("y");
+ // std::string modifiers = message.getValue("modifiers");
+
+ // We currently ignore horizontal scrolling.
+ // The scroll values are roughly 1 per wheel click, so we need to magnify them by some factor.
+ // Arbitrarily, I choose 16.
+ y *= 16;
+ LLQtWebKit::getInstance()->scrollByLines(mBrowserWindowId, y);
+ }
+ else if(message_name == "key_event")
+ {
+ std::string event = message_in.getValue("event");
+
+ // act on "key down" or "key repeat"
+ if ( (event == "down") || (event == "repeat") )
+ {
+ S32 key = message_in.getValueS32("key");
+ keyPress( key );
+ };
+ }
+ else if(message_name == "text_event")
+ {
+ std::string text = message_in.getValue("text");
+
+ unicodeInput(text);
+ }
+ if(message_name == "edit_cut")
+ {
+ LLQtWebKit::getInstance()->userAction( mBrowserWindowId, LLQtWebKit::UA_EDIT_CUT );
+ }
+ if(message_name == "edit_copy")
+ {
+ LLQtWebKit::getInstance()->userAction( mBrowserWindowId, LLQtWebKit::UA_EDIT_COPY );
+ }
+ if(message_name == "edit_paste")
+ {
+ LLQtWebKit::getInstance()->userAction( mBrowserWindowId, LLQtWebKit::UA_EDIT_PASTE );
+ }
+ else
+ {
+// std::cerr << "MediaPluginWebKit::receiveMessage: unknown media message: " << message_string << std::endl;
+ };
+ }
+ else if(message_class == LLPLUGIN_MESSAGE_CLASS_MEDIA_BROWSER)
+ {
+ if(message_name == "focus")
+ {
+ bool val = message_in.getValueBoolean("focused");
+ LLQtWebKit::getInstance()->focusBrowser( mBrowserWindowId, val );
+ }
+ else if(message_name == "clear_cache")
+ {
+ LLQtWebKit::getInstance()->clearCache();
+ }
+ else if(message_name == "clear_cookies")
+ {
+ LLQtWebKit::getInstance()->clearAllCookies();
+ }
+ else if(message_name == "enable_cookies")
+ {
+ bool val = message_in.getValueBoolean("enable");
+ LLQtWebKit::getInstance()->enableCookies( val );
+ }
+ else if(message_name == "proxy_setup")
+ {
+ bool val = message_in.getValueBoolean("enable");
+ std::string host = message_in.getValue("host");
+ int port = message_in.getValueS32("port");
+ LLQtWebKit::getInstance()->enableProxy( val, host, port );
+ }
+ else if(message_name == "browse_stop")
+ {
+ LLQtWebKit::getInstance()->userAction( mBrowserWindowId, LLQtWebKit::UA_NAVIGATE_STOP );
+ }
+ else if(message_name == "browse_reload")
+ {
+ // foo = message_in.getValueBoolean("ignore_cache");
+ LLQtWebKit::getInstance()->userAction( mBrowserWindowId, LLQtWebKit::UA_NAVIGATE_RELOAD );
+ }
+ else if(message_name == "browse_forward")
+ {
+ LLQtWebKit::getInstance()->userAction( mBrowserWindowId, LLQtWebKit::UA_NAVIGATE_FORWARD );
+ }
+ else if(message_name == "browse_back")
+ {
+ LLQtWebKit::getInstance()->userAction( mBrowserWindowId, LLQtWebKit::UA_NAVIGATE_BACK );
+ }
+ else if(message_name == "set_status_redirect")
+ {
+ int code = message_in.getValueS32("code");
+ std::string url = message_in.getValue("url");
+ if ( 404 == code ) // browser lib only supports 404 right now
+ {
+ LLQtWebKit::getInstance()->set404RedirectUrl( mBrowserWindowId, url );
+ };
+ }
+ else if(message_name == "set_user_agent")
+ {
+ std::string user_agent = message_in.getValue("user_agent");
+ LLQtWebKit::getInstance()->setBrowserAgentId( user_agent );
+ }
+ else if(message_name == "init_history")
+ {
+ // Initialize browser history
+ LLSD history = message_in.getValueLLSD("history");
+ // First, clear the URL history
+ LLQtWebKit::getInstance()->clearHistory(mBrowserWindowId);
+ // Then, add the history items in order
+ LLSD::array_iterator iter_history = history.beginArray();
+ LLSD::array_iterator end_history = history.endArray();
+ for(; iter_history != end_history; ++iter_history)
+ {
+ std::string url = (*iter_history).asString();
+ if(! url.empty()) {
+ LLQtWebKit::getInstance()->prependHistoryUrl(mBrowserWindowId, url);
+ }
+ }
+ }
+ else
+ {
+// std::cerr << "MediaPluginWebKit::receiveMessage: unknown media_browser message: " << message_string << std::endl;
+ };
+ }
+ else
+ {
+// std::cerr << "MediaPluginWebKit::receiveMessage: unknown message class: " << message_class << std::endl;
+ };
+ }
+}
+
+int init_media_plugin(LLPluginInstance::sendMessageFunction host_send_func, void *host_user_data, LLPluginInstance::sendMessageFunction *plugin_send_func, void **plugin_user_data)
+{
+ MediaPluginWebKit *self = new MediaPluginWebKit(host_send_func, host_user_data);
+ *plugin_send_func = MediaPluginWebKit::staticReceiveMessage;
+ *plugin_user_data = (void*)self;
+
+ return 0;
+}
+
diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt
index 0c8486bd4f..297540ffc0 100644
--- a/indra/newview/CMakeLists.txt
+++ b/indra/newview/CMakeLists.txt
@@ -18,17 +18,17 @@ include(LLImage)
include(LLImageJ2COJ)
include(LLInventory)
include(LLMath)
-include(LLMedia)
include(LLMessage)
+include(LLPlugin)
include(LLPrimitive)
include(LLRender)
include(LLUI)
include(LLVFS)
include(LLWindow)
include(LLXML)
+include(LLXUIXML)
include(LScript)
include(Linking)
-include(Mozlib)
include(NDOF)
include(GooglePerfTools)
include(TemplateCheck)
@@ -50,48 +50,60 @@ include_directories(
${LLIMAGE_INCLUDE_DIRS}
${LLINVENTORY_INCLUDE_DIRS}
${LLMATH_INCLUDE_DIRS}
- ${LLMEDIA_INCLUDE_DIRS}
${LLMESSAGE_INCLUDE_DIRS}
+ ${LLPLUGIN_INCLUDE_DIRS}
${LLPRIMITIVE_INCLUDE_DIRS}
${LLRENDER_INCLUDE_DIRS}
${LLUI_INCLUDE_DIRS}
${LLVFS_INCLUDE_DIRS}
${LLWINDOW_INCLUDE_DIRS}
${LLXML_INCLUDE_DIRS}
+ ${LLXUIXML_INCLUDE_DIRS}
${LSCRIPT_INCLUDE_DIRS}
${LSCRIPT_INCLUDE_DIRS}/lscript_compile
)
set(viewer_SOURCE_FILES
+ llaccordionctrltab.cpp
+ llaccordionctrl.cpp
+ llactiveimwindow.cpp
llagent.cpp
llagentaccess.cpp
llagentdata.cpp
llagentlanguage.cpp
llagentpilot.cpp
+ llagentui.cpp
+ llagentwearables.cpp
llanimstatelabels.cpp
llappviewer.cpp
llassetuploadresponders.cpp
llassetuploadqueue.cpp
llaudiosourcevo.cpp
- llbbox.cpp
+ llavataractions.cpp
+ llavatariconctrl.cpp
+ llavatarlist.cpp
+ llavatarlistitem.cpp
+ llavatarpropertiesprocessor.cpp
+ llbottomtray.cpp
llbox.cpp
+ llbreadcrumbview.cpp
llcallbacklist.cpp
llcallingcard.cpp
llcapabilitylistener.cpp
llcaphttpsender.cpp
+ llchannelmanager.cpp
llchatbar.cpp
+ llchatitemscontainerctrl.cpp
+ llchatmsgbox.cpp
+ llchiclet.cpp
llclassifiedinfo.cpp
llclassifiedstatsresponder.cpp
llcloud.cpp
- llcolorscheme.cpp
llcolorswatch.cpp
llcommandhandler.cpp
llcommandlineparser.cpp
- llcompass.cpp
llcompilequeue.cpp
llconfirmationmanager.cpp
- llconsole.cpp
- llcontainerview.cpp
llcurrencyuimanager.cpp
llcylinder.cpp
lldebugmessagebox.cpp
@@ -118,15 +130,16 @@ set(viewer_SOURCE_FILES
lleventpoll.cpp
llface.cpp
llfasttimerview.cpp
+ llfavoritesbar.cpp
llfeaturemanager.cpp
llfilepicker.cpp
llfirstuse.cpp
+ llfirsttimetipmanager.cpp
llflexibleobject.cpp
llfloaterabout.cpp
llfloateractivespeakers.cpp
llfloateranimpreview.cpp
llfloaterauction.cpp
- llfloateravatarinfo.cpp
llfloateravatarpicker.cpp
llfloateravatartextures.cpp
llfloaterbeacons.cpp
@@ -137,48 +150,42 @@ set(viewer_SOURCE_FILES
llfloaterbuy.cpp
llfloaterbuycurrency.cpp
llfloaterbuyland.cpp
+ llfloatercall.cpp
llfloatercamera.cpp
llfloaterchat.cpp
llfloaterchatterbox.cpp
- llfloaterclassified.cpp
llfloatercolorpicker.cpp
llfloatercustomize.cpp
llfloaterdaycycle.cpp
llfloaterdirectory.cpp
- llfloatereditui.cpp
llfloaterenvsettings.cpp
- llfloaterevent.cpp
+ llfloaterfirsttimetip.cpp
llfloaterfriends.cpp
llfloaterfonttest.cpp
llfloatergesture.cpp
llfloatergodtools.cpp
- llfloatergroupinfo.cpp
llfloatergroupinvite.cpp
llfloatergroups.cpp
llfloaterhandler.cpp
llfloaterhardwaresettings.cpp
- llfloaterhtml.cpp
llfloaterhtmlcurrency.cpp
- llfloaterhtmlhelp.cpp
+ llfloatermediabrowser.cpp
llfloaterhtmlsimple.cpp
llfloaterhud.cpp
llfloaterimagepreview.cpp
llfloaterinspect.cpp
+ llfloaterinventory.cpp
llfloaterjoystick.cpp
llfloaterlagmeter.cpp
llfloaterland.cpp
llfloaterlandholdings.cpp
- llfloaterlandmark.cpp
llfloatermap.cpp
llfloatermemleak.cpp
llfloatermute.cpp
llfloaternamedesc.cpp
- llfloaternewim.cpp
llfloaternotificationsconsole.cpp
- llfloaterobjectiminfo.cpp
llfloateropenobject.cpp
llfloaterparcel.cpp
- llfloaterpermissionsmgr.cpp
llfloaterperms.cpp
llfloaterpostcard.cpp
llfloaterpostprocess.cpp
@@ -190,25 +197,28 @@ set(viewer_SOURCE_FILES
llfloatersellland.cpp
llfloatersettingsdebug.cpp
llfloatersnapshot.cpp
- llfloaterstats.cpp
llfloatertelehub.cpp
- llfloatertest.cpp
+ llfloatertestlistview.cpp
llfloatertools.cpp
llfloatertopobjects.cpp
llfloatertos.cpp
+ llfloateruipreview.cpp
llfloaterurldisplay.cpp
llfloaterurlentry.cpp
llfloatervoicedevicesettings.cpp
llfloaterwater.cpp
llfloaterwindlight.cpp
llfloaterworldmap.cpp
+ llfoldertype.cpp
llfolderview.cpp
+ llfolderviewitem.cpp
llfollowcam.cpp
- llframestats.cpp
- llframestatview.cpp
+ llfriendcard.cpp
llgesturemgr.cpp
llgivemoney.cpp
llglsandbox.cpp
+ llgroupactions.cpp
+ llgrouplist.cpp
llgroupmgr.cpp
llgroupnotify.cpp
llhomelocationresponder.cpp
@@ -224,15 +234,24 @@ set(viewer_SOURCE_FILES
llhudrender.cpp
llhudtext.cpp
llhudview.cpp
+ llimhandler.cpp
llimpanel.cpp
llimview.cpp
- llinventoryactions.cpp
+ llimcontrolpanel.cpp
+ llinspectavatar.cpp
llinventorybridge.cpp
llinventoryclipboard.cpp
+ llinventoryfilter.cpp
llinventorymodel.cpp
- llinventoryview.cpp
lljoystickbutton.cpp
+ lllandmarkactions.cpp
lllandmarklist.cpp
+ lllistbrowser.cpp
+ lllistview.cpp
+ lllocaltextureobject.cpp
+ lllocationhistory.cpp
+ lllocationinputctrl.cpp
+ llurllineeditorctrl.cpp
lllogchat.cpp
llloginhandler.cpp
llmanip.cpp
@@ -243,6 +262,7 @@ set(viewer_SOURCE_FILES
llmediaremotectrl.cpp
llmemoryview.cpp
llmenucommands.cpp
+ llmetricperformancetester.cpp
llmimetypes.cpp
llmorphview.cpp
llmoveview.cpp
@@ -250,15 +270,25 @@ set(viewer_SOURCE_FILES
llnamebox.cpp
llnameeditor.cpp
llnamelistctrl.cpp
+ llnavigationbar.cpp
+ llnearbychat.cpp
+ llnearbychatbar.cpp
+ llnearbychathandler.cpp
llnetmap.cpp
+ llnotificationalerthandler.cpp
+ llnotificationgrouphandler.cpp
+ llnotificationinfohandler.cpp
+ llnotificationmanager.cpp
llnotify.cpp
+ lloutputmonitorctrl.cpp
lloverlaybar.cpp
- llpanelaudioprefs.cpp
- llpanelaudiovolume.cpp
+ llpanelappearance.cpp
+ llpanelappearancetab.cpp
llpanelavatar.cpp
+ llpanelavatarrow.cpp
+ llpanelavatartag.cpp
llpanelclassified.cpp
llpanelcontents.cpp
- llpaneldebug.cpp
llpaneldirbrowser.cpp
llpaneldirclassified.cpp
llpaneldirevents.cpp
@@ -267,72 +297,90 @@ set(viewer_SOURCE_FILES
llpaneldirland.cpp
llpaneldirpeople.cpp
llpaneldirplaces.cpp
- llpaneldirpopular.cpp
- llpaneldisplay.cpp
llpanelevent.cpp
llpanelface.cpp
- llpanelgeneral.cpp
llpanelgroup.cpp
llpanelgroupgeneral.cpp
llpanelgroupinvite.cpp
llpanelgrouplandmoney.cpp
llpanelgroupnotices.cpp
llpanelgrouproles.cpp
- llpanelinput.cpp
llpanelinventory.cpp
+ llpanelimcontrolpanel.cpp
llpanelland.cpp
+ llpanellandaudio.cpp
+ llpanellandmarks.cpp
llpanellandmedia.cpp
- llpanellandobjects.cpp
- llpanellandoptions.cpp
llpanellogin.cpp
- llpanelmorph.cpp
- llpanelmsgs.cpp
- llpanelnetwork.cpp
+ llpanellookinfo.cpp
+ llpanellooks.cpp
+ llpanelmedia.cpp
+ llpanelmediahud.cpp
+ llpanelmeprofile.cpp
+ llpanelmovetip.cpp
llpanelobject.cpp
+ llpanelpeople.cpp
llpanelpermissions.cpp
llpanelpick.cpp
+ llpanelpicks.cpp
llpanelplace.cpp
- llpanelskins.cpp
+ llpanelplaceinfo.cpp
+ llpanelplaces.cpp
+ llpanelplacestab.cpp
+ llpanelprofile.cpp
+ llpanelprofileview.cpp
+ llpanelteleporthistory.cpp
llpanelvolume.cpp
- llpanelweb.cpp
llparcelselection.cpp
llpatchvertexarray.cpp
llpolymesh.cpp
llpolymorph.cpp
- llprefschat.cpp
- llprefsim.cpp
- llprefsvoice.cpp
llpreviewanim.cpp
llpreview.cpp
llpreviewgesture.cpp
- llpreviewlandmark.cpp
llpreviewnotecard.cpp
llpreviewscript.cpp
llpreviewsound.cpp
llpreviewtexture.cpp
llproductinforequest.cpp
llprogressview.cpp
+ llrecentpeople.cpp
llregionposition.cpp
llremoteparcelrequest.cpp
llsavedsettingsglue.cpp
+ llscreenchannel.cpp
llselectmgr.cpp
+ llsidetray.cpp
+ llsidetraypanelcontainer.cpp
llsky.cpp
+ llslurl.cpp
llspatialpartition.cpp
+ llsplitbutton.cpp
llsprite.cpp
llsrv.cpp
llstartup.cpp
- llstatbar.cpp
- llstatgraph.cpp
llstatusbar.cpp
- llstatview.cpp
llstylemap.cpp
llsurface.cpp
llsurfacepatch.cpp
+ llsyswellitem.cpp
+ llsyswellwindow.cpp
+ llteleporthistory.cpp
+ llteleporthistorystorage.cpp
+ lltexglobalcolor.cpp
lltexlayer.cpp
+ lltexlayerparams.cpp
lltexturecache.cpp
lltexturectrl.cpp
lltexturefetch.cpp
lltextureview.cpp
+ lltoast.cpp
+ lltoastalertpanel.cpp
+ lltoastgroupnotifypanel.cpp
+ lltoastimpanel.cpp
+ lltoastnotifypanel.cpp
+ lltoastpanel.cpp
+ lltoggleablemenu.cpp
lltoolbar.cpp
lltoolbrush.cpp
lltoolcomp.cpp
@@ -352,9 +400,7 @@ set(viewer_SOURCE_FILES
lltoolselect.cpp
lltoolselectland.cpp
lltoolselectrect.cpp
- lltoolview.cpp
lltracker.cpp
- lltrans.cpp
lluploaddialog.cpp
llurl.cpp
llurldispatcher.cpp
@@ -363,17 +409,15 @@ set(viewer_SOURCE_FILES
llurlwhitelist.cpp
lluserauth.cpp
llvectorperfoptions.cpp
- llvelocitybar.cpp
llviewchildren.cpp
llviewerassetstorage.cpp
llvieweraudio.cpp
llviewercamera.cpp
llviewercontrol.cpp
llviewerdisplay.cpp
+ llviewerfloaterreg.cpp
llviewergenericmessage.cpp
- llviewergesture.cpp
- llviewerimage.cpp
- llviewerimagelist.cpp
+ llviewergesture.cpp
llviewerinventory.cpp
llviewerjointattachment.cpp
llviewerjoint.cpp
@@ -385,6 +429,8 @@ set(viewer_SOURCE_FILES
llviewerkeyboard.cpp
llviewerlayer.cpp
llviewermedia.cpp
+ llviewermediafocus.cpp
+ llviewermedia_streamingaudio.cpp
llviewermenu.cpp
llviewermenufile.cpp
llviewermessage.cpp
@@ -401,7 +447,9 @@ set(viewer_SOURCE_FILES
llviewershadermgr.cpp
llviewerstats.cpp
llviewertexteditor.cpp
+ llviewertexture.cpp
llviewertextureanim.cpp
+ llviewertexturelist.cpp
llviewerthrottle.cpp
llviewervisualparam.cpp
llviewerwindow.cpp
@@ -409,6 +457,7 @@ set(viewer_SOURCE_FILES
llvlmanager.cpp
llvoavatar.cpp
llvoavatardefines.cpp
+ llvoavatarself.cpp
llvocache.cpp
llvoclouds.cpp
llvograss.cpp
@@ -416,6 +465,7 @@ set(viewer_SOURCE_FILES
llvoiceclient.cpp
llvoiceremotectrl.cpp
llvoicevisualizer.cpp
+ llvoicecontrolpanel.cpp
llvoinventorylistener.cpp
llvopartgroup.cpp
llvosky.cpp
@@ -429,9 +479,10 @@ set(viewer_SOURCE_FILES
llwaterparammanager.cpp
llwaterparamset.cpp
llwearable.cpp
+ llwearabledictionary.cpp
llwearablelist.cpp
llweb.cpp
- llwebbrowserctrl.cpp
+ llmediactrl.cpp
llwind.cpp
llwlanimator.cpp
llwldaycycle.cpp
@@ -465,38 +516,48 @@ endif (LINUX)
set(viewer_HEADER_FILES
CMakeLists.txt
ViewerInstall.cmake
-
+ llaccordionctrltab.h
+ llaccordionctrl.h
+ llactiveimwindow.h
llagent.h
llagentaccess.h
llagentdata.h
llagentlanguage.h
llagentpilot.h
+ llagentui.h
+ llagentwearables.h
llanimstatelabels.h
llappearance.h
llappviewer.h
llassetuploadresponders.h
llassetuploadqueue.h
llaudiosourcevo.h
- llbbox.h
+ llavataractions.h
+ llavatariconctrl.h
+ llavatarlist.h
+ llavatarlistitem.h
+ llavatarpropertiesprocessor.h
+ llbottomtray.h
llbox.h
+ llbreadcrumbview.h
llcallbacklist.h
llcallingcard.h
llcapabilitylistener.h
llcapabilityprovider.h
llcaphttpsender.h
+ llchannelmanager.h
llchatbar.h
+ llchatitemscontainerctrl.h
+ llchatmsgbox.h
+ llchiclet.h
llclassifiedinfo.h
llclassifiedstatsresponder.h
llcloud.h
- llcolorscheme.h
llcolorswatch.h
llcommandhandler.h
llcommandlineparser.h
- llcompass.h
llcompilequeue.h
llconfirmationmanager.h
- llconsole.h
- llcontainerview.h
llcurrencyuimanager.h
llcylinder.h
lldebugmessagebox.h
@@ -524,15 +585,16 @@ set(viewer_HEADER_FILES
lleventpoll.h
llface.h
llfasttimerview.h
+ llfavoritesbar.h
llfeaturemanager.h
llfilepicker.h
llfirstuse.h
+ llfirsttimetipmanager.h
llflexibleobject.h
llfloaterabout.h
llfloateractivespeakers.h
llfloateranimpreview.h
llfloaterauction.h
- llfloateravatarinfo.h
llfloateravatarpicker.h
llfloateravatartextures.h
llfloaterbeacons.h
@@ -543,48 +605,42 @@ set(viewer_HEADER_FILES
llfloaterbuycontents.h
llfloaterbuycurrency.h
llfloaterbuyland.h
+ llfloatercall.h
llfloatercamera.h
llfloaterchat.h
llfloaterchatterbox.h
- llfloaterclassified.h
llfloatercolorpicker.h
llfloatercustomize.h
llfloaterdaycycle.h
llfloaterdirectory.h
- llfloatereditui.h
llfloaterenvsettings.h
- llfloaterevent.h
+ llfloaterfirsttimetip.h
llfloaterfonttest.h
llfloaterfriends.h
llfloatergesture.h
llfloatergodtools.h
- llfloatergroupinfo.h
llfloatergroupinvite.h
llfloatergroups.h
llfloaterhandler.h
llfloaterhardwaresettings.h
- llfloaterhtml.h
llfloaterhtmlcurrency.h
- llfloaterhtmlhelp.h
+ llfloatermediabrowser.h
llfloaterhtmlsimple.h
llfloaterhud.h
llfloaterimagepreview.h
llfloaterinspect.h
+ llfloaterinventory.h
llfloaterjoystick.h
llfloaterlagmeter.h
llfloaterland.h
llfloaterlandholdings.h
- llfloaterlandmark.h
llfloatermap.h
llfloatermemleak.h
llfloatermute.h
llfloaternamedesc.h
- llfloaternewim.h
llfloaternotificationsconsole.h
- llfloaterobjectiminfo.h
llfloateropenobject.h
llfloaterparcel.h
- llfloaterpermissionsmgr.h
llfloaterpostcard.h
llfloaterpostprocess.h
llfloaterpreference.h
@@ -596,24 +652,28 @@ set(viewer_HEADER_FILES
llfloatersellland.h
llfloatersettingsdebug.h
llfloatersnapshot.h
- llfloaterstats.h
llfloatertelehub.h
- llfloatertest.h
+ llfloatertestlistview.h
llfloatertools.h
llfloatertopobjects.h
llfloatertos.h
+ llfloateruipreview.h
llfloaterurldisplay.h
llfloaterurlentry.h
llfloatervoicedevicesettings.h
llfloaterwater.h
llfloaterwindlight.h
llfloaterworldmap.h
+ llfoldertype.h
llfolderview.h
+ llfoldervieweventlistener.h
+ llfolderviewitem.h
llfollowcam.h
- llframestats.h
- llframestatview.h
+ llfriendcard.h
llgesturemgr.h
llgivemoney.h
+ llgroupactions.h
+ llgrouplist.h
llgroupmgr.h
llgroupnotify.h
llhomelocationresponder.h
@@ -631,13 +691,22 @@ set(viewer_HEADER_FILES
llhudview.h
llimpanel.h
llimview.h
+ llimcontrolpanel.h
+ llinspectavatar.h
llinventorybridge.h
llinventoryclipboard.h
+ llinventoryfilter.h
llinventorymodel.h
- llinventoryview.h
lljoystickbutton.h
+ lllandmarkactions.h
lllandmarklist.h
lllightconstants.h
+ lllistbrowser.h
+ lllistview.h
+ lllocaltextureobject.h
+ lllocationhistory.h
+ lllocationinputctrl.h
+ llurllineeditorctrl.h
lllogchat.h
llloginhandler.h
llmanip.h
@@ -648,6 +717,7 @@ set(viewer_HEADER_FILES
llmediaremotectrl.h
llmemoryview.h
llmenucommands.h
+ llmetricperformancetester.h
llmimetypes.h
llmorphview.h
llmoveview.h
@@ -655,15 +725,23 @@ set(viewer_HEADER_FILES
llnamebox.h
llnameeditor.h
llnamelistctrl.h
+ llnavigationbar.h
+ llnearbychat.h
+ llnearbychatbar.h
+ llnearbychathandler.h
llnetmap.h
+ llnotificationhandler.h
+ llnotificationmanager.h
llnotify.h
+ lloutputmonitorctrl.h
lloverlaybar.h
- llpanelaudioprefs.h
- llpanelaudiovolume.h
+ llpanelappearance.h
+ llpanelappearancetab.h
llpanelavatar.h
+ llpanelavatarrow.h
+ llpanelavatartag.h
llpanelclassified.h
llpanelcontents.h
- llpaneldebug.h
llpaneldirbrowser.h
llpaneldirclassified.h
llpaneldirevents.h
@@ -672,75 +750,93 @@ set(viewer_HEADER_FILES
llpaneldirland.h
llpaneldirpeople.h
llpaneldirplaces.h
- llpaneldirpopular.h
- llpaneldisplay.h
llpanelevent.h
llpanelface.h
- llpanelgeneral.h
llpanelgroup.h
llpanelgroupgeneral.h
llpanelgroupinvite.h
llpanelgrouplandmoney.h
llpanelgroupnotices.h
llpanelgrouproles.h
- llpanelinput.h
llpanelinventory.h
+ llpanelimcontrolpanel.h
llpanelland.h
+ llpanellandaudio.h
+ llpanellandmarks.h
llpanellandmedia.h
- llpanellandobjects.h
- llpanellandoptions.h
- llpanelLCD.h
llpanellogin.h
- llpanelmorph.h
- llpanelmsgs.h
- llpanelnetwork.h
+ llpanellookinfo.h
+ llpanellooks.h
+ llpanelmedia.h
+ llpanelmediahud.h
+ llpanelmeprofile.h
+ llpanelmovetip.h
llpanelobject.h
+ llpanelpeople.h
llpanelpermissions.h
llpanelpick.h
+ llpanelpicks.h
llpanelplace.h
- llpanelskins.h
+ llpanelplaceinfo.h
+ llpanelplaces.h
+ llpanelplacestab.h
+ llpanelprofile.h
+ llpanelprofileview.h
+ llpanelteleporthistory.h
llpanelvolume.h
- llpanelweb.h
llparcelselection.h
llpatchvertexarray.h
llpolymesh.h
llpolymorph.h
- llprefschat.h
- llprefsim.h
- llprefsvoice.h
llpreview.h
llpreviewanim.h
llpreviewgesture.h
- llpreviewlandmark.h
llpreviewnotecard.h
llpreviewscript.h
llpreviewsound.h
llpreviewtexture.h
llproductinforequest.h
llprogressview.h
+ llrecentpeople.h
llregionposition.h
llremoteparcelrequest.h
llresourcedata.h
+ llrootview.h
+ llscreenchannel.h
llsavedsettingsglue.h
llselectmgr.h
+ llsidetray.h
+ llsidetraypanelcontainer.h
llsky.h
+ llslurl.h
llspatialpartition.h
+ llsplitbutton.h
llsprite.h
llsrv.h
llstartup.h
- llstatbar.h
- llstatgraph.h
llstatusbar.h
- llstatview.h
llstylemap.h
llsurface.h
llsurfacepatch.h
+ llsyswellitem.h
+ llsyswellwindow.h
lltable.h
+ llteleporthistory.h
+ llteleporthistorystorage.h
+ lltexglobalcolor.h
lltexlayer.h
+ lltexlayerparams.h
lltexturecache.h
lltexturectrl.h
lltexturefetch.h
lltextureview.h
+ lltoast.h
+ lltoastalertpanel.h
+ lltoastgroupnotifypanel.h
+ lltoastimpanel.h
+ lltoastnotifypanel.h
+ lltoastpanel.h
+ lltoggleablemenu.h
lltool.h
lltoolbar.h
lltoolbrush.h
@@ -760,9 +856,7 @@ set(viewer_HEADER_FILES
lltoolselect.h
lltoolselectland.h
lltoolselectrect.h
- lltoolview.h
lltracker.h
- lltrans.h
lluiconstants.h
lluploaddialog.h
llurl.h
@@ -772,7 +866,6 @@ set(viewer_HEADER_FILES
llurlwhitelist.h
lluserauth.h
llvectorperfoptions.h
- llvelocitybar.h
llviewchildren.h
llviewerassetstorage.h
llvieweraudio.h
@@ -780,10 +873,9 @@ set(viewer_HEADER_FILES
llviewercamera.h
llviewercontrol.h
llviewerdisplay.h
+ llviewerfloaterreg.h
llviewergenericmessage.h
- llviewergesture.h
- llviewerimage.h
- llviewerimagelist.h
+ llviewergesture.h
llviewerinventory.h
llviewerjoint.h
llviewerjointattachment.h
@@ -792,6 +884,8 @@ set(viewer_HEADER_FILES
llviewerkeyboard.h
llviewerlayer.h
llviewermedia.h
+ llviewermediaobserver.h
+ llviewermediafocus.h
llviewermenu.h
llviewermenufile.h
llviewermessage.h
@@ -809,7 +903,9 @@ set(viewer_HEADER_FILES
llviewershadermgr.h
llviewerstats.h
llviewertexteditor.h
+ llviewertexture.h
llviewertextureanim.h
+ llviewertexturelist.h
llviewerthrottle.h
llviewervisualparam.h
llviewerwindow.h
@@ -817,6 +913,7 @@ set(viewer_HEADER_FILES
llvlmanager.h
llvoavatar.h
llvoavatardefines.h
+ llvoavatarself.h
llvocache.h
llvoclouds.h
llvograss.h
@@ -824,6 +921,7 @@ set(viewer_HEADER_FILES
llvoiceclient.h
llvoiceremotectrl.h
llvoicevisualizer.h
+ llvoicecontrolpanel.h
llvoinventorylistener.h
llvopartgroup.h
llvosky.h
@@ -838,9 +936,10 @@ set(viewer_HEADER_FILES
llwaterparammanager.h
llwaterparamset.h
llwearable.h
+ llwearabledictionary.h
llwearablelist.h
llweb.h
- llwebbrowserctrl.h
+ llmediactrl.h
llwind.h
llwindebug.h
llwlanimator.h
@@ -937,6 +1036,10 @@ if (WINDOWS)
)
endforeach( src_file ${viewer_SOURCE_FILES} )
list(APPEND viewer_SOURCE_FILES llviewerprecompiledheaders.cpp)
+ # llstartup.cpp needs special symbols for audio libraries, so it resets
+ # COMPILE_FLAGS below. Make sure it maintains precompiled header settings.
+ set(LLSTARTUP_COMPILE_FLAGS
+ "${LLSTARTUP_COMPILE_FLAGS} /Yullviewerprecompiledheaders.h")
# Add resource files to the project.
# viewerRes.rc is the only buildable file, but
@@ -1000,12 +1103,11 @@ if (WINDOWS)
)
set(viewer_LIBRARIES
- advapi32
+ ${WINDOWS_LIBRARIES}
comdlg32
${DINPUT_LIBRARY}
${DXGUID_LIBRARY}
fmodvc
- gdi32
kernel32
odbc32
odbccp32
@@ -1013,7 +1115,6 @@ if (WINDOWS)
oleaut32
opengl32
shell32
- user32
Vfw32
winspool
)
@@ -1035,16 +1136,21 @@ endif (WINDOWS)
# Add the xui files. This is handy for searching for xui elements
# from within the IDE.
+set(viewer_XUI_FILES
+ skins/default/colors.xml
+ skins/default/textures/textures.xml
+
-file(GLOB viewer_XUI_FILE_GLOB_LIST
- ${CMAKE_CURRENT_SOURCE_DIR}/skins/default/xui/en-us/*.xml)
-set(viewer_XUI_FILES
- ${CMAKE_CURRENT_SOURCE_DIR}/skins/default/colors.xml
- ${CMAKE_CURRENT_SOURCE_DIR}/skins/default/colors_base.xml
)
+file(GLOB DEFAULT_XUI_FILE_GLOB_LIST
+ ${CMAKE_CURRENT_SOURCE_DIR}/skins/default/xui/en/*.xml)
+list(APPEND viewer_XUI_FILES ${DEFAULT_XUI_FILE_GLOB_LIST})
+
+file(GLOB DEFAULT_WIDGET_FILE_GLOB_LIST
+ ${CMAKE_CURRENT_SOURCE_DIR}/skins/default/xui/en/widgets/*.xml)
+list(APPEND viewer_XUI_FILES ${DEFAULT_WIDGET_FILE_GLOB_LIST})
-list(APPEND viewer_XUI_FILES ${viewer_XUI_FILE_GLOB_LIST})
list(SORT viewer_XUI_FILES)
source_group("XUI Files" FILES ${viewer_XUI_FILES})
@@ -1167,8 +1273,10 @@ if (WINDOWS)
set_target_properties(${VIEWER_BINARY_NAME}
PROPERTIES
+ # *TODO -reenable this once we get server usage sorted out
+ #LINK_FLAGS "/debug /NODEFAULTLIB:LIBCMT /SUBSYSTEM:WINDOWS /INCLUDE:\"__tcmalloc\""
LINK_FLAGS "/debug /NODEFAULTLIB:LIBCMT /SUBSYSTEM:WINDOWS"
- LINK_FLAGS_DEBUG "/NODEFAULTLIB:\"LIBCMT;LIBCMTD;MSVCRT\""
+ LINK_FLAGS_DEBUG "/NODEFAULTLIB:\"LIBCMT;LIBCMTD;MSVCRT\" /INCREMENTAL:NO"
LINK_FLAGS_RELEASE ${release_flags}
)
@@ -1231,6 +1339,9 @@ if (WINDOWS)
--touch=${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/touched.bat
DEPENDS ${VIEWER_BINARY_NAME} ${CMAKE_CURRENT_SOURCE_DIR}/viewer_manifest.py
)
+
+ add_dependencies(${VIEWER_BINARY_NAME} SLPlugin media_plugin_quicktime media_plugin_webkit)
+
if (PACKAGE)
add_custom_target(package ALL DEPENDS ${CMAKE_CFG_INTDIR}/touched.bat)
add_dependencies(package windows-updater windows-crash-logger)
@@ -1243,8 +1354,8 @@ target_link_libraries(${VIEWER_BINARY_NAME}
${LLIMAGE_LIBRARIES}
${LLIMAGEJ2COJ_LIBRARIES}
${LLINVENTORY_LIBRARIES}
- ${LLMEDIA_LIBRARIES}
${LLMESSAGE_LIBRARIES}
+ ${LLPLUGIN_LIBRARIES}
${LLPRIMITIVE_LIBRARIES}
${LLRENDER_LIBRARIES}
${FREETYPE_LIBRARIES}
@@ -1252,6 +1363,7 @@ target_link_libraries(${VIEWER_BINARY_NAME}
${LLVFS_LIBRARIES}
${LLWINDOW_LIBRARIES}
${LLXML_LIBRARIES}
+ ${LLXUIXML_LIBRARIES}
${LSCRIPT_LIBRARIES}
${LLMATH_LIBRARIES}
${LLCOMMON_LIBRARIES}
@@ -1263,14 +1375,13 @@ target_link_libraries(${VIEWER_BINARY_NAME}
${OPENGL_LIBRARIES}
${FMODWRAPPER_LIBRARY}
${OPENGL_LIBRARIES}
- ${MOZLIB_LIBRARIES}
${SDL_LIBRARY}
${SMARTHEAP_LIBRARY}
${UI_LIBRARIES}
- ${QUICKTIME_LIBRARY}
${WINDOWS_LIBRARIES}
${XMLRPCEPI_LIBRARIES}
${ELFIO_LIBRARIES}
+ ${GOOGLE_PERFTOOLS_LIBRARIES}
)
build_version(viewer)
@@ -1307,9 +1418,12 @@ if (LINUX)
DEPENDS secondlife-stripped ${CMAKE_CURRENT_SOURCE_DIR}/viewer_manifest.py
)
+ add_dependencies(${VIEWER_BINARY_NAME} SLPlugin media_plugin_gstreamer010 media_plugin_webkit)
+
if (NOT INSTALL)
add_custom_target(package ALL DEPENDS ${product}.tar.bz2)
add_dependencies(package linux-crash-logger-strip-target)
+ add_dependencies(package linux-updater-strip-target)
endif (NOT INSTALL)
endif (LINUX)
@@ -1344,6 +1458,8 @@ if (DARWIN)
DEPENDS ${VIEWER_BINARY_NAME} ${CMAKE_CURRENT_SOURCE_DIR}/viewer_manifest.py
)
+ add_dependencies(${VIEWER_BINARY_NAME} SLPlugin media_plugin_quicktime media_plugin_webkit)
+
if (PACKAGE)
add_custom_target(package ALL DEPENDS ${VIEWER_BINARY_NAME})
add_dependencies(package mac-updater mac-crash-logger)
@@ -1408,3 +1524,69 @@ set_source_files_properties(
)
LL_ADD_PROJECT_UNIT_TESTS(${VIEWER_BINARY_NAME} "${viewer_TEST_SOURCE_FILES}")
+#set(TEST_DEBUG on)
+set(test_sources llcapabilitylistener.cpp llviewerprecompiledheaders.cpp)
+set(test_libs
+ ${LLMESSAGE_LIBRARIES}
+ ${WINDOWS_LIBRARIES}
+ ${LLVFS_LIBRARIES}
+ ${LLMATH_LIBRARIES}
+ ${LLCOMMON_LIBRARIES}
+ )
+
+LL_ADD_INTEGRATION_TEST(llcapabilitylistener
+ "${test_sources}"
+ "${test_libs}"
+ ${PYTHON_EXECUTABLE}
+ "${CMAKE_SOURCE_DIR}/llmessage/tests/test_llsdmessage_peer.py"
+ )
+
+#ADD_VIEWER_BUILD_TEST(llmemoryview viewer)
+
+
+# Don't do these for DARWIN or LINUX here -- they're taken care of by viewer_manifest.py
+if (WINDOWS)
+ get_target_property(BUILT_SLPLUGIN SLPlugin LOCATION)
+ add_custom_command(
+ TARGET ${VIEWER_BINARY_NAME} POST_BUILD
+ COMMAND ${CMAKE_COMMAND}
+ ARGS
+ -E
+ copy_if_different
+ ${BUILT_SLPLUGIN}
+ ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/llplugin
+ COMMENT "Copying SLPlugin executable to the runtime folder."
+ )
+
+ get_target_property(BUILT_WEBKIT_PLUGIN media_plugin_webkit LOCATION)
+ add_custom_command(
+ TARGET ${VIEWER_BINARY_NAME} POST_BUILD
+ COMMAND ${CMAKE_COMMAND}
+ ARGS
+ -E
+ copy_if_different
+ ${BUILT_WEBKIT_PLUGIN}
+ ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/llplugin
+ COMMENT "Copying WebKit Plugin to the runtime folder."
+ )
+
+ get_target_property(BUILT_QUICKTIME_PLUGIN media_plugin_quicktime LOCATION)
+ add_custom_command(
+ TARGET ${VIEWER_BINARY_NAME} POST_BUILD
+ COMMAND ${CMAKE_COMMAND}
+ ARGS
+ -E
+ copy_if_different
+ ${BUILT_QUICKTIME_PLUGIN}
+ ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/llplugin
+ COMMENT "Copying Quicktime Plugin to the runtime folder."
+ )
+endif (WINDOWS)
+
+if (DARWIN)
+# Don't do this here -- it's taken care of by viewer_manifest.py
+# add_custom_command(TARGET ${VIEWER_BINARY_NAME} POST_BUILD
+# COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_SOURCE_DIR}/../libraries/universal-darwin/lib_release/libllqtwebkit.dylib ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/llplugin/
+# DEPENDS ${CMAKE_SOURCE_DIR}/../libraries/universal-darwin/lib_release/libllqtwebkit.dylib
+# )
+endif (DARWIN)
diff --git a/indra/newview/English.lproj/InfoPlist.strings b/indra/newview/English.lproj/InfoPlist.strings
index 8263a2381e..735424c647 100644
--- a/indra/newview/English.lproj/InfoPlist.strings
+++ b/indra/newview/English.lproj/InfoPlist.strings
@@ -2,6 +2,6 @@
CFBundleName = "Second Life";
-CFBundleShortVersionString = "Second Life version 1.24.4.0";
-CFBundleGetInfoString = "Second Life version 1.24.4.0, Copyright 2004-2008 Linden Research, Inc.";
+CFBundleShortVersionString = "Second Life version 2.0.0.0";
+CFBundleGetInfoString = "Second Life version 2.0.0.0, Copyright 2004-2009 Linden Research, Inc.";
diff --git a/indra/newview/Info-SecondLife.plist b/indra/newview/Info-SecondLife.plist
index ba7e7965cd..7264044d37 100644
--- a/indra/newview/Info-SecondLife.plist
+++ b/indra/newview/Info-SecondLife.plist
@@ -32,7 +32,7 @@
</dict>
</array>
<key>CFBundleVersion</key>
- <string>1.24.4.0</string>
+ <string>2.0.0.0</string>
<key>CSResourcesFileMapped</key>
<true/>
</dict>
diff --git a/indra/newview/app_settings/cmd_line.xml b/indra/newview/app_settings/cmd_line.xml
index 5f11ed8e22..5f143431de 100644
--- a/indra/newview/app_settings/cmd_line.xml
+++ b/indra/newview/app_settings/cmd_line.xml
@@ -106,6 +106,54 @@
<string>QuitAfterSeconds</string>
</map>
+ <key>logperformance</key>
+ <map>
+ <key>desc</key>
+ <string>Log performance metrics for benchmarking</string>
+ <key>map-to</key>
+ <string>LogPerformance</string>
+ </map>
+
+ <key>logmetrics</key>
+ <map>
+ <key>desc</key>
+ <string>Log metrics for benchmarking</string>
+ <key>map-to</key>
+ <string>LogMetrics</string>
+ </map>
+
+ <key>analyzeperformance</key>
+ <map>
+ <key>desc</key>
+ <string>When used in conjunction with logperformance, analyzes result of log against baseline.</string>
+ <key>map-to</key>
+ <string>AnalyzePerformance</string>
+ </map>
+
+ <key>debugsession</key>
+ <map>
+ <key>desc</key>
+ <string>Run as if RenderDebugGL is TRUE, but log errors until end of session.</string>
+ <key>map-to</key>
+ <string>DebugSession</string>
+ </map>
+
+ <key>replaysession</key>
+ <map>
+ <key>desc</key>
+ <string>After login, replay last recorded session and quit.</string>
+ <key>map-to</key>
+ <string>ReplaySession</string>
+ </map>
+
+ <key>nonotifications</key>
+ <map>
+ <key>desc</key>
+ <string>User will not get any notifications. NOTE: All notifications that occur will get added to ignore file for future runs.</string>
+ <key>map-to</key>
+ <string>IgnoreAllNotifications</string>
+ </map>
+
<key>rotate</key>
<map>
<key>map-to</key>
@@ -166,6 +214,16 @@
<string>UserLogFile</string>
</map>
+ <key>graphicslevel</key>
+ <map>
+ <key>desc</key>
+ <string>Set the detail level.
+ 0 - low, 1 - medium, 2 - high, 3 - ultra
+ </string>
+ <key>count</key>
+ <integer>1</integer>
+ </map>
+
<key>setdefault</key>
<map>
<key>desc</key>
diff --git a/indra/newview/app_settings/foldertypes.xml b/indra/newview/app_settings/foldertypes.xml
new file mode 100644
index 0000000000..698158308e
--- /dev/null
+++ b/indra/newview/app_settings/foldertypes.xml
@@ -0,0 +1,74 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<ensemble_defs>
+ <ensemble
+ asset_num="-1"
+ xui_name="default"
+ icon_name="inv_plain_closed.tga"
+ />
+ <ensemble
+ asset_num="27"
+ xui_name="head"
+ icon_name="inv_folder_outfit_head.tga"
+ allowed="hair,eyes"
+ />
+ <ensemble
+ asset_num="28"
+ xui_name="gloves"
+ icon_name="inv_folder_outfit_gloves.tga"
+ allowed="gloves"
+ />
+ <ensemble
+ asset_num="29"
+ xui_name="jacket"
+ icon_name="inv_folder_outfit_jacket.tga"
+ allowed="jacket"
+ />
+ <ensemble
+ asset_num="30"
+ xui_name="pants"
+ icon_name="inv_folder_outfit_pants.tga"
+ allowed="pants,underpants"
+ />
+ <ensemble
+ asset_num="31"
+ xui_name="shape"
+ icon_name="inv_folder_outfit_shape.tga"
+ allowed="shape,skin,hair,eyes"
+ />
+ <ensemble
+ asset_num="32"
+ xui_name="shoes"
+ icon_name="inv_folder_outfit_shoes.tga"
+ allowed="shoes,socks"
+ />
+ <ensemble
+ asset_num="33"
+ xui_name="shirt"
+ icon_name="inv_folder_outfit_shirt.tga"
+ allowed="shirt,undershirt"
+ />
+ <ensemble
+ asset_num="34"
+ xui_name="skirt"
+ icon_name="inv_folder_outfit_skirt.tga"
+ allowed=""
+ />
+ <ensemble
+ asset_num="35"
+ xui_name="underpants"
+ icon_name="inv_folder_outfit_underpants.tga"
+ allowed="underpants"
+ />
+ <ensemble
+ asset_num="36"
+ xui_name="undershirt"
+ icon_name="inv_folder_outfit_undershirt.tga"
+ allowed="undershirt"
+ />
+ <ensemble
+ asset_num="47"
+ xui_name="outfit"
+ icon_name="inv_folder_outfit.tga"
+ allowed="outfit"
+ />
+</ensemble_defs>
diff --git a/indra/newview/app_settings/ignorable_dialogs.xml b/indra/newview/app_settings/ignorable_dialogs.xml
new file mode 100644
index 0000000000..669235af1b
--- /dev/null
+++ b/indra/newview/app_settings/ignorable_dialogs.xml
@@ -0,0 +1,291 @@
+<?xml version="1.0" ?>
+<llsd>
+<map>
+ <key>FirstAppearance</key>
+ <map>
+ <key>Comment</key>
+ <string>Enables FirstAppearance warning dialog</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>Boolean</string>
+ <key>Value</key>
+ <integer>1</integer>
+ </map>
+ <key>FirstAttach</key>
+ <map>
+ <key>Comment</key>
+ <string>Enables FirstAttach warning dialog</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>Boolean</string>
+ <key>Value</key>
+ <integer>1</integer>
+ </map>
+ <key>FirstBalanceDecrease</key>
+ <map>
+ <key>Comment</key>
+ <string>Enables FirstBalanceDecrease warning dialog</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>Boolean</string>
+ <key>Value</key>
+ <integer>1</integer>
+ </map>
+ <key>FirstBalanceIncrease</key>
+ <map>
+ <key>Comment</key>
+ <string>Enables FirstBalanceIncrease warning dialog</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>Boolean</string>
+ <key>Value</key>
+ <integer>1</integer>
+ </map>
+ <key>FirstBuild</key>
+ <map>
+ <key>Comment</key>
+ <string>Enables FirstBuild warning dialog</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>Boolean</string>
+ <key>Value</key>
+ <integer>1</integer>
+ </map>
+ <key>FirstDebugMenus</key>
+ <map>
+ <key>Comment</key>
+ <string>Enables FirstDebugMenus warning dialog</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>Boolean</string>
+ <key>Value</key>
+ <integer>1</integer>
+ </map>
+ <key>FirstFlexible</key>
+ <map>
+ <key>Comment</key>
+ <string>Enables FirstFlexible warning dialog</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>Boolean</string>
+ <key>Value</key>
+ <integer>1</integer>
+ </map>
+ <key>FirstGoTo</key>
+ <map>
+ <key>Comment</key>
+ <string>Enables FirstGoTo warning dialog</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>Boolean</string>
+ <key>Value</key>
+ <integer>1</integer>
+ </map>
+ <key>FirstInventory</key>
+ <map>
+ <key>Comment</key>
+ <string>Enables FirstInventory warning dialog</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>Boolean</string>
+ <key>Value</key>
+ <integer>1</integer>
+ </map>
+ <key>FirstLeftClickNoHit</key>
+ <map>
+ <key>Comment</key>
+ <string>Enables FirstLeftClickNoHit warning dialog</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>Boolean</string>
+ <key>Value</key>
+ <integer>1</integer>
+ </map>
+ <key>FirstMap</key>
+ <map>
+ <key>Comment</key>
+ <string>Enables FirstMap warning dialog</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>Boolean</string>
+ <key>Value</key>
+ <integer>1</integer>
+ </map>
+ <key>FirstMedia</key>
+ <map>
+ <key>Comment</key>
+ <string>Enables FirstMedia warning dialog</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>Boolean</string>
+ <key>Value</key>
+ <integer>1</integer>
+ </map>
+ <key>FirstOverrideKeys</key>
+ <map>
+ <key>Comment</key>
+ <string>Enables FirstOverrideKeys warning dialog</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>Boolean</string>
+ <key>Value</key>
+ <integer>1</integer>
+ </map>
+ <key>FirstSandbox</key>
+ <map>
+ <key>Comment</key>
+ <string>Enables FirstSandbox warning dialog</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>Boolean</string>
+ <key>Value</key>
+ <integer>1</integer>
+ </map>
+ <key>FirstSculptedPrim</key>
+ <map>
+ <key>Comment</key>
+ <string>Enables FirstSculptedPrim warning dialog</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>Boolean</string>
+ <key>Value</key>
+ <integer>1</integer>
+ </map>
+ <key>FirstSit</key>
+ <map>
+ <key>Comment</key>
+ <string>Enables FirstSit warning dialog</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>Boolean</string>
+ <key>Value</key>
+ <integer>1</integer>
+ </map>
+ <key>FirstStreamingMusic</key>
+ <map>
+ <key>Comment</key>
+ <string>Enables FirstStreamingMusic warning dialog</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>Boolean</string>
+ <key>Value</key>
+ <integer>1</integer>
+ </map>
+ <key>FirstStreamingVideo</key>
+ <map>
+ <key>Comment</key>
+ <string>Enables FirstStreamingVideo warning dialog</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>Boolean</string>
+ <key>Value</key>
+ <integer>1</integer>
+ </map>
+ <key>FirstTeleport</key>
+ <map>
+ <key>Comment</key>
+ <string>Enables FirstTeleport warning dialog</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>Boolean</string>
+ <key>Value</key>
+ <integer>1</integer>
+ </map>
+ <key>FirstVoice</key>
+ <map>
+ <key>Comment</key>
+ <string>Enables FirstVoice warning dialog</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>Boolean</string>
+ <key>Value</key>
+ <integer>1</integer>
+ </map>
+ <key>AboutDirectX9</key>
+ <map>
+ <key>Comment</key>
+ <string>Enables AboutDirectX9 warning dialog</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>Boolean</string>
+ <key>Value</key>
+ <integer>1</integer>
+ </map>
+ <key>BrowserLaunch</key>
+ <map>
+ <key>Comment</key>
+ <string>Enables BrowserLaunch warning dialog</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>Boolean</string>
+ <key>Value</key>
+ <integer>1</integer>
+ </map>
+ <key>DeedObject</key>
+ <map>
+ <key>Comment</key>
+ <string>Enables DeedObject warning dialog</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>Boolean</string>
+ <key>Value</key>
+ <integer>1</integer>
+ </map>
+ <key>NewClassified</key>
+ <map>
+ <key>Comment</key>
+ <string>Enables NewClassified warning dialog</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>Boolean</string>
+ <key>Value</key>
+ <integer>1</integer>
+ </map>
+ <key>QuickTimeInstalled</key>
+ <map>
+ <key>Comment</key>
+ <string>Enables QuickTimeInstalled warning dialog</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>Boolean</string>
+ <key>Value</key>
+ <integer>1</integer>
+ </map>
+ <key>ReturnToOwner</key>
+ <map>
+ <key>Comment</key>
+ <string>Enables ReturnToOwner warning dialog</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>Boolean</string>
+ <key>Value</key>
+ <integer>1</integer>
+ </map>
+ </map>
+</llsd>
diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml
index 5ebf14d093..4e2f836606 100644
--- a/indra/newview/app_settings/settings.xml
+++ b/indra/newview/app_settings/settings.xml
@@ -23,38 +23,6 @@
<key>Value</key>
<integer>0</integer>
</map>
- <key>UserChatColor</key>
- <map>
- <key>Comment</key>
- <string>Color of your chat messages</string>
- <key>Persist</key>
- <integer>1</integer>
- <key>Type</key>
- <string>Color4</string>
- <key>Value</key>
- <array>
- <real>1.0</real>
- <real>1.0</real>
- <real>1.0</real>
- <real>1.0</real>
- </array>
- </map>
- <key>AgentChatColor</key>
- <map>
- <key>Comment</key>
- <string>Color of chat messages from other residents</string>
- <key>Persist</key>
- <integer>1</integer>
- <key>Type</key>
- <string>Color4</string>
- <key>Value</key>
- <array>
- <real>1.0</real>
- <real>1.0</real>
- <real>1.0</real>
- <real>1.0</real>
- </array>
- </map>
<key>AlertedUnsupportedHardware</key>
<map>
<key>Comment</key>
@@ -198,17 +166,6 @@
<key>Value</key>
<real>0.5</real>
</map>
- <key>AudioLevelDistance</key>
- <map>
- <key>Comment</key>
- <string>Scale factor for audio engine (multiple of world scale, 2.0 = audio falls off twice as fast)</string>
- <key>Persist</key>
- <integer>1</integer>
- <key>Type</key>
- <string>F32</string>
- <key>Value</key>
- <real>1.0</real>
- </map>
<key>AudioLevelDoppler</key>
<map>
<key>Comment</key>
@@ -308,6 +265,17 @@
<key>Value</key>
<real>0.5</real>
</map>
+ <key>AudioSteamingMedia</key>
+ <map>
+ <key>Comment</key>
+ <string>Enable streaming</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>Boolean</string>
+ <key>Value</key>
+ <integer>0</integer>
+ </map>
<key>AudioStreamingMusic</key>
<map>
<key>Comment</key>
@@ -594,22 +562,6 @@
<key>Value</key>
<integer>0</integer>
</map>
- <key>BackgroundChatColor</key>
- <map>
- <key>Comment</key>
- <string>Color of chat bubble background</string>
- <key>Persist</key>
- <integer>1</integer>
- <key>Type</key>
- <string>Color4</string>
- <key>Value</key>
- <array>
- <real>0.0</real>
- <real>0.0</real>
- <real>0.0</real>
- <real>1.0</real>
- </array>
- </map>
<key>BackgroundYieldTime</key>
<map>
<key>Comment</key>
@@ -621,42 +573,10 @@
<key>Value</key>
<integer>40</integer>
</map>
- <key>BackwardBtnRect</key>
+ <key>BottomPanelNew</key>
<map>
<key>Comment</key>
- <string />
- <key>Persist</key>
- <integer>0</integer>
- <key>Type</key>
- <string>Rect</string>
- <key>Value</key>
- <array>
- <integer>45</integer>
- <integer>29</integer>
- <integer>66</integer>
- <integer>4</integer>
- </array>
- </map>
- <key>BasicHelpRect</key>
- <map>
- <key>Comment</key>
- <string>Rectangle for help window</string>
- <key>Persist</key>
- <integer>1</integer>
- <key>Type</key>
- <string>Rect</string>
- <key>Value</key>
- <array>
- <integer>0</integer>
- <integer>404</integer>
- <integer>467</integer>
- <integer>0</integer>
- </array>
- </map>
- <key>BeaconAlwaysOn</key>
- <map>
- <key>Comment</key>
- <string>Beacons / highlighting always on</string>
+ <string>Enable the new bottom panel</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
@@ -884,6 +804,17 @@
<key>Value</key>
<integer>0</integer>
</map>
+ <key>BuildBtnEnabled</key>
+ <map>
+ <key>Comment</key>
+ <string />
+ <key>Persist</key>
+ <integer>0</integer>
+ <key>Type</key>
+ <string>Boolean</string>
+ <key>Value</key>
+ <integer>0</integer>
+ </map>
<key>BuildFeathering</key>
<map>
<key>Comment</key>
@@ -972,17 +903,6 @@
<key>Value</key>
<integer>1</integer>
</map>
- <key>BulkChangeIncludeLandmarks</key>
- <map>
- <key>Comment</key>
- <string>Bulk permission changes affect landmarks</string>
- <key>Persist</key>
- <integer>1</integer>
- <key>Type</key>
- <string>Boolean</string>
- <key>Value</key>
- <integer>1</integer>
- </map>
<key>BulkChangeIncludeNotecards</key>
<map>
<key>Comment</key>
@@ -1170,6 +1090,28 @@
<key>Value</key>
<string />
</map>
+ <key>CacheLocationTopFolder</key>
+ <map>
+ <key>Comment</key>
+ <string>Controls the top folder location of the local disk cache</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>String</string>
+ <key>Value</key>
+ <string />
+ </map>
+ <key>CacheLocationTopFolder</key>
+ <map>
+ <key>Comment</key>
+ <string>Controls the location of the local disk cache</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>String</string>
+ <key>Value</key>
+ <string />
+ </map>
<key>CacheSize</key>
<map>
<key>Comment</key>
@@ -1240,10 +1182,10 @@
<real>6.0</real>
</array>
</map>
- <key>CameraOffsetDefault</key>
+ <key>CameraOffsetRearView</key>
<map>
<key>Comment</key>
- <string>Default camera offset from avatar</string>
+ <string>Initial camera offset from avatar in Rear View</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
@@ -1255,6 +1197,36 @@
<real>0.75</real>
</array>
</map>
+ <key>CameraOffsetFrontView</key>
+ <map>
+ <key>Comment</key>
+ <string>Initial camera offset from avatar in Front View</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>Vector3</string>
+ <key>Value</key>
+ <array>
+ <real>2.2</real>
+ <real>0.0</real>
+ <real>0.0</real>
+ </array>
+ </map>
+ <key>CameraOffsetGroupView</key>
+ <map>
+ <key>Comment</key>
+ <string>Initial camera offset from avatar in Group View</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>Vector3</string>
+ <key>Value</key>
+ <array>
+ <real>-1.0</real>
+ <real>0.7</real>
+ <real>0.5</real>
+ </array>
+ </map>
<key>CameraOffsetScale</key>
<map>
<key>Comment</key>
@@ -1292,6 +1264,17 @@
<key>Value</key>
<real>1.0</real>
</map>
+ <key>CameraPreset</key>
+ <map>
+ <key>Comment</key>
+ <string>Preset camera position - view (0 - rear, 1 - front, 2 - group)</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>U32</string>
+ <key>Value</key>
+ <integer>0</integer>
+ </map>
<key>ChatBarStealsFocus</key>
<map>
<key>Comment</key>
@@ -1391,22 +1374,6 @@
<key>Value</key>
<integer>1</integer>
</map>
- <key>ChatterboxRect</key>
- <map>
- <key>Comment</key>
- <string>Rectangle for chatterbox window</string>
- <key>Persist</key>
- <integer>1</integer>
- <key>Type</key>
- <string>Rect</string>
- <key>Value</key>
- <array>
- <integer>0</integer>
- <integer>400</integer>
- <integer>350</integer>
- <integer>0</integer>
- </array>
- </map>
<key>CheesyBeacon</key>
<map>
<key>Comment</key>
@@ -1421,7 +1388,7 @@
<key>ClientSettingsFile</key>
<map>
<key>Comment</key>
- <string>Persisted client settings file name (per install).</string>
+ <string>Client settings file name (per install).</string>
<key>Persist</key>
<integer>0</integer>
<key>Type</key>
@@ -1497,545 +1464,17 @@
<string />
</array>
</map>
- <key>ColorPaletteEntry01</key>
- <map>
- <key>Comment</key>
- <string>Color picker palette entry</string>
- <key>Persist</key>
- <integer>1</integer>
- <key>Type</key>
- <string>Color4</string>
- <key>Value</key>
- <array>
- <real>0.0</real>
- <real>0.0</real>
- <real>0.0</real>
- <real>1.0</real>
- </array>
- </map>
- <key>ColorPaletteEntry02</key>
- <map>
- <key>Comment</key>
- <string>Color picker palette entry</string>
- <key>Persist</key>
- <integer>1</integer>
- <key>Type</key>
- <string>Color4</string>
- <key>Value</key>
- <array>
- <real>0.5</real>
- <real>0.5</real>
- <real>0.5</real>
- <real>1.0</real>
- </array>
- </map>
- <key>ColorPaletteEntry03</key>
- <map>
- <key>Comment</key>
- <string>Color picker palette entry</string>
- <key>Persist</key>
- <integer>1</integer>
- <key>Type</key>
- <string>Color4</string>
- <key>Value</key>
- <array>
- <real>0.5</real>
- <real>0.0</real>
- <real>0.0</real>
- <real>1.0</real>
- </array>
- </map>
- <key>ColorPaletteEntry04</key>
- <map>
- <key>Comment</key>
- <string>Color picker palette entry</string>
- <key>Persist</key>
- <integer>1</integer>
- <key>Type</key>
- <string>Color4</string>
- <key>Value</key>
- <array>
- <real>0.5</real>
- <real>0.5</real>
- <real>0.0</real>
- <real>1.0</real>
- </array>
- </map>
- <key>ColorPaletteEntry05</key>
- <map>
- <key>Comment</key>
- <string>Color picker palette entry</string>
- <key>Persist</key>
- <integer>1</integer>
- <key>Type</key>
- <string>Color4</string>
- <key>Value</key>
- <array>
- <real>0.0</real>
- <real>0.5</real>
- <real>0.0</real>
- <real>1.0</real>
- </array>
- </map>
- <key>ColorPaletteEntry06</key>
- <map>
- <key>Comment</key>
- <string>Color picker palette entry</string>
- <key>Persist</key>
- <integer>1</integer>
- <key>Type</key>
- <string>Color4</string>
- <key>Value</key>
- <array>
- <real>0.0</real>
- <real>0.5</real>
- <real>0.5</real>
- <real>1.0</real>
- </array>
- </map>
- <key>ColorPaletteEntry07</key>
- <map>
- <key>Comment</key>
- <string>Color picker palette entry</string>
- <key>Persist</key>
- <integer>1</integer>
- <key>Type</key>
- <string>Color4</string>
- <key>Value</key>
- <array>
- <real>0.0</real>
- <real>0.0</real>
- <real>0.5</real>
- <real>1.0</real>
- </array>
- </map>
- <key>ColorPaletteEntry08</key>
+ <key>CompressSnapshotsToDisk</key>
<map>
<key>Comment</key>
- <string>Color picker palette entry</string>
+ <string>Compress snapshots saved to disk (Using JPEG 2000)</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
- <string>Color4</string>
- <key>Value</key>
- <array>
- <real>0.5</real>
- <real>0.0</real>
- <real>0.5</real>
- <real>1.0</real>
- </array>
- </map>
- <key>ColorPaletteEntry09</key>
- <map>
- <key>Comment</key>
- <string>Color picker palette entry</string>
- <key>Persist</key>
- <integer>1</integer>
- <key>Type</key>
- <string>Color4</string>
- <key>Value</key>
- <array>
- <real>0.5</real>
- <real>0.5</real>
- <real>0.0</real>
- <real>1.0</real>
- </array>
- </map>
- <key>ColorPaletteEntry10</key>
- <map>
- <key>Comment</key>
- <string>Color picker palette entry</string>
- <key>Persist</key>
- <integer>1</integer>
- <key>Type</key>
- <string>Color4</string>
- <key>Value</key>
- <array>
- <real>0.0</real>
- <real>0.25</real>
- <real>0.25</real>
- <real>1.0</real>
- </array>
- </map>
- <key>ColorPaletteEntry11</key>
- <map>
- <key>Comment</key>
- <string>Color picker palette entry</string>
- <key>Persist</key>
- <integer>1</integer>
- <key>Type</key>
- <string>Color4</string>
- <key>Value</key>
- <array>
- <real>0.0</real>
- <real>0.5</real>
- <real>1.0</real>
- <real>1.0</real>
- </array>
- </map>
- <key>ColorPaletteEntry12</key>
- <map>
- <key>Comment</key>
- <string>Color picker palette entry</string>
- <key>Persist</key>
- <integer>1</integer>
- <key>Type</key>
- <string>Color4</string>
- <key>Value</key>
- <array>
- <real>0.0</real>
- <real>0.25</real>
- <real>0.5</real>
- <real>1.0</real>
- </array>
- </map>
- <key>ColorPaletteEntry13</key>
- <map>
- <key>Comment</key>
- <string>Color picker palette entry</string>
- <key>Persist</key>
- <integer>1</integer>
- <key>Type</key>
- <string>Color4</string>
- <key>Value</key>
- <array>
- <real>0.5</real>
- <real>0.0</real>
- <real>1.0</real>
- <real>1.0</real>
- </array>
- </map>
- <key>ColorPaletteEntry14</key>
- <map>
- <key>Comment</key>
- <string>Color picker palette entry</string>
- <key>Persist</key>
- <integer>1</integer>
- <key>Type</key>
- <string>Color4</string>
- <key>Value</key>
- <array>
- <real>0.5</real>
- <real>0.25</real>
- <real>0.0</real>
- <real>1.0</real>
- </array>
- </map>
- <key>ColorPaletteEntry15</key>
- <map>
- <key>Comment</key>
- <string>Color picker palette entry</string>
- <key>Persist</key>
- <integer>1</integer>
- <key>Type</key>
- <string>Color4</string>
- <key>Value</key>
- <array>
- <real>1.0</real>
- <real>1.0</real>
- <real>1.0</real>
- <real>1.0</real>
- </array>
- </map>
- <key>ColorPaletteEntry16</key>
- <map>
- <key>Comment</key>
- <string>Color picker palette entry</string>
- <key>Persist</key>
- <integer>1</integer>
- <key>Type</key>
- <string>Color4</string>
- <key>Value</key>
- <array>
- <real>1.0</real>
- <real>1.0</real>
- <real>1.0</real>
- <real>1.0</real>
- </array>
- </map>
- <key>ColorPaletteEntry17</key>
- <map>
- <key>Comment</key>
- <string>Color picker palette entry</string>
- <key>Persist</key>
- <integer>1</integer>
- <key>Type</key>
- <string>Color4</string>
- <key>Value</key>
- <array>
- <real>1.0</real>
- <real>1.0</real>
- <real>1.0</real>
- <real>1.0</real>
- </array>
- </map>
- <key>ColorPaletteEntry18</key>
- <map>
- <key>Comment</key>
- <string>Color picker palette entry</string>
- <key>Persist</key>
- <integer>1</integer>
- <key>Type</key>
- <string>Color4</string>
- <key>Value</key>
- <array>
- <real>0.75</real>
- <real>0.75</real>
- <real>0.75</real>
- <real>1.0</real>
- </array>
- </map>
- <key>ColorPaletteEntry19</key>
- <map>
- <key>Comment</key>
- <string>Color picker palette entry</string>
- <key>Persist</key>
- <integer>1</integer>
- <key>Type</key>
- <string>Color4</string>
- <key>Value</key>
- <array>
- <real>1.0</real>
- <real>0.0</real>
- <real>0.0</real>
- <real>1.0</real>
- </array>
- </map>
- <key>ColorPaletteEntry20</key>
- <map>
- <key>Comment</key>
- <string>Color picker palette entry</string>
- <key>Persist</key>
- <integer>1</integer>
- <key>Type</key>
- <string>Color4</string>
- <key>Value</key>
- <array>
- <real>1.0</real>
- <real>1.0</real>
- <real>0.0</real>
- <real>1.0</real>
- </array>
- </map>
- <key>ColorPaletteEntry21</key>
- <map>
- <key>Comment</key>
- <string>Color picker palette entry</string>
- <key>Persist</key>
- <integer>1</integer>
- <key>Type</key>
- <string>Color4</string>
- <key>Value</key>
- <array>
- <real>0.0</real>
- <real>1.0</real>
- <real>0.0</real>
- <real>1.0</real>
- </array>
- </map>
- <key>ColorPaletteEntry22</key>
- <map>
- <key>Comment</key>
- <string>Color picker palette entry</string>
- <key>Persist</key>
- <integer>1</integer>
- <key>Type</key>
- <string>Color4</string>
- <key>Value</key>
- <array>
- <real>0.0</real>
- <real>1.0</real>
- <real>1.0</real>
- <real>1.0</real>
- </array>
- </map>
- <key>ColorPaletteEntry23</key>
- <map>
- <key>Comment</key>
- <string>Color picker palette entry</string>
- <key>Persist</key>
- <integer>1</integer>
- <key>Type</key>
- <string>Color4</string>
- <key>Value</key>
- <array>
- <real>0.0</real>
- <real>0.0</real>
- <real>1.0</real>
- <real>1.0</real>
- </array>
- </map>
- <key>ColorPaletteEntry24</key>
- <map>
- <key>Comment</key>
- <string>Color picker palette entry</string>
- <key>Persist</key>
- <integer>1</integer>
- <key>Type</key>
- <string>Color4</string>
- <key>Value</key>
- <array>
- <real>1.0</real>
- <real>0.0</real>
- <real>1.0</real>
- <real>1.0</real>
- </array>
- </map>
- <key>ColorPaletteEntry25</key>
- <map>
- <key>Comment</key>
- <string>Color picker palette entry</string>
- <key>Persist</key>
- <integer>1</integer>
- <key>Type</key>
- <string>Color4</string>
- <key>Value</key>
- <array>
- <real>1.0</real>
- <real>1.0</real>
- <real>0.5</real>
- <real>1.0</real>
- </array>
- </map>
- <key>ColorPaletteEntry26</key>
- <map>
- <key>Comment</key>
- <string>Color picker palette entry</string>
- <key>Persist</key>
- <integer>1</integer>
- <key>Type</key>
- <string>Color4</string>
- <key>Value</key>
- <array>
- <real>0.0</real>
- <real>1.0</real>
- <real>0.5</real>
- <real>1.0</real>
- </array>
- </map>
- <key>ColorPaletteEntry27</key>
- <map>
- <key>Comment</key>
- <string>Color picker palette entry</string>
- <key>Persist</key>
- <integer>1</integer>
- <key>Type</key>
- <string>Color4</string>
- <key>Value</key>
- <array>
- <real>0.5</real>
- <real>1.0</real>
- <real>1.0</real>
- <real>1.0</real>
- </array>
- </map>
- <key>ColorPaletteEntry28</key>
- <map>
- <key>Comment</key>
- <string>Color picker palette entry</string>
- <key>Persist</key>
- <integer>1</integer>
- <key>Type</key>
- <string>Color4</string>
- <key>Value</key>
- <array>
- <real>0.5</real>
- <real>0.5</real>
- <real>1.0</real>
- <real>1.0</real>
- </array>
- </map>
- <key>ColorPaletteEntry29</key>
- <map>
- <key>Comment</key>
- <string>Color picker palette entry</string>
- <key>Persist</key>
- <integer>1</integer>
- <key>Type</key>
- <string>Color4</string>
- <key>Value</key>
- <array>
- <real>1.0</real>
- <real>0.0</real>
- <real>0.5</real>
- <real>1.0</real>
- </array>
- </map>
- <key>ColorPaletteEntry30</key>
- <map>
- <key>Comment</key>
- <string>Color picker palette entry</string>
- <key>Persist</key>
- <integer>1</integer>
- <key>Type</key>
- <string>Color4</string>
- <key>Value</key>
- <array>
- <real>1.0</real>
- <real>0.5</real>
- <real>0.0</real>
- <real>1.0</real>
- </array>
- </map>
- <key>ColorPaletteEntry31</key>
- <map>
- <key>Comment</key>
- <string>Color picker palette entry</string>
- <key>Persist</key>
- <integer>1</integer>
- <key>Type</key>
- <string>Color4</string>
- <key>Value</key>
- <array>
- <real>1.0</real>
- <real>1.0</real>
- <real>1.0</real>
- <real>1.0</real>
- </array>
- </map>
- <key>ColorPaletteEntry32</key>
- <map>
- <key>Comment</key>
- <string>Color picker palette entry</string>
- <key>Persist</key>
- <integer>1</integer>
- <key>Type</key>
- <string>Color4</string>
- <key>Value</key>
- <array>
- <real>1.0</real>
- <real>1.0</real>
- <real>1.0</real>
- <real>1.0</real>
- </array>
- </map>
- <key>ColumnHeaderDropDownDelay</key>
- <map>
- <key>Comment</key>
- <string>Time in seconds of mouse click before column header shows sort options list</string>
- <key>Persist</key>
- <integer>1</integer>
- <key>Type</key>
- <string>F32</string>
- <key>Value</key>
- <real>0.300000011921</real>
- </map>
- <key>CompileOutputRect</key>
- <map>
- <key>Comment</key>
- <string>Rectangle for script Recompile Everything output window</string>
- <key>Persist</key>
- <integer>1</integer>
- <key>Type</key>
- <string>Rect</string>
+ <string>Boolean</string>
<key>Value</key>
- <array>
- <integer>0</integer>
- <integer>400</integer>
- <integer>300</integer>
- <integer>0</integer>
- </array>
- </map>
+ <integer>0</integer>
+ </map>
<key>ConnectAsGod</key>
<map>
<key>Comment</key>
@@ -2223,6 +1662,17 @@
<key>Value</key>
<integer>0</integer>
</map>
+ <key>DebugPluginDisableTimeout</key>
+ <map>
+ <key>Comment</key>
+ <string>Disable the code which watches for plugins that are crashed or hung</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>Boolean</string>
+ <key>Value</key>
+ <integer>0</integer>
+ </map>
<key>DebugShowColor</key>
<map>
<key>Comment</key>
@@ -3136,22 +2586,6 @@
<key>Value</key>
<integer>0</integer>
</map>
- <key>EffectColor</key>
- <map>
- <key>Comment</key>
- <string>Particle effects color</string>
- <key>Persist</key>
- <integer>1</integer>
- <key>Type</key>
- <string>Color4</string>
- <key>Value</key>
- <array>
- <real>1.0</real>
- <real>1.0</real>
- <real>1.0</real>
- <real>1.0</real>
- </array>
- </map>
<key>EnableRippleWater</key>
<map>
<key>Comment</key>
@@ -3361,48 +2795,38 @@
<key>Value</key>
<integer>1</integer>
</map>
- <key>FixedWeather</key>
+ <key>FirstSelectedDisabledPopups</key>
<map>
<key>Comment</key>
- <string>Weather effects do not change over time</string>
+ <string>Return false if there is not disabled popup selected in the list of floater preferences popups</string>
<key>Persist</key>
- <integer>1</integer>
+ <integer>0</integer>
<key>Type</key>
<string>Boolean</string>
<key>Value</key>
<integer>0</integer>
- </map>
- <key>FloaterAboutRect</key>
+ </map>
+ <key>FirstSelectedEnabledPopups</key>
<map>
<key>Comment</key>
- <string>Rectangle for About window</string>
+ <string>Return false if there is not enable popup selected in the list of floater preferences popups</string>
<key>Persist</key>
- <integer>1</integer>
+ <integer>0</integer>
<key>Type</key>
- <string>Rect</string>
+ <string>Boolean</string>
<key>Value</key>
- <array>
- <integer>0</integer>
- <integer>440</integer>
- <integer>470</integer>
- <integer>0</integer>
- </array>
- </map>
- <key>FloaterActiveSpeakersRect</key>
+ <integer>0</integer>
+ </map>
+ <key>FixedWeather</key>
<map>
<key>Comment</key>
- <string>Rectangle for active speakers window</string>
+ <string>Weather effects do not change over time</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
- <string>Rect</string>
+ <string>Boolean</string>
<key>Value</key>
- <array>
- <integer>0</integer>
- <integer>300</integer>
- <integer>250</integer>
- <integer>0</integer>
- </array>
+ <integer>0</integer>
</map>
<key>FloaterActiveSpeakersSortAscending</key>
<map>
@@ -3426,618 +2850,95 @@
<key>Value</key>
<string>speaking_status</string>
</map>
- <key>FloaterAdvancedSkyRect</key>
- <map>
- <key>Comment</key>
- <string>Rectangle for Advanced Sky Editor</string>
- <key>Persist</key>
- <integer>1</integer>
- <key>Type</key>
- <string>Rect</string>
- <key>Value</key>
- <array>
- <integer>0</integer>
- <integer>220</integer>
- <integer>700</integer>
- <integer>0</integer>
- </array>
- </map>
- <key>FloaterAdvancedWaterRect</key>
- <map>
- <key>Comment</key>
- <string>Rectangle for Advanced Water Editor</string>
- <key>Persist</key>
- <integer>1</integer>
- <key>Type</key>
- <string>Rect</string>
- <key>Value</key>
- <array>
- <integer>0</integer>
- <integer>240</integer>
- <integer>700</integer>
- <integer>0</integer>
- </array>
- </map>
- <key>FloaterAudioVolumeRect</key>
- <map>
- <key>Comment</key>
- <string>Rectangle for Audio Volume window</string>
- <key>Persist</key>
- <integer>1</integer>
- <key>Type</key>
- <string>Rect</string>
- <key>Value</key>
- <array>
- <integer>0</integer>
- <integer>440</integer>
- <integer>470</integer>
- <integer>0</integer>
- </array>
- </map>
- <key>FloaterBeaconsRect</key>
- <map>
- <key>Comment</key>
- <string>Rectangle for beacon and highlight controls</string>
- <key>Persist</key>
- <integer>1</integer>
- <key>Type</key>
- <string>Rect</string>
- <key>Value</key>
- <array>
- <integer>200</integer>
- <integer>250</integer>
- <integer>250</integer>
- <integer>200</integer>
- </array>
- </map>
- <key>FloaterBuildOptionsRect</key>
- <map>
- <key>Comment</key>
- <string>Rectangle for build options window.</string>
- <key>Persist</key>
- <integer>1</integer>
- <key>Type</key>
- <string>Rect</string>
- <key>Value</key>
- <array>
- <integer>0</integer>
- <integer>0</integer>
- <integer>0</integer>
- <integer>0</integer>
- </array>
- </map>
- <key>FloaterBumpRect</key>
- <map>
- <key>Comment</key>
- <string>Rectangle for Bumps/Hits window</string>
- <key>Persist</key>
- <integer>1</integer>
- <key>Type</key>
- <string>Rect</string>
- <key>Value</key>
- <array>
- <integer>0</integer>
- <integer>180</integer>
- <integer>400</integer>
- <integer>0</integer>
- </array>
- </map>
- <key>FloaterBuyContentsRect</key>
- <map>
- <key>Comment</key>
- <string>Rectangle for Buy Contents window</string>
- <key>Persist</key>
- <integer>1</integer>
- <key>Type</key>
- <string>Rect</string>
- <key>Value</key>
- <array>
- <integer>0</integer>
- <integer>250</integer>
- <integer>300</integer>
- <integer>0</integer>
- </array>
- </map>
- <key>FloaterBuyRect</key>
- <map>
- <key>Comment</key>
- <string>Rectangle for buy window</string>
- <key>Persist</key>
- <integer>1</integer>
- <key>Type</key>
- <string>Rect</string>
- <key>Value</key>
- <array>
- <integer>0</integer>
- <integer>250</integer>
- <integer>300</integer>
- <integer>0</integer>
- </array>
- </map>
- <key>FloaterCameraRect3</key>
- <map>
- <key>Comment</key>
- <string>Rectangle for camera control window</string>
- <key>Persist</key>
- <integer>1</integer>
- <key>Type</key>
- <string>Rect</string>
- <key>Value</key>
- <array>
- <integer>0</integer>
- <integer>64</integer>
- <integer>176</integer>
- <integer>0</integer>
- </array>
- </map>
- <key>FloaterChatRect</key>
- <map>
- <key>Comment</key>
- <string>Rectangle for chat history</string>
- <key>Persist</key>
- <integer>1</integer>
- <key>Type</key>
- <string>Rect</string>
- <key>Value</key>
- <array>
- <integer>0</integer>
- <integer>172</integer>
- <integer>500</integer>
- <integer>0</integer>
- </array>
- </map>
- <key>FloaterClothingRect</key>
- <map>
- <key>Comment</key>
- <string>Rectangle for clothing window</string>
- <key>Persist</key>
- <integer>1</integer>
- <key>Type</key>
- <string>Rect</string>
- <key>Value</key>
- <array>
- <integer>0</integer>
- <integer>480</integer>
- <integer>320</integer>
- <integer>0</integer>
- </array>
- </map>
- <key>FloaterContactsRect</key>
- <map>
- <key>Comment</key>
- <string>Rectangle for chat history</string>
- <key>Persist</key>
- <integer>1</integer>
- <key>Type</key>
- <string>Rect</string>
- <key>Value</key>
- <array>
- <integer>0</integer>
- <integer>390</integer>
- <integer>395</integer>
- <integer>0</integer>
- </array>
- </map>
- <key>FloaterCustomizeAppearanceRect</key>
- <map>
- <key>Comment</key>
- <string>Rectangle for avatar customization window</string>
- <key>Persist</key>
- <integer>1</integer>
- <key>Type</key>
- <string>Rect</string>
- <key>Value</key>
- <array>
- <integer>0</integer>
- <integer>540</integer>
- <integer>494</integer>
- <integer>0</integer>
- </array>
- </map>
- <key>FloaterDayCycleRect</key>
- <map>
- <key>Comment</key>
- <string>Rectangle for Day Cycle Editor</string>
- <key>Persist</key>
- <integer>1</integer>
- <key>Type</key>
- <string>Rect</string>
- <key>Value</key>
- <array>
- <integer>0</integer>
- <integer>646</integer>
- <integer>275</integer>
- <integer>0</integer>
- </array>
- </map>
- <key>FloaterEnvRect</key>
- <map>
- <key>Comment</key>
- <string>Rectangle for Environment Editor</string>
- <key>Persist</key>
- <integer>1</integer>
- <key>Type</key>
- <string>Rect</string>
- <key>Value</key>
- <array>
- <integer>0</integer>
- <integer>150</integer>
- <integer>600</integer>
- <integer>0</integer>
- </array>
- </map>
- <key>FloaterFindRect2</key>
- <map>
- <key>Comment</key>
- <string>Rectangle for Find window</string>
- <key>Persist</key>
- <integer>1</integer>
- <key>Type</key>
- <string>Rect</string>
- <key>Value</key>
- <array>
- <integer>0</integer>
- <integer>570</integer>
- <integer>780</integer>
- <integer>0</integer>
- </array>
- </map>
- <key>FloaterFriendsRect</key>
- <map>
- <key>Comment</key>
- <string>Rectangle for friends window</string>
- <key>Persist</key>
- <integer>1</integer>
- <key>Type</key>
- <string>Rect</string>
- <key>Value</key>
- <array>
- <integer>0</integer>
- <integer>400</integer>
- <integer>250</integer>
- <integer>0</integer>
- </array>
- </map>
- <key>FloaterGestureRect2</key>
- <map>
- <key>Comment</key>
- <string>Rectangle for gestures window</string>
- <key>Persist</key>
- <integer>1</integer>
- <key>Type</key>
- <string>Rect</string>
- <key>Value</key>
- <array>
- <integer>0</integer>
- <integer>465</integer>
- <integer>350</integer>
- <integer>0</integer>
- </array>
- </map>
- <key>FloaterHUDRect2</key>
- <map>
- <key>Comment</key>
- <string>Rectangle for HUD Floater window</string>
- <key>Persist</key>
- <integer>1</integer>
- <key>Type</key>
- <string>Rect</string>
- <key>Value</key>
-<!-- NOTE: Height and width must match values in settings.xml for
- FloaterHUDRect because this floater is resized to those values
- in LLViewerWindow initialization. JC -->
- <array>
- <integer>0</integer>
- <integer>292</integer>
- <integer>362</integer>
- <integer>0</integer>
- </array>
- </map>
- <key>FloaterHtmlRect</key>
- <map>
- <key>Comment</key>
- <string>Rectangle for HTML window</string>
- <key>Persist</key>
- <integer>1</integer>
- <key>Type</key>
- <string>Rect</string>
- <key>Value</key>
- <array>
- <integer>100</integer>
- <integer>460</integer>
- <integer>370</integer>
- <integer>100</integer>
- </array>
- </map>
- <key>FloaterIMRect</key>
- <map>
- <key>Comment</key>
- <string>Rectangle for IM window</string>
- <key>Persist</key>
- <integer>1</integer>
- <key>Type</key>
- <string>Rect</string>
- <key>Value</key>
- <array>
- <integer>0</integer>
- <integer>160</integer>
- <integer>500</integer>
- <integer>0</integer>
- </array>
- </map>
- <key>FloaterInspectRect</key>
- <map>
- <key>Comment</key>
- <string>Rectangle for Object Inspect window</string>
- <key>Persist</key>
- <integer>1</integer>
- <key>Type</key>
- <string>Rect</string>
- <key>Value</key>
- <array>
- <integer>0</integer>
- <integer>400</integer>
- <integer>400</integer>
- <integer>0</integer>
- </array>
- </map>
- <key>FloaterInventoryRect</key>
+ <key>FloaterMapNorth</key>
<map>
<key>Comment</key>
- <string>Rectangle for inventory window</string>
+ <string>Floater Map North Label</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
- <string>Rect</string>
- <key>Value</key>
- <array>
- <integer>0</integer>
- <integer>400</integer>
- <integer>300</integer>
- <integer>0</integer>
- </array>
- </map>
- <key>FloaterJoystickRect</key>
- <map>
- <key>Comment</key>
- <string>Rectangle for joystick controls window.</string>
- <key>Persist</key>
- <integer>1</integer>
- <key>Type</key>
- <string>Rect</string>
+ <string>String</string>
<key>Value</key>
- <array>
- <integer>0</integer>
- <integer>0</integer>
- <integer>0</integer>
- <integer>0</integer>
- </array>
+ <string>N</string>
</map>
- <key>FloaterLagMeter</key>
+ <key>FloaterMapNorthEast</key>
<map>
<key>Comment</key>
- <string>Rectangle for lag meter</string>
+ <string>Floater Map North-East Label</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
- <string>Rect</string>
+ <string>String</string>
<key>Value</key>
- <array>
- <integer>0</integer>
- <integer>142</integer>
- <integer>350</integer>
- <integer>0</integer>
- </array>
+ <string>NE</string>
</map>
- <key>FloaterLandRect5</key>
+ <key>FloaterMapNorthWest</key>
<map>
<key>Comment</key>
- <string>Rectangle for About Land window</string>
+ <string>Floater Map North-West Label</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
- <string>Rect</string>
+ <string>String</string>
<key>Value</key>
- <array>
- <integer>0</integer>
- <integer>370</integer>
- <integer>460</integer>
- <integer>0</integer>
- </array>
+ <string>NW</string>
</map>
- <key>FloaterLandmarkRect</key>
+ <key>FloaterMapEast</key>
<map>
<key>Comment</key>
- <string>Rectangle for landmark picker</string>
+ <string>Floater Map East Label</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
- <string>Rect</string>
+ <string>String</string>
<key>Value</key>
- <array>
- <integer>0</integer>
- <integer>290</integer>
- <integer>310</integer>
- <integer>0</integer>
- </array>
+ <string>E</string>
</map>
- <key>FloaterMediaRect</key>
+ <key>FloaterMapWest</key>
<map>
<key>Comment</key>
- <string>Rectangle for media browser window</string>
+ <string>Floater Map West Label</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
- <string>Rect</string>
+ <string>String</string>
<key>Value</key>
- <array>
- <integer>16</integer>
- <integer>650</integer>
- <integer>600</integer>
- <integer>128</integer>
- </array>
+ <string>W</string>
</map>
- <key>FloaterMiniMapRect</key>
+ <key>FloaterMapSouth</key>
<map>
<key>Comment</key>
- <string>Rectangle for world map</string>
+ <string>Floater Map South Label</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
- <string>Rect</string>
+ <string>String</string>
<key>Value</key>
- <array>
- <integer>0</integer>
- <integer>225</integer>
- <integer>200</integer>
- <integer>0</integer>
- </array>
+ <string>S</string>
</map>
- <key>FloaterMoveRect2</key>
+ <key>FloaterMapSouthEast</key>
<map>
<key>Comment</key>
- <string>Rectangle for avatar control window</string>
+ <string>Floater Map South-East Label</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
- <string>Rect</string>
+ <string>String</string>
<key>Value</key>
- <array>
- <integer>0</integer>
- <integer>58</integer>
- <integer>135</integer>
- <integer>0</integer>
- </array>
+ <string>SE</string>
</map>
- <key>FloaterMuteRect3</key>
+ <key>FloaterMapSouthWest</key>
<map>
<key>Comment</key>
- <string>Rectangle for mute window</string>
+ <string>Floater Map South-West Label</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
- <string>Rect</string>
+ <string>String</string>
<key>Value</key>
- <array>
- <integer>0</integer>
- <integer>300</integer>
- <integer>300</integer>
- <integer>0</integer>
- </array>
+ <string>SW</string>
</map>
- <key>FloaterObjectIMInfo</key>
- <map>
- <key>Comment</key>
- <string>Rectangle for floater object im info windows</string>
- <key>Persist</key>
- <integer>1</integer>
- <key>Type</key>
- <string>Rect</string>
- <key>Value</key>
- <array>
- <integer>0</integer>
- <integer>300</integer>
- <integer>300</integer>
- <integer>0</integer>
- </array>
- </map>
- <key>FloaterOpenObjectRect</key>
- <map>
- <key>Comment</key>
- <string>Rectangle for Open Object window</string>
- <key>Persist</key>
- <integer>1</integer>
- <key>Type</key>
- <string>Rect</string>
- <key>Value</key>
- <array>
- <integer>0</integer>
- <integer>350</integer>
- <integer>300</integer>
- <integer>0</integer>
- </array>
- </map>
- <key>FloaterPayRectB</key>
- <map>
- <key>Comment</key>
- <string>Rectangle for pay window</string>
- <key>Persist</key>
- <integer>1</integer>
- <key>Type</key>
- <string>Rect</string>
- <key>Value</key>
- <array>
- <integer>0</integer>
- <integer>150</integer>
- <integer>400</integer>
- <integer>0</integer>
- </array>
- </map>
- <key>FloaterPermPrefsRect</key>
- <map>
- <key>Comment</key>
- <string>Rectangle for initial permissions preferences</string>
- <key>Persist</key>
- <integer>1</integer>
- <key>Type</key>
- <string>Rect</string>
- <key>Value</key>
- <array>
- <integer>200</integer>
- <integer>250</integer>
- <integer>250</integer>
- <integer>200</integer>
- </array>
- </map>
- <key>FloaterRegionInfo</key>
- <map>
- <key>Comment</key>
- <string>Rectangle for region info window</string>
- <key>Persist</key>
- <integer>1</integer>
- <key>Type</key>
- <string>Rect</string>
- <key>Value</key>
- <array>
- <integer>0</integer>
- <integer>512</integer>
- <integer>480</integer>
- <integer>0</integer>
- </array>
- </map>
- <key>FloaterScriptDebugRect</key>
- <map>
- <key>Comment</key>
- <string>Rectangle for Script Error/Debug window</string>
- <key>Persist</key>
- <integer>1</integer>
- <key>Type</key>
- <string>Rect</string>
- <key>Value</key>
- <array>
- <integer>0</integer>
- <integer>130</integer>
- <integer>450</integer>
- <integer>0</integer>
- </array>
- </map>
- <key>FloaterSnapshotRect</key>
- <map>
- <key>Comment</key>
- <string>Rectangle for snapshot window</string>
- <key>Persist</key>
- <integer>1</integer>
- <key>Type</key>
- <string>Rect</string>
- <key>Value</key>
- <array>
- <integer>0</integer>
- <integer>200</integer>
- <integer>200</integer>
- <integer>400</integer>
- </array>
- </map>
<key>FloaterStatisticsRect</key>
<map>
<key>Comment</key>
@@ -4054,32 +2955,16 @@
<integer>0</integer>
</array>
</map>
- <key>FloaterViewBottom</key>
+ <key>FlyBtnEnabled</key>
<map>
<key>Comment</key>
- <string>[DO NOT MODIFY] Controls layout of floating windows within SL window</string>
+ <string />
<key>Persist</key>
- <integer>1</integer>
+ <integer>0</integer>
<key>Type</key>
- <string>S32</string>
+ <string>Boolean</string>
<key>Value</key>
- <integer>-1</integer>
- </map>
- <key>FloaterWorldMapRect2</key>
- <map>
- <key>Comment</key>
- <string>Rectangle for world map window</string>
- <key>Persist</key>
<integer>1</integer>
- <key>Type</key>
- <string>Rect</string>
- <key>Value</key>
- <array>
- <integer>0</integer>
- <integer>0</integer>
- <integer>0</integer>
- <integer>0</integer>
- </array>
</map>
<key>FlyBtnState</key>
<map>
@@ -4290,14 +3175,14 @@
<key>Value</key>
<integer>0</integer>
</map>
- <key>FocusOffsetDefault</key>
+ <key>FocusOffsetRearView</key>
<map>
<key>Comment</key>
- <string>Default focus point offset relative to avatar (x-axis is forward)</string>
+ <string>Initial focus point offset relative to avatar for the camera preset Rear View (x-axis is forward)</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
- <string>Vector3</string>
+ <string>Vector3D</string>
<key>Value</key>
<array>
<real>1.0</real>
@@ -4305,6 +3190,36 @@
<real>1.0</real>
</array>
</map>
+ <key>FocusOffsetFrontView</key>
+ <map>
+ <key>Comment</key>
+ <string>Initial focus point offset relative to avatar for the camera preset Front View</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>Vector3D</string>
+ <key>Value</key>
+ <array>
+ <real>0.0</real>
+ <real>0.0</real>
+ <real>0.0</real>
+ </array>
+ </map>
+ <key>FocusOffsetGroupView</key>
+ <map>
+ <key>Comment</key>
+ <string>Initial focus point offset relative to avatar for the camera preset Group View</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>Vector3D</string>
+ <key>Value</key>
+ <array>
+ <real>1.5</real>
+ <real>0.7</real>
+ <real>1.0</real>
+ </array>
+ </map>
<key>FocusPosOnLogout</key>
<map>
<key>Comment</key>
@@ -4496,22 +3411,6 @@
<key>Value</key>
<integer>0</integer>
</map>
- <key>ForwardBtnRect</key>
- <map>
- <key>Comment</key>
- <string />
- <key>Persist</key>
- <integer>0</integer>
- <key>Type</key>
- <string>Rect</string>
- <key>Value</key>
- <array>
- <integer>45</integer>
- <integer>54</integer>
- <integer>66</integer>
- <integer>29</integer>
- </array>
- </map>
<key>FreezeTime</key>
<map>
<key>Comment</key>
@@ -4523,17 +3422,6 @@
<key>Value</key>
<integer>0</integer>
</map>
- <key>FullScreen</key>
- <map>
- <key>Comment</key>
- <string>Run SL in fullscreen mode</string>
- <key>Persist</key>
- <integer>1</integer>
- <key>Type</key>
- <string>Boolean</string>
- <key>Value</key>
- <integer>0</integer>
- </map>
<key>FullScreenAspectRatio</key>
<map>
<key>Comment</key>
@@ -4676,23 +3564,7 @@
<string>S32</string>
<key>Value</key>
<integer>400</integer>
- </map>
- <key>HTMLLinkColor</key>
- <map>
- <key>Comment</key>
- <string>Color of hyperlinks</string>
- <key>Persist</key>
- <integer>1</integer>
- <key>Type</key>
- <string>Color4</string>
- <key>Value</key>
- <array>
- <real>0.600000023842</real>
- <real>0.600000023842</real>
- <real>1.0</real>
- <real>1.0</real>
- </array>
- </map>
+ </map>
<key>HelpHomeURL</key>
<map>
<key>Comment</key>
@@ -4726,22 +3598,6 @@
<key>Value</key>
<integer>0</integer>
</map>
- <key>HtmlFindRect</key>
- <map>
- <key>Comment</key>
- <string>Rectangle for HTML find window</string>
- <key>Persist</key>
- <integer>1</integer>
- <key>Type</key>
- <string>Rect</string>
- <key>Value</key>
- <array>
- <integer>16</integer>
- <integer>650</integer>
- <integer>600</integer>
- <integer>128</integer>
- </array>
- </map>
<key>HtmlHelpLastPage</key>
<map>
<key>Comment</key>
@@ -4753,54 +3609,6 @@
<key>Value</key>
<string />
</map>
- <key>HtmlHelpRect</key>
- <map>
- <key>Comment</key>
- <string>Rectangle for HTML help window</string>
- <key>Persist</key>
- <integer>1</integer>
- <key>Type</key>
- <string>Rect</string>
- <key>Value</key>
- <array>
- <integer>16</integer>
- <integer>650</integer>
- <integer>600</integer>
- <integer>128</integer>
- </array>
- </map>
- <key>HtmlReleaseMessage</key>
- <map>
- <key>Comment</key>
- <string>Rectangle for HTML Release Message Floater window</string>
- <key>Persist</key>
- <integer>1</integer>
- <key>Type</key>
- <string>Rect</string>
- <key>Value</key>
- <array>
- <integer>46</integer>
- <integer>520</integer>
- <integer>400</integer>
- <integer>128</integer>
- </array>
- </map>
- <key>IMChatColor</key>
- <map>
- <key>Comment</key>
- <string>Color of instant messages from other residents</string>
- <key>Persist</key>
- <integer>1</integer>
- <key>Type</key>
- <string>Color4</string>
- <key>Value</key>
- <array>
- <real>1.0</real>
- <real>1.0</real>
- <real>1.0</real>
- <real>1.0</real>
- </array>
- </map>
<key>IMInChatConsole</key>
<map>
<key>Comment</key>
@@ -4834,6 +3642,17 @@
<key>Value</key>
<integer>1</integer>
</map>
+ <key>IgnoreAllNotifications</key>
+ <map>
+ <key>Comment</key>
+ <string>Ignore all notifications so we never need user input on them.</string>
+ <key>Persist</key>
+ <integer>0</integer>
+ <key>Type</key>
+ <string>Boolean</string>
+ <key>Value</key>
+ <integer>0</integer>
+ </map>
<key>IgnorePixelDepth</key>
<map>
<key>Comment</key>
@@ -5098,22 +3917,6 @@
<key>Value</key>
<integer>0</integer>
</map>
- <key>LSLHelpRect</key>
- <map>
- <key>Comment</key>
- <string>Rectangle for LSL help window</string>
- <key>Persist</key>
- <integer>1</integer>
- <key>Type</key>
- <string>Rect</string>
- <key>Value</key>
- <array>
- <integer>0</integer>
- <integer>400</integer>
- <integer>400</integer>
- <integer>0</integer>
- </array>
- </map>
<key>LSLHelpURL</key>
<map>
<key>Comment</key>
@@ -5423,16 +4226,16 @@
<key>Value</key>
<integer>0</integer>
</map>
- <key>LoginLastLocation</key>
+ <key>LoginLocation</key>
<map>
<key>Comment</key>
<string>Login at same location you last logged out</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
- <string>Boolean</string>
+ <string>String</string>
<key>Value</key>
- <integer>1</integer>
+ <string>last</string>
</map>
<key>LoginPage</key>
<map>
@@ -5632,7 +4435,40 @@
<key>Value</key>
<integer>0</integer>
</map>
- <key>MemoryLogFrequency</key>
+ <key>MediaControlFadeTime</key>
+ <map>
+ <key>Comment</key>
+ <string>Amount of time (in seconds) that the media control fades</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>F32</string>
+ <key>Value</key>
+ <real>1.5</real>
+ </map>
+ <key>MediaControlTimeout</key>
+ <map>
+ <key>Comment</key>
+ <string>Amount of time (in seconds) for media controls to fade with no mouse activity</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>F32</string>
+ <key>Value</key>
+ <real>3.0</real>
+ </map>
+ <key>MediaOnAPrimUI</key>
+ <map>
+ <key>Comment</key>
+ <string>Whether or not to show the "link sharing" UI</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>Boolean</string>
+ <key>Value</key>
+ <integer>0</integer>
+ </map>
+ <key>MemoryLogFrequency</key>
<map>
<key>Comment</key>
<string>Seconds between display of Memory in log (0 for never)</string>
@@ -5643,6 +4479,17 @@
<key>Value</key>
<real>600.0</real>
</map>
+ <key>MemProfiling</key>
+ <map>
+ <key>Comment</key>
+ <string>You want to use tcmalloc's memory profiling options.</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>Boolean</string>
+ <key>Value</key>
+ <integer>0</integer>
+ </map>
<key>MenuAccessKeyTime</key>
<map>
<key>Comment</key>
@@ -5753,38 +4600,6 @@
<key>Value</key>
<integer>0</integer>
</map>
- <key>MoveDownBtnRect</key>
- <map>
- <key>Comment</key>
- <string />
- <key>Persist</key>
- <integer>0</integer>
- <key>Type</key>
- <string>Rect</string>
- <key>Value</key>
- <array>
- <integer>91</integer>
- <integer>29</integer>
- <integer>116</integer>
- <integer>4</integer>
- </array>
- </map>
- <key>MoveUpBtnRect</key>
- <map>
- <key>Comment</key>
- <string />
- <key>Persist</key>
- <integer>0</integer>
- <key>Type</key>
- <string>Rect</string>
- <key>Value</key>
- <array>
- <integer>91</integer>
- <integer>54</integer>
- <integer>116</integer>
- <integer>29</integer>
- </array>
- </map>
<key>MuteAmbient</key>
<map>
<key>Comment</key>
@@ -5871,7 +4686,7 @@
<key>Type</key>
<string>Boolean</string>
<key>Value</key>
- <integer>1</integer>
+ <integer>0</integer>
</map>
<key>NearMeRange</key>
<map>
@@ -5882,7 +4697,7 @@
<key>Type</key>
<string>F32</string>
<key>Value</key>
- <integer>20</integer>
+ <integer>130</integer>
</map>
<key>NextOwnerCopy</key>
<map>
@@ -5928,6 +4743,17 @@
<key>Value</key>
<string />
</map>
+ <key>NewCacheLocationTopFolder</key>
+ <map>
+ <key>Comment</key>
+ <string>Change the top folder location of the local disk cache to this</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>String</string>
+ <key>Value</key>
+ <string />
+ </map>
<key>NextLoginLocation</key>
<map>
<key>Comment</key>
@@ -5994,34 +4820,29 @@
<key>Value</key>
<integer>0</integer>
</map>
- <key>NotecardEditorRect</key>
+ <key>NotifyBoxHeight</key>
<map>
<key>Comment</key>
- <string>Rectangle for notecard editor</string>
+ <string>Height of notification messages</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
- <string>Rect</string>
+ <string>S32</string>
<key>Value</key>
- <array>
- <integer>0</integer>
- <integer>400</integer>
- <integer>400</integer>
- <integer>0</integer>
- </array>
+ <integer>200</integer>
</map>
- <key>NotifyBoxHeight</key>
+ <key>NotifyBoxWidth</key>
<map>
<key>Comment</key>
- <string>Height of notification messages</string>
+ <string>Width of notification messages</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
<string>S32</string>
<key>Value</key>
- <integer>200</integer>
+ <integer>350</integer>
</map>
- <key>NotifyBoxWidth</key>
+ <key>NotificationToastTime</key>
<map>
<key>Comment</key>
<string>Width of notification messages</string>
@@ -6030,7 +4851,84 @@
<key>Type</key>
<string>S32</string>
<key>Value</key>
- <integer>350</integer>
+ <integer>5</integer>
+ </map>
+ <key>ToastOpaqueTime</key>
+ <map>
+ <key>Comment</key>
+ <string>Width of notification messages</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>S32</string>
+ <key>Value</key>
+ <integer>4</integer>
+ </map>
+ <key>StartUpToastTime</key>
+ <map>
+ <key>Comment</key>
+ <string>Width of notification messages</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>S32</string>
+ <key>Value</key>
+ <integer>5</integer>
+ </map>
+ <key>ToastMargin</key>
+ <map>
+ <key>Comment</key>
+ <string>Width of notification messages</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>S32</string>
+ <key>Value</key>
+ <integer>5</integer>
+ </map>
+ <key>ChannelBottomPanelMargin</key>
+ <map>
+ <key>Comment</key>
+ <string>Width of notification messages</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>S32</string>
+ <key>Value</key>
+ <integer>35</integer>
+ </map>
+ <key>NotificationChannelRightMargin</key>
+ <map>
+ <key>Comment</key>
+ <string>Width of notification messages</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>S32</string>
+ <key>Value</key>
+ <integer>10</integer>
+ </map>
+ <key>NavBarMargin</key>
+ <map>
+ <key>Comment</key>
+ <string>Width of notification messages</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>S32</string>
+ <key>Value</key>
+ <integer>60</integer>
+ </map>
+ <key>OverflowToastHeight</key>
+ <map>
+ <key>Comment</key>
+ <string>Width of notification messages</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>S32</string>
+ <key>Value</key>
+ <integer>72</integer>
</map>
<key>NotifyMoneyChange</key>
<map>
@@ -6076,22 +4974,6 @@
<key>Value</key>
<integer>0</integer>
</map>
- <key>ObjectChatColor</key>
- <map>
- <key>Comment</key>
- <string>Color of chat messages from objects</string>
- <key>Persist</key>
- <integer>1</integer>
- <key>Type</key>
- <string>Color4</string>
- <key>Value</key>
- <array>
- <real>0.699999988079</real>
- <real>0.899999976158</real>
- <real>0.699999988079</real>
- <real>1</real>
- </array>
- </map>
<key>OpenDebugStatAdvanced</key>
<map>
<key>Comment</key>
@@ -6194,29 +5076,24 @@
<key>OutBandwidth</key>
<map>
<key>Comment</key>
- <string>Outgoing bandwidth throttle (bps)</string>
+ <string>Expand render stats display</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
- <string>F32</string>
+ <string>Boolean</string>
<key>Value</key>
- <real>0.0</real>
+ <integer>1</integer>
</map>
- <key>OverdrivenColor</key>
+ <key>OutBandwidth</key>
<map>
<key>Comment</key>
- <string>Color of various indicators when resident is speaking too loud.</string>
+ <string>Outgoing bandwidth throttle (bps)</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
- <string>Color4</string>
+ <string>F32</string>
<key>Value</key>
- <array>
- <real>1.0</real>
- <real>0.0</real>
- <real>0.0</real>
- <real>1.0</real>
- </array>
+ <real>0.0</real>
</map>
<key>OverlayTitle</key>
<map>
@@ -6295,22 +5172,6 @@
<key>Value</key>
<integer>344</integer>
</map>
- <key>PermissionsManagerRect</key>
- <map>
- <key>Comment</key>
- <string>Rectangle for permissions manager window</string>
- <key>Persist</key>
- <integer>1</integer>
- <key>Type</key>
- <string>Rect</string>
- <key>Value</key>
- <array>
- <integer>0</integer>
- <integer>85</integer>
- <integer>300</integer>
- <integer>0</integer>
- </array>
- </map>
<key>PickerContextOpacity</key>
<map>
<key>Comment</key>
@@ -6355,17 +5216,6 @@
<key>Value</key>
<real>2.5</real>
</map>
- <key>PinTalkViewOpen</key>
- <map>
- <key>Comment</key>
- <string>Stay in IM after hitting return</string>
- <key>Persist</key>
- <integer>1</integer>
- <key>Type</key>
- <string>Boolean</string>
- <key>Value</key>
- <integer>1</integer>
- </map>
<key>PingInterpolate</key>
<map>
<key>Comment</key>
@@ -6421,166 +5271,6 @@
<key>Value</key>
<integer>13</integer>
</map>
- <key>PreviewAnimRect</key>
- <map>
- <key>Comment</key>
- <string>Rectangle for animation preview window</string>
- <key>Persist</key>
- <integer>1</integer>
- <key>Type</key>
- <string>Rect</string>
- <key>Value</key>
- <array>
- <integer>0</integer>
- <integer>85</integer>
- <integer>300</integer>
- <integer>0</integer>
- </array>
- </map>
- <key>PreviewClassifiedRect</key>
- <map>
- <key>Comment</key>
- <string>Rectangle for URL preview window</string>
- <key>Persist</key>
- <integer>1</integer>
- <key>Type</key>
- <string>Rect</string>
- <key>Value</key>
- <array>
- <integer>0</integer>
- <integer>530</integer>
- <integer>420</integer>
- <integer>0</integer>
- </array>
- </map>
- <key>PreviewEventRect</key>
- <map>
- <key>Comment</key>
- <string>Rectangle for Event preview window</string>
- <key>Persist</key>
- <integer>1</integer>
- <key>Type</key>
- <string>Rect</string>
- <key>Value</key>
- <array>
- <integer>0</integer>
- <integer>530</integer>
- <integer>420</integer>
- <integer>0</integer>
- </array>
- </map>
- <key>PreviewLandmarkRect</key>
- <map>
- <key>Comment</key>
- <string>Rectangle for landmark preview window</string>
- <key>Persist</key>
- <integer>1</integer>
- <key>Type</key>
- <string>Rect</string>
- <key>Value</key>
- <array>
- <integer>0</integer>
- <integer>90</integer>
- <integer>300</integer>
- <integer>0</integer>
- </array>
- </map>
- <key>PreviewObjectRect</key>
- <map>
- <key>Comment</key>
- <string>Rectangle for object preview window</string>
- <key>Persist</key>
- <integer>1</integer>
- <key>Type</key>
- <string>Rect</string>
- <key>Value</key>
- <array>
- <integer>0</integer>
- <integer>85</integer>
- <integer>300</integer>
- <integer>0</integer>
- </array>
- </map>
- <key>PreviewScriptRect</key>
- <map>
- <key>Comment</key>
- <string>Rectangle for script preview window</string>
- <key>Persist</key>
- <integer>1</integer>
- <key>Type</key>
- <string>Rect</string>
- <key>Value</key>
- <array>
- <integer>0</integer>
- <integer>586</integer>
- <integer>576</integer>
- <integer>0</integer>
- </array>
- </map>
- <key>PreviewSoundRect</key>
- <map>
- <key>Comment</key>
- <string>Rectangle for sound preview window</string>
- <key>Persist</key>
- <integer>1</integer>
- <key>Type</key>
- <string>Rect</string>
- <key>Value</key>
- <array>
- <integer>0</integer>
- <integer>85</integer>
- <integer>300</integer>
- <integer>0</integer>
- </array>
- </map>
- <key>PreviewTextureRect</key>
- <map>
- <key>Comment</key>
- <string>Rectangle for texture preview window</string>
- <key>Persist</key>
- <integer>1</integer>
- <key>Type</key>
- <string>Rect</string>
- <key>Value</key>
- <array>
- <integer>0</integer>
- <integer>400</integer>
- <integer>400</integer>
- <integer>0</integer>
- </array>
- </map>
- <key>PreviewURLRect</key>
- <map>
- <key>Comment</key>
- <string>Rectangle for URL preview window</string>
- <key>Persist</key>
- <integer>1</integer>
- <key>Type</key>
- <string>Rect</string>
- <key>Value</key>
- <array>
- <integer>0</integer>
- <integer>90</integer>
- <integer>300</integer>
- <integer>0</integer>
- </array>
- </map>
- <key>PreviewWearableRect</key>
- <map>
- <key>Comment</key>
- <string>Rectangle for wearable preview window</string>
- <key>Persist</key>
- <integer>1</integer>
- <key>Type</key>
- <string>Rect</string>
- <key>Value</key>
- <array>
- <integer>0</integer>
- <integer>85</integer>
- <integer>300</integer>
- <integer>0</integer>
- </array>
- </map>
<key>ProbeHardwareOnStartup</key>
<map>
<key>Comment</key>
@@ -6592,22 +5282,6 @@
<key>Value</key>
<integer>1</integer>
</map>
- <key>PropertiesRect</key>
- <map>
- <key>Comment</key>
- <string>Rectangle for inventory item properties window</string>
- <key>Persist</key>
- <integer>1</integer>
- <key>Type</key>
- <string>Rect</string>
- <key>Value</key>
- <array>
- <integer>0</integer>
- <integer>320</integer>
- <integer>350</integer>
- <integer>0</integer>
- </array>
- </map>
<key>PurgeCacheOnNextStartup</key>
<map>
<key>Comment</key>
@@ -6805,8 +5479,19 @@
<string>Boolean</string>
<key>Value</key>
<integer>1</integer>
- </map>
- <key>RenderAvatarCloth</key>
+ </map>
+ <key>RenderAvatar</key>
+ <map>
+ <key>Comment</key>
+ <string>Render Avatars</string>
+ <key>Persist</key>
+ <integer>0</integer>
+ <key>Type</key>
+ <string>Boolean</string>
+ <key>Value</key>
+ <integer>1</integer>
+ </map>
+ <key>RenderAvatarCloth</key>
<map>
<key>Comment</key>
<string>Controls if avatars use wavy cloth</string>
@@ -6989,16 +5674,16 @@
<key>Value</key>
<integer>1</integer>
</map>
- <key>RenderCustomSettings</key>
+ <key>RenderDebugAlphaMask</key>
<map>
<key>Comment</key>
- <string>Do you want to set the graphics settings yourself</string>
+ <string>Test Alpha Masking Cutoffs.</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
- <string>Boolean</string>
+ <string>F32</string>
<key>Value</key>
- <integer>0</integer>
+ <real>0.5</real>
</map>
<key>RenderDebugGL</key>
<map>
@@ -7427,7 +6112,7 @@
<key>Value</key>
<integer>0</integer>
</map>
- <key>RenderHideGroupTitleAll</key>
+ <key>RenderShowGroupTitleAll</key>
<map>
<key>Comment</key>
<string>Show group titles in name labels</string>
@@ -7436,7 +6121,7 @@
<key>Type</key>
<string>Boolean</string>
<key>Value</key>
- <integer>0</integer>
+ <integer>1</integer>
</map>
<key>RenderInitError</key>
<map>
@@ -7504,17 +6189,6 @@
<key>Value</key>
<integer>512</integer>
</map>
- <key>RenderName</key>
- <map>
- <key>Comment</key>
- <string>Controls display of names above avatars (0 = never, 1 = fade, 2 = always)</string>
- <key>Persist</key>
- <integer>1</integer>
- <key>Type</key>
- <string>S32</string>
- <key>Value</key>
- <integer>2</integer>
- </map>
<key>RenderNameFadeDuration</key>
<map>
<key>Comment</key>
@@ -7526,16 +6200,16 @@
<key>Value</key>
<real>1.0</real>
</map>
- <key>RenderNameHideSelf</key>
+ <key>RenderNameShowSelf</key>
<map>
<key>Comment</key>
- <string>Don't display own name above avatar</string>
+ <string>Display own name above avatar</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
<string>Boolean</string>
<key>Value</key>
- <integer>0</integer>
+ <integer>1</integer>
</map>
<key>RenderNameShowTime</key>
<map>
@@ -7944,22 +6618,6 @@
<key>Value</key>
<integer>0</integer>
</map>
- <key>ScriptErrorColor</key>
- <map>
- <key>Comment</key>
- <string>Color of script error messages</string>
- <key>Persist</key>
- <integer>1</integer>
- <key>Type</key>
- <string>Color4</string>
- <key>Value</key>
- <array>
- <real>0.8235294117</real>
- <real>0.2745098039</real>
- <real>0.2745098039</real>
- <real>1.0</real>
- </array>
- </map>
<key>ScriptErrorsAsChat</key>
<map>
<key>Comment</key>
@@ -8142,10 +6800,10 @@
<key>Value</key>
<integer>0</integer>
</map>
- <key>ShowActiveSpeakers</key>
+ <key>ShowAdvancedGraphicsSettings</key>
<map>
<key>Comment</key>
- <string>Display active speakers list on login</string>
+ <string>Show advanced graphics settings</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
@@ -8164,32 +6822,32 @@
<key>Value</key>
<integer>0</integer>
</map>
- <key>ShowAxes</key>
+ <key>AvatarNameTagMode</key>
<map>
<key>Comment</key>
- <string>Render coordinate frame at your position</string>
+ <string>Select Avatar Name Tag Mode</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
- <string>Boolean</string>
+ <string>S32</string>
<key>Value</key>
- <integer>0</integer>
+ <integer>1</integer>
</map>
- <key>ShowBanLines</key>
+ <key>ShowAxes</key>
<map>
<key>Comment</key>
- <string>Show in-world ban/access borders</string>
+ <string>Render coordinate frame at your position</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
<string>Boolean</string>
<key>Value</key>
- <integer>1</integer>
+ <integer>0</integer>
</map>
- <key>ShowCameraControls</key>
+ <key>ShowBanLines</key>
<map>
<key>Comment</key>
- <string>Display camera controls on login</string>
+ <string>Show in-world ban/access borders</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
@@ -8197,32 +6855,21 @@
<key>Value</key>
<integer>1</integer>
</map>
- <key>ShowChatHistory</key>
- <map>
- <key>Comment</key>
- <string />
- <key>Persist</key>
- <integer>0</integer>
- <key>Type</key>
- <string>Boolean</string>
- <key>Value</key>
- <integer>0</integer>
- </map>
- <key>ShowCommunicate</key>
+ <key>ShowConsoleWindow</key>
<map>
<key>Comment</key>
- <string />
+ <string>Show log in separate OS window</string>
<key>Persist</key>
- <integer>0</integer>
+ <integer>1</integer>
<key>Type</key>
<string>Boolean</string>
<key>Value</key>
<integer>0</integer>
</map>
- <key>ShowConsoleWindow</key>
+ <key>ShowCoordinatesOption</key>
<map>
<key>Comment</key>
- <string>Show log in separate OS window</string>
+ <string>Show Coordinates in Location Input Field</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
@@ -8252,28 +6899,6 @@
<key>Value</key>
<integer>0</integer>
</map>
- <key>ShowDebugStats</key>
- <map>
- <key>Comment</key>
- <string>Show performance stats display</string>
- <key>Persist</key>
- <integer>1</integer>
- <key>Type</key>
- <string>Boolean</string>
- <key>Value</key>
- <integer>0</integer>
- </map>
- <key>ShowDirectory</key>
- <map>
- <key>Comment</key>
- <string />
- <key>Persist</key>
- <integer>0</integer>
- <key>Type</key>
- <string>Boolean</string>
- <key>Value</key>
- <integer>0</integer>
- </map>
<key>ShowEmptyFoldersWhenSearching</key>
<map>
<key>Comment</key>
@@ -8296,40 +6921,40 @@
<key>Value</key>
<integer>1</integer>
</map>
- <key>ShowInventory</key>
+ <key>ShowLandHoverTip</key>
<map>
<key>Comment</key>
- <string>Open inventory window on login</string>
+ <string>Show descriptive tooltip when mouse hovers over land</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
<string>Boolean</string>
<key>Value</key>
<integer>0</integer>
- </map>
- <key>ShowLandHoverTip</key>
+ </map>
+ <key>ShowPGSearchAll</key>
<map>
<key>Comment</key>
- <string>Show descriptive tooltip when mouse hovers over land</string>
+ <string>Show/Hide Navigation Bar Favorites Panel</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
<string>Boolean</string>
<key>Value</key>
- <integer>0</integer>
+ <integer>1</integer>
</map>
- <key>ShowLeaders</key>
+ <key>ShowNavbarFavoritesPanel</key>
<map>
<key>Comment</key>
- <string />
+ <string>Show/Hide Navigation Bar Navigation Panel</string>
<key>Persist</key>
- <integer>0</integer>
+ <integer>1</integer>
<key>Type</key>
<string>Boolean</string>
<key>Value</key>
- <integer>0</integer>
+ <integer>1</integer>
</map>
- <key>ShowPGSearchAll</key>
+ <key>ShowNavbarNavigationPanel</key>
<map>
<key>Comment</key>
<string>Display results of search All that are flagged as PG</string>
@@ -8563,28 +7188,6 @@
<key>Value</key>
<integer>0</integer>
</map>
- <key>ShowMiniMap</key>
- <map>
- <key>Comment</key>
- <string>Display mini map on login</string>
- <key>Persist</key>
- <integer>1</integer>
- <key>Type</key>
- <string>Boolean</string>
- <key>Value</key>
- <integer>0</integer>
- </map>
- <key>ShowMovementControls</key>
- <map>
- <key>Comment</key>
- <string>Display movement controls on login</string>
- <key>Persist</key>
- <integer>1</integer>
- <key>Type</key>
- <string>Boolean</string>
- <key>Value</key>
- <integer>1</integer>
- </map>
<key>ShowNearClip</key>
<map>
<key>Comment</key>
@@ -8673,7 +7276,7 @@
<key>Value</key>
<integer>0</integer>
</map>
- <key>ShowSearchBar</key>
+ <key>ShowNetStats</key>
<map>
<key>Comment</key>
<string>Show the Search Bar in the Status Overlay</string>
@@ -8682,7 +7285,7 @@
<key>Type</key>
<string>Boolean</string>
<key>Value</key>
- <integer>1</integer>
+ <integer>0</integer>
</map>
<key>ShowSelectionBeam</key>
<map>
@@ -8704,7 +7307,7 @@
<key>Type</key>
<string>Boolean</string>
<key>Value</key>
- <integer>0</integer>
+ <integer>1</integer>
</map>
<key>ShowTangentBasis</key>
<map>
@@ -8728,17 +7331,6 @@
<key>Value</key>
<integer>1</integer>
</map>
- <key>ShowTools</key>
- <map>
- <key>Comment</key>
- <string />
- <key>Persist</key>
- <integer>0</integer>
- <key>Type</key>
- <string>Boolean</string>
- <key>Value</key>
- <integer>0</integer>
- </map>
<key>ShowTutorial</key>
<map>
<key>Comment</key>
@@ -8772,17 +7364,6 @@
<key>Value</key>
<integer>0</integer>
</map>
- <key>ShowWorldMap</key>
- <map>
- <key>Comment</key>
- <string>Display world map on login</string>
- <key>Persist</key>
- <integer>1</integer>
- <key>Type</key>
- <string>Boolean</string>
- <key>Value</key>
- <integer>0</integer>
- </map>
<key>ShowXUINames</key>
<map>
<key>Comment</key>
@@ -8816,6 +7397,17 @@
<key>Value</key>
<string>default</string>
</map>
+ <key>SkinningSettingsFile</key>
+ <map>
+ <key>Comment</key>
+ <string>Client skin color setting file name (per install).</string>
+ <key>Persist</key>
+ <integer>0</integer>
+ <key>Type</key>
+ <string>String</string>
+ <key>Value</key>
+ <string />
+ </map>
<key>SkyAmbientScale</key>
<map>
<key>Comment</key>
@@ -8848,8 +7440,8 @@
<string>Color3</string>
<key>Value</key>
<array>
- <real>0.699999988079</real>
- <real>0.699999988079</real>
+ <real>0.67</real>
+ <real>0.67</real>
<real>1.0</real>
</array>
</map>
@@ -8890,38 +7482,6 @@
<key>Value</key>
<integer>1</integer>
</map>
- <key>SlideLeftBtnRect</key>
- <map>
- <key>Comment</key>
- <string />
- <key>Persist</key>
- <integer>0</integer>
- <key>Type</key>
- <string>Rect</string>
- <key>Value</key>
- <array>
- <integer>20</integer>
- <integer>54</integer>
- <integer>45</integer>
- <integer>29</integer>
- </array>
- </map>
- <key>SlideRightBtnRect</key>
- <map>
- <key>Comment</key>
- <string />
- <key>Persist</key>
- <integer>0</integer>
- <key>Type</key>
- <string>Rect</string>
- <key>Value</key>
- <array>
- <integer>66</integer>
- <integer>54</integer>
- <integer>91</integer>
- <integer>29</integer>
- </array>
- </map>
<key>SmallAvatarNames</key>
<map>
<key>Comment</key>
@@ -9021,22 +7581,6 @@
<key>Value</key>
<integer>0</integer>
</map>
- <key>SpeakingColor</key>
- <map>
- <key>Comment</key>
- <string>Color of various indicators when resident is speaking on a voice channel.</string>
- <key>Persist</key>
- <integer>1</integer>
- <key>Type</key>
- <string>Color4</string>
- <key>Value</key>
- <array>
- <real>0.0</real>
- <real>1.0</real>
- <real>0.0</real>
- <real>1.0</real>
- </array>
- </map>
<key>SpeedTest</key>
<map>
<key>Comment</key>
@@ -9125,44 +7669,6 @@
<key>Value</key>
<string>fss.txt</string>
</map>
- <key>StatusBarHeight</key>
- <map>
- <key>Comment</key>
- <string>Height of menu/status bar at top of screen (pixels)</string>
- <key>Persist</key>
- <integer>1</integer>
- <key>Type</key>
- <string>S32</string>
- <key>Value</key>
- <integer>26</integer>
- </map>
- <key>StatusBarPad</key>
- <map>
- <key>Comment</key>
- <string>Spacing between popup buttons at bottom of screen (Stand up, Release Controls)</string>
- <key>Persist</key>
- <integer>1</integer>
- <key>Type</key>
- <string>S32</string>
- <key>Value</key>
- <integer>10</integer>
- </map>
- <key>SystemChatColor</key>
- <map>
- <key>Comment</key>
- <string>Color of chat messages from SL System</string>
- <key>Persist</key>
- <integer>1</integer>
- <key>Type</key>
- <string>Color4</string>
- <key>Value</key>
- <array>
- <real>0.800000011921</real>
- <real>1.0</real>
- <real>1.0</real>
- <real>1.0</real>
- </array>
- </map>
<key>SystemLanguage</key>
<map>
<key>Comment</key>
@@ -9172,7 +7678,7 @@
<key>Type</key>
<string>String</string>
<key>Value</key>
- <string>en-us</string>
+ <string>en</string>
</map>
<key>TabToTextFieldsOnly</key>
<map>
@@ -9218,22 +7724,6 @@
<key>Value</key>
<integer>0</integer>
</map>
- <key>TexturePickerRect</key>
- <map>
- <key>Comment</key>
- <string>Rectangle for texture picker</string>
- <key>Persist</key>
- <integer>1</integer>
- <key>Type</key>
- <string>Rect</string>
- <key>Value</key>
- <array>
- <integer>0</integer>
- <integer>290</integer>
- <integer>350</integer>
- <integer>0</integer>
- </array>
- </map>
<key>TexturePickerShowFolders</key>
<map>
<key>Comment</key>
@@ -9278,22 +7768,6 @@
<key>Value</key>
<real>500.0</real>
</map>
- <key>ToolHelpRect</key>
- <map>
- <key>Comment</key>
- <string />
- <key>Persist</key>
- <integer>0</integer>
- <key>Type</key>
- <string>Rect</string>
- <key>Value</key>
- <array>
- <integer>8</integer>
- <integer>178</integer>
- <integer>75</integer>
- <integer>162</integer>
- </array>
- </map>
<key>ToolTipDelay</key>
<map>
<key>Comment</key>
@@ -9305,32 +7779,27 @@
<key>Value</key>
<real>0.699999988079</real>
</map>
- <key>ToolboxAutoMove</key>
+ <key>ToolTipFadeTime</key>
<map>
<key>Comment</key>
- <string>[NOT USED]</string>
+ <string>Seconds over which tooltip fades away</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
- <string>Boolean</string>
+ <string>F32</string>
<key>Value</key>
- <integer>0</integer>
+ <real>0.2</real>
</map>
- <key>ToolboxRect</key>
+ <key>ToolboxAutoMove</key>
<map>
<key>Comment</key>
- <string>Rectangle for tools window</string>
+ <string>[NOT USED]</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
- <string>Rect</string>
+ <string>Boolean</string>
<key>Value</key>
- <array>
- <integer>0</integer>
- <integer>100</integer>
- <integer>100</integer>
- <integer>100</integer>
- </array>
+ <integer>0</integer>
</map>
<key>TrackFocusObject</key>
<map>
@@ -9343,38 +7812,6 @@
<key>Value</key>
<integer>1</integer>
</map>
- <key>TurnLeftBtnRect</key>
- <map>
- <key>Comment</key>
- <string />
- <key>Persist</key>
- <integer>0</integer>
- <key>Type</key>
- <string>Rect</string>
- <key>Value</key>
- <array>
- <integer>20</integer>
- <integer>29</integer>
- <integer>45</integer>
- <integer>4</integer>
- </array>
- </map>
- <key>TurnRightBtnRect</key>
- <map>
- <key>Comment</key>
- <string />
- <key>Persist</key>
- <integer>0</integer>
- <key>Type</key>
- <string>Rect</string>
- <key>Value</key>
- <array>
- <integer>66</integer>
- <integer>29</integer>
- <integer>91</integer>
- <integer>4</integer>
- </array>
- </map>
<key>TutorialURL</key>
<map>
<key>Comment</key>
@@ -9408,634 +7845,205 @@
<key>Value</key>
<integer>1</integer>
</map>
- <key>UIFloaterTestBool</key>
+ <key>UIAvatariconctrlSymbolHPad</key>
<map>
<key>Comment</key>
- <string>Example saved setting for the test floater</string>
+ <string>UI Avatar Icon Control Symbol Horizontal Pad</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
- <string>Boolean</string>
- <key>Value</key>
- <integer>0</integer>
- </map>
- <key>UIImgBtnCloseActiveUUID</key>
- <map>
- <key>Comment</key>
- <string />
- <key>Persist</key>
- <integer>0</integer>
- <key>Type</key>
- <string>String</string>
- <key>Value</key>
- <string>47a8c844-cd2a-4b1a-be01-df8b1612fe5d</string>
- </map>
- <key>UIImgBtnCloseInactiveUUID</key>
- <map>
- <key>Comment</key>
- <string />
- <key>Persist</key>
- <integer>0</integer>
- <key>Type</key>
- <string>String</string>
- <key>Value</key>
- <string>779e4fa3-9b13-f74a-fba9-3886fe9c86ba</string>
- </map>
- <key>UIImgBtnClosePressedUUID</key>
- <map>
- <key>Comment</key>
- <string />
- <key>Persist</key>
- <integer>0</integer>
- <key>Type</key>
- <string>String</string>
- <key>Value</key>
- <string>e5821134-23c0-4bd0-af06-7fa95b9fb01a</string>
- </map>
- <key>UIImgBtnForwardInUUID</key>
- <map>
- <key>Comment</key>
- <string />
- <key>Persist</key>
- <integer>0</integer>
- <key>Type</key>
- <string>String</string>
- <key>Value</key>
- <string>54197a61-f5d1-4c29-95d2-c071d08849cb</string>
- </map>
- <key>UIImgBtnForwardOutUUID</key>
- <map>
- <key>Comment</key>
- <string />
- <key>Persist</key>
- <integer>0</integer>
- <key>Type</key>
- <string>String</string>
- <key>Value</key>
- <string>a0eb4021-1b20-4a53-892d-8faa9265a6f5</string>
- </map>
- <key>UIImgBtnJumpLeftInUUID</key>
- <map>
- <key>Comment</key>
- <string />
- <key>Persist</key>
- <integer>0</integer>
- <key>Type</key>
- <string>String</string>
- <key>Value</key>
- <string>9cad3e6d-2d6d-107d-f8ab-5ba272b5bfe1</string>
- </map>
- <key>UIImgBtnJumpLeftOutUUID</key>
- <map>
- <key>Comment</key>
- <string />
- <key>Persist</key>
- <integer>0</integer>
- <key>Type</key>
- <string>String</string>
- <key>Value</key>
- <string>3c18c87e-5f50-14e2-e744-f44734aa365f</string>
- </map>
- <key>UIImgBtnJumpRightInUUID</key>
- <map>
- <key>Comment</key>
- <string />
- <key>Persist</key>
- <integer>0</integer>
- <key>Type</key>
- <string>String</string>
- <key>Value</key>
- <string>7dabc040-ec13-2309-ddf7-4f161f6de2f4</string>
- </map>
- <key>UIImgBtnJumpRightOutUUID</key>
- <map>
- <key>Comment</key>
- <string />
- <key>Persist</key>
- <integer>0</integer>
- <key>Type</key>
- <string>String</string>
- <key>Value</key>
- <string>ff9a71eb-7414-4cf8-866e-a701deb7c3cf</string>
- </map>
- <key>UIImgBtnLeftInUUID</key>
- <map>
- <key>Comment</key>
- <string />
- <key>Persist</key>
- <integer>0</integer>
- <key>Type</key>
- <string>String</string>
- <key>Value</key>
- <string>95463c78-aaa6-464d-892d-3a805b6bb7bf</string>
- </map>
- <key>UIImgBtnLeftOutUUID</key>
- <map>
- <key>Comment</key>
- <string />
- <key>Persist</key>
- <integer>0</integer>
- <key>Type</key>
- <string>String</string>
- <key>Value</key>
- <string>13a93910-6b44-45eb-ad3a-4d1324c59bac</string>
- </map>
- <key>UIImgBtnMinimizeActiveUUID</key>
- <map>
- <key>Comment</key>
- <string />
- <key>Persist</key>
- <integer>0</integer>
- <key>Type</key>
- <string>String</string>
- <key>Value</key>
- <string>34c9398d-bb78-4643-9633-46a2fa3e9637</string>
- </map>
- <key>UIImgBtnMinimizeInactiveUUID</key>
- <map>
- <key>Comment</key>
- <string />
- <key>Persist</key>
- <integer>0</integer>
- <key>Type</key>
- <string>String</string>
- <key>Value</key>
- <string>6e72abba-1378-437f-bf7a-f0c15f3e99a3</string>
- </map>
- <key>UIImgBtnMinimizePressedUUID</key>
- <map>
- <key>Comment</key>
- <string />
- <key>Persist</key>
- <integer>0</integer>
- <key>Type</key>
- <string>String</string>
- <key>Value</key>
- <string>39801651-26cb-4926-af57-7af9352c273c</string>
- </map>
- <key>UIImgBtnMoveDownInUUID</key>
- <map>
- <key>Comment</key>
- <string />
- <key>Persist</key>
- <integer>0</integer>
- <key>Type</key>
- <string>String</string>
- <key>Value</key>
- <string>b92a70b9-c841-4c94-b4b3-cee9eb460d48</string>
- </map>
- <key>UIImgBtnMoveDownOutUUID</key>
- <map>
- <key>Comment</key>
- <string />
- <key>Persist</key>
- <integer>0</integer>
- <key>Type</key>
- <string>String</string>
- <key>Value</key>
- <string>b5abc9fa-9e62-4e03-bc33-82c4c1b6b689</string>
- </map>
- <key>UIImgBtnMoveUpInUUID</key>
- <map>
- <key>Comment</key>
- <string />
- <key>Persist</key>
- <integer>0</integer>
- <key>Type</key>
- <string>String</string>
- <key>Value</key>
- <string>49b4b357-e430-4b56-b9e0-05b8759c3c82</string>
- </map>
- <key>UIImgBtnMoveUpOutUUID</key>
- <map>
- <key>Comment</key>
- <string />
- <key>Persist</key>
- <integer>0</integer>
- <key>Type</key>
- <string>String</string>
- <key>Value</key>
- <string>f887146d-829f-4e39-9211-cf872b78f97c</string>
- </map>
- <key>UIImgBtnPanDownInUUID</key>
- <map>
- <key>Comment</key>
- <string />
- <key>Persist</key>
- <integer>0</integer>
- <key>Type</key>
- <string>String</string>
- <key>Value</key>
- <string>e5821134-23c0-4bd0-af06-7fa95b9fb01a</string>
- </map>
- <key>UIImgBtnPanDownOutUUID</key>
- <map>
- <key>Comment</key>
- <string />
- <key>Persist</key>
- <integer>0</integer>
- <key>Type</key>
- <string>String</string>
- <key>Value</key>
- <string>47a8c844-cd2a-4b1a-be01-df8b1612fe5d</string>
- </map>
- <key>UIImgBtnPanLeftInUUID</key>
- <map>
- <key>Comment</key>
- <string />
- <key>Persist</key>
- <integer>0</integer>
- <key>Type</key>
- <string>String</string>
- <key>Value</key>
- <string>e5821134-23c0-4bd0-af06-7fa95b9fb01a</string>
- </map>
- <key>UIImgBtnPanLeftOutUUID</key>
- <map>
- <key>Comment</key>
- <string />
- <key>Persist</key>
- <integer>0</integer>
- <key>Type</key>
- <string>String</string>
- <key>Value</key>
- <string>47a8c844-cd2a-4b1a-be01-df8b1612fe5d</string>
- </map>
- <key>UIImgBtnPanRightInUUID</key>
- <map>
- <key>Comment</key>
- <string />
- <key>Persist</key>
- <integer>0</integer>
- <key>Type</key>
- <string>String</string>
- <key>Value</key>
- <string>e5821134-23c0-4bd0-af06-7fa95b9fb01a</string>
- </map>
- <key>UIImgBtnPanRightOutUUID</key>
- <map>
- <key>Comment</key>
- <string />
- <key>Persist</key>
- <integer>0</integer>
- <key>Type</key>
- <string>String</string>
- <key>Value</key>
- <string>47a8c844-cd2a-4b1a-be01-df8b1612fe5d</string>
- </map>
- <key>UIImgBtnPanUpInUUID</key>
- <map>
- <key>Comment</key>
- <string />
- <key>Persist</key>
- <integer>0</integer>
- <key>Type</key>
- <string>String</string>
- <key>Value</key>
- <string>e5821134-23c0-4bd0-af06-7fa95b9fb01a</string>
- </map>
- <key>UIImgBtnPanUpOutUUID</key>
- <map>
- <key>Comment</key>
- <string />
- <key>Persist</key>
- <integer>0</integer>
- <key>Type</key>
- <string>String</string>
- <key>Value</key>
- <string>47a8c844-cd2a-4b1a-be01-df8b1612fe5d</string>
- </map>
- <key>UIImgBtnRestoreActiveUUID</key>
- <map>
- <key>Comment</key>
- <string />
- <key>Persist</key>
- <integer>0</integer>
- <key>Type</key>
- <string>String</string>
- <key>Value</key>
- <string>111b39de-8928-4690-b7b2-e17d5c960277</string>
- </map>
- <key>UIImgBtnRestoreInactiveUUID</key>
- <map>
- <key>Comment</key>
- <string />
- <key>Persist</key>
- <integer>0</integer>
- <key>Type</key>
- <string>String</string>
- <key>Value</key>
- <string>0eafa471-70af-4882-b8c1-40a310929744</string>
- </map>
- <key>UIImgBtnRestorePressedUUID</key>
- <map>
- <key>Comment</key>
- <string />
- <key>Persist</key>
- <integer>0</integer>
- <key>Type</key>
- <string>String</string>
- <key>Value</key>
- <string>90a0ed5c-2e7b-4845-9958-a64a1b30f312</string>
- </map>
- <key>UIImgBtnRightInUUID</key>
- <map>
- <key>Comment</key>
- <string />
- <key>Persist</key>
- <integer>0</integer>
- <key>Type</key>
- <string>String</string>
- <key>Value</key>
- <string>5e616d0d-4335-476f-9977-560bccd009da</string>
- </map>
- <key>UIImgBtnRightOutUUID</key>
- <map>
- <key>Comment</key>
- <string />
- <key>Persist</key>
- <integer>0</integer>
- <key>Type</key>
- <string>String</string>
- <key>Value</key>
- <string>5a44fd04-f52b-4c30-8b00-4a31e27614bd</string>
- </map>
- <key>UIImgBtnScrollDownInUUID</key>
- <map>
- <key>Comment</key>
- <string />
- <key>Persist</key>
- <integer>0</integer>
- <key>Type</key>
- <string>String</string>
- <key>Value</key>
- <string>d2421bab-2eaf-4863-b8f6-5e4c52519247</string>
- </map>
- <key>UIImgBtnScrollDownOutUUID</key>
- <map>
- <key>Comment</key>
- <string />
- <key>Persist</key>
- <integer>0</integer>
- <key>Type</key>
- <string>String</string>
- <key>Value</key>
- <string>b4ecdecf-5c8d-44e7-b882-17a77e88ed55</string>
- </map>
- <key>UIImgBtnScrollLeftInUUID</key>
- <map>
- <key>Comment</key>
- <string />
- <key>Persist</key>
- <integer>0</integer>
- <key>Type</key>
- <string>String</string>
- <key>Value</key>
- <string>ea137a32-6718-4d05-9c22-7d570d27b2cd</string>
- </map>
- <key>UIImgBtnScrollLeftOutUUID</key>
- <map>
- <key>Comment</key>
- <string />
- <key>Persist</key>
- <integer>0</integer>
- <key>Type</key>
- <string>String</string>
- <key>Value</key>
- <string>43773e8d-49aa-48e0-80f3-a04715f4677a</string>
- </map>
- <key>UIImgBtnScrollRightInUUID</key>
- <map>
- <key>Comment</key>
- <string />
- <key>Persist</key>
- <integer>0</integer>
- <key>Type</key>
- <string>String</string>
- <key>Value</key>
- <string>b749de64-e903-4c3c-ac0b-25fb6fa39cb5</string>
- </map>
- <key>UIImgBtnScrollRightOutUUID</key>
- <map>
- <key>Comment</key>
- <string />
- <key>Persist</key>
- <integer>0</integer>
- <key>Type</key>
- <string>String</string>
- <key>Value</key>
- <string>3d700d19-e708-465d-87f2-46c8c0ee7938</string>
- </map>
- <key>UIImgBtnScrollUpInUUID</key>
- <map>
- <key>Comment</key>
- <string />
- <key>Persist</key>
- <integer>0</integer>
- <key>Type</key>
- <string>String</string>
+ <string>S32</string>
<key>Value</key>
- <string>a93abdf3-27b5-4e22-a8fa-c48216cd2e3a</string>
- </map>
- <key>UIImgBtnScrollUpOutUUID</key>
+ <real>2</real>
+ </map>
+ <key>UIAvatariconctrlSymbolVPad</key>
<map>
<key>Comment</key>
- <string />
+ <string>UI Avatar Icon Control Symbol Vertical Pad</string>
<key>Persist</key>
- <integer>0</integer>
+ <integer>1</integer>
<key>Type</key>
- <string>String</string>
+ <string>S32</string>
<key>Value</key>
- <string>dad084d7-9a46-452a-b0ff-4b9f1cefdde9</string>
- </map>
- <key>UIImgBtnSlideLeftInUUID</key>
+ <real>2</real>
+ </map>
+ <key>UIAvatariconctrlSymbolSize</key>
<map>
<key>Comment</key>
- <string />
+ <string>UI Avatar Icon Control Symbol Size</string>
<key>Persist</key>
- <integer>0</integer>
+ <integer>1</integer>
<key>Type</key>
- <string>String</string>
+ <string>S32</string>
<key>Value</key>
- <string>724996f5-b956-46f6-9844-4fcfce1d5e83</string>
- </map>
- <key>UIImgBtnSlideLeftOutUUID</key>
+ <real>5</real>
+ </map>
+ <key>UIAvatariconctrlSymbolPosition</key>
<map>
<key>Comment</key>
- <string />
+ <string>UI Avatar Icon Control Symbol Position (TopLeft|TopRight|BottomLeft|BottomRight)</string>
<key>Persist</key>
- <integer>0</integer>
+ <integer>1</integer>
<key>Type</key>
<string>String</string>
<key>Value</key>
- <string>82476321-0374-4c26-9567-521535ab4cd7</string>
+ <string>BottomRight</string>
</map>
- <key>UIImgBtnSlideRightInUUID</key>
+ <key>UIButtonOrigHPad</key>
<map>
<key>Comment</key>
- <string />
+ <string>UI Button Original Horizontal Pad</string>
<key>Persist</key>
- <integer>0</integer>
+ <integer>1</integer>
<key>Type</key>
- <string>String</string>
+ <string>S32</string>
<key>Value</key>
- <string>7eeb57d2-3f37-454d-a729-8b217b8be443</string>
+ <real>6</real>
</map>
- <key>UIImgBtnSlideRightOutUUID</key>
+ <key>UICheckboxctrlBtnSize</key>
<map>
<key>Comment</key>
- <string />
+ <string>UI Checkbox Control Button Size</string>
<key>Persist</key>
- <integer>0</integer>
+ <integer>1</integer>
<key>Type</key>
- <string>String</string>
+ <string>S32</string>
<key>Value</key>
- <string>1fbe4e60-0607-44d1-a50a-032eff56ae75</string>
+ <real>13</real>
</map>
- <key>UIImgBtnSpinDownInUUID</key>
+ <key>UICheckboxctrlHeight</key>
<map>
<key>Comment</key>
- <string />
+ <string>UI Checkbox Control Height</string>
<key>Persist</key>
- <integer>0</integer>
+ <integer>1</integer>
<key>Type</key>
- <string>String</string>
+ <string>S32</string>
<key>Value</key>
- <string>a985ac71-052f-48e6-9c33-d931c813ac92</string>
+ <real>16</real>
</map>
- <key>UIImgBtnSpinDownOutUUID</key>
+ <key>UICheckboxctrlHPad</key>
<map>
<key>Comment</key>
- <string />
+ <string>UI Checkbox Control Horizontal Pad</string>
<key>Persist</key>
- <integer>0</integer>
+ <integer>1</integer>
<key>Type</key>
- <string>String</string>
+ <string>S32</string>
<key>Value</key>
- <string>b6d240dd-5602-426f-b606-bbb49a30726d</string>
+ <real>2</real>
</map>
- <key>UIImgBtnSpinUpInUUID</key>
+ <key>UICheckboxctrlSpacing</key>
<map>
<key>Comment</key>
- <string />
+ <string>UI Checkbox Control Spacing</string>
<key>Persist</key>
- <integer>0</integer>
+ <integer>1</integer>
<key>Type</key>
- <string>String</string>
+ <string>S32</string>
<key>Value</key>
- <string>c8450082-96a0-4319-8090-d3ff900b4954</string>
+ <real>5</real>
</map>
- <key>UIImgBtnSpinUpOutUUID</key>
+ <key>UICheckboxctrlVPad</key>
<map>
<key>Comment</key>
- <string />
+ <string>UI Checkbox Control Vertical Pad</string>
<key>Persist</key>
- <integer>0</integer>
+ <integer>1</integer>
<key>Type</key>
- <string>String</string>
+ <string>S32</string>
<key>Value</key>
- <string>56576e6e-6710-4e66-89f9-471b59122794</string>
+ <real>2</real>
</map>
- <key>UIImgBtnTabBottomInUUID</key>
+ <key>UICloseBoxFromTop</key>
<map>
<key>Comment</key>
- <string />
+ <string>Size of UI floater close box from top</string>
<key>Persist</key>
- <integer>0</integer>
+ <integer>1</integer>
<key>Type</key>
- <string>String</string>
+ <string>S32</string>
<key>Value</key>
- <string>c001d8fd-a869-4b6f-86a1-fdcb106df9c7</string>
+ <real>1</real>
</map>
- <key>UIImgBtnTabBottomOutUUID</key>
+ <key>UIExtraTriangleHeight</key>
<map>
<key>Comment</key>
- <string />
+ <string>UI extra triangle height</string>
<key>Persist</key>
- <integer>0</integer>
+ <integer>1</integer>
<key>Type</key>
- <string>String</string>
+ <string>S32</string>
<key>Value</key>
- <string>bf0a8779-689b-48c3-bb9a-6af546366ef4</string>
+ <real>-2</real>
</map>
- <key>UIImgBtnTabBottomPartialInUUID</key>
+ <key>UIExtraTriangleWidth</key>
<map>
<key>Comment</key>
- <string />
+ <string>UI extra triangle width</string>
<key>Persist</key>
- <integer>0</integer>
+ <integer>1</integer>
<key>Type</key>
- <string>String</string>
+ <string>S32</string>
<key>Value</key>
- <string>eb0b0904-8c91-4f24-b500-1180b91140de</string>
+ <real>2</real>
</map>
- <key>UIImgBtnTabBottomPartialOutUUID</key>
+ <key>UIFloaterCloseBoxSize</key>
<map>
<key>Comment</key>
- <string />
+ <string>Size of UI floater close box size</string>
<key>Persist</key>
- <integer>0</integer>
+ <integer>1</integer>
<key>Type</key>
- <string>String</string>
+ <string>S32</string>
<key>Value</key>
- <string>8dca716c-b29c-403a-9886-91c028357d6e</string>
+ <real>16</real>
</map>
- <key>UIImgBtnTabTopInUUID</key>
+ <key>UIFloaterHeaderSize</key>
<map>
<key>Comment</key>
- <string />
+ <string>Size of UI floater header size</string>
<key>Persist</key>
- <integer>0</integer>
+ <integer>1</integer>
<key>Type</key>
- <string>String</string>
+ <string>S32</string>
<key>Value</key>
- <string>16d032e8-817b-4368-8a4e-b7b947ae3889</string>
+ <real>18</real>
</map>
- <key>UIImgBtnTabTopOutUUID</key>
+ <key>UIFloaterHPad</key>
<map>
<key>Comment</key>
- <string />
+ <string>Size of UI floater horizontal pad</string>
<key>Persist</key>
- <integer>0</integer>
+ <integer>1</integer>
<key>Type</key>
- <string>String</string>
+ <string>S32</string>
<key>Value</key>
- <string>1ed83f57-41cf-4052-a3b4-2e8bb78d8191</string>
+ <real>6</real>
</map>
- <key>UIImgBtnTabTopPartialInUUID</key>
+ <key>UIFloaterTestBool</key>
<map>
<key>Comment</key>
- <string />
+ <string>Example saved setting for the test floater</string>
<key>Persist</key>
- <integer>0</integer>
+ <integer>1</integer>
<key>Type</key>
- <string>String</string>
+ <string>Boolean</string>
<key>Value</key>
- <string>7c6c6c26-0e25-4438-89bd-30d8b8e9d704</string>
- </map>
- <key>UIImgBtnTabTopPartialOutUUID</key>
- <map>
- <key>Comment</key>
- <string />
- <key>Persist</key>
<integer>0</integer>
- <key>Type</key>
- <string>String</string>
- <key>Value</key>
- <string>932ad585-0e45-4a57-aa23-4cf81beeb7b0</string>
</map>
- <key>UIImgBtnTearOffActiveUUID</key>
+ <key>UIFloaterVPad</key>
<map>
<key>Comment</key>
- <string />
+ <string>Size of UI floater vertical pad</string>
<key>Persist</key>
- <integer>0</integer>
+ <integer>1</integer>
<key>Type</key>
- <string>String</string>
+ <string>S32</string>
<key>Value</key>
- <string>74e1a96f-4833-a24d-a1bb-1bce1468b0e7</string>
+ <real>6</real>
</map>
- <key>UIImgBtnTearOffInactiveUUID</key>
+ <key>UIImgDefaultEyesUUID</key>
<map>
<key>Comment</key>
<string />
@@ -10044,9 +8052,9 @@
<key>Type</key>
<string>String</string>
<key>Value</key>
- <string>74e1a96f-4833-a24d-a1bb-1bce1468b0e7</string>
+ <string>6522e74d-1660-4e7f-b601-6f48c1659a77</string>
</map>
- <key>UIImgBtnTearOffPressedUUID</key>
+ <key>UIImgDefaultGlovesUUID</key>
<map>
<key>Comment</key>
<string />
@@ -10055,9 +8063,9 @@
<key>Type</key>
<string>String</string>
<key>Value</key>
- <string>d2524c13-4ba6-af7c-e305-8ac6cc18d86a</string>
+ <string>5748decc-f629-461c-9a36-a35a221fe21f</string>
</map>
- <key>UIImgCheckboxActiveSelectedUUID</key>
+ <key>UIImgDefaultHairUUID</key>
<map>
<key>Comment</key>
<string />
@@ -10066,9 +8074,9 @@
<key>Type</key>
<string>String</string>
<key>Value</key>
- <string>cf4a2ed7-1533-4686-9dde-df9a37ddca55</string>
+ <string>7ca39b4c-bd19-4699-aff7-f93fd03d3e7b</string>
</map>
- <key>UIImgCheckboxActiveUUID</key>
+ <key>UIImgDefaultJacketUUID</key>
<map>
<key>Comment</key>
<string />
@@ -10077,9 +8085,9 @@
<key>Type</key>
<string>String</string>
<key>Value</key>
- <string>05bb64ee-96fd-4243-b74e-f40a41bc53ba</string>
+ <string>5748decc-f629-461c-9a36-a35a221fe21f</string>
</map>
- <key>UIImgCheckboxInactiveSelectedUUID</key>
+ <key>UIImgDefaultPantsUUID</key>
<map>
<key>Comment</key>
<string />
@@ -10088,9 +8096,9 @@
<key>Type</key>
<string>String</string>
<key>Value</key>
- <string>c817c642-9abd-4236-9287-ae0513fe7d2b</string>
+ <string>5748decc-f629-461c-9a36-a35a221fe21f</string>
</map>
- <key>UIImgCheckboxInactiveUUID</key>
+ <key>UIImgDefaultShirtUUID</key>
<map>
<key>Comment</key>
<string />
@@ -10099,9 +8107,9 @@
<key>Type</key>
<string>String</string>
<key>Value</key>
- <string>7d94cb59-32a2-49bf-a516-9e5a2045f9d9</string>
+ <string>5748decc-f629-461c-9a36-a35a221fe21f</string>
</map>
- <key>UIImgCreateSelectedUUID</key>
+ <key>UIImgDefaultShoesUUID</key>
<map>
<key>Comment</key>
<string />
@@ -10110,9 +8118,9 @@
<key>Type</key>
<string>String</string>
<key>Value</key>
- <string>0098b015-3daf-4cfe-a72f-915369ea97c2</string>
+ <string>5748decc-f629-461c-9a36-a35a221fe21f</string>
</map>
- <key>UIImgCreateUUID</key>
+ <key>UIImgDefaultSkirtUUID</key>
<map>
<key>Comment</key>
<string />
@@ -10121,20 +8129,9 @@
<key>Type</key>
<string>String</string>
<key>Value</key>
- <string>7a0b1bdb-b5d9-4df5-bac2-ba230da93b5b</string>
- </map>
- <key>UIImgCrosshairsUUID</key>
- <map>
- <key>Comment</key>
- <string>Image to use for crosshair display (UUID texture reference)</string>
- <key>Persist</key>
- <integer>1</integer>
- <key>Type</key>
- <string>String</string>
- <key>Value</key>
- <string>6e1a3980-bf2d-4274-8970-91e60d85fb52</string>
+ <string>5748decc-f629-461c-9a36-a35a221fe21f</string>
</map>
- <key>UIImgDefaultEyesUUID</key>
+ <key>UIImgDefaultSocksUUID</key>
<map>
<key>Comment</key>
<string />
@@ -10143,9 +8140,9 @@
<key>Type</key>
<string>String</string>
<key>Value</key>
- <string>6522e74d-1660-4e7f-b601-6f48c1659a77</string>
+ <string>5748decc-f629-461c-9a36-a35a221fe21f</string>
</map>
- <key>UIImgDefaultGlovesUUID</key>
+ <key>UIImgDefaultAlphaUUID</key>
<map>
<key>Comment</key>
<string />
@@ -10156,7 +8153,7 @@
<key>Value</key>
<string>5748decc-f629-461c-9a36-a35a221fe21f</string>
</map>
- <key>UIImgDefaultHairUUID</key>
+ <key>UIImgDefaultTattooUUID</key>
<map>
<key>Comment</key>
<string />
@@ -10165,9 +8162,9 @@
<key>Type</key>
<string>String</string>
<key>Value</key>
- <string>7ca39b4c-bd19-4699-aff7-f93fd03d3e7b</string>
+ <string>5748decc-f629-461c-9a36-a35a221fe21f</string>
</map>
- <key>UIImgDefaultJacketUUID</key>
+ <key>UIImgDefaultUnderwearUUID</key>
<map>
<key>Comment</key>
<string />
@@ -10178,7 +8175,7 @@
<key>Value</key>
<string>5748decc-f629-461c-9a36-a35a221fe21f</string>
</map>
- <key>UIImgDefaultPantsUUID</key>
+ <key>StartUpChannelUUID</key>
<map>
<key>Comment</key>
<string />
@@ -10187,9 +8184,9 @@
<key>Type</key>
<string>String</string>
<key>Value</key>
- <string>5748decc-f629-461c-9a36-a35a221fe21f</string>
- </map>
- <key>UIImgDefaultShirtUUID</key>
+ <string>B56AF90D-6684-48E4-B1E4-722D3DEB2CB6</string>
+ </map>
+ <key>NearByChatChannelUUID</key>
<map>
<key>Comment</key>
<string />
@@ -10198,9 +8195,9 @@
<key>Type</key>
<string>String</string>
<key>Value</key>
- <string>5748decc-f629-461c-9a36-a35a221fe21f</string>
- </map>
- <key>UIImgDefaultShoesUUID</key>
+ <string>E1158BD6-661C-4981-9DAD-4DCBFF062502</string>
+ </map>
+ <key>NotificationChannelUUID</key>
<map>
<key>Comment</key>
<string />
@@ -10209,9 +8206,9 @@
<key>Type</key>
<string>String</string>
<key>Value</key>
- <string>5748decc-f629-461c-9a36-a35a221fe21f</string>
- </map>
- <key>UIImgDefaultSkirtUUID</key>
+ <string>AEED3193-8709-4693-8558-7452CCA97AE5</string>
+ </map>
+ <key>AlertChannelUUID</key>
<map>
<key>Comment</key>
<string />
@@ -10220,9 +8217,9 @@
<key>Type</key>
<string>String</string>
<key>Value</key>
- <string>5748decc-f629-461c-9a36-a35a221fe21f</string>
- </map>
- <key>UIImgDefaultSocksUUID</key>
+ <string>F3E07BC8-A973-476D-8C7F-F3B7293975D1</string>
+ </map>
+ <key>UIImgWhiteUUID</key>
<map>
<key>Comment</key>
<string />
@@ -10233,236 +8230,236 @@
<key>Value</key>
<string>5748decc-f629-461c-9a36-a35a221fe21f</string>
</map>
- <key>UIImgDefaultUnderwearUUID</key>
+ <key>UILineEditorCursorThickness</key>
<map>
<key>Comment</key>
- <string />
+ <string>UI Line Editor Cursor Thickness</string>
<key>Persist</key>
- <integer>0</integer>
+ <integer>1</integer>
<key>Type</key>
- <string>String</string>
+ <string>S32</string>
<key>Value</key>
- <string>5748decc-f629-461c-9a36-a35a221fe21f</string>
+ <integer>2</integer>
</map>
- <key>UIImgDirectionArrowUUID</key>
+ <key>UILineEditorHPad</key>
<map>
<key>Comment</key>
- <string />
+ <string>UI Line Editor Horizontal Pad</string>
<key>Persist</key>
- <integer>0</integer>
+ <integer>1</integer>
<key>Type</key>
- <string>String</string>
+ <string>S32</string>
<key>Value</key>
- <string>586383e8-4d9b-4fba-9196-2b5938e79c2c</string>
+ <integer>2</integer>
</map>
- <key>UIImgFaceSelectedUUID</key>
+ <key>UILineEditorVPad</key>
<map>
<key>Comment</key>
- <string />
+ <string>UI Line Editor Vertical Pad</string>
<key>Persist</key>
- <integer>0</integer>
+ <integer>1</integer>
<key>Type</key>
- <string>String</string>
+ <string>S32</string>
<key>Value</key>
- <string>b4870163-6208-42a9-9801-93133bf9a6cd</string>
+ <integer>3</integer>
</map>
- <key>UIImgFaceUUID</key>
+ <key>UIMaxComboWidth</key>
<map>
<key>Comment</key>
- <string />
+ <string>Maximum width of combo box</string>
<key>Persist</key>
- <integer>0</integer>
+ <integer>1</integer>
<key>Type</key>
- <string>String</string>
+ <string>S32</string>
<key>Value</key>
- <string>ce15fd63-b0b6-463c-a37d-ea6393208b3e</string>
+ <real>500</real>
</map>
- <key>UIImgFocusSelectedUUID</key>
+ <key>UIMinimizedWidth</key>
<map>
<key>Comment</key>
- <string />
+ <string>Size of UI floater minimized width</string>
<key>Persist</key>
- <integer>0</integer>
+ <integer>1</integer>
<key>Type</key>
- <string>String</string>
+ <string>S32</string>
<key>Value</key>
- <string>ab6a730e-ddfd-4982-9a32-c6de3de6d31d</string>
+ <real>160</real>
</map>
- <key>UIImgFocusUUID</key>
+ <key>UIMultiSliderctrlSpacing</key>
<map>
<key>Comment</key>
- <string />
+ <string>UI multi slider ctrl spacing</string>
<key>Persist</key>
- <integer>0</integer>
+ <integer>1</integer>
<key>Type</key>
- <string>String</string>
+ <string>S32</string>
<key>Value</key>
- <string>57bc39d1-288c-4519-aea6-6d1786a5c274</string>
+ <real>4</real>
</map>
- <key>UIImgGrabSelectedUUID</key>
+ <key>UIMultiTrackHeight</key>
<map>
<key>Comment</key>
- <string />
+ <string>UI multi track height</string>
<key>Persist</key>
- <integer>0</integer>
+ <integer>1</integer>
<key>Type</key>
- <string>String</string>
+ <string>S32</string>
<key>Value</key>
- <string>c1e21504-f136-451d-b8e9-929037812f1d</string>
+ <real>6</real>
</map>
- <key>UIImgGrabUUID</key>
+ <key>UIPreeditMarkerBrightness</key>
<map>
<key>Comment</key>
- <string />
+ <string>UI Preedit Marker Brightness</string>
<key>Persist</key>
- <integer>0</integer>
+ <integer>1</integer>
<key>Type</key>
- <string>String</string>
+ <string>F32</string>
<key>Value</key>
- <string>c63f124c-6340-4fbf-b59e-0869a44adb64</string>
+ <real>0.4</real>
</map>
- <key>UIImgMoveSelectedUUID</key>
+ <key>UIPreeditMarkerGap</key>
<map>
<key>Comment</key>
- <string />
+ <string>UI Preedit Marker Gap</string>
<key>Persist</key>
- <integer>0</integer>
+ <integer>1</integer>
<key>Type</key>
- <string>String</string>
+ <string>S32</string>
<key>Value</key>
- <string>46f17c7b-8381-48c3-b628-6a406e060dd6</string>
+ <real>1</real>
</map>
- <key>UIImgMoveUUID</key>
+ <key>UIPreeditMarkerPosition</key>
<map>
<key>Comment</key>
- <string />
+ <string>UI Preedit Marker Position</string>
<key>Persist</key>
- <integer>0</integer>
+ <integer>1</integer>
<key>Type</key>
- <string>String</string>
+ <string>S32</string>
<key>Value</key>
- <string>2fa5dc06-bcdd-4e09-a426-f9f262d4fa65</string>
+ <integer>4</integer>
</map>
- <key>UIImgRadioActiveSelectedUUID</key>
+ <key>UIPreeditMarkerThickness</key>
<map>
<key>Comment</key>
- <string />
+ <string>UI Preedit Marker Thickness</string>
<key>Persist</key>
- <integer>0</integer>
+ <integer>1</integer>
<key>Type</key>
- <string>String</string>
+ <string>S32</string>
<key>Value</key>
- <string>52f09e07-5816-4052-953c-94c6c10479b7</string>
+ <real>1</real>
</map>
- <key>UIImgRadioActiveUUID</key>
+ <key>UIPreeditStandoutBrightness</key>
<map>
<key>Comment</key>
- <string />
+ <string>UI Preedit Standout Brightness</string>
<key>Persist</key>
- <integer>0</integer>
+ <integer>1</integer>
<key>Type</key>
- <string>String</string>
+ <string>F32</string>
<key>Value</key>
- <string>7a1ba9b8-1047-4d1e-9cfc-bc478c80b63f</string>
+ <real>0.6</real>
</map>
- <key>UIImgRadioInactiveSelectedUUID</key>
+ <key>UIPreeditStandoutGap</key>
<map>
<key>Comment</key>
- <string />
+ <string>UI Preedit Standout Gap</string>
<key>Persist</key>
- <integer>0</integer>
+ <integer>1</integer>
<key>Type</key>
- <string>String</string>
+ <string>S32</string>
<key>Value</key>
- <string>1975db39-aa29-4251-aea0-409ac09d414d</string>
+ <real>1</real>
</map>
- <key>UIImgRadioInactiveUUID</key>
+ <key>UIPreeditStandoutPosition</key>
<map>
<key>Comment</key>
- <string />
+ <string>UI Preedit Standout Position</string>
<key>Persist</key>
- <integer>0</integer>
+ <integer>1</integer>
<key>Type</key>
- <string>String</string>
+ <string>S32</string>
<key>Value</key>
- <string>90688481-67ff-4af0-be69-4aa084bcad1e</string>
+ <integer>4</integer>
</map>
- <key>UIImgResizeBottomRightUUID</key>
+ <key>UIPreeditStandoutThickness</key>
<map>
<key>Comment</key>
- <string />
+ <string>UI Preedit Standout Thickness</string>
<key>Persist</key>
- <integer>0</integer>
+ <integer>1</integer>
<key>Type</key>
- <string>String</string>
+ <string>S32</string>
<key>Value</key>
- <string>e3690e25-9690-4f6c-a745-e7dcd885285a</string>
+ <integer>2</integer>
</map>
- <key>UIImgRotateSelectedUUID</key>
+ <key>UIResizeBarHeight</key>
<map>
<key>Comment</key>
- <string />
+ <string>Size of UI resize bar height</string>
<key>Persist</key>
- <integer>0</integer>
+ <integer>1</integer>
<key>Type</key>
- <string>String</string>
+ <string>S32</string>
<key>Value</key>
- <string>cdfb7fde-0d13-418a-9d89-2bd91019fc95</string>
+ <real>3</real>
</map>
- <key>UIImgRotateUUID</key>
+ <key>UIResizeBarOverlap</key>
<map>
<key>Comment</key>
- <string />
+ <string>Size of UI resize bar overlap</string>
<key>Persist</key>
- <integer>0</integer>
+ <integer>1</integer>
<key>Type</key>
- <string>String</string>
+ <string>S32</string>
<key>Value</key>
- <string>c34b1eaa-aae3-4351-b082-e26c0b636779</string>
+ <real>1</real>
</map>
- <key>UIImgScaleSelectedUUID</key>
+ <key>UIScaleFactor</key>
<map>
<key>Comment</key>
- <string />
+ <string>Size of UI relative to default layout on 1024x768 screen</string>
<key>Persist</key>
- <integer>0</integer>
+ <integer>1</integer>
<key>Type</key>
- <string>String</string>
+ <string>F32</string>
<key>Value</key>
- <string>55aa57ef-508a-47f7-8867-85d21c5a810d</string>
+ <real>1.0</real>
</map>
- <key>UIImgScaleUUID</key>
+ <key>UIScrollbarSize</key>
<map>
<key>Comment</key>
- <string />
+ <string>UI scrollbar size</string>
<key>Persist</key>
- <integer>0</integer>
+ <integer>1</integer>
<key>Type</key>
- <string>String</string>
+ <string>S32</string>
<key>Value</key>
- <string>88a90fef-b448-4883-9344-ecf378a60433</string>
+ <real>15</real>
</map>
- <key>UIImgWhiteUUID</key>
+ <key>UISliderctrlHeight</key>
<map>
<key>Comment</key>
- <string />
+ <string>UI slider ctrl height</string>
<key>Persist</key>
- <integer>0</integer>
+ <integer>1</integer>
<key>Type</key>
- <string>String</string>
+ <string>S32</string>
<key>Value</key>
- <string>5748decc-f629-461c-9a36-a35a221fe21f</string>
+ <real>16</real>
</map>
- <key>UIScaleFactor</key>
+ <key>UISliderctrlSpacing</key>
<map>
<key>Comment</key>
- <string>Size of UI relative to default layout on 1024x768 screen</string>
+ <string>UI slider ctrl spacing</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
- <string>F32</string>
+ <string>S32</string>
<key>Value</key>
- <real>1.0</real>
+ <real>4</real>
</map>
<key>UISndAlert</key>
<map>
@@ -10827,6 +8824,193 @@
<key>Value</key>
<string>c80260ba-41fd-8a46-768a-6bf236360e3a</string>
</map>
+ <key>UISpinctrlBtnHeight</key>
+ <map>
+ <key>Comment</key>
+ <string>UI spin control button height</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>S32</string>
+ <key>Value</key>
+ <integer>8</integer>
+ </map>
+ <key>UISpinctrlBtnWidth</key>
+ <map>
+ <key>Comment</key>
+ <string>UI spin control button width</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>S32</string>
+ <key>Value</key>
+ <integer>16</integer>
+ </map>
+ <key>UISpinctrlDefaultLabelWidth</key>
+ <map>
+ <key>Comment</key>
+ <string>UI spin control default label width</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>S32</string>
+ <key>Value</key>
+ <integer>10</integer>
+ </map>
+ <key>UISpinctrlSpacing</key>
+ <map>
+ <key>Comment</key>
+ <string>UI spin control spacing</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>S32</string>
+ <key>Value</key>
+ <integer>2</integer>
+ </map>
+ <key>UITabCntrArrowBtnSize</key>
+ <map>
+ <key>Comment</key>
+ <string>UI Tab Container Arrow Button Size</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>S32</string>
+ <key>Value</key>
+ <integer>16</integer>
+ </map>
+ <key>UITabCntrvArrowBtnSize</key>
+ <map>
+ <key>Comment</key>
+ <string>UI Tab Container V Arrow Button Size</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>S32</string>
+ <key>Value</key>
+ <integer>16</integer>
+ </map>
+ <key>UITabCntrvPad</key>
+ <map>
+ <key>Comment</key>
+ <string>UI Tab Container V Pad</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>S32</string>
+ <key>Value</key>
+ <integer>0</integer>
+ </map>
+ <key>UITabCntrButtonPanelOverlap</key>
+ <map>
+ <key>Comment</key>
+ <string>UI Tab Container Button Panel Overlap</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>S32</string>
+ <key>Value</key>
+ <integer>1</integer>
+ </map>
+ <key>UITabCntrCloseBtnSize</key>
+ <map>
+ <key>Comment</key>
+ <string>UI Tab Container Close Button Size</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>S32</string>
+ <key>Value</key>
+ <integer>16</integer>
+ </map>
+ <key>UITabCntrTabHeight</key>
+ <map>
+ <key>Comment</key>
+ <string>UI Tab Container Tab Height</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>S32</string>
+ <key>Value</key>
+ <integer>16</integer>
+ </map>
+ <key>UITabCntrTabHPad</key>
+ <map>
+ <key>Comment</key>
+ <string>UI Tab Container Tab Horizontal Pad</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>S32</string>
+ <key>Value</key>
+ <integer>4</integer>
+ </map>
+ <key>UITabCntrTabPartialWidth</key>
+ <map>
+ <key>Comment</key>
+ <string>UI Tab Container Tab Partial Width</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>S32</string>
+ <key>Value</key>
+ <integer>12</integer>
+ </map>
+ <key>UITabCntrVertTabMinWidth</key>
+ <map>
+ <key>Comment</key>
+ <string>UI Tab Container Vertical Tab Minimum Width</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>S32</string>
+ <key>Value</key>
+ <integer>100</integer>
+ </map>
+ <key>UITabPadding</key>
+ <map>
+ <key>Comment</key>
+ <string>UI Tab Padding</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>S32</string>
+ <key>Value</key>
+ <integer>15</integer>
+ </map>
+ <key>UITextEditorBorder</key>
+ <map>
+ <key>Comment</key>
+ <string>UI Text Editor Border</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>S32</string>
+ <key>Value</key>
+ <integer>1</integer>
+ </map>
+ <key>UITextEditorHPad</key>
+ <map>
+ <key>Comment</key>
+ <string>UI Text Horizontal Pad</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>S32</string>
+ <key>Value</key>
+ <integer>4</integer>
+ </map>
+ <key>UITextEditorVPadTop</key>
+ <map>
+ <key>Comment</key>
+ <string>UI Text Vertical Pad Top</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>S32</string>
+ <key>Value</key>
+ <integer>4</integer>
+ </map>
<key>UploadBakedTexOld</key>
<map>
<key>Comment</key>
@@ -11312,335 +9496,27 @@
<key>Value</key>
<integer>44125</integer>
</map>
- <key>WLSkyDetail</key>
+ <key>WarningsAsChat</key>
<map>
<key>Comment</key>
- <string>Controls vertex detail on the WindLight sky. Lower numbers will give better performance and uglier skies.</string>
- <key>Persist</key>
- <integer>1</integer>
- <key>Type</key>
- <string>U32</string>
- <key>Value</key>
- <integer>64</integer>
- </map>
- <key>WarnAboutBadPCI</key>
- <map>
- <key>Comment</key>
- <string>Enables AboutBadPCI warning dialog</string>
- <key>Persist</key>
- <integer>1</integer>
- <key>Type</key>
- <string>Boolean</string>
- <key>Value</key>
- <integer>1</integer>
- </map>
- <key>WarnAboutDirectX9</key>
- <map>
- <key>Comment</key>
- <string>Enables AboutDirectX9 warning dialog</string>
+ <string>Display warning messages in chat history</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
<string>Boolean</string>
<key>Value</key>
- <integer>1</integer>
- </map>
- <key>WarnAboutOldGraphicsDriver</key>
- <map>
- <key>Comment</key>
- <string>Enables AboutOldGraphicsDriver warning dialog</string>
- <key>Persist</key>
- <integer>1</integer>
- <key>Type</key>
- <string>Boolean</string>
- <key>Value</key>
- <integer>1</integer>
- </map>
- <key>WarnAboutPCIGraphics</key>
- <map>
- <key>Comment</key>
- <string>Enables AboutPCIGraphics warning dialog</string>
- <key>Persist</key>
- <integer>1</integer>
- <key>Type</key>
- <string>Boolean</string>
- <key>Value</key>
- <integer>1</integer>
- </map>
- <key>WarnBrowserLaunch</key>
- <map>
- <key>Comment</key>
- <string>Enables BrowserLaunch warning dialog</string>
- <key>Persist</key>
- <integer>1</integer>
- <key>Type</key>
- <string>Boolean</string>
- <key>Value</key>
- <integer>1</integer>
- </map>
- <key>WarnDeedObject</key>
- <map>
- <key>Comment</key>
- <string>Enables DeedObject warning dialog</string>
- <key>Persist</key>
- <integer>1</integer>
- <key>Type</key>
- <string>Boolean</string>
- <key>Value</key>
- <integer>1</integer>
- </map>
- <key>WarnFirstAppearance</key>
- <map>
- <key>Comment</key>
- <string>Enables FirstAppearance warning dialog</string>
- <key>Persist</key>
- <integer>1</integer>
- <key>Type</key>
- <string>Boolean</string>
- <key>Value</key>
- <integer>1</integer>
- </map>
- <key>WarnFirstAttach</key>
- <map>
- <key>Comment</key>
- <string>Enables FirstAttach warning dialog</string>
- <key>Persist</key>
- <integer>1</integer>
- <key>Type</key>
- <string>Boolean</string>
- <key>Value</key>
- <integer>1</integer>
- </map>
- <key>WarnFirstBalanceDecrease</key>
- <map>
- <key>Comment</key>
- <string>Enables FirstBalanceDecrease warning dialog</string>
- <key>Persist</key>
- <integer>1</integer>
- <key>Type</key>
- <string>Boolean</string>
- <key>Value</key>
- <integer>1</integer>
- </map>
- <key>WarnFirstBalanceIncrease</key>
- <map>
- <key>Comment</key>
- <string>Enables FirstBalanceIncrease warning dialog</string>
- <key>Persist</key>
- <integer>1</integer>
- <key>Type</key>
- <string>Boolean</string>
- <key>Value</key>
- <integer>1</integer>
- </map>
- <key>WarnFirstBuild</key>
- <map>
- <key>Comment</key>
- <string>Enables FirstBuild warning dialog</string>
- <key>Persist</key>
- <integer>1</integer>
- <key>Type</key>
- <string>Boolean</string>
- <key>Value</key>
- <integer>1</integer>
- </map>
- <key>WarnFirstDebugMenus</key>
- <map>
- <key>Comment</key>
- <string>Enables FirstDebugMenus warning dialog</string>
- <key>Persist</key>
- <integer>1</integer>
- <key>Type</key>
- <string>Boolean</string>
- <key>Value</key>
- <integer>1</integer>
- </map>
- <key>WarnFirstFlexible</key>
- <map>
- <key>Comment</key>
- <string>Enables FirstFlexible warning dialog</string>
- <key>Persist</key>
- <integer>1</integer>
- <key>Type</key>
- <string>Boolean</string>
- <key>Value</key>
- <integer>1</integer>
- </map>
- <key>WarnFirstGoTo</key>
- <map>
- <key>Comment</key>
- <string>Enables FirstGoTo warning dialog</string>
- <key>Persist</key>
- <integer>1</integer>
- <key>Type</key>
- <string>Boolean</string>
- <key>Value</key>
- <integer>1</integer>
- </map>
- <key>WarnFirstInventory</key>
- <map>
- <key>Comment</key>
- <string>Enables FirstInventory warning dialog</string>
- <key>Persist</key>
- <integer>1</integer>
- <key>Type</key>
- <string>Boolean</string>
- <key>Value</key>
- <integer>1</integer>
- </map>
- <key>WarnFirstLeftClickNoHit</key>
- <map>
- <key>Comment</key>
- <string>Enables FirstLeftClickNoHit warning dialog</string>
- <key>Persist</key>
- <integer>1</integer>
- <key>Type</key>
- <string>Boolean</string>
- <key>Value</key>
- <integer>1</integer>
- </map>
- <key>WarnFirstMap</key>
- <map>
- <key>Comment</key>
- <string>Enables FirstMap warning dialog</string>
- <key>Persist</key>
- <integer>1</integer>
- <key>Type</key>
- <string>Boolean</string>
- <key>Value</key>
- <integer>1</integer>
- </map>
- <key>WarnFirstMedia</key>
- <map>
- <key>Comment</key>
- <string>Enables FirstMedia warning dialog</string>
- <key>Persist</key>
- <integer>1</integer>
- <key>Type</key>
- <string>Boolean</string>
- <key>Value</key>
- <integer>1</integer>
- </map>
- <key>WarnFirstOverrideKeys</key>
- <map>
- <key>Comment</key>
- <string>Enables FirstOverrideKeys warning dialog</string>
- <key>Persist</key>
- <integer>1</integer>
- <key>Type</key>
- <string>Boolean</string>
- <key>Value</key>
- <integer>1</integer>
- </map>
- <key>WarnFirstSandbox</key>
- <map>
- <key>Comment</key>
- <string>Enables FirstSandbox warning dialog</string>
- <key>Persist</key>
- <integer>1</integer>
- <key>Type</key>
- <string>Boolean</string>
- <key>Value</key>
- <integer>1</integer>
- </map>
- <key>WarnFirstSculptedPrim</key>
- <map>
- <key>Comment</key>
- <string>Enables FirstSculptedPrim warning dialog</string>
- <key>Persist</key>
- <integer>1</integer>
- <key>Type</key>
- <string>Boolean</string>
- <key>Value</key>
- <integer>1</integer>
- </map>
- <key>WarnFirstSit</key>
- <map>
- <key>Comment</key>
- <string>Enables FirstSit warning dialog</string>
- <key>Persist</key>
- <integer>1</integer>
- <key>Type</key>
- <string>Boolean</string>
- <key>Value</key>
- <integer>1</integer>
- </map>
- <key>WarnFirstStreamingMusic</key>
- <map>
- <key>Comment</key>
- <string>Enables FirstStreamingMusic warning dialog</string>
- <key>Persist</key>
- <integer>1</integer>
- <key>Type</key>
- <string>Boolean</string>
- <key>Value</key>
- <integer>1</integer>
- </map>
- <key>WarnFirstStreamingVideo</key>
- <map>
- <key>Comment</key>
- <string>Enables FirstStreamingVideo warning dialog</string>
- <key>Persist</key>
- <integer>1</integer>
- <key>Type</key>
- <string>Boolean</string>
- <key>Value</key>
- <integer>1</integer>
- </map>
- <key>WarnFirstTeleport</key>
- <map>
- <key>Comment</key>
- <string>Enables FirstTeleport warning dialog</string>
- <key>Persist</key>
- <integer>1</integer>
- <key>Type</key>
- <string>Boolean</string>
- <key>Value</key>
- <integer>1</integer>
- </map>
- <key>WarnFirstVoice</key>
- <map>
- <key>Comment</key>
- <string>Enables FirstVoice warning dialog</string>
- <key>Persist</key>
- <integer>1</integer>
- <key>Type</key>
- <string>Boolean</string>
- <key>Value</key>
- <integer>1</integer>
- </map>
- <key>WarnNewClassified</key>
- <map>
- <key>Comment</key>
- <string>Enables NewClassified warning dialog</string>
- <key>Persist</key>
- <integer>1</integer>
- <key>Type</key>
- <string>Boolean</string>
- <key>Value</key>
- <integer>1</integer>
- </map>
- <key>WarnQuickTimeInstalled</key>
- <map>
- <key>Comment</key>
- <string>Enables QuickTimeInstalled warning dialog</string>
- <key>Persist</key>
- <integer>1</integer>
- <key>Type</key>
- <string>Boolean</string>
- <key>Value</key>
- <integer>1</integer>
+ <integer>0</integer>
</map>
- <key>WarnReturnToOwner</key>
+ <key>WLSkyDetail</key>
<map>
<key>Comment</key>
- <string>Enables ReturnToOwner warning dialog</string>
+ <string>Controls vertex detail on the WindLight sky. Lower numbers will give better performance and uglier skies.</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
- <string>Boolean</string>
+ <string>U32</string>
<key>Value</key>
- <integer>1</integer>
+ <integer>64</integer>
</map>
<key>WatchdogEnabled</key>
<map>
@@ -11708,6 +9584,17 @@
<key>Value</key>
<integer>1</integer>
</map>
+ <key>WindowFullScreen</key>
+ <map>
+ <key>Comment</key>
+ <string>Run SL in fullscreen mode</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>Boolean</string>
+ <key>Value</key>
+ <integer>0</integer>
+ </map>
<key>WindowHeight</key>
<map>
<key>Comment</key>
@@ -11774,6 +9661,17 @@
<key>Value</key>
<real>150000.0</real>
</map>
+ <key>XUIEditor</key>
+ <map>
+ <key>Comment</key>
+ <string>Path to program used to edit XUI files</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>String</string>
+ <key>Value</key>
+ <real>150000.0</real>
+ </map>
<key>YawFromMousePosition</key>
<map>
<key>Comment</key>
@@ -11818,22 +9716,6 @@
<key>Value</key>
<real>0.40000000596</real>
</map>
- <key>llOwnerSayChatColor</key>
- <map>
- <key>Comment</key>
- <string>Color of chat messages from objects only visible to the owner</string>
- <key>Persist</key>
- <integer>1</integer>
- <key>Type</key>
- <string>Color4</string>
- <key>Value</key>
- <array>
- <real>0.990000009537</real>
- <real>0.990000009537</real>
- <real>0.689999997616</real>
- <real>1.0</real>
- </array>
- </map>
<key>particlesbeacon</key>
<map>
<key>Comment</key>
diff --git a/indra/newview/app_settings/settings_files.xml b/indra/newview/app_settings/settings_files.xml
index ec55745358..aa5b301959 100644
--- a/indra/newview/app_settings/settings_files.xml
+++ b/indra/newview/app_settings/settings_files.xml
@@ -4,10 +4,10 @@
<map>
<!--
The Locations LLSD block specifies the usage pattern of
- the settings file types listed above.
+ the settings file types
Each location is represented by a LLSD containing the following values:
PathIndex = hard coded path indicies.
- Files = map of files to load, from above 'Files' section.
+ Files = map of files to load
Each file can have:
Requirement = level of necessity for loading.
0 ( or Req. no key) = do not load
@@ -50,6 +50,13 @@
<key>Requirement</key>
<integer>1</integer>
</map>
+ <key>Warnings</key>
+ <map>
+ <key>Name</key>
+ <string>ignorable_dialogs.xml</string>
+ <key>Requirement</key>
+ <integer>1</integer>
+ </map>
</map>
</map>
<key>User</key>
@@ -70,6 +77,13 @@
<key>Name</key>
<string>settings_crash_behavior.xml</string>
</map>
+ <key>Warnings</key>
+ <map>
+ <key>Name</key>
+ <string>ignorable_dialogs.xml</string>
+ <key>NameFromSetting</key>
+ <string>WarningSettingsFile</string>
+ </map>
</map>
</map>
<key>Account</key>
@@ -82,6 +96,49 @@
<map>
<key>Name</key>
<string>settings_per_account.xml</string>
+ <key>NameFromSetting</key>
+ <string>PerAccountSettingsFile</string>
+ </map>
+ </map>
+ </map>
+ <key>DefaultSkin</key>
+ <map>
+ <key>PathIndex</key>
+ <integer>17</integer>
+ <key>Files</key>
+ <map>
+ <key>Skinning</key>
+ <map>
+ <key>Name</key>
+ <string>colors.xml</string>
+ </map>
+ </map>
+ </map>
+ <key>CurrentSkin</key>
+ <map>
+ <key>PathIndex</key>
+ <integer>10</integer>
+ <key>Files</key>
+ <map>
+ <key>Skinning</key>
+ <map>
+ <key>Name</key>
+ <string>colors.xml</string>
+ </map>
+ </map>
+ </map>
+ <key>UserSkin</key>
+ <map>
+ <key>PathIndex</key>
+ <integer>14</integer>
+ <key>Files</key>
+ <map>
+ <key>Skinning</key>
+ <map>
+ <key>Name</key>
+ <string>colors.xml</string>
+ <key>NameFromSetting</key>
+ <string>SkinningSettingsFile</string>
</map>
</map>
</map>
diff --git a/indra/newview/app_settings/settings_per_account.xml b/indra/newview/app_settings/settings_per_account.xml
index dab88a5ec3..893e7acd7a 100644
--- a/indra/newview/app_settings/settings_per_account.xml
+++ b/indra/newview/app_settings/settings_per_account.xml
@@ -22,17 +22,28 @@
<key>Value</key>
<string>|TOKEN COPY BusyModeResponse|</string>
</map>
- <key>IMLogTimestamp</key>
+ <key>IMLogOptions</key>
<map>
<key>Comment</key>
- <string>Log Timestamp of Instant Messages</string>
+ <string>Log options for Instant Messages</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
- <string>Boolean</string>
+ <string>S32</string>
<key>Value</key>
- <integer>1</integer>
+ <integer>2</integer>
</map>
+ <key>InstantMessageLogFolder</key>
+ <map>
+ <key>Comment</key>
+ <string>Top level folder to your log files.</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>String</string>
+ <key>Value</key>
+ <string />
+ </map>
<key>InstantMessageLogPath</key>
<map>
<key>Comment</key>
@@ -77,10 +88,10 @@
<key>Value</key>
<integer>0</integer>
</map>
- <key>LogChatTimestamp</key>
+ <key>LogTimestamp</key>
<map>
<key>Comment</key>
- <string>Log Timestamp of Chat</string>
+ <string>Log Timestamp</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
diff --git a/indra/newview/app_settings/std_bump.ini b/indra/newview/app_settings/std_bump.ini
index f34e21ce32..561e04c33c 100644
--- a/indra/newview/app_settings/std_bump.ini
+++ b/indra/newview/app_settings/std_bump.ini
@@ -1,18 +1,18 @@
LLStandardBumpmap version 1
-woodgrain 058c75c0-a0d5-f2f8-43f3-e9699a89c2fc.j2c
-bark 6c9fa78a-1c69-2168-325b-3e03ffa348ce.j2c
-bricks b8eed5f0-64b7-6e12-b67f-43fa8e773440.j2c
-checker 9deab416-9c63-78d6-d558-9a156f12044c.j2c
-concrete db9d39ec-a896-c287-1ced-64566217021e.j2c
-crustytile f2d7b6f6-4200-1e9a-fd5b-96459e950f94.j2c
-cutstone d9258671-868f-7511-c321-7baef9e948a4.j2c
-discs d21e44ca-ff1c-a96e-b2ef-c0753426b7d9.j2c
-gravel 4726f13e-bd07-f2fb-feb0-bfa2ac58ab61.j2c
-petridish e569711a-27c2-aad4-9246-0c910239a179.j2c
-siding 073c9723-540c-5449-cdd4-0e87fdc159e3.j2c
-stonetile ae874d1a-93ef-54fb-5fd3-eb0cb156afc0.j2c
-stucco 92e66e00-f56f-598a-7997-048aa64cde18.j2c
-suction 83b77fc6-10b4-63ec-4de7-f40629f238c5.j2c
-weave 735198cf-6ea0-2550-e222-21d3c6a341ae.j2c
+woodgrain 058c75c0-a0d5-f2f8-43f3-e9699a89c2fc
+bark 6c9fa78a-1c69-2168-325b-3e03ffa348ce
+bricks b8eed5f0-64b7-6e12-b67f-43fa8e773440
+checker 9deab416-9c63-78d6-d558-9a156f12044c
+concrete db9d39ec-a896-c287-1ced-64566217021e
+crustytile f2d7b6f6-4200-1e9a-fd5b-96459e950f94
+cutstone d9258671-868f-7511-c321-7baef9e948a4
+discs d21e44ca-ff1c-a96e-b2ef-c0753426b7d9
+gravel 4726f13e-bd07-f2fb-feb0-bfa2ac58ab61
+petridish e569711a-27c2-aad4-9246-0c910239a179
+siding 073c9723-540c-5449-cdd4-0e87fdc159e3
+stonetile ae874d1a-93ef-54fb-5fd3-eb0cb156afc0
+stucco 92e66e00-f56f-598a-7997-048aa64cde18
+suction 83b77fc6-10b4-63ec-4de7-f40629f238c5
+weave 735198cf-6ea0-2550-e222-21d3c6a341ae
diff --git a/indra/newview/build_win32_appConfig.py b/indra/newview/build_win32_appConfig.py
new file mode 100644
index 0000000000..fb6a0258bc
--- /dev/null
+++ b/indra/newview/build_win32_appConfig.py
@@ -0,0 +1,58 @@
+# @file build_win32_appConfig.py
+# @brief Create the windows app.config file to redirect crt linkage.
+#
+# $LicenseInfo:firstyear=2009&license=viewergpl$
+#
+# Copyright (c) 2009, Linden Research, Inc.
+#
+# Second Life Viewer Source Code
+# The source code in this file ("Source Code") is provided by Linden Lab
+# to you under the terms of the GNU General Public License, version 2.0
+# ("GPL"), unless you have obtained a separate licensing agreement
+# ("Other License"), formally executed by you and Linden Lab. Terms of
+# the GPL can be found in doc/GPL-license.txt in this distribution, or
+# online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
+#
+# There are special exceptions to the terms and conditions of the GPL as
+# it is applied to this Source Code. View the full text of the exception
+# in the file doc/FLOSS-exception.txt in this software distribution, or
+# online at
+# http://secondlifegrid.net/programs/open_source/licensing/flossexception
+#
+# By copying, modifying or distributing this software, you acknowledge
+# that you have read and understood your obligations described above,
+# and agree to abide by those obligations.
+#
+# ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+# WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+# COMPLETENESS OR PERFORMANCE.
+# $/LicenseInfo$
+
+import sys, os, re
+from xml.dom.minidom import parse
+
+def main():
+ src_manifest_name = sys.argv[1]
+ src_config_name = sys.argv[2]
+ dst_config_name = sys.argv[3]
+
+ manifest_dom = parse(src_manifest_name)
+ node = manifest_dom.getElementsByTagName('assemblyIdentity')[0]
+ manifest_assm_ver = node.getAttribute('version')
+
+ config_dom = parse(src_config_name)
+ node = config_dom.getElementsByTagName('bindingRedirect')[0]
+ node.setAttribute('newVersion', manifest_assm_ver)
+ src_old_ver = re.match('([^-]*-).*', node.getAttribute('oldVersion')).group(1)
+ node.setAttribute('oldVersion', src_old_ver + manifest_assm_ver)
+ comment = config_dom.createComment("This file is automatically generated by the build. see indra/newview/build_win32_appConfig.py")
+ config_dom.insertBefore(comment, config_dom.childNodes[0])
+
+ f = open(dst_config_name, 'w')
+ config_dom.writexml(f)
+ f.close()
+
+ return 0
+
+if __name__ == "__main__":
+ main()
diff --git a/indra/newview/character/avatar_lad.xml b/indra/newview/character/avatar_lad.xml
index 0ed5663ec1..c943c57fdb 100644
--- a/indra/newview/character/avatar_lad.xml
+++ b/indra/newview/character/avatar_lad.xml
@@ -5542,6 +5542,14 @@
<texture
local_texture="hair_grain" />
</layer>
+
+ <layer
+ name="hair alpha"
+ visibility_mask="TRUE">
+ <texture
+ local_texture="hair_alpha" />
+ </layer>
+
</layer_set>
<!-- =========================================================== -->
@@ -6451,8 +6459,6 @@
<layer
name="facialhair"
global_color="hair_color">
- <morph_mask
- morph_name="Displace_Hair_Facial" />
<texture
tga_file="head_hair.tga"
@@ -6544,6 +6550,18 @@
<texture
local_texture="head_bodypaint" />
</layer>
+ <layer
+ name="head alpha"
+ visibility_mask="TRUE">
+ <texture
+ local_texture="head_alpha" />
+ </layer>
+ <layer
+ name="head_tattoo">
+ <texture
+ local_texture="head_tattoo" />
+ </layer>
+
</layer_set>
<!-- =========================================================== -->
@@ -6660,6 +6678,13 @@
</layer>
<layer
+ name="upper_tattoo">
+ <texture
+ local_texture="upper_tattoo" />
+ </layer>
+
+
+ <layer
name="upper_undershirt bump"
render_pass="bump"
fixed_color="128,128,128,255">
@@ -7287,12 +7312,6 @@
<texture
local_texture="upper_shirt" />
- <morph_mask
- morph_name="Displace_Loose_Upperbody" />
-
- <morph_mask
- morph_name="Shirtsleeve_flair" />
-
<param
id="803"
group="0"
@@ -7728,6 +7747,14 @@
domain="0.01" />
</param>
</layer>
+
+ <layer
+ name="upper alpha"
+ visibility_mask="TRUE">
+ <texture
+ local_texture="upper_alpha" />
+ </layer>
+
</layer_set>
<!-- =========================================================== -->
@@ -7844,6 +7871,12 @@
</layer>
<layer
+ name="lower_tattoo">
+ <texture
+ local_texture="lower_tattoo" />
+ </layer>
+
+ <layer
name="lower_underpants bump"
render_pass="bump"
fixed_color="128,128,128,255">
@@ -8313,18 +8346,6 @@
<texture
local_texture="lower_pants" />
- <morph_mask
- morph_name="Displace_Loose_Lowerbody" />
-
- <morph_mask
- morph_name="Leg_Pantflair" />
-
- <morph_mask
- morph_name="Low_Crotch" />
-
- <morph_mask
- morph_name="Leg_Longcuffs" />
-
<param
id="806"
group="0"
@@ -8600,6 +8621,14 @@
domain="0.01" />
</param>
</layer>
+
+ <layer
+ name="lower alpha"
+ visibility_mask="TRUE">
+ <texture
+ local_texture="lower_alpha" />
+ </layer>
+
</layer_set>
<!-- =========================================================== -->
@@ -8619,6 +8648,14 @@
<texture
local_texture="eyes_iris" />
</layer>
+
+ <layer
+ name="eyes alpha"
+ visibility_mask="TRUE">
+ <texture
+ local_texture="eyes_alpha" />
+ </layer>
+
</layer_set>
<!-- =========================================================== -->
@@ -8798,6 +8835,7 @@
domain="0" />
</param>
</layer>
+
</layer_set>
<!-- =========================================================== -->
@@ -11258,5 +11296,36 @@
</param>
</driver_parameters>
+
+ <morph_masks>
+ <mask
+ morph_name="Displace_Hair_Facial"
+ body_region="head"
+ layer="facialhair" />
+ <mask
+ morph_name="Displace_Loose_Upperbody"
+ body_region="upper_body"
+ layer="upper_clothes" />
+ <mask
+ morph_name="Shirtsleeve_flair"
+ body_region="upper_body"
+ layer="upper_clothes" />
+ <mask
+ morph_name="Displace_Loose_Lowerbody"
+ body_region="lower_body"
+ layer="lower_pants" />
+ <mask
+ morph_name="Leg_Pantflair"
+ body_region="lower_body"
+ layer="lower_pants" />
+ <mask
+ morph_name="Low_Crotch"
+ body_region="lower_body"
+ layer="lower_pants" />
+ <mask
+ morph_name="Leg_Longcuffs"
+ body_region="lower_body"
+ layer="lower_pants" />
+ </morph_masks>
</linden_avatar>
diff --git a/indra/newview/character/checkerboard.tga b/indra/newview/character/checkerboard.tga
new file mode 100644
index 0000000000..1950d7403d
--- /dev/null
+++ b/indra/newview/character/checkerboard.tga
Binary files differ
diff --git a/indra/newview/character/invisible_head.tga b/indra/newview/character/invisible_head.tga
new file mode 100755
index 0000000000..2673a237d5
--- /dev/null
+++ b/indra/newview/character/invisible_head.tga
Binary files differ
diff --git a/indra/newview/gpu_table.txt b/indra/newview/gpu_table.txt
index 56de9c610a..733670f311 100644
--- a/indra/newview/gpu_table.txt
+++ b/indra/newview/gpu_table.txt
@@ -70,8 +70,8 @@ ATI M72 .*ATI.*M72.* 1 1
ATI M76 .*ATI.*M76.* 3 1
ATI Mobility Radeon 7xxx .*ATI.*Mobility.*Radeon 7.* 0 1
ATI Mobility Radeon 8xxx .*ATI.*Mobility.*Radeon 8.* 0 1
-ATI Mobility Radeon 9800 .*ATI.*Mobility.*98.* 1 1
-ATI Mobility Radeon 9700 .*ATI.*Mobility.*97.* 1 1
+ATI Mobility Radeon 9800 .*ATI.*Mobility.*98.* 0 1
+ATI Mobility Radeon 9700 .*ATI.*Mobility.*97.* 0 1
ATI Mobility Radeon 9600 .*ATI.*Mobility.*96.* 0 1
ATI Mobility Radeon HD 2300 .*ATI.*Mobility.*HD.*23.* 1 1
ATI Mobility Radeon HD 2400 .*ATI.*Mobility.*HD.*24.* 1 1
@@ -162,7 +162,10 @@ Intel Montara .*Intel.*Montara.* 0 0
Intel Springdale .*Intel.*Springdale.* 0 0
Matrox .*Matrox.* 0 0
Mesa .*Mesa.* 0 0
+NVIDIA GT 120 .*NVIDIA.*GeForce.*GT.*12.* 3 1
+NVIDIA GT 130 .*NVIDIA.*GeForce.*GT.*13.* 3 1
NVIDIA GTX 260 .*NVIDIA.*GeForce.*GTX.*26.* 3 1
+NVIDIA GTX 270 .*NVIDIA.*GeForce.*GTX.*27.* 3 1
NVIDIA GTX 280 .*NVIDIA.*GeForce.*GTX.*28.* 3 1
NVIDIA GTX 290 .*NVIDIA.*GeForce.*GTX.*29.* 3 1
NVIDIA C51 .*NVIDIA.*C51.* 0 1
@@ -263,7 +266,6 @@ NVIDIA Quadro FX 4500 .*Quadro.*FX.*4500.* 3 1
NVIDIA Quadro FX .*Quadro FX.* 1 1
NVIDIA Quadro NVS .*Quadro NVS.* 0 1
NVIDIA RIVA TNT .*RIVA TNT.* 0 0
-NVIDIA PCI .*NVIDIA.*/PCI/SSE2 0 0
S3 .*S3 Graphics.* 0 0
SiS SiS.* 0 0
Trident Trident.* 0 0
diff --git a/indra/newview/installers/windows/installer_template.nsi b/indra/newview/installers/windows/installer_template.nsi
index 87218008bd..73a548cdc6 100644
--- a/indra/newview/installers/windows/installer_template.nsi
+++ b/indra/newview/installers/windows/installer_template.nsi
@@ -498,7 +498,8 @@ RMDir "$INSTDIR"
IfFileExists "$INSTDIR" FOLDERFOUND NOFOLDER
FOLDERFOUND:
- MessageBox MB_YESNO $(DeleteProgramFilesMB) IDNO NOFOLDER
+ ; Silent uninstall always removes all files (/SD IDYES)
+ MessageBox MB_YESNO $(DeleteProgramFilesMB) /SD IDYES IDNO NOFOLDER
RMDir /r "$INSTDIR"
NOFOLDER:
diff --git a/indra/newview/linux_tools/client-readme.txt b/indra/newview/linux_tools/client-readme.txt
index 99c973f7ea..07a8f951ee 100644
--- a/indra/newview/linux_tools/client-readme.txt
+++ b/indra/newview/linux_tools/client-readme.txt
@@ -75,8 +75,9 @@ Life Linux client is very similar to that for Windows, as detailed at:
3. INSTALLING & RUNNING
-=-=-=-=-=-=-=-=-=-=-=-
-The Second Life Linux client entirely runs out of the directory you have
-unpacked it into - no installation step is required.
+The Second Life Linux client can entirely run from the directory you have
+unpacked it into - no installation step is required. If you wish to
+perform a separate installation step anyway, you may run './install.sh'
Run ./secondlife from the installation directory to start Second Life.
@@ -96,10 +97,7 @@ you wish.
4. KNOWN ISSUES
-=-=-=-=-=-=-=-
-* UPDATING - when the client detects that a new version of Second Life
- is available, it will ask you if you wish to download the new version.
- This option is not implemented; to upgrade, you should manually download a
- new version from the Second Life web site, <http://www.secondlife.com/>.
+* No significant known issues at this time.
5. TROUBLESHOOTING
diff --git a/indra/newview/linux_tools/handle_secondlifeprotocol.sh b/indra/newview/linux_tools/handle_secondlifeprotocol.sh
index 7ff86d1b93..203012132e 100755
--- a/indra/newview/linux_tools/handle_secondlifeprotocol.sh
+++ b/indra/newview/linux_tools/handle_secondlifeprotocol.sh
@@ -11,7 +11,7 @@ if [ -z "$URL" ]; then
fi
RUN_PATH=`dirname "$0" || echo .`
-cd "${RUN_PATH}"
+cd "${RUN_PATH}/.."
exec ./secondlife -url \'"${URL}"\'
diff --git a/indra/newview/linux_tools/install.sh b/indra/newview/linux_tools/install.sh
new file mode 100755
index 0000000000..c94510267a
--- /dev/null
+++ b/indra/newview/linux_tools/install.sh
@@ -0,0 +1,106 @@
+#!/bin/bash
+
+# Install the Second Life Viewer. This script can install the viewer both
+# system-wide and for an individual user.
+
+VT102_STYLE_NORMAL='\E[0m'
+VT102_COLOR_RED='\E[31m'
+
+SCRIPTSRC=`readlink -f "$0" || echo "$0"`
+RUN_PATH=`dirname "${SCRIPTSRC}" || echo .`
+tarball_path=${RUN_PATH}
+
+function prompt()
+{
+ local prompt=$1
+ local input
+
+ echo -n "$prompt"
+
+ while read input; do
+ case $input in
+ [Yy]* )
+ return 1
+ ;;
+ [Nn]* )
+ return 0
+ ;;
+ * )
+ echo "Please enter yes or no."
+ echo -n "$prompt"
+ esac
+ done
+}
+
+function die()
+{
+ warn $1
+ exit 1
+}
+
+function warn()
+{
+ echo -n -e $VT102_COLOR_RED
+ echo $1
+ echo -n -e $VT102_STYLE_NORMAL
+}
+
+function homedir_install()
+{
+ warn "You are not running as a privileged user, so you will only be able"
+ warn "to install the Second Life Viewer in your home directory. If you"
+ warn "would like to install the Second Life Viewer system-wide, please run"
+ warn "this script as the root user, or with the 'sudo' command."
+ echo
+
+ prompt "Proceed with the installation? [Y/N]: "
+ if [[ $? == 0 ]]; then
+ exit 0
+ fi
+
+ install_to_prefix "$HOME/.secondlife-install"
+ $HOME/.secondlife-install/etc/refresh_desktop_app_entry.sh
+}
+
+function root_install()
+{
+ local default_prefix="/opt/secondlife-install"
+
+ echo -n "Enter the desired installation directory [${default_prefix}]: ";
+ read
+ if [[ "$REPLY" = "" ]] ; then
+ local install_prefix=$default_prefix
+ else
+ local install_prefix=$REPLY
+ fi
+
+ install_to_prefix "$install_prefix"
+
+ mkdir -p /usr/local/share/applications
+ ${install_prefix}/etc/refresh_desktop_app_entry.sh
+}
+
+function install_to_prefix()
+{
+ test -e "$1" && backup_previous_installation "$1"
+ mkdir -p "$1" || die "Failed to create installation directory!"
+
+ echo " - Installing to $1"
+
+ cp -a "${tarball_path}"/* "$1/" || die "Failed to complete the installation!"
+}
+
+function backup_previous_installation()
+{
+ local backup_dir="$1".backup-$(date -I)
+ echo " - Backing up previous installation to $backup_dir"
+
+ mv "$1" "$backup_dir" || die "Failed to create backup of existing installation!"
+}
+
+
+if [ "$UID" == "0" ]; then
+ root_install
+else
+ homedir_install
+fi
diff --git a/indra/newview/linux_tools/refresh_desktop_app_entry.sh b/indra/newview/linux_tools/refresh_desktop_app_entry.sh
new file mode 100755
index 0000000000..d2b2a732d5
--- /dev/null
+++ b/indra/newview/linux_tools/refresh_desktop_app_entry.sh
@@ -0,0 +1,36 @@
+#!/bin/bash
+
+SCRIPTSRC=`readlink -f "$0" || echo "$0"`
+RUN_PATH=`dirname "${SCRIPTSRC}" || echo .`
+
+install_prefix=${RUN_PATH}/..
+
+function install_desktop_entry()
+{
+ local installation_prefix="$1"
+ local desktop_entries_dir="$2"
+
+ local desktop_entry="\
+[Desktop Entry]\n\
+Name=Second Life\n\
+Comment=Client for the On-line Virtual World, Second Life\n\
+Exec=${installation_prefix}/secondlife\n\
+Icon=${installation_prefix}/secondlife_icon.png\n\
+Terminal=false\n\
+Type=Application\n\
+Categories=Application;Network;\n\
+StartupNotify=true\n\
+X-Desktop-File-Install-Version=3.0"
+
+ echo " - Installing menu entries in ${desktop_entries_dir}"
+ mkdir -vp "${desktop_entries_dir}"
+ echo -e $desktop_entry > "${desktop_entries_dir}/secondlife-viewer.desktop" || "Failed to install application menu!"
+}
+
+if [ "$UID" == "0" ]; then
+ # system-wide
+ install_desktop_entry "$install_prefix" /usr/local/share/applications
+else
+ # user-specific
+ install_desktop_entry "$install_prefix" "$HOME/.local/share/applications"
+fi
diff --git a/indra/newview/linux_tools/register_secondlifeprotocol.sh b/indra/newview/linux_tools/register_secondlifeprotocol.sh
index 4ab96f97d6..c7b4d55461 100755
--- a/indra/newview/linux_tools/register_secondlifeprotocol.sh
+++ b/indra/newview/linux_tools/register_secondlifeprotocol.sh
@@ -7,10 +7,10 @@
HANDLER="$1"
RUN_PATH=`dirname "$0" || echo .`
-cd "${RUN_PATH}"
+cd "${RUN_PATH}/.."
if [ -z "$HANDLER" ]; then
- HANDLER=`pwd`/handle_secondlifeprotocol.sh
+ HANDLER=`pwd`/etc/handle_secondlifeprotocol.sh
fi
# Register handler for GNOME-aware apps
diff --git a/indra/newview/linux_tools/wrapper.sh b/indra/newview/linux_tools/wrapper.sh
index dfe19c1232..3209654498 100755
--- a/indra/newview/linux_tools/wrapper.sh
+++ b/indra/newview/linux_tools/wrapper.sh
@@ -91,7 +91,11 @@ echo "Running from ${RUN_PATH}"
cd "${RUN_PATH}"
# Re-register the secondlife:// protocol handler every launch, for now.
-./register_secondlifeprotocol.sh
+./etc/register_secondlifeprotocol.sh
+
+# Re-register the application with the desktop system every launch, for now.
+./etc/refresh_desktop_app_entry.sh
+
## Before we mess with LD_LIBRARY_PATH, save the old one to restore for
## subprocesses that care.
export SAVED_LD_LIBRARY_PATH="${LD_LIBRARY_PATH}"
@@ -116,7 +120,7 @@ fi
export SL_ENV='LD_LIBRARY_PATH="`pwd`"/lib:"`pwd`"/app_settings/mozilla-runtime-linux-i686:"${LD_LIBRARY_PATH}"'
export SL_CMD='$LL_WRAPPER bin/do-not-directly-run-secondlife-bin'
-export SL_OPT="`cat gridargs.dat` $@"
+export SL_OPT="`cat etc/gridargs.dat` $@"
# Run the program
eval ${SL_ENV} ${SL_CMD} ${SL_OPT} || LL_RUN_ERR=runerr
diff --git a/indra/newview/llagent.cpp b/indra/newview/llagent.cpp
index cc443d05c0..214065f080 100644
--- a/indra/newview/llagent.cpp
+++ b/indra/newview/llagent.cpp
@@ -32,115 +32,89 @@
#include "llviewerprecompiledheaders.h"
-#include "stdtypes.h"
-#include "stdenums.h"
-
#include "llagent.h"
+#include "llagentwearables.h"
-#include "llcamera.h"
-#include "llcoordframe.h"
-#include "indra_constants.h"
-#include "llmath.h"
-#include "llcriticaldamp.h"
-#include "llfocusmgr.h"
-#include "llglheaders.h"
-#include "llparcel.h"
-#include "llpermissions.h"
-#include "llregionhandle.h"
-#include "m3math.h"
-#include "m4math.h"
-#include "message.h"
-#include "llquaternion.h"
-#include "v3math.h"
-#include "v4math.h"
-#include "llsmoothstep.h"
-#include "llsdutil.h"
-//#include "vmath.h"
-
-#include "imageids.h"
-#include "llbox.h"
-#include "llbutton.h"
+#include "llanimationstates.h"
#include "llcallingcard.h"
-#include "llchatbar.h"
#include "llconsole.h"
#include "lldrawable.h"
-#include "llface.h"
#include "llfirstuse.h"
-#include "llfloater.h"
+#include "llfloaterreg.h"
#include "llfloateractivespeakers.h"
-#include "llfloateravatarinfo.h"
-#include "llfloaterbuildoptions.h"
#include "llfloatercamera.h"
-#include "llfloaterchat.h"
#include "llfloatercustomize.h"
#include "llfloaterdirectory.h"
-#include "llfloatergroupinfo.h"
-#include "llfloatergroups.h"
+
#include "llfloaterland.h"
-#include "llfloatermap.h"
#include "llfloatermute.h"
#include "llfloatersnapshot.h"
#include "llfloatertools.h"
#include "llfloaterworldmap.h"
+
+#include "llgroupactions.h"
+
+#include "llfocusmgr.h"
#include "llgroupmgr.h"
#include "llhomelocationresponder.h"
-#include "llhudeffectlookat.h"
+#include "llimview.h"
#include "llhudmanager.h"
-#include "llinventorymodel.h"
-#include "llinventoryview.h"
#include "lljoystickbutton.h"
#include "llmenugl.h"
#include "llmorphview.h"
#include "llmoveview.h"
-#include "llnotify.h"
+#include "llparcel.h"
#include "llquantize.h"
+#include "llrand.h"
+#include "llregionhandle.h"
#include "llsdutil.h"
#include "llselectmgr.h"
#include "llsky.h"
-#include "llrendersphere.h"
+#include "llslurl.h"
+#include "llsmoothstep.h"
+#include "llsidetray.h"
#include "llstatusbar.h"
-#include "llstartup.h"
-#include "llimview.h"
+#include "llteleportflags.h"
+#include "llteleporthistory.h"
#include "lltool.h"
#include "lltoolcomp.h"
-#include "lltoolfocus.h"
-#include "lltoolgrab.h"
#include "lltoolmgr.h"
-#include "lltoolpie.h"
-#include "lltoolview.h"
-#include "llui.h" // for make_ui_sound
+#include "lluictrlfactory.h"
#include "llurldispatcher.h"
+
#include "llviewercamera.h"
-#include "llviewerinventory.h"
-#include "llviewermenu.h"
-#include "llviewernetwork.h"
+#include "llviewerdisplay.h"
+#include "llviewermediafocus.h"
#include "llviewerobjectlist.h"
#include "llviewerparcelmgr.h"
-#include "llviewerparceloverlay.h"
-#include "llviewerregion.h"
#include "llviewerstats.h"
#include "llviewerwindow.h"
-#include "llviewerdisplay.h"
-#include "llvoavatar.h"
-#include "llvoground.h"
-#include "llvosky.h"
-#include "llwearable.h"
-#include "llwearablelist.h"
+#include "llviewercontrol.h"
+#include "llviewerjoystick.h"
+
+#include "llvoavatarself.h"
+#include "llwindow.h"
#include "llworld.h"
#include "llworldmap.h"
+
#include "pipeline.h"
-#include "roles_constants.h"
-#include "llviewercontrol.h"
-#include "llappviewer.h"
-#include "llviewerjoystick.h"
-#include "llfollowcam.h"
+#include "lltrans.h"
+#include "llbottomtray.h"
+#include "llnearbychatbar.h"
#include "stringize.h"
#include "llcapabilitylistener.h"
+#include "llnavigationbar.h" //to show/hide navigation bar when changing mouse look state
+#include "llagentui.h"
+
using namespace LLVOAvatarDefines;
extern LLMenuBarGL* gMenuBarView;
+const BOOL ANIMATE = TRUE;
+const U8 AGENT_STATE_TYPING = 0x04;
+const U8 AGENT_STATE_EDITING = 0x10;
+
//drone wandering constants
const F32 MAX_WANDER_TIME = 20.f; // seconds
const F32 MAX_HEADING_HALF_ERROR = 0.2f; // radians
@@ -216,7 +190,7 @@ const F64 CHAT_AGE_FAST_RATE = 3.0;
// The agent instance.
LLAgent gAgent;
-//
+//--------------------------------------------------------------------
// Statics
//
@@ -242,6 +216,19 @@ void LLAgentFriendObserver::changed(U32 mask)
}
}
+bool handleSlowMotionAnimation(const LLSD& newvalue)
+{
+ if (newvalue.asBoolean())
+ {
+ gAgent.getAvatarObject()->setAnimTimeFactor(0.2f);
+ }
+ else
+ {
+ gAgent.getAvatarObject()->setAnimTimeFactor(1.0f);
+ }
+ return true;
+}
+
// ************************************************************
// Enabled this definition to compile a 'hacked' viewer that
// locally believes the end user has godlike powers.
@@ -264,19 +251,12 @@ LLAgent::LLAgent() :
mHideGroupTitle(FALSE),
mGroupID(),
- mMapOriginX(0.F),
- mMapOriginY(0.F),
- mMapWidth(0),
- mMapHeight(0),
-
mLookAt(NULL),
mPointAt(NULL),
mHUDTargetZoom(1.f),
mHUDCurZoom(1.f),
mInitialized(FALSE),
- mNumPendingQueries(0),
- mActiveCacheQueries(NULL),
mForceMouselook(FALSE),
mDoubleTapRunTimer(),
@@ -304,6 +284,8 @@ LLAgent::LLAgent() :
mLastCameraMode( CAMERA_MODE_THIRD_PERSON ),
mViewsPushed(FALSE),
+ mCameraPreset(CAMERA_PRESET_REAR_VIEW),
+
mCustomAnim(FALSE),
mShowAvatar(TRUE),
mCameraAnimating( FALSE ),
@@ -317,7 +299,6 @@ LLAgent::LLAgent() :
mCameraFocusOffset(),
mCameraFOVDefault(DEFAULT_FIELD_OF_VIEW),
- mCameraOffsetDefault(),
mCameraCollidePlane(),
mCurrentCameraDistance(2.f), // meters, set in init()
@@ -384,7 +365,7 @@ LLAgent::LLAgent() :
mAutoPilotFinishedCallback(NULL),
mAutoPilotCallbackData(NULL),
- mEffectColor(0.f, 1.f, 1.f, 1.f),
+ mEffectColor(LLColor4(0.f, 1.f, 1.f, 1.f)),
mHaveHomePosition(FALSE),
mHomeRegionHandle( 0 ),
@@ -395,24 +376,14 @@ LLAgent::LLAgent() :
mFirstLogin(FALSE),
mGenderChosen(FALSE),
- mAgentWearablesUpdateSerialNum(0),
- mWearablesLoaded(FALSE),
- mTextureCacheQueryID(0),
mAppearanceSerialNum(0)
{
- U32 i;
- for (i = 0; i < TOTAL_CONTROLS; i++)
+ for (U32 i = 0; i < TOTAL_CONTROLS; i++)
{
mControlsTakenCount[i] = 0;
mControlsTakenPassedOnCount[i] = 0;
}
- mActiveCacheQueries = new S32[BAKED_NUM_INDICES];
- for (i = 0; i < (U32)BAKED_NUM_INDICES; i++)
- {
- mActiveCacheQueries[i] = 0;
- }
-
mFollowCam.setMaxCameraDistantFromSubject( MAX_CAMERA_DISTANCE_FROM_AGENT );
}
@@ -422,6 +393,9 @@ LLAgent::LLAgent() :
//-----------------------------------------------------------------------------
void LLAgent::init()
{
+ gSavedSettings.declareBOOL("SlowMotionAnimation", FALSE, "Declared in code", FALSE);
+ gSavedSettings.getControl("SlowMotionAnimation")->getSignal()->connect(boost::bind(&handleSlowMotionAnimation, _2));
+
mDrawDistance = gSavedSettings.getF32("RenderFarClip");
// *Note: this is where LLViewerCamera::getInstance() used to be constructed.
@@ -430,22 +404,33 @@ void LLAgent::init()
// Leave at 0.1 meters until we have real near clip management
LLViewerCamera::getInstance()->setNear(0.1f);
LLViewerCamera::getInstance()->setFar(mDrawDistance); // if you want to change camera settings, do so in camera.h
- LLViewerCamera::getInstance()->setAspect( gViewerWindow->getDisplayAspectRatio() ); // default, overridden in LLViewerWindow::reshape
+ LLViewerCamera::getInstance()->setAspect( gViewerWindow->getWorldViewAspectRatio() ); // default, overridden in LLViewerWindow::reshape
LLViewerCamera::getInstance()->setViewHeightInPixels(768); // default, overridden in LLViewerWindow::reshape
setFlying( gSavedSettings.getBOOL("FlyingAtExit") );
mCameraFocusOffsetTarget = LLVector4(gSavedSettings.getVector3("CameraOffsetBuild"));
- mCameraOffsetDefault = gSavedSettings.getVector3("CameraOffsetDefault");
+
+ mCameraPreset = (ECameraPreset) gSavedSettings.getU32("CameraPreset");
+
+ mCameraOffsetInitial[CAMERA_PRESET_REAR_VIEW] = gSavedSettings.getVector3("CameraOffsetRearView");
+ mCameraOffsetInitial[CAMERA_PRESET_FRONT_VIEW] = gSavedSettings.getVector3("CameraOffsetFrontView");
+ mCameraOffsetInitial[CAMERA_PRESET_GROUP_VIEW] = gSavedSettings.getVector3("CameraOffsetGroupView");
+
+ mFocusOffsetInitial[CAMERA_PRESET_REAR_VIEW] = gSavedSettings.getVector3d("FocusOffsetRearView");
+ mFocusOffsetInitial[CAMERA_PRESET_FRONT_VIEW] = gSavedSettings.getVector3d("FocusOffsetFrontView");
+ mFocusOffsetInitial[CAMERA_PRESET_GROUP_VIEW] = gSavedSettings.getVector3d("FocusOffsetGroupView");
+
mCameraCollidePlane.clearVec();
- mCurrentCameraDistance = mCameraOffsetDefault.magVec() * gSavedSettings.getF32("CameraOffsetScale");
+ mCurrentCameraDistance = getCameraOffsetInitial().magVec() * gSavedSettings.getF32("CameraOffsetScale");
mTargetCameraDistance = mCurrentCameraDistance;
mCameraZoomFraction = 1.f;
mTrackFocusObject = gSavedSettings.getBOOL("TrackFocusObject");
-// LLDebugVarMessageBox::show("Camera Lag", &CAMERA_FOCUS_HALF_LIFE, 0.5f, 0.01f);
+ mEffectColor = LLUIColorTable::instance().getColor("EffectColor");
- mEffectColor = gSavedSettings.getColor4("EffectColor");
+ gSavedSettings.getControl("PreferredMaturity")->getValidateSignal()->connect(boost::bind(&LLAgent::validateMaturity, this, _2));
+ gSavedSettings.getControl("PreferredMaturity")->getSignal()->connect(boost::bind(&LLAgent::handleMaturity, this, _2));
mInitialized = TRUE;
}
@@ -456,7 +441,9 @@ void LLAgent::init()
void LLAgent::cleanup()
{
setSitCamera(LLUUID::null);
+
mAvatarObject = NULL;
+
if(mLookAt)
{
mLookAt->markDead() ;
@@ -478,9 +465,6 @@ LLAgent::~LLAgent()
{
cleanup();
- delete [] mActiveCacheQueries;
- mActiveCacheQueries = NULL;
-
// *Note: this is where LLViewerCamera::getInstance() used to be deleted.
}
@@ -529,12 +513,16 @@ void LLAgent::resetView(BOOL reset_camera, BOOL change_camera)
LLViewerJoystick::getInstance()->moveAvatar(true);
}
- gFloaterTools->close();
+ //Camera Tool is needed for Free Camera Control Mode
+ if (!LLFloaterCamera::inFreeCameraMode())
+ {
+ LLFloaterReg::hideInstance("build");
+
+ // Switch back to basic toolset
+ LLToolMgr::getInstance()->setCurrentToolset(gBasicToolset);
+ }
gViewerWindow->showCursor();
-
- // Switch back to basic toolset
- LLToolMgr::getInstance()->setCurrentToolset(gBasicToolset);
}
@@ -785,7 +773,7 @@ void LLAgent::setFlying(BOOL fly)
}
// don't allow taking off while sitting
- if (fly && mAvatarObject->mIsSitting)
+ if (fly && mAvatarObject->isSitting())
{
return;
}
@@ -814,6 +802,11 @@ void LLAgent::setFlying(BOOL fly)
clearControlFlags(AGENT_CONTROL_FLY);
gSavedSettings.setBOOL("FlyBtnState", FALSE);
}
+
+
+ // Update Movement Controls according to Fly mode
+ LLFloaterMove::setFlyingMode(fly);
+
mbFlagsDirty = TRUE;
}
@@ -822,12 +815,29 @@ void LLAgent::setFlying(BOOL fly)
//-----------------------------------------------------------------------------
// toggleFlying()
//-----------------------------------------------------------------------------
+// static
void LLAgent::toggleFlying()
{
- BOOL fly = !(mControlFlags & AGENT_CONTROL_FLY);
+ BOOL fly = !(gAgent.mControlFlags & AGENT_CONTROL_FLY);
- setFlying( fly );
- resetView();
+ gAgent.setFlying( fly );
+ gAgent.resetView();
+}
+
+// static
+bool LLAgent::enableFlying()
+{
+ BOOL sitting = FALSE;
+ if (gAgent.getAvatarObject())
+ {
+ sitting = gAgent.getAvatarObject()->isSitting();
+ }
+ return !sitting;
+}
+
+void LLAgent::standUp()
+{
+ setControlFlags(AGENT_CONTROL_STAND_UP);
}
@@ -904,6 +914,8 @@ void LLAgent::setRegion(LLViewerRegion *regionp)
mRegionsVisited.insert(handle);
LLSelectMgr::getInstance()->updateSelectionCenter();
+
+ LLFloaterMove::sUpdateFlyingStatus();
}
@@ -929,25 +941,6 @@ LLHost LLAgent::getRegionHost() const
}
//-----------------------------------------------------------------------------
-// getSLURL()
-// returns empty() if getRegion() == NULL
-//-----------------------------------------------------------------------------
-std::string LLAgent::getSLURL() const
-{
- std::string slurl;
- LLViewerRegion *regionp = getRegion();
- if (regionp)
- {
- LLVector3d agentPos = getPositionGlobal();
- S32 x = llround( (F32)fmod( agentPos.mdV[VX], (F64)REGION_WIDTH_METERS ) );
- S32 y = llround( (F32)fmod( agentPos.mdV[VY], (F64)REGION_WIDTH_METERS ) );
- S32 z = llround( (F32)agentPos.mdV[VZ] );
- slurl = LLURLDispatcher::buildSLURL(regionp->getName(), x, y, z);
- }
- return slurl;
-}
-
-//-----------------------------------------------------------------------------
// inPrelude()
//-----------------------------------------------------------------------------
BOOL LLAgent::inPrelude()
@@ -1260,7 +1253,7 @@ F32 LLAgent::clampPitchToLimits(F32 angle)
F32 angle_from_skyward = acos( mFrameAgent.getAtAxis() * skyward );
- if (mAvatarObject.notNull() && mAvatarObject->mIsSitting)
+ if (mAvatarObject.notNull() && mAvatarObject->isSitting())
{
look_down_limit = 130.f * DEG_TO_RAD;
}
@@ -1890,7 +1883,7 @@ void LLAgent::cameraOrbitIn(const F32 meters)
{
if (mFocusOnAvatar && mCameraMode == CAMERA_MODE_THIRD_PERSON)
{
- F32 camera_offset_dist = llmax(0.001f, mCameraOffsetDefault.magVec() * gSavedSettings.getF32("CameraOffsetScale"));
+ F32 camera_offset_dist = llmax(0.001f, getCameraOffsetInitial().magVec() * gSavedSettings.getF32("CameraOffsetScale"));
mCameraZoomFraction = (mTargetCameraDistance - meters) / camera_offset_dist;
@@ -2124,8 +2117,7 @@ void LLAgent::setAFK()
gAwayTimer.start();
if (gAFKMenu)
{
- //*TODO:Translate
- gAFKMenu->setLabel(std::string("Set Not Away"));
+ gAFKMenu->setLabel(LLTrans::getString("AvatarSetNotAway"));
}
}
}
@@ -2148,8 +2140,7 @@ void LLAgent::clearAFK()
clearControlFlags(AGENT_CONTROL_AWAY);
if (gAFKMenu)
{
- //*TODO:Translate
- gAFKMenu->setLabel(std::string("Set Away"));
+ gAFKMenu->setLabel(LLTrans::getString("AvatarSetAway"));
}
}
}
@@ -2171,10 +2162,8 @@ void LLAgent::setBusy()
mIsBusy = TRUE;
if (gBusyMenu)
{
- //*TODO:Translate
- gBusyMenu->setLabel(std::string("Set Not Busy"));
+ gBusyMenu->setLabel(LLTrans::getString("AvatarSetNotBusy"));
}
- LLFloaterMute::getInstance()->updateButtons();
}
//-----------------------------------------------------------------------------
@@ -2186,10 +2175,8 @@ void LLAgent::clearBusy()
sendAnimationRequest(ANIM_AGENT_BUSY, ANIM_REQUEST_STOP);
if (gBusyMenu)
{
- //*TODO:Translate
- gBusyMenu->setLabel(std::string("Set Busy"));
+ gBusyMenu->setLabel(LLTrans::getString("AvatarSetBusy"));
}
- LLFloaterMute::getInstance()->updateButtons();
}
//-----------------------------------------------------------------------------
@@ -2512,13 +2499,11 @@ void LLAgent::autoPilot(F32 *delta_yaw)
void LLAgent::propagate(const F32 dt)
{
// Update UI based on agent motion
- LLFloaterMove *floater_move = LLFloaterMove::getInstance();
+ LLFloaterMove *floater_move = LLFloaterReg::findTypedInstance<LLFloaterMove>("moveview");
if (floater_move)
{
floater_move->mForwardButton ->setToggleState( mAtKey > 0 || mWalkKey > 0 );
floater_move->mBackwardButton ->setToggleState( mAtKey < 0 || mWalkKey < 0 );
- floater_move->mSlideLeftButton ->setToggleState( mLeftKey > 0 );
- floater_move->mSlideRightButton->setToggleState( mLeftKey < 0 );
floater_move->mTurnLeftButton ->setToggleState( mYawKey > 0.f );
floater_move->mTurnRightButton ->setToggleState( mYawKey < 0.f );
floater_move->mMoveUpButton ->setToggleState( mUpKey > 0 );
@@ -2603,7 +2588,7 @@ void LLAgent::updateLookAt(const S32 mouse_x, const S32 mouse_y)
else
{
// *FIX: rotate mframeagent by sit object's rotation?
- LLQuaternion look_rotation = mAvatarObject->mIsSitting ? mAvatarObject->getRenderRotation() : mFrameAgent.getQuaternion(); // use camera's current rotation
+ LLQuaternion look_rotation = mAvatarObject->isSitting() ? mAvatarObject->getRenderRotation() : mFrameAgent.getQuaternion(); // use camera's current rotation
LLVector3 look_offset = LLVector3(2.f, 0.f, 0.f) * look_rotation * av_inv_rot;
setLookAt(LOOKAT_TARGET_IDLE, mAvatarObject, look_offset);
}
@@ -2669,7 +2654,7 @@ std::ostream& operator<<(std::ostream &s, const LLAgent &agent)
//-----------------------------------------------------------------------------
// setAvatarObject()
//-----------------------------------------------------------------------------
-void LLAgent::setAvatarObject(LLVOAvatar *avatar)
+void LLAgent::setAvatarObject(LLVOAvatarSelf *avatar)
{
mAvatarObject = avatar;
@@ -2696,8 +2681,6 @@ void LLAgent::setAvatarObject(LLVOAvatar *avatar)
{
mPointAt->setSourceObject(avatar);
}
-
- sendAgentWearablesRequest();
}
// TRUE if your own avatar needs to be rendered. Usually only
@@ -2748,7 +2731,7 @@ void LLAgent::startTyping()
{
sendAnimationRequest(ANIM_AGENT_TYPE, ANIM_REQUEST_START);
}
- gChatBar->sendChatFromViewer("", CHAT_TYPE_START, FALSE);
+ LLNearbyChatBar::getInstance()->sendChatFromViewer("", CHAT_TYPE_START, FALSE);
}
//-----------------------------------------------------------------------------
@@ -2760,7 +2743,7 @@ void LLAgent::stopTyping()
{
clearRenderState(AGENT_STATE_TYPING);
sendAnimationRequest(ANIM_AGENT_TYPE, ANIM_REQUEST_STOP);
- gChatBar->sendChatFromViewer("", CHAT_TYPE_STOP, FALSE);
+ LLNearbyChatBar::getInstance()->sendChatFromViewer("", CHAT_TYPE_STOP, FALSE);
}
}
@@ -2814,13 +2797,6 @@ U8 LLAgent::getRenderState()
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
-static const LLFloaterView::skip_list_t& get_skip_list()
-{
- static LLFloaterView::skip_list_t skip_list;
- skip_list.insert(LLFloaterMap::getInstance());
- return skip_list;
-}
-
//-----------------------------------------------------------------------------
// endAnimationUpdateUI()
//-----------------------------------------------------------------------------
@@ -2839,17 +2815,33 @@ void LLAgent::endAnimationUpdateUI()
gViewerWindow->showCursor();
// show menus
gMenuBarView->setVisible(TRUE);
+ LLNavigationBar::getInstance()->setVisible(TRUE);
gStatusBar->setVisibleForMouselook(true);
+ LLBottomTray::getInstance()->setVisible(TRUE);
+
+ LLSideTray::getInstance()->setVisible(TRUE);
+
+ LLPanelStandStopFlying::getInstance()->setVisible(TRUE);
+
LLToolMgr::getInstance()->setCurrentToolset(gBasicToolset);
+ LLFloaterCamera::toPrevModeIfInAvatarViewMode();
+
// Only pop if we have pushed...
if (TRUE == mViewsPushed)
{
+#if 0 // Use this once all floaters are registered
+ LLFloaterReg::restoreVisibleInstances();
+#else // Use this for now
+ LLFloaterView::skip_list_t skip_list;
+ skip_list.insert(LLFloaterReg::findInstance("mini_map"));
+ gFloaterView->popVisibleAll(skip_list);
+#endif
mViewsPushed = FALSE;
- gFloaterView->popVisibleAll(get_skip_list());
}
+
gAgent.setLookAt(LOOKAT_TARGET_CLEAR);
if( gMorphView )
{
@@ -2891,13 +2883,6 @@ void LLAgent::endAnimationUpdateUI()
LLToolMgr::getInstance()->setCurrentToolset(gBasicToolset);
- // HACK: If we're quitting, and we were in customize avatar, don't
- // let the mini-map go visible again. JC
- if (!LLAppViewer::instance()->quitRequested())
- {
- LLFloaterMap::getInstance()->popVisible();
- }
-
if( gMorphView )
{
gMorphView->setVisible( FALSE );
@@ -2924,26 +2909,46 @@ void LLAgent::endAnimationUpdateUI()
{
// hide menus
gMenuBarView->setVisible(FALSE);
+ LLNavigationBar::getInstance()->setVisible(FALSE);
gStatusBar->setVisibleForMouselook(false);
+ LLBottomTray::getInstance()->setVisible(FALSE);
+
+ LLSideTray::getInstance()->setVisible(FALSE);
+
+ LLPanelStandStopFlying::getInstance()->setVisible(FALSE);
+
// clear out camera lag effect
mCameraLag.clearVec();
// JC - Added for always chat in third person option
gFocusMgr.setKeyboardFocus(NULL);
+ //Making sure Camera Controls floater is in the right state
+ //when entering Mouse Look using wheel scrolling
+ LLFloaterCamera::updateIfNotInAvatarViewMode();
+
LLToolMgr::getInstance()->setCurrentToolset(gMouselookToolset);
mViewsPushed = TRUE;
- gFloaterView->pushVisibleAll(FALSE, get_skip_list());
+ // hide all floaters except the mini map
+
+#if 0 // Use this once all floaters are registered
+ std::set<std::string> exceptions;
+ exceptions.insert("mini_map");
+ LLFloaterReg::hideVisibleInstances(exceptions);
+#else // Use this for now
+ LLFloaterView::skip_list_t skip_list;
+ skip_list.insert(LLFloaterReg::findInstance("mini_map"));
+ gFloaterView->pushVisibleAll(FALSE, skip_list);
+#endif
if( gMorphView )
{
gMorphView->setVisible(FALSE);
}
- gIMMgr->setFloaterOpen( FALSE );
gConsole->setVisible( TRUE );
if (mAvatarObject.notNull())
@@ -2992,15 +2997,6 @@ void LLAgent::endAnimationUpdateUI()
{
LLToolMgr::getInstance()->setCurrentToolset(gFaceEditToolset);
- LLFloaterMap::getInstance()->pushVisible(FALSE);
- /*
- LLView *view;
- for (view = gFloaterView->getFirstChild(); view; view = gFloaterView->getNextChild())
- {
- view->pushVisible(FALSE);
- }
- */
-
if( gMorphView )
{
gMorphView->setVisible( TRUE );
@@ -3042,7 +3038,7 @@ void LLAgent::updateCamera()
validateFocusObject();
if (mAvatarObject.notNull() &&
- mAvatarObject->mIsSitting &&
+ mAvatarObject->isSitting() &&
camera_mode == CAMERA_MODE_MOUSELOOK)
{
//Ventrella
@@ -3073,21 +3069,25 @@ void LLAgent::updateCamera()
}
// Update UI with our camera inputs
- LLFloaterCamera::getInstance()->mRotate->setToggleState(
+ LLFloaterCamera* camera_floater = LLFloaterReg::findTypedInstance<LLFloaterCamera>("camera");
+ if (camera_floater)
+ {
+ camera_floater->mRotate->setToggleState(
mOrbitRightKey > 0.f, // left
mOrbitUpKey > 0.f, // top
mOrbitLeftKey > 0.f, // right
mOrbitDownKey > 0.f); // bottom
- LLFloaterCamera::getInstance()->mZoom->setToggleState(
+ camera_floater->mZoom->setToggleState(
mOrbitInKey > 0.f, // top
mOrbitOutKey > 0.f); // bottom
- LLFloaterCamera::getInstance()->mTrack->setToggleState(
+ camera_floater->mTrack->setToggleState(
mPanLeftKey > 0.f, // left
mPanUpKey > 0.f, // top
mPanRightKey > 0.f, // right
mPanDownKey > 0.f); // bottom
+ }
// Handle camera movement based on keyboard.
const F32 ORBIT_OVER_RATE = 90.f * DEG_TO_RAD; // radians per second
@@ -3163,7 +3163,7 @@ void LLAgent::updateCamera()
// (2) focus, and (3) upvector. They can then be queried elsewhere in llAgent.
//--------------------------------------------------------------------------------
// *TODO: use combined rotation of frameagent and sit object
- LLQuaternion avatarRotationForFollowCam = mAvatarObject->mIsSitting ? mAvatarObject->getRenderRotation() : mFrameAgent.getQuaternion();
+ LLQuaternion avatarRotationForFollowCam = mAvatarObject->isSitting() ? mAvatarObject->getRenderRotation() : mFrameAgent.getQuaternion();
LLFollowCamParams* current_cam = LLFollowCamMgr::getActiveFollowCamParams();
if (current_cam)
@@ -3343,7 +3343,7 @@ void LLAgent::updateCamera()
}
mLastPositionGlobal = global_pos;
- if (LLVOAvatar::sVisibleInFirstPerson && mAvatarObject.notNull() && !mAvatarObject->mIsSitting && cameraMouselook())
+ if (LLVOAvatar::sVisibleInFirstPerson && mAvatarObject.notNull() && !mAvatarObject->isSitting() && cameraMouselook())
{
LLVector3 head_pos = mAvatarObject->mHeadp->getWorldPosition() +
LLVector3(0.08f, 0.f, 0.05f) * mAvatarObject->mHeadp->getWorldRotation() +
@@ -3523,7 +3523,7 @@ LLVector3d LLAgent::calcFocusPositionTargetGlobal()
}
return mFocusTargetGlobal;
}
- else if (mSitCameraEnabled && mAvatarObject.notNull() && mAvatarObject->mIsSitting && mSitCameraReferenceObject.notNull())
+ else if (mSitCameraEnabled && mAvatarObject.notNull() && mAvatarObject->isSitting() && mSitCameraReferenceObject.notNull())
{
// sit camera
LLVector3 object_pos = mSitCameraReferenceObject->getRenderPosition();
@@ -3542,7 +3542,6 @@ LLVector3d LLAgent::calcThirdPersonFocusOffset()
{
// ...offset from avatar
LLVector3d focus_offset;
- focus_offset.setVec(gSavedSettings.getVector3("FocusOffsetDefault"));
LLQuaternion agent_rot = mFrameAgent.getQuaternion();
if (!mAvatarObject.isNull() && mAvatarObject->getParent())
@@ -3550,7 +3549,7 @@ LLVector3d LLAgent::calcThirdPersonFocusOffset()
agent_rot *= ((LLViewerObject*)(mAvatarObject->getParent()))->getRenderRotation();
}
- focus_offset = focus_offset * agent_rot;
+ focus_offset = mFocusOffsetInitial[mCameraPreset] * agent_rot;
return focus_offset;
}
@@ -3627,7 +3626,6 @@ LLVector3d LLAgent::calcCameraPositionTargetGlobal(BOOL *hit_limit)
LLVector3d frame_center_global = mAvatarObject.isNull() ? getPositionGlobal()
: getPosGlobalFromAgent(mAvatarObject->mRoot.getWorldPosition());
- LLVector3 upAxis = getUpAxis();
BOOL isConstrained = FALSE;
LLVector3d head_offset;
head_offset.setVec(mThirdPersonHeadOffset);
@@ -3647,7 +3645,7 @@ LLVector3d LLAgent::calcCameraPositionTargetGlobal(BOOL *hit_limit)
return LLVector3d::zero;
}
head_offset.clearVec();
- if (mAvatarObject->mIsSitting && mAvatarObject->getParent())
+ if (mAvatarObject->isSitting() && mAvatarObject->getParent())
{
mAvatarObject->updateHeadOffset();
head_offset.mdV[VX] = mAvatarObject->mHeadOffset.mV[VX];
@@ -3661,7 +3659,7 @@ LLVector3d LLAgent::calcCameraPositionTargetGlobal(BOOL *hit_limit)
else
{
head_offset.mdV[VZ] = mAvatarObject->mHeadOffset.mV[VZ];
- if (mAvatarObject->mIsSitting)
+ if (mAvatarObject->isSitting())
{
head_offset.mdV[VZ] += 0.1;
}
@@ -3677,7 +3675,7 @@ LLVector3d LLAgent::calcCameraPositionTargetGlobal(BOOL *hit_limit)
if (mSitCameraEnabled
&& mAvatarObject.notNull()
- && mAvatarObject->mIsSitting
+ && mAvatarObject->isSitting()
&& mSitCameraReferenceObject.notNull())
{
// sit camera
@@ -3690,7 +3688,7 @@ LLVector3d LLAgent::calcCameraPositionTargetGlobal(BOOL *hit_limit)
}
else
{
- local_camera_offset = mCameraZoomFraction * mCameraOffsetDefault * gSavedSettings.getF32("CameraOffsetScale");
+ local_camera_offset = mCameraZoomFraction * getCameraOffsetInitial() * gSavedSettings.getF32("CameraOffsetScale");
// are we sitting down?
if (mAvatarObject.notNull() && mAvatarObject->getParent())
@@ -3709,7 +3707,7 @@ LLVector3d LLAgent::calcCameraPositionTargetGlobal(BOOL *hit_limit)
local_camera_offset = mFrameAgent.rotateToAbsolute( local_camera_offset );
}
- if (!mCameraCollidePlane.isExactlyZero() && (mAvatarObject.isNull() || !mAvatarObject->mIsSitting))
+ if (!mCameraCollidePlane.isExactlyZero() && (mAvatarObject.isNull() || !mAvatarObject->isSitting()))
{
LLVector3 plane_normal;
plane_normal.setVec(mCameraCollidePlane.mV);
@@ -3887,6 +3885,12 @@ LLVector3d LLAgent::calcCameraPositionTargetGlobal(BOOL *hit_limit)
}
+LLVector3 LLAgent::getCameraOffsetInitial()
+{
+ return mCameraOffsetInitial[mCameraPreset];
+}
+
+
//-----------------------------------------------------------------------------
// handleScrollWheel()
//-----------------------------------------------------------------------------
@@ -3921,10 +3925,12 @@ void LLAgent::handleScrollWheel(S32 clicks)
}
else if (mFocusOnAvatar && mCameraMode == CAMERA_MODE_THIRD_PERSON)
{
- F32 current_zoom_fraction = mTargetCameraDistance / (mCameraOffsetDefault.magVec() * gSavedSettings.getF32("CameraOffsetScale"));
+ F32 camera_offset_initial_mag = getCameraOffsetInitial().magVec();
+
+ F32 current_zoom_fraction = mTargetCameraDistance / (camera_offset_initial_mag * gSavedSettings.getF32("CameraOffsetScale"));
current_zoom_fraction *= 1.f - pow(ROOT_ROOT_TWO, clicks);
- cameraOrbitIn(current_zoom_fraction * mCameraOffsetDefault.magVec() * gSavedSettings.getF32("CameraOffsetScale"));
+ cameraOrbitIn(current_zoom_fraction * camera_offset_initial_mag * gSavedSettings.getF32("CameraOffsetScale"));
}
else
{
@@ -4135,7 +4141,7 @@ void LLAgent::changeCameraToThirdPerson(BOOL animate)
if (mAvatarObject.notNull())
{
- if (!mAvatarObject->mIsSitting)
+ if (!mAvatarObject->isSitting())
{
mAvatarObject->mPelvisp->setPosition(LLVector3::zero);
}
@@ -4217,7 +4223,7 @@ void LLAgent::changeCameraToCustomizeAvatar(BOOL avatar_animate, BOOL camera_ani
return;
}
- setControlFlags(AGENT_CONTROL_STAND_UP); // force stand up
+ standUp(); // force stand up
gViewerWindow->getWindow()->resetBusyCount();
if (gFaceEditToolset)
@@ -4255,7 +4261,7 @@ void LLAgent::changeCameraToCustomizeAvatar(BOOL avatar_animate, BOOL camera_ani
gFocusMgr.setKeyboardFocus( NULL );
gFocusMgr.setMouseCapture( NULL );
- LLVOAvatar::onCustomizeStart();
+ LLVOAvatarSelf::onCustomizeStart();
}
if (mAvatarObject.notNull())
@@ -4297,6 +4303,20 @@ void LLAgent::changeCameraToCustomizeAvatar(BOOL avatar_animate, BOOL camera_ani
}
+void LLAgent::switchCameraPreset(ECameraPreset preset)
+{
+ //zoom is supposed to be reset for the front and group views
+ mCameraZoomFraction = 1.f;
+
+ //focusing on avatar in that case means following him on movements
+ mFocusOnAvatar = TRUE;
+
+ mCameraPreset = preset;
+
+ gSavedSettings.setU32("CameraPreset", mCameraPreset);
+}
+
+
//
// Focus point management
//
@@ -4940,6 +4960,9 @@ int LLAgent::convertTextToMaturity(char text)
bool LLAgent::sendMaturityPreferenceToServer(int preferredMaturity)
{
+ if (!getRegion())
+ return false;
+
// Update agent access preference on the server
std::string url = getRegion()->getCapability("UpdateAgentInformation");
if (!url.empty())
@@ -4999,15 +5022,19 @@ const LLAgentAccess& LLAgent::getAgentAccess()
return mAgentAccess;
}
+bool LLAgent::validateMaturity(const LLSD& newvalue)
+{
+ return mAgentAccess.canSetMaturity(newvalue.asInteger());
+}
-void LLAgent::buildFullname(std::string& name) const
+void LLAgent::handleMaturity(const LLSD& newvalue)
{
- if (mAvatarObject.notNull())
- {
- name = mAvatarObject->getFullname();
- }
+ sendMaturityPreferenceToServer(newvalue.asInteger());
}
+//----------------------------------------------------------------------------
+
+//*TODO remove, is not used anywhere as of August 20, 2009
void LLAgent::buildFullnameAndTitle(std::string& name) const
{
if (isGroupMember())
@@ -5161,54 +5188,6 @@ BOOL LLAgent::setUserGroupFlags(const LLUUID& group_id, BOOL accept_notices, BOO
return FALSE;
}
-// utility to build a location string
-void LLAgent::buildLocationString(std::string& str)
-{
- const LLVector3& agent_pos_region = getPositionAgent();
- S32 pos_x = S32(agent_pos_region.mV[VX]);
- S32 pos_y = S32(agent_pos_region.mV[VY]);
- S32 pos_z = S32(agent_pos_region.mV[VZ]);
-
- // Round the numbers based on the velocity
- LLVector3 agent_velocity = getVelocity();
- F32 velocity_mag_sq = agent_velocity.magVecSquared();
-
- const F32 FLY_CUTOFF = 6.f; // meters/sec
- const F32 FLY_CUTOFF_SQ = FLY_CUTOFF * FLY_CUTOFF;
- const F32 WALK_CUTOFF = 1.5f; // meters/sec
- const F32 WALK_CUTOFF_SQ = WALK_CUTOFF * WALK_CUTOFF;
-
- if (velocity_mag_sq > FLY_CUTOFF_SQ)
- {
- pos_x -= pos_x % 4;
- pos_y -= pos_y % 4;
- }
- else if (velocity_mag_sq > WALK_CUTOFF_SQ)
- {
- pos_x -= pos_x % 2;
- pos_y -= pos_y % 2;
- }
-
- // create a defult name and description for the landmark
- std::string buffer;
- if( LLViewerParcelMgr::getInstance()->getAgentParcelName().empty() )
- {
- // the parcel doesn't have a name
- buffer = llformat("%.32s (%d, %d, %d)",
- getRegion()->getName().c_str(),
- pos_x, pos_y, pos_z);
- }
- else
- {
- // the parcel has a name, so include it in the landmark name
- buffer = llformat("%.32s, %.32s (%d, %d, %d)",
- LLViewerParcelMgr::getInstance()->getAgentParcelName().c_str(),
- getRegion()->getName().c_str(),
- pos_x, pos_y, pos_z);
- }
- str = buffer;
-}
-
LLQuaternion LLAgent::getHeadRotation()
{
if (mAvatarObject.isNull() || !mAvatarObject->mPelvisp || !mAvatarObject->mHeadp)
@@ -5370,30 +5349,6 @@ BOOL LLAgent::allowOperation(PermissionBit op,
return perm.allowOperationBy(op, agent_proxy, group_proxy);
}
-
-void LLAgent::getName(std::string& name)
-{
- name.clear();
-
- if (mAvatarObject.notNull())
- {
- LLNameValue *first_nv = mAvatarObject->getNVPair("FirstName");
- LLNameValue *last_nv = mAvatarObject->getNVPair("LastName");
- if (first_nv && last_nv)
- {
- name = first_nv->printData() + " " + last_nv->printData();
- }
- else
- {
- llwarns << "Agent is missing FirstName and/or LastName nv pair." << llendl;
- }
- }
- else
- {
- name = gSavedSettings.getString("FirstName") + " " + gSavedSettings.getString("LastName");
- }
-}
-
const LLColor4 &LLAgent::getEffectColor()
{
return mEffectColor;
@@ -5409,16 +5364,46 @@ void LLAgent::initOriginGlobal(const LLVector3d &origin_global)
mAgentOriginGlobal = origin_global;
}
+BOOL LLAgent::leftButtonGrabbed() const
+{
+ return (!cameraMouselook() && mControlsTakenCount[CONTROL_LBUTTON_DOWN_INDEX] > 0)
+ || (cameraMouselook() && mControlsTakenCount[CONTROL_ML_LBUTTON_DOWN_INDEX] > 0)
+ || (!cameraMouselook() && mControlsTakenPassedOnCount[CONTROL_LBUTTON_DOWN_INDEX] > 0)
+ || (cameraMouselook() && mControlsTakenPassedOnCount[CONTROL_ML_LBUTTON_DOWN_INDEX] > 0);
+}
+
+BOOL LLAgent::rotateGrabbed() const
+{
+ return (mControlsTakenCount[CONTROL_YAW_POS_INDEX] > 0)
+ || (mControlsTakenCount[CONTROL_YAW_NEG_INDEX] > 0);
+}
+
+BOOL LLAgent::forwardGrabbed() const
+{
+ return (mControlsTakenCount[CONTROL_AT_POS_INDEX] > 0);
+}
+
+BOOL LLAgent::backwardGrabbed() const
+{
+ return (mControlsTakenCount[CONTROL_AT_NEG_INDEX] > 0);
+}
+
+BOOL LLAgent::upGrabbed() const
+{
+ return (mControlsTakenCount[CONTROL_UP_POS_INDEX] > 0);
+}
+
+BOOL LLAgent::downGrabbed() const
+{
+ return (mControlsTakenCount[CONTROL_UP_NEG_INDEX] > 0);
+}
+
void update_group_floaters(const LLUUID& group_id)
{
- LLFloaterGroupInfo::refreshGroup(group_id);
-
- // update avatar info
- LLFloaterAvatarInfo* fa = LLFloaterAvatarInfo::getInstance(gAgent.getID());
- if(fa)
- {
- fa->resetGroupList();
- }
+
+ LLGroupActions::refresh(group_id);
+ //*TODO Implement group update for Profile View
+ // still actual as of July 31, 2009 (DZ)
if (gIMMgr)
{
@@ -5464,7 +5449,7 @@ void LLAgent::processAgentDropGroup(LLMessageSystem *msg, void **)
LLGroupMgr::getInstance()->clearGroupData(group_id);
// close the floater for this group, if any.
- LLFloaterGroupInfo::closeGroup(group_id);
+ LLGroupActions::closeGroup(group_id);
// refresh the group panel of the search window, if necessary.
LLFloaterDirectory::refreshGroup(group_id);
}
@@ -5487,7 +5472,7 @@ class LLAgentDropGroupViewerNode : public LLHTTPNode
!input.has("body") )
{
//what to do with badly formed message?
- response->status(400);
+ response->statusUnknownError(400);
response->result(LLSD("Invalid message parameters"));
}
@@ -5543,7 +5528,7 @@ class LLAgentDropGroupViewerNode : public LLHTTPNode
LLGroupMgr::getInstance()->clearGroupData(group_id);
// close the floater for this group, if any.
- LLFloaterGroupInfo::closeGroup(group_id);
+ LLGroupActions::closeGroup(group_id);
// refresh the group panel of the search window,
//if necessary.
LLFloaterDirectory::refreshGroup(group_id);
@@ -5560,7 +5545,7 @@ class LLAgentDropGroupViewerNode : public LLHTTPNode
else
{
//what to do with badly formed message?
- response->status(400);
+ response->statusUnknownError(400);
response->result(LLSD("Invalid message parameters"));
}
}
@@ -5854,9 +5839,9 @@ void LLAgent::processControlRelease(LLMessageSystem *msg, void **)
//static
void LLAgent::processAgentCachedTextureResponse(LLMessageSystem *mesgsys, void **user_data)
{
- gAgent.mNumPendingQueries--;
+ gAgentQueryManager.mNumPendingQueries--;
- LLVOAvatar* avatarp = gAgent.getAvatarObject();
+ LLVOAvatarSelf* avatarp = gAgent.getAvatarObject();
if (!avatarp || avatarp->isDead())
{
llwarns << "No avatar for user in cached texture update!" << llendl;
@@ -5886,12 +5871,12 @@ void LLAgent::processAgentCachedTextureResponse(LLMessageSystem *mesgsys, void *
if (texture_id.notNull()
&& (S32)texture_index < BAKED_NUM_INDICES
- && gAgent.mActiveCacheQueries[ texture_index ] == query_id)
+ && gAgentQueryManager.mActiveCacheQueries[texture_index] == query_id)
{
//llinfos << "Received cached texture " << (U32)texture_index << ": " << texture_id << llendl;
- avatarp->setCachedBakedTexture(getTextureIndex((EBakedTextureIndex)texture_index), texture_id);
+ avatarp->setCachedBakedTexture(LLVOAvatarDictionary::bakedToLocalTextureIndex((EBakedTextureIndex)texture_index), texture_id);
//avatarp->setTETexture( LLVOAvatar::sBakedTextureIndices[texture_index], texture_id );
- gAgent.mActiveCacheQueries[ texture_index ] = 0;
+ gAgentQueryManager.mActiveCacheQueries[texture_index] = 0;
num_results++;
}
}
@@ -5900,7 +5885,7 @@ void LLAgent::processAgentCachedTextureResponse(LLMessageSystem *mesgsys, void *
avatarp->updateMeshTextures();
- if (gAgent.mNumPendingQueries == 0)
+ if (gAgentQueryManager.mNumPendingQueries == 0)
{
// RN: not sure why composites are disabled at this point
avatarp->setCompositeUpdatesEnabled(TRUE);
@@ -5910,8 +5895,7 @@ void LLAgent::processAgentCachedTextureResponse(LLMessageSystem *mesgsys, void *
BOOL LLAgent::anyControlGrabbed() const
{
- U32 i;
- for (i = 0; i < TOTAL_CONTROLS; i++)
+ for (U32 i = 0; i < TOTAL_CONTROLS; i++)
{
if (gAgent.mControlsTakenCount[i] > 0)
return TRUE;
@@ -6003,13 +5987,14 @@ bool LLAgent::teleportCore(bool is_local)
// process_teleport_location_reply
// close the map and find panels so we can see our destination
- LLFloaterWorldMap::hide(NULL);
- LLFloaterDirectory::hide(NULL);
+ LLFloaterReg::hideInstance("world_map");
+ LLFloaterReg::hideInstance("search");
// hide land floater too - it'll be out of date
- LLFloaterLand::hideInstance();
-
+ LLFloaterReg::hideInstance("about_land");
+
LLViewerParcelMgr::getInstance()->deselectLand();
+ LLViewerMediaFocus::getInstance()->setFocusFace(false, NULL, 0, NULL);
// Close all pie menus, deselect land, etc.
// Don't change the camera until we know teleport succeeded. JC
@@ -6169,12 +6154,17 @@ void LLAgent::setTeleportState(ETeleportState state)
mTeleportState = state;
if (mTeleportState > TELEPORT_NONE && gSavedSettings.getBOOL("FreezeTime"))
{
- LLFloaterSnapshot::hide(0);
+ LLFloaterReg::hideInstance("snapshot");
}
if (mTeleportState == TELEPORT_MOVING)
{
// We're outa here. Save "back" slurl.
- mTeleportSourceSLURL = getSLURL();
+ mTeleportSourceSLURL = LLAgentUI::buildSLURL();
+ }
+ else if(mTeleportState == TELEPORT_ARRIVING)
+ {
+ // Let the interested parties know we've teleported.
+ LLViewerParcelMgr::getInstance()->onTeleportFinished(false, getPositionGlobal());
}
}
@@ -6303,878 +6293,6 @@ void LLAgent::requestLeaveGodMode()
sendReliableMessage();
}
-// wearables
-LLAgent::createStandardWearablesAllDoneCallback::~createStandardWearablesAllDoneCallback()
-{
- gAgent.createStandardWearablesAllDone();
-}
-
-LLAgent::sendAgentWearablesUpdateCallback::~sendAgentWearablesUpdateCallback()
-{
- gAgent.sendAgentWearablesUpdate();
-}
-
-LLAgent::addWearableToAgentInventoryCallback::addWearableToAgentInventoryCallback(
- LLPointer<LLRefCount> cb, S32 index, LLWearable* wearable, U32 todo) :
- mIndex(index),
- mWearable(wearable),
- mTodo(todo),
- mCB(cb)
-{
-}
-
-void LLAgent::addWearableToAgentInventoryCallback::fire(const LLUUID& inv_item)
-{
- if (inv_item.isNull())
- return;
-
- gAgent.addWearabletoAgentInventoryDone(mIndex, inv_item, mWearable);
-
- if (mTodo & CALL_UPDATE)
- {
- gAgent.sendAgentWearablesUpdate();
- }
- if (mTodo & CALL_RECOVERDONE)
- {
- gAgent.recoverMissingWearableDone();
- }
- /*
- * Do this for every one in the loop
- */
- if (mTodo & CALL_CREATESTANDARDDONE)
- {
- gAgent.createStandardWearablesDone(mIndex);
- }
- if (mTodo & CALL_MAKENEWOUTFITDONE)
- {
- gAgent.makeNewOutfitDone(mIndex);
- }
-}
-
-void LLAgent::addWearabletoAgentInventoryDone(
- S32 index,
- const LLUUID& item_id,
- LLWearable* wearable)
-{
- if (item_id.isNull())
- return;
-
- LLUUID old_item_id = mWearableEntry[index].mItemID;
- mWearableEntry[index].mItemID = item_id;
- mWearableEntry[index].mWearable = wearable;
- if (old_item_id.notNull())
- gInventory.addChangedMask(LLInventoryObserver::LABEL, old_item_id);
- gInventory.addChangedMask(LLInventoryObserver::LABEL, item_id);
- LLViewerInventoryItem* item = gInventory.getItem(item_id);
- if(item && wearable)
- {
- // We're changing the asset id, so we both need to set it
- // locally via setAssetUUID() and via setTransactionID() which
- // will be decoded on the server. JC
- item->setAssetUUID(wearable->getID());
- item->setTransactionID(wearable->getTransactionID());
- gInventory.addChangedMask(LLInventoryObserver::INTERNAL, item_id);
- item->updateServer(FALSE);
- }
- gInventory.notifyObservers();
-}
-
-void LLAgent::sendAgentWearablesUpdate()
-{
- // First make sure that we have inventory items for each wearable
- S32 i;
- for(i=0; i < WT_COUNT; ++i)
- {
- LLWearable* wearable = mWearableEntry[ i ].mWearable;
- if (wearable)
- {
- if( mWearableEntry[ i ].mItemID.isNull() )
- {
- LLPointer<LLInventoryCallback> cb =
- new addWearableToAgentInventoryCallback(
- LLPointer<LLRefCount>(NULL),
- i,
- wearable,
- addWearableToAgentInventoryCallback::CALL_NONE);
- addWearableToAgentInventory(cb, wearable);
- }
- else
- {
- gInventory.addChangedMask( LLInventoryObserver::LABEL,
- mWearableEntry[i].mItemID );
- }
- }
- }
-
- // Then make sure the inventory is in sync with the avatar.
- gInventory.notifyObservers();
-
- // Send the AgentIsNowWearing
- gMessageSystem->newMessageFast(_PREHASH_AgentIsNowWearing);
-
- gMessageSystem->nextBlockFast(_PREHASH_AgentData);
- gMessageSystem->addUUIDFast(_PREHASH_AgentID, getID());
- gMessageSystem->addUUIDFast(_PREHASH_SessionID, getSessionID());
-
- lldebugs << "sendAgentWearablesUpdate()" << llendl;
- for(i=0; i < WT_COUNT; ++i)
- {
- gMessageSystem->nextBlockFast(_PREHASH_WearableData);
-
- U8 type_u8 = (U8)i;
- gMessageSystem->addU8Fast(_PREHASH_WearableType, type_u8 );
-
- LLWearable* wearable = mWearableEntry[ i ].mWearable;
- if( wearable )
- {
- //llinfos << "Sending wearable " << wearable->getName() << llendl;
- gMessageSystem->addUUIDFast(_PREHASH_ItemID, mWearableEntry[ i ].mItemID );
- }
- else
- {
- //llinfos << "Not wearing wearable type " << LLWearable::typeToTypeName((EWearableType)i) << llendl;
- gMessageSystem->addUUIDFast(_PREHASH_ItemID, LLUUID::null );
- }
-
- lldebugs << " " << LLWearable::typeToTypeLabel((EWearableType)i) << ": " << (wearable ? wearable->getID() : LLUUID::null) << llendl;
- }
- gAgent.sendReliableMessage();
-}
-
-void LLAgent::saveWearable( EWearableType type, BOOL send_update )
-{
- LLWearable* old_wearable = mWearableEntry[(S32)type].mWearable;
- if( old_wearable && (old_wearable->isDirty() || old_wearable->isOldVersion()) )
- {
- LLWearable* new_wearable = gWearableList.createCopyFromAvatar( old_wearable );
- mWearableEntry[(S32)type].mWearable = new_wearable;
-
- LLInventoryItem* item = gInventory.getItem(mWearableEntry[(S32)type].mItemID);
- if( item )
- {
- // Update existing inventory item
- LLPointer<LLViewerInventoryItem> template_item =
- new LLViewerInventoryItem(item->getUUID(),
- item->getParentUUID(),
- item->getPermissions(),
- new_wearable->getID(),
- new_wearable->getAssetType(),
- item->getInventoryType(),
- item->getName(),
- item->getDescription(),
- item->getSaleInfo(),
- item->getFlags(),
- item->getCreationDate());
- template_item->setTransactionID(new_wearable->getTransactionID());
- template_item->updateServer(FALSE);
- gInventory.updateItem(template_item);
- }
- else
- {
- // Add a new inventory item (shouldn't ever happen here)
- U32 todo = addWearableToAgentInventoryCallback::CALL_NONE;
- if (send_update)
- {
- todo |= addWearableToAgentInventoryCallback::CALL_UPDATE;
- }
- LLPointer<LLInventoryCallback> cb =
- new addWearableToAgentInventoryCallback(
- LLPointer<LLRefCount>(NULL),
- (S32)type,
- new_wearable,
- todo);
- addWearableToAgentInventory(cb, new_wearable);
- return;
- }
-
- getAvatarObject()->wearableUpdated( type );
-
- if( send_update )
- {
- sendAgentWearablesUpdate();
- }
- }
-}
-
-void LLAgent::saveWearableAs(
- EWearableType type,
- const std::string& new_name,
- BOOL save_in_lost_and_found)
-{
- if(!isWearableCopyable(type))
- {
- llwarns << "LLAgent::saveWearableAs() not copyable." << llendl;
- return;
- }
- LLWearable* old_wearable = getWearable(type);
- if(!old_wearable)
- {
- llwarns << "LLAgent::saveWearableAs() no old wearable." << llendl;
- return;
- }
- LLInventoryItem* item = gInventory.getItem(mWearableEntry[type].mItemID);
- if(!item)
- {
- llwarns << "LLAgent::saveWearableAs() no inventory item." << llendl;
- return;
- }
- std::string trunc_name(new_name);
- LLStringUtil::truncate(trunc_name, DB_INV_ITEM_NAME_STR_LEN);
- LLWearable* new_wearable = gWearableList.createCopyFromAvatar(
- old_wearable,
- trunc_name);
- LLPointer<LLInventoryCallback> cb =
- new addWearableToAgentInventoryCallback(
- LLPointer<LLRefCount>(NULL),
- type,
- new_wearable,
- addWearableToAgentInventoryCallback::CALL_UPDATE);
- LLUUID category_id;
- if (save_in_lost_and_found)
- {
- category_id = gInventory.findCategoryUUIDForType(
- LLAssetType::AT_LOST_AND_FOUND);
- }
- else
- {
- // put in same folder as original
- category_id = item->getParentUUID();
- }
-
- copy_inventory_item(
- gAgent.getID(),
- item->getPermissions().getOwner(),
- item->getUUID(),
- category_id,
- new_name,
- cb);
-
-/*
- LLWearable* old_wearable = getWearable( type );
- if( old_wearable )
- {
- std::string old_name = old_wearable->getName();
- old_wearable->setName( new_name );
- LLWearable* new_wearable = gWearableList.createCopyFromAvatar( old_wearable );
- old_wearable->setName( old_name );
-
- LLUUID category_id;
- LLInventoryItem* item = gInventory.getItem( mWearableEntry[ type ].mItemID );
- if( item )
- {
- new_wearable->setPermissions(item->getPermissions());
- if (save_in_lost_and_found)
- {
- category_id = gInventory.findCategoryUUIDForType(LLAssetType::AT_LOST_AND_FOUND);
- }
- else
- {
- // put in same folder as original
- category_id = item->getParentUUID();
- }
- LLInventoryView* view = LLInventoryView::getActiveInventory();
- if(view)
- {
- view->getPanel()->setSelection(item->getUUID(), TAKE_FOCUS_NO);
- }
- }
-
- mWearableEntry[ type ].mWearable = new_wearable;
- LLPointer<LLInventoryCallback> cb =
- new addWearableToAgentInventoryCallback(
- LLPointer<LLRefCount>(NULL),
- type,
- addWearableToAgentInventoryCallback::CALL_UPDATE);
- addWearableToAgentInventory(cb, new_wearable, category_id);
- }
-*/
-}
-
-void LLAgent::revertWearable( EWearableType type )
-{
- LLWearable* wearable = mWearableEntry[(S32)type].mWearable;
- if( wearable )
- {
- wearable->writeToAvatar( TRUE );
- }
- sendAgentSetAppearance();
-}
-
-void LLAgent::revertAllWearables()
-{
- for( S32 i=0; i < WT_COUNT; i++ )
- {
- revertWearable( (EWearableType)i );
- }
-}
-
-void LLAgent::saveAllWearables()
-{
- //if(!gInventory.isLoaded())
- //{
- // return;
- //}
-
- for( S32 i=0; i < WT_COUNT; i++ )
- {
- saveWearable( (EWearableType)i, FALSE );
- }
- sendAgentWearablesUpdate();
-}
-
-// Called when the user changes the name of a wearable inventory item that is currenlty being worn.
-void LLAgent::setWearableName( const LLUUID& item_id, const std::string& new_name )
-{
- for( S32 i=0; i < WT_COUNT; i++ )
- {
- if( mWearableEntry[i].mItemID == item_id )
- {
- LLWearable* old_wearable = mWearableEntry[i].mWearable;
- llassert( old_wearable );
-
- std::string old_name = old_wearable->getName();
- old_wearable->setName( new_name );
- LLWearable* new_wearable = gWearableList.createCopy( old_wearable );
- LLInventoryItem* item = gInventory.getItem(item_id);
- if(item)
- {
- new_wearable->setPermissions(item->getPermissions());
- }
- old_wearable->setName( old_name );
-
- mWearableEntry[i].mWearable = new_wearable;
- sendAgentWearablesUpdate();
- break;
- }
- }
-}
-
-
-BOOL LLAgent::isWearableModifiable(EWearableType type)
-{
- LLUUID item_id = getWearableItem(type);
- if(!item_id.isNull())
- {
- LLInventoryItem* item = gInventory.getItem(item_id);
- if(item && item->getPermissions().allowModifyBy(gAgent.getID(),
- gAgent.getGroupID()))
- {
- return TRUE;
- }
- }
- return FALSE;
-}
-
-BOOL LLAgent::isWearableCopyable(EWearableType type)
-{
- LLUUID item_id = getWearableItem(type);
- if(!item_id.isNull())
- {
- LLInventoryItem* item = gInventory.getItem(item_id);
- if(item && item->getPermissions().allowCopyBy(gAgent.getID(),
- gAgent.getGroupID()))
- {
- return TRUE;
- }
- }
- return FALSE;
-}
-
-U32 LLAgent::getWearablePermMask(EWearableType type)
-{
- LLUUID item_id = getWearableItem(type);
- if(!item_id.isNull())
- {
- LLInventoryItem* item = gInventory.getItem(item_id);
- if(item)
- {
- return item->getPermissions().getMaskOwner();
- }
- }
- return PERM_NONE;
-}
-
-LLInventoryItem* LLAgent::getWearableInventoryItem(EWearableType type)
-{
- LLUUID item_id = getWearableItem(type);
- LLInventoryItem* item = NULL;
- if(item_id.notNull())
- {
- item = gInventory.getItem(item_id);
- }
- return item;
-}
-
-LLWearable* LLAgent::getWearableFromWearableItem( const LLUUID& item_id )
-{
- for( S32 i=0; i < WT_COUNT; i++ )
- {
- if( mWearableEntry[i].mItemID == item_id )
- {
- return mWearableEntry[i].mWearable;
- }
- }
- return NULL;
-}
-
-
-void LLAgent::sendAgentWearablesRequest()
-{
- gMessageSystem->newMessageFast(_PREHASH_AgentWearablesRequest);
- gMessageSystem->nextBlockFast(_PREHASH_AgentData);
- gMessageSystem->addUUIDFast(_PREHASH_AgentID, gAgent.getID() );
- gMessageSystem->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID() );
- sendReliableMessage();
-}
-
-// Used to enable/disable menu items.
-// static
-BOOL LLAgent::selfHasWearable( void* userdata )
-{
- EWearableType type = (EWearableType)(intptr_t)userdata;
- return gAgent.getWearable( type ) != NULL;
-}
-
-BOOL LLAgent::isWearingItem( const LLUUID& item_id )
-{
- return (getWearableFromWearableItem( item_id ) != NULL);
-}
-
-// static
-void LLAgent::processAgentInitialWearablesUpdate( LLMessageSystem* mesgsys, void** user_data )
-{
- // We should only receive this message a single time. Ignore subsequent AgentWearablesUpdates
- // that may result from AgentWearablesRequest having been sent more than once.
- static bool first = true;
- if (!first) return;
- first = false;
-
- LLUUID agent_id;
- gMessageSystem->getUUIDFast(_PREHASH_AgentData, _PREHASH_AgentID, agent_id );
-
- LLVOAvatar* avatar = gAgent.getAvatarObject();
- if( avatar && (agent_id == avatar->getID()) )
- {
- gMessageSystem->getU32Fast(_PREHASH_AgentData, _PREHASH_SerialNum, gAgent.mAgentWearablesUpdateSerialNum );
-
- S32 num_wearables = gMessageSystem->getNumberOfBlocksFast(_PREHASH_WearableData);
- if( num_wearables < 4 )
- {
- // Transitional state. Avatars should always have at least their body parts (hair, eyes, shape and skin).
- // The fact that they don't have any here (only a dummy is sent) implies that this account existed
- // before we had wearables, or that the database has gotten messed up.
- return;
- }
-
- //lldebugs << "processAgentInitialWearablesUpdate()" << llendl;
- // Add wearables
- LLUUID asset_id_array[ WT_COUNT ];
- S32 i;
- for( i=0; i < num_wearables; i++ )
- {
- U8 type_u8 = 0;
- gMessageSystem->getU8Fast(_PREHASH_WearableData, _PREHASH_WearableType, type_u8, i );
- if( type_u8 >= WT_COUNT )
- {
- continue;
- }
- EWearableType type = (EWearableType) type_u8;
-
- LLUUID item_id;
- gMessageSystem->getUUIDFast(_PREHASH_WearableData, _PREHASH_ItemID, item_id, i );
-
- LLUUID asset_id;
- gMessageSystem->getUUIDFast(_PREHASH_WearableData, _PREHASH_AssetID, asset_id, i );
- if( asset_id.isNull() )
- {
- LLWearable::removeFromAvatar( type, FALSE );
- }
- else
- {
- LLAssetType::EType asset_type = LLWearable::typeToAssetType( type );
- if( asset_type == LLAssetType::AT_NONE )
- {
- continue;
- }
-
- gAgent.mWearableEntry[type].mItemID = item_id;
- asset_id_array[type] = asset_id;
- }
-
- lldebugs << " " << LLWearable::typeToTypeLabel(type) << llendl;
- }
-
- // now that we have the asset ids...request the wearable assets
- for( i = 0; i < WT_COUNT; i++ )
- {
- if( !gAgent.mWearableEntry[i].mItemID.isNull() )
- {
- gWearableList.getAsset(
- asset_id_array[i],
- LLStringUtil::null,
- LLWearable::typeToAssetType( (EWearableType) i ),
- LLAgent::onInitialWearableAssetArrived, (void*)(intptr_t)i );
- }
- }
- }
-}
-
-// A single wearable that the avatar was wearing on start-up has arrived from the database.
-// static
-void LLAgent::onInitialWearableAssetArrived( LLWearable* wearable, void* userdata )
-{
- EWearableType type = (EWearableType)(intptr_t)userdata;
-
- LLVOAvatar* avatar = gAgent.getAvatarObject();
- if( !avatar )
- {
- return;
- }
-
- if( wearable )
- {
- llassert( type == wearable->getType() );
- gAgent.mWearableEntry[ type ].mWearable = wearable;
-
- // disable composites if initial textures are baked
- avatar->setupComposites();
- gAgent.queryWearableCache();
-
- wearable->writeToAvatar( FALSE );
- avatar->setCompositeUpdatesEnabled(TRUE);
- gInventory.addChangedMask( LLInventoryObserver::LABEL, gAgent.mWearableEntry[type].mItemID );
- }
- else
- {
- // Somehow the asset doesn't exist in the database.
- gAgent.recoverMissingWearable( type );
- }
-
- gInventory.notifyObservers();
-
- // Have all the wearables that the avatar was wearing at log-in arrived?
- if( !gAgent.mWearablesLoaded )
- {
- gAgent.mWearablesLoaded = TRUE;
- for( S32 i = 0; i < WT_COUNT; i++ )
- {
- if( !gAgent.mWearableEntry[i].mItemID.isNull() && !gAgent.mWearableEntry[i].mWearable )
- {
- gAgent.mWearablesLoaded = FALSE;
- break;
- }
- }
- }
-
- if( gAgent.mWearablesLoaded )
- {
- // Make sure that the server's idea of the avatar's wearables actually match the wearables.
- gAgent.sendAgentSetAppearance();
-
- // Check to see if there are any baked textures that we hadn't uploaded before we logged off last time.
- // If there are any, schedule them to be uploaded as soon as the layer textures they depend on arrive.
- if( !gAgent.cameraCustomizeAvatar() )
- {
- avatar->requestLayerSetUploads();
- }
- }
-}
-
-// Normally, all wearables referred to "AgentWearablesUpdate" will correspond to actual assets in the
-// database. If for some reason, we can't load one of those assets, we can try to reconstruct it so that
-// the user isn't left without a shape, for example. (We can do that only after the inventory has loaded.)
-void LLAgent::recoverMissingWearable( EWearableType type )
-{
- // Try to recover by replacing missing wearable with a new one.
- LLNotifications::instance().add("ReplacedMissingWearable");
- lldebugs << "Wearable " << LLWearable::typeToTypeLabel( type ) << " could not be downloaded. Replaced inventory item with default wearable." << llendl;
- LLWearable* new_wearable = gWearableList.createNewWearable(type);
-
- S32 type_s32 = (S32) type;
- mWearableEntry[type_s32].mWearable = new_wearable;
- new_wearable->writeToAvatar( TRUE );
-
- // Add a new one in the lost and found folder.
- // (We used to overwrite the "not found" one, but that could potentially
- // destory content.) JC
- LLUUID lost_and_found_id =
- gInventory.findCategoryUUIDForType(LLAssetType::AT_LOST_AND_FOUND);
- LLPointer<LLInventoryCallback> cb =
- new addWearableToAgentInventoryCallback(
- LLPointer<LLRefCount>(NULL),
- type_s32,
- new_wearable,
- addWearableToAgentInventoryCallback::CALL_RECOVERDONE);
- addWearableToAgentInventory( cb, new_wearable, lost_and_found_id, TRUE);
-}
-
-void LLAgent::recoverMissingWearableDone()
-{
- // Have all the wearables that the avatar was wearing at log-in arrived or been fabricated?
- mWearablesLoaded = TRUE;
- for( S32 i = 0; i < WT_COUNT; i++ )
- {
- if( !mWearableEntry[i].mItemID.isNull() && !mWearableEntry[i].mWearable )
- {
- mWearablesLoaded = FALSE;
- break;
- }
- }
-
- if( mWearablesLoaded )
- {
- // Make sure that the server's idea of the avatar's wearables actually match the wearables.
- sendAgentSetAppearance();
- }
- else
- {
- gInventory.addChangedMask( LLInventoryObserver::LABEL, LLUUID::null );
- gInventory.notifyObservers();
- }
-}
-
-void LLAgent::createStandardWearables(BOOL female)
-{
- llwarns << "Creating Standard " << (female ? "female" : "male" )
- << " Wearables" << llendl;
-
- if (mAvatarObject.isNull())
- {
- return;
- }
-
- if(female) mAvatarObject->setSex(SEX_FEMALE);
- else mAvatarObject->setSex(SEX_MALE);
-
- BOOL create[WT_COUNT] =
- {
- TRUE, //WT_SHAPE
- TRUE, //WT_SKIN
- TRUE, //WT_HAIR
- TRUE, //WT_EYES
- TRUE, //WT_SHIRT
- TRUE, //WT_PANTS
- TRUE, //WT_SHOES
- TRUE, //WT_SOCKS
- FALSE, //WT_JACKET
- FALSE, //WT_GLOVES
- TRUE, //WT_UNDERSHIRT
- TRUE, //WT_UNDERPANTS
- FALSE //WT_SKIRT
- };
-
- for( S32 i=0; i < WT_COUNT; i++ )
- {
- bool once = false;
- LLPointer<LLRefCount> donecb = NULL;
- if( create[i] )
- {
- if (!once)
- {
- once = true;
- donecb = new createStandardWearablesAllDoneCallback;
- }
- llassert( mWearableEntry[i].mWearable == NULL );
- LLWearable* wearable = gWearableList.createNewWearable((EWearableType)i);
- mWearableEntry[i].mWearable = wearable;
- // no need to update here...
- LLPointer<LLInventoryCallback> cb =
- new addWearableToAgentInventoryCallback(
- donecb,
- i,
- wearable,
- addWearableToAgentInventoryCallback::CALL_CREATESTANDARDDONE);
- addWearableToAgentInventory(cb, wearable, LLUUID::null, FALSE);
- }
- }
-}
-void LLAgent::createStandardWearablesDone(S32 index)
-{
- LLWearable* wearable = mWearableEntry[index].mWearable;
-
- if (wearable)
- {
- wearable->writeToAvatar(TRUE);
- }
-}
-
-void LLAgent::createStandardWearablesAllDone()
-{
- // ... because sendAgentWearablesUpdate will notify inventory
- // observers.
- mWearablesLoaded = TRUE;
- sendAgentWearablesUpdate();
- sendAgentSetAppearance();
-
- // Treat this as the first texture entry message, if none received yet
- mAvatarObject->onFirstTEMessageReceived();
-}
-
-void LLAgent::makeNewOutfit(
- const std::string& new_folder_name,
- const LLDynamicArray<S32>& wearables_to_include,
- const LLDynamicArray<S32>& attachments_to_include,
- BOOL rename_clothing)
-{
- if (mAvatarObject.isNull())
- {
- return;
- }
-
- // First, make a folder in the Clothes directory.
- LLUUID folder_id = gInventory.createNewCategory(
- gInventory.findCategoryUUIDForType(LLAssetType::AT_CLOTHING),
- LLAssetType::AT_NONE,
- new_folder_name);
-
- bool found_first_item = false;
-
- ///////////////////
- // Wearables
-
- if( wearables_to_include.count() )
- {
- // Then, iterate though each of the wearables and save copies of them in the folder.
- S32 i;
- S32 count = wearables_to_include.count();
- LLDynamicArray<LLUUID> delete_items;
- LLPointer<LLRefCount> cbdone = NULL;
- for( i = 0; i < count; ++i )
- {
- S32 index = wearables_to_include[i];
- LLWearable* old_wearable = mWearableEntry[ index ].mWearable;
- if( old_wearable )
- {
- std::string new_name;
- LLWearable* new_wearable;
- new_wearable = gWearableList.createCopy(old_wearable);
- if (rename_clothing)
- {
- new_name = new_folder_name;
- new_name.append(" ");
- new_name.append(old_wearable->getTypeLabel());
- LLStringUtil::truncate(new_name, DB_INV_ITEM_NAME_STR_LEN);
- new_wearable->setName(new_name);
- }
-
- LLViewerInventoryItem* item = gInventory.getItem(mWearableEntry[index].mItemID);
- S32 todo = addWearableToAgentInventoryCallback::CALL_NONE;
- if (!found_first_item)
- {
- found_first_item = true;
- /* set the focus to the first item */
- todo |= addWearableToAgentInventoryCallback::CALL_MAKENEWOUTFITDONE;
- /* send the agent wearables update when done */
- cbdone = new sendAgentWearablesUpdateCallback;
- }
- LLPointer<LLInventoryCallback> cb =
- new addWearableToAgentInventoryCallback(
- cbdone,
- index,
- new_wearable,
- todo);
- if (isWearableCopyable((EWearableType)index))
- {
- copy_inventory_item(
- gAgent.getID(),
- item->getPermissions().getOwner(),
- item->getUUID(),
- folder_id,
- new_name,
- cb);
- }
- else
- {
- move_inventory_item(
- gAgent.getID(),
- gAgent.getSessionID(),
- item->getUUID(),
- folder_id,
- new_name,
- cb);
- }
- }
- }
- gInventory.notifyObservers();
- }
-
-
- ///////////////////
- // Attachments
-
- if( attachments_to_include.count() )
- {
- BOOL msg_started = FALSE;
- LLMessageSystem* msg = gMessageSystem;
- for( S32 i = 0; i < attachments_to_include.count(); i++ )
- {
- S32 attachment_pt = attachments_to_include[i];
- LLViewerJointAttachment* attachment = get_if_there(mAvatarObject->mAttachmentPoints, attachment_pt, (LLViewerJointAttachment*)NULL );
- if(!attachment) continue;
- LLViewerObject* attached_object = attachment->getObject();
- if(!attached_object) continue;
- const LLUUID& item_id = attachment->getItemID();
- if(item_id.isNull()) continue;
- LLInventoryItem* item = gInventory.getItem(item_id);
- if(!item) continue;
- if(!msg_started)
- {
- msg_started = TRUE;
- msg->newMessage("CreateNewOutfitAttachments");
- msg->nextBlock("AgentData");
- msg->addUUID("AgentID", getID());
- msg->addUUID("SessionID", getSessionID());
- msg->nextBlock("HeaderData");
- msg->addUUID("NewFolderID", folder_id);
- }
- msg->nextBlock("ObjectData");
- msg->addUUID("OldItemID", item_id);
- msg->addUUID("OldFolderID", item->getParentUUID());
- }
-
- if( msg_started )
- {
- sendReliableMessage();
- }
-
- }
-}
-
-void LLAgent::makeNewOutfitDone(S32 index)
-{
- LLUUID first_item_id = mWearableEntry[index].mItemID;
- // Open the inventory and select the first item we added.
- if( first_item_id.notNull() )
- {
- LLInventoryView* view = LLInventoryView::getActiveInventory();
- if(view)
- {
- view->getPanel()->setSelection(first_item_id, TAKE_FOCUS_NO);
- }
- }
-}
-
-
-void LLAgent::addWearableToAgentInventory(
- LLPointer<LLInventoryCallback> cb,
- LLWearable* wearable,
- const LLUUID& category_id,
- BOOL notify)
-{
- create_inventory_item(
- gAgent.getID(),
- gAgent.getSessionID(),
- category_id,
- wearable->getTransactionID(),
- wearable->getName(),
- wearable->getDescription(),
- wearable->getAssetType(),
- LLInventoryType::IT_WEARABLE,
- wearable->getType(),
- wearable->getPermissions().getMaskNextOwner(),
- cb);
-}
-
//-----------------------------------------------------------------------------
// sendAgentSetAppearance()
//-----------------------------------------------------------------------------
@@ -7182,7 +6300,7 @@ void LLAgent::sendAgentSetAppearance()
{
if (mAvatarObject.isNull()) return;
- if (mNumPendingQueries > 0 && !gAgent.cameraCustomizeAvatar())
+ if (gAgentQueryManager.mNumPendingQueries > 0 && !gAgent.cameraCustomizeAvatar())
{
return;
}
@@ -7212,11 +6330,11 @@ void LLAgent::sendAgentSetAppearance()
// is texture data current relative to wearables?
// KLW - TAT this will probably need to check the local queue.
- BOOL textures_current = !mAvatarObject->hasPendingBakedUploads() && mWearablesLoaded;
+ BOOL textures_current = mAvatarObject->areTexturesCurrent();
for(U8 baked_index = 0; baked_index < BAKED_NUM_INDICES; baked_index++ )
{
- const ETextureIndex texture_index = getTextureIndex((EBakedTextureIndex)baked_index);
+ const ETextureIndex texture_index = LLVOAvatarDictionary::bakedToLocalTextureIndex((EBakedTextureIndex)baked_index);
// if we're not wearing a skirt, we don't need the texture to be baked
if (texture_index == TEX_SKIRT_BAKED && !mAvatarObject->isWearingWearableType(WT_SKIRT))
@@ -7238,24 +6356,25 @@ void LLAgent::sendAgentSetAppearance()
llinfos << "TAT: Sending cached texture data" << llendl;
for (U8 baked_index = 0; baked_index < BAKED_NUM_INDICES; baked_index++)
{
- const LLVOAvatarDictionary::WearableDictionaryEntry *wearable_dict = LLVOAvatarDictionary::getInstance()->getWearable((EBakedTextureIndex)baked_index);
+ const LLVOAvatarDictionary::BakedEntry *baked_dict = LLVOAvatarDictionary::getInstance()->getBakedTexture((EBakedTextureIndex)baked_index);
LLUUID hash;
- for (U8 i=0; i < wearable_dict->mWearablesVec.size(); i++)
+ for (U8 i=0; i < baked_dict->mWearables.size(); i++)
{
// EWearableType wearable_type = gBakedWearableMap[baked_index][wearable_num];
- const EWearableType wearable_type = wearable_dict->mWearablesVec[i];
- const LLWearable* wearable = getWearable(wearable_type);
+ const EWearableType wearable_type = baked_dict->mWearables[i];
+ // MULTI-WEARABLE: fixed to 0th - extend to everything once messaging works.
+ const LLWearable* wearable = gAgentWearables.getWearable(wearable_type,0);
if (wearable)
{
- hash ^= wearable->getID();
+ hash ^= wearable->getAssetID();
}
}
if (hash.notNull())
{
- hash ^= wearable_dict->mHashID;
+ hash ^= baked_dict->mWearablesHashID;
}
- const ETextureIndex texture_index = getTextureIndex((EBakedTextureIndex)baked_index);
+ const ETextureIndex texture_index = LLVOAvatarDictionary::bakedToLocalTextureIndex((EBakedTextureIndex)baked_index);
msg->nextBlockFast(_PREHASH_WearableData);
msg->addUUIDFast(_PREHASH_CacheID, hash);
@@ -7299,456 +6418,20 @@ void LLAgent::sendAgentDataUpdateRequest()
{
gMessageSystem->newMessageFast(_PREHASH_AgentDataUpdateRequest);
gMessageSystem->nextBlockFast(_PREHASH_AgentData);
- gMessageSystem->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
+ gMessageSystem->addUUIDFast(_PREHASH_AgentID, gAgent.getID() );
gMessageSystem->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
sendReliableMessage();
}
-void LLAgent::removeWearable( EWearableType type )
-{
- LLWearable* old_wearable = mWearableEntry[ type ].mWearable;
-
- if ( (gAgent.isTeen())
- && (type == WT_UNDERSHIRT || type == WT_UNDERPANTS))
- {
- // Can't take off underclothing in simple UI mode or on PG accounts
- return;
- }
-
- if( old_wearable )
- {
- if( old_wearable->isDirty() )
- {
- LLSD payload;
- payload["wearable_type"] = (S32)type;
- // Bring up view-modal dialog: Save changes? Yes, No, Cancel
- LLNotifications::instance().add("WearableSave", LLSD(), payload, &LLAgent::onRemoveWearableDialog);
- return;
- }
- else
- {
- removeWearableFinal( type );
- }
- }
-}
-
-// static
-bool LLAgent::onRemoveWearableDialog(const LLSD& notification, const LLSD& response )
-{
- S32 option = LLNotification::getSelectedOption(notification, response);
- EWearableType type = (EWearableType)notification["payload"]["wearable_type"].asInteger();
- switch( option )
- {
- case 0: // "Save"
- gAgent.saveWearable( type );
- gAgent.removeWearableFinal( type );
- break;
-
- case 1: // "Don't Save"
- gAgent.removeWearableFinal( type );
- break;
-
- case 2: // "Cancel"
- break;
-
- default:
- llassert(0);
- break;
- }
- return false;
-}
-
-// Called by removeWearable() and onRemoveWearableDialog() to actually do the removal.
-void LLAgent::removeWearableFinal( EWearableType type )
-{
- LLWearable* old_wearable = mWearableEntry[ type ].mWearable;
-
- gInventory.addChangedMask( LLInventoryObserver::LABEL, mWearableEntry[type].mItemID );
-
- mWearableEntry[ type ].mWearable = NULL;
- mWearableEntry[ type ].mItemID.setNull();
-
- queryWearableCache();
-
- if( old_wearable )
- {
- old_wearable->removeFromAvatar( TRUE );
- }
-
- // Update the server
- sendAgentWearablesUpdate();
- sendAgentSetAppearance();
- gInventory.notifyObservers();
-}
-
-void LLAgent::copyWearableToInventory( EWearableType type )
-{
- LLWearable* wearable = mWearableEntry[ type ].mWearable;
- if( wearable )
- {
- // Save the old wearable if it has changed.
- if( wearable->isDirty() )
- {
- wearable = gWearableList.createCopyFromAvatar( wearable );
- mWearableEntry[ type ].mWearable = wearable;
- }
-
- // Make a new entry in the inventory. (Put it in the same folder as the original item if possible.)
- LLUUID category_id;
- LLInventoryItem* item = gInventory.getItem( mWearableEntry[ type ].mItemID );
- if( item )
- {
- category_id = item->getParentUUID();
- wearable->setPermissions(item->getPermissions());
- }
- LLPointer<LLInventoryCallback> cb =
- new addWearableToAgentInventoryCallback(
- LLPointer<LLRefCount>(NULL),
- type,
- wearable);
- addWearableToAgentInventory(cb, wearable, category_id);
- }
-}
-
-
-// A little struct to let setWearable() communicate more than one value with onSetWearableDialog().
-struct LLSetWearableData
-{
- LLSetWearableData( const LLUUID& new_item_id, LLWearable* new_wearable ) :
- mNewItemID( new_item_id ), mNewWearable( new_wearable ) {}
- LLUUID mNewItemID;
- LLWearable* mNewWearable;
-};
-
-BOOL LLAgent::needsReplacement(EWearableType wearableType, S32 remove)
-{
- return TRUE;
- /*if (remove) return TRUE;
-
- return getWearable(wearableType) ? TRUE : FALSE;*/
-}
-
-// Assumes existing wearables are not dirty.
-void LLAgent::setWearableOutfit(
- const LLInventoryItem::item_array_t& items,
- const LLDynamicArray< LLWearable* >& wearables,
- BOOL remove )
-{
- lldebugs << "setWearableOutfit() start" << llendl;
-
- BOOL wearables_to_remove[WT_COUNT];
- wearables_to_remove[WT_SHAPE] = FALSE;
- wearables_to_remove[WT_SKIN] = FALSE;
- wearables_to_remove[WT_HAIR] = FALSE;
- wearables_to_remove[WT_EYES] = FALSE;
- wearables_to_remove[WT_SHIRT] = remove;
- wearables_to_remove[WT_PANTS] = remove;
- wearables_to_remove[WT_SHOES] = remove;
- wearables_to_remove[WT_SOCKS] = remove;
- wearables_to_remove[WT_JACKET] = remove;
- wearables_to_remove[WT_GLOVES] = remove;
- wearables_to_remove[WT_UNDERSHIRT] = (!gAgent.isTeen()) & remove;
- wearables_to_remove[WT_UNDERPANTS] = (!gAgent.isTeen()) & remove;
- wearables_to_remove[WT_SKIRT] = remove;
-
- S32 count = wearables.count();
- llassert( items.count() == count );
-
- S32 i;
- for( i = 0; i < count; i++ )
- {
- LLWearable* new_wearable = wearables[i];
- LLPointer<LLInventoryItem> new_item = items[i];
-
- EWearableType type = new_wearable->getType();
- wearables_to_remove[type] = FALSE;
-
- LLWearable* old_wearable = mWearableEntry[ type ].mWearable;
- if( old_wearable )
- {
- const LLUUID& old_item_id = mWearableEntry[ type ].mItemID;
- if( (old_wearable->getID() == new_wearable->getID()) &&
- (old_item_id == new_item->getUUID()) )
- {
- lldebugs << "No change to wearable asset and item: " << LLWearable::typeToTypeName( type ) << llendl;
- continue;
- }
-
- gInventory.addChangedMask(LLInventoryObserver::LABEL, old_item_id);
-
- // Assumes existing wearables are not dirty.
- if( old_wearable->isDirty() )
- {
- llassert(0);
- continue;
- }
- }
-
- mWearableEntry[ type ].mItemID = new_item->getUUID();
- mWearableEntry[ type ].mWearable = new_wearable;
- }
-
- std::vector<LLWearable*> wearables_being_removed;
-
- for( i = 0; i < WT_COUNT; i++ )
- {
- if( wearables_to_remove[i] )
- {
- wearables_being_removed.push_back(mWearableEntry[ i ].mWearable);
- mWearableEntry[ i ].mWearable = NULL;
-
- gInventory.addChangedMask(LLInventoryObserver::LABEL, mWearableEntry[ i ].mItemID);
- mWearableEntry[ i ].mItemID.setNull();
- }
- }
-
- gInventory.notifyObservers();
-
- queryWearableCache();
-
- std::vector<LLWearable*>::iterator wearable_iter;
-
- for( wearable_iter = wearables_being_removed.begin();
- wearable_iter != wearables_being_removed.end();
- ++wearable_iter)
- {
- LLWearable* wearablep = *wearable_iter;
- if (wearablep)
- {
- wearablep->removeFromAvatar( TRUE );
- }
- }
-
- for( i = 0; i < count; i++ )
- {
- wearables[i]->writeToAvatar( TRUE );
- }
-
- // Start rendering & update the server
- mWearablesLoaded = TRUE;
- sendAgentWearablesUpdate();
- sendAgentSetAppearance();
-
- lldebugs << "setWearableOutfit() end" << llendl;
-}
-
-
-// User has picked "wear on avatar" from a menu.
-void LLAgent::setWearable( LLInventoryItem* new_item, LLWearable* new_wearable )
+void LLAgent::sendAgentUserInfoRequest()
{
- EWearableType type = new_wearable->getType();
-
- LLWearable* old_wearable = mWearableEntry[ type ].mWearable;
- if( old_wearable )
- {
- const LLUUID& old_item_id = mWearableEntry[ type ].mItemID;
- if( (old_wearable->getID() == new_wearable->getID()) &&
- (old_item_id == new_item->getUUID()) )
- {
- lldebugs << "No change to wearable asset and item: " << LLWearable::typeToTypeName( type ) << llendl;
- return;
- }
-
- if( old_wearable->isDirty() )
- {
- // Bring up modal dialog: Save changes? Yes, No, Cancel
- LLSD payload;
- payload["item_id"] = new_item->getUUID();
- LLNotifications::instance().add( "WearableSave", LLSD(), payload, boost::bind(LLAgent::onSetWearableDialog, _1, _2, new_wearable));
- return;
- }
- }
-
- setWearableFinal( new_item, new_wearable );
-}
-
-// static
-bool LLAgent::onSetWearableDialog( const LLSD& notification, const LLSD& response, LLWearable* wearable )
-{
- S32 option = LLNotification::getSelectedOption(notification, response);
- LLInventoryItem* new_item = gInventory.getItem( notification["payload"]["item_id"].asUUID());
- if( !new_item )
- {
- delete wearable;
- return false;
- }
-
- switch( option )
- {
- case 0: // "Save"
- gAgent.saveWearable( wearable->getType() );
- gAgent.setWearableFinal( new_item, wearable );
- break;
-
- case 1: // "Don't Save"
- gAgent.setWearableFinal( new_item, wearable );
- break;
-
- case 2: // "Cancel"
- break;
-
- default:
- llassert(0);
- break;
- }
-
- delete wearable;
- return false;
-}
-
-// Called from setWearable() and onSetWearableDialog() to actually set the wearable.
-void LLAgent::setWearableFinal( LLInventoryItem* new_item, LLWearable* new_wearable )
-{
- EWearableType type = new_wearable->getType();
-
- // Replace the old wearable with a new one.
- llassert( new_item->getAssetUUID() == new_wearable->getID() );
- LLUUID old_item_id = mWearableEntry[ type ].mItemID;
- mWearableEntry[ type ].mItemID = new_item->getUUID();
- mWearableEntry[ type ].mWearable = new_wearable;
-
- if (old_item_id.notNull())
- {
- gInventory.addChangedMask( LLInventoryObserver::LABEL, old_item_id );
- gInventory.notifyObservers();
- }
-
- //llinfos << "LLVOAvatar::setWearable()" << llendl;
- queryWearableCache();
- new_wearable->writeToAvatar( TRUE );
-
- // Update the server
- sendAgentWearablesUpdate();
- sendAgentSetAppearance();
-}
-
-void LLAgent::queryWearableCache()
-{
- if (!mWearablesLoaded)
- {
- return;
- }
-
- // Look up affected baked textures.
- // If they exist:
- // disallow updates for affected layersets (until dataserver responds with cache request.)
- // If cache miss, turn updates back on and invalidate composite.
- // If cache hit, modify baked texture entries.
- //
- // Cache requests contain list of hashes for each baked texture entry.
- // Response is list of valid baked texture assets. (same message)
-
- gMessageSystem->newMessageFast(_PREHASH_AgentCachedTexture);
+ if(getID().isNull())
+ return; // not logged in
+ gMessageSystem->newMessageFast(_PREHASH_UserInfoRequest);
gMessageSystem->nextBlockFast(_PREHASH_AgentData);
gMessageSystem->addUUIDFast(_PREHASH_AgentID, getID());
gMessageSystem->addUUIDFast(_PREHASH_SessionID, getSessionID());
- gMessageSystem->addS32Fast(_PREHASH_SerialNum, mTextureCacheQueryID);
-
- S32 num_queries = 0;
- for (U8 baked_index = 0; baked_index < BAKED_NUM_INDICES; baked_index++ )
- {
- const LLVOAvatarDictionary::WearableDictionaryEntry *wearable_dict = LLVOAvatarDictionary::getInstance()->getWearable((EBakedTextureIndex)baked_index);
- LLUUID hash;
- for (U8 i=0; i < wearable_dict->mWearablesVec.size(); i++)
- {
- // EWearableType wearable_type = gBakedWearableMap[baked_index][wearable_num];
- const EWearableType wearable_type = wearable_dict->mWearablesVec[i];
- const LLWearable* wearable = getWearable(wearable_type);
- if (wearable)
- {
- hash ^= wearable->getID();
- }
- }
- if (hash.notNull())
- {
- hash ^= wearable_dict->mHashID;
- num_queries++;
- // *NOTE: make sure at least one request gets packed
-
- //llinfos << "Requesting texture for hash " << hash << " in baked texture slot " << baked_index << llendl;
- gMessageSystem->nextBlockFast(_PREHASH_WearableData);
- gMessageSystem->addUUIDFast(_PREHASH_ID, hash);
- gMessageSystem->addU8Fast(_PREHASH_TextureIndex, (U8)baked_index);
- }
-
- mActiveCacheQueries[ baked_index ] = mTextureCacheQueryID;
- }
-
- llinfos << "Requesting texture cache entry for " << num_queries << " baked textures" << llendl;
- gMessageSystem->sendReliable(getRegion()->getHost());
- mNumPendingQueries++;
- mTextureCacheQueryID++;
-}
-
-// User has picked "remove from avatar" from a menu.
-// static
-void LLAgent::userRemoveWearable( void* userdata )
-{
- EWearableType type = (EWearableType)(intptr_t)userdata;
-
- if( !(type==WT_SHAPE || type==WT_SKIN || type==WT_HAIR ) ) //&&
- //!((!gAgent.isTeen()) && ( type==WT_UNDERPANTS || type==WT_UNDERSHIRT )) )
- {
- gAgent.removeWearable( type );
- }
-}
-
-void LLAgent::userRemoveAllClothes( void* userdata )
-{
- // We have to do this up front to avoid having to deal with the case of multiple wearables being dirty.
- if( gFloaterCustomize )
- {
- gFloaterCustomize->askToSaveIfDirty( LLAgent::userRemoveAllClothesStep2, NULL );
- }
- else
- {
- LLAgent::userRemoveAllClothesStep2( TRUE, NULL );
- }
-}
-
-void LLAgent::userRemoveAllClothesStep2( BOOL proceed, void* userdata )
-{
- if( proceed )
- {
- gAgent.removeWearable( WT_SHIRT );
- gAgent.removeWearable( WT_PANTS );
- gAgent.removeWearable( WT_SHOES );
- gAgent.removeWearable( WT_SOCKS );
- gAgent.removeWearable( WT_JACKET );
- gAgent.removeWearable( WT_GLOVES );
- gAgent.removeWearable( WT_UNDERSHIRT );
- gAgent.removeWearable( WT_UNDERPANTS );
- gAgent.removeWearable( WT_SKIRT );
- }
-}
-
-void LLAgent::userRemoveAllAttachments( void* userdata )
-{
- LLVOAvatar* avatarp = gAgent.getAvatarObject();
- if(!avatarp)
- {
- llwarns << "No avatar found." << llendl;
- return;
- }
-
- gMessageSystem->newMessage("ObjectDetach");
- gMessageSystem->nextBlockFast(_PREHASH_AgentData);
- gMessageSystem->addUUIDFast(_PREHASH_AgentID, gAgent.getID() );
- gMessageSystem->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
-
- for (LLVOAvatar::attachment_map_t::iterator iter = avatarp->mAttachmentPoints.begin();
- iter != avatarp->mAttachmentPoints.end(); )
- {
- LLVOAvatar::attachment_map_t::iterator curiter = iter++;
- LLViewerJointAttachment* attachment = curiter->second;
- LLViewerObject* objectp = attachment->getObject();
- if (objectp)
- {
- gMessageSystem->nextBlockFast(_PREHASH_ObjectData);
- gMessageSystem->addU32Fast(_PREHASH_ObjectLocalID, objectp->getLocalID());
- }
- }
- gMessageSystem->sendReliable( gAgent.getRegionHost() );
+ sendReliableMessage();
}
void LLAgent::observeFriends()
@@ -7813,4 +6496,44 @@ void LLAgent::parseTeleportMessages(const std::string& xml_filename)
}//end for (all message sets in xml file)
}
+void LLAgent::sendAgentUpdateUserInfo(bool im_via_email, const std::string& directory_visibility )
+{
+ gMessageSystem->newMessageFast(_PREHASH_UpdateUserInfo);
+ gMessageSystem->nextBlockFast(_PREHASH_AgentData);
+ gMessageSystem->addUUIDFast(_PREHASH_AgentID, getID());
+ gMessageSystem->addUUIDFast(_PREHASH_SessionID, getSessionID());
+ gMessageSystem->nextBlockFast(_PREHASH_UserData);
+ gMessageSystem->addBOOLFast(_PREHASH_IMViaEMail, im_via_email);
+ gMessageSystem->addString("DirectoryVisibility", directory_visibility);
+ gAgent.sendReliableMessage();
+}
+
+// static
+void LLAgent::dumpGroupInfo()
+{
+ llinfos << "group " << gAgent.mGroupName << llendl;
+ llinfos << "ID " << gAgent.mGroupID << llendl;
+ llinfos << "powers " << gAgent.mGroupPowers << llendl;
+ llinfos << "title " << gAgent.mGroupTitle << llendl;
+ //llinfos << "insig " << gAgent.mGroupInsigniaID << llendl;
+}
+
+/********************************************************************************/
+LLAgentQueryManager gAgentQueryManager;
+
+LLAgentQueryManager::LLAgentQueryManager() :
+ mWearablesCacheQueryID(0),
+ mNumPendingQueries(0),
+ mUpdateSerialNum(0)
+{
+ for (U32 i = 0; i < BAKED_NUM_INDICES; i++)
+ {
+ mActiveCacheQueries[i] = 0;
+ }
+}
+
+LLAgentQueryManager::~LLAgentQueryManager()
+{
+}
+
// EOF
diff --git a/indra/newview/llagent.h b/indra/newview/llagent.h
index 27fcb07fd5..5ca630f8d1 100644
--- a/indra/newview/llagent.h
+++ b/indra/newview/llagent.h
@@ -33,63 +33,26 @@
#ifndef LL_LLAGENT_H
#define LL_LLAGENT_H
-#include <set>
-
#include "indra_constants.h"
-#include "llmath.h"
-#include "llcontrol.h"
-#include "llcoordframe.h"
-#include "llevent.h"
+#include "llevent.h" // LLObservable base class
+#include "llagentaccess.h"
#include "llagentaccess.h"
#include "llagentconstants.h"
-#include "llanimationstates.h"
-#include "lldbstrings.h"
-#include "llhudeffectlookat.h"
-#include "llhudeffectpointat.h"
-#include "llmemory.h"
-#include "llstring.h"
-#include "lluuid.h"
-#include "m3math.h"
-#include "m4math.h"
-#include "llquaternion.h"
-#include "lltimer.h"
-#include "v3dmath.h"
-#include "v3math.h"
-#include "v4color.h"
-#include "v4math.h"
-//#include "vmath.h"
-#include "stdenums.h"
-#include "llwearable.h"
-#include "llcharacter.h"
-#include "llinventory.h"
-#include "llviewerinventory.h"
-#include "llagentdata.h"
-
-// Ventrella
-#include "llfollowcam.h"
-// end Ventrella
-
-const U8 AGENT_STATE_TYPING = 0x04; // Typing indication
-const U8 AGENT_STATE_EDITING = 0x10; // Set when agent has objects selected
-
-const BOOL ANIMATE = TRUE;
-
-typedef enum e_camera_modes
-{
- CAMERA_MODE_THIRD_PERSON,
- CAMERA_MODE_MOUSELOOK,
- CAMERA_MODE_CUSTOMIZE_AVATAR,
- CAMERA_MODE_FOLLOW
-} ECameraMode;
-
-typedef enum e_anim_request
-{
- ANIM_REQUEST_START,
- ANIM_REQUEST_STOP
-} EAnimRequest;
+#include "llhudeffectpointat.h" // ELookAtType
+#include "llhudeffectlookat.h" // EPointAtType
+#include "llpointer.h"
+#include "llcharacter.h" // LLAnimPauseRequest
+#include "llfollowcam.h" // Ventrella
+#include "llagentdata.h" // gAgentID, gAgentSessionID
+#include "lluicolor.h"
+#include "llvoavatardefines.h"
+
+extern const BOOL ANIMATE;
+extern const U8 AGENT_STATE_TYPING; // Typing indication
+extern const U8 AGENT_STATE_EDITING; // Set when agent has objects selected
class LLChat;
-class LLVOAvatar;
+class LLVOAvatarSelf;
class LLViewerRegion;
class LLMotion;
class LLToolset;
@@ -98,6 +61,38 @@ class LLPermissions;
class LLHost;
class LLFriendObserver;
class LLPickInfo;
+class LLViewerObject;
+class LLAgentDropGroupViewerNode;
+
+//--------------------------------------------------------------------
+// Types
+//--------------------------------------------------------------------
+enum ECameraMode
+{
+ CAMERA_MODE_THIRD_PERSON,
+ CAMERA_MODE_MOUSELOOK,
+ CAMERA_MODE_CUSTOMIZE_AVATAR,
+ CAMERA_MODE_FOLLOW
+};
+
+/** Camera Presets for CAMERA_MODE_THIRD_PERSON */
+enum ECameraPreset
+{
+ /** Default preset, what the Third Person Mode actually was */
+ CAMERA_PRESET_REAR_VIEW,
+
+ /** "Looking at the Avatar from the front" */
+ CAMERA_PRESET_FRONT_VIEW,
+
+ /** "Above and to the left, over the shoulder, pulled back a little on the zoom" */
+ CAMERA_PRESET_GROUP_VIEW
+};
+
+enum EAnimRequest
+{
+ ANIM_REQUEST_START,
+ ANIM_REQUEST_STOP
+};
struct LLGroupData
{
@@ -110,331 +105,381 @@ struct LLGroupData
std::string mName;
};
-inline bool operator==(const LLGroupData &a, const LLGroupData &b)
-{
- return (a.mID == b.mID);
-}
-
-// forward declarations
-
-//
-
+//------------------------------------------------------------------------
+// LLAgent
+//------------------------------------------------------------------------
class LLAgent : public LLOldEvents::LLObservable
{
LOG_CLASS(LLAgent);
-
+
public:
- // When the agent hasn't typed anything for this duration, it leaves the
- // typing state (for both chat and IM).
- static const F32 TYPING_TIMEOUT_SECS;
+ friend class LLAgentDropGroupViewerNode;
- LLAgent();
- ~LLAgent();
+/********************************************************************************
+ ** **
+ ** INITIALIZATION
+ **/
+ //--------------------------------------------------------------------
+ // Constructors / Destructors
+ //--------------------------------------------------------------------
+public:
+ LLAgent();
+ virtual ~LLAgent();
void init();
void cleanup();
+ void setAvatarObject(LLVOAvatarSelf *avatar);
- //
- // MANIPULATORS
- //
- // TODO: Put all non-const functions here.
-
- // Called whenever the agent moves. Puts camera back in default position,
- // deselects items, etc.
- void resetView(BOOL reset_camera = TRUE, BOOL change_camera = FALSE);
-
- // Called on camera movement, to allow the camera to be unlocked from the
- // default position behind the avatar.
- void unlockView();
-
- void onAppFocusGained();
-
- void sendMessage(); // Send message to this agent's region.
- void sendReliableMessage();
-
- LLVector3d calcCameraPositionTargetGlobal(BOOL *hit_limit = NULL); // Calculate the camera position target
- LLVector3d calcFocusPositionTargetGlobal();
- LLVector3d calcThirdPersonFocusOffset();
- // target for this mode
- LLVector3d getCameraPositionGlobal() const;
- const LLVector3 &getCameraPositionAgent() const;
- F32 calcCameraFOVZoomFactor();
- F32 getCameraMinOffGround(); // minimum height off ground for this mode, meters
- void endAnimationUpdateUI();
- void setKey(const S32 direction, S32 &key); // sets key to +1 for +direction, -1 for -direction
- void handleScrollWheel(S32 clicks); // mousewheel driven zoom
-
- void setAvatarObject(LLVOAvatar *avatar);
-
- // rendering state bitmask helpers
- void startTyping();
- void stopTyping();
- void setRenderState(U8 newstate);
- void clearRenderState(U8 clearstate);
- U8 getRenderState();
-
- // Set the home data
- void setRegion(LLViewerRegion *regionp);
- LLViewerRegion *getRegion() const;
- LLHost getRegionHost() const;
- std::string getSLURL() const;
-
- void updateAgentPosition(const F32 dt, const F32 yaw, const S32 mouse_x, const S32 mouse_y); // call once per frame to update position, angles radians
- void updateLookAt(const S32 mouse_x, const S32 mouse_y);
-
-
- void updateCamera(); // call once per frame to update camera location/orientation
- void resetCamera(); // slam camera into its default position
- void setupSitCamera();
- void setCameraCollidePlane(const LLVector4 &plane) { mCameraCollidePlane = plane; }
-
- void changeCameraToDefault();
- void changeCameraToMouselook(BOOL animate = TRUE);
- void changeCameraToThirdPerson(BOOL animate = TRUE);
- void changeCameraToCustomizeAvatar(BOOL avatar_animate = TRUE, BOOL camera_animate = TRUE); // trigger transition animation
- // Ventrella
- void changeCameraToFollow(BOOL animate = TRUE);
- //end Ventrella
-
- void setFocusGlobal(const LLPickInfo& pick);
- void setFocusGlobal(const LLVector3d &focus, const LLUUID &object_id = LLUUID::null);
- void setFocusOnAvatar(BOOL focus, BOOL animate);
- void setCameraPosAndFocusGlobal(const LLVector3d& pos, const LLVector3d& focus, const LLUUID &object_id);
- void setSitCamera(const LLUUID &object_id, const LLVector3 &camera_pos = LLVector3::zero, const LLVector3 &camera_focus = LLVector3::zero);
- void clearFocusObject();
- void setFocusObject(LLViewerObject* object);
- void setObjectTracking(BOOL track) { mTrackFocusObject = track; }
-// void setLookingAtAvatar(BOOL looking);
-
- void heardChat(const LLUUID& id);
- void lookAtLastChat();
- F32 getTypingTime() { return mTypingTimer.getElapsedTimeF32(); }
-
- void setAFK();
- void clearAFK();
- BOOL getAFK() const;
-
- void setAlwaysRun() { mbAlwaysRun = true; }
- void clearAlwaysRun() { mbAlwaysRun = false; }
-
- void setRunning() { mbRunning = true; }
- void clearRunning() { mbRunning = false; }
-
- void setBusy();
- void clearBusy();
- BOOL getBusy() const;
-
- void setAdminOverride(BOOL b);
- void setGodLevel(U8 god_level);
- void setFirstLogin(BOOL b) { mFirstLogin = b; }
- void setGenderChosen(BOOL b) { mGenderChosen = b; }
-
- // update internal datastructures and update the server with the
- // new contribution level. Returns true if the group id was found
- // and contribution could be set.
- BOOL setGroupContribution(const LLUUID& group_id, S32 contribution);
- BOOL setUserGroupFlags(const LLUUID& group_id, BOOL accept_notices, BOOL list_in_profile);
- void setHideGroupTitle(BOOL hide) { mHideGroupTitle = hide; }
-
- //
- // ACCESSORS
- //
- // TODO: Put all read functions here, make them const
+ //--------------------------------------------------------------------
+ // Login
+ //--------------------------------------------------------------------
+public:
+ void onAppFocusGained();
+ void setFirstLogin(BOOL b) { mFirstLogin = b; }
+ // Return TRUE if the database reported this login as the first for this particular user.
+ BOOL isFirstLogin() const { return mFirstLogin; }
+public:
+ BOOL mInitialized;
+ BOOL mFirstLogin;
+ std::string mMOTD; // Message of the day
+ //--------------------------------------------------------------------
+ // Session
+ //--------------------------------------------------------------------
+public:
const LLUUID& getID() const { return gAgentID; }
const LLUUID& getSessionID() const { return gAgentSessionID; }
-
+ // Note: NEVER send this value in the clear or over any weakly
+ // encrypted channel (such as simple XOR masking). If you are unsure
+ // ask Aaron or MarkL.
const LLUUID& getSecureSessionID() const { return mSecureSessionID; }
- // Note: NEVER send this value in the clear or over any weakly
- // encrypted channel (such as simple XOR masking). If you are unsure
- // ask Aaron or MarkL.
-
- BOOL isGodlike() const;
- U8 getGodLevel() const;
- // note: this is a prime candidate for pulling out into a Maturity class
- // rather than just expose the preference setting, we're going to actually
- // expose what the client code cares about -- what the user should see
- // based on a combination of the is* and prefers* flags, combined with God bit.
- bool wantsPGOnly() const;
- bool canAccessMature() const;
- bool canAccessAdult() const;
- bool canAccessMaturityInRegion( U64 region_handle ) const;
- bool canAccessMaturityAtGlobal( LLVector3d pos_global ) const;
- bool prefersPG() const;
- bool prefersMature() const;
- bool prefersAdult() const;
- bool isTeen() const;
- bool isMature() const;
- bool isAdult() const;
- void setTeen(bool teen);
- void setMaturity(char text);
- static int convertTextToMaturity(char text);
- bool sendMaturityPreferenceToServer(int preferredMaturity);
-
- const LLAgentAccess& getAgentAccess();
-
- // This function can go away after the AO transition (see llstartup.cpp)
- void setAOTransition();
+public:
+ LLUUID mSecureSessionID; // Secure token for this login session
- BOOL isGroupTitleHidden() const { return mHideGroupTitle; }
- BOOL isGroupMember() const { return !mGroupID.isNull(); } // This is only used for building titles!
- const LLUUID &getGroupID() const { return mGroupID; }
- ECameraMode getCameraMode() const { return mCameraMode; }
- BOOL getFocusOnAvatar() const { return mFocusOnAvatar; }
- LLPointer<LLViewerObject>& getFocusObject() { return mFocusObject; }
- F32 getFocusObjectDist() const { return mFocusObjectDist; }
- BOOL inPrelude();
- BOOL canManageEstate() const;
- BOOL getAdminOverride() const;
+/** Initialization
+ ** **
+ *******************************************************************************/
- LLUUID getLastChatter() const { return mLastChatterID; }
- bool getAlwaysRun() const { return mbAlwaysRun; }
- bool getRunning() const { return mbRunning; }
+/********************************************************************************
+ ** **
+ ** IDENTITY
+ **/
- const LLUUID& getInventoryRootID() const { return mInventoryRootID; }
-
- void buildFullname(std::string &name) const;
+ //--------------------------------------------------------------------
+ // Name
+ //--------------------------------------------------------------------
+public:
+ //*TODO remove, is not used as of August 20, 2009
void buildFullnameAndTitle(std::string &name) const;
- // Check against all groups in the entire agent group list.
- BOOL isInGroup(const LLUUID& group_id) const;
- BOOL hasPowerInGroup(const LLUUID& group_id, U64 power) const;
- // Check for power in just the active group.
- BOOL hasPowerInActiveGroup(const U64 power) const;
- U64 getPowerInGroup(const LLUUID& group_id) const;
-
- // Get group information by group_id. if not in group, data is
- // left unchanged and method returns FALSE. otherwise, values are
- // copied and returns TRUE.
- BOOL getGroupData(const LLUUID& group_id, LLGroupData& data) const;
- // Get just the agent's contribution to the given group.
- S32 getGroupContribution(const LLUUID& group_id) const;
-
- // return TRUE if the database reported this login as the first
- // for this particular user.
- BOOL isFirstLogin() const { return mFirstLogin; }
-
+ //--------------------------------------------------------------------
+ // Gender
+ //--------------------------------------------------------------------
+public:
// On the very first login, gender isn't chosen until the user clicks
// in a dialog. We don't render the avatar until they choose.
- BOOL isGenderChosen() const { return mGenderChosen; }
-
- // utility to build a location string
- void buildLocationString(std::string& str);
-
- LLQuaternion getHeadRotation();
- LLVOAvatar *getAvatarObject() const { return mAvatarObject; }
-
- BOOL needsRenderAvatar(); // TRUE when camera mode is such that your own avatar should draw
- // Not const because timers can't be accessed in const-fashion.
- BOOL needsRenderHead();
- BOOL cameraThirdPerson() const { return (mCameraMode == CAMERA_MODE_THIRD_PERSON && mLastCameraMode == CAMERA_MODE_THIRD_PERSON); }
- BOOL cameraMouselook() const { return (mCameraMode == CAMERA_MODE_MOUSELOOK && mLastCameraMode == CAMERA_MODE_MOUSELOOK); }
- BOOL cameraCustomizeAvatar() const { return (mCameraMode == CAMERA_MODE_CUSTOMIZE_AVATAR /*&& !mCameraAnimating*/); }
- BOOL cameraFollow() const { return (mCameraMode == CAMERA_MODE_FOLLOW && mLastCameraMode == CAMERA_MODE_FOLLOW); }
+ BOOL isGenderChosen() const { return mGenderChosen; }
+ void setGenderChosen(BOOL b) { mGenderChosen = b; }
+private:
+ BOOL mGenderChosen;
- LLVector3 getPosAgentFromGlobal(const LLVector3d &pos_global) const;
- LLVector3d getPosGlobalFromAgent(const LLVector3 &pos_agent) const;
+/** Identity
+ ** **
+ *******************************************************************************/
- // Get the data members
- const LLVector3& getAtAxis() const { return mFrameAgent.getAtAxis(); } // direction avatar is looking, not camera
- const LLVector3& getUpAxis() const { return mFrameAgent.getUpAxis(); } // direction avatar is looking, not camera
- const LLVector3& getLeftAxis() const { return mFrameAgent.getLeftAxis(); } // direction avatar is looking, not camera
+/********************************************************************************
+ ** **
+ ** GENERAL ACCESSORS
+ **/
- LLCoordFrame getFrameAgent() const { return mFrameAgent; }
- LLVector3 getVelocity() const;
- F32 getVelocityZ() const { return getVelocity().mV[VZ]; } // a hack
+public:
+ LLVOAvatarSelf* getAvatarObject() const { return mAvatarObject; }
+private:
+ LLPointer<LLVOAvatarSelf> mAvatarObject; // NULL until avatar object sent down from simulator
- const LLVector3d &getPositionGlobal() const;
- const LLVector3 &getPositionAgent();
- S32 getRegionsVisited() const;
- F64 getDistanceTraveled() const;
+/** General Accessors
+ ** **
+ *******************************************************************************/
- const LLVector3d &getFocusGlobal() const { return mFocusGlobal; }
- const LLVector3d &getFocusTargetGlobal() const { return mFocusTargetGlobal; }
+/********************************************************************************
+ ** **
+ ** POSITION
+ **/
- BOOL getJump() const { return mbJump; }
- BOOL getAutoPilot() const { return mAutoPilot; }
- LLVector3d getAutoPilotTargetGlobal() const { return mAutoPilotTargetGlobal; }
+ //--------------------------------------------------------------------
+ // Position
+ //--------------------------------------------------------------------
+public:
+ LLVector3 getPosAgentFromGlobal(const LLVector3d &pos_global) const;
+ LLVector3d getPosGlobalFromAgent(const LLVector3 &pos_agent) const;
+ const LLVector3d &getPositionGlobal() const;
+ const LLVector3 &getPositionAgent();
+ // Call once per frame to update position, angles (radians).
+ void updateAgentPosition(const F32 dt, const F32 yaw, const S32 mouse_x, const S32 mouse_y);
+ void setPositionAgent(const LLVector3 &center);
+protected:
+ void propagate(const F32 dt); // ! BUG ! Should roll into updateAgentPosition
+private:
+ mutable LLVector3d mPositionGlobal;
- LLQuaternion getQuat() const; // returns the quat that represents the rotation
- // of the agent in the absolute frame
-// BOOL getLookingAtAvatar() const;
+ //--------------------------------------------------------------------
+ // Velocity
+ //--------------------------------------------------------------------
+public:
+ LLVector3 getVelocity() const;
+ F32 getVelocityZ() const { return getVelocity().mV[VZ]; } // ! HACK !
+
+ //--------------------------------------------------------------------
+ // Coordinate System
+ //--------------------------------------------------------------------
+public:
+ LLCoordFrame getFrameAgent() const { return mFrameAgent; }
+ void initOriginGlobal(const LLVector3d &origin_global); // Only to be used in ONE place
+ void resetAxes();
+ void resetAxes(const LLVector3 &look_at); // Makes reasonable left and up
+ // The following three get*Axis functions return direction avatar is looking, not camera.
+ const LLVector3& getAtAxis() const { return mFrameAgent.getAtAxis(); }
+ const LLVector3& getUpAxis() const { return mFrameAgent.getUpAxis(); }
+ const LLVector3& getLeftAxis() const { return mFrameAgent.getLeftAxis(); }
+ LLQuaternion getQuat() const; // Returns the quat that represents the rotation of the agent in the absolute frame
+private:
+ LLVector3d mAgentOriginGlobal; // Origin of agent coords from global coords
+ LLCoordFrame mFrameAgent; // Agent position and view, agent-region coordinates
- void getName(std::string& name);
- const LLColor4 &getEffectColor();
- void setEffectColor(const LLColor4 &color);
- //
- // UTILITIES
- //
+ //--------------------------------------------------------------------
+ // Home
+ //--------------------------------------------------------------------
+public:
+ void setStartPosition(U32 location_id); // Marks current location as start, sends information to servers
+ void setHomePosRegion(const U64& region_handle, const LLVector3& pos_region);
+ BOOL getHomePosGlobal(LLVector3d* pos_global);
+private:
+ BOOL mHaveHomePosition;
+ U64 mHomeRegionHandle;
+ LLVector3 mHomePosRegion;
- // Set the physics data
- void slamLookAt(const LLVector3 &look_at);
+ //--------------------------------------------------------------------
+ // Region
+ //--------------------------------------------------------------------
+public:
+ void setRegion(LLViewerRegion *regionp);
+ LLViewerRegion *getRegion() const;
+ LLHost getRegionHost() const;
+ BOOL inPrelude();
+private:
+ LLViewerRegion *mRegionp;
- void setPositionAgent(const LLVector3 &center);
+ //--------------------------------------------------------------------
+ // History
+ //--------------------------------------------------------------------
+public:
+ S32 getRegionsVisited() const;
+ F64 getDistanceTraveled() const;
+private:
+ std::set<U64> mRegionsVisited; // Stat - what distinct regions has the avatar been to?
+ F64 mDistanceTraveled; // Stat - how far has the avatar moved?
+ LLVector3d mLastPositionGlobal; // Used to calculate travel distance
+
+/** Position
+ ** **
+ *******************************************************************************/
- void resetAxes();
- void resetAxes(const LLVector3 &look_at); // makes reasonable left and up
+/********************************************************************************
+ ** **
+ ** ACTIONS
+ **/
- // Move the avatar's frame
- void rotate(F32 angle, const LLVector3 &axis);
- void rotate(F32 angle, F32 x, F32 y, F32 z);
- void rotate(const LLMatrix3 &matrix);
- void rotate(const LLQuaternion &quaternion);
- void pitch(F32 angle);
- void roll(F32 angle);
- void yaw(F32 angle);
- LLVector3 getReferenceUpVector();
- F32 clampPitchToLimits(F32 angle);
+ //--------------------------------------------------------------------
+ // Fidget
+ //--------------------------------------------------------------------
+ // Trigger random fidget animations
+public:
+ void fidget();
+ static void stopFidget();
+private:
+ LLFrameTimer mFidgetTimer;
+ LLFrameTimer mFocusObjectFadeTimer;
+ F32 mNextFidgetTime;
+ S32 mCurrentFidget;
- void setThirdPersonHeadOffset(LLVector3 offset) { mThirdPersonHeadOffset = offset; }
- // Flight management
- BOOL getFlying() const { return mControlFlags & AGENT_CONTROL_FLY; }
+ //--------------------------------------------------------------------
+ // Fly
+ //--------------------------------------------------------------------
+public:
+ BOOL getFlying() const { return mControlFlags & AGENT_CONTROL_FLY; }
void setFlying(BOOL fly);
- void toggleFlying();
-
- // Does this parcel allow you to fly?
- BOOL canFly();
-
- // Animation functions
- void stopCurrentAnimations();
- void requestStopMotion( LLMotion* motion );
- void onAnimStop(const LLUUID& id);
+ static void toggleFlying();
+ static bool enableFlying();
+ BOOL canFly(); // Does this parcel allow you to fly?
+
+ //--------------------------------------------------------------------
+ // Chat
+ //--------------------------------------------------------------------
+public:
+ void heardChat(const LLUUID& id);
+ void lookAtLastChat();
+ F32 getTypingTime() { return mTypingTimer.getElapsedTimeF32(); }
+ LLUUID getLastChatter() const { return mLastChatterID; }
+ F32 getNearChatRadius() { return mNearChatRadius; }
+protected:
+ void ageChat(); // Helper function to prematurely age chat when agent is moving
+private:
+ LLFrameTimer mChatTimer;
+ LLUUID mLastChatterID;
+ F32 mNearChatRadius;
+
+ //--------------------------------------------------------------------
+ // Typing
+ //--------------------------------------------------------------------
+public:
+ void startTyping();
+ void stopTyping();
+public:
+ // When the agent hasn't typed anything for this duration, it leaves the
+ // typing state (for both chat and IM).
+ static const F32 TYPING_TIMEOUT_SECS;
+private:
+ LLFrameTimer mTypingTimer;
- void sendAnimationRequests(LLDynamicArray<LLUUID> &anim_ids, EAnimRequest request);
- void sendAnimationRequest(const LLUUID &anim_id, EAnimRequest request);
+ //--------------------------------------------------------------------
+ // AFK
+ //--------------------------------------------------------------------
+public:
+ void setAFK();
+ void clearAFK();
+ BOOL getAFK() const;
- LLVector3 calcFocusOffset(LLViewerObject *object, LLVector3 pos_agent, S32 x, S32 y);
- BOOL calcCameraMinDistance(F32 &obj_min_distance);
+ //--------------------------------------------------------------------
+ // Run
+ //--------------------------------------------------------------------
+public:
+ enum EDoubleTapRunMode
+ {
+ DOUBLETAP_NONE,
+ DOUBLETAP_FORWARD,
+ DOUBLETAP_BACKWARD,
+ DOUBLETAP_SLIDELEFT,
+ DOUBLETAP_SLIDERIGHT
+ };
- void startCameraAnimation();
- void stopCameraAnimation();
+ void setAlwaysRun() { mbAlwaysRun = true; }
+ void clearAlwaysRun() { mbAlwaysRun = false; }
+ void setRunning() { mbRunning = true; }
+ void clearRunning() { mbRunning = false; }
+ void sendWalkRun(bool running);
+ bool getAlwaysRun() const { return mbAlwaysRun; }
+ bool getRunning() const { return mbRunning; }
+public:
+ LLFrameTimer mDoubleTapRunTimer;
+ EDoubleTapRunMode mDoubleTapRunMode;
+private:
+ bool mbAlwaysRun; // Should the avatar run by default rather than walk?
+ bool mbRunning; // Is the avatar trying to run right now?
- void cameraZoomIn(const F32 factor); // zoom in by fraction of current distance
- void cameraOrbitAround(const F32 radians); // rotate camera CCW radians about build focus point
- void cameraOrbitOver(const F32 radians); // rotate camera forward radians over build focus point
- void cameraOrbitIn(const F32 meters); // move camera in toward build focus point
+ //--------------------------------------------------------------------
+ // Sit and stand
+ //--------------------------------------------------------------------
+public:
+ void standUp();
- F32 getCameraZoomFraction(); // get camera zoom as fraction of minimum and maximum zoom
- void setCameraZoomFraction(F32 fraction); // set camera zoom as fraction of minimum and maximum zoom
+ //--------------------------------------------------------------------
+ // Busy
+ //--------------------------------------------------------------------
+public:
+ void setBusy();
+ void clearBusy();
+ BOOL getBusy() const;
+private:
+ BOOL mIsBusy;
- void cameraPanIn(const F32 meters);
- void cameraPanLeft(const F32 meters);
- void cameraPanUp(const F32 meters);
+ //--------------------------------------------------------------------
+ // Jump
+ //--------------------------------------------------------------------
+public:
+ BOOL getJump() const { return mbJump; }
+private:
+ BOOL mbJump;
- void updateFocusOffset();
- void validateFocusObject();
+ //--------------------------------------------------------------------
+ // Grab
+ //--------------------------------------------------------------------
+public:
+ BOOL leftButtonGrabbed() const;
+ BOOL rotateGrabbed() const;
+ BOOL forwardGrabbed() const;
+ BOOL backwardGrabbed() const;
+ BOOL upGrabbed() const;
+ BOOL downGrabbed() const;
- void setUsingFollowCam( bool using_follow_cam);
+ //--------------------------------------------------------------------
+ // Controls
+ //--------------------------------------------------------------------
+public:
+ U32 getControlFlags();
+ void setControlFlags(U32 mask); // Performs bitwise mControlFlags |= mask
+ void clearControlFlags(U32 mask); // Performs bitwise mControlFlags &= ~mask
+ BOOL controlFlagsDirty() const;
+ void enableControlFlagReset();
+ void resetControlFlags();
+ BOOL anyControlGrabbed() const; // True iff a script has taken over a control
+ BOOL isControlGrabbed(S32 control_index) const;
+ // Send message to simulator to force grabbed controls to be
+ // released, in case of a poorly written script.
+ void forceReleaseControls();
+private:
+ S32 mControlsTakenCount[TOTAL_CONTROLS];
+ S32 mControlsTakenPassedOnCount[TOTAL_CONTROLS];
+ U32 mControlFlags; // Replacement for the mFooKey's
+ BOOL mbFlagsDirty;
+ BOOL mbFlagsNeedReset; // ! HACK ! For preventing incorrect flags sent when crossing region boundaries
- F32 calcCustomizeAvatarUIOffset( const LLVector3d& camera_pos_global );
-
- // marks current location as start, sends information to servers
- void setStartPosition(U32 location_id);
+ //--------------------------------------------------------------------
+ // Animations
+ //--------------------------------------------------------------------
+public:
+ void stopCurrentAnimations();
+ void requestStopMotion(LLMotion* motion);
+ void onAnimStop(const LLUUID& id);
+ void sendAnimationRequests(LLDynamicArray<LLUUID> &anim_ids, EAnimRequest request);
+ void sendAnimationRequest(const LLUUID &anim_id, EAnimRequest request);
+ void endAnimationUpdateUI();
+private:
+ LLFrameTimer mAnimationTimer; // Seconds that transition animation has been active
+ F32 mAnimationDuration; // In seconds
+ BOOL mCustomAnim; // Current animation is ANIM_AGENT_CUSTOMIZE ?
+ LLAnimPauseRequest mPauseRequest;
+ BOOL mViewsPushed; // Keep track of whether or not we have pushed views
+
+/** Animation
+ ** **
+ *******************************************************************************/
+
+/********************************************************************************
+ ** **
+ ** MOVEMENT
+ **/
+
+ //--------------------------------------------------------------------
+ // Keys
+ //--------------------------------------------------------------------
+public:
+ void setKey(const S32 direction, S32 &key); // Sets key to +1 for +direction, -1 for -direction
+private:
+ S32 mAtKey; // Either 1, 0, or -1. Indicates that movement key is pressed
+ S32 mWalkKey; // Like AtKey, but causes less forward thrust
+ S32 mLeftKey;
+ S32 mUpKey;
+ F32 mYawKey;
+ S32 mPitchKey;
- // Movement from user input. All set the appropriate animation flags.
+ //--------------------------------------------------------------------
+ // Movement from user input
+ //--------------------------------------------------------------------
+ // All set the appropriate animation flags.
// All turn off autopilot and make sure the camera is behind the avatar.
- // direction is either positive, zero, or negative
+ // Direction is either positive, zero, or negative
+public:
void moveAt(S32 direction, bool reset_view = true);
void moveAtNudge(S32 direction);
void moveLeft(S32 direction);
@@ -443,145 +488,97 @@ public:
void moveYaw(F32 mag, bool reset_view = true);
void movePitch(S32 direction);
- void setOrbitLeftKey(F32 mag) { mOrbitLeftKey = mag; }
- void setOrbitRightKey(F32 mag) { mOrbitRightKey = mag; }
- void setOrbitUpKey(F32 mag) { mOrbitUpKey = mag; }
- void setOrbitDownKey(F32 mag) { mOrbitDownKey = mag; }
- void setOrbitInKey(F32 mag) { mOrbitInKey = mag; }
- void setOrbitOutKey(F32 mag) { mOrbitOutKey = mag; }
-
- void setPanLeftKey(F32 mag) { mPanLeftKey = mag; }
- void setPanRightKey(F32 mag) { mPanRightKey = mag; }
- void setPanUpKey(F32 mag) { mPanUpKey = mag; }
- void setPanDownKey(F32 mag) { mPanDownKey = mag; }
- void setPanInKey(F32 mag) { mPanInKey = mag; }
- void setPanOutKey(F32 mag) { mPanOutKey = mag; }
-
- U32 getControlFlags();
- void setControlFlags(U32 mask); // performs bitwise mControlFlags |= mask
- void clearControlFlags(U32 mask); // performs bitwise mControlFlags &= ~mask
- BOOL controlFlagsDirty() const;
- void enableControlFlagReset();
- void resetControlFlags();
-
- void propagate(const F32 dt); // BUG: should roll into updateAgentPosition
+ //--------------------------------------------------------------------
+ // Orbit
+ //--------------------------------------------------------------------
+public:
+ void setOrbitLeftKey(F32 mag) { mOrbitLeftKey = mag; }
+ void setOrbitRightKey(F32 mag) { mOrbitRightKey = mag; }
+ void setOrbitUpKey(F32 mag) { mOrbitUpKey = mag; }
+ void setOrbitDownKey(F32 mag) { mOrbitDownKey = mag; }
+ void setOrbitInKey(F32 mag) { mOrbitInKey = mag; }
+ void setOrbitOutKey(F32 mag) { mOrbitOutKey = mag; }
+private:
+ F32 mOrbitLeftKey;
+ F32 mOrbitRightKey;
+ F32 mOrbitUpKey;
+ F32 mOrbitDownKey;
+ F32 mOrbitInKey;
+ F32 mOrbitOutKey;
+
+ //--------------------------------------------------------------------
+ // Pan
+ //--------------------------------------------------------------------
+public:
+ void setPanLeftKey(F32 mag) { mPanLeftKey = mag; }
+ void setPanRightKey(F32 mag) { mPanRightKey = mag; }
+ void setPanUpKey(F32 mag) { mPanUpKey = mag; }
+ void setPanDownKey(F32 mag) { mPanDownKey = mag; }
+ void setPanInKey(F32 mag) { mPanInKey = mag; }
+ void setPanOutKey(F32 mag) { mPanOutKey = mag; }
+private:
+ F32 mPanUpKey;
+ F32 mPanDownKey;
+ F32 mPanLeftKey;
+ F32 mPanRightKey;
+ F32 mPanInKey;
+ F32 mPanOutKey;
- void startAutoPilotGlobal(const LLVector3d &pos_global, const std::string& behavior_name = std::string(), const LLQuaternion *target_rotation = NULL,
- void (*finish_callback)(BOOL, void *) = NULL, void *callback_data = NULL, F32 stop_distance = 0.f, F32 rotation_threshold = 0.03f);
+ //--------------------------------------------------------------------
+ // Move the avatar's frame
+ //--------------------------------------------------------------------
+public:
+ void rotate(F32 angle, const LLVector3 &axis);
+ void rotate(F32 angle, F32 x, F32 y, F32 z);
+ void rotate(const LLMatrix3 &matrix);
+ void rotate(const LLQuaternion &quaternion);
+ void pitch(F32 angle);
+ void roll(F32 angle);
+ void yaw(F32 angle);
+ LLVector3 getReferenceUpVector();
+ F32 clampPitchToLimits(F32 angle);
+ //--------------------------------------------------------------------
+ // Autopilot
+ //--------------------------------------------------------------------
+public:
+ BOOL getAutoPilot() const { return mAutoPilot; }
+ LLVector3d getAutoPilotTargetGlobal() const { return mAutoPilotTargetGlobal; }
+ void startAutoPilotGlobal(const LLVector3d &pos_global,
+ const std::string& behavior_name = std::string(),
+ const LLQuaternion *target_rotation = NULL,
+ void (*finish_callback)(BOOL, void *) = NULL, void *callback_data = NULL,
+ F32 stop_distance = 0.f, F32 rotation_threshold = 0.03f);
void startFollowPilot(const LLUUID &leader_id);
void stopAutoPilot(BOOL user_cancel = FALSE);
void setAutoPilotGlobal(const LLVector3d &pos_global);
- void autoPilot(F32 *delta_yaw); // autopilot walking action, angles in radians
+ void autoPilot(F32 *delta_yaw); // Autopilot walking action, angles in radians
void renderAutoPilotTarget();
+private:
+ BOOL mAutoPilot;
+ BOOL mAutoPilotFlyOnStop;
+ LLVector3d mAutoPilotTargetGlobal;
+ F32 mAutoPilotStopDistance;
+ BOOL mAutoPilotUseRotation;
+ LLVector3 mAutoPilotTargetFacing;
+ F32 mAutoPilotTargetDist;
+ S32 mAutoPilotNoProgressFrameCount;
+ F32 mAutoPilotRotationThreshold;
+ std::string mAutoPilotBehaviorName;
+ void (*mAutoPilotFinishedCallback)(BOOL, void *);
+ void* mAutoPilotCallbackData;
+ LLUUID mLeaderID;
+
+/** Movement
+ ** **
+ *******************************************************************************/
- //
- // teportation methods
- //
-
- // go to a named location home
- void teleportRequest(
- const U64& region_handle,
- const LLVector3& pos_local);
-
- // teleport to a landmark
- void teleportViaLandmark(const LLUUID& landmark_id);
-
- // go home
- void teleportHome() { teleportViaLandmark(LLUUID::null); }
-
- // to an invited location
- void teleportViaLure(const LLUUID& lure_id, BOOL godlike);
-
- // to a global location - this will probably need to be
- // deprecated.
- void teleportViaLocation(const LLVector3d& pos_global);
-
- // cancel the teleport, may or may not be allowed by server
- void teleportCancel();
-
- void setTargetVelocity(const LLVector3 &vel);
- const LLVector3 &getTargetVelocity() const;
-
- const std::string getTeleportSourceSLURL() const { return mTeleportSourceSLURL; }
-
-
- // Setting the ability for this avatar to proxy for another avatar.
- //static void processAddModifyAbility(LLMessageSystem* msg, void**);
- //static void processGrantedProxies(LLMessageSystem* msg, void**);
- //static void processRemoveModifyAbility(LLMessageSystem* msg, void**);
- //BOOL isProxyFor(const LLUUID& agent_id);// *FIX should be const
-
- static void processAgentDataUpdate(LLMessageSystem *msg, void **);
- static void processAgentGroupDataUpdate(LLMessageSystem *msg, void **);
- static void processAgentDropGroup(LLMessageSystem *msg, void **);
- static void processScriptControlChange(LLMessageSystem *msg, void **);
- static void processAgentCachedTextureResponse(LLMessageSystem *mesgsys, void **user_data);
- //static void processControlTake(LLMessageSystem *msg, void **);
- //static void processControlRelease(LLMessageSystem *msg, void **);
-
- // This method checks to see if this agent can modify an object
- // based on the permissions and the agent's proxy status.
- BOOL isGrantedProxy(const LLPermissions& perm);
-
- BOOL allowOperation(PermissionBit op,
- const LLPermissions& perm,
- U64 group_proxy_power = 0,
- U8 god_minimum = GOD_MAINTENANCE);
-
- friend std::ostream& operator<<(std::ostream &s, const LLAgent &sphere);
-
- void initOriginGlobal(const LLVector3d &origin_global); // Only to be used in ONE place! - djs 08/07/02
-
- BOOL leftButtonGrabbed() const { return ( (!cameraMouselook() && mControlsTakenCount[CONTROL_LBUTTON_DOWN_INDEX] > 0)
- ||(cameraMouselook() && mControlsTakenCount[CONTROL_ML_LBUTTON_DOWN_INDEX] > 0)
- ||(!cameraMouselook() && mControlsTakenPassedOnCount[CONTROL_LBUTTON_DOWN_INDEX] > 0)
- ||(cameraMouselook() && mControlsTakenPassedOnCount[CONTROL_ML_LBUTTON_DOWN_INDEX] > 0)); }
- BOOL rotateGrabbed() const { return ( (mControlsTakenCount[CONTROL_YAW_POS_INDEX] > 0)
- ||(mControlsTakenCount[CONTROL_YAW_NEG_INDEX] > 0)); }
- BOOL forwardGrabbed() const { return ( (mControlsTakenCount[CONTROL_AT_POS_INDEX] > 0)); }
- BOOL backwardGrabbed() const { return ( (mControlsTakenCount[CONTROL_AT_NEG_INDEX] > 0)); }
- BOOL upGrabbed() const { return ( (mControlsTakenCount[CONTROL_UP_POS_INDEX] > 0)); }
- BOOL downGrabbed() const { return ( (mControlsTakenCount[CONTROL_UP_NEG_INDEX] > 0)); }
-
- // True iff a script has taken over a control.
- BOOL anyControlGrabbed() const;
-
- BOOL isControlGrabbed(S32 control_index) const;
-
- // Send message to simulator to force grabbed controls to be
- // released, in case of a poorly written script.
- void forceReleaseControls();
-
- BOOL sitCameraEnabled() { return mSitCameraEnabled; }
-
- F32 getCurrentCameraBuildOffset() { return (F32)mCameraFocusOffset.length(); }
-
- // look at behavior
- BOOL setLookAt(ELookAtType target_type, LLViewerObject *object = NULL, LLVector3 position = LLVector3::zero);
- ELookAtType getLookAtType();
-
- // point at behavior
- BOOL setPointAt(EPointAtType target_type, LLViewerObject *object = NULL, LLVector3 position = LLVector3::zero);
- EPointAtType getPointAtType();
-
- void setHomePosRegion( const U64& region_handle, const LLVector3& pos_region );
- BOOL getHomePosGlobal( LLVector3d* pos_global );
- void setCameraAnimating( BOOL b ) { mCameraAnimating = b; }
- BOOL getCameraAnimating( ) { return mCameraAnimating; }
- void setAnimationDuration( F32 seconds ) { mAnimationDuration = seconds; }
-
- F32 getNearChatRadius() { return mNearChatRadius; }
-
- enum EDoubleTapRunMode
- {
- DOUBLETAP_NONE,
- DOUBLETAP_FORWARD,
- DOUBLETAP_BACKWARD,
- DOUBLETAP_SLIDELEFT,
- DOUBLETAP_SLIDERIGHT
- };
+/********************************************************************************
+ ** **
+ ** TELEPORT
+ **/
+public:
enum ETeleportState
{
TELEPORT_NONE = 0, // No teleport in progress
@@ -592,376 +589,507 @@ public:
TELEPORT_ARRIVING = 5 // Make the user wait while content "pre-caches"
};
- ETeleportState getTeleportState() const { return mTeleportState; }
- void setTeleportState( ETeleportState state );
- const std::string& getTeleportMessage() const { return mTeleportMessage; }
- void setTeleportMessage(const std::string& message)
- {
- mTeleportMessage = message;
- }
-
- // trigger random fidget animations
- void fidget();
-
- void requestEnterGodMode();
- void requestLeaveGodMode();
-
- void sendAgentSetAppearance();
+public:
+ static void parseTeleportMessages(const std::string& xml_filename);
+ const std::string getTeleportSourceSLURL() const { return mTeleportSourceSLURL; }
+public:
+ // ! TODO ! Define ERROR and PROGRESS enums here instead of exposing the mappings.
+ static std::map<std::string, std::string> sTeleportErrorMessages;
+ static std::map<std::string, std::string> sTeleportProgressMessages;
+private:
+ std::string mTeleportSourceSLURL; // SLURL where last TP began
- void sendAgentDataUpdateRequest();
+ //--------------------------------------------------------------------
+ // Teleport Actions
+ //--------------------------------------------------------------------
+public:
+ void teleportRequest(const U64& region_handle,
+ const LLVector3& pos_local); // Go to a named location home
+ void teleportViaLandmark(const LLUUID& landmark_id); // Teleport to a landmark
+ void teleportHome() { teleportViaLandmark(LLUUID::null); } // Go home
+ void teleportViaLure(const LLUUID& lure_id, BOOL godlike); // To an invited location
+ void teleportViaLocation(const LLVector3d& pos_global); // To a global location - this will probably need to be deprecated
+ void teleportCancel(); // May or may not be allowed by server
+protected:
+ bool teleportCore(bool is_local = false); // Stuff for all teleports; returns true if the teleport can proceed
- // Ventrella
- LLFollowCam mFollowCam;
- // end Ventrella
+ //--------------------------------------------------------------------
+ // Teleport State
+ //--------------------------------------------------------------------
+public:
+ ETeleportState getTeleportState() const { return mTeleportState; }
+ void setTeleportState(ETeleportState state);
+private:
+ ETeleportState mTeleportState;
//--------------------------------------------------------------------
- // Wearables
+ // Teleport Message
//--------------------------------------------------------------------
- void setWearable( LLInventoryItem* new_item, LLWearable* wearable );
- static bool onSetWearableDialog( const LLSD& notification, const LLSD& response, LLWearable* wearable );
- void setWearableFinal( LLInventoryItem* new_item, LLWearable* new_wearable );
- void setWearableOutfit( const LLInventoryItem::item_array_t& items, const LLDynamicArray< LLWearable* >& wearables, BOOL remove );
- void queryWearableCache();
+public:
+ const std::string& getTeleportMessage() const { return mTeleportMessage; }
+ void setTeleportMessage(const std::string& message) { mTeleportMessage = message; }
+private:
+ std::string mTeleportMessage;
+
+/** Teleport
+ ** **
+ *******************************************************************************/
- BOOL isWearableModifiable(EWearableType type);
- BOOL isWearableCopyable(EWearableType type);
- BOOL needsReplacement(EWearableType wearableType, S32 remove);
- U32 getWearablePermMask(EWearableType type);
+/********************************************************************************
+ ** **
+ ** CAMERA
+ **/
- LLInventoryItem* getWearableInventoryItem(EWearableType type);
+ //--------------------------------------------------------------------
+ // Mode
+ //--------------------------------------------------------------------
+public:
+ void changeCameraToDefault();
+ void changeCameraToMouselook(BOOL animate = TRUE);
+ void changeCameraToThirdPerson(BOOL animate = TRUE);
+ void changeCameraToCustomizeAvatar(BOOL avatar_animate = TRUE, BOOL camera_animate = TRUE); // Trigger transition animation
+ void changeCameraToFollow(BOOL animate = TRUE); // Ventrella
+ BOOL cameraThirdPerson() const { return (mCameraMode == CAMERA_MODE_THIRD_PERSON && mLastCameraMode == CAMERA_MODE_THIRD_PERSON); }
+ BOOL cameraMouselook() const { return (mCameraMode == CAMERA_MODE_MOUSELOOK && mLastCameraMode == CAMERA_MODE_MOUSELOOK); }
+ BOOL cameraCustomizeAvatar() const { return (mCameraMode == CAMERA_MODE_CUSTOMIZE_AVATAR /*&& !mCameraAnimating*/); }
+ BOOL cameraFollow() const { return (mCameraMode == CAMERA_MODE_FOLLOW && mLastCameraMode == CAMERA_MODE_FOLLOW); }
+ ECameraMode getCameraMode() const { return mCameraMode; }
+ void updateCamera(); // Call once per frame to update camera location/orientation
+ void resetCamera(); // Slam camera into its default position
+private:
+ ECameraMode mCameraMode; // Target mode after transition animation is done
+ ECameraMode mLastCameraMode;
- LLWearable* getWearable( EWearableType type ) { return (type < WT_COUNT) ? mWearableEntry[ type ].mWearable : NULL; }
- BOOL isWearingItem( const LLUUID& item_id );
- LLWearable* getWearableFromWearableItem( const LLUUID& item_id );
- const LLUUID& getWearableItem( EWearableType type ) { return (type < WT_COUNT) ? mWearableEntry[ type ].mItemID : LLUUID::null; }
+ //--------------------------------------------------------------------
+ // Preset
+ //--------------------------------------------------------------------
+public:
+ void switchCameraPreset(ECameraPreset preset);
- static EWearableType getTEWearableType( S32 te );
- static LLUUID getDefaultTEImageID( S32 te );
-
- void copyWearableToInventory( EWearableType type );
-
- void makeNewOutfit(
- const std::string& new_folder_name,
- const LLDynamicArray<S32>& wearables_to_include,
- const LLDynamicArray<S32>& attachments_to_include,
- BOOL rename_clothing);
- void makeNewOutfitDone(S32 index);
-
- void removeWearable( EWearableType type );
- static bool onRemoveWearableDialog(const LLSD& notification, const LLSD& response );
- void removeWearableFinal( EWearableType type );
-
- void sendAgentWearablesUpdate();
-
- /**
- * @brief Only public because of addWearableToAgentInventoryCallback.
- *
- * NOTE: Do not call this method unless you are the inventory callback.
- * NOTE: This can suffer from race conditions when working on the
- * same values for index.
- * @param index The index in mWearableEntry.
- * @param item_id The inventory item id of the new wearable to wear.
- * @param wearable The actual wearable data.
- */
- void addWearabletoAgentInventoryDone(
- S32 index,
- const LLUUID& item_id,
- LLWearable* wearable);
-
- void saveWearableAs( EWearableType type, const std::string& new_name, BOOL save_in_lost_and_found );
- void saveWearable( EWearableType type, BOOL send_update = TRUE );
- void saveAllWearables();
+private:
- void revertWearable( EWearableType type );
- void revertAllWearables();
-
- void setWearableName( const LLUUID& item_id, const std::string& new_name );
- void createStandardWearables(BOOL female);
- void createStandardWearablesDone(S32 index);
- void createStandardWearablesAllDone();
+ /** Determines default camera offset depending on the current camera preset */
+ LLVector3 getCameraOffsetInitial();
- BOOL areWearablesLoaded() { return mWearablesLoaded; }
+ /** Camera preset in Third Person Mode */
+ ECameraPreset mCameraPreset;
- void sendWalkRun(bool running);
+ /** Initial camera offsets */
+ std::map<ECameraPreset, LLVector3> mCameraOffsetInitial;
- void observeFriends();
- void friendsChanged();
+ /** Initial focus offsets */
+ std::map<ECameraPreset, LLVector3d> mFocusOffsetInitial;
- // statics
- static void stopFidget();
- static void processAgentInitialWearablesUpdate(LLMessageSystem* mesgsys, void** user_data);
- static void userRemoveWearable( void* userdata ); // userdata is EWearableType
- static void userRemoveAllClothes( void* userdata ); // userdata is NULL
- static void userRemoveAllClothesStep2(BOOL proceed, void* userdata ); // userdata is NULL
- static void userRemoveAllAttachments( void* userdata); // userdata is NULL
- static BOOL selfHasWearable( void* userdata ); // userdata is EWearableType
-
- //debug methods
- static void clearVisualParams(void *);
-
-protected:
- // stuff to do for any sort of teleport. Returns true if the
- // teleport can proceed.
- bool teleportCore(bool is_local = false);
- // helper function to prematurely age chat when agent is moving
- void ageChat();
+ //--------------------------------------------------------------------
+ // Position
+ //--------------------------------------------------------------------
+public:
+ LLVector3d getCameraPositionGlobal() const;
+ const LLVector3 &getCameraPositionAgent() const;
+ LLVector3d calcCameraPositionTargetGlobal(BOOL *hit_limit = NULL); // Calculate the camera position target
+ F32 getCameraMinOffGround(); // Minimum height off ground for this mode, meters
+ void setCameraCollidePlane(const LLVector4 &plane) { mCameraCollidePlane = plane; }
+ BOOL calcCameraMinDistance(F32 &obj_min_distance);
+ F32 calcCustomizeAvatarUIOffset(const LLVector3d& camera_pos_global);
+ F32 getCurrentCameraBuildOffset() { return (F32)mCameraFocusOffset.length(); }
+private:
+ F32 mCurrentCameraDistance; // Current camera offset from avatar
+ F32 mTargetCameraDistance; // Target camera offset from avatar
+ F32 mCameraFOVZoomFactor; // Amount of fov zoom applied to camera when zeroing in on an object
+ F32 mCameraCurrentFOVZoomFactor; // Interpolated fov zoom
+ F32 mCameraFOVDefault; // Default field of view that is basis for FOV zoom effect
+ LLVector4 mCameraCollidePlane; // Colliding plane for camera
+ F32 mCameraZoomFraction; // Mousewheel driven fraction of zoom
+ LLVector3 mCameraPositionAgent; // Camera position in agent coordinates
+ LLVector3 mCameraVirtualPositionAgent; // Camera virtual position (target) before performing FOV zoom
+ LLVector3d mCameraSmoothingLastPositionGlobal;
+ LLVector3d mCameraSmoothingLastPositionAgent;
+ BOOL mCameraSmoothingStop;
+ LLVector3 mCameraLag; // Third person camera lag
+ LLVector3 mCameraUpVector; // Camera's up direction in world coordinates (determines the 'roll' of the view)
- // internal wearable functions
- void sendAgentWearablesRequest();
- static void onInitialWearableAssetArrived(LLWearable* wearable, void* userdata);
- void recoverMissingWearable(EWearableType type);
- void recoverMissingWearableDone();
- void addWearableToAgentInventory(LLPointer<LLInventoryCallback> cb,
- LLWearable* wearable, const LLUUID& category_id = LLUUID::null,
- BOOL notify = TRUE);
+ //--------------------------------------------------------------------
+ // Follow
+ //--------------------------------------------------------------------
public:
- // TODO: Make these private!
- LLUUID mSecureSessionID; // secure token for this login session
+ void setUsingFollowCam(bool using_follow_cam);
+private:
+ LLFollowCam mFollowCam; // Ventrella
- F32 mDrawDistance;
+ //--------------------------------------------------------------------
+ // Sit
+ //--------------------------------------------------------------------
+public:
+ void setupSitCamera();
+ BOOL sitCameraEnabled() { return mSitCameraEnabled; }
+ void setSitCamera(const LLUUID &object_id,
+ const LLVector3 &camera_pos = LLVector3::zero, const LLVector3 &camera_focus = LLVector3::zero);
+private:
+ LLPointer<LLViewerObject> mSitCameraReferenceObject; // Object to which camera is related when sitting
+ BOOL mSitCameraEnabled; // Use provided camera information when sitting?
+ LLVector3 mSitCameraPos; // Root relative camera pos when sitting
+ LLVector3 mSitCameraFocus; // Root relative camera target when sitting
- U64 mGroupPowers;
- BOOL mHideGroupTitle;
- std::string mGroupTitle; // honorific, like "Sir"
- std::string mGroupName;
- LLUUID mGroupID;
- //LLUUID mGroupInsigniaID;
- LLUUID mInventoryRootID;
- LLUUID mMapID;
- F64 mMapOriginX; // Global x coord of mMapID's bottom left corner.
- F64 mMapOriginY; // Global y coord of mMapID's bottom left corner.
- S32 mMapWidth; // Width of map in meters
- S32 mMapHeight; // Height of map in meters
- std::string mMOTD; // message of the day
+ //--------------------------------------------------------------------
+ // Animation
+ //--------------------------------------------------------------------
+public:
+ void setCameraAnimating(BOOL b) { mCameraAnimating = b; }
+ BOOL getCameraAnimating() { return mCameraAnimating; }
+ void setAnimationDuration(F32 seconds) { mAnimationDuration = seconds; }
+ void startCameraAnimation();
+ void stopCameraAnimation();
+private:
+ BOOL mCameraAnimating; // Camera is transitioning from one mode to another
+ LLVector3d mAnimationCameraStartGlobal; // Camera start position, global coords
+ LLVector3d mAnimationFocusStartGlobal; // Camera focus point, global coords
+ //--------------------------------------------------------------------
+ // Focus
+ //--------------------------------------------------------------------
+public:
+ LLVector3d calcFocusPositionTargetGlobal();
+ LLVector3 calcFocusOffset(LLViewerObject *object, LLVector3 pos_agent, S32 x, S32 y);
+ BOOL getFocusOnAvatar() const { return mFocusOnAvatar; }
+ LLPointer<LLViewerObject>& getFocusObject() { return mFocusObject; }
+ F32 getFocusObjectDist() const { return mFocusObjectDist; }
+ void updateFocusOffset();
+ void validateFocusObject();
+ void setFocusGlobal(const LLPickInfo& pick);
+ void setFocusGlobal(const LLVector3d &focus, const LLUUID &object_id = LLUUID::null);
+ void setFocusOnAvatar(BOOL focus, BOOL animate);
+ void setCameraPosAndFocusGlobal(const LLVector3d& pos, const LLVector3d& focus, const LLUUID &object_id);
+ void clearFocusObject();
+ void setFocusObject(LLViewerObject* object);
+ void setObjectTracking(BOOL track) { mTrackFocusObject = track; }
+ const LLVector3d &getFocusGlobal() const { return mFocusGlobal; }
+ const LLVector3d &getFocusTargetGlobal() const { return mFocusTargetGlobal; }
+private:
+ LLVector3d mCameraFocusOffset; // Offset from focus point in build mode
+ LLVector3d mCameraFocusOffsetTarget; // Target towards which we are lerping the camera's focus offset
+ BOOL mFocusOnAvatar;
+ LLVector3d mFocusGlobal;
+ LLVector3d mFocusTargetGlobal;
+ LLPointer<LLViewerObject> mFocusObject;
+ F32 mFocusObjectDist;
+ LLVector3 mFocusObjectOffset;
+ F32 mFocusDotRadius; // Meters
+ BOOL mTrackFocusObject;
+ F32 mUIOffset;
+
+ //--------------------------------------------------------------------
+ // Lookat / Pointat
+ //--------------------------------------------------------------------
+public:
+ void updateLookAt(const S32 mouse_x, const S32 mouse_y);
+ BOOL setLookAt(ELookAtType target_type, LLViewerObject *object = NULL, LLVector3 position = LLVector3::zero);
+ ELookAtType getLookAtType();
+ void slamLookAt(const LLVector3 &look_at); // Set the physics data
+ BOOL setPointAt(EPointAtType target_type, LLViewerObject *object = NULL, LLVector3 position = LLVector3::zero);
+ EPointAtType getPointAtType();
+public:
LLPointer<LLHUDEffectLookAt> mLookAt;
LLPointer<LLHUDEffectPointAt> mPointAt;
- LLDynamicArray<LLGroupData> mGroups;
+ //--------------------------------------------------------------------
+ // Third person
+ //--------------------------------------------------------------------
+public:
+ LLVector3d calcThirdPersonFocusOffset();
+ void setThirdPersonHeadOffset(LLVector3 offset) { mThirdPersonHeadOffset = offset; }
+private:
+ LLVector3 mThirdPersonHeadOffset; // Head offset for third person camera position
- F32 mHUDTargetZoom; // target zoom level for HUD objects (used when editing)
- F32 mHUDCurZoom; // current animated zoom level for HUD objects
+ //--------------------------------------------------------------------
+ // Orbit
+ //--------------------------------------------------------------------
+public:
+ void cameraOrbitAround(const F32 radians); // Rotate camera CCW radians about build focus point
+ void cameraOrbitOver(const F32 radians); // Rotate camera forward radians over build focus point
+ void cameraOrbitIn(const F32 meters); // Move camera in toward build focus point
- BOOL mInitialized;
+ //--------------------------------------------------------------------
+ // Zoom
+ //--------------------------------------------------------------------
+public:
+ void handleScrollWheel(S32 clicks); // Mousewheel driven zoom
+ void cameraZoomIn(const F32 factor); // Zoom in by fraction of current distance
+ F32 getCameraZoomFraction(); // Get camera zoom as fraction of minimum and maximum zoom
+ void setCameraZoomFraction(F32 fraction); // Set camera zoom as fraction of minimum and maximum zoom
+ F32 calcCameraFOVZoomFactor();
- S32 mNumPendingQueries;
- S32* mActiveCacheQueries;
+ //--------------------------------------------------------------------
+ // Pan
+ //--------------------------------------------------------------------
+public:
+ void cameraPanIn(const F32 meters);
+ void cameraPanLeft(const F32 meters);
+ void cameraPanUp(const F32 meters);
+
+ //--------------------------------------------------------------------
+ // View
+ //--------------------------------------------------------------------
+public:
+ // Called whenever the agent moves. Puts camera back in default position, deselects items, etc.
+ void resetView(BOOL reset_camera = TRUE, BOOL change_camera = FALSE);
+ // Called on camera movement. Unlocks camera from the default position behind the avatar.
+ void unlockView();
+ //--------------------------------------------------------------------
+ // Mouselook
+ //--------------------------------------------------------------------
+public:
+ BOOL getForceMouselook() const { return mForceMouselook; }
+ void setForceMouselook(BOOL mouselook) { mForceMouselook = mouselook; }
+private:
BOOL mForceMouselook;
+
+ //--------------------------------------------------------------------
+ // HUD
+ //--------------------------------------------------------------------
+public:
+ const LLColor4 &getEffectColor();
+ void setEffectColor(const LLColor4 &color);
+public:
+ F32 mHUDTargetZoom; // Target zoom level for HUD objects (used when editing)
+ F32 mHUDCurZoom; // Current animated zoom level for HUD objects
+private:
+ LLUIColor mEffectColor;
- static void parseTeleportMessages(const std::string& xml_filename);
- //we should really define ERROR and PROGRESS enums here
- //but I don't really feel like doing that, so I am just going
- //to expose the mappings....yup
- static std::map<std::string, std::string> sTeleportErrorMessages;
- static std::map<std::string, std::string> sTeleportProgressMessages;
+/** Camera
+ ** **
+ *******************************************************************************/
- LLFrameTimer mDoubleTapRunTimer;
- EDoubleTapRunMode mDoubleTapRunMode;
+/********************************************************************************
+ ** **
+ ** ACCESS
+ **/
+public:
+ // Checks if agent can modify an object based on the permissions and the agent's proxy status.
+ BOOL isGrantedProxy(const LLPermissions& perm);
+ BOOL allowOperation(PermissionBit op,
+ const LLPermissions& perm,
+ U64 group_proxy_power = 0,
+ U8 god_minimum = GOD_MAINTENANCE);
+ const LLAgentAccess& getAgentAccess();
+ BOOL canManageEstate() const;
+ BOOL getAdminOverride() const;
+ // ! BACKWARDS COMPATIBILITY ! This function can go away after the AO transition (see llstartup.cpp).
+ void setAOTransition();
private:
- bool mbAlwaysRun; // should the avatar run by default rather than walk
- bool mbRunning; // is the avatar trying to run right now
-
- LLAgentAccess mAgentAccess;
+ LLAgentAccess mAgentAccess;
- ETeleportState mTeleportState;
- std::string mTeleportMessage;
-
- S32 mControlsTakenCount[TOTAL_CONTROLS];
- S32 mControlsTakenPassedOnCount[TOTAL_CONTROLS];
-
- LLViewerRegion *mRegionp;
- LLVector3d mAgentOriginGlobal; // Origin of agent coords from global coords
- mutable LLVector3d mPositionGlobal;
+ //--------------------------------------------------------------------
+ // God
+ //--------------------------------------------------------------------
+public:
+ BOOL isGodlike() const;
+ U8 getGodLevel() const;
+ void setAdminOverride(BOOL b);
+ void setGodLevel(U8 god_level);
+ void requestEnterGodMode();
+ void requestLeaveGodMode();
- std::string mTeleportSourceSLURL; // SLURL where last TP began.
+ //--------------------------------------------------------------------
+ // Maturity
+ //--------------------------------------------------------------------
+public:
+ // Note: this is a prime candidate for pulling out into a Maturity class.
+ // Rather than just expose the preference setting, we're going to actually
+ // expose what the client code cares about -- what the user should see
+ // based on a combination of the is* and prefers* flags, combined with god bit.
+ bool wantsPGOnly() const;
+ bool canAccessMature() const;
+ bool canAccessAdult() const;
+ bool canAccessMaturityInRegion( U64 region_handle ) const;
+ bool canAccessMaturityAtGlobal( LLVector3d pos_global ) const;
+ bool prefersPG() const;
+ bool prefersMature() const;
+ bool prefersAdult() const;
+ bool isTeen() const;
+ bool isMature() const;
+ bool isAdult() const;
+ void setTeen(bool teen);
+ void setMaturity(char text);
+ static int convertTextToMaturity(char text);
+ bool sendMaturityPreferenceToServer(int preferredMaturity); // ! "U8" instead of "int"?
+
+ // Maturity callbacks for PreferredMaturity control variable
+ void handleMaturity(const LLSD& newvalue);
+ bool validateMaturity(const LLSD& newvalue);
+
+
+/** Access
+ ** **
+ *******************************************************************************/
+
+/********************************************************************************
+ ** **
+ ** RENDERING
+ **/
- std::set<U64> mRegionsVisited; // stat - what distinct regions has the avatar been to?
- F64 mDistanceTraveled; // stat - how far has the avatar moved?
- LLVector3d mLastPositionGlobal; // Used to calculate travel distance
+public:
+ LLQuaternion getHeadRotation();
+ BOOL needsRenderAvatar(); // TRUE when camera mode is such that your own avatar should draw
+ BOOL needsRenderHead();
+public:
+ F32 mDrawDistance;
+private:
+ BOOL mShowAvatar; // Should we render the avatar?
+ U32 mAppearanceSerialNum;
+
+ //--------------------------------------------------------------------
+ // Rendering state bitmap helpers
+ //--------------------------------------------------------------------
+public:
+ void setRenderState(U8 newstate);
+ void clearRenderState(U8 clearstate);
+ U8 getRenderState();
+private:
+ U8 mRenderState; // Current behavior state of agent
- LLPointer<LLVOAvatar> mAvatarObject; // NULL until avatar object sent down from simulator
+/** Rendering
+ ** **
+ *******************************************************************************/
- U8 mRenderState; // Current behavior state of agent
- LLFrameTimer mTypingTimer;
+/********************************************************************************
+ ** **
+ ** GROUPS
+ **/
- ECameraMode mCameraMode; // target mode after transition animation is done
- ECameraMode mLastCameraMode;
- BOOL mViewsPushed; // keep track of whether or not we have pushed views.
-
- BOOL mCustomAnim ; //current animation is ANIM_AGENT_CUSTOMIZE ?
- BOOL mShowAvatar; // should we render the avatar?
- BOOL mCameraAnimating; // camera is transitioning from one mode to another
- LLVector3d mAnimationCameraStartGlobal; // camera start position, global coords
- LLVector3d mAnimationFocusStartGlobal; // camera focus point, global coords
- LLFrameTimer mAnimationTimer; // seconds that transition animation has been active
- F32 mAnimationDuration; // seconds
- F32 mCameraFOVZoomFactor; // amount of fov zoom applied to camera when zeroing in on an object
- F32 mCameraCurrentFOVZoomFactor; // interpolated fov zoom
- F32 mCameraFOVDefault; // default field of view that is basis for FOV zoom effect
- LLVector3d mCameraFocusOffset; // offset from focus point in build mode
- LLVector3d mCameraFocusOffsetTarget; // target towards which we are lerping the camera's focus offset
- LLVector3 mCameraOffsetDefault; // default third-person camera offset
- LLVector4 mCameraCollidePlane; // colliding plane for camera
- F32 mCurrentCameraDistance; // current camera offset from avatar
- F32 mTargetCameraDistance; // target camera offset from avatar
- F32 mCameraZoomFraction; // mousewheel driven fraction of zoom
- LLVector3 mCameraLag; // third person camera lag
- LLVector3 mThirdPersonHeadOffset; // head offset for third person camera position
- LLVector3 mCameraPositionAgent; // camera position in agent coordinates
- LLVector3 mCameraVirtualPositionAgent; // camera virtual position (target) before performing FOV zoom
- BOOL mSitCameraEnabled; // use provided camera information when sitting?
- LLVector3 mSitCameraPos; // root relative camera pos when sitting
- LLVector3 mSitCameraFocus; // root relative camera target when sitting
- LLVector3d mCameraSmoothingLastPositionGlobal;
- LLVector3d mCameraSmoothingLastPositionAgent;
- BOOL mCameraSmoothingStop;
+public:
+ const LLUUID &getGroupID() const { return mGroupID; }
+ // Get group information by group_id, or FALSE if not in group.
+ BOOL getGroupData(const LLUUID& group_id, LLGroupData& data) const;
+ // Get just the agent's contribution to the given group.
+ S32 getGroupContribution(const LLUUID& group_id) const;
+ // Update internal datastructures and update the server.
+ BOOL setGroupContribution(const LLUUID& group_id, S32 contribution);
+ BOOL setUserGroupFlags(const LLUUID& group_id, BOOL accept_notices, BOOL list_in_profile);
+ const std::string &getGroupName() const { return mGroupName; }
+private:
+ std::string mGroupName;
+ LLUUID mGroupID;
- LLVector3 mCameraUpVector; // camera's up direction in world coordinates (determines the 'roll' of the view)
+ //--------------------------------------------------------------------
+ // Group Membership
+ //--------------------------------------------------------------------
+public:
+ // Checks against all groups in the entire agent group list.
+ BOOL isInGroup(const LLUUID& group_id) const;
+protected:
+ // Only used for building titles.
+ BOOL isGroupMember() const { return !mGroupID.isNull(); }
+public:
+ LLDynamicArray<LLGroupData> mGroups;
- LLPointer<LLViewerObject> mSitCameraReferenceObject; // object to which camera is related when sitting
+ //--------------------------------------------------------------------
+ // Group Title
+ //--------------------------------------------------------------------
+public:
+ void setHideGroupTitle(BOOL hide) { mHideGroupTitle = hide; }
+ BOOL isGroupTitleHidden() const { return mHideGroupTitle; }
+private:
+ std::string mGroupTitle; // Honorific, like "Sir"
+ BOOL mHideGroupTitle;
- BOOL mFocusOnAvatar;
- LLVector3d mFocusGlobal;
- LLVector3d mFocusTargetGlobal;
- LLPointer<LLViewerObject> mFocusObject;
- F32 mFocusObjectDist;
- LLVector3 mFocusObjectOffset;
- F32 mFocusDotRadius; // meters
- BOOL mTrackFocusObject;
- F32 mUIOffset;
+ //--------------------------------------------------------------------
+ // Group Powers
+ //--------------------------------------------------------------------
+public:
+ BOOL hasPowerInGroup(const LLUUID& group_id, U64 power) const;
+ BOOL hasPowerInActiveGroup(const U64 power) const;
+ U64 getPowerInGroup(const LLUUID& group_id) const;
+ U64 mGroupPowers;
- LLCoordFrame mFrameAgent; // Agent position and view, agent-region coordinates
+ //--------------------------------------------------------------------
+ // Friends
+ //--------------------------------------------------------------------
+public:
+ void observeFriends();
+ void friendsChanged();
+private:
+ LLFriendObserver* mFriendObserver;
+ std::set<LLUUID> mProxyForAgents;
- BOOL mIsBusy;
+/** Groups
+ ** **
+ *******************************************************************************/
- S32 mAtKey; // Either 1, 0, or -1... indicates that movement-key is pressed
- S32 mWalkKey; // like AtKey, but causes less forward thrust
- S32 mLeftKey;
- S32 mUpKey;
- F32 mYawKey;
- S32 mPitchKey;
+/********************************************************************************
+ ** **
+ ** MESSAGING
+ **/
- F32 mOrbitLeftKey;
- F32 mOrbitRightKey;
- F32 mOrbitUpKey;
- F32 mOrbitDownKey;
- F32 mOrbitInKey;
- F32 mOrbitOutKey;
+ //--------------------------------------------------------------------
+ // Send
+ //--------------------------------------------------------------------
+public:
+ void sendMessage(); // Send message to this agent's region
+ void sendReliableMessage();
+ void sendAgentSetAppearance();
+ void sendAgentDataUpdateRequest();
+ void sendAgentUserInfoRequest();
+ // IM to Email and Online visibility
+ void sendAgentUpdateUserInfo(bool im_to_email, const std::string& directory_visibility);
- F32 mPanUpKey;
- F32 mPanDownKey;
- F32 mPanLeftKey;
- F32 mPanRightKey;
- F32 mPanInKey;
- F32 mPanOutKey;
+ //--------------------------------------------------------------------
+ // Receive
+ //--------------------------------------------------------------------
+public:
+ static void processAgentDataUpdate(LLMessageSystem *msg, void **);
+ static void processAgentGroupDataUpdate(LLMessageSystem *msg, void **);
+ static void processAgentDropGroup(LLMessageSystem *msg, void **);
+ static void processScriptControlChange(LLMessageSystem *msg, void **);
+ static void processAgentCachedTextureResponse(LLMessageSystem *mesgsys, void **user_data);
+
+/** Messaging
+ ** **
+ *******************************************************************************/
- U32 mControlFlags; // replacement for the mFooKey's
- BOOL mbFlagsDirty;
- BOOL mbFlagsNeedReset; // HACK for preventing incorrect flags sent when crossing region boundaries
+/********************************************************************************
+ ** **
+ ** DEBUGGING
+ **/
- BOOL mbJump;
+public:
+ static void dumpGroupInfo();
+ static void clearVisualParams(void *);
+ friend std::ostream& operator<<(std::ostream &s, const LLAgent &sphere);
- BOOL mAutoPilot;
- BOOL mAutoPilotFlyOnStop;
- LLVector3d mAutoPilotTargetGlobal;
- F32 mAutoPilotStopDistance;
- BOOL mAutoPilotUseRotation;
- LLVector3 mAutoPilotTargetFacing;
- F32 mAutoPilotTargetDist;
- S32 mAutoPilotNoProgressFrameCount;
- F32 mAutoPilotRotationThreshold;
- std::string mAutoPilotBehaviorName;
- void (*mAutoPilotFinishedCallback)(BOOL, void *);
- void* mAutoPilotCallbackData;
- LLUUID mLeaderID;
+/** Debugging
+ ** **
+ *******************************************************************************/
- std::set<LLUUID> mProxyForAgents;
+};
- LLColor4 mEffectColor;
+extern LLAgent gAgent;
- BOOL mHaveHomePosition;
- U64 mHomeRegionHandle;
- LLVector3 mHomePosRegion;
- LLFrameTimer mChatTimer;
- LLUUID mLastChatterID;
- F32 mNearChatRadius;
+inline bool operator==(const LLGroupData &a, const LLGroupData &b)
+{
+ return (a.mID == b.mID);
+}
- LLFrameTimer mFidgetTimer;
- LLFrameTimer mFocusObjectFadeTimer;
- F32 mNextFidgetTime;
- S32 mCurrentFidget;
- BOOL mFirstLogin;
- BOOL mGenderChosen;
+class LLAgentQueryManager
+{
+ friend class LLAgent;
+ friend class LLAgentWearables;
- //--------------------------------------------------------------------
- // Wearables
- //--------------------------------------------------------------------
- struct LLWearableEntry
- {
- LLWearableEntry() : mItemID( LLUUID::null ), mWearable( NULL ) {}
-
- LLUUID mItemID; // ID of the inventory item in the agent's inventory.
- LLWearable* mWearable;
- };
- LLWearableEntry mWearableEntry[ WT_COUNT ];
- U32 mAgentWearablesUpdateSerialNum;
- BOOL mWearablesLoaded;
- S32 mTextureCacheQueryID;
- U32 mAppearanceSerialNum;
- LLAnimPauseRequest mPauseRequest;
-
- class createStandardWearablesAllDoneCallback : public LLRefCount
- {
- protected:
- ~createStandardWearablesAllDoneCallback();
- };
- class sendAgentWearablesUpdateCallback : public LLRefCount
- {
- protected:
- ~sendAgentWearablesUpdateCallback();
- };
-
- class addWearableToAgentInventoryCallback : public LLInventoryCallback
- {
- public:
- enum {
- CALL_NONE = 0,
- CALL_UPDATE = 1,
- CALL_RECOVERDONE = 2,
- CALL_CREATESTANDARDDONE = 4,
- CALL_MAKENEWOUTFITDONE = 8
- } EType;
-
- /**
- * @brief Construct a callback for dealing with the wearables.
- *
- * Would like to pass the agent in here, but we can't safely
- * count on it being around later. Just use gAgent directly.
- * @param cb callback to execute on completion (??? unused ???)
- * @param index Index for the wearable in the agent
- * @param wearable The wearable data.
- * @param todo Bitmask of actions to take on completion.
- */
- addWearableToAgentInventoryCallback(
- LLPointer<LLRefCount> cb,
- S32 index,
- LLWearable* wearable,
- U32 todo = CALL_NONE);
- virtual void fire(const LLUUID& inv_item);
-
- private:
- S32 mIndex;
- LLWearable* mWearable;
- U32 mTodo;
- LLPointer<LLRefCount> mCB;
- };
-
- LLFriendObserver* mFriendObserver;
+public:
+ LLAgentQueryManager();
+ virtual ~LLAgentQueryManager();
+
+ BOOL hasNoPendingQueries() const { return getNumPendingQueries() == 0; }
+ S32 getNumPendingQueries() const { return mNumPendingQueries; }
+private:
+ S32 mNumPendingQueries;
+ S32 mWearablesCacheQueryID;
+ U32 mUpdateSerialNum;
+ S32 mActiveCacheQueries[LLVOAvatarDefines::BAKED_NUM_INDICES];
};
-extern LLAgent gAgent;
+extern LLAgentQueryManager gAgentQueryManager;
#endif
diff --git a/indra/newview/llagentaccess.cpp b/indra/newview/llagentaccess.cpp
index a4fbc04855..eb978eb6c1 100644
--- a/indra/newview/llagentaccess.cpp
+++ b/indra/newview/llagentaccess.cpp
@@ -3,16 +3,39 @@
* @brief LLAgentAccess class implementation - manages maturity and godmode info
*
* $LicenseInfo:firstyear=2001&license=viewergpl$
+ *
* Copyright (c) 2001-2009, Linden Research, Inc.
+ *
+ * Second Life Viewer Source Code
+ * The source code in this file ("Source Code") is provided by Linden Lab
+ * to you under the terms of the GNU General Public License, version 2.0
+ * ("GPL"), unless you have obtained a separate licensing agreement
+ * ("Other License"), formally executed by you and Linden Lab. Terms of
+ * the GPL can be found in doc/GPL-license.txt in this distribution, or
+ * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
+ *
+ * There are special exceptions to the terms and conditions of the GPL as
+ * it is applied to this Source Code. View the full text of the exception
+ * in the file doc/FLOSS-exception.txt in this software distribution, or
+ * online at
+ * http://secondlifegrid.net/programs/open_source/licensing/flossexception
+ *
+ * By copying, modifying or distributing this software, you acknowledge
+ * that you have read and understood your obligations described above,
+ * and agree to abide by those obligations.
+ *
+ * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+ * COMPLETENESS OR PERFORMANCE.
* $/LicenseInfo$
*/
#include "llviewerprecompiledheaders.h"
#include "llagentaccess.h"
#include "indra_constants.h"
-#include "llcontrolgroupreader.h"
+#include "llcontrol.h"
-LLAgentAccess::LLAgentAccess(LLControlGroupReader& savedSettings) :
+LLAgentAccess::LLAgentAccess(LLControlGroup& savedSettings) :
mSavedSettings(savedSettings),
mAccess(SIM_ACCESS_PG),
mAdminOverride(false),
@@ -140,6 +163,20 @@ int LLAgentAccess::convertTextToMaturity(char text)
void LLAgentAccess::setMaturity(char text)
{
mAccess = LLAgentAccess::convertTextToMaturity(text);
+ U32 preferred_access = mSavedSettings.getU32("PreferredMaturity");
+ while (!canSetMaturity(preferred_access))
+ {
+ if (preferred_access == SIM_ACCESS_ADULT)
+ {
+ preferred_access = SIM_ACCESS_MATURE;
+ }
+ else
+ {
+ // Mature or invalid access gets set to PG
+ preferred_access = SIM_ACCESS_PG;
+ }
+ }
+ mSavedSettings.setU32("PreferredMaturity", preferred_access);
}
void LLAgentAccess::setTransition()
@@ -152,3 +189,14 @@ bool LLAgentAccess::isInTransition() const
return mAOTransition;
}
+bool LLAgentAccess::canSetMaturity(S32 maturity)
+{
+ if (isGodlike()) // Gods can always set their Maturity level
+ return true;
+ if (isAdult()) // Adults can always set their Maturity level
+ return true;
+ if (maturity == SIM_ACCESS_PG || (maturity == SIM_ACCESS_MATURE && isMature()))
+ return true;
+ else
+ return false;
+}
diff --git a/indra/newview/llagentaccess.h b/indra/newview/llagentaccess.h
index dec0d76cc9..93d2f0a371 100644
--- a/indra/newview/llagentaccess.h
+++ b/indra/newview/llagentaccess.h
@@ -3,7 +3,30 @@
* @brief LLAgentAccess class implementation - manages maturity and godmode info
*
* $LicenseInfo:firstyear=2001&license=viewergpl$
+ *
* Copyright (c) 2001-2009, Linden Research, Inc.
+ *
+ * Second Life Viewer Source Code
+ * The source code in this file ("Source Code") is provided by Linden Lab
+ * to you under the terms of the GNU General Public License, version 2.0
+ * ("GPL"), unless you have obtained a separate licensing agreement
+ * ("Other License"), formally executed by you and Linden Lab. Terms of
+ * the GPL can be found in doc/GPL-license.txt in this distribution, or
+ * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
+ *
+ * There are special exceptions to the terms and conditions of the GPL as
+ * it is applied to this Source Code. View the full text of the exception
+ * in the file doc/FLOSS-exception.txt in this software distribution, or
+ * online at
+ * http://secondlifegrid.net/programs/open_source/licensing/flossexception
+ *
+ * By copying, modifying or distributing this software, you acknowledge
+ * that you have read and understood your obligations described above,
+ * and agree to abide by those obligations.
+ *
+ * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+ * COMPLETENESS OR PERFORMANCE.
* $/LicenseInfo$
*/
@@ -13,12 +36,12 @@
#include "stdtypes.h"
// forward declaration so that we don't have to include the whole class
-class LLControlGroupReader;
+class LLControlGroup;
class LLAgentAccess
{
public:
- LLAgentAccess(LLControlGroupReader& savedSettings);
+ LLAgentAccess(LLControlGroup& savedSettings);
bool getAdminOverride() const;
void setAdminOverride(bool b);
@@ -48,6 +71,7 @@ public:
void setTransition(); // sets the transition bit, which defaults to false
bool isInTransition() const;
+ bool canSetMaturity(S32 maturity);
private:
U8 mAccess; // SIM_ACCESS_MATURE etc
@@ -61,9 +85,7 @@ private:
// all of the code that depends on it.
bool mAOTransition;
- // we want this to be const but the getters for it aren't, so we're
- // overriding it for now
- /* const */ LLControlGroupReader& mSavedSettings;
+ LLControlGroup& mSavedSettings;
};
#endif // LL_LLAGENTACCESS_H
diff --git a/indra/newview/llagentlanguage.h b/indra/newview/llagentlanguage.h
index 596c584232..45348a1e50 100644
--- a/indra/newview/llagentlanguage.h
+++ b/indra/newview/llagentlanguage.h
@@ -33,7 +33,7 @@
#ifndef LL_LLAGENTLANGUAGE_H
#define LL_LLAGENTLANGUAGE_H
-#include "llmemory.h" // LLSingleton<>
+#include "llsingleton.h" // LLSingleton<>
#include "llevent.h"
class LLAgentLanguage: public LLSingleton<LLAgentLanguage>, public LLOldEvents::LLSimpleListener
diff --git a/indra/newview/llagentpilot.cpp b/indra/newview/llagentpilot.cpp
index 035c9426a1..8ffb97d8fc 100644
--- a/indra/newview/llagentpilot.cpp
+++ b/indra/newview/llagentpilot.cpp
@@ -38,13 +38,13 @@
#include "llagentpilot.h"
#include "llagent.h"
-#include "llframestats.h"
#include "llappviewer.h"
#include "llviewercontrol.h"
LLAgentPilot gAgentPilot;
BOOL LLAgentPilot::sLoop = TRUE;
+BOOL LLAgentPilot::sReplaySession = FALSE;
LLAgentPilot::LLAgentPilot() :
mNumRuns(-1),
@@ -177,6 +177,11 @@ void LLAgentPilot::stopPlayback()
mTimer.reset();
gAgent.stopAutoPilot();
}
+
+ if (sReplaySession)
+ {
+ LLAppViewer::instance()->forceQuit();
+ }
}
void LLAgentPilot::updateTarget()
@@ -198,7 +203,6 @@ void LLAgentPilot::updateTarget()
{
llinfos << "At start, beginning playback" << llendl;
mTimer.reset();
- LLFrameStats::startLogging(NULL);
mStarted = TRUE;
}
}
@@ -215,7 +219,6 @@ void LLAgentPilot::updateTarget()
else
{
stopPlayback();
- LLFrameStats::stopLogging(NULL);
mNumRuns--;
if (sLoop)
{
diff --git a/indra/newview/llagentpilot.h b/indra/newview/llagentpilot.h
index 0ad4772f68..dc034398a7 100644
--- a/indra/newview/llagentpilot.h
+++ b/indra/newview/llagentpilot.h
@@ -70,6 +70,7 @@ public:
static void startPlayback(void *);
static void stopPlayback(void *);
static BOOL sLoop;
+ static BOOL sReplaySession;
S32 mNumRuns;
BOOL mQuitAfterRuns;
diff --git a/indra/newview/llagentui.cpp b/indra/newview/llagentui.cpp
new file mode 100644
index 0000000000..1a69f1d975
--- /dev/null
+++ b/indra/newview/llagentui.cpp
@@ -0,0 +1,179 @@
+/**
+ * @file llagentui.cpp
+ * @brief Utility methods to process agent's data as slurl's etc. before displaying
+ *
+ * $LicenseInfo:firstyear=2009&license=viewergpl$
+ *
+ * Copyright (c) 2009, Linden Research, Inc.
+ *
+ * Second Life Viewer Source Code
+ * The source code in this file ("Source Code") is provided by Linden Lab
+ * to you under the terms of the GNU General Public License, version 2.0
+ * ("GPL"), unless you have obtained a separate licensing agreement
+ * ("Other License"), formally executed by you and Linden Lab. Terms of
+ * the GPL can be found in doc/GPL-license.txt in this distribution, or
+ * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
+ *
+ * There are special exceptions to the terms and conditions of the GPL as
+ * it is applied to this Source Code. View the full text of the exception
+ * in the file doc/FLOSS-exception.txt in this software distribution, or
+ * online at
+ * http://secondlifegrid.net/programs/open_source/licensing/flossexception
+ *
+ * By copying, modifying or distributing this software, you acknowledge
+ * that you have read and understood your obligations described above,
+ * and agree to abide by those obligations.
+ *
+ * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+ * COMPLETENESS OR PERFORMANCE.
+ * $/LicenseInfo$
+ */
+
+#include "llviewerprecompiledheaders.h"
+
+#include "llagentui.h"
+
+// Library includes
+#include "llparcel.h"
+
+// Viewer includes
+#include "llagent.h"
+#include "llviewercontrol.h"
+#include "llviewerregion.h"
+#include "llviewerparcelmgr.h"
+#include "llvoavatarself.h"
+#include "llslurl.h"
+
+//static
+void LLAgentUI::buildName(std::string& name)
+{
+ name.clear();
+
+ LLVOAvatarSelf* avatar_object = gAgent.getAvatarObject();
+ if (avatar_object)
+ {
+ LLNameValue *first_nv = avatar_object->getNVPair("FirstName");
+ LLNameValue *last_nv = avatar_object->getNVPair("LastName");
+ if (first_nv && last_nv)
+ {
+ name = first_nv->printData() + " " + last_nv->printData();
+ }
+ else
+ {
+ llwarns << "Agent is missing FirstName and/or LastName nv pair." << llendl;
+ }
+ }
+ else
+ {
+ name = gSavedSettings.getString("FirstName") + " " + gSavedSettings.getString("LastName");
+ }
+}
+
+//static
+void LLAgentUI::buildFullname(std::string& name)
+{
+ if (gAgent.getAvatarObject()) name = gAgent.getAvatarObject()->getFullname();
+}
+
+//static
+std::string LLAgentUI::buildSLURL(const bool escaped /*= true*/)
+{
+ std::string slurl;
+ LLViewerRegion *regionp = gAgent.getRegion();
+ if (regionp)
+ {
+ LLVector3d agentPos = gAgent.getPositionGlobal();
+ slurl = LLSLURL::buildSLURLfromPosGlobal(regionp->getName(), agentPos, escaped);
+ }
+ return slurl;
+}
+
+BOOL LLAgentUI::buildLocationString(std::string& str, ELocationFormat fmt,const LLVector3& agent_pos_region)
+{
+ LLViewerRegion* region = gAgent.getRegion();
+ LLParcel* parcel = LLViewerParcelMgr::getInstance()->getAgentParcel();
+
+ if (!region || !parcel) return FALSE;
+
+ S32 pos_x = S32(agent_pos_region.mV[VX]);
+ S32 pos_y = S32(agent_pos_region.mV[VY]);
+ S32 pos_z = S32(agent_pos_region.mV[VZ]);
+
+ // Round the numbers based on the velocity
+ F32 velocity_mag_sq = gAgent.getVelocity().magVecSquared();
+
+ const F32 FLY_CUTOFF = 6.f; // meters/sec
+ const F32 FLY_CUTOFF_SQ = FLY_CUTOFF * FLY_CUTOFF;
+ const F32 WALK_CUTOFF = 1.5f; // meters/sec
+ const F32 WALK_CUTOFF_SQ = WALK_CUTOFF * WALK_CUTOFF;
+
+ if (velocity_mag_sq > FLY_CUTOFF_SQ)
+ {
+ pos_x -= pos_x % 4;
+ pos_y -= pos_y % 4;
+ }
+ else if (velocity_mag_sq > WALK_CUTOFF_SQ)
+ {
+ pos_x -= pos_x % 2;
+ pos_y -= pos_y % 2;
+ }
+
+ // create a default name and description for the landmark
+ std::string parcel_name = LLViewerParcelMgr::getInstance()->getAgentParcelName();
+ std::string region_name = region->getName();
+ std::string buffer;
+ if( parcel_name.empty() )
+ {
+ // the parcel doesn't have a name
+ switch (fmt)
+ {
+ case LOCATION_FORMAT_LANDMARK:
+ buffer = llformat("%.100s", region_name.c_str());
+ break;
+ case LOCATION_FORMAT_NORMAL:
+ buffer = llformat("%s", region_name.c_str());
+ break;
+ case LOCATION_FORMAT_WITHOUT_SIM:
+ case LOCATION_FORMAT_FULL:
+ buffer = llformat("%s (%d, %d, %d)",
+ region_name.c_str(),
+ pos_x, pos_y, pos_z);
+ break;
+ }
+ }
+ else
+ {
+ // the parcel has a name, so include it in the landmark name
+ switch (fmt)
+ {
+ case LOCATION_FORMAT_LANDMARK:
+ buffer = llformat("%.100s", parcel_name.c_str());
+ break;
+ case LOCATION_FORMAT_NORMAL:
+ buffer = llformat("%s, %s", region_name.c_str(), parcel_name.c_str());
+ break;
+ case LOCATION_FORMAT_WITHOUT_SIM:
+ buffer = llformat("%s, %s (%d, %d, %d)",
+ region_name.c_str(),
+ parcel_name.c_str(),
+ pos_x, pos_y, pos_z);
+ break;
+ case LOCATION_FORMAT_FULL:
+ std::string sim_access_string = region->getSimAccessString();
+ buffer = llformat("%s, %s (%d, %d, %d)%s%s",
+ region_name.c_str(),
+ parcel_name.c_str(),
+ pos_x, pos_y, pos_z,
+ sim_access_string.empty() ? "" : " - ",
+ sim_access_string.c_str());
+ break;
+ }
+ }
+ str = buffer;
+ return TRUE;
+}
+BOOL LLAgentUI::buildLocationString(std::string& str, ELocationFormat fmt)
+{
+ return buildLocationString(str,fmt, gAgent.getPositionAgent());
+}
diff --git a/indra/newview/llagentui.h b/indra/newview/llagentui.h
new file mode 100644
index 0000000000..47ecb04547
--- /dev/null
+++ b/indra/newview/llagentui.h
@@ -0,0 +1,57 @@
+/**
+ * @file llagentui.h
+ * @brief Utility methods to process agent's data as slurl's etc. before displaying
+ *
+ * $LicenseInfo:firstyear=2009&license=viewergpl$
+ *
+ * Copyright (c) 2009, Linden Research, Inc.
+ *
+ * Second Life Viewer Source Code
+ * The source code in this file ("Source Code") is provided by Linden Lab
+ * to you under the terms of the GNU General Public License, version 2.0
+ * ("GPL"), unless you have obtained a separate licensing agreement
+ * ("Other License"), formally executed by you and Linden Lab. Terms of
+ * the GPL can be found in doc/GPL-license.txt in this distribution, or
+ * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
+ *
+ * There are special exceptions to the terms and conditions of the GPL as
+ * it is applied to this Source Code. View the full text of the exception
+ * in the file doc/FLOSS-exception.txt in this software distribution, or
+ * online at
+ * http://secondlifegrid.net/programs/open_source/licensing/flossexception
+ *
+ * By copying, modifying or distributing this software, you acknowledge
+ * that you have read and understood your obligations described above,
+ * and agree to abide by those obligations.
+ *
+ * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+ * COMPLETENESS OR PERFORMANCE.
+ * $/LicenseInfo$
+ */
+
+#ifndef LLAGENTUI_H
+#define LLAGENTUI_H
+
+class LLAgentUI
+{
+public:
+ enum ELocationFormat
+ {
+ LOCATION_FORMAT_NORMAL,
+ LOCATION_FORMAT_LANDMARK,
+ LOCATION_FORMAT_WITHOUT_SIM,
+ LOCATION_FORMAT_FULL,
+ };
+
+ static void buildName(std::string& name);
+ static void buildFullname(std::string &name);
+
+ static std::string buildSLURL(const bool escaped = true);
+ //build location string using the current position of gAgent.
+ static BOOL buildLocationString(std::string& str, ELocationFormat fmt = LOCATION_FORMAT_LANDMARK);
+ //build location string using a region position of the avatar.
+ static BOOL buildLocationString(std::string& str, ELocationFormat fmt,const LLVector3& agent_pos_region);
+};
+
+#endif //LLAGENTUI_H
diff --git a/indra/newview/llagentwearables.cpp b/indra/newview/llagentwearables.cpp
new file mode 100644
index 0000000000..0f735282cb
--- /dev/null
+++ b/indra/newview/llagentwearables.cpp
@@ -0,0 +1,1910 @@
+/**
+ * @file llagentwearables.cpp
+ * @brief LLAgentWearables class implementation
+ *
+ * $LicenseInfo:firstyear=2001&license=viewergpl$
+ *
+ * Copyright (c) 2001-2009, Linden Research, Inc.
+ *
+ * Second Life Viewer Source Code
+ * The source code in this file ("Source Code") is provided by Linden Lab
+ * to you under the terms of the GNU General Public License, version 2.0
+ * ("GPL"), unless you have obtained a separate licensing agreement
+ * ("Other License"), formally executed by you and Linden Lab. Terms of
+ * the GPL can be found in doc/GPL-license.txt in this distribution, or
+ * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
+ *
+ * There are special exceptions to the terms and conditions of the GPL as
+ * it is applied to this Source Code. View the full text of the exception
+ * in the file doc/FLOSS-exception.txt in this software distribution, or
+ * online at
+ * http://secondlifegrid.net/programs/open_source/licensing/flossexception
+ *
+ * By copying, modifying or distributing this software, you acknowledge
+ * that you have read and understood your obligations described above,
+ * and agree to abide by those obligations.
+ *
+ * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+ * COMPLETENESS OR PERFORMANCE.
+ * $/LicenseInfo$
+ */
+
+#include "llviewerprecompiledheaders.h"
+
+#include "llagent.h"
+#include "llagentwearables.h"
+
+#include "llfloatercustomize.h"
+#include "llfloaterinventory.h"
+#include "llinventorybridge.h"
+#include "llinventorymodel.h"
+#include "llnotify.h"
+#include "llviewerregion.h"
+#include "llvoavatarself.h"
+#include "llwearable.h"
+#include "llwearablelist.h"
+#include "llgesturemgr.h"
+
+#include <boost/scoped_ptr.hpp>
+
+#define USE_CURRENT_OUTFIT_FOLDER
+
+//--------------------------------------------------------------------
+// Classes for fetching initial wearables data
+//--------------------------------------------------------------------
+// Outfit folder fetching callback structure.
+class LLInitialWearablesFetch : public LLInventoryFetchDescendentsObserver
+{
+public:
+ LLInitialWearablesFetch() {}
+ ~LLInitialWearablesFetch() {}
+ virtual void done();
+
+ struct InitialWearableData
+ {
+ EWearableType mType;
+ U32 mIndex;
+ LLUUID mItemID;
+ LLUUID mAssetID;
+ InitialWearableData(EWearableType type, U32 index, LLUUID itemID, LLUUID assetID) :
+ mType(type), mIndex(index), mItemID(itemID), mAssetID(assetID) { }
+ };
+
+ typedef std::vector<InitialWearableData> initial_wearable_data_vec_t;
+ initial_wearable_data_vec_t mCOFInitialWearables; // Wearables from the Current Outfit Folder
+ initial_wearable_data_vec_t mAgentInitialWearables; // Wearables from the old agent wearables msg
+
+protected:
+ void processInitialWearables();
+};
+
+
+
+LLAgentWearables gAgentWearables;
+
+BOOL LLAgentWearables::mInitialWearablesUpdateReceived = FALSE;
+
+using namespace LLVOAvatarDefines;
+
+void LLAgentWearables::dump()
+{
+ llinfos << "LLAgentWearablesDump" << llendl;
+ for (S32 i = 0; i < WT_COUNT; i++)
+ {
+ U32 count = getWearableCount((EWearableType)i);
+ llinfos << "Type: " << i << " count " << count << llendl;
+ for (U32 j=0; j<count; j++)
+ {
+ LLWearable* wearable = getWearable((EWearableType)i,j);
+ if (wearable == NULL)
+ {
+ llinfos << " " << j << " NULL wearable" << llendl;
+ }
+ llinfos << " " << j << " Name " << wearable->getName()
+ << " description " << wearable->getDescription() << llendl;
+
+ }
+ }
+ llinfos << "Total items awaiting wearable update " << mItemsAwaitingWearableUpdate.size() << llendl;
+ for (std::set<LLUUID>::iterator it = mItemsAwaitingWearableUpdate.begin();
+ it != mItemsAwaitingWearableUpdate.end();
+ ++it)
+ {
+ llinfos << (*it).asString() << llendl;
+ }
+}
+
+// MULTI-WEARABLE: debugging
+struct LLAgentDumper
+{
+ LLAgentDumper(std::string name):
+ mName(name)
+ {
+ llinfos << llendl;
+ llinfos << "LLAgentDumper " << mName << llendl;
+ gAgentWearables.dump();
+ }
+
+ ~LLAgentDumper()
+ {
+ llinfos << llendl;
+ llinfos << "~LLAgentDumper " << mName << llendl;
+ gAgentWearables.dump();
+ }
+
+ std::string mName;
+};
+
+LLAgentWearables::LLAgentWearables() :
+ mWearablesLoaded(FALSE),
+ mAvatarObject(NULL)
+{
+ // MULTI-WEARABLE: TODO remove null entries.
+ for (U32 i = 0; i < WT_COUNT; i++)
+ {
+ mWearableDatas[(EWearableType)i].push_back(NULL);
+ }
+}
+
+LLAgentWearables::~LLAgentWearables()
+{
+ cleanup();
+}
+
+void LLAgentWearables::cleanup()
+{
+ mAvatarObject = NULL;
+}
+
+void LLAgentWearables::setAvatarObject(LLVOAvatarSelf *avatar)
+{
+ mAvatarObject = avatar;
+ if (avatar)
+ {
+ sendAgentWearablesRequest();
+ }
+}
+
+// wearables
+LLAgentWearables::createStandardWearablesAllDoneCallback::~createStandardWearablesAllDoneCallback()
+{
+ gAgentWearables.createStandardWearablesAllDone();
+}
+
+LLAgentWearables::sendAgentWearablesUpdateCallback::~sendAgentWearablesUpdateCallback()
+{
+ gAgentWearables.sendAgentWearablesUpdate();
+}
+
+/**
+ * @brief Construct a callback for dealing with the wearables.
+ *
+ * Would like to pass the agent in here, but we can't safely
+ * count on it being around later. Just use gAgent directly.
+ * @param cb callback to execute on completion (??? unused ???)
+ * @param type Type for the wearable in the agent
+ * @param wearable The wearable data.
+ * @param todo Bitmask of actions to take on completion.
+ */
+LLAgentWearables::addWearableToAgentInventoryCallback::addWearableToAgentInventoryCallback(
+ LLPointer<LLRefCount> cb, S32 type, U32 index, LLWearable* wearable, U32 todo) :
+ mType(type),
+ mIndex(index),
+ mWearable(wearable),
+ mTodo(todo),
+ mCB(cb)
+{
+}
+
+void LLAgentWearables::addWearableToAgentInventoryCallback::fire(const LLUUID& inv_item)
+{
+ if (inv_item.isNull())
+ return;
+
+ gAgentWearables.addWearabletoAgentInventoryDone(mType, mIndex, inv_item, mWearable);
+
+ if (mTodo & CALL_UPDATE)
+ {
+ gAgentWearables.sendAgentWearablesUpdate();
+ }
+ if (mTodo & CALL_RECOVERDONE)
+ {
+ gAgentWearables.recoverMissingWearableDone();
+ }
+ /*
+ * Do this for every one in the loop
+ */
+ if (mTodo & CALL_CREATESTANDARDDONE)
+ {
+ gAgentWearables.createStandardWearablesDone(mType, mIndex);
+ }
+ if (mTodo & CALL_MAKENEWOUTFITDONE)
+ {
+ gAgentWearables.makeNewOutfitDone(mType, mIndex);
+ }
+}
+
+void LLAgentWearables::addWearabletoAgentInventoryDone(const S32 type,
+ const U32 index,
+ const LLUUID& item_id,
+ LLWearable* wearable)
+{
+ if (item_id.isNull())
+ return;
+
+ LLUUID old_item_id = getWearableItemID((EWearableType)type,index);
+ if (wearable)
+ {
+ wearable->setItemID(item_id);
+ }
+ setWearable((EWearableType)type,index,wearable);
+
+ if (old_item_id.notNull())
+ gInventory.addChangedMask(LLInventoryObserver::LABEL, old_item_id);
+ gInventory.addChangedMask(LLInventoryObserver::LABEL, item_id);
+ LLViewerInventoryItem* item = gInventory.getItem(item_id);
+ if (item && wearable)
+ {
+ // We're changing the asset id, so we both need to set it
+ // locally via setAssetUUID() and via setTransactionID() which
+ // will be decoded on the server. JC
+ item->setAssetUUID(wearable->getAssetID());
+ item->setTransactionID(wearable->getTransactionID());
+ gInventory.addChangedMask(LLInventoryObserver::INTERNAL, item_id);
+ item->updateServer(FALSE);
+ }
+ gInventory.notifyObservers();
+}
+
+void LLAgentWearables::sendAgentWearablesUpdate()
+{
+ // MULTI-WEARABLE: call i "type" or something.
+ // First make sure that we have inventory items for each wearable
+ for (S32 i=0; i < WT_COUNT; ++i)
+ {
+ for (U32 j=0; j < getWearableCount((EWearableType)i); j++)
+ {
+ LLWearable* wearable = getWearable((EWearableType)i,j);
+ if (wearable)
+ {
+ if (wearable->getItemID().isNull())
+ {
+ LLPointer<LLInventoryCallback> cb =
+ new addWearableToAgentInventoryCallback(
+ LLPointer<LLRefCount>(NULL),
+ i,
+ j,
+ wearable,
+ addWearableToAgentInventoryCallback::CALL_NONE);
+ addWearableToAgentInventory(cb, wearable);
+ }
+ else
+ {
+ gInventory.addChangedMask(LLInventoryObserver::LABEL,
+ wearable->getItemID());
+ }
+ }
+ }
+ }
+
+ // Then make sure the inventory is in sync with the avatar.
+ gInventory.notifyObservers();
+
+ // Send the AgentIsNowWearing
+ gMessageSystem->newMessageFast(_PREHASH_AgentIsNowWearing);
+
+ gMessageSystem->nextBlockFast(_PREHASH_AgentData);
+ gMessageSystem->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
+ gMessageSystem->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
+
+ lldebugs << "sendAgentWearablesUpdate()" << llendl;
+ // MULTI-WEARABLE: update for multi-wearables after server-side support is in.
+ for (S32 i=0; i < WT_COUNT; ++i)
+ {
+ gMessageSystem->nextBlockFast(_PREHASH_WearableData);
+
+ U8 type_u8 = (U8)i;
+ gMessageSystem->addU8Fast(_PREHASH_WearableType, type_u8);
+
+ // MULTI-WEARABLE: TODO: hacked index to 0, needs to loop over all once messages support this.
+ LLWearable* wearable = getWearable((EWearableType)i, 0);
+ if (wearable)
+ {
+ //llinfos << "Sending wearable " << wearable->getName() << llendl;
+ gMessageSystem->addUUIDFast(_PREHASH_ItemID, wearable->getItemID());
+ }
+ else
+ {
+ //llinfos << "Not wearing wearable type " << LLWearableDictionary::getInstance()->getWearable((EWearableType)i) << llendl;
+ gMessageSystem->addUUIDFast(_PREHASH_ItemID, LLUUID::null);
+ }
+
+ lldebugs << " " << LLWearableDictionary::getTypeLabel((EWearableType)i) << ": " << (wearable ? wearable->getAssetID() : LLUUID::null) << llendl;
+ }
+ gAgent.sendReliableMessage();
+}
+
+// MULTI-WEARABLE: add index.
+void LLAgentWearables::saveWearable(const EWearableType type, const U32 index, BOOL send_update)
+{
+ LLWearable* old_wearable = getWearable(type, index);
+ if (old_wearable && (old_wearable->isDirty() || old_wearable->isOldVersion()))
+ {
+ LLUUID old_item_id = old_wearable->getItemID();
+ LLWearable* new_wearable = LLWearableList::instance().createCopyFromAvatar(old_wearable);
+ new_wearable->setItemID(old_item_id); // should this be in LLWearable::copyDataFrom()?
+ setWearable(type,index,new_wearable);
+
+ LLInventoryItem* item = gInventory.getItem(old_item_id);
+ if (item)
+ {
+ // Update existing inventory item
+ LLPointer<LLViewerInventoryItem> template_item =
+ new LLViewerInventoryItem(item->getUUID(),
+ item->getParentUUID(),
+ item->getPermissions(),
+ new_wearable->getAssetID(),
+ new_wearable->getAssetType(),
+ item->getInventoryType(),
+ item->getName(),
+ item->getDescription(),
+ item->getSaleInfo(),
+ item->getFlags(),
+ item->getCreationDate());
+ template_item->setTransactionID(new_wearable->getTransactionID());
+ template_item->updateServer(FALSE);
+ gInventory.updateItem(template_item);
+ }
+ else
+ {
+ // Add a new inventory item (shouldn't ever happen here)
+ U32 todo = addWearableToAgentInventoryCallback::CALL_NONE;
+ if (send_update)
+ {
+ todo |= addWearableToAgentInventoryCallback::CALL_UPDATE;
+ }
+ LLPointer<LLInventoryCallback> cb =
+ new addWearableToAgentInventoryCallback(
+ LLPointer<LLRefCount>(NULL),
+ (S32)type,
+ index,
+ new_wearable,
+ todo);
+ addWearableToAgentInventory(cb, new_wearable);
+ return;
+ }
+
+ gAgent.getAvatarObject()->wearableUpdated( type );
+
+ if (send_update)
+ {
+ sendAgentWearablesUpdate();
+ }
+ }
+}
+
+// MULTI-WEARABLE: add index
+void LLAgentWearables::saveWearableAs(const EWearableType type,
+ const U32 index,
+ const std::string& new_name,
+ BOOL save_in_lost_and_found)
+{
+ if (!isWearableCopyable(type, index))
+ {
+ llwarns << "LLAgent::saveWearableAs() not copyable." << llendl;
+ return;
+ }
+ LLWearable* old_wearable = getWearable(type, index);
+ if (!old_wearable)
+ {
+ llwarns << "LLAgent::saveWearableAs() no old wearable." << llendl;
+ return;
+ }
+
+ LLInventoryItem* item = gInventory.getItem(getWearableItemID(type,index));
+ if (!item)
+ {
+ llwarns << "LLAgent::saveWearableAs() no inventory item." << llendl;
+ return;
+ }
+ std::string trunc_name(new_name);
+ LLStringUtil::truncate(trunc_name, DB_INV_ITEM_NAME_STR_LEN);
+ LLWearable* new_wearable = LLWearableList::instance().createCopyFromAvatar(
+ old_wearable,
+ trunc_name);
+ LLPointer<LLInventoryCallback> cb =
+ new addWearableToAgentInventoryCallback(
+ LLPointer<LLRefCount>(NULL),
+ type,
+ index,
+ new_wearable,
+ addWearableToAgentInventoryCallback::CALL_UPDATE);
+ LLUUID category_id;
+ if (save_in_lost_and_found)
+ {
+ category_id = gInventory.findCategoryUUIDForType(
+ LLAssetType::AT_LOST_AND_FOUND);
+ }
+ else
+ {
+ // put in same folder as original
+ category_id = item->getParentUUID();
+ }
+
+ copy_inventory_item(
+ gAgent.getID(),
+ item->getPermissions().getOwner(),
+ item->getUUID(),
+ category_id,
+ new_name,
+ cb);
+}
+
+void LLAgentWearables::revertWearable(const EWearableType type, const U32 index)
+{
+ LLWearable* wearable = getWearable(type, index);
+ if (wearable)
+ {
+ wearable->writeToAvatar(TRUE);
+ }
+ gAgent.sendAgentSetAppearance();
+}
+
+void LLAgentWearables::saveAllWearables()
+{
+ //if (!gInventory.isLoaded())
+ //{
+ // return;
+ //}
+
+ for (S32 i=0; i < WT_COUNT; i++)
+ {
+ for (U32 j=0; j < getWearableCount((EWearableType)i); j++)
+ saveWearable((EWearableType)i, j, FALSE);
+ }
+ sendAgentWearablesUpdate();
+}
+
+// Called when the user changes the name of a wearable inventory item that is currently being worn.
+void LLAgentWearables::setWearableName(const LLUUID& item_id, const std::string& new_name)
+{
+ for (S32 i=0; i < WT_COUNT; i++)
+ {
+ for (U32 j=0; j < getWearableCount((EWearableType)i); j++)
+ {
+ LLUUID curr_item_id = getWearableItemID((EWearableType)i,j);
+ if (curr_item_id == item_id)
+ {
+ LLWearable* old_wearable = getWearable((EWearableType)i,j);
+ llassert(old_wearable);
+
+ std::string old_name = old_wearable->getName();
+ old_wearable->setName(new_name);
+ LLWearable* new_wearable = LLWearableList::instance().createCopy(old_wearable);
+ new_wearable->setItemID(item_id);
+ LLInventoryItem* item = gInventory.getItem(item_id);
+ if (item)
+ {
+ new_wearable->setPermissions(item->getPermissions());
+ }
+ old_wearable->setName(old_name);
+
+ setWearable((EWearableType)i,j,new_wearable);
+ sendAgentWearablesUpdate();
+ break;
+ }
+ }
+ }
+}
+
+
+BOOL LLAgentWearables::isWearableModifiable(EWearableType type, U32 index) const
+{
+ LLUUID item_id = getWearableItemID(type, index);
+ if (!item_id.isNull())
+ {
+ LLInventoryItem* item = gInventory.getItem(item_id);
+ if (item && item->getPermissions().allowModifyBy(gAgent.getID(),
+ gAgent.getGroupID()))
+ {
+ return TRUE;
+ }
+ }
+ return FALSE;
+}
+
+BOOL LLAgentWearables::isWearableCopyable(EWearableType type, U32 index) const
+{
+ LLUUID item_id = getWearableItemID(type, index);
+ if (!item_id.isNull())
+ {
+ LLInventoryItem* item = gInventory.getItem(item_id);
+ if (item && item->getPermissions().allowCopyBy(gAgent.getID(),
+ gAgent.getGroupID()))
+ {
+ return TRUE;
+ }
+ }
+ return FALSE;
+}
+
+/*
+ U32 LLAgentWearables::getWearablePermMask(EWearableType type)
+ {
+ LLUUID item_id = getWearableItemID(type);
+ if (!item_id.isNull())
+ {
+ LLInventoryItem* item = gInventory.getItem(item_id);
+ if (item)
+ {
+ return item->getPermissions().getMaskOwner();
+ }
+ }
+ return PERM_NONE;
+ }
+*/
+
+LLInventoryItem* LLAgentWearables::getWearableInventoryItem(EWearableType type, U32 index)
+{
+ LLUUID item_id = getWearableItemID(type,index);
+ LLInventoryItem* item = NULL;
+ if (item_id.notNull())
+ {
+ item = gInventory.getItem(item_id);
+ }
+ return item;
+}
+
+const LLWearable* LLAgentWearables::getWearableFromWearableItem(const LLUUID& item_id) const
+{
+ for (S32 i=0; i < WT_COUNT; i++)
+ {
+ for (U32 j=0; j < getWearableCount((EWearableType)i); j++)
+ {
+ LLUUID curr_item_id = getWearableItemID((EWearableType)i, j);
+ if (curr_item_id == item_id)
+ {
+ return getWearable((EWearableType)i, j);
+ }
+ }
+ }
+ return NULL;
+}
+
+void LLAgentWearables::sendAgentWearablesRequest()
+{
+ gMessageSystem->newMessageFast(_PREHASH_AgentWearablesRequest);
+ gMessageSystem->nextBlockFast(_PREHASH_AgentData);
+ gMessageSystem->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
+ gMessageSystem->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
+ gAgent.sendReliableMessage();
+}
+
+// MULTI-WEARABLE: update for multiple items per type.
+// Used to enable/disable menu items.
+// static
+BOOL LLAgentWearables::selfHasWearable(EWearableType type)
+{
+ // MULTI-WEARABLE: TODO could be getWearableCount > 0, once null entries have been eliminated.
+ return gAgentWearables.getWearable(type,0) != NULL;
+}
+
+LLWearable* LLAgentWearables::getWearable(const EWearableType type, U32 index)
+{
+ wearableentry_map_t::iterator wearable_iter = mWearableDatas.find(type);
+ if (wearable_iter == mWearableDatas.end())
+ {
+ return NULL;
+ }
+ wearableentry_vec_t& wearable_vec = wearable_iter->second;
+ if (index>=wearable_vec.size())
+ {
+ return NULL;
+ }
+ else
+ {
+ return wearable_vec[index];
+ }
+}
+
+void LLAgentWearables::setWearable(const EWearableType type, U32 index, LLWearable *wearable)
+{
+ wearableentry_map_t::iterator wearable_iter = mWearableDatas.find(type);
+ if (wearable_iter == mWearableDatas.end())
+ {
+ llwarns << "invalid type, type " << type << " index " << index << llendl;
+ return;
+ }
+ wearableentry_vec_t& wearable_vec = wearable_iter->second;
+ if (index>=wearable_vec.size())
+ {
+ llwarns << "invalid index, type " << type << " index " << index << llendl;
+ }
+ else
+ {
+ wearable_vec[index] = wearable;
+ }
+}
+
+const LLWearable* LLAgentWearables::getWearable(const EWearableType type, U32 index) const
+{
+ wearableentry_map_t::const_iterator wearable_iter = mWearableDatas.find(type);
+ if (wearable_iter == mWearableDatas.end())
+ {
+ return NULL;
+ }
+ const wearableentry_vec_t& wearable_vec = wearable_iter->second;
+ if (index>=wearable_vec.size())
+ {
+ return NULL;
+ }
+ else
+ {
+ return wearable_vec[index];
+ }
+}
+
+//MULTI-WEARABLE: this will give wrong values until we get rid of the "always one empty object" scheme.
+U32 LLAgentWearables::getWearableCount(const EWearableType type) const
+{
+ wearableentry_map_t::const_iterator wearable_iter = mWearableDatas.find(type);
+ if (wearable_iter == mWearableDatas.end())
+ {
+ return 0;
+ }
+ const wearableentry_vec_t& wearable_vec = wearable_iter->second;
+ return wearable_vec.size();
+}
+
+BOOL LLAgentWearables::itemUpdatePending(const LLUUID& item_id) const
+{
+ return mItemsAwaitingWearableUpdate.find(item_id) != mItemsAwaitingWearableUpdate.end();
+}
+
+U32 LLAgentWearables::itemUpdatePendingCount() const
+{
+ return mItemsAwaitingWearableUpdate.size();
+}
+
+const LLUUID LLAgentWearables::getWearableItemID(EWearableType type, U32 index) const
+{
+ const LLWearable *wearable = getWearable(type,index);
+ if (wearable)
+ return wearable->getItemID();
+ else
+ return LLUUID();
+}
+
+// Warning: include_linked_items = TRUE makes this operation expensive.
+BOOL LLAgentWearables::isWearingItem(const LLUUID& item_id, BOOL include_linked_items) const
+{
+ if (getWearableFromWearableItem(item_id) != NULL) return TRUE;
+ if (include_linked_items)
+ {
+ LLInventoryModel::item_array_t item_array;
+ gInventory.collectLinkedItems(item_id, item_array);
+ for (LLInventoryModel::item_array_t::iterator iter = item_array.begin();
+ iter != item_array.end();
+ iter++)
+ {
+ LLViewerInventoryItem *linked_item = (*iter);
+ const LLUUID &item_id = linked_item->getUUID();
+ if (getWearableFromWearableItem(item_id) != NULL) return TRUE;
+ }
+ }
+ return FALSE;
+}
+
+// MULTI-WEARABLE: update for multiple
+// static
+// ! BACKWARDS COMPATIBILITY ! When we stop supporting viewer1.23, we can assume
+// that viewers have a Current Outfit Folder and won't need this message, and thus
+// we can remove/ignore this whole function.
+void LLAgentWearables::processAgentInitialWearablesUpdate(LLMessageSystem* mesgsys, void** user_data)
+{
+ // We should only receive this message a single time. Ignore subsequent AgentWearablesUpdates
+ // that may result from AgentWearablesRequest having been sent more than once.
+ if (mInitialWearablesUpdateReceived)
+ return;
+ mInitialWearablesUpdateReceived = true;
+
+ LLUUID agent_id;
+ gMessageSystem->getUUIDFast(_PREHASH_AgentData, _PREHASH_AgentID, agent_id);
+
+ LLVOAvatar* avatar = gAgent.getAvatarObject();
+ if (avatar && (agent_id == avatar->getID()))
+ {
+ gMessageSystem->getU32Fast(_PREHASH_AgentData, _PREHASH_SerialNum, gAgentQueryManager.mUpdateSerialNum);
+
+ S32 num_wearables = gMessageSystem->getNumberOfBlocksFast(_PREHASH_WearableData);
+ if (num_wearables < 4)
+ {
+ // Transitional state. Avatars should always have at least their body parts (hair, eyes, shape and skin).
+ // The fact that they don't have any here (only a dummy is sent) implies that this account existed
+ // before we had wearables, or that the database has gotten messed up.
+ return;
+ }
+
+ // Get the UUID of the current outfit folder (will be created if it doesn't exist)
+ LLUUID current_outfit_id = gInventory.findCategoryUUIDForType(LLAssetType::AT_CURRENT_OUTFIT);
+
+ LLInitialWearablesFetch* outfit = new LLInitialWearablesFetch();
+
+ //lldebugs << "processAgentInitialWearablesUpdate()" << llendl;
+ // Add wearables
+ // MULTI-WEARABLE: TODO: update once messages change. Currently use results to populate the zeroth element.
+ gAgentWearables.mItemsAwaitingWearableUpdate.clear();
+ for (S32 i=0; i < num_wearables; i++)
+ {
+ // Parse initial werables data from message system
+ U8 type_u8 = 0;
+ gMessageSystem->getU8Fast(_PREHASH_WearableData, _PREHASH_WearableType, type_u8, i);
+ if (type_u8 >= WT_COUNT)
+ {
+ continue;
+ }
+ const EWearableType type = (EWearableType) type_u8;
+
+ LLUUID item_id;
+ gMessageSystem->getUUIDFast(_PREHASH_WearableData, _PREHASH_ItemID, item_id, i);
+
+ LLUUID asset_id;
+ gMessageSystem->getUUIDFast(_PREHASH_WearableData, _PREHASH_AssetID, asset_id, i);
+ if (asset_id.isNull())
+ {
+ LLWearable::removeFromAvatar(type, FALSE);
+ }
+ else
+ {
+ LLAssetType::EType asset_type = LLWearableDictionary::getAssetType(type);
+ if (asset_type == LLAssetType::AT_NONE)
+ {
+ continue;
+ }
+
+ // MULTI-WEARABLE: TODO: update once messages change. Currently use results to populate the zeroth element.
+
+ // Store initial wearables data until we know whether we have the current outfit folder or need to use the data.
+ LLInitialWearablesFetch::InitialWearableData wearable_data(type, 0, item_id, asset_id); // MULTI-WEARABLE: update
+ outfit->mAgentInitialWearables.push_back(wearable_data);
+
+ }
+
+ lldebugs << " " << LLWearableDictionary::getTypeLabel(type) << llendl;
+ }
+
+ // What we do here is get the complete information on the items in
+ // the inventory, and set up an observer that will wait for that to
+ // happen.
+ LLInventoryFetchDescendentsObserver::folder_ref_t folders;
+ folders.push_back(current_outfit_id);
+ outfit->fetchDescendents(folders);
+ if(outfit->isEverythingComplete())
+ {
+ // everything is already here - call done.
+ outfit->done();
+ }
+ else
+ {
+ // it's all on it's way - add an observer, and the inventory
+ // will call done for us when everything is here.
+ gInventory.addObserver(outfit);
+ }
+ }
+}
+
+// A single wearable that the avatar was wearing on start-up has arrived from the database.
+// static
+void LLAgentWearables::onInitialWearableAssetArrived(LLWearable* wearable, void* userdata)
+{
+ boost::scoped_ptr<LLInitialWearablesFetch::InitialWearableData> wear_data((LLInitialWearablesFetch::InitialWearableData*)userdata);
+ const EWearableType type = wear_data->mType;
+ const U32 index = wear_data->mIndex;
+
+ LLVOAvatarSelf* avatar = gAgent.getAvatarObject();
+ if (!avatar)
+ {
+ return;
+ }
+
+ if (wearable)
+ {
+ llassert(type == wearable->getType());
+ // MULTI-WEARABLE: is this always zeroth element? Change sometime.
+ wearable->setItemID(wear_data->mItemID);
+ gAgentWearables.setWearable(type, index, wearable);
+ gAgentWearables.mItemsAwaitingWearableUpdate.erase(wear_data->mItemID);
+
+ // disable composites if initial textures are baked
+ avatar->setupComposites();
+
+ wearable->writeToAvatar(FALSE);
+ avatar->setCompositeUpdatesEnabled(TRUE);
+ gInventory.addChangedMask(LLInventoryObserver::LABEL, wearable->getItemID());
+ }
+ else
+ {
+ // Somehow the asset doesn't exist in the database.
+ // MULTI-WEARABLE: assuming zeroth elt
+ gAgentWearables.recoverMissingWearable(type,index);
+ }
+
+ gInventory.notifyObservers();
+
+ // Have all the wearables that the avatar was wearing at log-in arrived?
+ // MULTI-WEARABLE: update when multiple wearables can arrive per type.
+
+ gAgentWearables.updateWearablesLoaded();
+ if (gAgentWearables.areWearablesLoaded())
+ {
+
+ // Can't query cache until all wearables have arrived, so calling this earlier is a no-op.
+ gAgentWearables.queryWearableCache();
+
+ // Make sure that the server's idea of the avatar's wearables actually match the wearables.
+ gAgent.sendAgentSetAppearance();
+
+ // Check to see if there are any baked textures that we hadn't uploaded before we logged off last time.
+ // If there are any, schedule them to be uploaded as soon as the layer textures they depend on arrive.
+ if (gAgent.cameraCustomizeAvatar())
+ {
+ avatar->requestLayerSetUploads();
+ }
+ }
+}
+
+// Normally, all wearables referred to "AgentWearablesUpdate" will correspond to actual assets in the
+// database. If for some reason, we can't load one of those assets, we can try to reconstruct it so that
+// the user isn't left without a shape, for example. (We can do that only after the inventory has loaded.)
+void LLAgentWearables::recoverMissingWearable(const EWearableType type, U32 index)
+{
+ // Try to recover by replacing missing wearable with a new one.
+ LLNotifications::instance().add("ReplacedMissingWearable");
+ lldebugs << "Wearable " << LLWearableDictionary::getTypeLabel(type) << " could not be downloaded. Replaced inventory item with default wearable." << llendl;
+ LLWearable* new_wearable = LLWearableList::instance().createNewWearable(type);
+
+ S32 type_s32 = (S32) type;
+ setWearable(type,index,new_wearable);
+ new_wearable->writeToAvatar(TRUE);
+
+ // Add a new one in the lost and found folder.
+ // (We used to overwrite the "not found" one, but that could potentially
+ // destory content.) JC
+ LLUUID lost_and_found_id =
+ gInventory.findCategoryUUIDForType(LLAssetType::AT_LOST_AND_FOUND);
+ LLPointer<LLInventoryCallback> cb =
+ new addWearableToAgentInventoryCallback(
+ LLPointer<LLRefCount>(NULL),
+ type_s32,
+ index,
+ new_wearable,
+ addWearableToAgentInventoryCallback::CALL_RECOVERDONE);
+ addWearableToAgentInventory(cb, new_wearable, lost_and_found_id, TRUE);
+}
+
+void LLAgentWearables::recoverMissingWearableDone()
+{
+ // Have all the wearables that the avatar was wearing at log-in arrived or been fabricated?
+ updateWearablesLoaded();
+ if (areWearablesLoaded())
+ {
+ // Make sure that the server's idea of the avatar's wearables actually match the wearables.
+ gAgent.sendAgentSetAppearance();
+ }
+ else
+ {
+ gInventory.addChangedMask(LLInventoryObserver::LABEL, LLUUID::null);
+ gInventory.notifyObservers();
+ }
+}
+
+void LLAgentWearables::addLocalTextureObject(const EWearableType wearable_type, const LLVOAvatarDefines::ETextureIndex texture_type, U32 wearable_index)
+{
+ LLWearable* wearable = getWearable((EWearableType)wearable_type, wearable_index);
+ if (!wearable)
+ {
+ llerrs << "Tried to add local texture object to invalid wearable with type " << wearable_type << " and index " << wearable_index << llendl;
+ }
+
+ wearable->setLocalTextureObject(texture_type, new LLLocalTextureObject());
+}
+
+void LLAgentWearables::createStandardWearables(BOOL female)
+{
+ llwarns << "Creating Standard " << (female ? "female" : "male")
+ << " Wearables" << llendl;
+
+ if (mAvatarObject.isNull())
+ {
+ return;
+ }
+
+ mAvatarObject->setSex(female ? SEX_FEMALE : SEX_MALE);
+
+ const BOOL create[WT_COUNT] =
+ {
+ TRUE, //WT_SHAPE
+ TRUE, //WT_SKIN
+ TRUE, //WT_HAIR
+ TRUE, //WT_EYES
+ TRUE, //WT_SHIRT
+ TRUE, //WT_PANTS
+ TRUE, //WT_SHOES
+ TRUE, //WT_SOCKS
+ FALSE, //WT_JACKET
+ FALSE, //WT_GLOVES
+ TRUE, //WT_UNDERSHIRT
+ TRUE, //WT_UNDERPANTS
+ FALSE //WT_SKIRT
+ };
+
+ for (S32 i=0; i < WT_COUNT; i++)
+ {
+ bool once = false;
+ LLPointer<LLRefCount> donecb = NULL;
+ if (create[i])
+ {
+ if (!once)
+ {
+ once = true;
+ donecb = new createStandardWearablesAllDoneCallback;
+ }
+ // MULTI_WEARABLE: only elt 0, may be the right thing?
+ llassert(getWearable((EWearableType)i,0) == NULL);
+ LLWearable* wearable = LLWearableList::instance().createNewWearable((EWearableType)i);
+ setWearable((EWearableType)i,0,wearable);
+ // no need to update here...
+ // MULTI_WEARABLE: hardwired index = 0 here.
+ LLPointer<LLInventoryCallback> cb =
+ new addWearableToAgentInventoryCallback(
+ donecb,
+ i,
+ 0,
+ wearable,
+ addWearableToAgentInventoryCallback::CALL_CREATESTANDARDDONE);
+ addWearableToAgentInventory(cb, wearable, LLUUID::null, FALSE);
+ }
+ }
+}
+
+void LLAgentWearables::createStandardWearablesDone(S32 type, U32 index)
+{
+ LLWearable* wearable = getWearable((EWearableType)type, index);
+
+ if (wearable)
+ {
+ wearable->writeToAvatar(TRUE);
+ }
+}
+
+void LLAgentWearables::createStandardWearablesAllDone()
+{
+ // ... because sendAgentWearablesUpdate will notify inventory
+ // observers.
+ mWearablesLoaded = TRUE;
+ checkWearablesLoaded();
+
+ updateServer();
+
+ // Treat this as the first texture entry message, if none received yet
+ mAvatarObject->onFirstTEMessageReceived();
+}
+
+void LLAgentWearables::getAllWearablesArray(LLDynamicArray<S32>& wearables)
+{
+ for( S32 i = 0; i < WT_COUNT; ++i )
+ {
+ // MULTI-WEARABLE: Properly handle multiwearables later.
+ if (getWearable( (EWearableType) i, 0 ) != NULL)
+ {
+ wearables.push_back(i);
+ }
+ }
+}
+
+// Note: wearables_to_include should be a list of EWearableType types
+// attachments_to_include should be a list of attachment points
+void LLAgentWearables::makeNewOutfit(const std::string& new_folder_name,
+ const LLDynamicArray<S32>& wearables_to_include,
+ const LLDynamicArray<S32>& attachments_to_include,
+ BOOL rename_clothing)
+{
+ if (mAvatarObject.isNull())
+ {
+ return;
+ }
+
+ // First, make a folder in the Clothes directory.
+ LLUUID folder_id = gInventory.createNewCategory(
+ gInventory.findCategoryUUIDForType(LLAssetType::AT_CLOTHING),
+ LLAssetType::AT_NONE,
+ new_folder_name);
+
+ bool found_first_item = false;
+
+ ///////////////////
+ // Wearables
+
+ if (wearables_to_include.count())
+ {
+ // Then, iterate though each of the wearables and save copies of them in the folder.
+ S32 i;
+ S32 count = wearables_to_include.count();
+ LLDynamicArray<LLUUID> delete_items;
+ LLPointer<LLRefCount> cbdone = NULL;
+ for (i = 0; i < count; ++i)
+ {
+ const S32 type = wearables_to_include[i];
+ for (U32 j=0; j<getWearableCount((EWearableType)i); j++)
+ {
+ LLWearable* old_wearable = getWearable((EWearableType)type, j);
+ if (old_wearable)
+ {
+ std::string new_name;
+ LLWearable* new_wearable;
+ new_wearable = LLWearableList::instance().createCopy(old_wearable);
+ if (rename_clothing)
+ {
+ new_name = new_folder_name;
+ new_name.append(" ");
+ new_name.append(old_wearable->getTypeLabel());
+ LLStringUtil::truncate(new_name, DB_INV_ITEM_NAME_STR_LEN);
+ new_wearable->setName(new_name);
+ }
+
+ LLViewerInventoryItem* item = gInventory.getItem(getWearableItemID((EWearableType)type,j));
+ S32 todo = addWearableToAgentInventoryCallback::CALL_NONE;
+ if (!found_first_item)
+ {
+ found_first_item = true;
+ /* set the focus to the first item */
+ todo |= addWearableToAgentInventoryCallback::CALL_MAKENEWOUTFITDONE;
+ /* send the agent wearables update when done */
+ cbdone = new sendAgentWearablesUpdateCallback;
+ }
+ LLPointer<LLInventoryCallback> cb =
+ new addWearableToAgentInventoryCallback(
+ cbdone,
+ type,
+ j,
+ new_wearable,
+ todo);
+ if (isWearableCopyable((EWearableType)type, j))
+ {
+ copy_inventory_item(
+ gAgent.getID(),
+ item->getPermissions().getOwner(),
+ item->getUUID(),
+ folder_id,
+ new_name,
+ cb);
+ }
+ else
+ {
+ move_inventory_item(
+ gAgent.getID(),
+ gAgent.getSessionID(),
+ item->getUUID(),
+ folder_id,
+ new_name,
+ cb);
+ }
+ }
+ }
+ }
+ gInventory.notifyObservers();
+ }
+
+
+ ///////////////////
+ // Attachments
+
+ if (attachments_to_include.count())
+ {
+ BOOL msg_started = FALSE;
+ LLMessageSystem* msg = gMessageSystem;
+ for (S32 i = 0; i < attachments_to_include.count(); i++)
+ {
+ S32 attachment_pt = attachments_to_include[i];
+ LLViewerJointAttachment* attachment = get_if_there(mAvatarObject->mAttachmentPoints, attachment_pt, (LLViewerJointAttachment*)NULL);
+ if (!attachment) continue;
+ LLViewerObject* attached_object = attachment->getObject();
+ if (!attached_object) continue;
+ const LLUUID& item_id = attachment->getItemID();
+ if (item_id.isNull()) continue;
+ LLInventoryItem* item = gInventory.getItem(item_id);
+ if (!item) continue;
+ if (!msg_started)
+ {
+ msg_started = TRUE;
+ msg->newMessage("CreateNewOutfitAttachments");
+ msg->nextBlock("AgentData");
+ msg->addUUID("AgentID", gAgent.getID());
+ msg->addUUID("SessionID", gAgent.getSessionID());
+ msg->nextBlock("HeaderData");
+ msg->addUUID("NewFolderID", folder_id);
+ }
+ msg->nextBlock("ObjectData");
+ msg->addUUID("OldItemID", item_id);
+ msg->addUUID("OldFolderID", item->getParentUUID());
+ }
+
+ if (msg_started)
+ {
+ gAgent.sendReliableMessage();
+ }
+
+ }
+}
+
+LLUUID LLAgentWearables::makeNewOutfitLinks(const std::string& new_folder_name)
+{
+ if (mAvatarObject.isNull())
+ {
+ return LLUUID::null;
+ }
+
+ LLDynamicArray<S32> wearables_to_include;
+ getAllWearablesArray(wearables_to_include);
+
+ LLDynamicArray<S32> attachments_to_include;
+ mAvatarObject->getAllAttachmentsArray(attachments_to_include);
+
+ return makeNewOutfitLinks(new_folder_name, wearables_to_include, attachments_to_include);
+}
+
+// Note: wearables_to_include should be a list of EWearableType types
+// attachments_to_include should be a list of attachment points
+LLUUID LLAgentWearables::makeNewOutfitLinks(const std::string& new_folder_name,
+ const LLDynamicArray<S32>& wearables_to_include,
+ const LLDynamicArray<S32>& attachments_to_include)
+{
+ if (mAvatarObject.isNull())
+ {
+ return LLUUID::null;
+ }
+
+ // First, make a folder in the Clothes directory.
+ LLUUID folder_id = gInventory.createNewCategory(
+ gInventory.findCategoryUUIDForType(LLAssetType::AT_MY_OUTFITS),
+ LLAssetType::AT_OUTFIT,
+ new_folder_name);
+
+// bool found_first_item = false;
+
+ ///////////////////
+ // Wearables
+
+ if (wearables_to_include.count())
+ {
+ // Then, iterate though each of the wearables and save links to them in the folder.
+ S32 i;
+ S32 count = wearables_to_include.count();
+ LLDynamicArray<LLUUID> delete_items;
+ LLPointer<LLRefCount> cbdone = NULL;
+ for (i = 0; i < count; ++i)
+ {
+ const S32 type = wearables_to_include[i];
+ for (U32 j=0; j<getWearableCount((EWearableType)i); j++)
+ {
+ LLWearable* old_wearable = getWearable((EWearableType)type,j);
+ if (old_wearable)
+ {
+ LLViewerInventoryItem* item = gInventory.getItem(getWearableItemID((EWearableType) type, j));
+ if (!item) continue;
+ LLPointer<LLInventoryCallback> cb = NULL;
+ link_inventory_item(gAgent.getID(),
+ item->getUUID(),
+ folder_id,
+ item->getName(),
+ LLAssetType::AT_LINK,
+ cb);
+ }
+ }
+ }
+ gInventory.notifyObservers();
+ }
+
+
+ ///////////////////
+ // Attachments
+
+ if (attachments_to_include.count())
+ {
+ for (S32 i = 0; i < attachments_to_include.count(); i++)
+ {
+ S32 attachment_pt = attachments_to_include[i];
+ LLViewerJointAttachment* attachment = get_if_there(mAvatarObject->mAttachmentPoints, attachment_pt, (LLViewerJointAttachment*)NULL);
+ if (!attachment) continue;
+ LLViewerObject* attached_object = attachment->getObject();
+ if (!attached_object) continue;
+ const LLUUID& item_id = attachment->getItemID();
+ if (item_id.isNull()) continue;
+ LLInventoryItem* item = gInventory.getItem(item_id);
+ if (!item) continue;
+
+ LLPointer<LLInventoryCallback> cb = NULL;
+ link_inventory_item(gAgent.getID(),
+ item->getUUID(),
+ folder_id,
+ item->getName(),
+ LLAssetType::AT_LINK,
+ cb);
+ }
+ }
+
+ ///////////////////
+ // Gestures
+
+ /* Disabling this for now, otherwise this adds all your default gestures and all previous
+ active gestures. Need to rethink the intended behavior.
+ for (LLGestureManager::item_map_t::iterator iter = LLGestureManager::instance().mActive.begin();
+ iter != LLGestureManager::instance().mActive.end();
+ ++iter)
+ {
+ const LLUUID &gesture_id = (*iter).first;
+ LLViewerInventoryItem* item = gInventory.getItem(gesture_id);
+ if (item)
+ {
+ LLPointer<LLInventoryCallback> cb = NULL;
+ link_inventory_item(gAgent.getID(),
+ item->getUUID(),
+ folder_id,
+ item->getName(),
+ LLAssetType::AT_LINK,
+ cb);
+ }
+ }
+ */
+
+ return folder_id;
+}
+
+void LLAgentWearables::makeNewOutfitDone(S32 type, U32 index)
+{
+ LLUUID first_item_id = getWearableItemID((EWearableType)type, index);
+ // Open the inventory and select the first item we added.
+ if (first_item_id.notNull())
+ {
+ LLFloaterInventory* view = LLFloaterInventory::getActiveInventory();
+ if (view)
+ {
+ view->getPanel()->setSelection(first_item_id, TAKE_FOCUS_NO);
+ }
+ }
+}
+
+
+void LLAgentWearables::addWearableToAgentInventory(LLPointer<LLInventoryCallback> cb,
+ LLWearable* wearable,
+ const LLUUID& category_id,
+ BOOL notify)
+{
+ create_inventory_item(gAgent.getID(),
+ gAgent.getSessionID(),
+ category_id,
+ wearable->getTransactionID(),
+ wearable->getName(),
+ wearable->getDescription(),
+ wearable->getAssetType(),
+ LLInventoryType::IT_WEARABLE,
+ wearable->getType(),
+ wearable->getPermissions().getMaskNextOwner(),
+ cb);
+}
+
+void LLAgentWearables::removeWearable(const EWearableType type, bool do_remove_all, U32 index)
+{
+
+ if (do_remove_all)
+ {
+ removeWearableFinal(type, do_remove_all, index);
+ }
+ else
+ {
+// MULTI_WEARABLE: handle vector changes from arbitrary removal.
+ LLWearable* old_wearable = getWearable(type,index);
+
+ if ((gAgent.isTeen())
+ && (type == WT_UNDERSHIRT || type == WT_UNDERPANTS))
+ {
+ // Can't take off underclothing in simple UI mode or on PG accounts
+ return;
+ }
+
+ if (old_wearable)
+ {
+ if (old_wearable->isDirty())
+ {
+ LLSD payload;
+ payload["wearable_type"] = (S32)type;
+ // Bring up view-modal dialog: Save changes? Yes, No, Cancel
+ LLNotifications::instance().add("WearableSave", LLSD(), payload, &LLAgentWearables::onRemoveWearableDialog);
+ return;
+ }
+ else
+ {
+ removeWearableFinal(type, do_remove_all, index);
+ }
+ }
+ }
+}
+
+
+// MULTI_WEARABLE: assuming one wearable per type.
+// MULTI_WEARABLE: hardwiring 0th elt for now - notification needs to change.
+// static
+bool LLAgentWearables::onRemoveWearableDialog(const LLSD& notification, const LLSD& response)
+{
+ S32 option = LLNotification::getSelectedOption(notification, response);
+ EWearableType type = (EWearableType)notification["payload"]["wearable_type"].asInteger();
+ switch(option)
+ {
+ case 0: // "Save"
+ gAgentWearables.saveWearable(type, 0);
+ gAgentWearables.removeWearableFinal(type, false, 0);
+ break;
+
+ case 1: // "Don't Save"
+ gAgentWearables.removeWearableFinal(type, false, 0);
+ break;
+
+ case 2: // "Cancel"
+ break;
+
+ default:
+ llassert(0);
+ break;
+ }
+ return false;
+}
+
+// Called by removeWearable() and onRemoveWearableDialog() to actually do the removal.
+void LLAgentWearables::removeWearableFinal(const EWearableType type, bool do_remove_all, U32 index)
+{
+ //LLAgentDumper dumper("removeWearable");
+ if (do_remove_all)
+ {
+ S32 max_entry = mWearableDatas[type].size()-1;
+ for (S32 i=max_entry; i>=0; i--)
+ {
+ LLWearable* old_wearable = getWearable(type,i);
+ gInventory.addChangedMask(LLInventoryObserver::LABEL, getWearableItemID(type,i));
+ setWearable(type,i,NULL);
+
+ //queryWearableCache(); // moved below
+ // MULTI_WEARABLE: FIXME - currently we keep a null entry, so can't delete the last one.
+ if (i>0)
+ {
+ mWearableDatas[type].pop_back();
+ }
+ if (old_wearable)
+ {
+ old_wearable->removeFromAvatar(TRUE);
+ }
+ }
+ }
+ else
+ {
+ LLWearable* old_wearable = getWearable(type, index);
+
+ gInventory.addChangedMask(LLInventoryObserver::LABEL, getWearableItemID(type,index));
+ setWearable(type,index,NULL);
+
+ //queryWearableCache(); // moved below
+
+ if (old_wearable)
+ {
+ old_wearable->removeFromAvatar(TRUE);
+ }
+
+ // MULTI_WEARABLE: logic changes if null entries go away
+ if (getWearableCount(type)>1)
+ {
+ // Have to shrink the vector and clean up the item.
+ wearableentry_map_t::iterator wearable_iter = mWearableDatas.find(type);
+ llassert_always(wearable_iter != mWearableDatas.end());
+ wearableentry_vec_t& wearable_vec = wearable_iter->second;
+ wearable_vec.erase( wearable_vec.begin() + index );
+ }
+ }
+
+ queryWearableCache();
+
+ // Update the server
+ updateServer();
+ gInventory.notifyObservers();
+}
+
+// Assumes existing wearables are not dirty.
+// MULTI_WEARABLE: assumes one wearable per type.
+void LLAgentWearables::setWearableOutfit(const LLInventoryItem::item_array_t& items,
+ const LLDynamicArray< LLWearable* >& wearables,
+ BOOL remove)
+{
+ lldebugs << "setWearableOutfit() start" << llendl;
+
+ BOOL wearables_to_remove[WT_COUNT];
+ wearables_to_remove[WT_SHAPE] = FALSE;
+ wearables_to_remove[WT_SKIN] = FALSE;
+ wearables_to_remove[WT_HAIR] = FALSE;
+ wearables_to_remove[WT_EYES] = FALSE;
+ wearables_to_remove[WT_SHIRT] = remove;
+ wearables_to_remove[WT_PANTS] = remove;
+ wearables_to_remove[WT_SHOES] = remove;
+ wearables_to_remove[WT_SOCKS] = remove;
+ wearables_to_remove[WT_JACKET] = remove;
+ wearables_to_remove[WT_GLOVES] = remove;
+ wearables_to_remove[WT_UNDERSHIRT] = (!gAgent.isTeen()) & remove;
+ wearables_to_remove[WT_UNDERPANTS] = (!gAgent.isTeen()) & remove;
+ wearables_to_remove[WT_SKIRT] = remove;
+
+ S32 count = wearables.count();
+ llassert(items.count() == count);
+
+ S32 i;
+ for (i = 0; i < count; i++)
+ {
+ LLWearable* new_wearable = wearables[i];
+ LLPointer<LLInventoryItem> new_item = items[i];
+
+ const EWearableType type = new_wearable->getType();
+ wearables_to_remove[type] = FALSE;
+
+ // MULTI_WEARABLE: using 0th
+ LLWearable* old_wearable = getWearable(type, 0);
+ if (old_wearable)
+ {
+ const LLUUID& old_item_id = getWearableItemID(type, 0);
+ if ((old_wearable->getAssetID() == new_wearable->getAssetID()) &&
+ (old_item_id == new_item->getUUID()))
+ {
+ lldebugs << "No change to wearable asset and item: " << LLWearableDictionary::getInstance()->getWearableEntry(type) << llendl;
+ continue;
+ }
+
+ gInventory.addChangedMask(LLInventoryObserver::LABEL, old_item_id);
+
+ // Assumes existing wearables are not dirty.
+ if (old_wearable->isDirty())
+ {
+ llassert(0);
+ continue;
+ }
+ }
+
+ setWearable(type,0,new_wearable);
+ if (new_wearable)
+ new_wearable->setItemID(new_item->getUUID());
+ }
+
+ std::vector<LLWearable*> wearables_being_removed;
+
+ for (i = 0; i < WT_COUNT; i++)
+ {
+ if (wearables_to_remove[i])
+ {
+ // MULTI_WEARABLE: assuming 0th
+ LLWearable* wearable = getWearable((EWearableType)i, 0);
+ gInventory.addChangedMask(LLInventoryObserver::LABEL, getWearableItemID((EWearableType)i,0));
+ if (wearable)
+ {
+ wearables_being_removed.push_back(wearable);
+ }
+ setWearable((EWearableType)i,0,NULL);
+ }
+ }
+
+ gInventory.notifyObservers();
+
+ queryWearableCache();
+
+ std::vector<LLWearable*>::iterator wearable_iter;
+
+ for (wearable_iter = wearables_being_removed.begin();
+ wearable_iter != wearables_being_removed.end();
+ ++wearable_iter)
+ {
+ LLWearable* wearablep = *wearable_iter;
+ if (wearablep)
+ {
+ wearablep->removeFromAvatar(TRUE);
+ }
+ }
+
+ for (i = 0; i < count; i++)
+ {
+ wearables[i]->writeToAvatar(TRUE);
+ }
+
+ // Start rendering & update the server
+ mWearablesLoaded = TRUE;
+ checkWearablesLoaded();
+ updateServer();
+
+ lldebugs << "setWearableOutfit() end" << llendl;
+}
+
+
+// User has picked "wear on avatar" from a menu.
+void LLAgentWearables::setWearableItem(LLInventoryItem* new_item, LLWearable* new_wearable, bool do_append)
+{
+ //LLAgentDumper dumper("setWearableItem");
+ if (isWearingItem(new_item->getUUID()))
+ {
+ llwarns << "wearable " << new_item->getUUID() << " is already worn" << llendl;
+ return;
+ }
+
+ const EWearableType type = new_wearable->getType();
+
+ if (!do_append)
+ {
+ // Remove old wearable, if any
+ // MULTI_WEARABLE: hardwired to 0
+ LLWearable* old_wearable = getWearable(type,0);
+ if (old_wearable)
+ {
+ const LLUUID& old_item_id = old_wearable->getItemID();
+ if ((old_wearable->getAssetID() == new_wearable->getAssetID()) &&
+ (old_item_id == new_item->getUUID()))
+ {
+ lldebugs << "No change to wearable asset and item: " << LLWearableDictionary::getInstance()->getWearableEntry(type) << llendl;
+ return;
+ }
+
+ if (old_wearable->isDirty())
+ {
+ // Bring up modal dialog: Save changes? Yes, No, Cancel
+ LLSD payload;
+ payload["item_id"] = new_item->getUUID();
+ LLNotifications::instance().add("WearableSave", LLSD(), payload, boost::bind(onSetWearableDialog, _1, _2, new_wearable));
+ return;
+ }
+ }
+ }
+
+ setWearableFinal(new_item, new_wearable, do_append);
+}
+
+// static
+bool LLAgentWearables::onSetWearableDialog(const LLSD& notification, const LLSD& response, LLWearable* wearable)
+{
+ S32 option = LLNotification::getSelectedOption(notification, response);
+ LLInventoryItem* new_item = gInventory.getItem(notification["payload"]["item_id"].asUUID());
+ if (!new_item)
+ {
+ delete wearable;
+ return false;
+ }
+
+ switch(option)
+ {
+ case 0: // "Save"
+// MULTI_WEARABLE: assuming 0th
+ gAgentWearables.saveWearable(wearable->getType(),0);
+ gAgentWearables.setWearableFinal(new_item, wearable);
+ break;
+
+ case 1: // "Don't Save"
+ gAgentWearables.setWearableFinal(new_item, wearable);
+ break;
+
+ case 2: // "Cancel"
+ break;
+
+ default:
+ llassert(0);
+ break;
+ }
+
+ delete wearable;
+ return false;
+}
+
+// Called from setWearableItem() and onSetWearableDialog() to actually set the wearable.
+// MULTI_WEARABLE: unify code after null objects are gone.
+void LLAgentWearables::setWearableFinal(LLInventoryItem* new_item, LLWearable* new_wearable, bool do_append)
+{
+ const EWearableType type = new_wearable->getType();
+
+ if (do_append && getWearableItemID(type,0).notNull())
+ {
+ new_wearable->setItemID(new_item->getUUID());
+ mWearableDatas[type].push_back(new_wearable);
+ llinfos << "Added additional wearable for type " << type
+ << " size is now " << mWearableDatas[type].size() << llendl;
+ }
+ else
+ {
+ // Replace the old wearable with a new one.
+ llassert(new_item->getAssetUUID() == new_wearable->getAssetID());
+
+ LLWearable *old_wearable = getWearable(type,0);
+ LLUUID old_item_id;
+ if (old_wearable)
+ {
+ old_item_id = old_wearable->getItemID();
+ }
+ new_wearable->setItemID(new_item->getUUID());
+ setWearable(type,0,new_wearable);
+
+ if (old_item_id.notNull())
+ {
+ gInventory.addChangedMask(LLInventoryObserver::LABEL, old_item_id);
+ gInventory.notifyObservers();
+ }
+ llinfos << "Replaced current element 0 for type " << type
+ << " size is now " << mWearableDatas[type].size() << llendl;
+ }
+
+ //llinfos << "LLVOAvatar::setWearableItem()" << llendl;
+ queryWearableCache();
+ new_wearable->writeToAvatar(TRUE);
+
+ updateServer();
+}
+
+void LLAgentWearables::queryWearableCache()
+{
+ if (!areWearablesLoaded())
+ {
+ return;
+ }
+
+ // Look up affected baked textures.
+ // If they exist:
+ // disallow updates for affected layersets (until dataserver responds with cache request.)
+ // If cache miss, turn updates back on and invalidate composite.
+ // If cache hit, modify baked texture entries.
+ //
+ // Cache requests contain list of hashes for each baked texture entry.
+ // Response is list of valid baked texture assets. (same message)
+
+ gMessageSystem->newMessageFast(_PREHASH_AgentCachedTexture);
+ gMessageSystem->nextBlockFast(_PREHASH_AgentData);
+ gMessageSystem->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
+ gMessageSystem->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
+ gMessageSystem->addS32Fast(_PREHASH_SerialNum, gAgentQueryManager.mWearablesCacheQueryID);
+
+ S32 num_queries = 0;
+ for (U8 baked_index = 0; baked_index < BAKED_NUM_INDICES; baked_index++)
+ {
+ const LLVOAvatarDictionary::BakedEntry *baked_dict = LLVOAvatarDictionary::getInstance()->getBakedTexture((EBakedTextureIndex)baked_index);
+ LLUUID hash;
+ for (U8 i=0; i < baked_dict->mWearables.size(); i++)
+ {
+ // EWearableType baked_type = gBakedWearableMap[baked_index][baked_num];
+ const EWearableType baked_type = baked_dict->mWearables[i];
+ // MULTI_WEARABLE: assuming 0th
+ const LLWearable* wearable = getWearable(baked_type,0);
+ if (wearable)
+ {
+ hash ^= wearable->getAssetID();
+ }
+ }
+ if (hash.notNull())
+ {
+ hash ^= baked_dict->mWearablesHashID;
+ num_queries++;
+ // *NOTE: make sure at least one request gets packed
+
+ //llinfos << "Requesting texture for hash " << hash << " in baked texture slot " << baked_index << llendl;
+ gMessageSystem->nextBlockFast(_PREHASH_WearableData);
+ gMessageSystem->addUUIDFast(_PREHASH_ID, hash);
+ gMessageSystem->addU8Fast(_PREHASH_TextureIndex, (U8)baked_index);
+ }
+
+ gAgentQueryManager.mActiveCacheQueries[baked_index] = gAgentQueryManager.mWearablesCacheQueryID;
+ }
+
+ llinfos << "Requesting texture cache entry for " << num_queries << " baked textures" << llendl;
+ gMessageSystem->sendReliable(gAgent.getRegion()->getHost());
+ gAgentQueryManager.mNumPendingQueries++;
+ gAgentQueryManager.mWearablesCacheQueryID++;
+}
+
+// MULTI_WEARABLE: need a way to specify by wearable rather than by type.
+// User has picked "remove from avatar" from a menu.
+// static
+void LLAgentWearables::userRemoveWearable(void* userdata)
+{
+ EWearableType type = (EWearableType)(intptr_t)userdata;
+
+ if (!(type==WT_SHAPE || type==WT_SKIN || type==WT_HAIR)) //&&
+ //!((!gAgent.isTeen()) && (type==WT_UNDERPANTS || type==WT_UNDERSHIRT)))
+ {
+ // MULTI_WEARABLE: fixed to 0th for now.
+ gAgentWearables.removeWearable(type,false,0);
+ }
+}
+
+// static
+void LLAgentWearables::userRemoveAllClothes(void* userdata)
+{
+ // We have to do this up front to avoid having to deal with the case of multiple wearables being dirty.
+ if (gFloaterCustomize)
+ {
+ gFloaterCustomize->askToSaveIfDirty(userRemoveAllClothesStep2);
+ }
+ else
+ {
+ userRemoveAllClothesStep2(TRUE);
+ }
+}
+
+// static
+// MULTI_WEARABLE: removing all here.
+void LLAgentWearables::userRemoveAllClothesStep2(BOOL proceed)
+{
+ if (proceed)
+ {
+ gAgentWearables.removeWearable(WT_SHIRT,true,0);
+ gAgentWearables.removeWearable(WT_PANTS,true,0);
+ gAgentWearables.removeWearable(WT_SHOES,true,0);
+ gAgentWearables.removeWearable(WT_SOCKS,true,0);
+ gAgentWearables.removeWearable(WT_JACKET,true,0);
+ gAgentWearables.removeWearable(WT_GLOVES,true,0);
+ gAgentWearables.removeWearable(WT_UNDERSHIRT,true,0);
+ gAgentWearables.removeWearable(WT_UNDERPANTS,true,0);
+ gAgentWearables.removeWearable(WT_SKIRT,true,0);
+ }
+}
+
+void LLAgentWearables::userRemoveAllAttachments(void* userdata)
+{
+ LLVOAvatar* avatarp = gAgent.getAvatarObject();
+ if (!avatarp)
+ {
+ llwarns << "No avatar found." << llendl;
+ return;
+ }
+
+ gMessageSystem->newMessage("ObjectDetach");
+ gMessageSystem->nextBlockFast(_PREHASH_AgentData);
+ gMessageSystem->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
+ gMessageSystem->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
+
+ for (LLVOAvatar::attachment_map_t::iterator iter = avatarp->mAttachmentPoints.begin();
+ iter != avatarp->mAttachmentPoints.end();)
+ {
+ LLVOAvatar::attachment_map_t::iterator curiter = iter++;
+ LLViewerJointAttachment* attachment = curiter->second;
+ LLViewerObject* objectp = attachment->getObject();
+ if (objectp)
+ {
+ gMessageSystem->nextBlockFast(_PREHASH_ObjectData);
+ gMessageSystem->addU32Fast(_PREHASH_ObjectLocalID, objectp->getLocalID());
+ }
+ }
+ gMessageSystem->sendReliable(gAgent.getRegionHost());
+}
+
+void LLAgentWearables::checkWearablesLoaded() const
+{
+#ifdef SHOW_ASSERT
+ U32 item_pend_count = itemUpdatePendingCount();
+ if (mWearablesLoaded)
+ {
+ llassert(item_pend_count==0);
+ }
+#endif
+}
+
+BOOL LLAgentWearables::areWearablesLoaded() const
+{
+ checkWearablesLoaded();
+ return mWearablesLoaded;
+}
+
+// MULTI-WEARABLE: update for multiple indices.
+void LLAgentWearables::updateWearablesLoaded()
+{
+ mWearablesLoaded = (itemUpdatePendingCount()==0);
+}
+
+void LLAgentWearables::updateServer()
+{
+ sendAgentWearablesUpdate();
+ gAgent.sendAgentSetAppearance();
+}
+
+void LLInitialWearablesFetch::done()
+{
+ // Get the complete information on the items in the library,
+ // and set up an observer that will wait for that to happen.
+ LLInventoryModel::cat_array_t cat_array;
+ LLInventoryModel::item_array_t item_array;
+
+ LLFindWearables is_wearable;
+ gInventory.collectDescendentsIf(mCompleteFolders.front(),
+ cat_array,
+ item_array,
+ LLInventoryModel::EXCLUDE_TRASH,
+ is_wearable);
+ S32 count = item_array.count();
+ mCOFInitialWearables.reserve(count);
+
+ for (LLInventoryModel::item_array_t::const_iterator iter = item_array.begin();
+ iter != item_array.end();
+ iter++)
+ {
+ const LLViewerInventoryItem *item = (*iter).get();
+ // We're only concerned with linked items in the COF. Ignore
+ // any non-link items or links to folders.
+ if (item->getActualType() != LLAssetType::AT_LINK)
+ {
+ continue;
+ }
+ EWearableType type = (EWearableType) (item->getFlags() & LLInventoryItem::II_FLAGS_WEARABLES_MASK);
+ // MULTI-WEARABLE: update
+ InitialWearableData wearable_data(type, 0, item->getUUID(), item->getAssetUUID());
+ mCOFInitialWearables.push_back(wearable_data);
+ }
+
+ gInventory.removeObserver(this);
+ processInitialWearables();
+ delete this;
+}
+
+// This will either grab the contents of the Current Outfit Folder if they exist,
+// or use the old-style initial agent wearables message.
+void LLInitialWearablesFetch::processInitialWearables()
+{
+#ifdef USE_CURRENT_OUTFIT_FOLDER
+ if (!mCOFInitialWearables.empty())
+ {
+ for (U8 i = 0; i < mCOFInitialWearables.size(); ++i)
+ {
+ // Fetch the wearables in the current outfit folder
+ InitialWearableData *wearable_data = new InitialWearableData(mCOFInitialWearables[i]); // This will be deleted in the callback.
+ if (wearable_data->mAssetID.notNull())
+ {
+ LLWearableList::instance().getAsset(wearable_data->mAssetID,
+ LLStringUtil::null,
+ LLWearableDictionary::getAssetType(wearable_data->mType),
+ LLAgentWearables::onInitialWearableAssetArrived, (void*)(wearable_data));
+ }
+ else
+ {
+ llinfos << "Invalid wearable, type " << wearable_data->mType << " itemID "
+ << wearable_data->mItemID << " assetID " << wearable_data->mAssetID << llendl;
+ }
+ }
+ }
+ else
+#endif
+ if (!mAgentInitialWearables.empty()) // We have an empty current outfit folder, use the message data instead.
+ {
+ LLUUID current_outfit_id = gInventory.findCategoryUUIDForType(LLAssetType::AT_CURRENT_OUTFIT);
+ for (U8 i = 0; i < mAgentInitialWearables.size(); ++i)
+ {
+ // Populate the current outfit folder with links to the wearables passed in the message
+ InitialWearableData *wearable_data = new InitialWearableData(mAgentInitialWearables[i]); // This will be deleted in the callback.
+
+ if (wearable_data->mAssetID.notNull())
+ {
+#ifdef USE_CURRENT_OUTFIT_FOLDER
+ const std::string link_name = "WearableLink"; // Unimportant what this is named, it isn't exposed.
+ link_inventory_item(gAgent.getID(), wearable_data->mItemID, current_outfit_id, link_name,
+ LLAssetType::AT_LINK, LLPointer<LLInventoryCallback>(NULL));
+#endif
+ // Fetch the wearables
+ LLWearableList::instance().getAsset(wearable_data->mAssetID,
+ LLStringUtil::null,
+ LLWearableDictionary::getAssetType(wearable_data->mType),
+ LLAgentWearables::onInitialWearableAssetArrived, (void*)(wearable_data));
+ }
+ else
+ {
+ llinfos << "Invalid wearable, type " << wearable_data->mType << " itemID "
+ << wearable_data->mItemID << " assetID " << wearable_data->mAssetID << llendl;
+ }
+ }
+ }
+ else
+ {
+ LL_WARNS("Wearables") << "No current outfit folder items found and no initial wearables fallback message received." << LL_ENDL;
+ }
+}
diff --git a/indra/newview/llagentwearables.h b/indra/newview/llagentwearables.h
new file mode 100644
index 0000000000..b415ef9eb3
--- /dev/null
+++ b/indra/newview/llagentwearables.h
@@ -0,0 +1,253 @@
+/**
+ * @file llagentwearables.h
+ * @brief LLAgentWearables class header file
+ *
+ * $LicenseInfo:firstyear=2000&license=viewergpl$
+ *
+ * Copyright (c) 2000-2009, Linden Research, Inc.
+ *
+ * Second Life Viewer Source Code
+ * The source code in this file ("Source Code") is provided by Linden Lab
+ * to you under the terms of the GNU General Public License, version 2.0
+ * ("GPL"), unless you have obtained a separate licensing agreement
+ * ("Other License"), formally executed by you and Linden Lab. Terms of
+ * the GPL can be found in doc/GPL-license.txt in this distribution, or
+ * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
+ *
+ * There are special exceptions to the terms and conditions of the GPL as
+ * it is applied to this Source Code. View the full text of the exception
+ * in the file doc/FLOSS-exception.txt in this software distribution, or
+ * online at
+ * http://secondlifegrid.net/programs/open_source/licensing/flossexception
+ *
+ * By copying, modifying or distributing this software, you acknowledge
+ * that you have read and understood your obligations described above,
+ * and agree to abide by those obligations.
+ *
+ * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+ * COMPLETENESS OR PERFORMANCE.
+ * $/LicenseInfo$
+ */
+
+#ifndef LL_LLAGENTWEARABLES_H
+#define LL_LLAGENTWEARABLES_H
+
+#include "llmemory.h"
+#include "lluuid.h"
+#include "llinventory.h"
+#include "llinventorymodel.h"
+#include "llviewerinventory.h"
+#include "llvoavatardefines.h"
+
+class LLInventoryItem;
+class LLVOAvatarSelf;
+class LLWearable;
+class LLInitialWearablesFetch;
+
+class LLAgentWearables
+{
+ //--------------------------------------------------------------------
+ // Constructors / destructors / Initializers
+ //--------------------------------------------------------------------
+public:
+ friend class LLInitialWearablesFetch;
+
+ LLAgentWearables();
+ virtual ~LLAgentWearables();
+ void setAvatarObject(LLVOAvatarSelf *avatar);
+ void createStandardWearables(BOOL female);
+ void cleanup();
+ void dump();
+protected:
+ // MULTI-WEARABLE: assuming one per type. Type is called index - rename.
+ void createStandardWearablesDone(S32 type, U32 index/* = 0*/);
+ void createStandardWearablesAllDone();
+
+ //--------------------------------------------------------------------
+ // Queries
+ //--------------------------------------------------------------------
+public:
+ BOOL isWearingItem(const LLUUID& item_id, const BOOL include_linked_items = FALSE) const;
+ BOOL isWearableModifiable(EWearableType type, U32 index /*= 0*/) const;
+ BOOL isWearableCopyable(EWearableType type, U32 index /*= 0*/) const;
+ BOOL areWearablesLoaded() const;
+ void updateWearablesLoaded();
+ void checkWearablesLoaded() const;
+
+
+ //--------------------------------------------------------------------
+ // Accessors
+ //--------------------------------------------------------------------
+public:
+ const LLUUID getWearableItemID(EWearableType type, U32 index /*= 0*/) const;
+ const LLWearable* getWearableFromWearableItem(const LLUUID& item_id) const;
+ LLInventoryItem* getWearableInventoryItem(EWearableType type, U32 index /*= 0*/);
+ // MULTI-WEARABLE: assuming one per type.
+ static BOOL selfHasWearable(EWearableType type);
+ LLWearable* getWearable(const EWearableType type, U32 index /*= 0*/);
+ const LLWearable* getWearable(const EWearableType type, U32 index /*= 0*/) const;
+ U32 getWearableCount(const EWearableType type) const;
+
+
+ //--------------------------------------------------------------------
+ // Setters
+ //--------------------------------------------------------------------
+
+private:
+ // Low-level data structure setter - public access is via setWearableItem, etc.
+ void setWearable(const EWearableType type, U32 index, LLWearable *wearable);
+
+public:
+ void setWearableItem(LLInventoryItem* new_item, LLWearable* wearable, bool do_append = false);
+ void setWearableOutfit(const LLInventoryItem::item_array_t& items, const LLDynamicArray< LLWearable* >& wearables, BOOL remove);
+ void setWearableName(const LLUUID& item_id, const std::string& new_name);
+ void addLocalTextureObject(const EWearableType wearable_type, const LLVOAvatarDefines::ETextureIndex texture_type, U32 wearable_index);
+protected:
+ void setWearableFinal(LLInventoryItem* new_item, LLWearable* new_wearable, bool do_append = false);
+ static bool onSetWearableDialog(const LLSD& notification, const LLSD& response, LLWearable* wearable);
+
+ void addWearableToAgentInventory(LLPointer<LLInventoryCallback> cb,
+ LLWearable* wearable,
+ const LLUUID& category_id = LLUUID::null,
+ BOOL notify = TRUE);
+ void addWearabletoAgentInventoryDone(const S32 type,
+ const U32 index,
+ const LLUUID& item_id,
+ LLWearable* wearable);
+ void recoverMissingWearable(const EWearableType type, U32 index /*= 0*/);
+ void recoverMissingWearableDone();
+
+ //--------------------------------------------------------------------
+ // Removing wearables
+ //--------------------------------------------------------------------
+public:
+ void removeWearable(const EWearableType type, bool do_remove_all /*= false*/, U32 index /*= 0*/);
+private:
+ void removeWearableFinal(const EWearableType type, bool do_remove_all /*= false*/, U32 index /*= 0*/);
+protected:
+ static bool onRemoveWearableDialog(const LLSD& notification, const LLSD& response);
+ static void userRemoveAllClothesStep2(BOOL proceed); // userdata is NULL
+
+ //--------------------------------------------------------------------
+ // Server Communication
+ //--------------------------------------------------------------------
+public:
+ // Processes the initial wearables update message (if necessary, since the outfit folder makes it redundant)
+ static void processAgentInitialWearablesUpdate(LLMessageSystem* mesgsys, void** user_data);
+protected:
+ void sendAgentWearablesUpdate();
+ void sendAgentWearablesRequest();
+ void queryWearableCache();
+ void updateServer();
+ static void onInitialWearableAssetArrived(LLWearable* wearable, void* userdata);
+
+ //--------------------------------------------------------------------
+ // Outfits
+ //--------------------------------------------------------------------
+public:
+ void getAllWearablesArray(LLDynamicArray<S32>& wearables);
+
+ // Note: wearables_to_include should be a list of EWearableType types
+ // attachments_to_include should be a list of attachment points
+ void makeNewOutfit(const std::string& new_folder_name,
+ const LLDynamicArray<S32>& wearables_to_include,
+ const LLDynamicArray<S32>& attachments_to_include,
+ BOOL rename_clothing);
+
+ // Note: wearables_to_include should be a list of EWearableType types
+ // attachments_to_include should be a list of attachment points
+ LLUUID makeNewOutfitLinks(const std::string& new_folder_name);
+ LLUUID makeNewOutfitLinks(const std::string& new_folder_name,
+ const LLDynamicArray<S32>& wearables_to_include,
+ const LLDynamicArray<S32>& attachments_to_include);
+private:
+ void makeNewOutfitDone(S32 type, U32 index);
+
+ //--------------------------------------------------------------------
+ // Save Wearables
+ //--------------------------------------------------------------------
+public:
+ // MULTI-WEARABLE: assumes one per type.
+ void saveWearableAs(const EWearableType type, const U32 index, const std::string& new_name, BOOL save_in_lost_and_found);
+ void saveWearable(const EWearableType type, const U32 index, BOOL send_update = TRUE);
+ void saveAllWearables();
+ void revertWearable(const EWearableType type, const U32 index);
+
+ //--------------------------------------------------------------------
+ // Static UI hooks
+ //--------------------------------------------------------------------
+public:
+ // MULTI-WEARABLE: assuming one wearable per type. Need upstream changes.
+ static void userRemoveWearable(void* userdata); // userdata is EWearableType
+ static void userRemoveAllClothes(void* userdata); // userdata is NULL
+ static void userRemoveAllAttachments(void* userdata); // userdata is NULL
+
+ BOOL itemUpdatePending(const LLUUID& item_id) const;
+ U32 itemUpdatePendingCount() const;
+
+ //--------------------------------------------------------------------
+ // Member variables
+ //--------------------------------------------------------------------
+private:
+ typedef std::vector<LLWearable*> wearableentry_vec_t; // all wearables of a certain type (EG all shirts)
+ typedef std::map<EWearableType, wearableentry_vec_t> wearableentry_map_t; // wearable "categories" arranged by wearable type
+ wearableentry_map_t mWearableDatas;
+
+ static BOOL mInitialWearablesUpdateReceived;
+ BOOL mWearablesLoaded;
+ std::set<LLUUID> mItemsAwaitingWearableUpdate;
+ LLPointer<LLVOAvatarSelf> mAvatarObject; // NULL until avatar object sent down from simulator
+
+ //--------------------------------------------------------------------------------
+ // Support classes
+ //--------------------------------------------------------------------------------
+private:
+ class createStandardWearablesAllDoneCallback : public LLRefCount
+ {
+ protected:
+ ~createStandardWearablesAllDoneCallback();
+ };
+ class sendAgentWearablesUpdateCallback : public LLRefCount
+ {
+ protected:
+ ~sendAgentWearablesUpdateCallback();
+ };
+
+ class addWearableToAgentInventoryCallback : public LLInventoryCallback
+ {
+ public:
+ enum EType
+ {
+ CALL_NONE = 0,
+ CALL_UPDATE = 1,
+ CALL_RECOVERDONE = 2,
+ CALL_CREATESTANDARDDONE = 4,
+ CALL_MAKENEWOUTFITDONE = 8
+ };
+
+ // MULTI-WEARABLE: index is an EWearableType - more confusing usage.
+ // MULTI-WEARABLE: need to have type and index args both?
+ addWearableToAgentInventoryCallback(LLPointer<LLRefCount> cb,
+ S32 type,
+ U32 index,
+ LLWearable* wearable,
+ U32 todo = CALL_NONE);
+ virtual void fire(const LLUUID& inv_item);
+ private:
+ S32 mType;
+ U32 mIndex;
+ LLWearable* mWearable;
+ U32 mTodo;
+ LLPointer<LLRefCount> mCB;
+ };
+
+}; // LLAgentWearables
+
+extern LLAgentWearables gAgentWearables;
+
+//--------------------------------------------------------------------
+// Types
+//--------------------------------------------------------------------
+
+#endif // LL_AGENTWEARABLES_H
diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp
index 584ab5e50f..de4f7ab091 100644
--- a/indra/newview/llappviewer.cpp
+++ b/indra/newview/llappviewer.cpp
@@ -30,9 +30,10 @@
* $/LicenseInfo$
*/
-
#include "llviewerprecompiledheaders.h"
+
#include "llappviewer.h"
+
#include "llprimitive.h"
#include "llversionviewer.h"
@@ -41,37 +42,46 @@
#include "lltexteditor.h"
#include "llalertdialog.h"
#include "llerrorcontrol.h"
-#include "llviewerimagelist.h"
+#include "llviewertexturelist.h"
#include "llgroupmgr.h"
#include "llagent.h"
+#include "llagentwearables.h"
#include "llwindow.h"
#include "llviewerstats.h"
#include "llmd5.h"
#include "llpumpio.h"
#include "llimpanel.h"
#include "llmimetypes.h"
+#include "llslurl.h"
#include "llstartup.h"
#include "llfocusmgr.h"
#include "llviewerjoystick.h"
-#include "llfloaterjoystick.h"
+#include "llallocator.h"
#include "llares.h"
#include "llcurl.h"
-#include "llfloatersnapshot.h"
#include "llviewerwindow.h"
#include "llviewerdisplay.h"
#include "llviewermedia.h"
+#include "llviewerparcelmedia.h"
+#include "llviewermediafocus.h"
#include "llviewermessage.h"
#include "llviewerobjectlist.h"
#include "llworldmap.h"
#include "llmutelist.h"
+#include "lluicolortable.h"
#include "llurldispatcher.h"
#include "llurlhistory.h"
#include "llfirstuse.h"
#include "llrender.h"
-
+#include "lllocationhistory.h"
+#include "llfasttimerview.h"
#include "llweb.h"
#include "llsecondlifeurls.h"
+// Linden library includes
+#include "llmemory.h"
+
+// Third party library includes
#include <boost/bind.hpp>
#if LL_WINDOWS
@@ -101,11 +111,12 @@
#include "llassetstorage.h"
#include "llpolymesh.h"
#include "llcachename.h"
-#include "audioengine.h"
+#include "llaudioengine.h"
+#include "llstreamingaudio.h"
#include "llviewermenu.h"
#include "llselectmgr.h"
#include "lltrans.h"
-#include "lluitrans.h"
+#include "lltransutil.h"
#include "lltracker.h"
#include "llviewerparcelmgr.h"
#include "llworldmapview.h"
@@ -116,9 +127,7 @@
#include "lldebugview.h"
#include "llconsole.h"
#include "llcontainerview.h"
-#include "llfloaterstats.h"
#include "llhoverview.h"
-#include "llfloatermemleak.h"
#include "llsdserialize.h"
@@ -139,12 +148,17 @@
#include "llvoavatar.h"
#include "llfolderview.h"
#include "lltoolbar.h"
-#include "llframestats.h"
#include "llagentpilot.h"
#include "llsrv.h"
#include "llvovolume.h"
#include "llflexibleobject.h"
#include "llvosurfacepatch.h"
+#include "llviewerfloaterreg.h"
+#include "llcommandlineparser.h"
+#include "llfloatermemleak.h"
+#include "llfloaterreg.h"
+#include "llfloatersnapshot.h"
+#include "llfloaterinventory.h"
// includes for idle() idleShutdown()
#include "llviewercontrol.h"
@@ -161,11 +175,6 @@
#include "llviewerthrottle.h"
#include "llparcel.h"
-
-#include "llinventoryview.h"
-
-#include "llcommandlineparser.h"
-
// *FIX: These extern globals should be cleaned up.
// The globals either represent state/config/resource-storage of either
// this app, or another 'component' of the viewer. App globals should be
@@ -181,10 +190,6 @@
////// Windows-specific includes to the bottom - nasty defines in these pollute the preprocessor
//
-#if LL_WINDOWS && LL_LCD_COMPILE
- #include "lllcd.h"
-#endif
-
//----------------------------------------------------------------------------
// viewer.cpp - these are only used in viewer, should be easily moved.
@@ -235,9 +240,6 @@ LLTimer gLogoutTimer;
static const F32 LOGOUT_REQUEST_TIME = 6.f; // this will be cut short by the LogoutReply msg.
F32 gLogoutMaxTime = LOGOUT_REQUEST_TIME;
-LLUUID gInventoryLibraryOwner;
-LLUUID gInventoryLibraryRoot;
-
BOOL gDisconnected = FALSE;
// Map scale in pixels per region
@@ -285,11 +287,22 @@ static std::string gLaunchFileOnQuit;
const char* const VIEWER_WINDOW_CLASSNAME = "Second Life";
//----------------------------------------------------------------------------
+
+// List of entries from strings.xml to always replace
+static std::set<std::string> default_trans_args;
+void init_default_trans_args()
+{
+ default_trans_args.insert("SECOND_LIFE"); // World
+ default_trans_args.insert("APP_NAME");
+ default_trans_args.insert("SECOND_LIFE_GRID");
+ default_trans_args.insert("SUPPORT_SITE");
+}
+
+//----------------------------------------------------------------------------
// File scope definitons
const char *VFS_DATA_FILE_BASE = "data.db2.x.";
const char *VFS_INDEX_FILE_BASE = "index.db2.x.";
-static std::string gSecondLife;
static std::string gWindowTitle;
std::string gLoginPage;
@@ -366,7 +379,6 @@ static void settings_to_globals()
MENU_BAR_HEIGHT = gSavedSettings.getS32("MenuBarHeight");
MENU_BAR_WIDTH = gSavedSettings.getS32("MenuBarWidth");
- STATUS_BAR_HEIGHT = gSavedSettings.getS32("StatusBarHeight");
LLCOMBOBOX_HEIGHT = BTN_HEIGHT - 2;
LLCOMBOBOX_WIDTH = 128;
@@ -388,10 +400,9 @@ static void settings_to_globals()
LLSelectMgr::sRenderHiddenSelections = gSavedSettings.getBOOL("RenderHiddenSelections");
LLSelectMgr::sRenderLightRadius = gSavedSettings.getBOOL("RenderLightRadius");
- gFrameStats.setTrackStats(gSavedSettings.getBOOL("StatsSessionTrackFrameStats"));
gAgentPilot.mNumRuns = gSavedSettings.getS32("StatsNumRuns");
gAgentPilot.mQuitAfterRuns = gSavedSettings.getBOOL("StatsQuitAfterRuns");
- gAgent.mHideGroupTitle = gSavedSettings.getBOOL("RenderHideGroupTitle");
+ gAgent.setHideGroupTitle(gSavedSettings.getBOOL("RenderHideGroupTitle"));
gDebugWindowProc = gSavedSettings.getBOOL("DebugWindowProc");
gAllowTapTapHoldRun = gSavedSettings.getBOOL("AllowTapTapHoldRun");
@@ -408,7 +419,7 @@ static void settings_modify()
LLVOAvatar::sUseImpostors = gSavedSettings.getBOOL("RenderUseImpostors");
LLVOSurfacePatch::sLODFactor = gSavedSettings.getF32("RenderTerrainLODFactor");
LLVOSurfacePatch::sLODFactor *= LLVOSurfacePatch::sLODFactor; //square lod factor to get exponential range of [1,4]
- gDebugGL = gSavedSettings.getBOOL("RenderDebugGL");
+ gDebugGL = gSavedSettings.getBOOL("RenderDebugGL") || gDebugSession;
gDebugPipeline = gSavedSettings.getBOOL("RenderDebugPipeline");
#if LL_VECTORIZE
@@ -446,6 +457,38 @@ static void settings_modify()
#endif
}
+class LLFastTimerLogThread : public LLThread
+{
+public:
+ std::string mFile;
+
+ LLFastTimerLogThread() : LLThread("fast timer log")
+ {
+ if(LLFastTimer::sLog)
+ {
+ mFile = gDirUtilp->getExpandedFilename(LL_PATH_LOGS, "performance.slp");
+ }
+ if(LLFastTimer::sMetricLog)
+ {
+ mFile = gDirUtilp->getExpandedFilename(LL_PATH_LOGS, "metric.slp");
+ }
+ }
+
+ void run()
+ {
+ std::ofstream os(mFile.c_str());
+
+ while (!LLAppViewer::instance()->isQuitting())
+ {
+ LLFastTimer::writeLog(os);
+ os.flush();
+ ms_sleep(32);
+ }
+
+ os.close();
+ }
+};
+
void LLAppViewer::initGridChoice()
{
// Load up the initial grid choice from:
@@ -497,8 +540,6 @@ bool LLAppViewer::sendURLToOtherInstance(const std::string& url)
LLAppViewer* LLAppViewer::sInstance = NULL;
const std::string LLAppViewer::sGlobalSettingsName = "Global";
-const std::string LLAppViewer::sPerAccountSettingsName = "PerAccount";
-const std::string LLAppViewer::sCrashSettingsName = "CrashSettings";
LLTextureCache* LLAppViewer::sTextureCache = NULL;
LLWorkerThread* LLAppViewer::sImageDecodeThread = NULL;
@@ -513,11 +554,15 @@ LLAppViewer::LLAppViewer() :
mPurgeOnExit(false),
mSecondInstance(false),
mSavedFinalSnapshot(false),
+ mForceGraphicsDetail(false),
mQuitRequested(false),
mLogoutRequestSent(false),
mYieldTime(-1),
mMainloopTimeout(NULL),
- mAgentRegionLastAlive(false)
+ mAgentRegionLastAlive(false),
+ mFastTimerLogThread(NULL),
+ mRandomizeFramerate(LLCachedControl<bool>(gSavedSettings,"Randomize Framerate", FALSE)),
+ mPeriodicSlowFrame(LLCachedControl<bool>(gSavedSettings,"Periodic Slow Frame", FALSE))
{
if(NULL != sInstance)
{
@@ -558,8 +603,13 @@ bool LLAppViewer::init()
//
// OK to write stuff to logs now, we've now crash reported if necessary
//
- if (!initConfiguration())
+
+ init_default_trans_args();
+
+ if (!initConfiguration())
return false;
+
+ mAlloc.setProfilingEnabled(gSavedSettings.getBOOL("MemProfiling"));
// *NOTE:Mani - LLCurl::initClass is not thread safe.
// Called before threads are created.
@@ -593,6 +643,11 @@ bool LLAppViewer::init()
// Get the single value from the crash settings file, if it exists
std::string crash_settings_filename = gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS, CRASH_SETTINGS_FILE);
gCrashSettings.loadFromFile(crash_settings_filename);
+ if(gSavedSettings.getBOOL("IgnoreAllNotifications"))
+ {
+ gCrashSettings.setS32(CRASH_BEHAVIOR_SETTING, CRASH_BEHAVIOR_ALWAYS_SEND);
+ gCrashSettings.saveToFile(crash_settings_filename, FALSE);
+ }
/////////////////////////////////////////////////
// OS-specific login dialogs
@@ -612,34 +667,37 @@ bool LLAppViewer::init()
LLError::setPrintLocation(true);
}
- // Load art UUID information, don't require these strings to be declared in code.
- std::string colors_base_filename = gDirUtilp->findSkinnedFilename("colors_base.xml");
- LL_DEBUGS("InitInfo") << "Loading base colors from " << colors_base_filename << LL_ENDL;
- gColors.loadFromFileLegacy(colors_base_filename, FALSE, TYPE_COL4U);
-
- // Load overrides from user colors file
- std::string user_colors_filename = gDirUtilp->findSkinnedFilename("colors.xml");
- LL_DEBUGS("InitInfo") << "Loading user colors from " << user_colors_filename << LL_ENDL;
- if (gColors.loadFromFileLegacy(user_colors_filename, FALSE, TYPE_COL4U) == 0)
- {
- LL_DEBUGS("InitInfo") << "Cannot load user colors from " << user_colors_filename << LL_ENDL;
- }
-
// Widget construction depends on LLUI being initialized
- LLUI::initClass(&gSavedSettings,
- &gSavedSettings,
- &gColors,
+ LLUI::settings_map_t settings_map;
+ settings_map["config"] = &gSavedSettings;
+ settings_map["ignores"] = &gWarningSettings;
+ settings_map["floater"] = &gSavedSettings; // *TODO: New settings file
+ settings_map["account"] = &gSavedPerAccountSettings;
+
+ LLUI::initClass(settings_map,
LLUIImageList::getInstance(),
ui_audio_callback,
&LLUI::sGLScaleFactor);
+
+ // Setup paths and LLTrans after LLUI::initClass has been called
+ LLUI::setupPaths();
+ LLTransUtil::parseStrings("strings.xml", default_trans_args);
+ LLTransUtil::parseLanguageStrings("language_settings.xml");
LLWeb::initClass(); // do this after LLUI
LLTextEditor::setURLCallbacks(&LLWeb::loadURL,
&LLURLDispatcher::dispatchFromTextEditor,
&LLURLDispatcher::dispatchFromTextEditor);
-
- LLUICtrlFactory::getInstance()->setupPaths(); // update paths with correct language set
+ // Load translations for tooltips
+ LLFloater::initClass();
+
+ /////////////////////////////////////////////////
+
+ LLToolMgr::getInstance(); // Initialize tool manager if not already instantiated
+
+ LLViewerFloaterReg::registerFloaters();
+
/////////////////////////////////////////////////
//
// Load settings files
@@ -692,18 +750,8 @@ bool LLAppViewer::init()
if (!initCache())
{
std::ostringstream msg;
- msg <<
- gSecondLife << " is unable to access a file that it needs.\n"
- "\n"
- "This can be because you somehow have multiple copies running, "
- "or your system incorrectly thinks a file is open. "
- "If this message persists, restart your computer and try again. "
- "If it continues to persist, you may need to completely uninstall " <<
- gSecondLife << " and reinstall it.";
- OSMessageBox(
- msg.str(),
- LLStringUtil::null,
- OSMB_OK);
+ msg << LLTrans::getString("MBUnableToAccessFile");
+ OSMessageBox(msg.str(),LLStringUtil::null,OSMB_OK);
return 1;
}
@@ -818,8 +866,14 @@ bool LLAppViewer::init()
return true;
}
+static LLFastTimer::DeclareTimer FTM_MESSAGES("System Messages");
+static LLFastTimer::DeclareTimer FTM_SLEEP("Sleep");
+static LLFastTimer::DeclareTimer FTM_IDLE("Idle");
+static LLFastTimer::DeclareTimer FTM_PUMP("Pump");
+
bool LLAppViewer::mainLoop()
{
+ LLMemType mt1(LLMemType::MTYPE_MAIN);
mMainloopTimeout = new LLWatchdogTimeout();
// *FIX:Mani - Make this a setting, once new settings exist in this branch.
@@ -837,7 +891,6 @@ bool LLAppViewer::mainLoop()
LLVoiceChannel::initClass();
LLVoiceClient::init(gServicePump);
- LLMemType mt1(LLMemType::MTYPE_MAIN);
LLTimer frameTimer,idleTimer;
LLTimer debugTime;
LLViewerJoystick* joystick(LLViewerJoystick::getInstance());
@@ -853,21 +906,22 @@ bool LLAppViewer::mainLoop()
// Handle messages
while (!LLApp::isExiting())
{
- LLFastTimer::reset(); // Should be outside of any timer instances
+ LLFastTimer::nextFrame(); // Should be outside of any timer instances
try
{
- LLFastTimer t(LLFastTimer::FTM_FRAME);
pingMainloopTimeout("Main:MiscNativeWindowEvents");
-
+
+ if (gViewerWindow)
{
- LLFastTimer t2(LLFastTimer::FTM_MESSAGES);
+ LLFastTimer t2(FTM_MESSAGES);
gViewerWindow->mWindow->processMiscNativeEvents();
}
pingMainloopTimeout("Main:GatherInput");
+ if (gViewerWindow)
{
- LLFastTimer t2(LLFastTimer::FTM_MESSAGES);
+ LLFastTimer t2(FTM_MESSAGES);
if (!restoreErrorTrap())
{
llwarns << " Someone took over my signal/exception handler (post messagehandling)!" << llendl;
@@ -885,9 +939,10 @@ bool LLAppViewer::mainLoop()
#endif
//memory leaking simulation
- if(LLFloaterMemLeak::getInstance())
+ LLFloaterMemLeak* mem_leak_instance = LLFloaterReg::getTypedInstance<LLFloaterMemLeak>("mem_leaking");
+ if(mem_leak_instance)
{
- LLFloaterMemLeak::getInstance()->idle() ;
+ mem_leak_instance->idle() ;
}
// canonical per-frame event
@@ -907,6 +962,7 @@ bool LLAppViewer::mainLoop()
&& !gViewerWindow->getShowProgress()
&& !gFocusMgr.focusLocked())
{
+ LLMemType mjk(LLMemType::MTYPE_JOY_KEY);
joystick->scanJoystick();
gKeyboard->scanKeyboard();
}
@@ -915,13 +971,14 @@ bool LLAppViewer::mainLoop()
{
pauseMainloopTimeout(); // *TODO: Remove. Messages shouldn't be stalling for 20+ seconds!
- LLFastTimer t3(LLFastTimer::FTM_IDLE);
+ LLFastTimer t3(FTM_IDLE);
idle();
if (gAres != NULL && gAres->isInitialized())
{
+ LLMemType mt_ip(LLMemType::MTYPE_IDLE_PUMP);
pingMainloopTimeout("Main:ServicePump");
- LLFastTimer t4(LLFastTimer::FTM_PUMP);
+ LLFastTimer t4(FTM_PUMP);
gAres->process();
// this pump is necessary to make the login screen show up
gServicePump->pump();
@@ -947,12 +1004,6 @@ bool LLAppViewer::mainLoop()
pingMainloopTimeout("Main:Snapshot");
LLFloaterSnapshot::update(); // take snapshots
-
-#if LL_LCD_COMPILE
- // update LCD Screen
- pingMainloopTimeout("Main:LCD");
- gLcdScreen->UpdateDisplay();
-#endif
}
}
@@ -963,7 +1014,8 @@ bool LLAppViewer::mainLoop()
// Sleep and run background threads
{
- LLFastTimer t2(LLFastTimer::FTM_SLEEP);
+ LLMemType mt_sleep(LLMemType::MTYPE_SLEEP);
+ LLFastTimer t2(FTM_SLEEP);
bool run_multiple_threads = gSavedSettings.getBOOL("RunMultipleThreads");
// yield some time to the os based on command line option
@@ -974,7 +1026,7 @@ bool LLAppViewer::mainLoop()
// yield cooperatively when not running as foreground window
if ( gNoRender
- || !gViewerWindow->mWindow->getVisible()
+ || (gViewerWindow && !gViewerWindow->mWindow->getVisible())
|| !gFocusMgr.getAppHasFocus())
{
// Sleep if we're not rendering, or the window is minimized.
@@ -990,12 +1042,12 @@ bool LLAppViewer::mainLoop()
}
}
- if (gRandomizeFramerate)
+ if (mRandomizeFramerate)
{
ms_sleep(rand() % 200);
}
- if (gPeriodicSlowFrame
+ if (mPeriodicSlowFrame
&& (gFrameCount % 10 == 0))
{
llinfos << "Periodic slow frame - sleeping 500 ms" << llendl;
@@ -1057,9 +1109,10 @@ bool LLAppViewer::mainLoop()
catch(std::bad_alloc)
{
//stop memory leaking simulation
- if(LLFloaterMemLeak::getInstance())
+ LLFloaterMemLeak* mem_leak_instance = LLFloaterReg::getTypedInstance<LLFloaterMemLeak>("mem_leaking");
+ if(mem_leak_instance)
{
- LLFloaterMemLeak::getInstance()->stop() ;
+ mem_leak_instance->stop() ;
llwarns << "Bad memory allocation in LLAppViewer::mainLoop()!" << llendl ;
}
else
@@ -1084,9 +1137,10 @@ bool LLAppViewer::mainLoop()
llwarns << "Bad memory allocation when saveFinalSnapshot() is called!" << llendl ;
//stop memory leaking simulation
- if(LLFloaterMemLeak::getInstance())
+ LLFloaterMemLeak* mem_leak_instance = LLFloaterReg::getTypedInstance<LLFloaterMemLeak>("mem_leaking");
+ if(mem_leak_instance)
{
- LLFloaterMemLeak::getInstance()->stop() ;
+ mem_leak_instance->stop() ;
}
}
}
@@ -1166,6 +1220,14 @@ bool LLAppViewer::cleanup()
if (gAudiop)
{
+ // shut down the streaming audio sub-subsystem first, in case it relies on not outliving the general audio subsystem.
+
+ LLStreamingAudioInterface *sai = gAudiop->getStreamingAudioImpl();
+ delete sai;
+ gAudiop->setStreamingAudioImpl(NULL);
+
+ // shut down the audio subsystem
+
bool want_longname = false;
if (gAudiop->getDriverName(want_longname) == "FMOD")
{
@@ -1221,22 +1283,26 @@ bool LLAppViewer::cleanup()
llinfos << "Shutting down." << llendflush;
// Destroy the UI
- gViewerWindow->shutdownViews();
+ if( gViewerWindow)
+ gViewerWindow->shutdownViews();
// Clean up selection managers after UI is destroyed, as UI may be observing them.
// Clean up before GL is shut down because we might be holding on to objects with texture references
LLSelectMgr::cleanupGlobals();
// Shut down OpenGL
- gViewerWindow->shutdownGL();
+ if( gViewerWindow)
+ {
+ gViewerWindow->shutdownGL();
+
+ // Destroy window, and make sure we're not fullscreen
+ // This may generate window reshape and activation events.
+ // Therefore must do this before destroying the message system.
+ delete gViewerWindow;
+ gViewerWindow = NULL;
+ llinfos << "ViewerWindow deleted" << llendflush;
+ }
- // Destroy window, and make sure we're not fullscreen
- // This may generate window reshape and activation events.
- // Therefore must do this before destroying the message system.
- delete gViewerWindow;
- gViewerWindow = NULL;
- llinfos << "ViewerWindow deleted" << llendflush;
-
// viewer UI relies on keyboard so keep it aound until viewer UI isa gone
delete gKeyboard;
gKeyboard = NULL;
@@ -1256,12 +1322,6 @@ bool LLAppViewer::cleanup()
// gDXHardware.cleanup();
//#endif // LL_WINDOWS
-#if LL_LCD_COMPILE
- // shut down the LCD window on a logitech keyboard, if there is one
- delete gLcdScreen;
- gLcdScreen = NULL;
-#endif
-
LLVolumeMgr* volume_manager = LLPrimitive::getVolumeManager();
if (!volume_manager->cleanup())
{
@@ -1303,7 +1363,9 @@ bool LLAppViewer::cleanup()
// Must do this after all panels have been deleted because panels that have persistent rects
// save their rects on delete.
- gSavedSettings.saveToFile(gSavedSettings.getString("ClientSettingsFile"), TRUE);
+ gSavedSettings.saveToFile(gSavedSettings.getString("ClientSettingsFile"), TRUE);
+
+ LLUIColorTable::instance().saveUserSettings();
// PerAccountSettingsFile should be empty if no use has been logged on.
// *FIX:Mani This should get really saved in a "logoff" mode.
@@ -1314,9 +1376,8 @@ bool LLAppViewer::cleanup()
// save all settings, even if equals defaults
gCrashSettings.saveToFile(crash_settings_filename, FALSE);
- gSavedSettings.cleanup();
- gColors.cleanup();
- gCrashSettings.cleanup();
+ std::string warnings_settings_filename = gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS, getSettingsFilename("Default", "Warnings"));
+ gWarningSettings.saveToFile(warnings_settings_filename, TRUE);
// Save URL history file
LLURLHistory::saveFile("url_history.xml");
@@ -1360,6 +1421,7 @@ bool LLAppViewer::cleanup()
sTextureCache->shutdown();
sTextureFetch->shutdown();
sImageDecodeThread->shutdown();
+
delete sTextureCache;
sTextureCache = NULL;
delete sTextureFetch;
@@ -1367,11 +1429,38 @@ bool LLAppViewer::cleanup()
delete sImageDecodeThread;
sImageDecodeThread = NULL;
+ LLLocationHistory::getInstance()->save();
+ delete mFastTimerLogThread;
+ mFastTimerLogThread = NULL;
+
+ if (LLFastTimerView::sAnalyzePerformance)
+ {
+ llinfos << "Analyzing performance" << llendl;
+
+ if(LLFastTimer::sLog)
+ {
+ LLFastTimerView::doAnalysis(
+ gDirUtilp->getExpandedFilename(LL_PATH_LOGS, "performance_baseline.slp"),
+ gDirUtilp->getExpandedFilename(LL_PATH_LOGS, "performance.slp"),
+ gDirUtilp->getExpandedFilename(LL_PATH_LOGS, "performance_report.csv"));
+ }
+ if(LLFastTimer::sMetricLog)
+ {
+ LLFastTimerView::doAnalysis(
+ gDirUtilp->getExpandedFilename(LL_PATH_LOGS, "metric_baseline.slp"),
+ gDirUtilp->getExpandedFilename(LL_PATH_LOGS, "metric.slp"),
+ gDirUtilp->getExpandedFilename(LL_PATH_LOGS, "metric_report.csv"));
+ }
+ }
+ LLMetricPerformanceTester::cleanClass() ;
+
//Note:
- //LLViewerMedia::cleanupClass() has to be put before gImageList.shutdown()
+ //LLViewerMedia::cleanupClass() has to be put before gTextureList.shutdown()
//because some new image might be generated during cleaning up media. --bao
+ LLViewerMediaFocus::cleanupClass();
LLViewerMedia::cleanupClass();
- gImageList.shutdown(); // shutdown again in case a callback added something
+ LLViewerParcelMedia::cleanupClass();
+ gTextureList.shutdown(); // shutdown again in case a callback added something
LLUIImageList::getInstance()->cleanUp();
// This should eventually be done in LLAppViewer
@@ -1392,6 +1481,10 @@ bool LLAppViewer::cleanup()
gStaticVFS = NULL;
delete gVFS;
gVFS = NULL;
+
+ gSavedSettings.cleanup();
+ LLUIColorTable::instance().clear();
+ gCrashSettings.cleanup();
LLWatchdog::getInstance()->cleanup();
@@ -1419,6 +1512,8 @@ bool LLAppViewer::cleanup()
llinfos << "File launched." << llendflush;
}
+ ll_close_fail_log();
+
llinfos << "Goodbye" << llendflush;
// return 0;
@@ -1469,6 +1564,13 @@ bool LLAppViewer::initThreads()
LLAppViewer::sTextureFetch = new LLTextureFetch(LLAppViewer::getTextureCache(), enable_threads && false);
LLImage::initClass(LLAppViewer::getImageDecodeThread());
+ if (LLFastTimer::sLog || LLFastTimer::sMetricLog)
+ {
+ LLFastTimer::sLogLock = new LLMutex(NULL);
+ mFastTimerLogThread = new LLFastTimerLogThread();
+ mFastTimerLogThread->start();
+ }
+
// *FIX: no error handling here!
return true;
}
@@ -1476,7 +1578,7 @@ bool LLAppViewer::initThreads()
void errorCallback(const std::string &error_string)
{
#ifndef LL_RELEASE_FOR_DOWNLOAD
- OSMessageBox(error_string, "Fatal Error", OSMB_OK);
+ OSMessageBox(error_string, LLTrans::getString("MBFatalError"), OSMB_OK);
#endif
//Set the ErrorActivated global so we know to create a marker file
@@ -1544,7 +1646,7 @@ bool LLAppViewer::loadSettingsFromDirectory(const std::string& location_key,
llinfos << "Attempting to load settings for the group " << settings_group
<< " - from location " << location_key << llendl;
- if(gSettings.find(settings_group) == gSettings.end())
+ if(!LLControlGroup::getInstance(settings_group))
{
llwarns << "No matching settings group for name " << settings_group << llendl;
continue;
@@ -1558,10 +1660,10 @@ bool LLAppViewer::loadSettingsFromDirectory(const std::string& location_key,
std::string custom_name_setting = file.get("NameFromSetting");
// *NOTE: Regardless of the group currently being lodaed,
// this setting is always read from the Global settings.
- if(gSettings[sGlobalSettingsName]->controlExists(custom_name_setting))
+ if(LLControlGroup::getInstance(sGlobalSettingsName)->controlExists(custom_name_setting))
{
std::string file_name =
- gSettings[sGlobalSettingsName]->getString(custom_name_setting);
+ LLControlGroup::getInstance(sGlobalSettingsName)->getString(custom_name_setting);
full_settings_path = file_name;
}
}
@@ -1578,7 +1680,7 @@ bool LLAppViewer::loadSettingsFromDirectory(const std::string& location_key,
requirement = file.get("Requirement").asInteger();
}
- if(!gSettings[settings_group]->loadFromFile(full_settings_path, set_defaults))
+ if(!LLControlGroup::getInstance(settings_group)->loadFromFile(full_settings_path, set_defaults))
{
if(requirement == 1)
{
@@ -1618,17 +1720,17 @@ std::string LLAppViewer::getSettingsFilename(const std::string& location_key,
return std::string();
}
+void LLAppViewer::loadColorSettings()
+{
+ LLUIColorTable::instance().loadFromSettings();
+}
+
bool LLAppViewer::initConfiguration()
{
- //Set up internal pointers
- gSettings[sGlobalSettingsName] = &gSavedSettings;
- gSettings[sPerAccountSettingsName] = &gSavedPerAccountSettings;
- gSettings[sCrashSettingsName] = &gCrashSettings;
-
//Load settings files list
std::string settings_file_list = gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS, "settings_files.xml");
- LLControlGroup settings_control;
- llinfos << "Loading settings file list" << settings_file_list << llendl;
+ LLControlGroup settings_control("SettingsFiles");
+ llinfos << "Loading settings file list " << settings_file_list << llendl;
if (0 == settings_control.loadFromFile(settings_file_list))
{
llerrs << "Cannot load default configuration file " << settings_file_list << llendl;
@@ -1651,18 +1753,16 @@ bool LLAppViewer::initConfiguration()
if(!loadSettingsFromDirectory("Default", set_defaults))
{
std::ostringstream msg;
- msg << "Second Life could not load its default settings file. \n"
- << "The installation may be corrupted. \n";
-
- OSMessageBox(
- msg.str(),
- LLStringUtil::null,
- OSMB_OK);
-
+ msg << "Unable to load default settings file. The installation may be corrupted.";
+ OSMessageBox(msg.str(),LLStringUtil::null,OSMB_OK);
return false;
}
-
- // - set procedural settings
+
+ LLUI::setupPaths(); // setup paths for LLTrans based on settings files only
+ LLTransUtil::parseStrings("strings.xml", default_trans_args);
+ LLTransUtil::parseLanguageStrings("language_settings.xml");
+ // - set procedural settings
+ // Note: can't use LL_PATH_PER_SL_ACCOUNT for any of these since we haven't logged in yet
gSavedSettings.setString("ClientSettingsFile",
gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS, getSettingsFilename("Default", "Global")));
@@ -1685,7 +1785,7 @@ bool LLAppViewer::initConfiguration()
gSavedSettings.setBOOL("WatchdogEnabled", FALSE);
#endif
- gCrashSettings.getControl(CRASH_BEHAVIOR_SETTING)->getSignal()->connect(boost::bind(&handleCrashSubmitBehaviorChanged, _1));
+ gCrashSettings.getControl(CRASH_BEHAVIOR_SETTING)->getSignal()->connect(boost::bind(&handleCrashSubmitBehaviorChanged, _2));
// These are warnings that appear on the first experience of that condition.
// They are already set in the settings_default.xml file, but still need to be added to LLFirstUse
@@ -1696,7 +1796,7 @@ bool LLAppViewer::initConfiguration()
LLFirstUse::addConfigVariable("FirstMap");
LLFirstUse::addConfigVariable("FirstGoTo");
LLFirstUse::addConfigVariable("FirstBuild");
- LLFirstUse::addConfigVariable("FirstLeftClickNoHit");
+// LLFirstUse::addConfigVariable("FirstLeftClickNoHit");
LLFirstUse::addConfigVariable("FirstTeleport");
LLFirstUse::addConfigVariable("FirstOverrideKeys");
LLFirstUse::addConfigVariable("FirstAttach");
@@ -1715,26 +1815,18 @@ bool LLAppViewer::initConfiguration()
LLControlGroupCLP clp;
std::string cmd_line_config = gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS,
"cmd_line.xml");
+
clp.configure(cmd_line_config, &gSavedSettings);
if(!initParseCommandLine(clp))
{
- llwarns
- << "Error parsing command line options. Command Line options ignored."
- << llendl;
-
+ llwarns << "Error parsing command line options. Command Line options ignored." << llendl;
+
llinfos << "Command line usage:\n" << clp << llendl;
std::ostringstream msg;
- msg << "Second Life found an error parsing the command line. \n"
- << "Please see: http://wiki.secondlife.com/wiki/Client_parameters \n"
- << "Error: " << clp.getErrorMessage();
-
- OSMessageBox(
- msg.str(),
- LLStringUtil::null,
- OSMB_OK);
-
+ msg << LLTrans::getString("MBCmdLineError") << clp.getErrorMessage();
+ OSMessageBox(msg.str(),LLStringUtil::null,OSMB_OK);
return false;
}
@@ -1754,7 +1846,6 @@ bool LLAppViewer::initConfiguration()
// - load overrides from user_settings
loadSettingsFromDirectory("User");
-
// - apply command line settings
clp.notify();
@@ -1768,7 +1859,7 @@ bool LLAppViewer::initConfiguration()
if(clp.hasOption("help"))
{
std::ostringstream msg;
- msg << "Command line usage:\n" << clp;
+ msg << LLTrans::getString("MBCmdLineUsg") << "\n" << clp;
llinfos << msg.str() << llendl;
OSMessageBox(
@@ -1779,36 +1870,6 @@ bool LLAppViewer::initConfiguration()
return false;
}
- //////////////////////////
- // Apply settings...
- if(clp.hasOption("setdefault"))
- {
- //const LLCommandLineParser::token_vector_t& setdefault = clp.getOption("setdefault");
- //if(0x1 & setdefault.size())
- //{
- // llwarns << "Invalid '--setdefault' parameter count." << llendl;
- //}
- //else
- //{
- // LLCommandLineParser::token_vector_t::const_iterator itr = setdefault.begin();
- // for(; itr != setdefault.end(); ++itr)
- // {
- // const std::string& name = *itr;
- // const std::string& value = *(++itr);
- // LLControlVariable* c = gSettings[sGlobalSettingsName]->getControl(name);
- // if(c)
- // {
- // c->setDefault(value);
- // }
- // else
- // {
- // llwarns << "'--setdefault' specified with unknown setting: '"
- // << name << "'." << llendl;
- // }
- // }
- //}
- }
-
if(clp.hasOption("set"))
{
const LLCommandLineParser::token_vector_t& set_values = clp.getOption("set");
@@ -1823,7 +1884,7 @@ bool LLAppViewer::initConfiguration()
{
const std::string& name = *itr;
const std::string& value = *(++itr);
- LLControlVariable* c = gSettings[sGlobalSettingsName]->getControl(name);
+ LLControlVariable* c = LLControlGroup::getInstance(sGlobalSettingsName)->getControl(name);
if(c)
{
c->setValue(value, false);
@@ -1845,6 +1906,73 @@ bool LLAppViewer::initConfiguration()
gCrashOnStartup = TRUE;
}
+ if (clp.hasOption("logperformance"))
+ {
+ LLFastTimer::sLog = TRUE;
+ }
+
+ if(clp.hasOption("logmetrics"))
+ {
+ LLFastTimer::sMetricLog = TRUE ;
+ }
+
+ if (clp.hasOption("graphicslevel"))
+ {
+ const LLCommandLineParser::token_vector_t& value = clp.getOption("graphicslevel");
+ if(value.size() != 1)
+ {
+ llwarns << "Usage: -graphicslevel <0-3>" << llendl;
+ }
+ else
+ {
+ std::string detail = value.front();
+ mForceGraphicsDetail = TRUE;
+
+ switch (detail.c_str()[0])
+ {
+ case '0':
+ gSavedSettings.setU32("RenderQualityPerformance", 0);
+ break;
+ case '1':
+ gSavedSettings.setU32("RenderQualityPerformance", 1);
+ break;
+ case '2':
+ gSavedSettings.setU32("RenderQualityPerformance", 2);
+ break;
+ case '3':
+ gSavedSettings.setU32("RenderQualityPerformance", 3);
+ break;
+ default:
+ mForceGraphicsDetail = FALSE;
+ llwarns << "Usage: -graphicslevel <0-3>" << llendl;
+ break;
+ }
+ }
+ }
+
+ if (clp.hasOption("analyzeperformance"))
+ {
+ LLFastTimerView::sAnalyzePerformance = TRUE;
+ }
+
+ if (clp.hasOption("replaysession"))
+ {
+ LLAgentPilot::sReplaySession = TRUE;
+ }
+
+ if (clp.hasOption("nonotifications"))
+ {
+ gSavedSettings.setBOOL("IgnoreAllNotifications", TRUE);
+ }
+
+ if (clp.hasOption("debugsession"))
+ {
+ gDebugSession = TRUE;
+ gDebugGL = TRUE;
+
+ ll_init_fail_log(gDirUtilp->getExpandedFilename(LL_PATH_LOGS, "test_failures.log"));
+ }
+
// Handle slurl use. NOTE: Don't let SL-55321 reappear.
// *FIX: This init code should be made more robust to prevent
@@ -1865,7 +1993,7 @@ bool LLAppViewer::initConfiguration()
if(clp.hasOption("url"))
{
std::string slurl = clp.getOption("url")[0];
- if (LLURLDispatcher::isSLURLCommand(slurl))
+ if (LLSLURL::isSLURLCommand(slurl))
{
LLStartUp::sSLURLCommand = slurl;
}
@@ -1877,9 +2005,9 @@ bool LLAppViewer::initConfiguration()
else if(clp.hasOption("slurl"))
{
std::string slurl = clp.getOption("slurl")[0];
- if(LLURLDispatcher::isSLURL(slurl))
+ if(LLSLURL::isSLURL(slurl))
{
- if (LLURLDispatcher::isSLURLCommand(slurl))
+ if (LLSLURL::isSLURLCommand(slurl))
{
LLStartUp::sSLURLCommand = slurl;
}
@@ -1893,13 +2021,12 @@ bool LLAppViewer::initConfiguration()
const LLControlVariable* skinfolder = gSavedSettings.getControl("SkinCurrent");
if(skinfolder && LLStringUtil::null != skinfolder->getValue().asString())
{
- gDirUtilp->setSkinFolder(skinfolder->getValue().asString());
+ // hack to force the skin to default.
+ //gDirUtilp->setSkinFolder(skinfolder->getValue().asString());
+ gDirUtilp->setSkinFolder("default");
}
mYieldTime = gSavedSettings.getS32("YieldTime");
-
- // XUI:translate
- gSecondLife = "Second Life";
// Read skin/branding settings if specified.
//if (! gDirUtilp->getSkinDir().empty() )
@@ -1916,7 +2043,7 @@ bool LLAppViewer::initConfiguration()
#if LL_DARWIN
// Initialize apple menubar and various callbacks
- init_apple_menu(gSecondLife.c_str());
+ init_apple_menu(LLTrans::getString("APP_NAME").c_str());
#if __ppc__
// If the CPU doesn't have Altivec (i.e. it's not at least a G4), don't go any further.
@@ -1924,7 +2051,7 @@ bool LLAppViewer::initConfiguration()
if(!gSysCPU.hasAltivec())
{
std::ostringstream msg;
- msg << gSecondLife << " requires a processor with AltiVec (G4 or later).";
+ msg << LLTrans::getString("MBRequiresAltiVec");
OSMessageBox(
msg.str(),
LLStringUtil::null,
@@ -1939,7 +2066,7 @@ bool LLAppViewer::initConfiguration()
// Display splash screen. Must be after above check for previous
// crash as this dialog is always frontmost.
std::ostringstream splash_msg;
- splash_msg << "Loading " << gSecondLife << "...";
+ splash_msg << "Loading " << LLTrans::getString("SECOND_LIFE") << "...";
LLSplashScreen::show();
LLSplashScreen::update(splash_msg.str());
@@ -1955,12 +2082,11 @@ bool LLAppViewer::initConfiguration()
//
// Set the name of the window
//
-#if LL_RELEASE_FOR_DOWNLOAD
- gWindowTitle = gSecondLife;
-#elif LL_DEBUG
- gWindowTitle = gSecondLife + std::string(" [DEBUG] ") + gArgs;
+ gWindowTitle = LLTrans::getString("APP_NAME");
+#if LL_DEBUG
+ gWindowTitle += std::string(" [DEBUG] ") + gArgs;
#else
- gWindowTitle = gSecondLife + std::string(" ") + gArgs;
+ gWindowTitle += std::string(" ") + gArgs;
#endif
LLStringUtil::truncate(gWindowTitle, 255);
@@ -1997,11 +2123,7 @@ bool LLAppViewer::initConfiguration()
if (mSecondInstance)
{
std::ostringstream msg;
- msg <<
- gSecondLife << " is already running.\n"
- "\n"
- "Check your task bar for a minimized copy of the program.\n"
- "If this message persists, restart your computer.",
+ msg << LLTrans::getString("MBAlreadyRunning");
OSMessageBox(
msg.str(),
LLStringUtil::null,
@@ -2046,6 +2168,8 @@ bool LLAppViewer::initConfiguration()
gLastRunVersion = gSavedSettings.getString("LastRunVersion");
+ loadColorSettings();
+
return true; // Config was successful.
}
@@ -2074,12 +2198,8 @@ void LLAppViewer::checkForCrash(void)
if(gCrashSettings.getS32(CRASH_BEHAVIOR_SETTING) == CRASH_BEHAVIOR_ASK)
{
std::ostringstream msg;
- msg << gSecondLife
- << " appears to have frozen or crashed on the previous run.\n"
- << "Would you like to send a crash report?";
- std::string alert;
- alert = gSecondLife;
- alert += " Alert";
+ msg << LLTrans::getString("MBFrozenCrashed");
+ std::string alert = LLTrans::getString("APP_NAME") + " " + LLTrans::getString("MBAlert");
choice = OSMessageBox(msg.str(),
alert,
OSMB_YESNO);
@@ -2127,10 +2247,10 @@ bool LLAppViewer::initWindow()
gSavedSettings.getS32("WindowWidth"), gSavedSettings.getS32("WindowHeight"),
FALSE, ignorePixelDepth);
- if (gSavedSettings.getBOOL("FullScreen"))
+ if (gSavedSettings.getBOOL("WindowFullScreen"))
{
+ // request to go full screen... which will be delayed until login
gViewerWindow->toggleFullscreen(FALSE);
- // request to go full screen... which will be delayed until login
}
if (gSavedSettings.getBOOL("WindowMaximized"))
@@ -2145,6 +2265,11 @@ bool LLAppViewer::initWindow()
// Initialize GL stuff
//
+ if (mForceGraphicsDetail)
+ {
+ LLFeatureManager::getInstance()->setGraphicsLevel(gSavedSettings.getU32("RenderQualityPerformance"), false);
+ }
+
// Set this flag in case we crash while initializing GL
gSavedSettings.setBOOL("RenderInitError", TRUE);
gSavedSettings.saveToFile( gSavedSettings.getString("ClientSettingsFile"), TRUE );
@@ -2165,9 +2290,6 @@ bool LLAppViewer::initWindow()
LLUI::sWindow = gViewerWindow->getWindow();
- LLTrans::parseStrings("strings.xml");
- LLUITrans::parseStrings("ui_strings.xml");
-
// Show watch cursor
gViewerWindow->setCursor(UI_CURSOR_WAIT);
@@ -2287,7 +2409,7 @@ void LLAppViewer::writeSystemInfo()
gDebugInfo["CrashNotHandled"] = (LLSD::Boolean)true;
// Dump some debugging info
- LL_INFOS("SystemInfo") << gSecondLife
+ LL_INFOS("SystemInfo") << LLTrans::getString("APP_NAME")
<< " version " << LL_VERSION_MAJOR << "." << LL_VERSION_MINOR << "." << LL_VERSION_PATCH
<< LL_ENDL;
@@ -2365,7 +2487,7 @@ void LLAppViewer::handleViewerCrash()
gDebugInfo["CurrentPath"] = gDirUtilp->getCurPath();
gDebugInfo["SessionLength"] = F32(LLFrameTimer::getElapsedSeconds());
gDebugInfo["StartupState"] = LLStartUp::getStartupStateString();
- gDebugInfo["RAMInfo"]["Allocated"] = (LLSD::Integer) getCurrentRSS() >> 10;
+ gDebugInfo["RAMInfo"]["Allocated"] = (LLSD::Integer) LLMemory::getCurrentRSS() >> 10;
gDebugInfo["FirstLogin"] = (LLSD::Boolean) gAgent.isFirstLogin();
gDebugInfo["FirstRunThisInstall"] = gSavedSettings.getBOOL("FirstRunThisInstall");
@@ -2776,12 +2898,14 @@ bool LLAppViewer::initCache()
gDirUtilp->setCacheDir(gSavedSettings.getString("CacheLocation"));
purgeCache(); // purge old cache
gSavedSettings.setString("CacheLocation", new_cache_location);
+ gSavedSettings.setString("CacheLocationTopFolder", gDirUtilp->getBaseFileName(new_cache_location));
}
if (!gDirUtilp->setCacheDir(gSavedSettings.getString("CacheLocation")))
{
LL_WARNS("AppCache") << "Unable to set cache location" << LL_ENDL;
gSavedSettings.setString("CacheLocation", "");
+ gSavedSettings.setString("CacheLocationTopFolder", "");
}
if (mPurgeCache)
@@ -2961,12 +3085,12 @@ void LLAppViewer::purgeCache()
gDirUtilp->deleteFilesInDir(gDirUtilp->getExpandedFilename(LL_PATH_CACHE,""),mask);
}
-const std::string& LLAppViewer::getSecondLifeTitle() const
+std::string LLAppViewer::getSecondLifeTitle() const
{
- return gSecondLife;
+ return LLTrans::getString("APP_NAME");
}
-const std::string& LLAppViewer::getWindowTitle() const
+std::string LLAppViewer::getWindowTitle() const
{
return gWindowTitle;
}
@@ -3000,7 +3124,7 @@ void LLAppViewer::forceDisconnect(const std::string& mesg)
return;
}
- // Translate the message if possible
+ // *TODO: Translate the message if possible
std::string big_reason = LLAgent::sTeleportErrorMessages[mesg];
if ( big_reason.size() == 0 )
{
@@ -3128,6 +3252,15 @@ public:
}
};
+static LLFastTimer::DeclareTimer FTM_AUDIO_UPDATE("Update Audio");
+static LLFastTimer::DeclareTimer FTM_CLEANUP("Cleanup");
+static LLFastTimer::DeclareTimer FTM_IDLE_CB("Idle Callbacks");
+static LLFastTimer::DeclareTimer FTM_LOD_UPDATE("Update LOD");
+static LLFastTimer::DeclareTimer FTM_OBJECTLIST_UPDATE("Update Objectlist");
+static LLFastTimer::DeclareTimer FTM_REGION_UPDATE("Update Region");
+static LLFastTimer::DeclareTimer FTM_WORLD_UPDATE("Update World");
+static LLFastTimer::DeclareTimer FTM_NETWORK("Network");
+
///////////////////////////////////////////////////////
// idle()
//
@@ -3136,6 +3269,7 @@ public:
///////////////////////////////////////////////////////
void LLAppViewer::idle()
{
+ LLMemType mt_idle(LLMemType::MTYPE_IDLE);
pingMainloopTimeout("Main:Idle");
// Update frame timers
@@ -3179,7 +3313,6 @@ void LLAppViewer::idle()
//
// Special case idle if still starting up
//
-
if (LLStartUp::getStartupState() < STATE_STARTED)
{
// Skip rest if idle startup returns false (essentially, no world yet)
@@ -3194,7 +3327,7 @@ void LLAppViewer::idle()
if (!gDisconnected)
{
- LLFastTimer t(LLFastTimer::FTM_NETWORK);
+ LLFastTimer t(FTM_NETWORK);
// Update spaceserver timeinfo
LLWorld::getInstance()->setSpaceTimeUSec(LLWorld::getInstance()->getSpaceTimeUSec() + (U32)(dt_raw * SEC_TO_MICROSEC));
@@ -3219,7 +3352,7 @@ void LLAppViewer::idle()
// When appropriate, update agent location to the simulator.
F32 agent_update_time = agent_update_timer.getElapsedTimeF32();
BOOL flags_changed = gAgent.controlFlagsDirty() || (last_control_flags != gAgent.getControlFlags());
-
+
if (flags_changed || (agent_update_time > (1.0f / (F32) AGENT_UPDATES_PER_SECOND)))
{
// Send avatar and camera info
@@ -3234,7 +3367,6 @@ void LLAppViewer::idle()
// Manage statistics
//
//
-
{
// Initialize the viewer_stats_timer with an already elapsed time
// of SEND_STATS_PERIOD so that the initial stats report will
@@ -3272,12 +3404,11 @@ void LLAppViewer::idle()
gObjectList.mNumUnknownUpdates = 0;
}
}
- gFrameStats.addFrameData();
}
-
+
if (!gDisconnected)
{
- LLFastTimer t(LLFastTimer::FTM_NETWORK);
+ LLFastTimer t(FTM_NETWORK);
////////////////////////////////////////////////
//
@@ -3287,12 +3418,10 @@ void LLAppViewer::idle()
// floating throughout the various object lists.
//
- gFrameStats.start(LLFrameStats::IDLE_NETWORK);
stop_glerror();
idleNetwork();
stop_glerror();
- gFrameStats.start(LLFrameStats::AGENT_MISC);
// Check for away from keyboard, kick idle agents.
idle_afk_check();
@@ -3308,7 +3437,7 @@ void LLAppViewer::idle()
//
{
-// LLFastTimer t(LLFastTimer::FTM_IDLE_CB);
+// LLFastTimer t(FTM_IDLE_CB);
// Do event notifications if necessary. Yes, we may want to move this elsewhere.
gEventNotifier.update();
@@ -3321,7 +3450,7 @@ void LLAppViewer::idle()
return;
}
- gViewerWindow->handlePerFrameHover();
+ gViewerWindow->updateUI();
///////////////////////////////////////
// Agent and camera movement
@@ -3337,14 +3466,13 @@ void LLAppViewer::idle()
{
// Handle pending gesture processing
- gGestureManager.update();
+ LLGestureManager::instance().update();
gAgent.updateAgentPosition(gFrameDTClamped, yaw, current_mouse.mX, current_mouse.mY);
}
{
- LLFastTimer t(LLFastTimer::FTM_OBJECTLIST_UPDATE); // Actually "object update"
- gFrameStats.start(LLFrameStats::OBJECT_UPDATE);
+ LLFastTimer t(FTM_OBJECTLIST_UPDATE); // Actually "object update"
if (!(logoutRequestSent() && hasSavedFinalSnapshot()))
{
@@ -3359,8 +3487,7 @@ void LLAppViewer::idle()
//
{
- LLFastTimer t(LLFastTimer::FTM_CLEANUP);
- gFrameStats.start(LLFrameStats::CLEAN_DEAD);
+ LLFastTimer t(FTM_CLEANUP);
gObjectList.cleanDeadObjects();
LLDrawable::cleanupDeadDrawables();
}
@@ -3379,7 +3506,6 @@ void LLAppViewer::idle()
//
{
- gFrameStats.start(LLFrameStats::UPDATE_EFFECTS);
LLSelectMgr::getInstance()->updateEffects();
LLHUDManager::getInstance()->cleanupEffects();
LLHUDManager::getInstance()->sendEffects();
@@ -3393,7 +3519,7 @@ void LLAppViewer::idle()
//
{
- LLFastTimer t(LLFastTimer::FTM_NETWORK);
+ LLFastTimer t(FTM_NETWORK);
gVLManager.unpackData();
}
@@ -3405,7 +3531,7 @@ void LLAppViewer::idle()
LLWorld::getInstance()->updateVisibilities();
{
const F32 max_region_update_time = .001f; // 1ms
- LLFastTimer t(LLFastTimer::FTM_REGION_UPDATE);
+ LLFastTimer t(FTM_REGION_UPDATE);
LLWorld::getInstance()->updateRegions(max_region_update_time);
}
@@ -3452,11 +3578,9 @@ void LLAppViewer::idle()
if (!gNoRender)
{
- LLFastTimer t(LLFastTimer::FTM_WORLD_UPDATE);
- gFrameStats.start(LLFrameStats::UPDATE_MOVE);
+ LLFastTimer t(FTM_WORLD_UPDATE);
gPipeline.updateMove();
- gFrameStats.start(LLFrameStats::UPDATE_PARTICLES);
LLWorld::getInstance()->updateParticles();
}
stop_glerror();
@@ -3475,15 +3599,17 @@ void LLAppViewer::idle()
gAgent.updateCamera();
}
+ // update media focus
+ LLViewerMediaFocus::getInstance()->update();
+
// objects and camera should be in sync, do LOD calculations now
{
- LLFastTimer t(LLFastTimer::FTM_LOD_UPDATE);
+ LLFastTimer t(FTM_LOD_UPDATE);
gObjectList.updateApparentAngles(gAgent);
}
{
- gFrameStats.start(LLFrameStats::AUDIO);
- LLFastTimer t(LLFastTimer::FTM_AUDIO_UPDATE);
+ LLFastTimer t(FTM_AUDIO_UPDATE);
if (gAudiop)
{
@@ -3623,8 +3749,11 @@ void LLAppViewer::sendLogoutRequest()
static F32 CheckMessagesMaxTime = CHECK_MESSAGES_DEFAULT_MAX_TIME;
#endif
+static LLFastTimer::DeclareTimer FTM_IDLE_NETWORK("Network");
+
void LLAppViewer::idleNetwork()
{
+ LLMemType mt_in(LLMemType::MTYPE_IDLE_NETWORK);
pingMainloopTimeout("idleNetwork");
LLError::LLCallStacks::clear() ;
llpushcallstacks ;
@@ -3634,7 +3763,7 @@ void LLAppViewer::idleNetwork()
if (!gSavedSettings.getBOOL("SpeedTest"))
{
- LLFastTimer t(LLFastTimer::FTM_IDLE_NETWORK); // decode
+ LLFastTimer t(FTM_IDLE_NETWORK); // decode
// deal with any queued name requests and replies.
gCacheName->processPending();
@@ -3644,7 +3773,8 @@ void LLAppViewer::idleNetwork()
stop_glerror();
const S64 frame_count = gFrameCount; // U32->S64
F32 total_time = 0.0f;
- while (gMessageSystem->checkAllMessages(frame_count, gServicePump))
+
+ while (gMessageSystem->checkAllMessages(frame_count, gServicePump))
{
if (gDoDisconnect)
{
@@ -3673,6 +3803,7 @@ void LLAppViewer::idleNetwork()
break;
#endif
}
+
// Handle per-frame message system processing.
gMessageSystem->processAcks();
@@ -3711,7 +3842,7 @@ void LLAppViewer::idleNetwork()
}
}
llpushcallstacks ;
- gObjectList.mNumNewObjectsStat.addValue(gObjectList.mNumNewObjects);
+ LLViewerStats::getInstance()->mNumNewObjectsStat.addValue(gObjectList.mNumNewObjects);
// Retransmit unacknowledged packets.
gXferManager->retransmitUnackedPackets();
@@ -3752,7 +3883,6 @@ void LLAppViewer::disconnectViewer()
llinfos << "Disconnecting viewer!" << llendl;
// Dump our frame statistics
- gFrameStats.dump();
// Remember if we were flying
gSavedSettings.setBOOL("FlyingAtExit", gAgent.getFlying() );
@@ -3764,35 +3894,6 @@ void LLAppViewer::disconnectViewer()
{
gFloaterView->restoreAll();
}
-
-
- std::list<LLFloater*> floaters_to_close;
- for(LLView::child_list_const_iter_t it = gFloaterView->getChildList()->begin();
- it != gFloaterView->getChildList()->end();
- ++it)
- {
- // The following names are defined in the
- // floater_image_preview.xml
- // floater_sound_preview.xml
- // floater_animation_preview.xml
- // files.
- LLFloater* fl = static_cast<LLFloater*>(*it);
- if(fl
- && (fl->getName() == "Image Preview"
- || fl->getName() == "Sound Preview"
- || fl->getName() == "Animation Preview"
- ))
- {
- floaters_to_close.push_back(fl);
- }
- }
-
- while(!floaters_to_close.empty())
- {
- LLFloater* fl = floaters_to_close.front();
- floaters_to_close.pop_front();
- fl->close();
- }
}
if (LLSelectMgr::getInstance())
@@ -3800,20 +3901,22 @@ void LLAppViewer::disconnectViewer()
LLSelectMgr::getInstance()->deselectAll();
}
- if (!gNoRender)
+ // save inventory if appropriate
+ gInventory.cache(gInventory.getRootFolderID(), gAgent.getID());
+ if (gInventory.getLibraryRootFolderID().notNull()
+ && gInventory.getLibraryOwnerID().notNull())
{
- // save inventory if appropriate
- gInventory.cache(gAgent.getInventoryRootID(), gAgent.getID());
- if(gInventoryLibraryRoot.notNull() && gInventoryLibraryOwner.notNull())
- {
- gInventory.cache(gInventoryLibraryRoot, gInventoryLibraryOwner);
- }
+ gInventory.cache(
+ gInventory.getLibraryRootFolderID(),
+ gInventory.getLibraryOwnerID());
}
saveNameCache();
// close inventory interface, close all windows
- LLInventoryView::cleanup();
+ LLFloaterInventory::cleanup();
+
+ gAgentWearables.cleanup();
// Also writes cached agent settings to gSavedSettings
gAgent.cleanup();
@@ -3965,5 +4068,8 @@ void LLAppViewer::handleLoginComplete()
{
gDebugInfo["MainloopTimeoutState"] = LLAppViewer::instance()->mMainloopTimeout->getState();
}
+
+ mOnLoginCompleted();
+
writeDebugInfo();
}
diff --git a/indra/newview/llappviewer.h b/indra/newview/llappviewer.h
index a3b84759f5..646b677264 100644
--- a/indra/newview/llappviewer.h
+++ b/indra/newview/llappviewer.h
@@ -33,11 +33,20 @@
#ifndef LL_LLAPPVIEWER_H
#define LL_LLAPPVIEWER_H
+#include "llallocator.h"
+#include "llcontrol.h"
+#include "llsys.h" // for LLOSInfo
+
+class LLCommandLineParser;
+class LLFrameTimer;
+class LLPumpIO;
class LLTextureCache;
-class LLWorkerThread;
class LLTextureFetch;
+class LLTimer;
+class LLVFS;
class LLWatchdogTimeout;
-class LLCommandLineParser;
+class LLWorkerThread;
+
class LLAppViewer : public LLApp
{
@@ -96,8 +105,8 @@ public:
bool getPurgeCache() const { return mPurgeCache; }
- const std::string& getSecondLifeTitle() const; // The Second Life title.
- const std::string& getWindowTitle() const; // The window display name.
+ std::string getSecondLifeTitle() const; // The Second Life title.
+ std::string getWindowTitle() const; // The window display name.
void forceDisconnect(const std::string& msg); // Force disconnection, with a message to the user.
void badNetworkHandler(); // Cause a crash state due to bad network packet.
@@ -119,14 +128,13 @@ public:
virtual void forceErrorSoftwareException();
virtual void forceErrorDriverCrash();
- // *NOTE: There are currently 3 settings files:
- // "Global", "PerAccount" and "CrashSettings"
// The list is found in app_settings/settings_files.xml
// but since they are used explicitly in code,
// the follow consts should also do the trick.
static const std::string sGlobalSettingsName;
- static const std::string sPerAccountSettingsName;
- static const std::string sCrashSettingsName;
+
+ LLCachedControl<bool> mRandomizeFramerate;
+ LLCachedControl<bool> mPeriodicSlowFrame;
// Load settings from the location specified by loction_key.
// Key availale and rules for loading, are specified in
@@ -136,6 +144,7 @@ public:
std::string getSettingsFilename(const std::string& location_key,
const std::string& file);
+ void loadColorSettings();
// For thread debugging.
// llstartup needs to control init.
@@ -150,6 +159,15 @@ public:
// *NOTE:Mani Fix this for login abstraction!!
void handleLoginComplete();
+ LLAllocator & getAllocator() { return mAlloc; }
+
+ // On LoginCompleted callback
+ typedef boost::signals2::signal<void (void)> login_completed_signal_t;
+ login_completed_signal_t mOnLoginCompleted;
+ boost::signals2::connection setOnLoginCompletedCallback( const login_completed_signal_t::slot_type& cb ) { return mOnLoginCompleted.connect(cb); }
+
+ void purgeCache(); // Clear the local cache.
+
protected:
virtual bool initWindow(); // Initialize the viewer's window.
virtual bool initLogging(); // Initialize log files, logging system, return false on failure.
@@ -171,7 +189,7 @@ private:
void initGridChoice();
bool initCache(); // Initialize local client cache.
- void purgeCache(); // Clear the local cache.
+
// We have switched locations of both Mac and Windows cache, make sure
// files migrate and old cache is cleared out.
@@ -221,6 +239,8 @@ private:
bool mSavedFinalSnapshot;
+ bool mForceGraphicsDetail;
+
bool mQuitRequested; // User wants to quit, may have modified documents open.
bool mLogoutRequestSent; // Disconnect message sent to simulator, no longer safe to send messages to the sim.
S32 mYieldTime;
@@ -228,10 +248,13 @@ private:
LLWatchdogTimeout* mMainloopTimeout;
+ LLThread* mFastTimerLogThread;
// for tracking viewer<->region circuit death
bool mAgentRegionLastAlive;
LLUUID mAgentRegionLastID;
+ LLAllocator mAlloc;
+
public:
//some information for updater
typedef struct
@@ -297,9 +320,6 @@ extern LLTimer gLogoutTimer;
extern F32 gSimLastTime;
extern F32 gSimFrames;
-extern LLUUID gInventoryLibraryOwner;
-extern LLUUID gInventoryLibraryRoot;
-
extern BOOL gDisconnected;
// Map scale in pixels per region
diff --git a/indra/newview/llappviewerlinux.cpp b/indra/newview/llappviewerlinux.cpp
index d02e86a557..ed291c16a8 100644
--- a/indra/newview/llappviewerlinux.cpp
+++ b/indra/newview/llappviewerlinux.cpp
@@ -451,7 +451,7 @@ gboolean viewer_app_api_GoSLURL(ViewerAppAPI *obj, gchar *slurl, gboolean **succ
llinfos << "Was asked to go to slurl: " << slurl << llendl;
std::string url = slurl;
- LLWebBrowserCtrl* web = NULL;
+ LLMediaCtrl* web = NULL;
const bool trusted_browser = false;
if (LLURLDispatcher::dispatch(url, web, trusted_browser))
{
@@ -553,7 +553,7 @@ void LLAppViewerLinux::handleSyncCrashTrace()
void LLAppViewerLinux::handleCrashReporting(bool reportFreeze)
{
- std::string cmd =gDirUtilp->getAppRODataDir();
+ std::string cmd =gDirUtilp->getExecutableDir();
cmd += gDirUtilp->getDirDelimiter();
#if LL_LINUX
cmd += "linux-crash-logger.bin";
diff --git a/indra/newview/llappviewermacosx.cpp b/indra/newview/llappviewermacosx.cpp
index 080bd2edc0..2b3939d92f 100644
--- a/indra/newview/llappviewermacosx.cpp
+++ b/indra/newview/llappviewermacosx.cpp
@@ -50,7 +50,7 @@
#include <Carbon/Carbon.h>
#include "lldir.h"
#include <signal.h>
-class LLWebBrowserCtrl; // for LLURLDispatcher
+class LLMediaCtrl; // for LLURLDispatcher
namespace
{
@@ -188,7 +188,7 @@ bool LLAppViewerMacOSX::initParseCommandLine(LLCommandLineParser& clp)
// in the "General" tab, click the "Add Localization" button
// create a new localization for the language you're adding
// set the contents of the new localization of the file to the string corresponding to our localization
- // (i.e. "en-us", "ja", etc. Use the existing ones as a guide.)
+ // (i.e. "en", "ja", etc. Use the existing ones as a guide.)
CFURLRef url = CFBundleCopyResourceURL(CFBundleGetMainBundle(), CFSTR("language"), CFSTR("txt"), NULL);
char path[MAX_PATH];
if(CFURLGetFileSystemRepresentation(url, false, (UInt8 *)path, sizeof(path)))
@@ -476,7 +476,7 @@ OSErr AEGURLHandler(const AppleEvent *messagein, AppleEvent *reply, long refIn)
url.replace(0, prefix.length(), "secondlife:///app/");
}
- LLWebBrowserCtrl* web = NULL;
+ LLMediaCtrl* web = NULL;
const bool trusted_browser = false;
LLURLDispatcher::dispatch(url, web, trusted_browser);
}
diff --git a/indra/newview/llappviewerwin32.cpp b/indra/newview/llappviewerwin32.cpp
index 7a8d486b72..98d7ab712b 100644
--- a/indra/newview/llappviewerwin32.cpp
+++ b/indra/newview/llappviewerwin32.cpp
@@ -64,6 +64,7 @@
#include "llfindlocale.h"
#include "llcommandlineparser.h"
+#include "lltrans.h"
// *FIX:Mani - This hack is to fix a linker issue with libndofdev.lib
// The lib was compiled under VS2005 - in VS2003 we need to remap assert
@@ -84,7 +85,7 @@ LONG WINAPI viewer_windows_exception_handler(struct _EXCEPTION_POINTERS *excepti
{
// *NOTE:Mani - this code is stolen from LLApp, where its never actually used.
//OSMessageBox("Attach Debugger Now", "Error", OSMB_OK);
- // Translate the signals/exceptions into cross-platform stuff
+ // *TODO: Translate the signals/exceptions into cross-platform stuff
// Windows implementation
_tprintf( _T("Entering Windows Exception Handler...\n") );
llinfos << "Entering Windows Exception Handler..." << llendl;
@@ -444,33 +445,24 @@ bool LLAppViewerWin32::initHardwareTest()
// but vram.
vram_only = TRUE;
- LLSplashScreen::update("Detecting hardware...");
+ LLSplashScreen::update(LLTrans::getString("StartupDetectingHardware"));
LL_DEBUGS("AppInit") << "Attempting to poll DirectX for hardware info" << LL_ENDL;
gDXHardware.setWriteDebugFunc(write_debug_dx);
BOOL probe_ok = gDXHardware.getInfo(vram_only);
if (!probe_ok
- && gSavedSettings.getWarning("AboutDirectX9"))
+ && gWarningSettings.getBOOL("AboutDirectX9"))
{
LL_WARNS("AppInit") << "DirectX probe failed, alerting user." << LL_ENDL;
// Warn them that runnin without DirectX 9 will
// not allow us to tell them about driver issues
std::ostringstream msg;
- msg <<
- LLAppViewer::instance()->getSecondLifeTitle() << " is unable to detect DirectX 9.0b or greater.\n"
- "\n" <<
- LLAppViewer::instance()->getSecondLifeTitle() << " uses DirectX to detect hardware and/or\n"
- "outdated drivers that can cause stability problems,\n"
- "poor performance and crashes. While you can run\n" <<
- LLAppViewer::instance()->getSecondLifeTitle() << " without it, we highly recommend running\n"
- "with DirectX 9.0b\n"
- "\n"
- "Do you wish to continue?\n";
+ msg << LLTrans::getString ("MBNoDirectX");
S32 button = OSMessageBox(
msg.str(),
- "Warning",
+ LLTrans::getString("MBWarning"),
OSMB_YESNO);
if (OSBTN_NO== button)
{
@@ -478,7 +470,7 @@ bool LLAppViewerWin32::initHardwareTest()
LLWeb::loadURLExternal(DIRECTX_9_URL);
return false;
}
- gSavedSettings.setWarning("AboutDirectX9", FALSE);
+ gWarningSettings.setBOOL("AboutDirectX9", FALSE);
}
LL_DEBUGS("AppInit") << "Done polling DirectX for hardware info" << LL_ENDL;
@@ -487,7 +479,7 @@ bool LLAppViewerWin32::initHardwareTest()
// Disable so debugger can work
std::ostringstream splash_msg;
- splash_msg << "Loading " << LLAppViewer::instance()->getSecondLifeTitle() << "...";
+ splash_msg << LLTrans::getString("StartupLoading") << " " << LLAppViewer::instance()->getSecondLifeTitle() << "...";
LLSplashScreen::update(splash_msg.str());
}
diff --git a/indra/newview/llassetuploadresponders.cpp b/indra/newview/llassetuploadresponders.cpp
index 4fca9b1f19..827ae5855b 100644
--- a/indra/newview/llassetuploadresponders.cpp
+++ b/indra/newview/llassetuploadresponders.cpp
@@ -41,7 +41,7 @@
#include "llfilepicker.h"
#include "llnotify.h"
#include "llinventorymodel.h"
-#include "llinventoryview.h"
+#include "llfloaterinventory.h"
#include "llpermissionsflags.h"
#include "llpreviewnotecard.h"
#include "llpreviewscript.h"
@@ -58,10 +58,13 @@
#include "lltexlayer.h"
// library includes
+#include "lldir.h"
#include "lleconomy.h"
+#include "llfloaterreg.h"
#include "llfocusmgr.h"
#include "llscrolllistctrl.h"
#include "llsdserialize.h"
+#include "llvfs.h"
// When uploading multiple files, don't display any of them when uploading more than this number.
static const S32 FILE_COUNT_DISPLAY_THRESHOLD = 5;
@@ -282,19 +285,20 @@ void LLNewAgentInventoryResponder::uploadComplete(const LLSD& content)
// Show the preview panel for textures and sounds to let
// user know that the image (or snapshot) arrived intact.
- LLInventoryView* view = LLInventoryView::getActiveInventory();
+ LLFloaterInventory* view = LLFloaterInventory::getActiveInventory();
if(view)
{
- LLUICtrl* focus_ctrl = gFocusMgr.getKeyboardFocus();
+ LLFocusableElement* focus = gFocusMgr.getKeyboardFocus();
+
view->getPanel()->setSelection(content["new_inventory_item"].asUUID(), TAKE_FOCUS_NO);
if((LLAssetType::AT_TEXTURE == asset_type || LLAssetType::AT_SOUND == asset_type)
&& LLFilePicker::instance().getFileCount() <= FILE_COUNT_DISPLAY_THRESHOLD)
{
view->getPanel()->openSelected();
}
- //LLInventoryView::dumpSelectionInformation((void*)view);
+ //LLFloaterInventory::dumpSelectionInformation((void*)view);
// restore keyboard focus
- gFocusMgr.setKeyboardFocus(focus_ctrl);
+ gFocusMgr.setKeyboardFocus(focus);
}
}
else
@@ -337,11 +341,11 @@ void LLNewAgentInventoryResponder::uploadComplete(const LLSD& content)
}
LLSendTexLayerResponder::LLSendTexLayerResponder(const LLSD& post_data,
- const LLUUID& vfile_id,
- LLAssetType::EType asset_type,
- LLBakedUploadData * baked_upload_data)
- : LLAssetUploadResponder(post_data, vfile_id, asset_type),
- mBakedUploadData(baked_upload_data)
+ const LLUUID& vfile_id,
+ LLAssetType::EType asset_type,
+ LLBakedUploadData * baked_upload_data) :
+ LLAssetUploadResponder(post_data, vfile_id, asset_type),
+ mBakedUploadData(baked_upload_data)
{
}
@@ -419,72 +423,68 @@ void LLUpdateAgentInventoryResponder::uploadComplete(const LLSD& content)
LLInventoryType::EType inventory_type = new_item->getInventoryType();
switch(inventory_type)
{
- case LLInventoryType::IT_NOTECARD:
- {
-
- // Update the UI with the new asset.
- LLPreviewNotecard* nc;
- nc = (LLPreviewNotecard*)LLPreview::find(new_item->getUUID());
- if(nc)
- {
- // *HACK: we have to delete the asset in the VFS so
- // that the viewer will redownload it. This is only
- // really necessary if the asset had to be modified by
- // the uploader, so this can be optimized away in some
- // cases. A better design is to have a new uuid if the
- // script actually changed the asset.
- if(nc->hasEmbeddedInventory())
- {
- gVFS->removeFile(
- content["new_asset"].asUUID(),
- LLAssetType::AT_NOTECARD);
- }
- nc->refreshFromInventory();
- }
- }
- break;
- case LLInventoryType::IT_LSL:
- {
- // Find our window and close it if requested.
- LLPreviewLSL* preview = (LLPreviewLSL*)LLPreview::find(item_id);
- if (preview)
- {
- // Bytecode save completed
- if (content["compiled"])
- {
- preview->callbackLSLCompileSucceeded();
- }
- else
- {
- preview->callbackLSLCompileFailed(content["errors"]);
- }
- }
- }
- break;
-
- case LLInventoryType::IT_GESTURE:
- {
- // If this gesture is active, then we need to update the in-memory
- // active map with the new pointer.
- if (gGestureManager.isGestureActive(item_id))
- {
- LLUUID asset_id = new_item->getAssetUUID();
- gGestureManager.replaceGesture(item_id, asset_id);
- gInventory.notifyObservers();
- }
-
- //gesture will have a new asset_id
- LLPreviewGesture* previewp = (LLPreviewGesture*)LLPreview::find(item_id);
- if(previewp)
- {
- previewp->onUpdateSucceeded();
- }
+ case LLInventoryType::IT_NOTECARD:
+ {
+ // Update the UI with the new asset.
+ LLPreviewNotecard* nc = LLFloaterReg::findTypedInstance<LLPreviewNotecard>("preview_notecard", LLSD(item_id));
+ if(nc)
+ {
+ // *HACK: we have to delete the asset in the VFS so
+ // that the viewer will redownload it. This is only
+ // really necessary if the asset had to be modified by
+ // the uploader, so this can be optimized away in some
+ // cases. A better design is to have a new uuid if the
+ // script actually changed the asset.
+ if(nc->hasEmbeddedInventory())
+ {
+ gVFS->removeFile(content["new_asset"].asUUID(), LLAssetType::AT_NOTECARD);
+ }
+ nc->refreshFromInventory(new_item->getUUID());
+ }
+ break;
+ }
+ case LLInventoryType::IT_LSL:
+ {
+ // Find our window and close it if requested.
+ LLPreviewLSL* preview = LLFloaterReg::findTypedInstance<LLPreviewLSL>("preview_script", LLSD(item_id));
+ if (preview)
+ {
+ // Bytecode save completed
+ if (content["compiled"])
+ {
+ preview->callbackLSLCompileSucceeded();
+ }
+ else
+ {
+ preview->callbackLSLCompileFailed(content["errors"]);
+ }
+ }
+ break;
+ }
+
+ case LLInventoryType::IT_GESTURE:
+ {
+ // If this gesture is active, then we need to update the in-memory
+ // active map with the new pointer.
+ if (LLGestureManager::instance().isGestureActive(item_id))
+ {
+ LLUUID asset_id = new_item->getAssetUUID();
+ LLGestureManager::instance().replaceGesture(item_id, asset_id);
+ gInventory.notifyObservers();
+ }
+
+ //gesture will have a new asset_id
+ LLPreviewGesture* previewp = LLFloaterReg::findTypedInstance<LLPreviewGesture>("preview_gesture", LLSD(item_id));
+ if(previewp)
+ {
+ previewp->onUpdateSucceeded();
+ }
- }
- break;
- case LLInventoryType::IT_WEARABLE:
- default:
- break;
+ break;
+ }
+ case LLInventoryType::IT_WEARABLE:
+ default:
+ break;
}
}
@@ -522,64 +522,57 @@ void LLUpdateTaskInventoryResponder::uploadComplete(const LLSD& content)
switch(mAssetType)
{
- case LLAssetType::AT_NOTECARD:
- {
-
- // Update the UI with the new asset.
- LLPreviewNotecard* nc;
- nc = (LLPreviewNotecard*)LLPreview::find(item_id);
- if(nc)
- {
- // *HACK: we have to delete the asset in the VFS so
- // that the viewer will redownload it. This is only
- // really necessary if the asset had to be modified by
- // the uploader, so this can be optimized away in some
- // cases. A better design is to have a new uuid if the
- // script actually changed the asset.
- if(nc->hasEmbeddedInventory())
- {
- gVFS->removeFile(
- content["new_asset"].asUUID(),
- LLAssetType::AT_NOTECARD);
- }
-
- nc->refreshFromInventory();
- }
- }
- break;
- case LLAssetType::AT_LSL_TEXT:
- {
- if(mQueueId.notNull())
- {
- LLFloaterCompileQueue* queue =
- (LLFloaterCompileQueue*) LLFloaterScriptQueue::findInstance(mQueueId);
- if(NULL != queue)
- {
- queue->removeItemByItemID(item_id);
- }
- }
- else
- {
- LLLiveLSLEditor* preview = LLLiveLSLEditor::find(item_id, task_id);
- if (preview)
- {
- // Bytecode save completed
- if (content["compiled"])
- {
- preview->callbackLSLCompileSucceeded(
- task_id,
- item_id,
- mPostData["is_script_running"]);
- }
- else
- {
- preview->callbackLSLCompileFailed(content["errors"]);
- }
- }
- }
- }
- break;
- default:
+ case LLAssetType::AT_NOTECARD:
+ {
+ // Update the UI with the new asset.
+ LLPreviewNotecard* nc = LLFloaterReg::findTypedInstance<LLPreviewNotecard>("preview_notecard", LLSD(item_id));
+ if(nc)
+ {
+ // *HACK: we have to delete the asset in the VFS so
+ // that the viewer will redownload it. This is only
+ // really necessary if the asset had to be modified by
+ // the uploader, so this can be optimized away in some
+ // cases. A better design is to have a new uuid if the
+ // script actually changed the asset.
+ if(nc->hasEmbeddedInventory())
+ {
+ gVFS->removeFile(content["new_asset"].asUUID(),
+ LLAssetType::AT_NOTECARD);
+ }
+
+ nc->refreshFromInventory();
+ }
+ break;
+ }
+ case LLAssetType::AT_LSL_TEXT:
+ {
+ if(mQueueId.notNull())
+ {
+ LLFloaterCompileQueue* queue = LLFloaterReg::findTypedInstance<LLFloaterCompileQueue>("compile_queue", mQueueId);
+ if(NULL != queue)
+ {
+ queue->removeItemByItemID(item_id);
+ }
+ }
+ else
+ {
+ LLLiveLSLEditor* preview = LLFloaterReg::findTypedInstance<LLLiveLSLEditor>("preview_scriptedit", LLSD(item_id));
+ if (preview)
+ {
+ // Bytecode save completed
+ if (content["compiled"])
+ {
+ preview->callbackLSLCompileSucceeded(task_id, item_id, mPostData["is_script_running"]);
+ }
+ else
+ {
+ preview->callbackLSLCompileFailed(content["errors"]);
+ }
+ }
+ }
+ break;
+ }
+ default:
break;
}
}
diff --git a/indra/newview/llassetuploadresponders.h b/indra/newview/llassetuploadresponders.h
index 9ab571ae99..a08d70213c 100644
--- a/indra/newview/llassetuploadresponders.h
+++ b/indra/newview/llassetuploadresponders.h
@@ -47,6 +47,7 @@ public:
const std::string& file_name,
LLAssetType::EType asset_type);
~LLAssetUploadResponder();
+
virtual void error(U32 statusNum, const std::string& reason);
virtual void result(const LLSD& content);
virtual void uploadUpload(const LLSD& content);
diff --git a/indra/newview/llaudiosourcevo.h b/indra/newview/llaudiosourcevo.h
index e7bb2837a4..4b70f8bc20 100644
--- a/indra/newview/llaudiosourcevo.h
+++ b/indra/newview/llaudiosourcevo.h
@@ -34,7 +34,7 @@
#ifndef LL_LLAUDIOSOURCEVO_H
#define LL_LLAUDIOSOURCEVO_H
-#include "audioengine.h"
+#include "llaudioengine.h"
#include "llviewerobject.h"
class LLViewerObject;
diff --git a/indra/newview/llavataractions.cpp b/indra/newview/llavataractions.cpp
new file mode 100644
index 0000000000..5f71b6e3f6
--- /dev/null
+++ b/indra/newview/llavataractions.cpp
@@ -0,0 +1,291 @@
+/**
+ * @file llavataractions.cpp
+ * @brief Friend-related actions (add, remove, offer teleport, etc)
+ *
+ * $LicenseInfo:firstyear=2009&license=viewergpl$
+ *
+ * Copyright (c) 2009, Linden Research, Inc.
+ *
+ * Second Life Viewer Source Code
+ * The source code in this file ("Source Code") is provided by Linden Lab
+ * to you under the terms of the GNU General Public License, version 2.0
+ * ("GPL"), unless you have obtained a separate licensing agreement
+ * ("Other License"), formally executed by you and Linden Lab. Terms of
+ * the GPL can be found in doc/GPL-license.txt in this distribution, or
+ * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
+ *
+ * There are special exceptions to the terms and conditions of the GPL as
+ * it is applied to this Source Code. View the full text of the exception
+ * in the file doc/FLOSS-exception.txt in this software distribution, or
+ * online at
+ * http://secondlifegrid.net/programs/open_source/licensing/flossexception
+ *
+ * By copying, modifying or distributing this software, you acknowledge
+ * that you have read and understood your obligations described above,
+ * and agree to abide by those obligations.
+ *
+ * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+ * COMPLETENESS OR PERFORMANCE.
+ * $/LicenseInfo$
+ */
+
+
+#include "llviewerprecompiledheaders.h"
+
+#include "llavataractions.h"
+
+#include "llsd.h"
+#include "lldarray.h"
+#include "llnotifications.h"
+
+#include "llagent.h"
+#include "llappviewer.h" // for gLastVersionChannel
+#include "llcallingcard.h" // for LLAvatarTracker
+#include "llinventorymodel.h" // for gInventory.findCategoryUUIDForType
+#include "llimview.h" // for gIMMgr
+#include "llsidetray.h"
+#include "llviewermessage.h" // for handle_lure
+#include "llviewerregion.h"
+
+
+// static
+void LLAvatarActions::requestFriendshipDialog(const LLUUID& id, const std::string& name)
+{
+ if(id == gAgentID)
+ {
+ LLNotifications::instance().add("AddSelfFriend");
+ return;
+ }
+
+ LLSD args;
+ args["NAME"] = name;
+ LLSD payload;
+ payload["id"] = id;
+ payload["name"] = name;
+ // Look for server versions like: Second Life Server 1.24.4.95600
+ if (gLastVersionChannel.find(" 1.24.") != std::string::npos)
+ {
+ // Old and busted server version, doesn't support friend
+ // requests with messages.
+ LLNotifications::instance().add("AddFriend", args, payload, &callbackAddFriend);
+ }
+ else
+ {
+ LLNotifications::instance().add("AddFriendWithMessage", args, payload, &callbackAddFriendWithMessage);
+ }
+
+ // add friend to recent people list
+ LLRecentPeople::instance().add(id);
+}
+
+// static
+void LLAvatarActions::requestFriendshipDialog(const LLUUID& id)
+{
+ if(id.isNull())
+ {
+ return;
+ }
+
+ std::string full_name;
+ gCacheName->getFullName(id, full_name);
+ requestFriendshipDialog(id, full_name);
+}
+
+// static
+void LLAvatarActions::removeFriendDialog(const LLUUID& id)
+{
+ if (id.isNull())
+ return;
+
+ std::vector<LLUUID> ids;
+ ids.push_back(id);
+ removeFriendsDialog(ids);
+}
+
+// static
+void LLAvatarActions::removeFriendsDialog(const std::vector<LLUUID>& ids)
+{
+ if(ids.size() == 0)
+ return;
+
+ LLSD args;
+ std::string msgType;
+ if(ids.size() == 1)
+ {
+ LLUUID agent_id = ids[0];
+ std::string first, last;
+ if(gCacheName->getName(agent_id, first, last))
+ {
+ args["FIRST_NAME"] = first;
+ args["LAST_NAME"] = last;
+ }
+
+ msgType = "RemoveFromFriends";
+ }
+ else
+ {
+ msgType = "RemoveMultipleFromFriends";
+ }
+
+ LLSD payload;
+ for (std::vector<LLUUID>::const_iterator it = ids.begin(); it != ids.end(); ++it)
+ {
+ payload["ids"].append(*it);
+ }
+
+ LLNotifications::instance().add(msgType,
+ args,
+ payload,
+ &handleRemove);
+}
+
+// static
+void LLAvatarActions::offerTeleport(const LLUUID& invitee)
+{
+ if (invitee.isNull())
+ return;
+
+ LLDynamicArray<LLUUID> ids;
+ ids.push_back(invitee);
+ offerTeleport(ids);
+}
+
+// static
+void LLAvatarActions::offerTeleport(const std::vector<LLUUID>& ids)
+{
+ if (ids.size() > 0)
+ handle_lure(ids);
+}
+
+// static
+void LLAvatarActions::startIM(const LLUUID& id)
+{
+ if (id.isNull())
+ return;
+
+ std::string name;
+ gCacheName->getFullName(id, name);
+ gIMMgr->addSession(name, IM_NOTHING_SPECIAL, id);
+ make_ui_sound("UISndStartIM");
+}
+
+// static
+void LLAvatarActions::startConference(const std::vector<LLUUID>& ids)
+{
+ // *HACK: Copy into dynamic array
+ LLDynamicArray<LLUUID> id_array;
+ for (std::vector<LLUUID>::const_iterator it = ids.begin(); it != ids.end(); ++it)
+ {
+ id_array.push_back(*it);
+ }
+ gIMMgr->addSession("Friends Conference", IM_SESSION_CONFERENCE_START, ids[0], id_array);
+ make_ui_sound("UISndStartIM");
+}
+
+// static
+void LLAvatarActions::showProfile(const LLUUID& id)
+{
+ if (id.notNull())
+ {
+ LLSD params;
+ params["id"] = id;
+ params["open_tab_name"] = "panel_profile";
+
+ //Show own profile
+ if(gAgent.getID() == id)
+ {
+ LLSideTray::getInstance()->showPanel("panel_me_profile", params);
+ }
+ //Show other user profile
+ else
+ {
+ LLSideTray::getInstance()->showPanel("panel_profile_view", params);
+ }
+ }
+}
+
+//== private methods ========================================================================================
+
+// static
+bool LLAvatarActions::handleRemove(const LLSD& notification, const LLSD& response)
+{
+ S32 option = LLNotification::getSelectedOption(notification, response);
+
+ const LLSD& ids = notification["payload"]["ids"];
+ for (LLSD::array_const_iterator itr = ids.beginArray(); itr != ids.endArray(); ++itr)
+ {
+ LLUUID id = itr->asUUID();
+ const LLRelationship* ip = LLAvatarTracker::instance().getBuddyInfo(id);
+ if (ip)
+ {
+ switch (option)
+ {
+ case 0: // YES
+ if( ip->isRightGrantedTo(LLRelationship::GRANT_MODIFY_OBJECTS))
+ {
+ LLAvatarTracker::instance().empower(id, FALSE);
+ LLAvatarTracker::instance().notifyObservers();
+ }
+ LLAvatarTracker::instance().terminateBuddy(id);
+ LLAvatarTracker::instance().notifyObservers();
+ break;
+
+ case 1: // NO
+ default:
+ llinfos << "No removal performed." << llendl;
+ break;
+ }
+ }
+ }
+ return false;
+}
+
+// static
+bool LLAvatarActions::callbackAddFriendWithMessage(const LLSD& notification, const LLSD& response)
+{
+ S32 option = LLNotification::getSelectedOption(notification, response);
+ if (option == 0)
+ {
+ requestFriendship(notification["payload"]["id"].asUUID(),
+ notification["payload"]["name"].asString(),
+ response["message"].asString());
+ }
+ return false;
+}
+
+// static
+bool LLAvatarActions::callbackAddFriend(const LLSD& notification, const LLSD& response)
+{
+ S32 option = LLNotification::getSelectedOption(notification, response);
+ if (option == 0)
+ {
+ // Servers older than 1.25 require the text of the message to be the
+ // calling card folder ID for the offering user. JC
+ LLUUID calling_card_folder_id =
+ gInventory.findCategoryUUIDForType(LLAssetType::AT_CALLINGCARD);
+ std::string message = calling_card_folder_id.asString();
+ requestFriendship(notification["payload"]["id"].asUUID(),
+ notification["payload"]["name"].asString(),
+ message);
+ }
+ return false;
+}
+
+// static
+void LLAvatarActions::requestFriendship(const LLUUID& target_id, const std::string& target_name, const std::string& message)
+{
+ LLUUID calling_card_folder_id = gInventory.findCategoryUUIDForType(LLAssetType::AT_CALLINGCARD);
+ send_improved_im(target_id,
+ target_name,
+ message,
+ IM_ONLINE,
+ IM_FRIENDSHIP_OFFERED,
+ calling_card_folder_id);
+}
+
+//static
+bool LLAvatarActions::isFriend(const LLUUID& id)
+{
+ return ( NULL != LLAvatarTracker::instance().getBuddyInfo(id) );
+}
diff --git a/indra/newview/llavataractions.h b/indra/newview/llavataractions.h
new file mode 100644
index 0000000000..f3c411e033
--- /dev/null
+++ b/indra/newview/llavataractions.h
@@ -0,0 +1,93 @@
+/**
+ * @file llavataractions.h
+ * @brief Friend-related actions (add, remove, offer teleport, etc)
+ *
+ * $LicenseInfo:firstyear=2009&license=viewergpl$
+ *
+ * Copyright (c) 2009, Linden Research, Inc.
+ *
+ * Second Life Viewer Source Code
+ * The source code in this file ("Source Code") is provided by Linden Lab
+ * to you under the terms of the GNU General Public License, version 2.0
+ * ("GPL"), unless you have obtained a separate licensing agreement
+ * ("Other License"), formally executed by you and Linden Lab. Terms of
+ * the GPL can be found in doc/GPL-license.txt in this distribution, or
+ * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
+ *
+ * There are special exceptions to the terms and conditions of the GPL as
+ * it is applied to this Source Code. View the full text of the exception
+ * in the file doc/FLOSS-exception.txt in this software distribution, or
+ * online at
+ * http://secondlifegrid.net/programs/open_source/licensing/flossexception
+ *
+ * By copying, modifying or distributing this software, you acknowledge
+ * that you have read and understood your obligations described above,
+ * and agree to abide by those obligations.
+ *
+ * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+ * COMPLETENESS OR PERFORMANCE.
+ * $/LicenseInfo$
+ */
+
+#ifndef LL_LLAVATARACTIONS_H
+#define LL_LLAVATARACTIONS_H
+
+/**
+ * Friend-related actions (add, remove, offer teleport, etc)
+ */
+class LLAvatarActions
+{
+public:
+ /**
+ * Show a dialog explaining what friendship entails, then request friendship.
+ */
+ static void requestFriendshipDialog(const LLUUID& id, const std::string& name);
+
+ /**
+ * Show a dialog explaining what friendship entails, then request friendship.
+ */
+ static void requestFriendshipDialog(const LLUUID& id);
+
+ /**
+ * Show a friend removal dialog.
+ */
+ static void removeFriendDialog(const LLUUID& id);
+ static void removeFriendsDialog(const std::vector<LLUUID>& ids);
+
+ /**
+ * Show teleport offer dialog.
+ */
+ static void offerTeleport(const LLUUID& invitee);
+ static void offerTeleport(const std::vector<LLUUID>& ids);
+
+ /**
+ * Start instant messaging session.
+ */
+ static void startIM(const LLUUID& id);
+
+ /**
+ * Start conference chat with the given avatars.
+ */
+ static void startConference(const std::vector<LLUUID>& ids);
+
+ /**
+ * Show avatar profile.
+ */
+ static void showProfile(const LLUUID& id);
+
+ /**
+ * Return true if avatar with "id" is a friend
+ */
+ static bool isFriend(const LLUUID& id);
+
+private:
+ static bool callbackAddFriend(const LLSD& notification, const LLSD& response);
+ static bool callbackAddFriendWithMessage(const LLSD& notification, const LLSD& response);
+ static bool handleRemove(const LLSD& notification, const LLSD& response);
+
+ // Just request friendship, no dialog.
+ static void requestFriendship(const LLUUID& target_id, const std::string& target_name, const std::string& message);
+};
+
+#endif // LL_LLAVATARACTIONS_H
diff --git a/indra/newview/llavatariconctrl.cpp b/indra/newview/llavatariconctrl.cpp
new file mode 100644
index 0000000000..05addf3f3a
--- /dev/null
+++ b/indra/newview/llavatariconctrl.cpp
@@ -0,0 +1,294 @@
+/**
+ * @file llavatariconctrl.cpp
+ * @brief LLAvatarIconCtrl class implementation
+ *
+ * $LicenseInfo:firstyear=2009&license=viewergpl$
+ *
+ * Copyright (c) 2009, Linden Research, Inc.
+ *
+ * Second Life Viewer Source Code
+ * The source code in this file ("Source Code") is provided by Linden Lab
+ * to you under the terms of the GNU General Public License, version 2.0
+ * ("GPL"), unless you have obtained a separate licensing agreement
+ * ("Other License"), formally executed by you and Linden Lab. Terms of
+ * the GPL can be found in doc/GPL-license.txt in this distribution, or
+ * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
+ *
+ * There are special exceptions to the terms and conditions of the GPL as
+ * it is applied to this Source Code. View the full text of the exception
+ * in the file doc/FLOSS-exception.txt in this software distribution, or
+ * online at
+ * http://secondlifegrid.net/programs/open_source/licensing/flossexception
+ *
+ * By copying, modifying or distributing this software, you acknowledge
+ * that you have read and understood your obligations described above,
+ * and agree to abide by those obligations.
+ *
+ * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+ * COMPLETENESS OR PERFORMANCE.
+ * $/LicenseInfo$
+ */
+
+#include "llviewerprecompiledheaders.h"
+
+#include "llagent.h"
+#include "llavatarconstants.h"
+#include "llavatariconctrl.h"
+#include "llcallingcard.h" // for LLAvatarTracker
+#include "llavataractions.h"
+#include "llimview.h"
+#include "llmenugl.h"
+#include "lluictrlfactory.h"
+
+#include "llcachename.h"
+#include "llagentdata.h"
+
+#define MENU_ITEM_VIEW_PROFILE 0
+#define MENU_ITEM_SEND_IM 1
+
+static LLDefaultChildRegistry::Register<LLAvatarIconCtrl> r("avatar_icon");
+
+LLAvatarIconCtrl::avatar_image_map_t LLAvatarIconCtrl::sImagesCache;
+
+
+LLAvatarIconCtrl::Params::Params()
+: avatar_id("avatar_id"),
+ draw_tooltip("draw_tooltip", true)
+{
+ name = "avatar_icon";
+}
+
+
+LLAvatarIconCtrl::LLAvatarIconCtrl(const LLAvatarIconCtrl::Params& p)
+: LLIconCtrl(p),
+ mDrawTooltip(p.draw_tooltip)
+{
+ LLRect rect = p.rect;
+
+ static LLUICachedControl<S32> llavatariconctrl_symbol_hpad("UIAvatariconctrlSymbolHPad", 2);
+ static LLUICachedControl<S32> llavatariconctrl_symbol_vpad("UIAvatariconctrlSymbolVPad", 2);
+ static LLUICachedControl<S32> llavatariconctrl_symbol_size("UIAvatariconctrlSymbolSize", 5);
+ static LLUICachedControl<std::string> llavatariconctrl_symbol_pos("UIAvatariconctrlSymbolPosition", "BottomRight");
+
+ // BottomRight is the default position
+ S32 left = rect.getWidth() - llavatariconctrl_symbol_size - llavatariconctrl_symbol_hpad;
+ S32 bottom = llavatariconctrl_symbol_vpad;
+
+ if ("BottomLeft" == (std::string)llavatariconctrl_symbol_pos)
+ {
+ left = llavatariconctrl_symbol_hpad;
+ bottom = llavatariconctrl_symbol_vpad;
+ }
+ else if ("TopLeft" == (std::string)llavatariconctrl_symbol_pos)
+ {
+ left = llavatariconctrl_symbol_hpad;
+ bottom = rect.getHeight() - llavatariconctrl_symbol_size - llavatariconctrl_symbol_vpad;
+ }
+ else if ("TopRight" == (std::string)llavatariconctrl_symbol_pos)
+ {
+ left = rect.getWidth() - llavatariconctrl_symbol_size - llavatariconctrl_symbol_hpad;
+ bottom = rect.getHeight() - llavatariconctrl_symbol_size - llavatariconctrl_symbol_vpad;
+ }
+
+ rect.setOriginAndSize(left, bottom, llavatariconctrl_symbol_size, llavatariconctrl_symbol_size);
+
+ LLIconCtrl::Params icparams;
+ icparams.name ("Status Symbol");
+ icparams.follows.flags (FOLLOWS_RIGHT | FOLLOWS_BOTTOM);
+ icparams.rect (rect);
+ mStatusSymbol = LLUICtrlFactory::create<LLIconCtrl> (icparams);
+ mStatusSymbol->setValue("circle.tga");
+ mStatusSymbol->setColor(LLColor4::grey);
+
+ addChild(mStatusSymbol);
+
+ if (p.avatar_id.isProvided())
+ {
+ LLSD value(p.avatar_id);
+ setValue(value);
+ }
+ else
+ {
+ LLIconCtrl::setValue("default_profile_picture.j2c");
+ }
+
+
+ LLUICtrl::CommitCallbackRegistry::ScopedRegistrar registrar;
+
+ registrar.add("AvatarIcon.Action", boost::bind(&LLAvatarIconCtrl::onAvatarIconContextMenuItemClicked, this, _2));
+
+ LLMenuGL* menu = LLUICtrlFactory::getInstance()->createFromFile<LLMenuGL>("menu_avatar_icon.xml", gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance());
+
+ mPopupMenuHandle = menu->getHandle();
+}
+
+LLAvatarIconCtrl::~LLAvatarIconCtrl()
+{
+ if (mAvatarId.notNull())
+ {
+ LLAvatarPropertiesProcessor::getInstance()->removeObserver(mAvatarId, this);
+ // Name callbacks will be automatically disconnected since LLUICtrl is trackable
+ }
+
+ LLView::deleteViewByHandle(mPopupMenuHandle);
+}
+
+//virtual
+void LLAvatarIconCtrl::setValue(const LLSD& value)
+{
+ if (value.isUUID())
+ {
+ if (mAvatarId.notNull())
+ {
+ LLAvatarPropertiesProcessor::getInstance()->removeObserver(mAvatarId, this);
+ }
+
+ if (mAvatarId != value.asUUID())
+ {
+ LLAvatarPropertiesProcessor::getInstance()->addObserver(value.asUUID(), this);
+ LLAvatarPropertiesProcessor::getInstance()->sendDataRequest(value.asUUID(),APT_PROPERTIES);
+ mAvatarId = value.asUUID();
+
+ // Check if cache already contains image_id for that avatar
+ avatar_image_map_t::iterator it;
+
+ it = sImagesCache.find(mAvatarId);
+ if (it != sImagesCache.end())
+ {
+ updateFromCache(it->second);
+ }
+ }
+
+ }
+ else
+ {
+ LLIconCtrl::setValue(value);
+ }
+
+ gCacheName->get(mAvatarId, FALSE, boost::bind(&LLAvatarIconCtrl::nameUpdatedCallback, this, _1, _2, _3, _4));
+}
+
+void LLAvatarIconCtrl::updateFromCache(LLAvatarIconCtrl::LLImagesCacheItem data)
+{
+ // Update the avatar
+ if (data.image_id.notNull())
+ {
+ LLIconCtrl::setValue(data.image_id);
+ }
+ else
+ {
+ LLIconCtrl::setValue("default_profile_picture.j2c");
+ }
+
+ // Update color of status symbol and tool tip
+ if (data.flags & AVATAR_ONLINE)
+ {
+ mStatusSymbol->setColor(LLColor4::green);
+ if (mDrawTooltip)
+ {
+ setToolTip((LLStringExplicit)"Online");
+ }
+ }
+ else
+ {
+ mStatusSymbol->setColor(LLColor4::grey);
+ if (mDrawTooltip)
+ {
+ setToolTip((LLStringExplicit)"Offline");
+ }
+ }
+}
+
+//virtual
+void LLAvatarIconCtrl::processProperties(void* data, EAvatarProcessorType type)
+{
+ if (APT_PROPERTIES == type)
+ {
+ LLAvatarData* avatar_data = static_cast<LLAvatarData*>(data);
+ if (avatar_data)
+ {
+ if (avatar_data->avatar_id != mAvatarId)
+ {
+ return;
+ }
+
+ LLAvatarIconCtrl::LLImagesCacheItem data(avatar_data->image_id, avatar_data->flags);
+
+ updateFromCache(data);
+ sImagesCache.insert(std::pair<LLUUID, LLAvatarIconCtrl::LLImagesCacheItem>(mAvatarId, data));
+ }
+ }
+}
+
+BOOL LLAvatarIconCtrl::handleRightMouseDown(S32 x, S32 y, MASK mask)
+{
+ LLMenuGL* menu = (LLMenuGL*)mPopupMenuHandle.get();
+
+ if(menu)
+ {
+ bool is_friend = LLAvatarTracker::instance().getBuddyInfo(mAvatarId) != NULL;
+
+ menu->setItemEnabled("Add Friend", !is_friend);
+ menu->setItemEnabled("Remove Friend", is_friend);
+
+ if(gAgentID == mAvatarId)
+ {
+ menu->setItemEnabled("Add Friend", false);
+ menu->setItemEnabled("Send IM", false);
+ menu->setItemEnabled("Remove Friend", false);
+ }
+
+ menu->buildDrawLabels();
+ menu->updateParent(LLMenuGL::sMenuContainer);
+ LLMenuGL::showPopup(this, menu, x, y);
+ }
+
+ return TRUE;
+}
+
+void LLAvatarIconCtrl::nameUpdatedCallback(
+ const LLUUID& id,
+ const std::string& first,
+ const std::string& last,
+ BOOL is_group)
+{
+ if (id == mAvatarId)
+ {
+ mFirstName = first;
+ mLastName = last;
+ }
+}
+
+void LLAvatarIconCtrl::onAvatarIconContextMenuItemClicked(const LLSD& userdata)
+{
+ std::string level = userdata.asString();
+ LLUUID id = getAvatarId();
+
+ if (level == "profile")
+ {
+ LLAvatarActions::showProfile(id);
+ }
+ else if (level == "im")
+ {
+ std::string name;
+ name.assign(getFirstName());
+ name.append(" ");
+ name.append(getLastName());
+
+ gIMMgr->addSession(name, IM_NOTHING_SPECIAL, id);
+ }
+ else if (level == "add")
+ {
+ std::string name;
+ name.assign(getFirstName());
+ name.append(" ");
+ name.append(getLastName());
+
+ LLAvatarActions::requestFriendshipDialog(id, name);
+ }
+ else if (level == "remove")
+ {
+ LLAvatarActions::removeFriendDialog(id);
+ }
+}
diff --git a/indra/newview/llavatariconctrl.h b/indra/newview/llavatariconctrl.h
new file mode 100644
index 0000000000..49e304a521
--- /dev/null
+++ b/indra/newview/llavatariconctrl.h
@@ -0,0 +1,100 @@
+/**
+ * @file llavatariconctrl.h
+ * @brief LLAvatarIconCtrl base class
+ *
+ * $LicenseInfo:firstyear=2001&license=viewergpl$
+ *
+ * Copyright (c) 2001-2009, Linden Research, Inc.
+ *
+ * Second Life Viewer Source Code
+ * The source code in this file ("Source Code") is provided by Linden Lab
+ * to you under the terms of the GNU General Public License, version 2.0
+ * ("GPL"), unless you have obtained a separate licensing agreement
+ * ("Other License"), formally executed by you and Linden Lab. Terms of
+ * the GPL can be found in doc/GPL-license.txt in this distribution, or
+ * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
+ *
+ * There are special exceptions to the terms and conditions of the GPL as
+ * it is applied to this Source Code. View the full text of the exception
+ * in the file doc/FLOSS-exception.txt in this software distribution, or
+ * online at
+ * http://secondlifegrid.net/programs/open_source/licensing/flossexception
+ *
+ * By copying, modifying or distributing this software, you acknowledge
+ * that you have read and understood your obligations described above,
+ * and agree to abide by those obligations.
+ *
+ * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+ * COMPLETENESS OR PERFORMANCE.
+ * $/LicenseInfo$
+ */
+
+#ifndef LL_LLAVATARICONCTRL_H
+#define LL_LLAVATARICONCTRL_H
+
+#include "lliconctrl.h"
+#include "llavatarpropertiesprocessor.h"
+#include "llviewermenu.h"
+
+class LLAvatarIconCtrl
+: public LLIconCtrl, public LLAvatarPropertiesObserver
+{
+public:
+ struct Params : public LLInitParam::Block<Params, LLIconCtrl::Params>
+ {
+ Optional <LLUUID> avatar_id;
+ Optional <bool> draw_tooltip;
+ Params();
+ };
+
+protected:
+ LLAvatarIconCtrl(const Params&);
+ friend class LLUICtrlFactory;
+
+ void onAvatarIconContextMenuItemClicked(const LLSD& userdata);
+
+public:
+ virtual ~LLAvatarIconCtrl();
+
+ virtual void setValue(const LLSD& value);
+
+ // LLAvatarPropertiesProcessor observer trigger
+ virtual void processProperties(void* data, EAvatarProcessorType type);
+
+ BOOL handleRightMouseDown(S32 x, S32 y, MASK mask);
+
+ void nameUpdatedCallback(
+ const LLUUID& id,
+ const std::string& first,
+ const std::string& last,
+ BOOL is_group);
+
+ const LLUUID& getAvatarId() const { return mAvatarId; }
+ const std::string& getFirstName() const { return mFirstName; }
+ const std::string& getLastName() const { return mLastName; }
+
+protected:
+ LLIconCtrl* mStatusSymbol;
+ LLUUID mAvatarId;
+ std::string mFirstName;
+ std::string mLastName;
+ LLHandle<LLView> mPopupMenuHandle;
+ bool mDrawTooltip;
+
+ struct LLImagesCacheItem
+ {
+ LLUUID image_id;
+ U32 flags;
+
+ LLImagesCacheItem(LLUUID image_id_, U32 flags_) : image_id(image_id_), flags(flags_) {}
+ };
+
+ typedef std::map<LLUUID, LLAvatarIconCtrl::LLImagesCacheItem> avatar_image_map_t;
+
+ static avatar_image_map_t sImagesCache;
+
+ void updateFromCache(LLAvatarIconCtrl::LLImagesCacheItem data);
+};
+
+#endif // LL_LLAVATARICONCTRL_H
diff --git a/indra/newview/llavatarlist.cpp b/indra/newview/llavatarlist.cpp
new file mode 100644
index 0000000000..f557adf6a6
--- /dev/null
+++ b/indra/newview/llavatarlist.cpp
@@ -0,0 +1,291 @@
+/**
+ * @file llavatarlist.h
+ * @brief Generic avatar list
+ *
+ * $LicenseInfo:firstyear=2009&license=viewergpl$
+ *
+ * Copyright (c) 2009, Linden Research, Inc.
+ *
+ * Second Life Viewer Source Code
+ * The source code in this file ("Source Code") is provided by Linden Lab
+ * to you under the terms of the GNU General Public License, version 2.0
+ * ("GPL"), unless you have obtained a separate licensing agreement
+ * ("Other License"), formally executed by you and Linden Lab. Terms of
+ * the GPL can be found in doc/GPL-license.txt in this distribution, or
+ * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
+ *
+ * There are special exceptions to the terms and conditions of the GPL as
+ * it is applied to this Source Code. View the full text of the exception
+ * in the file doc/FLOSS-exception.txt in this software distribution, or
+ * online at
+ * http://secondlifegrid.net/programs/open_source/licensing/flossexception
+ *
+ * By copying, modifying or distributing this software, you acknowledge
+ * that you have read and understood your obligations described above,
+ * and agree to abide by those obligations.
+ *
+ * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+ * COMPLETENESS OR PERFORMANCE.
+ * $/LicenseInfo$
+ */
+
+#include "llviewerprecompiledheaders.h"
+
+#include "llavatarlist.h"
+
+// newview
+#include "llcallingcard.h" // for LLAvatarTracker
+#include "llcachename.h"
+#include "lloutputmonitorctrl.h"
+#include "llvoiceclient.h"
+
+static LLDefaultChildRegistry::Register<LLAvatarList> r("avatar_list");
+
+LLAvatarList::Params::Params()
+:
+ volume_column_width("volume_column_width", 0)
+ , online_go_first("online_go_first", true)
+{
+ draw_heading = true;
+ draw_stripes = false;
+ multi_select = false;
+ column_padding = 0;
+ search_column = COL_NAME;
+ sort_column = COL_NAME;
+}
+
+LLAvatarList::LLAvatarList(const Params& p)
+: LLScrollListCtrl(p)
+ , mHaveVolumeColumn(p.volume_column_width > 0)
+ , mOnlineGoFirst(p.online_go_first)
+{
+ setCommitOnSelectionChange(TRUE); // there's no such param in LLScrollListCtrl::Params
+
+ // "volume" column
+ {
+ LLScrollListColumn::Params col_params;
+ col_params.name = "volume";
+ col_params.header.label = "Volume"; // *TODO: localize or remove the header
+ col_params.width.pixel_width = p.volume_column_width;
+ addColumn(col_params);
+ }
+
+ // "name" column
+ {
+ LLScrollListColumn::Params col_params;
+ col_params.name = "name";
+ col_params.header.label = "Name"; // *TODO: localize or remove the header
+ col_params.width.dynamic_width = true;
+ addColumn(col_params);
+ }
+
+ // "online status" column
+ {
+ LLScrollListColumn::Params col_params;
+ col_params.name = "online";
+ col_params.header.label = "Online"; // *TODO: localize or remove the header
+ col_params.width.pixel_width = 0; // invisible column
+ addColumn(col_params);
+ }
+
+
+ // invisible "id" column
+ {
+ LLScrollListColumn::Params col_params;
+ col_params.name = "id";
+ col_params.header.label = "ID"; // *TODO: localize or remove the header
+ col_params.width.pixel_width = 0;
+ addColumn(col_params);
+ }
+
+ // Primary sort = online status, secondary sort = name
+ // The corresponding parameters don't work because we create columns dynamically.
+ sortByColumnIndex(COL_NAME, TRUE);
+ if (mOnlineGoFirst)
+ sortByColumnIndex(COL_ONLINE, FALSE);
+ setSearchColumn(COL_NAME);
+}
+
+// virtual
+void LLAvatarList::draw()
+{
+ LLScrollListCtrl::draw();
+ if (mHaveVolumeColumn)
+ {
+ updateVolume();
+ }
+}
+
+std::vector<LLUUID> LLAvatarList::getSelectedIDs()
+{
+ LLUUID selected_id;
+ std::vector<LLUUID> avatar_ids;
+ std::vector<LLScrollListItem*> selected = getAllSelected();
+ for(std::vector<LLScrollListItem*>::iterator itr = selected.begin(); itr != selected.end(); ++itr)
+ {
+ avatar_ids.push_back((*itr)->getUUID());
+ }
+ return avatar_ids;
+}
+
+void LLAvatarList::addItem(const LLUUID& id, const std::string& name, BOOL is_bold, EAddPosition pos)
+{
+ std::string fullname;
+
+ // Populate list item.
+ LLSD element;
+ element["id"] = id;
+
+ // Update volume column (if we have one)
+ {
+ std::string icon = mHaveVolumeColumn ? getVolumeIcon(id) : "";
+ LLSD& volume_column = element["columns"][COL_VOLUME];
+ volume_column["column"] = "volume";
+ volume_column["type"] = "icon";
+ volume_column["value"] = icon;
+ }
+
+ LLSD& friend_column = element["columns"][COL_NAME];
+ friend_column["column"] = "name";
+ friend_column["value"] = name;
+
+ LLSD& online_column = element["columns"][COL_ONLINE];
+ online_column["column"] = "online";
+ online_column["value"] = is_bold ? "1" : "0";
+
+ LLScrollListItem* new_itemp = addElement(element, pos);
+
+ // Indicate buddy online status.
+ // (looks like parsing font parameters from LLSD is broken)
+ if (is_bold)
+ {
+ LLScrollListText* name_textp = dynamic_cast<LLScrollListText*>(new_itemp->getColumn(COL_NAME));
+ if (name_textp)
+ name_textp->setFontStyle(LLFontGL::BOLD);
+ else
+ {
+ llwarns << "Name column not found" << llendl;
+ }
+ }
+}
+
+static bool findInsensitive(std::string haystack, const std::string& needle_upper)
+{
+ LLStringUtil::toUpper(haystack);
+ return haystack.find(needle_upper) != std::string::npos;
+}
+
+BOOL LLAvatarList::update(const std::vector<LLUUID>& all_buddies, const std::string& name_filter)
+{
+ BOOL have_names = TRUE;
+
+ // Save selection.
+ std::vector<LLUUID> selected_ids = getSelectedIDs();
+ LLUUID current_id = getCurrentID();
+ S32 pos = getScrollPos();
+
+ std::vector<LLUUID>::const_iterator buddy_it = all_buddies.begin();
+ deleteAllItems();
+ for(; buddy_it != all_buddies.end(); ++buddy_it)
+ {
+ std::string name;
+ const LLUUID& buddy_id = *buddy_it;
+ have_names &= gCacheName->getFullName(buddy_id, name);
+ if (name_filter != LLStringUtil::null && !findInsensitive(name, name_filter))
+ continue;
+ addItem(buddy_id, name, LLAvatarTracker::instance().isBuddyOnline(buddy_id));
+ }
+
+ // Changed item in place, need to request sort and update columns
+ // because we might have changed data in a column on which the user
+ // has already sorted. JC
+ updateSort();
+
+ // re-select items
+ selectMultiple(selected_ids);
+ setCurrentByID(current_id);
+#if 0
+ // Restore selection.
+ if(selected_ids.size() > 0)
+ {
+ // only non-null if friends was already found. This may fail,
+ // but we don't really care here, because refreshUI() will
+ // clean up the interface.
+ for(std::vector<LLUUID>::iterator itr = selected_ids.begin(); itr != selected_ids.end(); ++itr)
+ {
+ setSelectedByValue(*itr, true);
+ }
+ }
+#endif
+ setScrollPos(pos);
+
+ return have_names;
+}
+
+// static
+std::string LLAvatarList::getVolumeIcon(const LLUUID& id)
+{
+ //
+ // Determine icon appropriate for the current avatar volume.
+ //
+ // *TODO: remove this in favor of LLOutputMonitorCtrl
+ // when ListView widget is implemented
+ // which is capable of containing arbitrary widgets.
+ //
+ static LLOutputMonitorCtrl::Params default_monitor_params(LLUICtrlFactory::getDefaultParams<LLOutputMonitorCtrl>());
+ bool muted = gVoiceClient->getIsModeratorMuted(id) || gVoiceClient->getOnMuteList(id);
+ F32 power = gVoiceClient->getCurrentPower(id);
+ std::string icon;
+
+ if (muted)
+ {
+ icon = default_monitor_params.image_mute.name;
+ }
+ else if (power == 0.f)
+ {
+ icon = default_monitor_params.image_off.name;
+ }
+ else if (power < LLVoiceClient::OVERDRIVEN_POWER_LEVEL)
+ {
+ S32 icon_image_idx = llmin(2, llfloor((power / LLVoiceClient::OVERDRIVEN_POWER_LEVEL) * 3.f));
+ switch(icon_image_idx)
+ {
+ default:
+ case 0:
+ icon = default_monitor_params.image_on.name;
+ break;
+ case 1:
+ icon = default_monitor_params.image_level_1.name;
+ break;
+ case 2:
+ icon = default_monitor_params.image_level_2.name;
+ break;
+ }
+ }
+ else
+ {
+ // overdriven
+ icon = default_monitor_params.image_level_3.name;
+ }
+
+ return icon;
+}
+
+// Update volume column for all list rows.
+void LLAvatarList::updateVolume()
+{
+ item_list& items = getItemList();
+
+ for (item_list::iterator item_it = items.begin();
+ item_it != items.end();
+ ++item_it)
+ {
+ LLScrollListItem* itemp = (*item_it);
+ LLUUID speaker_id = itemp->getUUID();
+
+ LLScrollListCell* icon_cell = itemp->getColumn(COL_VOLUME);
+ if (icon_cell)
+ icon_cell->setValue(getVolumeIcon(speaker_id));
+ }
+}
diff --git a/indra/newview/llavatarlist.h b/indra/newview/llavatarlist.h
new file mode 100644
index 0000000000..8b419dbb57
--- /dev/null
+++ b/indra/newview/llavatarlist.h
@@ -0,0 +1,78 @@
+/**
+ * @file llavatarlist.h
+ * @brief Generic avatar list
+ *
+ * $LicenseInfo:firstyear=2009&license=viewergpl$
+ *
+ * Copyright (c) 2009, Linden Research, Inc.
+ *
+ * Second Life Viewer Source Code
+ * The source code in this file ("Source Code") is provided by Linden Lab
+ * to you under the terms of the GNU General Public License, version 2.0
+ * ("GPL"), unless you have obtained a separate licensing agreement
+ * ("Other License"), formally executed by you and Linden Lab. Terms of
+ * the GPL can be found in doc/GPL-license.txt in this distribution, or
+ * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
+ *
+ * There are special exceptions to the terms and conditions of the GPL as
+ * it is applied to this Source Code. View the full text of the exception
+ * in the file doc/FLOSS-exception.txt in this software distribution, or
+ * online at
+ * http://secondlifegrid.net/programs/open_source/licensing/flossexception
+ *
+ * By copying, modifying or distributing this software, you acknowledge
+ * that you have read and understood your obligations described above,
+ * and agree to abide by those obligations.
+ *
+ * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+ * COMPLETENESS OR PERFORMANCE.
+ * $/LicenseInfo$
+ */
+
+#ifndef LL_LLAVATARLIST_H
+#define LL_LLAVATARLIST_H
+
+#include <llscrolllistctrl.h>
+
+// *TODO: derive from ListView when it's ready.
+class LLAvatarList : public LLScrollListCtrl
+{
+ LOG_CLASS(LLAvatarList);
+public:
+ struct Params : public LLInitParam::Block<Params, LLScrollListCtrl::Params>
+ {
+ Optional<S32> volume_column_width;
+ Optional<bool> online_go_first;
+ Params();
+ };
+
+ enum EColumnOrder
+ {
+ COL_VOLUME,
+ COL_NAME,
+ COL_ONLINE,
+ COL_ID,
+ };
+
+ LLAvatarList(const Params&);
+ virtual ~LLAvatarList() {}
+
+ /*virtual*/ void draw();
+
+ BOOL update(const std::vector<LLUUID>& all_buddies,
+ const std::string& name_filter = LLStringUtil::null);
+
+protected:
+ std::vector<LLUUID> getSelectedIDs();
+ void addItem(const LLUUID& id, const std::string& name, BOOL is_bold, EAddPosition pos = ADD_BOTTOM);
+
+private:
+ static std::string getVolumeIcon(const LLUUID& id); /// determine volume icon from current avatar volume
+ void updateVolume(); // update volume for all avatars
+
+ bool mHaveVolumeColumn;
+ bool mOnlineGoFirst;
+};
+
+#endif // LL_LLAVATARLIST_H
diff --git a/indra/newview/llavatarlistitem.cpp b/indra/newview/llavatarlistitem.cpp
new file mode 100644
index 0000000000..253c2ee9a6
--- /dev/null
+++ b/indra/newview/llavatarlistitem.cpp
@@ -0,0 +1,274 @@
+/**
+ * @file llavatarlistitem.cpp
+ * @avatar list item source file
+ *
+ * $LicenseInfo:firstyear=2004&license=viewergpl$
+ *
+ * Copyright (c) 2004-2009, Linden Research, Inc.
+ *
+ * Second Life Viewer Source Code
+ * The source code in this file ("Source Code") is provided by Linden Lab
+ * to you under the terms of the GNU General Public License, version 2.0
+ * ("GPL"), unless you have obtained a separate licensing agreement
+ * ("Other License"), formally executed by you and Linden Lab. Terms of
+ * the GPL can be found in doc/GPL-license.txt in this distribution, or
+ * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
+ *
+ * There are special exceptions to the terms and conditions of the GPL as
+ * it is applied to this Source Code. View the full text of the exception
+ * in the file doc/FLOSS-exception.txt in this software distribution, or
+ * online at
+ * http://secondlifegrid.net/programs/open_source/licensing/flossexception
+ *
+ * By copying, modifying or distributing this software, you acknowledge
+ * that you have read and understood your obligations described above,
+ * and agree to abide by those obligations.
+ *
+ * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+ * COMPLETENESS OR PERFORMANCE.
+ * $/LicenseInfo$
+ */
+
+
+#include "llviewerprecompiledheaders.h"
+
+#include "llfloaterreg.h"
+#include "llavatarlistitem.h"
+#include "llagent.h"
+
+
+
+//---------------------------------------------------------------------------------
+LLAvatarListItem::LLAvatarListItem(const Params& p) : LLPanel()
+{
+ mNeedsArrange = false;
+ LLUICtrlFactory::getInstance()->buildPanel(this, "panel_avatar_list_item.xml");
+
+ mStatus = NULL;
+ mInfo = NULL;
+ mProfile = NULL;
+ mInspector = NULL;
+
+ mAvatar = getChild<LLAvatarIconCtrl>("avatar_icon");
+ //mAvatar->setValue(p.avatar_icon);
+ mName = getChild<LLTextBox>("name");
+ //mName->setText(p.user_name);
+
+ init(p);
+
+
+}
+
+//---------------------------------------------------------------------------------
+void LLAvatarListItem::init(const Params& p)
+{
+ mLocator = getChild<LLIconCtrl>("locator");
+
+ mStatus = getChild<LLTextBox>("user_status");
+
+ mInfo = getChild<LLButton>("info_btn");
+ mInfo->setVisible(false);
+
+ mProfile = getChild<LLButton>("profile_btn");
+ mProfile->setVisible(false);
+
+ if(!p.buttons.locator)
+ {
+ mLocator->setVisible(false);
+ delete mLocator;
+ mLocator = NULL;
+ }
+
+ if(!p.buttons.status)
+ {
+ mStatus->setVisible(false);
+ delete mStatus;
+ mStatus = NULL;
+ }
+
+ if(!p.buttons.info)
+ {
+ delete mInfo;
+ mInfo = NULL;
+ }
+ else
+ {
+ mInfo->setClickedCallback(boost::bind(&LLAvatarListItem::onInfoBtnClick, this));
+ }
+
+ if(!p.buttons.profile)
+ {
+ delete mProfile;
+ mProfile = NULL;
+
+ LLRect rect;
+
+ rect.setLeftTopAndSize(mName->getRect().mLeft, mName->getRect().mTop, mName->getRect().getWidth() + 30, mName->getRect().getHeight());
+ mName->setRect(rect);
+
+ if(mStatus)
+ {
+ rect.setLeftTopAndSize(mStatus->getRect().mLeft + 30, mStatus->getRect().mTop, mStatus->getRect().getWidth(), mStatus->getRect().getHeight());
+ mStatus->setRect(rect);
+ }
+
+ if(mLocator)
+ {
+ rect.setLeftTopAndSize(mLocator->getRect().mLeft + 30, mLocator->getRect().mTop, mLocator->getRect().getWidth(), mLocator->getRect().getHeight());
+ mLocator->setRect(rect);
+ }
+
+ if(mInfo)
+ {
+ rect.setLeftTopAndSize(mInfo->getRect().mLeft + 30, mInfo->getRect().mTop, mInfo->getRect().getWidth(), mInfo->getRect().getHeight());
+ mInfo->setRect(rect);
+ }
+ }
+
+}
+
+//---------------------------------------------------------------------------------
+void LLAvatarListItem::reshape(S32 width, S32 height, BOOL called_from_parent)
+{
+ if(!mNeedsArrange)
+ {
+ LLView::reshape(width, height, called_from_parent);
+ return;
+ }
+
+ LLRect rect;
+ S32 profile_delta = 0;
+ S32 width_delta = getRect().getWidth() - width;
+
+ if(!mProfile)
+ {
+ profile_delta = 30;
+ }
+ else
+ {
+ rect.setLeftTopAndSize(mProfile->getRect().mLeft - width_delta, mProfile->getRect().mTop, mProfile->getRect().getWidth(), mProfile->getRect().getHeight());
+ mProfile->setRect(rect);
+ }
+
+ width_delta += profile_delta;
+
+ if(mInfo)
+ {
+ rect.setLeftTopAndSize(mInfo->getRect().mLeft - width_delta, mInfo->getRect().mTop, mInfo->getRect().getWidth(), mInfo->getRect().getHeight());
+ mInfo->setRect(rect);
+ }
+
+ if(mLocator)
+ {
+ rect.setLeftTopAndSize(mLocator->getRect().mLeft - width_delta, mLocator->getRect().mTop, mLocator->getRect().getWidth(), mLocator->getRect().getHeight());
+ mLocator->setRect(rect);
+ }
+
+ if(mStatus)
+ {
+ rect.setLeftTopAndSize(mStatus->getRect().mLeft - width_delta, mStatus->getRect().mTop, mStatus->getRect().getWidth(), mStatus->getRect().getHeight());
+ mStatus->setRect(rect);
+ }
+
+ mNeedsArrange = false;
+ LLView::reshape(width, height, called_from_parent);
+}
+
+//---------------------------------------------------------------------------------
+LLAvatarListItem::~LLAvatarListItem()
+{
+}
+//---------------------------------------------------------------------------------
+
+//---------------------------------------------------------------------------------
+BOOL LLAvatarListItem::handleHover(S32 x, S32 y, MASK mask)
+{
+ mYPos = y;
+ mXPos = x;
+
+ return true;
+}
+
+//---------------------------------------------------------------------------------
+void LLAvatarListItem::onMouseEnter(S32 x, S32 y, MASK mask)
+{
+ setTransparentColor( *(new LLColor4((F32)0.4, (F32)0.4, (F32)0.4)) );
+
+ if(mInfo)
+ mInfo->setVisible(true);
+
+ if(mProfile)
+ mProfile->setVisible(true);
+}
+
+//---------------------------------------------------------------------------------
+void LLAvatarListItem::onMouseLeave(S32 x, S32 y, MASK mask)
+{
+ if(mInfo)
+ {
+ if( mInfo->getRect().pointInRect(x, y) )
+ return;
+
+ mInfo->setVisible(false);
+ }
+
+ if(mProfile)
+ {
+ if( mProfile->getRect().pointInRect(x, y) )
+ return;
+
+ mProfile->setVisible(false);
+ }
+
+ setTransparentColor( *(new LLColor4((F32)0.3, (F32)0.3, (F32)0.3)) );
+}
+
+//---------------------------------------------------------------------------------
+void LLAvatarListItem::setStatus(int status)
+{
+}
+
+//---------------------------------------------------------------------------------
+void LLAvatarListItem::setName(std::string name)
+{
+}
+
+//---------------------------------------------------------------------------------
+void LLAvatarListItem::setAvatar(LLSD& data)
+{
+}
+
+//---------------------------------------------------------------------------------
+void LLAvatarListItem::onInfoBtnClick()
+{
+ mInspector = LLFloaterReg::showInstance("inspect_avatar", gAgent.getID());
+
+ if (!mInspector)
+ return;
+
+ LLRect rect;
+ localPointToScreen(mXPos, mYPos, &mXPos, &mYPos);
+
+
+ // *TODO Vadim: rewrite this. "+= -" looks weird.
+ S32 delta = mYPos - mInspector->getRect().getHeight();
+ if(delta < 0)
+ {
+ mYPos += -delta;
+ }
+
+ rect.setLeftTopAndSize(mXPos, mYPos,
+ mInspector->getRect().getWidth(), mInspector->getRect().getHeight());
+ mInspector->setRect(rect);
+ mInspector->setFrontmost(true);
+ mInspector->setVisible(true);
+
+}
+
+//---------------------------------------------------------------------------------
+void LLAvatarListItem::onProfileBtnClick()
+{
+}
+
+//---------------------------------------------------------------------------------
diff --git a/indra/newview/llavatarlistitem.h b/indra/newview/llavatarlistitem.h
new file mode 100644
index 0000000000..b41e0ff209
--- /dev/null
+++ b/indra/newview/llavatarlistitem.h
@@ -0,0 +1,104 @@
+/**
+ * @file llavatarlistitem.h
+ * @avatar list item header file
+ *
+ * $LicenseInfo:firstyear=2004&license=viewergpl$
+ *
+ * Copyright (c) 2004-2009, Linden Research, Inc.
+ *
+ * Second Life Viewer Source Code
+ * The source code in this file ("Source Code") is provided by Linden Lab
+ * to you under the terms of the GNU General Public License, version 2.0
+ * ("GPL"), unless you have obtained a separate licensing agreement
+ * ("Other License"), formally executed by you and Linden Lab. Terms of
+ * the GPL can be found in doc/GPL-license.txt in this distribution, or
+ * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
+ *
+ * There are special exceptions to the terms and conditions of the GPL as
+ * it is applied to this Source Code. View the full text of the exception
+ * in the file doc/FLOSS-exception.txt in this software distribution, or
+ * online at
+ * http://secondlifegrid.net/programs/open_source/licensing/flossexception
+ *
+ * By copying, modifying or distributing this software, you acknowledge
+ * that you have read and understood your obligations described above,
+ * and agree to abide by those obligations.
+ *
+ * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+ * COMPLETENESS OR PERFORMANCE.
+ * $/LicenseInfo$
+ */
+
+#include "llavatariconctrl.h"
+#include <llview.h>
+#include <llpanel.h>
+#include <llfloater.h>
+#include <lltextbox.h>
+#include <llbutton.h>
+#include <lluuid.h>
+
+//#include "llfloaterminiinspector.h"
+
+class LLAvatarListItem : public LLPanel
+{
+public:
+ struct Params : public LLInitParam::Block<Params, LLPanel::Params>
+ {
+ Optional<LLUUID> avatar_icon;
+ Optional<std::string> user_name;
+ struct avatar_list_item_buttons
+ {
+ bool status;
+ bool info;
+ bool profile;
+ bool locator;
+ avatar_list_item_buttons() : status(true), info(true), profile(true), locator(true)
+ {};
+ } buttons;
+
+ Params()
+ : avatar_icon("avatar_icon"),
+ user_name("user_name")
+ {};
+ };
+
+
+ LLAvatarListItem(const Params& p);
+ virtual ~LLAvatarListItem();
+
+ void reshape(S32 width, S32 height, BOOL called_from_parent);
+
+ //interface
+ void setStatus(int status);
+ void setName(std::string name);
+ void setAvatar(LLSD& data);
+ void needsArrange( void ) {mNeedsArrange = true;}
+
+
+ //event handlers
+ //mouse
+ virtual BOOL handleHover(S32 x, S32 y, MASK mask);
+ virtual void onMouseLeave(S32 x, S32 y, MASK mask);
+ virtual void onMouseEnter(S32 x, S32 y, MASK mask);
+ //buttons
+ void onInfoBtnClick();
+ void onProfileBtnClick();
+
+private:
+ LLAvatarIconCtrl* mAvatar;
+ LLIconCtrl* mLocator;
+ LLTextBox* mName;
+ LLTextBox* mStatus;
+ LLButton* mInfo;
+ LLButton* mProfile;
+
+ S32 mYPos;
+ S32 mXPos;
+
+ LLFloater* mInspector;
+ bool mNeedsArrange;
+
+ //
+ void init(const Params& p);
+};
diff --git a/indra/newview/llavatarpropertiesprocessor.cpp b/indra/newview/llavatarpropertiesprocessor.cpp
new file mode 100644
index 0000000000..ecd67e44ae
--- /dev/null
+++ b/indra/newview/llavatarpropertiesprocessor.cpp
@@ -0,0 +1,442 @@
+/**
+ * @file llavatarpropertiesprocessor.cpp
+ * @brief LLAvatarPropertiesProcessor class implementation
+ *
+ * $LicenseInfo:firstyear=2001&license=viewergpl$
+ *
+ * Copyright (c) 2001-2009, Linden Research, Inc.
+ *
+ * Second Life Viewer Source Code
+ * The source code in this file ("Source Code") is provided by Linden Lab
+ * to you under the terms of the GNU General Public License, version 2.0
+ * ("GPL"), unless you have obtained a separate licensing agreement
+ * ("Other License"), formally executed by you and Linden Lab. Terms of
+ * the GPL can be found in doc/GPL-license.txt in this distribution, or
+ * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
+ *
+ * There are special exceptions to the terms and conditions of the GPL as
+ * it is applied to this Source Code. View the full text of the exception
+ * in the file doc/FLOSS-exception.txt in this software distribution, or
+ * online at
+ * http://secondlifegrid.net/programs/open_source/licensing/flossexception
+ *
+ * By copying, modifying or distributing this software, you acknowledge
+ * that you have read and understood your obligations described above,
+ * and agree to abide by those obligations.
+ *
+ * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+ * COMPLETENESS OR PERFORMANCE.
+ * $/LicenseInfo$
+ */
+
+#include "llviewerprecompiledheaders.h"
+
+#include "llavatarpropertiesprocessor.h"
+
+#include "message.h"
+#include "llagent.h"
+#include "llviewergenericmessage.h"
+
+LLAvatarPropertiesProcessor::LLAvatarPropertiesProcessor()
+{
+}
+
+void LLAvatarPropertiesProcessor::addObserver(const LLUUID& avatar_id, LLAvatarPropertiesObserver* observer)
+{
+ // Check if that observer is already in mObservers for that avatar_id
+ observer_multimap_t::iterator it;
+
+ // IAN BUG this should update the observer's UUID if this is a dupe - sent to PE
+ it = mObservers.find(avatar_id);
+ while (it != mObservers.end())
+ {
+ if (it->second == observer)
+ {
+ return;
+ }
+ else
+ {
+ ++it;
+ }
+ }
+
+ mObservers.insert(std::pair<LLUUID, LLAvatarPropertiesObserver*>(avatar_id, observer));
+}
+
+void LLAvatarPropertiesProcessor::removeObserver(const LLUUID& avatar_id, LLAvatarPropertiesObserver* observer)
+{
+ if (!observer)
+ {
+ return;
+ }
+
+ observer_multimap_t::iterator it;
+ it = mObservers.find(avatar_id);
+ while (it != mObservers.end())
+ {
+ if (it->second == observer)
+ {
+ mObservers.erase(it);
+ break;
+ }
+ else
+ {
+ ++it;
+ }
+ }
+}
+
+void LLAvatarPropertiesProcessor::sendDataRequest(const LLUUID& avatar_id, EAvatarProcessorType type,
+ const void * data)
+{
+ switch(type)
+ {
+ case APT_PROPERTIES:
+ sendAvatarPropertiesRequest(avatar_id);
+ break;
+ case APT_PICKS:
+ sendGenericRequest(avatar_id, "avatarpicksrequest");
+ break;
+ case APT_PICK_INFO:
+ if (data) {
+ sendPickInfoRequest(avatar_id, *static_cast<const LLUUID*>(data));
+ }
+ break;
+ case APT_NOTES:
+ sendGenericRequest(avatar_id, "avatarnotesrequest");
+ break;
+ case APT_GROUPS:
+ sendGenericRequest(avatar_id, "avatargroupsrequest");
+ break;
+ default:
+ break;
+ }
+}
+
+void LLAvatarPropertiesProcessor::sendGenericRequest(const LLUUID& avatar_id, const std::string method)
+{
+ std::vector<std::string> strings;
+ strings.push_back( avatar_id.asString() );
+ send_generic_message(method, strings);
+}
+
+void LLAvatarPropertiesProcessor::sendAvatarPropertiesRequest(const LLUUID& avatar_id)
+{
+ LLMessageSystem *msg = gMessageSystem;
+
+ msg->newMessageFast(_PREHASH_AvatarPropertiesRequest);
+ msg->nextBlockFast( _PREHASH_AgentData);
+ msg->addUUIDFast( _PREHASH_AgentID, gAgent.getID() );
+ msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
+ msg->addUUIDFast( _PREHASH_AvatarID, avatar_id);
+ gAgent.sendReliableMessage();
+}
+
+void LLAvatarPropertiesProcessor::sendDataUpdate(const void* data, EAvatarProcessorType type)
+{
+ switch(type)
+ {
+ case APT_PROPERTIES:
+ sendAvatarPropertiesUpdate(data);
+ break;
+ case APT_PICK_INFO:
+ sendPicInfoUpdate(data);
+ case APT_PICKS:
+// sendGenericRequest(avatar_id, "avatarpicksrequest");
+ break;
+ case APT_NOTES:
+// sendGenericRequest(avatar_id, "avatarnotesrequest");
+ break;
+ case APT_GROUPS:
+// sendGenericRequest(avatar_id, "avatargroupsrequest");
+ break;
+ default:
+ break;
+ }
+
+}
+void LLAvatarPropertiesProcessor::sendAvatarPropertiesUpdate(const void* data)
+{
+ llinfos << "Sending avatarinfo update" << llendl;
+
+ const LLAvatarData* avatar_props = static_cast<const LLAvatarData*>(data);
+ // This value is required by sendAvatarPropertiesUpdate method.
+ //A profile should never be mature. (From the original code)
+ BOOL mature = FALSE;
+
+
+
+ LLMessageSystem *msg = gMessageSystem;
+
+ msg->newMessageFast(_PREHASH_AvatarPropertiesUpdate);
+ msg->nextBlockFast(_PREHASH_AgentData);
+ msg->addUUIDFast( _PREHASH_AgentID, gAgent.getID() );
+ msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID() );
+ msg->nextBlockFast(_PREHASH_PropertiesData);
+
+ msg->addUUIDFast( _PREHASH_ImageID, avatar_props->image_id);
+ msg->addUUIDFast( _PREHASH_FLImageID, avatar_props->fl_image_id);
+ msg->addStringFast( _PREHASH_AboutText, avatar_props->about_text);
+ msg->addStringFast( _PREHASH_FLAboutText, avatar_props->fl_about_text);
+
+ msg->addBOOL(_PREHASH_AllowPublish, avatar_props->allow_publish);
+ msg->addBOOL(_PREHASH_MaturePublish, mature);
+ msg->addString(_PREHASH_ProfileURL, avatar_props->profile_url);
+ gAgent.sendReliableMessage();
+}
+
+void LLAvatarPropertiesProcessor::processAvatarPropertiesReply(LLMessageSystem* msg, void**)
+{
+ LLAvatarData avatar_data;
+
+ msg->getUUIDFast( _PREHASH_AgentData, _PREHASH_AgentID, avatar_data.agent_id);
+ msg->getUUIDFast( _PREHASH_AgentData, _PREHASH_AvatarID, avatar_data.avatar_id);
+ msg->getUUIDFast( _PREHASH_PropertiesData, _PREHASH_ImageID, avatar_data.image_id);
+ msg->getUUIDFast( _PREHASH_PropertiesData, _PREHASH_FLImageID, avatar_data.fl_image_id);
+ msg->getUUIDFast( _PREHASH_PropertiesData, _PREHASH_PartnerID, avatar_data.partner_id);
+ msg->getStringFast( _PREHASH_PropertiesData, _PREHASH_AboutText, avatar_data.about_text);
+ msg->getStringFast( _PREHASH_PropertiesData, _PREHASH_FLAboutText, avatar_data.fl_about_text);
+ msg->getStringFast( _PREHASH_PropertiesData, _PREHASH_BornOn, avatar_data.born_on);
+ msg->getString( _PREHASH_PropertiesData, _PREHASH_ProfileURL, avatar_data.profile_url);
+ msg->getU32Fast( _PREHASH_PropertiesData, _PREHASH_Flags, avatar_data.flags);
+
+
+ avatar_data.caption_index = 0;
+
+ S32 charter_member_size = 0;
+ charter_member_size = msg->getSize(_PREHASH_PropertiesData, _PREHASH_CharterMember);
+ if(1 == charter_member_size)
+ {
+ msg->getBinaryData(_PREHASH_PropertiesData, _PREHASH_CharterMember, &avatar_data.caption_index, 1);
+ }
+ else if(1 < charter_member_size)
+ {
+ msg->getString(_PREHASH_PropertiesData, _PREHASH_CharterMember, avatar_data.caption_text);
+ }
+ notifyObservers(avatar_data.avatar_id,&avatar_data,APT_PROPERTIES);
+}
+
+void LLAvatarPropertiesProcessor::processAvatarInterestsReply(LLMessageSystem* msg, void**)
+{
+/*
+ AvatarInterestsReply is automatically sent by the server in response to the
+ AvatarPropertiesRequest sent when the panel is opened (in addition to the AvatarPropertiesReply message).
+ If the interests panel is no longer part of the design (?) we should just register the message
+ to a handler function that does nothing.
+ That will suppress the warnings and be compatible with old server versions.
+ WARNING: LLTemplateMessageReader::decodeData: Message from 216.82.37.237:13000 with no handler function received: AvatarInterestsReply
+*/
+}
+void LLAvatarPropertiesProcessor::processAvatarClassifiedReply(LLMessageSystem* msg, void**)
+{
+ // avatarclassifiedsrequest is not sent according to new UI design but
+ // keep this method according to resolved issues.
+}
+void LLAvatarPropertiesProcessor::processAvatarNotesReply(LLMessageSystem* msg, void**)
+{
+ LLAvatarNotes avatar_notes;
+
+ msg->getUUID(_PREHASH_AgentData, _PREHASH_AgentID, avatar_notes.agent_id);
+ msg->getUUID(_PREHASH_Data, _PREHASH_TargetID, avatar_notes.target_id);
+ msg->getString(_PREHASH_Data, _PREHASH_Notes, avatar_notes.notes);
+
+ notifyObservers(avatar_notes.target_id,&avatar_notes,APT_NOTES);
+}
+
+void LLAvatarPropertiesProcessor::processAvatarPicksReply(LLMessageSystem* msg, void**)
+{
+ LLAvatarPicks avatar_picks;
+ msg->getUUID(_PREHASH_AgentData, _PREHASH_AgentID, avatar_picks.target_id);
+ msg->getUUID(_PREHASH_AgentData, _PREHASH_TargetID, avatar_picks.target_id);
+
+ S32 block_count = msg->getNumberOfBlocks(_PREHASH_Data);
+ for (int block = 0; block < block_count; ++block)
+ {
+ LLUUID pick_id;
+ std::string pick_name;
+
+ msg->getUUID(_PREHASH_Data, _PREHASH_PickID, pick_id, block);
+ msg->getString(_PREHASH_Data, _PREHASH_PickName, pick_name, block);
+
+ avatar_picks.picks_list.push_back(std::make_pair(pick_id,pick_name));
+ }
+ notifyObservers(avatar_picks.target_id,&avatar_picks,APT_PICKS);
+}
+
+void LLAvatarPropertiesProcessor::processPickInfoReply(LLMessageSystem* msg, void**)
+{
+ LLPickData pick_data;
+
+ // Extract the agent id and verify the message is for this
+ // client.
+ msg->getUUID(_PREHASH_AgentData, _PREHASH_AgentID, pick_data.agent_id );
+ msg->getUUID(_PREHASH_Data, _PREHASH_PickID, pick_data.pick_id);
+ msg->getUUID(_PREHASH_Data, _PREHASH_CreatorID, pick_data.creator_id);
+
+ // ** top_pick should be deleted, not being used anymore - angela
+ msg->getBOOL(_PREHASH_Data, _PREHASH_TopPick, pick_data.top_pick);
+ msg->getUUID(_PREHASH_Data, _PREHASH_ParcelID, pick_data.parcel_id);
+ msg->getString(_PREHASH_Data, _PREHASH_Name, pick_data.name);
+ msg->getString(_PREHASH_Data, _PREHASH_Desc, pick_data.desc);
+ msg->getUUID(_PREHASH_Data, _PREHASH_SnapshotID, pick_data.snapshot_id);
+
+ // "Location text" is actually the owner name, the original
+ // name that owner gave the parcel, and the location.
+ msg->getString(_PREHASH_Data, _PREHASH_User, pick_data.location_text);
+ pick_data.location_text.append(", ");
+
+ msg->getString(_PREHASH_Data, _PREHASH_OriginalName, pick_data.original_name);
+ if (!pick_data.original_name.empty())
+ {
+ pick_data.location_text.append(pick_data.original_name);
+ pick_data.location_text.append(", ");
+ }
+
+ msg->getString(_PREHASH_Data, _PREHASH_SimName, pick_data.sim_name);
+ pick_data.location_text.append(pick_data.sim_name);
+ pick_data.location_text.append(" ");
+
+ msg->getVector3d(_PREHASH_Data, _PREHASH_PosGlobal, pick_data.pos_global);
+ S32 region_x = llround((F32)pick_data.pos_global.mdV[VX]) % REGION_WIDTH_UNITS;
+ S32 region_y = llround((F32)pick_data.pos_global.mdV[VY]) % REGION_WIDTH_UNITS;
+ S32 region_z = llround((F32)pick_data.pos_global.mdV[VZ]);
+ pick_data.location_text.append(llformat("(%d, %d, %d)", region_x, region_y, region_z));
+
+ msg->getS32(_PREHASH_Data, _PREHASH_SortOrder, pick_data.sort_order);
+ msg->getBOOL(_PREHASH_Data, _PREHASH_Enabled, pick_data.enabled);
+
+ notifyObservers(pick_data.creator_id, &pick_data, APT_PICK_INFO);
+}
+
+void LLAvatarPropertiesProcessor::processAvatarGroupsReply(LLMessageSystem* msg, void**)
+{
+ LLAvatarGroups avatar_groups;
+ msg->getUUIDFast(_PREHASH_AgentData, _PREHASH_AgentID, avatar_groups.agent_id );
+ msg->getUUIDFast(_PREHASH_AgentData, _PREHASH_AvatarID, avatar_groups.avatar_id );
+
+ S32 group_count = msg->getNumberOfBlocksFast(_PREHASH_GroupData);
+ for(S32 i = 0; i < group_count; ++i)
+ {
+ LLAvatarGroups::LLGroupData group_data;
+
+ msg->getU64( _PREHASH_GroupData, _PREHASH_GroupPowers, group_data.group_powers, i );
+ msg->getStringFast(_PREHASH_GroupData, _PREHASH_GroupTitle, group_data.group_title, i );
+ msg->getUUIDFast( _PREHASH_GroupData, _PREHASH_GroupID, group_data.group_id, i);
+ msg->getStringFast(_PREHASH_GroupData, _PREHASH_GroupName, group_data.group_name, i );
+ msg->getUUIDFast( _PREHASH_GroupData, _PREHASH_GroupInsigniaID, group_data.group_insignia_id, i );
+
+ avatar_groups.group_list.push_back(group_data);
+ }
+
+ notifyObservers(avatar_groups.avatar_id,&avatar_groups,APT_GROUPS);
+}
+
+void LLAvatarPropertiesProcessor::notifyObservers(const LLUUID& id,void* data, EAvatarProcessorType type)
+{
+ LLAvatarPropertiesProcessor::observer_multimap_t observers = LLAvatarPropertiesProcessor::getInstance()->mObservers;
+
+ observer_multimap_t::iterator oi = observers.lower_bound(id);
+ observer_multimap_t::iterator end = observers.upper_bound(id);
+ for (; oi != end; ++oi)
+ {
+ oi->second->processProperties(data,type);
+ }
+}
+
+void LLAvatarPropertiesProcessor::sendFriendRights(const LLUUID& avatar_id, S32 rights)
+{
+ if(!avatar_id.isNull())
+ {
+ LLMessageSystem* msg = gMessageSystem;
+
+ // setup message header
+ msg->newMessageFast(_PREHASH_GrantUserRights);
+ msg->nextBlockFast(_PREHASH_AgentData);
+ msg->addUUID(_PREHASH_AgentID, gAgent.getID());
+ msg->addUUID(_PREHASH_SessionID, gAgent.getSessionID());
+
+ msg->nextBlockFast(_PREHASH_Rights);
+ msg->addUUID(_PREHASH_AgentRelated, avatar_id);
+ msg->addS32(_PREHASH_RelatedRights, rights);
+
+ gAgent.sendReliableMessage();
+ }
+}
+
+void LLAvatarPropertiesProcessor::sendNotes(const LLUUID& avatar_id, const std::string notes)
+{
+ if(!avatar_id.isNull())
+ {
+ LLMessageSystem* msg = gMessageSystem;
+
+ // setup message header
+ msg->newMessageFast(_PREHASH_AvatarNotesUpdate);
+ msg->nextBlockFast(_PREHASH_AgentData);
+ msg->addUUID(_PREHASH_AgentID, gAgent.getID());
+ msg->addUUID(_PREHASH_SessionID, gAgent.getSessionID());
+
+ msg->nextBlockFast(_PREHASH_Data);
+ msg->addUUID(_PREHASH_TargetID, avatar_id);
+ msg->addString(_PREHASH_Notes, notes);
+
+ gAgent.sendReliableMessage();
+ }
+}
+
+
+void LLAvatarPropertiesProcessor::sendPickDelete( const LLUUID& pick_id )
+{
+ LLMessageSystem* msg = gMessageSystem;
+ msg->newMessage(_PREHASH_PickDelete);
+ msg->nextBlock(_PREHASH_AgentData);
+ msg->addUUID(_PREHASH_AgentID, gAgent.getID());
+ msg->addUUID(_PREHASH_SessionID, gAgent.getSessionID());
+ msg->nextBlock(_PREHASH_Data);
+ msg->addUUID(_PREHASH_PickID, pick_id);
+ gAgent.sendReliableMessage();
+}
+
+void LLAvatarPropertiesProcessor::sendPicInfoUpdate(const void* pick_data)
+{
+ if (!pick_data) return;
+ const LLPickData *new_pick = static_cast<const LLPickData*>(pick_data);
+ if (!new_pick) return;
+
+ LLMessageSystem* msg = gMessageSystem;
+
+ msg->newMessage(_PREHASH_PickInfoUpdate);
+ msg->nextBlock(_PREHASH_AgentData);
+ msg->addUUID(_PREHASH_AgentID, gAgent.getID());
+ msg->addUUID(_PREHASH_SessionID, gAgent.getSessionID());
+
+ msg->nextBlock(_PREHASH_Data);
+ msg->addUUID(_PREHASH_PickID, new_pick->pick_id);
+ msg->addUUID(_PREHASH_CreatorID, new_pick->creator_id);
+
+ //legacy var need to be deleted
+ msg->addBOOL(_PREHASH_TopPick, FALSE);
+
+ // fills in on simulator if null
+ msg->addUUID(_PREHASH_ParcelID, new_pick->parcel_id);
+ msg->addString(_PREHASH_Name, new_pick->name);
+ msg->addString(_PREHASH_Desc, new_pick->desc);
+ msg->addUUID(_PREHASH_SnapshotID, new_pick->snapshot_id);
+ msg->addVector3d(_PREHASH_PosGlobal, new_pick->pos_global);
+
+ // Only top picks have a sort order
+ msg->addS32(_PREHASH_SortOrder, 0);
+
+ msg->addBOOL(_PREHASH_Enabled, new_pick->enabled);
+ gAgent.sendReliableMessage();
+}
+
+void LLAvatarPropertiesProcessor::sendPickInfoRequest(const LLUUID& creator_id, const LLUUID& pick_id)
+{
+ // Must ask for a pick based on the creator id because
+ // the pick database is distributed to the inventory cluster. JC
+ std::vector<std::string> request_params;
+ request_params.push_back(creator_id.asString() );
+ request_params.push_back(pick_id.asString() );
+ send_generic_message("pickinforequest", request_params);
+}
diff --git a/indra/newview/llavatarpropertiesprocessor.h b/indra/newview/llavatarpropertiesprocessor.h
new file mode 100644
index 0000000000..2e10dea834
--- /dev/null
+++ b/indra/newview/llavatarpropertiesprocessor.h
@@ -0,0 +1,208 @@
+/**
+ * @file llavatarpropertiesprocessor.h
+ * @brief LLAvatatIconCtrl base class
+ *
+ * $LicenseInfo:firstyear=2001&license=viewergpl$
+ *
+ * Copyright (c) 2001-2009, Linden Research, Inc.
+ *
+ * Second Life Viewer Source Code
+ * The source code in this file ("Source Code") is provided by Linden Lab
+ * to you under the terms of the GNU General Public License, version 2.0
+ * ("GPL"), unless you have obtained a separate licensing agreement
+ * ("Other License"), formally executed by you and Linden Lab. Terms of
+ * the GPL can be found in doc/GPL-license.txt in this distribution, or
+ * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
+ *
+ * There are special exceptions to the terms and conditions of the GPL as
+ * it is applied to this Source Code. View the full text of the exception
+ * in the file doc/FLOSS-exception.txt in this software distribution, or
+ * online at
+ * http://secondlifegrid.net/programs/open_source/licensing/flossexception
+ *
+ * By copying, modifying or distributing this software, you acknowledge
+ * that you have read and understood your obligations described above,
+ * and agree to abide by those obligations.
+ *
+ * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+ * COMPLETENESS OR PERFORMANCE.
+ * $/LicenseInfo$
+ */
+
+#ifndef LL_LLAVATARPROPERTIESPROCESSOR_H
+#define LL_LLAVATARPROPERTIESPROCESSOR_H
+
+#include "lluuid.h"
+#include "llsingleton.h"
+#include "v3dmath.h" // LLVector3d
+#include <map>
+
+/*
+*TODO Vadim: This needs some refactoring:
+- Remove EAvatarProcessorType in favor of separate observers, derived from a common parent (to get rid of void*).
+*/
+
+/*
+*TODO: mantipov: get rid of sendDataRequest and sendDataUpdate methods. Use exact methods instead of.
+*/
+
+class LLMessageSystem;
+
+enum EAvatarProcessorType
+{
+ APT_PROPERTIES,
+ APT_NOTES,
+ APT_GROUPS,
+ APT_PICKS,
+ APT_PICK_INFO
+};
+
+struct LLAvatarData
+{
+ LLUUID agent_id;
+ LLUUID avatar_id; //target id
+ LLUUID image_id;
+ LLUUID fl_image_id;
+ LLUUID partner_id;
+ std::string about_text;
+ std::string fl_about_text;
+ std::string born_on;
+ std::string profile_url;
+ U8 caption_index;
+ std::string caption_text;
+ U32 flags;
+ BOOL allow_publish;
+};
+
+struct LLAvatarPicks
+{
+ LLUUID agent_id;
+ LLUUID target_id; //target id
+
+ typedef std::pair<LLUUID,std::string> pick_data_t;
+ typedef std::list< pick_data_t> picks_list_t;
+ picks_list_t picks_list;
+};
+
+struct LLPickData
+{
+ LLUUID agent_id;
+ LLUUID pick_id;
+ LLUUID creator_id;
+ BOOL top_pick;
+ LLUUID parcel_id;
+ std::string name;
+ std::string desc;
+ LLUUID snapshot_id;
+ LLVector3d pos_global;
+ S32 sort_order;
+ BOOL enabled;
+
+ //used only in read requests
+ std::string location_text;
+ std::string original_name;
+ std::string sim_name;
+
+ //used only in write (update) requests
+ LLUUID session_id;
+
+};
+
+struct LLAvatarNotes
+{
+ LLUUID agent_id;
+ LLUUID target_id; //target id
+ std::string notes;
+};
+
+struct LLAvatarGroups
+{
+ LLUUID agent_id;
+ LLUUID avatar_id; //target id
+ BOOL list_in_profile;
+
+ struct LLGroupData;
+ typedef std::list<LLGroupData> group_list_t;
+
+ group_list_t group_list;
+
+ struct LLGroupData
+ {
+ U64 group_powers;
+ BOOL accept_notices;
+ std::string group_title;
+ LLUUID group_id;
+ std::string group_name;
+ LLUUID group_insignia_id;
+ };
+};
+
+class LLAvatarPropertiesObserver
+{
+public:
+ virtual ~LLAvatarPropertiesObserver() {}
+ virtual void processProperties(void* data, EAvatarProcessorType type) = 0;
+};
+
+class LLAvatarPropertiesProcessor
+ : public LLSingleton<LLAvatarPropertiesProcessor>
+{
+public:
+
+ LLAvatarPropertiesProcessor();
+ virtual ~LLAvatarPropertiesProcessor()
+ {}
+
+ void addObserver(const LLUUID& avatar_id, LLAvatarPropertiesObserver* observer);
+
+ void removeObserver(const LLUUID& avatar_id, LLAvatarPropertiesObserver* observer);
+
+ void sendDataRequest(const LLUUID& avatar_id, EAvatarProcessorType type, const void * data = NULL);
+
+ void sendDataUpdate(const void* data, EAvatarProcessorType type);
+
+ void sendFriendRights(const LLUUID& avatar_id, S32 rights);
+
+ void sendNotes(const LLUUID& avatar_id, const std::string notes);
+
+ void sendPickDelete(const LLUUID& pick_id);
+
+ static void processAvatarPropertiesReply(LLMessageSystem* msg, void**);
+
+ static void processAvatarInterestsReply(LLMessageSystem* msg, void**);
+
+ static void processAvatarClassifiedReply(LLMessageSystem* msg, void**);
+
+ static void processAvatarGroupsReply(LLMessageSystem* msg, void**);
+
+ static void processAvatarNotesReply(LLMessageSystem* msg, void**);
+
+ static void processAvatarPicksReply(LLMessageSystem* msg, void**);
+
+ static void processPickInfoReply(LLMessageSystem* msg, void**);
+protected:
+
+ void sendAvatarPropertiesRequest(const LLUUID& avatar_id);
+
+ void sendGenericRequest(const LLUUID& avatar_id, const std::string method);
+
+ void sendAvatarPropertiesUpdate(const void* data);
+
+ void sendPickInfoRequest(const LLUUID& creator_id, const LLUUID& pick_id);
+
+ void sendPicInfoUpdate(const void * pick_data);
+
+ static void notifyObservers(const LLUUID& id,void* data, EAvatarProcessorType type);
+
+ typedef void* (*processor_method_t)(LLMessageSystem*);
+ static processor_method_t getProcessor(EAvatarProcessorType type);
+
+protected:
+
+ typedef std::multimap<LLUUID, LLAvatarPropertiesObserver*> observer_multimap_t;
+
+ observer_multimap_t mObservers;
+};
+
+#endif // LL_LLAVATARPROPERTIESPROCESSOR_H
diff --git a/indra/newview/llbottomtray.cpp b/indra/newview/llbottomtray.cpp
new file mode 100644
index 0000000000..2403e891f6
--- /dev/null
+++ b/indra/newview/llbottomtray.cpp
@@ -0,0 +1,191 @@
+/**
+ * @file llbottomtray.cpp
+ * @brief LLBottomTray class implementation
+ *
+ * $LicenseInfo:firstyear=2009&license=viewergpl$
+ *
+ * Copyright (c) 2009, Linden Research, Inc.
+ *
+ * Second Life Viewer Source Code
+ * The source code in this file ("Source Code") is provided by Linden Lab
+ * to you under the terms of the GNU General Public License, version 2.0
+ * ("GPL"), unless you have obtained a separate licensing agreement
+ * ("Other License"), formally executed by you and Linden Lab. Terms of
+ * the GPL can be found in doc/GPL-license.txt in this distribution, or
+ * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
+ *
+ * There are special exceptions to the terms and conditions of the GPL as
+ * it is applied to this Source Code. View the full text of the exception
+ * in the file doc/FLOSS-exception.txt in this software distribution, or
+ * online at
+ * http://secondlifegrid.net/programs/open_source/licensing/flossexception
+ *
+ * By copying, modifying or distributing this software, you acknowledge
+ * that you have read and understood your obligations described above,
+ * and agree to abide by those obligations.
+ *
+ * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+ * COMPLETENESS OR PERFORMANCE.
+ * $/LicenseInfo$
+ */
+
+#include "llviewerprecompiledheaders.h" // must be first include
+#include "llbottomtray.h"
+
+#include "llagent.h"
+#include "llchiclet.h"
+#include "llfloaterreg.h"
+#include "llflyoutbutton.h"
+#include "lllayoutstack.h"
+#include "llnearbychatbar.h"
+#include "llsplitbutton.h"
+#include "llfloatercamera.h"
+#include "llimpanel.h"
+#include "llactiveimwindow.h"
+
+LLBottomTray::LLBottomTray(const LLSD&)
+: mChicletPanel(NULL),
+ mIMWell(NULL),
+ mSysWell(NULL),
+ mTalkBtn(NULL),
+ mNearbyChatBar(NULL),
+ mToolbarStack(NULL)
+
+{
+ mFactoryMap["chat_bar"] = LLCallbackMap(LLBottomTray::createNearbyChatBar, NULL);
+
+ LLUICtrlFactory::getInstance()->buildPanel(this,"panel_bottomtray.xml");
+
+ mChicletPanel = getChild<LLChicletPanel>("chiclet_list");
+ mIMWell = getChild<LLNotificationChiclet>("im_well");
+ mSysWell = getChild<LLNotificationChiclet>("sys_well");
+
+ mSysWell->setNotificationChicletWindow(LLFloaterReg::getInstance("syswell_window"));
+ mChicletPanel->setChicletClickedCallback(boost::bind(&LLBottomTray::onChicletClick,this,_1));
+
+ LLSplitButton* presets = getChild<LLSplitButton>("presets");
+ presets->setSelectionCallback(LLFloaterCamera::onClickCameraPresets);
+
+ LLIMMgr::getInstance()->addSessionObserver(this);
+
+ //this is to fix a crash that occurs because LLBottomTray is a singleton
+ //and thus is deleted at the end of the viewers lifetime, but to be cleanly
+ //destroyed LLBottomTray requires some subsystems that are long gone
+ LLUI::getRootView()->addChild(this);
+
+ // Necessary for focus movement among child controls
+ setFocusRoot(TRUE);
+
+ LLActiveIMWindow::init(mIMWell);
+}
+
+BOOL LLBottomTray::postBuild()
+{
+ mNearbyChatBar = getChild<LLNearbyChatBar>("chat_bar");
+ mToolbarStack = getChild<LLLayoutStack>("toolbar_stack");
+
+ return TRUE;
+}
+
+LLBottomTray::~LLBottomTray()
+{
+ if (!LLSingleton<LLIMMgr>::destroyed())
+ {
+ LLIMMgr::getInstance()->removeSessionObserver(this);
+ }
+}
+
+void LLBottomTray::onChicletClick(LLUICtrl* ctrl)
+{
+ LLIMChiclet* chiclet = dynamic_cast<LLIMChiclet*>(ctrl);
+ if (chiclet)
+ {
+ // Until you can type into an IM Window and have a conversation,
+ // still show the old communicate window
+ //LLFloaterReg::showInstance("communicate", chiclet->getSessionId());
+
+ // Show after comm window so it is frontmost (and hence will not
+ // auto-hide)
+
+// this logic has been moved to LLIMChiclet::handleMouseDown
+// LLIMFloater::show(chiclet->getSessionId());
+// chiclet->setCounter(0);
+ }
+}
+
+void* LLBottomTray::createNearbyChatBar(void* userdata)
+{
+ return new LLNearbyChatBar();
+}
+
+//virtual
+void LLBottomTray::sessionAdded(const LLUUID& session_id, const std::string& name, const LLUUID& other_participant_id)
+{
+ if(getChicletPanel())
+ {
+ if(getChicletPanel()->findChiclet<LLChiclet>(session_id))
+ {
+
+ }
+ else
+ {
+ LLIMChiclet* chiclet = getChicletPanel()->createChiclet<LLIMChiclet>(session_id);
+ chiclet->setIMSessionName(name);
+ chiclet->setOtherParticipantId(other_participant_id);
+ }
+ }
+ updateImChicletCount();
+}
+
+//virtual
+void LLBottomTray::sessionRemoved(const LLUUID& session_id)
+{
+ if(getChicletPanel())
+ {
+ getChicletPanel()->removeChiclet(session_id);
+ }
+ updateImChicletCount();
+}
+
+//virtual
+void LLBottomTray::onFocusLost()
+{
+ if (gAgent.cameraMouselook())
+ {
+ setVisible(FALSE);
+ }
+}
+
+//virtual
+// setVisible used instead of onVisibilityChange, since LLAgent calls it on entering/leaving mouselook mode.
+// If bottom tray is already visible in mouselook mode, then onVisibilityChange will not be called from setVisible(true),
+void LLBottomTray::setVisible(BOOL visible)
+{
+ LLPanel::setVisible(visible);
+
+ // *NOTE: we must check mToolbarStack against NULL because setVisible is called from the
+ // LLPanel::initFromParams BEFORE postBuild is called and child controls are not exist yet
+ if (NULL != mToolbarStack)
+ {
+ BOOL visibility = gAgent.cameraMouselook() ? false : true;
+
+ for ( child_list_const_iter_t child_it = mToolbarStack->getChildList()->begin();
+ child_it != mToolbarStack->getChildList()->end(); child_it++)
+ {
+ LLView* viewp = *child_it;
+
+ if ("chat_bar" == viewp->getName())
+ continue;
+ else
+ {
+ viewp->setVisible(visibility);
+ }
+ }
+ }
+}
+
+void LLBottomTray::updateImChicletCount() {
+ U32 chicletCount = mChicletPanel->getChicletCount();
+ mIMWell->setCounter(chicletCount);
+}
diff --git a/indra/newview/llbottomtray.h b/indra/newview/llbottomtray.h
new file mode 100644
index 0000000000..7f606339bc
--- /dev/null
+++ b/indra/newview/llbottomtray.h
@@ -0,0 +1,91 @@
+/**
+* @file llbottomtray.h
+* @brief LLBottomTray class header file
+*
+* $LicenseInfo:firstyear=2009&license=viewergpl$
+*
+* Copyright (c) 2009, Linden Research, Inc.
+*
+* Second Life Viewer Source Code
+* The source code in this file ("Source Code") is provided by Linden Lab
+* to you under the terms of the GNU General Public License, version 2.0
+* ("GPL"), unless you have obtained a separate licensing agreement
+* ("Other License"), formally executed by you and Linden Lab. Terms of
+* the GPL can be found in doc/GPL-license.txt in this distribution, or
+* online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
+*
+* There are special exceptions to the terms and conditions of the GPL as
+* it is applied to this Source Code. View the full text of the exception
+* in the file doc/FLOSS-exception.txt in this software distribution, or
+* online at
+* http://secondlifegrid.net/programs/open_source/licensing/flossexception
+*
+* By copying, modifying or distributing this software, you acknowledge
+* that you have read and understood your obligations described above,
+* and agree to abide by those obligations.
+*
+* ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+* COMPLETENESS OR PERFORMANCE.
+* $/LicenseInfo$
+*/
+
+#ifndef LL_LLBOTTOMPANEL_H
+#define LL_LLBOTTOMPANEL_H
+
+#include "llpanel.h"
+#include "llimview.h"
+
+class LLChicletPanel;
+class LLLineEditor;
+class LLLayoutStack;
+class LLNotificationChiclet;
+class LLTalkButton;
+class LLNearbyChatBar;
+
+class LLBottomTray
+ : public LLSingleton<LLBottomTray>
+ , public LLPanel
+ , public LLIMSessionObserver
+{
+ friend class LLSingleton<LLBottomTray>;
+public:
+ ~LLBottomTray();
+
+ BOOL postBuild();
+
+ LLChicletPanel* getChicletPanel() {return mChicletPanel;}
+ LLNotificationChiclet* getIMWell() {return mIMWell;}
+ LLNotificationChiclet* getSysWell() {return mSysWell;}
+ LLNearbyChatBar* getNearbyChatBar() {return mNearbyChatBar;}
+
+ void onCommitGesture(LLUICtrl* ctrl);
+
+ // LLIMSessionObserver observe triggers
+ virtual void sessionAdded(const LLUUID& session_id, const std::string& name, const LLUUID& other_participant_id);
+ virtual void sessionRemoved(const LLUUID& session_id);
+
+ virtual void onFocusLost();
+ virtual void setVisible(BOOL visible);
+
+private:
+ void updateImChicletCount();
+
+protected:
+
+ LLBottomTray(const LLSD& key = LLSD());
+
+ void onChicletClick(LLUICtrl* ctrl);
+
+ static void* createNearbyChatBar(void* userdata);
+
+ LLChicletPanel* mChicletPanel;
+ LLNotificationChiclet* mIMWell;
+ LLNotificationChiclet* mSysWell;
+ LLTalkButton* mTalkBtn;
+ LLNearbyChatBar* mNearbyChatBar;
+ LLLayoutStack* mToolbarStack;
+
+};
+
+#endif // LL_LLBOTTOMPANEL_H
diff --git a/indra/newview/llbreadcrumbview.cpp b/indra/newview/llbreadcrumbview.cpp
new file mode 100644
index 0000000000..342994ee30
--- /dev/null
+++ b/indra/newview/llbreadcrumbview.cpp
@@ -0,0 +1,37 @@
+/**
+ * @file llbreadcrumbview.cpp
+ * @brief UI widget for displaying position in a folder hierarchy and allowing
+ * the user to click on a location in the hierarchy.
+ *
+ * $LicenseInfo:firstyear=2009&license=viewergpl$
+ *
+ * Copyright (c) 2009, Linden Research, Inc.
+ *
+ * Second Life Viewer Source Code
+ * The source code in this file ("Source Code") is provided by Linden Lab
+ * to you under the terms of the GNU General Public License, version 2.0
+ * ("GPL"), unless you have obtained a separate licensing agreement
+ * ("Other License"), formally executed by you and Linden Lab. Terms of
+ * the GPL can be found in doc/GPL-license.txt in this distribution, or
+ * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
+ *
+ * There are special exceptions to the terms and conditions of the GPL as
+ * it is applied to this Source Code. View the full text of the exception
+ * in the file doc/FLOSS-exception.txt in this software distribution, or
+ * online at
+ * http://secondlifegrid.net/programs/open_source/licensing/flossexception
+ *
+ * By copying, modifying or distributing this software, you acknowledge
+ * that you have read and understood your obligations described above,
+ * and agree to abide by those obligations.
+ *
+ * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+ * COMPLETENESS OR PERFORMANCE.
+ * $/LicenseInfo$
+ */
+#include "llviewerprecompiledheaders.h"
+
+#include "llbreadcrumbview.h"
+
+// TODO
diff --git a/indra/newview/llbreadcrumbview.h b/indra/newview/llbreadcrumbview.h
new file mode 100644
index 0000000000..ca6fbe7fb2
--- /dev/null
+++ b/indra/newview/llbreadcrumbview.h
@@ -0,0 +1,36 @@
+/**
+ * @file llbreadcrumbview.h
+ * @brief UI widget for displaying position in a folder hierarchy and allowing
+ * the user to click on a location in the hierarchy.
+ *
+ * $LicenseInfo:firstyear=2009&license=viewergpl$
+ *
+ * Copyright (c) 2009, Linden Research, Inc.
+ *
+ * Second Life Viewer Source Code
+ * The source code in this file ("Source Code") is provided by Linden Lab
+ * to you under the terms of the GNU General Public License, version 2.0
+ * ("GPL"), unless you have obtained a separate licensing agreement
+ * ("Other License"), formally executed by you and Linden Lab. Terms of
+ * the GPL can be found in doc/GPL-license.txt in this distribution, or
+ * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
+ *
+ * There are special exceptions to the terms and conditions of the GPL as
+ * it is applied to this Source Code. View the full text of the exception
+ * in the file doc/FLOSS-exception.txt in this software distribution, or
+ * online at
+ * http://secondlifegrid.net/programs/open_source/licensing/flossexception
+ *
+ * By copying, modifying or distributing this software, you acknowledge
+ * that you have read and understood your obligations described above,
+ * and agree to abide by those obligations.
+ *
+ * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+ * COMPLETENESS OR PERFORMANCE.
+ * $/LicenseInfo$
+ */
+#ifndef LLBREADCRUMBVIEW_H
+#define LLBREADCRUMBVIEW_H
+
+#endif // LLBREADCRUMBVIEW_H
diff --git a/indra/newview/llcallingcard.cpp b/indra/newview/llcallingcard.cpp
index db28c7ad38..7326e39af3 100644
--- a/indra/newview/llcallingcard.cpp
+++ b/indra/newview/llcallingcard.cpp
@@ -95,29 +95,8 @@ const F32 OFFLINE_SECONDS = FIND_FREQUENCY + 8.0f;
// static
LLAvatarTracker LLAvatarTracker::sInstance;
-/*
-class LLAvatarTrackerInventoryObserver : public LLInventoryObserver
-{
-public:
- LLAvatarTrackerInventoryObserver(LLAvatarTracker* at) :
- mAT(at) {}
- virtual ~LLAvatarTrackerInventoryObserver() {}
- virtual void changed(U32 mask);
-protected:
- LLAvatarTracker* mAT;
-};
-*/
-/*
-void LLAvatarTrackerInventoryObserver::changed(U32 mask)
-{
- // if there's a calling card change, just do it.
- if((mask & LLInventoryObserver::CALLING_CARD) != 0)
- {
- mAT->inventoryChanged();
- }
-}
-*/
+
///----------------------------------------------------------------------------
/// Class LLAvatarTracker
@@ -329,7 +308,8 @@ void LLAvatarTracker::terminateBuddy(const LLUUID& id)
msg->nextBlock("ExBlock");
msg->addUUID("OtherID", id);
gAgent.sendReliableMessage();
- mModifyMask |= LLFriendObserver::REMOVE;
+
+ addChangedMask(LLFriendObserver::REMOVE, id);
delete buddy;
}
@@ -503,6 +483,18 @@ void LLAvatarTracker::notifyObservers()
(*it)->changed(mModifyMask);
}
mModifyMask = LLFriendObserver::NONE;
+ mChangedBuddyIDs.clear();
+}
+
+// store flag for change
+// and id of object change applies to
+void LLAvatarTracker::addChangedMask(U32 mask, const LLUUID& referent)
+{
+ mModifyMask |= mask;
+ if (referent.notNull())
+ {
+ mChangedBuddyIDs.insert(referent);
+ }
}
void LLAvatarTracker::applyFunctor(LLRelationshipFunctor& f)
@@ -684,7 +676,7 @@ void LLAvatarTracker::processNotify(LLMessageSystem* msg, bool online)
{
std::string notifyMsg = notification->getMessage();
if (!notifyMsg.empty())
- floater->addHistoryLine(notifyMsg,gSavedSettings.getColor4("SystemChatColor"));
+ floater->addHistoryLine(notifyMsg,LLUIColorTable::instance().getColor("SystemChatColor"));
}
}
@@ -706,7 +698,7 @@ void LLAvatarTracker::formFriendship(const LLUUID& id)
//visible online to each other.
buddy_info = new LLRelationship(LLRelationship::GRANT_ONLINE_STATUS,LLRelationship::GRANT_ONLINE_STATUS, false);
at.mBuddyInfo[id] = buddy_info;
- at.mModifyMask |= LLFriendObserver::ADD;
+ at.addChangedMask(LLFriendObserver::ADD, id);
at.notifyObservers();
}
}
@@ -722,7 +714,7 @@ void LLAvatarTracker::processTerminateFriendship(LLMessageSystem* msg, void**)
LLRelationship* buddy = get_ptr_in_map(at.mBuddyInfo, id);
if(!buddy) return;
at.mBuddyInfo.erase(id);
- at.mModifyMask |= LLFriendObserver::REMOVE;
+ at.addChangedMask(LLFriendObserver::REMOVE, id);
delete buddy;
at.notifyObservers();
}
diff --git a/indra/newview/llcallingcard.h b/indra/newview/llcallingcard.h
index 85a1ab6e1e..113f16de70 100644
--- a/indra/newview/llcallingcard.h
+++ b/indra/newview/llcallingcard.h
@@ -147,6 +147,17 @@ public:
void removeObserver(LLFriendObserver* observer);
void notifyObservers();
+ /**
+ * Stores flag for change and id of object change applies to
+ *
+ * This allows outsiders to tell the AvatarTracker if something has
+ * been changed 'under the hood',
+ * and next notification will have exact avatar IDs have been changed.
+ */
+ void addChangedMask(U32 mask, const LLUUID& referent);
+
+ const std::set<LLUUID>& getChangedIDs() { return mChangedBuddyIDs; }
+
// Apply the functor to every buddy. Do not actually modify the
// buddy list in the functor or bad things will happen.
void applyFunctor(LLRelationshipFunctor& f);
@@ -179,6 +190,9 @@ protected:
buddy_map_t mBuddyInfo;
+ typedef std::set<LLUUID> changed_buddy_t;
+ changed_buddy_t mChangedBuddyIDs;
+
typedef std::vector<LLFriendObserver*> observer_list_t;
observer_list_t mObservers;
diff --git a/indra/newview/llcapabilitylistener.cpp b/indra/newview/llcapabilitylistener.cpp
index 3277da8930..4134e9e0a4 100644
--- a/indra/newview/llcapabilitylistener.cpp
+++ b/indra/newview/llcapabilitylistener.cpp
@@ -21,6 +21,7 @@
// other Linden headers
#include "stringize.h"
#include "llcapabilityprovider.h"
+#include "message.h"
class LLCapabilityListener::CapabilityMappers: public LLSingleton<LLCapabilityListener::CapabilityMappers>
{
diff --git a/indra/newview/llcapabilitylistener.h b/indra/newview/llcapabilitylistener.h
index 061227e04d..ce16b7da5d 100644
--- a/indra/newview/llcapabilitylistener.h
+++ b/indra/newview/llcapabilitylistener.h
@@ -17,6 +17,7 @@
#include "llerror.h" // LOG_CLASS()
class LLCapabilityProvider;
+class LLMessageSystem;
class LLSD;
class LLCapabilityListener
diff --git a/indra/newview/llcaphttpsender.cpp b/indra/newview/llcaphttpsender.cpp
index 1127f43424..b44e1f11fa 100644
--- a/indra/newview/llcaphttpsender.cpp
+++ b/indra/newview/llcaphttpsender.cpp
@@ -32,9 +32,10 @@
#include "llviewerprecompiledheaders.h"
-#include "linden_common.h"
#include "llcaphttpsender.h"
+#include "llhost.h"
+
LLCapHTTPSender::LLCapHTTPSender(const std::string& cap) :
mCap(cap)
{
diff --git a/indra/newview/llchannelmanager.cpp b/indra/newview/llchannelmanager.cpp
new file mode 100644
index 0000000000..a8373491cf
--- /dev/null
+++ b/indra/newview/llchannelmanager.cpp
@@ -0,0 +1,229 @@
+/**
+ * @file llchannelmanager.cpp
+ * @brief This class rules screen notification channels.
+ *
+ * $LicenseInfo:firstyear=2000&license=viewergpl$
+ *
+ * Copyright (c) 2000-2009, Linden Research, Inc.
+ *
+ * Second Life Viewer Source Code
+ * The source code in this file ("Source Code") is provided by Linden Lab
+ * to you under the terms of the GNU General Public License, version 2.0
+ * ("GPL"), unless you have obtained a separate licensing agreement
+ * ("Other License"), formally executed by you and Linden Lab. Terms of
+ * the GPL can be found in doc/GPL-license.txt in this distribution, or
+ * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
+ *
+ * There are special exceptions to the terms and conditions of the GPL as
+ * it is applied to this Source Code. View the full text of the exception
+ * in the file doc/FLOSS-exception.txt in this software distribution, or
+ * online at
+ * http://secondlifegrid.net/programs/open_source/licensing/flossexception
+ *
+ * By copying, modifying or distributing this software, you acknowledge
+ * that you have read and understood your obligations described above,
+ * and agree to abide by those obligations.
+ *
+ * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+ * COMPLETENESS OR PERFORMANCE.
+ * $/LicenseInfo$
+ */
+
+#include "llviewerprecompiledheaders.h" // must be first include
+
+#include "llchannelmanager.h"
+
+#include "llappviewer.h"
+#include "llviewercontrol.h"
+#include "llimview.h"
+
+#include <algorithm>
+
+using namespace LLNotificationsUI;
+
+//--------------------------------------------------------------------------
+LLChannelManager::LLChannelManager()
+{
+ LLAppViewer::instance()->setOnLoginCompletedCallback(boost::bind(&LLChannelManager::onLoginCompleted, this));
+ mChannelList.clear();
+ mStartUpChannel = NULL;
+}
+
+//--------------------------------------------------------------------------
+LLChannelManager::~LLChannelManager()
+{
+ //All channels are being deleted by Parent View
+}
+
+//--------------------------------------------------------------------------
+void LLChannelManager::onLoginCompleted()
+{
+ S32 away_notifications = 0;
+
+ for(std::vector<ChannelElem>::iterator it = mChannelList.begin(); it != mChannelList.end(); ++it)
+ {
+ if((*it).channel->getChannelID() == LLUUID(gSavedSettings.getString("NearByChatChannelUUID")))
+ {
+ continue;
+ }
+
+ if(!(*it).channel->getDisplayToastsAlways())
+ {
+ away_notifications +=(*it).channel->getNumberOfHiddenToasts();
+ }
+ }
+
+ // *TODO: calculate IM notifications
+ away_notifications += gIMMgr->getNumberOfUnreadIM();
+
+ if(!away_notifications)
+ {
+ onStartUpToastClose();
+ return;
+ }
+
+ LLChannelManager::Params p;
+ p.id = LLUUID(gSavedSettings.getString("StartUpChannelUUID"));
+ p.channel_right_bound = getRootView()->getRect().mRight - gSavedSettings.getS32("NotificationChannelRightMargin");
+ p.channel_width = gSavedSettings.getS32("NotifyBoxWidth");
+ mStartUpChannel = createChannel(p);
+
+ if(!mStartUpChannel)
+ {
+ onStartUpToastClose();
+ return;
+ }
+
+ mStartUpChannel->setShowToasts(true);
+ static_cast<LLUICtrl*>(mStartUpChannel)->setCommitCallback(boost::bind(&LLChannelManager::onStartUpToastClose, this));
+ mStartUpChannel->createStartUpToast(away_notifications, gSavedSettings.getS32("ChannelBottomPanelMargin"), gSavedSettings.getS32("StartUpToastTime"));
+}
+
+//--------------------------------------------------------------------------
+void LLChannelManager::onStartUpToastClose()
+{
+ if(mStartUpChannel)
+ {
+ mStartUpChannel->setVisible(FALSE);
+ mStartUpChannel->closeStartUpToast();
+ getRootView()->removeChild(mStartUpChannel);
+ removeChannelByID(LLUUID(gSavedSettings.getString("StartUpChannelUUID")));
+ delete mStartUpChannel;
+ mStartUpChannel = NULL;
+ }
+
+ // set StartUp Toast Flag
+ LLScreenChannel::setStartUpToastShown();
+
+ // allow all other channels to show incoming toasts
+ for(std::vector<ChannelElem>::iterator it = mChannelList.begin(); it != mChannelList.end(); ++it)
+ {
+ (*it).channel->setShowToasts(true);
+ }
+
+ // force NEARBY CHAT CHANNEL to repost all toasts if present
+ LLScreenChannel* nearby_channel = getChannelByID(LLUUID(gSavedSettings.getString("NearByChatChannelUUID")));
+ nearby_channel->loadStoredToastsToChannel();
+ nearby_channel->setCanStoreToasts(false);
+}
+
+//--------------------------------------------------------------------------
+LLScreenChannel* LLChannelManager::createChannel(LLChannelManager::Params& p)
+{
+ LLScreenChannel* new_channel = NULL;
+
+ if(!p.chiclet)
+ {
+ new_channel = getChannelByID(p.id);
+ }
+ else
+ {
+ new_channel = getChannelByChiclet(p.chiclet);
+ }
+
+ if(new_channel)
+ return new_channel;
+
+ new_channel = new LLScreenChannel(p.id);
+ getRootView()->addChild(new_channel);
+ new_channel->init(p.channel_right_bound - p.channel_width, p.channel_right_bound);
+ new_channel->setToastAlignment(p.align);
+ new_channel->setDisplayToastsAlways(p.display_toasts_always);
+
+ ChannelElem new_elem;
+ new_elem.id = p.id;
+ new_elem.chiclet = p.chiclet;
+ new_elem.channel = new_channel;
+
+ mChannelList.push_back(new_elem); //TODO: remove chiclet from ScreenChannel?
+
+ return new_channel;
+}
+
+//--------------------------------------------------------------------------
+LLScreenChannel* LLChannelManager::getChannelByID(const LLUUID id)
+{
+ std::vector<ChannelElem>::iterator it = find(mChannelList.begin(), mChannelList.end(), id);
+ if(it != mChannelList.end())
+ {
+ return (*it).channel;
+ }
+
+ return NULL;
+}
+
+//--------------------------------------------------------------------------
+LLScreenChannel* LLChannelManager::getChannelByChiclet(const LLChiclet* chiclet)
+{
+ std::vector<ChannelElem>::iterator it = find(mChannelList.begin(), mChannelList.end(), chiclet);
+ if(it != mChannelList.end())
+ {
+ return (*it).channel;
+ }
+
+ return NULL;
+}
+
+//--------------------------------------------------------------------------
+void LLChannelManager::reshape(S32 width, S32 height, BOOL called_from_parent)
+{
+ for(std::vector<ChannelElem>::iterator it = mChannelList.begin(); it != mChannelList.end(); ++it)
+ {
+ if((*it).channel->getToastAlignment() == NA_CENTRE)
+ {
+ LLRect channel_rect = (*it).channel->getRect();
+ S32 screen_width = getRootView()->getRect().getWidth();
+ channel_rect.setLeftTopAndSize(screen_width/2, channel_rect.mTop, channel_rect.getWidth(), channel_rect.getHeight());
+ (*it).channel->setRect(channel_rect);
+ (*it).channel->showToasts();
+ }
+ }
+}
+
+//--------------------------------------------------------------------------
+void LLChannelManager::removeChannelByID(const LLUUID id)
+{
+ std::vector<ChannelElem>::iterator it = find(mChannelList.begin(), mChannelList.end(), id);
+ if(it != mChannelList.end())
+ {
+ mChannelList.erase(it);
+ }
+}
+
+//--------------------------------------------------------------------------
+void LLChannelManager::removeChannelByChiclet(const LLChiclet* chiclet)
+{
+ std::vector<ChannelElem>::iterator it = find(mChannelList.begin(), mChannelList.end(), chiclet);
+ if(it != mChannelList.end())
+ {
+ mChannelList.erase(it);
+ }
+}
+
+//--------------------------------------------------------------------------
+
+
+
+
+
diff --git a/indra/newview/llchannelmanager.h b/indra/newview/llchannelmanager.h
new file mode 100644
index 0000000000..e26c96b62e
--- /dev/null
+++ b/indra/newview/llchannelmanager.h
@@ -0,0 +1,124 @@
+/**
+ * @file llchannelmanager.h
+ * @brief This class rules screen notification channels.
+ *
+ * $LicenseInfo:firstyear=2003&license=viewergpl$
+ *
+ * Copyright (c) 2003-2009, Linden Research, Inc.
+ *
+ * Second Life Viewer Source Code
+ * The source code in this file ("Source Code") is provided by Linden Lab
+ * to you under the terms of the GNU General Public License, version 2.0
+ * ("GPL"), unless you have obtained a separate licensing agreement
+ * ("Other License"), formally executed by you and Linden Lab. Terms of
+ * the GPL can be found in doc/GPL-license.txt in this distribution, or
+ * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
+ *
+ * There are special exceptions to the terms and conditions of the GPL as
+ * it is applied to this Source Code. View the full text of the exception
+ * in the file doc/FLOSS-exception.txt in this software distribution, or
+ * online at
+ * http://secondlifegrid.net/programs/open_source/licensing/flossexception
+ *
+ * By copying, modifying or distributing this software, you acknowledge
+ * that you have read and understood your obligations described above,
+ * and agree to abide by those obligations.
+ *
+ * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+ * COMPLETENESS OR PERFORMANCE.
+ * $/LicenseInfo$
+ */
+
+#ifndef LL_LLCHANNELMANAGER_H
+#define LL_LLCHANNELMANAGER_H
+
+
+#include "llchiclet.h"
+#include "llscreenchannel.h"
+
+#include "lluuid.h"
+
+#include <map>
+#include <boost/shared_ptr.hpp>
+
+namespace LLNotificationsUI
+{
+/**
+ * Manager for screen channels.
+ * Responsible for instantiating and retrieving screen channels.
+ */
+class LLChannelManager : public LLUICtrl, public LLSingleton<LLChannelManager>
+{
+public:
+ struct Params : public LLInitParam::Block<Params, LLUICtrl::Params>
+ {
+ LLUUID id;
+ LLChiclet* chiclet;
+ S32 channel_right_bound;
+ S32 channel_width;
+ bool display_toasts_always;
+ EToastAlignment align;
+
+ Params(): id(LLUUID("")), chiclet(NULL),
+ channel_right_bound(0), channel_width(0),
+ display_toasts_always(false), align(NA_BOTTOM)
+ {}
+ };
+
+ struct ChannelElem
+ {
+ LLUUID id;
+ LLChiclet* chiclet;
+ LLScreenChannel* channel;
+
+ ChannelElem() : id(LLUUID("")), chiclet(NULL), channel(NULL) { }
+
+ ChannelElem(const ChannelElem &elem)
+ {
+ id = elem.id;
+ chiclet = elem.chiclet;
+ channel = elem.channel;
+ }
+
+ bool operator == (const LLUUID &id_op) const
+ {
+ return (id == id_op);
+ }
+
+ bool operator == (const LLChiclet* chiclet_op) const
+ {
+ return (chiclet == chiclet_op);
+ }
+
+ };
+
+ LLChannelManager();
+ virtual ~LLChannelManager();
+
+ // On LoginCompleted - show StartUp toast
+ void onLoginCompleted();
+ // removes a channel intended for the startup toast and allows other channels to show their toasts
+ void onStartUpToastClose();
+
+ //TODO: make protected? in order to be shure that channels are created only by notification handlers
+ LLScreenChannel* createChannel(LLChannelManager::Params& p);
+
+ LLScreenChannel* getChannelByID(const LLUUID id);
+ LLScreenChannel* getChannelByChiclet(const LLChiclet* chiclet);
+
+ // remove channel methods
+ void removeChannelByID(const LLUUID id);
+ void removeChannelByChiclet(const LLChiclet* chiclet);
+
+ void reshape(S32 width, S32 height, BOOL called_from_parent = TRUE);
+
+private:
+
+ LLScreenChannel* mStartUpChannel;
+ std::vector<ChannelElem> mChannelList;
+};
+
+}
+#endif
+
diff --git a/indra/newview/llchatbar.cpp b/indra/newview/llchatbar.cpp
index 2395f3c5ae..3ee2c93961 100644
--- a/indra/newview/llchatbar.cpp
+++ b/indra/newview/llchatbar.cpp
@@ -67,7 +67,7 @@
#include "llui.h"
#include "llviewermenu.h"
#include "lluictrlfactory.h"
-
+#include "llbottomtray.h"
//
// Globals
@@ -76,11 +76,6 @@ const F32 AGENT_TYPING_TIMEOUT = 5.f; // seconds
LLChatBar *gChatBar = NULL;
-// legacy calllback glue
-void toggleChatHistory(void* user_data);
-void send_chat_from_viewer(const std::string& utf8_out_text, EChatType type, S32 channel);
-
-
class LLChatBarGestureObserver : public LLGestureManagerObserver
{
public:
@@ -92,12 +87,14 @@ private:
};
+extern void send_chat_from_viewer(const std::string& utf8_out_text, EChatType type, S32 channel);
+
//
// Functions
//
LLChatBar::LLChatBar()
-: LLPanel(LLStringUtil::null, LLRect(), BORDER_NO),
+: LLPanel(),
mInputEditor(NULL),
mGestureLabelTimer(),
mLastSpecialChatChannel(0),
@@ -106,16 +103,12 @@ LLChatBar::LLChatBar()
mObserver(NULL)
{
setIsChrome(TRUE);
-
- #if !LL_RELEASE_FOR_DOWNLOAD
- childDisplayNotFound();
-#endif
}
LLChatBar::~LLChatBar()
{
- gGestureManager.removeObserver(mObserver);
+ LLGestureManager::instance().removeObserver(mObserver);
delete mObserver;
mObserver = NULL;
// LLView destructor cleans up children
@@ -123,34 +116,25 @@ LLChatBar::~LLChatBar()
BOOL LLChatBar::postBuild()
{
- childSetAction("History", toggleChatHistory, this);
- childSetCommitCallback("Say", onClickSay, this);
+ getChild<LLUICtrl>("Say")->setCommitCallback(boost::bind(&LLChatBar::onClickSay, this, _1));
+ // * NOTE: mantipov: getChild with default parameters returns dummy widget.
+ // Seems this class will be completle removed
// attempt to bind to an existing combo box named gesture
- setGestureCombo(getChild<LLComboBox>( "Gesture"));
-
- LLButton * sayp = getChild<LLButton>("Say");
- if(sayp)
- {
- setDefaultBtn(sayp);
- }
+ setGestureCombo(findChild<LLComboBox>( "Gesture"));
mInputEditor = getChild<LLLineEditor>("Chat Editor");
- if (mInputEditor)
- {
- mInputEditor->setCallbackUserData(this);
- mInputEditor->setKeystrokeCallback(&onInputEditorKeystroke);
- mInputEditor->setFocusLostCallback(&onInputEditorFocusLost, this);
- mInputEditor->setFocusReceivedCallback( &onInputEditorGainFocus, this );
- mInputEditor->setCommitOnFocusLost( FALSE );
- mInputEditor->setRevertOnEsc( FALSE );
- mInputEditor->setIgnoreTab(TRUE);
- mInputEditor->setPassDelete(TRUE);
- mInputEditor->setReplaceNewlinesWithSpaces(FALSE);
-
- mInputEditor->setMaxTextLength(1023);
- mInputEditor->setEnableLineHistory(TRUE);
- }
+ mInputEditor->setKeystrokeCallback(&onInputEditorKeystroke, this);
+ mInputEditor->setFocusLostCallback(&onInputEditorFocusLost, this);
+ mInputEditor->setFocusReceivedCallback( &onInputEditorGainFocus, this );
+ mInputEditor->setCommitOnFocusLost( FALSE );
+ mInputEditor->setRevertOnEsc( FALSE );
+ mInputEditor->setIgnoreTab(TRUE);
+ mInputEditor->setPassDelete(TRUE);
+ mInputEditor->setReplaceNewlinesWithSpaces(FALSE);
+
+ mInputEditor->setMaxTextLength(1023);
+ mInputEditor->setEnableLineHistory(TRUE);
mIsBuilt = TRUE;
@@ -209,10 +193,7 @@ void LLChatBar::refresh()
gAgent.stopTyping();
}
- childSetValue("History", LLFloaterChat::instanceVisible(LLSD()));
-
childSetEnabled("Say", mInputEditor->getText().size() > 0);
- childSetEnabled("Shout", mInputEditor->getText().size() > 0);
}
@@ -230,7 +211,7 @@ void LLChatBar::refreshGestures()
// collect list of unique gestures
std::map <std::string, BOOL> unique;
LLGestureManager::item_map_t::iterator it;
- for (it = gGestureManager.mActive.begin(); it != gGestureManager.mActive.end(); ++it)
+ for (it = LLGestureManager::instance().mActive.begin(); it != LLGestureManager::instance().mActive.end(); ++it)
{
LLMultiGesture* gesture = (*it).second;
if (gesture)
@@ -311,12 +292,11 @@ void LLChatBar::setGestureCombo(LLComboBox* combo)
mGestureCombo = combo;
if (mGestureCombo)
{
- mGestureCombo->setCommitCallback(onCommitGesture);
- mGestureCombo->setCallbackUserData(this);
+ mGestureCombo->setCommitCallback(boost::bind(&LLChatBar::onCommitGesture, this, _1));
// now register observer since we have a place to put the results
mObserver = new LLChatBarGestureObserver(this);
- gGestureManager.addObserver(mObserver);
+ LLGestureManager::instance().addObserver(mObserver);
// refresh list from current active gestures
refreshGestures();
@@ -397,7 +377,7 @@ void LLChatBar::sendChat( EChatType type )
if (0 == channel)
{
// discard returned "found" boolean
- gGestureManager.triggerAndReviseString(utf8text, &utf8_revised_text);
+ LLGestureManager::instance().triggerAndReviseString(utf8text, &utf8_revised_text);
}
else
{
@@ -434,17 +414,26 @@ void LLChatBar::sendChat( EChatType type )
// static
void LLChatBar::startChat(const char* line)
{
- gChatBar->setVisible(TRUE);
- gChatBar->setKeyboardFocus(TRUE);
- gSavedSettings.setBOOL("ChatVisible", TRUE);
-
- if (line && gChatBar->mInputEditor)
- {
- std::string line_string(line);
- gChatBar->mInputEditor->setText(line_string);
- }
- // always move cursor to end so users don't obliterate chat when accidentally hitting WASD
- gChatBar->mInputEditor->setCursorToEnd();
+ //TODO* remove DUMMY chat
+ //if(gBottomTray && gBottomTray->getChatBox())
+ //{
+ // gBottomTray->setVisible(TRUE);
+ // gBottomTray->getChatBox()->setFocus(TRUE);
+ //}
+
+ // *TODO Vadim: Why was this code commented out?
+
+// gChatBar->setVisible(TRUE);
+// gChatBar->setKeyboardFocus(TRUE);
+// gSavedSettings.setBOOL("ChatVisible", TRUE);
+//
+// if (line && gChatBar->mInputEditor)
+// {
+// std::string line_string(line);
+// gChatBar->mInputEditor->setText(line_string);
+// }
+// // always move cursor to end so users don't obliterate chat when accidentally hitting WASD
+// gChatBar->mInputEditor->setCursorToEnd();
}
@@ -452,21 +441,29 @@ void LLChatBar::startChat(const char* line)
// static
void LLChatBar::stopChat()
{
- // In simple UI mode, we never release focus from the chat bar
- gChatBar->setKeyboardFocus(FALSE);
-
- // If we typed a movement key and pressed return during the
- // same frame, the keyboard handlers will see the key as having
- // gone down this frame and try to move the avatar.
- gKeyboard->resetKeys();
- gKeyboard->resetMaskKeys();
-
- // stop typing animation
- gAgent.stopTyping();
-
- // hide chat bar so it doesn't grab focus back
- gChatBar->setVisible(FALSE);
- gSavedSettings.setBOOL("ChatVisible", FALSE);
+ //TODO* remove DUMMY chat
+ //if(gBottomTray && gBottomTray->getChatBox())
+ ///{
+ // gBottomTray->getChatBox()->setFocus(FALSE);
+ //}
+
+ // *TODO Vadim: Why was this code commented out?
+
+// // In simple UI mode, we never release focus from the chat bar
+// gChatBar->setKeyboardFocus(FALSE);
+//
+// // If we typed a movement key and pressed return during the
+// // same frame, the keyboard handlers will see the key as having
+// // gone down this frame and try to move the avatar.
+// gKeyboard->resetKeys();
+// gKeyboard->resetMaskKeys();
+//
+// // stop typing animation
+// gAgent.stopTyping();
+//
+// // hide chat bar so it doesn't grab focus back
+// gChatBar->setVisible(FALSE);
+// gSavedSettings.setBOOL("ChatVisible", FALSE);
}
// static
@@ -519,7 +516,7 @@ void LLChatBar::onInputEditorKeystroke( LLLineEditor* caller, void* userdata )
std::string utf8_trigger = wstring_to_utf8str(raw_text);
std::string utf8_out_str(utf8_trigger);
- if (gGestureManager.matchPrefix(utf8_trigger, &utf8_out_str))
+ if (LLGestureManager::instance().matchPrefix(utf8_trigger, &utf8_out_str))
{
if (self->mInputEditor)
{
@@ -553,20 +550,19 @@ void LLChatBar::onInputEditorGainFocus( LLFocusableElement* caller, void* userda
LLFloaterChat::setHistoryCursorAndScrollToEnd();
}
-// static
-void LLChatBar::onClickSay( LLUICtrl* ctrl, void* userdata )
+void LLChatBar::onClickSay( LLUICtrl* ctrl )
{
+ std::string cmd = ctrl->getValue().asString();
e_chat_type chat_type = CHAT_TYPE_NORMAL;
- if (ctrl->getValue().asString() == "shout")
+ if (cmd == "shout")
{
chat_type = CHAT_TYPE_SHOUT;
}
- else if (ctrl->getValue().asString() == "whisper")
+ else if (cmd == "whisper")
{
chat_type = CHAT_TYPE_WHISPER;
}
- LLChatBar* self = (LLChatBar*) userdata;
- self->sendChat(chat_type);
+ sendChat(chat_type);
}
void LLChatBar::sendChatFromViewer(const std::string &utf8text, EChatType type, BOOL animate)
@@ -622,7 +618,7 @@ void LLChatBar::sendChatFromViewer(const LLWString &wtext, EChatType type, BOOL
send_chat_from_viewer(utf8_out_text, type, channel);
}
-
+/*
void send_chat_from_viewer(const std::string& utf8_out_text, EChatType type, S32 channel)
{
LLMessageSystem* msg = gMessageSystem;
@@ -639,13 +635,11 @@ void send_chat_from_viewer(const std::string& utf8_out_text, EChatType type, S32
LLViewerStats::getInstance()->incStat(LLViewerStats::ST_CHAT_COUNT);
}
+*/
-
-// static
-void LLChatBar::onCommitGesture(LLUICtrl* ctrl, void* data)
+void LLChatBar::onCommitGesture(LLUICtrl* ctrl)
{
- LLChatBar* self = (LLChatBar*)data;
- LLCtrlListInterface* gestures = self->mGestureCombo ? self->mGestureCombo->getListInterface() : NULL;
+ LLCtrlListInterface* gestures = mGestureCombo ? mGestureCombo->getListInterface() : NULL;
if (gestures)
{
S32 index = gestures->getFirstSelectedIndex();
@@ -659,29 +653,23 @@ void LLChatBar::onCommitGesture(LLUICtrl* ctrl, void* data)
// substitution and logging.
std::string text(trigger);
std::string revised_text;
- gGestureManager.triggerAndReviseString(text, &revised_text);
+ LLGestureManager::instance().triggerAndReviseString(text, &revised_text);
revised_text = utf8str_trim(revised_text);
if (!revised_text.empty())
{
// Don't play nodding animation
- self->sendChatFromViewer(revised_text, CHAT_TYPE_NORMAL, FALSE);
+ sendChatFromViewer(revised_text, CHAT_TYPE_NORMAL, FALSE);
}
}
- self->mGestureLabelTimer.start();
- if (self->mGestureCombo != NULL)
+ mGestureLabelTimer.start();
+ if (mGestureCombo != NULL)
{
// free focus back to chat bar
- self->mGestureCombo->setFocus(FALSE);
+ mGestureCombo->setFocus(FALSE);
}
}
-void toggleChatHistory(void* user_data)
-{
- LLFloaterChat::toggleInstance(LLSD());
-}
-
-
class LLChatHandler : public LLCommandHandler
{
public:
@@ -690,7 +678,7 @@ public:
// Your code here
bool handle(const LLSD& tokens, const LLSD& query_map,
- LLWebBrowserCtrl* web)
+ LLMediaCtrl* web)
{
if (tokens.size() < 2) return false;
S32 channel = tokens[0].asInteger();
@@ -701,4 +689,4 @@ public:
};
// Creating the object registers with the dispatcher.
-LLChatHandler gChatHandler;
+//LLChatHandler gChatHandler;
diff --git a/indra/newview/llchatbar.h b/indra/newview/llchatbar.h
index 56a98a78f9..a41947218d 100644
--- a/indra/newview/llchatbar.h
+++ b/indra/newview/llchatbar.h
@@ -45,6 +45,7 @@ class LLFrameTimer;
class LLChatBarGestureObserver;
class LLComboBox;
+
class LLChatBar
: public LLPanel
{
@@ -82,14 +83,14 @@ public:
LLWString stripChannelNumber(const LLWString &mesg, S32* channel);
// callbacks
- static void onClickSay( LLUICtrl*, void* userdata );
+ void onClickSay(LLUICtrl* ctrl);
static void onTabClick( void* userdata );
static void onInputEditorKeystroke(LLLineEditor* caller, void* userdata);
static void onInputEditorFocusLost(LLFocusableElement* caller,void* userdata);
static void onInputEditorGainFocus(LLFocusableElement* caller,void* userdata);
- static void onCommitGesture(LLUICtrl* ctrl, void* data);
+ void onCommitGesture(LLUICtrl* ctrl);
static void startChat(const char* line);
static void stopChat();
diff --git a/indra/newview/llchatitemscontainerctrl.cpp b/indra/newview/llchatitemscontainerctrl.cpp
new file mode 100644
index 0000000000..f5dfbb2851
--- /dev/null
+++ b/indra/newview/llchatitemscontainerctrl.cpp
@@ -0,0 +1,554 @@
+/**
+ * @file llchatitemscontainer.cpp
+ * @brief chat history scrolling panel implementation
+ *
+ * $LicenseInfo:firstyear=2009&license=viewergpl$
+ *
+ * Copyright (c) 2009, Linden Research, Inc.
+ *
+ * Second Life Viewer Source Code
+ * The source code in this file ("Source Code") is provided by Linden Lab
+ * to you under the terms of the GNU General Public License, version 2.0
+ * ("GPL"), unless you have obtained a separate licensing agreement
+ * ("Other License"), formally executed by you and Linden Lab. Terms of
+ * the GPL can be found in doc/GPL-license.txt in this distribution, or
+ * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
+ *
+ * There are special exceptions to the terms and conditions of the GPL as
+ * it is applied to this Source Code. View the full text of the exception
+ * in the file doc/FLOSS-exception.txt in this software distribution, or
+ * online at
+ * http://secondlifegrid.net/programs/open_source/licensing/flossexception
+ *
+ * By copying, modifying or distributing this software, you acknowledge
+ * that you have read and understood your obligations described above,
+ * and agree to abide by those obligations.
+ *
+ * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+ * COMPLETENESS OR PERFORMANCE.
+ * $/LicenseInfo$
+ */
+
+#include "llviewerprecompiledheaders.h"
+
+#include "llchatitemscontainerctrl.h"
+#include "lltextbox.h"
+
+#include "llchatmsgbox.h"
+#include "llavatariconctrl.h"
+#include "llfloaterreg.h"
+#include "lltrans.h"
+
+#include "llviewercontrol.h"
+#include "llagentdata.h"
+
+static const S32 BORDER_MARGIN = 2;
+static const S32 PARENT_BORDER_MARGIN = 0;
+
+static const S32 HORIZONTAL_MULTIPLE = 8;
+static const S32 VERTICAL_MULTIPLE = 16;
+static const F32 MIN_AUTO_SCROLL_RATE = 120.f;
+static const F32 MAX_AUTO_SCROLL_RATE = 500.f;
+static const F32 AUTO_SCROLL_RATE_ACCEL = 120.f;
+
+static const S32 msg_left_offset = 30;
+static const S32 msg_right_offset = 10;
+
+#define MAX_CHAT_HISTORY 100
+
+
+static LLDefaultChildRegistry::Register<LLChatItemsContainerCtrl> t2("chat_items_container");
+
+
+
+//*******************************************************************************************************************
+//LLChatItemCtrl
+//*******************************************************************************************************************
+
+LLChatItemCtrl* LLChatItemCtrl::createInstance()
+{
+ LLChatItemCtrl* item = new LLChatItemCtrl();
+ LLUICtrlFactory::getInstance()->buildPanel(item, "panel_chat_item.xml");
+ return item;
+}
+
+void LLChatItemCtrl::draw()
+{
+ LLPanel::draw();
+}
+
+void LLChatItemCtrl::reshape (S32 width, S32 height, BOOL called_from_parent )
+{
+ LLPanel::reshape(width, height,called_from_parent);
+
+ // *NOTE: we must check if child items exist because reshape is called from the
+ // LLView::initFromParams BEFORE postBuild is called and child controls are not exist yet
+ LLPanel* caption = findChild<LLPanel>("msg_caption", false);
+ LLChatMsgBox* msg_text = findChild<LLChatMsgBox>("msg_text" ,false);
+ if(caption && msg_text)
+ {
+ LLRect caption_rect = caption->getRect();
+ caption_rect.setLeftTopAndSize( 2, height, width - 4, caption_rect.getHeight());
+ caption->reshape( width - 4, caption_rect.getHeight(), 1);
+ caption->setRect(caption_rect);
+
+ LLRect msg_text_rect = msg_text->getRect();
+ msg_text_rect.setLeftTopAndSize( msg_left_offset, height - caption_rect.getHeight() , width - msg_left_offset - msg_right_offset, height - caption_rect.getHeight());
+ msg_text->reshape( width - msg_left_offset - msg_right_offset, height - caption_rect.getHeight(), 1);
+ msg_text->setRect(msg_text_rect);
+ }
+}
+
+BOOL LLChatItemCtrl::postBuild()
+{
+ return LLPanel::postBuild();
+}
+
+
+std::string LLChatItemCtrl::appendTime()
+{
+ time_t utc_time;
+ utc_time = time_corrected();
+ std::string timeStr ="["+ LLTrans::getString("TimeHour")+"]:["
+ +LLTrans::getString("TimeMin")+"] ";
+
+ LLSD substitution;
+
+ substitution["datetime"] = (S32) utc_time;
+ LLStringUtil::format (timeStr, substitution);
+
+ return timeStr;
+}
+
+
+
+void LLChatItemCtrl::addText (const std::string& message)
+{
+ LLChatMsgBox* msg_text = getChild<LLChatMsgBox>("msg_text", false);
+ msg_text->addText(message);
+ mMessages.push_back(message);
+}
+
+void LLChatItemCtrl::setMessage (const LLChat& msg)
+{
+ LLPanel* caption = getChild<LLPanel>("msg_caption", false);
+
+ std::string str_sender;
+
+
+ if(gAgentID != msg.mFromID)
+ str_sender = msg.mFromName;
+ else
+ str_sender = LLTrans::getString("You");;
+
+ caption->getChild<LLTextBox>("sender_name", false)->setText(str_sender);
+
+ std::string tt = appendTime();
+
+ caption->getChild<LLTextBox>("msg_time", false)->setText(tt);
+
+
+ caption->getChild<LLAvatarIconCtrl>("avatar_icon", false)->setValue(msg.mFromID);
+
+ mOriginalMessage = msg;
+
+ LLChatMsgBox* msg_text = getChild<LLChatMsgBox>("msg_text", false);
+ msg_text->setText(msg.mText);
+
+ LLUICtrl* msg_inspector = caption->getChild<LLUICtrl>("msg_inspector");
+ if(mOriginalMessage.mSourceType != CHAT_SOURCE_AGENT)
+ msg_inspector->setVisible(false);
+
+ mMessages.clear();
+
+}
+
+void LLChatItemCtrl::snapToMessageHeight ()
+{
+ LLChatMsgBox* text_box = getChild<LLChatMsgBox>("msg_text", false);
+ S32 new_height = text_box->getTextPixelHeight();
+ LLRect panel_rect = getRect();
+
+ S32 caption_height = 0;
+ LLPanel* caption = getChild<LLPanel>("msg_caption", false);
+ caption_height = caption->getRect().getHeight();
+
+ panel_rect.setLeftTopAndSize( panel_rect.mLeft, panel_rect.mTop, panel_rect.getWidth() , caption_height + new_height);
+
+ reshape( getRect().getWidth(), caption_height + new_height, 1);
+
+ setRect(panel_rect);
+
+}
+
+
+void LLChatItemCtrl::setWidth(S32 width)
+{
+ LLChatMsgBox* text_box = getChild<LLChatMsgBox>("msg_text", false);
+ text_box->reshape(width - msg_left_offset - msg_right_offset,100/*its not magic number, we just need any number*/);
+
+ LLChatMsgBox* msg_text = getChild<LLChatMsgBox>("msg_text", false);
+ if(mOriginalMessage.mText.length())
+ msg_text->setText(mOriginalMessage.mText);
+
+ for(size_t i=0;i<mMessages.size();++i)
+ msg_text->addText(mMessages[i]);
+
+ setRect(LLRect(getRect().mLeft, getRect().mTop, getRect().mLeft + width , getRect().mBottom));
+ snapToMessageHeight ();
+}
+
+void LLChatItemCtrl::onMouseLeave (S32 x, S32 y, MASK mask)
+{
+ LLPanel* caption = getChild<LLPanel>("msg_caption", false);
+ LLUICtrl* msg_inspector = caption->getChild<LLUICtrl>("msg_inspector");
+ msg_inspector->setVisible(false);
+
+}
+void LLChatItemCtrl::onMouseEnter (S32 x, S32 y, MASK mask)
+{
+ if(mOriginalMessage.mSourceType != CHAT_SOURCE_AGENT)
+ return;
+ LLPanel* caption = getChild<LLPanel>("msg_caption", false);
+ LLUICtrl* msg_inspector = caption->getChild<LLUICtrl>("msg_inspector");
+ msg_inspector->setVisible(true);
+}
+
+BOOL LLChatItemCtrl::handleMouseDown (S32 x, S32 y, MASK mask)
+{
+ if(mOriginalMessage.mSourceType != CHAT_SOURCE_AGENT)
+ return LLPanel::handleMouseDown(x,y,mask);
+ LLPanel* caption = getChild<LLPanel>("msg_caption", false);
+ LLUICtrl* msg_inspector = caption->getChild<LLUICtrl>("msg_inspector");
+ S32 local_x = x - msg_inspector->getRect().mLeft - caption->getRect().mLeft;
+ S32 local_y = y - msg_inspector->getRect().mBottom - caption->getRect().mBottom;
+ if(msg_inspector->pointInView(local_x, local_y))
+ {
+ LLFloaterReg::showInstance("inspect_avatar", mOriginalMessage.mFromID);
+ }
+ return LLPanel::handleMouseDown(x,y,mask);
+}
+
+void LLChatItemCtrl::setHeaderVisibility(EShowItemHeader e)
+{
+ LLPanel* caption = getChild<LLPanel>("msg_caption", false);
+
+ LLUICtrl* icon = caption->getChild<LLUICtrl>("avatar_icon", false);
+ LLUICtrl* name = caption->getChild<LLUICtrl>("sender_name", false);
+
+ icon->setVisible(e == CHATITEMHEADER_SHOW_ONLY_ICON || e==CHATITEMHEADER_SHOW_BOTH);
+ name->setVisible(e == CHATITEMHEADER_SHOW_ONLY_NAME || e==CHATITEMHEADER_SHOW_BOTH);
+
+}
+
+bool LLChatItemCtrl::canAddText ()
+{
+ LLChatMsgBox* msg_text = findChild<LLChatMsgBox>("msg_text");
+ if(!msg_text)
+ return false;
+ return msg_text->getTextLinesNum()<10;
+}
+
+BOOL LLChatItemCtrl::handleRightMouseDown(S32 x, S32 y, MASK mask)
+{
+ LLPanel* caption = getChild<LLPanel>("msg_caption", false);
+ LLUICtrl* avatar_icon = caption->getChild<LLUICtrl>("avatar_icon", false);
+
+ S32 local_x = x - avatar_icon->getRect().mLeft - caption->getRect().mLeft;
+ S32 local_y = y - avatar_icon->getRect().mBottom - caption->getRect().mBottom;
+
+ //eat message for avatar icon if msg was from object
+ if(avatar_icon->pointInView(local_x, local_y) && mOriginalMessage.mSourceType != CHAT_SOURCE_AGENT)
+ return TRUE;
+ return LLPanel::handleRightMouseDown(x,y,mask);
+}
+
+
+//*******************************************************************************************************************
+//LLChatItemsContainerCtrl
+//*******************************************************************************************************************
+
+LLChatItemsContainerCtrl::LLChatItemsContainerCtrl(const Params& params):LLPanel(params)
+{
+ mEShowItemHeader = CHATITEMHEADER_SHOW_BOTH;
+}
+
+
+void LLChatItemsContainerCtrl::addMessage(const LLChat& msg)
+{
+ /*
+ if(msg.mChatType == CHAT_TYPE_DEBUG_MSG)
+ return;
+ */
+ if(mItems.size() >= MAX_CHAT_HISTORY)
+ {
+ LLChatItemCtrl* item = mItems[0];
+ removeChild(item);
+ delete item;
+ mItems.erase(mItems.begin());
+ }
+
+
+ if(mItems.size() > 0
+ && msg.mFromID == mItems[mItems.size()-1]->getMessage().mFromID
+ && (msg.mTime-mItems[mItems.size()-1]->getMessage().mTime)<60
+ && mItems[mItems.size()-1]->canAddText()
+ )
+ {
+ mItems[mItems.size()-1]->addText(msg.mText);
+ mItems[mItems.size()-1]->snapToMessageHeight();
+ }
+ else
+ {
+ LLChatItemCtrl* item = LLChatItemCtrl::createInstance();
+ mItems.push_back(item);
+ addChild(item,0);
+ item->setWidth(getRect().getWidth() - 16);
+ item->setMessage(msg);
+ item->snapToMessageHeight();
+
+ item->setHeaderVisibility((EShowItemHeader)gSavedSettings.getS32("nearbychat_showicons_and_names"));
+
+ item->setVisible(true);
+ }
+
+ arrange(getRect().getWidth(),getRect().getHeight());
+ updateLayout(getRect().getWidth(),getRect().getHeight());
+ scrollToBottom();
+}
+
+void LLChatItemsContainerCtrl::scrollToBottom ()
+{
+ if(mScrollbar->getVisible())
+ {
+ mScrollbar->setDocPos(mScrollbar->getDocPosMax());
+ onScrollPosChangeCallback(0,0);
+ }
+}
+
+void LLChatItemsContainerCtrl::draw()
+{
+ LLLocalClipRect clip(getRect());
+ LLPanel::draw();
+}
+
+void LLChatItemsContainerCtrl::reshape (S32 width, S32 height, BOOL called_from_parent )
+{
+ S32 delta_width = width - getRect().getWidth();
+ S32 delta_height = height - getRect().getHeight();
+
+ if (delta_width || delta_height || sForceReshape)
+ {
+ arrange(width, height);
+ }
+
+ updateBoundingRect();
+}
+
+void LLChatItemsContainerCtrl::arrange (S32 width, S32 height)
+{
+ S32 delta_width = width - getRect().getWidth();
+ if(delta_width)//width changed...too bad. now we need to reformat all items
+ reformatHistoryScrollItems(width);
+
+ calcRecuiredHeight();
+
+ show_hide_scrollbar(width,height);
+
+ updateLayout(width,height);
+}
+
+void LLChatItemsContainerCtrl::reformatHistoryScrollItems(S32 width)
+{
+ for(std::vector<LLChatItemCtrl*>::iterator it = mItems.begin(); it != mItems.end();++it)
+ {
+ (*it)->setWidth(width);
+ }
+}
+
+S32 LLChatItemsContainerCtrl::calcRecuiredHeight ()
+{
+ S32 rec_height = 0;
+
+ std::vector<LLChatItemCtrl*>::iterator it;
+ for(it=mItems.begin(); it!=mItems.end(); ++it)
+ {
+ rec_height += (*it)->getRect().getHeight();
+ }
+
+ mInnerRect.setLeftTopAndSize(0,rec_height + BORDER_MARGIN*2,getRect().getWidth(),rec_height + BORDER_MARGIN);
+
+ return mInnerRect.getHeight();
+}
+
+
+void LLChatItemsContainerCtrl::updateLayout (S32 width, S32 height)
+{
+ S32 panel_top = height - BORDER_MARGIN ;
+ S32 panel_width = width;
+ if(mScrollbar->getVisible())
+ {
+ static LLUICachedControl<S32> scrollbar_size ("UIScrollbarSize", 0);
+
+ panel_top+=mScrollbar->getDocPos();
+ panel_width-=scrollbar_size;
+ }
+
+
+ //set sizes for first panels and dragbars
+ for(size_t i=0;i<mItems.size();++i)
+ {
+ LLRect panel_rect = mItems[i]->getRect();
+ panelSetLeftTopAndSize(mItems[i],panel_rect.mLeft,panel_top,panel_width,panel_rect.getHeight());
+ panel_top-=panel_rect.getHeight();
+ }
+}
+
+void LLChatItemsContainerCtrl::show_hide_scrollbar (S32 width, S32 height)
+{
+ calcRecuiredHeight();
+ if(getRecuiredHeight() > height )
+ showScrollbar(width, height);
+ else
+ hideScrollbar(width, height);
+}
+
+void LLChatItemsContainerCtrl::showScrollbar (S32 width, S32 height)
+{
+ bool was_visible = mScrollbar->getVisible();
+
+ mScrollbar->setVisible(true);
+
+ static LLUICachedControl<S32> scrollbar_size ("UIScrollbarSize", 0);
+
+ panelSetLeftTopAndSize(mScrollbar,width-scrollbar_size
+ ,height-PARENT_BORDER_MARGIN,scrollbar_size,height-2*PARENT_BORDER_MARGIN);
+
+ mScrollbar->setPageSize(height);
+ mScrollbar->setDocParams(mInnerRect.getHeight(),mScrollbar->getDocPos());
+
+ if(was_visible)
+ {
+ S32 scroll_pos = llmin(mScrollbar->getDocPos(), getRecuiredHeight() - height - 1);
+ mScrollbar->setDocPos(scroll_pos);
+ updateLayout(width,height);
+ return;
+ }
+}
+
+void LLChatItemsContainerCtrl::hideScrollbar (S32 width, S32 height)
+{
+ if(mScrollbar->getVisible() == false)
+ return;
+ mScrollbar->setVisible(false);
+
+ mScrollbar->setDocPos(0);
+
+ if(mItems.size()>0)
+ {
+ S32 panel_top = height - BORDER_MARGIN; // Top coordinate of the first panel
+ S32 diff = panel_top - mItems[0]->getRect().mTop;
+ shiftPanels(diff);
+ }
+}
+
+//---------------------------------------------------------------------------------
+void LLChatItemsContainerCtrl::panelSetLeftTopAndSize(LLView* panel, S32 left, S32 top, S32 width, S32 height)
+{
+ if(!panel)
+ return;
+ LLRect panel_rect = panel->getRect();
+ panel_rect.setLeftTopAndSize( left, top, width, height);
+ panel->reshape( width, height, 1);
+ panel->setRect(panel_rect);
+}
+
+void LLChatItemsContainerCtrl::panelShiftVertical(LLView* panel,S32 delta)
+{
+ if(!panel)
+ return;
+ panel->translate(0,delta);
+}
+
+void LLChatItemsContainerCtrl::shiftPanels(S32 delta)
+{
+ //Arrange panels
+ for(std::vector<LLChatItemCtrl*>::iterator it = mItems.begin(); it != mItems.end();++it)
+ {
+ panelShiftVertical((*it),delta);
+ }
+
+}
+
+//---------------------------------------------------------------------------------
+
+void LLChatItemsContainerCtrl::onScrollPosChangeCallback(S32, LLScrollbar*)
+{
+ updateLayout(getRect().getWidth(),getRect().getHeight());
+}
+
+BOOL LLChatItemsContainerCtrl::postBuild()
+{
+ static LLUICachedControl<S32> scrollbar_size ("UIScrollbarSize", 0);
+
+ LLRect scroll_rect;
+ scroll_rect.setOriginAndSize(
+ getRect().getWidth() - scrollbar_size,
+ 1,
+ scrollbar_size,
+ getRect().getHeight() - 1);
+
+
+ LLScrollbar::Params sbparams;
+ sbparams.name("scrollable vertical");
+ sbparams.rect(scroll_rect);
+ sbparams.orientation(LLScrollbar::VERTICAL);
+ sbparams.doc_size(mInnerRect.getHeight());
+ sbparams.doc_pos(0);
+ sbparams.page_size(mInnerRect.getHeight());
+ sbparams.step_size(VERTICAL_MULTIPLE);
+ sbparams.follows.flags(FOLLOWS_RIGHT | FOLLOWS_TOP | FOLLOWS_BOTTOM);
+ sbparams.change_callback(boost::bind(&LLChatItemsContainerCtrl::onScrollPosChangeCallback, this, _1, _2));
+
+ mScrollbar = LLUICtrlFactory::create<LLScrollbar> (sbparams);
+ LLView::addChild( mScrollbar );
+ mScrollbar->setVisible( true );
+ mScrollbar->setFollowsRight();
+ mScrollbar->setFollowsTop();
+ mScrollbar->setFollowsBottom();
+
+ reformatHistoryScrollItems(getRect().getWidth());
+ arrange(getRect().getWidth(),getRect().getHeight());
+
+ return LLPanel::postBuild();
+}
+BOOL LLChatItemsContainerCtrl::handleMouseDown (S32 x, S32 y, MASK mask)
+{
+ return LLPanel::handleMouseDown(x,y,mask);
+}
+BOOL LLChatItemsContainerCtrl::handleKeyHere (KEY key, MASK mask)
+{
+ if( mScrollbar->getVisible() && mScrollbar->handleKeyHere( key,mask ) )
+ return TRUE;
+ return LLPanel::handleKeyHere(key,mask);
+}
+BOOL LLChatItemsContainerCtrl::handleScrollWheel ( S32 x, S32 y, S32 clicks )
+{
+ if( mScrollbar->getVisible() && mScrollbar->handleScrollWheel( 0, 0, clicks ) )
+ return TRUE;
+ return false;
+}
+
+void LLChatItemsContainerCtrl::setHeaderVisibility(EShowItemHeader e)
+{
+ if(e == mEShowItemHeader)
+ return;
+ mEShowItemHeader = e;
+ for(std::vector<LLChatItemCtrl*>::iterator it = mItems.begin(); it != mItems.end();++it)
+ {
+ (*it)->setHeaderVisibility(e);
+ }
+}
+
+
diff --git a/indra/newview/llchatitemscontainerctrl.h b/indra/newview/llchatitemscontainerctrl.h
new file mode 100644
index 0000000000..de16cf9505
--- /dev/null
+++ b/indra/newview/llchatitemscontainerctrl.h
@@ -0,0 +1,154 @@
+/**
+ * @file llchatitemscontainer.h
+ * @brief chat history scrolling panel implementation
+ *
+ * $LicenseInfo:firstyear=2004&license=viewergpl$
+ *
+ * Copyright (c) 2004-2009, Linden Research, Inc.
+ *
+ * Second Life Viewer Source Code
+ * The source code in this file ("Source Code") is provided by Linden Lab
+ * to you under the terms of the GNU General Public License, version 2.0
+ * ("GPL"), unless you have obtained a separate licensing agreement
+ * ("Other License"), formally executed by you and Linden Lab. Terms of
+ * the GPL can be found in doc/GPL-license.txt in this distribution, or
+ * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
+ *
+ * There are special exceptions to the terms and conditions of the GPL as
+ * it is applied to this Source Code. View the full text of the exception
+ * in the file doc/FLOSS-exception.txt in this software distribution, or
+ * online at
+ * http://secondlifegrid.net/programs/open_source/licensing/flossexception
+ *
+ * By copying, modifying or distributing this software, you acknowledge
+ * that you have read and understood your obligations described above,
+ * and agree to abide by those obligations.
+ *
+ * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+ * COMPLETENESS OR PERFORMANCE.
+ * $/LicenseInfo$
+ */
+
+#ifndef LL_LLCHATITEMSCONTAINER_H_
+#define LL_LLCHATITEMSCONTAINER_H_
+
+#include "llpanel.h"
+#include "llscrollbar.h"
+#include "string"
+#include "llchat.h"
+
+typedef enum e_show_item_header
+{
+ CHATITEMHEADER_SHOW_ONLY_NAME = 0,
+ CHATITEMHEADER_SHOW_ONLY_ICON = 1,
+ CHATITEMHEADER_SHOW_BOTH
+} EShowItemHeader;
+
+class LLChatItemCtrl: public LLPanel
+{
+protected:
+ LLChatItemCtrl(){};
+public:
+
+
+ ~LLChatItemCtrl(){}
+
+ static LLChatItemCtrl* createInstance();
+
+ void draw();
+
+ const LLChat& getMessage() const { return mOriginalMessage;}
+
+ void addText (const std::string& message);
+ void setMessage (const LLChat& msg);
+ void setWidth (S32 width);
+ void snapToMessageHeight ();
+
+ bool canAddText ();
+
+ void onMouseLeave (S32 x, S32 y, MASK mask);
+ void onMouseEnter (S32 x, S32 y, MASK mask);
+ BOOL handleMouseDown (S32 x, S32 y, MASK mask);
+
+ virtual BOOL postBuild();
+
+ void reshape (S32 width, S32 height, BOOL called_from_parent = TRUE);
+
+ void setHeaderVisibility(EShowItemHeader e);
+ BOOL handleRightMouseDown(S32 x, S32 y, MASK mask);
+private:
+
+ std::string appendTime ();
+
+private:
+ LLChat mOriginalMessage;
+
+ std::vector<std::string> mMessages;
+};
+
+class LLChatItemsContainerCtrl: public LLPanel
+{
+public:
+ struct Params
+ : public LLInitParam::Block<Params, LLPanel::Params>
+ {
+ Params(){};
+ };
+
+ LLChatItemsContainerCtrl(const Params& params);
+
+
+ ~LLChatItemsContainerCtrl(){}
+
+ void addMessage (const LLChat& msg);
+
+ void draw();
+
+ void reshape (S32 width, S32 height, BOOL called_from_parent = TRUE);
+
+ void onScrollPosChangeCallback(S32, LLScrollbar*);
+
+ virtual BOOL postBuild();
+
+ BOOL handleMouseDown (S32 x, S32 y, MASK mask);
+ BOOL handleKeyHere (KEY key, MASK mask);
+ BOOL handleScrollWheel( S32 x, S32 y, S32 clicks );
+
+ void scrollToBottom ();
+
+ void setHeaderVisibility(EShowItemHeader e);
+ EShowItemHeader getHeaderVisibility() const { return mEShowItemHeader;};
+
+
+private:
+ void reformatHistoryScrollItems(S32 width);
+ void arrange (S32 width, S32 height);
+
+ S32 calcRecuiredHeight ();
+ S32 getRecuiredHeight () const { return mInnerRect.getHeight(); }
+
+ void updateLayout (S32 width, S32 height);
+
+ void show_hide_scrollbar (S32 width, S32 height);
+
+ void showScrollbar (S32 width, S32 height);
+ void hideScrollbar (S32 width, S32 height);
+
+ void panelSetLeftTopAndSize (LLView* panel, S32 left, S32 top, S32 width, S32 height);
+ void panelShiftVertical (LLView* panel,S32 delta);
+ void shiftPanels (S32 delta);
+
+private:
+ std::vector<LLChatItemCtrl*> mItems;
+
+ EShowItemHeader mEShowItemHeader;
+
+ LLRect mInnerRect;
+ LLScrollbar* mScrollbar;
+
+};
+
+#endif
+
+
diff --git a/indra/newview/llchatmsgbox.cpp b/indra/newview/llchatmsgbox.cpp
new file mode 100644
index 0000000000..9399e1f68d
--- /dev/null
+++ b/indra/newview/llchatmsgbox.cpp
@@ -0,0 +1,389 @@
+/**
+ * @file llchatmsgbox.cpp
+ * @brief chat history text box, able to show array of strings with separator
+ *
+ * $LicenseInfo:firstyear=2004&license=viewergpl$
+ *
+ * Copyright (c) 2004-2009, Linden Research, Inc.
+ *
+ * Second Life Viewer Source Code
+ * The source code in this file ("Source Code") is provided by Linden Lab
+ * to you under the terms of the GNU General Public License, version 2.0
+ * ("GPL"), unless you have obtained a separate licensing agreement
+ * ("Other License"), formally executed by you and Linden Lab. Terms of
+ * the GPL can be found in doc/GPL-license.txt in this distribution, or
+ * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
+ *
+ * There are special exceptions to the terms and conditions of the GPL as
+ * it is applied to this Source Code. View the full text of the exception
+ * in the file doc/FLOSS-exception.txt in this software distribution, or
+ * online at
+ * http://secondlifegrid.net/programs/open_source/licensing/flossexception
+ *
+ * By copying, modifying or distributing this software, you acknowledge
+ * that you have read and understood your obligations described above,
+ * and agree to abide by those obligations.
+ *
+ * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+ * COMPLETENESS OR PERFORMANCE.
+ * $/LicenseInfo$
+ */
+
+
+#include "llviewerprecompiledheaders.h"
+
+#include "llchatmsgbox.h"
+#include "llwindow.h"
+#include "llfocusmgr.h"
+
+static LLDefaultChildRegistry::Register<LLChatMsgBox> r("text_chat");
+
+LLChatMsgBox::Params::Params()
+: text_color("text_color"),
+ highlight_on_hover("hover", false),
+ border_visible("border_visible", false),
+ border_drop_shadow_visible("border_drop_shadow_visible", false),
+ bg_visible("bg_visible", false),
+ use_ellipses("use_ellipses"),
+ word_wrap("word_wrap", false),
+ hover_color("hover_color"),
+ disabled_color("disabled_color"),
+ background_color("background_color"),
+ border_color("border_color"),
+ line_spacing("line_spacing", 4),
+ block_spacing("block_spacing",10),
+ text("text"),
+ font_shadow("font_shadow", LLFontGL::NO_SHADOW)
+{}
+
+LLChatMsgBox::LLChatMsgBox(const LLChatMsgBox::Params& p)
+: LLUICtrl(p),
+ mFontGL(p.font),
+ mHoverActive( p.highlight_on_hover ),
+ mHasHover( FALSE ),
+ mBackgroundVisible( p.bg_visible ),
+ mBorderVisible( p.border_visible ),
+ mShadowType( p.font_shadow ),
+ mBorderDropShadowVisible( p.border_drop_shadow_visible ),
+ mUseEllipses( p.use_ellipses ),
+ mVAlign( LLFontGL::TOP ),
+ mClickedCallback(NULL),
+ mTextColor(p.text_color()),
+ mDisabledColor(p.disabled_color()),
+ mBackgroundColor(p.background_color()),
+ mBorderColor(p.border_color()),
+ mHoverColor(p.hover_color()),
+ mHAlign(p.font_halign),
+ mLineSpacing(p.line_spacing),
+ mBlockSpasing(p.block_spacing),
+ mWordWrap( p.word_wrap ),
+ mFontStyle(LLFontGL::getStyleFromString(p.font.style))
+{
+ setText( p.text() );
+}
+
+BOOL LLChatMsgBox::handleMouseDown(S32 x, S32 y, MASK mask)
+{
+ BOOL handled = FALSE;
+
+ // HACK: Only do this if there actually is a click callback, so that
+ // overly large text boxes in the older UI won't start eating clicks.
+ if (mClickedCallback)
+ {
+ handled = TRUE;
+
+ // Route future Mouse messages here preemptively. (Release on mouse up.)
+ gFocusMgr.setMouseCapture( this );
+
+ if (getSoundFlags() & MOUSE_DOWN)
+ {
+ make_ui_sound("UISndClick");
+ }
+ }
+
+ return handled;
+}
+
+BOOL LLChatMsgBox::handleMouseUp(S32 x, S32 y, MASK mask)
+{
+ BOOL handled = FALSE;
+
+ // We only handle the click if the click both started and ended within us
+
+ // HACK: Only do this if there actually is a click callback, so that
+ // overly large text boxes in the older UI won't start eating clicks.
+ if (mClickedCallback
+ && hasMouseCapture())
+ {
+ handled = TRUE;
+
+ // Release the mouse
+ gFocusMgr.setMouseCapture( NULL );
+
+ if (getSoundFlags() & MOUSE_UP)
+ {
+ make_ui_sound("UISndClickRelease");
+ }
+
+ // DO THIS AT THE VERY END to allow the button to be destroyed as a result of being clicked.
+ // If mouseup in the widget, it's been clicked
+ if (mClickedCallback)
+ {
+ mClickedCallback();
+ }
+ }
+
+ return handled;
+}
+
+BOOL LLChatMsgBox::handleHover(S32 x, S32 y, MASK mask)
+{
+ BOOL handled = LLView::handleHover(x,y,mask);
+ if(mHoverActive)
+ {
+ mHasHover = TRUE; // This should be set every frame during a hover.
+ getWindow()->setCursor(UI_CURSOR_ARROW);
+ }
+
+ return (handled || mHasHover);
+}
+
+void LLChatMsgBox::addText( const LLStringExplicit& text )
+{
+ boost::shared_ptr<text_block> t(new text_block());
+ t->text = wrapText(text);
+ setLineLengths(*t);
+ mTextStrings.push_back(t);
+}
+
+void LLChatMsgBox::setText(const LLStringExplicit& text)
+{
+ mTextStrings.clear();
+
+ addText(text);
+
+}
+
+void LLChatMsgBox::resetLineLengths()
+{
+ for(std::vector< boost::shared_ptr<text_block> >::iterator it = mTextStrings.begin();
+ it!=mTextStrings.end();++it)
+ {
+ boost::shared_ptr<text_block> tblock = *it;
+ setLineLengths(*tblock);
+ }
+}
+
+void LLChatMsgBox::setLineLengths(text_block& t)
+{
+ t.lines.clear();
+
+ std::string::size_type cur = 0;
+ std::string::size_type len = t.text.length();
+
+ while (cur < len)
+ {
+ std::string::size_type end = t.text.getWString().find('\n', cur);
+ std::string::size_type runLen;
+
+ if (end == std::string::npos)
+ {
+ runLen = len - cur;
+ cur = len;
+ }
+ else
+ {
+ runLen = end - cur;
+ cur = end + 1; // skip the new line character
+ }
+
+ t.lines.push_back( (S32)runLen );
+ }
+}
+
+std::string LLChatMsgBox::wrapText(const LLStringExplicit& in_text, F32 max_width)
+{
+ if (max_width < 0.0f)
+ {
+ max_width = (F32)getRect().getWidth();
+ }
+
+ LLWString wtext = utf8str_to_wstring(in_text);
+ LLWString final_wtext;
+
+ LLWString::size_type cur = 0;;
+ LLWString::size_type len = wtext.size();
+ while (cur < len)
+ {
+ LLWString::size_type end = wtext.find('\n', cur);
+ if (end == LLWString::npos)
+ {
+ end = len;
+ }
+
+ LLWString::size_type runLen = end - cur;
+ if (runLen > 0)
+ {
+ LLWString run(wtext, cur, runLen);
+ LLWString::size_type useLen =
+ mFontGL->maxDrawableChars(run.c_str(), max_width, runLen, TRUE);
+
+ final_wtext.append(wtext, cur, useLen);
+ cur += useLen;
+ // not enough room to add any more characters
+ if (useLen == 0) break;
+ }
+
+ if (cur < len)
+ {
+ if (wtext[cur] == '\n')
+ cur += 1;
+ else
+ final_wtext += '\n';
+ }
+ }
+
+ std::string final_text = wstring_to_utf8str(final_wtext);
+ return final_text;
+}
+
+S32 LLChatMsgBox::getTextLinesNum()
+{
+ S32 num_lines = 0;
+ for(std::vector< boost::shared_ptr<text_block> >::iterator it = mTextStrings.begin();
+ it!=mTextStrings.end();++it)
+ {
+ boost::shared_ptr<text_block> tblock = *it;
+ num_lines+=tblock->lines.size();
+ }
+
+ if( num_lines < 1 )
+ {
+ num_lines = 1;
+ }
+
+ return num_lines;
+}
+
+S32 LLChatMsgBox::getTextPixelHeight()
+{
+ S32 num_lines = getTextLinesNum();
+ return (S32)(num_lines * mFontGL->getLineHeight() + (num_lines-1)*mLineSpacing + mBlockSpasing*(mTextStrings.size()-1) + 2*mLineSpacing);//some extra space
+}
+
+void LLChatMsgBox::setValue(const LLSD& value )
+{
+ setText(value.asString());
+}
+
+
+void LLChatMsgBox::draw()
+{
+ if (mBorderVisible)
+ {
+ gl_rect_2d_offset_local(getLocalRect(), 2, FALSE);
+ }
+
+ if( mBorderDropShadowVisible )
+ {
+ static LLUICachedControl<LLColor4> color_drop_shadow ("ColorDropShadow", *(new LLColor4));
+ static LLUICachedControl<S32> drop_shadow_tooltip ("DropShadowTooltip", 0);
+ gl_drop_shadow(0, getRect().getHeight(), getRect().getWidth(), 0,
+ color_drop_shadow, drop_shadow_tooltip);
+ }
+
+ if (mBackgroundVisible)
+ {
+ LLRect r( 0, getRect().getHeight(), getRect().getWidth(), 0 );
+ gl_rect_2d( r, mBackgroundColor.get() );
+ }
+
+ S32 text_x = 0;
+ switch( mHAlign )
+ {
+ case LLFontGL::LEFT:
+ break;
+ case LLFontGL::HCENTER:
+ text_x = getRect().getWidth() / 2;
+ break;
+ case LLFontGL::RIGHT:
+ text_x = getRect().getWidth() ;
+ break;
+ }
+
+ S32 text_y = getRect().getHeight() ;
+
+ if ( getEnabled() )
+ {
+ if(mHasHover)
+ {
+ drawText( text_x, text_y, mHoverColor.get() );
+ }
+ else
+ {
+ drawText( text_x, text_y, mTextColor.get() );
+ }
+ }
+ else
+ {
+ drawText( text_x, text_y, mDisabledColor.get() );
+ }
+
+ if (sDebugRects)
+ {
+ drawDebugRect();
+ }
+
+ //// *HACK: also draw debug rectangles around currently-being-edited LLView, and any elements that are being highlighted by GUI preview code (see LLFloaterUIPreview)
+ //std::set<LLView*>::iterator iter = std::find(sPreviewHighlightedElements.begin(), sPreviewHighlightedElements.end(), this);
+ //if ((sEditingUI && this == sEditingUIView) || (iter != sPreviewHighlightedElements.end() && sDrawPreviewHighlights))
+ //{
+ // drawDebugRect();
+ //}
+
+ mHasHover = FALSE; // This is reset every frame.
+}
+
+void LLChatMsgBox::reshape(S32 width, S32 height, BOOL called_from_parent)
+{
+ // reparse line lengths
+ LLView::reshape(width, height, called_from_parent);
+ resetLineLengths();
+}
+
+void LLChatMsgBox::drawText( S32 x, S32 y, const LLColor4& color )
+{
+ S32 width = getRect().getWidth()-10;
+
+
+ for(std::vector< boost::shared_ptr<text_block> >::iterator it = mTextStrings.begin();
+ it!=mTextStrings.end();++it)
+ {
+ boost::shared_ptr<text_block> tblock = *it;
+
+ S32 cur_pos = 0;
+ for (std::vector<S32>::iterator iter = tblock->lines.begin();
+ iter != tblock->lines.end(); ++iter)
+ {
+ S32 line_length = *iter;
+ mFontGL->render(tblock->text, cur_pos, (F32)x, (F32)y, color,
+ mHAlign, mVAlign,
+ mFontStyle,
+ mShadowType,
+ line_length, getRect().getWidth(), NULL, mUseEllipses );
+ cur_pos += line_length + 1;
+ y -= llfloor(mFontGL->getLineHeight()) + mLineSpacing;
+
+ }
+ std::vector< boost::shared_ptr<text_block> >::iterator next = it;
+ ++next;
+ if(next == mTextStrings.end())
+ break;
+ //separator
+ gl_line_2d(5,y-mBlockSpasing/2,width,y-mBlockSpasing/2,LLColor4::grey);
+ y-=mBlockSpasing;
+ }
+
+}
+
diff --git a/indra/newview/llchatmsgbox.h b/indra/newview/llchatmsgbox.h
new file mode 100644
index 0000000000..61035499c7
--- /dev/null
+++ b/indra/newview/llchatmsgbox.h
@@ -0,0 +1,160 @@
+/**
+ * @file llchatmsgbox.h
+ * @brief chat history text box, able to show array of strings with separator
+ *
+ * $LicenseInfo:firstyear=2004&license=viewergpl$
+ *
+ * Copyright (c) 2004-2009, Linden Research, Inc.
+ *
+ * Second Life Viewer Source Code
+ * The source code in this file ("Source Code") is provided by Linden Lab
+ * to you under the terms of the GNU General Public License, version 2.0
+ * ("GPL"), unless you have obtained a separate licensing agreement
+ * ("Other License"), formally executed by you and Linden Lab. Terms of
+ * the GPL can be found in doc/GPL-license.txt in this distribution, or
+ * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
+ *
+ * There are special exceptions to the terms and conditions of the GPL as
+ * it is applied to this Source Code. View the full text of the exception
+ * in the file doc/FLOSS-exception.txt in this software distribution, or
+ * online at
+ * http://secondlifegrid.net/programs/open_source/licensing/flossexception
+ *
+ * By copying, modifying or distributing this software, you acknowledge
+ * that you have read and understood your obligations described above,
+ * and agree to abide by those obligations.
+ *
+ * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+ * COMPLETENESS OR PERFORMANCE.
+ * $/LicenseInfo$
+ */
+
+#ifndef LL_LLCHATMSGBOX_H
+#define LL_LLCHATMSGBOX_H
+
+
+#include "lluictrl.h"
+#include "v4color.h"
+#include "llstring.h"
+#include "lluistring.h"
+
+
+class LLChatMsgBox
+: public LLUICtrl
+{
+protected:
+ struct text_block
+ {
+ LLUIString text;
+ std::vector<S32> lines;
+ };
+public:
+ typedef boost::function<void (void)> callback_t;
+
+ struct Params : public LLInitParam::Block<Params, LLUICtrl::Params>
+ {
+ Optional<std::string> text;
+
+ Optional<bool> highlight_on_hover,
+ border_visible,
+ border_drop_shadow_visible,
+ bg_visible,
+ use_ellipses,
+ word_wrap;
+
+ Optional<LLFontGL::ShadowType> font_shadow;
+
+ Optional<LLUIColor> text_color,
+ hover_color,
+ disabled_color,
+ background_color,
+ border_color;
+
+ Optional<S32> line_spacing;
+
+ Optional<S32> block_spacing;
+
+ Params();
+ };
+protected:
+ LLChatMsgBox(const Params&);
+ friend class LLUICtrlFactory;
+public:
+ virtual void draw();
+ virtual void reshape(S32 width, S32 height, BOOL called_from_parent = TRUE);
+
+ virtual BOOL handleMouseDown(S32 x, S32 y, MASK mask);
+ virtual BOOL handleMouseUp(S32 x, S32 y, MASK mask);
+ virtual BOOL handleHover(S32 x, S32 y, MASK mask);
+
+ void setColor( const LLColor4& c ) { mTextColor = c; }
+ void setDisabledColor( const LLColor4& c) { mDisabledColor = c; }
+ void setBackgroundColor( const LLColor4& c) { mBackgroundColor = c; }
+ void setBorderColor( const LLColor4& c) { mBorderColor = c; }
+
+ void setHoverColor( const LLColor4& c ) { mHoverColor = c; }
+ void setHoverActive( BOOL active ) { mHoverActive = active; }
+
+ void setText( const LLStringExplicit& text );
+ void addText( const LLStringExplicit& text );
+
+ void setUseEllipses( BOOL use_ellipses ) { mUseEllipses = use_ellipses; }
+
+ void setBackgroundVisible(BOOL visible) { mBackgroundVisible = visible; }
+ void setBorderVisible(BOOL visible) { mBorderVisible = visible; }
+ void setBorderDropshadowVisible(BOOL visible){ mBorderDropShadowVisible = visible; }
+ void setRightAlign() { mHAlign = LLFontGL::RIGHT; }
+ void setHAlign( LLFontGL::HAlign align ) { mHAlign = align; }
+ void setClickedCallback( boost::function<void (void*)> cb, void* userdata = NULL ){ mClickedCallback = boost::bind(cb, userdata); } // mouse down and up within button
+
+ const LLFontGL* getFont() const { return mFontGL; }
+
+ S32 getTextPixelHeight();
+ S32 getTextLinesNum();
+
+ virtual void setValue(const LLSD& value );
+
+
+
+private:
+ std::string wrapText (const LLStringExplicit& in_text, F32 max_width = -1.0);
+
+ void setLineLengths (text_block& t);
+ void resetLineLengths ();
+ void drawText (S32 x, S32 y, const LLColor4& color );
+
+ const LLFontGL* mFontGL;
+ LLUIColor mTextColor;
+ LLUIColor mDisabledColor;
+ LLUIColor mBackgroundColor;
+ LLUIColor mBorderColor;
+ LLUIColor mHoverColor;
+
+ BOOL mHoverActive;
+ BOOL mHasHover;
+ BOOL mBackgroundVisible;
+ BOOL mBorderVisible;
+ BOOL mWordWrap;
+
+ U8 mFontStyle; // style bit flags for font
+ LLFontGL::ShadowType mShadowType;
+ BOOL mBorderDropShadowVisible;
+ BOOL mUseEllipses;
+
+ S32 mLineSpacing;
+ S32 mBlockSpasing;
+
+ LLFontGL::HAlign mHAlign;
+ LLFontGL::VAlign mVAlign;
+
+ callback_t mClickedCallback;
+
+
+ //same as mLineLengthList and mText in LLTextBox
+ std::vector< boost::shared_ptr<text_block> > mTextStrings;
+
+};
+
+#endif
+
diff --git a/indra/newview/llchiclet.cpp b/indra/newview/llchiclet.cpp
new file mode 100644
index 0000000000..6b4dfa73a4
--- /dev/null
+++ b/indra/newview/llchiclet.cpp
@@ -0,0 +1,1184 @@
+/**
+* @file llchiclet.cpp
+* @brief LLChiclet class implementation
+*
+* $LicenseInfo:firstyear=2002&license=viewergpl$
+*
+* Copyright (c) 2002-2009, Linden Research, Inc.
+*
+* Second Life Viewer Source Code
+* The source code in this file ("Source Code") is provided by Linden Lab
+* to you under the terms of the GNU General Public License, version 2.0
+* ("GPL"), unless you have obtained a separate licensing agreement
+* ("Other License"), formally executed by you and Linden Lab. Terms of
+* the GPL can be found in doc/GPL-license.txt in this distribution, or
+* online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
+*
+* There are special exceptions to the terms and conditions of the GPL as
+* it is applied to this Source Code. View the full text of the exception
+* in the file doc/FLOSS-exception.txt in this software distribution, or
+* online at
+* http://secondlifegrid.net/programs/open_source/licensing/flossexception
+*
+* By copying, modifying or distributing this software, you acknowledge
+* that you have read and understood your obligations described above,
+* and agree to abide by those obligations.
+*
+* ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+* COMPLETENESS OR PERFORMANCE.
+* $/LicenseInfo$
+*/
+
+#include "llviewerprecompiledheaders.h" // must be first include
+#include "llchiclet.h"
+#include "llagent.h"
+#include "llavataractions.h"
+#include "llbottomtray.h"
+#include "llgroupactions.h"
+#include "lliconctrl.h"
+#include "llimpanel.h" // LLFloaterIMPanel
+#include "llimview.h"
+#include "llfloaterreg.h"
+#include "llmenugl.h"
+#include "lloutputmonitorctrl.h"
+#include "lltextbox.h"
+#include "llvoiceclient.h"
+#include "llvoicecontrolpanel.h"
+#include "llgroupmgr.h"
+
+static const std::string P2P_MENU_NAME = "IMChiclet P2P Menu";
+static const std::string GROUP_MENU_NAME = "IMChiclet Group Menu";
+
+static LLDefaultChildRegistry::Register<LLChicletPanel> t1("chiclet_panel");
+static LLDefaultChildRegistry::Register<LLTalkButton> t2("chiclet_talk");
+static LLDefaultChildRegistry::Register<LLNotificationChiclet> t3("chiclet_notification");
+static LLDefaultChildRegistry::Register<LLIMChiclet> t4("chiclet_im");
+
+S32 LLNotificationChiclet::mUreadSystemNotifications = 0;
+S32 LLNotificationChiclet::mUreadIMNotifications = 0;
+
+
+boost::signals2::signal<LLChiclet* (const LLUUID&),
+ LLIMChiclet::CollectChicletCombiner<std::list<LLChiclet*> > >
+ LLIMChiclet::sFindChicletsSignal;
+//////////////////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////////////////
+
+LLNotificationChiclet::Params::Params()
+: button("button")
+, unread_notifications("unread_notifications")
+{
+ button.name("button");
+ button.tab_stop(FALSE);
+ button.label(LLStringUtil::null);
+
+ unread_notifications.name("unread");
+ unread_notifications.font(LLFontGL::getFontSansSerif());
+ unread_notifications.text_color=(LLColor4::white);
+ unread_notifications.font_halign(LLFontGL::HCENTER);
+ unread_notifications.mouse_opaque(FALSE);
+}
+
+LLNotificationChiclet::LLNotificationChiclet(const Params& p)
+: LLChiclet(p)
+, mButton(NULL)
+, mCounterCtrl(NULL)
+, mNotificationChicletWindow(NULL)
+{
+ LLButton::Params button_params = p.button;
+ button_params.rect(p.rect());
+ mButton = LLUICtrlFactory::create<LLButton>(button_params);
+ addChild(mButton);
+
+ LLChicletNotificationCounterCtrl::Params unread_params = p.unread_notifications;
+ mCounterCtrl = LLUICtrlFactory::create<LLChicletNotificationCounterCtrl>(unread_params);
+ addChild(mCounterCtrl);
+}
+
+LLNotificationChiclet::~LLNotificationChiclet()
+{
+
+}
+
+void LLNotificationChiclet::setCounter(S32 counter)
+{
+ mCounterCtrl->setCounter(counter);
+}
+
+void LLNotificationChiclet::setShowCounter(bool show)
+{
+ LLChiclet::setShowCounter(show);
+ mCounterCtrl->setVisible(getShowCounter());
+}
+
+boost::signals2::connection LLNotificationChiclet::setClickCallback(
+ const commit_callback_t& cb)
+{
+ return mButton->setClickedCallback(cb);
+}
+
+void LLNotificationChiclet::updateUreadIMNotifications()
+{
+ mUreadIMNotifications = gIMMgr->getNumberOfUnreadIM();
+ setCounter(mUreadSystemNotifications + mUreadIMNotifications);
+}
+
+//////////////////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////////////////
+
+LLChiclet::Params::Params()
+ : show_counter("show_counter")
+{
+ show_counter = true;
+}
+
+LLChiclet::LLChiclet(const Params& p)
+: LLUICtrl(p)
+, mSessionId(LLUUID::null)
+, mShowCounter(p.show_counter)
+{
+
+}
+
+LLChiclet::~LLChiclet()
+{
+
+}
+
+boost::signals2::connection LLChiclet::setLeftButtonClickCallback(
+ const commit_callback_t& cb)
+{
+ return mCommitSignal.connect(cb);
+}
+
+BOOL LLChiclet::handleMouseDown(S32 x, S32 y, MASK mask)
+{
+ onCommit();
+ childrenHandleMouseDown(x,y,mask);
+ return TRUE;
+}
+
+boost::signals2::connection LLChiclet::setChicletSizeChangedCallback(
+ const chiclet_size_changed_callback_t& cb)
+{
+ return mChicletSizeChangedSignal.connect(cb);
+}
+
+void LLChiclet::onChicletSizeChanged()
+{
+ mChicletSizeChangedSignal(this, getValue());
+}
+
+LLSD LLChiclet::getValue() const
+{
+ return LLSD(getSessionId());
+}
+
+void LLChiclet::setValue(const LLSD& value)
+{
+ if(value.isUUID())
+ setSessionId(value.asUUID());
+}
+
+//////////////////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////////////////
+
+LLIMChiclet::Params::Params()
+: avatar_icon("avatar_icon")
+, group_insignia("group_insignia")
+, unread_notifications("unread_notifications")
+, speaker("speaker")
+, show_speaker("show_speaker")
+{
+ rect(LLRect(0, 25, 45, 0));
+
+ avatar_icon.name("avatar_icon");
+ avatar_icon.visible(false);
+ avatar_icon.rect(LLRect(0, 25, 25, 0));
+
+ //it's an icon for a group in case there is a group chat created
+ group_insignia.name("group_icon");
+ group_insignia.visible(false);
+ group_insignia.rect(LLRect(0, 25, 25, 0));
+
+ unread_notifications.name("unread");
+ unread_notifications.rect(LLRect(25, 25, 45, 0));
+ unread_notifications.font(LLFontGL::getFontSansSerif());
+ unread_notifications.font_halign(LLFontGL::HCENTER);
+ unread_notifications.v_pad(5);
+ unread_notifications.text_color(LLColor4::white);
+
+ speaker.name("speaker");
+ speaker.rect(LLRect(45, 25, 65, 0));
+
+ show_speaker = false;
+}
+
+LLIMChiclet::LLIMChiclet(const Params& p)
+: LLChiclet(p)
+, LLGroupMgrObserver(LLUUID())
+, mAvatarCtrl(NULL)
+, mGroupInsignia(NULL)
+, mCounterCtrl(NULL)
+, mSpeakerCtrl(NULL)
+, mShowSpeaker(p.show_speaker)
+, mPopupMenu(NULL)
+{
+ LLChicletAvatarIconCtrl::Params avatar_params = p.avatar_icon;
+ mAvatarCtrl = LLUICtrlFactory::create<LLChicletAvatarIconCtrl>(avatar_params);
+ addChild(mAvatarCtrl);
+
+ //Before setOtherParticipantId() we are UNAWARE which dialog type will it be
+ //so keeping both icons for all both p2p and group chat cases
+ LLIconCtrl::Params grop_icon_params = p.group_insignia;
+ mGroupInsignia = LLUICtrlFactory::create<LLIconCtrl>(grop_icon_params);
+ addChild(mGroupInsignia);
+
+ LLChicletNotificationCounterCtrl::Params unread_params = p.unread_notifications;
+ mCounterCtrl = LLUICtrlFactory::create<LLChicletNotificationCounterCtrl>(unread_params);
+ addChild(mCounterCtrl);
+
+ setCounter(getCounter());
+ setShowCounter(getShowCounter());
+
+ LLChicletSpeakerCtrl::Params speaker_params = p.speaker;
+ mSpeakerCtrl = LLUICtrlFactory::create<LLChicletSpeakerCtrl>(speaker_params);
+ addChild(mSpeakerCtrl);
+
+ setShowSpeaker(getShowSpeaker());
+}
+
+LLIMChiclet::~LLIMChiclet()
+{
+ LLGroupMgr::getInstance()->removeObserver(this);
+}
+
+
+void LLIMChiclet::setCounter(S32 counter)
+{
+ mCounterCtrl->setCounter(counter);
+
+ if(getShowCounter())
+ {
+ LLRect counter_rect = mCounterCtrl->getRect();
+ LLRect required_rect = mCounterCtrl->getRequiredRect();
+ bool needs_resize = required_rect.getWidth() != counter_rect.getWidth();
+
+ if(needs_resize)
+ {
+ counter_rect.mRight = counter_rect.mLeft + required_rect.getWidth();
+ mCounterCtrl->reshape(counter_rect.getWidth(), counter_rect.getHeight());
+ mCounterCtrl->setRect(counter_rect);
+
+ onChicletSizeChanged();
+ }
+ }
+}
+
+void LLIMChiclet::onMouseDown()
+{
+ LLIMFloater::toggle(getSessionId());
+ setCounter(0);
+}
+
+LLRect LLIMChiclet::getRequiredRect()
+{
+ LLRect rect(0, 0, mAvatarCtrl->getRect().getWidth(), 0);
+ if(getShowCounter())
+ {
+ rect.mRight += mCounterCtrl->getRequiredRect().getWidth();
+ }
+ if(getShowSpeaker())
+ {
+ rect.mRight += mSpeakerCtrl->getRect().getWidth();
+ }
+ return rect;
+}
+
+void LLIMChiclet::setShowCounter(bool show)
+{
+ bool needs_resize = getShowCounter() != show;
+
+ LLChiclet::setShowCounter(show);
+ mCounterCtrl->setVisible(getShowCounter());
+
+ if(needs_resize)
+ {
+ onChicletSizeChanged();
+ }
+}
+
+
+void LLIMChiclet::setSessionId(const LLUUID& session_id)
+{
+ LLChiclet::setSessionId(session_id);
+
+ //for a group chat session_id = group_id
+ LLFloaterIMPanel* im = LLIMMgr::getInstance()->findFloaterBySession(session_id);
+ if (!im) return; //should never happen
+
+ EInstantMessage type = im->getDialogType();
+ if (type == IM_SESSION_INVITE || type == IM_SESSION_GROUP_START)
+ {
+ if (!gAgent.isInGroup(session_id)) return;
+
+ if (mGroupInsignia) {
+ LLGroupMgr* grp_mgr = LLGroupMgr::getInstance();
+ LLGroupMgrGroupData* group_data = grp_mgr->getGroupData(session_id);
+ if (group_data && group_data->mInsigniaID.notNull())
+ {
+ mGroupInsignia->setVisible(TRUE);
+ mGroupInsignia->setValue(group_data->mInsigniaID);
+ }
+ else
+ {
+ mID = session_id; //needed for LLGroupMgrObserver
+ grp_mgr->addObserver(this);
+ grp_mgr->sendGroupPropertiesRequest(session_id);
+ }
+ }
+ }
+}
+
+void LLIMChiclet::setIMSessionName(const std::string& name)
+{
+ setToolTip(name);
+}
+
+//session id should be set before calling this
+void LLIMChiclet::setOtherParticipantId(const LLUUID& other_participant_id)
+{
+ llassert(getSessionId().notNull());
+
+ LLFloaterIMPanel*floater = gIMMgr->findFloaterBySession(getSessionId());
+
+ //all alive sessions have alive floater, haven't they?
+ llassert(floater);
+
+ mOtherParticipantId = other_participant_id;
+
+ if (mAvatarCtrl && floater->getDialogType() == IM_NOTHING_SPECIAL)
+ {
+ mAvatarCtrl->setVisible(TRUE);
+ mAvatarCtrl->setValue(other_participant_id);
+ }
+}
+
+
+void LLIMChiclet::changed(LLGroupChange gc)
+{
+ LLSD group_insignia = mGroupInsignia->getValue();
+ if (group_insignia.isUUID() && group_insignia.asUUID().notNull()) return;
+
+ if (GC_PROPERTIES == gc)
+ {
+ LLGroupMgrGroupData* group_data = LLGroupMgr::getInstance()->getGroupData(getSessionId());
+ if (group_data && group_data->mInsigniaID.notNull())
+ {
+ mGroupInsignia->setVisible(TRUE);
+ mGroupInsignia->setValue(group_data->mInsigniaID);
+ }
+ }
+}
+
+LLUUID LLIMChiclet::getOtherParticipantId()
+{
+ return mOtherParticipantId;
+}
+
+void LLIMChiclet::updateMenuItems()
+{
+ if(!mPopupMenu)
+ return;
+ if(getSessionId().isNull())
+ return;
+
+ if(P2P_MENU_NAME == mPopupMenu->getName())
+ {
+ bool is_friend = LLAvatarActions::isFriend(getOtherParticipantId());
+
+ mPopupMenu->getChild<LLUICtrl>("Add Friend")->setEnabled(!is_friend);
+ mPopupMenu->getChild<LLUICtrl>("Remove Friend")->setEnabled(is_friend);
+ }
+}
+
+BOOL LLIMChiclet::handleMouseDown(S32 x, S32 y, MASK mask)
+{
+ onMouseDown();
+ return LLChiclet::handleMouseDown(x, y, mask);
+}
+
+void LLIMChiclet::setShowSpeaker(bool show)
+{
+ bool needs_resize = getShowSpeaker() != show;
+
+ mShowSpeaker = show;
+ mSpeakerCtrl->setVisible(getShowSpeaker());
+
+ if(needs_resize)
+ {
+ onChicletSizeChanged();
+ }
+}
+
+void LLIMChiclet::draw()
+{
+ LLUICtrl::draw();
+
+ //if we have a docked floater, we want to position it relative to us
+ LLIMFloater* im_floater = LLFloaterReg::findTypedInstance<LLIMFloater>("impanel", getSessionId());
+
+ if (im_floater && im_floater->isDocked())
+ {
+ S32 x, y;
+ getParent()->localPointToScreen(getRect().getCenterX(), 0, &x, &y);
+ im_floater->translate(x - im_floater->getRect().getCenterX(), 10 - im_floater->getRect().mBottom);
+ //set this so the docked floater knows it's been positioned and can now draw
+ im_floater->setPositioned(true);
+ }
+
+ gl_rect_2d(0, getRect().getHeight(), getRect().getWidth(), 0, LLColor4(0.0f,0.0f,0.0f,1.f), FALSE);
+}
+
+BOOL LLIMChiclet::handleRightMouseDown(S32 x, S32 y, MASK mask)
+{
+ if(!mPopupMenu)
+ createPopupMenu();
+
+ updateMenuItems();
+
+ if (mPopupMenu)
+ {
+ mPopupMenu->arrangeAndClear();
+ }
+
+ LLMenuGL::showPopup(this, mPopupMenu, x, y);
+
+ return TRUE;
+}
+
+void LLIMChiclet::createPopupMenu()
+{
+ if(mPopupMenu)
+ {
+ llwarns << "Menu already exists" << llendl;
+ return;
+ }
+ if(getSessionId().isNull())
+ return;
+
+ LLFloaterIMPanel*floater = gIMMgr->findFloaterBySession(getSessionId());
+ if(!floater)
+ return;
+
+ LLUICtrl::CommitCallbackRegistry::ScopedRegistrar registrar;
+ registrar.add("IMChicletMenu.Action", boost::bind(&LLIMChiclet::onMenuItemClicked, this, _2));
+
+ switch(floater->getDialogType())
+ {
+ case IM_SESSION_GROUP_START:
+ mPopupMenu = LLUICtrlFactory::getInstance()->createFromFile<LLMenuGL>
+ ("menu_imchiclet_group.xml", gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance());
+ break;
+ case IM_NOTHING_SPECIAL:
+ mPopupMenu = LLUICtrlFactory::getInstance()->createFromFile<LLMenuGL>
+ ("menu_imchiclet_p2p.xml", gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance());
+ break;
+ default:
+ llwarns << "Unexpected dialog type" << llendl;
+ break;
+ }
+}
+
+void LLIMChiclet::onMenuItemClicked(const LLSD& user_data)
+{
+ std::string level = user_data.asString();
+ LLUUID other_participant_id = getOtherParticipantId();
+
+ if("profile" == level)
+ {
+ LLAvatarActions::showProfile(other_participant_id);
+ }
+ else if("im" == level)
+ {
+ LLAvatarActions::startIM(other_participant_id);
+ }
+ else if("add" == level)
+ {
+ LLAvatarActions::requestFriendshipDialog(other_participant_id);
+ }
+ else if("group chat" == level)
+ {
+ LLGroupActions::startChat(other_participant_id);
+ }
+ else if("info" == level)
+ {
+ LLGroupActions::show(other_participant_id);
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////////////////
+
+LLChicletPanel::Params::Params()
+: chiclet_padding("chiclet_padding")
+, scrolling_offset("scrolling_offset")
+, left_scroll_button("left_scroll_button")
+, right_scroll_button("right_scroll_button")
+, min_width("min_width")
+{
+ chiclet_padding = 3;
+ scrolling_offset = 40;
+ min_width = 70;
+
+ LLRect scroll_button_rect(0, 25, 19, 5);
+
+ left_scroll_button.name("left_scroll");
+ left_scroll_button.label(LLStringUtil::null);
+ left_scroll_button.rect(scroll_button_rect);
+ left_scroll_button.tab_stop(false);
+ left_scroll_button.image_selected(LLUI::getUIImage("bottom_tray_scroll_left.tga"));
+ left_scroll_button.image_unselected(LLUI::getUIImage("bottom_tray_scroll_left.tga"));
+ left_scroll_button.image_hover_selected(LLUI::getUIImage("bottom_tray_scroll_left.tga"));
+
+ right_scroll_button.name("right_scroll");
+ right_scroll_button.label(LLStringUtil::null);
+ right_scroll_button.rect(scroll_button_rect);
+ right_scroll_button.tab_stop(false);
+ right_scroll_button.image_selected(LLUI::getUIImage("bottom_tray_scroll_right.tga"));
+ right_scroll_button.image_unselected(LLUI::getUIImage("bottom_tray_scroll_right.tga"));
+ right_scroll_button.image_hover_selected(LLUI::getUIImage("bottom_tray_scroll_right.tga"));
+};
+
+LLChicletPanel::LLChicletPanel(const Params&p)
+: LLPanel(p)
+, mScrollArea(NULL)
+, mLeftScrollButton(NULL)
+, mRightScrollButton(NULL)
+, mChicletPadding(p.chiclet_padding)
+, mScrollingOffset(p.scrolling_offset)
+, mMinWidth(p.min_width)
+, mShowControls(true)
+{
+ LLButton::Params scroll_button_params = p.left_scroll_button;
+
+ mLeftScrollButton = LLUICtrlFactory::create<LLButton>(scroll_button_params);
+ addChild(mLeftScrollButton);
+
+ mLeftScrollButton->setClickedCallback(boost::bind(&LLChicletPanel::onLeftScrollClick,this));
+ mLeftScrollButton->setEnabled(false);
+
+ scroll_button_params = p.right_scroll_button;
+ mRightScrollButton = LLUICtrlFactory::create<LLButton>(scroll_button_params);
+ addChild(mRightScrollButton);
+
+ mRightScrollButton->setClickedCallback(boost::bind(&LLChicletPanel::onRightScrollClick,this));
+ mRightScrollButton->setEnabled(false);
+
+ LLPanel::Params panel_params;
+ mScrollArea = LLUICtrlFactory::create<LLPanel>(panel_params,this);
+ addChild(mScrollArea);
+}
+
+LLChicletPanel::~LLChicletPanel()
+{
+
+}
+
+void im_chiclet_callback(LLChicletPanel* panel, const LLSD& data){
+
+ LLUUID session_id = data["session_id"].asUUID();
+ std::list<LLChiclet*> chiclets = LLIMChiclet::sFindChicletsSignal(session_id);
+ std::list<LLChiclet *>::iterator iter;
+ for (iter = chiclets.begin(); iter != chiclets.end(); iter++) {
+ LLChiclet* chiclet = *iter;
+ if (chiclet != NULL)
+ {
+ chiclet->setCounter(data["num_unread"].asInteger());
+ }
+ else
+ {
+ llwarns << "Unable to set counter for chiclet " << session_id << llendl;
+ }
+ }
+
+}
+
+
+BOOL LLChicletPanel::postBuild()
+{
+ LLPanel::postBuild();
+ LLIMModel::instance().addChangedCallback(boost::bind(im_chiclet_callback, this, _1));
+ LLIMChiclet::sFindChicletsSignal.connect(boost::bind(&LLChicletPanel::findChiclet<LLChiclet>, this, _1));
+
+ return TRUE;
+}
+
+bool LLChicletPanel::addChiclet(LLChiclet* chiclet, S32 index)
+{
+ if(mScrollArea->addChild(chiclet))
+ {
+ S32 offset = 0;
+ // Do not scroll chiclets if chiclets are scrolled right and new
+ // chiclet is added to the beginning of the list
+ if(canScrollLeft())
+ {
+ offset = - (chiclet->getRequiredRect().getWidth() + getChicletPadding());
+ if(0 == index)
+ {
+ offset += getChiclet(0)->getRect().mLeft;
+ }
+ }
+
+ mChicletList.insert(mChicletList.begin() + index, chiclet);
+
+ getChiclet(0)->translate(offset, 0);
+
+ chiclet->setLeftButtonClickCallback(boost::bind(&LLChicletPanel::onChicletClick, this, _1, _2));
+ chiclet->setChicletSizeChangedCallback(boost::bind(&LLChicletPanel::onChicletSizeChanged, this, _1, index));
+
+ arrange();
+ showScrollButtonsIfNeeded();
+
+ return true;
+ }
+
+ return false;
+}
+
+void LLChicletPanel::onChicletSizeChanged(LLChiclet* ctrl, const LLSD& param)
+{
+ S32 chiclet_width = ctrl->getRect().getWidth();
+ S32 chiclet_new_width = ctrl->getRequiredRect().getWidth();
+
+ if(chiclet_new_width == chiclet_width)
+ {
+ return;
+ }
+
+ LLRect chiclet_rect = ctrl->getRect();
+ chiclet_rect.mRight = chiclet_rect.mLeft + chiclet_new_width;
+
+ ctrl->setRect(chiclet_rect);
+
+ S32 offset = chiclet_new_width - chiclet_width;
+ S32 index = getChicletIndex(ctrl);
+
+ shiftChiclets(offset, index + 1);
+ trimChiclets();
+ showScrollButtonsIfNeeded();
+}
+
+void LLChicletPanel::onChicletClick(LLUICtrl*ctrl,const LLSD&param)
+{
+ mCommitSignal(ctrl,param);
+}
+
+void LLChicletPanel::removeChiclet(chiclet_list_t::iterator it)
+{
+ mScrollArea->removeChild(*it);
+ mChicletList.erase(it);
+
+ arrange();
+ trimChiclets();
+ showScrollButtonsIfNeeded();
+}
+
+void LLChicletPanel::removeChiclet(S32 index)
+{
+ if(index >= 0 && index < getChicletCount())
+ {
+ removeChiclet(mChicletList.begin() + index);
+ }
+}
+
+S32 LLChicletPanel::getChicletIndex(const LLChiclet* chiclet)
+{
+ if(mChicletList.empty())
+ return -1;
+
+ S32 size = getChicletCount();
+ for(int n = 0; n < size; ++n)
+ {
+ if(chiclet == mChicletList[n])
+ return n;
+ }
+
+ return -1;
+}
+
+void LLChicletPanel::removeChiclet(LLChiclet*chiclet)
+{
+ chiclet_list_t::iterator it = mChicletList.begin();
+ for( ; mChicletList.end() != it; ++it)
+ {
+ LLChiclet* temp = *it;
+ if(temp == chiclet)
+ {
+ removeChiclet(it);
+ return;
+ }
+ }
+}
+
+void LLChicletPanel::removeChiclet(const LLUUID& im_session_id)
+{
+ chiclet_list_t::iterator it = mChicletList.begin();
+ for( ; mChicletList.end() != it; ++it)
+ {
+ LLIMChiclet* chiclet = dynamic_cast<LLIMChiclet*>(*it);
+
+ if(chiclet->getSessionId() == im_session_id)
+ {
+ removeChiclet(it);
+ return;
+ }
+ }
+}
+
+void LLChicletPanel::removeAll()
+{
+ S32 size = getChicletCount();
+ for(S32 n = 0; n < size; ++n)
+ {
+ mScrollArea->removeChild(mChicletList[n]);
+ }
+
+ mChicletList.erase(mChicletList.begin(), mChicletList.end());
+
+ showScrollButtonsIfNeeded();
+}
+
+void LLChicletPanel::reshape(S32 width, S32 height, BOOL called_from_parent )
+{
+ LLPanel::reshape(width,height,called_from_parent);
+
+ static const S32 SCROLL_BUTTON_PAD = 5;
+
+ LLRect scroll_button_rect = mLeftScrollButton->getRect();
+ mLeftScrollButton->setRect(LLRect(0,height,scroll_button_rect.getWidth(),
+ height - scroll_button_rect.getHeight()));
+
+ scroll_button_rect = mRightScrollButton->getRect();
+ mRightScrollButton->setRect(LLRect(width - scroll_button_rect.getWidth(),height,
+ width, height - scroll_button_rect.getHeight()));
+
+ mScrollArea->setRect(LLRect(scroll_button_rect.getWidth() + SCROLL_BUTTON_PAD,
+ height + 7, width - scroll_button_rect.getWidth() - SCROLL_BUTTON_PAD, 0));
+
+ mShowControls = width > mMinWidth;
+ mScrollArea->setVisible(mShowControls);
+
+ trimChiclets();
+
+ showScrollButtonsIfNeeded();
+}
+
+void LLChicletPanel::arrange()
+{
+ if(mChicletList.empty())
+ return;
+
+ S32 chiclet_left = getChiclet(0)->getRect().mLeft;
+
+ S32 size = getChicletCount();
+ for( int n = 0; n < size; ++n)
+ {
+ LLChiclet* chiclet = getChiclet(n);
+
+ S32 chiclet_width = chiclet->getRequiredRect().getWidth();
+ LLRect rect = chiclet->getRect();
+ rect.set(chiclet_left, rect.mTop, chiclet_left + chiclet_width, rect.mBottom);
+
+ chiclet->setRect(rect);
+
+ chiclet_left += chiclet_width + getChicletPadding();
+ }
+}
+
+void LLChicletPanel::trimChiclets()
+{
+ // trim right
+ if(canScrollLeft() && !canScrollRight())
+ {
+ S32 last_chiclet_right = (*mChicletList.rbegin())->getRect().mRight;
+ S32 scroll_width = mScrollArea->getRect().getWidth();
+ if(last_chiclet_right < scroll_width)
+ {
+ shiftChiclets(scroll_width - last_chiclet_right);
+ }
+ }
+
+ // trim left
+ if(!mChicletList.empty())
+ {
+ LLRect first_chiclet_rect = getChiclet(0)->getRect();
+ if(first_chiclet_rect.mLeft > 0)
+ {
+ shiftChiclets( - first_chiclet_rect.mLeft);
+ }
+ }
+}
+
+void LLChicletPanel::showScrollButtonsIfNeeded()
+{
+ bool can_scroll_left = canScrollLeft();
+ bool can_scroll_right = canScrollRight();
+
+ mLeftScrollButton->setEnabled(can_scroll_left);
+ mRightScrollButton->setEnabled(can_scroll_right);
+
+ bool show_scroll_buttons = (can_scroll_left || can_scroll_right) && mShowControls;
+
+ mLeftScrollButton->setVisible(show_scroll_buttons);
+ mRightScrollButton->setVisible(show_scroll_buttons);
+}
+
+void LLChicletPanel::draw()
+{
+ child_list_const_iter_t it = getChildList()->begin();
+ for( ; getChildList()->end() != it; ++it)
+ {
+ LLView* child = *it;
+ if(child == dynamic_cast<LLView*>(mScrollArea))
+ {
+ LLLocalClipRect clip(mScrollArea->getRect());
+ drawChild(mScrollArea);
+ }
+ else
+ {
+ drawChild(child);
+ }
+ }
+}
+
+bool LLChicletPanel::canScrollRight()
+{
+ if(mChicletList.empty())
+ return false;
+
+ S32 scroll_width = mScrollArea->getRect().getWidth();
+ S32 last_chiclet_right = (*mChicletList.rbegin())->getRect().mRight;
+
+ if(last_chiclet_right > scroll_width)
+ return true;
+
+ return false;
+}
+
+bool LLChicletPanel::canScrollLeft()
+{
+ if(mChicletList.empty())
+ return false;
+
+ return getChiclet(0)->getRect().mLeft < 0;
+}
+
+void LLChicletPanel::scroll(S32 offset)
+{
+ shiftChiclets(offset);
+}
+
+void LLChicletPanel::shiftChiclets(S32 offset, S32 start_index /* = 0 */)
+{
+ if(start_index < 0 || start_index >= getChicletCount())
+ {
+ return;
+ }
+
+ chiclet_list_t::const_iterator it = mChicletList.begin() + start_index;
+ for(;mChicletList.end() != it; ++it)
+ {
+ LLChiclet* chiclet = *it;
+ chiclet->translate(offset,0);
+ }
+}
+
+void LLChicletPanel::scrollLeft()
+{
+ if(canScrollLeft())
+ {
+ S32 offset = getScrollingOffset();
+ LLRect first_chiclet_rect = getChiclet(0)->getRect();
+
+ // shift chiclets in case first chiclet is partially visible
+ if(first_chiclet_rect.mLeft < 0 && first_chiclet_rect.mRight > 0)
+ {
+ offset = llabs(first_chiclet_rect.mLeft);
+ }
+
+ scroll(offset);
+
+ showScrollButtonsIfNeeded();
+ }
+}
+
+void LLChicletPanel::scrollRight()
+{
+ if(canScrollRight())
+ {
+ S32 offset = - getScrollingOffset();
+
+ S32 last_chiclet_right = (*mChicletList.rbegin())->getRect().mRight;
+ S32 scroll_rect_width = mScrollArea->getRect().getWidth();
+ // if after scrolling, the last chiclet will not be aligned to
+ // scroll area right side - align it.
+ if( last_chiclet_right + offset < scroll_rect_width )
+ {
+ offset = scroll_rect_width - last_chiclet_right;
+ }
+
+ scroll(offset);
+
+ showScrollButtonsIfNeeded();
+ }
+}
+
+void LLChicletPanel::onLeftScrollClick()
+{
+ scrollLeft();
+}
+
+void LLChicletPanel::onRightScrollClick()
+{
+ scrollRight();
+}
+
+boost::signals2::connection LLChicletPanel::setChicletClickedCallback(
+ const commit_callback_t& cb)
+{
+ return mCommitSignal.connect(cb);
+}
+
+BOOL LLChicletPanel::handleScrollWheel(S32 x, S32 y, S32 clicks)
+{
+ if(clicks > 0)
+ {
+ scrollRight();
+ }
+ else
+ {
+ scrollLeft();
+ }
+ return TRUE;
+}
+
+//////////////////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////////////////
+
+LLTalkButton::Params::Params()
+ : speak_button("speak_button")
+ , show_button("show_button")
+ , monitor("monitor")
+{
+ speak_button.name("left");
+ speak_button.label("Speak");
+ speak_button.label_selected("Speak");
+ speak_button.font(LLFontGL::getFontSansSerifSmall());
+ speak_button.tab_stop(false);
+ speak_button.is_toggle(true);
+ speak_button.picture_style(true);
+ speak_button.image_selected(LLUI::getUIImage("SegmentedBtn_Left_Selected"));
+ speak_button.image_unselected(LLUI::getUIImage("SegmentedBtn_Left_Off"));
+
+ show_button.name("right");
+ show_button.label(LLStringUtil::null);
+ show_button.rect(LLRect(0, 0, 20, 0));
+ show_button.tab_stop(false);
+ show_button.is_toggle(true);
+ show_button.picture_style(true);
+ show_button.image_selected(LLUI::getUIImage("ComboButton_Selected"));
+ show_button.image_unselected(LLUI::getUIImage("ComboButton_Off"));
+
+ monitor.name("monitor");
+ // *TODO: Make this data driven.
+ monitor.rect(LLRect(0, 18, 18, 0));
+}
+
+LLTalkButton::LLTalkButton(const Params& p)
+: LLUICtrl(p)
+, mPrivateCallPanel(NULL)
+, mOutputMonitor(NULL)
+, mSpeakBtn(NULL)
+, mShowBtn(NULL)
+{
+ LLRect rect = p.rect();
+ LLRect speak_rect(0, rect.getHeight(), rect.getWidth(), 0);
+ LLRect show_rect = p.show_button.rect();
+ show_rect.set(0, rect.getHeight(), show_rect.getWidth(), 0);
+
+ speak_rect.mRight -= show_rect.getWidth();
+ show_rect.mLeft = speak_rect.getWidth();
+ show_rect.mRight = rect.getWidth();
+
+ LLButton::Params speak_params = p.speak_button;
+ speak_params.rect(speak_rect);
+ mSpeakBtn = LLUICtrlFactory::create<LLButton>(speak_params);
+ addChild(mSpeakBtn);
+
+ mSpeakBtn->setClickedCallback(boost::bind(&LLTalkButton::onClick_SpeakBtn, this));
+ mSpeakBtn->setToggleState(FALSE);
+
+ LLButton::Params show_params = p.show_button;
+ show_params.rect(show_rect);
+ mShowBtn = LLUICtrlFactory::create<LLButton>(show_params);
+ addChild(mShowBtn);
+
+ mShowBtn->setClickedCallback(boost::bind(&LLTalkButton::onClick_ShowBtn, this));
+ mShowBtn->setToggleState(FALSE);
+
+ static const S32 MONITOR_RIGHT_PAD = 2;
+
+ LLRect monitor_rect = p.monitor.rect();
+ S32 monitor_height = monitor_rect.getHeight();
+ monitor_rect.mLeft = speak_rect.getWidth() - monitor_rect.getWidth() - MONITOR_RIGHT_PAD;
+ monitor_rect.mRight = speak_rect.getWidth() - MONITOR_RIGHT_PAD;
+ monitor_rect.mBottom = (rect.getHeight() / 2) - (monitor_height / 2);
+ monitor_rect.mTop = monitor_rect.mBottom + monitor_height;
+
+ LLOutputMonitorCtrl::Params monitor_params = p.monitor;
+ monitor_params.draw_border(false);
+ monitor_params.rect(monitor_rect);
+ mOutputMonitor = LLUICtrlFactory::create<LLOutputMonitorCtrl>(monitor_params);
+ mSpeakBtn->addChild(mOutputMonitor);
+
+ // never show "muted" because you can't mute yourself
+ mOutputMonitor->setIsMuted(false);
+}
+
+LLTalkButton::~LLTalkButton()
+{
+}
+
+void LLTalkButton::draw()
+{
+ // Always provide speaking feedback. User can trigger speaking
+ // with keyboard or middle-mouse shortcut.
+ mOutputMonitor->setPower(gVoiceClient->getCurrentPower(gAgent.getID()));
+ mOutputMonitor->setIsTalking( gVoiceClient->getUserPTTState() );
+ mSpeakBtn->setToggleState( gVoiceClient->getUserPTTState() );
+
+ LLUICtrl::draw();
+}
+
+void LLTalkButton::setSpeakBtnToggleState(bool state)
+{
+ mSpeakBtn->setToggleState(state);
+}
+
+void LLTalkButton::onClick_SpeakBtn()
+{
+ bool speaking = mSpeakBtn->getToggleState();
+ gVoiceClient->setUserPTTState(speaking);
+}
+
+void LLTalkButton::onClick_ShowBtn()
+{
+ if(!mShowBtn->getToggleState())
+ {
+ mPrivateCallPanel->onClickClose(mPrivateCallPanel);
+ delete mPrivateCallPanel;
+ mPrivateCallPanel = NULL;
+ mShowBtn->setToggleState(FALSE);
+ return;
+ }
+
+ S32 x = mSpeakBtn->getRect().mLeft;
+ S32 y = 0;
+
+ localPointToScreen(x, y, &x, &y);
+
+ mPrivateCallPanel = new LLVoiceControlPanel;
+ getRootView()->addChild(mPrivateCallPanel);
+
+ y = LLBottomTray::getInstance()->getRect().getHeight() + mPrivateCallPanel->getRect().getHeight();
+
+ LLRect rect;
+ rect.setLeftTopAndSize(x, y, mPrivateCallPanel->getRect().getWidth(), mPrivateCallPanel->getRect().getHeight());
+ mPrivateCallPanel->setRect(rect);
+
+ LLAvatarListItem::Params p;
+ p.buttons.status = true;
+ p.buttons.info = true;
+ p.buttons.profile = false;
+ p.buttons.locator = true;
+
+ mPrivateCallPanel->addItem(new LLAvatarListItem(p));
+ mPrivateCallPanel->setVisible(TRUE);
+ mPrivateCallPanel->setFrontmost(TRUE);
+
+ mShowBtn->setToggleState(TRUE);
+}
+
+//////////////////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////////////////
+
+LLChicletNotificationCounterCtrl::LLChicletNotificationCounterCtrl(const Params& p)
+ : LLTextBox(p)
+ , mCounter(0)
+ , mInitialWidth(0)
+{
+ mInitialWidth = getRect().getWidth();
+}
+
+void LLChicletNotificationCounterCtrl::setCounter(S32 counter)
+{
+ mCounter = counter;
+
+ std::stringstream stream;
+ stream << getCounter();
+ if(mCounter != 0)
+ {
+ setText(stream.str());
+ }
+ else
+ {
+ setText(std::string(""));
+ }
+}
+
+LLRect LLChicletNotificationCounterCtrl::getRequiredRect()
+{
+ LLRect rc;
+ S32 text_width = getFont()->getWidth(getText());
+
+ rc.mRight = rc.mLeft + llmax(text_width, mInitialWidth);
+
+ return rc;
+}
+
+void LLChicletNotificationCounterCtrl::setValue(const LLSD& value)
+{
+ if(value.isInteger())
+ setCounter(value.asInteger());
+}
+
+LLSD LLChicletNotificationCounterCtrl::getValue() const
+{
+ return LLSD(getCounter());
+}
+
+//////////////////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////////////////
+
+LLChicletAvatarIconCtrl::LLChicletAvatarIconCtrl(const Params& p)
+ : LLAvatarIconCtrl(p)
+{
+}
+
+//////////////////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////////////////
+
+LLChicletSpeakerCtrl::LLChicletSpeakerCtrl(const Params&p)
+ : LLIconCtrl(p)
+{
+}
diff --git a/indra/newview/llchiclet.h b/indra/newview/llchiclet.h
new file mode 100644
index 0000000000..b1e73c9d8d
--- /dev/null
+++ b/indra/newview/llchiclet.h
@@ -0,0 +1,730 @@
+/**
+* @file llchiclet.h
+* @brief LLChiclet class header file
+*
+* $LicenseInfo:firstyear=2002&license=viewergpl$
+*
+* Copyright (c) 2002-2009, Linden Research, Inc.
+*
+* Second Life Viewer Source Code
+* The source code in this file ("Source Code") is provided by Linden Lab
+* to you under the terms of the GNU General Public License, version 2.0
+* ("GPL"), unless you have obtained a separate licensing agreement
+* ("Other License"), formally executed by you and Linden Lab. Terms of
+* the GPL can be found in doc/GPL-license.txt in this distribution, or
+* online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
+*
+* There are special exceptions to the terms and conditions of the GPL as
+* it is applied to this Source Code. View the full text of the exception
+* in the file doc/FLOSS-exception.txt in this software distribution, or
+* online at
+* http://secondlifegrid.net/programs/open_source/licensing/flossexception
+*
+* By copying, modifying or distributing this software, you acknowledge
+* that you have read and understood your obligations described above,
+* and agree to abide by those obligations.
+*
+* ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+* COMPLETENESS OR PERFORMANCE.
+* $/LicenseInfo$
+*/
+
+#ifndef LL_LLCHICLET_H
+#define LL_LLCHICLET_H
+
+#include "llavatariconctrl.h"
+#include "llbutton.h"
+#include "llpanel.h"
+#include "lltextbox.h"
+#include "lloutputmonitorctrl.h"
+#include "llgroupmgr.h"
+
+class LLVoiceControlPanel;
+class LLMenuGL;
+class LLIMFloater;
+
+/*
+ * Class for displaying amount of messages/notifications(unread).
+*/
+class LLChicletNotificationCounterCtrl : public LLTextBox
+{
+public:
+
+ struct Params : public LLInitParam::Block<Params, LLTextBox::Params>
+ {
+ Params()
+ {};
+ };
+
+ /*
+ * Sets number of notifications
+ */
+ virtual void setCounter(S32 counter);
+
+ /*
+ * Returns number of notifications
+ */
+ virtual S32 getCounter() const { return mCounter; }
+
+ /*
+ * Returns width, required to display amount of notifications in text form.
+ * Width is the only valid value.
+ */
+ /*virtual*/ LLRect getRequiredRect();
+
+ /*
+ * Sets number of notifications using LLSD
+ */
+ /*virtual*/ void setValue(const LLSD& value);
+
+ /*
+ * Returns number of notifications wrapped in LLSD
+ */
+ /*virtual*/ LLSD getValue() const;
+
+protected:
+
+ LLChicletNotificationCounterCtrl(const Params& p);
+ friend class LLUICtrlFactory;
+
+private:
+
+ S32 mCounter;
+ S32 mInitialWidth;
+};
+
+/*
+ * Class for displaying avatar's icon.
+*/
+class LLChicletAvatarIconCtrl : public LLAvatarIconCtrl
+{
+public:
+
+ struct Params : public LLInitParam::Block<Params, LLAvatarIconCtrl::Params>
+ {
+ Params()
+ {
+ draw_tooltip(FALSE);
+ mouse_opaque(FALSE);
+ };
+ };
+
+protected:
+
+ LLChicletAvatarIconCtrl(const Params& p);
+ friend class LLUICtrlFactory;
+};
+
+/*
+ * Class for displaying status of Voice Chat
+*/
+class LLChicletSpeakerCtrl : public LLIconCtrl
+{
+public:
+
+ struct Params : public LLInitParam::Block<Params, LLIconCtrl::Params>
+ {
+ Params(){};
+ };
+protected:
+
+ LLChicletSpeakerCtrl(const Params&p);
+ friend class LLUICtrlFactory;
+};
+
+/*
+ * Base class for all chiclets.
+ */
+class LLChiclet : public LLUICtrl
+{
+public:
+
+ struct Params : public LLInitParam::Block<Params, LLUICtrl::Params>
+ {
+ Optional<bool> show_counter;
+
+ Params();
+ };
+
+ /*virtual*/ ~LLChiclet();
+
+ /*
+ * Associates chat session id with chiclet.
+ */
+ virtual void setSessionId(const LLUUID& session_id) { mSessionId = session_id; }
+
+ /*
+ * Returns associated chat session.
+ */
+ virtual const LLUUID& getSessionId() const { return mSessionId; }
+
+ /*
+ * Sets number of unread notifications.
+ */
+ virtual void setCounter(S32 counter) = 0;
+
+ /*
+ * Returns number of unread notifications.
+ */
+ virtual S32 getCounter() = 0;
+
+ /*
+ * Sets show counter state.
+ */
+ virtual void setShowCounter(bool show) { mShowCounter = show; }
+
+ /*
+ * Returns show counter state.
+ */
+ virtual bool getShowCounter() {return mShowCounter;};
+
+ /*
+ * Connects chiclet clicked event with callback.
+ */
+ /*virtual*/ boost::signals2::connection setLeftButtonClickCallback(
+ const commit_callback_t& cb);
+
+ typedef boost::function<void (LLChiclet* ctrl, const LLSD& param)>
+ chiclet_size_changed_callback_t;
+
+ /*
+ * Connects chiclets size changed event with callback.
+ */
+ virtual boost::signals2::connection setChicletSizeChangedCallback(
+ const chiclet_size_changed_callback_t& cb);
+
+ /*
+ * Sets IM Session id using LLSD
+ */
+ /*virtual*/ LLSD getValue() const;
+
+ /*
+ * Returns IM Session id using LLSD
+ */
+ /*virtual*/ void setValue(const LLSD& value);
+
+protected:
+
+ friend class LLUICtrlFactory;
+ LLChiclet(const Params& p);
+
+ /*
+ * Notifies subscribers about click on chiclet.
+ */
+ /*virtual*/ BOOL handleMouseDown(S32 x, S32 y, MASK mask);
+
+ /*
+ * Notifies subscribers about chiclet size changed event.
+ */
+ virtual void onChicletSizeChanged();
+
+private:
+
+ LLUUID mSessionId;
+
+ bool mShowCounter;
+
+ typedef boost::signals2::signal<void (LLChiclet* ctrl, const LLSD& param)>
+ chiclet_size_changed_signal_t;
+
+ chiclet_size_changed_signal_t mChicletSizeChangedSignal;
+};
+
+/*
+* Implements Instant Message chiclet.
+* IMChiclet displays avatar's icon, number of unread messages(optional)
+* and voice chat status(optional).
+*/
+class LLIMChiclet : public LLChiclet, LLGroupMgrObserver
+{
+public:
+ struct Params : public LLInitParam::Block<Params, LLChiclet::Params>
+ {
+ Optional<LLChicletAvatarIconCtrl::Params> avatar_icon;
+
+ Optional<LLIconCtrl::Params> group_insignia;
+
+ Optional<LLChicletNotificationCounterCtrl::Params> unread_notifications;
+
+ Optional<LLChicletSpeakerCtrl::Params> speaker;
+
+ Optional<bool> show_speaker;
+
+ Params();
+ };
+
+ /*virtual*/ ~LLIMChiclet();
+
+ virtual void setSessionId(const LLUUID& session_id);
+
+ /*
+ * Sets IM session name. This name will be displayed in chiclet tooltip.
+ */
+ virtual void setIMSessionName(const std::string& name);
+
+ /*
+ * Sets id of person/group user is chatting with.
+ * Session id should be set before calling this
+ */
+ virtual void setOtherParticipantId(const LLUUID& other_participant_id);
+
+ /*
+ * Gets id of person/group user is chatting with.
+ */
+ virtual LLUUID getOtherParticipantId();
+
+ /*
+ * Shows/hides voice chat status control.
+ */
+ virtual void setShowSpeaker(bool show);
+
+ /*
+ * Returns voice chat status control visibility.
+ */
+ virtual bool getShowSpeaker() {return mShowSpeaker;};
+
+ /*
+ * Sets number of unread messages. Will update chiclet's width if number text
+ * exceeds size of counter and notify it's parent about size change.
+ */
+ /*virtual*/ void setCounter(S32);
+
+ /*
+ * Returns number of unread messages.
+ */
+ /*virtual*/ S32 getCounter() { return mCounterCtrl->getCounter(); }
+
+ /*
+ * Shows/hides number of unread messages.
+ */
+ /*virtual*/ void setShowCounter(bool show);
+
+ /*
+ * Draws border around chiclet.
+ */
+ /*virtual*/ void draw();
+
+ /**
+ * The action taken on mouse down event.
+ *
+ * Made public so that it can be triggered from outside
+ * (more specifically, from the Active IM window).
+ */
+ void onMouseDown();
+
+ /*
+ * Returns rect, required to display chiclet.
+ * Width is the only valid value.
+ */
+ /*virtual*/ LLRect getRequiredRect();
+
+ /** comes from LLGroupMgrObserver */
+ virtual void changed(LLGroupChange gc);
+
+protected:
+
+ LLIMChiclet(const Params& p);
+ friend class LLUICtrlFactory;
+
+ /*
+ * Creates chiclet popup menu. Will create P2P or Group IM Chat menu
+ * based on other participant's id.
+ */
+ virtual void createPopupMenu();
+
+ /*
+ * Processes clicks on chiclet popup menu.
+ */
+ virtual void onMenuItemClicked(const LLSD& user_data);
+
+ /*
+ * Enables/disables menus based on relationship with other participant.
+ */
+ virtual void updateMenuItems();
+
+ /*
+ * Displays popup menu.
+ */
+ /*virtual*/ BOOL handleRightMouseDown(S32 x, S32 y, MASK mask);
+
+ /*virtual*/ BOOL handleMouseDown(S32 x, S32 y, MASK mask);
+
+protected:
+ LLChicletAvatarIconCtrl* mAvatarCtrl;
+
+ /** the icon of a group in case of group chat */
+ LLIconCtrl* mGroupInsignia;
+ LLChicletNotificationCounterCtrl* mCounterCtrl;
+ LLChicletSpeakerCtrl* mSpeakerCtrl;
+
+ LLMenuGL* mPopupMenu;
+
+ bool mShowSpeaker;
+
+ /** the id of another participant, either an avatar id or a group id*/
+ LLUUID mOtherParticipantId;
+
+ template<typename Container>
+ struct CollectChicletCombiner {
+ typedef Container result_type;
+
+ template<typename InputIterator>
+ Container operator()(InputIterator first, InputIterator last) const {
+ Container c = Container();
+ for (InputIterator iter = first; iter != last; iter++) {
+ if (*iter != NULL) {
+ c.push_back(*iter);
+ }
+ }
+ return c;
+ }
+ };
+
+public:
+ static boost::signals2::signal<LLChiclet* (const LLUUID&),
+ CollectChicletCombiner<std::list<LLChiclet*> > >
+ sFindChicletsSignal;
+};
+
+/*
+ * Implements notification chiclet. Used to display total amount of unread messages
+ * across all IM sessions, total amount of system notifications.
+*/
+class LLNotificationChiclet : public LLChiclet
+{
+public:
+
+ struct Params : public LLInitParam::Block<Params, LLChiclet::Params>
+ {
+ Optional<LLButton::Params> button;
+
+ Optional<LLChicletNotificationCounterCtrl::Params> unread_notifications;
+
+ Params();
+ };
+
+ /*virtual*/ void setCounter(S32 counter);
+
+ /*virtual*/S32 getCounter() { return mCounterCtrl->getCounter(); }
+
+ /*virtual*/ void setShowCounter(bool show);
+
+ boost::signals2::connection setClickCallback(const commit_callback_t& cb);
+
+ /*virtual*/ ~ LLNotificationChiclet();
+
+ // Notification Chiclet Window
+ void setNotificationChicletWindow(LLFloater* wnd) { mNotificationChicletWindow = wnd; }
+
+ // methods for updating a number of unread System or IM notifications
+ void incUreadSystemNotifications() { setCounter(++mUreadSystemNotifications + mUreadIMNotifications); }
+ void decUreadSystemNotifications() { setCounter(--mUreadSystemNotifications + mUreadIMNotifications); }
+ void updateUreadIMNotifications();
+
+protected:
+ LLNotificationChiclet(const Params& p);
+ friend class LLUICtrlFactory;
+
+ LLFloater* mNotificationChicletWindow;
+
+ static S32 mUreadSystemNotifications;
+ static S32 mUreadIMNotifications;
+
+protected:
+ LLButton* mButton;
+ LLChicletNotificationCounterCtrl* mCounterCtrl;
+};
+
+/*
+ * Storage class for all IM chiclets. Provides mechanism to display,
+ * scroll, create, remove chiclets.
+*/
+class LLChicletPanel : public LLPanel
+{
+public:
+
+ struct Params : public LLInitParam::Block<Params, LLPanel::Params>
+ {
+ Optional<S32> chiclet_padding,
+ scrolling_offset;
+
+ Optional<LLButton::Params> left_scroll_button,
+ right_scroll_button;
+
+ Optional<S32> min_width;
+
+ Params();
+ };
+
+ virtual ~LLChicletPanel();
+
+ /*
+ * Creates chiclet and adds it to chiclet list.
+ */
+ template<class T> T* createChiclet(const LLUUID& session_id = LLUUID::null, S32 index = 0);
+
+ /*
+ * Returns pointer to chiclet of specified type at specified index.
+ */
+ template<class T> T* getChiclet(S32 index);
+
+ /*
+ * Returns pointer to LLChiclet at specified index.
+ */
+ LLChiclet* getChiclet(S32 index) { return getChiclet<LLChiclet>(index); }
+
+ /*
+ * Searches a chiclet using IM session id.
+ */
+ template<class T> T* findChiclet(const LLUUID& im_session_id);
+
+ /*
+ * Returns number of hosted chiclets.
+ */
+ S32 getChicletCount() {return mChicletList.size();};
+
+ /*
+ * Returns index of chiclet in list.
+ */
+ S32 getChicletIndex(const LLChiclet* chiclet);
+
+ /*
+ * Removes chiclet by index.
+ */
+ void removeChiclet(S32 index);
+
+ /*
+ * Removes chiclet by pointer.
+ */
+ void removeChiclet(LLChiclet* chiclet);
+
+ /*
+ * Removes chiclet by IM session id.
+ */
+ void removeChiclet(const LLUUID& im_session_id);
+
+ /*
+ * Removes all chiclets.
+ */
+ void removeAll();
+
+ boost::signals2::connection setChicletClickedCallback(
+ const commit_callback_t& cb);
+
+ /*virtual*/ BOOL postBuild();
+
+ /*
+ * Reshapes controls and rearranges chiclets if needed.
+ */
+ /*virtual*/ void reshape(S32 width, S32 height, BOOL called_from_parent = TRUE );
+
+ /*virtual*/ void draw();
+
+protected:
+ LLChicletPanel(const Params&p);
+ friend class LLUICtrlFactory;
+
+ /*
+ * Adds chiclet to list and rearranges all chiclets.
+ */
+ bool addChiclet(LLChiclet*, S32 index);
+
+ /*
+ * Arranges chiclets.
+ */
+ void arrange();
+
+ /*
+ * Returns true if chiclets can be scrolled right.
+ */
+ bool canScrollRight();
+
+ /*
+ * Returns true if chiclets can be scrolled left.
+ */
+ bool canScrollLeft();
+
+ /*
+ * Shows or hides chiclet scroll buttons if chiclets can or can not be scrolled.
+ */
+ void showScrollButtonsIfNeeded();
+
+ /*
+ * Shifts chiclets left or right.
+ */
+ void shiftChiclets(S32 offset, S32 start_index = 0);
+
+ /*
+ * Removes gaps between first chiclet and scroll area left side,
+ * last chiclet and scroll area right side.
+ */
+ void trimChiclets();
+
+ /*
+ * Scrolls chiclets to right or left.
+ */
+ void scroll(S32 offset);
+
+ /*
+ * Verifies that chiclets can be scrolled left, then calls scroll()
+ */
+ void scrollLeft();
+
+ /*
+ * Verifies that chiclets can be scrolled right, then calls scroll()
+ */
+ void scrollRight();
+
+ /*
+ * Callback for left scroll button clicked
+ */
+ void onLeftScrollClick();
+
+ /*
+ * Callback for right scroll button clicked
+ */
+ void onRightScrollClick();
+
+ /*
+ * Callback for mouse wheel scrolled, calls scrollRight() or scrollLeft()
+ */
+ BOOL handleScrollWheel(S32 x, S32 y, S32 clicks);
+
+ /*
+ * Notifies subscribers about click on chiclet.
+ * Do not place any code here, instead subscribe on event (see setChicletClickedCallback).
+ */
+ void onChicletClick(LLUICtrl*ctrl,const LLSD&param);
+
+ /*
+ * Callback for chiclet size changed event, rearranges chiclets.
+ */
+ void onChicletSizeChanged(LLChiclet* ctrl, const LLSD& param);
+
+ typedef std::vector<LLChiclet*> chiclet_list_t;
+
+ /*
+ * Removes chiclet from scroll area and chiclet list.
+ */
+ void removeChiclet(chiclet_list_t::iterator it);
+
+ S32 getChicletPadding() { return mChicletPadding; }
+
+ S32 getScrollingOffset() { return mScrollingOffset; }
+
+protected:
+
+ chiclet_list_t mChicletList;
+ LLButton* mLeftScrollButton;
+ LLButton* mRightScrollButton;
+ LLPanel* mScrollArea;
+
+ S32 mChicletPadding;
+ S32 mScrollingOffset;
+ S32 mMinWidth;
+ bool mShowControls;
+};
+
+/*
+ * Button displaying voice chat status. Displays voice chat options When clicked.
+*/
+class LLTalkButton : public LLUICtrl
+{
+public:
+
+ struct Params : public LLInitParam::Block<Params, LLUICtrl::Params>
+ {
+ Optional<LLButton::Params> speak_button,
+ show_button;
+
+ Optional<LLOutputMonitorCtrl::Params> monitor;
+
+ Params();
+ };
+
+ /*virtual*/ ~LLTalkButton();
+
+ /*virtual*/ void draw();
+ void setSpeakBtnToggleState(bool state);
+
+protected:
+ friend class LLUICtrlFactory;
+ LLTalkButton(const Params& p);
+
+ void onClick_SpeakBtn();
+
+ void onClick_ShowBtn();
+
+private:
+ LLButton* mSpeakBtn;
+ LLButton* mShowBtn;
+ LLVoiceControlPanel* mPrivateCallPanel;
+ LLOutputMonitorCtrl* mOutputMonitor;
+};
+
+template<class T>
+T* LLChicletPanel::createChiclet(const LLUUID& session_id /*= LLUUID::null*/, S32 index /*= 0*/)
+{
+ typename T::Params params;
+ T* chiclet = LLUICtrlFactory::create<T>(params);
+ if(!chiclet)
+ {
+ llwarns << "Could not create chiclet" << llendl;
+ return NULL;
+ }
+ if(!addChiclet(chiclet, index))
+ {
+ delete chiclet;
+ llwarns << "Could not add chiclet to chiclet panel" << llendl;
+ return NULL;
+ }
+
+ chiclet->setSessionId(session_id);
+
+ return chiclet;
+}
+
+template<class T>
+T* LLChicletPanel::findChiclet(const LLUUID& im_session_id)
+{
+ if(im_session_id.isNull())
+ {
+ return NULL;
+ }
+
+ chiclet_list_t::const_iterator it = mChicletList.begin();
+ for( ; mChicletList.end() != it; ++it)
+ {
+ LLChiclet* chiclet = *it;
+
+ if(chiclet->getSessionId() == im_session_id)
+ {
+ T* result = dynamic_cast<T*>(chiclet);
+ if(!result && chiclet)
+ {
+ llwarns << "Found chiclet but of wrong type " << llendl;
+ }
+ return result;
+ }
+ }
+ return NULL;
+}
+
+template<class T> T* LLChicletPanel::getChiclet(S32 index)
+{
+ if(index < 0 || index >= getChicletCount())
+ {
+ return NULL;
+ }
+
+ LLChiclet* chiclet = mChicletList[index];
+ T*result = dynamic_cast<T*>(chiclet);
+ if(!result && chiclet)
+ {
+ llwarns << "Found chiclet but of wrong type " << llendl;
+ }
+ return result;
+}
+
+#endif // LL_LLCHICLET_H
diff --git a/indra/newview/llclassifiedstatsresponder.cpp b/indra/newview/llclassifiedstatsresponder.cpp
index a218e2b4e5..ecd1879090 100644
--- a/indra/newview/llclassifiedstatsresponder.cpp
+++ b/indra/newview/llclassifiedstatsresponder.cpp
@@ -33,7 +33,6 @@
#include "llviewerprecompiledheaders.h"
-#include "llagent.h"
#include "llclassifiedstatsresponder.h"
#include "llpanelclassified.h"
diff --git a/indra/newview/llclassifiedstatsresponder.h b/indra/newview/llclassifiedstatsresponder.h
index c4591df8de..9c52ed5ae1 100644
--- a/indra/newview/llclassifiedstatsresponder.h
+++ b/indra/newview/llclassifiedstatsresponder.h
@@ -44,6 +44,7 @@ public:
//If we get back a normal response, handle it here
virtual void result(const LLSD& content);
//If we get back an error (not found, etc...), handle it here
+
virtual void error(U32 status, const std::string& reason);
protected:
diff --git a/indra/newview/llcloud.cpp b/indra/newview/llcloud.cpp
index 0099817de4..af6f4e3286 100644
--- a/indra/newview/llcloud.cpp
+++ b/indra/newview/llcloud.cpp
@@ -37,6 +37,7 @@
#include "v3math.h"
#include "v4math.h"
#include "llquaternion.h"
+#include "llrand.h"
#include "v4color.h"
#include "llwind.h"
diff --git a/indra/newview/llcloud.h b/indra/newview/llcloud.h
index f4ae03b689..155bf4eae9 100644
--- a/indra/newview/llcloud.h
+++ b/indra/newview/llcloud.h
@@ -72,7 +72,7 @@
#include "v3dmath.h"
#include "v4math.h"
#include "v4color.h"
-#include "llmemory.h"
+#include "llpointer.h"
#include "lldarray.h"
#include "llframetimer.h"
diff --git a/indra/newview/llcolorswatch.cpp b/indra/newview/llcolorswatch.cpp
index 5f8d9ed27b..31c2d93c05 100644
--- a/indra/newview/llcolorswatch.cpp
+++ b/indra/newview/llcolorswatch.cpp
@@ -37,74 +37,69 @@
// Linden library includes
#include "v4color.h"
+#include "llwindow.h" // setCursor()
// Project includes
#include "llui.h"
#include "llrender.h"
#include "lluiconstants.h"
-#include "llviewerwindow.h"
#include "llviewercontrol.h"
#include "llbutton.h"
#include "lltextbox.h"
#include "llfloatercolorpicker.h"
#include "llviewborder.h"
-#include "llviewerimagelist.h"
+#include "llviewertexturelist.h"
#include "llfocusmgr.h"
-static LLRegisterWidget<LLColorSwatchCtrl> r("color_swatch");
+static LLDefaultChildRegistry::Register<LLColorSwatchCtrl> r("color_swatch");
-LLColorSwatchCtrl::LLColorSwatchCtrl(const std::string& name, const LLRect& rect, const LLColor4& color,
- void (*commit_callback)(LLUICtrl* ctrl, void* userdata),
- void* userdata )
-: LLUICtrl(name, rect, TRUE, commit_callback, userdata, FOLLOWS_LEFT | FOLLOWS_TOP),
- mValid( TRUE ),
- mColor( color ),
- mBorderColor( gColors.getColor("DefaultHighlightLight") ),
- mCanApplyImmediately(FALSE),
- mOnCancelCallback(NULL),
- mOnSelectCallback(NULL)
+LLColorSwatchCtrl::Params::Params()
+: color("color", LLColor4::white),
+ can_apply_immediately("can_apply_immediately", false),
+ alpha_background_image("alpha_background_image"),
+ border_color("border_color"),
+ label_width("label_width", -1),
+ caption_text("caption_text"),
+ border("border")
{
- mCaption = new LLTextBox( name,
- LLRect( 0, BTN_HEIGHT_SMALL, getRect().getWidth(), 0 ),
- name,
- LLFontGL::getFontSansSerifSmall() );
- mCaption->setFollows( FOLLOWS_LEFT | FOLLOWS_RIGHT | FOLLOWS_BOTTOM );
- addChild( mCaption );
-
- // Scalable UI made this off-by-one, I don't know why. JC
- LLRect border_rect(0, getRect().getHeight()-1, getRect().getWidth()-1, 0);
- border_rect.mBottom += BTN_HEIGHT_SMALL;
- mBorder = new LLViewBorder(std::string("border"), border_rect, LLViewBorder::BEVEL_IN);
- addChild(mBorder);
-
- mAlphaGradientImage = LLUI::getUIImage("color_swatch_alpha.tga");
+ name = "colorswatch";
}
-LLColorSwatchCtrl::LLColorSwatchCtrl(const std::string& name, const LLRect& rect, const std::string& label, const LLColor4& color,
- void (*commit_callback)(LLUICtrl* ctrl, void* userdata),
- void* userdata )
-: LLUICtrl(name, rect, TRUE, commit_callback, userdata, FOLLOWS_LEFT | FOLLOWS_TOP),
+LLColorSwatchCtrl::LLColorSwatchCtrl(const Params& p)
+: LLUICtrl(p),
mValid( TRUE ),
- mColor( color ),
- mBorderColor( gColors.getColor("DefaultHighlightLight") ),
- mCanApplyImmediately(FALSE),
- mOnCancelCallback(NULL),
- mOnSelectCallback(NULL)
-{
- mCaption = new LLTextBox( label,
- LLRect( 0, BTN_HEIGHT_SMALL, getRect().getWidth(), 0 ),
- label,
- LLFontGL::getFontSansSerifSmall() );
- mCaption->setFollows( FOLLOWS_LEFT | FOLLOWS_RIGHT | FOLLOWS_BOTTOM );
+ mColor(p.color),
+ mCanApplyImmediately(p.can_apply_immediately),
+ mAlphaGradientImage(p.alpha_background_image),
+ mOnCancelCallback(p.cancel_callback()),
+ mOnSelectCallback(p.select_callback()),
+ mBorderColor(p.border_color()),
+ mLabelWidth(p.label_width)
+{
+ LLTextBox::Params tp = p.caption_text;
+ // label_width is specified, not -1
+ if(mLabelWidth!= -1)
+ {
+ tp.rect(LLRect( 0, BTN_HEIGHT_SMALL, mLabelWidth, 0 ));
+ }
+ else
+ {
+ tp.rect(LLRect( 0, BTN_HEIGHT_SMALL, getRect().getWidth(), 0 ));
+ }
+
+ tp.text(p.label);
+ mCaption = LLUICtrlFactory::create<LLTextBox>(tp);
addChild( mCaption );
- // Scalable UI made this off-by-one, I don't know why. JC
- LLRect border_rect(0, getRect().getHeight()-1, getRect().getWidth()-1, 0);
+ LLRect border_rect = getLocalRect();
+ border_rect.mTop -= 1;
+ border_rect.mRight -=1;
border_rect.mBottom += BTN_HEIGHT_SMALL;
- mBorder = new LLViewBorder(std::string("border"), border_rect, LLViewBorder::BEVEL_IN);
- addChild(mBorder);
- mAlphaGradientImage = LLUI::getUIImage("color_swatch_alpha.tga");
+ LLViewBorder::Params params = p.border;
+ params.rect(border_rect);
+ mBorder = LLUICtrlFactory::create<LLViewBorder> (params);
+ addChild(mBorder);
}
LLColorSwatchCtrl::~LLColorSwatchCtrl ()
@@ -114,9 +109,8 @@ LLColorSwatchCtrl::~LLColorSwatchCtrl ()
if (pickerp)
{
pickerp->cancelSelection();
- pickerp->close();
+ pickerp->closeFloater();
}
- mAlphaGradientImage = NULL;
}
BOOL LLColorSwatchCtrl::handleDoubleClick(S32 x, S32 y, MASK mask)
@@ -206,7 +200,7 @@ void LLColorSwatchCtrl::draw()
mBorder->setKeyboardFocusHighlight(hasFocus());
// Draw border
LLRect border( 0, getRect().getHeight(), getRect().getWidth(), BTN_HEIGHT_SMALL );
- gl_rect_2d( border, mBorderColor, FALSE );
+ gl_rect_2d( border, mBorderColor.get(), FALSE );
LLRect interior = border;
interior.stretch( -1 );
@@ -233,7 +227,7 @@ void LLColorSwatchCtrl::draw()
{
if (!mFallbackImageName.empty())
{
- LLPointer<LLViewerImage> fallback_image = gImageList.getImageFromFile(mFallbackImageName);
+ LLPointer<LLViewerTexture> fallback_image = LLViewerTextureManager::getFetchedTextureFromFile(mFallbackImageName, TRUE, FALSE, LLViewerTexture::LOD_TEXTURE);
if( fallback_image->getComponents() == 4 )
{
gl_rect_2d_checkerboard( interior );
@@ -264,7 +258,7 @@ void LLColorSwatchCtrl::setEnabled( BOOL enabled )
if (pickerp)
{
pickerp->cancelSelection();
- pickerp->close();
+ pickerp->closeFloater();
}
}
}
@@ -295,11 +289,11 @@ void LLColorSwatchCtrl::onColorChanged ( void* data, EColorPickOp pick_op )
if (pick_op == COLOR_CANCEL && subject->mOnCancelCallback)
{
- subject->mOnCancelCallback(subject, subject->mCallbackUserData);
+ subject->mOnCancelCallback( subject, LLSD());
}
else if (pick_op == COLOR_SELECT && subject->mOnSelectCallback)
{
- subject->mOnSelectCallback(subject, subject->mCallbackUserData);
+ subject->mOnSelectCallback( subject, LLSD() );
}
else
{
@@ -343,59 +337,3 @@ void LLColorSwatchCtrl::showPicker(BOOL take_focus)
}
}
-// virtual
-LLXMLNodePtr LLColorSwatchCtrl::getXML(bool save_children) const
-{
- LLXMLNodePtr node = LLUICtrl::getXML();
-
- node->createChild("color", TRUE)->setFloatValue(4, mColor.mV);
-
- node->createChild("border_color", TRUE)->setFloatValue(4, mBorderColor.mV);
-
- if (mCaption)
- {
- node->createChild("label", TRUE)->setStringValue(mCaption->getText());
- }
-
- node->createChild("can_apply_immediately", TRUE)->setBoolValue(mCanApplyImmediately);
-
- return node;
-}
-
-LLView* LLColorSwatchCtrl::fromXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFactory *factory)
-{
- std::string name("colorswatch");
- node->getAttributeString("name", name);
-
- std::string label;
- node->getAttributeString("label", label);
-
- LLColor4 color(1.f, 1.f, 1.f, 1.f);
- node->getAttributeColor("initial_color", color);
-
- LLRect rect;
- createRect(node, rect, parent, LLRect());
-
- BOOL can_apply_immediately = FALSE;
- node->getAttributeBOOL("can_apply_immediately", can_apply_immediately);
-
- LLUICtrlCallback callback = NULL;
-
- if (label.empty())
- {
- label.assign(node->getValue());
- }
-
- LLColorSwatchCtrl* color_swatch = new LLColorSwatchCtrl(
- name,
- rect,
- label,
- color,
- callback,
- NULL );
-
- color_swatch->setCanApplyImmediately(can_apply_immediately);
- color_swatch->initFromXML(node, parent);
-
- return color_swatch;
-}
diff --git a/indra/newview/llcolorswatch.h b/indra/newview/llcolorswatch.h
index 0dd021f51f..e3e267f831 100644
--- a/indra/newview/llcolorswatch.h
+++ b/indra/newview/llcolorswatch.h
@@ -36,7 +36,8 @@
#include "lluictrl.h"
#include "v4color.h"
#include "llfloater.h"
-#include "llviewerimage.h"
+#include "llviewertexture.h"
+#include "lltextbox.h"
//
// Classes
@@ -44,7 +45,7 @@
class LLColor4;
class LLTextBox;
class LLFloaterColorPicker;
-class LLViewerImage;
+class LLViewerTexture;
class LLColorSwatchCtrl
: public LLUICtrl
@@ -57,53 +58,65 @@ public:
COLOR_CANCEL
} EColorPickOp;
- LLColorSwatchCtrl(const std::string& name, const LLRect& rect, const LLColor4& color,
- void (*on_commit_callback)(LLUICtrl* ctrl, void* userdata),
- void* callback_userdata);
- LLColorSwatchCtrl(const std::string& name, const LLRect& rect, const std::string& label, const LLColor4& color,
- void (*on_commit_callback)(LLUICtrl* ctrl, void* userdata),
- void* callback_userdata);
+ struct Params : public LLInitParam::Block<Params, LLUICtrl::Params>
+ {
+ Optional<LLColor4> color;
+ Optional<bool> can_apply_immediately;
+ Optional<LLUIImage*> alpha_background_image;
+ Optional<commit_callback_t> cancel_callback;
+ Optional<commit_callback_t> select_callback;
+ Optional<LLUIColor> border_color;
+ Optional<S32> label_width;
+
+ Optional<LLTextBox::Params> caption_text;
+ Optional<LLViewBorder::Params> border;
+ Params();
+ };
+protected:
+ LLColorSwatchCtrl(const Params& p);
+ friend class LLUICtrlFactory;
+public:
~LLColorSwatchCtrl ();
- virtual void setValue(const LLSD& value);
+ /*virtual*/ void setValue(const LLSD& value);
- virtual LLSD getValue() const { return mColor.getValue(); }
+ /*virtual*/ LLSD getValue() const { return mColor.getValue(); }
const LLColor4& get() { return mColor; }
void set(const LLColor4& color, BOOL update_picker = FALSE, BOOL from_event = FALSE);
void setOriginal(const LLColor4& color);
void setValid(BOOL valid);
void setLabel(const std::string& label);
+ void setLabelWidth(S32 label_width) {mLabelWidth =label_width;}
void setCanApplyImmediately(BOOL apply) { mCanApplyImmediately = apply; }
- void setOnCancelCallback(LLUICtrlCallback cb) { mOnCancelCallback = cb; }
- void setOnSelectCallback(LLUICtrlCallback cb) { mOnSelectCallback = cb; }
+ void setOnCancelCallback(commit_callback_t cb) { mOnCancelCallback = cb; }
+ void setOnSelectCallback(commit_callback_t cb) { mOnSelectCallback = cb; }
void setFallbackImageName(const std::string& name) { mFallbackImageName = name; }
void showPicker(BOOL take_focus);
- virtual BOOL handleMouseDown(S32 x, S32 y, MASK mask);
- virtual BOOL handleMouseUp(S32 x, S32 y, MASK mask);
- virtual BOOL handleDoubleClick(S32 x,S32 y,MASK mask);
- virtual BOOL handleHover(S32 x, S32 y, MASK mask);
- virtual BOOL handleUnicodeCharHere(llwchar uni_char);
- virtual void draw();
- virtual void setEnabled( BOOL enabled );
- virtual LLXMLNodePtr getXML(bool save_children = true) const;
- static LLView* fromXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFactory *factory);
+ /*virtual*/ BOOL handleMouseDown(S32 x, S32 y, MASK mask);
+ /*virtual*/ BOOL handleMouseUp(S32 x, S32 y, MASK mask);
+ /*virtual*/ BOOL handleDoubleClick(S32 x,S32 y,MASK mask);
+ /*virtual*/ BOOL handleHover(S32 x, S32 y, MASK mask);
+ /*virtual*/ BOOL handleUnicodeCharHere(llwchar uni_char);
+ /*virtual*/ void draw();
+ /*virtual*/ void setEnabled( BOOL enabled );
static void onColorChanged ( void* data, EColorPickOp pick_op = COLOR_CHANGE );
protected:
BOOL mValid;
LLColor4 mColor;
- LLColor4 mBorderColor;
+ LLUIColor mBorderColor;
LLTextBox* mCaption;
LLHandle<LLFloater> mPickerHandle;
LLViewBorder* mBorder;
BOOL mCanApplyImmediately;
- LLUICtrlCallback mOnCancelCallback;
- LLUICtrlCallback mOnSelectCallback;
+ commit_callback_t mOnCancelCallback;
+ commit_callback_t mOnSelectCallback;
+ S32 mLabelWidth;
LLPointer<LLUIImage> mAlphaGradientImage;
std::string mFallbackImageName;
diff --git a/indra/newview/llcommandhandler.cpp b/indra/newview/llcommandhandler.cpp
index 422c94ade5..a04182a910 100644
--- a/indra/newview/llcommandhandler.cpp
+++ b/indra/newview/llcommandhandler.cpp
@@ -55,7 +55,7 @@ public:
bool dispatch(const std::string& cmd,
const LLSD& params,
const LLSD& query_map,
- LLWebBrowserCtrl* web,
+ LLMediaCtrl* web,
bool trusted_browser);
private:
@@ -84,7 +84,7 @@ void LLCommandHandlerRegistry::add(const char* cmd, bool require_trusted_browser
bool LLCommandHandlerRegistry::dispatch(const std::string& cmd,
const LLSD& params,
const LLSD& query_map,
- LLWebBrowserCtrl* web,
+ LLMediaCtrl* web,
bool trusted_browser)
{
std::map<std::string, LLCommandHandlerInfo>::iterator it = mMap.find(cmd);
@@ -126,7 +126,7 @@ LLCommandHandler::~LLCommandHandler()
bool LLCommandDispatcher::dispatch(const std::string& cmd,
const LLSD& params,
const LLSD& query_map,
- LLWebBrowserCtrl* web,
+ LLMediaCtrl* web,
bool trusted_browser)
{
return LLCommandHandlerRegistry::instance().dispatch(
diff --git a/indra/newview/llcommandhandler.h b/indra/newview/llcommandhandler.h
index ab4c2cc488..5cb3ee73d4 100644
--- a/indra/newview/llcommandhandler.h
+++ b/indra/newview/llcommandhandler.h
@@ -47,7 +47,7 @@ public:
// Your code here
bool handle(const LLSD& tokens, const LLSD& query_map,
- LLWebBrowserCtrl* web)
+ LLMediaCtrl* web)
{
if (tokens.size() < 1) return false;
LLUUID id( tokens[0] );
@@ -60,7 +60,7 @@ LLFooHandler gFooHandler;
*/
-class LLWebBrowserCtrl;
+class LLMediaCtrl;
class LLCommandHandler
{
@@ -68,14 +68,14 @@ public:
LLCommandHandler(const char* command, bool allow_from_untrusted_browser);
// Automatically registers object to get called when
// command is executed. All commands can be processed
- // in links from LLWebBrowserCtrl, but some (like teleport)
+ // in links from LLMediaCtrl, but some (like teleport)
// should not be allowed from outside the app.
virtual ~LLCommandHandler();
virtual bool handle(const LLSD& params,
const LLSD& query_map,
- LLWebBrowserCtrl* web) = 0;
+ LLMediaCtrl* web) = 0;
// For URL secondlife:///app/foo/bar/baz?cat=1&dog=2
// @params - array of "bar", "baz", possibly empty
// @query_map - map of "cat" -> 1, "dog" -> 2, possibly empty
@@ -91,7 +91,7 @@ public:
static bool dispatch(const std::string& cmd,
const LLSD& params,
const LLSD& query_map,
- LLWebBrowserCtrl* web,
+ LLMediaCtrl* web,
bool trusted_browser);
// Execute a command registered via the above mechanism,
// passing string parameters.
diff --git a/indra/newview/llcompilequeue.cpp b/indra/newview/llcompilequeue.cpp
index 689033a07b..9d3b92d937 100644
--- a/indra/newview/llcompilequeue.cpp
+++ b/indra/newview/llcompilequeue.cpp
@@ -46,6 +46,7 @@
#include "llassetuploadqueue.h"
#include "llassetuploadresponders.h"
#include "llchat.h"
+#include "llfloaterreg.h"
#include "llviewerwindow.h"
#include "llviewerobject.h"
#include "llviewerobjectlist.h"
@@ -55,28 +56,24 @@
#include "llviewerobject.h"
#include "llviewerregion.h"
#include "llresmgr.h"
+
#include "llbutton.h"
#include "lldir.h"
#include "llfloaterchat.h"
#include "llviewerstats.h"
+#include "llvfile.h"
#include "lluictrlfactory.h"
+#include "lltrans.h"
#include "llselectmgr.h"
+// *TODO: This should be separated into the script queue, and the floater views of that queue.
+// There should only be one floater class that can view any queue type
+
///----------------------------------------------------------------------------
/// Local function declarations, constants, enums, and typedefs
///----------------------------------------------------------------------------
-// *TODO:Translate
-const std::string COMPILE_QUEUE_TITLE("Recompilation Progress");
-const std::string COMPILE_START_STRING("recompile");
-const std::string RESET_QUEUE_TITLE("Reset Progress");
-const std::string RESET_START_STRING("reset");
-const std::string RUN_QUEUE_TITLE("Set Running Progress");
-const std::string RUN_START_STRING("set running");
-const std::string NOT_RUN_QUEUE_TITLE("Set Not Running Progress");
-const std::string NOT_RUN_START_STRING("set not running");
-
struct LLScriptQueueData
{
LLUUID mQueueID;
@@ -92,54 +89,26 @@ struct LLScriptQueueData
/// Class LLFloaterScriptQueue
///----------------------------------------------------------------------------
-// static
-LLMap<LLUUID, LLFloaterScriptQueue*> LLFloaterScriptQueue::sInstances;
-
-
// Default constructor
-LLFloaterScriptQueue::LLFloaterScriptQueue(const std::string& name,
- const LLRect& rect,
- const std::string& title,
- const std::string& start_string) :
- LLFloater(name, rect, title,
- RESIZE_YES, DEFAULT_MIN_WIDTH, DEFAULT_MIN_HEIGHT,
- DRAG_ON_TOP, MINIMIZE_YES, CLOSE_YES)
+LLFloaterScriptQueue::LLFloaterScriptQueue(const LLSD& key) :
+ LLFloater(key),
+ mDone(FALSE)
{
- mID.generate();
-
- LLUICtrlFactory::getInstance()->buildFloater(this,"floater_script_queue.xml");
-
- childSetAction("close",onCloseBtn,this);
- childSetEnabled("close",FALSE);
-
- setTitle(title);
-
- LLRect curRect = getRect();
- translate(rect.mLeft - curRect.mLeft, rect.mTop - curRect.mTop);
-
- mStartString = start_string;
- mDone = FALSE;
- sInstances.addData(mID, this);
+ //Called from floater reg: LLUICtrlFactory::getInstance()->buildFloater(this,"floater_script_queue.xml", FALSE);
}
// Destroys the object
LLFloaterScriptQueue::~LLFloaterScriptQueue()
{
- sInstances.removeData(mID);
}
-// find an instance by ID. Return NULL if it does not exist.
-// static
-LLFloaterScriptQueue* LLFloaterScriptQueue::findInstance(const LLUUID& id)
+BOOL LLFloaterScriptQueue::postBuild()
{
- if(sInstances.checkData(id))
- {
- return sInstances.getData(id);
- }
- return NULL;
+ childSetAction("close",onCloseBtn,this);
+ childSetEnabled("close",FALSE);
+ return TRUE;
}
-
// This is the callback method for the viewer object currently being
// worked on.
// NOT static, virtual!
@@ -185,7 +154,7 @@ void LLFloaterScriptQueue::inventoryChanged(LLViewerObject* viewer_object,
void LLFloaterScriptQueue::onCloseBtn(void* user_data)
{
LLFloaterScriptQueue* self = (LLFloaterScriptQueue*)user_data;
- self->close();
+ self->closeFloater();
}
void LLFloaterScriptQueue::addObject(const LLUUID& id)
@@ -210,10 +179,12 @@ BOOL LLFloaterScriptQueue::start()
n_objects = selectHandle->getRootObjectCount();
}
- buffer = llformat("Starting %s of %d items.", mStartString.c_str(), n_objects); // *TODO: Translate
+ LLStringUtil::format_map_t args;
+ args["[START]"] = mStartString;
+ args["[COUNT]"] = llformat ("%d", mObjectIDs.count());
+ buffer = getString ("Starting", args);
- LLScrollListCtrl* list = getChild<LLScrollListCtrl>("queue output");
- list->addCommentText(buffer);
+ getChild<LLScrollListCtrl>("queue output")->setCommentText(buffer);
return nextObject();
}
@@ -245,12 +216,8 @@ BOOL LLFloaterScriptQueue::nextObject()
} while((mObjectIDs.count() > 0) && !successful_start);
if(isDone() && !mDone)
{
-
- LLScrollListCtrl* list = getChild<LLScrollListCtrl>("queue output");
-
mDone = TRUE;
- std::string buffer = "Done."; // *TODO: Translate
- list->addCommentText(buffer);
+ getChild<LLScrollListCtrl>("queue output")->setCommentText(getString("Done"));
childSetEnabled("close",TRUE);
}
return successful_start;
@@ -275,7 +242,7 @@ BOOL LLFloaterScriptQueue::popNext()
{
llinfos << "LLFloaterScriptQueue::popNext() requesting inv for "
<< mCurrentObjectID << llendl;
- LLUUID* id = new LLUUID(mID);
+ LLUUID* id = new LLUUID(getKey().asUUID());
registerVOInventoryListener(obj,id);
requestVOInventory();
rv = TRUE;
@@ -289,64 +256,48 @@ BOOL LLFloaterScriptQueue::popNext()
/// Class LLFloaterCompileQueue
///----------------------------------------------------------------------------
-// static
-LLFloaterCompileQueue* LLFloaterCompileQueue::create(BOOL mono)
+class LLCompileFloaterUploadQueueSupplier : public LLAssetUploadQueueSupplier
{
- S32 left, top;
- gFloaterView->getNewFloaterPosition(&left, &top);
- LLRect rect = gSavedSettings.getRect("CompileOutputRect");
- rect.translate(left - rect.mLeft, top - rect.mTop);
- LLFloaterCompileQueue* new_queue = new LLFloaterCompileQueue("queue", rect);
+public:
- class LLCompileFloaterUploadQueueSupplier : public LLAssetUploadQueueSupplier
+ LLCompileFloaterUploadQueueSupplier(const LLUUID& queue_id) :
+ mQueueId(queue_id)
{
- public:
-
- LLCompileFloaterUploadQueueSupplier(const LLUUID& queue_id) :
- mQueueId(queue_id)
- {
- }
+ }
- virtual LLAssetUploadQueue* get() const
+ virtual LLAssetUploadQueue* get() const
+ {
+ LLFloaterCompileQueue* queue = LLFloaterReg::findTypedInstance<LLFloaterCompileQueue>("compile_queue", LLSD(mQueueId));
+ if(NULL == queue)
{
- LLFloaterCompileQueue* queue =
- (LLFloaterCompileQueue*) LLFloaterScriptQueue::findInstance(mQueueId);
-
- if(NULL == queue)
- {
- return NULL;
- }
-
- return queue->mUploadQueue;
+ return NULL;
}
+ return queue->getUploadQueue();
+ }
- virtual void log(std::string message) const
+ virtual void log(std::string message) const
+ {
+ LLFloaterCompileQueue* queue = LLFloaterReg::findTypedInstance<LLFloaterCompileQueue>("compile_queue", LLSD(mQueueId));
+ if(NULL == queue)
{
- LLFloaterCompileQueue* queue =
- (LLFloaterCompileQueue*) LLFloaterScriptQueue::findInstance(mQueueId);
-
- if(NULL == queue)
- {
- return;
- }
-
- LLScrollListCtrl* list = queue->getChild<LLScrollListCtrl>("queue output");
- list->addCommentText(message.c_str());
+ return;
}
+
+ queue->getChild<LLScrollListCtrl>("queue output")->setCommentText(message);
+ }
- private:
- LLUUID mQueueId;
- };
-
- new_queue->mUploadQueue = new LLAssetUploadQueue(new LLCompileFloaterUploadQueueSupplier(new_queue->getID()));
- new_queue->mMono = mono;
- new_queue->open();
- return new_queue;
-}
+private:
+ LLUUID mQueueId;
+};
-LLFloaterCompileQueue::LLFloaterCompileQueue(const std::string& name, const LLRect& rect)
-: LLFloaterScriptQueue(name, rect, COMPILE_QUEUE_TITLE, COMPILE_START_STRING)
-{ }
+LLFloaterCompileQueue::LLFloaterCompileQueue(const LLSD& key)
+ : LLFloaterScriptQueue(key)
+{
+ setTitle(LLTrans::getString("CompileQueueTitle"));
+ setStartString(LLTrans::getString("CompileQueueStart"));
+
+ mUploadQueue = new LLAssetUploadQueue(new LLCompileFloaterUploadQueueSupplier(key.asUUID()));
+}
LLFloaterCompileQueue::~LLFloaterCompileQueue()
{
@@ -391,7 +342,7 @@ void LLFloaterCompileQueue::handleInventory(LLViewerObject *viewer_object,
for(iter = asset_item_map.begin(); iter != asset_item_map.end(); iter++)
{
LLInventoryItem *itemp = iter->second;
- LLScriptQueueData* datap = new LLScriptQueueData(getID(),
+ LLScriptQueueData* datap = new LLScriptQueueData(getKey().asUUID(),
itemp->getName(),
viewer_object->getID(),
itemp->getUUID());
@@ -419,9 +370,12 @@ void LLFloaterCompileQueue::scriptArrived(LLVFS *vfs, const LLUUID& asset_id,
{
llinfos << "LLFloaterCompileQueue::scriptArrived()" << llendl;
LLScriptQueueData* data = (LLScriptQueueData*)user_data;
- if(!data) return;
- LLFloaterCompileQueue* queue = static_cast<LLFloaterCompileQueue*>
- (LLFloaterScriptQueue::findInstance(data->mQueueID));
+ if(!data)
+ {
+ return;
+ }
+ LLFloaterCompileQueue* queue = LLFloaterReg::findTypedInstance<LLFloaterCompileQueue>("compile_queue", data->mQueueID);
+
std::string buffer;
if(queue && (0 == status))
{
@@ -447,13 +401,13 @@ void LLFloaterCompileQueue::scriptArrived(LLVFS *vfs, const LLUUID& asset_id,
file.read(script_data, script_size);
queue->mUploadQueue->queue(filename, data->mTaskId,
- data->mItemId, is_running, queue->mMono, queue->getID(),
- script_data, script_size, data->mScriptName);
+ data->mItemId, is_running, queue->mMono, queue->getKey().asUUID(),
+ script_data, script_size, data->mScriptName);
}
else
{
// It's now in the file, now compile it.
- buffer = std::string("Downloaded, now compiling: ") + data->mScriptName; // *TODO: Translate
+ buffer = LLTrans::getString("CompileQueueDownloadedCompiling") + (": ") + data->mScriptName;
// Write script to local file for compilation.
LLFILE *fp = LLFile::fopen(filename, "wb"); /*Flawfinder: ignore*/
@@ -492,19 +446,19 @@ void LLFloaterCompileQueue::scriptArrived(LLVFS *vfs, const LLUUID& asset_id,
if( LL_ERR_ASSET_REQUEST_NOT_IN_DATABASE == status )
{
- LLChat chat(std::string("Script not found on server.")); // *TODO: Translate
+ LLChat chat(LLTrans::getString("CompileQueueScriptNotFound"));
LLFloaterChat::addChat(chat);
- buffer = std::string("Problem downloading: ") + data->mScriptName; // *TODO: Translate
+ buffer = LLTrans::getString("CompileQueueProblemDownloading") + (": ") + data->mScriptName;
}
else if (LL_ERR_INSUFFICIENT_PERMISSIONS == status)
{
- LLChat chat(std::string("Insufficient permissions to download a script.")); // *TODO: Translate
+ LLChat chat(LLTrans::getString("CompileQueueInsufficientPermDownload"));
LLFloaterChat::addChat(chat);
- buffer = std::string("Insufficient permissions for: ") + data->mScriptName; // *TODO: Translate
+ buffer = LLTrans::getString("CompileQueueInsufficientPermFor") + (": ") + data->mScriptName;
}
else
{
- buffer = std::string("Unknown failure to download ") + data->mScriptName; // *TODO: Translate
+ buffer = LLTrans::getString("CompileQueueUnknownFailure") + (" ") + data->mScriptName;
}
llwarns << "Problem downloading script asset." << llendl;
@@ -512,8 +466,7 @@ void LLFloaterCompileQueue::scriptArrived(LLVFS *vfs, const LLUUID& asset_id,
}
if(queue && (buffer.size() > 0))
{
- LLScrollListCtrl* list = queue->getChild<LLScrollListCtrl>("queue output");
- list->addCommentText(buffer);
+ queue->getChild<LLScrollListCtrl>("queue output")->setCommentText(buffer);
}
delete data;
}
@@ -536,8 +489,7 @@ void LLFloaterCompileQueue::onSaveBytecodeComplete(const LLUUID& asset_id, void*
{
llinfos << "LLFloaterCompileQueue::onSaveBytecodeComplete()" << llendl;
LLCompileQueueData* data = (LLCompileQueueData*)user_data;
- LLFloaterCompileQueue* queue = static_cast<LLFloaterCompileQueue*>
- (LLFloaterScriptQueue::findInstance(data->mQueueID));
+ LLFloaterCompileQueue* queue = LLFloaterReg::findTypedInstance<LLFloaterCompileQueue>("compile_queue", data->mQueueID);
if(queue && (0 == status) && data)
{
queue->saveItemByItemID(data->mItemId);
@@ -587,7 +539,7 @@ void LLFloaterCompileQueue::compile(const std::string& filename,
llinfos << "compile successful." << llendl;
// Save LSL bytecode
- LLCompileQueueData* data = new LLCompileQueueData(mID, item_id);
+ LLCompileQueueData* data = new LLCompileQueueData(getKey().asUUID(), item_id);
gAssetStorage->storeAssetData(dst_filename, new_asset_id,
LLAssetType::AT_LSL_BYTECODE,
&LLFloaterCompileQueue::onSaveBytecodeComplete,
@@ -656,23 +608,13 @@ void LLFloaterCompileQueue::saveItemByItemID(const LLUUID& asset_id)
/// Class LLFloaterResetQueue
///----------------------------------------------------------------------------
-// static
-LLFloaterResetQueue* LLFloaterResetQueue::create()
+LLFloaterResetQueue::LLFloaterResetQueue(const LLSD& key)
+ : LLFloaterScriptQueue(key)
{
- S32 left, top;
- gFloaterView->getNewFloaterPosition(&left, &top);
- LLRect rect = gSavedSettings.getRect("CompileOutputRect");
- rect.translate(left - rect.mLeft, top - rect.mTop);
- LLFloaterResetQueue* new_queue = new LLFloaterResetQueue("queue", rect);
- gFloaterView->addChild(new_queue);
- new_queue->open();
- return new_queue;
+ setTitle(LLTrans::getString("ResetQueueTitle"));
+ setStartString(LLTrans::getString("ResetQueueStart"));
}
-LLFloaterResetQueue::LLFloaterResetQueue(const std::string& name, const LLRect& rect)
-: LLFloaterScriptQueue(name, rect, RESET_QUEUE_TITLE, RESET_START_STRING)
-{ }
-
LLFloaterResetQueue::~LLFloaterResetQueue()
{
}
@@ -695,10 +637,9 @@ void LLFloaterResetQueue::handleInventory(LLViewerObject* viewer_obj,
if (object)
{
LLInventoryItem* item = (LLInventoryItem*)((LLInventoryObject*)(*it));
- LLScrollListCtrl* list = getChild<LLScrollListCtrl>("queue output");
std::string buffer;
- buffer = std::string("Resetting: ") + item->getName(); // *TODO: Translate
- list->addCommentText(buffer);
+ buffer = getString("Resetting") + (": ") + item->getName();
+ getChild<LLScrollListCtrl>("queue output")->setCommentText(buffer);
LLMessageSystem* msg = gMessageSystem;
msg->newMessageFast(_PREHASH_ScriptReset);
msg->nextBlockFast(_PREHASH_AgentData);
@@ -719,22 +660,13 @@ void LLFloaterResetQueue::handleInventory(LLViewerObject* viewer_obj,
/// Class LLFloaterRunQueue
///----------------------------------------------------------------------------
-// static
-LLFloaterRunQueue* LLFloaterRunQueue::create()
+LLFloaterRunQueue::LLFloaterRunQueue(const LLSD& key)
+ : LLFloaterScriptQueue(key)
{
- S32 left, top;
- gFloaterView->getNewFloaterPosition(&left, &top);
- LLRect rect = gSavedSettings.getRect("CompileOutputRect");
- rect.translate(left - rect.mLeft, top - rect.mTop);
- LLFloaterRunQueue* new_queue = new LLFloaterRunQueue("queue", rect);
- new_queue->open(); /*Flawfinder: ignore*/
- return new_queue;
+ setTitle(LLTrans::getString("RunQueueTitle"));
+ setStartString(LLTrans::getString("RunQueueStart"));
}
-LLFloaterRunQueue::LLFloaterRunQueue(const std::string& name, const LLRect& rect)
-: LLFloaterScriptQueue(name, rect, RUN_QUEUE_TITLE, RUN_START_STRING)
-{ }
-
LLFloaterRunQueue::~LLFloaterRunQueue()
{
}
@@ -759,8 +691,8 @@ void LLFloaterRunQueue::handleInventory(LLViewerObject* viewer_obj,
LLInventoryItem* item = (LLInventoryItem*)((LLInventoryObject*)(*it));
LLScrollListCtrl* list = getChild<LLScrollListCtrl>("queue output");
std::string buffer;
- buffer = std::string("Running: ") + item->getName(); // *TODO: Translate
- list->addCommentText(buffer);
+ buffer = getString("Running") + (": ") + item->getName();
+ list->setCommentText(buffer);
LLMessageSystem* msg = gMessageSystem;
msg->newMessageFast(_PREHASH_SetScriptRunning);
@@ -783,22 +715,13 @@ void LLFloaterRunQueue::handleInventory(LLViewerObject* viewer_obj,
/// Class LLFloaterNotRunQueue
///----------------------------------------------------------------------------
-// static
-LLFloaterNotRunQueue* LLFloaterNotRunQueue::create()
+LLFloaterNotRunQueue::LLFloaterNotRunQueue(const LLSD& key)
+ : LLFloaterScriptQueue(key)
{
- S32 left, top;
- gFloaterView->getNewFloaterPosition(&left, &top);
- LLRect rect = gSavedSettings.getRect("CompileOutputRect");
- rect.translate(left - rect.mLeft, top - rect.mTop);
- LLFloaterNotRunQueue* new_queue = new LLFloaterNotRunQueue("queue", rect);
- new_queue->open(); /*Flawfinder: ignore*/
- return new_queue;
+ setTitle(LLTrans::getString("NotRunQueueTitle"));
+ setStartString(LLTrans::getString("NotRunQueueStart"));
}
-LLFloaterNotRunQueue::LLFloaterNotRunQueue(const std::string& name, const LLRect& rect)
-: LLFloaterScriptQueue(name, rect, NOT_RUN_QUEUE_TITLE, NOT_RUN_START_STRING)
-{ }
-
LLFloaterNotRunQueue::~LLFloaterNotRunQueue()
{
}
@@ -823,8 +746,8 @@ void LLFloaterNotRunQueue::handleInventory(LLViewerObject* viewer_obj,
LLInventoryItem* item = (LLInventoryItem*)((LLInventoryObject*)(*it));
LLScrollListCtrl* list = getChild<LLScrollListCtrl>("queue output");
std::string buffer;
- buffer = std::string("Not running: ") +item->getName(); // *TODO: Translate
- list->addCommentText(buffer);
+ buffer = getString("NotRunning") + (": ") +item->getName();
+ list->setCommentText(buffer);
LLMessageSystem* msg = gMessageSystem;
msg->newMessageFast(_PREHASH_SetScriptRunning);
diff --git a/indra/newview/llcompilequeue.h b/indra/newview/llcompilequeue.h
index 51240423ba..063d573239 100644
--- a/indra/newview/llcompilequeue.h
+++ b/indra/newview/llcompilequeue.h
@@ -59,20 +59,20 @@
class LLFloaterScriptQueue : public LLFloater, public LLVOInventoryListener
{
public:
+ LLFloaterScriptQueue(const LLSD& key);
+ virtual ~LLFloaterScriptQueue();
+
+ /*virtual*/ BOOL postBuild();
+
+ void setMono(bool mono) { mMono = mono; }
+
// addObject() accepts an object id.
void addObject(const LLUUID& id);
// start() returns TRUE if the queue has started, otherwise FALSE.
BOOL start();
-
- // find an instance by ID. Return NULL if it does not exist.
- static LLFloaterScriptQueue* findInstance(const LLUUID& id);
-
+
protected:
- LLFloaterScriptQueue(const std::string& name, const LLRect& rect,
- const std::string& title, const std::string& start_string);
- virtual ~LLFloaterScriptQueue();
-
// This is the callback method for the viewer object currently
// being worked on.
/*virtual*/ void inventoryChanged(LLViewerObject* obj,
@@ -94,8 +94,7 @@ protected:
BOOL nextObject();
BOOL popNext();
- // Get this instances ID.
- const LLUUID& getID() const { return mID; }
+ void setStartString(const std::string& s) { mStartString = s; }
protected:
// UI
@@ -107,10 +106,8 @@ protected:
LLUUID mCurrentObjectID;
BOOL mDone;
- LLUUID mID;
- static LLMap<LLUUID, LLFloaterScriptQueue*> sInstances;
-
std::string mStartString;
+ BOOL mMono;
};
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -131,20 +128,19 @@ class LLAssetUploadQueue;
class LLFloaterCompileQueue : public LLFloaterScriptQueue
{
+ friend class LLFloaterReg;
public:
- // Use this method to create a compile queue. Once created, it
- // will be responsible for it's own destruction.
- static LLFloaterCompileQueue* create(BOOL mono);
-
static void onSaveBytecodeComplete(const LLUUID& asset_id,
void* user_data,
S32 status);
// remove any object in mScriptScripts with the matching uuid.
void removeItemByItemID(const LLUUID& item_id);
+
+ LLAssetUploadQueue* getUploadQueue() { return mUploadQueue; }
protected:
- LLFloaterCompileQueue(const std::string& name, const LLRect& rect);
+ LLFloaterCompileQueue(const LLSD& key);
virtual ~LLFloaterCompileQueue();
// This is called by inventoryChanged
@@ -173,12 +169,11 @@ protected:
// find InventoryItem given item id.
const LLInventoryItem* findItemByItemID(const LLUUID& item_id) const;
-
+
protected:
LLViewerInventoryItem::item_array_t mCurrentScripts;
private:
- BOOL mMono; // Compile to mono.
LLAssetUploadQueue* mUploadQueue;
};
@@ -190,20 +185,14 @@ private:
class LLFloaterResetQueue : public LLFloaterScriptQueue
{
-public:
- // Use this method to create a reset queue. Once created, it
- // will be responsible for it's own destruction.
- static LLFloaterResetQueue* create();
-
+ friend class LLFloaterReg;
protected:
- LLFloaterResetQueue(const std::string& name, const LLRect& rect);
+ LLFloaterResetQueue(const LLSD& key);
virtual ~LLFloaterResetQueue();
// This is called by inventoryChanged
virtual void handleInventory(LLViewerObject* viewer_obj,
InventoryObjectList* inv);
-
-protected:
};
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -214,20 +203,14 @@ protected:
class LLFloaterRunQueue : public LLFloaterScriptQueue
{
-public:
- // Use this method to create a run queue. Once created, it
- // will be responsible for it's own destruction.
- static LLFloaterRunQueue* create();
-
+ friend class LLFloaterReg;
protected:
- LLFloaterRunQueue(const std::string& name, const LLRect& rect);
+ LLFloaterRunQueue(const LLSD& key);
virtual ~LLFloaterRunQueue();
// This is called by inventoryChanged
virtual void handleInventory(LLViewerObject* viewer_obj,
InventoryObjectList* inv);
-
-protected:
};
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -238,20 +221,14 @@ protected:
class LLFloaterNotRunQueue : public LLFloaterScriptQueue
{
-public:
- // Use this method to create a not run queue. Once created, it
- // will be responsible for it's own destruction.
- static LLFloaterNotRunQueue* create();
-
+ friend class LLFloaterReg;
protected:
- LLFloaterNotRunQueue(const std::string& name, const LLRect& rect);
+ LLFloaterNotRunQueue(const LLSD& key);
virtual ~LLFloaterNotRunQueue();
// This is called by inventoryChanged
virtual void handleInventory(LLViewerObject* viewer_obj,
InventoryObjectList* inv);
-
-protected:
};
#endif // LL_LLCOMPILEQUEUE_H
diff --git a/indra/newview/llcurrencyuimanager.cpp b/indra/newview/llcurrencyuimanager.cpp
index 86821249a0..9957694727 100644
--- a/indra/newview/llcurrencyuimanager.cpp
+++ b/indra/newview/llcurrencyuimanager.cpp
@@ -46,6 +46,7 @@
#include "llviewchildren.h"
#include "llxmlrpctransaction.h"
#include "llviewernetwork.h"
+#include "llpanel.h"
const F64 CURRENCY_ESTIMATE_FREQUENCY = 2.0;
@@ -356,8 +357,7 @@ void LLCurrencyUIManager::Impl::prepare()
if (lindenAmount)
{
lindenAmount->setPrevalidate(LLLineEditor::prevalidateNonNegativeS32);
- lindenAmount->setKeystrokeCallback(onCurrencyKey);
- lindenAmount->setCallbackUserData(this);
+ lindenAmount->setKeystrokeCallback(onCurrencyKey, this);
}
}
diff --git a/indra/newview/lldebugmessagebox.cpp b/indra/newview/lldebugmessagebox.cpp
index 4188ecc0e2..786473eb9b 100644
--- a/indra/newview/lldebugmessagebox.cpp
+++ b/indra/newview/lldebugmessagebox.cpp
@@ -50,32 +50,69 @@
std::map<std::string, LLDebugVarMessageBox*> LLDebugVarMessageBox::sInstances;
LLDebugVarMessageBox::LLDebugVarMessageBox(const std::string& title, EDebugVarType var_type, void *var) :
- LLFloater(std::string("msg box"), LLRect(10,160,400,10), title),
+ LLFloater(LLSD()),
mVarType(var_type), mVarData(var), mAnimate(FALSE)
{
+ setRect(LLRect(10,160,400,10));
+
+ LLSliderCtrl::Params slider_p;
+ slider_p.label(title);
+ slider_p.label_width(70);
+ slider_p.text_width(40);
+ slider_p.can_edit_text(true);
+ slider_p.show_text(true);
+
+ mSlider1 = NULL;
+ mSlider2 = NULL;
+ mSlider3 = NULL;
+
switch(var_type)
{
case VAR_TYPE_F32:
- mSlider1 = new LLSliderCtrl(std::string("slider 1"), LLRect(20,130,190,110), title, NULL, 70, 130, TRUE, TRUE, FALSE, NULL, NULL, *((F32*)var), -100.f, 100.f, 0.1f, LLStringUtil::null);
- mSlider1->setPrecision(3);
+ slider_p.name("slider 1");
+ slider_p.rect(LLRect(20,130,190,110));
+ slider_p.initial_value(*((F32*)var));
+ slider_p.min_value(-100.f);
+ slider_p.max_value(100.f);
+ slider_p.increment(0.1f);
+ slider_p.decimal_digits(3);
+ mSlider1 = LLUICtrlFactory::create<LLSliderCtrl>(slider_p);
addChild(mSlider1);
- mSlider2 = NULL;
- mSlider3 = NULL;
break;
case VAR_TYPE_S32:
- mSlider1 = new LLSliderCtrl(std::string("slider 1"), LLRect(20,100,190,80), title, NULL, 70, 130, TRUE, TRUE, FALSE, NULL, NULL, (F32)*((S32*)var), -255.f, 255.f, 1.f, LLStringUtil::null);
- mSlider1->setPrecision(0);
+ slider_p.name("slider 1");
+ slider_p.rect(LLRect(20,100,190,80));
+ slider_p.initial_value((F32)*((S32*)var));
+ slider_p.min_value(-255.f);
+ slider_p.max_value(255.f);
+ slider_p.increment(1.f);
+ slider_p.decimal_digits(0);
+ mSlider1 = LLUICtrlFactory::create<LLSliderCtrl>(slider_p);
addChild(mSlider1);
- mSlider2 = NULL;
- mSlider3 = NULL;
break;
case VAR_TYPE_VEC3:
- mSlider1 = new LLSliderCtrl(std::string("slider 1"), LLRect(20,130,190,110), std::string("x: "), NULL, 70, 130, TRUE, TRUE, FALSE, NULL, NULL, ((LLVector3*)var)->mV[VX], -100.f, 100.f, 0.1f, LLStringUtil::null);
- mSlider1->setPrecision(3);
- mSlider2 = new LLSliderCtrl(std::string("slider 2"), LLRect(20,100,190,80), std::string("y: "), NULL, 70, 130, TRUE, TRUE, FALSE, NULL, NULL, ((LLVector3*)var)->mV[VY], -100.f, 100.f, 0.1f, LLStringUtil::null);
- mSlider2->setPrecision(3);
- mSlider3 = new LLSliderCtrl(std::string("slider 3"), LLRect(20,70,190,50), std::string("z: "), NULL, 70, 130, TRUE, TRUE, FALSE, NULL, NULL, ((LLVector3*)var)->mV[VZ], -100.f, 100.f, 0.1f, LLStringUtil::null);
- mSlider3->setPrecision(3);
+ slider_p.name("slider 1");
+ slider_p.label("x: ");
+ slider_p.rect(LLRect(20,130,190,110));
+ slider_p.initial_value(((LLVector3*)var)->mV[VX]);
+ slider_p.min_value(-100.f);
+ slider_p.max_value(100.f);
+ slider_p.increment(0.1f);
+ slider_p.decimal_digits(3);
+ mSlider1 = LLUICtrlFactory::create<LLSliderCtrl>(slider_p);
+
+ slider_p.name("slider 2");
+ slider_p.label("y: ");
+ slider_p.rect(LLRect(20,100,190,80));
+ slider_p.initial_value(((LLVector3*)var)->mV[VY]);
+ mSlider2 = LLUICtrlFactory::create<LLSliderCtrl>(slider_p);
+
+ slider_p.name("slider 3");
+ slider_p.label("z: ");
+ slider_p.rect(LLRect(20,70,190,50));
+ slider_p.initial_value(((LLVector3*)var)->mV[VZ]);
+ mSlider2 = LLUICtrlFactory::create<LLSliderCtrl>(slider_p);
+
addChild(mSlider1);
addChild(mSlider2);
addChild(mSlider3);
@@ -85,10 +122,18 @@ LLDebugVarMessageBox::LLDebugVarMessageBox(const std::string& title, EDebugVarTy
break;
}
- mAnimateButton = new LLButton(std::string("Animate"), LLRect(20, 45, 180, 25), LLStringUtil::null, onAnimateClicked, this);
+ LLButton::Params p;
+ p.name(std::string("Animate"));
+ p.rect(LLRect(20, 45, 180, 25));
+ p.click_callback.function(boost::bind(&LLDebugVarMessageBox::onAnimateClicked, this, _2));
+ mAnimateButton = LLUICtrlFactory::create<LLButton>(p);
addChild(mAnimateButton);
- mText = new LLTextBox(std::string("value"), LLRect(20,20,190,0));
+ LLTextBox::Params params;
+ params.name("value");
+ params.text(params.name);
+ params.rect(LLRect(20,20,190,0));
+ mText = LLUICtrlFactory::create<LLTextBox> (params);
addChild(mText);
//disable hitting enter closes dialog
@@ -112,8 +157,7 @@ void LLDebugVarMessageBox::show(const std::string& title, F32 *var, F32 max_valu
{
box->mSlider1->setValue(*var);
}
- box->mSlider1->setCommitCallback(slider_changed);
- box->mSlider1->setCallbackUserData(box);
+ box->mSlider1->setCommitCallback(boost::bind(&LLDebugVarMessageBox::sliderChanged, box, _2));
#endif
}
@@ -129,8 +173,7 @@ void LLDebugVarMessageBox::show(const std::string& title, S32 *var, S32 max_valu
{
box->mSlider1->setValue((F32)*var);
}
- box->mSlider1->setCommitCallback(slider_changed);
- box->mSlider1->setCallbackUserData(box);
+ box->mSlider1->setCommitCallback(boost::bind(&LLDebugVarMessageBox::sliderChanged, box, _2));
#endif
}
@@ -142,20 +185,17 @@ void LLDebugVarMessageBox::show(const std::string& title, LLVector3 *var, LLVect
box->mSlider1->setMaxValue(max_value.mV[VX]);
box->mSlider1->setMinValue(-max_value.mV[VX]);
box->mSlider1->setIncrement(increment.mV[VX]);
- box->mSlider1->setCommitCallback(slider_changed);
- box->mSlider1->setCallbackUserData(box);
+ box->mSlider1->setCommitCallback(boost::bind(&LLDebugVarMessageBox::sliderChanged, box, _2));
box->mSlider2->setMaxValue(max_value.mV[VX]);
box->mSlider2->setMinValue(-max_value.mV[VX]);
box->mSlider2->setIncrement(increment.mV[VX]);
- box->mSlider2->setCommitCallback(slider_changed);
- box->mSlider2->setCallbackUserData(box);
+ box->mSlider2->setCommitCallback(boost::bind(&LLDebugVarMessageBox::sliderChanged, box, _2));
box->mSlider3->setMaxValue(max_value.mV[VX]);
box->mSlider3->setMinValue(-max_value.mV[VX]);
box->mSlider3->setIncrement(increment.mV[VX]);
- box->mSlider3->setCommitCallback(slider_changed);
- box->mSlider3->setCallbackUserData(box);
+ box->mSlider3->setCommitCallback(boost::bind(&LLDebugVarMessageBox::sliderChanged, box, _2));
#endif
}
@@ -170,50 +210,44 @@ LLDebugVarMessageBox* LLDebugVarMessageBox::show(const std::string& title, EDebu
sInstances[title_string] = box;
gFloaterView->addChild(box);
box->reshape(200,150);
- box->open(); /*Flawfinder: ignore*/
+ box->openFloater();
box->mTitle = title_string;
}
return box;
}
-void LLDebugVarMessageBox::slider_changed(LLUICtrl* ctrl, void* user_data)
+void LLDebugVarMessageBox::sliderChanged(const LLSD& data)
{
- LLDebugVarMessageBox *msg_box = (LLDebugVarMessageBox*)user_data;
- if (!msg_box || !msg_box->mVarData) return;
+ if (!mVarData)
+ return;
- switch(msg_box->mVarType)
+ switch(mVarType)
{
case VAR_TYPE_F32:
- *((F32*)msg_box->mVarData) = (F32)msg_box->mSlider1->getValue().asReal();
+ *((F32*)mVarData) = (F32)mSlider1->getValue().asReal();
break;
case VAR_TYPE_S32:
- *((S32*)msg_box->mVarData) = (S32)msg_box->mSlider1->getValue().asInteger();
+ *((S32*)mVarData) = (S32)mSlider1->getValue().asInteger();
break;
case VAR_TYPE_VEC3:
{
- LLVector3* vec_p = (LLVector3*)msg_box->mVarData;
- vec_p->setVec((F32)msg_box->mSlider1->getValue().asReal(),
- (F32)msg_box->mSlider2->getValue().asReal(),
- (F32)msg_box->mSlider3->getValue().asReal());
+ LLVector3* vec_p = (LLVector3*)mVarData;
+ vec_p->setVec((F32)mSlider1->getValue().asReal(),
+ (F32)mSlider2->getValue().asReal(),
+ (F32)mSlider3->getValue().asReal());
break;
}
default:
- llwarns << "Unhandled var type " << msg_box->mVarType << llendl;
+ llwarns << "Unhandled var type " << mVarType << llendl;
break;
}
}
-void LLDebugVarMessageBox::onAnimateClicked(void* user_data)
-{
- LLDebugVarMessageBox* msg_boxp = (LLDebugVarMessageBox*)user_data;
- msg_boxp->mAnimate = !msg_boxp->mAnimate;
- msg_boxp->mAnimateButton->setToggleState(msg_boxp->mAnimate);
-}
-
-void LLDebugVarMessageBox::onClose(bool app_quitting)
+void LLDebugVarMessageBox::onAnimateClicked(const LLSD& data)
{
- setVisible(FALSE);
+ mAnimate = !mAnimate;
+ mAnimateButton->setToggleState(mAnimate);
}
void LLDebugVarMessageBox::draw()
@@ -245,16 +279,16 @@ void LLDebugVarMessageBox::draw()
{
F32 animated_val = clamp_rescale(fmodf((F32)LLFrameTimer::getElapsedSeconds() / 5.f, 1.f), 0.f, 1.f, 0.f, mSlider1->getMaxValue());
mSlider1->setValue(animated_val);
- slider_changed(mSlider1, this);
+ sliderChanged(LLSD());
if (mSlider2)
{
mSlider2->setValue(animated_val);
- slider_changed(mSlider2, this);
+ sliderChanged(LLSD());
}
if (mSlider3)
{
mSlider3->setValue(animated_val);
- slider_changed(mSlider3, this);
+ sliderChanged(LLSD());
}
}
}
diff --git a/indra/newview/lldebugmessagebox.h b/indra/newview/lldebugmessagebox.h
index 07062218ac..0def0ee7af 100644
--- a/indra/newview/lldebugmessagebox.h
+++ b/indra/newview/lldebugmessagebox.h
@@ -66,8 +66,8 @@ protected:
~LLDebugVarMessageBox();
static LLDebugVarMessageBox* show(const std::string& title, EDebugVarType var_type, void *var);
- static void slider_changed(LLUICtrl* ctrl, void* user_data);
- static void onAnimateClicked(void* user_data);
+ void sliderChanged(const LLSD& data);
+ void onAnimateClicked(const LLSD& data);
public:
static void show(const std::string& title, F32 *var, F32 max_value = 100.f, F32 increment = 0.1f);
@@ -76,7 +76,6 @@ public:
static void show(const std::string& title, LLVector3 *var, LLVector3 max_value = LLVector3(100.f, 100.f, 100.f), LLVector3 increment = LLVector3(0.1f, 0.1f, 0.1f));
//static void show(const std::string& title, LLVector4 *var, LLVector4 max_value = LLVector4(100.f, 100.f, 100.f, 100.f), LLVector4 increment = LLVector4(0.1f, 0.1f, 0.1f, 0.1f));
- virtual void onClose(bool app_quitting);
virtual void draw();
protected:
diff --git a/indra/newview/lldebugview.cpp b/indra/newview/lldebugview.cpp
index 40f5202067..bd5b9c30a2 100644
--- a/indra/newview/lldebugview.cpp
+++ b/indra/newview/lldebugview.cpp
@@ -35,16 +35,16 @@
#include "lldebugview.h"
// library includes
-#include "llframestatview.h"
#include "llfasttimerview.h"
#include "llmemoryview.h"
#include "llconsole.h"
#include "lltextureview.h"
#include "llresmgr.h"
#include "imageids.h"
-#include "llvelocitybar.h"
+#include "llviewercontrol.h"
#include "llviewerwindow.h"
-#include "llfloaterstats.h"
+#include "llappviewer.h"
+#include "llmemoryview.h"
//
// Globals
@@ -56,57 +56,52 @@ LLDebugView* gDebugView = NULL;
// Methods
//
-LLDebugView::LLDebugView(const std::string& name, const LLRect &rect)
-: LLView(name, rect, FALSE)
+LLDebugView::LLDebugView(const LLDebugView::Params& p)
+: LLView(p)
{
LLRect r;
+ LLRect rect(p.rect);
r.set(10, rect.getHeight() - 100, rect.getWidth()/2, 100);
- mDebugConsolep = new LLConsole("debug console", 20, r, -1, 0.f );
- mDebugConsolep->setFollowsBottom();
- mDebugConsolep->setFollowsLeft();
- mDebugConsolep->setVisible( FALSE );
+ LLConsole::Params cp;
+ cp.name("debug console");
+ cp.max_lines(20);
+ cp.rect(r);
+ cp.font(LLFontGL::getFontMonospace());
+ cp.follows.flags(FOLLOWS_BOTTOM | FOLLOWS_LEFT);
+ cp.visible(false);
+ mDebugConsolep = LLUICtrlFactory::create<LLConsole>(cp);
addChild(mDebugConsolep);
r.set(150 - 25, rect.getHeight() - 50, rect.getWidth()/2 - 25, rect.getHeight() - 450);
- mFrameStatView = new LLFrameStatView("frame stat", r);
- mFrameStatView->setFollowsTop();
- mFrameStatView->setFollowsLeft();
- mFrameStatView->setVisible(FALSE); // start invisible
- addChild(mFrameStatView);
r.set(25, rect.getHeight() - 50, (S32) (gViewerWindow->getVirtualWindowRect().getWidth() * 0.75f),
(S32) (gViewerWindow->getVirtualWindowRect().getHeight() * 0.75f));
- mFastTimerView = new LLFastTimerView("fast timers", r);
+ mFastTimerView = new LLFastTimerView(r);
mFastTimerView->setFollowsTop();
mFastTimerView->setFollowsLeft();
mFastTimerView->setVisible(FALSE); // start invisible
addChild(mFastTimerView);
- r.set(25, rect.getHeight() - 50, rect.getWidth()/2, rect.getHeight() - 450);
- mMemoryView = new LLMemoryView("memory", r);
- mMemoryView->setFollowsTop();
- mMemoryView->setFollowsLeft();
- mMemoryView->setVisible(FALSE); // start invisible
+ r.set(25, rect.getHeight() - 50, (S32) (gViewerWindow->getVirtualWindowRect().getWidth() * 0.75f),
+ (S32) (gViewerWindow->getVirtualWindowRect().getHeight() * 0.75f));
+ LLMemoryView::Params mp;
+ mp.name("memory");
+ mp.rect(r);
+ mp.follows.flags(FOLLOWS_TOP | FOLLOWS_LEFT);
+ mp.visible(false);
+ mMemoryView = LLUICtrlFactory::create<LLMemoryView>(mp);
addChild(mMemoryView);
r.set(150, rect.getHeight() - 50, 820, 100);
- gTextureView = new LLTextureView("gTextureView", r);
- gTextureView->setRect(r);
- gTextureView->setFollowsBottom();
- gTextureView->setFollowsLeft();
+ LLTextureView::Params tvp;
+ tvp.name("gTextureView");
+ tvp.rect(r);
+ tvp.follows.flags(FOLLOWS_BOTTOM|FOLLOWS_LEFT);
+ tvp.visible(false);
+ gTextureView = LLUICtrlFactory::create<LLTextureView>(tvp);
addChild(gTextureView);
//gTextureView->reshape(r.getWidth(), r.getHeight(), TRUE);
-
- const S32 VELOCITY_LEFT = 10; // 370;
- const S32 VELOCITY_WIDTH = 500;
- const S32 VELOCITY_TOP = 140;
- const S32 VELOCITY_HEIGHT = 45;
- r.setLeftTopAndSize( VELOCITY_LEFT, VELOCITY_TOP, VELOCITY_WIDTH, VELOCITY_HEIGHT );
- gVelocityBar = new LLVelocityBar("Velocity Bar", r);
- gVelocityBar->setFollowsBottom();
- gVelocityBar->setFollowsLeft();
- addChild(gVelocityBar);
}
diff --git a/indra/newview/lldebugview.h b/indra/newview/lldebugview.h
index 189efd3a3f..9cf2a59a0a 100644
--- a/indra/newview/lldebugview.h
+++ b/indra/newview/lldebugview.h
@@ -40,9 +40,7 @@
// declarations
class LLButton;
-class LLToolView;
class LLStatusPanel;
-class LLFrameStatView;
class LLFastTimerView;
class LLMemoryView;
class LLConsole;
@@ -52,10 +50,18 @@ class LLFloaterStats;
class LLDebugView : public LLView
{
public:
- LLDebugView(const std::string& name, const LLRect &rect);
+ struct Params : public LLInitParam::Block<Params, LLView::Params>
+ {
+ Params()
+ {
+ mouse_opaque = false;
+ }
+ };
+ LLDebugView(const Params&);
~LLDebugView();
- LLFrameStatView* mFrameStatView;
+ void setStatsVisible(BOOL visible);
+
LLFastTimerView* mFastTimerView;
LLMemoryView* mMemoryView;
LLConsole* mDebugConsolep;
diff --git a/indra/newview/lldirpicker.cpp b/indra/newview/lldirpicker.cpp
index 8b0ed39eb0..a720dc46b5 100644
--- a/indra/newview/lldirpicker.cpp
+++ b/indra/newview/lldirpicker.cpp
@@ -40,6 +40,7 @@
#include "lldir.h"
#include "llframetimer.h"
#include "lltrans.h"
+#include "llwindow.h" // beforeDialog()
#if LL_LINUX || LL_SOLARIS
# include "llfilepicker.h"
diff --git a/indra/newview/lldrawable.cpp b/indra/newview/lldrawable.cpp
index cb368974ae..7cc78aff92 100644
--- a/indra/newview/lldrawable.cpp
+++ b/indra/newview/lldrawable.cpp
@@ -60,6 +60,9 @@ const F32 MAX_INTERPOLATE_DISTANCE_SQUARED = 10.f * 10.f;
const F32 OBJECT_DAMPING_TIME_CONSTANT = 0.06f;
const F32 MIN_SHADOW_CASTER_RADIUS = 2.0f;
+static LLFastTimer::DeclareTimer FTM_CULL_REBOUND("Cull Rebound");
+
+
////////////////////////
//
// Inline implementations.
@@ -188,7 +191,7 @@ BOOL LLDrawable::isLight() const
void LLDrawable::cleanupReferences()
{
- LLFastTimer t(LLFastTimer::FTM_PIPELINE);
+ LLFastTimer t(FTM_PIPELINE);
std::for_each(mFaces.begin(), mFaces.end(), DeletePointer());
mFaces.clear();
@@ -229,7 +232,7 @@ S32 LLDrawable::findReferences(LLDrawable *drawablep)
return count;
}
-LLFace* LLDrawable::addFace(LLFacePool *poolp, LLViewerImage *texturep)
+LLFace* LLDrawable::addFace(LLFacePool *poolp, LLViewerTexture *texturep)
{
LLMemType mt(LLMemType::MTYPE_DRAWABLE);
@@ -253,7 +256,7 @@ LLFace* LLDrawable::addFace(LLFacePool *poolp, LLViewerImage *texturep)
return face;
}
-LLFace* LLDrawable::addFace(const LLTextureEntry *te, LLViewerImage *texturep)
+LLFace* LLDrawable::addFace(const LLTextureEntry *te, LLViewerTexture *texturep)
{
LLMemType mt(LLMemType::MTYPE_DRAWABLE);
@@ -275,7 +278,7 @@ LLFace* LLDrawable::addFace(const LLTextureEntry *te, LLViewerImage *texturep)
}
-void LLDrawable::setNumFaces(const S32 newFaces, LLFacePool *poolp, LLViewerImage *texturep)
+void LLDrawable::setNumFaces(const S32 newFaces, LLFacePool *poolp, LLViewerTexture *texturep)
{
if (newFaces == (S32)mFaces.size())
{
@@ -298,7 +301,7 @@ void LLDrawable::setNumFaces(const S32 newFaces, LLFacePool *poolp, LLViewerImag
llassert_always(mFaces.size() == newFaces);
}
-void LLDrawable::setNumFacesFast(const S32 newFaces, LLFacePool *poolp, LLViewerImage *texturep)
+void LLDrawable::setNumFacesFast(const S32 newFaces, LLFacePool *poolp, LLViewerTexture *texturep)
{
if (newFaces <= (S32)mFaces.size() && newFaces >= (S32)mFaces.size()/2)
{
@@ -1033,7 +1036,7 @@ void LLSpatialBridge::updateSpatialExtents()
LLSpatialGroup* root = (LLSpatialGroup*) mOctree->getListener(0);
{
- LLFastTimer ftm(LLFastTimer::FTM_CULL_REBOUND);
+ LLFastTimer ftm(FTM_CULL_REBOUND);
root->rebound();
}
diff --git a/indra/newview/lldrawable.h b/indra/newview/lldrawable.h
index 6e0b6e81d6..c765980c30 100644
--- a/indra/newview/lldrawable.h
+++ b/indra/newview/lldrawable.h
@@ -46,7 +46,6 @@
#include "llmemtype.h"
#include "llprimitive.h"
#include "lldarray.h"
-#include "llstat.h"
#include "llviewerobject.h"
#include "llrect.h"
#include "llappviewer.h" // for gFrameTimeSeconds
@@ -59,12 +58,11 @@ class LLSpatialGroup;
class LLSpatialBridge;
class LLSpatialPartition;
class LLVOVolume;
-class LLViewerImage;
+class LLViewerTexture;
// Can have multiple silhouettes for each object
const U32 SILHOUETTE_HIGHLIGHT = 0;
-
// All data for new renderer goes into this class.
class LLDrawable : public LLRefCount
{
@@ -126,11 +124,11 @@ public:
inline S32 getNumFaces() const;
//void removeFace(const S32 i); // SJB: Avoid using this, it's slow
- LLFace* addFace(LLFacePool *poolp, LLViewerImage *texturep);
- LLFace* addFace(const LLTextureEntry *te, LLViewerImage *texturep);
+ LLFace* addFace(LLFacePool *poolp, LLViewerTexture *texturep);
+ LLFace* addFace(const LLTextureEntry *te, LLViewerTexture *texturep);
void deleteFaces(S32 offset, S32 count);
- void setNumFaces(const S32 numFaces, LLFacePool *poolp, LLViewerImage *texturep);
- void setNumFacesFast(const S32 numFaces, LLFacePool *poolp, LLViewerImage *texturep);
+ void setNumFaces(const S32 numFaces, LLFacePool *poolp, LLViewerTexture *texturep);
+ void setNumFacesFast(const S32 numFaces, LLFacePool *poolp, LLViewerTexture *texturep);
void mergeFaces(LLDrawable* src);
void init();
diff --git a/indra/newview/lldrawpool.cpp b/indra/newview/lldrawpool.cpp
index 9f05ce3c46..3a064a4e7d 100644
--- a/indra/newview/lldrawpool.cpp
+++ b/indra/newview/lldrawpool.cpp
@@ -60,7 +60,7 @@ S32 LLDrawPool::sNumDrawPools = 0;
//=============================
// Draw Pool Implementation
//=============================
-LLDrawPool *LLDrawPool::createPool(const U32 type, LLViewerImage *tex0)
+LLDrawPool *LLDrawPool::createPool(const U32 type, LLViewerTexture *tex0)
{
LLDrawPool *poolp = NULL;
switch (type)
@@ -129,7 +129,7 @@ LLDrawPool::~LLDrawPool()
}
-LLViewerImage *LLDrawPool::getDebugTexture()
+LLViewerTexture *LLDrawPool::getDebugTexture()
{
return NULL;
}
@@ -244,7 +244,7 @@ void LLFacePool::destroy()
}
}
-void LLFacePool::dirtyTextures(const std::set<LLViewerImage*>& textures)
+void LLFacePool::dirtyTextures(const std::set<LLViewerFetchedTexture*>& textures)
{
}
@@ -279,7 +279,7 @@ S32 LLFacePool::drawLoopSetTex(face_array_t& face_list, S32 stage)
iter != face_list.end(); iter++)
{
LLFace *facep = *iter;
- gGL.getTexUnit(stage)->bind(facep->getTexture());
+ gGL.getTexUnit(stage)->bind(facep->getTexture()) ;
gGL.getTexUnit(0)->activate();
res += facep->renderIndexed();
}
@@ -295,13 +295,6 @@ void LLFacePool::drawLoop()
}
}
-void LLFacePool::renderFaceSelected(LLFace *facep,
- LLImageGL *image,
- const LLColor4 &color,
- const S32 index_offset, const S32 index_count)
-{
-}
-
void LLFacePool::enqueue(LLFace* facep)
{
mDrawFace.push_back(facep);
@@ -330,7 +323,7 @@ void LLFacePool::resetDrawOrders()
mDrawFace.resize(0);
}
-LLViewerImage *LLFacePool::getTexture()
+LLViewerTexture *LLFacePool::getTexture()
{
return NULL;
}
@@ -481,7 +474,7 @@ void LLRenderPass::pushBatch(LLDrawInfo& params, U32 mask, BOOL texture)
{
if (params.mTexture.notNull())
{
- gGL.getTexUnit(0)->bind(params.mTexture.get());
+ gGL.getTexUnit(0)->bind(params.mTexture) ;
if (params.mTextureMatrix)
{
glMatrixMode(GL_TEXTURE);
diff --git a/indra/newview/lldrawpool.h b/indra/newview/lldrawpool.h
index 87c3ccaffe..966de41df3 100644
--- a/indra/newview/lldrawpool.h
+++ b/indra/newview/lldrawpool.h
@@ -39,8 +39,8 @@
#include "llvertexbuffer.h"
class LLFace;
-class LLImageGL;
-class LLViewerImage;
+class LLViewerTexture;
+class LLViewerFetchedTexture;
class LLSpatialGroup;
class LLDrawInfo;
@@ -77,7 +77,7 @@ public:
S32 getId() const { return mId; }
U32 getType() const { return mType; }
- virtual LLViewerImage *getDebugTexture();
+ virtual LLViewerTexture *getDebugTexture();
virtual void beginRenderPass( S32 pass );
virtual void endRenderPass( S32 pass );
virtual S32 getNumPasses();
@@ -103,9 +103,9 @@ public:
virtual BOOL verify() const { return TRUE; } // Verify that all data in the draw pool is correct!
virtual S32 getVertexShaderLevel() const { return mVertexShaderLevel; }
- static LLDrawPool* createPool(const U32 type, LLViewerImage *tex0 = NULL);
+ static LLDrawPool* createPool(const U32 type, LLViewerTexture *tex0 = NULL);
virtual LLDrawPool *instancePool() = 0; // Create an empty new instance of the pool.
- virtual LLViewerImage* getTexture() = 0;
+ virtual LLViewerTexture* getTexture() = 0;
virtual BOOL isFacePool() { return FALSE; }
virtual void resetDrawOrders() = 0;
@@ -139,8 +139,8 @@ public:
LLRenderPass(const U32 type);
virtual ~LLRenderPass();
/*virtual*/ LLDrawPool* instancePool();
- /*virtual*/ LLViewerImage* getDebugTexture() { return NULL; }
- LLViewerImage* getTexture() { return NULL; }
+ /*virtual*/ LLViewerTexture* getDebugTexture() { return NULL; }
+ LLViewerTexture* getTexture() { return NULL; }
BOOL isDead() { return FALSE; }
void resetDrawOrders() { }
@@ -169,11 +169,9 @@ public:
virtual void renderForSelect() = 0;
BOOL isDead() { return mReferences.empty(); }
- virtual void renderFaceSelected(LLFace *facep, LLImageGL *image, const LLColor4 &color,
- const S32 index_offset = 0, const S32 index_count = 0);
-
- virtual LLViewerImage *getTexture();
- virtual void dirtyTextures(const std::set<LLViewerImage*>& textures);
+
+ virtual LLViewerTexture *getTexture();
+ virtual void dirtyTextures(const std::set<LLViewerFetchedTexture*>& textures);
virtual void enqueue(LLFace *face);
virtual BOOL addFace(LLFace *face);
diff --git a/indra/newview/lldrawpoolalpha.cpp b/indra/newview/lldrawpoolalpha.cpp
index 7e470bd01f..88f79fc1b9 100644
--- a/indra/newview/lldrawpoolalpha.cpp
+++ b/indra/newview/lldrawpoolalpha.cpp
@@ -42,11 +42,10 @@
#include "llcubemap.h"
#include "llsky.h"
-#include "llagent.h"
#include "lldrawable.h"
#include "llface.h"
#include "llviewercamera.h"
-#include "llviewerimagelist.h" // For debugging
+#include "llviewertexturelist.h" // For debugging
#include "llviewerobjectlist.h" // For debugging
#include "llviewerwindow.h"
#include "pipeline.h"
@@ -90,7 +89,7 @@ void LLDrawPoolAlpha::endDeferredPass(S32 pass)
{
gGL.setAlphaRejectSettings(LLRender::CF_GREATER, 0.4f);
{
- LLFastTimer t(LLFastTimer::FTM_RENDER_GRASS);
+ LLFastTimer t(FTM_RENDER_GRASS);
gDeferredTreeProgram.bind();
LLGLEnable test(GL_ALPHA_TEST);
//render alpha masked objects
@@ -112,7 +111,7 @@ S32 LLDrawPoolAlpha::getNumPostDeferredPasses()
void LLDrawPoolAlpha::beginPostDeferredPass(S32 pass)
{
- LLFastTimer t(LLFastTimer::FTM_RENDER_ALPHA);
+ LLFastTimer t(FTM_RENDER_ALPHA);
simple_shader = &gDeferredAlphaProgram;
fullbright_shader = &gDeferredFullbrightProgram;
@@ -139,7 +138,7 @@ void LLDrawPoolAlpha::renderPostDeferred(S32 pass)
void LLDrawPoolAlpha::beginRenderPass(S32 pass)
{
- LLFastTimer t(LLFastTimer::FTM_RENDER_ALPHA);
+ LLFastTimer t(FTM_RENDER_ALPHA);
if (LLPipeline::sUnderWaterRender)
{
@@ -163,7 +162,7 @@ void LLDrawPoolAlpha::beginRenderPass(S32 pass)
void LLDrawPoolAlpha::endRenderPass( S32 pass )
{
- LLFastTimer t(LLFastTimer::FTM_RENDER_ALPHA);
+ LLFastTimer t(FTM_RENDER_ALPHA);
LLRenderPass::endRenderPass(pass);
if(gPipeline.canUseWindLightShaders())
@@ -174,7 +173,7 @@ void LLDrawPoolAlpha::endRenderPass( S32 pass )
void LLDrawPoolAlpha::render(S32 pass)
{
- LLFastTimer t(LLFastTimer::FTM_RENDER_ALPHA);
+ LLFastTimer t(FTM_RENDER_ALPHA);
LLGLSPipelineAlpha gls_pipeline_alpha;
@@ -218,8 +217,8 @@ void LLDrawPoolAlpha::render(S32 pass)
}
gPipeline.enableLightsFullbright(LLColor4(1,1,1,1));
glColor4f(1,0,0,1);
- LLViewerImage::sSmokeImagep->addTextureStats(1024.f*1024.f);
- gGL.getTexUnit(0)->bind(LLViewerImage::sSmokeImagep.get());
+ LLViewerFetchedTexture::sSmokeImagep->addTextureStats(1024.f*1024.f);
+ gGL.getTexUnit(0)->bind(LLViewerFetchedTexture::sSmokeImagep) ;
renderAlphaHighlight(LLVertexBuffer::MAP_VERTEX |
LLVertexBuffer::MAP_TEXCOORD0);
}
@@ -294,7 +293,7 @@ void LLDrawPoolAlpha::renderAlpha(U32 mask)
if (params.mTexture.notNull())
{
gGL.getTexUnit(0)->activate();
- gGL.getTexUnit(0)->bind(params.mTexture.get());
+ gGL.getTexUnit(0)->bind(params.mTexture) ;
params.mTexture->addTextureStats(params.mVSize);
if (params.mTextureMatrix)
{
diff --git a/indra/newview/lldrawpoolavatar.cpp b/indra/newview/lldrawpoolavatar.cpp
index 80c7d73e6a..565f906a3b 100644
--- a/indra/newview/lldrawpoolavatar.cpp
+++ b/indra/newview/lldrawpoolavatar.cpp
@@ -38,7 +38,6 @@
#include "llvoavatar.h"
#include "m3math.h"
-#include "llagent.h"
#include "lldrawable.h"
#include "llface.h"
#include "llsky.h"
@@ -89,17 +88,16 @@ S32 AVATAR_OFFSET_TEX0 = 32;
S32 AVATAR_OFFSET_TEX1 = 40;
S32 AVATAR_VERTEX_BYTES = 48;
-
BOOL gAvatarEmbossBumpMap = FALSE;
static BOOL sRenderingSkinned = FALSE;
S32 normal_channel = -1;
S32 specular_channel = -1;
-LLDrawPoolAvatar::LLDrawPoolAvatar() :
-LLFacePool(POOL_AVATAR)
+static LLFastTimer::DeclareTimer FTM_SHADOW_AVATAR("Avatar Shadow");
+
+LLDrawPoolAvatar::LLDrawPoolAvatar() :
+ LLFacePool(POOL_AVATAR)
{
- //LLDebugVarMessageBox::show("acceleration", &CLOTHING_ACCEL_FORCE_FACTOR, 10.f, 0.1f);
- //LLDebugVarMessageBox::show("gravity", &CLOTHING_GRAVITY_EFFECT, 10.f, 0.1f);
}
//-----------------------------------------------------------------------------
@@ -110,7 +108,6 @@ LLDrawPool *LLDrawPoolAvatar::instancePool()
return new LLDrawPoolAvatar();
}
-BOOL gRenderAvatar = TRUE;
S32 LLDrawPoolAvatar::getVertexShaderLevel() const
{
@@ -157,7 +154,7 @@ S32 LLDrawPoolAvatar::getNumDeferredPasses()
void LLDrawPoolAvatar::beginDeferredPass(S32 pass)
{
- LLFastTimer t(LLFastTimer::FTM_RENDER_CHARACTERS);
+ LLFastTimer t(FTM_RENDER_CHARACTERS);
if (LLPipeline::sImpostorRender)
{
@@ -181,7 +178,7 @@ void LLDrawPoolAvatar::beginDeferredPass(S32 pass)
void LLDrawPoolAvatar::endDeferredPass(S32 pass)
{
- LLFastTimer t(LLFastTimer::FTM_RENDER_CHARACTERS);
+ LLFastTimer t(FTM_RENDER_CHARACTERS);
if (LLPipeline::sImpostorRender)
{
@@ -251,7 +248,7 @@ S32 LLDrawPoolAvatar::getNumShadowPasses()
void LLDrawPoolAvatar::beginShadowPass(S32 pass)
{
- LLFastTimer t(LLFastTimer::FTM_SHADOW_AVATAR);
+ LLFastTimer t(FTM_SHADOW_AVATAR);
sVertexProgram = &gDeferredAvatarShadowProgram;
if (sShaderLevel > 0)
@@ -273,7 +270,7 @@ void LLDrawPoolAvatar::beginShadowPass(S32 pass)
void LLDrawPoolAvatar::endShadowPass(S32 pass)
{
- LLFastTimer t(LLFastTimer::FTM_SHADOW_AVATAR);
+ LLFastTimer t(FTM_SHADOW_AVATAR);
if (sShaderLevel > 0)
{
@@ -287,11 +284,7 @@ void LLDrawPoolAvatar::endShadowPass(S32 pass)
void LLDrawPoolAvatar::renderShadow(S32 pass)
{
- LLFastTimer t(LLFastTimer::FTM_SHADOW_AVATAR);
- if (!gRenderAvatar)
- {
- return;
- }
+ LLFastTimer t(FTM_SHADOW_AVATAR);
if (mDrawFace.empty())
{
@@ -327,7 +320,7 @@ S32 LLDrawPoolAvatar::getNumPasses()
void LLDrawPoolAvatar::render(S32 pass)
{
- LLFastTimer t(LLFastTimer::FTM_RENDER_CHARACTERS);
+ LLFastTimer t(FTM_RENDER_CHARACTERS);
if (LLPipeline::sImpostorRender)
{
renderAvatars(NULL, 2);
@@ -339,7 +332,7 @@ void LLDrawPoolAvatar::render(S32 pass)
void LLDrawPoolAvatar::beginRenderPass(S32 pass)
{
- LLFastTimer t(LLFastTimer::FTM_RENDER_CHARACTERS);
+ LLFastTimer t(FTM_RENDER_CHARACTERS);
//reset vertex buffer mappings
LLVertexBuffer::unbind();
@@ -365,7 +358,7 @@ void LLDrawPoolAvatar::beginRenderPass(S32 pass)
void LLDrawPoolAvatar::endRenderPass(S32 pass)
{
- LLFastTimer t(LLFastTimer::FTM_RENDER_CHARACTERS);
+ LLFastTimer t(FTM_RENDER_CHARACTERS);
if (LLPipeline::sImpostorRender)
{
@@ -609,13 +602,6 @@ void LLDrawPoolAvatar::renderAvatars(LLVOAvatar* single_avatar, S32 pass)
return;
}
-
-
- if (!gRenderAvatar)
- {
- return;
- }
-
if (mDrawFace.empty() && !single_avatar)
{
return;
@@ -647,7 +633,7 @@ void LLDrawPoolAvatar::renderAvatars(LLVOAvatar* single_avatar, S32 pass)
if (pass==1 && (!gPipeline.hasRenderType(LLPipeline::RENDER_TYPE_PARTICLES) || LLViewerPartSim::getMaxPartCount() <= 0))
{
// debug code to draw a sphere in place of avatar
- gGL.getTexUnit(0)->bind(LLViewerImage::sWhiteImagep.get());
+ gGL.getTexUnit(0)->bind(LLViewerFetchedTexture::sWhiteImagep);
gGL.setColorMask(true, true);
LLVector3 pos = avatarp->getPositionAgent();
gGL.color4f(1.0f, 1.0f, 1.0f, 0.7f);
@@ -761,10 +747,7 @@ void LLDrawPoolAvatar::renderAvatars(LLVOAvatar* single_avatar, S32 pass)
//-----------------------------------------------------------------------------
void LLDrawPoolAvatar::renderForSelect()
{
- if (!gRenderAvatar)
- {
- return;
- }
+
if (mDrawFace.empty())
{
@@ -836,7 +819,7 @@ void LLDrawPoolAvatar::renderForSelect()
//-----------------------------------------------------------------------------
// getDebugTexture()
//-----------------------------------------------------------------------------
-LLViewerImage *LLDrawPoolAvatar::getDebugTexture()
+LLViewerTexture *LLDrawPoolAvatar::getDebugTexture()
{
if (mReferences.empty())
{
diff --git a/indra/newview/lldrawpoolavatar.h b/indra/newview/lldrawpoolavatar.h
index 1e2630e1fb..6a2b7fc218 100644
--- a/indra/newview/lldrawpoolavatar.h
+++ b/indra/newview/lldrawpoolavatar.h
@@ -105,7 +105,7 @@ public:
void endDeferredRigid();
void endDeferredSkinned();
- /*virtual*/ LLViewerImage *getDebugTexture();
+ /*virtual*/ LLViewerTexture *getDebugTexture();
/*virtual*/ LLColor3 getDebugColor() const; // For AGP debug display
void renderAvatars(LLVOAvatar *single_avatar, S32 pass = -1); // renders only one avatar if single_avatar is not null.
diff --git a/indra/newview/lldrawpoolbump.cpp b/indra/newview/lldrawpoolbump.cpp
index b11dcc1608..331ba67d36 100644
--- a/indra/newview/lldrawpoolbump.cpp
+++ b/indra/newview/lldrawpoolbump.cpp
@@ -37,21 +37,19 @@
#include "llstl.h"
#include "llviewercontrol.h"
#include "lldir.h"
-#include "llimagegl.h"
#include "m3math.h"
#include "m4math.h"
#include "v4math.h"
#include "llglheaders.h"
#include "llrender.h"
-#include "llagent.h"
#include "llcubemap.h"
#include "lldrawable.h"
#include "llface.h"
#include "llsky.h"
#include "lltextureentry.h"
#include "llviewercamera.h"
-#include "llviewerimagelist.h"
+#include "llviewertexturelist.h"
#include "pipeline.h"
#include "llspatialpartition.h"
#include "llviewershadermgr.h"
@@ -75,6 +73,7 @@ const U32 VERTEX_MASK_BUMP = LLVertexBuffer::MAP_VERTEX |LLVertexBuffer::MAP_TEX
U32 LLDrawPoolBump::sVertexMask = VERTEX_MASK_SHINY;
+
static LLGLSLShader* shader = NULL;
static S32 cube_channel = -1;
static S32 diffuse_channel = -1;
@@ -127,9 +126,9 @@ void LLStandardBumpmap::restoreGL()
{
// *NOTE: This buffer size is hard coded into scanf() below.
char label[2048] = ""; /* Flawfinder: ignore */
- char bump_file[2048] = ""; /* Flawfinder: ignore */
+ char bump_image_id[2048] = ""; /* Flawfinder: ignore */
fields_read = fscanf( /* Flawfinder: ignore */
- file, "\n%2047s %2047s", label, bump_file);
+ file, "\n%2047s %2047s", label, bump_image_id);
if( EOF == fields_read )
{
break;
@@ -140,12 +139,13 @@ void LLStandardBumpmap::restoreGL()
return;
}
-// llinfos << "Loading bumpmap: " << bump_file << " from viewerart" << llendl;
+// llinfos << "Loading bumpmap: " << bump_image_id << " from viewerart" << llendl;
gStandardBumpmapList[LLStandardBumpmap::sStandardBumpmapCount].mLabel = label;
gStandardBumpmapList[LLStandardBumpmap::sStandardBumpmapCount].mImage =
- gImageList.getImageFromFile(bump_file,
+ LLViewerTextureManager::getFetchedTexture(LLUUID(bump_image_id),
TRUE,
FALSE,
+ LLViewerTexture::LOD_TEXTURE,
0,
0);
gStandardBumpmapList[LLStandardBumpmap::sStandardBumpmapCount].mImage->setLoadedCallback(LLBumpImageList::onSourceStandardLoaded, 0, TRUE, FALSE, NULL );
@@ -220,7 +220,7 @@ S32 LLDrawPoolBump::getNumPasses()
void LLDrawPoolBump::beginRenderPass(S32 pass)
{
- LLFastTimer t(LLFastTimer::FTM_RENDER_BUMP);
+ LLFastTimer t(FTM_RENDER_BUMP);
switch( pass )
{
case 0:
@@ -247,7 +247,7 @@ void LLDrawPoolBump::beginRenderPass(S32 pass)
void LLDrawPoolBump::render(S32 pass)
{
- LLFastTimer t(LLFastTimer::FTM_RENDER_BUMP);
+ LLFastTimer t(FTM_RENDER_BUMP);
if (!gPipeline.hasRenderType(LLDrawPool::POOL_SIMPLE))
{
@@ -280,7 +280,7 @@ void LLDrawPoolBump::render(S32 pass)
void LLDrawPoolBump::endRenderPass(S32 pass)
{
- LLFastTimer t(LLFastTimer::FTM_RENDER_BUMP);
+ LLFastTimer t(FTM_RENDER_BUMP);
switch( pass )
{
case 0:
@@ -308,7 +308,7 @@ void LLDrawPoolBump::endRenderPass(S32 pass)
//static
void LLDrawPoolBump::beginShiny(bool invisible)
{
- LLFastTimer t(LLFastTimer::FTM_RENDER_SHINY);
+ LLFastTimer t(FTM_RENDER_SHINY);
if (!invisible && !gPipeline.hasRenderBatches(LLRenderPass::PASS_SHINY)||
invisible && !gPipeline.hasRenderBatches(LLRenderPass::PASS_INVISI_SHINY))
{
@@ -383,7 +383,7 @@ void LLDrawPoolBump::beginShiny(bool invisible)
void LLDrawPoolBump::renderShiny(bool invisible)
{
- LLFastTimer t(LLFastTimer::FTM_RENDER_SHINY);
+ LLFastTimer t(FTM_RENDER_SHINY);
if (!invisible && !gPipeline.hasRenderBatches(LLRenderPass::PASS_SHINY)||
invisible && !gPipeline.hasRenderBatches(LLRenderPass::PASS_INVISI_SHINY))
{
@@ -410,7 +410,7 @@ void LLDrawPoolBump::renderShiny(bool invisible)
void LLDrawPoolBump::endShiny(bool invisible)
{
- LLFastTimer t(LLFastTimer::FTM_RENDER_SHINY);
+ LLFastTimer t(FTM_RENDER_SHINY);
if (!invisible && !gPipeline.hasRenderBatches(LLRenderPass::PASS_SHINY)||
invisible && !gPipeline.hasRenderBatches(LLRenderPass::PASS_INVISI_SHINY))
{
@@ -450,7 +450,7 @@ void LLDrawPoolBump::endShiny(bool invisible)
void LLDrawPoolBump::beginFullbrightShiny()
{
- LLFastTimer t(LLFastTimer::FTM_RENDER_SHINY);
+ LLFastTimer t(FTM_RENDER_SHINY);
if (!gPipeline.hasRenderBatches(LLRenderPass::PASS_FULLBRIGHT_SHINY))
{
return;
@@ -499,7 +499,7 @@ void LLDrawPoolBump::beginFullbrightShiny()
void LLDrawPoolBump::renderFullbrightShiny()
{
- LLFastTimer t(LLFastTimer::FTM_RENDER_SHINY);
+ LLFastTimer t(FTM_RENDER_SHINY);
if (!gPipeline.hasRenderBatches(LLRenderPass::PASS_FULLBRIGHT_SHINY))
{
return;
@@ -514,7 +514,7 @@ void LLDrawPoolBump::renderFullbrightShiny()
void LLDrawPoolBump::endFullbrightShiny()
{
- LLFastTimer t(LLFastTimer::FTM_RENDER_SHINY);
+ LLFastTimer t(FTM_RENDER_SHINY);
if (!gPipeline.hasRenderBatches(LLRenderPass::PASS_FULLBRIGHT_SHINY))
{
return;
@@ -569,22 +569,23 @@ void LLDrawPoolBump::renderGroup(LLSpatialGroup* group, U32 type, U32 mask, BOOL
// static
BOOL LLDrawPoolBump::bindBumpMap(LLDrawInfo& params, S32 channel)
{
- LLImageGL* bump = NULL;
+ LLViewerTexture* bump = NULL;
U8 bump_code = params.mBump;
- LLViewerImage* tex = params.mTexture;
+ LLViewerFetchedTexture* tex = LLViewerTextureManager::staticCastToFetchedTexture(params.mTexture) ;
+ if(!tex)
+ {
+ //if the texture is not a fetched texture
+ return FALSE;
+ }
switch( bump_code )
{
- case BE_NO_BUMP:
- bump = NULL;
+ case BE_NO_BUMP:
break;
case BE_BRIGHTNESS:
case BE_DARKNESS:
- if( tex )
- {
- bump = gBumpImageList.getBrightnessDarknessImage( tex, bump_code );
- }
+ bump = gBumpImageList.getBrightnessDarknessImage( tex, bump_code );
break;
default:
@@ -623,7 +624,7 @@ void LLDrawPoolBump::beginBump()
}
sVertexMask = VERTEX_MASK_BUMP;
- LLFastTimer t(LLFastTimer::FTM_RENDER_BUMP);
+ LLFastTimer t(FTM_RENDER_BUMP);
// Optional second pass: emboss bump map
stop_glerror();
@@ -667,7 +668,7 @@ void LLDrawPoolBump::renderBump()
return;
}
- LLFastTimer ftm(LLFastTimer::FTM_RENDER_BUMP);
+ LLFastTimer ftm(FTM_RENDER_BUMP);
LLGLDisable fog(GL_FOG);
LLGLDepthTest gls_depth(GL_TRUE, GL_FALSE, GL_LEQUAL);
LLGLEnable blend(GL_BLEND);
@@ -704,7 +705,7 @@ void LLDrawPoolBump::beginDeferredPass(S32 pass)
{
return;
}
- LLFastTimer ftm(LLFastTimer::FTM_RENDER_BUMP);
+ LLFastTimer ftm(FTM_RENDER_BUMP);
mShiny = TRUE;
gDeferredBumpProgram.bind();
diffuse_channel = gDeferredBumpProgram.enableTexture(LLViewerShaderMgr::DIFFUSE_MAP);
@@ -719,7 +720,7 @@ void LLDrawPoolBump::endDeferredPass(S32 pass)
{
return;
}
- LLFastTimer ftm(LLFastTimer::FTM_RENDER_BUMP);
+ LLFastTimer ftm(FTM_RENDER_BUMP);
mShiny = FALSE;
gDeferredBumpProgram.disableTexture(LLViewerShaderMgr::DIFFUSE_MAP);
gDeferredBumpProgram.disableTexture(LLViewerShaderMgr::BUMP_MAP);
@@ -733,7 +734,7 @@ void LLDrawPoolBump::renderDeferred(S32 pass)
{
return;
}
- LLFastTimer ftm(LLFastTimer::FTM_RENDER_BUMP);
+ LLFastTimer ftm(FTM_RENDER_BUMP);
U32 type = LLRenderPass::PASS_BUMP;
LLCullResult::drawinfo_list_t::iterator begin = gPipeline.beginRenderMap(type);
@@ -812,7 +813,7 @@ LLBumpImageList::~LLBumpImageList()
void LLBumpImageList::addTextureStats(U8 bump, const LLUUID& base_image_id, F32 virtual_size)
{
bump &= TEM_BUMP_MASK;
- LLViewerImage* bump_image = gStandardBumpmapList[bump].mImage;
+ LLViewerFetchedTexture* bump_image = gStandardBumpmapList[bump].mImage;
if( bump_image )
{
bump_image->addTextureStats(virtual_size);
@@ -826,11 +827,11 @@ void LLBumpImageList::updateImages()
for (bump_image_map_t::iterator iter = mBrightnessEntries.begin(); iter != mBrightnessEntries.end(); )
{
bump_image_map_t::iterator curiter = iter++;
- LLImageGL* image = curiter->second;
+ LLViewerTexture* image = curiter->second;
if( image )
{
BOOL destroy = TRUE;
- if( image->getHasGLTexture())
+ if( image->hasValidGLTexture())
{
if( image->getBoundRecently() )
{
@@ -853,11 +854,11 @@ void LLBumpImageList::updateImages()
for (bump_image_map_t::iterator iter = mDarknessEntries.begin(); iter != mDarknessEntries.end(); )
{
bump_image_map_t::iterator curiter = iter++;
- LLImageGL* image = curiter->second;
+ LLViewerTexture* image = curiter->second;
if( image )
{
BOOL destroy = TRUE;
- if( image->getHasGLTexture())
+ if( image->hasValidGLTexture())
{
if( image->getBoundRecently() )
{
@@ -881,16 +882,16 @@ void LLBumpImageList::updateImages()
// Note: the caller SHOULD NOT keep the pointer that this function returns. It may be updated as more data arrives.
-LLImageGL* LLBumpImageList::getBrightnessDarknessImage(LLViewerImage* src_image, U8 bump_code )
+LLViewerTexture* LLBumpImageList::getBrightnessDarknessImage(LLViewerFetchedTexture* src_image, U8 bump_code )
{
llassert( (bump_code == BE_BRIGHTNESS) || (bump_code == BE_DARKNESS) );
- LLImageGL* bump = NULL;
+ LLViewerTexture* bump = NULL;
const F32 BRIGHTNESS_DARKNESS_PIXEL_AREA_THRESHOLD = 1000;
- if( src_image->mMaxVirtualSize > BRIGHTNESS_DARKNESS_PIXEL_AREA_THRESHOLD )
+ if( src_image->getMaxVirtualSize() > BRIGHTNESS_DARKNESS_PIXEL_AREA_THRESHOLD )
{
bump_image_map_t* entries_list = NULL;
- void (*callback_func)( BOOL success, LLViewerImage *src_vi, LLImageRaw* src, LLImageRaw* aux_src, S32 discard_level, BOOL final, void* userdata ) = NULL;
+ void (*callback_func)( BOOL success, LLViewerFetchedTexture *src_vi, LLImageRaw* src, LLImageRaw* aux_src, S32 discard_level, BOOL final, void* userdata ) = NULL;
switch( bump_code )
{
@@ -917,14 +918,8 @@ LLImageGL* LLBumpImageList::getBrightnessDarknessImage(LLViewerImage* src_image,
LLPointer<LLImageRaw> raw = new LLImageRaw(1,1,1);
raw->clear(0x77, 0x77, 0x77, 0xFF);
- //------------------------------
- bump = new LLImageGL( raw, TRUE);
- //immediately assign bump to a global smart pointer in case some local smart pointer
- //accidently releases it.
- (*entries_list)[src_image->getID()] = bump;
- //------------------------------
-
- bump->setExplicitFormat(GL_ALPHA8, GL_ALPHA);
+ (*entries_list)[src_image->getID()] = LLViewerTextureManager::getLocalTexture( raw.get(), TRUE);
+ (*entries_list)[src_image->getID()]->setExplicitFormat(GL_ALPHA8, GL_ALPHA);
// Note: this may create an LLImageGL immediately
src_image->setLoadedCallback( callback_func, 0, TRUE, FALSE, new LLUUID(src_image->getID()) );
@@ -940,7 +935,7 @@ LLImageGL* LLBumpImageList::getBrightnessDarknessImage(LLViewerImage* src_image,
// static
-void LLBumpImageList::onSourceBrightnessLoaded( BOOL success, LLViewerImage *src_vi, LLImageRaw* src, LLImageRaw* aux_src, S32 discard_level, BOOL final, void* userdata )
+void LLBumpImageList::onSourceBrightnessLoaded( BOOL success, LLViewerFetchedTexture *src_vi, LLImageRaw* src, LLImageRaw* aux_src, S32 discard_level, BOOL final, void* userdata )
{
LLUUID* source_asset_id = (LLUUID*)userdata;
LLBumpImageList::onSourceLoaded( success, src_vi, src, *source_asset_id, BE_BRIGHTNESS );
@@ -951,7 +946,7 @@ void LLBumpImageList::onSourceBrightnessLoaded( BOOL success, LLViewerImage *src
}
// static
-void LLBumpImageList::onSourceDarknessLoaded( BOOL success, LLViewerImage *src_vi, LLImageRaw* src, LLImageRaw* aux_src, S32 discard_level, BOOL final, void* userdata )
+void LLBumpImageList::onSourceDarknessLoaded( BOOL success, LLViewerFetchedTexture *src_vi, LLImageRaw* src, LLImageRaw* aux_src, S32 discard_level, BOOL final, void* userdata )
{
LLUUID* source_asset_id = (LLUUID*)userdata;
LLBumpImageList::onSourceLoaded( success, src_vi, src, *source_asset_id, BE_DARKNESS );
@@ -961,7 +956,7 @@ void LLBumpImageList::onSourceDarknessLoaded( BOOL success, LLViewerImage *src_v
}
}
-void LLBumpImageList::onSourceStandardLoaded( BOOL success, LLViewerImage* src_vi, LLImageRaw* src, LLImageRaw* aux_src, S32 discard_level, BOOL final, void* userdata)
+void LLBumpImageList::onSourceStandardLoaded( BOOL success, LLViewerFetchedTexture* src_vi, LLImageRaw* src, LLImageRaw* aux_src, S32 discard_level, BOOL final, void* userdata)
{
if (success && LLPipeline::sRenderDeferred)
{
@@ -1028,7 +1023,7 @@ void LLBumpImageList::generateNormalMapFromAlpha(LLImageRaw* src, LLImageRaw* nr
}
// static
-void LLBumpImageList::onSourceLoaded( BOOL success, LLViewerImage *src_vi, LLImageRaw* src, LLUUID& source_asset_id, EBumpEffect bump_code )
+void LLBumpImageList::onSourceLoaded( BOOL success, LLViewerTexture *src_vi, LLImageRaw* src, LLUUID& source_asset_id, EBumpEffect bump_code )
{
if( success )
{
@@ -1147,7 +1142,7 @@ void LLBumpImageList::onSourceLoaded( BOOL success, LLViewerImage *src_vi, LLIma
//---------------------------------------------------
//immediately assign bump to a global smart pointer in case some local smart pointer
//accidently releases it.
- LLPointer<LLImageGL> bump = new LLImageGL( TRUE);
+ LLPointer<LLViewerTexture> bump = LLViewerTextureManager::getLocalTexture( TRUE);
if (!LLPipeline::sRenderDeferred)
{
@@ -1220,7 +1215,7 @@ void LLDrawPoolBump::pushBatch(LLDrawInfo& params, U32 mask, BOOL texture)
{
if (params.mTexture.notNull())
{
- gGL.getTexUnit(diffuse_channel)->bind(params.mTexture.get());
+ gGL.getTexUnit(diffuse_channel)->bind(params.mTexture) ;
params.mTexture->addTextureStats(params.mVSize);
}
else
@@ -1255,7 +1250,7 @@ void LLDrawPoolBump::pushBatch(LLDrawInfo& params, U32 mask, BOOL texture)
void LLDrawPoolInvisible::render(S32 pass)
{ //render invisiprims
- LLFastTimer t(LLFastTimer::FTM_RENDER_INVISIBLE);
+ LLFastTimer t(FTM_RENDER_INVISIBLE);
U32 invisi_mask = LLVertexBuffer::MAP_VERTEX;
glStencilMask(0);
@@ -1284,7 +1279,7 @@ void LLDrawPoolInvisible::endDeferredPass( S32 pass )
void LLDrawPoolInvisible::renderDeferred( S32 pass )
{ //render invisiprims; this doesn't work becaue it also blocks all the post-deferred stuff
- LLFastTimer t(LLFastTimer::FTM_RENDER_INVISIBLE);
+ LLFastTimer t(FTM_RENDER_INVISIBLE);
U32 invisi_mask = LLVertexBuffer::MAP_VERTEX;
glStencilMask(0);
diff --git a/indra/newview/lldrawpoolbump.h b/indra/newview/lldrawpoolbump.h
index 34c1e9c29f..bf940cf1e4 100644
--- a/indra/newview/lldrawpoolbump.h
+++ b/indra/newview/lldrawpoolbump.h
@@ -41,6 +41,7 @@
class LLImageRaw;
class LLSpatialGroup;
class LLDrawInfo;
+class LLViewerFetchedTexture;
class LLDrawPoolBump : public LLRenderPass
{
@@ -110,7 +111,7 @@ public:
LLStandardBumpmap( const std::string& label ) : mLabel(label) {}
std::string mLabel;
- LLPointer<LLViewerImage> mImage;
+ LLPointer<LLViewerFetchedTexture> mImage;
static U32 sStandardBumpmapCount; // Number of valid values in gStandardBumpmapList[]
@@ -140,21 +141,20 @@ public:
void updateImages();
- LLImageGL* getBrightnessDarknessImage(LLViewerImage* src_image, U8 bump_code);
-// LLImageGL* getTestImage();
+ LLViewerTexture* getBrightnessDarknessImage(LLViewerFetchedTexture* src_image, U8 bump_code);
void addTextureStats(U8 bump, const LLUUID& base_image_id, F32 virtual_size);
- static void onSourceBrightnessLoaded( BOOL success, LLViewerImage *src_vi, LLImageRaw* src, LLImageRaw* aux_src, S32 discard_level, BOOL final, void* userdata );
- static void onSourceDarknessLoaded( BOOL success, LLViewerImage *src_vi, LLImageRaw* src, LLImageRaw* aux_src, S32 discard_level, BOOL final, void* userdata );
- static void onSourceStandardLoaded( BOOL success, LLViewerImage *src_vi, LLImageRaw* src, LLImageRaw* aux_src, S32 discard_level, BOOL final, void* userdata );
+ static void onSourceBrightnessLoaded( BOOL success, LLViewerFetchedTexture *src_vi, LLImageRaw* src, LLImageRaw* aux_src, S32 discard_level, BOOL final, void* userdata );
+ static void onSourceDarknessLoaded( BOOL success, LLViewerFetchedTexture *src_vi, LLImageRaw* src, LLImageRaw* aux_src, S32 discard_level, BOOL final, void* userdata );
+ static void onSourceStandardLoaded( BOOL success, LLViewerFetchedTexture *src_vi, LLImageRaw* src, LLImageRaw* aux_src, S32 discard_level, BOOL final, void* userdata );
static void generateNormalMapFromAlpha(LLImageRaw* src, LLImageRaw* nrm_image);
private:
- static void onSourceLoaded( BOOL success, LLViewerImage *src_vi, LLImageRaw* src, LLUUID& source_asset_id, EBumpEffect bump );
+ static void onSourceLoaded( BOOL success, LLViewerTexture *src_vi, LLImageRaw* src, LLUUID& source_asset_id, EBumpEffect bump );
private:
- typedef std::map<LLUUID, LLPointer<LLImageGL> > bump_image_map_t;
+ typedef std::map<LLUUID, LLPointer<LLViewerTexture> > bump_image_map_t;
bump_image_map_t mBrightnessEntries;
bump_image_map_t mDarknessEntries;
};
diff --git a/indra/newview/lldrawpoolsimple.cpp b/indra/newview/lldrawpoolsimple.cpp
index 1fdf87f6d2..331536fdca 100644
--- a/indra/newview/lldrawpoolsimple.cpp
+++ b/indra/newview/lldrawpoolsimple.cpp
@@ -35,7 +35,6 @@
#include "lldrawpoolsimple.h"
#include "llviewercamera.h"
-#include "llagent.h"
#include "lldrawable.h"
#include "llface.h"
#include "llsky.h"
@@ -50,7 +49,7 @@ static LLGLSLShader* fullbright_shader = NULL;
void LLDrawPoolGlow::render(S32 pass)
{
- LLFastTimer t(LLFastTimer::FTM_RENDER_GLOW);
+ LLFastTimer t(FTM_RENDER_GLOW);
LLGLEnable blend(GL_BLEND);
LLGLDisable test(GL_ALPHA_TEST);
gGL.setSceneBlendType(LLRender::BT_ADD);
@@ -98,7 +97,7 @@ void LLDrawPoolSimple::prerender()
void LLDrawPoolSimple::beginRenderPass(S32 pass)
{
- LLFastTimer t(LLFastTimer::FTM_RENDER_SIMPLE);
+ LLFastTimer t(FTM_RENDER_SIMPLE);
if (LLPipeline::sUnderWaterRender)
{
@@ -125,7 +124,7 @@ void LLDrawPoolSimple::beginRenderPass(S32 pass)
void LLDrawPoolSimple::endRenderPass(S32 pass)
{
- LLFastTimer t(LLFastTimer::FTM_RENDER_SIMPLE);
+ LLFastTimer t(FTM_RENDER_SIMPLE);
LLRenderPass::endRenderPass(pass);
if (mVertexShaderLevel > 0){
@@ -140,7 +139,7 @@ void LLDrawPoolSimple::render(S32 pass)
LLGLDisable alpha_test(GL_ALPHA_TEST);
{ //render simple
- LLFastTimer t(LLFastTimer::FTM_RENDER_SIMPLE);
+ LLFastTimer t(FTM_RENDER_SIMPLE);
gPipeline.enableLightsDynamic();
renderTexture(LLRenderPass::PASS_SIMPLE, getVertexDataMask());
@@ -157,13 +156,13 @@ void LLDrawPoolSimple::render(S32 pass)
void LLDrawPoolSimple::beginDeferredPass(S32 pass)
{
- LLFastTimer t(LLFastTimer::FTM_RENDER_SIMPLE);
+ LLFastTimer t(FTM_RENDER_SIMPLE);
gDeferredDiffuseProgram.bind();
}
void LLDrawPoolSimple::endDeferredPass(S32 pass)
{
- LLFastTimer t(LLFastTimer::FTM_RENDER_SIMPLE);
+ LLFastTimer t(FTM_RENDER_SIMPLE);
LLRenderPass::endRenderPass(pass);
gDeferredDiffuseProgram.unbind();
@@ -175,7 +174,7 @@ void LLDrawPoolSimple::renderDeferred(S32 pass)
LLGLDisable alpha_test(GL_ALPHA_TEST);
{ //render simple
- LLFastTimer t(LLFastTimer::FTM_RENDER_SIMPLE);
+ LLFastTimer t(FTM_RENDER_SIMPLE);
renderTexture(LLRenderPass::PASS_SIMPLE, getVertexDataMask());
}
}
@@ -195,7 +194,7 @@ void LLDrawPoolGrass::prerender()
void LLDrawPoolGrass::beginRenderPass(S32 pass)
{
- LLFastTimer t(LLFastTimer::FTM_RENDER_GRASS);
+ LLFastTimer t(FTM_RENDER_GRASS);
if (LLPipeline::sUnderWaterRender)
{
@@ -222,7 +221,7 @@ void LLDrawPoolGrass::beginRenderPass(S32 pass)
void LLDrawPoolGrass::endRenderPass(S32 pass)
{
- LLFastTimer t(LLFastTimer::FTM_RENDER_GRASS);
+ LLFastTimer t(FTM_RENDER_GRASS);
LLRenderPass::endRenderPass(pass);
if (mVertexShaderLevel > 0)
@@ -237,7 +236,7 @@ void LLDrawPoolGrass::render(S32 pass)
gGL.setAlphaRejectSettings(LLRender::CF_GREATER, 0.5f);
{
- LLFastTimer t(LLFastTimer::FTM_RENDER_GRASS);
+ LLFastTimer t(FTM_RENDER_GRASS);
LLGLEnable test(GL_ALPHA_TEST);
gGL.setSceneBlendType(LLRender::BT_ALPHA);
//render grass
@@ -262,7 +261,7 @@ void LLDrawPoolGrass::renderDeferred(S32 pass)
gGL.setAlphaRejectSettings(LLRender::CF_GREATER, 0.5f);
{
- LLFastTimer t(LLFastTimer::FTM_RENDER_GRASS);
+ LLFastTimer t(FTM_RENDER_GRASS);
gDeferredTreeProgram.bind();
LLGLEnable test(GL_ALPHA_TEST);
//render grass
@@ -286,7 +285,7 @@ void LLDrawPoolFullbright::prerender()
void LLDrawPoolFullbright::beginRenderPass(S32 pass)
{
- LLFastTimer t(LLFastTimer::FTM_RENDER_FULLBRIGHT);
+ LLFastTimer t(FTM_RENDER_FULLBRIGHT);
if (LLPipeline::sUnderWaterRender)
{
@@ -300,7 +299,7 @@ void LLDrawPoolFullbright::beginRenderPass(S32 pass)
void LLDrawPoolFullbright::endRenderPass(S32 pass)
{
- LLFastTimer t(LLFastTimer::FTM_RENDER_FULLBRIGHT);
+ LLFastTimer t(FTM_RENDER_FULLBRIGHT);
LLRenderPass::endRenderPass(pass);
if (mVertexShaderLevel > 0)
@@ -311,7 +310,7 @@ void LLDrawPoolFullbright::endRenderPass(S32 pass)
void LLDrawPoolFullbright::render(S32 pass)
{ //render fullbright
- LLFastTimer t(LLFastTimer::FTM_RENDER_FULLBRIGHT);
+ LLFastTimer t(FTM_RENDER_FULLBRIGHT);
if (mVertexShaderLevel > 0)
{
fullbright_shader->bind();
diff --git a/indra/newview/lldrawpoolsky.cpp b/indra/newview/lldrawpoolsky.cpp
index f0ed38057b..8428be194f 100644
--- a/indra/newview/lldrawpoolsky.cpp
+++ b/indra/newview/lldrawpoolsky.cpp
@@ -41,9 +41,8 @@
#include "llface.h"
#include "llsky.h"
#include "llviewercamera.h"
-#include "llviewerimagelist.h"
+#include "llviewertexturelist.h"
#include "llviewerregion.h"
-#include "llviewerwindow.h"
#include "llvosky.h"
#include "llworld.h" // To get water height
#include "pipeline.h"
diff --git a/indra/newview/lldrawpoolterrain.cpp b/indra/newview/lldrawpoolterrain.cpp
index 2c644b0fd5..345dd6bb84 100644
--- a/indra/newview/lldrawpoolterrain.cpp
+++ b/indra/newview/lldrawpoolterrain.cpp
@@ -49,7 +49,7 @@
#include "llviewerparceloverlay.h"
#include "llvosurfacepatch.h"
#include "llviewercamera.h"
-#include "llviewerimagelist.h" // To get alpha gradients
+#include "llviewertexturelist.h" // To get alpha gradients
#include "llworld.h"
#include "pipeline.h"
#include "llviewershadermgr.h"
@@ -61,29 +61,35 @@ int DebugDetailMap = 0;
S32 LLDrawPoolTerrain::sDetailMode = 1;
F32 LLDrawPoolTerrain::sDetailScale = DETAIL_SCALE;
static LLGLSLShader* sShader = NULL;
+static LLFastTimer::DeclareTimer FTM_SHADOW_TERRAIN("Terrain Shadow");
-LLDrawPoolTerrain::LLDrawPoolTerrain(LLViewerImage *texturep) :
+
+LLDrawPoolTerrain::LLDrawPoolTerrain(LLViewerTexture *texturep) :
LLFacePool(POOL_TERRAIN),
mTexturep(texturep)
{
// Hack!
sDetailScale = 1.f/gSavedSettings.getF32("RenderTerrainScale");
sDetailMode = gSavedSettings.getS32("RenderTerrainDetail");
- mAlphaRampImagep = gImageList.getImageFromFile("alpha_gradient.tga",
- TRUE, TRUE, GL_ALPHA8, GL_ALPHA,
+ mAlphaRampImagep = LLViewerTextureManager::getFetchedTextureFromFile("alpha_gradient.tga",
+ TRUE, TRUE,
+ LLViewerTexture::FETCHED_TEXTURE,
+ GL_ALPHA8, GL_ALPHA,
LLUUID("e97cf410-8e61-7005-ec06-629eba4cd1fb"));
- gGL.getTexUnit(0)->bind(mAlphaRampImagep.get());
+ gGL.getTexUnit(0)->bind(mAlphaRampImagep);
mAlphaRampImagep->setAddressMode(LLTexUnit::TAM_CLAMP);
- m2DAlphaRampImagep = gImageList.getImageFromFile("alpha_gradient_2d.j2c",
- TRUE, TRUE, GL_ALPHA8, GL_ALPHA,
+ m2DAlphaRampImagep = LLViewerTextureManager::getFetchedTextureFromFile("alpha_gradient_2d.j2c",
+ TRUE, TRUE,
+ LLViewerTexture::FETCHED_TEXTURE,
+ GL_ALPHA8, GL_ALPHA,
LLUUID("38b86f85-2575-52a9-a531-23108d8da837"));
- gGL.getTexUnit(0)->bind(m2DAlphaRampImagep.get());
+ gGL.getTexUnit(0)->bind(m2DAlphaRampImagep);
m2DAlphaRampImagep->setAddressMode(LLTexUnit::TAM_CLAMP);
- mTexturep->setBoostLevel(LLViewerImage::BOOST_TERRAIN);
+ mTexturep->setBoostLevel(LLViewerTexture::BOOST_TERRAIN);
gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
}
@@ -127,7 +133,7 @@ void LLDrawPoolTerrain::prerender()
void LLDrawPoolTerrain::beginRenderPass( S32 pass )
{
- LLFastTimer t(LLFastTimer::FTM_RENDER_TERRAIN);
+ LLFastTimer t(FTM_RENDER_TERRAIN);
LLFacePool::beginRenderPass(pass);
sShader = LLPipeline::sUnderWaterRender ?
@@ -142,7 +148,7 @@ void LLDrawPoolTerrain::beginRenderPass( S32 pass )
void LLDrawPoolTerrain::endRenderPass( S32 pass )
{
- LLFastTimer t(LLFastTimer::FTM_RENDER_TERRAIN);
+ LLFastTimer t(FTM_RENDER_TERRAIN);
LLFacePool::endRenderPass(pass);
if (mVertexShaderLevel > 1 && sShader->mShaderLevel > 0) {
@@ -158,7 +164,7 @@ S32 LLDrawPoolTerrain::getDetailMode()
void LLDrawPoolTerrain::render(S32 pass)
{
- LLFastTimer t(LLFastTimer::FTM_RENDER_TERRAIN);
+ LLFastTimer t(FTM_RENDER_TERRAIN);
if (mDrawFace.empty())
{
@@ -170,7 +176,7 @@ void LLDrawPoolTerrain::render(S32 pass)
LLVLComposition *compp = regionp->getComposition();
for (S32 i = 0; i < 4; i++)
{
- compp->mDetailTextures[i]->setBoostLevel(LLViewerImage::BOOST_TERRAIN);
+ compp->mDetailTextures[i]->setBoostLevel(LLViewerTexture::BOOST_TERRAIN);
compp->mDetailTextures[i]->addTextureStats(1024.f*1024.f); // assume large pixel area
}
@@ -231,7 +237,7 @@ void LLDrawPoolTerrain::render(S32 pass)
void LLDrawPoolTerrain::beginDeferredPass(S32 pass)
{
- LLFastTimer t(LLFastTimer::FTM_RENDER_TERRAIN);
+ LLFastTimer t(FTM_RENDER_TERRAIN);
LLFacePool::beginRenderPass(pass);
sShader = &gDeferredTerrainProgram;
@@ -241,14 +247,14 @@ void LLDrawPoolTerrain::beginDeferredPass(S32 pass)
void LLDrawPoolTerrain::endDeferredPass(S32 pass)
{
- LLFastTimer t(LLFastTimer::FTM_RENDER_TERRAIN);
+ LLFastTimer t(FTM_RENDER_TERRAIN);
LLFacePool::endRenderPass(pass);
sShader->unbind();
}
void LLDrawPoolTerrain::renderDeferred(S32 pass)
{
- LLFastTimer t(LLFastTimer::FTM_RENDER_TERRAIN);
+ LLFastTimer t(FTM_RENDER_TERRAIN);
if (mDrawFace.empty())
{
return;
@@ -258,7 +264,7 @@ void LLDrawPoolTerrain::renderDeferred(S32 pass)
void LLDrawPoolTerrain::beginShadowPass(S32 pass)
{
- LLFastTimer t(LLFastTimer::FTM_SHADOW_TERRAIN);
+ LLFastTimer t(FTM_SHADOW_TERRAIN);
LLFacePool::beginRenderPass(pass);
gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
gDeferredShadowProgram.bind();
@@ -266,14 +272,14 @@ void LLDrawPoolTerrain::beginShadowPass(S32 pass)
void LLDrawPoolTerrain::endShadowPass(S32 pass)
{
- LLFastTimer t(LLFastTimer::FTM_SHADOW_TERRAIN);
+ LLFastTimer t(FTM_SHADOW_TERRAIN);
LLFacePool::endRenderPass(pass);
gDeferredShadowProgram.unbind();
}
void LLDrawPoolTerrain::renderShadow(S32 pass)
{
- LLFastTimer t(LLFastTimer::FTM_SHADOW_TERRAIN);
+ LLFastTimer t(FTM_SHADOW_TERRAIN);
if (mDrawFace.empty())
{
return;
@@ -289,10 +295,10 @@ void LLDrawPoolTerrain::renderFullShader()
// Hack! Get the region that this draw pool is rendering from!
LLViewerRegion *regionp = mDrawFace[0]->getDrawable()->getVObj()->getRegion();
LLVLComposition *compp = regionp->getComposition();
- LLViewerImage *detail_texture0p = compp->mDetailTextures[0];
- LLViewerImage *detail_texture1p = compp->mDetailTextures[1];
- LLViewerImage *detail_texture2p = compp->mDetailTextures[2];
- LLViewerImage *detail_texture3p = compp->mDetailTextures[3];
+ LLViewerTexture *detail_texture0p = compp->mDetailTextures[0];
+ LLViewerTexture *detail_texture1p = compp->mDetailTextures[1];
+ LLViewerTexture *detail_texture2p = compp->mDetailTextures[2];
+ LLViewerTexture *detail_texture3p = compp->mDetailTextures[3];
LLVector3d region_origin_global = gAgent.getRegion()->getOriginGlobal();
F32 offset_x = (F32)fmod(region_origin_global.mdV[VX], 1.0/(F64)sDetailScale)*sDetailScale;
@@ -363,7 +369,7 @@ void LLDrawPoolTerrain::renderFullShader()
// Alpha Ramp
//
S32 alpha_ramp = sShader->enableTexture(LLViewerShaderMgr::TERRAIN_ALPHARAMP);
- gGL.getTexUnit(alpha_ramp)->bind(m2DAlphaRampImagep.get());
+ gGL.getTexUnit(alpha_ramp)->bind(m2DAlphaRampImagep);
// GL_BLEND disabled by default
drawLoop();
@@ -429,10 +435,10 @@ void LLDrawPoolTerrain::renderFull4TU()
// Hack! Get the region that this draw pool is rendering from!
LLViewerRegion *regionp = mDrawFace[0]->getDrawable()->getVObj()->getRegion();
LLVLComposition *compp = regionp->getComposition();
- LLViewerImage *detail_texture0p = compp->mDetailTextures[0];
- LLViewerImage *detail_texture1p = compp->mDetailTextures[1];
- LLViewerImage *detail_texture2p = compp->mDetailTextures[2];
- LLViewerImage *detail_texture3p = compp->mDetailTextures[3];
+ LLViewerTexture *detail_texture0p = compp->mDetailTextures[0];
+ LLViewerTexture *detail_texture1p = compp->mDetailTextures[1];
+ LLViewerTexture *detail_texture2p = compp->mDetailTextures[2];
+ LLViewerTexture *detail_texture3p = compp->mDetailTextures[3];
LLVector3d region_origin_global = gAgent.getRegion()->getOriginGlobal();
F32 offset_x = (F32)fmod(region_origin_global.mdV[VX], 1.0/(F64)sDetailScale)*sDetailScale;
@@ -527,7 +533,7 @@ void LLDrawPoolTerrain::renderFull4TU()
//
// Stage 1: Generate alpha ramp for detail2/detail3 transition
//
- gGL.getTexUnit(1)->bind(m2DAlphaRampImagep.get());
+ gGL.getTexUnit(1)->bind(m2DAlphaRampImagep);
gGL.getTexUnit(1)->enable(LLTexUnit::TT_TEXTURE);
gGL.getTexUnit(1)->activate();
@@ -559,7 +565,7 @@ void LLDrawPoolTerrain::renderFull4TU()
//
// Stage 3: Generate alpha ramp for detail1/detail2 transition
//
- gGL.getTexUnit(3)->bind(m2DAlphaRampImagep.get());
+ gGL.getTexUnit(3)->bind(m2DAlphaRampImagep);
gGL.getTexUnit(3)->enable(LLTexUnit::TT_TEXTURE);
gGL.getTexUnit(3)->activate();
@@ -630,10 +636,10 @@ void LLDrawPoolTerrain::renderFull2TU()
// Hack! Get the region that this draw pool is rendering from!
LLViewerRegion *regionp = mDrawFace[0]->getDrawable()->getVObj()->getRegion();
LLVLComposition *compp = regionp->getComposition();
- LLViewerImage *detail_texture0p = compp->mDetailTextures[0];
- LLViewerImage *detail_texture1p = compp->mDetailTextures[1];
- LLViewerImage *detail_texture2p = compp->mDetailTextures[2];
- LLViewerImage *detail_texture3p = compp->mDetailTextures[3];
+ LLViewerTexture *detail_texture0p = compp->mDetailTextures[0];
+ LLViewerTexture *detail_texture1p = compp->mDetailTextures[1];
+ LLViewerTexture *detail_texture2p = compp->mDetailTextures[2];
+ LLViewerTexture *detail_texture3p = compp->mDetailTextures[3];
LLVector3d region_origin_global = gAgent.getRegion()->getOriginGlobal();
F32 offset_x = (F32)fmod(region_origin_global.mdV[VX], 1.0/(F64)sDetailScale)*sDetailScale;
@@ -671,7 +677,7 @@ void LLDrawPoolTerrain::renderFull2TU()
//
// Stage 0: Generate alpha ramp for detail0/detail1 transition
//
- gGL.getTexUnit(0)->bind(m2DAlphaRampImagep.get());
+ gGL.getTexUnit(0)->bind(m2DAlphaRampImagep);
glDisable(GL_TEXTURE_GEN_S);
glDisable(GL_TEXTURE_GEN_T);
@@ -709,7 +715,7 @@ void LLDrawPoolTerrain::renderFull2TU()
//
// Stage 0: Generate alpha ramp for detail1/detail2 transition
//
- gGL.getTexUnit(0)->bind(m2DAlphaRampImagep.get());
+ gGL.getTexUnit(0)->bind(m2DAlphaRampImagep);
// Set the texture matrix
glMatrixMode(GL_TEXTURE);
@@ -749,7 +755,7 @@ void LLDrawPoolTerrain::renderFull2TU()
// Stage 0: Generate alpha ramp for detail2/detail3 transition
//
gGL.getTexUnit(0)->activate();
- gGL.getTexUnit(0)->bind(m2DAlphaRampImagep.get());
+ gGL.getTexUnit(0)->bind(m2DAlphaRampImagep);
// Set the texture matrix
glMatrixMode(GL_TEXTURE);
glLoadIdentity();
@@ -822,7 +828,7 @@ void LLDrawPoolTerrain::renderSimple()
gGL.getTexUnit(0)->activate();
gGL.getTexUnit(0)->enable(LLTexUnit::TT_TEXTURE);
- gGL.getTexUnit(0)->bind(mTexturep.get());
+ gGL.getTexUnit(0)->bind(mTexturep);
LLVector3 origin_agent = mDrawFace[0]->getDrawable()->getVObj()->getRegion()->getOriginAgent();
F32 tscale = 1.f/256.f;
@@ -872,7 +878,7 @@ void LLDrawPoolTerrain::renderOwnership()
LLSurface *surfacep = surface_patchp->getSurface();
LLViewerRegion *regionp = surfacep->getRegion();
LLViewerParcelOverlay *overlayp = regionp->getParcelOverlay();
- LLImageGL *texturep = overlayp->getTexture();
+ LLViewerTexture *texturep = overlayp->getTexture();
gGL.getTexUnit(0)->bind(texturep);
@@ -920,9 +926,10 @@ void LLDrawPoolTerrain::renderForSelect()
}
}
-void LLDrawPoolTerrain::dirtyTextures(const std::set<LLViewerImage*>& textures)
+void LLDrawPoolTerrain::dirtyTextures(const std::set<LLViewerFetchedTexture*>& textures)
{
- if (textures.find(mTexturep) != textures.end())
+ LLViewerFetchedTexture* tex = LLViewerTextureManager::staticCastToFetchedTexture(mTexturep) ;
+ if (tex && textures.find(tex) != textures.end())
{
for (std::vector<LLFace*>::iterator iter = mReferences.begin();
iter != mReferences.end(); iter++)
@@ -933,12 +940,12 @@ void LLDrawPoolTerrain::dirtyTextures(const std::set<LLViewerImage*>& textures)
}
}
-LLViewerImage *LLDrawPoolTerrain::getTexture()
+LLViewerTexture *LLDrawPoolTerrain::getTexture()
{
return mTexturep;
}
-LLViewerImage *LLDrawPoolTerrain::getDebugTexture()
+LLViewerTexture *LLDrawPoolTerrain::getDebugTexture()
{
return mTexturep;
}
diff --git a/indra/newview/lldrawpoolterrain.h b/indra/newview/lldrawpoolterrain.h
index 19d09e2feb..2e2a36d533 100644
--- a/indra/newview/lldrawpoolterrain.h
+++ b/indra/newview/lldrawpoolterrain.h
@@ -37,7 +37,7 @@
class LLDrawPoolTerrain : public LLFacePool
{
- LLPointer<LLViewerImage> mTexturep;
+ LLPointer<LLViewerTexture> mTexturep;
public:
enum
{
@@ -53,7 +53,7 @@ public:
virtual U32 getVertexDataMask();
static S32 getDetailMode();
- LLDrawPoolTerrain(LLViewerImage *texturep);
+ LLDrawPoolTerrain(LLViewerTexture *texturep);
virtual ~LLDrawPoolTerrain();
/*virtual*/ LLDrawPool *instancePool();
@@ -73,14 +73,14 @@ public:
/*virtual*/ void beginRenderPass( S32 pass );
/*virtual*/ void endRenderPass( S32 pass );
/*virtual*/ void renderForSelect();
- /*virtual*/ void dirtyTextures(const std::set<LLViewerImage*>& textures);
- /*virtual*/ LLViewerImage *getTexture();
- /*virtual*/ LLViewerImage *getDebugTexture();
+ /*virtual*/ void dirtyTextures(const std::set<LLViewerFetchedTexture*>& textures);
+ /*virtual*/ LLViewerTexture *getTexture();
+ /*virtual*/ LLViewerTexture *getDebugTexture();
/*virtual*/ LLColor3 getDebugColor() const; // For AGP debug display
- LLPointer<LLViewerImage> mAlphaRampImagep;
- LLPointer<LLViewerImage> m2DAlphaRampImagep;
- LLPointer<LLViewerImage> mAlphaNoiseImagep;
+ LLPointer<LLViewerTexture> mAlphaRampImagep;
+ LLPointer<LLViewerTexture> m2DAlphaRampImagep;
+ LLPointer<LLViewerTexture> mAlphaNoiseImagep;
static S32 sDetailMode;
static F32 sDetailScale; // meters per texture
diff --git a/indra/newview/lldrawpooltree.cpp b/indra/newview/lldrawpooltree.cpp
index 2f2b07232a..5cb1fcb635 100644
--- a/indra/newview/lldrawpooltree.cpp
+++ b/indra/newview/lldrawpooltree.cpp
@@ -37,7 +37,6 @@
#include "lldrawable.h"
#include "llface.h"
#include "llsky.h"
-#include "llviewerwindow.h"
#include "llvotree.h"
#include "pipeline.h"
#include "llviewercamera.h"
@@ -47,12 +46,13 @@
S32 LLDrawPoolTree::sDiffTex = 0;
static LLGLSLShader* shader = NULL;
+static LLFastTimer::DeclareTimer FTM_SHADOW_TREE("Tree Shadow");
-LLDrawPoolTree::LLDrawPoolTree(LLViewerImage *texturep) :
+LLDrawPoolTree::LLDrawPoolTree(LLViewerTexture *texturep) :
LLFacePool(POOL_TREE),
mTexturep(texturep)
{
- gGL.getTexUnit(0)->bind(mTexturep.get());
+ gGL.getTexUnit(0)->bind(mTexturep);
mTexturep->setAddressMode(LLTexUnit::TAM_WRAP);
}
@@ -68,7 +68,7 @@ void LLDrawPoolTree::prerender()
void LLDrawPoolTree::beginRenderPass(S32 pass)
{
- LLFastTimer t(LLFastTimer::FTM_RENDER_TREES);
+ LLFastTimer t(FTM_RENDER_TREES);
gGL.setAlphaRejectSettings(LLRender::CF_GREATER, 0.5f);
if (LLPipeline::sUnderWaterRender)
@@ -92,7 +92,7 @@ void LLDrawPoolTree::beginRenderPass(S32 pass)
void LLDrawPoolTree::render(S32 pass)
{
- LLFastTimer t(LLPipeline::sShadowRender ? LLFastTimer::FTM_SHADOW_TREE : LLFastTimer::FTM_RENDER_TREES);
+ LLFastTimer t(LLPipeline::sShadowRender ? FTM_SHADOW_TREE : FTM_RENDER_TREES);
if (mDrawFace.empty())
{
@@ -123,7 +123,7 @@ void LLDrawPoolTree::render(S32 pass)
void LLDrawPoolTree::endRenderPass(S32 pass)
{
- LLFastTimer t(LLFastTimer::FTM_RENDER_TREES);
+ LLFastTimer t(FTM_RENDER_TREES);
gGL.setAlphaRejectSettings(LLRender::CF_DEFAULT);
if (gPipeline.canUseWindLightShadersOnObjects())
@@ -137,7 +137,7 @@ void LLDrawPoolTree::endRenderPass(S32 pass)
//============================================
void LLDrawPoolTree::beginDeferredPass(S32 pass)
{
- LLFastTimer t(LLFastTimer::FTM_RENDER_TREES);
+ LLFastTimer t(FTM_RENDER_TREES);
gGL.setAlphaRejectSettings(LLRender::CF_GREATER, 0.5f);
shader = &gDeferredTreeProgram;
@@ -151,7 +151,7 @@ void LLDrawPoolTree::renderDeferred(S32 pass)
void LLDrawPoolTree::endDeferredPass(S32 pass)
{
- LLFastTimer t(LLFastTimer::FTM_RENDER_TREES);
+ LLFastTimer t(FTM_RENDER_TREES);
gGL.setAlphaRejectSettings(LLRender::CF_DEFAULT);
shader->unbind();
@@ -162,7 +162,7 @@ void LLDrawPoolTree::endDeferredPass(S32 pass)
//============================================
void LLDrawPoolTree::beginShadowPass(S32 pass)
{
- LLFastTimer t(LLFastTimer::FTM_SHADOW_TREE);
+ LLFastTimer t(FTM_SHADOW_TREE);
gGL.setAlphaRejectSettings(LLRender::CF_GREATER, 0.5f);
gDeferredShadowProgram.bind();
}
@@ -174,7 +174,7 @@ void LLDrawPoolTree::renderShadow(S32 pass)
void LLDrawPoolTree::endShadowPass(S32 pass)
{
- LLFastTimer t(LLFastTimer::FTM_SHADOW_TREE);
+ LLFastTimer t(FTM_SHADOW_TREE);
gGL.setAlphaRejectSettings(LLRender::CF_DEFAULT);
gDeferredShadowProgram.unbind();
}
@@ -247,7 +247,7 @@ void LLDrawPoolTree::renderTree(BOOL selecting)
LLGLState normalize(GL_NORMALIZE, TRUE);
// Bind the texture for this tree.
- gGL.getTexUnit(sDiffTex)->bind(mTexturep.get());
+ gGL.getTexUnit(sDiffTex)->bind(mTexturep);
U32 indices_drawn = 0;
@@ -377,12 +377,12 @@ BOOL LLDrawPoolTree::verify() const
return TRUE;
}
-LLViewerImage *LLDrawPoolTree::getTexture()
+LLViewerTexture *LLDrawPoolTree::getTexture()
{
return mTexturep;
}
-LLViewerImage *LLDrawPoolTree::getDebugTexture()
+LLViewerTexture *LLDrawPoolTree::getDebugTexture()
{
return mTexturep;
}
diff --git a/indra/newview/lldrawpooltree.h b/indra/newview/lldrawpooltree.h
index 80c4fdfffe..bc7711d4e8 100644
--- a/indra/newview/lldrawpooltree.h
+++ b/indra/newview/lldrawpooltree.h
@@ -37,7 +37,7 @@
class LLDrawPoolTree : public LLFacePool
{
- LLPointer<LLViewerImage> mTexturep;
+ LLPointer<LLViewerTexture> mTexturep;
public:
enum
{
@@ -48,7 +48,7 @@ public:
virtual U32 getVertexDataMask() { return VERTEX_DATA_MASK; }
- LLDrawPoolTree(LLViewerImage *texturep);
+ LLDrawPoolTree(LLViewerTexture *texturep);
/*virtual*/ LLDrawPool *instancePool();
@@ -70,8 +70,8 @@ public:
/*virtual*/ S32 getNumPasses() { return 1; }
/*virtual*/ void renderForSelect();
/*virtual*/ BOOL verify() const;
- /*virtual*/ LLViewerImage *getTexture();
- /*virtual*/ LLViewerImage *getDebugTexture();
+ /*virtual*/ LLViewerTexture *getTexture();
+ /*virtual*/ LLViewerTexture *getDebugTexture();
/*virtual*/ LLColor3 getDebugColor() const; // For AGP debug display
static S32 sDiffTex;
diff --git a/indra/newview/lldrawpoolwater.cpp b/indra/newview/lldrawpoolwater.cpp
index ce3425dd9e..fd4dc123d5 100644
--- a/indra/newview/lldrawpoolwater.cpp
+++ b/indra/newview/lldrawpoolwater.cpp
@@ -45,8 +45,7 @@
#include "lldrawable.h"
#include "llface.h"
#include "llsky.h"
-#include "llviewercamera.h" // to get OGL_TO_CFR_ROTATION
-#include "llviewerimagelist.h"
+#include "llviewertexturelist.h"
#include "llviewerregion.h"
#include "llvosky.h"
#include "llvowater.h"
@@ -70,17 +69,17 @@ LLVector3 LLDrawPoolWater::sLightDir;
LLDrawPoolWater::LLDrawPoolWater() :
LLFacePool(POOL_WATER)
{
- mHBTex[0] = gImageList.getImage(gSunTextureID, TRUE, TRUE);
- gGL.getTexUnit(0)->bind(mHBTex[0].get());
+ mHBTex[0] = LLViewerTextureManager::getFetchedTexture(gSunTextureID, TRUE, TRUE);
+ gGL.getTexUnit(0)->bind(mHBTex[0]) ;
mHBTex[0]->setAddressMode(LLTexUnit::TAM_CLAMP);
- mHBTex[1] = gImageList.getImage(gMoonTextureID, TRUE, TRUE);
- gGL.getTexUnit(0)->bind(mHBTex[1].get());
+ mHBTex[1] = LLViewerTextureManager::getFetchedTexture(gMoonTextureID, TRUE, TRUE);
+ gGL.getTexUnit(0)->bind(mHBTex[1]);
mHBTex[1]->setAddressMode(LLTexUnit::TAM_CLAMP);
- mWaterImagep = gImageList.getImage(WATER_TEST);
+ mWaterImagep = LLViewerTextureManager::getFetchedTexture(WATER_TEST);
mWaterImagep->setNoDelete() ;
- mWaterNormp = gImageList.getImage(DEFAULT_WATER_NORMAL);
+ mWaterNormp = LLViewerTextureManager::getFetchedTexture(DEFAULT_WATER_NORMAL);
mWaterNormp->setNoDelete() ;
restoreGL();
@@ -139,7 +138,7 @@ void LLDrawPoolWater::endPostDeferredPass(S32 pass)
void LLDrawPoolWater::render(S32 pass)
{
- LLFastTimer ftm(LLFastTimer::FTM_RENDER_WATER);
+ LLFastTimer ftm(FTM_RENDER_WATER);
if (mDrawFace.empty() || LLDrawable::getCurrentFrame() <= 1)
{
return;
@@ -185,7 +184,7 @@ void LLDrawPoolWater::render(S32 pass)
mWaterImagep->addTextureStats(1024.f*1024.f);
gGL.getTexUnit(1)->activate();
gGL.getTexUnit(1)->enable(LLTexUnit::TT_TEXTURE);
- gGL.getTexUnit(1)->bind(mWaterImagep.get());
+ gGL.getTexUnit(1)->bind(mWaterImagep) ;
LLVector3 camera_up = LLViewerCamera::getInstance()->getUpAxis();
F32 up_dot = camera_up * LLVector3::z_axis;
@@ -330,7 +329,7 @@ void LLDrawPoolWater::renderReflection(LLFace* face)
LLGLSNoFog noFog;
- gGL.getTexUnit(0)->bind(mHBTex[dr].get());
+ gGL.getTexUnit(0)->bind(mHBTex[dr]);
LLOverrideFaceColor override(this, face->getFaceColor().mV);
face->renderIndexed();
@@ -420,11 +419,11 @@ void LLDrawPoolWater::shade()
// change mWaterNormp if needed
if (mWaterNormp->getID() != param_mgr->getNormalMapID())
{
- mWaterNormp = gImageList.getImage(param_mgr->getNormalMapID());
+ mWaterNormp = LLViewerTextureManager::getFetchedTexture(param_mgr->getNormalMapID());
}
mWaterNormp->addTextureStats(1024.f*1024.f);
- gGL.getTexUnit(bumpTex)->bind(mWaterNormp.get());
+ gGL.getTexUnit(bumpTex)->bind(mWaterNormp) ;
if (gSavedSettings.getBOOL("RenderWaterMipNormal"))
{
mWaterNormp->setFilteringOption(LLTexUnit::TFO_ANISOTROPIC);
@@ -588,20 +587,9 @@ void LLDrawPoolWater::renderForSelect()
return;
}
-
-void LLDrawPoolWater::renderFaceSelected(LLFace *facep,
- LLImageGL *image,
- const LLColor4 &color,
- const S32 index_offset, const S32 index_count)
-{
- // Can't select water
- return;
-}
-
-
-LLViewerImage *LLDrawPoolWater::getDebugTexture()
+LLViewerTexture *LLDrawPoolWater::getDebugTexture()
{
- return LLViewerImage::sSmokeImagep;
+ return LLViewerFetchedTexture::sSmokeImagep;
}
LLColor3 LLDrawPoolWater::getDebugColor() const
diff --git a/indra/newview/lldrawpoolwater.h b/indra/newview/lldrawpoolwater.h
index 6351041140..e28ac1cfab 100644
--- a/indra/newview/lldrawpoolwater.h
+++ b/indra/newview/lldrawpoolwater.h
@@ -43,9 +43,9 @@ class LLWaterSurface;
class LLDrawPoolWater: public LLFacePool
{
protected:
- LLPointer<LLViewerImage> mHBTex[2];
- LLPointer<LLViewerImage> mWaterImagep;
- LLPointer<LLViewerImage> mWaterNormp;
+ LLPointer<LLViewerTexture> mHBTex[2];
+ LLPointer<LLViewerTexture> mWaterImagep;
+ LLPointer<LLViewerTexture> mWaterNormp;
const LLWaterSurface *mWaterSurface;
public:
@@ -78,12 +78,10 @@ public:
/*virtual*/ S32 getNumPasses();
/*virtual*/ void render(S32 pass = 0);
- /*virtual*/ void renderFaceSelected(LLFace *facep, LLImageGL *image, const LLColor4 &color,
- const S32 index_offset = 0, const S32 index_count = 0);
/*virtual*/ void prerender();
/*virtual*/ void renderForSelect();
- /*virtual*/ LLViewerImage *getDebugTexture();
+ /*virtual*/ LLViewerTexture *getDebugTexture();
/*virtual*/ LLColor3 getDebugColor() const; // For AGP debug display
void renderReflection(LLFace* face);
diff --git a/indra/newview/lldrawpoolwlsky.cpp b/indra/newview/lldrawpoolwlsky.cpp
index 6ff65c7ed0..c14ca2473b 100644
--- a/indra/newview/lldrawpoolwlsky.cpp
+++ b/indra/newview/lldrawpoolwlsky.cpp
@@ -42,12 +42,11 @@
#include "llwlparammanager.h"
#include "llsky.h"
#include "llvowlsky.h"
-#include "llagent.h"
#include "llviewerregion.h"
#include "llface.h"
#include "llrender.h"
-LLPointer<LLImageGL> LLDrawPoolWLSky::sCloudNoiseTexture = NULL;
+LLPointer<LLViewerTexture> LLDrawPoolWLSky::sCloudNoiseTexture = NULL;
LLPointer<LLImageRaw> LLDrawPoolWLSky::sCloudNoiseRawImage = NULL;
@@ -71,7 +70,7 @@ LLDrawPoolWLSky::LLDrawPoolWLSky(void) :
cloudNoiseFile->decode(sCloudNoiseRawImage, 0.0f);
- LLImageGL::create(sCloudNoiseTexture, sCloudNoiseRawImage, TRUE);
+ sCloudNoiseTexture = LLViewerTextureManager::getLocalTexture(sCloudNoiseRawImage.get(), TRUE);
LLWLParamManager::instance()->propagateParameters();
}
@@ -83,7 +82,7 @@ LLDrawPoolWLSky::~LLDrawPoolWLSky()
sCloudNoiseRawImage = NULL;
}
-LLViewerImage *LLDrawPoolWLSky::getDebugTexture()
+LLViewerTexture *LLDrawPoolWLSky::getDebugTexture()
{
return NULL;
}
@@ -224,7 +223,7 @@ void LLDrawPoolWLSky::renderHeavenlyBodies()
LLFace * face = gSky.mVOSkyp->mFace[LLVOSky::FACE_SUN];
if (gSky.mVOSkyp->getSun().getDraw() && face->getGeomCount())
{
- LLImageGL * tex = face->getTexture();
+ LLViewerTexture * tex = face->getTexture();
gGL.getTexUnit(0)->bind(tex);
LLColor4 color(gSky.mVOSkyp->getSun().getInterpColor());
LLFacePool::LLOverrideFaceColor color_override(this, color);
@@ -239,8 +238,7 @@ void LLDrawPoolWLSky::renderHeavenlyBodies()
// *NOTE: even though we already bound this texture above for the
// stars register combiners, we bind again here for defensive reasons,
// since LLImageGL::bind detects that it's a noop, and optimizes it out.
- LLImageGL * tex = face->getTexture();
- gGL.getTexUnit(0)->bind(tex);
+ gGL.getTexUnit(0)->bind(face->getTexture());
LLColor4 color(gSky.mVOSkyp->getMoon().getInterpColor());
F32 a = gSky.mVOSkyp->getMoon().getDirection().mV[2];
if (a > 0.f)
@@ -261,7 +259,7 @@ void LLDrawPoolWLSky::render(S32 pass)
{
return;
}
- LLFastTimer ftm(LLFastTimer::FTM_RENDER_WL_SKY);
+ LLFastTimer ftm(FTM_RENDER_WL_SKY);
const F32 camHeightLocal = LLWLParamManager::instance()->getDomeOffset() * LLWLParamManager::instance()->getDomeRadius();
@@ -280,9 +278,8 @@ void LLDrawPoolWLSky::render(S32 pass)
// *NOTE: have to bind a texture here since register combiners blending in
// renderStars() requires something to be bound and we might as well only
- // bind the moon's texture once.
- LLImageGL * tex = gSky.mVOSkyp->mFace[LLVOSky::FACE_MOON]->getTexture();
- gGL.getTexUnit(0)->bind(tex);
+ // bind the moon's texture once.
+ gGL.getTexUnit(0)->bind(gSky.mVOSkyp->mFace[LLVOSky::FACE_MOON]->getTexture());
renderHeavenlyBodies();
@@ -306,7 +303,7 @@ LLDrawPoolWLSky *LLDrawPoolWLSky::instancePool()
return new LLDrawPoolWLSky();
}
-LLViewerImage* LLDrawPoolWLSky::getTexture()
+LLViewerTexture* LLDrawPoolWLSky::getTexture()
{
return NULL;
}
@@ -324,5 +321,5 @@ void LLDrawPoolWLSky::cleanupGL()
//static
void LLDrawPoolWLSky::restoreGL()
{
- LLImageGL::create(sCloudNoiseTexture, sCloudNoiseRawImage, TRUE);
+ sCloudNoiseTexture = LLViewerTextureManager::getLocalTexture(sCloudNoiseRawImage.get(), TRUE);
}
diff --git a/indra/newview/lldrawpoolwlsky.h b/indra/newview/lldrawpoolwlsky.h
index c7a1f3fe27..7ff760ac39 100644
--- a/indra/newview/lldrawpoolwlsky.h
+++ b/indra/newview/lldrawpoolwlsky.h
@@ -55,7 +55,7 @@ public:
/*virtual*/ void endPostDeferredPass(S32 pass) { endRenderPass(pass); }
/*virtual*/ void renderPostDeferred(S32 pass) { render(pass); }
- /*virtual*/ LLViewerImage *getDebugTexture();
+ /*virtual*/ LLViewerTexture *getDebugTexture();
/*virtual*/ void beginRenderPass( S32 pass );
/*virtual*/ void endRenderPass( S32 pass );
/*virtual*/ S32 getNumPasses() { return 1; }
@@ -65,11 +65,11 @@ public:
/*virtual*/ BOOL verify() const { return TRUE; } // Verify that all data in the draw pool is correct!
/*virtual*/ S32 getVertexShaderLevel() const { return mVertexShaderLevel; }
- //static LLDrawPool* createPool(const U32 type, LLViewerImage *tex0 = NULL);
+ //static LLDrawPool* createPool(const U32 type, LLViewerTexture *tex0 = NULL);
// Create an empty new instance of the pool.
/*virtual*/ LLDrawPoolWLSky *instancePool(); ///< covariant override
- /*virtual*/ LLViewerImage* getTexture();
+ /*virtual*/ LLViewerTexture* getTexture();
/*virtual*/ BOOL isFacePool() { return FALSE; }
/*virtual*/ void resetDrawOrders();
@@ -83,7 +83,7 @@ private:
void renderHeavenlyBodies();
private:
- static LLPointer<LLImageGL> sCloudNoiseTexture;
+ static LLPointer<LLViewerTexture> sCloudNoiseTexture;
static LLPointer<LLImageRaw> sCloudNoiseRawImage;
};
diff --git a/indra/newview/lldynamictexture.cpp b/indra/newview/lldynamictexture.cpp
index 62fcf60e7f..0bb5edf3f9 100644
--- a/indra/newview/lldynamictexture.cpp
+++ b/indra/newview/lldynamictexture.cpp
@@ -1,6 +1,6 @@
/**
* @file lldynamictexture.cpp
- * @brief Implementation of LLDynamicTexture class
+ * @brief Implementation of LLViewerDynamicTexture class
*
* $LicenseInfo:firstyear=2001&license=viewergpl$
*
@@ -33,28 +33,29 @@
#include "llviewerprecompiledheaders.h"
#include "lldynamictexture.h"
+
+// Linden library includes
#include "llglheaders.h"
+#include "llwindow.h" // getPosition()
+
+// Viewer includes
#include "llviewerwindow.h"
#include "llviewercamera.h"
#include "llviewercontrol.h"
-#include "llviewerimage.h"
+#include "llviewertexture.h"
#include "llvertexbuffer.h"
#include "llviewerdisplay.h"
#include "llrender.h"
// static
-LLDynamicTexture::instance_list_t LLDynamicTexture::sInstances[ LLDynamicTexture::ORDER_COUNT ];
-S32 LLDynamicTexture::sNumRenders = 0;
+LLViewerDynamicTexture::instance_list_t LLViewerDynamicTexture::sInstances[ LLViewerDynamicTexture::ORDER_COUNT ];
+S32 LLViewerDynamicTexture::sNumRenders = 0;
//-----------------------------------------------------------------------------
-// LLDynamicTexture()
+// LLViewerDynamicTexture()
//-----------------------------------------------------------------------------
-LLDynamicTexture::LLDynamicTexture(S32 width, S32 height, S32 components, EOrder order, BOOL clamp) :
- mWidth(width),
- mHeight(height),
- mComponents(components),
- mTexture(NULL),
- mLastBindTime(0),
+LLViewerDynamicTexture::LLViewerDynamicTexture(S32 width, S32 height, S32 components, EOrder order, BOOL clamp) :
+ LLViewerTexture(width, height, components, FALSE),
mClamp(clamp)
{
llassert((1 <= components) && (components <= 4));
@@ -62,64 +63,56 @@ LLDynamicTexture::LLDynamicTexture(S32 width, S32 height, S32 components, EOrder
generateGLTexture();
llassert( 0 <= order && order < ORDER_COUNT );
- LLDynamicTexture::sInstances[ order ].insert(this);
+ LLViewerDynamicTexture::sInstances[ order ].insert(this);
}
//-----------------------------------------------------------------------------
-// LLDynamicTexture()
+// LLViewerDynamicTexture()
//-----------------------------------------------------------------------------
-LLDynamicTexture::~LLDynamicTexture()
+LLViewerDynamicTexture::~LLViewerDynamicTexture()
{
- releaseGLTexture();
for( S32 order = 0; order < ORDER_COUNT; order++ )
{
- LLDynamicTexture::sInstances[order].erase(this); // will fail in all but one case.
+ LLViewerDynamicTexture::sInstances[order].erase(this); // will fail in all but one case.
}
}
-//-----------------------------------------------------------------------------
-// releaseGLTexture()
-//-----------------------------------------------------------------------------
-void LLDynamicTexture::releaseGLTexture()
+//virtual
+S8 LLViewerDynamicTexture::getType() const
{
- if (mTexture.notNull())
- {
-// llinfos << "RELEASING " << (mWidth*mHeight*mComponents)/1024 << "K" << llendl;
- mTexture = NULL;
- }
+ return LLViewerTexture::DYNAMIC_TEXTURE ;
}
//-----------------------------------------------------------------------------
// generateGLTexture()
//-----------------------------------------------------------------------------
-void LLDynamicTexture::generateGLTexture()
+void LLViewerDynamicTexture::generateGLTexture()
{
+ LLViewerTexture::generateGLTexture() ;
generateGLTexture(-1, 0, 0, FALSE);
}
-void LLDynamicTexture::generateGLTexture(LLGLint internal_format, LLGLenum primary_format, LLGLenum type_format, BOOL swap_bytes)
+void LLViewerDynamicTexture::generateGLTexture(LLGLint internal_format, LLGLenum primary_format, LLGLenum type_format, BOOL swap_bytes)
{
if (mComponents < 1 || mComponents > 4)
{
llerrs << "Bad number of components in dynamic texture: " << mComponents << llendl;
}
- releaseGLTexture();
- LLPointer<LLImageRaw> raw_image = new LLImageRaw(mWidth, mHeight, mComponents);
- mTexture = new LLViewerImage(mWidth, mHeight, mComponents, FALSE);
+
+ LLPointer<LLImageRaw> raw_image = new LLImageRaw(mFullWidth, mFullHeight, mComponents);
if (internal_format >= 0)
{
- mTexture->setExplicitFormat(internal_format, primary_format, type_format, swap_bytes);
+ setExplicitFormat(internal_format, primary_format, type_format, swap_bytes);
}
-// llinfos << "ALLOCATING " << (mWidth*mHeight*mComponents)/1024 << "K" << llendl;
- mTexture->createGLTexture(0, raw_image);
- mTexture->setAddressMode((mClamp) ? LLTexUnit::TAM_CLAMP : LLTexUnit::TAM_WRAP);
- mTexture->setGLTextureCreated(false);
+ createGLTexture(0, raw_image);
+ setAddressMode((mClamp) ? LLTexUnit::TAM_CLAMP : LLTexUnit::TAM_WRAP);
+ mGLTexturep->setGLTextureCreated(false);
}
//-----------------------------------------------------------------------------
// render()
//-----------------------------------------------------------------------------
-BOOL LLDynamicTexture::render()
+BOOL LLViewerDynamicTexture::render()
{
return FALSE;
}
@@ -127,13 +120,13 @@ BOOL LLDynamicTexture::render()
//-----------------------------------------------------------------------------
// preRender()
//-----------------------------------------------------------------------------
-void LLDynamicTexture::preRender(BOOL clear_depth)
+void LLViewerDynamicTexture::preRender(BOOL clear_depth)
{
{
// force rendering to on-screen portion of frame buffer
LLCoordScreen window_pos;
gViewerWindow->getWindow()->getPosition( &window_pos );
- mOrigin.set(0, gViewerWindow->getWindowDisplayHeight() - mHeight); // top left corner
+ mOrigin.set(0, gViewerWindow->getWindowDisplayHeight() - mFullHeight); // top left corner
if (window_pos.mX < 0)
{
@@ -154,7 +147,7 @@ void LLDynamicTexture::preRender(BOOL clear_depth)
mCamera.setView(LLViewerCamera::getInstance()->getView());
mCamera.setNear(LLViewerCamera::getInstance()->getNear());
- glViewport(mOrigin.mX, mOrigin.mY, mWidth, mHeight);
+ glViewport(mOrigin.mX, mOrigin.mY, mFullWidth, mFullHeight);
if (clear_depth)
{
glClear(GL_DEPTH_BUFFER_BIT);
@@ -164,17 +157,21 @@ void LLDynamicTexture::preRender(BOOL clear_depth)
//-----------------------------------------------------------------------------
// postRender()
//-----------------------------------------------------------------------------
-void LLDynamicTexture::postRender(BOOL success)
+void LLViewerDynamicTexture::postRender(BOOL success)
{
{
if (success)
{
- success = mTexture->setSubImageFromFrameBuffer(0, 0, mOrigin.mX, mOrigin.mY, mWidth, mHeight);
+ if(mGLTexturep.isNull())
+ {
+ generateGLTexture() ;
+ }
+ success = mGLTexturep->setSubImageFromFrameBuffer(0, 0, mOrigin.mX, mOrigin.mY, mFullWidth, mFullHeight);
}
}
// restore viewport
- gViewerWindow->setupViewport();
+ gViewerWindow->setup2DViewport();
// restore camera
LLViewerCamera::getInstance()->setOrigin(mCamera);
@@ -189,7 +186,7 @@ void LLDynamicTexture::postRender(BOOL success)
// updateDynamicTextures()
// Calls update on each dynamic texture. Calls each group in order: "first," then "middle," then "last."
//-----------------------------------------------------------------------------
-BOOL LLDynamicTexture::updateAllInstances()
+BOOL LLViewerDynamicTexture::updateAllInstances()
{
sNumRenders = 0;
if (gGLManager.mIsDisabled)
@@ -201,10 +198,10 @@ BOOL LLDynamicTexture::updateAllInstances()
BOOL ret = FALSE ;
for( S32 order = 0; order < ORDER_COUNT; order++ )
{
- for (instance_list_t::iterator iter = LLDynamicTexture::sInstances[order].begin();
- iter != LLDynamicTexture::sInstances[order].end(); ++iter)
+ for (instance_list_t::iterator iter = LLViewerDynamicTexture::sInstances[order].begin();
+ iter != LLViewerDynamicTexture::sInstances[order].end(); ++iter)
{
- LLDynamicTexture *dynamicTexture = *iter;
+ LLViewerDynamicTexture *dynamicTexture = *iter;
if (dynamicTexture->needsRender())
{
glClear(GL_DEPTH_BUFFER_BIT);
@@ -231,30 +228,18 @@ BOOL LLDynamicTexture::updateAllInstances()
return ret;
}
-//virtual
-void LLDynamicTexture::restoreGLTexture()
-{
- generateGLTexture() ;
-}
-
-//virtual
-void LLDynamicTexture::destroyGLTexture()
-{
- releaseGLTexture() ;
-}
-
//-----------------------------------------------------------------------------
// static
// destroyGL()
//-----------------------------------------------------------------------------
-void LLDynamicTexture::destroyGL()
+void LLViewerDynamicTexture::destroyGL()
{
for( S32 order = 0; order < ORDER_COUNT; order++ )
{
- for (instance_list_t::iterator iter = LLDynamicTexture::sInstances[order].begin();
- iter != LLDynamicTexture::sInstances[order].end(); ++iter)
+ for (instance_list_t::iterator iter = LLViewerDynamicTexture::sInstances[order].begin();
+ iter != LLViewerDynamicTexture::sInstances[order].end(); ++iter)
{
- LLDynamicTexture *dynamicTexture = *iter;
+ LLViewerDynamicTexture *dynamicTexture = *iter;
dynamicTexture->destroyGLTexture() ;
}
}
@@ -264,7 +249,7 @@ void LLDynamicTexture::destroyGL()
// static
// restoreGL()
//-----------------------------------------------------------------------------
-void LLDynamicTexture::restoreGL()
+void LLViewerDynamicTexture::restoreGL()
{
if (gGLManager.mIsDisabled)
{
@@ -273,10 +258,10 @@ void LLDynamicTexture::restoreGL()
for( S32 order = 0; order < ORDER_COUNT; order++ )
{
- for (instance_list_t::iterator iter = LLDynamicTexture::sInstances[order].begin();
- iter != LLDynamicTexture::sInstances[order].end(); ++iter)
+ for (instance_list_t::iterator iter = LLViewerDynamicTexture::sInstances[order].begin();
+ iter != LLViewerDynamicTexture::sInstances[order].end(); ++iter)
{
- LLDynamicTexture *dynamicTexture = *iter;
+ LLViewerDynamicTexture *dynamicTexture = *iter;
dynamicTexture->restoreGLTexture() ;
}
}
diff --git a/indra/newview/lldynamictexture.h b/indra/newview/lldynamictexture.h
index 5a20eaef9b..2a944eaada 100644
--- a/indra/newview/lldynamictexture.h
+++ b/indra/newview/lldynamictexture.h
@@ -1,6 +1,6 @@
/**
* @file lldynamictexture.h
- * @brief Implementation of LLDynamicTexture class
+ * @brief Implementation of LLViewerDynamicTexture class
*
* $LicenseInfo:firstyear=2002&license=viewergpl$
*
@@ -33,61 +33,55 @@
#ifndef LL_LLDYNAMICTEXTURE_H
#define LL_LLDYNAMICTEXTURE_H
+#include "llcamera.h"
#include "llgl.h"
#include "llcoord.h"
-#include "llimagegl.h"
+#include "llviewertexture.h"
+#include "llcamera.h"
-class LLDynamicTexture
+class LLViewerDynamicTexture : public LLViewerTexture
{
+protected:
+ /*virtual*/ ~LLViewerDynamicTexture();
+
public:
enum EOrder { ORDER_FIRST = 0, ORDER_MIDDLE = 1, ORDER_LAST = 2, ORDER_RESET = 3, ORDER_COUNT = 4 };
- LLDynamicTexture(S32 width,
+ LLViewerDynamicTexture(S32 width,
S32 height,
S32 components, // = 4,
EOrder order, // = ORDER_MIDDLE,
BOOL clamp);
- virtual ~LLDynamicTexture();
+
+ /*virtual*/ S8 getType() const ;
S32 getOriginX() { return mOrigin.mX; }
S32 getOriginY() { return mOrigin.mY; }
- S32 getWidth() { return mWidth; }
- S32 getHeight() { return mHeight; }
- S32 getComponents() { return mComponents; }
- S32 getSize() { return mWidth * mHeight * mComponents; }
+
+ S32 getSize() { return mFullWidth * mFullHeight * mComponents; }
virtual BOOL needsRender() { return TRUE; }
virtual void preRender(BOOL clear_depth = TRUE);
virtual BOOL render();
virtual void postRender(BOOL success);
- virtual void restoreGLTexture() ;
- virtual void destroyGLTexture() ;
-
- LLImageGL* getTexture(void) const { return mTexture; }
+ virtual void restoreGLTexture() {}
+ virtual void destroyGLTexture() {}
static BOOL updateAllInstances();
-
- static void destroyGL();
- static void restoreGL();
-
+ static void destroyGL() ;
+ static void restoreGL() ;
protected:
- void releaseGLTexture();
void generateGLTexture();
void generateGLTexture(LLGLint internal_format, LLGLenum primary_format, LLGLenum type_format, BOOL swap_bytes = FALSE);
protected:
- S32 mWidth;
- S32 mHeight;
- S32 mComponents;
- LLPointer<LLImageGL> mTexture;
- F32 mLastBindTime;
BOOL mClamp;
LLCoordGL mOrigin;
-
LLCamera mCamera;
- typedef std::set<LLDynamicTexture*> instance_list_t;
- static instance_list_t sInstances[ LLDynamicTexture::ORDER_COUNT ];
+
+ typedef std::set<LLViewerDynamicTexture*> instance_list_t;
+ static instance_list_t sInstances[ LLViewerDynamicTexture::ORDER_COUNT ];
static S32 sNumRenders;
};
diff --git a/indra/newview/llemote.cpp b/indra/newview/llemote.cpp
index bacf3daf5a..c83846215e 100644
--- a/indra/newview/llemote.cpp
+++ b/indra/newview/llemote.cpp
@@ -39,7 +39,6 @@
#include "llcharacter.h"
#include "m3math.h"
#include "llvoavatar.h"
-#include "llagent.h"
//-----------------------------------------------------------------------------
// Constants
diff --git a/indra/newview/lleventnotifier.cpp b/indra/newview/lleventnotifier.cpp
index e7403c2903..2c52cf9565 100644
--- a/indra/newview/lleventnotifier.cpp
+++ b/indra/newview/lleventnotifier.cpp
@@ -38,6 +38,7 @@
#include "llnotify.h"
#include "lleventinfo.h"
+#include "llfloaterreg.h"
#include "llfloaterdirectory.h"
#include "llfloaterworldmap.h"
#include "llagent.h"
@@ -191,12 +192,15 @@ bool LLEventNotification::handleResponse(const LLSD& notification, const LLSD& r
switch (option)
{
case 0:
- gAgent.teleportViaLocation(getEventPosGlobal());
- gFloaterWorldMap->trackLocation(getEventPosGlobal());
- break;
+ {
+ gAgent.teleportViaLocation(getEventPosGlobal());
+ LLFloaterWorldMap* floater_world_map = LLFloaterWorldMap::getInstance();
+ if(floater_world_map) floater_world_map->trackLocation(getEventPosGlobal());
+ break;
+ }
case 1:
gDisplayEventHack = TRUE;
- LLFloaterDirectory::showEvents(getEventID());
+ LLFloaterReg::showInstance("search", LLSD().insert("panel", "event").insert("id", S32(getEventID())));
break;
case 2:
break;
diff --git a/indra/newview/lleventpoll.h b/indra/newview/lleventpoll.h
index 12e4b49d57..f2465a361e 100644
--- a/indra/newview/lleventpoll.h
+++ b/indra/newview/lleventpoll.h
@@ -35,6 +35,9 @@
#include "llhttpclient.h"
+class LLHost;
+
+
class LLEventPoll
///< implements the viewer side of server-to-viewer pushed events.
{
diff --git a/indra/newview/llface.cpp b/indra/newview/llface.cpp
index 69edccacf0..bef9e40c49 100644
--- a/indra/newview/llface.cpp
+++ b/indra/newview/llface.cpp
@@ -47,7 +47,7 @@
#include "lllightconstants.h"
#include "llsky.h"
#include "llviewercamera.h"
-#include "llviewerimagelist.h"
+#include "llviewertexturelist.h"
#include "llvosky.h"
#include "llvovolume.h"
#include "pipeline.h"
@@ -179,6 +179,10 @@ void LLFace::init(LLDrawable* drawablep, LLViewerObject* objp)
void LLFace::destroy()
{
+ if(mTexture.notNull())
+ {
+ mTexture->removeFace(this) ;
+ }
if (mDrawPoolp)
{
mDrawPoolp->removeFace(this);
@@ -217,7 +221,7 @@ void LLFace::setWorldMatrix(const LLMatrix4 &mat)
llerrs << "Faces on this drawable are not independently modifiable\n" << llendl;
}
-void LLFace::setPool(LLFacePool* new_pool, LLViewerImage *texturep)
+void LLFace::setPool(LLFacePool* new_pool, LLViewerTexture *texturep)
{
LLMemType mt1(LLMemType::MTYPE_DRAWABLE);
@@ -247,9 +251,28 @@ void LLFace::setPool(LLFacePool* new_pool, LLViewerImage *texturep)
}
mDrawPoolp = new_pool;
}
- mTexture = texturep;
+ setTexture(texturep) ;
}
+void LLFace::setTexture(LLViewerTexture* tex)
+{
+ if(mTexture == tex)
+ {
+ return ;
+ }
+
+ if(mTexture.notNull())
+ {
+ mTexture->removeFace(this) ;
+ }
+
+ mTexture = tex ;
+
+ if(mTexture.notNull())
+ {
+ mTexture->addFace(this) ;
+ }
+}
void LLFace::setTEOffset(const S32 te_offset)
{
@@ -422,7 +445,7 @@ void LLFace::renderForSelect(U32 data_mask)
}
}
-void LLFace::renderSelected(LLImageGL *imagep, const LLColor4& color)
+void LLFace::renderSelected(LLViewerTexture *imagep, const LLColor4& color)
{
if(mDrawablep.isNull() || mVertexBuffer.isNull() || mDrawablep->getSpatialGroup() == NULL ||
mDrawablep->getSpatialGroup()->isState(LLSpatialGroup::GEOM_DIRTY))
@@ -463,8 +486,8 @@ void LLFace::renderSelected(LLImageGL *imagep, const LLColor4& color)
/* removed in lieu of raycast uv detection
void LLFace::renderSelectedUV()
{
- LLViewerImage* red_blue_imagep = gImageList.getImageFromFile("uv_test1.j2c", TRUE, TRUE);
- LLViewerImage* green_imagep = gImageList.getImageFromFile("uv_test2.tga", TRUE, TRUE);
+ LLViewerTexture* red_blue_imagep = LLViewerTextureManager::getFetchedTextureFromFile("uv_test1.j2c", TRUE, TRUE);
+ LLViewerTexture* green_imagep = LLViewerTextureManager::getFetchedTextureFromFile("uv_test2.tga", TRUE, TRUE);
LLGLSUVSelect object_select;
@@ -998,7 +1021,7 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume,
break;
case BE_BRIGHTNESS:
case BE_DARKNESS:
- if( mTexture.notNull() && mTexture->getHasGLTexture())
+ if( mTexture.notNull() && mTexture->hasValidGLTexture())
{
// Offset by approximately one texel
S32 cur_discard = mTexture->getDiscardLevel();
diff --git a/indra/newview/llface.h b/indra/newview/llface.h
index 4a551ff261..e0728fe15e 100644
--- a/indra/newview/llface.h
+++ b/indra/newview/llface.h
@@ -45,16 +45,15 @@
#include "xform.h"
#include "lldarrayptr.h"
#include "llvertexbuffer.h"
-#include "llviewerimage.h"
-#include "llstat.h"
+#include "llviewertexture.h"
#include "lldrawable.h"
class LLFacePool;
class LLVolume;
-class LLViewerImage;
+class LLViewerTexture;
class LLTextureEntry;
class LLVertexProgram;
-class LLViewerImage;
+class LLViewerTexture;
class LLGeometryManager;
const F32 MIN_ALPHA_SIZE = 1024.f;
@@ -87,8 +86,8 @@ public:
U16 getGeomCount() const { return mGeomCount; } // vertex count for this face
U16 getGeomIndex() const { return mGeomIndex; } // index into draw pool
U16 getGeomStart() const { return mGeomIndex; } // index into draw pool
- LLViewerImage* getTexture() const { return mTexture; }
- void setTexture(LLViewerImage* tex) { mTexture = tex; }
+ LLViewerTexture* getTexture() const { return mTexture; }
+ void setTexture(LLViewerTexture* tex) ;
LLXformMatrix* getXform() const { return mXform; }
BOOL hasGeometry() const { return mGeomCount > 0; }
LLVector3 getPositionAgent() const;
@@ -120,10 +119,10 @@ public:
LLVertexBuffer* getVertexBuffer() const { return mVertexBuffer; }
void setPoolType(U32 type) { mPoolType = type; }
S32 getTEOffset() { return mTEOffset; }
- LLViewerImage* getTexture() { return mTexture; }
+ LLViewerTexture* getTexture() { return mTexture; }
void setViewerObject(LLViewerObject* object);
- void setPool(LLFacePool *pool, LLViewerImage *texturep);
+ void setPool(LLFacePool *pool, LLViewerTexture *texturep);
void setDrawable(LLDrawable *drawable);
void setTEOffset(const S32 te_offset);
@@ -172,7 +171,7 @@ public:
void renderSelectedUV();
void renderForSelect(U32 data_mask = LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_TEXCOORD0);
- void renderSelected(LLImageGL *image, const LLColor4 &color);
+ void renderSelected(LLViewerTexture *image, const LLColor4 &color);
F32 getKey() const { return mDistance; }
@@ -223,7 +222,7 @@ protected:
U32 mLastIndicesIndex;
LLXformMatrix* mXform;
- LLPointer<LLViewerImage> mTexture;
+ LLPointer<LLViewerTexture> mTexture;
LLPointer<LLDrawable> mDrawablep;
LLPointer<LLViewerObject> mVObjp;
S32 mTEOffset;
diff --git a/indra/newview/llfasttimerview.cpp b/indra/newview/llfasttimerview.cpp
index c9037d0fbb..8ceb41c27a 100644
--- a/indra/newview/llfasttimerview.cpp
+++ b/indra/newview/llfasttimerview.cpp
@@ -41,295 +41,117 @@
#include "llrender.h"
#include "llmath.h"
#include "llfontgl.h"
+#include "llsdserialize.h"
#include "llappviewer.h"
-#include "llviewerimagelist.h"
+#include "llviewertexturelist.h"
#include "llui.h"
#include "llviewercontrol.h"
#include "llstat.h"
#include "llfasttimer.h"
-
+#include "lltreeiterators.h"
+#include "llmetricperformancetester.h"
//////////////////////////////////////////////////////////////////////////////
static const S32 MAX_VISIBLE_HISTORY = 10;
static const S32 LINE_GRAPH_HEIGHT = 240;
-struct ft_display_info {
- int timer;
- const char *desc;
- const LLColor4 *color;
- S32 disabled; // initialized to 0
- int level; // calculated based on desc
- int parent; // calculated
-};
-
-static const LLColor4 red0(0.5f, 0.0f, 0.0f, 1.0f);
-static const LLColor4 green0(0.0f, 0.5f, 0.0f, 1.0f);
-static const LLColor4 blue0(0.0f, 0.0f, 0.5f, 1.0f);
-static const LLColor4 blue7(0.0f, 0.0f, 0.5f, 1.0f);
-
-static const LLColor4 green7(0.6f, 1.0f, 0.4f, 1.0f);
-static const LLColor4 green8(0.4f, 1.0f, 0.6f, 1.0f);
-static const LLColor4 green9(0.6f, 1.0f, 0.6f, 1.0f);
-
-// green(6), blue, yellow, orange, pink(2), cyan
-// red (5) magenta (4)
-static struct ft_display_info ft_display_table[] =
-{
- { LLFastTimer::FTM_FRAME, "Frame", &LLColor4::white, 0 },
- { LLFastTimer::FTM_MESSAGES, " System Messages", &LLColor4::grey1, 1 },
- { LLFastTimer::FTM_MOUSEHANDLER, " Mouse", &LLColor4::grey1, 0 },
- { LLFastTimer::FTM_KEYHANDLER, " Keyboard", &LLColor4::grey1, 0 },
- { LLFastTimer::FTM_SLEEP, " Sleep", &LLColor4::grey2, 0 },
- { LLFastTimer::FTM_IDLE, " Idle", &blue0, 0 },
- { LLFastTimer::FTM_PUMP, " Pump", &LLColor4::magenta2, 1 },
- { LLFastTimer::FTM_CURL, " Curl", &LLColor4::magenta3, 0 },
- { LLFastTimer::FTM_INVENTORY, " Inventory Update", &LLColor4::purple6, 1 },
- { LLFastTimer::FTM_AUTO_SELECT, " Open and Select", &LLColor4::red, 0 },
- { LLFastTimer::FTM_FILTER, " Filter", &LLColor4::red2, 0 },
- { LLFastTimer::FTM_ARRANGE, " Arrange", &LLColor4::red3, 0 },
- { LLFastTimer::FTM_REFRESH, " Refresh", &LLColor4::red4, 0 },
- { LLFastTimer::FTM_SORT, " Sort", &LLColor4::red5, 0 },
- { LLFastTimer::FTM_RESET_DRAWORDER, " ResetDrawOrder", &LLColor4::pink1, 0 },
- { LLFastTimer::FTM_WORLD_UPDATE, " World Update", &LLColor4::blue1, 1 },
- { LLFastTimer::FTM_UPDATE_MOVE, " Move Objects", &LLColor4::pink2, 0 },
- { LLFastTimer::FTM_OCTREE_BALANCE, " Octree Balance", &LLColor4::red3, 0 },
- { LLFastTimer::FTM_SIMULATE_PARTICLES, " Particle Sim", &LLColor4::blue4, 0 },
- { LLFastTimer::FTM_OBJECTLIST_UPDATE, " Object Update", &LLColor4::purple1, 1 },
- { LLFastTimer::FTM_AVATAR_UPDATE, " Avatars", &LLColor4::purple2, 0 },
- { LLFastTimer::FTM_JOINT_UPDATE, " Joints", &LLColor4::purple3, 0 },
- { LLFastTimer::FTM_ATTACHMENT_UPDATE, " Attachments", &LLColor4::purple4, 0 },
- { LLFastTimer::FTM_UPDATE_ANIMATION, " Animation", &LLColor4::purple5, 0 },
- { LLFastTimer::FTM_FLEXIBLE_UPDATE, " Flex Update", &LLColor4::pink2, 0 },
- { LLFastTimer::FTM_LOD_UPDATE, " LOD Update", &LLColor4::magenta1, 0 },
- { LLFastTimer::FTM_REGION_UPDATE, " Region Update", &LLColor4::cyan2, 0 },
- { LLFastTimer::FTM_NETWORK, " Network", &LLColor4::orange1, 1 },
- { LLFastTimer::FTM_IDLE_NETWORK, " Decode Msgs", &LLColor4::orange2, 0 },
- { LLFastTimer::FTM_PROCESS_MESSAGES, " Process Msgs", &LLColor4::orange3, 0 },
- { LLFastTimer::FTM_PROCESS_OBJECTS, " Object Updates",&LLColor4::orange4, 0 },
- { LLFastTimer::FTM_CREATE_OBJECT, " Create Obj", &LLColor4::orange5, 0 },
-// { LLFastTimer::FTM_LOAD_AVATAR, " Load Avatar", &LLColor4::pink2, 0 },
- { LLFastTimer::FTM_PROCESS_IMAGES, " Image Updates",&LLColor4::orange6, 0 },
- { LLFastTimer::FTM_PIPELINE, " Pipeline", &LLColor4::magenta4, 0 },
- { LLFastTimer::FTM_CLEANUP, " Cleanup", &LLColor4::cyan3, 0 },
- { LLFastTimer::FTM_AUDIO_UPDATE, " Audio Update", &LLColor4::yellow3, 0 },
- { LLFastTimer::FTM_VFILE_WAIT, " VFile Wait", &LLColor4::cyan6, 0 },
-// { LLFastTimer::FTM_IDLE_CB, " Callbacks", &LLColor4::pink1, 0 },
- { LLFastTimer::FTM_RENDER, " Render", &green0, 1 },
- { LLFastTimer::FTM_PICK, " Pick", &LLColor4::purple, 1 },
- { LLFastTimer::FTM_HUD_EFFECTS, " HUD Effects", &LLColor4::orange1, 0 },
- { LLFastTimer::FTM_HUD_UPDATE, " HUD Update", &LLColor4::orange2, 0 },
- { LLFastTimer::FTM_UPDATE_SKY, " Sky Update", &LLColor4::cyan1, 0 },
- { LLFastTimer::FTM_UPDATE_TEXTURES, " Textures", &LLColor4::pink2, 0 },
- { LLFastTimer::FTM_GEO_UPDATE, " Geo Update", &LLColor4::blue3, 1 },
- { LLFastTimer::FTM_UPDATE_PRIMITIVES, " Volumes", &LLColor4::blue4, 0 },
- { LLFastTimer::FTM_GEN_VOLUME, " Gen Volume", &LLColor4::yellow3, 0 },
- { LLFastTimer::FTM_GEN_FLEX, " Flexible", &LLColor4::yellow4, 0 },
- { LLFastTimer::FTM_GEN_TRIANGLES, " Triangles", &LLColor4::yellow5, 0 },
- { LLFastTimer::FTM_UPDATE_AVATAR, " Avatar", &LLColor4::yellow1, 0 },
- { LLFastTimer::FTM_UPDATE_TREE, " Tree", &LLColor4::yellow2, 0 },
- { LLFastTimer::FTM_UPDATE_TERRAIN, " Terrain", &LLColor4::yellow6, 0 },
- { LLFastTimer::FTM_UPDATE_CLOUDS, " Clouds", &LLColor4::yellow7, 0 },
- { LLFastTimer::FTM_UPDATE_GRASS, " Grass", &LLColor4::yellow8, 0 },
- { LLFastTimer::FTM_UPDATE_WATER, " Water", &LLColor4::yellow9, 0 },
- { LLFastTimer::FTM_GEO_LIGHT, " Lighting", &LLColor4::yellow1, 0 },
- { LLFastTimer::FTM_GEO_SHADOW, " Shadow", &LLColor4::black, 0 },
- { LLFastTimer::FTM_UPDATE_PARTICLES, " Particles", &LLColor4::blue5, 0 },
- { LLFastTimer::FTM_GEO_RESERVE, " Reserve", &LLColor4::blue6, 0 },
- { LLFastTimer::FTM_UPDATE_LIGHTS, " Lights", &LLColor4::yellow2, 0 },
- { LLFastTimer::FTM_GEO_SKY, " Sky", &LLColor4::yellow3, 0 },
- { LLFastTimer::FTM_UPDATE_WLPARAM, " Windlight Param",&LLColor4::magenta2, 0 },
- { LLFastTimer::FTM_CULL, " Object Cull", &LLColor4::blue2, 1 },
- { LLFastTimer::FTM_CULL_REBOUND, " Rebound", &LLColor4::blue3, 0 },
- { LLFastTimer::FTM_FRUSTUM_CULL, " Frustum Cull", &LLColor4::blue4, 0 },
- { LLFastTimer::FTM_OCCLUSION_READBACK, " Occlusion Read", &LLColor4::red2, 0 },
- { LLFastTimer::FTM_IMAGE_UPDATE, " Image Update", &LLColor4::yellow4, 1 },
- { LLFastTimer::FTM_IMAGE_CREATE, " Image CreateGL",&LLColor4::yellow5, 0 },
- { LLFastTimer::FTM_IMAGE_DECODE, " Image Decode", &LLColor4::yellow6, 0 },
- { LLFastTimer::FTM_IMAGE_MARK_DIRTY, " Dirty Textures",&LLColor4::red1, 0 },
- { LLFastTimer::FTM_STATESORT, " State Sort", &LLColor4::orange1, 1 },
- { LLFastTimer::FTM_STATESORT_DRAWABLE, " Drawable", &LLColor4::orange2, 0 },
- { LLFastTimer::FTM_STATESORT_POSTSORT, " Post Sort", &LLColor4::orange3, 0 },
- { LLFastTimer::FTM_REBUILD_OCCLUSION_VB," Occlusion", &LLColor4::cyan5, 0 },
- { LLFastTimer::FTM_REBUILD_VBO, " VBO Rebuild", &LLColor4::red4, 0 },
- { LLFastTimer::FTM_REBUILD_VOLUME_VB, " Volume", &LLColor4::blue1, 0 },
-// { LLFastTimer::FTM_REBUILD_NONE_VB, " Unknown", &LLColor4::cyan5, 0 },
-// { LLFastTimer::FTM_REBUILD_BRIDGE_VB, " Bridge", &LLColor4::blue2, 0 },
-// { LLFastTimer::FTM_REBUILD_HUD_VB, " HUD", &LLColor4::blue3, 0 },
- { LLFastTimer::FTM_REBUILD_TERRAIN_VB, " Terrain", &LLColor4::blue4, 0 },
-// { LLFastTimer::FTM_REBUILD_WATER_VB, " Water", &LLColor4::blue5, 0 },
-// { LLFastTimer::FTM_REBUILD_TREE_VB, " Tree", &LLColor4::cyan1, 0 },
- { LLFastTimer::FTM_REBUILD_PARTICLE_VB, " Particle", &LLColor4::cyan2, 0 },
-// { LLFastTimer::FTM_REBUILD_CLOUD_VB, " Cloud", &LLColor4::cyan3, 0 },
- { LLFastTimer::FTM_REBUILD_GRASS_VB, " Grass", &LLColor4::cyan4, 0 },
- { LLFastTimer::FTM_SHADOW_RENDER, " Shadow", &LLColor4::green5, 1 },
- { LLFastTimer::FTM_SHADOW_SIMPLE, " Simple", &LLColor4::yellow2, 1 },
- { LLFastTimer::FTM_SHADOW_ALPHA, " Alpha", &LLColor4::yellow6, 1 },
- { LLFastTimer::FTM_SHADOW_TERRAIN, " Terrain", &LLColor4::green6, 1 },
- { LLFastTimer::FTM_SHADOW_AVATAR, " Avatar", &LLColor4::yellow1, 1 },
- { LLFastTimer::FTM_SHADOW_TREE, " Tree", &LLColor4::yellow8, 1 },
- { LLFastTimer::FTM_RENDER_GEOMETRY, " Geometry", &LLColor4::green2, 1 },
- { LLFastTimer::FTM_POOLS, " Pools", &LLColor4::green3, 1 },
- { LLFastTimer::FTM_POOLRENDER, " RenderPool", &LLColor4::green4, 1 },
- { LLFastTimer::FTM_RENDER_TERRAIN, " Terrain", &LLColor4::green6, 0 },
- { LLFastTimer::FTM_RENDER_CHARACTERS, " Avatars", &LLColor4::yellow1, 0 },
- { LLFastTimer::FTM_RENDER_SIMPLE, " Simple", &LLColor4::yellow2, 0 },
- { LLFastTimer::FTM_RENDER_FULLBRIGHT, " Fullbright", &LLColor4::yellow5, 0 },
- { LLFastTimer::FTM_RENDER_GLOW, " Glow", &LLColor4::orange1, 0 },
- { LLFastTimer::FTM_RENDER_GRASS, " Grass", &LLColor4::yellow6, 0 },
- { LLFastTimer::FTM_RENDER_INVISIBLE, " Invisible", &LLColor4::red2, 0 },
- { LLFastTimer::FTM_RENDER_SHINY, " Shiny", &LLColor4::yellow3, 0 },
- { LLFastTimer::FTM_RENDER_BUMP, " Bump", &LLColor4::yellow4, 0 },
- { LLFastTimer::FTM_RENDER_TREES, " Trees", &LLColor4::yellow8, 0 },
- { LLFastTimer::FTM_RENDER_OCCLUSION, " Occlusion", &LLColor4::red1, 0 },
- { LLFastTimer::FTM_RENDER_CLOUDS, " Clouds", &LLColor4::yellow5, 0 },
- { LLFastTimer::FTM_RENDER_ALPHA, " Alpha", &LLColor4::yellow6, 0 },
- { LLFastTimer::FTM_RENDER_HUD, " HUD", &LLColor4::yellow7, 0 },
- { LLFastTimer::FTM_RENDER_WATER, " Water", &LLColor4::yellow9, 0 },
- { LLFastTimer::FTM_RENDER_WL_SKY, " WL Sky", &LLColor4::blue3, 0 },
- { LLFastTimer::FTM_RENDER_FAKE_VBO_UPDATE," Fake VBO update", &LLColor4::red2, 0 },
- { LLFastTimer::FTM_RENDER_BLOOM, " Bloom", &LLColor4::blue4, 0 },
- { LLFastTimer::FTM_RENDER_BLOOM_FBO, " First FBO", &LLColor4::blue, 0 },
- { LLFastTimer::FTM_RENDER_UI, " UI", &LLColor4::cyan4, 1 },
- { LLFastTimer::FTM_RENDER_TIMER, " Timers", &LLColor4::cyan5, 1, 0 },
- { LLFastTimer::FTM_RENDER_FONTS, " Fonts", &LLColor4::pink1, 0 },
- { LLFastTimer::FTM_SWAP, " Swap", &LLColor4::pink2, 0 },
- { LLFastTimer::FTM_CLIENT_COPY, " Client Copy", &LLColor4::red1, 1},
-
-#if 0 || !LL_RELEASE_FOR_DOWNLOAD
- { LLFastTimer::FTM_TEMP1, " Temp1", &LLColor4::red1, 0 },
- { LLFastTimer::FTM_TEMP2, " Temp2", &LLColor4::magenta1, 0 },
- { LLFastTimer::FTM_TEMP3, " Temp3", &LLColor4::red2, 0 },
- { LLFastTimer::FTM_TEMP4, " Temp4", &LLColor4::magenta2, 0 },
- { LLFastTimer::FTM_TEMP5, " Temp5", &LLColor4::red3, 0 },
- { LLFastTimer::FTM_TEMP6, " Temp6", &LLColor4::magenta3, 0 },
- { LLFastTimer::FTM_TEMP7, " Temp7", &LLColor4::red4, 0 },
- { LLFastTimer::FTM_TEMP8, " Temp8", &LLColor4::magenta4, 0 },
-#endif
-
- { LLFastTimer::FTM_OTHER, " Other", &red0 }
-};
-static int ft_display_didcalc = 0;
-static const int FTV_DISPLAY_NUM = LL_ARRAY_SIZE(ft_display_table);
+//static const int FTV_DISPLAY_NUM = (sizeof(ft_display_table)/sizeof(ft_display_table[0]));
+static S32 FTV_NUM_TIMERS;
+const S32 FTV_MAX_DEPTH = 8;
+
+std::vector<LLFastTimer::NamedTimer*> ft_display_idx; // line of table entry for display purposes (for collapse)
+
+typedef LLTreeDFSIter<LLFastTimer::NamedTimer, LLFastTimer::NamedTimer::child_const_iter> timer_tree_iterator_t;
-S32 ft_display_idx[FTV_DISPLAY_NUM]; // line of table entry for display purposes (for collapse)
+BOOL LLFastTimerView::sAnalyzePerformance = FALSE;
+
+static timer_tree_iterator_t begin_timer_tree(LLFastTimer::NamedTimer& id)
+{
+ return timer_tree_iterator_t(&id,
+ boost::bind(boost::mem_fn(&LLFastTimer::NamedTimer::beginChildren), _1),
+ boost::bind(boost::mem_fn(&LLFastTimer::NamedTimer::endChildren), _1));
+}
+
+static timer_tree_iterator_t end_timer_tree()
+{
+ return timer_tree_iterator_t();
+}
-LLFastTimerView::LLFastTimerView(const std::string& name, const LLRect& rect)
- : LLFloater(name, rect, std::string("Fast Timers"))
+LLFastTimerView::LLFastTimerView(const LLRect& rect)
+: LLFloater(LLSD()),
+ mHoverTimer(NULL)
{
+ setRect(rect);
setVisible(FALSE);
mDisplayMode = 0;
mAvgCountTotal = 0;
mMaxCountTotal = 0;
- mDisplayCenter = 1;
+ mDisplayCenter = ALIGN_CENTER;
mDisplayCalls = 0;
mDisplayHz = 0;
mScrollIndex = 0;
- mHoverIndex = -1;
+ mHoverID = NULL;
mHoverBarIndex = -1;
- mBarStart = new S32[(MAX_VISIBLE_HISTORY + 1) * FTV_DISPLAY_NUM];
- memset(mBarStart, 0, (MAX_VISIBLE_HISTORY + 1) * FTV_DISPLAY_NUM * sizeof(S32));
- mBarEnd = new S32[(MAX_VISIBLE_HISTORY + 1) * FTV_DISPLAY_NUM];
- memset(mBarEnd, 0, (MAX_VISIBLE_HISTORY + 1) * FTV_DISPLAY_NUM * sizeof(S32));
- mSubtractHidden = 0;
+ FTV_NUM_TIMERS = LLFastTimer::NamedTimer::instanceCount();
mPrintStats = -1;
-
- // One-time setup
- if (!ft_display_didcalc)
- {
- int pidx[FTV_DISPLAY_NUM];
- int pdisabled[FTV_DISPLAY_NUM];
- for (S32 i=0; i < FTV_DISPLAY_NUM; i++)
- {
- int level = 0;
- const char *text = ft_display_table[i].desc;
- while(text[0] == ' ')
- {
- text++;
- level++;
- }
- llassert(level < FTV_DISPLAY_NUM);
- ft_display_table[i].desc = text;
- ft_display_table[i].level = level;
- if (level > 0)
- {
- ft_display_table[i].parent = pidx[level-1];
- if (pdisabled[level-1])
- {
- ft_display_table[i].disabled = 3;
- }
- }
- else
- {
- ft_display_table[i].parent = -1;
- }
- ft_display_idx[i] = i;
- pidx[level] = i;
- pdisabled[level] = ft_display_table[i].disabled;
- }
- ft_display_didcalc = 1;
- }
}
-LLFastTimerView::~LLFastTimerView()
-{
- delete[] mBarStart;
- delete[] mBarEnd;
-}
BOOL LLFastTimerView::handleRightMouseDown(S32 x, S32 y, MASK mask)
{
- if (mBarRect.pointInRect(x, y))
+ if (mHoverTimer )
+ {
+ // right click collapses timers
+ if (!mHoverTimer->getCollapsed())
+ {
+ mHoverTimer->setCollapsed(true);
+ }
+ else if (mHoverTimer->getParent())
+ {
+ mHoverTimer->getParent()->setCollapsed(true);
+ }
+ }
+ else if (mBarRect.pointInRect(x, y))
{
S32 bar_idx = MAX_VISIBLE_HISTORY - ((y - mBarRect.mBottom) * (MAX_VISIBLE_HISTORY + 2) / mBarRect.getHeight());
bar_idx = llclamp(bar_idx, 0, MAX_VISIBLE_HISTORY);
mPrintStats = bar_idx;
-// return TRUE; // for now, pass all mouse events through
}
return FALSE;
}
-S32 LLFastTimerView::getLegendIndex(S32 y)
+LLFastTimer::NamedTimer* LLFastTimerView::getLegendID(S32 y)
{
S32 idx = (getRect().getHeight() - y) / ((S32) LLFontGL::getFontMonospace()->getLineHeight()+2) - 5;
- if (idx >= 0 && idx < FTV_DISPLAY_NUM)
+
+ if (idx >= 0 && idx < (S32)ft_display_idx.size())
{
return ft_display_idx[idx];
}
- return -1;
+ return NULL;
}
BOOL LLFastTimerView::handleMouseDown(S32 x, S32 y, MASK mask)
{
if (x < mBarRect.mLeft)
{
- S32 legend_index = getLegendIndex(y);
- if (legend_index >= 0 && legend_index < FTV_DISPLAY_NUM)
+ LLFastTimer::NamedTimer* idp = getLegendID(y);
+ if (idp)
{
- S32 disabled = ft_display_table[legend_index].disabled;
- if (++disabled > 2)
- disabled = 0;
- ft_display_table[legend_index].disabled = disabled;
- S32 level = ft_display_table[legend_index].level;
-
- // propagate enable/disable to all children
- legend_index++;
- while (legend_index < FTV_DISPLAY_NUM && ft_display_table[legend_index].level > level)
- {
- ft_display_table[legend_index].disabled = disabled ? 3 : 0;
- legend_index++;
- }
+ idp->setCollapsed(!idp->getCollapsed());
}
}
+ else if (mHoverTimer)
+ {
+ //left click drills down by expanding timers
+ mHoverTimer->setCollapsed(false);
+ }
else if (mask & MASK_ALT)
{
- if (mask & MASK_SHIFT)
- {
- mSubtractHidden = !mSubtractHidden;
- }
- else if (mask & MASK_CONTROL)
+ if (mask & MASK_CONTROL)
{
mDisplayHz = !mDisplayHz;
}
@@ -345,8 +167,7 @@ BOOL LLFastTimerView::handleMouseDown(S32 x, S32 y, MASK mask)
}
else if (mask & MASK_CONTROL)
{
- if (++mDisplayCenter > 2)
- mDisplayCenter = 0;
+ mDisplayCenter = (ChildAlignment)((mDisplayCenter + 1) % ALIGN_COUNT);
}
else
{
@@ -367,13 +188,15 @@ BOOL LLFastTimerView::handleMouseUp(S32 x, S32 y, MASK mask)
return FALSE;
}
-
BOOL LLFastTimerView::handleHover(S32 x, S32 y, MASK mask)
{
+ mHoverTimer = NULL;
+ mHoverID = NULL;
+
if(LLFastTimer::sPauseHistory && mBarRect.pointInRect(x, y))
{
- mHoverIndex = -1;
- mHoverBarIndex = MAX_VISIBLE_HISTORY - ((y - mBarRect.mBottom) * (MAX_VISIBLE_HISTORY + 2) / mBarRect.getHeight());
+ mHoverBarIndex = llmin(LLFastTimer::getCurFrameIndex() - 1,
+ MAX_VISIBLE_HISTORY - ((y - mBarRect.mBottom) * (MAX_VISIBLE_HISTORY + 2) / mBarRect.getHeight()));
if (mHoverBarIndex == 0)
{
return TRUE;
@@ -382,39 +205,89 @@ BOOL LLFastTimerView::handleHover(S32 x, S32 y, MASK mask)
{
mHoverBarIndex = 0;
}
- for (S32 i = 0; i < FTV_DISPLAY_NUM; i++)
+
+ S32 i = 0;
+ for(timer_tree_iterator_t it = begin_timer_tree(LLFastTimer::NamedTimer::getRootNamedTimer());
+ it != end_timer_tree();
+ ++it, ++i)
{
- if (x > mBarStart[mHoverBarIndex * FTV_DISPLAY_NUM + i] &&
- x < mBarEnd[mHoverBarIndex * FTV_DISPLAY_NUM + i] &&
- ft_display_table[i].disabled <= 1)
+ // is mouse over bar for this timer?
+ if (x > mBarStart[mHoverBarIndex][i] &&
+ x < mBarEnd[mHoverBarIndex][i])
{
- mHoverIndex = i;
+ mHoverID = (*it);
+ mHoverTimer = (*it);
+ mToolTipRect.set(mBarStart[mHoverBarIndex][i],
+ mBarRect.mBottom + llround(((F32)(MAX_VISIBLE_HISTORY - mHoverBarIndex + 1)) * ((F32)mBarRect.getHeight() / ((F32)MAX_VISIBLE_HISTORY + 2.f))),
+ mBarEnd[mHoverBarIndex][i],
+ mBarRect.mBottom + llround((F32)(MAX_VISIBLE_HISTORY - mHoverBarIndex) * ((F32)mBarRect.getHeight() / ((F32)MAX_VISIBLE_HISTORY + 2.f))));
+ }
+
+ if ((*it)->getCollapsed())
+ {
+ it.skipDescendants();
}
}
}
else if (x < mBarRect.mLeft)
{
- S32 legend_index = getLegendIndex(y);
- if (legend_index >= 0 && legend_index < FTV_DISPLAY_NUM)
+ LLFastTimer::NamedTimer* timer_id = getLegendID(y);
+ if (timer_id)
{
- mHoverIndex = legend_index;
+ mHoverID = timer_id;
}
}
return FALSE;
}
+
+BOOL LLFastTimerView::handleToolTip(S32 x, S32 y, std::string& msg, LLRect* sticky_rect_screen)
+{
+ if(LLFastTimer::sPauseHistory && mBarRect.pointInRect(x, y))
+ {
+ // tooltips for timer bars
+ if (mHoverTimer)
+ {
+ localRectToScreen(mToolTipRect, sticky_rect_screen);
+ msg = mHoverTimer->getToolTip(LLFastTimer::NamedTimer::HISTORY_NUM - mScrollIndex - mHoverBarIndex);
+ return TRUE;
+ }
+ }
+ else
+ {
+ // tooltips for timer legend
+ if (x < mBarRect.mLeft)
+ {
+ LLFastTimer::NamedTimer* idp = getLegendID(y);
+ if (idp)
+ {
+ msg = idp->getToolTip();
+ return TRUE;
+ }
+ }
+
+ }
+
+ return FALSE;
+}
+
BOOL LLFastTimerView::handleScrollWheel(S32 x, S32 y, S32 clicks)
{
LLFastTimer::sPauseHistory = TRUE;
mScrollIndex = llclamp(mScrollIndex - clicks,
- 0, llmin(LLFastTimer::sLastFrameIndex, (S32)LLFastTimer::FTM_HISTORY_NUM-MAX_VISIBLE_HISTORY));
+ 0,
+ llmin(LLFastTimer::getLastFrameIndex(), (S32)LLFastTimer::NamedTimer::HISTORY_NUM - MAX_VISIBLE_HISTORY));
return TRUE;
}
+static LLFastTimer::DeclareTimer FTM_RENDER_TIMER("Timers", true);
+
+static std::map<LLFastTimer::NamedTimer*, LLColor4> sTimerColors;
+
void LLFastTimerView::draw()
{
- LLFastTimer t(LLFastTimer::FTM_RENDER_TIMER);
+ LLFastTimer t(FTM_RENDER_TIMER);
std::string tdesc;
@@ -433,47 +306,9 @@ void LLFastTimerView::draw()
S32 texth, textw;
LLPointer<LLUIImage> box_imagep = LLUI::getUIImage("rounded_square.tga");
- // Make sure all timers are accounted for
- // Set 'FTM_OTHER' to unaccounted ticks last frame
- {
- S32 display_timer[LLFastTimer::FTM_NUM_TYPES];
- S32 hidx = LLFastTimer::sLastFrameIndex % LLFastTimer::FTM_HISTORY_NUM;
- for (S32 i=0; i < LLFastTimer::FTM_NUM_TYPES; i++)
- {
- display_timer[i] = 0;
- }
- for (S32 i=0; i < FTV_DISPLAY_NUM; i++)
- {
- S32 tidx = ft_display_table[i].timer;
- display_timer[tidx] = 1;
- }
- LLFastTimer::sCountHistory[hidx][LLFastTimer::FTM_OTHER] = 0;
- LLFastTimer::sCallHistory[hidx][LLFastTimer::FTM_OTHER] = 0;
- for (S32 tidx = 0; tidx < LLFastTimer::FTM_NUM_TYPES; tidx++)
- {
- U64 counts = LLFastTimer::sCountHistory[hidx][tidx];
- if (counts > 0 && display_timer[tidx] == 0)
- {
- LLFastTimer::sCountHistory[hidx][LLFastTimer::FTM_OTHER] += counts;
- LLFastTimer::sCallHistory[hidx][LLFastTimer::FTM_OTHER] += 1;
- }
- }
- LLFastTimer::sCountAverage[LLFastTimer::FTM_OTHER] = 0;
- LLFastTimer::sCallAverage[LLFastTimer::FTM_OTHER] = 0;
- for (S32 h = 0; h < LLFastTimer::FTM_HISTORY_NUM; h++)
- {
- LLFastTimer::sCountAverage[LLFastTimer::FTM_OTHER] += LLFastTimer::sCountHistory[h][LLFastTimer::FTM_OTHER];
- LLFastTimer::sCallAverage[LLFastTimer::FTM_OTHER] += LLFastTimer::sCallHistory[h][LLFastTimer::FTM_OTHER];
- }
- LLFastTimer::sCountAverage[LLFastTimer::FTM_OTHER] /= LLFastTimer::FTM_HISTORY_NUM;
- LLFastTimer::sCallAverage[LLFastTimer::FTM_OTHER] /= LLFastTimer::FTM_HISTORY_NUM;
- }
-
// Draw the window background
- {
- gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
- gl_rect_2d(0, getRect().getHeight(), getRect().getWidth(), 0, LLColor4(0.f, 0.f, 0.f, 0.25f));
- }
+ gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
+ gl_rect_2d(0, getRect().getHeight(), getRect().getWidth(), 0, LLColor4(0.f, 0.f, 0.f, 0.25f));
S32 xleft = margin;
S32 ytop = margin;
@@ -512,148 +347,135 @@ void LLFastTimerView::draw()
y -= (texth + 2);
}
- // Calc the total ticks
- S32 histmax = llmin(LLFastTimer::sLastFrameIndex+1, MAX_VISIBLE_HISTORY);
- U64 ticks_sum[LLFastTimer::FTM_HISTORY_NUM+1][FTV_DISPLAY_NUM];
- for (S32 j=-1; j<LLFastTimer::FTM_HISTORY_NUM; j++)
- {
- S32 hidx;
- if (j >= 0)
- hidx = (LLFastTimer::sLastFrameIndex+j) % LLFastTimer::FTM_HISTORY_NUM;
- else
- hidx = -1;
-
- // calculate tick info by adding child ticks to parents
- for (S32 i=0; i < FTV_DISPLAY_NUM; i++)
- {
- if (mSubtractHidden && ft_display_table[i].disabled > 1)
- {
- continue;
- }
- // Get ticks
- S32 tidx = ft_display_table[i].timer;
- if (hidx >= 0)
- ticks_sum[j+1][i] = LLFastTimer::sCountHistory[hidx][tidx];
- else
- ticks_sum[j+1][i] = LLFastTimer::sCountAverage[tidx];
- S32 pidx = ft_display_table[i].parent;
- // Add ticks to parents
- while (pidx >= 0)
- {
- ticks_sum[j+1][pidx] += ticks_sum[j+1][i];
- pidx = ft_display_table[pidx].parent;
- }
- }
- }
+ S32 histmax = llmin(LLFastTimer::getLastFrameIndex()+1, MAX_VISIBLE_HISTORY);
// Draw the legend
-
- S32 legendwidth = 0;
xleft = margin;
ytop = y;
y -= (texth + 2);
- S32 cur_line = 0;
- S32 display_line[FTV_DISPLAY_NUM];
- for (S32 i=0; i<FTV_DISPLAY_NUM; i++)
+ sTimerColors[&LLFastTimer::NamedTimer::getRootNamedTimer()] = LLColor4::grey;
+
+ F32 hue = 0.f;
+
+ for (timer_tree_iterator_t it = begin_timer_tree(LLFastTimer::NamedTimer::getRootNamedTimer());
+ it != timer_tree_iterator_t();
+ ++it)
{
- S32 disabled = ft_display_table[i].disabled;
- if (disabled == 3)
- {
- continue; // skip row
- }
- display_line[i] = cur_line;
- ft_display_idx[cur_line] = i;
- cur_line++;
- S32 level = ft_display_table[i].level;
- S32 parent = ft_display_table[i].parent;
-
- x = xleft;
+ LLFastTimer::NamedTimer* idp = (*it);
- left = x; right = x + texth;
- top = y; bottom = y - texth;
- S32 scale_offset = 0;
- if (i == mHoverIndex)
- {
- scale_offset = llfloor(sinf(mHighlightTimer.getElapsedTimeF32() * 6.f) * 2.f);
- }
- gl_rect_2d(left - scale_offset, top + scale_offset, right + scale_offset, bottom - scale_offset, *ft_display_table[i].color);
+ const F32 HUE_INCREMENT = 0.23f;
+ hue = fmodf(hue + HUE_INCREMENT, 1.f);
+ // saturation increases with depth
+ F32 saturation = clamp_rescale((F32)idp->getDepth(), 0.f, 3.f, 0.f, 1.f);
+ // lightness alternates with depth
+ F32 lightness = idp->getDepth() % 2 ? 0.5f : 0.6f;
- int tidx = ft_display_table[i].timer;
- F32 ms = 0;
- S32 calls = 0;
- if (mHoverBarIndex > 0 && mHoverIndex >= 0)
- {
- S32 hidx = (LLFastTimer::sLastFrameIndex + (mHoverBarIndex - 1) - mScrollIndex) % LLFastTimer::FTM_HISTORY_NUM;
- S32 bidx = LLFastTimer::FTM_HISTORY_NUM - mScrollIndex - mHoverBarIndex;
- U64 ticks = ticks_sum[bidx+1][i]; // : LLFastTimer::sCountHistory[hidx][tidx];
- ms = (F32)((F64)ticks * iclock_freq);
- calls = (S32)LLFastTimer::sCallHistory[hidx][tidx];
- }
- else
- {
- U64 ticks = ticks_sum[0][i];
- ms = (F32)((F64)ticks * iclock_freq);
- calls = (S32)LLFastTimer::sCallAverage[tidx];
- }
- if (mDisplayCalls)
- {
- tdesc = llformat("%s (%d)",ft_display_table[i].desc,calls);
- }
- else
- {
- tdesc = llformat("%s [%.1f]",ft_display_table[i].desc,ms);
- }
- dx = (texth+4) + level*8;
+ LLColor4 child_color;
+ child_color.setHSL(hue, saturation, lightness);
- LLColor4 color = disabled > 1 ? LLColor4::grey : LLColor4::white;
- if (level > 0)
+ sTimerColors[idp] = child_color;
+ }
+
+ const S32 LEGEND_WIDTH = 220;
+ {
+ LLLocalClipRect clip(LLRect(margin, y, LEGEND_WIDTH, margin));
+ S32 cur_line = 0;
+ ft_display_idx.clear();
+ std::map<LLFastTimer::NamedTimer*, S32> display_line;
+ for (timer_tree_iterator_t it = begin_timer_tree(LLFastTimer::NamedTimer::getRootNamedTimer());
+ it != timer_tree_iterator_t();
+ ++it)
{
- S32 line_start_y = (top + bottom) / 2;
- S32 line_end_y = line_start_y + ((texth + 2) * (display_line[i] - display_line[parent])) - (texth / 2);
- gl_line_2d(x + dx - 8, line_start_y, x + dx, line_start_y, color);
- S32 line_x = x + (texth + 4) + ((level - 1) * 8);
- gl_line_2d(line_x, line_start_y, line_x, line_end_y, color);
- if (disabled == 1)
+ LLFastTimer::NamedTimer* idp = (*it);
+ display_line[idp] = cur_line;
+ ft_display_idx.push_back(idp);
+ cur_line++;
+
+ x = xleft;
+
+ left = x; right = x + texth;
+ top = y; bottom = y - texth;
+ S32 scale_offset = 0;
+ if (idp == mHoverID)
{
- gl_line_2d(line_x+4, line_start_y-3, line_x+4, line_start_y+4, color);
+ scale_offset = llfloor(sinf(mHighlightTimer.getElapsedTimeF32() * 6.f) * 2.f);
}
- }
+ gl_rect_2d(left - scale_offset, top + scale_offset, right + scale_offset, bottom - scale_offset, sTimerColors[idp]);
- x += dx;
- BOOL is_child_of_hover_item = (i == mHoverIndex);
- S32 next_parent = ft_display_table[i].parent;
- while(!is_child_of_hover_item && next_parent >= 0)
- {
- is_child_of_hover_item = (mHoverIndex == next_parent);
- next_parent = ft_display_table[next_parent].parent;
- }
+ F32 ms = 0;
+ S32 calls = 0;
+ if (mHoverBarIndex > 0 && mHoverID)
+ {
+ S32 hidx = LLFastTimer::NamedTimer::HISTORY_NUM - mScrollIndex - mHoverBarIndex;
+ U64 ticks = idp->getHistoricalCount(hidx);
+ ms = (F32)((F64)ticks * iclock_freq);
+ calls = (S32)idp->getHistoricalCalls(hidx);
+ }
+ else
+ {
+ U64 ticks = idp->getCountAverage();
+ ms = (F32)((F64)ticks * iclock_freq);
+ calls = (S32)idp->getCallAverage();
+ }
- if (is_child_of_hover_item)
- {
- LLFontGL::getFontMonospace()->renderUTF8(tdesc, 0, x, y, color, LLFontGL::LEFT, LLFontGL::TOP, LLFontGL::BOLD);
- }
- else
- {
- LLFontGL::getFontMonospace()->renderUTF8(tdesc, 0, x, y, color, LLFontGL::LEFT, LLFontGL::TOP);
- }
- y -= (texth + 2);
+ if (mDisplayCalls)
+ {
+ tdesc = llformat("%s (%d)",idp->getName().c_str(),calls);
+ }
+ else
+ {
+ tdesc = llformat("%s [%.1f]",idp->getName().c_str(),ms);
+ }
+ dx = (texth+4) + idp->getDepth()*8;
- textw = dx + LLFontGL::getFontMonospace()->getWidth(std::string(ft_display_table[i].desc)) + 40;
- if (textw > legendwidth)
- legendwidth = textw;
- }
- for (S32 i=cur_line; i<FTV_DISPLAY_NUM; i++)
- {
- ft_display_idx[i] = -1;
+ LLColor4 color = LLColor4::white;
+ if (idp->getDepth() > 0)
+ {
+ S32 line_start_y = (top + bottom) / 2;
+ S32 line_end_y = line_start_y + ((texth + 2) * (cur_line - display_line[idp->getParent()])) - texth;
+ gl_line_2d(x + dx - 8, line_start_y, x + dx, line_start_y, color);
+ S32 line_x = x + (texth + 4) + ((idp->getDepth() - 1) * 8);
+ gl_line_2d(line_x, line_start_y, line_x, line_end_y, color);
+ if (idp->getCollapsed() && !idp->getChildren().empty())
+ {
+ gl_line_2d(line_x+4, line_start_y-3, line_x+4, line_start_y+4, color);
+ }
+ }
+
+ x += dx;
+ BOOL is_child_of_hover_item = (idp == mHoverID);
+ LLFastTimer::NamedTimer* next_parent = idp->getParent();
+ while(!is_child_of_hover_item && next_parent)
+ {
+ is_child_of_hover_item = (mHoverID == next_parent);
+ next_parent = next_parent->getParent();
+ }
+
+ LLFontGL::getFontMonospace()->renderUTF8(tdesc, 0,
+ x, y,
+ color,
+ LLFontGL::LEFT, LLFontGL::TOP,
+ is_child_of_hover_item ? LLFontGL::BOLD : LLFontGL::NORMAL);
+
+ y -= (texth + 2);
+
+ textw = dx + LLFontGL::getFontMonospace()->getWidth(idp->getName()) + 40;
+
+ if (idp->getCollapsed())
+ {
+ it.skipDescendants();
+ }
+ }
}
- xleft += legendwidth + 8;
+
+ xleft += LEGEND_WIDTH + 8;
// ytop = ytop;
// update rectangle that includes timer bars
mBarRect.mLeft = xleft;
- mBarRect.mRight = getRect().mRight - xleft;
+ mBarRect.mRight = getRect().getWidth();
mBarRect.mTop = ytop - ((S32)LLFontGL::getFontMonospace()->getLineHeight() + 4);
mBarRect.mBottom = margin + LINE_GRAPH_HEIGHT;
@@ -665,25 +487,18 @@ void LLFastTimerView::draw()
barw = width - xleft - margin;
// Draw the history bars
- if (LLFastTimer::sLastFrameIndex >= 0)
+ if (LLFastTimer::getLastFrameIndex() >= 0)
{
+ LLLocalClipRect clip(LLRect(xleft, ytop - margin, getRect().getWidth() - margin, margin));
+
U64 totalticks;
if (!LLFastTimer::sPauseHistory)
{
- U64 ticks = 0;
- int hidx = (LLFastTimer::sLastFrameIndex - mScrollIndex) % LLFastTimer::FTM_HISTORY_NUM;
- for (S32 i=0; i<FTV_DISPLAY_NUM; i++)
- {
- if (mSubtractHidden && ft_display_table[i].disabled > 1)
- {
- continue;
- }
- int tidx = ft_display_table[i].timer;
- ticks += LLFastTimer::sCountHistory[hidx][tidx];
- }
- if (LLFastTimer::sCurFrameIndex >= 10)
+ U64 ticks = LLFastTimer::NamedTimer::getRootNamedTimer().getHistoricalCount(mScrollIndex);
+
+ if (LLFastTimer::getCurFrameIndex() >= 10)
{
- U64 framec = LLFastTimer::sCurFrameIndex;
+ U64 framec = LLFastTimer::getCurFrameIndex();
U64 avg = (U64)mAvgCountTotal;
mAvgCountTotal = (avg*framec + ticks) / (framec + 1);
if (ticks > mMaxCountTotal)
@@ -691,11 +506,13 @@ void LLFastTimerView::draw()
mMaxCountTotal = ticks;
}
}
-#if 1
+
if (ticks < mAvgCountTotal/100 || ticks > mAvgCountTotal*100)
- LLFastTimer::sResetHistory = 1;
-#endif
- if (LLFastTimer::sCurFrameIndex < 10 || LLFastTimer::sResetHistory)
+ {
+ LLFastTimer::sResetHistory = true;
+ }
+
+ if (LLFastTimer::getCurFrameIndex() < 10 || LLFastTimer::sResetHistory)
{
mAvgCountTotal = ticks;
mMaxCountTotal = ticks;
@@ -716,16 +533,8 @@ void LLFastTimerView::draw()
totalticks = 0;
for (S32 j=0; j<histmax; j++)
{
- U64 ticks = 0;
- for (S32 i=0; i<FTV_DISPLAY_NUM; i++)
- {
- if (mSubtractHidden && ft_display_table[i].disabled > 1)
- {
- continue;
- }
- int tidx = ft_display_table[i].timer;
- ticks += LLFastTimer::sCountHistory[j][tidx];
- }
+ U64 ticks = LLFastTimer::NamedTimer::getRootNamedTimer().getHistoricalCount(j);
+
if (ticks > totalticks)
totalticks = ticks;
}
@@ -798,18 +607,23 @@ void LLFastTimerView::draw()
gl_rect_2d(graph_rect, FALSE);
}
+ mBarStart.clear();
+ mBarEnd.clear();
+
// Draw bars for each history entry
// Special: -1 = show running average
gGL.getTexUnit(0)->bind(box_imagep->getImage());
for (S32 j=-1; j<histmax && y > LINE_GRAPH_HEIGHT; j++)
{
- int sublevel_dx[FTV_DISPLAY_NUM+1];
- int sublevel_left[FTV_DISPLAY_NUM+1];
- int sublevel_right[FTV_DISPLAY_NUM+1];
+ mBarStart.push_back(std::vector<S32>());
+ mBarEnd.push_back(std::vector<S32>());
+ int sublevel_dx[FTV_MAX_DEPTH];
+ int sublevel_left[FTV_MAX_DEPTH];
+ int sublevel_right[FTV_MAX_DEPTH];
S32 tidx;
if (j >= 0)
{
- tidx = LLFastTimer::FTM_HISTORY_NUM - j - 1 - mScrollIndex;
+ tidx = LLFastTimer::NamedTimer::HISTORY_NUM - j - 1 - mScrollIndex;
}
else
{
@@ -819,88 +633,75 @@ void LLFastTimerView::draw()
x = xleft;
// draw the bars for each stat
- int xpos[FTV_DISPLAY_NUM+1];
- int deltax[FTV_DISPLAY_NUM+1];
- xpos[0] = xleft;
+ std::vector<S32> xpos;
+ std::vector<S32> deltax;
+ xpos.push_back(xleft);
+
+ LLFastTimer::NamedTimer* prev_id = NULL;
- for (S32 i = 0; i < FTV_DISPLAY_NUM; i++)
+ S32 i = 0;
+ for(timer_tree_iterator_t it = begin_timer_tree(LLFastTimer::NamedTimer::getRootNamedTimer());
+ it != end_timer_tree();
+ ++it, ++i)
{
- if (ft_display_table[i].disabled > 1)
- {
- continue;
- }
-
- F32 frac = (F32)ticks_sum[tidx+1][i] / (F32)totalticks;
+ LLFastTimer::NamedTimer* idp = (*it);
+ F32 frac = tidx == -1
+ ? (F32)idp->getCountAverage() / (F32)totalticks
+ : (F32)idp->getHistoricalCount(tidx) / (F32)totalticks;
dx = llround(frac * (F32)barw);
- deltax[i] = dx;
-
- int level = ft_display_table[i].level;
- int parent = ft_display_table[i].parent;
- llassert(level < FTV_DISPLAY_NUM);
- llassert(parent < FTV_DISPLAY_NUM);
+ S32 prev_delta_x = deltax.empty() ? 0 : deltax.back();
+ deltax.push_back(dx);
- left = xpos[level];
+ int level = idp->getDepth() - 1;
- S32 prev_idx = i - 1;
- while (prev_idx > 0)
- {
- if (ft_display_table[prev_idx].disabled <= 1)
- {
- break;
- }
- prev_idx--;
- }
- S32 next_idx = i + 1;
- while (next_idx < FTV_DISPLAY_NUM)
+ while ((S32)xpos.size() > level + 1)
{
- if (ft_display_table[next_idx].disabled <= 1)
- {
- break;
- }
- next_idx++;
+ xpos.pop_back();
}
-
+ left = xpos.back();
+
if (level == 0)
- {
+ {
sublevel_left[level] = xleft;
sublevel_dx[level] = dx;
sublevel_right[level] = sublevel_left[level] + sublevel_dx[level];
- }
- else if (i==0 || ft_display_table[prev_idx].level < level)
+ }
+ else if (prev_id && prev_id->getDepth() < idp->getDepth())
{
- // If we are the first entry at a new sublevel block, calc the
- // total width of this sublevel and modify left to align block.
- U64 sublevelticks = ticks_sum[tidx+1][i];
- for (S32 k=i+1; k<FTV_DISPLAY_NUM; k++)
- {
- if (ft_display_table[k].level < level)
- break;
- if (ft_display_table[k].disabled <= 1 && ft_display_table[k].level == level)
- sublevelticks += ticks_sum[tidx+1][k];
- }
- F32 subfrac = (F32)sublevelticks / (F32)totalticks;
+ U64 sublevelticks = 0;
+
+ for (LLFastTimer::NamedTimer::child_const_iter it = prev_id->beginChildren();
+ it != prev_id->endChildren();
+ ++it)
+ {
+ sublevelticks += (tidx == -1)
+ ? (*it)->getCountAverage()
+ : (*it)->getHistoricalCount(tidx);
+ }
+
+ F32 subfrac = (F32)sublevelticks / (F32)totalticks;
sublevel_dx[level] = (int)(subfrac * (F32)barw + .5f);
- if (mDisplayCenter == 1) // center aligned
+ if (mDisplayCenter == ALIGN_CENTER)
{
- left += (deltax[parent] - sublevel_dx[level])/2;
+ left += (prev_delta_x - sublevel_dx[level])/2;
}
- else if (mDisplayCenter == 2) // right aligned
+ else if (mDisplayCenter == ALIGN_RIGHT)
{
- left += (deltax[parent] - sublevel_dx[level]);
- }
+ left += (prev_delta_x - sublevel_dx[level]);
+ }
sublevel_left[level] = left;
sublevel_right[level] = sublevel_left[level] + sublevel_dx[level];
}
right = left + dx;
- xpos[level] = right;
- xpos[level+1] = left;
+ xpos.back() = right;
+ xpos.push_back(left);
- mBarStart[(j + 1) * FTV_DISPLAY_NUM + i] = left;
- mBarEnd[(j + 1) * FTV_DISPLAY_NUM + i] = right;
+ mBarStart.back().push_back(left);
+ mBarEnd.back().push_back(right);
top = y;
bottom = y - barh;
@@ -908,23 +709,23 @@ void LLFastTimerView::draw()
if (right > left)
{
//U32 rounded_edges = 0;
- LLColor4 color = *ft_display_table[i].color;
+ LLColor4 color = sTimerColors[idp];//*ft_display_table[i].color;
S32 scale_offset = 0;
- BOOL is_child_of_hover_item = (i == mHoverIndex);
- S32 next_parent = ft_display_table[i].parent;
- while(!is_child_of_hover_item && next_parent >= 0)
+ BOOL is_child_of_hover_item = (idp == mHoverID);
+ LLFastTimer::NamedTimer* next_parent = idp->getParent();
+ while(!is_child_of_hover_item && next_parent)
{
- is_child_of_hover_item = (mHoverIndex == next_parent);
- next_parent = ft_display_table[next_parent].parent;
+ is_child_of_hover_item = (mHoverID == next_parent);
+ next_parent = next_parent->getParent();
}
- if (i == mHoverIndex)
+ if (idp == mHoverID)
{
scale_offset = llfloor(sinf(mHighlightTimer.getElapsedTimeF32() * 6.f) * 3.f);
//color = lerp(color, LLColor4::black, -0.4f);
}
- else if (mHoverIndex >= 0 && !is_child_of_hover_item)
+ else if (mHoverID != NULL && !is_child_of_hover_item)
{
color = lerp(color, LLColor4::grey, 0.8f);
}
@@ -935,7 +736,13 @@ void LLFastTimerView::draw()
gl_segmented_rect_2d_fragment_tex(sublevel_left[level], top - level + scale_offset, sublevel_right[level], bottom + level - scale_offset, box_imagep->getTextureWidth(), box_imagep->getTextureHeight(), 16, start_fragment, end_fragment);
}
-
+
+ if ((*it)->getCollapsed())
+ {
+ it.skipDescendants();
+ }
+
+ prev_id = idp;
}
y -= (barh + dy);
if (j < 0)
@@ -970,10 +777,10 @@ void LLFastTimerView::draw()
//highlight visible range
{
- S32 first_frame = LLFastTimer::FTM_HISTORY_NUM - mScrollIndex;
+ S32 first_frame = LLFastTimer::NamedTimer::HISTORY_NUM - mScrollIndex;
S32 last_frame = first_frame - MAX_VISIBLE_HISTORY;
- F32 frame_delta = ((F32) (graph_rect.getWidth()))/(LLFastTimer::FTM_HISTORY_NUM-1);
+ F32 frame_delta = ((F32) (graph_rect.getWidth()))/(LLFastTimer::NamedTimer::HISTORY_NUM-1);
F32 right = (F32) graph_rect.mLeft + frame_delta*first_frame;
F32 left = (F32) graph_rect.mLeft + frame_delta*last_frame;
@@ -996,28 +803,27 @@ void LLFastTimerView::draw()
}
U64 cur_max = 0;
- for (S32 idx = 0; idx < FTV_DISPLAY_NUM; ++idx)
+ for(timer_tree_iterator_t it = begin_timer_tree(LLFastTimer::NamedTimer::getRootNamedTimer());
+ it != end_timer_tree();
+ ++it)
{
- if (ft_display_table[idx].disabled > 1)
- { //skip disabled timers
- continue;
- }
+ LLFastTimer::NamedTimer* idp = (*it);
//fatten highlighted timer
- if (mHoverIndex == idx)
+ if (mHoverID == idp)
{
gGL.flush();
glLineWidth(3);
}
- const F32 * col = ft_display_table[idx].color->mV;
+ const F32 * col = sTimerColors[idp].mV;// ft_display_table[idx].color->mV;
F32 alpha = 1.f;
- if (mHoverIndex >= 0 &&
- idx != mHoverIndex)
+ if (mHoverID != NULL &&
+ idp != mHoverID)
{ //fade out non-hihglighted timers
- if (ft_display_table[idx].parent != mHoverIndex)
+ if (idp->getParent() != mHoverID)
{
alpha = alpha_interp;
}
@@ -1025,9 +831,9 @@ void LLFastTimerView::draw()
gGL.color4f(col[0], col[1], col[2], alpha);
gGL.begin(LLRender::LINE_STRIP);
- for (U32 j = 0; j < LLFastTimer::FTM_HISTORY_NUM; j++)
+ for (U32 j = 0; j < LLFastTimer::NamedTimer::HISTORY_NUM; j++)
{
- U64 ticks = ticks_sum[j+1][idx];
+ U64 ticks = idp->getHistoricalCount(j);
if (mDisplayHz)
{
@@ -1037,26 +843,31 @@ void LLFastTimerView::draw()
}
else if (mDisplayCalls)
{
- S32 tidx = ft_display_table[idx].timer;
- S32 hidx = (LLFastTimer::sLastFrameIndex + j) % LLFastTimer::FTM_HISTORY_NUM;
- ticks = (S32)LLFastTimer::sCallHistory[hidx][tidx];
+ ticks = (S32)idp->getHistoricalCalls(j);
}
if (alpha == 1.f)
- { //normalize to highlighted timer
+ {
+ //normalize to highlighted timer
cur_max = llmax(cur_max, ticks);
}
- F32 x = graph_rect.mLeft + ((F32) (graph_rect.getWidth()))/(LLFastTimer::FTM_HISTORY_NUM-1)*j;
+ F32 x = graph_rect.mLeft + ((F32) (graph_rect.getWidth()))/(LLFastTimer::NamedTimer::HISTORY_NUM-1)*j;
F32 y = graph_rect.mBottom + (F32) graph_rect.getHeight()/max_ticks*ticks;
gGL.vertex2f(x,y);
}
gGL.end();
- if (mHoverIndex == idx)
+ if (mHoverID == idp)
{
gGL.flush();
glLineWidth(1);
}
+
+ if (idp->getCollapsed())
+ {
+ //skip hidden timers
+ it.skipDescendants();
+ }
}
//interpolate towards new maximum
@@ -1068,12 +879,16 @@ void LLFastTimerView::draw()
alpha_interp = alpha_interp + (alpha_target-alpha_interp) * dt;
- if (mHoverIndex >= 0)
+ if (mHoverID != NULL)
{
x = (graph_rect.mRight + graph_rect.mLeft)/2;
y = graph_rect.mBottom + 8;
- LLFontGL::getFontMonospace()->renderUTF8(std::string(ft_display_table[mHoverIndex].desc), 0, x, y, LLColor4::white,
+ LLFontGL::getFontMonospace()->renderUTF8(
+ mHoverID->getName(),
+ 0,
+ x, y,
+ LLColor4::white,
LLFontGL::LEFT, LLFontGL::BOTTOM);
}
}
@@ -1083,87 +898,274 @@ void LLFastTimerView::draw()
if (mPrintStats >= 0)
{
std::string legend_stat;
- S32 stat_num;
- S32 first = 1;
- for (stat_num = 0; stat_num < FTV_DISPLAY_NUM; stat_num++)
+ bool first = true;
+ for(timer_tree_iterator_t it = begin_timer_tree(LLFastTimer::NamedTimer::getRootNamedTimer());
+ it != end_timer_tree();
+ ++it)
{
- if (ft_display_table[stat_num].disabled > 1)
- continue;
+ LLFastTimer::NamedTimer* idp = (*it);
+
if (!first)
+ {
legend_stat += ", ";
- first=0;
- legend_stat += ft_display_table[stat_num].desc;
+ }
+ first = true;
+ legend_stat += idp->getName();
+
+ if (idp->getCollapsed())
+ {
+ it.skipDescendants();
+ }
}
llinfos << legend_stat << llendl;
std::string timer_stat;
- first = 1;
- for (stat_num = 0; stat_num < FTV_DISPLAY_NUM; stat_num++)
+ first = true;
+ for(timer_tree_iterator_t it = begin_timer_tree(LLFastTimer::NamedTimer::getRootNamedTimer());
+ it != end_timer_tree();
+ ++it)
{
- S32 disabled = ft_display_table[stat_num].disabled;
- if (disabled > 1)
- continue;
+ LLFastTimer::NamedTimer* idp = (*it);
+
if (!first)
+ {
timer_stat += ", ";
- first=0;
+ }
+ first = false;
+
U64 ticks;
- S32 tidx = ft_display_table[stat_num].timer;
if (mPrintStats > 0)
{
- S32 hidx = (LLFastTimer::sLastFrameIndex+(mPrintStats-1)-mScrollIndex) % LLFastTimer::FTM_HISTORY_NUM;
- ticks = disabled >= 1 ? ticks_sum[mPrintStats][stat_num] : LLFastTimer::sCountHistory[hidx][tidx];
+ S32 hidx = (mPrintStats - 1) - mScrollIndex;
+ ticks = idp->getHistoricalCount(hidx);
}
else
{
- ticks = disabled >= 1 ? ticks_sum[0][stat_num] : LLFastTimer::sCountAverage[tidx];
+ ticks = idp->getCountAverage();
}
F32 ms = (F32)((F64)ticks * iclock_freq);
timer_stat += llformat("%.1f",ms);
+
+ if (idp->getCollapsed())
+ {
+ it.skipDescendants();
+ }
}
llinfos << timer_stat << llendl;
mPrintStats = -1;
}
- mHoverIndex = -1;
+ mHoverID = NULL;
mHoverBarIndex = -1;
LLView::draw();
}
-F64 LLFastTimerView::getTime(LLFastTimer::EFastTimerType tidx)
+F64 LLFastTimerView::getTime(const std::string& name)
{
- // Find table index
- S32 i;
- for (i=0; i<FTV_DISPLAY_NUM; i++)
+ const LLFastTimer::NamedTimer* timerp = LLFastTimer::getTimerByName(name);
+ if (timerp)
{
- if (tidx == ft_display_table[i].timer)
+ return (F64)timerp->getCountAverage() / (F64)LLFastTimer::countsPerSecond();
+ }
+ return 0.0;
+}
+
+//static
+LLSD LLFastTimerView::analyzePerformanceLogDefault(std::istream& is)
+{
+ LLSD ret;
+
+ LLSD cur;
+
+ LLSD::Real total_time = 0.0;
+ LLSD::Integer total_frames = 0;
+
+ while (!is.eof() && LLSDSerialize::fromXML(cur, is))
+ {
+ for (LLSD::map_iterator iter = cur.beginMap(); iter != cur.endMap(); ++iter)
{
- break;
+ std::string label = iter->first;
+
+ F64 time = iter->second["Time"].asReal();
+
+ total_time += time;
+
+ if (time > 0.0)
+ {
+ ret[label]["TotalTime"] = ret[label]["TotalTime"].asReal() + time;
+ ret[label]["MaxTime"] = llmax(time, ret[label]["MaxTime"].asReal());
+
+ if (ret[label]["MinTime"].asReal() == 0)
+ {
+ ret[label]["MinTime"] = time;
+ }
+ else
+ {
+ ret[label]["MinTime"] = llmin(ret[label]["MinTime"].asReal(), time);
+ }
+
+ LLSD::Integer samples = iter->second["Calls"].asInteger();
+
+ ret[label]["Samples"] = ret[label]["Samples"].asInteger() + samples;
+ ret[label]["MaxSamples"] = llmax(ret[label]["MaxSamples"].asInteger(), samples);
+
+ if (ret[label]["MinSamples"].asInteger() == 0)
+ {
+ ret[label]["MinSamples"] = samples;
+ }
+ else
+ {
+ ret[label]["MinSamples"] = llmin(ret[label]["MinSamples"].asInteger(), samples);
+ }
+ }
}
+ total_frames++;
}
+
+ ret["SessionTime"] = total_time;
+ ret["FrameCount"] = total_frames;
+
+ return ret;
- if (i == FTV_DISPLAY_NUM)
+}
+
+//static
+void LLFastTimerView::doAnalysisDefault(std::string baseline, std::string target, std::string output)
+{
+
+ //analyze baseline
+ std::ifstream base_is(baseline.c_str());
+ LLSD base = analyzePerformanceLogDefault(base_is);
+ base_is.close();
+
+ //analyze current
+ std::ifstream target_is(target.c_str());
+ LLSD current = analyzePerformanceLogDefault(target_is);
+ target_is.close();
+
+ //output comparision
+ std::ofstream os(output.c_str());
+
+ LLSD::Real session_time = current["SessionTime"].asReal();
+
+ os << "Label, % Change, % of Session, Cur Min, Cur Max, Cur Mean, Cur Total, Cur Samples, Base Min, Base Max, Base Mean, Base Total, Base Samples\n";
+ for (LLSD::map_iterator iter = base.beginMap(); iter != base.endMap(); ++iter)
{
- // walked off the end of ft_display_table without finding
- // the desired timer type
- llwarns << "Timer type " << tidx << " not known." << llendl;
- return F64(0.0);
+ LLSD::String label = iter->first;
+
+ if (current[label]["Samples"].asInteger() == 0 ||
+ base[label]["Samples"].asInteger() == 0)
+ {
+ //cannot compare
+ continue;
+ }
+ LLSD::Real a = base[label]["TotalTime"].asReal() / base[label]["Samples"].asReal();
+ LLSD::Real b = current[label]["TotalTime"].asReal() / base[label]["Samples"].asReal();
+
+ LLSD::Real diff = b-a;
+
+ LLSD::Real perc = diff/a * 100;
+
+ os << llformat("%s, %.2f, %.4f, %.4f, %.4f, %.4f, %.4f, %d, %.4f, %.4f, %.4f, %.4f, %d\n",
+ label.c_str(),
+ (F32) perc,
+ (F32) (current[label]["TotalTime"].asReal()/session_time * 100.0),
+ (F32) current[label]["MinTime"].asReal(),
+ (F32) current[label]["MaxTime"].asReal(),
+ (F32) b,
+ (F32) current[label]["TotalTime"].asReal(),
+ current[label]["Samples"].asInteger(),
+ (F32) base[label]["MinTime"].asReal(),
+ (F32) base[label]["MaxTime"].asReal(),
+ (F32) a,
+ (F32) base[label]["TotalTime"].asReal(),
+ base[label]["Samples"].asInteger());
}
- S32 table_idx = i;
- // Add child ticks to parent
- U64 ticks = LLFastTimer::sCountAverage[tidx];
- S32 level = ft_display_table[table_idx].level;
- for (i=table_idx+1; i<FTV_DISPLAY_NUM; i++)
+ os.flush();
+ os.close();
+}
+
+//-------------------------
+//static
+LLSD LLFastTimerView::analyzeMetricPerformanceLog(std::istream& is)
+{
+ LLSD ret;
+ LLSD cur;
+
+ while (!is.eof() && LLSDSerialize::fromXML(cur, is))
{
- if (ft_display_table[i].level <= level)
+ for (LLSD::map_iterator iter = cur.beginMap(); iter != cur.endMap(); ++iter)
{
- break;
+ std::string label = iter->first;
+
+ LLMetricPerformanceTester* tester = LLMetricPerformanceTester::getTester(iter->second["Name"].asString()) ;
+ if(tester)
+ {
+ ret[label]["Name"] = iter->second["Name"] ;
+
+ S32 num_of_strings = tester->getNumOfMetricStrings() ;
+ for(S32 index = 0 ; index < num_of_strings ; index++)
+ {
+ ret[label][ tester->getMetricString(index) ] = iter->second[ tester->getMetricString(index) ] ;
+ }
+ }
}
- ticks += LLFastTimer::sCountAverage[ft_display_table[i].timer];
}
+
+ return ret;
+}
- return (F64)ticks / (F64)LLFastTimer::countsPerSecond();
+//static
+void LLFastTimerView::doAnalysisMetrics(std::string baseline, std::string target, std::string output)
+{
+ if(!LLMetricPerformanceTester::hasMetricPerformanceTesters())
+ {
+ return ;
+ }
+
+ //analyze baseline
+ std::ifstream base_is(baseline.c_str());
+ LLSD base = analyzeMetricPerformanceLog(base_is);
+ base_is.close();
+
+ //analyze current
+ std::ifstream target_is(target.c_str());
+ LLSD current = analyzeMetricPerformanceLog(target_is);
+ target_is.close();
+
+ //output comparision
+ std::ofstream os(output.c_str());
+
+ os << "Label, Metric, Base(B), Target(T), Diff(T-B), Percentage(100*T/B)\n";
+ for(LLMetricPerformanceTester::name_tester_map_t::iterator iter = LLMetricPerformanceTester::sTesterMap.begin() ;
+ iter != LLMetricPerformanceTester::sTesterMap.end() ; ++iter)
+ {
+ LLMetricPerformanceTester* tester = ((LLMetricPerformanceTester*)iter->second) ;
+ tester->analyzePerformance(&os, &base, &current) ;
+ }
+
+ os.flush();
+ os.close();
}
+
+//static
+void LLFastTimerView::doAnalysis(std::string baseline, std::string target, std::string output)
+{
+ if(LLFastTimer::sLog)
+ {
+ doAnalysisDefault(baseline, target, output) ;
+ return ;
+ }
+
+ if(LLFastTimer::sMetricLog)
+ {
+ doAnalysisMetrics(baseline, target, output) ;
+ return ;
+ }
+}
+
+
diff --git a/indra/newview/llfasttimerview.h b/indra/newview/llfasttimerview.h
index 86fc194610..f301888984 100644
--- a/indra/newview/llfasttimerview.h
+++ b/indra/newview/llfasttimerview.h
@@ -34,39 +34,62 @@
#define LL_LLFASTTIMERVIEW_H
#include "llfloater.h"
-#include "llframetimer.h"
+#include "llfasttimer.h"
class LLFastTimerView : public LLFloater
{
public:
- LLFastTimerView(const std::string& name, const LLRect& rect);
- virtual ~LLFastTimerView();
+ LLFastTimerView(const LLRect& rect);
+
+ static BOOL sAnalyzePerformance;
+
+ static void doAnalysis(std::string baseline, std::string target, std::string output);
+
+private:
+ static void doAnalysisDefault(std::string baseline, std::string target, std::string output) ;
+ static void doAnalysisMetrics(std::string baseline, std::string target, std::string output) ;
+ static LLSD analyzeMetricPerformanceLog(std::istream& is) ;
+ static LLSD analyzePerformanceLogDefault(std::istream& is) ;
+
+public:
virtual BOOL handleMouseDown(S32 x, S32 y, MASK mask);
virtual BOOL handleRightMouseDown(S32 x, S32 y, MASK mask);
virtual BOOL handleMouseUp(S32 x, S32 y, MASK mask);
virtual BOOL handleHover(S32 x, S32 y, MASK mask);
+ virtual BOOL handleToolTip(S32 x, S32 y, std::string& msg, LLRect* sticky_rect_screen);
virtual BOOL handleScrollWheel(S32 x, S32 y, S32 clicks);
virtual void draw();
- S32 getLegendIndex(S32 y);
- F64 getTime(LLFastTimer::EFastTimerType tidx);
+ LLFastTimer::NamedTimer* getLegendID(S32 y);
+ F64 getTime(const std::string& name);
private:
- S32* mBarStart;
- S32* mBarEnd;
+ typedef std::vector<std::vector<S32> > bar_positions_t;
+ bar_positions_t mBarStart;
+ bar_positions_t mBarEnd;
S32 mDisplayMode;
- S32 mDisplayCenter;
+
+ typedef enum child_alignment
+ {
+ ALIGN_LEFT,
+ ALIGN_CENTER,
+ ALIGN_RIGHT,
+ ALIGN_COUNT
+ } ChildAlignment;
+
+ ChildAlignment mDisplayCenter;
S32 mDisplayCalls;
S32 mDisplayHz;
U64 mAvgCountTotal;
U64 mMaxCountTotal;
LLRect mBarRect;
S32 mScrollIndex;
- S32 mHoverIndex;
+ LLFastTimer::NamedTimer* mHoverID;
+ LLFastTimer::NamedTimer* mHoverTimer;
+ LLRect mToolTipRect;
S32 mHoverBarIndex;
LLFrameTimer mHighlightTimer;
- S32 mSubtractHidden;
S32 mPrintStats;
};
diff --git a/indra/newview/llfavoritesbar.cpp b/indra/newview/llfavoritesbar.cpp
new file mode 100644
index 0000000000..7ad60232c7
--- /dev/null
+++ b/indra/newview/llfavoritesbar.cpp
@@ -0,0 +1,801 @@
+/**
+ * @file llfavoritesbar.cpp
+ * @brief LLFavoritesBarCtrl class implementation
+ *
+ * $LicenseInfo:firstyear=2009&license=viewergpl$
+ *
+ * Copyright (c) 2009, Linden Research, Inc.
+ *
+ * Second Life Viewer Source Code
+ * The source code in this file ("Source Code") is provided by Linden Lab
+ * to you under the terms of the GNU General Public License, version 2.0
+ * ("GPL"), unless you have obtained a separate licensing agreement
+ * ("Other License"), formally executed by you and Linden Lab. Terms of
+ * the GPL can be found in doc/GPL-license.txt in this distribution, or
+ * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
+ *
+ * There are special exceptions to the terms and conditions of the GPL as
+ * it is applied to this Source Code. View the full text of the exception
+ * in the file doc/FLOSS-exception.txt in this software distribution, or
+ * online at
+ * http://secondlifegrid.net/programs/open_source/licensing/flossexception
+ *
+ * By copying, modifying or distributing this software, you acknowledge
+ * that you have read and understood your obligations described above,
+ * and agree to abide by those obligations.
+ *
+ * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+ * COMPLETENESS OR PERFORMANCE.
+ * $/LicenseInfo$
+ */
+
+#include "llviewerprecompiledheaders.h"
+
+#include "llfavoritesbar.h"
+
+#include "llbutton.h"
+#include "llfloaterreg.h"
+#include "llfocusmgr.h"
+#include "llinventory.h"
+#include "lllandmarkactions.h"
+#include "lltrans.h"
+#include "lluictrlfactory.h"
+#include "llmenugl.h"
+
+#include "llagent.h"
+#include "llclipboard.h"
+#include "llinventoryclipboard.h"
+#include "llinventorybridge.h"
+#include "llinventorymodel.h"
+#include "llfloaterworldmap.h"
+#include "lllandmarkactions.h"
+#include "llsidetray.h"
+#include "lltoggleablemenu.h"
+#include "llviewerinventory.h"
+#include "llviewermenu.h"
+#include "llviewermenu.h"
+
+static LLDefaultChildRegistry::Register<LLFavoritesBarCtrl> r("favorites_bar");
+
+const S32 DROP_DOWN_MENU_WIDTH = 250;
+
+/**
+ * Helper for LLFavoriteLandmarkButton and LLFavoriteLandmarkMenuItem.
+ * Performing requests for SLURL for given Landmark ID
+ */
+class LLSLURLGetter
+{
+public:
+ LLSLURLGetter()
+ : mLandmarkID(LLUUID::null)
+ , mSLURL("(Loading...)")
+ , mLoaded(false) {}
+
+ void setLandmarkID(const LLUUID& id) { mLandmarkID = id; }
+
+ const std::string& getSLURL()
+ {
+ if(!mLoaded)
+ requestSLURL();
+
+ return mSLURL;
+ }
+private:
+ /**
+ * Requests landmark data from server.
+ */
+ void requestSLURL()
+ {
+ if (mLandmarkID.isNull())
+ return;
+
+ LLVector3d g_pos;
+ if(LLLandmarkActions::getLandmarkGlobalPos(mLandmarkID, g_pos))
+ {
+ LLLandmarkActions::getSLURLfromPosGlobal(g_pos,
+ boost::bind(&LLSLURLGetter::landmarkNameCallback, this, _1), false);
+ }
+ }
+
+ void landmarkNameCallback(const std::string& name)
+ {
+ mSLURL = name;
+ mLoaded = true;
+ }
+
+ LLUUID mLandmarkID;
+ std::string mSLURL;
+ bool mLoaded;
+};
+
+/**
+ * This class is needed to override LLButton default handleToolTip function and
+ * show SLURL as button tooltip.
+ * *NOTE: dzaporozhan: This is a workaround. We could set tooltips for buttons
+ * in createButtons function but landmark data is not available when Favorites Bar is
+ * created. Thats why we are requesting landmark data after
+ */
+class LLFavoriteLandmarkButton : public LLButton
+{
+public:
+
+ BOOL handleToolTip(S32 x, S32 y, std::string& msg, LLRect* sticky_rect)
+ {
+ if(LLUI::sShowXUINames)
+ {
+ return LLButton::handleToolTip(x, y, msg, sticky_rect);
+ }
+
+ msg = mUrlGetter.getSLURL();
+ return TRUE;
+ }
+
+ void setLandmarkID(const LLUUID& id){ mUrlGetter.setLandmarkID(id); }
+
+protected:
+ LLFavoriteLandmarkButton(const LLButton::Params& p) : LLButton(p) {}
+ friend class LLUICtrlFactory;
+
+private:
+ LLSLURLGetter mUrlGetter;
+};
+
+/**
+ * This class is needed to override LLMenuItemCallGL default handleToolTip function and
+ * show SLURL as button tooltip.
+ * *NOTE: dzaporozhan: This is a workaround. We could set tooltips for buttons
+ * in showDropDownMenu function but landmark data is not available when Favorites Bar is
+ * created. Thats why we are requesting landmark data after
+ */
+class LLFavoriteLandmarkMenuItem : public LLMenuItemCallGL
+{
+public:
+ BOOL handleToolTip(S32 x, S32 y, std::string& msg, LLRect* sticky_rect)
+ {
+ if(LLUI::sShowXUINames)
+ {
+ return LLMenuItemCallGL::handleToolTip(x, y, msg, sticky_rect);
+ }
+
+ msg = mUrlGetter.getSLURL();
+ return TRUE;
+ }
+
+ void setLandmarkID(const LLUUID& id){ mUrlGetter.setLandmarkID(id); }
+
+protected:
+
+ LLFavoriteLandmarkMenuItem(const LLMenuItemCallGL::Params& p) : LLMenuItemCallGL(p) {}
+ friend class LLUICtrlFactory;
+
+private:
+ LLSLURLGetter mUrlGetter;
+};
+
+
+// updateButtons's helper
+struct LLFavoritesSort
+{
+ // Sorting by creation date and name
+ // TODO - made it customizible using gSavedSettings
+ bool operator()(const LLViewerInventoryItem* const& a, const LLViewerInventoryItem* const& b)
+ {
+ time_t first_create = a->getCreationDate();
+ time_t second_create = b->getCreationDate();
+ if (first_create == second_create)
+ {
+ return (LLStringUtil::compareDict(a->getName(), b->getName()) < 0);
+ }
+ else
+ {
+ return (first_create > second_create);
+ }
+ }
+};
+
+LLFavoritesBarCtrl::Params::Params()
+: chevron_button_tool_tip("chevron_button_tool_tip")
+{
+}
+
+LLFavoritesBarCtrl::LLFavoritesBarCtrl(const LLFavoritesBarCtrl::Params& p)
+: LLUICtrl(p),
+ mFont(p.font.isProvided() ? p.font() : LLFontGL::getFontSansSerifSmall()),
+ mPopupMenuHandle(),
+ mInventoryItemsPopupMenuHandle(),
+ mChevronButtonToolTip(p.chevron_button_tool_tip)
+{
+ // Register callback for menus with current registrar (will be parent panel's registrar)
+ LLUICtrl::CommitCallbackRegistry::currentRegistrar().add("Favorites.DoToSelected",
+ boost::bind(&LLFavoritesBarCtrl::doToSelected, this, _2));
+
+ // Add this if we need to selectively enable items
+ //LLUICtrl::EnableCallbackRegistry::currentRegistrar().add("Favorites.EnableSelected",
+ // boost::bind(&LLFavoritesBarCtrl::enableSelected, this, _2));
+
+ gInventory.addObserver(this);
+}
+
+LLFavoritesBarCtrl::~LLFavoritesBarCtrl()
+{
+ gInventory.removeObserver(this);
+
+ LLView::deleteViewByHandle(mPopupMenuHandle);
+ LLView::deleteViewByHandle(mInventoryItemsPopupMenuHandle);
+}
+
+BOOL LLFavoritesBarCtrl::handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop,
+ EDragAndDropType cargo_type,
+ void* cargo_data,
+ EAcceptance* accept,
+ std::string& tooltip_msg)
+{
+ *accept = ACCEPT_NO;
+
+ switch (cargo_type)
+ {
+
+ case DAD_LANDMARK:
+ {
+ // Copy the item into the favorites folder (if it's not already there).
+ LLInventoryItem *item = (LLInventoryItem *)cargo_data;
+ LLUUID favorites_id = gInventory.findCategoryUUIDForType(LLAssetType::AT_FAVORITE);
+ if (item->getParentUUID() == favorites_id)
+ {
+ llwarns << "Attemt to copy a favorite item into the same folder." << llendl;
+ break;
+ }
+
+ *accept = ACCEPT_YES_COPY_SINGLE;
+
+ if (drop)
+ {
+ copy_inventory_item(
+ gAgent.getID(),
+ item->getPermissions().getOwner(),
+ item->getUUID(),
+ favorites_id,
+ std::string(),
+ LLPointer<LLInventoryCallback>(NULL));
+
+ llinfos << "Copied inventory item #" << item->getUUID() << " to favorites." << llendl;
+ }
+
+ }
+ break;
+ default:
+ break;
+ }
+
+ return TRUE;
+}
+
+//virtual
+void LLFavoritesBarCtrl::changed(U32 mask)
+{
+ if (mFavoriteFolderId.isNull())
+ {
+ mFavoriteFolderId = gInventory.findCategoryUUIDForType(LLAssetType::AT_FAVORITE);
+
+ if (mFavoriteFolderId.notNull())
+ {
+ gInventory.fetchDescendentsOf(mFavoriteFolderId);
+ }
+ }
+ else
+ {
+ updateButtons(getRect().getWidth());
+ }
+}
+
+//virtual
+void LLFavoritesBarCtrl::reshape(S32 width, S32 height, BOOL called_from_parent)
+{
+ updateButtons(width);
+
+ LLUICtrl::reshape(width, height, called_from_parent);
+}
+
+LLXMLNodePtr LLFavoritesBarCtrl::getButtonXMLNode()
+{
+ LLXMLNodePtr buttonXMLNode = NULL;
+ bool success = LLUICtrlFactory::getLayeredXMLNode("favorites_bar_button.xml", buttonXMLNode);
+ if (!success)
+ {
+ llwarns << "Unable to read xml file with button for Favorites Bar: favorites_bar_button.xml" << llendl;
+ buttonXMLNode = NULL;
+ }
+ return buttonXMLNode;
+}
+
+void LLFavoritesBarCtrl::updateButtons(U32 bar_width)
+{
+ LLInventoryModel::item_array_t items;
+
+ if (!collectFavoriteItems(items))
+ {
+ return;
+ }
+
+ static LLXMLNodePtr buttonXMLNode = getButtonXMLNode();
+ if (buttonXMLNode.isNull())
+ {
+ return;
+ }
+
+ S32 buttonWidth = 120; //default value
+ buttonXMLNode->getAttributeS32("width", buttonWidth);
+ S32 buttonHGap = 2; // default value
+ buttonXMLNode->getAttributeS32("left", buttonHGap);
+
+ const S32 buttonVGap = 2;
+
+ S32 count = items.count();
+
+ const S32 buttonHPad = LLUI::sSettingGroups["config"]->getS32("ButtonHPad");
+ const S32 chevron_button_width = mFont->getWidth(">>") + buttonHPad * 2;
+
+ S32 buttons_space = bar_width - buttonHGap;
+
+ S32 first_drop_down_item = count;
+
+ // Calculating, how much buttons can fit in the bar
+ S32 buttons_width = 0;
+ for (S32 i = 0; i < count; ++i)
+ {
+ buttons_width += buttonWidth + buttonHGap;
+ if (buttons_width > buttons_space)
+ {
+ // There is no space for all buttons.
+ // Calculating the number of buttons, that are fit with chevron button
+ buttons_space -= chevron_button_width + buttonHGap;
+ while (i >= 0 && buttons_width > buttons_space)
+ {
+ buttons_width -= buttonWidth + buttonHGap;
+ i--;
+ }
+ first_drop_down_item = i + 1; // First item behind visible items
+
+ break;
+ }
+ }
+
+ bool recreate_buttons = true;
+
+ // If inventory items are not changed up to mFirstDropDownItem, no need to recreate them
+ if (mFirstDropDownItem == first_drop_down_item && (mItemNamesCache.size() == count || mItemNamesCache.size() == mFirstDropDownItem))
+ {
+ S32 i;
+ for (i = 0; i < mFirstDropDownItem; ++i)
+ {
+ if (mItemNamesCache.get(i) != items.get(i)->getName())
+ {
+ break;
+ }
+ }
+ if (i == mFirstDropDownItem)
+ {
+ recreate_buttons = false;
+ }
+ }
+
+ if (recreate_buttons)
+ {
+ mFirstDropDownItem = first_drop_down_item;
+
+ mItemNamesCache.clear();
+ for (S32 i = 0; i < mFirstDropDownItem; i++)
+ {
+ mItemNamesCache.put(items.get(i)->getName());
+ }
+
+ // Rebuild the buttons only
+ // child_list_t is a linked list, so safe to erase from the middle if we pre-incrament the iterator
+ for ( child_list_const_iter_t child_it = getChildList()->begin(); child_it != getChildList()->end(); )
+ {
+ child_list_const_iter_t cur_it = child_it++;
+ LLView* viewp = *cur_it;
+ LLButton* button = dynamic_cast<LLButton*>(viewp);
+ if (button)
+ {
+ removeChild(button);
+ delete button;
+ }
+ }
+
+ createButtons(items, buttonXMLNode, buttonWidth, buttonHGap);
+ }
+
+ // Chevron button
+ if (mFirstDropDownItem != count)
+ {
+ // Chevron button should stay right aligned
+ LLView *chevron_button = findChildView(std::string(">>"), FALSE);
+ if (chevron_button)
+ {
+ LLRect rect;
+ rect.setOriginAndSize(bar_width - chevron_button_width - buttonHGap, buttonVGap, chevron_button_width, getRect().getHeight()-buttonVGap);
+ chevron_button->setRect(rect);
+ chevron_button->setVisible(TRUE);
+ mChevronRect = rect;
+ }
+ else
+ {
+ static LLButton::Params default_button_params(LLUICtrlFactory::getDefaultParams<LLButton>());
+ std::string flat_icon = "transparent.j2c";
+ std::string hover_icon = default_button_params.image_unselected.name;
+ std::string hover_icon_selected = default_button_params.image_selected.name;
+
+ LLButton::Params bparams;
+
+ LLRect rect;
+ rect.setOriginAndSize(bar_width - chevron_button_width - buttonHGap, buttonVGap, chevron_button_width, getRect().getHeight()-buttonVGap);
+
+ bparams.follows.flags (FOLLOWS_LEFT | FOLLOWS_BOTTOM);
+ bparams.image_unselected.name(flat_icon);
+ bparams.image_disabled.name(flat_icon);
+ bparams.image_selected.name(hover_icon_selected);
+ bparams.image_hover_selected.name(hover_icon_selected);
+ bparams.image_disabled_selected.name(hover_icon_selected);
+ bparams.image_hover_unselected.name(hover_icon);
+ bparams.rect (rect);
+ bparams.tab_stop(false);
+ bparams.font(mFont);
+ bparams.name(">>");
+ bparams.tool_tip(mChevronButtonToolTip);
+ bparams.click_callback.function(boost::bind(&LLFavoritesBarCtrl::showDropDownMenu, this));
+
+ addChildInBack(LLUICtrlFactory::create<LLButton> (bparams));
+
+ mChevronRect = rect;
+ }
+ }
+ else
+ {
+ // Hide chevron button if all items are visible on bar
+ LLView *chevron_button = findChildView(std::string(">>"), FALSE);
+ if (chevron_button)
+ {
+ chevron_button->setVisible(FALSE);
+ }
+ }
+}
+
+
+void LLFavoritesBarCtrl::createButtons(const LLInventoryModel::item_array_t &items, const LLXMLNodePtr &buttonXMLNode, S32 buttonWidth, S32 buttonHGap)
+{
+ S32 curr_x = buttonHGap;
+ // Adding buttons
+ for(S32 i = mFirstDropDownItem -1; i >= 0; i--)
+ {
+ LLInventoryItem* item = items.get(i);
+
+ LLFavoriteLandmarkButton* fav_btn = LLUICtrlFactory::defaultBuilder<LLFavoriteLandmarkButton>(buttonXMLNode, this, NULL);
+ if (NULL == fav_btn)
+ {
+ llwarns << "Unable to create button for landmark: " << item->getName() << llendl;
+ continue;
+ }
+
+ fav_btn->setLandmarkID(item->getUUID());
+
+ // change only left and save bottom
+ fav_btn->setOrigin(curr_x, fav_btn->getRect().mBottom);
+ fav_btn->setFont(mFont);
+ fav_btn->setName(item->getName());
+ fav_btn->setLabel(item->getName());
+ fav_btn->setToolTip(item->getName());
+ fav_btn->setCommitCallback(boost::bind(&LLFavoritesBarCtrl::onButtonClick, this, item->getUUID()));
+ fav_btn->setRightMouseDownCallback(boost::bind(&LLFavoritesBarCtrl::onButtonRightClick, this, item->getUUID(), _1, _2, _3,_4 ));
+ sendChildToBack(fav_btn);
+
+ curr_x += buttonWidth + buttonHGap;
+ }
+}
+
+
+BOOL LLFavoritesBarCtrl::postBuild()
+{
+ // make the popup menu available
+ LLMenuGL* menu = LLUICtrlFactory::getInstance()->createFromFile<LLMenuGL>("menu_favorites.xml", gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance());
+ if (!menu)
+ {
+ menu = LLUICtrlFactory::getDefaultWidget<LLMenuGL>("inventory_menu");
+ }
+ menu->setBackgroundColor(LLUIColorTable::instance().getColor("MenuPopupBgColor"));
+ mInventoryItemsPopupMenuHandle = menu->getHandle();
+
+ return TRUE;
+}
+
+BOOL LLFavoritesBarCtrl::collectFavoriteItems(LLInventoryModel::item_array_t &items)
+{
+ if (mFavoriteFolderId.isNull())
+ return FALSE;
+
+ LLInventoryModel::cat_array_t cats;
+
+ LLIsType is_type(LLAssetType::AT_LANDMARK);
+ gInventory.collectDescendentsIf(mFavoriteFolderId, cats, items, LLInventoryModel::EXCLUDE_TRASH, is_type);
+
+ std::sort(items.begin(), items.end(), LLFavoritesSort());
+
+ return TRUE;
+}
+
+void LLFavoritesBarCtrl::showDropDownMenu()
+{
+ if (mPopupMenuHandle.isDead())
+ {
+ LLToggleableMenu::Params menu_p;
+ menu_p.name("favorites menu");
+ menu_p.can_tear_off(false);
+ menu_p.visible(false);
+ menu_p.scrollable(true);
+ menu_p.max_scrollable_items = 10;
+ menu_p.preferred_width = DROP_DOWN_MENU_WIDTH;
+
+ LLToggleableMenu* menu = LLUICtrlFactory::create<LLToggleableMenu>(menu_p);
+
+ mPopupMenuHandle = menu->getHandle();
+ }
+
+ LLToggleableMenu* menu = (LLToggleableMenu*)mPopupMenuHandle.get();
+
+ if(menu)
+ {
+ if (!menu->toggleVisibility())
+ return;
+
+ LLInventoryModel::item_array_t items;
+
+ if (!collectFavoriteItems(items))
+ {
+ return;
+ }
+
+ S32 count = items.count();
+
+ // Check it there are changed items, since last call
+ if (mItemNamesCache.size() == count)
+ {
+ S32 i;
+ for (i = mFirstDropDownItem; i < count; i++)
+ {
+ if (mItemNamesCache.get(i) != items.get(i)->getName())
+ {
+ break;
+ }
+ }
+
+ // Check passed, just show the menu
+ if (i == count)
+ {
+ menu->buildDrawLabels();
+ menu->updateParent(LLMenuGL::sMenuContainer);
+
+ menu->setButtonRect(mChevronRect, this);
+
+ LLMenuGL::showPopup(this, menu, getRect().getWidth() - menu->getRect().getWidth(), 0);
+ return;
+ }
+ }
+
+ // Add menu items to cache, if there is only names of buttons
+ if (mItemNamesCache.size() == mFirstDropDownItem)
+ {
+ for (S32 i = mFirstDropDownItem; i < count; i++)
+ {
+ mItemNamesCache.put(items.get(i)->getName());
+ }
+ }
+
+ menu->empty();
+
+ U32 max_width = llmin(DROP_DOWN_MENU_WIDTH, getRect().getWidth());
+ U32 widest_item = 0;
+
+ for(S32 i = mFirstDropDownItem; i < count; i++)
+ {
+ LLInventoryItem* item = items.get(i);
+ const std::string& item_name = item->getName();
+
+ LLMenuItemCallGL::Params item_params;
+ item_params.name(item_name);
+ item_params.label(item_name);
+
+ item_params.on_click.function(boost::bind(&LLFavoritesBarCtrl::onButtonClick, this, item->getUUID()));
+ LLFavoriteLandmarkMenuItem *menu_item = LLUICtrlFactory::create<LLFavoriteLandmarkMenuItem>(item_params);
+ menu_item->setRightMouseDownCallback(boost::bind(&LLFavoritesBarCtrl::onButtonRightClick, this,item->getUUID(),_1,_2,_3,_4));
+ menu_item->setLandmarkID(item->getUUID());
+
+ // Check whether item name wider than menu
+ if (menu_item->getNominalWidth() > max_width)
+ {
+ S32 chars_total = item_name.length();
+ S32 chars_fitted = 1;
+ menu_item->setLabel(LLStringExplicit(""));
+ S32 label_space = max_width - menu_item->getFont()->getWidth("...") -
+ menu_item->getNominalWidth(); // This returns width of menu item with empty label (pad pixels)
+
+ while (chars_fitted < chars_total && menu_item->getFont()->getWidth(item_name, 0, chars_fitted) < label_space)
+ {
+ chars_fitted++;
+ }
+ chars_fitted--; // Rolling back one char, that doesn't fit
+
+ menu_item->setLabel(item_name.substr(0, chars_fitted) + "...");
+ }
+ widest_item = llmax(widest_item, menu_item->getNominalWidth());
+
+ menu->addChild(menu_item);
+ }
+
+ menu->buildDrawLabels();
+ menu->updateParent(LLMenuGL::sMenuContainer);
+
+ menu->setButtonRect(mChevronRect, this);
+
+ LLMenuGL::showPopup(this, menu, getRect().getWidth() - max_width, 0);
+
+ }
+}
+
+void LLFavoritesBarCtrl::onButtonClick(LLUUID item_id)
+{
+ LLInventoryModel::item_array_t items;
+
+ if (!collectFavoriteItems(items))
+ {
+ return;
+ }
+
+ // We only have one Inventory, gInventory. Some day this should be better abstracted.
+ LLInvFVBridgeAction::doAction(item_id,&gInventory);
+}
+
+void LLFavoritesBarCtrl::onButtonRightClick( LLUUID item_id,LLView* fav_button,S32 x,S32 y,MASK mask)
+{
+ mSelectedItemID = item_id;
+
+ LLMenuGL* menu = (LLMenuGL*)mInventoryItemsPopupMenuHandle.get();
+ if (!menu)
+ {
+ return;
+ }
+
+ // Release mouse capture so hover events go to the popup menu
+ // because this is happening during a mouse down.
+ gFocusMgr.setMouseCapture(NULL);
+
+ menu->updateParent(LLMenuGL::sMenuContainer);
+ LLMenuGL::showPopup(fav_button, menu, x, y);
+}
+
+void copy_slurl_to_clipboard_cb(std::string& slurl)
+{
+ gClipboard.copyFromString(utf8str_to_wstring(slurl));
+}
+
+
+void LLFavoritesBarCtrl::doToSelected(const LLSD& userdata)
+{
+ std::string action = userdata.asString();
+ llinfos << "Action = " << action << " Item = " << mSelectedItemID.asString() << llendl;
+
+ LLViewerInventoryItem* item = gInventory.getItem(mSelectedItemID);
+ if (!item)
+ return;
+
+ if (action == "open")
+ {
+ teleport_via_landmark(item->getAssetUUID());
+ }
+ else if (action == "about")
+ {
+ LLSD key;
+ key["type"] = "landmark";
+ key["id"] = mSelectedItemID;
+
+ LLSideTray::getInstance()->showPanel("panel_places", key);
+ }
+ else if (action == "copy_slurl")
+ {
+ LLVector3d posGlobal;
+ LLLandmarkActions::getLandmarkGlobalPos(mSelectedItemID, posGlobal);
+
+ if (!posGlobal.isExactlyZero())
+ {
+ LLLandmarkActions::getSLURLfromPosGlobal(posGlobal, copy_slurl_to_clipboard_cb);
+ }
+ }
+ else if (action == "show_on_map")
+ {
+ LLFloaterWorldMap* worldmap_instance = LLFloaterWorldMap::getInstance();
+
+ LLVector3d posGlobal;
+ LLLandmarkActions::getLandmarkGlobalPos(mSelectedItemID, posGlobal);
+
+ if (!posGlobal.isExactlyZero() && worldmap_instance)
+ {
+ worldmap_instance->trackLocation(posGlobal);
+ LLFloaterReg::showInstance("world_map", "center");
+ }
+ }
+ else if (action == "cut")
+ {
+ }
+ else if (action == "copy")
+ {
+ LLInventoryClipboard::instance().store(mSelectedItemID);
+ }
+ else if (action == "paste")
+ {
+ pastFromClipboard();
+ }
+ else if (action == "delete")
+ {
+ gInventory.removeItem(mSelectedItemID);
+ }
+}
+
+BOOL LLFavoritesBarCtrl::isClipboardPasteable() const
+{
+ if (!LLInventoryClipboard::instance().hasContents())
+ {
+ return FALSE;
+ }
+
+ LLDynamicArray<LLUUID> objects;
+ LLInventoryClipboard::instance().retrieve(objects);
+ S32 count = objects.count();
+ for(S32 i = 0; i < count; i++)
+ {
+ const LLUUID &item_id = objects.get(i);
+
+ // Can't paste folders
+ const LLInventoryCategory *cat = gInventory.getCategory(item_id);
+ if (cat)
+ {
+ return FALSE;
+ }
+
+ const LLInventoryItem *item = gInventory.getItem(item_id);
+ if (item && LLAssetType::AT_LANDMARK != item->getType())
+ {
+ return FALSE;
+ }
+ }
+ return TRUE;
+}
+
+void LLFavoritesBarCtrl::pastFromClipboard() const
+{
+ LLInventoryModel* model = &gInventory;
+ if(model && isClipboardPasteable())
+ {
+ LLInventoryItem* item = NULL;
+ LLDynamicArray<LLUUID> objects;
+ LLInventoryClipboard::instance().retrieve(objects);
+ S32 count = objects.count();
+ LLUUID parent_id(mFavoriteFolderId);
+ for(S32 i = 0; i < count; i++)
+ {
+ item = model->getItem(objects.get(i));
+ if (item)
+ {
+ copy_inventory_item(
+ gAgent.getID(),
+ item->getPermissions().getOwner(),
+ item->getUUID(),
+ parent_id,
+ std::string(),
+ LLPointer<LLInventoryCallback>(NULL));
+ }
+ }
+ }
+}
+
+
+// EOF
diff --git a/indra/newview/llfavoritesbar.h b/indra/newview/llfavoritesbar.h
new file mode 100644
index 0000000000..824b396add
--- /dev/null
+++ b/indra/newview/llfavoritesbar.h
@@ -0,0 +1,101 @@
+/**
+ * @file llfavoritesbar.h
+ * @brief LLFavoritesBarCtrl base class
+ *
+ * $LicenseInfo:firstyear=2009&license=viewergpl$
+ *
+ * Copyright (c) 2009, Linden Research, Inc.
+ *
+ * Second Life Viewer Source Code
+ * The source code in this file ("Source Code") is provided by Linden Lab
+ * to you under the terms of the GNU General Public License, version 2.0
+ * ("GPL"), unless you have obtained a separate licensing agreement
+ * ("Other License"), formally executed by you and Linden Lab. Terms of
+ * the GPL can be found in doc/GPL-license.txt in this distribution, or
+ * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
+ *
+ * There are special exceptions to the terms and conditions of the GPL as
+ * it is applied to this Source Code. View the full text of the exception
+ * in the file doc/FLOSS-exception.txt in this software distribution, or
+ * online at
+ * http://secondlifegrid.net/programs/open_source/licensing/flossexception
+ *
+ * By copying, modifying or distributing this software, you acknowledge
+ * that you have read and understood your obligations described above,
+ * and agree to abide by those obligations.
+ *
+ * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+ * COMPLETENESS OR PERFORMANCE.
+ * $/LicenseInfo$
+ */
+
+#ifndef LL_LLFAVORITESBARCTRL_H
+#define LL_LLFAVORITESBARCTRL_H
+
+#include "lluictrl.h"
+
+#include "llinventorymodel.h"
+
+class LLFavoritesBarCtrl : public LLUICtrl, public LLInventoryObserver
+{
+public:
+ struct Params : public LLInitParam::Block<Params, LLUICtrl::Params>
+ {
+ Optional<std::string> chevron_button_tool_tip;
+ Params();
+ };
+
+protected:
+ LLFavoritesBarCtrl(const Params&);
+ friend class LLUICtrlFactory;
+public:
+ virtual ~LLFavoritesBarCtrl();
+
+ /*virtual*/ BOOL postBuild();
+
+ /*virtual*/ BOOL handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop,
+ EDragAndDropType cargo_type,
+ void* cargo_data,
+ EAcceptance* accept,
+ std::string& tooltip_msg);
+
+ // LLInventoryObserver observer trigger
+ virtual void changed(U32 mask);
+ virtual void reshape(S32 width, S32 height, BOOL called_from_parent = TRUE);
+
+protected:
+ void updateButtons(U32 bar_width);
+ void createButtons(const LLInventoryModel::item_array_t &items, const LLXMLNodePtr &root, S32 buttonWidth, S32 buttonHGap);
+ LLXMLNodePtr getButtonXMLNode();
+ BOOL collectFavoriteItems(LLInventoryModel::item_array_t &items);
+
+ void onButtonClick(LLUUID id);
+ void onButtonRightClick(LLUUID id,LLView* button,S32 x,S32 y,MASK mask);
+
+ void doToSelected(const LLSD& userdata);
+ BOOL isClipboardPasteable() const;
+ void pastFromClipboard() const;
+
+
+ void showDropDownMenu();
+
+ LLHandle<LLView> mPopupMenuHandle;
+ LLHandle<LLView> mInventoryItemsPopupMenuHandle;
+
+ LLUUID mFavoriteFolderId;
+ const LLFontGL *mFont;
+ S32 mFirstDropDownItem;
+
+ typedef LLDynamicArray<std::string> item_names_array_t;
+ item_names_array_t mItemNamesCache;
+
+ LLUUID mSelectedItemID;
+ LLRect mChevronRect;
+
+ std::string mChevronButtonToolTip;
+};
+
+
+#endif // LL_LLFAVORITESBARCTRL_H
+
diff --git a/indra/newview/llfeaturemanager.cpp b/indra/newview/llfeaturemanager.cpp
index 35613b7c34..2a8365b3f0 100644
--- a/indra/newview/llfeaturemanager.cpp
+++ b/indra/newview/llfeaturemanager.cpp
@@ -47,7 +47,7 @@
#include "llviewercontrol.h"
#include "llworld.h"
#include "lldrawpoolterrain.h"
-#include "llviewerimagelist.h"
+#include "llviewertexturelist.h"
#include "llwindow.h"
#include "llui.h"
#include "llcontrol.h"
@@ -434,7 +434,6 @@ void LLFeatureManager::applyRecommendedSettings()
setGraphicsLevel(level, false);
gSavedSettings.setU32("RenderQualityPerformance", level);
- gSavedSettings.setBOOL("RenderCustomSettings", FALSE);
// now apply the tweaks to draw distance
// these are double negatives, because feature masks only work by
diff --git a/indra/newview/llfeaturemanager.h b/indra/newview/llfeaturemanager.h
index 537bf0c6a4..383963a41d 100644
--- a/indra/newview/llfeaturemanager.h
+++ b/indra/newview/llfeaturemanager.h
@@ -35,6 +35,7 @@
#include "stdtypes.h"
+#include "llsingleton.h"
#include "llstring.h"
#include <map>
diff --git a/indra/newview/llfilepicker.cpp b/indra/newview/llfilepicker.cpp
index 8f5882615f..028e1cc098 100644
--- a/indra/newview/llfilepicker.cpp
+++ b/indra/newview/llfilepicker.cpp
@@ -39,6 +39,7 @@
#include "lldir.h"
#include "llframetimer.h"
#include "lltrans.h"
+#include "llwindow.h" // beforeDialog()
#if LL_SDL
#include "llwindowsdl.h" // for some X/GTK utils to help with filepickers
@@ -818,6 +819,13 @@ BOOL LLFilePicker::getOpenFile(ELoadFilter filter)
reset();
mNavOptions.optionFlags &= ~kNavAllowMultipleFiles;
+
+ if(filter == FFLOAD_ALL) // allow application bundles etc. to be traversed; important for DEV-16869, but generally useful
+ {
+ // mNavOptions.optionFlags |= kNavAllowOpenPackages;
+ mNavOptions.optionFlags |= kNavSupportPackages;
+ }
+
// Modal, so pause agent
send_agent_pause();
{
diff --git a/indra/newview/llfirstuse.cpp b/indra/newview/llfirstuse.cpp
index 9ee24d6d83..de079b7123 100644
--- a/indra/newview/llfirstuse.cpp
+++ b/indra/newview/llfirstuse.cpp
@@ -51,8 +51,6 @@ std::set<std::string> LLFirstUse::sConfigVariables;
// static
void LLFirstUse::addConfigVariable(const std::string& var)
{
- //Don't add the warning, now that we're storing the default in the settings_default.xml file
- //gSavedSettings.addWarning(var);
sConfigVariables.insert(var);
}
@@ -63,7 +61,7 @@ void LLFirstUse::disableFirstUse()
for (std::set<std::string>::iterator iter = sConfigVariables.begin();
iter != sConfigVariables.end(); ++iter)
{
- gSavedSettings.setWarning(*iter, FALSE);
+ gWarningSettings.setBOOL(*iter, FALSE);
}
}
@@ -74,7 +72,7 @@ void LLFirstUse::resetFirstUse()
for (std::set<std::string>::iterator iter = sConfigVariables.begin();
iter != sConfigVariables.end(); ++iter)
{
- gSavedSettings.setWarning(*iter, TRUE);
+ gWarningSettings.setBOOL(*iter, TRUE);
}
}
@@ -82,9 +80,9 @@ void LLFirstUse::resetFirstUse()
// Called whenever the viewer detects that your balance went up
void LLFirstUse::useBalanceIncrease(S32 delta)
{
- if (gSavedSettings.getWarning("FirstBalanceIncrease"))
+ if (gWarningSettings.getBOOL("FirstBalanceIncrease"))
{
- gSavedSettings.setWarning("FirstBalanceIncrease", FALSE);
+ gWarningSettings.setBOOL("FirstBalanceIncrease", FALSE);
LLSD args;
args["AMOUNT"] = llformat("%d",delta);
@@ -96,9 +94,9 @@ void LLFirstUse::useBalanceIncrease(S32 delta)
// Called whenever the viewer detects your balance went down
void LLFirstUse::useBalanceDecrease(S32 delta)
{
- if (gSavedSettings.getWarning("FirstBalanceDecrease"))
+ if (gWarningSettings.getBOOL("FirstBalanceDecrease"))
{
- gSavedSettings.setWarning("FirstBalanceDecrease", FALSE);
+ gWarningSettings.setBOOL("FirstBalanceDecrease", FALSE);
LLSD args;
args["AMOUNT"] = llformat("%d",-delta);
@@ -112,9 +110,9 @@ void LLFirstUse::useSit()
{
// Our orientation island uses sitting to teach vehicle driving
// so just never show this message. JC
- //if (gSavedSettings.getWarning("FirstSit"))
+ //if (gWarningSettings.getBOOL("FirstSit"))
//{
- // gSavedSettings.setWarning("FirstSit", FALSE);
+ // gWarningSettings.setBOOL("FirstSit", FALSE);
//
// LLNotifications::instance().add("FirstSit");
//}
@@ -123,9 +121,9 @@ void LLFirstUse::useSit()
// static
void LLFirstUse::useMap()
{
- if (gSavedSettings.getWarning("FirstMap"))
+ if (gWarningSettings.getBOOL("FirstMap"))
{
- gSavedSettings.setWarning("FirstMap", FALSE);
+ gWarningSettings.setBOOL("FirstMap", FALSE);
LLNotifications::instance().add("FirstMap");
}
@@ -140,34 +138,34 @@ void LLFirstUse::useGoTo()
// static
void LLFirstUse::useBuild()
{
- if (gSavedSettings.getWarning("FirstBuild"))
+ if (gWarningSettings.getBOOL("FirstBuild"))
{
- gSavedSettings.setWarning("FirstBuild", FALSE);
+ gWarningSettings.setBOOL("FirstBuild", FALSE);
LLNotifications::instance().add("FirstBuild");
}
}
-
+/*
// static
void LLFirstUse::useLeftClickNoHit()
{
- if (gSavedSettings.getWarning("FirstLeftClickNoHit"))
+ if (gWarningSettings.getBOOL("FirstLeftClickNoHit"))
{
- gSavedSettings.setWarning("FirstLeftClickNoHit", FALSE);
+ gWarningSettings.setBOOL("FirstLeftClickNoHit", FALSE);
LLNotifications::instance().add("FirstLeftClickNoHit");
}
}
-
+*/
// static
void LLFirstUse::useTeleport()
{
- if (gSavedSettings.getWarning("FirstTeleport"))
+ if (gWarningSettings.getBOOL("FirstTeleport"))
{
LLVector3d teleportDestination = LLTracker::getTrackedPositionGlobal();
if(teleportDestination != LLVector3d::zero)
{
- gSavedSettings.setWarning("FirstTeleport", FALSE);
+ gWarningSettings.setBOOL("FirstTeleport", FALSE);
LLNotifications::instance().add("FirstTeleport");
}
@@ -181,9 +179,9 @@ void LLFirstUse::useOverrideKeys()
// so don't show this message until you get off OI. JC
if (!gAgent.inPrelude())
{
- if (gSavedSettings.getWarning("FirstOverrideKeys"))
+ if (gWarningSettings.getBOOL("FirstOverrideKeys"))
{
- gSavedSettings.setWarning("FirstOverrideKeys", FALSE);
+ gWarningSettings.setBOOL("FirstOverrideKeys", FALSE);
LLNotifications::instance().add("FirstOverrideKeys");
}
@@ -199,9 +197,9 @@ void LLFirstUse::useAttach()
// static
void LLFirstUse::useAppearance()
{
- if (gSavedSettings.getWarning("FirstAppearance"))
+ if (gWarningSettings.getBOOL("FirstAppearance"))
{
- gSavedSettings.setWarning("FirstAppearance", FALSE);
+ gWarningSettings.setBOOL("FirstAppearance", FALSE);
LLNotifications::instance().add("FirstAppearance");
}
@@ -210,9 +208,9 @@ void LLFirstUse::useAppearance()
// static
void LLFirstUse::useInventory()
{
- if (gSavedSettings.getWarning("FirstInventory"))
+ if (gWarningSettings.getBOOL("FirstInventory"))
{
- gSavedSettings.setWarning("FirstInventory", FALSE);
+ gWarningSettings.setBOOL("FirstInventory", FALSE);
LLNotifications::instance().add("FirstInventory");
}
@@ -222,9 +220,9 @@ void LLFirstUse::useInventory()
// static
void LLFirstUse::useSandbox()
{
- if (gSavedSettings.getWarning("FirstSandbox"))
+ if (gWarningSettings.getBOOL("FirstSandbox"))
{
- gSavedSettings.setWarning("FirstSandbox", FALSE);
+ gWarningSettings.setBOOL("FirstSandbox", FALSE);
LLSD args;
args["HOURS"] = llformat("%d",SANDBOX_CLEAN_FREQ);
@@ -236,9 +234,9 @@ void LLFirstUse::useSandbox()
// static
void LLFirstUse::useFlexible()
{
- if (gSavedSettings.getWarning("FirstFlexible"))
+ if (gWarningSettings.getBOOL("FirstFlexible"))
{
- gSavedSettings.setWarning("FirstFlexible", FALSE);
+ gWarningSettings.setBOOL("FirstFlexible", FALSE);
LLNotifications::instance().add("FirstFlexible");
}
@@ -247,9 +245,9 @@ void LLFirstUse::useFlexible()
// static
void LLFirstUse::useDebugMenus()
{
- if (gSavedSettings.getWarning("FirstDebugMenus"))
+ if (gWarningSettings.getBOOL("FirstDebugMenus"))
{
- gSavedSettings.setWarning("FirstDebugMenus", FALSE);
+ gWarningSettings.setBOOL("FirstDebugMenus", FALSE);
LLNotifications::instance().add("FirstDebugMenus");
}
@@ -258,9 +256,9 @@ void LLFirstUse::useDebugMenus()
// static
void LLFirstUse::useSculptedPrim()
{
- if (gSavedSettings.getWarning("FirstSculptedPrim"))
+ if (gWarningSettings.getBOOL("FirstSculptedPrim"))
{
- gSavedSettings.setWarning("FirstSculptedPrim", FALSE);
+ gWarningSettings.setBOOL("FirstSculptedPrim", FALSE);
LLNotifications::instance().add("FirstSculptedPrim");
@@ -270,9 +268,9 @@ void LLFirstUse::useSculptedPrim()
// static
void LLFirstUse::useMedia()
{
- if (gSavedSettings.getWarning("FirstMedia"))
+ if (gWarningSettings.getBOOL("FirstMedia"))
{
- gSavedSettings.setWarning("FirstMedia", FALSE);
+ gWarningSettings.setBOOL("FirstMedia", FALSE);
LLNotifications::instance().add("FirstMedia");
}
diff --git a/indra/newview/llfirstuse.h b/indra/newview/llfirstuse.h
index bb64cdd2c6..7b4f9f516f 100644
--- a/indra/newview/llfirstuse.h
+++ b/indra/newview/llfirstuse.h
@@ -95,7 +95,7 @@ public:
static void useMap();
static void useGoTo();
static void useBuild();
- static void useLeftClickNoHit();
+// static void useLeftClickNoHit();
static void useTeleport();
static void useOverrideKeys();
static void useAttach();
diff --git a/indra/newview/llflexibleobject.cpp b/indra/newview/llflexibleobject.cpp
index 8f2c6d538b..216bca8262 100644
--- a/indra/newview/llflexibleobject.cpp
+++ b/indra/newview/llflexibleobject.cpp
@@ -39,11 +39,10 @@
#include "llglheaders.h"
#include "llrendersphere.h"
#include "llviewerobject.h"
-#include "llimagegl.h"
#include "llagent.h"
#include "llsky.h"
#include "llviewercamera.h"
-#include "llviewerimagelist.h"
+#include "llviewertexturelist.h"
#include "llviewercontrol.h"
#include "llviewerobjectlist.h"
#include "llviewerregion.h"
@@ -262,6 +261,7 @@ void LLVolumeImplFlexible::onSetVolume(const LLVolumeParams &volume_params, cons
// updated every time step. In the future, perhaps there could be an
// optimization similar to what Havok does for objects that are stationary.
//---------------------------------------------------------------------------------
+static LLFastTimer::DeclareTimer FTM_FLEXIBLE_UPDATE("Update Flexies");
BOOL LLVolumeImplFlexible::doIdleUpdate(LLAgent &agent, LLWorld &world, const F64 &time)
{
if (mVO->mDrawable.isNull())
@@ -280,7 +280,7 @@ BOOL LLVolumeImplFlexible::doIdleUpdate(LLAgent &agent, LLWorld &world, const F6
parent->mDrawable->mQuietCount = 0;
}
- LLFastTimer ftm(LLFastTimer::FTM_FLEXIBLE_UPDATE);
+ LLFastTimer ftm(FTM_FLEXIBLE_UPDATE);
S32 new_res = mAttributes->getSimulateLOD();
diff --git a/indra/newview/llflexibleobject.h b/indra/newview/llflexibleobject.h
index 895701da3a..811ae24df2 100644
--- a/indra/newview/llflexibleobject.h
+++ b/indra/newview/llflexibleobject.h
@@ -43,7 +43,6 @@
#ifndef LL_LLFLEXIBLEOBJECT_H
#define LL_LLFLEXIBLEOBJECT_H
-#include "llmemory.h"
#include "llprimitive.h"
#include "llvovolume.h"
#include "llwind.h"
diff --git a/indra/newview/llfloaterabout.cpp b/indra/newview/llfloaterabout.cpp
index 810799d27c..56c5eaa70e 100644
--- a/indra/newview/llfloaterabout.cpp
+++ b/indra/newview/llfloaterabout.cpp
@@ -42,7 +42,7 @@
#include "llcurl.h"
#include "llimagej2c.h"
-#include "audioengine.h"
+#include "llaudioengine.h"
#include "llviewertexteditor.h"
#include "llviewercontrol.h"
@@ -58,9 +58,10 @@
#include "lltrans.h"
#include "llappviewer.h"
#include "llglheaders.h"
-#include "llmediamanager.h"
#include "llwindow.h"
+#include "llbutton.h"
+
#if LL_WINDOWS
#include "lldxhardware.h"
#endif
@@ -69,59 +70,51 @@ extern LLCPUInfo gSysCPU;
extern LLMemoryInfo gSysMemory;
extern U32 gPacketsIn;
-///----------------------------------------------------------------------------
-/// Local function declarations, constants, enums, and typedefs
-///----------------------------------------------------------------------------
-
-LLFloaterAbout* LLFloaterAbout::sInstance = NULL;
-
static std::string get_viewer_release_notes_url();
+
///----------------------------------------------------------------------------
/// Class LLFloaterAbout
///----------------------------------------------------------------------------
// Default constructor
-LLFloaterAbout::LLFloaterAbout()
-: LLFloater(std::string("floater_about"), std::string("FloaterAboutRect"), LLStringUtil::null)
+LLFloaterAbout::LLFloaterAbout(const LLSD& key)
+: LLFloater(key)
{
- LLUICtrlFactory::getInstance()->buildFloater(this, "floater_about.xml");
+ //LLUICtrlFactory::getInstance()->buildFloater(this, "floater_about.xml");
+
+}
- // Support for changing product name.
- std::string title("About ");
- title += LLAppViewer::instance()->getSecondLifeTitle();
- setTitle(title);
+// Destroys the object
+LLFloaterAbout::~LLFloaterAbout()
+{
+}
+BOOL LLFloaterAbout::postBuild()
+{
+ center();
LLViewerTextEditor *support_widget =
getChild<LLViewerTextEditor>("support_editor", true);
LLViewerTextEditor *credits_widget =
getChild<LLViewerTextEditor>("credits_editor", true);
-
- if (!support_widget || !credits_widget)
- {
- return;
- }
-
// For some reason, adding style doesn't work unless this is true.
support_widget->setParseHTML(TRUE);
// Text styles for release notes hyperlinks
- LLStyleSP viewer_link_style(new LLStyle);
- viewer_link_style->setVisible(true);
- viewer_link_style->setFontName(LLStringUtil::null);
- viewer_link_style->setLinkHREF(get_viewer_release_notes_url());
- viewer_link_style->setColor(gSavedSettings.getColor4("HTMLLinkColor"));
+ LLStyle::Params link_style_params;
+ link_style_params.color.control = "HTMLLinkColor";
+ link_style_params.link_href = get_viewer_release_notes_url();
// Version string
- std::string version = LLAppViewer::instance()->getSecondLifeTitle()
+ std::string version = LLTrans::getString("APP_NAME")
+ llformat(" %d.%d.%d (%d) %s %s (%s)\n",
LL_VERSION_MAJOR, LL_VERSION_MINOR, LL_VERSION_PATCH, LL_VIEWER_BUILD,
__DATE__, __TIME__,
gSavedSettings.getString("VersionChannelName").c_str());
- support_widget->appendColoredText(version, FALSE, FALSE, gColors.getColor("TextFgReadOnlyColor"));
- support_widget->appendStyledText(LLTrans::getString("ReleaseNotes"), false, false, viewer_link_style);
+ support_widget->appendColoredText(version, FALSE, FALSE, LLUIColorTable::instance().getColor("TextFgReadOnlyColor"));
+ support_widget->appendStyledText(LLTrans::getString("ReleaseNotes"), false, false, link_style_params);
std::string support;
support.append("\n\n");
@@ -138,11 +131,9 @@ LLFloaterAbout::LLFloaterAbout()
LLViewerRegion* region = gAgent.getRegion();
if (region)
{
- LLStyleSP server_link_style(new LLStyle);
- server_link_style->setVisible(true);
- server_link_style->setFontName(LLStringUtil::null);
- server_link_style->setLinkHREF(region->getCapability("ServerReleaseNotes"));
- server_link_style->setColor(gSavedSettings.getColor4("HTMLLinkColor"));
+ LLStyle::Params server_link_style_params;
+ server_link_style_params.color.control = "HTMLLinkColor";
+ server_link_style_params.link_href = region->getCapability("ServerReleaseNotes");
const LLVector3d &pos = gAgent.getPositionGlobal();
LLUIString pos_text = getString("you_are_at");
@@ -150,8 +141,8 @@ LLFloaterAbout::LLFloaterAbout()
llformat("%.1f, %.1f, %.1f ", pos.mdV[VX], pos.mdV[VY], pos.mdV[VZ]));
support.append(pos_text);
- std::string region_text = llformat("in %s located at ",
- gAgent.getRegion()->getName().c_str());
+ LLUIString region_text = getString ("in_region") + " ";
+ region_text.setArg("[REGION]", llformat ("%s", gAgent.getRegion()->getName().c_str()));
support.append(region_text);
std::string buffer;
@@ -164,8 +155,8 @@ LLFloaterAbout::LLFloaterAbout()
support.append(gLastVersionChannel);
support.append("\n");
- support_widget->appendColoredText(support, FALSE, FALSE, gColors.getColor("TextFgReadOnlyColor"));
- support_widget->appendStyledText(LLTrans::getString("ReleaseNotes"), false, false, server_link_style);
+ support_widget->appendColoredText(support, FALSE, FALSE, LLUIColorTable::instance().getColor("TextFgReadOnlyColor"));
+ support_widget->appendStyledText(LLTrans::getString("ReleaseNotes"), false, false, server_link_style_params);
support = "\n\n";
}
@@ -175,25 +166,26 @@ LLFloaterAbout::LLFloaterAbout()
// and this info sometimes gets sent to support
// CPU
- support.append("CPU: ");
+ support.append(getString("CPU") + " ");
support.append( gSysCPU.getCPUString() );
support.append("\n");
U32 memory = gSysMemory.getPhysicalMemoryKB() / 1024;
// Moved hack adjustment to Windows memory size into llsys.cpp
- std::string mem_text = llformat("Memory: %u MB\n", memory );
- support.append(mem_text);
+ LLStringUtil::format_map_t args;
+ args["[MEM]"] = llformat ("%u", memory);
+ support.append(getString("Memory", args) + "\n");
- support.append("OS Version: ");
+ support.append(getString("OSVersion") + " ");
support.append( LLAppViewer::instance()->getOSInfo().getOSString() );
support.append("\n");
- support.append("Graphics Card Vendor: ");
+ support.append(getString("GraphicsCardVendor") + " ");
support.append( (const char*) glGetString(GL_VENDOR) );
support.append("\n");
- support.append("Graphics Card: ");
+ support.append(getString("GraphicsCard") + " ");
support.append( (const char*) glGetString(GL_RENDERER) );
support.append("\n");
@@ -211,98 +203,65 @@ LLFloaterAbout::LLFloaterAbout()
getWindow()->setCursor(UI_CURSOR_ARROW);
#endif
- support.append("OpenGL Version: ");
+ support.append(getString("OpenGLVersion") + " ");
support.append( (const char*) glGetString(GL_VERSION) );
support.append("\n");
support.append("\n");
- support.append("libcurl Version: ");
+ support.append(getString("LibCurlVersion") + " ");
support.append( LLCurl::getVersionString() );
support.append("\n");
- support.append("J2C Decoder Version: ");
+ support.append(getString("J2CDecoderVersion") + " ");
support.append( LLImageJ2C::getEngineInfo() );
support.append("\n");
- support.append("Audio Driver Version: ");
+ support.append(getString("AudioDriverVersion") + " ");
bool want_fullname = true;
- support.append( gAudiop ? gAudiop->getDriverName(want_fullname) : "(none)" );
+ support.append( gAudiop ? gAudiop->getDriverName(want_fullname) : getString("none") );
support.append("\n");
- LLMediaManager *mgr = LLMediaManager::getInstance();
- if (mgr)
- {
- LLMediaBase *media_source = mgr->createSourceFromMimeType("http", "text/html");
- if (media_source)
- {
- support.append("LLMozLib Version: ");
- support.append(media_source->getVersion());
- support.append("\n");
- mgr->destroySource(media_source);
- }
- }
+ // TODO: Implement media plugin version query
+
+ support.append(getString("LLQtWebkitVersion") + " ");
+ support.append("\n");
if (gPacketsIn > 0)
{
- std::string packet_loss = llformat("Packets Lost: %.0f/%.0f (%.1f%%)",
- LLViewerStats::getInstance()->mPacketsLostStat.getCurrent(),
- F32(gPacketsIn),
- 100.f*LLViewerStats::getInstance()->mPacketsLostStat.getCurrent() / F32(gPacketsIn) );
- support.append(packet_loss);
- support.append("\n");
+ args["[LOST]"] = llformat ("%.0f", LLViewerStats::getInstance()->mPacketsLostStat.getCurrent());
+ args["[IN]"] = llformat ("%.0f", F32(gPacketsIn));
+ args["[PCT]"] = llformat ("%.1f", 100.f*LLViewerStats::getInstance()->mPacketsLostStat.getCurrent() / F32(gPacketsIn) );
+ support.append(getString ("PacketsLost", args) + "\n");
}
- support_widget->appendColoredText(support, FALSE, FALSE, gColors.getColor("TextFgReadOnlyColor"));
+ support_widget->appendColoredText(support, FALSE, FALSE, LLUIColorTable::instance().getColor("TextFgReadOnlyColor"));
// Fix views
support_widget->setCursorPos(0);
support_widget->setEnabled(FALSE);
- support_widget->setTakesFocus(TRUE);
- support_widget->setHandleEditKeysDirectly(TRUE);
credits_widget->setCursorPos(0);
credits_widget->setEnabled(FALSE);
- credits_widget->setTakesFocus(TRUE);
- credits_widget->setHandleEditKeysDirectly(TRUE);
-
- center();
- sInstance = this;
+ return TRUE;
}
-// Destroys the object
-LLFloaterAbout::~LLFloaterAbout()
-{
- sInstance = NULL;
-}
-// static
-void LLFloaterAbout::show(void*)
-{
- if (!sInstance)
- {
- sInstance = new LLFloaterAbout();
- }
+ static std::string get_viewer_release_notes_url()
+ {
+ std::ostringstream version;
+ version << LL_VERSION_MAJOR << "."
+ << LL_VERSION_MINOR << "."
+ << LL_VERSION_PATCH << "."
+ << LL_VERSION_BUILD;
- sInstance->open(); /*Flawfinder: ignore*/
-}
+ LLSD query;
+ query["channel"] = gSavedSettings.getString("VersionChannelName");
+ query["version"] = version.str();
+ std::ostringstream url;
+ url << LLTrans::getString("RELEASE_NOTES_BASE_URL") << LLURI::mapToQueryString(query);
-static std::string get_viewer_release_notes_url()
-{
- std::ostringstream version;
- version << LL_VERSION_MAJOR << "."
- << LL_VERSION_MINOR << "."
- << LL_VERSION_PATCH << "."
- << LL_VERSION_BUILD;
-
- LLSD query;
- query["channel"] = gSavedSettings.getString("VersionChannelName");
- query["version"] = version.str();
-
- std::ostringstream url;
- url << RELEASE_NOTES_BASE_URL << LLURI::mapToQueryString(query);
-
- return url.str();
-}
+ return url.str();
+ }
diff --git a/indra/newview/llfloaterabout.h b/indra/newview/llfloaterabout.h
index 7564b8e41c..c15a20d549 100644
--- a/indra/newview/llfloaterabout.h
+++ b/indra/newview/llfloaterabout.h
@@ -36,16 +36,15 @@
#include "llfloater.h"
class LLFloaterAbout
-: public LLFloater
+ : public LLFloater
{
-public:
- LLFloaterAbout();
+ friend class LLFloaterReg;
+private:
+ LLFloaterAbout(const LLSD& key);
virtual ~LLFloaterAbout();
- static void show(void*);
-
-private:
- static LLFloaterAbout* sInstance;
+public:
+ /*virtual*/ BOOL postBuild();
};
diff --git a/indra/newview/llfloateranimpreview.cpp b/indra/newview/llfloateranimpreview.cpp
index 162456b8ce..dec27db74b 100644
--- a/indra/newview/llfloateranimpreview.cpp
+++ b/indra/newview/llfloateranimpreview.cpp
@@ -37,11 +37,13 @@
#include "llbvhloader.h"
#include "lldatapacker.h"
#include "lldir.h"
+#include "lleconomy.h"
#include "llvfile.h"
#include "llapr.h"
#include "llstring.h"
#include "llagent.h"
+#include "llanimationstates.h"
#include "llbbox.h"
#include "llbutton.h"
#include "llcheckboxctrl.h"
@@ -66,8 +68,7 @@
#include "llvoavatar.h"
#include "pipeline.h"
#include "lluictrlfactory.h"
-
-S32 LLFloaterAnimPreview::sUploadAmount = 10;
+#include "lltrans.h"
const S32 PREVIEW_BORDER_WIDTH = 2;
const S32 PREVIEW_RESIZE_HANDLE_SIZE = S32(RESIZE_HANDLE_WIDTH * OO_SQRT2) + PREVIEW_BORDER_WIDTH;
@@ -82,6 +83,40 @@ const F32 MAX_CAMERA_ZOOM = 10.f;
const F32 BASE_ANIM_TIME_OFFSET = 5.f;
+std::string STATUS[] =
+{
+ "E_ST_OK",
+ "E_ST_EOF",
+ "E_ST_NO_CONSTRAINT",
+ "E_ST_NO_FILE",
+"E_ST_NO_HIER",
+"E_ST_NO_JOINT",
+"E_ST_NO_NAME",
+"E_ST_NO_OFFSET",
+"E_ST_NO_CHANNELS",
+"E_ST_NO_ROTATION",
+"E_ST_NO_AXIS",
+"E_ST_NO_MOTION",
+"E_ST_NO_FRAMES",
+"E_ST_NO_FRAME_TIME",
+"E_ST_NO_POS",
+"E_ST_NO_ROT",
+"E_ST_NO_XLT_FILE",
+"E_ST_NO_XLT_HEADER",
+"E_ST_NO_XLT_NAME",
+"E_ST_NO_XLT_IGNORE",
+"E_ST_NO_XLT_RELATIVE",
+"E_ST_NO_XLT_OUTNAME",
+"E_ST_NO_XLT_MATRIX",
+"E_ST_NO_XLT_MERGECHILD",
+"E_ST_NO_XLT_MERGEPARENT",
+"E_ST_NO_XLT_PRIORITY",
+"E_ST_NO_XLT_LOOP",
+"E_ST_NO_XLT_EASEIN",
+"E_ST_NO_XLT_EASEOUT",
+"E_ST_NO_XLT_HAND",
+"E_ST_NO_XLT_EMOTE",
+};
//-----------------------------------------------------------------------------
// LLFloaterAnimPreview()
//-----------------------------------------------------------------------------
@@ -131,9 +166,9 @@ void LLFloaterAnimPreview::setAnimCallbacks()
childSetCommitCallback("priority", onCommitPriority, this);
childSetCommitCallback("loop_check", onCommitLoop, this);
childSetCommitCallback("loop_in_point", onCommitLoopIn, this);
- childSetValidate("loop_in_point", validateLoopIn);
+ childSetValidate("loop_in_point", boost::bind(&LLFloaterAnimPreview::validateLoopIn, this, _1));
childSetCommitCallback("loop_out_point", onCommitLoopOut, this);
- childSetValidate("loop_out_point", validateLoopOut);
+ childSetValidate("loop_out_point", boost::bind(&LLFloaterAnimPreview::validateLoopOut, this, _1));
childSetCommitCallback("hand_pose_combo", onCommitHandPose, this);
@@ -141,9 +176,9 @@ void LLFloaterAnimPreview::setAnimCallbacks()
childSetValue("emote_combo", "[None]");
childSetCommitCallback("ease_in_time", onCommitEaseIn, this);
- childSetValidate("ease_in_time", validateEaseIn);
+ childSetValidate("ease_in_time", boost::bind(&LLFloaterAnimPreview::validateEaseIn, this, _1));
childSetCommitCallback("ease_out_time", onCommitEaseOut, this);
- childSetValidate("ease_out_time", validateEaseOut);
+ childSetValidate("ease_out_time", boost::bind(&LLFloaterAnimPreview::validateEaseOut, this, _1));
}
//-----------------------------------------------------------------------------
@@ -151,7 +186,6 @@ void LLFloaterAnimPreview::setAnimCallbacks()
//-----------------------------------------------------------------------------
BOOL LLFloaterAnimPreview::postBuild()
{
- LLRect r;
LLKeyframeMotion* motionp = NULL;
LLBVHLoader* loaderp = NULL;
@@ -162,7 +196,6 @@ BOOL LLFloaterAnimPreview::postBuild()
childSetCommitCallback("name_form", onCommitName, this);
- childSetLabelArg("ok_btn", "[AMOUNT]", llformat("%d",sUploadAmount));
childSetAction("ok_btn", onBtnOK, this);
setDefaultBtn();
@@ -172,63 +205,14 @@ BOOL LLFloaterAnimPreview::postBuild()
PREVIEW_HPAD + PREF_BUTTON_HEIGHT + PREVIEW_HPAD);
mPreviewImageRect.set(0.f, 1.f, 1.f, 0.f);
- S32 y = mPreviewRect.mTop + BTN_HEIGHT;
- S32 btn_left = PREVIEW_HPAD;
-
- r.set( btn_left, y, btn_left + 32, y - BTN_HEIGHT );
mPlayButton = getChild<LLButton>( "play_btn");
- if (!mPlayButton)
- {
- mPlayButton = new LLButton(std::string("play_btn"), LLRect(0,0,0,0));
- }
- mPlayButton->setClickedCallback(onBtnPlay);
- mPlayButton->setCallbackUserData(this);
-
- mPlayButton->setImages(std::string("button_anim_play.tga"),
- std::string("button_anim_play_selected.tga"));
- mPlayButton->setDisabledImages(LLStringUtil::null,LLStringUtil::null);
-
- mPlayButton->setScaleImage(TRUE);
+ mPlayButton->setClickedCallback(onBtnPlay, this);
mStopButton = getChild<LLButton>( "stop_btn");
- if (!mStopButton)
- {
- mStopButton = new LLButton(std::string("stop_btn"), LLRect(0,0,0,0));
- }
- mStopButton->setClickedCallback(onBtnStop);
- mStopButton->setCallbackUserData(this);
-
- mStopButton->setImages(std::string("button_anim_stop.tga"),
- std::string("button_anim_stop_selected.tga"));
- mStopButton->setDisabledImages(LLStringUtil::null,LLStringUtil::null);
-
- mStopButton->setScaleImage(TRUE);
-
- r.set(r.mRight + PREVIEW_HPAD, y, getRect().getWidth() - PREVIEW_HPAD, y - BTN_HEIGHT);
- //childSetCommitCallback("playback_slider", onSliderMove, this);
+ mStopButton->setClickedCallback(onBtnStop, this);
childHide("bad_animation_text");
- //childSetCommitCallback("preview_base_anim", onCommitBaseAnim, this);
- //childSetValue("preview_base_anim", "Standing");
-
- //childSetCommitCallback("priority", onCommitPriority, this);
- //childSetCommitCallback("loop_check", onCommitLoop, this);
- //childSetCommitCallback("loop_in_point", onCommitLoopIn, this);
- //childSetValidate("loop_in_point", validateLoopIn);
- //childSetCommitCallback("loop_out_point", onCommitLoopOut, this);
- //childSetValidate("loop_out_point", validateLoopOut);
-
- //childSetCommitCallback("hand_pose_combo", onCommitHandPose, this);
-
- //childSetCommitCallback("emote_combo", onCommitEmote, this);
- //childSetValue("emote_combo", "[None]");
-
- //childSetCommitCallback("ease_in_time", onCommitEaseIn, this);
- //childSetValidate("ease_in_time", validateEaseIn);
- //childSetCommitCallback("ease_out_time", onCommitEaseOut, this);
- //childSetValidate("ease_out_time", validateEaseOut);
-
std::string exten = gDirUtilp->getExtension(mFilename);
if (exten == "bvh")
{
@@ -254,7 +238,19 @@ BOOL LLFloaterAnimPreview::postBuild()
{
file_buffer[file_size] = '\0';
llinfos << "Loading BVH file " << mFilename << llendl;
- loaderp = new LLBVHLoader(file_buffer);
+ ELoadStatus load_status = E_ST_OK;
+ S32 line_number = 0;
+ loaderp = new LLBVHLoader(file_buffer, load_status, line_number);
+ std::string status = getString(STATUS[load_status]);
+
+ if(load_status == E_ST_NO_XLT_FILE)
+ {
+ llwarns << "NOTE: No translation table found." << llendl;
+ }
+ else
+ {
+ llwarns << "ERROR: [line: " << line_number << "] " << status << llendl;
+ }
}
infile.close() ;
@@ -309,8 +305,9 @@ BOOL LLFloaterAnimPreview::postBuild()
motionp->setName(childGetValue("name_form").asString());
mAnimPreview->getDummyAvatar()->startMotion(mMotionID);
- childSetMinValue("playback_slider", 0.0);
- childSetMaxValue("playback_slider", 1.0);
+
+ getChild<LLSlider>("playback_slider")->setMinValue(0.0);
+ getChild<LLSlider>("playback_slider")->setMaxValue(1.0);
childSetValue("loop_check", LLSD(motionp->getLoop()));
childSetValue("loop_in_point", LLSD(motionp->getLoopIn() / motionp->getDuration() * 100.f));
@@ -327,7 +324,6 @@ BOOL LLFloaterAnimPreview::postBuild()
}
else
{
- delete mAnimPreview;
mAnimPreview = NULL;
mMotionID.setNull();
childSetValue("bad_animation_text", getString("failed_to_initialize"));
@@ -347,7 +343,7 @@ BOOL LLFloaterAnimPreview::postBuild()
else
{
LLUIString out_str = getString("failed_file_read");
- out_str.setArg("[STATUS]", loaderp->getStatus()); // *TODO:Translate
+ out_str.setArg("[STATUS]", getString(STATUS[loaderp->getStatus()]));
childSetValue("bad_animation_text", out_str.getString());
}
}
@@ -369,7 +365,6 @@ BOOL LLFloaterAnimPreview::postBuild()
//-----------------------------------------------------------------------------
LLFloaterAnimPreview::~LLFloaterAnimPreview()
{
- delete mAnimPreview;
mAnimPreview = NULL;
setEnabled(FALSE);
@@ -389,7 +384,7 @@ void LLFloaterAnimPreview::draw()
{
gGL.color3f(1.f, 1.f, 1.f);
- gGL.getTexUnit(0)->bind(mAnimPreview->getTexture());
+ gGL.getTexUnit(0)->bind(mAnimPreview);
gGL.begin( LLRender::QUADS );
{
@@ -736,7 +731,7 @@ void LLFloaterAnimPreview::onCommitName(LLUICtrl* ctrl, void* data)
motionp->setName(previewp->childGetValue("name_form").asString());
}
- LLFloaterNameDesc::doCommit(ctrl, data);
+ previewp->doCommit();
}
//-----------------------------------------------------------------------------
@@ -813,57 +808,53 @@ void LLFloaterAnimPreview::onCommitEaseOut(LLUICtrl* ctrl, void* data)
//-----------------------------------------------------------------------------
// validateEaseIn()
//-----------------------------------------------------------------------------
-BOOL LLFloaterAnimPreview::validateEaseIn(LLUICtrl* spin, void* data)
+bool LLFloaterAnimPreview::validateEaseIn(const LLSD& data)
{
- LLFloaterAnimPreview* previewp = (LLFloaterAnimPreview*)data;
- if (!previewp->getEnabled())
- return FALSE;
+ if (!getEnabled())
+ return false;
- LLVOAvatar* avatarp = previewp->mAnimPreview->getDummyAvatar();
- LLKeyframeMotion* motionp = (LLKeyframeMotion*)avatarp->findMotion(previewp->mMotionID);
+ LLVOAvatar* avatarp = mAnimPreview->getDummyAvatar();
+ LLKeyframeMotion* motionp = (LLKeyframeMotion*)avatarp->findMotion(mMotionID);
if (!motionp->getLoop())
{
- F32 new_ease_in = llclamp((F32)previewp->childGetValue("ease_in_time").asReal(), 0.f, motionp->getDuration() - motionp->getEaseOutDuration());
- previewp->childSetValue("ease_in_time", LLSD(new_ease_in));
+ F32 new_ease_in = llclamp((F32)childGetValue("ease_in_time").asReal(), 0.f, motionp->getDuration() - motionp->getEaseOutDuration());
+ childSetValue("ease_in_time", LLSD(new_ease_in));
}
- return TRUE;
+ return true;
}
//-----------------------------------------------------------------------------
// validateEaseOut()
//-----------------------------------------------------------------------------
-BOOL LLFloaterAnimPreview::validateEaseOut(LLUICtrl* spin, void* data)
+bool LLFloaterAnimPreview::validateEaseOut(const LLSD& data)
{
- LLFloaterAnimPreview* previewp = (LLFloaterAnimPreview*)data;
-
- if (!previewp->getEnabled())
- return FALSE;
+ if (!getEnabled())
+ return false;
- LLVOAvatar* avatarp = previewp->mAnimPreview->getDummyAvatar();
- LLKeyframeMotion* motionp = (LLKeyframeMotion*)avatarp->findMotion(previewp->mMotionID);
+ LLVOAvatar* avatarp = mAnimPreview->getDummyAvatar();
+ LLKeyframeMotion* motionp = (LLKeyframeMotion*)avatarp->findMotion(mMotionID);
if (!motionp->getLoop())
{
- F32 new_ease_out = llclamp((F32)previewp->childGetValue("ease_out_time").asReal(), 0.f, motionp->getDuration() - motionp->getEaseInDuration());
- previewp->childSetValue("ease_out_time", LLSD(new_ease_out));
+ F32 new_ease_out = llclamp((F32)childGetValue("ease_out_time").asReal(), 0.f, motionp->getDuration() - motionp->getEaseInDuration());
+ childSetValue("ease_out_time", LLSD(new_ease_out));
}
- return TRUE;
+ return true;
}
//-----------------------------------------------------------------------------
// validateLoopIn()
//-----------------------------------------------------------------------------
-BOOL LLFloaterAnimPreview::validateLoopIn(LLUICtrl* ctrl, void* data)
+bool LLFloaterAnimPreview::validateLoopIn(const LLSD& data)
{
- LLFloaterAnimPreview* previewp = (LLFloaterAnimPreview*)data;
- if (!previewp->getEnabled())
- return FALSE;
+ if (!getEnabled())
+ return false;
- F32 loop_in_value = (F32)previewp->childGetValue("loop_in_point").asReal();
- F32 loop_out_value = (F32)previewp->childGetValue("loop_out_point").asReal();
+ F32 loop_in_value = (F32)childGetValue("loop_in_point").asReal();
+ F32 loop_out_value = (F32)childGetValue("loop_out_point").asReal();
if (loop_in_value < 0.f)
{
@@ -878,21 +869,20 @@ BOOL LLFloaterAnimPreview::validateLoopIn(LLUICtrl* ctrl, void* data)
loop_in_value = loop_out_value;
}
- previewp->childSetValue("loop_in_point", LLSD(loop_in_value));
- return TRUE;
+ childSetValue("loop_in_point", LLSD(loop_in_value));
+ return true;
}
//-----------------------------------------------------------------------------
// validateLoopOut()
//-----------------------------------------------------------------------------
-BOOL LLFloaterAnimPreview::validateLoopOut(LLUICtrl* spin, void* data)
+bool LLFloaterAnimPreview::validateLoopOut(const LLSD& data)
{
- LLFloaterAnimPreview* previewp = (LLFloaterAnimPreview*)data;
- if (!previewp->getEnabled())
- return FALSE;
+ if (!getEnabled())
+ return false;
- F32 loop_out_value = (F32)previewp->childGetValue("loop_out_point").asReal();
- F32 loop_in_value = (F32)previewp->childGetValue("loop_in_point").asReal();
+ F32 loop_out_value = (F32)childGetValue("loop_out_point").asReal();
+ F32 loop_in_value = (F32)childGetValue("loop_in_point").asReal();
if (loop_out_value < 0.f)
{
@@ -907,8 +897,8 @@ BOOL LLFloaterAnimPreview::validateLoopOut(LLUICtrl* spin, void* data)
loop_out_value = loop_in_value;
}
- previewp->childSetValue("loop_out_point", LLSD(loop_out_value));
- return TRUE;
+ childSetValue("loop_out_point", LLSD(loop_out_value));
+ return true;
}
@@ -992,7 +982,7 @@ void LLFloaterAnimPreview::onBtnOK(void* userdata)
std::string name = floaterp->childGetValue("name_form").asString();
std::string desc = floaterp->childGetValue("description_form").asString();
LLAssetStorage::LLStoreAssetCallback callback = NULL;
- S32 expected_upload_cost = sUploadAmount;
+ S32 expected_upload_cost = LLGlobalEconomy::Singleton::getInstance()->getPriceUpload();
void *userdata = NULL;
upload_new_resource(floaterp->mTransactionID, // tid
LLAssetType::AT_ANIMATION,
@@ -1018,13 +1008,13 @@ void LLFloaterAnimPreview::onBtnOK(void* userdata)
LLKeyframeDataCache::removeKeyframeData(floaterp->mMotionID);
}
- floaterp->close(false);
+ floaterp->closeFloater(false);
}
//-----------------------------------------------------------------------------
// LLPreviewAnimation
//-----------------------------------------------------------------------------
-LLPreviewAnimation::LLPreviewAnimation(S32 width, S32 height) : LLDynamicTexture(width, height, 3, ORDER_MIDDLE, FALSE)
+LLPreviewAnimation::LLPreviewAnimation(S32 width, S32 height) : LLViewerDynamicTexture(width, height, 3, ORDER_MIDDLE, FALSE)
{
mNeedsUpdate = TRUE;
mCameraDistance = PREVIEW_CAMERA_DISTANCE;
@@ -1070,7 +1060,7 @@ BOOL LLPreviewAnimation::render()
glMatrixMode(GL_PROJECTION);
gGL.pushMatrix();
glLoadIdentity();
- glOrtho(0.0f, mWidth, 0.0f, mHeight, -1.0f, 1.0f);
+ glOrtho(0.0f, mFullWidth, 0.0f, mFullHeight, -1.0f, 1.0f);
glMatrixMode(GL_MODELVIEW);
gGL.pushMatrix();
@@ -1080,7 +1070,7 @@ BOOL LLPreviewAnimation::render()
gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
gGL.color4f(0.15f, 0.2f, 0.3f, 1.f);
- gl_rect_2d_simple( mWidth, mHeight );
+ gl_rect_2d_simple( mFullWidth, mFullHeight );
glMatrixMode(GL_PROJECTION);
gGL.popMatrix();
@@ -1102,7 +1092,7 @@ BOOL LLPreviewAnimation::render()
target_pos + (mCameraOffset * av_rot) ); // point of interest
LLViewerCamera::getInstance()->setView(LLViewerCamera::getInstance()->getDefaultFOV() / mCameraZoom);
- LLViewerCamera::getInstance()->setPerspective(FALSE, mOrigin.mX, mOrigin.mY, mWidth, mHeight, FALSE);
+ LLViewerCamera::getInstance()->setPerspective(FALSE, mOrigin.mX, mOrigin.mY, mFullWidth, mFullHeight, FALSE);
mCameraRelPos = LLViewerCamera::getInstance()->getOrigin() - avatarp->mHeadp->getWorldPosition();
diff --git a/indra/newview/llfloateranimpreview.h b/indra/newview/llfloateranimpreview.h
index 639c9277cd..f1c4a6b0d0 100644
--- a/indra/newview/llfloateranimpreview.h
+++ b/indra/newview/llfloateranimpreview.h
@@ -41,12 +41,14 @@
class LLVOAvatar;
class LLViewerJointMesh;
-class LLPreviewAnimation : public LLDynamicTexture
+class LLPreviewAnimation : public LLViewerDynamicTexture
{
-public:
- LLPreviewAnimation(S32 width, S32 height);
+protected:
virtual ~LLPreviewAnimation();
+public:
+ LLPreviewAnimation(S32 width, S32 height);
+
BOOL render();
void requestUpdate();
void rotate(F32 yaw_radians, F32 pitch_radians);
@@ -86,22 +88,21 @@ public:
static void onBtnPlay(void*);
static void onBtnStop(void*);
- static void setUploadAmount(S32 amount) { sUploadAmount = amount; }
static void onSliderMove(LLUICtrl*, void*);
static void onCommitBaseAnim(LLUICtrl*, void*);
static void onCommitLoop(LLUICtrl*, void*);
static void onCommitLoopIn(LLUICtrl*, void*);
static void onCommitLoopOut(LLUICtrl*, void*);
- static BOOL validateLoopIn(LLUICtrl*, void*);
- static BOOL validateLoopOut(LLUICtrl*, void*);
+ bool validateLoopIn(const LLSD& data);
+ bool validateLoopOut(const LLSD& data);
static void onCommitName(LLUICtrl*, void*);
static void onCommitHandPose(LLUICtrl*, void*);
static void onCommitEmote(LLUICtrl*, void*);
static void onCommitPriority(LLUICtrl*, void*);
static void onCommitEaseIn(LLUICtrl*, void*);
static void onCommitEaseOut(LLUICtrl*, void*);
- static BOOL validateEaseIn(LLUICtrl*, void*);
- static BOOL validateEaseOut(LLUICtrl*, void*);
+ bool validateEaseIn(const LLSD& data);
+ bool validateEaseOut(const LLSD& data);
static void onBtnOK(void*);
static void onSaveComplete(const LLUUID& asset_uuid,
LLAssetType::EType type,
@@ -114,7 +115,7 @@ protected:
void draw();
void resetMotion();
- LLPreviewAnimation* mAnimPreview;
+ LLPointer< LLPreviewAnimation > mAnimPreview;
S32 mLastMouseX;
S32 mLastMouseY;
LLButton* mPlayButton;
@@ -127,8 +128,6 @@ protected:
LLAnimPauseRequest mPauseRequest;
std::map<std::string, LLUUID> mIDList;
-
- static S32 sUploadAmount;
};
#endif // LL_LLFLOATERANIMPREVIEW_H
diff --git a/indra/newview/llfloaterauction.cpp b/indra/newview/llfloaterauction.cpp
index 747431fb19..da2a4d9d93 100644
--- a/indra/newview/llfloaterauction.cpp
+++ b/indra/newview/llfloaterauction.cpp
@@ -41,12 +41,13 @@
#include "llparcel.h"
#include "llvfile.h"
#include "llvfs.h"
+#include "llwindow.h"
#include "llagent.h"
#include "llcombobox.h"
#include "llnotify.h"
#include "llsavedsettingsglue.h"
-#include "llviewerimagelist.h"
+#include "llviewertexturelist.h"
#include "llviewerparcelmgr.h"
#include "llviewerregion.h"
#include "lluictrlfactory.h"
@@ -69,41 +70,29 @@ void auction_tga_upload_done(const LLUUID& asset_id,
/// Class llfloaterauction
///----------------------------------------------------------------------------
-LLFloaterAuction* LLFloaterAuction::sInstance = NULL;
-
// Default constructor
-LLFloaterAuction::LLFloaterAuction() :
- LLFloater(std::string("floater_auction")),
+LLFloaterAuction::LLFloaterAuction(const LLSD& key)
+ : LLFloater(key),
mParcelID(-1)
{
- LLUICtrlFactory::getInstance()->buildFloater(this, "floater_auction.xml");
-
- childSetValue("fence_check",
- LLSD( gSavedSettings.getBOOL("AuctionShowFence") ) );
- childSetCommitCallback("fence_check",
- LLSavedSettingsGlue::setBOOL, (void*)"AuctionShowFence");
-
- childSetAction("snapshot_btn", onClickSnapshot, this);
- childSetAction("ok_btn", onClickOK, this);
+// LLUICtrlFactory::getInstance()->buildFloater(this, "floater_auction.xml");
+ mCommitCallbackRegistrar.add("ClickSnapshot", boost::bind(&LLFloaterAuction::onClickSnapshot, this));
+ mCommitCallbackRegistrar.add("ClickOK", boost::bind(&LLFloaterAuction::onClickOK, this));
}
// Destroys the object
LLFloaterAuction::~LLFloaterAuction()
{
- sInstance = NULL;
}
-// static
-void LLFloaterAuction::show()
+BOOL LLFloaterAuction::postBuild()
{
- if(!sInstance)
- {
- sInstance = new LLFloaterAuction();
- sInstance->center();
- sInstance->setFocus(TRUE);
- }
- sInstance->initialize();
- sInstance->open(); /*Flawfinder: ignore*/
+ return TRUE;
+}
+
+void LLFloaterAuction::onOpen(const LLSD& key)
+{
+ initialize();
}
void LLFloaterAuction::initialize()
@@ -197,7 +186,7 @@ void LLFloaterAuction::onClickSnapshot(void* data)
tga->encode(raw);
LLVFile::writeFile(tga->getData(), tga->getDataSize(), gVFS, self->mImageID, LLAssetType::AT_IMAGE_TGA);
- raw->biasedScaleToPowerOfTwo(LLViewerImage::MAX_IMAGE_SIZE_DEFAULT);
+ raw->biasedScaleToPowerOfTwo(LLViewerTexture::MAX_IMAGE_SIZE_DEFAULT);
llinfos << "Writing J2C..." << llendl;
@@ -205,7 +194,7 @@ void LLFloaterAuction::onClickSnapshot(void* data)
j2c->encode(raw, 0.0f);
LLVFile::writeFile(j2c->getData(), j2c->getDataSize(), gVFS, self->mImageID, LLAssetType::AT_TEXTURE);
- self->mImage = new LLImageGL((LLImageRaw*)raw, FALSE);
+ self->mImage = LLViewerTextureManager::getLocalTexture((LLImageRaw*)raw, FALSE);
gGL.getTexUnit(0)->bind(self->mImage);
self->mImage->setAddressMode(LLTexUnit::TAM_CLAMP);
}
@@ -259,7 +248,7 @@ void LLFloaterAuction::onClickOK(void* data)
self->mImage = NULL;
self->mParcelID = -1;
self->mParcelHost.invalidate();
- self->close();
+ self->closeFloater();
}
diff --git a/indra/newview/llfloaterauction.h b/indra/newview/llfloaterauction.h
index e13bce01e1..1acc08057c 100644
--- a/indra/newview/llfloaterauction.h
+++ b/indra/newview/llfloaterauction.h
@@ -36,8 +36,8 @@
#include "llfloater.h"
#include "lluuid.h"
-#include "llmemory.h"
-#include "llviewerimage.h"
+#include "llpointer.h"
+#include "llviewertexture.h"
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Class LLFloaterAuction
@@ -48,28 +48,27 @@ class LLParcelSelection;
class LLFloaterAuction : public LLFloater
{
+ friend class LLFloaterReg;
public:
// LLFloater interface
- /*virtual*/ void onClose(bool app_quitting) { setVisible(FALSE); }
+ /*virtual*/ void onOpen(const LLSD& key);
/*virtual*/ void draw();
- // LLFloaterAuction interface
- static void show();
-
private:
- LLFloaterAuction();
+
+ LLFloaterAuction(const LLSD& key);
~LLFloaterAuction();
+
void initialize();
static void onClickSnapshot(void* data);
static void onClickOK(void* data);
- static LLFloaterAuction* sInstance;
-
+ /*virtual*/ BOOL postBuild();
private:
LLTransactionID mTransactionID;
LLAssetID mImageID;
- LLPointer<LLImageGL> mImage;
+ LLPointer<LLViewerTexture> mImage;
LLSafeHandle<LLParcelSelection> mParcelp;
S32 mParcelID;
LLHost mParcelHost;
diff --git a/indra/newview/llfloateravatarpicker.cpp b/indra/newview/llfloateravatarpicker.cpp
index e382fefece..91b9bcfe72 100644
--- a/indra/newview/llfloateravatarpicker.cpp
+++ b/indra/newview/llfloateravatarpicker.cpp
@@ -33,85 +33,74 @@
#include "llfloateravatarpicker.h"
-#include "message.h"
-
+// Viewer includes
#include "llagent.h"
-#include "llbutton.h"
#include "llfocusmgr.h"
-#include "llinventoryview.h"
+#include "llfloaterreg.h"
+#include "llfloaterinventory.h"
+#include "llfoldervieweventlistener.h"
#include "llinventorymodel.h"
+#include "llviewercontrol.h"
+#include "llworld.h"
+
+// Linden libraries
+#include "llbutton.h"
#include "lllineeditor.h"
#include "llscrolllistctrl.h"
+#include "llscrolllistitem.h"
+#include "llscrolllistcell.h"
+#include "lltabcontainer.h"
#include "lltextbox.h"
#include "lluictrlfactory.h"
-#include "llviewercontrol.h"
-#include "llworld.h"
-
-const S32 MIN_WIDTH = 200;
-const S32 MIN_HEIGHT = 340;
-const LLRect FLOATER_RECT(0, 380, 240, 0);
-const std::string FLOATER_TITLE = "Choose Resident";
-
-// static
-LLFloaterAvatarPicker* LLFloaterAvatarPicker::sInstance = NULL;
-
+#include "message.h"
LLFloaterAvatarPicker* LLFloaterAvatarPicker::show(callback_t callback,
void* userdata,
BOOL allow_multiple,
BOOL closeOnSelect)
{
- // TODO: This class should not be a singleton as it's used in multiple places
- // and therefore can't be used simultaneously. -MG
- if (!sInstance)
- {
- sInstance = new LLFloaterAvatarPicker();
- sInstance->mCallback = callback;
- sInstance->mCallbackUserdata = userdata;
- sInstance->mCloseOnSelect = FALSE;
-
- sInstance->open(); /* Flawfinder: ignore */
- sInstance->center();
- sInstance->setAllowMultiple(allow_multiple);
- }
- else
- {
- sInstance->open(); /*Flawfinder: ignore*/
- sInstance->mCallback = callback;
- sInstance->mCallbackUserdata = userdata;
- sInstance->setAllowMultiple(allow_multiple);
- }
+ // *TODO: Use a key to allow this not to be an effective singleton
+ LLFloaterAvatarPicker* floater = LLFloaterReg::showTypedInstance<LLFloaterAvatarPicker>("avatar_picker");
+
+ floater->mCallback = callback;
+ floater->mCallbackUserdata = userdata;
+ floater->setAllowMultiple(allow_multiple);
+ floater->mNearMeListComplete = FALSE;
+ floater->mCloseOnSelect = closeOnSelect;
- sInstance->mNearMeListComplete = FALSE;
- sInstance->mCloseOnSelect = closeOnSelect;
- return sInstance;
+ return floater;
}
// Default constructor
-LLFloaterAvatarPicker::LLFloaterAvatarPicker() :
- LLFloater(std::string("avatarpicker"), FLOATER_RECT, FLOATER_TITLE, TRUE, MIN_WIDTH, MIN_HEIGHT),
+LLFloaterAvatarPicker::LLFloaterAvatarPicker(const LLSD& key)
+ : LLFloater(key),
mResultsReturned(FALSE),
mCallback(NULL),
- mCallbackUserdata(NULL)
+ mCallbackUserdata(NULL),
+ mNearMeListComplete(FALSE),
+ mCloseOnSelect(FALSE)
{
- LLUICtrlFactory::getInstance()->buildFloater(this, "floater_avatar_picker.xml", NULL);
+// LLUICtrlFactory::getInstance()->buildFloater(this, "floater_avatar_picker.xml");
}
BOOL LLFloaterAvatarPicker::postBuild()
{
- childSetKeystrokeCallback("Edit", editKeystroke, this);
+ getChild<LLLineEditor>("Edit")->setKeystrokeCallback(editKeystroke, this);
childSetAction("Find", onBtnFind, this);
childDisable("Find");
childSetAction("Refresh", onBtnRefresh, this);
childSetCommitCallback("near_me_range", onRangeAdjust, this);
-
- childSetDoubleClickCallback("SearchResults", onBtnSelect);
- childSetDoubleClickCallback("NearMe", onBtnSelect);
+
+ LLScrollListCtrl* searchresults = getChild<LLScrollListCtrl>("SearchResults");
+ searchresults->setDoubleClickCallback(onBtnSelect, this);
childSetCommitCallback("SearchResults", onList, this);
- childSetCommitCallback("NearMe", onList, this);
childDisable("SearchResults");
-
+
+ LLScrollListCtrl* nearme = getChild<LLScrollListCtrl>("NearMe");
+ nearme->setDoubleClickCallback(onBtnSelect, this);
+ childSetCommitCallback("NearMe", onList, this);
+
childSetAction("Select", onBtnSelect, this);
childDisable("Select");
@@ -126,41 +115,34 @@ BOOL LLFloaterAvatarPicker::postBuild()
search_panel->setDefaultBtn("Find");
}
- getChild<LLScrollListCtrl>("SearchResults")->addCommentText(getString("no_results"));
+ getChild<LLScrollListCtrl>("SearchResults")->setCommentText(getString("no_results"));
LLInventoryPanel* inventory_panel = getChild<LLInventoryPanel>("InventoryPanel");
inventory_panel->setFilterTypes(0x1 << LLInventoryType::IT_CALLINGCARD);
inventory_panel->setFollowsAll();
inventory_panel->setShowFolderState(LLInventoryFilter::SHOW_NON_EMPTY_FOLDERS);
inventory_panel->openDefaultFolderForType(LLAssetType::AT_CALLINGCARD);
- inventory_panel->setSelectCallback(LLFloaterAvatarPicker::onCallingCardSelectionChange, this);
-
- childSetTabChangeCallback("ResidentChooserTabs", "SearchPanel", onTabChanged, this);
- childSetTabChangeCallback("ResidentChooserTabs", "CallingCardsPanel", onTabChanged, this);
- childSetTabChangeCallback("ResidentChooserTabs", "NearMePanel", onTabChanged, this);
+ inventory_panel->setSelectCallback(boost::bind(&LLFloaterAvatarPicker::doCallingCardSelectionChange, this, _1, _2));
+
+ getChild<LLTabContainer>("ResidentChooserTabs")->setCommitCallback(
+ boost::bind(&LLFloaterAvatarPicker::onTabChanged, this));
setAllowMultiple(FALSE);
-
+
+ center();
+
return TRUE;
}
-void LLFloaterAvatarPicker::onTabChanged(void* userdata, bool from_click)
+void LLFloaterAvatarPicker::onTabChanged()
{
- LLFloaterAvatarPicker* self = (LLFloaterAvatarPicker*)userdata;
- if (!self)
- {
- return;
- }
-
- self->childSetEnabled("Select", self->visibleItemsSelected());
+ childSetEnabled("Select", visibleItemsSelected());
}
// Destroys the object
LLFloaterAvatarPicker::~LLFloaterAvatarPicker()
{
gFocusMgr.releaseFocusIfNeeded( this );
-
- sInstance = NULL;
}
void LLFloaterAvatarPicker::onBtnFind(void* userdata)
@@ -216,7 +198,7 @@ void LLFloaterAvatarPicker::onBtnSelect(void* userdata)
if(self->mCloseOnSelect)
{
self->mCloseOnSelect = FALSE;
- self->close();
+ self->closeFloater();
}
}
@@ -229,14 +211,14 @@ void LLFloaterAvatarPicker::onBtnRefresh(void* userdata)
}
self->getChild<LLScrollListCtrl>("NearMe")->deleteAllItems();
- self->getChild<LLScrollListCtrl>("NearMe")->addCommentText(self->getString("searching"));
+ self->getChild<LLScrollListCtrl>("NearMe")->setCommentText(self->getString("searching"));
self->mNearMeListComplete = FALSE;
}
void LLFloaterAvatarPicker::onBtnClose(void* userdata)
{
LLFloaterAvatarPicker* self = (LLFloaterAvatarPicker*)userdata;
- if(self) self->close();
+ if(self) self->closeFloater();
}
void LLFloaterAvatarPicker::onRangeAdjust(LLUICtrl* source, void* data)
@@ -253,18 +235,8 @@ void LLFloaterAvatarPicker::onList(LLUICtrl* ctrl, void* userdata)
}
}
-// static callback for inventory picker (select from calling cards)
-void LLFloaterAvatarPicker::onCallingCardSelectionChange(const std::deque<LLFolderViewItem*> &items, BOOL user_action, void* data)
-{
- LLFloaterAvatarPicker* self = (LLFloaterAvatarPicker*)data;
- if (self)
- {
- self->doCallingCardSelectionChange( items, user_action, data );
- }
-}
-
// Callback for inventory picker (select from calling cards)
-void LLFloaterAvatarPicker::doCallingCardSelectionChange(const std::deque<LLFolderViewItem*> &items, BOOL user_action, void* data)
+void LLFloaterAvatarPicker::doCallingCardSelectionChange(const std::deque<LLFolderViewItem*> &items, BOOL user_action)
{
bool panel_active = (childGetVisibleTab("ResidentChooserTabs") == getChild<LLPanel>("CallingCardsPanel"));
@@ -330,7 +302,7 @@ void LLFloaterAvatarPicker::populateNearMe()
{
childDisable("NearMe");
childDisable("Select");
- near_me_scroller->addCommentText(getString("no_one_near"));
+ near_me_scroller->setCommentText(getString("no_one_near"));
}
else
{
@@ -394,7 +366,7 @@ void LLFloaterAvatarPicker::find()
gAgent.sendReliableMessage();
getChild<LLScrollListCtrl>("SearchResults")->deleteAllItems();
- getChild<LLScrollListCtrl>("SearchResults")->addCommentText(getString("searching"));
+ getChild<LLScrollListCtrl>("SearchResults")->setCommentText(getString("searching"));
childSetEnabled("Select", FALSE);
mResultsReturned = FALSE;
@@ -421,23 +393,21 @@ void LLFloaterAvatarPicker::processAvatarPickerReply(LLMessageSystem* msg, void*
// Not for us
if (agent_id != gAgent.getID()) return;
-
- // Dialog already closed
- LLFloaterAvatarPicker *self = sInstance;
- if (!self) return;
+
+ LLFloaterAvatarPicker* floater = LLFloaterReg::findTypedInstance<LLFloaterAvatarPicker>("avatar_picker");
// these are not results from our last request
- if (query_id != self->mQueryID)
+ if (query_id != floater->mQueryID)
{
return;
}
- LLScrollListCtrl* search_results = self->getChild<LLScrollListCtrl>("SearchResults");
+ LLScrollListCtrl* search_results = floater->getChild<LLScrollListCtrl>("SearchResults");
// clear "Searching" label on first results
search_results->deleteAllItems();
- self->mResultsReturned = TRUE;
+ floater->mResultsReturned = TRUE;
BOOL found_one = FALSE;
S32 num_new_rows = msg->getNumberOfBlocks("Data");
@@ -451,10 +421,10 @@ void LLFloaterAvatarPicker::processAvatarPickerReply(LLMessageSystem* msg, void*
if (avatar_id.isNull())
{
LLStringUtil::format_map_t map;
- map["[TEXT]"] = self->childGetText("Edit");
- avatar_name = self->getString("not_found", map);
+ map["[TEXT]"] = floater->childGetText("Edit");
+ avatar_name = floater->getString("not_found", map);
search_results->setEnabled(FALSE);
- self->childDisable("Select");
+ floater->childDisable("Select");
}
else
{
@@ -470,9 +440,9 @@ void LLFloaterAvatarPicker::processAvatarPickerReply(LLMessageSystem* msg, void*
if (found_one)
{
- self->childEnable("Select");
+ floater->childEnable("Select");
search_results->selectFirstItem();
- self->onList(search_results, self);
+ floater->onList(search_results, floater);
search_results->setFocus(TRUE);
}
}
@@ -501,7 +471,7 @@ BOOL LLFloaterAvatarPicker::handleKeyHere(KEY key, MASK mask)
}
else if (key == KEY_ESCAPE && mask == MASK_NONE)
{
- close();
+ closeFloater();
return TRUE;
}
diff --git a/indra/newview/llfloateravatarpicker.h b/indra/newview/llfloateravatarpicker.h
index 56bc387bce..63896bef9f 100644
--- a/indra/newview/llfloateravatarpicker.h
+++ b/indra/newview/llfloateravatarpicker.h
@@ -48,6 +48,10 @@ public:
void* userdata,
BOOL allow_multiple = FALSE,
BOOL closeOnSelect = FALSE);
+
+ LLFloaterAvatarPicker(const LLSD& key);
+ virtual ~LLFloaterAvatarPicker();
+
virtual BOOL postBuild();
static void processAvatarPickerReply(class LLMessageSystem* msg, void**);
@@ -62,10 +66,9 @@ private:
static void onRangeAdjust(LLUICtrl* source, void* data);
static void onBtnClose(void* userdata);
static void onList(class LLUICtrl* ctrl, void* userdata);
- static void onTabChanged(void* userdata, bool from_click);
+ void onTabChanged();
- void doCallingCardSelectionChange(const std::deque<class LLFolderViewItem*> &items, BOOL user_action, void* data);
- static void onCallingCardSelectionChange(const std::deque<class LLFolderViewItem*> &items, BOOL user_action, void* data);
+ void doCallingCardSelectionChange(const std::deque<class LLFolderViewItem*> &items, BOOL user_action);
void populateNearMe();
BOOL visibleItemsSelected() const; // Returns true if any items in the current tab are selected.
@@ -85,12 +88,6 @@ private:
void (*mCallback)(const std::vector<std::string>& name, const std::vector<LLUUID>& id, void* userdata);
void* mCallbackUserdata;
-
- static LLFloaterAvatarPicker* sInstance;
-
- // do not call these directly
- LLFloaterAvatarPicker();
- virtual ~LLFloaterAvatarPicker();
};
#endif
diff --git a/indra/newview/llfloateravatartextures.cpp b/indra/newview/llfloateravatartextures.cpp
index e81b5d7fce..3976e25ba4 100644
--- a/indra/newview/llfloateravatartextures.cpp
+++ b/indra/newview/llfloateravatartextures.cpp
@@ -42,32 +42,17 @@
using namespace LLVOAvatarDefines;
-LLFloaterAvatarTextures::LLFloaterAvatarTextures(const LLUUID& id) :
- LLFloater(std::string("avatar_texture_debug")),
- mID(id)
+LLFloaterAvatarTextures::LLFloaterAvatarTextures(const LLSD& id)
+ : LLFloater(id),
+ mID(id.asUUID())
{
+// LLUICtrlFactory::getInstance()->buildFloater(this, "floater_avatar_textures.xml");
}
LLFloaterAvatarTextures::~LLFloaterAvatarTextures()
{
}
-LLFloaterAvatarTextures* LLFloaterAvatarTextures::show(const LLUUID &id)
-{
-
- LLFloaterAvatarTextures* floaterp = new LLFloaterAvatarTextures(id);
-
- // Builds and adds to gFloaterView
- LLUICtrlFactory::getInstance()->buildFloater(floaterp, "floater_avatar_textures.xml");
-
- gFloaterView->addChild(floaterp);
- floaterp->open(); /*Flawfinder: ignore*/
-
- gFloaterView->adjustToFitScreen(floaterp, FALSE);
-
- return floaterp;
-}
-
BOOL LLFloaterAvatarTextures::postBuild()
{
for (U32 i=0; i < TEX_NUM_INDICES; i++)
@@ -142,7 +127,7 @@ void LLFloaterAvatarTextures::refresh()
}
else
{
- setTitle(mTitle + ": INVALID AVATAR (" + mID.asString() + ")");
+ setTitle(mTitle + ": " + getString("InvalidAvatar") + " (" + mID.asString() + ")");
}
}
diff --git a/indra/newview/llfloateravatartextures.h b/indra/newview/llfloateravatartextures.h
index 4138edeb4d..e27484d26f 100644
--- a/indra/newview/llfloateravatartextures.h
+++ b/indra/newview/llfloateravatartextures.h
@@ -43,7 +43,7 @@ class LLTextureCtrl;
class LLFloaterAvatarTextures : public LLFloater
{
public:
- LLFloaterAvatarTextures(const LLUUID& id);
+ LLFloaterAvatarTextures(const LLSD& id);
virtual ~LLFloaterAvatarTextures();
/*virtual*/ BOOL postBuild();
@@ -51,8 +51,6 @@ public:
void refresh();
- static LLFloaterAvatarTextures* show(const LLUUID& id);
-
private:
static void onClickDump(void*);
diff --git a/indra/newview/llfloaterbeacons.cpp b/indra/newview/llfloaterbeacons.cpp
index 5476b35dc8..13a7888f60 100644
--- a/indra/newview/llfloaterbeacons.cpp
+++ b/indra/newview/llfloaterbeacons.cpp
@@ -40,8 +40,9 @@
LLFloaterBeacons::LLFloaterBeacons(const LLSD& seed)
+: LLFloater(seed)
{
- LLUICtrlFactory::getInstance()->buildFloater(this, "floater_beacons.xml");
+// LLUICtrlFactory::getInstance()->buildFloater(this, "floater_beacons.xml");
// Initialize pipeline states from saved settings.
// OK to do at floater constructor time because beacons do not display unless the floater is open
@@ -55,44 +56,21 @@ LLFloaterBeacons::LLFloaterBeacons(const LLSD& seed)
LLPipeline::setRenderParticleBeacons( gSavedSettings.getBOOL("particlesbeacon"));
LLPipeline::setRenderHighlights( gSavedSettings.getBOOL("renderhighlights"));
LLPipeline::setRenderBeacons( gSavedSettings.getBOOL("renderbeacons"));
+ mCommitCallbackRegistrar.add("Beacons.UICheck", boost::bind(&LLFloaterBeacons::onClickUICheck, this,_1));
}
BOOL LLFloaterBeacons::postBuild()
{
- childSetCommitCallback("touch_only", onClickUICheck, this);
- childSetCommitCallback("scripted", onClickUICheck, this);
- childSetCommitCallback("physical", onClickUICheck, this);
- childSetCommitCallback("sounds", onClickUICheck, this);
- childSetCommitCallback("particles", onClickUICheck, this);
- childSetCommitCallback("highlights", onClickUICheck, this);
- childSetCommitCallback("beacons", onClickUICheck, this);
return TRUE;
}
-// Needed to make the floater visibility toggle the beacons.
-// Too bad we can't just add control_name="BeaconAlwaysOn" to the XML.
-void LLFloaterBeacons::open()
-{
- LLFloater::open();
- gSavedSettings.setBOOL( "BeaconAlwaysOn", TRUE);
-}
-void LLFloaterBeacons::close(bool app_quitting)
-{
- LLFloater::close(app_quitting);
- if(!app_quitting)
- {
- gSavedSettings.setBOOL( "BeaconAlwaysOn", FALSE);
- }
-}
-
// Callback attached to each check box control to both affect their main purpose
// and to implement the couple screwy interdependency rules that some have.
-//static
-void LLFloaterBeacons::onClickUICheck(LLUICtrl *ctrl, void* data)
+
+void LLFloaterBeacons::onClickUICheck(LLUICtrl *ctrl)
{
LLCheckBoxCtrl *check = (LLCheckBoxCtrl *)ctrl;
std::string name = check->getName();
- LLFloaterBeacons* view = (LLFloaterBeacons*)data;
if( name == "touch_only")
{
LLPipeline::toggleRenderScriptedTouchBeacons(NULL);
@@ -102,8 +80,8 @@ void LLFloaterBeacons::onClickUICheck(LLUICtrl *ctrl, void* data)
LLPipeline::getRenderScriptedBeacons(NULL) )
{
LLPipeline::setRenderScriptedBeacons(FALSE);
- view->getChild<LLCheckBoxCtrl>("scripted")->setControlValue(LLSD(FALSE));
- view->getChild<LLCheckBoxCtrl>("touch_only")->setControlValue(LLSD(TRUE)); // just to be sure it's in sync with llpipeline
+ getChild<LLCheckBoxCtrl>("scripted")->setControlValue(LLSD(FALSE));
+ getChild<LLCheckBoxCtrl>("touch_only")->setControlValue(LLSD(TRUE)); // just to be sure it's in sync with llpipeline
}
}
else if(name == "scripted")
@@ -115,8 +93,8 @@ void LLFloaterBeacons::onClickUICheck(LLUICtrl *ctrl, void* data)
LLPipeline::getRenderScriptedBeacons(NULL) )
{
LLPipeline::setRenderScriptedTouchBeacons(FALSE);
- view->getChild<LLCheckBoxCtrl>("touch_only")->setControlValue(LLSD(FALSE));
- view->getChild<LLCheckBoxCtrl>("scripted")->setControlValue(LLSD(TRUE)); // just to be sure it's in sync with llpipeline
+ getChild<LLCheckBoxCtrl>("touch_only")->setControlValue(LLSD(FALSE));
+ getChild<LLCheckBoxCtrl>("scripted")->setControlValue(LLSD(TRUE)); // just to be sure it's in sync with llpipeline
}
}
else if(name == "physical") LLPipeline::setRenderPhysicalBeacons(check->get());
@@ -131,8 +109,8 @@ void LLFloaterBeacons::onClickUICheck(LLUICtrl *ctrl, void* data)
!LLPipeline::getRenderHighlights(NULL) )
{
LLPipeline::setRenderBeacons(TRUE);
- view->getChild<LLCheckBoxCtrl>("beacons")->setControlValue(LLSD(TRUE));
- view->getChild<LLCheckBoxCtrl>("highlights")->setControlValue(LLSD(FALSE)); // just to be sure it's in sync with llpipeline
+ getChild<LLCheckBoxCtrl>("beacons")->setControlValue(LLSD(TRUE));
+ getChild<LLCheckBoxCtrl>("highlights")->setControlValue(LLSD(FALSE)); // just to be sure it's in sync with llpipeline
}
}
else if(name == "beacons")
@@ -144,8 +122,8 @@ void LLFloaterBeacons::onClickUICheck(LLUICtrl *ctrl, void* data)
!LLPipeline::getRenderHighlights(NULL) )
{
LLPipeline::setRenderHighlights(TRUE);
- view->getChild<LLCheckBoxCtrl>("highlights")->setControlValue(LLSD(TRUE));
- view->getChild<LLCheckBoxCtrl>("beacons")->setControlValue(LLSD(FALSE)); // just to be sure it's in sync with llpipeline
+ getChild<LLCheckBoxCtrl>("highlights")->setControlValue(LLSD(TRUE));
+ getChild<LLCheckBoxCtrl>("beacons")->setControlValue(LLSD(FALSE)); // just to be sure it's in sync with llpipeline
}
}
}
diff --git a/indra/newview/llfloaterbeacons.h b/indra/newview/llfloaterbeacons.h
index c12bdd7261..c175cb3ef4 100644
--- a/indra/newview/llfloaterbeacons.h
+++ b/indra/newview/llfloaterbeacons.h
@@ -36,22 +36,20 @@
#include "llfloater.h"
-class LLFloaterBeacons : public LLFloater, public LLFloaterSingleton<LLFloaterBeacons>
+class LLFloaterBeacons : public LLFloater
{
- friend class LLUISingleton<LLFloaterBeacons, VisibilityPolicy<LLFloater> >;
+ friend class LLFloaterReg;
public:
+
/*virtual*/ BOOL postBuild();
// Needed to make the floater visibility toggle the beacons.
// Too bad we can't just add control_name="BeaconAlwaysOn" to the XML.
- /*virtual*/ void open();
- /*virtual*/ void close(bool app_quitting);
+ void onClickUICheck(LLUICtrl *ctrl);
private:
LLFloaterBeacons(const LLSD& seed);
-
- static void onClickUICheck(LLUICtrl *ctrl, void* data);
};
#endif
diff --git a/indra/newview/llfloaterbuildoptions.cpp b/indra/newview/llfloaterbuildoptions.cpp
index 3cd35db19c..30e9428df9 100644
--- a/indra/newview/llfloaterbuildoptions.cpp
+++ b/indra/newview/llfloaterbuildoptions.cpp
@@ -40,58 +40,16 @@
#include "llfloaterbuildoptions.h"
#include "lluictrlfactory.h"
-// library includes
-#include "llfontgl.h"
-#include "llcheckboxctrl.h"
-#include "llspinctrl.h"
-#include "llsliderctrl.h"
-
-// newview includes
-#include "llresmgr.h"
-#include "llviewercontrol.h"
-
-//
-// Globals
-//
-LLFloaterBuildOptions *LLFloaterBuildOptions::sInstance = NULL;
-
//
// Methods
//
-LLFloaterBuildOptions::LLFloaterBuildOptions( )
-: LLFloater(std::string("build options floater"))
+LLFloaterBuildOptions::LLFloaterBuildOptions(const LLSD& key)
+ : LLFloater(key)
{
- sInstance = this;
+ //LLUICtrlFactory::getInstance()->buildFloater(this, "floater_build_options.xml");
}
LLFloaterBuildOptions::~LLFloaterBuildOptions()
{
- sInstance = NULL;
-}
-
-// static
-void LLFloaterBuildOptions::show(void*)
-{
- if (sInstance)
- {
- sInstance->open(); /*Flawfinder: ignore*/
- }
- else
- {
- LLFloaterBuildOptions* floater = new LLFloaterBuildOptions();
-
- LLUICtrlFactory::getInstance()->buildFloater(floater, "floater_build_options.xml");
- floater->open(); /*Flawfinder: ignore*/
- }
}
-LLFloaterBuildOptions* LLFloaterBuildOptions::getInstance()
-{
- return sInstance;
-}
-
-// static
-BOOL LLFloaterBuildOptions::visible(void*)
-{
- return (sInstance != NULL);
-}
diff --git a/indra/newview/llfloaterbuildoptions.h b/indra/newview/llfloaterbuildoptions.h
index e030b063d9..43cbb201c2 100644
--- a/indra/newview/llfloaterbuildoptions.h
+++ b/indra/newview/llfloaterbuildoptions.h
@@ -42,19 +42,12 @@
class LLFloaterBuildOptions
-: public LLFloater
+ : public LLFloater
{
-protected:
- LLFloaterBuildOptions();
+ friend class LLFloaterReg;
+private:
+ LLFloaterBuildOptions(const LLSD& key);
~LLFloaterBuildOptions();
-
-public:
- static void show(void*);
- static LLFloaterBuildOptions* getInstance();
- static BOOL visible(void*);
-
-protected:
- static LLFloaterBuildOptions* sInstance;
};
#endif
diff --git a/indra/newview/llfloaterbulkpermission.cpp b/indra/newview/llfloaterbulkpermission.cpp
index d4e1e98125..a73ebf4e06 100644
--- a/indra/newview/llfloaterbulkpermission.cpp
+++ b/indra/newview/llfloaterbulkpermission.cpp
@@ -52,21 +52,29 @@
#include "llviewerstats.h"
#include "lluictrlfactory.h"
#include "llselectmgr.h"
+#include "llcheckboxctrl.h"
#include "roles_constants.h" // for GP_OBJECT_MANIPULATE
-LLFloaterBulkPermission::LLFloaterBulkPermission(const LLSD& seed) : mDone(FALSE)
+LLFloaterBulkPermission::LLFloaterBulkPermission(const LLSD& seed)
+: LLFloater(seed),
+ mDone(FALSE)
{
mID.generate();
- LLUICtrlFactory::getInstance()->buildFloater(this,"floater_bulk_perms.xml");
- childSetEnabled("next_owner_transfer", gSavedSettings.getBOOL("BulkChangeNextOwnerCopy"));
- childSetAction("help", onHelpBtn, this);
- childSetAction("apply", onApplyBtn, this);
- childSetAction("close", onCloseBtn, this);
- childSetAction("check_all", onCheckAll, this);
- childSetAction("check_none", onUncheckAll, this);
- childSetCommitCallback("next_owner_copy", &onCommitCopy, this);
+// LLUICtrlFactory::getInstance()->buildFloater(this,"floater_bulk_perms.xml");
+ mCommitCallbackRegistrar.add("BulkPermission.Apply", boost::bind(&LLFloaterBulkPermission::onApplyBtn, this));
+ mCommitCallbackRegistrar.add("BulkPermission.Close", boost::bind(&LLFloaterBulkPermission::onCloseBtn, this));
+ mCommitCallbackRegistrar.add("BulkPermission.CheckAll", boost::bind(&LLFloaterBulkPermission::onCheckAll, this));
+ mCommitCallbackRegistrar.add("BulkPermission.UncheckAll", boost::bind(&LLFloaterBulkPermission::onUncheckAll, this));
+ mCommitCallbackRegistrar.add("BulkPermission.CommitCopy", boost::bind(&LLFloaterBulkPermission::onCommitCopy, this));
+}
+
+BOOL LLFloaterBulkPermission::postBuild()
+{
+// childSetAction("help", onHelpBtn, this); // this is not in use
+
+ return TRUE;
}
void LLFloaterBulkPermission::doApply()
@@ -93,7 +101,7 @@ void LLFloaterBulkPermission::doApply()
LLSelectMgr::getInstance()->getSelection()->applyToNodes(&gatherer);
if(mObjectIDs.empty())
{
- list->addCommentText(getString("nothing_to_modify_text"));
+ list->setCommentText(getString("nothing_to_modify_text"));
}
else
{
@@ -144,41 +152,39 @@ void LLFloaterBulkPermission::inventoryChanged(LLViewerObject* viewer_object,
}
}
-void LLFloaterBulkPermission::onApplyBtn(void* user_data)
+void LLFloaterBulkPermission::onApplyBtn()
{
- LLFloaterBulkPermission* self = static_cast<LLFloaterBulkPermission*>(user_data);
- self->doApply();
+ doApply();
}
-void LLFloaterBulkPermission::onHelpBtn(void* user_data)
-{
- LLNotifications::instance().add("HelpBulkPermission");
-}
+// angela -- this is not in use
+//void LLFloaterBulkPermission::onHelpBtn(void* user_data)
+//{
+// LLNotifications::instance().add("HelpBulkPermission");
+//}
-void LLFloaterBulkPermission::onCloseBtn(void* user_data)
+void LLFloaterBulkPermission::onCloseBtn()
{
- LLFloaterBulkPermission* self = static_cast<LLFloaterBulkPermission*>(user_data);
- self->onClose(false);
+ closeFloater();
}
//static
-void LLFloaterBulkPermission::onCommitCopy(LLUICtrl* ctrl, void* data)
+void LLFloaterBulkPermission::onCommitCopy()
{
- LLFloaterBulkPermission* self = static_cast<LLFloaterBulkPermission*>(data);
// Implements fair use
BOOL copyable = gSavedSettings.getBOOL("BulkChangeNextOwnerCopy");
if(!copyable)
{
gSavedSettings.setBOOL("BulkChangeNextOwnerTransfer", TRUE);
}
- LLCheckBoxCtrl* xfer = self->getChild<LLCheckBoxCtrl>("next_owner_transfer");
+ LLCheckBoxCtrl* xfer =getChild<LLCheckBoxCtrl>("next_owner_transfer");
xfer->setEnabled(copyable);
}
BOOL LLFloaterBulkPermission::start()
{
// note: number of top-level objects to modify is mObjectIDs.count().
- getChild<LLScrollListCtrl>("queue output")->addCommentText(getString("start_text"));
+ getChild<LLScrollListCtrl>("queue output")->setCommentText(getString("start_text"));
return nextObject();
}
@@ -201,7 +207,7 @@ BOOL LLFloaterBulkPermission::nextObject()
if(isDone() && !mDone)
{
- getChild<LLScrollListCtrl>("queue output")->addCommentText(getString("done_text"));
+ getChild<LLScrollListCtrl>("queue output")->setCommentText(getString("done_text"));
mDone = TRUE;
}
return successful_start;
@@ -244,7 +250,6 @@ void LLFloaterBulkPermission::doCheckUncheckAll(BOOL check)
gSavedSettings.setBOOL("BulkChangeIncludeBodyParts" , check);
gSavedSettings.setBOOL("BulkChangeIncludeClothing" , check);
gSavedSettings.setBOOL("BulkChangeIncludeGestures" , check);
- gSavedSettings.setBOOL("BulkChangeIncludeLandmarks" , check);
gSavedSettings.setBOOL("BulkChangeIncludeNotecards" , check);
gSavedSettings.setBOOL("BulkChangeIncludeObjects" , check);
gSavedSettings.setBOOL("BulkChangeIncludeScripts" , check);
@@ -267,7 +272,7 @@ void LLFloaterBulkPermission::handleInventory(LLViewerObject* viewer_obj, Invent
( asstype == LLAssetType::AT_BODYPART && gSavedSettings.getBOOL("BulkChangeIncludeBodyParts" )) ||
( asstype == LLAssetType::AT_CLOTHING && gSavedSettings.getBOOL("BulkChangeIncludeClothing" )) ||
( asstype == LLAssetType::AT_GESTURE && gSavedSettings.getBOOL("BulkChangeIncludeGestures" )) ||
- ( asstype == LLAssetType::AT_LANDMARK && gSavedSettings.getBOOL("BulkChangeIncludeLandmarks" )) ||
+ ( asstype == LLAssetType::AT_FAVORITE && gSavedSettings.getBOOL("BulkChangeIncludeFavourite" )) ||
( asstype == LLAssetType::AT_NOTECARD && gSavedSettings.getBOOL("BulkChangeIncludeNotecards" )) ||
( asstype == LLAssetType::AT_OBJECT && gSavedSettings.getBOOL("BulkChangeIncludeObjects" )) ||
( asstype == LLAssetType::AT_LSL_TEXT && gSavedSettings.getBOOL("BulkChangeIncludeScripts" )) ||
@@ -317,7 +322,7 @@ void LLFloaterBulkPermission::handleInventory(LLViewerObject* viewer_obj, Invent
status_text.setArg("[STATUS]", "");
}
- list->addCommentText(status_text.getString());
+ list->setCommentText(status_text.getString());
//TODO if we are an object inside an object we should check a recuse flag and if set
//open the inventory of the object and recurse - Michelle2 Zenovka
diff --git a/indra/newview/llfloaterbulkpermission.h b/indra/newview/llfloaterbulkpermission.h
index a26b5b4f79..c34e4413cc 100644
--- a/indra/newview/llfloaterbulkpermission.h
+++ b/indra/newview/llfloaterbulkpermission.h
@@ -46,13 +46,16 @@
#include "llviewerinventory.h"
-class LLFloaterBulkPermission : public LLFloater, public LLVOInventoryListener, public LLFloaterSingleton<LLFloaterBulkPermission>
+class LLFloaterBulkPermission : public LLFloater, public LLVOInventoryListener
{
+ friend class LLFloaterReg;
public:
- LLFloaterBulkPermission(const LLSD& seed);
+ BOOL postBuild();
private:
+
+ LLFloaterBulkPermission(const LLSD& seed);
virtual ~LLFloaterBulkPermission() {}
BOOL start(); // returns TRUE if the queue has started, otherwise FALSE.
@@ -76,12 +79,12 @@ private:
U8 key,
bool is_new);
- static void onHelpBtn(void* user_data);
- static void onCloseBtn(void* user_data);
- static void onApplyBtn(void* user_data);
- static void onCommitCopy(LLUICtrl* ctrl, void* data);
- static void onCheckAll( void* user_data) { ((LLFloaterBulkPermission*)user_data)->doCheckUncheckAll(TRUE); }
- static void onUncheckAll(void* user_data) { ((LLFloaterBulkPermission*)user_data)->doCheckUncheckAll(FALSE); }
+// static void onHelpBtn(void* user_data);
+ void onCloseBtn();
+ void onApplyBtn();
+ void onCommitCopy();
+ void onCheckAll() { doCheckUncheckAll(TRUE); }
+ void onUncheckAll() { doCheckUncheckAll(FALSE); }
// returns true if this is done
BOOL isDone() const { return (mCurrentObjectID.isNull() || (mObjectIDs.count() == 0)); }
diff --git a/indra/newview/llfloaterbump.cpp b/indra/newview/llfloaterbump.cpp
index 96e51c2fa2..8b64f913e0 100644
--- a/indra/newview/llfloaterbump.cpp
+++ b/indra/newview/llfloaterbump.cpp
@@ -37,55 +37,41 @@
#include "llscrolllistctrl.h"
+#include "llsd.h"
#include "lluictrlfactory.h"
#include "llviewermessage.h"
#include "llappviewer.h" // gPacificDaylightTime
///----------------------------------------------------------------------------
-/// Local function declarations, constants, enums, and typedefs
-///----------------------------------------------------------------------------
-LLFloaterBump* LLFloaterBump::sInstance = NULL;
-
-///----------------------------------------------------------------------------
/// Class LLFloaterBump
///----------------------------------------------------------------------------
+extern BOOL gNoRender;
// Default constructor
-LLFloaterBump::LLFloaterBump()
-: LLFloater()
+LLFloaterBump::LLFloaterBump(const LLSD& key)
+: LLFloater(key)
{
- sInstance = this;
-
- LLUICtrlFactory::getInstance()->buildFloater(this, "floater_bumps.xml");
+ if(gNoRender) return;
+ //LLUICtrlFactory::getInstance()->buildFloater(this, "floater_bumps.xml");
}
// Destroys the object
LLFloaterBump::~LLFloaterBump()
{
- sInstance = NULL;
}
-// static
-void LLFloaterBump::show(void *contents)
+// virtual
+void LLFloaterBump::onOpen(const LLSD& key)
{
- if (gNoRender)
- {
+ LLScrollListCtrl* list = getChild<LLScrollListCtrl>("bump_list");
+ if (!list)
return;
- }
-
- if (!sInstance)
- {
- sInstance = new LLFloaterBump();
- }
-
- LLScrollListCtrl* list = sInstance->getChild<LLScrollListCtrl>("bump_list");
- if (!list) return;
list->deleteAllItems();
if (gMeanCollisionList.empty())
{
- std::string none_detected = sInstance->getString("none_detected");
+ std::string none_detected = getString("none_detected");
LLSD row;
row["columns"][0]["value"] = none_detected;
row["columns"][0]["font"] = "SansSerifBold";
@@ -97,33 +83,23 @@ void LLFloaterBump::show(void *contents)
iter != gMeanCollisionList.end(); ++iter)
{
LLMeanCollisionData *mcd = *iter;
- LLFloaterBump::add(list, mcd);
+ add(list, mcd);
}
}
-
- sInstance->open(); /*Flawfinder: ignore*/
}
void LLFloaterBump::add(LLScrollListCtrl* list, LLMeanCollisionData* mcd)
{
- if (!sInstance)
- {
- new LLFloaterBump();
- }
-
if (mcd->mFirstName.empty() || list->getItemCount() >= 20)
{
return;
}
- // There's only one internal tm buffer.
- struct tm* timep;
-
- // Convert to Pacific, based on server's opinion of whether
- // it's daylight savings time there.
- timep = utc_to_pacific_time(mcd->mTime, gPacificDaylightTime);
-
- std::string time = llformat("[%d:%02d]", timep->tm_hour, timep->tm_min);
+ std::string timeStr = getString ("timeStr");
+ LLSD substitution;
+
+ substitution["datetime"] = (S32) mcd->mTime;
+ LLStringUtil::format (timeStr, substitution);
std::string action;
switch(mcd->mType)
@@ -150,8 +126,8 @@ void LLFloaterBump::add(LLScrollListCtrl* list, LLMeanCollisionData* mcd)
}
// All above action strings are in XML file
- LLUIString text = sInstance->getString(action);
- text.setArg("[TIME]", time);
+ LLUIString text = getString(action);
+ text.setArg("[TIME]", timeStr);
text.setArg("[FIRST]", mcd->mFirstName);
text.setArg("[LAST]", mcd->mLastName);
diff --git a/indra/newview/llfloaterbump.h b/indra/newview/llfloaterbump.h
index eb15671d41..1f2cb6d6ab 100644
--- a/indra/newview/llfloaterbump.h
+++ b/indra/newview/llfloaterbump.h
@@ -42,16 +42,17 @@ class LLScrollListCtrl;
class LLFloaterBump
: public LLFloater
{
-public:
- static void show(void *);
+ friend class LLFloaterReg;
+protected:
+ void add(LLScrollListCtrl* list, LLMeanCollisionData *mcd);
-private:
- LLFloaterBump();
- virtual ~LLFloaterBump();
- static void add(LLScrollListCtrl* list, LLMeanCollisionData *mcd);
+public:
+ /*virtual*/ void onOpen(const LLSD& key);
private:
- static LLFloaterBump* sInstance;
+
+ LLFloaterBump(const LLSD& key);
+ virtual ~LLFloaterBump();
};
#endif
diff --git a/indra/newview/llfloaterbuy.cpp b/indra/newview/llfloaterbuy.cpp
index a33cabc749..a7aaf71ef6 100644
--- a/indra/newview/llfloaterbuy.cpp
+++ b/indra/newview/llfloaterbuy.cpp
@@ -43,32 +43,43 @@
#include "llagent.h" // for agent id
#include "llalertdialog.h"
#include "llinventorymodel.h" // for gInventory
-#include "llinventoryview.h" // for get_item_icon
+#include "llfloaterreg.h"
+#include "llfloaterinventory.h" // for get_item_icon
#include "llselectmgr.h"
#include "llscrolllistctrl.h"
#include "llviewerobject.h"
#include "lluictrlfactory.h"
#include "llviewerwindow.h"
+#include "lltrans.h"
-LLFloaterBuy* LLFloaterBuy::sInstance = NULL;
-
-LLFloaterBuy::LLFloaterBuy()
-: LLFloater(std::string("floater_buy_object"), std::string("FloaterBuyRect"), LLStringUtil::null)
+LLFloaterBuy::LLFloaterBuy(const LLSD& key)
+: LLFloater(key)
{
- LLUICtrlFactory::getInstance()->buildFloater(this, "floater_buy_object.xml");
+// LLUICtrlFactory::getInstance()->buildFloater(this, "floater_buy_object.xml");
+}
+BOOL LLFloaterBuy::postBuild()
+{
childDisable("object_list");
childDisable("item_list");
- childSetAction("cancel_btn", onClickCancel, this);
- childSetAction("buy_btn", onClickBuy, this);
+ getChild<LLUICtrl>("cancel_btn")->setCommitCallback( boost::bind(&LLFloaterBuy::onClickCancel, this));
+ getChild<LLUICtrl>("buy_btn")->setCommitCallback( boost::bind(&LLFloaterBuy::onClickBuy, this));
setDefaultBtn("cancel_btn"); // to avoid accidental buy (SL-43130)
+
+ // Always center the dialog. User can change the size,
+ // but purchases are important and should be center screen.
+ // This also avoids problems where the user resizes the application window
+ // mid-session and the saved rect is off-center.
+ center();
+
+ return TRUE;
}
LLFloaterBuy::~LLFloaterBuy()
{
- sInstance = NULL;
+ mObjectSelection = NULL;
}
void LLFloaterBuy::reset()
@@ -90,47 +101,34 @@ void LLFloaterBuy::show(const LLSaleInfo& sale_info)
LLNotifications::instance().add("BuyOneObjectOnly");
return;
}
-
- // Create a new instance only if one doesn't exist
- if (sInstance)
- {
- // Clean up the lists...
- sInstance->reset();
- }
- else
- {
- sInstance = new LLFloaterBuy();
- }
- sInstance->open(); /*Flawfinder: ignore*/
- sInstance->setFocus(TRUE);
- sInstance->mSaleInfo = sale_info;
- sInstance->mObjectSelection = LLSelectMgr::getInstance()->getEditSelection();
-
- // Always center the dialog. User can change the size,
- // but purchases are important and should be center screen.
- // This also avoids problems where the user resizes the application window
- // mid-session and the saved rect is off-center.
- sInstance->center();
-
+ LLFloaterBuy* floater = LLFloaterReg::showTypedInstance<LLFloaterBuy>("buy_object");
+ if (!floater)
+ return;
+
+ // Clean up the lists...
+ floater->reset();
+ floater->mSaleInfo = sale_info;
+ floater->mObjectSelection = LLSelectMgr::getInstance()->getEditSelection();
+
LLSelectNode* node = selection->getFirstRootNode();
if (!node)
return;
-
+
// Set title based on sale type
LLUIString title;
switch (sale_info.getSaleType())
{
case LLSaleInfo::FS_ORIGINAL:
- title = sInstance->getString("title_buy_text");
+ title = floater->getString("title_buy_text");
break;
case LLSaleInfo::FS_COPY:
default:
- title = sInstance->getString("title_buy_copy_text");
+ title = floater->getString("title_buy_copy_text");
break;
}
title.setArg("[NAME]", node->mName);
- sInstance->setTitle(title);
+ floater->setTitle(title);
LLUUID owner_id;
std::string owner_name;
@@ -141,7 +139,7 @@ void LLFloaterBuy::show(const LLSaleInfo& sale_info)
return;
}
- LLCtrlListInterface *object_list = sInstance->childGetListInterface("object_list");
+ LLCtrlListInterface *object_list = floater->childGetListInterface("object_list");
if (!object_list)
{
return;
@@ -166,15 +164,15 @@ void LLFloaterBuy::show(const LLSaleInfo& sale_info)
std::string text = node->mName;
if (!(next_owner_mask & PERM_COPY))
{
- text.append(sInstance->getString("no_copy_text"));
+ text.append(floater->getString("no_copy_text"));
}
if (!(next_owner_mask & PERM_MODIFY))
{
- text.append(sInstance->getString("no_modify_text"));
+ text.append(floater->getString("no_modify_text"));
}
if (!(next_owner_mask & PERM_TRANSFER))
{
- text.append(sInstance->getString("no_transfer_text"));
+ text.append(floater->getString("no_transfer_text"));
}
row["columns"][1]["column"] = "text";
@@ -184,15 +182,15 @@ void LLFloaterBuy::show(const LLSaleInfo& sale_info)
// Add after columns added so appropriate heights are correct.
object_list->addElement(row);
- sInstance->childSetTextArg("buy_text", "[AMOUNT]", llformat("%d", sale_info.getSalePrice()));
- sInstance->childSetTextArg("buy_text", "[NAME]", owner_name);
+ floater->childSetTextArg("buy_text", "[AMOUNT]", llformat("%d", sale_info.getSalePrice()));
+ floater->childSetTextArg("buy_text", "[NAME]", owner_name);
// Must do this after the floater is created, because
// sometimes the inventory is already there and
// the callback is called immediately.
LLViewerObject* obj = selection->getFirstRootObject();
- sInstance->registerVOInventoryListener(obj,NULL);
- sInstance->requestVOInventory();
+ floater->registerVOInventoryListener(obj,NULL);
+ floater->requestVOInventory();
}
void LLFloaterBuy::inventoryChanged(LLViewerObject* obj,
@@ -270,15 +268,15 @@ void LLFloaterBuy::inventoryChanged(LLViewerObject* obj,
std::string text = obj->getName();
if (!(next_owner_mask & PERM_COPY))
{
- text.append(" (no copy)");
+ text.append(LLTrans::getString("no_copy"));
}
if (!(next_owner_mask & PERM_MODIFY))
{
- text.append(" (no modify)");
+ text.append(LLTrans::getString("no_modify"));
}
if (!(next_owner_mask & PERM_TRANSFER))
{
- text.append(" (no transfer)");
+ text.append(LLTrans::getString("no_transfer"));
}
row["columns"][1]["column"] = "text";
@@ -290,16 +288,8 @@ void LLFloaterBuy::inventoryChanged(LLViewerObject* obj,
removeVOInventoryListener();
}
-
-// static
-void LLFloaterBuy::onClickBuy(void*)
+void LLFloaterBuy::onClickBuy()
{
- if (!sInstance)
- {
- llinfos << "LLFloaterBuy::onClickBuy no sInstance!" << llendl;
- return;
- }
-
// Put the items where we put new folders.
LLUUID category_id;
category_id = gInventory.findCategoryUUIDForType(LLAssetType::AT_OBJECT);
@@ -307,24 +297,13 @@ void LLFloaterBuy::onClickBuy(void*)
// *NOTE: doesn't work for multiple object buy, which UI does not
// currently support sale info is used for verification only, if
// it doesn't match region info then sale is canceled.
- LLSelectMgr::getInstance()->sendBuy(gAgent.getID(), category_id, sInstance->mSaleInfo );
+ LLSelectMgr::getInstance()->sendBuy(gAgent.getID(), category_id, mSaleInfo );
- sInstance->close();
+ closeFloater();
}
-// static
-void LLFloaterBuy::onClickCancel(void*)
+void LLFloaterBuy::onClickCancel()
{
- if (sInstance)
- {
- sInstance->close();
- }
-}
-
-void LLFloaterBuy::onClose(bool app_quitting)
-{
- // drop reference to current selection so selection goes away
- mObjectSelection = NULL;
- LLFloater::onClose(app_quitting);
+ closeFloater();
}
diff --git a/indra/newview/llfloaterbuy.h b/indra/newview/llfloaterbuy.h
index 7473e6c855..ee54303267 100644
--- a/indra/newview/llfloaterbuy.h
+++ b/indra/newview/llfloaterbuy.h
@@ -52,13 +52,14 @@ class LLFloaterBuy
: public LLFloater, public LLVOInventoryListener
{
public:
+ LLFloaterBuy(const LLSD& key);
+ ~LLFloaterBuy();
+
+ /*virtual*/ BOOL postBuild();
+
static void show(const LLSaleInfo& sale_info);
protected:
- LLFloaterBuy();
- ~LLFloaterBuy();
-
- /*virtual*/ void onClose(bool app_quitting);
void reset();
void requestObjectInventories();
@@ -67,12 +68,10 @@ protected:
S32 serial_num,
void* data);
- static void onClickBuy(void*);
- static void onClickCancel(void*);
+ void onClickBuy();
+ void onClickCancel();
private:
- static LLFloaterBuy* sInstance;
-
LLSafeHandle<LLObjectSelection> mObjectSelection;
LLSaleInfo mSaleInfo;
};
diff --git a/indra/newview/llfloaterbuycontents.cpp b/indra/newview/llfloaterbuycontents.cpp
index 95a8caac53..3a4171c6be 100644
--- a/indra/newview/llfloaterbuycontents.cpp
+++ b/indra/newview/llfloaterbuycontents.cpp
@@ -46,7 +46,8 @@
#include "llalertdialog.h"
#include "llcheckboxctrl.h"
#include "llinventorymodel.h" // for gInventory
-#include "llinventoryview.h" // for get_item_icon
+#include "llfloaterreg.h"
+#include "llfloaterinventory.h" // for get_item_icon
#include "llselectmgr.h"
#include "llscrolllistctrl.h"
#include "llviewerobject.h"
@@ -54,26 +55,35 @@
#include "lluictrlfactory.h"
#include "llviewerwindow.h"
-LLFloaterBuyContents* LLFloaterBuyContents::sInstance = NULL;
+LLFloaterBuyContents::LLFloaterBuyContents(const LLSD& key)
+: LLFloater(key)
+{
+// LLUICtrlFactory::getInstance()->buildFloater(this, "floater_buy_contents.xml");
+}
-LLFloaterBuyContents::LLFloaterBuyContents()
-: LLFloater(std::string("floater_buy_contents"), std::string("FloaterBuyContentsRect"), LLStringUtil::null)
+BOOL LLFloaterBuyContents::postBuild()
{
- LLUICtrlFactory::getInstance()->buildFloater(this, "floater_buy_contents.xml");
- childSetAction("cancel_btn", onClickCancel, this);
- childSetAction("buy_btn", onClickBuy, this);
+ getChild<LLUICtrl>("cancel_btn")->setCommitCallback( boost::bind(&LLFloaterBuyContents::onClickCancel, this));
+ getChild<LLUICtrl>("buy_btn")->setCommitCallback( boost::bind(&LLFloaterBuyContents::onClickBuy, this));
childDisable("item_list");
childDisable("buy_btn");
childDisable("wear_check");
setDefaultBtn("cancel_btn"); // to avoid accidental buy (SL-43130)
+
+ // Always center the dialog. User can change the size,
+ // but purchases are important and should be center screen.
+ // This also avoids problems where the user resizes the application window
+ // mid-session and the saved rect is off-center.
+ center();
+
+ return TRUE;
}
LLFloaterBuyContents::~LLFloaterBuyContents()
{
- sInstance = NULL;
}
@@ -87,27 +97,16 @@ void LLFloaterBuyContents::show(const LLSaleInfo& sale_info)
LLNotifications::instance().add("BuyContentsOneOnly");
return;
}
+
+ LLFloaterBuyContents* floater = LLFloaterReg::showTypedInstance<LLFloaterBuyContents>("buy_object_contents");
+ if (!floater)
+ return;
+
+ LLScrollListCtrl* list = floater->getChild<LLScrollListCtrl>("item_list");
+ if (list)
+ list->deleteAllItems();
- // Create a new instance only if needed
- if (sInstance)
- {
- LLScrollListCtrl* list = sInstance->getChild<LLScrollListCtrl>("item_list");
- if (list) list->deleteAllItems();
- }
- else
- {
- sInstance = new LLFloaterBuyContents();
- }
-
- sInstance->open(); /*Flawfinder: ignore*/
- sInstance->setFocus(TRUE);
- sInstance->mObjectSelection = LLSelectMgr::getInstance()->getEditSelection();
-
- // Always center the dialog. User can change the size,
- // but purchases are important and should be center screen.
- // This also avoids problems where the user resizes the application window
- // mid-session and the saved rect is off-center.
- sInstance->center();
+ floater->mObjectSelection = LLSelectMgr::getInstance()->getEditSelection();
LLUUID owner_id;
std::string owner_name;
@@ -118,7 +117,7 @@ void LLFloaterBuyContents::show(const LLSaleInfo& sale_info)
return;
}
- sInstance->mSaleInfo = sale_info;
+ floater->mSaleInfo = sale_info;
// Update the display
LLSelectNode* node = selection->getFirstRootNode();
@@ -128,16 +127,16 @@ void LLFloaterBuyContents::show(const LLSaleInfo& sale_info)
gCacheName->getGroupName(owner_id, owner_name);
}
- sInstance->childSetTextArg("contains_text", "[NAME]", node->mName);
- sInstance->childSetTextArg("buy_text", "[AMOUNT]", llformat("%d", sale_info.getSalePrice()));
- sInstance->childSetTextArg("buy_text", "[NAME]", owner_name);
+ floater->childSetTextArg("contains_text", "[NAME]", node->mName);
+ floater->childSetTextArg("buy_text", "[AMOUNT]", llformat("%d", sale_info.getSalePrice()));
+ floater->childSetTextArg("buy_text", "[NAME]", owner_name);
// Must do this after the floater is created, because
// sometimes the inventory is already there and
// the callback is called immediately.
LLViewerObject* obj = selection->getFirstRootObject();
- sInstance->registerVOInventoryListener(obj,NULL);
- sInstance->requestVOInventory();
+ floater->registerVOInventoryListener(obj,NULL);
+ floater->requestVOInventory();
}
@@ -267,22 +266,21 @@ void LLFloaterBuyContents::inventoryChanged(LLViewerObject* obj,
}
-// static
-void LLFloaterBuyContents::onClickBuy(void*)
+void LLFloaterBuyContents::onClickBuy()
{
// Make sure this wasn't selected through other mechanisms
// (ie, being the default button and pressing enter.
- if(!sInstance->childIsEnabled("buy_btn"))
+ if(!childIsEnabled("buy_btn"))
{
// We shouldn't be enabled. Just close.
- sInstance->close();
+ closeFloater();
return;
}
// We may want to wear this item
- if (sInstance->childGetValue("wear_check"))
+ if (childGetValue("wear_check"))
{
- LLInventoryView::sWearNewClothing = TRUE;
+ LLFloaterInventory::sWearNewClothing = TRUE;
}
// Put the items where we put new folders.
@@ -292,14 +290,12 @@ void LLFloaterBuyContents::onClickBuy(void*)
// *NOTE: doesn't work for multiple object buy, which UI does not
// currently support sale info is used for verification only, if
// it doesn't match region info then sale is canceled.
- LLSelectMgr::getInstance()->sendBuy(gAgent.getID(), category_id, sInstance->mSaleInfo);
+ LLSelectMgr::getInstance()->sendBuy(gAgent.getID(), category_id, mSaleInfo);
- sInstance->close();
+ closeFloater();
}
-
-// static
-void LLFloaterBuyContents::onClickCancel(void*)
+void LLFloaterBuyContents::onClickCancel()
{
- sInstance->close();
+ closeFloater();
}
diff --git a/indra/newview/llfloaterbuycontents.h b/indra/newview/llfloaterbuycontents.h
index 908ff134e6..8045a46c9f 100644
--- a/indra/newview/llfloaterbuycontents.h
+++ b/indra/newview/llfloaterbuycontents.h
@@ -52,22 +52,21 @@ class LLFloaterBuyContents
public:
static void show(const LLSaleInfo& sale_info);
-protected:
- LLFloaterBuyContents();
+ LLFloaterBuyContents(const LLSD& key);
~LLFloaterBuyContents();
-
+ /*virtual*/ BOOL postBuild();
+
+protected:
void requestObjectInventories();
/*virtual*/ void inventoryChanged(LLViewerObject* obj,
InventoryObjectList* inv,
S32 serial_num,
void* data);
-
- static void onClickBuy(void*);
- static void onClickCancel(void*);
+
+ void onClickBuy();
+ void onClickCancel();
protected:
- static LLFloaterBuyContents* sInstance;
-
LLSafeHandle<LLObjectSelection> mObjectSelection;
LLSaleInfo mSaleInfo;
};
diff --git a/indra/newview/llfloaterbuycurrency.cpp b/indra/newview/llfloaterbuycurrency.cpp
index cfbc5da761..0107cb6fe2 100644
--- a/indra/newview/llfloaterbuycurrency.cpp
+++ b/indra/newview/llfloaterbuycurrency.cpp
@@ -37,6 +37,7 @@
// viewer includes
#include "llcurrencyuimanager.h"
#include "llfloater.h"
+#include "llfloaterreg.h"
#include "llstatusbar.h"
#include "lltextbox.h"
#include "llviewchildren.h"
@@ -53,12 +54,7 @@ class LLFloaterBuyCurrencyUI
: public LLFloater
{
public:
- static LLFloaterBuyCurrencyUI* soleInstance(bool createIfNeeded);
-
-private:
- static LLFloaterBuyCurrencyUI* sInstance;
-
- LLFloaterBuyCurrencyUI();
+ LLFloaterBuyCurrencyUI(const LLSD& key);
virtual ~LLFloaterBuyCurrencyUI();
@@ -80,32 +76,18 @@ public:
virtual void draw();
virtual BOOL canClose();
- virtual void onClose(bool app_quitting);
- static void onClickBuy(void* data);
- static void onClickCancel(void* data);
- static void onClickErrorWeb(void* data);
+ void onClickBuy();
+ void onClickCancel();
+ void onClickErrorWeb();
};
-
-// static
-LLFloaterBuyCurrencyUI* LLFloaterBuyCurrencyUI::sInstance = NULL;
-
-// static
-LLFloaterBuyCurrencyUI* LLFloaterBuyCurrencyUI::soleInstance(bool createIfNeeded)
+LLFloater* LLFloaterBuyCurrency::buildFloater(const LLSD& key)
{
- if (!sInstance && createIfNeeded)
- {
- sInstance = new LLFloaterBuyCurrencyUI();
-
- LLUICtrlFactory::getInstance()->buildFloater(sInstance, "floater_buy_currency.xml");
- sInstance->center();
- }
-
- return sInstance;
+ LLFloaterBuyCurrencyUI* floater = new LLFloaterBuyCurrencyUI(key);
+ return floater;
}
-
#if LL_WINDOWS
// passing 'this' during construction generates a warning. The callee
// only uses the pointer to hold a reference to 'this' which is
@@ -113,8 +95,8 @@ LLFloaterBuyCurrencyUI* LLFloaterBuyCurrencyUI::soleInstance(bool createIfNeeded
// warning so that we can compile without generating a warning.
#pragma warning(disable : 4355)
#endif
-LLFloaterBuyCurrencyUI::LLFloaterBuyCurrencyUI()
-: LLFloater(std::string("Buy Currency")),
+LLFloaterBuyCurrencyUI::LLFloaterBuyCurrencyUI(const LLSD& key)
+: LLFloater(key),
mChildren(*this),
mManager(*this)
{
@@ -122,10 +104,6 @@ LLFloaterBuyCurrencyUI::LLFloaterBuyCurrencyUI()
LLFloaterBuyCurrencyUI::~LLFloaterBuyCurrencyUI()
{
- if (sInstance == this)
- {
- sInstance = NULL;
- }
}
@@ -157,10 +135,12 @@ BOOL LLFloaterBuyCurrencyUI::postBuild()
{
mManager.prepare();
- childSetAction("buy_btn", onClickBuy, this);
- childSetAction("cancel_btn", onClickCancel, this);
- childSetAction("error_web", onClickErrorWeb, this);
-
+ getChild<LLUICtrl>("buy_btn")->setCommitCallback( boost::bind(&LLFloaterBuyCurrencyUI::onClickBuy, this));
+ getChild<LLUICtrl>("cancel_btn")->setCommitCallback( boost::bind(&LLFloaterBuyCurrencyUI::onClickCancel, this));
+ getChild<LLUICtrl>("error_web")->setCommitCallback( boost::bind(&LLFloaterBuyCurrencyUI::onClickErrorWeb, this));
+
+ center();
+
updateUI();
return TRUE;
@@ -172,7 +152,7 @@ void LLFloaterBuyCurrencyUI::draw()
{
if (mManager.bought())
{
- close();
+ closeFloater();
return;
}
@@ -187,12 +167,6 @@ BOOL LLFloaterBuyCurrencyUI::canClose()
return mManager.canCancel();
}
-void LLFloaterBuyCurrencyUI::onClose(bool app_quitting)
-{
- LLFloater::onClose(app_quitting);
- destroy();
-}
-
void LLFloaterBuyCurrencyUI::updateUI()
{
bool hasError = mManager.hasError();
@@ -320,57 +294,41 @@ void LLFloaterBuyCurrencyUI::updateUI()
}
}
-// static
-void LLFloaterBuyCurrencyUI::onClickBuy(void* data)
+void LLFloaterBuyCurrencyUI::onClickBuy()
{
- LLFloaterBuyCurrencyUI* self = LLFloaterBuyCurrencyUI::soleInstance(false);
- if (self)
- {
- self->mManager.buy(self->getString("buy_currency"));
- self->updateUI();
- // JC: updateUI() doesn't get called again until progress is made
- // with transaction processing, so the "Purchase" button would be
- // left enabled for some time. Pre-emptively disable.
- self->childSetEnabled("buy_btn", false);
- }
+ mManager.buy(getString("buy_currency"));
+ updateUI();
+ // JC: updateUI() doesn't get called again until progress is made
+ // with transaction processing, so the "Purchase" button would be
+ // left enabled for some time. Pre-emptively disable.
+ childSetEnabled("buy_btn", false);
}
-// static
-void LLFloaterBuyCurrencyUI::onClickCancel(void* data)
+void LLFloaterBuyCurrencyUI::onClickCancel()
{
- LLFloaterBuyCurrencyUI* self = LLFloaterBuyCurrencyUI::soleInstance(false);
- if (self)
- {
- self->close();
- }
+ closeFloater();
}
-// static
-void LLFloaterBuyCurrencyUI::onClickErrorWeb(void* data)
+void LLFloaterBuyCurrencyUI::onClickErrorWeb()
{
- LLFloaterBuyCurrencyUI* self = LLFloaterBuyCurrencyUI::soleInstance(false);
- if (self)
- {
- LLWeb::loadURLExternal(self->mManager.errorURI());
- self->close();
- }
+ LLWeb::loadURLExternal(mManager.errorURI());
+ closeFloater();
}
// static
void LLFloaterBuyCurrency::buyCurrency()
{
- LLFloaterBuyCurrencyUI* ui = LLFloaterBuyCurrencyUI::soleInstance(true);
+ LLFloaterBuyCurrencyUI* ui = LLFloaterReg::showTypedInstance<LLFloaterBuyCurrencyUI>("buy_currency");
ui->noTarget();
ui->updateUI();
- ui->open();
}
+// static
void LLFloaterBuyCurrency::buyCurrency(const std::string& name, S32 price)
{
- LLFloaterBuyCurrencyUI* ui = LLFloaterBuyCurrencyUI::soleInstance(true);
+ LLFloaterBuyCurrencyUI* ui = LLFloaterReg::showTypedInstance<LLFloaterBuyCurrencyUI>("buy_currency");
ui->target(name, price);
ui->updateUI();
- ui->open();
}
diff --git a/indra/newview/llfloaterbuycurrency.h b/indra/newview/llfloaterbuycurrency.h
index 756acd2f0c..9b3f9b43d0 100644
--- a/indra/newview/llfloaterbuycurrency.h
+++ b/indra/newview/llfloaterbuycurrency.h
@@ -35,6 +35,8 @@
#include "stdtypes.h"
+class LLFloater;
+
class LLFloaterBuyCurrency
{
public:
@@ -46,6 +48,8 @@ public:
"Uploading costs"
a space and the price will be appended
*/
+
+ static LLFloater* buildFloater(const LLSD& key);
};
diff --git a/indra/newview/llfloaterbuyland.cpp b/indra/newview/llfloaterbuyland.cpp
index 29506e21d5..7075719299 100644
--- a/indra/newview/llfloaterbuyland.cpp
+++ b/indra/newview/llfloaterbuyland.cpp
@@ -43,6 +43,7 @@
#include "llconfirmationmanager.h"
#include "llcurrencyuimanager.h"
#include "llfloater.h"
+#include "llfloaterreg.h"
#include "llfloatertools.h"
#include "llframetimer.h"
#include "lliconctrl.h"
@@ -75,10 +76,22 @@ const F64 CURRENCY_ESTIMATE_FREQUENCY = 0.5;
class LLFloaterBuyLandUI
: public LLFloater
{
-private:
- LLFloaterBuyLandUI();
+public:
+ LLFloaterBuyLandUI(const LLSD& key);
virtual ~LLFloaterBuyLandUI();
-
+
+private:
+ class SelectionObserver : public LLParcelObserver
+ {
+ public:
+ SelectionObserver(LLFloaterBuyLandUI* floater) : mFloater(floater) {}
+ virtual void changed();
+ private:
+ LLFloaterBuyLandUI* mFloater;
+ };
+
+private:
+ SelectionObserver mParcelSelectionObserver;
LLViewerRegion* mRegion;
LLParcelSelectionHandle mParcel;
bool mIsClaim;
@@ -144,11 +157,7 @@ private:
LLViewerParcelMgr::ParcelBuyInfo* mParcelBuyInfo;
- static LLFloaterBuyLandUI* sInstance;
-
public:
- static LLFloaterBuyLandUI* soleInstance(bool createIfNeeded);
-
void setForGroup(bool is_for_group);
void setParcel(LLViewerRegion* region, LLParcelSelectionHandle parcel);
@@ -156,10 +165,10 @@ public:
void updateParcelInfo();
void updateCovenantInfo();
static void onChangeAgreeCovenant(LLUICtrl* ctrl, void* user_data);
- void updateCovenantText(const std::string& string, const LLUUID &asset_id);
- void updateEstateName(const std::string& name);
- void updateLastModified(const std::string& text);
- void updateEstateOwnerName(const std::string& name);
+ void updateFloaterCovenantText(const std::string& string, const LLUUID &asset_id);
+ void updateFloaterEstateName(const std::string& name);
+ void updateFloaterLastModified(const std::string& text);
+ void updateFloaterEstateOwnerName(const std::string& name);
void updateWebSiteInfo();
void finishWebSiteInfo();
@@ -171,7 +180,7 @@ public:
void refreshUI();
- void startTransaction(TransactionType type, LLXMLRPCValue params);
+ void startTransaction(TransactionType type, const LLXMLRPCValue& params);
bool checkTransaction();
void tellUserError(const std::string& message, const std::string& uri);
@@ -181,27 +190,21 @@ public:
void startBuyPreConfirm();
void startBuyPostConfirm(const std::string& password);
- static void onClickBuy(void* data);
- static void onClickCancel(void* data);
- static void onClickErrorWeb(void* data);
+ void onClickBuy();
+ void onClickCancel();
+ void onClickErrorWeb();
virtual void draw();
virtual BOOL canClose();
- virtual void onClose(bool app_quitting);
- /*virtual*/ void setMinimized(BOOL b);
+
+ void onVisibilityChange ( const LLSD& new_visibility );
-private:
- class SelectionObserver : public LLParcelObserver
- {
- public:
- virtual void changed();
- };
};
static void cacheNameUpdateRefreshesBuyLand(const LLUUID&,
- const std::string&, const std::string&, BOOL, void* data)
+ const std::string&, const std::string&, BOOL)
{
- LLFloaterBuyLandUI* ui = LLFloaterBuyLandUI::soleInstance(false);
+ LLFloaterBuyLandUI* ui = LLFloaterReg::findTypedInstance<LLFloaterBuyLandUI>("buy_land");
if (ui)
{
ui->updateNames();
@@ -218,101 +221,64 @@ void LLFloaterBuyLand::buyLand(
return;
}
- LLFloaterBuyLandUI* ui = LLFloaterBuyLandUI::soleInstance(true);
- ui->setForGroup(is_for_group);
- ui->setParcel(region, parcel);
- ui->open(); /*Flawfinder: ignore*/
+ LLFloaterBuyLandUI* ui = LLFloaterReg::showTypedInstance<LLFloaterBuyLandUI>("buy_land");
+ if (ui)
+ {
+ ui->setForGroup(is_for_group);
+ ui->setParcel(region, parcel);
+ }
}
// static
void LLFloaterBuyLand::updateCovenantText(const std::string& string, const LLUUID &asset_id)
{
- LLFloaterBuyLandUI* floater = LLFloaterBuyLandUI::soleInstance(FALSE);
+ LLFloaterBuyLandUI* floater = LLFloaterReg::findTypedInstance<LLFloaterBuyLandUI>("buy_land");
if (floater)
{
- floater->updateCovenantText(string, asset_id);
+ floater->updateFloaterCovenantText(string, asset_id);
}
}
// static
void LLFloaterBuyLand::updateEstateName(const std::string& name)
{
- LLFloaterBuyLandUI* floater = LLFloaterBuyLandUI::soleInstance(FALSE);
+ LLFloaterBuyLandUI* floater = LLFloaterReg::findTypedInstance<LLFloaterBuyLandUI>("buy_land");
if (floater)
{
- floater->updateEstateName(name);
+ floater->updateFloaterEstateName(name);
}
}
// static
void LLFloaterBuyLand::updateLastModified(const std::string& text)
{
- LLFloaterBuyLandUI* floater = LLFloaterBuyLandUI::soleInstance(FALSE);
+ LLFloaterBuyLandUI* floater = LLFloaterReg::findTypedInstance<LLFloaterBuyLandUI>("buy_land");
if (floater)
{
- floater->updateLastModified(text);
+ floater->updateFloaterLastModified(text);
}
}
// static
void LLFloaterBuyLand::updateEstateOwnerName(const std::string& name)
{
- LLFloaterBuyLandUI* floater = LLFloaterBuyLandUI::soleInstance(FALSE);
+ LLFloaterBuyLandUI* floater = LLFloaterReg::findTypedInstance<LLFloaterBuyLandUI>("buy_land");
if (floater)
{
- floater->updateEstateOwnerName(name);
+ floater->updateFloaterEstateOwnerName(name);
}
}
// static
-BOOL LLFloaterBuyLand::isOpen()
+LLFloater* LLFloaterBuyLand::buildFloater(const LLSD& key)
{
- LLFloaterBuyLandUI* floater = LLFloaterBuyLandUI::soleInstance(FALSE);
- if (floater)
- {
- return floater->getVisible();
- }
- return FALSE;
-}
-
-// static
-LLFloaterBuyLandUI* LLFloaterBuyLandUI::sInstance = NULL;
-
-// static
-LLFloaterBuyLandUI* LLFloaterBuyLandUI::soleInstance(bool createIfNeeded)
-{
-#if !LL_RELEASE_FOR_DOWNLOAD
- if (createIfNeeded)
- {
- delete sInstance;
- sInstance = NULL;
- }
-#endif
- if (!sInstance && createIfNeeded)
- {
- sInstance = new LLFloaterBuyLandUI();
-
- LLUICtrlFactory::getInstance()->buildFloater(sInstance, "floater_buy_land.xml");
- sInstance->center();
-
- static bool observingCacheName = false;
- if (!observingCacheName)
- {
- gCacheName->addObserver(cacheNameUpdateRefreshesBuyLand);
- observingCacheName = true;
- }
-
- static SelectionObserver* parcelSelectionObserver = NULL;
- if (!parcelSelectionObserver)
- {
- parcelSelectionObserver = new SelectionObserver;
- LLViewerParcelMgr::getInstance()->addObserver(parcelSelectionObserver);
- }
- }
-
- return sInstance;
+ LLFloaterBuyLandUI* floater = new LLFloaterBuyLandUI(key);
+ return floater;
}
+//----------------------------------------------------------------------------
+// LLFloaterBuyLandUI
+//----------------------------------------------------------------------------
#if LL_WINDOWS
// passing 'this' during construction generates a warning. The callee
@@ -321,42 +287,45 @@ LLFloaterBuyLandUI* LLFloaterBuyLandUI::soleInstance(bool createIfNeeded)
// warning so that we can compile without generating a warning.
#pragma warning(disable : 4355)
#endif
-LLFloaterBuyLandUI::LLFloaterBuyLandUI()
-: LLFloater(std::string("Buy Land")),
+LLFloaterBuyLandUI::LLFloaterBuyLandUI(const LLSD& key)
+: LLFloater(LLSD()),
+ mParcelSelectionObserver(this),
mParcel(0),
mBought(false),
mParcelValid(false), mSiteValid(false),
mChildren(*this), mCurrency(*this), mTransaction(0),
mParcelBuyInfo(0)
{
+ static bool observingCacheName = false;
+ if (!observingCacheName)
+ {
+ gCacheName->addObserver(&cacheNameUpdateRefreshesBuyLand);
+ observingCacheName = true;
+ }
+
+ LLViewerParcelMgr::getInstance()->addObserver(&mParcelSelectionObserver);
+
+// LLUICtrlFactory::getInstance()->buildFloater(sInstance, "floater_buy_land.xml");
}
LLFloaterBuyLandUI::~LLFloaterBuyLandUI()
{
- delete mTransaction;
-
+ LLViewerParcelMgr::getInstance()->removeObserver(&mParcelSelectionObserver);
LLViewerParcelMgr::getInstance()->deleteParcelBuy(mParcelBuyInfo);
- if (sInstance == this)
- {
- sInstance = NULL;
- }
+ delete mTransaction;
}
void LLFloaterBuyLandUI::SelectionObserver::changed()
{
- LLFloaterBuyLandUI* ui = LLFloaterBuyLandUI::soleInstance(false);
- if (ui)
+ if (LLViewerParcelMgr::getInstance()->selectionEmpty())
{
- if (LLViewerParcelMgr::getInstance()->selectionEmpty())
- {
- ui->close();
- }
- else {
- ui->setParcel(
- LLViewerParcelMgr::getInstance()->getSelectionRegion(),
- LLViewerParcelMgr::getInstance()->getParcelSelection());
- }
+ mFloater->closeFloater();
+ }
+ else
+ {
+ mFloater->setParcel(LLViewerParcelMgr::getInstance()->getSelectionRegion(),
+ LLViewerParcelMgr::getInstance()->getParcelSelection());
}
}
@@ -566,8 +535,7 @@ void LLFloaterBuyLandUI::updateCovenantInfo()
{
check->set(false);
check->setEnabled(true);
- check->setCallbackUserData(this);
- check->setCommitCallback(onChangeAgreeCovenant);
+ check->setCommitCallback(onChangeAgreeCovenant, this);
}
LLTextBox* box = getChild<LLTextBox>("covenant_text");
@@ -595,51 +563,44 @@ void LLFloaterBuyLandUI::onChangeAgreeCovenant(LLUICtrl* ctrl, void* user_data)
}
}
-void LLFloaterBuyLandUI::updateCovenantText(const std::string &string, const LLUUID& asset_id)
+void LLFloaterBuyLandUI::updateFloaterCovenantText(const std::string &string, const LLUUID& asset_id)
{
LLViewerTextEditor* editor = getChild<LLViewerTextEditor>("covenant_editor");
- if (editor)
- {
- editor->setHandleEditKeysDirectly(FALSE);
- editor->setText(string);
+ editor->setText(string);
- LLCheckBoxCtrl* check = getChild<LLCheckBoxCtrl>("agree_covenant");
- LLTextBox* box = getChild<LLTextBox>("covenant_text");
- if(check && box)
- {
- if (asset_id.isNull())
- {
- check->set(true);
- check->setEnabled(false);
- refreshUI();
+ LLCheckBoxCtrl* check = getChild<LLCheckBoxCtrl>("agree_covenant");
+ LLTextBox* box = getChild<LLTextBox>("covenant_text");
+ if (asset_id.isNull())
+ {
+ check->set(true);
+ check->setEnabled(false);
+ refreshUI();
- // remove the line stating that you must agree
- box->setVisible(FALSE);
- }
- else
- {
- check->setEnabled(true);
+ // remove the line stating that you must agree
+ box->setVisible(FALSE);
+ }
+ else
+ {
+ check->setEnabled(true);
- // remove the line stating that you must agree
- box->setVisible(TRUE);
- }
- }
+ // remove the line stating that you must agree
+ box->setVisible(TRUE);
}
}
-void LLFloaterBuyLandUI::updateEstateName(const std::string& name)
+void LLFloaterBuyLandUI::updateFloaterEstateName(const std::string& name)
{
LLTextBox* box = getChild<LLTextBox>("estate_name_text");
if (box) box->setText(name);
}
-void LLFloaterBuyLandUI::updateLastModified(const std::string& text)
+void LLFloaterBuyLandUI::updateFloaterLastModified(const std::string& text)
{
LLTextBox* editor = getChild<LLTextBox>("covenant_timestamp_text");
if (editor) editor->setText(text);
}
-void LLFloaterBuyLandUI::updateEstateOwnerName(const std::string& name)
+void LLFloaterBuyLandUI::updateFloaterEstateOwnerName(const std::string& name)
{
LLTextBox* box = getChild<LLTextBox>("estate_owner_text");
if (box) box->setText(name);
@@ -836,8 +797,7 @@ void LLFloaterBuyLandUI::updateNames()
}
-void LLFloaterBuyLandUI::startTransaction(TransactionType type,
- LLXMLRPCValue params)
+void LLFloaterBuyLandUI::startTransaction(TransactionType type, const LLXMLRPCValue& params)
{
delete mTransaction;
mTransaction = NULL;
@@ -918,11 +878,15 @@ void LLFloaterBuyLandUI::tellUserError(
// virtual
BOOL LLFloaterBuyLandUI::postBuild()
{
+ mVisibleSignal.connect(boost::bind(&LLFloaterBuyLandUI::onVisibilityChange, this, _2));
+
mCurrency.prepare();
- childSetAction("buy_btn", onClickBuy, this);
- childSetAction("cancel_btn", onClickCancel, this);
- childSetAction("error_web", onClickErrorWeb, this);
+ getChild<LLUICtrl>("buy_btn")->setCommitCallback( boost::bind(&LLFloaterBuyLandUI::onClickBuy, this));
+ getChild<LLUICtrl>("cancel_btn")->setCommitCallback( boost::bind(&LLFloaterBuyLandUI::onClickCancel, this));
+ getChild<LLUICtrl>("error_web")->setCommitCallback( boost::bind(&LLFloaterBuyLandUI::onClickErrorWeb, this));
+
+ center();
return TRUE;
}
@@ -963,7 +927,7 @@ void LLFloaterBuyLandUI::draw()
if (mBought)
{
- close();
+ closeFloater();
}
else if (needsUpdate)
{
@@ -988,24 +952,14 @@ BOOL LLFloaterBuyLandUI::canClose()
return can_close;
}
-// virtual
-void LLFloaterBuyLandUI::setMinimized(BOOL minimize)
+void LLFloaterBuyLandUI::onVisibilityChange ( const LLSD& new_visibility )
{
- bool restored = (isMinimized() && !minimize);
- LLFloater::setMinimized(minimize);
- if (restored)
+ if (new_visibility.asBoolean())
{
refreshUI();
}
}
-void LLFloaterBuyLandUI::onClose(bool app_quitting)
-{
- LLFloater::onClose(app_quitting);
- destroy();
-}
-
-
void LLFloaterBuyLandUI::refreshUI()
{
// section zero: title area
@@ -1155,7 +1109,7 @@ void LLFloaterBuyLandUI::refreshUI()
if (mIsForGroup)
{
LLStringUtil::format_map_t string_args;
- string_args["[GROUP]"] = std::string(gAgent.mGroupName);
+ string_args["[GROUP]"] = std::string(gAgent.getGroupName());
message += getString("insufficient_land_credits", string_args);
@@ -1169,7 +1123,7 @@ void LLFloaterBuyLandUI::refreshUI()
if (!mParcelValid)
{
- message += "(no parcel selected)";
+ message += getString("no_parcel_selected");
}
else if (mParcelBillableArea == mParcelActualArea)
{
@@ -1225,12 +1179,10 @@ void LLFloaterBuyLandUI::refreshUI()
? LLViewChildren::BADGE_NOTE
: LLViewChildren::BADGE_OK);
- childSetText("purchase_action",
- llformat(
- "Pay L$ %d to %s for this land",
- mParcelPrice,
- mParcelSellerName.c_str()
- ));
+ LLStringUtil::format_map_t string_args;
+ string_args["[AMOUNT]"] = llformat("%d", mParcelPrice);
+ string_args["[SELLER]"] = mParcelSellerName;
+ childSetText("purchase_action", getString("pay_to_for_land", string_args));
childSetVisible("purchase_action", mParcelValid);
std::string reasonString;
@@ -1357,26 +1309,20 @@ void LLFloaterBuyLandUI::startBuyPostConfirm(const std::string& password)
}
-// static
-void LLFloaterBuyLandUI::onClickBuy(void* data)
+void LLFloaterBuyLandUI::onClickBuy()
{
- LLFloaterBuyLandUI* self = (LLFloaterBuyLandUI*)data;
- self->startBuyPreConfirm();
+ startBuyPreConfirm();
}
-// static
-void LLFloaterBuyLandUI::onClickCancel(void* data)
+void LLFloaterBuyLandUI::onClickCancel()
{
- LLFloaterBuyLandUI* self = (LLFloaterBuyLandUI*)data;
- self->close();
+ closeFloater();
}
-// static
-void LLFloaterBuyLandUI::onClickErrorWeb(void* data)
+void LLFloaterBuyLandUI::onClickErrorWeb()
{
- LLFloaterBuyLandUI* self = (LLFloaterBuyLandUI*)data;
- LLWeb::loadURLExternal(self->mCannotBuyURI);
- self->close();
+ LLWeb::loadURLExternal(mCannotBuyURI);
+ closeFloater();
}
diff --git a/indra/newview/llfloaterbuyland.h b/indra/newview/llfloaterbuyland.h
index 82e59a0bcc..00d44035ae 100644
--- a/indra/newview/llfloaterbuyland.h
+++ b/indra/newview/llfloaterbuyland.h
@@ -33,8 +33,8 @@
#ifndef LL_LLFLOATERBUYLAND_H
#define LL_LLFLOATERBUYLAND_H
+class LLFloater;
class LLViewerRegion;
-class LLViewerTextEditor;
class LLParcelSelection;
class LLFloaterBuyLand
@@ -47,7 +47,8 @@ public:
static void updateEstateName(const std::string& name);
static void updateLastModified(const std::string& text);
static void updateEstateOwnerName(const std::string& name);
- static BOOL isOpen();
+
+ static LLFloater* buildFloater(const LLSD& key);
};
#endif
diff --git a/indra/newview/llfloatercamera.cpp b/indra/newview/llfloatercamera.cpp
index 7a4e5147fe..94ea20893a 100644
--- a/indra/newview/llfloatercamera.cpp
+++ b/indra/newview/llfloatercamera.cpp
@@ -35,87 +35,308 @@
#include "llfloatercamera.h"
// Library includes
-#include "lluictrlfactory.h"
+#include "llfloaterreg.h"
// Viewer includes
#include "lljoystickbutton.h"
+#include "llfirsttimetipmanager.h"
#include "llviewercontrol.h"
+#include "llbottomtray.h"
+#include "llagent.h"
+#include "lltoolmgr.h"
+#include "lltoolfocus.h"
// Constants
const F32 CAMERA_BUTTON_DELAY = 0.0f;
+#define ORBIT "cam_rotate_stick"
+#define PAN "cam_track_stick"
+#define CONTROLS "controls"
+
+
+void show_tip(LLFirstTimeTipsManager::EFirstTimeTipType tipType, LLView* anchorView)
+{
+ LLFirstTimeTipsManager::showTipsFor(tipType, anchorView, LLFirstTimeTipsManager::TPA_POS_RIGHT_ALIGN_TOP);
+}
//
// Member functions
//
+/*static*/ bool LLFloaterCamera::inFreeCameraMode()
+{
+ LLFloaterCamera* floater_camera = LLFloaterCamera::findInstance();
+ if (floater_camera && floater_camera->mCurrMode == CAMERA_CTRL_MODE_FREE_CAMERA)
+ {
+ return true;
+ }
+ return false;
+}
+
+bool LLFloaterCamera::inAvatarViewMode()
+{
+ return mCurrMode == CAMERA_CTRL_MODE_AVATAR_VIEW;
+}
+
+void LLFloaterCamera::resetFreeCameraMode()
+{
+ if (mCurrMode == CAMERA_CTRL_MODE_FREE_CAMERA)
+ {
+ /* Camera Tool can be deselected when we are mouse wheel scrolling into Mouse Look
+ In such case we are unable to determine that we will be into Mouse Look view */
+ if (mPrevMode == CAMERA_CTRL_MODE_AVATAR_VIEW)
+ {
+ setMode(CAMERA_CTRL_MODE_ORBIT);
+ }
+ else
+ {
+ setMode(mPrevMode);
+ }
+ }
+}
+
+void LLFloaterCamera::update()
+{
+ ECameraControlMode mode = determineMode();
+ if (mode != mCurrMode) setMode(mode);
+ updatePosition();
+ show_tip(mMode2TipType[mode], this);
+}
+
+
+/*static*/ void LLFloaterCamera::updateIfNotInAvatarViewMode()
+{
+ LLFloaterCamera* floater_camera = LLFloaterCamera::findInstance();
+ if (floater_camera && !floater_camera->inAvatarViewMode())
+ {
+ floater_camera->update();
+ }
+}
+
+
+void LLFloaterCamera::toPrevMode()
+{
+ switchMode(mPrevMode);
+}
+
+/*static*/ void LLFloaterCamera::toPrevModeIfInAvatarViewMode()
+{
+ LLFloaterCamera* floater_camera = LLFloaterCamera::findInstance();
+ if (floater_camera && floater_camera->inAvatarViewMode())
+ {
+ floater_camera->toPrevMode();
+ }
+}
+
+LLFloaterCamera* LLFloaterCamera::findInstance()
+{
+ return LLFloaterReg::findTypedInstance<LLFloaterCamera>("camera");
+}
+
+/*static*/
+void LLFloaterCamera::onClickCameraPresets(LLUICtrl* ctrl, const LLSD& param)
+{
+ std::string name = param.asString();
+
+ if ("rear_view" == name)
+ {
+ LLFirstTimeTipsManager::showTipsFor(LLFirstTimeTipsManager::FTT_CAMERA_PRESET_REAR, ctrl);
+ gAgent.switchCameraPreset(CAMERA_PRESET_REAR_VIEW);
+ }
+ else if ("group_view" == name)
+ {
+ LLFirstTimeTipsManager::showTipsFor(LLFirstTimeTipsManager::FTT_CAMERA_PRESET_GROUP);
+ gAgent.switchCameraPreset(CAMERA_PRESET_GROUP_VIEW);
+ }
+ else if ("front_view" == name)
+ {
+ LLFirstTimeTipsManager::showTipsFor(LLFirstTimeTipsManager::FTT_CAMERA_PRESET_FRONT);
+ gAgent.switchCameraPreset(CAMERA_PRESET_FRONT_VIEW);
+ }
+
+}
+
+void LLFloaterCamera::onOpen(const LLSD& key)
+{
+ updatePosition();
+}
+
+void LLFloaterCamera::updatePosition()
+{
+ LLBottomTray* tray = LLBottomTray::getInstance();
+ if (!tray) return;
+
+ LLButton* camera_button = tray->getChild<LLButton>("camera_btn");
+
+ //align centers of a button and a floater
+ S32 x = camera_button->calcScreenRect().getCenterX() - getRect().getWidth()/2;
+ setOrigin(x, 0);
+}
+
LLFloaterCamera::LLFloaterCamera(const LLSD& val)
-: LLFloater("camera floater") // uses "FloaterCameraRect3"
+: LLFloater(val),
+ mCurrMode(CAMERA_CTRL_MODE_ORBIT),
+ mPrevMode(CAMERA_CTRL_MODE_ORBIT)
+{
+}
+
+// virtual
+BOOL LLFloaterCamera::postBuild()
{
setIsChrome(TRUE);
+
+ mRotate = getChild<LLJoystickCameraRotate>(ORBIT);
+ mZoom = getChild<LLJoystickCameraZoom>("zoom");
+ mTrack = getChild<LLJoystickCameraTrack>(PAN);
+
+ initMode2TipTypeMap();
+
+ assignButton2Mode(CAMERA_CTRL_MODE_ORBIT, "orbit_btn");
+ assignButton2Mode(CAMERA_CTRL_MODE_PAN, "pan_btn");
+ assignButton2Mode(CAMERA_CTRL_MODE_FREE_CAMERA, "freecamera_btn");
+ assignButton2Mode(CAMERA_CTRL_MODE_AVATAR_VIEW, "avatarview_btn");
+
+ update();
+
+ return TRUE;
+}
+
+ECameraControlMode LLFloaterCamera::determineMode()
+{
+ LLTool* curr_tool = LLToolMgr::getInstance()->getCurrentTool();
+ if (curr_tool == LLToolCamera::getInstance())
+ {
+ return CAMERA_CTRL_MODE_FREE_CAMERA;
+ }
+
+ if (gAgent.getCameraMode() == CAMERA_MODE_MOUSELOOK)
+ {
+ return CAMERA_CTRL_MODE_AVATAR_VIEW;
+ }
+
+ return CAMERA_CTRL_MODE_ORBIT;
+}
+
+
+void clear_camera_tool()
+{
+ LLToolMgr* tool_mgr = LLToolMgr::getInstance();
+ if (tool_mgr->usingTransientTool() &&
+ tool_mgr->getCurrentTool() == LLToolCamera::getInstance())
+ {
+ tool_mgr->clearTransientTool();
+ }
+}
+
+
+void LLFloaterCamera::setMode(ECameraControlMode mode)
+{
+ if (mode != mCurrMode)
+ {
+ mPrevMode = mCurrMode;
+ mCurrMode = mode;
+ }
- // For now, only used for size and tooltip strings
- const BOOL DONT_OPEN = FALSE;
- LLUICtrlFactory::getInstance()->buildFloater(this, "floater_camera.xml", NULL, DONT_OPEN);
-
- S32 top = getRect().getHeight();
- S32 bottom = 0;
- S32 left = 16;
-
- const S32 ROTATE_WIDTH = 64;
- mRotate = new LLJoystickCameraRotate(std::string("cam rotate stick"),
- LLRect( left, top, left + ROTATE_WIDTH, bottom ),
- std::string("cam_rotate_out.tga"),
- std::string("cam_rotate_in.tga") );
- mRotate->setFollows(FOLLOWS_TOP | FOLLOWS_LEFT);
- mRotate->setHeldDownDelay(CAMERA_BUTTON_DELAY);
- mRotate->setToolTip( getString("rotate_tooltip") );
- mRotate->setSoundFlags(MOUSE_DOWN | MOUSE_UP);
- addChild(mRotate);
-
- left += ROTATE_WIDTH;
-
- const S32 ZOOM_WIDTH = 16;
- mZoom = new LLJoystickCameraZoom(
- std::string("zoom"),
- LLRect( left, top, left + ZOOM_WIDTH, bottom ),
- std::string("cam_zoom_out.tga"),
- std::string("cam_zoom_plus_in.tga"),
- std::string("cam_zoom_minus_in.tga"));
- mZoom->setFollows(FOLLOWS_TOP | FOLLOWS_LEFT);
- mZoom->setHeldDownDelay(CAMERA_BUTTON_DELAY);
- mZoom->setToolTip( getString("zoom_tooltip") );
- mZoom->setSoundFlags(MOUSE_DOWN | MOUSE_UP);
- addChild(mZoom);
-
- left += ZOOM_WIDTH;
-
- const S32 TRACK_WIDTH = 64;
- mTrack = new LLJoystickCameraTrack(std::string("cam track stick"),
- LLRect( left, top, left + TRACK_WIDTH, bottom ),
- std::string("cam_tracking_out.tga"),
- std::string("cam_tracking_in.tga"));
- mTrack->setFollows(FOLLOWS_TOP | FOLLOWS_LEFT);
- mTrack->setHeldDownDelay(CAMERA_BUTTON_DELAY);
- mTrack->setToolTip( getString("move_tooltip") );
- mTrack->setSoundFlags(MOUSE_DOWN | MOUSE_UP);
- addChild(mTrack);
+ updateState();
}
-// virtual
-void LLFloaterCamera::onOpen()
+void LLFloaterCamera::switchMode(ECameraControlMode mode)
{
- LLFloater::onOpen();
+ setMode(mode);
+
+ switch (mode)
+ {
+ case CAMERA_CTRL_MODE_ORBIT:
+ clear_camera_tool();
+ break;
+
+ case CAMERA_CTRL_MODE_PAN:
+ clear_camera_tool();
+ break;
+
+ case CAMERA_CTRL_MODE_FREE_CAMERA:
+ LLToolMgr::getInstance()->setTransientTool(LLToolCamera::getInstance());
+ break;
+
+ case CAMERA_CTRL_MODE_AVATAR_VIEW:
+ gAgent.changeCameraToMouselook();
+ break;
+
+ default:
+ //normally we won't occur here
+ llassert_always(FALSE);
+ }
+}
+
+
+void LLFloaterCamera::onClickBtn(ECameraControlMode mode)
+{
+ // check for a click on active button
+ if (mCurrMode == mode) mMode2Button[mode]->setToggleState(TRUE);
- gSavedSettings.setBOOL("ShowCameraControls", TRUE);
+ switchMode(mode);
+
+ show_tip(mMode2TipType[mode], this);
}
-// virtual
-void LLFloaterCamera::onClose(bool app_quitting)
+void LLFloaterCamera::assignButton2Mode(ECameraControlMode mode, const std::string& button_name)
{
- LLFloater::onClose(app_quitting);
+ LLButton* button = getChild<LLButton>(button_name);
- if (!app_quitting)
+ button->setClickedCallback(boost::bind(&LLFloaterCamera::onClickBtn, this, mode));
+ mMode2Button[mode] = button;
+}
+
+void LLFloaterCamera::initMode2TipTypeMap()
+{
+ mMode2TipType[CAMERA_CTRL_MODE_ORBIT] = LLFirstTimeTipsManager::FTT_CAMERA_ORBIT_MODE;
+ mMode2TipType[CAMERA_CTRL_MODE_PAN] = LLFirstTimeTipsManager::FTT_CAMERA_PAN_MODE;
+ mMode2TipType[CAMERA_CTRL_MODE_FREE_CAMERA] = LLFirstTimeTipsManager::FTT_CAMERA_FREE_MODE;
+ mMode2TipType[CAMERA_CTRL_MODE_AVATAR_VIEW] = LLFirstTimeTipsManager::FTT_AVATAR_FREE_MODE;
+}
+
+
+void LLFloaterCamera::updateState()
+{
+ //updating buttons
+ std::map<ECameraControlMode, LLButton*>::const_iterator iter = mMode2Button.begin();
+ for (; iter != mMode2Button.end(); ++iter)
{
- gSavedSettings.setBOOL("ShowCameraControls", FALSE);
+ iter->second->setToggleState(iter->first == mCurrMode);
+ }
+
+ //updating controls
+ bool isOrbitMode = CAMERA_CTRL_MODE_ORBIT == mCurrMode;
+ bool isPanMode = CAMERA_CTRL_MODE_PAN == mCurrMode;
+
+ childSetVisible(ORBIT, isOrbitMode);
+ childSetVisible(PAN, isPanMode);
+
+ //hiding or showing the panel with controls by reshaping the floater
+ bool showControls = isOrbitMode || isPanMode;
+ if (showControls == childIsVisible(CONTROLS)) return;
+
+ childSetVisible(CONTROLS, showControls);
+
+ LLRect rect = getRect();
+ LLRect controls_rect;
+ if (childGetRect(CONTROLS, controls_rect))
+ {
+ static S32 height = controls_rect.getHeight();
+ S32 newHeight = rect.getHeight();
+
+ if (showControls)
+ {
+ newHeight += height;
+ }
+ else
+ {
+ newHeight -= height;
+ }
+
+ rect.setOriginAndSize(rect.mLeft, rect.mBottom, rect.getWidth(), newHeight);
+ reshape(rect.getWidth(), rect.getHeight());
+ setRect(rect);
+
}
}
+
diff --git a/indra/newview/llfloatercamera.h b/indra/newview/llfloatercamera.h
index 6862db7068..04554c6493 100644
--- a/indra/newview/llfloatercamera.h
+++ b/indra/newview/llfloatercamera.h
@@ -35,27 +35,94 @@
#include "llfloater.h"
+#include "llfirsttimetipmanager.h"
+
class LLJoystickCameraRotate;
class LLJoystickCameraZoom;
class LLJoystickCameraTrack;
+class LLFloaterReg;
+
+enum ECameraControlMode
+{
+ CAMERA_CTRL_MODE_ORBIT,
+ CAMERA_CTRL_MODE_PAN,
+ CAMERA_CTRL_MODE_FREE_CAMERA,
+ CAMERA_CTRL_MODE_AVATAR_VIEW
+};
class LLFloaterCamera
- : public LLFloater,
- public LLFloaterSingleton<LLFloaterCamera>
+ : public LLFloater
{
- friend class LLUISingleton<LLFloaterCamera, VisibilityPolicy<LLFloater> >;
-
-private:
- LLFloaterCamera(const LLSD& val);
- ~LLFloaterCamera() {};
-
- /*virtual*/ void onOpen();
- /*virtual*/ void onClose(bool app_quitting);
+ friend class LLFloaterReg;
public:
+
+ /* whether in free camera mode */
+ static bool inFreeCameraMode();
+
+ static void toPrevModeIfInAvatarViewMode();
+
+ /* resets free camera mode to the previous mode */
+ //*TODO remove, if it won't be used by LLToolCamera::handleDeselect()
+ void resetFreeCameraMode();
+
+ /* determines actual mode and updates ui */
+ void update();
+
+ static void updateIfNotInAvatarViewMode();
+
+ static void onClickCameraPresets(LLUICtrl* ctrl, const LLSD& param);
+
+ virtual void onOpen(const LLSD& key);
+
+ // *HACK: due to hard enough to have this control aligned with "Camera" button while resizing
+ // let update its position in each frame
+ /*virtual*/ void draw(){updatePosition(); LLFloater::draw();}
+
LLJoystickCameraRotate* mRotate;
LLJoystickCameraZoom* mZoom;
LLJoystickCameraTrack* mTrack;
+
+private:
+
+ LLFloaterCamera(const LLSD& val);
+ ~LLFloaterCamera() {};
+
+ /* return instance if it exists - created by LLFloaterReg */
+ static LLFloaterCamera* findInstance();
+
+ /*virtual*/ BOOL postBuild();
+
+ ECameraControlMode determineMode();
+
+ /* whether in avatar view (first person) mode */
+ bool inAvatarViewMode();
+
+ /* resets to the previous mode */
+ void toPrevMode();
+
+ /* sets a new mode and performs related actions */
+ void switchMode(ECameraControlMode mode);
+
+ /* sets a new mode preserving previous one and updates ui*/
+ void setMode(ECameraControlMode mode);
+
+ /* updates the state (UI) according to the current mode */
+ void updateState();
+
+ void onClickBtn(ECameraControlMode mode);
+ void assignButton2Mode(ECameraControlMode mode, const std::string& button_name);
+ void initMode2TipTypeMap();
+
+ /*Updates position of the floater to be center aligned with "Camera" button.*/
+ void updatePosition();
+
+
+ ECameraControlMode mPrevMode;
+ ECameraControlMode mCurrMode;
+ std::map<ECameraControlMode, LLButton*> mMode2Button;
+ std::map<ECameraControlMode, LLFirstTimeTipsManager::EFirstTimeTipType> mMode2TipType;
+
};
#endif
diff --git a/indra/newview/llfloaterchat.cpp b/indra/newview/llfloaterchat.cpp
index 0e9295f9f8..0dee3a1e83 100644
--- a/indra/newview/llfloaterchat.cpp
+++ b/indra/newview/llfloaterchat.cpp
@@ -38,15 +38,6 @@
#include "llviewerprecompiledheaders.h"
#include "llfloaterchat.h"
-#include "llfloateractivespeakers.h"
-#include "llfloaterscriptdebug.h"
-
-#include "llchat.h"
-#include "llfontgl.h"
-#include "llrect.h"
-#include "llerror.h"
-#include "llstring.h"
-#include "message.h"
// project include
#include "llagent.h"
@@ -54,13 +45,17 @@
#include "llcheckboxctrl.h"
#include "llcombobox.h"
#include "llconsole.h"
+#include "llfloateractivespeakers.h"
#include "llfloaterchatterbox.h"
#include "llfloatermute.h"
+#include "llfloaterreg.h"
+#include "llfloaterscriptdebug.h"
#include "llkeyboard.h"
//#include "lllineeditor.h"
#include "llmutelist.h"
//#include "llresizehandle.h"
#include "llchatbar.h"
+#include "llrecentpeople.h"
#include "llstatusbar.h"
#include "llviewertexteditor.h"
#include "llviewergesture.h" // for triggering gestures
@@ -68,7 +63,6 @@
#include "llviewerwindow.h"
#include "llviewercontrol.h"
#include "lluictrlfactory.h"
-#include "llchatbar.h"
#include "lllogchat.h"
#include "lltexteditor.h"
#include "lltextparser.h"
@@ -76,16 +70,22 @@
#include "llweb.h"
#include "llstylemap.h"
-// Used for LCD display
-extern void AddNewIMToLCD(const std::string &newLine);
-extern void AddNewChatToLCD(const std::string &newLine);
+// linden library includes
+#include "llaudioengine.h"
+#include "llchat.h"
+#include "llfontgl.h"
+#include "llrect.h"
+#include "llerror.h"
+#include "llstring.h"
+#include "llwindow.h"
+#include "message.h"
+
//
// Constants
//
const F32 INSTANT_MSG_SIZE = 8.0f;
const F32 CHAT_MSG_SIZE = 8.0f;
-const LLColor4 MUTED_MSG_COLOR(0.5f, 0.5f, 0.5f, 1.f);
-const S32 MAX_CHATTER_COUNT = 16;
+
//
// Global statics
@@ -96,20 +96,13 @@ LLColor4 get_text_color(const LLChat& chat);
// Member Functions
//
LLFloaterChat::LLFloaterChat(const LLSD& seed)
-: LLFloater(std::string("chat floater"), std::string("FloaterChatRect"), LLStringUtil::null,
- RESIZE_YES, 440, 100, DRAG_ON_TOP, MINIMIZE_NO, CLOSE_YES),
- mPanel(NULL)
+ : LLFloater(seed),
+ mPanel(NULL)
{
mFactoryMap["chat_panel"] = LLCallbackMap(createChatPanel, NULL);
mFactoryMap["active_speakers_panel"] = LLCallbackMap(createSpeakersPanel, NULL);
- // do not automatically open singleton floaters (as result of getInstance())
- BOOL no_open = FALSE;
- LLUICtrlFactory::getInstance()->buildFloater(this,"floater_chat_history.xml",&getFactoryMap(),no_open);
+ //Called from floater reg: LLUICtrlFactory::getInstance()->buildFloater(this,"floater_chat_history.xml");
- childSetCommitCallback("show mutes",onClickToggleShowMute,this); //show mutes
- childSetVisible("Chat History Editor with mute",FALSE);
- childSetAction("toggle_active_speakers_btn", onClickToggleActiveSpeakers, this);
- setDefaultBtn("Chat");
}
LLFloaterChat::~LLFloaterChat()
@@ -117,20 +110,13 @@ LLFloaterChat::~LLFloaterChat()
// Children all cleaned up by default view destructor.
}
-void LLFloaterChat::setVisible(BOOL visible)
-{
- LLFloater::setVisible( visible );
-
- gSavedSettings.setBOOL("ShowChatHistory", visible);
-}
-
void LLFloaterChat::draw()
{
// enable say and shout only when text available
childSetValue("toggle_active_speakers_btn", childIsVisible("active_speakers_panel"));
- LLChatBar* chat_barp = getChild<LLChatBar>("chat_panel", TRUE);
+ LLChatBar* chat_barp = findChild<LLChatBar>("chat_panel", TRUE);
if (chat_barp)
{
chat_barp->refresh();
@@ -142,47 +128,18 @@ void LLFloaterChat::draw()
BOOL LLFloaterChat::postBuild()
{
- mPanel = (LLPanelActiveSpeakers*)getChild<LLPanel>("active_speakers_panel");
-
- LLChatBar* chat_barp = getChild<LLChatBar>("chat_panel", TRUE);
- if (chat_barp)
- {
- chat_barp->setGestureCombo(getChild<LLComboBox>( "Gesture"));
- }
- return TRUE;
-}
-
-// public virtual
-void LLFloaterChat::onClose(bool app_quitting)
-{
- if (!app_quitting)
- {
- gSavedSettings.setBOOL("ShowChatHistory", FALSE);
- }
- setVisible(FALSE);
-}
-
-void LLFloaterChat::onVisibilityChange(BOOL new_visibility)
-{
// Hide the chat overlay when our history is visible.
- updateConsoleVisibility();
-
- // stop chat history tab from flashing when it appears
- if (new_visibility)
- {
- LLFloaterChatterBox::getInstance()->setFloaterFlashing(this, FALSE);
- }
+ mVisibleSignal.connect(boost::bind(&LLFloaterChat::updateConsoleVisibility, this));
+
+ mPanel = (LLPanelActiveSpeakers*)getChild<LLPanel>("active_speakers_panel");
- LLFloater::onVisibilityChange(new_visibility);
-}
+ childSetCommitCallback("show mutes",onClickToggleShowMute,this); //show mutes
+ childSetVisible("Chat History Editor with mute",FALSE);
+ childSetAction("toggle_active_speakers_btn", onClickToggleActiveSpeakers, this);
-void LLFloaterChat::setMinimized(BOOL minimized)
-{
- LLFloater::setMinimized(minimized);
- updateConsoleVisibility();
+ return TRUE;
}
-
void LLFloaterChat::updateConsoleVisibility()
{
// determine whether we should show console due to not being visible
@@ -215,8 +172,7 @@ void add_timestamped_line(LLViewerTextEditor* edit, LLChat chat, const LLColor4&
{
std::string start_line = line.substr(0, chat.mFromName.length() + 1);
line = line.substr(chat.mFromName.length() + 1);
- const LLStyleSP &sourceStyle = LLStyleMap::instance().lookup(chat.mFromID,chat.mURL);
- edit->appendStyledText(start_line, false, prepend_newline, sourceStyle);
+ edit->appendStyledText(start_line, false, prepend_newline, LLStyleMap::instance().lookup(chat.mFromID,chat.mURL));
prepend_newline = false;
}
edit->appendColoredText(line, false, prepend_newline, color);
@@ -225,7 +181,7 @@ void add_timestamped_line(LLViewerTextEditor* edit, LLChat chat, const LLColor4&
void log_chat_text(const LLChat& chat)
{
std::string histstr;
- if (gSavedPerAccountSettings.getBOOL("LogChatTimestamp"))
+ if (gSavedPerAccountSettings.getBOOL("LogTimestamp"))
histstr = LLLogChat::timestamp(gSavedPerAccountSettings.getBOOL("LogTimestampDate")) + chat.mText;
else
histstr = chat.mText;
@@ -235,7 +191,7 @@ void log_chat_text(const LLChat& chat)
// static
void LLFloaterChat::addChatHistory(const LLChat& chat, bool log_to_file)
{
- if ( gSavedPerAccountSettings.getBOOL("LogChat") && log_to_file)
+ if ( (gSavedPerAccountSettings.getS32("IMLogOptions")!=LOG_IM) && log_to_file)
{
log_chat_text(chat);
}
@@ -257,7 +213,7 @@ void LLFloaterChat::addChatHistory(const LLChat& chat, bool log_to_file)
}
// could flash the chat button in the status bar here. JC
- LLFloaterChat* chat_floater = LLFloaterChat::getInstance(LLSD());
+ LLFloaterChat* chat_floater = LLFloaterChat::getInstance();
LLViewerTextEditor* history_editor = chat_floater->getChild<LLViewerTextEditor>("Chat History Editor");
LLViewerTextEditor* history_editor_with_mute = chat_floater->getChild<LLViewerTextEditor>("Chat History Editor with mute");
@@ -295,8 +251,8 @@ void LLFloaterChat::addChatHistory(const LLChat& chat, bool log_to_file)
// static
void LLFloaterChat::setHistoryCursorAndScrollToEnd()
{
- LLViewerTextEditor* history_editor = LLFloaterChat::getInstance(LLSD())->getChild<LLViewerTextEditor>("Chat History Editor");
- LLViewerTextEditor* history_editor_with_mute = LLFloaterChat::getInstance(LLSD())->getChild<LLViewerTextEditor>("Chat History Editor with mute");
+ LLViewerTextEditor* history_editor = LLFloaterChat::getInstance()->getChild<LLViewerTextEditor>("Chat History Editor");
+ LLViewerTextEditor* history_editor_with_mute = LLFloaterChat::getInstance()->getChild<LLViewerTextEditor>("Chat History Editor with mute");
if (history_editor)
{
@@ -324,8 +280,7 @@ void LLFloaterChat::onClickMute(void *data)
LLMute mute(id);
mute.setFromDisplayName(name);
LLMuteList::getInstance()->add(mute);
-
- LLFloaterMute::showInstance();
+ LLFloaterReg::showInstance("mute");
}
//static
@@ -368,20 +323,6 @@ void LLFloaterChat::addChat(const LLChat& chat,
chat.mChatType == CHAT_TYPE_DEBUG_MSG
&& !gSavedSettings.getBOOL("ScriptErrorsAsChat");
-#if LL_LCD_COMPILE
- // add into LCD displays
- if (!invisible_script_debug_chat)
- {
- if (!from_instant_message)
- {
- AddNewChatToLCD(chat.mText);
- }
- else
- {
- AddNewIMToLCD(chat.mText);
- }
- }
-#endif
if (!invisible_script_debug_chat
&& !chat.mMuted
&& gConsole
@@ -390,33 +331,81 @@ void LLFloaterChat::addChat(const LLChat& chat,
F32 size = CHAT_MSG_SIZE;
if (chat.mSourceType == CHAT_SOURCE_SYSTEM)
{
- text_color = gSavedSettings.getColor("SystemChatColor");
+ text_color = LLUIColorTable::instance().getColor("SystemChatColor");
}
else if(from_instant_message)
{
- text_color = gSavedSettings.getColor("IMChatColor");
+ text_color = LLUIColorTable::instance().getColor("IMChatColor");
size = INSTANT_MSG_SIZE;
}
+ // Disabling the console for 2.0 - SJB
+#if 0
// We display anything if it's not an IM. If it's an IM, check pref...
if ( !from_instant_message || gSavedSettings.getBOOL("IMInChatConsole") )
{
gConsole->addLine(chat.mText, size, text_color);
}
+#endif
}
- if(from_instant_message && gSavedPerAccountSettings.getBOOL("LogChatIM"))
+ if(from_instant_message && (gSavedPerAccountSettings.getS32("IMLogOptions")== LOG_BOTH_TOGETHER))
log_chat_text(chat);
if(from_instant_message && gSavedSettings.getBOOL("IMInChatHistory"))
addChatHistory(chat,false);
- LLTextParser* highlight = LLTextParser::getInstance();
- highlight->triggerAlerts(gAgent.getID(), gAgent.getPositionGlobal(), chat.mText, gViewerWindow->getWindow());
+ triggerAlerts(chat.mText);
+
+ // Add the sender to the list of people with which we've recently interacted.
+ if(chat.mSourceType == CHAT_SOURCE_AGENT && chat.mFromID.notNull())
+ LLRecentPeople::instance().add(chat.mFromID);
if(!from_instant_message)
addChatHistory(chat);
}
+// Moved from lltextparser.cpp to break llui/llaudio library dependency.
+//static
+void LLFloaterChat::triggerAlerts(const std::string& text)
+{
+ LLTextParser* parser = LLTextParser::getInstance();
+// bool spoken=FALSE;
+ for (S32 i=0;i<parser->mHighlights.size();i++)
+ {
+ LLSD& highlight = parser->mHighlights[i];
+ if (parser->findPattern(text,highlight) >= 0 )
+ {
+ if(gAudiop)
+ {
+ if ((std::string)highlight["sound_lluuid"] != LLUUID::null.asString())
+ {
+ gAudiop->triggerSound(highlight["sound_lluuid"].asUUID(),
+ gAgent.getID(),
+ 1.f,
+ LLAudioEngine::AUDIO_TYPE_UI,
+ gAgent.getPositionGlobal() );
+ }
+/*
+ if (!spoken)
+ {
+ LLTextToSpeech* text_to_speech = NULL;
+ text_to_speech = LLTextToSpeech::getInstance();
+ spoken = text_to_speech->speak((LLString)highlight["voice"],text);
+ }
+ */
+ }
+ if (highlight["flash"])
+ {
+ LLWindow* viewer_window = gViewerWindow->getWindow();
+ if (viewer_window && viewer_window->getMinimized())
+ {
+ viewer_window->flashIcon(5.f);
+ }
+ }
+ }
+ }
+}
+
LLColor4 get_text_color(const LLChat& chat)
{
LLColor4 text_color;
@@ -430,37 +419,37 @@ LLColor4 get_text_color(const LLChat& chat)
switch(chat.mSourceType)
{
case CHAT_SOURCE_SYSTEM:
- text_color = gSavedSettings.getColor4("SystemChatColor");
+ text_color = LLUIColorTable::instance().getColor("SystemChatColor");
break;
case CHAT_SOURCE_AGENT:
if (chat.mFromID.isNull())
{
- text_color = gSavedSettings.getColor4("SystemChatColor");
+ text_color = LLUIColorTable::instance().getColor("SystemChatColor");
}
else
{
if(gAgent.getID() == chat.mFromID)
{
- text_color = gSavedSettings.getColor4("UserChatColor");
+ text_color = LLUIColorTable::instance().getColor("UserChatColor");
}
else
{
- text_color = gSavedSettings.getColor4("AgentChatColor");
+ text_color = LLUIColorTable::instance().getColor("AgentChatColor");
}
}
break;
case CHAT_SOURCE_OBJECT:
if (chat.mChatType == CHAT_TYPE_DEBUG_MSG)
{
- text_color = gSavedSettings.getColor4("ScriptErrorColor");
+ text_color = LLUIColorTable::instance().getColor("ScriptErrorColor");
}
else if ( chat.mChatType == CHAT_TYPE_OWNER )
{
- text_color = gSavedSettings.getColor4("llOwnerSayChatColor");
+ text_color = LLUIColorTable::instance().getColor("llOwnerSayChatColor");
}
else
{
- text_color = gSavedSettings.getColor4("ObjectChatColor");
+ text_color = LLUIColorTable::instance().getColor("ObjectChatColor");
}
break;
default:
@@ -485,7 +474,7 @@ LLColor4 get_text_color(const LLChat& chat)
//static
void LLFloaterChat::loadHistory()
{
- LLLogChat::loadHistory(std::string("chat"), &chatFromLogFile, (void *)LLFloaterChat::getInstance(LLSD()));
+ LLLogChat::loadHistory(std::string("chat"), &chatFromLogFile, (void *)LLFloaterChat::getInstance());
}
//static
@@ -501,6 +490,7 @@ void LLFloaterChat::chatFromLogFile(LLLogChat::ELogLineType type , std::string l
{
LLChat chat;
chat.mText = line;
+ get_text_color(chat);
addChatHistory(chat, FALSE);
}
break;
@@ -531,27 +521,9 @@ void LLFloaterChat::onClickToggleActiveSpeakers(void* userdata)
self->childSetVisible("active_speakers_panel", !self->childIsVisible("active_speakers_panel"));
}
-//static
-bool LLFloaterChat::visible(LLFloater* instance, const LLSD& key)
-{
- return VisibilityPolicy<LLFloater>::visible(instance, key);
-}
-
-//static
-void LLFloaterChat::show(LLFloater* instance, const LLSD& key)
-{
- VisibilityPolicy<LLFloater>::show(instance, key);
-}
-
-//static
-void LLFloaterChat::hide(LLFloater* instance, const LLSD& key)
-{
- if(instance->getHost())
- {
- LLFloaterChatterBox::hideInstance();
- }
- else
- {
- VisibilityPolicy<LLFloater>::hide(instance, key);
- }
-}
+//static
+ LLFloaterChat* LLFloaterChat::getInstance()
+ {
+ return LLFloaterReg::getTypedInstance<LLFloaterChat>("chat", LLSD()) ;
+
+ }
diff --git a/indra/newview/llfloaterchat.h b/indra/newview/llfloaterchat.h
index b5393866b8..6ba3165d6a 100644
--- a/indra/newview/llfloaterchat.h
+++ b/indra/newview/llfloaterchat.h
@@ -40,41 +40,41 @@
#include "llfloater.h"
#include "lllogchat.h"
-class LLButton;
+
class LLChat;
-class LLComboBox;
-class LLLineEditor;
-class LLViewerTextEditor;
-class LLMessageSystem;
-class LLUUID;
-class LLCheckBoxCtrl;
class LLPanelActiveSpeakers;
class LLLogChat;
-class LLFloaterChat
- : public LLFloater, public LLUISingleton<LLFloaterChat, LLFloaterChat>
+enum ELogOptions
+{
+ LOG_CHAT = 0,
+ LOG_IM = 1,
+ LOG_BOTH_TOGETHER = 2,
+ LOG_BOTH_SEPARATE = 3
+};
+
+class LLFloaterChat : public LLFloater
{
public:
LLFloaterChat(const LLSD& seed);
~LLFloaterChat();
- virtual void setVisible( BOOL b );
virtual void draw();
virtual BOOL postBuild();
- virtual void onClose(bool app_quitting);
- virtual void onVisibilityChange(BOOL cur_visibility);
- virtual void setMinimized(BOOL);
+
void updateConsoleVisibility();
static void setHistoryCursorAndScrollToEnd();
-
+
+ // *TODO:Skinning - move these to LLChat (or LLViewerChat?)
// Add chat to console and history list.
// Color based on source, type, distance.
static void addChat(const LLChat& chat, BOOL from_im = FALSE, BOOL local_agent = FALSE);
-
// Add chat to history alone.
static void addChatHistory(const LLChat& chat, bool log_to_file = true);
+ static void triggerAlerts(const std::string& text);
+
static void onClickMute(void *data);
static void onClickToggleShowMute(LLUICtrl* caller, void *data);
static void onClickToggleActiveSpeakers(void* userdata);
@@ -82,12 +82,9 @@ public:
static void loadHistory();
static void* createSpeakersPanel(void* data);
static void* createChatPanel(void* data);
-
- // visibility policy for LLUISingleton
- static bool visible(LLFloater* instance, const LLSD& key);
- static void show(LLFloater* instance, const LLSD& key);
- static void hide(LLFloater* instance, const LLSD& key);
-
+
+ static LLFloaterChat* getInstance(); // *TODO:Skinning Deprecate
+
LLPanelActiveSpeakers* mPanel;
BOOL mScrolledToEnd;
};
diff --git a/indra/newview/llfloaterchatterbox.cpp b/indra/newview/llfloaterchatterbox.cpp
index 0fa1aa15e6..05ea800d0e 100644
--- a/indra/newview/llfloaterchatterbox.cpp
+++ b/indra/newview/llfloaterchatterbox.cpp
@@ -35,6 +35,7 @@
#include "llviewerprecompiledheaders.h"
+#include "llfloaterreg.h"
#include "llfloaterchatterbox.h"
#include "lluictrlfactory.h"
#include "llfloaterchat.h"
@@ -49,12 +50,11 @@
//
LLFloaterMyFriends::LLFloaterMyFriends(const LLSD& seed)
+ : LLFloater(seed)
{
mFactoryMap["friends_panel"] = LLCallbackMap(LLFloaterMyFriends::createFriendsPanel, NULL);
mFactoryMap["groups_panel"] = LLCallbackMap(LLFloaterMyFriends::createGroupsPanel, NULL);
- // do not automatically open singleton floaters (as result of getInstance())
- BOOL no_open = FALSE;
- LLUICtrlFactory::getInstance()->buildFloater(this, "floater_my_friends.xml", &getFactoryMap(), no_open);
+ //Called from floater reg: LLUICtrlFactory::getInstance()->buildFloater(this, "floater_my_friends.xml");
}
LLFloaterMyFriends::~LLFloaterMyFriends()
@@ -63,15 +63,19 @@ LLFloaterMyFriends::~LLFloaterMyFriends()
BOOL LLFloaterMyFriends::postBuild()
{
- mTabs = getChild<LLTabContainer>("friends_and_groups");
-
return TRUE;
}
-
-void LLFloaterMyFriends::onClose(bool app_quitting)
+void LLFloaterMyFriends::onOpen(const LLSD& key)
{
- setVisible(FALSE);
+ if (key.asString() == "friends")
+ {
+ childShowTab("friends_and_groups", "friends_panel");
+ }
+ else if (key.asString() == "groups")
+ {
+ childShowTab("friends_and_groups", "groups_panel");
+ }
}
//static
@@ -86,47 +90,67 @@ void* LLFloaterMyFriends::createGroupsPanel(void* data)
return new LLPanelGroups();
}
+//static
+LLFloaterMyFriends* LLFloaterMyFriends::getInstance()
+{
+ return LLFloaterReg::getTypedInstance<LLFloaterMyFriends>("contacts", "friends") ;
+}
+
//
// LLFloaterChatterBox
//
-LLFloaterChatterBox::LLFloaterChatterBox(const LLSD& seed) :
+LLFloaterChatterBox::LLFloaterChatterBox(const LLSD& seed)
+: LLMultiFloater(seed),
mActiveVoiceFloater(NULL)
{
mAutoResize = FALSE;
- LLUICtrlFactory::getInstance()->buildFloater(this, "floater_chatterbox.xml", NULL, FALSE);
+ //Called from floater reg: LLUICtrlFactory::getInstance()->buildFloater(this, "floater_chatterbox.xml", FALSE);
+}
+
+LLFloaterChatterBox::~LLFloaterChatterBox()
+{
+}
+
+BOOL LLFloaterChatterBox::postBuild()
+{
+ mVisibleSignal.connect(boost::bind(&LLFloaterChatterBox::onVisibilityChange, this, _2));
+
if (gSavedSettings.getBOOL("ContactsTornOff"))
{
- LLFloaterMyFriends* floater_contacts = LLFloaterMyFriends::getInstance(0);
- // add then remove to set up relationship for re-attach
- addFloater(floater_contacts, FALSE);
- removeFloater(floater_contacts);
- // reparent to floater view
- gFloaterView->addChild(floater_contacts);
+ LLFloaterMyFriends* floater_contacts = LLFloaterMyFriends::getInstance();
+ if(floater_contacts)
+ {
+ // add then remove to set up relationship for re-attach
+ addFloater(floater_contacts, FALSE);
+ removeFloater(floater_contacts);
+ // reparent to floater view
+ gFloaterView->addChild(floater_contacts);
+ }
}
else
{
- addFloater(LLFloaterMyFriends::getInstance(0), TRUE);
+ addFloater(LLFloaterMyFriends::getInstance(), TRUE);
}
if (gSavedSettings.getBOOL("ChatHistoryTornOff"))
{
LLFloaterChat* floater_chat = LLFloaterChat::getInstance();
- // add then remove to set up relationship for re-attach
- addFloater(floater_chat, FALSE);
- removeFloater(floater_chat);
- // reparent to floater view
- gFloaterView->addChild(floater_chat);
+ if(floater_chat)
+ {
+ // add then remove to set up relationship for re-attach
+ addFloater(floater_chat, FALSE);
+ removeFloater(floater_chat);
+ // reparent to floater view
+ gFloaterView->addChild(floater_chat);
+ }
}
else
{
- addFloater(LLFloaterChat::getInstance(LLSD()), FALSE);
+ addFloater(LLFloaterChat::getInstance(), FALSE);
}
mTabContainer->lockTabs();
-}
-
-LLFloaterChatterBox::~LLFloaterChatterBox()
-{
+ return TRUE;
}
BOOL LLFloaterChatterBox::handleKeyHere(KEY key, MASK mask)
@@ -139,13 +163,13 @@ BOOL LLFloaterChatterBox::handleKeyHere(KEY key, MASK mask)
{
if (floater->isCloseable())
{
- floater->close();
+ floater->closeFloater();
}
else
{
// close chatterbox window if frontmost tab is reserved, non-closeable tab
// such as contacts or near me
- close();
+ closeFloater();
}
}
return TRUE;
@@ -200,26 +224,38 @@ void LLFloaterChatterBox::draw()
LLMultiFloater::draw();
}
-void LLFloaterChatterBox::onOpen()
+void LLFloaterChatterBox::onOpen(const LLSD& key)
{
- gSavedSettings.setBOOL("ShowCommunicate", TRUE);
-}
-
-void LLFloaterChatterBox::onClose(bool app_quitting)
-{
- setVisible(FALSE);
- gSavedSettings.setBOOL("ShowCommunicate", FALSE);
+ //*TODO:Skinning show the session id associated with key
+ if (key.asString() == "local")
+ {
+ LLFloaterChat* chat = LLFloaterReg::findTypedInstance<LLFloaterChat>("chat");
+ chat->openFloater();
+ }
+ else if (key.isDefined())
+ {
+ LLFloaterIMPanel* impanel = gIMMgr->findFloaterBySession(key.asUUID());
+ if (impanel)
+ {
+ impanel->openFloater();
+ }
+ }
}
-void LLFloaterChatterBox::setMinimized(BOOL minimized)
+void LLFloaterChatterBox::onVisibilityChange ( const LLSD& new_visibility )
{
- LLFloater::setMinimized(minimized);
// HACK: potentially need to toggle console
- LLFloaterChat::getInstance()->updateConsoleVisibility();
+ LLFloaterChat* instance = LLFloaterChat::getInstance();
+ if(instance)
+ {
+ instance->updateConsoleVisibility();
+ }
}
void LLFloaterChatterBox::removeFloater(LLFloater* floaterp)
{
+ if(!floaterp) return;
+
if (floaterp->getName() == "chat floater")
{
// only my friends floater now locked
@@ -241,10 +277,16 @@ void LLFloaterChatterBox::addFloater(LLFloater* floaterp,
BOOL select_added_floater,
LLTabContainer::eInsertionPoint insertion_point)
{
+ if(!floaterp) return;
+
S32 num_locked_tabs = mTabContainer->getNumLockedTabs();
// already here
- if (floaterp->getHost() == this) return;
+ if (floaterp->getHost() == this)
+ {
+ openFloater(floaterp->getKey());
+ return;
+ }
// make sure my friends and chat history both locked when re-attaching chat history
if (floaterp->getName() == "chat floater")
@@ -281,6 +323,7 @@ void LLFloaterChatterBox::addFloater(LLFloater* floaterp,
else
{
LLMultiFloater::addFloater(floaterp, select_added_floater, insertion_point);
+ // openFloater(floaterp->getKey());
}
// make sure active voice icon shows up for new tab
@@ -290,6 +333,12 @@ void LLFloaterChatterBox::addFloater(LLFloater* floaterp,
}
}
+//static
+LLFloaterChatterBox* LLFloaterChatterBox::getInstance()
+{
+ return LLFloaterReg::getTypedInstance<LLFloaterChatterBox>("communicate", LLSD()) ;
+}
+
//static
LLFloater* LLFloaterChatterBox::getCurrentVoiceFloater()
{
@@ -300,11 +349,12 @@ LLFloater* LLFloaterChatterBox::getCurrentVoiceFloater()
if (LLVoiceChannelProximal::getInstance() == LLVoiceChannel::getCurrentVoiceChannel())
{
// show near me tab if in proximal channel
- return LLFloaterChat::getInstance(LLSD());
+ return LLFloaterChat::getInstance();
}
else
{
- LLFloaterChatterBox* floater = LLFloaterChatterBox::getInstance(LLSD());
+ LLFloaterChatterBox* floater = LLFloaterChatterBox::getInstance();
+ if(!floater) return NULL;
// iterator over all IM tabs (skip friends and near me)
for (S32 i = 0; i < floater->getFloaterCount(); i++)
{
diff --git a/indra/newview/llfloaterchatterbox.h b/indra/newview/llfloaterchatterbox.h
index 3adbd14370..3929e6e36c 100644
--- a/indra/newview/llfloaterchatterbox.h
+++ b/indra/newview/llfloaterchatterbox.h
@@ -42,125 +42,45 @@
class LLTabContainer;
-class LLFloaterChatterBox : public LLMultiFloater, public LLUISingleton<LLFloaterChatterBox, LLFloaterChatterBox>
+class LLFloaterChatterBox : public LLMultiFloater
{
public:
LLFloaterChatterBox(const LLSD& seed);
virtual ~LLFloaterChatterBox();
-
+
+ /*virtual*/ BOOL postBuild();
/*virtual*/ BOOL handleKeyHere(KEY key, MASK mask);
/*virtual*/ void draw();
- /*virtual*/ void onOpen();
- /*virtual*/ void onClose(bool app_quitting);
- /*virtual*/ void setMinimized(BOOL minimized);
+ /*virtual*/ void onOpen(const LLSD& key);
/*virtual*/ void removeFloater(LLFloater* floaterp);
/*virtual*/ void addFloater(LLFloater* floaterp,
BOOL select_added_floater,
LLTabContainer::eInsertionPoint insertion_point = LLTabContainer::END);
+ static LLFloaterChatterBox* getInstance(); // *TODO:Skinning Deprecate
static LLFloater* getCurrentVoiceFloater();
- // visibility policy for LLUISingleton
- static bool visible(LLFloater* instance, const LLSD& key)
- {
- LLFloater* floater_to_check = ((LLFloaterChatterBox*)instance)->getFloater(key);
-
- if (floater_to_check)
- {
- return floater_to_check->isInVisibleChain();
- }
-
- // otherwise use default visibility rule for chatterbox
- return VisibilityPolicy<LLFloater>::visible(instance, key);
- }
-
- static void show(LLFloater* instance, const LLSD& key)
- {
- LLFloater* floater_to_show = ((LLFloaterChatterBox*)instance)->getFloater(key);
- VisibilityPolicy<LLFloater>::show(instance, key);
-
- if (floater_to_show)
- {
- floater_to_show->open();
- }
- }
-
- static void hide(LLFloater* instance, const LLSD& key)
- {
- VisibilityPolicy<LLFloater>::hide(instance, key);
- }
-
-private:
- LLFloater* getFloater(const LLSD& key)
- {
- LLFloater* floater = NULL;
-
- //try to show requested session
- LLUUID session_id = key.asUUID();
- if (session_id.notNull())
- {
- floater = LLIMMgr::getInstance()->findFloaterBySession(session_id);
- }
-
- // if TRUE, show tab for active voice channel, otherwise, just show last tab
- if (key.asBoolean())
- {
- floater = getCurrentVoiceFloater();
- }
-
- return floater;
- }
-
protected:
+ void onVisibilityChange ( const LLSD& new_visibility );
+
LLFloater* mActiveVoiceFloater;
};
-class LLFloaterMyFriends : public LLFloater, public LLUISingleton<LLFloaterMyFriends, LLFloaterMyFriends>
+class LLFloaterMyFriends : public LLFloater
{
public:
LLFloaterMyFriends(const LLSD& seed);
virtual ~LLFloaterMyFriends();
- virtual BOOL postBuild();
-
- void onClose(bool app_quitting);
+ /*virtual*/ BOOL postBuild();
+ /*virtual*/ void onOpen(const LLSD& key);
+ static LLFloaterMyFriends* getInstance(); // *TODO:Skinning Deprecate
+
static void* createFriendsPanel(void* data);
static void* createGroupsPanel(void* data);
-
- // visibility policy for LLUISingleton
- static bool visible(LLFloater* instance, const LLSD& key)
- {
- LLFloaterMyFriends* floaterp = (LLFloaterMyFriends*)instance;
- return floaterp->isInVisibleChain() && floaterp->mTabs->getCurrentPanelIndex() == key.asInteger();
- }
-
- static void show(LLFloater* instance, const LLSD& key)
- {
- VisibilityPolicy<LLFloater>::show(instance, key);
- // garbage values in id will be interpreted as 0, or the friends tab
- ((LLFloaterMyFriends*)instance)->mTabs->selectTab(key);
- }
-
- static void hide(LLFloater* instance, const LLSD& key)
- {
- if (visible(instance, key))
- {
- if(instance->getHost())
- {
- LLFloaterChatterBox::hideInstance();
- }
- else
- {
- VisibilityPolicy<LLFloater>::hide(instance, key);
- }
- }
- }
-
-protected:
- LLTabContainer* mTabs;
};
#endif // LL_LLFLOATERCHATTERBOX_H
diff --git a/indra/newview/llfloatercolorpicker.cpp b/indra/newview/llfloatercolorpicker.cpp
index f82d692dd3..8e385fca78 100644
--- a/indra/newview/llfloatercolorpicker.cpp
+++ b/indra/newview/llfloatercolorpicker.cpp
@@ -32,11 +32,15 @@
#include "llviewerprecompiledheaders.h"
-#include <sstream>
-#include <iomanip>
-
#include "llfloatercolorpicker.h"
+// Viewer project includes
+#include "lltoolmgr.h"
+#include "lltoolpipette.h"
+#include "llviewercontrol.h"
+#include "llworld.h"
+
+// Linden library includes
#include "llfontgl.h"
#include "llsys.h"
#include "llgl.h"
@@ -47,23 +51,22 @@
#include "lllineeditor.h"
#include "v4coloru.h"
#include "llbutton.h"
-#include "llviewercontrol.h"
#include "lluictrlfactory.h"
-#include "llviewerwindow.h"
#include "llgl.h"
-#include "llmemory.h"
+#include "llpointer.h"
#include "llimage.h"
#include "llmousehandler.h"
-#include "llimagegl.h"
#include "llglheaders.h"
#include "llcheckboxctrl.h"
-#include "llworld.h"
#include "lltextbox.h"
#include "lluiconstants.h"
#include "llfocusmgr.h"
-#include "lltoolmgr.h"
-#include "lltoolpipette.h"
#include "lldraghandle.h"
+#include "llwindow.h"
+
+// System includes
+#include <sstream>
+#include <iomanip>
const F32 CONTEXT_CONE_IN_ALPHA = 0.0f;
const F32 CONTEXT_CONE_OUT_ALPHA = 1.f;
@@ -75,11 +78,8 @@ const F32 CONTEXT_FADE_TIME = 0.08f;
//
//////////////////////////////////////////////////////////////////////////////
-//////////////////////////////////////////////////////////////////////////////
-// default ctor
-LLFloaterColorPicker::
-LLFloaterColorPicker (LLColorSwatchCtrl* swatch, BOOL show_apply_immediate )
- : LLFloater (std::string("Color Picker Floater")),
+LLFloaterColorPicker::LLFloaterColorPicker (LLColorSwatchCtrl* swatch, BOOL show_apply_immediate )
+ : LLFloater(LLSD()),
mComponents ( 3 ),
mMouseDownInLumRegion ( FALSE ),
mMouseDownInHueRegion ( FALSE ),
@@ -113,6 +113,9 @@ LLFloaterColorPicker (LLColorSwatchCtrl* swatch, BOOL show_apply_immediate )
mCanApplyImmediately ( show_apply_immediate ),
mContextConeOpacity ( 0.f )
{
+ // build the majority of the gui using the factory builder
+ LLUICtrlFactory::getInstance()->buildFloater ( this, "floater_color_picker.xml", NULL );
+
// create user interface for this picker
createUI ();
@@ -123,10 +126,7 @@ LLFloaterColorPicker (LLColorSwatchCtrl* swatch, BOOL show_apply_immediate )
}
}
-//////////////////////////////////////////////////////////////////////////////
-// dtor
-LLFloaterColorPicker::
-~LLFloaterColorPicker()
+LLFloaterColorPicker::~LLFloaterColorPicker()
{
// destroy the UI we created
destroyUI ();
@@ -134,14 +134,8 @@ LLFloaterColorPicker::
//////////////////////////////////////////////////////////////////////////////
//
-void
-LLFloaterColorPicker::
-createUI ()
+void LLFloaterColorPicker::createUI ()
{
- // build the majority of the gui using the factory builder
- LLUICtrlFactory::getInstance()->buildFloater ( this, "floater_color_picker.xml" );
- setVisible ( FALSE );
-
// create RGB type area (not really RGB but it's got R,G & B in it.,..
LLPointer<LLImageRaw> raw = new LLImageRaw ( mRGBViewerImageWidth, mRGBViewerImageHeight, mComponents );
@@ -165,7 +159,7 @@ createUI ()
* ( bits + x + y * linesize + 2 ) = ( U8 )( bVal * 255.0f );
}
}
- mRGBImage = new LLImageGL ( (LLImageRaw*)raw, FALSE );
+ mRGBImage = LLViewerTextureManager::getLocalTexture( (LLImageRaw*)raw, FALSE );
gGL.getTexUnit(0)->bind(mRGBImage);
mRGBImage->setAddressMode(LLTexUnit::TAM_CLAMP);
@@ -177,19 +171,17 @@ createUI ()
// argh!
const std::string s ( codec.str () );
- mPalette.push_back ( new LLColor4 ( gSavedSettings.getColor4 ( s ) ) );
+ mPalette.push_back ( new LLColor4 ( LLUIColorTable::instance().getColor ( s ) ) );
}
}
//////////////////////////////////////////////////////////////////////////////
//
-void
-LLFloaterColorPicker::
-showUI ()
+void LLFloaterColorPicker::showUI ()
{
setVisible ( TRUE );
setFocus ( TRUE );
- open(); /*Flawfinder: ignore*/
+ openFloater(getKey());
// HACK: if system color picker is required - close the SL one we made and use default system dialog
if ( gSavedSettings.getBOOL ( "UseDefaultColorPicker" ) )
@@ -203,7 +195,7 @@ showUI ()
{
LLColor4 curCol = swatch->get ();
send_agent_pause();
- gViewerWindow->getWindow ()->dialog_color_picker ( &curCol [ 0 ], &curCol [ 1 ], &curCol [ 2 ] );
+ getWindow()->dialogColorPicker( &curCol [ 0 ], &curCol [ 1 ], &curCol [ 2 ] );
send_agent_resume();
setOrigRgb ( curCol [ 0 ], curCol [ 1 ], curCol [ 2 ] );
@@ -212,36 +204,30 @@ showUI ()
LLColorSwatchCtrl::onColorChanged ( swatch, LLColorSwatchCtrl::COLOR_CHANGE );
}
- close();
+ closeFloater();
}
}
//////////////////////////////////////////////////////////////////////////////
// called after the dialog is rendered
-BOOL
-LLFloaterColorPicker::
-postBuild()
+BOOL LLFloaterColorPicker::postBuild()
{
mCancelBtn = getChild<LLButton>( "cancel_btn" );
- mCancelBtn->setClickedCallback ( onClickCancel );
- mCancelBtn->setCallbackUserData ( this );
+ mCancelBtn->setClickedCallback ( onClickCancel, this );
mSelectBtn = getChild<LLButton>( "select_btn");
- mSelectBtn->setClickedCallback ( onClickSelect );
- mSelectBtn->setCallbackUserData ( this );
+ mSelectBtn->setClickedCallback ( onClickSelect, this );
mSelectBtn->setFocus ( TRUE );
mPipetteBtn = getChild<LLButton>("color_pipette" );
mPipetteBtn->setImages(std::string("eye_button_inactive.tga"), std::string("eye_button_active.tga"));
- mPipetteBtn->setClickedCallback( onClickPipette );
- mPipetteBtn->setCallbackUserData ( this );
+ mPipetteBtn->setCommitCallback( boost::bind(&LLFloaterColorPicker::onClickPipette, this ));
mApplyImmediateCheck = getChild<LLCheckBoxCtrl>("apply_immediate");
mApplyImmediateCheck->set(gSavedSettings.getBOOL("ApplyColorImmediately"));
- mApplyImmediateCheck->setCommitCallback(onImmediateCheck);
- mApplyImmediateCheck->setCallbackUserData(this);
+ mApplyImmediateCheck->setCommitCallback(onImmediateCheck, this);
childSetCommitCallback("rspin", onTextCommit, (void*)this );
childSetCommitCallback("gspin", onTextCommit, (void*)this );
@@ -250,18 +236,15 @@ postBuild()
childSetCommitCallback("sspin", onTextCommit, (void*)this );
childSetCommitCallback("lspin", onTextCommit, (void*)this );
+ LLToolPipette::getInstance()->setToolSelectCallback(boost::bind(&LLFloaterColorPicker::onColorSelect, this, _1));
+
return TRUE;
}
//////////////////////////////////////////////////////////////////////////////
//
-void
-LLFloaterColorPicker::
-initUI ( F32 rValIn, F32 gValIn, F32 bValIn )
+void LLFloaterColorPicker::initUI ( F32 rValIn, F32 gValIn, F32 bValIn )
{
- // start catching lose-focus events from entry widgets
- enableTextCallbacks ( TRUE );
-
// under some circumstances, we get rogue values that can be calmed by clamping...
rValIn = llclamp ( rValIn, 0.0f, 1.0f );
gValIn = llclamp ( gValIn, 0.0f, 1.0f );
@@ -279,9 +262,7 @@ initUI ( F32 rValIn, F32 gValIn, F32 bValIn )
//////////////////////////////////////////////////////////////////////////////
//
-void
-LLFloaterColorPicker::
-destroyUI ()
+void LLFloaterColorPicker::destroyUI ()
{
// shut down pipette tool if active
stopUsingPipette();
@@ -305,9 +286,7 @@ destroyUI ()
//////////////////////////////////////////////////////////////////////////////
//
-F32
-LLFloaterColorPicker::
-hueToRgb ( F32 val1In, F32 val2In, F32 valHUeIn )
+F32 LLFloaterColorPicker::hueToRgb ( F32 val1In, F32 val2In, F32 valHUeIn )
{
if ( valHUeIn < 0.0f ) valHUeIn += 1.0f;
if ( valHUeIn > 1.0f ) valHUeIn -= 1.0f;
@@ -319,9 +298,7 @@ hueToRgb ( F32 val1In, F32 val2In, F32 valHUeIn )
//////////////////////////////////////////////////////////////////////////////
//
-void
-LLFloaterColorPicker::
-hslToRgb ( F32 hValIn, F32 sValIn, F32 lValIn, F32& rValOut, F32& gValOut, F32& bValOut )
+void LLFloaterColorPicker::hslToRgb ( F32 hValIn, F32 sValIn, F32 lValIn, F32& rValOut, F32& gValOut, F32& bValOut )
{
if ( sValIn < 0.00001f )
{
@@ -349,9 +326,7 @@ hslToRgb ( F32 hValIn, F32 sValIn, F32 lValIn, F32& rValOut, F32& gValOut, F32&
//////////////////////////////////////////////////////////////////////////////
// mutator for original RGB value
-void
-LLFloaterColorPicker::
-setOrigRgb ( F32 origRIn, F32 origGIn, F32 origBIn )
+void LLFloaterColorPicker::setOrigRgb ( F32 origRIn, F32 origGIn, F32 origBIn )
{
origR = origRIn;
origG = origGIn;
@@ -360,9 +335,7 @@ setOrigRgb ( F32 origRIn, F32 origGIn, F32 origBIn )
//////////////////////////////////////////////////////////////////////////////
// accessor for original RGB value
-void
-LLFloaterColorPicker::
-getOrigRgb ( F32& origROut, F32& origGOut, F32& origBOut )
+void LLFloaterColorPicker::getOrigRgb ( F32& origROut, F32& origGOut, F32& origBOut )
{
origROut = origR;
origGOut = origG;
@@ -371,9 +344,7 @@ getOrigRgb ( F32& origROut, F32& origGOut, F32& origBOut )
//////////////////////////////////////////////////////////////////////////////
// mutator for current RGB value
-void
-LLFloaterColorPicker::
-setCurRgb ( F32 curRIn, F32 curGIn, F32 curBIn )
+void LLFloaterColorPicker::setCurRgb ( F32 curRIn, F32 curGIn, F32 curBIn )
{
// save current RGB
curR = curRIn;
@@ -383,19 +354,13 @@ setCurRgb ( F32 curRIn, F32 curGIn, F32 curBIn )
// update corresponding HSL values and
LLColor3(curRIn, curGIn, curBIn).calcHSL(&curH, &curS, &curL);
- // color changed so update text fields (fixes SL-16968)
- // HACK: turn off the call back wilst we update the text or we recurse ourselves into oblivion
- // CP: this was required when I first wrote the code but this may not be necessary anymore - leaving it there just in case
- enableTextCallbacks( FALSE );
+ // color changed so update text fields
updateTextEntry();
- enableTextCallbacks( TRUE );
}
//////////////////////////////////////////////////////////////////////////////
// accessor for current RGB value
-void
-LLFloaterColorPicker::
-getCurRgb ( F32& curROut, F32& curGOut, F32& curBOut )
+void LLFloaterColorPicker::getCurRgb ( F32& curROut, F32& curGOut, F32& curBOut )
{
curROut = curR;
curGOut = curG;
@@ -404,9 +369,7 @@ getCurRgb ( F32& curROut, F32& curGOut, F32& curBOut )
//////////////////////////////////////////////////////////////////////////////
// mutator for current HSL value
-void
-LLFloaterColorPicker::
-setCurHsl ( F32 curHIn, F32 curSIn, F32 curLIn )
+void LLFloaterColorPicker::setCurHsl ( F32 curHIn, F32 curSIn, F32 curLIn )
{
// save current HSL
curH = curHIn;
@@ -419,9 +382,7 @@ setCurHsl ( F32 curHIn, F32 curSIn, F32 curLIn )
//////////////////////////////////////////////////////////////////////////////
// accessor for current HSL value
-void
-LLFloaterColorPicker::
-getCurHsl ( F32& curHOut, F32& curSOut, F32& curLOut )
+void LLFloaterColorPicker::getCurHsl ( F32& curHOut, F32& curSOut, F32& curLOut )
{
curHOut = curH;
curSOut = curS;
@@ -430,9 +391,7 @@ getCurHsl ( F32& curHOut, F32& curSOut, F32& curLOut )
//////////////////////////////////////////////////////////////////////////////
// called when 'cancel' clicked
-void
-LLFloaterColorPicker::
-onClickCancel ( void* data )
+void LLFloaterColorPicker::onClickCancel ( void* data )
{
if (data)
{
@@ -441,16 +400,14 @@ onClickCancel ( void* data )
if ( self )
{
self->cancelSelection ();
- self->close();
+ self->closeFloater();
}
}
}
//////////////////////////////////////////////////////////////////////////////
// called when 'select' clicked
-void
-LLFloaterColorPicker::
-onClickSelect ( void* data )
+void LLFloaterColorPicker::onClickSelect ( void* data )
{
if (data)
{
@@ -460,36 +417,28 @@ onClickSelect ( void* data )
{
// apply to selection
LLColorSwatchCtrl::onColorChanged ( self->getSwatch (), LLColorSwatchCtrl::COLOR_SELECT );
- self->close();
+ self->closeFloater();
}
}
}
-void LLFloaterColorPicker::onClickPipette( void* data )
+void LLFloaterColorPicker::onClickPipette( )
{
- LLFloaterColorPicker* self = ( LLFloaterColorPicker* )data;
-
- if ( self)
+ BOOL pipette_active = mPipetteBtn->getToggleState();
+ pipette_active = !pipette_active;
+ if (pipette_active)
{
- BOOL pipette_active = self->mPipetteBtn->getToggleState();
- pipette_active = !pipette_active;
- if (pipette_active)
- {
- LLToolPipette::getInstance()->setSelectCallback(onColorSelect, self);
- LLToolMgr::getInstance()->setTransientTool(LLToolPipette::getInstance());
- }
- else
- {
- LLToolMgr::getInstance()->clearTransientTool();
- }
+ LLToolMgr::getInstance()->setTransientTool(LLToolPipette::getInstance());
+ }
+ else
+ {
+ LLToolMgr::getInstance()->clearTransientTool();
}
}
//////////////////////////////////////////////////////////////////////////////
// called when 'text is committed' - i,e. focus moves from a text field
-void
-LLFloaterColorPicker::
-onTextCommit ( LLUICtrl* ctrl, void* data )
+void LLFloaterColorPicker::onTextCommit ( LLUICtrl* ctrl, void* data )
{
if ( data )
{
@@ -515,16 +464,12 @@ void LLFloaterColorPicker::onImmediateCheck( LLUICtrl* ctrl, void* data)
}
}
-void LLFloaterColorPicker::onColorSelect( const LLTextureEntry& te, void *data )
+void LLFloaterColorPicker::onColorSelect( const LLTextureEntry& te )
{
- LLFloaterColorPicker* self = (LLFloaterColorPicker*)data;
- if (self)
+ setCurRgb(te.getColor().mV[VRED], te.getColor().mV[VGREEN], te.getColor().mV[VBLUE]);
+ if (mApplyImmediateCheck->get())
{
- self->setCurRgb(te.getColor().mV[VRED], te.getColor().mV[VGREEN], te.getColor().mV[VBLUE]);
- if (self->mApplyImmediateCheck->get())
- {
- LLColorSwatchCtrl::onColorChanged ( self->getSwatch (), LLColorSwatchCtrl::COLOR_CHANGE );
- }
+ LLColorSwatchCtrl::onColorChanged ( getSwatch (), LLColorSwatchCtrl::COLOR_CHANGE );
}
}
@@ -673,9 +618,7 @@ void LLFloaterColorPicker::draw()
//////////////////////////////////////////////////////////////////////////////
// find a complimentary color to the one passed in that can be used to highlight
-const LLColor4&
-LLFloaterColorPicker::
-getComplimentaryColor ( const LLColor4& backgroundColor )
+const LLColor4& LLFloaterColorPicker::getComplimentaryColor ( const LLColor4& backgroundColor )
{
// going to base calculation on luminance
F32 hVal, sVal, lVal;
@@ -695,9 +638,7 @@ getComplimentaryColor ( const LLColor4& backgroundColor )
//////////////////////////////////////////////////////////////////////////////
// draw color palette
-void
-LLFloaterColorPicker::
-drawPalette ()
+void LLFloaterColorPicker::drawPalette ()
{
S32 curEntry = 0;
@@ -748,9 +689,7 @@ drawPalette ()
//////////////////////////////////////////////////////////////////////////////
// update text entry values for RGB/HSL (can't be done in ::draw () since this overwrites input
-void
-LLFloaterColorPicker::
-updateTextEntry ()
+void LLFloaterColorPicker::updateTextEntry ()
{
// set values in spinners
childSetValue("rspin", ( getCurR () * 255.0f ) );
@@ -762,37 +701,8 @@ updateTextEntry ()
}
//////////////////////////////////////////////////////////////////////////////
-// turns on or off text entry commit call backs
-void
-LLFloaterColorPicker::
-enableTextCallbacks ( BOOL stateIn )
-{
- if ( stateIn )
- {
- childSetCommitCallback("rspin", onTextCommit, (void*)this );
- childSetCommitCallback("gspin", onTextCommit, (void*)this );
- childSetCommitCallback("bspin", onTextCommit, (void*)this );
- childSetCommitCallback("hspin", onTextCommit, (void*)this );
- childSetCommitCallback("sspin", onTextCommit, (void*)this );
- childSetCommitCallback("lspin", onTextCommit, (void*)this );
- }
- else
- {
- childSetCommitCallback("rspin", 0, (void*)this );
- childSetCommitCallback("gspin", 0, (void*)this );
- childSetCommitCallback("bspin", 0, (void*)this );
- childSetCommitCallback("hspin", 0, (void*)this );
- childSetCommitCallback("sspin", 0, (void*)this );
- childSetCommitCallback("lspin", 0, (void*)this );
- }
-}
-
-
-//////////////////////////////////////////////////////////////////////////////
//
-void
-LLFloaterColorPicker::
-onTextEntryChanged ( LLUICtrl* ctrl )
+void LLFloaterColorPicker::onTextEntryChanged ( LLUICtrl* ctrl )
{
// value in RGB boxes changed
std::string name = ctrl->getName();
@@ -821,10 +731,7 @@ onTextEntryChanged ( LLUICtrl* ctrl )
// update current RGB (and implicitly HSL)
setCurRgb ( rVal, gVal, bVal );
- // HACK: turn off the call back wilst we update the text or we recurse ourselves into oblivion
- enableTextCallbacks ( FALSE );
updateTextEntry ();
- enableTextCallbacks ( TRUE );
}
else
// value in HSL boxes changed
@@ -847,10 +754,7 @@ onTextEntryChanged ( LLUICtrl* ctrl )
// update current HSL (and implicitly RGB)
setCurHsl ( hVal, sVal, lVal );
- // HACK: turn off the call back wilst we update the text or we recurse ourselves into oblivion
- enableTextCallbacks ( FALSE );
updateTextEntry ();
- enableTextCallbacks ( TRUE );
}
if (mApplyImmediateCheck->get())
@@ -861,9 +765,7 @@ onTextEntryChanged ( LLUICtrl* ctrl )
//////////////////////////////////////////////////////////////////////////////
//
-BOOL
-LLFloaterColorPicker::
-updateRgbHslFromPoint ( S32 xPosIn, S32 yPosIn )
+BOOL LLFloaterColorPicker::updateRgbHslFromPoint ( S32 xPosIn, S32 yPosIn )
{
if ( xPosIn >= mRGBViewerImageLeft &&
xPosIn <= mRGBViewerImageLeft + mRGBViewerImageWidth &&
@@ -899,9 +801,7 @@ updateRgbHslFromPoint ( S32 xPosIn, S32 yPosIn )
//////////////////////////////////////////////////////////////////////////////
//
-BOOL
-LLFloaterColorPicker::
-handleMouseDown ( S32 x, S32 y, MASK mask )
+BOOL LLFloaterColorPicker::handleMouseDown ( S32 x, S32 y, MASK mask )
{
// make it the frontmost
gFloaterView->bringToFront(this);
@@ -987,10 +887,7 @@ handleMouseDown ( S32 x, S32 y, MASK mask )
LLColorSwatchCtrl::onColorChanged ( getSwatch (), LLColorSwatchCtrl::COLOR_CHANGE );
}
- // HACK: turn off the call back wilst we update the text or we recurse ourselves into oblivion
- enableTextCallbacks ( FALSE );
updateTextEntry ();
- enableTextCallbacks ( TRUE );
}
return TRUE;
@@ -1003,9 +900,7 @@ handleMouseDown ( S32 x, S32 y, MASK mask )
//////////////////////////////////////////////////////////////////////////////
//
-BOOL
-LLFloaterColorPicker::
-handleHover ( S32 x, S32 y, MASK mask )
+BOOL LLFloaterColorPicker::handleHover ( S32 x, S32 y, MASK mask )
{
// if we're the front most window
if ( isFrontmost () )
@@ -1071,19 +966,9 @@ handleHover ( S32 x, S32 y, MASK mask )
return LLFloater::handleHover ( x, y, mask );
}
-void LLFloaterColorPicker::onClose(bool app_quitting)
-{
- //RN: this is consistent with texture picker in that closing the window leaves the current selection
- // to change this to "close to cancel", uncomment the following line
- //cancelSelection();
- LLFloater::onClose(app_quitting);
-}
-
//////////////////////////////////////////////////////////////////////////////
// reverts state once mouse button is released
-BOOL
-LLFloaterColorPicker::
-handleMouseUp ( S32 x, S32 y, MASK mask )
+BOOL LLFloaterColorPicker::handleMouseUp ( S32 x, S32 y, MASK mask )
{
getWindow()->setCursor ( UI_CURSOR_ARROW );
@@ -1130,7 +1015,7 @@ handleMouseUp ( S32 x, S32 y, MASK mask )
std::ostringstream codec;
codec << "ColorPaletteEntry" << std::setfill ( '0' ) << std::setw ( 2 ) << curEntry + 1;
const std::string s ( codec.str () );
- gSavedSettings.setColor4( s, *mPalette [ curEntry ] );
+ LLUIColorTable::instance().setColor(s, *mPalette [ curEntry ] );
}
}
@@ -1158,16 +1043,11 @@ handleMouseUp ( S32 x, S32 y, MASK mask )
//////////////////////////////////////////////////////////////////////////////
// cancel current color selection, revert to original and close picker
-void
-LLFloaterColorPicker::
-cancelSelection ()
+void LLFloaterColorPicker::cancelSelection ()
{
// restore the previous color selection
setCurRgb ( getOrigR (), getOrigG (), getOrigB () );
- // we're going away and when we do and the entry widgets lose focus, they do bad things so turn them off
- enableTextCallbacks ( FALSE );
-
// update in world item with original color via current swatch
LLColorSwatchCtrl::onColorChanged( getSwatch(), LLColorSwatchCtrl::COLOR_CANCEL );
diff --git a/indra/newview/llfloatercolorpicker.h b/indra/newview/llfloatercolorpicker.h
index 7c8d36a7c7..a16cde7f10 100644
--- a/indra/newview/llfloatercolorpicker.h
+++ b/indra/newview/llfloatercolorpicker.h
@@ -36,7 +36,7 @@
#include <vector>
#include "llfloater.h"
-#include "llmemory.h"
+#include "llpointer.h"
#include "llcolorswatch.h"
#include "llspinctrl.h"
#include "lltextureentry.h"
@@ -61,7 +61,6 @@ class LLFloaterColorPicker
virtual BOOL handleMouseUp ( S32 x, S32 y, MASK mask );
virtual BOOL handleHover ( S32 x, S32 y, MASK mask );
virtual void onMouseCaptureLost();
- virtual void onClose(bool app_quitting);
// implicit methods
void createUI ();
@@ -123,14 +122,11 @@ class LLFloaterColorPicker
// callbacks
static void onClickCancel ( void* data );
static void onClickSelect ( void* data );
- static void onClickPipette ( void* data );
+ void onClickPipette ( );
static void onTextCommit ( LLUICtrl* ctrl, void* data );
static void onImmediateCheck ( LLUICtrl* ctrl, void* data );
- static void onColorSelect( const LLTextureEntry& te, void *data );
+ void onColorSelect( const LLTextureEntry& te );
private:
- // turns on or off text entry commit call backs
- void enableTextCallbacks ( BOOL stateIn );
-
// draws color selection palette
void drawPalette ();
@@ -179,7 +175,7 @@ class LLFloaterColorPicker
const S32 mPaletteRegionHeight;
// image used to compose color grid
- LLPointer<LLImageGL> mRGBImage;
+ LLPointer<LLViewerTexture> mRGBImage;
// current swatch in use
LLColorSwatchCtrl* mSwatch;
diff --git a/indra/newview/llfloaterdaycycle.cpp b/indra/newview/llfloaterdaycycle.cpp
index 58876a8dec..7f3b988dfe 100644
--- a/indra/newview/llfloaterdaycycle.cpp
+++ b/indra/newview/llfloaterdaycycle.cpp
@@ -59,19 +59,23 @@
#include "llfloaterwindlight.h"
-LLFloaterDayCycle* LLFloaterDayCycle::sDayCycle = NULL;
std::map<std::string, LLWLSkyKey> LLFloaterDayCycle::sSliderToKey;
const F32 LLFloaterDayCycle::sHoursPerDay = 24.0f;
-LLFloaterDayCycle::LLFloaterDayCycle() : LLFloater(std::string("Day Cycle Floater"))
+LLFloaterDayCycle::LLFloaterDayCycle(const LLSD& key)
+: LLFloater(key)
+{
+ //LLUICtrlFactory::getInstance()->buildFloater(this, "floater_day_cycle_options.xml");
+}
+
+BOOL LLFloaterDayCycle::postBuild()
{
- LLUICtrlFactory::getInstance()->buildFloater(this, "floater_day_cycle_options.xml");
-
// add the combo boxes
LLComboBox* keyCombo = getChild<LLComboBox>("WLKeyPresets");
if(keyCombo != NULL)
{
+ keyCombo->removeall();
std::map<std::string, LLWLParamSet>::iterator mIt =
LLWLParamManager::instance()->mParamList.begin();
for(; mIt != LLWLParamManager::instance()->mParamList.end(); mIt++)
@@ -90,23 +94,25 @@ LLFloaterDayCycle::LLFloaterDayCycle() : LLFloater(std::string("Day Cycle Floate
// load it up
initCallbacks();
+
+ syncMenu();
+ syncSliderTrack();
+
+ return TRUE;
}
LLFloaterDayCycle::~LLFloaterDayCycle()
{
}
-void LLFloaterDayCycle::onClickHelp(void* data)
+void LLFloaterDayCycle::onClickHelp(std::string xml_alert)
{
- LLFloaterDayCycle* self = LLFloaterDayCycle::instance();
-
- std::string xml_alert = *(std::string *) data;
- LLNotifications::instance().add(self->contextualNotification(xml_alert));
+ LLNotifications::instance().add(contextualNotification(xml_alert));
}
void LLFloaterDayCycle::initHelpBtn(const std::string& name, const std::string& xml_alert)
{
- childSetAction(name, onClickHelp, new std::string(xml_alert));
+ getChild<LLButton>(name)->setClickedCallback(boost::bind(&LLFloaterDayCycle::onClickHelp, this, xml_alert));
}
void LLFloaterDayCycle::initCallbacks(void)
@@ -114,24 +120,24 @@ void LLFloaterDayCycle::initCallbacks(void)
initHelpBtn("WLDayCycleHelp", "HelpDayCycle");
// WL Day Cycle
- childSetCommitCallback("WLTimeSlider", onTimeSliderMoved, NULL);
- childSetCommitCallback("WLDayCycleKeys", onKeyTimeMoved, NULL);
- childSetCommitCallback("WLCurKeyHour", onKeyTimeChanged, NULL);
- childSetCommitCallback("WLCurKeyMin", onKeyTimeChanged, NULL);
- childSetCommitCallback("WLKeyPresets", onKeyPresetChanged, NULL);
-
- childSetCommitCallback("WLLengthOfDayHour", onTimeRateChanged, NULL);
- childSetCommitCallback("WLLengthOfDayMin", onTimeRateChanged, NULL);
- childSetCommitCallback("WLLengthOfDaySec", onTimeRateChanged, NULL);
- childSetAction("WLUseLindenTime", onUseLindenTime, NULL);
- childSetAction("WLAnimSky", onRunAnimSky, NULL);
- childSetAction("WLStopAnimSky", onStopAnimSky, NULL);
-
- childSetAction("WLLoadDayCycle", onLoadDayCycle, NULL);
- childSetAction("WLSaveDayCycle", onSaveDayCycle, NULL);
-
- childSetAction("WLAddKey", onAddKey, NULL);
- childSetAction("WLDeleteKey", onDeleteKey, NULL);
+ getChild<LLUICtrl>("WLTimeSlider")->setCommitCallback(boost::bind(&LLFloaterDayCycle::onTimeSliderMoved, this, _1));
+ getChild<LLUICtrl>("WLDayCycleKeys")->setCommitCallback(boost::bind(&LLFloaterDayCycle::onKeyTimeMoved, this, _1));
+ getChild<LLUICtrl>("WLCurKeyHour")->setCommitCallback(boost::bind(&LLFloaterDayCycle::onKeyTimeChanged, this, _1));
+ getChild<LLUICtrl>("WLCurKeyMin")->setCommitCallback(boost::bind(&LLFloaterDayCycle::onKeyTimeChanged, this, _1));
+ getChild<LLUICtrl>("WLKeyPresets")->setCommitCallback(boost::bind(&LLFloaterDayCycle::onKeyPresetChanged, this, _1));
+
+ getChild<LLUICtrl>("WLLengthOfDayHour")->setCommitCallback(boost::bind(&LLFloaterDayCycle::onTimeRateChanged, this, _1));
+ getChild<LLUICtrl>("WLLengthOfDayMin")->setCommitCallback(boost::bind(&LLFloaterDayCycle::onTimeRateChanged, this, _1));
+ getChild<LLUICtrl>("WLLengthOfDaySec")->setCommitCallback(boost::bind(&LLFloaterDayCycle::onTimeRateChanged, this, _1));
+ getChild<LLUICtrl>("WLUseLindenTime")->setCommitCallback(boost::bind(&LLFloaterDayCycle::onUseLindenTime, this, _1));
+ getChild<LLUICtrl>("WLAnimSky")->setCommitCallback(boost::bind(&LLFloaterDayCycle::onRunAnimSky, this, _1));
+ getChild<LLUICtrl>("WLStopAnimSky")->setCommitCallback(boost::bind(&LLFloaterDayCycle::onStopAnimSky, this, _1));
+
+ getChild<LLUICtrl>("WLLoadDayCycle")->setCommitCallback(boost::bind(&LLFloaterDayCycle::onLoadDayCycle, this, _1));
+ getChild<LLUICtrl>("WLSaveDayCycle")->setCommitCallback(boost::bind(&LLFloaterDayCycle::onSaveDayCycle, this, _1));
+
+ getChild<LLUICtrl>("WLAddKey")->setCommitCallback(boost::bind(&LLFloaterDayCycle::onAddKey, this, _1));
+ getChild<LLUICtrl>("WLDeleteKey")->setCommitCallback(boost::bind(&LLFloaterDayCycle::onDeleteKey, this, _1));
}
void LLFloaterDayCycle::syncMenu()
@@ -139,12 +145,12 @@ void LLFloaterDayCycle::syncMenu()
// std::map<std::string, LLVector4> & currentParams = LLWLParamManager::instance()->mCurParams.mParamValues;
// set time
- LLMultiSliderCtrl* sldr = LLFloaterDayCycle::sDayCycle->getChild<LLMultiSliderCtrl>("WLTimeSlider");
+ LLMultiSliderCtrl* sldr = getChild<LLMultiSliderCtrl>("WLTimeSlider");
sldr->setCurSliderValue((F32)LLWLParamManager::instance()->mAnimator.getDayTime() * sHoursPerDay);
- LLSpinCtrl* secSpin = sDayCycle->getChild<LLSpinCtrl>("WLLengthOfDaySec");
- LLSpinCtrl* minSpin = sDayCycle->getChild<LLSpinCtrl>("WLLengthOfDayMin");
- LLSpinCtrl* hourSpin = sDayCycle->getChild<LLSpinCtrl>("WLLengthOfDayHour");
+ LLSpinCtrl* secSpin = getChild<LLSpinCtrl>("WLLengthOfDaySec");
+ LLSpinCtrl* minSpin = getChild<LLSpinCtrl>("WLLengthOfDayMin");
+ LLSpinCtrl* hourSpin = getChild<LLSpinCtrl>("WLLengthOfDayHour");
F32 curRate;
F32 hours, min, sec;
@@ -164,18 +170,18 @@ void LLFloaterDayCycle::syncMenu()
// turn off Use Estate Time button if it's already being used
if( LLWLParamManager::instance()->mAnimator.mUseLindenTime == true)
{
- LLFloaterDayCycle::sDayCycle->childDisable("WLUseLindenTime");
+ childDisable("WLUseLindenTime");
}
else
{
- LLFloaterDayCycle::sDayCycle->childEnable("WLUseLindenTime");
+ childEnable("WLUseLindenTime");
}
}
void LLFloaterDayCycle::syncSliderTrack()
{
// clear the slider
- LLMultiSliderCtrl* kSldr = sDayCycle->getChild<LLMultiSliderCtrl>("WLDayCycleKeys");
+ LLMultiSliderCtrl* kSldr = getChild<LLMultiSliderCtrl>("WLDayCycleKeys");
kSldr->clear();
sSliderToKey.clear();
@@ -198,12 +204,12 @@ void LLFloaterDayCycle::syncTrack()
}
LLMultiSliderCtrl* sldr;
- sldr = sDayCycle->getChild<LLMultiSliderCtrl>(
+ sldr = getChild<LLMultiSliderCtrl>(
"WLDayCycleKeys");
llassert_always(sSliderToKey.size() == sldr->getValue().size());
LLMultiSliderCtrl* tSldr;
- tSldr = sDayCycle->getChild<LLMultiSliderCtrl>(
+ tSldr = getChild<LLMultiSliderCtrl>(
"WLTimeSlider");
// create a new animation track
@@ -225,50 +231,7 @@ void LLFloaterDayCycle::syncTrack()
LLWLParamManager::instance()->mCurParams);
}
-// static
-LLFloaterDayCycle* LLFloaterDayCycle::instance()
-{
- if (!sDayCycle)
- {
- sDayCycle = new LLFloaterDayCycle();
- sDayCycle->open();
- sDayCycle->setFocus(TRUE);
- }
- return sDayCycle;
-}
-
-bool LLFloaterDayCycle::isOpen()
-{
- if (sDayCycle != NULL)
- {
- return true;
- }
- return false;
-}
-
-void LLFloaterDayCycle::show()
-{
- LLFloaterDayCycle* dayCycle = instance();
- dayCycle->syncMenu();
- syncSliderTrack();
-
- // comment in if you want the menu to rebuild each time
- //LLUICtrlFactory::getInstance()->buildFloater(dayCycle, "floater_day_cycle_options.xml");
- //dayCycle->initCallbacks();
-
- dayCycle->open();
-}
-
-// virtual
-void LLFloaterDayCycle::onClose(bool app_quitting)
-{
- if (sDayCycle)
- {
- sDayCycle->setVisible(FALSE);
- }
-}
-
-void LLFloaterDayCycle::onRunAnimSky(void* userData)
+void LLFloaterDayCycle::onRunAnimSky(LLUICtrl* ctrl)
{
// if no keys, do nothing
if(sSliderToKey.size() == 0)
@@ -277,11 +240,11 @@ void LLFloaterDayCycle::onRunAnimSky(void* userData)
}
LLMultiSliderCtrl* sldr;
- sldr = sDayCycle->getChild<LLMultiSliderCtrl>("WLDayCycleKeys");
+ sldr = getChild<LLMultiSliderCtrl>("WLDayCycleKeys");
llassert_always(sSliderToKey.size() == sldr->getValue().size());
LLMultiSliderCtrl* tSldr;
- tSldr = sDayCycle->getChild<LLMultiSliderCtrl>("WLTimeSlider");
+ tSldr = getChild<LLMultiSliderCtrl>("WLTimeSlider");
// turn off linden time
LLWLParamManager::instance()->mAnimator.mUseLindenTime = false;
@@ -293,7 +256,7 @@ void LLFloaterDayCycle::onRunAnimSky(void* userData)
llassert_always(LLWLParamManager::instance()->mAnimator.mTimeTrack.size() == sldr->getValue().size());
}
-void LLFloaterDayCycle::onStopAnimSky(void* userData)
+void LLFloaterDayCycle::onStopAnimSky(LLUICtrl* ctrl)
{
// if no keys, do nothing
if(sSliderToKey.size() == 0) {
@@ -305,17 +268,16 @@ void LLFloaterDayCycle::onStopAnimSky(void* userData)
LLWLParamManager::instance()->mAnimator.mUseLindenTime = false;
}
-void LLFloaterDayCycle::onUseLindenTime(void* userData)
+void LLFloaterDayCycle::onUseLindenTime(LLUICtrl* ctrl)
{
- LLFloaterWindLight* wl = LLFloaterWindLight::instance();
- LLComboBox* box = wl->getChild<LLComboBox>("WLPresetsCombo");
+ LLComboBox* box = getChild<LLComboBox>("WLPresetsCombo");
box->selectByValue("");
LLWLParamManager::instance()->mAnimator.mIsRunning = true;
LLWLParamManager::instance()->mAnimator.mUseLindenTime = true;
}
-void LLFloaterDayCycle::onLoadDayCycle(void* userData)
+void LLFloaterDayCycle::onLoadDayCycle(LLUICtrl* ctrl)
{
LLWLParamManager::instance()->mDay.loadDayCycle("Default.xml");
@@ -325,7 +287,7 @@ void LLFloaterDayCycle::onLoadDayCycle(void* userData)
// set the param manager's track to the new one
LLMultiSliderCtrl* tSldr;
- tSldr = sDayCycle->getChild<LLMultiSliderCtrl>(
+ tSldr = getChild<LLMultiSliderCtrl>(
"WLTimeSlider");
LLWLParamManager::instance()->resetAnimator(
tSldr->getCurSliderValue() / sHoursPerDay, false);
@@ -335,15 +297,15 @@ void LLFloaterDayCycle::onLoadDayCycle(void* userData)
LLWLParamManager::instance()->mCurParams);
}
-void LLFloaterDayCycle::onSaveDayCycle(void* userData)
+void LLFloaterDayCycle::onSaveDayCycle(LLUICtrl* ctrl)
{
LLWLParamManager::instance()->mDay.saveDayCycle("Default.xml");
}
-void LLFloaterDayCycle::onTimeSliderMoved(LLUICtrl* ctrl, void* userData)
+void LLFloaterDayCycle::onTimeSliderMoved(LLUICtrl* ctrl)
{
- LLMultiSliderCtrl* sldr = sDayCycle->getChild<LLMultiSliderCtrl>(
+ LLMultiSliderCtrl* sldr = getChild<LLMultiSliderCtrl>(
"WLTimeSlider");
/// get the slider value
@@ -359,12 +321,12 @@ void LLFloaterDayCycle::onTimeSliderMoved(LLUICtrl* ctrl, void* userData)
LLWLParamManager::instance()->mCurParams);
}
-void LLFloaterDayCycle::onKeyTimeMoved(LLUICtrl* ctrl, void* userData)
+void LLFloaterDayCycle::onKeyTimeMoved(LLUICtrl* ctrl)
{
- LLComboBox* comboBox = sDayCycle->getChild<LLComboBox>("WLKeyPresets");
- LLMultiSliderCtrl* sldr = sDayCycle->getChild<LLMultiSliderCtrl>("WLDayCycleKeys");
- LLSpinCtrl* hourSpin = sDayCycle->getChild<LLSpinCtrl>("WLCurKeyHour");
- LLSpinCtrl* minSpin = sDayCycle->getChild<LLSpinCtrl>("WLCurKeyMin");
+ LLComboBox* comboBox = getChild<LLComboBox>("WLKeyPresets");
+ LLMultiSliderCtrl* sldr = getChild<LLMultiSliderCtrl>("WLDayCycleKeys");
+ LLSpinCtrl* hourSpin = getChild<LLSpinCtrl>("WLCurKeyHour");
+ LLSpinCtrl* minSpin = getChild<LLSpinCtrl>("WLCurKeyMin");
if(sldr->getValue().size() == 0) {
return;
@@ -402,18 +364,18 @@ void LLFloaterDayCycle::onKeyTimeMoved(LLUICtrl* ctrl, void* userData)
}
-void LLFloaterDayCycle::onKeyTimeChanged(LLUICtrl* ctrl, void* userData)
+void LLFloaterDayCycle::onKeyTimeChanged(LLUICtrl* ctrl)
{
// if no keys, skipped
if(sSliderToKey.size() == 0) {
return;
}
- LLMultiSliderCtrl* sldr = sDayCycle->getChild<LLMultiSliderCtrl>(
+ LLMultiSliderCtrl* sldr = getChild<LLMultiSliderCtrl>(
"WLDayCycleKeys");
- LLSpinCtrl* hourSpin = sDayCycle->getChild<LLSpinCtrl>(
+ LLSpinCtrl* hourSpin = getChild<LLSpinCtrl>(
"WLCurKeyHour");
- LLSpinCtrl* minSpin = sDayCycle->getChild<LLSpinCtrl>(
+ LLSpinCtrl* minSpin = getChild<LLSpinCtrl>(
"WLCurKeyMin");
F32 hour = hourSpin->get();
@@ -431,12 +393,12 @@ void LLFloaterDayCycle::onKeyTimeChanged(LLUICtrl* ctrl, void* userData)
syncTrack();
}
-void LLFloaterDayCycle::onKeyPresetChanged(LLUICtrl* ctrl, void* userData)
+void LLFloaterDayCycle::onKeyPresetChanged(LLUICtrl* ctrl)
{
// get the time
- LLComboBox* comboBox = sDayCycle->getChild<LLComboBox>(
+ LLComboBox* comboBox = getChild<LLComboBox>(
"WLKeyPresets");
- LLMultiSliderCtrl* sldr = sDayCycle->getChild<LLMultiSliderCtrl>(
+ LLMultiSliderCtrl* sldr = getChild<LLMultiSliderCtrl>(
"WLDayCycleKeys");
// do nothing if no sliders
@@ -458,16 +420,16 @@ void LLFloaterDayCycle::onKeyPresetChanged(LLUICtrl* ctrl, void* userData)
syncTrack();
}
-void LLFloaterDayCycle::onTimeRateChanged(LLUICtrl* ctrl, void* userData)
+void LLFloaterDayCycle::onTimeRateChanged(LLUICtrl* ctrl)
{
// get the time
- LLSpinCtrl* secSpin = sDayCycle->getChild<LLSpinCtrl>(
+ LLSpinCtrl* secSpin = getChild<LLSpinCtrl>(
"WLLengthOfDaySec");
- LLSpinCtrl* minSpin = sDayCycle->getChild<LLSpinCtrl>(
+ LLSpinCtrl* minSpin = getChild<LLSpinCtrl>(
"WLLengthOfDayMin");
- LLSpinCtrl* hourSpin = sDayCycle->getChild<LLSpinCtrl>(
+ LLSpinCtrl* hourSpin = getChild<LLSpinCtrl>(
"WLLengthOfDayHour");
F32 hour;
@@ -486,13 +448,13 @@ void LLFloaterDayCycle::onTimeRateChanged(LLUICtrl* ctrl, void* userData)
syncTrack();
}
-void LLFloaterDayCycle::onAddKey(void* userData)
+void LLFloaterDayCycle::onAddKey(LLUICtrl* ctrl)
{
- LLComboBox* comboBox = sDayCycle->getChild<LLComboBox>(
+ LLComboBox* comboBox = getChild<LLComboBox>(
"WLKeyPresets");
- LLMultiSliderCtrl* kSldr = sDayCycle->getChild<LLMultiSliderCtrl>(
+ LLMultiSliderCtrl* kSldr = getChild<LLMultiSliderCtrl>(
"WLDayCycleKeys");
- LLMultiSliderCtrl* tSldr = sDayCycle->getChild<LLMultiSliderCtrl>(
+ LLMultiSliderCtrl* tSldr = getChild<LLMultiSliderCtrl>(
"WLTimeSlider");
llassert_always(sSliderToKey.size() == kSldr->getValue().size());
@@ -508,7 +470,7 @@ void LLFloaterDayCycle::onAddKey(void* userData)
void LLFloaterDayCycle::addSliderKey(F32 time, const std::string & presetName)
{
- LLMultiSliderCtrl* kSldr = sDayCycle->getChild<LLMultiSliderCtrl>(
+ LLMultiSliderCtrl* kSldr = getChild<LLMultiSliderCtrl>(
"WLDayCycleKeys");
// make a slider
@@ -533,7 +495,7 @@ void LLFloaterDayCycle::addSliderKey(F32 time, const std::string & presetName)
void LLFloaterDayCycle::deletePreset(std::string& presetName)
{
- LLMultiSliderCtrl* sldr = sDayCycle->getChild<LLMultiSliderCtrl>("WLDayCycleKeys");
+ LLMultiSliderCtrl* sldr = getChild<LLMultiSliderCtrl>("WLDayCycleKeys");
/// delete any reference
std::map<std::string, LLWLSkyKey>::iterator curr_preset, next_preset;
@@ -549,15 +511,15 @@ void LLFloaterDayCycle::deletePreset(std::string& presetName)
}
}
-void LLFloaterDayCycle::onDeleteKey(void* userData)
+void LLFloaterDayCycle::onDeleteKey(LLUICtrl* ctrl)
{
if(sSliderToKey.size() == 0) {
return;
}
- LLComboBox* comboBox = sDayCycle->getChild<LLComboBox>(
+ LLComboBox* comboBox = getChild<LLComboBox>(
"WLKeyPresets");
- LLMultiSliderCtrl* sldr = sDayCycle->getChild<LLMultiSliderCtrl>("WLDayCycleKeys");
+ LLMultiSliderCtrl* sldr = getChild<LLMultiSliderCtrl>("WLDayCycleKeys");
// delete from map
const std::string& sldrName = sldr->getCurSlider();
@@ -574,8 +536,8 @@ void LLFloaterDayCycle::onDeleteKey(void* userData)
comboBox->selectByValue(sSliderToKey[name].presetName);
F32 time = sSliderToKey[name].time;
- LLSpinCtrl* hourSpin = sDayCycle->getChild<LLSpinCtrl>("WLCurKeyHour");
- LLSpinCtrl* minSpin = sDayCycle->getChild<LLSpinCtrl>("WLCurKeyMin");
+ LLSpinCtrl* hourSpin = getChild<LLSpinCtrl>("WLCurKeyHour");
+ LLSpinCtrl* minSpin = getChild<LLSpinCtrl>("WLCurKeyMin");
// now set the spinners
F32 hour = (F32)((S32)time);
diff --git a/indra/newview/llfloaterdaycycle.h b/indra/newview/llfloaterdaycycle.h
index d230035545..43c347d4f2 100644
--- a/indra/newview/llfloaterdaycycle.h
+++ b/indra/newview/llfloaterdaycycle.h
@@ -56,87 +56,69 @@ class LLFloaterDayCycle : public LLFloater
{
public:
- LLFloaterDayCycle();
+ LLFloaterDayCycle(const LLSD& key);
virtual ~LLFloaterDayCycle();
-
+ /*virtual*/ BOOL postBuild();
/// help button stuff
- static void onClickHelp(void* data);
+ void onClickHelp(std::string xml_alert);
void initHelpBtn(const std::string& name, const std::string& xml_alert);
/// initialize all
void initCallbacks(void);
- /// one and one instance only
- static LLFloaterDayCycle* instance();
-
/// on time slider moved
- static void onTimeSliderMoved(LLUICtrl* ctrl, void* userData);
+ void onTimeSliderMoved(LLUICtrl* ctrl);
/// what happens when you move the key frame
- static void onKeyTimeMoved(LLUICtrl* ctrl, void* userData);
+ void onKeyTimeMoved(LLUICtrl* ctrl);
/// what happens when you change the key frame's time
- static void onKeyTimeChanged(LLUICtrl* ctrl, void* userData);
+ void onKeyTimeChanged(LLUICtrl* ctrl);
/// if you change the combo box, change the frame
- static void onKeyPresetChanged(LLUICtrl* ctrl, void* userData);
+ void onKeyPresetChanged(LLUICtrl* ctrl);
/// run this when user says to run the sky animation
- static void onRunAnimSky(void* userData);
+ void onRunAnimSky(LLUICtrl* ctrl);
/// run this when user says to stop the sky animation
- static void onStopAnimSky(void* userData);
+ void onStopAnimSky(LLUICtrl* ctrl);
/// if you change the combo box, change the frame
- static void onTimeRateChanged(LLUICtrl* ctrl, void* userData);
+ void onTimeRateChanged(LLUICtrl* ctrl);
/// add a new key on slider
- static void onAddKey(void* userData);
+ void onAddKey(LLUICtrl* ctrl);
/// delete any and all reference to a preset
void deletePreset(std::string& presetName);
/// delete a key frame
- static void onDeleteKey(void* userData);
+ void onDeleteKey(LLUICtrl* ctrl);
/// button to load day
- static void onLoadDayCycle(void* userData);
+ void onLoadDayCycle(LLUICtrl* ctrl);
/// button to save day
- static void onSaveDayCycle(void* userData);
+ void onSaveDayCycle(LLUICtrl* ctrl);
/// toggle for Linden time
- static void onUseLindenTime(void* userData);
-
-
- //// menu management
-
- /// show off our menu
- static void show();
-
- /// return if the menu exists or not
- static bool isOpen();
-
- /// stuff to do on exit
- virtual void onClose(bool app_quitting);
+ void onUseLindenTime(LLUICtrl* ctrl);
/// sync up sliders with day cycle structure
- static void syncMenu();
+ void syncMenu();
// makes sure key slider has what's in day cycle
- static void syncSliderTrack();
+ void syncSliderTrack();
/// makes sure day cycle data structure has what's in menu
- static void syncTrack();
+ void syncTrack();
/// add a slider to the track
- static void addSliderKey(F32 time, const std::string& presetName);
+ void addSliderKey(F32 time, const std::string& presetName);
private:
- // one instance on the inside
- static LLFloaterDayCycle* sDayCycle;
-
// map of sliders to parameters
static std::map<std::string, LLWLSkyKey> sSliderToKey;
diff --git a/indra/newview/llfloaterenvsettings.cpp b/indra/newview/llfloaterenvsettings.cpp
index 661c3988c0..a520df36de 100644
--- a/indra/newview/llfloaterenvsettings.cpp
+++ b/indra/newview/llfloaterenvsettings.cpp
@@ -34,6 +34,7 @@
#include "llfloaterenvsettings.h"
+#include "llfloaterreg.h"
#include "llfloaterwindlight.h"
#include "llfloaterwater.h"
#include "lluictrlfactory.h"
@@ -52,43 +53,43 @@
#include <sstream>
-LLFloaterEnvSettings* LLFloaterEnvSettings::sEnvSettings = NULL;
-
-LLFloaterEnvSettings::LLFloaterEnvSettings() : LLFloater(std::string("Environment Settings Floater"))
+LLFloaterEnvSettings::LLFloaterEnvSettings(const LLSD& key)
+ : LLFloater(key)
{
- LLUICtrlFactory::getInstance()->buildFloater(this, "floater_env_settings.xml");
-
- // load it up
- initCallbacks();
+ //LLUICtrlFactory::getInstance()->buildFloater(this, "floater_env_settings.xml");
}
-
+// virtual
LLFloaterEnvSettings::~LLFloaterEnvSettings()
{
}
-
-void LLFloaterEnvSettings::onClickHelp(void* data)
+// virtual
+BOOL LLFloaterEnvSettings::postBuild()
+{
+ // load it up
+ initCallbacks();
+ syncMenu();
+ return TRUE;
+}
+void LLFloaterEnvSettings::onClickHelp()
{
- LLFloaterEnvSettings* self = (LLFloaterEnvSettings*)data;
- LLNotifications::instance().add(self->contextualNotification("EnvSettingsHelpButton"));
+ LLNotifications::instance().add(contextualNotification("EnvSettingsHelpButton"));
}
void LLFloaterEnvSettings::initCallbacks(void)
{
// our three sliders
- childSetCommitCallback("EnvTimeSlider", onChangeDayTime, NULL);
- childSetCommitCallback("EnvCloudSlider", onChangeCloudCoverage, NULL);
- childSetCommitCallback("EnvWaterFogSlider", onChangeWaterFogDensity,
- &LLWaterParamManager::instance()->mFogDensity);
+ getChild<LLUICtrl>("EnvTimeSlider")->setCommitCallback(boost::bind(&LLFloaterEnvSettings::onChangeDayTime, this, _1));
+ getChild<LLUICtrl>("EnvCloudSlider")->setCommitCallback(boost::bind(&LLFloaterEnvSettings::onChangeCloudCoverage, this, _1));
+ getChild<LLUICtrl>("EnvWaterFogSlider")->setCommitCallback(boost::bind(&LLFloaterEnvSettings::onChangeWaterFogDensity, this, _1, &LLWaterParamManager::instance()->mFogDensity));
// color picker
- childSetCommitCallback("EnvWaterColor", onChangeWaterColor,
- &LLWaterParamManager::instance()->mFogColor);
+ getChild<LLUICtrl>("EnvWaterColor")->setCommitCallback(boost::bind(&LLFloaterEnvSettings::onChangeWaterColor, this, _1, &LLWaterParamManager::instance()->mFogColor));
// WL Top
- childSetAction("EnvAdvancedSkyButton", onOpenAdvancedSky, NULL);
- childSetAction("EnvAdvancedWaterButton", onOpenAdvancedWater, NULL);
- childSetAction("EnvUseEstateTimeButton", onUseEstateTime, NULL);
- childSetAction("EnvSettingsHelpButton", onClickHelp, this);
+ getChild<LLUICtrl>("EnvAdvancedSkyButton")->setCommitCallback(boost::bind(&LLFloaterEnvSettings::onOpenAdvancedSky, this));
+ getChild<LLUICtrl>("EnvAdvancedWaterButton")->setCommitCallback(boost::bind(&LLFloaterEnvSettings::onOpenAdvancedWater, this));
+ getChild<LLUICtrl>("EnvUseEstateTimeButton")->setCommitCallback(boost::bind(&LLFloaterEnvSettings::onUseEstateTime, this));
+ getChild<LLUICtrl>("EnvSettingsHelpButton")->setCommitCallback(boost::bind(&LLFloaterEnvSettings::onClickHelp, this));
}
@@ -97,14 +98,14 @@ void LLFloaterEnvSettings::initCallbacks(void)
void LLFloaterEnvSettings::syncMenu()
{
LLSliderCtrl* sldr;
- sldr = sEnvSettings->getChild<LLSliderCtrl>("EnvTimeSlider");
+ sldr = getChild<LLSliderCtrl>("EnvTimeSlider");
// sync the clock
F32 val = (F32)LLWLParamManager::instance()->mAnimator.getDayTime();
std::string timeStr = timeToString(val);
LLTextBox* textBox;
- textBox = sEnvSettings->getChild<LLTextBox>("EnvTimeText");
+ textBox = getChild<LLTextBox>("EnvTimeText");
textBox->setValue(timeStr);
@@ -123,7 +124,7 @@ void LLFloaterEnvSettings::syncMenu()
LLWaterParamManager * param_mgr = LLWaterParamManager::instance();
// sync water params
LLColor4 col = param_mgr->getFogColor();
- LLColorSwatchCtrl* colCtrl = sEnvSettings->getChild<LLColorSwatchCtrl>("EnvWaterColor");
+ LLColorSwatchCtrl* colCtrl = getChild<LLColorSwatchCtrl>("EnvWaterColor");
col.mV[3] = 1.0f;
colCtrl->set(col);
@@ -167,53 +168,9 @@ void LLFloaterEnvSettings::syncMenu()
}
}
-
-// static instance of it
-LLFloaterEnvSettings* LLFloaterEnvSettings::instance()
-{
- if (!sEnvSettings)
- {
- sEnvSettings = new LLFloaterEnvSettings();
- sEnvSettings->open();
- sEnvSettings->setFocus(TRUE);
- }
- return sEnvSettings;
-}
-void LLFloaterEnvSettings::show()
-{
- LLFloaterEnvSettings* envSettings = instance();
- envSettings->syncMenu();
-
- // comment in if you want the menu to rebuild each time
- //LLUICtrlFactory::getInstance()->buildFloater(envSettings, "floater_env_settings.xml");
- //envSettings->initCallbacks();
-
- envSettings->open();
-}
-
-bool LLFloaterEnvSettings::isOpen()
-{
- if (sEnvSettings != NULL)
- {
- return true;
- }
- return false;
-}
-
-// virtual
-void LLFloaterEnvSettings::onClose(bool app_quitting)
+void LLFloaterEnvSettings::onChangeDayTime(LLUICtrl* ctrl)
{
- if (sEnvSettings)
- {
- sEnvSettings->setVisible(FALSE);
- }
-}
-
-
-void LLFloaterEnvSettings::onChangeDayTime(LLUICtrl* ctrl, void* userData)
-{
- LLSliderCtrl* sldr;
- sldr = sEnvSettings->getChild<LLSliderCtrl>("EnvTimeSlider");
+ LLSliderCtrl* sldr = static_cast<LLSliderCtrl*>(ctrl);
// deactivate animator
LLWLParamManager::instance()->mAnimator.mIsRunning = false;
@@ -230,10 +187,9 @@ void LLFloaterEnvSettings::onChangeDayTime(LLUICtrl* ctrl, void* userData)
LLWLParamManager::instance()->mCurParams);
}
-void LLFloaterEnvSettings::onChangeCloudCoverage(LLUICtrl* ctrl, void* userData)
+void LLFloaterEnvSettings::onChangeCloudCoverage(LLUICtrl* ctrl)
{
- LLSliderCtrl* sldr;
- sldr = sEnvSettings->getChild<LLSliderCtrl>("EnvCloudSlider");
+ LLSliderCtrl* sldr = static_cast<LLSliderCtrl*>(ctrl);
// deactivate animator
//LLWLParamManager::instance()->mAnimator.mIsRunning = false;
@@ -243,17 +199,10 @@ void LLFloaterEnvSettings::onChangeCloudCoverage(LLUICtrl* ctrl, void* userData)
LLWLParamManager::instance()->mCurParams.set("cloud_shadow", val);
}
-void LLFloaterEnvSettings::onChangeWaterFogDensity(LLUICtrl* ctrl, void* userData)
+void LLFloaterEnvSettings::onChangeWaterFogDensity(LLUICtrl* ctrl, WaterExpFloatControl* expFloatControl)
{
LLSliderCtrl* sldr;
- sldr = sEnvSettings->getChild<LLSliderCtrl>("EnvWaterFogSlider");
-
- if(NULL == userData)
- {
- return;
- }
-
- WaterExpFloatControl * expFloatControl = static_cast<WaterExpFloatControl *>(userData);
+ sldr = getChild<LLSliderCtrl>("EnvWaterFogSlider");
F32 val = sldr->getValueF32();
expFloatControl->mExp = val;
@@ -263,10 +212,9 @@ void LLFloaterEnvSettings::onChangeWaterFogDensity(LLUICtrl* ctrl, void* userDat
LLWaterParamManager::instance()->propagateParameters();
}
-void LLFloaterEnvSettings::onChangeWaterColor(LLUICtrl* ctrl, void* userData)
+void LLFloaterEnvSettings::onChangeWaterColor(LLUICtrl* ctrl, WaterColorControl* colorControl)
{
LLColorSwatchCtrl* swatch = static_cast<LLColorSwatchCtrl*>(ctrl);
- WaterColorControl * colorControl = static_cast<WaterColorControl *>(userData);
*colorControl = swatch->get();
colorControl->update(LLWaterParamManager::instance()->mCurParams);
@@ -274,23 +222,22 @@ void LLFloaterEnvSettings::onChangeWaterColor(LLUICtrl* ctrl, void* userData)
}
-void LLFloaterEnvSettings::onOpenAdvancedSky(void* userData)
+void LLFloaterEnvSettings::onOpenAdvancedSky()
{
- LLFloaterWindLight::show();
+ LLFloaterReg::showInstance("env_windlight");
}
-void LLFloaterEnvSettings::onOpenAdvancedWater(void* userData)
+void LLFloaterEnvSettings::onOpenAdvancedWater()
{
- LLFloaterWater::show();
+ LLFloaterReg::showInstance("env_water");
}
-void LLFloaterEnvSettings::onUseEstateTime(void* userData)
+void LLFloaterEnvSettings::onUseEstateTime()
{
- if(LLFloaterWindLight::isOpen())
+ LLFloaterWindLight* wl = LLFloaterReg::findTypedInstance<LLFloaterWindLight>("env_windlight");
+ if(wl)
{
- // select the blank value in
- LLFloaterWindLight* wl = LLFloaterWindLight::instance();
LLComboBox* box = wl->getChild<LLComboBox>("WLPresetsCombo");
box->selectByValue("");
}
@@ -303,7 +250,6 @@ std::string LLFloaterEnvSettings::timeToString(F32 curTime)
{
S32 hours;
S32 min;
- bool isPM = false;
// get hours and minutes
hours = (S32) (24.0 * curTime);
@@ -317,46 +263,19 @@ std::string LLFloaterEnvSettings::timeToString(F32 curTime)
min = 0;
}
- // set for PM
- if(hours >= 12 && hours < 24)
- {
- isPM = true;
- }
+ std::string newTime = getString("timeStr");
+ struct tm * timeT;
+ time_t secT = time(0);
+ timeT = gmtime (&secT);
- // convert to non-military notation
- if(hours >= 24)
- {
- hours = 12;
- }
- else if(hours > 12)
- {
- hours -= 12;
- }
- else if(hours == 0)
- {
- hours = 12;
- }
+ timeT->tm_hour = hours;
+ timeT->tm_min = min;
+ secT = mktime (timeT);
+ secT -= LLStringOps::getLocalTimeOffset ();
- // make the string
- std::stringstream newTime;
- newTime << hours << ":";
-
- // double 0
- if(min < 10)
- {
- newTime << 0;
- }
-
- // finish it
- newTime << min << " ";
- if(isPM)
- {
- newTime << "PM";
- }
- else
- {
- newTime << "AM";
- }
+ LLSD substitution;
+ substitution["datetime"] = (S32) secT;
- return newTime.str();
+ LLStringUtil::format (newTime, substitution);
+ return newTime;
}
diff --git a/indra/newview/llfloaterenvsettings.h b/indra/newview/llfloaterenvsettings.h
index 4cdf6036c6..083e3636d1 100644
--- a/indra/newview/llfloaterenvsettings.h
+++ b/indra/newview/llfloaterenvsettings.h
@@ -39,59 +39,46 @@
#include "llfloater.h"
+struct WaterColorControl;
+struct WaterExpFloatControl;
/// Menuing system for all of windlight's functionality
class LLFloaterEnvSettings : public LLFloater
{
public:
- LLFloaterEnvSettings();
- virtual ~LLFloaterEnvSettings();
-
+ LLFloaterEnvSettings(const LLSD& key);
+ /*virtual*/ ~LLFloaterEnvSettings();
+ /*virtual*/ BOOL postBuild();
/// initialize all the callbacks for the menu
void initCallbacks(void);
- /// one and one instance only
- static LLFloaterEnvSettings* instance();
-
/// callback for the menus help button
- static void onClickHelp(void* data);
+ void onClickHelp();
/// handle if time of day is changed
- static void onChangeDayTime(LLUICtrl* ctrl, void* userData);
+ void onChangeDayTime(LLUICtrl* ctrl);
/// handle if cloud coverage is changed
- static void onChangeCloudCoverage(LLUICtrl* ctrl, void* userData);
+ void onChangeCloudCoverage(LLUICtrl* ctrl);
/// handle change in water fog density
- static void onChangeWaterFogDensity(LLUICtrl* ctrl, void* userData);
-
- /// handle change in under water fog density
- static void onChangeUnderWaterFogMod(LLUICtrl* ctrl, void* userData);
+ void onChangeWaterFogDensity(LLUICtrl* ctrl, WaterExpFloatControl* expFloatControl);
/// handle change in water fog color
- static void onChangeWaterColor(LLUICtrl* ctrl, void* userData);
+ void onChangeWaterColor(LLUICtrl* ctrl, WaterColorControl* colorControl);
/// open the advanced sky settings menu
- static void onOpenAdvancedSky(void* userData);
+ void onOpenAdvancedSky();
/// open the advanced water settings menu
- static void onOpenAdvancedWater(void* userData);
+ void onOpenAdvancedWater();
/// sync time with the server
- static void onUseEstateTime(void* userData);
+ void onUseEstateTime();
//// menu management
- /// show off our menu
- static void show();
-
- /// return if the menu exists or not
- static bool isOpen();
-
- /// stuff to do on exit
- virtual void onClose(bool app_quitting);
-
/// sync up sliders with parameters
void syncMenu();
@@ -99,8 +86,6 @@ public:
std::string timeToString(F32 curTime);
private:
- // one instance on the inside
- static LLFloaterEnvSettings* sEnvSettings;
};
diff --git a/indra/newview/llfloaterevent.cpp b/indra/newview/llfloaterevent.cpp
deleted file mode 100644
index 485c13c7b6..0000000000
--- a/indra/newview/llfloaterevent.cpp
+++ /dev/null
@@ -1,131 +0,0 @@
-/**
- * @file llfloaterevent.cpp
- * @brief Event information as shown in a floating window from
- * secondlife:// command handler.
- *
- * $LicenseInfo:firstyear=2007&license=viewergpl$
- *
- * Copyright (c) 2007-2009, Linden Research, Inc.
- *
- * Second Life Viewer Source Code
- * The source code in this file ("Source Code") is provided by Linden Lab
- * to you under the terms of the GNU General Public License, version 2.0
- * ("GPL"), unless you have obtained a separate licensing agreement
- * ("Other License"), formally executed by you and Linden Lab. Terms of
- * the GPL can be found in doc/GPL-license.txt in this distribution, or
- * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
- *
- * There are special exceptions to the terms and conditions of the GPL as
- * it is applied to this Source Code. View the full text of the exception
- * in the file doc/FLOSS-exception.txt in this software distribution, or
- * online at
- * http://secondlifegrid.net/programs/open_source/licensing/flossexception
- *
- * By copying, modifying or distributing this software, you acknowledge
- * that you have read and understood your obligations described above,
- * and agree to abide by those obligations.
- *
- * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
- * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
- * COMPLETENESS OR PERFORMANCE.
- * $/LicenseInfo$
- */
-
-#include "llviewerprecompiledheaders.h"
-
-#include "llfloaterevent.h"
-
-// viewer project includes
-#include "llcommandhandler.h"
-#include "llpanelevent.h"
-
-// linden library includes
-#include "lluuid.h"
-#include "lluictrlfactory.h"
-
-////////////////////////////////////////////////////////////////////////////
-// LLFloaterEventInfo
-
-//-----------------------------------------------------------------------------
-// Globals
-//-----------------------------------------------------------------------------
-
-LLMap< U32, LLFloaterEventInfo* > gEventInfoInstances;
-
-class LLEventHandler : public LLCommandHandler
-{
-public:
- // requires trusted browser to trigger
- LLEventHandler() : LLCommandHandler("event", true) { }
- bool handle(const LLSD& tokens, const LLSD& query_map,
- LLWebBrowserCtrl* web)
- {
- if (tokens.size() < 2)
- {
- return false;
- }
- U32 event_id = tokens[0].asInteger();
- if (tokens[1].asString() == "about")
- {
- LLFloaterEventInfo::show(event_id);
- return true;
- }
- return false;
- }
-};
-LLEventHandler gEventHandler;
-
-LLFloaterEventInfo::LLFloaterEventInfo(const std::string& name, const U32 event_id)
-: LLFloater(name),
- mEventID( event_id )
-{
-
- mFactoryMap["event_details_panel"] = LLCallbackMap(LLFloaterEventInfo::createEventDetail, this);
- LLUICtrlFactory::getInstance()->buildFloater(this, "floater_preview_event.xml", &getFactoryMap());
- gEventInfoInstances.addData(event_id, this);
-}
-
-LLFloaterEventInfo::~LLFloaterEventInfo()
-{
- // child views automatically deleted
- gEventInfoInstances.removeData(mEventID);
-}
-
-void LLFloaterEventInfo::displayEventInfo(const U32 event_id)
-{
- mPanelEventp->setEventID(event_id);
- this->setFrontmost(true);
-}
-
-// static
-void* LLFloaterEventInfo::createEventDetail(void* userdata)
-{
- LLFloaterEventInfo *self = (LLFloaterEventInfo*)userdata;
- self->mPanelEventp = new LLPanelEvent();
- LLUICtrlFactory::getInstance()->buildPanel(self->mPanelEventp, "panel_event.xml");
-
- return self->mPanelEventp;
-}
-
-// static
-LLFloaterEventInfo* LLFloaterEventInfo::show(const U32 event_id)
-{
- LLFloaterEventInfo *floater;
- if (gEventInfoInstances.checkData(event_id))
- {
- // ...bring that window to front
- floater = gEventInfoInstances.getData(event_id);
- floater->open(); /*Flawfinder: ignore*/
- floater->setFrontmost(true);
- }
- else
- {
- floater = new LLFloaterEventInfo("eventinfo", event_id );
- floater->center();
- floater->open(); /*Flawfinder: ignore*/
- floater->displayEventInfo(event_id);
- floater->setFrontmost(true);
- }
-
- return floater;
-}
diff --git a/indra/newview/llfloaterfonttest.cpp b/indra/newview/llfloaterfonttest.cpp
index 4bb1d9605d..413992910e 100644
--- a/indra/newview/llfloaterfonttest.cpp
+++ b/indra/newview/llfloaterfonttest.cpp
@@ -5,7 +5,7 @@
*
* $LicenseInfo:firstyear=2008&license=viewergpl$
*
- * Copyright (c) 2008 Linden Research, Inc.
+ * Copyright (c) 2008-2009, Linden Research, Inc.
*
* Second Life Viewer Source Code
* The source code in this file ("Source Code") is provided by Linden Lab
@@ -13,12 +13,13 @@
* ("GPL"), unless you have obtained a separate licensing agreement
* ("Other License"), formally executed by you and Linden Lab. Terms of
* the GPL can be found in doc/GPL-license.txt in this distribution, or
- * online at http://secondlife.com/developers/opensource/gplv2
+ * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
*
* There are special exceptions to the terms and conditions of the GPL as
* it is applied to this Source Code. View the full text of the exception
* in the file doc/FLOSS-exception.txt in this software distribution, or
- * online at http://secondlife.com/developers/opensource/flossexception
+ * online at
+ * http://secondlifegrid.net/programs/open_source/licensing/flossexception
*
* By copying, modifying or distributing this software, you acknowledge
* that you have read and understood your obligations described above,
@@ -41,25 +42,11 @@
#include "lluictrlfactory.h"
-LLFloaterFontTest* LLFloaterFontTest::sInstance = NULL;
-
-LLFloaterFontTest::LLFloaterFontTest()
- : LLFloater(std::string("floater_font_test"), LLRect(0,500,700,0), std::string("Font Test"))
+LLFloaterFontTest::LLFloaterFontTest(const LLSD& key)
+ : LLFloater("floater_font_test")
{
- LLUICtrlFactory::getInstance()->buildFloater(this, "floater_font_test.xml");
}
LLFloaterFontTest::~LLFloaterFontTest()
{
- sInstance = NULL;
-}
-
-// static
-void LLFloaterFontTest::show(void *unused)
-{
- if (!sInstance)
- sInstance = new LLFloaterFontTest();
-
- sInstance->open(); /*Flawfinder: ignore*/
- sInstance->setFocus(TRUE);
}
diff --git a/indra/newview/llfloaterfonttest.h b/indra/newview/llfloaterfonttest.h
index 45ff890423..4406a9f36a 100644
--- a/indra/newview/llfloaterfonttest.h
+++ b/indra/newview/llfloaterfonttest.h
@@ -5,7 +5,7 @@
*
* $LicenseInfo:firstyear=2008&license=viewergpl$
*
- * Copyright (c) 2008, Linden Research, Inc.
+ * Copyright (c) 2008-2009, Linden Research, Inc.
*
* Second Life Viewer Source Code
* The source code in this file ("Source Code") is provided by Linden Lab
@@ -13,12 +13,13 @@
* ("GPL"), unless you have obtained a separate licensing agreement
* ("Other License"), formally executed by you and Linden Lab. Terms of
* the GPL can be found in doc/GPL-license.txt in this distribution, or
- * online at http://secondlife.com/developers/opensource/gplv2
+ * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
*
* There are special exceptions to the terms and conditions of the GPL as
* it is applied to this Source Code. View the full text of the exception
* in the file doc/FLOSS-exception.txt in this software distribution, or
- * online at http://secondlife.com/developers/opensource/flossexception
+ * online at
+ * http://secondlifegrid.net/programs/open_source/licensing/flossexception
*
* By copying, modifying or distributing this software, you acknowledge
* that you have read and understood your obligations described above,
@@ -38,14 +39,10 @@
class LLFloaterFontTest:
public LLFloater
{
-public:
- static void show(void* unused);
-
+ friend class LLFloaterReg;
private:
- LLFloaterFontTest();
+ LLFloaterFontTest(const LLSD& key);
~LLFloaterFontTest();
-
- static LLFloaterFontTest* sInstance;
};
#endif
diff --git a/indra/newview/llfloaterfriends.cpp b/indra/newview/llfloaterfriends.cpp
index 014a631a53..eb73bd6d8f 100644
--- a/indra/newview/llfloaterfriends.cpp
+++ b/indra/newview/llfloaterfriends.cpp
@@ -46,12 +46,14 @@
#include "llfloateravatarpicker.h"
#include "llviewerwindow.h"
#include "llbutton.h"
-#include "llfloateravatarinfo.h"
+#include "llavataractions.h"
#include "llinventorymodel.h"
#include "llnamelistctrl.h"
#include "llnotify.h"
#include "llresmgr.h"
-#include "llimview.h"
+#include "llscrolllistctrl.h"
+#include "llscrolllistitem.h"
+#include "llscrolllistcell.h"
#include "lluictrlfactory.h"
#include "llmenucommands.h"
#include "llviewercontrol.h"
@@ -60,6 +62,8 @@
#include "lltextbox.h"
#include "llvoiceclient.h"
+// *TODO: Move more common stuff to LLAvatarActions?
+
//Maximum number of people you can select to do an operation on at once.
#define MAX_FRIEND_SELECT 20
#define DEFAULT_PERIOD 5.0
@@ -148,7 +152,7 @@ void LLPanelFriends::updateFriends(U32 changed_mask)
// if the maximum amount of friends are selected
mShowMaxSelectWarning = false;
- LLDynamicArray<LLUUID> selected_friends = getSelectedIDs();
+ std::vector<LLUUID> selected_friends = getSelectedIDs();
if(changed_mask & (LLFriendObserver::ADD | LLFriendObserver::REMOVE | LLFriendObserver::ONLINE))
{
refreshNames(changed_mask);
@@ -173,7 +177,7 @@ void LLPanelFriends::updateFriends(U32 changed_mask)
// but we don't really care here, because refreshUI() will
// clean up the interface.
friends_list->setCurrentByID(selected_id);
- for(LLDynamicArray<LLUUID>::iterator itr = selected_friends.begin(); itr != selected_friends.end(); ++itr)
+ for(std::vector<LLUUID>::iterator itr = selected_friends.begin(); itr != selected_friends.end(); ++itr)
{
friends_list->setSelectedByValue(*itr, true);
}
@@ -188,10 +192,10 @@ BOOL LLPanelFriends::postBuild()
{
mFriendsList = getChild<LLScrollListCtrl>("friend_list");
mFriendsList->setMaxSelectable(MAX_FRIEND_SELECT);
- mFriendsList->setMaximumSelectCallback(onMaximumSelect);
+ mFriendsList->setMaximumSelectCallback(boost::bind(&LLPanelFriends::onMaximumSelect));
mFriendsList->setCommitOnSelectionChange(TRUE);
childSetCommitCallback("friend_list", onSelectName, this);
- childSetDoubleClickCallback("friend_list", onClickIM);
+ getChild<LLScrollListCtrl>("friend_list")->setDoubleClickCallback(onClickIM, this);
U32 changed_mask = LLFriendObserver::ADD | LLFriendObserver::REMOVE | LLFriendObserver::ONLINE;
refreshNames(changed_mask);
@@ -233,7 +237,7 @@ BOOL LLPanelFriends::addFriend(const LLUUID& agent_id)
friend_column["column"] = "friend_name";
friend_column["value"] = fullname;
friend_column["font"] = "SANSSERIF";
- friend_column["font-style"] = "NORMAL";
+ friend_column["font"]["style"] = "NORMAL";
LLSD& online_status_column = element["columns"][LIST_ONLINE_STATUS];
online_status_column["column"] = "icon_online_status";
@@ -241,12 +245,12 @@ BOOL LLPanelFriends::addFriend(const LLUUID& agent_id)
if (isOnline)
{
- friend_column["font-style"] = "BOLD";
+ friend_column["font"]["style"] = "BOLD";
online_status_column["value"] = "icon_avatar_online.tga";
}
else if(isOnlineSIP)
{
- friend_column["font-style"] = "BOLD";
+ friend_column["font"]["style"] = "BOLD";
online_status_column["value"] = ONLINE_SIP_ICON_NAME;
}
@@ -325,31 +329,14 @@ BOOL LLPanelFriends::updateFriendItem(const LLUUID& agent_id, const LLRelationsh
void LLPanelFriends::refreshRightsChangeList()
{
- LLDynamicArray<LLUUID> friends = getSelectedIDs();
+ std::vector<LLUUID> friends = getSelectedIDs();
S32 num_selected = friends.size();
bool can_offer_teleport = num_selected >= 1;
bool selected_friends_online = true;
- LLTextBox* processing_label = getChild<LLTextBox>("process_rights_label");
-
- if(!mAllowRightsChange)
- {
- if(processing_label)
- {
- processing_label->setVisible(true);
- // ignore selection for now
- friends.clear();
- num_selected = 0;
- }
- }
- else if(processing_label)
- {
- processing_label->setVisible(false);
- }
-
const LLRelationship* friend_status = NULL;
- for(LLDynamicArray<LLUUID>::iterator itr = friends.begin(); itr != friends.end(); ++itr)
+ for(std::vector<LLUUID>::iterator itr = friends.begin(); itr != friends.end(); ++itr)
{
friend_status = LLAvatarTracker::instance().getBuddyInfo(*itr);
if (friend_status)
@@ -391,7 +378,7 @@ struct SortFriendsByID
void LLPanelFriends::refreshNames(U32 changed_mask)
{
- LLDynamicArray<LLUUID> selected_ids = getSelectedIDs();
+ std::vector<LLUUID> selected_ids = getSelectedIDs();
S32 pos = mFriendsList->getScrollPos();
// get all buddies we know about
@@ -417,7 +404,7 @@ void LLPanelFriends::refreshNames(U32 changed_mask)
// Changed item in place, need to request sort and update columns
// because we might have changed data in a column on which the user
// has already sorted. JC
- mFriendsList->sortItems();
+ mFriendsList->updateSort();
// re-select items
mFriendsList->selectMultiple(selected_ids);
@@ -499,17 +486,8 @@ void LLPanelFriends::refreshUI()
single_selected = TRUE;
if(num_selected > 1)
{
- childSetText("friend_name_label", getString("Multiple"));
multiple_selected = TRUE;
}
- else
- {
- childSetText("friend_name_label", mFriendsList->getFirstSelected()->getColumn(LIST_FRIEND_NAME)->getValue().asString() + "...");
- }
- }
- else
- {
- childSetText("friend_name_label", LLStringUtil::null);
}
@@ -521,15 +499,15 @@ void LLPanelFriends::refreshUI()
//(single_selected will always be true in this situations)
childSetEnabled("remove_btn", single_selected);
childSetEnabled("im_btn", single_selected);
- childSetEnabled("friend_rights", single_selected);
+// childSetEnabled("friend_rights", single_selected);
refreshRightsChangeList();
}
-LLDynamicArray<LLUUID> LLPanelFriends::getSelectedIDs()
+std::vector<LLUUID> LLPanelFriends::getSelectedIDs()
{
LLUUID selected_id;
- LLDynamicArray<LLUUID> friend_ids;
+ std::vector<LLUUID> friend_ids;
std::vector<LLScrollListItem*> selected = mFriendsList->getAllSelected();
for(std::vector<LLScrollListItem*>::iterator itr = selected.begin(); itr != selected.end(); ++itr)
{
@@ -552,7 +530,7 @@ void LLPanelFriends::onSelectName(LLUICtrl* ctrl, void* user_data)
}
//static
-void LLPanelFriends::onMaximumSelect(void* user_data)
+void LLPanelFriends::onMaximumSelect()
{
LLSD args;
args["MAX_SELECT"] = llformat("%d", MAX_FRIEND_SELECT);
@@ -564,14 +542,11 @@ void LLPanelFriends::onClickProfile(void* user_data)
{
LLPanelFriends* panelp = (LLPanelFriends*)user_data;
- //llinfos << "LLPanelFriends::onClickProfile()" << llendl;
- LLDynamicArray<LLUUID> ids = panelp->getSelectedIDs();
+ std::vector<LLUUID> ids = panelp->getSelectedIDs();
if(ids.size() > 0)
{
LLUUID agent_id = ids[0];
- BOOL online;
- online = LLAvatarTracker::instance().isBuddyOnline(agent_id);
- LLFloaterAvatarInfo::showFromFriend(agent_id, online);
+ LLAvatarActions::showProfile(agent_id);
}
}
@@ -580,70 +555,18 @@ void LLPanelFriends::onClickIM(void* user_data)
{
LLPanelFriends* panelp = (LLPanelFriends*)user_data;
- //llinfos << "LLPanelFriends::onClickIM()" << llendl;
- LLDynamicArray<LLUUID> ids = panelp->getSelectedIDs();
+ std::vector<LLUUID> ids = panelp->getSelectedIDs();
if(ids.size() > 0)
{
if(ids.size() == 1)
{
- LLUUID agent_id = ids[0];
- const LLRelationship* info = LLAvatarTracker::instance().getBuddyInfo(agent_id);
- std::string fullname;
- if(info && gCacheName->getFullName(agent_id, fullname))
- {
- gIMMgr->setFloaterOpen(TRUE);
- gIMMgr->addSession(fullname, IM_NOTHING_SPECIAL, agent_id);
- }
+ LLAvatarActions::startIM(ids[0]);
}
else
{
- gIMMgr->setFloaterOpen(TRUE);
- gIMMgr->addSession("Friends Conference", IM_SESSION_CONFERENCE_START, ids[0], ids);
+ LLAvatarActions::startConference(ids);
}
- make_ui_sound("UISndStartIM");
- }
-}
-
-// static
-void LLPanelFriends::requestFriendship(const LLUUID& target_id, const std::string& target_name, const std::string& message)
-{
- LLUUID calling_card_folder_id = gInventory.findCategoryUUIDForType(LLAssetType::AT_CALLINGCARD);
- send_improved_im(target_id,
- target_name,
- message,
- IM_ONLINE,
- IM_FRIENDSHIP_OFFERED,
- calling_card_folder_id);
-}
-
-// static
-bool LLPanelFriends::callbackAddFriendWithMessage(const LLSD& notification, const LLSD& response)
-{
- S32 option = LLNotification::getSelectedOption(notification, response);
- if (option == 0)
- {
- requestFriendship(notification["payload"]["id"].asUUID(),
- notification["payload"]["name"].asString(),
- response["message"].asString());
}
- return false;
-}
-
-bool LLPanelFriends::callbackAddFriend(const LLSD& notification, const LLSD& response)
-{
- S32 option = LLNotification::getSelectedOption(notification, response);
- if (option == 0)
- {
- // Servers older than 1.25 require the text of the message to be the
- // calling card folder ID for the offering user. JC
- LLUUID calling_card_folder_id =
- gInventory.findCategoryUUIDForType(LLAssetType::AT_CALLINGCARD);
- std::string message = calling_card_folder_id.asString();
- requestFriendship(notification["payload"]["id"].asUUID(),
- notification["payload"]["name"].asString(),
- message);
- }
- return false;
}
// static
@@ -653,35 +576,7 @@ void LLPanelFriends::onPickAvatar(const std::vector<std::string>& names,
{
if (names.empty()) return;
if (ids.empty()) return;
- requestFriendshipDialog(ids[0], names[0]);
-}
-
-// static
-void LLPanelFriends::requestFriendshipDialog(const LLUUID& id,
- const std::string& name)
-{
- if(id == gAgentID)
- {
- LLNotifications::instance().add("AddSelfFriend");
- return;
- }
-
- LLSD args;
- args["NAME"] = name;
- LLSD payload;
- payload["id"] = id;
- payload["name"] = name;
- // Look for server versions like: Second Life Server 1.24.4.95600
- if (gLastVersionChannel.find(" 1.24.") != std::string::npos)
- {
- // Old and busted server version, doesn't support friend
- // requests with messages.
- LLNotifications::instance().add("AddFriend", args, payload, &callbackAddFriend);
- }
- else
- {
- LLNotifications::instance().add("AddFriendWithMessage", args, payload, &callbackAddFriendWithMessage);
- }
+ LLAvatarActions::requestFriendshipDialog(ids[0], names[0]);
}
// static
@@ -700,53 +595,14 @@ void LLPanelFriends::onClickAddFriend(void* user_data)
void LLPanelFriends::onClickRemove(void* user_data)
{
LLPanelFriends* panelp = (LLPanelFriends*)user_data;
-
- //llinfos << "LLPanelFriends::onClickRemove()" << llendl;
- LLDynamicArray<LLUUID> ids = panelp->getSelectedIDs();
- LLSD args;
- if(ids.size() > 0)
- {
- std::string msgType = "RemoveFromFriends";
- if(ids.size() == 1)
- {
- LLUUID agent_id = ids[0];
- std::string first, last;
- if(gCacheName->getName(agent_id, first, last))
- {
- args["FIRST_NAME"] = first;
- args["LAST_NAME"] = last;
- }
- }
- else
- {
- msgType = "RemoveMultipleFromFriends";
- }
- LLSD payload;
-
- for (LLDynamicArray<LLUUID>::iterator it = ids.begin();
- it != ids.end();
- ++it)
- {
- payload["ids"].append(*it);
- }
-
- LLNotifications::instance().add(msgType,
- args,
- payload,
- &handleRemove);
- }
+ LLAvatarActions::removeFriendsDialog(panelp->getSelectedIDs());
}
// static
void LLPanelFriends::onClickOfferTeleport(void* user_data)
{
LLPanelFriends* panelp = (LLPanelFriends*)user_data;
-
- LLDynamicArray<LLUUID> ids = panelp->getSelectedIDs();
- if(ids.size() > 0)
- {
- handle_lure(ids);
- }
+ LLAvatarActions::offerTeleport(panelp->getSelectedIDs());
}
// static
@@ -754,7 +610,7 @@ void LLPanelFriends::onClickPay(void* user_data)
{
LLPanelFriends* panelp = (LLPanelFriends*)user_data;
- LLDynamicArray<LLUUID> ids = panelp->getSelectedIDs();
+ std::vector<LLUUID> ids = panelp->getSelectedIDs();
if(ids.size() == 1)
{
handle_pay_by_id(ids[0]);
@@ -955,42 +811,3 @@ void LLPanelFriends::sendRightsGrant(rights_map_t& ids)
mNumRightsChanged = ids.size();
gAgent.sendReliableMessage();
}
-
-
-
-// static
-bool LLPanelFriends::handleRemove(const LLSD& notification, const LLSD& response)
-{
- S32 option = LLNotification::getSelectedOption(notification, response);
-
- const LLSD& ids = notification["payload"]["ids"];
- for(LLSD::array_const_iterator itr = ids.beginArray(); itr != ids.endArray(); ++itr)
- {
- LLUUID id = itr->asUUID();
- const LLRelationship* ip = LLAvatarTracker::instance().getBuddyInfo(id);
- if(ip)
- {
- switch(option)
- {
- case 0: // YES
- if( ip->isRightGrantedTo(LLRelationship::GRANT_MODIFY_OBJECTS))
- {
- LLAvatarTracker::instance().empower(id, FALSE);
- LLAvatarTracker::instance().notifyObservers();
- }
- LLAvatarTracker::instance().terminateBuddy(id);
- LLAvatarTracker::instance().notifyObservers();
- gInventory.addChangedMask(LLInventoryObserver::LABEL | LLInventoryObserver::CALLING_CARD, LLUUID::null);
- gInventory.notifyObservers();
- break;
-
- case 1: // NO
- default:
- llinfos << "No removal performed." << llendl;
- break;
- }
- }
-
- }
- return false;
-}
diff --git a/indra/newview/llfloaterfriends.h b/indra/newview/llfloaterfriends.h
index a5c94ee485..9242f00c91 100644
--- a/indra/newview/llfloaterfriends.h
+++ b/indra/newview/llfloaterfriends.h
@@ -74,15 +74,6 @@ public:
virtual BOOL postBuild();
- // Show a dialog explaining what friendship entails, then request
- // friendship. JC
- static void requestFriendshipDialog(const LLUUID& target_id,
- const std::string& target_name);
-
- // Just request friendship, no dialog.
- static void requestFriendship(const LLUUID& target_id,
- const std::string& target_name, const std::string& message);
-
private:
enum FRIENDS_COLUMN_ORDER
@@ -115,15 +106,15 @@ private:
void confirmModifyRights(rights_map_t& ids, EGrantRevoke command);
void sendRightsGrant(rights_map_t& ids);
- // return LLUUID::null if nothing is selected
- LLDynamicArray<LLUUID> getSelectedIDs();
+ // return empty vector if nothing is selected
+ std::vector<LLUUID> getSelectedIDs();
// callback methods
static void onSelectName(LLUICtrl* ctrl, void* user_data);
static bool callbackAddFriend(const LLSD& notification, const LLSD& response);
static bool callbackAddFriendWithMessage(const LLSD& notification, const LLSD& response);
static void onPickAvatar(const std::vector<std::string>& names, const std::vector<LLUUID>& ids, void* user_data);
- static void onMaximumSelect(void* user_data);
+ static void onMaximumSelect();
static void onClickIM(void* user_data);
static void onClickProfile(void* user_data);
@@ -135,7 +126,6 @@ private:
static void onClickModifyStatus(LLUICtrl* ctrl, void* user_data);
- static bool handleRemove(const LLSD& notification, const LLSD& response);
bool modifyRightsConfirmation(const LLSD& notification, const LLSD& response, rights_map_t* rights);
private:
diff --git a/indra/newview/llfloatergesture.cpp b/indra/newview/llfloatergesture.cpp
index 6d39d75663..431bc09d86 100644
--- a/indra/newview/llfloatergesture.cpp
+++ b/indra/newview/llfloatergesture.cpp
@@ -44,7 +44,7 @@
#include "llcombobox.h"
#include "llgesturemgr.h"
#include "llinventorymodel.h"
-#include "llinventoryview.h"
+#include "llfloaterinventory.h"
#include "llkeyboard.h"
#include "lllineeditor.h"
#include "llpreviewgesture.h"
@@ -53,17 +53,14 @@
#include "llscrollcontainer.h"
#include "llscrolllistctrl.h"
#include "lltextbox.h"
+#include "lltrans.h"
#include "lluictrlfactory.h"
#include "llviewergesture.h"
-#include "llviewerimagelist.h"
+#include "llviewertexturelist.h"
#include "llviewerinventory.h"
#include "llvoavatar.h"
#include "llviewercontrol.h"
-// static
-LLFloaterGesture* LLFloaterGesture::sInstance = NULL;
-LLFloaterGestureObserver* LLFloaterGesture::sObserver = NULL;
-
BOOL item_name_precedes( LLInventoryItem* a, LLInventoryItem* b )
{
return LLStringUtil::precedesDict( a->getName(), b->getName() );
@@ -72,35 +69,31 @@ BOOL item_name_precedes( LLInventoryItem* a, LLInventoryItem* b )
class LLFloaterGestureObserver : public LLGestureManagerObserver
{
public:
- LLFloaterGestureObserver() {}
+ LLFloaterGestureObserver(LLFloaterGesture* floater) : mFloater(floater) {}
virtual ~LLFloaterGestureObserver() {}
- virtual void changed() { LLFloaterGesture::refreshAll(); }
+ virtual void changed() { mFloater->refreshAll(); }
+
+private:
+ LLFloaterGesture* mFloater;
};
//---------------------------------------------------------------------------
// LLFloaterGesture
//---------------------------------------------------------------------------
-LLFloaterGesture::LLFloaterGesture()
-: LLFloater(std::string("Gesture Floater"))
+LLFloaterGesture::LLFloaterGesture(const LLSD& key)
+ : LLFloater(key)
{
- sInstance = this;
-
- sObserver = new LLFloaterGestureObserver;
- gGestureManager.addObserver(sObserver);
+ mObserver = new LLFloaterGestureObserver(this);
+ LLGestureManager::instance().addObserver(mObserver);
+ //LLUICtrlFactory::getInstance()->buildFloater(this, "floater_gesture.xml");
}
// virtual
LLFloaterGesture::~LLFloaterGesture()
{
- gGestureManager.removeObserver(sObserver);
- delete sObserver;
- sObserver = NULL;
-
- sInstance = NULL;
-
- // Custom saving rectangle, since load must be done
- // after postBuild.
- gSavedSettings.setRect("FloaterGestureRect2", getRect());
+ LLGestureManager::instance().removeObserver(mObserver);
+ delete mObserver;
+ mObserver = NULL;
}
// virtual
@@ -108,55 +101,31 @@ BOOL LLFloaterGesture::postBuild()
{
std::string label;
- // Translate title
label = getTitle();
setTitle(label);
- childSetCommitCallback("gesture_list", onCommitList, this);
- childSetDoubleClickCallback("gesture_list", onClickPlay);
+ getChild<LLUICtrl>("gesture_list")->setCommitCallback(boost::bind(&LLFloaterGesture::onCommitList, this));
+ getChild<LLScrollListCtrl>("gesture_list")->setDoubleClickCallback(boost::bind(&LLFloaterGesture::onClickPlay, this));
- childSetAction("inventory_btn", onClickInventory, this);
+ getChild<LLUICtrl>("inventory_btn")->setCommitCallback(boost::bind(&LLFloaterGesture::onClickInventory, this));
- childSetAction("edit_btn", onClickEdit, this);
+ getChild<LLUICtrl>("edit_btn")->setCommitCallback(boost::bind(&LLFloaterGesture::onClickEdit, this));
- childSetAction("play_btn", onClickPlay, this);
- childSetAction("stop_btn", onClickPlay, this);
+ getChild<LLUICtrl>("play_btn")->setCommitCallback(boost::bind(&LLFloaterGesture::onClickPlay, this));
+ getChild<LLUICtrl>("stop_btn")->setCommitCallback(boost::bind(&LLFloaterGesture::onClickPlay, this));
- childSetAction("new_gesture_btn", onClickNew, this);
+ getChild<LLUICtrl>("new_gesture_btn")->setCommitCallback(boost::bind(&LLFloaterGesture::onClickNew, this));
childSetVisible("play_btn", true);
childSetVisible("stop_btn", false);
setDefaultBtn("play_btn");
+
+ buildGestureList();
+
+ childSetFocus("gesture_list");
- return TRUE;
-}
-
-
-// static
-void LLFloaterGesture::show()
-{
- if (sInstance)
- {
- sInstance->open(); /*Flawfinder: ignore*/
- return;
- }
-
- LLFloaterGesture *self = new LLFloaterGesture();
-
- // Builds and adds to gFloaterView
- LLUICtrlFactory::getInstance()->buildFloater(self, "floater_gesture.xml");
-
- // Fix up rectangle
- LLRect rect = gSavedSettings.getRect("FloaterGestureRect2");
- self->reshape(rect.getWidth(), rect.getHeight());
- self->setRect(rect);
-
- self->buildGestureList();
-
- self->childSetFocus("gesture_list");
-
- LLCtrlListInterface *list = self->childGetListInterface("gesture_list");
+ LLCtrlListInterface *list = childGetListInterface("gesture_list");
if (list)
{
const BOOL ascending = TRUE;
@@ -164,51 +133,34 @@ void LLFloaterGesture::show()
list->selectFirstItem();
}
- self->mSelectedID = LLUUID::null;
-
// Update button labels
- onCommitList(NULL, self);
- self->open(); /*Flawfinder: ignore*/
+ onCommitList();
+
+ return TRUE;
}
-// static
-void LLFloaterGesture::toggleVisibility()
-{
- if(sInstance && sInstance->getVisible())
- {
- sInstance->close();
- }
- else
- {
- show();
- }
-}
-// static
void LLFloaterGesture::refreshAll()
{
- if (sInstance)
- {
- sInstance->buildGestureList();
+ buildGestureList();
- LLCtrlListInterface *list = sInstance->childGetListInterface("gesture_list");
- if (!list) return;
+ LLCtrlListInterface *list = childGetListInterface("gesture_list");
+ if (!list) return;
- if (sInstance->mSelectedID.isNull())
+ if (mSelectedID.isNull())
+ {
+ list->selectFirstItem();
+ }
+ else
+ {
+ if (! list->setCurrentByID(mSelectedID))
{
list->selectFirstItem();
}
- else
- {
- if (! list->setCurrentByID(sInstance->mSelectedID))
- {
- list->selectFirstItem();
- }
- }
-
- // Update button labels
- onCommitList(NULL, sInstance);
}
+
+ // Update button labels
+ onCommitList();
}
void LLFloaterGesture::buildGestureList()
@@ -225,13 +177,13 @@ void LLFloaterGesture::buildGestureList()
list->operateOnAll(LLCtrlListInterface::OP_DELETE);
LLGestureManager::item_map_t::iterator it;
- for (it = gGestureManager.mActive.begin(); it != gGestureManager.mActive.end(); ++it)
+ for (it = LLGestureManager::instance().mActive.begin(); it != LLGestureManager::instance().mActive.end(); ++it)
{
const LLUUID& item_id = (*it).first;
LLMultiGesture* gesture = (*it).second;
// Note: Can have NULL item if inventory hasn't arrived yet.
- std::string item_name = "Loading...";
+ std::string item_name = getString("loading");
LLInventoryItem* item = gInventory.getItem(item_id);
if (item)
{
@@ -254,7 +206,7 @@ void LLFloaterGesture::buildGestureList()
element["columns"][0]["column"] = "trigger";
element["columns"][0]["value"] = gesture->mTrigger;
element["columns"][0]["font"] = "SANSSERIF";
- element["columns"][0]["font-style"] = font_style;
+ element["columns"][0]["font"]["style"] = font_style;
std::string key_string = LLKeyboard::stringFromKey(gesture->mKey);
std::string buffer;
@@ -281,42 +233,42 @@ void LLFloaterGesture::buildGestureList()
element["columns"][1]["column"] = "shortcut";
element["columns"][1]["value"] = buffer;
element["columns"][1]["font"] = "SANSSERIF";
- element["columns"][1]["font-style"] = font_style;
+ element["columns"][1]["font"]["style"] = font_style;
// hidden column for sorting
element["columns"][2]["column"] = "key";
element["columns"][2]["value"] = key_string;
element["columns"][2]["font"] = "SANSSERIF";
- element["columns"][2]["font-style"] = font_style;
+ element["columns"][2]["font"]["style"] = font_style;
// Only add "playing" if we've got the name, less confusing. JC
if (item && gesture->mPlaying)
{
- item_name += " (Playing)";
+ item_name += " " + getString("playing");
}
element["columns"][3]["column"] = "name";
element["columns"][3]["value"] = item_name;
element["columns"][3]["font"] = "SANSSERIF";
- element["columns"][3]["font-style"] = font_style;
+ element["columns"][3]["font"]["style"] = font_style;
}
else
{
element["columns"][0]["column"] = "trigger";
element["columns"][0]["value"] = "";
element["columns"][0]["font"] = "SANSSERIF";
- element["columns"][0]["font-style"] = font_style;
+ element["columns"][0]["font"]["style"] = font_style;
element["columns"][0]["column"] = "trigger";
element["columns"][0]["value"] = "---";
element["columns"][0]["font"] = "SANSSERIF";
- element["columns"][0]["font-style"] = font_style;
+ element["columns"][0]["font"]["style"] = font_style;
element["columns"][2]["column"] = "key";
element["columns"][2]["value"] = "~~~";
element["columns"][2]["font"] = "SANSSERIF";
- element["columns"][2]["font-style"] = font_style;
+ element["columns"][2]["font"]["style"] = font_style;
element["columns"][3]["column"] = "name";
element["columns"][3]["value"] = item_name;
element["columns"][3]["font"] = "SANSSERIF";
- element["columns"][3]["font-style"] = font_style;
+ element["columns"][3]["font"]["style"] = font_style;
}
list->addElement(element, ADD_BOTTOM);
}
@@ -324,104 +276,80 @@ void LLFloaterGesture::buildGestureList()
scroll->setScrollPos(current_scroll_pos);
}
-// static
-void LLFloaterGesture::onClickInventory(void* data)
+void LLFloaterGesture::onClickInventory()
{
- LLFloaterGesture* self = (LLFloaterGesture*)data;
-
- LLCtrlListInterface *list = self->childGetListInterface("gesture_list");
+ LLCtrlListInterface *list = childGetListInterface("gesture_list");
if (!list) return;
const LLUUID& item_id = list->getCurrentID();
- LLInventoryView* inv = LLInventoryView::showAgentInventory();
+ LLFloaterInventory* inv = LLFloaterInventory::showAgentInventory();
if (!inv) return;
inv->getPanel()->setSelection(item_id, TRUE);
}
-// static
-void LLFloaterGesture::onClickPlay(void* data)
+void LLFloaterGesture::onClickPlay()
{
- LLFloaterGesture* self = (LLFloaterGesture*)data;
-
- LLCtrlListInterface *list = self->childGetListInterface("gesture_list");
+ LLCtrlListInterface *list = childGetListInterface("gesture_list");
if (!list) return;
const LLUUID& item_id = list->getCurrentID();
- if (gGestureManager.isGesturePlaying(item_id))
+ if (LLGestureManager::instance().isGesturePlaying(item_id))
{
- gGestureManager.stopGesture(item_id);
+ LLGestureManager::instance().stopGesture(item_id);
}
else
{
- gGestureManager.playGesture(item_id);
+ LLGestureManager::instance().playGesture(item_id);
}
}
class GestureShowCallback : public LLInventoryCallback
{
public:
- GestureShowCallback(std::string &title)
- {
- mTitle = title;
- }
void fire(const LLUUID &inv_item)
{
- LLPreviewGesture::show(mTitle, inv_item, LLUUID::null);
+ LLPreviewGesture::show(inv_item, LLUUID::null);
}
-private:
- std::string mTitle;
};
-// static
-void LLFloaterGesture::onClickNew(void* data)
+void LLFloaterGesture::onClickNew()
{
- std::string title("Gesture: ");
- title.append("New Gesture");
- LLPointer<LLInventoryCallback> cb = new GestureShowCallback(title);
+ LLPointer<LLInventoryCallback> cb = new GestureShowCallback();
create_inventory_item(gAgent.getID(), gAgent.getSessionID(),
LLUUID::null, LLTransactionID::tnull, "New Gesture", "", LLAssetType::AT_GESTURE,
LLInventoryType::IT_GESTURE, NOT_WEARABLE, PERM_MOVE | PERM_TRANSFER, cb);
}
-// static
-void LLFloaterGesture::onClickEdit(void* data)
+void LLFloaterGesture::onClickEdit()
{
- LLFloaterGesture* self = (LLFloaterGesture*)data;
-
- LLCtrlListInterface *list = self->childGetListInterface("gesture_list");
+ LLCtrlListInterface *list = childGetListInterface("gesture_list");
if (!list) return;
const LLUUID& item_id = list->getCurrentID();
LLInventoryItem* item = gInventory.getItem(item_id);
if (!item) return;
- std::string title("Gesture: ");
- title.append(item->getName());
-
- LLPreviewGesture* previewp = LLPreviewGesture::show(title, item_id, LLUUID::null);
+ LLPreviewGesture* previewp = LLPreviewGesture::show(item_id, LLUUID::null);
if (!previewp->getHost())
{
- previewp->setRect(gFloaterView->findNeighboringPosition(self, previewp));
+ previewp->setRect(gFloaterView->findNeighboringPosition(this, previewp));
}
}
-// static
-void LLFloaterGesture::onCommitList(LLUICtrl* ctrl, void* data)
+void LLFloaterGesture::onCommitList()
{
- LLFloaterGesture* self = (LLFloaterGesture*)data;
-
- const LLUUID& item_id = self->childGetValue("gesture_list").asUUID();
+ const LLUUID& item_id = childGetValue("gesture_list").asUUID();
- self->mSelectedID = item_id;
- if (gGestureManager.isGesturePlaying(item_id))
+ mSelectedID = item_id;
+ if (LLGestureManager::instance().isGesturePlaying(item_id))
{
- self->childSetVisible("play_btn", false);
- self->childSetVisible("stop_btn", true);
+ childSetVisible("play_btn", false);
+ childSetVisible("stop_btn", true);
}
else
{
- self->childSetVisible("play_btn", true);
- self->childSetVisible("stop_btn", false);
+ childSetVisible("play_btn", true);
+ childSetVisible("stop_btn", false);
}
}
diff --git a/indra/newview/llfloatergesture.h b/indra/newview/llfloatergesture.h
index 4e11a10e61..9c1ab27cb0 100644
--- a/indra/newview/llfloatergesture.h
+++ b/indra/newview/llfloatergesture.h
@@ -41,7 +41,7 @@
#include "lldarray.h"
-class LLScrollableContainerView;
+class LLScrollContainer;
class LLView;
class LLButton;
class LLLineEditor;
@@ -56,32 +56,28 @@ class LLFloaterGesture
: public LLFloater
{
public:
- LLFloaterGesture();
+ LLFloaterGesture(const LLSD& key);
virtual ~LLFloaterGesture();
virtual BOOL postBuild();
- static void show();
- static void toggleVisibility();
- static void refreshAll();
+ void refreshAll();
protected:
// Reads from the gesture manager's list of active gestures
// and puts them in this list.
void buildGestureList();
- static void onClickInventory(void* data);
- static void onClickEdit(void* data);
- static void onClickPlay(void* data);
- static void onClickNew(void* data);
- static void onCommitList(LLUICtrl* ctrl, void* data);
+ void onClickInventory();
+ void onClickEdit();
+ void onClickPlay();
+ void onClickNew();
+ void onCommitList();
protected:
LLUUID mSelectedID;
- static LLFloaterGesture* sInstance;
- static LLFloaterGestureObserver* sObserver;
- static LLFloaterGestureInventoryObserver* sInventoryObserver;
+ LLFloaterGestureObserver* mObserver;
};
diff --git a/indra/newview/llfloatergodtools.cpp b/indra/newview/llfloatergodtools.cpp
index 4959a2913e..886f5ec924 100644
--- a/indra/newview/llfloatergodtools.cpp
+++ b/indra/newview/llfloatergodtools.cpp
@@ -50,6 +50,7 @@
#include "llcombobox.h"
#include "lldraghandle.h"
#include "llfloater.h"
+#include "llfloaterreg.h"
#include "llfocusmgr.h"
#include "llfloatertopobjects.h"
#include "lllineeditor.h"
@@ -73,36 +74,39 @@
#include "llsurface.h"
#include "llviewercontrol.h"
#include "lluictrlfactory.h"
+#include "lltrans.h"
#include "lltransfertargetfile.h"
#include "lltransfersourcefile.h"
const F32 SECONDS_BETWEEN_UPDATE_REQUESTS = 5.0f;
-static LLFloaterGodTools* sGodTools = NULL;
-
//*****************************************************************************
// LLFloaterGodTools
//*****************************************************************************
-// static
-LLFloaterGodTools* LLFloaterGodTools::instance()
+void LLFloaterGodTools::onOpen(const LLSD& key)
{
- if (!sGodTools)
+ center();
+ setFocus(TRUE);
+// LLPanel *panel = childGetVisibleTab("GodTools Tabs");
+// if (panel)
+// panel->setFocus(TRUE);
+ if (mPanelObjectTools)
+ mPanelObjectTools->setTargetAvatar(LLUUID::null);
+
+ if (gAgent.getRegionHost() != mCurrentHost)
{
- sGodTools = new LLFloaterGodTools();
- sGodTools->open(); /*Flawfinder: ignore*/
- sGodTools->center();
- sGodTools->setFocus(TRUE);
+ // we're in a new region
+ sendRegionInfoRequest();
}
- return sGodTools;
}
// static
void LLFloaterGodTools::refreshAll()
{
- LLFloaterGodTools* god_tools = instance();
+ LLFloaterGodTools* god_tools = LLFloaterReg::getTypedInstance<LLFloaterGodTools>("god_tools");
if (god_tools)
{
if (gAgent.getRegionHost() != god_tools->mCurrentHost)
@@ -115,39 +119,36 @@ void LLFloaterGodTools::refreshAll()
-LLFloaterGodTools::LLFloaterGodTools()
-: LLFloater(std::string("godtools floater")),
+LLFloaterGodTools::LLFloaterGodTools(const LLSD& key)
+: LLFloater(key),
mCurrentHost(LLHost::invalid),
mUpdateTimer()
{
- LLCallbackMap::map_t factory_map;
- factory_map["grid"] = LLCallbackMap(createPanelGrid, this);
- factory_map["region"] = LLCallbackMap(createPanelRegion, this);
- factory_map["objects"] = LLCallbackMap(createPanelObjects, this);
- factory_map["request"] = LLCallbackMap(createPanelRequest, this);
- LLUICtrlFactory::getInstance()->buildFloater(this, "floater_god_tools.xml", &factory_map);
+ mFactoryMap["grid"] = LLCallbackMap(createPanelGrid, this);
+ mFactoryMap["region"] = LLCallbackMap(createPanelRegion, this);
+ mFactoryMap["objects"] = LLCallbackMap(createPanelObjects, this);
+ mFactoryMap["request"] = LLCallbackMap(createPanelRequest, this);
+// LLUICtrlFactory::getInstance()->buildFloater(this, "floater_god_tools.xml");
- childSetTabChangeCallback("GodTools Tabs", "grid", onTabChanged, this);
- childSetTabChangeCallback("GodTools Tabs", "region", onTabChanged, this);
- childSetTabChangeCallback("GodTools Tabs", "objects", onTabChanged, this);
- childSetTabChangeCallback("GodTools Tabs", "request", onTabChanged, this);
+}
+BOOL LLFloaterGodTools::postBuild()
+{
sendRegionInfoRequest();
-
childShowTab("GodTools Tabs", "region");
+ return TRUE;
}
-
// static
void* LLFloaterGodTools::createPanelGrid(void *userdata)
{
- return new LLPanelGridTools("grid");
+ return new LLPanelGridTools();
}
// static
void* LLFloaterGodTools::createPanelRegion(void *userdata)
{
LLFloaterGodTools* self = (LLFloaterGodTools*)userdata;
- self->mPanelRegionTools = new LLPanelRegionTools("region");
+ self->mPanelRegionTools = new LLPanelRegionTools();
return self->mPanelRegionTools;
}
@@ -155,14 +156,14 @@ void* LLFloaterGodTools::createPanelRegion(void *userdata)
void* LLFloaterGodTools::createPanelObjects(void *userdata)
{
LLFloaterGodTools* self = (LLFloaterGodTools*)userdata;
- self->mPanelObjectTools = new LLPanelObjectTools("objects");
+ self->mPanelObjectTools = new LLPanelObjectTools();
return self->mPanelObjectTools;
}
// static
void* LLFloaterGodTools::createPanelRequest(void *userdata)
{
- return new LLPanelRequestTools("region");
+ return new LLPanelRequestTools();
}
LLFloaterGodTools::~LLFloaterGodTools()
@@ -170,6 +171,7 @@ LLFloaterGodTools::~LLFloaterGodTools()
// children automatically deleted
}
+
U32 LLFloaterGodTools::computeRegionFlags() const
{
U32 flags = gAgent.getRegion()->getRegionFlags();
@@ -184,15 +186,6 @@ void LLFloaterGodTools::updatePopup(LLCoordGL center, MASK mask)
}
// virtual
-void LLFloaterGodTools::onClose(bool app_quitting)
-{
- if (sGodTools)
- {
- sGodTools->setVisible(FALSE);
- }
-}
-
-// virtual
void LLFloaterGodTools::draw()
{
if (mCurrentHost == LLHost::invalid)
@@ -209,42 +202,15 @@ void LLFloaterGodTools::draw()
LLFloater::draw();
}
-// static
-void LLFloaterGodTools::show(void *)
-{
- LLFloaterGodTools* god_tools = instance();
- god_tools->open();
- LLPanel *panel = god_tools->childGetVisibleTab("GodTools Tabs");
- if (panel) panel->setFocus(TRUE);
- if (god_tools->mPanelObjectTools) god_tools->mPanelObjectTools->setTargetAvatar(LLUUID::null);
-
- if (gAgent.getRegionHost() != god_tools->mCurrentHost)
- {
- // we're in a new region
- god_tools->sendRegionInfoRequest();
- }
-}
-
void LLFloaterGodTools::showPanel(const std::string& panel_name)
{
childShowTab("GodTools Tabs", panel_name);
- open(); /*Flawfinder: ignore*/
+ openFloater();
LLPanel *panel = childGetVisibleTab("GodTools Tabs");
- if (panel) panel->setFocus(TRUE);
-}
-
-
-// static
-void LLFloaterGodTools::onTabChanged(void* data, bool from_click)
-{
- LLPanel* panel = (LLPanel*)data;
if (panel)
- {
panel->setFocus(TRUE);
- }
}
-
// static
void LLFloaterGodTools::processRegionInfo(LLMessageSystem* msg)
{
@@ -297,16 +263,19 @@ void LLFloaterGodTools::processRegionInfo(LLMessageSystem* msg)
regionp->setWaterHeight(water_height);
regionp->setBillableFactor(billable_factor);
}
+
+ LLFloaterGodTools* god_tools = LLFloaterReg::getTypedInstance<LLFloaterGodTools>("god_tools");
+ if (!god_tools) return;
// push values to god tools, if available
- if (sGodTools
- && sGodTools->mPanelRegionTools
- && sGodTools->mPanelObjectTools
- && msg
- && gAgent.isGodlike())
+ if ( gAgent.isGodlike()
+ && LLFloaterReg::instanceVisible("god_tools")
+ && god_tools->mPanelRegionTools
+ && god_tools->mPanelObjectTools
+ && msg )
{
- LLPanelRegionTools* rtool = sGodTools->mPanelRegionTools;
- sGodTools->mCurrentHost = host;
+ LLPanelRegionTools* rtool = god_tools->mPanelRegionTools;
+ god_tools->mCurrentHost = host;
// store locally
rtool->setSimName(sim_name);
@@ -319,7 +288,7 @@ void LLFloaterGodTools::processRegionInfo(LLMessageSystem* msg)
rtool->setRedirectGridY(redirect_grid_y);
rtool->enableAllWidgets();
- LLPanelObjectTools *otool = sGodTools->mPanelObjectTools;
+ LLPanelObjectTools *otool = god_tools->mPanelObjectTools;
otool->setCheckFlags(region_flags);
otool->enableAllWidgets();
@@ -362,14 +331,17 @@ void LLFloaterGodTools::sendRegionInfoRequest()
void LLFloaterGodTools::sendGodUpdateRegionInfo()
{
+ LLFloaterGodTools* god_tools = LLFloaterReg::getTypedInstance<LLFloaterGodTools>("god_tools");
+ if (!god_tools) return;
+
LLViewerRegion *regionp = gAgent.getRegion();
if (gAgent.isGodlike()
- && sGodTools->mPanelRegionTools
+ && god_tools->mPanelRegionTools
&& regionp
&& gAgent.getRegionHost() == mCurrentHost)
{
LLMessageSystem *msg = gMessageSystem;
- LLPanelRegionTools *rtool = sGodTools->mPanelRegionTools;
+ LLPanelRegionTools *rtool = god_tools->mPanelRegionTools;
msg->newMessage("GodUpdateRegionInfo");
msg->nextBlockFast(_PREHASH_AgentData);
@@ -426,61 +398,34 @@ const F32 PRICE_PER_METER_MIN = 0.f;
const F32 PRICE_PER_METER_MAX = 100.f;
-LLPanelRegionTools::LLPanelRegionTools(const std::string& title)
-: LLPanel(title)
+LLPanelRegionTools::LLPanelRegionTools()
+: LLPanel()
{
+ mCommitCallbackRegistrar.add("RegionTools.ChangeAnything", boost::bind(&LLPanelRegionTools::onChangeAnything, this));
+ mCommitCallbackRegistrar.add("RegionTools.ChangePrelude", boost::bind(&LLPanelRegionTools::onChangePrelude, this));
+ mCommitCallbackRegistrar.add("RegionTools.BakeTerrain", boost::bind(&LLPanelRegionTools::onBakeTerrain, this));
+ mCommitCallbackRegistrar.add("RegionTools.RevertTerrain", boost::bind(&LLPanelRegionTools::onRevertTerrain, this));
+ mCommitCallbackRegistrar.add("RegionTools.SwapTerrain", boost::bind(&LLPanelRegionTools::onSwapTerrain, this));
+ mCommitCallbackRegistrar.add("RegionTools.Refresh", boost::bind(&LLPanelRegionTools::onRefresh, this));
+ mCommitCallbackRegistrar.add("RegionTools.ApplyChanges", boost::bind(&LLPanelRegionTools::onApplyChanges, this));
+ mCommitCallbackRegistrar.add("RegionTools.SelectRegion", boost::bind(&LLPanelRegionTools::onSelectRegion, this));
+ mCommitCallbackRegistrar.add("RegionTools.SaveState", boost::bind(&LLPanelRegionTools::onSaveState, this));
}
BOOL LLPanelRegionTools::postBuild()
{
- childSetCommitCallback("region name", onChangeAnything, this);
- childSetKeystrokeCallback("region name", onChangeSimName, this);
+ getChild<LLLineEditor>("region name")->setKeystrokeCallback(onChangeSimName, this);
childSetPrevalidate("region name", &LLLineEditor::prevalidatePrintableNotPipe);
-
- childSetCommitCallback("check prelude", onChangePrelude, this);
- childSetCommitCallback("check fixed sun", onChangeAnything, this);
- childSetCommitCallback("check reset home", onChangeAnything, this);
- childSetCommitCallback("check visible", onChangeAnything, this);
- childSetCommitCallback("check damage", onChangeAnything, this);
- childSetCommitCallback("block dwell", onChangeAnything, this);
- childSetCommitCallback("block terraform", onChangeAnything, this);
- childSetCommitCallback("allow transfer", onChangeAnything, this);
- childSetCommitCallback("is sandbox", onChangeAnything, this);
-
- childSetAction("Bake Terrain", onBakeTerrain, this);
- childSetAction("Revert Terrain", onRevertTerrain, this);
- childSetAction("Swap Terrain", onSwapTerrain, this);
-
- childSetCommitCallback("estate", onChangeAnything, this);
childSetPrevalidate("estate", &LLLineEditor::prevalidatePositiveS32);
-
- childSetCommitCallback("parentestate", onChangeAnything, this);
childSetPrevalidate("parentestate", &LLLineEditor::prevalidatePositiveS32);
childDisable("parentestate");
-
- childSetCommitCallback("gridposx", onChangeAnything, this);
childSetPrevalidate("gridposx", &LLLineEditor::prevalidatePositiveS32);
childDisable("gridposx");
-
- childSetCommitCallback("gridposy", onChangeAnything, this);
childSetPrevalidate("gridposy", &LLLineEditor::prevalidatePositiveS32);
childDisable("gridposy");
-
- childSetCommitCallback("redirectx", onChangeAnything, this);
+
childSetPrevalidate("redirectx", &LLLineEditor::prevalidatePositiveS32);
-
- childSetCommitCallback("redirecty", onChangeAnything, this);
childSetPrevalidate("redirecty", &LLLineEditor::prevalidatePositiveS32);
-
- childSetCommitCallback("billable factor", onChangeAnything, this);
-
- childSetCommitCallback("land cost", onChangeAnything, this);
-
- childSetAction("Refresh", onRefresh, this);
- childSetAction("Apply", onApplyChanges, this);
-
- childSetAction("Select Region", onSelectRegion, this);
- childSetAction("Autosave now", onSaveState, this);
return TRUE;
}
@@ -567,8 +512,6 @@ void LLPanelRegionTools::enableAllWidgets()
childEnable("Autosave now");
}
-
-// static
void LLPanelRegionTools::onSaveState(void* userdata)
{
if (gAgent.isGodlike())
@@ -765,92 +708,81 @@ void LLPanelRegionTools::setPricePerMeter(S32 price)
childSetValue("land cost", price);
}
-// static
-void LLPanelRegionTools::onChangeAnything(LLUICtrl* ctrl, void* userdata)
+void LLPanelRegionTools::onChangeAnything()
{
- if (sGodTools
- && userdata
- && gAgent.isGodlike())
+ if (gAgent.isGodlike())
{
- LLPanelRegionTools* region_tools = (LLPanelRegionTools*) userdata;
- region_tools->childEnable("Apply");
+ childEnable("Apply");
}
}
-// static
-void LLPanelRegionTools::onChangePrelude(LLUICtrl* ctrl, void* data)
+void LLPanelRegionTools::onChangePrelude()
{
// checking prelude auto-checks fixed sun
- LLPanelRegionTools* self = (LLPanelRegionTools*)data;
- if (self->childGetValue("check prelude").asBoolean())
+ if (childGetValue("check prelude").asBoolean())
{
- self->childSetValue("check fixed sun", TRUE);
- self->childSetValue("check reset home", TRUE);
+ childSetValue("check fixed sun", TRUE);
+ childSetValue("check reset home", TRUE);
+ onChangeAnything();
}
// pass on to default onChange handler
- onChangeAnything(ctrl, data);
+
}
// static
void LLPanelRegionTools::onChangeSimName(LLLineEditor* caller, void* userdata )
{
- if (sGodTools
- && userdata
- && gAgent.isGodlike())
+ if (userdata && gAgent.isGodlike())
{
LLPanelRegionTools* region_tools = (LLPanelRegionTools*) userdata;
region_tools->childEnable("Apply");
}
}
-//static
-void LLPanelRegionTools::onRefresh(void* userdata)
+
+void LLPanelRegionTools::onRefresh()
{
+ LLFloaterGodTools* god_tools = LLFloaterReg::getTypedInstance<LLFloaterGodTools>("god_tools");
+ if(!god_tools) return;
LLViewerRegion *region = gAgent.getRegion();
- if (region
- && sGodTools
- && gAgent.isGodlike())
+ if (region && gAgent.isGodlike())
{
- sGodTools->sendRegionInfoRequest();
+ god_tools->sendRegionInfoRequest();
+ //LLFloaterGodTools::getInstance()->sendRegionInfoRequest();
+ //LLFloaterReg::getTypedInstance<LLFloaterGodTools>("god_tools")->sendRegionInfoRequest();
}
}
-// static
-void LLPanelRegionTools::onApplyChanges(void* userdata)
+void LLPanelRegionTools::onApplyChanges()
{
+ LLFloaterGodTools* god_tools = LLFloaterReg::getTypedInstance<LLFloaterGodTools>("god_tools");
+ if(!god_tools) return;
LLViewerRegion *region = gAgent.getRegion();
- if (region
- && sGodTools
- && userdata
- && gAgent.isGodlike())
+ if (region && gAgent.isGodlike())
{
- LLPanelRegionTools* region_tools = (LLPanelRegionTools*) userdata;
-
- region_tools->childDisable("Apply");
- sGodTools->sendGodUpdateRegionInfo();
+ childDisable("Apply");
+ god_tools->sendGodUpdateRegionInfo();
+ //LLFloaterReg::getTypedInstance<LLFloaterGodTools>("god_tools")->sendGodUpdateRegionInfo();
}
}
-// static
-void LLPanelRegionTools::onBakeTerrain(void *userdata)
+void LLPanelRegionTools::onBakeTerrain()
{
LLPanelRequestTools::sendRequest("terrain", "bake", gAgent.getRegionHost());
}
-// static
-void LLPanelRegionTools::onRevertTerrain(void *userdata)
+void LLPanelRegionTools::onRevertTerrain()
{
LLPanelRequestTools::sendRequest("terrain", "revert", gAgent.getRegionHost());
}
-// static
-void LLPanelRegionTools::onSwapTerrain(void *userdata)
+
+void LLPanelRegionTools::onSwapTerrain()
{
LLPanelRequestTools::sendRequest("terrain", "swap", gAgent.getRegionHost());
}
-// static
-void LLPanelRegionTools::onSelectRegion(void* userdata)
+void LLPanelRegionTools::onSelectRegion()
{
llinfos << "LLPanelRegionTools::onSelectRegion" << llendl;
@@ -890,12 +822,13 @@ void LLPanelRegionTools::onSelectRegion(void* userdata)
// LEFT R2 RIGHT
const F32 HOURS_TO_RADIANS = (2.f*F_PI)/24.f;
-const char FLOATER_GRID_ADMIN_TITLE[] = "Grid Administration";
-LLPanelGridTools::LLPanelGridTools(const std::string& name) :
- LLPanel(name)
+LLPanelGridTools::LLPanelGridTools() :
+ LLPanel()
{
+ mCommitCallbackRegistrar.add("GridTools.KickAll", boost::bind(&LLPanelGridTools::onClickKickAll, this));
+ mCommitCallbackRegistrar.add("GridTools.FlushMapVisibilityCaches", boost::bind(&LLPanelGridTools::onClickFlushMapVisibilityCaches, this));
}
// Destroys the object
@@ -905,9 +838,6 @@ LLPanelGridTools::~LLPanelGridTools()
BOOL LLPanelGridTools::postBuild()
{
- childSetAction("Kick all users", onClickKickAll, this);
- childSetAction("Flush This Region's Map Visibility Caches", onClickFlushMapVisibilityCaches, this);
-
return TRUE;
}
@@ -915,14 +845,8 @@ void LLPanelGridTools::refresh()
{
}
-
-// static
-void LLPanelGridTools::onClickKickAll(void* userdata)
+void LLPanelGridTools::onClickKickAll()
{
- S32 left, top;
- gFloaterView->getNewFloaterPosition(&left, &top);
- LLRect rect(left, top, left+400, top-300);
-
LLNotifications::instance().add("KickAllUsers", LLSD(), LLSD(), LLPanelGridTools::confirmKick);
}
@@ -961,9 +885,7 @@ bool LLPanelGridTools::finishKick(const LLSD& notification, const LLSD& response
return false;
}
-
-// static
-void LLPanelGridTools::onClickFlushMapVisibilityCaches(void* data)
+void LLPanelGridTools::onClickFlushMapVisibilityCaches()
{
LLNotifications::instance().add("FlushMapVisibilityCaches", LLSD(), LLSD(), flushMapVisibilityCachesConfirm);
}
@@ -1017,9 +939,19 @@ bool LLPanelGridTools::flushMapVisibilityCachesConfirm(const LLSD& notification,
// LEFT RIGHT
// Default constructor
-LLPanelObjectTools::LLPanelObjectTools(const std::string& title)
-: LLPanel(title), mTargetAvatar()
+LLPanelObjectTools::LLPanelObjectTools()
+ : LLPanel(),
+ mTargetAvatar()
{
+ mCommitCallbackRegistrar.add("ObjectTools.ChangeAnything", boost::bind(&LLPanelObjectTools::onChangeAnything, this));
+ mCommitCallbackRegistrar.add("ObjectTools.DeletePublicOwnedBy", boost::bind(&LLPanelObjectTools::onClickDeletePublicOwnedBy, this));
+ mCommitCallbackRegistrar.add("ObjectTools.DeleteAllScriptedOwnedBy", boost::bind(&LLPanelObjectTools::onClickDeleteAllScriptedOwnedBy, this));
+ mCommitCallbackRegistrar.add("ObjectTools.DeleteAllOwnedBy", boost::bind(&LLPanelObjectTools::onClickDeleteAllOwnedBy, this));
+ mCommitCallbackRegistrar.add("ObjectTools.ApplyChanges", boost::bind(&LLPanelObjectTools::onApplyChanges, this));
+ mCommitCallbackRegistrar.add("ObjectTools.Set", boost::bind(&LLPanelObjectTools::onClickSet, this));
+ mCommitCallbackRegistrar.add("ObjectTools.GetTopColliders", boost::bind(&LLPanelObjectTools::onGetTopColliders, this));
+ mCommitCallbackRegistrar.add("ObjectTools.GetTopScripts", boost::bind(&LLPanelObjectTools::onGetTopScripts, this));
+ mCommitCallbackRegistrar.add("ObjectTools.GetScriptDigest", boost::bind(&LLPanelObjectTools::onGetScriptDigest, this));
}
// Destroys the object
@@ -1030,22 +962,6 @@ LLPanelObjectTools::~LLPanelObjectTools()
BOOL LLPanelObjectTools::postBuild()
{
- childSetCommitCallback("disable scripts", onChangeAnything, this);
- childSetCommitCallback("disable collisions", onChangeAnything, this);
- childSetCommitCallback("disable physics", onChangeAnything, this);
-
- childSetAction("Apply", onApplyChanges, this);
-
- childSetAction("Set Target", onClickSet, this);
-
- childSetAction("Delete Target's Scripted Objects On Others Land", onClickDeletePublicOwnedBy, this);
- childSetAction("Delete Target's Scripted Objects On *Any* Land", onClickDeleteAllScriptedOwnedBy, this);
- childSetAction("Delete *ALL* Of Target's Objects", onClickDeleteAllOwnedBy, this);
-
- childSetAction("Get Top Colliders", onGetTopColliders, this);
- childSetAction("Get Top Scripts", onGetTopScripts, this);
- childSetAction("Scripts digest", onGetScriptDigest, this);
-
return TRUE;
}
@@ -1054,7 +970,7 @@ void LLPanelObjectTools::setTargetAvatar(const LLUUID &target_id)
mTargetAvatar = target_id;
if (target_id.isNull())
{
- childSetValue("target_avatar_name", "(no target)");
+ childSetValue("target_avatar_name", getString("no_target"));
}
}
@@ -1134,35 +1050,35 @@ void LLPanelObjectTools::enableAllWidgets()
}
-// static
-void LLPanelObjectTools::onGetTopColliders(void* userdata)
+void LLPanelObjectTools::onGetTopColliders()
{
- if (sGodTools
- && gAgent.isGodlike())
+ LLFloaterTopObjects* instance = LLFloaterReg::getTypedInstance<LLFloaterTopObjects>("top_objects");
+ if(!instance) return;
+
+ if (gAgent.isGodlike())
{
- LLFloaterTopObjects::show();
+ LLFloaterReg::showInstance("top_objects");
LLFloaterTopObjects::setMode(STAT_REPORT_TOP_COLLIDERS);
- LLFloaterTopObjects::onRefresh(NULL);
+ instance->onRefresh();
}
}
-// static
-void LLPanelObjectTools::onGetTopScripts(void* userdata)
+void LLPanelObjectTools::onGetTopScripts()
{
- if (sGodTools
- && gAgent.isGodlike())
+ LLFloaterTopObjects* instance = LLFloaterReg::getTypedInstance<LLFloaterTopObjects>("top_objects");
+ if(!instance) return;
+
+ if (gAgent.isGodlike())
{
- LLFloaterTopObjects::show();
+ LLFloaterReg::showInstance("top_objects");
LLFloaterTopObjects::setMode(STAT_REPORT_TOP_SCRIPTS);
- LLFloaterTopObjects::onRefresh(NULL);
+ instance->onRefresh();
}
}
-// static
-void LLPanelObjectTools::onGetScriptDigest(void* userdata)
+void LLPanelObjectTools::onGetScriptDigest()
{
- if (sGodTools
- && gAgent.isGodlike())
+ if (gAgent.isGodlike())
{
// get the list of scripts and number of occurences of each
// (useful for finding self-replicating objects)
@@ -1170,20 +1086,20 @@ void LLPanelObjectTools::onGetScriptDigest(void* userdata)
}
}
-void LLPanelObjectTools::onClickDeletePublicOwnedBy(void* userdata)
+void LLPanelObjectTools::onClickDeletePublicOwnedBy()
{
// Bring up view-modal dialog
- LLPanelObjectTools* panelp = (LLPanelObjectTools*)userdata;
- if (!panelp->mTargetAvatar.isNull())
+
+ if (!mTargetAvatar.isNull())
{
- panelp->mSimWideDeletesFlags =
+ mSimWideDeletesFlags =
SWD_SCRIPTED_ONLY | SWD_OTHERS_LAND_ONLY;
LLSD args;
- args["AVATAR_NAME"] = panelp->childGetValue("target_avatar_name").asString();
+ args["AVATAR_NAME"] = childGetValue("target_avatar_name").asString();
LLSD payload;
- payload["avatar_id"] = panelp->mTargetAvatar;
- payload["flags"] = (S32)panelp->mSimWideDeletesFlags;
+ payload["avatar_id"] = mTargetAvatar;
+ payload["flags"] = (S32)mSimWideDeletesFlags;
LLNotifications::instance().add( "GodDeleteAllScriptedPublicObjectsByUser",
args,
@@ -1192,20 +1108,18 @@ void LLPanelObjectTools::onClickDeletePublicOwnedBy(void* userdata)
}
}
-// static
-void LLPanelObjectTools::onClickDeleteAllScriptedOwnedBy(void* userdata)
+void LLPanelObjectTools::onClickDeleteAllScriptedOwnedBy()
{
// Bring up view-modal dialog
- LLPanelObjectTools* panelp = (LLPanelObjectTools*)userdata;
- if (!panelp->mTargetAvatar.isNull())
+ if (!mTargetAvatar.isNull())
{
- panelp->mSimWideDeletesFlags = SWD_SCRIPTED_ONLY;
+ mSimWideDeletesFlags = SWD_SCRIPTED_ONLY;
LLSD args;
- args["AVATAR_NAME"] = panelp->childGetValue("target_avatar_name").asString();
+ args["AVATAR_NAME"] = childGetValue("target_avatar_name").asString();
LLSD payload;
- payload["avatar_id"] = panelp->mTargetAvatar;
- payload["flags"] = (S32)panelp->mSimWideDeletesFlags;
+ payload["avatar_id"] = mTargetAvatar;
+ payload["flags"] = (S32)mSimWideDeletesFlags;
LLNotifications::instance().add( "GodDeleteAllScriptedObjectsByUser",
args,
@@ -1214,20 +1128,18 @@ void LLPanelObjectTools::onClickDeleteAllScriptedOwnedBy(void* userdata)
}
}
-// static
-void LLPanelObjectTools::onClickDeleteAllOwnedBy(void* userdata)
+void LLPanelObjectTools::onClickDeleteAllOwnedBy()
{
// Bring up view-modal dialog
- LLPanelObjectTools* panelp = (LLPanelObjectTools*)userdata;
- if (!panelp->mTargetAvatar.isNull())
+ if (!mTargetAvatar.isNull())
{
- panelp->mSimWideDeletesFlags = 0;
+ mSimWideDeletesFlags = 0;
LLSD args;
- args["AVATAR_NAME"] = panelp->childGetValue("target_avatar_name").asString();
+ args["AVATAR_NAME"] = childGetValue("target_avatar_name").asString();
LLSD payload;
- payload["avatar_id"] = panelp->mTargetAvatar;
- payload["flags"] = (S32)panelp->mSimWideDeletesFlags;
+ payload["avatar_id"] = mTargetAvatar;
+ payload["flags"] = (S32)mSimWideDeletesFlags;
LLNotifications::instance().add( "GodDeleteAllObjectsByUser",
args,
@@ -1251,11 +1163,10 @@ bool LLPanelObjectTools::callbackSimWideDeletes( const LLSD& notification, const
return false;
}
-void LLPanelObjectTools::onClickSet(void* data)
+void LLPanelObjectTools::onClickSet()
{
- LLPanelObjectTools* panelp = (LLPanelObjectTools*) data;
// grandparent is a floater, which can have a dependent
- gFloaterView->getParentFloater(panelp)->addDependentFloater(LLFloaterAvatarPicker::show(callbackAvatarID, data));
+ gFloaterView->getParentFloater(this)->addDependentFloater(LLFloaterAvatarPicker::show(callbackAvatarID, this));
}
void LLPanelObjectTools::onClickSetBySelection(void* data)
@@ -1272,7 +1183,10 @@ void LLPanelObjectTools::onClickSetBySelection(void* data)
LLSelectMgr::getInstance()->selectGetOwner(owner_id, owner_name);
panelp->mTargetAvatar = owner_id;
- std::string name = "Object " + node->mName + " owned by " + owner_name;
+ LLStringUtil::format_map_t args;
+ args["[OBJECT]"] = node->mName;
+ args["[OWNER]"] = owner_name;
+ std::string name = LLTrans::getString("GodToolsObjectOwnedBy", args);
panelp->childSetValue("target_avatar_name", name);
}
@@ -1286,33 +1200,25 @@ void LLPanelObjectTools::callbackAvatarID(const std::vector<std::string>& names,
object_tools->refresh();
}
-
-// static
-void LLPanelObjectTools::onChangeAnything(LLUICtrl* ctrl, void* userdata)
+void LLPanelObjectTools::onChangeAnything()
{
- if (sGodTools
- && userdata
- && gAgent.isGodlike())
+ if (gAgent.isGodlike())
{
- LLPanelObjectTools* object_tools = (LLPanelObjectTools*) userdata;
- object_tools->childEnable("Apply");
+ childEnable("Apply");
}
}
-// static
-void LLPanelObjectTools::onApplyChanges(void* userdata)
+void LLPanelObjectTools::onApplyChanges()
{
+ LLFloaterGodTools* god_tools = LLFloaterReg::getTypedInstance<LLFloaterGodTools>("god_tools");
+ if(!god_tools) return;
LLViewerRegion *region = gAgent.getRegion();
- if (region
- && sGodTools
- && userdata
- && gAgent.isGodlike())
+ if (region && gAgent.isGodlike())
{
- LLPanelObjectTools* object_tools = (LLPanelObjectTools*) userdata;
// TODO -- implement this
-
- object_tools->childDisable("Apply");
- sGodTools->sendGodUpdateRegionInfo();
+ childDisable("Apply");
+ god_tools->sendGodUpdateRegionInfo();
+ //LLFloaterReg::getTypedInstance<LLFloaterGodTools>("god_tools")->sendGodUpdateRegionInfo();
}
}
@@ -1324,9 +1230,10 @@ void LLPanelObjectTools::onApplyChanges(void* userdata)
const std::string SELECTION = "Selection";
const std::string AGENT_REGION = "Agent Region";
-LLPanelRequestTools::LLPanelRequestTools(const std::string& name):
- LLPanel(name)
+LLPanelRequestTools::LLPanelRequestTools():
+ LLPanel()
{
+ mCommitCallbackRegistrar.add("GodTools.Request", boost::bind(&LLPanelRequestTools::onClickRequest, this));
}
LLPanelRequestTools::~LLPanelRequestTools()
@@ -1335,8 +1242,6 @@ LLPanelRequestTools::~LLPanelRequestTools()
BOOL LLPanelRequestTools::postBuild()
{
- childSetAction("Make Request", onClickRequest, this);
-
refresh();
return TRUE;
@@ -1348,9 +1253,13 @@ void LLPanelRequestTools::refresh()
LLCtrlListInterface *list = childGetListInterface("destination");
if (!list) return;
- list->operateOnAll(LLCtrlListInterface::OP_DELETE);
- list->addSimpleElement(SELECTION);
- list->addSimpleElement(AGENT_REGION);
+ S32 last_item = list->getItemCount();
+
+ if (last_item >=3)
+ {
+ list->selectItemRange(2,last_item);
+ list->operateOnSelection(LLCtrlListInterface::OP_DELETE);
+ }
for (LLWorld::region_list_t::const_iterator iter = LLWorld::getInstance()->getRegionList().begin();
iter != LLWorld::getInstance()->getRegionList().end(); ++iter)
{
@@ -1367,7 +1276,7 @@ void LLPanelRequestTools::refresh()
}
else
{
- list->selectByValue(SELECTION);
+ list->operateOnSelection(LLCtrlListInterface::OP_DESELECT);
}
}
@@ -1393,21 +1302,19 @@ void LLPanelRequestTools::sendRequest(const std::string& request,
msg->sendReliable(host);
}
-// static
-void LLPanelRequestTools::onClickRequest(void* data)
+void LLPanelRequestTools::onClickRequest()
{
- LLPanelRequestTools* self = (LLPanelRequestTools*)data;
- const std::string dest = self->childGetValue("destination").asString();
+ const std::string dest = childGetValue("destination").asString();
if(dest == SELECTION)
{
- std::string req = self->childGetValue("request");
+ std::string req =childGetValue("request");
req = req.substr(0, req.find_first_of(" "));
- std::string param = self->childGetValue("parameter");
+ std::string param = childGetValue("parameter");
LLSelectMgr::getInstance()->sendGodlikeRequest(req, param);
}
else if(dest == AGENT_REGION)
{
- self->sendRequest(gAgent.getRegionHost());
+ sendRequest(gAgent.getRegionHost());
}
else
{
@@ -1419,7 +1326,7 @@ void LLPanelRequestTools::onClickRequest(void* data)
if(dest == regionp->getName())
{
// found it
- self->sendRequest(regionp->getHost());
+ sendRequest(regionp->getHost());
}
}
}
diff --git a/indra/newview/llfloatergodtools.h b/indra/newview/llfloatergodtools.h
index 75813ca886..ebab1fde11 100644
--- a/indra/newview/llfloatergodtools.h
+++ b/indra/newview/llfloatergodtools.h
@@ -57,12 +57,11 @@ class LLTextBox;
class LLMessageSystem;
class LLFloaterGodTools
-: public LLFloater
+ : public LLFloater
{
+ friend class LLFloaterReg;
public:
- static LLFloaterGodTools* instance();
-
enum EGodPanel
{
PANEL_GRID,
@@ -72,9 +71,6 @@ public:
PANEL_COUNT
};
- static void show(void *);
- static void hide(void *);
-
static void* createPanelGrid(void *userdata);
static void* createPanelRegion(void *userdata);
static void* createPanelObjects(void *userdata);
@@ -84,7 +80,7 @@ public:
void showPanel(const std::string& panel_name);
- virtual void onClose(bool app_quitting);
+ virtual void onOpen(const LLSD& key);
virtual void draw();
@@ -101,21 +97,21 @@ public:
// Send possibly changed values to simulator.
void sendGodUpdateRegionInfo();
- static void onTabChanged(void *data, bool from_click);
-
+private:
+
+ LLFloaterGodTools(const LLSD& key);
+ ~LLFloaterGodTools();
+
protected:
U32 computeRegionFlags() const;
protected:
- LLFloaterGodTools();
- ~LLFloaterGodTools();
+ /*virtual*/ BOOL postBuild();
// When the floater is going away, reset any options that need to be
// cleared.
void resetToolState();
- static LLFloaterGodTools* sInstance;
-
public:
LLPanelRegionTools *mPanelRegionTools;
LLPanelObjectTools *mPanelObjectTools;
@@ -133,23 +129,24 @@ class LLPanelRegionTools
: public LLPanel
{
public:
- LLPanelRegionTools(const std::string& name);
+ LLPanelRegionTools();
/*virtual*/ ~LLPanelRegionTools();
BOOL postBuild();
/*virtual*/ void refresh();
- static void onSaveState(void* data);
- static void onChangeAnything(LLUICtrl* ctrl, void* userdata);
- static void onChangePrelude(LLUICtrl* ctrl, void* data);
+ static void onSaveState(void* userdata);
static void onChangeSimName(LLLineEditor* caller, void* userdata);
- static void onApplyChanges(void* userdata);
- static void onBakeTerrain(void *userdata);
- static void onRevertTerrain(void *userdata);
- static void onSwapTerrain(void *userdata);
- static void onSelectRegion(void *userdata);
- static void onRefresh(void* userdata);
+
+ void onChangeAnything();
+ void onChangePrelude();
+ void onApplyChanges();
+ void onBakeTerrain();
+ void onRevertTerrain();
+ void onSwapTerrain();
+ void onSelectRegion();
+ void onRefresh();
// set internal checkboxes/spinners/combos
const std::string getSimName() const;
@@ -194,18 +191,18 @@ class LLPanelGridTools
: public LLPanel
{
public:
- LLPanelGridTools(const std::string& name);
+ LLPanelGridTools();
virtual ~LLPanelGridTools();
BOOL postBuild();
void refresh();
- static void onClickKickAll(void *data);
+ void onClickKickAll();
static bool confirmKick(const LLSD& notification, const LLSD& response);
static bool finishKick(const LLSD& notification, const LLSD& response);
static void onDragSunPhase(LLUICtrl *ctrl, void *userdata);
- static void onClickFlushMapVisibilityCaches(void* data);
+ void onClickFlushMapVisibilityCaches();
static bool flushMapVisibilityCachesConfirm(const LLSD& notification, const LLSD& response);
protected:
@@ -221,7 +218,7 @@ class LLPanelObjectTools
: public LLPanel
{
public:
- LLPanelObjectTools(const std::string& name);
+ LLPanelObjectTools();
/*virtual*/ ~LLPanelObjectTools();
BOOL postBuild();
@@ -234,17 +231,17 @@ public:
void enableAllWidgets();
void setCheckFlags(U32 flags);
- static void onChangeAnything(LLUICtrl* ctrl, void* data);
- static void onApplyChanges(void* data);
- static void onClickSet(void* data);
+ void onChangeAnything();
+ void onApplyChanges();
+ void onClickSet();
static void callbackAvatarID(const std::vector<std::string>& names, const std::vector<LLUUID>& ids, void* data);
- static void onClickDeletePublicOwnedBy(void* data);
- static void onClickDeleteAllScriptedOwnedBy(void* data);
- static void onClickDeleteAllOwnedBy(void* data);
+ void onClickDeletePublicOwnedBy();
+ void onClickDeleteAllScriptedOwnedBy();
+ void onClickDeleteAllOwnedBy();
static bool callbackSimWideDeletes(const LLSD& notification, const LLSD& response);
- static void onGetTopColliders(void* data);
- static void onGetTopScripts(void* data);
- static void onGetScriptDigest(void* data);
+ void onGetTopColliders();
+ void onGetTopScripts();
+ void onGetScriptDigest();
static void onClickSetBySelection(void* data);
protected:
@@ -262,7 +259,7 @@ protected:
class LLPanelRequestTools : public LLPanel
{
public:
- LLPanelRequestTools(const std::string& name);
+ LLPanelRequestTools();
/*virtual*/ ~LLPanelRequestTools();
BOOL postBuild();
@@ -274,7 +271,7 @@ public:
const LLHost& host);
protected:
- static void onClickRequest(void *data);
+ void onClickRequest();
void sendRequest(const LLHost& host);
};
diff --git a/indra/newview/llfloatergroupinvite.cpp b/indra/newview/llfloatergroupinvite.cpp
index 08a6269a04..3598479305 100644
--- a/indra/newview/llfloatergroupinvite.cpp
+++ b/indra/newview/llfloatergroupinvite.cpp
@@ -34,9 +34,8 @@
#include "llfloatergroupinvite.h"
#include "llpanelgroupinvite.h"
-
-const char FLOATER_TITLE[] = "Group Invitation";
-const LLRect FGI_RECT(0, 380, 210, 0);
+#include "lltrans.h"
+#include "lldraghandle.h"
class LLFloaterGroupInvite::impl
{
@@ -73,25 +72,26 @@ void LLFloaterGroupInvite::impl::closeFloater(void* data)
{
LLFloaterGroupInvite* floaterp = (LLFloaterGroupInvite*) data;
- if ( floaterp ) floaterp->close();
+ if ( floaterp ) floaterp->closeFloater();
}
//-----------------------------------------------------------------------------
// Implementation
//-----------------------------------------------------------------------------
-LLFloaterGroupInvite::LLFloaterGroupInvite(const std::string& name,
- const LLRect &rect,
- const std::string& title,
- const LLUUID& group_id)
-: LLFloater(name, rect, title)
+LLFloaterGroupInvite::LLFloaterGroupInvite(const LLUUID& group_id)
+: LLFloater(group_id)
{
- LLRect contents(getRect());
- contents.mTop -= LLFLOATER_HEADER_SIZE;
+ static LLUICachedControl<S32> floater_header_size ("UIFloaterHeaderSize", 0);
+ LLRect contents;
mImpl = new impl(group_id);
- mImpl->mInvitePanelp = new LLPanelGroupInvite("Group Invite Panel",
- group_id);
+ mImpl->mInvitePanelp = new LLPanelGroupInvite(group_id);
+
+ contents = mImpl->mInvitePanelp->getRect();
+ contents.mTop -= floater_header_size;
+
+ setTitle (mImpl->mInvitePanelp->getString("GroupInvitation"));
mImpl->mInvitePanelp->setCloseCallback(impl::closeFloater, this);
@@ -114,6 +114,9 @@ LLFloaterGroupInvite::~LLFloaterGroupInvite()
// static
void LLFloaterGroupInvite::showForGroup(const LLUUID& group_id, std::vector<LLUUID> *agent_ids)
{
+ static LLUICachedControl<S32> floater_header_size ("UIFloaterHeaderSize", 0);
+ LLRect contents;
+
// Make sure group_id isn't null
if (group_id.isNull())
{
@@ -127,10 +130,12 @@ void LLFloaterGroupInvite::showForGroup(const LLUUID& group_id, std::vector<LLUU
(LLFloaterGroupInvite*)NULL);
if (!fgi)
{
- fgi = new LLFloaterGroupInvite("groupinfo",
- FGI_RECT,
- FLOATER_TITLE,
- group_id);
+ fgi = new LLFloaterGroupInvite(group_id);
+ contents = fgi->mImpl->mInvitePanelp->getRect();
+ contents.mTop += floater_header_size;
+ fgi->setRect(contents);
+ fgi->getDragHandle()->setRect(contents);
+ fgi->getDragHandle()->setTitle(fgi->mImpl->mInvitePanelp->getString("GroupInvitation"));
impl::sInstances[group_id] = fgi;
@@ -143,6 +148,6 @@ void LLFloaterGroupInvite::showForGroup(const LLUUID& group_id, std::vector<LLUU
}
fgi->center();
- fgi->open(); /*Flawfinder: ignore*/
+ fgi->openFloater();
fgi->mImpl->mInvitePanelp->update();
}
diff --git a/indra/newview/llfloatergroupinvite.h b/indra/newview/llfloatergroupinvite.h
index d1485ead91..b3f5d75ac1 100644
--- a/indra/newview/llfloatergroupinvite.h
+++ b/indra/newview/llfloatergroupinvite.h
@@ -46,10 +46,7 @@ public:
static void showForGroup(const LLUUID &group_id, std::vector<LLUUID> *agent_ids = NULL);
protected:
- LLFloaterGroupInvite(const std::string& name,
- const LLRect &rect,
- const std::string& title,
- const LLUUID& group_id = LLUUID::null);
+ LLFloaterGroupInvite(const LLUUID& group_id = LLUUID::null);
class impl;
impl* mImpl;
diff --git a/indra/newview/llfloatergroups.cpp b/indra/newview/llfloatergroups.cpp
index 9e0b0d7230..7a88612f1a 100644
--- a/indra/newview/llfloatergroups.cpp
+++ b/indra/newview/llfloatergroups.cpp
@@ -41,27 +41,18 @@
#include "llfloatergroups.h"
-#include "message.h"
#include "roles_constants.h"
#include "llagent.h"
#include "llbutton.h"
-#include "llfloatergroupinfo.h"
-#include "llfloaterdirectory.h"
-#include "llfocusmgr.h"
-#include "llalertdialog.h"
-#include "llselectmgr.h"
+#include "llgroupactions.h"
#include "llscrolllistctrl.h"
#include "lltextbox.h"
#include "lluictrlfactory.h"
-#include "llviewerwindow.h"
-#include "llimview.h"
+#include "lltrans.h"
using namespace LLOldEvents;
-// static
-std::map<const LLUUID, LLFloaterGroupPicker*> LLFloaterGroupPicker::sInstances;
-
// helper functions
void init_group_list(LLScrollListCtrl* ctrl, const LLUUID& highlight_id, U64 powers_mask = GP_ALL_POWERS);
@@ -69,44 +60,16 @@ void init_group_list(LLScrollListCtrl* ctrl, const LLUUID& highlight_id, U64 pow
/// Class LLFloaterGroupPicker
///----------------------------------------------------------------------------
-// static
-LLFloaterGroupPicker* LLFloaterGroupPicker::findInstance(const LLSD& seed)
-{
- instance_map_t::iterator found_it = sInstances.find(seed.asUUID());
- if (found_it != sInstances.end())
- {
- return found_it->second;
- }
- return NULL;
-}
-
-// static
-LLFloaterGroupPicker* LLFloaterGroupPicker::createInstance(const LLSD &seed)
+LLFloaterGroupPicker::LLFloaterGroupPicker(const LLSD& seed)
+: LLFloater(seed),
+ mPowersMask(GP_ALL_POWERS),
+ mID(seed.asUUID())
{
- LLFloaterGroupPicker* pickerp = new LLFloaterGroupPicker(seed);
- LLUICtrlFactory::getInstance()->buildFloater(pickerp, "floater_choose_group.xml");
- return pickerp;
-}
-
-LLFloaterGroupPicker::LLFloaterGroupPicker(const LLSD& seed) :
- mSelectCallback(NULL),
- mCallbackUserdata(NULL),
- mPowersMask(GP_ALL_POWERS)
-{
- mID = seed.asUUID();
- sInstances.insert(std::make_pair(mID, this));
+// LLUICtrlFactory::getInstance()->buildFloater(this, "floater_choose_group.xml");
}
LLFloaterGroupPicker::~LLFloaterGroupPicker()
{
- sInstances.erase(mID);
-}
-
-void LLFloaterGroupPicker::setSelectCallback(void (*callback)(LLUUID, void*),
- void* userdata)
-{
- mSelectCallback = callback;
- mCallbackUserdata = userdata;
}
void LLFloaterGroupPicker::setPowersMask(U64 powers_mask)
@@ -118,7 +81,18 @@ void LLFloaterGroupPicker::setPowersMask(U64 powers_mask)
BOOL LLFloaterGroupPicker::postBuild()
{
- init_group_list(getChild<LLScrollListCtrl>("group list"), gAgent.getGroupID(), mPowersMask);
+ LLScrollListCtrl* list_ctrl = getChild<LLScrollListCtrl>("group list");
+ init_group_list(list_ctrl, gAgent.getGroupID(), mPowersMask);
+
+ // Remove group "none" from list. Group "none" is added in init_group_list().
+ // Some UI elements use group "none", we need to manually delete it here.
+ // Group "none" ID is LLUUID:null.
+ LLCtrlListInterface* group_list = list_ctrl->getListInterface();
+ if(group_list)
+ {
+ group_list->selectByValue(LLUUID::null);
+ group_list->operateOnSelection(LLCtrlListInterface::OP_DELETE);
+ }
childSetAction("OK", onBtnOK, this);
@@ -126,8 +100,7 @@ BOOL LLFloaterGroupPicker::postBuild()
setDefaultBtn("OK");
- childSetDoubleClickCallback("group list", onBtnOK);
- childSetUserData("group list", this);
+ getChild<LLScrollListCtrl>("group list")->setDoubleClickCallback(onBtnOK, this);
childEnable("OK");
@@ -143,7 +116,7 @@ void LLFloaterGroupPicker::onBtnOK(void* userdata)
void LLFloaterGroupPicker::onBtnCancel(void* userdata)
{
LLFloaterGroupPicker* self = (LLFloaterGroupPicker*)userdata;
- if(self) self->close();
+ if(self) self->closeFloater();
}
@@ -155,12 +128,9 @@ void LLFloaterGroupPicker::ok()
{
group_id = group_list->getCurrentID();
}
- if(mSelectCallback)
- {
- mSelectCallback(group_id, mCallbackUserdata);
- }
+ mGroupSelectSignal(group_id);
- close();
+ closeFloater();
}
///----------------------------------------------------------------------------
@@ -229,8 +199,7 @@ BOOL LLPanelGroups::postBuild()
setDefaultBtn("IM");
- childSetDoubleClickCallback("group list", onBtnIM);
- childSetUserData("group list", this);
+ getChild<LLScrollListCtrl>("group list")->setDoubleClickCallback(onBtnIM, this);
reset();
@@ -315,113 +284,54 @@ void LLPanelGroups::onBtnSearch(void* userdata)
void LLPanelGroups::create()
{
- llinfos << "LLPanelGroups::create" << llendl;
- LLFloaterGroupInfo::showCreateGroup(NULL);
+ LLGroupActions::createGroup();
}
void LLPanelGroups::activate()
{
- llinfos << "LLPanelGroups::activate" << llendl;
LLCtrlListInterface *group_list = childGetListInterface("group list");
LLUUID group_id;
if (group_list)
{
group_id = group_list->getCurrentID();
}
- LLMessageSystem* msg = gMessageSystem;
- msg->newMessageFast(_PREHASH_ActivateGroup);
- msg->nextBlockFast(_PREHASH_AgentData);
- msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
- msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
- msg->addUUIDFast(_PREHASH_GroupID, group_id);
- gAgent.sendReliableMessage();
+ LLGroupActions::activate(group_id);
}
void LLPanelGroups::info()
{
- llinfos << "LLPanelGroups::info" << llendl;
LLCtrlListInterface *group_list = childGetListInterface("group list");
LLUUID group_id;
if (group_list && (group_id = group_list->getCurrentID()).notNull())
{
- LLFloaterGroupInfo::showFromUUID(group_id);
+ LLGroupActions::show(group_id);
}
}
void LLPanelGroups::startIM()
{
- //llinfos << "LLPanelFriends::onClickIM()" << llendl;
LLCtrlListInterface *group_list = childGetListInterface("group list");
LLUUID group_id;
if (group_list && (group_id = group_list->getCurrentID()).notNull())
{
- LLGroupData group_data;
- if (gAgent.getGroupData(group_id, group_data))
- {
- gIMMgr->setFloaterOpen(TRUE);
- gIMMgr->addSession(
- group_data.mName,
- IM_SESSION_GROUP_START,
- group_id);
- make_ui_sound("UISndStartIM");
- }
- else
- {
- // this should never happen, as starting a group IM session
- // relies on you belonging to the group and hence having the group data
- make_ui_sound("UISndInvalidOp");
- }
+ LLGroupActions::startChat(group_id);
}
}
void LLPanelGroups::leave()
{
- llinfos << "LLPanelGroups::leave" << llendl;
LLCtrlListInterface *group_list = childGetListInterface("group list");
LLUUID group_id;
if (group_list && (group_id = group_list->getCurrentID()).notNull())
{
- S32 count = gAgent.mGroups.count();
- S32 i;
- for(i = 0; i < count; ++i)
- {
- if(gAgent.mGroups.get(i).mID == group_id)
- break;
- }
- if(i < count)
- {
- LLSD args;
- args["GROUP"] = gAgent.mGroups.get(i).mName;
- LLSD payload;
- payload["group_id"] = group_id;
- LLNotifications::instance().add("GroupLeaveConfirmMember", args, payload, callbackLeaveGroup);
- }
+ LLGroupActions::leave(group_id);
}
}
void LLPanelGroups::search()
{
- LLFloaterDirectory::showGroups();
-}
-
-// static
-bool LLPanelGroups::callbackLeaveGroup(const LLSD& notification, const LLSD& response)
-{
- S32 option = LLNotification::getSelectedOption(notification, response);
- LLUUID group_id = notification["payload"]["group_id"].asUUID();
- if(option == 0)
- {
- LLMessageSystem* msg = gMessageSystem;
- msg->newMessageFast(_PREHASH_LeaveGroupRequest);
- msg->nextBlockFast(_PREHASH_AgentData);
- msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
- msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
- msg->nextBlockFast(_PREHASH_GroupData);
- msg->addUUIDFast(_PREHASH_GroupID, group_id);
- gAgent.sendReliableMessage();
- }
- return false;
+ LLGroupActions::search();
}
void LLPanelGroups::onGroupList(LLUICtrl* ctrl, void* userdata)
@@ -456,7 +366,7 @@ void init_group_list(LLScrollListCtrl* ctrl, const LLUUID& highlight_id, U64 pow
element["columns"][0]["column"] = "name";
element["columns"][0]["value"] = group_datap->mName;
element["columns"][0]["font"] = "SANSSERIF";
- element["columns"][0]["font-style"] = style;
+ element["columns"][0]["font"]["style"] = style;
group_list->addElement(element, ADD_SORTED);
}
@@ -472,9 +382,9 @@ void init_group_list(LLScrollListCtrl* ctrl, const LLUUID& highlight_id, U64 pow
LLSD element;
element["id"] = LLUUID::null;
element["columns"][0]["column"] = "name";
- element["columns"][0]["value"] = "none"; // *TODO: Translate
+ element["columns"][0]["value"] = LLTrans::getString("GroupsNone");
element["columns"][0]["font"] = "SANSSERIF";
- element["columns"][0]["font-style"] = style;
+ element["columns"][0]["font"]["style"] = style;
group_list->addElement(element, ADD_TOP);
}
diff --git a/indra/newview/llfloatergroups.h b/indra/newview/llfloatergroups.h
index 3eb3e5af52..489238356d 100644
--- a/indra/newview/llfloatergroups.h
+++ b/indra/newview/llfloatergroups.h
@@ -47,6 +47,8 @@
#include "lluuid.h"
#include "llfloater.h"
#include <map>
+#include <boost/function.hpp>
+#include <boost/signals2.hpp>
class LLUICtrl;
class LLTextBox;
@@ -54,13 +56,15 @@ class LLScrollListCtrl;
class LLButton;
class LLFloaterGroupPicker;
-class LLFloaterGroupPicker : public LLFloater, public LLUIFactory<LLFloaterGroupPicker, LLFloaterGroupPicker, VisibilityPolicy<LLFloater> >
+class LLFloaterGroupPicker : public LLFloater
{
- friend class LLUIFactory<LLFloaterGroupPicker>;
public:
+ LLFloaterGroupPicker(const LLSD& seed);
~LLFloaterGroupPicker();
- void setSelectCallback( void (*callback)(LLUUID, void*),
- void* userdata);
+
+ // Note: Don't return connection; use boost::bind + boost::signals2::trackable to disconnect slots
+ typedef boost::signals2::signal<void (LLUUID id)> signal_t;
+ void setSelectGroupCallback(const signal_t::slot_type& cb) { mGroupSelectSignal.connect(cb); }
void setPowersMask(U64 powers_mask);
BOOL postBuild();
@@ -69,7 +73,6 @@ public:
static LLFloaterGroupPicker* createInstance(const LLSD& seed);
protected:
- LLFloaterGroupPicker(const LLSD& seed);
void ok();
static void onBtnOK(void* userdata);
static void onBtnCancel(void* userdata);
@@ -77,8 +80,7 @@ protected:
protected:
LLUUID mID;
U64 mPowersMask;
- void (*mSelectCallback)(LLUUID id, void* userdata);
- void* mCallbackUserdata;
+ signal_t mGroupSelectSignal;
typedef std::map<const LLUUID, LLFloaterGroupPicker*> instance_map_t;
static instance_map_t sInstances;
diff --git a/indra/newview/llfloaterhandler.cpp b/indra/newview/llfloaterhandler.cpp
index f4c7e43a7d..e50a09ed86 100644
--- a/indra/newview/llfloaterhandler.cpp
+++ b/indra/newview/llfloaterhandler.cpp
@@ -31,7 +31,7 @@
#include "llfloaterhandler.h"
#include "llfloater.h"
-#include "llwebbrowserctrl.h"
+#include "llmediactrl.h"
// register with dispatch via global object
LLFloaterHandler gFloaterHandler;
@@ -54,7 +54,7 @@ LLFloater* get_parent_floater(LLView* view)
}
-bool LLFloaterHandler::handle(const LLSD &params, const LLSD &query_map, LLWebBrowserCtrl *web)
+bool LLFloaterHandler::handle(const LLSD &params, const LLSD &query_map, LLMediaCtrl *web)
{
if (params.size() < 2) return false;
LLFloater* floater = NULL;
@@ -70,7 +70,7 @@ bool LLFloaterHandler::handle(const LLSD &params, const LLSD &query_map, LLWebBr
{
if (floater)
{
- floater->close();
+ floater->closeFloater();
return true;
}
}
diff --git a/indra/newview/llfloaterhandler.h b/indra/newview/llfloaterhandler.h
index b08f1f35b4..31ea80c12c 100644
--- a/indra/newview/llfloaterhandler.h
+++ b/indra/newview/llfloaterhandler.h
@@ -39,7 +39,7 @@ class LLFloaterHandler
{
public:
LLFloaterHandler() : LLCommandHandler("floater", true) { }
- bool handle(const LLSD& params, const LLSD& query_map, LLWebBrowserCtrl* web);
+ bool handle(const LLSD& params, const LLSD& query_map, LLMediaCtrl* web);
};
#endif
diff --git a/indra/newview/llfloaterhardwaresettings.cpp b/indra/newview/llfloaterhardwaresettings.cpp
index 7886e394a3..3c3508b65c 100644
--- a/indra/newview/llfloaterhardwaresettings.cpp
+++ b/indra/newview/llfloaterhardwaresettings.cpp
@@ -33,27 +33,26 @@
#include "llviewerprecompiledheaders.h"
#include "llfloaterhardwaresettings.h"
+
+// Viewer includes
#include "llfloaterpreference.h"
#include "llviewerwindow.h"
#include "llviewercontrol.h"
-#include "llviewerimagelist.h"
+#include "llviewertexturelist.h"
#include "llfeaturemanager.h"
#include "llstartup.h"
+#include "pipeline.h"
+// Linden library includes
#include "llradiogroup.h"
#include "lluictrlfactory.h"
+#include "llwindow.h"
+#include "llslider.h"
-#include "llimagegl.h"
-#include "pipeline.h"
-
-LLFloaterHardwareSettings* LLFloaterHardwareSettings::sHardwareSettings = NULL;
-
-LLFloaterHardwareSettings::LLFloaterHardwareSettings() : LLFloater(std::string("Hardware Settings Floater"))
+LLFloaterHardwareSettings::LLFloaterHardwareSettings(const LLSD& key)
+ : LLFloater(key)
{
- LLUICtrlFactory::getInstance()->buildFloater(this, "floater_hardware_settings.xml");
-
- // load it up
- initCallbacks();
+ //LLUICtrlFactory::getInstance()->buildFloater(this, "floater_hardware_settings.xml");
}
LLFloaterHardwareSettings::~LLFloaterHardwareSettings()
@@ -90,10 +89,10 @@ void LLFloaterHardwareSettings::refresh()
void LLFloaterHardwareSettings::refreshEnabledState()
{
- S32 min_tex_mem = LLViewerImageList::getMinVideoRamSetting();
- S32 max_tex_mem = LLViewerImageList::getMaxVideoRamSetting();
- childSetMinValue("GrapicsCardTextureMemory", min_tex_mem);
- childSetMaxValue("GrapicsCardTextureMemory", max_tex_mem);
+ S32 min_tex_mem = LLViewerTextureList::getMinVideoRamSetting();
+ S32 max_tex_mem = LLViewerTextureList::getMaxVideoRamSetting();
+ getChild<LLSlider>("GrapicsCardTextureMemory")->setMinValue(min_tex_mem);
+ getChild<LLSlider>("GrapicsCardTextureMemory")->setMinValue(max_tex_mem);
if (!LLFeatureManager::getInstance()->isFeatureAvailable("RenderVBOEnable") ||
!gGLManager.mHasVertexBufferObject)
@@ -108,48 +107,6 @@ void LLFloaterHardwareSettings::refreshEnabledState()
}
-// static instance of it
-LLFloaterHardwareSettings* LLFloaterHardwareSettings::instance()
-{
- if (!sHardwareSettings)
- {
- sHardwareSettings = new LLFloaterHardwareSettings();
- sHardwareSettings->close();
- }
- return sHardwareSettings;
-}
-void LLFloaterHardwareSettings::show()
-{
- LLFloaterHardwareSettings* hardSettings = instance();
- hardSettings->refresh();
- hardSettings->center();
-
- // comment in if you want the menu to rebuild each time
- //LLUICtrlFactory::getInstance()->buildFloater(hardSettings, "floater_hardware_settings.xml");
- //hardSettings->initCallbacks();
-
- hardSettings->open();
-}
-
-bool LLFloaterHardwareSettings::isOpen()
-{
- if (sHardwareSettings != NULL)
- {
- return true;
- }
- return false;
-}
-
-// virtual
-void LLFloaterHardwareSettings::onClose(bool app_quitting)
-{
- if (sHardwareSettings)
- {
- sHardwareSettings->setVisible(FALSE);
- }
-}
-
-
//============================================================================
BOOL LLFloaterHardwareSettings::postBuild()
@@ -157,7 +114,10 @@ BOOL LLFloaterHardwareSettings::postBuild()
childSetAction("OK", onBtnOK, this);
refresh();
+ center();
+ // load it up
+ initCallbacks();
return TRUE;
}
@@ -203,7 +163,7 @@ void LLFloaterHardwareSettings::cancel()
gSavedSettings.setF32("RenderFogRatio", mFogRatio);
gSavedSettings.setBOOL("ProbeHardwareOnStartup", mProbeHardwareOnStartup );
- close();
+ closeFloater();
}
// static
@@ -211,6 +171,7 @@ void LLFloaterHardwareSettings::onBtnOK( void* userdata )
{
LLFloaterHardwareSettings *fp =(LLFloaterHardwareSettings *)userdata;
fp->apply();
- fp->close(false);
+ fp->closeFloater(false);
}
+
diff --git a/indra/newview/llfloaterhardwaresettings.h b/indra/newview/llfloaterhardwaresettings.h
index 04a33f69dc..3f19d89cbb 100644
--- a/indra/newview/llfloaterhardwaresettings.h
+++ b/indra/newview/llfloaterhardwaresettings.h
@@ -35,26 +35,21 @@
#include "llfloater.h"
-class LLSliderCtrl;
-
/// Menuing system for all of windlight's functionality
class LLFloaterHardwareSettings : public LLFloater
{
- friend class LLPreferenceCore;
+ friend class LLFloaterPreference;
public:
- LLFloaterHardwareSettings();
- virtual ~LLFloaterHardwareSettings();
+ LLFloaterHardwareSettings(const LLSD& key);
+ /*virtual*/ ~LLFloaterHardwareSettings();
- virtual BOOL postBuild();
+ /*virtual*/ BOOL postBuild();
/// initialize all the callbacks for the menu
void initCallbacks(void);
- /// one and one instance only
- static LLFloaterHardwareSettings* instance();
-
/// callback for the menus help button
static void onClickHelp(void* data);
@@ -69,9 +64,6 @@ public:
/// return if the menu exists or not
static bool isOpen();
- /// stuff to do on exit
- virtual void onClose(bool app_quitting);
-
/// sync up menu with parameters
void refresh();
@@ -85,8 +77,6 @@ public:
void refreshEnabledState();
protected:
- LLSliderCtrl* mCtrlVideoCardMem;
-
BOOL mUseVBO;
BOOL mUseAniso;
U32 mFSAASamples;
@@ -96,8 +86,6 @@ protected:
BOOL mProbeHardwareOnStartup;
private:
- // one instance on the inside
- static LLFloaterHardwareSettings* sHardwareSettings;
};
#endif
diff --git a/indra/newview/llfloaterhud.cpp b/indra/newview/llfloaterhud.cpp
index 9810bf1009..047dc2fa92 100644
--- a/indra/newview/llfloaterhud.cpp
+++ b/indra/newview/llfloaterhud.cpp
@@ -36,14 +36,12 @@
// Viewer libs
#include "llviewercontrol.h"
-#include "llwebbrowserctrl.h"
+#include "llmediactrl.h"
#include "llalertdialog.h"
// Linden libs
#include "lluictrlfactory.h"
-// statics
-LLFloaterHUD* LLFloaterHUD::sInstance = 0;
///----------------------------------------------------------------------------
/// Class LLFloaterHUD
@@ -51,12 +49,18 @@ LLFloaterHUD* LLFloaterHUD::sInstance = 0;
#define super LLFloater /* superclass */
// Default constructor
-LLFloaterHUD::LLFloaterHUD()
-: LLFloater(std::string("floater_hud")),
+LLFloaterHUD::LLFloaterHUD(const LLSD& key)
+: LLFloater(key),
mWebBrowser(0)
{
- // Create floater from its XML definition
- LLUICtrlFactory::getInstance()->buildFloater(this, "floater_hud.xml");
+ // do not build the floater if there the url is empty
+ if (gSavedSettings.getString("TutorialURL") == "")
+ {
+ LLNotifications::instance().add("TutorialNotFound");
+ return;
+ }
+
+ //LLUICtrlFactory::getInstance()->buildFloater(this, "floater_hud.xml");
// Don't grab the focus as it will impede performing in-world actions
// while using the HUD
@@ -68,79 +72,32 @@ LLFloaterHUD::LLFloaterHUD()
// Opaque background since we never get the focus
setBackgroundOpaque(TRUE);
+}
- // Position floater based on saved location
- LLRect saved_position_rect = gSavedSettings.getRect("FloaterHUDRect2");
- reshape(saved_position_rect.getWidth(), saved_position_rect.getHeight(), FALSE);
- setRect(saved_position_rect);
-
- mWebBrowser = getChild<LLWebBrowserCtrl>("floater_hud_browser" );
+BOOL LLFloaterHUD::postBuild()
+{
+ mWebBrowser = getChild<LLMediaCtrl>("floater_hud_browser" );
if (mWebBrowser)
{
// Open links in internal browser
mWebBrowser->setOpenInExternalBrowser(false);
-
+
// This is a "chrome" floater, so we don't want anything to
// take focus (as the user needs to be able to walk with
// arrow keys during tutorial).
mWebBrowser->setTakeFocusOnClick(false);
-
+
std::string language = LLUI::getLanguage();
std::string base_url = gSavedSettings.getString("TutorialURL");
-
+
std::string url = base_url + language + "/";
mWebBrowser->navigateTo(url);
}
-
- // Remember the one instance
- sInstance = this;
-}
-
-// Get the instance
-LLFloaterHUD* LLFloaterHUD::getInstance()
-{
- if (!sInstance)
- {
- new LLFloaterHUD();
- }
- return sInstance;
+
+ return TRUE;
}
// Destructor
LLFloaterHUD::~LLFloaterHUD()
{
- // Save floater position
- gSavedSettings.setRect("FloaterHUDRect2", getRect() );
-
- // Clear out the one instance if it's ours
- if (sInstance == this)
- {
- sInstance = NULL;
- }
-}
-
-// Show the HUD
-void LLFloaterHUD::showHUD()
-{
- // do not build the floater if there the url is empty
- if (gSavedSettings.getString("TutorialURL") == "")
- {
- LLNotifications::instance().add("TutorialNotFound");
- return;
- }
-
- // Create the instance if necessary
- LLFloaterHUD* hud = getInstance();
- hud->open();
- hud->setFrontmost(FALSE);
-}
-
-// Save our visibility state on close in case the user accidentally
-// quit the application while the tutorial was visible.
-// virtual
-void LLFloaterHUD::onClose(bool app_quitting)
-{
- bool stay_visible = app_quitting;
- gSavedSettings.setBOOL("ShowTutorial", stay_visible);
- destroy();
}
diff --git a/indra/newview/llfloaterhud.h b/indra/newview/llfloaterhud.h
index 2d58685b58..23ff82362a 100644
--- a/indra/newview/llfloaterhud.h
+++ b/indra/newview/llfloaterhud.h
@@ -35,26 +35,22 @@
#include "llfloater.h"
-class LLWebBrowserCtrl;
+class LLMediaCtrl;
class LLFloaterHUD : public LLFloater
{
+ friend class LLFloaterReg;
public:
- static LLFloaterHUD* getInstance(); ///< get instance creating if necessary
-
- static void showHUD(); ///< show the HUD
-
- // Save our visibility state during close
- /*virtual*/ void onClose(bool app_quitting);
+ BOOL postBuild();
+
private:
// Handles its own construction and destruction, so private.
- LLFloaterHUD();
+ LLFloaterHUD(const LLSD& key);
/*virtual*/ ~LLFloaterHUD();
private:
- LLWebBrowserCtrl* mWebBrowser; ///< the actual web browser control
- static LLFloaterHUD* sInstance;
+ LLMediaCtrl* mWebBrowser; ///< the actual web browser control
};
#endif // LL_LLFLOATERHUD_H
diff --git a/indra/newview/llfloaterimagepreview.cpp b/indra/newview/llfloaterimagepreview.cpp
index 5ff4f735dd..07dbf98a1e 100644
--- a/indra/newview/llfloaterimagepreview.cpp
+++ b/indra/newview/llfloaterimagepreview.cpp
@@ -56,12 +56,9 @@
#include "llvoavatar.h"
#include "pipeline.h"
#include "lluictrlfactory.h"
-#include "llviewerimagelist.h"
+#include "llviewertexturelist.h"
#include "llstring.h"
-//static
-S32 LLFloaterImagePreview::sUploadAmount = 10;
-
const S32 PREVIEW_BORDER_WIDTH = 2;
const S32 PREVIEW_RESIZE_HANDLE_SIZE = S32(RESIZE_HANDLE_WIDTH * OO_SQRT2) + PREVIEW_BORDER_WIDTH;
const S32 PREVIEW_HPAD = PREVIEW_RESIZE_HANDLE_SIZE;
@@ -93,9 +90,7 @@ BOOL LLFloaterImagePreview::postBuild()
{
return FALSE;
}
-
- childSetLabelArg("ok_btn", "[AMOUNT]", llformat("%d",sUploadAmount));
-
+
LLCtrlSelectionInterface* iface = childGetSelectionInterface("clothing_type_combo");
if (iface)
{
@@ -130,7 +125,9 @@ BOOL LLFloaterImagePreview::postBuild()
childDisable("clothing_type_combo");
childDisable("ok_btn");
}
-
+
+ getChild<LLUICtrl>("ok_btn")->setCommitCallback(boost::bind(&LLFloaterNameDesc::onBtnOK, this));
+
return TRUE;
}
@@ -142,9 +139,6 @@ LLFloaterImagePreview::~LLFloaterImagePreview()
clearAllPreviewTextures();
mRawImagep = NULL;
- delete mAvatarPreview;
- delete mSculptedPreview;
-
mImagep = NULL ;
}
@@ -252,7 +246,7 @@ void LLFloaterImagePreview::draw()
}
else
{
- mImagep = new LLImageGL(mRawImagep, FALSE) ;
+ mImagep = LLViewerTextureManager::getLocalTexture(mRawImagep.get(), FALSE) ;
gGL.getTexUnit(0)->unbind(mImagep->getTarget()) ;
gGL.getTexUnit(0)->bindManual(LLTexUnit::TT_TEXTURE, mImagep->getTexName());
@@ -294,11 +288,11 @@ void LLFloaterImagePreview::draw()
if (selected == 9)
{
- gGL.getTexUnit(0)->bind(mSculptedPreview->getTexture());
+ gGL.getTexUnit(0)->bind(mSculptedPreview);
}
else
{
- gGL.getTexUnit(0)->bind(mAvatarPreview->getTexture());
+ gGL.getTexUnit(0)->bind(mAvatarPreview);
}
gGL.begin( LLRender::QUADS );
@@ -606,7 +600,7 @@ void LLFloaterImagePreview::onMouseCaptureLostImagePreview(LLMouseHandler* handl
//-----------------------------------------------------------------------------
// LLImagePreviewAvatar
//-----------------------------------------------------------------------------
-LLImagePreviewAvatar::LLImagePreviewAvatar(S32 width, S32 height) : LLDynamicTexture(width, height, 3, ORDER_MIDDLE, FALSE)
+LLImagePreviewAvatar::LLImagePreviewAvatar(S32 width, S32 height) : LLViewerDynamicTexture(width, height, 3, ORDER_MIDDLE, FALSE)
{
mNeedsUpdate = TRUE;
mTargetJoint = NULL;
@@ -617,6 +611,7 @@ LLImagePreviewAvatar::LLImagePreviewAvatar(S32 width, S32 height) : LLDynamicTex
mCameraZoom = 1.f;
mDummyAvatar = (LLVOAvatar*)gObjectList.createObjectViewer(LL_PCODE_LEGACY_AVATAR, gAgent.getRegion());
+ mDummyAvatar->initInstance();
mDummyAvatar->createDrawable(&gPipeline);
mDummyAvatar->mIsDummy = TRUE;
mDummyAvatar->mSpecialRenderMode = 2;
@@ -696,7 +691,7 @@ BOOL LLImagePreviewAvatar::render()
glMatrixMode(GL_PROJECTION);
gGL.pushMatrix();
glLoadIdentity();
- glOrtho(0.0f, mWidth, 0.0f, mHeight, -1.0f, 1.0f);
+ glOrtho(0.0f, mFullWidth, 0.0f, mFullHeight, -1.0f, 1.0f);
glMatrixMode(GL_MODELVIEW);
gGL.pushMatrix();
@@ -705,7 +700,7 @@ BOOL LLImagePreviewAvatar::render()
LLGLSUIDefault def;
gGL.color4f(0.15f, 0.2f, 0.3f, 1.f);
- gl_rect_2d_simple( mWidth, mHeight );
+ gl_rect_2d_simple( mFullWidth, mFullHeight );
glMatrixMode(GL_PROJECTION);
gGL.popMatrix();
@@ -727,9 +722,9 @@ BOOL LLImagePreviewAvatar::render()
stop_glerror();
- LLViewerCamera::getInstance()->setAspect((F32)mWidth / mHeight);
+ LLViewerCamera::getInstance()->setAspect((F32)mFullWidth / mFullHeight);
LLViewerCamera::getInstance()->setView(LLViewerCamera::getInstance()->getDefaultFOV() / mCameraZoom);
- LLViewerCamera::getInstance()->setPerspective(FALSE, mOrigin.mX, mOrigin.mY, mWidth, mHeight, FALSE);
+ LLViewerCamera::getInstance()->setPerspective(FALSE, mOrigin.mX, mOrigin.mY, mFullWidth, mFullHeight, FALSE);
LLVertexBuffer::unbind();
avatarp->updateLOD();
@@ -787,7 +782,7 @@ void LLImagePreviewAvatar::pan(F32 right, F32 up)
// LLImagePreviewSculpted
//-----------------------------------------------------------------------------
-LLImagePreviewSculpted::LLImagePreviewSculpted(S32 width, S32 height) : LLDynamicTexture(width, height, 3, ORDER_MIDDLE, FALSE)
+LLImagePreviewSculpted::LLImagePreviewSculpted(S32 width, S32 height) : LLViewerDynamicTexture(width, height, 3, ORDER_MIDDLE, FALSE)
{
mNeedsUpdate = TRUE;
mCameraDistance = 0.f;
@@ -870,7 +865,7 @@ BOOL LLImagePreviewSculpted::render()
glMatrixMode(GL_PROJECTION);
gGL.pushMatrix();
glLoadIdentity();
- glOrtho(0.0f, mWidth, 0.0f, mHeight, -1.0f, 1.0f);
+ glOrtho(0.0f, mFullWidth, 0.0f, mFullHeight, -1.0f, 1.0f);
glMatrixMode(GL_MODELVIEW);
gGL.pushMatrix();
@@ -878,7 +873,7 @@ BOOL LLImagePreviewSculpted::render()
gGL.color4f(0.15f, 0.2f, 0.3f, 1.f);
- gl_rect_2d_simple( mWidth, mHeight );
+ gl_rect_2d_simple( mFullWidth, mFullHeight );
glMatrixMode(GL_PROJECTION);
gGL.popMatrix();
@@ -901,9 +896,9 @@ BOOL LLImagePreviewSculpted::render()
stop_glerror();
- LLViewerCamera::getInstance()->setAspect((F32) mWidth / mHeight);
+ LLViewerCamera::getInstance()->setAspect((F32) mFullWidth / mFullHeight);
LLViewerCamera::getInstance()->setView(LLViewerCamera::getInstance()->getDefaultFOV() / mCameraZoom);
- LLViewerCamera::getInstance()->setPerspective(FALSE, mOrigin.mX, mOrigin.mY, mWidth, mHeight, FALSE);
+ LLViewerCamera::getInstance()->setPerspective(FALSE, mOrigin.mX, mOrigin.mY, mFullWidth, mFullHeight, FALSE);
const LLVolumeFace &vf = mVolume->getVolumeFace(0);
U32 num_indices = vf.mIndices.size();
diff --git a/indra/newview/llfloaterimagepreview.h b/indra/newview/llfloaterimagepreview.h
index 6a4de3d3cc..f007697e88 100644
--- a/indra/newview/llfloaterimagepreview.h
+++ b/indra/newview/llfloaterimagepreview.h
@@ -44,12 +44,14 @@ class LLVOAvatar;
class LLTextBox;
class LLVertexBuffer;
-class LLImagePreviewSculpted : public LLDynamicTexture
+class LLImagePreviewSculpted : public LLViewerDynamicTexture
{
- public:
- LLImagePreviewSculpted(S32 width, S32 height);
+protected:
virtual ~LLImagePreviewSculpted();
+ public:
+ LLImagePreviewSculpted(S32 width, S32 height);
+
void setPreviewTarget(LLImageRaw *imagep, F32 distance);
void setTexture(U32 name) { mTextureName = name; }
@@ -73,12 +75,14 @@ class LLImagePreviewSculpted : public LLDynamicTexture
};
-class LLImagePreviewAvatar : public LLDynamicTexture
+class LLImagePreviewAvatar : public LLViewerDynamicTexture
{
-public:
- LLImagePreviewAvatar(S32 width, S32 height);
+protected:
virtual ~LLImagePreviewAvatar();
+public:
+ LLImagePreviewAvatar(S32 width, S32 height);
+
void setPreviewTarget(const std::string& joint_name, const std::string& mesh_name, LLImageRaw* imagep, F32 distance, BOOL male);
void setTexture(U32 name) { mTextureName = name; }
void clearPreviewTexture(const std::string& mesh_name);
@@ -117,7 +121,6 @@ public:
BOOL handleScrollWheel(S32 x, S32 y, S32 clicks);
static void onMouseCaptureLostImagePreview(LLMouseHandler*);
- static void setUploadAmount(S32 amount) { sUploadAmount = amount; }
void clearAllPreviewTextures();
@@ -127,15 +130,14 @@ protected:
bool loadImage(const std::string& filename);
LLPointer<LLImageRaw> mRawImagep;
- LLImagePreviewAvatar* mAvatarPreview;
- LLImagePreviewSculpted* mSculptedPreview;
+ LLPointer<LLImagePreviewAvatar> mAvatarPreview;
+ LLPointer<LLImagePreviewSculpted> mSculptedPreview;
S32 mLastMouseX;
S32 mLastMouseY;
LLRect mPreviewRect;
LLRectf mPreviewImageRect;
- LLPointer<LLImageGL> mImagep ;
+ LLPointer<LLViewerTexture> mImagep ;
- static S32 sUploadAmount;
};
#endif // LL_LLFLOATERIMAGEPREVIEW_H
diff --git a/indra/newview/llfloaterinspect.cpp b/indra/newview/llfloaterinspect.cpp
index de8a094fa9..e26937e93f 100644
--- a/indra/newview/llfloaterinspect.cpp
+++ b/indra/newview/llfloaterinspect.cpp
@@ -31,11 +31,15 @@
*/
#include "llviewerprecompiledheaders.h"
-#include "llfloateravatarinfo.h"
+
#include "llfloaterinspect.h"
+
+#include "llfloaterreg.h"
#include "llfloatertools.h"
+#include "llavataractions.h"
#include "llcachename.h"
#include "llscrolllistctrl.h"
+#include "llscrolllistitem.h"
#include "llselectmgr.h"
#include "lltoolcomp.h"
#include "lltoolmgr.h"
@@ -43,19 +47,33 @@
#include "llviewerobject.h"
#include "lluictrlfactory.h"
-LLFloaterInspect* LLFloaterInspect::sInstance = NULL;
+//LLFloaterInspect* LLFloaterInspect::sInstance = NULL;
-LLFloaterInspect::LLFloaterInspect(void) :
- LLFloater(std::string("Inspect Object")),
+LLFloaterInspect::LLFloaterInspect(const LLSD& key)
+ : LLFloater(key),
mDirty(FALSE)
{
- sInstance = this;
- LLUICtrlFactory::getInstance()->buildFloater(this, "floater_inspect.xml");
+ //LLUICtrlFactory::getInstance()->buildFloater(this, "floater_inspect.xml");
+ mCommitCallbackRegistrar.add("Inspect.OwnerProfile", boost::bind(&LLFloaterInspect::onClickOwnerProfile, this));
+ mCommitCallbackRegistrar.add("Inspect.CreatorProfile", boost::bind(&LLFloaterInspect::onClickCreatorProfile, this));
+ mCommitCallbackRegistrar.add("Inspect.SelectObject", boost::bind(&LLFloaterInspect::onSelectObject, this));
+}
+
+BOOL LLFloaterInspect::postBuild()
+{
+ mObjectList = getChild<LLScrollListCtrl>("object_list");
+// childSetAction("button owner",onClickOwnerProfile, this);
+// childSetAction("button creator",onClickCreatorProfile, this);
+// childSetCommitCallback("object_list", onSelectObject, NULL);
+
+ refresh();
+
+ return TRUE;
}
LLFloaterInspect::~LLFloaterInspect(void)
{
- if(!gFloaterTools->getVisible())
+ if(!LLFloaterReg::instanceVisible("build"))
{
if(LLToolMgr::getInstance()->getBaseTool() == LLToolCompInspect::getInstance())
{
@@ -66,16 +84,16 @@ LLFloaterInspect::~LLFloaterInspect(void)
}
else
{
- gFloaterTools->setFocus(TRUE);
+ LLFloaterReg::showInstance("build", LLSD(), TRUE);
}
- sInstance = NULL;
+ //sInstance = NULL;
}
-
+/*
BOOL LLFloaterInspect::isVisible()
{
return (!!sInstance);
-}
-
+}*/
+/*
void LLFloaterInspect::show(void* ignored)
{
// setForceSelection ensures that the pie menu does not deselect things when it
@@ -88,22 +106,29 @@ void LLFloaterInspect::show(void* ignored)
sInstance = new LLFloaterInspect;
}
- sInstance->open();
+ sInstance->openFloater();
LLToolMgr::getInstance()->setTransientTool(LLToolCompInspect::getInstance());
LLSelectMgr::getInstance()->setForceSelection(forcesel); // restore previouis value
sInstance->mObjectSelection = LLSelectMgr::getInstance()->getSelection();
sInstance->refresh();
}
-
-void LLFloaterInspect::onClickCreatorProfile(void* ctrl)
+*/
+void LLFloaterInspect::onOpen(const LLSD& key)
{
- if(sInstance->mObjectList->getAllSelected().size() == 0)
+ BOOL forcesel = LLSelectMgr::getInstance()->setForceSelection(TRUE);
+ LLToolMgr::getInstance()->setTransientTool(LLToolCompInspect::getInstance());
+ LLSelectMgr::getInstance()->setForceSelection(forcesel); // restore previouis value
+ mObjectSelection = LLSelectMgr::getInstance()->getSelection();
+ refresh();
+}
+void LLFloaterInspect::onClickCreatorProfile()
+{
+ if(mObjectList->getAllSelected().size() == 0)
{
return;
}
- LLScrollListItem* first_selected =
- sInstance->mObjectList->getFirstSelected();
+ LLScrollListItem* first_selected =mObjectList->getFirstSelected();
if (first_selected)
{
@@ -116,19 +141,18 @@ void LLFloaterInspect::onClickCreatorProfile(void* ctrl)
return (obj_id == node->getObject()->getID());
}
} func(first_selected->getUUID());
- LLSelectNode* node = sInstance->mObjectSelection->getFirstNode(&func);
+ LLSelectNode* node = mObjectSelection->getFirstNode(&func);
if(node)
{
- LLFloaterAvatarInfo::showFromDirectory(node->mPermissions->getCreator());
+ LLAvatarActions::showProfile(node->mPermissions->getCreator());
}
}
}
-void LLFloaterInspect::onClickOwnerProfile(void* ctrl)
+void LLFloaterInspect::onClickOwnerProfile()
{
- if(sInstance->mObjectList->getAllSelected().size() == 0) return;
- LLScrollListItem* first_selected =
- sInstance->mObjectList->getFirstSelected();
+ if(mObjectList->getAllSelected().size() == 0) return;
+ LLScrollListItem* first_selected =mObjectList->getFirstSelected();
if (first_selected)
{
@@ -142,46 +166,34 @@ void LLFloaterInspect::onClickOwnerProfile(void* ctrl)
return (obj_id == node->getObject()->getID());
}
} func(selected_id);
- LLSelectNode* node = sInstance->mObjectSelection->getFirstNode(&func);
+ LLSelectNode* node = mObjectSelection->getFirstNode(&func);
if(node)
{
const LLUUID& owner_id = node->mPermissions->getOwner();
- LLFloaterAvatarInfo::showFromDirectory(owner_id);
+ LLAvatarActions::showProfile(owner_id);
}
}
}
-BOOL LLFloaterInspect::postBuild()
-{
- mObjectList = getChild<LLScrollListCtrl>("object_list");
- childSetAction("button owner",onClickOwnerProfile, this);
- childSetAction("button creator",onClickCreatorProfile, this);
- childSetCommitCallback("object_list", onSelectObject);
- return TRUE;
-}
-
-void LLFloaterInspect::onSelectObject(LLUICtrl* ctrl, void* user_data)
+void LLFloaterInspect::onSelectObject()
{
if(LLFloaterInspect::getSelectedUUID() != LLUUID::null)
{
- sInstance->childSetEnabled("button owner", true);
- sInstance->childSetEnabled("button creator", true);
+ childSetEnabled("button owner", true);
+ childSetEnabled("button creator", true);
}
}
LLUUID LLFloaterInspect::getSelectedUUID()
{
- if(sInstance)
+ if(mObjectList->getAllSelected().size() > 0)
{
- if(sInstance->mObjectList->getAllSelected().size() > 0)
+ LLScrollListItem* first_selected =mObjectList->getFirstSelected();
+ if (first_selected)
{
- LLScrollListItem* first_selected =
- sInstance->mObjectList->getFirstSelected();
- if (first_selected)
- {
- return first_selected->getUUID();
- }
+ return first_selected->getUUID();
}
+
}
return LLUUID::null;
}
@@ -212,7 +224,6 @@ void LLFloaterInspect::refresh()
{
LLSelectNode* obj = *iter;
LLSD row;
- char time[MAX_STRING];
std::string owner_name, creator_name;
if (obj->mCreationDate == 0)
@@ -221,8 +232,11 @@ void LLFloaterInspect::refresh()
}
time_t timestamp = (time_t) (obj->mCreationDate/1000000);
- LLStringUtil::copy(time, ctime(&timestamp), MAX_STRING);
- time[24] = '\0';
+ std::string timeStr = getString("timeStamp");
+ LLSD substitution;
+ substitution["datetime"] = (S32) timestamp;
+ LLStringUtil::format (timeStr, substitution);
+
gCacheName->getFullName(obj->mPermissions->getOwner(), owner_name);
gCacheName->getFullName(obj->mPermissions->getCreator(), creator_name);
row["id"] = obj->getObject()->getID();
@@ -246,7 +260,7 @@ void LLFloaterInspect::refresh()
row["columns"][2]["value"] = creator_name;
row["columns"][3]["column"] = "creation_date";
row["columns"][3]["type"] = "text";
- row["columns"][3]["value"] = time;
+ row["columns"][3]["value"] = timeStr;
mObjectList->addElement(row, ADD_TOP);
}
if(selected_index > -1 && mObjectList->getItemIndex(selected_uuid) == selected_index)
@@ -257,7 +271,7 @@ void LLFloaterInspect::refresh()
{
mObjectList->selectNthItem(0);
}
- onSelectObject(this, NULL);
+ onSelectObject();
mObjectList->setScrollPos(pos);
}
@@ -269,10 +283,7 @@ void LLFloaterInspect::onFocusReceived()
void LLFloaterInspect::dirty()
{
- if(sInstance)
- {
- sInstance->setDirty();
- }
+ setDirty();
}
void LLFloaterInspect::draw()
diff --git a/indra/newview/llfloaterinspect.h b/indra/newview/llfloaterinspect.h
index 57bba6864f..ce9485ee74 100644
--- a/indra/newview/llfloaterinspect.h
+++ b/indra/newview/llfloaterinspect.h
@@ -44,29 +44,33 @@ class LLUICtrl;
class LLFloaterInspect : public LLFloater
{
+ friend class LLFloaterReg;
public:
- virtual ~LLFloaterInspect(void);
- static void show(void* ignored = NULL);
+
+// static void show(void* ignored = NULL);
+ void onOpen(const LLSD& key);
virtual BOOL postBuild();
- static void dirty();
- static LLUUID getSelectedUUID();
+ void dirty();
+ LLUUID getSelectedUUID();
virtual void draw();
virtual void refresh();
- static BOOL isVisible();
+// static BOOL isVisible();
virtual void onFocusReceived();
- static void onClickCreatorProfile(void* ctrl);
- static void onClickOwnerProfile(void* ctrl);
- static void onSelectObject(LLUICtrl* ctrl, void* user_data);
+ void onClickCreatorProfile();
+ void onClickOwnerProfile();
+ void onSelectObject();
LLScrollListCtrl* mObjectList;
protected:
// protected members
- LLFloaterInspect();
void setDirty() { mDirty = TRUE; }
bool mDirty;
private:
+
+ LLFloaterInspect(const LLSD& key);
+ virtual ~LLFloaterInspect(void);
// static data
- static LLFloaterInspect* sInstance;
+// static LLFloaterInspect* sInstance;
LLSafeHandle<LLObjectSelection> mObjectSelection;
};
diff --git a/indra/newview/llfloaterinventory.cpp b/indra/newview/llfloaterinventory.cpp
new file mode 100644
index 0000000000..45a42f994d
--- /dev/null
+++ b/indra/newview/llfloaterinventory.cpp
@@ -0,0 +1,1885 @@
+/**
+ * @file llfloaterinventory.cpp
+ * @brief Implementation of the inventory view and associated stuff.
+ *
+ * $LicenseInfo:firstyear=2001&license=viewergpl$
+ *
+ * Copyright (c) 2001-2009, Linden Research, Inc.
+ *
+ * Second Life Viewer Source Code
+ * The source code in this file ("Source Code") is provided by Linden Lab
+ * to you under the terms of the GNU General Public License, version 2.0
+ * ("GPL"), unless you have obtained a separate licensing agreement
+ * ("Other License"), formally executed by you and Linden Lab. Terms of
+ * the GPL can be found in doc/GPL-license.txt in this distribution, or
+ * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
+ *
+ * There are special exceptions to the terms and conditions of the GPL as
+ * it is applied to this Source Code. View the full text of the exception
+ * in the file doc/FLOSS-exception.txt in this software distribution, or
+ * online at
+ * http://secondlifegrid.net/programs/open_source/licensing/flossexception
+ *
+ * By copying, modifying or distributing this software, you acknowledge
+ * that you have read and understood your obligations described above,
+ * and agree to abide by those obligations.
+ *
+ * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+ * COMPLETENESS OR PERFORMANCE.
+ * $/LicenseInfo$
+ */
+
+#include "llviewerprecompiledheaders.h"
+
+#include <utility> // for std::pair<>
+
+#include "llfloaterinventory.h"
+
+// library includes
+#include "llagent.h"
+#include "llagentwearables.h"
+#include "llcallingcard.h"
+#include "llfloaterreg.h"
+#include "llsdserialize.h"
+#include "llfiltereditor.h"
+#include "llspinctrl.h"
+#include "llui.h"
+#include "message.h"
+
+// newview includes
+#include "llappviewer.h"
+#include "llfirstuse.h"
+#include "llfloaterchat.h"
+#include "llfloatercustomize.h"
+#include "llfocusmgr.h"
+#include "llfolderview.h"
+#include "llgesturemgr.h"
+#include "lliconctrl.h"
+#include "llimview.h"
+#include "llinventorybridge.h"
+#include "llinventoryclipboard.h"
+#include "llinventorymodel.h"
+#include "lllineeditor.h"
+#include "llmenugl.h"
+#include "llpreviewanim.h"
+#include "llpreviewgesture.h"
+#include "llpreviewnotecard.h"
+#include "llpreviewscript.h"
+#include "llpreviewsound.h"
+#include "llpreviewtexture.h"
+#include "llresmgr.h"
+#include "llscrollbar.h"
+#include "llscrollcontainer.h"
+#include "llselectmgr.h"
+#include "lltabcontainer.h"
+#include "lltooldraganddrop.h"
+#include "lluictrlfactory.h"
+#include "llviewerinventory.h"
+#include "llviewermessage.h"
+#include "llviewerobjectlist.h"
+#include "llviewerregion.h"
+#include "llviewerwindow.h"
+#include "llvoavatarself.h"
+#include "llwearablelist.h"
+
+static LLDefaultChildRegistry::Register<LLInventoryPanel> r("inventory_panel");
+
+//BOOL LLFloaterInventory::sOpenNextNewItem = FALSE;
+BOOL LLFloaterInventory::sWearNewClothing = FALSE;
+LLUUID LLFloaterInventory::sWearNewClothingTransactionID;
+
+///----------------------------------------------------------------------------
+/// LLFloaterInventoryFinder
+///----------------------------------------------------------------------------
+
+LLFloaterInventoryFinder::LLFloaterInventoryFinder(LLFloaterInventory* inventory_view)
+: LLFloater(LLSD()),
+ mFloaterInventory(inventory_view),
+ mFilter(inventory_view->mActivePanel->getFilter())
+{
+ LLUICtrlFactory::getInstance()->buildFloater(this, "floater_inventory_view_finder.xml", NULL);
+ updateElementsFromFilter();
+}
+
+
+void LLFloaterInventoryFinder::onCheckSinceLogoff(LLUICtrl *ctrl, void *user_data)
+{
+ LLFloaterInventoryFinder *self = (LLFloaterInventoryFinder *)user_data;
+ if (!self) return;
+
+ bool since_logoff= self->childGetValue("check_since_logoff");
+
+ if (!since_logoff &&
+ !( self->mSpinSinceDays->get() || self->mSpinSinceHours->get() ) )
+ {
+ self->mSpinSinceHours->set(1.0f);
+ }
+}
+BOOL LLFloaterInventoryFinder::postBuild()
+{
+ const LLRect& viewrect = mFloaterInventory->getRect();
+ setRect(LLRect(viewrect.mLeft - getRect().getWidth(), viewrect.mTop, viewrect.mLeft, viewrect.mTop - getRect().getHeight()));
+
+ childSetAction("All", selectAllTypes, this);
+ childSetAction("None", selectNoTypes, this);
+
+ mSpinSinceHours = getChild<LLSpinCtrl>("spin_hours_ago");
+ childSetCommitCallback("spin_hours_ago", onTimeAgo, this);
+
+ mSpinSinceDays = getChild<LLSpinCtrl>("spin_days_ago");
+ childSetCommitCallback("spin_days_ago", onTimeAgo, this);
+
+ // mCheckSinceLogoff = getChild<LLSpinCtrl>("check_since_logoff");
+ childSetCommitCallback("check_since_logoff", onCheckSinceLogoff, this);
+
+ childSetAction("Close", onCloseBtn, this);
+
+ updateElementsFromFilter();
+ return TRUE;
+}
+void LLFloaterInventoryFinder::onTimeAgo(LLUICtrl *ctrl, void *user_data)
+{
+ LLFloaterInventoryFinder *self = (LLFloaterInventoryFinder *)user_data;
+ if (!self) return;
+
+ bool since_logoff=true;
+ if ( self->mSpinSinceDays->get() || self->mSpinSinceHours->get() )
+ {
+ since_logoff = false;
+ }
+ self->childSetValue("check_since_logoff", since_logoff);
+}
+
+void LLFloaterInventoryFinder::changeFilter(LLInventoryFilter* filter)
+{
+ mFilter = filter;
+ updateElementsFromFilter();
+}
+
+void LLFloaterInventoryFinder::updateElementsFromFilter()
+{
+ if (!mFilter)
+ return;
+
+ // Get data needed for filter display
+ U32 filter_types = mFilter->getFilterTypes();
+ std::string filter_string = mFilter->getFilterSubString();
+ LLInventoryFilter::EFolderShow show_folders = mFilter->getShowFolderState();
+ U32 hours = mFilter->getHoursAgo();
+
+ // update the ui elements
+ LLFloater::setTitle(mFilter->getName());
+ childSetValue("check_animation", (S32) (filter_types & 0x1 << LLInventoryType::IT_ANIMATION));
+
+ childSetValue("check_calling_card", (S32) (filter_types & 0x1 << LLInventoryType::IT_CALLINGCARD));
+ childSetValue("check_clothing", (S32) (filter_types & 0x1 << LLInventoryType::IT_WEARABLE));
+ childSetValue("check_gesture", (S32) (filter_types & 0x1 << LLInventoryType::IT_GESTURE));
+ childSetValue("check_landmark", (S32) (filter_types & 0x1 << LLInventoryType::IT_LANDMARK));
+ childSetValue("check_notecard", (S32) (filter_types & 0x1 << LLInventoryType::IT_NOTECARD));
+ childSetValue("check_object", (S32) (filter_types & 0x1 << LLInventoryType::IT_OBJECT));
+ childSetValue("check_script", (S32) (filter_types & 0x1 << LLInventoryType::IT_LSL));
+ childSetValue("check_sound", (S32) (filter_types & 0x1 << LLInventoryType::IT_SOUND));
+ childSetValue("check_texture", (S32) (filter_types & 0x1 << LLInventoryType::IT_TEXTURE));
+ childSetValue("check_snapshot", (S32) (filter_types & 0x1 << LLInventoryType::IT_SNAPSHOT));
+ childSetValue("check_show_empty", show_folders == LLInventoryFilter::SHOW_ALL_FOLDERS);
+ childSetValue("check_since_logoff", mFilter->isSinceLogoff());
+ mSpinSinceHours->set((F32)(hours % 24));
+ mSpinSinceDays->set((F32)(hours / 24));
+}
+
+void LLFloaterInventoryFinder::draw()
+{
+ LLMemType mt(LLMemType::MTYPE_INVENTORY_DRAW);
+ U32 filter = 0xffffffff;
+ BOOL filtered_by_all_types = TRUE;
+
+ if (!childGetValue("check_animation"))
+ {
+ filter &= ~(0x1 << LLInventoryType::IT_ANIMATION);
+ filtered_by_all_types = FALSE;
+ }
+
+
+ if (!childGetValue("check_calling_card"))
+ {
+ filter &= ~(0x1 << LLInventoryType::IT_CALLINGCARD);
+ filtered_by_all_types = FALSE;
+ }
+
+ if (!childGetValue("check_clothing"))
+ {
+ filter &= ~(0x1 << LLInventoryType::IT_WEARABLE);
+ filtered_by_all_types = FALSE;
+ }
+
+ if (!childGetValue("check_gesture"))
+ {
+ filter &= ~(0x1 << LLInventoryType::IT_GESTURE);
+ filtered_by_all_types = FALSE;
+ }
+
+ if (!childGetValue("check_landmark"))
+
+
+ {
+ filter &= ~(0x1 << LLInventoryType::IT_LANDMARK);
+ filtered_by_all_types = FALSE;
+ }
+
+ if (!childGetValue("check_notecard"))
+ {
+ filter &= ~(0x1 << LLInventoryType::IT_NOTECARD);
+ filtered_by_all_types = FALSE;
+ }
+
+ if (!childGetValue("check_object"))
+ {
+ filter &= ~(0x1 << LLInventoryType::IT_OBJECT);
+ filter &= ~(0x1 << LLInventoryType::IT_ATTACHMENT);
+ filtered_by_all_types = FALSE;
+ }
+
+ if (!childGetValue("check_script"))
+ {
+ filter &= ~(0x1 << LLInventoryType::IT_LSL);
+ filtered_by_all_types = FALSE;
+ }
+
+ if (!childGetValue("check_sound"))
+ {
+ filter &= ~(0x1 << LLInventoryType::IT_SOUND);
+ filtered_by_all_types = FALSE;
+ }
+
+ if (!childGetValue("check_texture"))
+ {
+ filter &= ~(0x1 << LLInventoryType::IT_TEXTURE);
+ filtered_by_all_types = FALSE;
+ }
+
+ if (!childGetValue("check_snapshot"))
+ {
+ filter &= ~(0x1 << LLInventoryType::IT_SNAPSHOT);
+ filtered_by_all_types = FALSE;
+ }
+
+ if (!filtered_by_all_types)
+ {
+ // don't include folders in filter, unless I've selected everything
+ filter &= ~(0x1 << LLInventoryType::IT_CATEGORY);
+ }
+
+ // update the panel, panel will update the filter
+ mFloaterInventory->mActivePanel->setShowFolderState(getCheckShowEmpty() ?
+ LLInventoryFilter::SHOW_ALL_FOLDERS : LLInventoryFilter::SHOW_NON_EMPTY_FOLDERS);
+ mFloaterInventory->mActivePanel->setFilterTypes(filter);
+ if (getCheckSinceLogoff())
+ {
+ mSpinSinceDays->set(0);
+ mSpinSinceHours->set(0);
+ }
+ U32 days = (U32)mSpinSinceDays->get();
+ U32 hours = (U32)mSpinSinceHours->get();
+ if (hours > 24)
+ {
+ days += hours / 24;
+ hours = (U32)hours % 24;
+ mSpinSinceDays->set((F32)days);
+ mSpinSinceHours->set((F32)hours);
+ }
+ hours += days * 24;
+ mFloaterInventory->mActivePanel->setHoursAgo(hours);
+ mFloaterInventory->mActivePanel->setSinceLogoff(getCheckSinceLogoff());
+ mFloaterInventory->setFilterTextFromFilter();
+
+ LLFloater::draw();
+}
+
+BOOL LLFloaterInventoryFinder::getCheckShowEmpty()
+{
+ return childGetValue("check_show_empty");
+}
+
+BOOL LLFloaterInventoryFinder::getCheckSinceLogoff()
+{
+ return childGetValue("check_since_logoff");
+}
+
+void LLFloaterInventoryFinder::onCloseBtn(void* user_data)
+{
+ LLFloaterInventoryFinder* finderp = (LLFloaterInventoryFinder*)user_data;
+ finderp->closeFloater();
+}
+
+// static
+void LLFloaterInventoryFinder::selectAllTypes(void* user_data)
+{
+ LLFloaterInventoryFinder* self = (LLFloaterInventoryFinder*)user_data;
+ if(!self) return;
+
+ self->childSetValue("check_animation", TRUE);
+ self->childSetValue("check_calling_card", TRUE);
+ self->childSetValue("check_clothing", TRUE);
+ self->childSetValue("check_gesture", TRUE);
+ self->childSetValue("check_landmark", TRUE);
+ self->childSetValue("check_notecard", TRUE);
+ self->childSetValue("check_object", TRUE);
+ self->childSetValue("check_script", TRUE);
+ self->childSetValue("check_sound", TRUE);
+ self->childSetValue("check_texture", TRUE);
+ self->childSetValue("check_snapshot", TRUE);
+
+/*
+ self->mCheckCallingCard->set(TRUE);
+ self->mCheckClothing->set(TRUE);
+ self->mCheckGesture->set(TRUE);
+ self->mCheckLandmark->set(TRUE);
+ self->mCheckNotecard->set(TRUE);
+ self->mCheckObject->set(TRUE);
+ self->mCheckScript->set(TRUE);
+ self->mCheckSound->set(TRUE);
+ self->mCheckTexture->set(TRUE);
+ self->mCheckSnapshot->set(TRUE);*/
+}
+
+//static
+void LLFloaterInventoryFinder::selectNoTypes(void* user_data)
+{
+ LLFloaterInventoryFinder* self = (LLFloaterInventoryFinder*)user_data;
+ if(!self) return;
+
+ /*
+ self->childSetValue("check_animation", FALSE);
+ self->mCheckCallingCard->set(FALSE);
+ self->mCheckClothing->set(FALSE);
+ self->mCheckGesture->set(FALSE);
+ self->mCheckLandmark->set(FALSE);
+ self->mCheckNotecard->set(FALSE);
+ self->mCheckObject->set(FALSE);
+ self->mCheckScript->set(FALSE);
+ self->mCheckSound->set(FALSE);
+ self->mCheckTexture->set(FALSE);
+ self->mCheckSnapshot->set(FALSE);*/
+
+
+ self->childSetValue("check_animation", FALSE);
+ self->childSetValue("check_calling_card", FALSE);
+ self->childSetValue("check_clothing", FALSE);
+ self->childSetValue("check_gesture", FALSE);
+ self->childSetValue("check_landmark", FALSE);
+ self->childSetValue("check_notecard", FALSE);
+ self->childSetValue("check_object", FALSE);
+ self->childSetValue("check_script", FALSE);
+ self->childSetValue("check_sound", FALSE);
+ self->childSetValue("check_texture", FALSE);
+ self->childSetValue("check_snapshot", FALSE);
+}
+
+
+///----------------------------------------------------------------------------
+/// LLFloaterInventory
+///----------------------------------------------------------------------------
+void LLSaveFolderState::setApply(BOOL apply)
+{
+ mApply = apply;
+ // before generating new list of open folders, clear the old one
+ if(!apply)
+ {
+ clearOpenFolders();
+ }
+}
+
+void LLSaveFolderState::doFolder(LLFolderViewFolder* folder)
+{
+ LLMemType mt(LLMemType::MTYPE_INVENTORY_DO_FOLDER);
+ if(mApply)
+ {
+ // we're applying the open state
+ LLInvFVBridge* bridge = (LLInvFVBridge*)folder->getListener();
+ if(!bridge) return;
+ LLUUID id(bridge->getUUID());
+ if(mOpenFolders.find(id) != mOpenFolders.end())
+ {
+ folder->setOpen(TRUE);
+ }
+ else
+ {
+ // keep selected filter in its current state, this is less jarring to user
+ if (!folder->isSelected())
+ {
+ folder->setOpen(FALSE);
+ }
+ }
+ }
+ else
+ {
+ // we're recording state at this point
+ if(folder->isOpen())
+ {
+ LLInvFVBridge* bridge = (LLInvFVBridge*)folder->getListener();
+ if(!bridge) return;
+ mOpenFolders.insert(bridge->getUUID());
+ }
+ }
+}
+
+LLFloaterInventory::LLFloaterInventory(const LLSD& key)
+ : LLFloater(key)
+{
+ LLMemType mt(LLMemType::MTYPE_INVENTORY_VIEW_INIT);
+ // Menu Callbacks (non contex menus)
+ mCommitCallbackRegistrar.add("Inventory.DoToSelected", boost::bind(&LLFloaterInventory::doToSelected, this, _2));
+ mCommitCallbackRegistrar.add("Inventory.CloseAllFolders", boost::bind(&LLFloaterInventory::closeAllFolders, this));
+ mCommitCallbackRegistrar.add("Inventory.EmptyTrash", boost::bind(&LLInventoryModel::emptyFolderType, &gInventory, "ConfirmEmptyTrash", LLAssetType::AT_TRASH));
+ mCommitCallbackRegistrar.add("Inventory.EmptyLostAndFound", boost::bind(&LLInventoryModel::emptyFolderType, &gInventory, "ConfirmEmptyLostAndFound", LLAssetType::AT_LOST_AND_FOUND));
+ mCommitCallbackRegistrar.add("Inventory.DoCreate", boost::bind(&LLFloaterInventory::doCreate, this, _2));
+// mCommitCallbackRegistrar.add("Inventory.NewWindow", boost::bind(&LLFloaterInventory::newWindow, this));
+ mCommitCallbackRegistrar.add("Inventory.ShowFilters", boost::bind(&LLFloaterInventory::toggleFindOptions, this));
+ mCommitCallbackRegistrar.add("Inventory.ResetFilters", boost::bind(&LLFloaterInventory::resetFilters, this));
+ mCommitCallbackRegistrar.add("Inventory.SetSortBy", boost::bind(&LLFloaterInventory::setSortBy, this, _2));
+
+ // Controls
+ // *TODO: Just use persistant settings for each of these
+ U32 sort_order = gSavedSettings.getU32("InventorySortOrder");
+ BOOL sort_by_name = ! ( sort_order & LLInventoryFilter::SO_DATE );
+ BOOL sort_folders_by_name = ( sort_order & LLInventoryFilter::SO_FOLDERS_BY_NAME );
+ BOOL sort_system_folders_to_top = ( sort_order & LLInventoryFilter::SO_SYSTEM_FOLDERS_TO_TOP );
+
+ gSavedSettings.declareBOOL("Inventory.SortByName", sort_by_name, "Declared in code", FALSE);
+ gSavedSettings.declareBOOL("Inventory.SortByDate", !sort_by_name, "Declared in code", FALSE);
+ gSavedSettings.declareBOOL("Inventory.FoldersAlwaysByName", sort_folders_by_name, "Declared in code", FALSE);
+ gSavedSettings.declareBOOL("Inventory.SystemFoldersToTop", sort_system_folders_to_top, "Declared in code", FALSE);
+
+ mSavedFolderState = new LLSaveFolderState();
+ mSavedFolderState->setApply(FALSE);
+
+ //Called from floater reg: LLUICtrlFactory::getInstance()->buildFloater(this, "floater_inventory.xml");
+}
+
+BOOL LLFloaterInventory::postBuild()
+{
+ gInventory.addObserver(this);
+
+ mFilterTabs = getChild<LLTabContainer>("inventory filter tabs");
+ mFilterTabs->setCommitCallback(boost::bind(&LLFloaterInventory::onFilterSelected, this));
+
+ //panel->getFilter()->markDefault();
+
+ // Set up the default inv. panel/filter settings.
+ mActivePanel = getChild<LLInventoryPanel>("All Items");
+ if (mActivePanel)
+ {
+ // "All Items" is the previous only view, so it gets the InventorySortOrder
+ mActivePanel->setSortOrder(gSavedSettings.getU32("InventorySortOrder"));
+ mActivePanel->getFilter()->markDefault();
+ mActivePanel->getRootFolder()->applyFunctorRecursively(*mSavedFolderState);
+ mActivePanel->setSelectCallback(boost::bind(&LLInventoryPanel::onSelectionChange, mActivePanel, _1, _2));
+ }
+ LLInventoryPanel* recent_items_panel = getChild<LLInventoryPanel>("Recent Items");
+ if (recent_items_panel)
+ {
+ recent_items_panel->setSinceLogoff(TRUE);
+ recent_items_panel->setSortOrder(LLInventoryFilter::SO_DATE);
+ recent_items_panel->setShowFolderState(LLInventoryFilter::SHOW_NON_EMPTY_FOLDERS);
+ recent_items_panel->getFilter()->markDefault();
+ recent_items_panel->setSelectCallback(boost::bind(&LLInventoryPanel::onSelectionChange, recent_items_panel, _1, _2));
+ }
+
+ // Now load the stored settings from disk, if available.
+ std::ostringstream filterSaveName;
+ filterSaveName << gDirUtilp->getExpandedFilename(LL_PATH_PER_SL_ACCOUNT, "filters.xml");
+ llinfos << "LLFloaterInventory::init: reading from " << filterSaveName << llendl;
+ llifstream file(filterSaveName.str());
+ LLSD savedFilterState;
+ if (file.is_open())
+ {
+ LLSDSerialize::fromXML(savedFilterState, file);
+ file.close();
+
+ // Load the persistent "Recent Items" settings.
+ // Note that the "All Items" settings do not persist.
+ if(recent_items_panel)
+ {
+ if(savedFilterState.has(recent_items_panel->getFilter()->getName()))
+ {
+ LLSD recent_items = savedFilterState.get(
+ recent_items_panel->getFilter()->getName());
+ recent_items_panel->getFilter()->fromLLSD(recent_items);
+ }
+ }
+
+ }
+
+
+ mFilterEditor = getChild<LLFilterEditor>("inventory search editor");
+ if (mFilterEditor)
+ {
+ mFilterEditor->setCommitCallback(boost::bind(&LLFloaterInventory::onFilterEdit, this, _2));
+ }
+
+ // *TODO:Get the cost info from the server
+ const std::string upload_cost("10");
+ childSetLabelArg("Upload Image", "[COST]", upload_cost);
+ childSetLabelArg("Upload Sound", "[COST]", upload_cost);
+ childSetLabelArg("Upload Animation", "[COST]", upload_cost);
+ childSetLabelArg("Bulk Upload", "[COST]", upload_cost);
+
+ return TRUE;
+}
+
+// Destroys the object
+LLFloaterInventory::~LLFloaterInventory( void )
+{
+ // Save the filters state.
+ LLSD filterRoot;
+ LLInventoryPanel* all_items_panel = getChild<LLInventoryPanel>("All Items");
+ if (all_items_panel)
+ {
+ LLInventoryFilter* filter = all_items_panel->getFilter();
+ LLSD filterState;
+ filter->toLLSD(filterState);
+ filterRoot[filter->getName()] = filterState;
+ }
+
+ LLInventoryPanel* recent_items_panel = getChild<LLInventoryPanel>("Recent Items");
+ if (recent_items_panel)
+ {
+ LLInventoryFilter* filter = recent_items_panel->getFilter();
+ LLSD filterState;
+ filter->toLLSD(filterState);
+ filterRoot[filter->getName()] = filterState;
+ }
+
+ std::ostringstream filterSaveName;
+ filterSaveName << gDirUtilp->getExpandedFilename(LL_PATH_PER_SL_ACCOUNT, "filters.xml");
+ llofstream filtersFile(filterSaveName.str());
+ if(!LLSDSerialize::toPrettyXML(filterRoot, filtersFile))
+ {
+ llwarns << "Could not write to filters save file " << filterSaveName << llendl;
+ }
+ else
+ filtersFile.close();
+
+ gInventory.removeObserver(this);
+ delete mSavedFolderState;
+}
+
+void LLFloaterInventory::draw()
+{
+ if (LLInventoryModel::isEverythingFetched())
+ {
+ LLLocale locale(LLLocale::USER_LOCALE);
+ std::ostringstream title;
+ //title << "Inventory";
+ title<<getString("Title");
+ std::string item_count_string;
+ LLResMgr::getInstance()->getIntegerString(item_count_string, gInventory.getItemCount());
+ title << " (" << item_count_string << getString("Items")<<")";
+ //TODO:: Translate mFilterText
+ title << mFilterText;
+ setTitle(title.str());
+ }
+ LLFloater::draw();
+}
+
+void LLOpenFilteredFolders::doItem(LLFolderViewItem *item)
+{
+ if (item->getFiltered())
+ {
+ item->getParentFolder()->setOpenArrangeRecursively(TRUE, LLFolderViewFolder::RECURSE_UP);
+ }
+}
+
+void LLOpenFilteredFolders::doFolder(LLFolderViewFolder* folder)
+{
+ if (folder->getFiltered() && folder->getParentFolder())
+ {
+ folder->getParentFolder()->setOpenArrangeRecursively(TRUE, LLFolderViewFolder::RECURSE_UP);
+ }
+ // if this folder didn't pass the filter, and none of its descendants did
+ else if (!folder->getFiltered() && !folder->hasFilteredDescendants())
+ {
+ folder->setOpenArrangeRecursively(FALSE, LLFolderViewFolder::RECURSE_NO);
+ }
+}
+
+void LLSelectFirstFilteredItem::doItem(LLFolderViewItem *item)
+{
+ if (item->getFiltered() && !mItemSelected)
+ {
+ item->getRoot()->setSelection(item, FALSE, FALSE);
+ if (item->getParentFolder())
+ {
+ item->getParentFolder()->setOpenArrangeRecursively(TRUE, LLFolderViewFolder::RECURSE_UP);
+ }
+ item->getRoot()->scrollToShowSelection();
+ mItemSelected = TRUE;
+ }
+}
+
+void LLSelectFirstFilteredItem::doFolder(LLFolderViewFolder* folder)
+{
+ if (folder->getFiltered() && !mItemSelected)
+ {
+ folder->getRoot()->setSelection(folder, FALSE, FALSE);
+ if (folder->getParentFolder())
+ {
+ folder->getParentFolder()->setOpenArrangeRecursively(TRUE, LLFolderViewFolder::RECURSE_UP);
+ }
+ folder->getRoot()->scrollToShowSelection();
+ mItemSelected = TRUE;
+ }
+}
+
+void LLOpenFoldersWithSelection::doItem(LLFolderViewItem *item)
+{
+ if (item->getParentFolder() && item->isSelected())
+ {
+ item->getParentFolder()->setOpenArrangeRecursively(TRUE, LLFolderViewFolder::RECURSE_UP);
+ }
+}
+
+void LLOpenFoldersWithSelection::doFolder(LLFolderViewFolder* folder)
+{
+ if (folder->getParentFolder() && folder->isSelected())
+ {
+ folder->getParentFolder()->setOpenArrangeRecursively(TRUE, LLFolderViewFolder::RECURSE_UP);
+ }
+}
+
+void LLFloaterInventory::startSearch()
+{
+ // this forces focus to line editor portion of search editor
+ if (mFilterEditor)
+ {
+ mFilterEditor->focusFirstItem(TRUE);
+ }
+}
+
+void LLFloaterInventory::onOpen(const LLSD& key)
+{
+ LLFirstUse::useInventory();
+}
+
+BOOL LLFloaterInventory::handleKeyHere(KEY key, MASK mask)
+{
+ LLFolderView* root_folder = mActivePanel ? mActivePanel->getRootFolder() : NULL;
+ if (root_folder)
+ {
+ // first check for user accepting current search results
+ if (mFilterEditor
+ && mFilterEditor->hasFocus()
+ && (key == KEY_RETURN
+ || key == KEY_DOWN)
+ && mask == MASK_NONE)
+ {
+ // move focus to inventory proper
+ mActivePanel->setFocus(TRUE);
+ root_folder->scrollToShowSelection();
+ return TRUE;
+ }
+
+ if (mActivePanel->hasFocus() && key == KEY_UP)
+ {
+ startSearch();
+ }
+ }
+
+ return LLFloater::handleKeyHere(key, mask);
+
+}
+
+void LLFloaterInventory::changed(U32 mask)
+{
+ std::ostringstream title;
+ //title << "Inventory";
+ title<<getString("Title");
+ if (LLInventoryModel::backgroundFetchActive())
+ {
+ LLLocale locale(LLLocale::USER_LOCALE);
+ std::string item_count_string;
+ LLResMgr::getInstance()->getIntegerString(item_count_string, gInventory.getItemCount());
+ title << " ( "<< getString("Fetched") << item_count_string << getString("Items")<<")";
+ }
+ //TODO:: Translate mFilterText
+ title << mFilterText;
+ setTitle(title.str());
+
+}
+
+//----------------------------------------------------------------------------
+// menu callbacks
+
+void LLFloaterInventory::doToSelected(const LLSD& userdata)
+{
+ getPanel()->getRootFolder()->doToSelected(&gInventory, userdata);
+}
+
+void LLFloaterInventory::closeAllFolders()
+{
+ getPanel()->getRootFolder()->closeAllFolders();
+}
+
+void LLFloaterInventory::doCreate(const LLSD& userdata)
+{
+ menu_create_inventory_item(getPanel()->getRootFolder(), NULL, userdata);
+}
+
+void LLFloaterInventory::resetFilters()
+{
+ LLFloaterInventoryFinder *finder = getFinder();
+ getActivePanel()->getFilter()->resetDefault();
+ if (finder)
+ {
+ finder->updateElementsFromFilter();
+ }
+
+ setFilterTextFromFilter();
+}
+
+void LLFloaterInventory::setSortBy(const LLSD& userdata)
+{
+ std::string sort_field = userdata.asString();
+ if (sort_field == "name")
+ {
+ U32 order = getActivePanel()->getSortOrder();
+ getActivePanel()->setSortOrder( order & ~LLInventoryFilter::SO_DATE );
+
+ gSavedSettings.setBOOL("Inventory.SortByName", TRUE );
+ gSavedSettings.setBOOL("Inventory.SortByDate", FALSE );
+ }
+ else if (sort_field == "date")
+ {
+ U32 order = getActivePanel()->getSortOrder();
+ getActivePanel()->setSortOrder( order | LLInventoryFilter::SO_DATE );
+
+ gSavedSettings.setBOOL("Inventory.SortByName", FALSE );
+ gSavedSettings.setBOOL("Inventory.SortByDate", TRUE );
+ }
+ else if (sort_field == "foldersalwaysbyname")
+ {
+ U32 order = getActivePanel()->getSortOrder();
+ if ( order & LLInventoryFilter::SO_FOLDERS_BY_NAME )
+ {
+ order &= ~LLInventoryFilter::SO_FOLDERS_BY_NAME;
+
+ gSavedSettings.setBOOL("Inventory.FoldersAlwaysByName", FALSE );
+ }
+ else
+ {
+ order |= LLInventoryFilter::SO_FOLDERS_BY_NAME;
+
+ gSavedSettings.setBOOL("Inventory.FoldersAlwaysByName", TRUE );
+ }
+ getActivePanel()->setSortOrder( order );
+ }
+ else if (sort_field == "systemfolderstotop")
+ {
+ U32 order = getActivePanel()->getSortOrder();
+ if ( order & LLInventoryFilter::SO_SYSTEM_FOLDERS_TO_TOP )
+ {
+ order &= ~LLInventoryFilter::SO_SYSTEM_FOLDERS_TO_TOP;
+
+ gSavedSettings.setBOOL("Inventory.SystemFoldersToTop", FALSE );
+ }
+ else
+ {
+ order |= LLInventoryFilter::SO_SYSTEM_FOLDERS_TO_TOP;
+
+ gSavedSettings.setBOOL("Inventory.SystemFoldersToTop", TRUE );
+ }
+ getActivePanel()->setSortOrder( order );
+ }
+}
+
+//----------------------------------------------------------------------------
+
+// static
+LLFloaterInventory* LLFloaterInventory::showAgentInventory()
+{
+ LLFloaterInventory* iv = NULL;
+ if (!gAgent.cameraMouselook())
+ {
+ iv = LLFloaterReg::showTypedInstance<LLFloaterInventory>("inventory", LLSD());
+ }
+ return iv;
+}
+
+// static
+LLFloaterInventory* LLFloaterInventory::getActiveInventory()
+{
+ LLFloaterInventory* res = NULL;
+ LLFloaterReg::const_instance_list_t& inst_list = LLFloaterReg::getFloaterList("inventory");
+ S32 z_min = S32_MAX;
+ for (LLFloaterReg::const_instance_list_t::const_iterator iter = inst_list.begin(); iter != inst_list.end(); ++iter)
+ {
+ LLFloaterInventory* iv = dynamic_cast<LLFloaterInventory*>(*iter);
+ if (iv)
+ {
+ S32 z_order = gFloaterView->getZOrder(iv);
+ if (z_order < z_min)
+ {
+ res = iv;
+ z_min = z_order;
+ }
+ }
+ }
+ return res;
+}
+
+// static
+void LLFloaterInventory::cleanup()
+{
+ LLFloaterReg::const_instance_list_t& inst_list = LLFloaterReg::getFloaterList("inventory");
+ for (LLFloaterReg::const_instance_list_t::const_iterator iter = inst_list.begin(); iter != inst_list.end();)
+ {
+ LLFloaterInventory* iv = dynamic_cast<LLFloaterInventory*>(*iter++);
+ if (iv)
+ {
+ iv->destroy();
+ }
+ }
+}
+
+void LLFloaterInventory::toggleFindOptions()
+{
+ LLMemType mt(LLMemType::MTYPE_INVENTORY_VIEW_TOGGLE);
+ LLFloater *floater = getFinder();
+ if (!floater)
+ {
+ LLFloaterInventoryFinder * finder = new LLFloaterInventoryFinder(this);
+ mFinderHandle = finder->getHandle();
+ finder->openFloater();
+ addDependentFloater(mFinderHandle);
+
+ // start background fetch of folders
+ gInventory.startBackgroundFetch();
+ }
+ else
+ {
+ floater->closeFloater();
+ }
+}
+
+// static
+BOOL LLFloaterInventory::filtersVisible(void* user_data)
+{
+ LLFloaterInventory* self = (LLFloaterInventory*)user_data;
+ if(!self) return FALSE;
+
+ return self->getFinder() != NULL;
+}
+
+void LLFloaterInventory::onClearSearch()
+{
+ LLFloater *finder = getFinder();
+ if (mActivePanel)
+ {
+ mActivePanel->setFilterSubString(LLStringUtil::null);
+ mActivePanel->setFilterTypes(0xffffffff);
+ }
+
+ if (finder)
+ {
+ LLFloaterInventoryFinder::selectAllTypes(finder);
+ }
+
+ // re-open folders that were initially open
+ if (mActivePanel)
+ {
+ mSavedFolderState->setApply(TRUE);
+ mActivePanel->getRootFolder()->applyFunctorRecursively(*mSavedFolderState);
+ LLOpenFoldersWithSelection opener;
+ mActivePanel->getRootFolder()->applyFunctorRecursively(opener);
+ mActivePanel->getRootFolder()->scrollToShowSelection();
+ }
+}
+
+void LLFloaterInventory::onFilterEdit(const std::string& search_string )
+{
+ if (search_string == "")
+ {
+ onClearSearch();
+ }
+ if (!mActivePanel)
+ {
+ return;
+ }
+
+ gInventory.startBackgroundFetch();
+
+ std::string uppercase_search_string = search_string;
+ LLStringUtil::toUpper(uppercase_search_string);
+ if (mActivePanel->getFilterSubString().empty() && uppercase_search_string.empty())
+ {
+ // current filter and new filter empty, do nothing
+ return;
+ }
+
+ // save current folder open state if no filter currently applied
+ if (!mActivePanel->getRootFolder()->isFilterModified())
+ {
+ mSavedFolderState->setApply(FALSE);
+ mActivePanel->getRootFolder()->applyFunctorRecursively(*mSavedFolderState);
+ }
+
+ // set new filter string
+ mActivePanel->setFilterSubString(uppercase_search_string);
+}
+
+
+ //static
+ BOOL LLFloaterInventory::incrementalFind(LLFolderViewItem* first_item, const char *find_text, BOOL backward)
+ {
+ LLFloaterInventory* active_view = NULL;
+
+ LLFloaterReg::const_instance_list_t& inst_list = LLFloaterReg::getFloaterList("inventory");
+ for (LLFloaterReg::const_instance_list_t::const_iterator iter = inst_list.begin(); iter != inst_list.end(); ++iter)
+ {
+ LLFloaterInventory* iv = dynamic_cast<LLFloaterInventory*>(*iter);
+ if (iv)
+ {
+ if (gFocusMgr.childHasKeyboardFocus(iv))
+ {
+ active_view = iv;
+ break;
+ }
+ }
+ }
+
+ if (!active_view)
+ {
+ return FALSE;
+ }
+
+ std::string search_string(find_text);
+
+ if (search_string.empty())
+ {
+ return FALSE;
+ }
+
+ if (active_view->mActivePanel &&
+ active_view->mActivePanel->getRootFolder()->search(first_item, search_string, backward))
+ {
+ return TRUE;
+ }
+
+ return FALSE;
+ }
+
+void LLFloaterInventory::onFilterSelected()
+{
+ // Find my index
+ mActivePanel = (LLInventoryPanel*)childGetVisibleTab("inventory filter tabs");
+
+ if (!mActivePanel)
+ {
+ return;
+ }
+ LLInventoryFilter* filter = mActivePanel->getFilter();
+ LLFloaterInventoryFinder *finder = getFinder();
+ if (finder)
+ {
+ finder->changeFilter(filter);
+ }
+ if (filter->isActive())
+ {
+ // If our filter is active we may be the first thing requiring a fetch so we better start it here.
+ gInventory.startBackgroundFetch();
+ }
+ setFilterTextFromFilter();
+}
+
+BOOL LLFloaterInventory::handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop,
+ EDragAndDropType cargo_type,
+ void* cargo_data,
+ EAcceptance* accept,
+ std::string& tooltip_msg)
+{
+ // Check to see if we are auto scrolling from the last frame
+ LLInventoryPanel* panel = (LLInventoryPanel*)this->getActivePanel();
+ BOOL needsToScroll = panel->getScrollableContainer()->autoScroll(x, y);
+ if(mFilterTabs)
+ {
+ if(needsToScroll)
+ {
+ mFilterTabs->startDragAndDropDelayTimer();
+ }
+ }
+
+ BOOL handled = LLFloater::handleDragAndDrop(x, y, mask, drop, cargo_type, cargo_data, accept, tooltip_msg);
+
+ return handled;
+}
+const std::string& get_item_icon_name(LLAssetType::EType asset_type,
+ LLInventoryType::EType inventory_type,
+ U32 attachment_point,
+ BOOL item_is_multi )
+{
+ EInventoryIcon idx = OBJECT_ICON_NAME;
+ if ( item_is_multi )
+ {
+ idx = OBJECT_MULTI_ICON_NAME;
+ }
+
+ switch(asset_type)
+ {
+ case LLAssetType::AT_TEXTURE:
+ if(LLInventoryType::IT_SNAPSHOT == inventory_type)
+ {
+ idx = SNAPSHOT_ICON_NAME;
+ }
+ else
+ {
+ idx = TEXTURE_ICON_NAME;
+ }
+ break;
+
+ case LLAssetType::AT_SOUND:
+ idx = SOUND_ICON_NAME;
+ break;
+ case LLAssetType::AT_CALLINGCARD:
+ if(attachment_point!= 0)
+ {
+ idx = CALLINGCARD_ONLINE_ICON_NAME;
+ }
+ else
+ {
+ idx = CALLINGCARD_OFFLINE_ICON_NAME;
+ }
+ break;
+ case LLAssetType::AT_LANDMARK:
+ if(attachment_point!= 0)
+ {
+ idx = LANDMARK_VISITED_ICON_NAME;
+ }
+ else
+ {
+ idx = LANDMARK_ICON_NAME;
+ }
+ break;
+ case LLAssetType::AT_SCRIPT:
+ case LLAssetType::AT_LSL_TEXT:
+ case LLAssetType::AT_LSL_BYTECODE:
+ idx = SCRIPT_ICON_NAME;
+ break;
+ case LLAssetType::AT_CLOTHING:
+ idx = CLOTHING_ICON_NAME;
+ case LLAssetType::AT_BODYPART :
+ if(LLAssetType::AT_BODYPART == asset_type)
+ {
+ idx = BODYPART_ICON_NAME;
+ }
+ switch(LLInventoryItem::II_FLAGS_WEARABLES_MASK & attachment_point)
+ {
+ case WT_SHAPE:
+ idx = BODYPART_SHAPE_ICON_NAME;
+ break;
+ case WT_SKIN:
+ idx = BODYPART_SKIN_ICON_NAME;
+ break;
+ case WT_HAIR:
+ idx = BODYPART_HAIR_ICON_NAME;
+ break;
+ case WT_EYES:
+ idx = BODYPART_EYES_ICON_NAME;
+ break;
+ case WT_SHIRT:
+ idx = CLOTHING_SHIRT_ICON_NAME;
+ break;
+ case WT_PANTS:
+ idx = CLOTHING_PANTS_ICON_NAME;
+ break;
+ case WT_SHOES:
+ idx = CLOTHING_SHOES_ICON_NAME;
+ break;
+ case WT_SOCKS:
+ idx = CLOTHING_SOCKS_ICON_NAME;
+ break;
+ case WT_JACKET:
+ idx = CLOTHING_JACKET_ICON_NAME;
+ break;
+ case WT_GLOVES:
+ idx = CLOTHING_GLOVES_ICON_NAME;
+ break;
+ case WT_UNDERSHIRT:
+ idx = CLOTHING_UNDERSHIRT_ICON_NAME;
+ break;
+ case WT_UNDERPANTS:
+ idx = CLOTHING_UNDERPANTS_ICON_NAME;
+ break;
+ case WT_SKIRT:
+ idx = CLOTHING_SKIRT_ICON_NAME;
+ break;
+ case WT_ALPHA:
+ idx = CLOTHING_ALPHA_ICON_NAME;
+ break;
+ case WT_TATTOO:
+ idx = CLOTHING_TATTOO_ICON_NAME;
+ break;
+ default:
+ // no-op, go with choice above
+ break;
+ }
+ break;
+ case LLAssetType::AT_NOTECARD:
+ idx = NOTECARD_ICON_NAME;
+ break;
+ case LLAssetType::AT_ANIMATION:
+ idx = ANIMATION_ICON_NAME;
+ break;
+ case LLAssetType::AT_GESTURE:
+ idx = GESTURE_ICON_NAME;
+ break;
+ case LLAssetType::AT_FAVORITE:
+ //TODO - need bette idx
+ idx = LANDMARK_ICON_NAME;
+ break;
+ case LLAssetType::AT_LINK:
+ idx = LINKITEM_ICON_NAME;
+ break;
+ case LLAssetType::AT_LINK_FOLDER:
+ idx = LINKFOLDER_ICON_NAME;
+ break;
+ default:
+ break;
+ }
+
+ return ICON_NAME[idx];
+}
+
+LLUIImagePtr get_item_icon(LLAssetType::EType asset_type,
+ LLInventoryType::EType inventory_type,
+ U32 attachment_point,
+ BOOL item_is_multi)
+{
+ const std::string& icon_name = get_item_icon_name(asset_type, inventory_type, attachment_point, item_is_multi );
+ return LLUI::getUIImage(icon_name);
+}
+
+const std::string LLInventoryPanel::DEFAULT_SORT_ORDER = std::string("InventorySortOrder");
+const std::string LLInventoryPanel::RECENTITEMS_SORT_ORDER = std::string("RecentItemsSortOrder");
+const std::string LLInventoryPanel::INHERIT_SORT_ORDER = std::string("");
+
+LLInventoryPanel::LLInventoryPanel(const LLInventoryPanel::Params& p)
+: LLPanel(p),
+ mInventoryObserver(NULL),
+ mFolders(NULL),
+ mScroller(NULL),
+ mSortOrderSetting(p.sort_order_setting),
+ mInventory(p.inventory),
+ mAllowMultiSelect(p.allow_multi_select)
+{
+ // contex menu callbacks
+ mCommitCallbackRegistrar.add("Inventory.DoToSelected", boost::bind(&LLInventoryPanel::doToSelected, this, _2));
+ mCommitCallbackRegistrar.add("Inventory.EmptyTrash", boost::bind(&LLInventoryModel::emptyFolderType, &gInventory, "ConfirmEmptyTrash", LLAssetType::AT_TRASH));
+ mCommitCallbackRegistrar.add("Inventory.EmptyLostAndFound", boost::bind(&LLInventoryModel::emptyFolderType, &gInventory, "ConfirmEmptyLostAndFound", LLAssetType::AT_LOST_AND_FOUND));
+ mCommitCallbackRegistrar.add("Inventory.DoCreate", boost::bind(&LLInventoryPanel::doCreate, this, _2));
+ mCommitCallbackRegistrar.add("Inventory.AttachObject", boost::bind(&LLInventoryPanel::attachObject, this, _2));
+ mCommitCallbackRegistrar.add("Inventory.BeginIMSession", boost::bind(&LLInventoryPanel::beginIMSession, this));
+
+ setBackgroundColor(LLUIColorTable::instance().getColor("InventoryBackgroundColor"));
+ setBackgroundVisible(TRUE);
+ setBackgroundOpaque(TRUE);
+}
+
+BOOL LLInventoryPanel::postBuild()
+{
+ LLMemType mt(LLMemType::MTYPE_INVENTORY_POST_BUILD);
+
+ mCommitCallbackRegistrar.pushScope(); // registered as a widget; need to push callback scope ourselves
+
+ // create root folder
+ {
+ LLRect folder_rect(0,
+ 0,
+ getRect().getWidth(),
+ 0);
+ LLFolderView::Params p;
+ p.name = getName();
+ p.rect = folder_rect;
+ p.parent_panel = this;
+ mFolders = LLUICtrlFactory::create<LLFolderView>(p);
+ mFolders->setAllowMultiSelect(mAllowMultiSelect);
+ }
+
+ mCommitCallbackRegistrar.popScope();
+
+ mFolders->setCallbackRegistrar(&mCommitCallbackRegistrar);
+
+ // scroller
+ {
+ LLRect scroller_view_rect = getRect();
+ scroller_view_rect.translate(-scroller_view_rect.mLeft, -scroller_view_rect.mBottom);
+ LLScrollContainer::Params p;
+ p.name("Inventory Scroller");
+ p.rect(scroller_view_rect);
+ p.follows.flags(FOLLOWS_ALL);
+ p.reserve_scroll_corner(true);
+ p.tab_stop(true);
+ mScroller = LLUICtrlFactory::create<LLScrollContainer>(p);
+ }
+ addChild(mScroller);
+ mScroller->addChild(mFolders);
+
+ mFolders->setScrollContainer(mScroller);
+
+ // set up the callbacks from the inventory we're viewing, and then
+ // build everything.
+ mInventoryObserver = new LLInventoryPanelObserver(this);
+ mInventory->addObserver(mInventoryObserver);
+ rebuildViewsFor(LLUUID::null, LLInventoryObserver::ADD);
+
+ // bit of a hack to make sure the inventory is open.
+ mFolders->openFolder(std::string("My Inventory"));
+
+ if (mSortOrderSetting != INHERIT_SORT_ORDER)
+ {
+ setSortOrder(gSavedSettings.getU32(mSortOrderSetting));
+ }
+ else
+ {
+ setSortOrder(gSavedSettings.getU32(DEFAULT_SORT_ORDER));
+ }
+ mFolders->setSortOrder(mFolders->getFilter()->getSortOrder());
+
+ return TRUE;
+}
+
+LLInventoryPanel::~LLInventoryPanel()
+{
+ // should this be a global setting?
+ if (mFolders)
+ {
+ U32 sort_order = mFolders->getSortOrder();
+ if (mSortOrderSetting != INHERIT_SORT_ORDER)
+ {
+ gSavedSettings.setU32(mSortOrderSetting, sort_order);
+ }
+ }
+
+ // LLView destructor will take care of the sub-views.
+ mInventory->removeObserver(mInventoryObserver);
+ delete mInventoryObserver;
+ mScroller = NULL;
+}
+
+ LLMemType mt(LLMemType::MTYPE_INVENTORY_FROM_XML);
+void LLInventoryPanel::draw()
+{
+ // select the desired item (in case it wasn't loaded when the selection was requested)
+ mFolders->updateSelection();
+ LLPanel::draw();
+}
+
+void LLInventoryPanel::setFilterTypes(U64 filter_types, BOOL filter_for_categories)
+{
+ mFolders->getFilter()->setFilterTypes(filter_types, filter_for_categories);
+}
+
+void LLInventoryPanel::setFilterPermMask(PermissionMask filter_perm_mask)
+{
+ mFolders->getFilter()->setFilterPermissions(filter_perm_mask);
+}
+
+void LLInventoryPanel::setFilterSubString(const std::string& string)
+{
+ mFolders->getFilter()->setFilterSubString(string);
+}
+
+void LLInventoryPanel::setSortOrder(U32 order)
+{
+ mFolders->getFilter()->setSortOrder(order);
+ if (mFolders->getFilter()->isModified())
+ {
+ mFolders->setSortOrder(order);
+ // try to keep selection onscreen, even if it wasn't to start with
+ mFolders->scrollToShowSelection();
+ }
+}
+
+void LLInventoryPanel::setSinceLogoff(BOOL sl)
+{
+ mFolders->getFilter()->setDateRangeLastLogoff(sl);
+}
+
+void LLInventoryPanel::setHoursAgo(U32 hours)
+{
+ mFolders->getFilter()->setHoursAgo(hours);
+}
+
+void LLInventoryPanel::setShowFolderState(LLInventoryFilter::EFolderShow show)
+{
+ mFolders->getFilter()->setShowFolderState(show);
+}
+
+LLInventoryFilter::EFolderShow LLInventoryPanel::getShowFolderState()
+{
+ return mFolders->getFilter()->getShowFolderState();
+}
+
+static LLFastTimer::DeclareTimer FTM_REFRESH("Inventory Refresh");
+
+void LLInventoryPanel::modelChanged(U32 mask)
+{
+ LLFastTimer t2(FTM_REFRESH);
+
+ bool handled = false;
+ if(mask & LLInventoryObserver::LABEL)
+ {
+ handled = true;
+ // label change - empty out the display name for each object
+ // in this change set.
+ const std::set<LLUUID>& changed_items = gInventory.getChangedIDs();
+ std::set<LLUUID>::const_iterator id_it = changed_items.begin();
+ std::set<LLUUID>::const_iterator id_end = changed_items.end();
+ LLFolderViewItem* view = NULL;
+ LLInvFVBridge* bridge = NULL;
+ for (;id_it != id_end; ++id_it)
+ {
+ view = mFolders->getItemByID(*id_it);
+ if(view)
+ {
+ // request refresh on this item (also flags for filtering)
+ bridge = (LLInvFVBridge*)view->getListener();
+ if(bridge)
+ { // Clear the display name first, so it gets properly re-built during refresh()
+ bridge->clearDisplayName();
+ }
+ view->refresh();
+ }
+ }
+ }
+ if((mask & (LLInventoryObserver::STRUCTURE
+ | LLInventoryObserver::ADD
+ | LLInventoryObserver::REMOVE)) != 0)
+ {
+ handled = true;
+ // Record which folders are open by uuid.
+ LLInventoryModel* model = getModel();
+ if (model)
+ {
+ const std::set<LLUUID>& changed_items = gInventory.getChangedIDs();
+
+ std::set<LLUUID>::const_iterator id_it = changed_items.begin();
+ std::set<LLUUID>::const_iterator id_end = changed_items.end();
+ for (;id_it != id_end; ++id_it)
+ {
+ // sync view with model
+ LLInventoryObject* model_item = model->getObject(*id_it);
+ LLFolderViewItem* view_item = mFolders->getItemByID(*id_it);
+
+ if (model_item)
+ {
+ if (!view_item)
+ {
+ // this object was just created, need to build a view for it
+ if ((mask & LLInventoryObserver::ADD) != LLInventoryObserver::ADD)
+ {
+ llwarns << *id_it << " is in model but not in view, but ADD flag not set" << llendl;
+ }
+ buildNewViews(*id_it);
+
+ // select any newly created object
+ // that has the auto rename at top of folder
+ // root set
+ if(mFolders->getRoot()->needsAutoRename())
+ {
+ setSelection(*id_it, FALSE);
+ }
+ }
+ else
+ {
+ // this object was probably moved, check its parent
+ if ((mask & LLInventoryObserver::STRUCTURE) != LLInventoryObserver::STRUCTURE)
+ {
+ llwarns << *id_it << " is in model and in view, but STRUCTURE flag not set" << llendl;
+ }
+
+ LLFolderViewFolder* new_parent = (LLFolderViewFolder*)mFolders->getItemByID(model_item->getParentUUID());
+ if (view_item->getParentFolder() != new_parent)
+ {
+ view_item->getParentFolder()->extractItem(view_item);
+ view_item->addToFolder(new_parent, mFolders);
+ }
+ }
+ }
+ else
+ {
+ if (view_item)
+ {
+ if ((mask & LLInventoryObserver::REMOVE) != LLInventoryObserver::REMOVE)
+ {
+ llwarns << *id_it << " is not in model but in view, but REMOVE flag not set" << llendl;
+ }
+ // item in view but not model, need to delete view
+ view_item->destroyView();
+ }
+ else
+ {
+ llwarns << *id_it << "Item does not exist in either view or model, but notification triggered" << llendl;
+ }
+ }
+ }
+ }
+ }
+
+ if (!handled)
+ {
+ // it's a small change that only requires a refresh.
+ // *TODO: figure out a more efficient way to do the refresh
+ // since it is expensive on large inventories
+ mFolders->refresh();
+ }
+}
+
+void LLInventoryPanel::rebuildViewsFor(const LLUUID& id, U32 mask)
+{
+ LLFolderViewItem* old_view = NULL;
+
+ // get old LLFolderViewItem
+ old_view = mFolders->getItemByID(id);
+ if (old_view && id.notNull())
+ {
+ old_view->destroyView();
+ }
+
+ buildNewViews(id);
+}
+
+void LLInventoryPanel::buildNewViews(const LLUUID& id)
+{
+ LLMemType mt(LLMemType::MTYPE_INVENTORY_BUILD_NEW_VIEWS);
+ LLFolderViewItem* itemp = NULL;
+ LLInventoryObject* objectp = gInventory.getObject(id);
+
+ if (objectp)
+ {
+ if (objectp->getType() <= LLAssetType::AT_NONE ||
+ objectp->getType() >= LLAssetType::AT_COUNT)
+ {
+ llwarns << "LLInventoryPanel::buildNewViews called with objectp->mType == "
+ << ((S32) objectp->getType())
+ << " (shouldn't happen)" << llendl;
+ }
+ else if (objectp->getType() == LLAssetType::AT_CATEGORY &&
+ objectp->getActualType() != LLAssetType::AT_LINK_FOLDER)
+ {
+ LLInvFVBridge* new_listener = LLInvFVBridge::createBridge(objectp->getType(),
+ objectp->getType(),
+ LLInventoryType::IT_CATEGORY,
+ this,
+ objectp->getUUID());
+
+ if (new_listener)
+ {
+ LLFolderViewFolder::Params p;
+ p.name = new_listener->getDisplayName();
+ p.icon = new_listener->getIcon();
+ p.root = mFolders;
+ p.listener = new_listener;
+ LLFolderViewFolder* folderp = LLUICtrlFactory::create<LLFolderViewFolder>(p);
+
+ folderp->setItemSortOrder(mFolders->getSortOrder());
+ itemp = folderp;
+ }
+ }
+ else
+ {
+ // Build new view for item
+ LLInventoryItem* item = (LLInventoryItem*)objectp;
+ LLInvFVBridge* new_listener = LLInvFVBridge::createBridge(item->getType(),
+ item->getActualType(),
+ item->getInventoryType(),
+ this,
+ item->getUUID(),
+ item->getFlags());
+
+ if (new_listener)
+ {
+ LLFolderViewItem::Params params;
+ params.name(new_listener->getDisplayName());
+ params.icon(new_listener->getIcon());
+ params.creation_date(new_listener->getCreationDate());
+ params.root(mFolders);
+ params.listener(new_listener);
+ params.rect(LLRect (0, 0, 0, 0));
+ itemp = LLUICtrlFactory::create<LLFolderViewItem> (params);
+ }
+ }
+
+ LLFolderViewFolder* parent_folder = (LLFolderViewFolder*)mFolders->getItemByID(objectp->getParentUUID());
+
+ if (itemp)
+ {
+ if (parent_folder)
+ {
+ itemp->addToFolder(parent_folder, mFolders);
+ }
+ else
+ {
+ llwarns << "Couldn't find parent folder for child " << itemp->getLabel() << llendl;
+ delete itemp;
+ }
+ }
+ }
+ if ((id.isNull() ||
+ (objectp && objectp->getType() == LLAssetType::AT_CATEGORY)))
+ {
+ LLViewerInventoryCategory::cat_array_t* categories;
+ LLViewerInventoryItem::item_array_t* items;
+
+ mInventory->lockDirectDescendentArrays(id, categories, items);
+ if(categories)
+ {
+ S32 count = categories->count();
+ for(S32 i = 0; i < count; ++i)
+ {
+ LLInventoryCategory* cat = categories->get(i);
+ buildNewViews(cat->getUUID());
+ }
+ }
+ if(items)
+ {
+ S32 count = items->count();
+ for(S32 i = 0; i < count; ++i)
+ {
+ LLInventoryItem* item = items->get(i);
+ buildNewViews(item->getUUID());
+ }
+ }
+ mInventory->unlockDirectDescendentArrays(id);
+ }
+}
+
+struct LLConfirmPurgeData
+{
+ LLUUID mID;
+ LLInventoryModel* mModel;
+};
+
+class LLIsNotWorn : public LLInventoryCollectFunctor
+{
+public:
+ LLIsNotWorn() {}
+ virtual ~LLIsNotWorn() {}
+ virtual bool operator()(LLInventoryCategory* cat,
+ LLInventoryItem* item)
+ {
+ return !gAgentWearables.isWearingItem(item->getUUID());
+ }
+};
+
+class LLOpenFolderByID : public LLFolderViewFunctor
+{
+public:
+ LLOpenFolderByID(const LLUUID& id) : mID(id) {}
+ virtual ~LLOpenFolderByID() {}
+ virtual void doFolder(LLFolderViewFolder* folder)
+ {
+ if (folder->getListener() && folder->getListener()->getUUID() == mID) folder->setOpenArrangeRecursively(TRUE, LLFolderViewFolder::RECURSE_UP);
+ }
+ virtual void doItem(LLFolderViewItem* item) {}
+protected:
+ const LLUUID& mID;
+};
+
+
+void LLInventoryPanel::openSelected()
+{
+ LLFolderViewItem* folder_item = mFolders->getCurSelectedItem();
+ if(!folder_item) return;
+ LLInvFVBridge* bridge = (LLInvFVBridge*)folder_item->getListener();
+ if(!bridge) return;
+ bridge->openItem();
+}
+
+BOOL LLInventoryPanel::handleHover(S32 x, S32 y, MASK mask)
+{
+ BOOL handled = LLView::handleHover(x, y, mask);
+ if(handled)
+ {
+ ECursorType cursor = getWindow()->getCursor();
+ if (LLInventoryModel::backgroundFetchActive() && cursor == UI_CURSOR_ARROW)
+ {
+ // replace arrow cursor with arrow and hourglass cursor
+ getWindow()->setCursor(UI_CURSOR_WORKING);
+ }
+ }
+ else
+ {
+ getWindow()->setCursor(UI_CURSOR_ARROW);
+ }
+ return TRUE;
+}
+
+BOOL LLInventoryPanel::handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop,
+ EDragAndDropType cargo_type,
+ void* cargo_data,
+ EAcceptance* accept,
+ std::string& tooltip_msg)
+{
+
+ BOOL handled = LLPanel::handleDragAndDrop(x, y, mask, drop, cargo_type, cargo_data, accept, tooltip_msg);
+
+ if (handled)
+ {
+ mFolders->setDragAndDropThisFrame();
+ }
+
+ return handled;
+}
+
+void LLInventoryPanel::onFocusLost()
+{
+ // inventory no longer handles cut/copy/paste/delete
+ if (LLEditMenuHandler::gEditMenuHandler == mFolders)
+ {
+ LLEditMenuHandler::gEditMenuHandler = NULL;
+ }
+
+ LLPanel::onFocusLost();
+}
+
+void LLInventoryPanel::onFocusReceived()
+{
+ // inventory now handles cut/copy/paste/delete
+ LLEditMenuHandler::gEditMenuHandler = mFolders;
+
+ LLPanel::onFocusReceived();
+}
+
+
+void LLInventoryPanel::openAllFolders()
+{
+ mFolders->setOpenArrangeRecursively(TRUE, LLFolderViewFolder::RECURSE_DOWN);
+ mFolders->arrangeAll();
+}
+
+void LLInventoryPanel::openDefaultFolderForType(LLAssetType::EType type)
+{
+ LLUUID category_id = mInventory->findCategoryUUIDForType(type);
+ LLOpenFolderByID opener(category_id);
+ mFolders->applyFunctorRecursively(opener);
+}
+
+void LLInventoryPanel::setSelection(const LLUUID& obj_id, BOOL take_keyboard_focus)
+{
+ mFolders->setSelectionByID(obj_id, take_keyboard_focus);
+}
+
+void LLInventoryPanel::clearSelection()
+{
+ mFolders->clearSelection();
+}
+
+void LLInventoryPanel::onSelectionChange(const std::deque<LLFolderViewItem*>& items, BOOL user_action)
+{
+ LLFolderView* fv = getRootFolder();
+ if (fv->needsAutoRename()) // auto-selecting a new user-created asset and preparing to rename
+ {
+ fv->setNeedsAutoRename(FALSE);
+ if (items.size()) // new asset is visible and selected
+ {
+ fv->startRenamingSelectedItem();
+ }
+ }
+ // Seraph - Put determineFolderType in here for ensemble typing?
+}
+
+//----------------------------------------------------------------------------
+
+void LLInventoryPanel::doToSelected(const LLSD& userdata)
+{
+ mFolders->doToSelected(&gInventory, userdata);
+}
+
+void LLInventoryPanel::doCreate(const LLSD& userdata)
+{
+ menu_create_inventory_item(mFolders, LLFolderBridge::sSelf, userdata);
+}
+
+bool LLInventoryPanel::beginIMSession()
+{
+ std::set<LLUUID> selected_items;
+ mFolders->getSelectionList(selected_items);
+
+ std::string name;
+ static int session_num = 1;
+
+ LLDynamicArray<LLUUID> members;
+ EInstantMessage type = IM_SESSION_CONFERENCE_START;
+
+ std::set<LLUUID>::const_iterator iter;
+ for (iter = selected_items.begin(); iter != selected_items.end(); iter++)
+ {
+
+ LLUUID item = *iter;
+ LLFolderViewItem* folder_item = mFolders->getItemByID(item);
+
+ if(folder_item)
+ {
+ LLFolderViewEventListener* fve_listener = folder_item->getListener();
+ if (fve_listener && (fve_listener->getInventoryType() == LLInventoryType::IT_CATEGORY))
+ {
+
+ LLFolderBridge* bridge = (LLFolderBridge*)folder_item->getListener();
+ if(!bridge) return true;
+ LLViewerInventoryCategory* cat = bridge->getCategory();
+ if(!cat) return true;
+ name = cat->getName();
+ LLUniqueBuddyCollector is_buddy;
+ LLInventoryModel::cat_array_t cat_array;
+ LLInventoryModel::item_array_t item_array;
+ gInventory.collectDescendentsIf(bridge->getUUID(),
+ cat_array,
+ item_array,
+ LLInventoryModel::EXCLUDE_TRASH,
+ is_buddy);
+ S32 count = item_array.count();
+ if(count > 0)
+ {
+ LLFloaterReg::showInstance("communicate");
+ // create the session
+ LLAvatarTracker& at = LLAvatarTracker::instance();
+ LLUUID id;
+ for(S32 i = 0; i < count; ++i)
+ {
+ id = item_array.get(i)->getCreatorUUID();
+ if(at.isBuddyOnline(id))
+ {
+ members.put(id);
+ }
+ }
+ }
+ }
+ else
+ {
+ LLFolderViewItem* folder_item = mFolders->getItemByID(item);
+ if(!folder_item) return true;
+ LLInvFVBridge* listenerp = (LLInvFVBridge*)folder_item->getListener();
+
+ if (listenerp->getInventoryType() == LLInventoryType::IT_CALLINGCARD)
+ {
+ LLInventoryItem* inv_item = gInventory.getItem(listenerp->getUUID());
+
+ if (inv_item)
+ {
+ LLAvatarTracker& at = LLAvatarTracker::instance();
+ LLUUID id = inv_item->getCreatorUUID();
+
+ if(at.isBuddyOnline(id))
+ {
+ members.put(id);
+ }
+ }
+ } //if IT_CALLINGCARD
+ } //if !IT_CATEGORY
+ }
+ } //for selected_items
+
+ // the session_id is randomly generated UUID which will be replaced later
+ // with a server side generated number
+
+ if (name.empty())
+ {
+ name = llformat("Session %d", session_num++);
+ }
+
+ gIMMgr->addSession(name, type, members[0], members);
+
+ return true;
+}
+
+bool LLInventoryPanel::attachObject(const LLSD& userdata)
+{
+ std::set<LLUUID> selected_items;
+ mFolders->getSelectionList(selected_items);
+ LLUUID id = *selected_items.begin();
+
+ std::string joint_name = userdata.asString();
+ LLVOAvatar *avatarp = static_cast<LLVOAvatar*>(gAgent.getAvatarObject());
+ LLViewerJointAttachment* attachmentp = NULL;
+ for (LLVOAvatar::attachment_map_t::iterator iter = avatarp->mAttachmentPoints.begin();
+ iter != avatarp->mAttachmentPoints.end(); )
+ {
+ LLVOAvatar::attachment_map_t::iterator curiter = iter++;
+ LLViewerJointAttachment* attachment = curiter->second;
+ if (attachment->getName() == joint_name)
+ {
+ attachmentp = attachment;
+ break;
+ }
+ }
+ if (attachmentp == NULL)
+ {
+ return true;
+ }
+ LLViewerInventoryItem* item = (LLViewerInventoryItem*)gInventory.getItem(id);
+
+ if(item && gInventory.isObjectDescendentOf(id, gInventory.getRootFolderID()))
+ {
+ rez_attachment(item, attachmentp);
+ }
+ else if(item && item->isComplete())
+ {
+ // must be in library. copy it to our inventory and put it on.
+ LLPointer<LLInventoryCallback> cb = new RezAttachmentCallback(attachmentp);
+ copy_inventory_item(gAgent.getID(),
+ item->getPermissions().getOwner(),
+ item->getUUID(),
+ LLUUID::null,
+ std::string(),
+ cb);
+ }
+ gFocusMgr.setKeyboardFocus(NULL);
+
+ return true;
+}
+
+
+//----------------------------------------------------------------------------
+
+// static DEBUG ONLY:
+void LLInventoryPanel::dumpSelectionInformation(void* user_data)
+{
+ LLInventoryPanel* iv = (LLInventoryPanel*)user_data;
+ iv->mFolders->dumpSelectionInformation();
+}
+
+BOOL LLInventoryPanel::getSinceLogoff()
+{
+ return mFolders->getFilter()->isSinceLogoff();
+}
+
+void example_param_block_usage()
+{
+ LLInventoryPanel::Params param_block;
+ param_block.name(std::string("inventory"));
+
+ param_block.sort_order_setting(LLInventoryPanel::RECENTITEMS_SORT_ORDER);
+ param_block.allow_multi_select(true);
+ param_block.filter(LLInventoryPanel::Filter()
+ .sort_order(1)
+ .types(0xffff0000));
+ param_block.inventory(&gInventory);
+ param_block.has_border(true);
+
+ LLUICtrlFactory::create<LLInventoryPanel>(param_block);
+
+ param_block = LLInventoryPanel::Params();
+ param_block.name(std::string("inventory"));
+
+ //LLSD param_block_sd;
+ //param_block_sd["sort_order_setting"] = LLInventoryPanel::RECENTITEMS_SORT_ORDER;
+ //param_block_sd["allow_multi_select"] = true;
+ //param_block_sd["filter"]["sort_order"] = 1;
+ //param_block_sd["filter"]["types"] = (S32)0xffff0000;
+ //param_block_sd["has_border"] = true;
+
+ //LLInitParam::LLSDParser(param_block_sd).parse(param_block);
+
+ LLUICtrlFactory::create<LLInventoryPanel>(param_block);
+}
diff --git a/indra/newview/llfloaterinventory.h b/indra/newview/llfloaterinventory.h
new file mode 100644
index 0000000000..fd61e121ea
--- /dev/null
+++ b/indra/newview/llfloaterinventory.h
@@ -0,0 +1,362 @@
+/**
+ * @file llfloaterinventory.h
+ * @brief LLFloaterInventory, LLInventoryFolder, and LLInventoryItem
+ * class definition
+ *
+ * $LicenseInfo:firstyear=2001&license=viewergpl$
+ *
+ * Copyright (c) 2001-2009, Linden Research, Inc.
+ *
+ * Second Life Viewer Source Code
+ * The source code in this file ("Source Code") is provided by Linden Lab
+ * to you under the terms of the GNU General Public License, version 2.0
+ * ("GPL"), unless you have obtained a separate licensing agreement
+ * ("Other License"), formally executed by you and Linden Lab. Terms of
+ * the GPL can be found in doc/GPL-license.txt in this distribution, or
+ * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
+ *
+ * There are special exceptions to the terms and conditions of the GPL as
+ * it is applied to this Source Code. View the full text of the exception
+ * in the file doc/FLOSS-exception.txt in this software distribution, or
+ * online at
+ * http://secondlifegrid.net/programs/open_source/licensing/flossexception
+ *
+ * By copying, modifying or distributing this software, you acknowledge
+ * that you have read and understood your obligations described above,
+ * and agree to abide by those obligations.
+ *
+ * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+ * COMPLETENESS OR PERFORMANCE.
+ * $/LicenseInfo$
+ */
+
+#ifndef LL_LLINVENTORYVIEW_H
+#define LL_LLINVENTORYVIEW_H
+
+#include "llassetstorage.h"
+#include "lldarray.h"
+#include "llfloater.h"
+#include "llinventory.h"
+#include "llinventoryfilter.h"
+#include "llfolderview.h"
+#include "llinventorymodel.h"
+#include "lluictrlfactory.h"
+#include <set>
+
+
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+// Class LLFloaterInventory
+//
+// This is the agent inventory _floater_.
+// It deals with the buttons and views used to navigate as
+// well as controls the behavior of the overall object.
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+class LLFolderViewItem;
+class LLInventoryFilter;
+class LLInventoryModel;
+class LLInvFVBridge;
+class LLMenuBarGL;
+class LLCheckBoxCtrl;
+class LLSpinCtrl;
+class LLScrollContainer;
+class LLTextBox;
+class LLIconCtrl;
+class LLSaveFolderState;
+class LLFilterEditor;
+class LLTabContainer;
+
+class LLInventoryPanel : public LLPanel
+{
+public:
+ static const std::string DEFAULT_SORT_ORDER;
+ static const std::string RECENTITEMS_SORT_ORDER;
+ static const std::string INHERIT_SORT_ORDER;
+
+ struct Filter : public LLInitParam::Block<Filter>
+ {
+ Optional<U32> sort_order;
+ Optional<U32> types;
+ Optional<std::string> search_string;
+
+ Filter()
+ : sort_order("sort_order"),
+ types("types", 0xffffffff),
+ search_string("search_string")
+ {}
+ };
+
+ struct Params
+ : public LLInitParam::Block<Params, LLPanel::Params>
+ {
+ Optional<std::string> sort_order_setting;
+ Optional<LLInventoryModel*> inventory;
+ Optional<bool> allow_multi_select;
+ Optional<Filter> filter;
+
+ Params()
+ : sort_order_setting("sort_order_setting"),
+ inventory("", &gInventory),
+ allow_multi_select("allow_multi_select", true),
+ filter("filter")
+ {}
+ };
+
+protected:
+ LLInventoryPanel(const Params&);
+ friend class LLUICtrlFactory;
+
+public:
+ ~LLInventoryPanel();
+
+ LLInventoryModel* getModel() { return mInventory; }
+
+ BOOL postBuild();
+
+ // LLView methods
+ void draw();
+ BOOL handleHover(S32 x, S32 y, MASK mask);
+ BOOL handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop,
+ EDragAndDropType cargo_type,
+ void* cargo_data,
+ EAcceptance* accept,
+ std::string& tooltip_msg);
+ // LLUICtrl methods
+ /*virtual*/ void onFocusLost();
+ /*virtual*/ void onFocusReceived();
+
+ // Call this method to set the selection.
+ void openAllFolders();
+ void openDefaultFolderForType(LLAssetType::EType);
+ void setSelection(const LLUUID& obj_id, BOOL take_keyboard_focus);
+ void setSelectCallback(const LLFolderView::signal_t::slot_type& cb) { if (mFolders) mFolders->setSelectCallback(cb); }
+ void clearSelection();
+ LLInventoryFilter* getFilter() { return mFolders->getFilter(); }
+ void setFilterTypes(U64 filter, BOOL filter_for_categories = FALSE); // if filter_for_categories is true, operate on folder preferred asset type
+ U32 getFilterTypes() const { return mFolders->getFilterTypes(); }
+ void setFilterPermMask(PermissionMask filter_perm_mask);
+ U32 getFilterPermMask() const { return mFolders->getFilterPermissions(); }
+ void setFilterSubString(const std::string& string);
+ const std::string getFilterSubString() { return mFolders->getFilterSubString(); }
+ void setSortOrder(U32 order);
+ U32 getSortOrder() { return mFolders->getSortOrder(); }
+ void setSinceLogoff(BOOL sl);
+ void setHoursAgo(U32 hours);
+ BOOL getSinceLogoff();
+
+ void setShowFolderState(LLInventoryFilter::EFolderShow show);
+ LLInventoryFilter::EFolderShow getShowFolderState();
+ void setAllowMultiSelect(BOOL allow) { mFolders->setAllowMultiSelect(allow); }
+ // This method is called when something has changed about the inventory.
+ void modelChanged(U32 mask);
+ LLFolderView* getRootFolder() { return mFolders; }
+ LLScrollContainer* getScrollableContainer() { return mScroller; }
+
+ void onSelectionChange(const std::deque<LLFolderViewItem*> &items, BOOL user_action);
+
+ // Callbacks
+ void doToSelected(const LLSD& userdata);
+ void doCreate(const LLSD& userdata);
+ bool beginIMSession();
+ bool attachObject(const LLSD& userdata);
+
+ // DEBUG ONLY:
+ static void dumpSelectionInformation(void* user_data);
+
+ void openSelected();
+ void unSelectAll() { mFolders->setSelection(NULL, FALSE, FALSE); }
+
+protected:
+ // Given the id and the parent, build all of the folder views.
+ void rebuildViewsFor(const LLUUID& id, U32 mask);
+ void buildNewViews(const LLUUID& id);
+
+protected:
+ LLInventoryModel* mInventory;
+ LLInventoryObserver* mInventoryObserver;
+ LLFolderView* mFolders;
+ LLScrollContainer* mScroller;
+ BOOL mAllowMultiSelect;
+ std::string mSortOrderSetting;
+};
+
+class LLFloaterInventory;
+
+class LLFloaterInventoryFinder : public LLFloater
+{
+public:
+ LLFloaterInventoryFinder( LLFloaterInventory* inventory_view);
+ virtual void draw();
+ /*virtual*/ BOOL postBuild();
+ void changeFilter(LLInventoryFilter* filter);
+ void updateElementsFromFilter();
+ BOOL getCheckShowEmpty();
+ BOOL getCheckSinceLogoff();
+
+ static void onTimeAgo(LLUICtrl*, void *);
+ static void onCheckSinceLogoff(LLUICtrl*, void *);
+ static void onCloseBtn(void* user_data);
+ static void selectAllTypes(void* user_data);
+ static void selectNoTypes(void* user_data);
+
+protected:
+ LLFloaterInventory* mFloaterInventory;
+ LLSpinCtrl* mSpinSinceDays;
+ LLSpinCtrl* mSpinSinceHours;
+ LLInventoryFilter* mFilter;
+};
+
+class LLFloaterInventory : public LLFloater, LLInventoryObserver
+{
+friend class LLFloaterInventoryFinder;
+
+public:
+ LLFloaterInventory(const LLSD& key);
+ ~LLFloaterInventory();
+
+ /*virtual*/ void changed(U32 mask);
+
+ BOOL postBuild();
+
+ //
+ // Misc functions
+ //
+ void setFilterTextFromFilter() { mFilterText = mActivePanel->getFilter()->getFilterText(); }
+ void startSearch();
+
+ // This method makes sure that an inventory view exists, is
+ // visible, and has focus. The view chosen is returned.
+ static LLFloaterInventory* showAgentInventory();
+
+ // Return the active inventory view if there is one. Active is
+ // defined as the inventory that is the closest to the front, and
+ // is visible.
+ static LLFloaterInventory* getActiveInventory();
+
+ // This method calls showAgentInventory() if no views are visible,
+ // or hides/destroyes them all if any are visible.
+ static void toggleVisibility();
+ static void toggleVisibility(void*) { toggleVisibility(); }
+
+ // Final cleanup, destroy all open inventory views.
+ static void cleanup();
+
+ // LLView & LLFloater functionality
+ virtual void onOpen(const LLSD& key);
+ virtual void draw();
+ virtual BOOL handleKeyHere(KEY key, MASK mask);
+
+ BOOL handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop,
+ EDragAndDropType cargo_type,
+ void* cargo_data,
+ EAcceptance* accept,
+ std::string& tooltip_msg);
+
+
+ LLInventoryPanel* getPanel() { return mActivePanel; }
+ LLInventoryPanel* getActivePanel() { return mActivePanel; }
+
+ static BOOL filtersVisible(void* user_data);
+ void onClearSearch();
+ static void onFoldersByName(void *user_data);
+ static BOOL checkFoldersByName(void *user_data);
+ void onFilterEdit(const std::string& search_string );
+ static BOOL incrementalFind(LLFolderViewItem* first_item, const char *find_text, BOOL backward);
+ void onFilterSelected();
+
+ const std::string getFilterSubString() { return mActivePanel->getFilterSubString(); }
+ void setFilterSubString(const std::string& string) { mActivePanel->setFilterSubString(string); }
+
+ // menu callbacks
+ void doToSelected(const LLSD& userdata);
+ void closeAllFolders();
+ void doCreate(const LLSD& userdata);
+ void resetFilters();
+ void setSortBy(const LLSD& userdata);
+
+ // HACK: Until we can route this info through the instant message hierarchy
+ static BOOL sWearNewClothing;
+ static LLUUID sWearNewClothingTransactionID; // wear all clothing in this transaction
+
+ void toggleFindOptions();
+
+ LLFloaterInventoryFinder* getFinder() { return (LLFloaterInventoryFinder*)mFinderHandle.get(); }
+
+protected:
+ LLFilterEditor* mFilterEditor;
+ LLTabContainer* mFilterTabs;
+ LLHandle<LLFloater> mFinderHandle;
+ LLInventoryPanel* mActivePanel;
+ LLSaveFolderState* mSavedFolderState;
+
+ std::string mFilterText;
+};
+
+class LLSelectFirstFilteredItem : public LLFolderViewFunctor
+{
+public:
+ LLSelectFirstFilteredItem() : mItemSelected(FALSE) {}
+ virtual ~LLSelectFirstFilteredItem() {}
+ virtual void doFolder(LLFolderViewFolder* folder);
+ virtual void doItem(LLFolderViewItem* item);
+ BOOL wasItemSelected() { return mItemSelected; }
+protected:
+ BOOL mItemSelected;
+};
+
+class LLOpenFilteredFolders : public LLFolderViewFunctor
+{
+public:
+ LLOpenFilteredFolders() {}
+ virtual ~LLOpenFilteredFolders() {}
+ virtual void doFolder(LLFolderViewFolder* folder);
+ virtual void doItem(LLFolderViewItem* item);
+};
+
+class LLSaveFolderState : public LLFolderViewFunctor
+{
+public:
+ LLSaveFolderState() : mApply(FALSE) {}
+ virtual ~LLSaveFolderState() {}
+ virtual void doFolder(LLFolderViewFolder* folder);
+ virtual void doItem(LLFolderViewItem* item) {}
+ void setApply(BOOL apply);
+ void clearOpenFolders() { mOpenFolders.clear(); }
+protected:
+ std::set<LLUUID> mOpenFolders;
+ BOOL mApply;
+};
+
+class LLOpenFoldersWithSelection : public LLFolderViewFunctor
+{
+public:
+ LLOpenFoldersWithSelection() {}
+ virtual ~LLOpenFoldersWithSelection() {}
+ virtual void doFolder(LLFolderViewFolder* folder);
+ virtual void doItem(LLFolderViewItem* item);
+};
+
+///----------------------------------------------------------------------------
+/// Function declarations, constants, enums, and typedefs
+///----------------------------------------------------------------------------
+
+// useful functions with the inventory view
+
+class LLInventoryCategory;
+class LLInventoryItem;
+
+const std::string& get_item_icon_name(LLAssetType::EType asset_type,
+ LLInventoryType::EType inventory_type,
+ U32 attachment_point,
+ BOOL item_is_multi );
+
+LLUIImagePtr get_item_icon(LLAssetType::EType asset_type,
+ LLInventoryType::EType inventory_type,
+ U32 attachment_point,
+ BOOL item_is_multi );
+
+#endif // LL_LLINVENTORYVIEW_H
+
+
+
diff --git a/indra/newview/llfloaterjoystick.cpp b/indra/newview/llfloaterjoystick.cpp
index e5811671ed..06fe2a84c8 100644
--- a/indra/newview/llfloaterjoystick.cpp
+++ b/indra/newview/llfloaterjoystick.cpp
@@ -48,10 +48,10 @@
#include "llcheckboxctrl.h"
LLFloaterJoystick::LLFloaterJoystick(const LLSD& data)
- : LLFloater("floater_joystick")
+ : LLFloater(data)
{
- LLUICtrlFactory::getInstance()->buildFloater(this, "floater_joystick.xml");
- center();
+ //Called from floater reg: LLUICtrlFactory::getInstance()->buildFloater(this, "floater_joystick.xml");
+
}
void LLFloaterJoystick::draw()
@@ -68,14 +68,15 @@ void LLFloaterJoystick::draw()
{
F32 value = joystick->getJoystickAxis(i);
mAxisStats[i]->addValue(value * gFrameIntervalSeconds);
-
- if (mAxisStatsBar[i]->mMinBar > value)
- {
- mAxisStatsBar[i]->mMinBar = value;
- }
- if (mAxisStatsBar[i]->mMaxBar < value)
+ if (mAxisStatsBar[i])
{
- mAxisStatsBar[i]->mMaxBar = value;
+ F32 minbar, maxbar;
+ mAxisStatsBar[i]->getRange(minbar, maxbar);
+ if (llabs(value) > maxbar)
+ {
+ F32 range = llabs(value);
+ mAxisStatsBar[i]->setRange(-range, range, range * 0.25f, range * 0.5f);
+ }
}
}
@@ -84,37 +85,20 @@ void LLFloaterJoystick::draw()
BOOL LLFloaterJoystick::postBuild()
{
- F32 range = gSavedSettings.getBOOL("Cursor3D") ? 1024.f : 2.f;
- LLUIString axis = getString("Axis");
- LLUIString joystick = getString("JoystickMonitor");
-
- // use this child to get relative positioning info; we'll place the
- // joystick monitor on its right, vertically aligned to it.
- LLView* child = getChild<LLView>("FlycamAxisScale1");
- LLRect rect;
-
- if (child)
- {
- LLRect r = child->getRect();
- LLRect f = getRect();
- rect = LLRect(350, r.mTop, r.mRight + 200, 0);
- }
-
- mAxisStatsView = new LLStatView("axis values", joystick, "", rect);
- mAxisStatsView->setDisplayChildren(TRUE);
+ center();
+ F32 range = gSavedSettings.getBOOL("Cursor3D") ? 128.f : 2.f;
for (U32 i = 0; i < 6; i++)
{
- axis.setArg("[NUM]", llformat("%d", i));
mAxisStats[i] = new LLStat(4);
- mAxisStatsBar[i] = mAxisStatsView->addStat(axis, mAxisStats[i]);
- mAxisStatsBar[i]->mMinBar = -range;
- mAxisStatsBar[i]->mMaxBar = range;
- mAxisStatsBar[i]->mLabelSpacing = range * 0.5f;
- mAxisStatsBar[i]->mTickSpacing = range * 0.25f;
+ std::string axisname = llformat("axis%d", i);
+ mAxisStatsBar[i] = getChild<LLStatBar>(axisname);
+ if (mAxisStatsBar[i])
+ {
+ mAxisStatsBar[i]->setStat(mAxisStats[i]);
+ mAxisStatsBar[i]->setRange(-range, range, range * 0.25f, range * 0.5f);
+ }
}
-
- addChild(mAxisStatsView);
mCheckJoystickEnabled = getChild<LLCheckBoxCtrl>("enable_joystick");
childSetCommitCallback("enable_joystick",onCommitJoystickEnabled,this);
@@ -310,7 +294,7 @@ void LLFloaterJoystick::onClickCancel(void *joy_panel)
if (self)
{
self->cancel();
- self->close();
+ self->closeFloater();
}
}
}
@@ -323,7 +307,7 @@ void LLFloaterJoystick::onClickOK(void *joy_panel)
if (self)
{
- self->close();
+ self->closeFloater();
}
}
}
diff --git a/indra/newview/llfloaterjoystick.h b/indra/newview/llfloaterjoystick.h
index 3ce647e5bb..f3559c28e9 100644
--- a/indra/newview/llfloaterjoystick.h
+++ b/indra/newview/llfloaterjoystick.h
@@ -38,11 +38,11 @@
class LLCheckBoxCtrl;
-class LLFloaterJoystick : public LLFloater, public LLFloaterSingleton<LLFloaterJoystick >
+class LLFloaterJoystick : public LLFloater
{
+ friend class LLFloaterReg;
+
public:
- LLFloaterJoystick(const LLSD& data);
- virtual ~LLFloaterJoystick();
virtual BOOL postBuild();
virtual void refresh();
@@ -52,6 +52,10 @@ public:
static void setSNDefaults();
private:
+
+ LLFloaterJoystick(const LLSD& data);
+ virtual ~LLFloaterJoystick();
+
static void onCommitJoystickEnabled(LLUICtrl*, void*);
static void onClickRestoreSNDefaults(void*);
static void onClickCancel(void*);
@@ -84,9 +88,8 @@ private:
LLCheckBoxCtrl *mCheckFlycamEnabled;
// stats view
- LLStatView* mAxisStatsView;
- LLStat* mAxisStats[6];
- LLStatBar* mAxisStatsBar[6];
+ LLStat* mAxisStats[6];
+ LLStatBar* mAxisStatsBar[6];
};
#endif
diff --git a/indra/newview/llfloaterlagmeter.cpp b/indra/newview/llfloaterlagmeter.cpp
index 8fe455fde4..3753dcaaa8 100644
--- a/indra/newview/llfloaterlagmeter.cpp
+++ b/indra/newview/llfloaterlagmeter.cpp
@@ -36,7 +36,7 @@
#include "lluictrlfactory.h"
#include "llviewerstats.h"
-#include "llviewerimage.h"
+#include "llviewertexture.h"
#include "llviewercontrol.h"
#include "llappviewer.h"
@@ -51,14 +51,24 @@ const std::string LAG_WARNING_IMAGE_NAME = "lag_status_warning.tga";
const std::string LAG_GOOD_IMAGE_NAME = "lag_status_good.tga";
LLFloaterLagMeter::LLFloaterLagMeter(const LLSD& key)
- : LLFloater(std::string("floater_lagmeter"))
+ : LLFloater(key)
{
- LLUICtrlFactory::getInstance()->buildFloater(this, "floater_lagmeter.xml");
+// LLUICtrlFactory::getInstance()->buildFloater(this, "floater_lagmeter.xml");
+ mCommitCallbackRegistrar.add("LagMeter.ClickShrink", boost::bind(&LLFloaterLagMeter::onClickShrink, this));
+}
+BOOL LLFloaterLagMeter::postBuild()
+{
// Don't let this window take keyboard focus -- it's confusing to
// lose arrow-key driving when testing lag.
setIsChrome(TRUE);
-
+
+ // were we shrunk last time?
+ if (gSavedSettings.getBOOL("LagMeterShrunk"))
+ {
+ onClickShrink();
+ }
+
mClientButton = getChild<LLButton>("client_lagmeter");
mClientText = getChild<LLTextBox>("client_text");
mClientCause = getChild<LLTextBox>("client_lag_cause");
@@ -93,7 +103,7 @@ LLFloaterLagMeter::LLFloaterLagMeter(const LLSD& key)
config_string = getString("server_single_process_max_time_ms", mStringArgs);
mServerSingleProcessMaxTime = (float)atof( config_string.c_str() );
- mShrunk = false;
+// mShrunk = false;
config_string = getString("max_width_px", mStringArgs);
mMaxWidth = atoi( config_string.c_str() );
config_string = getString("min_width_px", mStringArgs);
@@ -111,23 +121,18 @@ LLFloaterLagMeter::LLFloaterLagMeter(const LLSD& key)
mStringArgs["[SERVER_FRAME_RATE_CRITICAL]"] = getString("server_frame_rate_critical_fps");
mStringArgs["[SERVER_FRAME_RATE_WARNING]"] = getString("server_frame_rate_warning_fps");
- childSetAction("minimize", onClickShrink, this);
+// childSetAction("minimize", onClickShrink, this);
- // were we shrunk last time?
- if (gSavedSettings.getBOOL("LagMeterShrunk"))
- {
- onClickShrink(this);
- }
+ return TRUE;
}
-
LLFloaterLagMeter::~LLFloaterLagMeter()
{
// save shrunk status for next time
- gSavedSettings.setBOOL("LagMeterShrunk", mShrunk);
+// gSavedSettings.setBOOL("LagMeterShrunk", mShrunk);
// expand so we save the large window rectangle
- if (mShrunk)
+ if (gSavedSettings.getBOOL("LagMeterShrunk"))
{
- onClickShrink(this);
+ onClickShrink();
}
}
@@ -147,25 +152,25 @@ void LLFloaterLagMeter::determineClient()
if (!gFocusMgr.getAppHasFocus())
{
- mClientButton->setImageUnselected(LAG_GOOD_IMAGE_NAME);
+ mClientButton->setImageUnselected(LLUI::getUIImage(LAG_GOOD_IMAGE_NAME));
mClientText->setText( getString("client_frame_time_window_bg_msg", mStringArgs) );
mClientCause->setText( LLStringUtil::null );
}
else if(client_frame_time >= mClientFrameTimeCritical)
{
- mClientButton->setImageUnselected(LAG_CRITICAL_IMAGE_NAME);
+ mClientButton->setImageUnselected(LLUI::getUIImage(LAG_CRITICAL_IMAGE_NAME));
mClientText->setText( getString("client_frame_time_critical_msg", mStringArgs) );
find_cause = true;
}
else if(client_frame_time >= mClientFrameTimeWarning)
{
- mClientButton->setImageUnselected(LAG_WARNING_IMAGE_NAME);
+ mClientButton->setImageUnselected(LLUI::getUIImage(LAG_WARNING_IMAGE_NAME));
mClientText->setText( getString("client_frame_time_warning_msg", mStringArgs) );
find_cause = true;
}
else
{
- mClientButton->setImageUnselected(LAG_GOOD_IMAGE_NAME);
+ mClientButton->setImageUnselected(LLUI::getUIImage(LAG_GOOD_IMAGE_NAME));
mClientText->setText( getString("client_frame_time_normal_msg", mStringArgs) );
mClientCause->setText( LLStringUtil::null );
}
@@ -180,7 +185,7 @@ void LLFloaterLagMeter::determineClient()
{
mClientCause->setText( getString("client_texture_loading_cause_msg", mStringArgs) );
}
- else if((BYTES_TO_MEGA_BYTES(LLViewerImage::sBoundTextureMemoryInBytes)) > LLViewerImage::sMaxBoundTextureMemInMegaBytes)
+ else if((BYTES_TO_MEGA_BYTES(LLViewerTexture::sBoundTextureMemoryInBytes)) > LLViewerTexture::sMaxBoundTextureMemInMegaBytes)
{
mClientCause->setText( getString("client_texture_memory_cause_msg", mStringArgs) );
}
@@ -206,13 +211,13 @@ void LLFloaterLagMeter::determineNetwork()
if(packet_loss >= mNetworkPacketLossCritical)
{
- mNetworkButton->setImageUnselected(LAG_CRITICAL_IMAGE_NAME);
+ mNetworkButton->setImageUnselected(LLUI::getUIImage(LAG_CRITICAL_IMAGE_NAME));
mNetworkText->setText( getString("network_packet_loss_critical_msg", mStringArgs) );
find_cause_loss = true;
}
else if(ping_time >= mNetworkPingCritical)
{
- mNetworkButton->setImageUnselected(LAG_CRITICAL_IMAGE_NAME);
+ mNetworkButton->setImageUnselected(LLUI::getUIImage(LAG_CRITICAL_IMAGE_NAME));
if (client_frame_time_ms < mNetworkPingCritical)
{
mNetworkText->setText( getString("network_ping_critical_msg", mStringArgs) );
@@ -221,13 +226,13 @@ void LLFloaterLagMeter::determineNetwork()
}
else if(packet_loss >= mNetworkPacketLossWarning)
{
- mNetworkButton->setImageUnselected(LAG_WARNING_IMAGE_NAME);
+ mNetworkButton->setImageUnselected(LLUI::getUIImage(LAG_WARNING_IMAGE_NAME));
mNetworkText->setText( getString("network_packet_loss_warning_msg", mStringArgs) );
find_cause_loss = true;
}
else if(ping_time >= mNetworkPingWarning)
{
- mNetworkButton->setImageUnselected(LAG_WARNING_IMAGE_NAME);
+ mNetworkButton->setImageUnselected(LLUI::getUIImage(LAG_WARNING_IMAGE_NAME));
if (client_frame_time_ms < mNetworkPingWarning)
{
mNetworkText->setText( getString("network_ping_warning_msg", mStringArgs) );
@@ -236,7 +241,7 @@ void LLFloaterLagMeter::determineNetwork()
}
else
{
- mNetworkButton->setImageUnselected(LAG_GOOD_IMAGE_NAME);
+ mNetworkButton->setImageUnselected(LLUI::getUIImage(LAG_GOOD_IMAGE_NAME));
mNetworkText->setText( getString("network_performance_normal_msg", mStringArgs) );
}
@@ -261,19 +266,19 @@ void LLFloaterLagMeter::determineServer()
if(sim_frame_time >= mServerFrameTimeCritical)
{
- mServerButton->setImageUnselected(LAG_CRITICAL_IMAGE_NAME);
+ mServerButton->setImageUnselected(LLUI::getUIImage(LAG_CRITICAL_IMAGE_NAME));
mServerText->setText( getString("server_frame_time_critical_msg", mStringArgs) );
find_cause = true;
}
else if(sim_frame_time >= mServerFrameTimeWarning)
{
- mServerButton->setImageUnselected(LAG_WARNING_IMAGE_NAME);
+ mServerButton->setImageUnselected(LLUI::getUIImage(LAG_WARNING_IMAGE_NAME));
mServerText->setText( getString("server_frame_time_warning_msg", mStringArgs) );
find_cause = true;
}
else
{
- mServerButton->setImageUnselected(LAG_GOOD_IMAGE_NAME);
+ mServerButton->setImageUnselected(LLUI::getUIImage(LAG_GOOD_IMAGE_NAME));
mServerText->setText( getString("server_frame_time_normal_msg", mStringArgs) );
mServerCause->setText( LLStringUtil::null );
}
@@ -307,58 +312,61 @@ void LLFloaterLagMeter::determineServer()
}
}
-//static
-void LLFloaterLagMeter::onClickShrink(void * data)
+
+void LLFloaterLagMeter::onClickShrink() // toggle "LagMeterShrunk"
{
- LLFloaterLagMeter * self = (LLFloaterLagMeter*)data;
+// LLFloaterLagMeter * self = (LLFloaterLagMeter*)data;
+
+ LLButton * button = getChild<LLButton>("minimize");
+ S32 delta_width = mMaxWidth -mMinWidth;
+ LLRect r = getRect();
+ bool shrunk = gSavedSettings.getBOOL("LagMeterShrunk");
- LLButton * button = self->getChild<LLButton>("minimize");
- S32 delta_width = self->mMaxWidth - self->mMinWidth;
- LLRect r = self->getRect();
- if(self->mShrunk)
+ if(shrunk)
{
- self->setTitle( self->getString("max_title_msg", self->mStringArgs) );
+ setTitle(getString("max_title_msg", mStringArgs) );
// make left edge appear to expand
r.translate(-delta_width, 0);
- self->setRect(r);
- self->reshape(self->mMaxWidth, self->getRect().getHeight());
+ setRect(r);
+ reshape(mMaxWidth, getRect().getHeight());
- self->childSetText("client", self->getString("client_text_msg", self->mStringArgs) + ":");
- self->childSetText("network", self->getString("network_text_msg", self->mStringArgs) + ":");
- self->childSetText("server", self->getString("server_text_msg", self->mStringArgs) + ":");
+ childSetText("client", getString("client_text_msg", mStringArgs) + ":");
+ childSetText("network", getString("network_text_msg",mStringArgs) + ":");
+ childSetText("server", getString("server_text_msg", mStringArgs) + ":");
// usually "<<"
- button->setLabel( self->getString("smaller_label", self->mStringArgs) );
+ button->setLabel( getString("smaller_label", mStringArgs) );
}
else
{
- self->setTitle( self->getString("min_title_msg", self->mStringArgs) );
+ setTitle( getString("min_title_msg", mStringArgs) );
// make left edge appear to collapse
r.translate(delta_width, 0);
- self->setRect(r);
- self->reshape(self->mMinWidth, self->getRect().getHeight());
+ setRect(r);
+ reshape(mMinWidth, getRect().getHeight());
- self->childSetText("client", self->getString("client_text_msg", self->mStringArgs) );
- self->childSetText("network", self->getString("network_text_msg", self->mStringArgs) );
- self->childSetText("server", self->getString("server_text_msg", self->mStringArgs) );
+ childSetText("client", getString("client_text_msg", mStringArgs) );
+ childSetText("network",getString("network_text_msg",mStringArgs) );
+ childSetText("server", getString("server_text_msg", mStringArgs) );
// usually ">>"
- button->setLabel( self->getString("bigger_label", self->mStringArgs) );
+ button->setLabel( getString("bigger_label", mStringArgs) );
}
// Don't put keyboard focus on the button
button->setFocus(FALSE);
- self->mClientText->setVisible(self->mShrunk);
- self->mClientCause->setVisible(self->mShrunk);
- self->childSetVisible("client_help", self->mShrunk);
+// self->mClientText->setVisible(self->mShrunk);
+// self->mClientCause->setVisible(self->mShrunk);
+// self->childSetVisible("client_help", self->mShrunk);
- self->mNetworkText->setVisible(self->mShrunk);
- self->mNetworkCause->setVisible(self->mShrunk);
- self->childSetVisible("network_help", self->mShrunk);
+// self->mNetworkText->setVisible(self->mShrunk);
+// self->mNetworkCause->setVisible(self->mShrunk);
+// self->childSetVisible("network_help", self->mShrunk);
- self->mServerText->setVisible(self->mShrunk);
- self->mServerCause->setVisible(self->mShrunk);
- self->childSetVisible("server_help", self->mShrunk);
+// self->mServerText->setVisible(self->mShrunk);
+// self->mServerCause->setVisible(self->mShrunk);
+// self->childSetVisible("server_help", self->mShrunk);
- self->mShrunk = !self->mShrunk;
+// self->mShrunk = !self->mShrunk;
+ gSavedSettings.setBOOL("LagMeterShrunk", !gSavedSettings.getBOOL("LagMeterShrunk"));
}
diff --git a/indra/newview/llfloaterlagmeter.h b/indra/newview/llfloaterlagmeter.h
index d9cea18305..592630636a 100644
--- a/indra/newview/llfloaterlagmeter.h
+++ b/indra/newview/llfloaterlagmeter.h
@@ -35,22 +35,24 @@
#include "llfloater.h"
-class LLFloaterLagMeter : public LLFloater, public LLFloaterSingleton<LLFloaterLagMeter>
+class LLTextBox;
+
+class LLFloaterLagMeter : public LLFloater
{
- friend class LLUISingleton<LLFloaterLagMeter, VisibilityPolicy<LLFloater> >;
+ friend class LLFloaterReg;
public:
/*virtual*/ void draw();
-
+ /*virtual*/ BOOL postBuild();
private:
+
LLFloaterLagMeter(const LLSD& key);
/*virtual*/ ~LLFloaterLagMeter();
-
void determineClient();
void determineNetwork();
void determineServer();
- static void onClickShrink(void * data);
+ void onClickShrink();
bool mShrunk;
S32 mMaxWidth, mMinWidth;
diff --git a/indra/newview/llfloaterland.cpp b/indra/newview/llfloaterland.cpp
index 94a834502f..4cd09faaaf 100644
--- a/indra/newview/llfloaterland.cpp
+++ b/indra/newview/llfloaterland.cpp
@@ -44,21 +44,23 @@
#include "lluserauth.h"
#include "llagent.h"
-#include "llfloateravatarpicker.h"
#include "llbutton.h"
#include "llcheckboxctrl.h"
-#include "llradiogroup.h"
#include "llcombobox.h"
+#include "llfloaterreg.h"
+#include "llfloateravatarpicker.h"
#include "llfloaterauction.h"
-#include "llfloateravatarinfo.h"
#include "llfloatergroups.h"
-#include "llfloatergroupinfo.h"
+#include "llavataractions.h"
#include "lllineeditor.h"
#include "llnamelistctrl.h"
#include "llnotify.h"
+#include "llpanellandaudio.h"
#include "llpanellandmedia.h"
#include "llradiogroup.h"
#include "llscrolllistctrl.h"
+#include "llscrolllistitem.h"
+#include "llscrolllistcell.h"
#include "llselectmgr.h"
#include "llspinctrl.h"
#include "lltabcontainer.h"
@@ -66,7 +68,7 @@
#include "lltexturectrl.h"
#include "lluiconstants.h"
#include "lluictrlfactory.h"
-#include "llviewerimagelist.h" // LLUIImageList
+#include "llviewertexturelist.h" // LLUIImageList
#include "llviewermessage.h"
#include "llviewerparcelmgr.h"
#include "llviewerregion.h"
@@ -75,6 +77,9 @@
#include "llviewerwindow.h"
#include "llviewercontrol.h"
#include "roles_constants.h"
+#include "lltrans.h"
+
+#include "llgroupactions.h"
static std::string OWNER_ONLINE = "0";
static std::string OWNER_OFFLINE = "1";
@@ -146,23 +151,50 @@ void send_parcel_select_objects(S32 parcel_local_id, S32 return_type,
//static
LLPanelLandObjects* LLFloaterLand::getCurrentPanelLandObjects()
{
- return LLFloaterLand::getInstance()->mPanelObjects;
+ LLFloaterLand* land_instance = LLFloaterReg::getTypedInstance<LLFloaterLand>("about_land");
+ if(land_instance)
+ {
+ return land_instance->mPanelObjects;
+ }
+ else
+ {
+ return NULL;
+ }
}
//static
LLPanelLandCovenant* LLFloaterLand::getCurrentPanelLandCovenant()
{
- return LLFloaterLand::getInstance()->mPanelCovenant;
+ LLFloaterLand* land_instance = LLFloaterReg::getTypedInstance<LLFloaterLand>("about_land");
+ if(land_instance)
+ {
+ return land_instance->mPanelCovenant;
+ }
+ else
+ {
+ return NULL;
+ }
}
// static
void LLFloaterLand::refreshAll()
{
- LLFloaterLand::getInstance()->refresh();
+ LLFloaterLand* land_instance = LLFloaterReg::getTypedInstance<LLFloaterLand>("about_land");
+ if(land_instance)
+ {
+ land_instance->refresh();
+ }
}
-void LLFloaterLand::onOpen()
+void LLFloaterLand::onOpen(const LLSD& key)
{
+ // moved from triggering show instance in llviwermenu.cpp
+
+ if (LLViewerParcelMgr::getInstance()->selectionEmpty())
+ {
+ LLViewerParcelMgr::getInstance()->selectParcelAt(gAgent.getPositionGlobal());
+ }
+
// Done automatically when the selected parcel's properties arrive
// (and hence we have the local id).
// LLViewerParcelMgr::getInstance()->sendParcelAccessListRequest(AL_ACCESS | AL_BAN | AL_RENTER);
@@ -174,45 +206,40 @@ void LLFloaterLand::onOpen()
refresh();
}
-
-// virtual
-void LLFloaterLand::onClose(bool app_quitting)
+void LLFloaterLand::onVisibilityChange(const LLSD& visible)
{
- LLViewerParcelMgr::getInstance()->removeObserver( sObserver );
- delete sObserver;
- sObserver = NULL;
-
- // Might have been showing owned objects
- LLSelectMgr::getInstance()->unhighlightAll();
-
- // Save which panel we had open
- sLastTab = mTabLand->getCurrentPanelIndex();
+ if (!visible.asBoolean())
+ {
+ // Might have been showing owned objects
+ LLSelectMgr::getInstance()->unhighlightAll();
- destroy();
+ // Save which panel we had open
+ sLastTab = mTabLand->getCurrentPanelIndex();
+ }
}
LLFloaterLand::LLFloaterLand(const LLSD& seed)
-: LLFloater(std::string("floaterland"), std::string("FloaterLandRect5"), std::string("About Land"))
+: LLFloater(seed)
{
- LLCallbackMap::map_t factory_map;
- factory_map["land_general_panel"] = LLCallbackMap(createPanelLandGeneral, this);
-
-
- factory_map["land_covenant_panel"] = LLCallbackMap(createPanelLandCovenant, this);
- factory_map["land_objects_panel"] = LLCallbackMap(createPanelLandObjects, this);
- factory_map["land_options_panel"] = LLCallbackMap(createPanelLandOptions, this);
- factory_map["land_media_panel"] = LLCallbackMap(createPanelLandMedia, this);
- factory_map["land_access_panel"] = LLCallbackMap(createPanelLandAccess, this);
+ mFactoryMap["land_general_panel"] = LLCallbackMap(createPanelLandGeneral, this);
+ mFactoryMap["land_covenant_panel"] = LLCallbackMap(createPanelLandCovenant, this);
+ mFactoryMap["land_objects_panel"] = LLCallbackMap(createPanelLandObjects, this);
+ mFactoryMap["land_options_panel"] = LLCallbackMap(createPanelLandOptions, this);
+ mFactoryMap["land_audio_panel"] = LLCallbackMap(createPanelLandAudio, this);
+ mFactoryMap["land_media_panel"] = LLCallbackMap(createPanelLandMedia, this);
+ mFactoryMap["land_access_panel"] = LLCallbackMap(createPanelLandAccess, this);
- LLUICtrlFactory::getInstance()->buildFloater(this, "floater_about_land.xml", &factory_map, false);
+ //LLUICtrlFactory::getInstance()->buildFloater(this, "floater_about_land.xml", false);
sObserver = new LLParcelSelectionObserver();
LLViewerParcelMgr::getInstance()->addObserver( sObserver );
}
BOOL LLFloaterLand::postBuild()
-{
+{
+ mVisibleSignal.connect(boost::bind(&LLFloaterLand::onVisibilityChange, this, _2));
+
LLTabContainer* tab = getChild<LLTabContainer>("landtab");
mTabLand = (LLTabContainer*) tab;
@@ -229,6 +256,9 @@ BOOL LLFloaterLand::postBuild()
// virtual
LLFloaterLand::~LLFloaterLand()
{
+ LLViewerParcelMgr::getInstance()->removeObserver( sObserver );
+ delete sObserver;
+ sObserver = NULL;
}
// public
@@ -237,6 +267,7 @@ void LLFloaterLand::refresh()
mPanelGeneral->refresh();
mPanelObjects->refresh();
mPanelOptions->refresh();
+ mPanelAudio->refresh();
mPanelMedia->refresh();
mPanelAccess->refresh();
}
@@ -276,6 +307,14 @@ void* LLFloaterLand::createPanelLandOptions(void* data)
}
// static
+void* LLFloaterLand::createPanelLandAudio(void* data)
+{
+ LLFloaterLand* self = (LLFloaterLand*)data;
+ self->mPanelAudio = new LLPanelLandAudio(self->mParcel);
+ return self->mPanelAudio;
+}
+
+// static
void* LLFloaterLand::createPanelLandMedia(void* data)
{
LLFloaterLand* self = (LLFloaterLand*)data;
@@ -297,7 +336,7 @@ void* LLFloaterLand::createPanelLandAccess(void* data)
LLPanelLandGeneral::LLPanelLandGeneral(LLParcelSelectionHandle& parcel)
-: LLPanel(std::string("land_general_panel")),
+: LLPanel(),
mUncheckedSell(FALSE),
mParcel(parcel)
{
@@ -306,15 +345,13 @@ LLPanelLandGeneral::LLPanelLandGeneral(LLParcelSelectionHandle& parcel)
BOOL LLPanelLandGeneral::postBuild()
{
mEditName = getChild<LLLineEditor>("Name");
- mEditName->setCommitCallback(onCommitAny);
+ mEditName->setCommitCallback(onCommitAny, this);
childSetPrevalidate("Name", LLLineEditor::prevalidatePrintableNotPipe);
- childSetUserData("Name", this);
mEditDesc = getChild<LLTextEditor>("Description");
mEditDesc->setCommitOnFocusLost(TRUE);
- mEditDesc->setCommitCallback(onCommitAny);
+ mEditDesc->setCommitCallback(onCommitAny, this);
childSetPrevalidate("Description", LLLineEditor::prevalidatePrintableNotPipe);
- childSetUserData("Description", this);
mTextSalePending = getChild<LLTextBox>("SalePending");
@@ -333,7 +370,7 @@ BOOL LLPanelLandGeneral::postBuild()
mBtnSetGroup = getChild<LLButton>("Set...");
- mBtnSetGroup->setClickedCallback(onClickSetGroup, this);
+ mBtnSetGroup->setCommitCallback(boost::bind(&LLPanelLandGeneral::onClickSetGroup, this));
mCheckDeedToGroup = getChild<LLCheckBoxCtrl>( "check deed");
@@ -396,7 +433,7 @@ BOOL LLPanelLandGeneral::postBuild()
mBtnReclaimLand->setClickedCallback(onClickReclaim, NULL);
mBtnStartAuction = getChild<LLButton>("Linden Sale...");
- mBtnStartAuction->setClickedCallback(onClickStartAuction, NULL);
+ mBtnStartAuction->setClickedCallback(onClickStartAuction, this);
return TRUE;
}
@@ -754,22 +791,20 @@ void LLPanelLandGeneral::draw()
LLPanel::draw();
}
-// static
-void LLPanelLandGeneral::onClickSetGroup(void* userdata)
+void LLPanelLandGeneral::onClickSetGroup()
{
- LLPanelLandGeneral* panelp = (LLPanelLandGeneral*)userdata;
- LLFloaterGroupPicker* fg;
+ LLFloater* parent_floater = gFloaterView->getParentFloater(this);
- LLFloater* parent_floater = gFloaterView->getParentFloater(panelp);
-
- fg = LLFloaterGroupPicker::showInstance(LLSD(gAgent.getID()));
- fg->setSelectCallback( cbGroupID, userdata );
-
- if (parent_floater)
+ LLFloaterGroupPicker* fg = LLFloaterReg::showTypedInstance<LLFloaterGroupPicker>("group_picker", LLSD(gAgent.getID()));
+ if (fg)
{
- LLRect new_rect = gFloaterView->findNeighboringPosition(parent_floater, fg);
- fg->setOrigin(new_rect.mLeft, new_rect.mBottom);
- parent_floater->addDependentFloater(fg);
+ fg->setSelectGroupCallback( boost::bind(&LLPanelLandGeneral::setGroup, this, _1 ));
+ if (parent_floater)
+ {
+ LLRect new_rect = gFloaterView->findNeighboringPosition(parent_floater, fg);
+ fg->setOrigin(new_rect.mLeft, new_rect.mBottom);
+ parent_floater->addDependentFloater(fg);
+ }
}
}
@@ -783,22 +818,15 @@ void LLPanelLandGeneral::onClickProfile(void* data)
if (parcel->getIsGroupOwned())
{
const LLUUID& group_id = parcel->getGroupID();
- LLFloaterGroupInfo::showFromUUID(group_id);
+ LLGroupActions::show(group_id);
}
else
{
const LLUUID& avatar_id = parcel->getOwnerID();
- LLFloaterAvatarInfo::showFromObject(avatar_id);
+ LLAvatarActions::showProfile(avatar_id);
}
}
-// static
-void LLPanelLandGeneral::cbGroupID(LLUUID group_id, void* userdata)
-{
- LLPanelLandGeneral* self = (LLPanelLandGeneral*)userdata;
- self->setGroup(group_id);
-}
-
// public
void LLPanelLandGeneral::setGroup(const LLUUID& group_id)
{
@@ -900,7 +928,8 @@ void LLPanelLandGeneral::onClickStartAuction(void* data)
}
else
{
- LLFloaterAuction::show();
+ //LLFloaterAuction::showInstance();
+ LLFloaterReg::showInstance("auction");
}
}
}
@@ -974,7 +1003,8 @@ void LLPanelLandGeneral::onClickStopSellLand(void* data)
// LLPanelLandObjects
//---------------------------------------------------------------------------
LLPanelLandObjects::LLPanelLandObjects(LLParcelSelectionHandle& parcel)
-: LLPanel(std::string("land_objects_panel")), mParcel(parcel)
+ : LLPanel(),
+ mParcel(parcel)
{
}
@@ -1014,10 +1044,8 @@ BOOL LLPanelLandObjects::postBuild()
mCleanOtherObjectsTime = getChild<LLLineEditor>("clean other time");
mCleanOtherObjectsTime->setFocusLostCallback(onLostFocus, this);
- mCleanOtherObjectsTime->setCommitCallback(onCommitClean);
-
+ mCleanOtherObjectsTime->setCommitCallback(onCommitClean, this);
childSetPrevalidate("clean other time", LLLineEditor::prevalidateNonNegativeS32);
- childSetUserData("clean other time", this);
mBtnRefresh = getChild<LLButton>("Refresh List");
mBtnRefresh->setClickedCallback(onClickRefresh, this);
@@ -1032,7 +1060,7 @@ BOOL LLPanelLandObjects::postBuild()
mOwnerList = getChild<LLNameListCtrl>("owner list");
mOwnerList->sortByColumnIndex(3, FALSE);
childSetCommitCallback("owner list", onCommitList, this);
- mOwnerList->setDoubleClickCallback(onDoubleClickOwner);
+ mOwnerList->setDoubleClickCallback(onDoubleClickOwner, this);
return TRUE;
}
@@ -1064,11 +1092,11 @@ void LLPanelLandObjects::onDoubleClickOwner(void *userdata)
BOOL is_group = cell->getValue().asString() == OWNER_GROUP;
if (is_group)
{
- LLFloaterGroupInfo::showFromUUID(owner_id);
+ LLGroupActions::show(owner_id);
}
else
{
- LLFloaterAvatarInfo::showFromDirectory(owner_id);
+ LLAvatarActions::showProfile(owner_id);
}
}
}
@@ -1406,7 +1434,7 @@ void LLPanelLandObjects::onClickRefresh(void* userdata)
// ready the list for results
self->mOwnerList->deleteAllItems();
- self->mOwnerList->addCommentText(std::string("Searching...")); // *TODO: Translate
+ self->mOwnerList->setCommentText(LLTrans::getString("Searching"));
self->mOwnerList->setEnabled(FALSE);
self->mFirstReply = TRUE;
@@ -1468,39 +1496,34 @@ void LLPanelLandObjects::processParcelObjectOwnersReply(LLMessageSystem *msg, vo
continue;
}
- LLScrollListItem *row = new LLScrollListItem( TRUE, NULL, owner_id);
+ LLNameListCtrl::NameItem item_params;
+ item_params.value = owner_id;
+ item_params.target = is_group_owned ? LLNameListCtrl::GROUP : LLNameListCtrl::INDIVIDUAL;
+
if (is_group_owned)
{
- row->addColumn(self->mIconGroup);
- row->addColumn(OWNER_GROUP, FONT);
+ item_params.columns.add().type("icon").value(self->mIconGroup->getName()).column("type");
+ item_params.columns.add().value(OWNER_GROUP).font(FONT).column("online_status");
}
else if (is_online)
{
- row->addColumn(self->mIconAvatarOnline);
- row->addColumn(OWNER_ONLINE, FONT);
+ item_params.columns.add().type("icon").value(self->mIconAvatarOnline->getName()).column("type");
+ item_params.columns.add().value(OWNER_ONLINE).font(FONT).column("online_status");
}
else // offline
{
- row->addColumn(self->mIconAvatarOffline);
- row->addColumn(OWNER_OFFLINE, FONT);
+ item_params.columns.add().type("icon").value(self->mIconAvatarOffline->getName()).column("type");
+ item_params.columns.add().value(OWNER_OFFLINE).font(FONT).column("online_status");
}
+
// Placeholder for name.
- row->addColumn(LLStringUtil::null, FONT);
+ item_params.columns.add().font(FONT).column("name");
object_count_str = llformat("%d", object_count);
- row->addColumn(object_count_str, FONT);
-
- row->addColumn(formatted_time((time_t)most_recent_time), FONT);
+ item_params.columns.add().value(object_count_str).font(FONT).column("count");
+ item_params.columns.add().value(formatted_time((time_t)most_recent_time)).font(FONT).column("mostrecent");
-
- if (is_group_owned)
- {
- self->mOwnerList->addGroupNameItem(row, ADD_BOTTOM);
- }
- else
- {
- self->mOwnerList->addNameItem(row, ADD_BOTTOM);
- }
+ self->mOwnerList->addRow(item_params);
lldebugs << "object owner " << owner_id << " (" << (is_group_owned ? "group" : "agent")
<< ") owns " << object_count << " objects." << llendl;
@@ -1508,7 +1531,7 @@ void LLPanelLandObjects::processParcelObjectOwnersReply(LLMessageSystem *msg, vo
// check for no results
if (0 == self->mOwnerList->getItemCount())
{
- self->mOwnerList->addCommentText(std::string("None found.")); // *TODO: Translate
+ self->mOwnerList->setCommentText(LLTrans::getString("NoneFound"));
}
else
{
@@ -1699,7 +1722,7 @@ void LLPanelLandObjects::onCommitClean(LLUICtrl *caller, void* user_data)
//---------------------------------------------------------------------------
LLPanelLandOptions::LLPanelLandOptions(LLParcelSelectionHandle& parcel)
-: LLPanel(std::string("land_options_panel")),
+: LLPanel(),
mCheckEditObjects(NULL),
mCheckEditGroupObjects(NULL),
mCheckAllObjectEntry(NULL),
@@ -1709,7 +1732,6 @@ LLPanelLandOptions::LLPanelLandOptions(LLParcelSelectionHandle& parcel)
mCheckFly(NULL),
mCheckGroupScripts(NULL),
mCheckOtherScripts(NULL),
- mCheckLandmark(NULL),
mCheckShowDirectory(NULL),
mCategoryCombo(NULL),
mLandingTypeCombo(NULL),
@@ -1743,10 +1765,6 @@ BOOL LLPanelLandOptions::postBuild()
childSetCommitCallback("edit land check", onCommitAny, this);
- mCheckLandmark = getChild<LLCheckBoxCtrl>( "check landmark");
- childSetCommitCallback("check landmark", onCommitAny, this);
-
-
mCheckGroupScripts = getChild<LLCheckBoxCtrl>( "check group scripts");
childSetCommitCallback("check group scripts", onCommitAny, this);
@@ -1808,8 +1826,7 @@ BOOL LLPanelLandOptions::postBuild()
mSnapshotCtrl = getChild<LLTextureCtrl>("snapshot_ctrl");
if (mSnapshotCtrl)
{
- mSnapshotCtrl->setCommitCallback( onCommitAny );
- mSnapshotCtrl->setCallbackUserData( this );
+ mSnapshotCtrl->setCommitCallback( onCommitAny, this );
mSnapshotCtrl->setAllowNoTexture ( TRUE );
mSnapshotCtrl->setImmediateFilterPermMask(PERM_COPY | PERM_TRANSFER);
mSnapshotCtrl->setNonImmediateFilterPermMask(PERM_COPY | PERM_TRANSFER);
@@ -1873,9 +1890,6 @@ void LLPanelLandOptions::refresh()
mCheckFly ->set(FALSE);
mCheckFly ->setEnabled(FALSE);
- mCheckLandmark ->set(FALSE);
- mCheckLandmark ->setEnabled(FALSE);
-
mCheckGroupScripts ->set(FALSE);
mCheckGroupScripts ->setEnabled(FALSE);
@@ -1926,9 +1940,6 @@ void LLPanelLandOptions::refresh()
mCheckFly ->set( parcel->getAllowFly() );
mCheckFly ->setEnabled( can_change_options );
- mCheckLandmark ->set( parcel->getAllowLandmark() );
- mCheckLandmark ->setEnabled( can_change_options );
-
mCheckGroupScripts ->set( parcel->getAllowGroupScripts() || parcel->getAllowOtherScripts());
mCheckGroupScripts ->setEnabled( can_change_options && !parcel->getAllowOtherScripts());
@@ -2143,7 +2154,7 @@ void LLPanelLandOptions::onCommitAny(LLUICtrl *ctrl, void *userdata)
BOOL allow_terraform = self->mCheckEditLand->get();
BOOL allow_damage = !self->mCheckSafe->get();
BOOL allow_fly = self->mCheckFly->get();
- BOOL allow_landmark = self->mCheckLandmark->get();
+ BOOL allow_landmark = TRUE; // cannot restrict landmark creation
BOOL allow_group_scripts = self->mCheckGroupScripts->get() || self->mCheckOtherScripts->get();
BOOL allow_other_scripts = self->mCheckOtherScripts->get();
BOOL allow_publish = FALSE;
@@ -2262,7 +2273,8 @@ void LLPanelLandOptions::onClickPublishHelp(void*)
//---------------------------------------------------------------------------
LLPanelLandAccess::LLPanelLandAccess(LLParcelSelectionHandle& parcel)
-: LLPanel(std::string("land_access_panel")), mParcel(parcel)
+ : LLPanel(),
+ mParcel(parcel)
{
}
@@ -2301,6 +2313,8 @@ LLPanelLandAccess::~LLPanelLandAccess()
void LLPanelLandAccess::refresh()
{
+ LLFloater* parent_floater = gFloaterView->getParentFloater(this);
+
if (mListAccess)
mListAccess->deleteAllItems();
if (mListBanned)
@@ -2328,7 +2342,6 @@ void LLPanelLandAccess::refresh()
childSetToolTipArg("AccessList", "[LISTED]", llformat("%d",count));
childSetToolTipArg("AccessList", "[MAX]", llformat("%d",PARCEL_MAX_ACCESS_LIST));
- // *TODO: Translate
for (access_map_const_iterator cit = parcel->mAccessList.begin();
cit != parcel->mAccessList.end(); ++cit)
{
@@ -2336,25 +2349,28 @@ void LLPanelLandAccess::refresh()
std::string suffix;
if (entry.mTime != 0)
{
+ LLStringUtil::format_map_t args;
S32 now = time(NULL);
S32 seconds = entry.mTime - now;
if (seconds < 0) seconds = 0;
suffix.assign(" (");
if (seconds >= 120)
{
- std::string buf = llformat("%d minutes", (seconds/60));
+ args["[MINUTES]"] = llformat("%d", (seconds/60));
+ std::string buf = parent_floater->getString ("Minutes", args);
suffix.append(buf);
}
else if (seconds >= 60)
{
- suffix.append("1 minute");
+ suffix.append("1 " + parent_floater->getString("Minute"));
}
else
{
- std::string buf = llformat("%d seconds", seconds);
+ args["[SECONDS]"] = llformat("%d", seconds);
+ std::string buf = parent_floater->getString ("Seconds", args);
suffix.append(buf);
}
- suffix.append(" remaining)");
+ suffix.append(" " + parent_floater->getString("Remaining") + ")");
}
if (mListAccess)
mListAccess->addNameItem(entry.mID, ADD_SORTED, TRUE, suffix);
@@ -2375,25 +2391,28 @@ void LLPanelLandAccess::refresh()
std::string suffix;
if (entry.mTime != 0)
{
+ LLStringUtil::format_map_t args;
S32 now = time(NULL);
S32 seconds = entry.mTime - now;
if (seconds < 0) seconds = 0;
suffix.assign(" (");
if (seconds >= 120)
{
- std::string buf = llformat("%d minutes", (seconds/60));
+ args["[MINUTES]"] = llformat("%d", (seconds/60));
+ std::string buf = parent_floater->getString ("Minutes", args);
suffix.append(buf);
}
else if (seconds >= 60)
{
- suffix.append("1 minute");
+ suffix.append("1 " + parent_floater->getString("Minute"));
}
else
{
- std::string buf = llformat("%d seconds", seconds);
+ args["[SECONDS]"] = llformat("%d", seconds);
+ std::string buf = parent_floater->getString ("Seconds", args);
suffix.append(buf);
}
- suffix.append(" remaining)");
+ suffix.append(" " + parent_floater->getString("Remaining") + ")");
}
mListBanned->addNameItem(entry.mID, ADD_SORTED, TRUE, suffix);
}
@@ -2758,7 +2777,8 @@ void LLPanelLandAccess::onClickRemoveBanned(void* data)
// LLPanelLandCovenant
//---------------------------------------------------------------------------
LLPanelLandCovenant::LLPanelLandCovenant(LLParcelSelectionHandle& parcel)
-: LLPanel(std::string("land_covenant_panel")), mParcel(parcel)
+ : LLPanel(),
+ mParcel(parcel)
{
}
@@ -2838,11 +2858,7 @@ void LLPanelLandCovenant::updateCovenantText(const std::string &string)
if (self)
{
LLViewerTextEditor* editor = self->getChild<LLViewerTextEditor>("covenant_editor");
- if (editor)
- {
- editor->setHandleEditKeysDirectly(TRUE);
- editor->setText(string);
- }
+ editor->setText(string);
}
}
diff --git a/indra/newview/llfloaterland.h b/indra/newview/llfloaterland.h
index 4c3de65d71..749c395147 100644
--- a/indra/newview/llfloaterland.h
+++ b/indra/newview/llfloaterland.h
@@ -38,8 +38,9 @@
#include <vector>
#include "llfloater.h"
-//#include "llviewerimagelist.h"
-#include "llmemory.h" // LLPointer<>
+#include "llpointer.h" // LLPointer<>
+//#include "llviewertexturelist.h"
+#include "llsafehandle.h"
typedef std::set<LLUUID, lluuid_less> uuid_list_t;
const F32 CACHE_REFRESH_TIME = 2.5f;
@@ -58,12 +59,12 @@ class LLTextBox;
class LLTextEditor;
class LLTextureCtrl;
class LLUIImage;
-class LLViewerTextEditor;
class LLParcelSelection;
class LLPanelLandGeneral;
class LLPanelLandObjects;
class LLPanelLandOptions;
+class LLPanelLandAudio;
class LLPanelLandMedia;
class LLPanelLandAccess;
class LLPanelLandBan;
@@ -71,26 +72,27 @@ class LLPanelLandRenters;
class LLPanelLandCovenant;
class LLFloaterLand
-: public LLFloater, public LLFloaterSingleton<LLFloaterLand>
+: public LLFloater
{
- friend class LLUISingleton<LLFloaterLand, VisibilityPolicy<LLFloater> >;
+ friend class LLFloaterReg;
public:
static void refreshAll();
static LLPanelLandObjects* getCurrentPanelLandObjects();
static LLPanelLandCovenant* getCurrentPanelLandCovenant();
- // Destroys itself on close.
- virtual void onClose(bool app_quitting);
- virtual void onOpen();
+ virtual void onOpen(const LLSD& key);
virtual BOOL postBuild();
-protected:
-
+private:
// Does its own instance management, so clients not allowed
// to allocate or destroy.
LLFloaterLand(const LLSD& seed);
virtual ~LLFloaterLand();
+
+ void onVisibilityChange(const LLSD& visible);
+
+protected:
/*virtual*/ void refresh();
@@ -98,6 +100,7 @@ protected:
static void* createPanelLandCovenant(void* data);
static void* createPanelLandObjects(void* data);
static void* createPanelLandOptions(void* data);
+ static void* createPanelLandAudio(void* data);
static void* createPanelLandMedia(void* data);
static void* createPanelLandAccess(void* data);
static void* createPanelLandBan(void* data);
@@ -111,6 +114,7 @@ protected:
LLPanelLandGeneral* mPanelGeneral;
LLPanelLandObjects* mPanelObjects;
LLPanelLandOptions* mPanelOptions;
+ LLPanelLandAudio* mPanelAudio;
LLPanelLandMedia* mPanelMedia;
LLPanelLandAccess* mPanelAccess;
LLPanelLandCovenant* mPanelCovenant;
@@ -138,8 +142,7 @@ public:
void setGroup(const LLUUID& group_id);
static void onClickProfile(void*);
- static void onClickSetGroup(void*);
- static void cbGroupID(LLUUID group_id, void* userdata);
+ void onClickSetGroup();
static BOOL enableDeedToGroup(void*);
static void onClickDeed(void*);
static void onClickBuyLand(void* data);
@@ -329,7 +332,6 @@ private:
LLCheckBoxCtrl* mCheckFly;
LLCheckBoxCtrl* mCheckGroupScripts;
LLCheckBoxCtrl* mCheckOtherScripts;
- LLCheckBoxCtrl* mCheckLandmark;
LLCheckBoxCtrl* mCheckShowDirectory;
LLComboBox* mCategoryCombo;
diff --git a/indra/newview/llfloaterlandholdings.cpp b/indra/newview/llfloaterlandholdings.cpp
index bd1186b151..19552ca9c9 100644
--- a/indra/newview/llfloaterlandholdings.cpp
+++ b/indra/newview/llfloaterlandholdings.cpp
@@ -41,58 +41,32 @@
#include "message.h"
#include "llagent.h"
-#include "llbutton.h"
-#include "llfloatergroupinfo.h"
+#include "llfloaterreg.h"
#include "llfloaterworldmap.h"
#include "llproductinforequest.h"
#include "llscrolllistctrl.h"
#include "llstatusbar.h"
#include "lltextbox.h"
+#include "llscrolllistctrl.h"
+#include "llscrolllistitem.h"
+#include "llscrolllistcell.h"
#include "lltrans.h"
#include "lluiconstants.h"
#include "llviewermessage.h"
#include "lluictrlfactory.h"
-// statics
-LLFloaterLandHoldings* LLFloaterLandHoldings::sInstance = NULL;
-
-
-// static
-void LLFloaterLandHoldings::show(void*)
-{
- LLFloaterLandHoldings* floater = new LLFloaterLandHoldings();
- LLUICtrlFactory::getInstance()->buildFloater(floater, "floater_land_holdings.xml");
- floater->center();
-
- // query_id null is known to be us
- const LLUUID& query_id = LLUUID::null;
-
- // look only for parcels we own
- U32 query_flags = DFQ_AGENT_OWNED;
-
- send_places_query(query_id,
- LLUUID::null,
- "",
- query_flags,
- LLParcel::C_ANY,
- "");
-
- // TODO: request updated L$ balance?
- floater->open(); /* Flawfinder: ignore */
-}
-
+#include "llgroupactions.h"
// protected
-LLFloaterLandHoldings::LLFloaterLandHoldings()
-: LLFloater(std::string("land holdings floater")),
+LLFloaterLandHoldings::LLFloaterLandHoldings(const LLSD& key)
+: LLFloater(key),
mActualArea(0),
mBillableArea(0),
mFirstPacketReceived(FALSE),
mSortColumn(""),
mSortAscending(TRUE)
{
- // Instance management.
- sInstance = this;
+// LLUICtrlFactory::getInstance()->buildFloater(floater, "floater_land_holdings.xml");
}
BOOL LLFloaterLandHoldings::postBuild()
@@ -101,8 +75,7 @@ BOOL LLFloaterLandHoldings::postBuild()
childSetAction("Show on Map", onClickMap, this);
// Grant list
- childSetDoubleClickCallback("grant list", onGrantList);
- childSetUserData("grant list", this);
+ getChild<LLScrollListCtrl>("grant list")->setDoubleClickCallback(onGrantList, this);
LLCtrlListInterface *list = childGetListInterface("grant list");
if (!list) return TRUE;
@@ -126,7 +99,9 @@ BOOL LLFloaterLandHoldings::postBuild()
list->addElement(element, ADD_SORTED);
}
-
+
+ center();
+
return TRUE;
}
@@ -134,9 +109,23 @@ BOOL LLFloaterLandHoldings::postBuild()
// protected
LLFloaterLandHoldings::~LLFloaterLandHoldings()
{
- sInstance = NULL;
}
+void LLFloaterLandHoldings::onOpen(const LLSD& key)
+{
+ // query_id null is known to be us
+ const LLUUID& query_id = LLUUID::null;
+
+ // look only for parcels we own
+ U32 query_flags = DFQ_AGENT_OWNED;
+
+ send_places_query(query_id,
+ LLUUID::null,
+ "",
+ query_flags,
+ LLParcel::C_ANY,
+ "");
+}
void LLFloaterLandHoldings::draw()
{
@@ -166,7 +155,7 @@ void LLFloaterLandHoldings::refresh()
// static
void LLFloaterLandHoldings::processPlacesReply(LLMessageSystem* msg, void**)
{
- LLFloaterLandHoldings* self = sInstance;
+ LLFloaterLandHoldings* self = LLFloaterReg::findTypedInstance<LLFloaterLandHoldings>("land_holdings");
// Is this packet from an old, closed window?
if (!self)
@@ -222,50 +211,53 @@ void LLFloaterLandHoldings::processPlacesReply(LLMessageSystem* msg, void**)
land_type = LLTrans::getString("land_type_unknown");
}
- self->mActualArea += actual_area;
- self->mBillableArea += billable_area;
-
- S32 region_x = llround(global_x) % REGION_WIDTH_UNITS;
- S32 region_y = llround(global_y) % REGION_WIDTH_UNITS;
-
- std::string location;
- location = llformat("%s (%d, %d)", sim_name.c_str(), region_x, region_y);
-
- std::string area;
- if(billable_area == actual_area)
+ if(owner_id.notNull())
{
- area = llformat("%d", billable_area);
+ self->mActualArea += actual_area;
+ self->mBillableArea += billable_area;
+
+ S32 region_x = llround(global_x) % REGION_WIDTH_UNITS;
+ S32 region_y = llround(global_y) % REGION_WIDTH_UNITS;
+
+ std::string location;
+ location = llformat("%s (%d, %d)", sim_name.c_str(), region_x, region_y);
+
+ std::string area;
+ if(billable_area == actual_area)
+ {
+ area = llformat("%d", billable_area);
+ }
+ else
+ {
+ area = llformat("%d / %d", billable_area, actual_area);
+ }
+
+ std::string hidden;
+ hidden = llformat("%f %f", global_x, global_y);
+
+ LLSD element;
+ element["columns"][0]["column"] = "name";
+ element["columns"][0]["value"] = name;
+ element["columns"][0]["font"] = "SANSSERIF";
+
+ element["columns"][1]["column"] = "location";
+ element["columns"][1]["value"] = location;
+ element["columns"][1]["font"] = "SANSSERIF";
+
+ element["columns"][2]["column"] = "area";
+ element["columns"][2]["value"] = area;
+ element["columns"][2]["font"] = "SANSSERIF";
+
+ element["columns"][3]["column"] = "type";
+ element["columns"][3]["value"] = land_type;
+ element["columns"][3]["font"] = "SANSSERIF";
+
+ // hidden is always last column
+ element["columns"][4]["column"] = "hidden";
+ element["columns"][4]["value"] = hidden;
+
+ list->addElement(element);
}
- else
- {
- area = llformat("%d / %d", billable_area, actual_area);
- }
-
- std::string hidden;
- hidden = llformat("%f %f", global_x, global_y);
-
- LLSD element;
- element["columns"][0]["column"] = "name";
- element["columns"][0]["value"] = name;
- element["columns"][0]["font"] = "SANSSERIF";
-
- element["columns"][1]["column"] = "location";
- element["columns"][1]["value"] = location;
- element["columns"][1]["font"] = "SANSSERIF";
-
- element["columns"][2]["column"] = "area";
- element["columns"][2]["value"] = area;
- element["columns"][2]["font"] = "SANSSERIF";
-
- element["columns"][3]["column"] = "type";
- element["columns"][3]["value"] = land_type;
- element["columns"][3]["font"] = "SANSSERIF";
-
- // hidden is always last column
- element["columns"][4]["column"] = "hidden";
- element["columns"][4]["value"] = hidden;
-
- list->addElement(element);
}
self->refreshAggregates();
@@ -290,16 +282,17 @@ void LLFloaterLandHoldings::buttonCore(S32 which)
F64 global_z = gAgent.getPositionGlobal().mdV[VZ];
LLVector3d pos_global(global_x, global_y, global_z);
+ LLFloaterWorldMap* floater_world_map = LLFloaterWorldMap::getInstance();
switch(which)
{
case 0:
gAgent.teleportViaLocation(pos_global);
- gFloaterWorldMap->trackLocation(pos_global);
+ if(floater_world_map) floater_world_map->trackLocation(pos_global);
break;
case 1:
- gFloaterWorldMap->trackLocation(pos_global);
- LLFloaterWorldMap::show(NULL, TRUE);
+ if(floater_world_map) floater_world_map->trackLocation(pos_global);
+ LLFloaterReg::showInstance("world_map", "center");
break;
default:
break;
@@ -311,7 +304,7 @@ void LLFloaterLandHoldings::onClickTeleport(void* data)
{
LLFloaterLandHoldings* self = (LLFloaterLandHoldings*)data;
self->buttonCore(0);
- self->close();
+ self->closeFloater();
}
@@ -331,7 +324,7 @@ void LLFloaterLandHoldings::onGrantList(void* data)
LLUUID group_id = list->getCurrentID();
if (group_id.notNull())
{
- LLFloaterGroupInfo::showFromUUID(group_id);
+ LLGroupActions::show(group_id);
}
}
diff --git a/indra/newview/llfloaterlandholdings.h b/indra/newview/llfloaterlandholdings.h
index def77cf2a8..471ddf7f44 100644
--- a/indra/newview/llfloaterlandholdings.h
+++ b/indra/newview/llfloaterlandholdings.h
@@ -44,10 +44,11 @@ class LLFloaterLandHoldings
: public LLFloater
{
public:
- BOOL postBuild();
-
- static void show(void*);
-
+ LLFloaterLandHoldings(const LLSD& key);
+ virtual ~LLFloaterLandHoldings();
+
+ virtual BOOL postBuild();
+ virtual void onOpen(const LLSD& key);
virtual void draw();
void refresh();
@@ -63,14 +64,9 @@ public:
static void onGrantList(void* data);
protected:
- LLFloaterLandHoldings();
- virtual ~LLFloaterLandHoldings();
-
void refreshAggregates();
protected:
- static LLFloaterLandHoldings* sInstance;
-
// Sum up as packets arrive the total holdings
S32 mActualArea;
S32 mBillableArea;
diff --git a/indra/newview/llfloatermap.cpp b/indra/newview/llfloatermap.cpp
index 3b1e4c7ac7..eac1b65f7d 100644
--- a/indra/newview/llfloatermap.cpp
+++ b/indra/newview/llfloatermap.cpp
@@ -30,96 +30,188 @@
* $/LicenseInfo$
*/
+#include <string>
#include "llviewerprecompiledheaders.h"
+// self include
#include "llfloatermap.h"
+// Library includes
+#include "llfloaterreg.h"
+#include "llfontgl.h"
+#include "llglheaders.h"
+
+// Viewer includes
#include "llagent.h"
-#include "llcolorscheme.h"
#include "llviewercontrol.h"
-#include "lldraghandle.h"
#include "llnetmap.h"
-#include "llregionhandle.h"
-#include "llresizebar.h"
-#include "lluictrlfactory.h"
-
-LLFloaterMap::LLFloaterMap(const LLSD& key)
- :
- LLFloater(std::string("minimap")),
- mPanelMap(NULL)
+#include "lltracker.h"
+#include "llviewercamera.h"
+#include "lldraghandle.h"
+#include "lltextbox.h"
+#include "llviewermenu.h"
+
+//
+// Constants
+//
+const F32 MAP_SCALE_MIN = 64;
+const F32 MAP_SCALE_MID = 172;
+const F32 MAP_SCALE_MAX = 512;
+
+//
+// Member functions
+//
+
+LLFloaterMap::LLFloaterMap(const LLSD& key)
+ : LLFloater(key)
{
- LLCallbackMap::map_t factory_map;
- factory_map["mini_mapview"] = LLCallbackMap(createPanelMiniMap, this);
- LLUICtrlFactory::getInstance()->buildFloater(this, "floater_mini_map.xml", &factory_map, FALSE);
+ //Called from floater reg: LLUICtrlFactory::getInstance()->buildFloater(this, "floater_map.xml", FALSE);
}
-
-// static
-void* LLFloaterMap::createPanelMiniMap(void* data)
+LLFloaterMap::~LLFloaterMap()
{
- LLFloaterMap* self = (LLFloaterMap*)data;
- self->mPanelMap = new LLNetMap("Mapview");
- return self->mPanelMap;
}
BOOL LLFloaterMap::postBuild()
{
- // Send the drag handle to the back, but make sure close stays on top
+ mMap = getChild<LLNetMap>("Net Map");
+ mMap->setScale(gSavedSettings.getF32("MiniMapScale"));
+ mMap->setRotateMap(gSavedSettings.getBOOL( "MiniMapRotate" ));
+ mMap->setToolTipMsg(getString("ToolTipMsg"));
+ sendChildToBack(mMap);
+
+ mTextBoxNorth = getChild<LLTextBox> ("floater_map_north");
+ mTextBoxEast = getChild<LLTextBox> ("floater_map_east");
+ mTextBoxWest = getChild<LLTextBox> ("floater_map_west");
+ mTextBoxSouth = getChild<LLTextBox> ("floater_map_south");
+ mTextBoxSouthEast = getChild<LLTextBox> ("floater_map_southeast");
+ mTextBoxNorthEast = getChild<LLTextBox> ("floater_map_northeast");
+ mTextBoxSouthWest = getChild<LLTextBox> ("floater_map_southwest");
+ mTextBoxNorthWest = getChild<LLTextBox> ("floater_map_northwest");
+
+ LLUICtrl::CommitCallbackRegistry::ScopedRegistrar registrar;
+
+ registrar.add("Minimap.Zoom", boost::bind(&LLFloaterMap::handleZoom, this, _2));
+ registrar.add("Minimap.Tracker", boost::bind(&LLFloaterMap::handleStopTracking, this, _2));
+
+ mPopupMenu = LLUICtrlFactory::getInstance()->createFromFile<LLMenuGL>("menu_mini_map.xml", gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance());
+ if (mPopupMenu && !LLTracker::isTracking(0))
+ {
+ mPopupMenu->setItemEnabled ("Stop Tracking", false);
+ }
+
+ // Get the drag handle all the way in back
sendChildToBack(getDragHandle());
- sendChildToFront(getChild<LLButton>("llfloater_close_btn"));
+
setIsChrome(TRUE);
+
+ // keep onscreen
+ gFloaterView->adjustToFitScreen(this, FALSE);
+
return TRUE;
}
-
-LLFloaterMap::~LLFloaterMap()
+BOOL LLFloaterMap::handleDoubleClick( S32 x, S32 y, MASK mask )
{
+ LLFloaterReg::showInstance("world_map");
+ return TRUE;
}
+BOOL LLFloaterMap::handleRightMouseDown(S32 x, S32 y, MASK mask)
+{
+ if (mPopupMenu)
+ {
+ mPopupMenu->buildDrawLabels();
+ mPopupMenu->updateParent(LLMenuGL::sMenuContainer);
+ LLMenuGL::showPopup(this, mPopupMenu, x, y);
+ }
+ return TRUE;
+}
-// virtual
-void LLFloaterMap::onOpen()
+void LLFloaterMap::setDirectionPos( LLTextBox* text_box, F32 rotation )
{
- gFloaterView->adjustToFitScreen(this, FALSE);
+ // Rotation is in radians.
+ // Rotation of 0 means x = 1, y = 0 on the unit circle.
- gSavedSettings.setBOOL("ShowMiniMap", TRUE);
-}
+ F32 map_half_height = (F32)(getRect().getHeight() / 2);
+ F32 map_half_width = (F32)(getRect().getWidth() / 2);
+ F32 text_half_height = (F32)(text_box->getRect().getHeight() / 2);
+ F32 text_half_width = (F32)(text_box->getRect().getWidth() / 2);
+ F32 radius = llmin( map_half_height - text_half_height, map_half_width - text_half_width );
+ // Inset by a little to account for position display.
+ radius -= 8.f;
+
+ text_box->setOrigin(
+ llround(map_half_width - text_half_width + radius * cos( rotation )),
+ llround(map_half_height - text_half_height + radius * sin( rotation )) );
+}
// virtual
-void LLFloaterMap::onClose(bool app_quitting)
+void LLFloaterMap::draw()
{
- LLFloater::setVisible(FALSE);
+ F32 rotation = 0;
- if (!app_quitting)
+ if( mMap->getRotateMap() )
{
- gSavedSettings.setBOOL("ShowMiniMap", FALSE);
+ // rotate subsequent draws to agent rotation
+ rotation = atan2( LLViewerCamera::getInstance()->getAtAxis().mV[VX], LLViewerCamera::getInstance()->getAtAxis().mV[VY] );
}
-}
-BOOL LLFloaterMap::canClose()
-{
- return !LLApp::isExiting();
-}
+ setDirectionPos( mTextBoxEast, rotation );
+ setDirectionPos( mTextBoxNorth, rotation + F_PI_BY_TWO );
+ setDirectionPos( mTextBoxWest, rotation + F_PI );
+ setDirectionPos( mTextBoxSouth, rotation + F_PI + F_PI_BY_TWO );
+ setDirectionPos( mTextBoxNorthEast, rotation + F_PI_BY_TWO / 2);
+ setDirectionPos( mTextBoxNorthWest, rotation + F_PI_BY_TWO + F_PI_BY_TWO / 2);
+ setDirectionPos( mTextBoxSouthWest, rotation + F_PI + F_PI_BY_TWO / 2);
+ setDirectionPos( mTextBoxSouthEast, rotation + F_PI + F_PI_BY_TWO + F_PI_BY_TWO / 2);
-// virtual
-void LLFloaterMap::draw()
-{
// Note: we can't just gAgent.check cameraMouselook() because the transition states are wrong.
if( gAgent.cameraMouselook())
{
setMouseOpaque(FALSE);
getDragHandle()->setMouseOpaque(FALSE);
-
- drawChild(mPanelMap);
}
else
{
setMouseOpaque(TRUE);
getDragHandle()->setMouseOpaque(TRUE);
+ }
+
+ if (LLTracker::isTracking(0))
+ {
+ mPopupMenu->setItemEnabled ("Stop Tracking", true);
+ }
+
+ LLFloater::draw();
+}
+
+void LLFloaterMap::handleZoom(const LLSD& userdata)
+{
+ std::string level = userdata.asString();
+
+ F32 scale = 0.0f;
+ if (level == std::string("close"))
+ scale = MAP_SCALE_MAX;
+ else if (level == std::string("medium"))
+ scale = MAP_SCALE_MID;
+ else if (level == std::string("far"))
+ scale = MAP_SCALE_MIN;
+ if (scale != 0.0f)
+ {
+ gSavedSettings.setF32("MiniMapScale", scale );
+ mMap->setScale(scale);
+ }
+}
- LLFloater::draw();
+void LLFloaterMap::handleStopTracking (const LLSD& userdata)
+{
+ if (mPopupMenu)
+ {
+ mPopupMenu->setItemEnabled ("Stop Tracking", false);
+ LLTracker::stopTracking ((void*)LLTracker::isTracking(NULL));
}
}
diff --git a/indra/newview/llfloatermap.h b/indra/newview/llfloatermap.h
index ec2db27f7a..501777ed07 100644
--- a/indra/newview/llfloatermap.h
+++ b/indra/newview/llfloatermap.h
@@ -35,28 +35,42 @@
#include "llfloater.h"
+class LLMenuGL;
class LLNetMap;
+class LLTextBox;
-class LLFloaterMap :
- public LLFloater,
- public LLFloaterSingleton<LLFloaterMap>
+//
+// Classes
+//
+class LLFloaterMap : public LLFloater
{
- friend class LLUISingleton<LLFloaterMap, VisibilityPolicy<LLFloater> >;
public:
+ LLFloaterMap(const LLSD& key);
virtual ~LLFloaterMap();
-
- static void* createPanelMiniMap(void* data);
-
- BOOL postBuild();
-
+
+ /*virtual*/ BOOL postBuild();
+ /*virtual*/ BOOL handleDoubleClick( S32 x, S32 y, MASK mask );
+ /*virtual*/ BOOL handleRightMouseDown( S32 x, S32 y, MASK mask );
/*virtual*/ void draw();
- /*virtual*/ void onOpen();
- /*virtual*/ void onClose(bool app_quitting);
- /*virtual*/ BOOL canClose();
-
+
private:
- LLFloaterMap(const LLSD& key = LLSD());
- LLNetMap* mPanelMap;
+ void handleZoom(const LLSD& userdata);
+ void handleStopTracking (const LLSD& userdata);
+ void setDirectionPos( LLTextBox* text_box, F32 rotation );
+
+ LLMenuGL* mPopupMenu;
+
+ LLTextBox* mTextBoxEast;
+ LLTextBox* mTextBoxNorth;
+ LLTextBox* mTextBoxWest;
+ LLTextBox* mTextBoxSouth;
+
+ LLTextBox* mTextBoxSouthEast;
+ LLTextBox* mTextBoxNorthEast;
+ LLTextBox* mTextBoxNorthWest;
+ LLTextBox* mTextBoxSouthWest;
+
+ LLNetMap* mMap;
};
#endif // LL_LLFLOATERMAP_H
diff --git a/indra/newview/llfloatermediabrowser.cpp b/indra/newview/llfloatermediabrowser.cpp
new file mode 100644
index 0000000000..c580cdef8a
--- /dev/null
+++ b/indra/newview/llfloatermediabrowser.cpp
@@ -0,0 +1,398 @@
+/**
+ * @file llfloaterhtmlhelp.cpp
+ * @brief HTML Help floater - uses embedded web browser control
+ *
+ * $LicenseInfo:firstyear=2006&license=viewergpl$
+ *
+ * Copyright (c) 2006-2009, Linden Research, Inc.
+ *
+ * Second Life Viewer Source Code
+ * The source code in this file ("Source Code") is provided by Linden Lab
+ * to you under the terms of the GNU General Public License, version 2.0
+ * ("GPL"), unless you have obtained a separate licensing agreement
+ * ("Other License"), formally executed by you and Linden Lab. Terms of
+ * the GPL can be found in doc/GPL-license.txt in this distribution, or
+ * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
+ *
+ * There are special exceptions to the terms and conditions of the GPL as
+ * it is applied to this Source Code. View the full text of the exception
+ * in the file doc/FLOSS-exception.txt in this software distribution, or
+ * online at
+ * http://secondlifegrid.net/programs/open_source/licensing/flossexception
+ *
+ * By copying, modifying or distributing this software, you acknowledge
+ * that you have read and understood your obligations described above,
+ * and agree to abide by those obligations.
+ *
+ * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+ * COMPLETENESS OR PERFORMANCE.
+ * $/LicenseInfo$
+ */
+
+#include "llviewerprecompiledheaders.h"
+
+#include "llfloatermediabrowser.h"
+#include "llfloaterhtml.h"
+
+#include "llfloaterreg.h"
+#include "llparcel.h"
+#include "llpluginclassmedia.h"
+#include "lluictrlfactory.h"
+#include "llmediactrl.h"
+#include "llviewerwindow.h"
+#include "llviewercontrol.h"
+#include "llviewerparcelmgr.h"
+#include "llweb.h"
+#include "llui.h"
+#include "roles_constants.h"
+
+#include "llurlhistory.h"
+#include "llmediactrl.h"
+#include "llviewermedia.h"
+#include "llviewerparcelmedia.h"
+#include "llcombobox.h"
+
+
+// TEMP
+#include "llsdutil.h"
+
+LLFloaterMediaBrowser::LLFloaterMediaBrowser(const LLSD& key)
+ : LLFloater(key)
+{
+// LLUICtrlFactory::getInstance()->buildFloater(this, "floater_media_browser.xml");
+
+}
+
+void LLFloaterMediaBrowser::draw()
+{
+ childSetEnabled("go", !mAddressCombo->getValue().asString().empty());
+ LLParcel* parcel = LLViewerParcelMgr::getInstance()->getAgentParcel();
+ if(parcel)
+ {
+ childSetVisible("parcel_owner_controls", LLViewerParcelMgr::isParcelModifiableByAgent(parcel, GP_LAND_CHANGE_MEDIA));
+ childSetEnabled("assign", !mAddressCombo->getValue().asString().empty());
+ }
+ bool show_time_controls = false;
+ bool media_playing = false;
+ if(mBrowser)
+ {
+ LLPluginClassMedia* media_plugin = mBrowser->getMediaPlugin();
+ if(media_plugin)
+ {
+ show_time_controls = media_plugin->pluginSupportsMediaTime();
+ media_playing = media_plugin->getStatus() == LLPluginClassMediaOwner::MEDIA_PLAYING;
+ }
+ }
+ childSetVisible("rewind", show_time_controls);
+ childSetVisible("play", show_time_controls && ! media_playing);
+ childSetVisible("pause", show_time_controls && media_playing);
+ childSetVisible("stop", show_time_controls);
+ childSetVisible("seek", show_time_controls);
+
+ childSetEnabled("play", ! media_playing);
+ childSetEnabled("stop", media_playing);
+
+ childSetEnabled("back", mBrowser->canNavigateBack());
+ childSetEnabled("forward", mBrowser->canNavigateForward());
+
+ LLFloater::draw();
+}
+
+BOOL LLFloaterMediaBrowser::postBuild()
+{
+ mBrowser = getChild<LLMediaCtrl>("browser");
+ mBrowser->addObserver(this);
+
+ mAddressCombo = getChild<LLComboBox>("address");
+ mAddressCombo->setCommitCallback(onEnterAddress, this);
+
+ childSetAction("back", onClickBack, this);
+ childSetAction("forward", onClickForward, this);
+ childSetAction("reload", onClickRefresh, this);
+ childSetAction("rewind", onClickRewind, this);
+ childSetAction("play", onClickPlay, this);
+ childSetAction("stop", onClickStop, this);
+ childSetAction("pause", onClickPlay, this);
+ childSetAction("seek", onClickSeek, this);
+ childSetAction("go", onClickGo, this);
+ childSetAction("close", onClickClose, this);
+ childSetAction("open_browser", onClickOpenWebBrowser, this);
+ childSetAction("assign", onClickAssign, this);
+
+ buildURLHistory();
+ return TRUE;
+}
+
+void LLFloaterMediaBrowser::buildURLHistory()
+{
+ LLCtrlListInterface* url_list = childGetListInterface("address");
+ if (url_list)
+ {
+ url_list->operateOnAll(LLCtrlListInterface::OP_DELETE);
+ }
+
+ // Get all of the entries in the "browser" collection
+ LLSD browser_history = LLURLHistory::getURLHistory("browser");
+
+ LLSD::array_iterator iter_history =
+ browser_history.beginArray();
+ LLSD::array_iterator end_history =
+ browser_history.endArray();
+ for(; iter_history != end_history; ++iter_history)
+ {
+ std::string url = (*iter_history).asString();
+ if(! url.empty())
+ url_list->addSimpleElement(url);
+ }
+
+ // initialize URL history in the plugin
+ mBrowser->getMediaPlugin()->initializeUrlHistory(browser_history);
+}
+
+std::string LLFloaterMediaBrowser::getSupportURL()
+{
+ return getString("support_page_url");
+}
+void LLFloaterMediaBrowser::onClose(bool app_quitting)
+{
+ //setVisible(FALSE);
+ destroy();
+}
+
+void LLFloaterMediaBrowser::handleMediaEvent(LLPluginClassMedia* self, EMediaEvent event)
+{
+ if(event == MEDIA_EVENT_LOCATION_CHANGED)
+ {
+ setCurrentURL(self->getLocation());
+ }
+ else if(event == MEDIA_EVENT_NAVIGATE_COMPLETE)
+ {
+ // This is the event these flags are sent with.
+ childSetEnabled("back", self->getHistoryBackAvailable());
+ childSetEnabled("forward", self->getHistoryForwardAvailable());
+ }
+}
+void LLFloaterMediaBrowser::setCurrentURL(const std::string& url)
+{
+ mCurrentURL = url;
+
+ // redirects will navigate momentarily to about:blank, don't add to history
+ if (mCurrentURL != "about:blank")
+ {
+ mAddressCombo->remove(mCurrentURL);
+ mAddressCombo->add(mCurrentURL, ADD_SORTED);
+ mAddressCombo->selectByValue(mCurrentURL);
+
+ // Serialize url history
+ LLURLHistory::removeURL("browser", mCurrentURL);
+ LLURLHistory::addURL("browser", mCurrentURL);
+ }
+ childSetEnabled("back", mBrowser->canNavigateBack());
+ childSetEnabled("forward", mBrowser->canNavigateForward());
+ childSetEnabled("reload", TRUE);
+}
+
+void LLFloaterMediaBrowser::onOpen(const LLSD& media_url)
+{
+ LLFloater::onOpen(media_url);
+ openMedia(media_url.asString());
+}
+
+//static
+void LLFloaterMediaBrowser::onEnterAddress(LLUICtrl* ctrl, void* user_data)
+{
+ LLFloaterMediaBrowser* self = (LLFloaterMediaBrowser*)user_data;
+ self->mBrowser->navigateTo(self->mAddressCombo->getValue().asString());
+}
+
+//static
+void LLFloaterMediaBrowser::onClickRefresh(void* user_data)
+{
+ LLFloaterMediaBrowser* self = (LLFloaterMediaBrowser*)user_data;
+
+ self->mAddressCombo->remove(0);
+ self->mBrowser->navigateTo(self->mCurrentURL);
+}
+
+//static
+void LLFloaterMediaBrowser::onClickForward(void* user_data)
+{
+ LLFloaterMediaBrowser* self = (LLFloaterMediaBrowser*)user_data;
+
+ self->mBrowser->navigateForward();
+}
+
+//static
+void LLFloaterMediaBrowser::onClickBack(void* user_data)
+{
+ LLFloaterMediaBrowser* self = (LLFloaterMediaBrowser*)user_data;
+
+ self->mBrowser->navigateBack();
+}
+
+//static
+void LLFloaterMediaBrowser::onClickGo(void* user_data)
+{
+ LLFloaterMediaBrowser* self = (LLFloaterMediaBrowser*)user_data;
+
+ self->mBrowser->navigateTo(self->mAddressCombo->getValue().asString());
+}
+
+//static
+void LLFloaterMediaBrowser::onClickClose(void* user_data)
+{
+ LLFloaterMediaBrowser* self = (LLFloaterMediaBrowser*)user_data;
+
+ self->closeFloater();
+}
+
+//static
+void LLFloaterMediaBrowser::onClickOpenWebBrowser(void* user_data)
+{
+ LLFloaterMediaBrowser* self = (LLFloaterMediaBrowser*)user_data;
+
+ std::string url = self->mCurrentURL.empty() ?
+ self->mBrowser->getHomePageUrl() :
+ self->mCurrentURL;
+ LLWeb::loadURLExternal(url);
+}
+
+void LLFloaterMediaBrowser::onClickAssign(void* user_data)
+{
+ LLFloaterMediaBrowser* self = (LLFloaterMediaBrowser*)user_data;
+
+ LLParcel* parcel = LLViewerParcelMgr::getInstance()->getAgentParcel();
+ if (!parcel)
+ {
+ return;
+ }
+ std::string media_url = self->mAddressCombo->getValue().asString();
+ LLStringUtil::trim(media_url);
+
+ if(parcel->getMediaType() != "text/html")
+ {
+ parcel->setMediaURL(media_url);
+ parcel->setMediaCurrentURL(media_url);
+ parcel->setMediaType(std::string("text/html"));
+ LLViewerParcelMgr::getInstance()->sendParcelPropertiesUpdate( parcel, true );
+ LLViewerParcelMedia::sendMediaNavigateMessage(media_url);
+ LLViewerParcelMedia::stop();
+ // LLViewerParcelMedia::update( parcel );
+ }
+ LLViewerParcelMedia::sendMediaNavigateMessage(media_url);
+}
+//static
+void LLFloaterMediaBrowser::onClickRewind(void* user_data)
+{
+ LLFloaterMediaBrowser* self = (LLFloaterMediaBrowser*)user_data;
+
+ if(self->mBrowser->getMediaPlugin())
+ self->mBrowser->getMediaPlugin()->start(-2.0f);
+}
+//static
+void LLFloaterMediaBrowser::onClickPlay(void* user_data)
+{
+ LLFloaterMediaBrowser* self = (LLFloaterMediaBrowser*)user_data;
+
+ LLPluginClassMedia* plugin = self->mBrowser->getMediaPlugin();
+ if(plugin)
+ {
+ if(plugin->getStatus() == LLPluginClassMediaOwner::MEDIA_PLAYING)
+ {
+ plugin->pause();
+ }
+ else
+ {
+ plugin->start();
+ }
+ }
+}
+//static
+void LLFloaterMediaBrowser::onClickStop(void* user_data)
+{
+ LLFloaterMediaBrowser* self = (LLFloaterMediaBrowser*)user_data;
+
+ if(self->mBrowser->getMediaPlugin())
+ self->mBrowser->getMediaPlugin()->stop();
+}
+//static
+void LLFloaterMediaBrowser::onClickSeek(void* user_data)
+{
+ LLFloaterMediaBrowser* self = (LLFloaterMediaBrowser*)user_data;
+
+ if(self->mBrowser->getMediaPlugin())
+ self->mBrowser->getMediaPlugin()->start(2.0f);
+}
+void LLFloaterMediaBrowser::openMedia(const std::string& media_url)
+{
+ mBrowser->setHomePageUrl(media_url);
+ mBrowser->navigateTo(media_url);
+ setCurrentURL(media_url);
+}
+////////////////////////////////////////////////////////////////////////////////
+//
+
+LLViewerHtmlHelp gViewerHtmlHelp;
+
+
+////////////////////////////////////////////////////////////////////////////////
+//
+LLViewerHtmlHelp::LLViewerHtmlHelp()
+{
+
+ LLUI::setHtmlHelp(this);
+}
+
+LLViewerHtmlHelp::~LLViewerHtmlHelp()
+{
+
+ LLUI::setHtmlHelp(NULL);
+}
+
+void LLViewerHtmlHelp::show()
+{
+ show("");
+}
+
+void LLViewerHtmlHelp::show(std::string url)
+{
+ LLFloaterMediaBrowser* floater_html = dynamic_cast<LLFloaterMediaBrowser*>(LLFloaterReg::getInstance("media_browser"));
+ floater_html->setVisible(FALSE);
+
+ if (url.empty())
+ {
+ url = floater_html->getSupportURL();
+ }
+
+ if (gSavedSettings.getBOOL("UseExternalBrowser"))
+ {
+ LLSD notificationData;
+ notificationData["url"] = url;
+
+ LLNotifications::instance().add("ClickOpenF1Help", notificationData, LLSD(), onClickF1HelpLoadURL);
+ floater_html->closeFloater();
+ }
+ else
+ {
+ // don't wait, just do it
+ floater_html->setVisible(TRUE);
+ floater_html->openMedia(url);
+ }
+}
+
+// static
+bool LLViewerHtmlHelp::onClickF1HelpLoadURL(const LLSD& notification, const LLSD& response)
+{
+ LLFloaterMediaBrowser* floater_html = dynamic_cast<LLFloaterMediaBrowser*>(LLFloaterReg::getInstance("media_browser"));
+ floater_html->setVisible(FALSE);
+ std::string url = floater_html->getSupportURL();
+ S32 option = LLNotification::getSelectedOption(notification, response);
+ if (option == 0)
+ {
+ LLWeb::loadURL(url);
+ }
+ floater_html->closeFloater();
+ return false;
+}
+
diff --git a/indra/newview/llfloatermediabrowser.h b/indra/newview/llfloatermediabrowser.h
new file mode 100644
index 0000000000..76e8b517a0
--- /dev/null
+++ b/indra/newview/llfloatermediabrowser.h
@@ -0,0 +1,99 @@
+/**
+ * @file llfloatermediabrowser.h
+ * @brief HTML Help floater - uses embedded web browser control
+ *
+ * $LicenseInfo:firstyear=2006&license=viewergpl$
+ *
+ * Copyright (c) 2006-2009, Linden Research, Inc.
+ *
+ * Second Life Viewer Source Code
+ * The source code in this file ("Source Code") is provided by Linden Lab
+ * to you under the terms of the GNU General Public License, version 2.0
+ * ("GPL"), unless you have obtained a separate licensing agreement
+ * ("Other License"), formally executed by you and Linden Lab. Terms of
+ * the GPL can be found in doc/GPL-license.txt in this distribution, or
+ * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
+ *
+ * There are special exceptions to the terms and conditions of the GPL as
+ * it is applied to this Source Code. View the full text of the exception
+ * in the file doc/FLOSS-exception.txt in this software distribution, or
+ * online at
+ * http://secondlifegrid.net/programs/open_source/licensing/flossexception
+ *
+ * By copying, modifying or distributing this software, you acknowledge
+ * that you have read and understood your obligations described above,
+ * and agree to abide by those obligations.
+ *
+ * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+ * COMPLETENESS OR PERFORMANCE.
+ * $/LicenseInfo$
+ */
+
+#ifndef LL_LLFLOATERMEDIABROWSER_H
+#define LL_LLFLOATERMEDIABROWSER_H
+
+#include "llhtmlhelp.h"
+#include "llfloater.h"
+#include "llmediactrl.h"
+
+class LLViewerHtmlHelp : public LLHtmlHelp
+{
+public:
+ LLViewerHtmlHelp();
+ virtual ~LLViewerHtmlHelp();
+
+ /*virtual*/ void show();
+ /*virtual*/ void show(std::string start_url);
+ void show(std::string start_url, std::string title);
+
+ static bool onClickF1HelpLoadURL(const LLSD& notification, const LLSD& response);
+
+};
+
+class LLComboBox;
+class LLMediaCtrl;
+
+class LLFloaterMediaBrowser :
+ public LLFloater,
+ public LLViewerMediaObserver
+{
+public:
+ LLFloaterMediaBrowser(const LLSD& key);
+
+ /*virtual*/ BOOL postBuild();
+ /*virtual*/ void onClose(bool app_quitting);
+ /*virtual*/ void draw();
+ /*virtual*/ void onOpen(const LLSD& key);
+
+ // inherited from LLViewerMediaObserver
+ /*virtual*/ void handleMediaEvent(LLPluginClassMedia* self, EMediaEvent event);
+
+ void openMedia(const std::string& media_url);
+ void buildURLHistory();
+ std::string getSupportURL();
+ void setCurrentURL(const std::string& url);
+
+ static void onEnterAddress(LLUICtrl* ctrl, void* user_data);
+ static void onClickRefresh(void* user_data);
+ static void onClickBack(void* user_data);
+ static void onClickForward(void* user_data);
+ static void onClickGo(void* user_data);
+ static void onClickClose(void* user_data);
+ static void onClickOpenWebBrowser(void* user_data);
+ static void onClickAssign(void* user_data);
+ static void onClickRewind(void* user_data);
+ static void onClickPlay(void* user_data);
+ static void onClickStop(void* user_data);
+ static void onClickSeek(void* user_data);
+
+private:
+ LLMediaCtrl* mBrowser;
+ LLComboBox* mAddressCombo;
+ std::string mCurrentURL;
+};
+
+extern LLViewerHtmlHelp gViewerHtmlHelp;
+
+#endif // LL_LLFLOATERMEDIABROWSER_H
+
diff --git a/indra/newview/llfloatermemleak.cpp b/indra/newview/llfloatermemleak.cpp
index df51918e35..529bd68e03 100644
--- a/indra/newview/llfloatermemleak.cpp
+++ b/indra/newview/llfloatermemleak.cpp
@@ -42,24 +42,56 @@
#include "llmath.h"
#include "llviewerwindow.h"
-LLFloaterMemLeak* LLFloaterMemLeak::sInstance = NULL;
U32 LLFloaterMemLeak::sMemLeakingSpeed = 0 ; //bytes leaked per frame
U32 LLFloaterMemLeak::sMaxLeakedMem = 0 ; //maximum allowed leaked memory
U32 LLFloaterMemLeak::sTotalLeaked = 0 ;
S32 LLFloaterMemLeak::sStatus = LLFloaterMemLeak::STOP ;
BOOL LLFloaterMemLeak::sbAllocationFailed = FALSE ;
-LLFloaterMemLeak::LLFloaterMemLeak() : LLFloater("Memory Leaking Simulation Floater")
+LLFloaterMemLeak::LLFloaterMemLeak(const LLSD& key)
+ : LLFloater(key)
{
+ setTitle("Memory Leaking Simulation Floater");
+ mCommitCallbackRegistrar.add("MemLeak.ChangeLeakingSpeed", boost::bind(&LLFloaterMemLeak::onChangeLeakingSpeed, this));
+ mCommitCallbackRegistrar.add("MemLeak.ChangeMaxMemLeaking", boost::bind(&LLFloaterMemLeak::onChangeMaxMemLeaking, this));
+ mCommitCallbackRegistrar.add("MemLeak.Start", boost::bind(&LLFloaterMemLeak::onClickStart, this));
+ mCommitCallbackRegistrar.add("MemLeak.Stop", boost::bind(&LLFloaterMemLeak::onClickStop, this));
+ mCommitCallbackRegistrar.add("MemLeak.Release", boost::bind(&LLFloaterMemLeak::onClickRelease, this));
+ mCommitCallbackRegistrar.add("MemLeak.Close", boost::bind(&LLFloaterMemLeak::onClickClose, this));
}
+//----------------------------------------------
+BOOL LLFloaterMemLeak::postBuild(void)
+{
+ F32 a, b ;
+ a = childGetValue("leak_speed").asReal();
+ if(a > (F32)(0xFFFFFFFF))
+ {
+ sMemLeakingSpeed = 0xFFFFFFFF ;
+ }
+ else
+ {
+ sMemLeakingSpeed = (U32)a ;
+ }
+ b = childGetValue("max_leak").asReal();
+ if(b > (F32)0xFFF)
+ {
+ sMaxLeakedMem = 0xFFFFFFFF ;
+ }
+ else
+ {
+ sMaxLeakedMem = ((U32)b) << 20 ;
+ }
+
+ sbAllocationFailed = FALSE ;
+ return TRUE ;
+}
LLFloaterMemLeak::~LLFloaterMemLeak()
{
release() ;
sMemLeakingSpeed = 0 ; //bytes leaked per frame
sMaxLeakedMem = 0 ; //maximum allowed leaked memory
- sInstance = NULL ;
}
void LLFloaterMemLeak::release()
@@ -115,79 +147,56 @@ void LLFloaterMemLeak::idle()
}
//----------------------
-void LLFloaterMemLeak::onChangeLeakingSpeed(LLUICtrl* ctrl, void* userData)
+void LLFloaterMemLeak::onChangeLeakingSpeed()
{
- LLFloaterMemLeak *mem_leak = (LLFloaterMemLeak *)userData;
- if (mem_leak)
- {
- F32 tmp ;
- tmp = mem_leak->childGetValue("leak_speed").asReal();
+ F32 tmp ;
+ tmp =childGetValue("leak_speed").asReal();
- if(tmp > (F32)0xFFFFFFFF)
- {
- sMemLeakingSpeed = 0xFFFFFFFF ;
- }
- else
- {
- sMemLeakingSpeed = (U32)tmp ;
- }
+ if(tmp > (F32)0xFFFFFFFF)
+ {
+ sMemLeakingSpeed = 0xFFFFFFFF ;
}
+ else
+ {
+ sMemLeakingSpeed = (U32)tmp ;
+ }
+
}
-void LLFloaterMemLeak::onChangeMaxMemLeaking(LLUICtrl* ctrl, void* userData)
+void LLFloaterMemLeak::onChangeMaxMemLeaking()
{
- LLFloaterMemLeak *mem_leak = (LLFloaterMemLeak *)userData;
- if (mem_leak)
+
+ F32 tmp ;
+ tmp =childGetValue("max_leak").asReal();
+ if(tmp > (F32)0xFFF)
{
- F32 tmp ;
- tmp = mem_leak->childGetValue("max_leak").asReal();
- if(tmp > (F32)0xFFF)
- {
- sMaxLeakedMem = 0xFFFFFFFF ;
- }
- else
- {
- sMaxLeakedMem = ((U32)tmp) << 20 ;
- }
+ sMaxLeakedMem = 0xFFFFFFFF ;
}
+ else
+ {
+ sMaxLeakedMem = ((U32)tmp) << 20 ;
+ }
+
}
-void LLFloaterMemLeak::onClickStart(void* userData)
+void LLFloaterMemLeak::onClickStart()
{
sStatus = START ;
}
-void LLFloaterMemLeak::onClickStop(void* userData)
+void LLFloaterMemLeak::onClickStop()
{
sStatus = STOP ;
}
-void LLFloaterMemLeak::onClickRelease(void* userData)
+void LLFloaterMemLeak::onClickRelease()
{
sStatus = RELEASE ;
}
-void LLFloaterMemLeak::onClickClose(void* userData)
-{
- if (sInstance)
- {
- sInstance->setVisible(FALSE);
- }
-}
-
-//----------------------------------------------
-
-BOOL LLFloaterMemLeak::postBuild(void)
+void LLFloaterMemLeak::onClickClose()
{
- childSetCommitCallback("leak_speed", onChangeLeakingSpeed, this);
- childSetCommitCallback("max_leak", onChangeMaxMemLeaking, this);
-
- childSetAction("start_btn", onClickStart, this);
- childSetAction("stop_btn", onClickStop, this);
- childSetAction("release_btn", onClickRelease, this);
- childSetAction("close_btn", onClickClose, this);
-
- return TRUE ;
+ setVisible(FALSE);
}
void LLFloaterMemLeak::draw()
@@ -217,50 +226,3 @@ void LLFloaterMemLeak::draw()
LLFloater::draw();
}
-
-// static instance of it
-LLFloaterMemLeak* LLFloaterMemLeak::instance()
-{
- if (!sInstance)
- {
- sInstance = new LLFloaterMemLeak();
- LLUICtrlFactory::getInstance()->buildFloater(sInstance, "floater_mem_leaking.xml", NULL, FALSE);
-
- if(sInstance)
- {
- F32 a, b ;
- a = sInstance->childGetValue("leak_speed").asReal();
- if(a > (F32)(0xFFFFFFFF))
- {
- sMemLeakingSpeed = 0xFFFFFFFF ;
- }
- else
- {
- sMemLeakingSpeed = (U32)a ;
- }
- b = sInstance->childGetValue("max_leak").asReal();
- if(b > (F32)0xFFF)
- {
- sMaxLeakedMem = 0xFFFFFFFF ;
- }
- else
- {
- sMaxLeakedMem = ((U32)b) << 20 ;
- }
-
- sbAllocationFailed = FALSE ;
- }
- }
- return sInstance ;
-}
-
-void LLFloaterMemLeak::show(void*)
-{
- instance()->open();
-}
-
-LLFloaterMemLeak* LLFloaterMemLeak::getInstance()
-{
- return sInstance ;
-}
-
diff --git a/indra/newview/llfloatermemleak.h b/indra/newview/llfloatermemleak.h
index 7d9d5f9c5f..763af943ba 100644
--- a/indra/newview/llfloatermemleak.h
+++ b/indra/newview/llfloatermemleak.h
@@ -37,34 +37,28 @@
class LLFloaterMemLeak : public LLFloater
{
+ friend class LLFloaterReg;
public:
- LLFloaterMemLeak();
- virtual ~LLFloaterMemLeak();
-
/// initialize all the callbacks for the menu
- //void initCallbacks(void);
+
virtual BOOL postBuild() ;
virtual void draw() ;
-
- /// one and one instance only
- static LLFloaterMemLeak* instance();
- static void onChangeLeakingSpeed(LLUICtrl* ctrl, void* userData);
- static void onChangeMaxMemLeaking(LLUICtrl* ctrl, void* userData);
- static void onClickStart(void* userData);
- static void onClickStop(void* userData);
- static void onClickRelease(void* userData);
- static void onClickClose(void* userData);
-
- /// show off our menu
- static void show(void*);
+ void onChangeLeakingSpeed();
+ void onChangeMaxMemLeaking();
+ void onClickStart();
+ void onClickStop();
+ void onClickRelease();
+ void onClickClose();
public:
- static LLFloaterMemLeak* getInstance() ;
void idle() ;
void stop() ;
private:
+
+ LLFloaterMemLeak(const LLSD& key);
+ virtual ~LLFloaterMemLeak();
void release() ;
private:
@@ -75,9 +69,6 @@ private:
START
} ;
- // one instance on the inside
- static LLFloaterMemLeak* sInstance;
-
static U32 sMemLeakingSpeed ; //bytes leaked per frame
static U32 sMaxLeakedMem ; //maximum allowed leaked memory
static U32 sTotalLeaked ;
diff --git a/indra/newview/llfloaternamedesc.cpp b/indra/newview/llfloaternamedesc.cpp
index acfcfab445..ed7d2c71ea 100644
--- a/indra/newview/llfloaternamedesc.cpp
+++ b/indra/newview/llfloaternamedesc.cpp
@@ -41,6 +41,7 @@
#include "llbutton.h"
#include "llviewerwindow.h"
#include "llfocusmgr.h"
+#include "llrootview.h"
#include "llradiogroup.h"
#include "lldbstrings.h"
#include "lldir.h"
@@ -68,14 +69,12 @@ const S32 PREF_BUTTON_HEIGHT = 16;
//-----------------------------------------------------------------------------
// LLFloaterNameDesc()
//-----------------------------------------------------------------------------
-LLFloaterNameDesc::LLFloaterNameDesc(const std::string& filename )
- : LLFloater(std::string("Name/Description Floater"))
+LLFloaterNameDesc::LLFloaterNameDesc(const LLSD& filename )
+ : LLFloater(filename),
+ mIsAudio(FALSE)
{
- mFilenameAndPath = filename;
- mFilename = gDirUtilp->getBaseFileName(filename, false);
- // SL-5521 Maintain capitalization of filename when making the inventory item. JC
- //LLStringUtil::toLower(mFilename);
- mIsAudio = FALSE;
+ mFilenameAndPath = filename.asString();
+ mFilename = gDirUtilp->getBaseFileName(mFilenameAndPath, false);
}
//-----------------------------------------------------------------------------
@@ -91,11 +90,6 @@ BOOL LLFloaterNameDesc::postBuild()
LLStringUtil::stripNonprintable(asset_name);
LLStringUtil::trim(asset_name);
- std::string exten = gDirUtilp->getExtension(asset_name);
- if (exten == "wav")
- {
- mIsAudio = TRUE;
- }
asset_name = gDirUtilp->getBaseFileName(asset_name, true); // no extsntion
setTitle(mFilename);
@@ -110,7 +104,7 @@ BOOL LLFloaterNameDesc::postBuild()
r.setLeftTopAndSize( PREVIEW_HPAD, y, line_width, PREVIEW_LINE_HEIGHT );
- childSetCommitCallback("name_form", doCommit, this);
+ getChild<LLUICtrl>("name_form")->setCommitCallback(boost::bind(&LLFloaterNameDesc::doCommit, this));
childSetValue("name_form", LLSD(asset_name));
LLLineEditor *NameEditor = getChild<LLLineEditor>("name_form");
@@ -124,7 +118,7 @@ BOOL LLFloaterNameDesc::postBuild()
y -= PREVIEW_LINE_HEIGHT;
r.setLeftTopAndSize( PREVIEW_HPAD, y, line_width, PREVIEW_LINE_HEIGHT );
- childSetCommitCallback("description_form", doCommit, this);
+ getChild<LLUICtrl>("description_form")->setCommitCallback(boost::bind(&LLFloaterNameDesc::doCommit, this));
LLLineEditor *DescEditor = getChild<LLLineEditor>("description_form");
if (DescEditor)
{
@@ -135,12 +129,12 @@ BOOL LLFloaterNameDesc::postBuild()
y -= llfloor(PREVIEW_LINE_HEIGHT * 1.2f);
// Cancel button
- childSetAction("cancel_btn", onBtnCancel, this);
+ getChild<LLUICtrl>("cancel_btn")->setCommitCallback(boost::bind(&LLFloaterNameDesc::onBtnCancel, this));
- // OK button
- childSetAction("ok_btn", onBtnOK, this);
+ childSetLabelArg("ok_btn", "[AMOUNT]", llformat("%d", LLGlobalEconomy::Singleton::getInstance()->getPriceUpload() ));
+
setDefaultBtn("ok_btn");
-
+
return TRUE;
}
@@ -160,45 +154,59 @@ void LLFloaterNameDesc::onCommit()
{
}
-// static
//-----------------------------------------------------------------------------
// onCommit()
//-----------------------------------------------------------------------------
-void LLFloaterNameDesc::doCommit( class LLUICtrl *, void* userdata )
+void LLFloaterNameDesc::doCommit()
{
- LLFloaterNameDesc* self = (LLFloaterNameDesc*) userdata;
- self->onCommit();
+ onCommit();
}
-// static
//-----------------------------------------------------------------------------
// onBtnOK()
//-----------------------------------------------------------------------------
-void LLFloaterNameDesc::onBtnOK( void* userdata )
+void LLFloaterNameDesc::onBtnOK( )
{
- LLFloaterNameDesc *fp =(LLFloaterNameDesc *)userdata;
-
- fp->childDisable("ok_btn"); // don't allow inadvertent extra uploads
+ childDisable("ok_btn"); // don't allow inadvertent extra uploads
LLAssetStorage::LLStoreAssetCallback callback = NULL;
S32 expected_upload_cost = LLGlobalEconomy::Singleton::getInstance()->getPriceUpload(); // kinda hack - assumes that unsubclassed LLFloaterNameDesc is only used for uploading chargeable assets, which it is right now (it's only used unsubclassed for the sound upload dialog, and THAT should be a subclass).
void *nruserdata = NULL;
std::string display_name = LLStringUtil::null;
- upload_new_resource(fp->mFilenameAndPath, // file
- fp->childGetValue("name_form").asString(),
- fp->childGetValue("description_form").asString(),
+ upload_new_resource(mFilenameAndPath, // file
+ childGetValue("name_form").asString(),
+ childGetValue("description_form").asString(),
0, LLAssetType::AT_NONE, LLInventoryType::IT_NONE,
LLFloaterPerms::getNextOwnerPerms(), LLFloaterPerms::getGroupPerms(), LLFloaterPerms::getEveryonePerms(),
display_name, callback, expected_upload_cost, nruserdata);
- fp->close(false);
+ closeFloater(false);
}
-// static
//-----------------------------------------------------------------------------
// onBtnCancel()
//-----------------------------------------------------------------------------
-void LLFloaterNameDesc::onBtnCancel( void* userdata )
+void LLFloaterNameDesc::onBtnCancel()
{
- LLFloaterNameDesc *fp =(LLFloaterNameDesc *)userdata;
- fp->close(false);
+ closeFloater(false);
+}
+
+
+//-----------------------------------------------------------------------------
+// LLFloaterSoundPreview()
+//-----------------------------------------------------------------------------
+
+LLFloaterSoundPreview::LLFloaterSoundPreview(const LLSD& filename )
+ : LLFloaterNameDesc(filename)
+{
+ mIsAudio = TRUE;
+}
+
+BOOL LLFloaterSoundPreview::postBuild()
+{
+ if (!LLFloaterNameDesc::postBuild())
+ {
+ return FALSE;
+ }
+ getChild<LLUICtrl>("ok_btn")->setCommitCallback(boost::bind(&LLFloaterNameDesc::onBtnOK, this));
+ return TRUE;
}
diff --git a/indra/newview/llfloaternamedesc.h b/indra/newview/llfloaternamedesc.h
index 6aa19eba40..2cc7f1101d 100644
--- a/indra/newview/llfloaternamedesc.h
+++ b/indra/newview/llfloaternamedesc.h
@@ -44,11 +44,14 @@ class LLRadioGroup;
class LLFloaterNameDesc : public LLFloater
{
public:
- LLFloaterNameDesc(const std::string& filename);
+ LLFloaterNameDesc(const LLSD& filename);
virtual ~LLFloaterNameDesc();
virtual BOOL postBuild();
-
- static void doCommit(class LLUICtrl *, void* userdata);
+
+ void onBtnOK();
+ void onBtnCancel();
+ void doCommit();
+
protected:
virtual void onCommit();
@@ -57,9 +60,13 @@ protected:
std::string mFilenameAndPath;
std::string mFilename;
-
- static void onBtnOK(void*);
- static void onBtnCancel(void*);
};
+class LLFloaterSoundPreview : public LLFloaterNameDesc
+{
+public:
+ LLFloaterSoundPreview(const LLSD& filename );
+ virtual BOOL postBuild();
+};
+
#endif // LL_LLFLOATERNAMEDESC_H
diff --git a/indra/newview/llfloaternotificationsconsole.cpp b/indra/newview/llfloaternotificationsconsole.cpp
index e6250063f7..f2dff55044 100644
--- a/indra/newview/llfloaternotificationsconsole.cpp
+++ b/indra/newview/llfloaternotificationsconsole.cpp
@@ -36,9 +36,9 @@
#include "lluictrlfactory.h"
#include "llbutton.h"
#include "llscrolllistctrl.h"
+#include "llscrolllistitem.h"
#include "llpanel.h"
#include "llcombobox.h"
-#include "llviewertexteditor.h"
const S32 NOTIFICATION_PANEL_HEADER_HEIGHT = 20;
const S32 HEADER_PADDING = 38;
@@ -59,11 +59,12 @@ private:
};
LLNotificationChannelPanel::LLNotificationChannelPanel(const std::string& channel_name)
- : LLPanel(channel_name)
+ : LLPanel()
{
mChannelPtr = LLNotifications::instance().getChannel(channel_name);
mChannelRejectsPtr = LLNotificationChannelPtr(
- LLNotificationChannel::buildChannel(channel_name + "rejects", mChannelPtr->getParentChannelName(), !boost::bind(mChannelPtr->getFilter(), _1)));
+ LLNotificationChannel::buildChannel(channel_name + "rejects", mChannelPtr->getParentChannelName(),
+ !boost::bind(mChannelPtr->getFilter(), _1)));
LLUICtrlFactory::instance().buildPanel(this, "panel_notifications_channel.xml");
}
@@ -77,13 +78,11 @@ BOOL LLNotificationChannelPanel::postBuild()
mChannelRejectsPtr->connectChanged(boost::bind(&LLNotificationChannelPanel::update, this, _1, false));
LLScrollListCtrl* scroll = getChild<LLScrollListCtrl>("notifications_list");
- scroll->setDoubleClickCallback(onClickNotification);
- scroll->setCallbackUserData(this);
-
+ scroll->setDoubleClickCallback(onClickNotification, this);
+ scroll->setRect(LLRect( getRect().mLeft, getRect().mTop, getRect().mRight, 0));
scroll = getChild<LLScrollListCtrl>("notification_rejects_list");
- scroll->setDoubleClickCallback(onClickNotificationReject);
- scroll->setCallbackUserData(this);
-
+ scroll->setDoubleClickCallback(onClickNotificationReject, this);
+ scroll->setRect(LLRect( getRect().mLeft, getRect().mTop, getRect().mRight, 0));
return TRUE;
}
@@ -161,17 +160,13 @@ bool LLNotificationChannelPanel::update(const LLSD& payload, bool passed_filter)
// LLFloaterNotificationConsole
//
LLFloaterNotificationConsole::LLFloaterNotificationConsole(const LLSD& key)
+: LLFloater(key)
{
- LLUICtrlFactory::instance().buildFloater(this, "floater_notifications_console.xml");
-}
+ mCommitCallbackRegistrar.add("ClickAdd", boost::bind(&LLFloaterNotificationConsole::onClickAdd, this));
-void LLFloaterNotificationConsole::onClose(bool app_quitting)
-{
- setVisible(FALSE);
- //destroy();
+ //LLUICtrlFactory::instance().buildFloater(this, "floater_notifications_console.xml");
}
-
BOOL LLFloaterNotificationConsole::postBuild()
{
// these are in the order of processing
@@ -186,7 +181,7 @@ BOOL LLFloaterNotificationConsole::postBuild()
addChannel("Notifications");
addChannel("NotificationTips");
- getChild<LLButton>("add_notification")->setClickedCallback(onClickAdd, this);
+// getChild<LLButton>("add_notification")->setClickedCallback(onClickAdd, this);
LLComboBox* notifications = getChild<LLComboBox>("notification_types");
LLNotifications::TemplateNames names = LLNotifications::instance().getTemplateNames();
@@ -216,12 +211,9 @@ void LLFloaterNotificationConsole::addChannel(const std::string& name, bool open
void LLFloaterNotificationConsole::removeChannel(const std::string& name)
{
- LLPanel* panelp = getChild<LLPanel>(name, TRUE, FALSE);
- if (panelp)
- {
- getChildRef<LLLayoutStack>("notification_channels").removePanel(panelp);
- delete panelp;
- }
+ LLPanel* panelp = getChild<LLPanel>(name);
+ getChildRef<LLLayoutStack>("notification_channels").removePanel(panelp);
+ delete panelp;
updateResizeLimits();
}
@@ -229,15 +221,15 @@ void LLFloaterNotificationConsole::removeChannel(const std::string& name)
//static
void LLFloaterNotificationConsole::updateResizeLimits()
{
+ static LLUICachedControl<S32> floater_header_size ("UIFloaterHeaderSize", 0);
+
LLLayoutStack& stack = getChildRef<LLLayoutStack>("notification_channels");
- setResizeLimits(getMinWidth(), LLFLOATER_HEADER_SIZE + HEADER_PADDING + ((NOTIFICATION_PANEL_HEADER_HEIGHT + 3) * stack.getNumPanels()));
+ setResizeLimits(getMinWidth(), floater_header_size + HEADER_PADDING + ((NOTIFICATION_PANEL_HEADER_HEIGHT + 3) * stack.getNumPanels()));
}
-void LLFloaterNotificationConsole::onClickAdd(void* user_data)
+void LLFloaterNotificationConsole::onClickAdd()
{
- LLFloaterNotificationConsole* floater = (LLFloaterNotificationConsole*)user_data;
-
- std::string message_name = floater->getChild<LLComboBox>("notification_types")->getValue().asString();
+ std::string message_name = getChild<LLComboBox>("notification_types")->getValue().asString();
if (!message_name.empty())
{
LLNotifications::instance().add(message_name, LLSD());
@@ -247,15 +239,17 @@ void LLFloaterNotificationConsole::onClickAdd(void* user_data)
//=============== LLFloaterNotification ================
-LLFloaterNotification::LLFloaterNotification(LLNotification* note) : mNote(note)
+LLFloaterNotification::LLFloaterNotification(LLNotification* note)
+: LLFloater(LLSD()),
+ mNote(note)
{
- LLUICtrlFactory::instance().buildFloater(this, "floater_notification.xml");
+ LLUICtrlFactory::instance().buildFloater(this, "floater_notification.xml", NULL);
}
BOOL LLFloaterNotification::postBuild()
{
setTitle(mNote->getName());
- getChild<LLViewerTextEditor>("payload")->setText(mNote->getMessage());
+ getChild<LLUICtrl>("payload")->setValue(mNote->getMessage());
LLComboBox* responses_combo = getChild<LLComboBox>("response");
LLCtrlListInterface* response_list = responses_combo->getListInterface();
@@ -265,8 +259,7 @@ BOOL LLFloaterNotification::postBuild()
return TRUE;
}
- responses_combo->setCommitCallback(onCommitResponse);
- responses_combo->setCallbackUserData(this);
+ responses_combo->setCommitCallback(onCommitResponse, this);
LLSD form_sd = form->asLLSD();
diff --git a/indra/newview/llfloaternotificationsconsole.h b/indra/newview/llfloaternotificationsconsole.h
index 1a436b8bfe..7349ff1d8f 100644
--- a/indra/newview/llfloaternotificationsconsole.h
+++ b/indra/newview/llfloaternotificationsconsole.h
@@ -34,18 +34,18 @@
#define LL_LLFLOATER_NOTIFICATIONS_CONSOLE_H
#include "llfloater.h"
+#include "lllayoutstack.h"
#include "llnotifications.h"
class LLFloaterNotificationConsole :
- public LLFloater,
- public LLFloaterSingleton<LLFloaterNotificationConsole>
+ public LLFloater
{
+ friend class LLFloaterReg;
+
public:
- LLFloaterNotificationConsole(const LLSD& key);
// LLPanel
BOOL postBuild();
- void onClose(bool app_quitting);
void addChannel(const std::string& type, bool open = false);
void updateResizeLimits(LLLayoutStack &stack);
@@ -54,7 +54,8 @@ public:
void updateResizeLimits();
private:
- static void onClickAdd(void* user_data);
+ LLFloaterNotificationConsole(const LLSD& key);
+ void onClickAdd();
};
@@ -69,7 +70,6 @@ public:
// LLPanel
BOOL postBuild();
void respond();
- void onClose(bool app_quitting) { setVisible(FALSE); }
private:
static void onCommitResponse(LLUICtrl* ctrl, void* data) { ((LLFloaterNotification*)data)->respond(); }
diff --git a/indra/newview/llfloateropenobject.cpp b/indra/newview/llfloateropenobject.cpp
index f4984df6d9..aa82dc34b7 100644
--- a/indra/newview/llfloateropenobject.cpp
+++ b/indra/newview/llfloateropenobject.cpp
@@ -43,11 +43,12 @@
#include "llbutton.h"
#include "lltextbox.h"
-#include "llagent.h" // for agent id
#include "llalertdialog.h"
-#include "llinventoryview.h"
+#include "llinventorybridge.h"
+#include "llfloaterinventory.h"
#include "llinventorymodel.h"
#include "llpanelinventory.h"
+#include "llfloaterreg.h"
#include "llselectmgr.h"
#include "lluiconstants.h"
#include "llviewerobject.h"
@@ -55,27 +56,44 @@
#include "llviewerwindow.h"
-LLFloaterOpenObject* LLFloaterOpenObject::sInstance = NULL;
-
-LLFloaterOpenObject::LLFloaterOpenObject()
-: LLFloater(std::string("object_contents")),
+LLFloaterOpenObject::LLFloaterOpenObject(const LLSD& key)
+: LLFloater(key),
mPanelInventory(NULL),
mDirty(TRUE)
{
- LLCallbackMap::map_t factory_map;
- factory_map["object_contents"] = LLCallbackMap(createPanelInventory, this);
- LLUICtrlFactory::getInstance()->buildFloater(this,"floater_openobject.xml",&factory_map);
-
- childSetAction("copy_to_inventory_button", onClickMoveToInventory, this);
- childSetAction("copy_and_wear_button", onClickMoveAndWear, this);
- childSetTextArg("object_name", "[DESC]", std::string("Object") ); // *Note: probably do not want to translate this
+// LLUICtrlFactory::getInstance()->buildFloater(this,"floater_openobject.xml");
+ mCommitCallbackRegistrar.add("OpenObject.MoveToInventory", boost::bind(&LLFloaterOpenObject::onClickMoveToInventory, this));
+ mCommitCallbackRegistrar.add("OpenObject.MoveAndWear", boost::bind(&LLFloaterOpenObject::onClickMoveAndWear, this));
}
LLFloaterOpenObject::~LLFloaterOpenObject()
{
- sInstance = NULL;
+// sInstance = NULL;
+}
+// virtual
+BOOL LLFloaterOpenObject::postBuild()
+{
+ childSetTextArg("object_name", "[DESC]", std::string("Object") ); // *Note: probably do not want to translate this
+ mPanelInventory = getChild<LLPanelInventory>("object_contents");
+ return TRUE;
}
+void LLFloaterOpenObject::onOpen(const LLSD& key)
+{
+ LLObjectSelectionHandle object_selection = LLSelectMgr::getInstance()->getSelection();
+ if (object_selection->getRootObjectCount() != 1)
+ {
+ LLNotifications::instance().add("UnableToViewContentsMoreThanOne");
+ closeFloater();
+ return;
+ }
+ if(!(object_selection->getPrimaryObject()))
+ {
+ closeFloater();
+ return;
+ }
+ mObjectSelection = LLSelectMgr::getInstance()->getEditSelection();
+}
void LLFloaterOpenObject::refresh()
{
mPanelInventory->refresh();
@@ -96,7 +114,6 @@ void LLFloaterOpenObject::refresh()
}
childSetTextArg("object_name", "[DESC]", name);
-
childSetEnabled("copy_to_inventory_button", enabled);
childSetEnabled("copy_and_wear_button", enabled);
@@ -112,34 +129,11 @@ void LLFloaterOpenObject::draw()
LLFloater::draw();
}
-// static
void LLFloaterOpenObject::dirty()
{
- if (sInstance) sInstance->mDirty = TRUE;
+ mDirty = TRUE;
}
-// static
-void LLFloaterOpenObject::show()
-{
- LLObjectSelectionHandle object_selection = LLSelectMgr::getInstance()->getSelection();
- if (object_selection->getRootObjectCount() != 1)
- {
- LLNotifications::instance().add("UnableToViewContentsMoreThanOne");
- return;
- }
-
- // Create a new instance only if needed
- if (!sInstance)
- {
- sInstance = new LLFloaterOpenObject();
- sInstance->center();
- }
-
- sInstance->open(); /* Flawfinder: ignore */
- sInstance->setFocus(TRUE);
-
- sInstance->mObjectSelection = LLSelectMgr::getInstance()->getEditSelection();
-}
void LLFloaterOpenObject::moveToInventory(bool wear)
@@ -167,7 +161,7 @@ void LLFloaterOpenObject::moveToInventory(bool wear)
}
else
{
- parent_category_id = gAgent.getInventoryRootID();
+ parent_category_id = gInventory.getRootFolderID();
}
LLUUID category_id = gInventory.createNewCategory(parent_category_id,
LLAssetType::AT_NONE,
@@ -198,8 +192,8 @@ void LLFloaterOpenObject::callbackMoveInventory(S32 result, void* data)
if (result == 0)
{
- LLInventoryView::showAgentInventory();
- LLInventoryView* view = LLInventoryView::getActiveInventory();
+ LLFloaterInventory::showAgentInventory();
+ LLFloaterInventory* view = LLFloaterInventory::getActiveInventory();
if (view)
{
view->getPanel()->setSelection(cat->mCatID, TAKE_FOCUS_NO);
@@ -209,27 +203,15 @@ void LLFloaterOpenObject::callbackMoveInventory(S32 result, void* data)
delete cat;
}
-
-// static
-void LLFloaterOpenObject::onClickMoveToInventory(void* data)
+void LLFloaterOpenObject::onClickMoveToInventory()
{
- LLFloaterOpenObject* self = (LLFloaterOpenObject*)data;
- self->moveToInventory(false);
- self->close();
+ moveToInventory(false);
+ closeFloater();
}
-// static
-void LLFloaterOpenObject::onClickMoveAndWear(void* data)
+void LLFloaterOpenObject::onClickMoveAndWear()
{
- LLFloaterOpenObject* self = (LLFloaterOpenObject*)data;
- self->moveToInventory(true);
- self->close();
+ moveToInventory(true);
+ closeFloater();
}
-//static
-void* LLFloaterOpenObject::createPanelInventory(void* data)
-{
- LLFloaterOpenObject* floater = (LLFloaterOpenObject*)data;
- floater->mPanelInventory = new LLPanelInventory(std::string("Object Contents"), LLRect());
- return floater->mPanelInventory;
-}
diff --git a/indra/newview/llfloateropenobject.h b/indra/newview/llfloateropenobject.h
index 27653a5c99..0df3780ac4 100644
--- a/indra/newview/llfloateropenobject.h
+++ b/indra/newview/llfloateropenobject.h
@@ -46,9 +46,10 @@ class LLPanelInventory;
class LLFloaterOpenObject
: public LLFloater
{
+ friend class LLFloaterReg;
public:
- static void show();
- static void dirty();
+
+ void dirty();
struct LLCatAndWear
{
@@ -57,21 +58,25 @@ public:
};
protected:
- LLFloaterOpenObject();
- ~LLFloaterOpenObject();
+ /*virtual*/ BOOL postBuild();
void refresh();
void draw();
+ virtual void onOpen(const LLSD& key);
+// virtual void onClose();
void moveToInventory(bool wear);
- static void onClickMoveToInventory(void* data);
- static void onClickMoveAndWear(void* data);
+ void onClickMoveToInventory();
+ void onClickMoveAndWear();
static void callbackMoveInventory(S32 result, void* data);
- static void* createPanelInventory(void* data);
+private:
+
+ LLFloaterOpenObject(const LLSD& key);
+ ~LLFloaterOpenObject();
+
protected:
- static LLFloaterOpenObject* sInstance;
LLPanelInventory* mPanelInventory;
LLSafeHandle<LLObjectSelection> mObjectSelection;
diff --git a/indra/newview/llfloaterparcel.cpp b/indra/newview/llfloaterparcel.cpp
index 4213150553..44270683a0 100644
--- a/indra/newview/llfloaterparcel.cpp
+++ b/indra/newview/llfloaterparcel.cpp
@@ -35,6 +35,8 @@
#include "llfloaterparcel.h"
+#include "llfloaterreg.h"
+
// viewer project includes
#include "llcommandhandler.h"
#include "llpanelplace.h"
@@ -47,15 +49,13 @@
// Globals
//-----------------------------------------------------------------------------
-LLMap< const LLUUID, LLFloaterParcelInfo* > gPlaceInfoInstances;
-
class LLParcelHandler : public LLCommandHandler
{
public:
// requires trusted browser to trigger
LLParcelHandler() : LLCommandHandler("parcel", true) { }
bool handle(const LLSD& params, const LLSD& query_map,
- LLWebBrowserCtrl* web)
+ LLMediaCtrl* web)
{
if (params.size() < 2)
{
@@ -68,8 +68,11 @@ public:
}
if (params[1].asString() == "about")
{
- LLFloaterParcelInfo::show(parcel_id);
- return true;
+ if (parcel_id.notNull())
+ {
+ LLFloaterReg::showInstance("parcel_info", LLSD(parcel_id));
+ return true;
+ }
}
return false;
}
@@ -82,7 +85,7 @@ LLParcelHandler gParcelHandler;
//----------------------------------------------------------------------------
-void* LLFloaterParcelInfo::createPanelPlace(void* data)
+void* LLFloaterParcelInfo::createPanelPlace(void* data)
{
LLFloaterParcelInfo* self = (LLFloaterParcelInfo*)data;
self->mPanelParcelp = new LLPanelPlace(); // allow edit self
@@ -93,54 +96,29 @@ void* LLFloaterParcelInfo::createPanelPlace(void* data)
//----------------------------------------------------------------------------
-LLFloaterParcelInfo::LLFloaterParcelInfo(const std::string& name, const LLUUID &parcel_id)
-: LLFloater(name),
- mParcelID( parcel_id )
+LLFloaterParcelInfo::LLFloaterParcelInfo(const LLSD& parcel_id)
+: LLFloater(parcel_id),
+ mParcelID( parcel_id.asUUID() ),
+ mPanelParcelp(NULL)
{
mFactoryMap["place_details_panel"] = LLCallbackMap(LLFloaterParcelInfo::createPanelPlace, this);
- LLUICtrlFactory::getInstance()->buildFloater(this, "floater_preview_url.xml", &getFactoryMap());
- gPlaceInfoInstances.addData(parcel_id, this);
+// LLUICtrlFactory::getInstance()->buildFloater(this, "floater_preview_url.xml");
}
// virtual
LLFloaterParcelInfo::~LLFloaterParcelInfo()
{
- // child views automatically deleted
- gPlaceInfoInstances.removeData(mParcelID);
-
-}
-void LLFloaterParcelInfo::displayParcelInfo(const LLUUID& parcel_id)
-{
- mPanelParcelp->setParcelID(parcel_id);
}
-// static
-LLFloaterParcelInfo* LLFloaterParcelInfo::show(const LLUUID &parcel_id)
+BOOL LLFloaterParcelInfo::postBuild()
{
- if (parcel_id.isNull())
+ if (mPanelParcelp)
{
- return NULL;
+ mPanelParcelp->setParcelID(mParcelID);
}
-
- LLFloaterParcelInfo *floater;
- if (gPlaceInfoInstances.checkData(parcel_id))
- {
- // ...bring that window to front
- floater = gPlaceInfoInstances.getData(parcel_id);
- floater->open(); /*Flawfinder: ignore*/
- floater->setFrontmost(true);
- }
- else
- {
- floater = new LLFloaterParcelInfo("parcelinfo", parcel_id );
- floater->center();
- floater->open(); /*Flawfinder: ignore*/
- floater->displayParcelInfo(parcel_id);
- floater->setFrontmost(true);
- }
-
- return floater;
+ center();
+ return LLFloater::postBuild();
}
diff --git a/indra/newview/llfloaterparcel.h b/indra/newview/llfloaterparcel.h
index 4d698d64ae..386acb3fd5 100644
--- a/indra/newview/llfloaterparcel.h
+++ b/indra/newview/llfloaterparcel.h
@@ -43,13 +43,13 @@ class LLFloaterParcelInfo
public:
static void* createPanelPlace(void* data);
- LLFloaterParcelInfo(const std::string& name, const LLUUID &parcel_id );
+ LLFloaterParcelInfo( const LLSD& parcel_id );
/*virtual*/ ~LLFloaterParcelInfo();
-
+
+ /*virtual*/ BOOL postBuild();
+
void displayParcelInfo(const LLUUID& parcel_id);
- static LLFloaterParcelInfo* show(const LLUUID& parcel_id);
-
private:
LLUUID mParcelID; // for which parcel is this window?
LLPanelPlace* mPanelParcelp;
diff --git a/indra/newview/llfloaterperms.cpp b/indra/newview/llfloaterperms.cpp
index 52fba0aa20..17bb8221ad 100644
--- a/indra/newview/llfloaterperms.cpp
+++ b/indra/newview/llfloaterperms.cpp
@@ -42,50 +42,45 @@
LLFloaterPerms::LLFloaterPerms(const LLSD& seed)
+: LLFloater(seed)
{
- LLUICtrlFactory::getInstance()->buildFloater(this, "floater_perm_prefs.xml");
+ //LLUICtrlFactory::getInstance()->buildFloater(this, "floater_perm_prefs.xml");
+ mCommitCallbackRegistrar.add("Perms.Copy", boost::bind(&LLFloaterPerms::onCommitCopy, this));
+ mCommitCallbackRegistrar.add("Perms.OK", boost::bind(&LLFloaterPerms::onClickOK, this));
+ mCommitCallbackRegistrar.add("Perms.Cancel", boost::bind(&LLFloaterPerms::onClickCancel, this));
+
}
BOOL LLFloaterPerms::postBuild()
{
- childSetEnabled("next_owner_transfer", gSavedSettings.getBOOL("NextOwnerCopy"));
- childSetAction("help", onClickHelp, this);
- childSetAction("ok", onClickOK, this);
- childSetAction("cancel", onClickCancel, this);
- childSetCommitCallback("next_owner_copy", &onCommitCopy, this);
-
+ mCloseSignal.connect(boost::bind(&LLFloaterPerms::cancel, this));
+
refresh();
return TRUE;
}
-//static
-void LLFloaterPerms::onClickOK(void* data)
+void LLFloaterPerms::onClickOK()
{
- LLFloaterPerms* self = static_cast<LLFloaterPerms*>(data);
- self->ok();
- self->close();
+ ok();
+ closeFloater();
}
-//static
-void LLFloaterPerms::onClickCancel(void* data)
+void LLFloaterPerms::onClickCancel()
{
- LLFloaterPerms* self = static_cast<LLFloaterPerms*>(data);
- self->cancel();
- self->close();
+ cancel();
+ closeFloater();
}
-//static
-void LLFloaterPerms::onCommitCopy(LLUICtrl* ctrl, void* data)
+void LLFloaterPerms::onCommitCopy()
{
- LLFloaterPerms* self = static_cast<LLFloaterPerms*>(data);
// Implements fair use
BOOL copyable = gSavedSettings.getBOOL("NextOwnerCopy");
if(!copyable)
{
gSavedSettings.setBOOL("NextOwnerTransfer", TRUE);
}
- LLCheckBoxCtrl* xfer = self->getChild<LLCheckBoxCtrl>("next_owner_transfer");
+ LLCheckBoxCtrl* xfer = getChild<LLCheckBoxCtrl>("next_owner_transfer");
xfer->setEnabled(copyable);
}
@@ -112,14 +107,6 @@ void LLFloaterPerms::refresh()
mNextOwnerTransfer = gSavedSettings.getBOOL("NextOwnerTransfer");
}
-void LLFloaterPerms::onClose(bool app_quitting)
-{
- // Cancel any unsaved changes before closing.
- // Note: when closed due to the OK button this amounts to a no-op.
- cancel();
- LLFloater::onClose(app_quitting);
-}
-
//static
U32 LLFloaterPerms::getGroupPerms(std::string prefix)
{
@@ -151,9 +138,3 @@ U32 LLFloaterPerms::getNextOwnerPerms(std::string prefix)
return flags;
}
-
-//static
-void LLFloaterPerms::onClickHelp(void* data)
-{
- LLNotifications::instance().add("ClickUploadHelpPermissions");
-}
diff --git a/indra/newview/llfloaterperms.h b/indra/newview/llfloaterperms.h
index 805039efe4..2426f43ca7 100644
--- a/indra/newview/llfloaterperms.h
+++ b/indra/newview/llfloaterperms.h
@@ -36,18 +36,17 @@
#include "llfloater.h"
-class LLFloaterPerms : public LLFloater, public LLFloaterSingleton<LLFloaterPerms>
+class LLFloaterPerms : public LLFloater
{
- friend class LLUISingleton<LLFloaterPerms, VisibilityPolicy<LLFloater> >;
+ friend class LLFloaterReg;
public:
- /*virtual*/ void onClose(bool app_quitting = false);
/*virtual*/ BOOL postBuild();
void ok();
void cancel();
- static void onClickOK(void*);
- static void onClickCancel(void*);
- static void onCommitCopy(LLUICtrl* ctrl, void* data);
+ void onClickOK();
+ void onClickCancel();
+ void onCommitCopy();
// Convenience methods to get current permission preference bitfields from saved settings:
static U32 getEveryonePerms(std::string prefix=""); // prefix + "EveryoneCopy"
static U32 getGroupPerms(std::string prefix=""); // prefix + "ShareWithGroup"
@@ -57,9 +56,6 @@ private:
LLFloaterPerms(const LLSD& seed);
void refresh();
- /// callback for the menus help button
- static void onClickHelp(void* data);
-
BOOL // cached values only for implementing cancel.
mShareWithGroup,
mEveryoneCopy,
diff --git a/indra/newview/llfloaterpostcard.cpp b/indra/newview/llfloaterpostcard.cpp
index b0ab0f9625..a27070de39 100644
--- a/indra/newview/llfloaterpostcard.cpp
+++ b/indra/newview/llfloaterpostcard.cpp
@@ -43,8 +43,9 @@
#include "llagent.h"
#include "llui.h"
#include "lllineeditor.h"
-#include "llviewertexteditor.h"
#include "llbutton.h"
+#include "lltexteditor.h"
+#include "llfloaterreg.h"
#include "llviewercontrol.h"
#include "llviewernetwork.h"
#include "lluictrlfactory.h"
@@ -61,8 +62,9 @@
#include "llimagej2c.h"
#include "llvfile.h"
#include "llvfs.h"
-
+#include "llviewertexture.h"
#include "llassetuploadresponders.h"
+#include "llagentui.h"
#include <boost/regex.hpp> //boost.regex lib
@@ -70,89 +72,59 @@
/// Local function declarations, constants, enums, and typedefs
///----------------------------------------------------------------------------
-//static
-LLFloaterPostcard::instance_list_t LLFloaterPostcard::sInstances;
-
///----------------------------------------------------------------------------
/// Class LLFloaterPostcard
///----------------------------------------------------------------------------
-LLFloaterPostcard::LLFloaterPostcard(LLImageJPEG* jpeg, LLImageGL *img, const LLVector2& img_scale, const LLVector3d& pos_taken_global)
-: LLFloater(std::string("Postcard Floater")),
- mJPEGImage(jpeg),
- mViewerImage(img),
- mImageScale(img_scale),
- mPosTakenGlobal(pos_taken_global),
+LLFloaterPostcard::LLFloaterPostcard(const LLSD& key)
+: LLFloater(key),
+ mJPEGImage(NULL),
+ mViewerImage(NULL),
mHasFirstMsgFocus(false)
{
- init();
-}
-
-void LLFloaterPostcard::init()
-{
- // pick up the user's up-to-date email address
- if(!gAgent.getID().isNull())
- {
- // we're logged in, so we can get this info.
- gMessageSystem->newMessageFast(_PREHASH_UserInfoRequest);
- gMessageSystem->nextBlockFast(_PREHASH_AgentData);
- gMessageSystem->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
- gMessageSystem->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
- gAgent.sendReliableMessage();
- }
-
- sInstances.insert(this);
+ //LLUICtrlFactory::getInstance()->buildFloater(this, "floater_postcard.xml");
}
// Destroys the object
LLFloaterPostcard::~LLFloaterPostcard()
{
- sInstances.erase(this);
mJPEGImage = NULL; // deletes image
}
BOOL LLFloaterPostcard::postBuild()
{
+ // pick up the user's up-to-date email address
+ gAgent.sendAgentUserInfoRequest();
+
childSetAction("cancel_btn", onClickCancel, this);
childSetAction("send_btn", onClickSend, this);
childDisable("from_form");
std::string name_string;
- gAgent.buildFullname(name_string);
+ LLAgentUI::buildFullname(name_string);
childSetValue("name_form", LLSD(name_string));
- LLTextEditor* MsgField = getChild<LLTextEditor>("msg_form");
- if (MsgField)
- {
- MsgField->setWordWrap(TRUE);
-
- // For the first time a user focusess to .the msg box, all text will be selected.
- MsgField->setFocusChangedCallback(onMsgFormFocusRecieved, this);
- }
+ // For the first time a user focusess to .the msg box, all text will be selected.
+ getChild<LLUICtrl>("msg_form")->setFocusChangedCallback(onMsgFormFocusRecieved, this);
childSetFocus("to_form", TRUE);
return TRUE;
}
-
-
// static
-LLFloaterPostcard* LLFloaterPostcard::showFromSnapshot(LLImageJPEG *jpeg, LLImageGL *img, const LLVector2 &image_scale, const LLVector3d& pos_taken_global)
+LLFloaterPostcard* LLFloaterPostcard::showFromSnapshot(LLImageJPEG *jpeg, LLViewerTexture *img, const LLVector2 &image_scale, const LLVector3d& pos_taken_global)
{
// Take the images from the caller
// It's now our job to clean them up
- LLFloaterPostcard *instance = new LLFloaterPostcard(jpeg, img, image_scale, pos_taken_global);
-
- LLUICtrlFactory::getInstance()->buildFloater(instance, "floater_postcard.xml");
-
- S32 left, top;
- gFloaterView->getNewFloaterPosition(&left, &top);
- instance->setOrigin(left, top - instance->getRect().getHeight());
+ LLFloaterPostcard* instance = LLFloaterReg::showTypedInstance<LLFloaterPostcard>("postcard", LLSD(img->getID()));
+
+ instance->mJPEGImage = jpeg;
+ instance->mViewerImage = img;
+ instance->mImageScale = image_scale;
+ instance->mPosTakenGlobal = pos_taken_global;
- instance->open(); /*Flawfinder: ignore*/
-
return instance;
}
@@ -198,7 +170,7 @@ void LLFloaterPostcard::draw()
rect.mBottom,
rect.getWidth(),
rect.getHeight(),
- mViewerImage,
+ mViewerImage.get(),
LLColor4::white);
}
glMatrixMode(GL_TEXTURE);
@@ -215,7 +187,7 @@ void LLFloaterPostcard::onClickCancel(void* data)
{
LLFloaterPostcard *self = (LLFloaterPostcard *)data;
- self->close(false);
+ self->closeFloater(false);
}
}
@@ -313,16 +285,17 @@ void LLFloaterPostcard::uploadCallback(const LLUUID& asset_id, void *user_data,
gAgent.sendReliableMessage();
}
- self->close();
+ self->closeFloater();
}
// static
void LLFloaterPostcard::updateUserInfo(const std::string& email)
{
- for (instance_list_t::iterator iter = sInstances.begin();
- iter != sInstances.end(); ++iter)
+ LLFloaterReg::const_instance_list_t& inst_list = LLFloaterReg::getFloaterList("impanel");
+ for (LLFloaterReg::const_instance_list_t::const_iterator iter = inst_list.begin();
+ iter != inst_list.end(); ++iter)
{
- LLFloaterPostcard *instance = *iter;
+ LLFloater* instance = *iter;
const std::string& text = instance->childGetValue("from_form").asString();
if (text.empty())
{
diff --git a/indra/newview/llfloaterpostcard.h b/indra/newview/llfloaterpostcard.h
index 087649f159..49cce53106 100644
--- a/indra/newview/llfloaterpostcard.h
+++ b/indra/newview/llfloaterpostcard.h
@@ -36,25 +36,25 @@
#include "llfloater.h"
#include "llcheckboxctrl.h"
-#include "llmemory.h"
-#include "llimagegl.h"
+#include "llpointer.h"
class LLTextEditor;
class LLLineEditor;
class LLButton;
+class LLViewerTexture;
+class LLImageJPEG;
class LLFloaterPostcard
: public LLFloater
{
public:
- LLFloaterPostcard(LLImageJPEG* jpeg, LLImageGL *img, const LLVector2& img_scale, const LLVector3d& pos_taken_global);
+ LLFloaterPostcard(const LLSD& key);
virtual ~LLFloaterPostcard();
- virtual void init();
virtual BOOL postBuild();
virtual void draw();
- static LLFloaterPostcard* showFromSnapshot(LLImageJPEG *jpeg, LLImageGL *img, const LLVector2& img_scale, const LLVector3d& pos_taken_global);
+ static LLFloaterPostcard* showFromSnapshot(LLImageJPEG *jpeg, LLViewerTexture *img, const LLVector2& img_scale, const LLVector3d& pos_taken_global);
static void onClickCancel(void* data);
static void onClickSend(void* data);
@@ -73,15 +73,12 @@ public:
protected:
LLPointer<LLImageJPEG> mJPEGImage;
- LLPointer<LLImageGL> mViewerImage;
+ LLPointer<LLViewerTexture> mViewerImage;
LLTransactionID mTransactionID;
LLAssetID mAssetID;
LLVector2 mImageScale;
LLVector3d mPosTakenGlobal;
boolean mHasFirstMsgFocus;
-
- typedef std::set<LLFloaterPostcard*> instance_list_t;
- static instance_list_t sInstances;
};
diff --git a/indra/newview/llfloaterpostprocess.cpp b/indra/newview/llfloaterpostprocess.cpp
index de9b598b1e..2ab54d6e46 100644
--- a/indra/newview/llfloaterpostprocess.cpp
+++ b/indra/newview/llfloaterpostprocess.cpp
@@ -36,6 +36,7 @@
#include "llsliderctrl.h"
#include "llcheckboxctrl.h"
+#include "llcombobox.h"
#include "lluictrlfactory.h"
#include "llviewerdisplay.h"
#include "llpostprocess.h"
@@ -44,13 +45,19 @@
#include "llviewerwindow.h"
-LLFloaterPostProcess* LLFloaterPostProcess::sPostProcess = NULL;
-
+LLFloaterPostProcess::LLFloaterPostProcess(const LLSD& key)
+ : LLFloater(key)
+{
+ //LLUICtrlFactory::getInstance()->buildFloater(this, "floater_post_process.xml");
+}
-LLFloaterPostProcess::LLFloaterPostProcess() : LLFloater(std::string("Post-Process Floater"))
+LLFloaterPostProcess::~LLFloaterPostProcess()
{
- LLUICtrlFactory::getInstance()->buildFloater(this, "floater_post_process.xml");
+
+}
+BOOL LLFloaterPostProcess::postBuild()
+{
/// Color Filter Callbacks
childSetCommitCallback("ColorFilterToggle", &LLFloaterPostProcess::onBoolToggle, (char*)"enable_color_filter");
//childSetCommitCallback("ColorFilterGamma", &LLFloaterPostProcess::onFloatControlMoved, &(gPostProcess->tweaks.gamma()));
@@ -77,32 +84,14 @@ LLFloaterPostProcess::LLFloaterPostProcess() : LLFloater(std::string("Post-Proce
// Effect loading and saving.
LLComboBox* comboBox = getChild<LLComboBox>("PPEffectsCombo");
- childSetAction("PPLoadEffect", &LLFloaterPostProcess::onLoadEffect, comboBox);
- comboBox->setCommitCallback(onChangeEffectName);
+ getChild<LLComboBox>("PPLoadEffect")->setCommitCallback(boost::bind(&LLFloaterPostProcess::onLoadEffect, this, comboBox));
+ comboBox->setCommitCallback(boost::bind(&LLFloaterPostProcess::onChangeEffectName, this, _1));
LLLineEditor* editBox = getChild<LLLineEditor>("PPEffectNameEditor");
- childSetAction("PPSaveEffect", &LLFloaterPostProcess::onSaveEffect, editBox);
+ getChild<LLComboBox>("PPSaveEffect")->setCommitCallback(boost::bind(&LLFloaterPostProcess::onSaveEffect, this, editBox));
syncMenu();
-
-}
-
-LLFloaterPostProcess::~LLFloaterPostProcess()
-{
-
-
-}
-
-LLFloaterPostProcess* LLFloaterPostProcess::instance()
-{
- // if we don't have our singleton instance, create it
- if (!sPostProcess)
- {
- sPostProcess = new LLFloaterPostProcess();
- sPostProcess->open();
- sPostProcess->setFocus(TRUE);
- }
- return sPostProcess;
+ return TRUE;
}
// Bool Toggle
@@ -155,44 +144,39 @@ void LLFloaterPostProcess::onColorControlIMoved(LLUICtrl* ctrl, void* userData)
gPostProcess->tweaks[floatVariableName][3] = sldrCtrl->getValue();
}
-void LLFloaterPostProcess::onLoadEffect(void* userData)
+void LLFloaterPostProcess::onLoadEffect(LLComboBox* comboBox)
{
- LLComboBox* comboBox = static_cast<LLComboBox*>(userData);
-
LLSD::String effectName(comboBox->getSelectedValue().asString());
gPostProcess->setSelectedEffect(effectName);
- sPostProcess->syncMenu();
+ syncMenu();
}
-void LLFloaterPostProcess::onSaveEffect(void* userData)
+void LLFloaterPostProcess::onSaveEffect(LLLineEditor* editBox)
{
- LLLineEditor* editBox = static_cast<LLLineEditor*>(userData);
-
std::string effectName(editBox->getValue().asString());
if (gPostProcess->mAllEffects.has(effectName))
{
LLSD payload;
payload["effect_name"] = effectName;
- LLNotifications::instance().add("PPSaveEffectAlert", LLSD(), payload, &LLFloaterPostProcess::saveAlertCallback);
+ LLNotifications::instance().add("PPSaveEffectAlert", LLSD(), payload, boost::bind(&LLFloaterPostProcess::saveAlertCallback, this, _1, _2));
}
else
{
gPostProcess->saveEffect(effectName);
- sPostProcess->syncMenu();
+ syncMenu();
}
}
-void LLFloaterPostProcess::onChangeEffectName(LLUICtrl* ctrl, void * userData)
+void LLFloaterPostProcess::onChangeEffectName(LLUICtrl* ctrl)
{
// get the combo box and name
- LLComboBox * comboBox = static_cast<LLComboBox*>(ctrl);
- LLLineEditor* editBox = sPostProcess->getChild<LLLineEditor>("PPEffectNameEditor");
+ LLLineEditor* editBox = getChild<LLLineEditor>("PPEffectNameEditor");
// set the parameter's new name
- editBox->setValue(comboBox->getSelectedValue());
+ editBox->setValue(ctrl->getValue());
}
bool LLFloaterPostProcess::saveAlertCallback(const LLSD& notification, const LLSD& response)
@@ -204,30 +188,11 @@ bool LLFloaterPostProcess::saveAlertCallback(const LLSD& notification, const LLS
{
gPostProcess->saveEffect(notification["payload"]["effect_name"].asString());
- sPostProcess->syncMenu();
+ syncMenu();
}
return false;
}
-void LLFloaterPostProcess::show()
-{
- // get the instance, make sure the values are synced
- // and open the menu
- LLFloaterPostProcess* postProcess = instance();
- postProcess->syncMenu();
- postProcess->open();
-}
-
-// virtual
-void LLFloaterPostProcess::onClose(bool app_quitting)
-{
- // just set visibility to false, don't get fancy yet
- if (sPostProcess)
- {
- sPostProcess->setVisible(FALSE);
- }
-}
-
void LLFloaterPostProcess::syncMenu()
{
// add the combo boxe contents
diff --git a/indra/newview/llfloaterpostprocess.h b/indra/newview/llfloaterpostprocess.h
index 08a3618c2b..c789adee00 100644
--- a/indra/newview/llfloaterpostprocess.h
+++ b/indra/newview/llfloaterpostprocess.h
@@ -36,6 +36,8 @@
#include "llfloater.h"
class LLButton;
+class LLComboBox;
+class LLLineEditor;
class LLSliderCtrl;
class LLTabContainer;
class LLPanelPermissions;
@@ -51,11 +53,9 @@ class LLFloaterPostProcess : public LLFloater
{
public:
- LLFloaterPostProcess();
+ LLFloaterPostProcess(const LLSD& key);
virtual ~LLFloaterPostProcess();
-
- /// one and one instance only
- static LLFloaterPostProcess* instance();
+ /*virtual*/ BOOL postBuild();
/// post process callbacks
static void onBoolToggle(LLUICtrl* ctrl, void* userData);
@@ -64,18 +64,12 @@ public:
static void onColorControlGMoved(LLUICtrl* ctrl, void* userData);
static void onColorControlBMoved(LLUICtrl* ctrl, void* userData);
static void onColorControlIMoved(LLUICtrl* ctrl, void* userData);
- static void onLoadEffect(void* userData);
- static void onSaveEffect(void* userData);
- static void onChangeEffectName(LLUICtrl* ctrl, void * userData);
+ void onLoadEffect(LLComboBox* comboBox);
+ void onSaveEffect(LLLineEditor* editBox);
+ void onChangeEffectName(LLUICtrl* ctrl);
/// prompts a user when overwriting an effect
- static bool saveAlertCallback(const LLSD& notification, const LLSD& response);
-
- /// show off our menu
- static void show();
-
- /// stuff to do on exit
- virtual void onClose(bool app_quitting);
+ bool saveAlertCallback(const LLSD& notification, const LLSD& response);
/// sync up sliders
void syncMenu();
@@ -84,8 +78,6 @@ public:
void refresh();
*/
public:
-
- static LLFloaterPostProcess* sPostProcess;
};
#endif
diff --git a/indra/newview/llfloaterpreference.cpp b/indra/newview/llfloaterpreference.cpp
index 17a59ccb77..c47c7b073c 100644
--- a/indra/newview/llfloaterpreference.cpp
+++ b/indra/newview/llfloaterpreference.cpp
@@ -40,477 +40,1584 @@
#include "llfloaterpreference.h"
-#include "llbutton.h"
-#include "llcheckboxctrl.h"
-#include "lldir.h"
-#include "llfocusmgr.h"
-#include "llscrollbar.h"
-#include "llspinctrl.h"
#include "message.h"
+#include "llagent.h"
+#include "llavatarconstants.h"
+#include "llcheckboxctrl.h"
+#include "llcolorswatch.h"
+#include "llcombobox.h"
#include "llcommandhandler.h"
+#include "lldirpicker.h"
+#include "llfeaturemanager.h"
+#include "llfocusmgr.h"
+#include "llfirstuse.h"
+#include "llfloaterreg.h"
#include "llfloaterabout.h"
-#include "llfloaterpreference.h"
-#include "llpanelnetwork.h"
-#include "llpanelaudioprefs.h"
-#include "llpaneldisplay.h"
-#include "llpaneldebug.h"
-#include "llpanelgeneral.h"
-#include "llpanelinput.h"
+#include "llfloaterhardwaresettings.h"
+#include "llfloatervoicedevicesettings.h"
+#include "llkeyboard.h"
+#include "llmodaldialog.h"
+#include "llnavigationbar.h"
#include "llpanellogin.h"
-#include "llpanelLCD.h"
-#include "llpanelmsgs.h"
-#include "llpanelweb.h"
-#include "llpanelskins.h"
-#include "llprefschat.h"
-#include "llprefsvoice.h"
-#include "llprefsim.h"
-#include "llresizehandle.h"
-#include "llresmgr.h"
-#include "llassetstorage.h"
-#include "llagent.h"
+#include "llradiogroup.h"
+#include "llsky.h"
+#include "llscrolllistctrl.h"
+#include "llscrolllistitem.h"
+#include "llsliderctrl.h"
+#include "lltabcontainer.h"
+#include "lltrans.h"
#include "llviewercontrol.h"
-#include "llviewernetwork.h"
-#include "lluictrlfactory.h"
+#include "llviewercamera.h"
#include "llviewerwindow.h"
-#include "llkeyboard.h"
-#include "llscrollcontainer.h"
-#include "llfloaterhardwaresettings.h"
+#include "llviewermessage.h"
+#include "llviewershadermgr.h"
+#include "llvotree.h"
+#include "llvosky.h"
-const S32 PREF_BORDER = 4;
-const S32 PREF_PAD = 5;
-const S32 PREF_BUTTON_WIDTH = 70;
-const S32 PREF_CATEGORY_WIDTH = 150;
+// linden library includes
+#include "llerror.h"
+#include "llfontgl.h"
+#include "llrect.h"
+#include "llstring.h"
-const S32 PREF_FLOATER_MIN_HEIGHT = 2 * SCROLLBAR_SIZE + 2 * LLPANEL_BORDER_WIDTH + 96;
+// project includes
-LLFloaterPreference* LLFloaterPreference::sInstance = NULL;
+#include "llbutton.h"
+#include "llflexibleobject.h"
+#include "lllineeditor.h"
+#include "llresmgr.h"
+#include "llspinctrl.h"
+#include "llstartup.h"
+#include "lltextbox.h"
+#include "llui.h"
+#include "llviewerobjectlist.h"
+#include "llvoavatar.h"
+#include "llvovolume.h"
+#include "llwindow.h"
+#include "llworld.h"
+#include "pipeline.h"
+#include "lluictrlfactory.h"
+#include "llboost.h"
+#include "llviewermedia.h"
+#include "llpluginclassmedia.h"
+
+
+//RN temporary includes for resolution switching
+#include "llglheaders.h"
+const F32 MAX_USER_FAR_CLIP = 512.f;
+const F32 MIN_USER_FAR_CLIP = 64.f;
+const S32 ASPECT_RATIO_STR_LEN = 100;
-class LLPreferencesHandler : public LLCommandHandler
+class LLVoiceSetKeyDialog : public LLModalDialog
{
public:
- // requires trusted browser
- LLPreferencesHandler() : LLCommandHandler("preferences", true) { }
- bool handle(const LLSD& tokens, const LLSD& query_map,
- LLWebBrowserCtrl* web)
- {
- LLFloaterPreference::show(NULL);
- return true;
- }
+ LLVoiceSetKeyDialog(const LLSD& key);
+ ~LLVoiceSetKeyDialog();
+
+ /*virtual*/ BOOL postBuild();
+
+ void setParent(LLFloaterPreference* parent) { mParent = parent; }
+
+ BOOL handleKeyHere(KEY key, MASK mask);
+ static void onCancel(void* user_data);
+
+private:
+ LLFloaterPreference* mParent;
};
-LLPreferencesHandler gPreferencesHandler;
-
+LLVoiceSetKeyDialog::LLVoiceSetKeyDialog(const LLSD& key)
+ : LLModalDialog(key),
+ mParent(NULL)
+{
+// LLUICtrlFactory::getInstance()->buildFloater(this, "floater_select_key.xml", NULL);
+}
-// Must be done at run time, not compile time. JC
-S32 pref_min_width()
+//virtual
+BOOL LLVoiceSetKeyDialog::postBuild()
{
- return
- 2 * PREF_BORDER +
- 2 * PREF_BUTTON_WIDTH +
- PREF_PAD + RESIZE_HANDLE_WIDTH +
- PREF_CATEGORY_WIDTH +
- PREF_PAD;
+ childSetAction("Cancel", onCancel, this);
+ childSetFocus("Cancel");
+
+ gFocusMgr.setKeystrokesOnly(TRUE);
+
+ return TRUE;
}
-S32 pref_min_height()
+LLVoiceSetKeyDialog::~LLVoiceSetKeyDialog()
{
- return
- 2 * PREF_BORDER +
- 3*(BTN_HEIGHT + PREF_PAD) +
- PREF_FLOATER_MIN_HEIGHT;
}
+BOOL LLVoiceSetKeyDialog::handleKeyHere(KEY key, MASK mask)
+{
+ BOOL result = TRUE;
+
+ if(key == 'Q' && mask == MASK_CONTROL)
+ {
+ result = FALSE;
+ }
+ else if (mParent)
+ {
+ mParent->setKey(key);
+ }
+
+ closeFloater();
+ return result;
+}
-LLPreferenceCore::LLPreferenceCore(LLTabContainer* tab_container, LLButton * default_btn) :
- mTabContainer(tab_container),
- mGeneralPanel(NULL),
- mInputPanel(NULL),
- mNetworkPanel(NULL),
- mDisplayPanel(NULL),
- mAudioPanel(NULL),
- mMsgPanel(NULL),
- mSkinsPanel(NULL),
- mLCDPanel(NULL)
+//static
+void LLVoiceSetKeyDialog::onCancel(void* user_data)
{
- mGeneralPanel = new LLPanelGeneral();
- mTabContainer->addTabPanel(mGeneralPanel, mGeneralPanel->getLabel(), FALSE, onTabChanged, mTabContainer);
- mGeneralPanel->setDefaultBtn(default_btn);
+ LLVoiceSetKeyDialog* self = (LLVoiceSetKeyDialog*)user_data;
+ self->closeFloater();
+}
- mInputPanel = new LLPanelInput();
- mTabContainer->addTabPanel(mInputPanel, mInputPanel->getLabel(), FALSE, onTabChanged, mTabContainer);
- mInputPanel->setDefaultBtn(default_btn);
- mNetworkPanel = new LLPanelNetwork();
- mTabContainer->addTabPanel(mNetworkPanel, mNetworkPanel->getLabel(), FALSE, onTabChanged, mTabContainer);
- mNetworkPanel->setDefaultBtn(default_btn);
+// global functions
- mWebPanel = new LLPanelWeb();
- mTabContainer->addTabPanel(mWebPanel, mWebPanel->getLabel(), FALSE, onTabChanged, mTabContainer);
- mWebPanel->setDefaultBtn(default_btn);
+// helper functions for getting/freeing the web browser media
+// if creating/destroying these is too slow, we'll need to create
+// a static member and update all our static callbacks
- mDisplayPanel = new LLPanelDisplay();
- mTabContainer->addTabPanel(mDisplayPanel, mDisplayPanel->getLabel(), FALSE, onTabChanged, mTabContainer);
- mDisplayPanel->setDefaultBtn(default_btn);
+void handleNameTagOptionChanged(const LLSD& newvalue);
+viewer_media_t get_web_media();
+bool callback_clear_browser_cache(const LLSD& notification, const LLSD& response);
- mAudioPanel = new LLPanelAudioPrefs();
- mTabContainer->addTabPanel(mAudioPanel, mAudioPanel->getLabel(), FALSE, onTabChanged, mTabContainer);
- mAudioPanel->setDefaultBtn(default_btn);
+bool callback_skip_dialogs(const LLSD& notification, const LLSD& response, LLFloaterPreference* floater);
+bool callback_reset_dialogs(const LLSD& notification, const LLSD& response, LLFloaterPreference* floater);
- mPrefsChat = new LLPrefsChat();
- mTabContainer->addTabPanel(mPrefsChat->getPanel(), mPrefsChat->getPanel()->getLabel(), FALSE, onTabChanged, mTabContainer);
- mPrefsChat->getPanel()->setDefaultBtn(default_btn);
+bool extractWindowSizeFromString(const std::string& instr, U32 &width, U32 &height);
+void fractionFromDecimal(F32 decimal_val, S32& numerator, S32& denominator);
- mPrefsVoice = new LLPrefsVoice();
- mTabContainer->addTabPanel(mPrefsVoice, mPrefsVoice->getLabel(), FALSE, onTabChanged, mTabContainer);
- mPrefsVoice->setDefaultBtn(default_btn);
+viewer_media_t get_web_media()
+{
+ viewer_media_t media_source = LLViewerMedia::newMediaImpl("", LLUUID::null, 0, 0, 0, 0, "text/html");
+
+ return media_source;
+}
- mPrefsIM = new LLPrefsIM();
- mTabContainer->addTabPanel(mPrefsIM->getPanel(), mPrefsIM->getPanel()->getLabel(), FALSE, onTabChanged, mTabContainer);
- mPrefsIM->getPanel()->setDefaultBtn(default_btn);
-#if LL_LCD_COMPILE
+bool callback_clear_browser_cache(const LLSD& notification, const LLSD& response)
+{
+ S32 option = LLNotification::getSelectedOption(notification, response);
+ if ( option == 0 ) // YES
+ {
+ // clean web
+ viewer_media_t media_source = get_web_media();
+ if (media_source && media_source->hasMedia())
+ media_source->getMediaPlugin()->clear_cache();
+
+ // clean nav bar history
+ LLNavigationBar::getInstance()->clearHistoryCache();
+
+ // flag client texture cache for clearing next time the client runs
+ gSavedSettings.setBOOL("PurgeCacheOnNextStartup", TRUE);
+ LLNotifications::instance().add("CacheWillClear");
+ }
+
+ return false;
+}
- // only add this option if we actually have a logitech keyboard / speaker set
- if (gLcdScreen->Enabled())
+void handleNameTagOptionChanged(const LLSD& newvalue)
+{
+ S32 name_tag_option = S32(newvalue);
+ if(name_tag_option==2)
{
- mLCDPanel = new LLPanelLCD();
- mTabContainer->addTabPanel(mLCDPanel, mLCDPanel->getLabel(), FALSE, onTabChanged, mTabContainer);
- mLCDPanel->setDefaultBtn(default_btn);
+ gSavedSettings.setBOOL("SmallAvatarNames", TRUE);
}
+ else
+ {
+ gSavedSettings.setBOOL("SmallAvatarNames", FALSE);
+ }
+}
-#else
- mLCDPanel = NULL;
-#endif
+bool callback_skip_dialogs(const LLSD& notification, const LLSD& response, LLFloaterPreference* floater)
+{
+ S32 option = LLNotification::getSelectedOption(notification, response);
+ if (0 == option && floater )
+ {
+ if ( floater )
+ {
+ floater->setAllIgnored();
+ LLFirstUse::disableFirstUse();
+ LLFloaterPreference::buildLists(floater);
+ }
+ }
+ return false;
+}
- mMsgPanel = new LLPanelMsgs();
- mTabContainer->addTabPanel(mMsgPanel, mMsgPanel->getLabel(), FALSE, onTabChanged, mTabContainer);
- mMsgPanel->setDefaultBtn(default_btn);
-
- mSkinsPanel = new LLPanelSkins();
- mTabContainer->addTabPanel(mSkinsPanel, mSkinsPanel->getLabel(), FALSE, onTabChanged, mTabContainer);
- mSkinsPanel->setDefaultBtn(default_btn);
+bool callback_reset_dialogs(const LLSD& notification, const LLSD& response, LLFloaterPreference* floater)
+{
+ S32 option = LLNotification::getSelectedOption(notification, response);
+ if ( 0 == option && floater )
+ {
+ if ( floater )
+ {
+ floater->resetAllIgnored();
+ LLFirstUse::resetFirstUse();
+ LLFloaterPreference::buildLists(floater);
+ }
+ }
+ return false;
+}
- if (!mTabContainer->selectTab(gSavedSettings.getS32("LastPrefTab")))
+
+// Extract from strings of the form "<width> x <height>", e.g. "640 x 480".
+bool extractWindowSizeFromString(const std::string& instr, U32 &width, U32 &height)
+{
+ using namespace boost;
+ cmatch what;
+ const regex expression("([0-9]+) x ([0-9]+)");
+ if (regex_match(instr.c_str(), what, expression))
{
- mTabContainer->selectFirstTab();
+ width = atoi(what[1].first);
+ height = atoi(what[2].first);
+ return true;
}
+
+ width = height = 0;
+ return false;
}
-LLPreferenceCore::~LLPreferenceCore()
+void fractionFromDecimal(F32 decimal_val, S32& numerator, S32& denominator)
{
- if (mGeneralPanel)
+ numerator = 0;
+ denominator = 0;
+ for (F32 test_denominator = 1.f; test_denominator < 30.f; test_denominator += 1.f)
{
- delete mGeneralPanel;
- mGeneralPanel = NULL;
+ if (fmodf((decimal_val * test_denominator) + 0.01f, 1.f) < 0.02f)
+ {
+ numerator = llround(decimal_val * test_denominator);
+ denominator = llround(test_denominator);
+ break;
+ }
}
- if (mInputPanel)
+}
+// static
+std::string LLFloaterPreference::sSkin = "";
+F32 LLFloaterPreference::sAspectRatio = 0.0;
+//////////////////////////////////////////////
+// LLFloaterPreference
+
+LLFloaterPreference::LLFloaterPreference(const LLSD& key)
+ : LLFloater(key),
+ mGotPersonalInfo(false),
+ mOriginalIMViaEmail(false)
+{
+ //Build Floater is now Called from LLFloaterReg::add("preferences", "floater_preferences.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterPreference>);
+
+ static bool registered_dialog = false;
+ if (!registered_dialog)
{
- delete mInputPanel;
- mInputPanel = NULL;
+ LLFloaterReg::add("voice_set_key", "floater_select_key.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLVoiceSetKeyDialog>);
+ registered_dialog = true;
}
- if (mNetworkPanel)
+
+ mCommitCallbackRegistrar.add("Pref.Apply", boost::bind(&LLFloaterPreference::onBtnApply, this));
+ mCommitCallbackRegistrar.add("Pref.Cancel", boost::bind(&LLFloaterPreference::onBtnCancel, this));
+ mCommitCallbackRegistrar.add("Pref.OK", boost::bind(&LLFloaterPreference::onBtnOK, this));
+
+// mCommitCallbackRegistrar.add("Pref.ClearCache", boost::bind(&LLFloaterPreference::onClickClearCache, this));
+ mCommitCallbackRegistrar.add("Pref.WebClearCache", boost::bind(&LLFloaterPreference::onClickBrowserClearCache, this));
+ mCommitCallbackRegistrar.add("Pref.SetCache", boost::bind(&LLFloaterPreference::onClickSetCache, this));
+ mCommitCallbackRegistrar.add("Pref.ResetCache", boost::bind(&LLFloaterPreference::onClickResetCache, this));
+ mCommitCallbackRegistrar.add("Pref.ClickSkin", boost::bind(&LLFloaterPreference::onClickSkin, this,_1, _2));
+ mCommitCallbackRegistrar.add("Pref.SelectSkin", boost::bind(&LLFloaterPreference::onSelectSkin, this));
+ mCommitCallbackRegistrar.add("Pref.VoiceSetKey", boost::bind(&LLFloaterPreference::onClickSetKey, this));
+ mCommitCallbackRegistrar.add("Pref.VoiceSetMiddleMouse", boost::bind(&LLFloaterPreference::onClickSetMiddleMouse, this));
+ mCommitCallbackRegistrar.add("Pref.ClickSkipDialogs", boost::bind(&LLFloaterPreference::onClickSkipDialogs, this));
+ mCommitCallbackRegistrar.add("Pref.ClickResetDialogs", boost::bind(&LLFloaterPreference::onClickResetDialogs, this));
+ mCommitCallbackRegistrar.add("Pref.ClickEnablePopup", boost::bind(&LLFloaterPreference::onClickEnablePopup, this));
+ mCommitCallbackRegistrar.add("Pref.ClickDisablePopup", boost::bind(&LLFloaterPreference::onClickDisablePopup, this));
+ mCommitCallbackRegistrar.add("Pref.LogPath", boost::bind(&LLFloaterPreference::onClickLogPath, this));
+ mCommitCallbackRegistrar.add("Pref.Logging", boost::bind(&LLFloaterPreference::onCommitLogging, this));
+ mCommitCallbackRegistrar.add("Pref.OpenHelp", boost::bind(&LLFloaterPreference::onOpenHelp, this));
+ mCommitCallbackRegistrar.add("Pref.UpdateMeterText", boost::bind(&LLFloaterPreference::updateMeterText, this, _1));
+ mCommitCallbackRegistrar.add("Pref.HardwareSettings", boost::bind(&LLFloaterPreference::onOpenHardwareSettings, this));
+ mCommitCallbackRegistrar.add("Pref.HardwareDefaults", boost::bind(&LLFloaterPreference::setHardwareDefaults, this));
+ mCommitCallbackRegistrar.add("Pref.VertexShaderEnable", boost::bind(&LLFloaterPreference::onVertexShaderEnable, this));
+ mCommitCallbackRegistrar.add("Pref.WindowedMod", boost::bind(&LLFloaterPreference::onCommitWindowedMode, this));
+ mCommitCallbackRegistrar.add("Pref.UpdateSliderText", boost::bind(&LLFloaterPreference::onUpdateSliderText,this, _1,_2));
+ mCommitCallbackRegistrar.add("Pref.AutoDetectAspect", boost::bind(&LLFloaterPreference::onCommitAutoDetectAspect, this));
+ mCommitCallbackRegistrar.add("Pref.onSelectAspectRatio", boost::bind(&LLFloaterPreference::onKeystrokeAspectRatio, this));
+ mCommitCallbackRegistrar.add("Pref.QualityPerformance", boost::bind(&LLFloaterPreference::onChangeQuality, this, _2));
+
+ sSkin = gSavedSettings.getString("SkinCurrent");
+
+ gSavedSettings.getControl("AvatarNameTagMode")->getCommitSignal()->connect(boost::bind(&handleNameTagOptionChanged, _2));
+}
+
+BOOL LLFloaterPreference::postBuild()
+{
+ mCloseSignal.connect(boost::bind(&LLFloaterPreference::onClose, this));
+
+ LLTabContainer* tabcontainer = getChild<LLTabContainer>("pref core");
+ if (!tabcontainer->selectTab(gSavedSettings.getS32("LastPrefTab")))
+ tabcontainer->selectFirstTab();
+ S32 show_avatar_nametag_options = gSavedSettings.getS32("AvatarNameTagMode");
+ handleNameTagOptionChanged(LLSD(show_avatar_nametag_options));
+ return TRUE;
+}
+
+LLFloaterPreference::~LLFloaterPreference()
+{
+ // clean up user data
+ LLComboBox* ctrl_aspect_ratio = getChild<LLComboBox>( "aspect_ratio");
+ LLComboBox* ctrl_window_size = getChild<LLComboBox>("windowsize combo");
+ for (S32 i = 0; i < ctrl_aspect_ratio->getItemCount(); i++)
{
- delete mNetworkPanel;
- mNetworkPanel = NULL;
+ ctrl_aspect_ratio->setCurrentByIndex(i);
}
- if (mDisplayPanel)
+ for (S32 i = 0; i < ctrl_window_size->getItemCount(); i++)
{
- delete mDisplayPanel;
- mDisplayPanel = NULL;
+ ctrl_window_size->setCurrentByIndex(i);
}
+}
+void LLFloaterPreference::draw()
+{
+ BOOL has_first_selected = (getChildRef<LLScrollListCtrl>("disabled_popups").getFirstSelected()!=NULL);
+ gSavedSettings.setBOOL("FirstSelectedDisabledPopups", has_first_selected);
+
+ has_first_selected = (getChildRef<LLScrollListCtrl>("enabled_popups").getFirstSelected()!=NULL);
+ gSavedSettings.setBOOL("FirstSelectedEnabledPopups", has_first_selected);
+
+ LLFloater::draw();
+}
- if (mAudioPanel)
+void LLFloaterPreference::apply()
+{
+ LLTabContainer* tabcontainer = getChild<LLTabContainer>("pref core");
+ if (sSkin != gSavedSettings.getString("SkinCurrent"))
{
- delete mAudioPanel;
- mAudioPanel = NULL;
+ LLNotifications::instance().add("ChangeSkin");
+ refreshSkin(this);
}
- if (mPrefsChat)
+ // Call apply() on all panels that derive from LLPanelPreference
+ for (child_list_t::const_iterator iter = tabcontainer->getChildList()->begin();
+ iter != tabcontainer->getChildList()->end(); ++iter)
{
- delete mPrefsChat;
- mPrefsChat = NULL;
+ LLView* view = *iter;
+ LLPanelPreference* panel = dynamic_cast<LLPanelPreference*>(view);
+ if (panel)
+ panel->apply();
}
- if (mPrefsIM)
+ // hardware menu apply
+ LLFloaterHardwareSettings* hardware_settings = LLFloaterReg::getTypedInstance<LLFloaterHardwareSettings>("prefs_hardware_settings");
+ if (hardware_settings)
{
- delete mPrefsIM;
- mPrefsIM = NULL;
+ hardware_settings->apply();
}
- if (mMsgPanel)
+
+ LLFloaterVoiceDeviceSettings* voice_device_settings = LLFloaterReg::findTypedInstance<LLFloaterVoiceDeviceSettings>("pref_voicedevicesettings");
+ if(voice_device_settings)
{
- delete mMsgPanel;
- mMsgPanel = NULL;
+ voice_device_settings->apply();
}
- if (mWebPanel)
+
+ gViewerWindow->requestResolutionUpdate(); // for UIScaleFactor
+
+ LLSliderCtrl* fov_slider = getChild<LLSliderCtrl>("camera_fov");
+ fov_slider->setMinValue(LLViewerCamera::getInstance()->getMinView());
+ fov_slider->setMaxValue(LLViewerCamera::getInstance()->getMaxView());
+
+ std::string cache_location = gDirUtilp->getExpandedFilename(LL_PATH_CACHE, "");
+ childSetText("cache_location", cache_location);
+
+ viewer_media_t media_source = get_web_media();
+ if (media_source && media_source->hasMedia())
{
- delete mWebPanel;
- mWebPanel = NULL;
+ media_source->getMediaPlugin()->enable_cookies(childGetValue("cookies_enabled"));
+ if(hasChild("web_proxy_enabled") &&hasChild("web_proxy_editor") && hasChild("web_proxy_port"))
+ {
+ bool proxy_enable = childGetValue("web_proxy_enabled");
+ std::string proxy_address = childGetValue("web_proxy_editor");
+ int proxy_port = childGetValue("web_proxy_port");
+ media_source->getMediaPlugin()->proxy_setup(proxy_enable, proxy_address, proxy_port);
+ }
}
- if (mSkinsPanel)
+
+// LLWString busy_response = utf8str_to_wstring(getChild<LLUICtrl>("busy_response")->getValue().asString());
+// LLWStringUtil::replaceTabsWithSpaces(busy_response, 4);
+
+ if(mGotPersonalInfo)
+ {
+// gSavedSettings.setString("BusyModeResponse2", std::string(wstring_to_utf8str(busy_response)));
+ bool new_im_via_email = childGetValue("send_im_to_email").asBoolean();
+ bool new_hide_online = childGetValue("online_visibility").asBoolean();
+
+ if((new_im_via_email != mOriginalIMViaEmail)
+ ||(new_hide_online != mOriginalHideOnlineStatus))
+ {
+ // This hack is because we are representing several different
+ // possible strings with a single checkbox. Since most users
+ // can only select between 2 values, we represent it as a
+ // checkbox. This breaks down a little bit for liaisons, but
+ // works out in the end.
+ if(new_hide_online != mOriginalHideOnlineStatus)
+ {
+ if(new_hide_online) mDirectoryVisibility = VISIBILITY_HIDDEN;
+ else mDirectoryVisibility = VISIBILITY_DEFAULT;
+ //Update showonline value, otherwise multiple applys won't work
+ mOriginalHideOnlineStatus = new_hide_online;
+ }
+ gAgent.sendAgentUpdateUserInfo(new_im_via_email,mDirectoryVisibility);
+ }
+ }
+
+ applyResolution();
+
+ // Only set window size if we're not in fullscreen mode
+ if(!gSavedSettings.getBOOL("WindowFullScreen"))
{
- delete mSkinsPanel;
- mSkinsPanel = NULL;
+ applyWindowSize();
}
+
+}
+
+void LLFloaterPreference::cancel()
+{
+ LLTabContainer* tabcontainer = getChild<LLTabContainer>("pref core");
+ // Call cancel() on all panels that derive from LLPanelPreference
+ for (child_list_t::const_iterator iter = tabcontainer->getChildList()->begin();
+ iter != tabcontainer->getChildList()->end(); ++iter)
+ {
+ LLView* view = *iter;
+ LLPanelPreference* panel = dynamic_cast<LLPanelPreference*>(view);
+ if (panel)
+ panel->cancel();
+ }
+ // hide joystick pref floater
+ LLFloaterReg::hideInstance("pref_joystick");
+
+ // cancel hardware menu
+ LLFloaterHardwareSettings* hardware_settings = LLFloaterReg::getTypedInstance<LLFloaterHardwareSettings>("prefs_hardware_settings");
+ if (hardware_settings)
+ {
+ hardware_settings->cancel();
+ }
+
+ // reverts any changes to current skin
+ gSavedSettings.setString("SkinCurrent", sSkin);
+
+ LLFloaterVoiceDeviceSettings* voice_device_settings = LLFloaterReg::findTypedInstance<LLFloaterVoiceDeviceSettings>("pref_voicedevicesettings");
+ if (voice_device_settings)
+ {
+ voice_device_settings ->cancel();
+ }
+
+ LLFloaterReg::hideInstance("pref_voicedevicesettings");
+
+ gSavedSettings.setF32("FullScreenAspectRatio", sAspectRatio);
}
+void LLFloaterPreference::onOpen(const LLSD& key)
+{
+ gAgent.sendAgentUserInfoRequest();
+ LLPanelLogin::setAlwaysRefresh(true);
+ refresh();
+}
-void LLPreferenceCore::apply()
+void LLFloaterPreference::onVertexShaderEnable()
{
- mGeneralPanel->apply();
- mInputPanel->apply();
- mNetworkPanel->apply();
- mDisplayPanel->apply();
- mAudioPanel->apply();
- mPrefsChat->apply();
- mPrefsVoice->apply();
- mPrefsIM->apply();
- mMsgPanel->apply();
- mSkinsPanel->apply();
+ refreshEnabledGraphics();
+}
- // hardware menu apply
- LLFloaterHardwareSettings::instance()->apply();
+void LLFloaterPreference::setHardwareDefaults()
+{
+ LLFeatureManager::getInstance()->applyRecommendedSettings();
+ refreshEnabledGraphics();
+}
- mWebPanel->apply();
-#if LL_LCD_COMPILE
- // only add this option if we actually have a logitech keyboard / speaker set
- if (gLcdScreen->Enabled())
+void LLFloaterPreference::onClose()
+{
+ gSavedSettings.setS32("LastPrefTab", getChild<LLTabContainer>("pref core")->getCurrentPanelIndex());
+ LLPanelLogin::setAlwaysRefresh(false);
+ cancel(); // will be a no-op if OK or apply was performed just prior.
+}
+
+void LLFloaterPreference::onOpenHardwareSettings()
+{
+ LLFloaterReg::showInstance("prefs_hardware_settings");
+}
+// static
+void LLFloaterPreference::onBtnOK()
+{
+ // commit any outstanding text entry
+ if (hasFocus())
+ {
+ LLUICtrl* cur_focus = dynamic_cast<LLUICtrl*>(gFocusMgr.getKeyboardFocus());
+ if (cur_focus->acceptsTextInput())
+ {
+ cur_focus->onCommit();
+ }
+ }
+
+ if (canClose())
+ {
+ apply();
+ closeFloater(false);
+ gSavedSettings.saveToFile( gSavedSettings.getString("ClientSettingsFile"), TRUE );
+ LLUIColorTable::instance().saveUserSettings();
+ std::string crash_settings_filename = gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS, CRASH_SETTINGS_FILE);
+ // save all settings, even if equals defaults
+ gCrashSettings.saveToFile(crash_settings_filename, FALSE);
+ }
+ else
{
- mLCDPanel->apply();
+ // Show beep, pop up dialog, etc.
+ llinfos << "Can't close preferences!" << llendl;
}
-#endif
-// mWebPanel->apply();
+
+ LLPanelLogin::refreshLocation( false );
}
+void LLFloaterPreference::onOpenHelp()
+{
+ const char* xml_alert = "GraphicsPreferencesHelp";
+ LLNotifications::instance().add(this->contextualNotification(xml_alert));
+}
-void LLPreferenceCore::cancel()
+// static
+void LLFloaterPreference::onBtnApply( )
{
- mGeneralPanel->cancel();
- mInputPanel->cancel();
- mNetworkPanel->cancel();
- mDisplayPanel->cancel();
- mAudioPanel->cancel();
- mPrefsChat->cancel();
- mPrefsVoice->cancel();
- mPrefsIM->cancel();
- mMsgPanel->cancel();
- mSkinsPanel->cancel();
+ if (hasFocus())
+ {
+ LLUICtrl* cur_focus = dynamic_cast<LLUICtrl*>(gFocusMgr.getKeyboardFocus());
+ if (cur_focus->acceptsTextInput())
+ {
+ cur_focus->onCommit();
+ }
+ }
+ apply();
- // cancel hardware menu
- LLFloaterHardwareSettings::instance()->cancel();
+ LLPanelLogin::refreshLocation( false );
+}
- mWebPanel->cancel();
-#if LL_LCD_COMPILE
- // only add this option if we actually have a logitech keyboard / speaker set
- if (gLcdScreen->Enabled())
+// static
+void LLFloaterPreference::onBtnCancel()
+{
+ if (hasFocus())
{
- mLCDPanel->cancel();
+ LLUICtrl* cur_focus = dynamic_cast<LLUICtrl*>(gFocusMgr.getKeyboardFocus());
+ if (cur_focus->acceptsTextInput())
+ {
+ cur_focus->onCommit();
+ }
+ refresh();
}
-#endif
-// mWebPanel->cancel();
+ closeFloater(); // side effect will also cancel any unsaved changes.
}
-// static
-void LLPreferenceCore::onTabChanged(void* user_data, bool from_click)
+// static
+void LLFloaterPreference::updateUserInfo(const std::string& visibility, bool im_via_email, const std::string& email)
{
- LLTabContainer* self = (LLTabContainer*)user_data;
-
- gSavedSettings.setS32("LastPrefTab", self->getCurrentPanelIndex());
+ LLFloaterPreference* instance = LLFloaterReg::findTypedInstance<LLFloaterPreference>("preferences");
+ if(instance)
+ {
+ instance->setPersonalInfo(visibility, im_via_email, email);
+ }
}
-void LLPreferenceCore::setPersonalInfo(const std::string& visibility, bool im_via_email, const std::string& email)
+void LLFloaterPreference::refreshEnabledGraphics()
{
- mPrefsIM->setPersonalInfo(visibility, im_via_email, email);
+ LLFloaterPreference* instance = LLFloaterReg::findTypedInstance<LLFloaterPreference>("preferences");
+ if(instance)
+ {
+ instance->refreshEnabledState();
+ }
+ LLFloaterHardwareSettings* hardware_settings = LLFloaterReg::getTypedInstance<LLFloaterHardwareSettings>("prefs_hardware_settings");
+ if (hardware_settings)
+ {
+ hardware_settings->refreshEnabledState();
+ }
}
-void LLPreferenceCore::refreshEnabledGraphics()
+void LLFloaterPreference::updateMeterText(LLUICtrl* ctrl)
{
- LLFloaterHardwareSettings::instance()->refreshEnabledState();
- mDisplayPanel->refreshEnabledState();
-}
+ // get our UI widgets
+ LLSliderCtrl* slider = (LLSliderCtrl*) ctrl;
-//////////////////////////////////////////////
-// LLFloaterPreference
+ LLTextBox* m1 = getChild<LLTextBox>("DrawDistanceMeterText1");
+ LLTextBox* m2 = getChild<LLTextBox>("DrawDistanceMeterText2");
-LLFloaterPreference::LLFloaterPreference()
+ // toggle the two text boxes based on whether we have 1 or two digits
+ F32 val = slider->getValueF32();
+ bool two_digits = val < 100;
+ m1->setVisible(two_digits);
+ m2->setVisible(!two_digits);
+}
+/*
+void LLFloaterPreference::onClickClearCache()
{
- LLUICtrlFactory::getInstance()->buildFloater(this, "floater_preferences.xml");
+ // flag client cache for clearing next time the client runs
+ gSavedSettings.setBOOL("PurgeCacheOnNextStartup", TRUE);
+ LLNotifications::instance().add("CacheWillClear");
}
+*/
-BOOL LLFloaterPreference::postBuild()
+void LLFloaterPreference::onClickBrowserClearCache()
+{
+ LLNotifications::instance().add("ConfirmClearBrowserCache", LLSD(), LLSD(), callback_clear_browser_cache);
+}
+
+void LLFloaterPreference::onClickSetCache()
{
- requires<LLButton>("About...");
- requires<LLButton>("OK");
- requires<LLButton>("Cancel");
- requires<LLButton>("Apply");
- requires<LLTabContainer>("pref core");
+ std::string cur_name(gSavedSettings.getString("CacheLocation"));
+// std::string cur_top_folder(gDirUtilp->getBaseFileName(cur_name));
+
+ std::string proposed_name(cur_name);
- if (!checkRequirements())
+ LLDirPicker& picker = LLDirPicker::instance();
+ if (! picker.getDir(&proposed_name ) )
{
- return FALSE;
+ return; //Canceled!
}
- mAboutBtn = getChild<LLButton>("About...");
- mAboutBtn->setClickedCallback(onClickAbout, this);
+ std::string dir_name = picker.getDirName();
+ if (!dir_name.empty() && dir_name != cur_name)
+ {
+ std::string new_top_folder(gDirUtilp->getBaseFileName(dir_name));
+ LLNotifications::instance().add("CacheWillBeMoved");
+ gSavedSettings.setString("NewCacheLocation", dir_name);
+ gSavedSettings.setString("NewCacheLocationTopFolder", new_top_folder);
+ }
+ else
+ {
+ std::string cache_location = gDirUtilp->getCacheDir();
+ gSavedSettings.setString("CacheLocation", cache_location);
+ std::string top_folder(gDirUtilp->getBaseFileName(cache_location));
+ gSavedSettings.setString("CacheLocationTopFolder", top_folder);
+ }
+}
+
+void LLFloaterPreference::onClickResetCache()
+{
+ if (!gSavedSettings.getString("CacheLocation").empty())
+ {
+ gSavedSettings.setString("NewCacheLocation", "");
+ gSavedSettings.setString("NewCacheLocationTopFolder", "");
+ LLNotifications::instance().add("CacheWillBeMoved");
+ }
+ std::string cache_location = gDirUtilp->getCacheDir(true);
+ gSavedSettings.setString("CacheLocation", cache_location);
+ std::string top_folder(gDirUtilp->getBaseFileName(cache_location));
+ gSavedSettings.setString("CacheLocationTopFolder", top_folder);
+}
+
+void LLFloaterPreference::onClickSkin(LLUICtrl* ctrl, const LLSD& userdata)
+{
+ gSavedSettings.setString("SkinCurrent", userdata.asString());
+ ctrl->setValue(userdata.asString());
+}
+
+void LLFloaterPreference::onSelectSkin()
+{
+ std::string skin_selection = getChild<LLRadioGroup>("skin_selection")->getValue().asString();
+ gSavedSettings.setString("SkinCurrent", skin_selection);
+}
+
+void LLFloaterPreference::refreshSkin(void* data)
+{
+ LLPanel*self = (LLPanel*)data;
+ sSkin = gSavedSettings.getString("SkinCurrent");
+ self->getChild<LLRadioGroup>("skin_selection", true)->setValue(sSkin);
+}
+
+// static
+void LLFloaterPreference::buildLists(void* data)
+{
+ LLPanel*self = (LLPanel*)data;
+ LLScrollListCtrl& disabled_popups = self->getChildRef<LLScrollListCtrl>("disabled_popups");
+ LLScrollListCtrl& enabled_popups = self->getChildRef<LLScrollListCtrl>("enabled_popups");
- mApplyBtn = getChild<LLButton>("Apply");
- mApplyBtn->setClickedCallback(onBtnApply, this);
+ disabled_popups.deleteAllItems();
+ enabled_popups.deleteAllItems();
+
+ for (LLNotifications::TemplateMap::const_iterator iter = LLNotifications::instance().templatesBegin();
+ iter != LLNotifications::instance().templatesEnd();
+ ++iter)
+ {
+ LLNotificationTemplatePtr templatep = iter->second;
+ LLNotificationFormPtr formp = templatep->mForm;
+
+ LLNotificationForm::EIgnoreType ignore = formp->getIgnoreType();
+ if (ignore == LLNotificationForm::IGNORE_NO)
+ continue;
+
+ LLSD row;
+ row["columns"][0]["value"] = formp->getIgnoreMessage();
+ row["columns"][0]["font"] = "SANSSERIF_SMALL";
+ row["columns"][0]["width"] = 400;
- mCancelBtn = getChild<LLButton>("Cancel");
- mCancelBtn->setClickedCallback(onBtnCancel, this);
+ LLScrollListItem* item = NULL;
+
+ bool show_popup = LLUI::sSettingGroups["ignores"]->getBOOL(templatep->mName);
+ if (!show_popup)
+ {
+ if (ignore == LLNotificationForm::IGNORE_WITH_LAST_RESPONSE)
+ {
+ LLSD last_response = LLUI::sSettingGroups["config"]->getLLSD("Default" + templatep->mName);
+ if (!last_response.isUndefined())
+ {
+ for (LLSD::map_const_iterator it = last_response.beginMap();
+ it != last_response.endMap();
+ ++it)
+ {
+ if (it->second.asBoolean())
+ {
+ row["columns"][1]["value"] = formp->getElement(it->first)["ignore"].asString();
+ break;
+ }
+ }
+ }
+ row["columns"][1]["font"] = "SANSSERIF_SMALL";
+ row["columns"][1]["width"] = 360;
+ }
+ item = disabled_popups.addElement(row,
+ ADD_SORTED);
+ }
+ else
+ {
+ item = enabled_popups.addElement(row,
+ ADD_SORTED);
+ }
+
+ if (item)
+ {
+ item->setUserdata((void*)&iter->first);
+ }
+ }
+}
- mOKBtn = getChild<LLButton>("OK");
- mOKBtn->setClickedCallback(onBtnOK, this);
-
- mPreferenceCore = new LLPreferenceCore(
- getChild<LLTabContainer>("pref core"),
- getChild<LLButton>("OK")
- );
+void LLFloaterPreference::refreshEnabledState()
+{
+
+ LLCheckBoxCtrl* ctrl_reflections = getChild<LLCheckBoxCtrl>("Reflections");
+ LLRadioGroup* radio_reflection_detail = getChild<LLRadioGroup>("ReflectionDetailRadio");
+
+ // Reflections
+ BOOL reflections = gSavedSettings.getBOOL("VertexShaderEnable")
+ && gGLManager.mHasCubeMap
+ && LLCubeMap::sUseCubeMaps;
+ ctrl_reflections->setEnabled(reflections);
+
+ // Bump & Shiny
+ bool bumpshiny = gGLManager.mHasCubeMap && LLCubeMap::sUseCubeMaps && LLFeatureManager::getInstance()->isFeatureAvailable("RenderObjectBump");
+ getChild<LLCheckBoxCtrl>("BumpShiny")->setEnabled(bumpshiny ? TRUE : FALSE);
+
+ for (S32 i = 0; i < radio_reflection_detail->getItemCount(); ++i)
+ {
+ radio_reflection_detail->setIndexEnabled(i, ctrl_reflections->get() && reflections);
+ }
+
+ // Avatar Mode
+ // Enable Avatar Shaders
+ LLCheckBoxCtrl* ctrl_avatar_vp = getChild<LLCheckBoxCtrl>("AvatarVertexProgram");
+ // Avatar Render Mode
+ LLCheckBoxCtrl* ctrl_avatar_cloth = getChild<LLCheckBoxCtrl>("AvatarCloth");
+
+ S32 max_avatar_shader = LLViewerShaderMgr::instance()->mMaxAvatarShaderLevel;
+ ctrl_avatar_vp->setEnabled((max_avatar_shader > 0) ? TRUE : FALSE);
+
+ if (gSavedSettings.getBOOL("VertexShaderEnable") == FALSE ||
+ gSavedSettings.getBOOL("RenderAvatarVP") == FALSE)
+ {
+ ctrl_avatar_cloth->setEnabled(false);
+ }
+ else
+ {
+ ctrl_avatar_cloth->setEnabled(true);
+ }
- sInstance = this;
+ // Vertex Shaders
+ // Global Shader Enable
+ LLCheckBoxCtrl* ctrl_shader_enable = getChild<LLCheckBoxCtrl>("BasicShaders");
+ // radio set for terrain detail mode
+ LLRadioGroup* mRadioTerrainDetail = getChild<LLRadioGroup>("TerrainDetailRadio"); // can be linked with control var
- return TRUE;
+ ctrl_shader_enable->setEnabled(LLFeatureManager::getInstance()->isFeatureAvailable("VertexShaderEnable"));
+
+ BOOL shaders = ctrl_shader_enable->get();
+ if (shaders)
+ {
+ mRadioTerrainDetail->setValue(1);
+ mRadioTerrainDetail->setEnabled(FALSE);
+ }
+ else
+ {
+ mRadioTerrainDetail->setEnabled(TRUE);
+ }
+
+ // WindLight
+ LLCheckBoxCtrl* ctrl_wind_light = getChild<LLCheckBoxCtrl>("WindLightUseAtmosShaders");
+
+ // *HACK just checks to see if we can use shaders...
+ // maybe some cards that use shaders, but don't support windlight
+ ctrl_wind_light->setEnabled(ctrl_shader_enable->getEnabled() && shaders);
+ // now turn off any features that are unavailable
+ disableUnavailableSettings();
}
+void LLFloaterPreference::disableUnavailableSettings()
+{
+ LLCheckBoxCtrl* ctrl_reflections = getChild<LLCheckBoxCtrl>("Reflections");
+ LLCheckBoxCtrl* ctrl_avatar_vp = getChild<LLCheckBoxCtrl>("AvatarVertexProgram");
+ LLCheckBoxCtrl* ctrl_avatar_cloth = getChild<LLCheckBoxCtrl>("AvatarCloth");
+ LLCheckBoxCtrl* ctrl_shader_enable = getChild<LLCheckBoxCtrl>("BasicShaders");
+ LLCheckBoxCtrl* ctrl_wind_light = getChild<LLCheckBoxCtrl>("WindLightUseAtmosShaders");
+ LLCheckBoxCtrl* ctrl_avatar_impostors = getChild<LLCheckBoxCtrl>("AvatarImpostors");
+
+ // if vertex shaders off, disable all shader related products
+ if(!LLFeatureManager::getInstance()->isFeatureAvailable("VertexShaderEnable"))
+ {
+ ctrl_shader_enable->setEnabled(FALSE);
+ ctrl_shader_enable->setValue(FALSE);
+
+ ctrl_wind_light->setEnabled(FALSE);
+ ctrl_wind_light->setValue(FALSE);
+
+ ctrl_reflections->setEnabled(FALSE);
+ ctrl_reflections->setValue(FALSE);
+
+ ctrl_avatar_vp->setEnabled(FALSE);
+ ctrl_avatar_vp->setValue(FALSE);
+
+ ctrl_avatar_cloth->setEnabled(FALSE);
+ ctrl_avatar_cloth->setValue(FALSE);
+ }
+
+ // disabled windlight
+ if(!LLFeatureManager::getInstance()->isFeatureAvailable("WindLightUseAtmosShaders"))
+ {
+ ctrl_wind_light->setEnabled(FALSE);
+ ctrl_wind_light->setValue(FALSE);
+ }
+
+ // disabled reflections
+ if(!LLFeatureManager::getInstance()->isFeatureAvailable("RenderWaterReflections"))
+ {
+ ctrl_reflections->setEnabled(FALSE);
+ ctrl_reflections->setValue(FALSE);
+ }
+
+ // disabled av
+ if(!LLFeatureManager::getInstance()->isFeatureAvailable("RenderAvatarVP"))
+ {
+ ctrl_avatar_vp->setEnabled(FALSE);
+ ctrl_avatar_vp->setValue(FALSE);
+
+ ctrl_avatar_cloth->setEnabled(FALSE);
+ ctrl_avatar_cloth->setValue(FALSE);
+ }
+ // disabled cloth
+ if(!LLFeatureManager::getInstance()->isFeatureAvailable("RenderAvatarCloth"))
+ {
+ ctrl_avatar_cloth->setEnabled(FALSE);
+ ctrl_avatar_cloth->setValue(FALSE);
+ }
+ // disabled impostors
+ if(!LLFeatureManager::getInstance()->isFeatureAvailable("RenderUseImpostors"))
+ {
+ ctrl_avatar_impostors->setEnabled(FALSE);
+ ctrl_avatar_impostors->setValue(FALSE);
+ }
+}
-LLFloaterPreference::~LLFloaterPreference()
+void LLFloaterPreference::onCommitAutoDetectAspect()
{
- sInstance = NULL;
- delete mPreferenceCore;
+ BOOL auto_detect = getChild<LLCheckBoxCtrl>("aspect_auto_detect")->get();
+ F32 ratio;
+
+ if (auto_detect)
+ {
+ S32 numerator = 0;
+ S32 denominator = 0;
+
+ // clear any aspect ratio override
+ gViewerWindow->mWindow->setNativeAspectRatio(0.f);
+ fractionFromDecimal(gViewerWindow->mWindow->getNativeAspectRatio(), numerator, denominator);
+
+ std::string aspect;
+ if (numerator != 0)
+ {
+ aspect = llformat("%d:%d", numerator, denominator);
+ }
+ else
+ {
+ aspect = llformat("%.3f", gViewerWindow->mWindow->getNativeAspectRatio());
+ }
+
+ getChild<LLComboBox>( "aspect_ratio")->setLabel(aspect);
+
+ ratio = gViewerWindow->mWindow->getNativeAspectRatio();
+ gSavedSettings.setF32("FullScreenAspectRatio", ratio);
+ }
}
-void LLFloaterPreference::apply()
+void LLFloaterPreference::refresh()
{
- this->mPreferenceCore->apply();
+ LLPanel::refresh();
+
+ // sliders and their text boxes
+ // mPostProcess = gSavedSettings.getS32("RenderGlowResolutionPow");
+ // slider text boxes
+ updateSliderText(getChild<LLSliderCtrl>("ObjectMeshDetail", true), getChild<LLTextBox>("ObjectMeshDetailText", true));
+ updateSliderText(getChild<LLSliderCtrl>("FlexibleMeshDetail", true), getChild<LLTextBox>("FlexibleMeshDetailText", true));
+ updateSliderText(getChild<LLSliderCtrl>("TreeMeshDetail", true), getChild<LLTextBox>("TreeMeshDetailText", true));
+ updateSliderText(getChild<LLSliderCtrl>("AvatarMeshDetail", true), getChild<LLTextBox>("AvatarMeshDetailText", true));
+ updateSliderText(getChild<LLSliderCtrl>("TerrainMeshDetail", true), getChild<LLTextBox>("TerrainMeshDetailText", true));
+ updateSliderText(getChild<LLSliderCtrl>("RenderPostProcess", true), getChild<LLTextBox>("PostProcessText", true));
+ updateSliderText(getChild<LLSliderCtrl>("SkyMeshDetail", true), getChild<LLTextBox>("SkyMeshDetailText", true));
+
+ refreshEnabledState();
}
-
-void LLFloaterPreference::cancel()
+void LLFloaterPreference::onCommitWindowedMode()
{
- this->mPreferenceCore->cancel();
+ refresh();
}
+void LLFloaterPreference::onChangeQuality(const LLSD& data)
+{
+ U32 level = (U32)(data.asReal());
+ LLFeatureManager::getInstance()->setGraphicsLevel(level, true);
+ refreshEnabledGraphics();
+ refresh();
+}
// static
-void LLFloaterPreference::show(void*)
+// DEV-24146 - needs to be removed at a later date. jan-2009
+void LLFloaterPreference::cleanupBadSetting()
{
- if (!sInstance)
+ if (gSavedPerAccountSettings.getString("BusyModeResponse2") == "|TOKEN COPY BusyModeResponse|")
{
- new LLFloaterPreference();
- sInstance->center();
+ llwarns << "cleaning old BusyModeResponse" << llendl;
+ gSavedPerAccountSettings.setString("BusyModeResponse2", gSavedPerAccountSettings.getText("BusyModeResponse"));
}
+}
- sInstance->open(); /* Flawfinder: ignore */
-
- if(!gAgent.getID().isNull())
+void LLFloaterPreference::onClickSetKey()
+{
+ LLVoiceSetKeyDialog* dialog = LLFloaterReg::showTypedInstance<LLVoiceSetKeyDialog>("voice_set_key", LLSD(), TRUE);
+ if (dialog)
{
- // we're logged in, so we can get this info.
- gMessageSystem->newMessageFast(_PREHASH_UserInfoRequest);
- gMessageSystem->nextBlockFast(_PREHASH_AgentData);
- gMessageSystem->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
- gMessageSystem->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
- gAgent.sendReliableMessage();
+ dialog->setParent(this);
}
+}
- LLPanelLogin::setAlwaysRefresh(true);
+void LLFloaterPreference::setKey(KEY key)
+{
+ childSetValue("modifier_combo", LLKeyboard::stringFromKey(key));
}
+void LLFloaterPreference::onClickSetMiddleMouse()
+{
+ childSetValue("modifier_combo", "MiddleMouse");
+}
-// static
-void LLFloaterPreference::onClickAbout(void*)
+void LLFloaterPreference::onClickSkipDialogs()
+{
+ LLNotifications::instance().add("SkipShowNextTimeDialogs", LLSD(), LLSD(), boost::bind(&callback_skip_dialogs, _1, _2, this));
+}
+
+void LLFloaterPreference::onClickResetDialogs()
{
- LLFloaterAbout::show(NULL);
+ LLNotifications::instance().add("ResetShowNextTimeDialogs", LLSD(), LLSD(), boost::bind(&callback_reset_dialogs, _1, _2, this));
}
+void LLFloaterPreference::onClickEnablePopup()
+{
+ LLScrollListCtrl& disabled_popups = getChildRef<LLScrollListCtrl>("disabled_popups");
+
+ std::vector<LLScrollListItem*> items = disabled_popups.getAllSelected();
+ std::vector<LLScrollListItem*>::iterator itor;
+ for (itor = items.begin(); itor != items.end(); ++itor)
+ {
+ LLNotificationTemplatePtr templatep = LLNotifications::instance().getTemplate(*(std::string*)((*itor)->getUserdata()));
+ //gSavedSettings.setWarning(templatep->mName, TRUE);
+ std::string notification_name = templatep->mName;
+ LLUI::sSettingGroups["ignores"]->setBOOL(notification_name, TRUE);
+ }
+
+ buildLists(this);
+}
-// static
-void LLFloaterPreference::onBtnOK( void* userdata )
+void LLFloaterPreference::onClickDisablePopup()
+{
+ LLScrollListCtrl& enabled_popups = getChildRef<LLScrollListCtrl>("enabled_popups");
+
+ std::vector<LLScrollListItem*> items = enabled_popups.getAllSelected();
+ std::vector<LLScrollListItem*>::iterator itor;
+ for (itor = items.begin(); itor != items.end(); ++itor)
+ {
+ LLNotificationTemplatePtr templatep = LLNotifications::instance().getTemplate(*(std::string*)((*itor)->getUserdata()));
+ //gSavedSettings.setWarning(templatep->mName, TRUE);
+ std::string notification_name = templatep->mName;
+ LLUI::sSettingGroups["ignores"]->setBOOL(notification_name, FALSE);
+ }
+
+ buildLists(this);
+}
+void LLFloaterPreference::resetAllIgnored()
{
- LLFloaterPreference *fp =(LLFloaterPreference *)userdata;
- // commit any outstanding text entry
- if (fp->hasFocus())
+ for (LLNotifications::TemplateMap::const_iterator iter = LLNotifications::instance().templatesBegin();
+ iter != LLNotifications::instance().templatesEnd();
+ ++iter)
{
- LLUICtrl* cur_focus = gFocusMgr.getKeyboardFocus();
- if (cur_focus->acceptsTextInput())
+ if (iter->second->mForm->getIgnoreType() != LLNotificationForm::IGNORE_NO)
{
- cur_focus->onCommit();
+ LLUI::sSettingGroups["ignores"]->setBOOL(iter->first, TRUE);
}
}
+}
- if (fp->canClose())
+void LLFloaterPreference::setAllIgnored()
+{
+ for (LLNotifications::TemplateMap::const_iterator iter = LLNotifications::instance().templatesBegin();
+ iter != LLNotifications::instance().templatesEnd();
+ ++iter)
{
- fp->apply();
- fp->close(false);
+ if (iter->second->mForm->getIgnoreType() != LLNotificationForm::IGNORE_NO)
+ {
+ LLUI::sSettingGroups["ignores"]->setBOOL(iter->first, FALSE);
+ }
+ }
+}
- gSavedSettings.saveToFile( gSavedSettings.getString("ClientSettingsFile"), TRUE );
-
- std::string crash_settings_filename = gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS, CRASH_SETTINGS_FILE);
- // save all settings, even if equals defaults
- gCrashSettings.saveToFile(crash_settings_filename, FALSE);
+void LLFloaterPreference::onClickLogPath()
+{
+ std::string proposed_name(gSavedPerAccountSettings.getString("InstantMessageLogPath"));
+
+ LLDirPicker& picker = LLDirPicker::instance();
+ if (!picker.getDir(&proposed_name ) )
+ {
+ return; //Canceled!
+ }
+ std::string chat_log_dir = picker.getDirName();
+ std::string chat_log_top_folder= gDirUtilp->getBaseFileName(chat_log_dir);
+ gSavedPerAccountSettings.setString("InstantMessageLogPath",chat_log_dir);
+ gSavedPerAccountSettings.setString("InstantMessageLogFolder",chat_log_top_folder);
+}
+
+void LLFloaterPreference::onCommitLogging()
+{
+ enableHistory();
+}
+
+void LLFloaterPreference::enableHistory()
+{
+ if (childGetValue("log_instant_messages").asBoolean())
+ {
+ childEnable("ChatIMLogs");
+ childEnable("log_path_button");
+ childEnable("show_timestamps_check_im");
}
else
{
- // Show beep, pop up dialog, etc.
- llinfos << "Can't close preferences!" << llendl;
+ childDisable("ChatIMLogs");
+ childDisable("log_path_button");
+ childDisable("show_timestamps_check_im");
+ }
+}
+
+void LLFloaterPreference::setPersonalInfo(const std::string& visibility, bool im_via_email, const std::string& email)
+{
+ mGotPersonalInfo = true;
+ mOriginalIMViaEmail = im_via_email;
+ mDirectoryVisibility = visibility;
+
+ if(visibility == VISIBILITY_DEFAULT)
+ {
+ mOriginalHideOnlineStatus = false;
+ childEnable("online_visibility");
}
+ else if(visibility == VISIBILITY_HIDDEN)
+ {
+ mOriginalHideOnlineStatus = true;
+ childEnable("online_visibility");
+ }
+ else
+ {
+ mOriginalHideOnlineStatus = true;
+ }
+
+ childEnable("include_im_in_chat_history");
+ childEnable("show_timestamps_check_im");
+ childEnable("friends_online_notify_checkbox");
+
+ childSetValue("online_visibility", mOriginalHideOnlineStatus);
+ childSetLabelArg("online_visibility", "[DIR_VIS]", mDirectoryVisibility);
+ childEnable("send_im_to_email");
+ childSetValue("send_im_to_email", im_via_email);
+ childEnable("log_instant_messages");
+// childEnable("log_chat");
+// childEnable("busy_response");
+// childEnable("log_instant_messages_timestamp");
+// childEnable("log_chat_timestamp");
+ childEnable("log_chat_IM");
+ childEnable("log_date_timestamp");
+
+// childSetText("busy_response", gSavedSettings.getString("BusyModeResponse2"));
+
+ enableHistory();
+ std::string display_email(email);
+ childSetText("email_address",display_email);
- LLPanelLogin::refreshLocation( false );
}
+void LLFloaterPreference::onUpdateSliderText(LLUICtrl* ctrl, const LLSD& name)
+{
+ std::string ctrl_name = name.asString();
+
+ if((ctrl_name =="" )|| !hasChild(ctrl_name, true))
+ return;
+
+ LLTextBox* text_box = getChild<LLTextBox>(name.asString());
+ LLSliderCtrl* slider = dynamic_cast<LLSliderCtrl*>(ctrl);
+ updateSliderText(slider, text_box);
+}
-// static
-void LLFloaterPreference::onBtnApply( void* userdata )
+void LLFloaterPreference::updateSliderText(LLSliderCtrl* ctrl, LLTextBox* text_box)
{
- LLFloaterPreference *fp =(LLFloaterPreference *)userdata;
- if (fp->hasFocus())
+ if(text_box == NULL || ctrl== NULL)
+ return;
+
+ // get range and points when text should change
+ F32 value = (F32)ctrl->getValue().asReal();
+ F32 min = ctrl->getMinValue();
+ F32 max = ctrl->getMaxValue();
+ F32 range = max - min;
+ llassert(range > 0);
+ F32 midPoint = min + range / 3.0f;
+ F32 highPoint = min + (2.0f * range / 3.0f);
+
+ // choose the right text
+ if(value < midPoint)
{
- LLUICtrl* cur_focus = gFocusMgr.getKeyboardFocus();
- if (cur_focus->acceptsTextInput())
+ text_box->setText(LLTrans::getString("GraphicsQualityLow"));
+ }
+ else if (value < highPoint)
+ {
+ text_box->setText(LLTrans::getString("GraphicsQualityMid"));
+ }
+ else
+ {
+ text_box->setText(LLTrans::getString("GraphicsQualityHigh"));
+ }
+}
+
+void LLFloaterPreference::onKeystrokeAspectRatio()
+{
+ getChild<LLCheckBoxCtrl>("aspect_auto_detect")->set(FALSE);
+}
+
+void LLFloaterPreference::applyWindowSize()
+{
+ LLComboBox* ctrl_windowSize = getChild<LLComboBox>("windowsize combo");
+ if (ctrl_windowSize->getVisible() && (ctrl_windowSize->getCurrentIndex() != -1))
+ {
+ U32 width = 0;
+ U32 height = 0;
+ if (extractWindowSizeFromString(ctrl_windowSize->getValue().asString().c_str(), width,height))
{
- cur_focus->onCommit();
+ LLViewerWindow::movieSize(width, height);
}
}
- fp->apply();
+}
- LLPanelLogin::refreshLocation( false );
+void LLFloaterPreference::applyResolution()
+{
+ LLComboBox* ctrl_aspect_ratio = getChild<LLComboBox>( "aspect_ratio");
+ gGL.flush();
+ char aspect_ratio_text[ASPECT_RATIO_STR_LEN]; /*Flawfinder: ignore*/
+ if (ctrl_aspect_ratio->getCurrentIndex() == -1)
+ {
+ // *Can't pass const char* from c_str() into strtok
+ strncpy(aspect_ratio_text, ctrl_aspect_ratio->getSimple().c_str(), sizeof(aspect_ratio_text) -1); /*Flawfinder: ignore*/
+ aspect_ratio_text[sizeof(aspect_ratio_text) -1] = '\0';
+ char *element = strtok(aspect_ratio_text, ":/\\");
+ if (!element)
+ {
+ sAspectRatio = 0.f; // will be clamped later
+ }
+ else
+ {
+ LLLocale locale(LLLocale::USER_LOCALE);
+ sAspectRatio = (F32)atof(element);
+ }
+
+ // look for denominator
+ element = strtok(NULL, ":/\\");
+ if (element)
+ {
+ LLLocale locale(LLLocale::USER_LOCALE);
+
+ F32 denominator = (F32)atof(element);
+ if (denominator != 0.f)
+ {
+ sAspectRatio /= denominator;
+ }
+ }
+ }
+ else
+ {
+ sAspectRatio = (F32)ctrl_aspect_ratio->getValue().asReal();
+ }
+
+ // presumably, user entered a non-numeric value if aspect_ratio == 0.f
+ if (sAspectRatio != 0.f)
+ {
+ sAspectRatio = llclamp(sAspectRatio, 0.2f, 5.f);
+ gSavedSettings.setF32("FullScreenAspectRatio", sAspectRatio);
+ }
+
+ // Screen resolution
+ S32 num_resolutions;
+ LLWindow::LLWindowResolution* supported_resolutions =
+ gViewerWindow->getWindow()->getSupportedResolutions(num_resolutions);
+ S32 resIndex = getChild<LLComboBox>("fullscreen combo")->getCurrentIndex();
+ if (resIndex == -1)
+ {
+ // use highest resolution if nothing selected
+ resIndex = num_resolutions - 1;
+ }
+ gSavedSettings.setS32("FullScreenWidth", supported_resolutions[resIndex].mWidth);
+ gSavedSettings.setS32("FullScreenHeight", supported_resolutions[resIndex].mHeight);
+
+ gViewerWindow->requestResolutionUpdate(gSavedSettings.getBOOL("WindowFullScreen"));
+
+ send_agent_update(TRUE);
+
+ // Update enable/disable
+ refresh();
+}
+
+void LLFloaterPreference::initWindowSizeControls(LLPanel* panelp)
+{
+ // Window size
+ // mWindowSizeLabel = getChild<LLTextBox>("WindowSizeLabel");
+ LLComboBox* ctrl_window_size = panelp->getChild<LLComboBox>("windowsize combo");
+
+ // Look to see if current window size matches existing window sizes, if so then
+ // just set the selection value...
+ const U32 height = gViewerWindow->getWindowDisplayHeight();
+ const U32 width = gViewerWindow->getWindowDisplayWidth();
+ for (S32 i=0; i < ctrl_window_size->getItemCount(); i++)
+ {
+ U32 height_test = 0;
+ U32 width_test = 0;
+ ctrl_window_size->setCurrentByIndex(i);
+ if (extractWindowSizeFromString(ctrl_window_size->getValue().asString(), width_test, height_test))
+ {
+ if ((height_test == height) && (width_test == width))
+ {
+ return;
+ }
+ }
+ }
+ // ...otherwise, add a new entry with the current window height/width.
+ LLUIString resolution_label = panelp->getString("resolution_format");
+ resolution_label.setArg("[RES_X]", llformat("%d", width));
+ resolution_label.setArg("[RES_Y]", llformat("%d", height));
+ ctrl_window_size->add(resolution_label, ADD_TOP);
+ ctrl_window_size->setCurrentByIndex(0);
}
-void LLFloaterPreference::onClose(bool app_quitting)
+
+//----------------------------------------------------------------------------
+static LLRegisterPanelClassWrapper<LLPanelPreference> t_places("panel_preference");
+LLPanelPreference::LLPanelPreference()
+: LLPanel()
{
- LLPanelLogin::setAlwaysRefresh(false);
- cancel(); // will be a no-op if OK or apply was performed just prior.
- LLFloater::onClose(app_quitting);
+ mCommitCallbackRegistrar.add("Pref.setControlFalse", boost::bind(&LLPanelPreference::setControlFalse,this, _2));
}
+static void applyUIColor(const std::string& color_name, LLUICtrl* ctrl, const LLSD& param)
+{
+ LLUIColorTable::instance().setColor(color_name, LLColor4(param));
+}
-// static
-void LLFloaterPreference::onBtnCancel( void* userdata )
+//virtual
+BOOL LLPanelPreference::postBuild()
{
- LLFloaterPreference *fp =(LLFloaterPreference *)userdata;
- if (fp->hasFocus())
+ if (hasChild("maturity_desired_combobox"))
{
- LLUICtrl* cur_focus = gFocusMgr.getKeyboardFocus();
- if (cur_focus->acceptsTextInput())
+ /////////////////////////// From LLPanelGeneral //////////////////////////
+ // if we have no agent, we can't let them choose anything
+ // if we have an agent, then we only let them choose if they have a choice
+ bool canChoose = gAgent.getID().notNull() &&
+ (gAgent.isMature() || gAgent.isGodlike());
+
+ if (canChoose)
{
- cur_focus->onCommit();
+
+ // if they're not adult or a god, they shouldn't see the adult selection, so delete it
+ if (!gAgent.isAdult() && !gAgent.isGodlike())
+ {
+ LLComboBox* pMaturityCombo = getChild<LLComboBox>("maturity_desired_combobox");
+ // we're going to remove the adult entry from the combo. This obviously depends
+ // on the order of items in the XML file, but there doesn't seem to be a reasonable
+ // way to depend on the field in XML called 'name'.
+ pMaturityCombo->remove(0);
+ }
+ childSetVisible("maturity_desired_combobox", true);
+ childSetVisible("maturity_desired_textbox", false);
}
+ else
+ {
+ childSetVisible("maturity_desired_combobox", false);
+ std::string selectedItemLabel = getChild<LLComboBox>("maturity_desired_combobox")->getSelectedItemLabel();
+ childSetValue("maturity_desired_textbox", selectedItemLabel);
+ childSetVisible("maturity_desired_textbox", true);
+ }
+ }
+ ////////////////////// PanelVoice ///////////////////
+ if(hasChild("voice_unavailable"))
+ {
+ BOOL voice_disabled = gSavedSettings.getBOOL("CmdLineDisableVoice");
+ childSetVisible("voice_unavailable", voice_disabled);
+ childSetVisible("enable_voice_check", !voice_disabled);
}
- fp->close(); // side effect will also cancel any unsaved changes.
+
+ //////////////////////PanelSkins ///////////////////
+
+ if (hasChild("skin_selection"))
+ {
+ LLFloaterPreference::refreshSkin(this);
+
+ // if skin is set to a skin that no longer exists (silver) set back to default
+ if (getChild<LLRadioGroup>("skin_selection")->getSelectedIndex() < 0)
+ {
+ gSavedSettings.setString("SkinCurrent", "default");
+ LLFloaterPreference::refreshSkin(this);
+ }
+
+ }
+ ////////////////////////Panel Popups/////////////////
+ if(hasChild("disabled_popups") && hasChild("enabled_popups"))
+ {
+ LLFloaterPreference::buildLists(this);
+ }
+ //////
+ if(hasChild("online_visibility") && hasChild("send_im_to_email"))
+ {
+ childSetText("email_address",getString("log_in_to_change") );
+// childSetText("busy_response", getString("log_in_to_change"));
+
+ }
+
+
+ if(hasChild("aspect_ratio"))
+ {
+ //============================================================================
+ // Resolution
+/*
+ S32 num_resolutions = 0;
+ LLWindow::LLWindowResolution* supported_resolutions = gViewerWindow->getWindow()->getSupportedResolutions(num_resolutions);
+
+ S32 fullscreen_mode = num_resolutions - 1;
+
+ LLComboBox*ctrl_full_screen = getChild<LLComboBox>( "fullscreen combo");
+ LLUIString resolution_label = getString("resolution_format");
+
+ for (S32 i = 0; i < num_resolutions; i++)
+ {
+ resolution_label.setArg("[RES_X]", llformat("%d", supported_resolutions[i].mWidth));
+ resolution_label.setArg("[RES_Y]", llformat("%d", supported_resolutions[i].mHeight));
+ ctrl_full_screen->add( resolution_label, ADD_BOTTOM );
+ }
+
+ {
+ BOOL targetFullscreen;
+ S32 targetWidth;
+ S32 targetHeight;
+
+ gViewerWindow->getTargetWindow(targetFullscreen, targetWidth, targetHeight);
+
+ if (targetFullscreen)
+ {
+ fullscreen_mode = 0; // default to 800x600
+ for (S32 i = 0; i < num_resolutions; i++)
+ {
+ if (targetWidth == supported_resolutions[i].mWidth
+ && targetHeight == supported_resolutions[i].mHeight)
+ {
+ fullscreen_mode = i;
+ }
+ }
+ ctrl_full_screen->setCurrentByIndex(fullscreen_mode);
+ }
+ else
+ {
+ // set to windowed mode
+ //fullscreen_mode = mCtrlFullScreen->getItemCount() - 1;
+ ctrl_full_screen->setCurrentByIndex(0);
+ }
+ }
+ */
+ LLFloaterPreference::initWindowSizeControls(this);
+
+ if (gSavedSettings.getBOOL("FullScreenAutoDetectAspectRatio"))
+ {
+ LLFloaterPreference::sAspectRatio = gViewerWindow->getDisplayAspectRatio();
+ }
+ else
+ {
+ LLFloaterPreference::sAspectRatio = gSavedSettings.getF32("FullScreenAspectRatio");
+ }
+
+ getChild<LLComboBox>("aspect_ratio")->setTextEntryCallback(boost::bind(&LLPanelPreference::setControlFalse, this, LLSD("FullScreenAutoDetectAspectRatio") ));
+
+
+ S32 numerator = 0;
+ S32 denominator = 0;
+ fractionFromDecimal(LLFloaterPreference::sAspectRatio, numerator, denominator);
+
+ LLUIString aspect_ratio_text = getString("aspect_ratio_text");
+ if (numerator != 0)
+ {
+ aspect_ratio_text.setArg("[NUM]", llformat("%d", numerator));
+ aspect_ratio_text.setArg("[DEN]", llformat("%d", denominator));
+ }
+ else
+ {
+ aspect_ratio_text = llformat("%.3f", LLFloaterPreference::sAspectRatio);
+ }
+
+ LLComboBox* ctrl_aspect_ratio = getChild<LLComboBox>( "aspect_ratio");
+ //mCtrlAspectRatio->setCommitCallback(onSelectAspectRatio, this);
+ // add default aspect ratios
+ ctrl_aspect_ratio->add(aspect_ratio_text, &LLFloaterPreference::sAspectRatio, ADD_TOP);
+ ctrl_aspect_ratio->setCurrentByIndex(0);
+
+ refresh();
+ }
+
+
+ if(hasChild("user") && hasChild("agent") && hasChild("im")
+ && hasChild("system") && hasChild("script_error") && hasChild("objects")
+ && hasChild("owner") && hasChild("background") && hasChild("links"))
+ {
+ LLColorSwatchCtrl* color_swatch = getChild<LLColorSwatchCtrl>("user");
+ color_swatch->setCommitCallback(boost::bind(&applyUIColor, "UserChatColor", _1, _2));
+ color_swatch->setOriginal(LLUIColorTable::instance().getColor("UserChatColor"));
+
+ color_swatch = getChild<LLColorSwatchCtrl>("agent");
+ color_swatch->setCommitCallback(boost::bind(&applyUIColor, "AgentChatColor", _1, _2));
+ color_swatch->setOriginal(LLUIColorTable::instance().getColor("AgentChatColor"));
+
+ color_swatch = getChild<LLColorSwatchCtrl>("im");
+ color_swatch->setCommitCallback(boost::bind(&applyUIColor, "IMChatColor", _1, _2));
+ color_swatch->setOriginal(LLUIColorTable::instance().getColor("IMChatColor"));
+
+ color_swatch = getChild<LLColorSwatchCtrl>("system");
+ color_swatch->setCommitCallback(boost::bind(&applyUIColor, "SystemChatColor", _1, _2));
+ color_swatch->setOriginal(LLUIColorTable::instance().getColor("SystemChatColor"));
+
+ color_swatch = getChild<LLColorSwatchCtrl>("script_error");
+ color_swatch->setCommitCallback(boost::bind(&applyUIColor, "ScriptErrorColor", _1, _2));
+ color_swatch->setOriginal(LLUIColorTable::instance().getColor("ScriptErrorColor"));
+
+ color_swatch = getChild<LLColorSwatchCtrl>("objects");
+ color_swatch->setCommitCallback(boost::bind(&applyUIColor, "ObjectChatColor", _1, _2));
+ color_swatch->setOriginal(LLUIColorTable::instance().getColor("ObjectChatColor"));
+
+ color_swatch = getChild<LLColorSwatchCtrl>("owner");
+ color_swatch->setCommitCallback(boost::bind(&applyUIColor, "llOwnerSayChatColor", _1, _2));
+ color_swatch->setOriginal(LLUIColorTable::instance().getColor("llOwnerSayChatColor"));
+
+ color_swatch = getChild<LLColorSwatchCtrl>("background");
+ color_swatch->setCommitCallback(boost::bind(&applyUIColor, "BackgroundChatColor", _1, _2));
+ color_swatch->setOriginal(LLUIColorTable::instance().getColor("BackgroundChatColor"));
+
+ color_swatch = getChild<LLColorSwatchCtrl>("links");
+ color_swatch->setCommitCallback(boost::bind(&applyUIColor, "HTMLLinkColor", _1, _2));
+ color_swatch->setOriginal(LLUIColorTable::instance().getColor("HTMLLinkColor"));
+ }
+
+ if(hasChild("effect_color_swatch"))
+ {
+ LLColorSwatchCtrl* color_swatch = getChild<LLColorSwatchCtrl>("effect_color_swatch");
+ color_swatch->setCommitCallback(boost::bind(&applyUIColor, "EffectColor", _1, _2));
+ color_swatch->setOriginal(LLUIColorTable::instance().getColor("EffectColor"));
+ }
+
+ apply();
+ return true;
}
+void LLPanelPreference::apply()
+{
+ // Save the value of all controls in the hierarchy
+ mSavedValues.clear();
+ std::list<LLView*> view_stack;
+ view_stack.push_back(this);
+ while(!view_stack.empty())
+ {
+ // Process view on top of the stack
+ LLView* curview = view_stack.front();
+ view_stack.pop_front();
-// static
-void LLFloaterPreference::updateUserInfo(const std::string& visibility, bool im_via_email, const std::string& email)
+ LLColorSwatchCtrl* color_swatch = dynamic_cast<LLColorSwatchCtrl *>(curview);
+ if (color_swatch)
+ {
+ mSavedColors[color_swatch->getName()] = color_swatch->get();
+ }
+ else
+ {
+ LLUICtrl* ctrl = dynamic_cast<LLUICtrl*>(curview);
+ if (ctrl)
+ {
+ LLControlVariable* control = ctrl->getControlVariable();
+ if (control)
+ {
+ mSavedValues[control] = control->getValue();
+ }
+ }
+ }
+
+ // Push children onto the end of the work stack
+ for (child_list_t::const_iterator iter = curview->getChildList()->begin();
+ iter != curview->getChildList()->end(); ++iter)
+ {
+ view_stack.push_back(*iter);
+ }
+ }
+
+}
+
+void LLPanelPreference::cancel()
{
- if(sInstance && sInstance->mPreferenceCore)
+ for (control_values_map_t::iterator iter = mSavedValues.begin();
+ iter != mSavedValues.end(); ++iter)
{
- sInstance->mPreferenceCore->setPersonalInfo(visibility, im_via_email, email);
+ LLControlVariable* control = iter->first;
+ LLSD ctrl_value = iter->second;
+ control->set(ctrl_value);
+ }
+
+ for (string_color_map_t::iterator iter = mSavedColors.begin();
+ iter != mSavedColors.end(); ++iter)
+ {
+ LLColorSwatchCtrl* color_swatch = findChild<LLColorSwatchCtrl>(iter->first);
+ if(color_swatch)
+ {
+ color_swatch->set(iter->second);
+ color_swatch->onCommit();
+ }
}
}
-void LLFloaterPreference::refreshEnabledGraphics()
+void LLPanelPreference::setControlFalse(const LLSD& user_data)
{
- sInstance->mPreferenceCore->refreshEnabledGraphics();
+ std::string control_name = user_data.asString();
+ LLControlVariable* control = findControl(control_name);
+
+ if (control)
+ control->set(LLSD(FALSE));
}
+
diff --git a/indra/newview/llfloaterpreference.h b/indra/newview/llfloaterpreference.h
index f48696ffdb..ce31abcd9e 100644
--- a/indra/newview/llfloaterpreference.h
+++ b/indra/newview/llfloaterpreference.h
@@ -40,94 +40,134 @@
#define LL_LLFLOATERPREFERENCE_H
#include "llfloater.h"
-#include "lltabcontainervertical.h"
-class LLPanelGeneral;
-class LLPanelInput;
+class LLPanelPreference;
class LLPanelLCD;
-class LLPanelDisplay;
-class LLPanelAudioPrefs;
class LLPanelDebug;
-class LLPanelNetwork;
-class LLPanelWeb;
class LLMessageSystem;
-class LLPrefsChat;
-class LLPrefsVoice;
-class LLPrefsIM;
-class LLPanelMsgs;
-class LLPanelSkins;
class LLScrollListCtrl;
+class LLSliderCtrl;
+class LLSD;
+class LLTextBox;
-class LLPreferenceCore
-{
-
-public:
- LLPreferenceCore(LLTabContainer* tab_container, LLButton * default_btn);
- ~LLPreferenceCore();
-
- void apply();
- void cancel();
-
- LLTabContainer* getTabContainer() { return mTabContainer; }
-
- void setPersonalInfo(const std::string& visibility, bool im_via_email, const std::string& email);
+typedef enum
+ {
+ GS_LOW_GRAPHICS,
+ GS_MID_GRAPHICS,
+ GS_HIGH_GRAPHICS,
+ GS_ULTRA_GRAPHICS
+
+ } EGraphicsSettings;
- static void onTabChanged(void* user_data, bool from_click);
-
- // refresh all the graphics preferences menus
- void refreshEnabledGraphics();
-
-private:
- LLTabContainer *mTabContainer;
- LLPanelGeneral *mGeneralPanel;
- LLPanelSkins *mSkinsPanel;
- LLPanelInput *mInputPanel;
- LLPanelNetwork *mNetworkPanel;
- LLPanelDisplay *mDisplayPanel;
- LLPanelAudioPrefs *mAudioPanel;
-// LLPanelDebug *mDebugPanel;
- LLPrefsChat *mPrefsChat;
- LLPrefsVoice *mPrefsVoice;
- LLPrefsIM *mPrefsIM;
- LLPanelWeb *mWebPanel;
- LLPanelMsgs *mMsgPanel;
- LLPanelLCD *mLCDPanel;
-};
// Floater to control preferences (display, audio, bandwidth, general.
class LLFloaterPreference : public LLFloater
{
public:
- LLFloaterPreference();
+ LLFloaterPreference(const LLSD& key);
~LLFloaterPreference();
void apply();
void cancel();
+ /*virtual*/ void draw();
virtual BOOL postBuild();
- static void show(void*);
+ virtual void onOpen(const LLSD& key);
// static data update, called from message handler
static void updateUserInfo(const std::string& visibility, bool im_via_email, const std::string& email);
// refresh all the graphics preferences menus
static void refreshEnabledGraphics();
-
+
protected:
- LLPreferenceCore *mPreferenceCore;
+
+ void onClose();
+
+ void onBtnOK();
+ void onBtnCancel();
+ void onBtnApply();
+ void onOpenHelp();
+
+// void onClickClearCache();
+ void onClickBrowserClearCache();
+
+ // if the custom settings box is clicked
+ void onChangeCustom();
+ void updateMeterText(LLUICtrl* ctrl);
+ void onOpenHardwareSettings();
+ /// callback for defaults
+ void setHardwareDefaults();
+ // callback for when client turns on shaders
+ void onVertexShaderEnable();
+
+
+public:
- /*virtual*/ void onClose(bool app_quitting);
+ void onClickSetCache();
+ void onClickResetCache();
+ void onClickSkin(LLUICtrl* ctrl,const LLSD& userdata);
+ void onSelectSkin();
+ void onClickSetKey();
+ void setKey(KEY key);
+ void onClickSetMiddleMouse();
+ void onClickSkipDialogs();
+ void onClickResetDialogs();
+ void onClickEnablePopup();
+ void onClickDisablePopup();
+ void resetAllIgnored();
+ void setAllIgnored();
+ void onClickLogPath();
+ void enableHistory();
+ void onCommitLogging();
+ void setPersonalInfo(const std::string& visibility, bool im_via_email, const std::string& email);
+ void refreshEnabledState();
+ void disableUnavailableSettings();
+ void onCommitWindowedMode();
+ void refresh(); // Refresh enable/disable
+ // if the quality radio buttons are changed
+ void onChangeQuality(const LLSD& data);
+
+ void updateSliderText(LLSliderCtrl* ctrl, LLTextBox* text_box);
+ void onUpdateSliderText(LLUICtrl* ctrl, const LLSD& name);
+ void onKeystrokeAspectRatio();
+// void fractionFromDecimal(F32 decimal_val, S32& numerator, S32& denominator);
+// bool extractWindowSizeFromString(const std::string& instr, U32 &width, U32 &height);
- LLButton* mAboutBtn;
- LLButton *mOKBtn;
- LLButton *mCancelBtn;
- LLButton *mApplyBtn;
+ void onCommitAutoDetectAspect();
+ void applyResolution();
+ void applyWindowSize();
- static void onClickAbout(void*);
- static void onBtnOK(void*);
- static void onBtnCancel(void*);
- static void onBtnApply(void*);
+ static void initWindowSizeControls(LLPanel* panelp);
+
+ static void buildLists(void* data);
+ static void refreshSkin(void* data);
+ static void cleanupBadSetting();
+ static F32 sAspectRatio;
+private:
+ static std::string sSkin;
+ bool mGotPersonalInfo;
+ bool mOriginalIMViaEmail;
+
+ bool mOriginalHideOnlineStatus;
+ std::string mDirectoryVisibility;
+
+};
+
+class LLPanelPreference : public LLPanel
+{
+public:
+ LLPanelPreference();
+ /*virtual*/ BOOL postBuild();
+
+ virtual void apply();
+ virtual void cancel();
+ void setControlFalse(const LLSD& user_data);
+private:
+ typedef std::map<LLControlVariable*, LLSD> control_values_map_t;
+ control_values_map_t mSavedValues;
- static LLFloaterPreference* sInstance;
+ typedef std::map<std::string, LLColor4> string_color_map_t;
+ string_color_map_t mSavedColors;
};
#endif // LL_LLPREFERENCEFLOATER_H
diff --git a/indra/newview/llfloaterproperties.cpp b/indra/newview/llfloaterproperties.cpp
index 406d940cf0..091debe95e 100644
--- a/indra/newview/llfloaterproperties.cpp
+++ b/indra/newview/llfloaterproperties.cpp
@@ -37,25 +37,29 @@
#include <functional>
#include "llcachename.h"
#include "lldbstrings.h"
+#include "llfloaterreg.h"
#include "llinventory.h"
#include "llagent.h"
#include "llbutton.h"
#include "llcheckboxctrl.h"
-#include "llfloateravatarinfo.h"
-#include "llfloatergroupinfo.h"
+#include "llavataractions.h"
#include "llinventorymodel.h"
#include "lllineeditor.h"
+//#include "llspinctrl.h"
#include "llradiogroup.h"
#include "llresmgr.h"
#include "roles_constants.h"
#include "llselectmgr.h"
#include "lltextbox.h"
+#include "lltrans.h"
#include "lluiconstants.h"
#include "llviewerinventory.h"
#include "llviewerobjectlist.h"
#include "llviewerregion.h"
#include "llviewercontrol.h"
+#include "llviewerwindow.h"
+#include "llgroupactions.h"
#include "lluictrlfactory.h"
@@ -73,7 +77,8 @@
class LLPropertiesObserver : public LLInventoryObserver
{
public:
- LLPropertiesObserver()
+ LLPropertiesObserver(LLFloaterProperties* floater)
+ : mFloater(floater)
{
gInventory.addObserver(this);
}
@@ -82,6 +87,8 @@ public:
gInventory.removeObserver(this);
}
virtual void changed(U32 mask);
+private:
+ LLFloaterProperties* mFloater;
};
void LLPropertiesObserver::changed(U32 mask)
@@ -89,7 +96,7 @@ void LLPropertiesObserver::changed(U32 mask)
// if there's a change we're interested in.
if((mask & (LLInventoryObserver::LABEL | LLInventoryObserver::INTERNAL | LLInventoryObserver::REMOVE)) != 0)
{
- LLFloaterProperties::dirtyAll();
+ mFloater->dirty();
}
}
@@ -99,120 +106,63 @@ void LLPropertiesObserver::changed(U32 mask)
/// Class LLFloaterProperties
///----------------------------------------------------------------------------
-// static
-LLFloaterProperties::instance_map LLFloaterProperties::sInstances;
-LLPropertiesObserver* LLFloaterProperties::sPropertiesObserver = NULL;
-S32 LLFloaterProperties::sPropertiesObserverCount = 0;
-
-// static
-LLFloaterProperties* LLFloaterProperties::find(const LLUUID& item_id,
- const LLUUID& object_id)
-{
- // for simplicity's sake, we key the properties window with a
- // single uuid. However, the items are keyed by item and object
- // (obj == null -> agent inventory). So, we xor the two ids, and
- // use that as a lookup key
- instance_map::iterator it = sInstances.find(item_id ^ object_id);
- if(it != sInstances.end())
- {
- return (*it).second;
- }
- return NULL;
-}
-
-// static
-LLFloaterProperties* LLFloaterProperties::show(const LLUUID& item_id,
- const LLUUID& object_id)
+// Default constructor
+LLFloaterProperties::LLFloaterProperties(const LLUUID& item_id)
+ : LLFloater(mItemID),
+ mItemID(item_id),
+ mDirty(TRUE)
{
- LLFloaterProperties* instance = find(item_id, object_id);
- if(instance)
- {
- if (LLFloater::getFloaterHost() && LLFloater::getFloaterHost() != instance->getHost())
- {
- // this properties window is being opened in a new context
- // needs to be rehosted
- LLFloater::getFloaterHost()->addFloater(instance, TRUE);
- }
-
- instance->refresh();
- instance->open(); /* Flawfinder: ignore */
- }
- return instance;
+ mPropertiesObserver = new LLPropertiesObserver(this);
+
+ //LLUICtrlFactory::getInstance()->buildFloater(this,"floater_inventory_item_properties.xml");
}
-void LLFloaterProperties::dirtyAll()
+// Destroys the object
+LLFloaterProperties::~LLFloaterProperties()
{
- // ...this is more clear. Possibly more correct, because the
- // refresh method may delete the object.
- for(instance_map::iterator it = sInstances.begin(); it!=sInstances.end(); )
- {
- (*it++).second->dirty();
- }
+ delete mPropertiesObserver;
+ mPropertiesObserver = NULL;
}
-// Default constructor
-LLFloaterProperties::LLFloaterProperties(const std::string& name, const LLRect& rect, const std::string& title, const LLUUID& item_id, const LLUUID& object_id) :
- LLFloater(name, rect, title),
- mItemID(item_id),
- mObjectID(object_id),
- mDirty(TRUE)
+// virtual
+BOOL LLFloaterProperties::postBuild()
{
- LLUICtrlFactory::getInstance()->buildFloater(this,"floater_inventory_item_properties.xml");
-
- if (!sPropertiesObserver)
- {
- sPropertiesObserver = new LLPropertiesObserver;
- }
- sPropertiesObserverCount++;
-
- // add the object to the static structure
- LLUUID key = mItemID ^ mObjectID;
- sInstances.insert(instance_map::value_type(key, this));
// build the UI
// item name & description
childSetPrevalidate("LabelItemName",&LLLineEditor::prevalidatePrintableNotPipe);
- childSetCommitCallback("LabelItemName",onCommitName,this);
+ getChild<LLUICtrl>("LabelItemName")->setCommitCallback(boost::bind(&LLFloaterProperties::onCommitName,this));
childSetPrevalidate("LabelItemDesc",&LLLineEditor::prevalidatePrintableNotPipe);
- childSetCommitCallback("LabelItemDesc", onCommitDescription, this);
+ getChild<LLUICtrl>("LabelItemDesc")->setCommitCallback(boost::bind(&LLFloaterProperties:: onCommitDescription, this));
// Creator information
- childSetAction("BtnCreator",onClickCreator,this);
+ getChild<LLUICtrl>("BtnCreator")->setCommitCallback(boost::bind(&LLFloaterProperties::onClickCreator,this));
// owner information
- childSetAction("BtnOwner",onClickOwner,this);
+ getChild<LLUICtrl>("BtnOwner")->setCommitCallback(boost::bind(&LLFloaterProperties::onClickOwner,this));
// acquired date
// owner permissions
// Permissions debug text
// group permissions
- childSetCommitCallback("CheckShareWithGroup",&onCommitPermissions, this);
+ getChild<LLUICtrl>("CheckShareWithGroup")->setCommitCallback(boost::bind(&LLFloaterProperties::onCommitPermissions, this));
// everyone permissions
- childSetCommitCallback("CheckEveryoneCopy",&onCommitPermissions, this);
+ getChild<LLUICtrl>("CheckEveryoneCopy")->setCommitCallback(boost::bind(&LLFloaterProperties::onCommitPermissions, this));
// next owner permissions
- childSetCommitCallback("CheckNextOwnerModify",&onCommitPermissions, this);
- childSetCommitCallback("CheckNextOwnerCopy",&onCommitPermissions, this);
- childSetCommitCallback("CheckNextOwnerTransfer",&onCommitPermissions, this);
+ getChild<LLUICtrl>("CheckNextOwnerModify")->setCommitCallback(boost::bind(&LLFloaterProperties::onCommitPermissions, this));
+ getChild<LLUICtrl>("CheckNextOwnerCopy")->setCommitCallback(boost::bind(&LLFloaterProperties::onCommitPermissions, this));
+ getChild<LLUICtrl>("CheckNextOwnerTransfer")->setCommitCallback(boost::bind(&LLFloaterProperties::onCommitPermissions, this));
// Mark for sale or not, and sale info
- childSetCommitCallback("CheckPurchase",&onCommitSaleInfo, this);
- childSetCommitCallback("RadioSaleType",&onCommitSaleType, this);
+ getChild<LLUICtrl>("CheckPurchase")->setCommitCallback(boost::bind(&LLFloaterProperties::onCommitSaleInfo, this));
+ getChild<LLUICtrl>("RadioSaleType")->setCommitCallback(boost::bind(&LLFloaterProperties::onCommitSaleType, this));
// "Price" label for edit
- childSetCommitCallback("EditPrice",&onCommitSaleInfo, this);
+ getChild<LLUICtrl>("Edit Cost")->setCommitCallback(boost::bind(&LLFloaterProperties::onCommitSaleInfo, this));
// The UI has been built, now fill in all the values
refresh();
+
+ return TRUE;
}
-// Destroys the object
-LLFloaterProperties::~LLFloaterProperties()
+// virtual
+void LLFloaterProperties::onOpen(const LLSD& key)
{
- // clean up the static data.
- instance_map::iterator it = sInstances.find(mItemID ^ mObjectID);
- if(it != sInstances.end())
- {
- sInstances.erase(it);
- }
- sPropertiesObserverCount--;
- if (!sPropertiesObserverCount)
- {
- delete sPropertiesObserver;
- sPropertiesObserver = NULL;
- }
+ refresh();
}
void LLFloaterProperties::refresh()
@@ -246,7 +196,7 @@ void LLFloaterProperties::refresh()
"CheckNextOwnerTransfer",
"CheckPurchase",
"RadioSaleType",
- "EditPrice"
+ "Edit Cost"
};
for(size_t t=0; t<LL_ARRAY_SIZE(enableNames); ++t)
{
@@ -287,12 +237,15 @@ void LLFloaterProperties::refreshFromItem(LLInventoryItem* item)
// do not enable the UI for incomplete items.
LLViewerInventoryItem* i = (LLViewerInventoryItem*)item;
BOOL is_complete = i->isComplete();
-
+ const BOOL cannot_restrict_permissions = LLInventoryType::cannotRestrictPermissions(i->getInventoryType());
+ const BOOL is_calling_card = (i->getInventoryType() == LLInventoryType::IT_CALLINGCARD);
const LLPermissions& perm = item->getPermissions();
- BOOL can_agent_manipulate = gAgent.allowOperation(PERM_OWNER, perm,
- GP_OBJECT_MANIPULATE);
- BOOL can_agent_sell = gAgent.allowOperation(PERM_OWNER, perm,
- GP_OBJECT_SET_SALE);
+ const BOOL can_agent_manipulate = gAgent.allowOperation(PERM_OWNER, perm,
+ GP_OBJECT_MANIPULATE);
+ const BOOL can_agent_sell = gAgent.allowOperation(PERM_OWNER, perm,
+ GP_OBJECT_SET_SALE) &&
+ !cannot_restrict_permissions;
+ const BOOL is_link = i->getIsLinkType();
// You need permission to modify the object to modify an inventory
// item in it.
@@ -308,11 +261,11 @@ void LLFloaterProperties::refreshFromItem(LLInventoryItem* item)
// ITEM NAME & DESC //
//////////////////////
BOOL is_modifiable = gAgent.allowOperation(PERM_MODIFY, perm,
- GP_OBJECT_MANIPULATE)
- && is_obj_modify && is_complete;
+ GP_OBJECT_MANIPULATE)
+ && is_obj_modify && is_complete;
childSetEnabled("LabelItemNameTitle",TRUE);
- childSetEnabled("LabelItemName",is_modifiable);
+ childSetEnabled("LabelItemName",is_modifiable && !is_calling_card); // for now, don't allow rename of calling cards
childSetText("LabelItemName",item->getName());
childSetEnabled("LabelItemDescTitle",TRUE);
childSetEnabled("LabelItemDesc",is_modifiable);
@@ -372,8 +325,7 @@ void LLFloaterProperties::refreshFromItem(LLInventoryItem* item)
//////////////////
// ACQUIRE DATE //
//////////////////
-
- // *TODO: Localize / translate this
+
time_t time_utc = item->getCreationDate();
if (0 == time_utc)
{
@@ -381,7 +333,11 @@ void LLFloaterProperties::refreshFromItem(LLInventoryItem* item)
}
else
{
- childSetText("LabelAcquiredDate", std::string(ctime(&time_utc)) );
+ std::string timeStr = getString("acquiredDate");
+ LLSD substitution;
+ substitution["datetime"] = (S32) time_utc;
+ LLStringUtil::format (timeStr, substitution);
+ childSetText ("LabelAcquiredDate", timeStr);
}
///////////////////////
@@ -472,7 +428,12 @@ void LLFloaterProperties::refreshFromItem(LLInventoryItem* item)
/////////////
// Check for ability to change values.
- if (is_obj_modify && can_agent_manipulate)
+ if (is_link || cannot_restrict_permissions)
+ {
+ childSetEnabled("CheckShareWithGroup",FALSE);
+ childSetEnabled("CheckEveryoneCopy",FALSE);
+ }
+ else if (is_obj_modify && can_agent_manipulate)
{
childSetEnabled("CheckShareWithGroup",TRUE);
childSetEnabled("CheckEveryoneCopy",(owner_mask & PERM_COPY) && (owner_mask & PERM_TRANSFER));
@@ -533,13 +494,13 @@ void LLFloaterProperties::refreshFromItem(LLInventoryItem* item)
childSetEnabled("CheckPurchase",is_complete);
childSetEnabled("NextOwnerLabel",TRUE);
- childSetEnabled("CheckNextOwnerModify",base_mask & PERM_MODIFY);
- childSetEnabled("CheckNextOwnerCopy",base_mask & PERM_COPY);
- childSetEnabled("CheckNextOwnerTransfer",next_owner_mask & PERM_COPY);
+ childSetEnabled("CheckNextOwnerModify",(base_mask & PERM_MODIFY) && !cannot_restrict_permissions);
+ childSetEnabled("CheckNextOwnerCopy",(base_mask & PERM_COPY) && !cannot_restrict_permissions);
+ childSetEnabled("CheckNextOwnerTransfer",(next_owner_mask & PERM_COPY) && !cannot_restrict_permissions);
childSetEnabled("RadioSaleType",is_complete && is_for_sale);
childSetEnabled("TextPrice",is_complete && is_for_sale);
- childSetEnabled("EditPrice",is_complete && is_for_sale);
+ childSetEnabled("Edit Cost",is_complete && is_for_sale);
}
else
{
@@ -553,11 +514,13 @@ void LLFloaterProperties::refreshFromItem(LLInventoryItem* item)
childSetEnabled("RadioSaleType",FALSE);
childSetEnabled("TextPrice",FALSE);
- childSetEnabled("EditPrice",FALSE);
+ childSetEnabled("Edit Cost",FALSE);
}
// Set values.
childSetValue("CheckPurchase", is_for_sale);
+ childSetEnabled("combobox sale copy", is_for_sale);
+ childSetEnabled("Edit Cost", is_for_sale);
childSetValue("CheckNextOwnerModify",LLSD(BOOL(next_owner_mask & PERM_MODIFY)));
childSetValue("CheckNextOwnerCopy",LLSD(BOOL(next_owner_mask & PERM_COPY)));
childSetValue("CheckNextOwnerTransfer",LLSD(BOOL(next_owner_mask & PERM_TRANSFER)));
@@ -568,63 +531,50 @@ void LLFloaterProperties::refreshFromItem(LLInventoryItem* item)
radioSaleType->setSelectedIndex((S32)sale_info.getSaleType() - 1);
S32 numerical_price;
numerical_price = sale_info.getSalePrice();
- childSetText("EditPrice",llformat("%d",numerical_price));
+ childSetText("Edit Cost",llformat("%d",numerical_price));
}
else
{
radioSaleType->setSelectedIndex(-1);
- childSetText("EditPrice",llformat("%d",0));
+ childSetText("Edit Cost",llformat("%d",0));
}
}
-// static
-void LLFloaterProperties::onClickCreator(void* data)
+void LLFloaterProperties::onClickCreator()
{
- LLFloaterProperties* self = (LLFloaterProperties*)data;
- if(!self) return;
- LLInventoryItem* item = self->findItem();
+ LLInventoryItem* item = findItem();
if(!item) return;
if(!item->getCreatorUUID().isNull())
{
- LLFloaterAvatarInfo::showFromObject(item->getCreatorUUID());
+ LLAvatarActions::showProfile(item->getCreatorUUID());
}
}
// static
-void LLFloaterProperties::onClickOwner(void* data)
+void LLFloaterProperties::onClickOwner()
{
- LLFloaterProperties* self = (LLFloaterProperties*)data;
- if(!self) return;
- LLInventoryItem* item = self->findItem();
+ LLInventoryItem* item = findItem();
if(!item) return;
if(item->getPermissions().isGroupOwned())
{
- LLFloaterGroupInfo::showFromUUID(item->getPermissions().getGroup());
+ LLGroupActions::show(item->getPermissions().getGroup());
}
else
{
- if(!item->getPermissions().getOwner().isNull())
- {
- LLFloaterAvatarInfo::showFromObject(item->getPermissions().getOwner());
- }
+ LLAvatarActions::showProfile(item->getPermissions().getOwner());
}
}
// static
-void LLFloaterProperties::onCommitName(LLUICtrl* ctrl, void* data)
+void LLFloaterProperties::onCommitName()
{
//llinfos << "LLFloaterProperties::onCommitName()" << llendl;
- LLFloaterProperties* self = (LLFloaterProperties*)data;
- if(!self)
- {
- return;
- }
- LLViewerInventoryItem* item = (LLViewerInventoryItem*)self->findItem();
+ LLViewerInventoryItem* item = (LLViewerInventoryItem*)findItem();
if(!item)
{
return;
}
- LLLineEditor* labelItemName = self->getChild<LLLineEditor>("LabelItemName");
+ LLLineEditor* labelItemName = getChild<LLLineEditor>("LabelItemName");
if(labelItemName&&
(item->getName() != labelItemName->getText()) &&
@@ -632,15 +582,16 @@ void LLFloaterProperties::onCommitName(LLUICtrl* ctrl, void* data)
{
LLPointer<LLViewerInventoryItem> new_item = new LLViewerInventoryItem(item);
new_item->rename(labelItemName->getText());
- if(self->mObjectID.isNull())
+ if(mObjectID.isNull())
{
new_item->updateServer(FALSE);
gInventory.updateItem(new_item);
+ gInventory.updateLinkedObjects(new_item->getUUID());
gInventory.notifyObservers();
}
else
{
- LLViewerObject* object = gObjectList.findObject(self->mObjectID);
+ LLViewerObject* object = gObjectList.findObject(mObjectID);
if(object)
{
object->updateInventory(
@@ -652,16 +603,13 @@ void LLFloaterProperties::onCommitName(LLUICtrl* ctrl, void* data)
}
}
-// static
-void LLFloaterProperties::onCommitDescription(LLUICtrl* ctrl, void* data)
+void LLFloaterProperties::onCommitDescription()
{
//llinfos << "LLFloaterProperties::onCommitDescription()" << llendl;
- LLFloaterProperties* self = (LLFloaterProperties*)data;
- if(!self) return;
- LLViewerInventoryItem* item = (LLViewerInventoryItem*)self->findItem();
+ LLViewerInventoryItem* item = (LLViewerInventoryItem*)findItem();
if(!item) return;
- LLLineEditor* labelItemDesc = self->getChild<LLLineEditor>("LabelItemDesc");
+ LLLineEditor* labelItemDesc = getChild<LLLineEditor>("LabelItemDesc");
if(!labelItemDesc)
{
return;
@@ -672,7 +620,7 @@ void LLFloaterProperties::onCommitDescription(LLUICtrl* ctrl, void* data)
LLPointer<LLViewerInventoryItem> new_item = new LLViewerInventoryItem(item);
new_item->setDescription(labelItemDesc->getText());
- if(self->mObjectID.isNull())
+ if(mObjectID.isNull())
{
new_item->updateServer(FALSE);
gInventory.updateItem(new_item);
@@ -680,7 +628,7 @@ void LLFloaterProperties::onCommitDescription(LLUICtrl* ctrl, void* data)
}
else
{
- LLViewerObject* object = gObjectList.findObject(self->mObjectID);
+ LLViewerObject* object = gObjectList.findObject(mObjectID);
if(object)
{
object->updateInventory(
@@ -693,17 +641,15 @@ void LLFloaterProperties::onCommitDescription(LLUICtrl* ctrl, void* data)
}
// static
-void LLFloaterProperties::onCommitPermissions(LLUICtrl* ctrl, void* data)
+void LLFloaterProperties::onCommitPermissions()
{
//llinfos << "LLFloaterProperties::onCommitPermissions()" << llendl;
- LLFloaterProperties* self = (LLFloaterProperties*)data;
- if(!self) return;
- LLViewerInventoryItem* item = (LLViewerInventoryItem*)self->findItem();
+ LLViewerInventoryItem* item = (LLViewerInventoryItem*)findItem();
if(!item) return;
LLPermissions perm(item->getPermissions());
- LLCheckBoxCtrl* CheckShareWithGroup = self->getChild<LLCheckBoxCtrl>("CheckShareWithGroup");
+ LLCheckBoxCtrl* CheckShareWithGroup = getChild<LLCheckBoxCtrl>("CheckShareWithGroup");
if(CheckShareWithGroup)
{
@@ -711,26 +657,26 @@ void LLFloaterProperties::onCommitPermissions(LLUICtrl* ctrl, void* data)
CheckShareWithGroup->get(),
PERM_MODIFY | PERM_MOVE | PERM_COPY);
}
- LLCheckBoxCtrl* CheckEveryoneCopy = self->getChild<LLCheckBoxCtrl>("CheckEveryoneCopy");
+ LLCheckBoxCtrl* CheckEveryoneCopy = getChild<LLCheckBoxCtrl>("CheckEveryoneCopy");
if(CheckEveryoneCopy)
{
perm.setEveryoneBits(gAgent.getID(), gAgent.getGroupID(),
CheckEveryoneCopy->get(), PERM_COPY);
}
- LLCheckBoxCtrl* CheckNextOwnerModify = self->getChild<LLCheckBoxCtrl>("CheckNextOwnerModify");
+ LLCheckBoxCtrl* CheckNextOwnerModify = getChild<LLCheckBoxCtrl>("CheckNextOwnerModify");
if(CheckNextOwnerModify)
{
perm.setNextOwnerBits(gAgent.getID(), gAgent.getGroupID(),
CheckNextOwnerModify->get(), PERM_MODIFY);
}
- LLCheckBoxCtrl* CheckNextOwnerCopy = self->getChild<LLCheckBoxCtrl>("CheckNextOwnerCopy");
+ LLCheckBoxCtrl* CheckNextOwnerCopy = getChild<LLCheckBoxCtrl>("CheckNextOwnerCopy");
if(CheckNextOwnerCopy)
{
perm.setNextOwnerBits(gAgent.getID(), gAgent.getGroupID(),
CheckNextOwnerCopy->get(), PERM_COPY);
}
- LLCheckBoxCtrl* CheckNextOwnerTransfer = self->getChild<LLCheckBoxCtrl>("CheckNextOwnerTransfer");
+ LLCheckBoxCtrl* CheckNextOwnerTransfer = getChild<LLCheckBoxCtrl>("CheckNextOwnerTransfer");
if(CheckNextOwnerTransfer)
{
perm.setNextOwnerBits(gAgent.getID(), gAgent.getGroupID(),
@@ -766,7 +712,7 @@ void LLFloaterProperties::onCommitPermissions(LLUICtrl* ctrl, void* data)
flags |= LLInventoryItem::II_FLAGS_OBJECT_PERM_OVERWRITE_GROUP;
}
new_item->setFlags(flags);
- if(self->mObjectID.isNull())
+ if(mObjectID.isNull())
{
new_item->updateServer(FALSE);
gInventory.updateItem(new_item);
@@ -774,7 +720,7 @@ void LLFloaterProperties::onCommitPermissions(LLUICtrl* ctrl, void* data)
}
else
{
- LLViewerObject* object = gObjectList.findObject(self->mObjectID);
+ LLViewerObject* object = gObjectList.findObject(mObjectID);
if(object)
{
object->updateInventory(
@@ -787,26 +733,22 @@ void LLFloaterProperties::onCommitPermissions(LLUICtrl* ctrl, void* data)
else
{
// need to make sure we don't just follow the click
- self->refresh();
+ refresh();
}
}
// static
-void LLFloaterProperties::onCommitSaleInfo(LLUICtrl* ctrl, void* data)
+void LLFloaterProperties::onCommitSaleInfo()
{
//llinfos << "LLFloaterProperties::onCommitSaleInfo()" << llendl;
- LLFloaterProperties* self = (LLFloaterProperties*)data;
- if(!self) return;
- self->updateSaleInfo();
+ updateSaleInfo();
}
// static
-void LLFloaterProperties::onCommitSaleType(LLUICtrl* ctrl, void* data)
+void LLFloaterProperties::onCommitSaleType()
{
//llinfos << "LLFloaterProperties::onCommitSaleType()" << llendl;
- LLFloaterProperties* self = (LLFloaterProperties*)data;
- if(!self) return;
- self->updateSaleInfo();
+ updateSaleInfo();
}
void LLFloaterProperties::updateSaleInfo()
@@ -851,13 +793,11 @@ void LLFloaterProperties::updateSaleInfo()
sale_type = LLSaleInfo::FS_ORIGINAL;
}
- LLLineEditor* EditPrice = getChild<LLLineEditor>("EditPrice");
+
S32 price = -1;
- if(EditPrice)
- {
- price = atoi(EditPrice->getText().c_str());
- }
+ price = getChild<LLUICtrl>("Edit Cost")->getValue().asInteger();;
+
// Invalid data - turn off the sale
if (price < 0)
{
@@ -932,13 +872,15 @@ LLInventoryItem* LLFloaterProperties::findItem() const
return item;
}
-void LLFloaterProperties::closeByID(const LLUUID& item_id, const LLUUID &object_id)
+//static
+void LLFloaterProperties::dirtyAll()
{
- LLFloaterProperties* floaterp = find(item_id, object_id);
-
- if (floaterp)
+ LLFloaterReg::const_instance_list_t& inst_list = LLFloaterReg::getFloaterList("properties");
+ for (LLFloaterReg::const_instance_list_t::const_iterator iter = inst_list.begin();
+ iter != inst_list.end(); ++iter)
{
- floaterp->close();
+ LLFloaterProperties* floater = dynamic_cast<LLFloaterProperties*>(*iter);
+ floater->dirty();
}
}
@@ -946,8 +888,24 @@ void LLFloaterProperties::closeByID(const LLUUID& item_id, const LLUUID &object_
/// LLMultiProperties
///----------------------------------------------------------------------------
-LLMultiProperties::LLMultiProperties(const LLRect &rect) : LLMultiFloater(std::string("Properties"), rect)
+LLMultiProperties::LLMultiProperties()
+ : LLMultiFloater(LLSD())
{
+ // *TODO: There should be a .xml file for this
+ const LLRect& nextrect = LLFloaterReg::getFloaterRect("properties"); // place where the next properties should show up
+ if (nextrect.getWidth() > 0)
+ {
+ setRect(nextrect);
+ }
+ else
+ {
+ // start with a small rect in the top-left corner ; will get resized
+ LLRect rect;
+ rect.setLeftTopAndSize(0, gViewerWindow->getWindowHeight(), 20, 20);
+ setRect(rect);
+ }
+ setTitle(LLTrans::getString("MultiPropertiesTitle"));
+ buildTabContainer();
}
///----------------------------------------------------------------------------
diff --git a/indra/newview/llfloaterproperties.h b/indra/newview/llfloaterproperties.h
index 2f5d97d384..586719a4dc 100644
--- a/indra/newview/llfloaterproperties.h
+++ b/indra/newview/llfloaterproperties.h
@@ -34,7 +34,7 @@
#define LL_LLFLOATERPROPERTIES_H
#include <map>
-#include "llfloater.h"
+#include "llmultifloater.h"
#include "lliconctrl.h"
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -53,30 +53,27 @@ class LLPropertiesObserver;
class LLFloaterProperties : public LLFloater
{
public:
- static LLFloaterProperties* find(const LLUUID& item_id,
- const LLUUID& object_id);
- static LLFloaterProperties* show(const LLUUID& item_id,
- const LLUUID& object_id);
- static void dirtyAll();
-
- static void closeByID(const LLUUID& item_id, const LLUUID& object_id);
-
- LLFloaterProperties(const std::string& name, const LLRect& rect, const std::string& title, const LLUUID& item_id, const LLUUID& object_id);
- virtual ~LLFloaterProperties();
+ LLFloaterProperties(const LLUUID& item_id);
+ /*virtual*/ ~LLFloaterProperties();
+
+ /*virtual*/ BOOL postBuild();
+ /*virtual*/ void onOpen(const LLSD& key);
+ void setObjectID(const LLUUID& object_id) { mObjectID = object_id; }
- // do everything necessary
void dirty() { mDirty = TRUE; }
void refresh();
-
+
+ static void dirtyAll();
+
protected:
// ui callbacks
- static void onClickCreator(void* data);
- static void onClickOwner(void* data);
- static void onCommitName(LLUICtrl* ctrl, void* data);
- static void onCommitDescription(LLUICtrl* ctrl, void* data);
- static void onCommitPermissions(LLUICtrl* ctrl, void* data);
- static void onCommitSaleInfo(LLUICtrl* ctrl, void* data);
- static void onCommitSaleType(LLUICtrl* ctrl, void* data);
+ void onClickCreator();
+ void onClickOwner();
+ void onCommitName();
+ void onCommitDescription();
+ void onCommitPermissions();
+ void onCommitSaleInfo();
+ void onCommitSaleType();
void updateSaleInfo();
LLInventoryItem* findItem() const;
@@ -93,18 +90,15 @@ protected:
// inventory.
LLUUID mObjectID;
- BOOL mDirty;
+ BOOL mDirty;
- typedef std::map<LLUUID, LLFloaterProperties*, lluuid_less> instance_map;
- static instance_map sInstances;
- static LLPropertiesObserver* sPropertiesObserver;
- static S32 sPropertiesObserverCount;
+ LLPropertiesObserver* mPropertiesObserver;
};
class LLMultiProperties : public LLMultiFloater
{
public:
- LLMultiProperties(const LLRect& rect);
+ LLMultiProperties();
};
#endif // LL_LLFLOATERPROPERTIES_H
diff --git a/indra/newview/llfloaterregioninfo.cpp b/indra/newview/llfloaterregioninfo.cpp
index 9d6c26d834..10276ba36d 100644
--- a/indra/newview/llfloaterregioninfo.cpp
+++ b/indra/newview/llfloaterregioninfo.cpp
@@ -58,12 +58,14 @@
#include "llfloatergodtools.h" // for send_sim_wide_deletes()
#include "llfloatertopobjects.h" // added to fix SL-32336
#include "llfloatergroups.h"
+#include "llfloaterreg.h"
#include "llfloatertelehub.h"
#include "llfloaterwindlight.h"
#include "llinventorymodel.h"
#include "lllineeditor.h"
#include "llalertdialog.h"
#include "llnamelistctrl.h"
+#include "llscrolllistitem.h"
#include "llsliderctrl.h"
#include "llspinctrl.h"
#include "lltabcontainer.h"
@@ -73,13 +75,16 @@
#include "lltrans.h"
#include "llviewercontrol.h"
#include "lluictrlfactory.h"
-#include "llviewerimage.h"
-#include "llviewerimagelist.h"
+#include "llviewerinventory.h"
+#include "llviewertexture.h"
+#include "llviewertexturelist.h"
#include "llviewerregion.h"
#include "llviewerstats.h"
#include "llviewertexteditor.h"
#include "llviewerwindow.h"
#include "llvlcomposition.h"
+#include "lltrans.h"
+#include "llagentui.h"
#define ELAR_ENABLED 0 // Enable when server support is implemented
@@ -161,8 +166,9 @@ bool estate_dispatch_initialized = false;
LLUUID LLFloaterRegionInfo::sRequestInvoice;
LLFloaterRegionInfo::LLFloaterRegionInfo(const LLSD& seed)
+ : LLFloater(seed)
{
- LLUICtrlFactory::getInstance()->buildFloater(this, "floater_region_info.xml", NULL, FALSE);
+ //LLUICtrlFactory::getInstance()->buildFloater(this, "floater_region_info.xml", FALSE);
}
BOOL LLFloaterRegionInfo::postBuild()
@@ -174,32 +180,32 @@ BOOL LLFloaterRegionInfo::postBuild()
panel = new LLPanelRegionGeneralInfo;
mInfoPanels.push_back(panel);
LLUICtrlFactory::getInstance()->buildPanel(panel, "panel_region_general.xml");
- mTab->addTabPanel(panel, panel->getLabel(), TRUE);
+ mTab->addTabPanel(LLTabContainer::TabPanelParams().panel(panel).select_tab(true));
panel = new LLPanelRegionDebugInfo;
mInfoPanels.push_back(panel);
LLUICtrlFactory::getInstance()->buildPanel(panel, "panel_region_debug.xml");
- mTab->addTabPanel(panel, panel->getLabel(), FALSE);
+ mTab->addTabPanel(panel);
panel = new LLPanelRegionTextureInfo;
mInfoPanels.push_back(panel);
LLUICtrlFactory::getInstance()->buildPanel(panel, "panel_region_texture.xml");
- mTab->addTabPanel(panel, panel->getLabel(), FALSE);
+ mTab->addTabPanel(panel);
panel = new LLPanelRegionTerrainInfo;
mInfoPanels.push_back(panel);
LLUICtrlFactory::getInstance()->buildPanel(panel, "panel_region_terrain.xml");
- mTab->addTabPanel(panel, panel->getLabel(), FALSE);
+ mTab->addTabPanel(panel);
panel = new LLPanelEstateInfo;
mInfoPanels.push_back(panel);
LLUICtrlFactory::getInstance()->buildPanel(panel, "panel_region_estate.xml");
- mTab->addTabPanel(panel, panel->getLabel(), FALSE);
+ mTab->addTabPanel(panel);
panel = new LLPanelEstateCovenant;
mInfoPanels.push_back(panel);
LLUICtrlFactory::getInstance()->buildPanel(panel, "panel_region_covenant.xml");
- mTab->addTabPanel(panel, panel->getLabel(), FALSE);
+ mTab->addTabPanel(panel);
gMessageSystem->setHandlerFunc(
"EstateOwnerMessage",
@@ -212,22 +218,16 @@ LLFloaterRegionInfo::~LLFloaterRegionInfo()
{
}
-void LLFloaterRegionInfo::onOpen()
+void LLFloaterRegionInfo::onOpen(const LLSD& key)
{
- LLRect rect = gSavedSettings.getRect("FloaterRegionInfo");
- S32 left, top;
- gFloaterView->getNewFloaterPosition(&left, &top);
- rect.translate(left,top);
-
refreshFromRegion(gAgent.getRegion());
requestRegionInfo();
- LLFloater::onOpen();
}
// static
void LLFloaterRegionInfo::requestRegionInfo()
{
- LLTabContainer* tab = findInstance()->getChild<LLTabContainer>("region_panels");
+ LLTabContainer* tab = getChild<LLTabContainer>("region_panels");
tab->getChild<LLPanel>("General")->setCtrlsEnabled(FALSE);
tab->getChild<LLPanel>("Debug")->setCtrlsEnabled(FALSE);
@@ -249,7 +249,8 @@ void LLFloaterRegionInfo::requestRegionInfo()
void LLFloaterRegionInfo::processEstateOwnerRequest(LLMessageSystem* msg,void**)
{
static LLDispatcher dispatch;
- if(!findInstance())
+ LLFloaterRegionInfo* floater = LLFloaterReg::getTypedInstance<LLFloaterRegionInfo>("region_info");
+ if(!floater)
{
return;
}
@@ -259,7 +260,7 @@ void LLFloaterRegionInfo::processEstateOwnerRequest(LLMessageSystem* msg,void**)
LLPanelEstateInfo::initDispatch(dispatch);
}
- LLTabContainer* tab = findInstance()->getChild<LLTabContainer>("region_panels");
+ LLTabContainer* tab = floater->getChild<LLTabContainer>("region_panels");
LLPanelEstateInfo* panel = (LLPanelEstateInfo*)tab->getChild<LLPanel>("Estate");
// unpack the message
@@ -285,14 +286,14 @@ void LLFloaterRegionInfo::processEstateOwnerRequest(LLMessageSystem* msg,void**)
void LLFloaterRegionInfo::processRegionInfo(LLMessageSystem* msg)
{
LLPanel* panel;
-
+ LLFloaterRegionInfo* floater = LLFloaterReg::getTypedInstance<LLFloaterRegionInfo>("region_info");
llinfos << "LLFloaterRegionInfo::processRegionInfo" << llendl;
- if(!findInstance())
+ if(!floater)
{
return;
}
- LLTabContainer* tab = findInstance()->getChild<LLTabContainer>("region_panels");
+ LLTabContainer* tab = floater->getChild<LLTabContainer>("region_panels");
LLViewerRegion* region = gAgent.getRegion();
BOOL allow_modify = gAgent.isGodlike() || (region && region->canManageEstate());
@@ -379,13 +380,13 @@ void LLFloaterRegionInfo::processRegionInfo(LLMessageSystem* msg)
panel->childSetEnabled("sun_hour_slider", allow_modify && !use_estate_sun);
panel->setCtrlsEnabled(allow_modify);
- getInstance()->refreshFromRegion( gAgent.getRegion() );
+ floater->refreshFromRegion( gAgent.getRegion() );
}
// static
LLPanelEstateInfo* LLFloaterRegionInfo::getPanelEstate()
{
- LLFloaterRegionInfo* floater = LLFloaterRegionInfo::getInstance();
+ LLFloaterRegionInfo* floater = LLFloaterReg::getTypedInstance<LLFloaterRegionInfo>("region_info");
if (!floater) return NULL;
LLTabContainer* tab = floater->getChild<LLTabContainer>("region_panels");
LLPanelEstateInfo* panel = (LLPanelEstateInfo*)tab->getChild<LLPanel>("Estate");
@@ -395,7 +396,7 @@ LLPanelEstateInfo* LLFloaterRegionInfo::getPanelEstate()
// static
LLPanelEstateCovenant* LLFloaterRegionInfo::getPanelCovenant()
{
- LLFloaterRegionInfo* floater = LLFloaterRegionInfo::getInstance();
+ LLFloaterRegionInfo* floater = LLFloaterReg::getTypedInstance<LLFloaterRegionInfo>("region_info");
if (!floater) return NULL;
LLTabContainer* tab = floater->getChild<LLTabContainer>("region_panels");
LLPanelEstateCovenant* panel = (LLPanelEstateCovenant*)tab->getChild<LLPanel>("Covenant");
@@ -436,6 +437,11 @@ void LLFloaterRegionInfo::refresh()
// LLPanelRegionInfo
//
+LLPanelRegionInfo::LLPanelRegionInfo()
+ : LLPanel()
+{
+}
+
// static
void LLPanelRegionInfo::onBtnSet(void* user_data)
{
@@ -608,7 +614,8 @@ BOOL LLPanelRegionGeneralInfo::postBuild()
childSetAction("kick_btn", onClickKick, this);
childSetAction("kick_all_btn", onClickKickAll, this);
childSetAction("im_btn", onClickMessage, this);
- childSetAction("manage_telehub_btn", onClickManageTelehub, this);
+// childSetAction("manage_telehub_btn", onClickManageTelehub, this);
+ mCommitCallbackRegistrar.add("RegionInfo.Cancel", boost::bind(&LLPanelRegionGeneralInfo::onClickManageTelehub, this));
return LLPanelRegionInfo::postBuild();
}
@@ -708,7 +715,7 @@ bool LLPanelRegionGeneralInfo::onMessageCommit(const LLSD& notification, const L
gAgent.getID().toString(buffer);
strings.push_back(buffer);
std::string name;
- gAgent.buildFullname(name);
+ LLAgentUI::buildFullname(name);
strings.push_back(strings_t::value_type(name));
strings.push_back(strings_t::value_type(text));
LLUUID invoice(LLFloaterRegionInfo::getLastInvoice());
@@ -716,12 +723,10 @@ bool LLPanelRegionGeneralInfo::onMessageCommit(const LLSD& notification, const L
return false;
}
-// static
-void LLPanelRegionGeneralInfo::onClickManageTelehub(void* data)
+void LLPanelRegionGeneralInfo::onClickManageTelehub()
{
- LLFloaterRegionInfo::getInstance()->close();
-
- LLFloaterTelehub::show();
+ LLFloaterReg::hideInstance("region_info");
+ LLFloaterReg::showInstance("telehubs");
}
// setregioninfo
@@ -955,8 +960,10 @@ void LLPanelRegionDebugInfo::onClickTopColliders(void* data)
strings_t strings;
strings.push_back("1"); // one physics step
LLUUID invoice(LLFloaterRegionInfo::getLastInvoice());
- LLFloaterTopObjects::show();
- LLFloaterTopObjects::clearList();
+ LLFloaterTopObjects* instance = LLFloaterReg::getTypedInstance<LLFloaterTopObjects>("top_objects");
+ if(!instance) return;
+ LLFloaterReg::showInstance("top_objects");
+ instance->clearList();
self->sendEstateOwnerMessage(gMessageSystem, "colliders", invoice, strings);
}
@@ -967,8 +974,10 @@ void LLPanelRegionDebugInfo::onClickTopScripts(void* data)
strings_t strings;
strings.push_back("6"); // top 5 scripts
LLUUID invoice(LLFloaterRegionInfo::getLastInvoice());
- LLFloaterTopObjects::show();
- LLFloaterTopObjects::clearList();
+ LLFloaterTopObjects* instance = LLFloaterReg::getTypedInstance<LLFloaterTopObjects>("top_objects");
+ if(!instance) return;
+ LLFloaterReg::showInstance("top_objects");
+ instance->clearList();
self->sendEstateOwnerMessage(gMessageSystem, "scripts", invoice, strings);
}
@@ -1074,7 +1083,7 @@ BOOL LLPanelRegionTextureInfo::postBuild()
initCtrl(buffer);
}
-// LLButton* btn = new LLButton("dump", LLRect(0, 20, 100, 0), "", onClickDump, this);
+// LLButton* btn = ("dump", LLRect(0, 20, 100, 0), "", onClickDump, this);
// btn->setFollows(FOLLOWS_TOP|FOLLOWS_LEFT);
// addChild(btn);
@@ -1136,11 +1145,11 @@ BOOL LLPanelRegionTextureInfo::validateTextureSizes()
if (!texture_ctrl) continue;
LLUUID image_asset_id = texture_ctrl->getImageAssetID();
- LLViewerImage* img = gImageList.getImage(image_asset_id);
+ LLViewerTexture* img = LLViewerTextureManager::getFetchedTexture(image_asset_id);
S32 components = img->getComponents();
// Must ask for highest resolution version's width. JC
- S32 width = img->getWidth(0);
- S32 height = img->getHeight(0);
+ S32 width = img->getFullWidth();
+ S32 height = img->getFullHeight();
//llinfos << "texture detail " << i << " is " << width << "x" << height << "x" << components << llendl;
@@ -1251,7 +1260,7 @@ BOOL LLPanelRegionTerrainInfo::sendUpdate()
// Grab estate information in case the user decided to set the
// region back to estate time. JC
- LLFloaterRegionInfo* floater = LLFloaterRegionInfo::getInstance();
+ LLFloaterRegionInfo* floater = LLFloaterReg::getTypedInstance<LLFloaterRegionInfo>("region_info");
if (!floater) return true;
LLTabContainer* tab = floater->getChild<LLTabContainer>("region_panels");
@@ -1363,9 +1372,10 @@ void LLPanelRegionTerrainInfo::onClickUploadRaw(void* data)
// static
void LLPanelRegionTerrainInfo::onClickBakeTerrain(void* data)
{
- LLNotifications::instance().add(
- LLNotification::Params("ConfirmBakeTerrain")
- .functor(boost::bind(&LLPanelRegionTerrainInfo::callbackBakeTerrain, (LLPanelRegionTerrainInfo*)data, _1, _2)));
+ LLNotification::Params::Functor functor_params;
+ functor_params.function(boost::bind(&LLPanelRegionTerrainInfo::callbackBakeTerrain, (LLPanelRegionTerrainInfo*)data, _1, _2));
+
+ LLNotifications::instance().add(LLNotification::Params("ConfirmBakeTerrain").functor(functor_params));
}
bool LLPanelRegionTerrainInfo::callbackBakeTerrain(const LLSD& notification, const LLSD& response)
@@ -1446,12 +1456,12 @@ void LLPanelEstateInfo::onChangeFixedSun(LLUICtrl* ctrl, void* user_data)
//---------------------------------------------------------------------------
void LLPanelEstateInfo::onClickEditSky(void* user_data)
{
- LLFloaterWindLight::show();
+ LLFloaterReg::showInstance("env_windlight");
}
void LLPanelEstateInfo::onClickEditDayCycle(void* user_data)
{
- LLFloaterDayCycle::show();
+ LLFloaterReg::showInstance("env_day_cycle");
}
// static
@@ -1478,11 +1488,9 @@ void LLPanelEstateInfo::onClickRemoveAllowedAgent(void* user_data)
accessRemoveCore(ESTATE_ACCESS_ALLOWED_AGENT_REMOVE, "EstateAllowedAgentRemove", "allowed_avatar_name_list");
}
-// static
-void LLPanelEstateInfo::onClickAddAllowedGroup(void* user_data)
+void LLPanelEstateInfo::onClickAddAllowedGroup()
{
- LLPanelEstateInfo* self = (LLPanelEstateInfo*)user_data;
- LLCtrlListInterface *list = self->childGetListInterface("allowed_group_name_list");
+ LLCtrlListInterface *list = childGetListInterface("allowed_group_name_list");
if (!list) return;
if (list->getItemCount() >= ESTATE_MAX_ACCESS_IDS)
{
@@ -1493,7 +1501,7 @@ void LLPanelEstateInfo::onClickAddAllowedGroup(void* user_data)
}
LLNotification::Params params("ChangeLindenAccess");
- params.functor(boost::bind(&LLPanelEstateInfo::addAllowedGroup, self, _1, _2));
+ params.functor.function(boost::bind(&LLPanelEstateInfo::addAllowedGroup, this, _1, _2));
if (isLindenEstate())
{
LLNotifications::instance().add(params);
@@ -1511,11 +1519,10 @@ bool LLPanelEstateInfo::addAllowedGroup(const LLSD& notification, const LLSD& re
LLFloater* parent_floater = gFloaterView->getParentFloater(this);
- LLFloaterGroupPicker* widget;
- widget = LLFloaterGroupPicker::showInstance(LLSD(gAgent.getID()));
+ LLFloaterGroupPicker* widget = LLFloaterReg::showTypedInstance<LLFloaterGroupPicker>("group_picker", LLSD(gAgent.getID()));
if (widget)
{
- widget->setSelectCallback(addAllowedGroup2, NULL);
+ widget->setSelectGroupCallback(boost::bind(&LLPanelEstateInfo::addAllowedGroup2, this, _1));
if (parent_floater)
{
LLRect new_rect = gFloaterView->findNeighboringPosition(parent_floater, widget);
@@ -1656,26 +1663,29 @@ bool LLPanelEstateInfo::kickUserConfirm(const LLSD& notification, const LLSD& re
std::string all_estates_text()
{
LLPanelEstateInfo* panel = LLFloaterRegionInfo::getPanelEstate();
- if (!panel) return "(error)";
+ if (!panel) return "(" + LLTrans::getString("RegionInfoError") + ")";
+ LLStringUtil::format_map_t args;
std::string owner = panel->getOwnerName();
LLViewerRegion* region = gAgent.getRegion();
if (gAgent.isGodlike())
{
- return llformat("all estates\nowned by %s", owner.c_str());
+ args["[OWNER]"] = owner.c_str();
+ return LLTrans::getString("RegionInfoAllEstatesOwnedBy", args);
}
else if (region && region->getOwner() == gAgent.getID())
{
- return "all estates you own";
+ return LLTrans::getString("AllEstatesYouOwn");
}
else if (region && region->isEstateManager())
{
- return llformat("all estates that\nyou manage for %s", owner.c_str());
+ args["[OWNER]"] = owner.c_str();
+ return LLTrans::getString("RegionInfoAllEstatesYouManage", args);
}
else
{
- return "(error)";
+ return "(" + LLTrans::getString("RegionInfoError") + ")";
}
}
@@ -1725,8 +1735,7 @@ struct LLEstateAccessChangeInfo
};
// Special case callback for groups, since it has different callback format than names
-// static
-void LLPanelEstateInfo::addAllowedGroup2(LLUUID id, void* user_data)
+void LLPanelEstateInfo::addAllowedGroup2(LLUUID id)
{
LLSD payload;
payload["operation"] = (S32)ESTATE_ACCESS_ALLOWED_GROUP_ADD;
@@ -1739,7 +1748,7 @@ void LLPanelEstateInfo::addAllowedGroup2(LLUUID id, void* user_data)
LLNotification::Params params("EstateAllowedGroupAdd");
params.payload(payload)
.substitutions(args)
- .functor(accessCoreConfirm);
+ .functor.function(accessCoreConfirm);
if (isLindenEstate())
{
LLNotifications::instance().forceResponse(params, 0);
@@ -1760,7 +1769,7 @@ void LLPanelEstateInfo::accessAddCore(U32 operation_flag, const std::string& dia
LLNotification::Params params("ChangeLindenAccess");
params.payload(payload)
- .functor(accessAddCore2);
+ .functor.function(accessAddCore2);
if (isLindenEstate())
{
@@ -1848,7 +1857,7 @@ void LLPanelEstateInfo::accessAddCore3(const std::vector<std::string>& names, co
LLNotification::Params params(change_info->mDialogName);
params.substitutions(args)
.payload(change_info->asLLSD())
- .functor(accessCoreConfirm);
+ .functor.function(accessCoreConfirm);
if (isLindenEstate())
{
@@ -1888,7 +1897,7 @@ void LLPanelEstateInfo::accessRemoveCore(U32 operation_flag, const std::string&
LLNotification::Params params("ChangeLindenAccess");
params.payload(payload)
- .functor(accessRemoveCore2);
+ .functor.function(accessRemoveCore2);
if (isLindenEstate())
{
@@ -2121,7 +2130,7 @@ BOOL LLPanelEstateInfo::postBuild()
initCtrl("limit_age_verified");
initCtrl("voice_chat_check");
childSetCommitCallback("abuse_email_address", onChangeAnything, this);
- childSetKeystrokeCallback("abuse_email_address", onChangeText, this);
+ getChild<LLLineEditor>("abuse_email_address")->setKeystrokeCallback(onChangeText, this);
initHelpBtn("estate_manager_help", "HelpEstateEstateManager");
initHelpBtn("use_global_time_help", "HelpEstateUseGlobalTime");
@@ -2161,7 +2170,7 @@ BOOL LLPanelEstateInfo::postBuild()
group_name_list->setMaxItemCount(ESTATE_MAX_ACCESS_IDS);
}
- childSetAction("add_allowed_group_btn", onClickAddAllowedGroup, this);
+ getChild<LLUICtrl>("add_allowed_group_btn")->setCommitCallback(boost::bind(&LLPanelEstateInfo::onClickAddAllowedGroup, this));
childSetAction("remove_allowed_group_btn", onClickRemoveAllowedGroup, this);
childSetCommitCallback("banned_avatar_name_list", onChangeChildCtrl, this);
@@ -2213,7 +2222,7 @@ BOOL LLPanelEstateInfo::sendUpdate()
llinfos << "LLPanelEsateInfo::sendUpdate()" << llendl;
LLNotification::Params params("ChangeLindenEstate");
- params.functor(boost::bind(&LLPanelEstateInfo::callbackChangeLindenEstate, this, _1, _2));
+ params.functor.function(boost::bind(&LLPanelEstateInfo::callbackChangeLindenEstate, this, _1, _2));
if (getEstateID() <= ESTATE_LAST_LINDEN)
{
@@ -2556,8 +2565,7 @@ void LLPanelEstateInfo::callbackCacheName(
const LLUUID& id,
const std::string& first,
const std::string& last,
- BOOL is_group,
- void*)
+ BOOL is_group)
{
LLPanelEstateInfo* self = LLFloaterRegionInfo::getPanelEstate();
if (!self) return;
@@ -2652,7 +2660,7 @@ bool LLPanelEstateInfo::onMessageCommit(const LLSD& notification, const LLSD& re
strings_t strings;
//integers_t integers;
std::string name;
- gAgent.buildFullname(name);
+ LLAgentUI::buildFullname(name);
strings.push_back(strings_t::value_type(name));
strings.push_back(strings_t::value_type(text));
LLUUID invoice(LLFloaterRegionInfo::getLastInvoice());
@@ -2739,7 +2747,6 @@ BOOL LLPanelEstateCovenant::postBuild()
mEstateOwnerText = getChild<LLTextBox>("estate_owner_text");
mLastModifiedText = getChild<LLTextBox>("covenant_timestamp_text");
mEditor = getChild<LLViewerTextEditor>("covenant_editor");
- if (mEditor) mEditor->setHandleEditKeysDirectly(TRUE);
LLButton* reset_button = getChild<LLButton>("reset_covenant");
reset_button->setEnabled(gAgent.canManageEstate());
reset_button->setClickedCallback(LLPanelEstateCovenant::resetCovenantID, NULL);
@@ -2852,7 +2859,7 @@ void LLPanelEstateCovenant::loadInvItem(LLInventoryItem *itemp)
else
{
mAssetStatus = ASSET_LOADED;
- setCovenantTextEditor("There is no Covenant provided for this Estate.");
+ setCovenantTextEditor(LLTrans::getString("RegionNoCovenant"));
sendChangeCovenantID(LLUUID::null);
}
}
@@ -3063,7 +3070,7 @@ bool LLDispatchEstateUpdateInfo::operator()(
regionp->setOwner(owner_id);
// Update estate owner name in UI
const BOOL is_group = FALSE;
- gCacheName->getNameFromUUID(owner_id, is_group, LLPanelEstateInfo::callbackCacheName);
+ gCacheName->get(owner_id, is_group, &LLPanelEstateInfo::callbackCacheName);
U32 estate_id = strtoul(strings[2].c_str(), NULL, 10);
panel->setEstateID(estate_id);
@@ -3162,9 +3169,10 @@ bool LLDispatchSetEstateAccess::operator()(
totalAllowedAgents += allowed_agent_name_list->getItemCount();
}
- std::string msg = llformat("Allowed residents: (%d, max %d)",
- totalAllowedAgents,
- ESTATE_MAX_ACCESS_IDS);
+ LLStringUtil::format_map_t args;
+ args["[ALLOWEDAGENTS]"] = llformat ("%d", totalAllowedAgents);
+ args["[MAXACCESS]"] = llformat ("%d", ESTATE_MAX_ACCESS_IDS);
+ std::string msg = LLTrans::getString("RegionInfoAllowedResidents", args);
panel->childSetValue("allow_resident_label", LLSD(msg));
if (allowed_agent_name_list)
@@ -3186,9 +3194,10 @@ bool LLDispatchSetEstateAccess::operator()(
LLNameListCtrl* allowed_group_name_list;
allowed_group_name_list = panel->getChild<LLNameListCtrl>("allowed_group_name_list");
- std::string msg = llformat("Allowed groups: (%d, max %d)",
- num_allowed_groups,
- (S32) ESTATE_MAX_GROUP_IDS);
+ LLStringUtil::format_map_t args;
+ args["[ALLOWEDGROUPS]"] = llformat ("%d", num_allowed_groups);
+ args["[MAXACCESS]"] = llformat ("%d", ESTATE_MAX_GROUP_IDS);
+ std::string msg = LLTrans::getString("RegionInfoAllowedGroups", args);
panel->childSetValue("allow_group_label", LLSD(msg));
if (allowed_group_name_list)
diff --git a/indra/newview/llfloaterregioninfo.h b/indra/newview/llfloaterregioninfo.h
index 806d1f57d6..be4becf7e7 100644
--- a/indra/newview/llfloaterregioninfo.h
+++ b/indra/newview/llfloaterregioninfo.h
@@ -59,13 +59,13 @@ class LLPanelRegionTerrainInfo;
class LLPanelEstateInfo;
class LLPanelEstateCovenant;
-class LLFloaterRegionInfo : public LLFloater, public LLFloaterSingleton<LLFloaterRegionInfo>
+class LLFloaterRegionInfo : public LLFloater
{
- friend class LLUISingleton<LLFloaterRegionInfo, VisibilityPolicy<LLFloater> >;
+ friend class LLFloaterReg;
public:
- ~LLFloaterRegionInfo();
- /*virtual*/ void onOpen();
+
+ /*virtual*/ void onOpen(const LLSD& key);
/*virtual*/ BOOL postBuild();
static void processEstateOwnerRequest(LLMessageSystem* msg, void**);
@@ -84,10 +84,14 @@ public:
// from LLPanel
virtual void refresh();
- static void requestRegionInfo();
+ void requestRegionInfo();
-protected:
+private:
+
LLFloaterRegionInfo(const LLSD& seed);
+ ~LLFloaterRegionInfo();
+
+protected:
void refreshFromRegion(LLViewerRegion* region);
// member data
@@ -103,7 +107,8 @@ protected:
class LLPanelRegionInfo : public LLPanel
{
public:
- LLPanelRegionInfo() : LLPanel(std::string("Region Info Panel")) {}
+ LLPanelRegionInfo();
+
static void onBtnSet(void* user_data);
static void onChangeChildCtrl(LLUICtrl* ctrl, void* user_data);
static void onChangeAnything(LLUICtrl* ctrl, void* user_data);
@@ -165,7 +170,7 @@ protected:
bool onKickAllCommit(const LLSD& notification, const LLSD& response);
static void onClickMessage(void* userdata);
bool onMessageCommit(const LLSD& notification, const LLSD& response);
- static void onClickManageTelehub(void* data);
+ void onClickManageTelehub();
};
/////////////////////////////////////////////////////////////////////////////
@@ -261,7 +266,7 @@ public:
static void onClickAddAllowedAgent(void* user_data);
static void onClickRemoveAllowedAgent(void* user_data);
- static void onClickAddAllowedGroup(void* user_data);
+ void onClickAddAllowedGroup();
static void onClickRemoveAllowedGroup(void* user_data);
static void onClickAddBannedAgent(void* user_data);
static void onClickRemoveBannedAgent(void* user_data);
@@ -271,7 +276,7 @@ public:
// Group picker callback is different, can't use core methods below
bool addAllowedGroup(const LLSD& notification, const LLSD& response);
- static void addAllowedGroup2(LLUUID id, void* data);
+ void addAllowedGroup2(LLUUID id);
// Core methods for all above add/remove button clicks
static void accessAddCore(U32 operation_flag, const std::string& dialog_name);
@@ -339,8 +344,7 @@ public:
const LLUUID& id,
const std::string& first,
const std::string& last,
- BOOL is_group,
- void*);
+ BOOL is_group);
protected:
virtual BOOL sendUpdate();
diff --git a/indra/newview/llfloaterreporter.cpp b/indra/newview/llfloaterreporter.cpp
index 412494eeb3..4d154c4cd3 100644
--- a/indra/newview/llfloaterreporter.cpp
+++ b/indra/newview/llfloaterreporter.cpp
@@ -48,19 +48,19 @@
#include "llversionviewer.h"
#include "message.h"
#include "v3math.h"
+#include "lltexteditor.h"
// viewer project includes
#include "llagent.h"
#include "llbutton.h"
#include "llcheckboxctrl.h"
-#include "llinventoryview.h"
+#include "llfloaterreg.h"
#include "lllineeditor.h"
#include "lltexturectrl.h"
#include "llscrolllistctrl.h"
#include "llimview.h"
#include "lltextbox.h"
#include "lldispatcher.h"
-#include "llviewertexteditor.h"
#include "llviewerobject.h"
#include "llviewerregion.h"
#include "llcombobox.h"
@@ -73,7 +73,7 @@
#include "lltoolmgr.h"
#include "llresourcedata.h" // for LLResourceData
#include "llviewerwindow.h"
-#include "llviewerimagelist.h"
+#include "llviewertexturelist.h"
#include "llworldmap.h"
#include "llfilepicker.h"
#include "llfloateravatarpicker.h"
@@ -84,6 +84,7 @@
#include "llviewernetwork.h"
#include "llassetuploadresponders.h"
+#include "llagentui.h"
const U32 INCLUDE_SCREENSHOT = 0x01 << 0;
@@ -91,28 +92,14 @@ const U32 INCLUDE_SCREENSHOT = 0x01 << 0;
// Globals
//-----------------------------------------------------------------------------
-// this map keeps track of current reporter instances
-// there can only be one instance of each reporter type
-LLMap< EReportType, LLFloaterReporter* > gReporterInstances;
-
-// keeps track of where email is going to - global to avoid a pile
-// of static/non-static access outside my control
-namespace {
- static BOOL gEmailToEstateOwner = FALSE;
- static BOOL gDialogVisible = FALSE;
-}
-
//-----------------------------------------------------------------------------
// Member functions
//-----------------------------------------------------------------------------
-LLFloaterReporter::LLFloaterReporter(
- const std::string& name,
- const LLRect& rect,
- const std::string& title,
- EReportType report_type)
- :
- LLFloater(name, rect, title),
- mReportType(report_type),
+
+LLFloaterReporter::LLFloaterReporter(const LLSD& key)
+: LLFloater(key),
+ mReportType(COMPLAINT_REPORT),
+ mEmailToEstateOwner(FALSE),
mObjectID(),
mScreenID(),
mAbuserID(),
@@ -122,37 +109,35 @@ LLFloaterReporter::LLFloaterReporter(
mCopyrightWarningSeen( FALSE ),
mResourceDatap(new LLResourceData())
{
- if (report_type == BUG_REPORT)
- {
- LLUICtrlFactory::getInstance()->buildFloater(this, "floater_report_bug.xml");
- }
- else
- {
- LLUICtrlFactory::getInstance()->buildFloater(this, "floater_report_abuse.xml");
- }
-
- childSetText("abuse_location_edit", gAgent.getSLURL() );
-
- LLButton* pick_btn = getChild<LLButton>("pick_btn");
- if (pick_btn)
- {
- // XUI: Why aren't these in viewerart.ini?
- pick_btn->setImages( std::string("UIImgFaceUUID"),
- std::string("UIImgFaceSelectedUUID") );
- childSetAction("pick_btn", onClickObjPicker, this);
- }
+ //LLUICtrlFactory::getInstance()->buildFloater(this, "floater_report_abuse.xml");
+}
- if (report_type != BUG_REPORT)
+// static
+void LLFloaterReporter::processRegionInfo(LLMessageSystem* msg)
+{
+ U32 region_flags;
+ msg->getU32("RegionInfo", "RegionFlags", region_flags);
+
+ if ( LLFloaterReg::instanceVisible("reporter") )
{
- // abuser name is selected from a list
- LLLineEditor* le = getChild<LLLineEditor>("abuser_name_edit");
- le->setEnabled( FALSE );
- }
-
- childSetAction("select_abuser", onClickSelectAbuser, this);
+ LLFloaterReporter *f = LLFloaterReg::findTypedInstance<LLFloaterReporter>("reporter");
+ BOOL email_to_estate_owner = ( region_flags & REGION_FLAGS_ABUSE_EMAIL_TO_ESTATE_OWNER );
+ f->mEmailToEstateOwner = email_to_estate_owner;
- childSetAction("send_btn", onClickSend, this);
- childSetAction("cancel_btn", onClickCancel, this);
+ if ( email_to_estate_owner )
+ {
+ LLNotifications::instance().add("HelpReportAbuseEmailEO");
+ }
+ else
+ {
+ LLNotifications::instance().add("HelpReportAbuseEmailLL");
+ }
+ };
+}
+// virtual
+BOOL LLFloaterReporter::postBuild()
+{
+ childSetText("abuse_location_edit", LLAgentUI::buildSLURL());
enableControls(TRUE);
@@ -165,8 +150,6 @@ LLFloaterReporter::LLFloaterReporter(
}
setPosBox(pos);
- gReporterInstances.addData(report_type, this);
-
// Take a screenshot, but don't draw this floater.
setVisible(FALSE);
takeScreenshot();
@@ -180,44 +163,43 @@ LLFloaterReporter::LLFloaterReporter(
mDefaultSummary = childGetText("details_edit");
- gDialogVisible = TRUE;
+ // send a message and ask for information about this region -
+ // result comes back in processRegionInfo(..)
+ LLMessageSystem* msg = gMessageSystem;
+ msg->newMessage("RequestRegionInfo");
+ msg->nextBlock("AgentData");
+ msg->addUUID("AgentID", gAgent.getID());
+ msg->addUUID("SessionID", gAgent.getSessionID());
+ gAgent.sendReliableMessage();
+
+
+ // abuser name is selected from a list
+ LLLineEditor* le = getChild<LLLineEditor>("abuser_name_edit");
+ le->setEnabled( FALSE );
- // only request details for abuse reports (not BUG reports)
- if (report_type != BUG_REPORT)
- {
- // send a message and ask for information about this region -
- // result comes back in processRegionInfo(..)
- LLMessageSystem* msg = gMessageSystem;
- msg->newMessage("RequestRegionInfo");
- msg->nextBlock("AgentData");
- msg->addUUID("AgentID", gAgent.getID());
- msg->addUUID("SessionID", gAgent.getSessionID());
- gAgent.sendReliableMessage();
- };
-}
+ setPosBox((LLVector3d)mPosition.getValue());
+ LLButton* pick_btn = getChild<LLButton>("pick_btn");
+ pick_btn->setImages(std::string("tool_face.tga"),
+ std::string("tool_face_active.tga") );
+ childSetAction("pick_btn", onClickObjPicker, this);
-// static
-void LLFloaterReporter::processRegionInfo(LLMessageSystem* msg)
-{
- U32 region_flags;
- msg->getU32("RegionInfo", "RegionFlags", region_flags);
- gEmailToEstateOwner = ( region_flags & REGION_FLAGS_ABUSE_EMAIL_TO_ESTATE_OWNER );
+ childSetAction("select_abuser", onClickSelectAbuser, this);
- if ( gDialogVisible )
- {
- if ( gEmailToEstateOwner )
- {
- LLNotifications::instance().add("HelpReportAbuseEmailEO");
- }
- else
- LLNotifications::instance().add("HelpReportAbuseEmailLL");
- };
-}
+ childSetAction("send_btn", onClickSend, this);
+ childSetAction("cancel_btn", onClickCancel, this);
+
+ // grab the user's name
+ std::string fullname;
+ LLAgentUI::buildFullname(fullname);
+ childSetText("reporter_field", fullname);
+
+ center();
+ return TRUE;
+}
// virtual
LLFloaterReporter::~LLFloaterReporter()
{
- gReporterInstances.removeData(mReportType);
// child views automatically deleted
mObjectID = LLUUID::null;
@@ -232,7 +214,6 @@ LLFloaterReporter::~LLFloaterReporter()
mMCDList.clear();
delete mResourceDatap;
- gDialogVisible = FALSE;
}
// virtual
@@ -241,7 +222,7 @@ void LLFloaterReporter::draw()
// this is set by a static callback sometime after the dialog is created.
// Only disable screenshot for abuse reports to estate owners - bug reports always
// allow screenshots to be taken.
- if ( gEmailToEstateOwner && ( mReportType != BUG_REPORT ) )
+ if ( mEmailToEstateOwner )
{
childSetValue("screen_check", FALSE );
childSetEnabled("screen_check", FALSE );
@@ -257,11 +238,7 @@ void LLFloaterReporter::draw()
void LLFloaterReporter::enableControls(BOOL enable)
{
childSetEnabled("category_combo", enable);
- // bug reports never include the chat history
- if (mReportType != BUG_REPORT)
- {
- childSetEnabled("chat_check", enable);
- }
+ childSetEnabled("chat_check", enable);
childSetEnabled("screen_check", enable);
childDisable("screenshot");
childSetEnabled("pick_btn", enable);
@@ -332,7 +309,7 @@ void LLFloaterReporter::getObjectInfo(const LLUUID& object_id)
// we have to query the simulator for information
// about this object
LLMessageSystem* msg = gMessageSystem;
- U32 request_flags = (mReportType == BUG_REPORT) ? BUG_REPORT_REQUEST : COMPLAINT_REPORT_REQUEST;
+ U32 request_flags = COMPLAINT_REPORT_REQUEST;
msg->newMessageFast(_PREHASH_RequestObjectPropertiesFamily);
msg->nextBlockFast(_PREHASH_AgentData);
msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
@@ -363,15 +340,12 @@ void LLFloaterReporter::callbackAvatarID(const std::vector<std::string>& names,
if (ids.empty() || names.empty()) return;
- // this should never be called in a bug report but here for safety.
- if ( self->mReportType != BUG_REPORT )
- {
- self->childSetText("abuser_name_edit", names[0] );
-
- self->mAbuserID = ids[0];
+ self->childSetText("abuser_name_edit", names[0] );
+
+ self->mAbuserID = ids[0];
+
+ self->refresh();
- self->refresh();
- };
}
// static
@@ -386,9 +360,7 @@ void LLFloaterReporter::onClickSend(void *userdata)
if(self->validateReport())
{
- // only show copyright alert for abuse reports
- if ( self->mReportType != BUG_REPORT )
- {
+
const int IP_CONTENT_REMOVAL = 66;
const int IP_PERMISSONS_EXPLOIT = 37;
LLComboBox* combo = self->getChild<LLComboBox>( "category_combo");
@@ -418,7 +390,7 @@ void LLFloaterReporter::onClickSend(void *userdata)
LLNotifications::instance().add("HelpReportAbuseContainsCopyright");
return;
}
- }
+
LLUploadDialog::modalUploadDialog("Uploading...\n\nReport");
// *TODO don't upload image if checkbox isn't checked
@@ -427,7 +399,7 @@ void LLFloaterReporter::onClickSend(void *userdata)
if(!url.empty() || !sshot_url.empty())
{
self->sendReportViaCaps(url, sshot_url, self->gatherReport());
- self->close();
+ self->closeFloater();
}
else
{
@@ -442,7 +414,7 @@ void LLFloaterReporter::onClickSend(void *userdata)
{
self->sendReportViaLegacy(self->gatherReport());
LLUploadDialog::modalUploadFinished();
- self->close();
+ self->closeFloater();
}
}
}
@@ -461,7 +433,7 @@ void LLFloaterReporter::onClickCancel(void *userdata)
{
closePickTool(self);
}
- self->close();
+ self->closeFloater();
}
@@ -497,30 +469,16 @@ void LLFloaterReporter::closePickTool(void *userdata)
// static
void LLFloaterReporter::showFromMenu(EReportType report_type)
{
- if (gReporterInstances.checkData(report_type))
+ if (COMPLAINT_REPORT != report_type)
{
- // ...bring that window to front
- LLFloaterReporter *f = gReporterInstances.getData(report_type);
- f->open(); /* Flawfinder: ignore */
+ llwarns << "Unknown LLViewerReporter type : " << report_type << llendl;
+ return;
}
- else
+
+ LLFloaterReporter* f = LLFloaterReg::showTypedInstance<LLFloaterReporter>("reporter", LLSD());
+ if (f)
{
- LLFloaterReporter *f;
- if (BUG_REPORT == report_type)
- {
- f = LLFloaterReporter::createNewBugReporter();
- }
- else if (COMPLAINT_REPORT == report_type)
- {
- f = LLFloaterReporter::createNewAbuseReporter();
- }
- else
- {
- llwarns << "Unknown LLViewerReporter type : " << report_type << llendl;
- return;
- }
-
- f->center();
+ f->setReportType(report_type);
if (report_type == BUG_REPORT)
{
@@ -530,11 +488,6 @@ void LLFloaterReporter::showFromMenu(EReportType report_type)
{
// popup for abuse reports is triggered elsewhere
}
-
- // grab the user's name
- std::string fullname;
- gAgent.buildFullname(fullname);
- f->childSetText("reporter_field", fullname);
}
}
@@ -542,13 +495,11 @@ void LLFloaterReporter::showFromMenu(EReportType report_type)
// static
void LLFloaterReporter::showFromObject(const LLUUID& object_id)
{
- LLFloaterReporter* f = createNewAbuseReporter();
- f->center();
- f->setFocus(TRUE);
+ LLFloaterReporter* f = LLFloaterReg::showTypedInstance<LLFloaterReporter>("reporter");
// grab the user's name
std::string fullname;
- gAgent.buildFullname(fullname);
+ LLAgentUI::buildFullname(fullname);
f->childSetText("reporter_field", fullname);
// Request info for this object
@@ -557,39 +508,8 @@ void LLFloaterReporter::showFromObject(const LLUUID& object_id)
// Need to deselect on close
f->mDeselectOnClose = TRUE;
- f->open(); /* Flawfinder: ignore */
-}
-
-
-// static
-LLFloaterReporter* LLFloaterReporter::getReporter(EReportType report_type)
-{
- LLFloaterReporter *self = NULL;
- if (gReporterInstances.checkData(report_type))
- {
- // ...bring that window to front
- self = gReporterInstances.getData(report_type);
- }
- return self;
-}
-
-LLFloaterReporter* LLFloaterReporter::createNewAbuseReporter()
-{
- return new LLFloaterReporter("complaint_reporter",
- LLRect(),
- "Report Abuse",
- COMPLAINT_REPORT);
-}
-
-//static
-LLFloaterReporter* LLFloaterReporter::createNewBugReporter()
-{
- return new LLFloaterReporter("bug_reporter",
- LLRect(),
- "Report Bug",
- BUG_REPORT);
+ f->openFloater();
}
-
void LLFloaterReporter::setPickedObjectProperties(const std::string& object_name, const std::string& owner_name, const LLUUID owner_id)
@@ -619,21 +539,26 @@ bool LLFloaterReporter::validateReport()
return false;
}
- if ( mReportType != BUG_REPORT )
+
+ if ( childGetText("abuser_name_edit").empty() )
+ {
+ LLNotifications::instance().add("HelpReportAbuseAbuserNameEmpty");
+ return false;
+ };
+
+ if ( childGetText("abuse_location_edit").empty() )
+ {
+ LLNotifications::instance().add("HelpReportAbuseAbuserLocationEmpty");
+ return false;
+ };
+
+ if ( childGetText("abuse_location_edit").empty() )
{
- if ( childGetText("abuser_name_edit").empty() )
- {
- LLNotifications::instance().add("HelpReportAbuseAbuserNameEmpty");
- return false;
- };
-
- if ( childGetText("abuse_location_edit").empty() )
- {
- LLNotifications::instance().add("HelpReportAbuseAbuserLocationEmpty");
- return false;
- };
+ LLNotifications::instance().add("HelpReportAbuseAbuserLocationEmpty");
+ return false;
};
+
if ( childGetText("summary_edit").empty() )
{
if ( mReportType != BUG_REPORT )
@@ -685,50 +610,34 @@ LLSD LLFloaterReporter::gatherReport()
#if LL_WINDOWS
const char* platform = "Win";
- const char* short_platform = "O:W";
#elif LL_DARWIN
const char* platform = "Mac";
- const char* short_platform = "O:M";
#elif LL_LINUX
const char* platform = "Lnx";
- const char* short_platform = "O:L";
#elif LL_SOLARIS
const char* platform = "Sol";
const char* short_platform = "O:S";
#else
const char* platform = "???";
- const char* short_platform = "O:?";
#endif
- if ( mReportType == BUG_REPORT)
- {
- summary << short_platform << " V" << LL_VERSION_MAJOR << "."
- << LL_VERSION_MINOR << "."
- << LL_VERSION_PATCH << "."
- << LL_VIEWER_BUILD
- << " (" << regionp->getName() << ")"
- << "[" << category_name << "] "
- << "\"" << childGetValue("summary_edit").asString() << "\"";
- }
- else
- {
- summary << ""
- << " |" << regionp->getName() << "|" // region reporter is currently in.
- << " (" << childGetText("abuse_location_edit") << ")" // region abuse occured in (freeform text - no LLRegionPicker tool)
- << " [" << category_name << "] " // updated category
- << " {" << childGetText("abuser_name_edit") << "} " // name of abuse entered in report (chosen using LLAvatarPicker)
- << " \"" << childGetValue("summary_edit").asString() << "\""; // summary as entered
- };
+
+ summary << ""
+ << " |" << regionp->getName() << "|" // region reporter is currently in.
+ << " (" << childGetText("abuse_location_edit") << ")" // region abuse occured in (freeform text - no LLRegionPicker tool)
+ << " [" << category_name << "] " // updated category
+ << " {" << childGetText("abuser_name_edit") << "} " // name of abuse entered in report (chosen using LLAvatarPicker)
+ << " \"" << childGetValue("summary_edit").asString() << "\""; // summary as entered
+
std::ostringstream details;
- if (mReportType != BUG_REPORT)
- {
- details << "V" << LL_VERSION_MAJOR << "." // client version moved to body of email for abuse reports
- << LL_VERSION_MINOR << "."
- << LL_VERSION_PATCH << "."
- << LL_VIEWER_BUILD << std::endl << std::endl;
- }
+
+ details << "V" << LL_VERSION_MAJOR << "." // client version moved to body of email for abuse reports
+ << LL_VERSION_MINOR << "."
+ << LL_VERSION_PATCH << "."
+ << LL_VIEWER_BUILD << std::endl << std::endl;
+
std::string object_name = childGetText("object_name");
std::string owner_name = childGetText("owner_name");
if (!object_name.empty() && !owner_name.empty())
@@ -737,11 +646,9 @@ LLSD LLFloaterReporter::gatherReport()
details << "Owner: " << owner_name << "\n";
}
- if ( mReportType != BUG_REPORT )
- {
- details << "Abuser name: " << childGetText("abuser_name_edit") << " \n";
- details << "Abuser location: " << childGetText("abuse_location_edit") << " \n";
- };
+
+ details << "Abuser name: " << childGetText("abuser_name_edit") << " \n";
+ details << "Abuser location: " << childGetText("abuse_location_edit") << " \n";
details << childGetValue("details_edit").asString();
@@ -761,17 +668,11 @@ LLSD LLFloaterReporter::gatherReport()
LLUUID screenshot_id = LLUUID::null;
if (childGetValue("screen_check"))
{
- if ( mReportType != BUG_REPORT )
- {
- if ( gEmailToEstateOwner == FALSE )
- {
- screenshot_id = childGetValue("screenshot");
- }
- }
- else
+
+ if ( mEmailToEstateOwner == FALSE )
{
screenshot_id = childGetValue("screenshot");
- };
+ }
};
LLSD report = LLSD::emptyMap();
@@ -883,7 +784,7 @@ void LLFloaterReporter::takeScreenshot()
llwarns << "Unable to take screenshot" << llendl;
return;
}
- LLPointer<LLImageJ2C> upload_data = LLViewerImageList::convertToUploadFile(raw);
+ LLPointer<LLImageJ2C> upload_data = LLViewerTextureList::convertToUploadFile(raw);
// create a resource data
mResourceDatap->mInventoryType = LLInventoryType::IT_NONE;
@@ -891,12 +792,8 @@ void LLFloaterReporter::takeScreenshot()
mResourceDatap->mExpectedUploadCost = 0; // we expect that abuse screenshots are free
mResourceDatap->mAssetInfo.mTransactionID.generate();
mResourceDatap->mAssetInfo.mUuid = mResourceDatap->mAssetInfo.mTransactionID.makeAssetID(gAgent.getSecureSessionID());
- if (BUG_REPORT == mReportType)
- {
- mResourceDatap->mAssetInfo.mType = LLAssetType::AT_TEXTURE;
- mResourceDatap->mPreferredLocation = LLAssetType::EType(-1);
- }
- else if (COMPLAINT_REPORT == mReportType)
+
+ if (COMPLAINT_REPORT == mReportType)
{
mResourceDatap->mAssetInfo.mType = LLAssetType::AT_TEXTURE;
mResourceDatap->mPreferredLocation = LLAssetType::EType(-2);
@@ -917,17 +814,17 @@ void LLFloaterReporter::takeScreenshot()
mResourceDatap->mAssetInfo.mType);
// store in the image list so it doesn't try to fetch from the server
- LLPointer<LLViewerImage> image_in_list = new LLViewerImage(mResourceDatap->mAssetInfo.mUuid, TRUE);
+ LLPointer<LLViewerFetchedTexture> image_in_list =
+ LLViewerTextureManager::getFetchedTexture(mResourceDatap->mAssetInfo.mUuid, TRUE, FALSE, LLViewerTexture::FETCHED_TEXTURE);
image_in_list->createGLTexture(0, raw);
- gImageList.addImage(image_in_list);
-
+
// the texture picker then uses that texture
LLTexturePicker* texture = getChild<LLTextureCtrl>("screenshot");
if (texture)
{
texture->setImageAssetID(mResourceDatap->mAssetInfo.mUuid);
texture->setDefaultImageAssetID(mResourceDatap->mAssetInfo.mUuid);
- texture->setCaption(std::string("Screenshot"));
+ texture->setCaption(getString("Screenshot"));
}
}
@@ -967,11 +864,7 @@ void LLFloaterReporter::uploadDoneCallback(const LLUUID &uuid, void *user_data,
}
EReportType report_type = UNKNOWN_REPORT;
- if (data->mPreferredLocation == -1)
- {
- report_type = BUG_REPORT;
- }
- else if (data->mPreferredLocation == -2)
+ if (data->mPreferredLocation == -2)
{
report_type = COMPLAINT_REPORT;
}
@@ -980,13 +873,13 @@ void LLFloaterReporter::uploadDoneCallback(const LLUUID &uuid, void *user_data,
llwarns << "Unknown report type : " << data->mPreferredLocation << llendl;
}
- LLFloaterReporter *self = getReporter(report_type);
+ LLFloaterReporter *self = LLFloaterReg::findTypedInstance<LLFloaterReporter>("reporter");
if (self)
{
self->mScreenID = uuid;
llinfos << "Got screen shot " << uuid << llendl;
self->sendReportViaLegacy(self->gatherReport());
- self->close();
+ self->closeFloater();
}
}
@@ -1001,35 +894,35 @@ void LLFloaterReporter::setPosBox(const LLVector3d &pos)
childSetText("pos_field", pos_string);
}
-void LLFloaterReporter::setDescription(const std::string& description, LLMeanCollisionData *mcd)
-{
- LLFloaterReporter *self = gReporterInstances[COMPLAINT_REPORT];
- if (self)
- {
- self->childSetText("details_edit", description);
-
- for_each(self->mMCDList.begin(), self->mMCDList.end(), DeletePointer());
- self->mMCDList.clear();
- if (mcd)
- {
- self->mMCDList.push_back(new LLMeanCollisionData(mcd));
- }
- }
-}
-
-void LLFloaterReporter::addDescription(const std::string& description, LLMeanCollisionData *mcd)
-{
- LLFloaterReporter *self = gReporterInstances[COMPLAINT_REPORT];
- if (self)
- {
- LLTextEditor* text = self->getChild<LLTextEditor>("details_edit");
- if (text)
- {
- text->insertText(description);
- }
- if (mcd)
- {
- self->mMCDList.push_back(new LLMeanCollisionData(mcd));
- }
- }
-}
+// void LLFloaterReporter::setDescription(const std::string& description, LLMeanCollisionData *mcd)
+// {
+// LLFloaterReporter *self = LLFloaterReg::findTypedInstance<LLFloaterReporter>("reporter");
+// if (self)
+// {
+// self->childSetText("details_edit", description);
+
+// for_each(self->mMCDList.begin(), self->mMCDList.end(), DeletePointer());
+// self->mMCDList.clear();
+// if (mcd)
+// {
+// self->mMCDList.push_back(new LLMeanCollisionData(mcd));
+// }
+// }
+// }
+
+// void LLFloaterReporter::addDescription(const std::string& description, LLMeanCollisionData *mcd)
+// {
+// LLFloaterReporter *self = LLFloaterReg::findTypedInstance<LLFloaterReporter>("reporter");
+// if (self)
+// {
+// LLTextEditor* text = self->getChild<LLTextEditor>("details_edit");
+// if (text)
+// {
+// text->insertText(description);
+// }
+// if (mcd)
+// {
+// self->mMCDList.push_back(new LLMeanCollisionData(mcd));
+// }
+// }
+// }
diff --git a/indra/newview/llfloaterreporter.h b/indra/newview/llfloaterreporter.h
index 86bc60559e..f363b9531e 100644
--- a/indra/newview/llfloaterreporter.h
+++ b/indra/newview/llfloaterreporter.h
@@ -39,7 +39,7 @@
#include "v3math.h"
class LLMessageSystem;
-class LLViewerImage;
+class LLViewerTexture;
class LLInventoryItem;
class LLViewerObject;
class LLAgent;
@@ -82,14 +82,13 @@ class LLFloaterReporter
: public LLFloater
{
public:
- LLFloaterReporter(const std::string& name,
- const LLRect &rect,
- const std::string& title,
- EReportType = UNKNOWN_REPORT);
+ LLFloaterReporter(const LLSD& key);
/*virtual*/ ~LLFloaterReporter();
-
+ /*virtual*/ BOOL postBuild();
virtual void draw();
-
+
+ void setReportType(EReportType type) { mReportType = type; }
+
// Enables all buttons
static void showFromMenu(EReportType report_type);
@@ -104,11 +103,6 @@ public:
static void addDescription(const std::string& description, LLMeanCollisionData *mcd = NULL);
static void setDescription(const std::string& description, LLMeanCollisionData *mcd = NULL);
- // returns a pointer to reporter of report_type
- static LLFloaterReporter* getReporter(EReportType report_type);
- static LLFloaterReporter* createNewAbuseReporter();
- static LLFloaterReporter* createNewBugReporter();
-
// static
static void processRegionInfo(LLMessageSystem* msg);
@@ -130,6 +124,7 @@ private:
private:
EReportType mReportType;
+ BOOL mEmailToEstateOwner;
LLUUID mObjectID;
LLUUID mScreenID;
LLUUID mAbuserID;
diff --git a/indra/newview/llfloaterscriptdebug.cpp b/indra/newview/llfloaterscriptdebug.cpp
index bc774e77ac..328fb6450e 100644
--- a/indra/newview/llfloaterscriptdebug.cpp
+++ b/indra/newview/llfloaterscriptdebug.cpp
@@ -32,9 +32,10 @@
#include "llviewerprecompiledheaders.h"
-#include "lluictrlfactory.h"
#include "llfloaterscriptdebug.h"
+#include "llfloaterreg.h"
+#include "lluictrlfactory.h"
#include "llfontgl.h"
#include "llrect.h"
#include "llerror.h"
@@ -45,19 +46,20 @@
#include "llviewertexteditor.h"
#include "llviewercontrol.h"
#include "llviewerobjectlist.h"
-#include "llviewerimagelist.h"
+#include "llviewertexturelist.h"
//
// Statics
//
-LLFloaterScriptDebug* LLFloaterScriptDebug::sInstance = NULL;
//
// Member Functions
//
-LLFloaterScriptDebug::LLFloaterScriptDebug() :
- LLMultiFloater()
+LLFloaterScriptDebug::LLFloaterScriptDebug(const LLSD& key)
+ : LLMultiFloater(key)
{
+// LLUICtrlFactory::getInstance()->buildFloater(this, "floater_script_debug.xml");
+
// avoid resizing of the window to match
// the initial size of the tabbed-childs, whenever a tab is opened or closed
mAutoResize = FALSE;
@@ -65,17 +67,11 @@ LLFloaterScriptDebug::LLFloaterScriptDebug() :
LLFloaterScriptDebug::~LLFloaterScriptDebug()
{
- sInstance = NULL;
}
void LLFloaterScriptDebug::show(const LLUUID& object_id)
{
- LLFloater* floaterp = addOutputWindow(object_id);
- if (sInstance)
- {
- sInstance->open(); /* Flawfinder: ignore */
- sInstance->showFloater(floaterp);
- }
+ addOutputWindow(object_id);
}
BOOL LLFloaterScriptDebug::postBuild()
@@ -84,41 +80,22 @@ BOOL LLFloaterScriptDebug::postBuild()
if (mTabContainer)
{
- // *FIX: apparantly fails for tab containers?
-// mTabContainer->requires<LLFloater>("all_scripts");
-// mTabContainer->checkRequirements();
return TRUE;
}
return FALSE;
}
-void* getOutputWindow(void* data)
-{
- return new LLFloaterScriptDebugOutput();
-}
-
LLFloater* LLFloaterScriptDebug::addOutputWindow(const LLUUID &object_id)
{
- if (!sInstance)
- {
- sInstance = new LLFloaterScriptDebug();
- LLCallbackMap::map_t factory_map;
- factory_map["all_scripts"] = LLCallbackMap(getOutputWindow, NULL);
- LLUICtrlFactory::getInstance()->buildFloater(sInstance, "floater_script_debug.xml", &factory_map);
- sInstance->setVisible(FALSE);
- }
+ LLMultiFloater* host = LLFloaterReg::showTypedInstance<LLMultiFloater>("script_debug", LLSD());
+ if (!host)
+ return NULL;
- LLFloater* floaterp = NULL;
- LLFloater::setFloaterHost(sInstance);
- {
- floaterp = LLFloaterScriptDebugOutput::show(object_id);
- }
+ LLFloater::setFloaterHost(host);
+ LLFloater* floaterp = LLFloaterReg::showInstance("script_debug_output", object_id);
LLFloater::setFloaterHost(NULL);
- // Tabs sometimes overlap resize handle
- sInstance->moveResizeHandlesToFront();
-
return floaterp;
}
@@ -129,7 +106,7 @@ void LLFloaterScriptDebug::addScriptLine(const std::string &utf8mesg, const std:
if (objectp)
{
- objectp->setIcon(gImageList.getImageFromFile("script_error.j2c", TRUE, TRUE));
+ objectp->setIcon(LLViewerTextureManager::getFetchedTextureFromFile("script_error.j2c", TRUE, TRUE));
floater_label = llformat("%s(%.2f, %.2f)", user_name.c_str(), objectp->getPositionRegion().mV[VX], objectp->getPositionRegion().mV[VY]);
}
else
@@ -141,119 +118,55 @@ void LLFloaterScriptDebug::addScriptLine(const std::string &utf8mesg, const std:
addOutputWindow(source_id);
// add to "All" floater
- LLFloaterScriptDebugOutput* floaterp = LLFloaterScriptDebugOutput::getFloaterByID(LLUUID::null);
- floaterp->addLine(utf8mesg, user_name, color);
-
+ LLFloaterScriptDebugOutput* floaterp = LLFloaterReg::getTypedInstance<LLFloaterScriptDebugOutput>("script_debug_output", LLUUID::null);
+ if (floaterp)
+ {
+ floaterp->addLine(utf8mesg, user_name, color);
+ }
+
// add to specific script instance floater
- floaterp = LLFloaterScriptDebugOutput::getFloaterByID(source_id);
- floaterp->addLine(utf8mesg, floater_label, color);
+ floaterp = LLFloaterReg::getTypedInstance<LLFloaterScriptDebugOutput>("script_debug_output", source_id);
+ if (floaterp)
+ {
+ floaterp->addLine(utf8mesg, floater_label, color);
+ }
}
//
// LLFloaterScriptDebugOutput
//
-std::map<LLUUID, LLFloaterScriptDebugOutput*> LLFloaterScriptDebugOutput::sInstanceMap;
-
-LLFloaterScriptDebugOutput::LLFloaterScriptDebugOutput()
-: mObjectID(LLUUID::null)
+LLFloaterScriptDebugOutput::LLFloaterScriptDebugOutput(const LLSD& object_id)
+ : LLFloater(LLSD(object_id)),
+ mObjectID(object_id.asUUID())
{
- sInstanceMap[mObjectID] = this;
+ //LLUICtrlFactory::getInstance()->buildFloater(this, "floater_script_debug_panel.xml");
}
-LLFloaterScriptDebugOutput::LLFloaterScriptDebugOutput(const LLUUID& object_id)
-: LLFloater(std::string("script instance floater"), LLRect(0, 200, 200, 0), std::string("Script"), TRUE), mObjectID(object_id)
+BOOL LLFloaterScriptDebugOutput::postBuild()
{
- S32 y = getRect().getHeight() - LLFLOATER_HEADER_SIZE - LLFLOATER_VPAD;
- S32 x = LLFLOATER_HPAD;
- // History editor
- // Give it a border on the top
- LLRect history_editor_rect(
- x,
- y,
- getRect().getWidth() - LLFLOATER_HPAD,
- LLFLOATER_VPAD );
- mHistoryEditor = new LLViewerTextEditor( std::string("Chat History Editor"),
- history_editor_rect, S32_MAX, LLStringUtil::null, LLFontGL::getFontSansSerif());
- mHistoryEditor->setWordWrap( TRUE );
- mHistoryEditor->setFollowsAll();
- mHistoryEditor->setEnabled( FALSE );
- mHistoryEditor->setTabStop( TRUE ); // We want to be able to cut or copy from the history.
- addChild(mHistoryEditor);
-}
-
-void LLFloaterScriptDebugOutput::initFloater(const std::string& title, BOOL resizable,
- S32 min_width, S32 min_height, BOOL drag_on_left,
- BOOL minimizable, BOOL close_btn)
-{
- LLFloater::initFloater(title, resizable, min_width, min_height, drag_on_left, minimizable, close_btn);
- S32 y = getRect().getHeight() - LLFLOATER_HEADER_SIZE - LLFLOATER_VPAD;
- S32 x = LLFLOATER_HPAD;
- // History editor
- // Give it a border on the top
- LLRect history_editor_rect(
- x,
- y,
- getRect().getWidth() - LLFLOATER_HPAD,
- LLFLOATER_VPAD );
- mHistoryEditor = new LLViewerTextEditor( std::string("Chat History Editor"),
- history_editor_rect, S32_MAX, LLStringUtil::null, LLFontGL::getFontSansSerif());
- mHistoryEditor->setWordWrap( TRUE );
- mHistoryEditor->setFollowsAll();
- mHistoryEditor->setEnabled( FALSE );
- mHistoryEditor->setTabStop( TRUE ); // We want to be able to cut or copy from the history.
- addChild(mHistoryEditor);
+ LLFloater::postBuild();
+ mHistoryEditor = getChild<LLViewerTextEditor>("Chat History Editor");
+ return TRUE;
}
LLFloaterScriptDebugOutput::~LLFloaterScriptDebugOutput()
{
- sInstanceMap.erase(mObjectID);
}
void LLFloaterScriptDebugOutput::addLine(const std::string &utf8mesg, const std::string &user_name, const LLColor4& color)
{
if (mObjectID.isNull())
{
- //setTitle("[All scripts]");
setCanTearOff(FALSE);
setCanClose(FALSE);
}
else
{
setTitle(user_name);
+ setShortTitle(user_name);
}
mHistoryEditor->appendColoredText(utf8mesg, false, true, color);
}
-//static
-LLFloaterScriptDebugOutput* LLFloaterScriptDebugOutput::show(const LLUUID& object_id)
-{
- LLFloaterScriptDebugOutput* floaterp = NULL;
- instance_map_t::iterator found_it = sInstanceMap.find(object_id);
- if (found_it == sInstanceMap.end())
- {
- floaterp = new LLFloaterScriptDebugOutput(object_id);
- sInstanceMap[object_id] = floaterp;
- floaterp->open(); /* Flawfinder: ignore*/
- }
- else
- {
- floaterp = found_it->second;
- }
-
- return floaterp;
-}
-
-//static
-LLFloaterScriptDebugOutput* LLFloaterScriptDebugOutput::getFloaterByID(const LLUUID& object_id)
-{
- LLFloaterScriptDebugOutput* floaterp = NULL;
- instance_map_t::iterator found_it = sInstanceMap.find(object_id);
- if (found_it != sInstanceMap.end())
- {
- floaterp = found_it->second;
- }
-
- return floaterp;
-}
diff --git a/indra/newview/llfloaterscriptdebug.h b/indra/newview/llfloaterscriptdebug.h
index 59c0ba1c8b..ffc60e5554 100644
--- a/indra/newview/llfloaterscriptdebug.h
+++ b/indra/newview/llfloaterscriptdebug.h
@@ -33,7 +33,7 @@
#ifndef LL_LLFLOATERSCRIPTDEBUG_H
#define LL_LLFLOATERSCRIPTDEBUG_H
-#include "llfloater.h"
+#include "llmultifloater.h"
class LLTextEditor;
class LLUUID;
@@ -41,15 +41,13 @@ class LLUUID;
class LLFloaterScriptDebug : public LLMultiFloater
{
public:
+ LLFloaterScriptDebug(const LLSD& key);
virtual ~LLFloaterScriptDebug();
- virtual void onClose(bool app_quitting) { setVisible(FALSE); }
virtual BOOL postBuild();
static void show(const LLUUID& object_id);
static void addScriptLine(const std::string &utf8mesg, const std::string &user_name, const LLColor4& color, const LLUUID& source_id);
protected:
- LLFloaterScriptDebug();
-
static LLFloater* addOutputWindow(const LLUUID& object_id);
protected:
@@ -59,26 +57,17 @@ protected:
class LLFloaterScriptDebugOutput : public LLFloater
{
public:
- LLFloaterScriptDebugOutput();
- LLFloaterScriptDebugOutput(const LLUUID& object_id);
+ LLFloaterScriptDebugOutput(const LLSD& object_id);
~LLFloaterScriptDebugOutput();
- virtual void initFloater(const std::string& title, BOOL resizable,
- S32 min_width, S32 min_height, BOOL drag_on_left,
- BOOL minimizable, BOOL close_btn);
-
void addLine(const std::string &utf8mesg, const std::string &user_name, const LLColor4& color);
- static LLFloaterScriptDebugOutput* show(const LLUUID& object_id);
- static LLFloaterScriptDebugOutput* getFloaterByID(const LLUUID& id);
-
+ virtual BOOL postBuild();
+
protected:
- LLTextEditor* mHistoryEditor;
-
- typedef std::map<LLUUID, LLFloaterScriptDebugOutput*> instance_map_t;
- static instance_map_t sInstanceMap;
+ LLTextEditor* mHistoryEditor;
- LLUUID mObjectID;
+ LLUUID mObjectID;
};
#endif // LL_LLFLOATERSCRIPTDEBUG_H
diff --git a/indra/newview/llfloatersellland.cpp b/indra/newview/llfloatersellland.cpp
index 92e070f766..a6aa01e83b 100644
--- a/indra/newview/llfloatersellland.cpp
+++ b/indra/newview/llfloatersellland.cpp
@@ -34,7 +34,7 @@
#include "llfloatersellland.h"
#include "llfloateravatarpicker.h"
-#include "llfloater.h"
+#include "llfloaterreg.h"
#include "llfloaterland.h"
#include "lllineeditor.h"
#include "llnotify.h"
@@ -55,10 +55,21 @@ enum Badge { BADGE_OK, BADGE_NOTE, BADGE_WARN, BADGE_ERROR };
class LLFloaterSellLandUI
: public LLFloater
{
-private:
- LLFloaterSellLandUI();
+public:
+ LLFloaterSellLandUI(const LLSD& key);
virtual ~LLFloaterSellLandUI();
-
+
+private:
+ class SelectionObserver : public LLParcelObserver
+ {
+ public:
+ SelectionObserver(LLFloaterSellLandUI* floater) : mFloater(floater) {}
+ virtual void changed();
+ private:
+ LLFloaterSellLandUI* mFloater;
+ };
+
+private:
LLViewerRegion* mRegion;
LLParcelSelectionHandle mParcelSelection;
bool mParcelIsForSale;
@@ -69,13 +80,12 @@ private:
LLUUID mParcelSnapshot;
LLUUID mAuthorizedBuyer;
bool mParcelSoldWithObjects;
+ SelectionObserver mParcelSelectionObserver;
void updateParcelInfo();
void refreshUI();
void setBadge(const char* id, Badge badge);
- static LLFloaterSellLandUI* sInstance;
-
static void onChangeValue(LLUICtrl *ctrl, void *userdata);
static void doSelectAgent(void *userdata);
static void doCancel(void *userdata);
@@ -88,91 +98,57 @@ private:
public:
virtual BOOL postBuild();
- virtual void onClose(bool app_quitting);
- static LLFloaterSellLandUI* soleInstance(bool createIfNeeded);
-
bool setParcel(LLViewerRegion* region, LLParcelSelectionHandle parcel);
-
-private:
- class SelectionObserver : public LLParcelObserver
- {
- public:
- virtual void changed();
- };
};
// static
void LLFloaterSellLand::sellLand(
LLViewerRegion* region, LLParcelSelectionHandle parcel)
{
- LLFloaterSellLandUI* ui = LLFloaterSellLandUI::soleInstance(true);
- if (ui->setParcel(region, parcel))
- {
- ui->open(); /* Flawfinder: ignore */
- }
+ LLFloaterSellLandUI* ui = LLFloaterReg::showTypedInstance<LLFloaterSellLandUI>("sell_land");
+ ui->setParcel(region, parcel);
}
// static
-LLFloaterSellLandUI* LLFloaterSellLandUI::sInstance = NULL;
-
-// static
-LLFloaterSellLandUI* LLFloaterSellLandUI::soleInstance(bool createIfNeeded)
+LLFloater* LLFloaterSellLand::buildFloater(const LLSD& key)
{
- if (!sInstance && createIfNeeded)
- {
- sInstance = new LLFloaterSellLandUI();
-
- LLUICtrlFactory::getInstance()->buildFloater(sInstance, "floater_sell_land.xml");
- sInstance->center();
- }
-
-
- static SelectionObserver* parcelSelectionObserver = NULL;
- if (!parcelSelectionObserver)
- {
- parcelSelectionObserver = new SelectionObserver;
- LLViewerParcelMgr::getInstance()->addObserver(parcelSelectionObserver);
- }
-
- return sInstance;
+ LLFloaterSellLandUI* floater = new LLFloaterSellLandUI(key);
+ return floater;
}
-LLFloaterSellLandUI::LLFloaterSellLandUI()
-: LLFloater(std::string("Sell Land")),
+#if LL_WINDOWS
+// passing 'this' during construction generates a warning. The callee
+// only uses the pointer to hold a reference to 'this' which is
+// already valid, so this call does the correct thing. Disable the
+// warning so that we can compile without generating a warning.
+#pragma warning(disable : 4355)
+#endif
+LLFloaterSellLandUI::LLFloaterSellLandUI(const LLSD& key)
+: LLFloater(key),
+ mParcelSelectionObserver(this),
mRegion(0)
{
+ LLViewerParcelMgr::getInstance()->addObserver(&mParcelSelectionObserver);
+// LLUICtrlFactory::getInstance()->buildFloater(sInstance, "floater_sell_land.xml");
}
LLFloaterSellLandUI::~LLFloaterSellLandUI()
{
- if (sInstance == this)
- {
- sInstance = NULL;
- }
+ LLViewerParcelMgr::getInstance()->removeObserver(&mParcelSelectionObserver);
}
void LLFloaterSellLandUI::SelectionObserver::changed()
{
- LLFloaterSellLandUI* ui = LLFloaterSellLandUI::soleInstance(false);
- if (ui)
+ if (LLViewerParcelMgr::getInstance()->selectionEmpty())
{
- if (LLViewerParcelMgr::getInstance()->selectionEmpty())
- {
- ui->close();
- }
- else {
- ui->setParcel(
- LLViewerParcelMgr::getInstance()->getSelectionRegion(),
- LLViewerParcelMgr::getInstance()->getParcelSelection());
- }
+ mFloater->closeFloater();
+ }
+ else
+ {
+ mFloater->setParcel(LLViewerParcelMgr::getInstance()->getSelectionRegion(),
+ LLViewerParcelMgr::getInstance()->getParcelSelection());
}
-}
-
-void LLFloaterSellLandUI::onClose(bool app_quitting)
-{
- LLFloater::onClose(app_quitting);
- destroy();
}
BOOL LLFloaterSellLandUI::postBuild()
@@ -185,6 +161,7 @@ BOOL LLFloaterSellLandUI::postBuild()
childSetAction("cancel_btn", doCancel, this);
childSetAction("sell_btn", doSellLand, this);
childSetAction("show_objects", doShowObjects, this);
+ center();
return TRUE;
}
@@ -432,7 +409,7 @@ void LLFloaterSellLandUI::callbackAvatarPick(const std::vector<std::string>& nam
void LLFloaterSellLandUI::doCancel(void *userdata)
{
LLFloaterSellLandUI* self = (LLFloaterSellLandUI*)userdata;
- self->close();
+ self->closeFloater();
}
// static
@@ -490,7 +467,7 @@ void LLFloaterSellLandUI::doSellLand(void *userdata)
LLNotification::Params params("ConfirmLandSaleChange");
params.substitutions(args)
- .functor(boost::bind(&LLFloaterSellLandUI::onConfirmSale, self, _1, _2));
+ .functor.function(boost::bind(&LLFloaterSellLandUI::onConfirmSale, self, _1, _2));
if (sell_to_anyone)
{
@@ -556,6 +533,6 @@ bool LLFloaterSellLandUI::onConfirmSale(const LLSD& notification, const LLSD& re
// Send update to server
LLViewerParcelMgr::getInstance()->sendParcelPropertiesUpdate( parcel );
- close();
+ closeFloater();
return false;
}
diff --git a/indra/newview/llfloatersellland.h b/indra/newview/llfloatersellland.h
index 1b3a33ebb8..1adf08052b 100644
--- a/indra/newview/llfloatersellland.h
+++ b/indra/newview/llfloatersellland.h
@@ -31,8 +31,10 @@
#ifndef LL_LLFLOATERSELLLAND_H
#define LL_LLFLOATERSELLLAND_H
-#include "llmemory.h"
+#include "llsafehandle.h"
+
+class LLFloater;
class LLParcel;
class LLViewerRegion;
class LLParcelSelection;
@@ -42,6 +44,8 @@ class LLFloaterSellLand
public:
static void sellLand(LLViewerRegion* region,
LLSafeHandle<LLParcelSelection> parcel);
+
+ static LLFloater* buildFloater(const LLSD& key);
};
#endif // LL_LLFLOATERSELLLAND_H
diff --git a/indra/newview/llfloatersettingsdebug.cpp b/indra/newview/llfloatersettingsdebug.cpp
index 2677467611..616e9bac35 100644
--- a/indra/newview/llfloatersettingsdebug.cpp
+++ b/indra/newview/llfloatersettingsdebug.cpp
@@ -39,17 +39,21 @@
#include "llspinctrl.h"
#include "llcolorswatch.h"
#include "llviewercontrol.h"
+#include "lltexteditor.h"
-LLFloaterSettingsDebug* LLFloaterSettingsDebug::sInstance = NULL;
-LLFloaterSettingsDebug::LLFloaterSettingsDebug() : LLFloater(std::string("Configuration Editor"))
+LLFloaterSettingsDebug::LLFloaterSettingsDebug(const LLSD& key)
+: LLFloater(key)
{
+ //LLUICtrlFactory::getInstance()->buildFloater(this, "floater_settings_debug.xml");
+ mCommitCallbackRegistrar.add("SettingSelect", boost::bind(&LLFloaterSettingsDebug::onSettingSelect, this,_1));
+ mCommitCallbackRegistrar.add("CommitSettings", boost::bind(&LLFloaterSettingsDebug::onCommitSettings, this));
+ mCommitCallbackRegistrar.add("ClickDefault", boost::bind(&LLFloaterSettingsDebug::onClickDefault, this));
+
}
LLFloaterSettingsDebug::~LLFloaterSettingsDebug()
-{
- sInstance = NULL;
-}
+{}
BOOL LLFloaterSettingsDebug::postBuild()
{
@@ -68,30 +72,18 @@ BOOL LLFloaterSettingsDebug::postBuild()
}
} func(settings_combo);
- gSavedSettings.applyToAll(&func);
- gSavedPerAccountSettings.applyToAll(&func);
- gColors.applyToAll(&func);
+ std::string key = getKey().asString();
+ if (key == "all" || key == "base")
+ {
+ gSavedSettings.applyToAll(&func);
+ }
+ if (key == "all" || key == "account")
+ {
+ gSavedPerAccountSettings.applyToAll(&func);
+ }
settings_combo->sortByName();
- settings_combo->setCommitCallback(onSettingSelect);
- settings_combo->setCallbackUserData(this);
settings_combo->updateSelection();
-
- childSetCommitCallback("val_spinner_1", onCommitSettings);
- childSetUserData("val_spinner_1", this);
- childSetCommitCallback("val_spinner_2", onCommitSettings);
- childSetUserData("val_spinner_2", this);
- childSetCommitCallback("val_spinner_3", onCommitSettings);
- childSetUserData("val_spinner_3", this);
- childSetCommitCallback("val_spinner_4", onCommitSettings);
- childSetUserData("val_spinner_4", this);
- childSetCommitCallback("val_text", onCommitSettings);
- childSetUserData("val_text", this);
- childSetCommitCallback("boolean_combo", onCommitSettings);
- childSetUserData("boolean_combo", this);
- childSetCommitCallback("color_swatch", onCommitSettings);
- childSetUserData("color_swatch", this);
- childSetAction("default_btn", onClickDefault, this);
mComment = getChild<LLTextEditor>("comment_text");
return TRUE;
}
@@ -105,35 +97,18 @@ void LLFloaterSettingsDebug::draw()
LLFloater::draw();
}
-//static
-void LLFloaterSettingsDebug::show(void*)
-{
- if (sInstance == NULL)
- {
- sInstance = new LLFloaterSettingsDebug();
-
- LLUICtrlFactory::getInstance()->buildFloater(sInstance, "floater_settings_debug.xml");
- }
-
- sInstance->open(); /* Flawfinder: ignore */
-}
-
//static
-void LLFloaterSettingsDebug::onSettingSelect(LLUICtrl* ctrl, void* user_data)
+void LLFloaterSettingsDebug::onSettingSelect(LLUICtrl* ctrl)
{
- LLFloaterSettingsDebug* floaterp = (LLFloaterSettingsDebug*)user_data;
LLComboBox* combo_box = (LLComboBox*)ctrl;
LLControlVariable* controlp = (LLControlVariable*)combo_box->getCurrentUserdata();
- floaterp->updateControl(controlp);
+ updateControl(controlp);
}
-//static
-void LLFloaterSettingsDebug::onCommitSettings(LLUICtrl* ctrl, void* user_data)
+void LLFloaterSettingsDebug::onCommitSettings()
{
- LLFloaterSettingsDebug* floaterp = (LLFloaterSettingsDebug*)user_data;
-
- LLComboBox* settings_combo = floaterp->getChild<LLComboBox>("settings_combo");
+ LLComboBox* settings_combo = getChild<LLComboBox>("settings_combo");
LLControlVariable* controlp = (LLControlVariable*)settings_combo->getCurrentUserdata();
LLVector3 vector;
@@ -147,73 +122,66 @@ void LLFloaterSettingsDebug::onCommitSettings(LLUICtrl* ctrl, void* user_data)
switch(controlp->type())
{
case TYPE_U32:
- controlp->set(floaterp->childGetValue("val_spinner_1"));
+ controlp->set(childGetValue("val_spinner_1"));
break;
case TYPE_S32:
- controlp->set(floaterp->childGetValue("val_spinner_1"));
+ controlp->set(childGetValue("val_spinner_1"));
break;
case TYPE_F32:
- controlp->set(LLSD(floaterp->childGetValue("val_spinner_1").asReal()));
+ controlp->set(LLSD(childGetValue("val_spinner_1").asReal()));
break;
case TYPE_BOOLEAN:
- controlp->set(floaterp->childGetValue("boolean_combo"));
+ controlp->set(childGetValue("boolean_combo"));
break;
case TYPE_STRING:
- controlp->set(LLSD(floaterp->childGetValue("val_text").asString()));
+ controlp->set(LLSD(childGetValue("val_text").asString()));
break;
case TYPE_VEC3:
- vector.mV[VX] = (F32)floaterp->childGetValue("val_spinner_1").asReal();
- vector.mV[VY] = (F32)floaterp->childGetValue("val_spinner_2").asReal();
- vector.mV[VZ] = (F32)floaterp->childGetValue("val_spinner_3").asReal();
+ vector.mV[VX] = (F32)childGetValue("val_spinner_1").asReal();
+ vector.mV[VY] = (F32)childGetValue("val_spinner_2").asReal();
+ vector.mV[VZ] = (F32)childGetValue("val_spinner_3").asReal();
controlp->set(vector.getValue());
break;
case TYPE_VEC3D:
- vectord.mdV[VX] = floaterp->childGetValue("val_spinner_1").asReal();
- vectord.mdV[VY] = floaterp->childGetValue("val_spinner_2").asReal();
- vectord.mdV[VZ] = floaterp->childGetValue("val_spinner_3").asReal();
+ vectord.mdV[VX] = childGetValue("val_spinner_1").asReal();
+ vectord.mdV[VY] = childGetValue("val_spinner_2").asReal();
+ vectord.mdV[VZ] = childGetValue("val_spinner_3").asReal();
controlp->set(vectord.getValue());
break;
case TYPE_RECT:
- rect.mLeft = floaterp->childGetValue("val_spinner_1").asInteger();
- rect.mRight = floaterp->childGetValue("val_spinner_2").asInteger();
- rect.mBottom = floaterp->childGetValue("val_spinner_3").asInteger();
- rect.mTop = floaterp->childGetValue("val_spinner_4").asInteger();
+ rect.mLeft = childGetValue("val_spinner_1").asInteger();
+ rect.mRight = childGetValue("val_spinner_2").asInteger();
+ rect.mBottom = childGetValue("val_spinner_3").asInteger();
+ rect.mTop = childGetValue("val_spinner_4").asInteger();
controlp->set(rect.getValue());
break;
case TYPE_COL4:
- col3.setValue(floaterp->childGetValue("color_swatch"));
- col4 = LLColor4(col3, (F32)floaterp->childGetValue("val_spinner_4").asReal());
+ col3.setValue(childGetValue("val_color_swatch"));
+ col4 = LLColor4(col3, (F32)childGetValue("val_spinner_4").asReal());
controlp->set(col4.getValue());
break;
case TYPE_COL3:
- controlp->set(floaterp->childGetValue("color_swatch"));
+ controlp->set(childGetValue("val_color_swatch"));
//col3.mV[VRED] = (F32)floaterp->childGetValue("val_spinner_1").asC();
//col3.mV[VGREEN] = (F32)floaterp->childGetValue("val_spinner_2").asReal();
//col3.mV[VBLUE] = (F32)floaterp->childGetValue("val_spinner_3").asReal();
//controlp->set(col3.getValue());
break;
- case TYPE_COL4U:
- col3.setValue(floaterp->childGetValue("color_swatch"));
- col4U.setVecScaleClamp(col3);
- col4U.mV[VALPHA] = floaterp->childGetValue("val_spinner_4").asInteger();
- controlp->set(col4U.getValue());
- break;
default:
break;
}
}
// static
-void LLFloaterSettingsDebug::onClickDefault(void* user_data)
+void LLFloaterSettingsDebug::onClickDefault()
{
- LLFloaterSettingsDebug* floaterp = (LLFloaterSettingsDebug*)user_data;
- LLComboBox* settings_combo = floaterp->getChild<LLComboBox>("settings_combo");
+ LLComboBox* settings_combo = getChild<LLComboBox>("settings_combo");
LLControlVariable* controlp = (LLControlVariable*)settings_combo->getCurrentUserdata();
if (controlp)
{
controlp->resetToDefault();
- floaterp->updateControl(controlp);
+ updateControl(controlp);
}
}
@@ -224,7 +192,7 @@ void LLFloaterSettingsDebug::updateControl(LLControlVariable* controlp)
LLSpinCtrl* spinner2 = getChild<LLSpinCtrl>("val_spinner_2");
LLSpinCtrl* spinner3 = getChild<LLSpinCtrl>("val_spinner_3");
LLSpinCtrl* spinner4 = getChild<LLSpinCtrl>("val_spinner_4");
- LLColorSwatchCtrl* color_swatch = getChild<LLColorSwatchCtrl>("color_swatch");
+ LLColorSwatchCtrl* color_swatch = getChild<LLColorSwatchCtrl>("val_color_swatch");
if (!spinner1 || !spinner2 || !spinner3 || !spinner4 || !color_swatch)
{
@@ -464,29 +432,6 @@ void LLFloaterSettingsDebug::updateControl(LLControlVariable* controlp)
color_swatch->setValue(sd);
break;
}
- case TYPE_COL4U:
- {
- LLColor4U clr;
- clr.setValue(sd);
- color_swatch->setVisible(TRUE);
- if(LLColor4(clr) != LLColor4(color_swatch->getValue()))
- {
- color_swatch->set(LLColor4(clr), TRUE, FALSE);
- }
- spinner4->setVisible(TRUE);
- spinner4->setLabel(std::string("Alpha"));
- if(!spinner4->hasFocus())
- {
- spinner4->setPrecision(0);
- spinner4->setValue(clr.mV[VALPHA]);
- }
-
- spinner4->setMinValue(0);
- spinner4->setMaxValue(255);
- spinner4->setIncrement(1.f);
-
- break;
- }
default:
mComment->setText(std::string("unknown"));
break;
diff --git a/indra/newview/llfloatersettingsdebug.h b/indra/newview/llfloatersettingsdebug.h
index e08e6b5d74..65803fbf70 100644
--- a/indra/newview/llfloatersettingsdebug.h
+++ b/indra/newview/llfloatersettingsdebug.h
@@ -35,27 +35,31 @@
#include "llcontrol.h"
#include "llfloater.h"
-#include "lltexteditor.h"
-class LLFloaterSettingsDebug : public LLFloater
+class LLFloaterSettingsDebug
+: public LLFloater
{
+ friend class LLFloaterReg;
+
public:
- LLFloaterSettingsDebug();
- virtual ~LLFloaterSettingsDebug();
virtual BOOL postBuild();
virtual void draw();
void updateControl(LLControlVariable* control);
- static void show(void*);
- static void onSettingSelect(LLUICtrl* ctrl, void* user_data);
- static void onCommitSettings(LLUICtrl* ctrl, void* user_data);
- static void onClickDefault(void* user_data);
+ void onSettingSelect(LLUICtrl* ctrl);
+ void onCommitSettings();
+ void onClickDefault();
+private:
+ // key - selects which settings to show, one of:
+ // "all", "base", "account", "skin"
+ LLFloaterSettingsDebug(const LLSD& key);
+ virtual ~LLFloaterSettingsDebug();
+
protected:
- static LLFloaterSettingsDebug* sInstance;
- LLTextEditor* mComment;
+ class LLTextEditor* mComment;
};
#endif //LLFLOATERDEBUGSETTINGS_H
diff --git a/indra/newview/llfloatersnapshot.cpp b/indra/newview/llfloatersnapshot.cpp
index e68d699d03..b5c36b1083 100644
--- a/indra/newview/llfloatersnapshot.cpp
+++ b/indra/newview/llfloatersnapshot.cpp
@@ -34,20 +34,13 @@
#include "llfloatersnapshot.h"
-#include "llfontgl.h"
-#include "llsys.h"
-#include "llgl.h"
-#include "llrender.h"
-#include "v3dmath.h"
-#include "llmath.h"
-#include "lldir.h"
-#include "llsdserialize.h"
+#include "llfloaterreg.h"
+// Viewer includes
#include "llagent.h"
#include "llcallbacklist.h"
#include "llcriticaldamp.h"
#include "llui.h"
-#include "llviewertexteditor.h"
#include "llfocusmgr.h"
#include "llbutton.h"
#include "llcombobox.h"
@@ -66,15 +59,26 @@
#include "lltoolfocus.h"
#include "lltoolmgr.h"
#include "llworld.h"
+#include "llagentui.h"
+// Linden library includes
+#include "llfontgl.h"
+#include "llsys.h"
+#include "llrender.h"
+#include "v3dmath.h"
+#include "llmath.h"
+#include "lldir.h"
+#include "llsdserialize.h"
#include "llgl.h"
#include "llglheaders.h"
#include "llimagejpeg.h"
#include "llimagepng.h"
#include "llimagebmp.h"
#include "llimagej2c.h"
+#include "llresmgr.h" // LLLocale
#include "llvfile.h"
#include "llvfs.h"
+#include "llwindow.h"
///----------------------------------------------------------------------------
/// Local function declarations, constants, enums, and typedefs
@@ -85,8 +89,6 @@ S32 LLFloaterSnapshot::sUIWinWidth = 215 ;
LLSnapshotFloaterView* gSnapshotFloaterView = NULL;
-LLFloaterSnapshot* LLFloaterSnapshot::sInstance = NULL;
-
const F32 AUTO_SNAPSHOT_TIME_DELAY = 1.f;
F32 SHINE_TIME = 0.5f;
@@ -112,7 +114,17 @@ public:
};
- LLSnapshotLivePreview(const LLRect& rect);
+ struct Params : public LLInitParam::Block<Params, LLView::Params>
+ {
+ Params()
+ {
+ name = "snapshot_live_preview";
+ mouse_opaque = false;
+ }
+ };
+
+
+ LLSnapshotLivePreview(const LLSnapshotLivePreview::Params& p);
~LLSnapshotLivePreview();
/*virtual*/ void draw();
@@ -128,12 +140,12 @@ public:
LLFloaterSnapshot::ESnapshotFormat getSnapshotFormat() const { return mSnapshotFormat; }
BOOL getSnapshotUpToDate() const { return mSnapshotUpToDate; }
BOOL isSnapshotActive() { return mSnapshotActive; }
- LLImageGL* getThumbnailImage() const { return mThumbnailImage ; }
+ LLViewerTexture* getThumbnailImage() const { return mThumbnailImage ; }
S32 getThumbnailWidth() const { return mThumbnailWidth ; }
S32 getThumbnailHeight() const { return mThumbnailHeight ; }
BOOL getThumbnailLock() const { return mThumbnailUpdateLock ; }
BOOL getThumbnailUpToDate() const { return mThumbnailUpToDate ;}
- LLImageGL* getCurrentImage();
+ LLViewerTexture* getCurrentImage();
F32 getImageAspect();
F32 getAspect() ;
LLRect getImageRect();
@@ -158,7 +170,7 @@ public:
private:
LLColor4 mColor;
- LLPointer<LLImageGL> mViewerImage[2]; //used to represent the scene when the frame is frozen.
+ LLPointer<LLViewerTexture> mViewerImage[2]; //used to represent the scene when the frame is frozen.
LLRect mImageRect[2];
S32 mWidth[2];
S32 mHeight[2];
@@ -166,7 +178,7 @@ private:
S32 mMaxImageSize ;
//thumbnail image
- LLPointer<LLImageGL> mThumbnailImage ;
+ LLPointer<LLViewerTexture> mThumbnailImage ;
S32 mThumbnailWidth ;
S32 mThumbnailHeight ;
LLRect mPreviewRect ;
@@ -200,8 +212,9 @@ public:
};
std::set<LLSnapshotLivePreview*> LLSnapshotLivePreview::sList;
-LLSnapshotLivePreview::LLSnapshotLivePreview (const LLRect& rect) :
- LLView(std::string("snapshot_live_preview"), rect, FALSE),
+
+LLSnapshotLivePreview::LLSnapshotLivePreview (const LLSnapshotLivePreview::Params& p)
+: LLView(p),
mColor(1.f, 0.f, 0.f, 0.5f),
mCurImageIndex(0),
mPreviewImage(NULL),
@@ -265,7 +278,7 @@ void LLSnapshotLivePreview::setMaxImageSize(S32 size)
}
}
-LLImageGL* LLSnapshotLivePreview::getCurrentImage()
+LLViewerTexture* LLSnapshotLivePreview::getCurrentImage()
{
return mViewerImage[mCurImageIndex];
}
@@ -472,10 +485,6 @@ void LLSnapshotLivePreview::draw()
}
else if (mShineAnimTimer.getStarted())
{
- //LLDebugVarMessageBox::show("Shine time", &SHINE_TIME, 10.f, 0.1f);
- //LLDebugVarMessageBox::show("Shine width", &SHINE_WIDTH, 2.f, 0.05f);
- //LLDebugVarMessageBox::show("Shine opacity", &SHINE_OPACITY, 1.f, 0.05f);
-
F32 shine_interp = llmin(1.f, mShineAnimTimer.getElapsedTimeF32() / SHINE_TIME);
// draw "shine" effect
@@ -714,7 +723,7 @@ void LLSnapshotLivePreview::generateThumbnailImage(BOOL force_update)
if(raw)
{
- mThumbnailImage = new LLImageGL(raw, FALSE);
+ mThumbnailImage = LLViewerTextureManager::getLocalTexture(raw.get(), FALSE);
mThumbnailUpToDate = TRUE ;
}
@@ -862,8 +871,8 @@ BOOL LLSnapshotLivePreview::onIdle( void* snapshot_preview )
scaled->expandToPowerOfTwo(1024, FALSE);
}
- previewp->mViewerImage[previewp->mCurImageIndex] = new LLImageGL(scaled, FALSE);
- LLPointer<LLImageGL> curr_preview_image = previewp->mViewerImage[previewp->mCurImageIndex];
+ previewp->mViewerImage[previewp->mCurImageIndex] = LLViewerTextureManager::getLocalTexture(scaled.get(), FALSE);
+ LLPointer<LLViewerTexture> curr_preview_image = previewp->mViewerImage[previewp->mCurImageIndex];
gGL.getTexUnit(0)->bind(curr_preview_image);
if (previewp->getSnapshotType() != SNAPSHOT_TEXTURE)
{
@@ -959,9 +968,9 @@ void LLSnapshotLivePreview::saveTexture()
{
LLVFile::writeFile(formatted->getData(), formatted->getDataSize(), gVFS, new_asset_id, LLAssetType::AT_TEXTURE);
std::string pos_string;
- gAgent.buildLocationString(pos_string);
+ LLAgentUI::buildLocationString(pos_string, LLAgentUI::LOCATION_FORMAT_FULL);
std::string who_took_it;
- gAgent.buildFullname(who_took_it);
+ LLAgentUI::buildFullname(who_took_it);
LLAssetStorage::LLStoreAssetCallback callback = NULL;
S32 expected_upload_cost = LLGlobalEconomy::Singleton::getInstance()->getPriceUpload();
void *userdata = NULL;
@@ -1053,9 +1062,6 @@ public:
static void updateLayout(LLFloaterSnapshot* floater);
static void updateResolutionTextEntry(LLFloaterSnapshot* floater);
- static LLHandle<LLView> sPreviewHandle;
- static BOOL sAspectRatioCheckOff ;
-
private:
static LLSnapshotLivePreview::ESnapshotType getTypeIndex(LLFloaterSnapshot* floater);
static ESnapshotFormat getFormatIndex(LLFloaterSnapshot* floater);
@@ -1068,18 +1074,14 @@ public:
std::vector<LLAnimPauseRequest> mAvatarPauseHandles;
LLToolset* mLastToolset;
+ LLHandle<LLView> mPreviewHandle;
+ BOOL mAspectRatioCheckOff ;
};
// static
-LLHandle<LLView> LLFloaterSnapshot::Impl::sPreviewHandle;
-
-//static
-BOOL LLFloaterSnapshot::Impl::sAspectRatioCheckOff = FALSE ;
-
-// static
LLSnapshotLivePreview* LLFloaterSnapshot::Impl::getPreviewView(LLFloaterSnapshot *floater)
{
- LLSnapshotLivePreview* previewp = (LLSnapshotLivePreview*)sPreviewHandle.get();
+ LLSnapshotLivePreview* previewp = (LLSnapshotLivePreview*)floater->impl.mPreviewHandle.get();
return previewp;
}
@@ -1186,7 +1188,7 @@ void LLFloaterSnapshot::Impl::updateLayout(LLFloaterSnapshot* floaterp)
iter != LLCharacter::sInstances.end(); ++iter)
{
avatarp = *iter;
- sInstance->impl.mAvatarPauseHandles.push_back(avatarp->requestPause());
+ floaterp->impl.mAvatarPauseHandles.push_back(avatarp->requestPause());
}
// freeze everything else
@@ -1194,7 +1196,7 @@ void LLFloaterSnapshot::Impl::updateLayout(LLFloaterSnapshot* floaterp)
if (LLToolMgr::getInstance()->getCurrentToolset() != gCameraToolset)
{
- sInstance->impl.mLastToolset = LLToolMgr::getInstance()->getCurrentToolset();
+ floaterp->impl.mLastToolset = LLToolMgr::getInstance()->getCurrentToolset();
LLToolMgr::getInstance()->setCurrentToolset(gCameraToolset);
}
}
@@ -1209,15 +1211,15 @@ void LLFloaterSnapshot::Impl::updateLayout(LLFloaterSnapshot* floaterp)
}
//RN: thaw all avatars
- sInstance->impl.mAvatarPauseHandles.clear();
+ floaterp->impl.mAvatarPauseHandles.clear();
// thaw everything else
gSavedSettings.setBOOL("FreezeTime", FALSE);
// restore last tool (e.g. pie menu, etc)
- if (sInstance->impl.mLastToolset)
+ if (floaterp->impl.mLastToolset)
{
- LLToolMgr::getInstance()->setCurrentToolset(sInstance->impl.mLastToolset);
+ LLToolMgr::getInstance()->setCurrentToolset(floaterp->impl.mLastToolset);
}
}
}
@@ -1248,7 +1250,7 @@ void LLFloaterSnapshot::Impl::updateControls(LLFloaterSnapshot* floater)
floater->childSetVisible("upload_btn", shot_type == LLSnapshotLivePreview::SNAPSHOT_TEXTURE);
floater->childSetVisible("send_btn", shot_type == LLSnapshotLivePreview::SNAPSHOT_POSTCARD);
floater->childSetVisible("save_btn", shot_type == LLSnapshotLivePreview::SNAPSHOT_LOCAL);
- floater->childSetEnabled("keep_aspect_check", shot_type != LLSnapshotLivePreview::SNAPSHOT_TEXTURE && !sAspectRatioCheckOff);
+ floater->childSetEnabled("keep_aspect_check", shot_type != LLSnapshotLivePreview::SNAPSHOT_TEXTURE && !floater->impl.mAspectRatioCheckOff);
floater->childSetEnabled("layer_types", shot_type == LLSnapshotLivePreview::SNAPSHOT_LOCAL);
BOOL is_advance = gSavedSettings.getBOOL("AdvanceSnapshot");
@@ -1295,7 +1297,7 @@ void LLFloaterSnapshot::Impl::updateControls(LLFloaterSnapshot* floater)
floater->childSetColor("file_size_label",
shot_type == LLSnapshotLivePreview::SNAPSHOT_POSTCARD
&& got_bytes
- && previewp->getDataSize() > MAX_POSTCARD_DATASIZE ? LLColor4::red : gColors.getColor( "LabelTextColor" ));
+ && previewp->getDataSize() > MAX_POSTCARD_DATASIZE ? LLUIColor(LLColor4::red) : LLUIColorTable::instance().getColor( "LabelTextColor" ));
switch(shot_type)
{
@@ -1369,7 +1371,7 @@ void LLFloaterSnapshot::Impl::onClickDiscard(void* data)
LLFloaterSnapshot *view = (LLFloaterSnapshot *)data;
if (view)
{
- view->close();
+ view->closeFloater();
}
}
@@ -1415,7 +1417,7 @@ void LLFloaterSnapshot::Impl::onClickKeep(void* data)
if (gSavedSettings.getBOOL("CloseSnapshotOnKeep"))
{
- view->close();
+ view->closeFloater();
}
else
{
@@ -1596,7 +1598,7 @@ void LLFloaterSnapshot::Impl::checkAspectRatio(LLFloaterSnapshot *view, S32 inde
if(0 == index) //current window size
{
- sAspectRatioCheckOff = TRUE ;
+ view->impl.mAspectRatioCheckOff = TRUE ;
view->childSetEnabled("keep_aspect_check", FALSE) ;
if(previewp)
@@ -1606,7 +1608,7 @@ void LLFloaterSnapshot::Impl::checkAspectRatio(LLFloaterSnapshot *view, S32 inde
}
else if(-1 == index) //custom
{
- sAspectRatioCheckOff = FALSE ;
+ view->impl.mAspectRatioCheckOff = FALSE ;
//if(LLSnapshotLivePreview::SNAPSHOT_TEXTURE != gSavedSettings.getS32("LastSnapshotType"))
{
view->childSetEnabled("keep_aspect_check", TRUE) ;
@@ -1619,7 +1621,7 @@ void LLFloaterSnapshot::Impl::checkAspectRatio(LLFloaterSnapshot *view, S32 inde
}
else
{
- sAspectRatioCheckOff = TRUE ;
+ view->impl.mAspectRatioCheckOff = TRUE ;
view->childSetEnabled("keep_aspect_check", FALSE) ;
if(previewp)
@@ -1955,21 +1957,17 @@ void LLFloaterSnapshot::Impl::onCommitCustomResolution(LLUICtrl *ctrl, void* dat
///----------------------------------------------------------------------------
// Default constructor
-LLFloaterSnapshot::LLFloaterSnapshot()
- : LLFloater(std::string("Snapshot Floater")),
+LLFloaterSnapshot::LLFloaterSnapshot(const LLSD& key)
+ : LLFloater(key),
impl (*(new Impl))
{
+ //Called from floater reg: LLUICtrlFactory::getInstance()->buildFloater(this, "floater_snapshot.xml", FALSE);
}
// Destroys the object
LLFloaterSnapshot::~LLFloaterSnapshot()
{
- if (sInstance == this)
- {
- LLView::deleteViewByHandle(Impl::sPreviewHandle);
- Impl::sPreviewHandle = LLHandle<LLView>();
- sInstance = NULL;
- }
+ LLView::deleteViewByHandle(impl.mPreviewHandle);
//unfreeze everything else
gSavedSettings.setBOOL("FreezeTime", FALSE);
@@ -2034,16 +2032,22 @@ BOOL LLFloaterSnapshot::postBuild()
childSetCommitCallback("local_size_combo", Impl::onCommitResolution, this);
// create preview window
- LLRect full_screen_rect = sInstance->getRootView()->getRect();
- LLSnapshotLivePreview* previewp = new LLSnapshotLivePreview(full_screen_rect);
- sInstance->getRootView()->removeChild(gSnapshotFloaterView);
+ LLRect full_screen_rect = getRootView()->getRect();
+ LLSnapshotLivePreview::Params p;
+ p.rect(full_screen_rect);
+ LLSnapshotLivePreview* previewp = new LLSnapshotLivePreview(p);
+ getRootView()->removeChild(gSnapshotFloaterView);
// make sure preview is below snapshot floater
- sInstance->getRootView()->addChild(previewp);
- sInstance->getRootView()->addChild(gSnapshotFloaterView);
-
- Impl::sPreviewHandle = previewp->getHandle();
+ getRootView()->addChild(previewp);
+ getRootView()->addChild(gSnapshotFloaterView);
+
+ //move snapshot floater to special purpose snapshotfloaterview
+ gFloaterView->removeChild(this);
+ gSnapshotFloaterView->addChild(this);
+ impl.mPreviewHandle = previewp->getHandle();
impl.updateControls(this);
+ impl.updateLayout(this);
return TRUE;
}
@@ -2077,54 +2081,26 @@ void LLFloaterSnapshot::draw()
}
}
-void LLFloaterSnapshot::onClose(bool app_quitting)
-{
- gSnapshotFloaterView->setEnabled(FALSE);
- // Set invisible so it doesn't eat tooltips. JC
- gSnapshotFloaterView->setVisible(FALSE);
- destroy();
-}
-
-// static
-void LLFloaterSnapshot::show(void*)
+void LLFloaterSnapshot::onOpen(const LLSD& key)
{
- if (!sInstance)
+ LLSnapshotLivePreview* preview = LLFloaterSnapshot::Impl::getPreviewView(this);
+ if(preview)
{
- sInstance = new LLFloaterSnapshot();
- LLUICtrlFactory::getInstance()->buildFloater(sInstance, "floater_snapshot.xml", NULL, FALSE);
- //move snapshot floater to special purpose snapshotfloaterview
- gFloaterView->removeChild(sInstance);
- gSnapshotFloaterView->addChild(sInstance);
-
- sInstance->impl.updateLayout(sInstance);
+ preview->updateSnapshot(TRUE);
}
- else // just refresh the snapshot in the existing floater instance (DEV-12255)
- {
- LLSnapshotLivePreview* preview = LLFloaterSnapshot::Impl::getPreviewView(sInstance);
- if(preview)
- {
- preview->updateSnapshot(TRUE);
- }
- }
-
- sInstance->open(); /* Flawfinder: ignore */
- sInstance->focusFirstItem(FALSE);
+ focusFirstItem(FALSE);
gSnapshotFloaterView->setEnabled(TRUE);
gSnapshotFloaterView->setVisible(TRUE);
- gSnapshotFloaterView->adjustToFitScreen(sInstance, FALSE);
-}
-
-void LLFloaterSnapshot::hide(void*)
-{
- if (sInstance && !sInstance->isDead())
- {
- sInstance->close();
- }
+ gSnapshotFloaterView->adjustToFitScreen(this, FALSE);
}
//static
void LLFloaterSnapshot::update()
{
+ LLFloaterSnapshot* inst = LLFloaterReg::findTypedInstance<LLFloaterSnapshot>("snapshot");
+ if (!inst)
+ return;
+
BOOL changed = FALSE;
for (std::set<LLSnapshotLivePreview*>::iterator iter = LLSnapshotLivePreview::sList.begin();
iter != LLSnapshotLivePreview::sList.end(); ++iter)
@@ -2133,7 +2109,7 @@ void LLFloaterSnapshot::update()
}
if(changed)
{
- sInstance->impl.updateControls(sInstance);
+ inst->impl.updateControls(inst);
}
}
@@ -2142,10 +2118,8 @@ void LLFloaterSnapshot::update()
/// Class LLSnapshotFloaterView
///----------------------------------------------------------------------------
-LLSnapshotFloaterView::LLSnapshotFloaterView( const std::string& name, const LLRect& rect ) : LLFloaterView(name, rect)
+LLSnapshotFloaterView::LLSnapshotFloaterView (const Params& p) : LLFloaterView (p)
{
- setMouseOpaque(TRUE);
- setEnabled(FALSE);
}
LLSnapshotFloaterView::~LLSnapshotFloaterView()
diff --git a/indra/newview/llfloatersnapshot.h b/indra/newview/llfloatersnapshot.h
index 14f1872cd1..bd01f6c573 100644
--- a/indra/newview/llfloatersnapshot.h
+++ b/indra/newview/llfloatersnapshot.h
@@ -35,10 +35,6 @@
#include "llfloater.h"
-#include "llmemory.h"
-#include "llimagegl.h"
-#include "llcharacter.h"
-
class LLFloaterSnapshot : public LLFloater
{
@@ -50,17 +46,15 @@ public:
SNAPSHOT_FORMAT_BMP
} ESnapshotFormat;
- LLFloaterSnapshot();
+ LLFloaterSnapshot(const LLSD& key);
virtual ~LLFloaterSnapshot();
-
+
/*virtual*/ BOOL postBuild();
/*virtual*/ void draw();
- /*virtual*/ void onClose(bool app_quitting);
-
- static void show(void*);
- static void hide(void*);
+ /*virtual*/ void onOpen(const LLSD& key);
+
static void update();
-
+
static S32 getUIWinHeightLong() {return sUIWinHeightLong ;}
static S32 getUIWinHeightShort() {return sUIWinHeightShort ;}
static S32 getUIWinWidth() {return sUIWinWidth ;}
@@ -69,7 +63,6 @@ private:
class Impl;
Impl& impl;
- static LLFloaterSnapshot* sInstance;
static S32 sUIWinHeightLong ;
static S32 sUIWinHeightShort ;
static S32 sUIWinWidth ;
@@ -78,7 +71,16 @@ private:
class LLSnapshotFloaterView : public LLFloaterView
{
public:
- LLSnapshotFloaterView( const std::string& name, const LLRect& rect );
+ struct Params
+ : public LLInitParam::Block<Params, LLFloaterView::Params>
+ {
+ };
+
+protected:
+ LLSnapshotFloaterView (const Params& p);
+ friend class LLUICtrlFactory;
+
+public:
virtual ~LLSnapshotFloaterView();
/*virtual*/ BOOL handleKey(KEY key, MASK mask, BOOL called_from_parent);
diff --git a/indra/newview/llfloatertelehub.cpp b/indra/newview/llfloatertelehub.cpp
index 530bb87983..9841cd2796 100644
--- a/indra/newview/llfloatertelehub.cpp
+++ b/indra/newview/llfloatertelehub.cpp
@@ -39,6 +39,7 @@
#include "llfontgl.h"
#include "llagent.h"
+#include "llfloaterreg.h"
#include "llfloatertools.h"
#include "llscrolllistctrl.h"
#include "llselectmgr.h"
@@ -48,56 +49,25 @@
#include "llviewerobjectlist.h"
#include "lluictrlfactory.h"
-LLFloaterTelehub* LLFloaterTelehub::sInstance = NULL;
-
-
-// static
-void LLFloaterTelehub::show()
-{
- if (sInstance)
- {
- sInstance->setVisibleAndFrontmost();
- return;
- }
-
- sInstance = new LLFloaterTelehub();
-
- // Show tools floater by selecting translate (select) tool
- LLToolMgr::getInstance()->setCurrentToolset(gBasicToolset);
- LLToolMgr::getInstance()->getCurrentToolset()->selectTool( LLToolCompTranslate::getInstance() );
-
- // Find tools floater, glue to bottom
- if (gFloaterTools)
- {
- LLRect tools_rect = gFloaterTools->getRect();
- S32 our_width = sInstance->getRect().getWidth();
- S32 our_height = sInstance->getRect().getHeight();
- LLRect our_rect;
- our_rect.setLeftTopAndSize(tools_rect.mLeft, tools_rect.mBottom, our_width, our_height);
- sInstance->setRect(our_rect);
- }
-
- sInstance->sendTelehubInfoRequest();
-}
-
-LLFloaterTelehub::LLFloaterTelehub()
-: LLFloater(std::string("telehub")),
+LLFloaterTelehub::LLFloaterTelehub(const LLSD& key)
+: LLFloater(key),
mTelehubObjectID(),
mTelehubObjectName(),
mTelehubPos(),
mTelehubRot(),
mNumSpawn(0)
{
- sInstance = this;
+ //LLUICtrlFactory::getInstance()->buildFloater(sInstance, "floater_telehub.xml");
+}
+BOOL LLFloaterTelehub::postBuild()
+{
gMessageSystem->setHandlerFunc("TelehubInfo", processTelehubInfo);
- LLUICtrlFactory::getInstance()->buildFloater(sInstance, "floater_telehub.xml");
-
- childSetAction("connect_btn", onClickConnect, this);
- childSetAction("disconnect_btn", onClickDisconnect, this);
- childSetAction("add_spawn_point_btn", onClickAddSpawnPoint, this);
- childSetAction("remove_spawn_point_btn", onClickRemoveSpawnPoint, this);
+ getChild<LLUICtrl>("connect_btn")->setCommitCallback(boost::bind(&LLFloaterTelehub::onClickConnect, this));
+ getChild<LLUICtrl>("disconnect_btn")->setCommitCallback(boost::bind(&LLFloaterTelehub::onClickDisconnect, this));
+ getChild<LLUICtrl>("add_spawn_point_btn")->setCommitCallback(boost::bind(&LLFloaterTelehub::onClickAddSpawnPoint, this));
+ getChild<LLUICtrl>("remove_spawn_point_btn")->setCommitCallback(boost::bind(&LLFloaterTelehub::onClickRemoveSpawnPoint, this));
LLScrollListCtrl* list = getChild<LLScrollListCtrl>("spawn_points_list");
if (list)
@@ -106,13 +76,32 @@ LLFloaterTelehub::LLFloaterTelehub()
list->setAllowKeyboardMovement(FALSE);
}
+ return TRUE;
+}
+void LLFloaterTelehub::onOpen(const LLSD& key)
+{
+ // Show tools floater by selecting translate (select) tool
+ LLToolMgr::getInstance()->setCurrentToolset(gBasicToolset);
+ LLToolMgr::getInstance()->getCurrentToolset()->selectTool( LLToolCompTranslate::getInstance() );
+
+ // Find tools floater, glue to bottom
+ if (gFloaterTools)
+ {
+ LLRect tools_rect = gFloaterTools->getRect();
+ S32 our_width = getRect().getWidth();
+ S32 our_height = getRect().getHeight();
+ LLRect our_rect;
+ our_rect.setLeftTopAndSize(tools_rect.mLeft, tools_rect.mBottom, our_width, our_height);
+ setRect(our_rect);
+ }
+
+ sendTelehubInfoRequest();
+
mObjectSelection = LLSelectMgr::getInstance()->getEditSelection();
}
LLFloaterTelehub::~LLFloaterTelehub()
{
- sInstance = NULL;
-
// no longer interested in this message
gMessageSystem->setHandlerFunc("TelehubInfo", NULL);
}
@@ -154,19 +143,22 @@ void LLFloaterTelehub::refresh()
BOOL LLFloaterTelehub::renderBeacons()
{
// only render if we've got a telehub
- return sInstance && sInstance->mTelehubObjectID.notNull();
+ LLFloaterTelehub* floater = LLFloaterReg::findTypedInstance<LLFloaterTelehub>("telehubs");
+ return floater && floater->mTelehubObjectID.notNull();
}
// static
void LLFloaterTelehub::addBeacons()
{
- if (!sInstance) return;
-
+ LLFloaterTelehub* floater = LLFloaterReg::findTypedInstance<LLFloaterTelehub>("telehubs");
+ if (!floater)
+ return;
+
// Find the telehub position, either our cached old position, or
// an updated one based on the actual object position.
- LLVector3 hub_pos_region = sInstance->mTelehubPos;
- LLQuaternion hub_rot = sInstance->mTelehubRot;
- LLViewerObject* obj = gObjectList.findObject(sInstance->mTelehubObjectID);
+ LLVector3 hub_pos_region = floater->mTelehubPos;
+ LLQuaternion hub_rot = floater->mTelehubRot;
+ LLViewerObject* obj = gObjectList.findObject(floater->mTelehubObjectID);
if (obj)
{
hub_pos_region = obj->getPositionRegion();
@@ -175,13 +167,13 @@ void LLFloaterTelehub::addBeacons()
// Draw nice thick 3-pixel lines.
gObjectList.addDebugBeacon(hub_pos_region, "", LLColor4::yellow, LLColor4::white, 4);
- LLScrollListCtrl* list = sInstance->getChild<LLScrollListCtrl>("spawn_points_list");
+ LLScrollListCtrl* list = floater->getChild<LLScrollListCtrl>("spawn_points_list");
if (list)
{
S32 spawn_index = list->getFirstSelectedIndex();
if (spawn_index >= 0)
{
- LLVector3 spawn_pos = hub_pos_region + (sInstance->mSpawnPointPos[spawn_index] * hub_rot);
+ LLVector3 spawn_pos = hub_pos_region + (floater->mSpawnPointPos[spawn_index] * hub_rot);
gObjectList.addDebugBeacon(spawn_pos, "", LLColor4::orange, LLColor4::white, 4);
}
}
@@ -192,32 +184,27 @@ void LLFloaterTelehub::sendTelehubInfoRequest()
LLSelectMgr::getInstance()->sendGodlikeRequest("telehub", "info ui");
}
-// static
-void LLFloaterTelehub::onClickConnect(void* data)
+void LLFloaterTelehub::onClickConnect()
{
LLSelectMgr::getInstance()->sendGodlikeRequest("telehub", "connect");
}
-// static
-void LLFloaterTelehub::onClickDisconnect(void* data)
+void LLFloaterTelehub::onClickDisconnect()
{
LLSelectMgr::getInstance()->sendGodlikeRequest("telehub", "delete");
}
-// static
-void LLFloaterTelehub::onClickAddSpawnPoint(void* data)
+void LLFloaterTelehub::onClickAddSpawnPoint()
{
LLSelectMgr::getInstance()->sendGodlikeRequest("telehub", "spawnpoint add");
LLSelectMgr::getInstance()->deselectAll();
}
-// static
-void LLFloaterTelehub::onClickRemoveSpawnPoint(void* data)
+void LLFloaterTelehub::onClickRemoveSpawnPoint()
{
- if (!sInstance) return;
-
- LLScrollListCtrl* list = sInstance->getChild<LLScrollListCtrl>("spawn_points_list");
- if (!list) return;
+ LLScrollListCtrl* list = getChild<LLScrollListCtrl>("spawn_points_list");
+ if (!list)
+ return;
S32 spawn_index = list->getFirstSelectedIndex();
if (spawn_index < 0) return; // nothing selected
@@ -255,9 +242,10 @@ void LLFloaterTelehub::onClickRemoveSpawnPoint(void* data)
// static
void LLFloaterTelehub::processTelehubInfo(LLMessageSystem* msg, void**)
{
- if (sInstance)
+ LLFloaterTelehub* floater = LLFloaterReg::findTypedInstance<LLFloaterTelehub>("telehubs");
+ if (floater)
{
- sInstance->unpackTelehubInfo(msg);
+ floater->unpackTelehubInfo(msg);
}
}
diff --git a/indra/newview/llfloatertelehub.h b/indra/newview/llfloatertelehub.h
index 28c9d16573..5b654585f1 100644
--- a/indra/newview/llfloatertelehub.h
+++ b/indra/newview/llfloatertelehub.h
@@ -44,25 +44,24 @@ const S32 MAX_SPAWNPOINTS_PER_TELEHUB = 16;
class LLFloaterTelehub : public LLFloater
{
public:
- // Opens the floater on screen.
- static void show();
-
- virtual void draw();
+ LLFloaterTelehub(const LLSD& key);
+ ~LLFloaterTelehub();
+
+ /*virtual*/ BOOL postBuild();
+ /*virtual*/ void onOpen(const LLSD& key);
+ /*virtual*/ void draw();
+
static BOOL renderBeacons();
static void addBeacons();
-private:
- LLFloaterTelehub();
- ~LLFloaterTelehub();
-
void refresh();
void sendTelehubInfoRequest();
- static void onClickConnect(void* data);
- static void onClickDisconnect(void* data);
- static void onClickAddSpawnPoint(void* data);
- static void onClickRemoveSpawnPoint(void* data);
+ void onClickConnect();
+ void onClickDisconnect();
+ void onClickAddSpawnPoint();
+ void onClickRemoveSpawnPoint();
static void processTelehubInfo(LLMessageSystem* msg, void**);
void unpackTelehubInfo(LLMessageSystem* msg);
diff --git a/indra/newview/llfloatertestlistview.cpp b/indra/newview/llfloatertestlistview.cpp
new file mode 100644
index 0000000000..5c942d0ed9
--- /dev/null
+++ b/indra/newview/llfloatertestlistview.cpp
@@ -0,0 +1,77 @@
+/**
+* @file llfloatertestlistview.cpp
+* @brief Tests of programmatic manipulation of LLListView widgets
+*
+* $LicenseInfo:firstyear=2009&license=viewergpl$
+*
+* Copyright (c) 2009, Linden Research, Inc.
+*
+* Second Life Viewer Source Code
+* The source code in this file ("Source Code") is provided by Linden Lab
+* to you under the terms of the GNU General Public License, version 2.0
+* ("GPL"), unless you have obtained a separate licensing agreement
+* ("Other License"), formally executed by you and Linden Lab. Terms of
+* the GPL can be found in doc/GPL-license.txt in this distribution, or
+* online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
+*
+* There are special exceptions to the terms and conditions of the GPL as
+* it is applied to this Source Code. View the full text of the exception
+* in the file doc/FLOSS-exception.txt in this software distribution, or
+* online at
+* http://secondlifegrid.net/programs/open_source/licensing/flossexception
+*
+* By copying, modifying or distributing this software, you acknowledge
+* that you have read and understood your obligations described above,
+* and agree to abide by those obligations.
+*
+* ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+* COMPLETENESS OR PERFORMANCE.
+* $/LicenseInfo$
+*/
+#include "llviewerprecompiledheaders.h"
+
+#include "llfloatertestlistview.h"
+
+// Viewer includes
+#include "lllistview.h"
+
+// Linden library includes
+//#include "lluictrlfactory.h"
+
+LLFloaterTestListView::LLFloaterTestListView(const LLSD& seed)
+: LLFloater(seed),
+ mListView(NULL)
+{
+ // set up named callback functions for test buttons
+ mCommitCallbackRegistrar.add("TestListView.Test1",
+ boost::bind(&LLFloaterTestListView::onClickTest1, this));
+ mCommitCallbackRegistrar.add("TestListView.Test2",
+ boost::bind(&LLFloaterTestListView::onClickTest2, this));
+}
+
+LLFloaterTestListView::~LLFloaterTestListView()
+{}
+
+BOOL LLFloaterTestListView::postBuild()
+{
+ mListView = getChild<LLListView>("test_list_view");
+ // just set a random property
+ mListView->setString("set programmatically");
+ return LLFloater::postBuild();
+}
+
+void LLFloaterTestListView::onListViewChanged()
+{
+ llinfos << "list view changed" << llendl;
+}
+
+void LLFloaterTestListView::onClickTest1()
+{
+ llinfos << "test 1" << llendl;
+}
+
+void LLFloaterTestListView::onClickTest2()
+{
+ llinfos << "test 2" << llendl;
+}
diff --git a/indra/newview/llfloatertestlistview.h b/indra/newview/llfloatertestlistview.h
new file mode 100644
index 0000000000..053da95def
--- /dev/null
+++ b/indra/newview/llfloatertestlistview.h
@@ -0,0 +1,64 @@
+/**
+* @file llfloatertestlistview.h
+* @brief Tests of programmatic manipulation of LLListView widgets
+*
+* $LicenseInfo:firstyear=2009&license=viewergpl$
+*
+* Copyright (c) 2009, Linden Research, Inc.
+*
+* Second Life Viewer Source Code
+* The source code in this file ("Source Code") is provided by Linden Lab
+* to you under the terms of the GNU General Public License, version 2.0
+* ("GPL"), unless you have obtained a separate licensing agreement
+* ("Other License"), formally executed by you and Linden Lab. Terms of
+* the GPL can be found in doc/GPL-license.txt in this distribution, or
+* online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
+*
+* There are special exceptions to the terms and conditions of the GPL as
+* it is applied to this Source Code. View the full text of the exception
+* in the file doc/FLOSS-exception.txt in this software distribution, or
+* online at
+* http://secondlifegrid.net/programs/open_source/licensing/flossexception
+*
+* By copying, modifying or distributing this software, you acknowledge
+* that you have read and understood your obligations described above,
+* and agree to abide by those obligations.
+*
+* ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+* COMPLETENESS OR PERFORMANCE.
+* $/LicenseInfo$
+*/
+#ifndef LLFLOATERTESTLISTVIEW_H
+#define LLFLOATERTESTLISTVIEW_H
+
+#include "llfloater.h"
+
+class LLListView;
+class LLSD;
+
+class LLFloaterTestListView : public LLFloater
+{
+ friend class LLFloaterReg;
+public:
+ // nothing yet
+
+private:
+ // Construction handled by LLFloaterReg
+ LLFloaterTestListView(const LLSD& seed);
+ ~LLFloaterTestListView();
+
+ /*virtual*/ BOOL postBuild();
+
+ // Perform some debug action when the list-view sends change notification
+ void onListViewChanged();
+
+ // Debug function hookups for buttons
+ void onClickTest1();
+ void onClickTest2();
+
+private:
+ LLListView* mListView;
+};
+
+#endif
diff --git a/indra/newview/llfloatertools.cpp b/indra/newview/llfloatertools.cpp
index a33b49563c..d05c9cb9a7 100644
--- a/indra/newview/llfloatertools.cpp
+++ b/indra/newview/llfloatertools.cpp
@@ -45,6 +45,7 @@
#include "lldraghandle.h"
#include "llfloaterbuildoptions.h"
#include "llfloateropenobject.h"
+#include "llfloaterreg.h"
#include "llfocusmgr.h"
#include "llmenugl.h"
#include "llpanelcontents.h"
@@ -54,6 +55,7 @@
#include "llpanelobject.h"
#include "llpanelvolume.h"
#include "llpanelpermissions.h"
+#include "llradiogroup.h"
#include "llresmgr.h"
#include "llselectmgr.h"
#include "llslider.h"
@@ -95,25 +97,21 @@ const std::string PANEL_NAMES[LLFloaterTools::PANEL_COUNT] =
};
// Local prototypes
-void commit_select_tool(LLUICtrl *ctrl, void *data);
void commit_select_component(LLUICtrl *ctrl, void *data);
void click_show_more(void*);
void click_popup_info(void*);
void click_popup_done(void*);
void click_popup_minimize(void*);
-void click_popup_grab_drag(LLUICtrl *, void*);
-void click_popup_grab_lift(LLUICtrl *, void*);
-void click_popup_grab_spin(LLUICtrl *, void*);
void click_popup_rotate_left(void*);
void click_popup_rotate_reset(void*);
void click_popup_rotate_right(void*);
-void click_popup_dozer_mode(LLUICtrl *, void *user);
void commit_slider_dozer_size(LLUICtrl *, void*);
void commit_slider_dozer_force(LLUICtrl *, void*);
void click_apply_to_selection(void*);
-void commit_radio_zoom(LLUICtrl *, void*);
-void commit_radio_orbit(LLUICtrl *, void*);
-void commit_radio_pan(LLUICtrl *, void*);
+void commit_radio_group_focus(LLUICtrl* ctrl, void* data);
+void commit_radio_group_move(LLUICtrl* ctrl, void* data);
+void commit_radio_group_edit(LLUICtrl* ctrl, void* data);
+void commit_radio_group_land(LLUICtrl* ctrl, void* data);
void commit_grid_mode(LLUICtrl *, void*);
void commit_slider_zoom(LLUICtrl *, void*);
@@ -122,14 +120,14 @@ void commit_slider_zoom(LLUICtrl *, void*);
void* LLFloaterTools::createPanelPermissions(void* data)
{
LLFloaterTools* floater = (LLFloaterTools*)data;
- floater->mPanelPermissions = new LLPanelPermissions("General");
+ floater->mPanelPermissions = new LLPanelPermissions();
return floater->mPanelPermissions;
}
//static
void* LLFloaterTools::createPanelObject(void* data)
{
LLFloaterTools* floater = (LLFloaterTools*)data;
- floater->mPanelObject = new LLPanelObject("Object");
+ floater->mPanelObject = new LLPanelObject();
return floater->mPanelObject;
}
@@ -137,7 +135,7 @@ void* LLFloaterTools::createPanelObject(void* data)
void* LLFloaterTools::createPanelVolume(void* data)
{
LLFloaterTools* floater = (LLFloaterTools*)data;
- floater->mPanelVolume = new LLPanelVolume("Features");
+ floater->mPanelVolume = new LLPanelVolume();
return floater->mPanelVolume;
}
@@ -145,7 +143,7 @@ void* LLFloaterTools::createPanelVolume(void* data)
void* LLFloaterTools::createPanelFace(void* data)
{
LLFloaterTools* floater = (LLFloaterTools*)data;
- floater->mPanelFace = new LLPanelFace("Texture");
+ floater->mPanelFace = new LLPanelFace();
return floater->mPanelFace;
}
@@ -153,28 +151,54 @@ void* LLFloaterTools::createPanelFace(void* data)
void* LLFloaterTools::createPanelContents(void* data)
{
LLFloaterTools* floater = (LLFloaterTools*)data;
- floater->mPanelContents = new LLPanelContents("Contents");
+ floater->mPanelContents = new LLPanelContents();
return floater->mPanelContents;
}
//static
-void* LLFloaterTools::createPanelContentsInventory(void* data)
-{
- LLFloaterTools* floater = (LLFloaterTools*)data;
- floater->mPanelContents->mPanelInventory = new LLPanelInventory(std::string("ContentsInventory"), LLRect());
- return floater->mPanelContents->mPanelInventory;
-}
-
-//static
void* LLFloaterTools::createPanelLandInfo(void* data)
{
LLFloaterTools* floater = (LLFloaterTools*)data;
- floater->mPanelLandInfo = new LLPanelLandInfo(std::string("land info panel"));
+ floater->mPanelLandInfo = new LLPanelLandInfo();
return floater->mPanelLandInfo;
}
+static const std::string toolNames[]={
+ "ToolCube",
+ "ToolPrism",
+ "ToolPyramid",
+ "ToolTetrahedron",
+ "ToolCylinder",
+ "ToolHemiCylinder",
+ "ToolCone",
+ "ToolHemiCone",
+ "ToolSphere",
+ "ToolHemiSphere",
+ "ToolTorus",
+ "ToolTube",
+ "ToolRing",
+ "ToolTree",
+ "ToolGrass"};
+LLPCode toolData[]={
+ LL_PCODE_CUBE,
+ LL_PCODE_PRISM,
+ LL_PCODE_PYRAMID,
+ LL_PCODE_TETRAHEDRON,
+ LL_PCODE_CYLINDER,
+ LL_PCODE_CYLINDER_HEMI,
+ LL_PCODE_CONE,
+ LL_PCODE_CONE_HEMI,
+ LL_PCODE_SPHERE,
+ LL_PCODE_SPHERE_HEMI,
+ LL_PCODE_TORUS,
+ LLViewerObject::LL_VO_SQUARE_TORUS,
+ LLViewerObject::LL_VO_TRIANGLE_TORUS,
+ LL_PCODE_LEGACY_TREE,
+ LL_PCODE_LEGACY_GRASS};
+
BOOL LLFloaterTools::postBuild()
{
+ mCloseSignal.connect(boost::bind(&LLFloaterTools::onClose, this));
// Hide until tool selected
setVisible(FALSE);
@@ -200,27 +224,15 @@ BOOL LLFloaterTools::postBuild()
childSetCommitCallback("slider zoom",commit_slider_zoom,this);
- mRadioZoom = getChild<LLCheckBoxCtrl>("radio zoom");
- childSetCommitCallback("radio zoom",commit_radio_zoom,this);
- mRadioOrbit = getChild<LLCheckBoxCtrl>("radio orbit");
- childSetCommitCallback("radio orbit",commit_radio_orbit,this);
- mRadioPan = getChild<LLCheckBoxCtrl>("radio pan");
- childSetCommitCallback("radio pan",commit_radio_pan,this);
-
- mRadioMove = getChild<LLCheckBoxCtrl>("radio move");
- childSetCommitCallback("radio move",click_popup_grab_drag,this);
- mRadioLift = getChild<LLCheckBoxCtrl>("radio lift");
- childSetCommitCallback("radio lift",click_popup_grab_lift,this);
- mRadioSpin = getChild<LLCheckBoxCtrl>("radio spin");
- childSetCommitCallback("radio spin",click_popup_grab_spin,NULL);
- mRadioPosition = getChild<LLCheckBoxCtrl>("radio position");
- childSetCommitCallback("radio position",commit_select_tool,LLToolCompTranslate::getInstance());
- mRadioRotate = getChild<LLCheckBoxCtrl>("radio rotate");
- childSetCommitCallback("radio rotate",commit_select_tool,LLToolCompRotate::getInstance());
- mRadioStretch = getChild<LLCheckBoxCtrl>("radio stretch");
- childSetCommitCallback("radio stretch",commit_select_tool,LLToolCompScale::getInstance());
- mRadioSelectFace = getChild<LLCheckBoxCtrl>("radio select face");
- childSetCommitCallback("radio select face",commit_select_tool,LLToolFace::getInstance());
+ mRadioGroupFocus = getChild<LLRadioGroup>("focus_radio_group");
+ childSetCommitCallback("focus_radio_group", commit_radio_group_focus, this);
+
+ mRadioGroupMove = getChild<LLRadioGroup>("move_radio_group");
+ childSetCommitCallback("move_radio_group", commit_radio_group_move, this);
+
+ mRadioGroupEdit = getChild<LLRadioGroup>("edit_radio_group");
+ childSetCommitCallback("edit_radio_group", commit_radio_group_edit, this);
+
mCheckSelectIndividual = getChild<LLCheckBoxCtrl>("checkbox edit linked parts");
childSetValue("checkbox edit linked parts",(BOOL)gSavedSettings.getBOOL("EditLinkedParts"));
childSetCommitCallback("checkbox edit linked parts",commit_select_component,this);
@@ -239,44 +251,12 @@ BOOL LLFloaterTools::postBuild()
// Create Buttons
//
- static const std::string toolNames[]={
- "ToolCube",
- "ToolPrism",
- "ToolPyramid",
- "ToolTetrahedron",
- "ToolCylinder",
- "ToolHemiCylinder",
- "ToolCone",
- "ToolHemiCone",
- "ToolSphere",
- "ToolHemiSphere",
- "ToolTorus",
- "ToolTube",
- "ToolRing",
- "ToolTree",
- "ToolGrass"};
- void* toolData[]={
- &LLToolPlacerPanel::sCube,
- &LLToolPlacerPanel::sPrism,
- &LLToolPlacerPanel::sPyramid,
- &LLToolPlacerPanel::sTetrahedron,
- &LLToolPlacerPanel::sCylinder,
- &LLToolPlacerPanel::sCylinderHemi,
- &LLToolPlacerPanel::sCone,
- &LLToolPlacerPanel::sConeHemi,
- &LLToolPlacerPanel::sSphere,
- &LLToolPlacerPanel::sSphereHemi,
- &LLToolPlacerPanel::sTorus,
- &LLToolPlacerPanel::sSquareTorus,
- &LLToolPlacerPanel::sTriangleTorus,
- &LLToolPlacerPanel::sTree,
- &LLToolPlacerPanel::sGrass};
for(size_t t=0; t<LL_ARRAY_SIZE(toolNames); ++t)
{
LLButton *found = getChild<LLButton>(toolNames[t]);
if(found)
{
- found->setClickedCallback(setObjectType,toolData[t]);
+ found->setClickedCallback(boost::bind(&LLFloaterTools::setObjectType, toolData[t]));
mButtons.push_back( found );
}else{
llwarns << "Tool button not found! DOA Pending." << llendl;
@@ -290,20 +270,10 @@ BOOL LLFloaterTools::postBuild()
childSetValue("checkbox copy centers",(BOOL)gSavedSettings.getBOOL("CreateToolCopyCenters"));
mCheckCopyRotates = getChild<LLCheckBoxCtrl>("checkbox copy rotates");
childSetValue("checkbox copy rotates",(BOOL)gSavedSettings.getBOOL("CreateToolCopyRotates"));
- mRadioSelectLand = getChild<LLCheckBoxCtrl>("radio select land");
- childSetCommitCallback("radio select land",commit_select_tool, LLToolSelectLand::getInstance());
- mRadioDozerFlatten = getChild<LLCheckBoxCtrl>("radio flatten");
- childSetCommitCallback("radio flatten",click_popup_dozer_mode, (void*)0);
- mRadioDozerRaise = getChild<LLCheckBoxCtrl>("radio raise");
- childSetCommitCallback("radio raise",click_popup_dozer_mode, (void*)1);
- mRadioDozerLower = getChild<LLCheckBoxCtrl>("radio lower");
- childSetCommitCallback("radio lower",click_popup_dozer_mode, (void*)2);
- mRadioDozerSmooth = getChild<LLCheckBoxCtrl>("radio smooth");
- childSetCommitCallback("radio smooth",click_popup_dozer_mode, (void*)3);
- mRadioDozerNoise = getChild<LLCheckBoxCtrl>("radio noise");
- childSetCommitCallback("radio noise",click_popup_dozer_mode, (void*)4);
- mRadioDozerRevert = getChild<LLCheckBoxCtrl>("radio revert");
- childSetCommitCallback("radio revert",click_popup_dozer_mode, (void*)5);
+
+ mRadioGroupLand = getChild<LLRadioGroup>("land_radio_group");
+ childSetCommitCallback("land_radio_group", commit_radio_group_land, this);
+
mBtnApplyToSelection = getChild<LLButton>("button apply to selection");
childSetAction("button apply to selection",click_apply_to_selection, (void*)0);
@@ -338,8 +308,8 @@ BOOL LLFloaterTools::postBuild()
// Create the popupview with a dummy center. It will be moved into place
// during LLViewerWindow's per-frame hover processing.
-LLFloaterTools::LLFloaterTools()
-: LLFloater(std::string("toolbox floater")),
+LLFloaterTools::LLFloaterTools(const LLSD& key)
+: LLFloater(key),
mBtnFocus(NULL),
mBtnMove(NULL),
mBtnEdit(NULL),
@@ -347,18 +317,10 @@ LLFloaterTools::LLFloaterTools()
mBtnLand(NULL),
mTextStatus(NULL),
- mRadioOrbit(NULL),
- mRadioZoom(NULL),
- mRadioPan(NULL),
-
- mRadioMove(NULL),
- mRadioLift(NULL),
- mRadioSpin(NULL),
+ mRadioGroupFocus(NULL),
+ mRadioGroupMove(NULL),
+ mRadioGroupEdit(NULL),
- mRadioPosition(NULL),
- mRadioRotate(NULL),
- mRadioStretch(NULL),
- mRadioSelectFace(NULL),
mCheckSelectIndividual(NULL),
mCheckSnapToGrid(NULL),
@@ -380,13 +342,7 @@ LLFloaterTools::LLFloaterTools()
mCheckCopySelection(NULL),
mCheckCopyCenters(NULL),
mCheckCopyRotates(NULL),
- mRadioSelectLand(NULL),
- mRadioDozerFlatten(NULL),
- mRadioDozerRaise(NULL),
- mRadioDozerLower(NULL),
- mRadioDozerSmooth(NULL),
- mRadioDozerNoise(NULL),
- mRadioDozerRevert(NULL),
+ mRadioGroupLand(NULL),
mSliderDozerSize(NULL),
mSliderDozerForce(NULL),
mBtnApplyToSelection(NULL),
@@ -402,22 +358,23 @@ LLFloaterTools::LLFloaterTools()
mTabLand(NULL),
mDirty(TRUE)
{
+ gFloaterTools = this;
+
setAutoFocus(FALSE);
- LLCallbackMap::map_t factory_map;
- factory_map["General"] = LLCallbackMap(createPanelPermissions, this);//LLPanelPermissions
- factory_map["Object"] = LLCallbackMap(createPanelObject, this);//LLPanelObject
- factory_map["Features"] = LLCallbackMap(createPanelVolume, this);//LLPanelVolume
- factory_map["Texture"] = LLCallbackMap(createPanelFace, this);//LLPanelFace
- factory_map["Contents"] = LLCallbackMap(createPanelContents, this);//LLPanelContents
- factory_map["ContentsInventory"] = LLCallbackMap(createPanelContentsInventory, this);//LLPanelContents
- factory_map["land info panel"] = LLCallbackMap(createPanelLandInfo, this);//LLPanelLandInfo
-
- LLUICtrlFactory::getInstance()->buildFloater(this,"floater_tools.xml",&factory_map,FALSE);
+ mFactoryMap["General"] = LLCallbackMap(createPanelPermissions, this);//LLPanelPermissions
+ mFactoryMap["Object"] = LLCallbackMap(createPanelObject, this);//LLPanelObject
+ mFactoryMap["Features"] = LLCallbackMap(createPanelVolume, this);//LLPanelVolume
+ mFactoryMap["Texture"] = LLCallbackMap(createPanelFace, this);//LLPanelFace
+ mFactoryMap["Contents"] = LLCallbackMap(createPanelContents, this);//LLPanelContents
+ mFactoryMap["land info panel"] = LLCallbackMap(createPanelLandInfo, this);//LLPanelLandInfo
+
+ //Called from floater reg: LLUICtrlFactory::getInstance()->buildFloater(this,"floater_tools.xml",FALSE);
}
LLFloaterTools::~LLFloaterTools()
{
// children automatically deleted
+ gFloaterTools = NULL;
}
void LLFloaterTools::setStatusText(const std::string& text)
@@ -489,7 +446,8 @@ void LLFloaterTools::draw()
void LLFloaterTools::dirty()
{
mDirty = TRUE;
- LLFloaterOpenObject::dirty();
+ LLFloaterOpenObject* instance = LLFloaterReg::findTypedInstance<LLFloaterOpenObject>("openobject");
+ if (instance) instance->dirty();
}
// Clean up any tool state that should not persist when the
@@ -525,26 +483,31 @@ void LLFloaterTools::updatePopup(LLCoordGL center, MASK mask)
mBtnFocus ->setToggleState( focus_visible );
- mRadioZoom ->setVisible( focus_visible );
- mRadioOrbit ->setVisible( focus_visible );
- mRadioPan ->setVisible( focus_visible );
+ mRadioGroupFocus->setVisible( focus_visible );
childSetVisible("slider zoom", focus_visible);
childSetEnabled("slider zoom", gCameraBtnZoom);
- mRadioZoom ->set( !gCameraBtnOrbit &&
- !gCameraBtnPan &&
- !(mask == MASK_ORBIT) &&
- !(mask == (MASK_ORBIT | MASK_ALT)) &&
- !(mask == MASK_PAN) &&
- !(mask == (MASK_PAN | MASK_ALT)) );
-
- mRadioOrbit ->set( gCameraBtnOrbit ||
- (mask == MASK_ORBIT) ||
- (mask == (MASK_ORBIT | MASK_ALT)) );
-
- mRadioPan ->set( gCameraBtnPan ||
- (mask == MASK_PAN) ||
- (mask == (MASK_PAN | MASK_ALT)) );
+ if (!gCameraBtnOrbit &&
+ !gCameraBtnPan &&
+ !(mask == MASK_ORBIT) &&
+ !(mask == (MASK_ORBIT | MASK_ALT)) &&
+ !(mask == MASK_PAN) &&
+ !(mask == (MASK_PAN | MASK_ALT)) )
+ {
+ mRadioGroupFocus->setValue("radio zoom");
+ }
+ else if ( gCameraBtnOrbit ||
+ (mask == MASK_ORBIT) ||
+ (mask == (MASK_ORBIT | MASK_ALT)) )
+ {
+ mRadioGroupFocus->setValue("radio orbit");
+ }
+ else if ( gCameraBtnPan ||
+ (mask == MASK_PAN) ||
+ (mask == (MASK_PAN | MASK_ALT)) )
+ {
+ mRadioGroupFocus->setValue("radio pan");
+ }
// multiply by correction factor because volume sliders go [0, 0.5]
childSetValue( "slider zoom", gAgent.getCameraZoomFraction() * 0.5f);
@@ -555,27 +518,23 @@ void LLFloaterTools::updatePopup(LLCoordGL center, MASK mask)
if (mBtnMove) mBtnMove ->setToggleState( move_visible );
// HACK - highlight buttons for next click
- if (mRadioMove)
+ mRadioGroupMove->setVisible(move_visible);
+ if (!gGrabBtnSpin &&
+ !gGrabBtnVertical &&
+ !(mask == MASK_VERTICAL) &&
+ !(mask == MASK_SPIN) )
{
- mRadioMove ->setVisible( move_visible );
- mRadioMove ->set( !gGrabBtnSpin &&
- !gGrabBtnVertical &&
- !(mask == MASK_VERTICAL) &&
- !(mask == MASK_SPIN) );
+ mRadioGroupMove->setValue("radio move");
}
-
- if (mRadioLift)
+ else if (gGrabBtnVertical ||
+ (mask == MASK_VERTICAL) )
{
- mRadioLift ->setVisible( move_visible );
- mRadioLift ->set( gGrabBtnVertical ||
- (mask == MASK_VERTICAL) );
+ mRadioGroupMove->setValue("radio lift");
}
-
- if (mRadioSpin)
+ else if (gGrabBtnSpin ||
+ (mask == MASK_SPIN) )
{
- mRadioSpin ->setVisible( move_visible );
- mRadioSpin ->set( gGrabBtnSpin ||
- (mask == MASK_SPIN) );
+ mRadioGroupMove->setValue("radio spin");
}
// Edit buttons
@@ -587,15 +546,7 @@ void LLFloaterTools::updatePopup(LLCoordGL center, MASK mask)
tool == LLToolPipette::getInstance();
mBtnEdit ->setToggleState( edit_visible );
-
- mRadioPosition ->setVisible( edit_visible );
- mRadioRotate ->setVisible( edit_visible );
- mRadioStretch ->setVisible( edit_visible );
- if (mRadioSelectFace)
- {
- mRadioSelectFace->setVisible( edit_visible );
- mRadioSelectFace->set( tool == LLToolFace::getInstance() );
- }
+ mRadioGroupEdit->setVisible( edit_visible );
if (mCheckSelectIndividual)
{
@@ -603,9 +554,22 @@ void LLFloaterTools::updatePopup(LLCoordGL center, MASK mask)
//mCheckSelectIndividual->set(gSavedSettings.getBOOL("EditLinkedParts"));
}
- mRadioPosition ->set( tool == LLToolCompTranslate::getInstance() );
- mRadioRotate ->set( tool == LLToolCompRotate::getInstance() );
- mRadioStretch ->set( tool == LLToolCompScale::getInstance() );
+ if ( tool == LLToolCompTranslate::getInstance() )
+ {
+ mRadioGroupEdit->setValue("radio position");
+ }
+ else if ( tool == LLToolCompRotate::getInstance() )
+ {
+ mRadioGroupEdit->setValue("radio rotate");
+ }
+ else if ( tool == LLToolCompScale::getInstance() )
+ {
+ mRadioGroupEdit->setValue("radio stretch");
+ }
+ else if ( tool == LLToolFace::getInstance() )
+ {
+ mRadioGroupEdit->setValue("radio select face");
+ }
if (mComboGridMode)
{
@@ -662,15 +626,13 @@ void LLFloaterTools::updatePopup(LLCoordGL center, MASK mask)
else
{
// Highlight the correct placer button
- for( std::vector<LLButton*>::size_type i = 0; i < mButtons.size(); i++ )
+ for( S32 t = 0; t < (S32)mButtons.size(); t++ )
{
LLPCode pcode = LLToolPlacer::getObjectType();
- void *userdata = mButtons[i]->getCallbackUserData();
- LLPCode *cur = (LLPCode*) userdata;
-
- BOOL state = (pcode == *cur);
- mButtons[i]->setToggleState( state );
- mButtons[i]->setVisible( create_visible );
+ LLPCode button_pcode = toolData[t];
+ BOOL state = (pcode == button_pcode);
+ mButtons[t]->setToggleState( state );
+ mButtons[t]->setVisible( create_visible );
}
}
@@ -687,44 +649,39 @@ void LLFloaterTools::updatePopup(LLCoordGL center, MASK mask)
if (mBtnLand) mBtnLand ->setToggleState( land_visible );
- // mRadioEditLand ->set( tool == LLToolBrushLand::getInstance() );
- if (mRadioSelectLand) mRadioSelectLand->set( tool == LLToolSelectLand::getInstance() );
-
- // mRadioEditLand ->setVisible( land_visible );
- if (mRadioSelectLand) mRadioSelectLand->setVisible( land_visible );
-
- S32 dozer_mode = gSavedSettings.getS32("RadioLandBrushAction");
-
- if (mRadioDozerFlatten)
- {
- mRadioDozerFlatten ->set( tool == LLToolBrushLand::getInstance() && dozer_mode == 0);
- mRadioDozerFlatten ->setVisible( land_visible );
- }
- if (mRadioDozerRaise)
- {
- mRadioDozerRaise ->set( tool == LLToolBrushLand::getInstance() && dozer_mode == 1);
- mRadioDozerRaise ->setVisible( land_visible );
- }
- if (mRadioDozerLower)
+ mRadioGroupLand->setVisible( land_visible );
+ if ( tool == LLToolSelectLand::getInstance() )
{
- mRadioDozerLower ->set( tool == LLToolBrushLand::getInstance() && dozer_mode == 2);
- mRadioDozerLower ->setVisible( land_visible );
+ mRadioGroupLand->setValue("radio select land");
}
- if (mRadioDozerSmooth)
+ else if ( tool == LLToolBrushLand::getInstance() )
{
- mRadioDozerSmooth ->set( tool == LLToolBrushLand::getInstance() && dozer_mode == 3);
- mRadioDozerSmooth ->setVisible( land_visible );
- }
- if (mRadioDozerNoise)
- {
- mRadioDozerNoise ->set( tool == LLToolBrushLand::getInstance() && dozer_mode == 4);
- mRadioDozerNoise ->setVisible( land_visible );
- }
- if (mRadioDozerRevert)
- {
- mRadioDozerRevert ->set( tool == LLToolBrushLand::getInstance() && dozer_mode == 5);
- mRadioDozerRevert ->setVisible( land_visible );
+ S32 dozer_mode = gSavedSettings.getS32("RadioLandBrushAction");
+ switch(dozer_mode)
+ {
+ case 0:
+ mRadioGroupLand->setValue("radio flatten");
+ break;
+ case 1:
+ mRadioGroupLand->setValue("radio raise");
+ break;
+ case 2:
+ mRadioGroupLand->setValue("radio lower");
+ break;
+ case 3:
+ mRadioGroupLand->setValue("radio smooth");
+ break;
+ case 4:
+ mRadioGroupLand->setValue("radio noise");
+ break;
+ case 5:
+ mRadioGroupLand->setValue("radio revert");
+ break;
+ default:
+ break;
+ }
}
+
if (mBtnApplyToSelection)
{
mBtnApplyToSelection->setVisible( land_visible );
@@ -757,20 +714,22 @@ BOOL LLFloaterTools::canClose()
}
// virtual
-void LLFloaterTools::onOpen()
+void LLFloaterTools::onOpen(const LLSD& key)
{
mParcelSelection = LLViewerParcelMgr::getInstance()->getFloatingParcelSelection();
mObjectSelection = LLSelectMgr::getInstance()->getEditSelection();
- // gMenuBarView->setItemVisible(std::string("Tools"), TRUE);
- // gMenuBarView->arrange();
+ std::string panel = key.asString();
+ if (!panel.empty())
+ {
+ mTab->selectTabByName(panel);
+ }
+
+ gMenuBarView->setItemVisible("BuildTools", TRUE);
}
-// virtual
-void LLFloaterTools::onClose(bool app_quitting)
+void LLFloaterTools::onClose()
{
- setMinimized(FALSE);
- setVisible(FALSE);
mTab->setVisible(FALSE);
LLViewerJoystick::getInstance()->moveAvatar(false);
@@ -796,19 +755,11 @@ void LLFloaterTools::onClose(bool app_quitting)
// so manually reset tool to default (pie menu tool)
LLToolMgr::getInstance()->getCurrentToolset()->selectFirstTool();
- // gMenuBarView->setItemVisible(std::string("Tools"), FALSE);
- // gMenuBarView->arrange();
-}
-
-void LLFloaterTools::showPanel(EInfoPanel panel)
-{
- llassert(panel >= 0 && panel < PANEL_COUNT);
- mTab->selectTabByName(PANEL_NAMES[panel]);
+ gMenuBarView->setItemVisible("BuildTools", FALSE);
}
void click_popup_info(void*)
{
-// gBuildView->setPropertiesPanelOpen(TRUE);
}
void click_popup_done(void*)
@@ -816,43 +767,49 @@ void click_popup_done(void*)
handle_reset_view();
}
-void click_popup_grab_drag(LLUICtrl*, void*)
-{
- gGrabBtnVertical = FALSE;
- gGrabBtnSpin = FALSE;
-}
-
-void click_popup_grab_lift(LLUICtrl*, void*)
+void commit_radio_group_move(LLUICtrl* ctrl, void* data)
{
- gGrabBtnVertical = TRUE;
- gGrabBtnSpin = FALSE;
-}
-
-void click_popup_grab_spin(LLUICtrl*, void*)
-{
- gGrabBtnVertical = FALSE;
- gGrabBtnSpin = TRUE;
-}
-
-void commit_radio_zoom(LLUICtrl *, void*)
-{
- gCameraBtnZoom = TRUE;
- gCameraBtnOrbit = FALSE;
- gCameraBtnPan = FALSE;
-}
-
-void commit_radio_orbit(LLUICtrl *, void*)
-{
- gCameraBtnZoom = FALSE;
- gCameraBtnOrbit = TRUE;
- gCameraBtnPan = FALSE;
+ LLRadioGroup* group = (LLRadioGroup*)ctrl;
+ std::string selected = group->getValue().asString();
+ if (selected == "radio move")
+ {
+ gGrabBtnVertical = FALSE;
+ gGrabBtnSpin = FALSE;
+ }
+ else if (selected == "radio lift")
+ {
+ gGrabBtnVertical = TRUE;
+ gGrabBtnSpin = FALSE;
+ }
+ else if (selected == "radio spin")
+ {
+ gGrabBtnVertical = FALSE;
+ gGrabBtnSpin = TRUE;
+ }
}
-void commit_radio_pan(LLUICtrl *, void*)
+void commit_radio_group_focus(LLUICtrl* ctrl, void* data)
{
- gCameraBtnZoom = FALSE;
- gCameraBtnOrbit = FALSE;
- gCameraBtnPan = TRUE;
+ LLRadioGroup* group = (LLRadioGroup*)ctrl;
+ std::string selected = group->getValue().asString();
+ if (selected == "radio zoom")
+ {
+ gCameraBtnZoom = TRUE;
+ gCameraBtnOrbit = FALSE;
+ gCameraBtnPan = FALSE;
+ }
+ else if (selected == "radio orbit")
+ {
+ gCameraBtnZoom = FALSE;
+ gCameraBtnOrbit = TRUE;
+ gCameraBtnPan = FALSE;
+ }
+ else if (selected == "radio pan")
+ {
+ gCameraBtnZoom = FALSE;
+ gCameraBtnOrbit = FALSE;
+ gCameraBtnPan = TRUE;
+ }
}
void commit_slider_zoom(LLUICtrl *ctrl, void*)
@@ -881,13 +838,6 @@ void click_popup_rotate_right(void*)
}
-void click_popup_dozer_mode(LLUICtrl *, void *user)
-{
- S32 mode = (S32)(intptr_t) user;
- gFloaterTools->setEditTool( LLToolBrushLand::getInstance() );
- gSavedSettings.setS32("RadioLandBrushAction", mode);
-}
-
void commit_slider_dozer_size(LLUICtrl *ctrl, void*)
{
F32 size = (F32)ctrl->getValue().asReal();
@@ -901,21 +851,64 @@ void commit_slider_dozer_force(LLUICtrl *ctrl, void*)
gSavedSettings.setF32("LandBrushForce", dozer_force);
}
-
-
-
void click_apply_to_selection(void* user)
{
LLToolBrushLand::getInstance()->modifyLandInSelectionGlobal();
}
-void commit_select_tool(LLUICtrl *ctrl, void *data)
+void commit_radio_group_edit(LLUICtrl *ctrl, void *data)
{
S32 show_owners = gSavedSettings.getBOOL("ShowParcelOwners");
- gFloaterTools->setEditTool(data);
+
+ LLRadioGroup* group = (LLRadioGroup*)ctrl;
+ std::string selected = group->getValue().asString();
+ if (selected == "radio position")
+ {
+ LLFloaterTools::setEditTool( LLToolCompTranslate::getInstance() );
+ }
+ else if (selected == "radio rotate")
+ {
+ LLFloaterTools::setEditTool( LLToolCompRotate::getInstance() );
+ }
+ else if (selected == "radio stretch")
+ {
+ LLFloaterTools::setEditTool( LLToolCompScale::getInstance() );
+ }
+ else if (selected == "radio select face")
+ {
+ LLFloaterTools::setEditTool( LLToolFace::getInstance() );
+ }
gSavedSettings.setBOOL("ShowParcelOwners", show_owners);
}
+void commit_radio_group_land(LLUICtrl* ctrl, void* data)
+{
+ LLRadioGroup* group = (LLRadioGroup*)ctrl;
+ std::string selected = group->getValue().asString();
+ if (selected == "radio select land")
+ {
+ LLFloaterTools::setEditTool( LLToolSelectLand::getInstance() );
+ }
+ else
+ {
+ LLFloaterTools::setEditTool( LLToolBrushLand::getInstance() );
+ S32 dozer_mode = gSavedSettings.getS32("RadioLandBrushAction");
+ if (selected == "radio flatten")
+ dozer_mode = 0;
+ else if (selected == "radio raise")
+ dozer_mode = 1;
+ else if (selected == "radio lower")
+ dozer_mode = 2;
+ else if (selected == "radio smooth")
+ dozer_mode = 3;
+ else if (selected == "radio noise")
+ dozer_mode = 4;
+ else if (selected == "radio revert")
+ dozer_mode = 5;
+ gSavedSettings.setS32("RadioLandBrushAction", dozer_mode);
+ }
+}
+
void commit_select_component(LLUICtrl *ctrl, void *data)
{
LLFloaterTools* floaterp = (LLFloaterTools*)data;
@@ -948,9 +941,8 @@ void commit_grid_mode(LLUICtrl *ctrl, void *data)
}
// static
-void LLFloaterTools::setObjectType( void* data )
+void LLFloaterTools::setObjectType( LLPCode pcode )
{
- LLPCode pcode = *(LLPCode*) data;
LLToolPlacer::setObjectType( pcode );
gSavedSettings.setBOOL("CreateToolCopySelection", FALSE);
gFocusMgr.setMouseCapture(NULL);
@@ -960,14 +952,16 @@ void LLFloaterTools::setObjectType( void* data )
void LLFloaterTools::onClickGridOptions(void* data)
{
//LLFloaterTools* floaterp = (LLFloaterTools*)data;
- LLFloaterBuildOptions::show(NULL);
+ LLFloaterReg::showInstance("build_options");
// RN: this makes grid options dependent on build tools window
//floaterp->addDependentFloater(LLFloaterBuildOptions::getInstance(), FALSE);
}
+// static
void LLFloaterTools::setEditTool(void* tool_pointer)
{
- select_tool(tool_pointer);
+ LLTool *tool = (LLTool *)tool_pointer;
+ LLToolMgr::getInstance()->getCurrentToolset()->selectTool( tool );
}
void LLFloaterTools::onFocusReceived()
diff --git a/indra/newview/llfloatertools.h b/indra/newview/llfloatertools.h
index 833a8a7b73..1b9f1d31ec 100644
--- a/indra/newview/llfloatertools.h
+++ b/indra/newview/llfloatertools.h
@@ -38,18 +38,20 @@
#include "llparcelselection.h"
class LLButton;
-class LLTextBox;
-class LLTool;
+class LLComboBox;
class LLCheckBoxCtrl;
-class LLTabContainer;
class LLPanelPermissions;
class LLPanelObject;
class LLPanelVolume;
class LLPanelContents;
class LLPanelFace;
class LLPanelLandInfo;
-class LLComboBox;
+class LLRadioCtrl;
+class LLRadioGroup;
class LLSlider;
+class LLTabContainer;
+class LLTextBox;
+class LLTool;
class LLParcelSelection;
class LLObjectSelection;
@@ -65,15 +67,15 @@ public:
static void* createPanelVolume(void* vdata);
static void* createPanelFace(void* vdata);
static void* createPanelContents(void* vdata);
- static void* createPanelContentsInventory(void* vdata);
static void* createPanelLandInfo(void* vdata);
- LLFloaterTools();
+ LLFloaterTools(const LLSD& key);
virtual ~LLFloaterTools();
- virtual void onOpen();
- virtual void onClose(bool app_quitting);
- virtual BOOL canClose();
+ /*virtual*/ void onOpen(const LLSD& key);
+ /*virtual*/ BOOL canClose();
+ /*virtual*/ void draw();
+ /*virtual*/ void onFocusReceived();
// call this once per frame to handle visibility, rect location,
// button highlights, etc.
@@ -93,24 +95,20 @@ public:
PANEL_COUNT
};
- /*virtual*/ void draw();
-
void dirty();
void showPanel(EInfoPanel panel);
void setStatusText(const std::string& text);
- virtual void onFocusReceived();
static void setEditTool(void* data);
void saveLastTool();
private:
- static void setObjectType( void* data );
-
+ void onClose();
void refresh();
+ static void setObjectType( LLPCode pcode );
static void onClickGridOptions(void* data);
public:
-
LLButton *mBtnFocus;
LLButton *mBtnMove;
LLButton *mBtnEdit;
@@ -120,20 +118,13 @@ public:
LLTextBox *mTextStatus;
// Focus buttons
- LLCheckBoxCtrl *mRadioOrbit;
- LLCheckBoxCtrl *mRadioZoom;
- LLCheckBoxCtrl *mRadioPan;
+ LLRadioGroup* mRadioGroupFocus;
// Move buttons
- LLCheckBoxCtrl *mRadioMove;
- LLCheckBoxCtrl *mRadioLift;
- LLCheckBoxCtrl *mRadioSpin;
+ LLRadioGroup* mRadioGroupMove;
// Edit buttons
- LLCheckBoxCtrl *mRadioPosition;
- LLCheckBoxCtrl *mRadioRotate;
- LLCheckBoxCtrl *mRadioStretch;
- LLCheckBoxCtrl *mRadioSelectFace;
+ LLRadioGroup* mRadioGroupEdit;
LLCheckBoxCtrl *mCheckSelectIndividual;
@@ -159,15 +150,7 @@ public:
LLCheckBoxCtrl *mCheckCopyRotates;
// Land buttons
-// LLCheckBoxCtrl *mRadioEditLand;
- LLCheckBoxCtrl *mRadioSelectLand;
-
- LLCheckBoxCtrl *mRadioDozerFlatten;
- LLCheckBoxCtrl *mRadioDozerRaise;
- LLCheckBoxCtrl *mRadioDozerLower;
- LLCheckBoxCtrl *mRadioDozerSmooth;
- LLCheckBoxCtrl *mRadioDozerNoise;
- LLCheckBoxCtrl *mRadioDozerRevert;
+ LLRadioGroup* mRadioGroupLand;
LLSlider *mSliderDozerSize;
LLSlider *mSliderDozerForce;
diff --git a/indra/newview/llfloatertopobjects.cpp b/indra/newview/llfloatertopobjects.cpp
index fa6ba162ec..bf5a1141a6 100644
--- a/indra/newview/llfloatertopobjects.cpp
+++ b/indra/newview/llfloatertopobjects.cpp
@@ -40,8 +40,11 @@
#include "llagent.h"
#include "llbutton.h"
#include "llfloatergodtools.h"
+#include "llfloaterreg.h"
#include "llparcel.h"
#include "llscrolllistctrl.h"
+#include "llscrolllistitem.h"
+#include "llscrolllistcell.h"
#include "lllineeditor.h"
#include "lltextbox.h"
#include "lltracker.h"
@@ -51,11 +54,11 @@
#include "lluictrlfactory.h"
#include "llviewerwindow.h"
-LLFloaterTopObjects* LLFloaterTopObjects::sInstance = NULL;
+//LLFloaterTopObjects* LLFloaterTopObjects::sInstance = NULL;
// Globals
// const U32 TIME_STR_LENGTH = 30;
-
+/*
// static
void LLFloaterTopObjects::show()
{
@@ -66,64 +69,53 @@ void LLFloaterTopObjects::show()
}
sInstance = new LLFloaterTopObjects();
- LLUICtrlFactory::getInstance()->buildFloater(sInstance, "floater_top_objects.xml");
+// LLUICtrlFactory::getInstance()->buildFloater(sInstance, "floater_top_objects.xml");
sInstance->center();
}
-
-LLFloaterTopObjects::LLFloaterTopObjects()
-: LLFloater(std::string("top_objects")),
+*/
+LLFloaterTopObjects::LLFloaterTopObjects(const LLSD& key)
+: LLFloater(key),
mInitialized(FALSE),
mtotalScore(0.f)
{
- sInstance = this;
+ mCommitCallbackRegistrar.add("TopObjects.ShowBeacon", boost::bind(&LLFloaterTopObjects::onClickShowBeacon, this));
+ mCommitCallbackRegistrar.add("TopObjects.ReturnSelected", boost::bind(&LLFloaterTopObjects::onReturnSelected, this));
+ mCommitCallbackRegistrar.add("TopObjects.ReturnAll", boost::bind(&LLFloaterTopObjects::onReturnAll, this));
+ mCommitCallbackRegistrar.add("TopObjects.DisableSelected", boost::bind(&LLFloaterTopObjects::onDisableSelected, this));
+ mCommitCallbackRegistrar.add("TopObjects.DisableAll", boost::bind(&LLFloaterTopObjects::onDisableAll, this));
+ mCommitCallbackRegistrar.add("TopObjects.Refresh", boost::bind(&LLFloaterTopObjects::onRefresh, this));
+ mCommitCallbackRegistrar.add("TopObjects.GetByObjectName", boost::bind(&LLFloaterTopObjects::onGetByObjectName, this));
+ mCommitCallbackRegistrar.add("TopObjects.GetByOwnerName", boost::bind(&LLFloaterTopObjects::onGetByOwnerName, this));
+ mCommitCallbackRegistrar.add("TopObjects.CommitObjectsList",boost::bind(&LLFloaterTopObjects::onCommitObjectsList, this));
}
LLFloaterTopObjects::~LLFloaterTopObjects()
{
- sInstance = NULL;
}
// virtual
BOOL LLFloaterTopObjects::postBuild()
{
- childSetCommitCallback("objects_list", onCommitObjectsList, this);
- childSetDoubleClickCallback("objects_list", onDoubleClickObjectsList);
- childSetFocus("objects_list");
LLScrollListCtrl *objects_list = getChild<LLScrollListCtrl>("objects_list");
- if (objects_list)
- {
- objects_list->setCommitOnSelectionChange(TRUE);
- }
+ childSetFocus("objects_list");
+ objects_list->setDoubleClickCallback(onDoubleClickObjectsList, this);
+ objects_list->setCommitOnSelectionChange(TRUE);
- childSetAction("show_beacon_btn", onClickShowBeacon, this);
setDefaultBtn("show_beacon_btn");
- childSetAction("return_selected_btn", onReturnSelected, this);
- childSetAction("return_all_btn", onReturnAll, this);
- childSetAction("disable_selected_btn", onDisableSelected, this);
- childSetAction("disable_all_btn", onDisableAll, this);
- childSetAction("refresh_btn", onRefresh, this);
-
-
- childSetAction("filter_object_btn", onGetByObjectNameClicked, this);
- childSetAction("filter_owner_btn", onGetByOwnerNameClicked, this);
-
-
/*
LLLineEditor* line_editor = getChild<LLLineEditor>("owner_name_editor");
if (line_editor)
{
line_editor->setCommitOnFocusLost(FALSE);
- line_editor->setCommitCallback(onGetByOwnerName);
- line_editor->setCallbackUserData(this);
+ line_editor->setCommitCallback(onGetByOwnerName, this);
}
line_editor = getChild<LLLineEditor>("object_name_editor");
if (line_editor)
{
line_editor->setCommitOnFocusLost(FALSE);
- line_editor->setCommitCallback(onGetByObjectName);
- line_editor->setCallbackUserData(this);
+ line_editor->setCommitCallback(onGetByObjectName, this);
}*/
mCurrentMode = STAT_REPORT_TOP_SCRIPTS;
@@ -132,19 +124,29 @@ BOOL LLFloaterTopObjects::postBuild()
return TRUE;
}
+// static
+void LLFloaterTopObjects::setMode(U32 mode)
+{
+ LLFloaterTopObjects* instance = LLFloaterReg::getTypedInstance<LLFloaterTopObjects>("top_objects");
+ if(!instance) return;
+ instance->mCurrentMode = mode;
+}
+// static
void LLFloaterTopObjects::handle_land_reply(LLMessageSystem* msg, void** data)
{
+ LLFloaterTopObjects* instance = LLFloaterReg::getTypedInstance<LLFloaterTopObjects>("top_objects");
+ if(!instance) return;
// Make sure dialog is on screen
- show();
- sInstance->handleReply(msg, data);
+ LLFloaterReg::showInstance("top_objects");
+ instance->handleReply(msg, data);
//HACK: for some reason sometimes top scripts originally comes back
//with no results even though they're there
- if (!sInstance->mObjectListIDs.size() && !sInstance->mInitialized)
+ if (!instance->mObjectListIDs.size() && !instance->mInitialized)
{
- sInstance->onRefresh(NULL);
- sInstance->mInitialized = TRUE;
+ instance->onRefresh();
+ instance->mInitialized = TRUE;
}
}
@@ -234,7 +236,7 @@ void LLFloaterTopObjects::handleReply(LLMessageSystem *msg, void** data)
if (total_count == 0 && list->getItemCount() == 0)
{
- list->addCommentText(getString("none_descriptor"));
+ list->setCommentText(getString("none_descriptor"));
}
else
{
@@ -263,12 +265,9 @@ void LLFloaterTopObjects::handleReply(LLMessageSystem *msg, void** data)
}
}
-// static
-void LLFloaterTopObjects::onCommitObjectsList(LLUICtrl* ctrl, void* data)
+void LLFloaterTopObjects::onCommitObjectsList()
{
- LLFloaterTopObjects* self = (LLFloaterTopObjects*)data;
-
- self->updateSelectionInfo();
+ updateSelectionInfo();
}
void LLFloaterTopObjects::updateSelectionInfo()
@@ -295,11 +294,9 @@ void LLFloaterTopObjects::onDoubleClickObjectsList(void* data)
}
// static
-void LLFloaterTopObjects::onClickShowBeacon(void* data)
+void LLFloaterTopObjects::onClickShowBeacon()
{
- LLFloaterTopObjects* self = (LLFloaterTopObjects*)data;
- if (!self) return;
- self->showBeacon();
+ showBeacon();
}
void LLFloaterTopObjects::doToObjects(int action, bool all)
@@ -363,22 +360,24 @@ void LLFloaterTopObjects::doToObjects(int action, bool all)
bool LLFloaterTopObjects::callbackReturnAll(const LLSD& notification, const LLSD& response)
{
S32 option = LLNotification::getSelectedOption(notification, response);
+ LLFloaterTopObjects* instance = LLFloaterReg::getTypedInstance<LLFloaterTopObjects>("top_objects");
+ if(!instance) return false;
if (option == 0)
{
- sInstance->doToObjects(ACTION_RETURN, true);
+ instance->doToObjects(ACTION_RETURN, true);
}
return false;
}
-void LLFloaterTopObjects::onReturnAll(void* data)
+void LLFloaterTopObjects::onReturnAll()
{
LLNotifications::instance().add("ReturnAllTopObjects", LLSD(), LLSD(), &callbackReturnAll);
}
-void LLFloaterTopObjects::onReturnSelected(void* data)
+void LLFloaterTopObjects::onReturnSelected()
{
- sInstance->doToObjects(ACTION_RETURN, false);
+ doToObjects(ACTION_RETURN, false);
}
@@ -386,52 +385,52 @@ void LLFloaterTopObjects::onReturnSelected(void* data)
bool LLFloaterTopObjects::callbackDisableAll(const LLSD& notification, const LLSD& response)
{
S32 option = LLNotification::getSelectedOption(notification, response);
+ LLFloaterTopObjects* instance = LLFloaterReg::getTypedInstance<LLFloaterTopObjects>("top_objects");
+ if(!instance) return false;
if (option == 0)
{
- sInstance->doToObjects(ACTION_DISABLE, true);
+ instance->doToObjects(ACTION_DISABLE, true);
}
return false;
}
-void LLFloaterTopObjects::onDisableAll(void* data)
+void LLFloaterTopObjects::onDisableAll()
{
LLNotifications::instance().add("DisableAllTopObjects", LLSD(), LLSD(), callbackDisableAll);
}
-void LLFloaterTopObjects::onDisableSelected(void* data)
+void LLFloaterTopObjects::onDisableSelected()
{
- sInstance->doToObjects(ACTION_DISABLE, false);
+ doToObjects(ACTION_DISABLE, false);
}
-//static
+
void LLFloaterTopObjects::clearList()
{
- LLCtrlListInterface *list = sInstance->childGetListInterface("objects_list");
+ LLCtrlListInterface *list = childGetListInterface("objects_list");
if (list)
{
list->operateOnAll(LLCtrlListInterface::OP_DELETE);
}
- sInstance->mObjectListData.clear();
- sInstance->mObjectListIDs.clear();
- sInstance->mtotalScore = 0.f;
+ mObjectListData.clear();
+ mObjectListIDs.clear();
+ mtotalScore = 0.f;
}
-//static
-void LLFloaterTopObjects::onRefresh(void* data)
+
+void LLFloaterTopObjects::onRefresh()
{
U32 mode = STAT_REPORT_TOP_SCRIPTS;
U32 flags = 0;
std::string filter = "";
- if (sInstance)
- {
- mode = sInstance->mCurrentMode;
- flags = sInstance->mFlags;
- filter = sInstance->mFilter;
- sInstance->clearList();
- }
+ mode = mCurrentMode;
+ flags = mFlags;
+ filter = mFilter;
+ clearList();
+
LLMessageSystem *msg = gMessageSystem;
msg->newMessageFast(_PREHASH_LandStatRequest);
@@ -446,31 +445,22 @@ void LLFloaterTopObjects::onRefresh(void* data)
msg->sendReliable(gAgent.getRegionHost());
- if (sInstance)
- {
- sInstance->mFilter.clear();
- sInstance->mFlags = 0;
- }
+ mFilter.clear();
+ mFlags = 0;
}
-void LLFloaterTopObjects::onGetByObjectName(LLUICtrl* ctrl, void* data)
+void LLFloaterTopObjects::onGetByObjectName()
{
- if (sInstance)
- {
- sInstance->mFlags = STAT_FILTER_BY_OBJECT;
- sInstance->mFilter = sInstance->childGetText("object_name_editor");
- onRefresh(NULL);
- }
+ mFlags = STAT_FILTER_BY_OBJECT;
+ mFilter = childGetText("object_name_editor");
+ onRefresh();
}
-void LLFloaterTopObjects::onGetByOwnerName(LLUICtrl* ctrl, void* data)
+void LLFloaterTopObjects::onGetByOwnerName()
{
- if (sInstance)
- {
- sInstance->mFlags = STAT_FILTER_BY_OWNER;
- sInstance->mFilter = sInstance->childGetText("owner_name_editor");
- onRefresh(NULL);
- }
+ mFlags = STAT_FILTER_BY_OWNER;
+ mFilter = childGetText("owner_name_editor");
+ onRefresh();
}
void LLFloaterTopObjects::showBeacon()
diff --git a/indra/newview/llfloatertopobjects.h b/indra/newview/llfloatertopobjects.h
index 58cbf5d2ce..ee3c5d3cce 100644
--- a/indra/newview/llfloatertopobjects.h
+++ b/indra/newview/llfloatertopobjects.h
@@ -39,48 +39,49 @@ class LLUICtrl;
class LLFloaterTopObjects : public LLFloater
{
+ friend class LLFloaterReg;
public:
// Opens the floater on screen.
- static void show();
+// static void show();
// Opens the floater if it's not on-screen.
// Juggles the UI based on method = "scripts" or "colliders"
static void handle_land_reply(LLMessageSystem* msg, void** data);
void handleReply(LLMessageSystem* msg, void** data);
- static void clearList();
+ void clearList();
void updateSelectionInfo();
virtual BOOL postBuild();
- static void onRefresh(void* data);
+ void onRefresh();
- static void setMode(U32 mode) { if (sInstance) sInstance->mCurrentMode = mode; }
+ static void setMode(U32 mode);
private:
- LLFloaterTopObjects();
+ LLFloaterTopObjects(const LLSD& key);
~LLFloaterTopObjects();
void initColumns(LLCtrlListInterface *list);
- static void onCommitObjectsList(LLUICtrl* ctrl, void* data);
+ void onCommitObjectsList();
static void onDoubleClickObjectsList(void* data);
- static void onClickShowBeacon(void* data);
+ void onClickShowBeacon();
void doToObjects(int action, bool all);
- static void onReturnAll(void* data);
- static void onReturnSelected(void* data);
- static void onDisableAll(void* data);
- static void onDisableSelected(void* data);
+ void onReturnAll();
+ void onReturnSelected();
+ void onDisableAll();
+ void onDisableSelected();
static bool callbackReturnAll(const LLSD& notification, const LLSD& response);
static bool callbackDisableAll(const LLSD& notification, const LLSD& response);
- static void onGetByOwnerName(LLUICtrl* ctrl, void* data);
- static void onGetByObjectName(LLUICtrl* ctrl, void* data);
+ void onGetByOwnerName();
+ void onGetByObjectName();
- static void onGetByOwnerNameClicked(void* data) { onGetByOwnerName(NULL, data); };
- static void onGetByObjectNameClicked(void* data) { onGetByObjectName(NULL, data); };
+// static void onGetByOwnerNameClicked(void* data) { onGetByOwnerName(NULL, data); };
+// static void onGetByObjectNameClicked(void* data) { onGetByObjectName(NULL, data); };
void showBeacon();
diff --git a/indra/newview/llfloatertos.cpp b/indra/newview/llfloatertos.cpp
index 6a392e03fb..1c3443ae80 100644
--- a/indra/newview/llfloatertos.cpp
+++ b/indra/newview/llfloatertos.cpp
@@ -35,11 +35,9 @@
#include "llfloatertos.h"
// viewer includes
-#include "llagent.h"
#include "llappviewer.h"
#include "llstartup.h"
#include "llviewerstats.h"
-#include "llviewertexteditor.h"
#include "llviewerwindow.h"
// linden library includes
@@ -54,34 +52,9 @@
#include "message.h"
-// static
-LLFloaterTOS* LLFloaterTOS::sInstance = NULL;
-
-// static
-LLFloaterTOS* LLFloaterTOS::show(ETOSType type, const std::string & message)
-{
- if( !LLFloaterTOS::sInstance )
- {
- LLFloaterTOS::sInstance = new LLFloaterTOS(type, message);
- }
-
- if (type == TOS_TOS)
- {
- LLUICtrlFactory::getInstance()->buildFloater(LLFloaterTOS::sInstance, "floater_tos.xml");
- }
- else
- {
- LLUICtrlFactory::getInstance()->buildFloater(LLFloaterTOS::sInstance, "floater_critical.xml");
- }
-
- return LLFloaterTOS::sInstance;
-}
-
-
-LLFloaterTOS::LLFloaterTOS(ETOSType type, const std::string & message)
-: LLModalDialog( std::string(" "), 100, 100 ),
- mType(type),
- mMessage(message),
+LLFloaterTOS::LLFloaterTOS(const LLSD& message)
+: LLModalDialog( message ),
+ mMessage(message.asString()),
mWebBrowserWindowId( 0 ),
mLoadCompleteCount( 0 )
{
@@ -139,16 +112,14 @@ BOOL LLFloaterTOS::postBuild()
childSetAction("Continue", onContinue, this);
childSetAction("Cancel", onCancel, this);
childSetCommitCallback("agree_chk", updateAgree, this);
-
- if ( mType != TOS_TOS )
+
+ if (hasChild("tos_text"))
{
// this displays the critical message
- LLTextEditor *editor = getChild<LLTextEditor>("tos_text");
- editor->setHandleEditKeysDirectly( TRUE );
- editor->setEnabled( FALSE );
- editor->setWordWrap(TRUE);
- editor->setFocus(TRUE);
- editor->setValue(LLSD(mMessage));
+ LLUICtrl *tos_text = getChild<LLUICtrl>("tos_text");
+ tos_text->setEnabled( FALSE );
+ tos_text->setFocus(TRUE);
+ tos_text->setValue(LLSD(mMessage));
return TRUE;
}
@@ -158,15 +129,13 @@ BOOL LLFloaterTOS::postBuild()
tos_agreement->setEnabled( false );
// hide the SL text widget if we're displaying TOS with using a browser widget.
- LLTextEditor *editor = getChild<LLTextEditor>("tos_text");
+ LLUICtrl *editor = getChild<LLUICtrl>("tos_text");
editor->setVisible( FALSE );
- LLWebBrowserCtrl* web_browser = getChild<LLWebBrowserCtrl>("tos_html");
+ LLMediaCtrl* web_browser = getChild<LLMediaCtrl>("tos_html");
if ( web_browser )
{
- // start to observe it so we see navigate complete events
- web_browser->addObserver( this );
-
+ web_browser->addObserver(this);
gResponsePtr = LLIamHere::build( this );
LLHTTPClient::get( getString( "real_url" ), gResponsePtr );
}
@@ -177,17 +146,14 @@ BOOL LLFloaterTOS::postBuild()
void LLFloaterTOS::setSiteIsAlive( bool alive )
{
// only do this for TOS pages
- if ( mType == TOS_TOS )
+ if (hasChild("tos_html"))
{
- LLWebBrowserCtrl* web_browser = getChild<LLWebBrowserCtrl>("tos_html");
+ LLMediaCtrl* web_browser = getChild<LLMediaCtrl>("tos_html");
// if the contents of the site was retrieved
if ( alive )
{
- if ( web_browser )
- {
- // navigate to the "real" page
- web_browser->navigateTo( getString( "real_url" ) );
- };
+ // navigate to the "real" page
+ web_browser->navigateTo( getString( "real_url" ) );
}
else
{
@@ -195,24 +161,16 @@ void LLFloaterTOS::setSiteIsAlive( bool alive )
// but if the page is unavailable, we need to do this now
LLCheckBoxCtrl* tos_agreement = getChild<LLCheckBoxCtrl>("agree_chk");
tos_agreement->setEnabled( true );
- };
- };
+ }
+ }
}
LLFloaterTOS::~LLFloaterTOS()
{
- // stop obsaerving events
- LLWebBrowserCtrl* web_browser = getChild<LLWebBrowserCtrl>("tos_html");
- if ( web_browser )
- {
- web_browser->remObserver( this );
- };
// tell the responder we're not here anymore
if ( gResponsePtr )
gResponsePtr->setParent( 0 );
-
- LLFloaterTOS::sInstance = NULL;
}
// virtual
@@ -235,7 +193,7 @@ void LLFloaterTOS::onContinue( void* userdata )
{
LLFloaterTOS* self = (LLFloaterTOS*) userdata;
llinfos << "User agrees with TOS." << llendl;
- if (self->mType == TOS_TOS)
+ if (self->getInstanceName() == "message_tos")
{
gAcceptTOS = TRUE;
}
@@ -254,7 +212,7 @@ void LLFloaterTOS::onContinue( void* userdata )
#endif
LLStartUp::setStartupState( STATE_LOGIN_AUTH_INIT ); // Go back and finish authentication
- self->close(); // destroys this object
+ self->closeFloater(); // destroys this object
}
// static
@@ -265,18 +223,21 @@ void LLFloaterTOS::onCancel( void* userdata )
LLNotifications::instance().add("MustAgreeToLogIn", LLSD(), LLSD(), login_alert_done);
LLStartUp::setStartupState( STATE_LOGIN_SHOW );
self->mLoadCompleteCount = 0; // reset counter for next time we come to TOS
- self->close(); // destroys this object
+ self->closeFloater(); // destroys this object
}
//virtual
-void LLFloaterTOS::onNavigateComplete( const EventType& eventIn )
+void LLFloaterTOS::handleMediaEvent(LLPluginClassMedia* /*self*/, EMediaEvent event)
{
- // skip past the loading screen navigate complete
- if ( ++mLoadCompleteCount == 2 )
+ if(event == MEDIA_EVENT_NAVIGATE_COMPLETE)
{
- llinfos << "NAVIGATE COMPLETE" << llendl;
- // enable Agree to TOS radio button now that page has loaded
- LLCheckBoxCtrl * tos_agreement = getChild<LLCheckBoxCtrl>("agree_chk");
- tos_agreement->setEnabled( true );
- };
+ // skip past the loading screen navigate complete
+ if ( ++mLoadCompleteCount == 2 )
+ {
+ llinfos << "NAVIGATE COMPLETE" << llendl;
+ // enable Agree to TOS radio button now that page has loaded
+ LLCheckBoxCtrl * tos_agreement = getChild<LLCheckBoxCtrl>("agree_chk");
+ tos_agreement->setEnabled( true );
+ }
+ }
}
diff --git a/indra/newview/llfloatertos.h b/indra/newview/llfloatertos.h
index dbec3ff8b6..49f982aa80 100644
--- a/indra/newview/llfloatertos.h
+++ b/indra/newview/llfloatertos.h
@@ -35,7 +35,7 @@
#include "llmodaldialog.h"
#include "llassetstorage.h"
-#include "llwebbrowserctrl.h"
+#include "llmediactrl.h"
class LLButton;
class LLRadioGroup;
@@ -45,21 +45,12 @@ class LLUUID;
class LLFloaterTOS :
public LLModalDialog,
- public LLWebBrowserCtrlObserver
+ public LLViewerMediaObserver
{
public:
+ LLFloaterTOS(const LLSD& message);
virtual ~LLFloaterTOS();
- // Types of dialog.
- enum ETOSType
- {
- TOS_TOS = 0,
- TOS_CRITICAL_MESSAGE = 1
- };
-
- // Asset_id is overwritten with LLUUID::null when agree is clicked.
- static LLFloaterTOS* show(ETOSType type, const std::string & message);
-
BOOL postBuild();
virtual void draw();
@@ -70,19 +61,13 @@ public:
void setSiteIsAlive( bool alive );
- virtual void onNavigateComplete( const EventType& eventIn );
+ // inherited from LLViewerMediaObserver
+ /*virtual*/ void handleMediaEvent(LLPluginClassMedia* self, EMediaEvent event);
private:
- // Asset_id is overwritten with LLUUID::null when agree is clicked.
- LLFloaterTOS(ETOSType type, const std::string & message);
-
-private:
- ETOSType mType;
std::string mMessage;
int mWebBrowserWindowId;
int mLoadCompleteCount;
-
- static LLFloaterTOS* sInstance;
};
#endif // LL_LLFLOATERTOS_H
diff --git a/indra/newview/llfloateruipreview.cpp b/indra/newview/llfloateruipreview.cpp
new file mode 100644
index 0000000000..2eb4e7580e
--- /dev/null
+++ b/indra/newview/llfloateruipreview.cpp
@@ -0,0 +1,1642 @@
+/**
+ * @file llfloateruipreview.cpp
+ * @brief Tool for previewing and editing floaters, plus localization tool integration
+ *
+ * $LicenseInfo:firstyear=2008&license=viewergpl$
+ *
+ * Copyright (c) 2008-2009, Linden Research, Inc.
+ *
+ * Second Life Viewer Source Code
+ * The source code in this file ("Source Code") is provided by Linden Lab
+ * to you under the terms of the GNU General Public License, version 2.0
+ * ("GPL"), unless you have obtained a separate licensing agreement
+ * ("Other License"), formally executed by you and Linden Lab. Terms of
+ * the GPL can be found in doc/GPL-license.txt in this distribution, or
+ * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
+ *
+ * There are special exceptions to the terms and conditions of the GPL as
+ * it is applied to this Source Code. View the full text of the exception
+ * in the file doc/FLOSS-exception.txt in this software distribution, or
+ * online at
+ * http://secondlifegrid.net/programs/open_source/licensing/flossexception
+ *
+ * By copying, modifying or distributing this software, you acknowledge
+ * that you have read and understood your obligations described above,
+ * and agree to abide by those obligations.
+ *
+ * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+ * COMPLETENESS OR PERFORMANCE.
+ * $/LicenseInfo$
+ */
+
+// Tool for previewing floaters and panels for localization and UI design purposes.
+// See: https://wiki.lindenlab.com/wiki/GUI_Preview_And_Localization_Tools
+// See: https://jira.lindenlab.com/browse/DEV-16869
+
+// *TODO: Translate error messgaes using notifications/alerts.xml
+
+#include "llviewerprecompiledheaders.h" // Precompiled headers
+
+#include "llfloateruipreview.h" // Own header
+
+// Internal utility
+#include "llrender.h"
+#include "llsdutil.h"
+#include "llxmltree.h"
+#include "llviewerwindow.h"
+#include "lllivefile.h"
+
+// XUI
+#include "lluictrlfactory.h"
+#include "llcombobox.h"
+#include "llresizebar.h"
+#include "llscrolllistitem.h"
+#include "llscrolllistctrl.h"
+#include "llfilepicker.h"
+#include "lldraghandle.h"
+#include "lllayoutstack.h"
+#include "llviewermenu.h"
+#include "llrngwriter.h"
+
+// Boost (for linux/unix command-line execv)
+#include <boost/tokenizer.hpp>
+#include <boost/shared_ptr.hpp>
+
+// External utility
+#include <string>
+
+#if LL_DARWIN
+#include <CoreFoundation/CFURL.h>
+#endif
+
+// Static initialization
+static const S32 PRIMARY_FLOATER = 1;
+static const S32 SECONDARY_FLOATER = 2;
+
+static LLDefaultChildRegistry::Register<LLOverlapPanel> register_overlap_panel("overlap_panel");
+
+static std::string get_xui_dir()
+{
+ std::string delim = gDirUtilp->getDirDelimiter();
+ return gDirUtilp->getSkinBaseDir() + delim + "default" + delim + "xui" + delim;
+}
+
+//----------------------------------------------------------------------------
+// Local class declarations
+// Reset object to ensure that when we change the current language setting for preview purposes,
+// it automatically is reset. Constructed on the stack at the start of the method; the reset
+// occurs as it falls out of scope at the end of the method. See llfloateruipreview.cpp for usage.
+class LLLocalizationResetForcer
+{
+public:
+ LLLocalizationResetForcer(LLFloaterUIPreview* floater, S32 ID);
+ virtual ~LLLocalizationResetForcer();
+
+private:
+ std::string mSavedLocalization; // the localization before we change it
+};
+
+// Implementation of live file
+// When a floater is being previewed, any saved changes to its corresponding
+// file cause the previewed floater to be reloaded
+class LLGUIPreviewLiveFile : public LLLiveFile
+{
+public:
+ LLGUIPreviewLiveFile(std::string path, std::string name, LLFloaterUIPreview* parent);
+ virtual ~LLGUIPreviewLiveFile();
+ LLFloaterUIPreview* mParent;
+ LLFadeEventTimer* mFadeTimer; // timer for fade-to-yellow-and-back effect to warn that file has been reloaded
+ BOOL mFirstFade; // setting this avoids showing the fade reload warning on first load
+ std::string mFileName;
+protected:
+ bool loadFile();
+};
+
+// Implementation of graphical fade in/out (on timer) for when XUI files are updated
+class LLFadeEventTimer : public LLEventTimer
+{
+public:
+ LLFadeEventTimer(F32 refresh, LLGUIPreviewLiveFile* parent);
+ BOOL tick();
+ LLGUIPreviewLiveFile* mParent;
+private:
+ BOOL mFadingOut; // fades in then out; this is toggled in between
+ LLColor4 mOriginalColor; // original color; color is reset to this after fade is coimplete
+};
+
+// Implementation of previewed floater
+// Used to override draw and mouse handler
+class LLPreviewedFloater : public LLFloater
+{
+public:
+ LLPreviewedFloater(LLFloaterUIPreview* floater)
+ : LLFloater(LLSD()),
+ mFloaterUIPreview(floater)
+ {
+ }
+ virtual void draw();
+ BOOL handleRightMouseDown(S32 x, S32 y, MASK mask);
+ BOOL selectElement(LLView* parent, int x, int y, int depth); // select element to display its overlappers
+
+ LLFloaterUIPreview* mFloaterUIPreview;
+};
+
+//----------------------------------------------------------------------------
+
+// Localization reset forcer -- ensures that when localization is temporarily changed for previewed floater, it is reset
+// Changes are made here
+LLLocalizationResetForcer::LLLocalizationResetForcer(LLFloaterUIPreview* floater, S32 ID)
+{
+ mSavedLocalization = LLUI::sSettingGroups["config"]->getString("Language"); // save current localization setting
+ LLUI::sSettingGroups["config"]->setString("Language", floater->getLocStr(ID));// hack language to be the one we want to preview floaters in
+ LLUI::setupPaths(); // forcibly reset XUI paths with this new language
+}
+
+// Actually reset in destructor
+// Changes are reversed here
+LLLocalizationResetForcer::~LLLocalizationResetForcer()
+{
+ LLUI::sSettingGroups["config"]->setString("Language", mSavedLocalization); // reset language to what it was before we changed it
+ LLUI::setupPaths(); // forcibly reset XUI paths with this new language
+}
+
+// Live file constructor
+// Needs full path for LLLiveFile but needs just file name for this code, hence the reduntant arguments; easier than separating later
+LLGUIPreviewLiveFile::LLGUIPreviewLiveFile(std::string path, std::string name, LLFloaterUIPreview* parent)
+ : mFileName(name),
+ mParent(parent),
+ mFirstFade(TRUE),
+ mFadeTimer(NULL),
+ LLLiveFile(path, 1.0)
+{}
+
+LLGUIPreviewLiveFile::~LLGUIPreviewLiveFile()
+{
+ mParent->mLiveFile = NULL;
+ if(mFadeTimer)
+ {
+ mFadeTimer->mParent = NULL;
+ // deletes itself; see lltimer.cpp
+ }
+}
+
+// Live file load
+bool LLGUIPreviewLiveFile::loadFile()
+{
+ mParent->displayFloater(FALSE,1); // redisplay the floater
+ if(mFirstFade) // only fade if it wasn't just clicked on; can't use "clicked" BOOL below because of an oddity with setting LLLiveFile initial state
+ {
+ mFirstFade = FALSE;
+ }
+ else
+ {
+ if(mFadeTimer)
+ {
+ mFadeTimer->mParent = NULL;
+ }
+ mFadeTimer = new LLFadeEventTimer(0.05f,this);
+ }
+ return true;
+}
+
+// Initialize fade event timer
+LLFadeEventTimer::LLFadeEventTimer(F32 refresh, LLGUIPreviewLiveFile* parent)
+ : mParent(parent),
+ mFadingOut(TRUE),
+ LLEventTimer(refresh)
+{
+ mOriginalColor = mParent->mParent->mDisplayedFloater->getBackgroundColor();
+}
+
+// Single tick of fade event timer: increment the color
+BOOL LLFadeEventTimer::tick()
+{
+ float diff = 0.04f;
+ if(TRUE == mFadingOut) // set fade for in/out color direction
+ {
+ diff = -diff;
+ }
+
+ if(NULL == mParent) // no more need to tick, so suicide
+ {
+ delete this;
+ return FALSE;
+ }
+
+ // Set up colors
+ LLColor4 bg_color = mParent->mParent->mDisplayedFloater->getBackgroundColor();
+ LLSD colors = bg_color.getValue();
+ LLSD colors_old = colors;
+
+ // Tick colors
+ colors[0] = colors[0].asReal() - diff; if(colors[0].asReal() < mOriginalColor.getValue()[0].asReal()) { colors[0] = colors_old[0]; }
+ colors[1] = colors[1].asReal() - diff; if(colors[1].asReal() < mOriginalColor.getValue()[1].asReal()) { colors[1] = colors_old[1]; }
+ colors[2] = colors[2].asReal() + diff; if(colors[2].asReal() > mOriginalColor.getValue()[2].asReal()) { colors[2] = colors_old[2]; }
+
+ // Clamp and set colors
+ bg_color.setValue(colors);
+ bg_color.clamp(); // make sure we didn't exceed [0,1]
+ mParent->mParent->mDisplayedFloater->setBackgroundColor(bg_color);
+
+ if(bg_color[2] <= 0.0f) // end of fade out, start fading in
+ {
+ mFadingOut = FALSE;
+ }
+
+ return FALSE;
+}
+
+// Constructor
+LLFloaterUIPreview::LLFloaterUIPreview(const LLSD& key)
+ : LLFloater(key),
+ mDisplayedFloater(NULL),
+ mDisplayedFloater_2(NULL),
+ mLiveFile(NULL),
+ // sHighlightingDiffs(FALSE),
+ mHighlightingOverlaps(FALSE),
+ mLastDisplayedX(0),
+ mLastDisplayedY(0)
+
+{
+ // called from floater reg: LLUICtrlFactory::getInstance()->buildFloater(this, "floater_ui_preview.xml");
+}
+
+// Destructor
+LLFloaterUIPreview::~LLFloaterUIPreview()
+{
+ // spawned floaters are deleted automatically, so we don't need to delete them here
+
+ // save contents of textfields so it can be restored later if the floater is created again this session
+ mSavedEditorPath = mEditorPathTextBox->getText();
+ mSavedEditorArgs = mEditorArgsTextBox->getText();
+ mSavedDiffPath = mDiffPathTextBox->getText();
+
+ // delete live file if it exists
+ if(mLiveFile)
+ {
+ delete mLiveFile;
+ mLiveFile = NULL;
+ }
+}
+
+// Perform post-build setup (defined in superclass)
+BOOL LLFloaterUIPreview::postBuild()
+{
+ mCloseSignal.connect(boost::bind(&LLFloaterUIPreview::onClose, this, _2));
+
+ LLPanel* main_panel_tmp = getChild<LLPanel>("main_panel"); // get a pointer to the main panel in order to...
+ mFileList = main_panel_tmp->getChild<LLScrollListCtrl>("name_list"); // save pointer to file list
+ // Double-click opens the floater, for convenience
+ mFileList->setDoubleClickCallback(boost::bind(&LLFloaterUIPreview::onClickDisplayFloater, this, PRIMARY_FLOATER));
+
+ // get pointers to buttons and link to callbacks
+ mLanguageSelection = main_panel_tmp->getChild<LLComboBox>("language_select_combo");
+ mLanguageSelection->setSelectionCallback(boost::bind(&LLFloaterUIPreview::onLanguageComboSelect, this, mLanguageSelection));
+ mLanguageSelection_2 = main_panel_tmp->getChild<LLComboBox>("language_select_combo_2");
+ mLanguageSelection_2->setSelectionCallback(boost::bind(&LLFloaterUIPreview::onLanguageComboSelect, this, mLanguageSelection));
+ LLPanel* editor_panel_tmp = main_panel_tmp->getChild<LLPanel>("editor_panel");
+ mDisplayFloaterBtn = main_panel_tmp->getChild<LLButton>("display_floater");
+ mDisplayFloaterBtn->setClickedCallback(boost::bind(&LLFloaterUIPreview::onClickDisplayFloater, this, PRIMARY_FLOATER));
+ mDisplayFloaterBtn_2 = main_panel_tmp->getChild<LLButton>("display_floater_2");
+ mDisplayFloaterBtn_2->setClickedCallback(boost::bind(&LLFloaterUIPreview::onClickDisplayFloater, this, SECONDARY_FLOATER));
+ mToggleOverlapButton = main_panel_tmp->getChild<LLButton>("toggle_overlap_panel");
+ mToggleOverlapButton->setClickedCallback(boost::bind(&LLFloaterUIPreview::onClickToggleOverlapping, this));
+ mCloseOtherButton = main_panel_tmp->getChild<LLButton>("close_displayed_floater");
+ mCloseOtherButton->setClickedCallback(boost::bind(&LLFloaterUIPreview::onClickCloseDisplayedFloater, this, PRIMARY_FLOATER));
+ mCloseOtherButton_2 = main_panel_tmp->getChild<LLButton>("close_displayed_floater_2");
+ mCloseOtherButton_2->setClickedCallback(boost::bind(&LLFloaterUIPreview::onClickCloseDisplayedFloater, this, SECONDARY_FLOATER));
+ mEditFloaterBtn = main_panel_tmp->getChild<LLButton>("edit_floater");
+ mEditFloaterBtn->setClickedCallback(boost::bind(&LLFloaterUIPreview::onClickEditFloater, this));
+ mExecutableBrowseButton = editor_panel_tmp->getChild<LLButton>("browse_for_executable");
+ LLPanel* vlt_panel_tmp = main_panel_tmp->getChild<LLPanel>("vlt_panel");
+ mExecutableBrowseButton->setClickedCallback(boost::bind(&LLFloaterUIPreview::onClickBrowseForEditor, this));
+ mDiffBrowseButton = vlt_panel_tmp->getChild<LLButton>("browse_for_vlt_diffs");
+ mDiffBrowseButton->setClickedCallback(boost::bind(&LLFloaterUIPreview::onClickBrowseForDiffs, this));
+ mToggleHighlightButton = vlt_panel_tmp->getChild<LLButton>("toggle_vlt_diff_highlight");
+ mToggleHighlightButton->setClickedCallback(boost::bind(&LLFloaterUIPreview::onClickToggleDiffHighlighting, this));
+ main_panel_tmp->getChild<LLButton>("save_floater")->setClickedCallback(boost::bind(&LLFloaterUIPreview::onClickSaveFloater, this, PRIMARY_FLOATER));
+ main_panel_tmp->getChild<LLButton>("save_all_floaters")->setClickedCallback(boost::bind(&LLFloaterUIPreview::onClickSaveAll, this, PRIMARY_FLOATER));
+
+ getChild<LLButton>("export_schema")->setClickedCallback(boost::bind(&LLFloaterUIPreview::onClickExportSchema, this));
+
+ // get pointers to text fields
+ mEditorPathTextBox = editor_panel_tmp->getChild<LLLineEditor>("executable_path_field");
+ mEditorArgsTextBox = editor_panel_tmp->getChild<LLLineEditor>("executable_args_field");
+ mDiffPathTextBox = vlt_panel_tmp->getChild<LLLineEditor>("vlt_diff_path_field");
+
+ // *HACK: restored saved editor path and args to textfields
+ mEditorPathTextBox->setText(mSavedEditorPath);
+ mEditorArgsTextBox->setText(mSavedEditorArgs);
+ mDiffPathTextBox->setText(mSavedDiffPath);
+
+ // Set up overlap panel
+ mOverlapPanel = getChild<LLOverlapPanel>("overlap_panel");
+
+ childSetVisible("overlap_scroll", mHighlightingOverlaps);
+
+ mDelim = gDirUtilp->getDirDelimiter(); // initialize delimiter to dir sep slash
+
+ // refresh list of available languages (EN will still be default)
+ BOOL found = TRUE;
+ BOOL found_en_us = FALSE;
+ std::string language_directory;
+ std::string xui_dir = get_xui_dir(); // directory containing localizations -- don't forget trailing delim
+ mLanguageSelection->removeall(); // clear out anything temporarily in list from XML
+ while(found) // for every directory
+ {
+ if((found = gDirUtilp->getNextFileInDir(xui_dir, "*", language_directory, FALSE))) // get next directory
+ {
+ std::string full_path = xui_dir + language_directory;
+ if(LLFile::isfile(full_path.c_str())) // if it's not a directory, skip it
+ {
+ continue;
+ }
+
+ if(strncmp("template",language_directory.c_str(),8) && -1 == language_directory.find(".")) // if it's not the template directory or a hidden directory
+ {
+ if(!strncmp("en",language_directory.c_str(),5)) // remember if we've seen en, so we can make it default
+ {
+ found_en_us = TRUE;
+ }
+ else
+ {
+ mLanguageSelection->add(std::string(language_directory)); // add it to the language selection dropdown menu
+ mLanguageSelection_2->add(std::string(language_directory));
+ }
+ }
+ }
+ }
+ if(found_en_us)
+ {
+ mLanguageSelection->add(std::string("en"),ADD_TOP); // make en first item if we found it
+ mLanguageSelection_2->add(std::string("en"),ADD_TOP);
+ }
+ else
+ {
+ std::string warning = std::string("No EN localization found; check your XUI directories!");
+ popupAndPrintWarning(warning);
+ }
+ mLanguageSelection->selectFirstItem(); // select the first item
+ mLanguageSelection_2->selectFirstItem();
+
+ refreshList(); // refresh the list of available floaters
+
+ return TRUE;
+}
+
+// Callback for language combo box selection: refresh current floater when you change languages
+void LLFloaterUIPreview::onLanguageComboSelect(LLUICtrl* ctrl)
+{
+ LLComboBox* caller = dynamic_cast<LLComboBox*>(ctrl);
+ if (!caller)
+ return;
+ if(caller->getName() == std::string("language_select_combo"))
+ {
+ if(mDisplayedFloater)
+ {
+ onClickCloseDisplayedFloater(PRIMARY_FLOATER);
+ displayFloater(TRUE,1);
+ }
+ }
+ else
+ {
+ if(mDisplayedFloater_2)
+ {
+ onClickCloseDisplayedFloater(PRIMARY_FLOATER);
+ displayFloater(TRUE,2); // *TODO: make take an arg
+ }
+ }
+
+}
+
+void LLFloaterUIPreview::onClickExportSchema()
+{
+ gViewerWindow->setCursor(UI_CURSOR_WAIT);
+ std::string template_path = gDirUtilp->getExpandedFilename(LL_PATH_DEFAULT_SKIN, "xui", "schema");
+
+ typedef LLWidgetTypeRegistry::Registrar::registry_map_t::const_iterator registry_it;
+ registry_it end_it = LLWidgetTypeRegistry::defaultRegistrar().endItems();
+ for(registry_it it = LLWidgetTypeRegistry::defaultRegistrar().beginItems();
+ it != end_it;
+ ++it)
+ {
+ std::string widget_name = it->first;
+ const LLInitParam::BaseBlock& block =
+ (*LLDefaultParamBlockRegistry::instance().getValue(*LLWidgetTypeRegistry::instance().getValue(widget_name)))();
+ LLXMLNodePtr root_nodep = new LLXMLNode();
+ LLRNGWriter().writeRNG(widget_name, root_nodep, block, "http://www.lindenlab.com/xui");
+
+ std::string file_name(template_path + gDirUtilp->getDirDelimiter() + widget_name + ".rng");
+
+ LLFILE* rng_file = LLFile::fopen(file_name.c_str(), "w");
+ {
+ LLXMLNode::writeHeaderToFile(rng_file);
+ const bool use_type_decorations = false;
+ root_nodep->writeToFile(rng_file, std::string(), use_type_decorations);
+ }
+ fclose(rng_file);
+ }
+ gViewerWindow->setCursor(UI_CURSOR_ARROW);
+}
+
+
+// Close click handler -- delete my displayed floater if it exists
+void LLFloaterUIPreview::onClose(const LLSD& app_quitting)
+{
+ if(!app_quitting.asBoolean() && mDisplayedFloater)
+ {
+ onClickCloseDisplayedFloater(PRIMARY_FLOATER);
+ onClickCloseDisplayedFloater(SECONDARY_FLOATER);
+ delete mDisplayedFloater;
+ mDisplayedFloater = NULL;
+ delete mDisplayedFloater_2;
+ mDisplayedFloater_2 = NULL;
+ }
+}
+
+// Error handling (to avoid code repetition)
+// *TODO: this is currently unlocalized. Add to alerts/notifications.xml, someday, maybe.
+void LLFloaterUIPreview::popupAndPrintWarning(std::string& warning)
+{
+ llwarns << warning << llendl;
+ LLSD args;
+ args["MESSAGE"] = warning;
+ LLNotifications::instance().add("GenericAlert", args);
+}
+
+// Get localization string from drop-down menu
+std::string LLFloaterUIPreview::getLocStr(S32 ID)
+{
+ if(ID == 1)
+ {
+ return mLanguageSelection->getSelectedItemLabel(0);
+ }
+ else
+ {
+ return mLanguageSelection_2->getSelectedItemLabel(0);
+ }
+}
+
+// Get localized directory (build path from data directory to XUI files, substituting localization string in for language)
+std::string LLFloaterUIPreview::getLocalizedDirectory()
+{
+ return get_xui_dir() + (getLocStr(1)) + mDelim; // e.g. "C:/Code/guipreview/indra/newview/skins/xui/en/";
+}
+
+// Refresh the list of floaters by doing a directory traverse for XML XUI floater files
+// Could be used to grab any specific language's list of compatible floaters, but currently it's just used to get all of them
+void LLFloaterUIPreview::refreshList()
+{
+ // Note: the mask doesn't seem to accept regular expressions, so there need to be two directory searches here
+ mFileList->clearRows(); // empty list
+ std::string name;
+ BOOL found = TRUE;
+ while(found) // for every floater file that matches the pattern
+ {
+ if((found = gDirUtilp->getNextFileInDir(getLocalizedDirectory(), "floater_*.xml", name, FALSE))) // get next file matching pattern
+ {
+ addFloaterEntry(name.c_str()); // and add it to the list (file name only; localization code takes care of rest of path)
+ }
+ }
+ found = TRUE;
+ while(found) // for every menu file that matches the pattern
+ {
+ if((found = gDirUtilp->getNextFileInDir(getLocalizedDirectory(), "menu_*.xml", name, FALSE))) // get next file matching pattern
+ {
+ addFloaterEntry(name.c_str()); // and add it to the list (file name only; localization code takes care of rest of path)
+ }
+ }
+ found = TRUE;
+ while(found) // for every panel file that matches the pattern
+ {
+ if((found = gDirUtilp->getNextFileInDir(getLocalizedDirectory(), "panel_*.xml", name, FALSE))) // get next file matching pattern
+ {
+ addFloaterEntry(name.c_str()); // and add it to the list (file name only; localization code takes care of rest of path)
+ }
+ }
+
+ if(!mFileList->isEmpty()) // if there were any matching files, just select the first one (so we don't have to worry about disabling buttons when no entry is selected)
+ {
+ mFileList->selectFirstItem();
+ }
+}
+
+// Add a single entry to the list of available floaters
+// Note: no deduplification (shouldn't be necessary)
+void LLFloaterUIPreview::addFloaterEntry(const std::string& path)
+{
+ LLUUID* entry_id = new LLUUID(); // create a new UUID
+ entry_id->generate(path);
+ const LLUUID& entry_id_ref = *entry_id; // get a reference to the UUID for the LLSD block
+
+ // fill LLSD column entry: initialize row/col structure
+ LLSD row;
+ row["id"] = entry_id_ref;
+ LLSD& columns = row["columns"];
+
+ // Get name of floater:
+ LLXmlTree xml_tree;
+ std::string full_path = getLocalizedDirectory() + path; // get full path
+ BOOL success = xml_tree.parseFile(full_path.c_str(), TRUE); // parse xml
+ std::string entry_name;
+ std::string entry_title;
+ if(success)
+ {
+ // get root (or error handle)
+ LLXmlTreeNode* root_floater = xml_tree.getRoot();
+ if (!root_floater)
+ {
+ std::string warning = std::string("No root node found in XUI file: ") + path;
+ popupAndPrintWarning(warning);
+ return;
+ }
+
+ // get name
+ root_floater->getAttributeString("name",entry_name);
+ if(std::string("") == entry_name)
+ {
+ entry_name = "Error: unable to load " + std::string(path); // set to error state if load fails
+ }
+
+ // get title
+ root_floater->getAttributeString("title",entry_title); // some don't have a title, and some have title = "(unknown)", so just leave it blank if it fails
+ }
+ else
+ {
+ std::string warning = std::string("Unable to parse XUI file: ") + path; // error handling
+ popupAndPrintWarning(warning);
+ if(mLiveFile)
+ {
+ delete mLiveFile;
+ mLiveFile = NULL;
+ }
+ return;
+ }
+
+ // Fill floater title column
+ columns[0]["column"] = "title_column";
+ columns[0]["type"] = "text";
+ columns[0]["value"] = entry_title;
+
+ // Fill floater path column
+ columns[1]["column"] = "file_column";
+ columns[1]["type"] = "text";
+ columns[1]["value"] = std::string(path);
+
+ // Fill floater name column
+ columns[2]["column"] = "top_level_node_column";
+ columns[2]["type"] = "text";
+ columns[2]["value"] = entry_name;
+
+ mFileList->addElement(row); // actually add to list
+}
+
+// Respond to button click to display/refresh currently-selected floater
+void LLFloaterUIPreview::onClickDisplayFloater(S32 caller_id)
+{
+ displayFloater(TRUE, caller_id);
+ if(caller_id == PRIMARY_FLOATER)
+ {
+ mDisplayedFloater->center(); // move displayed floater to the center of the screen
+ }
+}
+
+// Saves the current floater/panel
+void LLFloaterUIPreview::onClickSaveFloater(S32 caller_id)
+{
+ displayFloater(TRUE, caller_id, true);
+ if(caller_id == PRIMARY_FLOATER)
+ {
+ mDisplayedFloater->center(); // move displayed floater to the center of the screen
+ }
+}
+
+// Saves all floater/panels
+void LLFloaterUIPreview::onClickSaveAll(S32 caller_id)
+{
+ int listSize = mFileList->getItemCount();
+
+ for (int index = 0; index < listSize; index++)
+ {
+ mFileList->selectNthItem(index);
+ displayFloater(TRUE, caller_id, true);
+ }
+}
+
+// Given path to floater or panel XML file "filename.xml",
+// returns "filename_new.xml"
+static std::string append_new_to_xml_filename(const std::string& path)
+{
+ std::string full_filename = gDirUtilp->findSkinnedFilename(LLUI::getLocalizedSkinPath(), path);
+ std::string::size_type extension_pos = full_filename.rfind(".xml");
+ full_filename.resize(extension_pos);
+ full_filename += "_new.xml";
+ return full_filename;
+}
+
+// Actually display the floater
+// Only set up a new live file if this came from a click (at which point there should be no existing live file), rather than from the live file's update itself;
+// otherwise, we get an infinite loop as the live file keeps recreating itself. That means this function is generally called twice.
+void LLFloaterUIPreview::displayFloater(BOOL click, S32 ID, bool save)
+{
+ // Convince UI that we're in a different language (the one selected on the drop-down menu)
+ LLLocalizationResetForcer reset_forcer(this, ID); // save old language in reset forcer object (to be reset upon destruction when it falls out of scope)
+
+ LLPreviewedFloater** floaterp = (ID == 1 ? &(mDisplayedFloater) : &(mDisplayedFloater_2));
+ if(ID == 1)
+ {
+ BOOL floater_already_open = mDisplayedFloater != NULL;
+ if(floater_already_open) // if we are already displaying a floater
+ {
+ mLastDisplayedX = mDisplayedFloater->calcScreenRect().mLeft; // save floater's last known position to put the new one there
+ mLastDisplayedY = mDisplayedFloater->calcScreenRect().mBottom;
+ delete mDisplayedFloater; // delete it (this closes it too)
+ mDisplayedFloater = NULL; // and reset the pointer
+ }
+ }
+ else
+ {
+ if(mDisplayedFloater_2 != NULL)
+ {
+ delete mDisplayedFloater_2;
+ mDisplayedFloater_2 = NULL;
+ }
+ }
+
+ std::string path = mFileList->getSelectedItemLabel(1); // get the path of the currently-selected floater
+ if(std::string("") == path) // if no item is selected
+ {
+ return; // ignore click (this can only happen with empty list; otherwise an item is always selected)
+ }
+
+ *floaterp = new LLPreviewedFloater(this);
+
+ if(!strncmp(path.c_str(),"floater_",8)) // if it's a floater
+ {
+ if (save)
+ {
+ LLXMLNodePtr floater_write = new LLXMLNode();
+ LLUICtrlFactory::getInstance()->buildFloater(*floaterp, path, floater_write); // just build it
+
+ if (!floater_write->isNull())
+ {
+ std::string full_filename = append_new_to_xml_filename(path);
+ LLFILE* floater_temp = LLFile::fopen(full_filename.c_str(), "w");
+ LLXMLNode::writeHeaderToFile(floater_temp);
+ const bool use_type_decorations = false;
+ floater_write->writeToFile(floater_temp, std::string(), use_type_decorations);
+ fclose(floater_temp);
+ }
+ }
+ else
+ {
+ LLUICtrlFactory::getInstance()->buildFloater(*floaterp, path, NULL); // just build it
+ (*floaterp)->openFloater((*floaterp)->getKey());
+ }
+
+ }
+ else if (!strncmp(path.c_str(),"menu_",5)) // if it's a menu
+ {
+ if (save)
+ {
+ LLXMLNodePtr menu_write = new LLXMLNode();
+ LLMenuGL* menu = LLUICtrlFactory::getInstance()->createFromFile<LLMenuGL>(path, gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance(), menu_write);
+
+ if (!menu_write->isNull())
+ {
+ std::string full_filename = append_new_to_xml_filename(path);
+ LLFILE* menu_temp = LLFile::fopen(full_filename.c_str(), "w");
+ LLXMLNode::writeHeaderToFile(menu_temp);
+ const bool use_type_decorations = false;
+ menu_write->writeToFile(menu_temp, std::string(), use_type_decorations);
+ fclose(menu_temp);
+ }
+
+ delete menu;
+ }
+ }
+ else // if it is a panel...
+ {
+ static LLUICachedControl<S32> floater_header_size ("UIFloaterHeaderSize", 0);
+
+ LLPanel::Params panel_params;
+ LLPanel* panel = LLUICtrlFactory::create<LLPanel>(panel_params); // create a new panel
+
+ if (save)
+ {
+ LLXMLNodePtr panel_write = new LLXMLNode();
+ LLUICtrlFactory::getInstance()->buildPanel(panel, path, panel_write); // build it
+
+ if (!panel_write->isNull())
+ {
+ std::string full_filename = append_new_to_xml_filename(path);
+ LLFILE* panel_temp = LLFile::fopen(full_filename.c_str(), "w");
+ LLXMLNode::writeHeaderToFile(panel_temp);
+ const bool use_type_decorations = false;
+ panel_write->writeToFile(panel_temp, std::string(), use_type_decorations);
+ fclose(panel_temp);
+ }
+ }
+ else
+ {
+ LLUICtrlFactory::getInstance()->buildPanel(panel, path); // build it
+ LLRect new_size = panel->getRect(); // get its rectangle
+ panel->setOrigin(0,0); // reset its origin point so it's not offset by -left or other XUI attributes
+ (*floaterp)->setTitle(path); // use the file name as its title, since panels have no guaranteed meaningful name attribute
+ panel->setUseBoundingRect(TRUE); // enable the use of its outer bounding rect (normally disabled because it's O(n) on the number of sub-elements)
+ panel->updateBoundingRect(); // update bounding rect
+ LLRect bounding_rect = panel->getBoundingRect(); // get the bounding rect
+ LLRect new_rect = panel->getRect(); // get the panel's rect
+ new_rect.unionWith(bounding_rect); // union them to make sure we get the biggest one possible
+ (*floaterp)->reshape(new_rect.getWidth(), new_rect.getHeight() + floater_header_size); // reshape floater to match the union rect's dimensions
+ panel->reshape(new_rect.getWidth(), new_rect.getHeight()); // reshape panel to match the union rect's dimensions as well (both are needed)
+ (*floaterp)->addChild(panel); // add panel as child
+ (*floaterp)->openFloater(); // open floater (needed?)
+ }
+ }
+
+ if(ID == 1)
+ {
+ (*floaterp)->setOrigin(mLastDisplayedX, mLastDisplayedY);
+ }
+
+ // *HACK: Remove ability to close it; if you close it, its destructor gets called, but we don't know it's null and try to delete it again,
+ // resulting in a double free
+ (*floaterp)->setCanClose(FALSE);
+
+ if(ID == 1)
+ {
+ mCloseOtherButton->setEnabled(TRUE); // enable my floater's close button
+ }
+ else
+ {
+ mCloseOtherButton_2->setEnabled(TRUE);
+ }
+
+ // *TODO: Make the secondary floater pop up next to the primary one. Doesn't seem to always work if secondary was up first...
+ if((mDisplayedFloater && ID == 2) || (mDisplayedFloater_2 && ID == 1))
+ {
+ mDisplayedFloater_2->setSnapTarget(mDisplayedFloater->getHandle());
+ mDisplayedFloater->addDependentFloater(mDisplayedFloater_2);
+ }
+
+ // Add localization to title so user knows whether it's localized or defaulted to en
+ std::string full_path = getLocalizedDirectory() + path;
+ std::string floater_lang = "EN";
+ llstat dummy;
+ if(!LLFile::stat(full_path.c_str(), &dummy)) // if the file does not exist
+ {
+ floater_lang = getLocStr(ID);
+ }
+ std::string new_title = (*floaterp)->getTitle() + std::string(" [") + floater_lang +
+ (ID == 1 ? " - Primary" : " - Secondary") + std::string("]");
+ (*floaterp)->setTitle(new_title);
+
+ if(click && ID == 1 && !save)
+ {
+ // set up live file to track it
+ if(mLiveFile)
+ {
+ delete mLiveFile;
+ mLiveFile = NULL;
+ }
+ mLiveFile = new LLGUIPreviewLiveFile(std::string(full_path.c_str()),std::string(path.c_str()),this);
+ mLiveFile->checkAndReload();
+ mLiveFile->addToEventTimer();
+ }
+
+ if(ID == 1)
+ {
+ mToggleOverlapButton->setEnabled(TRUE);
+ }
+
+ if(LLView::sHighlightingDiffs && click && ID == 1)
+ {
+ highlightChangedElements();
+ }
+
+ if(ID == 1)
+ {
+ mOverlapPanel->mOverlapMap.clear();
+ LLView::sPreviewClickedElement = NULL; // stop overlapping elements from drawing
+ mOverlapPanel->mLastClickedElement = NULL;
+ findOverlapsInChildren((LLView*)mDisplayedFloater);
+
+ // highlight and enable them
+ if(mHighlightingOverlaps)
+ {
+ for(LLOverlapPanel::OverlapMap::iterator iter = mOverlapPanel->mOverlapMap.begin(); iter != mOverlapPanel->mOverlapMap.end(); ++iter)
+ {
+ LLView* viewp = iter->first;
+ LLView::sPreviewHighlightedElements.insert(viewp);
+ }
+ }
+ else if(LLView::sHighlightingDiffs)
+ {
+ highlightChangedElements();
+ }
+ }
+
+ // NOTE: language is reset here automatically when the reset forcer object falls out of scope (see header for details)
+}
+
+// Respond to button click to edit currently-selected floater
+void LLFloaterUIPreview::onClickEditFloater()
+{
+ std::string file_name = mFileList->getSelectedItemLabel(1); // get the file name of the currently-selected floater
+ if(std::string("") == file_name) // if no item is selected
+ {
+ return; // ignore click
+ }
+ std::string path = getLocalizedDirectory() + file_name;
+
+ // stat file to see if it exists (some localized versions may not have it there are no diffs, and then we try to open an nonexistent file)
+ llstat dummy;
+ if(LLFile::stat(path.c_str(), &dummy)) // if the file does not exist
+ {
+ std::string warning = "No file for this floater exists in the selected localization. Opening the EN version instead.";
+ popupAndPrintWarning(warning);
+
+ path = get_xui_dir() + mDelim + "en" + mDelim + file_name; // open the en version instead, by default
+ }
+
+ // get executable path
+ const char* exe_path_char;
+ std::string path_in_textfield = mEditorPathTextBox->getText();
+ if(std::string("") != path_in_textfield) // if the text field is not emtpy, use its path
+ {
+ exe_path_char = path_in_textfield.c_str();
+ }
+ else if (!LLUI::sSettingGroups["config"]->getString("XUIEditor").empty())
+ {
+ exe_path_char = LLUI::sSettingGroups["config"]->getString("XUIEditor").c_str();
+ }
+ else // otherwise use the path specified by the environment variable
+ {
+ exe_path_char = getenv("LL_XUI_EDITOR");
+ }
+
+ // error check executable path
+ if(NULL == exe_path_char)
+ {
+ std::string warning = "Select an editor by setting the environment variable LL_XUI_EDITOR or specifying its path in the \"Editor Path\" field.";
+ popupAndPrintWarning(warning);
+ return;
+ }
+ std::string exe_path = exe_path_char; // do this after error check, otherwise internal strlen call fails on bad char*
+
+ // remove any quotes; they're added back in later where necessary
+ int found_at;
+ while((found_at = exe_path.find("\"")) != -1 || (found_at = exe_path.find("'")) != -1)
+ {
+ exe_path.erase(found_at,1);
+ }
+
+ llstat s;
+ if(!LLFile::stat(exe_path.c_str(), &s)) // If the executable exists
+ {
+ // build paths and arguments
+ std::string args;
+ std::string custom_args = mEditorArgsTextBox->getText();
+ int position_of_file = custom_args.find(std::string("%FILE%"), 0); // prepare to replace %FILE% with actual file path
+ std::string first_part_of_args = "";
+ std::string second_part_of_args = "";
+ if(-1 == position_of_file) // default: Executable.exe File.xml
+ {
+ args = std::string("\"") + path + std::string("\""); // execute the command Program.exe "File.xml"
+ }
+ else // use advanced command-line arguments, e.g. "Program.exe -safe File.xml" -windowed for "-safe %FILE% -windowed"
+ {
+ first_part_of_args = custom_args.substr(0,position_of_file); // get part of args before file name
+ second_part_of_args = custom_args.substr(position_of_file+6,custom_args.length()); // get part of args after file name
+ custom_args = first_part_of_args + std::string("\"") + path + std::string("\"") + second_part_of_args; // replace %FILE% with "<file path>" and put back together
+ args = custom_args; // and save in the variable that is actually used
+ }
+
+ // find directory in which executable resides by taking everything after last slash
+ int last_slash_position = exe_path.find_last_of(mDelim);
+ if(-1 == last_slash_position)
+ {
+ std::string warning = std::string("Unable to find a valid path to the specified executable for XUI XML editing: ") + exe_path;
+ popupAndPrintWarning(warning);
+ return;
+ }
+ std::string exe_dir = exe_path.substr(0,last_slash_position); // strip executable off, e.g. get "C:\Program Files\TextPad 5" (with or without trailing slash)
+
+#if LL_WINDOWS
+ PROCESS_INFORMATION pinfo;
+ STARTUPINFOA sinfo;
+ memset(&sinfo, 0, sizeof(sinfo));
+ memset(&pinfo, 0, sizeof(pinfo));
+
+ std::string exe_name = exe_path.substr(last_slash_position+1);
+ args = exe_name + std::string(" ") + args; // and prepend the executable name, so we get 'Program.exe "Arg1"'
+
+ char *args2 = new char[args.size() + 1]; // Windows requires that the second parameter to CreateProcessA be a writable (non-const) string...
+ strcpy(args2, args.c_str());
+
+ if(!CreateProcessA(exe_path.c_str(), args2, NULL, NULL, FALSE, 0, NULL, exe_dir.c_str(), &sinfo, &pinfo))
+ {
+ // DWORD dwErr = GetLastError();
+ std::string warning = "Creating editor process failed!";
+ popupAndPrintWarning(warning);
+ }
+ else
+ {
+ // foo = pinfo.dwProcessId; // get your pid here if you want to use it later on
+ // sGatewayHandle = pinfo.hProcess;
+ CloseHandle(pinfo.hThread); // stops leaks - nothing else
+ }
+
+ delete[] args2;
+#else // if !LL_WINDOWS
+ // This code was copied from the code to run SLVoice, with some modification; should work in UNIX (Mac/Darwin or Linux)
+ {
+ std::vector<std::string> arglist;
+ arglist.push_back(exe_path.c_str());
+
+ // Split the argument string into separate strings for each argument
+ typedef boost::tokenizer< boost::char_separator<char> > tokenizer;
+ boost::char_separator<char> sep("","\" ", boost::drop_empty_tokens);
+
+ tokenizer tokens(args, sep);
+ tokenizer::iterator token_iter;
+ BOOL inside_quotes = FALSE;
+ BOOL last_was_space = FALSE;
+ for(token_iter = tokens.begin(); token_iter != tokens.end(); ++token_iter)
+ {
+ if(!strncmp("\"",(*token_iter).c_str(),2))
+ {
+ inside_quotes = !inside_quotes;
+ }
+ else if(!strncmp(" ",(*token_iter).c_str(),2))
+ {
+ if(inside_quotes)
+ {
+ arglist.back().append(std::string(" "));
+ last_was_space = TRUE;
+ }
+ }
+ else
+ {
+ std::string to_push = *token_iter;
+ if(last_was_space)
+ {
+ arglist.back().append(to_push);
+ last_was_space = FALSE;
+ }
+ else
+ {
+ arglist.push_back(to_push);
+ }
+ }
+ }
+
+ // create an argv vector for the child process
+ char **fakeargv = new char*[arglist.size() + 1];
+ int i;
+ for(i=0; i < arglist.size(); i++)
+ fakeargv[i] = const_cast<char*>(arglist[i].c_str());
+
+ fakeargv[i] = NULL;
+
+ fflush(NULL); // flush all buffers before the child inherits them
+ pid_t id = vfork();
+ if(id == 0)
+ {
+ // child
+ execv(exe_path.c_str(), fakeargv);
+
+ // If we reach this point, the exec failed.
+ // Use _exit() instead of exit() per the vfork man page.
+ std::string warning = "Creating editor process failed (vfork/execv)!";
+ popupAndPrintWarning(warning);
+ _exit(0);
+ }
+
+ // parent
+ delete[] fakeargv;
+ // sGatewayPID = id;
+ }
+#endif // LL_WINDOWS
+ }
+ else
+ {
+ std::string warning = "Unable to find path to external XML editor for XUI preview tool";
+ popupAndPrintWarning(warning);
+ }
+}
+
+// Respond to button click to browse for an executable with which to edit XML files
+void LLFloaterUIPreview::onClickBrowseForEditor()
+{
+ // create load dialog box
+ LLFilePicker::ELoadFilter type = (LLFilePicker::ELoadFilter)((intptr_t)((void*)LLFilePicker::FFLOAD_ALL)); // nothing for *.exe so just use all
+ LLFilePicker& picker = LLFilePicker::instance();
+ if (!picker.getOpenFile(type)) // user cancelled -- do nothing
+ {
+ return;
+ }
+
+ // put the selected path into text field
+ const std::string chosen_path = picker.getFirstFile();
+ std::string executable_path = chosen_path;
+#if LL_DARWIN
+ // on Mac, if it's an application bundle, figure out the actual path from the Info.plist file
+ CFStringRef path_cfstr = CFStringCreateWithCString(kCFAllocatorDefault, chosen_path.c_str(), kCFStringEncodingMacRoman); // get path as a CFStringRef
+ CFURLRef path_url = CFURLCreateWithFileSystemPath(kCFAllocatorDefault, path_cfstr, kCFURLPOSIXPathStyle, TRUE); // turn it into a CFURLRef
+ CFBundleRef chosen_bundle = CFBundleCreate(kCFAllocatorDefault, path_url); // get a handle for the bundle
+ if(NULL != chosen_bundle)
+ {
+ CFDictionaryRef bundleInfoDict = CFBundleGetInfoDictionary(chosen_bundle); // get the bundle's dictionary
+ if(NULL != bundleInfoDict)
+ {
+ CFStringRef executable_cfstr = (CFStringRef)CFDictionaryGetValue(bundleInfoDict, CFSTR("CFBundleExecutable")); // get the name of the actual executable (e.g. TextEdit or firefox-bin)
+ int max_file_length = 256; // (max file name length is 255 in OSX)
+ char executable_buf[max_file_length];
+ if(CFStringGetCString(executable_cfstr, executable_buf, max_file_length, kCFStringEncodingMacRoman)) // convert CFStringRef to char*
+ {
+ executable_path += std::string("/Contents/MacOS/") + std::string(executable_buf); // append path to executable directory and then executable name to exec path
+ }
+ else
+ {
+ std::string warning = "Unable to get CString from CFString for executable path";
+ popupAndPrintWarning(warning);
+ }
+ }
+ else
+ {
+ std::string warning = "Unable to get bundle info dictionary from application bundle";
+ popupAndPrintWarning(warning);
+ }
+ }
+ else
+ {
+ if(-1 != executable_path.find(".app")) // only warn if this path actually had ".app" in it, i.e. it probably just wasn'nt an app bundle and that's okay
+ {
+ std::string warning = std::string("Unable to get bundle from path \"") + chosen_path + std::string("\"");
+ popupAndPrintWarning(warning);
+ }
+ }
+
+#endif
+ mEditorPathTextBox->setText(std::string(executable_path)); // copy the path to the executable to the textfield for display and later fetching
+}
+
+// Respond to button click to browse for a VLT-generated diffs file
+void LLFloaterUIPreview::onClickBrowseForDiffs()
+{
+ // create load dialog box
+ LLFilePicker::ELoadFilter type = (LLFilePicker::ELoadFilter)((intptr_t)((void*)LLFilePicker::FFLOAD_XML)); // nothing for *.exe so just use all
+ LLFilePicker& picker = LLFilePicker::instance();
+ if (!picker.getOpenFile(type)) // user cancelled -- do nothing
+ {
+ return;
+ }
+
+ // put the selected path into text field
+ const std::string chosen_path = picker.getFirstFile();
+ mDiffPathTextBox->setText(std::string(chosen_path)); // copy the path to the executable to the textfield for display and later fetching
+ if(LLView::sHighlightingDiffs) // if we're already highlighting, toggle off and then on so we get the data from the new file
+ {
+ onClickToggleDiffHighlighting();
+ onClickToggleDiffHighlighting();
+ }
+}
+
+void LLFloaterUIPreview::onClickToggleDiffHighlighting()
+{
+ if(mHighlightingOverlaps)
+ {
+ onClickToggleOverlapping();
+ mToggleOverlapButton->toggleState();
+ }
+
+ LLView::sPreviewHighlightedElements.clear(); // clear lists first
+ mDiffsMap.clear();
+ mFileList->clearHighlightedItems();
+
+ if(LLView::sHighlightingDiffs) // Turning highlighting off
+ {
+ LLView::sHighlightingDiffs = !sHighlightingDiffs;
+ return;
+ }
+ else // Turning highlighting on
+ {
+ // Get the file and make sure it exists
+ std::string path_in_textfield = mDiffPathTextBox->getText(); // get file path
+ BOOL error = FALSE;
+
+ if(std::string("") == path_in_textfield) // check for blank file
+ {
+ std::string warning = "Unable to highlight differences because no file was provided; fill in the relevant text field";
+ popupAndPrintWarning(warning);
+ error = TRUE;
+ }
+
+ llstat dummy;
+ if(LLFile::stat(path_in_textfield.c_str(), &dummy) && !error) // check if the file exists (empty check is reduntant but useful for the informative error message)
+ {
+ std::string warning = std::string("Unable to highlight differences because an invalid path to a difference file was provided:\"") + path_in_textfield + "\"";
+ popupAndPrintWarning(warning);
+ error = TRUE;
+ }
+
+ // Build a list of changed elements as given by the XML
+ std::list<std::string> changed_element_names;
+ LLXmlTree xml_tree;
+ BOOL success = xml_tree.parseFile(path_in_textfield.c_str(), TRUE);
+
+ if(success && !error)
+ {
+ LLXmlTreeNode* root_floater = xml_tree.getRoot();
+ if(!strncmp("XuiDelta",root_floater->getName().c_str(),9))
+ {
+ for (LLXmlTreeNode* child = root_floater->getFirstChild(); // get the first child first, then below get the next one; otherwise the iterator is invalid (bug or feature in XML code?)
+ child != NULL;
+ child = root_floater->getNextChild()) // get child for next iteration
+ {
+ if(!strncmp("file",child->getName().c_str(),5))
+ {
+ scanDiffFile(child);
+ }
+ else if(!strncmp("error",child->getName().c_str(),6))
+ {
+ std::string error_file, error_message;
+ child->getAttributeString("filename",error_file);
+ child->getAttributeString("message",error_message);
+ if(mDiffsMap.find(error_file) != mDiffsMap.end())
+ {
+ mDiffsMap.insert(std::make_pair(error_file,std::make_pair(StringListPtr(new StringList), StringListPtr(new StringList))));
+ }
+ mDiffsMap[error_file].second->push_back(error_message);
+ }
+ else
+ {
+ std::string warning = std::string("Child was neither a file or an error, but rather the following:\"") + std::string(child->getName()) + "\"";
+ popupAndPrintWarning(warning);
+ error = TRUE;
+ break;
+ }
+ }
+ }
+ else
+ {
+ std::string warning = std::string("Root node not named XuiDelta:\"") + path_in_textfield + "\"";
+ popupAndPrintWarning(warning);
+ error = TRUE;
+ }
+ }
+ else if(!error)
+ {
+ std::string warning = std::string("Unable to create tree from XML:\"") + path_in_textfield + "\"";
+ popupAndPrintWarning(warning);
+ error = TRUE;
+ }
+
+ if(error) // if we encountered an error, reset the button to off
+ {
+ mToggleHighlightButton->setToggleState(FALSE);
+ }
+ else // only toggle if we didn't encounter an error
+ {
+ LLView::sHighlightingDiffs = !sHighlightingDiffs;
+ highlightChangedElements(); // *TODO: this is extraneous, right?
+ highlightChangedFiles(); // *TODO: this is extraneous, right?
+ }
+ }
+}
+
+void LLFloaterUIPreview::scanDiffFile(LLXmlTreeNode* file_node)
+{
+ // Get file name
+ std::string file_name;
+ file_node->getAttributeString("name",file_name);
+ if(std::string("") == file_name)
+ {
+ std::string warning = std::string("Empty file name encountered in differences:\"") + file_name + "\"";
+ popupAndPrintWarning(warning);
+ return;
+ }
+
+ // Get a list of changed elements
+ // Get the first child first, then below get the next one; otherwise the iterator is invalid (bug or feature in XML code?)
+ for (LLXmlTreeNode* child = file_node->getFirstChild(); child != NULL; child = file_node->getNextChild())
+ {
+ if(!strncmp("delta",child->getName().c_str(),6))
+ {
+ std::string id;
+ child->getAttributeString("id",id);
+ if(mDiffsMap.find(file_name) == mDiffsMap.end())
+ {
+ mDiffsMap.insert(std::make_pair(file_name,std::make_pair(StringListPtr(new StringList), StringListPtr(new StringList))));
+ }
+ mDiffsMap[file_name].first->push_back(std::string(id.c_str()));
+ }
+ else
+ {
+ std::string warning = std::string("Child of file was not a delta, but rather the following:\"") + std::string(child->getName()) + "\"";
+ popupAndPrintWarning(warning);
+ return;
+ }
+ }
+}
+
+void LLFloaterUIPreview::highlightChangedElements()
+{
+ if(NULL == mLiveFile)
+ {
+ return;
+ }
+
+ // Process differences first (we want their warnings to be shown underneath other warnings)
+ StringListPtr changed_element_paths;
+ DiffMap::iterator iterExists = mDiffsMap.find(mLiveFile->mFileName);
+ if(iterExists != mDiffsMap.end())
+ {
+ changed_element_paths = mDiffsMap[mLiveFile->mFileName].first; // retrieve list of changed element paths from map
+ }
+
+ for(std::list<std::string>::iterator iter = changed_element_paths->begin(); iter != changed_element_paths->end(); ++iter) // for every changed element path
+ {
+ LLView* element = mDisplayedFloater;
+ if(!strncmp(iter->c_str(),".",1)) // if it's the root floater itself
+ {
+ continue;
+ }
+
+ // Split element hierarchy path on period (*HACK: it's possible that the element name will have a period in it, in which case this won't work. See https://wiki.lindenlab.com/wiki/Viewer_Localization_Tool_Documentation.)
+ typedef boost::tokenizer<boost::char_separator<char> > tokenizer;
+ boost::char_separator<char> sep(".");
+ tokenizer tokens(*iter, sep);
+ tokenizer::iterator token_iter;
+ BOOL failed = FALSE;
+ for(token_iter = tokens.begin(); token_iter != tokens.end(); ++token_iter)
+ {
+ element = element->findChild<LLView>(*token_iter,FALSE); // try to find element: don't recur, and don't create if missing
+
+ // if we still didn't find it...
+ if(NULL == element)
+ {
+ llinfos << "Unable to find element in XuiDelta file named \"" << *iter << "\" in file \"" << mLiveFile->mFileName <<
+ "\". The element may no longer exist, the path may be incorrect, or it may not be a non-displayable element (not an LLView) such as a \"string\" type." << llendl;
+ failed = TRUE;
+ break;
+ }
+ }
+
+ if(!failed)
+ {
+ // Now that we have a pointer to the actual element, add it to the list of elements to be highlighted
+ std::set<LLView*>::iterator iter2 = std::find(LLView::sPreviewHighlightedElements.begin(), LLView::sPreviewHighlightedElements.end(), element);
+ if(iter2 == LLView::sPreviewHighlightedElements.end())
+ {
+ LLView::sPreviewHighlightedElements.insert(element);
+ }
+ }
+ }
+
+ // Process errors second, so their warnings show up on top of other warnings
+ StringListPtr error_list;
+ if(iterExists != mDiffsMap.end())
+ {
+ error_list = mDiffsMap[mLiveFile->mFileName].second;
+ }
+ for(std::list<std::string>::iterator iter = error_list->begin(); iter != error_list->end(); ++iter) // for every changed element path
+ {
+ std::string warning = std::string("Error listed among differences. Filename: \"") + mLiveFile->mFileName + "\". Message: \"" + *iter + "\"";
+ popupAndPrintWarning(warning);
+ }
+}
+
+void LLFloaterUIPreview::highlightChangedFiles()
+{
+ for(DiffMap::iterator iter = mDiffsMap.begin(); iter != mDiffsMap.end(); ++iter) // for every file listed in diffs
+ {
+ LLScrollListItem* item = mFileList->getItemByLabel(std::string(iter->first), FALSE, 1);
+ if(item)
+ {
+ item->setHighlighted(TRUE);
+ }
+ }
+}
+
+// Respond to button click to browse for an executable with which to edit XML files
+void LLFloaterUIPreview::onClickCloseDisplayedFloater(S32 caller_id)
+{
+ if(caller_id == PRIMARY_FLOATER)
+ {
+ mCloseOtherButton->setEnabled(FALSE);
+ mToggleOverlapButton->setEnabled(FALSE);
+
+ if(mDisplayedFloater)
+ {
+ mLastDisplayedX = mDisplayedFloater->calcScreenRect().mLeft;
+ mLastDisplayedY = mDisplayedFloater->calcScreenRect().mBottom;
+ delete mDisplayedFloater;
+ mDisplayedFloater = NULL;
+ }
+
+ if(mLiveFile)
+ {
+ delete mLiveFile;
+ mLiveFile = NULL;
+ }
+
+ if(mToggleOverlapButton->getToggleState())
+ {
+ mToggleOverlapButton->toggleState();
+ onClickToggleOverlapping();
+ }
+
+ LLView::sPreviewClickedElement = NULL; // stop overlapping elements panel from drawing
+ mOverlapPanel->mLastClickedElement = NULL;
+ }
+ else
+ {
+ mCloseOtherButton_2->setEnabled(FALSE);
+ delete mDisplayedFloater_2;
+ mDisplayedFloater_2 = NULL;
+ }
+
+}
+
+BOOL LLPreviewedFloater::handleRightMouseDown(S32 x, S32 y, MASK mask)
+{
+ selectElement(this,x,y,0);
+ return TRUE;
+}
+
+// *NOTE: In order to hide all of the overlapping elements of the selected element so as to see it in context, here is what you would need to do:
+// -This selectElement call fills the overlap panel as normal. The element which is "selected" here is actually just an intermediate selection step;
+// what you've really selected is a list of elements: the one you clicked on and everything that overlaps it.
+// -The user then selects one of the elements from this list the overlap panel (click handling to the overlap panel would have to be added).
+// This becomes the final selection (as opposed to the intermediate selection that was just made).
+// -Everything else that is currently displayed on the overlap panel should be hidden from view in the previewed floater itself (setVisible(FALSE)).
+// -Subsequent clicks on other elements in the overlap panel (they should still be there) should make other elements the final selection.
+// -On close or on the click of a new button, everything should be shown again and all selection state should be cleared.
+// ~Jacob, 8/08
+BOOL LLPreviewedFloater::selectElement(LLView* parent, int x, int y, int depth)
+{
+ if(getVisible())
+ {
+ BOOL handled = FALSE;
+ if(LLFloaterUIPreview::containerType(parent))
+ {
+ for(child_list_const_iter_t child_it = parent->getChildList()->begin(); child_it != parent->getChildList()->end(); ++child_it)
+ {
+ LLView* child = *child_it;
+ S32 local_x = x - child->getRect().mLeft;
+ S32 local_y = y - child->getRect().mBottom;
+ if (child->pointInView(local_x, local_y) &&
+ child->getVisible() &&
+ selectElement(child, x, y, ++depth))
+ {
+ handled = TRUE;
+ break;
+ }
+ }
+ }
+
+ if(!handled)
+ {
+ LLView::sPreviewClickedElement = parent;
+ }
+ return TRUE;
+ }
+ else
+ {
+ return FALSE;
+ }
+}
+
+void LLPreviewedFloater::draw()
+{
+ if(NULL != mFloaterUIPreview)
+ {
+ // Set and unset sDrawPreviewHighlights flag so as to avoid using two flags
+ if(mFloaterUIPreview->mHighlightingOverlaps)
+ {
+ LLView::sDrawPreviewHighlights = TRUE;
+ }
+ LLFloater::draw();
+ if(mFloaterUIPreview->mHighlightingOverlaps)
+ {
+ LLView::sDrawPreviewHighlights = FALSE;
+ }
+ }
+}
+
+void LLFloaterUIPreview::onClickToggleOverlapping()
+{
+ if(LLView::sHighlightingDiffs)
+ {
+ onClickToggleDiffHighlighting();
+ mToggleHighlightButton->toggleState();
+ }
+ LLView::sPreviewHighlightedElements.clear(); // clear lists first
+
+ S32 width, height;
+ getResizeLimits(&width, &height); // illegal call of non-static member function
+ if(mHighlightingOverlaps)
+ {
+ mHighlightingOverlaps = !mHighlightingOverlaps;
+ // reset list of preview highlighted elements
+ setRect(LLRect(getRect().mLeft,getRect().mTop,getRect().mRight - mOverlapPanel->getRect().getWidth(),getRect().mBottom));
+ setResizeLimits(width - mOverlapPanel->getRect().getWidth(), height);
+ }
+ else
+ {
+ mHighlightingOverlaps = !mHighlightingOverlaps;
+ displayFloater(FALSE,1);
+ setRect(LLRect(getRect().mLeft,getRect().mTop,getRect().mRight + mOverlapPanel->getRect().getWidth(),getRect().mBottom));
+ setResizeLimits(width + mOverlapPanel->getRect().getWidth(), height);
+ }
+ childSetVisible("overlap_scroll", mHighlightingOverlaps);
+}
+
+void LLFloaterUIPreview::findOverlapsInChildren(LLView* parent)
+{
+ if(parent->getChildCount() == 0 || !containerType(parent)) // if it has no children or isn't a container type, skip it
+ {
+ return;
+ }
+
+ // for every child of the parent
+ for(child_list_const_iter_t child_it = parent->getChildList()->begin(); child_it != parent->getChildList()->end(); ++child_it)
+ {
+ LLView* child = *child_it;
+ if(overlapIgnorable(child))
+ {
+ continue;
+ }
+
+ // for every sibling
+ for(child_list_const_iter_t sibling_it = parent->getChildList()->begin(); sibling_it != parent->getChildList()->end(); ++sibling_it) // for each sibling
+ {
+ LLView* sibling = *sibling_it;
+ if(overlapIgnorable(sibling))
+ {
+ continue;
+ }
+
+ // if they overlap... (we don't care if they're visible or enabled -- we want to check those anyway, i.e. hidden tabs that can be later shown)
+ if(sibling != child && elementOverlap(child, sibling))
+ {
+ mOverlapPanel->mOverlapMap[child].push_back(sibling); // add to the map
+ }
+ }
+ findOverlapsInChildren(child); // recur
+ }
+}
+
+// *HACK: don't overlap with the drag handle and various other elements
+// This is using dynamic casts because there is no object-oriented way to tell which elements contain localizable text. These are a few that are ignorable.
+// *NOTE: If a list of elements which have localizable content were created, this function should return false if viewp's class is in that list.
+BOOL LLFloaterUIPreview::overlapIgnorable(LLView* viewp)
+{
+ return NULL != dynamic_cast<LLDragHandle*>(viewp) ||
+ NULL != dynamic_cast<LLViewBorder*>(viewp) ||
+ NULL != dynamic_cast<LLResizeBar*>(viewp);
+}
+
+// *HACK: these are the only two container types as of 8/08, per Richard
+// This is using dynamic casts because there is no object-oriented way to tell which elements are containers.
+BOOL LLFloaterUIPreview::containerType(LLView* viewp)
+{
+ return NULL != dynamic_cast<LLPanel*>(viewp) || NULL != dynamic_cast<LLLayoutStack*>(viewp);
+}
+
+// Check if two llview's rectangles overlap, with some tolerance
+BOOL LLFloaterUIPreview::elementOverlap(LLView* view1, LLView* view2)
+{
+ LLSD rec1 = view1->getRect().getValue();
+ LLSD rec2 = view2->getRect().getValue();
+ int tolerance = 2;
+ return (int)rec1[0] <= (int)rec2[2] - tolerance &&
+ (int)rec2[0] <= (int)rec1[2] - tolerance &&
+ (int)rec1[3] <= (int)rec2[1] - tolerance &&
+ (int)rec2[3] <= (int)rec1[1] - tolerance;
+}
+
+void LLOverlapPanel::draw()
+{
+ static const std::string current_selection_text("Current selection: ");
+ static const std::string overlapper_text("Overlapper: ");
+ LLColor4 text_color = LLColor4::grey;
+ gGL.color4fv(text_color.mV);
+
+ if(!LLView::sPreviewClickedElement)
+ {
+ LLUI::translate(5,getRect().getHeight()-20); // translate to top-5,left-5
+ LLView::sDrawPreviewHighlights = FALSE;
+ LLFontGL::getFontSansSerifSmall()->renderUTF8(current_selection_text, 0, 0, 0, text_color,
+ LLFontGL::LEFT, LLFontGL::BASELINE, LLFontGL::NORMAL, LLFontGL::NO_SHADOW, S32_MAX, S32_MAX, NULL, FALSE);
+ }
+ else
+ {
+ OverlapMap::iterator iterExists = mOverlapMap.find(LLView::sPreviewClickedElement);
+ if(iterExists == mOverlapMap.end())
+ {
+ return;
+ }
+
+ std::list<LLView*> overlappers = mOverlapMap[LLView::sPreviewClickedElement];
+ if(overlappers.size() == 0)
+ {
+ LLUI::translate(5,getRect().getHeight()-20); // translate to top-5,left-5
+ LLView::sDrawPreviewHighlights = FALSE;
+ std::string current_selection = std::string(current_selection_text + LLView::sPreviewClickedElement->getName() + " (no elements overlap)");
+ S32 text_width = LLFontGL::getFontSansSerifSmall()->getWidth(current_selection) + 10;
+ LLFontGL::getFontSansSerifSmall()->renderUTF8(current_selection, 0, 0, 0, text_color,
+ LLFontGL::LEFT, LLFontGL::BASELINE, LLFontGL::NORMAL, LLFontGL::NO_SHADOW, S32_MAX, S32_MAX, NULL, FALSE);
+ // widen panel enough to fit this text
+ LLRect rect = getRect();
+ setRect(LLRect(rect.mLeft,rect.mTop,rect.getWidth() < text_width ? rect.mLeft + text_width : rect.mRight,rect.mTop));
+ return;
+ }
+
+ // recalculate required with and height; otherwise use cached
+ BOOL need_to_recalculate_bounds = FALSE;
+ if(mLastClickedElement == NULL)
+ {
+ need_to_recalculate_bounds = TRUE;
+ }
+
+ if(NULL == mLastClickedElement)
+ {
+ mLastClickedElement = LLView::sPreviewClickedElement;
+ }
+
+ // recalculate bounds for scroll panel
+ if(need_to_recalculate_bounds || LLView::sPreviewClickedElement->getName() != mLastClickedElement->getName())
+ {
+ // reset panel's rectangle to its default width and height (300x600)
+ LLRect panel_rect = getRect();
+ setRect(LLRect(panel_rect.mLeft,panel_rect.mTop,panel_rect.mLeft+getRect().getWidth(),panel_rect.mTop-getRect().getHeight()));
+
+ LLRect rect;
+
+ // change bounds for selected element
+ int height_sum = mLastClickedElement->getRect().getHeight() + mSpacing + 80;
+ rect = getRect();
+ setRect(LLRect(rect.mLeft,rect.mTop,rect.getWidth() > mLastClickedElement->getRect().getWidth() + 5 ? rect.mRight : rect.mLeft + mLastClickedElement->getRect().getWidth() + 5, rect.mBottom));
+
+ // and widen to accomodate text if that's wider
+ std::string display_text = current_selection_text + LLView::sPreviewClickedElement->getName();
+ S32 text_width = LLFontGL::getFontSansSerifSmall()->getWidth(display_text) + 10;
+ rect = getRect();
+ setRect(LLRect(rect.mLeft,rect.mTop,rect.getWidth() < text_width ? rect.mLeft + text_width : rect.mRight,rect.mTop));
+
+ std::list<LLView*> overlappers = mOverlapMap[LLView::sPreviewClickedElement];
+ for(std::list<LLView*>::iterator overlap_it = overlappers.begin(); overlap_it != overlappers.end(); ++overlap_it)
+ {
+ LLView* viewp = *overlap_it;
+ height_sum += viewp->getRect().getHeight() + mSpacing*3;
+
+ // widen panel's rectangle to accommodate widest overlapping element of this floater
+ rect = getRect();
+ setRect(LLRect(rect.mLeft,rect.mTop,rect.getWidth() > viewp->getRect().getWidth() + 5 ? rect.mRight : rect.mLeft + viewp->getRect().getWidth() + 5, rect.mBottom));
+
+ // and widen to accomodate text if that's wider
+ std::string display_text = overlapper_text + viewp->getName();
+ S32 text_width = LLFontGL::getFontSansSerifSmall()->getWidth(display_text) + 10;
+ rect = getRect();
+ setRect(LLRect(rect.mLeft,rect.mTop,rect.getWidth() < text_width ? rect.mLeft + text_width : rect.mRight,rect.mTop));
+ }
+ // change panel's height to accommodate all element heights plus spacing between them
+ rect = getRect();
+ setRect(LLRect(rect.mLeft,rect.mTop,rect.mRight,rect.mTop-height_sum));
+ }
+
+ LLUI::translate(5,getRect().getHeight()-10); // translate to top left
+ LLView::sDrawPreviewHighlights = FALSE;
+
+ // draw currently-selected element at top of overlappers
+ LLUI::translate(0,-mSpacing);
+ LLFontGL::getFontSansSerifSmall()->renderUTF8(current_selection_text + LLView::sPreviewClickedElement->getName(), 0, 0, 0, text_color,
+ LLFontGL::LEFT, LLFontGL::BASELINE, LLFontGL::NORMAL, LLFontGL::NO_SHADOW, S32_MAX, S32_MAX, NULL, FALSE);
+ LLUI::translate(0,-mSpacing-LLView::sPreviewClickedElement->getRect().getHeight()); // skip spacing distance + height
+ LLView::sPreviewClickedElement->draw();
+
+ for(std::list<LLView*>::iterator overlap_it = overlappers.begin(); overlap_it != overlappers.end(); ++overlap_it)
+ {
+ LLView* viewp = *overlap_it;
+
+ // draw separating line
+ LLUI::translate(0,-mSpacing);
+ gl_line_2d(0,0,getRect().getWidth()-10,0,LLColor4(192.0f/255.0f,192.0f/255.0f,192.0f/255.0f));
+
+ // draw name
+ LLUI::translate(0,-mSpacing);
+ LLFontGL::getFontSansSerifSmall()->renderUTF8(overlapper_text + viewp->getName(), 0, 0, 0, text_color,
+ LLFontGL::LEFT, LLFontGL::BASELINE, LLFontGL::NORMAL, LLFontGL::NO_SHADOW, S32_MAX, S32_MAX, NULL, FALSE);
+
+ // draw element
+ LLUI::translate(0,-mSpacing-viewp->getRect().getHeight()); // skip spacing distance + height
+ viewp->draw();
+ }
+ mLastClickedElement = LLView::sPreviewClickedElement;
+ }
+}
diff --git a/indra/newview/llfloateruipreview.h b/indra/newview/llfloateruipreview.h
new file mode 100644
index 0000000000..b8c378e2e9
--- /dev/null
+++ b/indra/newview/llfloateruipreview.h
@@ -0,0 +1,174 @@
+/**
+ * @file llfloateruipreview.h
+ * @brief Tool for previewing and editing floaters
+ *
+ * $LicenseInfo:firstyear=2008&license=viewergpl$
+ *
+ * Copyright (c) 2008-2009, Linden Research, Inc.
+ *
+ * Second Life Viewer Source Code
+ * The source code in this file ("Source Code") is provided by Linden Lab
+ * to you under the terms of the GNU General Public License, version 2.0
+ * ("GPL"), unless you have obtained a separate licensing agreement
+ * ("Other License"), formally executed by you and Linden Lab. Terms of
+ * the GPL can be found in doc/GPL-license.txt in this distribution, or
+ * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
+ *
+ * There are special exceptions to the terms and conditions of the GPL as
+ * it is applied to this Source Code. View the full text of the exception
+ * in the file doc/FLOSS-exception.txt in this software distribution, or
+ * online at
+ * http://secondlifegrid.net/programs/open_source/licensing/flossexception
+ *
+ * By copying, modifying or distributing this software, you acknowledge
+ * that you have read and understood your obligations described above,
+ * and agree to abide by those obligations.
+ *
+ * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+ * COMPLETENESS OR PERFORMANCE.
+ * $/LicenseInfo$
+ */
+
+// Tool for previewing floaters and panels for localization and UI design purposes.
+// See: https://wiki.lindenlab.com/wiki/GUI_Preview_And_Localization_Tools
+// See: https://jira.lindenlab.com/browse/DEV-16869
+
+#ifndef LL_LLUIPREVIEW_H
+#define LL_LLUIPREVIEW_H
+
+#include "llfloater.h" // superclass
+#include "llscrollcontainer.h" // scroll container for overlapping elements
+#include "lllivefile.h" // live file poll/stat/reload
+#include <list>
+#include <map>
+
+// Forward declarations to avoid header dependencies
+class LLEventTimer;
+class LLColor;
+class LLScrollListCtrl;
+class LLComboBox;
+class LLButton;
+class LLLineEditor;
+class LLXmlTreeNode;
+class LLFloaterUIPreview;
+class LLFadeEventTimer;
+
+class LLLocalizationResetForcer;
+class LLGUIPreviewLiveFile;
+class LLFadeEventTimer;
+class LLPreviewedFloater;
+
+// Implementation of custom overlapping element display panel
+class LLOverlapPanel : public LLPanel
+{
+public:
+ struct Params : public LLInitParam::Block<Params, LLPanel::Params>
+ {
+ Params() {}
+ };
+ LLOverlapPanel(Params p = Params()) : LLPanel(p),
+ mSpacing(10),
+ // mClickedElement(NULL),
+ mLastClickedElement(NULL)
+ {
+ mOriginalWidth = getRect().getWidth();
+ mOriginalHeight = getRect().getHeight();
+ }
+ virtual void draw();
+
+ typedef std::map<LLView*, std::list<LLView*> > OverlapMap;
+ OverlapMap mOverlapMap; // map, of XUI element to a list of XUI elements it overlaps
+
+ // LLView *mClickedElement;
+ LLView *mLastClickedElement;
+ int mOriginalWidth, mOriginalHeight, mSpacing;
+};
+
+
+class LLFloaterUIPreview : public LLFloater
+{
+public:
+ // Setup
+ LLFloaterUIPreview(const LLSD& key);
+ virtual ~LLFloaterUIPreview();
+
+ std::string getLocStr(S32 ID); // fetches the localization string based on what is selected in the drop-down menu
+ void displayFloater(BOOL click, S32 ID, bool save = false); // needs to be public so live file can call it when it finds an update
+
+ BOOL postBuild(); // post-build setup (called by superclass' constructor)
+ void refreshList(); // refresh list (empty it out and fill it up from scratch)
+ void addFloaterEntry(const std::string& path); // add a single file's entry to the list of floaters
+
+ static BOOL containerType(LLView* viewp); // check if the element is a container type and tree traverses need to look at its children
+
+public:
+ LLPreviewedFloater* mDisplayedFloater; // the floater which is currently being displayed
+ LLPreviewedFloater* mDisplayedFloater_2; // the floater which is currently being displayed
+ LLGUIPreviewLiveFile* mLiveFile; // live file for checking for updates to the currently-displayed XML file
+ LLOverlapPanel* mOverlapPanel; // custom overlapping elements panel
+ // BOOL mHighlightingDiffs; // bool for whether localization diffs are being highlighted or not
+ BOOL mHighlightingOverlaps; // bool for whether overlapping elements are being highlighted
+
+ // typedef std::map<std::string,std::pair<std::list<std::string>,std::list<std::string> > > DiffMap; // this version copies the lists etc., and thus is bad memory-wise
+ typedef std::list<std::string> StringList;
+ typedef boost::shared_ptr<StringList> StringListPtr;
+ typedef std::map<std::string, std::pair<StringListPtr,StringListPtr> > DiffMap;
+ DiffMap mDiffsMap; // map, of filename to pair of list of changed element paths and list of errors
+
+protected:
+ void onClose(const LLSD& app_quitting);
+
+private:
+ // XUI elements for this floater
+ LLScrollListCtrl* mFileList; // scroll list control for file list
+ LLLineEditor* mEditorPathTextBox; // text field for path to editor executable
+ LLLineEditor* mEditorArgsTextBox; // text field for arguments to editor executable
+ LLLineEditor* mDiffPathTextBox; // text field for path to diff file
+ LLButton* mDisplayFloaterBtn; // button to display primary floater
+ LLButton* mDisplayFloaterBtn_2; // button to display secondary floater
+ LLButton* mEditFloaterBtn; // button to edit floater
+ LLButton* mExecutableBrowseButton; // button to browse for executable
+ LLButton* mCloseOtherButton; // button to close primary displayed floater
+ LLButton* mCloseOtherButton_2; // button to close secondary displayed floater
+ LLButton* mDiffBrowseButton; // button to browse for diff file
+ LLButton* mToggleHighlightButton; // button to toggle highlight of files/elements with diffs
+ LLButton* mToggleOverlapButton; // button to togle overlap panel/highlighting
+ LLComboBox* mLanguageSelection; // combo box for primary language selection
+ LLComboBox* mLanguageSelection_2; // combo box for secondary language selection
+ LLScrollContainer* mOverlapScrollView; // overlapping elements scroll container
+ S32 mLastDisplayedX, mLastDisplayedY; // stored position of last floater so the new one opens up in the same place
+ std::string mDelim; // the OS-specific delimiter character (/ or \) (*TODO: this shouldn't be needed, right?)
+
+ std::string mSavedEditorPath; // stored editor path so closing this floater doesn't reset it
+ std::string mSavedEditorArgs; // stored editor args so closing this floater doesn't reset it
+ std::string mSavedDiffPath; // stored diff file path so closing this floater doesn't reset it
+
+ // Internal functionality
+ static void popupAndPrintWarning(std::string& warning); // pop up a warning
+ std::string getLocalizedDirectory(); // build and return the path to the XUI directory for the currently-selected localization
+ void scanDiffFile(LLXmlTreeNode* file_node); // scan a given XML node for diff entries and highlight them in its associated file
+ void highlightChangedElements(); // look up the list of elements to highlight and highlight them in the current floater
+ void highlightChangedFiles(); // look up the list of changed files to highlight and highlight them in the scroll list
+ void findOverlapsInChildren(LLView* parent); // fill the map below with element overlap information
+ static BOOL overlapIgnorable(LLView* viewp); // check it the element can be ignored for overlap/localization purposes
+
+ // check if two elements overlap using their rectangles
+ // used instead of llrect functions because by adding a few pixels of leeway I can cut down drastically on the number of overlaps
+ BOOL elementOverlap(LLView* view1, LLView* view2);
+
+ // Button/drop-down action listeners (self explanatory)
+ void onClickDisplayFloater(S32 id);
+ void onClickSaveFloater(S32 id);
+ void onClickSaveAll(S32 id);
+ void onClickEditFloater();
+ void onClickBrowseForEditor();
+ void onClickBrowseForDiffs();
+ void onClickToggleDiffHighlighting();
+ void onClickToggleOverlapping();
+ void onClickCloseDisplayedFloater(S32 id);
+ void onLanguageComboSelect(LLUICtrl* ctrl);
+ void onClickExportSchema();
+};
+#endif // LL_LLUIPREVIEW_H
+
diff --git a/indra/newview/llfloaterurldisplay.cpp b/indra/newview/llfloaterurldisplay.cpp
index c265c6169a..3b9321a876 100644
--- a/indra/newview/llfloaterurldisplay.cpp
+++ b/indra/newview/llfloaterurldisplay.cpp
@@ -45,10 +45,10 @@
LLFloaterURLDisplay::LLFloaterURLDisplay(const LLSD& sd)
+ : LLFloater(sd)
{
mFactoryMap["place_details_panel"] = LLCallbackMap(LLFloaterURLDisplay::createPlaceDetail, this);
- LLUICtrlFactory::getInstance()->buildFloater(this, "floater_preview_url.xml", &getFactoryMap());
- this->setVisible(false);
+// LLUICtrlFactory::getInstance()->buildFloater(this, "floater_preview_url.xml");
// If positioned at 0,0 the teleport button is behind the toolbar.
LLRect r = getRect();
diff --git a/indra/newview/llfloaterurldisplay.h b/indra/newview/llfloaterurldisplay.h
index 91c544ae86..22f5a95ad0 100644
--- a/indra/newview/llfloaterurldisplay.h
+++ b/indra/newview/llfloaterurldisplay.h
@@ -40,11 +40,10 @@ class LLPanelPlace;
class LLSD;
class LLUUID;
-class LLFloaterURLDisplay : public LLFloater, public LLFloaterSingleton<LLFloaterURLDisplay>
+class LLFloaterURLDisplay : public LLFloater
{
+ friend class LLFloaterReg;
public:
- LLFloaterURLDisplay(const LLSD& sd);
- virtual ~LLFloaterURLDisplay();
void displayParcelInfo(U64 region_handle, const LLVector3& pos);
void setSnapshotDisplay(const LLUUID& snapshot_id);
@@ -54,6 +53,9 @@ public:
static void* createPlaceDetail(void* userdata);
private:
+ LLFloaterURLDisplay(const LLSD& sd);
+ virtual ~LLFloaterURLDisplay();
+
LLVector3 mRegionPosition;
U64 mRegionHandle;
LLPanelPlace* mPlacePanel;
diff --git a/indra/newview/llfloaterurlentry.cpp b/indra/newview/llfloaterurlentry.cpp
index 9d91aa9868..1e975cd447 100644
--- a/indra/newview/llfloaterurlentry.cpp
+++ b/indra/newview/llfloaterurlentry.cpp
@@ -86,12 +86,22 @@ public:
// LLFloaterURLEntry()
//-----------------------------------------------------------------------------
LLFloaterURLEntry::LLFloaterURLEntry(LLHandle<LLPanel> parent)
- :
- LLFloater(),
- mPanelLandMediaHandle(parent)
+ : LLFloater(LLSD()),
+ mPanelLandMediaHandle(parent)
{
- LLUICtrlFactory::getInstance()->buildFloater(this, "floater_url_entry.xml");
+ LLUICtrlFactory::getInstance()->buildFloater(this, "floater_url_entry.xml", NULL);
+}
+
+//-----------------------------------------------------------------------------
+// ~LLFloaterURLEntry()
+//-----------------------------------------------------------------------------
+LLFloaterURLEntry::~LLFloaterURLEntry()
+{
+ sInstance = NULL;
+}
+BOOL LLFloaterURLEntry::postBuild()
+{
mMediaURLEdit = getChild<LLComboBox>("media_entry");
// Cancel button
@@ -99,7 +109,6 @@ LLFloaterURLEntry::LLFloaterURLEntry(LLHandle<LLPanel> parent)
// Cancel button
childSetAction("clear_btn", onBtnClear, this);
-
// clear media list button
LLSD parcel_history = LLURLHistory::getURLHistory("parcel");
bool enable_clear_button = parcel_history.size() > 0 ? true : false;
@@ -111,17 +120,8 @@ LLFloaterURLEntry::LLFloaterURLEntry(LLHandle<LLPanel> parent)
setDefaultBtn("ok_btn");
buildURLHistory();
- sInstance = this;
-}
-
-//-----------------------------------------------------------------------------
-// ~LLFloaterURLEntry()
-//-----------------------------------------------------------------------------
-LLFloaterURLEntry::~LLFloaterURLEntry()
-{
- sInstance = NULL;
+ return TRUE;
}
-
void LLFloaterURLEntry::buildURLHistory()
{
LLCtrlListInterface* url_list = childGetListInterface("media_entry");
@@ -155,7 +155,7 @@ void LLFloaterURLEntry::headerFetchComplete(U32 status, const std::string& mime_
// Decrement the cursor
getWindow()->decBusyCount();
childSetVisible("loading_label", false);
- close();
+ closeFloater();
}
// static
@@ -163,7 +163,7 @@ LLHandle<LLFloater> LLFloaterURLEntry::show(LLHandle<LLPanel> parent)
{
if (sInstance)
{
- sInstance->open();
+ sInstance->openFloater();
}
else
{
@@ -227,7 +227,7 @@ void LLFloaterURLEntry::onBtnOK( void* userdata )
}
// Discover the MIME type only for "http" scheme.
- if(scheme == "http")
+ if(scheme == "http" || scheme == "https")
{
LLHTTPClient::getHeaderOnly( media_url,
new LLMediaTypeResponder(self->getHandle()));
@@ -254,7 +254,7 @@ void LLFloaterURLEntry::onBtnOK( void* userdata )
void LLFloaterURLEntry::onBtnCancel( void* userdata )
{
LLFloaterURLEntry *self =(LLFloaterURLEntry *)userdata;
- self->close();
+ self->closeFloater();
}
// static
diff --git a/indra/newview/llfloaterurlentry.h b/indra/newview/llfloaterurlentry.h
index 6d04326cf8..0aeca823b8 100644
--- a/indra/newview/llfloaterurlentry.h
+++ b/indra/newview/llfloaterurlentry.h
@@ -1,6 +1,6 @@
/**
- * @file llfloaternamedesc.h
- * @brief LLFloaterNameDesc class definition
+ * @file llfloaterurlentry.h
+ * @brief LLFloaterURLEntry class definition
*
* $LicenseInfo:firstyear=2007&license=viewergpl$
*
@@ -45,7 +45,7 @@ public:
// Can only be shown by LLPanelLandMedia, and pushes data back into
// that panel via the handle.
static LLHandle<LLFloater> show(LLHandle<LLPanel> panel_land_media_handle);
-
+ /*virtual*/ BOOL postBuild();
void updateFromLandMediaPanel();
void headerFetchComplete(U32 status, const std::string& mime_type);
diff --git a/indra/newview/llfloatervoicedevicesettings.cpp b/indra/newview/llfloatervoicedevicesettings.cpp
index 2922628786..a7658d90e9 100644
--- a/indra/newview/llfloatervoicedevicesettings.cpp
+++ b/indra/newview/llfloatervoicedevicesettings.cpp
@@ -36,12 +36,10 @@
#include "llfloatervoicedevicesettings.h"
// Viewer includes
-#include "llagent.h"
#include "llbutton.h"
#include "llcombobox.h"
#include "llfocusmgr.h"
#include "lliconctrl.h"
-#include "llprefsvoice.h"
#include "llsliderctrl.h"
#include "llviewercontrol.h"
#include "llvoiceclient.h"
@@ -52,6 +50,7 @@
LLPanelVoiceDeviceSettings::LLPanelVoiceDeviceSettings()
+ : LLPanel()
{
mCtrlInputDevices = NULL;
mCtrlOutputDevices = NULL;
@@ -113,7 +112,7 @@ void LLPanelVoiceDeviceSettings::draw()
{
if (power_bar_idx < discrete_power)
{
- LLColor4 color = (power_bar_idx >= 3) ? gSavedSettings.getColor4("OverdrivenColor") : gSavedSettings.getColor4("SpeakingColor");
+ LLColor4 color = (power_bar_idx >= 3) ? LLUIColorTable::instance().getColor("OverdrivenColor") : LLUIColorTable::instance().getColor("SpeakingColor");
gl_rect_2d(bar_view->getRect(), color, TRUE);
}
gl_rect_2d(bar_view->getRect(), LLColor4::grey, FALSE);
@@ -240,7 +239,7 @@ void LLPanelVoiceDeviceSettings::refresh()
}
}
-void LLPanelVoiceDeviceSettings::onOpen()
+void LLPanelVoiceDeviceSettings::initialize()
{
mInputDevice = gSavedSettings.getString("VoiceInputAudioDevice");
mOutputDevice = gSavedSettings.getString("VoiceOutputAudioDevice");
@@ -255,7 +254,7 @@ void LLPanelVoiceDeviceSettings::onOpen()
LLVoiceChannel::suspend();
}
-void LLPanelVoiceDeviceSettings::onClose(bool app_quitting)
+void LLPanelVoiceDeviceSettings::cleanup()
{
gVoiceClient->tuningStop();
LLVoiceChannel::resume();
@@ -284,34 +283,36 @@ void LLPanelVoiceDeviceSettings::onCommitOutputDevice(LLUICtrl* ctrl, void* user
//
LLFloaterVoiceDeviceSettings::LLFloaterVoiceDeviceSettings(const LLSD& seed)
- : LLFloater(std::string("floater_device_settings")),
+ : LLFloater(seed),
mDevicePanel(NULL)
{
mFactoryMap["device_settings"] = LLCallbackMap(createPanelVoiceDeviceSettings, this);
// do not automatically open singleton floaters (as result of getInstance())
- BOOL no_open = FALSE;
- LLUICtrlFactory::getInstance()->buildFloater(this, "floater_device_settings.xml", &mFactoryMap, no_open);
+// BOOL no_open = FALSE;
+// Called from floater reg: LLUICtrlFactory::getInstance()->buildFloater(this, "floater_device_settings.xml", no_open);
+}
+BOOL LLFloaterVoiceDeviceSettings::postBuild()
+{
+ mCloseSignal.connect(boost::bind(&LLFloaterVoiceDeviceSettings::onClose, this));
+
center();
+ return TRUE;
}
-
-void LLFloaterVoiceDeviceSettings::onOpen()
+void LLFloaterVoiceDeviceSettings::onOpen(const LLSD& key)
{
if(mDevicePanel)
{
- mDevicePanel->onOpen();
+ mDevicePanel->initialize();
}
-
- LLFloater::onOpen();
}
-void LLFloaterVoiceDeviceSettings::onClose(bool app_quitting)
+void LLFloaterVoiceDeviceSettings::onClose()
{
if(mDevicePanel)
{
- mDevicePanel->onClose(app_quitting);
+ mDevicePanel->apply();
+ mDevicePanel->cleanup();
}
-
- setVisible(FALSE);
}
void LLFloaterVoiceDeviceSettings::apply()
diff --git a/indra/newview/llfloatervoicedevicesettings.h b/indra/newview/llfloatervoicedevicesettings.h
index d30a57f161..2565bfad2b 100644
--- a/indra/newview/llfloatervoicedevicesettings.h
+++ b/indra/newview/llfloatervoicedevicesettings.h
@@ -36,8 +36,6 @@
#include "llfloater.h"
-class LLPrefsVoiceLogic;
-
class LLPanelVoiceDeviceSettings : public LLPanel
{
public:
@@ -49,8 +47,8 @@ public:
void apply();
void cancel();
void refresh();
- void onOpen();
- void onClose(bool app_quitting);
+ void initialize();
+ void cleanup();
protected:
static void onCommitInputDevice(LLUICtrl* ctrl, void* user_data);
@@ -64,19 +62,26 @@ protected:
BOOL mDevicesUpdated;
};
-class LLFloaterVoiceDeviceSettings : public LLFloater, public LLFloaterSingleton<LLFloaterVoiceDeviceSettings>
+class LLFloaterVoiceDeviceSettings : public LLFloater
{
+ friend class LLFloaterReg;
+
public:
- LLFloaterVoiceDeviceSettings(const LLSD& seed);
- /*virtual*/ void onOpen();
- /*virtual*/ void onClose(bool app_quitting);
+
+ virtual BOOL postBuild();
+ /*virtual*/ void onOpen(const LLSD& key);
/*virtual*/ void draw();
void apply();
void cancel();
-
+private:
+ LLFloaterVoiceDeviceSettings(const LLSD& seed);
+
protected:
static void* createPanelVoiceDeviceSettings(void* user_data);
-
+
+ void onClose();
+
+protected:
LLPanelVoiceDeviceSettings* mDevicePanel;
};
diff --git a/indra/newview/llfloaterwater.cpp b/indra/newview/llfloaterwater.cpp
index 730c1393ca..72c82c178b 100644
--- a/indra/newview/llfloaterwater.cpp
+++ b/indra/newview/llfloaterwater.cpp
@@ -37,6 +37,7 @@
#include "pipeline.h"
#include "llsky.h"
+#include "llfloaterreg.h"
#include "llsliderctrl.h"
#include "llspinctrl.h"
#include "llcolorswatch.h"
@@ -62,19 +63,36 @@
#undef max
-LLFloaterWater* LLFloaterWater::sWaterMenu = NULL;
-
std::set<std::string> LLFloaterWater::sDefaultPresets;
-LLFloaterWater::LLFloaterWater() : LLFloater(std::string("water floater"))
+LLFloaterWater::LLFloaterWater(const LLSD& key)
+ : LLFloater(key)
+{
+ //LLUICtrlFactory::getInstance()->buildFloater(this, "floater_water.xml");
+}
+
+LLFloaterWater::~LLFloaterWater()
{
- LLUICtrlFactory::getInstance()->buildFloater(this, "floater_water.xml");
+}
+BOOL LLFloaterWater::postBuild()
+{
+
+ std::string def_water = getString("WLDefaultWaterNames");
+
+ // no editing or deleting of the blank string
+ sDefaultPresets.insert("");
+ boost_tokenizer tokens(def_water, boost::char_separator<char>(":"));
+ for (boost_tokenizer::iterator token_iter = tokens.begin(); token_iter != tokens.end(); ++token_iter)
+ {
+ std::string tok(*token_iter);
+ sDefaultPresets.insert(tok);
+ }
// add the combo boxes
LLComboBox* comboBox = getChild<LLComboBox>("WaterPresetsCombo");
if(comboBox != NULL) {
-
+
std::map<std::string, LLWaterParamSet>::iterator mIt =
LLWaterParamManager::instance()->mParamList.begin();
for(; mIt != LLWaterParamManager::instance()->mParamList.end(); mIt++)
@@ -85,26 +103,11 @@ LLFloaterWater::LLFloaterWater() : LLFloater(std::string("water floater"))
// set defaults on combo boxes
comboBox->selectByValue(LLSD("Default"));
}
-
- std::string def_water = getString("WLDefaultWaterNames");
-
- // no editing or deleting of the blank string
- sDefaultPresets.insert("");
- boost_tokenizer tokens(def_water, boost::char_separator<char>(":"));
- for (boost_tokenizer::iterator token_iter = tokens.begin(); token_iter != tokens.end(); ++token_iter)
- {
- std::string tok(*token_iter);
- sDefaultPresets.insert(tok);
- }
-
// load it up
initCallbacks();
+ syncMenu();
+ return TRUE;
}
-
-LLFloaterWater::~LLFloaterWater()
-{
-}
-
void LLFloaterWater::initCallbacks(void) {
// help buttons
@@ -126,63 +129,58 @@ void LLFloaterWater::initCallbacks(void) {
LLWaterParamManager * param_mgr = LLWaterParamManager::instance();
- childSetCommitCallback("WaterFogColor", onWaterFogColorMoved, &param_mgr->mFogColor);
+ getChild<LLUICtrl>("WaterFogColor")->setCommitCallback(boost::bind(&LLFloaterWater::onWaterFogColorMoved, this, _1, &param_mgr->mFogColor));
//
- childSetCommitCallback("WaterGlow", onColorControlAMoved, &param_mgr->mFogColor);
+ getChild<LLUICtrl>("WaterGlow")->setCommitCallback(boost::bind(&LLFloaterWater::onColorControlAMoved, this, _1, &param_mgr->mFogColor));
// fog density
- childSetCommitCallback("WaterFogDensity", onExpFloatControlMoved, &param_mgr->mFogDensity);
- childSetCommitCallback("WaterUnderWaterFogMod", onFloatControlMoved, &param_mgr->mUnderWaterFogMod);
+ getChild<LLUICtrl>("WaterFogDensity")->setCommitCallback(boost::bind(&LLFloaterWater::onExpFloatControlMoved, this, _1, &param_mgr->mFogDensity));
+ getChild<LLUICtrl>("WaterUnderWaterFogMod")->setCommitCallback(boost::bind(&LLFloaterWater::onFloatControlMoved, this, _1, &param_mgr->mUnderWaterFogMod));
// blue density
- childSetCommitCallback("WaterNormalScaleX", onVector3ControlXMoved, &param_mgr->mNormalScale);
- childSetCommitCallback("WaterNormalScaleY", onVector3ControlYMoved, &param_mgr->mNormalScale);
- childSetCommitCallback("WaterNormalScaleZ", onVector3ControlZMoved, &param_mgr->mNormalScale);
+ getChild<LLUICtrl>("WaterNormalScaleX")->setCommitCallback(boost::bind(&LLFloaterWater::onVector3ControlXMoved, this, _1, &param_mgr->mNormalScale));
+ getChild<LLUICtrl>("WaterNormalScaleY")->setCommitCallback(boost::bind(&LLFloaterWater::onVector3ControlYMoved, this, _1, &param_mgr->mNormalScale));
+ getChild<LLUICtrl>("WaterNormalScaleZ")->setCommitCallback(boost::bind(&LLFloaterWater::onVector3ControlZMoved, this, _1, &param_mgr->mNormalScale));
// fresnel
- childSetCommitCallback("WaterFresnelScale", onFloatControlMoved, &param_mgr->mFresnelScale);
- childSetCommitCallback("WaterFresnelOffset", onFloatControlMoved, &param_mgr->mFresnelOffset);
+ getChild<LLUICtrl>("WaterFresnelScale")->setCommitCallback(boost::bind(&LLFloaterWater::onFloatControlMoved, this, _1, &param_mgr->mFresnelScale));
+ getChild<LLUICtrl>("WaterFresnelOffset")->setCommitCallback(boost::bind(&LLFloaterWater::onFloatControlMoved, this, _1, &param_mgr->mFresnelOffset));
// scale above/below
- childSetCommitCallback("WaterScaleAbove", onFloatControlMoved, &param_mgr->mScaleAbove);
- childSetCommitCallback("WaterScaleBelow", onFloatControlMoved, &param_mgr->mScaleBelow);
+ getChild<LLUICtrl>("WaterScaleAbove")->setCommitCallback(boost::bind(&LLFloaterWater::onFloatControlMoved, this, _1, &param_mgr->mScaleAbove));
+ getChild<LLUICtrl>("WaterScaleBelow")->setCommitCallback(boost::bind(&LLFloaterWater::onFloatControlMoved, this, _1, &param_mgr->mScaleBelow));
// blur mult
- childSetCommitCallback("WaterBlurMult", onFloatControlMoved, &param_mgr->mBlurMultiplier);
+ getChild<LLUICtrl>("WaterBlurMult")->setCommitCallback(boost::bind(&LLFloaterWater::onFloatControlMoved, this, _1, &param_mgr->mBlurMultiplier));
// Load/save
- LLComboBox* comboBox = getChild<LLComboBox>("WaterPresetsCombo");
-
- //childSetAction("WaterLoadPreset", onLoadPreset, comboBox);
- childSetAction("WaterNewPreset", onNewPreset, comboBox);
- childSetAction("WaterSavePreset", onSavePreset, comboBox);
- childSetAction("WaterDeletePreset", onDeletePreset, comboBox);
+// getChild<LLUICtrl>("WaterLoadPreset")->setCommitCallback(boost::bind(&LLFloaterWater::onLoadPreset, this));
+ getChild<LLUICtrl>("WaterNewPreset")->setCommitCallback(boost::bind(&LLFloaterWater::onNewPreset, this));
+ getChild<LLUICtrl>("WaterSavePreset")->setCommitCallback(boost::bind(&LLFloaterWater::onSavePreset, this));
+ getChild<LLUICtrl>("WaterDeletePreset")->setCommitCallback(boost::bind(&LLFloaterWater::onDeletePreset, this));
// wave direction
- childSetCommitCallback("WaterWave1DirX", onVector2ControlXMoved, &param_mgr->mWave1Dir);
- childSetCommitCallback("WaterWave1DirY", onVector2ControlYMoved, &param_mgr->mWave1Dir);
- childSetCommitCallback("WaterWave2DirX", onVector2ControlXMoved, &param_mgr->mWave2Dir);
- childSetCommitCallback("WaterWave2DirY", onVector2ControlYMoved, &param_mgr->mWave2Dir);
+ getChild<LLUICtrl>("WaterWave1DirX")->setCommitCallback(boost::bind(&LLFloaterWater::onVector2ControlXMoved, this, _1, &param_mgr->mWave1Dir));
+ getChild<LLUICtrl>("WaterWave1DirY")->setCommitCallback(boost::bind(&LLFloaterWater::onVector2ControlYMoved, this, _1, &param_mgr->mWave1Dir));
+ getChild<LLUICtrl>("WaterWave2DirX")->setCommitCallback(boost::bind(&LLFloaterWater::onVector2ControlXMoved, this, _1, &param_mgr->mWave2Dir));
+ getChild<LLUICtrl>("WaterWave2DirY")->setCommitCallback(boost::bind(&LLFloaterWater::onVector2ControlYMoved, this, _1, &param_mgr->mWave2Dir));
- comboBox->setCommitCallback(onChangePresetName);
+ getChild<LLUICtrl>("WaterPresetsCombo")->setCommitCallback(boost::bind(&LLFloaterWater::onChangePresetName, this, _1));
LLTextureCtrl* textCtrl = getChild<LLTextureCtrl>("WaterNormalMap");
textCtrl->setDefaultImageAssetID(DEFAULT_WATER_NORMAL);
- childSetCommitCallback("WaterNormalMap", onNormalMapPicked, NULL);
+ getChild<LLUICtrl>("WaterNormalMap")->setCommitCallback(boost::bind(&LLFloaterWater::onNormalMapPicked, this, _1));
}
-void LLFloaterWater::onClickHelp(void* data)
+void LLFloaterWater::onClickHelp(std::string xml_alert)
{
- LLFloaterWater* self = LLFloaterWater::instance();
-
- const std::string* xml_alert = (std::string*)data;
- LLNotifications::instance().add(self->contextualNotification(*xml_alert));
+ LLNotifications::instance().add(contextualNotification(xml_alert));
}
void LLFloaterWater::initHelpBtn(const std::string& name, const std::string& xml_alert)
{
- childSetAction(name, onClickHelp, new std::string(xml_alert));
+ getChild<LLButton>(name)->setClickedCallback(boost::bind(&LLFloaterWater::onClickHelp, this, xml_alert));
}
bool LLFloaterWater::newPromptCallback(const LLSD& notification, const LLSD& response)
@@ -196,7 +194,7 @@ bool LLFloaterWater::newPromptCallback(const LLSD& notification, const LLSD& res
}
if(option == 0) {
- LLComboBox* comboBox = sWaterMenu->getChild<LLComboBox>( "WaterPresetsCombo");
+ LLComboBox* comboBox = getChild<LLComboBox>( "WaterPresetsCombo");
LLWaterParamManager * param_mgr = LLWaterParamManager::instance();
@@ -240,7 +238,7 @@ void LLFloaterWater::syncMenu()
LLColor4 col = param_mgr->getFogColor();
childSetValue("WaterGlow", col.mV[3]);
col.mV[3] = 1.0f;
- LLColorSwatchCtrl* colCtrl = sWaterMenu->getChild<LLColorSwatchCtrl>("WaterFogColor");
+ LLColorSwatchCtrl* colCtrl = getChild<LLColorSwatchCtrl>("WaterFogColor");
colCtrl->set(col);
@@ -285,56 +283,15 @@ void LLFloaterWater::syncMenu()
childSetValue("WaterWave2DirX", param_mgr->mWave2Dir.mX);
childSetValue("WaterWave2DirY", param_mgr->mWave2Dir.mY);
- LLTextureCtrl* textCtrl = sWaterMenu->getChild<LLTextureCtrl>("WaterNormalMap");
+ LLTextureCtrl* textCtrl = getChild<LLTextureCtrl>("WaterNormalMap");
textCtrl->setImageAssetID(param_mgr->getNormalMapID());
}
-// static
-LLFloaterWater* LLFloaterWater::instance()
-{
- if (!sWaterMenu)
- {
- sWaterMenu = new LLFloaterWater();
- sWaterMenu->open();
- sWaterMenu->setFocus(TRUE);
- }
- return sWaterMenu;
-}
-void LLFloaterWater::show()
-{
- LLFloaterWater* water = instance();
- water->syncMenu();
-
- // comment in if you want the menu to rebuild each time
- //LLUICtrlFactory::getInstance()->buildFloater(water, "floater_water.xml");
- //water->initCallbacks();
-
- water->open();
-}
-
-bool LLFloaterWater::isOpen()
-{
- if (sWaterMenu != NULL) {
- return true;
- }
- return false;
-}
-
-// virtual
-void LLFloaterWater::onClose(bool app_quitting)
-{
- if (sWaterMenu)
- {
- sWaterMenu->setVisible(FALSE);
- }
-}
-
// vector control callbacks
-void LLFloaterWater::onVector3ControlXMoved(LLUICtrl* ctrl, void* userData)
+void LLFloaterWater::onVector3ControlXMoved(LLUICtrl* ctrl, WaterVector3Control* vectorControl)
{
LLSliderCtrl* sldrCtrl = static_cast<LLSliderCtrl*>(ctrl);
- WaterVector3Control * vectorControl = static_cast<WaterVector3Control *>(userData);
vectorControl->mX = sldrCtrl->getValueF32();
@@ -344,10 +301,9 @@ void LLFloaterWater::onVector3ControlXMoved(LLUICtrl* ctrl, void* userData)
}
// vector control callbacks
-void LLFloaterWater::onVector3ControlYMoved(LLUICtrl* ctrl, void* userData)
+void LLFloaterWater::onVector3ControlYMoved(LLUICtrl* ctrl, WaterVector3Control* vectorControl)
{
LLSliderCtrl* sldrCtrl = static_cast<LLSliderCtrl*>(ctrl);
- WaterVector3Control * vectorControl = static_cast<WaterVector3Control *>(userData);
vectorControl->mY = sldrCtrl->getValueF32();
@@ -357,10 +313,9 @@ void LLFloaterWater::onVector3ControlYMoved(LLUICtrl* ctrl, void* userData)
}
// vector control callbacks
-void LLFloaterWater::onVector3ControlZMoved(LLUICtrl* ctrl, void* userData)
+void LLFloaterWater::onVector3ControlZMoved(LLUICtrl* ctrl, WaterVector3Control* vectorControl)
{
LLSliderCtrl* sldrCtrl = static_cast<LLSliderCtrl*>(ctrl);
- WaterVector3Control * vectorControl = static_cast<WaterVector3Control *>(userData);
vectorControl->mZ = sldrCtrl->getValueF32();
@@ -371,10 +326,9 @@ void LLFloaterWater::onVector3ControlZMoved(LLUICtrl* ctrl, void* userData)
// vector control callbacks
-void LLFloaterWater::onVector2ControlXMoved(LLUICtrl* ctrl, void* userData)
+void LLFloaterWater::onVector2ControlXMoved(LLUICtrl* ctrl, WaterVector2Control* vectorControl)
{
LLSliderCtrl* sldrCtrl = static_cast<LLSliderCtrl*>(ctrl);
- WaterVector2Control * vectorControl = static_cast<WaterVector2Control *>(userData);
vectorControl->mX = sldrCtrl->getValueF32();
@@ -384,10 +338,9 @@ void LLFloaterWater::onVector2ControlXMoved(LLUICtrl* ctrl, void* userData)
}
// vector control callbacks
-void LLFloaterWater::onVector2ControlYMoved(LLUICtrl* ctrl, void* userData)
+void LLFloaterWater::onVector2ControlYMoved(LLUICtrl* ctrl, WaterVector2Control* vectorControl)
{
LLSliderCtrl* sldrCtrl = static_cast<LLSliderCtrl*>(ctrl);
- WaterVector2Control * vectorControl = static_cast<WaterVector2Control *>(userData);
vectorControl->mY = sldrCtrl->getValueF32();
@@ -397,10 +350,9 @@ void LLFloaterWater::onVector2ControlYMoved(LLUICtrl* ctrl, void* userData)
}
// color control callbacks
-void LLFloaterWater::onColorControlRMoved(LLUICtrl* ctrl, void* userData)
+void LLFloaterWater::onColorControlRMoved(LLUICtrl* ctrl, WaterColorControl* colorControl)
{
LLSliderCtrl* sldrCtrl = static_cast<LLSliderCtrl*>(ctrl);
- WaterColorControl * colorControl = static_cast<WaterColorControl *>(userData);
colorControl->mR = sldrCtrl->getValueF32();
@@ -413,7 +365,7 @@ void LLFloaterWater::onColorControlRMoved(LLUICtrl* ctrl, void* userData)
std::string name = colorControl->mSliderName;
name.append("I");
- sWaterMenu->childSetValue(name, colorControl->mR);
+ childSetValue(name, colorControl->mR);
}
colorControl->update(LLWaterParamManager::instance()->mCurParams);
@@ -421,10 +373,9 @@ void LLFloaterWater::onColorControlRMoved(LLUICtrl* ctrl, void* userData)
LLWaterParamManager::instance()->propagateParameters();
}
-void LLFloaterWater::onColorControlGMoved(LLUICtrl* ctrl, void* userData)
+void LLFloaterWater::onColorControlGMoved(LLUICtrl* ctrl, WaterColorControl* colorControl)
{
LLSliderCtrl* sldrCtrl = static_cast<LLSliderCtrl*>(ctrl);
- WaterColorControl * colorControl = static_cast<WaterColorControl *>(userData);
colorControl->mG = sldrCtrl->getValueF32();
@@ -437,7 +388,7 @@ void LLFloaterWater::onColorControlGMoved(LLUICtrl* ctrl, void* userData)
std::string name = colorControl->mSliderName;
name.append("I");
- sWaterMenu->childSetValue(name, colorControl->mG);
+ childSetValue(name, colorControl->mG);
}
@@ -446,10 +397,9 @@ void LLFloaterWater::onColorControlGMoved(LLUICtrl* ctrl, void* userData)
LLWaterParamManager::instance()->propagateParameters();
}
-void LLFloaterWater::onColorControlBMoved(LLUICtrl* ctrl, void* userData)
+void LLFloaterWater::onColorControlBMoved(LLUICtrl* ctrl, WaterColorControl* colorControl)
{
LLSliderCtrl* sldrCtrl = static_cast<LLSliderCtrl*>(ctrl);
- WaterColorControl * colorControl = static_cast<WaterColorControl *>(userData);
colorControl->mB = sldrCtrl->getValueF32();
@@ -462,7 +412,7 @@ void LLFloaterWater::onColorControlBMoved(LLUICtrl* ctrl, void* userData)
std::string name = colorControl->mSliderName;
name.append("I");
- sWaterMenu->childSetValue(name, colorControl->mB);
+ childSetValue(name, colorControl->mB);
}
colorControl->update(LLWaterParamManager::instance()->mCurParams);
@@ -470,10 +420,9 @@ void LLFloaterWater::onColorControlBMoved(LLUICtrl* ctrl, void* userData)
LLWaterParamManager::instance()->propagateParameters();
}
-void LLFloaterWater::onColorControlAMoved(LLUICtrl* ctrl, void* userData)
+void LLFloaterWater::onColorControlAMoved(LLUICtrl* ctrl, WaterColorControl* colorControl)
{
LLSliderCtrl* sldrCtrl = static_cast<LLSliderCtrl*>(ctrl);
- WaterColorControl * colorControl = static_cast<WaterColorControl *>(userData);
colorControl->mA = sldrCtrl->getValueF32();
@@ -483,10 +432,9 @@ void LLFloaterWater::onColorControlAMoved(LLUICtrl* ctrl, void* userData)
}
-void LLFloaterWater::onColorControlIMoved(LLUICtrl* ctrl, void* userData)
+void LLFloaterWater::onColorControlIMoved(LLUICtrl* ctrl, WaterColorControl* colorControl)
{
LLSliderCtrl* sldrCtrl = static_cast<LLSliderCtrl*>(ctrl);
- WaterColorControl * colorControl = static_cast<WaterColorControl *>(userData);
colorControl->mI = sldrCtrl->getValueF32();
@@ -533,9 +481,9 @@ void LLFloaterWater::onColorControlIMoved(LLUICtrl* ctrl, void* userData)
}
// set the sliders to the new vals
- sWaterMenu->childSetValue(rName, colorControl->mR);
- sWaterMenu->childSetValue(gName, colorControl->mG);
- sWaterMenu->childSetValue(bName, colorControl->mB);
+ childSetValue(rName, colorControl->mR);
+ childSetValue(gName, colorControl->mG);
+ childSetValue(bName, colorControl->mB);
}
// now update the current parameters and send them to shaders
@@ -543,10 +491,9 @@ void LLFloaterWater::onColorControlIMoved(LLUICtrl* ctrl, void* userData)
LLWaterParamManager::instance()->propagateParameters();
}
-void LLFloaterWater::onExpFloatControlMoved(LLUICtrl* ctrl, void* userData)
+void LLFloaterWater::onExpFloatControlMoved(LLUICtrl* ctrl, WaterExpFloatControl* expFloatControl)
{
LLSliderCtrl* sldrCtrl = static_cast<LLSliderCtrl*>(ctrl);
- WaterExpFloatControl * expFloatControl = static_cast<WaterExpFloatControl *>(userData);
F32 val = sldrCtrl->getValueF32();
expFloatControl->mExp = val;
@@ -556,50 +503,40 @@ void LLFloaterWater::onExpFloatControlMoved(LLUICtrl* ctrl, void* userData)
LLWaterParamManager::instance()->propagateParameters();
}
-void LLFloaterWater::onFloatControlMoved(LLUICtrl* ctrl, void* userData)
+void LLFloaterWater::onFloatControlMoved(LLUICtrl* ctrl, WaterFloatControl* floatControl)
{
LLSliderCtrl* sldrCtrl = static_cast<LLSliderCtrl*>(ctrl);
- WaterFloatControl * floatControl = static_cast<WaterFloatControl *>(userData);
floatControl->mX = sldrCtrl->getValueF32() / floatControl->mMult;
floatControl->update(LLWaterParamManager::instance()->mCurParams);
LLWaterParamManager::instance()->propagateParameters();
}
-void LLFloaterWater::onWaterFogColorMoved(LLUICtrl* ctrl, void* userData)
+void LLFloaterWater::onWaterFogColorMoved(LLUICtrl* ctrl, WaterColorControl* colorControl)
{
LLColorSwatchCtrl* swatch = static_cast<LLColorSwatchCtrl*>(ctrl);
- WaterColorControl * colorControl = static_cast<WaterColorControl *>(userData);
*colorControl = swatch->get();
colorControl->update(LLWaterParamManager::instance()->mCurParams);
LLWaterParamManager::instance()->propagateParameters();
}
-void LLFloaterWater::onBoolToggle(LLUICtrl* ctrl, void* userData)
-{
- LLCheckBoxCtrl* cbCtrl = static_cast<LLCheckBoxCtrl*>(ctrl);
-
- bool value = cbCtrl->get();
- (*(static_cast<BOOL *>(userData))) = value;
-}
-
-void LLFloaterWater::onNormalMapPicked(LLUICtrl* ctrl, void* userData)
+void LLFloaterWater::onNormalMapPicked(LLUICtrl* ctrl)
{
LLTextureCtrl* textCtrl = static_cast<LLTextureCtrl*>(ctrl);
LLUUID textID = textCtrl->getImageAssetID();
LLWaterParamManager::instance()->setNormalMapID(textID);
}
-void LLFloaterWater::onNewPreset(void* userData)
+void LLFloaterWater::onNewPreset()
{
- LLNotifications::instance().add("NewWaterPreset", LLSD(), LLSD(), newPromptCallback);
+ LLNotifications::instance().add("NewWaterPreset", LLSD(), LLSD(), boost::bind(&LLFloaterWater::newPromptCallback, this, _1, _2));
}
-void LLFloaterWater::onSavePreset(void* userData)
+void LLFloaterWater::onSavePreset()
{
// get the name
- LLComboBox* comboBox = sWaterMenu->getChild<LLComboBox>("WaterPresetsCombo");
+ LLComboBox* comboBox = getChild<LLComboBox>("WaterPresetsCombo");
// don't save the empty name
if(comboBox->getSelectedItemLabel() == "")
@@ -619,7 +556,7 @@ void LLFloaterWater::onSavePreset(void* userData)
return;
}
- LLNotifications::instance().add("WLSavePresetAlert", LLSD(), LLSD(), saveAlertCallback);
+ LLNotifications::instance().add("WLSavePresetAlert", LLSD(), LLSD(), boost::bind(&LLFloaterWater::saveAlertCallback, this, _1, _2));
}
bool LLFloaterWater::saveAlertCallback(const LLSD& notification, const LLSD& response)
@@ -640,9 +577,9 @@ bool LLFloaterWater::saveAlertCallback(const LLSD& notification, const LLSD& res
return false;
}
-void LLFloaterWater::onDeletePreset(void* userData)
+void LLFloaterWater::onDeletePreset()
{
- LLComboBox* combo_box = sWaterMenu->getChild<LLComboBox>("WaterPresetsCombo");
+ LLComboBox* combo_box = getChild<LLComboBox>("WaterPresetsCombo");
if(combo_box->getSelectedValue().asString() == "")
{
@@ -651,7 +588,7 @@ void LLFloaterWater::onDeletePreset(void* userData)
LLSD args;
args["SKY"] = combo_box->getSelectedValue().asString();
- LLNotifications::instance().add("WLDeletePresetAlert", args, LLSD(), deleteAlertCallback);
+ LLNotifications::instance().add("WLDeletePresetAlert", args, LLSD(), boost::bind(&LLFloaterWater::deleteAlertCallback, this, _1, _2));
}
bool LLFloaterWater::deleteAlertCallback(const LLSD& notification, const LLSD& response)
@@ -660,14 +597,13 @@ bool LLFloaterWater::deleteAlertCallback(const LLSD& notification, const LLSD& r
// if they choose delete, do it. Otherwise, don't do anything
if(option == 0)
{
- LLComboBox* combo_box = sWaterMenu->getChild<LLComboBox>("WaterPresetsCombo");
- LLFloaterDayCycle* day_cycle = NULL;
+ LLComboBox* combo_box = getChild<LLComboBox>("WaterPresetsCombo");
+ LLFloaterDayCycle* day_cycle = LLFloaterReg::findTypedInstance<LLFloaterDayCycle>("env_day_cycle");
LLComboBox* key_combo = NULL;
LLMultiSliderCtrl* mult_sldr = NULL;
- if(LLFloaterDayCycle::isOpen())
+ if (day_cycle)
{
- day_cycle = LLFloaterDayCycle::instance();
key_combo = day_cycle->getChild<LLComboBox>("WaterKeyPresets");
mult_sldr = day_cycle->getChild<LLMultiSliderCtrl>("WaterDayCycleKeys");
}
@@ -712,17 +648,13 @@ bool LLFloaterWater::deleteAlertCallback(const LLSD& notification, const LLSD& r
}
-void LLFloaterWater::onChangePresetName(LLUICtrl* ctrl, void * userData)
+void LLFloaterWater::onChangePresetName(LLUICtrl* ctrl)
{
- LLComboBox * combo_box = static_cast<LLComboBox*>(ctrl);
-
- if(combo_box->getSimple() == "")
+ std::string data = ctrl->getValue().asString();
+ if(!data.empty())
{
- return;
+ LLWaterParamManager::instance()->loadPreset(data);
+ syncMenu();
}
-
- LLWaterParamManager::instance()->loadPreset(
- combo_box->getSelectedValue().asString());
- sWaterMenu->syncMenu();
}
diff --git a/indra/newview/llfloaterwater.h b/indra/newview/llfloaterwater.h
index 774d5c5a75..08c630c69e 100644
--- a/indra/newview/llfloaterwater.h
+++ b/indra/newview/llfloaterwater.h
@@ -42,91 +42,74 @@
#include <vector>
#include "llwlparamset.h"
+struct WaterVector2Control;
+struct WaterVector3Control;
struct WaterColorControl;
-struct WaterloatControl;
-
+struct WaterFloatControl;
+struct WaterExpFloatControl;
/// Menuing system for all of windlight's functionality
class LLFloaterWater : public LLFloater
{
public:
- LLFloaterWater();
+ LLFloaterWater(const LLSD& key);
virtual ~LLFloaterWater();
-
+ /*virtual*/ BOOL postBuild();
/// initialize all
void initCallbacks(void);
- /// one and one instance only
- static LLFloaterWater* instance();
-
// help button stuff
- static void onClickHelp(void* data);
+ void onClickHelp(std::string xml_alert);
void initHelpBtn(const std::string& name, const std::string& xml_alert);
- static bool newPromptCallback(const LLSD& notification, const LLSD& response);
+ bool newPromptCallback(const LLSD& notification, const LLSD& response);
/// general purpose callbacks for dealing with color controllers
- static void onColorControlRMoved(LLUICtrl* ctrl, void* userData);
- static void onColorControlGMoved(LLUICtrl* ctrl, void* userData);
- static void onColorControlBMoved(LLUICtrl* ctrl, void* userData);
- static void onColorControlAMoved(LLUICtrl* ctrl, void* userData);
- static void onColorControlIMoved(LLUICtrl* ctrl, void* userData);
-
- static void onVector3ControlXMoved(LLUICtrl* ctrl, void* userData);
- static void onVector3ControlYMoved(LLUICtrl* ctrl, void* userData);
- static void onVector3ControlZMoved(LLUICtrl* ctrl, void* userData);
-
- static void onVector2ControlXMoved(LLUICtrl* ctrl, void* userData);
- static void onVector2ControlYMoved(LLUICtrl* ctrl, void* userData);
-
- static void onFloatControlMoved(LLUICtrl* ctrl, void* userData);
-
- static void onExpFloatControlMoved(LLUICtrl* ctrl, void* userData);
+ void onColorControlRMoved(LLUICtrl* ctrl, WaterColorControl* colorControl);
+ void onColorControlGMoved(LLUICtrl* ctrl, WaterColorControl* colorControl);
+ void onColorControlBMoved(LLUICtrl* ctrl, WaterColorControl* colorControl);
+ void onColorControlAMoved(LLUICtrl* ctrl, WaterColorControl* colorControl);
+ void onColorControlIMoved(LLUICtrl* ctrl, WaterColorControl* colorControl);
+
+ void onVector3ControlXMoved(LLUICtrl* ctrl, WaterVector3Control* vectorControl);
+ void onVector3ControlYMoved(LLUICtrl* ctrl, WaterVector3Control* vectorControl);
+ void onVector3ControlZMoved(LLUICtrl* ctrl, WaterVector3Control* vectorControl);
+
+ void onVector2ControlXMoved(LLUICtrl* ctrl, WaterVector2Control* vectorControl);
+ void onVector2ControlYMoved(LLUICtrl* ctrl, WaterVector2Control* vectorControl);
+
+ void onFloatControlMoved(LLUICtrl* ctrl, WaterFloatControl* floatControl);
- static void onWaterFogColorMoved(LLUICtrl* ctrl, void* userData);
+ void onExpFloatControlMoved(LLUICtrl* ctrl, WaterExpFloatControl* expFloatControl);
- static void onBoolToggle(LLUICtrl* ctrl, void* userData);
+ void onWaterFogColorMoved(LLUICtrl* ctrl, WaterColorControl* colorControl);
/// handle if they choose a new normal map
- static void onNormalMapPicked(LLUICtrl* ctrl, void* userData);
+ void onNormalMapPicked(LLUICtrl* ctrl);
/// when user hits the load preset button
- static void onNewPreset(void* userData);
+ void onNewPreset();
/// when user hits the save preset button
- static void onSavePreset(void* userData);
+ void onSavePreset();
/// prompts a user when overwriting a preset
- static bool saveAlertCallback(const LLSD& notification, const LLSD& response);
+ bool saveAlertCallback(const LLSD& notification, const LLSD& response);
/// when user hits the save preset button
- static void onDeletePreset(void* userData);
+ void onDeletePreset();
/// prompts a user when overwriting a preset
- static bool deleteAlertCallback(const LLSD& notification, const LLSD& response);
+ bool deleteAlertCallback(const LLSD& notification, const LLSD& response);
/// what to do when you change the preset name
- static void onChangePresetName(LLUICtrl* ctrl, void* userData);
-
- //// menu management
-
- /// show off our menu
- static void show();
-
- /// return if the menu exists or not
- static bool isOpen();
-
- /// stuff to do on exit
- virtual void onClose(bool app_quitting);
+ void onChangePresetName(LLUICtrl* ctrl);
/// sync up sliders with parameters
void syncMenu();
private:
- // one instance on the inside
- static LLFloaterWater* sWaterMenu;
-
static std::set<std::string> sDefaultPresets;
};
diff --git a/indra/newview/llfloaterwindlight.cpp b/indra/newview/llfloaterwindlight.cpp
index 98b315795a..18745284cb 100644
--- a/indra/newview/llfloaterwindlight.cpp
+++ b/indra/newview/llfloaterwindlight.cpp
@@ -37,6 +37,7 @@
#include "pipeline.h"
#include "llsky.h"
+#include "llfloaterreg.h"
#include "llsliderctrl.h"
#include "llmultislider.h"
#include "llmultisliderctrl.h"
@@ -61,21 +62,39 @@
#undef max
-LLFloaterWindLight* LLFloaterWindLight::sWindLight = NULL;
-
std::set<std::string> LLFloaterWindLight::sDefaultPresets;
static const F32 WL_SUN_AMBIENT_SLIDER_SCALE = 3.0f;
-LLFloaterWindLight::LLFloaterWindLight() : LLFloater(std::string("windlight floater"))
+LLFloaterWindLight::LLFloaterWindLight(const LLSD& key)
+ : LLFloater(key)
{
- LLUICtrlFactory::getInstance()->buildFloater(this, "floater_windlight_options.xml");
-
+ //LLUICtrlFactory::getInstance()->buildFloater(this, "floater_windlight_options.xml");
+}
+
+LLFloaterWindLight::~LLFloaterWindLight()
+{
+}
+
+BOOL LLFloaterWindLight::postBuild()
+{
+ // add the list of presets
+ std::string def_days = getString("WLDefaultSkyNames");
+
+ // no editing or deleting of the blank string
+ sDefaultPresets.insert("");
+ boost_tokenizer tokens(def_days, boost::char_separator<char>(":"));
+ for (boost_tokenizer::iterator token_iter = tokens.begin(); token_iter != tokens.end(); ++token_iter)
+ {
+ std::string tok(*token_iter);
+ sDefaultPresets.insert(tok);
+ }
+
// add the combo boxes
LLComboBox* comboBox = getChild<LLComboBox>("WLPresetsCombo");
if(comboBox != NULL) {
-
+
std::map<std::string, LLWLParamSet>::iterator mIt =
LLWLParamManager::instance()->mParamList.begin();
for(; mIt != LLWLParamManager::instance()->mParamList.end(); mIt++)
@@ -89,27 +108,13 @@ LLFloaterWindLight::LLFloaterWindLight() : LLFloater(std::string("windlight floa
// set defaults on combo boxes
comboBox->selectByValue(LLSD("Default"));
}
-
- // add the list of presets
- std::string def_days = getString("WLDefaultSkyNames");
-
- // no editing or deleting of the blank string
- sDefaultPresets.insert("");
- boost_tokenizer tokens(def_days, boost::char_separator<char>(":"));
- for (boost_tokenizer::iterator token_iter = tokens.begin(); token_iter != tokens.end(); ++token_iter)
- {
- std::string tok(*token_iter);
- sDefaultPresets.insert(tok);
- }
-
// load it up
initCallbacks();
-}
-LLFloaterWindLight::~LLFloaterWindLight()
-{
+ syncMenu();
+
+ return TRUE;
}
-
void LLFloaterWindLight::initCallbacks(void) {
// help buttons
@@ -145,102 +150,99 @@ void LLFloaterWindLight::initCallbacks(void) {
LLWLParamManager * param_mgr = LLWLParamManager::instance();
// blue horizon
- childSetCommitCallback("WLBlueHorizonR", onColorControlRMoved, &param_mgr->mBlueHorizon);
- childSetCommitCallback("WLBlueHorizonG", onColorControlGMoved, &param_mgr->mBlueHorizon);
- childSetCommitCallback("WLBlueHorizonB", onColorControlBMoved, &param_mgr->mBlueHorizon);
- childSetCommitCallback("WLBlueHorizonI", onColorControlIMoved, &param_mgr->mBlueHorizon);
+ getChild<LLUICtrl>("WLBlueHorizonR")->setCommitCallback(boost::bind(&LLFloaterWindLight::onColorControlRMoved, this, _1, &param_mgr->mBlueHorizon));
+ getChild<LLUICtrl>("WLBlueHorizonG")->setCommitCallback(boost::bind(&LLFloaterWindLight::onColorControlGMoved, this, _1, &param_mgr->mBlueHorizon));
+ getChild<LLUICtrl>("WLBlueHorizonB")->setCommitCallback(boost::bind(&LLFloaterWindLight::onColorControlBMoved, this, _1, &param_mgr->mBlueHorizon));
+ getChild<LLUICtrl>("WLBlueHorizonI")->setCommitCallback(boost::bind(&LLFloaterWindLight::onColorControlIMoved, this, _1, &param_mgr->mBlueHorizon));
// haze density, horizon, mult, and altitude
- childSetCommitCallback("WLHazeDensity", onColorControlRMoved, &param_mgr->mHazeDensity);
- childSetCommitCallback("WLHazeHorizon", onColorControlRMoved, &param_mgr->mHazeHorizon);
- childSetCommitCallback("WLDensityMult", onFloatControlMoved, &param_mgr->mDensityMult);
- childSetCommitCallback("WLMaxAltitude", onFloatControlMoved, &param_mgr->mMaxAlt);
+ getChild<LLUICtrl>("WLHazeDensity")->setCommitCallback(boost::bind(&LLFloaterWindLight::onColorControlRMoved, this, _1, &param_mgr->mHazeDensity));
+ getChild<LLUICtrl>("WLHazeHorizon")->setCommitCallback(boost::bind(&LLFloaterWindLight::onColorControlRMoved, this, _1, &param_mgr->mHazeHorizon));
+ getChild<LLUICtrl>("WLDensityMult")->setCommitCallback(boost::bind(&LLFloaterWindLight::onFloatControlMoved, this, _1, &param_mgr->mDensityMult));
+ getChild<LLUICtrl>("WLMaxAltitude")->setCommitCallback(boost::bind(&LLFloaterWindLight::onFloatControlMoved, this, _1, &param_mgr->mMaxAlt));
// blue density
- childSetCommitCallback("WLBlueDensityR", onColorControlRMoved, &param_mgr->mBlueDensity);
- childSetCommitCallback("WLBlueDensityG", onColorControlGMoved, &param_mgr->mBlueDensity);
- childSetCommitCallback("WLBlueDensityB", onColorControlBMoved, &param_mgr->mBlueDensity);
- childSetCommitCallback("WLBlueDensityI", onColorControlIMoved, &param_mgr->mBlueDensity);
+ getChild<LLUICtrl>("WLBlueDensityR")->setCommitCallback(boost::bind(&LLFloaterWindLight::onColorControlRMoved, this, _1, &param_mgr->mBlueDensity));
+ getChild<LLUICtrl>("WLBlueDensityG")->setCommitCallback(boost::bind(&LLFloaterWindLight::onColorControlGMoved, this, _1, &param_mgr->mBlueDensity));
+ getChild<LLUICtrl>("WLBlueDensityB")->setCommitCallback(boost::bind(&LLFloaterWindLight::onColorControlBMoved, this, _1, &param_mgr->mBlueDensity));
+ getChild<LLUICtrl>("WLBlueDensityI")->setCommitCallback(boost::bind(&LLFloaterWindLight::onColorControlIMoved, this, _1, &param_mgr->mBlueDensity));
// Lighting
// sunlight
- childSetCommitCallback("WLSunlightR", onColorControlRMoved, &param_mgr->mSunlight);
- childSetCommitCallback("WLSunlightG", onColorControlGMoved, &param_mgr->mSunlight);
- childSetCommitCallback("WLSunlightB", onColorControlBMoved, &param_mgr->mSunlight);
- childSetCommitCallback("WLSunlightI", onColorControlIMoved, &param_mgr->mSunlight);
+ getChild<LLUICtrl>("WLSunlightR")->setCommitCallback(boost::bind(&LLFloaterWindLight::onColorControlRMoved, this, _1, &param_mgr->mSunlight));
+ getChild<LLUICtrl>("WLSunlightG")->setCommitCallback(boost::bind(&LLFloaterWindLight::onColorControlGMoved, this, _1, &param_mgr->mSunlight));
+ getChild<LLUICtrl>("WLSunlightB")->setCommitCallback(boost::bind(&LLFloaterWindLight::onColorControlBMoved, this, _1, &param_mgr->mSunlight));
+ getChild<LLUICtrl>("WLSunlightI")->setCommitCallback(boost::bind(&LLFloaterWindLight::onColorControlIMoved, this, _1, &param_mgr->mSunlight));
// glow
- childSetCommitCallback("WLGlowR", onGlowRMoved, &param_mgr->mGlow);
- childSetCommitCallback("WLGlowB", onGlowBMoved, &param_mgr->mGlow);
+ getChild<LLUICtrl>("WLGlowR")->setCommitCallback(boost::bind(&LLFloaterWindLight::onGlowRMoved, this, _1, &param_mgr->mGlow));
+ getChild<LLUICtrl>("WLGlowB")->setCommitCallback(boost::bind(&LLFloaterWindLight::onGlowBMoved, this, _1, &param_mgr->mGlow));
// ambient
- childSetCommitCallback("WLAmbientR", onColorControlRMoved, &param_mgr->mAmbient);
- childSetCommitCallback("WLAmbientG", onColorControlGMoved, &param_mgr->mAmbient);
- childSetCommitCallback("WLAmbientB", onColorControlBMoved, &param_mgr->mAmbient);
- childSetCommitCallback("WLAmbientI", onColorControlIMoved, &param_mgr->mAmbient);
+ getChild<LLUICtrl>("WLAmbientR")->setCommitCallback(boost::bind(&LLFloaterWindLight::onColorControlRMoved, this, _1, &param_mgr->mAmbient));
+ getChild<LLUICtrl>("WLAmbientG")->setCommitCallback(boost::bind(&LLFloaterWindLight::onColorControlGMoved, this, _1, &param_mgr->mAmbient));
+ getChild<LLUICtrl>("WLAmbientB")->setCommitCallback(boost::bind(&LLFloaterWindLight::onColorControlBMoved, this, _1, &param_mgr->mAmbient));
+ getChild<LLUICtrl>("WLAmbientI")->setCommitCallback(boost::bind(&LLFloaterWindLight::onColorControlIMoved, this, _1, &param_mgr->mAmbient));
// time of day
- childSetCommitCallback("WLSunAngle", onSunMoved, &param_mgr->mLightnorm);
- childSetCommitCallback("WLEastAngle", onSunMoved, &param_mgr->mLightnorm);
+ getChild<LLUICtrl>("WLSunAngle")->setCommitCallback(boost::bind(&LLFloaterWindLight::onSunMoved, this, _1, &param_mgr->mLightnorm));
+ getChild<LLUICtrl>("WLEastAngle")->setCommitCallback(boost::bind(&LLFloaterWindLight::onSunMoved, this, _1, &param_mgr->mLightnorm));
// Clouds
// Cloud Color
- childSetCommitCallback("WLCloudColorR", onColorControlRMoved, &param_mgr->mCloudColor);
- childSetCommitCallback("WLCloudColorG", onColorControlGMoved, &param_mgr->mCloudColor);
- childSetCommitCallback("WLCloudColorB", onColorControlBMoved, &param_mgr->mCloudColor);
- childSetCommitCallback("WLCloudColorI", onColorControlIMoved, &param_mgr->mCloudColor);
+ getChild<LLUICtrl>("WLCloudColorR")->setCommitCallback(boost::bind(&LLFloaterWindLight::onColorControlRMoved, this, _1, &param_mgr->mCloudColor));
+ getChild<LLUICtrl>("WLCloudColorG")->setCommitCallback(boost::bind(&LLFloaterWindLight::onColorControlGMoved, this, _1, &param_mgr->mCloudColor));
+ getChild<LLUICtrl>("WLCloudColorB")->setCommitCallback(boost::bind(&LLFloaterWindLight::onColorControlBMoved, this, _1, &param_mgr->mCloudColor));
+ getChild<LLUICtrl>("WLCloudColorI")->setCommitCallback(boost::bind(&LLFloaterWindLight::onColorControlIMoved, this, _1, &param_mgr->mCloudColor));
// Cloud
- childSetCommitCallback("WLCloudX", onColorControlRMoved, &param_mgr->mCloudMain);
- childSetCommitCallback("WLCloudY", onColorControlGMoved, &param_mgr->mCloudMain);
- childSetCommitCallback("WLCloudDensity", onColorControlBMoved, &param_mgr->mCloudMain);
+ getChild<LLUICtrl>("WLCloudX")->setCommitCallback(boost::bind(&LLFloaterWindLight::onColorControlRMoved, this, _1, &param_mgr->mCloudMain));
+ getChild<LLUICtrl>("WLCloudY")->setCommitCallback(boost::bind(&LLFloaterWindLight::onColorControlGMoved, this, _1, &param_mgr->mCloudMain));
+ getChild<LLUICtrl>("WLCloudDensity")->setCommitCallback(boost::bind(&LLFloaterWindLight::onColorControlBMoved, this, _1, &param_mgr->mCloudMain));
// Cloud Detail
- childSetCommitCallback("WLCloudDetailX", onColorControlRMoved, &param_mgr->mCloudDetail);
- childSetCommitCallback("WLCloudDetailY", onColorControlGMoved, &param_mgr->mCloudDetail);
- childSetCommitCallback("WLCloudDetailDensity", onColorControlBMoved, &param_mgr->mCloudDetail);
+ getChild<LLUICtrl>("WLCloudDetailX")->setCommitCallback(boost::bind(&LLFloaterWindLight::onColorControlRMoved, this, _1, &param_mgr->mCloudDetail));
+ getChild<LLUICtrl>("WLCloudDetailY")->setCommitCallback(boost::bind(&LLFloaterWindLight::onColorControlGMoved, this, _1, &param_mgr->mCloudDetail));
+ getChild<LLUICtrl>("WLCloudDetailDensity")->setCommitCallback(boost::bind(&LLFloaterWindLight::onColorControlBMoved, this, _1, &param_mgr->mCloudDetail));
// Cloud extras
- childSetCommitCallback("WLCloudCoverage", onFloatControlMoved, &param_mgr->mCloudCoverage);
- childSetCommitCallback("WLCloudScale", onFloatControlMoved, &param_mgr->mCloudScale);
- childSetCommitCallback("WLCloudLockX", onCloudScrollXToggled, NULL);
- childSetCommitCallback("WLCloudLockY", onCloudScrollYToggled, NULL);
- childSetCommitCallback("WLCloudScrollX", onCloudScrollXMoved, NULL);
- childSetCommitCallback("WLCloudScrollY", onCloudScrollYMoved, NULL);
- childSetCommitCallback("WLDistanceMult", onFloatControlMoved, &param_mgr->mDistanceMult);
- childSetCommitCallback("DrawClassicClouds", LLSavedSettingsGlue::setBOOL, (void*)"SkyUseClassicClouds");
+ getChild<LLUICtrl>("WLCloudCoverage")->setCommitCallback(boost::bind(&LLFloaterWindLight::onFloatControlMoved, this, _1, &param_mgr->mCloudCoverage));
+ getChild<LLUICtrl>("WLCloudScale")->setCommitCallback(boost::bind(&LLFloaterWindLight::onFloatControlMoved, this, _1, &param_mgr->mCloudScale));
+ getChild<LLUICtrl>("WLCloudLockX")->setCommitCallback(boost::bind(&LLFloaterWindLight::onCloudScrollXToggled, this, _1));
+ getChild<LLUICtrl>("WLCloudLockY")->setCommitCallback(boost::bind(&LLFloaterWindLight::onCloudScrollYToggled, this, _1));
+ getChild<LLUICtrl>("WLCloudScrollX")->setCommitCallback(boost::bind(&LLFloaterWindLight::onCloudScrollXMoved, this, _1));
+ getChild<LLUICtrl>("WLCloudScrollY")->setCommitCallback(boost::bind(&LLFloaterWindLight::onCloudScrollYMoved, this, _1));
+ getChild<LLUICtrl>("WLDistanceMult")->setCommitCallback(boost::bind(&LLFloaterWindLight::onFloatControlMoved, this, _1, &param_mgr->mDistanceMult));
+ getChild<LLUICtrl>("DrawClassicClouds")->setCommitCallback(boost::bind(LLSavedSettingsGlue::setBOOL, _1, "SkyUseClassicClouds"));
// WL Top
- childSetAction("WLDayCycleMenuButton", onOpenDayCycle, NULL);
+ getChild<LLUICtrl>("WLDayCycleMenuButton")->setCommitCallback(boost::bind(&LLFloaterWindLight::onOpenDayCycle, this));
// Load/save
LLComboBox* comboBox = getChild<LLComboBox>("WLPresetsCombo");
//childSetAction("WLLoadPreset", onLoadPreset, comboBox);
- childSetAction("WLNewPreset", onNewPreset, comboBox);
- childSetAction("WLSavePreset", onSavePreset, comboBox);
- childSetAction("WLDeletePreset", onDeletePreset, comboBox);
+ getChild<LLUICtrl>("WLNewPreset")->setCommitCallback(boost::bind(&LLFloaterWindLight::onNewPreset, this));
+ getChild<LLUICtrl>("WLSavePreset")->setCommitCallback(boost::bind(&LLFloaterWindLight::onSavePreset, this));
+ getChild<LLUICtrl>("WLDeletePreset")->setCommitCallback(boost::bind(&LLFloaterWindLight::onDeletePreset, this));
- comboBox->setCommitCallback(onChangePresetName);
+ comboBox->setCommitCallback(boost::bind(&LLFloaterWindLight::onChangePresetName, this, _1));
// Dome
- childSetCommitCallback("WLGamma", onFloatControlMoved, &param_mgr->mWLGamma);
- childSetCommitCallback("WLStarAlpha", onStarAlphaMoved, NULL);
+ getChild<LLUICtrl>("WLGamma")->setCommitCallback(boost::bind(&LLFloaterWindLight::onFloatControlMoved, this, _1, &param_mgr->mWLGamma));
+ getChild<LLUICtrl>("WLStarAlpha")->setCommitCallback(boost::bind(&LLFloaterWindLight::onStarAlphaMoved, this, _1));
}
-void LLFloaterWindLight::onClickHelp(void* data)
+void LLFloaterWindLight::onClickHelp(std::string xml_alert)
{
- LLFloaterWindLight* self = LLFloaterWindLight::instance();
-
- const std::string xml_alert = *(std::string*)data;
- LLNotifications::instance().add(self->contextualNotification(xml_alert));
+ LLNotifications::instance().add(contextualNotification(xml_alert));
}
void LLFloaterWindLight::initHelpBtn(const std::string& name, const std::string& xml_alert)
{
- childSetAction(name, onClickHelp, new std::string(xml_alert));
+ getChild<LLButton>(name)->setClickedCallback(boost::bind(&LLFloaterWindLight::onClickHelp, this, xml_alert));
}
bool LLFloaterWindLight::newPromptCallback(const LLSD& notification, const LLSD& response)
@@ -254,16 +256,13 @@ bool LLFloaterWindLight::newPromptCallback(const LLSD& notification, const LLSD&
}
if(option == 0) {
- LLComboBox* comboBox = sWindLight->getChild<LLComboBox>(
- "WLPresetsCombo");
+ LLComboBox* comboBox = getChild<LLComboBox>("WLPresetsCombo");
- LLFloaterDayCycle* sDayCycle = NULL;
+ LLFloaterDayCycle* day_cycle = LLFloaterReg::findTypedInstance<LLFloaterDayCycle>("env_day_cycle");
LLComboBox* keyCombo = NULL;
- if(LLFloaterDayCycle::isOpen())
+ if(day_cycle)
{
- sDayCycle = LLFloaterDayCycle::instance();
- keyCombo = sDayCycle->getChild<LLComboBox>(
- "WLKeyPresets");
+ keyCombo = day_cycle->getChild<LLComboBox>("WLKeyPresets");
}
// add the current parameters to the list
@@ -288,7 +287,7 @@ bool LLFloaterWindLight::newPromptCallback(const LLSD& notification, const LLSD&
comboBox->add(LLStringUtil::null);
comboBox->setSelectedByValue(text, true);
- if(LLFloaterDayCycle::isOpen())
+ if(keyCombo)
{
keyCombo->add(text);
keyCombo->sortByName();
@@ -438,53 +437,12 @@ void LLFloaterWindLight::syncMenu()
}
-// static
-LLFloaterWindLight* LLFloaterWindLight::instance()
-{
- if (!sWindLight)
- {
- sWindLight = new LLFloaterWindLight();
- sWindLight->open();
- sWindLight->setFocus(TRUE);
- }
- return sWindLight;
-}
-void LLFloaterWindLight::show()
-{
- LLFloaterWindLight* windLight = instance();
- windLight->syncMenu();
-
- // comment in if you want the menu to rebuild each time
- //LLUICtrlFactory::getInstance()->buildFloater(windLight, "floater_windlight_options.xml");
- //windLight->initCallbacks();
-
- windLight->open();
-}
-
-bool LLFloaterWindLight::isOpen()
-{
- if (sWindLight != NULL) {
- return true;
- }
- return false;
-}
-
-// virtual
-void LLFloaterWindLight::onClose(bool app_quitting)
-{
- if (sWindLight)
- {
- sWindLight->setVisible(FALSE);
- }
-}
-
// color control callbacks
-void LLFloaterWindLight::onColorControlRMoved(LLUICtrl* ctrl, void* userData)
+void LLFloaterWindLight::onColorControlRMoved(LLUICtrl* ctrl, WLColorControl* colorControl)
{
deactivateAnimator();
LLSliderCtrl* sldrCtrl = static_cast<LLSliderCtrl*>(ctrl);
- WLColorControl * colorControl = static_cast<WLColorControl *>(userData);
colorControl->r = sldrCtrl->getValueF32();
if(colorControl->isSunOrAmbientColor) {
@@ -502,11 +460,11 @@ void LLFloaterWindLight::onColorControlRMoved(LLUICtrl* ctrl, void* userData)
name.append("I");
if(colorControl->isSunOrAmbientColor) {
- sWindLight->childSetValue(name, colorControl->r / 3);
+ childSetValue(name, colorControl->r / 3);
} else if(colorControl->isBlueHorizonOrDensity) {
- sWindLight->childSetValue(name, colorControl->r / 2);
+ childSetValue(name, colorControl->r / 2);
} else {
- sWindLight->childSetValue(name, colorControl->r);
+ childSetValue(name, colorControl->r);
}
}
@@ -515,12 +473,11 @@ void LLFloaterWindLight::onColorControlRMoved(LLUICtrl* ctrl, void* userData)
LLWLParamManager::instance()->propagateParameters();
}
-void LLFloaterWindLight::onColorControlGMoved(LLUICtrl* ctrl, void* userData)
+void LLFloaterWindLight::onColorControlGMoved(LLUICtrl* ctrl, WLColorControl* colorControl)
{
deactivateAnimator();
LLSliderCtrl* sldrCtrl = static_cast<LLSliderCtrl*>(ctrl);
- WLColorControl * colorControl = static_cast<WLColorControl *>(userData);
colorControl->g = sldrCtrl->getValueF32();
if(colorControl->isSunOrAmbientColor) {
@@ -538,11 +495,11 @@ void LLFloaterWindLight::onColorControlGMoved(LLUICtrl* ctrl, void* userData)
name.append("I");
if(colorControl->isSunOrAmbientColor) {
- sWindLight->childSetValue(name, colorControl->g / 3);
+ childSetValue(name, colorControl->g / 3);
} else if(colorControl->isBlueHorizonOrDensity) {
- sWindLight->childSetValue(name, colorControl->g / 2);
+ childSetValue(name, colorControl->g / 2);
} else {
- sWindLight->childSetValue(name, colorControl->g);
+ childSetValue(name, colorControl->g);
}
}
@@ -551,12 +508,11 @@ void LLFloaterWindLight::onColorControlGMoved(LLUICtrl* ctrl, void* userData)
LLWLParamManager::instance()->propagateParameters();
}
-void LLFloaterWindLight::onColorControlBMoved(LLUICtrl* ctrl, void* userData)
+void LLFloaterWindLight::onColorControlBMoved(LLUICtrl* ctrl, WLColorControl* colorControl)
{
deactivateAnimator();
LLSliderCtrl* sldrCtrl = static_cast<LLSliderCtrl*>(ctrl);
- WLColorControl * colorControl = static_cast<WLColorControl *>(userData);
colorControl->b = sldrCtrl->getValueF32();
if(colorControl->isSunOrAmbientColor) {
@@ -574,11 +530,11 @@ void LLFloaterWindLight::onColorControlBMoved(LLUICtrl* ctrl, void* userData)
name.append("I");
if(colorControl->isSunOrAmbientColor) {
- sWindLight->childSetValue(name, colorControl->b / 3);
+ childSetValue(name, colorControl->b / 3);
} else if(colorControl->isBlueHorizonOrDensity) {
- sWindLight->childSetValue(name, colorControl->b / 2);
+ childSetValue(name, colorControl->b / 2);
} else {
- sWindLight->childSetValue(name, colorControl->b);
+ childSetValue(name, colorControl->b);
}
}
@@ -587,12 +543,11 @@ void LLFloaterWindLight::onColorControlBMoved(LLUICtrl* ctrl, void* userData)
LLWLParamManager::instance()->propagateParameters();
}
-void LLFloaterWindLight::onColorControlIMoved(LLUICtrl* ctrl, void* userData)
+void LLFloaterWindLight::onColorControlIMoved(LLUICtrl* ctrl, WLColorControl* colorControl)
{
deactivateAnimator();
LLSliderCtrl* sldrCtrl = static_cast<LLSliderCtrl*>(ctrl);
- WLColorControl * colorControl = static_cast<WLColorControl *>(userData);
colorControl->i = sldrCtrl->getValueF32();
@@ -649,24 +604,24 @@ void LLFloaterWindLight::onColorControlIMoved(LLUICtrl* ctrl, void* userData)
// divide sun color vals by three
if(colorControl->isSunOrAmbientColor)
{
- sWindLight->childSetValue(rName, colorControl->r/3);
- sWindLight->childSetValue(gName, colorControl->g/3);
- sWindLight->childSetValue(bName, colorControl->b/3);
+ childSetValue(rName, colorControl->r/3);
+ childSetValue(gName, colorControl->g/3);
+ childSetValue(bName, colorControl->b/3);
}
else if(colorControl->isBlueHorizonOrDensity)
{
- sWindLight->childSetValue(rName, colorControl->r/2);
- sWindLight->childSetValue(gName, colorControl->g/2);
- sWindLight->childSetValue(bName, colorControl->b/2);
+ childSetValue(rName, colorControl->r/2);
+ childSetValue(gName, colorControl->g/2);
+ childSetValue(bName, colorControl->b/2);
}
else
{
// set the sliders to the new vals
- sWindLight->childSetValue(rName, colorControl->r);
- sWindLight->childSetValue(gName, colorControl->g);
- sWindLight->childSetValue(bName, colorControl->b);
+ childSetValue(rName, colorControl->r);
+ childSetValue(gName, colorControl->g);
+ childSetValue(bName, colorControl->b);
}
}
@@ -676,12 +631,11 @@ void LLFloaterWindLight::onColorControlIMoved(LLUICtrl* ctrl, void* userData)
}
/// GLOW SPECIFIC CODE
-void LLFloaterWindLight::onGlowRMoved(LLUICtrl* ctrl, void* userData)
+void LLFloaterWindLight::onGlowRMoved(LLUICtrl* ctrl, WLColorControl* colorControl)
{
deactivateAnimator();
LLSliderCtrl* sldrCtrl = static_cast<LLSliderCtrl*>(ctrl);
- WLColorControl * colorControl = static_cast<WLColorControl *>(userData);
// scaled by 20
colorControl->r = (2 - sldrCtrl->getValueF32()) * 20;
@@ -691,12 +645,11 @@ void LLFloaterWindLight::onGlowRMoved(LLUICtrl* ctrl, void* userData)
}
/// \NOTE that we want NEGATIVE (-) B
-void LLFloaterWindLight::onGlowBMoved(LLUICtrl* ctrl, void* userData)
+void LLFloaterWindLight::onGlowBMoved(LLUICtrl* ctrl, WLColorControl* colorControl)
{
deactivateAnimator();
LLSliderCtrl* sldrCtrl = static_cast<LLSliderCtrl*>(ctrl);
- WLColorControl * colorControl = static_cast<WLColorControl *>(userData);
/// \NOTE that we want NEGATIVE (-) B and NOT by 20 as 20 is too big
colorControl->b = -sldrCtrl->getValueF32() * 5;
@@ -705,12 +658,11 @@ void LLFloaterWindLight::onGlowBMoved(LLUICtrl* ctrl, void* userData)
LLWLParamManager::instance()->propagateParameters();
}
-void LLFloaterWindLight::onFloatControlMoved(LLUICtrl* ctrl, void* userData)
+void LLFloaterWindLight::onFloatControlMoved(LLUICtrl* ctrl, WLFloatControl* floatControl)
{
deactivateAnimator();
LLSliderCtrl* sldrCtrl = static_cast<LLSliderCtrl*>(ctrl);
- WLFloatControl * floatControl = static_cast<WLFloatControl *>(userData);
floatControl->x = sldrCtrl->getValueF32() / floatControl->mult;
@@ -718,29 +670,16 @@ void LLFloaterWindLight::onFloatControlMoved(LLUICtrl* ctrl, void* userData)
LLWLParamManager::instance()->propagateParameters();
}
-void LLFloaterWindLight::onBoolToggle(LLUICtrl* ctrl, void* userData)
-{
- deactivateAnimator();
-
- LLCheckBoxCtrl* cbCtrl = static_cast<LLCheckBoxCtrl*>(ctrl);
-
- bool value = cbCtrl->get();
- (*(static_cast<BOOL *>(userData))) = value;
-}
-
-
// Lighting callbacks
// time of day
-void LLFloaterWindLight::onSunMoved(LLUICtrl* ctrl, void* userData)
+void LLFloaterWindLight::onSunMoved(LLUICtrl* ctrl, WLColorControl* colorControl)
{
deactivateAnimator();
- LLSliderCtrl* sunSldr = sWindLight->getChild<LLSliderCtrl>("WLSunAngle");
- LLSliderCtrl* eastSldr = sWindLight->getChild<LLSliderCtrl>("WLEastAngle");
+ LLSliderCtrl* sunSldr = getChild<LLSliderCtrl>("WLSunAngle");
+ LLSliderCtrl* eastSldr = getChild<LLSliderCtrl>("WLEastAngle");
- WLColorControl * colorControl = static_cast<WLColorControl *>(userData);
-
// get the two angles
LLWLParamManager * param_mgr = LLWLParamManager::instance();
@@ -759,18 +698,7 @@ void LLFloaterWindLight::onSunMoved(LLUICtrl* ctrl, void* userData)
param_mgr->propagateParameters();
}
-void LLFloaterWindLight::onFloatTweakMoved(LLUICtrl* ctrl, void* userData)
-{
- deactivateAnimator();
-
- LLSliderCtrl* sldrCtrl = static_cast<LLSliderCtrl*>(ctrl);
- F32 * tweak = static_cast<F32 *>(userData);
-
- (*tweak) = sldrCtrl->getValueF32();
- LLWLParamManager::instance()->propagateParameters();
-}
-
-void LLFloaterWindLight::onStarAlphaMoved(LLUICtrl* ctrl, void* userData)
+void LLFloaterWindLight::onStarAlphaMoved(LLUICtrl* ctrl)
{
deactivateAnimator();
@@ -779,15 +707,15 @@ void LLFloaterWindLight::onStarAlphaMoved(LLUICtrl* ctrl, void* userData)
LLWLParamManager::instance()->mCurParams.setStarBrightness(sldrCtrl->getValueF32());
}
-void LLFloaterWindLight::onNewPreset(void* userData)
+void LLFloaterWindLight::onNewPreset()
{
- LLNotifications::instance().add("NewSkyPreset", LLSD(), LLSD(), newPromptCallback);
+ LLNotifications::instance().add("NewSkyPreset", LLSD(), LLSD(), boost::bind(&LLFloaterWindLight::newPromptCallback, this, _1, _2));
}
-void LLFloaterWindLight::onSavePreset(void* userData)
+void LLFloaterWindLight::onSavePreset()
{
// get the name
- LLComboBox* comboBox = sWindLight->getChild<LLComboBox>(
+ LLComboBox* comboBox = getChild<LLComboBox>(
"WLPresetsCombo");
// don't save the empty name
@@ -808,7 +736,7 @@ void LLFloaterWindLight::onSavePreset(void* userData)
LLWLParamManager::instance()->mCurParams.mName =
comboBox->getSelectedItemLabel();
- LLNotifications::instance().add("WLSavePresetAlert", LLSD(), LLSD(), saveAlertCallback);
+ LLNotifications::instance().add("WLSavePresetAlert", LLSD(), LLSD(), boost::bind(&LLFloaterWindLight::saveAlertCallback, this, _1, _2));
}
bool LLFloaterWindLight::saveAlertCallback(const LLSD& notification, const LLSD& response)
@@ -827,9 +755,9 @@ bool LLFloaterWindLight::saveAlertCallback(const LLSD& notification, const LLSD&
return false;
}
-void LLFloaterWindLight::onDeletePreset(void* userData)
+void LLFloaterWindLight::onDeletePreset()
{
- LLComboBox* combo_box = sWindLight->getChild<LLComboBox>(
+ LLComboBox* combo_box = getChild<LLComboBox>(
"WLPresetsCombo");
if(combo_box->getSelectedValue().asString() == "")
@@ -840,7 +768,7 @@ void LLFloaterWindLight::onDeletePreset(void* userData)
LLSD args;
args["SKY"] = combo_box->getSelectedValue().asString();
LLNotifications::instance().add("WLDeletePresetAlert", args, LLSD(),
- boost::bind(&LLFloaterWindLight::deleteAlertCallback, sWindLight, _1, _2));
+ boost::bind(&LLFloaterWindLight::deleteAlertCallback, this, _1, _2));
}
bool LLFloaterWindLight::deleteAlertCallback(const LLSD& notification, const LLSD& response)
@@ -850,17 +778,14 @@ bool LLFloaterWindLight::deleteAlertCallback(const LLSD& notification, const LLS
// if they choose delete, do it. Otherwise, don't do anything
if(option == 0)
{
- LLComboBox* combo_box = getChild<LLComboBox>(
- "WLPresetsCombo");
- LLFloaterDayCycle* day_cycle = NULL;
+ LLComboBox* combo_box = getChild<LLComboBox>("WLPresetsCombo");
+ LLFloaterDayCycle* day_cycle = LLFloaterReg::findTypedInstance<LLFloaterDayCycle>("env_day_cycle");
LLComboBox* key_combo = NULL;
LLMultiSliderCtrl* mult_sldr = NULL;
- if(LLFloaterDayCycle::isOpen())
+ if (day_cycle)
{
- day_cycle = LLFloaterDayCycle::instance();
- key_combo = day_cycle->getChild<LLComboBox>(
- "WLKeyPresets");
+ key_combo = day_cycle->getChild<LLComboBox>("WLKeyPresets");
mult_sldr = day_cycle->getChild<LLMultiSliderCtrl>("WLDayCycleKeys");
}
@@ -903,29 +828,25 @@ bool LLFloaterWindLight::deleteAlertCallback(const LLSD& notification, const LLS
}
-void LLFloaterWindLight::onChangePresetName(LLUICtrl* ctrl, void * userData)
+void LLFloaterWindLight::onChangePresetName(LLUICtrl* ctrl)
{
deactivateAnimator();
- LLComboBox * combo_box = static_cast<LLComboBox*>(ctrl);
-
- if(combo_box->getSimple() == "")
+ std::string data = ctrl->getValue().asString();
+ if(!data.empty())
{
- return;
+ LLWLParamManager::instance()->loadPreset( data);
+ syncMenu();
}
-
- LLWLParamManager::instance()->loadPreset(
- combo_box->getSelectedValue().asString());
- sWindLight->syncMenu();
}
-void LLFloaterWindLight::onOpenDayCycle(void* userData)
+void LLFloaterWindLight::onOpenDayCycle()
{
- LLFloaterDayCycle::show();
+ LLFloaterReg::showInstance("env_day_cycle");
}
// Clouds
-void LLFloaterWindLight::onCloudScrollXMoved(LLUICtrl* ctrl, void* userData)
+void LLFloaterWindLight::onCloudScrollXMoved(LLUICtrl* ctrl)
{
deactivateAnimator();
@@ -934,7 +855,7 @@ void LLFloaterWindLight::onCloudScrollXMoved(LLUICtrl* ctrl, void* userData)
LLWLParamManager::instance()->mCurParams.setCloudScrollX(sldrCtrl->getValueF32() + 10.0f);
}
-void LLFloaterWindLight::onCloudScrollYMoved(LLUICtrl* ctrl, void* userData)
+void LLFloaterWindLight::onCloudScrollYMoved(LLUICtrl* ctrl)
{
deactivateAnimator();
@@ -944,7 +865,7 @@ void LLFloaterWindLight::onCloudScrollYMoved(LLUICtrl* ctrl, void* userData)
LLWLParamManager::instance()->mCurParams.setCloudScrollY(sldrCtrl->getValueF32() + 10.0f);
}
-void LLFloaterWindLight::onCloudScrollXToggled(LLUICtrl* ctrl, void* userData)
+void LLFloaterWindLight::onCloudScrollXToggled(LLUICtrl* ctrl)
{
deactivateAnimator();
@@ -953,7 +874,7 @@ void LLFloaterWindLight::onCloudScrollXToggled(LLUICtrl* ctrl, void* userData)
bool lock = cbCtrl->get();
LLWLParamManager::instance()->mCurParams.setEnableCloudScrollX(!lock);
- LLSliderCtrl* sldr = sWindLight->getChild<LLSliderCtrl>(
+ LLSliderCtrl* sldr = getChild<LLSliderCtrl>(
"WLCloudScrollX");
if(cbCtrl->get())
@@ -967,7 +888,7 @@ void LLFloaterWindLight::onCloudScrollXToggled(LLUICtrl* ctrl, void* userData)
}
-void LLFloaterWindLight::onCloudScrollYToggled(LLUICtrl* ctrl, void* userData)
+void LLFloaterWindLight::onCloudScrollYToggled(LLUICtrl* ctrl)
{
deactivateAnimator();
@@ -975,7 +896,7 @@ void LLFloaterWindLight::onCloudScrollYToggled(LLUICtrl* ctrl, void* userData)
bool lock = cbCtrl->get();
LLWLParamManager::instance()->mCurParams.setEnableCloudScrollY(!lock);
- LLSliderCtrl* sldr = sWindLight->getChild<LLSliderCtrl>(
+ LLSliderCtrl* sldr = getChild<LLSliderCtrl>(
"WLCloudScrollY");
if(cbCtrl->get())
diff --git a/indra/newview/llfloaterwindlight.h b/indra/newview/llfloaterwindlight.h
index 3447caa923..56c2c6623b 100644
--- a/indra/newview/llfloaterwindlight.h
+++ b/indra/newview/llfloaterwindlight.h
@@ -51,80 +51,62 @@ class LLFloaterWindLight : public LLFloater
{
public:
- LLFloaterWindLight();
+ LLFloaterWindLight(const LLSD& key);
virtual ~LLFloaterWindLight();
-
+ /*virtual*/ BOOL postBuild();
/// initialize all
void initCallbacks(void);
- /// one and one instance only
- static LLFloaterWindLight* instance();
-
// help button stuff
- static void onClickHelp(void* data);
+ void onClickHelp(std::string alert);
void initHelpBtn(const std::string& name, const std::string& xml_alert);
- static bool newPromptCallback(const LLSD& notification, const LLSD& response);
+ bool newPromptCallback(const LLSD& notification, const LLSD& response);
/// general purpose callbacks for dealing with color controllers
- static void onColorControlRMoved(LLUICtrl* ctrl, void* userData);
- static void onColorControlGMoved(LLUICtrl* ctrl, void* userData);
- static void onColorControlBMoved(LLUICtrl* ctrl, void* userData);
- static void onColorControlIMoved(LLUICtrl* ctrl, void* userData);
- static void onFloatControlMoved(LLUICtrl* ctrl, void* userData);
- static void onBoolToggle(LLUICtrl* ctrl, void* userData);
+ void onColorControlRMoved(LLUICtrl* ctrl, WLColorControl* userData);
+ void onColorControlGMoved(LLUICtrl* ctrl, WLColorControl* userData);
+ void onColorControlBMoved(LLUICtrl* ctrl, WLColorControl* userData);
+ void onColorControlIMoved(LLUICtrl* ctrl, WLColorControl* userData);
+ void onFloatControlMoved(LLUICtrl* ctrl, WLFloatControl* userData);
/// lighting callbacks for glow
- static void onGlowRMoved(LLUICtrl* ctrl, void* userData);
+ void onGlowRMoved(LLUICtrl* ctrl, WLColorControl* userData);
//static void onGlowGMoved(LLUICtrl* ctrl, void* userData);
- static void onGlowBMoved(LLUICtrl* ctrl, void* userData);
+ void onGlowBMoved(LLUICtrl* ctrl, WLColorControl* userData);
/// lighting callbacks for sun
- static void onSunMoved(LLUICtrl* ctrl, void* userData);
-
- /// handle if float is changed
- static void onFloatTweakMoved(LLUICtrl* ctrl, void* userData);
+ void onSunMoved(LLUICtrl* ctrl, WLColorControl* userData);
/// for handling when the star slider is moved to adjust the alpha
- static void onStarAlphaMoved(LLUICtrl* ctrl, void* userData);
+ void onStarAlphaMoved(LLUICtrl* ctrl);
/// when user hits the load preset button
- static void onNewPreset(void* userData);
+ void onNewPreset();
/// when user hits the save preset button
- static void onSavePreset(void* userData);
+ void onSavePreset();
/// prompts a user when overwriting a preset
- static bool saveAlertCallback(const LLSD& notification, const LLSD& response);
+ bool saveAlertCallback(const LLSD& notification, const LLSD& response);
/// when user hits the save preset button
- static void onDeletePreset(void* userData);
+ void onDeletePreset();
/// prompts a user when overwriting a preset
bool deleteAlertCallback(const LLSD& notification, const LLSD& response);
/// what to do when you change the preset name
- static void onChangePresetName(LLUICtrl* ctrl, void* userData);
+ void onChangePresetName(LLUICtrl* ctrl);
/// when user hits the save preset button
- static void onOpenDayCycle(void* userData);
+ void onOpenDayCycle();
/// handle cloud scrolling
- static void onCloudScrollXMoved(LLUICtrl* ctrl, void* userData);
- static void onCloudScrollYMoved(LLUICtrl* ctrl, void* userData);
- static void onCloudScrollXToggled(LLUICtrl* ctrl, void* userData);
- static void onCloudScrollYToggled(LLUICtrl* ctrl, void* userData);
-
- //// menu management
-
- /// show off our menu
- static void show();
-
- /// return if the menu exists or not
- static bool isOpen();
-
- /// stuff to do on exit
- virtual void onClose(bool app_quitting);
+ void onCloudScrollXMoved(LLUICtrl* ctrl);
+ void onCloudScrollYMoved(LLUICtrl* ctrl);
+ void onCloudScrollXToggled(LLUICtrl* ctrl);
+ void onCloudScrollYToggled(LLUICtrl* ctrl);
/// sync up sliders with parameters
void syncMenu();
@@ -133,9 +115,6 @@ public:
static void deactivateAnimator();
private:
- // one instance on the inside
- static LLFloaterWindLight* sWindLight;
-
static std::set<std::string> sDefaultPresets;
};
diff --git a/indra/newview/llfloaterworldmap.cpp b/indra/newview/llfloaterworldmap.cpp
index 8326557cf8..098a5197df 100644
--- a/indra/newview/llfloaterworldmap.cpp
+++ b/indra/newview/llfloaterworldmap.cpp
@@ -41,23 +41,24 @@
#include "llfloaterworldmap.h"
#include "llagent.h"
-#include "llviewerwindow.h"
#include "llbutton.h"
#include "llcallingcard.h"
-#include "llcolorscheme.h"
#include "llcombobox.h"
#include "llviewercontrol.h"
#include "lldraghandle.h"
#include "llfirstuse.h"
+#include "llfloaterreg.h" // getTypedInstance()
#include "llfocusmgr.h"
#include "lllandmarklist.h"
#include "lllineeditor.h"
-#include "llpreviewlandmark.h"
#include "llregionhandle.h"
#include "llscrolllistctrl.h"
+#include "llslurl.h"
+#include "lltabcontainer.h"
#include "lltextbox.h"
#include "lltracker.h"
-#include "llurldispatcher.h"
+#include "llinventorymodel.h"
+#include "llviewerinventory.h" // LLViewerInventoryItem
#include "llviewermenu.h"
#include "llviewerregion.h"
#include "llviewerstats.h"
@@ -67,8 +68,10 @@
#include "llappviewer.h"
#include "llmapimagetype.h"
#include "llweb.h"
+#include "llslider.h"
#include "llglheaders.h"
+#include "llwindow.h" // copyTextToClipboard()
//---------------------------------------------------------------------------
// Constants
@@ -84,17 +87,10 @@ enum EPanDirection
};
// Values in pixels per region
-static const F32 ZOOM_MIN = -8.f; // initial value, updated by adjustZoomSlider
-static const F32 ZOOM_MAX = 0.f;
-static const F32 ZOOM_INC = 0.2f;
+static const F32 ZOOM_MAX = 128.f;
-static const F32 SIM_COORD_MIN = 0.f;
-static const F32 SIM_COORD_MAX = 255.f;
static const F32 SIM_COORD_DEFAULT = 128.f;
-static const F64 MAX_FLY_DISTANCE = 363.f; // Diagonal size of one sim.
-static const F64 MAX_FLY_DISTANCE_SQUARED = MAX_FLY_DISTANCE * MAX_FLY_DISTANCE;
-
//---------------------------------------------------------------------------
// Globals
//---------------------------------------------------------------------------
@@ -148,8 +144,8 @@ const LLUUID LLFloaterWorldMap::sHomeID( "10000000-0000-0000-0000-000000000001"
//---------------------------------------------------------------------------
-LLFloaterWorldMap::LLFloaterWorldMap()
-: LLFloater(std::string("worldmap")),
+LLFloaterWorldMap::LLFloaterWorldMap(const LLSD& key)
+: LLFloater(key),
mInventory(NULL),
mInventoryObserver(NULL),
mFriendObserver(NULL),
@@ -161,90 +157,72 @@ LLFloaterWorldMap::LLFloaterWorldMap()
mTrackedLocation(0,0,0),
mTrackedStatus(LLTracker::TRACKING_NOTHING)
{
- LLCallbackMap::map_t factory_map;
- factory_map["objects_mapview"] = LLCallbackMap(createWorldMapView, NULL);
- factory_map["terrain_mapview"] = LLCallbackMap(createWorldMapView, NULL);
- LLUICtrlFactory::getInstance()->buildFloater(this, "floater_world_map.xml", &factory_map);
+ gFloaterWorldMap = this;
+
+ mFactoryMap["objects_mapview"] = LLCallbackMap(createWorldMapView, NULL);
+ mFactoryMap["terrain_mapview"] = LLCallbackMap(createWorldMapView, NULL);
+
+ //Called from floater reg: LLUICtrlFactory::getInstance()->buildFloater(this, "floater_world_map.xml", FALSE);
+ mCommitCallbackRegistrar.add("WMap.Location", boost::bind(&LLFloaterWorldMap::onLocationCommit, this));
+ mCommitCallbackRegistrar.add("WMap.AvatarCombo", boost::bind(&LLFloaterWorldMap::onAvatarComboCommit, this));
+ mCommitCallbackRegistrar.add("WMap.SearchResult", boost::bind(&LLFloaterWorldMap::onCommitSearchResult, this));
+ mCommitCallbackRegistrar.add("WMap.CommitLocation", boost::bind(&LLFloaterWorldMap::onCommitLocation, this));
+ mCommitCallbackRegistrar.add("WMap.GoHome", boost::bind(&LLFloaterWorldMap::onGoHome, this));
+ mCommitCallbackRegistrar.add("WMap.Teleport", boost::bind(&LLFloaterWorldMap::onClickTeleportBtn, this));
+ mCommitCallbackRegistrar.add("WMap.ShowTarget", boost::bind(&LLFloaterWorldMap::onShowTargetBtn, this));
+ mCommitCallbackRegistrar.add("WMap.ShowAgent", boost::bind(&LLFloaterWorldMap::onShowAgentBtn, this));
+ mCommitCallbackRegistrar.add("WMap.Clear", boost::bind(&LLFloaterWorldMap::onClearBtn, this));
+ mCommitCallbackRegistrar.add("WMap.CopySLURL", boost::bind(&LLFloaterWorldMap::onCopySLURL, this));
}
// static
void* LLFloaterWorldMap::createWorldMapView(void* data)
{
- return new LLWorldMapView(std::string("mapview"), LLRect(0,300,400,0));
+ return new LLWorldMapView();
}
BOOL LLFloaterWorldMap::postBuild()
{
+ mCloseSignal.connect(boost::bind(&LLFloaterWorldMap::onClose, this));
+
mTabs = getChild<LLTabContainer>("maptab");
if (!mTabs) return FALSE;
- LLPanel *panel;
-
- panel = mTabs->getChild<LLPanel>("objects_mapview");
- if (panel)
- {
- mTabs->setTabChangeCallback(panel, onCommitBackground);
- mTabs->setTabUserData(panel, this);
- }
- panel = mTabs->getChild<LLPanel>("terrain_mapview");
- if (panel)
- {
- mTabs->setTabChangeCallback(panel, onCommitBackground);
- mTabs->setTabUserData(panel, this);
- }
+ mTabs->setCommitCallback(boost::bind(&LLFloaterWorldMap::onCommitBackground, this));
// The following callback syncs the worlmap tabs with the images.
// Commented out since it was crashing when LLWorldMap became a singleton.
// We should be fine without it but override the onOpen method and put it
// there if it turns out to be needed. -MG
//
- //onCommitBackground((void*)this, false);
-
- childSetCommitCallback("friend combo", onAvatarComboCommit, this);
+ //onCommitBackground();
LLComboBox *avatar_combo = getChild<LLComboBox>("friend combo");
if (avatar_combo)
{
avatar_combo->selectFirstItem();
- avatar_combo->setPrearrangeCallback( onAvatarComboPrearrange );
- avatar_combo->setTextEntryCallback( onComboTextEntry );
+ avatar_combo->setPrearrangeCallback( boost::bind(&LLFloaterWorldMap::onAvatarComboPrearrange, this) );
+ avatar_combo->setTextEntryCallback( boost::bind(&LLFloaterWorldMap::onComboTextEntry, this) );
}
- childSetAction("DoSearch", onLocationCommit, this);
-
- childSetFocusChangedCallback("location", onLocationFocusChanged, this);
+ getChild<LLScrollListCtrl>("location")->setFocusChangedCallback(boost::bind(&LLFloaterWorldMap::onLocationFocusChanged, this, _1));
LLLineEditor *location_editor = getChild<LLLineEditor>("location");
if (location_editor)
{
- location_editor->setKeystrokeCallback( onSearchTextEntry );
+ location_editor->setKeystrokeCallback( boost::bind(&LLFloaterWorldMap::onSearchTextEntry, this, _1), NULL );
}
- childSetCommitCallback("search_results", onCommitSearchResult, this);
- childSetDoubleClickCallback("search_results", onClickTeleportBtn);
- childSetCommitCallback("spin x", onCommitLocation, this);
- childSetCommitCallback("spin y", onCommitLocation, this);
- childSetCommitCallback("spin z", onCommitLocation, this);
-
- childSetCommitCallback("landmark combo", onLandmarkComboCommit, this);
+ getChild<LLScrollListCtrl>("search_results")->setDoubleClickCallback( boost::bind(&LLFloaterWorldMap::onClickTeleportBtn, this));
LLComboBox *landmark_combo = getChild<LLComboBox>( "landmark combo");
if (landmark_combo)
{
landmark_combo->selectFirstItem();
- landmark_combo->setPrearrangeCallback( onLandmarkComboPrearrange );
- landmark_combo->setTextEntryCallback( onComboTextEntry );
+ landmark_combo->setPrearrangeCallback( boost::bind(&LLFloaterWorldMap::onLandmarkComboPrearrange, this) );
+ landmark_combo->setTextEntryCallback( boost::bind(&LLFloaterWorldMap::onComboTextEntry, this) );
}
- childSetAction("Go Home", onGoHome, this);
-
- childSetAction("Teleport", onClickTeleportBtn, this);
-
- childSetAction("Show Destination", onShowTargetBtn, this);
- childSetAction("Show My Location", onShowAgentBtn, this);
- childSetAction("Clear", onClearBtn, this);
- childSetAction("copy_slurl", onCopySLURL, this);
-
mCurZoomVal = log(gMapScale)/log(2.f);
childSetValue("zoom slider", gMapScale);
@@ -267,28 +245,33 @@ LLFloaterWorldMap::~LLFloaterWorldMap()
// avatar tracker will delete this for us.
mFriendObserver = NULL;
+
+ gFloaterWorldMap = NULL;
}
+//static
+LLFloaterWorldMap* LLFloaterWorldMap::getInstance()
+{
+ return LLFloaterReg::getTypedInstance<LLFloaterWorldMap>("world_map");
+}
-// virtual
-void LLFloaterWorldMap::onClose(bool app_quitting)
+void LLFloaterWorldMap::onClose()
{
- setVisible(FALSE);
+ // While we're not visible, discard the overlay images we're using
+ LLWorldMap::getInstance()->clearImageRefs();
}
-// static
-void LLFloaterWorldMap::show(void*, BOOL center_on_target)
+// virtual
+void LLFloaterWorldMap::onOpen(const LLSD& key)
{
- BOOL was_visible = gFloaterWorldMap->getVisible();
+ bool center_on_target = (key.asString() == "center");
- gFloaterWorldMap->mIsClosing = FALSE;
- gFloaterWorldMap->open(); /* Flawfinder: ignore */
+ mIsClosing = FALSE;
LLWorldMapView* map_panel;
- map_panel = (LLWorldMapView*)gFloaterWorldMap->mTabs->getCurrentPanel();
+ map_panel = (LLWorldMapView*)mTabs->getCurrentPanel();
map_panel->clearLastClick();
- if (!was_visible)
{
// reset pan on show, so it centers on you again
if (!center_on_target)
@@ -303,13 +286,13 @@ void LLFloaterWorldMap::show(void*, BOOL center_on_target)
// Reload any maps that may have changed
LLWorldMap::getInstance()->clearSimFlags();
- const S32 panel_num = gFloaterWorldMap->mTabs->getCurrentPanelIndex();
+ const S32 panel_num = mTabs->getCurrentPanelIndex();
const bool request_from_sim = true;
LLWorldMap::getInstance()->setCurrentLayer(panel_num, request_from_sim);
// We may already have a bounding box for the regions of the world,
// so use that to adjust the view.
- gFloaterWorldMap->adjustZoomSliderBounds();
+ adjustZoomSliderBounds();
// Could be first show
LLFirstUse::useMap();
@@ -318,19 +301,19 @@ void LLFloaterWorldMap::show(void*, BOOL center_on_target)
LLUUID landmark_folder_id = gInventory.findCategoryUUIDForType(LLAssetType::AT_LANDMARK);
gInventory.startBackgroundFetch(landmark_folder_id);
- gFloaterWorldMap->childSetFocus("location", TRUE);
+ childSetFocus("location", TRUE);
gFocusMgr.triggerFocusFlash();
- gFloaterWorldMap->buildAvatarIDList();
- gFloaterWorldMap->buildLandmarkIDLists();
+ buildAvatarIDList();
+ buildLandmarkIDLists();
// If nothing is being tracked, set flag so the user position will be found
- gFloaterWorldMap->mSetToUserPosition = ( LLTracker::getTrackingStatus() == LLTracker::TRACKING_NOTHING );
+ mSetToUserPosition = ( LLTracker::getTrackingStatus() == LLTracker::TRACKING_NOTHING );
}
if (center_on_target)
{
- gFloaterWorldMap->centerOnTarget(FALSE);
+ centerOnTarget(FALSE);
}
}
@@ -345,46 +328,6 @@ void LLFloaterWorldMap::reloadIcons(void*)
}
-// static
-void LLFloaterWorldMap::toggle(void*)
-{
- BOOL visible = gFloaterWorldMap->getVisible();
-
- if (!visible)
- {
- show(NULL, FALSE);
- }
- else
- {
- gFloaterWorldMap->mIsClosing = TRUE;
- gFloaterWorldMap->close();
- }
-}
-
-
-// static
-void LLFloaterWorldMap::hide(void*)
-{
- gFloaterWorldMap->mIsClosing = TRUE;
- gFloaterWorldMap->close();
-}
-
-
-// virtual
-void LLFloaterWorldMap::setVisible( BOOL visible )
-{
- LLFloater::setVisible( visible );
-
- gSavedSettings.setBOOL( "ShowWorldMap", visible );
-
- if( !visible )
- {
- // While we're not visible, discard the overlay images we're using
- LLWorldMap::getInstance()->clearImageRefs();
- }
-}
-
-
// virtual
BOOL LLFloaterWorldMap::handleHover(S32 x, S32 y, MASK mask)
{
@@ -428,6 +371,9 @@ void LLFloaterWorldMap::reshape( S32 width, S32 height, BOOL called_from_parent
// virtual
void LLFloaterWorldMap::draw()
{
+ static LLUIColor map_track_color = LLUIColorTable::instance().getColor("MapTrackColor", LLColor4::white);
+ static LLUIColor map_track_disabled_color = LLUIColorTable::instance().getColor("MapTrackDisabledColor", LLColor4::white);
+
// Hide/Show Mature Events controls
childSetVisible("events_mature_icon", gAgent.canAccessMature());
childSetVisible("events_mature_label", gAgent.canAccessMature());
@@ -456,25 +402,25 @@ void LLFloaterWorldMap::draw()
LLTracker::ETrackingStatus tracking_status = LLTracker::getTrackingStatus();
if (LLTracker::TRACKING_AVATAR == tracking_status)
{
- childSetColor("avatar_icon", gTrackColor);
+ childSetColor("avatar_icon", map_track_color);
}
else
{
- childSetColor("avatar_icon", gDisabledTrackColor);
+ childSetColor("avatar_icon", map_track_disabled_color);
}
if (LLTracker::TRACKING_LANDMARK == tracking_status)
{
- childSetColor("landmark_icon", gTrackColor);
+ childSetColor("landmark_icon", map_track_color);
}
else
{
- childSetColor("landmark_icon", gDisabledTrackColor);
+ childSetColor("landmark_icon", map_track_disabled_color);
}
if (LLTracker::TRACKING_LOCATION == tracking_status)
{
- childSetColor("location_icon", gTrackColor);
+ childSetColor("location_icon", map_track_color);
}
else
{
@@ -488,7 +434,7 @@ void LLFloaterWorldMap::draw()
}
else
{
- childSetColor("location_icon", gDisabledTrackColor);
+ childSetColor("location_icon", map_track_disabled_color);
}
}
@@ -703,7 +649,7 @@ void LLFloaterWorldMap::updateLocation()
childSetValue("spin z", LLSD(agent_z) );
// Set the current SLURL
- mSLURL = LLURLDispatcher::buildSLURL(agent_sim_name, agent_x, agent_y, agent_z);
+ mSLURL = LLSLURL::buildSLURL(agent_sim_name, agent_x, agent_y, agent_z);
}
}
@@ -740,7 +686,7 @@ void LLFloaterWorldMap::updateLocation()
// simNameFromPosGlobal can fail, so don't give the user an invalid SLURL
if ( gotSimName )
{
- mSLURL = LLURLDispatcher::buildSLURL(sim_name, llround(region_x), llround(region_y), llround((F32)pos_global.mdV[VZ]));
+ mSLURL = LLSLURL::buildSLURL(sim_name, llround(region_x), llround(region_y), llround((F32)pos_global.mdV[VZ]));
}
else
{ // Empty SLURL will disable the "Copy SLURL to clipboard" button
@@ -901,7 +847,7 @@ void LLFloaterWorldMap::buildLandmarkIDLists()
LLInventoryModel::cat_array_t cats;
LLInventoryModel::item_array_t items;
LLIsType is_landmark(LLAssetType::AT_LANDMARK);
- gInventory.collectDescendentsIf(gAgent.getInventoryRootID(),
+ gInventory.collectDescendentsIf(gInventory.getRootFolderID(),
cats,
items,
LLInventoryModel::EXCLUDE_TRASH,
@@ -1024,10 +970,11 @@ void LLFloaterWorldMap::adjustZoomSliderBounds()
// Make sure the zoom slider can be moved at least a little bit.
// Likewise, less than the increment pixels per region is just silly.
- pixels_per_region = llclamp(pixels_per_region, 1.f, (F32)(pow(2.f, ZOOM_MAX) * 128.f));
+ pixels_per_region = llclamp(pixels_per_region, 1.f, ZOOM_MAX);
F32 min_power = log(pixels_per_region/256.f)/log(2.f);
- childSetMinValue("zoom slider", min_power);
+
+ getChild<LLSlider>("zoom slider")->setMinValue(min_power);
}
@@ -1035,52 +982,26 @@ void LLFloaterWorldMap::adjustZoomSliderBounds()
// User interface widget callbacks
//-------------------------------------------------------------------------
-// static
-void LLFloaterWorldMap::onPanBtn( void* userdata )
-{
- if( !gFloaterWorldMap ) return;
-
- EPanDirection direction = (EPanDirection)(intptr_t)userdata;
-
- S32 pan_x = 0;
- S32 pan_y = 0;
- switch( direction )
- {
- case PAN_UP: pan_y = -1; break;
- case PAN_DOWN: pan_y = 1; break;
- case PAN_LEFT: pan_x = 1; break;
- case PAN_RIGHT: pan_x = -1; break;
- default: llassert(0); return;
- }
-
- LLWorldMapView* map_panel;
- map_panel = (LLWorldMapView*)gFloaterWorldMap->mTabs->getCurrentPanel();
- map_panel->translatePan( pan_x, pan_y );
-}
-
-// static
-void LLFloaterWorldMap::onGoHome(void*)
+void LLFloaterWorldMap::onGoHome()
{
gAgent.teleportHome();
- gFloaterWorldMap->close();
+ closeFloater();
}
-// static
-void LLFloaterWorldMap::onLandmarkComboPrearrange( LLUICtrl* ctrl, void* userdata )
+void LLFloaterWorldMap::onLandmarkComboPrearrange( )
{
- LLFloaterWorldMap* self = gFloaterWorldMap;
- if( !self || self->mIsClosing )
+ if( mIsClosing )
{
return;
}
- LLCtrlListInterface *list = self->childGetListInterface("landmark combo");
+ LLCtrlListInterface *list = childGetListInterface("landmark combo");
if (!list) return;
LLUUID current_choice = list->getCurrentID();
- gFloaterWorldMap->buildLandmarkIDLists();
+ buildLandmarkIDLists();
if( current_choice.isNull() || !list->setCurrentByID( current_choice ) )
{
@@ -1089,7 +1010,7 @@ void LLFloaterWorldMap::onLandmarkComboPrearrange( LLUICtrl* ctrl, void* userdat
}
-void LLFloaterWorldMap::onComboTextEntry( LLLineEditor* ctrl, void* userdata )
+void LLFloaterWorldMap::onComboTextEntry()
{
// Reset the tracking whenever we start typing into any of the search fields,
// so that hitting <enter> does an auto-complete versus teleporting us to the
@@ -1097,24 +1018,21 @@ void LLFloaterWorldMap::onComboTextEntry( LLLineEditor* ctrl, void* userdata )
LLTracker::clearFocus();
}
-// static
-void LLFloaterWorldMap::onSearchTextEntry( LLLineEditor* ctrl, void* userdata )
+void LLFloaterWorldMap::onSearchTextEntry( LLLineEditor* ctrl )
{
- onComboTextEntry(ctrl, userdata);
- updateSearchEnabled(ctrl, userdata);
+ onComboTextEntry();
+ updateSearchEnabled();
}
-// static
-void LLFloaterWorldMap::onLandmarkComboCommit( LLUICtrl* ctrl, void* userdata )
-{
- LLFloaterWorldMap* self = gFloaterWorldMap;
- if( !self || self->mIsClosing )
+void LLFloaterWorldMap::onLandmarkComboCommit()
+{
+ if( mIsClosing )
{
return;
}
- LLCtrlListInterface *list = gFloaterWorldMap->childGetListInterface("landmark combo");
+ LLCtrlListInterface *list = childGetListInterface("landmark combo");
if (!list) return;
LLUUID asset_id;
@@ -1146,23 +1064,22 @@ void LLFloaterWorldMap::onLandmarkComboCommit( LLUICtrl* ctrl, void* userdata )
}
}
- self->trackLandmark( item_id);
- onShowTargetBtn(self);
+ trackLandmark( item_id);
+ onShowTargetBtn();
// Reset to user postion if nothing is tracked
- self->mSetToUserPosition = ( LLTracker::getTrackingStatus() == LLTracker::TRACKING_NOTHING );
+ mSetToUserPosition = ( LLTracker::getTrackingStatus() == LLTracker::TRACKING_NOTHING );
}
// static
-void LLFloaterWorldMap::onAvatarComboPrearrange( LLUICtrl* ctrl, void* userdata )
+void LLFloaterWorldMap::onAvatarComboPrearrange( )
{
- LLFloaterWorldMap* self = gFloaterWorldMap;
- if( !self || self->mIsClosing )
+ if( mIsClosing )
{
return;
}
- LLCtrlListInterface *list = self->childGetListInterface("friend combo");
+ LLCtrlListInterface *list = childGetListInterface("friend combo");
if (!list) return;
LLUUID current_choice;
@@ -1172,7 +1089,7 @@ void LLFloaterWorldMap::onAvatarComboPrearrange( LLUICtrl* ctrl, void* userdata
current_choice = LLAvatarTracker::instance().getAvatarID();
}
- self->buildAvatarIDList();
+ buildAvatarIDList();
if( !list->setCurrentByID( current_choice ) || current_choice.isNull() )
{
@@ -1180,82 +1097,74 @@ void LLFloaterWorldMap::onAvatarComboPrearrange( LLUICtrl* ctrl, void* userdata
}
}
-
-// static
-void LLFloaterWorldMap::onAvatarComboCommit( LLUICtrl* ctrl, void* userdata )
+void LLFloaterWorldMap::onAvatarComboCommit()
{
- LLFloaterWorldMap* self = gFloaterWorldMap;
- if( !self || self->mIsClosing )
+ if( mIsClosing )
{
return;
}
- LLCtrlListInterface *list = gFloaterWorldMap->childGetListInterface("friend combo");
+ LLCtrlListInterface *list = childGetListInterface("friend combo");
if (!list) return;
const LLUUID& new_avatar_id = list->getCurrentID();
if (new_avatar_id.notNull())
{
std::string name;
- LLComboBox* combo = gFloaterWorldMap->getChild<LLComboBox>("friend combo");
+ LLComboBox* combo = getChild<LLComboBox>("friend combo");
if (combo) name = combo->getSimple();
- self->trackAvatar(new_avatar_id, name);
- onShowTargetBtn(self);
+ trackAvatar(new_avatar_id, name);
+ onShowTargetBtn();
}
else
{ // Reset to user postion if nothing is tracked
- self->mSetToUserPosition = ( LLTracker::getTrackingStatus() == LLTracker::TRACKING_NOTHING );
+ mSetToUserPosition = ( LLTracker::getTrackingStatus() == LLTracker::TRACKING_NOTHING );
}
}
-//static
-void LLFloaterWorldMap::onLocationFocusChanged( LLFocusableElement* focus, void* userdata )
+void LLFloaterWorldMap::onLocationFocusChanged( LLFocusableElement* focus )
{
- updateSearchEnabled((LLUICtrl*)focus, userdata);
+ updateSearchEnabled();
}
-// static
-void LLFloaterWorldMap::updateSearchEnabled( LLUICtrl* ctrl, void* userdata )
+void LLFloaterWorldMap::updateSearchEnabled()
{
- LLFloaterWorldMap *self = gFloaterWorldMap;
- if (self->childHasKeyboardFocus("location") &&
- self->childGetValue("location").asString().length() > 0)
+ if (childHasKeyboardFocus("location") &&
+ childGetValue("location").asString().length() > 0)
{
- self->setDefaultBtn("DoSearch");
+ setDefaultBtn("DoSearch");
}
else
{
- self->setDefaultBtn(NULL);
+ setDefaultBtn(NULL);
}
}
-// static
-void LLFloaterWorldMap::onLocationCommit( void* userdata )
+void LLFloaterWorldMap::onLocationCommit()
{
- LLFloaterWorldMap *self = gFloaterWorldMap;
- if( !self || self->mIsClosing )
+ if( mIsClosing )
{
return;
}
- self->clearLocationSelection(FALSE);
- self->mCompletingRegionName = "";
- self->mLastRegionName = "";
+ clearLocationSelection(FALSE);
+ mCompletingRegionName = "";
+ mLastRegionName = "";
- std::string str = self->childGetValue("location").asString();
+ std::string str = childGetValue("location").asString();
// Trim any leading and trailing spaces in the search target
std::string saved_str = str;
LLStringUtil::trim( str );
if ( str != saved_str )
{ // Set the value in the UI if any spaces were removed
- self->childSetValue("location", str);
+ childSetValue("location", str);
}
LLStringUtil::toLower(str);
- gFloaterWorldMap->mCompletingRegionName = str;
+ mCompletingRegionName = str;
LLWorldMap::getInstance()->mIsTrackingCommit = TRUE;
- self->mExactMatch = FALSE;
+ mExactMatch = FALSE;
if (str.length() >= 3)
{
LLWorldMap::getInstance()->sendNamedRegionRequest(str);
@@ -1267,67 +1176,42 @@ void LLFloaterWorldMap::onLocationCommit( void* userdata )
}
}
-
-// static
-void LLFloaterWorldMap::onClearBtn(void* data)
+void LLFloaterWorldMap::onClearBtn()
{
- LLFloaterWorldMap* self = (LLFloaterWorldMap*)data;
- self->mTrackedStatus = LLTracker::TRACKING_NOTHING;
+ mTrackedStatus = LLTracker::TRACKING_NOTHING;
LLTracker::stopTracking((void *)(intptr_t)TRUE);
LLWorldMap::getInstance()->mIsTrackingUnknownLocation = FALSE;
- self->mSLURL = ""; // Clear the SLURL since it's invalid
- self->mSetToUserPosition = TRUE; // Revert back to the current user position
-}
-
-// static
-void LLFloaterWorldMap::onFlyBtn(void* data)
-{
- LLFloaterWorldMap* self = (LLFloaterWorldMap*)data;
- self->fly();
+ mSLURL = ""; // Clear the SLURL since it's invalid
+ mSetToUserPosition = TRUE; // Revert back to the current user position
}
-void LLFloaterWorldMap::onShowTargetBtn(void* data)
+void LLFloaterWorldMap::onShowTargetBtn()
{
- LLFloaterWorldMap* self = (LLFloaterWorldMap*)data;
- self->centerOnTarget(TRUE);
+ centerOnTarget(TRUE);
}
-void LLFloaterWorldMap::onShowAgentBtn(void* data)
+void LLFloaterWorldMap::onShowAgentBtn()
{
LLWorldMapView::setPan( 0, 0, FALSE); // FALSE == animate
-
// Set flag so user's location will be displayed if not tracking anything else
- LLFloaterWorldMap* self = (LLFloaterWorldMap*)data;
- self->mSetToUserPosition = TRUE;
+ mSetToUserPosition = TRUE;
}
-// static
-void LLFloaterWorldMap::onClickTeleportBtn(void* data)
+void LLFloaterWorldMap::onClickTeleportBtn()
{
- LLFloaterWorldMap* self = (LLFloaterWorldMap*)data;
- self->teleport();
+ teleport();
}
-// static
-void LLFloaterWorldMap::onCopySLURL(void* data)
+void LLFloaterWorldMap::onCopySLURL()
{
- LLFloaterWorldMap* self = (LLFloaterWorldMap*)data;
- gViewerWindow->mWindow->copyTextToClipboard(utf8str_to_wstring(self->mSLURL));
+ getWindow()->copyTextToClipboard(utf8str_to_wstring(mSLURL));
LLSD args;
- args["SLURL"] = self->mSLURL;
+ args["SLURL"] = mSLURL;
LLNotifications::instance().add("CopySLURL", args);
}
-void LLFloaterWorldMap::onCheckEvents(LLUICtrl*, void* data)
-{
- LLFloaterWorldMap* self = (LLFloaterWorldMap*)data;
- if(!self) return;
- self->childSetEnabled("event_mature_chk", self->childGetValue("event_chk"));
- self->childSetEnabled("event_adult_chk", self->childGetValue("event_chk"));
-}
-
// protected
void LLFloaterWorldMap::centerOnTarget(BOOL animate)
{
@@ -1375,7 +1259,7 @@ void LLFloaterWorldMap::fly()
if (!pos_global.isExactlyZero())
{
gAgent.startAutoPilotGlobal( pos_global );
- close();
+ closeFloater();
}
else
{
@@ -1447,24 +1331,6 @@ void LLFloaterWorldMap::teleport()
}
}
-// static
-void LLFloaterWorldMap::onGoToLandmarkDialog( S32 option, void* userdata )
-{
- LLFloaterWorldMap* self = (LLFloaterWorldMap*) userdata;
- switch( option )
- {
- case 0:
- self->teleportToLandmark();
- break;
- case 1:
- self->flyToLandmark();
- break;
- default:
- // nothing
- break;
- }
-}
-
void LLFloaterWorldMap::flyToLandmark()
{
LLVector3d destination_pos_global;
@@ -1536,14 +1402,10 @@ void LLFloaterWorldMap::flyToAvatar()
}
}
-// static
-void LLFloaterWorldMap::onCommitBackground(void* userdata, bool from_click)
+void LLFloaterWorldMap::onCommitBackground()
{
- LLFloaterWorldMap* self = (LLFloaterWorldMap*) userdata;
-
// Find my index
- S32 index = self->mTabs->getCurrentPanelIndex();
-
+ S32 index = mTabs->getCurrentPanelIndex();
LLWorldMap::getInstance()->setCurrentLayer(index);
}
@@ -1602,45 +1464,40 @@ void LLFloaterWorldMap::updateSims(bool found_null_sim)
{
mExactMatch = TRUE;
childSetFocus("search_results");
- onCommitSearchResult(NULL, this);
+ onCommitSearchResult();
}
else if (!mExactMatch && num_results > 0)
{
list->selectFirstItem(); // select first item by default
childSetFocus("search_results");
- onCommitSearchResult(NULL, this);
+ onCommitSearchResult();
}
else if (num_results == 0)
{
- list->addCommentText(std::string("None found."));
+ list->setCommentText(std::string("None found."));
list->operateOnAll(LLCtrlListInterface::OP_DESELECT);
}
}
-// static
-void LLFloaterWorldMap::onCommitLocation(LLUICtrl* ctrl, void* userdata)
+void LLFloaterWorldMap::onCommitLocation()
{
- LLFloaterWorldMap* self = (LLFloaterWorldMap*) userdata;
LLTracker::ETrackingStatus tracking_status = LLTracker::getTrackingStatus();
if ( LLTracker::TRACKING_LOCATION == tracking_status)
{
LLVector3d pos_global = LLTracker::getTrackedPositionGlobal();
- F64 local_x = self->childGetValue("spin x");
- F64 local_y = self->childGetValue("spin y");
- F64 local_z = self->childGetValue("spin z");
+ F64 local_x = childGetValue("spin x");
+ F64 local_y = childGetValue("spin y");
+ F64 local_z = childGetValue("spin z");
pos_global.mdV[VX] += -fmod(pos_global.mdV[VX], 256.0) + local_x;
pos_global.mdV[VY] += -fmod(pos_global.mdV[VY], 256.0) + local_y;
pos_global.mdV[VZ] = local_z;
- self->trackLocation(pos_global);
+ trackLocation(pos_global);
}
}
-// static
-void LLFloaterWorldMap::onCommitSearchResult(LLUICtrl*, void* userdata)
+void LLFloaterWorldMap::onCommitSearchResult()
{
- LLFloaterWorldMap* self = (LLFloaterWorldMap*) userdata;
-
- LLCtrlListInterface *list = self->childGetListInterface("search_results");
+ LLCtrlListInterface *list = childGetListInterface("search_results");
if (!list) return;
LLSD selected_value = list->getSelectedValue();
@@ -1661,19 +1518,19 @@ void LLFloaterWorldMap::onCommitSearchResult(LLUICtrl*, void* userdata)
if (sim_name == info_sim_name)
{
LLVector3d pos_global = from_region_handle( info->mHandle );
- F64 local_x = self->childGetValue("spin x");
- F64 local_y = self->childGetValue("spin y");
- F64 local_z = self->childGetValue("spin z");
+ F64 local_x = childGetValue("spin x");
+ F64 local_y = childGetValue("spin y");
+ F64 local_z = childGetValue("spin z");
pos_global.mdV[VX] += local_x;
pos_global.mdV[VY] += local_y;
pos_global.mdV[VZ] = local_z;
- self->childSetValue("location", sim_name);
- self->trackLocation(pos_global);
- self->setDefaultBtn("Teleport");
+ childSetValue("location", sim_name);
+ trackLocation(pos_global);
+ setDefaultBtn("Teleport");
break;
}
}
- onShowTargetBtn(self);
+ onShowTargetBtn();
}
diff --git a/indra/newview/llfloaterworldmap.h b/indra/newview/llfloaterworldmap.h
index b0e72f298a..f117ea05af 100644
--- a/indra/newview/llfloaterworldmap.h
+++ b/indra/newview/llfloaterworldmap.h
@@ -49,29 +49,28 @@ class LLFriendObserver;
class LLInventoryModel;
class LLInventoryObserver;
class LLItemInfo;
+class LLLineEditor;
class LLTabContainer;
-class LLWorldMapView;
class LLFloaterWorldMap : public LLFloater
{
public:
- LLFloaterWorldMap();
+ LLFloaterWorldMap(const LLSD& key);
virtual ~LLFloaterWorldMap();
+ // Prefer this to gFloaterWorldMap
+ static LLFloaterWorldMap* getInstance();
+
static void *createWorldMapView(void* data);
BOOL postBuild();
- /*virtual*/ void onClose(bool app_quitting);
+ /*virtual*/ void onOpen(const LLSD& key);
- static void show(void*, BOOL center_on_target );
static void reloadIcons(void*);
- static void toggle(void*);
- static void hide(void*);
/*virtual*/ void reshape( S32 width, S32 height, BOOL called_from_parent = TRUE );
/*virtual*/ BOOL handleHover(S32 x, S32 y, MASK mask);
/*virtual*/ BOOL handleScrollWheel(S32 x, S32 y, S32 clicks);
- /*virtual*/ void setVisible(BOOL visible);
/*virtual*/ void draw();
// methods for dealing with inventory. The observe() method is
@@ -113,29 +112,26 @@ public:
void teleport();
protected:
- static void onPanBtn( void* userdata );
-
- static void onGoHome(void* data);
-
- static void onLandmarkComboPrearrange( LLUICtrl* ctrl, void* data );
- static void onLandmarkComboCommit( LLUICtrl* ctrl, void* data );
+ void onClose();
+
+ void onGoHome();
- static void onAvatarComboPrearrange( LLUICtrl* ctrl, void* data );
- static void onAvatarComboCommit( LLUICtrl* ctrl, void* data );
+ void onLandmarkComboPrearrange();
+ void onLandmarkComboCommit();
- static void onCommitBackground(void* data, bool from_click);
+ void onAvatarComboPrearrange();
+ void onAvatarComboCommit();
- static void onComboTextEntry( LLLineEditor* ctrl, void* data );
- static void onSearchTextEntry( LLLineEditor* ctrl, void* data );
+ void onCommitBackground();
- static void onClearBtn(void*);
- static void onFlyBtn(void*);
- static void onClickTeleportBtn(void*);
- static void onShowTargetBtn(void*);
- static void onShowAgentBtn(void*);
- static void onCopySLURL(void*);
+ void onComboTextEntry( );
+ void onSearchTextEntry( LLLineEditor* ctrl );
- static void onCheckEvents(LLUICtrl* ctrl, void*);
+ void onClearBtn();
+ void onClickTeleportBtn();
+ void onShowTargetBtn();
+ void onShowAgentBtn();
+ void onCopySLURL();
void centerOnTarget(BOOL animate);
void updateLocation();
@@ -144,7 +140,6 @@ protected:
void fly();
void buildLandmarkIDLists();
- static void onGoToLandmarkDialog(S32 option,void* userdata);
void flyToLandmark();
void teleportToLandmark();
void setLandmarkVisited();
@@ -153,11 +148,11 @@ protected:
void flyToAvatar();
void teleportToAvatar();
- static void updateSearchEnabled( LLUICtrl* ctrl, void* userdata );
- static void onLocationFocusChanged( LLFocusableElement* ctrl, void* userdata );
- static void onLocationCommit( void* userdata );
- static void onCommitLocation( LLUICtrl* ctrl, void* userdata );
- static void onCommitSearchResult( LLUICtrl* ctrl, void* userdata );
+ void updateSearchEnabled();
+ void onLocationFocusChanged( LLFocusableElement* ctrl );
+ void onLocationCommit();
+ void onCommitLocation();
+ void onCommitSearchResult();
void cacheLandmarkPosition();
@@ -170,7 +165,6 @@ protected:
LLDynamicArray<LLUUID> mLandmarkAssetIDList;
LLDynamicArray<LLUUID> mLandmarkItemIDList;
- BOOL mHasLandmarkPosition;
static const LLUUID sHomeID;
diff --git a/indra/newview/llfolderview.cpp b/indra/newview/llfolderview.cpp
index 97a3bd7c50..2a29566120 100644
--- a/indra/newview/llfolderview.cpp
+++ b/indra/newview/llfolderview.cpp
@@ -34,60 +34,54 @@
#include "llfolderview.h"
-#include <algorithm>
-
-#include "llviewercontrol.h"
-#include "lldbstrings.h"
-#include "llfocusmgr.h"
-#include "llfontgl.h"
-#include "llgl.h"
-#include "llrender.h"
-#include "llinventory.h"
-
#include "llcallbacklist.h"
+#include "llinventorybridge.h"
#include "llinventoryclipboard.h" // *TODO: remove this once hack below gone.
-#include "llinventoryview.h"// hacked in for the bonus context menu items.
+#include "llinventoryfilter.h"
+#include "llfoldertype.h"
+#include "llfloaterinventory.h"// hacked in for the bonus context menu items.
#include "llkeyboard.h"
#include "lllineeditor.h"
#include "llmenugl.h"
-#include "llresmgr.h"
#include "llpreview.h"
#include "llscrollcontainer.h" // hack to allow scrolling
#include "lltooldraganddrop.h"
+#include "lltrans.h"
#include "llui.h"
-#include "llviewerimage.h"
-#include "llviewerimagelist.h"
+#include "llviewertexture.h"
+#include "llviewertexturelist.h"
#include "llviewerjointattachment.h"
#include "llviewermenu.h"
#include "lluictrlfactory.h"
+#include "llviewercontrol.h"
#include "llviewerwindow.h"
#include "llvoavatar.h"
#include "llfloaterproperties.h"
-// RN: HACK
-// We need these because some of the code below relies on things like
-// gAgent root folder. Remove them once the abstraction leak is fixed.
-#include "llagent.h"
-#include "llappviewer.h"
+// Linden library includes
+#include "lldbstrings.h"
+#include "llfocusmgr.h"
+#include "llfontgl.h"
+#include "llgl.h"
+#include "llrender.h"
+#include "llinventory.h"
+
+// Third-party library includes
+#include <algorithm>
///----------------------------------------------------------------------------
/// Local function declarations, constants, enums, and typedefs
///----------------------------------------------------------------------------
-const S32 LEFT_PAD = 5;
-const S32 LEFT_INDENTATION = 13;
-const S32 ICON_PAD = 2;
-const S32 ICON_WIDTH = 16;
-const S32 TEXT_PAD = 1;
-const S32 ARROW_SIZE = 12;
const S32 RENAME_WIDTH_PAD = 4;
-const S32 RENAME_HEIGHT_PAD = 6;
+const S32 RENAME_HEIGHT_PAD = 2;
const S32 AUTO_OPEN_STACK_DEPTH = 16;
-const S32 MIN_ITEM_WIDTH_VISIBLE = ICON_WIDTH + ICON_PAD + ARROW_SIZE + TEXT_PAD + /*first few characters*/ 40;
+const S32 MIN_ITEM_WIDTH_VISIBLE = LLFolderViewItem::ICON_WIDTH
+ + LLFolderViewItem::ICON_PAD
+ + LLFolderViewItem::ARROW_SIZE
+ + LLFolderViewItem::TEXT_PAD
+ + /*first few characters*/ 40;
const S32 MINIMUM_RENAMER_WIDTH = 80;
-const F32 FOLDER_CLOSE_TIME_CONSTANT = 0.02f;
-const F32 FOLDER_OPEN_TIME_CONSTANT = 0.03f;
-const S32 MAX_FOLDER_ITEM_OVERLAP = 2;
enum {
SIGNAL_NO_KEYBOARD_FOCUS = 1,
@@ -103,2328 +97,6 @@ void properties_selected_items(void* user_data);
void paste_items(void* user_data);
void renamer_focus_lost( LLFocusableElement* handler, void* user_data );
-///----------------------------------------------------------------------------
-/// Class LLFolderViewItem
-///----------------------------------------------------------------------------
-
-// statics
-const LLFontGL* LLFolderViewItem::sFont = NULL;
-const LLFontGL* LLFolderViewItem::sSmallFont = NULL;
-LLColor4 LLFolderViewItem::sFgColor;
-LLColor4 LLFolderViewItem::sHighlightBgColor;
-LLColor4 LLFolderViewItem::sHighlightFgColor;
-LLColor4 LLFolderViewItem::sFilterBGColor;
-LLColor4 LLFolderViewItem::sFilterTextColor;
-LLColor4 LLFolderViewItem::sSuffixColor;
-LLColor4 LLFolderViewItem::sSearchStatusColor;
-LLUIImagePtr LLFolderViewItem::sArrowImage;
-LLUIImagePtr LLFolderViewItem::sBoxImage;
-
-//static
-void LLFolderViewItem::initClass()
-{
- sFont = LLResMgr::getInstance()->getRes( LLFONT_SANSSERIF_SMALL );
- sSmallFont = LLResMgr::getInstance()->getRes( LLFONT_SMALL );
- sFgColor = gColors.getColor( "MenuItemEnabledColor" );
- sHighlightBgColor = gColors.getColor( "MenuItemHighlightBgColor" );
- sHighlightFgColor = gColors.getColor( "MenuItemHighlightFgColor" );
- sFilterBGColor = gColors.getColor( "FilterBackgroundColor" );
- sFilterTextColor = gColors.getColor( "FilterTextColor" );
- sSuffixColor = gColors.getColor( "InventoryItemSuffixColor" );
- sSearchStatusColor = gColors.getColor( "InventorySearchStatusColor" );
- sArrowImage = LLUI::getUIImage("folder_arrow.tga");
- sBoxImage = LLUI::getUIImage("rounded_square.tga");
-}
-
-//static
-void LLFolderViewItem::cleanupClass()
-{
- sArrowImage = NULL;
- sBoxImage = NULL;
-}
-
-// Default constructor
-// NOTE: Optimize this, we call it a *lot* when opening a large inventory
-LLFolderViewItem::LLFolderViewItem( const std::string& name, LLUIImagePtr icon,
- time_t creation_date,
- LLFolderView* root,
- LLFolderViewEventListener* listener ) :
- LLUICtrl( name, LLRect(0, 0, 0, 0), TRUE, NULL, NULL, FOLLOWS_LEFT|FOLLOWS_TOP|FOLLOWS_RIGHT),
- mLabel( name ),
- mLabelWidth(0),
- mCreationDate(creation_date),
- mParentFolder( NULL ),
- mListener( listener ),
- mIsSelected( FALSE ),
- mIsCurSelection( FALSE ),
- mSelectPending(FALSE),
- mLabelStyle( LLFontGL::NORMAL ),
- mIcon(icon),
- mHasVisibleChildren(FALSE),
- mIndentation(0),
- mNumDescendantsSelected(0),
- mFiltered(FALSE),
- mLastFilterGeneration(-1),
- mStringMatchOffset(std::string::npos),
- mControlLabelRotation(0.f),
- mRoot( root ),
- mDragAndDropTarget(FALSE),
- mIsLoading(FALSE)
-{
- refresh(); // possible opt: only call refreshFromListener()
- setTabStop(FALSE);
-}
-
-// Destroys the object
-LLFolderViewItem::~LLFolderViewItem( void )
-{
- delete mListener;
- mListener = NULL;
-}
-
-LLFolderView* LLFolderViewItem::getRoot()
-{
- return mRoot;
-}
-
-// Returns true if this object is a child (or grandchild, etc.) of potential_ancestor.
-BOOL LLFolderViewItem::isDescendantOf( const LLFolderViewFolder* potential_ancestor )
-{
- LLFolderViewItem* root = this;
- while( root->mParentFolder )
- {
- if( root->mParentFolder == potential_ancestor )
- {
- return TRUE;
- }
- root = root->mParentFolder;
- }
- return FALSE;
-}
-
-LLFolderViewItem* LLFolderViewItem::getNextOpenNode(BOOL include_children)
-{
- if (!mParentFolder)
- {
- return NULL;
- }
-
- LLFolderViewItem* itemp = mParentFolder->getNextFromChild( this, include_children );
- while(itemp && !itemp->getVisible())
- {
- LLFolderViewItem* next_itemp = itemp->mParentFolder->getNextFromChild( itemp, include_children );
- if (itemp == next_itemp)
- {
- // hit last item
- return itemp->getVisible() ? itemp : this;
- }
- itemp = next_itemp;
- }
-
- return itemp;
-}
-
-LLFolderViewItem* LLFolderViewItem::getPreviousOpenNode(BOOL include_children)
-{
- if (!mParentFolder)
- {
- return NULL;
- }
-
- LLFolderViewItem* itemp = mParentFolder->getPreviousFromChild( this, include_children );
- while(itemp && !itemp->getVisible())
- {
- LLFolderViewItem* next_itemp = itemp->mParentFolder->getPreviousFromChild( itemp, include_children );
- if (itemp == next_itemp)
- {
- // hit first item
- return itemp->getVisible() ? itemp : this;
- }
- itemp = next_itemp;
- }
-
- return itemp;
-}
-
-// is this item something we think we should be showing?
-// for example, if we haven't gotten around to filtering it yet, then the answer is yes
-// until we find out otherwise
-BOOL LLFolderViewItem::potentiallyVisible()
-{
- // we haven't been checked against min required filter
- // or we have and we passed
- return getLastFilterGeneration() < getRoot()->getFilter()->getMinRequiredGeneration() || getFiltered();
-}
-
-BOOL LLFolderViewItem::getFiltered()
-{
- return mFiltered && mLastFilterGeneration >= mRoot->getFilter()->getMinRequiredGeneration();
-}
-
-BOOL LLFolderViewItem::getFiltered(S32 filter_generation)
-{
- return mFiltered && mLastFilterGeneration >= filter_generation;
-}
-
-void LLFolderViewItem::setFiltered(BOOL filtered, S32 filter_generation)
-{
- mFiltered = filtered;
- mLastFilterGeneration = filter_generation;
-}
-
-void LLFolderViewItem::setIcon(LLUIImagePtr icon)
-{
- mIcon = icon;
-}
-
-// refresh information from the listener
-void LLFolderViewItem::refreshFromListener()
-{
- if(mListener)
- {
- mLabel = mListener->getDisplayName();
- setIcon(mListener->getIcon());
- time_t creation_date = mListener->getCreationDate();
- if (mCreationDate != creation_date)
- {
- mCreationDate = mListener->getCreationDate();
- dirtyFilter();
- }
- mLabelStyle = mListener->getLabelStyle();
- mLabelSuffix = mListener->getLabelSuffix();
- }
-}
-
-void LLFolderViewItem::refresh()
-{
- refreshFromListener();
-
- std::string searchable_label(mLabel);
- searchable_label.append(mLabelSuffix);
- LLStringUtil::toUpper(searchable_label);
-
- if (mSearchableLabel.compare(searchable_label))
- {
- mSearchableLabel.assign(searchable_label);
- dirtyFilter();
- // some part of label has changed, so overall width has potentially changed
- if (mParentFolder)
- {
- mParentFolder->requestArrange();
- }
- }
-
- S32 label_width = sFont->getWidth(mLabel);
- if( mLabelSuffix.size() )
- {
- label_width += sFont->getWidth( mLabelSuffix );
- }
-
- mLabelWidth = ARROW_SIZE + TEXT_PAD + ICON_WIDTH + ICON_PAD + label_width;
-}
-
-void LLFolderViewItem::applyListenerFunctorRecursively(LLFolderViewListenerFunctor& functor)
-{
- functor(mListener);
-}
-
-// This function is called when items are added or view filters change. It's
-// implemented here but called by derived classes when folding the
-// views.
-void LLFolderViewItem::filterFromRoot( void )
-{
- LLFolderViewItem* root = getRoot();
-
- root->filter(*((LLFolderView*)root)->getFilter());
-}
-
-// This function is called when the folder view is dirty. It's
-// implemented here but called by derived classes when folding the
-// views.
-void LLFolderViewItem::arrangeFromRoot()
-{
- LLFolderViewItem* root = getRoot();
-
- S32 height = 0;
- S32 width = 0;
- root->arrange( &width, &height, 0 );
-}
-
-// This function clears the currently selected item, and records the
-// specified selected item appropriately for display and use in the
-// UI. If open is TRUE, then folders are opened up along the way to
-// the selection.
-void LLFolderViewItem::setSelectionFromRoot(LLFolderViewItem* selection,
- BOOL openitem,
- BOOL take_keyboard_focus)
-{
- getRoot()->setSelection(selection, openitem, take_keyboard_focus);
-}
-
-// helper function to change the selection from the root.
-void LLFolderViewItem::changeSelectionFromRoot(LLFolderViewItem* selection, BOOL selected)
-{
- getRoot()->changeSelection(selection, selected);
-}
-
-void LLFolderViewItem::extendSelectionFromRoot(LLFolderViewItem* selection)
-{
- LLDynamicArray<LLFolderViewItem*> selected_items;
-
- getRoot()->extendSelection(selection, NULL, selected_items);
-}
-
-EInventorySortGroup LLFolderViewItem::getSortGroup() const
-{
- return SG_ITEM;
-}
-
-// addToFolder() returns TRUE if it succeeds. FALSE otherwise
-BOOL LLFolderViewItem::addToFolder(LLFolderViewFolder* folder, LLFolderView* root)
-{
- if (!folder)
- {
- return FALSE;
- }
- mParentFolder = folder;
- root->addItemID(getListener()->getUUID(), this);
- return folder->addItem(this);
-}
-
-
-// Finds width and height of this object and it's children. Also
-// makes sure that this view and it's children are the right size.
-S32 LLFolderViewItem::arrange( S32* width, S32* height, S32 filter_generation)
-{
- mIndentation = mParentFolder ? mParentFolder->getIndentation() + LEFT_INDENTATION : 0;
- *width = llmax(*width, mLabelWidth + mIndentation);
- *height = getItemHeight();
- return *height;
-}
-
-S32 LLFolderViewItem::getItemHeight()
-{
- S32 icon_height = mIcon->getHeight();
- S32 label_height = llround(sFont->getLineHeight());
- return llmax( icon_height, label_height ) + ICON_PAD;
-}
-
-void LLFolderViewItem::filter( LLInventoryFilter& filter)
-{
- BOOL filtered = mListener && filter.check(this);
-
- // if our visibility will change as a result of this filter, then
- // we need to be rearranged in our parent folder
- if (getVisible() != filtered)
- {
- if (mParentFolder)
- {
- mParentFolder->requestArrange();
- }
- }
-
- setFiltered(filtered, filter.getCurrentGeneration());
- mStringMatchOffset = filter.getStringMatchOffset();
- filter.decrementFilterCount();
-
- if (getRoot()->getDebugFilters())
- {
- mStatusText = llformat("%d", mLastFilterGeneration);
- }
-}
-
-void LLFolderViewItem::dirtyFilter()
-{
- mLastFilterGeneration = -1;
- // bubble up dirty flag all the way to root
- if (getParentFolder())
- {
- getParentFolder()->setCompletedFilterGeneration(-1, TRUE);
- }
-}
-
-// *TODO: This can be optimized a lot by simply recording that it is
-// selected in the appropriate places, and assuming that set selection
-// means 'deselect' for a leaf item. Do this optimization after
-// multiple selection is implemented to make sure it all plays nice
-// together.
-BOOL LLFolderViewItem::setSelection(LLFolderViewItem* selection, BOOL openitem, BOOL take_keyboard_focus)
-{
- if( selection == this )
- {
- mIsSelected = TRUE;
- if(mListener)
- {
- mListener->selectItem();
- }
- }
- else
- {
- mIsSelected = FALSE;
- }
- return mIsSelected;
-}
-
-BOOL LLFolderViewItem::changeSelection(LLFolderViewItem* selection, BOOL selected)
-{
- if(selection == this && mIsSelected != selected)
- {
- mIsSelected = selected;
- if(mListener)
- {
- mListener->selectItem();
- }
- return TRUE;
- }
- return FALSE;
-}
-
-void LLFolderViewItem::recursiveDeselect(BOOL deselect_self)
-{
- if (mIsSelected && deselect_self)
- {
- mIsSelected = FALSE;
-
- // update ancestors' count of selected descendents
- LLFolderViewFolder* parent_folder = getParentFolder();
- while(parent_folder)
- {
- parent_folder->mNumDescendantsSelected--;
- parent_folder = parent_folder->getParentFolder();
- }
- }
-}
-
-
-BOOL LLFolderViewItem::isMovable()
-{
- if( mListener )
- {
- return mListener->isItemMovable();
- }
- else
- {
- return TRUE;
- }
-}
-
-BOOL LLFolderViewItem::isRemovable()
-{
- if( mListener )
- {
- return mListener->isItemRemovable();
- }
- else
- {
- return TRUE;
- }
-}
-
-void LLFolderViewItem::destroyView()
-{
- if (mParentFolder)
- {
- // removeView deletes me
- mParentFolder->removeView(this);
- }
-}
-
-// Call through to the viewed object and return true if it can be
-// removed.
-//BOOL LLFolderViewItem::removeRecursively(BOOL single_item)
-BOOL LLFolderViewItem::remove()
-{
- if(!isRemovable())
- {
- return FALSE;
- }
- if(mListener)
- {
- return mListener->removeItem();
- }
- return TRUE;
-}
-
-// Build an appropriate context menu for the item.
-void LLFolderViewItem::buildContextMenu(LLMenuGL& menu, U32 flags)
-{
- if(mListener)
- {
- mListener->buildContextMenu(menu, flags);
- }
-}
-
-void LLFolderViewItem::openItem( void )
-{
- if( mListener )
- {
- mListener->openItem();
- }
-}
-
-void LLFolderViewItem::preview( void )
-{
- if (mListener)
- {
- mListener->previewItem();
- }
-}
-
-void LLFolderViewItem::rename(const std::string& new_name)
-{
- if( !new_name.empty() )
- {
- mLabel = new_name;
- if( mListener )
- {
- mListener->renameItem(new_name);
-
- if(mParentFolder)
- {
- mParentFolder->resort(this);
- }
- }
- }
-}
-
-const std::string& LLFolderViewItem::getSearchableLabel() const
-{
- return mSearchableLabel;
-}
-
-const std::string& LLFolderViewItem::getName( void ) const
-{
- if(mListener)
- {
- return mListener->getName();
- }
- return mLabel;
-}
-
-// LLView functionality
-BOOL LLFolderViewItem::handleRightMouseDown( S32 x, S32 y, MASK mask )
-{
- if(!mIsSelected)
- {
- setSelectionFromRoot(this, FALSE);
- }
- make_ui_sound("UISndClick");
- return TRUE;
-}
-
-BOOL LLFolderViewItem::handleMouseDown( S32 x, S32 y, MASK mask )
-{
- // No handler needed for focus lost since this class has no
- // state that depends on it.
- gFocusMgr.setMouseCapture( this );
-
- if (!mIsSelected)
- {
- if(mask & MASK_CONTROL)
- {
- changeSelectionFromRoot(this, !mIsSelected);
- }
- else if (mask & MASK_SHIFT)
- {
- extendSelectionFromRoot(this);
- }
- else
- {
- setSelectionFromRoot(this, FALSE);
- }
- make_ui_sound("UISndClick");
- }
- else
- {
- mSelectPending = TRUE;
- }
-
- if( isMovable() )
- {
- S32 screen_x;
- S32 screen_y;
- localPointToScreen(x, y, &screen_x, &screen_y );
- LLToolDragAndDrop::getInstance()->setDragStart( screen_x, screen_y );
- }
- return TRUE;
-}
-
-BOOL LLFolderViewItem::handleHover( S32 x, S32 y, MASK mask )
-{
- if( hasMouseCapture() && isMovable() )
- {
- S32 screen_x;
- S32 screen_y;
- localPointToScreen(x, y, &screen_x, &screen_y );
- BOOL can_drag = TRUE;
- if( LLToolDragAndDrop::getInstance()->isOverThreshold( screen_x, screen_y ) )
- {
- LLFolderView* root = getRoot();
-
- if(root->getCurSelectedItem())
- {
- LLToolDragAndDrop::ESource src = LLToolDragAndDrop::SOURCE_WORLD;
-
- // *TODO: push this into listener and remove
- // dependency on llagent
- if(mListener && gInventory.isObjectDescendentOf(mListener->getUUID(), gAgent.getInventoryRootID()))
- {
- src = LLToolDragAndDrop::SOURCE_AGENT;
- }
- else if (mListener && gInventory.isObjectDescendentOf(mListener->getUUID(), gInventoryLibraryRoot))
- {
- src = LLToolDragAndDrop::SOURCE_LIBRARY;
- }
-
- can_drag = root->startDrag(src);
- if (can_drag)
- {
- // if (mListener) mListener->startDrag();
- // RN: when starting drag and drop, clear out last auto-open
- root->autoOpenTest(NULL);
- root->setShowSelectionContext(TRUE);
-
- // Release keyboard focus, so that if stuff is dropped into the
- // world, pressing the delete key won't blow away the inventory
- // item.
- gFocusMgr.setKeyboardFocus(NULL);
-
- return LLToolDragAndDrop::getInstance()->handleHover( x, y, mask );
- }
- }
- }
-
- if (can_drag)
- {
- gViewerWindow->setCursor(UI_CURSOR_ARROW);
- }
- else
- {
- gViewerWindow->setCursor(UI_CURSOR_NOLOCKED);
- }
- return TRUE;
- }
- else
- {
- getRoot()->setShowSelectionContext(FALSE);
- gViewerWindow->setCursor(UI_CURSOR_ARROW);
- // let parent handle this then...
- return FALSE;
- }
-}
-
-
-BOOL LLFolderViewItem::handleDoubleClick( S32 x, S32 y, MASK mask )
-{
- preview();
- return TRUE;
-}
-
-BOOL LLFolderViewItem::handleScrollWheel(S32 x, S32 y, S32 clicks)
-{
- if (getParent())
- {
- return getParent()->handleScrollWheel(x, y, clicks);
- }
- return FALSE;
-}
-
-BOOL LLFolderViewItem::handleMouseUp( S32 x, S32 y, MASK mask )
-{
- // if mouse hasn't moved since mouse down...
- if ( pointInView(x, y) && mSelectPending )
- {
- //...then select
- if(mask & MASK_CONTROL)
- {
- changeSelectionFromRoot(this, !mIsSelected);
- }
- else if (mask & MASK_SHIFT)
- {
- extendSelectionFromRoot(this);
- }
- else
- {
- setSelectionFromRoot(this, FALSE);
- }
- }
-
- mSelectPending = FALSE;
-
- if( hasMouseCapture() )
- {
- getRoot()->setShowSelectionContext(FALSE);
- gFocusMgr.setMouseCapture( NULL );
- }
- return TRUE;
-}
-
-BOOL LLFolderViewItem::handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop,
- EDragAndDropType cargo_type,
- void* cargo_data,
- EAcceptance* accept,
- std::string& tooltip_msg)
-{
- BOOL accepted = FALSE;
- BOOL handled = FALSE;
- if(mListener)
- {
- accepted = mListener->dragOrDrop(mask,drop,cargo_type,cargo_data);
- handled = accepted;
- if (accepted)
- {
- mDragAndDropTarget = TRUE;
- *accept = ACCEPT_YES_MULTI;
- }
- else
- {
- *accept = ACCEPT_NO;
- }
- }
- if(mParentFolder && !handled)
- {
- handled = mParentFolder->handleDragAndDropFromChild(mask,drop,cargo_type,cargo_data,accept,tooltip_msg);
- }
- if (handled)
- {
- lldebugst(LLERR_USER_INPUT) << "dragAndDrop handled by LLFolderViewItem" << llendl;
- }
-
- return handled;
-}
-
-
-void LLFolderViewItem::draw()
-{
- bool possibly_has_children = false;
- bool up_to_date = mListener && mListener->isUpToDate();
- if((up_to_date && hasVisibleChildren() ) || // we fetched our children and some of them have passed the filter...
- (!up_to_date && mListener && mListener->hasChildren())) // ...or we know we have children but haven't fetched them (doesn't obey filter)
- {
- possibly_has_children = true;
- }
- if(/*mControlLabel[0] != '\0' && */possibly_has_children)
- {
- if (sArrowImage)
- {
- gl_draw_scaled_rotated_image(mIndentation, getRect().getHeight() - ARROW_SIZE - TEXT_PAD,
- ARROW_SIZE, ARROW_SIZE, mControlLabelRotation, sArrowImage->getImage(), sFgColor);
- }
- }
-
- F32 text_left = (F32)(ARROW_SIZE + TEXT_PAD + ICON_WIDTH + ICON_PAD + mIndentation);
-
- // If we have keyboard focus, draw selection filled
- BOOL show_context = getRoot()->getShowSelectionContext();
- BOOL filled = show_context || (gFocusMgr.getKeyboardFocus() == getRoot());
-
- // always render "current" item, only render other selected items if
- // mShowSingleSelection is FALSE
- if( mIsSelected )
- {
- gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
- LLColor4 bg_color = sHighlightBgColor;
- //const S32 TRAILING_PAD = 5; // It just looks better with this.
- if (!mIsCurSelection)
- {
- // do time-based fade of extra objects
- F32 fade_time = getRoot()->getSelectionFadeElapsedTime();
- if (getRoot()->getShowSingleSelection())
- {
- // fading out
- bg_color.mV[VALPHA] = clamp_rescale(fade_time, 0.f, 0.4f, bg_color.mV[VALPHA], 0.f);
- }
- else
- {
- // fading in
- bg_color.mV[VALPHA] = clamp_rescale(fade_time, 0.f, 0.4f, 0.f, bg_color.mV[VALPHA]);
- }
- }
-
- gl_rect_2d(
- 0,
- getRect().getHeight(),
- getRect().getWidth() - 2,
- llfloor(getRect().getHeight() - sFont->getLineHeight() - ICON_PAD),
- bg_color, filled);
- if (mIsCurSelection)
- {
- gl_rect_2d(
- 0,
- getRect().getHeight(),
- getRect().getWidth() - 2,
- llfloor(getRect().getHeight() - sFont->getLineHeight() - ICON_PAD),
- sHighlightFgColor, FALSE);
- }
- if (getRect().getHeight() > llround(sFont->getLineHeight()) + ICON_PAD + 2)
- {
- gl_rect_2d(
- 0,
- llfloor(getRect().getHeight() - sFont->getLineHeight() - ICON_PAD) - 2,
- getRect().getWidth() - 2,
- 2,
- sHighlightFgColor, FALSE);
- if (show_context)
- {
- gl_rect_2d(
- 0,
- llfloor(getRect().getHeight() - sFont->getLineHeight() - ICON_PAD) - 2,
- getRect().getWidth() - 2,
- 2,
- sHighlightBgColor, TRUE);
- }
- }
- }
- if (mDragAndDropTarget)
- {
- gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
- gl_rect_2d(
- 0,
- getRect().getHeight(),
- getRect().getWidth() - 2,
- llfloor(getRect().getHeight() - sFont->getLineHeight() - ICON_PAD),
- sHighlightBgColor, FALSE);
-
- if (getRect().getHeight() > llround(sFont->getLineHeight()) + ICON_PAD + 2)
- {
- gl_rect_2d(
- 0,
- llfloor(getRect().getHeight() - sFont->getLineHeight() - ICON_PAD) - 2,
- getRect().getWidth() - 2,
- 2,
- sHighlightBgColor, FALSE);
- }
- mDragAndDropTarget = FALSE;
- }
-
-
- if(mIcon)
- {
- mIcon->draw(mIndentation + ARROW_SIZE + TEXT_PAD, getRect().getHeight() - mIcon->getHeight());
- }
-
- if (!mLabel.empty())
- {
- // highlight filtered text
- BOOL debug_filters = getRoot()->getDebugFilters();
- LLColor4 color = ( (mIsSelected && filled) ? sHighlightFgColor : sFgColor );
- F32 right_x;
- F32 y = (F32)getRect().getHeight() - sFont->getLineHeight() - (F32)TEXT_PAD;
-
- if (debug_filters)
- {
- if (!getFiltered() && !possibly_has_children)
- {
- color.mV[VALPHA] *= 0.5f;
- }
-
- LLColor4 filter_color = mLastFilterGeneration >= getRoot()->getFilter()->getCurrentGeneration() ? LLColor4(0.5f, 0.8f, 0.5f, 1.f) : LLColor4(0.8f, 0.5f, 0.5f, 1.f);
- sSmallFont->renderUTF8(mStatusText, 0, text_left, y, filter_color,
- LLFontGL::LEFT, LLFontGL::BOTTOM, LLFontGL::NORMAL,
- S32_MAX, S32_MAX, &right_x, FALSE );
- text_left = right_x;
- }
-
-
- if ( mIsLoading && mTimeSinceRequestStart.getElapsedTimeF32() >= gSavedSettings.getF32("FolderLoadingMessageWaitTime") )
- {
- // *TODO: Translate
- sFont->renderUTF8( std::string("Loading... "), 0, text_left, y, sSearchStatusColor,
- LLFontGL::LEFT, LLFontGL::BOTTOM, mLabelStyle, S32_MAX, S32_MAX, &right_x, FALSE);
- text_left = right_x;
- }
-
- sFont->renderUTF8( mLabel, 0, text_left, y, color,
- LLFontGL::LEFT, LLFontGL::BOTTOM, mLabelStyle,
- S32_MAX, S32_MAX, &right_x, FALSE );
- if (!mLabelSuffix.empty())
- {
- sFont->renderUTF8( mLabelSuffix, 0, right_x, y, sSuffixColor,
- LLFontGL::LEFT, LLFontGL::BOTTOM, mLabelStyle,
- S32_MAX, S32_MAX, &right_x, FALSE );
- }
-
- if (sBoxImage.notNull() && mStringMatchOffset != std::string::npos)
- {
- // don't draw backgrounds for zero-length strings
- S32 filter_string_length = mRoot->getFilterSubString().size();
- if (filter_string_length > 0)
- {
- std::string combined_string = mLabel + mLabelSuffix;
- S32 left = llround(text_left) + sFont->getWidth(combined_string, 0, mStringMatchOffset) - 1;
- S32 right = left + sFont->getWidth(combined_string, mStringMatchOffset, filter_string_length) + 2;
- S32 bottom = llfloor(getRect().getHeight() - sFont->getLineHeight() - 3);
- S32 top = getRect().getHeight();
-
- LLRect box_rect(left, top, right, bottom);
- sBoxImage->draw(box_rect, sFilterBGColor);
- F32 match_string_left = text_left + sFont->getWidthF32(combined_string, 0, mStringMatchOffset);
- F32 y = (F32)getRect().getHeight() - sFont->getLineHeight() - (F32)TEXT_PAD;
- sFont->renderUTF8( combined_string, mStringMatchOffset, match_string_left, y,
- sFilterTextColor, LLFontGL::LEFT, LLFontGL::BOTTOM, mLabelStyle,
- filter_string_length, S32_MAX, &right_x, FALSE );
- }
- }
- }
-
- if( sDebugRects )
- {
- drawDebugRect();
- }
-}
-
-
-///----------------------------------------------------------------------------
-/// Class LLFolderViewFolder
-///----------------------------------------------------------------------------
-
-// Default constructor
-LLFolderViewFolder::LLFolderViewFolder( const std::string& name, LLUIImagePtr icon,
- LLFolderView* root,
- LLFolderViewEventListener* listener ):
- LLFolderViewItem( name, icon, 0, root, listener ), // 0 = no create time
- mIsOpen(FALSE),
- mExpanderHighlighted(FALSE),
- mCurHeight(0.f),
- mTargetHeight(0.f),
- mAutoOpenCountdown(0.f),
- mSubtreeCreationDate(0),
- mAmTrash(LLFolderViewFolder::UNKNOWN),
- mLastArrangeGeneration( -1 ),
- mLastCalculatedWidth(0),
- mCompletedFilterGeneration(-1),
- mMostFilteredDescendantGeneration(-1)
-{
- mType = std::string("(folder)");
-}
-
-// Destroys the object
-LLFolderViewFolder::~LLFolderViewFolder( void )
-{
- // The LLView base class takes care of object destruction. make sure that we
- // don't have mouse or keyboard focus
- gFocusMgr.releaseFocusIfNeeded( this ); // calls onCommit()
-}
-
-// addToFolder() returns TRUE if it succeeds. FALSE otherwise
-BOOL LLFolderViewFolder::addToFolder(LLFolderViewFolder* folder, LLFolderView* root)
-{
- if (!folder)
- {
- return FALSE;
- }
- mParentFolder = folder;
- root->addItemID(getListener()->getUUID(), this);
- return folder->addFolder(this);
-}
-
-// Finds width and height of this object and it's children. Also
-// makes sure that this view and it's children are the right size.
-S32 LLFolderViewFolder::arrange( S32* width, S32* height, S32 filter_generation)
-{
- mHasVisibleChildren = hasFilteredDescendants(filter_generation);
-
- LLInventoryFilter::EFolderShow show_folder_state = getRoot()->getShowFolderState();
-
- // calculate height as a single item (without any children), and reshapes rectangle to match
- LLFolderViewItem::arrange( width, height, filter_generation );
-
- // clamp existing animated height so as to never get smaller than a single item
- mCurHeight = llmax((F32)*height, mCurHeight);
-
- // initialize running height value as height of single item in case we have no children
- *height = getItemHeight();
- F32 running_height = (F32)*height;
- F32 target_height = (F32)*height;
-
- // are my children visible?
- if (needsArrange())
- {
- // set last arrange generation first, in case children are animating
- // and need to be arranged again
- mLastArrangeGeneration = mRoot->getArrangeGeneration();
- if (mIsOpen)
- {
- // Add sizes of children
- S32 parent_item_height = getRect().getHeight();
-
- for(folders_t::iterator fit = mFolders.begin(); fit != mFolders.end(); ++fit)
- {
- LLFolderViewFolder* folderp = (*fit);
- if (getRoot()->getDebugFilters())
- {
- folderp->setVisible(TRUE);
- }
- else
- {
- folderp->setVisible(show_folder_state == LLInventoryFilter::SHOW_ALL_FOLDERS || // always show folders?
- (folderp->getFiltered(filter_generation) || folderp->hasFilteredDescendants(filter_generation))); // passed filter or has descendants that passed filter
- }
-
- if (folderp->getVisible())
- {
- S32 child_width = *width;
- S32 child_height = 0;
- S32 child_top = parent_item_height - llround(running_height);
-
- target_height += folderp->arrange( &child_width, &child_height, filter_generation );
-
- running_height += (F32)child_height;
- *width = llmax(*width, child_width);
- folderp->setOrigin( 0, child_top - folderp->getRect().getHeight() );
- }
- }
- for(items_t::iterator iit = mItems.begin();
- iit != mItems.end(); ++iit)
- {
- LLFolderViewItem* itemp = (*iit);
- if (getRoot()->getDebugFilters())
- {
- itemp->setVisible(TRUE);
- }
- else
- {
- itemp->setVisible(itemp->getFiltered(filter_generation));
- }
-
- if (itemp->getVisible())
- {
- S32 child_width = *width;
- S32 child_height = 0;
- S32 child_top = parent_item_height - llround(running_height);
-
- target_height += itemp->arrange( &child_width, &child_height, filter_generation );
- // don't change width, as this item is as wide as its parent folder by construction
- itemp->reshape( itemp->getRect().getWidth(), child_height);
-
- running_height += (F32)child_height;
- *width = llmax(*width, child_width);
- itemp->setOrigin( 0, child_top - itemp->getRect().getHeight() );
- }
- }
- }
-
- mTargetHeight = target_height;
- // cache this width so next time we can just return it
- mLastCalculatedWidth = *width;
- }
- else
- {
- // just use existing width
- *width = mLastCalculatedWidth;
- }
-
- // animate current height towards target height
- if (llabs(mCurHeight - mTargetHeight) > 1.f)
- {
- mCurHeight = lerp(mCurHeight, mTargetHeight, LLCriticalDamp::getInterpolant(mIsOpen ? FOLDER_OPEN_TIME_CONSTANT : FOLDER_CLOSE_TIME_CONSTANT));
-
- requestArrange();
-
- // hide child elements that fall out of current animated height
- for (folders_t::iterator iter = mFolders.begin();
- iter != mFolders.end();)
- {
- folders_t::iterator fit = iter++;
- // number of pixels that bottom of folder label is from top of parent folder
- if (getRect().getHeight() - (*fit)->getRect().mTop + (*fit)->getItemHeight()
- > llround(mCurHeight) + MAX_FOLDER_ITEM_OVERLAP)
- {
- // hide if beyond current folder height
- (*fit)->setVisible(FALSE);
- }
- }
-
- for (items_t::iterator iter = mItems.begin();
- iter != mItems.end();)
- {
- items_t::iterator iit = iter++;
- // number of pixels that bottom of item label is from top of parent folder
- if (getRect().getHeight() - (*iit)->getRect().mBottom
- > llround(mCurHeight) + MAX_FOLDER_ITEM_OVERLAP)
- {
- (*iit)->setVisible(FALSE);
- }
- }
- }
- else
- {
- mCurHeight = mTargetHeight;
- }
-
- // don't change width as this item is already as wide as its parent folder
- reshape(getRect().getWidth(),llround(mCurHeight));
-
- // pass current height value back to parent
- *height = llround(mCurHeight);
-
- return llround(mTargetHeight);
-}
-
-BOOL LLFolderViewFolder::needsArrange()
-{
- return mLastArrangeGeneration < mRoot->getArrangeGeneration();
-}
-
-void LLFolderViewFolder::setCompletedFilterGeneration(S32 generation, BOOL recurse_up)
-{
- mMostFilteredDescendantGeneration = llmin(mMostFilteredDescendantGeneration, generation);
- mCompletedFilterGeneration = generation;
- // only aggregate up if we are a lower (older) value
- if (recurse_up && mParentFolder && generation < mParentFolder->getCompletedFilterGeneration())
- {
- mParentFolder->setCompletedFilterGeneration(generation, TRUE);
- }
-}
-
-void LLFolderViewFolder::filter( LLInventoryFilter& filter)
-{
- S32 filter_generation = filter.getCurrentGeneration();
- // if failed to pass filter newer than must_pass_generation
- // you will automatically fail this time, so we only
- // check against items that have passed the filter
- S32 must_pass_generation = filter.getMustPassGeneration();
-
- // if we have already been filtered against this generation, skip out
- if (getCompletedFilterGeneration() >= filter_generation)
- {
- return;
- }
-
- // filter folder itself
- if (getLastFilterGeneration() < filter_generation)
- {
- if (getLastFilterGeneration() >= must_pass_generation && // folder has been compared to a valid precursor filter
- !mFiltered) // and did not pass the filter
- {
- // go ahead and flag this folder as done
- mLastFilterGeneration = filter_generation;
- }
- else
- {
- // filter self only on first pass through
- LLFolderViewItem::filter( filter );
- }
- }
-
- if (getRoot()->getDebugFilters())
- {
- mStatusText = llformat("%d", mLastFilterGeneration);
- mStatusText += llformat("(%d)", mCompletedFilterGeneration);
- mStatusText += llformat("+%d", mMostFilteredDescendantGeneration);
- }
-
- // all descendants have been filtered later than must pass generation
- // but none passed
- if(getCompletedFilterGeneration() >= must_pass_generation && !hasFilteredDescendants(must_pass_generation))
- {
- // don't traverse children if we've already filtered them since must_pass_generation
- // and came back with nothing
- return;
- }
-
- // we entered here with at least one filter iteration left
- // check to see if we have any more before continuing on to children
- if (filter.getFilterCount() < 0)
- {
- return;
- }
-
- // when applying a filter, matching folders get their contents downloaded first
- if (filter.isNotDefault() && getFiltered(filter.getMinRequiredGeneration()) && (mListener && !gInventory.isCategoryComplete(mListener->getUUID())))
- {
- gInventory.startBackgroundFetch(mListener->getUUID());
- }
-
- // now query children
- for (folders_t::iterator iter = mFolders.begin();
- iter != mFolders.end();)
- {
- folders_t::iterator fit = iter++;
- // have we run out of iterations this frame?
- if (filter.getFilterCount() < 0)
- {
- break;
- }
-
- // mMostFilteredDescendantGeneration might have been reset
- // in which case we need to update it even for folders that
- // don't need to be filtered anymore
- if ((*fit)->getCompletedFilterGeneration() >= filter_generation)
- {
- // track latest generation to pass any child items
- if ((*fit)->getFiltered() || (*fit)->hasFilteredDescendants(filter.getMinRequiredGeneration()))
- {
- mMostFilteredDescendantGeneration = filter_generation;
- if (mRoot->needsAutoSelect())
- {
- (*fit)->setOpenArrangeRecursively(TRUE);
- }
- }
- // just skip it, it has already been filtered
- continue;
- }
-
- // update this folders filter status (and children)
- (*fit)->filter( filter );
-
- // track latest generation to pass any child items
- if ((*fit)->getFiltered() || (*fit)->hasFilteredDescendants(filter_generation))
- {
- mMostFilteredDescendantGeneration = filter_generation;
- if (mRoot->needsAutoSelect())
- {
- (*fit)->setOpenArrangeRecursively(TRUE);
- }
- }
- }
-
- for (items_t::iterator iter = mItems.begin();
- iter != mItems.end();)
- {
- items_t::iterator iit = iter++;
- if (filter.getFilterCount() < 0)
- {
- break;
- }
- if ((*iit)->getLastFilterGeneration() >= filter_generation)
- {
- if ((*iit)->getFiltered())
- {
- mMostFilteredDescendantGeneration = filter_generation;
- }
- continue;
- }
-
- if ((*iit)->getLastFilterGeneration() >= must_pass_generation &&
- !(*iit)->getFiltered(must_pass_generation))
- {
- // failed to pass an earlier filter that was a subset of the current one
- // go ahead and flag this item as done
- (*iit)->setFiltered(FALSE, filter_generation);
- continue;
- }
-
- (*iit)->filter( filter );
-
- if ((*iit)->getFiltered(filter.getMinRequiredGeneration()))
- {
- mMostFilteredDescendantGeneration = filter_generation;
- }
- }
-
- // if we didn't use all filter iterations
- // that means we filtered all of our descendants
- // instead of exhausting the filter count for this frame
- if (filter.getFilterCount() > 0)
- {
- // flag this folder as having completed filter pass for all descendants
- setCompletedFilterGeneration(filter_generation, FALSE/*dont recurse up to root*/);
- }
-}
-
-void LLFolderViewFolder::setFiltered(BOOL filtered, S32 filter_generation)
-{
- // if this folder is now filtered, but wasn't before
- // (it just passed)
- if (filtered && !mFiltered)
- {
- // reset current height, because last time we drew it
- // it might have had more visible items than now
- mCurHeight = 0.f;
- }
-
- LLFolderViewItem::setFiltered(filtered, filter_generation);
-}
-
-void LLFolderViewFolder::dirtyFilter()
-{
- // we're a folder, so invalidate our completed generation
- setCompletedFilterGeneration(-1, FALSE);
- LLFolderViewItem::dirtyFilter();
-}
-
-BOOL LLFolderViewFolder::hasFilteredDescendants()
-{
- return mMostFilteredDescendantGeneration >= mRoot->getFilter()->getCurrentGeneration();
-}
-
-// Passes selection information on to children and record selection
-// information if necessary.
-BOOL LLFolderViewFolder::setSelection(LLFolderViewItem* selection, BOOL openitem,
- BOOL take_keyboard_focus)
-{
- BOOL rv = FALSE;
- if( selection == this )
- {
- mIsSelected = TRUE;
- if(mListener)
- {
- mListener->selectItem();
- }
- rv = TRUE;
- }
- else
- {
- mIsSelected = FALSE;
- rv = FALSE;
- }
- BOOL child_selected = FALSE;
-
- for (folders_t::iterator iter = mFolders.begin();
- iter != mFolders.end();)
- {
- folders_t::iterator fit = iter++;
- if((*fit)->setSelection(selection, openitem, take_keyboard_focus))
- {
- rv = TRUE;
- child_selected = TRUE;
- mNumDescendantsSelected++;
- }
- }
- for (items_t::iterator iter = mItems.begin();
- iter != mItems.end();)
- {
- items_t::iterator iit = iter++;
- if((*iit)->setSelection(selection, openitem, take_keyboard_focus))
- {
- rv = TRUE;
- child_selected = TRUE;
- mNumDescendantsSelected++;
- }
- }
- if(openitem && child_selected)
- {
- setOpenArrangeRecursively(TRUE);
- }
- return rv;
-}
-
-// This method is used to change the selection of an item. If
-// selection is 'this', then note selection as true. Returns TRUE
-// if this or a child is now selected.
-BOOL LLFolderViewFolder::changeSelection(LLFolderViewItem* selection,
- BOOL selected)
-{
- BOOL rv = FALSE;
- if(selection == this)
- {
- mIsSelected = selected;
- if(mListener && selected)
- {
- mListener->selectItem();
- }
- rv = TRUE;
- }
-
- for (folders_t::iterator iter = mFolders.begin();
- iter != mFolders.end();)
- {
- folders_t::iterator fit = iter++;
- if((*fit)->changeSelection(selection, selected))
- {
- if (selected)
- {
- mNumDescendantsSelected++;
- }
- else
- {
- mNumDescendantsSelected--;
- }
- rv = TRUE;
- }
- }
- for (items_t::iterator iter = mItems.begin();
- iter != mItems.end();)
- {
- items_t::iterator iit = iter++;
- if((*iit)->changeSelection(selection, selected))
- {
- if (selected)
- {
- mNumDescendantsSelected++;
- }
- else
- {
- mNumDescendantsSelected--;
- }
- rv = TRUE;
- }
- }
- return rv;
-}
-
-S32 LLFolderViewFolder::extendSelection(LLFolderViewItem* selection, LLFolderViewItem* last_selected, LLDynamicArray<LLFolderViewItem*>& selected_items)
-{
- S32 num_selected = 0;
-
- // pass on to child folders first
- for (folders_t::iterator iter = mFolders.begin();
- iter != mFolders.end();)
- {
- folders_t::iterator fit = iter++;
- num_selected += (*fit)->extendSelection(selection, last_selected, selected_items);
- mNumDescendantsSelected += num_selected;
- }
-
- // handle selection of our immediate children...
- BOOL reverse_select = FALSE;
- BOOL found_last_selected = FALSE;
- BOOL found_selection = FALSE;
- LLDynamicArray<LLFolderViewItem*> items_to_select;
- LLFolderViewItem* item;
-
- //...folders first...
- for (folders_t::iterator iter = mFolders.begin();
- iter != mFolders.end();)
- {
- folders_t::iterator fit = iter++;
- item = (*fit);
- if(item == selection)
- {
- found_selection = TRUE;
- }
- else if (item == last_selected)
- {
- found_last_selected = TRUE;
- if (found_selection)
- {
- reverse_select = TRUE;
- }
- }
-
- if (found_selection || found_last_selected)
- {
- // deselect currently selected items so they can be pushed back on queue
- if (item->isSelected())
- {
- item->changeSelection(item, FALSE);
- }
- items_to_select.put(item);
- }
-
- if (found_selection && found_last_selected)
- {
- break;
- }
- }
-
- if (!(found_selection && found_last_selected))
- {
- //,,,then items
- for (items_t::iterator iter = mItems.begin();
- iter != mItems.end();)
- {
- items_t::iterator iit = iter++;
- item = (*iit);
- if(item == selection)
- {
- found_selection = TRUE;
- }
- else if (item == last_selected)
- {
- found_last_selected = TRUE;
- if (found_selection)
- {
- reverse_select = TRUE;
- }
- }
-
- if (found_selection || found_last_selected)
- {
- // deselect currently selected items so they can be pushed back on queue
- if (item->isSelected())
- {
- item->changeSelection(item, FALSE);
- }
- items_to_select.put(item);
- }
-
- if (found_selection && found_last_selected)
- {
- break;
- }
- }
- }
-
- if (found_last_selected && found_selection)
- {
- // we have a complete selection inside this folder
- for (S32 index = reverse_select ? items_to_select.getLength() - 1 : 0;
- reverse_select ? index >= 0 : index < items_to_select.getLength(); reverse_select ? index-- : index++)
- {
- LLFolderViewItem* item = items_to_select[index];
- if (item->changeSelection(item, TRUE))
- {
- selected_items.put(item);
- mNumDescendantsSelected++;
- num_selected++;
- }
- }
- }
- else if (found_selection)
- {
- // last selection was not in this folder....go ahead and select just the new item
- if (selection->changeSelection(selection, TRUE))
- {
- selected_items.put(selection);
- mNumDescendantsSelected++;
- num_selected++;
- }
- }
-
- return num_selected;
-}
-
-void LLFolderViewFolder::recursiveDeselect(BOOL deselect_self)
-{
- // make sure we don't have negative values
- llassert(mNumDescendantsSelected >= 0);
-
- if (mIsSelected && deselect_self)
- {
- mIsSelected = FALSE;
-
- // update ancestors' count of selected descendents
- LLFolderViewFolder* parent_folder = getParentFolder();
- while(parent_folder)
- {
- parent_folder->mNumDescendantsSelected--;
- parent_folder = parent_folder->getParentFolder();
- }
- }
-
- if (0 == mNumDescendantsSelected)
- {
- return;
- }
-
- for (items_t::iterator iter = mItems.begin();
- iter != mItems.end();)
- {
- items_t::iterator iit = iter++;
- LLFolderViewItem* item = (*iit);
- item->recursiveDeselect(TRUE);
- }
-
- for (folders_t::iterator iter = mFolders.begin();
- iter != mFolders.end();)
- {
- folders_t::iterator fit = iter++;
- LLFolderViewFolder* folder = (*fit);
- folder->recursiveDeselect(TRUE);
- }
-
-}
-
-void LLFolderViewFolder::destroyView()
-{
- for (items_t::iterator iter = mItems.begin();
- iter != mItems.end();)
- {
- items_t::iterator iit = iter++;
- LLFolderViewItem* item = (*iit);
- getRoot()->removeItemID(item->getListener()->getUUID());
- }
-
- std::for_each(mItems.begin(), mItems.end(), DeletePointer());
- mItems.clear();
-
- while (!mFolders.empty())
- {
- LLFolderViewFolder *folderp = mFolders.back();
- folderp->destroyView(); // removes entry from mFolders
- }
-
- deleteAllChildren();
-
- if (mParentFolder)
- {
- mParentFolder->removeView(this);
- }
-}
-
-// remove the specified item (and any children) if possible. Return
-// TRUE if the item was deleted.
-BOOL LLFolderViewFolder::removeItem(LLFolderViewItem* item)
-{
- if(item->remove())
- {
- //RN: this seem unneccessary as remove() moves to trash
- //removeView(item);
- return TRUE;
- }
- return FALSE;
-}
-
-// simply remove the view (and any children) Don't bother telling the
-// listeners.
-void LLFolderViewFolder::removeView(LLFolderViewItem* item)
-{
- if (!item || item->getParentFolder() != this)
- {
- return;
- }
- // deselect without traversing hierarchy
- item->recursiveDeselect(TRUE);
- getRoot()->removeFromSelectionList(item);
- extractItem(item);
- delete item;
-}
-
-// extractItem() removes the specified item from the folder, but
-// doesn't delete it.
-void LLFolderViewFolder::extractItem( LLFolderViewItem* item )
-{
- items_t::iterator it = std::find(mItems.begin(), mItems.end(), item);
- if(it == mItems.end())
- {
- // This is an evil downcast. However, it's only doing
- // pointer comparison to find if (which it should be ) the
- // item is in the container, so it's pretty safe.
- LLFolderViewFolder* f = reinterpret_cast<LLFolderViewFolder*>(item);
- folders_t::iterator ft;
- ft = std::find(mFolders.begin(), mFolders.end(), f);
- if(ft != mFolders.end())
- {
- mFolders.erase(ft);
- }
- }
- else
- {
- mItems.erase(it);
- }
- //item has been removed, need to update filter
- dirtyFilter();
- //because an item is going away regardless of filter status, force rearrange
- requestArrange();
- getRoot()->removeItemID(item->getListener()->getUUID());
- removeChild(item);
-}
-
-// This function is called by a child that needs to be resorted.
-// This is only called for renaming an object because it won't work for date
-void LLFolderViewFolder::resort(LLFolderViewItem* item)
-{
- mItems.sort(mSortFunction);
- mFolders.sort(mSortFunction);
-}
-
-bool LLFolderViewFolder::isTrash() const
-{
- if (mAmTrash == LLFolderViewFolder::UNKNOWN)
- {
- mAmTrash = mListener->getUUID() == gInventory.findCategoryUUIDForType(LLAssetType::AT_TRASH, false) ? LLFolderViewFolder::TRASH : LLFolderViewFolder::NOT_TRASH;
- }
- return mAmTrash == LLFolderViewFolder::TRASH;
-}
-
-void LLFolderViewFolder::sortBy(U32 order)
-{
- if (!mSortFunction.updateSort(order))
- {
- // No changes.
- return;
- }
-
- // Propegate this change to sub folders
- for (folders_t::iterator iter = mFolders.begin();
- iter != mFolders.end();)
- {
- folders_t::iterator fit = iter++;
- (*fit)->sortBy(order);
- }
-
- mFolders.sort(mSortFunction);
- mItems.sort(mSortFunction);
-
- if (order & LLInventoryFilter::SO_DATE)
- {
- time_t latest = 0;
-
- if (!mItems.empty())
- {
- LLFolderViewItem* item = *(mItems.begin());
- latest = item->getCreationDate();
- }
-
- if (!mFolders.empty())
- {
- LLFolderViewFolder* folder = *(mFolders.begin());
- if (folder->getCreationDate() > latest)
- {
- latest = folder->getCreationDate();
- }
- }
- mSubtreeCreationDate = latest;
- }
-}
-
-void LLFolderViewFolder::setItemSortOrder(U32 ordering)
-{
- if (mSortFunction.updateSort(ordering))
- {
- for (folders_t::iterator iter = mFolders.begin();
- iter != mFolders.end();)
- {
- folders_t::iterator fit = iter++;
- (*fit)->setItemSortOrder(ordering);
- }
-
- mFolders.sort(mSortFunction);
- mItems.sort(mSortFunction);
- }
-}
-
-EInventorySortGroup LLFolderViewFolder::getSortGroup() const
-{
- if (isTrash())
- {
- return SG_TRASH_FOLDER;
- }
-
- // Folders that can't be moved are 'system' folders.
- if( mListener )
- {
- if( !(mListener->isItemMovable()) )
- {
- return SG_SYSTEM_FOLDER;
- }
- }
-
- return SG_NORMAL_FOLDER;
-}
-
-BOOL LLFolderViewFolder::isMovable()
-{
- if( mListener )
- {
- if( !(mListener->isItemMovable()) )
- {
- return FALSE;
- }
-
- for (items_t::iterator iter = mItems.begin();
- iter != mItems.end();)
- {
- items_t::iterator iit = iter++;
- if(!(*iit)->isMovable())
- {
- return FALSE;
- }
- }
-
- for (folders_t::iterator iter = mFolders.begin();
- iter != mFolders.end();)
- {
- folders_t::iterator fit = iter++;
- if(!(*fit)->isMovable())
- {
- return FALSE;
- }
- }
- }
- return TRUE;
-}
-
-
-BOOL LLFolderViewFolder::isRemovable()
-{
- if( mListener )
- {
- if( !(mListener->isItemRemovable()) )
- {
- return FALSE;
- }
-
- for (items_t::iterator iter = mItems.begin();
- iter != mItems.end();)
- {
- items_t::iterator iit = iter++;
- if(!(*iit)->isRemovable())
- {
- return FALSE;
- }
- }
-
- for (folders_t::iterator iter = mFolders.begin();
- iter != mFolders.end();)
- {
- folders_t::iterator fit = iter++;
- if(!(*fit)->isRemovable())
- {
- return FALSE;
- }
- }
- }
- return TRUE;
-}
-
-// this is an internal method used for adding items to folders.
-BOOL LLFolderViewFolder::addItem(LLFolderViewItem* item)
-{
-
- items_t::iterator it = std::lower_bound(
- mItems.begin(),
- mItems.end(),
- item,
- mSortFunction);
- mItems.insert(it,item);
- item->setRect(LLRect(0, 0, getRect().getWidth(), 0));
- item->setVisible(FALSE);
- addChild( item );
- item->dirtyFilter();
- requestArrange();
- return TRUE;
-}
-
-// this is an internal method used for adding items to folders.
-BOOL LLFolderViewFolder::addFolder(LLFolderViewFolder* folder)
-{
- folders_t::iterator it = std::lower_bound(
- mFolders.begin(),
- mFolders.end(),
- folder,
- mSortFunction);
- mFolders.insert(it,folder);
- folder->setOrigin(0, 0);
- folder->reshape(getRect().getWidth(), 0);
- folder->setVisible(FALSE);
- addChild( folder );
- folder->dirtyFilter();
- // rearrange all descendants too, as our indentation level might have changed
- folder->requestArrange(TRUE);
- return TRUE;
-}
-
-void LLFolderViewFolder::requestArrange(BOOL include_descendants)
-{
- mLastArrangeGeneration = -1;
- // flag all items up to root
- if (mParentFolder)
- {
- mParentFolder->requestArrange();
- }
-
- if (include_descendants)
- {
- for (folders_t::iterator iter = mFolders.begin();
- iter != mFolders.end();
- ++iter)
- {
- (*iter)->requestArrange(TRUE);
- }
- }
-}
-
-void LLFolderViewFolder::toggleOpen()
-{
- setOpen(!mIsOpen);
-}
-
-// Force a folder open or closed
-void LLFolderViewFolder::setOpen(BOOL openitem)
-{
- setOpenArrangeRecursively(openitem);
-}
-
-void LLFolderViewFolder::setOpenArrangeRecursively(BOOL openitem, ERecurseType recurse)
-{
- BOOL was_open = mIsOpen;
- mIsOpen = openitem;
- if(!was_open && openitem)
- {
- if(mListener)
- {
- mListener->openItem();
- }
- }
-
- if (recurse == RECURSE_DOWN || recurse == RECURSE_UP_DOWN)
- {
- for (folders_t::iterator iter = mFolders.begin();
- iter != mFolders.end();)
- {
- folders_t::iterator fit = iter++;
- (*fit)->setOpenArrangeRecursively(openitem, RECURSE_DOWN); /* Flawfinder: ignore */
- }
- }
- if (mParentFolder && (recurse == RECURSE_UP || recurse == RECURSE_UP_DOWN))
- {
- mParentFolder->setOpenArrangeRecursively(openitem, RECURSE_UP);
- }
-
- if (was_open != mIsOpen)
- {
- requestArrange();
- }
-}
-
-BOOL LLFolderViewFolder::handleDragAndDropFromChild(MASK mask,
- BOOL drop,
- EDragAndDropType c_type,
- void* cargo_data,
- EAcceptance* accept,
- std::string& tooltip_msg)
-{
- BOOL accepted = mListener && mListener->dragOrDrop(mask,drop,c_type,cargo_data);
- if (accepted)
- {
- mDragAndDropTarget = TRUE;
- *accept = ACCEPT_YES_MULTI;
- }
- else
- {
- *accept = ACCEPT_NO;
- }
-
- // drag and drop to child item, so clear pending auto-opens
- getRoot()->autoOpenTest(NULL);
-
- return TRUE;
-}
-
-void LLFolderViewFolder::openItem( void )
-{
- toggleOpen();
-}
-
-void LLFolderViewFolder::applyFunctorRecursively(LLFolderViewFunctor& functor)
-{
- functor.doFolder(this);
-
- for (folders_t::iterator iter = mFolders.begin();
- iter != mFolders.end();)
- {
- folders_t::iterator fit = iter++;
- (*fit)->applyFunctorRecursively(functor);
- }
- for (items_t::iterator iter = mItems.begin();
- iter != mItems.end();)
- {
- items_t::iterator iit = iter++;
- functor.doItem((*iit));
- }
-}
-
-void LLFolderViewFolder::applyListenerFunctorRecursively(LLFolderViewListenerFunctor& functor)
-{
- functor(mListener);
- for (folders_t::iterator iter = mFolders.begin();
- iter != mFolders.end();)
- {
- folders_t::iterator fit = iter++;
- (*fit)->applyListenerFunctorRecursively(functor);
- }
- for (items_t::iterator iter = mItems.begin();
- iter != mItems.end();)
- {
- items_t::iterator iit = iter++;
- (*iit)->applyListenerFunctorRecursively(functor);
- }
-}
-
-// LLView functionality
-BOOL LLFolderViewFolder::handleDragAndDrop(S32 x, S32 y, MASK mask,
- BOOL drop,
- EDragAndDropType cargo_type,
- void* cargo_data,
- EAcceptance* accept,
- std::string& tooltip_msg)
-{
- LLFolderView* root_view = getRoot();
-
- BOOL handled = FALSE;
- if(mIsOpen)
- {
- handled = childrenHandleDragAndDrop(x, y, mask, drop, cargo_type,
- cargo_data, accept, tooltip_msg) != NULL;
- }
-
- if (!handled)
- {
- BOOL accepted = mListener && mListener->dragOrDrop(mask, drop,cargo_type,cargo_data);
-
- if (accepted)
- {
- mDragAndDropTarget = TRUE;
- *accept = ACCEPT_YES_MULTI;
- }
- else
- {
- *accept = ACCEPT_NO;
- }
-
- if (!drop && accepted)
- {
- root_view->autoOpenTest(this);
- }
-
- lldebugst(LLERR_USER_INPUT) << "dragAndDrop handled by LLFolderViewFolder" << llendl;
- }
-
- return TRUE;
-}
-
-
-BOOL LLFolderViewFolder::handleRightMouseDown( S32 x, S32 y, MASK mask )
-{
- BOOL handled = FALSE;
- // fetch contents of this folder, as context menu can depend on contents
- // still, user would have to open context menu again to see the changes
- gInventory.fetchDescendentsOf(mListener->getUUID());
-
- if( mIsOpen )
- {
- handled = childrenHandleRightMouseDown( x, y, mask ) != NULL;
- }
- if (!handled)
- {
- handled = LLFolderViewItem::handleRightMouseDown( x, y, mask );
- }
- return handled;
-}
-
-
-BOOL LLFolderViewFolder::handleHover(S32 x, S32 y, MASK mask)
-{
- BOOL handled = LLView::handleHover(x, y, mask);
-
- if (!handled)
- {
- // this doesn't do child processing
- handled = LLFolderViewItem::handleHover(x, y, mask);
- }
-
- //if(x < LEFT_INDENTATION + mIndentation && x > mIndentation - LEFT_PAD && y > getRect().getHeight() - )
- //{
- // gViewerWindow->setCursor(UI_CURSOR_ARROW);
- // mExpanderHighlighted = TRUE;
- // handled = TRUE;
- //}
- return handled;
-}
-
-BOOL LLFolderViewFolder::handleMouseDown( S32 x, S32 y, MASK mask )
-{
- BOOL handled = FALSE;
- if( mIsOpen )
- {
- handled = childrenHandleMouseDown(x,y,mask) != NULL;
- }
- if( !handled )
- {
- if(x < LEFT_INDENTATION + mIndentation && x > mIndentation - LEFT_PAD)
- {
- toggleOpen();
- handled = TRUE;
- }
- else
- {
- // do normal selection logic
- handled = LLFolderViewItem::handleMouseDown(x, y, mask);
- }
- }
-
- return handled;
-}
-
-BOOL LLFolderViewFolder::handleDoubleClick( S32 x, S32 y, MASK mask )
-{
- BOOL handled = FALSE;
- if( mIsOpen )
- {
- handled = childrenHandleDoubleClick( x, y, mask ) != NULL;
- }
- if( !handled )
- {
- if(x < LEFT_INDENTATION + mIndentation && x > mIndentation - LEFT_PAD)
- {
- // don't select when user double-clicks plus sign
- // so as not to contradict single-click behavior
- toggleOpen();
- }
- else
- {
- setSelectionFromRoot(this, FALSE);
- toggleOpen();
- }
- handled = TRUE;
- }
- return handled;
-}
-
-void LLFolderViewFolder::draw()
-{
- if (mAutoOpenCountdown != 0.f)
- {
- mControlLabelRotation = mAutoOpenCountdown * -90.f;
- }
- else if (mIsOpen)
- {
- mControlLabelRotation = lerp(mControlLabelRotation, -90.f, LLCriticalDamp::getInterpolant(0.04f));
- }
- else
- {
- mControlLabelRotation = lerp(mControlLabelRotation, 0.f, LLCriticalDamp::getInterpolant(0.025f));
- }
-
- bool possibly_has_children = false;
- bool up_to_date = mListener && mListener->isUpToDate();
- if(!up_to_date && mListener && mListener->hasChildren()) // we know we have children but haven't fetched them (doesn't obey filter)
- {
- possibly_has_children = true;
- }
-
-
- BOOL loading = ( mIsOpen && possibly_has_children && !up_to_date );
-
- if ( loading && !mIsLoading )
- {
- // Measure how long we've been in the loading state
- mTimeSinceRequestStart.reset();
- }
-
- mIsLoading = loading;
-
- LLFolderViewItem::draw();
-
- // draw children if root folder, or any other folder that is open or animating to closed state
- if( getRoot() == this || (mIsOpen || mCurHeight != mTargetHeight ))
- {
- LLView::draw();
- }
-
- mExpanderHighlighted = FALSE;
-}
-
-time_t LLFolderViewFolder::getCreationDate() const
-{
- return llmax<time_t>(mCreationDate, mSubtreeCreationDate);
-}
-
-
-BOOL LLFolderViewFolder::potentiallyVisible()
-{
- // folder should be visible by it's own filter status
- return LLFolderViewItem::potentiallyVisible()
- // or one or more of its descendants have passed the minimum filter requirement
- || hasFilteredDescendants(mRoot->getFilter()->getMinRequiredGeneration())
- // or not all of its descendants have been checked against minimum filter requirement
- || getCompletedFilterGeneration() < getRoot()->getFilter()->getMinRequiredGeneration();
-}
-
-// this does prefix traversal, as folders are listed above their contents
-LLFolderViewItem* LLFolderViewFolder::getNextFromChild( LLFolderViewItem* item, BOOL include_children )
-{
- BOOL found_item = FALSE;
-
- LLFolderViewItem* result = NULL;
- // when not starting from a given item, start at beginning
- if(item == NULL)
- {
- found_item = TRUE;
- }
-
- // find current item among children
- folders_t::iterator fit = mFolders.begin();
- folders_t::iterator fend = mFolders.end();
-
- items_t::iterator iit = mItems.begin();
- items_t::iterator iend = mItems.end();
-
- // if not trivially starting at the beginning, we have to find the current item
- if (!found_item)
- {
- // first, look among folders, since they are always above items
- for(; fit != fend; ++fit)
- {
- if(item == (*fit))
- {
- found_item = TRUE;
- // if we are on downwards traversal
- if (include_children && (*fit)->isOpen())
- {
- // look for first descendant
- return (*fit)->getNextFromChild(NULL, TRUE);
- }
- // otherwise advance to next folder
- ++fit;
- include_children = TRUE;
- break;
- }
- }
-
- // didn't find in folders? Check items...
- if (!found_item)
- {
- for(; iit != iend; ++iit)
- {
- if(item == (*iit))
- {
- found_item = TRUE;
- // point to next item
- ++iit;
- break;
- }
- }
- }
- }
-
- if (!found_item)
- {
- // you should never call this method with an item that isn't a child
- // so we should always find something
- llassert(FALSE);
- return NULL;
- }
-
- // at this point, either iit or fit point to a candidate "next" item
- // if both are out of range, we need to punt up to our parent
-
- // now, starting from found folder, continue through folders
- // searching for next visible folder
- while(fit != fend && !(*fit)->getVisible())
- {
- // turn on downwards traversal for next folder
- ++fit;
- }
-
- if (fit != fend)
- {
- result = (*fit);
- }
- else
- {
- // otherwise, scan for next visible item
- while(iit != iend && !(*iit)->getVisible())
- {
- ++iit;
- }
-
- // check to see if we have a valid item
- if (iit != iend)
- {
- result = (*iit);
- }
- }
-
- if( !result && mParentFolder )
- {
- // If there are no siblings or children to go to, recurse up one level in the tree
- // and skip children for this folder, as we've already discounted them
- result = mParentFolder->getNextFromChild(this, FALSE);
- }
-
- return result;
-}
-
-// this does postfix traversal, as folders are listed above their contents
-LLFolderViewItem* LLFolderViewFolder::getPreviousFromChild( LLFolderViewItem* item, BOOL include_children )
-{
- BOOL found_item = FALSE;
-
- LLFolderViewItem* result = NULL;
- // when not starting from a given item, start at end
- if(item == NULL)
- {
- found_item = TRUE;
- }
-
- // find current item among children
- folders_t::reverse_iterator fit = mFolders.rbegin();
- folders_t::reverse_iterator fend = mFolders.rend();
-
- items_t::reverse_iterator iit = mItems.rbegin();
- items_t::reverse_iterator iend = mItems.rend();
-
- // if not trivially starting at the end, we have to find the current item
- if (!found_item)
- {
- // first, look among items, since they are always below the folders
- for(; iit != iend; ++iit)
- {
- if(item == (*iit))
- {
- found_item = TRUE;
- // point to next item
- ++iit;
- break;
- }
- }
-
- // didn't find in items? Check folders...
- if (!found_item)
- {
- for(; fit != fend; ++fit)
- {
- if(item == (*fit))
- {
- found_item = TRUE;
- // point to next folder
- ++fit;
- break;
- }
- }
- }
- }
-
- if (!found_item)
- {
- // you should never call this method with an item that isn't a child
- // so we should always find something
- llassert(FALSE);
- return NULL;
- }
-
- // at this point, either iit or fit point to a candidate "next" item
- // if both are out of range, we need to punt up to our parent
-
- // now, starting from found item, continue through items
- // searching for next visible item
- while(iit != iend && !(*iit)->getVisible())
- {
- ++iit;
- }
-
- if (iit != iend)
- {
- // we found an appropriate item
- result = (*iit);
- }
- else
- {
- // otherwise, scan for next visible folder
- while(fit != fend && !(*fit)->getVisible())
- {
- ++fit;
- }
-
- // check to see if we have a valid folder
- if (fit != fend)
- {
- // try selecting child element of this folder
- if ((*fit)->isOpen())
- {
- result = (*fit)->getPreviousFromChild(NULL);
- }
- else
- {
- result = (*fit);
- }
- }
- }
-
- if( !result )
- {
- // If there are no siblings or children to go to, recurse up one level in the tree
- // which gets back to this folder, which will only be visited if it is a valid, visible item
- result = this;
- }
-
- return result;
-}
-
//---------------------------------------------------------------------------
@@ -2494,39 +166,32 @@ void LLCloseAllFoldersFunctor::doItem(LLFolderViewItem* item)
///----------------------------------------------------------------------------
// Default constructor
-LLFolderView::LLFolderView( const std::string& name, LLUIImagePtr root_folder_icon,
- const LLRect& rect, const LLUUID& source_id, LLView *parent_view ) :
-#if LL_WINDOWS
-#pragma warning( push )
-#pragma warning( disable : 4355 ) // warning C4355: 'this' : used in base member initializer list
-#endif
- LLFolderViewFolder( name, root_folder_icon, this, NULL ),
-#if LL_WINDOWS
-#pragma warning( pop )
-#endif
+LLFolderView::LLFolderView(const Params& p)
+: LLFolderViewFolder(p),
mScrollContainer( NULL ),
mPopupMenuHandle(),
mAllowMultiSelect(TRUE),
mShowFolderHierarchy(FALSE),
- mSourceID(source_id),
+ mSourceID(p.task_id),
mRenameItem( NULL ),
mNeedsScroll( FALSE ),
- mLastScrollItem( NULL ),
+ mPinningSelectedItem(FALSE),
mNeedsAutoSelect( FALSE ),
mAutoSelectOverride(FALSE),
mNeedsAutoRename(FALSE),
mDebugFilters(FALSE),
mSortOrder(LLInventoryFilter::SO_FOLDERS_BY_NAME), // This gets overridden by a pref immediately
- mFilter(name),
+ mFilter( new LLInventoryFilter(p.name) ),
mShowSelectionContext(FALSE),
mShowSingleSelection(FALSE),
mArrangeGeneration(0),
- mUserData(NULL),
- mSelectCallback(NULL),
mSignalSelectCallback(0),
mMinWidth(0),
- mDragAndDropThisFrame(FALSE)
+ mDragAndDropThisFrame(FALSE),
+ mCallbackRegistrar(NULL),
+ mParentPanel(p.parent_panel)
{
+ LLRect rect = p.rect;
LLRect new_rect(rect.mLeft, rect.mBottom + getRect().getHeight(), rect.mLeft + getRect().getWidth(), rect.mBottom);
setRect( rect );
reshape(rect.getWidth(), rect.getHeight());
@@ -2543,30 +208,29 @@ LLFolderView::LLFolderView( const std::string& name, LLUIImagePtr root_folder_ic
// just make sure the label ("Inventory Folder") never shows up
mLabel = LLStringUtil::null;
- mRenamer = new LLLineEditor(std::string("ren"), getRect(), LLStringUtil::null, sFont,
- DB_INV_ITEM_NAME_STR_LEN,
- &LLFolderView::commitRename,
- NULL,
- NULL,
- this,
- &LLLineEditor::prevalidatePrintableNotPipe);
//mRenamer->setWriteableBgColor(LLColor4::white);
// Escape is handled by reverting the rename, not commiting it (default behavior)
- mRenamer->setCommitOnFocusLost(TRUE);
- mRenamer->setVisible(FALSE);
+ LLLineEditor::Params params;
+ params.name("ren");
+ params.rect(getRect());
+ params.font(sFont);
+ params.max_length_bytes(DB_INV_ITEM_NAME_STR_LEN);
+ params.commit_callback.function(boost::bind(&LLFolderView::commitRename, this, _2));
+ params.prevalidate_callback(&LLLineEditor::prevalidatePrintableNotPipe);
+ params.commit_on_focus_lost(true);
+ params.visible(false);
+ mRenamer = LLUICtrlFactory::create<LLLineEditor> (params);
addChild(mRenamer);
// make the popup menu available
- LLMenuGL* menu = LLUICtrlFactory::getInstance()->buildMenu("menu_inventory.xml", parent_view);
+ LLMenuGL* menu = LLUICtrlFactory::getInstance()->createFromFile<LLMenuGL>("menu_inventory.xml", gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance());
if (!menu)
{
- menu = new LLMenuGL(LLStringUtil::null);
+ menu = LLUICtrlFactory::getDefaultWidget<LLMenuGL>("inventory_menu");
}
- menu->setBackgroundColor(gColors.getColor("MenuPopupBgColor"));
- menu->setVisible(FALSE);
+ menu->setBackgroundColor(LLUIColorTable::instance().getColor("MenuPopupBgColor"));
mPopupMenuHandle = menu->getHandle();
- setTabStop(TRUE);
}
// Destroys the object
@@ -2580,7 +244,6 @@ LLFolderView::~LLFolderView( void )
mScrollContainer = NULL;
mRenameItem = NULL;
mRenamer = NULL;
- gFocusMgr.releaseFocusIfNeeded( this );
if( gEditMenuHandler == this )
{
@@ -2603,6 +266,9 @@ LLFolderView::~LLFolderView( void )
mFolders.clear();
mItemMap.clear();
+
+ delete mFilter;
+ mFilter = NULL;
}
BOOL LLFolderView::canFocusChildren() const
@@ -2622,11 +288,13 @@ void LLFolderView::checkTreeResortForModelChanged()
}
}
+static LLFastTimer::DeclareTimer FTM_SORT("Sort Inventory");
+
void LLFolderView::setSortOrder(U32 order)
{
if (order != mSortOrder)
{
- LLFastTimer t(LLFastTimer::FTM_SORT);
+ LLFastTimer t(FTM_SORT);
mSortOrder = order;
for (folders_t::iterator iter = mFolders.begin();
@@ -2649,7 +317,7 @@ U32 LLFolderView::getSortOrder() const
BOOL LLFolderView::addFolder( LLFolderViewFolder* folder)
{
// enforce sort order of My Inventory followed by Library
- if (folder->getListener()->getUUID() == gInventoryLibraryRoot)
+ if (folder->getListener()->getUUID() == gInventory.getLibraryRootFolderID())
{
mFolders.push_back(folder);
}
@@ -2670,11 +338,12 @@ void LLFolderView::closeAllFolders()
{
// Close all the folders
setOpenArrangeRecursively(FALSE, LLFolderViewFolder::RECURSE_DOWN);
+ arrangeAll();
}
void LLFolderView::openFolder(const std::string& foldername)
{
- LLFolderViewFolder* inv = getChild<LLFolderViewFolder>(foldername);
+ LLFolderViewFolder* inv = findChild<LLFolderViewFolder>(foldername);
if (inv)
{
setSelection(inv, FALSE, FALSE);
@@ -2690,19 +359,22 @@ void LLFolderView::setOpenArrangeRecursively(BOOL openitem, ERecurseType recurse
mIsOpen = TRUE;
}
+static LLFastTimer::DeclareTimer FTM_ARRANGE("Arrange");
+
// This view grows and shinks to enclose all of its children items and folders.
S32 LLFolderView::arrange( S32* unused_width, S32* unused_height, S32 filter_generation )
{
- LLFastTimer t2(LLFastTimer::FTM_ARRANGE);
+ LLFastTimer t2(FTM_ARRANGE);
- filter_generation = mFilter.getMinRequiredGeneration();
+ filter_generation = mFilter->getMinRequiredGeneration();
mMinWidth = 0;
mHasVisibleChildren = hasFilteredDescendants(filter_generation);
// arrange always finishes, so optimistically set the arrange generation to the most current
- mLastArrangeGeneration = mRoot->getArrangeGeneration();
+ mLastArrangeGeneration = getRoot()->getArrangeGeneration();
- LLInventoryFilter::EFolderShow show_folder_state = getRoot()->getShowFolderState();
+ LLInventoryFilter::EFolderShow show_folder_state =
+ getRoot()->getFilter()->getShowFolderState();
S32 total_width = LEFT_PAD;
S32 running_height = mDebugFilters ? llceil(sSmallFont->getLineHeight()) : 0;
@@ -2761,31 +433,32 @@ S32 LLFolderView::arrange( S32* unused_width, S32* unused_height, S32 filter_gen
}
}
- S32 dummy_s32;
- BOOL dummy_bool;
- S32 min_width;
- mScrollContainer->calcVisibleSize( &min_width, &dummy_s32, &dummy_bool, &dummy_bool);
- reshape( llmax(min_width, total_width), running_height );
+ LLRect scroll_rect = mScrollContainer->getContentWindowRect();
+ reshape( llmax(scroll_rect.getWidth(), total_width), running_height );
- S32 new_min_width;
- mScrollContainer->calcVisibleSize( &new_min_width, &dummy_s32, &dummy_bool, &dummy_bool);
- if (new_min_width != min_width)
+ LLRect new_scroll_rect = mScrollContainer->getContentWindowRect();
+ if (new_scroll_rect.getWidth() != scroll_rect.getWidth())
{
- reshape( llmax(min_width, total_width), running_height );
+ reshape( llmax(scroll_rect.getWidth(), total_width), running_height );
}
+ // move item renamer text field to item's new position
+ updateRenamerPosition();
+
mTargetHeight = (F32)target_height;
return llround(mTargetHeight);
}
const std::string LLFolderView::getFilterSubString(BOOL trim)
{
- return mFilter.getFilterSubString(trim);
+ return mFilter->getFilterSubString(trim);
}
+static LLFastTimer::DeclareTimer FTM_FILTER("Filter Inventory");
+
void LLFolderView::filter( LLInventoryFilter& filter )
{
- LLFastTimer t2(LLFastTimer::FTM_FILTER);
+ LLFastTimer t2(FTM_FILTER);
filter.setFilterCount(llclamp(gSavedSettings.getS32("FilterItemsPerFrame"), 1, 5000));
if (getCompletedFilterGeneration() < filter.getCurrentGeneration())
@@ -2794,19 +467,23 @@ void LLFolderView::filter( LLInventoryFilter& filter )
mMinWidth = 0;
LLFolderViewFolder::filter(filter);
}
+ else
+ {
+ mFiltered = TRUE;
+ }
}
void LLFolderView::reshape(S32 width, S32 height, BOOL called_from_parent)
{
- S32 min_width = 0;
- S32 dummy_height;
- BOOL dummy_bool;
+ LLRect scroll_rect;
if (mScrollContainer)
{
- mScrollContainer->calcVisibleSize( &min_width, &dummy_height, &dummy_bool, &dummy_bool);
+ scroll_rect = mScrollContainer->getContentWindowRect();
}
- width = llmax(mMinWidth, min_width);
+ width = llmax(mMinWidth, scroll_rect.getWidth());
LLView::reshape(width, height, called_from_parent);
+
+ mReshapeSignal(mSelectedItems, FALSE);
}
void LLFolderView::addToSelectionList(LLFolderViewItem* item)
@@ -2871,7 +548,7 @@ BOOL LLFolderView::setSelection(LLFolderViewItem* selection, BOOL openitem,
if( selection && take_keyboard_focus)
{
- setFocus(TRUE);
+ mParentPanel->setFocus(TRUE);
}
// clear selection down here because change of keyboard focus can potentially
@@ -2896,6 +573,30 @@ BOOL LLFolderView::setSelection(LLFolderViewItem* selection, BOOL openitem,
return rv;
}
+void LLFolderView::setSelectionByID(const LLUUID& obj_id, BOOL take_keyboard_focus)
+{
+ LLFolderViewItem* itemp = getItemByID(obj_id);
+ if(itemp && itemp->getListener())
+ {
+ itemp->arrangeAndSet(TRUE, take_keyboard_focus);
+ mSelectThisID.setNull();
+ return;
+ }
+ else
+ {
+ // save the desired item to be selected later (if/when ready)
+ mSelectThisID = obj_id;
+ }
+}
+
+void LLFolderView::updateSelection()
+{
+ if (mSelectThisID.notNull())
+ {
+ setSelectionByID(mSelectThisID, false);
+ }
+}
+
BOOL LLFolderView::changeSelection(LLFolderViewItem* selection, BOOL selected)
{
BOOL rv = FALSE;
@@ -2970,7 +671,7 @@ void LLFolderView::sanitizeSelection()
LLFolderViewItem* original_selected_item = getCurSelectedItem();
// Cache "Show all folders" filter setting
- BOOL show_all_folders = (getRoot()->getShowFolderState() == LLInventoryFilter::SHOW_ALL_FOLDERS);
+ BOOL show_all_folders = (getRoot()->getFilter()->getShowFolderState() == LLInventoryFilter::SHOW_ALL_FOLDERS);
std::vector<LLFolderViewItem*> items_to_remove;
selected_items_t::iterator item_iter;
@@ -3060,7 +761,7 @@ void LLFolderView::sanitizeSelection()
else
{
// nothing selected to start with, so pick "My Inventory" as best guess
- new_selection = getItemByID(gAgent.getInventoryRootID());
+ new_selection = getItemByID(gInventory.getRootFolderID());
}
if (new_selection)
@@ -3077,6 +778,7 @@ void LLFolderView::clearSelection()
recursiveDeselect(FALSE);
mSelectedItems.clear();
}
+ mSelectThisID.setNull();
}
BOOL LLFolderView::getSelectionList(std::set<LLUUID> &selection)
@@ -3113,24 +815,21 @@ BOOL LLFolderView::startDrag(LLToolDragAndDrop::ESource source)
return can_drag;
}
-void LLFolderView::commitRename( LLUICtrl* renamer, void* user_data )
+void LLFolderView::commitRename( const LLSD& data )
{
- LLFolderView* root = reinterpret_cast<LLFolderView*>(user_data);
- if( root )
- {
- root->finishRenamingItem();
- }
+ finishRenamingItem();
}
void LLFolderView::draw()
{
+ static LLUIColor sSearchStatusColor = LLUIColorTable::instance().getColor("InventorySearchStatusColor", LLColor4::white);
if (mDebugFilters)
{
std::string current_filter_string = llformat("Current Filter: %d, Least Filter: %d, Auto-accept Filter: %d",
- mFilter.getCurrentGeneration(), mFilter.getMinRequiredGeneration(), mFilter.getMustPassGeneration());
+ mFilter->getCurrentGeneration(), mFilter->getMinRequiredGeneration(), mFilter->getMustPassGeneration());
sSmallFont->renderUTF8(current_filter_string, 0, 2,
getRect().getHeight() - sSmallFont->getLineHeight(), LLColor4(0.5f, 0.5f, 0.8f, 1.f),
- LLFontGL::LEFT, LLFontGL::BOTTOM, LLFontGL::NORMAL, S32_MAX, S32_MAX, NULL, FALSE );
+ LLFontGL::LEFT, LLFontGL::BOTTOM, LLFontGL::NORMAL, LLFontGL::NO_SHADOW, S32_MAX, S32_MAX, NULL, FALSE );
}
// if cursor has moved off of me during drag and drop
@@ -3139,10 +838,6 @@ void LLFolderView::draw()
{
closeAutoOpenedFolders();
}
- if(this == gFocusMgr.getKeyboardFocus() && !getVisible())
- {
- gFocusMgr.setKeyboardFocus( NULL );
- }
// while dragging, update selection rendering to reflect single/multi drag status
if (LLToolDragAndDrop::getInstance()->hasMouseCapture())
@@ -3168,21 +863,22 @@ void LLFolderView::draw()
mSearchString.clear();
}
- if (hasVisibleChildren() || getShowFolderState() == LLInventoryFilter::SHOW_ALL_FOLDERS)
+ if (hasVisibleChildren()
+ || mFilter->getShowFolderState() == LLInventoryFilter::SHOW_ALL_FOLDERS)
{
mStatusText.clear();
}
else
{
- if (gInventory.backgroundFetchActive() || mCompletedFilterGeneration < mFilter.getMinRequiredGeneration())
+ if (gInventory.backgroundFetchActive() || mCompletedFilterGeneration < mFilter->getMinRequiredGeneration())
{
- mStatusText = std::string("Searching..."); // *TODO:translate
- sFont->renderUTF8(mStatusText, 0, 2, 1, sSearchStatusColor, LLFontGL::LEFT, LLFontGL::TOP, LLFontGL::NORMAL, S32_MAX, S32_MAX, NULL, FALSE );
+ mStatusText = LLTrans::getString("Searching");
+ sFont->renderUTF8(mStatusText, 0, 2, 1, sSearchStatusColor, LLFontGL::LEFT, LLFontGL::TOP, LLFontGL::NORMAL, LLFontGL::NO_SHADOW, S32_MAX, S32_MAX, NULL, FALSE );
}
else
{
- mStatusText = std::string("No matching items found in inventory."); // *TODO:translate
- sFont->renderUTF8(mStatusText, 0, 2, 1, sSearchStatusColor, LLFontGL::LEFT, LLFontGL::TOP, LLFontGL::NORMAL, S32_MAX, S32_MAX, NULL, FALSE );
+ mStatusText = LLTrans::getString("InventoryNoMatchingItems");
+ sFont->renderUTF8(mStatusText, 0, 2, 1, sSearchStatusColor, LLFontGL::LEFT, LLFontGL::TOP, LLFontGL::NORMAL, LLFontGL::NO_SHADOW, S32_MAX, S32_MAX, NULL, FALSE );
}
}
@@ -3280,11 +976,11 @@ void LLFolderView::removeSelectedItems( void )
// change selection on successful delete
if (new_selection)
{
- setSelectionFromRoot(new_selection, new_selection->isOpen(), gFocusMgr.childHasKeyboardFocus(this));
+ setSelectionFromRoot(new_selection, new_selection->isOpen(), mParentPanel->hasFocus());
}
else
{
- setSelectionFromRoot(NULL, gFocusMgr.childHasKeyboardFocus(this));
+ setSelectionFromRoot(NULL, mParentPanel->hasFocus());
}
}
}
@@ -3310,11 +1006,11 @@ void LLFolderView::removeSelectedItems( void )
}
if (new_selection)
{
- setSelectionFromRoot(new_selection, new_selection->isOpen(), gFocusMgr.childHasKeyboardFocus(this));
+ setSelectionFromRoot(new_selection, new_selection->isOpen(), mParentPanel->hasFocus());
}
else
{
- setSelectionFromRoot(NULL, gFocusMgr.childHasKeyboardFocus(this));
+ setSelectionFromRoot(NULL, mParentPanel->hasFocus());
}
for(S32 i = 0; i < count; ++i)
@@ -3347,11 +1043,8 @@ void LLFolderView::openSelectedItems( void )
}
else
{
- S32 left, top;
- gFloaterView->getNewFloaterPosition(&left, &top);
- LLMultiPreview* multi_previewp = new LLMultiPreview(LLRect(left, top, left + 300, top - 100));
- gFloaterView->getNewFloaterPosition(&left, &top);
- LLMultiProperties* multi_propertiesp = new LLMultiProperties(LLRect(left, top, left + 300, top - 100));
+ LLMultiPreview* multi_previewp = new LLMultiPreview();
+ LLMultiProperties* multi_propertiesp = new LLMultiProperties();
selected_items_t::iterator item_it;
for (item_it = mSelectedItems.begin(); item_it != mSelectedItems.end(); ++item_it)
@@ -3371,8 +1064,8 @@ void LLFolderView::openSelectedItems( void )
LLFloater::setFloaterHost(NULL);
// *NOTE: LLMulti* will safely auto-delete when open'd
// without any children.
- multi_previewp->open();
- multi_propertiesp->open();
+ multi_previewp->openFloater(LLSD());
+ multi_propertiesp->openFloater(LLSD());
}
}
}
@@ -3389,10 +1082,7 @@ void LLFolderView::propertiesSelectedItems( void )
}
else
{
- S32 left, top;
- gFloaterView->getNewFloaterPosition(&left, &top);
-
- LLMultiProperties* multi_propertiesp = new LLMultiProperties(LLRect(left, top, left + 100, top - 100));
+ LLMultiProperties* multi_propertiesp = new LLMultiProperties();
LLFloater::setFloaterHost(multi_propertiesp);
@@ -3403,11 +1093,21 @@ void LLFolderView::propertiesSelectedItems( void )
}
LLFloater::setFloaterHost(NULL);
- multi_propertiesp->open(); /* Flawfinder: ignore */
+ multi_propertiesp->openFloater(LLSD());
}
}
}
+void LLFolderView::changeType(LLInventoryModel *model, LLAssetType::EType new_folder_type)
+{
+ LLFolderBridge *folder_bridge = LLFolderBridge::sSelf;
+
+ if (!folder_bridge) return;
+ LLViewerInventoryCategory *cat = folder_bridge->getCategory();
+ if (!cat) return;
+ cat->changeType(new_folder_type);
+}
+
void LLFolderView::autoOpenItem( LLFolderViewFolder* item )
{
if (mAutoOpenItems.check() == item || mAutoOpenItems.getDepth() >= (U32)AUTO_OPEN_STACK_DEPTH)
@@ -3429,7 +1129,9 @@ void LLFolderView::autoOpenItem( LLFolderViewFolder* item )
mAutoOpenItems.push(item);
item->setOpen(TRUE);
- scrollToShowItem(item);
+ LLRect content_rect = mScrollContainer->getContentWindowRect();
+ LLRect constraint_rect(0,content_rect.getHeight(), content_rect.getWidth(), 0);
+ scrollToShowItem(item, constraint_rect);
}
void LLFolderView::closeAutoOpenedFolders()
@@ -3608,47 +1310,19 @@ void LLFolderView::startRenamingSelectedItem( void )
{
mRenameItem = item;
- S32 x = ARROW_SIZE + TEXT_PAD + ICON_WIDTH + ICON_PAD - 1 + item->getIndentation();
- S32 y = llfloor(item->getRect().getHeight()-sFont->getLineHeight()-2);
- item->localPointToScreen( x, y, &x, &y );
- screenPointToLocal( x, y, &x, &y );
- mRenamer->setOrigin( x, y );
+ updateRenamerPosition();
- S32 scroller_height = 0;
- S32 scroller_width = gViewerWindow->getWindowWidth();
- BOOL dummy_bool;
- if (mScrollContainer)
- {
- mScrollContainer->calcVisibleSize( &scroller_width, &scroller_height, &dummy_bool, &dummy_bool);
- }
-
- S32 width = llmax(llmin(item->getRect().getWidth() - x, scroller_width - x - getRect().mLeft), MINIMUM_RENAMER_WIDTH);
- S32 height = llfloor(sFont->getLineHeight() + RENAME_HEIGHT_PAD);
- mRenamer->reshape( width, height, TRUE );
mRenamer->setText(item->getName());
mRenamer->selectAll();
mRenamer->setVisible( TRUE );
// set focus will fail unless item is visible
mRenamer->setFocus( TRUE );
- mRenamer->setLostTopCallback(onRenamerLost);
+ mRenamer->setTopLostCallback(onRenamerLost);
gFocusMgr.setTopCtrl( mRenamer );
}
}
-void LLFolderView::setFocus(BOOL focus)
-{
- if (focus)
- {
- if(!hasFocus())
- {
- gEditMenuHandler = this;
- }
- }
-
- LLFolderViewFolder::setFocus(focus);
-}
-
BOOL LLFolderView::handleKeyHere( KEY key, MASK mask )
{
BOOL handled = FALSE;
@@ -3851,7 +1525,7 @@ BOOL LLFolderView::handleKeyHere( KEY key, MASK mask )
break;
}
- if (!handled && hasFocus())
+ if (!handled && mParentPanel->hasFocus())
{
if (key == KEY_BACKSPACE)
{
@@ -3940,20 +1614,11 @@ BOOL LLFolderView::handleMouseDown( S32 x, S32 y, MASK mask )
mKeyboardSelection = FALSE;
mSearchString.clear();
- setFocus(TRUE);
+ mParentPanel->setFocus(TRUE);
return LLView::handleMouseDown( x, y, mask );
}
-void LLFolderView::onFocusLost( )
-{
- if( gEditMenuHandler == this )
- {
- gEditMenuHandler = NULL;
- }
- LLUICtrl::onFocusLost();
-}
-
BOOL LLFolderView::search(LLFolderViewItem* first_item, const std::string &search_string, BOOL backward)
{
// get first selected item
@@ -4030,13 +1695,15 @@ BOOL LLFolderView::handleRightMouseDown( S32 x, S32 y, MASK mask )
{
// all user operations move keyboard focus to inventory
// this way, we know when to stop auto-updating a search
- setFocus(TRUE);
+ mParentPanel->setFocus(TRUE);
BOOL handled = childrenHandleRightMouseDown(x, y, mask) != NULL;
S32 count = mSelectedItems.size();
LLMenuGL* menu = (LLMenuGL*)mPopupMenuHandle.get();
if(handled && (count > 0) && menu)
{
+ if (mCallbackRegistrar)
+ mCallbackRegistrar->pushScope();
//menu->empty();
const LLView::child_list_t *list = menu->getChildList();
@@ -4056,9 +1723,10 @@ BOOL LLFolderView::handleRightMouseDown( S32 x, S32 y, MASK mask )
flags = 0x0;
}
- menu->arrange();
menu->updateParent(LLMenuGL::sMenuContainer);
LLMenuGL::showPopup(this, menu, x, y);
+ if (mCallbackRegistrar)
+ mCallbackRegistrar->popScope();
}
else
{
@@ -4127,49 +1795,41 @@ void LLFolderView::scrollToShowSelection()
// If the parent is scroll containter, scroll it to make the selection
// is maximally visible.
-void LLFolderView::scrollToShowItem(LLFolderViewItem* item)
+void LLFolderView::scrollToShowItem(LLFolderViewItem* item, const LLRect& constraint_rect)
{
+ if (!mScrollContainer) return;
+
// don't scroll to items when mouse is being used to scroll/drag and drop
if (gFocusMgr.childHasMouseCapture(mScrollContainer))
{
mNeedsScroll = FALSE;
return;
}
- if(item && mScrollContainer)
+
+ // if item exists and is in visible portion of parent folder...
+ if(item)
{
- LLRect local_rect = item->getRect();
+ LLRect local_rect = item->getLocalRect();
LLRect item_scrolled_rect; // item position relative to display area of scroller
+ LLRect visible_doc_rect = mScrollContainer->getVisibleContentRect();
S32 icon_height = mIcon.isNull() ? 0 : mIcon->getHeight();
S32 label_height = llround(sFont->getLineHeight());
// when navigating with keyboard, only move top of folders on screen, otherwise show whole folder
- S32 max_height_to_show = gFocusMgr.childHasKeyboardFocus(this) ? (llmax( icon_height, label_height ) + ICON_PAD) : local_rect.getHeight();
- item->localPointToOtherView(item->getIndentation(), llmax(0, local_rect.getHeight() - max_height_to_show), &item_scrolled_rect.mLeft, &item_scrolled_rect.mBottom, mScrollContainer);
- item->localPointToOtherView(local_rect.getWidth(), local_rect.getHeight(), &item_scrolled_rect.mRight, &item_scrolled_rect.mTop, mScrollContainer);
-
- item_scrolled_rect.mRight = llmin(item_scrolled_rect.mLeft + MIN_ITEM_WIDTH_VISIBLE, item_scrolled_rect.mRight);
- LLCoordGL scroll_offset(-mScrollContainer->getBorderWidth() - item_scrolled_rect.mLeft,
- mScrollContainer->getRect().getHeight() - item_scrolled_rect.mTop - 1);
-
- S32 max_scroll_offset = getVisibleRect().getHeight() - item_scrolled_rect.getHeight();
- if (item != mLastScrollItem || // if we're scrolling to focus on a new item
- // or the item has just appeared on screen and it wasn't onscreen before
- (scroll_offset.mY > 0 && scroll_offset.mY < max_scroll_offset &&
- (mLastScrollOffset.mY < 0 || mLastScrollOffset.mY > max_scroll_offset)))
- {
- // we now have a position on screen that we want to keep stable
- // offset of selection relative to top of visible area
- mLastScrollOffset = scroll_offset;
- mLastScrollItem = item;
- }
+ S32 max_height_to_show = mScrollContainer->hasFocus() ? (llmax( icon_height, label_height ) + ICON_PAD) : local_rect.getHeight();
+
+ // get portion of item that we want to see...
+ LLRect item_local_rect = LLRect(item->getIndentation(),
+ local_rect.getHeight(),
+ llmin(MIN_ITEM_WIDTH_VISIBLE, local_rect.getWidth()),
+ llmax(0, local_rect.getHeight() - max_height_to_show));
+
+ LLRect item_doc_rect;
- mScrollContainer->scrollToShowRect( item_scrolled_rect, mLastScrollOffset );
+ item->localRectToOtherView(item_local_rect, &item_doc_rect, this);
+
+ mScrollContainer->scrollToShowRect( item_doc_rect, constraint_rect );
- // after scrolling, store new offset
- // in case we don't have room to maintain the original position
- LLCoordGL new_item_left_top;
- item->localPointToOtherView(item->getIndentation(), item->getRect().getHeight(), &new_item_left_top.mX, &new_item_left_top.mY, mScrollContainer);
- mLastScrollOffset.set(-mScrollContainer->getBorderWidth() - new_item_left_top.mX, mScrollContainer->getRect().getHeight() - new_item_left_top.mY - 1);
}
}
@@ -4232,11 +1892,90 @@ LLFolderViewItem* LLFolderView::getItemByID(const LLUUID& id)
return NULL;
}
+bool LLFolderView::doToSelected(LLInventoryModel* model, const LLSD& userdata)
+{
+ std::string action = userdata.asString();
+
+ if ("rename" == action)
+ {
+ startRenamingSelectedItem();
+ return true;
+ }
+ if ("delete" == action)
+ {
+ removeSelectedItems();
+ return true;
+ }
+
+ if ("copy" == action)
+ {
+ LLInventoryClipboard::instance().reset();
+ }
+
+ static const std::string change_folder_string = "change_folder_type_";
+ if (action.length() > change_folder_string.length() &&
+ (action.compare(0,change_folder_string.length(),"change_folder_type_") == 0))
+ {
+ LLAssetType::EType new_folder_type = LLFolderType::lookupTypeFromXUIName(action.substr(change_folder_string.length()));
+ changeType(model, new_folder_type);
+ return true;
+ }
+
+
+ std::set<LLUUID> selected_items;
+ getSelectionList(selected_items);
+
+ LLMultiPreview* multi_previewp = NULL;
+ LLMultiProperties* multi_propertiesp = NULL;
+
+ if (("task_open" == action || "open" == action) && selected_items.size() > 1)
+ {
+ multi_previewp = new LLMultiPreview();
+ gFloaterView->addChild(multi_previewp);
+
+ LLFloater::setFloaterHost(multi_previewp);
+
+ }
+ else if (("task_properties" == action || "properties" == action) && selected_items.size() > 1)
+ {
+ multi_propertiesp = new LLMultiProperties();
+ gFloaterView->addChild(multi_propertiesp);
+
+ LLFloater::setFloaterHost(multi_propertiesp);
+ }
+
+ std::set<LLUUID>::iterator set_iter;
+
+ for (set_iter = selected_items.begin(); set_iter != selected_items.end(); ++set_iter)
+ {
+ LLFolderViewItem* folder_item = getItemByID(*set_iter);
+ if(!folder_item) continue;
+ LLInvFVBridge* bridge = (LLInvFVBridge*)folder_item->getListener();
+ if(!bridge) continue;
+
+ bridge->performAction(this, model, action);
+ }
+
+ LLFloater::setFloaterHost(NULL);
+ if (multi_previewp)
+ {
+ multi_previewp->openFloater(LLSD());
+ }
+ else if (multi_propertiesp)
+ {
+ multi_propertiesp->openFloater(LLSD());
+ }
+
+ return true;
+}
+
+static LLFastTimer::DeclareTimer FTM_AUTO_SELECT("Open and Select");
+static LLFastTimer::DeclareTimer FTM_INVENTORY("Inventory");
// Main idle routine
void LLFolderView::doIdle()
{
- LLFastTimer t2(LLFastTimer::FTM_INVENTORY);
+ LLFastTimer t2(FTM_INVENTORY);
BOOL debug_filters = gSavedSettings.getBOOL("DebugInventoryFilters");
if (debug_filters != getDebugFilters())
@@ -4245,12 +1984,12 @@ void LLFolderView::doIdle()
arrangeAll();
}
- mFilter.clearModified();
- BOOL filter_modified_and_active = mCompletedFilterGeneration < mFilter.getCurrentGeneration() &&
- mFilter.isNotDefault();
+ mFilter->clearModified();
+ BOOL filter_modified_and_active = mCompletedFilterGeneration < mFilter->getCurrentGeneration() &&
+ mFilter->isNotDefault();
mNeedsAutoSelect = filter_modified_and_active &&
!(gFocusMgr.childHasKeyboardFocus(this) || gFocusMgr.getMouseCapture());
-
+
// filter to determine visiblity before arranging
filterFromRoot();
@@ -4261,7 +2000,7 @@ void LLFolderView::doIdle()
// potentially changed
if (mNeedsAutoSelect)
{
- LLFastTimer t3(LLFastTimer::FTM_AUTO_SELECT);
+ LLFastTimer t3(FTM_AUTO_SELECT);
// select new item only if a filtered item not currently selected
LLFolderViewItem* selected_itemp = mSelectedItems.empty() ? NULL : mSelectedItems.back();
if ((!selected_itemp || !selected_itemp->getFiltered()) && !mAutoSelectOverride)
@@ -4273,6 +2012,59 @@ void LLFolderView::doIdle()
scrollToShowSelection();
}
+ // during filtering process, try to pin selected item's location on screen
+ // this will happen when searching your inventory and when new items arrive
+ if (filter_modified_and_active)
+ {
+ // calculate rectangle to pin item to at start of animated rearrange
+ if (!mPinningSelectedItem && !mSelectedItems.empty())
+ {
+ // lets pin it!
+ mPinningSelectedItem = TRUE;
+
+ LLRect visible_content_rect = mScrollContainer->getVisibleContentRect();
+ LLFolderViewItem* selected_item = mSelectedItems.back();
+
+ LLRect item_rect;
+ selected_item->localRectToOtherView(selected_item->getLocalRect(), &item_rect, this);
+ // if item is visible in scrolled region
+ if (visible_content_rect.overlaps(item_rect))
+ {
+ // then attempt to keep it in same place on screen
+ mScrollConstraintRect = item_rect;
+ mScrollConstraintRect.translate(-visible_content_rect.mLeft, -visible_content_rect.mBottom);
+ }
+ else
+ {
+ // otherwise we just want it onscreen somewhere
+ LLRect content_rect = mScrollContainer->getContentWindowRect();
+ mScrollConstraintRect.setOriginAndSize(0, 0, content_rect.getWidth(), content_rect.getHeight());
+ }
+ }
+ }
+ else
+ {
+ // stop pinning selected item after folders stop rearranging
+ if (!needsArrange())
+ {
+ mPinningSelectedItem = FALSE;
+ }
+ }
+
+ LLRect constraint_rect;
+ if (mPinningSelectedItem)
+ {
+ // use last known constraint rect for pinned item
+ constraint_rect = mScrollConstraintRect;
+ }
+ else
+ {
+ // during normal use (page up/page down, etc), just try to fit item on screen
+ LLRect content_rect = mScrollContainer->getContentWindowRect();
+ constraint_rect.setOriginAndSize(0, 0, content_rect.getWidth(), content_rect.getHeight());
+ }
+
+
BOOL is_visible = isInVisibleChain();
if ( is_visible )
@@ -4286,20 +2078,20 @@ void LLFolderView::doIdle()
if (mSelectedItems.size() && mNeedsScroll)
{
- scrollToShowItem(mSelectedItems.back());
+ scrollToShowItem(mSelectedItems.back(), constraint_rect);
// continue scrolling until animated layout change is done
- if (getCompletedFilterGeneration() >= mFilter.getMinRequiredGeneration() &&
- (!needsArrange() || !is_visible))
+ if (!filter_modified_and_active
+ && (!needsArrange() || !is_visible))
{
mNeedsScroll = FALSE;
}
}
- if (mSignalSelectCallback && mSelectCallback)
+ if (mSignalSelectCallback)
{
//RN: we use keyboard focus as a proxy for user-explicit actions
BOOL take_keyboard_focus = (mSignalSelectCallback == SIGNAL_KEYBOARD_FOCUS);
- mSelectCallback(mSelectedItems, take_keyboard_focus, mUserData);
+ mSelectSignal(mSelectedItems, take_keyboard_focus);
}
mSignalSelectCallback = FALSE;
}
@@ -4315,7 +2107,6 @@ void LLFolderView::idle(void* user_data)
}
}
-
void LLFolderView::dumpSelectionInformation()
{
llinfos << "LLFolderView::dumpSelectionInformation()" << llendl;
@@ -4328,706 +2119,120 @@ void LLFolderView::dumpSelectionInformation()
llinfos << "****************************************" << llendl;
}
-///----------------------------------------------------------------------------
-/// Local function definitions
-///----------------------------------------------------------------------------
-bool LLInventorySort::updateSort(U32 order)
+void LLFolderView::updateRenamerPosition()
{
- if (order != mSortOrder)
+ if(mRenameItem)
{
- mSortOrder = order;
- mByDate = (order & LLInventoryFilter::SO_DATE);
- mSystemToTop = (order & LLInventoryFilter::SO_SYSTEM_FOLDERS_TO_TOP);
- mFoldersByName = (order & LLInventoryFilter::SO_FOLDERS_BY_NAME);
- return true;
- }
- return false;
-}
-
-bool LLInventorySort::operator()(const LLFolderViewItem* const& a, const LLFolderViewItem* const& b)
-{
- // We sort by name if we aren't sorting by date
- // OR if these are folders and we are sorting folders by name.
- bool by_name = (!mByDate
- || (mFoldersByName
- && (a->getSortGroup() != SG_ITEM)));
-
- if (a->getSortGroup() != b->getSortGroup())
- {
- if (mSystemToTop)
- {
- // Group order is System Folders, Trash, Normal Folders, Items
- return (a->getSortGroup() < b->getSortGroup());
- }
- else if (mByDate)
- {
- // Trash needs to go to the bottom if we are sorting by date
- if ( (a->getSortGroup() == SG_TRASH_FOLDER)
- || (b->getSortGroup() == SG_TRASH_FOLDER))
- {
- return (b->getSortGroup() == SG_TRASH_FOLDER);
- }
- }
- }
+ S32 x = ARROW_SIZE + TEXT_PAD + ICON_WIDTH + ICON_PAD - 1 + mRenameItem->getIndentation();
+ S32 y = llfloor(mRenameItem->getRect().getHeight()-sFont->getLineHeight()-2);
+ mRenameItem->localPointToScreen( x, y, &x, &y );
+ screenPointToLocal( x, y, &x, &y );
+ mRenamer->setOrigin( x, y );
- if (by_name)
- {
- S32 compare = LLStringUtil::compareDict(a->getLabel(), b->getLabel());
- if (0 == compare)
- {
- return (a->getCreationDate() > b->getCreationDate());
- }
- else
- {
- return (compare < 0);
- }
- }
- else
- {
- // BUG: This is very very slow. The getCreationDate() is log n in number
- // of inventory items.
- time_t first_create = a->getCreationDate();
- time_t second_create = b->getCreationDate();
- if (first_create == second_create)
- {
- return (LLStringUtil::compareDict(a->getLabel(), b->getLabel()) < 0);
- }
- else
+ LLRect scroller_rect(0, 0, gViewerWindow->getWindowWidth(), 0);
+ if (mScrollContainer)
{
- return (first_create > second_create);
+ scroller_rect = mScrollContainer->getContentWindowRect();
}
- }
-}
-//static
-void LLFolderView::onRenamerLost( LLUICtrl* renamer, void* user_data)
-{
- renamer->setVisible(FALSE);
-}
-
-void delete_selected_item(void* user_data)
-{
- if(user_data)
- {
- LLFolderView* fv = reinterpret_cast<LLFolderView*>(user_data);
- fv->removeSelectedItems();
- }
-}
-
-void copy_selected_item(void* user_data)
-{
- if(user_data)
- {
- LLFolderView* fv = reinterpret_cast<LLFolderView*>(user_data);
- fv->copy();
- }
-}
-
-void paste_items(void* user_data)
-{
- if(user_data)
- {
- LLFolderView* fv = reinterpret_cast<LLFolderView*>(user_data);
- fv->paste();
- }
-}
-
-void open_selected_items(void* user_data)
-{
- if(user_data)
- {
- LLFolderView* fv = reinterpret_cast<LLFolderView*>(user_data);
- fv->openSelectedItems();
- }
-}
-
-void properties_selected_items(void* user_data)
-{
- if(user_data)
- {
- LLFolderView* fv = reinterpret_cast<LLFolderView*>(user_data);
- fv->propertiesSelectedItems();
- }
-}
-
-///----------------------------------------------------------------------------
-/// Class LLFolderViewEventListener
-///----------------------------------------------------------------------------
-
-void LLFolderViewEventListener::arrangeAndSet(LLFolderViewItem* focus,
- BOOL set_selection,
- BOOL take_keyboard_focus)
-{
- if(!focus) return;
- LLFolderView* root = focus->getRoot();
- focus->getParentFolder()->requestArrange();
- if(set_selection)
- {
- focus->setSelectionFromRoot(focus, TRUE, take_keyboard_focus);
- if(root)
- {
- root->scrollToShowSelection();
- }
+ S32 width = llmax(llmin(mRenameItem->getRect().getWidth() - x, scroller_rect.getWidth() - x - getRect().mLeft), MINIMUM_RENAMER_WIDTH);
+ S32 height = llfloor(sFont->getLineHeight() + RENAME_HEIGHT_PAD);
+ mRenamer->reshape( width, height, TRUE );
}
}
///----------------------------------------------------------------------------
-/// Class LLInventoryFilter
+/// Local function definitions
///----------------------------------------------------------------------------
-LLInventoryFilter::LLInventoryFilter(const std::string& name) :
- mName(name),
- mModified(FALSE),
- mNeedTextRebuild(TRUE)
-{
- mFilterOps.mFilterTypes = 0xffffffff;
- mFilterOps.mMinDate = time_min();
- mFilterOps.mMaxDate = time_max();
- mFilterOps.mHoursAgo = 0;
- mFilterOps.mShowFolderState = SHOW_NON_EMPTY_FOLDERS;
- mFilterOps.mPermissions = PERM_NONE;
-
- mOrder = SO_FOLDERS_BY_NAME; // This gets overridden by a pref immediately
- mSubStringMatchOffset = 0;
- mFilterSubString.clear();
- mFilterGeneration = 0;
- mMustPassGeneration = S32_MAX;
- mMinRequiredGeneration = 0;
- mFilterCount = 0;
- mNextFilterGeneration = mFilterGeneration + 1;
-
- mLastLogoff = gSavedPerAccountSettings.getU32("LastLogoff");
- mFilterBehavior = FILTER_NONE;
-
- // copy mFilterOps into mDefaultFilterOps
- markDefault();
-}
-
-LLInventoryFilter::~LLInventoryFilter()
-{
-}
-
-BOOL LLInventoryFilter::check(LLFolderViewItem* item)
+//static
+void LLFolderView::onRenamerLost( LLFocusableElement* renamer, void* user_data)
{
- time_t earliest;
-
- earliest = time_corrected() - mFilterOps.mHoursAgo * 3600;
- if (mFilterOps.mMinDate > time_min() && mFilterOps.mMinDate < earliest)
- {
- earliest = mFilterOps.mMinDate;
- }
- else if (!mFilterOps.mHoursAgo)
+ LLUICtrl* uictrl = dynamic_cast<LLUICtrl*>(renamer);
+ if (uictrl)
{
- earliest = 0;
+ uictrl->setVisible(FALSE);
}
- LLFolderViewEventListener* listener = item->getListener();
- mSubStringMatchOffset = mFilterSubString.size() ? item->getSearchableLabel().find(mFilterSubString) : std::string::npos;
- BOOL passed = (0x1 << listener->getInventoryType() & mFilterOps.mFilterTypes || listener->getInventoryType() == LLInventoryType::IT_NONE)
- && (mFilterSubString.size() == 0 || mSubStringMatchOffset != std::string::npos)
- && ((listener->getPermissionMask() & mFilterOps.mPermissions) == mFilterOps.mPermissions)
- && (listener->getCreationDate() >= earliest && listener->getCreationDate() <= mFilterOps.mMaxDate);
- return passed;
}
-const std::string LLInventoryFilter::getFilterSubString(BOOL trim)
+LLInventoryFilter* LLFolderView::getFilter()
{
- return mFilterSubString;
+ return mFilter;
}
-std::string::size_type LLInventoryFilter::getStringMatchOffset() const
+void LLFolderView::setFilterPermMask( PermissionMask filter_perm_mask )
{
- return mSubStringMatchOffset;
+ mFilter->setFilterPermissions(filter_perm_mask);
}
-// has user modified default filter params?
-BOOL LLInventoryFilter::isNotDefault()
+U32 LLFolderView::getFilterTypes() const
{
- return mFilterOps.mFilterTypes != mDefaultFilterOps.mFilterTypes
- || mFilterSubString.size()
- || mFilterOps.mPermissions != mDefaultFilterOps.mPermissions
- || mFilterOps.mMinDate != mDefaultFilterOps.mMinDate
- || mFilterOps.mMaxDate != mDefaultFilterOps.mMaxDate
- || mFilterOps.mHoursAgo != mDefaultFilterOps.mHoursAgo;
+ return mFilter->getFilterTypes();
}
-BOOL LLInventoryFilter::isActive()
+PermissionMask LLFolderView::getFilterPermissions() const
{
- return mFilterOps.mFilterTypes != 0xffffffff
- || mFilterSubString.size()
- || mFilterOps.mPermissions != PERM_NONE
- || mFilterOps.mMinDate != time_min()
- || mFilterOps.mMaxDate != time_max()
- || mFilterOps.mHoursAgo != 0;
+ return mFilter->getFilterPermissions();
}
-BOOL LLInventoryFilter::isModified()
-{
- return mModified;
-}
+// JAMESDEBUG
+//LLInventoryFilter::EFolderShow LLFolderView::getShowFolderState()
+//{
+// return mFilter->getShowFolderState();
+//}
-BOOL LLInventoryFilter::isModifiedAndClear()
+BOOL LLFolderView::isFilterModified()
{
- BOOL ret = mModified;
- mModified = FALSE;
- return ret;
+ return mFilter->isNotDefault();
}
-void LLInventoryFilter::setFilterTypes(U32 types)
+BOOL LLFolderView::getAllowMultiSelect()
{
- if (mFilterOps.mFilterTypes != types)
- {
- // keep current items only if no type bits getting turned off
- BOOL fewer_bits_set = (mFilterOps.mFilterTypes & ~types);
- BOOL more_bits_set = (~mFilterOps.mFilterTypes & types);
-
- mFilterOps.mFilterTypes = types;
- if (more_bits_set && fewer_bits_set)
- {
- // neither less or more restrive, both simultaneously
- // so we need to filter from scratch
- setModified(FILTER_RESTART);
- }
- else if (more_bits_set)
- {
- // target is only one of all requested types so more type bits == less restrictive
- setModified(FILTER_LESS_RESTRICTIVE);
- }
- else if (fewer_bits_set)
- {
- setModified(FILTER_MORE_RESTRICTIVE);
- }
-
- }
+ return mAllowMultiSelect;
}
-void LLInventoryFilter::setFilterSubString(const std::string& string)
-{
- if (mFilterSubString != string)
- {
- // hitting BACKSPACE, for example
- BOOL less_restrictive = mFilterSubString.size() >= string.size() && !mFilterSubString.substr(0, string.size()).compare(string);
- // appending new characters
- BOOL more_restrictive = mFilterSubString.size() < string.size() && !string.substr(0, mFilterSubString.size()).compare(mFilterSubString);
- mFilterSubString = string;
- LLStringUtil::toUpper(mFilterSubString);
- LLStringUtil::trimHead(mFilterSubString);
-
- if (less_restrictive)
- {
- setModified(FILTER_LESS_RESTRICTIVE);
- }
- else if (more_restrictive)
- {
- setModified(FILTER_MORE_RESTRICTIVE);
- }
- else
- {
- setModified(FILTER_RESTART);
- }
- }
-}
-
-void LLInventoryFilter::setFilterPermissions(PermissionMask perms)
-{
- if (mFilterOps.mPermissions != perms)
- {
- // keep current items only if no perm bits getting turned off
- BOOL fewer_bits_set = (mFilterOps.mPermissions & ~perms);
- BOOL more_bits_set = (~mFilterOps.mPermissions & perms);
- mFilterOps.mPermissions = perms;
-
- if (more_bits_set && fewer_bits_set)
- {
- setModified(FILTER_RESTART);
- }
- else if (more_bits_set)
- {
- // target must have all requested permission bits, so more bits == more restrictive
- setModified(FILTER_MORE_RESTRICTIVE);
- }
- else if (fewer_bits_set)
- {
- setModified(FILTER_LESS_RESTRICTIVE);
- }
- }
-}
-
-void LLInventoryFilter::setDateRange(time_t min_date, time_t max_date)
-{
- mFilterOps.mHoursAgo = 0;
- if (mFilterOps.mMinDate != min_date)
- {
- mFilterOps.mMinDate = min_date;
- setModified();
- }
- if (mFilterOps.mMaxDate != llmax(mFilterOps.mMinDate, max_date))
- {
- mFilterOps.mMaxDate = llmax(mFilterOps.mMinDate, max_date);
- setModified();
- }
-}
-
-void LLInventoryFilter::setDateRangeLastLogoff(BOOL sl)
-{
- if (sl && !isSinceLogoff())
- {
- setDateRange(mLastLogoff, time_max());
- setModified();
- }
- if (!sl && isSinceLogoff())
- {
- setDateRange(0, time_max());
- setModified();
- }
-}
-
-BOOL LLInventoryFilter::isSinceLogoff()
-{
- return (mFilterOps.mMinDate == (time_t)mLastLogoff) &&
- (mFilterOps.mMaxDate == time_max());
-}
-
-void LLInventoryFilter::setHoursAgo(U32 hours)
-{
- if (mFilterOps.mHoursAgo != hours)
- {
- // *NOTE: need to cache last filter time, in case filter goes stale
- BOOL less_restrictive = (mFilterOps.mMinDate == time_min() && mFilterOps.mMaxDate == time_max() && hours > mFilterOps.mHoursAgo);
- BOOL more_restrictive = (mFilterOps.mMinDate == time_min() && mFilterOps.mMaxDate == time_max() && hours <= mFilterOps.mHoursAgo);
- mFilterOps.mHoursAgo = hours;
- mFilterOps.mMinDate = time_min();
- mFilterOps.mMaxDate = time_max();
- if (less_restrictive)
- {
- setModified(FILTER_LESS_RESTRICTIVE);
- }
- else if (more_restrictive)
- {
- setModified(FILTER_MORE_RESTRICTIVE);
- }
- else
- {
- setModified(FILTER_RESTART);
- }
- }
-}
-void LLInventoryFilter::setShowFolderState(EFolderShow state)
+void delete_selected_item(void* user_data)
{
- if (mFilterOps.mShowFolderState != state)
+ if(user_data)
{
- mFilterOps.mShowFolderState = state;
- if (state == SHOW_NON_EMPTY_FOLDERS)
- {
- // showing fewer folders than before
- setModified(FILTER_MORE_RESTRICTIVE);
- }
- else if (state == SHOW_ALL_FOLDERS)
- {
- // showing same folders as before and then some
- setModified(FILTER_LESS_RESTRICTIVE);
- }
- else
- {
- setModified();
- }
+ LLFolderView* fv = reinterpret_cast<LLFolderView*>(user_data);
+ fv->removeSelectedItems();
}
}
-void LLInventoryFilter::setSortOrder(U32 order)
+void copy_selected_item(void* user_data)
{
- if (mOrder != order)
+ if(user_data)
{
- mOrder = order;
- setModified();
+ LLFolderView* fv = reinterpret_cast<LLFolderView*>(user_data);
+ fv->copy();
}
}
-void LLInventoryFilter::markDefault()
-{
- mDefaultFilterOps = mFilterOps;
-}
-
-void LLInventoryFilter::resetDefault()
-{
- mFilterOps = mDefaultFilterOps;
- setModified();
-}
-
-void LLInventoryFilter::setModified(EFilterBehavior behavior)
+void paste_items(void* user_data)
{
- mModified = TRUE;
- mNeedTextRebuild = TRUE;
- mFilterGeneration = mNextFilterGeneration++;
-
- if (mFilterBehavior == FILTER_NONE)
- {
- mFilterBehavior = behavior;
- }
- else if (mFilterBehavior != behavior)
- {
- // trying to do both less restrictive and more restrictive filter
- // basically means restart from scratch
- mFilterBehavior = FILTER_RESTART;
- }
-
- if (isNotDefault())
- {
- // if not keeping current filter results, update last valid as well
- switch(mFilterBehavior)
- {
- case FILTER_RESTART:
- mMustPassGeneration = mFilterGeneration;
- mMinRequiredGeneration = mFilterGeneration;
- break;
- case FILTER_LESS_RESTRICTIVE:
- mMustPassGeneration = mFilterGeneration;
- break;
- case FILTER_MORE_RESTRICTIVE:
- mMinRequiredGeneration = mFilterGeneration;
- // must have passed either current filter generation (meaningless, as it hasn't been run yet)
- // or some older generation, so keep the value
- mMustPassGeneration = llmin(mMustPassGeneration, mFilterGeneration);
- break;
- default:
- llerrs << "Bad filter behavior specified" << llendl;
- }
- }
- else
+ if(user_data)
{
- // shortcut disabled filters to show everything immediately
- mMinRequiredGeneration = 0;
- mMustPassGeneration = S32_MAX;
+ LLFolderView* fv = reinterpret_cast<LLFolderView*>(user_data);
+ fv->paste();
}
}
-BOOL LLInventoryFilter::isFilterWith(LLInventoryType::EType t)
-{
- return mFilterOps.mFilterTypes & (0x01 << t);
-}
-
-std::string LLInventoryFilter::getFilterText()
+void open_selected_items(void* user_data)
{
- if (!mNeedTextRebuild)
- {
- return mFilterText;
- }
-
- mNeedTextRebuild = FALSE;
- std::string filtered_types;
- std::string not_filtered_types;
- BOOL filtered_by_type = FALSE;
- BOOL filtered_by_all_types = TRUE;
- S32 num_filter_types = 0;
- mFilterText.clear();
-
- if (isFilterWith(LLInventoryType::IT_ANIMATION))
- {
- filtered_types += " Animations,";
- filtered_by_type = TRUE;
- num_filter_types++;
- }
- else
- {
- not_filtered_types += " Animations,";
- filtered_by_all_types = FALSE;
- }
-
- if (isFilterWith(LLInventoryType::IT_CALLINGCARD))
- {
- filtered_types += " Calling Cards,";
- filtered_by_type = TRUE;
- num_filter_types++;
- }
- else
- {
- not_filtered_types += " Calling Cards,";
- filtered_by_all_types = FALSE;
- }
-
- if (isFilterWith(LLInventoryType::IT_WEARABLE))
- {
- filtered_types += " Clothing,";
- filtered_by_type = TRUE;
- num_filter_types++;
- }
- else
- {
- not_filtered_types += " Clothing,";
- filtered_by_all_types = FALSE;
- }
-
- if (isFilterWith(LLInventoryType::IT_GESTURE))
- {
- filtered_types += " Gestures,";
- filtered_by_type = TRUE;
- num_filter_types++;
- }
- else
- {
- not_filtered_types += " Gestures,";
- filtered_by_all_types = FALSE;
- }
-
- if (isFilterWith(LLInventoryType::IT_LANDMARK))
- {
- filtered_types += " Landmarks,";
- filtered_by_type = TRUE;
- num_filter_types++;
- }
- else
- {
- not_filtered_types += " Landmarks,";
- filtered_by_all_types = FALSE;
- }
-
- if (isFilterWith(LLInventoryType::IT_NOTECARD))
- {
- filtered_types += " Notecards,";
- filtered_by_type = TRUE;
- num_filter_types++;
- }
- else
- {
- not_filtered_types += " Notecards,";
- filtered_by_all_types = FALSE;
- }
-
- if (isFilterWith(LLInventoryType::IT_OBJECT) && isFilterWith(LLInventoryType::IT_ATTACHMENT))
- {
- filtered_types += " Objects,";
- filtered_by_type = TRUE;
- num_filter_types++;
- }
- else
- {
- not_filtered_types += " Objects,";
- filtered_by_all_types = FALSE;
- }
-
- if (isFilterWith(LLInventoryType::IT_LSL))
- {
- filtered_types += " Scripts,";
- filtered_by_type = TRUE;
- num_filter_types++;
- }
- else
- {
- not_filtered_types += " Scripts,";
- filtered_by_all_types = FALSE;
- }
-
- if (isFilterWith(LLInventoryType::IT_SOUND))
- {
- filtered_types += " Sounds,";
- filtered_by_type = TRUE;
- num_filter_types++;
- }
- else
- {
- not_filtered_types += " Sounds,";
- filtered_by_all_types = FALSE;
- }
-
- if (isFilterWith(LLInventoryType::IT_TEXTURE))
- {
- filtered_types += " Textures,";
- filtered_by_type = TRUE;
- num_filter_types++;
- }
- else
- {
- not_filtered_types += " Textures,";
- filtered_by_all_types = FALSE;
- }
-
- if (isFilterWith(LLInventoryType::IT_SNAPSHOT))
- {
- filtered_types += " Snapshots,";
- filtered_by_type = TRUE;
- num_filter_types++;
- }
- else
- {
- not_filtered_types += " Snapshots,";
- filtered_by_all_types = FALSE;
- }
-
- if (!gInventory.backgroundFetchActive() && filtered_by_type && !filtered_by_all_types)
- {
- mFilterText += " - ";
- if (num_filter_types < 5)
- {
- mFilterText += filtered_types;
- }
- else
- {
- mFilterText += "No ";
- mFilterText += not_filtered_types;
- }
- // remove the ',' at the end
- mFilterText.erase(mFilterText.size() - 1, 1);
- }
-
- if (isSinceLogoff())
+ if(user_data)
{
- mFilterText += " - Since Logoff";
+ LLFolderView* fv = reinterpret_cast<LLFolderView*>(user_data);
+ fv->openSelectedItems();
}
- return mFilterText;
-}
-
-void LLInventoryFilter::toLLSD(LLSD& data)
-{
- data["filter_types"] = (LLSD::Integer)getFilterTypes();
- data["min_date"] = (LLSD::Integer)getMinDate();
- data["max_date"] = (LLSD::Integer)getMaxDate();
- data["hours_ago"] = (LLSD::Integer)getHoursAgo();
- data["show_folder_state"] = (LLSD::Integer)getShowFolderState();
- data["permissions"] = (LLSD::Integer)getFilterPermissions();
- data["substring"] = (LLSD::String)getFilterSubString();
- data["sort_order"] = (LLSD::Integer)getSortOrder();
- data["since_logoff"] = (LLSD::Boolean)isSinceLogoff();
}
-void LLInventoryFilter::fromLLSD(LLSD& data)
+void properties_selected_items(void* user_data)
{
- if(data.has("filter_types"))
- {
- setFilterTypes((U32)data["filter_types"].asInteger());
- }
-
- if(data.has("min_date") && data.has("max_date"))
- {
- setDateRange(data["min_date"].asInteger(), data["max_date"].asInteger());
- }
-
- if(data.has("hours_ago"))
- {
- setHoursAgo((U32)data["hours_ago"].asInteger());
- }
-
- if(data.has("show_folder_state"))
- {
- setShowFolderState((EFolderShow)data["show_folder_state"].asInteger());
- }
-
- if(data.has("permissions"))
- {
- setFilterPermissions((PermissionMask)data["permissions"].asInteger());
- }
-
- if(data.has("substring"))
- {
- setFilterSubString(std::string(data["substring"].asString()));
- }
-
- if(data.has("sort_order"))
- {
- setSortOrder((U32)data["sort_order"].asInteger());
- }
-
- if(data.has("since_logoff"))
+ if(user_data)
{
- setDateRangeLastLogoff((bool)data["since_logoff"].asBoolean());
+ LLFolderView* fv = reinterpret_cast<LLFolderView*>(user_data);
+ fv->propertiesSelectedItems();
}
}
diff --git a/indra/newview/llfolderview.h b/indra/newview/llfolderview.h
index 3fe3095c58..a05dec3193 100644
--- a/indra/newview/llfolderview.h
+++ b/indra/newview/llfolderview.h
@@ -41,9 +41,12 @@
#ifndef LL_LLFOLDERVIEW_H
#define LL_LLFOLDERVIEW_H
+// JAMESDEBUG - trim this list
#include <vector>
#include <map>
#include <deque>
+#include <boost/function.hpp>
+#include <boost/signals2.hpp>
#include "lluictrl.h"
#include "v4color.h"
@@ -52,97 +55,11 @@
#include "stdenums.h"
#include "llfontgl.h"
#include "lleditmenuhandler.h"
-#include "llviewerimage.h"
+#include "llviewertexture.h"
#include "lldepthstack.h"
#include "lltooldraganddrop.h"
-
-class LLMenuGL;
-
-//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-// Class LLFolderViewEventListener
-//
-// This is an abstract base class that users of the folderview classes
-// would use to catch the useful events emitted from the folder
-// views.
-//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-
-class LLFolderViewItem;
-class LLFolderView;
-class LLInventoryModel;
-class LLScrollableContainerView;
-
-class LLFolderViewEventListener
-{
-public:
- virtual ~LLFolderViewEventListener( void ) {}
- virtual const std::string& getName() const = 0;
- virtual const std::string& getDisplayName() const = 0;
- virtual const LLUUID& getUUID() const = 0;
- virtual time_t getCreationDate() const = 0; // UTC seconds
- virtual PermissionMask getPermissionMask() const = 0;
- virtual LLUIImagePtr getIcon() const = 0;
- virtual LLFontGL::StyleFlags getLabelStyle() const = 0;
- virtual std::string getLabelSuffix() const = 0;
- virtual void openItem( void ) = 0;
- virtual void previewItem( void ) = 0;
- virtual void selectItem(void) = 0;
- virtual void showProperties(void) = 0;
- virtual BOOL isItemRenameable() const = 0;
- virtual BOOL renameItem(const std::string& new_name) = 0;
- virtual BOOL isItemMovable( void ) = 0; // Can be moved to another folder
- virtual BOOL isItemRemovable( void ) = 0; // Can be destroyed
- virtual BOOL removeItem() = 0;
- virtual void removeBatch(LLDynamicArray<LLFolderViewEventListener*>& batch) = 0;
- virtual void move( LLFolderViewEventListener* parent_listener ) = 0;
- virtual BOOL isItemCopyable() const = 0;
- virtual BOOL copyToClipboard() const = 0;
- virtual void cutToClipboard() = 0;
- virtual BOOL isClipboardPasteable() const = 0;
- virtual void pasteFromClipboard() = 0;
- virtual void buildContextMenu(LLMenuGL& menu, U32 flags) = 0;
- virtual BOOL isUpToDate() const = 0;
- virtual BOOL hasChildren() const = 0;
- virtual LLInventoryType::EType getInventoryType() const = 0;
- virtual void performAction(LLFolderView* folder, LLInventoryModel* model, std::string action) {}
-
- // This method should be called when a drag begins. returns TRUE
- // if the drag can begin, otherwise FALSE.
- virtual BOOL startDrag(EDragAndDropType* type, LLUUID* id) const = 0;
-
- // This method will be called to determine if a drop can be
- // performed, and will set drop to TRUE if a drop is
- // requested. Returns TRUE if a drop is possible/happened,
- // otherwise FALSE.
- virtual BOOL dragOrDrop(MASK mask, BOOL drop,
- EDragAndDropType cargo_type,
- void* cargo_data) = 0;
-
- // This method is called when the object being referenced by the
- // bridge is actually dropped. This allows for cleanup of the old
- // view, reference counting, etc.
-// virtual void dropped() = 0;
-
- // this method accesses the parent and arranges and sets it as
- // specified.
- void arrangeAndSet(LLFolderViewItem* focus, BOOL set_selection,
- BOOL take_keyboard_focus = TRUE);
-};
-
-
-//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-// Class LLFolderViewListenerFunctor
-//
-// This simple abstract base class can be used to applied to all
-// listeners in a hierarchy.
-//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-class LLFolderViewListenerFunctor
-{
-public:
- virtual ~LLFolderViewListenerFunctor() {}
- virtual void operator()(LLFolderViewEventListener* listener) = 0;
-};
+// JAMESDEBUG - move this up
+#include "llfolderviewitem.h" // because LLFolderView is-a LLFolderViewFolder
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Class LLFolderViewFunctor
@@ -164,552 +81,6 @@ public:
virtual void doItem(LLFolderViewItem* item) = 0;
};
-class LLInventoryFilter
-{
-public:
- typedef enum e_folder_show
- {
- SHOW_ALL_FOLDERS,
- SHOW_NON_EMPTY_FOLDERS,
- SHOW_NO_FOLDERS
- } EFolderShow;
-
- typedef enum e_filter_behavior
- {
- FILTER_NONE, // nothing to do, already filtered
- FILTER_RESTART, // restart filtering from scratch
- FILTER_LESS_RESTRICTIVE, // existing filtered items will certainly pass this filter
- FILTER_MORE_RESTRICTIVE // if you didn't pass the previous filter, you definitely won't pass this one
- } EFilterBehavior;
-
- static const U32 SO_DATE = 1;
- static const U32 SO_FOLDERS_BY_NAME = 2;
- static const U32 SO_SYSTEM_FOLDERS_TO_TOP = 4;
-
- LLInventoryFilter(const std::string& name);
- virtual ~LLInventoryFilter();
-
- void setFilterTypes(U32 types);
- U32 getFilterTypes() const { return mFilterOps.mFilterTypes; }
-
- void setFilterSubString(const std::string& string);
- const std::string getFilterSubString(BOOL trim = FALSE);
-
- void setFilterPermissions(PermissionMask perms);
- PermissionMask getFilterPermissions() const { return mFilterOps.mPermissions; }
-
- void setDateRange(time_t min_date, time_t max_date);
- void setDateRangeLastLogoff(BOOL sl);
- time_t getMinDate() const { return mFilterOps.mMinDate; }
- time_t getMaxDate() const { return mFilterOps.mMaxDate; }
-
- void setHoursAgo(U32 hours);
- U32 getHoursAgo() const { return mFilterOps.mHoursAgo; }
-
- void setShowFolderState( EFolderShow state);
- EFolderShow getShowFolderState() { return mFilterOps.mShowFolderState; }
-
- void setSortOrder(U32 order);
- U32 getSortOrder() { return mOrder; }
-
- BOOL check(LLFolderViewItem* item);
- std::string::size_type getStringMatchOffset() const;
- BOOL isActive();
- BOOL isNotDefault();
- BOOL isModified();
- BOOL isModifiedAndClear();
- BOOL isSinceLogoff();
- void clearModified() { mModified = FALSE; mFilterBehavior = FILTER_NONE; }
- const std::string getName() const { return mName; }
- std::string getFilterText();
-
- void setFilterCount(S32 count) { mFilterCount = count; }
- S32 getFilterCount() { return mFilterCount; }
- void decrementFilterCount() { mFilterCount--; }
-
- void markDefault();
- void resetDefault();
-
- BOOL isFilterWith(LLInventoryType::EType t);
-
- S32 getCurrentGeneration() const { return mFilterGeneration; }
- S32 getMinRequiredGeneration() const { return mMinRequiredGeneration; }
- S32 getMustPassGeneration() const { return mMustPassGeneration; }
-
- //RN: this is public to allow system to externally force a global refilter
- void setModified(EFilterBehavior behavior = FILTER_RESTART);
-
- void toLLSD(LLSD& data);
- void fromLLSD(LLSD& data);
-
-protected:
- struct filter_ops
- {
- U32 mFilterTypes;
- time_t mMinDate;
- time_t mMaxDate;
- U32 mHoursAgo;
- EFolderShow mShowFolderState;
- PermissionMask mPermissions;
- };
- filter_ops mFilterOps;
- filter_ops mDefaultFilterOps;
- std::string::size_type mSubStringMatchOffset;
- std::string mFilterSubString;
- U32 mOrder;
- const std::string mName;
- S32 mFilterGeneration;
- S32 mMustPassGeneration;
- S32 mMinRequiredGeneration;
- S32 mFilterCount;
- S32 mNextFilterGeneration;
- EFilterBehavior mFilterBehavior;
-
-private:
- U32 mLastLogoff;
- BOOL mModified;
- BOOL mNeedTextRebuild;
- std::string mFilterText;
-};
-
-// These are grouping of inventory types.
-// Order matters when sorting system folders to the top.
-enum EInventorySortGroup
-{
- SG_SYSTEM_FOLDER,
- SG_TRASH_FOLDER,
- SG_NORMAL_FOLDER,
- SG_ITEM
-};
-
-class LLInventorySort
-{
-public:
- LLInventorySort()
- : mSortOrder(0),
- mByDate(false),
- mSystemToTop(false),
- mFoldersByName(false) { }
-
- // Returns true if order has changed
- bool updateSort(U32 order);
- U32 getSort() { return mSortOrder; }
-
- bool operator()(const LLFolderViewItem* const& a, const LLFolderViewItem* const& b);
-private:
- U32 mSortOrder;
- bool mByDate;
- bool mSystemToTop;
- bool mFoldersByName;
-};
-
-//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-// Class LLFolderViewItem
-//
-// An instance of this class represents a single item in a folder view
-// such as an inventory item or a file.
-//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-class LLFontGL;
-class LLFolderViewFolder;
-class LLFolderView;
-
-class LLFolderViewItem : public LLUICtrl
-{
-protected:
- friend class LLFolderViewEventListener;
-
- static const LLFontGL* sFont;
- static const LLFontGL* sSmallFont;
- static LLColor4 sFgColor;
- static LLColor4 sHighlightBgColor;
- static LLColor4 sHighlightFgColor;
- static LLColor4 sFilterBGColor;
- static LLColor4 sFilterTextColor;
- static LLColor4 sSuffixColor;
- static LLColor4 sSearchStatusColor;
- static LLUIImagePtr sArrowImage;
- static LLUIImagePtr sBoxImage;
-
- std::string mLabel;
- std::string mSearchableLabel;
- std::string mType;
- S32 mLabelWidth;
- time_t mCreationDate;
- LLFolderViewFolder* mParentFolder;
- LLFolderViewEventListener* mListener;
- BOOL mIsSelected;
- BOOL mIsCurSelection;
- BOOL mSelectPending;
- LLFontGL::StyleFlags mLabelStyle;
- std::string mLabelSuffix;
- LLUIImagePtr mIcon;
- std::string mStatusText;
- BOOL mHasVisibleChildren;
- S32 mIndentation;
- S32 mNumDescendantsSelected;
- BOOL mFiltered;
- S32 mLastFilterGeneration;
- std::string::size_type mStringMatchOffset;
- F32 mControlLabelRotation;
- LLFolderView* mRoot;
- BOOL mDragAndDropTarget;
- BOOL mIsLoading;
- LLTimer mTimeSinceRequestStart;
-
- // This function clears the currently selected item, and records
- // the specified selected item appropriately for display and use
- // in the UI. If open is TRUE, then folders are opened up along
- // the way to the selection.
- void setSelectionFromRoot(LLFolderViewItem* selection, BOOL openitem,
- BOOL take_keyboard_focus = TRUE);
-
- // helper function to change the selection from the root.
- void changeSelectionFromRoot(LLFolderViewItem* selection, BOOL selected);
-
- // helper function to change the selection from the root.
- void extendSelectionFromRoot(LLFolderViewItem* selection);
-
- // this is an internal method used for adding items to folders. A
- // no-op at this leve, but reimplemented in derived classes.
- virtual BOOL addItem(LLFolderViewItem*) { return FALSE; }
- virtual BOOL addFolder(LLFolderViewFolder*) { return FALSE; }
-
-public:
- static void initClass();
- static void cleanupClass();
-
- // This function is called when the folder view is dirty. It's
- // implemented here but called by derived classes when folding the
- // views.
- void arrangeFromRoot();
- void filterFromRoot( void );
-
- // creation_date is in UTC seconds
- LLFolderViewItem( const std::string& name, LLUIImagePtr icon, time_t creation_date, LLFolderView* root, LLFolderViewEventListener* listener );
- virtual ~LLFolderViewItem( void );
-
- // addToFolder() returns TRUE if it succeeds. FALSE otherwise
- enum { ARRANGE = TRUE, DO_NOT_ARRANGE = FALSE };
- virtual BOOL addToFolder(LLFolderViewFolder* folder, LLFolderView* root);
-
- virtual EInventorySortGroup getSortGroup() const;
-
- // Finds width and height of this object and it's children. Also
- // makes sure that this view and it's children are the right size.
- virtual S32 arrange( S32* width, S32* height, S32 filter_generation );
- virtual S32 getItemHeight();
-
- // applies filters to control visibility of inventory items
- virtual void filter( LLInventoryFilter& filter);
-
- // updates filter serial number and optionally propagated value up to root
- S32 getLastFilterGeneration() { return mLastFilterGeneration; }
-
- virtual void dirtyFilter();
-
- // If the selection is 'this' then note that otherwise
- // ignore. Returns TRUE if this object was affected. If open is
- // TRUE, then folders are opened up along the way to the
- // selection.
- virtual BOOL setSelection(LLFolderViewItem* selection, BOOL openitem,
- BOOL take_keyboard_focus);
-
- // This method is used to toggle the selection of an item. If
- // selection is 'this', then note selection, and return TRUE.
- virtual BOOL changeSelection(LLFolderViewItem* selection, BOOL selected);
-
- // this method is used to group select items
- virtual S32 extendSelection(LLFolderViewItem* selection, LLFolderViewItem* last_selected, LLDynamicArray<LLFolderViewItem*>& items){ return FALSE; }
-
- // this method is used to group select items
- virtual void recursiveDeselect(BOOL deselect_self);
-
- // gets multiple-element selection
- virtual BOOL getSelectionList(std::set<LLUUID> &selection){return TRUE;}
-
- // Returns true is this object and all of its children can be removed (deleted by user)
- virtual BOOL isRemovable();
-
- // Returns true is this object and all of its children can be moved
- virtual BOOL isMovable();
-
- // destroys this item recursively
- virtual void destroyView();
-
- S32 getNumSelectedDescendants() { return mNumDescendantsSelected; }
-
- BOOL isSelected() { return mIsSelected; }
-
- void setIsCurSelection(BOOL select) { mIsCurSelection = select; }
-
- BOOL getIsCurSelection() { return mIsCurSelection; }
-
- BOOL hasVisibleChildren() { return mHasVisibleChildren; }
-
- // Call through to the viewed object and return true if it can be
- // removed. Returns true if it's removed.
- //virtual BOOL removeRecursively(BOOL single_item);
- BOOL remove();
-
- // Build an appropriate context menu for the item. Flags unused.
- void buildContextMenu(LLMenuGL& menu, U32 flags);
-
- // This method returns the actual name of the thing being
- // viewed. This method will ask the viewed object itself.
- const std::string& getName( void ) const;
-
- const std::string& getSearchableLabel( void ) const;
-
- // This method returns the label displayed on the view. This
- // method was primarily added to allow sorting on the folder
- // contents possible before the entire view has been constructed.
- const std::string& getLabel() const { return mLabel; }
-
- // Used for sorting, like getLabel() above.
- virtual time_t getCreationDate() const { return mCreationDate; }
-
- LLFolderViewFolder* getParentFolder( void ) { return mParentFolder; }
- const LLFolderViewFolder* getParentFolder( void ) const { return mParentFolder; }
-
- LLFolderViewItem* getNextOpenNode( BOOL include_children = TRUE );
- LLFolderViewItem* getPreviousOpenNode( BOOL include_children = TRUE );
-
- const LLFolderViewEventListener* getListener( void ) const { return mListener; }
- LLFolderViewEventListener* getListener( void ) { return mListener; }
-
- // just rename the object.
- void rename(const std::string& new_name);
-
- // open
- virtual void openItem( void );
- virtual void preview(void);
-
- // Show children (unfortunate that this is called "open")
- virtual void setOpen(BOOL open = TRUE) {};
-
- virtual BOOL isOpen() { return FALSE; }
-
- LLFolderView* getRoot();
- BOOL isDescendantOf( const LLFolderViewFolder* potential_ancestor );
- S32 getIndentation() { return mIndentation; }
-
- virtual BOOL potentiallyVisible(); // do we know for a fact that this item has been filtered out?
-
- virtual BOOL getFiltered();
- virtual BOOL getFiltered(S32 filter_generation);
- virtual void setFiltered(BOOL filtered, S32 filter_generation);
-
- // change the icon
- void setIcon(LLUIImagePtr icon);
-
- // refresh information from the object being viewed.
- void refreshFromListener();
- virtual void refresh();
-
- virtual void applyListenerFunctorRecursively(LLFolderViewListenerFunctor& functor);
-
- // LLView functionality
- virtual BOOL handleRightMouseDown( S32 x, S32 y, MASK mask );
- virtual BOOL handleMouseDown( S32 x, S32 y, MASK mask );
- virtual BOOL handleHover( S32 x, S32 y, MASK mask );
- virtual BOOL handleMouseUp( S32 x, S32 y, MASK mask );
- virtual BOOL handleDoubleClick( S32 x, S32 y, MASK mask );
- virtual BOOL handleScrollWheel(S32 x, S32 y, S32 clicks);
-
- // virtual void handleDropped();
- virtual void draw();
- virtual BOOL handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop,
- EDragAndDropType cargo_type,
- void* cargo_data,
- EAcceptance* accept,
- std::string& tooltip_msg);
-};
-
-
-// function used for sorting.
-typedef bool (*sort_order_f)(LLFolderViewItem* a, LLFolderViewItem* b);
-
-
-//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-// Class LLFolderViewFolder
-//
-// An instance of an LLFolderViewFolder represents a collection of
-// more folders and items. This is used to build the hierarchy of
-// items found in the folder view. :)
-//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-class LLFolderViewFolder : public LLFolderViewItem
-{
-public:
- typedef enum e_trash
- {
- UNKNOWN, TRASH, NOT_TRASH
- } ETrash;
-
-protected:
- typedef std::list<LLFolderViewItem*> items_t;
- typedef std::list<LLFolderViewFolder*> folders_t;
- items_t mItems;
- folders_t mFolders;
- LLInventorySort mSortFunction;
-
- BOOL mIsOpen;
- BOOL mExpanderHighlighted;
- F32 mCurHeight;
- F32 mTargetHeight;
- F32 mAutoOpenCountdown;
- time_t mSubtreeCreationDate;
- mutable ETrash mAmTrash;
- S32 mLastArrangeGeneration;
- S32 mLastCalculatedWidth;
- S32 mCompletedFilterGeneration;
- S32 mMostFilteredDescendantGeneration;
-public:
- typedef enum e_recurse_type
- {
- RECURSE_NO,
- RECURSE_UP,
- RECURSE_DOWN,
- RECURSE_UP_DOWN
- } ERecurseType;
-
- LLFolderViewFolder( const std::string& name, LLUIImagePtr icon,
- LLFolderView* root,
- LLFolderViewEventListener* listener );
- virtual ~LLFolderViewFolder( void );
-
- virtual BOOL potentiallyVisible();
-
- LLFolderViewItem* getNextFromChild( LLFolderViewItem*, BOOL include_children = TRUE );
- LLFolderViewItem* getPreviousFromChild( LLFolderViewItem*, BOOL include_children = TRUE );
-
- // addToFolder() returns TRUE if it succeeds. FALSE otherwise
- virtual BOOL addToFolder(LLFolderViewFolder* folder, LLFolderView* root);
-
- // Finds width and height of this object and it's children. Also
- // makes sure that this view and it's children are the right size.
- virtual S32 arrange( S32* width, S32* height, S32 filter_generation );
-
- BOOL needsArrange();
-
- // Returns the sort group (system, trash, folder) for this folder.
- virtual EInventorySortGroup getSortGroup() const;
-
- virtual void setCompletedFilterGeneration(S32 generation, BOOL recurse_up);
- virtual S32 getCompletedFilterGeneration() { return mCompletedFilterGeneration; }
-
- BOOL hasFilteredDescendants(S32 filter_generation) { return mMostFilteredDescendantGeneration >= filter_generation; }
- BOOL hasFilteredDescendants();
-
- // applies filters to control visibility of inventory items
- virtual void filter( LLInventoryFilter& filter);
- virtual void setFiltered(BOOL filtered, S32 filter_generation);
- virtual void dirtyFilter();
-
- // Passes selection information on to children and record
- // selection information if necessary. Returns TRUE if this object
- // (or a child) was affected.
- virtual BOOL setSelection(LLFolderViewItem* selection, BOOL openitem,
- BOOL take_keyboard_focus);
-
- // This method is used to change the selection of an item. If
- // selection is 'this', then note selection as true. Returns TRUE
- // if this or a child is now selected.
- virtual BOOL changeSelection(LLFolderViewItem* selection, BOOL selected);
-
- // this method is used to group select items
- virtual S32 extendSelection(LLFolderViewItem* selection, LLFolderViewItem* last_selected, LLDynamicArray<LLFolderViewItem*>& items);
-
- virtual void recursiveDeselect(BOOL deselect_self);
-
- // Returns true is this object and all of its children can be removed.
- virtual BOOL isRemovable();
-
- // Returns true is this object and all of its children can be moved
- virtual BOOL isMovable();
-
- // destroys this folder, and all children
- virtual void destroyView();
-
- // If this folder can be removed, remove all children that can be
- // removed, return TRUE if this is empty after the operation and
- // it's viewed folder object can be removed.
- //virtual BOOL removeRecursively(BOOL single_item);
- //virtual BOOL remove();
-
- // remove the specified item (and any children) if
- // possible. Return TRUE if the item was deleted.
- BOOL removeItem(LLFolderViewItem* item);
-
- // simply remove the view (and any children) Don't bother telling
- // the listeners.
- void removeView(LLFolderViewItem* item);
-
- // extractItem() removes the specified item from the folder, but
- // doesn't delete it.
- void extractItem( LLFolderViewItem* item );
-
- // This function is called by a child that needs to be resorted.
- void resort(LLFolderViewItem* item);
-
- void setItemSortOrder(U32 ordering);
- void sortBy(U32);
- //BOOL (*func)(LLFolderViewItem* a, LLFolderViewItem* b));
-
- void setAutoOpenCountdown(F32 countdown) { mAutoOpenCountdown = countdown; }
-
- // folders can be opened. This will usually be called by internal
- // methods.
- virtual void toggleOpen();
-
- // Force a folder open or closed
- virtual void setOpen(BOOL openitem = TRUE);
-
- // Called when a child is refreshed.
- // don't rearrange child folder contents unless explicitly requested
- virtual void requestArrange(BOOL include_descendants = FALSE);
-
- // internal method which doesn't update the entire view. This
- // method was written because the list iterators destroy the state
- // of other iterations, thus, we can't arrange while iterating
- // through the children (such as when setting which is selected.
- virtual void setOpenArrangeRecursively(BOOL openitem, ERecurseType recurse = RECURSE_NO);
-
- // Get the current state of the folder.
- virtual BOOL isOpen() { return mIsOpen; }
-
- // special case if an object is dropped on the child.
- BOOL handleDragAndDropFromChild(MASK mask,
- BOOL drop,
- EDragAndDropType cargo_type,
- void* cargo_data,
- EAcceptance* accept,
- std::string& tooltip_msg);
-
- void applyFunctorRecursively(LLFolderViewFunctor& functor);
- virtual void applyListenerFunctorRecursively(LLFolderViewListenerFunctor& functor);
-
- virtual void openItem( void );
- virtual BOOL addItem(LLFolderViewItem* item);
- virtual BOOL addFolder( LLFolderViewFolder* folder);
-
- // LLView functionality
- virtual BOOL handleHover(S32 x, S32 y, MASK mask);
- virtual BOOL handleRightMouseDown( S32 x, S32 y, MASK mask );
- virtual BOOL handleMouseDown( S32 x, S32 y, MASK mask );
- virtual BOOL handleDoubleClick( S32 x, S32 y, MASK mask );
- virtual BOOL handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop,
- EDragAndDropType cargo_type,
- void* cargo_data,
- EAcceptance* accept,
- std::string& tooltip_msg);
- virtual void draw();
-
- time_t getCreationDate() const;
- bool isTrash() const;
-};
-
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Class LLFolderView
@@ -718,38 +89,51 @@ public:
// manages the screen region of the folder view.
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-class LLUICtrl;
+class LLFolderViewEventListener;
+class LLInventoryModel;
class LLLineEditor;
+class LLMenuGL;
+class LLScrollContainer;
+class LLUICtrl;
-class LLFolderView : public LLFolderViewFolder, LLEditMenuHandler
+class LLFolderView : public LLFolderViewFolder, public LLEditMenuHandler
{
public:
- typedef void (*SelectCallback)(const std::deque<LLFolderViewItem*> &items, BOOL user_action, void* data);
-
- static F32 sAutoOpenTime;
-
+ struct Params : public LLInitParam::Block<Params, LLFolderViewFolder::Params>
+ {
+ Mandatory<LLPanel*> parent_panel;
+ Optional<LLUUID> task_id;
+ };
LLFolderView( const std::string& name, LLUIImagePtr root_folder_icon, const LLRect& rect,
- const LLUUID& source_id, LLView *parent_view );
+ const LLUUID& source_id, LLPanel *parent_view );
+ LLFolderView(const Params&);
virtual ~LLFolderView( void );
virtual BOOL canFocusChildren() const;
+ virtual LLFolderView* getRoot() { return this; }
+
// FolderViews default to sort by name. This will change that,
// and resort the items if necessary.
void setSortOrder(U32 order);
void checkTreeResortForModelChanged();
- void setFilterPermMask(PermissionMask filter_perm_mask) { mFilter.setFilterPermissions(filter_perm_mask); }
- void setSelectCallback(SelectCallback callback, void* user_data) { mSelectCallback = callback, mUserData = user_data; }
+ void setFilterPermMask(PermissionMask filter_perm_mask);
void setAllowMultiSelect(BOOL allow) { mAllowMultiSelect = allow; }
-
- LLInventoryFilter* getFilter() { return &mFilter; }
+
+ typedef boost::signals2::signal<void (const std::deque<LLFolderViewItem*>& items, BOOL user_action)> signal_t;
+ void setSelectCallback(const signal_t::slot_type& cb) { mSelectSignal.connect(cb); }
+ void setReshapeCallback(const signal_t::slot_type& cb) { mReshapeSignal.connect(cb); }
+
+ // filter is never null
+ LLInventoryFilter* getFilter();
const std::string getFilterSubString(BOOL trim = FALSE);
- U32 getFilterTypes() const { return mFilter.getFilterTypes(); }
- PermissionMask getFilterPermissions() const { return mFilter.getFilterPermissions(); }
- LLInventoryFilter::EFolderShow getShowFolderState() { return mFilter.getShowFolderState(); }
+ U32 getFilterTypes() const;
+ PermissionMask getFilterPermissions() const;
+ // JAMESDEBUG use getFilter()->getShowFolderState();
+ //LLInventoryFilter::EFolderShow getShowFolderState();
U32 getSortOrder() const;
- BOOL isFilterModified() { return mFilter.isNotDefault(); }
- BOOL getAllowMultiSelect() { return mAllowMultiSelect; }
+ BOOL isFilterModified();
+ BOOL getAllowMultiSelect();
// Close all folders in the view
void closeAllFolders();
@@ -775,7 +159,13 @@ public:
// Record the selected item and pass it down the hierachy.
virtual BOOL setSelection(LLFolderViewItem* selection, BOOL openitem,
BOOL take_keyboard_focus);
-
+
+ // Used by menu callbacks
+ void setSelectionByID(const LLUUID& obj_id, BOOL take_keyboard_focus);
+
+ // Called once a frame to update the selection if mSelectThisID has been set
+ void updateSelection();
+
// This method is used to toggle the selection of an item. Walks
// children, and keeps track of selected objects.
virtual BOOL changeSelection(LLFolderViewItem* selection, BOOL selected);
@@ -800,6 +190,9 @@ public:
void openSelectedItems( void );
void propertiesSelectedItems( void );
+ // change the folder type
+ void changeType(LLInventoryModel *model, LLAssetType::EType new_folder_type);
+
void autoOpenItem(LLFolderViewFolder* item);
void closeAutoOpenedFolders();
BOOL autoOpenTest(LLFolderViewFolder* item);
@@ -828,9 +221,6 @@ public:
//void dragItemIntoFolder( LLFolderViewItem* moving_item, LLFolderViewFolder* dst_folder, BOOL drop, BOOL* accept );
//void dragFolderIntoFolder( LLFolderViewFolder* moving_folder, LLFolderViewFolder* dst_folder, BOOL drop, BOOL* accept );
- // LLUICtrl Functionality
- /*virtual*/ void setFocus(BOOL focus);
-
// LLView functionality
///*virtual*/ BOOL handleKey( KEY key, MASK mask, BOOL called_from_parent );
/*virtual*/ BOOL handleKeyHere( KEY key, MASK mask );
@@ -845,14 +235,13 @@ public:
EAcceptance* accept,
std::string& tooltip_msg);
/*virtual*/ void reshape(S32 width, S32 height, BOOL called_from_parent = TRUE);
- /*virtual*/ void onFocusLost();
virtual BOOL handleScrollWheel(S32 x, S32 y, S32 clicks);
virtual void draw();
virtual void deleteAllChildren();
void scrollToShowSelection();
- void scrollToShowItem(LLFolderViewItem* item);
- void setScrollContainer( LLScrollableContainerView* parent ) { mScrollContainer = parent; }
+ void scrollToShowItem(LLFolderViewItem* item, const LLRect& constraint_rect);
+ void setScrollContainer( LLScrollContainer* parent ) { mScrollContainer = parent; }
LLRect getVisibleRect();
BOOL search(LLFolderViewItem* first_item, const std::string &search_string, BOOL backward);
@@ -865,7 +254,9 @@ public:
void addItemID(const LLUUID& id, LLFolderViewItem* itemp);
void removeItemID(const LLUUID& id);
LLFolderViewItem* getItemByID(const LLUUID& id);
-
+
+ bool doToSelected(LLInventoryModel* model, const LLSD& userdata);
+
void doIdle(); // Real idle routine
static void idle(void* user_data); // static glue to doIdle()
@@ -873,20 +264,26 @@ public:
BOOL needsAutoRename() { return mNeedsAutoRename; }
void setNeedsAutoRename(BOOL val) { mNeedsAutoRename = val; }
+ void setCallbackRegistrar(LLUICtrl::CommitCallbackRegistry::ScopedRegistrar* registrar) { mCallbackRegistrar = registrar; }
+
BOOL getDebugFilters() { return mDebugFilters; }
+ LLPanel* getParentPanel() { return mParentPanel; }
// DEBUG only
void dumpSelectionInformation();
+
+private:
+ void updateRenamerPosition();
protected:
- LLScrollableContainerView* mScrollContainer; // NULL if this is not a child of a scroll container.
+ LLScrollContainer* mScrollContainer; // NULL if this is not a child of a scroll container.
- static void commitRename( LLUICtrl* renamer, void* user_data );
- static void onRenamerLost( LLUICtrl* renamer, void* user_data);
+ void commitRename( const LLSD& data );
+ static void onRenamerLost( LLFocusableElement* renamer, void* user_data);
void finishRenamingItem( void );
void closeRenamer( void );
-
+
protected:
LLHandle<LLView> mPopupMenuHandle;
@@ -902,8 +299,8 @@ protected:
LLLineEditor* mRenamer;
BOOL mNeedsScroll;
- LLFolderViewItem* mLastScrollItem;
- LLCoordGL mLastScrollOffset;
+ BOOL mPinningSelectedItem;
+ LLRect mScrollConstraintRect;
BOOL mNeedsAutoSelect;
BOOL mAutoSelectOverride;
BOOL mNeedsAutoRename;
@@ -915,19 +312,27 @@ protected:
LLFrameTimer mAutoOpenTimer;
LLFrameTimer mSearchTimer;
std::string mSearchString;
- LLInventoryFilter mFilter;
+ LLInventoryFilter* mFilter;
BOOL mShowSelectionContext;
BOOL mShowSingleSelection;
LLFrameTimer mMultiSelectionFadeTimer;
S32 mArrangeGeneration;
- void* mUserData;
- SelectCallback mSelectCallback;
+ signal_t mSelectSignal;
+ signal_t mReshapeSignal;
S32 mSignalSelectCallback;
S32 mMinWidth;
std::map<LLUUID, LLFolderViewItem*> mItemMap;
BOOL mDragAndDropThisFrame;
+
+ LLUUID mSelectThisID; // if non null, select this item
+
+ LLPanel* mParentPanel;
+ LLUICtrl::CommitCallbackRegistry::ScopedRegistrar* mCallbackRegistrar;
+
+public:
+ static F32 sAutoOpenTime;
};
bool sort_item_name(LLFolderViewItem* a, LLFolderViewItem* b);
diff --git a/indra/newview/llfoldervieweventlistener.h b/indra/newview/llfoldervieweventlistener.h
new file mode 100644
index 0000000000..254ce4062a
--- /dev/null
+++ b/indra/newview/llfoldervieweventlistener.h
@@ -0,0 +1,101 @@
+/**
+ * @file llfoldervieweventlistener.h
+ *
+ * $LicenseInfo:firstyear=2001&license=viewergpl$
+ *
+ * Copyright (c) 2001-2009, Linden Research, Inc.
+ *
+ * Second Life Viewer Source Code
+ * The source code in this file ("Source Code") is provided by Linden Lab
+ * to you under the terms of the GNU General Public License, version 2.0
+ * ("GPL"), unless you have obtained a separate licensing agreement
+ * ("Other License"), formally executed by you and Linden Lab. Terms of
+ * the GPL can be found in doc/GPL-license.txt in this distribution, or
+ * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
+ *
+ * There are special exceptions to the terms and conditions of the GPL as
+ * it is applied to this Source Code. View the full text of the exception
+ * in the file doc/FLOSS-exception.txt in this software distribution, or
+ * online at
+ * http://secondlifegrid.net/programs/open_source/licensing/flossexception
+ *
+ * By copying, modifying or distributing this software, you acknowledge
+ * that you have read and understood your obligations described above,
+ * and agree to abide by those obligations.
+ *
+ * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+ * COMPLETENESS OR PERFORMANCE.
+ * $/LicenseInfo$
+ */
+#ifndef LLFOLDERVIEWEVENTLISTENER_H
+#define LLFOLDERVIEWEVENTLISTENER_H
+
+#include "lldarray.h" // JAMESDEBUG convert to std::vector
+#include "llfontgl.h" // just for StyleFlags enum
+#include "llpointer.h"
+
+
+class LLFolderViewItem;
+class LLFolderView;
+class LLFontGL;
+class LLInventoryModel;
+class LLMenuGL;
+class LLScrollContainer;
+class LLUIImage;
+class LLUUID;
+
+// This is an abstract base class that users of the folderview classes
+// would use to catch the useful events emitted from the folder
+// views.
+class LLFolderViewEventListener
+{
+public:
+ virtual ~LLFolderViewEventListener( void ) {}
+ virtual const std::string& getName() const = 0;
+ virtual const std::string& getDisplayName() const = 0;
+ virtual const LLUUID& getUUID() const = 0;
+ virtual time_t getCreationDate() const = 0; // UTC seconds
+ virtual PermissionMask getPermissionMask() const = 0;
+ virtual LLAssetType::EType getPreferredType() const = 0;
+ virtual LLPointer<LLUIImage> getIcon() const = 0;
+ virtual LLFontGL::StyleFlags getLabelStyle() const = 0;
+ virtual std::string getLabelSuffix() const = 0;
+ virtual void openItem( void ) = 0;
+ virtual void closeItem( void ) = 0;
+ virtual void previewItem( void ) = 0;
+ virtual void selectItem(void) = 0;
+ virtual void showProperties(void) = 0;
+ virtual BOOL isItemRenameable() const = 0;
+ virtual BOOL renameItem(const std::string& new_name) = 0;
+ virtual BOOL isItemMovable( void ) = 0; // Can be moved to another folder
+ virtual BOOL isItemRemovable( void ) = 0; // Can be destroyed
+ virtual BOOL removeItem() = 0;
+ virtual void removeBatch(LLDynamicArray<LLFolderViewEventListener*>& batch) = 0;
+ virtual void move( LLFolderViewEventListener* parent_listener ) = 0;
+ virtual BOOL isItemCopyable() const = 0;
+ virtual BOOL copyToClipboard() const = 0;
+ virtual void cutToClipboard() = 0;
+ virtual BOOL isClipboardPasteable() const = 0;
+ virtual void pasteFromClipboard() = 0;
+ virtual void pasteLinkFromClipboard() = 0;
+ virtual void buildContextMenu(LLMenuGL& menu, U32 flags) = 0;
+ virtual BOOL isUpToDate() const = 0;
+ virtual BOOL hasChildren() const = 0;
+ virtual LLInventoryType::EType getInventoryType() const = 0;
+ virtual void performAction(LLFolderView* folder, LLInventoryModel* model, std::string action) = 0;
+
+ // This method should be called when a drag begins. returns TRUE
+ // if the drag can begin, otherwise FALSE.
+ virtual BOOL startDrag(EDragAndDropType* type, LLUUID* id) const = 0;
+
+ // This method will be called to determine if a drop can be
+ // performed, and will set drop to TRUE if a drop is
+ // requested. Returns TRUE if a drop is possible/happened,
+ // otherwise FALSE.
+ virtual BOOL dragOrDrop(MASK mask, BOOL drop,
+ EDragAndDropType cargo_type,
+ void* cargo_data) = 0;
+};
+
+#endif
diff --git a/indra/newview/llfolderviewitem.cpp b/indra/newview/llfolderviewitem.cpp
new file mode 100644
index 0000000000..f1e499e14b
--- /dev/null
+++ b/indra/newview/llfolderviewitem.cpp
@@ -0,0 +1,2489 @@
+/**
+* @file llfolderviewitem.cpp
+* @brief Items and folders that can appear in a hierarchical folder view
+*
+* $LicenseInfo:firstyear=2001&license=viewergpl$
+*
+* Copyright (c) 2001-2009, Linden Research, Inc.
+*
+* Second Life Viewer Source Code
+* The source code in this file ("Source Code") is provided by Linden Lab
+* to you under the terms of the GNU General Public License, version 2.0
+* ("GPL"), unless you have obtained a separate licensing agreement
+* ("Other License"), formally executed by you and Linden Lab. Terms of
+* the GPL can be found in doc/GPL-license.txt in this distribution, or
+* online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
+*
+* There are special exceptions to the terms and conditions of the GPL as
+* it is applied to this Source Code. View the full text of the exception
+* in the file doc/FLOSS-exception.txt in this software distribution, or
+* online at
+* http://secondlifegrid.net/programs/open_source/licensing/flossexception
+*
+* By copying, modifying or distributing this software, you acknowledge
+* that you have read and understood your obligations described above,
+* and agree to abide by those obligations.
+*
+* ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+* COMPLETENESS OR PERFORMANCE.
+* $/LicenseInfo$
+*/
+#include "llviewerprecompiledheaders.h"
+
+#include "llfolderviewitem.h"
+
+// viewer includes
+#include "llfolderview.h" // Items depend extensively on LLFolderViews
+#include "llfoldervieweventlistener.h"
+#include "llinventoryfilter.h"
+#include "llinventorymodel.h" // *TODO: make it take a pointer to an inventory-model interface
+#include "llviewercontrol.h" // gSavedSettings
+#include "llviewerwindow.h" // Argh, only for setCursor()
+
+// linden library includes
+#include "llfocusmgr.h" // gFocusMgr
+#include "llpanel.h" // panel->hasFocus()
+#include "lltrans.h"
+
+///----------------------------------------------------------------------------
+/// Class LLFolderViewItem
+///----------------------------------------------------------------------------
+
+// statics
+const LLFontGL* LLFolderViewItem::sFont = NULL;
+const LLFontGL* LLFolderViewItem::sSmallFont = NULL;
+LLUIImagePtr LLFolderViewItem::sArrowImage;
+LLUIImagePtr LLFolderViewItem::sBoxImage;
+
+// only integers can be initialized in header
+const F32 LLFolderViewItem::FOLDER_CLOSE_TIME_CONSTANT = 0.02f;
+const F32 LLFolderViewItem::FOLDER_OPEN_TIME_CONSTANT = 0.03f;
+
+const LLColor4U DEFAULT_WHITE(255, 255, 255);
+
+//static
+void LLFolderViewItem::initClass()
+{
+ sFont = LLFontGL::getFontSansSerifSmall();
+ sSmallFont = LLFontGL::getFontMonospace();
+ sArrowImage = LLUI::getUIImage("folder_arrow.tga");
+ sBoxImage = LLUI::getUIImage("rounded_square.tga");
+}
+
+//static
+void LLFolderViewItem::cleanupClass()
+{
+ sArrowImage = NULL;
+ sBoxImage = NULL;
+}
+
+
+// NOTE: Optimize this, we call it a *lot* when opening a large inventory
+LLFolderViewItem::Params::Params()
+: icon("icon"),
+ folder_arrow_image("folder_arrow_image", LLUI::getUIImage("folder_arrow.tga")),
+ selection_image("selection_image", LLUI::getUIImage("rounded_square.tga"))
+{
+ mouse_opaque(true);
+ follows.flags(FOLLOWS_LEFT|FOLLOWS_TOP|FOLLOWS_RIGHT);
+ // JAMESDEBUG tab_stop(false);
+}
+
+// Default constructor
+LLFolderViewItem::LLFolderViewItem(LLFolderViewItem::Params p)
+: LLView(p),
+ mLabelWidth(0),
+ mLabelWidthDirty(false),
+ mParentFolder( NULL ),
+ mIsSelected( FALSE ),
+ mIsCurSelection( FALSE ),
+ mSelectPending(FALSE),
+ mLabelStyle( LLFontGL::NORMAL ),
+ mHasVisibleChildren(FALSE),
+ mIndentation(0),
+ mNumDescendantsSelected(0),
+ mFiltered(FALSE),
+ mLastFilterGeneration(-1),
+ mStringMatchOffset(std::string::npos),
+ mControlLabelRotation(0.f),
+ mDragAndDropTarget(FALSE),
+ mIsLoading(FALSE),
+ mLabel(p.name),
+ mRoot(p.root),
+ mCreationDate(p.creation_date),
+ mListener(p.listener),
+ mArrowImage(p.folder_arrow_image),
+ mBoxImage(p.selection_image)
+{
+ refresh();
+}
+
+// Destroys the object
+LLFolderViewItem::~LLFolderViewItem( void )
+{
+ delete mListener;
+ mListener = NULL;
+}
+
+LLFolderView* LLFolderViewItem::getRoot()
+{
+ return mRoot;
+}
+
+// Returns true if this object is a child (or grandchild, etc.) of potential_ancestor.
+BOOL LLFolderViewItem::isDescendantOf( const LLFolderViewFolder* potential_ancestor )
+{
+ LLFolderViewItem* root = this;
+ while( root->mParentFolder )
+ {
+ if( root->mParentFolder == potential_ancestor )
+ {
+ return TRUE;
+ }
+ root = root->mParentFolder;
+ }
+ return FALSE;
+}
+
+LLFolderViewItem* LLFolderViewItem::getNextOpenNode(BOOL include_children)
+{
+ if (!mParentFolder)
+ {
+ return NULL;
+ }
+
+ LLFolderViewItem* itemp = mParentFolder->getNextFromChild( this, include_children );
+ while(itemp && !itemp->getVisible())
+ {
+ LLFolderViewItem* next_itemp = itemp->mParentFolder->getNextFromChild( itemp, include_children );
+ if (itemp == next_itemp)
+ {
+ // hit last item
+ return itemp->getVisible() ? itemp : this;
+ }
+ itemp = next_itemp;
+ }
+
+ return itemp;
+}
+
+LLFolderViewItem* LLFolderViewItem::getPreviousOpenNode(BOOL include_children)
+{
+ if (!mParentFolder)
+ {
+ return NULL;
+ }
+
+ LLFolderViewItem* itemp = mParentFolder->getPreviousFromChild( this, include_children );
+ while(itemp && !itemp->getVisible())
+ {
+ LLFolderViewItem* next_itemp = itemp->mParentFolder->getPreviousFromChild( itemp, include_children );
+ if (itemp == next_itemp)
+ {
+ // hit first item
+ return itemp->getVisible() ? itemp : this;
+ }
+ itemp = next_itemp;
+ }
+
+ return itemp;
+}
+
+// is this item something we think we should be showing?
+// for example, if we haven't gotten around to filtering it yet, then the answer is yes
+// until we find out otherwise
+BOOL LLFolderViewItem::potentiallyVisible()
+{
+ // we haven't been checked against min required filter
+ // or we have and we passed
+ return getLastFilterGeneration() < getRoot()->getFilter()->getMinRequiredGeneration() || getFiltered();
+}
+
+BOOL LLFolderViewItem::getFiltered()
+{
+ return mFiltered && mLastFilterGeneration >= getRoot()->getFilter()->getMinRequiredGeneration();
+}
+
+BOOL LLFolderViewItem::getFiltered(S32 filter_generation)
+{
+ return mFiltered && mLastFilterGeneration >= filter_generation;
+}
+
+void LLFolderViewItem::setFiltered(BOOL filtered, S32 filter_generation)
+{
+ mFiltered = filtered;
+ mLastFilterGeneration = filter_generation;
+}
+
+void LLFolderViewItem::setIcon(LLUIImagePtr icon)
+{
+ mIcon = icon;
+}
+
+// refresh information from the listener
+void LLFolderViewItem::refreshFromListener()
+{
+ if(mListener)
+ {
+ mLabel = mListener->getDisplayName();
+ LLAssetType::EType preferred_type = mListener->getPreferredType();
+
+ // *TODO: to be removed when database supports multi language. This is a
+ // temporary attempt to display the inventory folder in the user locale.
+ // mantipov: *NOTE: be sure this code is synchronized with LLFriendCardsManager::findChildFolderUUID
+ // it uses the same way to find localized string
+ if (LLAssetType::lookupIsProtectedCategoryType(preferred_type))
+ {
+ LLTrans::findString(mLabel, "InvFolder " + mLabel);
+ };
+
+ setIcon(mListener->getIcon());
+ time_t creation_date = mListener->getCreationDate();
+ if (mCreationDate != creation_date)
+ {
+ mCreationDate = mListener->getCreationDate();
+ dirtyFilter();
+ }
+ mLabelStyle = mListener->getLabelStyle();
+ mLabelSuffix = mListener->getLabelSuffix();
+ }
+}
+
+void LLFolderViewItem::refresh()
+{
+ refreshFromListener();
+
+ std::string searchable_label(mLabel);
+ searchable_label.append(mLabelSuffix);
+ LLStringUtil::toUpper(searchable_label);
+
+ if (mSearchableLabel.compare(searchable_label))
+ {
+ mSearchableLabel.assign(searchable_label);
+ dirtyFilter();
+ // some part of label has changed, so overall width has potentially changed, and sort order too
+ if (mParentFolder)
+ {
+ mParentFolder->requestSort();
+ mParentFolder->requestArrange();
+ }
+ }
+
+ mLabelWidthDirty = true;
+}
+
+void LLFolderViewItem::applyListenerFunctorRecursively(LLFolderViewListenerFunctor& functor)
+{
+ functor(mListener);
+}
+
+// This function is called when items are added or view filters change. It's
+// implemented here but called by derived classes when folding the
+// views.
+void LLFolderViewItem::filterFromRoot( void )
+{
+ LLFolderViewItem* root = getRoot();
+
+ root->filter(*((LLFolderView*)root)->getFilter());
+}
+
+// This function is called when the folder view is dirty. It's
+// implemented here but called by derived classes when folding the
+// views.
+void LLFolderViewItem::arrangeFromRoot()
+{
+ LLFolderViewItem* root = getRoot();
+
+ S32 height = 0;
+ S32 width = 0;
+ root->arrange( &width, &height, 0 );
+}
+
+// Utility function for LLFolderView
+void LLFolderViewItem::arrangeAndSet(BOOL set_selection,
+ BOOL take_keyboard_focus)
+{
+ LLFolderView* root = getRoot();
+ getParentFolder()->requestArrange();
+ if(set_selection)
+ {
+ setSelectionFromRoot(this, TRUE, take_keyboard_focus);
+ if(root)
+ {
+ root->scrollToShowSelection();
+ }
+ }
+}
+
+// This function clears the currently selected item, and records the
+// specified selected item appropriately for display and use in the
+// UI. If open is TRUE, then folders are opened up along the way to
+// the selection.
+void LLFolderViewItem::setSelectionFromRoot(LLFolderViewItem* selection,
+ BOOL openitem,
+ BOOL take_keyboard_focus)
+{
+ getRoot()->setSelection(selection, openitem, take_keyboard_focus);
+}
+
+// helper function to change the selection from the root.
+void LLFolderViewItem::changeSelectionFromRoot(LLFolderViewItem* selection, BOOL selected)
+{
+ getRoot()->changeSelection(selection, selected);
+}
+
+void LLFolderViewItem::extendSelectionFromRoot(LLFolderViewItem* selection)
+{
+ LLDynamicArray<LLFolderViewItem*> selected_items;
+
+ getRoot()->extendSelection(selection, NULL, selected_items);
+}
+
+EInventorySortGroup LLFolderViewItem::getSortGroup() const
+{
+ return SG_ITEM;
+}
+
+// addToFolder() returns TRUE if it succeeds. FALSE otherwise
+BOOL LLFolderViewItem::addToFolder(LLFolderViewFolder* folder, LLFolderView* root)
+{
+ if (!folder)
+ {
+ return FALSE;
+ }
+ mParentFolder = folder;
+ root->addItemID(getListener()->getUUID(), this);
+ return folder->addItem(this);
+}
+
+
+// Finds width and height of this object and it's children. Also
+// makes sure that this view and it's children are the right size.
+S32 LLFolderViewItem::arrange( S32* width, S32* height, S32 filter_generation)
+{
+ mIndentation = mParentFolder ? mParentFolder->getIndentation() + LEFT_INDENTATION : 0;
+ if (mLabelWidthDirty)
+ {
+ mLabelWidth = ARROW_SIZE + TEXT_PAD + ICON_WIDTH + ICON_PAD + sFont->getWidth(mSearchableLabel);
+ mLabelWidthDirty = false;
+ }
+
+ *width = llmax(*width, mLabelWidth + mIndentation);
+ *height = getItemHeight();
+ return *height;
+}
+
+S32 LLFolderViewItem::getItemHeight()
+{
+ S32 icon_height = mIcon->getHeight();
+ S32 label_height = llround(sFont->getLineHeight());
+ return llmax( icon_height, label_height ) + ICON_PAD;
+}
+
+void LLFolderViewItem::filter( LLInventoryFilter& filter)
+{
+ BOOL filtered = mListener && filter.check(this);
+
+ // if our visibility will change as a result of this filter, then
+ // we need to be rearranged in our parent folder
+ if (getVisible() != filtered)
+ {
+ if (mParentFolder)
+ {
+ mParentFolder->requestArrange();
+ }
+ }
+
+ setFiltered(filtered, filter.getCurrentGeneration());
+ mStringMatchOffset = filter.getStringMatchOffset();
+ filter.decrementFilterCount();
+
+ if (getRoot()->getDebugFilters())
+ {
+ mStatusText = llformat("%d", mLastFilterGeneration);
+ }
+}
+
+void LLFolderViewItem::dirtyFilter()
+{
+ mLastFilterGeneration = -1;
+ // bubble up dirty flag all the way to root
+ if (getParentFolder())
+ {
+ getParentFolder()->setCompletedFilterGeneration(-1, TRUE);
+ }
+}
+
+// *TODO: This can be optimized a lot by simply recording that it is
+// selected in the appropriate places, and assuming that set selection
+// means 'deselect' for a leaf item. Do this optimization after
+// multiple selection is implemented to make sure it all plays nice
+// together.
+BOOL LLFolderViewItem::setSelection(LLFolderViewItem* selection, BOOL openitem, BOOL take_keyboard_focus)
+{
+ if( selection == this )
+ {
+ mIsSelected = TRUE;
+ if(mListener)
+ {
+ mListener->selectItem();
+ }
+ }
+ else
+ {
+ mIsSelected = FALSE;
+ }
+ return mIsSelected;
+}
+
+BOOL LLFolderViewItem::changeSelection(LLFolderViewItem* selection, BOOL selected)
+{
+ if(selection == this && mIsSelected != selected)
+ {
+ mIsSelected = selected;
+ if(mListener)
+ {
+ mListener->selectItem();
+ }
+ return TRUE;
+ }
+ return FALSE;
+}
+
+void LLFolderViewItem::recursiveDeselect(BOOL deselect_self)
+{
+ if (mIsSelected && deselect_self)
+ {
+ mIsSelected = FALSE;
+
+ // update ancestors' count of selected descendents
+ LLFolderViewFolder* parent_folder = getParentFolder();
+ while(parent_folder)
+ {
+ parent_folder->mNumDescendantsSelected--;
+ parent_folder = parent_folder->getParentFolder();
+ }
+ }
+}
+
+
+BOOL LLFolderViewItem::isMovable()
+{
+ if( mListener )
+ {
+ return mListener->isItemMovable();
+ }
+ else
+ {
+ return TRUE;
+ }
+}
+
+BOOL LLFolderViewItem::isRemovable()
+{
+ if( mListener )
+ {
+ return mListener->isItemRemovable();
+ }
+ else
+ {
+ return TRUE;
+ }
+}
+
+void LLFolderViewItem::destroyView()
+{
+ if (mParentFolder)
+ {
+ // removeView deletes me
+ mParentFolder->removeView(this);
+ }
+}
+
+// Call through to the viewed object and return true if it can be
+// removed.
+//BOOL LLFolderViewItem::removeRecursively(BOOL single_item)
+BOOL LLFolderViewItem::remove()
+{
+ if(!isRemovable())
+ {
+ return FALSE;
+ }
+ if(mListener)
+ {
+ return mListener->removeItem();
+ }
+ return TRUE;
+}
+
+// Build an appropriate context menu for the item.
+void LLFolderViewItem::buildContextMenu(LLMenuGL& menu, U32 flags)
+{
+ if(mListener)
+ {
+ mListener->buildContextMenu(menu, flags);
+ }
+}
+
+void LLFolderViewItem::openItem( void )
+{
+ if( mListener )
+ {
+ mListener->openItem();
+ }
+}
+
+void LLFolderViewItem::preview( void )
+{
+ if (mListener)
+ {
+ mListener->previewItem();
+ }
+}
+
+void LLFolderViewItem::rename(const std::string& new_name)
+{
+ if( !new_name.empty() )
+ {
+ if( mListener )
+ {
+ mListener->renameItem(new_name);
+
+ if(mParentFolder)
+ {
+ mParentFolder->requestSort();
+ }
+ }
+ }
+}
+
+const std::string& LLFolderViewItem::getSearchableLabel() const
+{
+ return mSearchableLabel;
+}
+
+const std::string& LLFolderViewItem::getName( void ) const
+{
+ if(mListener)
+ {
+ return mListener->getName();
+ }
+ return mLabel;
+}
+
+// LLView functionality
+BOOL LLFolderViewItem::handleRightMouseDown( S32 x, S32 y, MASK mask )
+{
+ if(!mIsSelected)
+ {
+ setSelectionFromRoot(this, FALSE);
+ }
+ make_ui_sound("UISndClick");
+ return TRUE;
+}
+
+BOOL LLFolderViewItem::handleMouseDown( S32 x, S32 y, MASK mask )
+{
+ // No handler needed for focus lost since this class has no
+ // state that depends on it.
+ gFocusMgr.setMouseCapture( this );
+
+ if (!mIsSelected)
+ {
+ if(mask & MASK_CONTROL)
+ {
+ changeSelectionFromRoot(this, !mIsSelected);
+ }
+ else if (mask & MASK_SHIFT)
+ {
+ extendSelectionFromRoot(this);
+ }
+ else
+ {
+ setSelectionFromRoot(this, FALSE);
+ }
+ make_ui_sound("UISndClick");
+ }
+ else
+ {
+ mSelectPending = TRUE;
+ }
+
+ if( isMovable() )
+ {
+ S32 screen_x;
+ S32 screen_y;
+ localPointToScreen(x, y, &screen_x, &screen_y );
+ LLToolDragAndDrop::getInstance()->setDragStart( screen_x, screen_y );
+ }
+ return TRUE;
+}
+
+BOOL LLFolderViewItem::handleHover( S32 x, S32 y, MASK mask )
+{
+ if( hasMouseCapture() && isMovable() )
+ {
+ S32 screen_x;
+ S32 screen_y;
+ localPointToScreen(x, y, &screen_x, &screen_y );
+ BOOL can_drag = TRUE;
+ if( LLToolDragAndDrop::getInstance()->isOverThreshold( screen_x, screen_y ) )
+ {
+ LLFolderView* root = getRoot();
+
+ if(root->getCurSelectedItem())
+ {
+ LLToolDragAndDrop::ESource src = LLToolDragAndDrop::SOURCE_WORLD;
+
+ // *TODO: push this into listener and remove
+ // dependency on llagent
+ if (mListener
+ && gInventory.isObjectDescendentOf(mListener->getUUID(), gInventory.getRootFolderID()))
+ {
+ src = LLToolDragAndDrop::SOURCE_AGENT;
+ }
+ else if (mListener
+ && gInventory.isObjectDescendentOf(mListener->getUUID(), gInventory.getLibraryRootFolderID()))
+ {
+ src = LLToolDragAndDrop::SOURCE_LIBRARY;
+ }
+
+ can_drag = root->startDrag(src);
+ if (can_drag)
+ {
+ // if (mListener) mListener->startDrag();
+ // RN: when starting drag and drop, clear out last auto-open
+ root->autoOpenTest(NULL);
+ root->setShowSelectionContext(TRUE);
+
+ // Release keyboard focus, so that if stuff is dropped into the
+ // world, pressing the delete key won't blow away the inventory
+ // item.
+ gFocusMgr.setKeyboardFocus(NULL);
+
+ return LLToolDragAndDrop::getInstance()->handleHover( x, y, mask );
+ }
+ }
+ }
+
+ if (can_drag)
+ {
+ gViewerWindow->setCursor(UI_CURSOR_ARROW);
+ }
+ else
+ {
+ gViewerWindow->setCursor(UI_CURSOR_NOLOCKED);
+ }
+ return TRUE;
+ }
+ else
+ {
+ getRoot()->setShowSelectionContext(FALSE);
+ gViewerWindow->setCursor(UI_CURSOR_ARROW);
+ // let parent handle this then...
+ return FALSE;
+ }
+}
+
+
+BOOL LLFolderViewItem::handleDoubleClick( S32 x, S32 y, MASK mask )
+{
+ preview();
+ return TRUE;
+}
+
+BOOL LLFolderViewItem::handleScrollWheel(S32 x, S32 y, S32 clicks)
+{
+ if (getParent())
+ {
+ return getParent()->handleScrollWheel(x, y, clicks);
+ }
+ return FALSE;
+}
+
+BOOL LLFolderViewItem::handleMouseUp( S32 x, S32 y, MASK mask )
+{
+ // if mouse hasn't moved since mouse down...
+ if ( pointInView(x, y) && mSelectPending )
+ {
+ //...then select
+ if(mask & MASK_CONTROL)
+ {
+ changeSelectionFromRoot(this, !mIsSelected);
+ }
+ else if (mask & MASK_SHIFT)
+ {
+ extendSelectionFromRoot(this);
+ }
+ else
+ {
+ setSelectionFromRoot(this, FALSE);
+ }
+ }
+
+ mSelectPending = FALSE;
+
+ if( hasMouseCapture() )
+ {
+ getRoot()->setShowSelectionContext(FALSE);
+ gFocusMgr.setMouseCapture( NULL );
+ }
+ return TRUE;
+}
+
+BOOL LLFolderViewItem::handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop,
+ EDragAndDropType cargo_type,
+ void* cargo_data,
+ EAcceptance* accept,
+ std::string& tooltip_msg)
+{
+ BOOL accepted = FALSE;
+ BOOL handled = FALSE;
+ if(mListener)
+ {
+ accepted = mListener->dragOrDrop(mask,drop,cargo_type,cargo_data);
+ handled = accepted;
+ if (accepted)
+ {
+ mDragAndDropTarget = TRUE;
+ *accept = ACCEPT_YES_MULTI;
+ }
+ else
+ {
+ *accept = ACCEPT_NO;
+ }
+ }
+ if(mParentFolder && !handled)
+ {
+ handled = mParentFolder->handleDragAndDropFromChild(mask,drop,cargo_type,cargo_data,accept,tooltip_msg);
+ }
+ if (handled)
+ {
+ lldebugst(LLERR_USER_INPUT) << "dragAndDrop handled by LLFolderViewItem" << llendl;
+ }
+
+ return handled;
+}
+
+
+void LLFolderViewItem::draw()
+{
+ static LLUIColor sFgColor = LLUIColorTable::instance().getColor("MenuItemEnabledColor", DEFAULT_WHITE);
+ static LLUIColor sHighlightBgColor = LLUIColorTable::instance().getColor("MenuItemHighlightBgColor", DEFAULT_WHITE);
+ static LLUIColor sHighlightFgColor = LLUIColorTable::instance().getColor("MenuItemHighlightFgColor", DEFAULT_WHITE);
+ static LLUIColor sFilterBGColor = LLUIColorTable::instance().getColor("FilterBackgroundColor", DEFAULT_WHITE);
+ static LLUIColor sFilterTextColor = LLUIColorTable::instance().getColor("FilterTextColor", DEFAULT_WHITE);
+ static LLUIColor sSuffixColor = LLUIColorTable::instance().getColor("InventoryItemSuffixColor", DEFAULT_WHITE);
+ static LLUIColor sSearchStatusColor = LLUIColorTable::instance().getColor("InventorySearchStatusColor", DEFAULT_WHITE);
+
+ bool possibly_has_children = false;
+ bool up_to_date = mListener && mListener->isUpToDate();
+ if((up_to_date && hasVisibleChildren() ) || // we fetched our children and some of them have passed the filter...
+ (!up_to_date && mListener && mListener->hasChildren())) // ...or we know we have children but haven't fetched them (doesn't obey filter)
+ {
+ possibly_has_children = true;
+ }
+ if(/*mControlLabel[0] != '\0' && */possibly_has_children)
+ {
+ if (sArrowImage)
+ {
+ gl_draw_scaled_rotated_image(mIndentation, getRect().getHeight() - ARROW_SIZE - TEXT_PAD,
+ ARROW_SIZE, ARROW_SIZE, mControlLabelRotation, sArrowImage->getImage(), sFgColor);
+ }
+ }
+
+ F32 text_left = (F32)(ARROW_SIZE + TEXT_PAD + ICON_WIDTH + ICON_PAD + mIndentation);
+
+ // If we have keyboard focus, draw selection filled
+ BOOL show_context = getRoot()->getShowSelectionContext();
+ BOOL filled = show_context || (getRoot()->getParentPanel()->hasFocus());
+
+ // always render "current" item, only render other selected items if
+ // mShowSingleSelection is FALSE
+ if( mIsSelected )
+ {
+ gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
+ LLColor4 bg_color = sHighlightBgColor;
+ //const S32 TRAILING_PAD = 5; // It just looks better with this.
+ if (!mIsCurSelection)
+ {
+ // do time-based fade of extra objects
+ F32 fade_time = getRoot()->getSelectionFadeElapsedTime();
+ if (getRoot()->getShowSingleSelection())
+ {
+ // fading out
+ bg_color.mV[VALPHA] = clamp_rescale(fade_time, 0.f, 0.4f, bg_color.mV[VALPHA], 0.f);
+ }
+ else
+ {
+ // fading in
+ bg_color.mV[VALPHA] = clamp_rescale(fade_time, 0.f, 0.4f, 0.f, bg_color.mV[VALPHA]);
+ }
+ }
+
+ gl_rect_2d(
+ 0,
+ getRect().getHeight(),
+ getRect().getWidth() - 2,
+ llfloor(getRect().getHeight() - sFont->getLineHeight() - ICON_PAD),
+ bg_color, filled);
+ if (mIsCurSelection)
+ {
+ gl_rect_2d(
+ 0,
+ getRect().getHeight(),
+ getRect().getWidth() - 2,
+ llfloor(getRect().getHeight() - sFont->getLineHeight() - ICON_PAD),
+ sHighlightFgColor, FALSE);
+ }
+ if (getRect().getHeight() > llround(sFont->getLineHeight()) + ICON_PAD + 2)
+ {
+ gl_rect_2d(
+ 0,
+ llfloor(getRect().getHeight() - sFont->getLineHeight() - ICON_PAD) - 2,
+ getRect().getWidth() - 2,
+ 2,
+ sHighlightFgColor, FALSE);
+ if (show_context)
+ {
+ gl_rect_2d(
+ 0,
+ llfloor(getRect().getHeight() - sFont->getLineHeight() - ICON_PAD) - 2,
+ getRect().getWidth() - 2,
+ 2,
+ sHighlightBgColor, TRUE);
+ }
+ }
+ }
+ if (mDragAndDropTarget)
+ {
+ gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
+ gl_rect_2d(
+ 0,
+ getRect().getHeight(),
+ getRect().getWidth() - 2,
+ llfloor(getRect().getHeight() - sFont->getLineHeight() - ICON_PAD),
+ sHighlightBgColor, FALSE);
+
+ if (getRect().getHeight() > llround(sFont->getLineHeight()) + ICON_PAD + 2)
+ {
+ gl_rect_2d(
+ 0,
+ llfloor(getRect().getHeight() - sFont->getLineHeight() - ICON_PAD) - 2,
+ getRect().getWidth() - 2,
+ 2,
+ sHighlightBgColor, FALSE);
+ }
+ mDragAndDropTarget = FALSE;
+ }
+
+
+ if(mIcon)
+ {
+ mIcon->draw(mIndentation + ARROW_SIZE + TEXT_PAD, getRect().getHeight() - mIcon->getHeight());
+ }
+
+ if (!mLabel.empty())
+ {
+ // highlight filtered text
+ BOOL debug_filters = getRoot()->getDebugFilters();
+ LLColor4 color = ( (mIsSelected && filled) ? sHighlightFgColor : sFgColor );
+ F32 right_x;
+ F32 y = (F32)getRect().getHeight() - sFont->getLineHeight() - (F32)TEXT_PAD;
+
+ if (debug_filters)
+ {
+ if (!getFiltered() && !possibly_has_children)
+ {
+ color.mV[VALPHA] *= 0.5f;
+ }
+
+ LLColor4 filter_color = mLastFilterGeneration >= getRoot()->getFilter()->getCurrentGeneration() ? LLColor4(0.5f, 0.8f, 0.5f, 1.f) : LLColor4(0.8f, 0.5f, 0.5f, 1.f);
+ sSmallFont->renderUTF8(mStatusText, 0, text_left, y, filter_color,
+ LLFontGL::LEFT, LLFontGL::BOTTOM, LLFontGL::NORMAL, LLFontGL::NO_SHADOW,
+ S32_MAX, S32_MAX, &right_x, FALSE );
+ text_left = right_x;
+ }
+
+
+ if ( mIsLoading
+ && mTimeSinceRequestStart.getElapsedTimeF32() >= gSavedSettings.getF32("FolderLoadingMessageWaitTime") )
+ {
+ sFont->renderUTF8(LLTrans::getString("LoadingData"), 0, text_left, y, sSearchStatusColor,
+ LLFontGL::LEFT, LLFontGL::BOTTOM, mLabelStyle, LLFontGL::NO_SHADOW, S32_MAX, S32_MAX, &right_x, FALSE);
+ text_left = right_x;
+ }
+
+ sFont->renderUTF8( mLabel, 0, text_left, y, color,
+ LLFontGL::LEFT, LLFontGL::BOTTOM, mLabelStyle, LLFontGL::NO_SHADOW,
+ S32_MAX, S32_MAX, &right_x, FALSE );
+ if (!mLabelSuffix.empty())
+ {
+ sFont->renderUTF8( mLabelSuffix, 0, right_x, y, sSuffixColor,
+ LLFontGL::LEFT, LLFontGL::BOTTOM, mLabelStyle, LLFontGL::NO_SHADOW,
+ S32_MAX, S32_MAX, &right_x, FALSE );
+ }
+
+ if (sBoxImage.notNull() && mStringMatchOffset != std::string::npos)
+ {
+ // don't draw backgrounds for zero-length strings
+ S32 filter_string_length = getRoot()->getFilterSubString().size();
+ if (filter_string_length > 0)
+ {
+ std::string combined_string = mLabel + mLabelSuffix;
+ S32 left = llround(text_left) + sFont->getWidth(combined_string, 0, mStringMatchOffset) - 1;
+ S32 right = left + sFont->getWidth(combined_string, mStringMatchOffset, filter_string_length) + 2;
+ S32 bottom = llfloor(getRect().getHeight() - sFont->getLineHeight() - 3);
+ S32 top = getRect().getHeight();
+
+ LLRect box_rect(left, top, right, bottom);
+ sBoxImage->draw(box_rect, sFilterBGColor);
+ F32 match_string_left = text_left + sFont->getWidthF32(combined_string, 0, mStringMatchOffset);
+ F32 y = (F32)getRect().getHeight() - sFont->getLineHeight() - (F32)TEXT_PAD;
+ sFont->renderUTF8( combined_string, mStringMatchOffset, match_string_left, y,
+ sFilterTextColor, LLFontGL::LEFT, LLFontGL::BOTTOM, mLabelStyle, LLFontGL::NO_SHADOW,
+ filter_string_length, S32_MAX, &right_x, FALSE );
+ }
+ }
+ }
+
+ if( sDebugRects )
+ {
+ drawDebugRect();
+ }
+
+ //// *HACK: also draw debug rectangles around currently-being-edited LLView, and any elements that are being highlighted by GUI preview code (see LLFloaterUIPreview)
+ //std::set<LLView*>::iterator iter = std::find(sPreviewHighlightedElements.begin(), sPreviewHighlightedElements.end(), this);
+ //if ((sEditingUI && this == sEditingUIView) || (iter != sPreviewHighlightedElements.end() && sDrawPreviewHighlights))
+ //{
+ // drawDebugRect();
+ //}
+}
+
+
+///----------------------------------------------------------------------------
+/// Class LLFolderViewFolder
+///----------------------------------------------------------------------------
+
+LLFolderViewFolder::LLFolderViewFolder( const LLFolderViewItem::Params& p ):
+LLFolderViewItem( p ), // 0 = no create time
+mIsOpen(FALSE),
+mExpanderHighlighted(FALSE),
+mCurHeight(0.f),
+mTargetHeight(0.f),
+mAutoOpenCountdown(0.f),
+mSubtreeCreationDate(0),
+mAmTrash(LLFolderViewFolder::UNKNOWN),
+mLastArrangeGeneration( -1 ),
+mLastCalculatedWidth(0),
+mCompletedFilterGeneration(-1),
+mMostFilteredDescendantGeneration(-1),
+mNeedsSort(false)
+{}
+
+// Destroys the object
+LLFolderViewFolder::~LLFolderViewFolder( void )
+{
+ // The LLView base class takes care of object destruction. make sure that we
+ // don't have mouse or keyboard focus
+ gFocusMgr.releaseFocusIfNeeded( this ); // calls onCommit()
+}
+
+// addToFolder() returns TRUE if it succeeds. FALSE otherwise
+BOOL LLFolderViewFolder::addToFolder(LLFolderViewFolder* folder, LLFolderView* root)
+{
+ if (!folder)
+ {
+ return FALSE;
+ }
+ mParentFolder = folder;
+ root->addItemID(getListener()->getUUID(), this);
+ return folder->addFolder(this);
+}
+
+// Finds width and height of this object and it's children. Also
+// makes sure that this view and it's children are the right size.
+S32 LLFolderViewFolder::arrange( S32* width, S32* height, S32 filter_generation)
+{
+ // sort before laying out contents
+ if (mNeedsSort)
+ {
+ mFolders.sort(mSortFunction);
+ mItems.sort(mSortFunction);
+ mNeedsSort = false;
+ }
+
+ mHasVisibleChildren = hasFilteredDescendants(filter_generation);
+
+ LLInventoryFilter::EFolderShow show_folder_state = getRoot()->getFilter()->getShowFolderState();
+
+ // calculate height as a single item (without any children), and reshapes rectangle to match
+ LLFolderViewItem::arrange( width, height, filter_generation );
+
+ // clamp existing animated height so as to never get smaller than a single item
+ mCurHeight = llmax((F32)*height, mCurHeight);
+
+ // initialize running height value as height of single item in case we have no children
+ *height = getItemHeight();
+ F32 running_height = (F32)*height;
+ F32 target_height = (F32)*height;
+
+ // are my children visible?
+ if (needsArrange())
+ {
+ // set last arrange generation first, in case children are animating
+ // and need to be arranged again
+ mLastArrangeGeneration = getRoot()->getArrangeGeneration();
+ if (mIsOpen)
+ {
+ // Add sizes of children
+ S32 parent_item_height = getRect().getHeight();
+
+ for(folders_t::iterator fit = mFolders.begin(); fit != mFolders.end(); ++fit)
+ {
+ LLFolderViewFolder* folderp = (*fit);
+ if (getRoot()->getDebugFilters())
+ {
+ folderp->setVisible(TRUE);
+ }
+ else
+ {
+ folderp->setVisible(show_folder_state == LLInventoryFilter::SHOW_ALL_FOLDERS || // always show folders?
+ (folderp->getFiltered(filter_generation) || folderp->hasFilteredDescendants(filter_generation))); // passed filter or has descendants that passed filter
+ }
+
+ if (folderp->getVisible())
+ {
+ S32 child_width = *width;
+ S32 child_height = 0;
+ S32 child_top = parent_item_height - llround(running_height);
+
+ target_height += folderp->arrange( &child_width, &child_height, filter_generation );
+
+ running_height += (F32)child_height;
+ *width = llmax(*width, child_width);
+ folderp->setOrigin( 0, child_top - folderp->getRect().getHeight() );
+ }
+ }
+ for(items_t::iterator iit = mItems.begin();
+ iit != mItems.end(); ++iit)
+ {
+ LLFolderViewItem* itemp = (*iit);
+ if (getRoot()->getDebugFilters())
+ {
+ itemp->setVisible(TRUE);
+ }
+ else
+ {
+ itemp->setVisible(itemp->getFiltered(filter_generation));
+ }
+
+ if (itemp->getVisible())
+ {
+ S32 child_width = *width;
+ S32 child_height = 0;
+ S32 child_top = parent_item_height - llround(running_height);
+
+ target_height += itemp->arrange( &child_width, &child_height, filter_generation );
+ // don't change width, as this item is as wide as its parent folder by construction
+ itemp->reshape( itemp->getRect().getWidth(), child_height);
+
+ running_height += (F32)child_height;
+ *width = llmax(*width, child_width);
+ itemp->setOrigin( 0, child_top - itemp->getRect().getHeight() );
+ }
+ }
+ }
+
+ mTargetHeight = target_height;
+ // cache this width so next time we can just return it
+ mLastCalculatedWidth = *width;
+ }
+ else
+ {
+ // just use existing width
+ *width = mLastCalculatedWidth;
+ }
+
+ // animate current height towards target height
+ if (llabs(mCurHeight - mTargetHeight) > 1.f)
+ {
+ mCurHeight = lerp(mCurHeight, mTargetHeight, LLCriticalDamp::getInterpolant(mIsOpen ? FOLDER_OPEN_TIME_CONSTANT : FOLDER_CLOSE_TIME_CONSTANT));
+
+ requestArrange();
+
+ // hide child elements that fall out of current animated height
+ for (folders_t::iterator iter = mFolders.begin();
+ iter != mFolders.end();)
+ {
+ folders_t::iterator fit = iter++;
+ // number of pixels that bottom of folder label is from top of parent folder
+ if (getRect().getHeight() - (*fit)->getRect().mTop + (*fit)->getItemHeight()
+ > llround(mCurHeight) + MAX_FOLDER_ITEM_OVERLAP)
+ {
+ // hide if beyond current folder height
+ (*fit)->setVisible(FALSE);
+ }
+ }
+
+ for (items_t::iterator iter = mItems.begin();
+ iter != mItems.end();)
+ {
+ items_t::iterator iit = iter++;
+ // number of pixels that bottom of item label is from top of parent folder
+ if (getRect().getHeight() - (*iit)->getRect().mBottom
+ > llround(mCurHeight) + MAX_FOLDER_ITEM_OVERLAP)
+ {
+ (*iit)->setVisible(FALSE);
+ }
+ }
+ }
+ else
+ {
+ mCurHeight = mTargetHeight;
+ }
+
+ // don't change width as this item is already as wide as its parent folder
+ reshape(getRect().getWidth(),llround(mCurHeight));
+
+ // pass current height value back to parent
+ *height = llround(mCurHeight);
+
+ return llround(mTargetHeight);
+}
+
+BOOL LLFolderViewFolder::needsArrange()
+{
+ return mLastArrangeGeneration < getRoot()->getArrangeGeneration();
+}
+
+void LLFolderViewFolder::requestSort()
+{
+ mNeedsSort = true;
+ // whenever item order changes, we need to lay things out again
+ requestArrange();
+}
+
+void LLFolderViewFolder::setCompletedFilterGeneration(S32 generation, BOOL recurse_up)
+{
+ mMostFilteredDescendantGeneration = llmin(mMostFilteredDescendantGeneration, generation);
+ mCompletedFilterGeneration = generation;
+ // only aggregate up if we are a lower (older) value
+ if (recurse_up && mParentFolder && generation < mParentFolder->getCompletedFilterGeneration())
+ {
+ mParentFolder->setCompletedFilterGeneration(generation, TRUE);
+ }
+}
+
+void LLFolderViewFolder::filter( LLInventoryFilter& filter)
+{
+ S32 filter_generation = filter.getCurrentGeneration();
+ // if failed to pass filter newer than must_pass_generation
+ // you will automatically fail this time, so we only
+ // check against items that have passed the filter
+ S32 must_pass_generation = filter.getMustPassGeneration();
+
+ // if we have already been filtered against this generation, skip out
+ if (getCompletedFilterGeneration() >= filter_generation)
+ {
+ return;
+ }
+
+ // filter folder itself
+ if (getLastFilterGeneration() < filter_generation)
+ {
+ if (getLastFilterGeneration() >= must_pass_generation && // folder has been compared to a valid precursor filter
+ !mFiltered) // and did not pass the filter
+ {
+ // go ahead and flag this folder as done
+ mLastFilterGeneration = filter_generation;
+ }
+ else
+ {
+ // filter self only on first pass through
+ LLFolderViewItem::filter( filter );
+ }
+ }
+
+ if (getRoot()->getDebugFilters())
+ {
+ mStatusText = llformat("%d", mLastFilterGeneration);
+ mStatusText += llformat("(%d)", mCompletedFilterGeneration);
+ mStatusText += llformat("+%d", mMostFilteredDescendantGeneration);
+ }
+
+ // all descendants have been filtered later than must pass generation
+ // but none passed
+ if(getCompletedFilterGeneration() >= must_pass_generation && !hasFilteredDescendants(must_pass_generation))
+ {
+ // don't traverse children if we've already filtered them since must_pass_generation
+ // and came back with nothing
+ return;
+ }
+
+ // we entered here with at least one filter iteration left
+ // check to see if we have any more before continuing on to children
+ if (filter.getFilterCount() < 0)
+ {
+ return;
+ }
+
+ // when applying a filter, matching folders get their contents downloaded first
+ if (filter.isNotDefault() && getFiltered(filter.getMinRequiredGeneration()) && (mListener && !gInventory.isCategoryComplete(mListener->getUUID())))
+ {
+ gInventory.startBackgroundFetch(mListener->getUUID());
+ }
+
+ // now query children
+ for (folders_t::iterator iter = mFolders.begin();
+ iter != mFolders.end();)
+ {
+ folders_t::iterator fit = iter++;
+ // have we run out of iterations this frame?
+ if (filter.getFilterCount() < 0)
+ {
+ break;
+ }
+
+ // mMostFilteredDescendantGeneration might have been reset
+ // in which case we need to update it even for folders that
+ // don't need to be filtered anymore
+ if ((*fit)->getCompletedFilterGeneration() >= filter_generation)
+ {
+ // track latest generation to pass any child items
+ if ((*fit)->getFiltered() || (*fit)->hasFilteredDescendants(filter.getMinRequiredGeneration()))
+ {
+ mMostFilteredDescendantGeneration = filter_generation;
+ if (getRoot()->needsAutoSelect())
+ {
+ (*fit)->setOpenArrangeRecursively(TRUE);
+ }
+ }
+ // just skip it, it has already been filtered
+ continue;
+ }
+
+ // update this folders filter status (and children)
+ (*fit)->filter( filter );
+
+ // track latest generation to pass any child items
+ if ((*fit)->getFiltered() || (*fit)->hasFilteredDescendants(filter_generation))
+ {
+ mMostFilteredDescendantGeneration = filter_generation;
+ if (getRoot()->needsAutoSelect())
+ {
+ (*fit)->setOpenArrangeRecursively(TRUE);
+ }
+ }
+ }
+
+ for (items_t::iterator iter = mItems.begin();
+ iter != mItems.end();)
+ {
+ items_t::iterator iit = iter++;
+ if (filter.getFilterCount() < 0)
+ {
+ break;
+ }
+ if ((*iit)->getLastFilterGeneration() >= filter_generation)
+ {
+ if ((*iit)->getFiltered())
+ {
+ mMostFilteredDescendantGeneration = filter_generation;
+ }
+ continue;
+ }
+
+ if ((*iit)->getLastFilterGeneration() >= must_pass_generation &&
+ !(*iit)->getFiltered(must_pass_generation))
+ {
+ // failed to pass an earlier filter that was a subset of the current one
+ // go ahead and flag this item as done
+ (*iit)->setFiltered(FALSE, filter_generation);
+ continue;
+ }
+
+ (*iit)->filter( filter );
+
+ if ((*iit)->getFiltered(filter.getMinRequiredGeneration()))
+ {
+ mMostFilteredDescendantGeneration = filter_generation;
+ }
+ }
+
+ // if we didn't use all filter iterations
+ // that means we filtered all of our descendants
+ // instead of exhausting the filter count for this frame
+ if (filter.getFilterCount() > 0)
+ {
+ // flag this folder as having completed filter pass for all descendants
+ setCompletedFilterGeneration(filter_generation, FALSE/*dont recurse up to root*/);
+ }
+}
+
+void LLFolderViewFolder::setFiltered(BOOL filtered, S32 filter_generation)
+{
+ // if this folder is now filtered, but wasn't before
+ // (it just passed)
+ if (filtered && !mFiltered)
+ {
+ // reset current height, because last time we drew it
+ // it might have had more visible items than now
+ mCurHeight = 0.f;
+ }
+
+ LLFolderViewItem::setFiltered(filtered, filter_generation);
+}
+
+void LLFolderViewFolder::dirtyFilter()
+{
+ // we're a folder, so invalidate our completed generation
+ setCompletedFilterGeneration(-1, FALSE);
+ LLFolderViewItem::dirtyFilter();
+}
+
+BOOL LLFolderViewFolder::hasFilteredDescendants()
+{
+ return mMostFilteredDescendantGeneration >= getRoot()->getFilter()->getCurrentGeneration();
+}
+
+// Passes selection information on to children and record selection
+// information if necessary.
+BOOL LLFolderViewFolder::setSelection(LLFolderViewItem* selection, BOOL openitem,
+ BOOL take_keyboard_focus)
+{
+ BOOL rv = FALSE;
+ if( selection == this )
+ {
+ mIsSelected = TRUE;
+ if(mListener)
+ {
+ mListener->selectItem();
+ }
+ rv = TRUE;
+ }
+ else
+ {
+ mIsSelected = FALSE;
+ rv = FALSE;
+ }
+ BOOL child_selected = FALSE;
+
+ for (folders_t::iterator iter = mFolders.begin();
+ iter != mFolders.end();)
+ {
+ folders_t::iterator fit = iter++;
+ if((*fit)->setSelection(selection, openitem, take_keyboard_focus))
+ {
+ rv = TRUE;
+ child_selected = TRUE;
+ mNumDescendantsSelected++;
+ }
+ }
+ for (items_t::iterator iter = mItems.begin();
+ iter != mItems.end();)
+ {
+ items_t::iterator iit = iter++;
+ if((*iit)->setSelection(selection, openitem, take_keyboard_focus))
+ {
+ rv = TRUE;
+ child_selected = TRUE;
+ mNumDescendantsSelected++;
+ }
+ }
+ if(openitem && child_selected)
+ {
+ setOpenArrangeRecursively(TRUE);
+ }
+ return rv;
+}
+
+// This method is used to change the selection of an item. If
+// selection is 'this', then note selection as true. Returns TRUE
+// if this or a child is now selected.
+BOOL LLFolderViewFolder::changeSelection(LLFolderViewItem* selection,
+ BOOL selected)
+{
+ BOOL rv = FALSE;
+ if(selection == this)
+ {
+ mIsSelected = selected;
+ if(mListener && selected)
+ {
+ mListener->selectItem();
+ }
+ rv = TRUE;
+ }
+
+ for (folders_t::iterator iter = mFolders.begin();
+ iter != mFolders.end();)
+ {
+ folders_t::iterator fit = iter++;
+ if((*fit)->changeSelection(selection, selected))
+ {
+ if (selected)
+ {
+ mNumDescendantsSelected++;
+ }
+ else
+ {
+ mNumDescendantsSelected--;
+ }
+ rv = TRUE;
+ }
+ }
+ for (items_t::iterator iter = mItems.begin();
+ iter != mItems.end();)
+ {
+ items_t::iterator iit = iter++;
+ if((*iit)->changeSelection(selection, selected))
+ {
+ if (selected)
+ {
+ mNumDescendantsSelected++;
+ }
+ else
+ {
+ mNumDescendantsSelected--;
+ }
+ rv = TRUE;
+ }
+ }
+ return rv;
+}
+
+S32 LLFolderViewFolder::extendSelection(LLFolderViewItem* selection, LLFolderViewItem* last_selected, LLDynamicArray<LLFolderViewItem*>& selected_items)
+{
+ S32 num_selected = 0;
+
+ // pass on to child folders first
+ for (folders_t::iterator iter = mFolders.begin();
+ iter != mFolders.end();)
+ {
+ folders_t::iterator fit = iter++;
+ num_selected += (*fit)->extendSelection(selection, last_selected, selected_items);
+ mNumDescendantsSelected += num_selected;
+ }
+
+ // handle selection of our immediate children...
+ BOOL reverse_select = FALSE;
+ BOOL found_last_selected = FALSE;
+ BOOL found_selection = FALSE;
+ LLDynamicArray<LLFolderViewItem*> items_to_select;
+ LLFolderViewItem* item;
+
+ //...folders first...
+ for (folders_t::iterator iter = mFolders.begin();
+ iter != mFolders.end();)
+ {
+ folders_t::iterator fit = iter++;
+ item = (*fit);
+ if(item == selection)
+ {
+ found_selection = TRUE;
+ }
+ else if (item == last_selected)
+ {
+ found_last_selected = TRUE;
+ if (found_selection)
+ {
+ reverse_select = TRUE;
+ }
+ }
+
+ if (found_selection || found_last_selected)
+ {
+ // deselect currently selected items so they can be pushed back on queue
+ if (item->isSelected())
+ {
+ item->changeSelection(item, FALSE);
+ }
+ items_to_select.put(item);
+ }
+
+ if (found_selection && found_last_selected)
+ {
+ break;
+ }
+ }
+
+ if (!(found_selection && found_last_selected))
+ {
+ //,,,then items
+ for (items_t::iterator iter = mItems.begin();
+ iter != mItems.end();)
+ {
+ items_t::iterator iit = iter++;
+ item = (*iit);
+ if(item == selection)
+ {
+ found_selection = TRUE;
+ }
+ else if (item == last_selected)
+ {
+ found_last_selected = TRUE;
+ if (found_selection)
+ {
+ reverse_select = TRUE;
+ }
+ }
+
+ if (found_selection || found_last_selected)
+ {
+ // deselect currently selected items so they can be pushed back on queue
+ if (item->isSelected())
+ {
+ item->changeSelection(item, FALSE);
+ }
+ items_to_select.put(item);
+ }
+
+ if (found_selection && found_last_selected)
+ {
+ break;
+ }
+ }
+ }
+
+ if (found_last_selected && found_selection)
+ {
+ // we have a complete selection inside this folder
+ for (S32 index = reverse_select ? items_to_select.getLength() - 1 : 0;
+ reverse_select ? index >= 0 : index < items_to_select.getLength(); reverse_select ? index-- : index++)
+ {
+ LLFolderViewItem* item = items_to_select[index];
+ if (item->changeSelection(item, TRUE))
+ {
+ selected_items.put(item);
+ mNumDescendantsSelected++;
+ num_selected++;
+ }
+ }
+ }
+ else if (found_selection)
+ {
+ // last selection was not in this folder....go ahead and select just the new item
+ if (selection->changeSelection(selection, TRUE))
+ {
+ selected_items.put(selection);
+ mNumDescendantsSelected++;
+ num_selected++;
+ }
+ }
+
+ return num_selected;
+}
+
+void LLFolderViewFolder::recursiveDeselect(BOOL deselect_self)
+{
+ // make sure we don't have negative values
+ llassert(mNumDescendantsSelected >= 0);
+
+ if (mIsSelected && deselect_self)
+ {
+ mIsSelected = FALSE;
+
+ // update ancestors' count of selected descendents
+ LLFolderViewFolder* parent_folder = getParentFolder();
+ while(parent_folder)
+ {
+ parent_folder->mNumDescendantsSelected--;
+ parent_folder = parent_folder->getParentFolder();
+ }
+ }
+
+ if (0 == mNumDescendantsSelected)
+ {
+ return;
+ }
+
+ for (items_t::iterator iter = mItems.begin();
+ iter != mItems.end();)
+ {
+ items_t::iterator iit = iter++;
+ LLFolderViewItem* item = (*iit);
+ item->recursiveDeselect(TRUE);
+ }
+
+ for (folders_t::iterator iter = mFolders.begin();
+ iter != mFolders.end();)
+ {
+ folders_t::iterator fit = iter++;
+ LLFolderViewFolder* folder = (*fit);
+ folder->recursiveDeselect(TRUE);
+ }
+
+}
+
+void LLFolderViewFolder::destroyView()
+{
+ for (items_t::iterator iter = mItems.begin();
+ iter != mItems.end();)
+ {
+ items_t::iterator iit = iter++;
+ LLFolderViewItem* item = (*iit);
+ getRoot()->removeItemID(item->getListener()->getUUID());
+ }
+
+ std::for_each(mItems.begin(), mItems.end(), DeletePointer());
+ mItems.clear();
+
+ while (!mFolders.empty())
+ {
+ LLFolderViewFolder *folderp = mFolders.back();
+ folderp->destroyView(); // removes entry from mFolders
+ }
+
+ deleteAllChildren();
+
+ if (mParentFolder)
+ {
+ mParentFolder->removeView(this);
+ }
+}
+
+// remove the specified item (and any children) if possible. Return
+// TRUE if the item was deleted.
+BOOL LLFolderViewFolder::removeItem(LLFolderViewItem* item)
+{
+ if(item->remove())
+ {
+ //RN: this seem unneccessary as remove() moves to trash
+ //removeView(item);
+ return TRUE;
+ }
+ return FALSE;
+}
+
+// simply remove the view (and any children) Don't bother telling the
+// listeners.
+void LLFolderViewFolder::removeView(LLFolderViewItem* item)
+{
+ if (!item || item->getParentFolder() != this)
+ {
+ return;
+ }
+ // deselect without traversing hierarchy
+ item->recursiveDeselect(TRUE);
+ getRoot()->removeFromSelectionList(item);
+ extractItem(item);
+ delete item;
+}
+
+// extractItem() removes the specified item from the folder, but
+// doesn't delete it.
+void LLFolderViewFolder::extractItem( LLFolderViewItem* item )
+{
+ items_t::iterator it = std::find(mItems.begin(), mItems.end(), item);
+ if(it == mItems.end())
+ {
+ // This is an evil downcast. However, it's only doing
+ // pointer comparison to find if (which it should be ) the
+ // item is in the container, so it's pretty safe.
+ LLFolderViewFolder* f = reinterpret_cast<LLFolderViewFolder*>(item);
+ folders_t::iterator ft;
+ ft = std::find(mFolders.begin(), mFolders.end(), f);
+ if(ft != mFolders.end())
+ {
+ mFolders.erase(ft);
+ }
+ }
+ else
+ {
+ mItems.erase(it);
+ }
+ //item has been removed, need to update filter
+ dirtyFilter();
+ //because an item is going away regardless of filter status, force rearrange
+ requestArrange();
+ getRoot()->removeItemID(item->getListener()->getUUID());
+ removeChild(item);
+}
+
+bool LLFolderViewFolder::isTrash() const
+{
+ if (mAmTrash == LLFolderViewFolder::UNKNOWN)
+ {
+ mAmTrash = mListener->getUUID() == gInventory.findCategoryUUIDForType(LLAssetType::AT_TRASH, false) ? LLFolderViewFolder::TRASH : LLFolderViewFolder::NOT_TRASH;
+ }
+ return mAmTrash == LLFolderViewFolder::TRASH;
+}
+
+void LLFolderViewFolder::sortBy(U32 order)
+{
+ if (!mSortFunction.updateSort(order))
+ {
+ // No changes.
+ return;
+ }
+
+ // Propegate this change to sub folders
+ for (folders_t::iterator iter = mFolders.begin();
+ iter != mFolders.end();)
+ {
+ folders_t::iterator fit = iter++;
+ (*fit)->sortBy(order);
+ }
+
+ mFolders.sort(mSortFunction);
+ mItems.sort(mSortFunction);
+
+ if (order & LLInventoryFilter::SO_DATE)
+ {
+ time_t latest = 0;
+
+ if (!mItems.empty())
+ {
+ LLFolderViewItem* item = *(mItems.begin());
+ latest = item->getCreationDate();
+ }
+
+ if (!mFolders.empty())
+ {
+ LLFolderViewFolder* folder = *(mFolders.begin());
+ if (folder->getCreationDate() > latest)
+ {
+ latest = folder->getCreationDate();
+ }
+ }
+ mSubtreeCreationDate = latest;
+ }
+}
+
+void LLFolderViewFolder::setItemSortOrder(U32 ordering)
+{
+ if (mSortFunction.updateSort(ordering))
+ {
+ for (folders_t::iterator iter = mFolders.begin();
+ iter != mFolders.end();)
+ {
+ folders_t::iterator fit = iter++;
+ (*fit)->setItemSortOrder(ordering);
+ }
+
+ mFolders.sort(mSortFunction);
+ mItems.sort(mSortFunction);
+ }
+}
+
+EInventorySortGroup LLFolderViewFolder::getSortGroup() const
+{
+ if (isTrash())
+ {
+ return SG_TRASH_FOLDER;
+ }
+
+ // Folders that can't be moved are 'system' folders.
+ if( mListener )
+ {
+ if( !(mListener->isItemMovable()) )
+ {
+ return SG_SYSTEM_FOLDER;
+ }
+ }
+
+ return SG_NORMAL_FOLDER;
+}
+
+BOOL LLFolderViewFolder::isMovable()
+{
+ if( mListener )
+ {
+ if( !(mListener->isItemMovable()) )
+ {
+ return FALSE;
+ }
+
+ for (items_t::iterator iter = mItems.begin();
+ iter != mItems.end();)
+ {
+ items_t::iterator iit = iter++;
+ if(!(*iit)->isMovable())
+ {
+ return FALSE;
+ }
+ }
+
+ for (folders_t::iterator iter = mFolders.begin();
+ iter != mFolders.end();)
+ {
+ folders_t::iterator fit = iter++;
+ if(!(*fit)->isMovable())
+ {
+ return FALSE;
+ }
+ }
+ }
+ return TRUE;
+}
+
+
+BOOL LLFolderViewFolder::isRemovable()
+{
+ if( mListener )
+ {
+ if( !(mListener->isItemRemovable()) )
+ {
+ return FALSE;
+ }
+
+ for (items_t::iterator iter = mItems.begin();
+ iter != mItems.end();)
+ {
+ items_t::iterator iit = iter++;
+ if(!(*iit)->isRemovable())
+ {
+ return FALSE;
+ }
+ }
+
+ for (folders_t::iterator iter = mFolders.begin();
+ iter != mFolders.end();)
+ {
+ folders_t::iterator fit = iter++;
+ if(!(*fit)->isRemovable())
+ {
+ return FALSE;
+ }
+ }
+ }
+ return TRUE;
+}
+
+// this is an internal method used for adding items to folders.
+BOOL LLFolderViewFolder::addItem(LLFolderViewItem* item)
+{
+ mItems.push_back(item);
+ item->setRect(LLRect(0, 0, getRect().getWidth(), 0));
+ item->setVisible(FALSE);
+ addChild( item );
+ item->dirtyFilter();
+ requestArrange();
+ requestSort();
+ return TRUE;
+}
+
+// this is an internal method used for adding items to folders.
+BOOL LLFolderViewFolder::addFolder(LLFolderViewFolder* folder)
+{
+ mFolders.push_back(folder);
+ folder->setOrigin(0, 0);
+ folder->reshape(getRect().getWidth(), 0);
+ folder->setVisible(FALSE);
+ addChild( folder );
+ folder->dirtyFilter();
+ // rearrange all descendants too, as our indentation level might have changed
+ folder->requestArrange(TRUE);
+ requestSort();
+ return TRUE;
+}
+
+void LLFolderViewFolder::requestArrange(BOOL include_descendants)
+{
+ mLastArrangeGeneration = -1;
+ // flag all items up to root
+ if (mParentFolder)
+ {
+ mParentFolder->requestArrange();
+ }
+
+ if (include_descendants)
+ {
+ for (folders_t::iterator iter = mFolders.begin();
+ iter != mFolders.end();
+ ++iter)
+ {
+ (*iter)->requestArrange(TRUE);
+ }
+ }
+}
+
+void LLFolderViewFolder::toggleOpen()
+{
+ setOpen(!mIsOpen);
+}
+
+// Force a folder open or closed
+void LLFolderViewFolder::setOpen(BOOL openitem)
+{
+ setOpenArrangeRecursively(openitem);
+}
+
+void LLFolderViewFolder::setOpenArrangeRecursively(BOOL openitem, ERecurseType recurse)
+{
+ BOOL was_open = mIsOpen;
+ mIsOpen = openitem;
+ if (mListener)
+ {
+ if(!was_open && openitem)
+ {
+ mListener->openItem();
+ }
+ else if(was_open && !openitem)
+ {
+ mListener->closeItem();
+ }
+ }
+
+ if (recurse == RECURSE_DOWN || recurse == RECURSE_UP_DOWN)
+ {
+ for (folders_t::iterator iter = mFolders.begin();
+ iter != mFolders.end();)
+ {
+ folders_t::iterator fit = iter++;
+ (*fit)->setOpenArrangeRecursively(openitem, RECURSE_DOWN); /* Flawfinder: ignore */
+ }
+ }
+ if (mParentFolder && (recurse == RECURSE_UP || recurse == RECURSE_UP_DOWN))
+ {
+ mParentFolder->setOpenArrangeRecursively(openitem, RECURSE_UP);
+ }
+
+ if (was_open != mIsOpen)
+ {
+ requestArrange();
+ }
+}
+
+BOOL LLFolderViewFolder::handleDragAndDropFromChild(MASK mask,
+ BOOL drop,
+ EDragAndDropType c_type,
+ void* cargo_data,
+ EAcceptance* accept,
+ std::string& tooltip_msg)
+{
+ BOOL accepted = mListener && mListener->dragOrDrop(mask,drop,c_type,cargo_data);
+ if (accepted)
+ {
+ mDragAndDropTarget = TRUE;
+ *accept = ACCEPT_YES_MULTI;
+ }
+ else
+ {
+ *accept = ACCEPT_NO;
+ }
+
+ // drag and drop to child item, so clear pending auto-opens
+ getRoot()->autoOpenTest(NULL);
+
+ return TRUE;
+}
+
+void LLFolderViewFolder::openItem( void )
+{
+ toggleOpen();
+}
+
+void LLFolderViewFolder::applyFunctorRecursively(LLFolderViewFunctor& functor)
+{
+ functor.doFolder(this);
+
+ for (folders_t::iterator iter = mFolders.begin();
+ iter != mFolders.end();)
+ {
+ folders_t::iterator fit = iter++;
+ (*fit)->applyFunctorRecursively(functor);
+ }
+ for (items_t::iterator iter = mItems.begin();
+ iter != mItems.end();)
+ {
+ items_t::iterator iit = iter++;
+ functor.doItem((*iit));
+ }
+}
+
+void LLFolderViewFolder::applyListenerFunctorRecursively(LLFolderViewListenerFunctor& functor)
+{
+ functor(mListener);
+ for (folders_t::iterator iter = mFolders.begin();
+ iter != mFolders.end();)
+ {
+ folders_t::iterator fit = iter++;
+ (*fit)->applyListenerFunctorRecursively(functor);
+ }
+ for (items_t::iterator iter = mItems.begin();
+ iter != mItems.end();)
+ {
+ items_t::iterator iit = iter++;
+ (*iit)->applyListenerFunctorRecursively(functor);
+ }
+}
+
+// LLView functionality
+BOOL LLFolderViewFolder::handleDragAndDrop(S32 x, S32 y, MASK mask,
+ BOOL drop,
+ EDragAndDropType cargo_type,
+ void* cargo_data,
+ EAcceptance* accept,
+ std::string& tooltip_msg)
+{
+ LLFolderView* root_view = getRoot();
+
+ BOOL handled = FALSE;
+ if(mIsOpen)
+ {
+ handled = childrenHandleDragAndDrop(x, y, mask, drop, cargo_type,
+ cargo_data, accept, tooltip_msg) != NULL;
+ }
+
+ if (!handled)
+ {
+ BOOL accepted = mListener && mListener->dragOrDrop(mask, drop,cargo_type,cargo_data);
+
+ if (accepted)
+ {
+ mDragAndDropTarget = TRUE;
+ *accept = ACCEPT_YES_MULTI;
+ }
+ else
+ {
+ *accept = ACCEPT_NO;
+ }
+
+ if (!drop && accepted)
+ {
+ root_view->autoOpenTest(this);
+ }
+
+ lldebugst(LLERR_USER_INPUT) << "dragAndDrop handled by LLFolderViewFolder" << llendl;
+ }
+
+ return TRUE;
+}
+
+
+BOOL LLFolderViewFolder::handleRightMouseDown( S32 x, S32 y, MASK mask )
+{
+ BOOL handled = FALSE;
+ // fetch contents of this folder, as context menu can depend on contents
+ // still, user would have to open context menu again to see the changes
+ gInventory.fetchDescendentsOf(mListener->getUUID());
+
+ if( mIsOpen )
+ {
+ handled = childrenHandleRightMouseDown( x, y, mask ) != NULL;
+ }
+ if (!handled)
+ {
+ handled = LLFolderViewItem::handleRightMouseDown( x, y, mask );
+ }
+ return handled;
+}
+
+
+BOOL LLFolderViewFolder::handleHover(S32 x, S32 y, MASK mask)
+{
+ BOOL handled = LLView::handleHover(x, y, mask);
+
+ if (!handled)
+ {
+ // this doesn't do child processing
+ handled = LLFolderViewItem::handleHover(x, y, mask);
+ }
+
+ //if(x < LEFT_INDENTATION + mIndentation && x > mIndentation - LEFT_PAD && y > getRect().getHeight() - )
+ //{
+ // gViewerWindow->setCursor(UI_CURSOR_ARROW);
+ // mExpanderHighlighted = TRUE;
+ // handled = TRUE;
+ //}
+ return handled;
+}
+
+BOOL LLFolderViewFolder::handleMouseDown( S32 x, S32 y, MASK mask )
+{
+ BOOL handled = FALSE;
+ if( mIsOpen )
+ {
+ handled = childrenHandleMouseDown(x,y,mask) != NULL;
+ }
+ if( !handled )
+ {
+ if(x < LEFT_INDENTATION + mIndentation && x > mIndentation - LEFT_PAD)
+ {
+ toggleOpen();
+ handled = TRUE;
+ }
+ else
+ {
+ // do normal selection logic
+ handled = LLFolderViewItem::handleMouseDown(x, y, mask);
+ }
+ }
+
+ return handled;
+}
+
+BOOL LLFolderViewFolder::handleDoubleClick( S32 x, S32 y, MASK mask )
+{
+ const LLUUID &cat_uuid = getListener()->getUUID();
+ const LLViewerInventoryCategory *cat = gInventory.getCategory(cat_uuid);
+ if (cat && cat->getPreferredType() == LLAssetType::AT_OUTFIT)
+ {
+ getListener()->performAction(NULL, NULL,"replaceoutfit");
+ return TRUE;
+ }
+
+ BOOL handled = FALSE;
+ if( mIsOpen )
+ {
+ handled = childrenHandleDoubleClick( x, y, mask ) != NULL;
+ }
+ if( !handled )
+ {
+ if(x < LEFT_INDENTATION + mIndentation && x > mIndentation - LEFT_PAD)
+ {
+ // don't select when user double-clicks plus sign
+ // so as not to contradict single-click behavior
+ toggleOpen();
+ }
+ else
+ {
+ setSelectionFromRoot(this, FALSE);
+ toggleOpen();
+ }
+ handled = TRUE;
+ }
+ return handled;
+}
+
+void LLFolderViewFolder::draw()
+{
+ if (mAutoOpenCountdown != 0.f)
+ {
+ mControlLabelRotation = mAutoOpenCountdown * -90.f;
+ }
+ else if (mIsOpen)
+ {
+ mControlLabelRotation = lerp(mControlLabelRotation, -90.f, LLCriticalDamp::getInterpolant(0.04f));
+ }
+ else
+ {
+ mControlLabelRotation = lerp(mControlLabelRotation, 0.f, LLCriticalDamp::getInterpolant(0.025f));
+ }
+
+ bool possibly_has_children = false;
+ bool up_to_date = mListener && mListener->isUpToDate();
+ if(!up_to_date && mListener && mListener->hasChildren()) // we know we have children but haven't fetched them (doesn't obey filter)
+ {
+ possibly_has_children = true;
+ }
+
+
+ BOOL loading = ( mIsOpen && possibly_has_children && !up_to_date );
+
+ if ( loading && !mIsLoading )
+ {
+ // Measure how long we've been in the loading state
+ mTimeSinceRequestStart.reset();
+ }
+
+ mIsLoading = loading;
+
+ LLFolderViewItem::draw();
+
+ // draw children if root folder, or any other folder that is open or animating to closed state
+ if( getRoot() == this || (mIsOpen || mCurHeight != mTargetHeight ))
+ {
+ LLView::draw();
+ }
+
+ mExpanderHighlighted = FALSE;
+}
+
+time_t LLFolderViewFolder::getCreationDate() const
+{
+ return llmax<time_t>(mCreationDate, mSubtreeCreationDate);
+}
+
+
+BOOL LLFolderViewFolder::potentiallyVisible()
+{
+ // folder should be visible by it's own filter status
+ return LLFolderViewItem::potentiallyVisible()
+ // or one or more of its descendants have passed the minimum filter requirement
+ || hasFilteredDescendants(getRoot()->getFilter()->getMinRequiredGeneration())
+ // or not all of its descendants have been checked against minimum filter requirement
+ || getCompletedFilterGeneration() < getRoot()->getFilter()->getMinRequiredGeneration();
+}
+
+// this does prefix traversal, as folders are listed above their contents
+LLFolderViewItem* LLFolderViewFolder::getNextFromChild( LLFolderViewItem* item, BOOL include_children )
+{
+ BOOL found_item = FALSE;
+
+ LLFolderViewItem* result = NULL;
+ // when not starting from a given item, start at beginning
+ if(item == NULL)
+ {
+ found_item = TRUE;
+ }
+
+ // find current item among children
+ folders_t::iterator fit = mFolders.begin();
+ folders_t::iterator fend = mFolders.end();
+
+ items_t::iterator iit = mItems.begin();
+ items_t::iterator iend = mItems.end();
+
+ // if not trivially starting at the beginning, we have to find the current item
+ if (!found_item)
+ {
+ // first, look among folders, since they are always above items
+ for(; fit != fend; ++fit)
+ {
+ if(item == (*fit))
+ {
+ found_item = TRUE;
+ // if we are on downwards traversal
+ if (include_children && (*fit)->isOpen())
+ {
+ // look for first descendant
+ return (*fit)->getNextFromChild(NULL, TRUE);
+ }
+ // otherwise advance to next folder
+ ++fit;
+ include_children = TRUE;
+ break;
+ }
+ }
+
+ // didn't find in folders? Check items...
+ if (!found_item)
+ {
+ for(; iit != iend; ++iit)
+ {
+ if(item == (*iit))
+ {
+ found_item = TRUE;
+ // point to next item
+ ++iit;
+ break;
+ }
+ }
+ }
+ }
+
+ if (!found_item)
+ {
+ // you should never call this method with an item that isn't a child
+ // so we should always find something
+ llassert(FALSE);
+ return NULL;
+ }
+
+ // at this point, either iit or fit point to a candidate "next" item
+ // if both are out of range, we need to punt up to our parent
+
+ // now, starting from found folder, continue through folders
+ // searching for next visible folder
+ while(fit != fend && !(*fit)->getVisible())
+ {
+ // turn on downwards traversal for next folder
+ ++fit;
+ }
+
+ if (fit != fend)
+ {
+ result = (*fit);
+ }
+ else
+ {
+ // otherwise, scan for next visible item
+ while(iit != iend && !(*iit)->getVisible())
+ {
+ ++iit;
+ }
+
+ // check to see if we have a valid item
+ if (iit != iend)
+ {
+ result = (*iit);
+ }
+ }
+
+ if( !result && mParentFolder )
+ {
+ // If there are no siblings or children to go to, recurse up one level in the tree
+ // and skip children for this folder, as we've already discounted them
+ result = mParentFolder->getNextFromChild(this, FALSE);
+ }
+
+ return result;
+}
+
+// this does postfix traversal, as folders are listed above their contents
+LLFolderViewItem* LLFolderViewFolder::getPreviousFromChild( LLFolderViewItem* item, BOOL include_children )
+{
+ BOOL found_item = FALSE;
+
+ LLFolderViewItem* result = NULL;
+ // when not starting from a given item, start at end
+ if(item == NULL)
+ {
+ found_item = TRUE;
+ }
+
+ // find current item among children
+ folders_t::reverse_iterator fit = mFolders.rbegin();
+ folders_t::reverse_iterator fend = mFolders.rend();
+
+ items_t::reverse_iterator iit = mItems.rbegin();
+ items_t::reverse_iterator iend = mItems.rend();
+
+ // if not trivially starting at the end, we have to find the current item
+ if (!found_item)
+ {
+ // first, look among items, since they are always below the folders
+ for(; iit != iend; ++iit)
+ {
+ if(item == (*iit))
+ {
+ found_item = TRUE;
+ // point to next item
+ ++iit;
+ break;
+ }
+ }
+
+ // didn't find in items? Check folders...
+ if (!found_item)
+ {
+ for(; fit != fend; ++fit)
+ {
+ if(item == (*fit))
+ {
+ found_item = TRUE;
+ // point to next folder
+ ++fit;
+ break;
+ }
+ }
+ }
+ }
+
+ if (!found_item)
+ {
+ // you should never call this method with an item that isn't a child
+ // so we should always find something
+ llassert(FALSE);
+ return NULL;
+ }
+
+ // at this point, either iit or fit point to a candidate "next" item
+ // if both are out of range, we need to punt up to our parent
+
+ // now, starting from found item, continue through items
+ // searching for next visible item
+ while(iit != iend && !(*iit)->getVisible())
+ {
+ ++iit;
+ }
+
+ if (iit != iend)
+ {
+ // we found an appropriate item
+ result = (*iit);
+ }
+ else
+ {
+ // otherwise, scan for next visible folder
+ while(fit != fend && !(*fit)->getVisible())
+ {
+ ++fit;
+ }
+
+ // check to see if we have a valid folder
+ if (fit != fend)
+ {
+ // try selecting child element of this folder
+ if ((*fit)->isOpen())
+ {
+ result = (*fit)->getPreviousFromChild(NULL);
+ }
+ else
+ {
+ result = (*fit);
+ }
+ }
+ }
+
+ if( !result )
+ {
+ // If there are no siblings or children to go to, recurse up one level in the tree
+ // which gets back to this folder, which will only be visited if it is a valid, visible item
+ result = this;
+ }
+
+ return result;
+}
+
+
+bool LLInventorySort::updateSort(U32 order)
+{
+ if (order != mSortOrder)
+ {
+ mSortOrder = order;
+ mByDate = (order & LLInventoryFilter::SO_DATE);
+ mSystemToTop = (order & LLInventoryFilter::SO_SYSTEM_FOLDERS_TO_TOP);
+ mFoldersByName = (order & LLInventoryFilter::SO_FOLDERS_BY_NAME);
+ return true;
+ }
+ return false;
+}
+
+bool LLInventorySort::operator()(const LLFolderViewItem* const& a, const LLFolderViewItem* const& b)
+{
+ // We sort by name if we aren't sorting by date
+ // OR if these are folders and we are sorting folders by name.
+ bool by_name = (!mByDate
+ || (mFoldersByName
+ && (a->getSortGroup() != SG_ITEM)));
+
+ if (a->getSortGroup() != b->getSortGroup())
+ {
+ if (mSystemToTop)
+ {
+ // Group order is System Folders, Trash, Normal Folders, Items
+ return (a->getSortGroup() < b->getSortGroup());
+ }
+ else if (mByDate)
+ {
+ // Trash needs to go to the bottom if we are sorting by date
+ if ( (a->getSortGroup() == SG_TRASH_FOLDER)
+ || (b->getSortGroup() == SG_TRASH_FOLDER))
+ {
+ return (b->getSortGroup() == SG_TRASH_FOLDER);
+ }
+ }
+ }
+
+ if (by_name)
+ {
+ S32 compare = LLStringUtil::compareDict(a->getLabel(), b->getLabel());
+ if (0 == compare)
+ {
+ return (a->getCreationDate() > b->getCreationDate());
+ }
+ else
+ {
+ return (compare < 0);
+ }
+ }
+ else
+ {
+ // BUG: This is very very slow. The getCreationDate() is log n in number
+ // of inventory items.
+ time_t first_create = a->getCreationDate();
+ time_t second_create = b->getCreationDate();
+ if (first_create == second_create)
+ {
+ return (LLStringUtil::compareDict(a->getLabel(), b->getLabel()) < 0);
+ }
+ else
+ {
+ return (first_create > second_create);
+ }
+ }
+}
diff --git a/indra/newview/llfolderviewitem.h b/indra/newview/llfolderviewitem.h
new file mode 100644
index 0000000000..31866c83c8
--- /dev/null
+++ b/indra/newview/llfolderviewitem.h
@@ -0,0 +1,528 @@
+/**
+* @file llfolderviewitem.h
+* @brief Items and folders that can appear in a hierarchical folder view
+*
+* $LicenseInfo:firstyear=2001&license=viewergpl$
+*
+* Copyright (c) 2001-2009, Linden Research, Inc.
+*
+* Second Life Viewer Source Code
+* The source code in this file ("Source Code") is provided by Linden Lab
+* to you under the terms of the GNU General Public License, version 2.0
+* ("GPL"), unless you have obtained a separate licensing agreement
+* ("Other License"), formally executed by you and Linden Lab. Terms of
+* the GPL can be found in doc/GPL-license.txt in this distribution, or
+* online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
+*
+* There are special exceptions to the terms and conditions of the GPL as
+* it is applied to this Source Code. View the full text of the exception
+* in the file doc/FLOSS-exception.txt in this software distribution, or
+* online at
+* http://secondlifegrid.net/programs/open_source/licensing/flossexception
+*
+* By copying, modifying or distributing this software, you acknowledge
+* that you have read and understood your obligations described above,
+* and agree to abide by those obligations.
+*
+* ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+* COMPLETENESS OR PERFORMANCE.
+* $/LicenseInfo$
+*/
+#ifndef LLFOLDERVIEWITEM_H
+#define LLFOLDERVIEWITEM_H
+
+#include "llview.h"
+
+class LLFontGL;
+class LLFolderView;
+class LLFolderViewEventListener;
+class LLFolderViewFolder;
+class LLFolderViewFunctor;
+class LLFolderViewItem;
+class LLFolderViewListenerFunctor;
+class LLInventoryFilter;
+class LLMenuGL;
+class LLUIImage;
+
+// These are grouping of inventory types.
+// Order matters when sorting system folders to the top.
+enum EInventorySortGroup
+{
+ SG_SYSTEM_FOLDER,
+ SG_TRASH_FOLDER,
+ SG_NORMAL_FOLDER,
+ SG_ITEM
+};
+
+// JAMESDEBUG *TODO: do we really need one sort object per folder?
+// can we just have one of these per LLFolderView ?
+class LLInventorySort
+{
+public:
+ LLInventorySort()
+ : mSortOrder(0),
+ mByDate(false),
+ mSystemToTop(false),
+ mFoldersByName(false) { }
+
+ // Returns true if order has changed
+ bool updateSort(U32 order);
+ U32 getSort() { return mSortOrder; }
+
+ bool operator()(const LLFolderViewItem* const& a, const LLFolderViewItem* const& b);
+private:
+ U32 mSortOrder;
+ bool mByDate;
+ bool mSystemToTop;
+ bool mFoldersByName;
+};
+
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+// Class LLFolderViewItem
+//
+// An instance of this class represents a single item in a folder view
+// such as an inventory item or a file.
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+class LLFolderViewItem : public LLView
+{
+public:
+ static void initClass();
+ static void cleanupClass();
+
+ // jamesdebug was LLUICtrl::Params
+ struct Params : public LLInitParam::Block<Params, LLView::Params>
+ {
+ Optional<LLUIImage*> icon;
+ Optional<LLFolderView*> root;
+ Optional<LLFolderViewEventListener*> listener;
+
+ Optional<LLUIImage*> folder_arrow_image;
+ Optional<LLUIImage*> selection_image;
+
+ Optional<S32> creation_date; //UTC seconds
+
+ Params();
+ };
+
+ // layout constants
+ static const S32 LEFT_PAD = 5;
+ static const S32 LEFT_INDENTATION = 13;
+ static const S32 ICON_PAD = 2;
+ static const S32 ICON_WIDTH = 16;
+ static const S32 TEXT_PAD = 1;
+ static const S32 ARROW_SIZE = 12;
+ static const S32 MAX_FOLDER_ITEM_OVERLAP = 2;
+ // animation parameters
+ static const F32 FOLDER_CLOSE_TIME_CONSTANT;
+ static const F32 FOLDER_OPEN_TIME_CONSTANT;
+
+protected:
+ friend class LLUICtrlFactory;
+ friend class LLFolderViewEventListener;
+
+ LLFolderViewItem(Params p = LLFolderViewItem::Params());
+
+ static const LLFontGL* sFont;
+ static const LLFontGL* sSmallFont;
+ static LLUIImagePtr sArrowImage;
+ static LLUIImagePtr sBoxImage;
+
+ std::string mLabel;
+ std::string mSearchableLabel;
+ S32 mLabelWidth;
+ bool mLabelWidthDirty;
+ time_t mCreationDate;
+ LLFolderViewFolder* mParentFolder;
+ LLFolderViewEventListener* mListener;
+ BOOL mIsSelected;
+ BOOL mIsCurSelection;
+ BOOL mSelectPending;
+ LLFontGL::StyleFlags mLabelStyle;
+ std::string mLabelSuffix;
+ LLUIImagePtr mIcon;
+ std::string mStatusText;
+ BOOL mHasVisibleChildren;
+ S32 mIndentation;
+ S32 mNumDescendantsSelected;
+ BOOL mFiltered;
+ S32 mLastFilterGeneration;
+ std::string::size_type mStringMatchOffset;
+ F32 mControlLabelRotation;
+ LLFolderView* mRoot;
+ BOOL mDragAndDropTarget;
+ LLUIImagePtr mArrowImage;
+ LLUIImagePtr mBoxImage;
+ BOOL mIsLoading;
+ LLTimer mTimeSinceRequestStart;
+
+ // helper function to change the selection from the root.
+ void changeSelectionFromRoot(LLFolderViewItem* selection, BOOL selected);
+
+ // helper function to change the selection from the root.
+ void extendSelectionFromRoot(LLFolderViewItem* selection);
+
+ // this is an internal method used for adding items to folders. A
+ // no-op at this leve, but reimplemented in derived classes.
+ virtual BOOL addItem(LLFolderViewItem*) { return FALSE; }
+ virtual BOOL addFolder(LLFolderViewFolder*) { return FALSE; }
+
+public:
+ // This function clears the currently selected item, and records
+ // the specified selected item appropriately for display and use
+ // in the UI. If open is TRUE, then folders are opened up along
+ // the way to the selection.
+ void setSelectionFromRoot(LLFolderViewItem* selection, BOOL openitem,
+ BOOL take_keyboard_focus = TRUE);
+
+ // This function is called when the folder view is dirty. It's
+ // implemented here but called by derived classes when folding the
+ // views.
+ void arrangeFromRoot();
+ void filterFromRoot( void );
+
+ void arrangeAndSet(BOOL set_selection, BOOL take_keyboard_focus);
+
+ virtual ~LLFolderViewItem( void );
+
+ // addToFolder() returns TRUE if it succeeds. FALSE otherwise
+ enum { ARRANGE = TRUE, DO_NOT_ARRANGE = FALSE };
+ virtual BOOL addToFolder(LLFolderViewFolder* folder, LLFolderView* root);
+
+ virtual EInventorySortGroup getSortGroup() const;
+
+ // Finds width and height of this object and it's children. Also
+ // makes sure that this view and it's children are the right size.
+ virtual S32 arrange( S32* width, S32* height, S32 filter_generation );
+ virtual S32 getItemHeight();
+
+ // applies filters to control visibility of inventory items
+ virtual void filter( LLInventoryFilter& filter);
+
+ // updates filter serial number and optionally propagated value up to root
+ S32 getLastFilterGeneration() { return mLastFilterGeneration; }
+
+ virtual void dirtyFilter();
+
+ // If the selection is 'this' then note that otherwise
+ // ignore. Returns TRUE if this object was affected. If open is
+ // TRUE, then folders are opened up along the way to the
+ // selection.
+ virtual BOOL setSelection(LLFolderViewItem* selection, BOOL openitem,
+ BOOL take_keyboard_focus);
+
+ // This method is used to toggle the selection of an item. If
+ // selection is 'this', then note selection, and return TRUE.
+ virtual BOOL changeSelection(LLFolderViewItem* selection, BOOL selected);
+
+ // this method is used to group select items
+ virtual S32 extendSelection(LLFolderViewItem* selection, LLFolderViewItem* last_selected, LLDynamicArray<LLFolderViewItem*>& items){ return FALSE; }
+
+ // this method is used to group select items
+ virtual void recursiveDeselect(BOOL deselect_self);
+
+ // gets multiple-element selection
+ virtual BOOL getSelectionList(std::set<LLUUID> &selection){return TRUE;}
+
+ // Returns true is this object and all of its children can be removed (deleted by user)
+ virtual BOOL isRemovable();
+
+ // Returns true is this object and all of its children can be moved
+ virtual BOOL isMovable();
+
+ // destroys this item recursively
+ virtual void destroyView();
+
+ S32 getNumSelectedDescendants() { return mNumDescendantsSelected; }
+
+ BOOL isSelected() { return mIsSelected; }
+
+ void setIsCurSelection(BOOL select) { mIsCurSelection = select; }
+
+ BOOL getIsCurSelection() { return mIsCurSelection; }
+
+ BOOL hasVisibleChildren() { return mHasVisibleChildren; }
+
+ // Call through to the viewed object and return true if it can be
+ // removed. Returns true if it's removed.
+ //virtual BOOL removeRecursively(BOOL single_item);
+ BOOL remove();
+
+ // Build an appropriate context menu for the item. Flags unused.
+ void buildContextMenu(LLMenuGL& menu, U32 flags);
+
+ // This method returns the actual name of the thing being
+ // viewed. This method will ask the viewed object itself.
+ const std::string& getName( void ) const;
+
+ const std::string& getSearchableLabel( void ) const;
+
+ // This method returns the label displayed on the view. This
+ // method was primarily added to allow sorting on the folder
+ // contents possible before the entire view has been constructed.
+ const std::string& getLabel() const { return mLabel; }
+
+ // Used for sorting, like getLabel() above.
+ virtual time_t getCreationDate() const { return mCreationDate; }
+
+ LLFolderViewFolder* getParentFolder( void ) { return mParentFolder; }
+ const LLFolderViewFolder* getParentFolder( void ) const { return mParentFolder; }
+
+ LLFolderViewItem* getNextOpenNode( BOOL include_children = TRUE );
+ LLFolderViewItem* getPreviousOpenNode( BOOL include_children = TRUE );
+
+ const LLFolderViewEventListener* getListener( void ) const { return mListener; }
+ LLFolderViewEventListener* getListener( void ) { return mListener; }
+
+ // just rename the object.
+ void rename(const std::string& new_name);
+
+ // open
+ virtual void openItem( void );
+ virtual void preview(void);
+
+ // Show children (unfortunate that this is called "open")
+ virtual void setOpen(BOOL open = TRUE) {};
+
+ virtual BOOL isOpen() { return FALSE; }
+
+ virtual LLFolderView* getRoot();
+ BOOL isDescendantOf( const LLFolderViewFolder* potential_ancestor );
+ S32 getIndentation() { return mIndentation; }
+
+ virtual BOOL potentiallyVisible(); // do we know for a fact that this item has been filtered out?
+
+ virtual BOOL getFiltered();
+ virtual BOOL getFiltered(S32 filter_generation);
+ virtual void setFiltered(BOOL filtered, S32 filter_generation);
+
+ // change the icon
+ void setIcon(LLUIImagePtr icon);
+
+ // refresh information from the object being viewed.
+ void refreshFromListener();
+ virtual void refresh();
+
+ virtual void applyListenerFunctorRecursively(LLFolderViewListenerFunctor& functor);
+
+ // LLView functionality
+ virtual BOOL handleRightMouseDown( S32 x, S32 y, MASK mask );
+ virtual BOOL handleMouseDown( S32 x, S32 y, MASK mask );
+ virtual BOOL handleHover( S32 x, S32 y, MASK mask );
+ virtual BOOL handleMouseUp( S32 x, S32 y, MASK mask );
+ virtual BOOL handleDoubleClick( S32 x, S32 y, MASK mask );
+ virtual BOOL handleScrollWheel(S32 x, S32 y, S32 clicks);
+
+ // virtual void handleDropped();
+ virtual void draw();
+ virtual BOOL handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop,
+ EDragAndDropType cargo_type,
+ void* cargo_data,
+ EAcceptance* accept,
+ std::string& tooltip_msg);
+};
+
+
+// function used for sorting.
+typedef bool (*sort_order_f)(LLFolderViewItem* a, LLFolderViewItem* b);
+
+
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+// Class LLFolderViewFolder
+//
+// An instance of an LLFolderViewFolder represents a collection of
+// more folders and items. This is used to build the hierarchy of
+// items found in the folder view. :)
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+class LLFolderViewFolder : public LLFolderViewItem
+{
+protected:
+ LLFolderViewFolder( const LLFolderViewItem::Params& );
+ friend class LLUICtrlFactory;
+
+public:
+ typedef enum e_trash
+ {
+ UNKNOWN, TRASH, NOT_TRASH
+ } ETrash;
+
+protected:
+ typedef std::list<LLFolderViewItem*> items_t;
+ typedef std::list<LLFolderViewFolder*> folders_t;
+ items_t mItems;
+ folders_t mFolders;
+ LLInventorySort mSortFunction;
+
+ BOOL mIsOpen;
+ BOOL mExpanderHighlighted;
+ F32 mCurHeight;
+ F32 mTargetHeight;
+ F32 mAutoOpenCountdown;
+ time_t mSubtreeCreationDate;
+ mutable ETrash mAmTrash;
+ S32 mLastArrangeGeneration;
+ S32 mLastCalculatedWidth;
+ S32 mCompletedFilterGeneration;
+ S32 mMostFilteredDescendantGeneration;
+ bool mNeedsSort;
+public:
+ typedef enum e_recurse_type
+ {
+ RECURSE_NO,
+ RECURSE_UP,
+ RECURSE_DOWN,
+ RECURSE_UP_DOWN
+ } ERecurseType;
+
+
+ virtual ~LLFolderViewFolder( void );
+
+ virtual BOOL potentiallyVisible();
+
+ LLFolderViewItem* getNextFromChild( LLFolderViewItem*, BOOL include_children = TRUE );
+ LLFolderViewItem* getPreviousFromChild( LLFolderViewItem*, BOOL include_children = TRUE );
+
+ // addToFolder() returns TRUE if it succeeds. FALSE otherwise
+ virtual BOOL addToFolder(LLFolderViewFolder* folder, LLFolderView* root);
+
+ // Finds width and height of this object and it's children. Also
+ // makes sure that this view and it's children are the right size.
+ virtual S32 arrange( S32* width, S32* height, S32 filter_generation );
+
+ BOOL needsArrange();
+ void requestSort();
+
+ // Returns the sort group (system, trash, folder) for this folder.
+ virtual EInventorySortGroup getSortGroup() const;
+
+ virtual void setCompletedFilterGeneration(S32 generation, BOOL recurse_up);
+ virtual S32 getCompletedFilterGeneration() { return mCompletedFilterGeneration; }
+
+ BOOL hasFilteredDescendants(S32 filter_generation) { return mMostFilteredDescendantGeneration >= filter_generation; }
+ BOOL hasFilteredDescendants();
+
+ // applies filters to control visibility of inventory items
+ virtual void filter( LLInventoryFilter& filter);
+ virtual void setFiltered(BOOL filtered, S32 filter_generation);
+ virtual void dirtyFilter();
+
+ // Passes selection information on to children and record
+ // selection information if necessary. Returns TRUE if this object
+ // (or a child) was affected.
+ virtual BOOL setSelection(LLFolderViewItem* selection, BOOL openitem,
+ BOOL take_keyboard_focus);
+
+ // This method is used to change the selection of an item. If
+ // selection is 'this', then note selection as true. Returns TRUE
+ // if this or a child is now selected.
+ virtual BOOL changeSelection(LLFolderViewItem* selection, BOOL selected);
+
+ // this method is used to group select items
+ virtual S32 extendSelection(LLFolderViewItem* selection, LLFolderViewItem* last_selected, LLDynamicArray<LLFolderViewItem*>& items);
+
+ virtual void recursiveDeselect(BOOL deselect_self);
+
+ // Returns true is this object and all of its children can be removed.
+ virtual BOOL isRemovable();
+
+ // Returns true is this object and all of its children can be moved
+ virtual BOOL isMovable();
+
+ // destroys this folder, and all children
+ virtual void destroyView();
+
+ // If this folder can be removed, remove all children that can be
+ // removed, return TRUE if this is empty after the operation and
+ // it's viewed folder object can be removed.
+ //virtual BOOL removeRecursively(BOOL single_item);
+ //virtual BOOL remove();
+
+ // remove the specified item (and any children) if
+ // possible. Return TRUE if the item was deleted.
+ BOOL removeItem(LLFolderViewItem* item);
+
+ // simply remove the view (and any children) Don't bother telling
+ // the listeners.
+ void removeView(LLFolderViewItem* item);
+
+ // extractItem() removes the specified item from the folder, but
+ // doesn't delete it.
+ void extractItem( LLFolderViewItem* item );
+
+ // This function is called by a child that needs to be resorted.
+ void resort(LLFolderViewItem* item);
+
+ void setItemSortOrder(U32 ordering);
+ void sortBy(U32);
+ //BOOL (*func)(LLFolderViewItem* a, LLFolderViewItem* b));
+
+ void setAutoOpenCountdown(F32 countdown) { mAutoOpenCountdown = countdown; }
+
+ // folders can be opened. This will usually be called by internal
+ // methods.
+ virtual void toggleOpen();
+
+ // Force a folder open or closed
+ virtual void setOpen(BOOL openitem = TRUE);
+
+ // Called when a child is refreshed.
+ // don't rearrange child folder contents unless explicitly requested
+ virtual void requestArrange(BOOL include_descendants = FALSE);
+
+ // internal method which doesn't update the entire view. This
+ // method was written because the list iterators destroy the state
+ // of other iterations, thus, we can't arrange while iterating
+ // through the children (such as when setting which is selected.
+ virtual void setOpenArrangeRecursively(BOOL openitem, ERecurseType recurse = RECURSE_NO);
+
+ // Get the current state of the folder.
+ virtual BOOL isOpen() { return mIsOpen; }
+
+ // special case if an object is dropped on the child.
+ BOOL handleDragAndDropFromChild(MASK mask,
+ BOOL drop,
+ EDragAndDropType cargo_type,
+ void* cargo_data,
+ EAcceptance* accept,
+ std::string& tooltip_msg);
+
+ void applyFunctorRecursively(LLFolderViewFunctor& functor);
+ virtual void applyListenerFunctorRecursively(LLFolderViewListenerFunctor& functor);
+
+ virtual void openItem( void );
+ virtual BOOL addItem(LLFolderViewItem* item);
+ virtual BOOL addFolder( LLFolderViewFolder* folder);
+
+ // LLView functionality
+ virtual BOOL handleHover(S32 x, S32 y, MASK mask);
+ virtual BOOL handleRightMouseDown( S32 x, S32 y, MASK mask );
+ virtual BOOL handleMouseDown( S32 x, S32 y, MASK mask );
+ virtual BOOL handleDoubleClick( S32 x, S32 y, MASK mask );
+ virtual BOOL handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop,
+ EDragAndDropType cargo_type,
+ void* cargo_data,
+ EAcceptance* accept,
+ std::string& tooltip_msg);
+ virtual void draw();
+
+ time_t getCreationDate() const;
+ bool isTrash() const;
+};
+
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+// Class LLFolderViewListenerFunctor
+//
+// This simple abstract base class can be used to applied to all
+// listeners in a hierarchy.
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+class LLFolderViewListenerFunctor
+{
+public:
+ virtual ~LLFolderViewListenerFunctor() {}
+ virtual void operator()(LLFolderViewEventListener* listener) = 0;
+};
+
+#endif // LLFOLDERVIEWITEM_H
diff --git a/indra/newview/llfriendcard.cpp b/indra/newview/llfriendcard.cpp
new file mode 100644
index 0000000000..bef5f094e3
--- /dev/null
+++ b/indra/newview/llfriendcard.cpp
@@ -0,0 +1,425 @@
+/**
+ * @file llfriendcard.cpp
+ * @brief Implementation of classes to process Friends Cards
+ *
+ * $LicenseInfo:firstyear=2002&license=viewergpl$
+ *
+ * Copyright (c) 2002-2009, Linden Research, Inc.
+ *
+ * Second Life Viewer Source Code
+ * The source code in this file ("Source Code") is provided by Linden Lab
+ * to you under the terms of the GNU General Public License, version 2.0
+ * ("GPL"), unless you have obtained a separate licensing agreement
+ * ("Other License"), formally executed by you and Linden Lab. Terms of
+ * the GPL can be found in doc/GPL-license.txt in this distribution, or
+ * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
+ *
+ * There are special exceptions to the terms and conditions of the GPL as
+ * it is applied to this Source Code. View the full text of the exception
+ * in the file doc/FLOSS-exception.txt in this software distribution, or
+ * online at
+ * http://secondlifegrid.net/programs/open_source/licensing/flossexception
+ *
+ * By copying, modifying or distributing this software, you acknowledge
+ * that you have read and understood your obligations described above,
+ * and agree to abide by those obligations.
+ *
+ * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+ * COMPLETENESS OR PERFORMANCE.
+ * $/LicenseInfo$
+ */
+
+#include "llviewerprecompiledheaders.h"
+
+#include "llinventory.h"
+#include "lltrans.h"
+
+#include "llfriendcard.h"
+
+#include "llcallingcard.h" // for LLAvatarTracker
+#include "llviewerinventory.h"
+#include "llinventorymodel.h"
+
+// Constants;
+
+static const std::string INVENTORY_STRING_FRIENDS_SUBFOLDER = "Friends";
+static const std::string INVENTORY_STRING_FRIENDS_ALL_SUBFOLDER = "All";
+
+// helper functions
+
+/*
+mantipov *NOTE: unable to use
+LLTrans::getString("InvFolder Friends"); or
+LLTrans::getString("InvFolder FriendsAll");
+in next two functions to set localized folders' names because of there is a hack in the
+LLFolderViewItem::refreshFromListener() method for protected asset types.
+So, localized names will be got from the strings with "InvFolder LABEL_NAME" in the strings.xml
+*/
+inline const std::string& get_friend_folder_name()
+{
+ return INVENTORY_STRING_FRIENDS_SUBFOLDER;
+}
+
+inline const std::string& get_friend_all_subfolder_name()
+{
+ return INVENTORY_STRING_FRIENDS_ALL_SUBFOLDER;
+}
+
+void move_from_to_arrays(LLInventoryModel::cat_array_t& from, LLInventoryModel::cat_array_t& to)
+{
+ while (from.count() > 0)
+ {
+ to.put(from.get(0));
+ from.remove(0);
+ }
+}
+
+const LLUUID& get_folder_uuid(const LLUUID& parentFolderUUID, LLInventoryCollectFunctor& matchFunctor)
+{
+ LLInventoryModel::cat_array_t cats;
+ LLInventoryModel::item_array_t items;
+
+ gInventory.collectDescendentsIf(parentFolderUUID, cats, items,
+ LLInventoryModel::EXCLUDE_TRASH, matchFunctor);
+
+ if (cats.count() == 1)
+ {
+ return cats.get(0)->getUUID();
+ }
+
+ return LLUUID::null;
+}
+
+// LLFriendCardsManager Constructor / Destructor
+LLFriendCardsManager::LLFriendCardsManager()
+{
+ LLAvatarTracker::instance().addObserver(this);
+}
+
+LLFriendCardsManager::~LLFriendCardsManager()
+{
+ LLAvatarTracker::instance().removeObserver(this);
+}
+
+void LLFriendCardsManager::putAvatarData(const LLUUID& avatarID)
+{
+ llinfos << "Store avatar data, avatarID: " << avatarID << llendl;
+ std::pair< avatar_uuid_set_t::iterator, bool > pr;
+ pr = mBuddyIDSet.insert(avatarID);
+ if (pr.second == false)
+ {
+ llwarns << "Trying to add avatar UUID for the stored avatar: "
+ << avatarID
+ << llendl;
+ }
+}
+
+const LLUUID LLFriendCardsManager::extractAvatarID(const LLUUID& avatarID)
+{
+ LLUUID rv;
+ avatar_uuid_set_t::iterator it = mBuddyIDSet.find(avatarID);
+ if (mBuddyIDSet.end() == it)
+ {
+ llwarns << "Call method for non-existent avatar name in the map: " << avatarID << llendl;
+ }
+ else
+ {
+ rv = (*it);
+ mBuddyIDSet.erase(it);
+ }
+ return rv;
+}
+
+// be sure LLInventoryModel::buildParentChildMap() has been called before it.
+// and this method must be called before any actions with friend list
+void LLFriendCardsManager::ensureFriendFoldersExist()
+{
+ LLUUID callingCardsFolderID = gInventory.findCategoryUUIDForType(LLAssetType::AT_CALLINGCARD);
+
+ LLUUID friendFolderUUID = findFriendFolderUUIDImpl();
+
+ if (friendFolderUUID.isNull())
+ {
+ friendFolderUUID = gInventory.createNewCategory(callingCardsFolderID,
+ LLAssetType::AT_CALLINGCARD, get_friend_folder_name());
+ }
+
+ LLUUID friendAllSubfolderUUID = findFriendAllSubfolderUUIDImpl();
+
+ if (friendAllSubfolderUUID.isNull())
+ {
+ friendAllSubfolderUUID = gInventory.createNewCategory(friendFolderUUID,
+ LLAssetType::AT_CALLINGCARD, get_friend_all_subfolder_name());
+ }
+}
+
+
+bool LLFriendCardsManager::isItemInAnyFriendsList(const LLViewerInventoryItem* item)
+{
+ if (item->getType() != LLAssetType::AT_CALLINGCARD)
+ return false;
+
+ LLInventoryModel::item_array_t items;
+ findMatchedFriendCards(item->getCreatorUUID(), items);
+
+ return items.count() > 0;
+}
+
+bool LLFriendCardsManager::isCategoryInFriendFolder(const LLViewerInventoryCategory* cat) const
+{
+ if (NULL == cat)
+ return false;
+ return TRUE == gInventory.isObjectDescendentOf(cat->getUUID(), findFriendFolderUUIDImpl());
+}
+
+void LLFriendCardsManager::syncFriendsFolder()
+{
+ //lets create "Friends" and "Friends/All" in the Inventory "Calling Cards" if they are absent
+ LLFriendCardsManager::instance().ensureFriendFoldersExist();
+
+ LLAvatarTracker::buddy_map_t all_buddies;
+ LLAvatarTracker::instance().copyBuddyList(all_buddies);
+
+ // 1. Remove Friend Cards for non-friends
+ LLInventoryModel::cat_array_t cats;
+ LLInventoryModel::item_array_t items;
+
+ gInventory.collectDescendents(findFriendAllSubfolderUUIDImpl(), cats, items, LLInventoryModel::EXCLUDE_TRASH);
+
+ LLInventoryModel::item_array_t::const_iterator it;
+ for (it = items.begin(); it != items.end(); ++it)
+ {
+ lldebugs << "Check if buddy is in list: " << (*it)->getName() << " " << (*it)->getCreatorUUID() << llendl;
+ if (NULL == get_ptr_in_map(all_buddies, (*it)->getCreatorUUID()))
+ {
+ lldebugs << "NONEXISTS, so remove it" << llendl;
+ removeFriendCardFromInventory((*it)->getCreatorUUID());
+ }
+ }
+
+ // 2. Add missing Friend Cards for friends
+ LLAvatarTracker::buddy_map_t::const_iterator buddy_it = all_buddies.begin();
+ llinfos << "try to build friends, count: " << all_buddies.size() << llendl;
+ for(; buddy_it != all_buddies.end(); ++buddy_it)
+ {
+ const LLUUID& buddy_id = (*buddy_it).first;
+ addFriendCardToInventory(buddy_id);
+ }
+}
+
+void LLFriendCardsManager::collectFriendsLists(folderid_buddies_map_t& folderBuddiesMap) const
+{
+ folderBuddiesMap.clear();
+
+ LLInventoryModel::cat_array_t* listFolders;
+ LLInventoryModel::item_array_t* items;
+
+ // get folders in the Friend folder. Items should be NULL due to Cards should be in lists.
+ gInventory.getDirectDescendentsOf(findFriendFolderUUIDImpl(), listFolders, items);
+
+ if (NULL == listFolders)
+ return;
+
+ LLInventoryModel::cat_array_t::const_iterator itCats; // to iterate Friend Lists (categories)
+ LLInventoryModel::item_array_t::const_iterator itBuddy; // to iterate Buddies in each List
+ LLInventoryModel::cat_array_t* fakeCatsArg;
+ for (itCats = listFolders->begin(); itCats != listFolders->end(); ++itCats)
+ {
+ if (items)
+ items->clear();
+
+ // *HACK: Only Friends/All content will be shown for now
+ // *TODO: Remove this hack, implement sorting if it will be needded by spec.
+ if ((*itCats)->getUUID() != findFriendAllSubfolderUUIDImpl())
+ continue;
+
+ gInventory.getDirectDescendentsOf((*itCats)->getUUID(), fakeCatsArg, items);
+
+ if (NULL == items)
+ continue;
+
+ std::vector<LLUUID> buddyUUIDs;
+ for (itBuddy = items->begin(); itBuddy != items->end(); ++itBuddy)
+ {
+ buddyUUIDs.push_back((*itBuddy)->getCreatorUUID());
+ }
+
+ folderBuddiesMap.insert(make_pair((*itCats)->getUUID(), buddyUUIDs));
+ }
+}
+
+
+/************************************************************************/
+/* Private Methods */
+/************************************************************************/
+const LLUUID& LLFriendCardsManager::findFriendFolderUUIDImpl() const
+{
+ LLUUID callingCardsFolderID = gInventory.findCategoryUUIDForType(LLAssetType::AT_CALLINGCARD);
+
+ std::string friendFolderName = get_friend_folder_name();
+
+ return findChildFolderUUID(callingCardsFolderID, friendFolderName);
+}
+
+const LLUUID& LLFriendCardsManager::findFriendAllSubfolderUUIDImpl() const
+{
+ LLUUID friendFolderUUID = findFriendFolderUUIDImpl();
+
+ std::string friendAllSubfolderName = get_friend_all_subfolder_name();
+
+ return findChildFolderUUID(friendFolderUUID, friendAllSubfolderName);
+}
+
+const LLUUID& LLFriendCardsManager::findChildFolderUUID(const LLUUID& parentFolderUUID, const std::string& folderLabel) const
+{
+ // mantipov *HACK: get localaized name in the same way like in the LLFolderViewItem::refreshFromListener() method.
+ // be sure these both methods are synchronized.
+ // see also get_friend_folder_name() and get_friend_all_subfolder_name() functions
+ std::string localizedName = LLTrans::getString("InvFolder " + folderLabel);
+
+ LLNameCategoryCollector matchFolderFunctor(localizedName);
+
+ return get_folder_uuid(parentFolderUUID, matchFolderFunctor);
+}
+const LLUUID& LLFriendCardsManager::findFriendCardInventoryUUIDImpl(const LLUUID& avatarID)
+{
+ LLUUID friendAllSubfolderUUID = findFriendAllSubfolderUUIDImpl();
+ LLInventoryModel::cat_array_t cats;
+ LLInventoryModel::item_array_t items;
+ LLInventoryModel::item_array_t::const_iterator it;
+
+ // it is not necessary to check friendAllSubfolderUUID against NULL. It will be processed by collectDescendents
+ gInventory.collectDescendents(friendAllSubfolderUUID, cats, items, LLInventoryModel::EXCLUDE_TRASH);
+ for (it = items.begin(); it != items.end(); ++it)
+ {
+ if ((*it)->getCreatorUUID() == avatarID)
+ return (*it)->getUUID();
+ }
+
+ return LLUUID::null;
+}
+
+void LLFriendCardsManager::findMatchedFriendCards(const LLUUID& avatarID, LLInventoryModel::item_array_t& items) const
+{
+ LLInventoryModel::cat_array_t cats;
+ LLUUID friendFolderUUID = findFriendFolderUUIDImpl();
+
+ LLParticularBuddyCollector matchFunctor(avatarID);
+
+ LLViewerInventoryCategory* friendFolder = gInventory.getCategory(friendFolderUUID);
+
+ LLInventoryModel::cat_array_t subFolders;
+ subFolders.push_back(friendFolder);
+
+ while (subFolders.count() > 0)
+ {
+ LLViewerInventoryCategory* cat = subFolders.get(0);
+ subFolders.remove(0);
+
+ gInventory.collectDescendentsIf(cat->getUUID(), cats, items,
+ LLInventoryModel::EXCLUDE_TRASH, matchFunctor);
+
+ move_from_to_arrays(cats, subFolders);
+ }
+}
+
+class CreateFriendCardCallback : public LLInventoryCallback
+{
+public:
+ void fire(const LLUUID& inv_item_id)
+ {
+ LLViewerInventoryItem* item = gInventory.getItem(inv_item_id);
+
+ if (item)
+ LLFriendCardsManager::instance().extractAvatarID(item->getCreatorUUID());
+ }
+};
+
+bool LLFriendCardsManager::addFriendCardToInventory(const LLUUID& avatarID)
+{
+ LLInventoryModel* invModel = &gInventory;
+
+ bool shouldBeAdded = true;
+ std::string name;
+ gCacheName->getFullName(avatarID, name);
+
+ lldebugs << "Processing buddy name: " << name
+ << ", id: " << avatarID
+ << llendl;
+
+ if (shouldBeAdded && findFriendCardInventoryUUIDImpl(avatarID).notNull())
+ {
+ shouldBeAdded = false;
+ lldebugs << "is found in Inventory: " << name << llendl;
+ }
+
+ if (shouldBeAdded && isAvatarDataStored(avatarID))
+ {
+ shouldBeAdded = false;
+ lldebugs << "is found in sentRequests: " << name << llendl;
+ }
+
+ LLUUID friendListFolderID = findFriendAllSubfolderUUIDImpl();
+ if (shouldBeAdded && !invModel->isCategoryComplete(friendListFolderID))
+ {
+ shouldBeAdded = false;
+ }
+ if (shouldBeAdded)
+ {
+ putAvatarData(avatarID);
+ lldebugs << "Sent create_inventory_item for " << avatarID << ", " << name << llendl;
+
+ // TODO: mantipov: Is CreateFriendCardCallback really needed? Probably not
+ LLPointer<LLInventoryCallback> cb = new CreateFriendCardCallback();
+
+ create_inventory_callingcard(avatarID, friendListFolderID, cb);
+ }
+
+ return shouldBeAdded;
+}
+
+void LLFriendCardsManager::removeFriendCardFromInventory(const LLUUID& avatarID)
+{
+ LLInventoryModel::item_array_t items;
+ findMatchedFriendCards(avatarID, items);
+
+ LLInventoryModel::item_array_t::const_iterator it;
+ for (it = items.begin(); it != items.end(); ++ it)
+ {
+ gInventory.removeItem((*it)->getUUID());
+ }
+}
+
+void LLFriendCardsManager::onFriendListUpdate(U32 changed_mask)
+{
+ LLAvatarTracker& at = LLAvatarTracker::instance();
+
+ switch(changed_mask) {
+ case LLFriendObserver::ADD:
+ {
+ const std::set<LLUUID>& changed_items = at.getChangedIDs();
+ std::set<LLUUID>::const_iterator id_it = changed_items.begin();
+ std::set<LLUUID>::const_iterator id_end = changed_items.end();
+ for (;id_it != id_end; ++id_it)
+ {
+ LLFriendCardsManager::instance().addFriendCardToInventory(*id_it);
+ }
+ }
+ break;
+ case LLFriendObserver::REMOVE:
+ {
+ const std::set<LLUUID>& changed_items = at.getChangedIDs();
+ std::set<LLUUID>::const_iterator id_it = changed_items.begin();
+ std::set<LLUUID>::const_iterator id_end = changed_items.end();
+ for (;id_it != id_end; ++id_it)
+ {
+ LLFriendCardsManager::instance().removeFriendCardFromInventory(*id_it);
+ }
+ }
+
+ default:;
+ }
+}
+
+// EOF
diff --git a/indra/newview/llfriendcard.h b/indra/newview/llfriendcard.h
new file mode 100644
index 0000000000..18a6d0ab69
--- /dev/null
+++ b/indra/newview/llfriendcard.h
@@ -0,0 +1,143 @@
+/**
+ * @file llfriendcard.h
+ * @brief Definition of classes to process Friends Cards
+ *
+ * $LicenseInfo:firstyear=2002&license=viewergpl$
+ *
+ * Copyright (c) 2002-2009, Linden Research, Inc.
+ *
+ * Second Life Viewer Source Code
+ * The source code in this file ("Source Code") is provided by Linden Lab
+ * to you under the terms of the GNU General Public License, version 2.0
+ * ("GPL"), unless you have obtained a separate licensing agreement
+ * ("Other License"), formally executed by you and Linden Lab. Terms of
+ * the GPL can be found in doc/GPL-license.txt in this distribution, or
+ * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
+ *
+ * There are special exceptions to the terms and conditions of the GPL as
+ * it is applied to this Source Code. View the full text of the exception
+ * in the file doc/FLOSS-exception.txt in this software distribution, or
+ * online at
+ * http://secondlifegrid.net/programs/open_source/licensing/flossexception
+ *
+ * By copying, modifying or distributing this software, you acknowledge
+ * that you have read and understood your obligations described above,
+ * and agree to abide by those obligations.
+ *
+ * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+ * COMPLETENESS OR PERFORMANCE.
+ * $/LicenseInfo$
+ */
+
+#ifndef LL_LLFRIENDCARD_H
+#define LL_LLFRIENDCARD_H
+
+
+#include "llcallingcard.h"
+#include "llinventorymodel.h" // for LLInventoryModel::item_array_t
+
+class LLViewerInventoryItem;
+
+class LLFriendCardsManager
+ : public LLSingleton<LLFriendCardsManager>
+ , public LLFriendObserver
+{
+ LOG_CLASS(LLFriendCardsManager);
+
+ friend class LLSingleton<LLFriendCardsManager>;
+ friend class CreateFriendCardCallback;
+
+public:
+ typedef std::map<LLUUID, std::vector<LLUUID> > folderid_buddies_map_t;
+
+ // LLFriendObserver implementation
+ void changed(U32 mask)
+ {
+ onFriendListUpdate(mask);
+ }
+
+ /**
+ * Ensures that all necessary folders are created in Inventory.
+ *
+ * For now it processes Calling Card, Calling Card/Friends & Calling Card/Friends/All folders
+ */
+ void ensureFriendFoldersExist();
+
+
+ /**
+ * Determines if specified Inventory Calling Card exists in any of lists
+ * in the Calling Card/Friends/ folder (Default, or Custom)
+ */
+ bool isItemInAnyFriendsList(const LLViewerInventoryItem* item);
+
+ /**
+ * Checks is the specified category is in the Calling Card/Friends folder
+ */
+ bool isCategoryInFriendFolder(const LLViewerInventoryCategory* cat) const;
+
+ /**
+ * Synchronizes content of the Calling Card/Friends/All Global Inventory folder with Agent's Friend List
+ */
+ void syncFriendsFolder();
+
+ /*!
+ * \brief
+ * Collects folders' IDs with the buddies' IDs in the Inventory Calling Card/Friends folder.
+ *
+ * \param folderBuddiesMap
+ * map into collected data will be put. It will be cleared before adding new data.
+ *
+ * Each item in the out map is a pair where first is an LLViewerInventoryCategory UUID,
+ * second is a vector with UUID of Avatars from this folder.
+ *
+ */
+ void collectFriendsLists(folderid_buddies_map_t& folderBuddiesMap) const;
+
+private:
+ LLFriendCardsManager();
+ ~LLFriendCardsManager();
+
+
+ /**
+ * Stores buddy id to avoid sent create_inventory_callingcard several time for the same Avatar
+ */
+ void putAvatarData(const LLUUID& avatarID);
+
+ /**
+ * Extracts buddy id of Created Friend Card
+ */
+ const LLUUID extractAvatarID(const LLUUID& avatarID);
+
+ bool isAvatarDataStored(const LLUUID& avatarID) const
+ {
+ return (mBuddyIDSet.end() != mBuddyIDSet.find(avatarID));
+ }
+
+ const LLUUID& findChildFolderUUID(const LLUUID& parentFolderUUID, const std::string& folderLabel) const;
+ const LLUUID& findFriendFolderUUIDImpl() const;
+ const LLUUID& findFriendAllSubfolderUUIDImpl() const;
+ const LLUUID& findFriendCardInventoryUUIDImpl(const LLUUID& avatarID);
+ void findMatchedFriendCards(const LLUUID& avatarID, LLInventoryModel::item_array_t& items) const;
+
+ /**
+ * Adds avatar specified by its UUID into the Calling Card/Friends/All Global Inventory folder
+ */
+ bool addFriendCardToInventory(const LLUUID& avatarID);
+
+ /**
+ * Removes an avatar specified by its UUID from the Calling Card/Friends/All Global Inventory folder
+ * and from the all Custom Folders
+ */
+ void removeFriendCardFromInventory(const LLUUID& avatarID);
+
+ void onFriendListUpdate(U32 changed_mask);
+
+
+private:
+ typedef std::set<LLUUID> avatar_uuid_set_t;
+
+ avatar_uuid_set_t mBuddyIDSet;
+};
+
+#endif // LL_LLFRIENDCARD_H
diff --git a/indra/newview/llgesturemgr.cpp b/indra/newview/llgesturemgr.cpp
index 2dbff92ba0..59274c8638 100644
--- a/indra/newview/llgesturemgr.cpp
+++ b/indra/newview/llgesturemgr.cpp
@@ -50,15 +50,13 @@
// newview
#include "llagent.h"
-#include "llchatbar.h"
#include "lldelayedgestureerror.h"
#include "llinventorymodel.h"
#include "llnotify.h"
#include "llviewermessage.h"
-#include "llvoavatar.h"
+#include "llvoavatarself.h"
#include "llviewerstats.h"
-
-LLGestureManager gGestureManager;
+#include "llnearbychatbar.h"
// Longest time, in seconds, to wait for all animations to stop playing
const F32 MAX_WAIT_ANIM_SECS = 30.f;
@@ -71,7 +69,9 @@ LLGestureManager::LLGestureManager()
mPlaying(),
mActive(),
mLoadingCount(0)
-{ }
+{
+ gInventory.addObserver(this);
+}
// We own the data for gestures, so clean them up.
@@ -85,6 +85,7 @@ LLGestureManager::~LLGestureManager()
delete gesture;
gesture = NULL;
}
+ gInventory.removeObserver(this);
}
@@ -442,7 +443,7 @@ void LLGestureManager::replaceGesture(const LLUUID& item_id, LLMultiGesture* new
void LLGestureManager::replaceGesture(const LLUUID& item_id, const LLUUID& new_asset_id)
{
- item_map_t::iterator it = gGestureManager.mActive.find(item_id);
+ item_map_t::iterator it = LLGestureManager::instance().mActive.find(item_id);
if (it == mActive.end())
{
llwarns << "replaceGesture for inactive gesture " << item_id << llendl;
@@ -451,7 +452,7 @@ void LLGestureManager::replaceGesture(const LLUUID& item_id, const LLUUID& new_a
// mActive owns this gesture pointer, so clean up memory.
LLMultiGesture* gesture = (*it).second;
- gGestureManager.replaceGesture(item_id, gesture, new_asset_id);
+ LLGestureManager::instance().replaceGesture(item_id, gesture, new_asset_id);
}
void LLGestureManager::playGesture(LLMultiGesture* gesture)
@@ -868,9 +869,11 @@ void LLGestureManager::runStep(LLMultiGesture* gesture, LLGestureStep* step)
std::string chat_text = chat_step->mChatText;
// Don't animate the nodding, as this might not blend with
// other playing animations.
+
const BOOL animate = FALSE;
- gChatBar->sendChatFromViewer(chat_text, CHAT_TYPE_NORMAL, animate);
+ LLNearbyChatBar::getInstance()->sendChatFromViewer(chat_text, CHAT_TYPE_NORMAL, animate);
+
gesture->mCurrentStep++;
break;
}
@@ -919,7 +922,7 @@ void LLGestureManager::onLoadComplete(LLVFS *vfs,
delete info;
info = NULL;
- gGestureManager.mLoadingCount--;
+ LLGestureManager::instance().mLoadingCount--;
if (0 == status)
{
@@ -941,22 +944,34 @@ void LLGestureManager::onLoadComplete(LLVFS *vfs,
{
if (deactivate_similar)
{
- gGestureManager.deactivateSimilarGestures(gesture, item_id);
+ LLGestureManager::instance().deactivateSimilarGestures(gesture, item_id);
// Display deactivation message if this was the last of the bunch.
- if (gGestureManager.mLoadingCount == 0
- && gGestureManager.mDeactivateSimilarNames.length() > 0)
+ if (LLGestureManager::instance().mLoadingCount == 0
+ && LLGestureManager::instance().mDeactivateSimilarNames.length() > 0)
{
// we're done with this set of deactivations
LLSD args;
- args["NAMES"] = gGestureManager.mDeactivateSimilarNames;
+ args["NAMES"] = LLGestureManager::instance().mDeactivateSimilarNames;
LLNotifications::instance().add("DeactivatedGesturesTrigger", args);
}
}
+ LLViewerInventoryItem* item = gInventory.getItem(item_id);
+ if(item)
+ {
+ gesture->mName = item->getName();
+ }
+ else
+ {
+ // Watch this item and set gesture name when item exists in inventory
+ LLGestureManager::instance().watchItem(item_id);
+ }
+ LLGestureManager::instance().mActive[item_id] = gesture;
+
// Everything has been successful. Add to the active list.
- gGestureManager.mActive[item_id] = gesture;
gInventory.addChangedMask(LLInventoryObserver::LABEL, item_id);
+
if (inform_server)
{
// Inform the database of this change
@@ -975,13 +990,13 @@ void LLGestureManager::onLoadComplete(LLVFS *vfs,
gAgent.sendReliableMessage();
}
- gGestureManager.notifyObservers();
+ LLGestureManager::instance().notifyObservers();
}
else
{
llwarns << "Unable to load gesture" << llendl;
- gGestureManager.mActive.erase(item_id);
+ LLGestureManager::instance().mActive.erase(item_id);
delete gesture;
gesture = NULL;
@@ -1003,7 +1018,7 @@ void LLGestureManager::onLoadComplete(LLVFS *vfs,
llwarns << "Problem loading gesture: " << status << llendl;
- gGestureManager.mActive.erase(item_id);
+ LLGestureManager::instance().mActive.erase(item_id);
}
}
@@ -1131,3 +1146,19 @@ void LLGestureManager::getItemIDs(std::vector<LLUUID>* ids)
ids->push_back(it->first);
}
}
+
+void LLGestureManager::done()
+{
+ for(item_map_t::iterator it = mActive.begin(); it != mActive.end(); ++it)
+ {
+ if(it->second && it->second->mName.empty())
+ {
+ LLViewerInventoryItem* item = gInventory.getItem(it->first);
+ if(item)
+ {
+ it->second->mName = item->getName();
+ }
+ }
+ }
+ notifyObservers();
+}
diff --git a/indra/newview/llgesturemgr.h b/indra/newview/llgesturemgr.h
index f564c17486..947773d66d 100644
--- a/indra/newview/llgesturemgr.h
+++ b/indra/newview/llgesturemgr.h
@@ -38,6 +38,8 @@
#include <vector>
#include "llassetstorage.h" // LLAssetType
+#include "llinventorymodel.h"
+#include "llsingleton.h"
#include "llviewerinventory.h"
class LLMultiGesture;
@@ -52,7 +54,7 @@ public:
virtual void changed() = 0;
};
-class LLGestureManager
+class LLGestureManager : public LLSingleton<LLGestureManager>, public LLInventoryCompletionObserver
{
public:
LLGestureManager();
@@ -133,6 +135,9 @@ protected:
// Do a single step in a gesture
void runStep(LLMultiGesture* gesture, LLGestureStep* step);
+ // LLInventoryCompletionObserver trigger
+ void done();
+
// Used by loadGesture
static void onLoadComplete(LLVFS *vfs,
const LLUUID& asset_uuid,
@@ -158,6 +163,4 @@ public:
std::vector<LLGestureManagerObserver*> mObservers;
};
-extern LLGestureManager gGestureManager;
-
#endif
diff --git a/indra/newview/llglsandbox.cpp b/indra/newview/llglsandbox.cpp
index 91beb801ad..3b3ada46a8 100644
--- a/indra/newview/llglsandbox.cpp
+++ b/indra/newview/llglsandbox.cpp
@@ -49,7 +49,7 @@
#include "lltextureentry.h"
#include "llviewercamera.h"
-#include "llvoavatar.h"
+#include "llvoavatarself.h"
#include "llagent.h"
#include "lltoolmgr.h"
#include "llselectmgr.h"
@@ -58,7 +58,6 @@
#include "llviewerobjectlist.h"
#include "lltoolselectrect.h"
#include "llviewerwindow.h"
-#include "llcompass.h"
#include "llsurface.h"
#include "llwind.h"
#include "llworld.h"
@@ -338,127 +337,8 @@ void LLToolSelectRect::handleRectangleSelection(S32 x, S32 y, MASK mask)
gViewerWindow->setup3DRender();
}
-
-const F32 COMPASS_SIZE = 64;
-static const F32 COMPASS_RANGE = 0.33f;
-
-void LLCompass::draw()
-{
- glMatrixMode(GL_MODELVIEW);
- gGL.pushMatrix();
-
- S32 width = 32;
- S32 height = 32;
-
- LLGLSUIDefault gls_ui;
-
- gGL.translatef( COMPASS_SIZE/2.f, COMPASS_SIZE/2.f, 0.f);
-
- if (mBkgndTexture)
- {
- gGL.getTexUnit(0)->bind(mBkgndTexture.get());
-
- gGL.color4f(1.0f, 1.0f, 1.0f, 1.0f);
-
- gGL.begin(LLRender::QUADS);
-
- gGL.texCoord2f(1.f, 1.f);
- gGL.vertex2i(width, height);
-
- gGL.texCoord2f(0.f, 1.f);
- gGL.vertex2i(-width, height);
-
- gGL.texCoord2f(0.f, 0.f);
- gGL.vertex2i(-width, -height);
-
- gGL.texCoord2f(1.f, 0.f);
- gGL.vertex2i(width, -height);
-
- gGL.end();
- }
-
- // rotate subsequent draws to agent rotation
- F32 rotation = atan2( gAgent.getFrameAgent().getAtAxis().mV[VX], gAgent.getFrameAgent().getAtAxis().mV[VY] );
- glRotatef( - rotation * RAD_TO_DEG, 0.f, 0.f, -1.f);
-
- if (mTexture)
- {
- gGL.getTexUnit(0)->bind(mTexture.get());
- gGL.color4f(1.0f, 1.0f, 1.0f, 1.0f);
-
- gGL.begin(LLRender::QUADS);
-
- gGL.texCoord2f(1.f, 1.f);
- gGL.vertex2i(width, height);
-
- gGL.texCoord2f(0.f, 1.f);
- gGL.vertex2i(-width, height);
-
- gGL.texCoord2f(0.f, 0.f);
- gGL.vertex2i(-width, -height);
-
- gGL.texCoord2f(1.f, 0.f);
- gGL.vertex2i(width, -height);
-
- gGL.end();
- }
-
- gGL.popMatrix();
-
-}
-
-
-
-void LLHorizontalCompass::draw()
-{
- LLGLSUIDefault gls_ui;
-
- S32 width = getRect().getWidth();
- S32 height = getRect().getHeight();
- S32 half_width = width / 2;
-
- if( mTexture )
- {
- const LLVector3& at_axis = LLViewerCamera::getInstance()->getAtAxis();
- F32 center = atan2( at_axis.mV[VX], at_axis.mV[VY] );
-
- center += F_PI;
- center = llclamp( center, 0.0f, F_TWO_PI ); // probably not necessary...
- center /= F_TWO_PI;
- F32 left = center - COMPASS_RANGE;
- F32 right = center + COMPASS_RANGE;
-
- gGL.getTexUnit(0)->bind(mTexture.get());
- gGL.color4f(1.0f, 1.0f, 1.0f, 1.0f );
- gGL.begin( LLRender::QUADS );
-
- gGL.texCoord2f(right, 1.f);
- gGL.vertex2i(width, height);
-
- gGL.texCoord2f(left, 1.f);
- gGL.vertex2i(0, height);
-
- gGL.texCoord2f(left, 0.f);
- gGL.vertex2i(0, 0);
-
- gGL.texCoord2f(right, 0.f);
- gGL.vertex2i(width, 0);
-
- gGL.end();
- }
-
- // Draw the focus line
- {
- gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
- gGL.color4fv( mFocusColor.mV );
- gl_line_2d( half_width, 0, half_width, height );
- }
-}
-
-
const F32 WIND_ALTITUDE = 180.f;
-
void LLWind::renderVectors()
{
// Renders the wind as vectors (used for debug)
@@ -1008,8 +888,6 @@ void LLViewerObjectList::renderObjectBeacons()
return;
}
- //const LLFontGL *font = LLResMgr::getInstance()->getRes(LLFONT_SANSSERIF);
-
LLGLSUIDefault gls_ui;
{
diff --git a/indra/newview/llgroupactions.cpp b/indra/newview/llgroupactions.cpp
new file mode 100644
index 0000000000..10a17476d9
--- /dev/null
+++ b/indra/newview/llgroupactions.cpp
@@ -0,0 +1,283 @@
+/**
+ * @file llgroupactions.cpp
+ * @brief Group-related actions (join, leave, new, delete, etc)
+ *
+ * $LicenseInfo:firstyear=2009&license=viewergpl$
+ *
+ * Copyright (c) 2009, Linden Research, Inc.
+ *
+ * Second Life Viewer Source Code
+ * The source code in this file ("Source Code") is provided by Linden Lab
+ * to you under the terms of the GNU General Public License, version 2.0
+ * ("GPL"), unless you have obtained a separate licensing agreement
+ * ("Other License"), formally executed by you and Linden Lab. Terms of
+ * the GPL can be found in doc/GPL-license.txt in this distribution, or
+ * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
+ *
+ * There are special exceptions to the terms and conditions of the GPL as
+ * it is applied to this Source Code. View the full text of the exception
+ * in the file doc/FLOSS-exception.txt in this software distribution, or
+ * online at
+ * http://secondlifegrid.net/programs/open_source/licensing/flossexception
+ *
+ * By copying, modifying or distributing this software, you acknowledge
+ * that you have read and understood your obligations described above,
+ * and agree to abide by those obligations.
+ *
+ * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+ * COMPLETENESS OR PERFORMANCE.
+ * $/LicenseInfo$
+ */
+
+
+#include "llviewerprecompiledheaders.h"
+
+#include "llgroupactions.h"
+
+#include "llagent.h"
+#include "llfloaterreg.h"
+#include "llgroupmgr.h"
+#include "llimview.h" // for gIMMgr
+#include "llsidetray.h"
+
+#include "llcommandhandler.h"
+
+//
+// Globals
+//
+
+class LLGroupHandler : public LLCommandHandler
+{
+public:
+ // requires trusted browser to trigger
+ LLGroupHandler() : LLCommandHandler("group", true) { }
+ bool handle(const LLSD& tokens, const LLSD& query_map,
+ LLMediaCtrl* web)
+ {
+ if (tokens.size() < 1)
+ {
+ return false;
+ }
+
+ if (tokens[0].asString() == "create")
+ {
+ LLGroupActions::createGroup();
+ return true;
+ }
+
+ if (tokens.size() < 2)
+ {
+ return false;
+ }
+
+ if (tokens[0].asString() == "list")
+ {
+ if (tokens[1].asString() == "show")
+ {
+ LLFloaterReg::showInstance("contacts", "groups");
+ return true;
+ }
+ return false;
+ }
+
+ LLUUID group_id;
+ if (!group_id.set(tokens[0], FALSE))
+ {
+ return false;
+ }
+
+ if (tokens[1].asString() == "about")
+ {
+ if (group_id.isNull())
+ return true;
+
+ LLGroupActions::show(group_id);
+
+ return true;
+ }
+ return false;
+ }
+};
+LLGroupHandler gGroupHandler;
+
+// static
+void LLGroupActions::search()
+{
+ LLFloaterReg::showInstance("search", LLSD().insert("panel", "group"));
+}
+
+// static
+void LLGroupActions::leave(const LLUUID& group_id)
+{
+ if (group_id.isNull())
+ return;
+
+ S32 count = gAgent.mGroups.count();
+ S32 i;
+ for (i = 0; i < count; ++i)
+ {
+ if(gAgent.mGroups.get(i).mID == group_id)
+ break;
+ }
+ if (i < count)
+ {
+ LLSD args;
+ args["GROUP"] = gAgent.mGroups.get(i).mName;
+ LLSD payload;
+ payload["group_id"] = group_id;
+ LLNotifications::instance().add("GroupLeaveConfirmMember", args, payload, onLeaveGroup);
+ }
+}
+
+// static
+void LLGroupActions::activate(const LLUUID& group_id)
+{
+ LLMessageSystem* msg = gMessageSystem;
+ msg->newMessageFast(_PREHASH_ActivateGroup);
+ msg->nextBlockFast(_PREHASH_AgentData);
+ msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
+ msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
+ msg->addUUIDFast(_PREHASH_GroupID, group_id);
+ gAgent.sendReliableMessage();
+}
+
+bool isGroupUIVisible()
+{
+ LLPanel* panel = LLSideTray::getInstance()->findChild<LLPanel>("panel_group_info_sidetray");
+ if(!panel)
+ return false;
+ return panel->getVisible();
+}
+
+// static
+void LLGroupActions::show(const LLUUID& group_id)
+{
+ if (group_id.isNull())
+ return;
+
+ LLSD params;
+ params["group_id"] = group_id;
+ params["open_tab_name"] = "panel_group_info_sidetray";
+
+ LLSideTray::getInstance()->showPanel("panel_group_info_sidetray", params);
+}
+
+void LLGroupActions::refresh_notices()
+{
+ if(!isGroupUIVisible())
+ return;
+
+ LLSD params;
+ params["group_id"] = LLUUID::null;
+ params["open_tab_name"] = "panel_group_info_sidetray";
+ params["action"] = "refresh_notices";
+
+ LLSideTray::getInstance()->showPanel("panel_group_info_sidetray", params);
+}
+
+//static
+void LLGroupActions::refresh(const LLUUID& group_id)
+{
+ if(!isGroupUIVisible())
+ return;
+
+ LLSD params;
+ params["group_id"] = group_id;
+ params["open_tab_name"] = "panel_group_info_sidetray";
+ params["action"] = "refresh";
+
+ LLSideTray::getInstance()->showPanel("panel_group_info_sidetray", params);
+}
+
+//static
+void LLGroupActions::createGroup()
+{
+ LLSD params;
+ params["group_id"] = LLUUID::null;
+ params["open_tab_name"] = "panel_group_info_sidetray";
+ params["action"] = "create";
+
+ LLSideTray::getInstance()->showPanel("panel_group_info_sidetray", params);
+
+}
+//static
+void LLGroupActions::closeGroup(const LLUUID& group_id)
+{
+ if(!isGroupUIVisible())
+ return;
+
+ LLSD params;
+ params["group_id"] = group_id;
+ params["open_tab_name"] = "panel_group_info_sidetray";
+ params["action"] = "close";
+
+ LLSideTray::getInstance()->showPanel("panel_group_info_sidetray", params);
+}
+
+
+// static
+void LLGroupActions::startChat(const LLUUID& group_id)
+{
+ if (group_id.isNull())
+ return;
+
+ LLGroupData group_data;
+ if (gAgent.getGroupData(group_id, group_data))
+ {
+ gIMMgr->addSession(
+ group_data.mName,
+ IM_SESSION_GROUP_START,
+ group_id);
+ make_ui_sound("UISndStartIM");
+ }
+ else
+ {
+ // this should never happen, as starting a group IM session
+ // relies on you belonging to the group and hence having the group data
+ make_ui_sound("UISndInvalidOp");
+ }
+}
+
+// static
+bool LLGroupActions::isAvatarMemberOfGroup(const LLUUID& group_id, const LLUUID& avatar_id)
+{
+ if(group_id.isNull() || avatar_id.isNull())
+ {
+ return false;
+ }
+
+ LLGroupMgrGroupData* group_data = LLGroupMgr::getInstance()->getGroupData(group_id);
+ if(!group_data)
+ {
+ return false;
+ }
+
+ if(group_data->mMembers.end() == group_data->mMembers.find(avatar_id))
+ {
+ return false;
+ }
+
+ return true;
+}
+
+//-- Private methods ----------------------------------------------------------
+
+// static
+bool LLGroupActions::onLeaveGroup(const LLSD& notification, const LLSD& response)
+{
+ S32 option = LLNotification::getSelectedOption(notification, response);
+ LLUUID group_id = notification["payload"]["group_id"].asUUID();
+ if(option == 0)
+ {
+ LLMessageSystem* msg = gMessageSystem;
+ msg->newMessageFast(_PREHASH_LeaveGroupRequest);
+ msg->nextBlockFast(_PREHASH_AgentData);
+ msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
+ msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
+ msg->nextBlockFast(_PREHASH_GroupData);
+ msg->addUUIDFast(_PREHASH_GroupID, group_id);
+ gAgent.sendReliableMessage();
+ }
+ return false;
+}
diff --git a/indra/newview/llgroupactions.h b/indra/newview/llgroupactions.h
new file mode 100644
index 0000000000..9fe1da8af2
--- /dev/null
+++ b/indra/newview/llgroupactions.h
@@ -0,0 +1,103 @@
+/**
+ * @file llgroupactions.h
+ * @brief Group-related actions (join, leave, new, delete, etc)
+ *
+ * $LicenseInfo:firstyear=2009&license=viewergpl$
+ *
+ * Copyright (c) 2009, Linden Research, Inc.
+ *
+ * Second Life Viewer Source Code
+ * The source code in this file ("Source Code") is provided by Linden Lab
+ * to you under the terms of the GNU General Public License, version 2.0
+ * ("GPL"), unless you have obtained a separate licensing agreement
+ * ("Other License"), formally executed by you and Linden Lab. Terms of
+ * the GPL can be found in doc/GPL-license.txt in this distribution, or
+ * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
+ *
+ * There are special exceptions to the terms and conditions of the GPL as
+ * it is applied to this Source Code. View the full text of the exception
+ * in the file doc/FLOSS-exception.txt in this software distribution, or
+ * online at
+ * http://secondlifegrid.net/programs/open_source/licensing/flossexception
+ *
+ * By copying, modifying or distributing this software, you acknowledge
+ * that you have read and understood your obligations described above,
+ * and agree to abide by those obligations.
+ *
+ * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+ * COMPLETENESS OR PERFORMANCE.
+ * $/LicenseInfo$
+ */
+
+#ifndef LL_LLGROUPACTIONS_H
+#define LL_LLGROUPACTIONS_H
+
+#include "llsd.h"
+#include "lluuid.h"
+
+/**
+ * Group-related actions (join, leave, new, delete, etc)
+ */
+class LLGroupActions
+{
+public:
+ /**
+ * Invokes group search floater.
+ */
+ static void search();
+
+ /**
+ * Invokes "Leave Group" floater.
+ */
+ static void leave(const LLUUID& group_id);
+
+ /**
+ * Activate group.
+ */
+ static void activate(const LLUUID& group_id);
+
+ /**
+ * Show group information panel.
+ */
+ static void show(const LLUUID& group_id);
+
+ /**
+ * Refresh group information panel.
+ */
+ static void refresh(const LLUUID& group_id);
+
+ /**
+ * Refresh group notices panel.
+ */
+ static void refresh_notices();
+
+ /**
+ * Refresh group information panel.
+ */
+ static void createGroup();
+
+ /**
+ * Close group information panel.
+ */
+ static void closeGroup (const LLUUID& group_id);
+
+ /**
+ * Start group instant messaging session.
+ */
+ static void startChat(const LLUUID& group_id);
+
+ /**
+ * Returns true if avatar is in group.
+ *
+ * Note that data about group members is loaded from server.
+ * If data has not been loaded yet, function will return inaccurate result.
+ * See LLGroupMgr::sendGroupMembersRequest
+ */
+ static bool isAvatarMemberOfGroup(const LLUUID& group_id, const LLUUID& avatar_id);
+
+private:
+ static bool onLeaveGroup(const LLSD& notification, const LLSD& response);
+};
+
+#endif // LL_LLGROUPACTIONS_H
diff --git a/indra/newview/llgrouplist.cpp b/indra/newview/llgrouplist.cpp
new file mode 100644
index 0000000000..278fd5b9f6
--- /dev/null
+++ b/indra/newview/llgrouplist.cpp
@@ -0,0 +1,90 @@
+/**
+ * @file llgrouplist.cpp
+ * @brief List of the groups the agent belongs to.
+ *
+ * $LicenseInfo:firstyear=2009&license=viewergpl$
+ *
+ * Copyright (c) 2009, Linden Research, Inc.
+ *
+ * Second Life Viewer Source Code
+ * The source code in this file ("Source Code") is provided by Linden Lab
+ * to you under the terms of the GNU General Public License, version 2.0
+ * ("GPL"), unless you have obtained a separate licensing agreement
+ * ("Other License"), formally executed by you and Linden Lab. Terms of
+ * the GPL can be found in doc/GPL-license.txt in this distribution, or
+ * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
+ *
+ * There are special exceptions to the terms and conditions of the GPL as
+ * it is applied to this Source Code. View the full text of the exception
+ * in the file doc/FLOSS-exception.txt in this software distribution, or
+ * online at
+ * http://secondlifegrid.net/programs/open_source/licensing/flossexception
+ *
+ * By copying, modifying or distributing this software, you acknowledge
+ * that you have read and understood your obligations described above,
+ * and agree to abide by those obligations.
+ *
+ * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+ * COMPLETENESS OR PERFORMANCE.
+ * $/LicenseInfo$
+ */
+
+#include "llviewerprecompiledheaders.h"
+
+#include "llgrouplist.h"
+
+// libs
+#include "lltrans.h"
+
+// newview
+#include "llagent.h"
+
+static LLDefaultChildRegistry::Register<LLGroupList> r("group_list");
+
+LLGroupList::Params::Params()
+{
+ // Prevent the active group from being always first in the list.
+ online_go_first = false;
+}
+
+LLGroupList::LLGroupList(const Params& p)
+: LLAvatarList(p)
+{
+}
+
+static bool findInsensitive(std::string haystack, const std::string& needle_upper)
+{
+ LLStringUtil::toUpper(haystack);
+ return haystack.find(needle_upper) != std::string::npos;
+}
+
+BOOL LLGroupList::update(const std::string& name_filter)
+{
+ LLCtrlListInterface *group_list = getListInterface();
+ const LLUUID& highlight_id = gAgent.getGroupID();
+ S32 count = gAgent.mGroups.count();
+ LLUUID id;
+
+ group_list->operateOnAll(LLCtrlListInterface::OP_DELETE);
+
+ for(S32 i = 0; i < count; ++i)
+ {
+ // *TODO: check powers mask?
+ id = gAgent.mGroups.get(i).mID;
+ const LLGroupData& group_data = gAgent.mGroups.get(i);
+ if (name_filter != LLStringUtil::null && !findInsensitive(group_data.mName, name_filter))
+ continue;
+ addItem(id, group_data.mName, highlight_id == id, ADD_BOTTOM);
+ }
+
+ // add "none" to list at top
+ {
+ std::string loc_none = LLTrans::getString("GroupsNone");
+ if (name_filter == LLStringUtil::null || findInsensitive(loc_none, name_filter))
+ addItem(LLUUID::null, loc_none, highlight_id.isNull(), ADD_TOP);
+ }
+
+ group_list->selectByValue(highlight_id);
+ return TRUE;
+}
diff --git a/indra/newview/llgrouplist.h b/indra/newview/llgrouplist.h
new file mode 100644
index 0000000000..e893313f4b
--- /dev/null
+++ b/indra/newview/llgrouplist.h
@@ -0,0 +1,54 @@
+/**
+ * @file llgrouplist.h
+ * @brief List of the groups the agent belongs to.
+ *
+ * $LicenseInfo:firstyear=2009&license=viewergpl$
+ *
+ * Copyright (c) 2009, Linden Research, Inc.
+ *
+ * Second Life Viewer Source Code
+ * The source code in this file ("Source Code") is provided by Linden Lab
+ * to you under the terms of the GNU General Public License, version 2.0
+ * ("GPL"), unless you have obtained a separate licensing agreement
+ * ("Other License"), formally executed by you and Linden Lab. Terms of
+ * the GPL can be found in doc/GPL-license.txt in this distribution, or
+ * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
+ *
+ * There are special exceptions to the terms and conditions of the GPL as
+ * it is applied to this Source Code. View the full text of the exception
+ * in the file doc/FLOSS-exception.txt in this software distribution, or
+ * online at
+ * http://secondlifegrid.net/programs/open_source/licensing/flossexception
+ *
+ * By copying, modifying or distributing this software, you acknowledge
+ * that you have read and understood your obligations described above,
+ * and agree to abide by those obligations.
+ *
+ * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+ * COMPLETENESS OR PERFORMANCE.
+ * $/LicenseInfo$
+ */
+
+#ifndef LL_LLGROUPLIST_H
+#define LL_LLGROUPLIST_H
+
+#include <llscrolllistctrl.h>
+
+#include "llavatarlist.h"
+
+// *TODO: derive from ListView when it's ready.
+class LLGroupList: public LLAvatarList
+{
+ LOG_CLASS(LLGroupList);
+public:
+ struct Params : public LLInitParam::Block<Params, LLAvatarList::Params>
+ {
+ Params();
+ };
+
+ LLGroupList(const Params&);
+ BOOL update(const std::string& name_filter = LLStringUtil::null);
+};
+
+#endif // LL_LLGROUPLIST_H
diff --git a/indra/newview/llgroupmgr.cpp b/indra/newview/llgroupmgr.cpp
index 003a02c3cd..5e50fad008 100644
--- a/indra/newview/llgroupmgr.cpp
+++ b/indra/newview/llgroupmgr.cpp
@@ -51,7 +51,8 @@
#include "lleconomy.h"
#include "llviewerwindow.h"
#include "llfloaterdirectory.h"
-#include "llfloatergroupinfo.h"
+#include "llpanelgroup.h"
+#include "llgroupactions.h"
#include "lluictrlfactory.h"
#include <boost/regex.hpp>
@@ -808,7 +809,7 @@ static void formatDateString(std::string &date_string)
std::string day = result[2];
// ISO 8601 date format
- date_string = llformat("%04s-%02s-%02s", year.c_str(), month.c_str(), day.c_str());
+ date_string = llformat("%02s/%02s/%04s", month.c_str(), day.c_str(), year.c_str());
}
}
@@ -1210,7 +1211,7 @@ void LLGroupMgr::processEjectGroupMemberReply(LLMessageSystem* msg, void ** data
// If we had a failure, the group panel needs to be updated.
if (!success)
{
- LLFloaterGroupInfo::refreshGroup(group_id);
+ LLGroupActions::refresh(group_id);
}
}
@@ -1230,7 +1231,7 @@ void LLGroupMgr::processJoinGroupReply(LLMessageSystem* msg, void ** data)
LLGroupMgr::getInstance()->clearGroupData(group_id);
// refresh the floater for this group, if any.
- LLFloaterGroupInfo::refreshGroup(group_id);
+ LLGroupActions::refresh(group_id);
// refresh the group panel of the search window, if necessary.
LLFloaterDirectory::refreshGroup(group_id);
}
@@ -1252,7 +1253,7 @@ void LLGroupMgr::processLeaveGroupReply(LLMessageSystem* msg, void ** data)
LLGroupMgr::getInstance()->clearGroupData(group_id);
// close the floater for this group, if any.
- LLFloaterGroupInfo::closeGroup(group_id);
+ LLGroupActions::closeGroup(group_id);
// refresh the group panel of the search window, if necessary.
LLFloaterDirectory::refreshGroup(group_id);
}
@@ -1288,12 +1289,14 @@ void LLGroupMgr::processCreateGroupReply(LLMessageSystem* msg, void ** data)
gAgent.mGroups.push_back(gd);
- LLFloaterGroupInfo::closeCreateGroup();
- LLFloaterGroupInfo::showFromUUID(group_id,"roles_tab");
+ LLPanelGroup::refreshCreatedGroup(group_id);
+ //FIXME
+ //LLFloaterGroupInfo::closeCreateGroup();
+ //LLFloaterGroupInfo::showFromUUID(group_id,"roles_tab");
}
else
{
- // *TODO:translate
+ // *TODO: Translate
LLSD args;
args["MESSAGE"] = message;
LLNotifications::instance().add("UnableToCreateGroup", args);
diff --git a/indra/newview/llhomelocationresponder.cpp b/indra/newview/llhomelocationresponder.cpp
index 3ef58e7561..df478a0a04 100644
--- a/indra/newview/llhomelocationresponder.cpp
+++ b/indra/newview/llhomelocationresponder.cpp
@@ -103,7 +103,7 @@ void LLHomeLocationResponder::result( const LLSD& content )
}
}
-void LLHomeLocationResponder::error( const LLSD& content )
+void LLHomeLocationResponder::error( U32 status, const std::string& reason )
{
- llinfos << "received error(" << ll_pretty_print_sd( content ) << ")" << llendl;
+ llinfos << "received error(" << reason << ")" << llendl;
}
diff --git a/indra/newview/llhomelocationresponder.h b/indra/newview/llhomelocationresponder.h
index 1e222cd5b2..3a1d8ebfed 100644
--- a/indra/newview/llhomelocationresponder.h
+++ b/indra/newview/llhomelocationresponder.h
@@ -42,7 +42,7 @@
class LLHomeLocationResponder : public LLHTTPClient::Responder
{
virtual void result( const LLSD& content );
- virtual void error( const LLSD& content );
+ virtual void error( U32 status, const std::string& reason );
};
#endif
diff --git a/indra/newview/llhudeffect.cpp b/indra/newview/llhudeffect.cpp
index c1d46f98d4..bfd62805a1 100644
--- a/indra/newview/llhudeffect.cpp
+++ b/indra/newview/llhudeffect.cpp
@@ -38,7 +38,6 @@
#include "llgl.h"
#include "llagent.h"
#include "llrendersphere.h"
-#include "llimagegl.h"
#include "llviewerobjectlist.h"
#include "lldrawable.h"
diff --git a/indra/newview/llhudeffect.h b/indra/newview/llhudeffect.h
index 954cda7c8d..781e57fa6a 100644
--- a/indra/newview/llhudeffect.h
+++ b/indra/newview/llhudeffect.h
@@ -37,9 +37,6 @@
#include "lluuid.h"
#include "v4coloru.h"
-#include "llinterp.h"
-#include "llframetimer.h"
-#include "llmemory.h"
const F32 LL_HUD_DUR_SHORT = 1.f;
diff --git a/indra/newview/llhudeffectbeam.cpp b/indra/newview/llhudeffectbeam.cpp
index 6cb3bef751..43a8dd1d81 100644
--- a/indra/newview/llhudeffectbeam.cpp
+++ b/indra/newview/llhudeffectbeam.cpp
@@ -43,7 +43,6 @@
#include "llgl.h"
#include "llglheaders.h"
#include "llhudrender.h"
-#include "llimagegl.h"
#include "llrendersphere.h"
#include "llviewercamera.h"
#include "llvoavatar.h"
diff --git a/indra/newview/llhudeffectlookat.cpp b/indra/newview/llhudeffectlookat.cpp
index 3a5bec2be0..e366340a10 100644
--- a/indra/newview/llhudeffectlookat.cpp
+++ b/indra/newview/llhudeffectlookat.cpp
@@ -610,7 +610,9 @@ bool LLHUDEffectLookAt::calcTargetPosition()
}
LLVOAvatar* source_avatar = (LLVOAvatar*)(LLViewerObject*)mSourceObject;
-
+ if (!source_avatar->isBuilt())
+ return false;
+
if (target_obj && target_obj->mDrawable.notNull())
{
LLQuaternion target_rot;
diff --git a/indra/newview/llhudeffectpointat.h b/indra/newview/llhudeffectpointat.h
index 81db3da1c7..278c69fe2b 100644
--- a/indra/newview/llhudeffectpointat.h
+++ b/indra/newview/llhudeffectpointat.h
@@ -33,6 +33,7 @@
#ifndef LL_LLHUDEFFECTPOINTAT_H
#define LL_LLHUDEFFECTPOINTAT_H
+#include "llframetimer.h"
#include "llhudeffect.h"
class LLViewerObject;
diff --git a/indra/newview/llhudeffecttrail.cpp b/indra/newview/llhudeffecttrail.cpp
index 0ade6810ba..786491211d 100644
--- a/indra/newview/llhudeffecttrail.cpp
+++ b/indra/newview/llhudeffecttrail.cpp
@@ -35,14 +35,13 @@
#include "llhudeffecttrail.h"
#include "llviewercontrol.h"
-#include "llimagegl.h"
#include "message.h"
#include "llagent.h"
#include "llbox.h"
#include "lldrawable.h"
#include "llhudrender.h"
-#include "llviewerimagelist.h"
+#include "llviewertexturelist.h"
#include "llviewerobjectlist.h"
#include "llviewerpartsim.h"
#include "llviewerpartsource.h"
diff --git a/indra/newview/llhudicon.cpp b/indra/newview/llhudicon.cpp
index 3535fe185c..eda1d3fc55 100644
--- a/indra/newview/llhudicon.cpp
+++ b/indra/newview/llhudicon.cpp
@@ -40,7 +40,7 @@
#include "llviewerobject.h"
#include "lldrawable.h"
#include "llviewercamera.h"
-#include "llviewerimage.h"
+#include "llviewertexture.h"
#include "llviewerwindow.h"
//-----------------------------------------------------------------------------
@@ -144,7 +144,7 @@ void LLHUDIcon::renderIcon(BOOL for_select)
alpha_factor *= clamp_rescale(time_elapsed, MAX_VISIBLE_TIME - FADE_OUT_TIME, MAX_VISIBLE_TIME, 1.f, 0.f);
}
- F32 image_aspect = (F32)mImagep->mFullWidth / (F32)mImagep->mFullHeight;
+ F32 image_aspect = (F32)mImagep->getFullWidth() / (F32)mImagep->getFullHeight() ;
LLVector3 x_scale = image_aspect * (F32)gViewerWindow->getWindowHeight() * mScale * scale_factor * x_pixel_vec;
LLVector3 y_scale = (F32)gViewerWindow->getWindowHeight() * mScale * scale_factor * y_pixel_vec;
@@ -164,7 +164,7 @@ void LLHUDIcon::renderIcon(BOOL for_select)
LLColor4 icon_color = LLColor4::white;
icon_color.mV[VALPHA] = alpha_factor;
gGL.color4fv(icon_color.mV);
- gGL.getTexUnit(0)->bind(mImagep.get());
+ gGL.getTexUnit(0)->bind(mImagep);
}
gGL.begin(LLRender::QUADS);
@@ -181,7 +181,7 @@ void LLHUDIcon::renderIcon(BOOL for_select)
gGL.end();
}
-void LLHUDIcon::setImage(LLViewerImage* imagep)
+void LLHUDIcon::setImage(LLViewerTexture* imagep)
{
mImagep = imagep;
mImagep->setAddressMode(LLTexUnit::TAM_CLAMP);
@@ -260,7 +260,7 @@ BOOL LLHUDIcon::lineSegmentIntersect(const LLVector3& start, const LLVector3& en
return FALSE;
}
- F32 image_aspect = (F32)mImagep->mFullWidth / (F32)mImagep->mFullHeight;
+ F32 image_aspect = (F32)mImagep->getFullWidth() / (F32)mImagep->getFullHeight() ;
LLVector3 x_scale = image_aspect * (F32)gViewerWindow->getWindowHeight() * mScale * scale_factor * x_pixel_vec;
LLVector3 y_scale = (F32)gViewerWindow->getWindowHeight() * mScale * scale_factor * y_pixel_vec;
diff --git a/indra/newview/llhudicon.h b/indra/newview/llhudicon.h
index 154e6df518..770e3bbcd0 100644
--- a/indra/newview/llhudicon.h
+++ b/indra/newview/llhudicon.h
@@ -33,7 +33,7 @@
#ifndef LL_LLHUDICON_H
#define LL_LLHUDICON_H
-#include "llmemory.h"
+#include "llpointer.h"
#include "lldarrayptr.h"
#include "llhudobject.h"
@@ -61,7 +61,7 @@ public:
/*virtual*/ void markDead();
/*virtual*/ F32 getDistance() const { return mDistance; }
- void setImage(LLViewerImage* imagep);
+ void setImage(LLViewerTexture* imagep);
void setScale(F32 fraction_of_fov);
void restartLifeTimer() { mLifeTimer.reset(); }
@@ -88,7 +88,7 @@ protected:
void renderIcon(BOOL for_select); // common render code
private:
- LLPointer<LLViewerImage> mImagep;
+ LLPointer<LLViewerTexture> mImagep;
LLFrameTimer mAnimTimer;
LLFrameTimer mLifeTimer;
F32 mDistance;
diff --git a/indra/newview/llhudmanager.cpp b/indra/newview/llhudmanager.cpp
index 955d786187..bdb8dadfb4 100644
--- a/indra/newview/llhudmanager.cpp
+++ b/indra/newview/llhudmanager.cpp
@@ -40,6 +40,7 @@
#include "llagent.h"
#include "llhudeffect.h"
#include "pipeline.h"
+#include "llui.h"
#include "llviewercontrol.h"
#include "llviewerobjectlist.h"
@@ -52,19 +53,20 @@ LLColor4 LLHUDManager::sChildColor;
LLHUDManager::LLHUDManager()
{
- LLHUDManager::sParentColor = gColors.getColor("FocusColor");
+ LLHUDManager::sParentColor = LLUIColorTable::instance().getColor("FocusColor");
// rdw commented out since it's not used. Also removed from colors_base.xml
- //LLHUDManager::sChildColor = gColors.getColor("FocusSecondaryColor");
+ //LLHUDManager::sChildColor =LLUIColorTable::instance().getColor("FocusSecondaryColor");
}
LLHUDManager::~LLHUDManager()
{
}
+static LLFastTimer::DeclareTimer FTM_HUD_EFFECTS("Hud Effects");
void LLHUDManager::updateEffects()
{
- LLFastTimer ftm(LLFastTimer::FTM_HUD_EFFECTS);
+ LLFastTimer ftm(FTM_HUD_EFFECTS);
S32 i;
for (i = 0; i < mHUDEffects.count(); i++)
{
diff --git a/indra/newview/llhudmanager.h b/indra/newview/llhudmanager.h
index 615eb93a27..b2b4ffb559 100644
--- a/indra/newview/llhudmanager.h
+++ b/indra/newview/llhudmanager.h
@@ -36,7 +36,7 @@
// Responsible for managing all HUD elements.
#include "llhudobject.h"
-#include "lldarray.h"
+#include "lldarrayptr.h"
class LLViewerObject;
class LLHUDEffect;
diff --git a/indra/newview/llhudobject.cpp b/indra/newview/llhudobject.cpp
index bdff492948..dc55aba0db 100644
--- a/indra/newview/llhudobject.cpp
+++ b/indra/newview/llhudobject.cpp
@@ -254,10 +254,12 @@ LLHUDEffect *LLHUDObject::addHUDEffect(const U8 type)
return hud_objectp;
}
+static LLFastTimer::DeclareTimer FTM_HUD_UPDATE("Update Hud");
+
// static
void LLHUDObject::updateAll()
{
- LLFastTimer ftm(LLFastTimer::FTM_HUD_UPDATE);
+ LLFastTimer ftm(FTM_HUD_UPDATE);
LLHUDText::updateAll();
LLHUDIcon::updateAll();
sortObjects();
diff --git a/indra/newview/llhudobject.h b/indra/newview/llhudobject.h
index 2cd8abf886..d304ac41af 100644
--- a/indra/newview/llhudobject.h
+++ b/indra/newview/llhudobject.h
@@ -37,7 +37,7 @@
* Base class and manager for in-world 2.5D non-interactive objects
*/
-#include "llmemory.h"
+#include "llpointer.h"
#include "v4color.h"
#include "v3math.h"
diff --git a/indra/newview/llhudrender.cpp b/indra/newview/llhudrender.cpp
index 95b8442ec7..886fe3da07 100644
--- a/indra/newview/llhudrender.cpp
+++ b/indra/newview/llhudrender.cpp
@@ -40,24 +40,26 @@
#include "v3math.h"
#include "llquaternion.h"
#include "llfontgl.h"
-#include "llimagegl.h"
#include "llglheaders.h"
#include "llviewerwindow.h"
+#include "llui.h"
void hud_render_utf8text(const std::string &str, const LLVector3 &pos_agent,
const LLFontGL &font,
const U8 style,
+ const LLFontGL::ShadowType shadow,
const F32 x_offset, const F32 y_offset,
const LLColor4& color,
const BOOL orthographic)
{
LLWString wstr(utf8str_to_wstring(str));
- hud_render_text(wstr, pos_agent, font, style, x_offset, y_offset, color, orthographic);
+ hud_render_text(wstr, pos_agent, font, style, shadow, x_offset, y_offset, color, orthographic);
}
void hud_render_text(const LLWString &wstr, const LLVector3 &pos_agent,
const LLFontGL &font,
const U8 style,
+ const LLFontGL::ShadowType shadow,
const F32 x_offset, const F32 y_offset,
const LLColor4& color,
const BOOL orthographic)
@@ -75,8 +77,8 @@ void hud_render_text(const LLWString &wstr, const LLVector3 &pos_agent,
LLVector3 up_axis;
if (orthographic)
{
- right_axis.setVec(0.f, -1.f / gViewerWindow->getWindowHeight(), 0.f);
- up_axis.setVec(0.f, 0.f, 1.f / gViewerWindow->getWindowHeight());
+ right_axis.setVec(0.f, -1.f / gViewerWindow->getWorldViewWidth(), 0.f);
+ up_axis.setVec(0.f, 0.f, 1.f / gViewerWindow->getWorldViewHeight());
}
else
{
@@ -104,26 +106,36 @@ void hud_render_text(const LLWString &wstr, const LLVector3 &pos_agent,
//get the render_pos in screen space
F64 winX, winY, winZ;
+ LLRect world_view_rect = gViewerWindow->getWorldViewRect();
+ S32 viewport[4];
+ viewport[0] = world_view_rect.mLeft;
+ viewport[1] = world_view_rect.mBottom;
+ viewport[2] = world_view_rect.getWidth();
+ viewport[3] = world_view_rect.getHeight();
gluProject(render_pos.mV[0], render_pos.mV[1], render_pos.mV[2],
- gGLModelView, gGLProjection, (GLint*) gGLViewport,
+ gGLModelView, gGLProjection, (GLint*) viewport,
&winX, &winY, &winZ);
- //fonts all render orthographically, set up projection
+ //fonts all render orthographically, set up projection``
glMatrixMode(GL_PROJECTION);
glPushMatrix();
glMatrixMode(GL_MODELVIEW);
LLUI::pushMatrix();
- gViewerWindow->setup2DRender();
+ gl_state_for_2d(world_view_rect.getWidth(), world_view_rect.getHeight());
+ gViewerWindow->setup3DViewport();
+ //gViewerWindow->setup2DRender();
+ winX -= world_view_rect.mLeft;
+ winY -= world_view_rect.mBottom;
LLUI::loadIdentity();
LLUI::translate((F32) winX*1.0f/LLFontGL::sScaleX, (F32) winY*1.0f/(LLFontGL::sScaleY), -(((F32) winZ*2.f)-1.f));
//glRotatef(angle * RAD_TO_DEG, axis.mV[VX], axis.mV[VY], axis.mV[VZ]);
//glScalef(right_scale, up_scale, 1.f);
F32 right_x;
- font.render(wstr, 0, 0, 0, color, LLFontGL::LEFT, LLFontGL::BASELINE, style, wstr.length(), 1000, &right_x);
+ font.render(wstr, 0, 0, 0, color, LLFontGL::LEFT, LLFontGL::BASELINE, style, shadow, wstr.length(), 1000, &right_x);
LLUI::popMatrix();
glMatrixMode(GL_PROJECTION);
diff --git a/indra/newview/llhudrender.h b/indra/newview/llhudrender.h
index 5ca865737f..93de89f7b0 100644
--- a/indra/newview/llhudrender.h
+++ b/indra/newview/llhudrender.h
@@ -43,6 +43,7 @@ void hud_render_text(const LLWString &wstr,
const LLVector3 &pos_agent,
const LLFontGL &font,
const U8 style,
+ const LLFontGL::ShadowType,
const F32 x_offset,
const F32 y_offset,
const LLColor4& color,
@@ -53,6 +54,7 @@ void hud_render_utf8text(const std::string &str,
const LLVector3 &pos_agent,
const LLFontGL &font,
const U8 style,
+ const LLFontGL::ShadowType,
const F32 x_offset,
const F32 y_offset,
const LLColor4& color,
diff --git a/indra/newview/llhudtext.cpp b/indra/newview/llhudtext.cpp
index 20140073f4..8086400493 100644
--- a/indra/newview/llhudtext.cpp
+++ b/indra/newview/llhudtext.cpp
@@ -39,16 +39,14 @@
#include "llagent.h"
#include "llviewercontrol.h"
-#include "llchatbar.h"
#include "llcriticaldamp.h"
#include "lldrawable.h"
#include "llfontgl.h"
#include "llglheaders.h"
#include "llhudrender.h"
-#include "llimagegl.h"
#include "llui.h"
#include "llviewercamera.h"
-#include "llviewerimagelist.h"
+#include "llviewertexturelist.h"
#include "llviewerobject.h"
#include "llvovolume.h"
#include "llviewerwindow.h"
@@ -113,7 +111,6 @@ LLHUDText::LLHUDText(const U8 type) :
mRadius = 0.1f;
LLPointer<LLHUDText> ptr(this);
sTextObjects.insert(ptr);
- //LLDebugVarMessageBox::show("max width", &HUD_TEXT_MAX_WIDTH, 500.f, 1.f);
}
LLHUDText::~LLHUDText()
@@ -293,7 +290,7 @@ void LLHUDText::renderText(BOOL for_select)
LLUIImagePtr imagep = LLUI::getUIImage("rounded_square.tga");
// *TODO: make this a per-text setting
- LLColor4 bg_color = gSavedSettings.getColor4("BackgroundChatColor");
+ LLColor4 bg_color = LLUIColorTable::instance().getColor("BackgroundChatColor");
bg_color.setAlpha(gSavedSettings.getF32("ChatBubbleOpacity") * alpha_factor);
const S32 border_height = 16;
@@ -319,8 +316,8 @@ void LLHUDText::renderText(BOOL for_select)
if (mOnHUDAttachment)
{
- x_pixel_vec = LLVector3::y_axis / (F32)gViewerWindow->getWindowWidth();
- y_pixel_vec = LLVector3::z_axis / (F32)gViewerWindow->getWindowHeight();
+ x_pixel_vec = LLVector3::y_axis / (F32)gViewerWindow->getWorldViewWidth();
+ y_pixel_vec = LLVector3::z_axis / (F32)gViewerWindow->getWorldViewHeight();
}
else
{
@@ -509,7 +506,7 @@ void LLHUDText::renderText(BOOL for_select)
LLColor4 label_color(0.f, 0.f, 0.f, 1.f);
label_color.mV[VALPHA] = alpha_factor;
- hud_render_text(segment_iter->getText(), render_position, *fontp, segment_iter->mStyle, x_offset, y_offset, label_color, mOnHUDAttachment);
+ hud_render_text(segment_iter->getText(), render_position, *fontp, segment_iter->mStyle, LLFontGL::NO_SHADOW, x_offset, y_offset, label_color, mOnHUDAttachment);
}
}
@@ -535,9 +532,10 @@ void LLHUDText::renderText(BOOL for_select)
y_offset -= fontp->getLineHeight();
U8 style = segment_iter->mStyle;
+ LLFontGL::ShadowType shadow = LLFontGL::NO_SHADOW;
if (mDropShadow)
{
- style |= LLFontGL::DROP_SHADOW;
+ shadow = LLFontGL::DROP_SHADOW;
}
F32 x_offset;
@@ -553,7 +551,7 @@ void LLHUDText::renderText(BOOL for_select)
text_color = segment_iter->mColor;
text_color.mV[VALPHA] *= alpha_factor;
- hud_render_text(segment_iter->getText(), render_position, *fontp, style, x_offset, y_offset, text_color, mOnHUDAttachment);
+ hud_render_text(segment_iter->getText(), render_position, *fontp, style, shadow, x_offset, y_offset, text_color, mOnHUDAttachment);
}
}
/// Reset the default color to white. The renderer expects this to be the default.
@@ -797,44 +795,22 @@ LLVector2 LLHUDText::updateScreenPos(LLVector2 &offset)
if (!LLViewerCamera::getInstance()->projectPosAgentToScreen(world_pos, screen_pos, FALSE) && mVisibleOffScreen)
{
// bubble off-screen, so find a spot for it along screen edge
- LLVector2 window_center(gViewerWindow->getWindowDisplayWidth() * 0.5f, gViewerWindow->getWindowDisplayHeight() * 0.5f);
- LLVector2 delta_from_center(screen_pos.mX - window_center.mV[VX],
- screen_pos.mY - window_center.mV[VY]);
- delta_from_center.normVec();
-
- F32 camera_aspect = LLViewerCamera::getInstance()->getAspect();
- F32 delta_aspect = llabs(delta_from_center.mV[VX] / delta_from_center.mV[VY]);
- if (camera_aspect / llmax(delta_aspect, 0.001f) > 1.f)
- {
- // camera has wider aspect ratio than offset vector, so clamp to height
- delta_from_center *= llabs(window_center.mV[VY] / delta_from_center.mV[VY]);
- }
- else
- {
- // camera has narrower aspect ratio than offset vector, so clamp to width
- delta_from_center *= llabs(window_center.mV[VX] / delta_from_center.mV[VX]);
- }
-
- screen_pos_vec = window_center + delta_from_center;
- }
- else
- {
- screen_pos_vec.setVec((F32)screen_pos.mX, (F32)screen_pos.mY);
- }
- S32 bottom = STATUS_BAR_HEIGHT;
- if (gChatBar->getVisible())
- {
- bottom += CHAT_BAR_HEIGHT;
+ LLViewerCamera::getInstance()->projectPosAgentToScreenEdge(world_pos, screen_pos);
}
+ screen_pos_vec.setVec((F32)screen_pos.mX, (F32)screen_pos.mY);
+
+ LLRect world_rect = gViewerWindow->getVirtualWorldViewRect();
+ S32 bottom = world_rect.mBottom + STATUS_BAR_HEIGHT;
+
LLVector2 screen_center;
- screen_center.mV[VX] = llclamp((F32)screen_pos_vec.mV[VX], mWidth * 0.5f, (F32)gViewerWindow->getWindowDisplayWidth() - mWidth * 0.5f);
+ screen_center.mV[VX] = llclamp((F32)screen_pos_vec.mV[VX], (F32)world_rect.mLeft + mWidth * 0.5f, (F32)world_rect.mRight - mWidth * 0.5f);
if(mVertAlignment == ALIGN_VERT_TOP)
{
screen_center.mV[VY] = llclamp((F32)screen_pos_vec.mV[VY],
(F32)bottom,
- (F32)gViewerWindow->getWindowDisplayHeight() - mHeight - (F32)MENU_BAR_HEIGHT);
+ (F32)world_rect.mTop - mHeight - (F32)MENU_BAR_HEIGHT);
mSoftScreenRect.setLeftTopAndSize(screen_center.mV[VX] - (mWidth + BUFFER_SIZE) * 0.5f,
screen_center.mV[VY] + (mHeight + BUFFER_SIZE), mWidth + BUFFER_SIZE, mHeight + BUFFER_SIZE);
}
@@ -842,7 +818,7 @@ LLVector2 LLHUDText::updateScreenPos(LLVector2 &offset)
{
screen_center.mV[VY] = llclamp((F32)screen_pos_vec.mV[VY],
(F32)bottom + mHeight * 0.5f,
- (F32)gViewerWindow->getWindowDisplayHeight() - mHeight * 0.5f - (F32)MENU_BAR_HEIGHT);
+ (F32)world_rect.mTop - mHeight * 0.5f - (F32)MENU_BAR_HEIGHT);
mSoftScreenRect.setCenterAndSize(screen_center.mV[VX], screen_center.mV[VY], mWidth + BUFFER_SIZE, mHeight + BUFFER_SIZE);
}
@@ -981,7 +957,7 @@ void LLHUDText::updateAll()
{
continue;
}
- if (src_textp->mSoftScreenRect.rectInRect(&dst_textp->mSoftScreenRect))
+ if (src_textp->mSoftScreenRect.overlaps(dst_textp->mSoftScreenRect))
{
LLRectf intersect_rect = src_textp->mSoftScreenRect;
intersect_rect.intersectWith(dst_textp->mSoftScreenRect);
diff --git a/indra/newview/llhudtext.h b/indra/newview/llhudtext.h
index 645cbc2698..dc14a8c764 100644
--- a/indra/newview/llhudtext.h
+++ b/indra/newview/llhudtext.h
@@ -33,7 +33,7 @@
#ifndef LL_LLHUDTEXT_H
#define LL_LLHUDTEXT_H
-#include "llmemory.h"
+#include "llpointer.h"
#include "lldarrayptr.h"
#include "llhudobject.h"
diff --git a/indra/newview/llhudview.cpp b/indra/newview/llhudview.cpp
index 198514ce0c..027cd2ab07 100644
--- a/indra/newview/llhudview.cpp
+++ b/indra/newview/llhudview.cpp
@@ -39,31 +39,36 @@
#include "llcoord.h"
// viewer includes
-#include "llagent.h"
#include "llcallingcard.h"
-#include "llcolorscheme.h"
#include "llviewercontrol.h"
#include "llfloaterworldmap.h"
#include "llworldmapview.h"
#include "lltracker.h"
#include "llviewercamera.h"
#include "llui.h"
+#include "lluictrlfactory.h"
LLHUDView *gHUDView = NULL;
const S32 HUD_ARROW_SIZE = 32;
-LLHUDView::LLHUDView()
-: LLPanel()
-{ }
+
+
+LLHUDView::LLHUDView(const LLRect& r)
+{
+ LLUICtrlFactory::getInstance()->buildPanel(this, "panel_hud.xml");
+ setShape(r, true);
+}
LLHUDView::~LLHUDView()
-{ }
+{
+}
// virtual
void LLHUDView::draw()
{
LLTracker::drawHUDArrow();
+ LLView::draw();
}
@@ -89,4 +94,3 @@ BOOL LLHUDView::handleMouseDown(S32 x, S32 y, MASK mask)
}
return LLView::handleMouseDown(x, y, mask);
}
-
diff --git a/indra/newview/llhudview.h b/indra/newview/llhudview.h
index 7859e7f8be..05ff9c8596 100644
--- a/indra/newview/llhudview.h
+++ b/indra/newview/llhudview.h
@@ -42,7 +42,7 @@ class LLHUDView
: public LLPanel
{
public:
- LLHUDView();
+ LLHUDView(const LLRect& rect);
virtual ~LLHUDView();
virtual void draw();
diff --git a/indra/newview/llimhandler.cpp b/indra/newview/llimhandler.cpp
new file mode 100644
index 0000000000..0262e40803
--- /dev/null
+++ b/indra/newview/llimhandler.cpp
@@ -0,0 +1,127 @@
+/**
+ * @file llimhandler.cpp
+ * @brief Notification Handler Class for IM notifications
+ *
+ * $LicenseInfo:firstyear=2000&license=viewergpl$
+ *
+ * Copyright (c) 2000-2009, Linden Research, Inc.
+ *
+ * Second Life Viewer Source Code
+ * The source code in this file ("Source Code") is provided by Linden Lab
+ * to you under the terms of the GNU General Public License, version 2.0
+ * ("GPL"), unless you have obtained a separate licensing agreement
+ * ("Other License"), formally executed by you and Linden Lab. Terms of
+ * the GPL can be found in doc/GPL-license.txt in this distribution, or
+ * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
+ *
+ * There are special exceptions to the terms and conditions of the GPL as
+ * it is applied to this Source Code. View the full text of the exception
+ * in the file doc/FLOSS-exception.txt in this software distribution, or
+ * online at
+ * http://secondlifegrid.net/programs/open_source/licensing/flossexception
+ *
+ * By copying, modifying or distributing this software, you acknowledge
+ * that you have read and understood your obligations described above,
+ * and agree to abide by those obligations.
+ *
+ * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+ * COMPLETENESS OR PERFORMANCE.
+ * $/LicenseInfo$
+ */
+
+
+#include "llviewerprecompiledheaders.h" // must be first include
+
+#include "llnotificationhandler.h"
+
+#include "llbottomtray.h"
+#include "llviewercontrol.h"
+#include "lltoastimpanel.h"
+
+using namespace LLNotificationsUI;
+
+//--------------------------------------------------------------------------
+LLIMHandler::LLIMHandler()
+{
+
+ // getting a Chiclet and creating params for a channel
+ LLBottomTray* tray = LLBottomTray::getInstance();
+ mChiclet = tray->getSysWell();
+
+ LLChannelManager::Params p;
+ // *TODO: createNotificationChannel method
+ p.id = LLUUID(gSavedSettings.getString("NotificationChannelUUID"));
+ p.channel_right_bound = tray->getRect().mRight - gSavedSettings.getS32("NotificationChannelRightMargin");
+ p.channel_width = gSavedSettings.getS32("NotifyBoxWidth");
+
+ // Getting a Channel for our notifications
+ mChannel = LLChannelManager::getInstance()->createChannel(p);
+
+}
+
+//--------------------------------------------------------------------------
+LLIMHandler::~LLIMHandler()
+{
+}
+
+//--------------------------------------------------------------------------
+void LLIMHandler::processNotification(const LLSD& notify)
+{
+ LLNotificationPtr notification = LLNotifications::instance().find(notify["id"].asUUID());
+
+ if(!notification)
+ return;
+
+ if(notify["sigtype"].asString() == "add" || notify["sigtype"].asString() == "change")
+ {
+ LLSD substitutions = notification->getSubstitutions();
+
+ LLToastIMPanel::Params im_p;
+ im_p.notification = notification;
+ im_p.avatar_id = substitutions["FROM_ID"].asUUID();
+ im_p.from = substitutions["FROM"].asString();
+ im_p.time = substitutions["TIME"].asString();
+ im_p.message = substitutions["MESSAGE"].asString();
+ im_p.session_id = substitutions["SESSION_ID"].asUUID();
+
+ LLToastIMPanel* im_box = new LLToastIMPanel(im_p);
+
+ LLToast::Params p;
+ p.id = notification->getID();
+ p.notification = notification;
+ p.panel = im_box;
+ p.can_be_stored = false;
+ p.on_toast_destroy = boost::bind(&LLIMHandler::onToastDestroy, this, _1);
+ mChannel->addToast(p);
+
+
+ static_cast<LLNotificationChiclet*>(mChiclet)->updateUreadIMNotifications();
+ }
+ else if (notify["sigtype"].asString() == "delete")
+ {
+ mChannel->killToastByNotificationID(notification->getID());
+ }
+}
+
+//--------------------------------------------------------------------------
+void LLIMHandler::onToastDestroy(LLToast* toast)
+{
+ toast->closeFloater();
+ static_cast<LLNotificationChiclet*>(mChiclet)->updateUreadIMNotifications();
+}
+
+//--------------------------------------------------------------------------
+void LLIMHandler::onChicletClick(void)
+{
+}
+
+//--------------------------------------------------------------------------
+void LLIMHandler::onChicletClose(void)
+{
+}
+
+//--------------------------------------------------------------------------
+
+
+
diff --git a/indra/newview/llimpanel.cpp b/indra/newview/llimpanel.cpp
index 0586409283..9cf3e57e22 100644
--- a/indra/newview/llimpanel.cpp
+++ b/indra/newview/llimpanel.cpp
@@ -35,6 +35,7 @@
#include "llimpanel.h"
#include "indra_constants.h"
+#include "llfloaterreg.h"
#include "llfocusmgr.h"
#include "llfontgl.h"
#include "llrect.h"
@@ -45,22 +46,29 @@
#include "llagent.h"
#include "llbutton.h"
+#include "llbottomtray.h"
#include "llcallingcard.h"
#include "llchat.h"
+#include "llchiclet.h"
#include "llconsole.h"
+#include "llgroupactions.h"
#include "llfloater.h"
-#include "llfloatergroupinfo.h"
+#include "llfloatercall.h"
+#include "llavataractions.h"
#include "llimview.h"
#include "llinventory.h"
#include "llinventorymodel.h"
-#include "llinventoryview.h"
-#include "llfloateractivespeakers.h"
-#include "llfloateravatarinfo.h"
+#include "llfloaterinventory.h"
#include "llfloaterchat.h"
+#include "lliconctrl.h"
+#include "llimview.h" // for LLIMModel to get other avatar id in chat
#include "llkeyboard.h"
#include "lllineeditor.h"
#include "llnotify.h"
+#include "llpanelimcontrolpanel.h"
+#include "llrecentpeople.h"
#include "llresmgr.h"
+#include "lltrans.h"
#include "lltabcontainer.h"
#include "llviewertexteditor.h"
#include "llviewermessage.h"
@@ -69,7 +77,6 @@
#include "lluictrlfactory.h"
#include "llviewerwindow.h"
#include "lllogchat.h"
-#include "llfloaterhtml.h"
#include "llweb.h"
#include "llhttpclient.h"
#include "llmutelist.h"
@@ -98,190 +105,7 @@ LLVoiceChannel* LLVoiceChannel::sSuspendedVoiceChannel = NULL;
BOOL LLVoiceChannel::sSuspended = FALSE;
-void session_starter_helper(
- const LLUUID& temp_session_id,
- const LLUUID& other_participant_id,
- EInstantMessage im_type)
-{
- LLMessageSystem *msg = gMessageSystem;
-
- msg->newMessageFast(_PREHASH_ImprovedInstantMessage);
- msg->nextBlockFast(_PREHASH_AgentData);
- msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
- msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
-
- msg->nextBlockFast(_PREHASH_MessageBlock);
- msg->addBOOLFast(_PREHASH_FromGroup, FALSE);
- msg->addUUIDFast(_PREHASH_ToAgentID, other_participant_id);
- msg->addU8Fast(_PREHASH_Offline, IM_ONLINE);
- msg->addU8Fast(_PREHASH_Dialog, im_type);
- msg->addUUIDFast(_PREHASH_ID, temp_session_id);
- msg->addU32Fast(_PREHASH_Timestamp, NO_TIMESTAMP); // no timestamp necessary
-
- std::string name;
- gAgent.buildFullname(name);
-
- msg->addStringFast(_PREHASH_FromAgentName, name);
- msg->addStringFast(_PREHASH_Message, LLStringUtil::null);
- msg->addU32Fast(_PREHASH_ParentEstateID, 0);
- msg->addUUIDFast(_PREHASH_RegionID, LLUUID::null);
- msg->addVector3Fast(_PREHASH_Position, gAgent.getPositionAgent());
-}
-
-void start_deprecated_conference_chat(
- const LLUUID& temp_session_id,
- const LLUUID& creator_id,
- const LLUUID& other_participant_id,
- const LLSD& agents_to_invite)
-{
- U8* bucket;
- U8* pos;
- S32 count;
- S32 bucket_size;
-
- // *FIX: this could suffer from endian issues
- count = agents_to_invite.size();
- bucket_size = UUID_BYTES * count;
- bucket = new U8[bucket_size];
- pos = bucket;
-
- for(S32 i = 0; i < count; ++i)
- {
- LLUUID agent_id = agents_to_invite[i].asUUID();
-
- memcpy(pos, &agent_id, UUID_BYTES);
- pos += UUID_BYTES;
- }
-
- session_starter_helper(
- temp_session_id,
- other_participant_id,
- IM_SESSION_CONFERENCE_START);
-
- gMessageSystem->addBinaryDataFast(
- _PREHASH_BinaryBucket,
- bucket,
- bucket_size);
-
- gAgent.sendReliableMessage();
-
- delete[] bucket;
-}
-
-class LLStartConferenceChatResponder : public LLHTTPClient::Responder
-{
-public:
- LLStartConferenceChatResponder(
- const LLUUID& temp_session_id,
- const LLUUID& creator_id,
- const LLUUID& other_participant_id,
- const LLSD& agents_to_invite)
- {
- mTempSessionID = temp_session_id;
- mCreatorID = creator_id;
- mOtherParticipantID = other_participant_id;
- mAgents = agents_to_invite;
- }
-
- virtual void error(U32 statusNum, const std::string& reason)
- {
- //try an "old school" way.
- if ( statusNum == 400 )
- {
- start_deprecated_conference_chat(
- mTempSessionID,
- mCreatorID,
- mOtherParticipantID,
- mAgents);
- }
-
- //else throw an error back to the client?
- //in theory we should have just have these error strings
- //etc. set up in this file as opposed to the IMMgr,
- //but the error string were unneeded here previously
- //and it is not worth the effort switching over all
- //the possible different language translations
- }
-
-private:
- LLUUID mTempSessionID;
- LLUUID mCreatorID;
- LLUUID mOtherParticipantID;
-
- LLSD mAgents;
-};
-
-// Returns true if any messages were sent, false otherwise.
-// Is sort of equivalent to "does the server need to do anything?"
-bool send_start_session_messages(
- const LLUUID& temp_session_id,
- const LLUUID& other_participant_id,
- const LLDynamicArray<LLUUID>& ids,
- EInstantMessage dialog)
-{
- if ( dialog == IM_SESSION_GROUP_START )
- {
- session_starter_helper(
- temp_session_id,
- other_participant_id,
- dialog);
-
- switch(dialog)
- {
- case IM_SESSION_GROUP_START:
- gMessageSystem->addBinaryDataFast(
- _PREHASH_BinaryBucket,
- EMPTY_BINARY_BUCKET,
- EMPTY_BINARY_BUCKET_SIZE);
- break;
- default:
- break;
- }
- gAgent.sendReliableMessage();
-
- return true;
- }
- else if ( dialog == IM_SESSION_CONFERENCE_START )
- {
- LLSD agents;
- for (int i = 0; i < (S32) ids.size(); i++)
- {
- agents.append(ids.get(i));
- }
- //we have a new way of starting conference calls now
- LLViewerRegion* region = gAgent.getRegion();
- if (region)
- {
- std::string url = region->getCapability(
- "ChatSessionRequest");
- LLSD data;
- data["method"] = "start conference";
- data["session-id"] = temp_session_id;
-
- data["params"] = agents;
-
- LLHTTPClient::post(
- url,
- data,
- new LLStartConferenceChatResponder(
- temp_session_id,
- gAgent.getID(),
- other_participant_id,
- data["params"]));
- }
- else
- {
- start_deprecated_conference_chat(
- temp_session_id,
- gAgent.getID(),
- other_participant_id,
- agents);
- }
- }
-
- return false;
-}
class LLVoiceCallCapResponder : public LLHTTPClient::Responder
{
@@ -587,7 +411,6 @@ LLVoiceChannel* LLVoiceChannel::getChannelByURI(std::string uri)
}
}
-
void LLVoiceChannel::updateSessionID(const LLUUID& new_session_id)
{
sVoiceChannelMap.erase(sVoiceChannelMap.find(mSessionID));
@@ -622,6 +445,21 @@ void LLVoiceChannel::setState(EState state)
mState = state;
}
+void LLVoiceChannel::toggleCallWindowIfNeeded(EState state)
+{
+ if (state == STATE_CONNECTED)
+ {
+ LLFloaterReg::showInstance("voice_call", mSessionID);
+ }
+ // By checking that current state is CONNECTED we make sure that the call window
+ // has been shown, hence there's something to hide. This helps when user presses
+ // the "End call" button right after initiating the call.
+ // *TODO: move this check to LLFloaterCall?
+ else if (state == STATE_HUNG_UP && mState == STATE_CONNECTED)
+ {
+ LLFloaterReg::hideInstance("voice_call", mSessionID);
+ }
+}
//static
void LLVoiceChannel::initClass()
@@ -693,6 +531,15 @@ void LLVoiceChannelGroup::activate()
LLVoiceClient::getInstance()->setNonSpatialChannel(
mURI,
mCredentials);
+
+#if 0 // *TODO
+ if (!gAgent.isInGroup(mSessionID)) // ad-hoc channel
+ {
+ // Add the party to the list of people with which we've recently interacted.
+ for (/*people in the chat*/)
+ LLRecentPeople::instance().add(buddy_id);
+ }
+#endif
}
}
@@ -814,6 +661,9 @@ void LLVoiceChannelGroup::handleError(EStatusType status)
void LLVoiceChannelGroup::setState(EState state)
{
+ // HACK: Open/close the call window if needed.
+ toggleCallWindowIfNeeded(state);
+
switch(state)
{
case STATE_RINGING:
@@ -999,6 +849,9 @@ void LLVoiceChannelP2P::activate()
// using the session handle invalidates it. Clear it out here so we can't reuse it by accident.
mSessionHandle.clear();
}
+
+ // Add the party to the list of people with which we've recently interacted.
+ LLRecentPeople::instance().add(mOtherUserID);
}
}
@@ -1056,6 +909,9 @@ void LLVoiceChannelP2P::setSessionHandle(const std::string& handle, const std::s
void LLVoiceChannelP2P::setState(EState state)
{
+ // HACK: Open/close the call window if needed.
+ toggleCallWindowIfNeeded(state);
+
// you only "answer" voice invites in p2p mode
// so provide a special purpose message here
if (mReceivedCall && state == STATE_RINGING)
@@ -1071,57 +927,28 @@ void LLVoiceChannelP2P::setState(EState state)
//
// LLFloaterIMPanel
//
-LLFloaterIMPanel::LLFloaterIMPanel(
- const std::string& session_label,
- const LLUUID& session_id,
- const LLUUID& other_participant_id,
- EInstantMessage dialog) :
- LLFloater(session_label, LLRect(), session_label),
- mInputEditor(NULL),
- mHistoryEditor(NULL),
- mSessionUUID(session_id),
- mVoiceChannel(NULL),
- mSessionInitialized(FALSE),
- mSessionStartMsgPos(0),
- mOtherParticipantUUID(other_participant_id),
- mDialog(dialog),
- mTyping(FALSE),
- mOtherTyping(FALSE),
- mTypingLineStartIndex(0),
- mSentTypingState(TRUE),
- mNumUnreadMessages(0),
- mShowSpeakersOnConnect(TRUE),
- mAutoConnect(FALSE),
- mTextIMPossible(TRUE),
- mProfileButtonEnabled(TRUE),
- mCallBackEnabled(TRUE),
- mSpeakers(NULL),
- mSpeakerPanel(NULL),
- mFirstKeystrokeTimer(),
- mLastKeystrokeTimer()
-{
- init(session_label);
-}
-LLFloaterIMPanel::LLFloaterIMPanel(
- const std::string& session_label,
- const LLUUID& session_id,
- const LLUUID& other_participant_id,
- const LLDynamicArray<LLUUID>& ids,
- EInstantMessage dialog) :
- LLFloater(session_label, LLRect(), session_label),
+LLFloaterIMPanel::LLFloaterIMPanel(const std::string& session_label,
+ const LLUUID& session_id,
+ const LLUUID& other_participant_id,
+ const std::vector<LLUUID>& ids,
+ EInstantMessage dialog)
+: LLFloater(session_id),
mInputEditor(NULL),
mHistoryEditor(NULL),
mSessionUUID(session_id),
+ mSessionLabel(session_label),
mVoiceChannel(NULL),
mSessionInitialized(FALSE),
mSessionStartMsgPos(0),
mOtherParticipantUUID(other_participant_id),
mDialog(dialog),
+ mSessionInitialTargetIDs(ids),
mTyping(FALSE),
mOtherTyping(FALSE),
mTypingLineStartIndex(0),
mSentTypingState(TRUE),
+ mNumUnreadMessages(0),
mShowSpeakersOnConnect(TRUE),
mAutoConnect(FALSE),
mTextIMPossible(TRUE),
@@ -1132,15 +959,6 @@ LLFloaterIMPanel::LLFloaterIMPanel(
mFirstKeystrokeTimer(),
mLastKeystrokeTimer()
{
- mSessionInitialTargetIDs = ids;
- init(session_label);
-}
-
-
-void LLFloaterIMPanel::init(const std::string& session_label)
-{
- mSessionLabel = session_label;
-
std::string xml_filename;
switch(mDialog)
{
@@ -1188,11 +1006,10 @@ void LLFloaterIMPanel::init(const std::string& session_label)
}
mSpeakers = new LLIMSpeakerMgr(mVoiceChannel);
+ // All participants will be added to the list of people we've recently interacted with.
+ mSpeakers->addListener(&LLRecentPeople::instance(), "add");
- LLUICtrlFactory::getInstance()->buildFloater(this,
- xml_filename,
- &getFactoryMap(),
- FALSE);
+ LLUICtrlFactory::getInstance()->buildFloater(this, xml_filename, NULL);
setTitle(mSessionLabel);
mInputEditor->setMaxTextLength(1023);
@@ -1208,7 +1025,7 @@ void LLFloaterIMPanel::init(const std::string& session_label)
if ( !mSessionInitialized )
{
- if ( !send_start_session_messages(
+ if ( !LLIMModel::instance().sendStartSession(
mSessionUUID,
mOtherParticipantUUID,
mSessionInitialTargetIDs,
@@ -1230,7 +1047,7 @@ void LLFloaterIMPanel::init(const std::string& session_label)
addHistoryLine(
session_start,
- gSavedSettings.getColor4("SystemChatColor"),
+ LLUIColorTable::instance().getColor("SystemChatColor"),
false);
}
}
@@ -1275,67 +1092,62 @@ LLFloaterIMPanel::~LLFloaterIMPanel()
BOOL LLFloaterIMPanel::postBuild()
{
- requires<LLLineEditor>("chat_editor");
- requires<LLTextEditor>("im_history");
-
- if (checkRequirements())
- {
- mInputEditor = getChild<LLLineEditor>("chat_editor");
- mInputEditor->setFocusReceivedCallback( onInputEditorFocusReceived, this );
- mInputEditor->setFocusLostCallback( onInputEditorFocusLost, this );
- mInputEditor->setKeystrokeCallback( onInputEditorKeystroke );
- mInputEditor->setCommitCallback( onCommitChat );
- mInputEditor->setCallbackUserData(this);
- mInputEditor->setCommitOnFocusLost( FALSE );
- mInputEditor->setRevertOnEsc( FALSE );
- mInputEditor->setReplaceNewlinesWithSpaces( FALSE );
+ mCloseSignal.connect(boost::bind(&LLFloaterIMPanel::onClose, this));
+
+ mVisibleSignal.connect(boost::bind(&LLFloaterIMPanel::onVisibilityChange, this, _2));
+
+ mInputEditor = getChild<LLLineEditor>("chat_editor");
+ mInputEditor->setFocusReceivedCallback( onInputEditorFocusReceived, this );
+ mInputEditor->setFocusLostCallback( onInputEditorFocusLost, this );
+ mInputEditor->setKeystrokeCallback( onInputEditorKeystroke, this );
+ mInputEditor->setCommitCallback( onCommitChat, this );
+ mInputEditor->setCommitOnFocusLost( FALSE );
+ mInputEditor->setRevertOnEsc( FALSE );
+ mInputEditor->setReplaceNewlinesWithSpaces( FALSE );
- childSetAction("profile_callee_btn", onClickProfile, this);
- childSetAction("group_info_btn", onClickGroupInfo, this);
+ childSetAction("profile_callee_btn", onClickProfile, this);
+ childSetAction("group_info_btn", onClickGroupInfo, this);
- childSetAction("start_call_btn", onClickStartCall, this);
- childSetAction("end_call_btn", onClickEndCall, this);
- childSetAction("send_btn", onClickSend, this);
- childSetAction("toggle_active_speakers_btn", onClickToggleActiveSpeakers, this);
+ childSetAction("start_call_btn", onClickStartCall, this);
+ childSetAction("end_call_btn", onClickEndCall, this);
+ childSetAction("send_btn", onClickSend, this);
+ childSetAction("toggle_active_speakers_btn", onClickToggleActiveSpeakers, this);
- childSetAction("moderator_kick_speaker", onKickSpeaker, this);
- //LLButton* close_btn = getChild<LLButton>("close_btn");
- //close_btn->setClickedCallback(&LLFloaterIMPanel::onClickClose, this);
+ childSetAction("moderator_kick_speaker", onKickSpeaker, this);
+ //LLButton* close_btn = getChild<LLButton>("close_btn");
+ //close_btn->setClickedCallback(&LLFloaterIMPanel::onClickClose, this);
- mHistoryEditor = getChild<LLViewerTextEditor>("im_history");
- mHistoryEditor->setParseHTML(TRUE);
- mHistoryEditor->setParseHighlights(TRUE);
+ mHistoryEditor = getChild<LLViewerTextEditor>("im_history");
+ mHistoryEditor->setParseHTML(TRUE);
+ mHistoryEditor->setParseHighlights(TRUE);
- if ( IM_SESSION_GROUP_START == mDialog )
- {
- childSetEnabled("profile_btn", FALSE);
- }
-
- if(!mProfileButtonEnabled)
- {
- childSetEnabled("profile_callee_btn", FALSE);
- }
-
- sTitleString = getString("title_string");
- sTypingStartString = getString("typing_start_string");
- sSessionStartString = getString("session_start_string");
+ if ( IM_SESSION_GROUP_START == mDialog )
+ {
+ childSetEnabled("profile_btn", FALSE);
+ }
+
+ if(!mProfileButtonEnabled)
+ {
+ childSetEnabled("profile_callee_btn", FALSE);
+ }
- if (mSpeakerPanel)
- {
- mSpeakerPanel->refreshSpeakers();
- }
+ sTitleString = getString("title_string");
+ sTypingStartString = getString("typing_start_string");
+ sSessionStartString = getString("session_start_string");
- if (mDialog == IM_NOTHING_SPECIAL)
- {
- childSetAction("mute_btn", onClickMuteVoice, this);
- childSetCommitCallback("speaker_volume", onVolumeChange, this);
- }
+ if (mSpeakerPanel)
+ {
+ mSpeakerPanel->refreshSpeakers();
+ }
- setDefaultBtn("send_btn");
- return TRUE;
+ if (mDialog == IM_NOTHING_SPECIAL)
+ {
+ childSetAction("mute_btn", onClickMuteVoice, this);
+ childSetCommitCallback("speaker_volume", onVolumeChange, this);
}
- return FALSE;
+ setDefaultBtn("send_btn");
+ return TRUE;
}
void* LLFloaterIMPanel::createSpeakersPanel(void* data)
@@ -1479,7 +1291,7 @@ private:
LLUUID mSessionID;
};
-BOOL LLFloaterIMPanel::inviteToSession(const LLDynamicArray<LLUUID>& ids)
+BOOL LLFloaterIMPanel::inviteToSession(const std::vector<LLUUID>& ids)
{
LLViewerRegion* region = gAgent.getRegion();
if (!region)
@@ -1487,7 +1299,7 @@ BOOL LLFloaterIMPanel::inviteToSession(const LLDynamicArray<LLUUID>& ids)
return FALSE;
}
- S32 count = ids.count();
+ S32 count = ids.size();
if( isInviteAllowed() && (count > 0) )
{
@@ -1500,7 +1312,7 @@ BOOL LLFloaterIMPanel::inviteToSession(const LLDynamicArray<LLUUID>& ids)
data["params"] = LLSD::emptyArray();
for (int i = 0; i < count; i++)
{
- data["params"].append(ids.get(i));
+ data["params"].append(ids[i]);
}
data["method"] = "invite";
@@ -1551,34 +1363,41 @@ void LLFloaterIMPanel::addHistoryLine(const std::string &utf8msg, const LLColor4
prepend_newline = false;
}
+ std::string separator_string(": ");
+
// 'name' is a sender name that we want to hotlink so that clicking on it opens a profile.
if (!name.empty()) // If name exists, then add it to the front of the message.
{
// Don't hotlink any messages from the system (e.g. "Second Life:"), so just add those in plain text.
if (name == SYSTEM_FROM)
{
- mHistoryEditor->appendColoredText(name,false,prepend_newline,color);
+ mHistoryEditor->appendColoredText(name + separator_string, false, prepend_newline, color);
}
else
{
// Convert the name to a hotlink and add to message.
- const LLStyleSP &source_style = LLStyleMap::instance().lookupAgent(source);
- mHistoryEditor->appendStyledText(name,false,prepend_newline,source_style);
+ mHistoryEditor->appendStyledText(name + separator_string, false, prepend_newline, LLStyleMap::instance().lookupAgent(source));
}
prepend_newline = false;
}
mHistoryEditor->appendColoredText(utf8msg, false, prepend_newline, color);
-
- if (log_to_file
- && gSavedPerAccountSettings.getBOOL("LogInstantMessages") )
+ S32 im_log_option = gSavedPerAccountSettings.getS32("IMLogOptions");
+ if (log_to_file && (im_log_option!=LOG_CHAT))
{
std::string histstr;
- if (gSavedPerAccountSettings.getBOOL("IMLogTimestamp"))
- histstr = LLLogChat::timestamp(gSavedPerAccountSettings.getBOOL("LogTimestampDate")) + name + utf8msg;
+ if (gSavedPerAccountSettings.getBOOL("LogTimestamp"))
+ histstr = LLLogChat::timestamp(gSavedPerAccountSettings.getBOOL("LogTimestampDate")) + name + separator_string + utf8msg;
else
- histstr = name + utf8msg;
+ histstr = name + separator_string + utf8msg;
- LLLogChat::saveHistory(getTitle(),histstr);
+ if(im_log_option==LOG_BOTH_TOGETHER)
+ {
+ LLLogChat::saveHistory(std::string("chat"),histstr);
+ }
+ else
+ {
+ LLLogChat::saveHistory(getTitle(),histstr);
+ }
}
if (!isInVisibleChain())
@@ -1594,24 +1413,6 @@ void LLFloaterIMPanel::addHistoryLine(const std::string &utf8msg, const LLColor4
}
-void LLFloaterIMPanel::setVisible(BOOL b)
-{
- LLPanel::setVisible(b);
-
- LLMultiFloater* hostp = getHost();
- if( b && hostp )
- {
- hostp->setFloaterFlashing(this, FALSE);
-
- /* Don't change containing floater title - leave it "Instant Message" JC
- LLUIString title = sTitleString;
- title.setArg("[NAME]", mSessionLabel);
- hostp->setTitle( title );
- */
- }
-}
-
-
void LLFloaterIMPanel::setInputFocus( BOOL b )
{
mInputEditor->setFocus( b );
@@ -1629,7 +1430,6 @@ void LLFloaterIMPanel::selectNone()
mInputEditor->deselect();
}
-
BOOL LLFloaterIMPanel::handleKeyHere( KEY key, MASK mask )
{
BOOL handled = FALSE;
@@ -1637,24 +1437,11 @@ BOOL LLFloaterIMPanel::handleKeyHere( KEY key, MASK mask )
{
sendMsg();
handled = TRUE;
-
- // Close talk panels on hitting return
- // but not shift-return or control-return
- if ( !gSavedSettings.getBOOL("PinTalkViewOpen") && !(mask & MASK_CONTROL) && !(mask & MASK_SHIFT) )
- {
- gIMMgr->toggle(NULL);
- }
}
else if ( KEY_ESCAPE == key )
{
handled = TRUE;
gFocusMgr.setKeyboardFocus(NULL);
-
- // Close talk panel with escape
- if( !gSavedSettings.getBOOL("PinTalkViewOpen") )
- {
- gIMMgr->toggle(NULL);
- }
}
// May need to call base class LLPanel::handleKeyHere if not handled
@@ -1705,8 +1492,8 @@ BOOL LLFloaterIMPanel::dropCallingCard(LLInventoryItem* item, BOOL drop)
{
if(drop)
{
- LLDynamicArray<LLUUID> ids;
- ids.put(item->getCreatorUUID());
+ std::vector<LLUUID> ids;
+ ids.push_back(item->getCreatorUUID());
inviteToSession(ids);
}
}
@@ -1738,10 +1525,11 @@ BOOL LLFloaterIMPanel::dropCategory(LLInventoryCategory* category, BOOL drop)
}
else if(drop)
{
- LLDynamicArray<LLUUID> ids;
+ std::vector<LLUUID> ids;
+ ids.reserve(count);
for(S32 i = 0; i < count; ++i)
{
- ids.put(items.get(i)->getCreatorUUID());
+ ids.push_back(items.get(i)->getCreatorUUID());
}
inviteToSession(ids);
}
@@ -1771,9 +1559,9 @@ void LLFloaterIMPanel::onClickProfile( void* userdata )
// Bring up the Profile window
LLFloaterIMPanel* self = (LLFloaterIMPanel*) userdata;
- if (self->mOtherParticipantUUID.notNull())
+ if (self->getOtherParticipantID().notNull())
{
- LLFloaterAvatarInfo::showFromDirectory(self->getOtherParticipantID());
+ LLAvatarActions::showProfile(self->getOtherParticipantID());
}
}
@@ -1783,7 +1571,8 @@ void LLFloaterIMPanel::onClickGroupInfo( void* userdata )
// Bring up the Profile window
LLFloaterIMPanel* self = (LLFloaterIMPanel*) userdata;
- LLFloaterGroupInfo::showFromUUID(self->mSessionUUID);
+ LLGroupActions::show(self->mSessionUUID);
+
}
// static
@@ -1792,7 +1581,7 @@ void LLFloaterIMPanel::onClickClose( void* userdata )
LLFloaterIMPanel* self = (LLFloaterIMPanel*) userdata;
if(self)
{
- self->close();
+ self->closeFloater();
}
}
@@ -1864,108 +1653,29 @@ void LLFloaterIMPanel::onInputEditorKeystroke(LLLineEditor* caller, void* userda
}
}
-void LLFloaterIMPanel::onClose(bool app_quitting)
+void LLFloaterIMPanel::onClose()
{
setTyping(FALSE);
- if(mSessionUUID.notNull())
- {
- std::string name;
- gAgent.buildFullname(name);
- pack_instant_message(
- gMessageSystem,
- gAgent.getID(),
- FALSE,
- gAgent.getSessionID(),
- mOtherParticipantUUID,
- name,
- LLStringUtil::null,
- IM_ONLINE,
- IM_SESSION_LEAVE,
- mSessionUUID);
- gAgent.sendReliableMessage();
- }
+ LLIMModel::instance().sendLeaveSession(mSessionUUID, mOtherParticipantUUID);
+
gIMMgr->removeSession(mSessionUUID);
- destroy();
+ // *HACK hide the voice floater
+ LLFloaterReg::hideInstance("voice_call", mSessionUUID);
}
-void LLFloaterIMPanel::onVisibilityChange(BOOL new_visibility)
+void LLFloaterIMPanel::onVisibilityChange(const LLSD& new_visibility)
{
- if (new_visibility)
+ if (new_visibility.asBoolean())
{
mNumUnreadMessages = 0;
}
-}
-
-void deliver_message(const std::string& utf8_text,
- const LLUUID& im_session_id,
- const LLUUID& other_participant_id,
- EInstantMessage dialog)
-{
- std::string name;
- bool sent = false;
- gAgent.buildFullname(name);
-
- const LLRelationship* info = NULL;
- info = LLAvatarTracker::instance().getBuddyInfo(other_participant_id);
-
- U8 offline = (!info || info->isOnline()) ? IM_ONLINE : IM_OFFLINE;
-
- if((offline == IM_OFFLINE) && (LLVoiceClient::getInstance()->isOnlineSIP(other_participant_id)))
- {
- // User is online through the OOW connector, but not with a regular viewer. Try to send the message via SLVoice.
- sent = gVoiceClient->sendTextMessage(other_participant_id, utf8_text);
- }
- if(!sent)
- {
- // Send message normally.
-
- // default to IM_SESSION_SEND unless it's nothing special - in
- // which case it's probably an IM to everyone.
- U8 new_dialog = dialog;
-
- if ( dialog != IM_NOTHING_SPECIAL )
- {
- new_dialog = IM_SESSION_SEND;
- }
- pack_instant_message(
- gMessageSystem,
- gAgent.getID(),
- FALSE,
- gAgent.getSessionID(),
- other_participant_id,
- name.c_str(),
- utf8_text.c_str(),
- offline,
- (EInstantMessage)new_dialog,
- im_session_id);
- gAgent.sendReliableMessage();
- }
-
- // If there is a mute list and this is not a group chat...
- if ( LLMuteList::getInstance() )
- {
- // ... the target should not be in our mute list for some message types.
- // Auto-remove them if present.
- switch( dialog )
- {
- case IM_NOTHING_SPECIAL:
- case IM_GROUP_INVITATION:
- case IM_INVENTORY_OFFERED:
- case IM_SESSION_INVITE:
- case IM_SESSION_P2P_INVITE:
- case IM_SESSION_CONFERENCE_START:
- case IM_SESSION_SEND: // This one is marginal - erring on the side of hearing.
- case IM_LURE_USER:
- case IM_GODLIKE_LURE_USER:
- case IM_FRIENDSHIP_OFFERED:
- LLMuteList::getInstance()->autoRemove(other_participant_id, LLMuteList::AR_IM);
- break;
- default: ; // do nothing
- }
- }
+ if (new_visibility.asBoolean() && mVoiceChannel->getState() == LLVoiceChannel::STATE_CONNECTED)
+ LLFloaterReg::showInstance("voice_call", mSessionUUID);
+ else
+ LLFloaterReg::hideInstance("voice_call", mSessionUUID);
}
void LLFloaterIMPanel::sendMsg()
@@ -1989,40 +1699,11 @@ void LLFloaterIMPanel::sendMsg()
if ( mSessionInitialized )
{
- deliver_message(utf8_text,
+ LLIMModel::sendMessage(utf8_text,
mSessionUUID,
mOtherParticipantUUID,
mDialog);
- // local echo
- if((mDialog == IM_NOTHING_SPECIAL) &&
- (mOtherParticipantUUID.notNull()))
- {
- std::string history_echo;
- gAgent.buildFullname(history_echo);
-
- // Look for IRC-style emotes here.
- std::string prefix = utf8_text.substr(0, 4);
- if (prefix == "/me " || prefix == "/me'")
- {
- utf8_text.replace(0,3,"");
- }
- else
- {
- history_echo += ": ";
- }
- history_echo += utf8_text;
-
- BOOL other_was_typing = mOtherTyping;
-
- addHistoryLine(history_echo, gSavedSettings.getColor("IMChatColor"), true, gAgent.getID());
-
- if (other_was_typing)
- {
- addTypingIndicator(mOtherTypingName);
- }
-
- }
}
else
{
@@ -2095,7 +1776,7 @@ void LLFloaterIMPanel::sessionInitReplyReceived(const LLUUID& session_id)
iter != mQueuedMsgsForInit.endArray();
++iter)
{
- deliver_message(
+ LLIMModel::sendMessage(
iter->asString(),
mSessionUUID,
mOtherParticipantUUID,
@@ -2146,23 +1827,10 @@ void LLFloaterIMPanel::sendTypingState(BOOL typing)
// much network traffic. Only send in person-to-person IMs.
if (mDialog != IM_NOTHING_SPECIAL) return;
- std::string name;
- gAgent.buildFullname(name);
-
- pack_instant_message(
- gMessageSystem,
- gAgent.getID(),
- FALSE,
- gAgent.getSessionID(),
- mOtherParticipantUUID,
- name,
- std::string("typing"),
- IM_ONLINE,
- (typing ? IM_TYPING_START : IM_TYPING_STOP),
- mSessionUUID);
- gAgent.sendReliableMessage();
+ LLIMModel::instance().sendTypingState(mSessionUUID, mOtherParticipantUUID, typing);
}
+
void LLFloaterIMPanel::processIMTyping(const LLIMInfo* im_info, BOOL typing)
{
if (typing)
@@ -2186,7 +1854,7 @@ void LLFloaterIMPanel::addTypingIndicator(const std::string &name)
mTypingLineStartIndex = mHistoryEditor->getWText().length();
LLUIString typing_start = sTypingStartString;
typing_start.setArg("[NAME]", name);
- addHistoryLine(typing_start, gSavedSettings.getColor4("SystemChatColor"), false);
+ addHistoryLine(typing_start, LLUIColorTable::instance().getColor("SystemChatColor"), false);
mOtherTypingName = name;
mOtherTyping = TRUE;
}
@@ -2217,21 +1885,21 @@ void LLFloaterIMPanel::chatFromLogFile(LLLogChat::ELogLineType type, std::string
{
LLFloaterIMPanel* self = (LLFloaterIMPanel*)userdata;
std::string message = line;
-
+ S32 im_log_option = gSavedPerAccountSettings.getS32("IMLogOptions");
switch (type)
{
case LLLogChat::LOG_EMPTY:
// add warning log enabled message
- if (gSavedPerAccountSettings.getBOOL("LogInstantMessages"))
+ if (im_log_option!=LOG_CHAT)
{
- message = LLFloaterChat::getInstance()->getString("IM_logging_string");
+ message = LLTrans::getString("IM_logging_string");
}
break;
case LLLogChat::LOG_END:
// add log end message
- if (gSavedPerAccountSettings.getBOOL("LogInstantMessages"))
+ if (im_log_option!=LOG_CHAT)
{
- message = LLFloaterChat::getInstance()->getString("IM_logging_string");
+ message = LLTrans::getString("IM_logging_string");
}
break;
case LLLogChat::LOG_LINE:
@@ -2243,7 +1911,7 @@ void LLFloaterIMPanel::chatFromLogFile(LLLogChat::ELogLineType type, std::string
}
//self->addHistoryLine(line, LLColor4::grey, FALSE);
- self->mHistoryEditor->appendColoredText(message, false, true, LLColor4::grey);
+ self->mHistoryEditor->appendColoredText(message, false, true, LLUIColorTable::instance().getColor("ChatHistoryTextColor"));
}
void LLFloaterIMPanel::showSessionStartError(
@@ -2325,9 +1993,340 @@ bool LLFloaterIMPanel::onConfirmForceCloseError(const LLSD& notification, const
LLFloaterIMPanel* floaterp = gIMMgr->findFloaterBySession(
session_id);
- if ( floaterp ) floaterp->close(FALSE);
+ if ( floaterp ) floaterp->closeFloater(FALSE);
}
return false;
}
+
+
+LLIMFloater::LLIMFloater(const LLUUID& session_id)
+ : LLFloater(session_id),
+ mControlPanel(NULL),
+ mSessionID(session_id),
+ mLastMessageIndex(-1),
+ mLastFromName(),
+ mDialog(IM_NOTHING_SPECIAL),
+ mHistoryEditor(NULL),
+ mInputEditor(NULL),
+ mPositioned(false)
+{
+ LLIMModel::LLIMSession* session = get_if_there(LLIMModel::instance().sSessionsMap, mSessionID, (LLIMModel::LLIMSession*)NULL);
+ if(session)
+ {
+ mDialog = session->mType;
+ }
+
+ if (mDialog == IM_NOTHING_SPECIAL)
+ {
+ mFactoryMap["panel_im_control_panel"] = LLCallbackMap(createPanelIMControl, this);
+ }
+ else
+ {
+ mFactoryMap["panel_im_control_panel"] = LLCallbackMap(createPanelGroupControl, this);
+ }
+// LLUICtrlFactory::getInstance()->buildFloater(this, "floater_im_session.xml");
+}
+
+/* static */
+void LLIMFloater::newIMCallback(const LLSD& data){
+
+ if (data["num_unread"].asInteger() > 0)
+ {
+ LLUUID session_id = data["session_id"].asUUID();
+
+ LLIMFloater* floater = LLFloaterReg::findTypedInstance<LLIMFloater>("impanel", session_id);
+ if (floater == NULL)
+ {
+ llwarns << "new_im_callback for non-existent session_id " << session_id << llendl;
+ return;
+ }
+
+ // update if visible, otherwise will be updated when opened
+ if (floater->getVisible())
+ {
+ floater->updateMessages();
+ }
+ }
+}
+
+void LLIMFloater::onSendMsg( LLUICtrl* ctrl, void* userdata )
+{
+ LLIMFloater* self = (LLIMFloater*) userdata;
+ self->sendMsg();
+}
+
+void LLIMFloater::sendMsg()
+{
+ if (!gAgent.isGodlike()
+ && (mDialog == IM_NOTHING_SPECIAL)
+ && mOtherParticipantUUID.isNull())
+ {
+ llinfos << "Cannot send IM to everyone unless you're a god." << llendl;
+ return;
+ }
+
+ if (mInputEditor)
+ {
+ LLWString text = mInputEditor->getConvertedText();
+ if(!text.empty())
+ {
+ // Truncate and convert to UTF8 for transport
+ std::string utf8_text = wstring_to_utf8str(text);
+ utf8_text = utf8str_truncate(utf8_text, MAX_MSG_BUF_SIZE - 1);
+
+ LLIMModel::sendMessage(utf8_text,
+ mSessionID,
+ mOtherParticipantUUID,
+ mDialog);
+
+ mInputEditor->setText(LLStringUtil::null);
+
+ updateMessages();
+ }
+ }
+}
+
+
+
+LLIMFloater::~LLIMFloater()
+{
+}
+
+//virtual
+BOOL LLIMFloater::postBuild()
+{
+ LLIMModel::LLIMSession* session = get_if_there(LLIMModel::instance().sSessionsMap, mSessionID, (LLIMModel::LLIMSession*)NULL);
+ if(session)
+ {
+ mOtherParticipantUUID = session->mOtherParticipantID;
+ mControlPanel->setID(session->mOtherParticipantID);
+ }
+
+ LLButton* slide_left = getChild<LLButton>("slide_left_btn");
+ slide_left->setVisible(mControlPanel->getVisible());
+ slide_left->setClickedCallback(boost::bind(&LLIMFloater::onSlide, this));
+
+ LLButton* slide_right = getChild<LLButton>("slide_right_btn");
+ slide_right->setVisible(!mControlPanel->getVisible());
+ slide_right->setClickedCallback(boost::bind(&LLIMFloater::onSlide, this));
+
+ mInputEditor = getChild<LLLineEditor>("chat_editor");
+ mInputEditor->setMaxTextLength(1023);
+ // enable line history support for instant message bar
+ mInputEditor->setEnableLineHistory(TRUE);
+
+ mInputEditor->setFocusReceivedCallback( onInputEditorFocusReceived, this );
+ mInputEditor->setFocusLostCallback( onInputEditorFocusLost, this );
+ mInputEditor->setKeystrokeCallback( onInputEditorKeystroke, this );
+ mInputEditor->setCommitOnFocusLost( FALSE );
+ mInputEditor->setRevertOnEsc( FALSE );
+ mInputEditor->setReplaceNewlinesWithSpaces( FALSE );
+
+ childSetCommitCallback("chat_editor", onSendMsg, this);
+
+ mHistoryEditor = getChild<LLViewerTextEditor>("im_text");
+
+ setTitle(LLIMModel::instance().getName(mSessionID));
+ setDocked(true);
+
+ mDockTongue = LLUI::getUIImage("windows/Flyout_Pointer.png");
+
+ return TRUE;
+}
+
+
+
+// static
+void* LLIMFloater::createPanelIMControl(void* userdata)
+{
+ LLIMFloater *self = (LLIMFloater*)userdata;
+ self->mControlPanel = new LLPanelIMControlPanel();
+ self->mControlPanel->setXMLFilename("panel_im_control_panel.xml");
+ return self->mControlPanel;
+}
+
+
+// static
+void* LLIMFloater::createPanelGroupControl(void* userdata)
+{
+ LLIMFloater *self = (LLIMFloater*)userdata;
+ self->mControlPanel = new LLPanelGroupControlPanel();
+ self->mControlPanel->setXMLFilename("panel_group_control_panel.xml");
+ return self->mControlPanel;
+}
+
+
+const U32 UNDOCK_LEAP_HEIGHT = 12;
+const U32 DOCK_ICON_HEIGHT = 6;
+
+//virtual
+void LLIMFloater::onFocusLost()
+{
+ // spec says close if docked to bottom tray and user has clicked away
+ // (hence we are no longer focused)
+ if (isDocked())
+ {
+ LLIMFloater* floater = LLFloaterReg::getTypedInstance<LLIMFloater>("impanel", mSessionID);
+ if (floater)
+ {
+ floater->setVisible(false);
+ }
+ }
+}
+
+
+
+//virtual
+void LLIMFloater::setDocked(bool docked, bool pop_on_undock)
+{
+ LLFloater::setDocked(docked);
+
+ if (!docked && pop_on_undock)
+ {
+ // visually pop up a little bit to emphasize the undocking
+ translate(0, UNDOCK_LEAP_HEIGHT);
+ }
+}
+
+void LLIMFloater::onSlide()
+{
+ LLPanel* im_control_panel = getChild<LLPanel>("panel_im_control_panel");
+ im_control_panel->setVisible(!im_control_panel->getVisible());
+
+ getChild<LLButton>("slide_left_btn")->setVisible(im_control_panel->getVisible());
+ getChild<LLButton>("slide_right_btn")->setVisible(!im_control_panel->getVisible());
+}
+
+//static
+LLIMFloater* LLIMFloater::show(const LLUUID& session_id)
+{
+ //hide all
+ LLFloaterReg::const_instance_list_t& inst_list = LLFloaterReg::getFloaterList("impanel");
+ for (LLFloaterReg::const_instance_list_t::const_iterator iter = inst_list.begin();
+ iter != inst_list.end(); ++iter)
+ {
+ LLIMFloater* floater = dynamic_cast<LLIMFloater*>(*iter);
+ if (floater && floater->isDocked())
+ {
+ floater->setVisible(false);
+ }
+ }
+
+ LLIMFloater* floater = LLFloaterReg::showTypedInstance<LLIMFloater>("impanel", session_id);
+
+ floater->updateMessages();
+ floater->mInputEditor->setFocus(TRUE);
+ return floater;
+}
+
+//static
+bool LLIMFloater::toggle(const LLUUID& session_id)
+{
+ LLIMFloater* floater = LLFloaterReg::findTypedInstance<LLIMFloater>("impanel", session_id);
+ if (floater && floater->getVisible())
+ {
+ // clicking on chiclet to close floater just hides it to maintain existing
+ // scroll/text entry state
+ floater->setVisible(false);
+ return false;
+ }
+ else
+ {
+ // ensure the list of messages is updated when floater is made visible
+ show(session_id);
+ // update number of unread notifications in the SysWell
+ LLBottomTray::getInstance()->getSysWell()->updateUreadIMNotifications();
+ return true;
+ }
+}
+
+void LLIMFloater::updateMessages()
+{
+ std::list<LLSD> messages = LLIMModel::instance().getMessages(mSessionID, mLastMessageIndex+1);
+
+ if (messages.size())
+ {
+ LLUIColor divider_color = LLUIColorTable::instance().getColor("LtGray_50");
+ LLUIColor chat_color = LLUIColorTable::instance().getColor("IMChatColor");
+
+ std::ostringstream message;
+ std::list<LLSD>::const_reverse_iterator iter = messages.rbegin();
+ std::list<LLSD>::const_reverse_iterator iter_end = messages.rend();
+ for (; iter != iter_end; ++iter)
+ {
+ LLSD msg = *iter;
+
+ const bool prepend_newline = true;
+ std::string from = msg["from"].asString();
+ if (mLastFromName != from)
+ {
+ message << from << " ----- " << msg["time"].asString();
+ mHistoryEditor->appendColoredText(message.str(), false,
+ prepend_newline, divider_color);
+ message.str("");
+ mLastFromName = from;
+ }
+
+ message << msg["message"].asString();
+ mHistoryEditor->appendColoredText(message.str(), false,
+ prepend_newline, chat_color);
+ message.str("");
+
+ mLastMessageIndex = msg["index"].asInteger();
+ }
+
+ mHistoryEditor->setCursorAndScrollToEnd();
+ }
+}
+
+// static
+void LLIMFloater::onInputEditorFocusReceived( LLFocusableElement* caller, void* userdata )
+{
+ LLIMFloater* self= (LLIMFloater*) userdata;
+ self->mHistoryEditor->setCursorAndScrollToEnd();
+}
+
+// static
+void LLIMFloater::onInputEditorFocusLost(LLFocusableElement* caller, void* userdata)
+{
+ LLIMFloater* self = (LLIMFloater*) userdata;
+ self->setTyping(FALSE);
+}
+
+// static
+void LLIMFloater::onInputEditorKeystroke(LLLineEditor* caller, void* userdata)
+{
+ LLIMFloater* self = (LLIMFloater*)userdata;
+ std::string text = self->mInputEditor->getText();
+ if (!text.empty())
+ {
+ self->setTyping(TRUE);
+ }
+ else
+ {
+ // Deleting all text counts as stopping typing.
+ self->setTyping(FALSE);
+ }
+}
+
+
+//just a stub for now
+void LLIMFloater::setTyping(BOOL typing)
+{
+}
+void LLIMFloater::draw()
+{
+ //if we are docked, make sure we've been positioned by the chiclet
+ if (!isDocked() || mPositioned)
+ {
+ LLFloater::draw();
+
+ if (isDocked())
+ {
+ mDockTongue->draw( (getRect().getWidth()/2) - mDockTongue->getWidth()/2, -mDockTongue->getHeight());
+ }
+ }
+}
+
diff --git a/indra/newview/llimpanel.h b/indra/newview/llimpanel.h
index 8b3ca202c7..284a486b0f 100644
--- a/indra/newview/llimpanel.h
+++ b/indra/newview/llimpanel.h
@@ -47,6 +47,7 @@ class LLInventoryItem;
class LLInventoryCategory;
class LLIMSpeakerMgr;
class LLPanelActiveSpeakers;
+class LLPanelChatControlPanel;
class LLVoiceChannel : public LLVoiceClientStatusObserver
{
@@ -77,6 +78,7 @@ public:
virtual void getChannelInfo();
virtual BOOL isActive();
virtual BOOL callStarted();
+ const std::string& getSessionName() const { return mSessionName; }
const LLUUID getSessionID() { return mSessionID; }
EState getState() { return mState; }
@@ -94,6 +96,7 @@ public:
protected:
virtual void setState(EState state);
+ void toggleCallWindowIfNeeded(EState state);
void setURI(std::string uri);
std::string mURI;
@@ -185,11 +188,7 @@ public:
LLFloaterIMPanel(const std::string& session_label,
const LLUUID& session_id,
const LLUUID& target_id,
- EInstantMessage dialog);
- LLFloaterIMPanel(const std::string& session_label,
- const LLUUID& session_id,
- const LLUUID& target_id,
- const LLDynamicArray<LLUUID>& ids,
+ const std::vector<LLUUID>& ids,
EInstantMessage dialog);
virtual ~LLFloaterIMPanel();
@@ -197,12 +196,13 @@ public:
// Check typing timeout timer.
/*virtual*/ void draw();
- /*virtual*/ void onClose(bool app_quitting = FALSE);
- /*virtual*/ void onVisibilityChange(BOOL new_visibility);
+
+ void onClose();
+ void onVisibilityChange(const LLSD& new_visibility);
// add target ids to the session.
// Return TRUE if successful, otherwise FALSE.
- BOOL inviteToSession(const LLDynamicArray<LLUUID>& agent_ids);
+ BOOL inviteToSession(const std::vector<LLUUID>& agent_ids);
void addHistoryLine(const std::string &utf8msg,
const LLColor4& color = LLColor4::white,
@@ -214,7 +214,6 @@ public:
void selectAll();
void selectNone();
- void setVisible(BOOL b);
S32 getNumUnreadMessages() { return mNumUnreadMessages; }
@@ -246,11 +245,13 @@ public:
const LLUUID& getSessionID() const { return mSessionUUID; }
const LLUUID& getOtherParticipantID() const { return mOtherParticipantUUID; }
+ LLIMSpeakerMgr* getSpeakerManager() const { return mSpeakers; }
void updateSpeakersList(const LLSD& speaker_updates);
void processSessionUpdate(const LLSD& update);
void setSpeakers(const LLSD& speaker_list);
LLVoiceChannel* getVoiceChannel() { return mVoiceChannel; }
EInstantMessage getDialogType() const { return mDialog; }
+ void setDialogType(EInstantMessage dialog) { mDialog = dialog; }
void requestAutoConnect();
@@ -270,9 +271,6 @@ public:
static bool onConfirmForceCloseError(const LLSD& notification, const LLSD& response);
private:
- // called by constructors
- void init(const std::string& session_label);
-
// Called by UI methods.
void sendMsg();
@@ -318,7 +316,7 @@ private:
// inventory folder ==> first target id in list
// 911 ==> sender
LLUUID mOtherParticipantUUID;
- LLDynamicArray<LLUUID> mSessionInitialTargetIDs;
+ std::vector<LLUUID> mSessionInitialTargetIDs;
EInstantMessage mDialog;
@@ -360,10 +358,78 @@ private:
LLFrameTimer mLastKeystrokeTimer;
void disableWhileSessionStarting();
+};
+
+
+// Individual IM window that appears at the bottom of the screen,
+// optionally "docked" to the bottom tray.
+class LLIMFloater : public LLFloater
+{
+public:
+ LLIMFloater(const LLUUID& session_id);
+
+ virtual ~LLIMFloater();
+
+ // LLView overrides
+ /*virtual*/ BOOL postBuild();
+
+ // LLView overrides for drawing dock tongue
+ /*virtual*/
+ void draw();
+
+ // Floater should close when user clicks away to other UI area,
+ // hence causing focus loss.
+ /*virtual*/ void onFocusLost();
+
+ // LLFloater overrides
+ /*virtual*/ void setDocked(bool docked, bool pop_on_undock = true);
+
+ // Make IM conversion visible and update the message history
+ static LLIMFloater* show(const LLUUID& session_id);
+
+ // Toggle panel specified by session_id
+ // Returns true iff panel became visible
+ static bool toggle(const LLUUID& session_id);
- typedef std::map<LLUUID, LLStyleSP> styleMap;
- static styleMap mStyleMap;
+ // get new messages from LLIMModel
+ void updateMessages();
+ static void onSendMsg( LLUICtrl*, void*);
+ void sendMsg();
+
+ // callback for LLIMModel on new messages
+ // route to specific floater if it is visible
+ static void newIMCallback(const LLSD& data);
+
+ // called when docked floater's position has been set by chiclet
+ void setPositioned(bool b) { mPositioned = b; };
+
+
+
+private:
+
+ static void onInputEditorFocusReceived( LLFocusableElement* caller, void* userdata );
+ static void onInputEditorFocusLost(LLFocusableElement* caller, void* userdata);
+ static void onInputEditorKeystroke(LLLineEditor* caller, void* userdata);
+ void setTyping(BOOL typing);
+ void onSlide();
+ static void* createPanelIMControl(void* userdata);
+ static void* createPanelGroupControl(void* userdata);
+
+ LLPanelChatControlPanel* mControlPanel;
+ LLUUID mSessionID;
+ S32 mLastMessageIndex;
+ // username of last user who added text to this conversation, used to
+ // suppress duplicate username divider bars
+ std::string mLastFromName;
+ EInstantMessage mDialog;
+ LLUUID mOtherParticipantUUID;
+ LLViewerTextEditor* mHistoryEditor;
+ LLLineEditor* mInputEditor;
+ bool mPositioned;
+ LLUIImagePtr mDockTongue;
};
+
+
#endif // LL_IMPANEL_H
diff --git a/indra/newview/llimview.cpp b/indra/newview/llimview.cpp
index 5b3f3952c9..5272bc2165 100644
--- a/indra/newview/llimview.cpp
+++ b/indra/newview/llimview.cpp
@@ -34,6 +34,7 @@
#include "llimview.h"
+#include "llfloaterreg.h"
#include "llfontgl.h"
#include "llrect.h"
#include "llerror.h"
@@ -44,12 +45,13 @@
#include "lluictrlfactory.h"
#include "llagent.h"
+#include "llavatariconctrl.h"
#include "llcallingcard.h"
#include "llchat.h"
#include "llresmgr.h"
#include "llfloaterchat.h"
#include "llfloaterchatterbox.h"
-#include "llfloaternewim.h"
+#include "llavataractions.h"
#include "llhttpnode.h"
#include "llimpanel.h"
#include "llresizebar.h"
@@ -67,8 +69,10 @@
#include "llviewerwindow.h"
#include "llnotify.h"
#include "llviewerregion.h"
+#include "lltrans.h"
#include "llfirstuse.h"
+#include "llagentui.h"
//
// Globals
@@ -88,16 +92,531 @@ std::map<std::string,std::string> LLFloaterIM::sEventStringsMap;
std::map<std::string,std::string> LLFloaterIM::sErrorStringsMap;
std::map<std::string,std::string> LLFloaterIM::sForceCloseSessionMap;
+std::map<LLUUID, LLIMModel::LLIMSession*> LLIMModel::sSessionsMap;
+
+
+
+void toast_callback(const LLSD& msg){
+
+ //we send notifications to reset counter also
+ if (msg["num_unread"].asInteger())
+ {
+ LLSD args;
+ args["MESSAGE"] = msg["message"];
+ args["TIME"] = msg["time"];
+ args["FROM"] = msg["from"];
+ args["FROM_ID"] = msg["from_id"];
+ args["SESSION_ID"] = msg["session_id"];
+
+ LLNotifications::instance().add("IMToast", args, LLSD(), boost::bind(&LLFloaterChatterBox::onOpen, LLFloaterChatterBox::getInstance(), msg["session_id"].asUUID()));
+ }
+}
+
+LLIMModel::LLIMModel()
+{
+ addChangedCallback(toast_callback);
+ addChangedCallback(LLIMFloater::newIMCallback);
+}
+
+
+void LLIMModel::testMessages()
+{
+ LLUUID bot1_id("d0426ec6-6535-4c11-a5d9-526bb0c654d9");
+ LLUUID bot1_session_id;
+ std::string from = "IM Tester";
+
+ bot1_session_id = LLIMMgr::computeSessionID(IM_NOTHING_SPECIAL, bot1_id);
+ newSession(bot1_session_id, from, IM_NOTHING_SPECIAL, bot1_id);
+ addMessage(bot1_session_id, from, bot1_id, "Test Message: Hi from testerbot land!");
+
+ LLUUID bot2_id;
+ std::string firstname[] = {"Roflcopter", "Joe"};
+ std::string lastname[] = {"Linden", "Tester", "Resident", "Schmoe"};
+
+ S32 rand1 = ll_rand(sizeof firstname)/(sizeof firstname[0]);
+ S32 rand2 = ll_rand(sizeof lastname)/(sizeof lastname[0]);
+
+ from = firstname[rand1] + " " + lastname[rand2];
+ bot2_id.generate(from);
+ LLUUID bot2_session_id = LLIMMgr::computeSessionID(IM_NOTHING_SPECIAL, bot2_id);
+ newSession(bot2_session_id, from, IM_NOTHING_SPECIAL, bot2_id);
+ addMessage(bot2_session_id, from, bot2_id, "Test Message: Can I haz bear? ");
+ addMessage(bot2_session_id, from, bot2_id, "Test Message: OMGWTFBBQ.");
+}
+
+
+bool LLIMModel::newSession(LLUUID session_id, std::string name, EInstantMessage type, LLUUID other_participant_id)
+{
+ if (is_in_map(sSessionsMap, session_id))
+ {
+ llwarns << "IM Session " << session_id << " already exists" << llendl;
+ return false;
+ }
+
+ LLIMSession* session = new LLIMSession(name, type, other_participant_id);
+ sSessionsMap[session_id] = session;
+
+ LLIMMgr::getInstance()->notifyObserverSessionAdded(session_id, name, other_participant_id);
+
+ return true;
+
+}
+
+bool LLIMModel::clearSession(LLUUID session_id)
+{
+ if (sSessionsMap.find(session_id) == sSessionsMap.end()) return false;
+ delete (sSessionsMap[session_id]);
+ sSessionsMap.erase(session_id);
+ return true;
+}
+
+std::list<LLSD> LLIMModel::getMessages(LLUUID session_id, int start_index)
+{
+ std::list<LLSD> return_list;
+
+ LLIMSession* session = get_if_there(sSessionsMap, session_id, (LLIMSession*)NULL);
+
+ if (!session)
+ {
+ llwarns << "session " << session_id << "does not exist " << llendl;
+ return return_list;
+ }
+
+ int i = session->mMsgs.size() - start_index;
+
+ for (std::list<LLSD>::iterator iter = session->mMsgs.begin();
+ iter != session->mMsgs.end() && i > 0;
+ iter++)
+ {
+ LLSD msg;
+ msg = *iter;
+ return_list.push_back(*iter);
+ i--;
+ }
+
+ session->mNumUnread = 0;
+
+ LLSD arg;
+ arg["session_id"] = session_id;
+ arg["num_unread"] = 0;
+ mChangedSignal(arg);
+
+ // TODO: in the future is there a more efficient way to return these
+ return return_list;
+
+}
+
+bool LLIMModel::addToHistory(LLUUID session_id, std::string from, std::string utf8_text) {
+
+ LLIMSession* session = get_if_there(sSessionsMap, session_id, (LLIMSession*)NULL);
+
+ if (!session)
+ {
+ llwarns << "session " << session_id << "does not exist " << llendl;
+ return false;
+ }
+
+ LLSD message;
+ message["from"] = from;
+ message["message"] = utf8_text;
+ message["time"] = LLLogChat::timestamp(false); //might want to add date separately
+ message["index"] = (LLSD::Integer)session->mMsgs.size();
+
+ session->mMsgs.push_front(message);
+
+ return true;
+
+}
+
+
+bool LLIMModel::addMessage(LLUUID session_id, std::string from, LLUUID from_id, std::string utf8_text) {
+
+ LLIMSession* session = get_if_there(sSessionsMap, session_id, (LLIMSession*)NULL);
+
+ if (!session)
+ {
+ llwarns << "session " << session_id << "does not exist " << llendl;
+ return false;
+ }
+
+ addToHistory(session_id, from, utf8_text);
+
+ std::string agent_name;
+ LLAgentUI::buildFullname(agent_name);
+
+ session->mNumUnread++;
+
+ // notify listeners
+ LLSD arg;
+ arg["session_id"] = session_id;
+ arg["num_unread"] = session->mNumUnread;
+ arg["message"] = utf8_text;
+ arg["from"] = from;
+ arg["from_id"] = from_id;
+ arg["time"] = LLLogChat::timestamp(false);
+ mChangedSignal(arg);
+
+ return true;
+}
+
+
+const std::string& LLIMModel::getName(LLUUID session_id)
+{
+ LLIMSession* session = get_if_there(sSessionsMap, session_id, (LLIMSession*)NULL);
+
+ if (!session)
+ {
+ llwarns << "session " << session_id << "does not exist " << llendl;
+ return LLStringUtil::null;
+ }
+
+ return session->mName;
+}
+
+
+// TODO get rid of other participant ID
+void LLIMModel::sendTypingState(LLUUID session_id, LLUUID other_participant_id, BOOL typing)
+{
+ std::string name;
+ LLAgentUI::buildFullname(name);
+
+ pack_instant_message(
+ gMessageSystem,
+ gAgent.getID(),
+ FALSE,
+ gAgent.getSessionID(),
+ other_participant_id,
+ name,
+ std::string("typing"),
+ IM_ONLINE,
+ (typing ? IM_TYPING_START : IM_TYPING_STOP),
+ session_id);
+ gAgent.sendReliableMessage();
+}
+
+void LLIMModel::sendLeaveSession(LLUUID session_id, LLUUID other_participant_id)
+{
+ if(session_id.notNull())
+ {
+ std::string name;
+ LLAgentUI::buildFullname(name);
+ pack_instant_message(
+ gMessageSystem,
+ gAgent.getID(),
+ FALSE,
+ gAgent.getSessionID(),
+ other_participant_id,
+ name,
+ LLStringUtil::null,
+ IM_ONLINE,
+ IM_SESSION_LEAVE,
+ session_id);
+ gAgent.sendReliableMessage();
+ }
+}
+
+
+
+void LLIMModel::sendMessage(const std::string& utf8_text,
+ const LLUUID& im_session_id,
+ const LLUUID& other_participant_id,
+ EInstantMessage dialog)
+{
+ std::string name;
+ bool sent = false;
+ LLAgentUI::buildFullname(name);
+
+ const LLRelationship* info = NULL;
+ info = LLAvatarTracker::instance().getBuddyInfo(other_participant_id);
+
+ U8 offline = (!info || info->isOnline()) ? IM_ONLINE : IM_OFFLINE;
+
+ if((offline == IM_OFFLINE) && (LLVoiceClient::getInstance()->isOnlineSIP(other_participant_id)))
+ {
+ // User is online through the OOW connector, but not with a regular viewer. Try to send the message via SLVoice.
+ sent = gVoiceClient->sendTextMessage(other_participant_id, utf8_text);
+ }
+
+ if(!sent)
+ {
+ // Send message normally.
+
+ // default to IM_SESSION_SEND unless it's nothing special - in
+ // which case it's probably an IM to everyone.
+ U8 new_dialog = dialog;
+
+ if ( dialog != IM_NOTHING_SPECIAL )
+ {
+ new_dialog = IM_SESSION_SEND;
+ }
+ pack_instant_message(
+ gMessageSystem,
+ gAgent.getID(),
+ FALSE,
+ gAgent.getSessionID(),
+ other_participant_id,
+ name.c_str(),
+ utf8_text.c_str(),
+ offline,
+ (EInstantMessage)new_dialog,
+ im_session_id);
+ gAgent.sendReliableMessage();
+ }
+
+ // If there is a mute list and this is not a group chat...
+ if ( LLMuteList::getInstance() )
+ {
+ // ... the target should not be in our mute list for some message types.
+ // Auto-remove them if present.
+ switch( dialog )
+ {
+ case IM_NOTHING_SPECIAL:
+ case IM_GROUP_INVITATION:
+ case IM_INVENTORY_OFFERED:
+ case IM_SESSION_INVITE:
+ case IM_SESSION_P2P_INVITE:
+ case IM_SESSION_CONFERENCE_START:
+ case IM_SESSION_SEND: // This one is marginal - erring on the side of hearing.
+ case IM_LURE_USER:
+ case IM_GODLIKE_LURE_USER:
+ case IM_FRIENDSHIP_OFFERED:
+ LLMuteList::getInstance()->autoRemove(other_participant_id, LLMuteList::AR_IM);
+ break;
+ default: ; // do nothing
+ }
+ }
+
+ if((dialog == IM_NOTHING_SPECIAL) &&
+ (other_participant_id.notNull()))
+ {
+ // Do we have to replace the /me's here?
+ std::string from;
+ LLAgentUI::buildFullname(from);
+ LLIMModel::instance().addToHistory(im_session_id, from, utf8_text);
+
+ //local echo for the legacy communicate panel
+ std::string history_echo;
+ std::string utf8_copy = utf8_text;
+ LLAgentUI::buildFullname(history_echo);
+
+ // Look for IRC-style emotes here.
+
+ std::string prefix = utf8_copy.substr(0, 4);
+ if (prefix == "/me " || prefix == "/me'")
+ {
+ utf8_copy.replace(0,3,"");
+ }
+ else
+ {
+ history_echo += ": ";
+ }
+ history_echo += utf8_copy;
+
+ LLFloaterIMPanel* floater = gIMMgr->findFloaterBySession(im_session_id);
+ if (floater) floater->addHistoryLine(history_echo, LLUIColorTable::instance().getColor("IMChatColor"), true, gAgent.getID());
+
+ }
+
+ // Add the recipient to the recent people list.
+ LLRecentPeople::instance().add(other_participant_id);
+}
+
+boost::signals2::connection LLIMModel::addChangedCallback( boost::function<void (const LLSD& data)> cb )
+{
+ return mChangedSignal.connect(cb);
+}
+
+void session_starter_helper(
+ const LLUUID& temp_session_id,
+ const LLUUID& other_participant_id,
+ EInstantMessage im_type)
+{
+ LLMessageSystem *msg = gMessageSystem;
+
+ msg->newMessageFast(_PREHASH_ImprovedInstantMessage);
+ msg->nextBlockFast(_PREHASH_AgentData);
+ msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
+ msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
+
+ msg->nextBlockFast(_PREHASH_MessageBlock);
+ msg->addBOOLFast(_PREHASH_FromGroup, FALSE);
+ msg->addUUIDFast(_PREHASH_ToAgentID, other_participant_id);
+ msg->addU8Fast(_PREHASH_Offline, IM_ONLINE);
+ msg->addU8Fast(_PREHASH_Dialog, im_type);
+ msg->addUUIDFast(_PREHASH_ID, temp_session_id);
+ msg->addU32Fast(_PREHASH_Timestamp, NO_TIMESTAMP); // no timestamp necessary
+
+ std::string name;
+ LLAgentUI::buildFullname(name);
+
+ msg->addStringFast(_PREHASH_FromAgentName, name);
+ msg->addStringFast(_PREHASH_Message, LLStringUtil::null);
+ msg->addU32Fast(_PREHASH_ParentEstateID, 0);
+ msg->addUUIDFast(_PREHASH_RegionID, LLUUID::null);
+ msg->addVector3Fast(_PREHASH_Position, gAgent.getPositionAgent());
+}
+
+void start_deprecated_conference_chat(
+ const LLUUID& temp_session_id,
+ const LLUUID& creator_id,
+ const LLUUID& other_participant_id,
+ const LLSD& agents_to_invite)
+{
+ U8* bucket;
+ U8* pos;
+ S32 count;
+ S32 bucket_size;
+
+ // *FIX: this could suffer from endian issues
+ count = agents_to_invite.size();
+ bucket_size = UUID_BYTES * count;
+ bucket = new U8[bucket_size];
+ pos = bucket;
+
+ for(S32 i = 0; i < count; ++i)
+ {
+ LLUUID agent_id = agents_to_invite[i].asUUID();
+
+ memcpy(pos, &agent_id, UUID_BYTES);
+ pos += UUID_BYTES;
+ }
+
+ session_starter_helper(
+ temp_session_id,
+ other_participant_id,
+ IM_SESSION_CONFERENCE_START);
+
+ gMessageSystem->addBinaryDataFast(
+ _PREHASH_BinaryBucket,
+ bucket,
+ bucket_size);
+
+ gAgent.sendReliableMessage();
+
+ delete[] bucket;
+}
+
+class LLStartConferenceChatResponder : public LLHTTPClient::Responder
+{
+public:
+ LLStartConferenceChatResponder(
+ const LLUUID& temp_session_id,
+ const LLUUID& creator_id,
+ const LLUUID& other_participant_id,
+ const LLSD& agents_to_invite)
+ {
+ mTempSessionID = temp_session_id;
+ mCreatorID = creator_id;
+ mOtherParticipantID = other_participant_id;
+ mAgents = agents_to_invite;
+ }
+
+ virtual void error(U32 statusNum, const std::string& reason)
+ {
+ //try an "old school" way.
+ if ( statusNum == 400 )
+ {
+ start_deprecated_conference_chat(
+ mTempSessionID,
+ mCreatorID,
+ mOtherParticipantID,
+ mAgents);
+ }
+
+ //else throw an error back to the client?
+ //in theory we should have just have these error strings
+ //etc. set up in this file as opposed to the IMMgr,
+ //but the error string were unneeded here previously
+ //and it is not worth the effort switching over all
+ //the possible different language translations
+ }
+
+private:
+ LLUUID mTempSessionID;
+ LLUUID mCreatorID;
+ LLUUID mOtherParticipantID;
+
+ LLSD mAgents;
+};
+
+// Returns true if any messages were sent, false otherwise.
+// Is sort of equivalent to "does the server need to do anything?"
+bool LLIMModel::sendStartSession(
+ const LLUUID& temp_session_id,
+ const LLUUID& other_participant_id,
+ const std::vector<LLUUID>& ids,
+ EInstantMessage dialog)
+{
+ if ( dialog == IM_SESSION_GROUP_START )
+ {
+ session_starter_helper(
+ temp_session_id,
+ other_participant_id,
+ dialog);
+
+ switch(dialog)
+ {
+ case IM_SESSION_GROUP_START:
+ gMessageSystem->addBinaryDataFast(
+ _PREHASH_BinaryBucket,
+ EMPTY_BINARY_BUCKET,
+ EMPTY_BINARY_BUCKET_SIZE);
+ break;
+ default:
+ break;
+ }
+ gAgent.sendReliableMessage();
+
+ return true;
+ }
+ else if ( dialog == IM_SESSION_CONFERENCE_START )
+ {
+ LLSD agents;
+ for (int i = 0; i < (S32) ids.size(); i++)
+ {
+ agents.append(ids[i]);
+ }
+
+ //we have a new way of starting conference calls now
+ LLViewerRegion* region = gAgent.getRegion();
+ if (region)
+ {
+ std::string url = region->getCapability(
+ "ChatSessionRequest");
+ LLSD data;
+ data["method"] = "start conference";
+ data["session-id"] = temp_session_id;
+
+ data["params"] = agents;
+
+ LLHTTPClient::post(
+ url,
+ data,
+ new LLStartConferenceChatResponder(
+ temp_session_id,
+ gAgent.getID(),
+ other_participant_id,
+ data["params"]));
+ }
+ else
+ {
+ start_deprecated_conference_chat(
+ temp_session_id,
+ gAgent.getID(),
+ other_participant_id,
+ agents);
+ }
+ }
+
+ return false;
+}
+
+
+
//
// Helper Functions
//
-// returns true if a should appear before b
-//static BOOL group_dictionary_sort( LLGroupData* a, LLGroupData* b )
-//{
-// return (LLStringUtil::compareDict( a->mName, b->mName ) < 0);
-//}
-
class LLViewerChatterBoxInvitationAcceptResponder :
public LLHTTPClient::Responder
{
@@ -145,11 +664,11 @@ public:
floaterp->requestAutoConnect();
LLFloaterIMPanel::onClickStartCall(floaterp);
// always open IM window when connecting to voice
- LLFloaterChatterBox::showInstance(TRUE);
+ LLFloaterReg::showInstance("communicate", LLSD(), TRUE);
}
else if ( mInvitiationType == LLIMMgr::INVITATION_TYPE_IMMEDIATE )
{
- LLFloaterChatterBox::showInstance(TRUE);
+ LLFloaterReg::showInstance("communicate", LLSD(), TRUE);
}
}
@@ -234,14 +753,15 @@ LLUUID LLIMMgr::computeSessionID(
// LLFloaterIM
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-LLFloaterIM::LLFloaterIM()
+LLFloaterIM::LLFloaterIM()
+ : LLMultiFloater(LLSD())
{
// autoresize=false is necessary to avoid resizing of the IM window whenever
// a session is opened or closed (it would otherwise resize the window to match
// the size of the im-sesssion when they were created. This happens in
// LLMultiFloater::resizeToContents() when called through LLMultiFloater::addFloater())
- this->mAutoResize = FALSE;
- LLUICtrlFactory::getInstance()->buildFloater(this, "floater_im.xml");
+ mAutoResize = FALSE;
+ LLUICtrlFactory::getInstance()->buildFloater(this, "floater_im.xml", NULL);
}
BOOL LLFloaterIM::postBuild()
@@ -325,6 +845,172 @@ BOOL LLFloaterIM::postBuild()
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+// Class LLIncomingCallDialog
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+LLIncomingCallDialog::LLIncomingCallDialog(const LLSD& payload) :
+ LLModalDialog(payload),
+ mPayload(payload)
+{
+}
+
+BOOL LLIncomingCallDialog::postBuild()
+{
+ LLSD caller_id = mPayload["caller_id"];
+ EInstantMessage type = (EInstantMessage)mPayload["type"].asInteger();
+
+ std::string call_type = getString("VoiceInviteP2P");
+ std::string caller_name = mPayload["caller_name"].asString();
+ if (caller_name == "anonymous")
+ {
+ caller_name = getString("anonymous");
+ }
+
+ setTitle(caller_name + " " + call_type);
+
+ // If it is not a P2P invite, then it's an AdHoc invite
+ if ( type != IM_SESSION_P2P_INVITE )
+ {
+ call_type = getString("VoiceInviteAdHoc");
+ }
+
+ LLUICtrl* caller_name_widget = getChild<LLUICtrl>("caller name");
+ caller_name_widget->setValue(caller_name + " " + call_type);
+ LLAvatarIconCtrl* icon = getChild<LLAvatarIconCtrl>("avatar_icon");
+ icon->setValue(caller_id);
+
+ childSetAction("Accept", onAccept, this);
+ childSetAction("Reject", onReject, this);
+ childSetAction("Start IM", onStartIM, this);
+ childSetFocus("Accept");
+
+ return TRUE;
+}
+
+//static
+void LLIncomingCallDialog::onAccept(void* user_data)
+{
+ LLIncomingCallDialog* self = (LLIncomingCallDialog*)user_data;
+ self->processCallResponse(0);
+ self->closeFloater();
+}
+
+//static
+void LLIncomingCallDialog::onReject(void* user_data)
+{
+ LLIncomingCallDialog* self = (LLIncomingCallDialog*)user_data;
+ self->processCallResponse(1);
+ self->closeFloater();
+}
+
+//static
+void LLIncomingCallDialog::onStartIM(void* user_data)
+{
+ LLIncomingCallDialog* self = (LLIncomingCallDialog*)user_data;
+ self->processCallResponse(2);
+ self->closeFloater();
+}
+
+void LLIncomingCallDialog::processCallResponse(S32 response)
+{
+ LLUUID session_id = mPayload["session_id"].asUUID();
+ EInstantMessage type = (EInstantMessage)mPayload["type"].asInteger();
+ LLIMMgr::EInvitationType inv_type = (LLIMMgr::EInvitationType)mPayload["inv_type"].asInteger();
+ bool voice = true;
+ switch(response)
+ {
+ case 2: // start IM: just don't start the voice chat
+ {
+ voice = false;
+ /* FALLTHROUGH */
+ }
+ case 0: // accept
+ {
+ if (type == IM_SESSION_P2P_INVITE)
+ {
+ // create a normal IM session
+ session_id = gIMMgr->addP2PSession(
+ mPayload["session_name"].asString(),
+ mPayload["caller_id"].asUUID(),
+ mPayload["session_handle"].asString());
+
+ if (voice)
+ {
+ LLFloaterIMPanel* im_floater =
+ gIMMgr->findFloaterBySession(
+ session_id);
+
+ if (im_floater)
+ {
+ im_floater->requestAutoConnect();
+ LLFloaterIMPanel::onClickStartCall(im_floater);
+ }
+ }
+
+ // always open IM window when connecting to voice
+ LLFloaterReg::showInstance("communicate", session_id);
+
+ gIMMgr->clearPendingAgentListUpdates(session_id);
+ gIMMgr->clearPendingInvitation(session_id);
+ }
+ else
+ {
+ gIMMgr->addSession(
+ mPayload["session_name"].asString(),
+ type,
+ session_id);
+
+ std::string url = gAgent.getRegion()->getCapability(
+ "ChatSessionRequest");
+
+ if (voice)
+ {
+ LLSD data;
+ data["method"] = "accept invitation";
+ data["session-id"] = session_id;
+ LLHTTPClient::post(
+ url,
+ data,
+ new LLViewerChatterBoxInvitationAcceptResponder(
+ session_id,
+ inv_type));
+ }
+ }
+ if (voice)
+ {
+ break;
+ }
+ }
+ case 1: // decline
+ {
+ if (type == IM_SESSION_P2P_INVITE)
+ {
+ if(gVoiceClient)
+ {
+ std::string s = mPayload["session_handle"].asString();
+ gVoiceClient->declineInvite(s);
+ }
+ }
+ else
+ {
+ std::string url = gAgent.getRegion()->getCapability(
+ "ChatSessionRequest");
+
+ LLSD data;
+ data["method"] = "decline invitation";
+ data["session-id"] = session_id;
+ LLHTTPClient::post(
+ url,
+ data,
+ NULL);
+ }
+ }
+
+ gIMMgr->clearPendingAgentListUpdates(session_id);
+ gIMMgr->clearPendingInvitation(session_id);
+ }
+}
+
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Class LLIMViewFriendObserver
//
// Bridge to suport knowing when the inventory has changed.
@@ -375,7 +1061,7 @@ bool inviteUserResponse(const LLSD& notification, const LLSD& response)
im_floater->requestAutoConnect();
LLFloaterIMPanel::onClickStartCall(im_floater);
// always open IM window when connecting to voice
- LLFloaterChatterBox::showInstance(session_id);
+ LLFloaterReg::showInstance("communicate", session_id, TRUE);
}
gIMMgr->clearPendingAgentListUpdates(session_id);
@@ -448,74 +1134,6 @@ bool inviteUserResponse(const LLSD& notification, const LLSD& response)
}
//
-// Public Static Member Functions
-//
-
-// This is a helper function to determine what kind of im session
-// should be used for the given agent.
-// static
-EInstantMessage LLIMMgr::defaultIMTypeForAgent(const LLUUID& agent_id)
-{
- EInstantMessage type = IM_NOTHING_SPECIAL;
- if(is_agent_friend(agent_id))
- {
- if(LLAvatarTracker::instance().isBuddyOnline(agent_id))
- {
- type = IM_SESSION_CONFERENCE_START;
- }
- }
- return type;
-}
-
-// static
-//void LLIMMgr::onPinButton(void*)
-//{
-// BOOL state = gSavedSettings.getBOOL( "PinTalkViewOpen" );
-// gSavedSettings.setBOOL( "PinTalkViewOpen", !state );
-//}
-
-// static
-void LLIMMgr::toggle(void*)
-{
- static BOOL return_to_mouselook = FALSE;
-
- // Hide the button and show the floater or vice versa.
- llassert( gIMMgr );
- BOOL old_state = gIMMgr->getFloaterOpen();
-
- // If we're in mouselook and we triggered the Talk View, we want to talk.
- if( gAgent.cameraMouselook() && old_state )
- {
- return_to_mouselook = TRUE;
- gAgent.changeCameraToDefault();
- return;
- }
-
- BOOL new_state = !old_state;
-
- if (new_state)
- {
- // ...making visible
- if ( gAgent.cameraMouselook() )
- {
- return_to_mouselook = TRUE;
- gAgent.changeCameraToDefault();
- }
- }
- else
- {
- // ...hiding
- if ( gAgent.cameraThirdPerson() && return_to_mouselook )
- {
- gAgent.changeCameraToMouselook();
- }
- return_to_mouselook = FALSE;
- }
-
- gIMMgr->setFloaterOpen( new_state );
-}
-
-//
// Member Functions
//
@@ -523,6 +1141,13 @@ LLIMMgr::LLIMMgr() :
mFriendObserver(NULL),
mIMReceived(FALSE)
{
+ static bool registered_dialog = false;
+ if (!registered_dialog)
+ {
+ LLFloaterReg::add("incoming_call", "floater_incoming_call.xml.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLIncomingCallDialog>);
+ registered_dialog = true;
+ }
+
mFriendObserver = new LLIMViewFriendObserver(this);
LLAvatarTracker::instance().addObserver(mFriendObserver);
@@ -614,10 +1239,10 @@ void LLIMMgr::addMessage(
{
// *TODO:translate (low priority, god ability)
std::ostringstream bonus_info;
- bonus_info << "*** parent estate: "
+ bonus_info << LLTrans::getString("***")+ " "+ LLTrans::getString("IMParentEstate") + ":" + " "
<< parent_estate_id
- << ((parent_estate_id == 1) ? ", mainland" : "")
- << ((parent_estate_id == 5) ? ", teen" : "");
+ << ((parent_estate_id == 1) ? "," + LLTrans::getString("IMMainland") : "")
+ << ((parent_estate_id == 5) ? "," + LLTrans::getString ("IMTeen") : "");
// once we have web-services (or something) which returns
// information about a region id, we can print this out
@@ -625,7 +1250,8 @@ void LLIMMgr::addMessage(
//<< "*** region_id: " << region_id << std::endl
//<< "*** position: " << position << std::endl;
- floater->addHistoryLine(bonus_info.str(), gSavedSettings.getColor4("SystemChatColor"));
+ floater->addHistoryLine(bonus_info.str(), LLUIColorTable::instance().getColor("SystemChatColor"));
+ LLIMModel::instance().addMessage(new_session_id, from, other_participant_id, bonus_info.str());
}
make_ui_sound("UISndNewIncomingIMSession");
@@ -634,8 +1260,8 @@ void LLIMMgr::addMessage(
// now add message to floater
bool is_from_system = target_id.isNull() || (from == SYSTEM_FROM);
const LLColor4& color = ( is_from_system ?
- gSavedSettings.getColor4("SystemChatColor") :
- gSavedSettings.getColor("IMChatColor"));
+ LLUIColorTable::instance().getColor("SystemChatColor") :
+ LLUIColorTable::instance().getColor("IMChatColor"));
if ( !link_name )
{
floater->addHistoryLine(msg,color); // No name to prepend, so just add the message normally
@@ -645,10 +1271,12 @@ void LLIMMgr::addMessage(
floater->addHistoryLine(msg, color, true, other_participant_id, from); // Insert linked name to front of message
}
- LLFloaterChatterBox* chat_floater = LLFloaterChatterBox::getInstance(LLSD());
+ LLIMModel::instance().addMessage(new_session_id, from, other_participant_id, msg);
- if( !chat_floater->getVisible() && !floater->getVisible())
+ if( !LLFloaterReg::instanceVisible("communicate") && !floater->getVisible())
{
+ LLFloaterChatterBox* chat_floater = LLFloaterChatterBox::getInstance();
+
//if the IM window is not open and the floater is not visible (i.e. not torn off)
LLFloater* previouslyActiveFloater = chat_floater->getActiveFloater();
@@ -675,14 +1303,12 @@ void LLIMMgr::addSystemMessage(const LLUUID& session_id, const std::string& mess
// null session id means near me (chat history)
if (session_id.isNull())
{
- LLFloaterChat* floaterp = LLFloaterChat::getInstance();
-
- message = floaterp->getString(message_name);
+ message = LLTrans::getString(message_name);
message.setArgs(args);
LLChat chat(message);
chat.mSourceType = CHAT_SOURCE_SYSTEM;
- LLFloaterChat::getInstance()->addChatHistory(chat);
+ LLFloaterChat::addChatHistory(chat);
}
else // going to IM session
{
@@ -699,12 +1325,25 @@ void LLIMMgr::addSystemMessage(const LLUUID& session_id, const std::string& mess
void LLIMMgr::notifyNewIM()
{
- if(!gIMMgr->getFloaterOpen())
+ if(!LLFloaterReg::instanceVisible("communicate"))
{
mIMReceived = TRUE;
}
}
+S32 LLIMMgr::getNumberOfUnreadIM()
+{
+ std::map<LLUUID, LLIMModel::LLIMSession*>::iterator it;
+
+ S32 num = 0;
+ for(it = LLIMModel::sSessionsMap.begin(); it != LLIMModel::sSessionsMap.end(); ++it)
+ {
+ num += (*it).second->mNumUnread;
+ }
+
+ return num;
+}
+
void LLIMMgr::clearNewIMNotification()
{
mIMReceived = FALSE;
@@ -750,39 +1389,9 @@ LLUUID LLIMMgr::addSession(
EInstantMessage dialog,
const LLUUID& other_participant_id)
{
- LLUUID session_id = computeSessionID(dialog, other_participant_id);
-
- LLFloaterIMPanel* floater = findFloaterBySession(session_id);
- if(!floater)
- {
- LLDynamicArray<LLUUID> ids;
- ids.put(other_participant_id);
-
- floater = createFloater(
- session_id,
- other_participant_id,
- name,
- ids,
- dialog,
- TRUE);
-
- noteOfflineUsers(floater, ids);
- LLFloaterChatterBox::showInstance(session_id);
-
- // Only warn for regular IMs - not group IMs
- if( dialog == IM_NOTHING_SPECIAL )
- {
- noteMutedUsers(floater, ids);
- }
- LLFloaterChatterBox::getInstance(LLSD())->showFloater(floater);
- }
- else
- {
- floater->open();
- }
- //mTabContainer->selectTabPanel(panel);
- floater->setInputFocus(TRUE);
- return floater->getSessionID();
+ LLDynamicArray<LLUUID> ids;
+ ids.put(other_participant_id);
+ return addSession(name, dialog, other_participant_id, ids);
}
// Adds a session using the given session_id. If the session already exists
@@ -798,9 +1407,7 @@ LLUUID LLIMMgr::addSession(
return LLUUID::null;
}
- LLUUID session_id = computeSessionID(
- dialog,
- other_participant_id);
+ LLUUID session_id = computeSessionID(dialog,other_participant_id);
LLFloaterIMPanel* floater = findFloaterBySession(session_id);
if(!floater)
@@ -811,14 +1418,13 @@ LLUUID LLIMMgr::addSession(
session_id,
other_participant_id,
name,
- ids,
dialog,
- TRUE);
+ TRUE,
+ ids);
if ( !floater ) return LLUUID::null;
noteOfflineUsers(floater, ids);
- LLFloaterChatterBox::showInstance(session_id);
// Only warn for regular IMs - not group IMs
if( dialog == IM_NOTHING_SPECIAL )
@@ -828,27 +1434,39 @@ LLUUID LLIMMgr::addSession(
}
else
{
- floater->open();
+ // *TODO: Remove this? Otherwise old communicate window opens on
+ // second initiation of IM session from People panel?
+ // floater->openFloater();
}
//mTabContainer->selectTabPanel(panel);
floater->setInputFocus(TRUE);
+ LLIMFloater::show(session_id);
+ notifyObserverSessionAdded(floater->getSessionID(), name, other_participant_id);
return floater->getSessionID();
}
// This removes the panel referenced by the uuid, and then restores
-// internal consistency. The internal pointer is not deleted.
+// internal consistency. The internal pointer is not deleted? Did you mean
+// a pointer to the corresponding LLIMSession? Session data is cleared now.
void LLIMMgr::removeSession(const LLUUID& session_id)
{
LLFloaterIMPanel* floater = findFloaterBySession(session_id);
if(floater)
{
mFloaters.erase(floater->getHandle());
- LLFloaterChatterBox::getInstance(LLSD())->removeFloater(floater);
+ LLFloaterChatterBox::getInstance()->removeFloater(floater);
//mTabContainer->removeTabPanel(floater);
clearPendingInvitation(session_id);
clearPendingAgentListUpdates(session_id);
}
+ notifyObserverSessionRemoved(session_id);
+
+ //if we don't clear session data on removing the session
+ //we can't use LLBottomTray as observer of session creation/delettion and
+ //creating chiclets only on session created even, we need to handle chiclets creation
+ //the same way as LLFloaterIMPanels were managed.
+ LLIMModel::getInstance()->clearSession(session_id);
}
void LLIMMgr::inviteToSession(
@@ -932,66 +1550,55 @@ void LLIMMgr::inviteToSession(
{
if (caller_name.empty())
{
- BOOL is_group = FALSE; // Inviter must be a person
- gCacheName->getNameFromUUID(caller_id, is_group, onInviteNameLookup, new LLSD(payload));
+ gCacheName->get(caller_id, FALSE, boost::bind(&LLIMMgr::onInviteNameLookup, payload, _1, _2, _3, _4));
}
else
{
- LLSD args;
- args["NAME"] = caller_name;
- args["GROUP"] = session_name;
-
- LLNotifications::instance().add(notify_box_type,
- args,
- payload,
- &inviteUserResponse);
+ if (notify_box_type == "VoiceInviteP2P" || notify_box_type == "VoiceInviteAdHoc")
+ {
+ LLFloaterReg::showInstance("incoming_call", payload, TRUE);
+ }
+ else
+ {
+ LLSD args;
+ args["NAME"] = caller_name;
+ args["GROUP"] = session_name;
+ LLNotifications::instance().add(notify_box_type, args, payload, &inviteUserResponse);
+ }
}
mPendingInvitations[session_id.asString()] = LLSD();
}
}
-//static
-void LLIMMgr::onInviteNameLookup(const LLUUID& id, const std::string& first, const std::string& last, BOOL is_group, void* userdata)
+void LLIMMgr::onInviteNameLookup(LLSD payload, const LLUUID& id, const std::string& first, const std::string& last, BOOL is_group)
{
- LLSD payload = *(LLSD*)userdata;
- delete (LLSD*)userdata;
-
payload["caller_name"] = first + " " + last;
payload["session_name"] = payload["caller_name"].asString();
- LLSD args;
- args["NAME"] = payload["caller_name"].asString();
+ std::string notify_box_type = payload["notify_box_type"].asString();
- LLNotifications::instance().add(
- payload["notify_box_type"].asString(),
- args,
- payload,
- &inviteUserResponse);
-}
-
-void LLIMMgr::refresh()
-{
-}
-
-void LLIMMgr::setFloaterOpen(BOOL set_open)
-{
- if (set_open)
+ if (notify_box_type == "VoiceInviteP2P" || notify_box_type == "VoiceInviteAdHoc")
{
- LLFloaterChatterBox::showInstance();
+ LLFloaterReg::showInstance("incoming_call", payload, TRUE);
}
else
{
- LLFloaterChatterBox::hideInstance();
+ LLSD args;
+ args["NAME"] = payload["caller_name"].asString();
+
+ LLNotifications::instance().add(
+ payload["notify_box_type"].asString(),
+ args,
+ payload,
+ &inviteUserResponse);
}
}
-
-BOOL LLIMMgr::getFloaterOpen()
+void LLIMMgr::refresh()
{
- return LLFloaterChatterBox::instanceVisible(LLSD());
}
-
+
void LLIMMgr::disconnectAllSessions()
{
LLFloaterIMPanel* floater = NULL;
@@ -1008,7 +1615,7 @@ void LLIMMgr::disconnectAllSessions()
if (floater)
{
floater->setEnabled(FALSE);
- floater->close(TRUE);
+ floater->closeFloater(TRUE);
}
}
}
@@ -1129,41 +1736,43 @@ void LLIMMgr::clearPendingAgentListUpdates(const LLUUID& session_id)
}
}
-// create a floater and update internal representation for
-// consistency. Returns the pointer, caller (the class instance since
-// it is a private method) is not responsible for deleting the
-// pointer. Add the floater to this but do not select it.
-LLFloaterIMPanel* LLIMMgr::createFloater(
- const LLUUID& session_id,
- const LLUUID& other_participant_id,
- const std::string& session_label,
- EInstantMessage dialog,
- BOOL user_initiated)
+void LLIMMgr::notifyObserverSessionAdded(const LLUUID& session_id, const std::string& name, const LLUUID& other_participant_id)
{
- if (session_id.isNull())
+ for (session_observers_list_t::iterator it = mSessionObservers.begin(); it != mSessionObservers.end(); it++)
{
- llwarns << "Creating LLFloaterIMPanel with null session ID" << llendl;
+ (*it)->sessionAdded(session_id, name, other_participant_id);
}
+}
- llinfos << "LLIMMgr::createFloater: from " << other_participant_id
- << " in session " << session_id << llendl;
- LLFloaterIMPanel* floater = new LLFloaterIMPanel(session_label,
- session_id,
- other_participant_id,
- dialog);
- LLTabContainer::eInsertionPoint i_pt = user_initiated ? LLTabContainer::RIGHT_OF_CURRENT : LLTabContainer::END;
- LLFloaterChatterBox::getInstance(LLSD())->addFloater(floater, FALSE, i_pt);
- mFloaters.insert(floater->getHandle());
- return floater;
+void LLIMMgr::notifyObserverSessionRemoved(const LLUUID& session_id)
+{
+ for (session_observers_list_t::iterator it = mSessionObservers.begin(); it != mSessionObservers.end(); it++)
+ {
+ (*it)->sessionRemoved(session_id);
+ }
}
+void LLIMMgr::addSessionObserver(LLIMSessionObserver *observer)
+{
+ mSessionObservers.push_back(observer);
+}
+
+void LLIMMgr::removeSessionObserver(LLIMSessionObserver *observer)
+{
+ mSessionObservers.remove(observer);
+}
+
+// create a floater and update internal representation for
+// consistency. Returns the pointer, caller (the class instance since
+// it is a private method) is not responsible for deleting the
+// pointer. Add the floater to this but do not select it.
LLFloaterIMPanel* LLIMMgr::createFloater(
const LLUUID& session_id,
const LLUUID& other_participant_id,
const std::string& session_label,
- const LLDynamicArray<LLUUID>& ids,
EInstantMessage dialog,
- BOOL user_initiated)
+ BOOL user_initiated,
+ const LLDynamicArray<LLUUID>& ids)
{
if (session_id.isNull())
{
@@ -1178,8 +1787,9 @@ LLFloaterIMPanel* LLIMMgr::createFloater(
ids,
dialog);
LLTabContainer::eInsertionPoint i_pt = user_initiated ? LLTabContainer::RIGHT_OF_CURRENT : LLTabContainer::END;
- LLFloaterChatterBox::getInstance(LLSD())->addFloater(floater, FALSE, i_pt);
+ LLFloaterChatterBox::getInstance()->addFloater(floater, FALSE, i_pt);
mFloaters.insert(floater->getHandle());
+ LLIMModel::instance().newSession(session_id, session_label, dialog, other_participant_id);
return floater;
}
@@ -1190,7 +1800,7 @@ void LLIMMgr::noteOfflineUsers(
S32 count = ids.count();
if(count == 0)
{
- floater->addHistoryLine(sOnlyUserMessage, gSavedSettings.getColor4("SystemChatColor"));
+ floater->addHistoryLine(sOnlyUserMessage, LLUIColorTable::instance().getColor("SystemChatColor"));
}
else
{
@@ -1206,7 +1816,7 @@ void LLIMMgr::noteOfflineUsers(
LLUIString offline = sOfflineMessage;
offline.setArg("[FIRST]", first);
offline.setArg("[LAST]", last);
- floater->addHistoryLine(offline, gSavedSettings.getColor4("SystemChatColor"));
+ floater->addHistoryLine(offline, LLUIColorTable::instance().getColor("SystemChatColor"));
}
}
}
@@ -1268,11 +1878,6 @@ void LLIMMgr::updateFloaterSessionID(
}
}
-LLFloaterChatterBox* LLIMMgr::getFloater()
-{
- return LLFloaterChatterBox::getInstance(LLSD());
-}
-
class LLViewerChatterBoxSessionStartReply : public LLHTTPNode
{
public:
@@ -1515,7 +2120,7 @@ public:
{
saved = llformat("(Saved %s) ", formatted_time(timestamp).c_str());
}
- std::string buffer = separator_string + saved + message.substr(message_offset);
+ std::string buffer = saved + message.substr(message_offset);
BOOL is_this_agent = FALSE;
if(from_id == gAgentID)
diff --git a/indra/newview/llimview.h b/indra/newview/llimview.h
index a4e419694d..ce6f0394dd 100644
--- a/indra/newview/llimview.h
+++ b/indra/newview/llimview.h
@@ -33,9 +33,12 @@
#ifndef LL_LLIMVIEW_H
#define LL_LLIMVIEW_H
-#include "llfloater.h"
+#include "lldarray.h"
+#include "llmodaldialog.h"
#include "llinstantmessage.h"
#include "lluuid.h"
+#include "llmultifloater.h"
+#include "llrecentpeople.h"
class LLFloaterChatterBox;
class LLUUID;
@@ -43,8 +46,61 @@ class LLFloaterIMPanel;
class LLFriendObserver;
class LLFloaterIM;
+class LLIMModel : public LLSingleton<LLIMModel>
+{
+public:
+
+ struct LLIMSession
+ {
+ LLIMSession(std::string name, EInstantMessage type, LLUUID other_participant_id)
+ :mName(name), mType(type), mNumUnread(0), mOtherParticipantID(other_participant_id) {}
+
+ std::string mName;
+ EInstantMessage mType;
+ LLUUID mOtherParticipantID;
+ S32 mNumUnread;
+ std::list<LLSD> mMsgs;
+ };
+
+
+ LLIMModel();
+
+ static std::map<LLUUID, LLIMSession*> sSessionsMap; //mapping session_id to session
+ boost::signals2::signal<void(const LLSD&)> mChangedSignal;
+ boost::signals2::connection addChangedCallback( boost::function<void (const LLSD& data)> cb );
+
+ bool newSession(LLUUID session_id, std::string name, EInstantMessage type, LLUUID other_participant_id);
+ bool clearSession(LLUUID session_id);
+ std::list<LLSD> getMessages(LLUUID session_id, int start_index = 0);
+ bool addMessage(LLUUID session_id, std::string from, LLUUID other_participant_id, std::string utf8_text);
+ bool addToHistory(LLUUID session_id, std::string from, std::string utf8_text);
+ //used to get the name of the session, for use as the title
+ //currently just the other avatar name
+ const std::string& getName(LLUUID session_id);
+
+ static void sendLeaveSession(LLUUID session_id, LLUUID other_participant_id);
+ static bool sendStartSession(const LLUUID& temp_session_id, const LLUUID& other_participant_id,
+ const std::vector<LLUUID>& ids, EInstantMessage dialog);
+ static void sendTypingState(LLUUID session_id, LLUUID other_participant_id, BOOL typing);
+ static void sendMessage(const std::string& utf8_text, const LLUUID& im_session_id,
+ const LLUUID& other_participant_id, EInstantMessage dialog);
+
+ void testMessages();
+};
+
+class LLIMSessionObserver
+{
+public:
+ virtual ~LLIMSessionObserver() {}
+ virtual void sessionAdded(const LLUUID& session_id, const std::string& name, const LLUUID& other_participant_id) = 0;
+ virtual void sessionRemoved(const LLUUID& session_id) = 0;
+};
+
+
class LLIMMgr : public LLSingleton<LLIMMgr>
{
+ friend class LLIMModel;
+
public:
enum EInvitationType
{
@@ -134,10 +190,8 @@ public:
// IM received that you haven't seen yet
BOOL getIMReceived() const;
- void setFloaterOpen(BOOL open); /*Flawfinder: ignore*/
- BOOL getFloaterOpen();
-
- LLFloaterChatterBox* getFloater();
+ // Calc number of unread IMs
+ S32 getNumberOfUnreadIM();
// This method is used to go through all active sessions and
// disable all of them. This method is usally called when you are
@@ -145,8 +199,6 @@ public:
// good connection.
void disconnectAllSessions();
- static void toggle(void*);
-
// This is a helper function to determine what kind of im session
// should be used for the given agent.
static EInstantMessage defaultIMTypeForAgent(const LLUUID& agent_id);
@@ -171,6 +223,9 @@ public:
//HACK: need a better way of enumerating existing session, or listening to session create/destroy events
const std::set<LLHandle<LLFloater> >& getIMFloaterHandles() { return mFloaters; }
+ void addSessionObserver(LLIMSessionObserver *);
+ void removeSessionObserver(LLIMSessionObserver *);
+
private:
// create a panel and update internal representation for
// consistency. Returns the pointer, caller (the class instance
@@ -180,14 +235,8 @@ private:
const LLUUID& target_id,
const std::string& name,
EInstantMessage dialog,
- BOOL user_initiated = FALSE);
-
- LLFloaterIMPanel* createFloater(const LLUUID& session_id,
- const LLUUID& target_id,
- const std::string& name,
- const LLDynamicArray<LLUUID>& ids,
- EInstantMessage dialog,
- BOOL user_initiated = FALSE);
+ BOOL user_initiated = FALSE,
+ const LLDynamicArray<LLUUID>& ids = LLDynamicArray<LLUUID>());
// This simple method just iterates through all of the ids, and
// prints a simple message if they are not online. Used to help
@@ -198,12 +247,18 @@ private:
void processIMTypingCore(const LLIMInfo* im_info, BOOL typing);
- static void onInviteNameLookup(const LLUUID& id, const std::string& first, const std::string& last, BOOL is_group, void* userdata);
+ static void onInviteNameLookup(LLSD payload, const LLUUID& id, const std::string& first, const std::string& last, BOOL is_group);
+
+ void notifyObserverSessionAdded(const LLUUID& session_id, const std::string& name, const LLUUID& other_participant_id);
+ void notifyObserverSessionRemoved(const LLUUID& session_id);
private:
std::set<LLHandle<LLFloater> > mFloaters;
LLFriendObserver* mFriendObserver;
+ typedef std::list <LLIMSessionObserver *> session_observers_list_t;
+ session_observers_list_t mSessionObservers;
+
// An IM has been received that you haven't seen yet.
BOOL mIMReceived;
@@ -223,6 +278,23 @@ public:
static std::map<std::string,std::string> sForceCloseSessionMap;
};
+class LLIncomingCallDialog : public LLModalDialog
+{
+public:
+ LLIncomingCallDialog(const LLSD& payload);
+
+ /*virtual*/ BOOL postBuild();
+
+ static void onAccept(void* user_data);
+ static void onReject(void* user_data);
+ static void onStartIM(void* user_data);
+
+private:
+ void processCallResponse(S32 response);
+
+ LLSD mPayload;
+};
+
// Globals
extern LLIMMgr *gIMMgr;
diff --git a/indra/newview/llinspectavatar.cpp b/indra/newview/llinspectavatar.cpp
new file mode 100644
index 0000000000..5bb96f0469
--- /dev/null
+++ b/indra/newview/llinspectavatar.cpp
@@ -0,0 +1,127 @@
+/**
+ * @file llinspectavatar.cpp
+ *
+ * $LicenseInfo:firstyear=2009&license=viewergpl$
+ *
+ * Copyright (c) 2009, Linden Research, Inc.
+ *
+ * Second Life Viewer Source Code
+ * The source code in this file ("Source Code") is provided by Linden Lab
+ * to you under the terms of the GNU General Public License, version 2.0
+ * ("GPL"), unless you have obtained a separate licensing agreement
+ * ("Other License"), formally executed by you and Linden Lab. Terms of
+ * the GPL can be found in doc/GPL-license.txt in this distribution, or
+ * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
+ *
+ * There are special exceptions to the terms and conditions of the GPL as
+ * it is applied to this Source Code. View the full text of the exception
+ * in the file doc/FLOSS-exception.txt in this software distribution, or
+ * online at
+ * http://secondlifegrid.net/programs/open_source/licensing/flossexception
+ *
+ * By copying, modifying or distributing this software, you acknowledge
+ * that you have read and understood your obligations described above,
+ * and agree to abide by those obligations.
+ *
+ * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+ * COMPLETENESS OR PERFORMANCE.
+ * $/LicenseInfo$
+ */
+
+#include "llviewerprecompiledheaders.h"
+
+#include "llinspectavatar.h"
+
+// viewer files
+#include "llagentdata.h"
+#include "llavataractions.h"
+#include "llcallingcard.h"
+
+// linden libraries
+#include "lluictrl.h"
+
+
+LLInspectAvatar::LLInspectAvatar(const LLSD& avatar_id)
+: LLFloater(avatar_id),
+ mAvatarID( avatar_id.asUUID() ),
+ mFirstName(),
+ mLastName()
+{
+}
+
+LLInspectAvatar::~LLInspectAvatar()
+{
+}
+
+/*virtual*/
+BOOL LLInspectAvatar::postBuild(void)
+{
+ getChild<LLUICtrl>("add_friend_btn")->setCommitCallback(
+ boost::bind(&LLInspectAvatar::onClickAddFriend, this) );
+
+ getChild<LLUICtrl>("view_profile_btn")->setCommitCallback(
+ boost::bind(&LLInspectAvatar::onClickViewProfile, this) );
+
+ // can't call from constructor as widgets are not built yet
+ refresh();
+
+ return TRUE;
+}
+
+void LLInspectAvatar::setAvatarID(const LLUUID &avatar_id)
+{
+ mAvatarID = avatar_id;
+ refresh();
+}
+
+void LLInspectAvatar::refresh()
+{
+ // *HACK: Don't stomp data when spawning from login screen
+ if (mAvatarID.isNull()) return;
+
+ // You can't re-add someone as a friend if they are already your friend
+ bool is_friend = LLAvatarTracker::instance().getBuddyInfo(mAvatarID) != NULL;
+ bool is_self = (mAvatarID == gAgentID);
+ childSetEnabled("add_friend_btn", !is_friend && !is_self);
+
+ // *TODO: replace with generic
+ // LLAvatarPropertiesProcessor::getInstance()->addObserver()
+ // ->sendDataRequest()
+ childSetValue("avatar_icon", LLSD(mAvatarID) );
+
+ gCacheName->get(mAvatarID, FALSE,
+ boost::bind(&LLInspectAvatar::nameUpdatedCallback,
+ this, _1, _2, _3, _4));
+}
+
+void LLInspectAvatar::nameUpdatedCallback(
+ const LLUUID& id,
+ const std::string& first,
+ const std::string& last,
+ BOOL is_group)
+{
+ // Possibly a request for an older inspector
+ if (id != mAvatarID) return;
+
+ mFirstName = first;
+ mLastName = last;
+ std::string name = first + " " + last;
+
+ childSetValue("user_name", LLSD(name) );
+}
+
+void LLInspectAvatar::onClickAddFriend()
+{
+ std::string name;
+ name.assign(getFirstName());
+ name.append(" ");
+ name.append(getLastName());
+
+ LLAvatarActions::requestFriendshipDialog(getAvatarID(), name);
+}
+
+void LLInspectAvatar::onClickViewProfile()
+{
+ LLAvatarActions::showProfile(getAvatarID());
+}
diff --git a/indra/newview/llinspectavatar.h b/indra/newview/llinspectavatar.h
new file mode 100644
index 0000000000..05b0d6fe20
--- /dev/null
+++ b/indra/newview/llinspectavatar.h
@@ -0,0 +1,80 @@
+/**
+ * @file llinspectavatar.h
+ * @brief Avatar Inspector, a small information window used when clicking
+ * on avatar names in the 2D UI and in the ambient inspector widget for
+ * the 3D world.
+ *
+ * $LicenseInfo:firstyear=2009&license=viewergpl$
+ *
+ * Copyright (c) 2009, Linden Research, Inc.
+ *
+ * Second Life Viewer Source Code
+ * The source code in this file ("Source Code") is provided by Linden Lab
+ * to you under the terms of the GNU General Public License, version 2.0
+ * ("GPL"), unless you have obtained a separate licensing agreement
+ * ("Other License"), formally executed by you and Linden Lab. Terms of
+ * the GPL can be found in doc/GPL-license.txt in this distribution, or
+ * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
+ *
+ * There are special exceptions to the terms and conditions of the GPL as
+ * it is applied to this Source Code. View the full text of the exception
+ * in the file doc/FLOSS-exception.txt in this software distribution, or
+ * online at
+ * http://secondlifegrid.net/programs/open_source/licensing/flossexception
+ *
+ * By copying, modifying or distributing this software, you acknowledge
+ * that you have read and understood your obligations described above,
+ * and agree to abide by those obligations.
+ *
+ * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+ * COMPLETENESS OR PERFORMANCE.
+ * $/LicenseInfo$
+ */
+
+#ifndef LLINSPECTAVATAR_H
+#define LLINSPECTAVATAR_H
+
+#include "llfloater.h"
+
+class LLInspectAvatar : public LLFloater
+{
+ friend class LLFloaterReg;
+
+public:
+ // key is the UUID of avatar for whom to show information
+ // *TODO: Needs to take a spawn location
+ LLInspectAvatar(const LLSD& avatar_id);
+ virtual ~LLInspectAvatar();
+
+ /*virtual*/ BOOL postBuild(void);
+
+ void setAvatarID(const LLUUID &avatar_id);
+
+ const LLUUID& getAvatarID() const { return mAvatarID; }
+ const std::string& getFirstName() const { return mFirstName; }
+ const std::string& getLastName() const { return mLastName; }
+
+private:
+ // Update widgets, including avatar name, buttons enabled, etc.
+ // Used after avatar id changes.
+ void refresh();
+
+ void onClickAddFriend();
+ void onClickViewProfile();
+
+ void nameUpdatedCallback(
+ const LLUUID& id,
+ const std::string& first,
+ const std::string& last,
+ BOOL is_group);
+
+private:
+ LLUUID mAvatarID;
+ // Need avatar name information to spawn friend add request
+ std::string mFirstName;
+ std::string mLastName;
+};
+
+
+#endif
diff --git a/indra/newview/llinventorybridge.cpp b/indra/newview/llinventorybridge.cpp
index d96bcf5bbf..789e628b67 100644
--- a/indra/newview/llinventorybridge.cpp
+++ b/indra/newview/llinventorybridge.cpp
@@ -34,14 +34,16 @@
#include <utility> // for std::pair<>
-#include "llinventoryview.h"
+#include "llfloaterinventory.h"
#include "llinventorybridge.h"
#include "message.h"
#include "llagent.h"
+#include "llagentwearables.h"
#include "llcallingcard.h"
#include "llcheckboxctrl.h" // for radio buttons
+#include "llfloaterreg.h"
#include "llradiogroup.h"
#include "llspinctrl.h"
#include "lltextbox.h"
@@ -49,13 +51,15 @@
#include "llviewercontrol.h"
#include "llfirstuse.h"
-#include "llfloateravatarinfo.h"
+#include "llfoldertype.h"
#include "llfloaterchat.h"
#include "llfloatercustomize.h"
#include "llfloaterproperties.h"
#include "llfloaterworldmap.h"
#include "llfocusmgr.h"
#include "llfolderview.h"
+#include "llfriendcard.h"
+#include "llavataractions.h"
#include "llgesturemgr.h"
#include "lliconctrl.h"
#include "llinventorymodel.h"
@@ -64,7 +68,6 @@
#include "llmenugl.h"
#include "llpreviewanim.h"
#include "llpreviewgesture.h"
-#include "llpreviewlandmark.h"
#include "llpreviewnotecard.h"
#include "llpreviewscript.h"
#include "llpreviewsound.h"
@@ -73,7 +76,7 @@
#include "llscrollcontainer.h"
#include "llimview.h"
#include "lltooldraganddrop.h"
-#include "llviewerimagelist.h"
+#include "llviewertexturelist.h"
#include "llviewerinventory.h"
#include "llviewerobjectlist.h"
#include "llviewerwindow.h"
@@ -82,10 +85,13 @@
#include "llwearablelist.h"
#include "llviewermessage.h"
#include "llviewerregion.h"
+#include "llvoavatarself.h"
#include "lltabcontainer.h"
#include "lluictrlfactory.h"
#include "llselectmgr.h"
+#include "llsidetray.h"
#include "llfloateropenobject.h"
+#include "lltrans.h"
using namespace LLOldEvents;
@@ -106,12 +112,13 @@ void dec_busy_count()
// Function declarations
struct LLWearableHoldingPattern;
+void wear_add_inventory_item_on_avatar(LLInventoryItem* item);
void wear_inventory_category_on_avatar(LLInventoryCategory* category, BOOL append);
-void wear_inventory_category_on_avatar_step2( BOOL proceed, void* userdata);
+void wear_inventory_category_on_avatar_step2( BOOL proceed, LLUUID category, BOOL append, BOOL follow_folder_links);
void wear_inventory_category_on_avatar_loop(LLWearable* wearable, void*);
void wear_inventory_category_on_avatar_step3(LLWearableHoldingPattern* holder, BOOL append);
void remove_inventory_category_from_avatar(LLInventoryCategory* category);
-void remove_inventory_category_from_avatar_step2( BOOL proceed, void* userdata);
+void remove_inventory_category_from_avatar_step2( BOOL proceed, LLUUID category_id);
bool move_task_inventory_callback(const LLSD& notification, const LLSD& response, LLMoveInv*);
bool confirm_replace_attachment_rez(const LLSD& notification, const LLSD& response);
@@ -144,23 +151,38 @@ std::string ICON_NAME[ICON_NAME_COUNT] =
"inv_item_undershirt.tga",
"inv_item_underpants.tga",
"inv_item_skirt.tga",
+ "inv_item_alpha.tga",
+ "inv_item_tattoo.tga",
"inv_item_animation.tga",
"inv_item_gesture.tga",
-};
-struct LLWearInfo
-{
- LLUUID mCategoryID;
- BOOL mAppend;
+ "inv_item_linkitem.tga",
+ "inv_item_linkfolder.tga"
};
BOOL gAddToOutfit = FALSE;
+
+// +=================================================+
+// | LLInventoryPanelObserver |
+// +=================================================+
+void LLInventoryPanelObserver::changed(U32 mask)
+{
+ mIP->modelChanged(mask);
+}
+
+
// +=================================================+
// | LLInvFVBridge |
// +=================================================+
+LLInvFVBridge::LLInvFVBridge(LLInventoryPanel* inventory, const LLUUID& uuid) :
+mUUID(uuid), mInvType(LLInventoryType::IT_NONE)
+{
+ mInventoryPanel = inventory->getHandle();
+}
+
const std::string& LLInvFVBridge::getName() const
{
LLInventoryObject* obj = getInventoryObject();
@@ -183,6 +205,13 @@ PermissionMask LLInvFVBridge::getPermissionMask() const
return PERM_ALL;
}
+// virtual
+LLAssetType::EType LLInvFVBridge::getPreferredType() const
+{
+ return LLAssetType::AT_NONE;
+}
+
+
// Folders don't have creation dates.
time_t LLInvFVBridge::getCreationDate() const
{
@@ -192,15 +221,47 @@ time_t LLInvFVBridge::getCreationDate() const
// Can be destoryed (or moved to trash)
BOOL LLInvFVBridge::isItemRemovable()
{
- LLInventoryModel* model = mInventoryPanel->getModel();
+ LLInventoryModel* model = getInventoryModel();
if(!model) return FALSE;
- if(model->isObjectDescendentOf(mUUID, gAgent.getInventoryRootID()))
+ if(model->isObjectDescendentOf(mUUID, gInventory.getRootFolderID()))
{
return TRUE;
}
return FALSE;
}
+// Sends an update to all link items that point to the base item.
+void LLInvFVBridge::renameLinkedItems(const LLUUID &item_id, const std::string& new_name)
+{
+ LLInventoryModel* model = getInventoryModel();
+ if(!model) return;
+
+ LLInventoryItem* itemp = model->getItem(mUUID);
+ if (!itemp) return;
+
+ if (itemp->getIsLinkType())
+ {
+ return;
+ }
+
+ LLInventoryModel::item_array_t item_array;
+ model->collectLinkedItems(item_id, item_array);
+ for (LLInventoryModel::item_array_t::iterator iter = item_array.begin();
+ iter != item_array.end();
+ iter++)
+ {
+ LLViewerInventoryItem *linked_item = (*iter);
+ if (linked_item->getUUID() == item_id) continue;
+
+ LLPointer<LLViewerInventoryItem> new_item = new LLViewerInventoryItem(linked_item);
+ new_item->rename(new_name);
+ new_item->updateServer(FALSE);
+ model->updateItem(new_item);
+ // model->addChangedMask(LLInventoryObserver::LABEL, linked_item->getUUID());
+ }
+ model->notifyObservers();
+}
+
// Can be moved to another folder
BOOL LLInvFVBridge::isItemMovable()
{
@@ -210,14 +271,14 @@ BOOL LLInvFVBridge::isItemMovable()
// *TODO: make sure this does the right thing
void LLInvFVBridge::showProperties()
{
- LLShowProps::showProperties(mUUID);
+ LLFloaterReg::showInstance("properties", mUUID);
}
void LLInvFVBridge::removeBatch(LLDynamicArray<LLFolderViewEventListener*>& batch)
{
// Deactivate gestures when moving them into Trash
LLInvFVBridge* bridge;
- LLInventoryModel* model = mInventoryPanel->getModel();
+ LLInventoryModel* model = getInventoryModel();
LLViewerInventoryItem* item = NULL;
LLViewerInventoryCategory* cat = NULL;
LLInventoryModel::cat_array_t descendent_categories;
@@ -233,7 +294,7 @@ void LLInvFVBridge::removeBatch(LLDynamicArray<LLFolderViewEventListener*>& batc
{
if(LLAssetType::AT_GESTURE == item->getType())
{
- gGestureManager.deactivateGesture(item->getUUID());
+ LLGestureManager::instance().deactivateGesture(item->getUUID());
}
}
}
@@ -249,7 +310,7 @@ void LLInvFVBridge::removeBatch(LLDynamicArray<LLFolderViewEventListener*>& batc
{
if(LLAssetType::AT_GESTURE == descendent_items[j]->getType())
{
- gGestureManager.deactivateGesture(descendent_items[j]->getUUID());
+ LLGestureManager::instance().deactivateGesture(descendent_items[j]->getUUID());
}
}
}
@@ -265,7 +326,7 @@ void LLInvFVBridge::removeBatchNoCheck(LLDynamicArray<LLFolderViewEventListener*
// we call LLInventoryModel::moveObject() to move everything
// around.
LLInvFVBridge* bridge;
- LLInventoryModel* model = mInventoryPanel->getModel();
+ LLInventoryModel* model = getInventoryModel();
if(!model) return;
LLMessageSystem* msg = gMessageSystem;
LLUUID trash_id = model->findCategoryUUIDForType(LLAssetType::AT_TRASH);
@@ -369,20 +430,76 @@ void LLInvFVBridge::removeBatchNoCheck(LLDynamicArray<LLFolderViewEventListener*
BOOL LLInvFVBridge::isClipboardPasteable() const
{
- LLInventoryModel* model = mInventoryPanel->getModel();
- if(!model) return FALSE;
- BOOL is_agent_inventory = model->isObjectDescendentOf(mUUID, gAgent.getInventoryRootID());
+ if (!LLInventoryClipboard::instance().hasContents() || !isAgentInventory())
+ {
+ return FALSE;
+ }
+ LLInventoryModel* model = getInventoryModel();
+ if (!model)
+ {
+ return FALSE;
+ }
+
+ const LLUUID &agent_id = gAgent.getID();
- if(LLInventoryClipboard::instance().hasContents() && is_agent_inventory)
+ LLDynamicArray<LLUUID> objects;
+ LLInventoryClipboard::instance().retrieve(objects);
+ S32 count = objects.count();
+ for(S32 i = 0; i < count; i++)
{
- return TRUE;
+ const LLUUID &item_id = objects.get(i);
+
+ // Can't paste folders
+ const LLInventoryCategory *cat = model->getCategory(item_id);
+ if (cat)
+ {
+ return FALSE;
+ }
+
+ const LLInventoryItem *item = model->getItem(item_id);
+ if (item)
+ {
+ if (!item->getPermissions().allowCopyBy(agent_id))
+ {
+ return FALSE;
+ }
+ }
}
- return FALSE;
+ return TRUE;
+}
+
+BOOL LLInvFVBridge::isClipboardPasteableAsLink() const
+{
+ if (!LLInventoryClipboard::instance().hasContents() || !isAgentInventory())
+ {
+ return FALSE;
+ }
+ LLInventoryModel* model = getInventoryModel();
+ if (!model)
+ {
+ return FALSE;
+ }
+
+ LLDynamicArray<LLUUID> objects;
+ LLInventoryClipboard::instance().retrieve(objects);
+ S32 count = objects.count();
+ for(S32 i = 0; i < count; i++)
+ {
+ LLInventoryItem *item = model->getItem(objects.get(i));
+ if (item)
+ {
+ if (!LLAssetType::lookupCanLink(item->getActualType()))
+ {
+ return FALSE;
+ }
+ }
+ }
+ return TRUE;
}
void hideContextEntries(LLMenuGL& menu,
- const std::vector<std::string> &entries_to_show,
- const std::vector<std::string> &disabled_entries)
+ const std::vector<std::string> &entries_to_show,
+ const std::vector<std::string> &disabled_entries)
{
const LLView::child_list_t *list = menu.getChildList();
@@ -426,10 +543,10 @@ void hideContextEntries(LLMenuGL& menu,
}
// Helper for commonly-used entries
-void LLInvFVBridge::getClipboardEntries(bool show_asset_id, std::vector<std::string> &items,
- std::vector<std::string> &disabled_items, U32 flags)
+void LLInvFVBridge::getClipboardEntries(bool show_asset_id,
+ std::vector<std::string> &items,
+ std::vector<std::string> &disabled_items, U32 flags)
{
- // *TODO: Translate
items.push_back(std::string("Rename"));
if (!isItemRenameable() || (flags & FIRST_SELECTED_ITEM) == 0)
{
@@ -460,6 +577,11 @@ void LLInvFVBridge::getClipboardEntries(bool show_asset_id, std::vector<std::str
disabled_items.push_back(std::string("Paste"));
}
+ items.push_back(std::string("Paste As Link"));
+ if (!isClipboardPasteableAsLink() || (flags & FIRST_SELECTED_ITEM) == 0)
+ {
+ disabled_items.push_back(std::string("Paste As Link"));
+ }
items.push_back(std::string("Paste Separator"));
items.push_back(std::string("Delete"));
@@ -471,18 +593,17 @@ void LLInvFVBridge::getClipboardEntries(bool show_asset_id, std::vector<std::str
void LLInvFVBridge::buildContextMenu(LLMenuGL& menu, U32 flags)
{
- // *TODO: Translate
lldebugs << "LLInvFVBridge::buildContextMenu()" << llendl;
std::vector<std::string> items;
std::vector<std::string> disabled_items;
if(isInTrash())
{
- items.push_back(std::string("Purge Item"));
+ items.push_back(std::string("PurgeItem"));
if (!isItemRemovable())
{
- disabled_items.push_back(std::string("Purge Item"));
+ disabled_items.push_back(std::string("PurgeItem"));
}
- items.push_back(std::string("Restore Item"));
+ items.push_back(std::string("RestoreItem"));
}
else
{
@@ -503,7 +624,7 @@ BOOL LLInvFVBridge::startDrag(EDragAndDropType* type, LLUUID* id) const
if(obj)
{
- *type = LLAssetType::lookupDragAndDropType(obj->getType());
+ *type = LLAssetType::lookupDragAndDropType(obj->getActualType());
if(*type == DAD_NONE)
{
return FALSE;
@@ -526,7 +647,7 @@ BOOL LLInvFVBridge::startDrag(EDragAndDropType* type, LLUUID* id) const
LLInventoryObject* LLInvFVBridge::getInventoryObject() const
{
LLInventoryObject* obj = NULL;
- LLInventoryModel* model = mInventoryPanel->getModel();
+ LLInventoryModel* model = getInventoryModel();
if(model)
{
obj = (LLInventoryObject*)model->getObject(mUUID);
@@ -534,20 +655,41 @@ LLInventoryObject* LLInvFVBridge::getInventoryObject() const
return obj;
}
+LLInventoryModel* LLInvFVBridge::getInventoryModel() const
+{
+ LLInventoryPanel* panel = dynamic_cast<LLInventoryPanel*>(mInventoryPanel.get());
+ return panel ? panel->getModel() : NULL;
+}
+
BOOL LLInvFVBridge::isInTrash() const
{
- LLInventoryModel* model = mInventoryPanel->getModel();
+ LLInventoryModel* model = getInventoryModel();
if(!model) return FALSE;
- LLUUID trash_id = model->findCategoryUUIDForType(LLAssetType::AT_TRASH);
+ const LLUUID& trash_id = model->findCategoryUUIDForType(LLAssetType::AT_TRASH);
return model->isObjectDescendentOf(mUUID, trash_id);
}
+BOOL LLInvFVBridge::isLinkedObjectInTrash() const
+{
+ if (isInTrash()) return TRUE;
+
+ LLInventoryObject *obj = getInventoryObject();
+ if (obj && obj->getIsLinkType())
+ {
+ LLInventoryModel* model = getInventoryModel();
+ if(!model) return FALSE;
+ const LLUUID& trash_id = model->findCategoryUUIDForType(LLAssetType::AT_TRASH);
+ return model->isObjectDescendentOf(obj->getLinkedUUID(), trash_id);
+ }
+ return FALSE;
+}
+
BOOL LLInvFVBridge::isAgentInventory() const
{
- LLInventoryModel* model = mInventoryPanel->getModel();
+ LLInventoryModel* model = getInventoryModel();
if(!model) return FALSE;
- if(gAgent.getInventoryRootID() == mUUID) return TRUE;
- return model->isObjectDescendentOf(mUUID, gAgent.getInventoryRootID());
+ if(gInventory.getRootFolderID() == mUUID) return TRUE;
+ return model->isObjectDescendentOf(mUUID, gInventory.getRootFolderID());
}
BOOL LLInvFVBridge::isItemPermissive() const
@@ -613,112 +755,125 @@ const std::string safe_inv_type_lookup(LLInventoryType::EType inv_type)
}
LLInvFVBridge* LLInvFVBridge::createBridge(LLAssetType::EType asset_type,
- LLInventoryType::EType inv_type,
- LLInventoryPanel* inventory,
- const LLUUID& uuid,
- U32 flags)
+ LLAssetType::EType actual_asset_type,
+ LLInventoryType::EType inv_type,
+ LLInventoryPanel* inventory,
+ const LLUUID& uuid,
+ U32 flags)
{
LLInvFVBridge* new_listener = NULL;
switch(asset_type)
{
- case LLAssetType::AT_TEXTURE:
- if(!(inv_type == LLInventoryType::IT_TEXTURE || inv_type == LLInventoryType::IT_SNAPSHOT))
- {
- llwarns << LLAssetType::lookup(asset_type) << " asset has inventory type " << safe_inv_type_lookup(inv_type) << " on uuid " << uuid << llendl;
- }
- new_listener = new LLTextureBridge(inventory, uuid, inv_type);
- break;
+ case LLAssetType::AT_TEXTURE:
+ if(!(inv_type == LLInventoryType::IT_TEXTURE || inv_type == LLInventoryType::IT_SNAPSHOT))
+ {
+ llwarns << LLAssetType::lookup(asset_type) << " asset has inventory type " << safe_inv_type_lookup(inv_type) << " on uuid " << uuid << llendl;
+ }
+ new_listener = new LLTextureBridge(inventory, uuid, inv_type);
+ break;
- case LLAssetType::AT_SOUND:
- if(!(inv_type == LLInventoryType::IT_SOUND))
- {
- llwarns << LLAssetType::lookup(asset_type) << " asset has inventory type " << safe_inv_type_lookup(inv_type) << " on uuid " << uuid << llendl;
- }
- new_listener = new LLSoundBridge(inventory, uuid);
- break;
+ case LLAssetType::AT_SOUND:
+ if(!(inv_type == LLInventoryType::IT_SOUND))
+ {
+ llwarns << LLAssetType::lookup(asset_type) << " asset has inventory type " << safe_inv_type_lookup(inv_type) << " on uuid " << uuid << llendl;
+ }
+ new_listener = new LLSoundBridge(inventory, uuid);
+ break;
- case LLAssetType::AT_LANDMARK:
- if(!(inv_type == LLInventoryType::IT_LANDMARK))
- {
- llwarns << LLAssetType::lookup(asset_type) << " asset has inventory type " << safe_inv_type_lookup(inv_type) << " on uuid " << uuid << llendl;
- }
- new_listener = new LLLandmarkBridge(inventory, uuid, flags);
- break;
+ case LLAssetType::AT_LANDMARK:
+ if(!(inv_type == LLInventoryType::IT_LANDMARK))
+ {
+ llwarns << LLAssetType::lookup(asset_type) << " asset has inventory type " << safe_inv_type_lookup(inv_type) << " on uuid " << uuid << llendl;
+ }
+ new_listener = new LLLandmarkBridge(inventory, uuid, flags);
+ break;
- case LLAssetType::AT_CALLINGCARD:
- if(!(inv_type == LLInventoryType::IT_CALLINGCARD))
- {
- llwarns << LLAssetType::lookup(asset_type) << " asset has inventory type " << safe_inv_type_lookup(inv_type) << " on uuid " << uuid << llendl;
- }
- new_listener = new LLCallingCardBridge(inventory, uuid);
- break;
-
- case LLAssetType::AT_SCRIPT:
- if(!(inv_type == LLInventoryType::IT_LSL))
- {
- llwarns << LLAssetType::lookup(asset_type) << " asset has inventory type " << safe_inv_type_lookup(inv_type) << " on uuid " << uuid << llendl;
- }
- new_listener = new LLScriptBridge(inventory, uuid);
- break;
+ case LLAssetType::AT_CALLINGCARD:
+ if(!(inv_type == LLInventoryType::IT_CALLINGCARD))
+ {
+ llwarns << LLAssetType::lookup(asset_type) << " asset has inventory type " << safe_inv_type_lookup(inv_type) << " on uuid " << uuid << llendl;
+ }
+ new_listener = new LLCallingCardBridge(inventory, uuid);
+ break;
- case LLAssetType::AT_OBJECT:
- if(!(inv_type == LLInventoryType::IT_OBJECT || inv_type == LLInventoryType::IT_ATTACHMENT))
- {
- llwarns << LLAssetType::lookup(asset_type) << " asset has inventory type " << safe_inv_type_lookup(inv_type) << " on uuid " << uuid << llendl;
- }
- new_listener = new LLObjectBridge(inventory, uuid, inv_type, flags);
- break;
+ case LLAssetType::AT_SCRIPT:
+ if(!(inv_type == LLInventoryType::IT_LSL))
+ {
+ llwarns << LLAssetType::lookup(asset_type) << " asset has inventory type " << safe_inv_type_lookup(inv_type) << " on uuid " << uuid << llendl;
+ }
+ new_listener = new LLScriptBridge(inventory, uuid);
+ break;
- case LLAssetType::AT_NOTECARD:
- if(!(inv_type == LLInventoryType::IT_NOTECARD))
- {
- llwarns << LLAssetType::lookup(asset_type) << " asset has inventory type " << safe_inv_type_lookup(inv_type) << " on uuid " << uuid << llendl;
- }
- new_listener = new LLNotecardBridge(inventory, uuid);
- break;
+ case LLAssetType::AT_OBJECT:
+ if(!(inv_type == LLInventoryType::IT_OBJECT || inv_type == LLInventoryType::IT_ATTACHMENT))
+ {
+ llwarns << LLAssetType::lookup(asset_type) << " asset has inventory type " << safe_inv_type_lookup(inv_type) << " on uuid " << uuid << llendl;
+ }
+ new_listener = new LLObjectBridge(inventory, uuid, inv_type, flags);
+ break;
- case LLAssetType::AT_ANIMATION:
- if(!(inv_type == LLInventoryType::IT_ANIMATION))
- {
- llwarns << LLAssetType::lookup(asset_type) << " asset has inventory type " << safe_inv_type_lookup(inv_type) << " on uuid " << uuid << llendl;
- }
- new_listener = new LLAnimationBridge(inventory, uuid);
- break;
+ case LLAssetType::AT_NOTECARD:
+ if(!(inv_type == LLInventoryType::IT_NOTECARD))
+ {
+ llwarns << LLAssetType::lookup(asset_type) << " asset has inventory type " << safe_inv_type_lookup(inv_type) << " on uuid " << uuid << llendl;
+ }
+ new_listener = new LLNotecardBridge(inventory, uuid);
+ break;
- case LLAssetType::AT_GESTURE:
- if(!(inv_type == LLInventoryType::IT_GESTURE))
- {
- llwarns << LLAssetType::lookup(asset_type) << " asset has inventory type " << safe_inv_type_lookup(inv_type) << " on uuid " << uuid << llendl;
- }
- new_listener = new LLGestureBridge(inventory, uuid);
- break;
+ case LLAssetType::AT_ANIMATION:
+ if(!(inv_type == LLInventoryType::IT_ANIMATION))
+ {
+ llwarns << LLAssetType::lookup(asset_type) << " asset has inventory type " << safe_inv_type_lookup(inv_type) << " on uuid " << uuid << llendl;
+ }
+ new_listener = new LLAnimationBridge(inventory, uuid);
+ break;
- case LLAssetType::AT_LSL_TEXT:
- if(!(inv_type == LLInventoryType::IT_LSL))
- {
- llwarns << LLAssetType::lookup(asset_type) << " asset has inventory type " << safe_inv_type_lookup(inv_type) << " on uuid " << uuid << llendl;
- }
- new_listener = new LLLSLTextBridge(inventory, uuid);
- break;
+ case LLAssetType::AT_GESTURE:
+ if(!(inv_type == LLInventoryType::IT_GESTURE))
+ {
+ llwarns << LLAssetType::lookup(asset_type) << " asset has inventory type " << safe_inv_type_lookup(inv_type) << " on uuid " << uuid << llendl;
+ }
+ new_listener = new LLGestureBridge(inventory, uuid);
+ break;
- case LLAssetType::AT_CLOTHING:
- case LLAssetType::AT_BODYPART:
- if(!(inv_type == LLInventoryType::IT_WEARABLE))
- {
- llwarns << LLAssetType::lookup(asset_type) << " asset has inventory type " << safe_inv_type_lookup(inv_type) << " on uuid " << uuid << llendl;
- }
- new_listener = new LLWearableBridge(inventory, uuid, asset_type, inv_type, (EWearableType)flags);
- break;
+ case LLAssetType::AT_LSL_TEXT:
+ if(!(inv_type == LLInventoryType::IT_LSL))
+ {
+ llwarns << LLAssetType::lookup(asset_type) << " asset has inventory type " << safe_inv_type_lookup(inv_type) << " on uuid " << uuid << llendl;
+ }
+ new_listener = new LLLSLTextBridge(inventory, uuid);
+ break;
- case LLAssetType::AT_CATEGORY:
- case LLAssetType::AT_ROOT_CATEGORY:
- new_listener = new LLFolderBridge(inventory, uuid);
- break;
-
- default:
- llinfos << "Unhandled asset type (llassetstorage.h): "
- << (S32)asset_type << llendl;
- break;
+ case LLAssetType::AT_CLOTHING:
+ case LLAssetType::AT_BODYPART:
+ if(!(inv_type == LLInventoryType::IT_WEARABLE))
+ {
+ llwarns << LLAssetType::lookup(asset_type) << " asset has inventory type " << safe_inv_type_lookup(inv_type) << " on uuid " << uuid << llendl;
+ }
+ new_listener = new LLWearableBridge(inventory, uuid, asset_type, inv_type, (EWearableType)flags);
+ break;
+ case LLAssetType::AT_CATEGORY:
+ case LLAssetType::AT_ROOT_CATEGORY:
+ if (actual_asset_type == LLAssetType::AT_LINK_FOLDER)
+ {
+ // Create a link folder handler instead.
+ new_listener = new LLLinkFolderBridge(inventory, uuid);
+ break;
+ }
+ new_listener = new LLFolderBridge(inventory, uuid);
+ break;
+ case LLAssetType::AT_LINK:
+ // Only should happen for broken links.
+ new_listener = new LLLinkItemBridge(inventory, uuid);
+ break;
+ case LLAssetType::AT_LINK_FOLDER:
+ // Only should happen for broken links.
+ new_listener = new LLLinkItemBridge(inventory, uuid);
+ break;
+ default:
+ llinfos << "Unhandled asset type (llassetstorage.h): "
+ << (S32)asset_type << llendl;
+ break;
}
if (new_listener)
@@ -729,41 +884,56 @@ LLInvFVBridge* LLInvFVBridge::createBridge(LLAssetType::EType asset_type,
return new_listener;
}
+void LLInvFVBridge::purgeItem(LLInventoryModel *model, const LLUUID &uuid)
+{
+ LLInventoryCategory* cat = model->getCategory(uuid);
+ if (cat)
+ {
+ model->purgeDescendentsOf(uuid);
+ model->notifyObservers();
+ }
+ LLInventoryObject* obj = model->getObject(uuid);
+ if (obj)
+ {
+ model->purgeObject(uuid);
+ model->notifyObservers();
+ }
+}
+
// +=================================================+
// | LLItemBridge |
// +=================================================+
void LLItemBridge::performAction(LLFolderView* folder, LLInventoryModel* model, std::string action)
{
+ if ("goto" == action)
+ {
+ gotoItem(folder);
+ }
if ("open" == action)
{
openItem();
+ return;
}
else if ("properties" == action)
{
showProperties();
+ return;
}
else if ("purge" == action)
{
- LLInventoryCategory* cat = model->getCategory(mUUID);
- if(cat)
- {
- model->purgeDescendentsOf(mUUID);
- }
- LLInventoryObject* obj = model->getObject(mUUID);
- if(!obj) return;
- obj->removeFromServer();
- LLPreview::hide(mUUID);
- model->deleteObject(mUUID);
- model->notifyObservers();
+ purgeItem(model, mUUID);
+ return;
}
else if ("restoreToWorld" == action)
{
restoreToWorld();
+ return;
}
else if ("restore" == action)
{
restoreItem();
+ return;
}
else if ("copy_uuid" == action)
{
@@ -794,6 +964,18 @@ void LLItemBridge::performAction(LLFolderView* folder, LLInventoryModel* model,
folder_view_itemp->getListener()->pasteFromClipboard();
return;
}
+ else if ("paste_link" == action)
+ {
+ // Single item only
+ LLInventoryItem* itemp = model->getItem(mUUID);
+ if (!itemp) return;
+
+ LLFolderViewItem* folder_view_itemp = folder->getItemByID(itemp->getParentUUID());
+ if (!folder_view_itemp) return;
+
+ folder_view_itemp->getListener()->pasteLinkFromClipboard();
+ return;
+ }
}
void LLItemBridge::selectItem()
@@ -810,7 +992,7 @@ void LLItemBridge::restoreItem()
LLViewerInventoryItem* item = (LLViewerInventoryItem*)getItem();
if(item)
{
- LLInventoryModel* model = mInventoryPanel->getModel();
+ LLInventoryModel* model = getInventoryModel();
LLUUID new_parent = model->findCategoryUUIDForType(item->getType());
// do not restamp on restore.
LLInvFVBridge::changeItemParent(model, item, new_parent, FALSE);
@@ -858,6 +1040,19 @@ void LLItemBridge::restoreToWorld()
}
}
+void LLItemBridge::gotoItem(LLFolderView *folder)
+{
+ LLInventoryObject *obj = getInventoryObject();
+ if (obj && obj->getIsLinkType())
+ {
+ LLInventoryPanel* active_panel = LLFloaterInventory::getActiveInventory()->getPanel();
+ if (active_panel)
+ {
+ active_panel->setSelection(obj->getLinkedUUID(), TAKE_FOCUS_NO);
+ }
+ }
+}
+
LLUIImagePtr LLItemBridge::getIcon() const
{
return LLUI::getUIImage(ICON_NAME[OBJECT_ICON_NAME]);
@@ -881,7 +1076,7 @@ PermissionMask LLItemBridge::getPermissionMask() const
}
return perm_mask;
}
-
+
const std::string& LLItemBridge::getDisplayName() const
{
if(mDisplayName.empty())
@@ -903,8 +1098,33 @@ void LLItemBridge::buildDisplayName(LLInventoryItem* item, std::string& name)
}
}
+LLFontGL::StyleFlags LLItemBridge::getLabelStyle() const
+{
+ U8 font = LLFontGL::NORMAL;
+
+ if( gAgentWearables.isWearingItem( mUUID ) )
+ {
+ // llinfos << "BOLD" << llendl;
+ font |= LLFontGL::BOLD;
+ }
+
+ const LLViewerInventoryItem* item = getItem();
+ if (item && item->getIsLinkType())
+ {
+ font |= LLFontGL::ITALIC;
+ }
+ return (LLFontGL::StyleFlags)font;
+}
+
std::string LLItemBridge::getLabelSuffix() const
{
+ // String table is loaded before login screen and inventory items are
+ // loaded after login, so LLTrans should be ready.
+ static std::string NO_COPY =LLTrans::getString("no_copy");
+ static std::string NO_MOD = LLTrans::getString("no_modify");
+ static std::string NO_XFER = LLTrans::getString("no_transfer");
+ static std::string LINK = LLTrans::getString("link");
+ static std::string BROKEN_LINK = LLTrans::getString("broken_link");
std::string suffix;
LLInventoryItem* item = getItem();
if(item)
@@ -913,25 +1133,28 @@ std::string LLItemBridge::getLabelSuffix() const
if(LLAssetType::AT_CALLINGCARD != item->getType()
&& item->getPermissions().getOwner() == gAgent.getID())
{
+ BOOL broken_link = LLAssetType::lookupIsLinkType(item->getType());
+ if (broken_link) return BROKEN_LINK;
+
+ BOOL link = item->getIsLinkType();
+ if (link) return LINK;
+
BOOL copy = item->getPermissions().allowCopyBy(gAgent.getID());
+ if (!copy)
+ {
+ suffix += NO_COPY;
+ }
BOOL mod = item->getPermissions().allowModifyBy(gAgent.getID());
+ if (!mod)
+ {
+ suffix += NO_MOD;
+ }
BOOL xfer = item->getPermissions().allowOperationBy(PERM_TRANSFER,
gAgent.getID());
- // *TODO: Translate
- const char* EMPTY = "";
- const char* NO_COPY = " (no copy)";
- const char* NO_MOD = " (no modify)";
- const char* NO_XFER = " (no transfer)";
- const char* scopy;
- if(copy) scopy = EMPTY;
- else scopy = NO_COPY;
- const char* smod;
- if(mod) smod = EMPTY;
- else smod = NO_MOD;
- const char* sxfer;
- if(xfer) sxfer = EMPTY;
- else sxfer = NO_XFER;
- suffix = llformat("%s%s%s",scopy,smod,sxfer);
+ if (!xfer)
+ {
+ suffix += NO_XFER;
+ }
}
}
return suffix;
@@ -953,6 +1176,12 @@ BOOL LLItemBridge::isItemRenameable() const
LLViewerInventoryItem* item = getItem();
if(item)
{
+ // (For now) Don't allow calling card rename since that may confuse users as to
+ // what the calling card points to.
+ if (item->getInventoryType() == LLInventoryType::IT_CALLINGCARD)
+ {
+ return FALSE;
+ }
return (item->getPermissions().allowModifyBy(gAgent.getID()));
}
return FALSE;
@@ -960,10 +1189,12 @@ BOOL LLItemBridge::isItemRenameable() const
BOOL LLItemBridge::renameItem(const std::string& new_name)
{
- if(!isItemRenameable()) return FALSE;
- LLPreview::rename(mUUID, getPrefix() + new_name);
- LLInventoryModel* model = mInventoryPanel->getModel();
- if(!model) return FALSE;
+ if(!isItemRenameable())
+ return FALSE;
+ LLPreview::dirty(mUUID);
+ LLInventoryModel* model = getInventoryModel();
+ if(!model)
+ return FALSE;
LLViewerInventoryItem* item = getItem();
if(item && (item->getName() != new_name))
{
@@ -972,6 +1203,8 @@ BOOL LLItemBridge::renameItem(const std::string& new_name)
buildDisplayName(new_item, mDisplayName);
new_item->updateServer(FALSE);
model->updateItem(new_item);
+ model->updateLinkedObjects(item->getUUID());
+
model->notifyObservers();
}
// return FALSE because we either notified observers (& therefore
@@ -988,7 +1221,7 @@ BOOL LLItemBridge::removeItem()
}
// move it to the trash
LLPreview::hide(mUUID, TRUE);
- LLInventoryModel* model = mInventoryPanel->getModel();
+ LLInventoryModel* model = getInventoryModel();
if(!model) return FALSE;
LLUUID trash_id = model->findCategoryUUIDForType(LLAssetType::AT_TRASH);
LLViewerInventoryItem* item = getItem();
@@ -1014,19 +1247,25 @@ BOOL LLItemBridge::isItemCopyable() const
if (item)
{
// can't copy worn objects. DEV-15183
- LLVOAvatar *avatarp = gAgent.getAvatarObject();
+ LLVOAvatarSelf *avatarp = gAgent.getAvatarObject();
if( !avatarp )
{
return FALSE;
}
- if( avatarp->isWearingAttachment( mUUID ) )
+ if( avatarp->isWearingAttachment( mUUID, TRUE ) )
{
return FALSE;
}
-
-
- return (item->getPermissions().allowCopyBy(gAgent.getID()));
+
+ // All items can be copied, not all can be pasted.
+ // The only time an item can't be copied is if it's a link
+ // return (item->getPermissions().allowCopyBy(gAgent.getID()));
+ if (item->getIsLinkType())
+ {
+ return FALSE;
+ }
+ return TRUE;
}
return FALSE;
}
@@ -1043,7 +1282,7 @@ BOOL LLItemBridge::copyToClipboard() const
LLViewerInventoryItem* LLItemBridge::getItem() const
{
LLViewerInventoryItem* item = NULL;
- LLInventoryModel* model = mInventoryPanel->getModel();
+ LLInventoryModel* model = getInventoryModel();
if(model)
{
item = (LLViewerInventoryItem*)model->getItem(mUUID);
@@ -1077,7 +1316,7 @@ BOOL LLFolderBridge::isItemMovable()
LLInventoryObject* obj = getInventoryObject();
if(obj)
{
- return (LLAssetType::AT_NONE == ((LLInventoryCategory*)obj)->getPreferredType());
+ return (!LLAssetType::lookupIsProtectedCategoryType(((LLInventoryCategory*)obj)->getPreferredType()));
}
return FALSE;
}
@@ -1090,18 +1329,18 @@ void LLFolderBridge::selectItem()
// Can be destroyed (or moved to trash)
BOOL LLFolderBridge::isItemRemovable()
{
- LLInventoryModel* model = mInventoryPanel->getModel();
+ LLInventoryModel* model = getInventoryModel();
if(!model)
{
return FALSE;
}
- if(!model->isObjectDescendentOf(mUUID, gAgent.getInventoryRootID()))
+ if(!model->isObjectDescendentOf(mUUID, gInventory.getRootFolderID()))
{
return FALSE;
}
- LLVOAvatar* avatar = gAgent.getAvatarObject();
+ LLVOAvatarSelf* avatar = gAgent.getAvatarObject();
if( !avatar )
{
return FALSE;
@@ -1113,7 +1352,7 @@ BOOL LLFolderBridge::isItemRemovable()
return FALSE;
}
- if( LLAssetType::AT_NONE != category->getPreferredType() )
+ if(LLAssetType::lookupIsProtectedCategoryType(category->getPreferredType()))
{
return FALSE;
}
@@ -1126,7 +1365,7 @@ BOOL LLFolderBridge::isItemRemovable()
for( i = 0; i < descendent_categories.count(); i++ )
{
LLInventoryCategory* category = descendent_categories[i];
- if( LLAssetType::AT_NONE != category->getPreferredType() )
+ if(LLAssetType::lookupIsProtectedCategoryType(category->getPreferredType()))
{
return FALSE;
}
@@ -1138,7 +1377,7 @@ BOOL LLFolderBridge::isItemRemovable()
if( (item->getType() == LLAssetType::AT_CLOTHING) ||
(item->getType() == LLAssetType::AT_BODYPART) )
{
- if( gAgent.isWearingItem( item->getUUID() ) )
+ if( gAgentWearables.isWearingItem( item->getUUID(), TRUE ) )
{
return FALSE;
}
@@ -1146,7 +1385,7 @@ BOOL LLFolderBridge::isItemRemovable()
else
if( item->getType() == LLAssetType::AT_OBJECT )
{
- if( avatar->isWearingAttachment( item->getUUID() ) )
+ if( avatar->isWearingAttachment( item->getUUID(), TRUE ) )
{
return FALSE;
}
@@ -1158,7 +1397,7 @@ BOOL LLFolderBridge::isItemRemovable()
BOOL LLFolderBridge::isUpToDate() const
{
- LLInventoryModel* model = mInventoryPanel->getModel();
+ LLInventoryModel* model = getInventoryModel();
if(!model) return FALSE;
LLViewerInventoryCategory* category = (LLViewerInventoryCategory*)model->getCategory(mUUID);
if( !category )
@@ -1169,6 +1408,21 @@ BOOL LLFolderBridge::isUpToDate() const
return category->getVersion() != LLViewerInventoryCategory::VERSION_UNKNOWN;
}
+BOOL LLFolderBridge::isItemCopyable() const
+{
+ return TRUE;
+}
+
+BOOL LLFolderBridge::copyToClipboard() const
+{
+ if(isItemCopyable())
+ {
+ LLInventoryClipboard::instance().add(mUUID);
+ return TRUE;
+ }
+ return FALSE;
+}
+
BOOL LLFolderBridge::dragCategoryIntoFolder(LLInventoryCategory* inv_cat,
BOOL drop)
{
@@ -1176,10 +1430,10 @@ BOOL LLFolderBridge::dragCategoryIntoFolder(LLInventoryCategory* inv_cat,
// the UI will get confused and pass in a NULL.
if(!inv_cat) return FALSE;
- LLInventoryModel* model = mInventoryPanel->getModel();
+ LLInventoryModel* model = getInventoryModel();
if(!model) return FALSE;
- LLVOAvatar* avatar = gAgent.getAvatarObject();
+ LLVOAvatarSelf* avatar = gAgent.getAvatarObject();
if(!avatar) return FALSE;
// cannot drag into library
@@ -1206,7 +1460,14 @@ BOOL LLFolderBridge::dragCategoryIntoFolder(LLInventoryCategory* inv_cat,
trash_id = model->findCategoryUUIDForType(LLAssetType::AT_TRASH);
BOOL move_is_into_trash = (mUUID == trash_id)
|| model->isObjectDescendentOf(mUUID, trash_id);
- BOOL is_movable = (LLAssetType::AT_NONE == inv_cat->getPreferredType());
+ BOOL is_movable = (!LLAssetType::lookupIsProtectedCategoryType(inv_cat->getPreferredType()));
+ LLUUID current_outfit_id = model->findCategoryUUIDForType(LLAssetType::AT_CURRENT_OUTFIT);
+ BOOL move_is_into_current_outfit = (mUUID == current_outfit_id);
+ if (move_is_into_current_outfit)
+ {
+ // BAP - restrictions?
+ is_movable = true;
+ }
if( is_movable )
{
gInventory.collectDescendents( cat_id, descendent_categories, descendent_items, FALSE );
@@ -1214,7 +1475,7 @@ BOOL LLFolderBridge::dragCategoryIntoFolder(LLInventoryCategory* inv_cat,
for( i = 0; i < descendent_categories.count(); i++ )
{
LLInventoryCategory* category = descendent_categories[i];
- if( LLAssetType::AT_NONE != category->getPreferredType() )
+ if(LLAssetType::lookupIsProtectedCategoryType(category->getPreferredType()))
{
// ...can't move "special folders" like Textures
is_movable = FALSE;
@@ -1232,7 +1493,7 @@ BOOL LLFolderBridge::dragCategoryIntoFolder(LLInventoryCategory* inv_cat,
if( (item->getType() == LLAssetType::AT_CLOTHING) ||
(item->getType() == LLAssetType::AT_BODYPART) )
{
- if( gAgent.isWearingItem( item->getUUID() ) )
+ if( gAgentWearables.isWearingItem( item->getUUID() ) )
{
is_movable = FALSE; // It's generally movable, but not into the trash!
break;
@@ -1266,20 +1527,34 @@ BOOL LLFolderBridge::dragCategoryIntoFolder(LLInventoryCategory* inv_cat,
{
LLInventoryItem* item = descendent_items[i];
if (item->getType() == LLAssetType::AT_GESTURE
- && gGestureManager.isGestureActive(item->getUUID()))
+ && LLGestureManager::instance().isGestureActive(item->getUUID()))
{
- gGestureManager.deactivateGesture(item->getUUID());
+ LLGestureManager::instance().deactivateGesture(item->getUUID());
}
}
}
- // Reparent the folder and restamp children if it's moving
- // into trash.
- LLInvFVBridge::changeCategoryParent(
- model,
- (LLViewerInventoryCategory*)inv_cat,
- mUUID,
- move_is_into_trash);
+ if (current_outfit_id == mUUID) // if target is current outfit folder we use link
+ {
+ link_inventory_item(
+ gAgent.getID(),
+ inv_cat->getUUID(),
+ mUUID,
+ inv_cat->getName(),
+ LLAssetType::AT_LINK_FOLDER,
+ LLPointer<LLInventoryCallback>(NULL));
+ }
+ else
+ {
+
+ // Reparent the folder and restamp children if it's moving
+ // into trash.
+ LLInvFVBridge::changeCategoryParent(
+ model,
+ (LLViewerInventoryCategory*)inv_cat,
+ mUUID,
+ move_is_into_trash);
+ }
}
}
else if(LLToolDragAndDrop::SOURCE_WORLD == source)
@@ -1393,22 +1668,13 @@ BOOL move_inv_category_world_to_agent(const LLUUID& object_id,
else
{
LLNotification::Params params("MoveInventoryFromObject");
- params.functor(boost::bind(move_task_inventory_callback, _1, _2, move_inv));
+ params.functor.function(boost::bind(move_task_inventory_callback, _1, _2, move_inv));
LLNotifications::instance().forceResponse(params, 0);
}
}
return accept;
}
-class LLFindWearables : public LLInventoryCollectFunctor
-{
-public:
- LLFindWearables() {}
- virtual ~LLFindWearables() {}
- virtual bool operator()(LLInventoryCategory* cat,
- LLInventoryItem* item);
-};
-
bool LLFindWearables::operator()(LLInventoryCategory* cat,
LLInventoryItem* item)
{
@@ -1606,65 +1872,94 @@ void LLFolderBridge::performAction(LLFolderView* folder, LLInventoryModel* model
if ("open" == action)
{
openItem();
+ return;
}
else if ("paste" == action)
{
pasteFromClipboard();
+ return;
+ }
+ else if ("paste_link" == action)
+ {
+ pasteLinkFromClipboard();
+ return;
}
else if ("properties" == action)
{
showProperties();
+ return;
}
else if ("replaceoutfit" == action)
{
modifyOutfit(FALSE);
+ return;
}
else if ("addtooutfit" == action)
{
modifyOutfit(TRUE);
+ return;
+ }
+ else if ("copy" == action)
+ {
+ copyToClipboard();
+ return;
}
else if ("removefromoutfit" == action)
{
- LLInventoryModel* model = mInventoryPanel->getModel();
+ LLInventoryModel* model = getInventoryModel();
if(!model) return;
LLViewerInventoryCategory* cat = getCategory();
if(!cat) return;
remove_inventory_category_from_avatar ( cat );
+ return;
}
else if ("purge" == action)
{
- LLViewerInventoryCategory* cat;
- cat = (LLViewerInventoryCategory*)getCategory();
-
- if(cat)
- {
- model->purgeDescendentsOf(mUUID);
- }
- LLInventoryObject* obj = model->getObject(mUUID);
- if(!obj) return;
- obj->removeFromServer();
- model->deleteObject(mUUID);
- model->notifyObservers();
+ purgeItem(model, mUUID);
+ return;
}
else if ("restore" == action)
{
restoreItem();
+ return;
}
}
void LLFolderBridge::openItem()
{
lldebugs << "LLFolderBridge::openItem()" << llendl;
- LLInventoryModel* model = mInventoryPanel->getModel();
+ LLInventoryModel* model = getInventoryModel();
if(!model) return;
- model->fetchDescendentsOf(mUUID);
+ bool fetching_inventory = model->fetchDescendentsOf(mUUID);
+ // Only change folder type if we have the folder contents.
+ if (!fetching_inventory)
+ {
+ // Disabling this for now, it's causing crash when new items are added to folders
+ // since folder type may change before new item item has finished processing.
+ // determineFolderType();
+ }
+}
+
+void LLFolderBridge::closeItem()
+{
+ determineFolderType();
+}
+
+void LLFolderBridge::determineFolderType()
+{
+ if (isUpToDate())
+ {
+ LLInventoryModel* model = getInventoryModel();
+ LLViewerInventoryCategory* category = model->getCategory(mUUID);
+ category->determineFolderType();
+ }
}
BOOL LLFolderBridge::isItemRenameable() const
{
LLViewerInventoryCategory* cat = (LLViewerInventoryCategory*)getCategory();
- if(cat && (cat->getPreferredType() == LLAssetType::AT_NONE)
+ if(cat && !LLAssetType::lookupIsProtectedCategoryType(cat->getPreferredType())
&& (cat->getOwnerID() == gAgent.getID()))
{
return TRUE;
@@ -1678,83 +1973,123 @@ void LLFolderBridge::restoreItem()
cat = (LLViewerInventoryCategory*)getCategory();
if(cat)
{
- LLInventoryModel* model = mInventoryPanel->getModel();
+ LLInventoryModel* model = getInventoryModel();
LLUUID new_parent = model->findCategoryUUIDForType(cat->getType());
// do not restamp children on restore
LLInvFVBridge::changeCategoryParent(model, cat, new_parent, FALSE);
}
}
+LLAssetType::EType LLFolderBridge::getPreferredType() const
+{
+ LLAssetType::EType preferred_type = LLAssetType::AT_NONE;
+ LLViewerInventoryCategory* cat = getCategory();
+ if(cat)
+ {
+ preferred_type = cat->getPreferredType();
+ }
+
+ return preferred_type;
+}
+
// Icons for folders are based on the preferred type
LLUIImagePtr LLFolderBridge::getIcon() const
{
- const char* control = NULL;
LLAssetType::EType preferred_type = LLAssetType::AT_NONE;
LLViewerInventoryCategory* cat = getCategory();
if(cat)
{
preferred_type = cat->getPreferredType();
}
+ return getIcon(preferred_type);
+}
+
+LLUIImagePtr LLFolderBridge::getIcon(LLAssetType::EType preferred_type)
+{
+ if (preferred_type >= LLAssetType::AT_FOLDER_ENSEMBLE_START &&
+ preferred_type <= LLAssetType::AT_FOLDER_ENSEMBLE_END)
+ {
+ LLUIImage* icon = LLUI::getUIImage(LLFolderType::lookupIconName(preferred_type));
+ if (icon)
+ return icon;
+ }
+
+ const char* control = NULL;
switch(preferred_type)
{
- case LLAssetType::AT_TEXTURE:
- control = "inv_folder_texture.tga";
- break;
- case LLAssetType::AT_SOUND:
- control = "inv_folder_sound.tga";
- break;
- case LLAssetType::AT_CALLINGCARD:
- control = "inv_folder_callingcard.tga";
- break;
- case LLAssetType::AT_LANDMARK:
- control = "inv_folder_landmark.tga";
- break;
- case LLAssetType::AT_SCRIPT:
- case LLAssetType::AT_LSL_TEXT:
- control = "inv_folder_script.tga";
- break;
- case LLAssetType::AT_OBJECT:
- control = "inv_folder_object.tga";
- break;
- case LLAssetType::AT_NOTECARD:
- control = "inv_folder_notecard.tga";
- break;
- case LLAssetType::AT_CATEGORY:
- control = "inv_folder_plain_closed.tga";
- break;
- case LLAssetType::AT_CLOTHING:
- control = "inv_folder_clothing.tga";
- break;
- case LLAssetType::AT_BODYPART:
- control = "inv_folder_bodypart.tga";
- break;
- case LLAssetType::AT_TRASH:
- control = "inv_folder_trash.tga";
- break;
- case LLAssetType::AT_SNAPSHOT_CATEGORY:
- control = "inv_folder_snapshot.tga";
- break;
- case LLAssetType::AT_LOST_AND_FOUND:
- control = "inv_folder_lostandfound.tga";
- break;
- case LLAssetType::AT_ANIMATION:
- control = "inv_folder_animation.tga";
- break;
- case LLAssetType::AT_GESTURE:
- control = "inv_folder_gesture.tga";
- break;
- default:
- control = "inv_folder_plain_closed.tga";
- break;
+ case LLAssetType::AT_TEXTURE:
+ control = "inv_folder_texture.tga";
+ break;
+ case LLAssetType::AT_SOUND:
+ control = "inv_folder_sound.tga";
+ break;
+ case LLAssetType::AT_CALLINGCARD:
+ control = "inv_folder_callingcard.tga";
+ break;
+ case LLAssetType::AT_LANDMARK:
+ control = "inv_folder_landmark.tga";
+ break;
+ case LLAssetType::AT_SCRIPT:
+ case LLAssetType::AT_LSL_TEXT:
+ control = "inv_folder_script.tga";
+ break;
+ case LLAssetType::AT_OBJECT:
+ control = "inv_folder_object.tga";
+ break;
+ case LLAssetType::AT_NOTECARD:
+ control = "inv_folder_notecard.tga";
+ break;
+ case LLAssetType::AT_CATEGORY:
+ control = "inv_folder_plain_closed.tga";
+ break;
+ case LLAssetType::AT_CLOTHING:
+ control = "inv_folder_clothing.tga";
+ break;
+ case LLAssetType::AT_BODYPART:
+ control = "inv_folder_bodypart.tga";
+ break;
+ case LLAssetType::AT_TRASH:
+ control = "inv_folder_trash.tga";
+ break;
+ case LLAssetType::AT_SNAPSHOT_CATEGORY:
+ control = "inv_folder_snapshot.tga";
+ break;
+ case LLAssetType::AT_LOST_AND_FOUND:
+ control = "inv_folder_lostandfound.tga";
+ break;
+ case LLAssetType::AT_ANIMATION:
+ control = "inv_folder_animation.tga";
+ break;
+ case LLAssetType::AT_GESTURE:
+ control = "inv_folder_gesture.tga";
+ break;
+ case LLAssetType::AT_FAVORITE:
+ //TODO - need icon
+ control = "inv_folder_plain_closed.tga";
+ break;
+ case LLAssetType::AT_OUTFIT:
+ control = "inv_folder_outfit.tga";
+ break;
+ case LLAssetType::AT_CURRENT_OUTFIT:
+ control = "inv_folder_current_outfit.tga";
+ break;
+ case LLAssetType::AT_MY_OUTFITS:
+ control = "inv_folder_my_outfits.tga";
+ break;
+ default:
+ control = "inv_folder_plain_closed.tga";
+ break;
}
return LLUI::getUIImage(control);
}
BOOL LLFolderBridge::renameItem(const std::string& new_name)
{
- if(!isItemRenameable()) return FALSE;
- LLInventoryModel* model = mInventoryPanel->getModel();
- if(!model) return FALSE;
+ if(!isItemRenameable())
+ return FALSE;
+ LLInventoryModel* model = getInventoryModel();
+ if(!model)
+ return FALSE;
LLViewerInventoryCategory* cat = getCategory();
if(cat && (cat->getName() != new_name))
{
@@ -1762,6 +2097,8 @@ BOOL LLFolderBridge::renameItem(const std::string& new_name)
new_cat->rename(new_name);
new_cat->updateServer(FALSE);
model->updateCategory(new_cat);
+ model->updateLinkedObjects(cat->getUUID());
+
model->notifyObservers();
}
// return FALSE because we either notified observers (& therefore
@@ -1777,7 +2114,7 @@ BOOL LLFolderBridge::removeItem()
}
// move it to the trash
LLPreview::hide(mUUID);
- LLInventoryModel* model = mInventoryPanel->getModel();
+ LLInventoryModel* model = getInventoryModel();
if(!model) return FALSE;
LLUUID trash_id;
@@ -1793,9 +2130,9 @@ BOOL LLFolderBridge::removeItem()
{
LLInventoryItem* item = descendent_items[i];
if (item->getType() == LLAssetType::AT_GESTURE
- && gGestureManager.isGestureActive(item->getUUID()))
+ && LLGestureManager::instance().isGestureActive(item->getUUID()))
{
- gGestureManager.deactivateGesture(item->getUUID());
+ LLGestureManager::instance().deactivateGesture(item->getUUID());
}
}
@@ -1810,18 +2147,9 @@ BOOL LLFolderBridge::removeItem()
return TRUE;
}
-BOOL LLFolderBridge::isClipboardPasteable() const
-{
- if(LLInventoryClipboard::instance().hasContents() && isAgentInventory())
- {
- return TRUE;
- }
- return FALSE;
-}
-
void LLFolderBridge::pasteFromClipboard()
{
- LLInventoryModel* model = mInventoryPanel->getModel();
+ LLInventoryModel* model = getInventoryModel();
if(model && isClipboardPasteable())
{
LLInventoryItem* item = NULL;
@@ -1846,6 +2174,42 @@ void LLFolderBridge::pasteFromClipboard()
}
}
+void LLFolderBridge::pasteLinkFromClipboard()
+{
+ LLInventoryModel* model = getInventoryModel();
+ if(model)
+ {
+ LLDynamicArray<LLUUID> objects;
+ LLInventoryClipboard::instance().retrieve(objects);
+ S32 count = objects.count();
+ LLUUID parent_id(mUUID);
+ for(S32 i = 0; i < count; i++)
+ {
+ const LLUUID &object_id = objects.get(i);
+ if (LLInventoryCategory *cat = model->getCategory(object_id))
+ {
+ link_inventory_item(
+ gAgent.getID(),
+ cat->getUUID(),
+ parent_id,
+ cat->getName(),
+ LLAssetType::AT_LINK_FOLDER,
+ LLPointer<LLInventoryCallback>(NULL));
+ }
+ else if (LLInventoryItem *item = model->getItem(object_id))
+ {
+ link_inventory_item(
+ gAgent.getID(),
+ item->getUUID(),
+ parent_id,
+ item->getName(),
+ LLAssetType::AT_LINK,
+ LLPointer<LLInventoryCallback>(NULL));
+ }
+ }
+ }
+}
+
void LLFolderBridge::staticFolderOptionsMenu()
{
if (!sSelf) return;
@@ -1856,14 +2220,12 @@ void LLFolderBridge::folderOptionsMenu()
{
std::vector<std::string> disabled_items;
- // *TODO: Translate
-
- LLInventoryModel* model = mInventoryPanel->getModel();
+ LLInventoryModel* model = getInventoryModel();
if(!model) return;
const LLInventoryCategory* category = model->getCategory(mUUID);
bool is_default_folder = category &&
- (LLAssetType::AT_NONE != category->getPreferredType());
+ (LLAssetType::lookupIsProtectedCategoryType(category->getPreferredType()));
// calling card related functionality for folders.
@@ -1900,6 +2262,10 @@ void LLFolderBridge::folderOptionsMenu()
}
mItems.push_back(std::string("Take Off Items"));
}
+ if (LLAssetType::AT_CURRENT_OUTFIT == category->getPreferredType())
+ {
+ mItems.push_back(std::string("Replace Outfit"));
+ }
hideContextEntries(*mMenu, mItems, disabled_items);
}
@@ -1918,10 +2284,12 @@ BOOL LLFolderBridge::checkFolderForContentsOfType(LLInventoryModel* model, LLInv
// Flags unused
void LLFolderBridge::buildContextMenu(LLMenuGL& menu, U32 flags)
{
- // *TODO: Translate
+ mItems.clear();
+ mDisabledItems.clear();
+
lldebugs << "LLFolderBridge::buildContextMenu()" << llendl;
// std::vector<std::string> disabled_items;
- LLInventoryModel* model = mInventoryPanel->getModel();
+ LLInventoryModel* model = getInventoryModel();
if(!model) return;
LLUUID trash_id = model->findCategoryUUIDForType(LLAssetType::AT_TRASH);
LLUUID lost_and_found_id = model->findCategoryUUIDForType(LLAssetType::AT_LOST_AND_FOUND);
@@ -1951,38 +2319,23 @@ void LLFolderBridge::buildContextMenu(LLMenuGL& menu, U32 flags)
}
else if(isAgentInventory()) // do not allow creating in library
{
- // only mature accounts can create undershirts/underwear
- /*if (!gAgent.isTeen())
- {
- sub_menu->append(new LLMenuItemCallGL("New Undershirt",
- &createNewUndershirt,
- NULL,
- (void*)this));
- sub_menu->append(new LLMenuItemCallGL("New Underpants",
- &createNewUnderpants,
- NULL,
- (void*)this));
- }*/
-
-/* BOOL contains_calling_cards = FALSE;
- LLInventoryModel::cat_array_t cat_array;
- LLInventoryModel::item_array_t item_array;
+ LLViewerInventoryCategory *cat = getCategory();
- LLIsType is_callingcard(LLAssetType::AT_CALLINGCARD);
- model->collectDescendentsIf(mUUID,
- cat_array,
- item_array,
- LLInventoryModel::EXCLUDE_TRASH,
- is_callingcard);
- if(item_array.count() > 0) contains_calling_cards = TRUE;
-*/
- mItems.push_back(std::string("New Folder"));
+ // Do not allow to create 2-level subfolder in the Calling Card/Friends folder. EXT-694.
+ if (!LLFriendCardsManager::instance().isCategoryInFriendFolder(cat))
+ mItems.push_back(std::string("New Folder"));
mItems.push_back(std::string("New Script"));
mItems.push_back(std::string("New Note"));
mItems.push_back(std::string("New Gesture"));
mItems.push_back(std::string("New Clothes"));
mItems.push_back(std::string("New Body Parts"));
+ mItems.push_back(std::string("Change Type"));
+ if (cat && LLAssetType::lookupIsProtectedCategoryType(cat->getPreferredType()))
+ {
+ mDisabledItems.push_back(std::string("Change Type"));
+ }
+
getClipboardEntries(false, mItems, mDisabledItems, flags);
//Added by spatters to force inventory pull on right-click to display folder options correctly. 07-17-06
@@ -2036,7 +2389,7 @@ void LLFolderBridge::buildContextMenu(LLMenuGL& menu, U32 flags)
BOOL LLFolderBridge::hasChildren() const
{
- LLInventoryModel* model = mInventoryPanel->getModel();
+ LLInventoryModel* model = getInventoryModel();
if(!model) return FALSE;
LLInventoryModel::EHasChildren has_children;
has_children = gInventory.categoryHasChildren(mUUID);
@@ -2051,26 +2404,27 @@ BOOL LLFolderBridge::dragOrDrop(MASK mask, BOOL drop,
BOOL accept = FALSE;
switch(cargo_type)
{
- case DAD_TEXTURE:
- case DAD_SOUND:
- case DAD_CALLINGCARD:
- case DAD_LANDMARK:
- case DAD_SCRIPT:
- case DAD_OBJECT:
- case DAD_NOTECARD:
- case DAD_CLOTHING:
- case DAD_BODYPART:
- case DAD_ANIMATION:
- case DAD_GESTURE:
- accept = dragItemIntoFolder((LLInventoryItem*)cargo_data,
- drop);
- break;
- case DAD_CATEGORY:
- accept = dragCategoryIntoFolder((LLInventoryCategory*)cargo_data,
+ case DAD_TEXTURE:
+ case DAD_SOUND:
+ case DAD_CALLINGCARD:
+ case DAD_LANDMARK:
+ case DAD_SCRIPT:
+ case DAD_OBJECT:
+ case DAD_NOTECARD:
+ case DAD_CLOTHING:
+ case DAD_BODYPART:
+ case DAD_ANIMATION:
+ case DAD_GESTURE:
+ case DAD_LINK:
+ accept = dragItemIntoFolder((LLInventoryItem*)cargo_data,
drop);
- break;
- default:
- break;
+ break;
+ case DAD_CATEGORY:
+ accept = dragCategoryIntoFolder((LLInventoryCategory*)cargo_data,
+ drop);
+ break;
+ default:
+ break;
}
return accept;
}
@@ -2078,7 +2432,7 @@ BOOL LLFolderBridge::dragOrDrop(MASK mask, BOOL drop,
LLViewerInventoryCategory* LLFolderBridge::getCategory() const
{
LLViewerInventoryCategory* cat = NULL;
- LLInventoryModel* model = mInventoryPanel->getModel();
+ LLInventoryModel* model = getInventoryModel();
if(model)
{
cat = (LLViewerInventoryCategory*)model->getCategory(mUUID);
@@ -2098,7 +2452,8 @@ void LLFolderBridge::createNewCategory(void* user_data)
{
LLFolderBridge* bridge = (LLFolderBridge*)user_data;
if(!bridge) return;
- LLInventoryPanel* panel = bridge->mInventoryPanel;
+ LLInventoryPanel* panel = dynamic_cast<LLInventoryPanel*>(bridge->mInventoryPanel.get());
+ if (!panel) return;
LLInventoryModel* model = panel->getModel();
if(!model) return;
LLUUID id;
@@ -2190,7 +2545,7 @@ void LLFolderBridge::createWearable(LLFolderBridge* bridge, EWearableType type)
// static
void LLFolderBridge::createWearable(LLUUID parent_id, EWearableType type)
{
- LLWearable* wearable = gWearableList.createNewWearable(type);
+ LLWearable* wearable = LLWearableList::instance().createNewWearable(type);
LLAssetType::EType asset_type = wearable->getAssetType();
LLInventoryType::EType inv_type = LLInventoryType::IT_WEARABLE;
create_inventory_item(gAgent.getID(), gAgent.getSessionID(),
@@ -2202,12 +2557,14 @@ void LLFolderBridge::createWearable(LLUUID parent_id, EWearableType type)
void LLFolderBridge::modifyOutfit(BOOL append)
{
- LLInventoryModel* model = mInventoryPanel->getModel();
+ LLInventoryModel* model = getInventoryModel();
if(!model) return;
LLViewerInventoryCategory* cat = getCategory();
if(!cat) return;
- wear_inventory_category_on_avatar( cat, append );
+ // BAP - was:
+ // wear_inventory_category_on_avatar( cat, append );
+ wear_inventory_category( cat, FALSE, append );
}
// helper stuff
@@ -2253,7 +2610,7 @@ bool move_task_inventory_callback(const LLSD& notification, const LLSD& response
BOOL LLFolderBridge::dragItemIntoFolder(LLInventoryItem* inv_item,
BOOL drop)
{
- LLInventoryModel* model = mInventoryPanel->getModel();
+ LLInventoryModel* model = getInventoryModel();
if(!model) return FALSE;
// cannot drag into library
@@ -2262,7 +2619,7 @@ BOOL LLFolderBridge::dragItemIntoFolder(LLInventoryItem* inv_item,
return FALSE;
}
- LLVOAvatar* avatar = gAgent.getAvatarObject();
+ LLVOAvatarSelf* avatar = gAgent.getAvatarObject();
if(!avatar) return FALSE;
LLToolDragAndDrop::ESource source = LLToolDragAndDrop::getInstance()->getSource();
@@ -2272,14 +2629,14 @@ BOOL LLFolderBridge::dragItemIntoFolder(LLInventoryItem* inv_item,
{
BOOL is_movable = TRUE;
- switch( inv_item->getType() )
+ switch( inv_item->getActualType() )
{
case LLAssetType::AT_ROOT_CATEGORY:
is_movable = FALSE;
break;
case LLAssetType::AT_CATEGORY:
- is_movable = ( LLAssetType::AT_NONE == ((LLInventoryCategory*)inv_item)->getPreferredType() );
+ is_movable = !LLAssetType::lookupIsProtectedCategoryType(((LLInventoryCategory*)inv_item)->getPreferredType());
break;
default:
break;
@@ -2293,11 +2650,11 @@ BOOL LLFolderBridge::dragItemIntoFolder(LLInventoryItem* inv_item,
{
case LLAssetType::AT_CLOTHING:
case LLAssetType::AT_BODYPART:
- is_movable = !gAgent.isWearingItem(inv_item->getUUID());
+ is_movable = !gAgentWearables.isWearingItem(inv_item->getUUID(), TRUE);
break;
case LLAssetType::AT_OBJECT:
- is_movable = !avatar->isWearingAttachment(inv_item->getUUID());
+ is_movable = !avatar->isWearingAttachment(inv_item->getUUID(), TRUE);
break;
default:
break;
@@ -2308,29 +2665,44 @@ BOOL LLFolderBridge::dragItemIntoFolder(LLInventoryItem* inv_item,
if(accept && drop)
{
if (inv_item->getType() == LLAssetType::AT_GESTURE
- && gGestureManager.isGestureActive(inv_item->getUUID()) && move_is_into_trash)
+ && LLGestureManager::instance().isGestureActive(inv_item->getUUID()) && move_is_into_trash)
{
- gGestureManager.deactivateGesture(inv_item->getUUID());
+ LLGestureManager::instance().deactivateGesture(inv_item->getUUID());
}
// If an item is being dragged between windows, unselect
// everything in the active window so that we don't follow
// the selection to its new location (which is very
// annoying).
- if (LLInventoryView::getActiveInventory())
+ if (LLFloaterInventory::getActiveInventory())
{
- LLInventoryPanel* active_panel = LLInventoryView::getActiveInventory()->getPanel();
- if (active_panel && (mInventoryPanel != active_panel))
+ LLInventoryPanel* active_panel = LLFloaterInventory::getActiveInventory()->getPanel();
+ LLInventoryPanel* panel = dynamic_cast<LLInventoryPanel*>(mInventoryPanel.get());
+ if (active_panel && (panel != active_panel))
{
active_panel->unSelectAll();
}
}
- // restamp if the move is into the trash.
- LLInvFVBridge::changeItemParent(
- model,
- (LLViewerInventoryItem*)inv_item,
- mUUID,
- move_is_into_trash);
+ LLUUID favorites_id = model->findCategoryUUIDForType(LLAssetType::AT_FAVORITE);
+ if (favorites_id == mUUID) // if target is the favorites folder we use copy
+ {
+ copy_inventory_item(
+ gAgent.getID(),
+ inv_item->getPermissions().getOwner(),
+ inv_item->getUUID(),
+ mUUID,
+ std::string(),
+ LLPointer<LLInventoryCallback>(NULL));
+ }
+ else
+ {
+ // restamp if the move is into the trash.
+ LLInvFVBridge::changeItemParent(
+ model,
+ (LLViewerInventoryItem*)inv_item,
+ mUUID,
+ move_is_into_trash);
+ }
}
}
else if(LLToolDragAndDrop::SOURCE_WORLD == source)
@@ -2379,7 +2751,7 @@ BOOL LLFolderBridge::dragItemIntoFolder(LLInventoryItem* inv_item,
else
{
LLNotification::Params params("MoveInventoryFromObject");
- params.functor(boost::bind(move_task_inventory_callback, _1, _2, move_inv));
+ params.functor.function(boost::bind(move_task_inventory_callback, _1, _2, move_inv));
LLNotifications::instance().forceResponse(params, 0);
}
}
@@ -2432,49 +2804,18 @@ LLUIImagePtr LLScriptBridge::getIcon() const
// | LLTextureBridge |
// +=================================================+
-std::string LLTextureBridge::sPrefix("Texture: ");
-
-
LLUIImagePtr LLTextureBridge::getIcon() const
{
return get_item_icon(LLAssetType::AT_TEXTURE, mInvType, 0, FALSE);
}
-void open_texture(const LLUUID& item_id,
- const std::string& title,
- BOOL show_keep_discard,
- const LLUUID& source_id,
- BOOL take_focus)
-{
- // See if we can bring an exiting preview to the front
- if( !LLPreview::show( item_id, take_focus ) )
- {
- // There isn't one, so make a new preview
- S32 left, top;
- gFloaterView->getNewFloaterPosition(&left, &top);
- LLRect rect = gSavedSettings.getRect("PreviewTextureRect");
- rect.translate( left - rect.mLeft, top - rect.mTop );
-
- LLPreviewTexture* preview;
- preview = new LLPreviewTexture("preview texture",
- rect,
- title,
- item_id,
- LLUUID::null,
- show_keep_discard);
- preview->setSourceID(source_id);
- if(take_focus) preview->setFocus(TRUE);
-
- gFloaterView->adjustToFitScreen(preview, FALSE);
- }
-}
-
void LLTextureBridge::openItem()
{
LLViewerInventoryItem* item = getItem();
- if(item)
+
+ if (item)
{
- open_texture(mUUID, getPrefix() + item->getName(), FALSE);
+ LLInvFVBridgeAction::doAction(item->getType(),mUUID,getInventoryModel());
}
}
@@ -2482,9 +2823,6 @@ void LLTextureBridge::openItem()
// | LLSoundBridge |
// +=================================================+
-std::string LLSoundBridge::sPrefix("Sound: ");
-
-
LLUIImagePtr LLSoundBridge::getIcon() const
{
return get_item_icon(LLAssetType::AT_SOUND, LLInventoryType::IT_SOUND, 0, FALSE);
@@ -2492,6 +2830,13 @@ LLUIImagePtr LLSoundBridge::getIcon() const
void LLSoundBridge::openItem()
{
+ LLViewerInventoryItem* item = getItem();
+
+ if (item)
+ {
+ LLInvFVBridgeAction::doAction(item->getType(),mUUID,getInventoryModel());
+ }
+/*
// Changed this back to the way it USED to work:
// only open the preview dialog through the contextual right-click menu
// double-click just plays the sound
@@ -2502,18 +2847,7 @@ void LLSoundBridge::openItem()
openSoundPreview((void*)this);
//send_uuid_sound_trigger(item->getAssetUUID(), 1.0);
}
-
-// if(!LLPreview::show(mUUID))
-// {
-// S32 left, top;
-// gFloaterView->getNewFloaterPosition(&left, &top);
-// LLRect rect = gSavedSettings.getRect("PreviewSoundRect");
-// rect.translate(left - rect.mLeft, top - rect.mTop);
-// new LLPreviewSound("preview sound",
-// rect,
-// getPrefix() + getName(),
-// mUUID));
-// }
+*/
}
void LLSoundBridge::previewItem()
@@ -2528,20 +2862,7 @@ void LLSoundBridge::previewItem()
void LLSoundBridge::openSoundPreview(void* which)
{
LLSoundBridge *me = (LLSoundBridge *)which;
- if(!LLPreview::show(me->mUUID))
- {
- S32 left, top;
- gFloaterView->getNewFloaterPosition(&left, &top);
- LLRect rect = gSavedSettings.getRect("PreviewSoundRect");
- rect.translate(left - rect.mLeft, top - rect.mTop);
- LLPreviewSound* preview = new LLPreviewSound("preview sound",
- rect,
- me->getPrefix() + me->getName(),
- me->mUUID);
- preview->setFocus(TRUE);
- // Keep entirely onscreen.
- gFloaterView->adjustToFitScreen(preview, FALSE);
- }
+ LLFloaterReg::showInstance("preview_sound", LLSD(me->mUUID), TAKE_FOCUS_YES);
}
void LLSoundBridge::buildContextMenu(LLMenuGL& menu, U32 flags)
@@ -2550,7 +2871,6 @@ void LLSoundBridge::buildContextMenu(LLMenuGL& menu, U32 flags)
std::vector<std::string> items;
std::vector<std::string> disabled_items;
- // *TODO: Translate
if(isInTrash())
{
items.push_back(std::string("Purge Item"));
@@ -2579,7 +2899,15 @@ void LLSoundBridge::buildContextMenu(LLMenuGL& menu, U32 flags)
// | LLLandmarkBridge |
// +=================================================+
-std::string LLLandmarkBridge::sPrefix("Landmark: ");
+LLLandmarkBridge::LLLandmarkBridge(LLInventoryPanel* inventory, const LLUUID& uuid, U32 flags/* = 0x00*/) :
+LLItemBridge(inventory, uuid)
+{
+ mVisited = FALSE;
+ if (flags & LLInventoryItem::II_FLAGS_LANDMARK_VISITED)
+ {
+ mVisited = TRUE;
+ }
+}
LLUIImagePtr LLLandmarkBridge::getIcon() const
{
@@ -2591,7 +2919,6 @@ void LLLandmarkBridge::buildContextMenu(LLMenuGL& menu, U32 flags)
std::vector<std::string> items;
std::vector<std::string> disabled_items;
- // *TODO: Translate
lldebugs << "LLLandmarkBridge::buildContextMenu()" << llendl;
if(isInTrash())
{
@@ -2618,6 +2945,20 @@ void LLLandmarkBridge::buildContextMenu(LLMenuGL& menu, U32 flags)
}
+// Convenience function for the two functions below.
+void teleport_via_landmark(const LLUUID& asset_id)
+{
+ gAgent.teleportViaLandmark( asset_id );
+
+ // we now automatically track the landmark you're teleporting to
+ // because you'll probably arrive at a telehub instead
+ LLFloaterWorldMap* floater_world_map = LLFloaterWorldMap::getInstance();
+ if( floater_world_map )
+ {
+ floater_world_map->trackLandmark( asset_id );
+ }
+}
+
// virtual
void LLLandmarkBridge::performAction(LLFolderView* folder, LLInventoryModel* model, std::string action)
{
@@ -2626,52 +2967,24 @@ void LLLandmarkBridge::performAction(LLFolderView* folder, LLInventoryModel* mod
LLViewerInventoryItem* item = getItem();
if(item)
{
- gAgent.teleportViaLandmark(item->getAssetUUID());
-
- // we now automatically track the landmark you're teleporting to
- // because you'll probably arrive at a telehub instead
- if( gFloaterWorldMap )
- {
- gFloaterWorldMap->trackLandmark( item->getAssetUUID() );
- }
+ teleport_via_landmark(item->getAssetUUID());
}
}
- if ("about" == action)
+ else if ("about" == action)
{
LLViewerInventoryItem* item = getItem();
if(item)
{
- open_landmark(item, std::string(" ") + getPrefix() + item->getName(), FALSE);
+ LLSD key;
+ key["type"] = "landmark";
+ key["id"] = item->getUUID();
+
+ LLSideTray::getInstance()->showPanel("panel_places", key);
}
}
- else LLItemBridge::performAction(folder, model, action);
-}
-
-void open_landmark(LLViewerInventoryItem* inv_item,
- const std::string& title,
- BOOL show_keep_discard,
- const LLUUID& source_id,
- BOOL take_focus)
-{
- // See if we can bring an exiting preview to the front
- if( !LLPreview::show( inv_item->getUUID(), take_focus ) )
+ else
{
- // There isn't one, so make a new preview
- S32 left, top;
- gFloaterView->getNewFloaterPosition(&left, &top);
- LLRect rect = gSavedSettings.getRect("PreviewLandmarkRect");
- rect.translate( left - rect.mLeft, top - rect.mTop );
-
- LLPreviewLandmark* preview = new LLPreviewLandmark(title,
- rect,
- title,
- inv_item->getUUID(),
- show_keep_discard,
- inv_item);
- preview->setSourceID(source_id);
- if(take_focus) preview->setFocus(TRUE);
- // keep onscreen
- gFloaterView->adjustToFitScreen(preview, FALSE);
+ LLItemBridge::performAction(folder, model, action);
}
}
@@ -2682,15 +2995,7 @@ static bool open_landmark_callback(const LLSD& notification, const LLSD& respons
LLUUID asset_id = notification["payload"]["asset_id"].asUUID();
if (option == 0)
{
- // HACK: This is to demonstrate teleport on double click for landmarks
- gAgent.teleportViaLandmark( asset_id );
-
- // we now automatically track the landmark you're teleporting to
- // because you'll probably arrive at a telehub instead
- if( gFloaterWorldMap )
- {
- gFloaterWorldMap->trackLandmark( asset_id );
- }
+ teleport_via_landmark(asset_id);
}
return false;
@@ -2701,15 +3006,23 @@ static LLNotificationFunctorRegistration open_landmark_callback_reg("TeleportFro
void LLLandmarkBridge::openItem()
{
LLViewerInventoryItem* item = getItem();
+
+ if (item)
+ {
+ LLInvFVBridgeAction::doAction(item->getType(),mUUID,getInventoryModel());
+ }
+/*
+ LLViewerInventoryItem* item = getItem();
if( item )
{
// Opening (double-clicking) a landmark immediately teleports,
// but warns you the first time.
- // open_landmark(item, std::string(" ") + getPrefix() + item->getName(), FALSE);
+ // open_landmark(item);
LLSD payload;
payload["asset_id"] = item->getAssetUUID();
LLNotifications::instance().add("TeleportFromLandmark", LLSD(), payload);
}
+*/
}
@@ -2725,8 +3038,6 @@ void LLCallingCardObserver::changed(U32 mask)
// | LLCallingCardBridge |
// +=================================================+
-std::string LLCallingCardBridge::sPrefix("Calling Card: ");
-
LLCallingCardBridge::LLCallingCardBridge( LLInventoryPanel* inventory, const LLUUID& uuid ) :
LLItemBridge(inventory, uuid)
{
@@ -2742,7 +3053,8 @@ LLCallingCardBridge::~LLCallingCardBridge()
void LLCallingCardBridge::refreshFolderViewItem()
{
- LLFolderViewItem* itemp = mInventoryPanel->getRootFolder()->getItemByID(mUUID);
+ LLInventoryPanel* panel = dynamic_cast<LLInventoryPanel*>(mInventoryPanel.get());
+ LLFolderViewItem* itemp = panel ? panel->getRootFolder()->getItemByID(mUUID) : NULL;
if (itemp)
{
itemp->refresh();
@@ -2758,8 +3070,9 @@ void LLCallingCardBridge::performAction(LLFolderView* folder, LLInventoryModel*
if (item && (item->getCreatorUUID() != gAgent.getID()) &&
(!item->getCreatorUUID().isNull()))
{
- gIMMgr->setFloaterOpen(TRUE);
- gIMMgr->addSession(item->getName(), IM_NOTHING_SPECIAL, item->getCreatorUUID());
+ std::string callingcard_name;
+ gCacheName->getFullName(item->getCreatorUUID(), callingcard_name);
+ gIMMgr->addSession(callingcard_name, IM_NOTHING_SPECIAL, item->getCreatorUUID());
}
}
else if ("lure" == action)
@@ -2768,7 +3081,7 @@ void LLCallingCardBridge::performAction(LLFolderView* folder, LLInventoryModel*
if (item && (item->getCreatorUUID() != gAgent.getID()) &&
(!item->getCreatorUUID().isNull()))
{
- handle_lure(item->getCreatorUUID());
+ LLAvatarActions::offerTeleport(item->getCreatorUUID());
}
}
else LLItemBridge::performAction(folder, model, action);
@@ -2801,17 +3114,22 @@ std::string LLCallingCardBridge::getLabelSuffix() const
void LLCallingCardBridge::openItem()
{
LLViewerInventoryItem* item = getItem();
+
+ if (item)
+ {
+ LLInvFVBridgeAction::doAction(item->getType(),mUUID,getInventoryModel());
+ }
+/*
+ LLViewerInventoryItem* item = getItem();
if(item && !item->getCreatorUUID().isNull())
{
- BOOL online;
- online = LLAvatarTracker::instance().isBuddyOnline(item->getCreatorUUID());
- LLFloaterAvatarInfo::showFromFriend(item->getCreatorUUID(), online);
+ LLAvatarActions::showProfile(item->getCreatorUUID());
}
+*/
}
void LLCallingCardBridge::buildContextMenu(LLMenuGL& menu, U32 flags)
{
- // *TODO: Translate
lldebugs << "LLCallingCardBridge::buildContextMenu()" << llendl;
std::vector<std::string> items;
std::vector<std::string> disabled_items;
@@ -2928,72 +3246,43 @@ BOOL LLCallingCardBridge::dragOrDrop(MASK mask, BOOL drop,
return rv;
}
+BOOL LLCallingCardBridge::removeItem()
+{
+ if (LLFriendCardsManager::instance().isItemInAnyFriendsList(getItem()))
+ {
+ LLAvatarActions::removeFriendDialog(getItem()->getCreatorUUID());
+ return FALSE;
+ }
+ else
+ {
+ return LLItemBridge::removeItem();
+ }
+}
// +=================================================+
// | LLNotecardBridge |
// +=================================================+
-std::string LLNotecardBridge::sPrefix("Note: ");
-
-
LLUIImagePtr LLNotecardBridge::getIcon() const
{
return get_item_icon(LLAssetType::AT_NOTECARD, LLInventoryType::IT_NOTECARD, 0, FALSE);
}
-void open_notecard(LLViewerInventoryItem* inv_item,
- const std::string& title,
- const LLUUID& object_id,
- BOOL show_keep_discard,
- const LLUUID& source_id,
- BOOL take_focus)
-{
- // See if we can bring an existing preview to the front
- if(!LLPreview::show(inv_item->getUUID(), take_focus))
- {
- // There isn't one, so make a new preview
- S32 left, top;
- gFloaterView->getNewFloaterPosition(&left, &top);
- LLRect rect = gSavedSettings.getRect("NotecardEditorRect");
- rect.translate(left - rect.mLeft, top - rect.mTop);
- LLPreviewNotecard* preview;
- preview = new LLPreviewNotecard("preview notecard", rect, title,
- inv_item->getUUID(), object_id, inv_item->getAssetUUID(),
- show_keep_discard, inv_item);
- preview->setSourceID(source_id);
- if(take_focus) preview->setFocus(TRUE);
- // Force to be entirely onscreen.
- gFloaterView->adjustToFitScreen(preview, FALSE);
-
- //if (source_id.notNull())
- //{
- // // look for existing tabbed view for content from same source
- // LLPreview* existing_preview = LLPreview::getPreviewForSource(source_id);
- // if (existing_preview)
- // {
- // // found existing preview from this source
- // // is it already hosted in a multi-preview window?
- // LLMultiPreview* preview_hostp = (LLMultiPreview*)existing_preview->getHost();
- // if (!preview_hostp)
- // {
- // // create new multipreview if it doesn't exist
- // LLMultiPreview* preview_hostp = new LLMultiPreview(existing_preview->getRect());
- // preview_hostp->addFloater(existing_preview);
- // }
- // // add this preview to existing host
- // preview_hostp->addFloater(preview);
- // }
- //}
- }
-}
-
-
void LLNotecardBridge::openItem()
{
LLViewerInventoryItem* item = getItem();
+
if (item)
{
- open_notecard(item, getPrefix() + item->getName(), LLUUID::null, FALSE);
+ LLInvFVBridgeAction::doAction(item->getType(),mUUID,getInventoryModel());
}
+
+/*
+ LLViewerInventoryItem* item = getItem();
+ if (item)
+ {
+ LLFloaterReg::showInstance("preview_notecard", LLSD(item->getUUID()), TAKE_FOCUS_YES);
+ }
+*/
}
@@ -3001,8 +3290,6 @@ void LLNotecardBridge::openItem()
// | LLGestureBridge |
// +=================================================+
-std::string LLGestureBridge::sPrefix("Gesture: ");
-
LLUIImagePtr LLGestureBridge::getIcon() const
{
return get_item_icon(LLAssetType::AT_GESTURE, LLInventoryType::IT_GESTURE, 0, FALSE);
@@ -3010,7 +3297,7 @@ LLUIImagePtr LLGestureBridge::getIcon() const
LLFontGL::StyleFlags LLGestureBridge::getLabelStyle() const
{
- if( gGestureManager.isGestureActive(mUUID) )
+ if( LLGestureManager::instance().isGestureActive(mUUID) )
{
return LLFontGL::BOLD;
}
@@ -3022,7 +3309,7 @@ LLFontGL::StyleFlags LLGestureBridge::getLabelStyle() const
std::string LLGestureBridge::getLabelSuffix() const
{
- if( gGestureManager.isGestureActive(mUUID) )
+ if( LLGestureManager::instance().isGestureActive(mUUID) )
{
return LLItemBridge::getLabelSuffix() + " (active)";
}
@@ -3037,7 +3324,7 @@ void LLGestureBridge::performAction(LLFolderView* folder, LLInventoryModel* mode
{
if ("activate" == action)
{
- gGestureManager.activateGesture(mUUID);
+ LLGestureManager::instance().activateGesture(mUUID);
LLViewerInventoryItem* item = gInventory.getItem(mUUID);
if (!item) return;
@@ -3049,7 +3336,7 @@ void LLGestureBridge::performAction(LLFolderView* folder, LLInventoryModel* mode
}
else if ("deactivate" == action)
{
- gGestureManager.deactivateGesture(mUUID);
+ LLGestureManager::instance().deactivateGesture(mUUID);
LLViewerInventoryItem* item = gInventory.getItem(mUUID);
if (!item) return;
@@ -3065,34 +3352,30 @@ void LLGestureBridge::performAction(LLFolderView* folder, LLInventoryModel* mode
void LLGestureBridge::openItem()
{
LLViewerInventoryItem* item = getItem();
- if (!item) return;
-
- // See if we can bring an existing preview to the front
- if(!LLPreview::show(mUUID))
+
+ if (item)
{
- LLUUID item_id = mUUID;
- std::string title = getPrefix() + item->getName();
- LLUUID object_id = LLUUID::null;
-
- // TODO: save the rectangle
- LLPreviewGesture* preview = LLPreviewGesture::show(title, item_id, object_id);
+ LLInvFVBridgeAction::doAction(item->getType(),mUUID,getInventoryModel());
+ }
+/*
+ LLViewerInventoryItem* item = getItem();
+ if (item)
+ {
+ LLPreviewGesture* preview = LLPreviewGesture::show(mUUID, LLUUID::null);
preview->setFocus(TRUE);
-
- // Force to be entirely onscreen.
- gFloaterView->adjustToFitScreen(preview, FALSE);
}
+*/
}
BOOL LLGestureBridge::removeItem()
{
// Force close the preview window, if it exists
- gGestureManager.deactivateGesture(mUUID);
+ LLGestureManager::instance().deactivateGesture(mUUID);
return LLItemBridge::removeItem();
}
void LLGestureBridge::buildContextMenu(LLMenuGL& menu, U32 flags)
{
- // *TODO: Translate
lldebugs << "LLGestureBridge::buildContextMenu()" << llendl;
std::vector<std::string> items;
std::vector<std::string> disabled_items;
@@ -3116,15 +3399,6 @@ void LLGestureBridge::buildContextMenu(LLMenuGL& menu, U32 flags)
items.push_back(std::string("Gesture Separator"));
items.push_back(std::string("Activate"));
items.push_back(std::string("Deactivate"));
-
- /*menu.append(new LLMenuItemCallGL("Activate",
- handleActivateGesture,
- enableActivateGesture,
- (void*)this));
- menu.append(new LLMenuItemCallGL("Deactivate",
- handleDeactivateGesture,
- enableDeactivateGesture,
- (void*)this));*/
}
hideContextEntries(menu, items, disabled_items);
}
@@ -3133,9 +3407,6 @@ void LLGestureBridge::buildContextMenu(LLMenuGL& menu, U32 flags)
// | LLAnimationBridge |
// +=================================================+
-std::string LLAnimationBridge::sPrefix("Animation: ");
-
-
LLUIImagePtr LLAnimationBridge::getIcon() const
{
return get_item_icon(LLAssetType::AT_ANIMATION, LLInventoryType::IT_ANIMATION, 0, FALSE);
@@ -3143,7 +3414,6 @@ LLUIImagePtr LLAnimationBridge::getIcon() const
void LLAnimationBridge::buildContextMenu(LLMenuGL& menu, U32 flags)
{
- // *TODO: Translate
std::vector<std::string> items;
std::vector<std::string> disabled_items;
@@ -3177,32 +3447,18 @@ void LLAnimationBridge::buildContextMenu(LLMenuGL& menu, U32 flags)
// virtual
void LLAnimationBridge::performAction(LLFolderView* folder, LLInventoryModel* model, std::string action)
{
- S32 activate = 0;
-
if ((action == "playworld") || (action == "playlocal"))
{
-
- if ("playworld" == action) activate = 1;
- if ("playlocal" == action) activate = 2;
-
- // See if we can bring an existing preview to the front
- if( !LLPreview::show( mUUID ) )
+ if (getItem())
{
- // There isn't one, so make a new preview
- LLViewerInventoryItem* item = getItem();
- if( item )
+ LLPreviewAnim::e_activation_type activate = LLPreviewAnim::NONE;
+ if ("playworld" == action) activate = LLPreviewAnim::PLAY;
+ if ("playlocal" == action) activate = LLPreviewAnim::AUDITION;
+
+ LLPreviewAnim* preview = LLFloaterReg::showTypedInstance<LLPreviewAnim>("preview_anim", LLSD(mUUID));
+ if (preview)
{
- S32 left, top;
- gFloaterView->getNewFloaterPosition(&left, &top);
- LLRect rect = gSavedSettings.getRect("PreviewAnimRect");
- rect.translate( left - rect.mLeft, top - rect.mTop );
- LLPreviewAnim* preview = new LLPreviewAnim("preview anim",
- rect,
- getPrefix() + item->getName(),
- mUUID,
- activate);
- // Force to be entirely onscreen.
- gFloaterView->adjustToFitScreen(preview, FALSE);
+ preview->activate(activate);
}
}
}
@@ -3214,27 +3470,19 @@ void LLAnimationBridge::performAction(LLFolderView* folder, LLInventoryModel* mo
void LLAnimationBridge::openItem()
{
- // See if we can bring an existing preview to the front
- if( !LLPreview::show( mUUID ) )
+ LLViewerInventoryItem* item = getItem();
+
+ if (item)
{
- // There isn't one, so make a new preview
- LLViewerInventoryItem* item = getItem();
- if( item )
- {
- S32 left, top;
- gFloaterView->getNewFloaterPosition(&left, &top);
- LLRect rect = gSavedSettings.getRect("PreviewAnimRect");
- rect.translate( left - rect.mLeft, top - rect.mTop );
- LLPreviewAnim* preview = new LLPreviewAnim("preview anim",
- rect,
- getPrefix() + item->getName(),
- mUUID,
- 0);
- preview->setFocus(TRUE);
- // Force to be entirely onscreen.
- gFloaterView->adjustToFitScreen(preview, FALSE);
- }
+ LLInvFVBridgeAction::doAction(item->getType(),mUUID,getInventoryModel());
}
+/*
+ LLViewerInventoryItem* item = getItem();
+ if (item)
+ {
+ LLFloaterReg::showInstance("preview_anim", LLSD(mUUID), TAKE_FOCUS_YES);
+ }
+*/
}
// +=================================================+
@@ -3242,16 +3490,21 @@ void LLAnimationBridge::openItem()
// +=================================================+
// static
-std::string LLObjectBridge::sPrefix("Object: ");
-
-// static
LLUUID LLObjectBridge::sContextMenuItemID;
+LLObjectBridge::LLObjectBridge(LLInventoryPanel* inventory, const LLUUID& uuid, LLInventoryType::EType type, U32 flags) :
+LLItemBridge(inventory, uuid), mInvType(type)
+{
+ mAttachPt = (flags & 0xff); // low bye of inventory flags
+
+ mIsMultiObject = ( flags & LLInventoryItem::II_FLAGS_OBJECT_HAS_MULTIPLE_ITEMS ) ? TRUE: FALSE;
+}
+
BOOL LLObjectBridge::isItemRemovable()
{
- LLVOAvatar* avatar = gAgent.getAvatarObject();
+ LLVOAvatarSelf* avatar = gAgent.getAvatarObject();
if(!avatar) return FALSE;
- if(avatar->isWearingAttachment(mUUID)) return FALSE;
+ if(avatar->isWearingAttachment(mUUID, TRUE)) return FALSE;
return LLInvFVBridge::isItemRemovable();
}
@@ -3260,7 +3513,16 @@ LLUIImagePtr LLObjectBridge::getIcon() const
return get_item_icon(LLAssetType::AT_OBJECT, mInvType, mAttachPt, mIsMultiObject );
}
-void rez_attachment(LLViewerInventoryItem* item, LLViewerJointAttachment* attachment);
+LLInventoryObject* LLObjectBridge::getObject() const
+{
+ LLInventoryObject* object = NULL;
+ LLInventoryModel* model = getInventoryModel();
+ if(model)
+ {
+ object = (LLInventoryObject*)model->getObject(mUUID);
+ }
+ return object;
+}
// virtual
void LLObjectBridge::performAction(LLFolderView* folder, LLInventoryModel* model, std::string action)
@@ -3270,7 +3532,7 @@ void LLObjectBridge::performAction(LLFolderView* folder, LLInventoryModel* model
LLUUID object_id = mUUID;
LLViewerInventoryItem* item;
item = (LLViewerInventoryItem*)gInventory.getItem(object_id);
- if(item && gInventory.isObjectDescendentOf(object_id, gAgent.getInventoryRootID()))
+ if(item && gInventory.isObjectDescendentOf(object_id, gInventory.getRootFolderID()))
{
rez_attachment(item, NULL);
}
@@ -3317,28 +3579,40 @@ void LLObjectBridge::performAction(LLFolderView* folder, LLInventoryModel* model
void LLObjectBridge::openItem()
{
- /* Disabled -- this preview isn't useful. JC */
- // CP: actually, this code is required - made changes to match LLAnimationBridge::openItem() idiom
- // The properties preview is useful, converting to show object properties. - DaveP
- LLShowProps::showProperties(mUUID);
+ LLViewerInventoryItem* item = getItem();
+
+ if (item)
+ {
+ LLInvFVBridgeAction::doAction(item->getType(),mUUID,getInventoryModel());
+ }
+
+ /*
+ LLFloaterReg::showInstance("properties", mUUID);
+ */
}
LLFontGL::StyleFlags LLObjectBridge::getLabelStyle() const
{
- LLVOAvatar* avatar = gAgent.getAvatarObject();
+ U8 font = LLFontGL::NORMAL;
+
+ LLVOAvatarSelf* avatar = gAgent.getAvatarObject();
if( avatar && avatar->isWearingAttachment( mUUID ) )
{
- return LLFontGL::BOLD;
+ font |= LLFontGL::BOLD;
}
- else
+
+ LLInventoryItem* item = getItem();
+ if (item && item->getIsLinkType())
{
- return LLFontGL::NORMAL;
+ font |= LLFontGL::ITALIC;
}
+
+ return (LLFontGL::StyleFlags)font;
}
std::string LLObjectBridge::getLabelSuffix() const
{
- LLVOAvatar* avatar = gAgent.getAvatarObject();
+ LLVOAvatarSelf* avatar = gAgent.getAvatarObject();
if( avatar && avatar->isWearingAttachment( mUUID ) )
{
std::string attachment_point_name = avatar->getAttachedPointName(mUUID);
@@ -3354,7 +3628,7 @@ std::string LLObjectBridge::getLabelSuffix() const
void rez_attachment(LLViewerInventoryItem* item, LLViewerJointAttachment* attachment)
{
LLSD payload;
- payload["item_id"] = item->getUUID();
+ payload["item_id"] = item->getLinkedUUID(); // Wear the base object in case this is a link.
S32 attach_pt = 0;
if (gAgent.getAvatarObject() && attachment)
@@ -3412,7 +3686,6 @@ static LLNotificationFunctorRegistration confirm_replace_attachment_rez_reg("Rep
void LLObjectBridge::buildContextMenu(LLMenuGL& menu, U32 flags)
{
- // *TODO: Translate
std::vector<std::string> items;
std::vector<std::string> disabled_items;
if(isInTrash())
@@ -3427,16 +3700,21 @@ void LLObjectBridge::buildContextMenu(LLMenuGL& menu, U32 flags)
}
else
{
+ LLInventoryItem* item = getItem();
+ if (item && item->getIsLinkType())
+ {
+ items.push_back(std::string("Goto Link"));
+ }
+
items.push_back(std::string("Properties"));
getClipboardEntries(true, items, disabled_items, flags);
LLObjectBridge::sContextMenuItemID = mUUID;
- LLInventoryItem* item = getItem();
if(item)
{
- LLVOAvatar *avatarp = gAgent.getAvatarObject();
+ LLVOAvatarSelf* avatarp = gAgent.getAvatarObject();
if( !avatarp )
{
return;
@@ -3447,7 +3725,7 @@ void LLObjectBridge::buildContextMenu(LLMenuGL& menu, U32 flags)
items.push_back(std::string("Detach From Yourself"));
}
else
- if( !isInTrash() )
+ if( !isInTrash() && !isLinkedObjectInTrash() )
{
items.push_back(std::string("Attach Separator"));
items.push_back(std::string("Object Wear"));
@@ -3456,38 +3734,39 @@ void LLObjectBridge::buildContextMenu(LLMenuGL& menu, U32 flags)
// commented out for DEV-32347
//items.push_back(std::string("Restore to Last Position"));
- LLMenuGL* attach_menu = menu.getChildMenuByName("Attach To", TRUE);
- LLMenuGL* attach_hud_menu = menu.getChildMenuByName("Attach To HUD", TRUE);
+ LLMenuGL* attach_menu = menu.findChildMenuByName("Attach To", TRUE);
+ LLMenuGL* attach_hud_menu = menu.findChildMenuByName("Attach To HUD", TRUE);
LLVOAvatar *avatarp = gAgent.getAvatarObject();
- if (attach_menu && (attach_menu->getChildCount() == 0) &&
- attach_hud_menu && (attach_hud_menu->getChildCount() == 0) &&
- avatarp)
+ if (attach_menu
+ && (attach_menu->getChildCount() == 0)
+ && attach_hud_menu
+ && (attach_hud_menu->getChildCount() == 0)
+ && avatarp)
{
for (LLVOAvatar::attachment_map_t::iterator iter = avatarp->mAttachmentPoints.begin();
iter != avatarp->mAttachmentPoints.end(); )
{
LLVOAvatar::attachment_map_t::iterator curiter = iter++;
LLViewerJointAttachment* attachment = curiter->second;
- LLMenuItemCallGL *new_item;
- if (attachment->getIsHUDAttachment())
+ LLMenuItemCallGL::Params p;
+ std::string submenu_name = attachment->getName();
+ if (LLTrans::getString(submenu_name) != "")
{
- attach_hud_menu->append(new_item = new LLMenuItemCallGL(attachment->getName(),
- NULL, //&LLObjectBridge::attachToAvatar,
- NULL, &attach_label, (void*)attachment));
+ p.name = (" ")+LLTrans::getString(submenu_name)+" ";
}
else
{
- attach_menu->append(new_item = new LLMenuItemCallGL(attachment->getName(),
- NULL, //&LLObjectBridge::attachToAvatar,
- NULL, &attach_label, (void*)attachment));
- }
-
- LLSimpleListener* callback = mInventoryPanel->getListenerByName("Inventory.AttachObject");
-
- if (callback)
- {
- new_item->addListener(callback, "on_click", LLSD(attachment->getName()));
+ p.name = submenu_name;
}
+ LLSD cbparams;
+ cbparams["index"] = curiter->first;
+ cbparams["label"] = attachment->getName();
+ p.on_click.function_name = "Inventory.AttachObject";
+ p.on_click.parameter = LLSD(attachment->getName());
+ p.on_enable.function_name = "Attachment.Label";
+ p.on_enable.parameter = cbparams;
+ LLView* parent = attachment->getIsHUDAttachment() ? attach_hud_menu : attach_menu;
+ LLUICtrlFactory::create<LLMenuItemCallGL>(p, parent);
}
}
}
@@ -3498,10 +3777,12 @@ void LLObjectBridge::buildContextMenu(LLMenuGL& menu, U32 flags)
BOOL LLObjectBridge::renameItem(const std::string& new_name)
{
- if(!isItemRenameable()) return FALSE;
- LLPreview::rename(mUUID, getPrefix() + new_name);
- LLInventoryModel* model = mInventoryPanel->getModel();
- if(!model) return FALSE;
+ if(!isItemRenameable())
+ return FALSE;
+ LLPreview::dirty(mUUID);
+ LLInventoryModel* model = getInventoryModel();
+ if(!model)
+ return FALSE;
LLViewerInventoryItem* item = getItem();
if(item && (item->getName() != new_name))
{
@@ -3510,9 +3791,11 @@ BOOL LLObjectBridge::renameItem(const std::string& new_name)
buildDisplayName(new_item, mDisplayName);
new_item->updateServer(FALSE);
model->updateItem(new_item);
+ model->updateLinkedObjects(item->getUUID());
+
model->notifyObservers();
- LLVOAvatar* avatar = gAgent.getAvatarObject();
+ LLVOAvatarSelf* avatar = gAgent.getAvatarObject();
if( avatar )
{
LLViewerObject* obj = avatar->getWornAttachment( item->getUUID() );
@@ -3534,8 +3817,6 @@ BOOL LLObjectBridge::renameItem(const std::string& new_name)
// | LLLSLTextBridge |
// +=================================================+
-std::string LLLSLTextBridge::sPrefix("Script: ");
-
LLUIImagePtr LLLSLTextBridge::getIcon() const
{
return get_item_icon(LLAssetType::AT_SCRIPT, LLInventoryType::IT_LSL, 0, FALSE);
@@ -3543,27 +3824,19 @@ LLUIImagePtr LLLSLTextBridge::getIcon() const
void LLLSLTextBridge::openItem()
{
- // See if we can bring an exiting preview to the front
- if(!LLPreview::show(mUUID))
+ LLViewerInventoryItem* item = getItem();
+
+ if (item)
{
- LLViewerInventoryItem* item = getItem();
- if (item)
- {
- // There isn't one, so make a new preview
- S32 left, top;
- gFloaterView->getNewFloaterPosition(&left, &top);
- LLRect rect = gSavedSettings.getRect("PreviewScriptRect");
- rect.translate(left - rect.mLeft, top - rect.mTop);
-
- LLPreviewLSL* preview = new LLPreviewLSL("preview lsl text",
- rect,
- getPrefix() + item->getName(),
- mUUID);
- preview->setFocus(TRUE);
- // keep onscreen
- gFloaterView->adjustToFitScreen(preview, FALSE);
- }
+ LLInvFVBridgeAction::doAction(item->getType(),mUUID,getInventoryModel());
+ }
+ /*
+ LLViewerInventoryItem* item = getItem();
+ if (item)
+ {
+ LLFloaterReg::showInstance("preview_script", LLSD(mUUID), TAKE_FOCUS_YES);
}
+ */
}
// +=================================================+
@@ -3578,7 +3851,7 @@ void wear_inventory_item_on_avatar( LLInventoryItem* item )
lldebugs << "wear_inventory_item_on_avatar( " << item->getName()
<< " )" << llendl;
- gWearableList.getAsset(item->getAssetUUID(),
+ LLWearableList::instance().getAsset(item->getAssetUUID(),
item->getName(),
item->getType(),
LLWearableBridge::onWearOnAvatarArrived,
@@ -3586,6 +3859,22 @@ void wear_inventory_item_on_avatar( LLInventoryItem* item )
}
}
+void wear_add_inventory_item_on_avatar( LLInventoryItem* item )
+{
+ if(item)
+ {
+ lldebugs << "wear_add_inventory_item_on_avatar( " << item->getName()
+ << " )" << llendl;
+
+ LLWearableList::instance().getAsset(item->getAssetUUID(),
+ item->getName(),
+ item->getType(),
+ LLWearableBridge::onWearAddOnAvatarArrived,
+ new LLUUID(item->getUUID()));
+ }
+}
+
+
struct LLFoundData
{
LLFoundData(const LLUUID& item_id,
@@ -3715,7 +4004,7 @@ void LLOutfitObserver::done()
}
if(pid.isNull())
{
- pid = gAgent.getInventoryRootID();
+ pid = gInventory.getRootFolderID();
}
LLUUID cat_id = gInventory.createNewCategory(
@@ -3822,7 +4111,7 @@ void wear_outfit_by_name(const std::string& name)
LLInventoryModel::cat_array_t cat_array;
LLInventoryModel::item_array_t item_array;
LLNameCategoryCollector has_name(name);
- gInventory.collectDescendentsIf(gAgent.getInventoryRootID(),
+ gInventory.collectDescendentsIf(gInventory.getRootFolderID(),
cat_array,
item_array,
LLInventoryModel::EXCLUDE_TRASH,
@@ -3899,30 +4188,71 @@ void wear_inventory_category_on_avatar( LLInventoryCategory* category, BOOL appe
lldebugs << "wear_inventory_category_on_avatar( " << category->getName()
<< " )" << llendl;
- LLWearInfo* userdata = new LLWearInfo;
- userdata->mAppend = append;
- userdata->mCategoryID = category->getUUID();
-
+ BOOL follow_folder_links = (category->getPreferredType() == LLAssetType::AT_CURRENT_OUTFIT || category->getPreferredType() == LLAssetType::AT_OUTFIT );
if( gFloaterCustomize )
{
- gFloaterCustomize->askToSaveIfDirty(
- wear_inventory_category_on_avatar_step2,
- userdata);
+ gFloaterCustomize->askToSaveIfDirty(boost::bind(wear_inventory_category_on_avatar_step2, _1, category->getUUID(), append, follow_folder_links));
}
else
{
- wear_inventory_category_on_avatar_step2(
- TRUE,
- userdata );
+ wear_inventory_category_on_avatar_step2(TRUE, category->getUUID(), append, follow_folder_links );
}
}
-
-void wear_inventory_category_on_avatar_step2( BOOL proceed, void* userdata )
+void removeDuplicateItems(LLInventoryModel::item_array_t& dst, const LLInventoryModel::item_array_t& src)
{
- LLWearInfo* wear_info = (LLWearInfo*)userdata;
- if (!wear_info) return;
+ LLInventoryModel::item_array_t new_dst;
+ std::set<LLUUID> mark_inventory;
+ std::set<LLUUID> mark_asset;
+
+ S32 inventory_dups = 0;
+ S32 asset_dups = 0;
+
+ for (LLInventoryModel::item_array_t::const_iterator src_pos = src.begin();
+ src_pos != src.end();
+ ++src_pos)
+ {
+ LLUUID src_item_id = (*src_pos)->getLinkedUUID();
+ mark_inventory.insert(src_item_id);
+ LLUUID src_asset_id = (*src_pos)->getAssetUUID();
+ mark_asset.insert(src_asset_id);
+ }
+
+ for (LLInventoryModel::item_array_t::const_iterator dst_pos = dst.begin();
+ dst_pos != dst.end();
+ ++dst_pos)
+ {
+ LLUUID dst_item_id = (*dst_pos)->getLinkedUUID();
+
+ if (mark_inventory.find(dst_item_id) == mark_inventory.end())
+ {
+ }
+ else
+ {
+ inventory_dups++;
+ }
+
+ LLUUID dst_asset_id = (*dst_pos)->getAssetUUID();
+
+ if (mark_asset.find(dst_asset_id) == mark_asset.end())
+ {
+ // Item is not already present in COF.
+ new_dst.put(*dst_pos);
+ mark_asset.insert(dst_item_id);
+ }
+ else
+ {
+ asset_dups++;
+ }
+ }
+ llinfos << "removeDups, original " << dst.count() << " final " << new_dst.count()
+ << " inventory dups " << inventory_dups << " asset_dups " << asset_dups << llendl;
+
+ dst = new_dst;
+}
+void wear_inventory_category_on_avatar_step2( BOOL proceed, LLUUID category, BOOL append, BOOL follow_folder_links )
+{
// Find all the wearables that are in the category's subtree.
lldebugs << "wear_inventory_category_on_avatar_step2()" << llendl;
if(proceed)
@@ -3930,46 +4260,76 @@ void wear_inventory_category_on_avatar_step2( BOOL proceed, void* userdata )
LLInventoryModel::cat_array_t cat_array;
LLInventoryModel::item_array_t item_array;
LLFindWearables is_wearable;
- gInventory.collectDescendentsIf(wear_info->mCategoryID,
+ gInventory.collectDescendentsIf(category,
cat_array,
item_array,
LLInventoryModel::EXCLUDE_TRASH,
- is_wearable);
+ is_wearable,
+ follow_folder_links);
S32 i;
S32 wearable_count = item_array.count();
LLInventoryModel::cat_array_t obj_cat_array;
LLInventoryModel::item_array_t obj_item_array;
LLIsType is_object( LLAssetType::AT_OBJECT );
- gInventory.collectDescendentsIf(wear_info->mCategoryID,
+ gInventory.collectDescendentsIf(category,
obj_cat_array,
obj_item_array,
LLInventoryModel::EXCLUDE_TRASH,
- is_object);
+ is_object,
+ follow_folder_links);
S32 obj_count = obj_item_array.count();
// Find all gestures in this folder
LLInventoryModel::cat_array_t gest_cat_array;
LLInventoryModel::item_array_t gest_item_array;
LLIsType is_gesture( LLAssetType::AT_GESTURE );
- gInventory.collectDescendentsIf(wear_info->mCategoryID,
+ gInventory.collectDescendentsIf(category,
gest_cat_array,
gest_item_array,
LLInventoryModel::EXCLUDE_TRASH,
- is_gesture);
+ is_gesture,
+ follow_folder_links);
S32 gest_count = gest_item_array.count();
if( !wearable_count && !obj_count && !gest_count)
{
LLNotifications::instance().add("CouldNotPutOnOutfit");
- delete wear_info;
return;
}
-
+
+ const LLUUID &current_outfit_id = gInventory.findCategoryUUIDForType(LLAssetType::AT_CURRENT_OUTFIT);
// Processes that take time should show the busy cursor
+ inc_busy_count();
+
+ LLInventoryModel::cat_array_t co_cat_array;
+ LLInventoryModel::item_array_t co_item_array;
+ gInventory.collectDescendents(current_outfit_id, co_cat_array, co_item_array,
+ LLInventoryModel::EXCLUDE_TRASH);
+ if (append)
+ {
+ // Remove duplicates and update counts.
+ removeDuplicateItems(item_array,co_item_array);
+ wearable_count = item_array.count();
+
+ removeDuplicateItems(obj_item_array,co_item_array);
+ obj_count = obj_item_array.count();
+
+ removeDuplicateItems(gest_item_array,co_item_array);
+ gest_count = gest_item_array.count();
+ }
+
+
if (wearable_count > 0 || obj_count > 0)
{
- inc_busy_count();
+ if (!append)
+ {
+ // Remove all current outfit folder links if we're now replacing the contents.
+ for (i = 0; i < co_item_array.count(); ++i)
+ {
+ gInventory.purgeObject(co_item_array.get(i)->getUUID());
+ }
+ }
}
// Activate all gestures in this folder
@@ -3977,11 +4337,11 @@ void wear_inventory_category_on_avatar_step2( BOOL proceed, void* userdata )
{
llinfos << "Activating " << gest_count << " gestures" << llendl;
- gGestureManager.activateGestures(gest_item_array);
+ LLGestureManager::instance().activateGestures(gest_item_array);
// Update the inventory item labels to reflect the fact
// they are active.
- LLViewerInventoryCategory* catp = gInventory.getCategory(wear_info->mCategoryID);
+ LLViewerInventoryCategory* catp = gInventory.getCategory(category);
if (catp)
{
gInventory.updateCategory(catp);
@@ -4009,23 +4369,29 @@ void wear_inventory_category_on_avatar_step2( BOOL proceed, void* userdata )
}
for(i = 0; i < wearable_count; ++i)
{
- gAddToOutfit = wear_info->mAppend;
-
+ gAddToOutfit = append;
found = found_container.get(i);
- gWearableList.getAsset(found->mAssetID,
- found->mName,
- found->mAssetType,
- wear_inventory_category_on_avatar_loop,
- (void*)holder);
+
+ // Populate the current outfit folder with links to the newly added wearables
+ std::string link_name = "WearableLink";
+ link_inventory_item(gAgent.getID(), found->mItemID, current_outfit_id, link_name,
+ LLAssetType::AT_LINK, LLPointer<LLInventoryCallback>(NULL));
+
+ // Fetch the wearables about to be worn.
+ LLWearableList::instance().getAsset(found->mAssetID,
+ found->mName,
+ found->mAssetType,
+ wear_inventory_category_on_avatar_loop,
+ (void*)holder);
}
}
//If not appending and the folder doesn't contain only gestures, take off all attachments.
- if (!wear_info->mAppend
+ if (!append
&& !(wearable_count == 0 && obj_count == 0 && gest_count > 0) )
{
- LLAgent::userRemoveAllAttachments(NULL);
+ LLAgentWearables::userRemoveAllAttachments(NULL);
}
if( obj_count > 0 )
@@ -4063,12 +4429,12 @@ void wear_inventory_category_on_avatar_step2( BOOL proceed, void* userdata )
msg->nextBlockFast(_PREHASH_HeaderData);
msg->addUUIDFast(_PREHASH_CompoundMsgID, compound_msg_id );
msg->addU8Fast(_PREHASH_TotalObjects, obj_count );
- msg->addBOOLFast(_PREHASH_FirstDetachAll, !wear_info->mAppend );
+ msg->addBOOLFast(_PREHASH_FirstDetachAll, !append );
}
- LLInventoryItem* item = obj_item_array.get(i);
+ const LLInventoryItem* item = obj_item_array.get(i).get();
msg->nextBlockFast(_PREHASH_ObjectData );
- msg->addUUIDFast(_PREHASH_ItemID, item->getUUID() );
+ msg->addUUIDFast(_PREHASH_ItemID, item->getLinkedUUID());
msg->addUUIDFast(_PREHASH_OwnerID, item->getPermissions().getOwner());
msg->addU8Fast(_PREHASH_AttachmentPt, 0 ); // Wear at the previous or default attachment point
pack_permissions_slam(msg, item->getFlags(), item->getPermissions());
@@ -4080,12 +4446,28 @@ void wear_inventory_category_on_avatar_step2( BOOL proceed, void* userdata )
// End of message chunk
msg->sendReliable( gAgent.getRegion()->getHost() );
}
+
+ }
+
+ for(i = 0; i < obj_count; ++i)
+ {
+ const std::string link_name = "AttachmentLink";
+ const LLInventoryItem* item = obj_item_array.get(i).get();
+ link_inventory_item(gAgent.getID(), item->getLinkedUUID(), current_outfit_id, link_name,
+ LLAssetType::AT_LINK, LLPointer<LLInventoryCallback>(NULL));
}
}
}
+
+ // In the particular case that we're switching to a different outfit,
+ // create a link to the folder that we wore.
+ LLViewerInventoryCategory* catp = gInventory.getCategory(category);
+ if (!append && catp && catp->getPreferredType() == LLAssetType::AT_OUTFIT)
+ {
+ link_inventory_item(gAgent.getID(), category, current_outfit_id, catp->getName(),
+ LLAssetType::AT_LINK_FOLDER, LLPointer<LLInventoryCallback>(NULL));
+ }
}
- delete wear_info;
- wear_info = NULL;
}
void wear_inventory_category_on_avatar_loop(LLWearable* wearable, void* data)
@@ -4099,7 +4481,7 @@ void wear_inventory_category_on_avatar_loop(LLWearable* wearable, void* data)
iter != holder->mFoundList.end(); ++iter)
{
LLFoundData* data = *iter;
- if(wearable->getID() == data->mAssetID)
+ if(wearable->getAssetID() == data->mAssetID)
{
data->mWearable = wearable;
break;
@@ -4132,20 +4514,8 @@ void wear_inventory_category_on_avatar_step3(LLWearableHoldingPattern* holder, B
{
LLViewerInventoryItem* item;
item = (LLViewerInventoryItem*)gInventory.getItem(data->mItemID);
- if( item && (item->getAssetUUID() == wearable->getID()) )
+ if( item && (item->getAssetUUID() == wearable->getAssetID()) )
{
- //RN: after discussing with Brashears, I disabled this code
- //Metadata should reside in the item, not the asset
- //And this code does not handle failed asset uploads properly
-// if(!wearable->isMatchedToInventoryItem(item ))
-// {
-// wearable = gWearableList.createWearableMatchedToInventoryItem( wearable, item );
-// // Now that we have an asset that matches the
-// // item, update the item to point to the new
-// // asset.
-// item->setAssetUUID(wearable->getID());
-// item->updateAssetOnServer();
-// }
items.put(item);
wearables.put(wearable);
}
@@ -4156,7 +4526,7 @@ void wear_inventory_category_on_avatar_step3(LLWearableHoldingPattern* holder, B
if(wearables.count() > 0)
{
- gAgent.setWearableOutfit(items, wearables, !append);
+ gAgentWearables.setWearableOutfit(items, wearables, !append);
gInventory.notifyObservers();
}
@@ -4172,36 +4542,29 @@ void remove_inventory_category_from_avatar( LLInventoryCategory* category )
<< " )" << llendl;
- LLUUID* uuid = new LLUUID(category->getUUID());
-
if( gFloaterCustomize )
{
gFloaterCustomize->askToSaveIfDirty(
- remove_inventory_category_from_avatar_step2,
- uuid);
+ boost::bind(remove_inventory_category_from_avatar_step2, _1, category->getUUID()));
}
else
{
- remove_inventory_category_from_avatar_step2(
- TRUE,
- uuid );
+ remove_inventory_category_from_avatar_step2(TRUE, category->getUUID() );
}
}
-void remove_inventory_category_from_avatar_step2( BOOL proceed, void* userdata)
+void remove_inventory_category_from_avatar_step2( BOOL proceed, LLUUID category_id)
{
// Find all the wearables that are in the category's subtree.
- LLUUID* category_id = (LLUUID *)userdata;
-
lldebugs << "remove_inventory_category_from_avatar_step2()" << llendl;
if(proceed)
{
LLInventoryModel::cat_array_t cat_array;
LLInventoryModel::item_array_t item_array;
LLFindWearables is_wearable;
- gInventory.collectDescendentsIf(*category_id,
+ gInventory.collectDescendentsIf(category_id,
cat_array,
item_array,
LLInventoryModel::EXCLUDE_TRASH,
@@ -4212,7 +4575,7 @@ void remove_inventory_category_from_avatar_step2( BOOL proceed, void* userdata)
LLInventoryModel::cat_array_t obj_cat_array;
LLInventoryModel::item_array_t obj_item_array;
LLIsType is_object( LLAssetType::AT_OBJECT );
- gInventory.collectDescendentsIf(*category_id,
+ gInventory.collectDescendentsIf(category_id,
obj_cat_array,
obj_item_array,
LLInventoryModel::EXCLUDE_TRASH,
@@ -4223,7 +4586,7 @@ void remove_inventory_category_from_avatar_step2( BOOL proceed, void* userdata)
LLInventoryModel::cat_array_t gest_cat_array;
LLInventoryModel::item_array_t gest_item_array;
LLIsType is_gesture( LLAssetType::AT_GESTURE );
- gInventory.collectDescendentsIf(*category_id,
+ gInventory.collectDescendentsIf(category_id,
gest_cat_array,
gest_item_array,
LLInventoryModel::EXCLUDE_TRASH,
@@ -4234,9 +4597,9 @@ void remove_inventory_category_from_avatar_step2( BOOL proceed, void* userdata)
{
for(i = 0; i < wearable_count; ++i)
{
- if( gAgent.isWearingItem (item_array.get(i)->getUUID()) )
+ if( gAgentWearables.isWearingItem (item_array.get(i)->getUUID()) )
{
- gWearableList.getAsset(item_array.get(i)->getAssetUUID(),
+ LLWearableList::instance().getAsset(item_array.get(i)->getAssetUUID(),
item_array.get(i)->getName(),
item_array.get(i)->getType(),
LLWearableBridge::onRemoveFromAvatarArrived,
@@ -4275,9 +4638,9 @@ void remove_inventory_category_from_avatar_step2( BOOL proceed, void* userdata)
{
for(i = 0; i < gest_count; ++i)
{
- if ( gGestureManager.isGestureActive( gest_item_array.get(i)->getUUID()) )
+ if ( LLGestureManager::instance().isGestureActive( gest_item_array.get(i)->getUUID()) )
{
- gGestureManager.deactivateGesture( gest_item_array.get(i)->getUUID() );
+ LLGestureManager::instance().deactivateGesture( gest_item_array.get(i)->getUUID() );
gInventory.updateItem( gest_item_array.get(i) );
gInventory.notifyObservers();
}
@@ -4285,41 +4648,26 @@ void remove_inventory_category_from_avatar_step2( BOOL proceed, void* userdata)
}
}
}
- delete category_id;
- category_id = NULL;
}
BOOL LLWearableBridge::renameItem(const std::string& new_name)
{
- if( gAgent.isWearingItem( mUUID ) )
+ if( gAgentWearables.isWearingItem( mUUID ) )
{
- gAgent.setWearableName( mUUID, new_name );
+ gAgentWearables.setWearableName( mUUID, new_name );
}
return LLItemBridge::renameItem(new_name);
}
BOOL LLWearableBridge::isItemRemovable()
{
- if(gAgent.isWearingItem(mUUID)) return FALSE;
+ if (gAgentWearables.isWearingItem(mUUID, TRUE)) return FALSE;
return LLInvFVBridge::isItemRemovable();
}
-LLFontGL::StyleFlags LLWearableBridge::getLabelStyle() const
-{
- if( gAgent.isWearingItem( mUUID ) )
- {
- // llinfos << "BOLD" << llendl;
- return LLFontGL::BOLD;
- }
- else
- {
- return LLFontGL::NORMAL;
- }
-}
-
std::string LLWearableBridge::getLabelSuffix() const
{
- if( gAgent.isWearingItem( mUUID ) )
+ if( gAgentWearables.isWearingItem( mUUID ) )
{
return LLItemBridge::getLabelSuffix() + " (worn)";
}
@@ -4341,6 +4689,10 @@ void LLWearableBridge::performAction(LLFolderView* folder, LLInventoryModel* mod
{
wearOnAvatar();
}
+ else if ("wear_add" == action)
+ {
+ wearAddOnAvatar();
+ }
else if ("edit" == action)
{
editOnAvatar();
@@ -4348,12 +4700,12 @@ void LLWearableBridge::performAction(LLFolderView* folder, LLInventoryModel* mod
}
else if ("take_off" == action)
{
- if(gAgent.isWearingItem(mUUID))
+ if(gAgentWearables.isWearingItem(mUUID))
{
LLViewerInventoryItem* item = getItem();
if (item)
{
- gWearableList.getAsset(item->getAssetUUID(),
+ LLWearableList::instance().getAsset(item->getAssetUUID(),
item->getName(),
item->getType(),
LLWearableBridge::onRemoveFromAvatarArrived,
@@ -4366,13 +4718,20 @@ void LLWearableBridge::performAction(LLFolderView* folder, LLInventoryModel* mod
void LLWearableBridge::openItem()
{
+ LLViewerInventoryItem* item = getItem();
+
+ if (item)
+ {
+ LLInvFVBridgeAction::doAction(item->getType(),mUUID,getInventoryModel());
+ }
+ /*
if( isInTrash() )
{
LLNotifications::instance().add("CannotWearTrash");
}
else if(isAgentInventory())
{
- if( !gAgent.isWearingItem( mUUID ) )
+ if( !gAgentWearables.isWearingItem( mUUID ) )
{
wearOnAvatar();
}
@@ -4400,11 +4759,11 @@ void LLWearableBridge::openItem()
LLNotifications::instance().add("CannotWearInfoNotComplete");
}
}
+ */
}
void LLWearableBridge::buildContextMenu(LLMenuGL& menu, U32 flags)
{
- // *TODO: Translate
lldebugs << "LLWearableBridge::buildContextMenu()" << llendl;
std::vector<std::string> items;
std::vector<std::string> disabled_items;
@@ -4434,6 +4793,11 @@ void LLWearableBridge::buildContextMenu(LLMenuGL& menu, U32 flags)
items.push_back(std::string("Open"));
}
+ if (item && item->getIsLinkType())
+ {
+ items.push_back(std::string("Goto Link"));
+ }
+
items.push_back(std::string("Properties"));
getClipboardEntries(true, items, disabled_items, flags);
@@ -4441,29 +4805,24 @@ void LLWearableBridge::buildContextMenu(LLMenuGL& menu, U32 flags)
items.push_back(std::string("Wearable Separator"));
items.push_back(std::string("Wearable Wear"));
+ items.push_back(std::string("Wearable Add"));
items.push_back(std::string("Wearable Edit"));
if ((flags & FIRST_SELECTED_ITEM) == 0)
{
disabled_items.push_back(std::string("Wearable Edit"));
}
- //menu.appendSeparator();
- //menu.append(new LLMenuItemCallGL("Wear",
- // LLWearableBridge::onWearOnAvatar,
- // LLWearableBridge::canWearOnAvatar,
- // (void*)this));
- //menu.append(new LLMenuItemCallGL("Edit",
- // LLWearableBridge::onEditOnAvatar,
- // LLWearableBridge::canEditOnAvatar,
- // (void*)this));
+ // Don't allow items to be worn if their baseobj is in the trash.
+ if (isLinkedObjectInTrash())
+ {
+ disabled_items.push_back(std::string("Wearable Wear"));
+ disabled_items.push_back(std::string("Wearable Add"));
+ disabled_items.push_back(std::string("Wearable Edit"));
+ }
if( item && (item->getType() == LLAssetType::AT_CLOTHING) )
{
items.push_back(std::string("Take Off"));
- /*menu.append(new LLMenuItemCallGL("Take Off",
- LLWearableBridge::onRemoveFromAvatar,
- LLWearableBridge::canRemoveFromAvatar,
- (void*)this));*/
}
}
hideContextEntries(menu, items, disabled_items);
@@ -4480,7 +4839,7 @@ BOOL LLWearableBridge::canWearOnAvatar(void* user_data)
LLViewerInventoryItem* item = (LLViewerInventoryItem*)self->getItem();
if(!item || !item->isComplete()) return FALSE;
}
- return (!gAgent.isWearingItem(self->mUUID));
+ return (!gAgentWearables.isWearingItem(self->mUUID));
}
// Called from menus
@@ -4496,7 +4855,7 @@ void LLWearableBridge::wearOnAvatar()
{
// Don't wear anything until initial wearables are loaded, can
// destroy clothing items.
- if (!gAgent.areWearablesLoaded())
+ if (!gAgentWearables.areWearablesLoaded())
{
LLNotifications::instance().add("CanNotChangeAppearanceUntilLoaded");
return;
@@ -4523,6 +4882,37 @@ void LLWearableBridge::wearOnAvatar()
}
}
+void LLWearableBridge::wearAddOnAvatar()
+{
+ // Don't wear anything until initial wearables are loaded, can
+ // destroy clothing items.
+ if (!gAgentWearables.areWearablesLoaded())
+ {
+ LLNotifications::instance().add("CanNotChangeAppearanceUntilLoaded");
+ return;
+ }
+
+ LLViewerInventoryItem* item = getItem();
+ if(item)
+ {
+ if(!isAgentInventory())
+ {
+ LLPointer<LLInventoryCallback> cb = new WearOnAvatarCallback();
+ copy_inventory_item(
+ gAgent.getID(),
+ item->getPermissions().getOwner(),
+ item->getUUID(),
+ LLUUID::null,
+ std::string(),
+ cb);
+ }
+ else
+ {
+ wear_add_inventory_item_on_avatar(item);
+ }
+ }
+}
+
// static
void LLWearableBridge::onWearOnAvatarArrived( LLWearable* wearable, void* userdata )
{
@@ -4533,24 +4923,35 @@ void LLWearableBridge::onWearOnAvatarArrived( LLWearable* wearable, void* userda
item = (LLViewerInventoryItem*)gInventory.getItem(*item_id);
if(item)
{
- if(item->getAssetUUID() == wearable->getID())
+ if(item->getAssetUUID() == wearable->getAssetID())
{
- //RN: after discussing with Brashears, I disabled this code
- //Metadata should reside in the item, not the asset
- //And this code does not handle failed asset uploads properly
+ gAgentWearables.setWearableItem(item, wearable);
+ gInventory.notifyObservers();
+ //self->getFolderItem()->refreshFromRoot();
+ }
+ else
+ {
+ llinfos << "By the time wearable asset arrived, its inv item already pointed to a different asset." << llendl;
+ }
+ }
+ }
+ delete item_id;
+}
-// if(!wearable->isMatchedToInventoryItem(item))
-// {
-// LLWearable* new_wearable = gWearableList.createWearableMatchedToInventoryItem( wearable, item );
-//
-// // Now that we have an asset that matches the
-// // item, update the item to point to the new
-// // asset.
-// item->setAssetUUID(new_wearable->getID());
-// item->updateAssetOnServer();
-// wearable = new_wearable;
-// }
- gAgent.setWearable(item, wearable);
+// static
+void LLWearableBridge::onWearAddOnAvatarArrived( LLWearable* wearable, void* userdata )
+{
+ LLUUID* item_id = (LLUUID*) userdata;
+ if(wearable)
+ {
+ LLViewerInventoryItem* item = NULL;
+ item = (LLViewerInventoryItem*)gInventory.getItem(*item_id);
+ if(item)
+ {
+ if(item->getAssetUUID() == wearable->getAssetID())
+ {
+ bool do_append = true;
+ gAgentWearables.setWearableItem(item, wearable, do_append);
gInventory.notifyObservers();
//self->getFolderItem()->refreshFromRoot();
}
@@ -4569,7 +4970,7 @@ BOOL LLWearableBridge::canEditOnAvatar(void* user_data)
LLWearableBridge* self = (LLWearableBridge*)user_data;
if(!self) return FALSE;
- return (gAgent.isWearingItem(self->mUUID));
+ return (gAgentWearables.isWearingItem(self->mUUID));
}
// static
@@ -4584,11 +4985,12 @@ void LLWearableBridge::onEditOnAvatar(void* user_data)
void LLWearableBridge::editOnAvatar()
{
- LLWearable* wearable = gAgent.getWearableFromWearableItem(mUUID);
+ const LLWearable* wearable = gAgentWearables.getWearableFromWearableItem(mUUID);
if( wearable )
{
// Set the tab to the right wearable.
- LLFloaterCustomize::setCurrentWearableType( wearable->getType() );
+ if (gFloaterCustomize)
+ gFloaterCustomize->setCurrentWearableType( wearable->getType() );
if( CAMERA_MODE_CUSTOMIZE_AVATAR != gAgent.getCameraMode() )
{
@@ -4604,7 +5006,7 @@ BOOL LLWearableBridge::canRemoveFromAvatar(void* user_data)
LLWearableBridge* self = (LLWearableBridge*)user_data;
if( self && (LLAssetType::AT_BODYPART != self->mAssetType) )
{
- return gAgent.isWearingItem( self->mUUID );
+ return gAgentWearables.isWearingItem( self->mUUID );
}
return FALSE;
}
@@ -4614,12 +5016,12 @@ void LLWearableBridge::onRemoveFromAvatar(void* user_data)
{
LLWearableBridge* self = (LLWearableBridge*)user_data;
if(!self) return;
- if(gAgent.isWearingItem(self->mUUID))
+ if(gAgentWearables.isWearingItem(self->mUUID))
{
LLViewerInventoryItem* item = self->getItem();
if (item)
{
- gWearableList.getAsset(item->getAssetUUID(),
+ LLWearableList::instance().getAsset(item->getAssetUUID(),
item->getName(),
item->getType(),
onRemoveFromAvatarArrived,
@@ -4635,16 +5037,440 @@ void LLWearableBridge::onRemoveFromAvatarArrived(LLWearable* wearable,
LLUUID* item_id = (LLUUID*) userdata;
if(wearable)
{
- if( gAgent.isWearingItem( *item_id ) )
+ if( gAgentWearables.isWearingItem( *item_id ) )
{
EWearableType type = wearable->getType();
if( !(type==WT_SHAPE || type==WT_SKIN || type==WT_HAIR || type==WT_EYES ) ) //&&
//!((!gAgent.isTeen()) && ( type==WT_UNDERPANTS || type==WT_UNDERSHIRT )) )
{
- gAgent.removeWearable( type );
+ // MULTI_WEARABLE: FIXME HACK - always remove all
+ bool do_remove_all = false;
+ gAgentWearables.removeWearable( type, do_remove_all, 0 );
}
}
}
delete item_id;
}
+
+LLInvFVBridgeAction* LLInvFVBridgeAction::createAction(LLAssetType::EType asset_type,
+ const LLUUID& uuid,LLInventoryModel* model)
+{
+ LLInvFVBridgeAction* action = NULL;
+ switch(asset_type)
+ {
+ case LLAssetType::AT_TEXTURE:
+ action = new LLTextureBridgeAction(uuid,model);
+ break;
+
+ case LLAssetType::AT_SOUND:
+ action = new LLSoundBridgeAction(uuid,model);
+ break;
+
+ case LLAssetType::AT_LANDMARK:
+ action = new LLLandmarkBridgeAction(uuid,model);
+ break;
+
+ case LLAssetType::AT_CALLINGCARD:
+ action = new LLCallingCardBridgeAction(uuid,model);
+ break;
+
+ case LLAssetType::AT_OBJECT:
+ action = new LLObjectBridgeAction(uuid,model);
+ break;
+
+ case LLAssetType::AT_NOTECARD:
+ action = new LLNotecardBridgeAction(uuid,model);
+ break;
+
+ case LLAssetType::AT_ANIMATION:
+ action = new LLAnimationBridgeAction(uuid,model);
+ break;
+
+ case LLAssetType::AT_GESTURE:
+ action = new LLGestureBridgeAction(uuid,model);
+ break;
+
+ case LLAssetType::AT_LSL_TEXT:
+ action = new LLLSLTextBridgeAction(uuid,model);
+ break;
+
+ case LLAssetType::AT_CLOTHING:
+ case LLAssetType::AT_BODYPART:
+ action = new LLWearableBridgeAction(uuid,model);
+
+ break;
+
+ default:
+ break;
+ }
+ return action;
+}
+
+//static
+void LLInvFVBridgeAction::doAction(LLAssetType::EType asset_type,
+ const LLUUID& uuid,LLInventoryModel* model)
+{
+ LLInvFVBridgeAction* action = createAction(asset_type,uuid,model);
+ if(action)
+ {
+ action->doIt();
+ delete action;
+ }
+}
+
+//static
+void LLInvFVBridgeAction::doAction(const LLUUID& uuid, LLInventoryModel* model)
+{
+ LLAssetType::EType asset_type = model->getItem(uuid)->getType();
+ LLInvFVBridgeAction* action = createAction(asset_type,uuid,model);
+ if(action)
+ {
+ action->doIt();
+ delete action;
+ }
+}
+
+LLViewerInventoryItem* LLInvFVBridgeAction::getItem() const
+{
+ if(mModel)
+ return (LLViewerInventoryItem*)mModel->getItem(mUUID);
+ return NULL;
+}
+
+//virtual
+void LLTextureBridgeAction::doIt()
+{
+ if (getItem())
+ {
+ LLFloaterReg::showInstance("preview_texture", LLSD(mUUID), TAKE_FOCUS_YES);
+ }
+
+ LLInvFVBridgeAction::doIt();
+}
+
+//virtual
+void LLSoundBridgeAction::doIt()
+{
+ LLViewerInventoryItem* item = getItem();
+ if(item)
+ {
+ LLFloaterReg::showInstance("preview_sound", LLSD(mUUID), TAKE_FOCUS_YES);
+ }
+
+ LLInvFVBridgeAction::doIt();
+}
+
+
+//virtual
+void LLLandmarkBridgeAction::doIt()
+{
+ LLViewerInventoryItem* item = getItem();
+ if( item )
+ {
+ // Opening (double-clicking) a landmark immediately teleports,
+ // but warns you the first time.
+ LLSD payload;
+ payload["asset_id"] = item->getAssetUUID();
+ LLNotifications::instance().add("TeleportFromLandmark", LLSD(), payload);
+ }
+
+ LLInvFVBridgeAction::doIt();
+}
+
+
+//virtual
+void LLCallingCardBridgeAction::doIt()
+{
+ LLViewerInventoryItem* item = getItem();
+ if(item && item->getCreatorUUID().notNull())
+ {
+ LLAvatarActions::showProfile(item->getCreatorUUID());
+ }
+
+ LLInvFVBridgeAction::doIt();
+}
+
+//virtual
+void
+LLNotecardBridgeAction::doIt()
+{
+ LLViewerInventoryItem* item = getItem();
+ if (item)
+ {
+ LLFloaterReg::showInstance("preview_notecard", LLSD(item->getUUID()), TAKE_FOCUS_YES);
+ }
+
+ LLInvFVBridgeAction::doIt();
+}
+
+//virtual
+void LLGestureBridgeAction::doIt()
+{
+ LLViewerInventoryItem* item = getItem();
+ if (item)
+ {
+ LLPreviewGesture* preview = LLPreviewGesture::show(mUUID, LLUUID::null);
+ preview->setFocus(TRUE);
+ }
+
+ LLInvFVBridgeAction::doIt();
+}
+
+//virtual
+void LLAnimationBridgeAction::doIt()
+{
+ LLViewerInventoryItem* item = getItem();
+ if (item)
+ {
+ LLFloaterReg::showInstance("preview_anim", LLSD(mUUID), TAKE_FOCUS_YES);
+ }
+
+ LLInvFVBridgeAction::doIt();
+}
+
+
+//virtual
+void LLObjectBridgeAction::doIt()
+{
+ LLFloaterReg::showInstance("properties", mUUID);
+
+ LLInvFVBridgeAction::doIt();
+}
+
+
+//virtual
+void LLLSLTextBridgeAction::doIt()
+{
+ LLViewerInventoryItem* item = getItem();
+ if (item)
+ {
+ LLFloaterReg::showInstance("preview_script", LLSD(mUUID), TAKE_FOCUS_YES);
+ }
+
+ LLInvFVBridgeAction::doIt();
+}
+
+
+BOOL LLWearableBridgeAction::isInTrash() const
+{
+ if(!mModel) return FALSE;
+ LLUUID trash_id = mModel->findCategoryUUIDForType(LLAssetType::AT_TRASH);
+ return mModel->isObjectDescendentOf(mUUID, trash_id);
+}
+
+BOOL LLWearableBridgeAction::isAgentInventory() const
+{
+ if(!mModel) return FALSE;
+ if(gInventory.getRootFolderID() == mUUID) return TRUE;
+ return mModel->isObjectDescendentOf(mUUID, gInventory.getRootFolderID());
+}
+
+void LLWearableBridgeAction::wearOnAvatar()
+{
+ // Don't wear anything until initial wearables are loaded, can
+ // destroy clothing items.
+ if (!gAgentWearables.areWearablesLoaded())
+ {
+ LLNotifications::instance().add("CanNotChangeAppearanceUntilLoaded");
+ return;
+ }
+
+ LLViewerInventoryItem* item = getItem();
+ if(item)
+ {
+ if(!isAgentInventory())
+ {
+ LLPointer<LLInventoryCallback> cb = new WearOnAvatarCallback();
+ copy_inventory_item(
+ gAgent.getID(),
+ item->getPermissions().getOwner(),
+ item->getUUID(),
+ LLUUID::null,
+ std::string(),
+ cb);
+ }
+ else
+ {
+ wear_inventory_item_on_avatar(item);
+ }
+ }
+}
+
+//virtual
+void LLWearableBridgeAction::doIt()
+{
+ if( isInTrash() )
+ {
+ LLNotifications::instance().add("CannotWearTrash");
+ }
+ else if(isAgentInventory())
+ {
+ if( !gAgentWearables.isWearingItem( mUUID ) )
+ {
+ wearOnAvatar();
+ }
+ }
+ else
+ {
+ // must be in the inventory library. copy it to our inventory
+ // and put it on right away.
+ LLViewerInventoryItem* item = getItem();
+ if(item && item->isComplete())
+ {
+ LLPointer<LLInventoryCallback> cb = new WearOnAvatarCallback();
+ copy_inventory_item(
+ gAgent.getID(),
+ item->getPermissions().getOwner(),
+ item->getUUID(),
+ LLUUID::null,
+ std::string(),
+ cb);
+ }
+ else if(item)
+ {
+ // *TODO: We should fetch the item details, and then do
+ // the operation above.
+ LLNotifications::instance().add("CannotWearInfoNotComplete");
+ }
+ }
+
+ LLInvFVBridgeAction::doIt();
+}
+
+// +=================================================+
+// | LLLinkItemBridge |
+// +=================================================+
+// For broken links
+
+std::string LLLinkItemBridge::sPrefix("Link: ");
+
+
+LLUIImagePtr LLLinkItemBridge::getIcon() const
+{
+ if (LLViewerInventoryItem *item = getItem())
+ {
+ return get_item_icon(item->getActualType(), LLInventoryType::IT_NONE, 0, FALSE);
+ }
+ return get_item_icon(LLAssetType::AT_LINK, LLInventoryType::IT_NONE, 0, FALSE);
+}
+
+void LLLinkItemBridge::buildContextMenu(LLMenuGL& menu, U32 flags)
+{
+ // *TODO: Translate
+ lldebugs << "LLLink::buildContextMenu()" << llendl;
+ std::vector<std::string> items;
+ std::vector<std::string> disabled_items;
+
+ if(isInTrash())
+ {
+ items.push_back(std::string("Purge Item"));
+ if (!isItemRemovable())
+ {
+ disabled_items.push_back(std::string("Purge Item"));
+ }
+
+ items.push_back(std::string("Restore Item"));
+ }
+ else
+ {
+ items.push_back(std::string("Delete"));
+ if (!isItemRemovable())
+ {
+ disabled_items.push_back(std::string("Delete"));
+ }
+ }
+ hideContextEntries(menu, items, disabled_items);
+}
+
+
+// +=================================================+
+// | LLLinkBridge |
+// +=================================================+
+// For broken links.
+
+std::string LLLinkFolderBridge::sPrefix("Link: ");
+
+
+LLUIImagePtr LLLinkFolderBridge::getIcon() const
+{
+ LLAssetType::EType preferred_type = LLAssetType::AT_NONE;
+ if (LLViewerInventoryItem *item = getItem())
+ {
+ if (const LLViewerInventoryCategory* cat = item->getLinkedCategory())
+ {
+ preferred_type = cat->getPreferredType();
+ }
+ }
+ return LLFolderBridge::getIcon(preferred_type);
+}
+
+void LLLinkFolderBridge::buildContextMenu(LLMenuGL& menu, U32 flags)
+{
+ // *TODO: Translate
+ lldebugs << "LLLink::buildContextMenu()" << llendl;
+ std::vector<std::string> items;
+ std::vector<std::string> disabled_items;
+
+ if(isInTrash())
+ {
+ items.push_back(std::string("Purge Item"));
+ if (!isItemRemovable())
+ {
+ disabled_items.push_back(std::string("Purge Item"));
+ }
+
+ items.push_back(std::string("Restore Item"));
+ }
+ else
+ {
+ items.push_back(std::string("Goto Link"));
+ items.push_back(std::string("Delete"));
+ if (!isItemRemovable())
+ {
+ disabled_items.push_back(std::string("Delete"));
+ }
+ }
+ hideContextEntries(menu, items, disabled_items);
+}
+
+void LLLinkFolderBridge::performAction(LLFolderView* folder, LLInventoryModel* model, std::string action)
+{
+ if ("goto" == action)
+ {
+ gotoItem(folder);
+ return;
+ }
+ LLItemBridge::performAction(folder,model,action);
+}
+
+void LLLinkFolderBridge::gotoItem(LLFolderView *folder)
+{
+ const LLUUID &cat_uuid = getFolderID();
+ if (!cat_uuid.isNull())
+ {
+ if (LLFolderViewItem *base_folder = folder->getItemByID(cat_uuid))
+ {
+ if (LLInventoryModel* model = getInventoryModel())
+ {
+ model->fetchDescendentsOf(cat_uuid);
+ }
+ base_folder->setOpen(TRUE);
+ folder->setSelectionFromRoot(base_folder,TRUE);
+ folder->scrollToShowSelection();
+ }
+ }
+}
+
+const LLUUID &LLLinkFolderBridge::getFolderID() const
+{
+ if (LLViewerInventoryItem *link_item = getItem())
+ {
+ if (const LLViewerInventoryCategory *cat = link_item->getLinkedCategory())
+ {
+ const LLUUID& cat_uuid = cat->getUUID();
+ return cat_uuid;
+ }
+ }
+ return LLUUID::null;
+}
diff --git a/indra/newview/llinventorybridge.h b/indra/newview/llinventorybridge.h
index 526b30f214..25859b7f73 100644
--- a/indra/newview/llinventorybridge.h
+++ b/indra/newview/llinventorybridge.h
@@ -30,10 +30,17 @@
* $/LicenseInfo$
*/
+#ifndef LL_LLINVENTORYBRIDGE_H
+#define LL_LLINVENTORYBRIDGE_H
+
#include "llfloaterproperties.h"
#include "llwearable.h"
#include "llviewercontrol.h"
#include "llcallingcard.h"
+#include "llinventorymodel.h"
+#include "llfoldervieweventlistener.h"
+
+class LLInventoryPanel;
enum EInventoryIcon
{
@@ -64,10 +71,15 @@ enum EInventoryIcon
CLOTHING_UNDERSHIRT_ICON_NAME,
CLOTHING_UNDERPANTS_ICON_NAME,
CLOTHING_SKIRT_ICON_NAME,
+ CLOTHING_ALPHA_ICON_NAME,
+ CLOTHING_TATTOO_ICON_NAME,
ANIMATION_ICON_NAME,
GESTURE_ICON_NAME,
+ LINKITEM_ICON_NAME,
+ LINKFOLDER_ICON_NAME,
+
ICON_NAME_COUNT
};
@@ -93,31 +105,6 @@ struct LLAttachmentRezAction
};
-//helper functions
-class LLShowProps
-{
-public:
-
- static void showProperties(const LLUUID& uuid)
- {
- if(!LLFloaterProperties::show(uuid, LLUUID::null))
- {
- S32 left, top;
- gFloaterView->getNewFloaterPosition(&left, &top);
- LLRect rect = gSavedSettings.getRect("PropertiesRect");
- rect.translate( left - rect.mLeft, top - rect.mTop );
- LLFloaterProperties* floater;
- floater = new LLFloaterProperties("item properties",
- rect,
- "Inventory Item Properties",
- uuid,
- LLUUID::null);
- // keep onscreen
- gFloaterView->adjustToFitScreen(floater, FALSE);
- }
- }
-};
-
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Class LLInventoryPanelObserver
//
@@ -128,7 +115,7 @@ class LLInventoryPanelObserver : public LLInventoryObserver
public:
LLInventoryPanelObserver(LLInventoryPanel* ip) : mIP(ip) {}
virtual ~LLInventoryPanelObserver() {}
- virtual void changed(U32 mask) { mIP->modelChanged(mask); }
+ virtual void changed(U32 mask);
protected:
LLInventoryPanel* mIP;
};
@@ -150,6 +137,7 @@ public:
// This method is a convenience function which creates the correct
// type of bridge based on some basic information
static LLInvFVBridge* createBridge(LLAssetType::EType asset_type,
+ LLAssetType::EType actual_asset_type,
LLInventoryType::EType inv_type,
LLInventoryPanel* inventory,
const LLUUID& uuid,
@@ -158,7 +146,6 @@ public:
virtual const LLUUID& getUUID() const { return mUUID; }
- virtual const std::string& getPrefix() { return LLStringUtil::null; }
virtual void restoreItem() {}
virtual void restoreToWorld() {}
@@ -166,6 +153,7 @@ public:
virtual const std::string& getName() const;
virtual const std::string& getDisplayName() const;
virtual PermissionMask getPermissionMask() const;
+ virtual LLAssetType::EType getPreferredType() const;
virtual time_t getCreationDate() const;
virtual LLFontGL::StyleFlags getLabelStyle() const
{
@@ -173,6 +161,8 @@ public:
}
virtual std::string getLabelSuffix() const { return LLStringUtil::null; }
virtual void openItem() {}
+ virtual void closeItem() {}
+ virtual void gotoItem(LLFolderView *folder) {} // for links
virtual void previewItem() {openItem();}
virtual void showProperties();
virtual BOOL isItemRenameable() const { return TRUE; }
@@ -186,7 +176,9 @@ public:
virtual BOOL copyToClipboard() const { return FALSE; }
virtual void cutToClipboard() {}
virtual BOOL isClipboardPasteable() const;
+ virtual BOOL isClipboardPasteableAsLink() const;
virtual void pasteFromClipboard() {}
+ virtual void pasteLinkFromClipboard() {}
void getClipboardEntries(bool show_asset_id, std::vector<std::string> &items,
std::vector<std::string> &disabled_items, U32 flags);
virtual void buildContextMenu(LLMenuGL& menu, U32 flags);
@@ -200,11 +192,14 @@ public:
virtual void clearDisplayName() {}
protected:
- LLInvFVBridge(LLInventoryPanel* inventory, const LLUUID& uuid) :
- mInventoryPanel(inventory), mUUID(uuid), mInvType(LLInventoryType::IT_NONE) {}
+ LLInvFVBridge(LLInventoryPanel* inventory, const LLUUID& uuid);
LLInventoryObject* getInventoryObject() const;
+ LLInventoryModel* getInventoryModel() const;
+
BOOL isInTrash() const;
+ BOOL isLinkedObjectInTrash() const; // Is this obj or its baseobj in the trash?
+
// return true if the item is in agent inventory. if false, it
// must be lost or in the inventory library.
BOOL isAgentInventory() const;
@@ -218,11 +213,13 @@ protected:
const LLUUID& new_parent,
BOOL restamp);
void removeBatchNoCheck(LLDynamicArray<LLFolderViewEventListener*>& batch);
+ void renameLinkedItems(const LLUUID &item_id, const std::string& new_name);
protected:
- LLInventoryPanel* mInventoryPanel;
- LLUUID mUUID; // item id
+ LLHandle<LLPanel> mInventoryPanel;
+ const LLUUID mUUID; // item id
LLInventoryType::EType mInvType;
+ void purgeItem(LLInventoryModel *model, const LLUUID &uuid);
};
@@ -237,10 +234,12 @@ public:
virtual void selectItem();
virtual void restoreItem();
virtual void restoreToWorld();
+ virtual void gotoItem(LLFolderView *folder);
virtual LLUIImagePtr getIcon() const;
virtual const std::string& getDisplayName() const;
virtual std::string getLabelSuffix() const;
+ virtual LLFontGL::StyleFlags getLabelStyle() const;
virtual PermissionMask getPermissionMask() const;
virtual time_t getCreationDate() const;
virtual BOOL isItemRenameable() const;
@@ -273,15 +272,19 @@ public:
BOOL drop);
virtual void performAction(LLFolderView* folder, LLInventoryModel* model, std::string action);
virtual void openItem();
+ virtual void closeItem();
virtual BOOL isItemRenameable() const;
virtual void selectItem();
virtual void restoreItem();
+ virtual LLAssetType::EType getPreferredType() const;
virtual LLUIImagePtr getIcon() const;
+ static LLUIImagePtr getIcon(LLAssetType::EType asset_type);
+
virtual BOOL renameItem(const std::string& new_name);
virtual BOOL removeItem();
- virtual BOOL isClipboardPasteable() const;
virtual void pasteFromClipboard();
+ virtual void pasteLinkFromClipboard();
virtual void buildContextMenu(LLMenuGL& menu, U32 flags);
virtual BOOL hasChildren() const;
virtual BOOL dragOrDrop(MASK mask, BOOL drop,
@@ -291,7 +294,9 @@ public:
virtual BOOL isItemRemovable();
virtual BOOL isItemMovable();
virtual BOOL isUpToDate() const;
-
+ virtual BOOL isItemCopyable() const;
+ virtual BOOL copyToClipboard() const;
+
static void createWearable(LLFolderBridge* bridge, EWearableType type);
static void createWearable(LLUUID parent_folder_id, EWearableType type);
@@ -322,6 +327,8 @@ protected:
BOOL checkFolderForContentsOfType(LLInventoryModel* model, LLInventoryCollectFunctor& typeToCheck);
void modifyOutfit(BOOL append);
+ void determineFolderType();
+
public:
static LLFolderBridge* sSelf;
static void staticFolderOptionsMenu();
@@ -351,15 +358,12 @@ class LLTextureBridge : public LLItemBridge
{
friend class LLInvFVBridge;
public:
- virtual const std::string& getPrefix() { return sPrefix; }
-
virtual LLUIImagePtr getIcon() const;
virtual void openItem();
protected:
LLTextureBridge(LLInventoryPanel* inventory, const LLUUID& uuid, LLInventoryType::EType type) :
LLItemBridge(inventory, uuid), mInvType(type) {}
- static std::string sPrefix;
LLInventoryType::EType mInvType;
};
@@ -367,8 +371,6 @@ class LLSoundBridge : public LLItemBridge
{
friend class LLInvFVBridge;
public:
- virtual const std::string& getPrefix() { return sPrefix; }
-
virtual LLUIImagePtr getIcon() const;
virtual void openItem();
virtual void previewItem();
@@ -378,33 +380,21 @@ public:
protected:
LLSoundBridge(LLInventoryPanel* inventory, const LLUUID& uuid) :
LLItemBridge(inventory, uuid) {}
- static std::string sPrefix;
};
class LLLandmarkBridge : public LLItemBridge
{
friend class LLInvFVBridge;
public:
- static const std::string& prefix() { return sPrefix; }
- virtual const std::string& getPrefix() { return sPrefix; }
virtual void performAction(LLFolderView* folder, LLInventoryModel* model, std::string action);
virtual void buildContextMenu(LLMenuGL& menu, U32 flags);
virtual LLUIImagePtr getIcon() const;
virtual void openItem();
protected:
- LLLandmarkBridge(LLInventoryPanel* inventory, const LLUUID& uuid, U32 flags = 0x00) :
- LLItemBridge(inventory, uuid)
- {
- mVisited = FALSE;
- if (flags & LLInventoryItem::II_FLAGS_LANDMARK_VISITED)
- {
- mVisited = TRUE;
- }
- }
+ LLLandmarkBridge(LLInventoryPanel* inventory, const LLUUID& uuid, U32 flags = 0x00);
protected:
- static std::string sPrefix;
BOOL mVisited;
};
@@ -425,8 +415,6 @@ class LLCallingCardBridge : public LLItemBridge
{
friend class LLInvFVBridge;
public:
- virtual const std::string& getPrefix() { return sPrefix; }
-
virtual std::string getLabelSuffix() const;
//virtual const std::string& getDisplayName() const;
virtual LLUIImagePtr getIcon() const;
@@ -439,13 +427,13 @@ public:
EDragAndDropType cargo_type,
void* cargo_data);
void refreshFolderViewItem();
+ BOOL removeItem();
protected:
LLCallingCardBridge( LLInventoryPanel* inventory, const LLUUID& uuid );
~LLCallingCardBridge();
protected:
- static std::string sPrefix;
LLCallingCardObserver* mObserver;
};
@@ -454,25 +442,18 @@ class LLNotecardBridge : public LLItemBridge
{
friend class LLInvFVBridge;
public:
- virtual const std::string& getPrefix() { return sPrefix; }
-
virtual LLUIImagePtr getIcon() const;
virtual void openItem();
protected:
LLNotecardBridge(LLInventoryPanel* inventory, const LLUUID& uuid) :
LLItemBridge(inventory, uuid) {}
-
-protected:
- static std::string sPrefix;
};
class LLGestureBridge : public LLItemBridge
{
friend class LLInvFVBridge;
public:
- virtual const std::string& getPrefix() { return sPrefix; }
-
virtual LLUIImagePtr getIcon() const;
// Only suffix for gesture items, not task items, because only
@@ -489,9 +470,6 @@ public:
protected:
LLGestureBridge(LLInventoryPanel* inventory, const LLUUID& uuid)
: LLItemBridge(inventory, uuid) {}
-
-protected:
- static std::string sPrefix;
};
@@ -499,7 +477,6 @@ class LLAnimationBridge : public LLItemBridge
{
friend class LLInvFVBridge;
public:
- virtual const std::string& getPrefix() { return sPrefix; }
virtual void performAction(LLFolderView* folder, LLInventoryModel* model, std::string action);
virtual void buildContextMenu(LLMenuGL& menu, U32 flags);
@@ -509,9 +486,6 @@ public:
protected:
LLAnimationBridge(LLInventoryPanel* inventory, const LLUUID& uuid) :
LLItemBridge(inventory, uuid) {}
-
-protected:
- static std::string sPrefix;
};
@@ -519,8 +493,6 @@ class LLObjectBridge : public LLItemBridge
{
friend class LLInvFVBridge;
public:
- virtual const std::string& getPrefix() { return sPrefix; }
-
virtual LLUIImagePtr getIcon() const;
virtual void performAction(LLFolderView* folder, LLInventoryModel* model, std::string action);
virtual void openItem();
@@ -530,17 +502,12 @@ public:
virtual BOOL isItemRemovable();
virtual BOOL renameItem(const std::string& new_name);
-protected:
- LLObjectBridge(LLInventoryPanel* inventory, const LLUUID& uuid, LLInventoryType::EType type, U32 flags) :
- LLItemBridge(inventory, uuid), mInvType(type)
- {
- mAttachPt = (flags & 0xff); // low bye of inventory flags
+ LLInventoryObject* getObject() const;
- mIsMultiObject = ( flags & LLInventoryItem::II_FLAGS_OBJECT_HAS_MULTIPLE_ITEMS ) ? TRUE: FALSE;
- }
+protected:
+ LLObjectBridge(LLInventoryPanel* inventory, const LLUUID& uuid, LLInventoryType::EType type, U32 flags);
protected:
- static std::string sPrefix;
static LLUUID sContextMenuItemID; // Only valid while the context menu is open.
LLInventoryType::EType mInvType;
U32 mAttachPt;
@@ -552,17 +519,12 @@ class LLLSLTextBridge : public LLItemBridge
{
friend class LLInvFVBridge;
public:
- virtual const std::string& getPrefix() { return sPrefix; }
-
virtual LLUIImagePtr getIcon() const;
virtual void openItem();
protected:
LLLSLTextBridge( LLInventoryPanel* inventory, const LLUUID& uuid ) :
LLItemBridge(inventory, uuid) {}
-
-protected:
- static std::string sPrefix;
};
@@ -574,7 +536,6 @@ public:
virtual void performAction(LLFolderView* folder, LLInventoryModel* model, std::string action);
virtual void openItem();
virtual void buildContextMenu(LLMenuGL& menu, U32 flags);
- virtual LLFontGL::StyleFlags getLabelStyle() const;
virtual std::string getLabelSuffix() const;
virtual BOOL isItemRemovable();
virtual BOOL renameItem(const std::string& new_name);
@@ -584,6 +545,9 @@ public:
static void onWearOnAvatarArrived( LLWearable* wearable, void* userdata );
void wearOnAvatar();
+ static void onWearAddOnAvatarArrived( LLWearable* wearable, void* userdata );
+ void wearAddOnAvatar();
+
static BOOL canEditOnAvatar( void* userdata ); // Access to editOnAvatar() from menu
static void onEditOnAvatar( void* userdata );
void editOnAvatar();
@@ -605,3 +569,222 @@ protected:
LLInventoryType::EType mInvType;
EWearableType mWearableType;
};
+
+class LLLinkItemBridge : public LLItemBridge
+{
+ friend class LLInvFVBridge;
+public:
+ virtual const std::string& getPrefix() { return sPrefix; }
+
+ virtual LLUIImagePtr getIcon() const;
+ virtual void buildContextMenu(LLMenuGL& menu, U32 flags);
+
+protected:
+ LLLinkItemBridge(LLInventoryPanel* inventory, const LLUUID& uuid) :
+ LLItemBridge(inventory, uuid) {}
+
+protected:
+ static std::string sPrefix;
+};
+
+
+class LLLinkFolderBridge : public LLItemBridge
+{
+ friend class LLInvFVBridge;
+public:
+ virtual const std::string& getPrefix() { return sPrefix; }
+
+ virtual LLUIImagePtr getIcon() const;
+ virtual void buildContextMenu(LLMenuGL& menu, U32 flags);
+ virtual void performAction(LLFolderView* folder, LLInventoryModel* model, std::string action);
+ virtual void gotoItem(LLFolderView *folder);
+
+protected:
+ LLLinkFolderBridge(LLInventoryPanel* inventory, const LLUUID& uuid) :
+ LLItemBridge(inventory, uuid) {}
+ const LLUUID &getFolderID() const;
+
+protected:
+ static std::string sPrefix;
+};
+
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+// Class LLInvFVBridgeAction (& its derived classes)
+//
+// This is an implementation class to be able to
+// perform action to view inventory items.
+//
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+class LLInvFVBridgeAction
+{
+public:
+ // This method is a convenience function which creates the correct
+ // type of bridge action based on some basic information
+ static LLInvFVBridgeAction* createAction(LLAssetType::EType asset_type,
+ const LLUUID& uuid,LLInventoryModel* model);
+
+ static void doAction(LLAssetType::EType asset_type,
+ const LLUUID& uuid, LLInventoryModel* model);
+ static void doAction(const LLUUID& uuid, LLInventoryModel* model);
+
+ virtual void doIt() { };
+ virtual ~LLInvFVBridgeAction(){}//need this because of warning on OSX
+protected:
+ LLInvFVBridgeAction(const LLUUID& id,LLInventoryModel* model):mUUID(id),mModel(model){}
+
+ LLViewerInventoryItem* getItem() const;
+protected:
+ const LLUUID& mUUID; // item id
+ LLInventoryModel* mModel;
+
+};
+
+
+
+class LLTextureBridgeAction: public LLInvFVBridgeAction
+{
+ friend class LLInvFVBridgeAction;
+public:
+ virtual void doIt() ;
+ virtual ~LLTextureBridgeAction(){}
+protected:
+ LLTextureBridgeAction(const LLUUID& id,LLInventoryModel* model):LLInvFVBridgeAction(id,model){}
+
+};
+
+
+class LLSoundBridgeAction: public LLInvFVBridgeAction
+{
+ friend class LLInvFVBridgeAction;
+public:
+ virtual void doIt() ;
+ virtual ~LLSoundBridgeAction(){}
+protected:
+ LLSoundBridgeAction(const LLUUID& id,LLInventoryModel* model):LLInvFVBridgeAction(id,model){}
+
+};
+
+
+class LLLandmarkBridgeAction: public LLInvFVBridgeAction
+{
+ friend class LLInvFVBridgeAction;
+public:
+ virtual void doIt() ;
+ virtual ~LLLandmarkBridgeAction(){}
+protected:
+ LLLandmarkBridgeAction(const LLUUID& id,LLInventoryModel* model):LLInvFVBridgeAction(id,model){}
+
+};
+
+
+class LLCallingCardBridgeAction: public LLInvFVBridgeAction
+{
+ friend class LLInvFVBridgeAction;
+public:
+ virtual void doIt() ;
+ virtual ~LLCallingCardBridgeAction(){}
+protected:
+ LLCallingCardBridgeAction(const LLUUID& id,LLInventoryModel* model):LLInvFVBridgeAction(id,model){}
+
+};
+
+
+class LLNotecardBridgeAction: public LLInvFVBridgeAction
+{
+ friend class LLInvFVBridgeAction;
+public:
+ virtual void doIt() ;
+ virtual ~LLNotecardBridgeAction(){}
+protected:
+ LLNotecardBridgeAction(const LLUUID& id,LLInventoryModel* model):LLInvFVBridgeAction(id,model){}
+
+};
+
+
+class LLGestureBridgeAction: public LLInvFVBridgeAction
+{
+ friend class LLInvFVBridgeAction;
+public:
+ virtual void doIt() ;
+ virtual ~LLGestureBridgeAction(){}
+protected:
+ LLGestureBridgeAction(const LLUUID& id,LLInventoryModel* model):LLInvFVBridgeAction(id,model){}
+
+};
+
+
+class LLAnimationBridgeAction: public LLInvFVBridgeAction
+{
+ friend class LLInvFVBridgeAction;
+public:
+ virtual void doIt() ;
+ virtual ~LLAnimationBridgeAction(){}
+protected:
+ LLAnimationBridgeAction(const LLUUID& id,LLInventoryModel* model):LLInvFVBridgeAction(id,model){}
+
+};
+
+
+class LLObjectBridgeAction: public LLInvFVBridgeAction
+{
+ friend class LLInvFVBridgeAction;
+public:
+ virtual void doIt() ;
+ virtual ~LLObjectBridgeAction(){}
+protected:
+ LLObjectBridgeAction(const LLUUID& id,LLInventoryModel* model):LLInvFVBridgeAction(id,model){}
+
+};
+
+
+class LLLSLTextBridgeAction: public LLInvFVBridgeAction
+{
+ friend class LLInvFVBridgeAction;
+public:
+ virtual void doIt() ;
+ virtual ~LLLSLTextBridgeAction(){}
+protected:
+ LLLSLTextBridgeAction(const LLUUID& id,LLInventoryModel* model):LLInvFVBridgeAction(id,model){}
+
+};
+
+
+class LLWearableBridgeAction: public LLInvFVBridgeAction
+{
+ friend class LLInvFVBridgeAction;
+public:
+ virtual void doIt();
+ virtual ~LLWearableBridgeAction(){}
+protected:
+ LLWearableBridgeAction(const LLUUID& id,LLInventoryModel* model):LLInvFVBridgeAction(id,model){}
+
+
+ BOOL isInTrash() const;
+ // return true if the item is in agent inventory. if false, it
+ // must be lost or in the inventory library.
+ BOOL isAgentInventory() const;
+
+ void wearOnAvatar();
+
+};
+
+void wear_inventory_item_on_avatar(LLInventoryItem* item);
+void wear_outfit_by_name(const std::string& name);
+void wear_inventory_category(LLInventoryCategory* category, bool copy, bool append);
+
+class LLViewerJointAttachment;
+void rez_attachment(LLViewerInventoryItem* item, LLViewerJointAttachment* attachment);
+
+// Move items from an in-world object's "Contents" folder to a specified
+// folder in agent inventory.
+BOOL move_inv_category_world_to_agent(const LLUUID& object_id,
+ const LLUUID& category_id,
+ BOOL drop,
+ void (*callback)(S32, void*) = NULL,
+ void* user_data = NULL);
+
+
+
+void teleport_via_landmark(const LLUUID& asset_id);
+
+#endif // LL_LLINVENTORYBRIDGE_H
diff --git a/indra/newview/llinventoryfilter.cpp b/indra/newview/llinventoryfilter.cpp
new file mode 100644
index 0000000000..b4d3f4575b
--- /dev/null
+++ b/indra/newview/llinventoryfilter.cpp
@@ -0,0 +1,664 @@
+/**
+* @file llinventoryfilter.cpp
+* @brief Support for filtering your inventory to only display a subset of the
+* available items.
+*
+* $LicenseInfo:firstyear=2005&license=viewergpl$
+*
+* Copyright (c) 2005-2009, Linden Research, Inc.
+*
+* Second Life Viewer Source Code
+* The source code in this file ("Source Code") is provided by Linden Lab
+* to you under the terms of the GNU General Public License, version 2.0
+* ("GPL"), unless you have obtained a separate licensing agreement
+* ("Other License"), formally executed by you and Linden Lab. Terms of
+* the GPL can be found in doc/GPL-license.txt in this distribution, or
+* online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
+*
+* There are special exceptions to the terms and conditions of the GPL as
+* it is applied to this Source Code. View the full text of the exception
+* in the file doc/FLOSS-exception.txt in this software distribution, or
+* online at
+* http://secondlifegrid.net/programs/open_source/licensing/flossexception
+*
+* By copying, modifying or distributing this software, you acknowledge
+* that you have read and understood your obligations described above,
+* and agree to abide by those obligations.
+*
+* ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+* COMPLETENESS OR PERFORMANCE.
+* $/LicenseInfo$
+*/
+#include "llviewerprecompiledheaders.h"
+
+#include "llinventoryfilter.h"
+
+// viewer includes
+#include "llfoldervieweventlistener.h"
+#include "llfolderviewitem.h"
+#include "llinventorymodel.h" // gInventory.backgroundFetchActive()
+#include "llviewercontrol.h"
+#include "llviewerinventory.h"
+
+// linden library includes
+#include "lltrans.h"
+
+///----------------------------------------------------------------------------
+/// Class LLInventoryFilter
+///----------------------------------------------------------------------------
+LLInventoryFilter::LLInventoryFilter(const std::string& name)
+: mName(name),
+ mModified(FALSE),
+ mNeedTextRebuild(TRUE)
+{
+ mFilterOps.mFilterTypes = 0xffffffffffffffffULL;
+ mFilterOps.mMinDate = time_min();
+ mFilterOps.mMaxDate = time_max();
+ mFilterOps.mHoursAgo = 0;
+ mFilterOps.mShowFolderState = SHOW_NON_EMPTY_FOLDERS;
+ mFilterOps.mPermissions = PERM_NONE;
+ mFilterOps.mFilterForCategories = FALSE;
+
+ mOrder = SO_FOLDERS_BY_NAME; // This gets overridden by a pref immediately
+
+ mSubStringMatchOffset = 0;
+ mFilterSubString.clear();
+ mFilterGeneration = 0;
+ mMustPassGeneration = S32_MAX;
+ mMinRequiredGeneration = 0;
+ mFilterCount = 0;
+ mNextFilterGeneration = mFilterGeneration + 1;
+
+ mLastLogoff = gSavedPerAccountSettings.getU32("LastLogoff");
+ mFilterBehavior = FILTER_NONE;
+
+ // copy mFilterOps into mDefaultFilterOps
+ markDefault();
+}
+
+LLInventoryFilter::~LLInventoryFilter()
+{
+}
+
+BOOL LLInventoryFilter::check(LLFolderViewItem* item)
+{
+ time_t earliest;
+
+ earliest = time_corrected() - mFilterOps.mHoursAgo * 3600;
+ if (mFilterOps.mMinDate > time_min() && mFilterOps.mMinDate < earliest)
+ {
+ earliest = mFilterOps.mMinDate;
+ }
+ else if (!mFilterOps.mHoursAgo)
+ {
+ earliest = 0;
+ }
+ LLFolderViewEventListener* listener = item->getListener();
+ mSubStringMatchOffset = mFilterSubString.size() ? item->getSearchableLabel().find(mFilterSubString) : std::string::npos;
+
+ bool passed_type = false;
+ if (mFilterOps.mFilterForCategories)
+ {
+ if (listener->getInventoryType() == LLInventoryType::IT_CATEGORY)
+ {
+ LLViewerInventoryCategory *cat = gInventory.getCategory(listener->getUUID());
+ if (cat)
+ {
+ passed_type |= ((1LL << cat->getPreferredType() & mFilterOps.mFilterTypes) != U64(0));
+ }
+ }
+ }
+ else
+ {
+ LLInventoryType::EType type = listener->getInventoryType();
+ passed_type |= ((1LL << type & mFilterOps.mFilterTypes) != U64(0));
+ if (type == LLInventoryType::IT_NONE)
+ {
+ const LLInventoryObject *obj = gInventory.getObject(listener->getUUID());
+ if (obj && obj->getIsLinkType())
+ {
+ passed_type = FALSE;
+ }
+ else
+ {
+ passed_type = TRUE;
+ }
+ }
+ }
+
+ BOOL passed = passed_type
+ && (mFilterSubString.size() == 0 || mSubStringMatchOffset != std::string::npos)
+ && ((listener->getPermissionMask() & mFilterOps.mPermissions) == mFilterOps.mPermissions)
+ && (listener->getCreationDate() >= earliest && listener->getCreationDate() <= mFilterOps.mMaxDate);
+ return passed;
+}
+
+const std::string LLInventoryFilter::getFilterSubString(BOOL trim)
+{
+ return mFilterSubString;
+}
+
+std::string::size_type LLInventoryFilter::getStringMatchOffset() const
+{
+ return mSubStringMatchOffset;
+}
+
+// has user modified default filter params?
+BOOL LLInventoryFilter::isNotDefault()
+{
+ return mFilterOps.mFilterTypes != mDefaultFilterOps.mFilterTypes
+ || mFilterSubString.size()
+ || mFilterOps.mPermissions != mDefaultFilterOps.mPermissions
+ || mFilterOps.mMinDate != mDefaultFilterOps.mMinDate
+ || mFilterOps.mMaxDate != mDefaultFilterOps.mMaxDate
+ || mFilterOps.mHoursAgo != mDefaultFilterOps.mHoursAgo;
+}
+
+BOOL LLInventoryFilter::isActive()
+{
+ return mFilterOps.mFilterTypes != 0xffffffffffffffffULL
+ || mFilterSubString.size()
+ || mFilterOps.mPermissions != PERM_NONE
+ || mFilterOps.mMinDate != time_min()
+ || mFilterOps.mMaxDate != time_max()
+ || mFilterOps.mHoursAgo != 0;
+}
+
+BOOL LLInventoryFilter::isModified()
+{
+ return mModified;
+}
+
+BOOL LLInventoryFilter::isModifiedAndClear()
+{
+ BOOL ret = mModified;
+ mModified = FALSE;
+ return ret;
+}
+
+void LLInventoryFilter::setFilterTypes(U64 types, BOOL filter_for_categories)
+{
+ if (mFilterOps.mFilterTypes != types)
+ {
+ // keep current items only if no type bits getting turned off
+ BOOL fewer_bits_set = (mFilterOps.mFilterTypes & ~types);
+ BOOL more_bits_set = (~mFilterOps.mFilterTypes & types);
+
+ mFilterOps.mFilterTypes = types;
+ if (more_bits_set && fewer_bits_set)
+ {
+ // neither less or more restrive, both simultaneously
+ // so we need to filter from scratch
+ setModified(FILTER_RESTART);
+ }
+ else if (more_bits_set)
+ {
+ // target is only one of all requested types so more type bits == less restrictive
+ setModified(FILTER_LESS_RESTRICTIVE);
+ }
+ else if (fewer_bits_set)
+ {
+ setModified(FILTER_MORE_RESTRICTIVE);
+ }
+ }
+ mFilterOps.mFilterForCategories = filter_for_categories;
+}
+
+void LLInventoryFilter::setFilterSubString(const std::string& string)
+{
+ if (mFilterSubString != string)
+ {
+ // hitting BACKSPACE, for example
+ BOOL less_restrictive = mFilterSubString.size() >= string.size() && !mFilterSubString.substr(0, string.size()).compare(string);
+ // appending new characters
+ BOOL more_restrictive = mFilterSubString.size() < string.size() && !string.substr(0, mFilterSubString.size()).compare(mFilterSubString);
+ mFilterSubString = string;
+ LLStringUtil::toUpper(mFilterSubString);
+ LLStringUtil::trimHead(mFilterSubString);
+
+ if (less_restrictive)
+ {
+ setModified(FILTER_LESS_RESTRICTIVE);
+ }
+ else if (more_restrictive)
+ {
+ setModified(FILTER_MORE_RESTRICTIVE);
+ }
+ else
+ {
+ setModified(FILTER_RESTART);
+ }
+ }
+}
+
+void LLInventoryFilter::setFilterPermissions(PermissionMask perms)
+{
+ if (mFilterOps.mPermissions != perms)
+ {
+ // keep current items only if no perm bits getting turned off
+ BOOL fewer_bits_set = (mFilterOps.mPermissions & ~perms);
+ BOOL more_bits_set = (~mFilterOps.mPermissions & perms);
+ mFilterOps.mPermissions = perms;
+
+ if (more_bits_set && fewer_bits_set)
+ {
+ setModified(FILTER_RESTART);
+ }
+ else if (more_bits_set)
+ {
+ // target must have all requested permission bits, so more bits == more restrictive
+ setModified(FILTER_MORE_RESTRICTIVE);
+ }
+ else if (fewer_bits_set)
+ {
+ setModified(FILTER_LESS_RESTRICTIVE);
+ }
+ }
+}
+
+void LLInventoryFilter::setDateRange(time_t min_date, time_t max_date)
+{
+ mFilterOps.mHoursAgo = 0;
+ if (mFilterOps.mMinDate != min_date)
+ {
+ mFilterOps.mMinDate = min_date;
+ setModified();
+ }
+ if (mFilterOps.mMaxDate != llmax(mFilterOps.mMinDate, max_date))
+ {
+ mFilterOps.mMaxDate = llmax(mFilterOps.mMinDate, max_date);
+ setModified();
+ }
+}
+
+void LLInventoryFilter::setDateRangeLastLogoff(BOOL sl)
+{
+ if (sl && !isSinceLogoff())
+ {
+ setDateRange(mLastLogoff, time_max());
+ setModified();
+ }
+ if (!sl && isSinceLogoff())
+ {
+ setDateRange(0, time_max());
+ setModified();
+ }
+}
+
+BOOL LLInventoryFilter::isSinceLogoff()
+{
+ return (mFilterOps.mMinDate == (time_t)mLastLogoff) &&
+ (mFilterOps.mMaxDate == time_max());
+}
+
+void LLInventoryFilter::setHoursAgo(U32 hours)
+{
+ if (mFilterOps.mHoursAgo != hours)
+ {
+ // *NOTE: need to cache last filter time, in case filter goes stale
+ BOOL less_restrictive = (mFilterOps.mMinDate == time_min() && mFilterOps.mMaxDate == time_max() && hours > mFilterOps.mHoursAgo);
+ BOOL more_restrictive = (mFilterOps.mMinDate == time_min() && mFilterOps.mMaxDate == time_max() && hours <= mFilterOps.mHoursAgo);
+ mFilterOps.mHoursAgo = hours;
+ mFilterOps.mMinDate = time_min();
+ mFilterOps.mMaxDate = time_max();
+ if (less_restrictive)
+ {
+ setModified(FILTER_LESS_RESTRICTIVE);
+ }
+ else if (more_restrictive)
+ {
+ setModified(FILTER_MORE_RESTRICTIVE);
+ }
+ else
+ {
+ setModified(FILTER_RESTART);
+ }
+ }
+}
+void LLInventoryFilter::setShowFolderState(EFolderShow state)
+{
+ if (mFilterOps.mShowFolderState != state)
+ {
+ mFilterOps.mShowFolderState = state;
+ if (state == SHOW_NON_EMPTY_FOLDERS)
+ {
+ // showing fewer folders than before
+ setModified(FILTER_MORE_RESTRICTIVE);
+ }
+ else if (state == SHOW_ALL_FOLDERS)
+ {
+ // showing same folders as before and then some
+ setModified(FILTER_LESS_RESTRICTIVE);
+ }
+ else
+ {
+ setModified();
+ }
+ }
+}
+
+void LLInventoryFilter::setSortOrder(U32 order)
+{
+ if (mOrder != order)
+ {
+ mOrder = order;
+ setModified();
+ }
+}
+
+void LLInventoryFilter::markDefault()
+{
+ mDefaultFilterOps = mFilterOps;
+}
+
+void LLInventoryFilter::resetDefault()
+{
+ mFilterOps = mDefaultFilterOps;
+ setModified();
+}
+
+void LLInventoryFilter::setModified(EFilterBehavior behavior)
+{
+ mModified = TRUE;
+ mNeedTextRebuild = TRUE;
+ mFilterGeneration = mNextFilterGeneration++;
+
+ if (mFilterBehavior == FILTER_NONE)
+ {
+ mFilterBehavior = behavior;
+ }
+ else if (mFilterBehavior != behavior)
+ {
+ // trying to do both less restrictive and more restrictive filter
+ // basically means restart from scratch
+ mFilterBehavior = FILTER_RESTART;
+ }
+
+ if (isNotDefault())
+ {
+ // if not keeping current filter results, update last valid as well
+ switch(mFilterBehavior)
+ {
+ case FILTER_RESTART:
+ mMustPassGeneration = mFilterGeneration;
+ mMinRequiredGeneration = mFilterGeneration;
+ break;
+ case FILTER_LESS_RESTRICTIVE:
+ mMustPassGeneration = mFilterGeneration;
+ break;
+ case FILTER_MORE_RESTRICTIVE:
+ mMinRequiredGeneration = mFilterGeneration;
+ // must have passed either current filter generation (meaningless, as it hasn't been run yet)
+ // or some older generation, so keep the value
+ mMustPassGeneration = llmin(mMustPassGeneration, mFilterGeneration);
+ break;
+ default:
+ llerrs << "Bad filter behavior specified" << llendl;
+ }
+ }
+ else
+ {
+ // shortcut disabled filters to show everything immediately
+ mMinRequiredGeneration = 0;
+ mMustPassGeneration = S32_MAX;
+ }
+}
+
+BOOL LLInventoryFilter::isFilterWith(LLInventoryType::EType t)
+{
+ return mFilterOps.mFilterTypes & (1LL << t);
+}
+
+std::string LLInventoryFilter::getFilterText()
+{
+ if (!mNeedTextRebuild)
+ {
+ return mFilterText;
+ }
+
+ mNeedTextRebuild = FALSE;
+ std::string filtered_types;
+ std::string not_filtered_types;
+ BOOL filtered_by_type = FALSE;
+ BOOL filtered_by_all_types = TRUE;
+ S32 num_filter_types = 0;
+ mFilterText.clear();
+
+ if (isFilterWith(LLInventoryType::IT_ANIMATION))
+ {
+ //filtered_types += " Animations,";
+ filtered_types += LLTrans::getString("Animations");
+ filtered_by_type = TRUE;
+ num_filter_types++;
+ }
+ else
+ {
+ //not_filtered_types += " Animations,";
+ not_filtered_types += LLTrans::getString("Animations");
+
+ filtered_by_all_types = FALSE;
+ }
+
+ if (isFilterWith(LLInventoryType::IT_CALLINGCARD))
+ {
+ //filtered_types += " Calling Cards,";
+ filtered_types += LLTrans::getString("Calling Cards");
+ filtered_by_type = TRUE;
+ num_filter_types++;
+ }
+ else
+ {
+ //not_filtered_types += " Calling Cards,";
+ not_filtered_types += LLTrans::getString("Calling Cards");
+ filtered_by_all_types = FALSE;
+ }
+
+ if (isFilterWith(LLInventoryType::IT_WEARABLE))
+ {
+ //filtered_types += " Clothing,";
+ filtered_types += LLTrans::getString("Clothing");
+ filtered_by_type = TRUE;
+ num_filter_types++;
+ }
+ else
+ {
+ //not_filtered_types += " Clothing,";
+ not_filtered_types += LLTrans::getString("Clothing");
+ filtered_by_all_types = FALSE;
+ }
+
+ if (isFilterWith(LLInventoryType::IT_GESTURE))
+ {
+ //filtered_types += " Gestures,";
+ filtered_types += LLTrans::getString("Gestures");
+ filtered_by_type = TRUE;
+ num_filter_types++;
+ }
+ else
+ {
+ //not_filtered_types += " Gestures,";
+ not_filtered_types += LLTrans::getString("Gestures");
+ filtered_by_all_types = FALSE;
+ }
+
+ if (isFilterWith(LLInventoryType::IT_LANDMARK))
+ {
+ //filtered_types += " Landmarks,";
+ filtered_types += LLTrans::getString("Landmarks");
+ filtered_by_type = TRUE;
+ num_filter_types++;
+ }
+ else
+ {
+ //not_filtered_types += " Landmarks,";
+ not_filtered_types += LLTrans::getString("Landmarks");
+ filtered_by_all_types = FALSE;
+ }
+
+ if (isFilterWith(LLInventoryType::IT_NOTECARD))
+ {
+ //filtered_types += " Notecards,";
+ filtered_types += LLTrans::getString("Notecards");
+ filtered_by_type = TRUE;
+ num_filter_types++;
+ }
+ else
+ {
+ //not_filtered_types += " Notecards,";
+ not_filtered_types += LLTrans::getString("Notecards");
+ filtered_by_all_types = FALSE;
+ }
+
+ if (isFilterWith(LLInventoryType::IT_OBJECT) && isFilterWith(LLInventoryType::IT_ATTACHMENT))
+ {
+ //filtered_types += " Objects,";
+ filtered_types += LLTrans::getString("Objects");
+ filtered_by_type = TRUE;
+ num_filter_types++;
+ }
+ else
+ {
+ //not_filtered_types += " Objects,";
+ not_filtered_types += LLTrans::getString("Objects");
+ filtered_by_all_types = FALSE;
+ }
+
+ if (isFilterWith(LLInventoryType::IT_LSL))
+ {
+ //filtered_types += " Scripts,";
+ filtered_types += LLTrans::getString("Scripts");
+ filtered_by_type = TRUE;
+ num_filter_types++;
+ }
+ else
+ {
+ //not_filtered_types += " Scripts,";
+ not_filtered_types += LLTrans::getString("Scripts");
+ filtered_by_all_types = FALSE;
+ }
+
+ if (isFilterWith(LLInventoryType::IT_SOUND))
+ {
+ //filtered_types += " Sounds,";
+ filtered_types += LLTrans::getString("Sounds");
+ filtered_by_type = TRUE;
+ num_filter_types++;
+ }
+ else
+ {
+ //not_filtered_types += " Sounds,";
+ not_filtered_types += LLTrans::getString("Sounds");
+ filtered_by_all_types = FALSE;
+ }
+
+ if (isFilterWith(LLInventoryType::IT_TEXTURE))
+ {
+ //filtered_types += " Textures,";
+ filtered_types += LLTrans::getString("Textures");
+ filtered_by_type = TRUE;
+ num_filter_types++;
+ }
+ else
+ {
+ //not_filtered_types += " Textures,";
+ not_filtered_types += LLTrans::getString("Textures");
+ filtered_by_all_types = FALSE;
+ }
+
+ if (isFilterWith(LLInventoryType::IT_SNAPSHOT))
+ {
+ //filtered_types += " Snapshots,";
+ filtered_types += LLTrans::getString("Snapshots");
+ filtered_by_type = TRUE;
+ num_filter_types++;
+ }
+ else
+ {
+ //not_filtered_types += " Snapshots,";
+ not_filtered_types += LLTrans::getString("Snapshots");
+ filtered_by_all_types = FALSE;
+ }
+
+ if (!gInventory.backgroundFetchActive()
+ && filtered_by_type
+ && !filtered_by_all_types)
+ {
+ mFilterText += " - ";
+ if (num_filter_types < 5)
+ {
+ mFilterText += filtered_types;
+ }
+ else
+ {
+ //mFilterText += "No ";
+ mFilterText += LLTrans::getString("No Filters");
+ mFilterText += not_filtered_types;
+ }
+ // remove the ',' at the end
+ mFilterText.erase(mFilterText.size() - 1, 1);
+ }
+
+ if (isSinceLogoff())
+ {
+ //mFilterText += " - Since Logoff";
+ mFilterText += LLTrans::getString("Since Logoff");
+ }
+ return mFilterText;
+}
+
+void LLInventoryFilter::toLLSD(LLSD& data)
+{
+ data["filter_types"] = (LLSD::Integer)getFilterTypes();
+ data["min_date"] = (LLSD::Integer)getMinDate();
+ data["max_date"] = (LLSD::Integer)getMaxDate();
+ data["hours_ago"] = (LLSD::Integer)getHoursAgo();
+ data["show_folder_state"] = (LLSD::Integer)getShowFolderState();
+ data["permissions"] = (LLSD::Integer)getFilterPermissions();
+ data["substring"] = (LLSD::String)getFilterSubString();
+ data["sort_order"] = (LLSD::Integer)getSortOrder();
+ data["since_logoff"] = (LLSD::Boolean)isSinceLogoff();
+}
+
+void LLInventoryFilter::fromLLSD(LLSD& data)
+{
+ if(data.has("filter_types"))
+ {
+ setFilterTypes((U32)data["filter_types"].asInteger());
+ }
+
+ if(data.has("min_date") && data.has("max_date"))
+ {
+ setDateRange(data["min_date"].asInteger(), data["max_date"].asInteger());
+ }
+
+ if(data.has("hours_ago"))
+ {
+ setHoursAgo((U32)data["hours_ago"].asInteger());
+ }
+
+ if(data.has("show_folder_state"))
+ {
+ setShowFolderState((EFolderShow)data["show_folder_state"].asInteger());
+ }
+
+ if(data.has("permissions"))
+ {
+ setFilterPermissions((PermissionMask)data["permissions"].asInteger());
+ }
+
+ if(data.has("substring"))
+ {
+ setFilterSubString(std::string(data["substring"].asString()));
+ }
+
+ if(data.has("sort_order"))
+ {
+ setSortOrder((U32)data["sort_order"].asInteger());
+ }
+
+ if(data.has("since_logoff"))
+ {
+ setDateRangeLastLogoff((bool)data["since_logoff"].asBoolean());
+ }
+}
diff --git a/indra/newview/llinventoryfilter.h b/indra/newview/llinventoryfilter.h
new file mode 100644
index 0000000000..670b1f000b
--- /dev/null
+++ b/indra/newview/llinventoryfilter.h
@@ -0,0 +1,151 @@
+/**
+* @file llinventoryfilter.h
+* @brief Support for filtering your inventory to only display a subset of the
+* available items.
+*
+* $LicenseInfo:firstyear=2005&license=viewergpl$
+*
+* Copyright (c) 2005-2009, Linden Research, Inc.
+*
+* Second Life Viewer Source Code
+* The source code in this file ("Source Code") is provided by Linden Lab
+* to you under the terms of the GNU General Public License, version 2.0
+* ("GPL"), unless you have obtained a separate licensing agreement
+* ("Other License"), formally executed by you and Linden Lab. Terms of
+* the GPL can be found in doc/GPL-license.txt in this distribution, or
+* online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
+*
+* There are special exceptions to the terms and conditions of the GPL as
+* it is applied to this Source Code. View the full text of the exception
+* in the file doc/FLOSS-exception.txt in this software distribution, or
+* online at
+* http://secondlifegrid.net/programs/open_source/licensing/flossexception
+*
+* By copying, modifying or distributing this software, you acknowledge
+* that you have read and understood your obligations described above,
+* and agree to abide by those obligations.
+*
+* ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+* COMPLETENESS OR PERFORMANCE.
+* $/LicenseInfo$
+*/
+#ifndef LLINVENTORYFILTER_H
+#define LLINVENTORYFILTER_H
+
+// lots of includes here
+#include "llinventorytype.h"
+#include "llpermissionsflags.h" // PermissionsMask
+
+class LLFolderViewItem;
+
+class LLInventoryFilter
+{
+public:
+ typedef enum e_folder_show
+ {
+ SHOW_ALL_FOLDERS,
+ SHOW_NON_EMPTY_FOLDERS,
+ SHOW_NO_FOLDERS
+ } EFolderShow;
+
+ typedef enum e_filter_behavior
+ {
+ FILTER_NONE, // nothing to do, already filtered
+ FILTER_RESTART, // restart filtering from scratch
+ FILTER_LESS_RESTRICTIVE, // existing filtered items will certainly pass this filter
+ FILTER_MORE_RESTRICTIVE // if you didn't pass the previous filter, you definitely won't pass this one
+ } EFilterBehavior;
+
+ static const U32 SO_DATE = 1;
+ static const U32 SO_FOLDERS_BY_NAME = 2;
+ static const U32 SO_SYSTEM_FOLDERS_TO_TOP = 4;
+
+ LLInventoryFilter(const std::string& name);
+ virtual ~LLInventoryFilter();
+
+ void setFilterTypes(U64 types, BOOL filter_for_categories = FALSE); // if filter_for_categories is true, operate on folder preferred asset type
+ U32 getFilterTypes() const { return mFilterOps.mFilterTypes; }
+
+ void setFilterSubString(const std::string& string);
+ const std::string getFilterSubString(BOOL trim = FALSE);
+
+ void setFilterPermissions(PermissionMask perms);
+ PermissionMask getFilterPermissions() const { return mFilterOps.mPermissions; }
+
+ void setDateRange(time_t min_date, time_t max_date);
+ void setDateRangeLastLogoff(BOOL sl);
+ time_t getMinDate() const { return mFilterOps.mMinDate; }
+ time_t getMaxDate() const { return mFilterOps.mMaxDate; }
+
+ void setHoursAgo(U32 hours);
+ U32 getHoursAgo() const { return mFilterOps.mHoursAgo; }
+
+ void setShowFolderState( EFolderShow state);
+ EFolderShow getShowFolderState() { return mFilterOps.mShowFolderState; }
+
+ void setSortOrder(U32 order);
+ U32 getSortOrder() { return mOrder; }
+
+ BOOL check(LLFolderViewItem* item);
+ std::string::size_type getStringMatchOffset() const;
+ BOOL isActive();
+ BOOL isNotDefault();
+ BOOL isModified();
+ BOOL isModifiedAndClear();
+ BOOL isSinceLogoff();
+ void clearModified() { mModified = FALSE; mFilterBehavior = FILTER_NONE; }
+ const std::string getName() const { return mName; }
+ std::string getFilterText();
+
+ void setFilterCount(S32 count) { mFilterCount = count; }
+ S32 getFilterCount() { return mFilterCount; }
+ void decrementFilterCount() { mFilterCount--; }
+
+ void markDefault();
+ void resetDefault();
+
+ BOOL isFilterWith(LLInventoryType::EType t);
+
+ S32 getCurrentGeneration() const { return mFilterGeneration; }
+ S32 getMinRequiredGeneration() const { return mMinRequiredGeneration; }
+ S32 getMustPassGeneration() const { return mMustPassGeneration; }
+
+ //RN: this is public to allow system to externally force a global refilter
+ void setModified(EFilterBehavior behavior = FILTER_RESTART);
+
+ void toLLSD(LLSD& data);
+ void fromLLSD(LLSD& data);
+
+protected:
+ struct filter_ops
+ {
+ U64 mFilterTypes;
+ BOOL mFilterForCategories;
+ time_t mMinDate;
+ time_t mMaxDate;
+ U32 mHoursAgo;
+ EFolderShow mShowFolderState;
+ PermissionMask mPermissions;
+ };
+ filter_ops mFilterOps;
+ filter_ops mDefaultFilterOps;
+ std::string::size_type mSubStringMatchOffset;
+ std::string mFilterSubString;
+ U32 mOrder;
+ const std::string mName;
+ S32 mFilterGeneration;
+ S32 mMustPassGeneration;
+ S32 mMinRequiredGeneration;
+ S32 mFilterCount;
+ S32 mNextFilterGeneration;
+ EFilterBehavior mFilterBehavior;
+
+private:
+ U32 mLastLogoff;
+ BOOL mModified;
+ BOOL mNeedTextRebuild;
+ std::string mFilterText;
+};
+
+#endif
diff --git a/indra/newview/llinventorymodel.cpp b/indra/newview/llinventorymodel.cpp
index f98a3f9ee5..aadda3fbfd 100644
--- a/indra/newview/llinventorymodel.cpp
+++ b/indra/newview/llinventorymodel.cpp
@@ -42,9 +42,11 @@
#include "message.h"
#include "llagent.h"
+#include "llagentwearables.h"
#include "llfloater.h"
#include "llfocusmgr.h"
-#include "llinventoryview.h"
+#include "llinventorybridge.h"
+#include "llfloaterinventory.h"
#include "llviewerinventory.h"
#include "llviewermessage.h"
#include "llviewerwindow.h"
@@ -53,11 +55,11 @@
#include "lldbstrings.h"
#include "llviewerstats.h"
#include "llmutelist.h"
-#include "llnotify.h"
+#include "llnotifications.h"
#include "llcallbacklist.h"
#include "llpreview.h"
#include "llviewercontrol.h"
-#include "llvoavatar.h"
+#include "llvoavatarself.h"
#include "llsdutil.h"
#include <deque>
@@ -87,33 +89,6 @@ static std::deque<LLUUID> sFetchQueue;
const F32 MAX_TIME_FOR_SINGLE_FETCH = 10.f;
const S32 MAX_FETCH_RETRIES = 10;
const char CACHE_FORMAT_STRING[] = "%s.inv";
-const char* NEW_CATEGORY_NAME = "New Folder";
-const char* NEW_CATEGORY_NAMES[LLAssetType::AT_COUNT] =
-{
- "Textures", // AT_TEXTURE
- "Sounds", // AT_SOUND
- "Calling Cards", // AT_CALLINGCARD
- "Landmarks", // AT_LANDMARK
- "Scripts", // AT_SCRIPT (deprecated?)
- "Clothing", // AT_CLOTHING
- "Objects", // AT_OBJECT
- "Notecards", // AT_NOTECARD
- "New Folder", // AT_CATEGORY
- "Inventory", // AT_ROOT_CATEGORY
- "Scripts", // AT_LSL_TEXT
- "Scripts", // AT_LSL_BYTECODE
- "Uncompressed Images", // AT_TEXTURE_TGA
- "Body Parts", // AT_BODYPART
- "Trash", // AT_TRASH
- "Photo Album", // AT_SNAPSHOT_CATEGORY
- "Lost And Found", // AT_LOST_AND_FOUND
- "Uncompressed Sounds", // AT_SOUND_WAV
- "Uncompressed Images", // AT_IMAGE_TGA
- "Uncompressed Images", // AT_IMAGE_JPEG
- "Animations", // AT_ANIMATION
- "Gestures", // AT_GESTURE
- "New Folder" // AT_SIMSTATE
-};
struct InventoryIDPtrLess
{
@@ -180,9 +155,20 @@ bool LLCanCache::operator()(LLInventoryCategory* cat, LLInventoryItem* item)
LLInventoryModel gInventory;
// Default constructor
-LLInventoryModel::LLInventoryModel() :
- mModifyMask(LLInventoryObserver::ALL),
+LLInventoryModel::LLInventoryModel()
+: mModifyMask(LLInventoryObserver::ALL),
+ mChangedItemIDs(),
+ mCategoryMap(),
+ mItemMap(),
+ mCategoryLock(),
+ mItemLock(),
mLastItem(NULL),
+ mParentChildCategoryTree(),
+ mParentChildItemTree(),
+ mObservers(),
+ mRootFolderID(),
+ mLibraryRootFolderID(),
+ mLibraryOwnerID(),
mIsAgentInvUsable(false)
{
}
@@ -324,7 +310,7 @@ LLUUID LLInventoryModel::findCategoryUUIDForType(LLAssetType::EType t, bool crea
LLUUID rv = findCatUUID(t);
if(rv.isNull() && isInventoryUsable() && create_folder)
{
- LLUUID root_id = gAgent.getInventoryRootID();
+ LLUUID root_id = gInventory.getRootFolderID();
if(root_id.notNull())
{
rv = createNewCategory(root_id, t, LLStringUtil::null);
@@ -337,7 +323,7 @@ LLUUID LLInventoryModel::findCategoryUUIDForType(LLAssetType::EType t, bool crea
// preferred type. Returns LLUUID::null if not found.
LLUUID LLInventoryModel::findCatUUID(LLAssetType::EType preferred_type)
{
- LLUUID root_id = gAgent.getInventoryRootID();
+ LLUUID root_id = gInventory.getRootFolderID();
if(LLAssetType::AT_CATEGORY == preferred_type)
{
return root_id;
@@ -388,14 +374,9 @@ LLUUID LLInventoryModel::createNewCategory(const LLUUID& parent_id,
{
name.assign(pname);
}
- else if((preferred_type >= LLAssetType::AT_TEXTURE) &&
- (preferred_type < LLAssetType::AT_SIMSTATE))
- {
- name.assign(NEW_CATEGORY_NAMES[preferred_type]);
- }
else
{
- name.assign(NEW_CATEGORY_NAME);
+ name.assign(LLAssetType::lookupCategoryName(preferred_type));
}
// Add the category to the internal representation
@@ -453,7 +434,8 @@ void LLInventoryModel::collectDescendentsIf(const LLUUID& id,
cat_array_t& cats,
item_array_t& items,
BOOL include_trash,
- LLInventoryCollectFunctor& add)
+ LLInventoryCollectFunctor& add,
+ BOOL follow_folder_links)
{
// Start with categories
if(!include_trash)
@@ -477,9 +459,38 @@ void LLInventoryModel::collectDescendentsIf(const LLUUID& id,
}
}
- // Move onto items
LLViewerInventoryItem* item = NULL;
item_array_t* item_array = get_ptr_in_map(mParentChildItemTree, id);
+
+ // Follow folder links recursively. Currently never goes more
+ // than one level deep (for current outfit support)
+ // Note: if making it fully recursive, need more checking against infinite loops.
+ if (follow_folder_links && item_array)
+ {
+ S32 count = item_array->count();
+ for(S32 i = 0; i < count; ++i)
+ {
+ item = item_array->get(i);
+ if (item->getActualType() == LLAssetType::AT_LINK_FOLDER)
+ {
+ // BAP either getLinkedCategory() should return non-const, or the functor should take const.
+ LLViewerInventoryCategory *linked_cat = const_cast<LLViewerInventoryCategory*>(item->getLinkedCategory());
+ if (linked_cat)
+ {
+ if(add(linked_cat,NULL))
+ {
+ // BAP should this be added here? May not
+ // matter if it's only being used in current
+ // outfit traversal.
+ cats.put(LLPointer<LLViewerInventoryCategory>(linked_cat));
+ }
+ collectDescendentsIf(linked_cat->getUUID(), cats, items, include_trash, add, FALSE);
+ }
+ }
+ }
+ }
+
+ // Move onto items
if(item_array)
{
S32 count = item_array->count();
@@ -494,6 +505,47 @@ void LLInventoryModel::collectDescendentsIf(const LLUUID& id,
}
}
+void LLInventoryModel::updateLinkedObjects(const LLUUID& object_id)
+{
+ LLInventoryModel::cat_array_t cat_array;
+ LLInventoryModel::item_array_t item_array;
+ LLLinkedItemIDMatches is_linked_item_match(object_id);
+ collectDescendentsIf(gInventory.getRootFolderID(),
+ cat_array,
+ item_array,
+ LLInventoryModel::INCLUDE_TRASH,
+ is_linked_item_match);
+
+ for (LLInventoryModel::cat_array_t::iterator cat_iter = cat_array.begin();
+ cat_iter != cat_array.end();
+ cat_iter++)
+ {
+ LLViewerInventoryCategory *linked_cat = (*cat_iter);
+ addChangedMask(LLInventoryObserver::LABEL, linked_cat->getUUID());
+ };
+
+ for (LLInventoryModel::item_array_t::iterator iter = item_array.begin();
+ iter != item_array.end();
+ iter++)
+ {
+ LLViewerInventoryItem *linked_item = (*iter);
+ addChangedMask(LLInventoryObserver::LABEL, linked_item->getUUID());
+ };
+ notifyObservers();
+}
+
+void LLInventoryModel::collectLinkedItems(const LLUUID& id,
+ item_array_t& items)
+{
+ LLInventoryModel::cat_array_t cat_array;
+ LLLinkedItemIDMatches is_linked_item_match(id);
+ collectDescendentsIf(gInventory.getRootFolderID(),
+ cat_array,
+ items,
+ LLInventoryModel::INCLUDE_TRASH,
+ is_linked_item_match);
+}
+
// Generates a string containing the path to the item specified by
// item_id.
void LLInventoryModel::appendPath(const LLUUID& id, std::string& path)
@@ -518,7 +570,7 @@ void LLInventoryModel::appendPath(const LLUUID& id, std::string& path)
bool LLInventoryModel::isInventoryUsable()
{
bool result = false;
- if(gAgent.getInventoryRootID().notNull() && mIsAgentInvUsable)
+ if(gInventory.getRootFolderID().notNull() && mIsAgentInvUsable)
{
result = true;
}
@@ -543,9 +595,11 @@ U32 LLInventoryModel::updateItem(const LLViewerInventoryItem* item)
}
LLViewerInventoryItem* old_item = getItem(item->getUUID());
+ LLPointer<LLViewerInventoryItem> new_item;
if(old_item)
{
- // We already have an old item, modify it's values
+ // We already have an old item, modify its values
+ new_item = old_item;
LLUUID old_parent_id = old_item->getParentUUID();
LLUUID new_parent_id = item->getParentUUID();
if(old_parent_id != new_parent_id)
@@ -574,7 +628,7 @@ U32 LLInventoryModel::updateItem(const LLViewerInventoryItem* item)
else
{
// Simply add this item
- LLPointer<LLViewerInventoryItem> new_item = new LLViewerInventoryItem(item);
+ new_item = new LLViewerInventoryItem(item);
addItem(new_item);
if(item->getParentUUID().isNull())
@@ -634,11 +688,24 @@ U32 LLInventoryModel::updateItem(const LLViewerInventoryItem* item)
}
mask |= LLInventoryObserver::ADD;
}
- if(item->getType() == LLAssetType::AT_CALLINGCARD)
+ if(new_item->getType() == LLAssetType::AT_CALLINGCARD)
{
mask |= LLInventoryObserver::CALLING_CARD;
+ // Handle user created calling cards.
+ // Target ID is stored in the description field of the card.
+ LLUUID id;
+ std::string desc = new_item->getDescription();
+ BOOL isId = desc.empty() ? FALSE : id.set(desc, FALSE);
+ if (isId)
+ {
+ // Valid UUID; set the item UUID and rename it
+ new_item->setCreator(id);
+ std::string avatar_name;
+ // Fetch the currect name
+ gCacheName->get(id, FALSE, boost::bind(&LLViewerInventoryItem::onCallingCardNameLookup, new_item.get(), _1, _2, _3));
+ }
}
- addChangedMask(mask, item->getUUID());
+ addChangedMask(mask, new_item->getUUID());
return mask;
}
@@ -777,6 +844,7 @@ void LLInventoryModel::moveObject(const LLUUID& object_id, const LLUUID& cat_id)
// Delete a particular inventory object by ID.
void LLInventoryModel::deleteObject(const LLUUID& id)
{
+ purgeLinkedObjects(id);
lldebugs << "LLInventoryModel::deleteObject()" << llendl;
LLPointer<LLInventoryObject> obj = getObject(id);
if(obj)
@@ -816,6 +884,42 @@ void LLInventoryModel::deleteObject(const LLUUID& id)
}
}
+// Delete a particular inventory item by ID, and remove it from the server.
+void LLInventoryModel::purgeObject(const LLUUID &id)
+{
+ lldebugs << "LLInventoryModel::purgeObject()" << llendl;
+ LLPointer<LLInventoryObject> obj = getObject(id);
+ if(obj)
+ {
+ obj->removeFromServer();
+ LLPreview::hide(id);
+ deleteObject(id);
+ }
+}
+
+void LLInventoryModel::purgeLinkedObjects(const LLUUID &id)
+{
+ LLInventoryObject* objectp = getObject(id);
+ if (!objectp) return;
+
+ if (objectp->getIsLinkType())
+ {
+ return;
+ }
+
+ LLInventoryModel::item_array_t item_array;
+ collectLinkedItems(id, item_array);
+
+ for (LLInventoryModel::item_array_t::iterator iter = item_array.begin();
+ iter != item_array.end();
+ iter++)
+ {
+ LLViewerInventoryItem *linked_item = (*iter);
+ if (linked_item->getUUID() == id) continue;
+ purgeObject(linked_item->getUUID());
+ }
+}
+
// This is a method which collects the descendents of the id
// provided. If the category is not found, no action is
// taken. This method goes through the long winded process of
@@ -1042,7 +1146,7 @@ void LLInventoryModel::mock(const LLUUID& root_id)
root_id,
LLUUID::null,
LLAssetType::AT_CATEGORY,
- NEW_CATEGORY_NAMES[LLAssetType::AT_ROOT_CATEGORY],
+ LLAssetType::lookupCategoryName(LLAssetType::AT_ROOT_CATEGORY),
gAgent.getID());
addCategory(cat);
gInventory.buildParentChildMap();
@@ -1122,14 +1226,14 @@ void LLInventoryModel::fetchInventoryResponder::error(U32 status, const std::str
gInventory.notifyObservers("fetchinventory");
}
-void LLInventoryModel::fetchDescendentsOf(const LLUUID& folder_id)
+bool LLInventoryModel::fetchDescendentsOf(const LLUUID& folder_id)
{
LLViewerInventoryCategory* cat = getCategory(folder_id);
if(!cat)
{
llwarns << "Asked to fetch descendents of non-existent folder: "
<< folder_id << llendl;
- return;
+ return false;
}
//S32 known_descendents = 0;
///cat_array_t* categories = get_ptr_in_map(mParentChildCategoryTree, folder_id);
@@ -1142,10 +1246,7 @@ void LLInventoryModel::fetchDescendentsOf(const LLUUID& folder_id)
//{
// known_descendents += items->count();
//}
- if(!cat->fetchDescendents())
- {
- //llinfos << "Not fetching descendents" << llendl;
- }
+ return cat->fetchDescendents();
}
//Initialize statics.
@@ -1263,6 +1364,7 @@ void fetchDescendentsResponder::result(const LLSD& content)
{
cat->setVersion(version);
cat->setDescendentCount(descendents);
+ cat->determineFolderType();
}
}
@@ -1459,8 +1561,8 @@ void LLInventoryModel::startBackgroundFetch(const LLUUID& cat_id)
if (!sFullFetchStarted)
{
sFullFetchStarted = TRUE;
- sFetchQueue.push_back(gInventoryLibraryRoot);
- sFetchQueue.push_back(gAgent.getInventoryRootID());
+ sFetchQueue.push_back(gInventory.getLibraryRootFolderID());
+ sFetchQueue.push_back(gInventory.getRootFolderID());
gIdleCallbacks.addFunction(&LLInventoryModel::backgroundFetch, NULL);
}
}
@@ -1684,6 +1786,12 @@ void LLInventoryModel::addItem(LLViewerInventoryItem* item)
//llinfos << "LLInventoryModel::addItem()" << llendl;
if(item)
{
+ // This condition means that we tried to add a link without the baseobj being in memory.
+ // The item will show up as a broken link.
+ if (item->getIsBrokenLink())
+ {
+ llwarns << "Add link item without baseobj present ( name: " << item->getName() << " itemID: " << item->getUUID() << " assetID: " << item->getAssetUUID() << " ) parent: " << item->getParentUUID() << llendl;
+ }
mItemMap[item->getUUID()] = item;
//mInventory[item->getUUID()] = item;
}
@@ -1933,6 +2041,7 @@ bool LLInventoryModel::loadSkeleton(
{
cat_array_t categories;
item_array_t items;
+ cat_set_t invalid_categories; // Used to mark categories that weren't successfully loaded.
std::string owner_id_str;
owner_id.toString(owner_id_str);
std::string path(gDirUtilp->getExpandedFilename(LL_PATH_CACHE, owner_id_str));
@@ -1998,7 +2107,7 @@ bool LLInventoryModel::loadSkeleton(
}
// go ahead and add the cats returned during the download
- std::set<LLUUID>::iterator not_cached_id = cached_ids.end();
+ std::set<LLUUID>::const_iterator not_cached_id = cached_ids.end();
cached_category_count = cached_ids.size();
for(cat_set_t::iterator it = temp_cats.begin(); it != temp_cats.end(); ++it)
{
@@ -2018,16 +2127,26 @@ bool LLInventoryModel::loadSkeleton(
// category with a correctly cached parent
count = items.count();
cat_map_t::iterator unparented = mCategoryMap.end();
- for(int i = 0; i < count; ++i)
+ for(item_array_t::const_iterator item_iter = items.begin();
+ item_iter != items.end();
+ ++item_iter)
{
- cat_map_t::iterator cit = mCategoryMap.find(items[i]->getParentUUID());
+ LLViewerInventoryItem *item = (*item_iter).get();
+ const cat_map_t::iterator cit = mCategoryMap.find(item->getParentUUID());
if(cit != unparented)
{
- LLViewerInventoryCategory* cat = cit->second;
+ const LLViewerInventoryCategory* cat = cit->second.get();
if(cat->getVersion() != NO_VERSION)
{
- addItem(items[i]);
+ // This can happen if the linked object's baseobj is removed from the cache but the linked object is still in the cache.
+ if (item->getIsBrokenLink())
+ {
+ llinfos << "Attempted to cached link item without baseobj present ( itemID: " << item->getUUID() << " assetID: " << item->getAssetUUID() << " ) " << llendl;
+ invalid_categories.insert(cit->second);
+ continue;
+ }
+ addItem(item);
cached_item_count += 1;
++child_counts[cat->getUUID()];
}
@@ -2049,14 +2168,13 @@ bool LLInventoryModel::loadSkeleton(
// At this point, we need to set the known descendents for each
// category which successfully cached so that we do not
// needlessly fetch descendents for categories which we have.
- update_map_t::iterator no_child_counts = child_counts.end();
- update_map_t::iterator the_count;
+ update_map_t::const_iterator no_child_counts = child_counts.end();
for(cat_set_t::iterator it = temp_cats.begin(); it != temp_cats.end(); ++it)
{
- LLViewerInventoryCategory* cat = (*it);
+ LLViewerInventoryCategory* cat = (*it).get();
if(cat->getVersion() != NO_VERSION)
{
- the_count = child_counts.find(cat->getUUID());
+ update_map_t::const_iterator the_count = child_counts.find(cat->getUUID());
if(the_count != no_child_counts)
{
cat->setDescendentCount((*the_count).second.mValue);
@@ -2068,6 +2186,17 @@ bool LLInventoryModel::loadSkeleton(
}
}
+ // Invalidate all categories that failed fetching descendents for whatever
+ // reason (e.g. one of the descendents was a broken link).
+ for (cat_set_t::iterator invalid_cat_it = invalid_categories.begin();
+ invalid_cat_it != invalid_categories.end();
+ invalid_cat_it++)
+ {
+ LLViewerInventoryCategory* cat = (*invalid_cat_it).get();
+ cat->setVersion(NO_VERSION);
+ llinfos << "Invalidating category name: " << cat->getName() << " UUID: " << cat->getUUID() << " due to invalid descendents cache" << llendl;
+ }
+
if(remove_inventory_file)
{
// clean up the gunzipped file.
@@ -2252,7 +2381,7 @@ void LLInventoryModel::buildParentChildMap()
else
{
// it's a protected folder.
- cat->setParent(gAgent.getInventoryRootID());
+ cat->setParent(gInventory.getRootFolderID());
}
cat->updateServer(TRUE);
catsp = getUnlockedCatArray(cat->getParentUUID());
@@ -2352,7 +2481,7 @@ void LLInventoryModel::buildParentChildMap()
}
}
- const LLUUID& agent_inv_root_id = gAgent.getInventoryRootID();
+ LLUUID agent_inv_root_id = gInventory.getRootFolderID();
if (agent_inv_root_id.notNull())
{
cat_array_t* catsp = get_ptr_in_map(mParentChildCategoryTree, agent_inv_root_id);
@@ -2802,7 +2931,7 @@ void LLInventoryModel::processUpdateInventoryFolder(LLMessageSystem* msg,
gInventory.notifyObservers();
// *HACK: Do the 'show' logic for a new item in the inventory.
- LLInventoryView* view = LLInventoryView::getActiveInventory();
+ LLFloaterInventory* view = LLFloaterInventory::getActiveInventory();
if(view)
{
view->getPanel()->setSelection(lastfolder->getUUID(), TAKE_FOCUS_NO);
@@ -3011,13 +3140,13 @@ void LLInventoryModel::processBulkUpdateInventory(LLMessageSystem* msg, void**)
// The incoming inventory could span more than one BulkInventoryUpdate packet,
// so record the transaction ID for this purchase, then wear all clothing
// that comes in as part of that transaction ID. JC
- if (LLInventoryView::sWearNewClothing)
+ if (LLFloaterInventory::sWearNewClothing)
{
- LLInventoryView::sWearNewClothingTransactionID = tid;
- LLInventoryView::sWearNewClothing = FALSE;
+ LLFloaterInventory::sWearNewClothingTransactionID = tid;
+ LLFloaterInventory::sWearNewClothing = FALSE;
}
- if (tid == LLInventoryView::sWearNewClothingTransactionID)
+ if (tid == LLFloaterInventory::sWearNewClothingTransactionID)
{
count = wearable_ids.size();
for (i = 0; i < count; ++i)
@@ -3035,7 +3164,7 @@ void LLInventoryModel::processBulkUpdateInventory(LLMessageSystem* msg, void**)
gInventoryCallbacks.fire(cbinfo.mCallback, cbinfo.mInvID);
}
// Don't show the inventory. We used to call showAgentInventory here.
- //LLInventoryView* view = LLInventoryView::getActiveInventory();
+ //LLFloaterInventory* view = LLFloaterInventory::getActiveInventory();
//if(view)
//{
// const BOOL take_keyboard_focus = FALSE;
@@ -3045,10 +3174,10 @@ void LLInventoryModel::processBulkUpdateInventory(LLMessageSystem* msg, void**)
// // HACK to open inventory offers that are accepted. This information
// // really needs to flow through the instant messages and inventory
// // transfer/update messages.
- // if (LLInventoryView::sOpenNextNewItem)
+ // if (LLFloaterInventory::sOpenNextNewItem)
// {
// view->openSelected();
- // LLInventoryView::sOpenNextNewItem = FALSE;
+ // LLFloaterInventory::sOpenNextNewItem = FALSE;
// }
//
// // restore keyboard focus
@@ -3158,6 +3287,93 @@ void LLInventoryModel::processMoveInventoryItem(LLMessageSystem* msg, void**)
}
}
+//----------------------------------------------------------------------------
+
+// Trash: LLAssetType::AT_TRASH, "ConfirmEmptyTrash"
+// Lost&Found: LLAssetType::AT_LOST_AND_FOUND, "ConfirmEmptyLostAndFound"
+
+bool LLInventoryModel::callbackEmptyFolderType(const LLSD& notification, const LLSD& response, LLAssetType::EType folder_type)
+{
+ S32 option = LLNotification::getSelectedOption(notification, response);
+ if (option == 0) // YES
+ {
+ LLUUID folder_id = findCategoryUUIDForType(folder_type);
+ purgeDescendentsOf(folder_id);
+ notifyObservers();
+ }
+ return false;
+}
+
+void LLInventoryModel::emptyFolderType(const std::string notification, LLAssetType::EType folder_type)
+{
+ if (!notification.empty())
+ {
+ LLNotifications::instance().add(notification, LLSD(), LLSD(),
+ boost::bind(&LLInventoryModel::callbackEmptyFolderType, this, _1, _2, folder_type));
+ }
+ else
+ {
+ LLUUID folder_id = findCategoryUUIDForType(folder_type);
+ purgeDescendentsOf(folder_id);
+ notifyObservers();
+ }
+}
+
+//----------------------------------------------------------------------------
+
+void LLInventoryModel::removeItem(const LLUUID& item_id)
+{
+ LLViewerInventoryItem* item = getItem(item_id);
+ const LLUUID& new_parent = findCategoryUUIDForType(LLAssetType::AT_TRASH);
+ if (item && item->getParentUUID() != new_parent)
+ {
+ LLInventoryModel::update_list_t update;
+ LLInventoryModel::LLCategoryUpdate old_folder(item->getParentUUID(),-1);
+ update.push_back(old_folder);
+ LLInventoryModel::LLCategoryUpdate new_folder(new_parent, 1);
+ update.push_back(new_folder);
+ accountForUpdate(update);
+
+ LLPointer<LLViewerInventoryItem> new_item = new LLViewerInventoryItem(item);
+ new_item->setParent(new_parent);
+ new_item->updateParentOnServer(TRUE);
+ updateItem(new_item);
+ notifyObservers();
+ }
+}
+
+LLUUID LLInventoryModel::getRootFolderID() const
+{
+ return mRootFolderID;
+}
+
+void LLInventoryModel::setRootFolderID(const LLUUID& val)
+{
+ mRootFolderID = val;
+}
+
+LLUUID LLInventoryModel::getLibraryRootFolderID() const
+{
+ return mLibraryRootFolderID;
+}
+
+void LLInventoryModel::setLibraryRootFolderID(const LLUUID& val)
+{
+ mLibraryRootFolderID = val;
+}
+
+LLUUID LLInventoryModel::getLibraryOwnerID() const
+{
+ return mLibraryOwnerID;
+}
+
+void LLInventoryModel::setLibraryOwnerID(const LLUUID& val)
+{
+ mLibraryOwnerID = val;
+}
+
+//----------------------------------------------------------------------------
+
// *NOTE: DEBUG functionality
void LLInventoryModel::dumpInventory()
{
@@ -3205,7 +3421,7 @@ bool LLInventoryCollectFunctor::itemTransferCommonlyAllowed(LLInventoryItem* ite
return false;
bool allowed = false;
- LLVOAvatar* my_avatar = NULL;
+ LLVOAvatarSelf* my_avatar = NULL;
switch(item->getType())
{
@@ -3223,7 +3439,7 @@ bool LLInventoryCollectFunctor::itemTransferCommonlyAllowed(LLInventoryItem* ite
case LLAssetType::AT_BODYPART:
case LLAssetType::AT_CLOTHING:
- if(!gAgent.isWearingItem(item->getUUID()))
+ if(!gAgentWearables.isWearingItem(item->getUUID()))
{
allowed = true;
}
@@ -3887,11 +4103,20 @@ void LLInventoryTransactionObserver::changed(U32 mask)
///----------------------------------------------------------------------------
/// LLAssetIDMatches
///----------------------------------------------------------------------------
-bool LLAssetIDMatches ::operator()(LLInventoryCategory* cat, LLInventoryItem* item)
+bool LLAssetIDMatches::operator()(LLInventoryCategory* cat, LLInventoryItem* item)
{
return (item && item->getAssetUUID() == mAssetID);
}
+///----------------------------------------------------------------------------
+/// LLLinkedItemIDMatches
+///----------------------------------------------------------------------------
+bool LLLinkedItemIDMatches::operator()(LLInventoryCategory* cat, LLInventoryItem* item)
+{
+ return (item &&
+ (item->getIsLinkType()) &&
+ (item->getLinkedUUID() == mBaseItemID)); // A linked item's assetID will be the compared-to item's itemID.
+}
///----------------------------------------------------------------------------
/// Local function definitions
diff --git a/indra/newview/llinventorymodel.h b/indra/newview/llinventorymodel.h
index d73fef7207..2ddc35b9ef 100644
--- a/indra/newview/llinventorymodel.h
+++ b/indra/newview/llinventorymodel.h
@@ -35,6 +35,8 @@
#include "llassettype.h"
#include "lldarray.h"
+#include "llframetimer.h"
+#include "llhttpclient.h"
#include "lluuid.h"
#include "llpermissionsflags.h"
#include "llstring.h"
@@ -111,11 +113,12 @@ public:
LLInventoryModel();
~LLInventoryModel();
- class fetchInventoryResponder: public LLHTTPClient::Responder
+ class fetchInventoryResponder : public LLHTTPClient::Responder
{
public:
fetchInventoryResponder(const LLSD& request_sd) : mRequestSD(request_sd) {};
void result(const LLSD& content);
+
void error(U32 status, const std::string& reason);
public:
@@ -167,7 +170,7 @@ public:
item_array_t*& items);
void unlockDirectDescendentArrays(const LLUUID& cat_id);
- // Starting with the object specified, add it's descendents to the
+ // Starting with the object specified, add its descendents to the
// array provided, but do not add the inventory object specified
// by id. There is no guaranteed order. Neither array will be
// erased before adding objects to it. Do not store a copy of the
@@ -178,14 +181,20 @@ public:
cat_array_t& categories,
item_array_t& items,
BOOL include_trash);
-
void collectDescendentsIf(const LLUUID& id,
cat_array_t& categories,
item_array_t& items,
BOOL include_trash,
- LLInventoryCollectFunctor& add);
+ LLInventoryCollectFunctor& add,
+ BOOL follow_folder_links = FALSE);
+
+ // Collect all items in inventory that are linked to item_id.
+ // Assumes item_id is itself not a linked item.
+ void collectLinkedItems(const LLUUID& item_id,
+ item_array_t& items);
+ // Updates all linked objects pointing to this id.
+ void updateLinkedObjects(const LLUUID& object_id);
- // This method will return false if this inventory model is in an usabel state.
// The inventory model usage is sensitive to the initial construction of the
// model.
bool isInventoryUsable();
@@ -197,7 +206,7 @@ public:
// Calling this method with an inventory item will either change
// an existing item with a matching item_id, or will add the item
// to the current inventory. Returns the change mask generated by
- // the update. No notifcation will be sent to observers. This
+ // the update. No notification will be sent to observers. This
// method will only generate network traffic if the item had to be
// reparented.
// *NOTE: In usage, you will want to perform cache accounting
@@ -224,16 +233,21 @@ public:
// delete a particular inventory object by ID. This will purge one
// object from the internal data structures maintaining a
- // cosistent internal state. No cache accounting, observer
- // notification, or server update is performed.
+ // consistent internal state. No cache accounting, observer
+ // notification, or server update is performed. Purges linked items.
void deleteObject(const LLUUID& id);
+
+ // delete a particular inventory object by ID, and delete it from
+ // the server. Also purges linked items via purgeLinkedObjects.
+ void purgeObject(const LLUUID& id);
+ void purgeLinkedObjects(const LLUUID& id);
- // This is a method which collects the descendents of the id
+ // This is a method which collects the descendants of the id
// provided. If the category is not found, no action is
// taken. This method goes through the long winded process of
// removing server representation of folders and items while doing
// cache accounting in a fairly efficient manner. This method does
- // not notify observers (though maybe it shouldd...)
+ // not notify observers (though maybe it should...)
void purgeDescendentsOf(const LLUUID& id);
// This method optimally removes the referenced categories and
@@ -283,8 +297,9 @@ public:
// minimal functionality before the actual arrival of inventory.
//void mock(const LLUUID& root_id);
- // make sure we have the descendents in the structure.
- void fetchDescendentsOf(const LLUUID& folder_id);
+ // Make sure we have the descendents in the structure. Returns true
+ // if a fetch was performed.
+ bool fetchDescendentsOf(const LLUUID& folder_id);
// Add categories to a list to be fetched in bulk.
static void bulkFetch(std::string url);
@@ -365,7 +380,15 @@ public:
// returns true iff category version is known and theoretical
// descendents == actual descendents.
bool isCategoryComplete(const LLUUID& cat_id) const;
+
+ // callbacks
+ // Trigger a notification and empty the folder type (AT_TRASH or AT_LOST_AND_FOUND) if confirmed
+ void emptyFolderType(const std::string notification, LLAssetType::EType folder_type);
+ bool callbackEmptyFolderType(const LLSD& notification, const LLSD& response, LLAssetType::EType folder_type);
+ // Utility Functions
+ void removeItem(const LLUUID& item_id);
+
// start and stop background breadth-first fetching of inventory contents
// this gets triggered when performing a filter-search
static void startBackgroundFetch(const LLUUID& cat_id = LLUUID::null); // start fetch process
@@ -374,6 +397,22 @@ public:
static bool isEverythingFetched();
static void backgroundFetch(void*); // background fetch idle function
static void incrBulkFetch(S16 fetching) { sBulkFetchCount+=fetching; if (sBulkFetchCount<0) sBulkFetchCount=0; }
+
+
+ // Data about the agent's root folder and root library folder
+ // are stored here, rather than in LLAgent where it used to be, because
+ // gInventory is a singleton and represents the agent's inventory.
+ // The "library" is actually the inventory of a special agent,
+ // usually Alexandria Linden.
+ LLUUID getRootFolderID() const;
+ LLUUID getLibraryOwnerID() const;
+ LLUUID getLibraryRootFolderID() const;
+
+ // These are set during login with data from the server
+ void setRootFolderID(const LLUUID& id);
+ void setLibraryOwnerID(const LLUUID& id);
+ void setLibraryRootFolderID(const LLUUID& id);
+
protected:
// Internal methods which add inventory and make sure that all of
@@ -426,7 +465,7 @@ protected:
item_array_t* getUnlockedItemArray(const LLUUID& id);
protected:
- // Varaibles used to track what has changed since the last notify.
+ // Variables used to track what has changed since the last notify.
U32 mModifyMask;
typedef std::set<LLUUID> changed_items_t;
changed_items_t mChangedItemIDs;
@@ -457,6 +496,11 @@ protected:
typedef std::set<LLInventoryObserver*> observer_list_t;
observer_list_t mObservers;
+ // Agent inventory folder information.
+ LLUUID mRootFolderID;
+ LLUUID mLibraryRootFolderID;
+ LLUUID mLibraryOwnerID;
+
// completing the fetch once per session should be sufficient
static BOOL sBackgroundFetchActive;
static BOOL sTimelyFetchPending;
@@ -520,6 +564,22 @@ protected:
LLUUID mAssetID;
};
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+// Class LLLinkedItemIDMatches
+//
+// This functor finds inventory items linked to the specific inventory id.
+// Assumes the inventory id is itself not a linked item.
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+class LLLinkedItemIDMatches : public LLInventoryCollectFunctor
+{
+public:
+ LLLinkedItemIDMatches(const LLUUID& item_id) : mBaseItemID(item_id) {}
+ virtual ~LLLinkedItemIDMatches() {}
+ bool operator()(LLInventoryCategory* cat, LLInventoryItem* item);
+
+protected:
+ LLUUID mBaseItemID;
+};
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Class LLIsType
@@ -666,6 +726,20 @@ protected:
std::string mName;
};
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+// Class LLFindWearables
+//
+// Collects wearables based on item type.
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+class LLFindWearables : public LLInventoryCollectFunctor
+{
+public:
+ LLFindWearables() {}
+ virtual ~LLFindWearables() {}
+ virtual bool operator()(LLInventoryCategory* cat,
+ LLInventoryItem* item);
+};
+
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Class LLInventoryCompletionObserver
diff --git a/indra/newview/lljoystickbutton.cpp b/indra/newview/lljoystickbutton.cpp
index 326c511fcf..efc03b3d88 100644
--- a/indra/newview/lljoystickbutton.cpp
+++ b/indra/newview/lljoystickbutton.cpp
@@ -42,15 +42,19 @@
// Project includes
#include "llui.h"
#include "llagent.h"
-#include "llviewerimage.h"
-#include "llviewerimagelist.h"
+#include "llviewertexture.h"
+#include "llviewertexturelist.h"
#include "llviewerwindow.h"
#include "llmoveview.h"
#include "llglheaders.h"
-static LLRegisterWidget<LLJoystickAgentSlide> r1("joystick_slide");
-static LLRegisterWidget<LLJoystickAgentTurn> r2("joystick_turn");
+static LLDefaultChildRegistry::Register<LLJoystickAgentSlide> r1("joystick_slide");
+static LLDefaultChildRegistry::Register<LLJoystickAgentTurn> r2("joystick_turn");
+static LLDefaultChildRegistry::Register<LLJoystickCameraRotate> r3("joystick_rotate");
+static LLDefaultChildRegistry::Register<LLJoystickCameraZoom> r4("joystick_zoom");
+static LLDefaultChildRegistry::Register<LLJoystickCameraTrack> r5("joystick_track");
+
const F32 NUDGE_TIME = 0.25f; // in seconds
@@ -59,15 +63,18 @@ const F32 ORBIT_NUDGE_RATE = 0.05f; // fraction of normal speed
//
// Public Methods
//
-LLJoystick::LLJoystick(
- const std::string& name,
- LLRect rect,
- const std::string &default_image,
- const std::string &selected_image,
- EJoystickQuadrant initial_quadrant )
- :
- LLButton(name, rect, default_image, selected_image, LLStringUtil::null, NULL, NULL),
- mInitialQuadrant(initial_quadrant),
+void QuadrantNames::declareValues()
+{
+ declare("origin", JQ_ORIGIN);
+ declare("up", JQ_UP);
+ declare("down", JQ_DOWN);
+ declare("left", JQ_LEFT);
+ declare("right", JQ_RIGHT);
+}
+
+
+LLJoystick::LLJoystick(const LLJoystick::Params& p)
+: LLButton(p),
mInitialOffset(0, 0),
mLastMouse(0, 0),
mFirstMouse(0, 0),
@@ -76,10 +83,10 @@ LLJoystick::LLJoystick(
mHorizSlopNear(0),
mHorizSlopFar(0),
mHeldDown(FALSE),
- mHeldDownTimer()
+ mHeldDownTimer(),
+ mInitialQuadrant(p.quadrant)
{
- setHeldDownCallback(&LLJoystick::onHeldDown);
- setCallbackUserData(this);
+ setHeldDownCallback(&LLJoystick::onBtnHeldDown, this);
}
@@ -178,16 +185,14 @@ F32 LLJoystick::getElapsedHeldDownTime()
}
// static
-void LLJoystick::onHeldDown(void *userdata)
+void LLJoystick::onBtnHeldDown(void *userdata)
{
LLJoystick *self = (LLJoystick *)userdata;
-
- // somebody removed this function without checking the
- // build. Removed 2007-03-26.
- //llassert( gViewerWindow->hasMouseCapture( self ) );
-
- self->mHeldDown = TRUE;
- self->onHeldDown();
+ if (self)
+ {
+ self->mHeldDown = TRUE;
+ self->onHeldDown();
+ }
}
EJoystickQuadrant LLJoystick::selectQuadrant(LLXMLNodePtr node)
@@ -246,23 +251,6 @@ EJoystickQuadrant LLJoystick::quadrantFromName(const std::string& sQuadrant)
}
-LLXMLNodePtr LLJoystick::getXML(bool save_children) const
-{
- LLXMLNodePtr node = LLUICtrl::getXML();
-
- node->createChild("halign", TRUE)->setStringValue(LLFontGL::nameFromHAlign(getHAlign()));
- node->createChild("quadrant", TRUE)->setStringValue(nameFromQuadrant(mInitialQuadrant));
-
- addImageAttributeToXML(node,getImageUnselectedName(),getImageUnselectedID(),std::string("image_unselected"));
- addImageAttributeToXML(node,getImageSelectedName(),getImageSelectedID(),std::string("image_selected"));
-
- node->createChild("scale_image", TRUE)->setBoolValue(getScaleImage());
-
- return node;
-}
-
-
-
//-------------------------------------------------------------------------------
// LLJoystickAgentTurn
//-------------------------------------------------------------------------------
@@ -327,46 +315,6 @@ void LLJoystickAgentTurn::onHeldDown()
}
}
-LLView* LLJoystickAgentTurn::fromXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFactory *factory)
-{
- std::string name("button");
- node->getAttributeString("name", name);
-
- std::string image_unselected;
- if (node->hasAttribute("image_unselected")) node->getAttributeString("image_unselected",image_unselected);
-
- std::string image_selected;
- if (node->hasAttribute("image_selected")) node->getAttributeString("image_selected",image_selected);
-
- EJoystickQuadrant quad = JQ_ORIGIN;
- if (node->hasAttribute("quadrant")) quad = selectQuadrant(node);
-
- LLJoystickAgentTurn *button = new LLJoystickAgentTurn(name,
- LLRect(),
- image_unselected,
- image_selected,
- quad);
-
- if (node->hasAttribute("halign"))
- {
- LLFontGL::HAlign halign = selectFontHAlign(node);
- button->setHAlign(halign);
- }
-
- if (node->hasAttribute("scale_image"))
- {
- BOOL needsScale = FALSE;
- node->getAttributeBOOL("scale_image",needsScale);
- button->setScaleImage( needsScale );
- }
-
- button->initFromXML(node, parent);
-
- return button;
-}
-
-
-
//-------------------------------------------------------------------------------
// LLJoystickAgentSlide
//-------------------------------------------------------------------------------
@@ -435,54 +383,12 @@ void LLJoystickAgentSlide::onHeldDown()
}
-// static
-LLView* LLJoystickAgentSlide::fromXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFactory *factory)
-{
- std::string name("button");
- node->getAttributeString("name", name);
-
- std::string image_unselected;
- if (node->hasAttribute("image_unselected")) node->getAttributeString("image_unselected",image_unselected);
-
- std::string image_selected;
- if (node->hasAttribute("image_selected")) node->getAttributeString("image_selected",image_selected);
-
-
- EJoystickQuadrant quad = JQ_ORIGIN;
- if (node->hasAttribute("quadrant")) quad = selectQuadrant(node);
-
- LLJoystickAgentSlide *button = new LLJoystickAgentSlide(name,
- LLRect(),
- image_unselected,
- image_selected,
- quad);
-
- if (node->hasAttribute("halign"))
- {
- LLFontGL::HAlign halign = selectFontHAlign(node);
- button->setHAlign(halign);
- }
-
- if (node->hasAttribute("scale_image"))
- {
- BOOL needsScale = FALSE;
- node->getAttributeBOOL("scale_image",needsScale);
- button->setScaleImage( needsScale );
- }
-
- button->initFromXML(node, parent);
-
- return button;
-}
-
-
//-------------------------------------------------------------------------------
// LLJoystickCameraRotate
//-------------------------------------------------------------------------------
-LLJoystickCameraRotate::LLJoystickCameraRotate(const std::string& name, LLRect rect, const std::string &out_img, const std::string &in_img)
- :
- LLJoystick(name, rect, out_img, in_img, JQ_ORIGIN),
+LLJoystickCameraRotate::LLJoystickCameraRotate(const LLJoystickCameraRotate::Params& p)
+: LLJoystick(p),
mInLeft( FALSE ),
mInTop( FALSE ),
mInRight( FALSE ),
@@ -636,10 +542,17 @@ void LLJoystickCameraRotate::draw()
{
drawDebugRect();
}
+
+ //// *HACK: also draw debug rectangles around currently-being-edited LLView, and any elements that are being highlighted by GUI preview code (see LLFloaterUIPreview)
+ //std::set<LLView*>::iterator iter = std::find(sPreviewHighlightedElements.begin(), sPreviewHighlightedElements.end(), this);
+ //if ((sEditingUI && this == sEditingUIView) || (iter != sPreviewHighlightedElements.end() && sDrawPreviewHighlights))
+ //{
+ // drawDebugRect();
+ //}
}
// Draws image rotated by multiples of 90 degrees
-void LLJoystickCameraRotate::drawRotatedImage( LLImageGL* image, S32 rotations )
+void LLJoystickCameraRotate::drawRotatedImage( LLTexture* image, S32 rotations )
{
S32 width = image->getWidth();
S32 height = image->getHeight();
@@ -679,6 +592,15 @@ void LLJoystickCameraRotate::drawRotatedImage( LLImageGL* image, S32 rotations )
// LLJoystickCameraTrack
//-------------------------------------------------------------------------------
+LLJoystickCameraTrack::Params::Params()
+{
+ held_down_delay.seconds(0.0);
+}
+
+LLJoystickCameraTrack::LLJoystickCameraTrack(const LLJoystickCameraTrack::Params& p)
+: LLJoystickCameraRotate(p)
+{}
+
void LLJoystickCameraTrack::onHeldDown()
{
@@ -717,17 +639,15 @@ void LLJoystickCameraTrack::onHeldDown()
// LLJoystickCameraZoom
//-------------------------------------------------------------------------------
-LLJoystickCameraZoom::LLJoystickCameraZoom(const std::string& name, LLRect rect, const std::string &out_img, const std::string &plus_in_img, const std::string &minus_in_img)
- :
- LLJoystick(name, rect, out_img, LLStringUtil::null, JQ_ORIGIN),
+LLJoystickCameraZoom::LLJoystickCameraZoom(const LLJoystickCameraZoom::Params& p)
+: LLJoystick(p),
mInTop( FALSE ),
- mInBottom( FALSE )
+ mInBottom( FALSE ),
+ mPlusInImage(p.plus_image),
+ mMinusInImage(p.minus_image)
{
- mPlusInImage = LLUIImageList::getInstance()->getUIImage(plus_in_img);
- mMinusInImage = LLUIImageList::getInstance()->getUIImage(minus_in_img);
}
-
BOOL LLJoystickCameraZoom::handleMouseDown(S32 x, S32 y, MASK mask)
{
BOOL handled = LLJoystick::handleMouseDown(x, y, mask);
@@ -808,6 +728,13 @@ void LLJoystickCameraZoom::draw()
{
drawDebugRect();
}
+
+ //// *HACK: also draw debug rectangles around currently-being-edited LLView, and any elements that are being highlighted by GUI preview code (see LLFloaterUIPreview)
+ //std::set<LLView*>::iterator iter = std::find(sPreviewHighlightedElements.begin(), sPreviewHighlightedElements.end(), this);
+ //if ((sEditingUI && this == sEditingUIView) || (iter != sPreviewHighlightedElements.end() && sDrawPreviewHighlights))
+ //{
+ // drawDebugRect();
+ //}
}
void LLJoystickCameraZoom::updateSlop()
diff --git a/indra/newview/lljoystickbutton.h b/indra/newview/lljoystickbutton.h
index 076a506f14..8caef30fa4 100644
--- a/indra/newview/lljoystickbutton.h
+++ b/indra/newview/lljoystickbutton.h
@@ -35,7 +35,7 @@
#include "llbutton.h"
#include "llcoord.h"
-#include "llviewerimage.h"
+#include "llviewertexture.h"
typedef enum e_joystick_quadrant
{
@@ -46,11 +46,27 @@ typedef enum e_joystick_quadrant
JQ_RIGHT
} EJoystickQuadrant;
+struct QuadrantNames : public LLInitParam::TypeValuesHelper<EJoystickQuadrant, QuadrantNames>
+{
+ static void declareValues();
+};
+
class LLJoystick
: public LLButton
{
public:
- LLJoystick(const std::string& name, LLRect rect, const std::string &default_image, const std::string &selected_image, EJoystickQuadrant initial);
+ struct Params
+ : public LLInitParam::Block<Params, LLButton::Params>
+ {
+ Optional<EJoystickQuadrant, QuadrantNames> quadrant;
+
+ Params()
+ : quadrant("quadrant", JQ_ORIGIN)
+ {
+ label = "";
+ }
+ };
+ LLJoystick(const Params&);
virtual BOOL handleMouseDown(S32 x, S32 y, MASK mask);
virtual BOOL handleMouseUp(S32 x, S32 y, MASK mask);
@@ -60,10 +76,9 @@ public:
virtual void onHeldDown() = 0;
F32 getElapsedHeldDownTime();
- static void onHeldDown(void *userdata); // called by llbutton callback handler
+ static void onBtnHeldDown(void *userdata); // called by llbutton callback handler
void setInitialQuadrant(EJoystickQuadrant initial) { mInitialQuadrant = initial; };
- virtual LLXMLNodePtr getXML(bool save_children = true) const;
static std::string nameFromQuadrant(const EJoystickQuadrant quadrant);
static EJoystickQuadrant quadrantFromName(const std::string& name);
static EJoystickQuadrant selectQuadrant(LLXMLNodePtr node);
@@ -91,14 +106,9 @@ class LLJoystickAgentTurn
: public LLJoystick
{
public:
- LLJoystickAgentTurn(const std::string& name, LLRect rect, const std::string &default_image, const std::string &selected_image, EJoystickQuadrant initial)
- : LLJoystick(name, rect, default_image, selected_image, initial)
- { }
-
+ struct Params : public LLJoystick::Params {};
+ LLJoystickAgentTurn(const Params& p) : LLJoystick(p) {}
virtual void onHeldDown();
-
- static LLView* fromXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFactory *factory);
-
};
@@ -107,14 +117,11 @@ class LLJoystickAgentSlide
: public LLJoystick
{
public:
- LLJoystickAgentSlide(const std::string& name, LLRect rect, const std::string &default_image, const std::string &selected_image, EJoystickQuadrant initial)
- : LLJoystick(name, rect, default_image, selected_image, initial)
- { }
-
+ struct Params : public LLJoystick::Params {};
+ LLJoystickAgentSlide(const Params& p) : LLJoystick(p) {}
+
virtual void onHeldDown();
virtual void onMouseUp();
-
- static LLView* fromXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFactory *factory);
};
@@ -123,7 +130,16 @@ class LLJoystickCameraRotate
: public LLJoystick
{
public:
- LLJoystickCameraRotate(const std::string& name, LLRect rect, const std::string &out_img, const std::string &in_img);
+ struct Params
+ : public LLInitParam::Block<Params, LLJoystick::Params>
+ {
+ Params()
+ {
+ held_down_delay.seconds(0.0);
+ }
+ };
+
+ LLJoystickCameraRotate(const LLJoystickCameraRotate::Params&);
virtual void setToggleState( BOOL left, BOOL top, BOOL right, BOOL bottom );
@@ -134,7 +150,7 @@ public:
protected:
F32 getOrbitRate();
virtual void updateSlop();
- void drawRotatedImage( LLImageGL* image, S32 rotations );
+ void drawRotatedImage( LLTexture* image, S32 rotations );
protected:
BOOL mInLeft;
@@ -149,10 +165,13 @@ class LLJoystickCameraTrack
: public LLJoystickCameraRotate
{
public:
- LLJoystickCameraTrack(const std::string& name, LLRect rect, const std::string &out_img, const std::string &in_img)
- : LLJoystickCameraRotate(name, rect, out_img, in_img)
- { }
+ struct Params
+ : public LLInitParam::Block<Params, LLJoystickCameraRotate::Params>
+ {
+ Params();
+ };
+ LLJoystickCameraTrack(const LLJoystickCameraTrack::Params&);
virtual void onHeldDown();
};
@@ -162,7 +181,20 @@ class LLJoystickCameraZoom
: public LLJoystick
{
public:
- LLJoystickCameraZoom(const std::string& name, LLRect rect, const std::string &out_img, const std::string &plus_in_img, const std::string &minus_in_img);
+ struct Params
+ : public LLInitParam::Block<Params, LLJoystick::Params>
+ {
+ Optional<LLUIImage*> plus_image;
+ Optional<LLUIImage*> minus_image;
+
+ Params()
+ : plus_image ("plus_image", NULL),
+ minus_image ("minus_image", NULL)
+ {
+ held_down_delay.seconds(0.0);
+ }
+ };
+ LLJoystickCameraZoom(const Params&);
virtual void setToggleState( BOOL top, BOOL bottom );
diff --git a/indra/newview/lllandmarkactions.cpp b/indra/newview/lllandmarkactions.cpp
new file mode 100644
index 0000000000..df9aa32d1b
--- /dev/null
+++ b/indra/newview/lllandmarkactions.cpp
@@ -0,0 +1,299 @@
+/**
+* @file lllandmarkactions.cpp
+* @brief LLLandmarkActions class implementation
+*
+* $LicenseInfo:firstyear=2001&license=viewergpl$
+*
+* Copyright (c) 2001-2009, Linden Research, Inc.
+*
+* Second Life Viewer Source Code
+* The source code in this file ("Source Code") is provided by Linden Lab
+* to you under the terms of the GNU General Public License, version 2.0
+* ("GPL"), unless you have obtained a separate licensing agreement
+* ("Other License"), formally executed by you and Linden Lab. Terms of
+* the GPL can be found in doc/GPL-license.txt in this distribution, or
+* online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
+*
+* There are special exceptions to the terms and conditions of the GPL as
+* it is applied to this Source Code. View the full text of the exception
+* in the file doc/FLOSS-exception.txt in this software distribution, or
+* online at
+* http://secondlifegrid.net/programs/open_source/licensing/flossexception
+*
+* By copying, modifying or distributing this software, you acknowledge
+* that you have read and understood your obligations described above,
+* and agree to abide by those obligations.
+*
+* ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+* COMPLETENESS OR PERFORMANCE.
+* $/LicenseInfo$
+*/
+
+#include "llviewerprecompiledheaders.h"
+#include "lllandmarkactions.h"
+
+#include "roles_constants.h"
+
+#include "llinventory.h"
+#include "lllandmark.h"
+#include "llparcel.h"
+
+#include "llnotifications.h"
+
+#include "llagent.h"
+#include "llinventorymodel.h"
+#include "lllandmarklist.h"
+#include "llslurl.h"
+#include "llviewerinventory.h"
+#include "llviewerparcelmgr.h"
+#include "llworldmap.h"
+#include "lllandmark.h"
+#include "llinventorymodel.h"
+#include "llagentui.h"
+
+// Returns true if the given inventory item is a landmark pointing to the current parcel.
+// Used to filter inventory items.
+class LLIsAgentParcelLandmark : public LLInventoryCollectFunctor
+{
+public:
+ /*virtual*/ bool operator()(LLInventoryCategory* cat, LLInventoryItem* item)
+ {
+ if (!item || item->getType() != LLAssetType::AT_LANDMARK)
+ return false;
+
+ LLLandmark* landmark = gLandmarkList.getAsset(item->getAssetUUID());
+ if (!landmark) // the landmark not been loaded yet
+ return false;
+
+ LLVector3d landmark_global_pos;
+ if (!landmark->getGlobalPos(landmark_global_pos))
+ return false;
+
+ return LLViewerParcelMgr::getInstance()->inAgentParcel(landmark_global_pos);
+ }
+};
+
+class LLFetchLandmarksByName : public LLInventoryCollectFunctor
+{
+private:
+ std::string name;
+ BOOL use_substring;
+ //this member will be contain copy of founded items to keep the result unique
+ std::set<std::string> check_duplicate;
+
+public:
+LLFetchLandmarksByName(std::string &landmark_name, BOOL if_use_substring)
+:name(landmark_name),
+use_substring(if_use_substring)
+ {
+ LLStringUtil::toLower(name);
+ }
+
+public:
+ /*virtual*/ bool operator()(LLInventoryCategory* cat, LLInventoryItem* item)
+ {
+ if (!item || item->getType() != LLAssetType::AT_LANDMARK)
+ return false;
+
+ LLLandmark* landmark = gLandmarkList.getAsset(item->getAssetUUID());
+ if (!landmark) // the landmark not been loaded yet
+ return false;
+
+ bool acceptable = false;
+ std::string landmark_name = item->getName();
+ LLStringUtil::toLower(landmark_name);
+ if(use_substring)
+ {
+ acceptable = landmark_name.find( name ) != std::string::npos;
+ }
+ else
+ {
+ acceptable = landmark_name == name;
+ }
+ if(acceptable){
+ if(check_duplicate.find(landmark_name) != check_duplicate.end()){
+ // we have duplicated items in landmarks
+ acceptable = false;
+ }else{
+ check_duplicate.insert(landmark_name);
+ }
+ }
+
+ return acceptable;
+ }
+};
+
+LLInventoryModel::item_array_t LLLandmarkActions::fetchLandmarksByName(std::string& name, BOOL use_substring)
+{
+ LLInventoryModel::cat_array_t cats;
+ LLInventoryModel::item_array_t items;
+ LLFetchLandmarksByName fetchLandmarks(name, use_substring);
+ gInventory.collectDescendentsIf(gInventory.getRootFolderID(),
+ cats,
+ items,
+ LLInventoryModel::EXCLUDE_TRASH,
+ fetchLandmarks);
+ return items;
+}
+
+bool LLLandmarkActions::landmarkAlreadyExists()
+{
+ // Determine whether there are landmarks pointing to the current parcel.
+ LLInventoryModel::item_array_t items;
+ collectParcelLandmark(items);
+ return !items.empty();
+}
+
+
+LLViewerInventoryItem* LLLandmarkActions::findLandmarkForAgentParcel()
+{
+ // Determine whether there are landmarks pointing to the current parcel.
+ LLInventoryModel::cat_array_t cats;
+ LLInventoryModel::item_array_t items;
+ LLIsAgentParcelLandmark is_current_parcel_landmark;
+ gInventory.collectDescendentsIf(gInventory.getRootFolderID(),
+ cats,
+ items,
+ LLInventoryModel::EXCLUDE_TRASH,
+ is_current_parcel_landmark);
+
+ if(items.empty())
+ {
+ return NULL;
+ }
+
+ return items[0];
+}
+
+bool LLLandmarkActions::canCreateLandmarkHere()
+{
+ LLParcel* agent_parcel = LLViewerParcelMgr::getInstance()->getAgentParcel();
+ if(!agent_parcel)
+ {
+ llwarns << "No agent region" << llendl;
+ return false;
+ }
+ if (agent_parcel->getAllowLandmark()
+ || LLViewerParcelMgr::isParcelOwnedByAgent(agent_parcel, GP_LAND_ALLOW_LANDMARK))
+ {
+ return true;
+ }
+
+ return false;
+}
+
+void LLLandmarkActions::createLandmarkHere(
+ const std::string& name,
+ const std::string& desc,
+ const LLUUID& folder_id)
+{
+ if(!gAgent.getRegion())
+ {
+ llwarns << "No agent region" << llendl;
+ return;
+ }
+ LLParcel* agent_parcel = LLViewerParcelMgr::getInstance()->getAgentParcel();
+ if (!agent_parcel)
+ {
+ llwarns << "No agent parcel" << llendl;
+ return;
+ }
+ if (!canCreateLandmarkHere())
+ {
+ LLNotifications::instance().add("CannotCreateLandmarkNotOwner");
+ return;
+ }
+
+ create_inventory_item(gAgent.getID(), gAgent.getSessionID(),
+ folder_id, LLTransactionID::tnull,
+ name, desc,
+ LLAssetType::AT_LANDMARK,
+ LLInventoryType::IT_LANDMARK,
+ NOT_WEARABLE, PERM_ALL,
+ NULL);
+}
+
+void LLLandmarkActions::createLandmarkHere()
+{
+ std::string landmark_name, landmark_desc;
+
+ LLAgentUI::buildLocationString(landmark_name, LLAgentUI::LOCATION_FORMAT_LANDMARK);
+ LLAgentUI::buildLocationString(landmark_desc, LLAgentUI::LOCATION_FORMAT_FULL);
+ LLUUID folder_id = gInventory.findCategoryUUIDForType(LLAssetType::AT_LANDMARK);
+
+ createLandmarkHere(landmark_name, landmark_desc, folder_id);
+}
+
+void LLLandmarkActions::getSLURLfromPosGlobal(const LLVector3d& global_pos, slurl_callback_t cb, bool escaped /* = true */)
+{
+ std::string sim_name;
+ bool gotSimName = LLWorldMap::getInstance()->simNameFromPosGlobal(global_pos, sim_name);
+ if (gotSimName)
+ {
+ std::string slurl = LLSLURL::buildSLURLfromPosGlobal(sim_name, global_pos, escaped);
+ cb(slurl);
+
+ return;
+ }
+ else
+ {
+ U64 new_region_handle = to_region_handle(global_pos);
+
+ LLWorldMap::url_callback_t url_cb = boost::bind(&LLLandmarkActions::onRegionResponse,
+ cb,
+ global_pos,
+ escaped,
+ _1, _2, _3, _4);
+
+ LLWorldMap::getInstance()->sendHandleRegionRequest(new_region_handle, url_cb, std::string("unused"), false);
+ }
+}
+
+void LLLandmarkActions::onRegionResponse(slurl_callback_t cb,
+ const LLVector3d& global_pos,
+ bool escaped,
+ U64 region_handle,
+ const std::string& url,
+ const LLUUID& snapshot_id,
+ bool teleport)
+{
+ std::string sim_name;
+ std::string slurl;
+ bool gotSimName = LLWorldMap::getInstance()->simNameFromPosGlobal(global_pos, sim_name);
+ if (gotSimName)
+ {
+ slurl = LLSLURL::buildSLURLfromPosGlobal(sim_name, global_pos, escaped);
+ }
+ else
+ {
+ slurl = "";
+ }
+
+ cb(slurl);
+}
+
+bool LLLandmarkActions::getLandmarkGlobalPos(const LLUUID& landmarkInventoryItemID, LLVector3d& posGlobal)
+{
+ LLViewerInventoryItem* item = gInventory.getItem(landmarkInventoryItemID);
+ if (NULL == item)
+ return false;
+
+ const LLUUID& asset_id = item->getAssetUUID();
+ LLLandmark* landmark = gLandmarkList.getAsset(asset_id, NULL);
+
+ if (NULL == landmark)
+ return false;
+
+ return landmark->getGlobalPos(posGlobal);
+}
+
+void LLLandmarkActions::collectParcelLandmark(LLInventoryModel::item_array_t& items){
+ LLInventoryModel::cat_array_t cats;
+ LLIsAgentParcelLandmark is_current_parcel_landmark;
+ gInventory.collectDescendentsIf(gInventory.getRootFolderID(),
+ cats,
+ items,
+ LLInventoryModel::EXCLUDE_TRASH,
+ is_current_parcel_landmark);
+}
diff --git a/indra/newview/lllandmarkactions.h b/indra/newview/lllandmarkactions.h
new file mode 100644
index 0000000000..c74072c0f4
--- /dev/null
+++ b/indra/newview/lllandmarkactions.h
@@ -0,0 +1,116 @@
+/**
+ * @file lllandmarkactions.h
+ * @brief LLLandmark class declaration
+ *
+ * $LicenseInfo:firstyear=2000&license=viewergpl$
+ *
+ * Copyright (c) 2000-2009, Linden Research, Inc.
+ *
+ * Second Life Viewer Source Code
+ * The source code in this file ("Source Code") is provided by Linden Lab
+ * to you under the terms of the GNU General Public License, version 2.0
+ * ("GPL"), unless you have obtained a separate licensing agreement
+ * ("Other License"), formally executed by you and Linden Lab. Terms of
+ * the GPL can be found in doc/GPL-license.txt in this distribution, or
+ * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
+ *
+ * There are special exceptions to the terms and conditions of the GPL as
+ * it is applied to this Source Code. View the full text of the exception
+ * in the file doc/FLOSS-exception.txt in this software distribution, or
+ * online at
+ * http://secondlifegrid.net/programs/open_source/licensing/flossexception
+ *
+ * By copying, modifying or distributing this software, you acknowledge
+ * that you have read and understood your obligations described above,
+ * and agree to abide by those obligations.
+ *
+ * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+ * COMPLETENESS OR PERFORMANCE.
+ * $/LicenseInfo$
+ */
+
+#ifndef LL_LLLANDMARKACTIONS_H
+#define LL_LLLANDMARKACTIONS_H
+
+#include "llinventorymodel.h"
+
+/**
+ * @brief Provides helper functions to manage landmarks
+ */
+class LLLandmarkActions
+{
+public:
+ typedef boost::function<void(std::string& slurl)> slurl_callback_t;
+
+ /**
+ * @brief Fetches landmark LLViewerInventoryItems for the given landmark name.
+ */
+ static LLInventoryModel::item_array_t fetchLandmarksByName(std::string& name, BOOL if_use_substring);
+ /**
+ * @brief Checks whether landmark exists for current parcel.
+ */
+ static bool landmarkAlreadyExists();
+
+ /**
+ * @brief Searches landmark for parcel agent is currently in.
+ * @return Returns landmark for agent parcel or NULL.
+ *
+ * *TODO: dzaporozhan: There can be many landmarks for single parcel.
+ */
+ static LLViewerInventoryItem* findLandmarkForAgentParcel();
+
+ /**
+ * @brief Checks whether agent has rights to create landmark for current parcel.
+ */
+ static bool canCreateLandmarkHere();
+
+ /**
+ * @brief Creates landmark for current parcel.
+ */
+ static void createLandmarkHere();
+
+ /**
+ * @brief Creates landmark for current parcel.
+ */
+ static void createLandmarkHere(
+ const std::string& name,
+ const std::string& desc,
+ const LLUUID& folder_id);
+
+ /**
+ * @brief Trying to find in inventory a landmark of the current parcel.
+ * Normally items should contain only one item,
+ * because we can create the only landmark per parcel according to Navigation spec.
+ */
+ static void collectParcelLandmark(LLInventoryModel::item_array_t& items);
+
+ /**
+ * @brief Creates SLURL for given global position.
+ */
+ static void getSLURLfromPosGlobal(const LLVector3d& global_pos, slurl_callback_t cb, bool escaped = true);
+
+ /**
+ * @brief Gets landmark global position specified by inventory LLUUID.
+ * Found position is placed into "posGlobal" variable.
+ *.
+ * @return - true if specified item exists in Inventory and an appropriate landmark found.
+ * and its position is known, false otherwise.
+ */
+ // *TODO: mantipov: profide callback for cases, when Landmark is not loaded yet.
+ static bool getLandmarkGlobalPos(const LLUUID& landmarkInventoryItemID, LLVector3d& posGlobal);
+
+private:
+ LLLandmarkActions();
+ LLLandmarkActions(const LLLandmarkActions&);
+
+ static void onRegionResponse(slurl_callback_t cb,
+ const LLVector3d& global_pos,
+ bool escaped,
+ U64 region_handle,
+ const std::string& url,
+ const LLUUID& snapshot_id,
+ bool teleport);
+};
+
+#endif //LL_LLLANDMARKACTIONS_H
diff --git a/indra/newview/lllandmarklist.cpp b/indra/newview/lllandmarklist.cpp
index 2f43b41042..318344f9ef 100644
--- a/indra/newview/lllandmarklist.cpp
+++ b/indra/newview/lllandmarklist.cpp
@@ -54,7 +54,7 @@ LLLandmarkList::~LLLandmarkList()
std::for_each(mList.begin(), mList.end(), DeletePairedPointer());
}
-LLLandmark* LLLandmarkList::getAsset( const LLUUID& asset_uuid )
+LLLandmark* LLLandmarkList::getAsset(const LLUUID& asset_uuid, loaded_callback_t cb)
{
LLLandmark* landmark = get_ptr_in_map(mList, asset_uuid);
if(landmark)
@@ -65,6 +65,12 @@ LLLandmark* LLLandmarkList::getAsset( const LLUUID& asset_uuid )
{
if ( gLandmarkList.mBadList.find(asset_uuid) == gLandmarkList.mBadList.end() )
{
+ if (cb)
+ {
+ loaded_callback_map_t::value_type vt(asset_uuid, cb);
+ mLoadedCallbackMap.insert(vt);
+ }
+
gAssetStorage->getAssetData(
asset_uuid,
LLAssetType::AT_LANDMARK,
@@ -96,6 +102,8 @@ void LLLandmarkList::processGetAssetReply(
LLLandmark* landmark = LLLandmark::constructFromString(&buffer[0]);
if (landmark)
{
+ gLandmarkList.mList[ uuid ] = landmark;
+
LLVector3d pos;
if(!landmark->getGlobalPos(pos))
{
@@ -106,10 +114,15 @@ void LLLandmarkList::processGetAssetReply(
gMessageSystem,
gAgent.getRegionHost(),
region_id,
- NULL);
+ boost::bind(&LLLandmarkList::onRegionHandle, &gLandmarkList, uuid));
}
+
+ // the callback will be called when we get the region handle.
+ }
+ else
+ {
+ gLandmarkList.makeCallbacks(uuid);
}
- gLandmarkList.mList[ uuid ] = landmark;
}
}
else
@@ -134,3 +147,45 @@ BOOL LLLandmarkList::assetExists(const LLUUID& asset_uuid)
{
return mList.count(asset_uuid) != 0 || mBadList.count(asset_uuid) != 0;
}
+
+void LLLandmarkList::onRegionHandle(const LLUUID& landmark_id)
+{
+ LLLandmark* landmark = getAsset(landmark_id);
+
+ if (!landmark)
+ {
+ llwarns << "Got region handle but the landmark not found." << llendl;
+ return;
+ }
+
+ // Calculate landmark global position.
+ // This should succeed since the region handle is available.
+ LLVector3d pos;
+ if (!landmark->getGlobalPos(pos))
+ {
+ llwarns << "Got region handle but the landmark global position is still unknown." << llendl;
+ return;
+ }
+
+ makeCallbacks(landmark_id);
+}
+
+void LLLandmarkList::makeCallbacks(const LLUUID& landmark_id)
+{
+ LLLandmark* landmark = getAsset(landmark_id);
+
+ if (!landmark)
+ {
+ llwarns << "Landmark to make callbacks for not found." << llendl;
+ }
+
+ // make all the callbacks here.
+ loaded_callback_map_t::iterator it;
+ while((it = mLoadedCallbackMap.find(landmark_id)) != mLoadedCallbackMap.end())
+ {
+ if (landmark)
+ (*it).second(landmark);
+
+ mLoadedCallbackMap.erase(it);
+ }
+}
diff --git a/indra/newview/lllandmarklist.h b/indra/newview/lllandmarklist.h
index c41ba7a0f0..ebf1b65e97 100644
--- a/indra/newview/lllandmarklist.h
+++ b/indra/newview/lllandmarklist.h
@@ -33,6 +33,7 @@
#ifndef LL_LLLANDMARKLIST_H
#define LL_LLLANDMARKLIST_H
+#include <boost/function.hpp>
#include <map>
#include "lllandmark.h"
#include "lluuid.h"
@@ -45,6 +46,8 @@ class LLInventoryItem;
class LLLandmarkList
{
public:
+ typedef boost::function<void(LLLandmark*)> loaded_callback_t;
+
LLLandmarkList() {}
~LLLandmarkList();
@@ -53,7 +56,7 @@ public:
//const LLLandmark* getNext() { return mList.getNextData(); }
BOOL assetExists(const LLUUID& asset_uuid);
- LLLandmark* getAsset(const LLUUID& asset_uuid);
+ LLLandmark* getAsset(const LLUUID& asset_uuid, loaded_callback_t cb = NULL);
static void processGetAssetReply(
LLVFS *vfs,
const LLUUID& uuid,
@@ -63,11 +66,19 @@ public:
LLExtStat ext_status );
protected:
+ void onRegionHandle(const LLUUID& landmark_id);
+ void makeCallbacks(const LLUUID& landmark_id);
+
typedef std::map<LLUUID, LLLandmark*> landmark_list_t;
landmark_list_t mList;
typedef std::set<LLUUID> landmark_bad_list_t;
landmark_bad_list_t mBadList;
+
+ // *TODO: make the callback multimap a template class and make use of it
+ // here and in LLLandmark.
+ typedef std::multimap<LLUUID, loaded_callback_t> loaded_callback_map_t;
+ loaded_callback_map_t mLoadedCallbackMap;
};
diff --git a/indra/newview/lllistbrowser.cpp b/indra/newview/lllistbrowser.cpp
new file mode 100644
index 0000000000..edd8e9818f
--- /dev/null
+++ b/indra/newview/lllistbrowser.cpp
@@ -0,0 +1,37 @@
+/**
+ * @file lllistbrowser.cpp
+ * @brief UI widget showing a search filter, list view, icon action buttons,
+ * and verb action buttons, as usually embedded in the side tray.
+ *
+ * $LicenseInfo:firstyear=2009&license=viewergpl$
+ *
+ * Copyright (c) 2009, Linden Research, Inc.
+ *
+ * Second Life Viewer Source Code
+ * The source code in this file ("Source Code") is provided by Linden Lab
+ * to you under the terms of the GNU General Public License, version 2.0
+ * ("GPL"), unless you have obtained a separate licensing agreement
+ * ("Other License"), formally executed by you and Linden Lab. Terms of
+ * the GPL can be found in doc/GPL-license.txt in this distribution, or
+ * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
+ *
+ * There are special exceptions to the terms and conditions of the GPL as
+ * it is applied to this Source Code. View the full text of the exception
+ * in the file doc/FLOSS-exception.txt in this software distribution, or
+ * online at
+ * http://secondlifegrid.net/programs/open_source/licensing/flossexception
+ *
+ * By copying, modifying or distributing this software, you acknowledge
+ * that you have read and understood your obligations described above,
+ * and agree to abide by those obligations.
+ *
+ * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+ * COMPLETENESS OR PERFORMANCE.
+ * $/LicenseInfo$
+ */
+#include "llviewerprecompiledheaders.h"
+
+#include "lllistbrowser.h"
+
+// TODO
diff --git a/indra/newview/lllistbrowser.h b/indra/newview/lllistbrowser.h
new file mode 100644
index 0000000000..bc9498c514
--- /dev/null
+++ b/indra/newview/lllistbrowser.h
@@ -0,0 +1,36 @@
+/**
+ * @file lllistbrowser.h
+ * @brief UI widget showing a search filter, list view, icon action buttons,
+ * and verb action buttons, as usually embedded in the side tray.
+ *
+ * $LicenseInfo:firstyear=2009&license=viewergpl$
+ *
+ * Copyright (c) 2009, Linden Research, Inc.
+ *
+ * Second Life Viewer Source Code
+ * The source code in this file ("Source Code") is provided by Linden Lab
+ * to you under the terms of the GNU General Public License, version 2.0
+ * ("GPL"), unless you have obtained a separate licensing agreement
+ * ("Other License"), formally executed by you and Linden Lab. Terms of
+ * the GPL can be found in doc/GPL-license.txt in this distribution, or
+ * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
+ *
+ * There are special exceptions to the terms and conditions of the GPL as
+ * it is applied to this Source Code. View the full text of the exception
+ * in the file doc/FLOSS-exception.txt in this software distribution, or
+ * online at
+ * http://secondlifegrid.net/programs/open_source/licensing/flossexception
+ *
+ * By copying, modifying or distributing this software, you acknowledge
+ * that you have read and understood your obligations described above,
+ * and agree to abide by those obligations.
+ *
+ * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+ * COMPLETENESS OR PERFORMANCE.
+ * $/LicenseInfo$
+ */
+#ifndef LLLISTBROWSER_H
+#define LLLISTBROWSER_H
+
+#endif // LLLISTBROWSER_H
diff --git a/indra/newview/lllistview.cpp b/indra/newview/lllistview.cpp
new file mode 100644
index 0000000000..3019d5d3d5
--- /dev/null
+++ b/indra/newview/lllistview.cpp
@@ -0,0 +1,73 @@
+/**
+ * @file lllistview.cpp
+ * @brief UI widget containing a scrollable, possibly hierarchical list of
+ * folders (LLListViewFolder) and items (LLListViewItem).
+ *
+ * $LicenseInfo:firstyear=2009&license=viewergpl$
+ *
+ * Copyright (c) 2009, Linden Research, Inc.
+ *
+ * Second Life Viewer Source Code
+ * The source code in this file ("Source Code") is provided by Linden Lab
+ * to you under the terms of the GNU General Public License, version 2.0
+ * ("GPL"), unless you have obtained a separate licensing agreement
+ * ("Other License"), formally executed by you and Linden Lab. Terms of
+ * the GPL can be found in doc/GPL-license.txt in this distribution, or
+ * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
+ *
+ * There are special exceptions to the terms and conditions of the GPL as
+ * it is applied to this Source Code. View the full text of the exception
+ * in the file doc/FLOSS-exception.txt in this software distribution, or
+ * online at
+ * http://secondlifegrid.net/programs/open_source/licensing/flossexception
+ *
+ * By copying, modifying or distributing this software, you acknowledge
+ * that you have read and understood your obligations described above,
+ * and agree to abide by those obligations.
+ *
+ * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+ * COMPLETENESS OR PERFORMANCE.
+ * $/LicenseInfo$
+ */
+#include "llviewerprecompiledheaders.h"
+
+#include "lllistview.h"
+
+#include "lltextbox.h"
+#include "lluictrlfactory.h" // LLDefaultChildRegistry
+
+// linker optimizes this out on Windows until there is a real reference
+// to this file
+static LLDefaultChildRegistry::Register<LLListView> r("list_view");
+
+LLListView::Params::Params()
+: bg_color("bg_color"),
+ fg_selected_color("fg_selected_color"),
+ bg_selected_color("bg_selected_color")
+{}
+
+LLListView::LLListView(const Params& p)
+: LLUICtrl(p),
+ mLabel(NULL),
+ mBgColor(p.bg_color()),
+ mFgSelectedColor(p.fg_selected_color()),
+ mBgSelectedColor(p.bg_selected_color())
+{
+ LLRect label_rect(0, 20, 300, 0);
+ LLTextBox::Params text_box_params;
+ text_box_params.rect(label_rect);
+ text_box_params.text("This is a list-view");
+ mLabel = LLUICtrlFactory::create<LLTextBox>(text_box_params);
+ addChild(mLabel);
+}
+
+LLListView::~LLListView()
+{}
+
+
+// placeholder for setting a property
+void LLListView::setString(const std::string& s)
+{
+ mLabel->setValue( LLSD(s) );
+}
diff --git a/indra/newview/lllistview.h b/indra/newview/lllistview.h
new file mode 100644
index 0000000000..501c0c9e1f
--- /dev/null
+++ b/indra/newview/lllistview.h
@@ -0,0 +1,66 @@
+/**
+ * @file lllistview.h
+ * @brief UI widget containing a scrollable, possibly hierarchical list of
+ * folders (LLListViewFolder) and items (LLListViewItem).
+ *
+ * $LicenseInfo:firstyear=2009&license=viewergpl$
+ *
+ * Copyright (c) 2009, Linden Research, Inc.
+ *
+ * Second Life Viewer Source Code
+ * The source code in this file ("Source Code") is provided by Linden Lab
+ * to you under the terms of the GNU General Public License, version 2.0
+ * ("GPL"), unless you have obtained a separate licensing agreement
+ * ("Other License"), formally executed by you and Linden Lab. Terms of
+ * the GPL can be found in doc/GPL-license.txt in this distribution, or
+ * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
+ *
+ * There are special exceptions to the terms and conditions of the GPL as
+ * it is applied to this Source Code. View the full text of the exception
+ * in the file doc/FLOSS-exception.txt in this software distribution, or
+ * online at
+ * http://secondlifegrid.net/programs/open_source/licensing/flossexception
+ *
+ * By copying, modifying or distributing this software, you acknowledge
+ * that you have read and understood your obligations described above,
+ * and agree to abide by those obligations.
+ *
+ * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+ * COMPLETENESS OR PERFORMANCE.
+ * $/LicenseInfo$
+ */
+#ifndef LLLISTVIEW_H
+#define LLLISTVIEW_H
+
+#include "llui.h" // for LLUIColor, *TODO: use more specific header
+#include "lluictrl.h"
+
+class LLTextBox;
+
+class LLListView
+: public LLUICtrl
+{
+public:
+ struct Params : public LLInitParam::Block<Params, LLUICtrl::Params>
+ {
+ Optional<LLUIColor> bg_color,
+ fg_selected_color,
+ bg_selected_color;
+ Params();
+ };
+ LLListView(const Params& p);
+ virtual ~LLListView();
+
+ // placeholder for setting a property
+ void setString(const std::string& s);
+
+private:
+ // TODO: scroll container?
+ LLTextBox* mLabel; // just for testing
+ LLUIColor mBgColor;
+ LLUIColor mFgSelectedColor;
+ LLUIColor mBgSelectedColor;
+};
+
+#endif // LLLISTVIEW_H
diff --git a/indra/newview/lllocaltextureobject.cpp b/indra/newview/lllocaltextureobject.cpp
new file mode 100644
index 0000000000..e4a20aea68
--- /dev/null
+++ b/indra/newview/lllocaltextureobject.cpp
@@ -0,0 +1,149 @@
+/**
+ * @file lllocaltextureobject.cpp
+ *
+ * $LicenseInfo:firstyear=2009&license=viewergpl$
+ *
+ * Copyright (c) 2009-2009, Linden Research, Inc.
+ *
+ * Second Life Viewer Source Code
+ * The source code in this file ("Source Code") is provided by Linden Lab
+ * to you under the terms of the GNU General Public License, version 2.0
+ * ("GPL"), unless you have obtained a separate licensing agreement
+ * ("Other License"), formally executed by you and Linden Lab. Terms of
+ * the GPL can be found in doc/GPL-license.txt in this distribution, or
+ * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
+ *
+ * There are special exceptions to the terms and conditions of the GPL as
+ * it is applied to this Source Code. View the full text of the exception
+ * in the file doc/FLOSS-exception.txt in this software distribution, or
+ * online at
+ * http://secondlifegrid.net/programs/open_source/licensing/flossexception
+ *
+ * By copying, modifying or distributing this software, you acknowledge
+ * that you have read and understood your obligations described above,
+ * and agree to abide by those obligations.
+ *
+ * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+ * COMPLETENESS OR PERFORMANCE.
+ * $/LicenseInfo$
+ */
+
+#include "llviewerprecompiledheaders.h"
+
+#include "lllocaltextureobject.h"
+
+#include "lltexlayer.h"
+#include "llviewertexture.h"
+#include "lltextureentry.h"
+#include "lluuid.h"
+
+
+LLLocalTextureObject::LLLocalTextureObject() :
+ mIsBakedReady(FALSE),
+ mDiscard(MAX_DISCARD_LEVEL+1)
+{
+ mImage = NULL;
+}
+
+LLLocalTextureObject::LLLocalTextureObject(LLViewerFetchedTexture *image, LLTextureEntry *entry, LLTexLayer *layer, LLUUID id)
+{
+ if (entry)
+ {
+ LLTextureEntry * te = new LLTextureEntry(*entry);
+ mTexEntry = boost::shared_ptr<LLTextureEntry>(te);
+ }
+
+ if (layer)
+ {
+ LLTexLayer *texLayer = new LLTexLayer(*layer);
+ mTexLayer = boost::shared_ptr<LLTexLayer>(texLayer);
+ }
+ mImage = image;
+ mID = id;
+}
+
+LLLocalTextureObject::LLLocalTextureObject(const LLLocalTextureObject &lto) :
+mImage(lto.mImage),
+mTexEntry(lto.mTexEntry),
+mTexLayer(lto.mTexLayer),
+mID(lto.mID),
+mIsBakedReady(lto.mIsBakedReady),
+mDiscard(lto.mDiscard)
+{
+}
+
+LLLocalTextureObject::~LLLocalTextureObject()
+{
+}
+
+LLViewerFetchedTexture* LLLocalTextureObject::getImage() const
+{
+ return mImage;
+}
+
+LLTextureEntry* LLLocalTextureObject::getTexEntry() const
+{
+ return mTexEntry.get();
+}
+
+LLTexLayer* LLLocalTextureObject::getTexLayer() const
+{
+ return mTexLayer.get();
+}
+
+LLUUID LLLocalTextureObject::getID() const
+{
+ return mID;
+}
+
+S32 LLLocalTextureObject::getDiscard() const
+{
+ return mDiscard;
+}
+
+BOOL LLLocalTextureObject::getBakedReady() const
+{
+ return mIsBakedReady;
+}
+
+void LLLocalTextureObject::setImage(LLViewerFetchedTexture* new_image)
+{
+ mImage = new_image;
+}
+
+void LLLocalTextureObject::setTexEntry(LLTextureEntry *new_te)
+{
+ LLTextureEntry *ptr = NULL;
+ if (new_te)
+ {
+ ptr = new LLTextureEntry(*new_te);
+ }
+ mTexEntry = boost::shared_ptr<LLTextureEntry>(ptr);
+}
+
+void LLLocalTextureObject::setTexLayer(LLTexLayer *new_tex_layer)
+{
+ LLTexLayer *ptr = NULL;
+ if (new_tex_layer)
+ {
+ ptr = new LLTexLayer(*new_tex_layer);
+ }
+ mTexLayer = boost::shared_ptr<LLTexLayer>(ptr);
+}
+
+void LLLocalTextureObject::setID(LLUUID new_id)
+{
+ mID = new_id;
+}
+
+void LLLocalTextureObject::setDiscard(S32 new_discard)
+{
+ mDiscard = new_discard;
+}
+
+void LLLocalTextureObject::setBakedReady(BOOL ready)
+{
+ mIsBakedReady = ready;
+}
+
diff --git a/indra/newview/lllocaltextureobject.h b/indra/newview/lllocaltextureobject.h
new file mode 100644
index 0000000000..79e1562dce
--- /dev/null
+++ b/indra/newview/lllocaltextureobject.h
@@ -0,0 +1,85 @@
+/**
+ * @file lllocaltextureobject.h
+ * @brief LLLocalTextureObject class header file
+ *
+ * $LicenseInfo:firstyear=2009&license=viewergpl$
+ *
+ * Copyright (c) 2009-2009, Linden Research, Inc.
+ *
+ * Second Life Viewer Source Code
+ * The source code in this file ("Source Code") is provided by Linden Lab
+ * to you under the terms of the GNU General Public License, version 2.0
+ * ("GPL"), unless you have obtained a separate licensing agreement
+ * ("Other License"), formally executed by you and Linden Lab. Terms of
+ * the GPL can be found in doc/GPL-license.txt in this distribution, or
+ * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
+ *
+ * There are special exceptions to the terms and conditions of the GPL as
+ * it is applied to this Source Code. View the full text of the exception
+ * in the file doc/FLOSS-exception.txt in this software distribution, or
+ * online at
+ * http://secondlifegrid.net/programs/open_source/licensing/flossexception
+ *
+ * By copying, modifying or distributing this software, you acknowledge
+ * that you have read and understood your obligations described above,
+ * and agree to abide by those obligations.
+ *
+ * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+ * COMPLETENESS OR PERFORMANCE.
+ * $/LicenseInfo$
+ */
+
+#ifndef LL_LOCALTEXTUREOBJECT_H
+#define LL_LOCALTEXTUREOBJECT_H
+
+#include <boost/shared_ptr.hpp>
+
+class LLViewerFetchedTexture;
+class LLUUID;
+class LLTexLayer;
+class LLTextureEntry;
+
+// Stores all relevant information for a single texture
+// assumed to have ownership of all objects referred to -
+// will delete objects when being replaced or if object is destroyed.
+class LLLocalTextureObject
+{
+public:
+ LLLocalTextureObject();
+ LLLocalTextureObject(LLViewerFetchedTexture *image, LLTextureEntry *entry, LLTexLayer *layer, LLUUID id);
+ LLLocalTextureObject(const LLLocalTextureObject &lto);
+ ~LLLocalTextureObject();
+
+ LLViewerFetchedTexture* getImage() const;
+ LLTextureEntry* getTexEntry() const;
+ LLTexLayer* getTexLayer() const;
+ LLUUID getID() const;
+ S32 getDiscard() const;
+ BOOL getBakedReady() const;
+
+ void setImage(LLViewerFetchedTexture* new_image);
+ void setTexEntry(LLTextureEntry *new_te);
+ void setTexLayer(LLTexLayer *new_tex_layer);
+ void setID(LLUUID new_id);
+ void setDiscard(S32 new_discard);
+ void setBakedReady(BOOL ready);
+
+protected:
+
+private:
+
+ LLPointer<LLViewerFetchedTexture> mImage;
+ // NOTE: LLLocalTextureObject should be the exclusive owner of mTexEntry and mTexLayer
+ // using shared pointers here only for smart assignment & cleanup
+ // do NOT create new shared pointers to these objects, or keep pointers to them around
+ boost::shared_ptr<LLTextureEntry> mTexEntry;
+ boost::shared_ptr<LLTexLayer> mTexLayer;
+ LLUUID mID;
+
+ BOOL mIsBakedReady;
+ S32 mDiscard;
+};
+
+ #endif // LL_LOCALTEXTUREOBJECT_H
+
diff --git a/indra/newview/lllocationhistory.cpp b/indra/newview/lllocationhistory.cpp
new file mode 100644
index 0000000000..c83cde9d83
--- /dev/null
+++ b/indra/newview/lllocationhistory.cpp
@@ -0,0 +1,204 @@
+/**
+ * @file lllocationhistory.cpp
+ * @brief Typed locations history
+ *
+ * $LicenseInfo:firstyear=2009&license=viewergpl$
+ *
+ * Copyright (c) 2009, Linden Research, Inc.
+ *
+ * Second Life Viewer Source Code
+ * The source code in this file ("Source Code") is provided by Linden Lab
+ * to you under the terms of the GNU General Public License, version 2.0
+ * ("GPL"), unless you have obtained a separate licensing agreement
+ * ("Other License"), formally executed by you and Linden Lab. Terms of
+ * the GPL can be found in doc/GPL-license.txt in this distribution, or
+ * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
+ *
+ * There are special exceptions to the terms and conditions of the GPL as
+ * it is applied to this Source Code. View the full text of the exception
+ * in the file doc/FLOSS-exception.txt in this software distribution, or
+ * online at
+ * http://secondlifegrid.net/programs/open_source/licensing/flossexception
+ *
+ * By copying, modifying or distributing this software, you acknowledge
+ * that you have read and understood your obligations described above,
+ * and agree to abide by those obligations.
+ *
+ * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+ * COMPLETENESS OR PERFORMANCE.
+ * $/LicenseInfo$
+ */
+
+#include "llviewerprecompiledheaders.h"
+
+#include "lllocationhistory.h"
+
+#include <iomanip> // for std::setw()
+
+#include "llui.h"
+
+const char LLLocationHistory::delimiter = '\t';
+
+LLLocationHistory::LLLocationHistory() :
+ mFilename("typed_locations.txt")
+{
+}
+
+void LLLocationHistory::addItem(const std::string & item, const std::string & tooltip) {
+ static LLUICachedControl<S32> max_items("LocationHistoryMaxSize", 100);
+
+ // check if this item doesn't duplicate any existing one
+ std::vector<std::string>::iterator item_iter = std::find_if(mItems.begin(), mItems.end(),
+ boost::bind(&LLLocationHistory::equalByRegionParcel,this,_1,item));
+ if(item_iter != mItems.end()){
+ /*replace duplicate.
+ * If an item's region and item's parcel are equal.
+ */
+ mToolTips.erase(*item_iter);
+ mItems.erase(item_iter);
+
+ }
+
+ mItems.push_back(item);
+ mToolTips[item] = tooltip;
+
+ // If the vector size exceeds the maximum, purge the oldest items.
+ if ((S32)mItems.size() > max_items) {
+ for(std::vector<std::string>::iterator i = mItems.begin(); i != mItems.end()-max_items; ++i) {
+ mToolTips.erase(*i);
+ mItems.erase(i);
+ }
+ }
+}
+
+/**
+ * check if the history item is equal.
+ * @return true - if region name and parcel is equal.
+ */
+bool LLLocationHistory::equalByRegionParcel(const std::string& item, const std::string& newItem){
+
+
+ S32 itemIndex = item.find('(');
+ S32 newItemIndex = newItem.find('(');
+
+ std::string region_parcel = item.substr(0,itemIndex);
+ std::string new_region_parcel = newItem.substr(0,newItemIndex);
+
+ return region_parcel == new_region_parcel;
+}
+bool LLLocationHistory::touchItem(const std::string & item) {
+ bool result = false;
+ std::vector<std::string>::iterator item_iter = std::find(mItems.begin(), mItems.end(), item);
+
+ // the last used item should be the first in the history
+ if (item_iter != mItems.end()) {
+ mItems.erase(item_iter);
+ mItems.push_back(item);
+ result = true;
+ }
+
+ return result;
+}
+
+void LLLocationHistory::removeItems()
+{
+ mItems.clear();
+ mToolTips.clear();
+}
+
+std::string LLLocationHistory::getToolTip(const std::string & item) const {
+ std::map<std::string, std::string>::const_iterator i = mToolTips.find(item);
+
+ return i != mToolTips.end() ? i->second : "";
+}
+
+bool LLLocationHistory::getMatchingItems(std::string substring, location_list_t& result) const
+{
+ // *TODO: an STL algorithm would look nicer
+ result.clear();
+
+ std::string needle = substring;
+ LLStringUtil::toLower(needle);
+
+ for (location_list_t::const_iterator it = mItems.begin(); it != mItems.end(); ++it)
+ {
+ std::string haystack = *it;
+ LLStringUtil::toLower(haystack);
+
+ if (haystack.find(needle) != std::string::npos)
+ result.push_back(*it);
+ }
+
+ return result.size();
+}
+
+void LLLocationHistory::dump() const
+{
+ llinfos << "Location history dump:" << llendl;
+ int i = 0;
+ for (location_list_t::const_iterator it = mItems.begin(); it != mItems.end(); ++it, ++i)
+ {
+ llinfos << "#" << std::setw(2) << std::setfill('0') << i << ": " << *it << llendl;
+ }
+}
+
+void LLLocationHistory::save() const
+{
+ // build filename for each user
+ std::string resolved_filename = gDirUtilp->getExpandedFilename(LL_PATH_PER_SL_ACCOUNT, mFilename);
+
+ // open a file for writing
+ llofstream file (resolved_filename);
+ if (!file.is_open())
+ {
+ llwarns << "can't open location history file \"" << mFilename << "\" for writing" << llendl;
+ return;
+ }
+
+ for (location_list_t::const_iterator it = mItems.begin(); it != mItems.end(); ++it)
+ {
+ std::string tooltip = getToolTip(*it);
+ if(!tooltip.empty())
+ {
+ file << (*it) << delimiter << tooltip << std::endl;
+ }
+ }
+
+ file.close();
+}
+
+void LLLocationHistory::load()
+{
+ llinfos << "Loading location history." << llendl;
+
+ // build filename for each user
+ std::string resolved_filename = gDirUtilp->getExpandedFilename(LL_PATH_PER_SL_ACCOUNT, mFilename);
+ llifstream file(resolved_filename);
+
+ if (!file.is_open())
+ {
+ llwarns << "can't load location history from file \"" << mFilename << "\"" << llendl;
+ return;
+ }
+
+ removeItems();
+
+ // add each line in the file to the list
+ std::string line;
+
+ while (std::getline(file, line)) {
+ size_t dp = line.find(delimiter);
+
+ if (dp != std::string::npos) {
+ const std::string reg_name = line.substr(0, dp);
+ const std::string tooltip = line.substr(dp + 1, std::string::npos);
+
+ addItem(reg_name, tooltip);
+ }
+ }
+
+ file.close();
+
+ mLoadedSignal();
+}
diff --git a/indra/newview/lllocationhistory.h b/indra/newview/lllocationhistory.h
new file mode 100644
index 0000000000..060a6b2fe8
--- /dev/null
+++ b/indra/newview/lllocationhistory.h
@@ -0,0 +1,76 @@
+/**
+ * @file llocationhistory.h
+ * @brief Typed locations history
+ *
+ * $LicenseInfo:firstyear=2009&license=viewergpl$
+ *
+ * Copyright (c) 2009, Linden Research, Inc.
+ *
+ * Second Life Viewer Source Code
+ * The source code in this file ("Source Code") is provided by Linden Lab
+ * to you under the terms of the GNU General Public License, version 2.0
+ * ("GPL"), unless you have obtained a separate licensing agreement
+ * ("Other License"), formally executed by you and Linden Lab. Terms of
+ * the GPL can be found in doc/GPL-license.txt in this distribution, or
+ * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
+ *
+ * There are special exceptions to the terms and conditions of the GPL as
+ * it is applied to this Source Code. View the full text of the exception
+ * in the file doc/FLOSS-exception.txt in this software distribution, or
+ * online at
+ * http://secondlifegrid.net/programs/open_source/licensing/flossexception
+ *
+ * By copying, modifying or distributing this software, you acknowledge
+ * that you have read and understood your obligations described above,
+ * and agree to abide by those obligations.
+ *
+ * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+ * COMPLETENESS OR PERFORMANCE.
+ * $/LicenseInfo$
+ */
+
+#ifndef LL_LLLOCATIONHISTORY_H
+#define LL_LLLOCATIONHISTORY_H
+
+#include "llsingleton.h" // for LLSingleton
+
+#include <vector>
+#include <string>
+#include <map>
+#include <boost/function.hpp>
+
+class LLLocationHistory: public LLSingleton<LLLocationHistory>
+{
+ LOG_CLASS(LLLocationHistory);
+
+public:
+ typedef std::vector<std::string> location_list_t;
+ typedef boost::function<void()> loaded_callback_t;
+ typedef boost::signals2::signal<void()> loaded_signal_t;
+
+ LLLocationHistory();
+
+ void addItem(const std::string & item, const std::string & tooltip);
+ bool touchItem(const std::string & item);
+ void removeItems();
+ std::string getToolTip(const std::string & item) const;
+ size_t getItemCount() const { return mItems.size(); }
+ const location_list_t& getItems() const { return mItems; }
+ bool getMatchingItems(std::string substring, location_list_t& result) const;
+ boost::signals2::connection setLoadedCallback(loaded_callback_t cb) { return mLoadedSignal.connect(cb); }
+
+ void save() const;
+ void load();
+ void dump() const;
+
+private:
+ bool equalByRegionParcel(const std::string& item, const std::string& item_to_add);
+ const static char delimiter;
+ std::vector<std::string> mItems;
+ std::map<std::string, std::string> mToolTips;
+ std::string mFilename; /// File to store the history to.
+ loaded_signal_t mLoadedSignal;
+};
+
+#endif
diff --git a/indra/newview/lllocationinputctrl.cpp b/indra/newview/lllocationinputctrl.cpp
new file mode 100644
index 0000000000..a8ec826e88
--- /dev/null
+++ b/indra/newview/lllocationinputctrl.cpp
@@ -0,0 +1,688 @@
+/**
+ * @file lllocationinputctrl.cpp
+ * @brief Combobox-like location input control
+ *
+ * $LicenseInfo:firstyear=2009&license=viewergpl$
+ *
+ * Copyright (c) 2009, Linden Research, Inc.
+ *
+ * Second Life Viewer Source Code
+ * The source code in this file ("Source Code") is provided by Linden Lab
+ * to you under the terms of the GNU General Public License, version 2.0
+ * ("GPL"), unless you have obtained a separate licensing agreement
+ * ("Other License"), formally executed by you and Linden Lab. Terms of
+ * the GPL can be found in doc/GPL-license.txt in this distribution, or
+ * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
+ *
+ * There are special exceptions to the terms and conditions of the GPL as
+ * it is applied to this Source Code. View the full text of the exception
+ * in the file doc/FLOSS-exception.txt in this software distribution, or
+ * online at
+ * http://secondlifegrid.net/programs/open_source/licensing/flossexception
+ *
+ * By copying, modifying or distributing this software, you acknowledge
+ * that you have read and understood your obligations described above,
+ * and agree to abide by those obligations.
+ *
+ * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+ * COMPLETENESS OR PERFORMANCE.
+ * $/LicenseInfo$
+ */
+
+#include "llviewerprecompiledheaders.h"
+
+// file includes
+#include "lllocationinputctrl.h"
+
+// common includes
+#include "llbutton.h"
+#include "llfocusmgr.h"
+#include "llmenugl.h"
+#include "llstring.h"
+#include "lltrans.h"
+#include "lluictrlfactory.h"
+
+// newview includes
+#include "llinventorymodel.h"
+#include "lllandmarkactions.h"
+#include "lllandmarklist.h"
+#include "lllocationhistory.h"
+#include "llsidetray.h"
+#include "llslurl.h"
+#include "lltrans.h"
+#include "llviewerinventory.h"
+#include "llviewerparcelmgr.h"
+#include "llviewercontrol.h"
+#include "llviewermenu.h"
+#include "llurllineeditorctrl.h"
+#include "llagentui.h"
+
+//============================================================================
+/*
+ * "ADD LANDMARK" BUTTON UPDATING LOGIC
+ *
+ * If the current parcel has been landmarked, we should draw
+ * a special image on the button.
+ *
+ * To avoid determining the appropriate image on every draw() we do that
+ * only in the following cases:
+ * 1) Navbar is shown for the first time after login.
+ * 2) Agent moves to another parcel.
+ * 3) A landmark is created or removed.
+ *
+ * The first case is handled by the handleLoginComplete() method.
+ *
+ * The second case is handled by setting the "agent parcel changed" callback
+ * on LLViewerParcelMgr.
+ *
+ * The third case is the most complex one. We have two inventory observers for that:
+ * one is designated to handle adding landmarks, the other handles removal.
+ * Let's see how the former works.
+ *
+ * When we get notified about landmark addition, the landmark position is unknown yet. What we can
+ * do at that point is initiate loading the landmark data by LLLandmarkList and set the
+ * "loading finished" callback on it. Finally, when the callback is triggered,
+ * we can determine whether the landmark refers to a point within the current parcel
+ * and choose the appropriate image for the "Add landmark" button.
+ */
+
+/**
+ * Initiates loading the landmarks that have been just added.
+ *
+ * Once the loading is complete we'll be notified
+ * with the callback we set for LLLandmarkList.
+ */
+class LLAddLandmarkObserver : public LLInventoryAddedObserver
+{
+public:
+ LLAddLandmarkObserver(LLLocationInputCtrl* input) : mInput(input) {}
+
+private:
+ /*virtual*/ void done()
+ {
+ std::vector<LLUUID>::const_iterator it = mAdded.begin(), end = mAdded.end();
+ for(; it != end; ++it)
+ {
+ LLInventoryItem* item = gInventory.getItem(*it);
+ if (!item || item->getType() != LLAssetType::AT_LANDMARK)
+ continue;
+
+ // Start loading the landmark.
+ LLLandmark* lm = gLandmarkList.getAsset(
+ item->getAssetUUID(),
+ boost::bind(&LLLocationInputCtrl::onLandmarkLoaded, mInput, _1));
+ if (lm)
+ {
+ // Already loaded? Great, handle it immediately (the callback won't be called).
+ mInput->onLandmarkLoaded(lm);
+ }
+ }
+
+ mAdded.clear();
+ }
+
+ LLLocationInputCtrl* mInput;
+};
+
+/**
+ * Updates the "Add landmark" button once a landmark gets removed.
+ */
+class LLRemoveLandmarkObserver : public LLInventoryObserver
+{
+public:
+ LLRemoveLandmarkObserver(LLLocationInputCtrl* input) : mInput(input) {}
+
+private:
+ /*virtual*/ void changed(U32 mask)
+ {
+ if (mask & (~(LLInventoryObserver::LABEL|LLInventoryObserver::INTERNAL|LLInventoryObserver::ADD)))
+ {
+ mInput->updateAddLandmarkButton();
+ }
+ }
+
+ LLLocationInputCtrl* mInput;
+};
+
+//============================================================================
+
+
+static LLDefaultChildRegistry::Register<LLLocationInputCtrl> r("location_input");
+
+LLLocationInputCtrl::Params::Params()
+: add_landmark_image_enabled("add_landmark_image_enabled"),
+ add_landmark_image_disabled("add_landmark_image_disabled"),
+ add_landmark_image_hover("add_landmark_image_hover"),
+ add_landmark_image_selected("add_landmark_image_selected"),
+ add_landmark_button("add_landmark_button"),
+ add_landmark_hpad("add_landmark_hpad", 0),
+ info_button("info_button")
+{
+}
+
+LLLocationInputCtrl::LLLocationInputCtrl(const LLLocationInputCtrl::Params& p)
+: LLComboBox(p),
+ mAddLandmarkHPad(p.add_landmark_hpad),
+ mInfoBtn(NULL),
+ mLocationContextMenu(NULL),
+ mAddLandmarkBtn(NULL),
+ mLandmarkImageOn(NULL),
+ mLandmarkImageOff(NULL)
+{
+ // Lets replace default LLLineEditor with LLLocationLineEditor
+ // to make needed escaping while copying and cutting url
+ this->removeChild(mTextEntry);
+ delete mTextEntry;
+
+ // Can't access old mTextEntry fields as they are protected, so lets build new params
+ // That is C&P from LLComboBox::createLineEditor function
+ static LLUICachedControl<S32> drop_shadow_button ("DropShadowButton", 0);
+ S32 arrow_width = mArrowImage ? mArrowImage->getWidth() : 0;
+ LLRect text_entry_rect(0, getRect().getHeight(), getRect().getWidth(), 0);
+ text_entry_rect.mRight -= llmax(8,arrow_width) + 2 * drop_shadow_button;
+
+ LLLineEditor::Params params = p.combo_editor;
+ params.rect(text_entry_rect);
+ params.default_text(LLStringUtil::null);
+ params.max_length_bytes(p.max_chars);
+ params.commit_callback.function(boost::bind(&LLComboBox::onTextCommit, this, _2));
+ params.keystroke_callback(boost::bind(&LLComboBox::onTextEntry, this, _1));
+ params.focus_lost_callback(NULL);
+ params.handle_edit_keys_directly(true);
+ params.commit_on_focus_lost(false);
+ params.follows.flags(FOLLOWS_ALL);
+ mTextEntry = LLUICtrlFactory::create<LLURLLineEditor>(params);
+ this->addChild(mTextEntry);
+ // LLLineEditor is replaced with LLLocationLineEditor
+
+ // "Place information" button.
+ LLButton::Params info_params = p.info_button;
+ mInfoBtn = LLUICtrlFactory::create<LLButton>(info_params);
+ mInfoBtn->setClickedCallback(boost::bind(&LLLocationInputCtrl::onInfoButtonClicked, this));
+ addChild(mInfoBtn);
+
+ // "Add landmark" button.
+ LLButton::Params al_params = p.add_landmark_button;
+
+ // Image for unselected state will be set in updateAddLandmarkButton(),
+ // it will be either mLandmarkOn or mLandmarkOff
+ if (p.add_landmark_image_enabled())
+ {
+ mLandmarkImageOn = p.add_landmark_image_enabled;
+ }
+ if (p.add_landmark_image_disabled())
+ {
+ mLandmarkImageOff = p.add_landmark_image_disabled;
+ }
+
+ if(p.add_landmark_image_selected)
+ {
+ al_params.image_selected = p.add_landmark_image_selected;
+ }
+ if (p.add_landmark_image_hover())
+ {
+ al_params.image_hover_unselected = p.add_landmark_image_hover;
+ }
+
+ al_params.click_callback.function(boost::bind(&LLLocationInputCtrl::onAddLandmarkButtonClicked, this));
+ mAddLandmarkBtn = LLUICtrlFactory::create<LLButton>(al_params);
+ enableAddLandmarkButton(true);
+ addChild(mAddLandmarkBtn);
+
+ // Register callbacks and load the location field context menu (NB: the order matters).
+ LLUICtrl::CommitCallbackRegistry::currentRegistrar().add("Navbar.Action", boost::bind(&LLLocationInputCtrl::onLocationContextMenuItemClicked, this, _2));
+ LLUICtrl::EnableCallbackRegistry::currentRegistrar().add("Navbar.EnableMenuItem", boost::bind(&LLLocationInputCtrl::onLocationContextMenuItemEnabled, this, _2));
+
+ setPrearrangeCallback(boost::bind(&LLLocationInputCtrl::onLocationPrearrange, this, _2));
+ getTextEntry()->setMouseUpCallback(boost::bind(&LLLocationInputCtrl::changeLocationPresentation, this));
+
+ // Load the location field context menu
+ mLocationContextMenu = LLUICtrlFactory::getInstance()->createFromFile<LLMenuGL>("menu_navbar.xml", gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance());
+ if (!mLocationContextMenu)
+ {
+ llwarns << "Error loading navigation bar context menu" << llendl;
+
+ }
+ getTextEntry()->setRightMouseUpCallback(boost::bind(&LLLocationInputCtrl::onTextEditorRightClicked,this,_2,_3,_4));
+ updateWidgetlayout();
+
+ // - Make the "Add landmark" button updated when either current parcel gets changed
+ // or a landmark gets created or removed from the inventory.
+ // - Update the location string on parcel change.
+ mParcelMgrConnection = LLViewerParcelMgr::getInstance()->addAgentParcelChangedCallback(
+ boost::bind(&LLLocationInputCtrl::onAgentParcelChange, this));
+
+ mLocationHistoryConnection = LLLocationHistory::getInstance()->setLoadedCallback(
+ boost::bind(&LLLocationInputCtrl::onLocationHistoryLoaded, this));
+
+ mRemoveLandmarkObserver = new LLRemoveLandmarkObserver(this);
+ mAddLandmarkObserver = new LLAddLandmarkObserver(this);
+ gInventory.addObserver(mRemoveLandmarkObserver);
+ gInventory.addObserver(mAddLandmarkObserver);
+
+ mAddLandmarkTooltip = LLTrans::getString("location_ctrl_add_landmark");
+ mEditLandmarkTooltip = LLTrans::getString("location_ctrl_edit_landmark");
+}
+
+LLLocationInputCtrl::~LLLocationInputCtrl()
+{
+ gInventory.removeObserver(mRemoveLandmarkObserver);
+ gInventory.removeObserver(mAddLandmarkObserver);
+ delete mRemoveLandmarkObserver;
+ delete mAddLandmarkObserver;
+
+ mParcelMgrConnection.disconnect();
+ mLocationHistoryConnection.disconnect();
+}
+
+void LLLocationInputCtrl::setEnabled(BOOL enabled)
+{
+ LLComboBox::setEnabled(enabled);
+ mAddLandmarkBtn->setEnabled(enabled);
+}
+
+void LLLocationInputCtrl::hideList()
+{
+ LLComboBox::hideList();
+ if (mTextEntry && hasFocus())
+ focusTextEntry();
+}
+
+BOOL LLLocationInputCtrl::handleToolTip(S32 x, S32 y, std::string& msg, LLRect* sticky_rect_screen)
+{
+ // Let the buttons show their tooltips.
+ if (LLUICtrl::handleToolTip(x, y, msg, sticky_rect_screen) && !msg.empty())
+ {
+ if (mList->getRect().pointInRect(x, y)) {
+ LLLocationHistory* lh = LLLocationHistory::getInstance();
+ const std::string tooltip = lh->getToolTip(msg);
+
+ if (!tooltip.empty()) {
+ msg = tooltip;
+ }
+ }
+
+ return TRUE;
+ }
+
+ msg = LLUI::sShowXUINames ? getShowNamesToolTip() : "";
+ return mTextEntry->getRect().pointInRect(x, y);
+}
+
+BOOL LLLocationInputCtrl::handleKeyHere(KEY key, MASK mask)
+{
+ BOOL result = LLComboBox::handleKeyHere(key, mask);
+
+ if (key == KEY_DOWN && hasFocus() && mList->getItemCount() != 0)
+ {
+ showList();
+ }
+
+ return result;
+}
+
+void LLLocationInputCtrl::onTextEntry(LLLineEditor* line_editor)
+{
+ KEY key = gKeyboard->currentKey();
+
+ if (line_editor->getText().empty())
+ {
+ prearrangeList(); // resets filter
+ hideList();
+ }
+ // Typing? (moving cursor should not affect showing the list)
+ else if (key != KEY_LEFT && key != KEY_RIGHT && key != KEY_HOME && key != KEY_END)
+ {
+ prearrangeList(line_editor->getText());
+ if (mList->getItemCount() != 0)
+ {
+ showList();
+ focusTextEntry();
+ }
+ else
+ {
+ // Hide the list if it's empty.
+ hideList();
+ }
+ }
+
+ LLComboBox::onTextEntry(line_editor);
+}
+
+/**
+ * Useful if we want to just set the text entry value, no matter what the list contains.
+ *
+ * This is faster than setTextEntry().
+ */
+void LLLocationInputCtrl::setText(const LLStringExplicit& text)
+{
+ if (mTextEntry)
+ {
+ mTextEntry->setText(text);
+ mHasAutocompletedText = FALSE;
+ }
+}
+
+void LLLocationInputCtrl::setFocus(BOOL b)
+{
+ LLComboBox::setFocus(b);
+
+ if (mTextEntry && b && !mList->getVisible())
+ mTextEntry->setFocus(TRUE);
+}
+
+void LLLocationInputCtrl::handleLoginComplete()
+{
+ // An agent parcel update hasn't occurred yet, so we have to
+ // manually set location and the appropriate "Add landmark" icon.
+ refresh();
+}
+
+//== private methods =========================================================
+
+void LLLocationInputCtrl::onFocusReceived()
+{
+ prearrangeList();
+}
+
+void LLLocationInputCtrl::onFocusLost()
+{
+ LLUICtrl::onFocusLost();
+ refreshLocation();
+ if(mTextEntry->hasSelection()){
+ mTextEntry->deselect();
+ }
+}
+void LLLocationInputCtrl::draw(){
+
+ if(!hasFocus() && gSavedSettings.getBOOL("ShowCoordinatesOption")){
+ refreshLocation();
+ }
+ LLComboBox::draw();
+}
+
+void LLLocationInputCtrl::onInfoButtonClicked()
+{
+ LLSideTray::getInstance()->showPanel("panel_places", LLSD().insert("type", "agent"));
+}
+
+void LLLocationInputCtrl::onAddLandmarkButtonClicked()
+{
+ LLViewerInventoryItem* landmark = LLLandmarkActions::findLandmarkForAgentParcel();
+
+ // Landmark exists, open it for preview and edit
+ if(landmark && landmark->getUUID().notNull())
+ {
+ LLSD key;
+ key["type"] = "landmark";
+ key["id"] = landmark->getUUID();
+
+ LLSideTray::getInstance()->showPanel("panel_places", key);
+ }
+ else
+ {
+ LLSideTray::getInstance()->showPanel("panel_places", LLSD().insert("type", "create_landmark"));
+ }
+}
+
+void LLLocationInputCtrl::onAgentParcelChange()
+{
+ refresh();
+}
+
+void LLLocationInputCtrl::onLandmarkLoaded(LLLandmark* lm)
+{
+ (void) lm;
+ updateAddLandmarkButton();
+}
+
+void LLLocationInputCtrl::onLocationHistoryLoaded()
+{
+ rebuildLocationHistory();
+}
+
+void LLLocationInputCtrl::onLocationPrearrange(const LLSD& data)
+{
+ std::string filter = data.asString();
+ rebuildLocationHistory(filter);
+
+ //Let's add landmarks to the top of the list if any
+ if( filter.size() !=0 )
+ {
+ LLInventoryModel::item_array_t landmark_items = LLLandmarkActions::fetchLandmarksByName(filter, TRUE);
+
+ for(U32 i=0; i < landmark_items.size(); i++)
+ {
+ mList->addSimpleElement(landmark_items[i]->getName(), ADD_TOP);
+ }
+ }
+ mList->mouseOverHighlightNthItem(-1); // Clear highlight on the last selected item.
+}
+
+void LLLocationInputCtrl::onTextEditorRightClicked(S32 x, S32 y, MASK mask)
+{
+ if (mLocationContextMenu)
+ {
+ updateContextMenu();
+ mLocationContextMenu->buildDrawLabels();
+ mLocationContextMenu->updateParent(LLMenuGL::sMenuContainer);
+ hideList();
+ setFocus(true);
+ changeLocationPresentation();
+ LLMenuGL::showPopup(this, mLocationContextMenu, x, y);
+ }
+}
+
+void LLLocationInputCtrl::refresh()
+{
+ refreshLocation(); // update location string
+ updateAddLandmarkButton(); // indicate whether current parcel has been landmarked
+}
+
+void LLLocationInputCtrl::refreshLocation()
+{
+ // Is one of our children focused?
+ if (LLUICtrl::hasFocus() || mButton->hasFocus() || mList->hasFocus() ||
+ (mTextEntry && mTextEntry->hasFocus()) || (mAddLandmarkBtn->hasFocus()))
+
+ {
+ llwarns << "Location input should not be refreshed when having focus" << llendl;
+ return;
+ }
+
+ // Update location field.
+ std::string location_name;
+ LLAgentUI::ELocationFormat format = (gSavedSettings.getBOOL("ShowCoordinatesOption") ?
+ LLAgentUI::LOCATION_FORMAT_WITHOUT_SIM: LLAgentUI::LOCATION_FORMAT_NORMAL);
+
+ if (!LLAgentUI::buildLocationString(location_name, format)) location_name = "Unknown";
+ setText(location_name);
+}
+
+void LLLocationInputCtrl::rebuildLocationHistory(std::string filter)
+{
+ LLLocationHistory::location_list_t filtered_items;
+ const LLLocationHistory::location_list_t* itemsp = NULL;
+ LLLocationHistory* lh = LLLocationHistory::getInstance();
+
+ if (filter.empty())
+ {
+ itemsp = &lh->getItems();
+ }
+ else
+ {
+ lh->getMatchingItems(filter, filtered_items);
+ itemsp = &filtered_items;
+ }
+
+ removeall();
+ for (LLLocationHistory::location_list_t::const_reverse_iterator it = itemsp->rbegin(); it != itemsp->rend(); it++)
+ {
+ add(*it);
+ }
+}
+
+void LLLocationInputCtrl::focusTextEntry()
+{
+ // We can't use "mTextEntry->setFocus(TRUE)" instead because
+ // if the "select_on_focus" parameter is true it places the cursor
+ // at the beginning (after selecting text), thus screwing up updateSelection().
+ if (mTextEntry)
+ gFocusMgr.setKeyboardFocus(mTextEntry);
+}
+
+void LLLocationInputCtrl::enableAddLandmarkButton(bool val)
+{
+ // We don't want to disable the button because it should be click able at any time,
+ // instead switch images.
+ LLUIImage* img = val ? mLandmarkImageOn : mLandmarkImageOff;
+ if(img)
+ {
+ mAddLandmarkBtn->setImageUnselected(img);
+ }
+}
+
+// Change the "Add landmark" button image
+// depending on whether current parcel has been landmarked.
+void LLLocationInputCtrl::updateAddLandmarkButton()
+{
+ bool landmark_exists = LLLandmarkActions::landmarkAlreadyExists();
+ enableAddLandmarkButton(!landmark_exists);
+
+ std::string tooltip;
+ if(landmark_exists)
+ {
+ tooltip = mEditLandmarkTooltip;
+ }
+ else
+ {
+ tooltip = mAddLandmarkTooltip;
+ }
+ mAddLandmarkBtn->setToolTip(tooltip);
+}
+
+void LLLocationInputCtrl::updateContextMenu(){
+
+ if (mLocationContextMenu)
+ {
+ LLMenuItemGL* landmarkItem = mLocationContextMenu->getChild<LLMenuItemGL>("Landmark");
+ if (!LLLandmarkActions::landmarkAlreadyExists())
+ {
+ landmarkItem->setLabel(LLTrans::getString("AddLandmarkNavBarMenu"));
+ }
+ else
+ {
+ landmarkItem->setLabel(LLTrans::getString("EditLandmarkNavBarMenu"));
+ }
+ }
+}
+void LLLocationInputCtrl::updateWidgetlayout()
+{
+ const LLRect& rect = getLocalRect();
+ const LLRect& hist_btn_rect = mButton->getRect();
+ LLRect info_btn_rect = mInfoBtn->getRect();
+
+ // info button
+ info_btn_rect.setOriginAndSize(
+ 2, (rect.getHeight() - info_btn_rect.getHeight()) / 2,
+ info_btn_rect.getWidth(), info_btn_rect.getHeight());
+ mInfoBtn->setRect(info_btn_rect);
+
+ // "Add Landmark" button
+ {
+ LLRect al_btn_rect = mAddLandmarkBtn->getRect();
+ al_btn_rect.translate(
+ hist_btn_rect.mLeft - mAddLandmarkHPad - al_btn_rect.getWidth(),
+ (rect.getHeight() - al_btn_rect.getHeight()) / 2);
+ mAddLandmarkBtn->setRect(al_btn_rect);
+ }
+}
+
+void LLLocationInputCtrl::changeLocationPresentation()
+{
+ //change location presentation only if user does not select anything and
+ //human-readable region name is being displayed
+ if(mTextEntry && !mTextEntry->hasSelection() &&
+ !LLSLURL::isSLURL(mTextEntry->getText()))
+ {
+ //needs unescaped one
+ mTextEntry->setText(LLAgentUI::buildSLURL(false));
+ mTextEntry->selectAll();
+ }
+}
+
+void LLLocationInputCtrl::onLocationContextMenuItemClicked(const LLSD& userdata)
+{
+ std::string item = userdata.asString();
+
+ if (item == std::string("show_coordinates"))
+ {
+ gSavedSettings.setBOOL("ShowCoordinatesOption",!gSavedSettings.getBOOL("ShowCoordinatesOption"));
+ }
+ else if (item == std::string("landmark"))
+ {
+ LLInventoryModel::item_array_t items;
+ LLLandmarkActions::collectParcelLandmark(items);
+
+ if(items.empty())
+ {
+ LLSideTray::getInstance()->showPanel("panel_places", LLSD().insert("type", "create_landmark"));
+ }else{
+ LLSideTray::getInstance()->showPanel("panel_places",
+ LLSD().insert("type", "landmark").insert("id",items.get(0)->getUUID()));
+ }
+ }
+ else if (item == std::string("cut"))
+ {
+ mTextEntry->cut();
+ }
+ else if (item == std::string("copy"))
+ {
+ mTextEntry->copy();
+ }
+ else if (item == std::string("paste"))
+ {
+ mTextEntry->paste();
+ }
+ else if (item == std::string("delete"))
+ {
+ mTextEntry->deleteSelection();
+ }
+ else if (item == std::string("select_all"))
+ {
+ mTextEntry->selectAll();
+ }
+}
+
+bool LLLocationInputCtrl::onLocationContextMenuItemEnabled(const LLSD& userdata)
+{
+ std::string item = userdata.asString();
+
+ if (item == std::string("can_cut"))
+ {
+ return mTextEntry->canCut();
+ }
+ else if (item == std::string("can_copy"))
+ {
+ return mTextEntry->canCopy();
+ }
+ else if (item == std::string("can_paste"))
+ {
+ return mTextEntry->canPaste();
+ }
+ else if (item == std::string("can_delete"))
+ {
+ return mTextEntry->canDeselect();
+ }
+ else if (item == std::string("can_select_all"))
+ {
+ return mTextEntry->canSelectAll();
+ }
+ else if(item == std::string("show_coordinates")){
+
+ return gSavedSettings.getBOOL("ShowCoordinatesOption");
+ }
+
+ return false;
+}
diff --git a/indra/newview/lllocationinputctrl.h b/indra/newview/lllocationinputctrl.h
new file mode 100644
index 0000000000..d967df8257
--- /dev/null
+++ b/indra/newview/lllocationinputctrl.h
@@ -0,0 +1,140 @@
+/**
+ * @file lllocationinputctrl.h
+ * @brief Combobox-like location input control
+ *
+ * $LicenseInfo:firstyear=2009&license=viewergpl$
+ *
+ * Copyright (c) 2009, Linden Research, Inc.
+ *
+ * Second Life Viewer Source Code
+ * The source code in this file ("Source Code") is provided by Linden Lab
+ * to you under the terms of the GNU General Public License, version 2.0
+ * ("GPL"), unless you have obtained a separate licensing agreement
+ * ("Other License"), formally executed by you and Linden Lab. Terms of
+ * the GPL can be found in doc/GPL-license.txt in this distribution, or
+ * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
+ *
+ * There are special exceptions to the terms and conditions of the GPL as
+ * it is applied to this Source Code. View the full text of the exception
+ * in the file doc/FLOSS-exception.txt in this software distribution, or
+ * online at
+ * http://secondlifegrid.net/programs/open_source/licensing/flossexception
+ *
+ * By copying, modifying or distributing this software, you acknowledge
+ * that you have read and understood your obligations described above,
+ * and agree to abide by those obligations.
+ *
+ * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+ * COMPLETENESS OR PERFORMANCE.
+ * $/LicenseInfo$
+ */
+
+#ifndef LL_LLLOCATIONINPUTCTRL_H
+#define LL_LLLOCATIONINPUTCTRL_H
+
+#include <llcombobox.h>
+
+class LLLandmark;
+
+// internals
+class LLAddLandmarkObserver;
+class LLRemoveLandmarkObserver;
+class LLMenuGL;
+
+/**
+ * Location input control.
+ *
+ * @see LLNavigationBar
+ */
+class LLLocationInputCtrl
+: public LLComboBox
+{
+ LOG_CLASS(LLLocationInputCtrl);
+ friend class LLAddLandmarkObserver;
+ friend class LLRemoveLandmarkObserver;
+
+public:
+ struct Params
+ : public LLInitParam::Block<Params, LLComboBox::Params>
+ {
+ Optional<LLUIImage*> add_landmark_image_enabled,
+ add_landmark_image_disabled,
+ add_landmark_image_hover,
+ add_landmark_image_selected;
+ Optional<S32> add_landmark_hpad;
+ Optional<LLButton::Params> add_landmark_button,
+ info_button;
+ Params();
+ };
+
+ // LLView interface
+ /*virtual*/ void setEnabled(BOOL enabled);
+ /*virtual*/ BOOL handleToolTip(S32 x, S32 y, std::string& msg, LLRect* sticky_rect);
+ /*virtual*/ BOOL handleKeyHere(KEY key, MASK mask);
+ /*virtual*/ void onFocusReceived();
+ /*virtual*/ void onFocusLost();
+ /*virtual*/ void draw();
+ //========================================================================
+
+ // LLUICtrl interface
+ /*virtual*/ void setFocus(BOOL b);
+ //========================================================================
+
+ // LLComboBox interface
+ void hideList();
+ void onTextEntry(LLLineEditor* line_editor);
+ //========================================================================
+
+ LLLineEditor* getTextEntry() const { return mTextEntry; }
+ void handleLoginComplete();
+
+private:
+ friend class LLUICtrlFactory;
+ LLLocationInputCtrl(const Params&);
+ virtual ~LLLocationInputCtrl();
+
+ void focusTextEntry();
+ /**
+ * Changes the "Add landmark" button image
+ * depending on whether current parcel has been landmarked.
+ */
+ void enableAddLandmarkButton(bool val);
+ void refresh();
+ void refreshLocation();
+ void rebuildLocationHistory(std::string filter = "");
+ void setText(const LLStringExplicit& text);
+ void updateAddLandmarkButton();
+ void updateContextMenu();
+ void updateWidgetlayout();
+ void changeLocationPresentation();
+
+ void onInfoButtonClicked();
+ void onLocationHistoryLoaded();
+ void onLocationPrearrange(const LLSD& data);
+ void onTextEditorRightClicked(S32 x, S32 y, MASK mask);
+ void onLandmarkLoaded(LLLandmark* lm);
+ void onAddLandmarkButtonClicked();
+ void onAgentParcelChange();
+ // callbacks
+ bool onLocationContextMenuItemEnabled(const LLSD& userdata);
+ void onLocationContextMenuItemClicked(const LLSD& userdata);
+
+ LLMenuGL* mLocationContextMenu;
+ LLButton* mAddLandmarkBtn;
+ LLButton* mInfoBtn;
+ S32 mAddLandmarkHPad;
+
+ LLAddLandmarkObserver* mAddLandmarkObserver;
+ LLRemoveLandmarkObserver* mRemoveLandmarkObserver;
+
+ boost::signals2::connection mParcelMgrConnection;
+ boost::signals2::connection mLocationHistoryConnection;
+ LLUIImage* mLandmarkImageOn;
+ LLUIImage* mLandmarkImageOff;
+
+ std::string mAddLandmarkTooltip;
+ std::string mEditLandmarkTooltip;
+};
+
+#endif
diff --git a/indra/newview/lllogchat.cpp b/indra/newview/lllogchat.cpp
index 1709d6465d..69214b5cab 100644
--- a/indra/newview/lllogchat.cpp
+++ b/indra/newview/lllogchat.cpp
@@ -35,6 +35,7 @@
#include "lllogchat.h"
#include "llappviewer.h"
#include "llfloaterchat.h"
+#include "lltrans.h"
const S32 LOG_RECALL_SIZE = 2048;
@@ -64,20 +65,26 @@ std::string LLLogChat::timestamp(bool withdate)
time_t utc_time;
utc_time = time_corrected();
- // There's only one internal tm buffer.
- struct tm* timep;
+ std::string timeStr;
+ LLSD substitution;
+ substitution["datetime"] = (S32) utc_time;
- // Convert to Pacific, based on server's opinion of whether
- // it's daylight savings time there.
- timep = utc_to_pacific_time(utc_time, gPacificDaylightTime);
-
- std::string text;
if (withdate)
- text = llformat("[%d/%02d/%02d %d:%02d] ", (timep->tm_year-100)+2000, timep->tm_mon+1, timep->tm_mday, timep->tm_hour, timep->tm_min);
+ {
+ timeStr = "["+LLTrans::getString ("TimeYear")+"]/["
+ +LLTrans::getString ("TimeMonth")+"]/["
+ +LLTrans::getString ("TimeDay")+"] ["
+ +LLTrans::getString ("TimeHour")+"]:["
+ +LLTrans::getString ("TimeMin")+"] ";
+ }
else
- text = llformat("[%d:%02d] ", timep->tm_hour, timep->tm_min);
+ {
+ timeStr = "[" + LLTrans::getString("TimeHour") + "]:["
+ + LLTrans::getString ("TimeMin")+"] ";
+ }
- return text;
+ LLStringUtil::format (timeStr, substitution);
+ return timeStr;
}
@@ -114,7 +121,7 @@ void LLLogChat::loadHistory(std::string filename , void (*callback)(ELogLineType
LLFILE* fptr = LLFile::fopen(makeLogFileName(filename), "r"); /*Flawfinder: ignore*/
if (!fptr)
{
- //LLUIString message = LLFloaterChat::getInstance()->getString("IM_logging_string");
+ //LLUIString message = LLTrans::getString("IM_logging_string");
//callback(LOG_EMPTY,"IM_logging_string",userdata);
callback(LOG_EMPTY,LLStringUtil::null,userdata);
return; //No previous conversation with this name.
diff --git a/indra/newview/llloginhandler.cpp b/indra/newview/llloginhandler.cpp
index 053f798882..6f0b8a3c1e 100644
--- a/indra/newview/llloginhandler.cpp
+++ b/indra/newview/llloginhandler.cpp
@@ -156,21 +156,15 @@ void LLLoginHandler::parse(const LLSD& queryMap)
{
LLURLSimString::setString(queryMap["region"].asString());
}
- else if (startLocation == "home")
+ else if (!startLocation.empty()) // "last" or "home" or ??? (let LLURLSimString figure it out)
{
- gSavedSettings.setBOOL("LoginLastLocation", FALSE);
- LLURLSimString::setString(LLStringUtil::null);
- }
- else if (startLocation == "last")
- {
- gSavedSettings.setBOOL("LoginLastLocation", TRUE);
- LLURLSimString::setString(LLStringUtil::null);
+ LLURLSimString::setString(startLocation);
}
}
bool LLLoginHandler::handle(const LLSD& tokens,
const LLSD& query_map,
- LLWebBrowserCtrl* web)
+ LLMediaCtrl* web)
{
parse(query_map);
diff --git a/indra/newview/llloginhandler.h b/indra/newview/llloginhandler.h
index c76d7e8274..0844b80c7c 100644
--- a/indra/newview/llloginhandler.h
+++ b/indra/newview/llloginhandler.h
@@ -40,7 +40,7 @@ class LLLoginHandler : public LLCommandHandler
public:
// allow from external browsers
LLLoginHandler() : LLCommandHandler("login", false) { }
- /*virtual*/ bool handle(const LLSD& tokens, const LLSD& query_map, LLWebBrowserCtrl* web);
+ /*virtual*/ bool handle(const LLSD& tokens, const LLSD& query_map, LLMediaCtrl* web);
// Fill in our internal fields from a SLURL like
// secondlife:///app/login?first=Bob&last=Dobbs
diff --git a/indra/newview/lllookshistorypanel.h b/indra/newview/lllookshistorypanel.h
new file mode 100644
index 0000000000..986c9a1c4d
--- /dev/null
+++ b/indra/newview/lllookshistorypanel.h
@@ -0,0 +1,72 @@
+/**
+ * @file llpanelteleporthistory.h
+ * @brief Teleport history represented by a scrolling list
+ * class definition
+ *
+ * $LicenseInfo:firstyear=2009&license=viewergpl$
+ *
+ * Copyright (c) 2001-2009, Linden Research, Inc.
+ *
+ * Second Life Viewer Source Code
+ * The source code in this file ("Source Code") is provided by Linden Lab
+ * to you under the terms of the GNU General Public License, version 2.0
+ * ("GPL"), unless you have obtained a separate licensing agreement
+ * ("Other License"), formally executed by you and Linden Lab. Terms of
+ * the GPL can be found in doc/GPL-license.txt in this distribution, or
+ * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
+ *
+ * There are special exceptions to the terms and conditions of the GPL as
+ * it is applied to this Source Code. View the full text of the exception
+ * in the file doc/FLOSS-exception.txt in this software distribution, or
+ * online at http://secondlifegrid.net/programs/open_source/licensing/flossexception
+ *
+ * By copying, modifying or distributing this software, you acknowledge
+ * that you have read and understood your obligations described above,
+ * and agree to abide by those obligations.
+ *
+ * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+ * COMPLETENESS OR PERFORMANCE.
+ * $/LicenseInfo$
+ */
+
+#ifndef LL_LLPANELLOOKSHISTORY_H
+#define LL_LLPANELLOOKSHISTORY_H
+
+#include "lluictrlfactory.h"
+#include "llscrolllistctrl.h"
+
+#include "llpanelappearancetab.h"
+#include "lllookshistory.h"
+
+class LLLooksHistoryPanel : public LLPanelAppearanceTab
+{
+public:
+ LLLooksHistoryPanel();
+ virtual ~LLLooksHistoryPanel();
+
+ /*virtual*/ BOOL postBuild();
+ /*virtual*/ void onSearchEdit(const std::string& string);
+ /*virtual*/ void onShowOnMap();
+ /*virtual*/ void onLooks();
+ ///*virtual*/ void onCopySLURL();
+
+ void showLooksHistory();
+ void handleItemSelect(const LLSD& data);
+
+ static void onDoubleClickItem(void* user_data);
+
+private:
+ enum LOOKS_HISTORY_COLUMN_ORDER
+ {
+ LIST_ICON,
+ LIST_ITEM_TITLE,
+ LIST_INDEX
+ };
+
+ LLLooksHistory* mLooksHistory;
+ LLScrollListCtrl* mHistoryItems;
+ std::string mFilterSubString;
+};
+
+#endif //LL_LLPANELLOOKSHISTORY_H
diff --git a/indra/newview/llmanip.cpp b/indra/newview/llmanip.cpp
index 53c74aaec1..3d1d6cad74 100644
--- a/indra/newview/llmanip.cpp
+++ b/indra/newview/llmanip.cpp
@@ -40,7 +40,7 @@
#include "llrender.h"
#include "llprimitive.h"
#include "llview.h"
-#include "llviewerimagelist.h"
+#include "llviewertexturelist.h"
#include "llagent.h"
#include "llviewercontrol.h"
@@ -452,35 +452,36 @@ void LLManip::renderXYZ(const LLVector3 &vec)
gViewerWindow->setup3DRender();
{
+ LLFontGL* font = LLFontGL::getFontSansSerif();
LLLocale locale(LLLocale::USER_LOCALE);
LLGLDepthTest gls_depth(GL_FALSE);
// render drop shadowed text
feedback_string = llformat("X: %.3f", vec.mV[VX]);
- hud_render_text(utf8str_to_wstring(feedback_string), camera_pos, *LLResMgr::getInstance()->getRes( LLFONT_SANSSERIF ), LLFontGL::NORMAL, -102.f + 1.f, (F32)vertical_offset - 1.f, LLColor4::black, FALSE);
+ hud_render_text(utf8str_to_wstring(feedback_string), camera_pos, *font, LLFontGL::NORMAL, LLFontGL::NO_SHADOW, -102.f + 1.f, (F32)vertical_offset - 1.f, LLColor4::black, FALSE);
feedback_string = llformat("Y: %.3f", vec.mV[VY]);
- hud_render_text(utf8str_to_wstring(feedback_string), camera_pos, *LLResMgr::getInstance()->getRes( LLFONT_SANSSERIF ), LLFontGL::NORMAL, -27.f + 1.f, (F32)vertical_offset - 1.f, LLColor4::black, FALSE);
+ hud_render_text(utf8str_to_wstring(feedback_string), camera_pos, *font, LLFontGL::NORMAL, LLFontGL::NO_SHADOW, -27.f + 1.f, (F32)vertical_offset - 1.f, LLColor4::black, FALSE);
feedback_string = llformat("Z: %.3f", vec.mV[VZ]);
- hud_render_text(utf8str_to_wstring(feedback_string), camera_pos, *LLResMgr::getInstance()->getRes( LLFONT_SANSSERIF ), LLFontGL::NORMAL, 48.f + 1.f, (F32)vertical_offset - 1.f, LLColor4::black, FALSE);
+ hud_render_text(utf8str_to_wstring(feedback_string), camera_pos, *font, LLFontGL::NORMAL, LLFontGL::NO_SHADOW, 48.f + 1.f, (F32)vertical_offset - 1.f, LLColor4::black, FALSE);
// render text on top
feedback_string = llformat("X: %.3f", vec.mV[VX]);
- hud_render_text(utf8str_to_wstring(feedback_string), camera_pos, *LLResMgr::getInstance()->getRes( LLFONT_SANSSERIF ), LLFontGL::NORMAL, -102.f, (F32)vertical_offset, LLColor4(1.f, 0.5f, 0.5f, 1.f), FALSE);
+ hud_render_text(utf8str_to_wstring(feedback_string), camera_pos, *font, LLFontGL::NORMAL, LLFontGL::NO_SHADOW, -102.f, (F32)vertical_offset, LLColor4(1.f, 0.5f, 0.5f, 1.f), FALSE);
glColor3f(0.5f, 1.f, 0.5f);
feedback_string = llformat("Y: %.3f", vec.mV[VY]);
- hud_render_text(utf8str_to_wstring(feedback_string), camera_pos, *LLResMgr::getInstance()->getRes( LLFONT_SANSSERIF ), LLFontGL::NORMAL, -27.f, (F32)vertical_offset, LLColor4(0.5f, 1.f, 0.5f, 1.f), FALSE);
+ hud_render_text(utf8str_to_wstring(feedback_string), camera_pos, *font, LLFontGL::NORMAL, LLFontGL::NO_SHADOW, -27.f, (F32)vertical_offset, LLColor4(0.5f, 1.f, 0.5f, 1.f), FALSE);
glColor3f(0.5f, 0.5f, 1.f);
feedback_string = llformat("Z: %.3f", vec.mV[VZ]);
- hud_render_text(utf8str_to_wstring(feedback_string), camera_pos, *LLResMgr::getInstance()->getRes( LLFONT_SANSSERIF ), LLFontGL::NORMAL, 48.f, (F32)vertical_offset, LLColor4(0.5f, 0.5f, 1.f, 1.f), FALSE);
+ hud_render_text(utf8str_to_wstring(feedback_string), camera_pos, *font, LLFontGL::NORMAL, LLFontGL::NO_SHADOW, 48.f, (F32)vertical_offset, LLColor4(0.5f, 0.5f, 1.f, 1.f), FALSE);
}
}
void LLManip::renderTickText(const LLVector3& pos, const std::string& text, const LLColor4 &color)
{
- const LLFontGL* big_fontp = LLResMgr::getInstance()->getRes( LLFONT_SANSSERIF );
+ const LLFontGL* big_fontp = LLFontGL::getFontSansSerif();
BOOL hud_selection = mObjectSelection->getSelectType() == SELECT_TYPE_HUD;
glMatrixMode(GL_MODELVIEW);
@@ -498,10 +499,10 @@ void LLManip::renderTickText(const LLVector3& pos, const std::string& text, cons
// render shadow first
LLColor4 shadow_color = LLColor4::black;
shadow_color.mV[VALPHA] = color.mV[VALPHA] * 0.5f;
- gViewerWindow->setupViewport(1, -1);
- hud_render_utf8text(text, render_pos, *big_fontp, LLFontGL::NORMAL, -0.5f * big_fontp->getWidthF32(text), 3.f, shadow_color, mObjectSelection->getSelectType() == SELECT_TYPE_HUD);
- gViewerWindow->setupViewport();
- hud_render_utf8text(text, render_pos, *big_fontp, LLFontGL::NORMAL, -0.5f * big_fontp->getWidthF32(text), 3.f, color, mObjectSelection->getSelectType() == SELECT_TYPE_HUD);
+ gViewerWindow->setup3DViewport(1, -1);
+ hud_render_utf8text(text, render_pos, *big_fontp, LLFontGL::NORMAL, LLFontGL::NO_SHADOW, -0.5f * big_fontp->getWidthF32(text), 3.f, shadow_color, mObjectSelection->getSelectType() == SELECT_TYPE_HUD);
+ gViewerWindow->setup3DViewport();
+ hud_render_utf8text(text, render_pos, *big_fontp, LLFontGL::NORMAL, LLFontGL::NO_SHADOW, -0.5f * big_fontp->getWidthF32(text), 3.f, color, mObjectSelection->getSelectType() == SELECT_TYPE_HUD);
glPopMatrix();
}
@@ -510,8 +511,8 @@ void LLManip::renderTickValue(const LLVector3& pos, F32 value, const std::string
{
LLLocale locale(LLLocale::USER_LOCALE);
- const LLFontGL* big_fontp = LLResMgr::getInstance()->getRes( LLFONT_SANSSERIF );
- const LLFontGL* small_fontp = LLResMgr::getInstance()->getRes( LLFONT_SANSSERIF_SMALL );
+ const LLFontGL* big_fontp = LLFontGL::getFontSansSerif();
+ const LLFontGL* small_fontp = LLFontGL::getFontSansSerifSmall();
std::string val_string;
std::string fraction_string;
@@ -560,29 +561,29 @@ void LLManip::renderTickValue(const LLVector3& pos, F32 value, const std::string
{
fraction_string = llformat("%c%02d%s", LLResMgr::getInstance()->getDecimalPoint(), fractional_portion, suffix.c_str());
- gViewerWindow->setupViewport(1, -1);
- hud_render_utf8text(val_string, render_pos, *big_fontp, LLFontGL::NORMAL, -1.f * big_fontp->getWidthF32(val_string), 3.f, shadow_color, hud_selection);
- hud_render_utf8text(fraction_string, render_pos, *small_fontp, LLFontGL::NORMAL, 1.f, 3.f, shadow_color, hud_selection);
+ gViewerWindow->setup3DViewport(1, -1);
+ hud_render_utf8text(val_string, render_pos, *big_fontp, LLFontGL::NORMAL, LLFontGL::NO_SHADOW, -1.f * big_fontp->getWidthF32(val_string), 3.f, shadow_color, hud_selection);
+ hud_render_utf8text(fraction_string, render_pos, *small_fontp, LLFontGL::NORMAL, LLFontGL::NO_SHADOW, 1.f, 3.f, shadow_color, hud_selection);
- gViewerWindow->setupViewport();
- hud_render_utf8text(val_string, render_pos, *big_fontp, LLFontGL::NORMAL, -1.f * big_fontp->getWidthF32(val_string), 3.f, color, hud_selection);
- hud_render_utf8text(fraction_string, render_pos, *small_fontp, LLFontGL::NORMAL, 1.f, 3.f, color, hud_selection);
+ gViewerWindow->setup3DViewport();
+ hud_render_utf8text(val_string, render_pos, *big_fontp, LLFontGL::NORMAL, LLFontGL::NO_SHADOW, -1.f * big_fontp->getWidthF32(val_string), 3.f, color, hud_selection);
+ hud_render_utf8text(fraction_string, render_pos, *small_fontp, LLFontGL::NORMAL, LLFontGL::NO_SHADOW, 1.f, 3.f, color, hud_selection);
}
else
{
- gViewerWindow->setupViewport(1, -1);
- hud_render_utf8text(val_string, render_pos, *big_fontp, LLFontGL::NORMAL, -0.5f * big_fontp->getWidthF32(val_string), 3.f, shadow_color, hud_selection);
- gViewerWindow->setupViewport();
- hud_render_utf8text(val_string, render_pos, *big_fontp, LLFontGL::NORMAL, -0.5f * big_fontp->getWidthF32(val_string), 3.f, color, hud_selection);
+ gViewerWindow->setup3DViewport(1, -1);
+ hud_render_utf8text(val_string, render_pos, *big_fontp, LLFontGL::NORMAL, LLFontGL::NO_SHADOW, -0.5f * big_fontp->getWidthF32(val_string), 3.f, shadow_color, hud_selection);
+ gViewerWindow->setup3DViewport();
+ hud_render_utf8text(val_string, render_pos, *big_fontp, LLFontGL::NORMAL, LLFontGL::NO_SHADOW, -0.5f * big_fontp->getWidthF32(val_string), 3.f, color, hud_selection);
}
glPopMatrix();
}
LLColor4 LLManip::setupSnapGuideRenderPass(S32 pass)
{
- static LLColor4 grid_color_fg = gColors.getColor("GridlineColor");
- static LLColor4 grid_color_bg = gColors.getColor("GridlineBGColor");
- static LLColor4 grid_color_shadow = gColors.getColor("GridlineShadowColor");
+ static LLColor4 grid_color_fg = LLUIColorTable::instance().getColor("GridlineColor");
+ static LLColor4 grid_color_bg = LLUIColorTable::instance().getColor("GridlineBGColor");
+ static LLColor4 grid_color_shadow = LLUIColorTable::instance().getColor("GridlineShadowColor");
LLColor4 line_color;
F32 line_alpha = gSavedSettings.getF32("GridOpacity");
@@ -591,14 +592,14 @@ LLColor4 LLManip::setupSnapGuideRenderPass(S32 pass)
{
case 0:
// shadow
- gViewerWindow->setupViewport(1, -1);
+ gViewerWindow->setup3DViewport(1, -1);
line_color = grid_color_shadow;
line_color.mV[VALPHA] *= line_alpha;
LLUI::setLineWidth(2.f);
break;
case 1:
// hidden lines
- gViewerWindow->setupViewport();
+ gViewerWindow->setup3DViewport();
line_color = grid_color_bg;
line_color.mV[VALPHA] *= line_alpha;
LLUI::setLineWidth(1.f);
diff --git a/indra/newview/llmaniprotate.cpp b/indra/newview/llmaniprotate.cpp
index 8b0484bba6..d1d112c4bf 100644
--- a/indra/newview/llmaniprotate.cpp
+++ b/indra/newview/llmaniprotate.cpp
@@ -63,6 +63,7 @@
#include "pipeline.h"
#include "lldrawable.h"
#include "llglheaders.h"
+#include "lltrans.h"
const F32 RADIUS_PIXELS = 100.f; // size in screen space
const F32 SQ_RADIUS = RADIUS_PIXELS * RADIUS_PIXELS;
@@ -897,7 +898,6 @@ void LLManipRotate::renderSnapGuides()
}
gGL.end();
- // *TODO: Translate
//RN: text rendering does own shadow pass, so only render once
if (pass == 1 && render_text && i % 16 == 0)
{
@@ -905,32 +905,32 @@ void LLManipRotate::renderSnapGuides()
{
if (i == 0)
{
- renderTickText(text_point, mObjectSelection->isAttachment() ? std::string("Forward") : std::string("East"), LLColor4::white);
+ renderTickText(text_point, mObjectSelection->isAttachment() ? LLTrans::getString("Forward") : LLTrans::getString("East"), LLColor4::white);
}
else if (i == 16)
{
if (constraint_axis.mV[VZ] > 0.f)
{
- renderTickText(text_point, mObjectSelection->isAttachment() ? std::string("Left") : std::string("North"), LLColor4::white);
+ renderTickText(text_point, mObjectSelection->isAttachment() ? LLTrans::getString("Left") : LLTrans::getString("North"), LLColor4::white);
}
else
{
- renderTickText(text_point, mObjectSelection->isAttachment() ? std::string("Right") : std::string("South"), LLColor4::white);
+ renderTickText(text_point, mObjectSelection->isAttachment() ? LLTrans::getString("Right") : LLTrans::getString("South"), LLColor4::white);
}
}
else if (i == 32)
{
- renderTickText(text_point, mObjectSelection->isAttachment() ? std::string("Back") : std::string("West"), LLColor4::white);
+ renderTickText(text_point, mObjectSelection->isAttachment() ? LLTrans::getString("Back") : LLTrans::getString("West"), LLColor4::white);
}
else
{
if (constraint_axis.mV[VZ] > 0.f)
{
- renderTickText(text_point, mObjectSelection->isAttachment() ? std::string("Right") : std::string("South"), LLColor4::white);
+ renderTickText(text_point, mObjectSelection->isAttachment() ? LLTrans::getString("Right") : LLTrans::getString("South"), LLColor4::white);
}
else
{
- renderTickText(text_point, mObjectSelection->isAttachment() ? std::string("Left") : std::string("North"), LLColor4::white);
+ renderTickText(text_point, mObjectSelection->isAttachment() ? LLTrans::getString("Left") : LLTrans::getString("North"), LLColor4::white);
}
}
}
@@ -938,32 +938,32 @@ void LLManipRotate::renderSnapGuides()
{
if (i == 0)
{
- renderTickText(text_point, mObjectSelection->isAttachment() ? std::string("Left") : std::string("North"), LLColor4::white);
+ renderTickText(text_point, mObjectSelection->isAttachment() ? LLTrans::getString("Left") : LLTrans::getString("North"), LLColor4::white);
}
else if (i == 16)
{
if (constraint_axis.mV[VX] > 0.f)
{
- renderTickText(text_point, std::string("Up"), LLColor4::white);
+ renderTickText(text_point, LLTrans::getString("Up"), LLColor4::white);
}
else
{
- renderTickText(text_point, std::string("Down"), LLColor4::white);
+ renderTickText(text_point, LLTrans::getString("Down"), LLColor4::white);
}
}
else if (i == 32)
{
- renderTickText(text_point, mObjectSelection->isAttachment() ? std::string("Right") : std::string("South"), LLColor4::white);
+ renderTickText(text_point, mObjectSelection->isAttachment() ? LLTrans::getString("Right") : LLTrans::getString("South"), LLColor4::white);
}
else
{
if (constraint_axis.mV[VX] > 0.f)
{
- renderTickText(text_point, std::string("Down"), LLColor4::white);
+ renderTickText(text_point, LLTrans::getString("Down"), LLColor4::white);
}
else
{
- renderTickText(text_point, std::string("Up"), LLColor4::white);
+ renderTickText(text_point, LLTrans::getString("Up"), LLColor4::white);
}
}
}
@@ -971,32 +971,32 @@ void LLManipRotate::renderSnapGuides()
{
if (i == 0)
{
- renderTickText(text_point, std::string("Up"), LLColor4::white);
+ renderTickText(text_point, LLTrans::getString("Up"), LLColor4::white);
}
else if (i == 16)
{
if (constraint_axis.mV[VY] > 0.f)
{
- renderTickText(text_point, mObjectSelection->isAttachment() ? std::string("Forward") : std::string("East"), LLColor4::white);
+ renderTickText(text_point, mObjectSelection->isAttachment() ? LLTrans::getString("Forward") : LLTrans::getString("East"), LLColor4::white);
}
else
{
- renderTickText(text_point, mObjectSelection->isAttachment() ? std::string("Back") : std::string("West"), LLColor4::white);
+ renderTickText(text_point, mObjectSelection->isAttachment() ? LLTrans::getString("Back") : LLTrans::getString("West"), LLColor4::white);
}
}
else if (i == 32)
{
- renderTickText(text_point, std::string("Down"), LLColor4::white);
+ renderTickText(text_point, LLTrans::getString("Down"), LLColor4::white);
}
else
{
if (constraint_axis.mV[VY] > 0.f)
{
- renderTickText(text_point, mObjectSelection->isAttachment() ? std::string("Back") : std::string("West"), LLColor4::white);
+ renderTickText(text_point, mObjectSelection->isAttachment() ? LLTrans::getString("Back") : LLTrans::getString("West"), LLColor4::white);
}
else
{
- renderTickText(text_point, mObjectSelection->isAttachment() ? std::string("Forward") : std::string("East"), LLColor4::white);
+ renderTickText(text_point, mObjectSelection->isAttachment() ? LLTrans::getString("Forward") : LLTrans::getString("East"), LLColor4::white);
}
}
}
@@ -1107,8 +1107,8 @@ BOOL LLManipRotate::updateVisiblity()
mCenterToProfilePlaneMag = mRadiusMeters * mRadiusMeters / mCenterToCamMag;
mCenterToProfilePlane = -mCenterToProfilePlaneMag * mCenterToCamNorm;
- mCenterScreen.set((S32)((0.5f - mRotationCenter.mdV[VY]) / gAgent.mHUDCurZoom * gViewerWindow->getWindowWidth()),
- (S32)((mRotationCenter.mdV[VZ] + 0.5f) / gAgent.mHUDCurZoom * gViewerWindow->getWindowHeight()));
+ mCenterScreen.set((S32)((0.5f - mRotationCenter.mdV[VY]) / gAgent.mHUDCurZoom * gViewerWindow->getWorldViewWidth()),
+ (S32)((mRotationCenter.mdV[VZ] + 0.5f) / gAgent.mHUDCurZoom * gViewerWindow->getWorldViewHeight()));
visible = TRUE;
}
else
@@ -1624,8 +1624,8 @@ void LLManipRotate::mouseToRay( S32 x, S32 y, LLVector3* ray_pt, LLVector3* ray_
{
if (LLSelectMgr::getInstance()->getSelection()->getSelectType() == SELECT_TYPE_HUD)
{
- F32 mouse_x = (((F32)x / gViewerWindow->getWindowWidth()) - 0.5f) / gAgent.mHUDCurZoom;
- F32 mouse_y = ((((F32)y) / gViewerWindow->getWindowHeight()) - 0.5f) / gAgent.mHUDCurZoom;
+ F32 mouse_x = (((F32)x / gViewerWindow->getWorldViewWidth()) - 0.5f) / gAgent.mHUDCurZoom;
+ F32 mouse_y = ((((F32)y) / gViewerWindow->getWorldViewHeight()) - 0.5f) / gAgent.mHUDCurZoom;
*ray_pt = LLVector3(-1.f, -mouse_x, mouse_y);
*ray_dir = LLVector3(1.f, 0.f, 0.f);
@@ -1699,7 +1699,7 @@ void LLManipRotate::highlightManipulators( S32 x, S32 y )
F32 dist_y = mouse_dir_y.normVec();
F32 dist_z = mouse_dir_z.normVec();
- F32 distance_threshold = (MAX_MANIP_SELECT_DISTANCE * mRadiusMeters) / gViewerWindow->getWindowHeight();
+ F32 distance_threshold = (MAX_MANIP_SELECT_DISTANCE * mRadiusMeters) / gViewerWindow->getWorldViewHeight();
if (llabs(dist_x - mRadiusMeters) * llmax(0.05f, proj_rot_x_axis) < distance_threshold)
{
diff --git a/indra/newview/llmanipscale.cpp b/indra/newview/llmanipscale.cpp
index b1cdfe3886..72596e850a 100644
--- a/indra/newview/llmanipscale.cpp
+++ b/indra/newview/llmanipscale.cpp
@@ -415,7 +415,7 @@ BOOL LLManipScale::handleHover(S32 x, S32 y, MASK mask)
// Patch up textures, if possible.
LLSelectMgr::getInstance()->adjustTexturesByScale(FALSE, getStretchTextures());
- gViewerWindow->getWindow()->setCursor(UI_CURSOR_TOOLSCALE);
+ gViewerWindow->setCursor(UI_CURSOR_TOOLSCALE);
return TRUE;
}
@@ -493,8 +493,8 @@ void LLManipScale::highlightManipulators(S32 x, S32 y)
mProjectedManipulators.insert(projManipulator);
}
- F32 half_width = (F32)gViewerWindow->getWindowWidth() / 2.f;
- F32 half_height = (F32)gViewerWindow->getWindowHeight() / 2.f;
+ F32 half_width = (F32)gViewerWindow->getWorldViewWidth() / 2.f;
+ F32 half_height = (F32)gViewerWindow->getWorldViewHeight() / 2.f;
LLVector2 manip2d;
LLVector2 mousePos((F32)x - half_width, (F32)y - half_height);
LLVector2 delta;
@@ -1368,7 +1368,7 @@ void LLManipScale::updateSnapGuides(const LLBBox& bbox)
else
{
F32 object_distance = dist_vec(mScaleCenter, LLViewerCamera::getInstance()->getOrigin());
- mSnapRegimeOffset = (SNAP_GUIDE_SCREEN_OFFSET * gViewerWindow->getWindowWidth() * object_distance) / LLViewerCamera::getInstance()->getPixelMeterRatio();
+ mSnapRegimeOffset = (SNAP_GUIDE_SCREEN_OFFSET * gViewerWindow->getWorldViewWidth() * object_distance) / LLViewerCamera::getInstance()->getPixelMeterRatio();
}
LLVector3 cam_at_axis;
F32 snap_guide_length;
@@ -1381,7 +1381,7 @@ void LLManipScale::updateSnapGuides(const LLBBox& bbox)
{
cam_at_axis = LLViewerCamera::getInstance()->getAtAxis();
F32 manipulator_distance = dist_vec(box_corner_agent, LLViewerCamera::getInstance()->getOrigin());
- snap_guide_length = (SNAP_GUIDE_SCREEN_LENGTH * gViewerWindow->getWindowWidth() * manipulator_distance) / LLViewerCamera::getInstance()->getPixelMeterRatio();
+ snap_guide_length = (SNAP_GUIDE_SCREEN_LENGTH * gViewerWindow->getWorldViewWidth() * manipulator_distance) / LLViewerCamera::getInstance()->getPixelMeterRatio();
}
mSnapGuideLength = snap_guide_length / llmax(0.1f, (llmin(mSnapGuideDir1 * cam_at_axis, mSnapGuideDir2 * cam_at_axis)));
@@ -1827,10 +1827,10 @@ void LLManipScale::renderSnapGuides(const LLBBox& bbox)
std::string help_text = "Move mouse cursor over ruler";
LLColor4 help_text_color = LLColor4::white;
help_text_color.mV[VALPHA] = clamp_rescale(mHelpTextTimer.getElapsedTimeF32(), sHelpTextVisibleTime, sHelpTextVisibleTime + sHelpTextFadeTime, grid_alpha, 0.f);
- hud_render_utf8text(help_text, help_text_pos, *big_fontp, LLFontGL::NORMAL, -0.5f * big_fontp->getWidthF32(help_text), 3.f, help_text_color, mObjectSelection->getSelectType() == SELECT_TYPE_HUD);
+ hud_render_utf8text(help_text, help_text_pos, *big_fontp, LLFontGL::NORMAL, LLFontGL::NO_SHADOW, -0.5f * big_fontp->getWidthF32(help_text), 3.f, help_text_color, mObjectSelection->getSelectType() == SELECT_TYPE_HUD);
help_text = "to snap to grid";
help_text_pos -= LLViewerCamera::getInstance()->getUpAxis() * mSnapRegimeOffset * 0.4f;
- hud_render_utf8text(help_text, help_text_pos, *big_fontp, LLFontGL::NORMAL, -0.5f * big_fontp->getWidthF32(help_text), 3.f, help_text_color, mObjectSelection->getSelectType() == SELECT_TYPE_HUD);
+ hud_render_utf8text(help_text, help_text_pos, *big_fontp, LLFontGL::NORMAL, LLFontGL::NO_SHADOW, -0.5f * big_fontp->getWidthF32(help_text), 3.f, help_text_color, mObjectSelection->getSelectType() == SELECT_TYPE_HUD);
}
}
}
diff --git a/indra/newview/llmaniptranslate.cpp b/indra/newview/llmaniptranslate.cpp
index f2585c8543..cc2531d139 100644
--- a/indra/newview/llmaniptranslate.cpp
+++ b/indra/newview/llmaniptranslate.cpp
@@ -61,7 +61,7 @@
#include "llviewerjoint.h"
#include "llviewerobject.h"
#include "llviewerwindow.h"
-#include "llvoavatar.h"
+#include "llvoavatarself.h"
#include "llworld.h"
#include "llui.h"
#include "pipeline.h"
@@ -78,7 +78,7 @@ const F32 PLANE_TICK_SIZE = 0.4f;
const F32 MANIPULATOR_SCALE_HALF_LIFE = 0.07f;
const F32 SNAP_ARROW_SCALE = 0.7f;
-static LLPointer<LLImageGL> sGridTex = NULL ;
+static LLPointer<LLViewerTexture> sGridTex = NULL ;
const LLManip::EManipPart MANIPULATOR_IDS[9] =
{
@@ -154,7 +154,7 @@ void LLManipTranslate::restoreGL()
U32 mip = 0;
destroyGL() ;
- sGridTex = new LLImageGL() ;
+ sGridTex = LLViewerTextureManager::getLocalTexture() ;
if(!sGridTex->createGLTexture())
{
sGridTex = NULL ;
@@ -414,7 +414,7 @@ BOOL LLManipTranslate::handleHover(S32 x, S32 y, MASK mask)
// Handle auto-rotation if necessary.
const F32 ROTATE_ANGLE_PER_SECOND = 30.f * DEG_TO_RAD;
- const S32 ROTATE_H_MARGIN = gViewerWindow->getWindowWidth() / 20;
+ const S32 ROTATE_H_MARGIN = gViewerWindow->getWorldViewWidth() / 20;
const F32 rotate_angle = ROTATE_ANGLE_PER_SECOND / gFPSClamped;
BOOL rotated = FALSE;
@@ -426,7 +426,7 @@ BOOL LLManipTranslate::handleHover(S32 x, S32 y, MASK mask)
gAgent.cameraOrbitAround(rotate_angle);
rotated = TRUE;
}
- else if (x > gViewerWindow->getWindowWidth() - ROTATE_H_MARGIN)
+ else if (x > gViewerWindow->getWorldViewWidth() - ROTATE_H_MARGIN)
{
gAgent.cameraOrbitAround(-rotate_angle);
rotated = TRUE;
@@ -960,8 +960,8 @@ void LLManipTranslate::highlightManipulators(S32 x, S32 y)
LLVector2 manip_start_2d;
LLVector2 manip_end_2d;
LLVector2 manip_dir;
- F32 half_width = gViewerWindow->getWindowWidth() / 2.f;
- F32 half_height = gViewerWindow->getWindowHeight() / 2.f;
+ F32 half_width = gViewerWindow->getWorldViewWidth() / 2.f;
+ F32 half_height = gViewerWindow->getWorldViewHeight() / 2.f;
LLVector2 mousePos((F32)x - half_width, (F32)y - half_height);
LLVector2 mouse_delta;
@@ -1225,7 +1225,7 @@ void LLManipTranslate::renderSnapGuides()
{
LLVector3 cam_to_selection = getPivotPoint() - LLViewerCamera::getInstance()->getOrigin();
F32 current_range = cam_to_selection.normVec();
- guide_size_meters = SNAP_GUIDE_SCREEN_SIZE * gViewerWindow->getWindowHeight() * current_range / LLViewerCamera::getInstance()->getPixelMeterRatio();
+ guide_size_meters = SNAP_GUIDE_SCREEN_SIZE * gViewerWindow->getWorldViewHeight() * current_range / LLViewerCamera::getInstance()->getPixelMeterRatio();
F32 fraction_of_fov = mAxisArrowLength / (F32) LLViewerCamera::getInstance()->getViewHeightInPixels();
F32 apparent_angle = fraction_of_fov * LLViewerCamera::getInstance()->getView(); // radians
@@ -1441,10 +1441,10 @@ void LLManipTranslate::renderSnapGuides()
std::string help_text = "Move mouse cursor over ruler to snap";
LLColor4 help_text_color = LLColor4::white;
help_text_color.mV[VALPHA] = clamp_rescale(mHelpTextTimer.getElapsedTimeF32(), sHelpTextVisibleTime, sHelpTextVisibleTime + sHelpTextFadeTime, line_alpha, 0.f);
- hud_render_utf8text(help_text, help_text_pos, *big_fontp, LLFontGL::NORMAL, -0.5f * big_fontp->getWidthF32(help_text), 3.f, help_text_color, mObjectSelection->getSelectType() == SELECT_TYPE_HUD);
+ hud_render_utf8text(help_text, help_text_pos, *big_fontp, LLFontGL::NORMAL, LLFontGL::NO_SHADOW, -0.5f * big_fontp->getWidthF32(help_text), 3.f, help_text_color, mObjectSelection->getSelectType() == SELECT_TYPE_HUD);
help_text = "to snap to grid";
help_text_pos -= LLViewerCamera::getInstance()->getUpAxis() * mSnapOffsetMeters * 0.2f;
- hud_render_utf8text(help_text, help_text_pos, *big_fontp, LLFontGL::NORMAL, -0.5f * big_fontp->getWidthF32(help_text), 3.f, help_text_color, mObjectSelection->getSelectType() == SELECT_TYPE_HUD);
+ hud_render_utf8text(help_text, help_text_pos, *big_fontp, LLFontGL::NORMAL, LLFontGL::NO_SHADOW, -0.5f * big_fontp->getWidthF32(help_text), 3.f, help_text_color, mObjectSelection->getSelectType() == SELECT_TYPE_HUD);
}
}
}
@@ -1522,7 +1522,7 @@ void LLManipTranslate::renderSnapGuides()
float a = line_alpha;
- LLColor4 col = gColors.getColor("SilhouetteChildColor");
+ LLColor4 col = LLUIColorTable::instance().getColor("SilhouetteChildColor");
{
//draw grid behind objects
LLGLDepthTest gls_depth(GL_TRUE, GL_FALSE);
@@ -1800,7 +1800,7 @@ void LLManipTranslate::renderTranslationHandles()
// Drag handles
if (mObjectSelection->getSelectType() == SELECT_TYPE_HUD)
{
- mArrowLengthMeters = mAxisArrowLength / gViewerWindow->getWindowHeight();
+ mArrowLengthMeters = mAxisArrowLength / gViewerWindow->getWorldViewHeight();
mArrowLengthMeters /= gAgent.mHUDCurZoom;
}
else
diff --git a/indra/newview/llmediactrl.cpp b/indra/newview/llmediactrl.cpp
new file mode 100644
index 0000000000..62b38f2b4a
--- /dev/null
+++ b/indra/newview/llmediactrl.cpp
@@ -0,0 +1,937 @@
+/**
+ * @file LLMediaCtrl.cpp
+ * @brief Web browser UI control
+ *
+ * $LicenseInfo:firstyear=2006&license=viewergpl$
+ *
+ * Copyright (c) 2006-2009, Linden Research, Inc.
+ *
+ * Second Life Viewer Source Code
+ * The source code in this file ("Source Code") is provided by Linden Lab
+ * to you under the terms of the GNU General Public License, version 2.0
+ * ("GPL"), unless you have obtained a separate licensing agreement
+ * ("Other License"), formally executed by you and Linden Lab. Terms of
+ * the GPL can be found in doc/GPL-license.txt in this distribution, or
+ * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
+ *
+ * There are special exceptions to the terms and conditions of the GPL as
+ * it is applied to this Source Code. View the full text of the exception
+ * in the file doc/FLOSS-exception.txt in this software distribution, or
+ * online at
+ * http://secondlifegrid.net/programs/open_source/licensing/flossexception
+ *
+ * By copying, modifying or distributing this software, you acknowledge
+ * that you have read and understood your obligations described above,
+ * and agree to abide by those obligations.
+ *
+ * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+ * COMPLETENESS OR PERFORMANCE.
+ * $/LicenseInfo$
+ */
+
+#include "llviewerprecompiledheaders.h"
+
+
+#include "llmediactrl.h"
+
+// viewer includes
+#include "llfloaterhtml.h"
+#include "llfloaterworldmap.h"
+#include "lluictrlfactory.h"
+#include "llurldispatcher.h"
+#include "llurlsimstring.h"
+#include "llviewborder.h"
+#include "llviewercontrol.h"
+#include "llviewermedia.h"
+#include "llviewerwindow.h"
+#include "llnotifications.h"
+#include "llweb.h"
+#include "llrender.h"
+#include "llpluginclassmedia.h"
+#include "llslurl.h"
+#include "lluictrlfactory.h" // LLDefaultChildRegistry
+
+// linden library includes
+#include "llfocusmgr.h"
+
+extern BOOL gRestoreGL;
+
+static LLDefaultChildRegistry::Register<LLMediaCtrl> r("web_browser");
+
+LLMediaCtrl::Params::Params()
+: start_url("start_url"),
+ border_visible("border_visible", true),
+ ignore_ui_scale("ignore_ui_scale", true),
+ hide_loading("hide_loading", false),
+ caret_color("caret_color")
+{}
+
+LLMediaCtrl::LLMediaCtrl( const Params& p) :
+ LLPanel( p ),
+ mTextureDepthBytes( 4 ),
+ mBorder(NULL),
+ mFrequentUpdates( true ),
+ mForceUpdate( false ),
+ mOpenLinksInExternalBrowser( false ),
+ mOpenLinksInInternalBrowser( false ),
+ mTrusted( false ),
+ mHomePageUrl( "" ),
+ mIgnoreUIScale( true ),
+ mAlwaysRefresh( false ),
+ mExternalUrl( "" ),
+ mMediaSource( 0 ),
+ mTakeFocusOnClick( true ),
+ mCurrentNavUrl( "" ),
+ mLastSetCursor( UI_CURSOR_ARROW ),
+ mStretchToFill( true ),
+ mMaintainAspectRatio ( true ),
+ mHideLoading (false)
+{
+ {
+ LLColor4 color = p.caret_color().get();
+ setCaretColor( (unsigned int)color.mV[0], (unsigned int)color.mV[1], (unsigned int)color.mV[2] );
+ }
+
+ setIgnoreUIScale(p.ignore_ui_scale());
+
+ setHomePageUrl(p.start_url());
+
+ setBorderVisible(p.border_visible());
+
+ mHideLoading = p.hide_loading();
+
+ S32 screen_width = mIgnoreUIScale ?
+ llround((F32)getRect().getWidth() * LLUI::sGLScaleFactor.mV[VX]) : getRect().getWidth();
+ S32 screen_height = mIgnoreUIScale ?
+ llround((F32)getRect().getHeight() * LLUI::sGLScaleFactor.mV[VY]) : getRect().getHeight();
+
+ mMediaTextureID.generate();
+ mMediaSource = LLViewerMedia::newMediaImpl(mHomePageUrl, mMediaTextureID, screen_width, screen_height, false, false, "text/html");
+ if ( !mMediaSource )
+ {
+ llwarns << "media source create failed " << llendl;
+ // return;
+ }
+
+ mMediaSource->setVisible( getVisible() );
+
+ mMediaSource->addObserver( this );
+
+ // FIXME: How do we create a bevel now?
+// LLRect border_rect( 0, getRect().getHeight() + 2, getRect().getWidth() + 2, 0 );
+// mBorder = new LLViewBorder( std::string("web control border"), border_rect, LLViewBorder::BEVEL_IN );
+// addChild( mBorder );
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// note: this is now a singleton and destruction happens via initClass() now
+LLMediaCtrl::~LLMediaCtrl()
+{
+
+ if (mMediaSource)
+ {
+ mMediaSource->remObserver( this );
+ mMediaSource = NULL;
+ }
+}
+
+////////////////////////////////////////////////////////////////////////////////
+//
+void LLMediaCtrl::setBorderVisible( BOOL border_visible )
+{
+ if ( mBorder )
+ {
+ mBorder->setVisible( border_visible );
+ };
+};
+
+////////////////////////////////////////////////////////////////////////////////
+//
+void LLMediaCtrl::setTakeFocusOnClick( bool take_focus )
+{
+ mTakeFocusOnClick = take_focus;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// set flag that forces the embedded browser to open links in the external system browser
+void LLMediaCtrl::setOpenInExternalBrowser( bool valIn )
+{
+ mOpenLinksInExternalBrowser = valIn;
+};
+
+////////////////////////////////////////////////////////////////////////////////
+// set flag that forces the embedded browser to open links in the internal browser floater
+void LLMediaCtrl::setOpenInInternalBrowser( bool valIn )
+{
+ mOpenLinksInInternalBrowser = valIn;
+};
+
+////////////////////////////////////////////////////////////////////////////////
+void LLMediaCtrl::setTrusted( bool valIn )
+{
+ mTrusted = valIn;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+//
+BOOL LLMediaCtrl::handleHover( S32 x, S32 y, MASK mask )
+{
+ convertInputCoords(x, y);
+
+ if (mMediaSource)
+ mMediaSource->mouseMove(x, y);
+
+ gViewerWindow->setCursor(mLastSetCursor);
+
+ return TRUE;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+//
+BOOL LLMediaCtrl::handleScrollWheel( S32 x, S32 y, S32 clicks )
+{
+ if (mMediaSource && mMediaSource->hasMedia())
+ mMediaSource->getMediaPlugin()->scrollEvent(0, clicks, MASK_NONE);
+
+ return TRUE;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+//
+BOOL LLMediaCtrl::handleMouseUp( S32 x, S32 y, MASK mask )
+{
+ convertInputCoords(x, y);
+
+ if (mMediaSource)
+ {
+ mMediaSource->mouseUp(x, y);
+
+ // *HACK: LLMediaImplLLMozLib automatically takes focus on mouseup,
+ // in addition to the onFocusReceived() call below. Undo this. JC
+ if (!mTakeFocusOnClick)
+ {
+ mMediaSource->focus(false);
+ gViewerWindow->focusClient();
+ }
+ }
+
+ gFocusMgr.setMouseCapture( NULL );
+
+ return TRUE;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+//
+BOOL LLMediaCtrl::handleMouseDown( S32 x, S32 y, MASK mask )
+{
+ convertInputCoords(x, y);
+
+ if (mMediaSource)
+ mMediaSource->mouseDown(x, y);
+
+ gFocusMgr.setMouseCapture( this );
+
+ if (mTakeFocusOnClick)
+ {
+ setFocus( TRUE );
+ }
+
+ return TRUE;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+//
+BOOL LLMediaCtrl::handleDoubleClick( S32 x, S32 y, MASK mask )
+{
+ convertInputCoords(x, y);
+
+ if (mMediaSource)
+ mMediaSource->mouseLeftDoubleClick( x, y );
+
+ gFocusMgr.setMouseCapture( this );
+
+ if (mTakeFocusOnClick)
+ {
+ setFocus( TRUE );
+ }
+
+ return TRUE;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+//
+void LLMediaCtrl::onFocusReceived()
+{
+ if (mMediaSource)
+ {
+ mMediaSource->focus(true);
+
+ // Set focus for edit menu items
+ LLEditMenuHandler::gEditMenuHandler = mMediaSource;
+ }
+
+ LLPanel::onFocusReceived();
+}
+
+////////////////////////////////////////////////////////////////////////////////
+//
+void LLMediaCtrl::onFocusLost()
+{
+ if (mMediaSource)
+ {
+ mMediaSource->focus(false);
+
+ if( LLEditMenuHandler::gEditMenuHandler == mMediaSource )
+ {
+ // Clear focus for edit menu items
+ LLEditMenuHandler::gEditMenuHandler = NULL;
+ }
+ }
+
+ gViewerWindow->focusClient();
+
+ LLPanel::onFocusLost();
+}
+
+////////////////////////////////////////////////////////////////////////////////
+//
+BOOL LLMediaCtrl::postBuild ()
+{
+ mVisibleSignal.connect(boost::bind(&LLMediaCtrl::onVisibilityChange, this, _2));
+ return TRUE;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+//
+BOOL LLMediaCtrl::handleKeyHere( KEY key, MASK mask )
+{
+ BOOL result = FALSE;
+
+ // FIXME: THIS IS SO WRONG.
+ // Menu keys should be handled by the menu system and not passed to UI elements, but this is how LLTextEditor and LLLineEditor do it...
+
+ if (mMediaSource)
+ {
+ if( MASK_CONTROL & mask )
+ {
+ if( 'C' == key )
+ {
+ mMediaSource->copy();
+ result = TRUE;
+ }
+ else
+ if( 'V' == key )
+ {
+ mMediaSource->paste();
+ result = TRUE;
+ }
+ else
+ if( 'X' == key )
+ {
+ mMediaSource->cut();
+ result = TRUE;
+ }
+ }
+
+ if(!result)
+ {
+ result = mMediaSource->handleKeyHere(key, mask);
+ }
+ }
+
+ return result;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+//
+void LLMediaCtrl::handleVisibilityChange ( BOOL new_visibility )
+{
+ llinfos << "visibility changed to " << (new_visibility?"true":"false") << llendl;
+ if(mMediaSource)
+ {
+ mMediaSource->setVisible( new_visibility );
+ }
+}
+
+////////////////////////////////////////////////////////////////////////////////
+//
+BOOL LLMediaCtrl::handleUnicodeCharHere(llwchar uni_char)
+{
+ BOOL result = FALSE;
+
+ // only accept 'printable' characters, sigh...
+ if (uni_char >= 32 // discard 'control' characters
+ && uni_char != 127) // SDL thinks this is 'delete' - yuck.
+ {
+ if (mMediaSource)
+ result = mMediaSource->handleUnicodeCharHere(uni_char);
+ }
+
+ return result;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+//
+void LLMediaCtrl::onVisibilityChange ( const LLSD& new_visibility )
+{
+ // set state of frequent updates automatically if visibility changes
+ if ( new_visibility.asBoolean() )
+ {
+ mFrequentUpdates = true;
+ }
+ else
+ {
+ mFrequentUpdates = false;
+ }
+}
+
+////////////////////////////////////////////////////////////////////////////////
+//
+void LLMediaCtrl::reshape( S32 width, S32 height, BOOL called_from_parent )
+{
+ S32 screen_width = mIgnoreUIScale ? llround((F32)width * LLUI::sGLScaleFactor.mV[VX]) : width;
+ S32 screen_height = mIgnoreUIScale ? llround((F32)height * LLUI::sGLScaleFactor.mV[VY]) : height;
+
+// llinfos << "reshape called with width = " << width << ", height = " << height << llendl;
+
+ // when floater is minimized, these sizes are negative
+ if ( screen_height > 0 && screen_width > 0 )
+ {
+ mMediaSource->setSize(screen_width, screen_height);
+ mForceUpdate = true;
+ }
+
+ LLPanel::reshape( width, height, called_from_parent );
+}
+
+////////////////////////////////////////////////////////////////////////////////
+//
+void LLMediaCtrl::navigateBack()
+{
+ if (mMediaSource && mMediaSource->hasMedia())
+ {
+ mMediaSource->getMediaPlugin()->browse_back();
+ }
+}
+
+////////////////////////////////////////////////////////////////////////////////
+//
+void LLMediaCtrl::navigateForward()
+{
+ if (mMediaSource && mMediaSource->hasMedia())
+ {
+ mMediaSource->getMediaPlugin()->browse_forward();
+ }
+}
+
+////////////////////////////////////////////////////////////////////////////////
+//
+bool LLMediaCtrl::canNavigateBack()
+{
+ if (mMediaSource)
+ return mMediaSource->canNavigateBack();
+ else
+ return false;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+//
+bool LLMediaCtrl::canNavigateForward()
+{
+ if (mMediaSource)
+ return mMediaSource->canNavigateForward();
+ else
+ return false;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+//
+void LLMediaCtrl::set404RedirectUrl( std::string redirect_url )
+{
+ if(mMediaSource && mMediaSource->hasMedia())
+ mMediaSource->getMediaPlugin()->set_status_redirect( 404, redirect_url );
+}
+
+////////////////////////////////////////////////////////////////////////////////
+//
+void LLMediaCtrl::clr404RedirectUrl()
+{
+ if(mMediaSource && mMediaSource->hasMedia())
+ mMediaSource->getMediaPlugin()->set_status_redirect(404, "");
+}
+
+////////////////////////////////////////////////////////////////////////////////
+//
+void LLMediaCtrl::navigateTo( std::string url_in, std::string mime_type)
+{
+ // don't browse to anything that starts with secondlife:// or sl://
+ const std::string protocol1 = "secondlife://";
+ const std::string protocol2 = "sl://";
+ if ((LLStringUtil::compareInsensitive(url_in.substr(0, protocol1.length()), protocol1) == 0) ||
+ (LLStringUtil::compareInsensitive(url_in.substr(0, protocol2.length()), protocol2) == 0))
+ {
+ // TODO: Print out/log this attempt?
+ // llinfos << "Rejecting attempt to load restricted website :" << urlIn << llendl;
+ return;
+ }
+
+ if (mMediaSource)
+ {
+ mCurrentNavUrl = url_in;
+ mMediaSource->navigateTo(url_in, mime_type, mime_type.empty());
+ }
+}
+
+////////////////////////////////////////////////////////////////////////////////
+//
+void LLMediaCtrl::navigateToLocalPage( const std::string& subdir, const std::string& filename_in )
+{
+ std::string language = LLUI::getLanguage();
+ std::string delim = gDirUtilp->getDirDelimiter();
+ std::string filename;
+
+ filename += subdir;
+ filename += delim;
+ filename += filename_in;
+
+ std::string expanded_filename = gDirUtilp->findSkinnedFilename("html", language, filename);
+
+ if (! gDirUtilp->fileExists(expanded_filename))
+ {
+ if (language != "en-us")
+ {
+ expanded_filename = gDirUtilp->findSkinnedFilename("html", "en-us", filename);
+ if (! gDirUtilp->fileExists(expanded_filename))
+ {
+ llwarns << "File " << subdir << delim << filename_in << "not found" << llendl;
+ return;
+ }
+ }
+ else
+ {
+ llwarns << "File " << subdir << delim << filename_in << "not found" << llendl;
+ return;
+ }
+ }
+ if (mMediaSource)
+ {
+ mCurrentNavUrl = expanded_filename;
+ mMediaSource->navigateTo(expanded_filename, "text/html", false);
+ }
+
+}
+
+////////////////////////////////////////////////////////////////////////////////
+//
+void LLMediaCtrl::navigateHome()
+{
+ if( mHomePageUrl.length() )
+ {
+ if (mMediaSource)
+ mMediaSource->navigateTo(mHomePageUrl);
+ };
+}
+
+////////////////////////////////////////////////////////////////////////////////
+//
+void LLMediaCtrl::setHomePageUrl( const std::string urlIn )
+{
+ mHomePageUrl = urlIn;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+//
+bool LLMediaCtrl::setCaretColor(unsigned int red, unsigned int green, unsigned int blue)
+{
+ //NOOP
+ return false;
+}
+////////////////////////////////////////////////////////////////////////////////
+//
+std::string LLMediaCtrl::getHomePageUrl()
+{
+ return mHomePageUrl;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+//
+LLPluginClassMedia* LLMediaCtrl::getMediaPlugin()
+{
+ return mMediaSource.isNull() ? NULL : mMediaSource->getMediaPlugin();
+}
+
+////////////////////////////////////////////////////////////////////////////////
+//
+void LLMediaCtrl::draw()
+{
+ LLPluginClassMedia* media_plugin = NULL;
+
+ if(mMediaSource && mMediaSource->hasMedia())
+ {
+ media_plugin = mMediaSource->getMediaPlugin();
+ }
+ else
+ {
+ return;
+ }
+
+ LLViewerMediaTexture* media_texture = LLViewerTextureManager::findMediaTexture(mMediaTextureID);
+
+ if (!media_texture )
+ {
+ return;
+ }
+
+ if ( gRestoreGL == 1 )
+ {
+ LLRect r = getRect();
+ reshape( r.getWidth(), r.getHeight(), FALSE );
+ return;
+ };
+
+ // NOTE: optimization needed here - probably only need to do this once
+ // unless tearoffs change the parent which they probably do.
+ const LLUICtrl* ptr = findRootMostFocusRoot();
+ if ( ptr && ptr->hasFocus() )
+ {
+ setFrequentUpdates( true );
+ }
+ else
+ {
+ setFrequentUpdates( false );
+ };
+
+ // alpha off for this
+ LLGLSUIDefault gls_ui;
+ LLGLDisable gls_alphaTest( GL_ALPHA_TEST );
+
+ gGL.pushMatrix();
+ {
+ if (mIgnoreUIScale)
+ {
+ glLoadIdentity();
+ // font system stores true screen origin, need to scale this by UI scale factor
+ // to get render origin for this view (with unit scale)
+ gGL.translatef(floorf(LLFontGL::sCurOrigin.mX * LLUI::sGLScaleFactor.mV[VX]),
+ floorf(LLFontGL::sCurOrigin.mY * LLUI::sGLScaleFactor.mV[VY]),
+ LLFontGL::sCurOrigin.mZ);
+ }
+
+ // scale texture to fit the space using texture coords
+ gGL.getTexUnit(0)->bind(media_texture);
+ gGL.color4fv( LLColor4::white.mV );
+ F32 max_u = ( F32 )media_plugin->getWidth() / ( F32 )media_plugin->getTextureWidth();
+ F32 max_v = ( F32 )media_plugin->getHeight() / ( F32 )media_plugin->getTextureHeight();
+
+ LLRect r = getRect();
+ S32 width, height;
+ S32 x_offset = 0;
+ S32 y_offset = 0;
+
+ if(mStretchToFill)
+ {
+ if(mMaintainAspectRatio)
+ {
+ F32 media_aspect = (F32)(media_plugin->getWidth()) / (F32)(media_plugin->getHeight());
+ F32 view_aspect = (F32)(r.getWidth()) / (F32)(r.getHeight());
+ if(media_aspect > view_aspect)
+ {
+ // max width, adjusted height
+ width = r.getWidth();
+ height = llmin(llmax(S32(width / media_aspect), 0), r.getHeight());
+ }
+ else
+ {
+ // max height, adjusted width
+ height = r.getHeight();
+ width = llmin(llmax(S32(height * media_aspect), 0), r.getWidth());
+ }
+ }
+ else
+ {
+ width = r.getWidth();
+ height = r.getHeight();
+ }
+ }
+ else
+ {
+ width = llmin(media_plugin->getWidth(), r.getWidth());
+ height = llmin(media_plugin->getHeight(), r.getHeight());
+ }
+
+ x_offset = (r.getWidth() - width) / 2;
+ y_offset = (r.getHeight() - height) / 2;
+
+ // draw the browser
+ gGL.setSceneBlendType(LLRender::BT_REPLACE);
+ gGL.begin( LLRender::QUADS );
+ if (! media_plugin->getTextureCoordsOpenGL())
+ {
+ // render using web browser reported width and height, instead of trying to invert GL scale
+ gGL.texCoord2f( max_u, 0.f );
+ gGL.vertex2i( x_offset + width, y_offset + height );
+
+ gGL.texCoord2f( 0.f, 0.f );
+ gGL.vertex2i( x_offset, y_offset + height );
+
+ gGL.texCoord2f( 0.f, max_v );
+ gGL.vertex2i( x_offset, y_offset );
+
+ gGL.texCoord2f( max_u, max_v );
+ gGL.vertex2i( x_offset + width, y_offset );
+ }
+ else
+ {
+ // render using web browser reported width and height, instead of trying to invert GL scale
+ gGL.texCoord2f( max_u, max_v );
+ gGL.vertex2i( x_offset + width, y_offset + height );
+
+ gGL.texCoord2f( 0.f, max_v );
+ gGL.vertex2i( x_offset, y_offset + height );
+
+ gGL.texCoord2f( 0.f, 0.f );
+ gGL.vertex2i( x_offset, y_offset );
+
+ gGL.texCoord2f( max_u, 0.f );
+ gGL.vertex2i( x_offset + width, y_offset );
+ }
+ gGL.end();
+ gGL.setSceneBlendType(LLRender::BT_ALPHA);
+ }
+ gGL.popMatrix();
+
+ // highlight if keyboard focus here. (TODO: this needs some work)
+ if ( mBorder && mBorder->getVisible() )
+ mBorder->setKeyboardFocusHighlight( gFocusMgr.childHasKeyboardFocus( this ) );
+
+
+ LLPanel::draw();
+}
+
+////////////////////////////////////////////////////////////////////////////////
+//
+void LLMediaCtrl::convertInputCoords(S32& x, S32& y)
+{
+ bool coords_opengl = false;
+
+ if(mMediaSource && mMediaSource->hasMedia())
+ {
+ coords_opengl = mMediaSource->getMediaPlugin()->getTextureCoordsOpenGL();
+ }
+
+ x = mIgnoreUIScale ? llround((F32)x * LLUI::sGLScaleFactor.mV[VX]) : x;
+ if ( ! coords_opengl )
+ {
+ y = mIgnoreUIScale ? llround((F32)(y) * LLUI::sGLScaleFactor.mV[VY]) : y;
+ }
+ else
+ {
+ y = mIgnoreUIScale ? llround((F32)(getRect().getHeight() - y) * LLUI::sGLScaleFactor.mV[VY]) : getRect().getHeight() - y;
+ };
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// static
+bool LLMediaCtrl::onClickLinkExternalTarget(const LLSD& notification, const LLSD& response )
+{
+ S32 option = LLNotification::getSelectedOption(notification, response);
+ if ( 0 == option )
+ {
+ // open in external browser because we don't support
+ // creation of our own secondary browser windows
+ LLWeb::loadURLExternal( notification["payload"]["external_url"].asString() );
+ }
+ return false;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// inherited from LLViewerMediaObserver
+//virtual
+void LLMediaCtrl::handleMediaEvent(LLPluginClassMedia* self, EMediaEvent event)
+{
+ switch(event)
+ {
+ case MEDIA_EVENT_CONTENT_UPDATED:
+ {
+ // LL_DEBUGS("Media") << "Media event: MEDIA_EVENT_CONTENT_UPDATED " << LL_ENDL;
+ };
+ break;
+
+ case MEDIA_EVENT_TIME_DURATION_UPDATED:
+ {
+ // LL_DEBUGS("Media") << "Media event: MEDIA_EVENT_TIME_DURATION_UPDATED, time is " << self->getCurrentTime() << " of " << self->getDuration() << LL_ENDL;
+ };
+ break;
+
+ case MEDIA_EVENT_SIZE_CHANGED:
+ {
+ LL_DEBUGS("Media") << "Media event: MEDIA_EVENT_SIZE_CHANGED " << LL_ENDL;
+ LLRect r = getRect();
+ reshape( r.getWidth(), r.getHeight(), FALSE );
+ };
+ break;
+
+ case MEDIA_EVENT_CURSOR_CHANGED:
+ {
+ LL_DEBUGS("Media") << "Media event: MEDIA_EVENT_CURSOR_CHANGED, new cursor is " << self->getCursorName() << LL_ENDL;
+
+ std::string cursor = self->getCursorName();
+
+ if(cursor == "arrow")
+ mLastSetCursor = UI_CURSOR_ARROW;
+ else if(cursor == "ibeam")
+ mLastSetCursor = UI_CURSOR_IBEAM;
+ else if(cursor == "splith")
+ mLastSetCursor = UI_CURSOR_SIZEWE;
+ else if(cursor == "splitv")
+ mLastSetCursor = UI_CURSOR_SIZENS;
+ else if(cursor == "hand")
+ mLastSetCursor = UI_CURSOR_HAND;
+ else // for anything else, default to the arrow
+ mLastSetCursor = UI_CURSOR_ARROW;
+ };
+ break;
+
+ case MEDIA_EVENT_NAVIGATE_BEGIN:
+ {
+ LL_DEBUGS("Media") << "Media event: MEDIA_EVENT_NAVIGATE_BEGIN, url is " << self->getNavigateURI() << LL_ENDL;
+ if(mMediaSource && mHideLoading)
+ {
+ mMediaSource->suspendUpdates(true);
+ }
+ };
+ break;
+
+ case MEDIA_EVENT_NAVIGATE_COMPLETE:
+ {
+ LL_DEBUGS("Media") << "Media event: MEDIA_EVENT_NAVIGATE_COMPLETE, result string is: " << self->getNavigateResultString() << LL_ENDL;
+ if(mMediaSource && mHideLoading)
+ {
+ mMediaSource->suspendUpdates(false);
+ }
+ };
+ break;
+
+ case MEDIA_EVENT_PROGRESS_UPDATED:
+ {
+ LL_DEBUGS("Media") << "Media event: MEDIA_EVENT_PROGRESS_UPDATED, loading at " << self->getProgressPercent() << "%" << LL_ENDL;
+ };
+ break;
+
+ case MEDIA_EVENT_STATUS_TEXT_CHANGED:
+ {
+ LL_DEBUGS("Media") << "Media event: MEDIA_EVENT_STATUS_TEXT_CHANGED, new status text is: " << self->getStatusText() << LL_ENDL;
+ };
+ break;
+
+ case MEDIA_EVENT_LOCATION_CHANGED:
+ {
+ LL_DEBUGS("Media") << "Media event: MEDIA_EVENT_LOCATION_CHANGED, new uri is: " << self->getLocation() << LL_ENDL;
+ };
+ break;
+
+ case MEDIA_EVENT_CLICK_LINK_HREF:
+ {
+ LL_DEBUGS("Media") << "Media event: MEDIA_EVENT_CLICK_LINK_HREF, target is \"" << self->getClickTarget() << "\", uri is " << self->getClickURL() << LL_ENDL;
+ onClickLinkHref(self);
+ };
+ break;
+
+ case MEDIA_EVENT_CLICK_LINK_NOFOLLOW:
+ {
+ LL_DEBUGS("Media") << "Media event: MEDIA_EVENT_CLICK_LINK_NOFOLLOW, uri is " << self->getClickURL() << LL_ENDL;
+ onClickLinkNoFollow(self);
+ };
+ break;
+
+ case MEDIA_EVENT_PLUGIN_FAILED:
+ {
+ LL_DEBUGS("Media") << "Media event: MEDIA_EVENT_PLUGIN_FAILED" << LL_ENDL;
+ };
+ break;
+ };
+
+ // chain all events to any potential observers of this object.
+ emitEvent(self, event);
+}
+
+////////////////////////////////////////////////////////////////////////////////
+//
+void LLMediaCtrl::onClickLinkHref( LLPluginClassMedia* self )
+{
+ // retrieve the event parameters
+ std::string target = self->getClickTarget();
+ std::string url = self->getClickURL();
+
+ // if there is a value for the target
+ if ( !target.empty() )
+ {
+ if ( target == "_external" )
+ {
+ mExternalUrl = url;
+ LLSD payload;
+ payload["external_url"] = mExternalUrl;
+ LLNotifications::instance().add( "WebLaunchExternalTarget", LLSD(), payload, onClickLinkExternalTarget);
+ return;
+ }
+ }
+
+ const std::string protocol1( "http://" );
+ const std::string protocol2( "https://" );
+ if( mOpenLinksInExternalBrowser )
+ {
+ if ( !url.empty() )
+ {
+ if ( LLStringUtil::compareInsensitive( url.substr( 0, protocol1.length() ), protocol1 ) == 0 ||
+ LLStringUtil::compareInsensitive( url.substr( 0, protocol2.length() ), protocol2 ) == 0 )
+ {
+ LLWeb::loadURLExternal( url );
+ }
+ }
+ }
+ else
+ if( mOpenLinksInInternalBrowser )
+ {
+ if ( !url.empty() )
+ {
+ if ( LLStringUtil::compareInsensitive( url.substr( 0, protocol1.length() ), protocol1 ) == 0 ||
+ LLStringUtil::compareInsensitive( url.substr( 0, protocol2.length() ), protocol2 ) == 0 )
+ {
+ // If we spawn a new LLFloaterHTML, assume we want it to
+ // follow this LLMediaCtrl's trust for whether or
+ // not to open secondlife:///app/ links. JC.
+// const bool open_links_externally = false;
+// LLFloaterHtml::getInstance()->show(
+// event_in.mStringPayload,
+// "Second Life Browser",
+// open_links_externally,
+// mTrusted);
+ }
+ }
+ }
+}
+
+////////////////////////////////////////////////////////////////////////////////
+//
+void LLMediaCtrl::onClickLinkNoFollow( LLPluginClassMedia* self )
+{
+ std::string url = self->getClickURL();
+ if (LLSLURL::isSLURLCommand(url)
+ && !mTrusted)
+ {
+ // block handling of this secondlife:///app/ URL
+ LLNotifications::instance().add("UnableToOpenCommandURL");
+ return;
+ }
+
+ LLURLDispatcher::dispatch(url, this, mTrusted);
+}
+
+////////////////////////////////////////////////////////////////////////////////
+//
+std::string LLMediaCtrl::getCurrentNavUrl()
+{
+ return mCurrentNavUrl;
+}
+
diff --git a/indra/newview/llmediactrl.h b/indra/newview/llmediactrl.h
new file mode 100644
index 0000000000..a19b3ad67b
--- /dev/null
+++ b/indra/newview/llmediactrl.h
@@ -0,0 +1,182 @@
+/**
+ * @file llmediactrl.h
+ * @brief Web browser UI control
+ *
+ * $LicenseInfo:firstyear=2006&license=viewergpl$
+ *
+ * Copyright (c) 2006-2009, Linden Research, Inc.
+ *
+ * Second Life Viewer Source Code
+ * The source code in this file ("Source Code") is provided by Linden Lab
+ * to you under the terms of the GNU General Public License, version 2.0
+ * ("GPL"), unless you have obtained a separate licensing agreement
+ * ("Other License"), formally executed by you and Linden Lab. Terms of
+ * the GPL can be found in doc/GPL-license.txt in this distribution, or
+ * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
+ *
+ * There are special exceptions to the terms and conditions of the GPL as
+ * it is applied to this Source Code. View the full text of the exception
+ * in the file doc/FLOSS-exception.txt in this software distribution, or
+ * online at
+ * http://secondlifegrid.net/programs/open_source/licensing/flossexception
+ *
+ * By copying, modifying or distributing this software, you acknowledge
+ * that you have read and understood your obligations described above,
+ * and agree to abide by those obligations.
+ *
+ * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+ * COMPLETENESS OR PERFORMANCE.
+ * $/LicenseInfo$
+ */
+
+#ifndef LL_LLMediaCtrl_H
+#define LL_LLMediaCtrl_H
+
+#include "llviewermedia.h"
+
+#include "lluictrl.h"
+#include "llframetimer.h"
+#include "lldynamictexture.h"
+
+class LLViewBorder;
+class LLUICtrlFactory;
+
+////////////////////////////////////////////////////////////////////////////////
+//
+class LLMediaCtrl :
+ public LLPanel,
+ public LLViewerMediaObserver,
+ public LLViewerMediaEventEmitter
+{
+ LOG_CLASS(LLMediaCtrl);
+
+public:
+ struct Params : public LLInitParam::Block<Params, LLPanel::Params>
+ {
+ Optional<std::string> start_url;
+
+ Optional<bool> border_visible,
+ ignore_ui_scale,
+ hide_loading;
+
+ Optional<LLUIColor> caret_color;
+
+ Params();
+ };
+
+protected:
+ LLMediaCtrl(const Params&);
+ friend class LLUICtrlFactory;
+
+public:
+ virtual ~LLMediaCtrl();
+
+ void setBorderVisible( BOOL border_visible );
+
+ // For the tutorial window, we don't want to take focus on clicks,
+ // as the examples include how to move around with the arrow
+ // keys. Thus we keep focus on the app by setting this false.
+ // Defaults to true.
+ void setTakeFocusOnClick( bool take_focus );
+
+ // handle mouse related methods
+ virtual BOOL handleHover( S32 x, S32 y, MASK mask );
+ virtual BOOL handleMouseUp( S32 x, S32 y, MASK mask );
+ virtual BOOL handleMouseDown( S32 x, S32 y, MASK mask );
+ virtual BOOL handleDoubleClick( S32 x, S32 y, MASK mask );
+ virtual BOOL handleScrollWheel( S32 x, S32 y, S32 clicks );
+
+ // navigation
+ void navigateTo( std::string url_in, std::string mime_type = "");
+ void navigateBack();
+ void navigateHome();
+ void navigateForward();
+ void navigateToLocalPage( const std::string& subdir, const std::string& filename_in );
+ bool canNavigateBack();
+ bool canNavigateForward();
+ void setOpenInExternalBrowser( bool valIn );
+ void setOpenInInternalBrowser( bool valIn );
+ std::string getCurrentNavUrl();
+
+ // By default, we do not handle "secondlife:///app/" SLURLs, because
+ // those can cause teleports, open windows, etc. We cannot be sure
+ // that each "click" is actually due to a user action, versus
+ // Javascript or some other mechanism. However, we need the search
+ // floater and login page to handle these URLs. Those are safe
+ // because we control the page content. See DEV-9530. JC.
+ void setTrusted( bool valIn );
+
+ void setHomePageUrl( const std::string urlIn );
+ std::string getHomePageUrl();
+
+ // set/clear URL to visit when a 404 page is reached
+ void set404RedirectUrl( std::string redirect_url );
+ void clr404RedirectUrl();
+
+ // accessor/mutator for flag that indicates if frequent updates to texture happen
+ bool getFrequentUpdates() { return mFrequentUpdates; };
+ void setFrequentUpdates( bool frequentUpdatesIn ) { mFrequentUpdates = frequentUpdatesIn; };
+
+ void setIgnoreUIScale(bool ignore) { mIgnoreUIScale = ignore; }
+ bool getIgnoreUIScale() { return mIgnoreUIScale; }
+
+ void setAlwaysRefresh(bool refresh) { mAlwaysRefresh = refresh; }
+ bool getAlwaysRefresh() { return mAlwaysRefresh; }
+
+ void setForceUpdate(bool force_update) { mForceUpdate = force_update; }
+ bool getForceUpdate() { return mForceUpdate; }
+
+ LLPluginClassMedia* getMediaPlugin();
+
+ bool setCaretColor( unsigned int red, unsigned int green, unsigned int blue );
+
+
+ // over-rides
+ virtual BOOL handleKeyHere( KEY key, MASK mask);
+ virtual void handleVisibilityChange ( BOOL new_visibility );
+ virtual BOOL handleUnicodeCharHere(llwchar uni_char);
+ virtual void reshape( S32 width, S32 height, BOOL called_from_parent = TRUE);
+ virtual void draw();
+ virtual BOOL postBuild();
+
+ // focus overrides
+ void onFocusLost();
+ void onFocusReceived();
+
+ // Incoming media event dispatcher
+ virtual void handleMediaEvent(LLPluginClassMedia* self, EMediaEvent event);
+
+ // handlers for individual events (could be done inside the switch in handleMediaEvent, they're just individual functions for clarity)
+ void onClickLinkHref( LLPluginClassMedia* self );
+ void onClickLinkNoFollow( LLPluginClassMedia* self );
+
+ protected:
+ void convertInputCoords(S32& x, S32& y);
+
+ private:
+ void onVisibilityChange ( const LLSD& new_visibility );
+ static bool onClickLinkExternalTarget( const LLSD&, const LLSD& );
+
+ const S32 mTextureDepthBytes;
+ LLUUID mMediaTextureID;
+ LLViewBorder* mBorder;
+ bool mFrequentUpdates;
+ bool mForceUpdate;
+ bool mOpenLinksInExternalBrowser;
+ bool mOpenLinksInInternalBrowser;
+ bool mTrusted;
+ std::string mHomePageUrl;
+ std::string mExternalUrl;
+ std::string mCurrentNavUrl;
+ bool mIgnoreUIScale;
+ bool mAlwaysRefresh;
+ viewer_media_t mMediaSource;
+ bool mTakeFocusOnClick;
+ ECursorType mLastSetCursor;
+ bool mStretchToFill;
+ bool mMaintainAspectRatio;
+ bool mHideLoading;
+};
+
+#endif // LL_LLMediaCtrl_H
diff --git a/indra/newview/llmemoryview.cpp b/indra/newview/llmemoryview.cpp
index 215cc6940b..3c7716e9c2 100644
--- a/indra/newview/llmemoryview.cpp
+++ b/indra/newview/llmemoryview.cpp
@@ -35,34 +35,20 @@
#include "indra_constants.h"
#include "llmemoryview.h"
-#include "llrect.h"
-#include "llerror.h"
-#include "llgl.h"
-#include "llmath.h"
-#include "llfontgl.h"
-#include "llmemtype.h"
-
-#include "llcharacter.h"
-#include "llui.h"
+#include "llappviewer.h"
+#include "llallocator_heap_profile.h"
+#include "llviewerwindow.h"
#include "llviewercontrol.h"
-#include "llstat.h"
-#include "llfasttimer.h"
+#include <sstream>
+#include <boost/algorithm/string/split.hpp>
-
-LLMemoryView::LLMemoryView(const std::string& name, const LLRect& rect)
-: LLView(name, rect, TRUE),
-mDelay(120)
+LLMemoryView::LLMemoryView(const LLMemoryView::Params& p)
+: LLView(p),
+ //mDelay(120),
+ mAlloc(NULL)
{
- setVisible(FALSE);
- mDumpTimer.reset();
-
-#ifdef MEM_DUMP_DATA
- // clear out file.
- LLFILE *dump = LLFile::fopen("memusagedump.txt", "w");
- fclose(dump);
-#endif
}
LLMemoryView::~LLMemoryView()
@@ -94,62 +80,101 @@ BOOL LLMemoryView::handleHover(S32 x, S32 y, MASK mask)
return FALSE;
}
-//////////////////////////////////////////////////////////////////////////////
-
-struct mtv_display_info {
- S32 memtype;
- const char *desc;
- const LLColor4 *color;
-};
-
-static const LLColor4 red0(0.5f, 0.0f, 0.0f, 1.0f);
-
-static const struct mtv_display_info mtv_display_table[] =
+void LLMemoryView::refreshProfile()
{
- { LLMemType::MTYPE_INIT, "Init", &LLColor4::white },
- { LLMemType::MTYPE_STARTUP, "Startup", &LLColor4::cyan1 },
- { LLMemType::MTYPE_MAIN, "Main", &LLColor4::cyan2 },
- { LLMemType::MTYPE_IMAGEBASE, "ImageBase", &LLColor4::yellow1 },
- { LLMemType::MTYPE_IMAGERAW, "ImageRaw", &LLColor4::yellow2 },
- { LLMemType::MTYPE_IMAGEFORMATTED, "ImageFmtd", &LLColor4::yellow3 },
- { LLMemType::MTYPE_APPFMTIMAGE, "ViewerImageFmt", &LLColor4::orange1 },
- { LLMemType::MTYPE_APPRAWIMAGE, "ViewerImageRaw", &LLColor4::orange2 },
- { LLMemType::MTYPE_APPAUXRAWIMAGE, "ViewerImageAux", &LLColor4::orange3 },
- { LLMemType::MTYPE_DRAWABLE, "Drawable", &LLColor4::green1 },
- { LLMemType::MTYPE_OBJECT, "ViewerObject", &LLColor4::green2 },
- { LLMemType::MTYPE_PIPELINE, "Pipeline", &LLColor4::green3 },
- { LLMemType::MTYPE_PARTICLES, "Particles", &LLColor4::green4 },
- { LLMemType::MTYPE_SPACE_PARTITION, "Space Partition", &LLColor4::blue2 },
- { LLMemType::MTYPE_VERTEX_DATA, "Vertex Buffer", &LLColor4::blue3 },
- { LLMemType::MTYPE_AVATAR, "Avatar", &LLColor4::purple1 },
- { LLMemType::MTYPE_AVATAR_MESH, "Avatar Mesh", &LLColor4::purple2 },
- { LLMemType::MTYPE_ANIMATION, "Animation", &LLColor4::purple3 },
- { LLMemType::MTYPE_REGIONS, "Regions", &LLColor4::blue1 },
- { LLMemType::MTYPE_VOLUME, "Volume", &LLColor4::pink1 },
- { LLMemType::MTYPE_PRIMITIVE, "Profile", &LLColor4::pink2 },
- { LLMemType::MTYPE_TEMP1, "Temp1", &LLColor4::red1 },
- { LLMemType::MTYPE_TEMP2, "Temp2", &LLColor4::magenta1 },
- { LLMemType::MTYPE_TEMP3, "Temp3", &LLColor4::red2 },
- { LLMemType::MTYPE_TEMP4, "Temp4", &LLColor4::magenta2 },
- { LLMemType::MTYPE_TEMP5, "Temp5", &LLColor4::red3 },
- { LLMemType::MTYPE_TEMP6, "Temp6", &LLColor4::magenta3 },
- { LLMemType::MTYPE_TEMP7, "Temp7", &LLColor4::red4 },
- { LLMemType::MTYPE_TEMP8, "Temp8", &LLColor4::magenta4 },
-
- { LLMemType::MTYPE_OTHER, "Other", &red0 },
-};
-static const int MTV_DISPLAY_NUM = LL_ARRAY_SIZE(mtv_display_table);
+ /*
+ LLAllocator & alloc = LLAppViewer::instance()->getAllocator();
+ if(alloc.isProfiling()) {
+ std::string profile_text = alloc.getRawProfile();
+
+ boost::algorithm::split(mLines, profile_text, boost::bind(std::equal_to<llwchar>(), '\n', _1));
+ } else {
+ mLines.clear();
+ }
+ */
+ if (mAlloc == NULL) {
+ mAlloc = &LLAppViewer::instance()->getAllocator();
+ }
+
+ mLines.clear();
+
+ if(mAlloc->isProfiling())
+ {
+ const LLAllocatorHeapProfile &prof = mAlloc->getProfile();
+ for(size_t i = 0; i < prof.mLines.size(); ++i)
+ {
+ std::stringstream ss;
+ ss << "Unfreed Mem: " << (prof.mLines[i].mLiveSize >> 20) << " M Trace: ";
+ for(size_t k = 0; k < prof.mLines[i].mTrace.size(); ++k)
+ {
+ ss << LLMemType::getNameFromID(prof.mLines[i].mTrace[k]) << " ";
+ }
+ mLines.push_back(utf8string_to_wstring(ss.str()));
+ }
+ }
+}
void LLMemoryView::draw()
{
- std::string tdesc;
- S32 width = getRect().getWidth();
- S32 height = getRect().getHeight();
+ const S32 UPDATE_INTERVAL = 60;
+ const S32 MARGIN_AMT = 10;
+ static S32 curUpdate = UPDATE_INTERVAL;
+ static LLUIColor s_console_color = LLUIColorTable::instance().getColor("ConsoleBackground", LLColor4U::black);
+
+ // setup update interval
+ if (curUpdate >= UPDATE_INTERVAL)
+ {
+ refreshProfile();
+ curUpdate = 0;
+ }
+ curUpdate++;
+
+ // setup window properly
+ S32 height = (S32) (gViewerWindow->getVirtualWindowRect().getHeight()*0.75f);
+ S32 width = (S32) (gViewerWindow->getVirtualWindowRect().getWidth() * 0.9f);
+ setRect(LLRect().setLeftTopAndSize(getRect().mLeft, getRect().mTop, width, height));
+ // setup window color
+ F32 console_opacity = llclamp(gSavedSettings.getF32("ConsoleBackgroundOpacity"), 0.f, 1.f);
+ LLColor4 color = s_console_color;
+ color.mV[VALPHA] *= console_opacity;
+
LLGLSUIDefault gls_ui;
gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
- gl_rect_2d(0, height, width, 0, LLColor4(0.f, 0.f, 0.f, 0.25f));
+ gl_rect_2d(0, height, width, 0, color);
+ LLFontGL * font = LLFontGL::getFontSansSerifSmall();
+
+ // draw remaining lines
+ F32 y_pos = 0.f;
+ F32 y_off = 0.f;
+
+ F32 line_height = font->getLineHeight();
+ S32 target_width = width - 2 * MARGIN_AMT;
+
+ // cut off lines on bottom
+ U32 max_lines = U32((height - 2 * line_height) / line_height);
+ std::vector<LLWString>::const_iterator end = mLines.end();
+ if(mLines.size() > max_lines) {
+ end = mLines.begin() + max_lines;
+ }
+
+ y_pos = height - MARGIN_AMT - line_height;
+ y_off = 0.f;
+ for (std::vector<LLWString>::const_iterator i = mLines.begin(); i != end; ++i)
+ {
+ font->render(*i, 0, MARGIN_AMT, y_pos - y_off,
+ LLColor4::white,
+ LLFontGL::LEFT,
+ LLFontGL::BASELINE,
+ LLFontGL::NORMAL,
+ LLFontGL::DROP_SHADOW,
+ S32_MAX,
+ target_width
+ );
+ y_off += line_height;
+ }
+
#if MEM_TRACK_TYPE
S32 left, top, right, bottom;
@@ -267,40 +292,3 @@ void LLMemoryView::draw()
LLView::draw();
}
-
-void LLMemoryView::setDataDumpInterval(float delay)
-{
- mDelay = delay;
-}
-
-void LLMemoryView::dumpData()
-{
-#if MEM_TRACK_TYPE && MEM_DUMP_DATA
- if (mDelay && (mDumpTimer.getElapsedTimeF32() > mDelay ))
- {
- // reset timer
- mDumpTimer.reset();
- // append dump info to text file
- LLFILE *dump = LLFile::fopen("memusagedump.txt", "a");
-
- if (dump)
- {
- // write out total memory usage
- fprintf (dump, "Total memory in use = %09d (%03d MB)\n", LLMemType::sTotalMem, LLMemType::sTotalMem>>20);
- fprintf (dump, "High Water Mark = %09d (%03d MB)\n\n", LLMemType::sMaxTotalMem, LLMemType::sMaxTotalMem>>20);
- // dump out usage of 'new' for each memory type
- for (S32 i=0; i<LLMemType::MTYPE_NUM_TYPES; i++)
- {
- if (LLMemType::sMemCount[i])
- {
- std::string outData = llformat("MEM: % 20s %09d %03d MB (%09d %03d MB) in %06d News", LLMemType::sTypeDesc[i], LLMemType::sMemCount[i], LLMemType::sMemCount[i]>>20, LLMemType::sMaxMemCount[i], LLMemType::sMaxMemCount[i]>>20, LLMemType::sNewCount[i]);
- fprintf (dump, "%s\n", outData.c_str());
- }
- }
- fprintf (dump, "\n\n");
-
- fclose(dump);
- }
- }
-#endif
-}
diff --git a/indra/newview/llmemoryview.h b/indra/newview/llmemoryview.h
index 81466bd6b0..774a52b88b 100644
--- a/indra/newview/llmemoryview.h
+++ b/indra/newview/llmemoryview.h
@@ -35,10 +35,20 @@
#include "llview.h"
+class LLAllocator;
+
class LLMemoryView : public LLView
{
public:
- LLMemoryView(const std::string& name, const LLRect& rect);
+ struct Params : public LLInitParam::Block<Params, LLView::Params>
+ {
+ Params()
+ {
+ mouse_opaque = true;
+ visible = false;
+ }
+ };
+ LLMemoryView(const LLMemoryView::Params&);
virtual ~LLMemoryView();
virtual BOOL handleMouseDown(S32 x, S32 y, MASK mask);
@@ -46,14 +56,12 @@ public:
virtual BOOL handleHover(S32 x, S32 y, MASK mask);
virtual void draw();
-private:
- void setDataDumpInterval(float delay);
- void dumpData();
-
- float mDelay;
- LLFrameTimer mDumpTimer;
+ void refreshProfile();
private:
+ std::vector<LLWString> mLines;
+ LLAllocator* mAlloc;
+
};
#endif
diff --git a/indra/newview/llmenucommands.cpp b/indra/newview/llmenucommands.cpp
index ac77a920a5..1666ec1336 100644
--- a/indra/newview/llmenucommands.cpp
+++ b/indra/newview/llmenucommands.cpp
@@ -35,6 +35,7 @@
#include "llmenucommands.h"
#include "imageids.h"
+#include "llfloaterreg.h"
#include "llfontgl.h"
#include "llrect.h"
#include "llerror.h"
@@ -43,15 +44,13 @@
#include "llagent.h"
#include "llcallingcard.h"
-#include "llchatbar.h"
#include "llviewercontrol.h"
#include "llfirstuse.h"
#include "llfloaterchat.h"
#include "llfloaterdirectory.h"
-#include "llfloatermap.h"
#include "llfloaterworldmap.h"
#include "llgivemoney.h"
-#include "llinventoryview.h"
+#include "lllineeditor.h"
#include "llnotify.h"
#include "llstatusbar.h"
#include "llimview.h"
@@ -67,14 +66,7 @@
#include "llworld.h"
#include "llworldmap.h"
#include "llfocusmgr.h"
-
-void handle_track_avatar(const LLUUID& agent_id, const std::string& name)
-{
- LLAvatarTracker::instance().track(agent_id, name);
-
- LLFloaterDirectory::hide(NULL);
- LLFloaterWorldMap::show(NULL, TRUE);
-}
+#include "llnearbychatbar.h"
void handle_pay_by_id(const LLUUID& agent_id)
{
@@ -88,55 +80,23 @@ void handle_mouselook(void*)
}
-void handle_map(void*)
-{
- LLFloaterWorldMap::toggle(NULL);
-}
-
-void handle_mini_map(void*)
-{
- LLFloaterMap::toggleInstance();
-}
-
-
-void handle_find(void*)
-{
- LLFloaterDirectory::toggleFind(NULL);
-}
-
-
-void handle_events(void*)
-{
- LLFloaterDirectory::toggleEvents(NULL);
-}
-
-
-void handle_inventory(void*)
-{
- // We're using the inventory, possibly for the
- // first time.
- LLFirstUse::useInventory();
-
- LLInventoryView::toggleVisibility(NULL);
-}
-
-
void handle_chat(void*)
{
// give focus to chatbar if it's open but not focused
- if (gSavedSettings.getBOOL("ChatVisible") && gFocusMgr.childHasKeyboardFocus(gChatBar))
+ if (gSavedSettings.getBOOL("ChatVisible") &&
+ gFocusMgr.childHasKeyboardFocus(LLNearbyChatBar::getInstance()->getChatBox()))
{
- LLChatBar::stopChat();
+ LLNearbyChatBar::stopChat();
}
else
{
- LLChatBar::startChat(NULL);
+ LLNearbyChatBar::startChat(NULL);
}
}
void handle_slash_key(void*)
{
- // LLChatBar::startChat("/");
+ // LLBottomTray::startChat("/");
//
// Don't do this, it results in a double-slash in the input field.
// Another "/" will be automatically typed for us, because the WM_KEYDOWN event
@@ -146,5 +106,5 @@ void handle_slash_key(void*)
// menu accelerators that put input focus into a field. And Mac works
// the same way. JC
- LLChatBar::startChat(NULL);
+ LLNearbyChatBar::startChat(NULL);
}
diff --git a/indra/newview/llmenucommands.h b/indra/newview/llmenucommands.h
index 03f7a2571c..368c6fe752 100644
--- a/indra/newview/llmenucommands.h
+++ b/indra/newview/llmenucommands.h
@@ -35,14 +35,8 @@
class LLUUID;
-void handle_track_avatar(const LLUUID& agent_id, const std::string& name);
void handle_pay_by_id(const LLUUID& agent_id);
void handle_mouselook(void*);
-void handle_map(void*);
-void handle_mini_map(void*);
-void handle_find(void*);
-void handle_events(void*);
-void handle_inventory(void*);
void handle_chat(void*);
void handle_return_key(void*);
void handle_slash_key(void*);
diff --git a/indra/newview/llmetricperformancetester.cpp b/indra/newview/llmetricperformancetester.cpp
new file mode 100644
index 0000000000..93288c98d7
--- /dev/null
+++ b/indra/newview/llmetricperformancetester.cpp
@@ -0,0 +1,258 @@
+/**
+ * @file llmetricperformancetester.cpp
+ * @brief LLMetricPerformanceTester class implementation
+ *
+ * $LicenseInfo:firstyear=2004&license=viewergpl$
+ *
+ * Copyright (c) 2004-2009, Linden Research, Inc.
+ *
+ * Second Life Viewer Source Code
+ * The source code in this file ("Source Code") is provided by Linden Lab
+ * to you under the terms of the GNU General Public License, version 2.0
+ * ("GPL"), unless you have obtained a separate licensing agreement
+ * ("Other License"), formally executed by you and Linden Lab. Terms of
+ * the GPL can be found in doc/GPL-license.txt in this distribution, or
+ * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
+ *
+ * There are special exceptions to the terms and conditions of the GPL as
+ * it is applied to this Source Code. View the full text of the exception
+ * in the file doc/FLOSS-exception.txt in this software distribution, or
+ * online at
+ * http://secondlifegrid.net/programs/open_source/licensing/flossexception
+ *
+ * By copying, modifying or distributing this software, you acknowledge
+ * that you have read and understood your obligations described above,
+ * and agree to abide by those obligations.
+ *
+ * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+ * COMPLETENESS OR PERFORMANCE.
+ * $/LicenseInfo$
+ */
+
+#include "llviewerprecompiledheaders.h"
+
+#include "indra_constants.h"
+#include "llerror.h"
+#include "llmath.h"
+#include "llfontgl.h"
+#include "llsdserialize.h"
+#include "llstat.h"
+#include "lltreeiterators.h"
+#include "llmetricperformancetester.h"
+
+LLMetricPerformanceTester::name_tester_map_t LLMetricPerformanceTester::sTesterMap ;
+
+//static
+void LLMetricPerformanceTester::initClass()
+{
+}
+//static
+void LLMetricPerformanceTester::cleanClass()
+{
+ for(name_tester_map_t::iterator iter = sTesterMap.begin() ; iter != sTesterMap.end() ; ++iter)
+ {
+ delete iter->second ;
+ }
+ sTesterMap.clear() ;
+}
+
+//static
+void LLMetricPerformanceTester::addTester(LLMetricPerformanceTester* tester)
+{
+ if(!tester)
+ {
+ llerrs << "invalid tester!" << llendl ;
+ return ;
+ }
+
+ std::string name = tester->getName() ;
+ if(getTester(name))
+ {
+ llerrs << "Tester name is used by some other tester: " << name << llendl ;
+ return ;
+ }
+
+ sTesterMap.insert(std::make_pair(name, tester));
+
+ return ;
+}
+
+//static
+LLMetricPerformanceTester* LLMetricPerformanceTester::getTester(std::string label)
+{
+ name_tester_map_t::iterator found_it = sTesterMap.find(label) ;
+ if(found_it != sTesterMap.end())
+ {
+ return found_it->second ;
+ }
+
+ return NULL ;
+}
+
+LLMetricPerformanceTester::LLMetricPerformanceTester(std::string name, BOOL use_default_performance_analysis)
+ : mName(name),
+ mBaseSessionp(NULL),
+ mCurrentSessionp(NULL),
+ mCount(0),
+ mUseDefaultPerformanceAnalysis(use_default_performance_analysis)
+{
+ if(mName == std::string())
+ {
+ llerrs << "invalid name." << llendl ;
+ }
+
+ LLMetricPerformanceTester::addTester(this) ;
+}
+
+/*virtual*/
+LLMetricPerformanceTester::~LLMetricPerformanceTester()
+{
+ if(mBaseSessionp)
+ {
+ delete mBaseSessionp ;
+ mBaseSessionp = NULL ;
+ }
+ if(mCurrentSessionp)
+ {
+ delete mCurrentSessionp ;
+ mCurrentSessionp = NULL ;
+ }
+}
+
+void LLMetricPerformanceTester::incLabel()
+{
+ mCurLabel = llformat("%s-%d", mName.c_str(), mCount++) ;
+}
+void LLMetricPerformanceTester::preOutputTestResults(LLSD* sd)
+{
+ incLabel() ;
+ (*sd)[mCurLabel]["Name"] = mName ;
+}
+void LLMetricPerformanceTester::postOutputTestResults(LLSD* sd)
+{
+ LLMutexLock lock(LLFastTimer::sLogLock);
+ LLFastTimer::sLogQueue.push((*sd));
+}
+
+void LLMetricPerformanceTester::outputTestResults()
+{
+ LLSD sd ;
+ preOutputTestResults(&sd) ;
+
+ outputTestRecord(&sd) ;
+
+ postOutputTestResults(&sd) ;
+}
+
+void LLMetricPerformanceTester::addMetricString(std::string str)
+{
+ mMetricStrings.push_back(str) ;
+}
+
+const std::string& LLMetricPerformanceTester::getMetricString(U32 index) const
+{
+ return mMetricStrings[index] ;
+}
+
+void LLMetricPerformanceTester::prePerformanceAnalysis()
+{
+ mCount = 0 ;
+ incLabel() ;
+}
+
+//
+//default analyzing the performance
+//
+/*virtual*/
+void LLMetricPerformanceTester::analyzePerformance(std::ofstream* os, LLSD* base, LLSD* current)
+{
+ if(mUseDefaultPerformanceAnalysis)//use default performance analysis
+ {
+ prePerformanceAnalysis() ;
+
+ BOOL in_base = (*base).has(mCurLabel) ;
+ BOOL in_current = (*current).has(mCurLabel) ;
+
+ while(in_base || in_current)
+ {
+ LLSD::String label = mCurLabel ;
+
+ if(in_base && in_current)
+ {
+ *os << llformat("%s\n", label.c_str()) ;
+
+ for(U32 index = 0 ; index < mMetricStrings.size() ; index++)
+ {
+ switch((*current)[label][ mMetricStrings[index] ].type())
+ {
+ case LLSD::TypeInteger:
+ compareTestResults(os, mMetricStrings[index],
+ (S32)((*base)[label][ mMetricStrings[index] ].asInteger()), (S32)((*current)[label][ mMetricStrings[index] ].asInteger())) ;
+ break ;
+ case LLSD::TypeReal:
+ compareTestResults(os, mMetricStrings[index],
+ (F32)((*base)[label][ mMetricStrings[index] ].asReal()), (F32)((*current)[label][ mMetricStrings[index] ].asReal())) ;
+ break;
+ default:
+ llerrs << "unsupported metric " << mMetricStrings[index] << " LLSD type: " << (S32)(*current)[label][ mMetricStrings[index] ].type() << llendl ;
+ }
+ }
+ }
+
+ incLabel() ;
+ in_base = (*base).has(mCurLabel) ;
+ in_current = (*current).has(mCurLabel) ;
+ }
+ }//end of default
+ else
+ {
+ //load the base session
+ prePerformanceAnalysis() ;
+ mBaseSessionp = loadTestSession(base) ;
+
+ //load the current session
+ prePerformanceAnalysis() ;
+ mCurrentSessionp = loadTestSession(current) ;
+
+ if(!mBaseSessionp || !mCurrentSessionp)
+ {
+ llerrs << "memory error during loading test sessions." << llendl ;
+ }
+
+ //compare
+ compareTestSessions(os) ;
+
+ //release memory
+ if(mBaseSessionp)
+ {
+ delete mBaseSessionp ;
+ mBaseSessionp = NULL ;
+ }
+ if(mCurrentSessionp)
+ {
+ delete mCurrentSessionp ;
+ mCurrentSessionp = NULL ;
+ }
+ }
+}
+
+//virtual
+void LLMetricPerformanceTester::compareTestResults(std::ofstream* os, std::string metric_string, S32 v_base, S32 v_current)
+{
+ *os << llformat(" ,%s, %d, %d, %d, %.4f\n", metric_string.c_str(), v_base, v_current,
+ v_current - v_base, (v_base != 0) ? 100.f * v_current / v_base : 0) ;
+}
+
+//virtual
+void LLMetricPerformanceTester::compareTestResults(std::ofstream* os, std::string metric_string, F32 v_base, F32 v_current)
+{
+ *os << llformat(" ,%s, %.4f, %.4f, %.4f, %.4f\n", metric_string.c_str(), v_base, v_current,
+ v_current - v_base, (fabs(v_base) > 0.0001f) ? 100.f * v_current / v_base : 0.f ) ;
+}
+
+//virtual
+LLMetricPerformanceTester::LLTestSession::~LLTestSession()
+{
+}
+
diff --git a/indra/newview/llmetricperformancetester.h b/indra/newview/llmetricperformancetester.h
new file mode 100644
index 0000000000..ab5ccaeb8e
--- /dev/null
+++ b/indra/newview/llmetricperformancetester.h
@@ -0,0 +1,159 @@
+/**
+ * @file LLMetricPerformanceTester.h
+ * @brief LLMetricPerformanceTester class definition
+ *
+ * $LicenseInfo:firstyear=2004&license=viewergpl$
+ *
+ * Copyright (c) 2004-2009, Linden Research, Inc.
+ *
+ * Second Life Viewer Source Code
+ * The source code in this file ("Source Code") is provided by Linden Lab
+ * to you under the terms of the GNU General Public License, version 2.0
+ * ("GPL"), unless you have obtained a separate licensing agreement
+ * ("Other License"), formally executed by you and Linden Lab. Terms of
+ * the GPL can be found in doc/GPL-license.txt in this distribution, or
+ * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
+ *
+ * There are special exceptions to the terms and conditions of the GPL as
+ * it is applied to this Source Code. View the full text of the exception
+ * in the file doc/FLOSS-exception.txt in this software distribution, or
+ * online at
+ * http://secondlifegrid.net/programs/open_source/licensing/flossexception
+ *
+ * By copying, modifying or distributing this software, you acknowledge
+ * that you have read and understood your obligations described above,
+ * and agree to abide by those obligations.
+ *
+ * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+ * COMPLETENESS OR PERFORMANCE.
+ * $/LicenseInfo$
+ */
+
+#ifndef LL_METRICPERFORMANCETESTER_H
+#define LL_METRICPERFORMANCETESTER_H
+
+class LLMetricPerformanceTester
+{
+public:
+ //
+ //name passed to the constructor is a unique string for each tester.
+ //an error is reported if the name is already used by some other tester.
+ //
+ LLMetricPerformanceTester(std::string name, BOOL use_default_performance_analysis) ;
+ virtual ~LLMetricPerformanceTester();
+
+ //
+ //return the name of the tester
+ //
+ std::string getName() const { return mName ;}
+ //
+ //return the number of the test metrics in this tester
+ //
+ S32 getNumOfMetricStrings() const { return mMetricStrings.size() ;}
+ //
+ //return the metric string at the index
+ //
+ const std::string& getMetricString(U32 index) const ;
+
+ //
+ //this function to compare the test results.
+ //by default, it compares the test results against the baseline one by one, item by item,
+ //in the increasing order of the LLSD label counter, starting from the first one.
+ //you can define your own way to analyze performance by passing FALSE to "use_default_performance_analysis",
+ //and implement two abstract virtual functions below: loadTestSession(...) and compareTestSessions(...).
+ //
+ void analyzePerformance(std::ofstream* os, LLSD* base, LLSD* current) ;
+
+protected:
+ //
+ //insert metric strings used in the tester.
+ //
+ void addMetricString(std::string str) ;
+
+ //
+ //increase LLSD label by 1
+ //
+ void incLabel() ;
+
+ //
+ //the function to write a set of test results to the log LLSD.
+ //
+ void outputTestResults() ;
+
+ //
+ //compare the test results.
+ //you can write your own to overwrite the default one.
+ //
+ virtual void compareTestResults(std::ofstream* os, std::string metric_string, S32 v_base, S32 v_current) ;
+ virtual void compareTestResults(std::ofstream* os, std::string metric_string, F32 v_base, F32 v_current) ;
+
+ //
+ //for performance analysis use
+ //it defines an interface for the two abstract virtual functions loadTestSession(...) and compareTestSessions(...).
+ //please make your own test session class derived from it.
+ //
+ class LLTestSession
+ {
+ public:
+ virtual ~LLTestSession() ;
+ };
+
+ //
+ //load a test session for log LLSD
+ //you need to implement it only when you define your own way to analyze performance.
+ //otherwise leave it empty.
+ //
+ virtual LLMetricPerformanceTester::LLTestSession* loadTestSession(LLSD* log) = 0 ;
+ //
+ //compare the base session and the target session
+ //you need to implement it only when you define your own way to analyze performance.
+ //otherwise leave it empty.
+ //
+ virtual void compareTestSessions(std::ofstream* os) = 0 ;
+ //
+ //the function to write a set of test results to the log LLSD.
+ //you have to write you own version of this function.
+ //
+ virtual void outputTestRecord(LLSD* sd) = 0 ;
+
+private:
+ void preOutputTestResults(LLSD* sd) ;
+ void postOutputTestResults(LLSD* sd) ;
+ void prePerformanceAnalysis() ;
+
+protected:
+ //
+ //the unique name string of the tester
+ //
+ std::string mName ;
+ //
+ //the current label counter for the log LLSD
+ //
+ std::string mCurLabel ;
+ S32 mCount ;
+
+ BOOL mUseDefaultPerformanceAnalysis ;
+ LLTestSession* mBaseSessionp ;
+ LLTestSession* mCurrentSessionp ;
+
+ //metrics strings
+ std::vector< std::string > mMetricStrings ;
+
+//static members
+private:
+ static void addTester(LLMetricPerformanceTester* tester) ;
+
+public:
+ typedef std::map< std::string, LLMetricPerformanceTester* > name_tester_map_t;
+ static name_tester_map_t sTesterMap ;
+
+ static LLMetricPerformanceTester* getTester(std::string label) ;
+ static BOOL hasMetricPerformanceTesters() {return !sTesterMap.empty() ;}
+
+ static void initClass() ;
+ static void cleanClass() ;
+};
+
+#endif
+
diff --git a/indra/newview/llmimetypes.cpp b/indra/newview/llmimetypes.cpp
index bfbc81aa66..525e89cdff 100644
--- a/indra/newview/llmimetypes.cpp
+++ b/indra/newview/llmimetypes.cpp
@@ -46,6 +46,8 @@ std::string sDefaultWidgetType;
// Returned when we don't know what widget set to use
std::string sDefaultImpl;
// Returned when we don't know what impl to use
+std::string sXMLFilename;
+ // Squirrel away XML filename so we know how to reset
/////////////////////////////////////////////////////////////////////////////
@@ -146,6 +148,8 @@ bool LLMIMETypes::parseMIMETypes(const std::string& xml_filename)
sWidgetMap[set_name] = info;
}
}
+
+ sXMLFilename = xml_filename;
return true;
}
@@ -267,3 +271,23 @@ bool LLMIMETypes::findAllowLooping(const std::string& mime_type)
}
return allow_looping;
}
+
+// static
+bool LLMIMETypes::isTypeHandled(const std::string& mime_type)
+{
+ mime_info_map_t::const_iterator it = sMap.find(mime_type);
+ if (it != sMap.end())
+ {
+ return true;
+ }
+ return false;
+}
+
+// static
+void LLMIMETypes::reload(void*)
+{
+ sMap.clear();
+ sWidgetMap.clear();
+ (void)LLMIMETypes::parseMIMETypes(sXMLFilename);
+}
+
diff --git a/indra/newview/llmimetypes.h b/indra/newview/llmimetypes.h
index 7a50c29429..b217ce7a81 100644
--- a/indra/newview/llmimetypes.h
+++ b/indra/newview/llmimetypes.h
@@ -72,6 +72,12 @@ public:
static bool findAllowLooping(const std::string& mime_type);
// accessor for flag to enable/disable media looping checkbox
+ static bool isTypeHandled(const std::string& mime_type);
+ // determines if the specific mime type is handled by the media system
+
+ static void reload(void*);
+ // re-loads the MIME types file from the file path last passed into parseMIMETypes
+
public:
struct LLMIMEInfo
{
diff --git a/indra/newview/llmorphview.cpp b/indra/newview/llmorphview.cpp
index 18fd20d12a..f562e45770 100644
--- a/indra/newview/llmorphview.cpp
+++ b/indra/newview/llmorphview.cpp
@@ -47,7 +47,7 @@
#include "lltoolmgr.h"
#include "lltoolmorph.h"
#include "llviewercamera.h"
-#include "llvoavatar.h"
+#include "llvoavatarself.h"
#include "llviewerwindow.h"
#include "pipeline.h"
@@ -67,9 +67,8 @@ const F32 CAMERA_DIST_STEP = 1.5f;
//-----------------------------------------------------------------------------
// LLMorphView()
//-----------------------------------------------------------------------------
-LLMorphView::LLMorphView(const std::string& name, const LLRect& rect)
- :
- LLView(name, rect, FALSE, FOLLOWS_ALL),
+LLMorphView::LLMorphView(const LLMorphView::Params& p)
+: LLView(p),
mCameraTargetJoint( NULL ),
mCameraOffset(-0.5f, 0.05f, 0.07f ),
mCameraTargetOffset(0.f, 0.f, 0.05f ),
@@ -78,8 +77,7 @@ LLMorphView::LLMorphView(const std::string& name, const LLRect& rect)
mCameraYaw( 0.f ),
mCameraDist( -1.f ),
mCameraDrivenByKeys( FALSE )
-{
-}
+{}
//-----------------------------------------------------------------------------
// initialize()
@@ -110,7 +108,7 @@ void LLMorphView::initialize()
//-----------------------------------------------------------------------------
void LLMorphView::shutdown()
{
- LLVOAvatar::onCustomizeEnd();
+ LLVOAvatarSelf::onCustomizeEnd();
LLVOAvatar *avatarp = gAgent.getAvatarObject();
if(avatarp && !avatarp->isDead())
@@ -137,7 +135,7 @@ void LLMorphView::setVisible(BOOL visible)
llassert( !gFloaterCustomize );
gFloaterCustomize = new LLFloaterCustomize();
gFloaterCustomize->fetchInventory();
- gFloaterCustomize->open(); /*Flawfinder: ignore*/
+ gFloaterCustomize->openFloater();
// Must do this _after_ gFloaterView is initialized.
gFloaterCustomize->switchToDefaultSubpart();
diff --git a/indra/newview/llmorphview.h b/indra/newview/llmorphview.h
index 1dd8ef7a5f..493f906c6b 100644
--- a/indra/newview/llmorphview.h
+++ b/indra/newview/llmorphview.h
@@ -43,7 +43,15 @@ class LLFloaterCustomize;
class LLMorphView : public LLView
{
public:
- LLMorphView(const std::string& name, const LLRect& rect);
+ struct Params : public LLInitParam::Block<Params, LLView::Params>
+ {
+ Params()
+ {
+ mouse_opaque(false);
+ follows.flags(FOLLOWS_ALL);
+ }
+ };
+ LLMorphView(const LLMorphView::Params&);
void initialize();
void shutdown();
diff --git a/indra/newview/llmoveview.cpp b/indra/newview/llmoveview.cpp
index a180047875..11c8b03f7f 100644
--- a/indra/newview/llmoveview.cpp
+++ b/indra/newview/llmoveview.cpp
@@ -36,14 +36,24 @@
// Library includes
#include "indra_constants.h"
+#include "llparcel.h"
// Viewer includes
+
#include "llagent.h"
-#include "llviewercontrol.h"
+#include "llvoavatarself.h" // to check gAgent.getAvatarObject()->isSitting()
+#include "llbottomtray.h"
#include "llbutton.h"
-#include "llviewerwindow.h"
+#include "llfirsttimetipmanager.h"
+#include "llfloaterreg.h"
+#include "llfloaterfirsttimetip.h"
#include "lljoystickbutton.h"
#include "lluictrlfactory.h"
+#include "llviewerwindow.h"
+#include "llviewercontrol.h"
+#include "llselectmgr.h"
+#include "llviewerparcelmgr.h"
+#include "llviewerregion.h"
//
// Constants
@@ -53,111 +63,545 @@ const F32 MOVE_BUTTON_DELAY = 0.0f;
const F32 YAW_NUDGE_RATE = 0.05f; // fraction of normal speed
const F32 NUDGE_TIME = 0.25f; // in seconds
+const std::string BOTTOM_TRAY_BUTTON_NAME = "movement_btn";
+
//
// Member functions
//
// protected
LLFloaterMove::LLFloaterMove(const LLSD& key)
-: LLFloater(std::string("move floater"))
+: LLFloater(key),
+ mForwardButton(NULL),
+ mBackwardButton(NULL),
+ mTurnLeftButton(NULL),
+ mTurnRightButton(NULL),
+ mMoveUpButton(NULL),
+ mMoveDownButton(NULL),
+ mStopFlyingButton(NULL),
+ mModeActionsPanel(NULL)
{
- setIsChrome(TRUE);
-
- const BOOL DONT_OPEN = FALSE;
- LLUICtrlFactory::getInstance()->buildFloater(this,"floater_moveview.xml", NULL, DONT_OPEN);
+}
+// virtual
+BOOL LLFloaterMove::postBuild()
+{
+ setIsChrome(TRUE);
+
+
mForwardButton = getChild<LLJoystickAgentTurn>("forward btn");
mForwardButton->setHeldDownDelay(MOVE_BUTTON_DELAY);
mBackwardButton = getChild<LLJoystickAgentTurn>("backward btn");
mBackwardButton->setHeldDownDelay(MOVE_BUTTON_DELAY);
- mSlideLeftButton = getChild<LLJoystickAgentSlide>("slide left btn");
- mSlideLeftButton->setHeldDownDelay(MOVE_BUTTON_DELAY);
-
- mSlideRightButton = getChild<LLJoystickAgentSlide>("slide right btn");
- mSlideRightButton->setHeldDownDelay(MOVE_BUTTON_DELAY);
-
mTurnLeftButton = getChild<LLButton>("turn left btn");
mTurnLeftButton->setHeldDownDelay(MOVE_BUTTON_DELAY);
- mTurnLeftButton->setHeldDownCallback( turnLeft );
-
+ mTurnLeftButton->setHeldDownCallback(boost::bind(&LLFloaterMove::turnLeft, this));
mTurnRightButton = getChild<LLButton>("turn right btn");
mTurnRightButton->setHeldDownDelay(MOVE_BUTTON_DELAY);
- mTurnRightButton->setHeldDownCallback( turnRight );
+ mTurnRightButton->setHeldDownCallback(boost::bind(&LLFloaterMove::turnRight, this));
mMoveUpButton = getChild<LLButton>("move up btn");
- childSetAction("move up btn",moveUp,NULL);
mMoveUpButton->setHeldDownDelay(MOVE_BUTTON_DELAY);
- mMoveUpButton->setHeldDownCallback( moveUp );
+ mMoveUpButton->setHeldDownCallback(boost::bind(&LLFloaterMove::moveUp, this));
mMoveDownButton = getChild<LLButton>("move down btn");
- childSetAction("move down btn",moveDown,NULL);
mMoveDownButton->setHeldDownDelay(MOVE_BUTTON_DELAY);
- mMoveDownButton->setHeldDownCallback( moveDown );
+ mMoveDownButton->setHeldDownCallback(boost::bind(&LLFloaterMove::moveDown, this));
+
+
+ mStopFlyingButton = getChild<LLButton>("stop_fly_btn");
+
+ mModeActionsPanel = getChild<LLPanel>("panel_modes");
+
+ LLButton* btn;
+ btn = getChild<LLButton>("mode_walk_btn");
+ btn->setCommitCallback(boost::bind(&LLFloaterMove::onWalkButtonClick, this));
+
+ btn = getChild<LLButton>("mode_run_btn");
+ btn->setCommitCallback(boost::bind(&LLFloaterMove::onRunButtonClick, this));
+
+ btn = getChild<LLButton>("mode_fly_btn");
+ btn->setCommitCallback(boost::bind(&LLFloaterMove::onFlyButtonClick, this));
+
+ btn = getChild<LLButton>("stop_fly_btn");
+ btn->setCommitCallback(boost::bind(&LLFloaterMove::onStopFlyingButtonClick, this));
+
+
+
+ showFlyControls(false);
+
+ initModeTooltips();
+
+ updatePosition();
+
+ initModeButtonMap();
+
+ initMovementMode();
+
+ LLViewerParcelMgr::getInstance()->addAgentParcelChangedCallback(LLFloaterMove::sUpdateFlyingStatus);
+
+ return TRUE;
}
-// virtual
-void LLFloaterMove::onClose(bool app_quitting)
+// static
+F32 LLFloaterMove::getYawRate( F32 time )
{
- LLFloater::onClose(app_quitting);
-
- if (!app_quitting)
+ if( time < NUDGE_TIME )
+ {
+ F32 rate = YAW_NUDGE_RATE + time * (1 - YAW_NUDGE_RATE)/ NUDGE_TIME;
+ return rate;
+ }
+ else
{
- gSavedSettings.setBOOL("ShowMovementControls", FALSE);
+ return 1.f;
}
}
-//
-// Static member functions
-//
-void LLFloaterMove::onOpen()
+// static
+void LLFloaterMove::setFlyingMode(BOOL fly)
+{
+ LLFloaterMove* instance = LLFloaterReg::findTypedInstance<LLFloaterMove>("moveview");
+ if (instance)
+ {
+ instance->setFlyingModeImpl(fly);
+ instance->showModeButtons(!fly);
+ }
+ if (fly)
+ {
+ LLPanelStandStopFlying::setStandStopFlyingMode(LLPanelStandStopFlying::SSFM_STOP_FLYING);
+ }
+ else
+ {
+ LLPanelStandStopFlying::clearStandStopFlyingMode(LLPanelStandStopFlying::SSFM_STOP_FLYING);
+ }
+}
+//static
+void LLFloaterMove::setAlwaysRunMode(bool run)
{
- LLFloater::onOpen();
- gSavedSettings.setBOOL("ShowMovementControls", TRUE);
+ LLFloaterMove* instance = LLFloaterReg::findTypedInstance<LLFloaterMove>("moveview");
+ if (instance)
+ {
+ instance->setAlwaysRunModeImpl(run);
+ }
}
-// protected static
-F32 LLFloaterMove::getYawRate( F32 time )
+void LLFloaterMove::setFlyingModeImpl(BOOL fly)
{
- if( time < NUDGE_TIME )
+ updateButtonsWithMovementMode(fly ? MM_FLY : (gAgent.getAlwaysRun() ? MM_RUN : MM_WALK));
+}
+
+void LLFloaterMove::setAlwaysRunModeImpl(bool run)
+{
+ if (!gAgent.getFlying())
{
- F32 rate = YAW_NUDGE_RATE + time * (1 - YAW_NUDGE_RATE)/ NUDGE_TIME;
- return rate;
+ updateButtonsWithMovementMode(run ? MM_RUN : MM_WALK);
+ }
+}
+
+//static
+void LLFloaterMove::setSittingMode(BOOL bSitting)
+{
+ if (bSitting)
+ {
+ LLPanelStandStopFlying::setStandStopFlyingMode(LLPanelStandStopFlying::SSFM_STAND);
}
else
{
- return 1.f;
+ LLPanelStandStopFlying::clearStandStopFlyingMode(LLPanelStandStopFlying::SSFM_STAND);
}
+ enableInstance(!bSitting);
}
-// protected static
-void LLFloaterMove::turnLeft(void *)
+// protected
+void LLFloaterMove::turnLeft()
{
- F32 time = getInstance()->mTurnLeftButton->getHeldDownTime();
+ F32 time = mTurnLeftButton->getHeldDownTime();
gAgent.moveYaw( getYawRate( time ) );
}
-// protected static
-void LLFloaterMove::turnRight(void *)
+// protected
+void LLFloaterMove::turnRight()
{
- F32 time = getInstance()->mTurnRightButton->getHeldDownTime();
+ F32 time = mTurnRightButton->getHeldDownTime();
gAgent.moveYaw( -getYawRate( time ) );
}
-// protected static
-void LLFloaterMove::moveUp(void *)
+// protected
+void LLFloaterMove::moveUp()
{
// Jumps or flys up, depending on fly state
gAgent.moveUp(1);
}
-// protected static
-void LLFloaterMove::moveDown(void *)
+// protected
+void LLFloaterMove::moveDown()
{
// Crouches or flys down, depending on fly state
gAgent.moveUp(-1);
}
+//////////////////////////////////////////////////////////////////////////
+// Private Section:
+//////////////////////////////////////////////////////////////////////////
+
+void LLFloaterMove::onWalkButtonClick()
+{
+ setMovementMode(MM_WALK);
+}
+void LLFloaterMove::onRunButtonClick()
+{
+ setMovementMode(MM_RUN);
+}
+void LLFloaterMove::onFlyButtonClick()
+{
+ setMovementMode(MM_FLY);
+}
+void LLFloaterMove::onStopFlyingButtonClick()
+{
+ setMovementMode(gAgent.getAlwaysRun() ? MM_RUN : MM_WALK);
+}
+
+void LLFloaterMove::setMovementMode(const EMovementMode mode)
+{
+ gAgent.setFlying(MM_FLY == mode);
+
+ switch (mode)
+ {
+ case MM_RUN:
+ gAgent.setAlwaysRun();
+ gAgent.setRunning();
+ break;
+ case MM_WALK:
+ gAgent.clearAlwaysRun();
+ gAgent.clearRunning();
+ break;
+ default:
+ //do nothing for other modes (MM_FLY)
+ break;
+ }
+ // tell the simulator.
+ gAgent.sendWalkRun(gAgent.getAlwaysRun());
+
+ updateButtonsWithMovementMode(mode);
+
+ bool bHideModeButtons = MM_FLY == mode
+ || (gAgent.getAvatarObject() && gAgent.getAvatarObject()->isSitting());
+
+ showModeButtons(!bHideModeButtons);
+
+ showQuickTips(mode);
+}
+
+void LLFloaterMove::updateButtonsWithMovementMode(const EMovementMode newMode)
+{
+ showFlyControls(MM_FLY == newMode);
+ setModeTooltip(newMode);
+ setModeButtonToggleState(newMode);
+}
+
+void LLFloaterMove::showFlyControls(bool bShow)
+{
+ mMoveUpButton->setVisible(bShow);
+ mMoveDownButton->setVisible(bShow);
+
+ // *TODO: mantipov: mStopFlyingButton from the FloaterMove is not used now.
+ // It was not completly removed until functionality is reviewed by LL
+ mStopFlyingButton->setVisible(FALSE);
+}
+
+void LLFloaterMove::initModeTooltips()
+{
+ control_tooltip_map_t walkTipMap;
+ walkTipMap.insert(std::make_pair(mForwardButton, getString("walk_forward_tooltip")));
+ walkTipMap.insert(std::make_pair(mBackwardButton, getString("walk_back_tooltip")));
+ mModeControlTooltipsMap[MM_WALK] = walkTipMap;
+
+ control_tooltip_map_t runTipMap;
+ runTipMap.insert(std::make_pair(mForwardButton, getString("run_forward_tooltip")));
+ runTipMap.insert(std::make_pair(mBackwardButton, getString("run_back_tooltip")));
+ mModeControlTooltipsMap[MM_RUN] = runTipMap;
+
+ control_tooltip_map_t flyTipMap;
+ flyTipMap.insert(std::make_pair(mForwardButton, getString("fly_forward_tooltip")));
+ flyTipMap.insert(std::make_pair(mBackwardButton, getString("fly_back_tooltip")));
+ mModeControlTooltipsMap[MM_FLY] = flyTipMap;
+
+ setModeTooltip(MM_WALK);
+}
+
+void LLFloaterMove::initModeButtonMap()
+{
+ mModeControlButtonMap[MM_WALK] = getChild<LLButton>("mode_walk_btn");
+ mModeControlButtonMap[MM_RUN] = getChild<LLButton>("mode_run_btn");
+ mModeControlButtonMap[MM_FLY] = getChild<LLButton>("mode_fly_btn");
+}
+
+void LLFloaterMove::initMovementMode()
+{
+ EMovementMode initMovementMode = gAgent.getAlwaysRun() ? MM_RUN : MM_WALK;
+ if (gAgent.getFlying())
+ {
+ initMovementMode = MM_FLY;
+ }
+ setMovementMode(initMovementMode);
+
+ if (gAgent.getAvatarObject())
+ {
+ setEnabled(!gAgent.getAvatarObject()->isSitting());
+ }
+}
+
+void LLFloaterMove::setModeTooltip(const EMovementMode mode)
+{
+ llassert_always(mModeControlTooltipsMap.end() != mModeControlTooltipsMap.find(mode));
+ control_tooltip_map_t controlsTipMap = mModeControlTooltipsMap[mode];
+ control_tooltip_map_t::const_iterator it = controlsTipMap.begin();
+ for (; it != controlsTipMap.end(); ++it)
+ {
+ LLView* ctrl = it->first;
+ std::string tooltip = it->second;
+ ctrl->setToolTip(tooltip);
+ }
+}
+
+/**
+ * Updates position of the floater to be center aligned with Move button.
+ *
+ * Because Tip floater created as dependent floater this method
+ * must be called before "showQuickTips()" to get Tip floater be positioned at the right side of the floater
+ */
+void LLFloaterMove::updatePosition()
+{
+ LLBottomTray* tray = LLBottomTray::getInstance();
+ if (!tray) return;
+
+ LLButton* movement_btn = tray->getChild<LLButton>(BOTTOM_TRAY_BUTTON_NAME);
+
+ //align centers of a button and a floater
+ S32 x = movement_btn->calcScreenRect().getCenterX() - getRect().getWidth()/2;
+
+ S32 y = 0;
+ if (!mModeActionsPanel->getVisible())
+ {
+ y = mModeActionsPanel->getRect().getHeight();
+ }
+ setOrigin(x, y);
+}
+
+//static
+void LLFloaterMove::sUpdateFlyingStatus()
+{
+ LLFloaterMove *floater = LLFloaterReg::findTypedInstance<LLFloaterMove>("moveview");
+ if (floater) floater->mModeControlButtonMap[MM_FLY]->setEnabled(gAgent.canFly());
+
+}
+
+void LLFloaterMove::showModeButtons(BOOL bShow)
+{
+ if (mModeActionsPanel->getVisible() == bShow)
+ return;
+ mModeActionsPanel->setVisible(bShow);
+
+ LLRect rect = getRect();
+
+ static S32 height = mModeActionsPanel->getRect().getHeight();
+ S32 newHeight = getRect().getHeight();
+ if (!bShow)
+ {
+ newHeight -= height;
+ }
+ else
+ {
+ newHeight += height;
+ }
+ rect.setLeftTopAndSize(rect.mLeft, rect.mTop, rect.getWidth(), newHeight);
+ reshape(rect.getWidth(), rect.getHeight());
+ setRect(rect);
+}
+//static
+void LLFloaterMove::enableInstance(BOOL bEnable)
+{
+ LLFloaterMove* instance = LLFloaterReg::findTypedInstance<LLFloaterMove>("moveview");
+ if (instance)
+ {
+ instance->setEnabled(bEnable);
+ instance->showModeButtons(bEnable);
+ }
+}
+
+void LLFloaterMove::onOpen(const LLSD& key)
+{
+ updatePosition();
+
+ sUpdateFlyingStatus();
+}
+
+void LLFloaterMove::showQuickTips(const EMovementMode mode)
+{
+ LLFirstTimeTipsManager::EFirstTimeTipType tipType = LLFirstTimeTipsManager::FTT_MOVE_WALK;
+ switch (mode)
+ {
+ case MM_FLY: tipType = LLFirstTimeTipsManager::FTT_MOVE_FLY; break;
+ case MM_RUN: tipType = LLFirstTimeTipsManager::FTT_MOVE_RUN; break;
+ case MM_WALK: tipType = LLFirstTimeTipsManager::FTT_MOVE_WALK; break;
+ default: llwarns << "Quick Tip type was not detected, FTT_MOVE_WALK will be used" << llendl;
+ }
+
+ LLFirstTimeTipsManager::showTipsFor(tipType, this, LLFirstTimeTipsManager::TPA_POS_LEFT_ALIGN_TOP);
+}
+
+void LLFloaterMove::setModeButtonToggleState(const EMovementMode mode)
+{
+ llassert_always(mModeControlButtonMap.end() != mModeControlButtonMap.find(mode));
+
+ mode_control_button_map_t::const_iterator it = mModeControlButtonMap.begin();
+ for (; it != mModeControlButtonMap.end(); ++it)
+ {
+ it->second->setToggleState(FALSE);
+ }
+
+ mModeControlButtonMap[mode]->setToggleState(TRUE);
+}
+
+
+
+/************************************************************************/
+/* LLPanelStandStopFlying */
+/************************************************************************/
+LLPanelStandStopFlying::LLPanelStandStopFlying() :
+ mStandButton(NULL),
+ mStopFlyingButton(NULL)
+{
+ // make sure we have the only instance of this class
+ static bool b = true;
+ llassert_always(b);
+ b=false;
+}
+
+// static
+inline LLPanelStandStopFlying* LLPanelStandStopFlying::getInstance()
+{
+ static LLPanelStandStopFlying* panel = getStandStopFlyingPanel();
+ return panel;
+}
+
+//static
+void LLPanelStandStopFlying::setStandStopFlyingMode(EStandStopFlyingMode mode)
+{
+ LLPanelStandStopFlying* panel = getInstance();
+
+ panel->mStandButton->setVisible(SSFM_STAND == mode);
+ panel->mStopFlyingButton->setVisible(SSFM_STOP_FLYING == mode);
+
+ //visibility of it should be updated after updating visibility of the buttons
+ panel->setVisible(TRUE);
+}
+
+//static
+void LLPanelStandStopFlying::clearStandStopFlyingMode(EStandStopFlyingMode mode)
+{
+ LLPanelStandStopFlying* panel = getInstance();
+ switch(mode) {
+ case SSFM_STAND:
+ panel->mStandButton->setVisible(FALSE);
+ break;
+ case SSFM_STOP_FLYING:
+ panel->mStopFlyingButton->setVisible(FALSE);
+ break;
+ default:
+ llerrs << "Unexpected EStandStopFlyingMode is passed: " << mode << llendl;
+ }
+
+}
+
+BOOL LLPanelStandStopFlying::postBuild()
+{
+ mStandButton = getChild<LLButton>("stand_btn");
+ mStandButton->setCommitCallback(boost::bind(&LLPanelStandStopFlying::onStandButtonClick, this));
+ mStandButton->setCommitCallback(boost::bind(&LLFloaterMove::enableInstance, TRUE));
+ mStandButton->setVisible(FALSE);
+
+ mStopFlyingButton = getChild<LLButton>("stop_fly_btn");
+ mStopFlyingButton->setCommitCallback(boost::bind(&LLFloaterMove::setFlyingMode, FALSE));
+ mStopFlyingButton->setCommitCallback(boost::bind(&LLPanelStandStopFlying::onStopFlyingButtonClick, this));
+ mStopFlyingButton->setVisible(FALSE);
+
+ return TRUE;
+}
+
+//virtual
+void LLPanelStandStopFlying::setVisible(BOOL visible)
+{
+ //we dont need to show the panel if these buttons are not activated
+ if (visible && !mStandButton->getVisible() && !mStopFlyingButton->getVisible()) visible = false;
+
+ if (gAgent.getCameraMode() == CAMERA_MODE_MOUSELOOK) visible = false;
+
+ if (visible)
+ {
+ updatePosition();
+ }
+
+ LLPanel::setVisible(visible);
+}
+
+//////////////////////////////////////////////////////////////////////////
+// Private Section
+//////////////////////////////////////////////////////////////////////////
+
+//static
+LLPanelStandStopFlying* LLPanelStandStopFlying::getStandStopFlyingPanel()
+{
+ LLPanelStandStopFlying* panel = new LLPanelStandStopFlying();
+ LLUICtrlFactory::getInstance()->buildPanel(panel, "panel_stand_stop_flying.xml");
+
+ panel->setVisible(FALSE);
+ LLUI::getRootView()->addChild(panel);
+
+ llinfos << "Build LLPanelStandStopFlying panel" << llendl;
+
+ panel->updatePosition();
+ return panel;
+}
+
+void LLPanelStandStopFlying::onStandButtonClick()
+{
+ LLSelectMgr::getInstance()->deselectAllForStandingUp();
+ gAgent.setControlFlags(AGENT_CONTROL_STAND_UP);
+
+ setFocus(FALSE); // EXT-482
+ setVisible(FALSE);
+}
+
+void LLPanelStandStopFlying::onStopFlyingButtonClick()
+{
+ gAgent.setFlying(FALSE);
+
+ setFocus(FALSE); // EXT-482
+ setVisible(FALSE);
+}
+
+/**
+ * Updates position of the Stand & Stop Flying panel to be center aligned with Move button.
+ */
+void LLPanelStandStopFlying::updatePosition()
+{
+
+ LLBottomTray* tray = LLBottomTray::getInstance();
+ if (!tray) return;
+
+ LLButton* movement_btn = tray->getChild<LLButton>(BOTTOM_TRAY_BUTTON_NAME);
+
+ //align centers of a button and a floater
+ S32 x = movement_btn->calcScreenRect().getCenterX() - getRect().getWidth()/2;
+
+ S32 y = tray->getRect().getHeight();
+
+ setOrigin(x, y);
+}
+
+
// EOF
diff --git a/indra/newview/llmoveview.h b/indra/newview/llmoveview.h
index e772551efe..6e6af9b693 100644
--- a/indra/newview/llmoveview.h
+++ b/indra/newview/llmoveview.h
@@ -44,40 +44,118 @@ class LLJoystickAgentSlide;
// Classes
//
class LLFloaterMove
-: public LLFloater,
- public LLFloaterSingleton<LLFloaterMove>
+: public LLFloater
{
- friend class LLUISingleton<LLFloaterMove, VisibilityPolicy<LLFloater> >;
-
-protected:
+ friend class LLFloaterReg;
+
+private:
LLFloaterMove(const LLSD& key);
~LLFloaterMove() {}
-
public:
- /*virtual*/ void onOpen();
- /*virtual*/ void onClose(bool app_quitting);
+ /*virtual*/ BOOL postBuild();
static F32 getYawRate(F32 time);
+ static void setFlyingMode(BOOL fly);
+ void setFlyingModeImpl(BOOL fly);
+ static void setAlwaysRunMode(bool run);
+ void setAlwaysRunModeImpl(bool run);
+ static void setSittingMode(BOOL bSitting);
+ static void enableInstance(BOOL bEnable);
+ /*virtual*/ void onOpen(const LLSD& key);
+
+ // *HACK: due to hard enough to have this control aligned with "Move" button while resizing
+ // let update its position in each frame
+ /*virtual*/ void draw(){updatePosition(); LLFloater::draw();}
+
+ static void sUpdateFlyingStatus();
protected:
- static void turnLeftNudge(void* userdata);
- static void turnLeft(void* userdata);
-
- static void turnRightNudge(void* userdata);
- static void turnRight(void* userdata);
+ void turnLeft();
+ void turnRight();
- static void moveUp(void* userdata);
- static void moveDown(void* userdata);
+ void moveUp();
+ void moveDown();
+
+private:
+ typedef enum movement_mode_t
+ {
+ MM_WALK,
+ MM_RUN,
+ MM_FLY
+ } EMovementMode;
+ void onWalkButtonClick();
+ void onRunButtonClick();
+ void onFlyButtonClick();
+ void onStopFlyingButtonClick();
+ void initMovementMode();
+ void setMovementMode(const EMovementMode mode);
+ void showFlyControls(bool bShow);
+ void initModeTooltips();
+ void setModeTooltip(const EMovementMode mode);
+ void showQuickTips(const EMovementMode mode);
+ void initModeButtonMap();
+ void setModeButtonToggleState(const EMovementMode mode);
+ void updateButtonsWithMovementMode(const EMovementMode newMode);
+ void updatePosition();
+ void showModeButtons(BOOL bShow);
public:
+
LLJoystickAgentTurn* mForwardButton;
LLJoystickAgentTurn* mBackwardButton;
- LLJoystickAgentSlide* mSlideLeftButton;
- LLJoystickAgentSlide* mSlideRightButton;
LLButton* mTurnLeftButton;
LLButton* mTurnRightButton;
LLButton* mMoveUpButton;
LLButton* mMoveDownButton;
+private:
+ LLButton* mStopFlyingButton;
+ LLPanel* mModeActionsPanel;
+
+ typedef std::map<LLView*, std::string> control_tooltip_map_t;
+ typedef std::map<EMovementMode, control_tooltip_map_t> mode_control_tooltip_map_t;
+ mode_control_tooltip_map_t mModeControlTooltipsMap;
+
+ typedef std::map<EMovementMode, LLButton*> mode_control_button_map_t;
+ mode_control_button_map_t mModeControlButtonMap;
+
+};
+
+
+/**
+ * This class contains Stand Up and Stop Flying buttons displayed above Move button in bottom tray
+ */
+class LLPanelStandStopFlying : public LLPanel
+{
+public:
+ typedef enum stand_stop_flying_mode_t
+ {
+ SSFM_STAND,
+ SSFM_STOP_FLYING
+ } EStandStopFlyingMode;
+
+ static LLPanelStandStopFlying* getInstance();
+ static void setStandStopFlyingMode(EStandStopFlyingMode mode);
+ static void clearStandStopFlyingMode(EStandStopFlyingMode mode);
+ /*virtual*/ BOOL postBuild();
+ /*virtual*/ void setVisible(BOOL visible);
+
+ // *HACK: due to hard enough to have this control aligned with "Move" button while resizing
+ // let update its position in each frame
+ /*virtual*/ void draw(){updatePosition(); LLPanel::draw();}
+
+
+protected:
+ LLPanelStandStopFlying();
+
+
+private:
+ static LLPanelStandStopFlying* getStandStopFlyingPanel();
+ void onStandButtonClick();
+ void onStopFlyingButtonClick();
+ void updatePosition();
+
+ LLButton* mStandButton;
+ LLButton* mStopFlyingButton;
};
diff --git a/indra/newview/llmutelist.cpp b/indra/newview/llmutelist.cpp
index a840b59140..b47d6f4214 100644
--- a/indra/newview/llmutelist.cpp
+++ b/indra/newview/llmutelist.cpp
@@ -71,6 +71,7 @@
#include "lluistring.h"
#include "llviewerobject.h"
#include "llviewerobjectlist.h"
+#include "lltrans.h"
namespace
{
@@ -111,11 +112,6 @@ static LLDispatchEmptyMuteList sDispatchEmptyMuteList;
//-----------------------------------------------------------------------------
// LLMute()
//-----------------------------------------------------------------------------
-const char BY_NAME_SUFFIX[] = " (by name)";
-const char AGENT_SUFFIX[] = " (resident)";
-const char OBJECT_SUFFIX[] = " (object)";
-const char GROUP_SUFFIX[] = " (group)";
-
LLMute::LLMute(const LLUUID& id, const std::string& name, EType type, U32 flags)
: mID(id),
@@ -149,16 +145,16 @@ std::string LLMute::getDisplayName() const
{
case BY_NAME:
default:
- name_with_suffix += BY_NAME_SUFFIX;
+ name_with_suffix += " " + LLTrans::getString("MuteByName");
break;
case AGENT:
- name_with_suffix += AGENT_SUFFIX;
+ name_with_suffix += " " + LLTrans::getString("MuteAgent");
break;
case OBJECT:
- name_with_suffix += OBJECT_SUFFIX;
+ name_with_suffix += " " + LLTrans::getString("MuteObject");
break;
case GROUP:
- name_with_suffix += GROUP_SUFFIX;
+ name_with_suffix += " " + LLTrans::getString("MuteGroup");
break;
}
return name_with_suffix;
@@ -169,7 +165,7 @@ void LLMute::setFromDisplayName(const std::string& display_name)
size_t pos = 0;
mName = display_name;
- pos = mName.rfind(GROUP_SUFFIX);
+ pos = mName.rfind(" " + LLTrans::getString("MuteGroup"));
if (pos != std::string::npos)
{
mName.erase(pos);
@@ -177,7 +173,7 @@ void LLMute::setFromDisplayName(const std::string& display_name)
return;
}
- pos = mName.rfind(OBJECT_SUFFIX);
+ pos = mName.rfind(" " + LLTrans::getString("MuteObject"));
if (pos != std::string::npos)
{
mName.erase(pos);
@@ -185,7 +181,7 @@ void LLMute::setFromDisplayName(const std::string& display_name)
return;
}
- pos = mName.rfind(AGENT_SUFFIX);
+ pos = mName.rfind(" " + LLTrans::getString("MuteAgent"));
if (pos != std::string::npos)
{
mName.erase(pos);
@@ -193,7 +189,7 @@ void LLMute::setFromDisplayName(const std::string& display_name)
return;
}
- pos = mName.rfind(BY_NAME_SUFFIX);
+ pos = mName.rfind(" " + LLTrans::getString("MuteByName"));
if (pos != std::string::npos)
{
mName.erase(pos);
@@ -501,11 +497,8 @@ void LLMuteList::updateRemove(const LLMute& mute)
gAgent.sendReliableMessage();
}
-void notify_automute_callback(const LLUUID& agent_id, const std::string& first_name, const std::string& last_name, BOOL is_group, void* user_data)
+void notify_automute_callback(const LLUUID& agent_id, const std::string& first_name, const std::string& last_name, BOOL is_group, LLMuteList::EAutoReason reason)
{
- U32 temp_data = (U32) (uintptr_t) user_data;
- LLMuteList::EAutoReason reason = (LLMuteList::EAutoReason)temp_data;
-
std::string notif_name;
switch (reason)
{
@@ -561,18 +554,18 @@ BOOL LLMuteList::autoRemove(const LLUUID& agent_id, const EAutoReason reason, co
if (gCacheName->getName(agent_id, cache_first, cache_last))
{
// name in cache, call callback directly
- notify_automute_callback(agent_id, cache_first, cache_last, FALSE, (void *)reason);
+ notify_automute_callback(agent_id, cache_first, cache_last, FALSE, reason);
}
else
{
// not in cache, lookup name from cache
- gCacheName->getNameFromUUID(agent_id, FALSE, notify_automute_callback, (void *)reason);
+ gCacheName->get(agent_id, FALSE, boost::bind(&notify_automute_callback, _1, _2, _3, _4, reason));
}
}
else
{
// call callback directly
- notify_automute_callback(agent_id, first_name, last_name, FALSE, (void *)reason);
+ notify_automute_callback(agent_id, first_name, last_name, FALSE, reason);
}
}
diff --git a/indra/newview/llnamebox.cpp b/indra/newview/llnamebox.cpp
index 98c7a4b631..2f4a266198 100644
--- a/indra/newview/llnamebox.cpp
+++ b/indra/newview/llnamebox.cpp
@@ -41,25 +41,19 @@
#include "lluuid.h"
#include "llcachename.h"
-#include "llagent.h"
// statics
std::set<LLNameBox*> LLNameBox::sInstances;
+static LLDefaultChildRegistry::Register<LLNameBox> r("name_box");
-LLNameBox::LLNameBox(const std::string& name, const LLRect& rect, const LLUUID& name_id, BOOL is_group, const LLFontGL* font, BOOL mouse_opaque)
-: LLTextBox(name, rect, std::string("(retrieving)"), font, mouse_opaque),
- mNameID(name_id)
+
+LLNameBox::LLNameBox(const Params& p)
+: LLTextBox(p)
{
+ mNameID = LLUUID::null;
LLNameBox::sInstances.insert(this);
- if(!name_id.isNull())
- {
- setNameID(name_id, is_group);
- }
- else
- {
- setText(LLStringUtil::null);
- }
+ setText(LLStringUtil::null);
}
LLNameBox::~LLNameBox()
diff --git a/indra/newview/llnamebox.h b/indra/newview/llnamebox.h
index f76850bd3c..3edb36883f 100644
--- a/indra/newview/llnamebox.h
+++ b/indra/newview/llnamebox.h
@@ -44,10 +44,15 @@ class LLNameBox
: public LLTextBox
{
public:
- LLNameBox(const std::string& name, const LLRect& rect, const LLUUID& name_id = LLUUID::null, BOOL is_group = FALSE, const LLFontGL* font = NULL, BOOL mouse_opaque = TRUE );
- // By default, follows top and left and is mouse-opaque.
- // If no text, text = name.
- // If no font, uses default system font.
+ struct Params : public LLInitParam::Block<Params, LLTextBox::Params>
+ {
+ Optional<bool> is_group;
+
+ Params()
+ : is_group("is_group", false)
+ {}
+ };
+
virtual ~LLNameBox();
void setNameID(const LLUUID& name_id, BOOL is_group);
@@ -57,6 +62,10 @@ public:
static void refreshAll(const LLUUID& id, const std::string& firstname,
const std::string& lastname, BOOL is_group);
+protected:
+ LLNameBox (const Params&);
+
+ friend class LLUICtrlFactory;
private:
static std::set<LLNameBox*> sInstances;
diff --git a/indra/newview/llnameeditor.cpp b/indra/newview/llnameeditor.cpp
index e4a65734d8..65601da7da 100644
--- a/indra/newview/llnameeditor.cpp
+++ b/indra/newview/llnameeditor.cpp
@@ -34,7 +34,6 @@
#include "llnameeditor.h"
#include "llcachename.h"
-#include "llagent.h"
#include "llfontgl.h"
@@ -43,40 +42,22 @@
#include "llstring.h"
#include "llui.h"
-static LLRegisterWidget<LLNameEditor> r("name_editor");
+static LLDefaultChildRegistry::Register<LLNameEditor> r("name_editor");
// statics
std::set<LLNameEditor*> LLNameEditor::sInstances;
-LLNameEditor::LLNameEditor(const std::string& name, const LLRect& rect,
- const LLUUID& name_id,
- BOOL is_group,
- const LLFontGL* glfont,
- S32 max_text_length,
- void (*commit_callback)(LLUICtrl* caller, void* user_data),
- void (*keystroke_callback)(LLLineEditor* caller, void* user_data),
- void (*focus_lost_callback)(LLFocusableElement* caller, void* user_data),
- void* userdata,
- LLLinePrevalidateFunc prevalidate_func)
-: LLLineEditor(name, rect,
- std::string("(retrieving)"),
- glfont,
- max_text_length,
- commit_callback,
- keystroke_callback,
- focus_lost_callback,
- userdata,
- prevalidate_func),
- mNameID(name_id)
+LLNameEditor::LLNameEditor(const LLNameEditor::Params& p)
+: LLLineEditor(p)
{
LLNameEditor::sInstances.insert(this);
- if(!name_id.isNull())
+
+ if(!p.name_id().isNull())
{
- setNameID(name_id, is_group);
+ setNameID(p.name_id, p.is_group);
}
}
-
LLNameEditor::~LLNameEditor()
{
LLNameEditor::sInstances.erase(this);
@@ -141,35 +122,3 @@ LLSD LLNameEditor::getValue() const
return LLSD(mNameID);
}
-LLView* LLNameEditor::fromXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFactory *factory)
-{
- std::string name("name_editor");
- node->getAttributeString("name", name);
-
- LLRect rect;
- createRect(node, rect, parent, LLRect());
-
- S32 max_text_length = 128;
- node->getAttributeS32("max_length", max_text_length);
-
- LLFontGL* font = LLView::selectFont(node);
-
- LLUICtrlCallback commit_callback = NULL;
-
- LLNameEditor* line_editor = new LLNameEditor(name,
- rect,
- LLUUID::null, FALSE,
- font,
- max_text_length,
- commit_callback);
-
- std::string label;
- if(node->getAttributeString("label", label))
- {
- line_editor->setLabel(label);
- }
- line_editor->setColorParameters(node);
- line_editor->initFromXML(node, parent);
-
- return line_editor;
-}
diff --git a/indra/newview/llnameeditor.h b/indra/newview/llnameeditor.h
index bc5a67866c..99e03a1166 100644
--- a/indra/newview/llnameeditor.h
+++ b/indra/newview/llnameeditor.h
@@ -46,24 +46,23 @@ class LLNameEditor
: public LLLineEditor
{
public:
- LLNameEditor(const std::string& name, const LLRect& rect,
- const LLUUID& name_id = LLUUID::null,
- BOOL is_group = FALSE,
- const LLFontGL* glfont = NULL,
- S32 max_text_length = 254,
- void (*commit_callback)(LLUICtrl* caller, void* user_data) = NULL,
- void (*keystroke_callback)(LLLineEditor* caller, void* user_data) = NULL,
- void (*focus_lost_callback)(LLFocusableElement* caller, void* user_data) = NULL,
- void* userdata = NULL,
- LLLinePrevalidateFunc prevalidate_func = NULL);
- // By default, follows top and left and is mouse-opaque.
- // If no text, text = name.
- // If no font, uses default system font.
-
+ struct Params : public LLInitParam::Block<Params, LLLineEditor::Params>
+ {
+ Optional<bool> is_group;
+ Optional<LLUUID> name_id;
+
+ Params()
+ : is_group("is_group"),
+ name_id("name_id")
+ {}
+ };
+
+protected:
+ LLNameEditor(const Params&);
+ friend class LLUICtrlFactory;
+public:
virtual ~LLNameEditor();
- static LLView* fromXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFactory *factory);
-
void setNameID(const LLUUID& name_id, BOOL is_group);
void refresh(const LLUUID& id, const std::string& first, const std::string& last, BOOL is_group);
diff --git a/indra/newview/llnamelistctrl.cpp b/indra/newview/llnamelistctrl.cpp
index baf06567c1..1b82c2dc18 100644
--- a/indra/newview/llnamelistctrl.cpp
+++ b/indra/newview/llnamelistctrl.cpp
@@ -37,53 +37,47 @@
#include "llnamelistctrl.h"
#include "llcachename.h"
-#include "llagent.h"
#include "llinventory.h"
+#include "llscrolllistitem.h"
+#include "llscrolllistcell.h"
+#include "llscrolllistcolumn.h"
+#include "llsdparam.h"
-static LLRegisterWidget<LLNameListCtrl> r("name_list");
-
-// statics
-std::set<LLNameListCtrl*> LLNameListCtrl::sInstances;
-
-LLNameListCtrl::LLNameListCtrl(const std::string& name,
- const LLRect& rect,
- LLUICtrlCallback cb,
- void* userdata,
- BOOL allow_multiple_selection,
- BOOL draw_border,
- S32 name_column_index,
- const std::string& tooltip)
-: LLScrollListCtrl(name, rect, cb, userdata, allow_multiple_selection,
- draw_border),
- mNameColumnIndex(name_column_index),
- mAllowCallingCardDrop(FALSE)
+static LLDefaultChildRegistry::Register<LLNameListCtrl> r("name_list");
+
+void LLNameListCtrl::NameTypeNames::declareValues()
{
- setToolTip(tooltip);
- LLNameListCtrl::sInstances.insert(this);
+ declare("INDIVIDUAL", LLNameListCtrl::INDIVIDUAL);
+ declare("GROUP", LLNameListCtrl::GROUP);
+ declare("SPECIAL", LLNameListCtrl::SPECIAL);
}
-
-// virtual
-LLNameListCtrl::~LLNameListCtrl()
+LLNameListCtrl::Params::Params()
+: name_column(""),
+ allow_calling_card_drop("allow_calling_card_drop", false)
{
- LLNameListCtrl::sInstances.erase(this);
+ name = "name_list";
}
+LLNameListCtrl::LLNameListCtrl(const LLNameListCtrl::Params& p)
+: LLScrollListCtrl(p),
+ mAllowCallingCardDrop(p.allow_calling_card_drop),
+ mNameColumn(p.name_column.column_name),
+ mNameColumnIndex(p.name_column.column_index)
+{}
// public
-BOOL LLNameListCtrl::addNameItem(const LLUUID& agent_id, EAddPosition pos,
+void LLNameListCtrl::addNameItem(const LLUUID& agent_id, EAddPosition pos,
BOOL enabled, std::string& suffix)
{
//llinfos << "LLNameListCtrl::addNameItem " << agent_id << llendl;
std::string fullname;
- BOOL result = gCacheName->getFullName(agent_id, fullname);
+ gCacheName->getFullName(agent_id, fullname);
fullname.append(suffix);
addStringUUIDItem(fullname, agent_id, pos, enabled);
-
- return result;
}
// virtual, public
@@ -138,75 +132,70 @@ BOOL LLNameListCtrl::handleDragAndDrop(
void LLNameListCtrl::addGroupNameItem(const LLUUID& group_id, EAddPosition pos,
BOOL enabled)
{
- //llinfos << "LLNameListCtrl::addGroupNameItem " << group_id << llendl;
- std::string group_name;
- gCacheName->getGroupName(group_id, group_name);
- addStringUUIDItem(group_name, group_id, pos, enabled);
+ NameItem item;
+ item.value = group_id;
+ item.enabled = enabled;
+ item.target = GROUP;
+
+ addNameItemRow(item, pos);
}
// public
-void LLNameListCtrl::addGroupNameItem(LLScrollListItem* item, EAddPosition pos)
-
+void LLNameListCtrl::addGroupNameItem(LLNameListCtrl::NameItem& item, EAddPosition pos)
{
- //llinfos << "LLNameListCtrl::addGroupNameItem " << item->getUUID() << llendl;
-
- std::string group_name;
- gCacheName->getGroupName(item->getUUID(), group_name);
-
- LLScrollListCell* cell = (LLScrollListCell*)item->getColumn(mNameColumnIndex);
- ((LLScrollListText*)cell)->setText( std::string(group_name) );
-
- addItem(item, pos);
+ item.target = GROUP;
+ addNameItemRow(item, pos);
}
-BOOL LLNameListCtrl::addNameItem(LLScrollListItem* item, EAddPosition pos)
+void LLNameListCtrl::addNameItem(LLNameListCtrl::NameItem& item, EAddPosition pos)
{
- //llinfos << "LLNameListCtrl::addNameItem " << item->getUUID() << llendl;
-
- std::string fullname;
- BOOL result = gCacheName->getFullName(item->getUUID(), fullname);
-
- LLScrollListCell* cell = (LLScrollListCell*)item->getColumn(mNameColumnIndex);
- ((LLScrollListText*)cell)->setText( fullname );
-
- addItem(item, pos);
-
- // this column is resizable
- LLScrollListColumn* columnp = getColumn(mNameColumnIndex);
- if (columnp && columnp->mHeader)
- {
- columnp->mHeader->setHasResizableElement(TRUE);
- }
+ item.target = INDIVIDUAL;
+ addNameItemRow(item, pos);
+}
- return result;
+LLScrollListItem* LLNameListCtrl::addElement(const LLSD& element, EAddPosition pos, void* userdata)
+{
+ LLNameListCtrl::NameItem item_params;
+ LLParamSDParser::instance().readSD(element, item_params);
+ item_params.userdata = userdata;
+ return addNameItemRow(item_params, pos);
}
-LLScrollListItem* LLNameListCtrl::addElement(const LLSD& value, EAddPosition pos, void* userdata)
+
+LLScrollListItem* LLNameListCtrl::addNameItemRow(const LLNameListCtrl::NameItem& name_item, EAddPosition pos)
{
- LLScrollListItem* item = LLScrollListCtrl::addElement(value, pos, userdata);
+ LLScrollListItem* item = LLScrollListCtrl::addRow(name_item, pos);
+ if (!item) return NULL;
// use supplied name by default
- std::string fullname = value["name"].asString();
- if (value["target"].asString() == "GROUP")
+ std::string fullname = name_item.name;
+ switch(name_item.target)
{
- gCacheName->getGroupName(item->getUUID(), fullname);
+ case GROUP:
+ gCacheName->getGroupName(name_item.value().asUUID(), fullname);
// fullname will be "nobody" if group not found
- }
- else if (value["target"].asString() == "SPECIAL")
- {
+ break;
+ case SPECIAL:
// just use supplied name
- }
- else // normal resident
- {
- std::string name;
- if (gCacheName->getFullName(item->getUUID(), name))
+ break;
+ case INDIVIDUAL:
{
- fullname = name;
+ std::string name;
+ if (gCacheName->getFullName(name_item.value().asUUID(), name))
+ {
+ fullname = name;
+ }
+ break;
}
+ default:
+ break;
}
- LLScrollListCell* cell = (LLScrollListCell*)item->getColumn(mNameColumnIndex);
- ((LLScrollListText*)cell)->setText( fullname );
+ LLScrollListCell* cell = item->getColumn(mNameColumnIndex);
+ if (cell)
+ {
+ cell->setValue(fullname);
+ }
dirtyColumns();
@@ -259,9 +248,11 @@ void LLNameListCtrl::refresh(const LLUUID& id, const std::string& first,
if (item->getUUID() == id)
{
LLScrollListCell* cell = (LLScrollListCell*)item->getColumn(0);
- cell = (LLScrollListCell*)item->getColumn(mNameColumnIndex);
-
- ((LLScrollListText*)cell)->setText( fullname );
+ cell = item->getColumn(mNameColumnIndex);
+ if (cell)
+ {
+ cell->setValue(fullname);
+ }
}
}
@@ -273,186 +264,24 @@ void LLNameListCtrl::refresh(const LLUUID& id, const std::string& first,
void LLNameListCtrl::refreshAll(const LLUUID& id, const std::string& first,
const std::string& last, BOOL is_group)
{
- std::set<LLNameListCtrl*>::iterator it;
- for (it = LLNameListCtrl::sInstances.begin();
- it != LLNameListCtrl::sInstances.end();
- ++it)
+ LLInstanceTracker<LLNameListCtrl>::instance_iter it;
+ for (it = beginInstances(); it != endInstances(); ++it)
{
LLNameListCtrl* ctrl = *it;
ctrl->refresh(id, first, last, is_group);
}
}
-// virtual
-LLXMLNodePtr LLNameListCtrl::getXML(bool save_children) const
+void LLNameListCtrl::updateColumns()
{
- LLXMLNodePtr node = LLScrollListCtrl::getXML();
-
- node->createChild("allow_calling_card_drop", TRUE)->setBoolValue(mAllowCallingCardDrop);
-
- if (mNameColumnIndex != 0)
- {
- node->createChild("name_column_index", TRUE)->setIntValue(mNameColumnIndex);
- }
-
- // Don't save contents, probably filled by code
-
- return node;
-}
-
-LLView* LLNameListCtrl::fromXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFactory *factory)
-{
- std::string name("name_list");
- node->getAttributeString("name", name);
-
- LLRect rect;
- createRect(node, rect, parent, LLRect());
-
- BOOL multi_select = FALSE;
- node->getAttributeBOOL("multi_select", multi_select);
-
- BOOL draw_border = TRUE;
- node->getAttributeBOOL("draw_border", draw_border);
-
- BOOL draw_heading = FALSE;
- node->getAttributeBOOL("draw_heading", draw_heading);
-
- S32 name_column_index = 0;
- node->getAttributeS32("name_column_index", name_column_index);
+ LLScrollListCtrl::updateColumns();
- LLUICtrlCallback callback = NULL;
-
- LLNameListCtrl* name_list = new LLNameListCtrl(name,
- rect,
- callback,
- NULL,
- multi_select,
- draw_border,
- name_column_index);
-
- name_list->setDisplayHeading(draw_heading);
- if (node->hasAttribute("heading_height"))
- {
- S32 heading_height;
- node->getAttributeS32("heading_height", heading_height);
- name_list->setHeadingHeight(heading_height);
- }
-
- BOOL allow_calling_card_drop = FALSE;
- if (node->getAttributeBOOL("allow_calling_card_drop", allow_calling_card_drop))
- {
- name_list->setAllowCallingCardDrop(allow_calling_card_drop);
- }
-
- name_list->setScrollListParameters(node);
-
- name_list->initFromXML(node, parent);
-
- LLSD columns;
- S32 index = 0;
- //S32 total_static = 0;
- LLXMLNodePtr child;
- for (child = node->getFirstChild(); child.notNull(); child = child->getNextSibling())
- {
- if (child->hasName("column"))
- {
- std::string labelname("");
- child->getAttributeString("label", labelname);
-
- std::string columnname(labelname);
- child->getAttributeString("name", columnname);
-
- BOOL columndynamicwidth = FALSE;
- child->getAttributeBOOL("dynamicwidth", columndynamicwidth);
-
- std::string sortname(columnname);
- child->getAttributeString("sort", sortname);
-
- S32 columnwidth = -1;
- if (child->hasAttribute("relwidth"))
- {
- F32 columnrelwidth = 0.f;
- child->getAttributeF32("relwidth", columnrelwidth);
- columns[index]["relwidth"] = columnrelwidth;
- }
- else
- {
- child->getAttributeS32("width", columnwidth);
- columns[index]["width"] = columnwidth;
- }
-
- LLFontGL::HAlign h_align = LLFontGL::LEFT;
- h_align = LLView::selectFontHAlign(child);
-
- //if(!columndynamicwidth) total_static += llmax(0, columnwidth);
-
- columns[index]["name"] = columnname;
- columns[index]["label"] = labelname;
- columns[index]["halign"] = (S32)h_align;
- columns[index]["dynamicwidth"] = columndynamicwidth;
- columns[index]["sort"] = sortname;
-
- index++;
- }
- }
- name_list->setColumnHeadings(columns);
-
-
- for (child = node->getFirstChild(); child.notNull(); child = child->getNextSibling())
+ if (!mNameColumn.empty())
{
- if (child->hasName("row"))
+ LLScrollListColumn* name_column = getColumn(mNameColumn);
+ if (name_column)
{
- LLUUID id;
- child->getAttributeUUID("id", id);
-
- LLSD row;
-
- row["id"] = id;
-
- S32 column_idx = 0;
- LLXMLNodePtr row_child;
- for (row_child = node->getFirstChild(); row_child.notNull(); row_child = row_child->getNextSibling())
- {
- if (row_child->hasName("column"))
- {
- std::string value = row_child->getTextContents();
-
- std::string columnname("");
- row_child->getAttributeString("name", columnname);
-
- std::string font("");
- row_child->getAttributeString("font", font);
-
- std::string font_style("");
- row_child->getAttributeString("font-style", font_style);
-
- row["columns"][column_idx]["column"] = columnname;
- row["columns"][column_idx]["value"] = value;
- row["columns"][column_idx]["font"] = font;
- row["columns"][column_idx]["font-style"] = font_style;
- column_idx++;
- }
- }
- name_list->addElement(row);
+ mNameColumnIndex = name_column->mIndex;
}
}
-
- std::string contents = node->getTextContents();
-
- typedef boost::tokenizer<boost::char_separator<char> > tokenizer;
- boost::char_separator<char> sep("\t\n");
- tokenizer tokens(contents, sep);
- tokenizer::iterator token_iter = tokens.begin();
-
- while(token_iter != tokens.end())
- {
- const std::string& line = *token_iter;
- name_list->addCommentText(line);
- ++token_iter;
- }
-
- return name_list;
}
-
-
-
diff --git a/indra/newview/llnamelistctrl.h b/indra/newview/llnamelistctrl.h
index 1b7795ddff..070b6c4f4f 100644
--- a/indra/newview/llnamelistctrl.h
+++ b/indra/newview/llnamelistctrl.h
@@ -39,35 +39,68 @@
class LLNameListCtrl
-: public LLScrollListCtrl
+: public LLScrollListCtrl, protected LLInstanceTracker<LLNameListCtrl>
{
public:
- LLNameListCtrl(const std::string& name,
- const LLRect& rect,
- LLUICtrlCallback callback,
- void* userdata,
- BOOL allow_multiple_selection,
- BOOL draw_border = TRUE,
- S32 name_column_index = 0,
- const std::string& tooltip = LLStringUtil::null);
- virtual ~LLNameListCtrl();
-
- virtual LLXMLNodePtr getXML(bool save_children = true) const;
- static LLView* fromXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFactory *factory);
-
+ typedef enum e_name_type
+ {
+ INDIVIDUAL,
+ GROUP,
+ SPECIAL
+ } ENameType;
+
+ // provide names for enums
+ struct NameTypeNames : public LLInitParam::TypeValuesHelper<LLNameListCtrl::ENameType, NameTypeNames>
+ {
+ static void declareValues();
+ };
+
+ struct NameItem : public LLInitParam::Block<NameItem, LLScrollListItem::Params>
+ {
+ Optional<std::string> name;
+ Optional<ENameType, NameTypeNames> target;
+
+ NameItem()
+ : name("name"),
+ target("target", INDIVIDUAL)
+ {}
+ };
+
+ struct NameColumn : public LLInitParam::Choice<NameColumn>
+ {
+ Alternative<S32> column_index;
+ Alternative<std::string> column_name;
+ NameColumn()
+ : column_name("name_column"),
+ column_index("name_column_index", 0)
+ {}
+ };
+
+ struct Params : public LLInitParam::Block<Params, LLScrollListCtrl::Params>
+ {
+ Optional<NameColumn> name_column;
+ Optional<bool> allow_calling_card_drop;
+ Params();
+ };
+
+protected:
+ LLNameListCtrl(const Params&);
+ friend class LLUICtrlFactory;
+public:
// Add a user to the list by name. It will be added, the name
// requested from the cache, and updated as necessary.
- BOOL addNameItem(const LLUUID& agent_id, EAddPosition pos = ADD_BOTTOM,
+ void addNameItem(const LLUUID& agent_id, EAddPosition pos = ADD_BOTTOM,
BOOL enabled = TRUE, std::string& suffix = LLStringUtil::null);
- BOOL addNameItem(LLScrollListItem* item, EAddPosition pos = ADD_BOTTOM);
+ void addNameItem(NameItem& item, EAddPosition pos = ADD_BOTTOM);
- virtual LLScrollListItem* addElement(const LLSD& value, EAddPosition pos = ADD_BOTTOM, void* userdata = NULL);
+ /*virtual*/ LLScrollListItem* addElement(const LLSD& element, EAddPosition pos = ADD_BOTTOM, void* userdata = NULL);
+ LLScrollListItem* addNameItemRow(const NameItem& value, EAddPosition pos = ADD_BOTTOM);
// Add a user to the list by name. It will be added, the name
// requested from the cache, and updated as necessary.
void addGroupNameItem(const LLUUID& group_id, EAddPosition pos = ADD_BOTTOM,
BOOL enabled = TRUE);
- void addGroupNameItem(LLScrollListItem* item, EAddPosition pos = ADD_BOTTOM);
+ void addGroupNameItem(NameItem& item, EAddPosition pos = ADD_BOTTOM);
void removeNameItem(const LLUUID& agent_id);
@@ -84,10 +117,11 @@ public:
void setAllowCallingCardDrop(BOOL b) { mAllowCallingCardDrop = b; }
+ /*virtual*/ void updateColumns();
private:
- static std::set<LLNameListCtrl*> sInstances;
- S32 mNameColumnIndex;
- BOOL mAllowCallingCardDrop;
+ S32 mNameColumnIndex;
+ std::string mNameColumn;
+ BOOL mAllowCallingCardDrop;
};
#endif
diff --git a/indra/newview/llnavigationbar.cpp b/indra/newview/llnavigationbar.cpp
new file mode 100644
index 0000000000..e40568a0cb
--- /dev/null
+++ b/indra/newview/llnavigationbar.cpp
@@ -0,0 +1,648 @@
+/**
+ * @file llnavigationbar.cpp
+ * @brief Navigation bar implementation
+ *
+ * $LicenseInfo:firstyear=2009&license=viewergpl$
+ *
+ * Copyright (c) 2009, Linden Research, Inc.
+ *
+ * Second Life Viewer Source Code
+ * The source code in this file ("Source Code") is provided by Linden Lab
+ * to you under the terms of the GNU General Public License, version 2.0
+ * ("GPL"), unless you have obtained a separate licensing agreement
+ * ("Other License"), formally executed by you and Linden Lab. Terms of
+ * the GPL can be found in doc/GPL-license.txt in this distribution, or
+ * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
+ *
+ * There are special exceptions to the terms and conditions of the GPL as
+ * it is applied to this Source Code. View the full text of the exception
+ * in the file doc/FLOSS-exception.txt in this software distribution, or
+ * online at
+ * http://secondlifegrid.net/programs/open_source/licensing/flossexception
+ *
+ * By copying, modifying or distributing this software, you acknowledge
+ * that you have read and understood your obligations described above,
+ * and agree to abide by those obligations.
+ *
+ * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+ * COMPLETENESS OR PERFORMANCE.
+ * $/LicenseInfo$
+ */
+
+#include "llviewerprecompiledheaders.h"
+
+#include "llnavigationbar.h"
+
+#include <llfloaterreg.h>
+#include <llfocusmgr.h>
+#include <lliconctrl.h>
+#include <llmenugl.h>
+
+#include "llagent.h"
+#include "llviewerregion.h"
+#include "lllandmarkactions.h"
+#include "lllocationhistory.h"
+#include "lllocationinputctrl.h"
+#include "llteleporthistory.h"
+#include "llsearcheditor.h"
+#include "llsidetray.h"
+#include "llslurl.h"
+#include "llurlsimstring.h"
+#include "llviewerinventory.h"
+#include "llviewerparcelmgr.h"
+#include "llworldmap.h"
+#include "llappviewer.h"
+#include "llviewercontrol.h"
+#include "llfloatermediabrowser.h"
+
+#include "llinventorymodel.h"
+#include "lllandmarkactions.h"
+
+#include "llfavoritesbar.h"
+#include "llagentui.h"
+
+//-- LLTeleportHistoryMenuItem -----------------------------------------------
+
+/**
+ * Item look varies depending on the type (backward/current/forward).
+ */
+class LLTeleportHistoryMenuItem : public LLMenuItemCallGL
+{
+public:
+ typedef enum e_item_type
+ {
+ TYPE_BACKWARD,
+ TYPE_CURRENT,
+ TYPE_FORWARD,
+ } EType;
+
+ struct Params : public LLInitParam::Block<Params, LLMenuItemCallGL::Params>
+ {
+ Mandatory<EType> item_type;
+
+ Params() {}
+ Params(EType type, std::string title);
+ };
+
+ /*virtual*/ void draw();
+ /*virtual*/ void onMouseEnter(S32 x, S32 y, MASK mask);
+ /*virtual*/ void onMouseLeave(S32 x, S32 y, MASK mask);
+
+private:
+ LLTeleportHistoryMenuItem(const Params&);
+ friend class LLUICtrlFactory;
+
+ static const S32 ICON_WIDTH = 16;
+ static const S32 ICON_HEIGHT = 16;
+ static const std::string ICON_IMG_BACKWARD;
+ static const std::string ICON_IMG_FORWARD;
+
+ LLIconCtrl* mArrowIcon;
+};
+
+const std::string LLTeleportHistoryMenuItem::ICON_IMG_BACKWARD("teleport_history_backward.tga");
+const std::string LLTeleportHistoryMenuItem::ICON_IMG_FORWARD("teleport_history_forward.tga");
+
+LLTeleportHistoryMenuItem::Params::Params(EType type, std::string title)
+{
+ item_type(type);
+ font.name("SANSSERIF");
+
+ if (type == TYPE_CURRENT)
+ font.style("BOLD");
+ else
+ title = " " + title;
+
+ name(title);
+ label(title);
+}
+
+LLTeleportHistoryMenuItem::LLTeleportHistoryMenuItem(const Params& p)
+: LLMenuItemCallGL(p),
+ mArrowIcon(NULL)
+{
+ LLIconCtrl::Params icon_params;
+ icon_params.name("icon");
+ icon_params.rect(LLRect(0, ICON_HEIGHT, ICON_WIDTH, 0));
+ icon_params.mouse_opaque(false);
+ icon_params.follows.flags(FOLLOWS_LEFT | FOLLOWS_TOP);
+ icon_params.visible(false);
+
+ mArrowIcon = LLUICtrlFactory::create<LLIconCtrl> (icon_params);
+
+ // no image for the current item
+ if (p.item_type == TYPE_BACKWARD)
+ mArrowIcon->setValue(ICON_IMG_BACKWARD);
+ else if (p.item_type == TYPE_FORWARD)
+ mArrowIcon->setValue(ICON_IMG_FORWARD);
+
+ addChild(mArrowIcon);
+}
+
+void LLTeleportHistoryMenuItem::draw()
+{
+ // Draw menu item itself.
+ LLMenuItemCallGL::draw();
+
+ // Draw children if any. *TODO: move this to LLMenuItemGL?
+ LLUICtrl::draw();
+}
+
+void LLTeleportHistoryMenuItem::onMouseEnter(S32 x, S32 y, MASK mask)
+{
+ mArrowIcon->setVisible(TRUE);
+}
+
+void LLTeleportHistoryMenuItem::onMouseLeave(S32 x, S32 y, MASK mask)
+{
+ mArrowIcon->setVisible(FALSE);
+}
+
+//-- LNavigationBar ----------------------------------------------------------
+
+/*
+TODO:
+- Load navbar height from saved settings (as it's done for status bar) or think of a better way.
+*/
+
+S32 NAVIGATION_BAR_HEIGHT = 60; // *HACK
+LLNavigationBar* LLNavigationBar::sInstance = 0;
+
+LLNavigationBar* LLNavigationBar::getInstance()
+{
+ if (!sInstance)
+ sInstance = new LLNavigationBar();
+
+ return sInstance;
+}
+
+LLNavigationBar::LLNavigationBar()
+: mTeleportHistoryMenu(NULL),
+ mBtnBack(NULL),
+ mBtnForward(NULL),
+ mBtnHome(NULL),
+ mCmbLocation(NULL),
+ mLeSearch(NULL),
+ mPurgeTPHistoryItems(false)
+{
+ setIsChrome(TRUE);
+
+ mParcelMgrConnection = LLViewerParcelMgr::getInstance()->setTeleportFinishedCallback(
+ boost::bind(&LLNavigationBar::onTeleportFinished, this, _1));
+
+ LLUICtrlFactory::getInstance()->buildPanel(this, "panel_navigation_bar.xml");
+
+ // set a listener function for LoginComplete event
+ LLAppViewer::instance()->setOnLoginCompletedCallback(boost::bind(&LLNavigationBar::handleLoginComplete, this));
+
+ // Necessary for focus movement among child controls
+ setFocusRoot(TRUE);
+}
+
+LLNavigationBar::~LLNavigationBar()
+{
+ mParcelMgrConnection.disconnect();
+ sInstance = 0;
+}
+
+BOOL LLNavigationBar::postBuild()
+{
+ mBtnBack = getChild<LLButton>("back_btn");
+ mBtnForward = getChild<LLButton>("forward_btn");
+ mBtnHome = getChild<LLButton>("home_btn");
+
+ mCmbLocation= getChild<LLLocationInputCtrl>("location_combo");
+ mLeSearch = getChild<LLSearchEditor>("search_input");
+
+ if (!mBtnBack || !mBtnForward || !mBtnHome ||
+ !mCmbLocation || !mLeSearch)
+ {
+ llwarns << "Malformed navigation bar" << llendl;
+ return FALSE;
+ }
+
+ mBtnBack->setEnabled(FALSE);
+ mBtnBack->setClickedCallback(boost::bind(&LLNavigationBar::onBackButtonClicked, this));
+ mBtnBack->setHeldDownCallback(boost::bind(&LLNavigationBar::onBackOrForwardButtonHeldDown, this, _2));
+
+ mBtnForward->setEnabled(FALSE);
+ mBtnForward->setClickedCallback(boost::bind(&LLNavigationBar::onForwardButtonClicked, this));
+ mBtnForward->setHeldDownCallback(boost::bind(&LLNavigationBar::onBackOrForwardButtonHeldDown, this, _2));
+
+ mBtnHome->setClickedCallback(boost::bind(&LLNavigationBar::onHomeButtonClicked, this));
+
+ mCmbLocation->setSelectionCallback(boost::bind(&LLNavigationBar::onLocationSelection, this));
+
+ mLeSearch->setCommitCallback(boost::bind(&LLNavigationBar::onSearchCommit, this));
+
+ mDefaultNbRect = getRect();
+ mDefaultFpRect = getChild<LLFavoritesBarCtrl>("favorite")->getRect();
+
+ // we'll be notified on teleport history changes
+ LLTeleportHistory::getInstance()->setHistoryChangedCallback(
+ boost::bind(&LLNavigationBar::onTeleportHistoryChanged, this));
+
+ return TRUE;
+}
+
+void LLNavigationBar::draw()
+{
+ if(mPurgeTPHistoryItems)
+ {
+ LLTeleportHistory::getInstance()->purgeItems();
+ onTeleportHistoryChanged();
+ mPurgeTPHistoryItems = false;
+ }
+ LLPanel::draw();
+}
+
+void LLNavigationBar::onBackButtonClicked()
+{
+ LLTeleportHistory::getInstance()->goBack();
+}
+
+void LLNavigationBar::onBackOrForwardButtonHeldDown(const LLSD& param)
+{
+ if (param["count"].asInteger() == 0)
+ showTeleportHistoryMenu();
+}
+
+void LLNavigationBar::onForwardButtonClicked()
+{
+ LLTeleportHistory::getInstance()->goForward();
+}
+
+void LLNavigationBar::onHomeButtonClicked()
+{
+ gAgent.teleportHome();
+}
+
+void LLNavigationBar::onSearchCommit()
+{
+ invokeSearch(mLeSearch->getValue().asString());
+}
+
+void LLNavigationBar::onTeleportHistoryMenuItemClicked(const LLSD& userdata)
+{
+ int idx = userdata.asInteger();
+ LLTeleportHistory::getInstance()->goToItem(idx);
+}
+
+// This is called when user presses enter in the location input
+// or selects a location from the typed locations dropdown.
+void LLNavigationBar::onLocationSelection()
+{
+ std::string typed_location = mCmbLocation->getSimple();
+
+ // Will not teleport to empty location.
+ if (typed_location.empty())
+ return;
+
+ std::string region_name;
+ LLVector3 local_coords(128, 128, 0);
+ S32 x = 0, y = 0, z = 0;
+
+ // Is the typed location a SLURL?
+ if (LLSLURL::isSLURL(typed_location))
+ {
+ // Yes. Extract region name and local coordinates from it.
+ if (LLURLSimString::parse(LLSLURL::stripProtocol(typed_location), &region_name, &x, &y, &z))
+ local_coords.set(x, y, z);
+ else
+ return;
+ }
+ else
+ {
+ //If it is not slurl let's look for landmarks
+ LLInventoryModel::item_array_t landmark_items = LLLandmarkActions::fetchLandmarksByName(typed_location, FALSE);
+ if ( !landmark_items.empty() )
+ {
+ gAgent.teleportViaLandmark(landmark_items[0]->getAssetUUID());
+ return;
+ }
+ //No landmark match, check if it is a region name
+ region_name = parseLocation(typed_location, &x, &y, &z);
+ if (region_name != typed_location)
+ local_coords.set(x, y, z);
+
+ // Treat it as region name.
+ // region_name = typed_location;
+ }
+
+ // Resolve the region name to its global coordinates.
+ // If resolution succeeds we'll teleport.
+ LLWorldMap::url_callback_t cb = boost::bind(
+ &LLNavigationBar::onRegionNameResponse, this,
+ typed_location, region_name, local_coords, _1, _2, _3, _4);
+ LLWorldMap::getInstance()->sendNamedRegionRequest(region_name, cb, std::string("unused"), false);
+}
+
+void LLNavigationBar::onTeleportFinished(const LLVector3d& global_agent_pos)
+{
+ // Location is valid. Add it to the typed locations history.
+ LLLocationHistory* lh = LLLocationHistory::getInstance();
+
+ std::string location;
+ /*NOTE:
+ * We can't use gAgent.getPositionAgent() in case of local teleport to build location.
+ * At this moment gAgent.getPositionAgent() contains previous coordinates.
+ * according to EXT-65 agent position is being reseted on each frame.
+ */
+ LLAgentUI::buildLocationString(location, LLAgentUI::LOCATION_FORMAT_WITHOUT_SIM,
+ gAgent.getPosAgentFromGlobal(global_agent_pos));
+
+ //Touch it, if it is at list already, add new location otherwise
+ if ( !lh->touchItem(location) ) {
+ std::string tooltip = LLSLURL::buildSLURLfromPosGlobal(
+ gAgent.getRegion()->getName(), global_agent_pos, false);
+
+ lh->addItem(location, tooltip);
+ }
+ llinfos << "Saving after on teleport finish" << llendl;
+ lh->save();
+
+}
+
+void LLNavigationBar::onTeleportHistoryChanged()
+{
+ // Update navigation controls.
+ LLTeleportHistory* h = LLTeleportHistory::getInstance();
+ int cur_item = h->getCurrentItemIndex();
+ mBtnBack->setEnabled(cur_item > 0);
+ mBtnForward->setEnabled(cur_item < ((int)h->getItems().size() - 1));
+}
+
+void LLNavigationBar::rebuildTeleportHistoryMenu()
+{
+ // Has the pop-up menu been built?
+ if (mTeleportHistoryMenu)
+ {
+ // Clear it.
+ mTeleportHistoryMenu->empty();
+ }
+ else
+ {
+ // Create it.
+ LLMenuGL::Params menu_p;
+ menu_p.name("popup");
+ menu_p.can_tear_off(false);
+ menu_p.visible(false);
+ menu_p.bg_visible(true);
+ menu_p.scrollable(true);
+ mTeleportHistoryMenu = LLUICtrlFactory::create<LLMenuGL>(menu_p);
+
+ addChild(mTeleportHistoryMenu);
+ }
+
+ // Populate the menu with teleport history items.
+ LLTeleportHistory* hist = LLTeleportHistory::getInstance();
+ const LLTeleportHistory::slurl_list_t& hist_items = hist->getItems();
+ int cur_item = hist->getCurrentItemIndex();
+
+ // Items will be shown in the reverse order, just like in Firefox.
+ for (int i = (int)hist_items.size()-1; i >= 0; i--)
+ {
+ LLTeleportHistoryMenuItem::EType type;
+ if (i < cur_item)
+ type = LLTeleportHistoryMenuItem::TYPE_BACKWARD;
+ else if (i > cur_item)
+ type = LLTeleportHistoryMenuItem::TYPE_FORWARD;
+ else
+ type = LLTeleportHistoryMenuItem::TYPE_CURRENT;
+
+ LLTeleportHistoryMenuItem::Params item_params(type, hist_items[i].getTitle());
+ item_params.on_click.function(boost::bind(&LLNavigationBar::onTeleportHistoryMenuItemClicked, this, i));
+ mTeleportHistoryMenu->addChild(LLUICtrlFactory::create<LLTeleportHistoryMenuItem>(item_params));
+ }
+}
+
+void LLNavigationBar::onRegionNameResponse(
+ std::string typed_location,
+ std::string region_name,
+ LLVector3 local_coords,
+ U64 region_handle, const std::string& url, const LLUUID& snapshot_id, bool teleport)
+{
+ // Invalid location?
+ if (!region_handle)
+ {
+ invokeSearch(typed_location);
+ return;
+ }
+
+ // Teleport to the location.
+ LLVector3d region_pos = from_region_handle(region_handle);
+ LLVector3d global_pos = region_pos + (LLVector3d) local_coords;
+
+ llinfos << "Teleporting to: " << global_pos << llendl;
+ gAgent.teleportViaLocation(global_pos);
+}
+
+void LLNavigationBar::showTeleportHistoryMenu()
+{
+ // Don't show the popup if teleport history is empty.
+ if (LLTeleportHistory::getInstance()->isEmpty())
+ {
+ lldebugs << "Teleport history is empty, will not show the menu." << llendl;
+ return;
+ }
+
+ rebuildTeleportHistoryMenu();
+
+ if (mTeleportHistoryMenu == NULL)
+ return;
+
+ // *TODO: why to draw/update anything before showing the menu?
+ mTeleportHistoryMenu->buildDrawLabels();
+ mTeleportHistoryMenu->updateParent(LLMenuGL::sMenuContainer);
+ LLRect btnBackRect = mBtnBack->getRect();
+ LLMenuGL::showPopup(this, mTeleportHistoryMenu, btnBackRect.mLeft, btnBackRect.mBottom);
+
+ // *HACK pass the mouse capturing to the drop-down menu
+ gFocusMgr.setMouseCapture( NULL );
+}
+
+void LLNavigationBar::handleLoginComplete()
+{
+ mCmbLocation->handleLoginComplete();
+}
+
+void LLNavigationBar::invokeSearch(std::string search_text)
+{
+ LLFloaterReg::showInstance("search", LLSD().insert("panel", "all").insert("id", LLSD(search_text)));
+}
+
+std::string LLNavigationBar::parseLocation(const std::string & location, S32* x, S32* y, S32* z) {
+ /*
+ * This regular expression extracts numbers from the following string
+ * construct: "(num1, num2, num3)", where num1, num2 and num3 are decimal
+ * numbers. Leading and trailing spaces are also caught by the expression.
+ */
+ const boost::regex re("\\s*\\((\\d+),\\s*(\\d+),\\s*(\\d+)\\)\\s*");
+
+ boost::smatch m;
+ if (boost::regex_search(location, m, re)) {
+ // string representations of parsed by regex++ numbers
+ std::string xstr(m[1].first, m[1].second);
+ std::string ystr(m[2].first, m[2].second);
+ std::string zstr(m[3].first, m[3].second);
+
+ *x = atoi(xstr.c_str());
+ *y = atoi(ystr.c_str());
+ *z = atoi(zstr.c_str());
+ //erase commas in coordinates
+ std::string region_parcel = boost::regex_replace(location, re, "");
+ // cut region name
+ return region_parcel.substr(0, region_parcel.find_first_of(','));
+ }
+
+ *x = *y = *z = 0;
+
+ return location;
+}
+
+void LLNavigationBar::clearHistoryCache()
+{
+ mCmbLocation->removeall();
+ LLLocationHistory* lh = LLLocationHistory::getInstance();
+ lh->removeItems();
+ lh->save();
+ mPurgeTPHistoryItems= true;
+}
+
+void LLNavigationBar::showNavigationPanel(BOOL visible)
+{
+ bool fpVisible = gSavedSettings.getBOOL("ShowNavbarFavoritesPanel");
+
+ LLFavoritesBarCtrl* fb = getChild<LLFavoritesBarCtrl>("favorite");
+ LLPanel* navPanel = getChild<LLPanel>("navigation_panel");
+
+ LLRect nbRect(getRect());
+ LLRect fbRect(fb->getRect());
+
+ navPanel->setVisible(visible);
+
+ if (visible)
+ {
+ if (fpVisible)
+ {
+ // Navigation Panel must be shown. Favorites Panel is visible.
+
+ nbRect.setLeftTopAndSize(nbRect.mLeft, nbRect.mTop, nbRect.getWidth(), mDefaultNbRect.getHeight());
+ fbRect.setLeftTopAndSize(fbRect.mLeft, mDefaultFpRect.mTop, fbRect.getWidth(), fbRect.getHeight());
+
+ // this is duplicated in 'else' section because it should be called BEFORE fb->reshape
+ reshape(nbRect.getWidth(), nbRect.getHeight());
+ setRect(nbRect);
+
+ fb->reshape(fbRect.getWidth(), fbRect.getHeight());
+ fb->setRect(fbRect);
+ }
+ else
+ {
+ // Navigation Panel must be shown. Favorites Panel is hidden.
+
+ S32 height = mDefaultNbRect.getHeight() - mDefaultFpRect.getHeight();
+ nbRect.setLeftTopAndSize(nbRect.mLeft, nbRect.mTop, nbRect.getWidth(), height);
+
+ reshape(nbRect.getWidth(), nbRect.getHeight());
+ setRect(nbRect);
+ }
+ }
+ else
+ {
+ if (fpVisible)
+ {
+ // Navigation Panel must be hidden. Favorites Panel is visible.
+
+ nbRect.setLeftTopAndSize(nbRect.mLeft, nbRect.mTop, nbRect.getWidth(), fbRect.getHeight());
+ fbRect.setLeftTopAndSize(fbRect.mLeft, fbRect.getHeight(), fbRect.getWidth(), fbRect.getHeight());
+
+ // this is duplicated in 'else' section because it should be called BEFORE fb->reshape
+ reshape(nbRect.getWidth(), nbRect.getHeight());
+ setRect(nbRect);
+
+ fb->reshape(fbRect.getWidth(), fbRect.getHeight());
+ fb->setRect(fbRect);
+ }
+ else
+ {
+ // Navigation Panel must be hidden. Favorites Panel is hidden.
+
+ nbRect.setLeftTopAndSize(nbRect.mLeft, nbRect.mTop, nbRect.getWidth(), 0);
+
+ reshape(nbRect.getWidth(), nbRect.getHeight());
+ setRect(nbRect);
+ }
+ }
+
+ if(LLSideTray::instanceCreated())
+ {
+ LLSideTray::getInstance()->resetPanelRect();
+ }
+}
+
+void LLNavigationBar::showFavoritesPanel(BOOL visible)
+{
+ bool npVisible = gSavedSettings.getBOOL("ShowNavbarNavigationPanel");
+
+ LLFavoritesBarCtrl* fb = getChild<LLFavoritesBarCtrl>("favorite");
+
+ LLRect nbRect(getRect());
+ LLRect fbRect(fb->getRect());
+
+ if (visible)
+ {
+ if (npVisible)
+ {
+ // Favorites Panel must be shown. Navigation Panel is visible.
+
+ S32 fbHeight = fbRect.getHeight();
+ S32 newHeight = nbRect.getHeight() + fbHeight;
+
+ nbRect.setLeftTopAndSize(nbRect.mLeft, nbRect.mTop, nbRect.getWidth(), newHeight);
+ fbRect.setLeftTopAndSize(mDefaultFpRect.mLeft, mDefaultFpRect.mTop, fbRect.getWidth(), fbRect.getHeight());
+ }
+ else
+ {
+ // Favorites Panel must be shown. Navigation Panel is hidden.
+
+ S32 fpHeight = mDefaultFpRect.getHeight();
+ nbRect.setLeftTopAndSize(nbRect.mLeft, nbRect.mTop, nbRect.getWidth(), fpHeight);
+ fbRect.setLeftTopAndSize(fbRect.mLeft, fpHeight, fbRect.getWidth(), fpHeight);
+ }
+
+ reshape(nbRect.getWidth(), nbRect.getHeight());
+ setRect(nbRect);
+
+ fb->reshape(fbRect.getWidth(), fbRect.getHeight());
+ fb->setRect(fbRect);
+ }
+ else
+ {
+ if (npVisible)
+ {
+ // Favorites Panel must be hidden. Navigation Panel is visible.
+
+ S32 fbHeight = fbRect.getHeight();
+ S32 newHeight = nbRect.getHeight() - fbHeight;
+
+ nbRect.setLeftTopAndSize(nbRect.mLeft, nbRect.mTop, nbRect.getWidth(), newHeight);
+ }
+ else
+ {
+ // Favorites Panel must be hidden. Navigation Panel is hidden.
+
+ nbRect.setLeftTopAndSize(nbRect.mLeft, nbRect.mTop, nbRect.getWidth(), 0);
+ }
+
+ reshape(nbRect.getWidth(), nbRect.getHeight());
+ setRect(nbRect);
+ }
+
+ fb->setVisible(visible);
+ if(LLSideTray::instanceCreated())
+ {
+ LLSideTray::getInstance()->resetPanelRect();
+ }
+}
diff --git a/indra/newview/llnavigationbar.h b/indra/newview/llnavigationbar.h
new file mode 100644
index 0000000000..6932847854
--- /dev/null
+++ b/indra/newview/llnavigationbar.h
@@ -0,0 +1,111 @@
+/**
+ * @file llnavigationbar.h
+ * @brief Navigation bar definition
+ *
+ * $LicenseInfo:firstyear=2009&license=viewergpl$
+ *
+ * Copyright (c) 2009, Linden Research, Inc.
+ *
+ * Second Life Viewer Source Code
+ * The source code in this file ("Source Code") is provided by Linden Lab
+ * to you under the terms of the GNU General Public License, version 2.0
+ * ("GPL"), unless you have obtained a separate licensing agreement
+ * ("Other License"), formally executed by you and Linden Lab. Terms of
+ * the GPL can be found in doc/GPL-license.txt in this distribution, or
+ * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
+ *
+ * There are special exceptions to the terms and conditions of the GPL as
+ * it is applied to this Source Code. View the full text of the exception
+ * in the file doc/FLOSS-exception.txt in this software distribution, or
+ * online at
+ * http://secondlifegrid.net/programs/open_source/licensing/flossexception
+ *
+ * By copying, modifying or distributing this software, you acknowledge
+ * that you have read and understood your obligations described above,
+ * and agree to abide by those obligations.
+ *
+ * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+ * COMPLETENESS OR PERFORMANCE.
+ * $/LicenseInfo$
+ */
+
+#ifndef LL_LLNAVIGATIONBAR_H
+#define LL_LLNAVIGATIONBAR_H
+
+#include "llpanel.h"
+
+extern S32 NAVIGATION_BAR_HEIGHT;
+
+class LLButton;
+class LLLocationInputCtrl;
+class LLMenuGL;
+class LLSearchEditor;
+
+/**
+ * Web browser-like navigation bar.
+ */
+class LLNavigationBar
+: public LLPanel
+{
+ LOG_CLASS(LLNavigationBar);
+
+public:
+ static LLNavigationBar* getInstance();
+ virtual ~LLNavigationBar();
+
+ /*virtual*/ void draw();
+ /*virtual*/ BOOL postBuild();
+
+ void handleLoginComplete();
+ void clearHistoryCache();
+
+ void showNavigationPanel(BOOL visible);
+ void showFavoritesPanel(BOOL visible);
+
+private:
+ LLNavigationBar();
+
+ void rebuildTeleportHistoryMenu();
+ void showTeleportHistoryMenu();
+ void invokeSearch(std::string search_text);
+
+ /**
+ * Get region name and local coordinates from typed location
+ */
+ static std::string parseLocation(const std::string & location, S32* x, S32* y, S32* z);
+
+ // callbacks
+ void onTeleportHistoryMenuItemClicked(const LLSD& userdata);
+ void onTeleportHistoryChanged();
+ void onBackButtonClicked();
+ void onBackOrForwardButtonHeldDown(const LLSD& param);
+ void onForwardButtonClicked();
+ void onHomeButtonClicked();
+ void onHelpButtonClicked();
+ void onLocationSelection();
+ void onLocationPrearrange(const LLSD& data);
+ void onSearchCommit();
+ void onTeleportFinished(const LLVector3d& global_agent_pos);
+ void onRegionNameResponse(
+ std::string typed_location,
+ std::string region_name,
+ LLVector3 local_coords,
+ U64 region_handle, const std::string& url,
+ const LLUUID& snapshot_id, bool teleport);
+
+ static LLNavigationBar *sInstance;
+
+ LLMenuGL* mTeleportHistoryMenu;
+ LLButton* mBtnBack;
+ LLButton* mBtnForward;
+ LLButton* mBtnHome;
+ LLSearchEditor* mLeSearch;
+ LLLocationInputCtrl* mCmbLocation;
+ LLRect mDefaultNbRect;
+ LLRect mDefaultFpRect;
+ boost::signals2::connection mParcelMgrConnection;
+ bool mPurgeTPHistoryItems;
+};
+
+#endif
diff --git a/indra/newview/llnearbychat.cpp b/indra/newview/llnearbychat.cpp
new file mode 100644
index 0000000000..3856a86da0
--- /dev/null
+++ b/indra/newview/llnearbychat.cpp
@@ -0,0 +1,486 @@
+/**
+ * @file LLNearbyChat.cpp
+ * @brief Nearby chat history scrolling panel implementation
+ *
+ * $LicenseInfo:firstyear=2009&license=viewergpl$
+ *
+ * Copyright (c) 2009, Linden Research, Inc.
+ *
+ * Second Life Viewer Source Code
+ * The source code in this file ("Source Code") is provided by Linden Lab
+ * to you under the terms of the GNU General Public License, version 2.0
+ * ("GPL"), unless you have obtained a separate licensing agreement
+ * ("Other License"), formally executed by you and Linden Lab. Terms of
+ * the GPL can be found in doc/GPL-license.txt in this distribution, or
+ * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
+ *
+ * There are special exceptions to the terms and conditions of the GPL as
+ * it is applied to this Source Code. View the full text of the exception
+ * in the file doc/FLOSS-exception.txt in this software distribution, or
+ * online at
+ * http://secondlifegrid.net/programs/open_source/licensing/flossexception
+ *
+ * By copying, modifying or distributing this software, you acknowledge
+ * that you have read and understood your obligations described above,
+ * and agree to abide by those obligations.
+ *
+ * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+ * COMPLETENESS OR PERFORMANCE.
+ * $/LicenseInfo$
+ */
+
+#include "llviewerprecompiledheaders.h"
+
+#include "llnearbychat.h"
+#include "llviewercontrol.h"
+#include "llviewerwindow.h"
+#include "llrootview.h"
+//#include "llchatitemscontainerctrl.h"
+#include "lliconctrl.h"
+#include "llsidetray.h"
+#include "llfocusmgr.h"
+#include "llresizebar.h"
+#include "llresizehandle.h"
+#include "llmenugl.h"
+#include "llviewermenu.h"//for gMenuHolder
+
+#include "llnearbychathandler.h"
+#include "llchannelmanager.h"
+
+//for LLViewerTextEditor support
+#include "llagent.h" // gAgent
+#include "llfloaterscriptdebug.h"
+#include "llviewertexteditor.h"
+#include "llstylemap.h"
+
+#include "lldraghandle.h"
+
+
+static const S32 RESIZE_BAR_THICKNESS = 3;
+
+LLNearbyChat::LLNearbyChat(const LLSD& key) :
+ LLFloater(key),
+ mEChatTearofState(CHAT_PINNED),
+ mChatCaptionPanel(NULL),
+ mChatHistoryEditor(NULL)
+{
+}
+
+LLNearbyChat::~LLNearbyChat()
+{
+}
+
+BOOL LLNearbyChat::postBuild()
+{
+ //resize bars
+ setCanResize(true);
+
+ mResizeBar[LLResizeBar::BOTTOM]->setVisible(false);
+ mResizeBar[LLResizeBar::LEFT]->setVisible(false);
+ mResizeBar[LLResizeBar::RIGHT]->setVisible(false);
+
+ mResizeBar[LLResizeBar::BOTTOM]->setResizeLimits(120,500);
+ mResizeBar[LLResizeBar::TOP]->setResizeLimits(120,500);
+ mResizeBar[LLResizeBar::LEFT]->setResizeLimits(220,600);
+ mResizeBar[LLResizeBar::RIGHT]->setResizeLimits(220,600);
+
+ mResizeHandle[0]->setVisible(false);
+ mResizeHandle[1]->setVisible(false);
+ mResizeHandle[2]->setVisible(false);
+ mResizeHandle[3]->setVisible(false);
+
+ getDragHandle()->setVisible(false);
+
+ //menu
+ LLUICtrl::CommitCallbackRegistry::ScopedRegistrar registrar;
+ LLUICtrl::EnableCallbackRegistry::ScopedRegistrar enable_registrar;
+
+ enable_registrar.add("NearbyChat.Check", boost::bind(&LLNearbyChat::onNearbyChatCheckContextMenuItem, this, _2));
+ registrar.add("NearbyChat.Action", boost::bind(&LLNearbyChat::onNearbyChatContextMenuItemClicked, this, _2));
+
+
+ LLMenuGL* menu = LLUICtrlFactory::getInstance()->createFromFile<LLMenuGL>("menu_nearby_chat.xml", gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance());
+
+ if(menu)
+ mPopupMenuHandle = menu->getHandle();
+
+ gSavedSettings.declareS32("nearbychat_showicons_and_names",2,"NearByChat header settings",true);
+
+ mChatCaptionPanel = getChild<LLPanel>("chat_caption", false);
+ mChatHistoryEditor = getChild<LLViewerTextEditor>("Chat History Editor");
+
+ reshape(getRect().getWidth(), getRect().getHeight(), FALSE);
+
+ return LLFloater::postBuild();
+}
+
+
+LLColor4 nearbychat_get_text_color(const LLChat& chat)
+{
+ LLColor4 text_color;
+
+ if(chat.mMuted)
+ {
+ text_color.setVec(0.8f, 0.8f, 0.8f, 1.f);
+ }
+ else
+ {
+ switch(chat.mSourceType)
+ {
+ case CHAT_SOURCE_SYSTEM:
+ text_color = LLUIColorTable::instance().getColor("SystemChatColor");
+ break;
+ case CHAT_SOURCE_AGENT:
+ if (chat.mFromID.isNull())
+ {
+ text_color = LLUIColorTable::instance().getColor("SystemChatColor");
+ }
+ else
+ {
+ if(gAgentID == chat.mFromID)
+ {
+ text_color = LLUIColorTable::instance().getColor("UserChatColor");
+ }
+ else
+ {
+ text_color = LLUIColorTable::instance().getColor("AgentChatColor");
+ }
+ }
+ break;
+ case CHAT_SOURCE_OBJECT:
+ if (chat.mChatType == CHAT_TYPE_DEBUG_MSG)
+ {
+ text_color = LLUIColorTable::instance().getColor("ScriptErrorColor");
+ }
+ else if ( chat.mChatType == CHAT_TYPE_OWNER )
+ {
+ text_color = LLUIColorTable::instance().getColor("llOwnerSayChatColor");
+ }
+ else
+ {
+ text_color = LLUIColorTable::instance().getColor("ObjectChatColor");
+ }
+ break;
+ default:
+ text_color.setToWhite();
+ }
+
+ if (!chat.mPosAgent.isExactlyZero())
+ {
+ LLVector3 pos_agent = gAgent.getPositionAgent();
+ F32 distance = dist_vec(pos_agent, chat.mPosAgent);
+ if (distance > gAgent.getNearChatRadius())
+ {
+ // diminish far-off chat
+ text_color.mV[VALPHA] = 0.8f;
+ }
+ }
+ }
+
+ return text_color;
+}
+
+void nearbychat_add_timestamped_line(LLViewerTextEditor* edit, LLChat chat, const LLColor4& color)
+{
+ std::string line = chat.mFromName;
+ line +=": ";
+ line +=chat.mText;
+
+ bool prepend_newline = true;
+ if (gSavedSettings.getBOOL("ChatShowTimestamps"))
+ {
+ edit->appendTime(prepend_newline);
+ prepend_newline = false;
+ }
+
+ // If the msg is from an agent (not yourself though),
+ // extract out the sender name and replace it with the hotlinked name.
+ if (chat.mSourceType == CHAT_SOURCE_AGENT &&
+ chat.mFromID != LLUUID::null)
+ {
+ chat.mURL = llformat("secondlife:///app/agent/%s/about",chat.mFromID.asString().c_str());
+ }
+
+ // If the chat line has an associated url, link it up to the name.
+ if (!chat.mURL.empty()
+ && (line.length() > chat.mFromName.length() && line.find(chat.mFromName,0) == 0))
+ {
+ std::string start_line = line.substr(0, chat.mFromName.length() + 1);
+ line = line.substr(chat.mFromName.length() + 1);
+ edit->appendStyledText(start_line, false, prepend_newline, LLStyleMap::instance().lookup(chat.mFromID,chat.mURL));
+ prepend_newline = false;
+ }
+
+ S32 font_size = gSavedSettings.getS32("ChatFontSize");
+
+ std::string font_name = "";
+
+ if (0 == font_size)
+ font_name = "small";
+ else if (2 == font_size)
+ font_name = "sansserifbig";
+
+ edit->appendColoredText(line, false, prepend_newline, color, font_name);
+}
+
+
+
+void LLNearbyChat::addMessage(const LLChat& chat)
+{
+ LLColor4 color = nearbychat_get_text_color(chat);
+
+
+ if (chat.mChatType == CHAT_TYPE_DEBUG_MSG)
+ {
+ LLFloaterScriptDebug::addScriptLine(chat.mText,
+ chat.mFromName,
+ color,
+ chat.mFromID);
+ if (!gSavedSettings.getBOOL("ScriptErrorsAsChat"))
+ {
+ return;
+ }
+ }
+
+ // could flash the chat button in the status bar here. JC
+
+
+ mChatHistoryEditor->setParseHTML(TRUE);
+ mChatHistoryEditor->setParseHighlights(TRUE);
+
+ if (!chat.mMuted)
+ nearbychat_add_timestamped_line(mChatHistoryEditor, chat, color);
+}
+
+void LLNearbyChat::onNearbySpeakers()
+{
+ LLSD param;
+ param["people_panel_tab_name"] = "nearby_panel";
+ LLSideTray::getInstance()->showPanel("panel_people",param);
+}
+
+void LLNearbyChat::onTearOff()
+{
+ if(mEChatTearofState == CHAT_PINNED)
+ float_panel();
+ else
+ pinn_panel();
+}
+
+void LLNearbyChat::reshape(S32 width, S32 height, BOOL called_from_parent)
+{
+
+ LLFloater::reshape(width, height, called_from_parent);
+
+ LLRect resize_rect;
+ resize_rect.setLeftTopAndSize( 0, height, width, RESIZE_BAR_THICKNESS);
+ if (mResizeBar[LLResizeBar::TOP])
+ {
+ mResizeBar[LLResizeBar::TOP]->reshape(width,RESIZE_BAR_THICKNESS);
+ mResizeBar[LLResizeBar::TOP]->setRect(resize_rect);
+ }
+
+ resize_rect.setLeftTopAndSize( 0, RESIZE_BAR_THICKNESS, width, RESIZE_BAR_THICKNESS);
+ if (mResizeBar[LLResizeBar::BOTTOM])
+ {
+ mResizeBar[LLResizeBar::BOTTOM]->reshape(width,RESIZE_BAR_THICKNESS);
+ mResizeBar[LLResizeBar::BOTTOM]->setRect(resize_rect);
+ }
+
+ resize_rect.setLeftTopAndSize( 0, height, RESIZE_BAR_THICKNESS, height);
+ if (mResizeBar[LLResizeBar::LEFT])
+ {
+ mResizeBar[LLResizeBar::LEFT]->reshape(RESIZE_BAR_THICKNESS,height);
+ mResizeBar[LLResizeBar::LEFT]->setRect(resize_rect);
+ }
+
+ resize_rect.setLeftTopAndSize( width - RESIZE_BAR_THICKNESS, height, RESIZE_BAR_THICKNESS, height);
+ if (mResizeBar[LLResizeBar::RIGHT])
+ {
+ mResizeBar[LLResizeBar::RIGHT]->reshape(RESIZE_BAR_THICKNESS,height);
+ mResizeBar[LLResizeBar::RIGHT]->setRect(resize_rect);
+ }
+
+ // *NOTE: we must check mChatCaptionPanel and mChatHistoryEditor against NULL because reshape is called from the
+ // LLView::initFromParams BEFORE postBuild is called and child controls are not exist yet
+ LLRect caption_rect;
+ if (NULL != mChatCaptionPanel)
+ {
+ caption_rect = mChatCaptionPanel->getRect();
+ caption_rect.setLeftTopAndSize( 2, height - RESIZE_BAR_THICKNESS, width - 4, caption_rect.getHeight());
+ mChatCaptionPanel->reshape( width - 4, caption_rect.getHeight(), 1);
+ mChatCaptionPanel->setRect(caption_rect);
+ }
+
+ if (NULL != mChatHistoryEditor)
+ {
+ LLRect scroll_rect = mChatHistoryEditor->getRect();
+ scroll_rect.setLeftTopAndSize( 2, height - caption_rect.getHeight() - RESIZE_BAR_THICKNESS, width - 4, height - caption_rect.getHeight() - RESIZE_BAR_THICKNESS*2);
+ mChatHistoryEditor->reshape( width - 4, height - caption_rect.getHeight() - RESIZE_BAR_THICKNESS*2, 1);
+ mChatHistoryEditor->setRect(scroll_rect);
+ }
+
+ //
+ if(mEChatTearofState == CHAT_PINNED)
+ {
+ const LLRect& parent_rect = gViewerWindow->getRootView()->getRect();
+
+ LLRect panel_rect;
+ panel_rect.setLeftTopAndSize( parent_rect.mLeft+2, parent_rect.mBottom+height+4, width, height);
+ setRect(panel_rect);
+ }
+ else
+ {
+ LLRect panel_rect;
+ panel_rect.setLeftTopAndSize( getRect().mLeft, getRect().mTop, width, height);
+ setRect(panel_rect);
+ }
+
+}
+
+BOOL LLNearbyChat::handleMouseDown (S32 x, S32 y, MASK mask)
+{
+ LLUICtrl* nearby_speakers_btn = mChatCaptionPanel->getChild<LLUICtrl>("nearby_speakers_btn");
+ LLUICtrl* tearoff_btn = mChatCaptionPanel->getChild<LLUICtrl>("tearoff_btn");
+ LLUICtrl* close_btn = mChatCaptionPanel->getChild<LLUICtrl>("close_btn");
+
+ S32 caption_local_x = x - mChatCaptionPanel->getRect().mLeft;
+ S32 caption_local_y = y - mChatCaptionPanel->getRect().mBottom;
+
+ S32 local_x = caption_local_x - nearby_speakers_btn->getRect().mLeft;
+ S32 local_y = caption_local_y - nearby_speakers_btn->getRect().mBottom;
+ if(nearby_speakers_btn->pointInView(local_x, local_y))
+ {
+
+ onNearbySpeakers();
+ bringToFront( x, y );
+ return true;
+ }
+ local_x = caption_local_x - tearoff_btn->getRect().mLeft;
+ local_y = caption_local_y- tearoff_btn->getRect().mBottom;
+ if(tearoff_btn->pointInView(local_x, local_y))
+ {
+ onTearOff();
+ bringToFront( x, y );
+ return true;
+ }
+
+ local_x = caption_local_x - close_btn->getRect().mLeft;
+ local_y = caption_local_y - close_btn->getRect().mBottom;
+ if(close_btn->pointInView(local_x, local_y))
+ {
+ setVisible(false);
+ bringToFront( x, y );
+ return true;
+ }
+
+ if(mEChatTearofState == CHAT_UNPINNED && mChatCaptionPanel->pointInView(caption_local_x, caption_local_y) )
+ {
+ //start draggind
+ gFocusMgr.setMouseCapture(this);
+ mStart_Y = y;
+ mStart_X = x;
+ bringToFront( x, y );
+ return true;
+ }
+
+ return LLFloater::handleMouseDown(x,y,mask);
+}
+
+BOOL LLNearbyChat::handleMouseUp(S32 x, S32 y, MASK mask)
+{
+ if( hasMouseCapture() )
+ {
+ // Release the mouse
+ gFocusMgr.setMouseCapture( NULL );
+ mStart_X = 0;
+ mStart_Y = 0;
+ return true;
+ }
+
+ return LLFloater::handleMouseUp(x,y,mask);
+}
+
+BOOL LLNearbyChat::handleHover(S32 x, S32 y, MASK mask)
+{
+ if( hasMouseCapture() )
+ {
+ translate(x-mStart_X,y-mStart_Y);
+ return true;
+ }
+ return LLFloater::handleHover(x,y,mask);
+}
+
+void LLNearbyChat::pinn_panel()
+{
+ mEChatTearofState = CHAT_PINNED;
+ LLIconCtrl* tearoff_btn = mChatCaptionPanel->getChild<LLIconCtrl>("tearoff_btn",false);
+
+ tearoff_btn->setValue("inv_item_landmark_visited.tga");
+
+ const LLRect& parent_rect = gViewerWindow->getRootView()->getRect();
+
+ LLRect panel_rect;
+ panel_rect.setLeftTopAndSize( parent_rect.mLeft+2, parent_rect.mBottom+getRect().getHeight()+4, getRect().getWidth(), getRect().getHeight());
+ setRect(panel_rect);
+
+ mResizeBar[LLResizeBar::BOTTOM]->setVisible(false);
+ mResizeBar[LLResizeBar::LEFT]->setVisible(false);
+ mResizeBar[LLResizeBar::RIGHT]->setVisible(false);
+
+ getDragHandle()->setVisible(false);
+
+}
+
+void LLNearbyChat::float_panel()
+{
+ mEChatTearofState = CHAT_UNPINNED;
+ LLIconCtrl* tearoff_btn = mChatCaptionPanel->getChild<LLIconCtrl>("tearoff_btn", false);
+
+ tearoff_btn->setValue("inv_item_landmark.tga");
+ mResizeBar[LLResizeBar::BOTTOM]->setVisible(true);
+ mResizeBar[LLResizeBar::LEFT]->setVisible(true);
+ mResizeBar[LLResizeBar::RIGHT]->setVisible(true);
+
+ getDragHandle()->setVisible(true);
+
+ translate(4,4);
+}
+
+void LLNearbyChat::onNearbyChatContextMenuItemClicked(const LLSD& userdata)
+{
+}
+bool LLNearbyChat::onNearbyChatCheckContextMenuItem(const LLSD& userdata)
+{
+ std::string str = userdata.asString();
+ if(str == "nearby_people")
+ onNearbySpeakers();
+ return false;
+}
+
+BOOL LLNearbyChat::handleRightMouseDown(S32 x, S32 y, MASK mask)
+{
+ if(mChatCaptionPanel->pointInView(x - mChatCaptionPanel->getRect().mLeft, y - mChatCaptionPanel->getRect().mBottom) )
+ {
+ LLMenuGL* menu = (LLMenuGL*)mPopupMenuHandle.get();
+
+ if(menu)
+ {
+ menu->buildDrawLabels();
+ menu->updateParent(LLMenuGL::sMenuContainer);
+ LLMenuGL::showPopup(this, menu, x, y);
+ }
+ return true;
+ }
+ return LLFloater::handleRightMouseDown(x, y, mask);
+}
+
+void LLNearbyChat::onOpen(const LLSD& key )
+{
+ LLNotificationsUI::LLScreenChannel* chat_channel = LLNotificationsUI::LLChannelManager::getInstance()->getChannelByID(LLUUID(gSavedSettings.getString("NearByChatChannelUUID")));
+ if(chat_channel)
+ {
+ chat_channel->removeToastsFromChannel();
+ }
+}
diff --git a/indra/newview/llnearbychat.h b/indra/newview/llnearbychat.h
new file mode 100644
index 0000000000..efa2e479e6
--- /dev/null
+++ b/indra/newview/llnearbychat.h
@@ -0,0 +1,97 @@
+/**
+ * @file llnearbychat.h
+ * @brief nearby chat history scrolling panel implementation
+ *
+ * $LicenseInfo:firstyear=2004&license=viewergpl$
+ *
+ * Copyright (c) 2004-2009, Linden Research, Inc.
+ *
+ * Second Life Viewer Source Code
+ * The source code in this file ("Source Code") is provided by Linden Lab
+ * to you under the terms of the GNU General Public License, version 2.0
+ * ("GPL"), unless you have obtained a separate licensing agreement
+ * ("Other License"), formally executed by you and Linden Lab. Terms of
+ * the GPL can be found in doc/GPL-license.txt in this distribution, or
+ * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
+ *
+ * There are special exceptions to the terms and conditions of the GPL as
+ * it is applied to this Source Code. View the full text of the exception
+ * in the file doc/FLOSS-exception.txt in this software distribution, or
+ * online at
+ * http://secondlifegrid.net/programs/open_source/licensing/flossexception
+ *
+ * By copying, modifying or distributing this software, you acknowledge
+ * that you have read and understood your obligations described above,
+ * and agree to abide by those obligations.
+ *
+ * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+ * COMPLETENESS OR PERFORMANCE.
+ * $/LicenseInfo$
+ */
+
+#ifndef LL_LLNEARBYCHAT_H_
+#define LL_LLNEARBYCHAT_H_
+
+#include "llfloater.h"
+#include "llscrollbar.h"
+#include "llchat.h"
+
+class LLResizeBar;
+class LLViewerTextEditor;
+
+class LLNearbyChat: public LLFloater
+{
+public:
+ // enumerations used by the chat system
+ typedef enum e_chat_tearof_state
+ {
+ CHAT_PINNED = 0,
+ CHAT_UNPINNED = 1,
+ } EChatTearofState;
+
+ enum { RESIZE_BAR_COUNT=4 };
+
+ LLNearbyChat(const LLSD& key);
+ ~LLNearbyChat();
+
+ BOOL postBuild ();
+ void reshape (S32 width, S32 height, BOOL called_from_parent = TRUE);
+
+ BOOL handleMouseDown (S32 x, S32 y, MASK mask);
+ BOOL handleMouseUp (S32 x, S32 y, MASK mask);
+ BOOL handleHover (S32 x, S32 y, MASK mask);
+
+ BOOL handleRightMouseDown(S32 x, S32 y, MASK mask);
+
+ void addMessage (const LLChat& message);
+
+ void onNearbySpeakers ();
+ void onTearOff();
+
+ void onNearbyChatContextMenuItemClicked(const LLSD& userdata);
+ bool onNearbyChatCheckContextMenuItem(const LLSD& userdata);
+
+ virtual void onClose (bool app_quitting) { if(app_quitting) destroy(); else setVisible(false); }
+
+ virtual void onOpen (const LLSD& key);
+
+private:
+
+ void pinn_panel();
+ void float_panel();
+
+private:
+ EChatTearofState mEChatTearofState;
+ S32 mStart_X;
+ S32 mStart_Y;
+
+ //LLResizeBar* mResizeBar[RESIZE_BAR_COUNT];
+ LLHandle<LLView> mPopupMenuHandle;
+ LLPanel* mChatCaptionPanel;
+ LLViewerTextEditor* mChatHistoryEditor;
+};
+
+#endif
+
+
diff --git a/indra/newview/llnearbychatbar.cpp b/indra/newview/llnearbychatbar.cpp
new file mode 100644
index 0000000000..d4a9be0355
--- /dev/null
+++ b/indra/newview/llnearbychatbar.cpp
@@ -0,0 +1,639 @@
+/**
+ * @file llnearbychatbar.cpp
+ * @brief LLNearbyChatBar class implementation
+ *
+ * $LicenseInfo:firstyear=2002&license=viewergpl$
+ *
+ * Copyright (c) 2002-2009, Linden Research, Inc.
+ *
+ * Second Life Viewer Source Code
+ * The source code in this file ("Source Code") is provided by Linden Lab
+ * to you under the terms of the GNU General Public License, version 2.0
+ * ("GPL"), unless you have obtained a separate licensing agreement
+ * ("Other License"), formally executed by you and Linden Lab. Terms of
+ * the GPL can be found in doc/GPL-license.txt in this distribution, or
+ * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
+ *
+ * There are special exceptions to the terms and conditions of the GPL as
+ * it is applied to this Source Code. View the full text of the exception
+ * in the file doc/FLOSS-exception.txt in this software distribution, or
+ * online at
+ * http://secondlifegrid.net/programs/open_source/licensing/flossexception
+ *
+ * By copying, modifying or distributing this software, you acknowledge
+ * that you have read and understood your obligations described above,
+ * and agree to abide by those obligations.
+ *
+ * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+ * COMPLETENESS OR PERFORMANCE.
+ * $/LicenseInfo$
+ */
+
+#include "llviewerprecompiledheaders.h"
+
+#include "llnearbychatbar.h"
+#include "llbottomtray.h"
+#include "llagent.h"
+#include "llgesturemgr.h"
+#include "llmultigesture.h"
+#include "llkeyboard.h"
+#include "llanimationstates.h"
+#include "llviewerstats.h"
+#include "llcommandhandler.h"
+#include "llviewercontrol.h"
+
+S32 LLNearbyChatBar::sLastSpecialChatChannel = 0;
+
+// legacy calllback glue
+void send_chat_from_viewer(const std::string& utf8_out_text, EChatType type, S32 channel);
+
+static LLDefaultChildRegistry::Register<LLGestureComboBox> r("gesture_combo_box");
+
+struct LLChatTypeTrigger {
+ std::string name;
+ EChatType type;
+};
+
+static LLChatTypeTrigger sChatTypeTriggers[] = {
+ { "/whisper" , CHAT_TYPE_WHISPER},
+ { "/shout" , CHAT_TYPE_SHOUT}
+};
+
+LLGestureComboBox::LLGestureComboBox(const LLGestureComboBox::Params& p)
+ : LLComboBox(p)
+ , mGestureLabelTimer()
+ , mLabel(p.label)
+{
+ setCommitCallback(boost::bind(&LLGestureComboBox::onCommitGesture, this));
+
+ // now register us as observer since we have a place to put the results
+ LLGestureManager::instance().addObserver(this);
+
+ // refresh list from current active gestures
+ refreshGestures();
+}
+
+LLGestureComboBox::~LLGestureComboBox()
+{
+ LLGestureManager::instance().removeObserver(this);
+}
+
+void LLGestureComboBox::refreshGestures()
+{
+ //store current selection so we can maintain it
+ LLSD cur_gesture = getValue();
+ selectFirstItem();
+ // clear
+ clearRows();
+ mGestures.clear();
+
+ LLGestureManager::item_map_t::iterator it;
+ LLSD::Integer idx(0);
+ for (it = LLGestureManager::instance().mActive.begin(); it != LLGestureManager::instance().mActive.end(); ++it)
+ {
+ LLMultiGesture* gesture = (*it).second;
+ if (gesture)
+ {
+ addSimpleElement(gesture->mName, ADD_BOTTOM, LLSD(idx));
+ mGestures.push_back(gesture);
+ idx++;
+ }
+ }
+
+ sortByName();
+ // Insert label after sorting, at top, with separator below it
+ addSeparator(ADD_TOP);
+ addSimpleElement(mLabel, ADD_TOP);
+
+ if (cur_gesture.isDefined())
+ {
+ selectByValue(cur_gesture);
+ }
+ else
+ {
+ selectFirstItem();
+ }
+}
+
+void LLGestureComboBox::onCommitGesture()
+{
+ LLCtrlListInterface* gestures = getListInterface();
+ if (gestures)
+ {
+ S32 index = gestures->getFirstSelectedIndex();
+ if (index == 0)
+ {
+ return;
+ }
+
+ index = gestures->getSelectedValue().asInteger();
+ LLMultiGesture* gesture = mGestures.at(index);
+ if(gesture)
+ {
+ LLGestureManager::instance().playGesture(gesture);
+ if(!gesture->mReplaceText.empty())
+ {
+ LLNearbyChatBar::sendChatFromViewer(gesture->mReplaceText, CHAT_TYPE_NORMAL, FALSE);
+ }
+ }
+ }
+
+ mGestureLabelTimer.start();
+ // free focus back to chat bar
+ setFocus(FALSE);
+}
+
+//virtual
+void LLGestureComboBox::draw()
+{
+ // HACK: Leave the name of the gesture in place for a few seconds.
+ const F32 SHOW_GESTURE_NAME_TIME = 2.f;
+ if (mGestureLabelTimer.getStarted() && mGestureLabelTimer.getElapsedTimeF32() > SHOW_GESTURE_NAME_TIME)
+ {
+ LLCtrlListInterface* gestures = getListInterface();
+ if (gestures) gestures->selectFirstItem();
+ mGestureLabelTimer.stop();
+ }
+
+ LLComboBox::draw();
+}
+
+LLNearbyChatBar::LLNearbyChatBar()
+ : LLPanel()
+ , mChatBox(NULL)
+{
+}
+
+//virtual
+BOOL LLNearbyChatBar::postBuild()
+{
+ mChatBox = getChild<LLLineEditor>("chat_box");
+
+ mChatBox->setCommitCallback(boost::bind(&LLNearbyChatBar::onChatBoxCommit, this));
+ mChatBox->setKeystrokeCallback(&onChatBoxKeystroke, this);
+ mChatBox->setFocusLostCallback(&onChatBoxFocusLost, this);
+
+ mChatBox->setIgnoreArrowKeys(TRUE);
+ mChatBox->setCommitOnFocusLost( FALSE );
+ mChatBox->setRevertOnEsc( FALSE );
+ mChatBox->setIgnoreTab(TRUE);
+ mChatBox->setPassDelete(TRUE);
+ mChatBox->setReplaceNewlinesWithSpaces(FALSE);
+ mChatBox->setMaxTextLength(1023);
+ mChatBox->setEnableLineHistory(TRUE);
+
+ mTalkBtn = getChild<LLTalkButton>("talk");
+
+ // Speak button should be initially disabled because
+ // it takes some time between logging in to world and connecting to voice channel.
+ mTalkBtn->setEnabled(FALSE);
+
+ // Registering Chat Bar to receive Voice client status change notifications.
+ gVoiceClient->addObserver(this);
+
+ return TRUE;
+}
+
+//static
+LLNearbyChatBar* LLNearbyChatBar::getInstance()
+{
+ return LLBottomTray::getInstance() ? LLBottomTray::getInstance()->getNearbyChatBar() : NULL;
+}
+
+//static
+bool LLNearbyChatBar::instanceExists()
+{
+ return LLBottomTray::instanceExists() && LLBottomTray::getInstance()->getNearbyChatBar() != NULL;
+}
+
+std::string LLNearbyChatBar::getCurrentChat()
+{
+ return mChatBox ? mChatBox->getText() : LLStringUtil::null;
+}
+
+// virtual
+BOOL LLNearbyChatBar::handleKeyHere( KEY key, MASK mask )
+{
+ BOOL handled = FALSE;
+
+ // ALT-RETURN is reserved for windowed/fullscreen toggle
+ if( KEY_RETURN == key && mask == MASK_CONTROL)
+ {
+ // shout
+ sendChat(CHAT_TYPE_SHOUT);
+ handled = TRUE;
+ }
+
+ return handled;
+}
+
+BOOL LLNearbyChatBar::matchChatTypeTrigger(const std::string& in_str, std::string* out_str)
+{
+ U32 in_len = in_str.length();
+ S32 cnt = sizeof(sChatTypeTriggers) / sizeof(*sChatTypeTriggers);
+
+ for (S32 n = 0; n < cnt; n++)
+ {
+ if (in_len > sChatTypeTriggers[n].name.length())
+ continue;
+
+ std::string trigger_trunc = sChatTypeTriggers[n].name;
+ LLStringUtil::truncate(trigger_trunc, in_len);
+
+ if (!LLStringUtil::compareInsensitive(in_str, trigger_trunc))
+ {
+ *out_str = sChatTypeTriggers[n].name;
+ return TRUE;
+ }
+ }
+
+ return FALSE;
+}
+
+void LLNearbyChatBar::onChatBoxKeystroke(LLLineEditor* caller, void* userdata)
+{
+
+ LLNearbyChatBar* self = (LLNearbyChatBar *)userdata;
+
+ LLWString raw_text = self->mChatBox->getWText();
+
+ // Can't trim the end, because that will cause autocompletion
+ // to eat trailing spaces that might be part of a gesture.
+ LLWStringUtil::trimHead(raw_text);
+
+ S32 length = raw_text.length();
+
+ if( (length > 0) && (raw_text[0] != '/') ) // forward slash is used for escape (eg. emote) sequences
+ {
+ gAgent.startTyping();
+ }
+ else
+ {
+ gAgent.stopTyping();
+ }
+
+ /* Doesn't work -- can't tell the difference between a backspace
+ that killed the selection vs. backspace at the end of line.
+ if (length > 1
+ && text[0] == '/'
+ && key == KEY_BACKSPACE)
+ {
+ // the selection will already be deleted, but we need to trim
+ // off the character before
+ std::string new_text = raw_text.substr(0, length-1);
+ self->mInputEditor->setText( new_text );
+ self->mInputEditor->setCursorToEnd();
+ length = length - 1;
+ }
+ */
+
+ KEY key = gKeyboard->currentKey();
+
+ // Ignore "special" keys, like backspace, arrows, etc.
+ if (length > 1
+ && raw_text[0] == '/'
+ && key < KEY_SPECIAL)
+ {
+ // we're starting a gesture, attempt to autocomplete
+
+ std::string utf8_trigger = wstring_to_utf8str(raw_text);
+ std::string utf8_out_str(utf8_trigger);
+
+ if (LLGestureManager::instance().matchPrefix(utf8_trigger, &utf8_out_str))
+ {
+ std::string rest_of_match = utf8_out_str.substr(utf8_trigger.size());
+ self->mChatBox->setText(utf8_trigger + rest_of_match); // keep original capitalization for user-entered part
+ S32 outlength = self->mChatBox->getLength(); // in characters
+
+ // Select to end of line, starting from the character
+ // after the last one the user typed.
+ self->mChatBox->setSelection(length, outlength);
+ }
+ else if (matchChatTypeTrigger(utf8_trigger, &utf8_out_str))
+ {
+ std::string rest_of_match = utf8_out_str.substr(utf8_trigger.size());
+ self->mChatBox->setText(utf8_trigger + rest_of_match + " "); // keep original capitalization for user-entered part
+ self->mChatBox->setCursorToEnd();
+ }
+
+ //llinfos << "GESTUREDEBUG " << trigger
+ // << " len " << length
+ // << " outlen " << out_str.getLength()
+ // << llendl;
+ }
+}
+
+// static
+void LLNearbyChatBar::onChatBoxFocusLost(LLFocusableElement* caller, void* userdata)
+{
+ // stop typing animation
+ gAgent.stopTyping();
+}
+
+EChatType LLNearbyChatBar::processChatTypeTriggers(EChatType type, std::string &str)
+{
+ U32 length = str.length();
+ S32 cnt = sizeof(sChatTypeTriggers) / sizeof(*sChatTypeTriggers);
+
+ for (S32 n = 0; n < cnt; n++)
+ {
+ if (length >= sChatTypeTriggers[n].name.length())
+ {
+ std::string trigger = str.substr(0, sChatTypeTriggers[n].name.length());
+
+ if (!LLStringUtil::compareInsensitive(trigger, sChatTypeTriggers[n].name))
+ {
+ U32 trigger_length = sChatTypeTriggers[n].name.length();
+
+ // It's to remove space after trigger name
+ if (length > trigger_length && str[trigger_length] == ' ')
+ trigger_length++;
+
+ str = str.substr(trigger_length, length);
+
+ if (CHAT_TYPE_NORMAL == type)
+ return sChatTypeTriggers[n].type;
+ else
+ break;
+ }
+ }
+ }
+
+ return type;
+}
+
+void LLNearbyChatBar::sendChat( EChatType type )
+{
+ if (mChatBox)
+ {
+ LLWString text = mChatBox->getConvertedText();
+ if (!text.empty())
+ {
+ // store sent line in history, duplicates will get filtered
+ mChatBox->updateHistory();
+ // Check if this is destined for another channel
+ S32 channel = 0;
+ stripChannelNumber(text, &channel);
+
+ std::string utf8text = wstring_to_utf8str(text);
+ // Try to trigger a gesture, if not chat to a script.
+ std::string utf8_revised_text;
+ if (0 == channel)
+ {
+ // discard returned "found" boolean
+ LLGestureManager::instance().triggerAndReviseString(utf8text, &utf8_revised_text);
+ }
+ else
+ {
+ utf8_revised_text = utf8text;
+ }
+
+ utf8_revised_text = utf8str_trim(utf8_revised_text);
+
+ type = processChatTypeTriggers(type, utf8_revised_text);
+
+ if (!utf8_revised_text.empty())
+ {
+ // Chat with animation
+ sendChatFromViewer(utf8_revised_text, type, TRUE);
+ }
+ }
+
+ mChatBox->setText(LLStringExplicit(""));
+ }
+
+ gAgent.stopTyping();
+
+ // If the user wants to stop chatting on hitting return, lose focus
+ // and go out of chat mode.
+ if (gSavedSettings.getBOOL("CloseChatOnReturn"))
+ {
+ stopChat();
+ }
+}
+
+void LLNearbyChatBar::onChatBoxCommit()
+{
+ if (mChatBox->getText().length() > 0)
+ {
+ sendChat(CHAT_TYPE_NORMAL);
+ }
+
+ gAgent.stopTyping();
+}
+
+void LLNearbyChatBar::sendChatFromViewer(const std::string &utf8text, EChatType type, BOOL animate)
+{
+ sendChatFromViewer(utf8str_to_wstring(utf8text), type, animate);
+}
+
+void LLNearbyChatBar::sendChatFromViewer(const LLWString &wtext, EChatType type, BOOL animate)
+{
+ // Look for "/20 foo" channel chats.
+ S32 channel = 0;
+ LLWString out_text = stripChannelNumber(wtext, &channel);
+ std::string utf8_out_text = wstring_to_utf8str(out_text);
+ std::string utf8_text = wstring_to_utf8str(wtext);
+
+ utf8_text = utf8str_trim(utf8_text);
+ if (!utf8_text.empty())
+ {
+ utf8_text = utf8str_truncate(utf8_text, MAX_STRING - 1);
+ }
+
+ // Don't animate for chats people can't hear (chat to scripts)
+ if (animate && (channel == 0))
+ {
+ if (type == CHAT_TYPE_WHISPER)
+ {
+ lldebugs << "You whisper " << utf8_text << llendl;
+ gAgent.sendAnimationRequest(ANIM_AGENT_WHISPER, ANIM_REQUEST_START);
+ }
+ else if (type == CHAT_TYPE_NORMAL)
+ {
+ lldebugs << "You say " << utf8_text << llendl;
+ gAgent.sendAnimationRequest(ANIM_AGENT_TALK, ANIM_REQUEST_START);
+ }
+ else if (type == CHAT_TYPE_SHOUT)
+ {
+ lldebugs << "You shout " << utf8_text << llendl;
+ gAgent.sendAnimationRequest(ANIM_AGENT_SHOUT, ANIM_REQUEST_START);
+ }
+ else
+ {
+ llinfos << "send_chat_from_viewer() - invalid volume" << llendl;
+ return;
+ }
+ }
+ else
+ {
+ if (type != CHAT_TYPE_START && type != CHAT_TYPE_STOP)
+ {
+ lldebugs << "Channel chat: " << utf8_text << llendl;
+ }
+ }
+
+ send_chat_from_viewer(utf8_out_text, type, channel);
+}
+
+// static
+void LLNearbyChatBar::startChat(const char* line)
+{
+ LLBottomTray *bt = LLBottomTray::getInstance();
+
+ if (!bt)
+ return;
+
+ LLNearbyChatBar* cb = bt->getNearbyChatBar();
+
+ if (!cb )
+ return;
+
+ bt->setVisible(TRUE);
+ cb->mChatBox->setFocus(TRUE);
+
+ if (line)
+ {
+ std::string line_string(line);
+ cb->mChatBox->setText(line_string);
+ }
+
+ cb->mChatBox->setCursorToEnd();
+}
+
+// Exit "chat mode" and do the appropriate focus changes
+// static
+void LLNearbyChatBar::stopChat()
+{
+ LLBottomTray *bt = LLBottomTray::getInstance();
+
+ if (!bt)
+ return;
+
+ LLNearbyChatBar* cb = bt->getNearbyChatBar();
+
+ if (!cb)
+ return;
+
+ cb->mChatBox->setFocus(FALSE);
+
+ // stop typing animation
+ gAgent.stopTyping();
+}
+
+// If input of the form "/20foo" or "/20 foo", returns "foo" and channel 20.
+// Otherwise returns input and channel 0.
+LLWString LLNearbyChatBar::stripChannelNumber(const LLWString &mesg, S32* channel)
+{
+ if (mesg[0] == '/'
+ && mesg[1] == '/')
+ {
+ // This is a "repeat channel send"
+ *channel = sLastSpecialChatChannel;
+ return mesg.substr(2, mesg.length() - 2);
+ }
+ else if (mesg[0] == '/'
+ && mesg[1]
+ && LLStringOps::isDigit(mesg[1]))
+ {
+ // This a special "/20" speak on a channel
+ S32 pos = 0;
+
+ // Copy the channel number into a string
+ LLWString channel_string;
+ llwchar c;
+ do
+ {
+ c = mesg[pos+1];
+ channel_string.push_back(c);
+ pos++;
+ }
+ while(c && pos < 64 && LLStringOps::isDigit(c));
+
+ // Move the pointer forward to the first non-whitespace char
+ // Check isspace before looping, so we can handle "/33foo"
+ // as well as "/33 foo"
+ while(c && iswspace(c))
+ {
+ c = mesg[pos+1];
+ pos++;
+ }
+
+ sLastSpecialChatChannel = strtol(wstring_to_utf8str(channel_string).c_str(), NULL, 10);
+ *channel = sLastSpecialChatChannel;
+ return mesg.substr(pos, mesg.length() - pos);
+ }
+ else
+ {
+ // This is normal chat.
+ *channel = 0;
+ return mesg;
+ }
+}
+
+void LLNearbyChatBar::setPTTState(bool state)
+{
+ mTalkBtn->setSpeakBtnToggleState(state);
+}
+
+void send_chat_from_viewer(const std::string& utf8_out_text, EChatType type, S32 channel)
+{
+ LLMessageSystem* msg = gMessageSystem;
+ msg->newMessageFast(_PREHASH_ChatFromViewer);
+ msg->nextBlockFast(_PREHASH_AgentData);
+ msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
+ msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
+ msg->nextBlockFast(_PREHASH_ChatData);
+ msg->addStringFast(_PREHASH_Message, utf8_out_text);
+ msg->addU8Fast(_PREHASH_Type, type);
+ msg->addS32("Channel", channel);
+
+ gAgent.sendReliableMessage();
+
+ LLViewerStats::getInstance()->incStat(LLViewerStats::ST_CHAT_COUNT);
+}
+
+class LLChatHandler : public LLCommandHandler
+{
+public:
+ // not allowed from outside the app
+ LLChatHandler() : LLCommandHandler("chat", true) { }
+
+ // Your code here
+ bool handle(const LLSD& tokens, const LLSD& query_map,
+ LLMediaCtrl* web)
+ {
+ if (tokens.size() < 2) return false;
+ S32 channel = tokens[0].asInteger();
+ std::string mesg = tokens[1].asString();
+ send_chat_from_viewer(mesg, CHAT_TYPE_NORMAL, channel);
+ return true;
+ }
+};
+
+void LLNearbyChatBar::onChange(EStatusType status, const std::string &channelURI, bool proximal)
+{
+ // Time it takes to connect to voice channel might be pretty long,
+ // so don't expect user login or STATUS_VOICE_ENABLED to be followed by STATUS_JOINED.
+ BOOL enable = FALSE;
+
+ switch (status)
+ {
+ // Do not add STATUS_VOICE_ENABLED because voice chat is
+ // inactive until STATUS_JOINED
+ case STATUS_JOINED:
+ enable = TRUE;
+ break;
+ default:
+ enable = FALSE;
+ break;
+ }
+
+ mTalkBtn->setEnabled(enable);
+}
+
+// Creating the object registers with the dispatcher.
+LLChatHandler gChatHandler;
+
+
diff --git a/indra/newview/llnearbychatbar.h b/indra/newview/llnearbychatbar.h
new file mode 100644
index 0000000000..19177e37b3
--- /dev/null
+++ b/indra/newview/llnearbychatbar.h
@@ -0,0 +1,118 @@
+/**
+ * @file llnearbychatbar.h
+ * @brief LLNearbyChatBar class definition
+ *
+ * $LicenseInfo:firstyear=2002&license=viewergpl$
+ *
+ * Copyright (c) 2002-2009, Linden Research, Inc.
+ *
+ * Second Life Viewer Source Code
+ * The source code in this file ("Source Code") is provided by Linden Lab
+ * to you under the terms of the GNU General Public License, version 2.0
+ * ("GPL"), unless you have obtained a separate licensing agreement
+ * ("Other License"), formally executed by you and Linden Lab. Terms of
+ * the GPL can be found in doc/GPL-license.txt in this distribution, or
+ * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
+ *
+ * There are special exceptions to the terms and conditions of the GPL as
+ * it is applied to this Source Code. View the full text of the exception
+ * in the file doc/FLOSS-exception.txt in this software distribution, or
+ * online at
+ * http://secondlifegrid.net/programs/open_source/licensing/flossexception
+ *
+ * By copying, modifying or distributing this software, you acknowledge
+ * that you have read and understood your obligations described above,
+ * and agree to abide by those obligations.
+ *
+ * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+ * COMPLETENESS OR PERFORMANCE.
+ * $/LicenseInfo$
+ */
+
+#ifndef LL_LLNEARBYCHATBAR_H
+#define LL_LLNEARBYCHATBAR_H
+
+#include "llpanel.h"
+#include "llcombobox.h"
+#include "llgesturemgr.h"
+#include "llchat.h"
+#include "llchiclet.h"
+#include "llvoiceclient.h"
+
+class LLGestureComboBox
+ : public LLComboBox
+ , public LLGestureManagerObserver
+{
+public:
+ struct Params : public LLInitParam::Block<Params, LLComboBox::Params> { };
+protected:
+ LLGestureComboBox(const Params&);
+ friend class LLUICtrlFactory;
+public:
+ ~LLGestureComboBox();
+
+ void refreshGestures();
+ void onCommitGesture();
+ virtual void draw();
+
+ // LLGestureManagerObserver trigger
+ virtual void changed() { refreshGestures(); }
+
+protected:
+ LLFrameTimer mGestureLabelTimer;
+ std::vector<LLMultiGesture*> mGestures;
+ std::string mLabel;
+};
+
+class LLNearbyChatBar
+: public LLPanel
+, public LLVoiceClientStatusObserver
+{
+public:
+ // constructor for inline chat-bars (e.g. hosted in chat history window)
+ LLNearbyChatBar();
+ ~LLNearbyChatBar() {}
+
+ virtual BOOL postBuild();
+
+ static LLNearbyChatBar* getInstance();
+
+ static bool instanceExists();
+
+ LLLineEditor* getChatBox() { return mChatBox; }
+
+ std::string getCurrentChat();
+ virtual BOOL handleKeyHere( KEY key, MASK mask );
+
+ void setPTTState(bool state);
+ static void startChat(const char* line);
+ static void stopChat();
+
+ static void sendChatFromViewer(const std::string &utf8text, EChatType type, BOOL animate);
+ static void sendChatFromViewer(const LLWString &wtext, EChatType type, BOOL animate);
+
+ /**
+ * Implements LLVoiceClientStatusObserver::onChange()
+ */
+ /*virtual*/ void onChange(EStatusType status, const std::string &channelURI, bool proximal);
+
+protected:
+ static BOOL matchChatTypeTrigger(const std::string& in_str, std::string* out_str);
+ static void onChatBoxKeystroke(LLLineEditor* caller, void* userdata);
+ static void onChatBoxFocusLost(LLFocusableElement* caller, void* userdata);
+
+ void sendChat( EChatType type );
+ void onChatBoxCommit();
+
+ static LLWString stripChannelNumber(const LLWString &mesg, S32* channel);
+ EChatType processChatTypeTriggers(EChatType type, std::string &str);
+
+ // Which non-zero channel did we last chat on?
+ static S32 sLastSpecialChatChannel;
+
+ LLLineEditor* mChatBox;
+ LLTalkButton* mTalkBtn;
+};
+
+#endif
diff --git a/indra/newview/llnearbychathandler.cpp b/indra/newview/llnearbychathandler.cpp
new file mode 100644
index 0000000000..a1912655a3
--- /dev/null
+++ b/indra/newview/llnearbychathandler.cpp
@@ -0,0 +1,129 @@
+/**
+ * @file LLNearbyChatHandler.cpp
+ * @brief Nearby chat notification managment
+ *
+ * $LicenseInfo:firstyear=2009&license=viewergpl$
+ *
+ * Copyright (c) 2009, Linden Research, Inc.
+ *
+ * Second Life Viewer Source Code
+ * The source code in this file ("Source Code") is provided by Linden Lab
+ * to you under the terms of the GNU General Public License, version 2.0
+ * ("GPL"), unless you have obtained a separate licensing agreement
+ * ("Other License"), formally executed by you and Linden Lab. Terms of
+ * the GPL can be found in doc/GPL-license.txt in this distribution, or
+ * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
+ *
+ * There are special exceptions to the terms and conditions of the GPL as
+ * it is applied to this Source Code. View the full text of the exception
+ * in the file doc/FLOSS-exception.txt in this software distribution, or
+ * online at
+ * http://secondlifegrid.net/programs/open_source/licensing/flossexception
+ *
+ * By copying, modifying or distributing this software, you acknowledge
+ * that you have read and understood your obligations described above,
+ * and agree to abide by those obligations.
+ *
+ * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+ * COMPLETENESS OR PERFORMANCE.
+ * $/LicenseInfo$
+ */
+
+#include "llviewerprecompiledheaders.h"
+
+#include "llnearbychathandler.h"
+
+#include "llchatitemscontainerctrl.h"
+#include "llnearbychat.h"
+#include "llrecentpeople.h"
+
+#include "llviewercontrol.h"
+
+#include "llfloaterreg.h"//for LLFloaterReg::getTypedInstance
+
+//add LLNearbyChatHandler to LLNotificationsUI namespace
+namespace LLNotificationsUI{
+
+
+LLNearbyChatHandler::LLNearbyChatHandler(e_notification_type type, const LLSD& id)
+{
+ mType = type;
+ LLNearbyChat* nearby_chat = LLFloaterReg::getTypedInstance<LLNearbyChat>("nearby_chat", LLSD());
+ /////////////////////////////////////////////////////
+ LLChannelManager::Params p; //TODO: check and correct
+ p.id = LLUUID(gSavedSettings.getString("NearByChatChannelUUID"));
+ p.channel_right_bound = nearby_chat->getRect().mRight;
+ p.channel_width = nearby_chat->getRect().mRight - 16; //HACK: 16 - ?
+ /////////////////////////////////////////////////////
+
+
+ // Getting a Channel for our notifications
+ mChannel = LLChannelManager::getInstance()->createChannel(p);
+ mChannel->setFollows(FOLLOWS_LEFT | FOLLOWS_BOTTOM | FOLLOWS_TOP);
+ mChannel->setOverflowFormatString("You have %d unread nearby chat messages");
+}
+LLNearbyChatHandler::~LLNearbyChatHandler()
+{
+}
+void LLNearbyChatHandler::processChat(const LLChat& chat_msg)
+{
+ if(chat_msg.mMuted == TRUE)
+ return;
+ if(chat_msg.mSourceType == CHAT_SOURCE_AGENT && chat_msg.mFromID.notNull())
+ LLRecentPeople::instance().add(chat_msg.mFromID);
+
+ if(chat_msg.mText.empty())
+ return;//don't process empty messages
+
+ LLNearbyChat* nearby_chat = LLFloaterReg::getTypedInstance<LLNearbyChat>("nearby_chat", LLSD());
+ nearby_chat->addMessage(chat_msg);
+ if(nearby_chat->getVisible())
+ return;//no need in toast if chat is visible
+
+ LLUUID id;
+ id.generate();
+
+ LLChatItemCtrl* item = LLChatItemCtrl::createInstance();
+
+ item->setMessage(chat_msg);
+ //static S32 chat_item_width = nearby_chat->getRect().getWidth() - 16;
+ static S32 chat_item_width = 304;
+ item->setWidth(chat_item_width);
+ item->setHeaderVisibility((EShowItemHeader)gSavedSettings.getS32("nearbychat_showicons_and_names"));
+
+ item->setVisible(true);
+
+ LLToast::Params p;
+ p.id = id;
+ p.panel = item;
+ p.on_toast_destroy = boost::bind(&LLNearbyChatHandler::onToastDestroy, this, _1);
+ p.on_mouse_enter = boost::bind(&LLNearbyChatHandler::removeNearbyToastsAndShowChat, this);
+ mChannel->addToast(p);
+}
+
+void LLNearbyChatHandler::onToastDestroy(LLToast* toast)
+{
+ if(toast)
+ toast->closeFloater();
+}
+
+void LLNearbyChatHandler::onChicletClick(void)
+{
+}
+void LLNearbyChatHandler::onChicletClose(void)
+{
+}
+
+void LLNearbyChatHandler::removeNearbyToastsAndShowChat()
+{
+ /*
+ if(mChannel)
+ mChannel->removeToastsFromChannel();
+
+ LLFloaterReg::showTypedInstance<LLNearbyChat>("nearby_chat", LLSD());
+ */
+}
+
+}
+
diff --git a/indra/newview/llnearbychathandler.h b/indra/newview/llnearbychathandler.h
new file mode 100644
index 0000000000..8fcd03689d
--- /dev/null
+++ b/indra/newview/llnearbychathandler.h
@@ -0,0 +1,59 @@
+/**
+ * @file llnearbychathandler.h
+ * @brief nearby chat notify
+ *
+ * $LicenseInfo:firstyear=2004&license=viewergpl$
+ *
+ * Copyright (c) 2004-2009, Linden Research, Inc.
+ *
+ * Second Life Viewer Source Code
+ * The source code in this file ("Source Code") is provided by Linden Lab
+ * to you under the terms of the GNU General Public License, version 2.0
+ * ("GPL"), unless you have obtained a separate licensing agreement
+ * ("Other License"), formally executed by you and Linden Lab. Terms of
+ * the GPL can be found in doc/GPL-license.txt in this distribution, or
+ * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
+ *
+ * There are special exceptions to the terms and conditions of the GPL as
+ * it is applied to this Source Code. View the full text of the exception
+ * in the file doc/FLOSS-exception.txt in this software distribution, or
+ * online at
+ * http://secondlifegrid.net/programs/open_source/licensing/flossexception
+ *
+ * By copying, modifying or distributing this software, you acknowledge
+ * that you have read and understood your obligations described above,
+ * and agree to abide by those obligations.
+ *
+ * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+ * COMPLETENESS OR PERFORMANCE.
+ * $/LicenseInfo$
+ */
+
+#ifndef LL_LLNEARBYCHATHANDLER_H
+#define LL_LLNEARBYCHATHANDLER_H
+
+#include "llnotificationhandler.h"
+
+//add LLNearbyChatHandler to LLNotificationsUI namespace
+namespace LLNotificationsUI{
+
+class LLNearbyChatHandler : public LLChatHandler
+{
+public:
+ LLNearbyChatHandler(e_notification_type type,const LLSD& id);
+ virtual ~LLNearbyChatHandler();
+
+
+ virtual void processChat(const LLChat& chat_msg);
+ virtual void onToastDestroy(LLToast* toast);
+ virtual void onChicletClick(void);
+ virtual void onChicletClose(void);
+
+protected:
+ void removeNearbyToastsAndShowChat();
+};
+
+}
+
+#endif /* LL_LLNEARBYCHATHANDLER_H */
diff --git a/indra/newview/llnetmap.cpp b/indra/newview/llnetmap.cpp
index 23d32fee81..7b0b0c2fb7 100644
--- a/indra/newview/llnetmap.cpp
+++ b/indra/newview/llnetmap.cpp
@@ -1,7 +1,7 @@
/**
* @file llnetmap.cpp
* @author James Cook
- * @brief Display of surrounding regions, objects, and agents. View contained by LLFloaterMap.
+ * @brief Display of surrounding regions, objects, and agents.
*
* $LicenseInfo:firstyear=2001&license=viewergpl$
*
@@ -36,83 +36,46 @@
#include "llnetmap.h"
#include "indra_constants.h"
-#include "llui.h"
-#include "llmath.h" // clampf()
+#include "llmath.h"
+#include "llfloaterreg.h"
#include "llfocusmgr.h"
#include "llrender.h"
+#include "llui.h"
+
+#include "llglheaders.h"
#include "llagent.h"
-#include "llcallingcard.h"
-#include "llcolorscheme.h"
-#include "llviewercontrol.h"
-#include "llfloateravatarinfo.h"
-#include "llfloaterworldmap.h"
-#include "llframetimer.h"
+#include "llappviewer.h" // for gDisconnected
+#include "llcallingcard.h" // LLAvatarTracker
#include "lltracker.h"
-#include "llmenugl.h"
#include "llsurface.h"
-#include "lltextbox.h"
-#include "lluictrlfactory.h"
-#include "lluuid.h"
#include "llviewercamera.h"
-#include "llviewerimage.h"
-#include "llviewerimagelist.h"
+#include "llviewercontrol.h"
+#include "llviewertexture.h"
+#include "llviewertexturelist.h"
#include "llviewermenu.h"
#include "llviewerobjectlist.h"
#include "llviewerregion.h"
-#include "llviewerwindow.h"
-#include "llvoavatar.h"
#include "llworld.h"
#include "llworldmapview.h" // shared draw code
-#include "llappviewer.h" // Only for constants!
-
-#include "llglheaders.h"
-using namespace LLOldEvents;
+static LLDefaultChildRegistry::Register<LLNetMap> r1("net_map");
const F32 MAP_SCALE_MIN = 64;
const F32 MAP_SCALE_MID = 172;
const F32 MAP_SCALE_MAX = 512;
const F32 MAP_SCALE_INCREMENT = 16;
const F32 MAP_MIN_PICK_DIST = 4;
-const F32 MAP_MINOR_DIR_THRESHOLD = 0.08f;
-
-const S32 TRACKING_RADIUS = 3;
-
-LLNetMap::LLNetMap(const std::string& name) :
- LLPanel(name),
- mScale(128.f),
- mObjectMapTPM(1.f),
- mObjectMapPixels(255.f),
- mTargetPanX( 0.f ),
- mTargetPanY( 0.f ),
- mCurPanX( 0.f ),
- mCurPanY( 0.f ),
- mUpdateNow( FALSE )
-{
- mScale = gSavedSettings.getF32("MiniMapScale");
- mPixelsPerMeter = mScale / LLWorld::getInstance()->getRegionWidthInMeters();
+const F32 MAX_PRIM_RADIUS = 256.0f; // Don't try to draw giant mega-prims on the mini map
+LLNetMap::LLNetMap (const Params & p) :
+ LLUICtrl (p),
+ mScale(128.0f),
+ mBackgroundColor (p.bg_color()),
+ mRotateMap(FALSE)
+{
mObjectImageCenterGlobal = gAgent.getCameraPositionGlobal();
-
- // Register event listeners for popup menu
- (new LLScaleMap())->registerListener(this, "MiniMap.ZoomLevel");
- (new LLStopTracking())->registerListener(this, "MiniMap.StopTracking");
- (new LLEnableTracking())->registerListener(this, "MiniMap.EnableTracking");
- (new LLShowAgentProfile())->registerListener(this, "MiniMap.ShowProfile");
- (new LLEnableProfile())->registerListener(this, "MiniMap.EnableProfile");
-
- LLUICtrlFactory::getInstance()->buildPanel(this, "panel_mini_map.xml");
-
- updateMinorDirections();
-
- LLMenuGL* menu = LLUICtrlFactory::getInstance()->buildMenu("menu_mini_map.xml", this);
- if (!menu)
- {
- menu = new LLMenuGL(LLStringUtil::null);
- }
- menu->setVisible(FALSE);
- mPopupMenuHandle = menu->getHandle();
+ mPixelsPerMeter = mScale / REGION_WIDTH_METERS;
}
LLNetMap::~LLNetMap()
@@ -121,26 +84,21 @@ LLNetMap::~LLNetMap()
void LLNetMap::setScale( F32 scale )
{
- mScale = scale;
- if (mScale == 0.f)
- {
- mScale = 0.1f;
- }
- gSavedSettings.setF32("MiniMapScale", mScale);
-
+ mScale = llclamp(scale, 0.1f, 16.f*1024.f); // [reasonably small , unreasonably large]
+
if (mObjectImagep.notNull())
{
- F32 width = (F32)(getRect().getWidth());
- F32 height = (F32)(getRect().getHeight());
- F32 diameter = sqrt(width * width + height * height);
- F32 region_widths = diameter / mScale;
+ F32 half_width = (F32)(getRect().getWidth() / 2);
+ F32 half_height = (F32)(getRect().getHeight() / 2);
+ F32 radius = sqrt( half_width * half_width + half_height * half_height );
+ F32 region_widths = (2.f*radius)/mScale;
F32 meters = region_widths * LLWorld::getInstance()->getRegionWidthInMeters();
F32 num_pixels = (F32)mObjectImagep->getWidth();
- mObjectMapTPM = num_pixels / meters;
- mObjectMapPixels = diameter;
+ mObjectMapTPM = num_pixels/meters;
+ mObjectMapPixels = 2.f*radius;
}
- mPixelsPerMeter = mScale / LLWorld::getInstance()->getRegionWidthInMeters();
+ mPixelsPerMeter = mScale / REGION_WIDTH_METERS;
mUpdateNow = TRUE;
}
@@ -157,21 +115,27 @@ void LLNetMap::translatePan( F32 delta_x, F32 delta_y )
void LLNetMap::draw()
{
static LLFrameTimer map_timer;
-
+ static LLUIColor map_avatar_color = LLUIColorTable::instance().getColor("MapAvatarColor", LLColor4::white);
+ static LLUIColor map_avatar_friend_color = LLUIColorTable::instance().getColor("MapAvatarFriendColor", LLColor4::white);
+ static LLUIColor map_track_color = LLUIColorTable::instance().getColor("MapTrackColor", LLColor4::white);
+ static LLUIColor map_track_disabled_color = LLUIColorTable::instance().getColor("MapTrackDisabledColor", LLColor4::white);
+ static LLUIColor map_frustum_color = LLUIColorTable::instance().getColor("MapFrustumColor", LLColor4::white);
+ static LLUIColor map_frustum_rotating_color = LLUIColorTable::instance().getColor("MapFrustumRotatingColor", LLColor4::white);
+
if (mObjectImagep.isNull())
{
createObjectImage();
}
-
+
mCurPanX = lerp(mCurPanX, mTargetPanX, LLCriticalDamp::getInterpolant(0.1f));
mCurPanY = lerp(mCurPanY, mTargetPanY, LLCriticalDamp::getInterpolant(0.1f));
+ // Prepare a scissor region
F32 rotation = 0;
- // Prepare a scissor region
{
LLGLEnable scissor(GL_SCISSOR_TEST);
-
+
{
gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
LLLocalClipRect clip(getLocalRect());
@@ -179,11 +143,9 @@ void LLNetMap::draw()
glMatrixMode(GL_MODELVIEW);
// Draw background rectangle
- if(isBackgroundVisible())
- {
- gGL.color4fv(isBackgroundOpaque() ? getBackgroundColor().mV : getTransparentColor().mV);
- gl_rect_2d(0, getRect().getHeight(), getRect().getWidth(), 0);
- }
+ LLColor4 background_color = mBackgroundColor.get();
+ gGL.color4fv( background_color.mV );
+ gl_rect_2d(0, getRect().getHeight(), getRect().getWidth(), 0);
}
// region 0,0 is in the middle
@@ -194,8 +156,7 @@ void LLNetMap::draw()
gGL.translatef( (F32) center_sw_left, (F32) center_sw_bottom, 0.f);
- BOOL rotate_map = gSavedSettings.getBOOL( "MiniMapRotate" );
- if( rotate_map )
+ if( mRotateMap )
{
// rotate subsequent draws to agent rotation
rotation = atan2( LLViewerCamera::getInstance()->getAtAxis().mV[VX], LLViewerCamera::getInstance()->getAtAxis().mV[VY] );
@@ -204,9 +165,6 @@ void LLNetMap::draw()
// figure out where agent is
S32 region_width = llround(LLWorld::getInstance()->getRegionWidthInMeters());
- LLColor4 this_region_color = gColors.getColor( "NetMapThisRegion" );
- LLColor4 live_region_color = gColors.getColor( "NetMapLiveRegion" );
- LLColor4 dead_region_color = gColors.getColor( "NetMapDeadRegion" );
for (LLWorld::region_list_t::const_iterator iter = LLWorld::getInstance()->getRegionList().begin();
iter != LLWorld::getInstance()->getRegionList().end(); ++iter)
@@ -224,10 +182,18 @@ void LLNetMap::draw()
F32 top = bottom + mScale ;
F32 right = left + mScale ;
- gGL.color4fv(regionp == gAgent.getRegion() ? this_region_color.mV : live_region_color.mV);
+ if (regionp == gAgent.getRegion())
+ {
+ gGL.color4f(1.f, 1.f, 1.f, 1.f);
+ }
+ else
+ {
+ gGL.color4f(0.8f, 0.8f, 0.8f, 1.f);
+ }
+
if (!regionp->isAlive())
{
- gGL.color4fv(dead_region_color.mV);
+ gGL.color4f(1.f, 0.5f, 0.5f, 1.f);
}
@@ -319,57 +285,86 @@ void LLNetMap::draw()
// Mouse pointer in local coordinates
S32 local_mouse_x;
S32 local_mouse_y;
+ //localMouse(&local_mouse_x, &local_mouse_y);
LLUI::getCursorPositionLocal(this, &local_mouse_x, &local_mouse_y);
mClosestAgentToCursor.setNull();
F32 closest_dist = F32_MAX;
// Draw avatars
- LLColor4 avatar_color = gColors.getColor( "MapAvatar" );
- LLColor4 friend_color = gColors.getColor( "MapFriend" );
- std::vector<LLUUID> avatar_ids;
- std::vector<LLVector3d> positions;
- LLWorld::getInstance()->getAvatars(&avatar_ids, &positions);
- for(U32 i=0; i<avatar_ids.size(); i++)
+ for (LLWorld::region_list_t::const_iterator iter = LLWorld::getInstance()->getRegionList().begin();
+ iter != LLWorld::getInstance()->getRegionList().end(); ++iter)
{
+ LLViewerRegion* regionp = *iter;
+ const LLVector3d& origin_global = regionp->getOriginGlobal();
+
+ S32 count = regionp->mMapAvatars.count();
+ S32 i;
+ LLVector3 pos_local;
+ U32 compact_local;
+ U8 bits;
// TODO: it'd be very cool to draw these in sorted order from lowest Z to highest.
// just be careful to sort the avatar IDs along with the positions. -MG
- pos_map = globalPosToView(positions[i], rotate_map);
+ for (i = 0; i < count; i++)
+ {
+ compact_local = regionp->mMapAvatars.get(i);
- LLWorldMapView::drawAvatar(
- pos_map.mV[VX], pos_map.mV[VY],
- is_agent_friend(avatar_ids[i]) ? friend_color : avatar_color,
- pos_map.mV[VZ]);
+ bits = compact_local & 0xFF;
+ pos_local.mV[VZ] = F32(bits) * 4.f;
+ compact_local >>= 8;
- F32 dist_to_cursor = dist_vec(LLVector2(pos_map.mV[VX], pos_map.mV[VY]), LLVector2(local_mouse_x,local_mouse_y));
- if(dist_to_cursor < MAP_MIN_PICK_DIST && dist_to_cursor < closest_dist)
- {
- closest_dist = dist_to_cursor;
- mClosestAgentToCursor = avatar_ids[i];
+ bits = compact_local & 0xFF;
+ pos_local.mV[VY] = (F32)bits;
+ compact_local >>= 8;
+
+ bits = compact_local & 0xFF;
+ pos_local.mV[VX] = (F32)bits;
+
+ pos_global.setVec( pos_local );
+ pos_global += origin_global;
+
+ pos_map = globalPosToView(pos_global);
+
+ BOOL show_as_friend = FALSE;
+ if( i < regionp->mMapAvatarIDs.count())
+ {
+ show_as_friend = (LLAvatarTracker::instance().getBuddyInfo(regionp->mMapAvatarIDs.get(i)) != NULL);
+ }
+ LLWorldMapView::drawAvatar(
+ pos_map.mV[VX], pos_map.mV[VY],
+ show_as_friend ? map_avatar_friend_color : map_avatar_color,
+ pos_map.mV[VZ]);
+
+ F32 dist_to_cursor = dist_vec(LLVector2(pos_map.mV[VX], pos_map.mV[VY]), LLVector2(local_mouse_x,local_mouse_y));
+ if(dist_to_cursor < MAP_MIN_PICK_DIST && dist_to_cursor < closest_dist)
+ {
+ closest_dist = dist_to_cursor;
+ mClosestAgentToCursor = regionp->mMapAvatarIDs.get(i);
+ }
}
}
// Draw dot for autopilot target
if (gAgent.getAutoPilot())
{
- drawTracking( gAgent.getAutoPilotTargetGlobal(), rotate_map, gTrackColor );
+ drawTracking( gAgent.getAutoPilotTargetGlobal(), map_track_color );
}
else
{
LLTracker::ETrackingStatus tracking_status = LLTracker::getTrackingStatus();
if ( LLTracker::TRACKING_AVATAR == tracking_status )
{
- drawTracking( LLAvatarTracker::instance().getGlobalPos(), rotate_map, gTrackColor );
+ drawTracking( LLAvatarTracker::instance().getGlobalPos(), map_track_color );
}
else if ( LLTracker::TRACKING_LANDMARK == tracking_status
|| LLTracker::TRACKING_LOCATION == tracking_status )
{
- drawTracking( LLTracker::getTrackedPositionGlobal(), rotate_map, gTrackColor );
+ drawTracking( LLTracker::getTrackedPositionGlobal(), map_track_color );
}
}
// Draw dot for self avatar position
pos_global = gAgent.getPositionGlobal();
- pos_map = globalPosToView(pos_global, rotate_map);
+ pos_map = globalPosToView(pos_global);
LLUIImagePtr you = LLWorldMapView::sAvatarYouSmallImage;
you->draw(
llround(pos_map.mV[VX]) - you->getWidth()/2,
@@ -391,9 +386,9 @@ void LLNetMap::draw()
gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
- if( rotate_map )
+ if( mRotateMap )
{
- gGL.color4fv(gColors.getColor("NetMapFrustum").mV);
+ gGL.color4fv((map_frustum_color()).mV);
gGL.begin( LLRender::TRIANGLES );
gGL.vertex2f( ctr_x, ctr_y );
@@ -403,7 +398,7 @@ void LLNetMap::draw()
}
else
{
- gGL.color4fv(gColors.getColor("NetMapFrustumRotating").mV);
+ gGL.color4fv((map_frustum_rotating_color()).mV);
// If we don't rotate the map, we have to rotate the frustum.
gGL.pushMatrix();
@@ -418,27 +413,11 @@ void LLNetMap::draw()
}
}
- // Rotation of 0 means that North is up
- setDirectionPos( getChild<LLTextBox>("e_label"), rotation);
- setDirectionPos( getChild<LLTextBox>("n_label"), rotation + F_PI_BY_TWO);
- setDirectionPos( getChild<LLTextBox>("w_label"), rotation + F_PI);
- setDirectionPos( getChild<LLTextBox>("s_label"), rotation + F_PI + F_PI_BY_TWO);
-
- setDirectionPos( getChild<LLTextBox>("ne_label"), rotation + F_PI_BY_TWO / 2);
- setDirectionPos( getChild<LLTextBox>("nw_label"), rotation + F_PI_BY_TWO + F_PI_BY_TWO / 2);
- setDirectionPos( getChild<LLTextBox>("sw_label"), rotation + F_PI + F_PI_BY_TWO / 2);
- setDirectionPos( getChild<LLTextBox>("se_label"), rotation + F_PI + F_PI_BY_TWO + F_PI_BY_TWO / 2);
-
- LLView::draw();
+ LLUICtrl::draw();
}
-void LLNetMap::reshape(S32 width, S32 height, BOOL called_from_parent)
+LLVector3 LLNetMap::globalPosToView( const LLVector3d& global_pos )
{
- LLPanel::reshape(width, height, called_from_parent);
- updateMinorDirections();
-}
-
-LLVector3 LLNetMap::globalPosToView( const LLVector3d& global_pos, BOOL rotated ){
LLVector3d relative_pos_global = global_pos - gAgent.getCameraPositionGlobal();
LLVector3 pos_local;
pos_local.setVec(relative_pos_global); // convert to floats from doubles
@@ -447,7 +426,7 @@ LLVector3 LLNetMap::globalPosToView( const LLVector3d& global_pos, BOOL rotated
pos_local.mV[VY] *= mPixelsPerMeter;
// leave Z component in meters
- if( rotated )
+ if( mRotateMap )
{
F32 radians = atan2( LLViewerCamera::getInstance()->getAtAxis().mV[VX], LLViewerCamera::getInstance()->getAtAxis().mV[VY] );
LLQuaternion rot(radians, LLVector3(0.f, 0.f, 1.f));
@@ -460,10 +439,10 @@ LLVector3 LLNetMap::globalPosToView( const LLVector3d& global_pos, BOOL rotated
return pos_local;
}
-void LLNetMap::drawTracking(const LLVector3d& pos_global, BOOL rotated,
- const LLColor4& color, BOOL draw_arrow )
+void LLNetMap::drawTracking(const LLVector3d& pos_global, const LLColor4& color,
+ BOOL draw_arrow )
{
- LLVector3 pos_local = globalPosToView( pos_global, rotated );
+ LLVector3 pos_local = globalPosToView( pos_global );
if( (pos_local.mV[VX] < 0) ||
(pos_local.mV[VY] < 0) ||
(pos_local.mV[VX] >= getRect().getWidth()) ||
@@ -486,16 +465,16 @@ void LLNetMap::drawTracking(const LLVector3d& pos_global, BOOL rotated,
}
}
-LLVector3d LLNetMap::viewPosToGlobal( S32 x, S32 y, BOOL rotated )
+LLVector3d LLNetMap::viewPosToGlobal( S32 x, S32 y )
{
x -= llround(getRect().getWidth() / 2 + mCurPanX);
y -= llround(getRect().getHeight() / 2 + mCurPanY);
- LLVector3 pos_local( (F32)x, (F32)y, 0.f );
+ LLVector3 pos_local( (F32)x, (F32)y, 0 );
F32 radians = - atan2( LLViewerCamera::getInstance()->getAtAxis().mV[VX], LLViewerCamera::getInstance()->getAtAxis().mV[VY] );
- if( rotated )
+ if( mRotateMap )
{
LLQuaternion rot(radians, LLVector3(0.f, 0.f, 1.f));
pos_local.rotVec( rot );
@@ -524,87 +503,55 @@ BOOL LLNetMap::handleToolTip( S32 x, S32 y, std::string& msg, LLRect* sticky_rec
{
return FALSE;
}
- LLViewerRegion* region = LLWorld::getInstance()->getRegionFromPosGlobal( viewPosToGlobal( x, y , gSavedSettings.getBOOL( "MiniMapRotate" )) );
+
+ // mToolTipMsg = "[AGENT][REGION](Double-click to open Map)"
+
+ LLStringUtil::format_map_t args;
+ std::string fullname;
+ if(mClosestAgentToCursor.notNull() && gCacheName->getFullName(mClosestAgentToCursor, fullname))
+ {
+ args["[AGENT]"] = fullname + "\n";
+ }
+ else
+ {
+ args["[AGENT]"] = "";
+ }
+
+ LLViewerRegion* region = LLWorld::getInstance()->getRegionFromPosGlobal( viewPosToGlobal( x, y ) );
if( region )
{
- msg.assign("");
- std::string fullname;
- if(mClosestAgentToCursor.notNull() && gCacheName->getFullName(mClosestAgentToCursor, fullname))
- {
- msg.append(fullname);
- msg.append("\n");
- }
- msg.append( region->getName() );
-
-#ifndef LL_RELEASE_FOR_DOWNLOAD
- std::string buffer;
- msg.append("\n");
- buffer = region->getHost().getHostName();
- msg.append(buffer);
- msg.append("\n");
- buffer = region->getHost().getString();
- msg.append(buffer);
-#endif
- msg.append("\n");
- msg.append(getToolTip());
-
+ args["[REGION]"] = region->getName() + "\n";
+ }
+ else
+ {
+ args["[REGION]"] = "";
+ }
+
+ msg = mToolTipMsg;
+ LLStringUtil::format(msg, args);
+
+ // set sticky_rect
+ if (region)
+ {
S32 SLOP = 4;
localPointToScreen(
x - SLOP, y - SLOP,
&(sticky_rect_screen->mLeft), &(sticky_rect_screen->mBottom) );
sticky_rect_screen->mRight = sticky_rect_screen->mLeft + 2 * SLOP;
sticky_rect_screen->mTop = sticky_rect_screen->mBottom + 2 * SLOP;
- handled = TRUE;
- }
- if(!handled)
- {
- return LLPanel::handleToolTip(x, y, msg, sticky_rect_screen);
}
+
+ handled = TRUE;
return handled;
}
-void LLNetMap::setDirectionPos( LLTextBox* text_box, F32 rotation )
-{
- // Rotation is in radians.
- // Rotation of 0 means x = 1, y = 0 on the unit circle.
-
- F32 half_height = (F32)( (getRect().getHeight() - text_box->getRect().getHeight()) / 2);
- F32 half_width = (F32)( (getRect().getWidth() - text_box->getRect().getWidth()) / 2);
- F32 radius = llmin( half_height, half_width );
-
- // Inset by a little to account for position display.
- radius -= 8.f;
-
- text_box->setOrigin(llround(half_width + radius * cos( rotation )),
- llround(half_height + radius * sin( rotation )));
-}
-
-void LLNetMap::updateMinorDirections()
-{
- if (getChild<LLTextBox>("ne_label") == NULL)
- {
- return;
- }
-
- // Hide minor directions if they cover too much of the map
- bool show_minors = getChild<LLTextBox>("ne_label")->getRect().getHeight() < MAP_MINOR_DIR_THRESHOLD *
- llmin(getRect().getWidth(), getRect().getHeight());
-
- getChild<LLTextBox>("ne_label")->setVisible(show_minors);
- getChild<LLTextBox>("nw_label")->setVisible(show_minors);
- getChild<LLTextBox>("sw_label")->setVisible(show_minors);
- getChild<LLTextBox>("se_label")->setVisible(show_minors);
-}
-
void LLNetMap::renderScaledPointGlobal( const LLVector3d& pos, const LLColor4U &color, F32 radius_meters )
{
LLVector3 local_pos;
local_pos.setVec( pos - mObjectImageCenterGlobal );
- // DEV-17370 - megaprims of size > 4096 cause lag. (go figger.)
- const F32 MAX_RADIUS = 256.0f;
- F32 radius_clamped = llmin(radius_meters, MAX_RADIUS);
+ F32 radius_clamped = llmin(radius_meters, MAX_PRIM_RADIUS);
S32 diameter_pixels = llround(2 * radius_clamped * mObjectMapTPM);
renderPoint( local_pos, color, diameter_pixels );
@@ -699,10 +646,10 @@ void LLNetMap::renderPoint(const LLVector3 &pos_local, const LLColor4U &color,
void LLNetMap::createObjectImage()
{
// Find the size of the side of a square that surrounds the circle that surrounds getRect().
- // ... which is, the diagonal of the rect.
- F32 width = getRect().getWidth();
- F32 height = getRect().getHeight();
- S32 square_size = llround( sqrt(width*width + height*height) );
+ F32 half_width = (F32)(getRect().getWidth() / 2);
+ F32 half_height = (F32)(getRect().getHeight() / 2);
+ F32 radius = sqrt( half_width * half_width + half_height * half_height );
+ S32 square_size = S32( 2 * radius );
// Find the least power of two >= the minimum size.
const S32 MIN_SIZE = 32;
@@ -720,80 +667,8 @@ void LLNetMap::createObjectImage()
mObjectRawImagep = new LLImageRaw(img_size, img_size, 4);
U8* data = mObjectRawImagep->getData();
memset( data, 0, img_size * img_size * 4 );
- mObjectImagep = new LLImageGL( mObjectRawImagep, FALSE);
+ mObjectImagep = LLViewerTextureManager::getLocalTexture( mObjectRawImagep.get(), FALSE);
setScale(mScale);
}
mUpdateNow = TRUE;
}
-
-BOOL LLNetMap::handleDoubleClick( S32 x, S32 y, MASK mask )
-{
- LLFloaterWorldMap::show(NULL, FALSE);
- return TRUE;
-}
-
-BOOL LLNetMap::handleRightMouseDown(S32 x, S32 y, MASK mask)
-{
- mClosestAgentAtLastRightClick = mClosestAgentToCursor;
- LLMenuGL* menu = (LLMenuGL*)mPopupMenuHandle.get();
- if (menu)
- {
- menu->buildDrawLabels();
- menu->updateParent(LLMenuGL::sMenuContainer);
- LLMenuGL::showPopup(this, menu, x, y);
- }
- return TRUE;
-}
-
-
-// static
-bool LLNetMap::LLScaleMap::handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
-{
- LLNetMap *self = mPtr;
-
- S32 level = userdata.asInteger();
-
- switch(level)
- {
- case 0:
- self->setScale(MAP_SCALE_MIN);
- break;
- case 1:
- self->setScale(MAP_SCALE_MID);
- break;
- case 2:
- self->setScale(MAP_SCALE_MAX);
- break;
- default:
- break;
- }
-
- return true;
-}
-
-bool LLNetMap::LLStopTracking::handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
-{
- LLTracker::stopTracking(NULL);
- return true;
-}
-
-bool LLNetMap::LLEnableTracking::handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
-{
- LLNetMap *self = mPtr;
- self->findControl(userdata["control"].asString())->setValue(LLTracker::isTracking(NULL));
- return true;
-}
-
-bool LLNetMap::LLShowAgentProfile::handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
-{
- LLNetMap *self = mPtr;
- LLFloaterAvatarInfo::show(self->mClosestAgentAtLastRightClick);
- return true;
-}
-
-bool LLNetMap::LLEnableProfile::handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
-{
- LLNetMap *self = mPtr;
- self->findControl(userdata["control"].asString())->setValue(self->isAgentUnderCursor());
- return true;
-}
diff --git a/indra/newview/llnetmap.h b/indra/newview/llnetmap.h
index 9fbd5097fd..a673ea3f57 100644
--- a/indra/newview/llnetmap.h
+++ b/indra/newview/llnetmap.h
@@ -33,55 +33,67 @@
#ifndef LL_LLNETMAP_H
#define LL_LLNETMAP_H
-#include "llpanel.h"
-#include "llmemberlistener.h"
+#include "llmath.h"
+#include "lluictrl.h"
#include "v3math.h"
#include "v3dmath.h"
#include "v4color.h"
#include "llimage.h"
-#include "llimagegl.h"
-
+class LLColor4U;
+class LLCoordGL;
class LLTextBox;
+class LLViewerTexture ;
-class LLNetMap : public LLPanel
+class LLNetMap : public LLUICtrl
{
public:
- LLNetMap(const std::string& name);
- virtual ~LLNetMap();
+ struct Params
+ : public LLInitParam::Block<Params, LLUICtrl::Params>
+ {
+ Optional<LLUIColor> bg_color;
- virtual void draw();
- virtual void reshape(S32 width, S32 height, BOOL called_from_parent = TRUE);
- virtual BOOL handleDoubleClick( S32 x, S32 y, MASK mask );
- virtual BOOL handleRightMouseDown( S32 x, S32 y, MASK mask );
- virtual BOOL handleScrollWheel(S32 x, S32 y, S32 clicks);
- virtual BOOL handleToolTip( S32 x, S32 y, std::string& msg, LLRect* sticky_rect_screen );
+ Params()
+ : bg_color("bg_color")
+ {}
+ };
- void renderScaledPointGlobal( const LLVector3d& pos, const LLColor4U &color, F32 radius );
+protected:
+ LLNetMap (const Params & p);
+ friend class LLUICtrlFactory;
-private:
+public:
+ virtual ~LLNetMap();
+ /*virtual*/ void draw();
+ /*virtual*/ BOOL handleScrollWheel(S32 x, S32 y, S32 clicks);
+ /*virtual*/ BOOL handleToolTip( S32 x, S32 y, std::string& msg, LLRect* sticky_rect_screen );
+
void setScale( F32 scale );
-
- // *TODO: Enable panning of the mini-map
+ void setRotateMap( BOOL b ) { mRotateMap = b; }
+ void setToolTipMsg(const std::string& msg) { mToolTipMsg = msg; }
+ BOOL getRotateMap( ) { return mRotateMap; }
+ void renderScaledPointGlobal( const LLVector3d& pos, const LLColor4U &color, F32 radius );
+
+private:
void translatePan( F32 delta_x, F32 delta_y );
void setPan( F32 x, F32 y ) { mTargetPanX = x; mTargetPanY = y; }
- void renderPoint(const LLVector3 &pos, const LLColor4U &color,
- S32 diameter, S32 relative_height = 0);
- LLVector3 globalPosToView(const LLVector3d& global_pos, BOOL rotated);
- LLVector3d viewPosToGlobal(S32 x,S32 y, BOOL rotated);
+ const LLVector3d& getObjectImageCenterGlobal() { return mObjectImageCenterGlobal; }
+ void renderPoint(const LLVector3 &pos, const LLColor4U &color,
+ S32 diameter, S32 relative_height = 0);
- void drawTracking( const LLVector3d& pos_global,
- BOOL rotated,
- const LLColor4& color,
- BOOL draw_arrow = TRUE);
+ LLVector3 globalPosToView(const LLVector3d& global_pos);
+ LLVector3d viewPosToGlobal(S32 x,S32 y);
- void setDirectionPos( LLTextBox* text_box, F32 rotation );
- void updateMinorDirections();
- void createObjectImage();
+ void drawTracking( const LLVector3d& pos_global,
+ const LLColor4& color,
+ BOOL draw_arrow = TRUE);
- LLHandle<LLView> mPopupMenuHandle;
+ void createObjectImage();
+
+private:
+ LLUIColor mBackgroundColor;
F32 mScale; // Size of a region in pixels
F32 mPixelsPerMeter; // world meters to map pixels
@@ -94,47 +106,13 @@ private:
BOOL mUpdateNow;
LLVector3d mObjectImageCenterGlobal;
LLPointer<LLImageRaw> mObjectRawImagep;
- LLPointer<LLImageGL> mObjectImagep;
+ LLPointer<LLViewerTexture> mObjectImagep;
-private:
LLUUID mClosestAgentToCursor;
LLUUID mClosestAgentAtLastRightClick;
- static BOOL sRotateMap;
- static LLNetMap* sInstance;
- static BOOL isAgentUnderCursor(void*) { return sInstance && sInstance->mClosestAgentToCursor.notNull(); }
- static void showAgentProfile(void*);
- BOOL isAgentUnderCursor() { return mClosestAgentToCursor.notNull(); }
-
- class LLScaleMap : public LLMemberListener<LLNetMap>
- {
- public:
- /*virtual*/ bool handleEvent(LLPointer<LLOldEvents::LLEvent> event, const LLSD& userdata);
- };
-
- class LLStopTracking : public LLMemberListener<LLNetMap>
- {
- public:
- /*virtual*/ bool handleEvent(LLPointer<LLOldEvents::LLEvent> event, const LLSD& userdata);
- };
-
- class LLEnableTracking : public LLMemberListener<LLNetMap>
- {
- public:
- /*virtual*/ bool handleEvent(LLPointer<LLOldEvents::LLEvent> event, const LLSD& userdata);
- };
-
- class LLShowAgentProfile : public LLMemberListener<LLNetMap>
- {
- public:
- /*virtual*/ bool handleEvent(LLPointer<LLOldEvents::LLEvent> event, const LLSD& userdata);
- };
-
- class LLEnableProfile : public LLMemberListener<LLNetMap>
- {
- public:
- /*virtual*/ bool handleEvent(LLPointer<LLOldEvents::LLEvent> event, const LLSD& userdata);
- };
+ BOOL mRotateMap;
+ std::string mToolTipMsg;
};
diff --git a/indra/newview/llnotificationalerthandler.cpp b/indra/newview/llnotificationalerthandler.cpp
new file mode 100644
index 0000000000..bd6c6b2308
--- /dev/null
+++ b/indra/newview/llnotificationalerthandler.cpp
@@ -0,0 +1,117 @@
+/**
+ * @file llnotificationalerthandler.cpp
+ * @brief Notification Handler Class for Alert Notifications
+ *
+ * $LicenseInfo:firstyear=2000&license=viewergpl$
+ *
+ * Copyright (c) 2000-2009, Linden Research, Inc.
+ *
+ * Second Life Viewer Source Code
+ * The source code in this file ("Source Code") is provided by Linden Lab
+ * to you under the terms of the GNU General Public License, version 2.0
+ * ("GPL"), unless you have obtained a separate licensing agreement
+ * ("Other License"), formally executed by you and Linden Lab. Terms of
+ * the GPL can be found in doc/GPL-license.txt in this distribution, or
+ * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
+ *
+ * There are special exceptions to the terms and conditions of the GPL as
+ * it is applied to this Source Code. View the full text of the exception
+ * in the file doc/FLOSS-exception.txt in this software distribution, or
+ * online at
+ * http://secondlifegrid.net/programs/open_source/licensing/flossexception
+ *
+ * By copying, modifying or distributing this software, you acknowledge
+ * that you have read and understood your obligations described above,
+ * and agree to abide by those obligations.
+ *
+ * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+ * COMPLETENESS OR PERFORMANCE.
+ * $/LicenseInfo$
+ */
+
+
+#include "llviewerprecompiledheaders.h" // must be first include
+
+#include "llnotificationhandler.h"
+#include "lltoastnotifypanel.h"
+#include "llbottomtray.h"
+#include "llviewercontrol.h"
+
+#include "lltoastalertpanel.h"
+
+using namespace LLNotificationsUI;
+
+//--------------------------------------------------------------------------
+LLAlertHandler::LLAlertHandler(e_notification_type type, const LLSD& id) : mIsModal(false)
+{
+ mType = type;
+
+ LLBottomTray* tray = LLBottomTray::getInstance();
+ LLChannelManager::Params p;
+ p.id = LLUUID(gSavedSettings.getString("AlertChannelUUID"));
+ p.channel_right_bound = tray->getRect().getWidth() / 2;
+ p.channel_width = 0;
+ p.display_toasts_always = true;
+ p.align = NA_CENTRE;
+
+ // Getting a Channel for our notifications
+ mChannel = LLChannelManager::getInstance()->createChannel(p);
+ mChannel->setFollows(FOLLOWS_BOTTOM | FOLLOWS_TOP);
+ mChannel->setShowToasts(true);
+}
+
+//--------------------------------------------------------------------------
+LLAlertHandler::~LLAlertHandler()
+{
+}
+
+//--------------------------------------------------------------------------
+void LLAlertHandler::processNotification(const LLSD& notify)
+{
+ LLNotificationPtr notification = LLNotifications::instance().find(notify["id"].asUUID());
+
+ if (notify["sigtype"].asString() == "add" || notify["sigtype"].asString() == "load")
+ {
+ LLToastAlertPanel* alert_dialog = new LLToastAlertPanel(notification, mIsModal);
+ LLToast::Params p;
+ p.id = notification->getID();
+ p.notification = notification;
+ p.panel = dynamic_cast<LLToastPanel*>(alert_dialog);
+ p.enable_hide_btn = false;
+ p.can_fade = false;
+ p.is_modal = mIsModal;
+ p.on_toast_destroy = boost::bind(&LLAlertHandler::onToastDestroy, this, _1);
+ mChannel->addToast(p);
+ }
+ else if (notify["sigtype"].asString() == "change")
+ {
+ LLToastAlertPanel* alert_dialog = new LLToastAlertPanel(notification, mIsModal);
+ mChannel->modifyToastByNotificationID(notification->getID(), (LLToastPanel*)alert_dialog);
+ }
+ else
+ {
+ mChannel->killToastByNotificationID(notification->getID());
+ }
+}
+
+//--------------------------------------------------------------------------
+
+void LLAlertHandler::onToastDestroy(LLToast* toast)
+{
+ toast->closeFloater();
+}
+
+//--------------------------------------------------------------------------
+void LLAlertHandler::onChicletClick(void)
+{
+}
+
+//--------------------------------------------------------------------------
+void LLAlertHandler::onChicletClose(void)
+{
+}
+
+//--------------------------------------------------------------------------
+
+
diff --git a/indra/newview/llnotificationgrouphandler.cpp b/indra/newview/llnotificationgrouphandler.cpp
new file mode 100644
index 0000000000..31753efec9
--- /dev/null
+++ b/indra/newview/llnotificationgrouphandler.cpp
@@ -0,0 +1,118 @@
+/**
+ * @file llnotificationgrouphandler.cpp
+ * @brief Notification Handler Class for Group Notifications
+ *
+ * $LicenseInfo:firstyear=2000&license=viewergpl$
+ *
+ * Copyright (c) 2000-2009, Linden Research, Inc.
+ *
+ * Second Life Viewer Source Code
+ * The source code in this file ("Source Code") is provided by Linden Lab
+ * to you under the terms of the GNU General Public License, version 2.0
+ * ("GPL"), unless you have obtained a separate licensing agreement
+ * ("Other License"), formally executed by you and Linden Lab. Terms of
+ * the GPL can be found in doc/GPL-license.txt in this distribution, or
+ * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
+ *
+ * There are special exceptions to the terms and conditions of the GPL as
+ * it is applied to this Source Code. View the full text of the exception
+ * in the file doc/FLOSS-exception.txt in this software distribution, or
+ * online at
+ * http://secondlifegrid.net/programs/open_source/licensing/flossexception
+ *
+ * By copying, modifying or distributing this software, you acknowledge
+ * that you have read and understood your obligations described above,
+ * and agree to abide by those obligations.
+ *
+ * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+ * COMPLETENESS OR PERFORMANCE.
+ * $/LicenseInfo$
+ */
+
+#include "llviewerprecompiledheaders.h" // must be first include
+
+#include "llnotificationhandler.h"
+#include "lltoastgroupnotifypanel.h"
+#include "llbottomtray.h"
+#include "llgroupactions.h"
+#include "llviewercontrol.h"
+#include "llfloaterreg.h"
+#include "llsyswellwindow.h"
+
+using namespace LLNotificationsUI;
+
+//--------------------------------------------------------------------------
+LLGroupHandler::LLGroupHandler(e_notification_type type, const LLSD& id)
+{
+ mType = type;
+
+ // getting a Chiclet and creating params for a channel
+ LLBottomTray* tray = LLBottomTray::getInstance();
+ mChiclet = tray->getSysWell();
+ LLChannelManager::Params p;
+ p.id = LLUUID(gSavedSettings.getString("NotificationChannelUUID"));
+ p.channel_right_bound = tray->getRect().mRight - gSavedSettings.getS32("NotificationChannelRightMargin");
+ p.channel_width = gSavedSettings.getS32("NotifyBoxWidth");
+
+ // Getting a Channel for our notifications
+ mChannel = LLChannelManager::getInstance()->createChannel(p);
+}
+
+//--------------------------------------------------------------------------
+LLGroupHandler::~LLGroupHandler()
+{
+}
+
+//--------------------------------------------------------------------------
+void LLGroupHandler::processNotification(const LLSD& notify)
+{
+ LLNotificationPtr notification = LLNotifications::instance().find(notify["id"].asUUID());
+ if(notify["sigtype"].asString() == "add" || notify["sigtype"].asString() == "change")
+ {
+ LLPanel* notify_box = new LLToastGroupNotifyPanel(notification);
+ LLToast::Params p;
+ p.id = notification->getID();
+ p.notification = notification;
+ p.panel = notify_box;
+ p.on_toast_destroy = boost::bind(&LLGroupHandler::onToastDestroy, this, _1);
+ mChannel->addToast(p);
+ static_cast<LLNotificationChiclet*>(mChiclet)->incUreadSystemNotifications();
+
+ LLGroupActions::refresh_notices();
+
+ }
+ else if (notify["sigtype"].asString() == "delete")
+ {
+ mChannel->killToastByNotificationID(notification->getID());
+ }
+}
+
+//--------------------------------------------------------------------------
+void LLGroupHandler::onToastDestroy(LLToast* toast)
+{
+ static_cast<LLNotificationChiclet*>(mChiclet)->decUreadSystemNotifications();
+
+ LLToastPanel* panel = dynamic_cast<LLToastPanel*>(toast->getPanel());
+ LLFloaterReg::getTypedInstance<LLSysWellWindow>("syswell_window")->removeItemByID(panel->getID());
+
+ // turning hovering off mannualy because onMouseLeave won't happen if a toast was closed using a keyboard
+ if(toast->hasFocus())
+ mChannel->setHovering(false);
+
+ toast->closeFloater();
+}
+
+//--------------------------------------------------------------------------
+void LLGroupHandler::onChicletClick(void)
+{
+}
+
+//--------------------------------------------------------------------------
+void LLGroupHandler::onChicletClose(void)
+{
+}
+
+//--------------------------------------------------------------------------
+
+
diff --git a/indra/newview/llnotificationhandler.h b/indra/newview/llnotificationhandler.h
new file mode 100644
index 0000000000..6982ab7096
--- /dev/null
+++ b/indra/newview/llnotificationhandler.h
@@ -0,0 +1,199 @@
+/**
+ * @file llnotificationhandler.h
+ * @brief Here are implemented Notification Handling Classes.
+ *
+ * $LicenseInfo:firstyear=2003&license=viewergpl$
+ *
+ * Copyright (c) 2003-2009, Linden Research, Inc.
+ *
+ * Second Life Viewer Source Code
+ * The source code in this file ("Source Code") is provided by Linden Lab
+ * to you under the terms of the GNU General Public License, version 2.0
+ * ("GPL"), unless you have obtained a separate licensing agreement
+ * ("Other License"), formally executed by you and Linden Lab. Terms of
+ * the GPL can be found in doc/GPL-license.txt in this distribution, or
+ * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
+ *
+ * There are special exceptions to the terms and conditions of the GPL as
+ * it is applied to this Source Code. View the full text of the exception
+ * in the file doc/FLOSS-exception.txt in this software distribution, or
+ * online at
+ * http://secondlifegrid.net/programs/open_source/licensing/flossexception
+ *
+ * By copying, modifying or distributing this software, you acknowledge
+ * that you have read and understood your obligations described above,
+ * and agree to abide by those obligations.
+ *
+ * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+ * COMPLETENESS OR PERFORMANCE.
+ * $/LicenseInfo$
+ */
+
+#ifndef LL_LLNOTIFICATIONHANDLER_H
+#define LL_LLNOTIFICATIONHANDLER_H
+
+
+#include "llwindow.h"
+
+#include "llnotifications.h"
+#include "llchannelmanager.h"
+#include "llchat.h"
+
+namespace LLNotificationsUI
+{
+// ENotificationType enumerates all possible types of notifications that could be met
+//
+typedef enum e_notification_type
+{
+ NT_NOTIFY,
+ NT_NOTIFYTIP,
+ NT_GROUPNOTIFY,
+ NT_IMCHAT,
+ NT_GROUPCHAT,
+ NT_NEARBYCHAT,
+ NT_ALERT,
+ NT_ALERTMODAL
+} ENotificationType;
+
+/**
+ * Handler of notification events.
+ * This handler manages events related to toasts and chicklets. This is base class
+ * for chat and system notification handlers.
+ */
+
+// LLEventHandler is a base class that specifies a common interface for all
+// notification handlers. It states, that every handler must react on the follofing
+// events:
+// - destroying of a toast;
+// - clicking on a correspondet chiclet;
+// - closing of a correspondent chiclet.
+// Also every handler must have the following attributes:
+// - type of the notification that this handler is responsible to;
+// - pointer to a correspondent chiclet;
+// - pointer to a correspondent screen channel, in which all toasts of the handled notification's
+// type should be displayed
+//
+class LLEventHandler
+{
+public:
+ virtual ~LLEventHandler() {};
+
+ virtual void onToastDestroy(LLToast* toast)=0;
+ virtual void onChicletClick(void)=0;
+ virtual void onChicletClose(void)=0;
+
+ LLScreenChannel* mChannel;
+ LLChiclet* mChiclet;
+ e_notification_type mType;
+};
+
+// LLSysHandler and LLChatHandler are more specific base classes
+// that divide all notification handlers on to groups:
+// - handlers for different system notifications (script dialogs, tips, group notices and alerts);
+// - handlers for different messaging notifications (nearby chat, IM chat, group chat etc.)
+/**
+ * Handler for system notifications.
+ */
+class LLSysHandler : public LLEventHandler
+{
+public:
+ virtual ~LLSysHandler() {};
+
+ virtual void processNotification(const LLSD& notify)=0;
+};
+
+/**
+ * Handler for chat message notifications.
+ */
+class LLChatHandler : public LLEventHandler
+{
+public:
+ virtual ~LLChatHandler() {};
+
+ virtual void processChat(const LLChat& chat_msg)=0;
+};
+
+/**
+ * Handler for IM notifications.
+ * It manages life time of tip and script notices.
+ */
+class LLIMHandler : public LLSysHandler
+{
+public:
+ LLIMHandler();
+ virtual ~LLIMHandler();
+
+ // base interface functions
+ virtual void processNotification(const LLSD& notify);
+ virtual void onToastDestroy(LLToast* toast);
+ virtual void onChicletClick(void);
+ virtual void onChicletClose(void);
+
+protected:
+};
+
+/**
+ * Handler for system informational notices.
+ * It manages life time of tip and script notices.
+ */
+class LLInfoHandler : public LLSysHandler
+{
+public:
+ LLInfoHandler(e_notification_type type, const LLSD& id);
+ virtual ~LLInfoHandler();
+
+ // base interface functions
+ virtual void processNotification(const LLSD& notify);
+ virtual void onToastDestroy(LLToast* toast);
+ virtual void onChicletClick(void);
+ virtual void onChicletClose(void);
+
+ // own handlers
+ void onStoreToast(LLPanel* info_panel, LLUUID id);
+ void onRejectToast(LLToast::Params p);
+protected:
+};
+
+
+/**
+ * Handler for group system notices.
+ */
+class LLGroupHandler : public LLSysHandler
+{
+public:
+ LLGroupHandler(e_notification_type type, const LLSD& id);
+ virtual ~LLGroupHandler();
+
+
+ virtual void processNotification(const LLSD& notify);
+ virtual void onToastDestroy(LLToast* toast);
+ virtual void onChicletClick(void);
+ virtual void onChicletClose(void);
+
+protected:
+};
+
+/**
+ * Handler for alert system notices.
+ */
+class LLAlertHandler : public LLSysHandler
+{
+public:
+ LLAlertHandler(e_notification_type type, const LLSD& id);
+ virtual ~LLAlertHandler();
+
+ void setAlertMode(bool is_modal) { mIsModal = is_modal; }
+
+ virtual void processNotification(const LLSD& notify);
+ virtual void onToastDestroy(LLToast* toast);
+ virtual void onChicletClick(void);
+ virtual void onChicletClose(void);
+
+protected:
+ bool mIsModal;
+};
+
+}
+#endif
+
diff --git a/indra/newview/llnotificationmanager.cpp b/indra/newview/llnotificationmanager.cpp
new file mode 100644
index 0000000000..31266fdecf
--- /dev/null
+++ b/indra/newview/llnotificationmanager.cpp
@@ -0,0 +1,130 @@
+/**
+ * @file llnotificationmanager.cpp
+ * @brief Class implements a brige between the old and a new notification sistems
+ *
+ * $LicenseInfo:firstyear=2000&license=viewergpl$
+ *
+ * Copyright (c) 2000-2009, Linden Research, Inc.
+ *
+ * Second Life Viewer Source Code
+ * The source code in this file ("Source Code") is provided by Linden Lab
+ * to you under the terms of the GNU General Public License, version 2.0
+ * ("GPL"), unless you have obtained a separate licensing agreement
+ * ("Other License"), formally executed by you and Linden Lab. Terms of
+ * the GPL can be found in doc/GPL-license.txt in this distribution, or
+ * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
+ *
+ * There are special exceptions to the terms and conditions of the GPL as
+ * it is applied to this Source Code. View the full text of the exception
+ * in the file doc/FLOSS-exception.txt in this software distribution, or
+ * online at
+ * http://secondlifegrid.net/programs/open_source/licensing/flossexception
+ *
+ * By copying, modifying or distributing this software, you acknowledge
+ * that you have read and understood your obligations described above,
+ * and agree to abide by those obligations.
+ *
+ * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+ * COMPLETENESS OR PERFORMANCE.
+ * $/LicenseInfo$
+ */
+
+
+
+#include "llviewerprecompiledheaders.h" // must be first include
+
+
+#include "llnotificationmanager.h"
+#include "llnearbychathandler.h"
+
+#include "boost/bind.hpp"
+
+using namespace LLNotificationsUI;
+
+//--------------------------------------------------------------------------
+LLNotificationManager::LLNotificationManager()
+{
+ mNotifyHandlers.clear();
+ init();
+}
+
+//--------------------------------------------------------------------------
+LLNotificationManager::~LLNotificationManager()
+{
+}
+
+//--------------------------------------------------------------------------
+void LLNotificationManager::init()
+{
+ LLNotificationChannel::buildChannel("Notifications", "Visible", LLNotificationFilters::filterBy<std::string>(&LLNotification::getType, "notify"));
+ LLNotificationChannel::buildChannel("NotificationTips", "Visible", LLNotificationFilters::filterBy<std::string>(&LLNotification::getType, "notifytip"));
+ LLNotificationChannel::buildChannel("Group Notifications", "Visible", LLNotificationFilters::filterBy<std::string>(&LLNotification::getType, "groupnotify"));
+ LLNotificationChannel::buildChannel("Alerts", "Visible", LLNotificationFilters::filterBy<std::string>(&LLNotification::getType, "alert"));
+ LLNotificationChannel::buildChannel("AlertModal", "Visible", LLNotificationFilters::filterBy<std::string>(&LLNotification::getType, "alertmodal"));
+ LLNotificationChannel::buildChannel("IM Notifications", "Visible", LLNotificationFilters::filterBy<std::string>(&LLNotification::getType, "notifytoast"));
+
+ LLNotifications::instance().getChannel("Notifications")->connectChanged(boost::bind(&LLNotificationManager::onNotification, this, _1));
+ LLNotifications::instance().getChannel("NotificationTips")->connectChanged(boost::bind(&LLNotificationManager::onNotification, this, _1));
+ LLNotifications::instance().getChannel("Group Notifications")->connectChanged(boost::bind(&LLNotificationManager::onNotification, this, _1));
+ LLNotifications::instance().getChannel("Alerts")->connectChanged(boost::bind(&LLNotificationManager::onNotification, this, _1));
+ LLNotifications::instance().getChannel("AlertModal")->connectChanged(boost::bind(&LLNotificationManager::onNotification, this, _1));
+ LLNotifications::instance().getChannel("IM Notifications")->connectChanged(boost::bind(&LLNotificationManager::onNotification, this, _1));
+
+ mNotifyHandlers["notify"] = boost::shared_ptr<LLEventHandler>(new LLInfoHandler(NT_NOTIFY, LLSD()));
+ mNotifyHandlers["notifytip"] = mNotifyHandlers["notify"];
+ mNotifyHandlers["groupnotify"] = boost::shared_ptr<LLEventHandler>(new LLGroupHandler(NT_GROUPNOTIFY, LLSD()));
+ mNotifyHandlers["alert"] = boost::shared_ptr<LLEventHandler>(new LLAlertHandler(NT_ALERT, LLSD()));
+ mNotifyHandlers["alertmodal"] = mNotifyHandlers["alert"];
+ mNotifyHandlers["notifytoast"] = boost::shared_ptr<LLEventHandler>(new LLIMHandler());
+
+ mNotifyHandlers["nearbychat"] = boost::shared_ptr<LLEventHandler>(new LLNearbyChatHandler(NT_NEARBYCHAT, LLSD()));
+}
+
+//--------------------------------------------------------------------------
+bool LLNotificationManager::onNotification(const LLSD& notify)
+{
+ LLSysHandler* handle = NULL;
+
+ LLNotificationPtr notification = LLNotifications::instance().find(notify["id"].asUUID());
+
+ if (!notification)
+ return false;
+
+ std::string notification_type = notification->getType();
+ handle = dynamic_cast<LLSysHandler*>(mNotifyHandlers[notification_type].get());
+
+ if(!handle)
+ return false;
+
+ if( notification_type == "alertmodal" )
+ dynamic_cast<LLAlertHandler*>(handle)->setAlertMode(true);
+
+ handle->processNotification(notify);
+
+ return true;
+}
+
+//--------------------------------------------------------------------------
+void LLNotificationManager::onChat(const LLChat& msg,ENotificationType type)
+{
+ switch(type)
+ {
+ case NT_NEARBYCHAT:
+ {
+ LLNearbyChatHandler* handle = dynamic_cast<LLNearbyChatHandler*>(mNotifyHandlers["nearbychat"].get());
+
+ if(handle)
+ handle->processChat(msg);
+ }
+ break;
+ default: //no need to handle all enum types
+ break;
+ }
+}
+
+//--------------------------------------------------------------------------
+
+
+
+
diff --git a/indra/newview/llnotificationmanager.h b/indra/newview/llnotificationmanager.h
new file mode 100644
index 0000000000..838a00ee11
--- /dev/null
+++ b/indra/newview/llnotificationmanager.h
@@ -0,0 +1,79 @@
+// Notification Manager Class
+/**
+ * @file llnotificationmanager.h
+ * @brief Class implements a brige between the old and a new notification sistems
+ *
+ * $LicenseInfo:firstyear=2003&license=viewergpl$
+ *
+ * Copyright (c) 2003-2009, Linden Research, Inc.
+ *
+ * Second Life Viewer Source Code
+ * The source code in this file ("Source Code") is provided by Linden Lab
+ * to you under the terms of the GNU General Public License, version 2.0
+ * ("GPL"), unless you have obtained a separate licensing agreement
+ * ("Other License"), formally executed by you and Linden Lab. Terms of
+ * the GPL can be found in doc/GPL-license.txt in this distribution, or
+ * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
+ *
+ * There are special exceptions to the terms and conditions of the GPL as
+ * it is applied to this Source Code. View the full text of the exception
+ * in the file doc/FLOSS-exception.txt in this software distribution, or
+ * online at
+ * http://secondlifegrid.net/programs/open_source/licensing/flossexception
+ *
+ * By copying, modifying or distributing this software, you acknowledge
+ * that you have read and understood your obligations described above,
+ * and agree to abide by those obligations.
+ *
+ * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+ * COMPLETENESS OR PERFORMANCE.
+ * $/LicenseInfo$
+ */
+
+#ifndef LL_LLNOTIFICATIONMANAGER_H
+#define LL_LLNOTIFICATIONMANAGER_H
+
+#include "lluictrl.h"
+#include "llnotificationhandler.h"
+
+
+#include <map>
+#include <string>
+
+#include <boost/shared_ptr.hpp>
+
+namespace LLNotificationsUI {
+
+class LLToast;
+
+/**
+ * Responsible for registering notification handlers.
+ */
+class LLNotificationManager : public LLUICtrl, public LLSingleton<LLNotificationManager>
+{
+ typedef std::pair<std::string, LLEventHandler*> eventhandlers;
+public:
+ LLNotificationManager();
+ virtual ~LLNotificationManager();
+
+ //TODO: make private
+ // this method initialize handlers' map for different types of notifications
+ void init(void);
+ //TODO: combine processing and storage (*)
+
+ // this method reacts on system notifications and calls an appropriate handler
+ bool onNotification(const LLSD& notification);
+
+ // this method reacts on chat notifications and calls an appropriate handler
+ void onChat(const LLChat& msg,ENotificationType type);
+
+private:
+ //TODO (*)
+ std::map<std::string, boost::shared_ptr<LLEventHandler> > mNotifyHandlers;
+ std::map<std::string, LLChatHandler*> mChatHandlers;
+};
+
+}
+#endif
+
diff --git a/indra/newview/lloutputmonitorctrl.cpp b/indra/newview/lloutputmonitorctrl.cpp
new file mode 100644
index 0000000000..d088c45710
--- /dev/null
+++ b/indra/newview/lloutputmonitorctrl.cpp
@@ -0,0 +1,207 @@
+/**
+ * @file lloutputmonitorctrl.cpp
+ * @brief LLOutputMonitorCtrl base class
+ *
+ * $LicenseInfo:firstyear=2001&license=viewergpl$
+ *
+ * Copyright (c) 2001-2009, Linden Research, Inc.
+ *
+ * Second Life Viewer Source Code
+ * The source code in this file ("Source Code") is provided by Linden Lab
+ * to you under the terms of the GNU General Public License, version 2.0
+ * ("GPL"), unless you have obtained a separate licensing agreement
+ * ("Other License"), formally executed by you and Linden Lab. Terms of
+ * the GPL can be found in doc/GPL-license.txt in this distribution, or
+ * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
+ *
+ * There are special exceptions to the terms and conditions of the GPL as
+ * it is applied to this Source Code. View the full text of the exception
+ * in the file doc/FLOSS-exception.txt in this software distribution, or
+ * online at
+ * http://secondlifegrid.net/programs/open_source/licensing/flossexception
+ *
+ * By copying, modifying or distributing this software, you acknowledge
+ * that you have read and understood your obligations described above,
+ * and agree to abide by those obligations.
+ *
+ * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+ * COMPLETENESS OR PERFORMANCE.
+ * $/LicenseInfo$
+ */
+
+#include "llviewerprecompiledheaders.h"
+#include "lloutputmonitorctrl.h"
+
+// library includes
+#include "llui.h"
+
+// viewer includes
+#include "llvoiceclient.h"
+
+// default options set in output_monitor.xml
+static LLDefaultChildRegistry::Register<LLOutputMonitorCtrl> r("output_monitor");
+
+// The defaults will be initialized in the constructor.
+//LLColor4 LLOutputMonitorCtrl::sColorMuted;
+//LLColor4 LLOutputMonitorCtrl::sColorOverdriven;
+//LLColor4 LLOutputMonitorCtrl::sColorNormal;
+LLColor4 LLOutputMonitorCtrl::sColorBound;
+//S32 LLOutputMonitorCtrl::sRectsNumber = 0;
+//F32 LLOutputMonitorCtrl::sRectWidthRatio = 0.f;
+//F32 LLOutputMonitorCtrl::sRectHeightRatio = 0.f;
+
+LLOutputMonitorCtrl::Params::Params()
+: draw_border("draw_border"),
+ image_mute("image_mute"),
+ image_off("image_off"),
+ image_on("image_on"),
+ image_level_1("image_level_1"),
+ image_level_2("image_level_2"),
+ image_level_3("image_level_3")
+{
+ draw_border = true;
+ name = "output_monitor";
+ follows.flags(FOLLOWS_LEFT|FOLLOWS_TOP);
+ mouse_opaque = false;
+};
+
+LLOutputMonitorCtrl::LLOutputMonitorCtrl(const LLOutputMonitorCtrl::Params& p)
+: LLView(p),
+ mPower(0),
+ mIsMuted(true),
+ mIsTalking(false),
+ mImageMute(p.image_mute),
+ mImageOff(p.image_off),
+ mImageOn(p.image_on),
+ mImageLevel1(p.image_level_1),
+ mImageLevel2(p.image_level_2),
+ mImageLevel3(p.image_level_3)
+{
+ //static LLUIColor output_monitor_muted_color = LLUIColorTable::instance().getColor("OutputMonitorMutedColor", LLColor4::orange);
+ //static LLUIColor output_monitor_overdriven_color = LLUIColorTable::instance().getColor("OutputMonitorOverdrivenColor", LLColor4::red);
+ //static LLUIColor output_monitor_normal_color = LLUIColorTable::instance().getColor("OutputMonitorNotmalColor", LLColor4::green);
+ static LLUIColor output_monitor_bound_color = LLUIColorTable::instance().getColor("OutputMonitorBoundColor", LLColor4::white);
+ //static LLUICachedControl<S32> output_monitor_rects_number("OutputMonitorRectanglesNumber", 20);
+ //static LLUICachedControl<F32> output_monitor_rect_width_ratio("OutputMonitorRectangleWidthRatio", 0.5f);
+ //static LLUICachedControl<F32> output_monitor_rect_height_ratio("OutputMonitorRectangleHeightRatio", 0.8f);
+
+ // IAN BUG compare to existing pattern where these are members - some will change per-widget and need to be anyway
+ // sent feedback to PE
+
+ // *TODO: it looks suboptimal to load the defaults every time an output monitor is constructed.
+ //sColorMuted = output_monitor_muted_color;
+ //sColorOverdriven = output_monitor_overdriven_color;
+ //sColorNormal = output_monitor_normal_color;
+ sColorBound = output_monitor_bound_color;
+ //sRectsNumber = output_monitor_rects_number;
+ //sRectWidthRatio = output_monitor_rect_width_ratio;
+ //sRectHeightRatio = output_monitor_rect_height_ratio;
+
+ mBorder = p.draw_border;
+}
+
+LLOutputMonitorCtrl::~LLOutputMonitorCtrl()
+{
+}
+
+void LLOutputMonitorCtrl::setPower(F32 val)
+{
+ mPower = llmax(0.f, llmin(1.f, val));
+}
+
+void LLOutputMonitorCtrl::draw()
+{
+ // Copied from llmediaremotectrl.cpp
+ // *TODO: Give the LLOutputMonitorCtrl an agent-id to monitor, then
+ // call directly into gVoiceClient to ask if that agent-id is muted, is
+ // speaking, and what power. This avoids duplicating data, which can get
+ // out of sync.
+ const F32 LEVEL_0 = LLVoiceClient::OVERDRIVEN_POWER_LEVEL / 3.f;
+ const F32 LEVEL_1 = LLVoiceClient::OVERDRIVEN_POWER_LEVEL * 2.f / 3.f;
+ const F32 LEVEL_2 = LLVoiceClient::OVERDRIVEN_POWER_LEVEL;
+
+ LLPointer<LLUIImage> icon;
+ if (mIsMuted)
+ {
+ icon = mImageMute;
+ }
+ else if (mPower == 0.f && !mIsTalking)
+ {
+ // only show off if PTT is not engaged
+ icon = mImageOff;
+ }
+ else if (mPower < LEVEL_0)
+ {
+ // PTT is on, possibly with quiet background noise
+ icon = mImageOn;
+ }
+ else if (mPower < LEVEL_1)
+ {
+ icon = mImageLevel1;
+ }
+ else if (mPower < LEVEL_2)
+ {
+ icon = mImageLevel2;
+ }
+ else
+ {
+ // overdriven
+ icon = mImageLevel3;
+ }
+
+ if (icon)
+ {
+ icon->draw(0, 0);
+ }
+
+ //
+ // Fill the monitor with a bunch of small rectangles.
+ // The rectangles will be filled with gradient color,
+ // beginning with sColorNormal and ending with sColorOverdriven.
+ //
+ // *TODO: would using a (partially drawn) pixmap instead be faster?
+ //
+ const int monh = getRect().getHeight();
+ const int monw = getRect().getWidth();
+ //int maxrects = sRectsNumber;
+ //const int period = llmax(1, monw / maxrects, 0, 0); // "1" - min value for the period
+ //const int rectw = llmax(1, llfloor(period * sRectWidthRatio), 0, 0); // "1" - min value for the rect's width
+ //const int recth = llfloor(monh * sRectHeightRatio);
+
+ //if(period == 1 && rectw == 1) //if we have so small control, then "maxrects = monitor's_width - 2*monitor_border's_width
+ // maxrects = monw-2;
+
+ //const int nrects = mIsMuted ? maxrects : llfloor(mPower * maxrects); // how many rects to draw?
+ //const int rectbtm = (monh - recth) / 2;
+ //const int recttop = rectbtm + recth;
+ //
+ //LLColor4 rect_color;
+ //
+ //for (int i=1, xpos = 0; i <= nrects; i++)
+ //{
+ // // Calculate color to use for the current rectangle.
+ // if (mIsMuted)
+ // {
+ // rect_color = sColorMuted;
+ // }
+ // else
+ // {
+ // F32 frac = (mPower * i/nrects) / LLVoiceClient::OVERDRIVEN_POWER_LEVEL;
+ // // Use overdriven color if the power exceeds overdriven level.
+ // if (frac > 1.0f)
+ // frac = 1.0f;
+ // rect_color = lerp(sColorNormal, sColorOverdriven, frac);
+ // }
+
+ // // Draw rectangle filled with the color.
+ // gl_rect_2d(xpos, recttop, xpos+rectw, rectbtm, rect_color, TRUE);
+ // xpos += period;
+ //}
+
+ //
+ // Draw bounding box.
+ //
+ if(mBorder)
+ gl_rect_2d(0, monh, monw, 0, sColorBound, FALSE);
+}
diff --git a/indra/newview/lloutputmonitorctrl.h b/indra/newview/lloutputmonitorctrl.h
new file mode 100644
index 0000000000..98b2fe9dc6
--- /dev/null
+++ b/indra/newview/lloutputmonitorctrl.h
@@ -0,0 +1,103 @@
+/**
+ * @file lloutputmonitorctrl.h
+ * @brief LLOutputMonitorCtrl base class
+ *
+ * $LicenseInfo:firstyear=2001&license=viewergpl$
+ *
+ * Copyright (c) 2001-2009, Linden Research, Inc.
+ *
+ * Second Life Viewer Source Code
+ * The source code in this file ("Source Code") is provided by Linden Lab
+ * to you under the terms of the GNU General Public License, version 2.0
+ * ("GPL"), unless you have obtained a separate licensing agreement
+ * ("Other License"), formally executed by you and Linden Lab. Terms of
+ * the GPL can be found in doc/GPL-license.txt in this distribution, or
+ * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
+ *
+ * There are special exceptions to the terms and conditions of the GPL as
+ * it is applied to this Source Code. View the full text of the exception
+ * in the file doc/FLOSS-exception.txt in this software distribution, or
+ * online at
+ * http://secondlifegrid.net/programs/open_source/licensing/flossexception
+ *
+ * By copying, modifying or distributing this software, you acknowledge
+ * that you have read and understood your obligations described above,
+ * and agree to abide by those obligations.
+ *
+ * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+ * COMPLETENESS OR PERFORMANCE.
+ * $/LicenseInfo$
+ */
+
+#ifndef LL_LLOUTPUTMONITORCTRL_H
+#define LL_LLOUTPUTMONITORCTRL_H
+
+#include "v4color.h"
+#include "llview.h"
+
+class LLTextBox;
+class LLUICtrlFactory;
+
+//
+// Classes
+//
+
+class LLOutputMonitorCtrl
+: public LLView
+{
+public:
+ struct Params : public LLInitParam::Block<Params, LLView::Params>
+ {
+ Optional<bool> draw_border;
+ Mandatory<LLUIImage*> image_mute,
+ image_off,
+ image_on,
+ image_level_1,
+ image_level_2,
+ image_level_3;
+
+ Params();
+ };
+protected:
+ bool mBorder;
+ LLOutputMonitorCtrl(const Params&);
+ friend class LLUICtrlFactory;
+
+public:
+ virtual ~LLOutputMonitorCtrl();
+
+ // llview overrides
+ virtual void draw();
+
+ void setPower(F32 val);
+ F32 getPower(F32 val) const { return mPower; }
+
+ bool getIsMuted() const { return mIsMuted; }
+ void setIsMuted(bool val) { mIsMuted = val; }
+
+ // For the current user, need to know the PTT state to show
+ // correct button image.
+ void setIsTalking(bool val) { mIsTalking = val; }
+
+private:
+ //static LLColor4 sColorMuted;
+ //static LLColor4 sColorNormal;
+ //static LLColor4 sColorOverdriven;
+ static LLColor4 sColorBound;
+ //static S32 sRectsNumber;
+ //static F32 sRectWidthRatio;
+ //static F32 sRectHeightRatio;
+
+ F32 mPower;
+ bool mIsMuted;
+ bool mIsTalking;
+ LLPointer<LLUIImage> mImageMute;
+ LLPointer<LLUIImage> mImageOff;
+ LLPointer<LLUIImage> mImageOn;
+ LLPointer<LLUIImage> mImageLevel1;
+ LLPointer<LLUIImage> mImageLevel2;
+ LLPointer<LLUIImage> mImageLevel3;
+};
+
+#endif
diff --git a/indra/newview/lloverlaybar.cpp b/indra/newview/lloverlaybar.cpp
index b16f56d0d8..ea24638b6d 100644
--- a/indra/newview/lloverlaybar.cpp
+++ b/indra/newview/lloverlaybar.cpp
@@ -37,20 +37,18 @@
#include "lloverlaybar.h"
-#include "audioengine.h"
+#include "llaudioengine.h"
#include "llrender.h"
#include "llagent.h"
#include "llbutton.h"
-#include "llchatbar.h"
#include "llfocusmgr.h"
#include "llimview.h"
#include "llmediaremotectrl.h"
-#include "llpanelaudiovolume.h"
#include "llparcel.h"
#include "lltextbox.h"
#include "llui.h"
#include "llviewercontrol.h"
-#include "llviewerimagelist.h"
+#include "llviewertexturelist.h"
#include "llviewerjoystick.h"
#include "llviewermedia.h"
#include "llviewermenu.h" // handle_reset_view()
@@ -60,9 +58,9 @@
#include "lluictrlfactory.h"
#include "llviewerwindow.h"
#include "llvoiceclient.h"
-#include "llvoavatar.h"
+#include "llvoavatarself.h"
#include "llvoiceremotectrl.h"
-#include "llwebbrowserctrl.h"
+#include "llmediactrl.h"
#include "llselectmgr.h"
//
@@ -89,16 +87,10 @@ void* LLOverlayBar::createMediaRemote(void* userdata)
void* LLOverlayBar::createVoiceRemote(void* userdata)
{
LLOverlayBar *self = (LLOverlayBar*)userdata;
- self->mVoiceRemote = new LLVoiceRemoteCtrl(std::string("voice_remote"));
+ self->mVoiceRemote = new LLVoiceRemoteCtrl();
return self->mVoiceRemote;
}
-void* LLOverlayBar::createChatBar(void* userdata)
-{
- gChatBar = new LLChatBar();
- return gChatBar;
-}
-
LLOverlayBar::LLOverlayBar()
: LLPanel(),
mMediaRemote(NULL),
@@ -110,23 +102,23 @@ LLOverlayBar::LLOverlayBar()
mBuilt = false;
- LLCallbackMap::map_t factory_map;
- factory_map["media_remote"] = LLCallbackMap(LLOverlayBar::createMediaRemote, this);
- factory_map["voice_remote"] = LLCallbackMap(LLOverlayBar::createVoiceRemote, this);
- factory_map["chat_bar"] = LLCallbackMap(LLOverlayBar::createChatBar, this);
+ mFactoryMap["media_remote"] = LLCallbackMap(LLOverlayBar::createMediaRemote, this);
+ mFactoryMap["voice_remote"] = LLCallbackMap(LLOverlayBar::createVoiceRemote, this);
- LLUICtrlFactory::getInstance()->buildPanel(this, "panel_overlaybar.xml", &factory_map);
+ LLUICtrlFactory::getInstance()->buildPanel(this, "panel_overlaybar.xml");
}
BOOL LLOverlayBar::postBuild()
{
- childSetAction("IM Received",onClickIMReceived,this);
childSetAction("Set Not Busy",onClickSetNotBusy,this);
childSetAction("Mouselook",onClickMouselook,this);
childSetAction("Stand Up",onClickStandUp,this);
childSetAction("Flycam",onClickFlycam,this);
childSetVisible("chat_bar", gSavedSettings.getBOOL("ChatVisible"));
+ mVoiceRemote->expandOrCollapse();
+ mMediaRemote->expandOrCollapse();
+
setFocusRoot(TRUE);
mBuilt = true;
@@ -168,8 +160,9 @@ void LLOverlayBar::layoutButtons()
// calculate button widths
const S32 MAX_BUTTON_WIDTH = 150;
+ const S32 STATUS_BAR_PAD = 10;
S32 segment_width = llclamp(lltrunc((F32)(bar_width) / (F32)button_list.size()), 0, MAX_BUTTON_WIDTH);
- S32 btn_width = segment_width - gSavedSettings.getS32("StatusBarPad");
+ S32 btn_width = segment_width - STATUS_BAR_PAD;
// Evenly space all buttons, starting from left
S32 left = 0;
@@ -238,7 +231,7 @@ void LLOverlayBar::refresh()
BOOL sitting = FALSE;
if (gAgent.getAvatarObject())
{
- sitting = gAgent.getAvatarObject()->mIsSitting;
+ sitting = gAgent.getAvatarObject()->isSitting();
}
button = getChild<LLButton>("Stand Up");
@@ -283,13 +276,6 @@ void LLOverlayBar::refresh()
//-----------------------------------------------------------------------
// static
-void LLOverlayBar::onClickIMReceived(void*)
-{
- gIMMgr->setFloaterOpen(TRUE);
-}
-
-
-// static
void LLOverlayBar::onClickSetNotBusy(void*)
{
gAgent.clearBusy();
@@ -329,7 +315,7 @@ void LLOverlayBar::mediaStop(void*)
{
if (!gOverlayBar)
{
- return;
+ // return;
}
LLViewerParcelMedia::stop();
}
@@ -338,15 +324,15 @@ void LLOverlayBar::toggleMediaPlay(void*)
{
if (!gOverlayBar)
{
- return;
+ // return;
}
- if (LLViewerMedia::isMediaPaused())
+ if (LLViewerParcelMedia::getStatus() == LLViewerMediaImpl::MEDIA_PAUSED)
{
LLViewerParcelMedia::start();
}
- else if(LLViewerMedia::isMediaPlaying())
+ else if(LLViewerParcelMedia::getStatus() == LLViewerMediaImpl::MEDIA_PLAYING)
{
LLViewerParcelMedia::pause();
}
diff --git a/indra/newview/lloverlaybar.h b/indra/newview/lloverlaybar.h
index 852d033a10..ffdbd96f60 100644
--- a/indra/newview/lloverlaybar.h
+++ b/indra/newview/lloverlaybar.h
@@ -67,7 +67,6 @@ public:
// helpers for returning desired state
BOOL musicPlaying() { return mMusicState == PLAYING; }
- static void onClickIMReceived(void* data);
static void onClickSetNotBusy(void* data);
static void onClickMouselook(void* data);
static void onClickStandUp(void* data);
@@ -86,7 +85,6 @@ public:
protected:
static void* createMediaRemote(void* userdata);
static void* createVoiceRemote(void* userdata);
- static void* createChatBar(void* userdata);
void enableMediaButtons();
diff --git a/indra/newview/llpanelappearancetab.h b/indra/newview/llpanelappearancetab.h
new file mode 100644
index 0000000000..8a9ba66ec0
--- /dev/null
+++ b/indra/newview/llpanelappearancetab.h
@@ -0,0 +1,65 @@
+/**
+ * @file llpanelplacestab.h
+ * @brief Tabs interface for Side Bar "Places" panel
+ *
+ * $LicenseInfo:firstyear=2009&license=viewergpl$
+ *
+ * Copyright (c) 2004-2009, Linden Research, Inc.
+ *
+ * Second Life Viewer Source Code
+ * The source code in this file ("Source Code") is provided by Linden Lab
+ * to you under the terms of the GNU General Public License, version 2.0
+ * ("GPL"), unless you have obtained a separate licensing agreement
+ * ("Other License"), formally executed by you and Linden Lab. Terms of
+ * the GPL can be found in doc/GPL-license.txt in this distribution, or
+ * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
+ *
+ * There are special exceptions to the terms and conditions of the GPL as
+ * it is applied to this Source Code. View the full text of the exception
+ * in the file doc/FLOSS-exception.txt in this software distribution, or
+ * online at http://secondlifegrid.net/programs/open_source/licensing/flossexception
+ *
+ * By copying, modifying or distributing this software, you acknowledge
+ * that you have read and understood your obligations described above,
+ * and agree to abide by those obligations.
+ *
+ * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+ * COMPLETENESS OR PERFORMANCE.
+ * $/LicenseInfo$
+ */
+
+#ifndef LL_LLPANELAPPEARANCETAB_H
+#define LL_LLPANELAPPEARANCETAB_H
+
+#include "llpanel.h"
+
+#include "llpanelappearance.h"
+
+class LLPanelAppearanceTab : public LLPanel
+{
+public:
+ LLPanelAppearanceTab(LLPanelAppearance *parent) :
+ LLPanel(),
+ mParent(parent)
+ {}
+ virtual ~LLPanelAppearanceTab() {}
+
+ virtual void onSearchEdit(const std::string& string) = 0;
+ virtual void updateVerbs() = 0; // Updates buttons at the bottom of Appearance panel
+ virtual void onWear() = 0;
+ virtual void onEdit() = 0;
+ virtual void onNew() = 0;
+
+ bool isTabVisible(); // Check if parent TabContainer is visible.
+
+ void setPanelAppearanceButtons(LLPanelAppearance* panel);
+
+
+protected:
+ LLButton* mWearBtn;
+ LLButton* mEditBtn;
+ LLPanelAppearance* mParent;
+};
+
+#endif //LL_LLPANELAPPEARANCETAB_H
diff --git a/indra/newview/llpanelavatar.cpp b/indra/newview/llpanelavatar.cpp
index 9d5a4ad01c..6e94b087a6 100644
--- a/indra/newview/llpanelavatar.cpp
+++ b/indra/newview/llpanelavatar.cpp
@@ -31,61 +31,19 @@
*/
#include "llviewerprecompiledheaders.h"
-
#include "llpanelavatar.h"
-#include "llclassifiedflags.h"
-#include "llfontgl.h"
-#include "llcachename.h"
-
-#include "llavatarconstants.h"
-#include "lluiconstants.h"
-#include "lltextbox.h"
-#include "llviewertexteditor.h"
-#include "lltexturectrl.h"
#include "llagent.h"
-#include "llviewerwindow.h"
-#include "llbutton.h"
+#include "llavataractions.h"
+#include "llavatarconstants.h"
#include "llcallingcard.h"
-#include "llcheckboxctrl.h"
-#include "llfloater.h"
-
-#include "llfloaterfriends.h"
-#include "llfloatergroupinfo.h"
-#include "llfloaterworldmap.h"
-#include "llfloatermute.h"
-#include "llfloateravatarinfo.h"
-#include "lliconctrl.h"
-#include "llinventoryview.h"
-#include "lllineeditor.h"
-#include "llnameeditor.h"
-#include "llmutelist.h"
-#include "llpanelclassified.h"
-#include "llpanelpick.h"
-#include "llscrolllistctrl.h"
-#include "llstatusbar.h"
-#include "lltabcontainer.h"
-#include "lltabcontainervertical.h"
+#include "llcombobox.h"
#include "llimview.h"
+#include "lltexteditor.h"
+#include "lltexturectrl.h"
#include "lltooldraganddrop.h"
-#include "lluiconstants.h"
-#include "llvoavatar.h"
-#include "llviewercontrol.h"
-#include "llviewermenu.h" // *FIX: for is_agent_friend()
-#include "llviewergenericmessage.h" // send_generic_message
-#include "llviewerobjectlist.h"
-#include "llviewerregion.h"
+#include "llscrollcontainer.h"
#include "llweb.h"
-#include "llinventorymodel.h"
-#include "roles_constants.h"
-#include "lluictrlfactory.h"
-
-// Statics
-std::list<LLPanelAvatar*> LLPanelAvatar::sAllPanels;
-BOOL LLPanelAvatar::sAllowFirstLife = FALSE;
-
-extern void handle_lure(const LLUUID& invitee);
-extern void handle_pay_by_id(const LLUUID& payee);
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Class LLDropTarget
@@ -98,7 +56,18 @@ extern void handle_pay_by_id(const LLUUID& payee);
class LLDropTarget : public LLView
{
public:
- LLDropTarget(const std::string& name, const LLRect& rect, const LLUUID& agent_id);
+ struct Params : public LLInitParam::Block<Params, LLView::Params>
+ {
+ Optional<LLUUID> agent_id;
+ Params()
+ : agent_id("agent_id")
+ {
+ mouse_opaque(false);
+ follows.flags(FOLLOWS_ALL);
+ }
+ };
+
+ LLDropTarget(const Params&);
~LLDropTarget();
void doDrop(EDragAndDropType cargo_type, void* cargo_data);
@@ -115,17 +84,13 @@ protected:
LLUUID mAgentID;
};
-
-LLDropTarget::LLDropTarget(const std::string& name, const LLRect& rect,
- const LLUUID& agent_id) :
- LLView(name, rect, NOT_MOUSE_OPAQUE, FOLLOWS_ALL),
- mAgentID(agent_id)
-{
-}
+LLDropTarget::LLDropTarget(const LLDropTarget::Params& p)
+: LLView(p),
+ mAgentID(p.agent_id)
+{}
LLDropTarget::~LLDropTarget()
-{
-}
+{}
void LLDropTarget::doDrop(EDragAndDropType cargo_type, void* cargo_data)
{
@@ -149,2156 +114,580 @@ BOOL LLDropTarget::handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop,
return FALSE;
}
+static LLDefaultChildRegistry::Register<LLDropTarget> r("drop_target");
-//-----------------------------------------------------------------------------
-// LLPanelAvatarTab()
-//-----------------------------------------------------------------------------
-LLPanelAvatarTab::LLPanelAvatarTab(const std::string& name, const LLRect &rect,
- LLPanelAvatar* panel_avatar)
-: LLPanel(name, rect),
- mPanelAvatar(panel_avatar),
- mDataRequested(false)
-{ }
-
-// virtual
-void LLPanelAvatarTab::draw()
-{
- refresh();
-
- LLPanel::draw();
-}
-
-void LLPanelAvatarTab::sendAvatarProfileRequestIfNeeded(const std::string& method)
-{
- if (!mDataRequested)
- {
- std::vector<std::string> strings;
- strings.push_back( mPanelAvatar->getAvatarID().asString() );
- send_generic_message(method, strings);
- mDataRequested = true;
- }
-}
-
-//-----------------------------------------------------------------------------
-// LLPanelAvatarSecondLife()
-//-----------------------------------------------------------------------------
-LLPanelAvatarSecondLife::LLPanelAvatarSecondLife(const std::string& name,
- const LLRect &rect,
- LLPanelAvatar* panel_avatar )
-: LLPanelAvatarTab(name, rect, panel_avatar),
- mPartnerID()
-{
-}
-
-void LLPanelAvatarSecondLife::refresh()
-{
- updatePartnerName();
-}
-
-void LLPanelAvatarSecondLife::updatePartnerName()
-{
- if (mPartnerID.notNull())
- {
- std::string first, last;
- BOOL found = gCacheName->getName(mPartnerID, first, last);
- if (found)
- {
- childSetTextArg("partner_edit", "[FIRST]", first);
- childSetTextArg("partner_edit", "[LAST]", last);
- }
- childSetEnabled("partner_info", TRUE);
- }
-}
+static LLRegisterPanelClassWrapper<LLPanelAvatarProfile> t_panel_profile("panel_profile");
+static LLRegisterPanelClassWrapper<LLPanelAvatarMeProfile> t_panel_me_profile("panel_me_profile");
+static LLRegisterPanelClassWrapper<LLPanelAvatarNotes> t_panel_notes("panel_notes");
//-----------------------------------------------------------------------------
-// clearControls()
-// Empty the data out of the controls, since we have to wait for new
-// data off the network.
+// LLPanelAvatarNotes()
//-----------------------------------------------------------------------------
-void LLPanelAvatarSecondLife::clearControls()
+LLPanelAvatarNotes::LLPanelAvatarNotes()
+: LLPanelProfileTab()
{
- LLTextureCtrl* image_ctrl = getChild<LLTextureCtrl>("img");
- if(image_ctrl)
- {
- image_ctrl->setImageAssetID(LLUUID::null);
- }
- childSetValue("about", "");
- childSetValue("born", "");
- childSetValue("acct", "");
-
- childSetTextArg("partner_edit", "[FIRST]", LLStringUtil::null);
- childSetTextArg("partner_edit", "[LAST]", LLStringUtil::null);
-
- mPartnerID = LLUUID::null;
-
- LLScrollListCtrl* group_list = getChild<LLScrollListCtrl>("groups");
- if(group_list)
- {
- group_list->deleteAllItems();
- }
- LLScrollListCtrl* ratings_list = getChild<LLScrollListCtrl>("ratings");
- if(ratings_list)
- {
- ratings_list->deleteAllItems();
- }
}
-
-//-----------------------------------------------------------------------------
-// enableControls()
-//-----------------------------------------------------------------------------
-void LLPanelAvatarSecondLife::enableControls(BOOL self)
+void LLPanelAvatarNotes::updateData()
{
- childSetEnabled("img", self);
- childSetEnabled("about", self);
- childSetVisible("allow_publish", self);
- childSetEnabled("allow_publish", self);
- childSetVisible("?", self);
- childSetEnabled("?", self);
+ LLAvatarPropertiesProcessor::getInstance()->sendDataRequest(getAvatarId(),APT_NOTES);
}
-
-// static
-void LLPanelAvatarSecondLife::onClickImage(void *)
-{ }
-
-// static
-void LLPanelAvatarSecondLife::onDoubleClickGroup(void* data)
+BOOL LLPanelAvatarNotes::postBuild()
{
- LLPanelAvatarSecondLife* self = (LLPanelAvatarSecondLife*)data;
-
-
- LLScrollListCtrl* group_list = self->getChild<LLScrollListCtrl>("groups");
- if(group_list)
- {
- LLScrollListItem* item = group_list->getFirstSelected();
-
- if(item && item->getUUID().notNull())
- {
- llinfos << "Show group info " << item->getUUID() << llendl;
-
- LLFloaterGroupInfo::showFromUUID(item->getUUID());
- }
- }
-}
+ childSetCommitCallback("status_check", boost::bind(&LLPanelAvatarNotes::onCommitRights, this), NULL);
+ childSetCommitCallback("map_check", boost::bind(&LLPanelAvatarNotes::onCommitRights, this), NULL);
+ childSetCommitCallback("objects_check", boost::bind(&LLPanelAvatarNotes::onCommitRights, this), NULL);
-// static
-void LLPanelAvatarSecondLife::onClickPublishHelp(void *)
-{
- LLNotifications::instance().add("ClickPublishHelpAvatar");
-}
+ childSetCommitCallback("add_friend", boost::bind(&LLPanelAvatarNotes::onAddFriendButtonClick, this),NULL);
+ childSetCommitCallback("im", boost::bind(&LLPanelAvatarNotes::onIMButtonClick, this), NULL);
+ childSetCommitCallback("call", boost::bind(&LLPanelAvatarNotes::onCallButtonClick, this), NULL);
+ childSetCommitCallback("teleport", boost::bind(&LLPanelAvatarNotes::onTeleportButtonClick, this), NULL);
+ childSetCommitCallback("share", boost::bind(&LLPanelAvatarNotes::onShareButtonClick, this), NULL);
-// static
-void LLPanelAvatarSecondLife::onClickPartnerHelp(void *)
-{
- LLNotifications::instance().add("ClickPartnerHelpAvatar", LLSD(), LLSD(), onClickPartnerHelpLoadURL);
-}
+ LLTextEditor* te = getChild<LLTextEditor>("notes_edit");
+ te->setCommitCallback(boost::bind(&LLPanelAvatarNotes::onCommitNotes,this));
+ te->setCommitOnFocusLost(TRUE);
-// static
-bool LLPanelAvatarSecondLife::onClickPartnerHelpLoadURL(const LLSD& notification, const LLSD& response)
-{
- S32 option = LLNotification::getSelectedOption(notification, response);
- if (option == 0)
- {
- LLWeb::loadURL("http://secondlife.com/partner");
- }
- return false;
-}
-
-// static
-void LLPanelAvatarSecondLife::onClickPartnerInfo(void *data)
-{
- LLPanelAvatarSecondLife* self = (LLPanelAvatarSecondLife*) data;
- if (self->mPartnerID.notNull())
- {
- LLFloaterAvatarInfo::showFromProfile(self->mPartnerID,
- self->getScreenRect());
- }
-}
-
-//-----------------------------------------------------------------------------
-// LLPanelAvatarFirstLife()
-//-----------------------------------------------------------------------------
-LLPanelAvatarFirstLife::LLPanelAvatarFirstLife(const std::string& name,
- const LLRect &rect,
- LLPanelAvatar* panel_avatar )
-: LLPanelAvatarTab(name, rect, panel_avatar)
-{
-}
-
-void LLPanelAvatarFirstLife::enableControls(BOOL self)
-{
- childSetEnabled("img", self);
- childSetEnabled("about", self);
-}
-
-//-----------------------------------------------------------------------------
-// postBuild
-//-----------------------------------------------------------------------------
-
-BOOL LLPanelAvatarSecondLife::postBuild(void)
-{
- childSetEnabled("born", FALSE);
- childSetEnabled("partner_edit", FALSE);
- childSetAction("partner_help",onClickPartnerHelp,this);
- childSetAction("partner_info", onClickPartnerInfo, this);
- childSetEnabled("partner_info", mPartnerID.notNull());
-
- childSetAction("?",onClickPublishHelp,this);
- BOOL own_avatar = (getPanelAvatar()->getAvatarID() == gAgent.getID() );
- enableControls(own_avatar);
-
- childSetVisible("About:",LLPanelAvatar::sAllowFirstLife);
- childSetVisible("(500 chars)",LLPanelAvatar::sAllowFirstLife);
- childSetVisible("about",LLPanelAvatar::sAllowFirstLife);
-
- childSetVisible("allow_publish",LLPanelAvatar::sAllowFirstLife);
- childSetVisible("?",LLPanelAvatar::sAllowFirstLife);
-
- childSetVisible("online_yes",FALSE);
-
- // These are cruft but may still exist in some xml files
- // TODO: remove the following 2 lines once translators grab these changes
- childSetVisible("online_unknown",FALSE);
- childSetVisible("online_no",FALSE);
-
- childSetAction("Find on Map", LLPanelAvatar::onClickTrack, getPanelAvatar());
- childSetAction("Instant Message...", LLPanelAvatar::onClickIM, getPanelAvatar());
-
- childSetAction("Add Friend...", LLPanelAvatar::onClickAddFriend, getPanelAvatar());
- childSetAction("Pay...", LLPanelAvatar::onClickPay, getPanelAvatar());
- childSetAction("Mute", LLPanelAvatar::onClickMute, getPanelAvatar() );
-
- childSetAction("Offer Teleport...", LLPanelAvatar::onClickOfferTeleport,
- getPanelAvatar() );
-
- childSetDoubleClickCallback("groups", onDoubleClickGroup, this );
-
- getChild<LLTextureCtrl>("img")->setFallbackImageName("default_profile_picture.j2c");
+ resetControls();
+ resetData();
return TRUE;
}
-BOOL LLPanelAvatarFirstLife::postBuild(void)
+void LLPanelAvatarNotes::onOpen(const LLSD& key)
{
- BOOL own_avatar = (getPanelAvatar()->getAvatarID() == gAgent.getID() );
- enableControls(own_avatar);
+ LLPanelProfileTab::onOpen(key);
- getChild<LLTextureCtrl>("img")->setFallbackImageName("default_profile_picture.j2c");
+ fillRightsData();
- return TRUE;
+ //Disable "Add Friend" button for friends.
+ childSetEnabled("add_friend", !LLAvatarActions::isFriend(getAvatarId()));
}
-BOOL LLPanelAvatarNotes::postBuild(void)
+void LLPanelAvatarNotes::fillRightsData()
{
- childSetCommitCallback("notes edit",onCommitNotes,this);
-
- LLTextEditor* te = getChild<LLTextEditor>("notes edit");
- if(te) te->setCommitOnFocusLost(TRUE);
- return TRUE;
-}
-
-BOOL LLPanelAvatarWeb::postBuild(void)
-{
- childSetKeystrokeCallback("url_edit", onURLKeystroke, this);
- childSetCommitCallback("load", onCommitLoad, this);
-
- childSetAction("web_profile_help",onClickWebProfileHelp,this);
-
- childSetCommitCallback("url_edit",onCommitURL,this);
-
- childSetControlName("auto_load","AutoLoadWebProfiles");
-
- mWebBrowser = getChild<LLWebBrowserCtrl>("profile_html");
-
- // links open in internally
- mWebBrowser->setOpenInExternalBrowser( false );
-
- // observe browser events
- mWebBrowser->addObserver( this );
-
- return TRUE;
-}
-
-BOOL LLPanelAvatarClassified::postBuild(void)
-{
- childSetAction("New...",onClickNew,NULL);
- childSetAction("Delete...",onClickDelete,NULL);
- return TRUE;
-}
-
-BOOL LLPanelAvatarPicks::postBuild(void)
-{
- childSetAction("New...",onClickNew,NULL);
- childSetAction("Delete...",onClickDelete,NULL);
- return TRUE;
-}
-
-BOOL LLPanelAvatarAdvanced::postBuild()
-{
- for(size_t ii = 0; ii < LL_ARRAY_SIZE(mWantToCheck); ++ii)
- mWantToCheck[ii] = NULL;
- for(size_t ii = 0; ii < LL_ARRAY_SIZE(mSkillsCheck); ++ii)
- mSkillsCheck[ii] = NULL;
- mWantToCount = (8>LL_ARRAY_SIZE(mWantToCheck))?LL_ARRAY_SIZE(mWantToCheck):8;
- for(S32 tt=0; tt < mWantToCount; ++tt)
- {
- std::string ctlname = llformat("chk%d", tt);
- mWantToCheck[tt] = getChild<LLCheckBoxCtrl>(ctlname);
- }
- mSkillsCount = (6>LL_ARRAY_SIZE(mSkillsCheck))?LL_ARRAY_SIZE(mSkillsCheck):6;
-
- for(S32 tt=0; tt < mSkillsCount; ++tt)
+ const LLRelationship* relation = LLAvatarTracker::instance().getBuddyInfo(getAvatarId());
+ // If true - we are viewing friend's profile, enable check boxes and set values.
+ if(relation)
{
- //Find the Skills checkboxes and save off thier controls
- std::string ctlname = llformat("schk%d",tt);
- mSkillsCheck[tt] = getChild<LLCheckBoxCtrl>(ctlname);
- }
-
- mWantToEdit = getChild<LLLineEditor>("want_to_edit");
- mSkillsEdit = getChild<LLLineEditor>("skills_edit");
- childSetVisible("skills_edit",LLPanelAvatar::sAllowFirstLife);
- childSetVisible("want_to_edit",LLPanelAvatar::sAllowFirstLife);
+ S32 rights = relation->getRightsGrantedTo();
- return TRUE;
-}
+ childSetValue("status_check",LLRelationship::GRANT_ONLINE_STATUS & rights ? TRUE : FALSE);
+ childSetValue("map_check",LLRelationship::GRANT_MAP_LOCATION & rights ? TRUE : FALSE);
+ childSetValue("objects_check",LLRelationship::GRANT_MODIFY_OBJECTS & rights ? TRUE : FALSE);
-//-----------------------------------------------------------------------------
-// LLPanelAvatarWeb
-//-----------------------------------------------------------------------------
-LLPanelAvatarWeb::LLPanelAvatarWeb(const std::string& name, const LLRect& rect,
- LLPanelAvatar* panel_avatar)
-: LLPanelAvatarTab(name, rect, panel_avatar),
- mWebBrowser(NULL)
-{
+ childSetEnabled("status_check",TRUE);
+ childSetEnabled("map_check",TRUE);
+ childSetEnabled("objects_check",TRUE);
+ }
}
-LLPanelAvatarWeb::~LLPanelAvatarWeb()
+void LLPanelAvatarNotes::onCommitNotes()
{
- // stop observing browser events
- if ( mWebBrowser )
- {
- mWebBrowser->remObserver( this );
- };
+ std::string notes = childGetValue("notes_edit").asString();
+ LLAvatarPropertiesProcessor::getInstance()-> sendNotes(getAvatarId(),notes);
}
-void LLPanelAvatarWeb::refresh()
+void LLPanelAvatarNotes::onCommitRights()
{
- if (mNavigateTo != "")
- {
- llinfos << "Loading " << mNavigateTo << llendl;
- mWebBrowser->navigateTo( mNavigateTo );
- mNavigateTo = "";
- }
-}
+ S32 rights = 0;
+ if(childGetValue("status_check").asBoolean())
+ rights |= LLRelationship::GRANT_ONLINE_STATUS;
+ if(childGetValue("map_check").asBoolean())
+ rights |= LLRelationship::GRANT_MAP_LOCATION;
+ if(childGetValue("objects_check").asBoolean())
+ rights |= LLRelationship::GRANT_MODIFY_OBJECTS;
-void LLPanelAvatarWeb::enableControls(BOOL self)
-{
- childSetEnabled("url_edit",self);
+ LLAvatarPropertiesProcessor::getInstance()->sendFriendRights(getAvatarId(),rights);
}
-void LLPanelAvatarWeb::setWebURL(std::string url)
+void LLPanelAvatarNotes::processProperties(void* data, EAvatarProcessorType type)
{
- bool changed_url = (mHome != url);
-
- mHome = url;
- bool have_url = !mHome.empty();
-
- childSetText("url_edit", mHome);
- childSetEnabled("load", mHome.length() > 0);
-
- if (have_url
- && gSavedSettings.getBOOL("AutoLoadWebProfiles"))
+ if(APT_NOTES == type)
{
- if (changed_url)
+ LLAvatarNotes* avatar_notes = static_cast<LLAvatarNotes*>(data);
+ if(avatar_notes && getAvatarId() == avatar_notes->target_id)
{
- load(mHome);
+ childSetValue("notes_edit",avatar_notes->notes);
+ childSetEnabled("notes edit", true);
+
+ LLAvatarPropertiesProcessor::getInstance()->removeObserver(getAvatarId(),this);
}
}
- else
- {
- childSetVisible("profile_html",false);
- childSetVisible("status_text", false);
- }
}
-// static
-void LLPanelAvatarWeb::onCommitURL(LLUICtrl* ctrl, void* data)
+void LLPanelAvatarNotes::resetData()
{
- LLPanelAvatarWeb* self = (LLPanelAvatarWeb*)data;
-
- if (!self) return;
-
- self->load( self->childGetText("url_edit") );
+ childSetValue("notes_edit",LLStringUtil::null);
+ // Default value is TRUE
+ childSetValue("status_check", TRUE);
}
-// static
-void LLPanelAvatarWeb::onClickWebProfileHelp(void *)
+void LLPanelAvatarNotes::resetControls()
{
- LLNotifications::instance().add("ClickWebProfileHelpAvatar");
+ //Disable "Add Friend" button for friends.
+ childSetEnabled("add_friend", TRUE);
+
+ childSetEnabled("status_check",FALSE);
+ childSetEnabled("map_check",FALSE);
+ childSetEnabled("objects_check",FALSE);
}
-void LLPanelAvatarWeb::load(std::string url)
+void LLPanelAvatarNotes::onAddFriendButtonClick()
{
- bool have_url = (!url.empty());
-
-
- childSetVisible("profile_html", have_url);
- childSetVisible("status_text", have_url);
- childSetText("status_text", LLStringUtil::null);
-
- if (have_url)
- {
- mNavigateTo = url;
- }
+ LLAvatarActions::requestFriendshipDialog(getAvatarId());
}
-//static
-void LLPanelAvatarWeb::onURLKeystroke(LLLineEditor* editor, void* data)
+void LLPanelAvatarNotes::onIMButtonClick()
{
- LLPanelAvatarWeb* self = (LLPanelAvatarWeb*)data;
- if (!self) return;
- LLSD::String url = editor->getText();
- self->childSetEnabled("load", url.length() > 0);
- return;
+ LLAvatarActions::startIM(getAvatarId());
}
-// static
-void LLPanelAvatarWeb::onCommitLoad(LLUICtrl* ctrl, void* data)
+void LLPanelAvatarNotes::onTeleportButtonClick()
{
- LLPanelAvatarWeb* self = (LLPanelAvatarWeb*)data;
-
- if (!self) return;
-
- LLSD::String valstr = ctrl->getValue().asString();
- LLSD::String urlstr = self->childGetText("url_edit");
- if (valstr == "") // load url string into browser panel
- {
- self->load(urlstr);
- }
- else if (valstr == "open") // open in user's external browser
- {
- if (!urlstr.empty())
- {
- LLWeb::loadURLExternal(urlstr);
- }
- }
- else if (valstr == "home") // reload profile owner's home page
- {
- if (!self->mHome.empty())
- {
- self->load(self->mHome);
- }
- }
+ LLAvatarActions::offerTeleport(getAvatarId());
}
-void LLPanelAvatarWeb::onStatusTextChange( const EventType& eventIn )
+void LLPanelAvatarNotes::onCallButtonClick()
{
- childSetText("status_text", eventIn.getStringValue() );
+ //*TODO not implemented.
}
-void LLPanelAvatarWeb::onLocationChange( const EventType& eventIn )
+void LLPanelAvatarNotes::onShareButtonClick()
{
- childSetText("url_edit", eventIn.getStringValue() );
+ //*TODO not implemented.
}
+//////////////////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////////////////
-//-----------------------------------------------------------------------------
-// LLPanelAvatarAdvanced
-//-----------------------------------------------------------------------------
-LLPanelAvatarAdvanced::LLPanelAvatarAdvanced(const std::string& name,
- const LLRect& rect,
- LLPanelAvatar* panel_avatar)
-: LLPanelAvatarTab(name, rect, panel_avatar),
- mWantToCount(0),
- mSkillsCount(0),
- mWantToEdit( NULL ),
- mSkillsEdit( NULL )
+LLPanelProfileTab::LLPanelProfileTab()
+: LLPanel()
+, mAvatarId(LLUUID::null)
{
}
-void LLPanelAvatarAdvanced::enableControls(BOOL self)
+LLPanelProfileTab::~LLPanelProfileTab()
{
- S32 t;
- for(t=0;t<mWantToCount;t++)
- {
- if(mWantToCheck[t])mWantToCheck[t]->setEnabled(self);
- }
- for(t=0;t<mSkillsCount;t++)
+ if(getAvatarId().notNull())
{
- if(mSkillsCheck[t])mSkillsCheck[t]->setEnabled(self);
+ LLAvatarPropertiesProcessor::getInstance()->removeObserver(getAvatarId(),this);
}
-
- if (mWantToEdit) mWantToEdit->setEnabled(self);
- if (mSkillsEdit) mSkillsEdit->setEnabled(self);
- childSetEnabled("languages_edit",self);
}
-void LLPanelAvatarAdvanced::setWantSkills(U32 want_to_mask, const std::string& want_to_text,
- U32 skills_mask, const std::string& skills_text,
- const std::string& languages_text)
+void LLPanelProfileTab::setAvatarId(const LLUUID& id)
{
- for(int id =0;id<mWantToCount;id++)
- {
- mWantToCheck[id]->set( want_to_mask & 1<<id );
- }
- for(int id =0;id<mSkillsCount;id++)
- {
- mSkillsCheck[id]->set( skills_mask & 1<<id );
- }
- if (mWantToEdit && mSkillsEdit)
+ if(id.notNull())
{
- mWantToEdit->setText( want_to_text );
- mSkillsEdit->setText( skills_text );
+ if(getAvatarId().notNull())
+ {
+ LLAvatarPropertiesProcessor::getInstance()->removeObserver(mAvatarId,this);
+ }
+ mAvatarId = id;
+ LLAvatarPropertiesProcessor::getInstance()->addObserver(getAvatarId(),this);
}
-
- childSetText("languages_edit",languages_text);
}
-void LLPanelAvatarAdvanced::getWantSkills(U32* want_to_mask, std::string& want_to_text,
- U32* skills_mask, std::string& skills_text,
- std::string& languages_text)
+void LLPanelProfileTab::onOpen(const LLSD& key)
{
- if (want_to_mask)
+ // Don't reset panel if we are opening it for same avatar.
+ if(getAvatarId() != key.asUUID())
{
- *want_to_mask = 0;
- for(int t=0;t<mWantToCount;t++)
- {
- if(mWantToCheck[t]->get())
- *want_to_mask |= 1<<t;
- }
- }
- if (skills_mask)
- {
- *skills_mask = 0;
- for(int t=0;t<mSkillsCount;t++)
- {
- if(mSkillsCheck[t]->get())
- *skills_mask |= 1<<t;
- }
- }
- if (mWantToEdit)
- {
- want_to_text = mWantToEdit->getText();
- }
+ resetControls();
+ resetData();
- if (mSkillsEdit)
- {
- skills_text = mSkillsEdit->getText();
+ scrollToTop();
}
- languages_text = childGetText("languages_edit");
-}
-
-//-----------------------------------------------------------------------------
-// LLPanelAvatarNotes()
-//-----------------------------------------------------------------------------
-LLPanelAvatarNotes::LLPanelAvatarNotes(const std::string& name, const LLRect& rect, LLPanelAvatar* panel_avatar)
-: LLPanelAvatarTab(name, rect, panel_avatar)
-{
+ // Update data even if we are viewing same avatar profile as some data might been changed.
+ setAvatarId(key.asUUID());
+ updateData();
}
-void LLPanelAvatarNotes::refresh()
+void LLPanelProfileTab::scrollToTop()
{
- sendAvatarProfileRequestIfNeeded("avatarnotesrequest");
+ LLScrollContainer* scrollContainer = getChild<LLScrollContainer>("profile_scroll");
+ scrollContainer->goToTop();
}
-void LLPanelAvatarNotes::clearControls()
-{
- childSetText("notes edit", getString("Loading"));
- childSetEnabled("notes edit", false);
-}
+//////////////////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////////////////
-// static
-void LLPanelAvatarNotes::onCommitNotes(LLUICtrl*, void* userdata)
+LLPanelAvatarProfile::LLPanelAvatarProfile()
+: LLPanelProfileTab()
{
- LLPanelAvatarNotes* self = (LLPanelAvatarNotes*)userdata;
-
- self->getPanelAvatar()->sendAvatarNotesUpdate();
}
-
-//-----------------------------------------------------------------------------
-// LLPanelAvatarClassified()
-//-----------------------------------------------------------------------------
-LLPanelAvatarClassified::LLPanelAvatarClassified(const std::string& name, const LLRect& rect,
- LLPanelAvatar* panel_avatar)
-: LLPanelAvatarTab(name, rect, panel_avatar)
+BOOL LLPanelAvatarProfile::postBuild()
{
-}
+ childSetActionTextbox("homepage_edit", boost::bind(&LLPanelAvatarProfile::onHomepageTextboxClicked, this));
+ childSetCommitCallback("add_friend",(boost::bind(&LLPanelAvatarProfile::onAddFriendButtonClick,this)),NULL);
+ childSetCommitCallback("im",(boost::bind(&LLPanelAvatarProfile::onIMButtonClick,this)),NULL);
+ childSetCommitCallback("call",(boost::bind(&LLPanelAvatarProfile::onCallButtonClick,this)),NULL);
+ childSetCommitCallback("teleport",(boost::bind(&LLPanelAvatarProfile::onTeleportButtonClick,this)),NULL);
+ childSetCommitCallback("share",(boost::bind(&LLPanelAvatarProfile::onShareButtonClick,this)),NULL);
+ LLTextureCtrl* pic = getChild<LLTextureCtrl>("2nd_life_pic");
+ pic->setFallbackImageName("default_land_picture.j2c");
-void LLPanelAvatarClassified::refresh()
-{
- BOOL self = (gAgent.getID() == getPanelAvatar()->getAvatarID());
-
- LLTabContainer* tabs = getChild<LLTabContainer>("classified tab");
-
- S32 tab_count = tabs ? tabs->getTabCount() : 0;
-
- bool allow_new = tab_count < MAX_CLASSIFIEDS;
- bool allow_delete = (tab_count > 0);
- bool show_help = (tab_count == 0);
-
- // *HACK: Don't allow making new classifieds from inside the directory.
- // The logic for save/don't save when closing is too hairy, and the
- // directory is conceptually read-only. JC
- bool in_directory = false;
- LLView* view = this;
- while (view)
- {
- if (view->getName() == "directory")
- {
- in_directory = true;
- break;
- }
- view = view->getParent();
- }
- childSetEnabled("New...", self && !in_directory && allow_new);
- childSetVisible("New...", !in_directory);
- childSetEnabled("Delete...", self && !in_directory && allow_delete);
- childSetVisible("Delete...", !in_directory);
- childSetVisible("classified tab",!show_help);
-
- sendAvatarProfileRequestIfNeeded("avatarclassifiedsrequest");
-}
+ pic = getChild<LLTextureCtrl>("real_world_pic");
+ pic->setFallbackImageName("default_land_picture.j2c");
+ resetControls();
+ resetData();
-BOOL LLPanelAvatarClassified::canClose()
-{
- LLTabContainer* tabs = getChild<LLTabContainer>("classified tab");
- for (S32 i = 0; i < tabs->getTabCount(); i++)
- {
- LLPanelClassified* panel = (LLPanelClassified*)tabs->getPanelByIndex(i);
- if (!panel->canClose())
- {
- return FALSE;
- }
- }
return TRUE;
}
-BOOL LLPanelAvatarClassified::titleIsValid()
+void LLPanelAvatarProfile::onOpen(const LLSD& key)
{
- LLTabContainer* tabs = getChild<LLTabContainer>("classified tab");
- if ( tabs )
- {
- LLPanelClassified* panel = (LLPanelClassified*)tabs->getCurrentPanel();
- if ( panel )
- {
- if ( ! panel->titleIsValid() )
- {
- return FALSE;
- };
- };
- };
+ LLPanelProfileTab::onOpen(key);
- return TRUE;
+ //Disable "Add Friend" button for friends.
+ childSetEnabled("add_friend", !LLAvatarActions::isFriend(getAvatarId()));
}
-void LLPanelAvatarClassified::apply()
-{
- LLTabContainer* tabs = getChild<LLTabContainer>("classified tab");
- for (S32 i = 0; i < tabs->getTabCount(); i++)
- {
- LLPanelClassified* panel = (LLPanelClassified*)tabs->getPanelByIndex(i);
- panel->apply();
- }
-}
-
-
-void LLPanelAvatarClassified::deleteClassifiedPanels()
+void LLPanelAvatarProfile::updateData()
{
- LLTabContainer* tabs = getChild<LLTabContainer>("classified tab");
- if (tabs)
+ if (getAvatarId().notNull())
{
- tabs->deleteAllTabs();
+ LLAvatarPropertiesProcessor::getInstance()->sendDataRequest(getAvatarId(),APT_PROPERTIES);
+ LLAvatarPropertiesProcessor::getInstance()->sendDataRequest(getAvatarId(),APT_GROUPS);
}
-
- childSetVisible("New...", false);
- childSetVisible("Delete...", false);
- childSetVisible("loading_text", true);
}
-
-void LLPanelAvatarClassified::processAvatarClassifiedReply(LLMessageSystem* msg, void**)
+void LLPanelAvatarProfile::resetControls()
{
- S32 block = 0;
- S32 block_count = 0;
- LLUUID classified_id;
- std::string classified_name;
- LLPanelClassified* panel_classified = NULL;
-
- LLTabContainer* tabs = getChild<LLTabContainer>("classified tab");
-
- // Don't remove old panels. We need to be able to process multiple
- // packets for people who have lots of classifieds. JC
-
- block_count = msg->getNumberOfBlocksFast(_PREHASH_Data);
- for (block = 0; block < block_count; block++)
- {
- msg->getUUIDFast(_PREHASH_Data, _PREHASH_ClassifiedID, classified_id, block);
- msg->getStringFast(_PREHASH_Data, _PREHASH_Name, classified_name, block);
-
- panel_classified = new LLPanelClassified(false, false);
-
- panel_classified->setClassifiedID(classified_id);
-
- // This will request data from the server when the pick is first drawn.
- panel_classified->markForServerRequest();
+ childSetVisible("status_panel", true);
+ childSetVisible("profile_buttons_panel", true);
+ childSetVisible("title_groups_text", true);
+ childSetVisible("sl_groups", true);
+ childSetEnabled("add_friend", true);
- // The button should automatically truncate long names for us
- if(tabs)
- {
- tabs->addTabPanel(panel_classified, classified_name);
- }
- }
-
- // Make sure somebody is highlighted. This works even if there
- // are no tabs in the container.
- if(tabs)
- {
- tabs->selectFirstTab();
- }
-
- childSetVisible("New...", true);
- childSetVisible("Delete...", true);
- childSetVisible("loading_text", false);
+ childSetVisible("status_me_panel", false);
+ childSetVisible("profile_me_buttons_panel", false);
+ childSetVisible("account_actions_panel", false);
+ childSetVisible("partner_edit_link", false);
}
-
-// Create a new classified panel. It will automatically handle generating
-// its own id when it's time to save.
-// static
-void LLPanelAvatarClassified::onClickNew(void* data)
+void LLPanelAvatarProfile::resetData()
{
- LLPanelAvatarClassified* self = (LLPanelAvatarClassified*)data;
-
- LLNotifications::instance().add("AddClassified", LLSD(), LLSD(), boost::bind(&LLPanelAvatarClassified::callbackNew, self, _1, _2));
-
+ childSetValue("2nd_life_pic",LLUUID::null);
+ childSetValue("real_world_pic",LLUUID::null);
+ childSetValue("online_status",LLStringUtil::null);
+ childSetValue("status_message",LLStringUtil::null);
+ childSetValue("sl_description_edit",LLStringUtil::null);
+ childSetValue("fl_description_edit",LLStringUtil::null);
+ childSetValue("sl_groups",LLStringUtil::null);
+ childSetValue("homepage_edit",LLStringUtil::null);
+ childSetValue("register_date",LLStringUtil::null);
+ childSetValue("acc_status_text",LLStringUtil::null);
+ childSetTextArg("partner_text", "[FIRST]", LLStringUtil::null);
+ childSetTextArg("partner_text", "[LAST]", LLStringUtil::null);
}
-bool LLPanelAvatarClassified::callbackNew(const LLSD& notification, const LLSD& response)
+void LLPanelAvatarProfile::processProperties(void* data, EAvatarProcessorType type)
{
- S32 option = LLNotification::getSelectedOption(notification, response);
- if (0 == option)
+ if(APT_PROPERTIES == type)
{
- LLPanelClassified* panel_classified = new LLPanelClassified(false, false);
- panel_classified->initNewClassified();
- LLTabContainer* tabs = getChild<LLTabContainer>("classified tab");
- if(tabs)
+ const LLAvatarData* avatar_data = static_cast<const LLAvatarData*>(data);
+ if(avatar_data && getAvatarId() == avatar_data->avatar_id)
{
- tabs->addTabPanel(panel_classified, panel_classified->getClassifiedName());
- tabs->selectLastTab();
+ processProfileProperties(avatar_data);
}
}
- return false;
-}
-
-
-// static
-void LLPanelAvatarClassified::onClickDelete(void* data)
-{
- LLPanelAvatarClassified* self = (LLPanelAvatarClassified*)data;
-
- LLTabContainer* tabs = self->getChild<LLTabContainer>("classified tab");
- LLPanelClassified* panel_classified = NULL;
- if(tabs)
+ else if(APT_GROUPS == type)
{
- panel_classified = (LLPanelClassified*)tabs->getCurrentPanel();
- }
- if (!panel_classified) return;
-
- LLSD args;
- args["NAME"] = panel_classified->getClassifiedName();
- LLNotifications::instance().add("DeleteClassified", args, LLSD(), boost::bind(&LLPanelAvatarClassified::callbackDelete, self, _1, _2));
-
-}
-
-
-bool LLPanelAvatarClassified::callbackDelete(const LLSD& notification, const LLSD& response)
-{
- S32 option = LLNotification::getSelectedOption(notification, response);
- LLTabContainer* tabs = getChild<LLTabContainer>("classified tab");
- LLPanelClassified* panel_classified=NULL;
- if(tabs)
- {
- panel_classified = (LLPanelClassified*)tabs->getCurrentPanel();
- }
-
- LLMessageSystem* msg = gMessageSystem;
-
- if (!panel_classified) return false;
-
- if (0 == option)
- {
- msg->newMessageFast(_PREHASH_ClassifiedDelete);
- msg->nextBlockFast(_PREHASH_AgentData);
- msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
- msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
- msg->nextBlockFast(_PREHASH_Data);
- msg->addUUIDFast(_PREHASH_ClassifiedID, panel_classified->getClassifiedID());
- gAgent.sendReliableMessage();
-
- if(tabs)
+ LLAvatarGroups* avatar_groups = static_cast<LLAvatarGroups*>(data);
+ if(avatar_groups && getAvatarId() == avatar_groups->avatar_id)
{
- tabs->removeTabPanel(panel_classified);
+ processGroupProperties(avatar_groups);
}
- delete panel_classified;
- panel_classified = NULL;
}
- return false;
-}
-
-
-//-----------------------------------------------------------------------------
-// LLPanelAvatarPicks()
-//-----------------------------------------------------------------------------
-LLPanelAvatarPicks::LLPanelAvatarPicks(const std::string& name,
- const LLRect& rect,
- LLPanelAvatar* panel_avatar)
-: LLPanelAvatarTab(name, rect, panel_avatar)
-{
}
-
-void LLPanelAvatarPicks::refresh()
+void LLPanelAvatarProfile::processProfileProperties(const LLAvatarData* avatar_data)
{
- BOOL self = (gAgent.getID() == getPanelAvatar()->getAvatarID());
- LLTabContainer* tabs = getChild<LLTabContainer>("picks tab");
- S32 tab_count = tabs ? tabs->getTabCount() : 0;
- childSetEnabled("New...", self && tab_count < MAX_AVATAR_PICKS);
- childSetEnabled("Delete...", self && tab_count > 0);
- childSetVisible("New...", self && getPanelAvatar()->isEditable());
- childSetVisible("Delete...", self && getPanelAvatar()->isEditable());
-
- sendAvatarProfileRequestIfNeeded("avatarpicksrequest");
-}
+ fillCommonData(avatar_data);
+ fillPartnerData(avatar_data);
-void LLPanelAvatarPicks::deletePickPanels()
-{
- LLTabContainer* tabs = getChild<LLTabContainer>("picks tab");
- if(tabs)
- {
- tabs->deleteAllTabs();
- }
+ fillOnlineStatus(avatar_data);
- childSetVisible("New...", false);
- childSetVisible("Delete...", false);
- childSetVisible("loading_text", true);
+ fillAccountStatus(avatar_data);
}
-void LLPanelAvatarPicks::processAvatarPicksReply(LLMessageSystem* msg, void**)
+void LLPanelAvatarProfile::processGroupProperties(const LLAvatarGroups* avatar_groups)
{
- S32 block = 0;
- S32 block_count = 0;
- LLUUID pick_id;
- std::string pick_name;
- LLPanelPick* panel_pick = NULL;
-
- LLTabContainer* tabs = getChild<LLTabContainer>("picks tab");
-
- // Clear out all the old panels. We'll replace them with the correct
- // number of new panels.
- deletePickPanels();
-
- // The database needs to know for which user to look up picks.
- LLUUID avatar_id = getPanelAvatar()->getAvatarID();
-
- block_count = msg->getNumberOfBlocks("Data");
- for (block = 0; block < block_count; block++)
- {
- msg->getUUID("Data", "PickID", pick_id, block);
- msg->getString("Data", "PickName", pick_name, block);
+ std::string groups;
+ LLAvatarGroups::group_list_t::const_iterator it = avatar_groups->group_list.begin();
+ const LLAvatarGroups::group_list_t::const_iterator it_end = avatar_groups->group_list.end();
- panel_pick = new LLPanelPick(FALSE);
-
- panel_pick->setPickID(pick_id, avatar_id);
-
- // This will request data from the server when the pick is first
- // drawn.
- panel_pick->markForServerRequest();
-
- // The button should automatically truncate long names for us
- if(tabs)
- {
- tabs->addTabPanel(panel_pick, pick_name);
- }
- }
-
- // Make sure somebody is highlighted. This works even if there
- // are no tabs in the container.
- if(tabs)
+ if(it_end != it)
{
- tabs->selectFirstTab();
+ groups = (*it).group_name;
+ ++it;
}
-
- childSetVisible("New...", true);
- childSetVisible("Delete...", true);
- childSetVisible("loading_text", false);
-}
-
-
-// Create a new pick panel. It will automatically handle generating
-// its own id when it's time to save.
-// static
-void LLPanelAvatarPicks::onClickNew(void* data)
-{
- LLPanelAvatarPicks* self = (LLPanelAvatarPicks*)data;
- LLPanelPick* panel_pick = new LLPanelPick(FALSE);
- LLTabContainer* tabs = self->getChild<LLTabContainer>("picks tab");
-
- panel_pick->initNewPick();
- if(tabs)
+ for(; it_end != it; ++it)
{
- tabs->addTabPanel(panel_pick, panel_pick->getPickName());
- tabs->selectLastTab();
+ LLAvatarGroups::LLGroupData group_data = *it;
+ groups += ", ";
+ groups += group_data.group_name;
}
+ childSetValue("sl_groups",groups);
}
-
-// static
-void LLPanelAvatarPicks::onClickDelete(void* data)
+void LLPanelAvatarProfile::fillCommonData(const LLAvatarData* avatar_data)
{
- LLPanelAvatarPicks* self = (LLPanelAvatarPicks*)data;
- LLTabContainer* tabs = self->getChild<LLTabContainer>("picks tab");
- LLPanelPick* panel_pick = tabs?(LLPanelPick*)tabs->getCurrentPanel():NULL;
-
- if (!panel_pick) return;
-
- LLSD args;
- args["PICK"] = panel_pick->getPickName();
-
- LLNotifications::instance().add("DeleteAvatarPick", args, LLSD(),
- boost::bind(&LLPanelAvatarPicks::callbackDelete, self, _1, _2));
+ childSetValue("register_date", avatar_data->born_on);
+ childSetValue("sl_description_edit", avatar_data->about_text);
+ childSetValue("fl_description_edit",avatar_data->fl_about_text);
+ childSetValue("2nd_life_pic", avatar_data->image_id);
+ childSetValue("real_world_pic", avatar_data->fl_image_id);
+ childSetValue("homepage_edit", avatar_data->profile_url);
}
-
-// static
-bool LLPanelAvatarPicks::callbackDelete(const LLSD& notification, const LLSD& response)
+void LLPanelAvatarProfile::fillPartnerData(const LLAvatarData* avatar_data)
{
- S32 option = LLNotification::getSelectedOption(notification, response);
- LLTabContainer* tabs = getChild<LLTabContainer>("picks tab");
- LLPanelPick* panel_pick = tabs ? (LLPanelPick*)tabs->getCurrentPanel() : NULL;
- LLMessageSystem* msg = gMessageSystem;
-
- if (!panel_pick) return false;
-
- if (0 == option)
+ if (avatar_data->partner_id.notNull())
{
- // If the viewer has a hacked god-mode, then this call will
- // fail.
- if(gAgent.isGodlike())
- {
- msg->newMessage("PickGodDelete");
- msg->nextBlock("AgentData");
- msg->addUUID("AgentID", gAgent.getID());
- msg->addUUID("SessionID", gAgent.getSessionID());
- msg->nextBlock("Data");
- msg->addUUID("PickID", panel_pick->getPickID());
- // *HACK: We need to send the pick's creator id to accomplish
- // the delete, and we don't use the query id for anything. JC
- msg->addUUID( "QueryID", panel_pick->getPickCreatorID() );
- }
- else
- {
- msg->newMessage("PickDelete");
- msg->nextBlock("AgentData");
- msg->addUUID("AgentID", gAgent.getID());
- msg->addUUID("SessionID", gAgent.getSessionID());
- msg->nextBlock("Data");
- msg->addUUID("PickID", panel_pick->getPickID());
- }
- gAgent.sendReliableMessage();
-
- if(tabs)
+ std::string first, last;
+ BOOL found = gCacheName->getName(avatar_data->partner_id, first, last);
+ if (found)
{
- tabs->removeTabPanel(panel_pick);
+ childSetTextArg("partner_text", "[FIRST]", first);
+ childSetTextArg("partner_text", "[LAST]", last);
}
- delete panel_pick;
- panel_pick = NULL;
- }
- return false;
-}
-
-
-//-----------------------------------------------------------------------------
-// LLPanelAvatar
-//-----------------------------------------------------------------------------
-LLPanelAvatar::LLPanelAvatar(
- const std::string& name,
- const LLRect &rect,
- BOOL allow_edit)
- :
- LLPanel(name, rect, FALSE),
- mPanelSecondLife(NULL),
- mPanelAdvanced(NULL),
- mPanelClassified(NULL),
- mPanelPicks(NULL),
- mPanelNotes(NULL),
- mPanelFirstLife(NULL),
- mPanelWeb(NULL),
- mDropTarget(NULL),
- mAvatarID( LLUUID::null ), // mAvatarID is set with 'setAvatar' or 'setAvatarID'
- mHaveProperties(FALSE),
- mHaveStatistics(FALSE),
- mHaveNotes(false),
- mLastNotes(),
- mAllowEdit(allow_edit)
-{
-
- sAllPanels.push_back(this);
-
- LLCallbackMap::map_t factory_map;
-
- factory_map["2nd Life"] = LLCallbackMap(createPanelAvatarSecondLife, this);
- factory_map["WebProfile"] = LLCallbackMap(createPanelAvatarWeb, this);
- factory_map["Interests"] = LLCallbackMap(createPanelAvatarInterests, this);
- factory_map["Picks"] = LLCallbackMap(createPanelAvatarPicks, this);
- factory_map["Classified"] = LLCallbackMap(createPanelAvatarClassified, this);
- factory_map["1st Life"] = LLCallbackMap(createPanelAvatarFirstLife, this);
- factory_map["My Notes"] = LLCallbackMap(createPanelAvatarNotes, this);
-
- LLUICtrlFactory::getInstance()->buildPanel(this, "panel_avatar.xml", &factory_map);
-
- selectTab(0);
-
-
-}
-
-BOOL LLPanelAvatar::postBuild(void)
-{
- mTab = getChild<LLTabContainer>("tab");
- childSetAction("Kick",onClickKick,this);
- childSetAction("Freeze",onClickFreeze, this);
- childSetAction("Unfreeze", onClickUnfreeze, this);
- childSetAction("csr_btn", onClickCSR, this);
- childSetAction("OK", onClickOK, this);
- childSetAction("Cancel", onClickCancel, this);
-
- if(mTab && !sAllowFirstLife)
- {
- LLPanel* panel = mTab->getPanelByName("1st Life");
- if (panel) mTab->removeTabPanel(panel);
-
- panel = mTab->getPanelByName("WebProfile");
- if (panel) mTab->removeTabPanel(panel);
- }
- childSetVisible("Kick",FALSE);
- childSetEnabled("Kick",FALSE);
- childSetVisible("Freeze",FALSE);
- childSetEnabled("Freeze",FALSE);
- childSetVisible("Unfreeze",FALSE);
- childSetEnabled("Unfreeze",FALSE);
- childSetVisible("csr_btn", FALSE);
- childSetEnabled("csr_btn", FALSE);
-
- return TRUE;
-}
-
-
-LLPanelAvatar::~LLPanelAvatar()
-{
- sAllPanels.remove(this);
-}
-
-
-BOOL LLPanelAvatar::canClose()
-{
- return mPanelClassified && mPanelClassified->canClose();
-}
-
-void LLPanelAvatar::setAvatar(LLViewerObject *avatarp)
-{
- // find the avatar and grab the name
- LLNameValue *firstname = avatarp->getNVPair("FirstName");
- LLNameValue *lastname = avatarp->getNVPair("LastName");
-
- std::string name;
- if (firstname && lastname)
- {
- name.assign( firstname->getString() );
- name.append(" ");
- name.append( lastname->getString() );
}
else
{
- name.assign("");
+ childSetTextArg("partner_text", "[FIRST]", getString("no_partner_text"));
}
-
- // If we have an avatar pointer, they must be online.
- setAvatarID(avatarp->getID(), name, ONLINE_STATUS_YES);
}
-void LLPanelAvatar::setOnlineStatus(EOnlineStatus online_status)
+void LLPanelAvatarProfile::fillOnlineStatus(const LLAvatarData* avatar_data)
{
- // Online status NO could be because they are hidden
- // If they are a friend, we may know the truth!
- if ((ONLINE_STATUS_YES != online_status)
- && mIsFriend
- && (LLAvatarTracker::instance().isBuddyOnline( mAvatarID )))
- {
- online_status = ONLINE_STATUS_YES;
- }
-
- mPanelSecondLife->childSetVisible("online_yes", (online_status == ONLINE_STATUS_YES));
-
- // Since setOnlineStatus gets called after setAvatarID
- // need to make sure that "Offer Teleport" doesn't get set
- // to TRUE again for yourself
- if (mAvatarID != gAgent.getID())
- {
- childSetVisible("Offer Teleport...",TRUE);
- }
-
- BOOL in_prelude = gAgent.inPrelude();
- if(gAgent.isGodlike())
+ bool online = avatar_data->flags & AVATAR_ONLINE;
+ if(LLAvatarActions::isFriend(avatar_data->avatar_id))
{
- childSetEnabled("Offer Teleport...", TRUE);
- childSetToolTip("Offer Teleport...", childGetValue("TeleportGod").asString());
- }
- else if (in_prelude)
- {
- childSetEnabled("Offer Teleport...",FALSE);
- childSetToolTip("Offer Teleport...",childGetValue("TeleportPrelude").asString());
- }
- else
- {
- childSetEnabled("Offer Teleport...", (online_status == ONLINE_STATUS_YES));
- childSetToolTip("Offer Teleport...", childGetValue("TeleportNormal").asString());
+ // Online status NO could be because they are hidden
+ // If they are a friend, we may know the truth!
+ online = LLAvatarTracker::instance().isBuddyOnline(avatar_data->avatar_id);
}
+ childSetValue("online_status", online ?
+ "Online" : "Offline");
+ childSetColor("online_status", online ?
+ LLColor4::green : LLColor4::red);
}
-void LLPanelAvatar::setAvatarID(const LLUUID &avatar_id, const std::string &name,
- EOnlineStatus online_status)
+void LLPanelAvatarProfile::fillAccountStatus(const LLAvatarData* avatar_data)
{
- if (avatar_id.isNull()) return;
-
- BOOL avatar_changed = FALSE;
- if (avatar_id != mAvatarID)
- {
- avatar_changed = TRUE;
- }
- mAvatarID = avatar_id;
-
- // Determine if we have their calling card.
- mIsFriend = is_agent_friend(mAvatarID);
-
- // setOnlineStatus uses mIsFriend
- setOnlineStatus(online_status);
-
- BOOL own_avatar = (mAvatarID == gAgent.getID() );
- BOOL avatar_is_friend = LLAvatarTracker::instance().getBuddyInfo(mAvatarID) != NULL;
-
- mPanelSecondLife->enableControls(own_avatar && mAllowEdit);
- mPanelWeb->enableControls(own_avatar && mAllowEdit);
- mPanelAdvanced->enableControls(own_avatar && mAllowEdit);
- // Teens don't have this.
- if (mPanelFirstLife) mPanelFirstLife->enableControls(own_avatar && mAllowEdit);
-
- LLView *target_view = getChild<LLView>("drop_target_rect");
- if(target_view)
- {
- if (mDropTarget)
- {
- delete mDropTarget;
- }
- mDropTarget = new LLDropTarget("drop target", target_view->getRect(), mAvatarID);
- addChild(mDropTarget);
- mDropTarget->setAgentID(mAvatarID);
- }
-
- LLNameEditor* name_edit = getChild<LLNameEditor>("name");
- if(name_edit)
- {
- if (name.empty())
- {
- name_edit->setNameID(avatar_id, FALSE);
- }
- else
- {
- name_edit->setText(name);
- }
- }
-// if (avatar_changed)
+ std::string caption_text = avatar_data->caption_text;
+ if(caption_text.empty())
{
- // While we're waiting for data off the network, clear out the
- // old data.
- mPanelSecondLife->clearControls();
-
- mPanelPicks->deletePickPanels();
- mPanelPicks->setDataRequested(false);
-
- mPanelClassified->deleteClassifiedPanels();
- mPanelClassified->setDataRequested(false);
-
- mPanelNotes->clearControls();
- mPanelNotes->setDataRequested(false);
- mHaveNotes = false;
- mLastNotes.clear();
-
- // Request just the first two pages of data. The picks,
- // classifieds, and notes will be requested when that panel
- // is made visible. JC
- sendAvatarPropertiesRequest();
-
- if (own_avatar)
- {
- if (mAllowEdit)
- {
- // OK button disabled until properties data arrives
- childSetVisible("OK", true);
- childSetEnabled("OK", false);
- childSetVisible("Cancel",TRUE);
- childSetEnabled("Cancel",TRUE);
- }
- else
- {
- childSetVisible("OK",FALSE);
- childSetEnabled("OK",FALSE);
- childSetVisible("Cancel",FALSE);
- childSetEnabled("Cancel",FALSE);
- }
- childSetVisible("Instant Message...",FALSE);
- childSetEnabled("Instant Message...",FALSE);
- childSetVisible("Mute",FALSE);
- childSetEnabled("Mute",FALSE);
- childSetVisible("Offer Teleport...",FALSE);
- childSetEnabled("Offer Teleport...",FALSE);
- childSetVisible("drop target",FALSE);
- childSetEnabled("drop target",FALSE);
- childSetVisible("Find on Map",FALSE);
- childSetEnabled("Find on Map",FALSE);
- childSetVisible("Add Friend...",FALSE);
- childSetEnabled("Add Friend...",FALSE);
- childSetVisible("Pay...",FALSE);
- childSetEnabled("Pay...",FALSE);
- }
- else
- {
- childSetVisible("OK",FALSE);
- childSetEnabled("OK",FALSE);
-
- childSetVisible("Cancel",FALSE);
- childSetEnabled("Cancel",FALSE);
-
- childSetVisible("Instant Message...",TRUE);
- childSetEnabled("Instant Message...",FALSE);
- childSetVisible("Mute",TRUE);
- childSetEnabled("Mute",FALSE);
+ LLStringUtil::format_map_t args;
+ caption_text = getString("CaptionTextAcctInfo");
+ BOOL transacted = (avatar_data->flags & AVATAR_TRANSACTED);
+ BOOL identified = (avatar_data->flags & AVATAR_IDENTIFIED);
+ BOOL age_verified = (avatar_data->flags & AVATAR_AGEVERIFIED); // Not currently getting set in dataserver/lldataavatar.cpp for privacy considerations
- childSetVisible("drop target",TRUE);
- childSetEnabled("drop target",FALSE);
-
- childSetVisible("Find on Map",TRUE);
- // Note: we don't always know online status, so always allow gods to try to track
- BOOL enable_track = gAgent.isGodlike() || is_agent_mappable(mAvatarID);
- childSetEnabled("Find on Map",enable_track);
- if (!mIsFriend)
+ const char* ACCT_TYPE[] = {
+ "AcctTypeResident",
+ "AcctTypeTrial",
+ "AcctTypeCharterMember",
+ "AcctTypeEmployee"
+ };
+ U8 caption_index = llclamp(avatar_data->caption_index, (U8)0, (U8)(LL_ARRAY_SIZE(ACCT_TYPE)-1));
+ args["[ACCTTYPE]"] = getString(ACCT_TYPE[caption_index]);
+
+ std::string payment_text = " ";
+ const S32 DEFAULT_CAPTION_LINDEN_INDEX = 3;
+ if(caption_index != DEFAULT_CAPTION_LINDEN_INDEX)
+ {
+ if(transacted)
{
- childSetToolTip("Find on Map",childGetValue("ShowOnMapNonFriend").asString());
+ payment_text = "PaymentInfoUsed";
}
- else if (ONLINE_STATUS_YES != online_status)
+ else if (identified)
{
- childSetToolTip("Find on Map",childGetValue("ShowOnMapFriendOffline").asString());
+ payment_text = "PaymentInfoOnFile";
}
else
{
- childSetToolTip("Find on Map",childGetValue("ShowOnMapFriendOnline").asString());
+ payment_text = "NoPaymentInfoOnFile";
}
- childSetVisible("Add Friend...", true);
- childSetEnabled("Add Friend...", !avatar_is_friend);
- childSetVisible("Pay...",TRUE);
- childSetEnabled("Pay...",FALSE);
- }
- }
-
- BOOL is_god = FALSE;
- if (gAgent.isGodlike()) is_god = TRUE;
-
- childSetVisible("Kick", is_god);
- childSetEnabled("Kick", is_god);
- childSetVisible("Freeze", is_god);
- childSetEnabled("Freeze", is_god);
- childSetVisible("Unfreeze", is_god);
- childSetEnabled("Unfreeze", is_god);
- childSetVisible("csr_btn", is_god);
- childSetEnabled("csr_btn", is_god);
-}
+ args["[PAYMENTINFO]"] = getString(payment_text);
-
-void LLPanelAvatar::resetGroupList()
-{
- // only get these updates asynchronously via the group floater, which works on the agent only
- if (mAvatarID != gAgent.getID())
- {
- return;
- }
-
- if (mPanelSecondLife)
- {
- LLScrollListCtrl* group_list = mPanelSecondLife->getChild<LLScrollListCtrl>("groups");
- if (group_list)
- {
- group_list->deleteAllItems();
-
- S32 count = gAgent.mGroups.count();
- LLUUID id;
-
- for(S32 i = 0; i < count; ++i)
- {
- LLGroupData group_data = gAgent.mGroups.get(i);
- id = group_data.mID;
- std::string group_string;
- /* Show group title? DUMMY_POWER for Don Grep
- if(group_data.mOfficer)
- {
- group_string = "Officer of ";
- }
- else
- {
- group_string = "Member of ";
- }
- */
-
- group_string += group_data.mName;
-
- LLSD row;
-
- row["id"] = id ;
- row["columns"][0]["value"] = group_string;
- row["columns"][0]["font"] = "SANSSERIF_SMALL";
- row["columns"][0]["width"] = 0;
- group_list->addElement(row);
- }
- group_list->sortByColumnIndex(0, TRUE);
- }
- }
-}
-
-// static
-//-----------------------------------------------------------------------------
-// onClickIM()
-//-----------------------------------------------------------------------------
-void LLPanelAvatar::onClickIM(void* userdata)
-{
- LLPanelAvatar* self = (LLPanelAvatar*) userdata;
- gIMMgr->setFloaterOpen(TRUE);
-
- std::string name;
- LLNameEditor* nameedit = self->mPanelSecondLife->getChild<LLNameEditor>("name");
- if (nameedit) name = nameedit->getText();
- gIMMgr->addSession(name, IM_NOTHING_SPECIAL, self->mAvatarID);
-}
-
-
-// static
-//-----------------------------------------------------------------------------
-// onClickTrack()
-//-----------------------------------------------------------------------------
-void LLPanelAvatar::onClickTrack(void* userdata)
-{
- LLPanelAvatar* self = (LLPanelAvatar*) userdata;
-
- if( gFloaterWorldMap )
- {
- std::string name;
- LLNameEditor* nameedit = self->mPanelSecondLife->getChild<LLNameEditor>("name");
- if (nameedit) name = nameedit->getText();
- gFloaterWorldMap->trackAvatar(self->mAvatarID, name);
- LLFloaterWorldMap::show(NULL, TRUE);
- }
-}
-
-
-// static
-void LLPanelAvatar::onClickAddFriend(void* userdata)
-{
- LLPanelAvatar* self = (LLPanelAvatar*) userdata;
- LLNameEditor* name_edit = self->mPanelSecondLife->getChild<LLNameEditor>("name");
- if (name_edit)
- {
- LLPanelFriends::requestFriendshipDialog(self->getAvatarID(),
- name_edit->getText());
- }
-}
-
-//-----------------------------------------------------------------------------
-// onClickMute()
-//-----------------------------------------------------------------------------
-void LLPanelAvatar::onClickMute(void *userdata)
-{
- LLPanelAvatar* self = (LLPanelAvatar*) userdata;
-
- LLUUID agent_id = self->getAvatarID();
- LLNameEditor* name_edit = self->mPanelSecondLife->getChild<LLNameEditor>("name");
-
- if (name_edit)
- {
- std::string agent_name = name_edit->getText();
- LLFloaterMute::showInstance();
-
- if (LLMuteList::getInstance()->isMuted(agent_id))
- {
- LLFloaterMute::getInstance()->selectMute(agent_id);
+ std::string age_text = age_verified ? "AgeVerified" : "NotAgeVerified";
+ // Do not display age verification status at this time
+ //args["[[AGEVERIFICATION]]"] = mPanelSecondLife->getString(age_text);
+ args["[AGEVERIFICATION]"] = " ";
}
else
{
- LLMute mute(agent_id, agent_name, LLMute::AGENT);
- LLMuteList::getInstance()->add(mute);
+ args["[PAYMENTINFO]"] = " ";
+ args["[AGEVERIFICATION]"] = " ";
}
+ LLStringUtil::format(caption_text, args);
}
-}
-
-
-// static
-void LLPanelAvatar::onClickOfferTeleport(void *userdata)
-{
- LLPanelAvatar* self = (LLPanelAvatar*) userdata;
- handle_lure(self->mAvatarID);
+ childSetValue("acc_status_text", caption_text);
}
-
-// static
-void LLPanelAvatar::onClickPay(void *userdata)
+void LLPanelAvatarProfile::onUrlTextboxClicked(std::string url)
{
- LLPanelAvatar* self = (LLPanelAvatar*) userdata;
- handle_pay_by_id(self->mAvatarID);
+ LLWeb::loadURL(url);
}
-
-// static
-void LLPanelAvatar::onClickOK(void *userdata)
+void LLPanelAvatarProfile::onHomepageTextboxClicked()
{
- LLPanelAvatar *self = (LLPanelAvatar *)userdata;
-
- // JC: Only save the data if we actually got the original
- // properties. Otherwise we might save blanks into
- // the database.
- if (self
- && self->mHaveProperties)
+ std::string url = childGetValue("homepage_edit").asString();
+ if(!url.empty())
{
- self->sendAvatarPropertiesUpdate();
-
- LLTabContainer* tabs = self->getChild<LLTabContainer>("tab");
- if ( tabs->getCurrentPanel() != self->mPanelClassified )
- {
- self->mPanelClassified->apply();
-
- LLFloaterAvatarInfo *infop = LLFloaterAvatarInfo::getInstance(self->mAvatarID);
- if (infop)
- {
- infop->close();
- }
- }
- else
- {
- if ( self->mPanelClassified->titleIsValid() )
- {
- self->mPanelClassified->apply();
-
- LLFloaterAvatarInfo *infop = LLFloaterAvatarInfo::getInstance(self->mAvatarID);
- if (infop)
- {
- infop->close();
- }
- }
- }
+ onUrlTextboxClicked(url);
}
}
-// static
-void LLPanelAvatar::onClickCancel(void *userdata)
+void LLPanelAvatarProfile::onAddFriendButtonClick()
{
- LLPanelAvatar *self = (LLPanelAvatar *)userdata;
-
- if (self)
- {
- LLFloaterAvatarInfo *infop;
- if ((infop = LLFloaterAvatarInfo::getInstance(self->mAvatarID)))
- {
- infop->close();
- }
- else
- {
- // We're in the Search directory and are cancelling an edit
- // to our own profile, so reset.
- self->sendAvatarPropertiesRequest();
- }
- }
+ LLAvatarActions::requestFriendshipDialog(getAvatarId());
}
-
-void LLPanelAvatar::sendAvatarPropertiesRequest()
+void LLPanelAvatarProfile::onIMButtonClick()
{
- lldebugs << "LLPanelAvatar::sendAvatarPropertiesRequest()" << llendl;
- LLMessageSystem *msg = gMessageSystem;
-
- msg->newMessageFast(_PREHASH_AvatarPropertiesRequest);
- msg->nextBlockFast( _PREHASH_AgentData);
- msg->addUUIDFast( _PREHASH_AgentID, gAgent.getID() );
- msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
- msg->addUUIDFast( _PREHASH_AvatarID, mAvatarID);
- gAgent.sendReliableMessage();
+ LLAvatarActions::startIM(getAvatarId());
}
-void LLPanelAvatar::sendAvatarNotesUpdate()
+void LLPanelAvatarProfile::onTeleportButtonClick()
{
- std::string notes = mPanelNotes->childGetValue("notes edit").asString();
-
- if (!mHaveNotes
- && (notes.empty() || notes == getString("Loading")))
- {
- // no notes from server and no user updates
- return;
- }
- if (notes == mLastNotes)
- {
- // Avatar notes unchanged
- return;
- }
-
- LLMessageSystem *msg = gMessageSystem;
-
- msg->newMessage("AvatarNotesUpdate");
- msg->nextBlock("AgentData");
- msg->addUUID("AgentID", gAgent.getID());
- msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
- msg->nextBlock("Data");
- msg->addUUID("TargetID", mAvatarID);
- msg->addString("Notes", notes);
-
- gAgent.sendReliableMessage();
+ LLAvatarActions::offerTeleport(getAvatarId());
}
-
-// static
-void LLPanelAvatar::processAvatarPropertiesReply(LLMessageSystem *msg, void**)
+void LLPanelAvatarProfile::onCallButtonClick()
{
- LLUUID agent_id; // your id
- LLUUID avatar_id; // target of this panel
- LLUUID image_id;
- LLUUID fl_image_id;
- LLUUID partner_id;
- std::string about_text;
- std::string fl_about_text;
- std::string born_on;
- S32 charter_member_size = 0;
- BOOL allow_publish = FALSE;
- //BOOL mature = FALSE;
- BOOL identified = FALSE;
- BOOL transacted = FALSE;
- BOOL age_verified = FALSE;
- BOOL online = FALSE;
- std::string profile_url;
-
- U32 flags = 0x0;
-
- //llinfos << "properties packet size " << msg->getReceiveSize() << llendl;
-
- msg->getUUIDFast(_PREHASH_AgentData, _PREHASH_AgentID, agent_id);
- msg->getUUIDFast(_PREHASH_AgentData, _PREHASH_AvatarID, avatar_id );
-
- for (panel_list_t::iterator iter = sAllPanels.begin(); iter != sAllPanels.end(); ++iter)
- {
- LLPanelAvatar* self = *iter;
- if (self->mAvatarID != avatar_id)
- {
- continue;
- }
- self->childSetEnabled("Instant Message...",TRUE);
- self->childSetEnabled("Pay...",TRUE);
- self->childSetEnabled("Mute",TRUE);
-
- self->childSetEnabled("drop target",TRUE);
-
- self->mHaveProperties = TRUE;
- self->enableOKIfReady();
-
- msg->getUUIDFast( _PREHASH_PropertiesData, _PREHASH_ImageID, image_id );
- msg->getUUIDFast( _PREHASH_PropertiesData, _PREHASH_FLImageID, fl_image_id );
- msg->getUUIDFast(_PREHASH_PropertiesData, _PREHASH_PartnerID, partner_id);
- msg->getStringFast(_PREHASH_PropertiesData, _PREHASH_AboutText, about_text );
- msg->getStringFast(_PREHASH_PropertiesData, _PREHASH_FLAboutText, fl_about_text );
- msg->getStringFast(_PREHASH_PropertiesData, _PREHASH_BornOn, born_on);
- msg->getString("PropertiesData","ProfileURL", profile_url);
- msg->getU32Fast(_PREHASH_PropertiesData, _PREHASH_Flags, flags);
-
- identified = (flags & AVATAR_IDENTIFIED);
- transacted = (flags & AVATAR_TRANSACTED);
- age_verified = (flags & AVATAR_AGEVERIFIED); // Not currently getting set in dataserver/lldataavatar.cpp for privacy considerations
- allow_publish = (flags & AVATAR_ALLOW_PUBLISH);
- online = (flags & AVATAR_ONLINE);
-
- U8 caption_index = 0;
- std::string caption_text;
- charter_member_size = msg->getSize("PropertiesData", "CharterMember");
- if(1 == charter_member_size)
- {
- msg->getBinaryData("PropertiesData", "CharterMember", &caption_index, 1);
- }
- else if(1 < charter_member_size)
- {
- msg->getString("PropertiesData", "CharterMember", caption_text);
- }
-
-
- if(caption_text.empty())
- {
- LLStringUtil::format_map_t args;
- caption_text = self->mPanelSecondLife->getString("CaptionTextAcctInfo");
-
- const char* ACCT_TYPE[] = {
- "AcctTypeResident",
- "AcctTypeTrial",
- "AcctTypeCharterMember",
- "AcctTypeEmployee"
- };
- caption_index = llclamp(caption_index, (U8)0, (U8)(LL_ARRAY_SIZE(ACCT_TYPE)-1));
- args["[ACCTTYPE]"] = self->mPanelSecondLife->getString(ACCT_TYPE[caption_index]);
-
- std::string payment_text = " ";
- const S32 DEFAULT_CAPTION_LINDEN_INDEX = 3;
- if(caption_index != DEFAULT_CAPTION_LINDEN_INDEX)
- {
- if(transacted)
- {
- payment_text = "PaymentInfoUsed";
- }
- else if (identified)
- {
- payment_text = "PaymentInfoOnFile";
- }
- else
- {
- payment_text = "NoPaymentInfoOnFile";
- }
- args["[PAYMENTINFO]"] = self->mPanelSecondLife->getString(payment_text);
- std::string age_text = age_verified ? "AgeVerified" : "NotAgeVerified";
- // Do not display age verification status at this time
- //args["[[AGEVERIFICATION]]"] = self->mPanelSecondLife->getString(age_text);
- args["[AGEVERIFICATION]"] = " ";
- }
- else
- {
- args["[PAYMENTINFO]"] = " ";
- args["[AGEVERIFICATION]"] = " ";
- }
- LLStringUtil::format(caption_text, args);
- }
-
- self->mPanelSecondLife->childSetValue("acct", caption_text);
- self->mPanelSecondLife->childSetValue("born", born_on);
-
- EOnlineStatus online_status = (online) ? ONLINE_STATUS_YES : ONLINE_STATUS_NO;
-
- self->setOnlineStatus(online_status);
-
- self->mPanelWeb->setWebURL(profile_url);
-
- LLTextureCtrl* image_ctrl = self->mPanelSecondLife->getChild<LLTextureCtrl>("img");
- if(image_ctrl)
- {
- image_ctrl->setImageAssetID(image_id);
- }
- self->childSetValue("about", about_text);
-
- self->mPanelSecondLife->setPartnerID(partner_id);
- self->mPanelSecondLife->updatePartnerName();
-
- if (self->mPanelFirstLife)
- {
- // Teens don't get these
- self->mPanelFirstLife->childSetValue("about", fl_about_text);
- LLTextureCtrl* image_ctrl = self->mPanelFirstLife->getChild<LLTextureCtrl>("img");
- if(image_ctrl)
- {
- image_ctrl->setImageAssetID(fl_image_id);
- }
-
- self->mPanelSecondLife->childSetValue("allow_publish", allow_publish);
-
- }
- }
+ //*TODO not implemented
}
-// static
-void LLPanelAvatar::processAvatarInterestsReply(LLMessageSystem *msg, void**)
+void LLPanelAvatarProfile::onShareButtonClick()
{
- LLUUID agent_id; // your id
- LLUUID avatar_id; // target of this panel
-
- U32 want_to_mask;
- std::string want_to_text;
- U32 skills_mask;
- std::string skills_text;
- std::string languages_text;
-
- //llinfos << "properties packet size " << msg->getReceiveSize() << llendl;
-
- msg->getUUIDFast(_PREHASH_AgentData, _PREHASH_AgentID, agent_id);
- msg->getUUIDFast(_PREHASH_AgentData, _PREHASH_AvatarID, avatar_id );
-
- for (panel_list_t::iterator iter = sAllPanels.begin(); iter != sAllPanels.end(); ++iter)
- {
- LLPanelAvatar* self = *iter;
- if (self->mAvatarID != avatar_id)
- {
- continue;
- }
-
- msg->getU32Fast( _PREHASH_PropertiesData, _PREHASH_WantToMask, want_to_mask );
- msg->getStringFast(_PREHASH_PropertiesData, _PREHASH_WantToText, want_to_text );
- msg->getU32Fast( _PREHASH_PropertiesData, _PREHASH_SkillsMask, skills_mask );
- msg->getStringFast(_PREHASH_PropertiesData, _PREHASH_SkillsText, skills_text );
- msg->getString(_PREHASH_PropertiesData, "LanguagesText", languages_text );
-
- self->mPanelAdvanced->setWantSkills(want_to_mask, want_to_text, skills_mask, skills_text, languages_text);
- }
+ //*TODO not implemented
}
-// Separate function because the groups list can be very long, almost
-// filling a packet. JC
-// static
-void LLPanelAvatar::processAvatarGroupsReply(LLMessageSystem *msg, void**)
-{
- LLUUID agent_id; // your id
- LLUUID avatar_id; // target of this panel
- U64 group_powers;
- std::string group_title;
- LLUUID group_id;
- std::string group_name;
- LLUUID group_insignia_id;
-
- llinfos << "groups packet size " << msg->getReceiveSize() << llendl;
-
- msg->getUUIDFast(_PREHASH_AgentData, _PREHASH_AgentID, agent_id);
- msg->getUUIDFast(_PREHASH_AgentData, _PREHASH_AvatarID, avatar_id );
-
- for (panel_list_t::iterator iter = sAllPanels.begin(); iter != sAllPanels.end(); ++iter)
- {
- LLPanelAvatar* self = *iter;
- if (self->mAvatarID != avatar_id)
- {
- continue;
- }
-
- LLScrollListCtrl* group_list = self->mPanelSecondLife->getChild<LLScrollListCtrl>("groups");
-// if(group_list)
-// {
-// group_list->deleteAllItems();
-// }
-
- S32 group_count = msg->getNumberOfBlocksFast(_PREHASH_GroupData);
- if (0 == group_count)
- {
- if(group_list) group_list->addCommentText(std::string("None")); // *TODO: Translate
- }
- else
- {
- for(S32 i = 0; i < group_count; ++i)
- {
- msg->getU64( _PREHASH_GroupData, "GroupPowers", group_powers, i );
- msg->getStringFast(_PREHASH_GroupData, _PREHASH_GroupTitle, group_title, i );
- msg->getUUIDFast( _PREHASH_GroupData, _PREHASH_GroupID, group_id, i);
- msg->getStringFast(_PREHASH_GroupData, _PREHASH_GroupName, group_name, i );
- msg->getUUIDFast( _PREHASH_GroupData, _PREHASH_GroupInsigniaID, group_insignia_id, i );
-
- std::string group_string;
- if (group_id.notNull())
- {
- group_string.assign(group_name);
- }
- else
- {
- group_string.assign("");
- }
-
- // Is this really necessary? Remove existing entry if it exists.
- // TODO: clear the whole list when a request for data is made
- if (group_list)
- {
- S32 index = group_list->getItemIndex(group_id);
- if ( index >= 0 )
- {
- group_list->deleteSingleItem(index);
- }
- }
-
- LLSD row;
- row["id"] = group_id;
- row["columns"][0]["value"] = group_string;
- row["columns"][0]["font"] = "SANSSERIF_SMALL";
- if (group_list)
- {
- group_list->addElement(row);
- }
- }
- }
- if(group_list) group_list->sortByColumnIndex(0, TRUE);
- }
-}
+//////////////////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////////////////
-// Don't enable the OK button until you actually have the data.
-// Otherwise you will write blanks back into the database.
-void LLPanelAvatar::enableOKIfReady()
+LLPanelAvatarMeProfile::LLPanelAvatarMeProfile()
+: LLPanelAvatarProfile()
{
- if(mHaveProperties && childIsVisible("OK"))
- {
- childSetEnabled("OK", TRUE);
- }
- else
- {
- childSetEnabled("OK", FALSE);
- }
}
-void LLPanelAvatar::sendAvatarPropertiesUpdate()
+BOOL LLPanelAvatarMeProfile::postBuild()
{
- llinfos << "Sending avatarinfo update" << llendl;
- BOOL allow_publish = FALSE;
- BOOL mature = FALSE;
- if (LLPanelAvatar::sAllowFirstLife)
- {
- allow_publish = childGetValue("allow_publish");
- //A profile should never be mature.
- mature = FALSE;
- }
- U32 want_to_mask = 0x0;
- U32 skills_mask = 0x0;
- std::string want_to_text;
- std::string skills_text;
- std::string languages_text;
- mPanelAdvanced->getWantSkills(&want_to_mask, want_to_text, &skills_mask, skills_text, languages_text);
-
- LLUUID first_life_image_id;
- std::string first_life_about_text;
- if (mPanelFirstLife)
- {
- first_life_about_text = mPanelFirstLife->childGetValue("about").asString();
- LLTextureCtrl* image_ctrl = mPanelFirstLife->getChild<LLTextureCtrl>("img");
- if(image_ctrl)
- {
- first_life_image_id = image_ctrl->getImageAssetID();
- }
- }
+ LLPanelAvatarProfile::postBuild();
- std::string about_text = mPanelSecondLife->childGetValue("about").asString();
+ mStatusCombobox = getChild<LLComboBox>("status_combo");
- LLMessageSystem *msg = gMessageSystem;
+ childSetCommitCallback("status_combo", boost::bind(&LLPanelAvatarMeProfile::onStatusChanged, this), NULL);
+ childSetCommitCallback("status_me_message_text", boost::bind(&LLPanelAvatarMeProfile::onStatusMessageChanged, this), NULL);
+ childSetActionTextbox("payment_update_link", boost::bind(&LLPanelAvatarMeProfile::onUpdateAccountTextboxClicked, this));
+ childSetActionTextbox("my_account_link", boost::bind(&LLPanelAvatarMeProfile::onMyAccountTextboxClicked, this));
+ childSetActionTextbox("partner_edit_link", boost::bind(&LLPanelAvatarMeProfile::onPartnerEditTextboxClicked, this));
- msg->newMessageFast(_PREHASH_AvatarPropertiesUpdate);
- msg->nextBlockFast(_PREHASH_AgentData);
- msg->addUUIDFast( _PREHASH_AgentID, gAgent.getID() );
- msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID() );
- msg->nextBlockFast(_PREHASH_PropertiesData);
-
- LLTextureCtrl* image_ctrl = mPanelSecondLife->getChild<LLTextureCtrl>("img");
- if(image_ctrl)
- {
- msg->addUUIDFast( _PREHASH_ImageID, image_ctrl->getImageAssetID());
- }
- else
- {
- msg->addUUIDFast( _PREHASH_ImageID, LLUUID::null);
- }
-// msg->addUUIDFast( _PREHASH_ImageID, mPanelSecondLife->mimage_ctrl->getImageAssetID() );
- msg->addUUIDFast( _PREHASH_FLImageID, first_life_image_id);
- msg->addStringFast( _PREHASH_AboutText, about_text);
- msg->addStringFast( _PREHASH_FLAboutText, first_life_about_text);
-
- msg->addBOOL("AllowPublish", allow_publish);
- msg->addBOOL("MaturePublish", mature);
- msg->addString("ProfileURL", mPanelWeb->childGetText("url_edit"));
- gAgent.sendReliableMessage();
-
- msg->newMessage("AvatarInterestsUpdate");
- msg->nextBlockFast(_PREHASH_AgentData);
- msg->addUUIDFast( _PREHASH_AgentID, gAgent.getID() );
- msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID() );
- msg->nextBlockFast(_PREHASH_PropertiesData);
- msg->addU32Fast( _PREHASH_WantToMask, want_to_mask);
- msg->addStringFast( _PREHASH_WantToText, want_to_text);
- msg->addU32Fast( _PREHASH_SkillsMask, skills_mask);
- msg->addStringFast( _PREHASH_SkillsText, skills_text);
- msg->addString( "LanguagesText", languages_text);
- gAgent.sendReliableMessage();
-}
+ resetControls();
+ resetData();
-void LLPanelAvatar::selectTab(S32 tabnum)
-{
- if(mTab)
- {
- mTab->selectTab(tabnum);
- }
+ return TRUE;
}
-void LLPanelAvatar::selectTabByName(std::string tab_name)
+void LLPanelAvatarMeProfile::onOpen(const LLSD& key)
{
- if (mTab)
- {
- if (tab_name.empty())
- {
- mTab->selectFirstTab();
- }
- else
- {
- mTab->selectTabByName(tab_name);
- }
- }
+ LLPanelProfileTab::onOpen(key);
}
-
-void LLPanelAvatar::processAvatarNotesReply(LLMessageSystem *msg, void**)
+void LLPanelAvatarMeProfile::processProfileProperties(const LLAvatarData* avatar_data)
{
- // extract the agent id
- LLUUID agent_id;
- msg->getUUID("AgentData", "AgentID", agent_id);
+ fillCommonData(avatar_data);
- LLUUID target_id;
- msg->getUUID("Data", "TargetID", target_id);
+ fillPartnerData(avatar_data);
- // look up all panels which have this avatar
- for (panel_list_t::iterator iter = sAllPanels.begin(); iter != sAllPanels.end(); ++iter)
- {
- LLPanelAvatar* self = *iter;
- if (self->mAvatarID != target_id)
- {
- continue;
- }
+ fillStatusData(avatar_data);
- std::string text;
- msg->getString("Data", "Notes", text);
- self->childSetValue("notes edit", text);
- self->childSetEnabled("notes edit", true);
- self->mHaveNotes = true;
- self->mLastNotes = text;
- }
+ fillAccountStatus(avatar_data);
}
-
-void LLPanelAvatar::processAvatarClassifiedReply(LLMessageSystem *msg, void** userdata)
+void LLPanelAvatarMeProfile::fillStatusData(const LLAvatarData* avatar_data)
{
- LLUUID agent_id;
- LLUUID target_id;
-
- msg->getUUIDFast(_PREHASH_AgentData, _PREHASH_AgentID, agent_id);
- msg->getUUIDFast(_PREHASH_AgentData, _PREHASH_TargetID, target_id);
-
- // look up all panels which have this avatar target
- for (panel_list_t::iterator iter = sAllPanels.begin(); iter != sAllPanels.end(); ++iter)
+ std::string status;
+ if (gAgent.getAFK())
{
- LLPanelAvatar* self = *iter;
- if (self->mAvatarID != target_id)
- {
- continue;
- }
-
- self->mPanelClassified->processAvatarClassifiedReply(msg, userdata);
+ status = "away";
}
-}
-
-void LLPanelAvatar::processAvatarPicksReply(LLMessageSystem *msg, void** userdata)
-{
- LLUUID agent_id;
- LLUUID target_id;
-
- msg->getUUID("AgentData", "AgentID", agent_id);
- msg->getUUID("AgentData", "TargetID", target_id);
-
- // look up all panels which have this avatar target
- for (panel_list_t::iterator iter = sAllPanels.begin(); iter != sAllPanels.end(); ++iter)
+ else if (gAgent.getBusy())
{
- LLPanelAvatar* self = *iter;
- if (self->mAvatarID != target_id)
- {
- continue;
- }
-
- self->mPanelPicks->processAvatarPicksReply(msg, userdata);
+ status = "busy";
}
-}
-
-// static
-void LLPanelAvatar::onClickKick(void* userdata)
-{
- LLPanelAvatar* self = (LLPanelAvatar*) userdata;
-
- S32 left, top;
- gFloaterView->getNewFloaterPosition(&left, &top);
- LLRect rect(left, top, left+400, top-300);
-
- LLSD payload;
- payload["avatar_id"] = self->mAvatarID;
- LLNotifications::instance().add("KickUser", LLSD(), payload, finishKick);
-}
-
-//static
-bool LLPanelAvatar::finishKick(const LLSD& notification, const LLSD& response)
-{
- S32 option = LLNotification::getSelectedOption(notification, response);
-
- if (option == 0)
+ else
{
- LLUUID avatar_id = notification["payload"]["avatar_id"].asUUID();
- LLMessageSystem* msg = gMessageSystem;
-
- msg->newMessageFast(_PREHASH_GodKickUser);
- msg->nextBlockFast(_PREHASH_UserInfo);
- msg->addUUIDFast(_PREHASH_GodID, gAgent.getID() );
- msg->addUUIDFast(_PREHASH_GodSessionID, gAgent.getSessionID());
- msg->addUUIDFast(_PREHASH_AgentID, avatar_id );
- msg->addU32("KickFlags", KICK_FLAGS_DEFAULT );
- msg->addStringFast(_PREHASH_Reason, response["message"].asString() );
- gAgent.sendReliableMessage();
+ status = "online";
}
- return false;
+
+ mStatusCombobox->setValue(status);
}
-// static
-void LLPanelAvatar::onClickFreeze(void* userdata)
+void LLPanelAvatarMeProfile::resetControls()
{
- LLPanelAvatar* self = (LLPanelAvatar*) userdata;
- LLSD payload;
- payload["avatar_id"] = self->mAvatarID;
- LLNotifications::instance().add("FreezeUser", LLSD(), payload, LLPanelAvatar::finishFreeze);
+ childSetVisible("status_panel", false);
+ childSetVisible("profile_buttons_panel", false);
+ childSetVisible("title_groups_text", false);
+ childSetVisible("sl_groups", false);
+ childSetVisible("status_me_panel", true);
+ childSetVisible("profile_me_buttons_panel", true);
}
-// static
-bool LLPanelAvatar::finishFreeze(const LLSD& notification, const LLSD& response)
+void LLPanelAvatarMeProfile::onStatusChanged()
{
- S32 option = LLNotification::getSelectedOption(notification, response);
+ LLSD::String status = mStatusCombobox->getValue().asString();
- if (option == 0)
+ if ("online" == status)
{
- LLUUID avatar_id = notification["payload"]["avatar_id"].asUUID();
- LLMessageSystem* msg = gMessageSystem;
-
- msg->newMessageFast(_PREHASH_GodKickUser);
- msg->nextBlockFast(_PREHASH_UserInfo);
- msg->addUUIDFast(_PREHASH_GodID, gAgent.getID() );
- msg->addUUIDFast(_PREHASH_GodSessionID, gAgent.getSessionID());
- msg->addUUIDFast(_PREHASH_AgentID, avatar_id );
- msg->addU32("KickFlags", KICK_FLAGS_FREEZE );
- msg->addStringFast(_PREHASH_Reason, response["message"].asString() );
- gAgent.sendReliableMessage();
+ gAgent.clearAFK();
+ gAgent.clearBusy();
}
- return false;
-}
-
-// static
-void LLPanelAvatar::onClickUnfreeze(void* userdata)
-{
- LLPanelAvatar* self = (LLPanelAvatar*) userdata;
- LLSD payload;
- payload["avatar_id"] = self->mAvatarID;
- LLNotifications::instance().add("UnFreezeUser", LLSD(), payload, LLPanelAvatar::finishUnfreeze);
-}
-
-// static
-bool LLPanelAvatar::finishUnfreeze(const LLSD& notification, const LLSD& response)
-{
- S32 option = LLNotification::getSelectedOption(notification, response);
- std::string text = response["message"].asString();
- if (option == 0)
+ else if ("away" == status)
{
- LLUUID avatar_id = notification["payload"]["avatar_id"].asUUID();
- LLMessageSystem* msg = gMessageSystem;
-
- msg->newMessageFast(_PREHASH_GodKickUser);
- msg->nextBlockFast(_PREHASH_UserInfo);
- msg->addUUIDFast(_PREHASH_GodID, gAgent.getID() );
- msg->addUUIDFast(_PREHASH_GodSessionID, gAgent.getSessionID());
- msg->addUUIDFast(_PREHASH_AgentID, avatar_id );
- msg->addU32("KickFlags", KICK_FLAGS_UNFREEZE );
- msg->addStringFast(_PREHASH_Reason, text );
- gAgent.sendReliableMessage();
+ gAgent.clearBusy();
+ gAgent.setAFK();
}
- return false;
-}
-
-// static
-void LLPanelAvatar::onClickCSR(void* userdata)
-{
- LLPanelAvatar* self = (LLPanelAvatar*)userdata;
- if (!self) return;
-
- LLNameEditor* name_edit = self->getChild<LLNameEditor>("name");
- if (!name_edit) return;
-
- std::string name = name_edit->getText();
- if (name.empty()) return;
-
- std::string url = "http://csr.lindenlab.com/agent/";
-
- // slow and stupid, but it's late
- S32 len = name.length();
- for (S32 i = 0; i < len; i++)
+ else if ("busy" == status)
{
- if (name[i] == ' ')
- {
- url += "%20";
- }
- else
- {
- url += name[i];
- }
+ gAgent.clearAFK();
+ gAgent.setBusy();
+ LLNotifications::instance().add("BusyModeSet");
}
-
- LLWeb::loadURL(url);
-}
-
-
-void* LLPanelAvatar::createPanelAvatarSecondLife(void* data)
-{
- LLPanelAvatar* self = (LLPanelAvatar*)data;
- self->mPanelSecondLife = new LLPanelAvatarSecondLife(std::string("2nd Life"),LLRect(),self);
- return self->mPanelSecondLife;
-}
-
-void* LLPanelAvatar::createPanelAvatarWeb(void* data)
-{
- LLPanelAvatar* self = (LLPanelAvatar*)data;
- self->mPanelWeb = new LLPanelAvatarWeb(std::string("Web"),LLRect(),self);
- return self->mPanelWeb;
}
-void* LLPanelAvatar::createPanelAvatarInterests(void* data)
-{
- LLPanelAvatar* self = (LLPanelAvatar*)data;
- self->mPanelAdvanced = new LLPanelAvatarAdvanced(std::string("Interests"),LLRect(),self);
- return self->mPanelAdvanced;
-}
-
-
-void* LLPanelAvatar::createPanelAvatarPicks(void* data)
+void LLPanelAvatarMeProfile::onStatusMessageChanged()
{
- LLPanelAvatar* self = (LLPanelAvatar*)data;
- self->mPanelPicks = new LLPanelAvatarPicks(std::string("Picks"),LLRect(),self);
- return self->mPanelPicks;
+ updateData();
}
-void* LLPanelAvatar::createPanelAvatarClassified(void* data)
+void LLPanelAvatarMeProfile::onUpdateAccountTextboxClicked()
{
- LLPanelAvatar* self = (LLPanelAvatar*)data;
- self->mPanelClassified = new LLPanelAvatarClassified(std::string("Classified"),LLRect(),self);
- return self->mPanelClassified;
+ onUrlTextboxClicked(getString("payment_update_link_url"));
}
-void* LLPanelAvatar::createPanelAvatarFirstLife(void* data)
+void LLPanelAvatarMeProfile::onMyAccountTextboxClicked()
{
- LLPanelAvatar* self = (LLPanelAvatar*)data;
- self->mPanelFirstLife = new LLPanelAvatarFirstLife(std::string("1st Life"), LLRect(), self);
- return self->mPanelFirstLife;
+ onUrlTextboxClicked(getString("my_account_link_url"));
}
-void* LLPanelAvatar::createPanelAvatarNotes(void* data)
+void LLPanelAvatarMeProfile::onPartnerEditTextboxClicked()
{
- LLPanelAvatar* self = (LLPanelAvatar*)data;
- self->mPanelNotes = new LLPanelAvatarNotes(std::string("My Notes"),LLRect(),self);
- return self->mPanelNotes;
+ onUrlTextboxClicked(getString("partner_edit_link_url"));
}
diff --git a/indra/newview/llpanelavatar.h b/indra/newview/llpanelavatar.h
index 12e1b99360..51bd619901 100644
--- a/indra/newview/llpanelavatar.h
+++ b/indra/newview/llpanelavatar.h
@@ -34,28 +34,10 @@
#define LL_LLPANELAVATAR_H
#include "llpanel.h"
-#include "v3dmath.h"
-#include "lluuid.h"
-#include "llwebbrowserctrl.h"
-
-class LLButton;
-class LLCheckBoxCtrl;
-class LLDropTarget;
-class LLInventoryItem;
+#include "llavatarpropertiesprocessor.h"
+
+class LLComboBox;
class LLLineEditor;
-class LLNameEditor;
-class LLPanelAvatar;
-class LLScrollListCtrl;
-class LLTabContainer;
-class LLTextBox;
-class LLTextEditor;
-class LLTextureCtrl;
-class LLUICtrl;
-class LLViewerImage;
-class LLViewerObject;
-class LLMessageSystem;
-class LLIconCtrl;
-class LLWebBrowserCtrl;
enum EOnlineStatus
{
@@ -63,321 +45,209 @@ enum EOnlineStatus
ONLINE_STATUS_YES = 1
};
-// Base class for all sub-tabs inside the avatar profile. Many of these
-// panels need to keep track of the parent panel (to get the avatar id)
-// and only request data from the database when they are first drawn. JC
-class LLPanelAvatarTab : public LLPanel
+/**
+* Base class for any Profile View or Me Profile Panel.
+*/
+class LLPanelProfileTab
+ : public LLPanel
+ , public LLAvatarPropertiesObserver
{
public:
- LLPanelAvatarTab(const std::string& name, const LLRect &rect,
- LLPanelAvatar* panel_avatar);
-
- // Calls refresh() once per frame when panel is visible
- /*virtual*/ void draw();
-
- LLPanelAvatar* getPanelAvatar() const { return mPanelAvatar; }
-
- void setDataRequested(bool requested) { mDataRequested = requested; }
- bool isDataRequested() const { return mDataRequested; }
- // If the data for this tab has not yet been requested,
- // send the request. Used by tabs that are filled in only
- // when they are first displayed.
- // type is one of "avatarnotesrequest", "avatarpicksrequest",
- // or "avatarclassifiedsrequest"
- void sendAvatarProfileRequestIfNeeded(const std::string& method);
+ /**
+ * Sets avatar ID, sets panel as observer of avatar related info replies from server.
+ */
+ virtual void setAvatarId(const LLUUID& id);
+
+ /**
+ * Returns avatar ID.
+ */
+ virtual const LLUUID& getAvatarId() { return mAvatarId; }
+
+ /**
+ * Sends update data request to server.
+ */
+ virtual void updateData() = 0;
+
+ /**
+ * Clears panel data if viewing avatar info for first time and sends update data request.
+ */
+ virtual void onOpen(const LLSD& key);
+
+ /**
+ * Profile tabs should close any opened panels here.
+ *
+ * Called from LLPanelProfile::onOpen() before opening new profile.
+ * See LLPanelpicks::onClose for example. LLPanelPicks closes picture info panel
+ * before new profile is displayed, otherwise new profile will
+ * be hidden behind picture info panel.
+ */
+ virtual void onClose() {}
+
+ /**
+ * Resets controls visibility, state, etc.
+ */
+ virtual void resetControls(){};
+
+ /**
+ * Clears all data received from server.
+ */
+ virtual void resetData(){};
+
+ /*virtual*/ ~LLPanelProfileTab();
+
+protected:
+
+ LLPanelProfileTab();
+
+ /**
+ * Scrolls panel to top when viewing avatar info for first time.
+ */
+ void scrollToTop();
private:
- LLPanelAvatar* mPanelAvatar;
- bool mDataRequested;
-};
-
-
-class LLPanelAvatarFirstLife : public LLPanelAvatarTab
-{
-public:
- LLPanelAvatarFirstLife(const std::string& name, const LLRect &rect, LLPanelAvatar* panel_avatar);
-
- /*virtual*/ BOOL postBuild(void);
- void enableControls(BOOL own_avatar);
+ LLUUID mAvatarId;
};
-
-class LLPanelAvatarSecondLife
-: public LLPanelAvatarTab
+/**
+* Panel for displaying Avatar's first and second life related info.
+*/
+class LLPanelAvatarProfile
+ : public LLPanelProfileTab
{
public:
- LLPanelAvatarSecondLife(const std::string& name, const LLRect &rect, LLPanelAvatar* panel_avatar );
-
- /*virtual*/ BOOL postBuild(void);
- /*virtual*/ void refresh();
-
- static void onClickImage( void *userdata);
- static void onClickFriends( void *userdata);
- static void onDoubleClickGroup(void* userdata);
- static void onClickPublishHelp(void *userdata);
- static void onClickPartnerHelp(void *userdata);
- static bool onClickPartnerHelpLoadURL(const LLSD& notification, const LLSD& response);
- static void onClickPartnerInfo(void *userdata);
-
- // Clear out the controls anticipating new network data.
- void clearControls();
- void enableControls(BOOL own_avatar);
- void updateOnlineText(BOOL online, BOOL have_calling_card);
- void updatePartnerName();
-
- void setPartnerID(LLUUID id) { mPartnerID = id; }
-
-private:
- LLUUID mPartnerID;
-};
+ LLPanelAvatarProfile();
+ /*virtual*/ void onOpen(const LLSD& key);
-// WARNING! The order of the inheritance here matters!! Do not change. - KLW
-class LLPanelAvatarWeb :
- public LLPanelAvatarTab
- , public LLWebBrowserCtrlObserver
-{
-public:
- LLPanelAvatarWeb(const std::string& name, const LLRect& rect, LLPanelAvatar* panel_avatar);
- /*virtual*/ ~LLPanelAvatarWeb();
- /*virtual*/ BOOL postBuild(void);
+ /**
+ * Processes data received from server.
+ */
+ /*virtual*/ void processProperties(void* data, EAvatarProcessorType type);
- /*virtual*/ void refresh();
+ /*virtual*/ BOOL postBuild();
- void enableControls(BOOL own_avatar);
+ /*virtual*/ void updateData();
- void setWebURL(std::string url);
+ /*virtual*/ void resetControls();
- void load(std::string url);
- static void onURLKeystroke(LLLineEditor* editor, void* data);
- static void onCommitLoad(LLUICtrl* ctrl, void* data);
- static void onCommitURL(LLUICtrl* ctrl, void* data);
- static void onClickWebProfileHelp(void *);
+ /*virtual*/ void resetData();
- // browser observer impls
- virtual void onStatusTextChange( const EventType& eventIn );
- virtual void onLocationChange( const EventType& eventIn );
+protected:
-private:
- std::string mHome;
- std::string mNavigateTo;
- LLWebBrowserCtrl* mWebBrowser;
-};
-
-
-class LLPanelAvatarAdvanced : public LLPanelAvatarTab
-{
-public:
- LLPanelAvatarAdvanced(const std::string& name, const LLRect& rect, LLPanelAvatar* panel_avatar);
-
- /*virtual*/ BOOL postBuild(void);
-
- void enableControls(BOOL own_avatar);
- void setWantSkills(U32 want_to_mask, const std::string& want_to_text,
- U32 skills_mask, const std::string& skills_text,
- const std::string& languages_text);
- void getWantSkills(U32* want_to_mask, std::string& want_to_text,
- U32* skills_mask, std::string& skills_text,
- std::string& languages_text);
-
-private:
- S32 mWantToCount;
- S32 mSkillsCount;
- LLCheckBoxCtrl *mWantToCheck[8];
- LLLineEditor *mWantToEdit;
- LLCheckBoxCtrl *mSkillsCheck[8];
- LLLineEditor *mSkillsEdit;
-};
-
-
-class LLPanelAvatarNotes : public LLPanelAvatarTab
-{
-public:
- LLPanelAvatarNotes(const std::string& name, const LLRect& rect, LLPanelAvatar* panel_avatar);
+ /**
+ * Process profile related data received from server.
+ */
+ virtual void processProfileProperties(const LLAvatarData* avatar_data);
- /*virtual*/ BOOL postBuild(void);
+ /**
+ * Processes group related data received from server.
+ */
+ virtual void processGroupProperties(const LLAvatarGroups* avatar_groups);
- /*virtual*/ void refresh();
+ /**
+ * Fills common for Avatar profile and Me Profile fields.
+ */
+ virtual void fillCommonData(const LLAvatarData* avatar_data);
- void clearControls();
+ /**
+ * Fills partner data.
+ */
+ virtual void fillPartnerData(const LLAvatarData* avatar_data);
- static void onCommitNotes(LLUICtrl* field, void* userdata);
+ /**
+ * Fills Avatar's online status.
+ */
+ virtual void fillOnlineStatus(const LLAvatarData* avatar_data);
+
+ /**
+ * Fills account status.
+ */
+ virtual void fillAccountStatus(const LLAvatarData* avatar_data);
+
+ void onUrlTextboxClicked(std::string url);
+ void onHomepageTextboxClicked();
+ void onAddFriendButtonClick();
+ void onIMButtonClick();
+ void onCallButtonClick();
+ void onTeleportButtonClick();
+ void onShareButtonClick();
};
-
-class LLPanelAvatarClassified : public LLPanelAvatarTab
+/**
+ * Panel for displaying own first and second life related info.
+ */
+class LLPanelAvatarMeProfile
+ : public LLPanelAvatarProfile
{
public:
- LLPanelAvatarClassified(const std::string& name, const LLRect& rect, LLPanelAvatar* panel_avatar);
-
- /*virtual*/ BOOL postBuild(void);
-
- /*virtual*/ void refresh();
-
- // If can close, return TRUE. If cannot close, pop save/discard dialog
- // and return FALSE.
- BOOL canClose();
-
- void apply();
-
- BOOL titleIsValid();
+ LLPanelAvatarMeProfile();
- // Delete all the classified sub-panels from the tab container
- void deleteClassifiedPanels();
+ /*virtual*/ BOOL postBuild();
- // Unpack the outline of classified for this avatar (count, names, but not
- // actual data).
- void processAvatarClassifiedReply(LLMessageSystem* msg, void**);
-
-private:
- static void onClickNew(void* data);
- static void onClickDelete(void* data);
-
- bool callbackDelete(const LLSD& notification, const LLSD& response);
- bool callbackNew(const LLSD& notification, const LLSD& response);
-};
+protected:
+ /*virtual*/ void onOpen(const LLSD& key);
-class LLPanelAvatarPicks : public LLPanelAvatarTab
-{
-public:
- LLPanelAvatarPicks(const std::string& name, const LLRect& rect, LLPanelAvatar* panel_avatar);
+ /*virtual*/ void processProfileProperties(const LLAvatarData* avatar_data);
- /*virtual*/ BOOL postBuild(void);
+ /**
+ * Fills Avatar status data.
+ */
+ virtual void fillStatusData(const LLAvatarData* avatar_data);
- /*virtual*/ void refresh();
+ /*virtual*/ void resetControls();
- // Delete all the pick sub-panels from the tab container
- void deletePickPanels();
+protected:
- // Unpack the outline of picks for this avatar (count, names, but not
- // actual data).
- void processAvatarPicksReply(LLMessageSystem* msg, void**);
- void processAvatarClassifiedReply(LLMessageSystem* msg, void**);
+ void onStatusChanged();
+ void onStatusMessageChanged();
+ void onUpdateAccountTextboxClicked();
+ void onMyAccountTextboxClicked();
+ void onPartnerEditTextboxClicked();
private:
- static void onClickNew(void* data);
- static void onClickDelete(void* data);
- bool callbackDelete(const LLSD& notification, const LLSD& response);
+ LLComboBox* mStatusCombobox;
};
-
-class LLPanelAvatar : public LLPanel
+/**
+* Panel for displaying Avatar's notes and modifying friend's rights.
+*/
+class LLPanelAvatarNotes
+ : public LLPanelProfileTab
{
public:
- LLPanelAvatar(const std::string& name, const LLRect &rect, BOOL allow_edit);
- /*virtual*/ ~LLPanelAvatar();
+ LLPanelAvatarNotes();
- /*virtual*/ BOOL postBuild(void);
+ /*virtual*/ void onOpen(const LLSD& key);
- // If can close, return TRUE. If cannot close, pop save/discard dialog
- // and return FALSE.
- BOOL canClose();
+ /*virtual*/ BOOL postBuild();
- void setAvatar(LLViewerObject *avatarp);
+ /*virtual*/ void processProperties(void* data, EAvatarProcessorType type);
- // Fill in the avatar ID and handle some field fill-in, as well as
- // button enablement.
- // Pass one of the ONLINE_STATUS_foo constants above.
- void setAvatarID(const LLUUID &avatar_id, const std::string &name, EOnlineStatus online_status);
+ /*virtual*/ void updateData();
- void setOnlineStatus(EOnlineStatus online_status);
+protected:
- const LLUUID& getAvatarID() const { return mAvatarID; }
-
- void resetGroupList();
+ /*virtual*/ void resetControls();
- void sendAvatarStatisticsRequest();
+ /*virtual*/ void resetData();
- void sendAvatarPropertiesRequest();
- void sendAvatarPropertiesUpdate();
+ /**
+ * Fills rights data for friends.
+ */
+ void fillRightsData();
- void sendAvatarNotesRequest();
- void sendAvatarNotesUpdate();
+ void onCommitRights();
+ void onCommitNotes();
- void sendAvatarPicksRequest();
-
- void selectTab(S32 tabnum);
- void selectTabByName(std::string tab_name);
-
- BOOL haveData() { return mHaveProperties && mHaveStatistics; }
- BOOL isEditable() const { return mAllowEdit; }
-
- static void processAvatarPropertiesReply(LLMessageSystem *msg, void **);
- static void processAvatarInterestsReply(LLMessageSystem *msg, void **);
- static void processAvatarGroupsReply(LLMessageSystem* msg, void**);
- static void processAvatarNotesReply(LLMessageSystem *msg, void **);
- static void processAvatarPicksReply(LLMessageSystem *msg, void **);
- static void processAvatarClassifiedReply(LLMessageSystem *msg, void **);
-
- static void onClickTrack( void *userdata);
- static void onClickIM( void *userdata);
- static void onClickOfferTeleport( void *userdata);
- static void onClickPay( void *userdata);
- static void onClickAddFriend(void* userdata);
- static void onClickOK( void *userdata);
- static void onClickCancel( void *userdata);
- static void onClickKick( void *userdata);
- static void onClickFreeze( void *userdata);
- static void onClickUnfreeze(void *userdata);
- static void onClickCSR( void *userdata);
- static void onClickMute( void *userdata);
-
-private:
- void enableOKIfReady();
-
- static bool finishKick(const LLSD& notification, const LLSD& response);
- static bool finishFreeze(const LLSD& notification, const LLSD& response);
- static bool finishUnfreeze(const LLSD& notification, const LLSD& response);
-
- static void showProfileCallback(S32 option, void *userdata);
-
- static void* createPanelAvatar(void* data);
- static void* createFloaterAvatarInfo(void* data);
- static void* createPanelAvatarSecondLife(void* data);
- static void* createPanelAvatarWeb(void* data);
- static void* createPanelAvatarInterests(void* data);
- static void* createPanelAvatarPicks(void* data);
- static void* createPanelAvatarClassified(void* data);
- static void* createPanelAvatarFirstLife(void* data);
- static void* createPanelAvatarNotes(void* data);
-
-public:
- LLPanelAvatarSecondLife* mPanelSecondLife;
- LLPanelAvatarAdvanced* mPanelAdvanced;
- LLPanelAvatarClassified* mPanelClassified;
- LLPanelAvatarPicks* mPanelPicks;
- LLPanelAvatarNotes* mPanelNotes;
- LLPanelAvatarFirstLife* mPanelFirstLife;
- LLPanelAvatarWeb* mPanelWeb;
-
- LLDropTarget* mDropTarget;
-
- // Teen users are not allowed to see or enter data into the first life page,
- // or their own about/interests text entry fields.
- static BOOL sAllowFirstLife;
-
-private:
- LLUUID mAvatarID; // for which avatar is this window?
- BOOL mIsFriend; // Are we friends?
- BOOL mHaveProperties;
- BOOL mHaveStatistics;
- // only update note if data received from database and
- // note is changed from database version
- bool mHaveNotes;
- std::string mLastNotes;
- LLTabContainer* mTab;
- BOOL mAllowEdit;
-
- typedef std::list<LLPanelAvatar*> panel_list_t;
- static panel_list_t sAllPanels;
+ void onAddFriendButtonClick();
+ void onIMButtonClick();
+ void onCallButtonClick();
+ void onTeleportButtonClick();
+ void onShareButtonClick();
};
-// helper funcs
-void add_left_label(LLPanel *panel, const std::string& name, S32 y);
-
-
#endif // LL_LLPANELAVATAR_H
diff --git a/indra/newview/llpanelavatartag.cpp b/indra/newview/llpanelavatartag.cpp
new file mode 100644
index 0000000000..e66c36287b
--- /dev/null
+++ b/indra/newview/llpanelavatartag.cpp
@@ -0,0 +1,129 @@
+/**
+ * @file llpanelavatartag.cpp
+ * @brief Avatar tag panel
+ *
+ * $LicenseInfo:firstyear=2009&license=viewergpl$
+ *
+ * Copyright (c) 2009, Linden Research, Inc.
+ *
+ * Second Life Viewer Source Code
+ * The source code in this file ("Source Code") is provided by Linden Lab
+ * to you under the terms of the GNU General Public License, version 2.0
+ * ("GPL"), unless you have obtained a separate licensing agreement
+ * ("Other License"), formally executed by you and Linden Lab. Terms of
+ * the GPL can be found in doc/GPL-license.txt in this distribution, or
+ * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
+ *
+ * There are special exceptions to the terms and conditions of the GPL as
+ * it is applied to this Source Code. View the full text of the exception
+ * in the file doc/FLOSS-exception.txt in this software distribution, or
+ * online at
+ * http://secondlifegrid.net/programs/open_source/licensing/flossexception
+ *
+ * By copying, modifying or distributing this software, you acknowledge
+ * that you have read and understood your obligations described above,
+ * and agree to abide by those obligations.
+ *
+ * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+ * COMPLETENESS OR PERFORMANCE.
+ * $/LicenseInfo$
+ */
+
+#include "llviewerprecompiledheaders.h"
+
+#include "llpanelavatartag.h"
+
+#include "lluictrlfactory.h"
+#include "llavatariconctrl.h"
+#include "lltextbox.h"
+
+LLPanelAvatarTag::LLPanelAvatarTag(const LLUUID& key, const std::string im_time)
+ : LLPanel()
+ , mAvatarId(LLUUID::null)
+// , mFadeTimer()
+{
+ LLUICtrlFactory::getInstance()->buildPanel(this, "panel_avatar_tag.xml");
+ setLeftButtonClickCallback(boost::bind(&LLPanelAvatarTag::onClick, this));
+ setAvatarId(key);
+ setTime(im_time);
+}
+
+LLPanelAvatarTag::~LLPanelAvatarTag()
+{
+ // Name callbacks will be automatically disconnected since LLPanel is trackable
+}
+
+BOOL LLPanelAvatarTag::postBuild()
+{
+ mIcon = getChild<LLAvatarIconCtrl>("avatar_tag_icon");
+ mName = getChild<LLTextBox>("sender_tag_name");
+ mTime = getChild<LLTextBox>("tag_time");
+ return TRUE;
+}
+
+void LLPanelAvatarTag::draw()
+{
+
+ ///TODO: ANGELA do something similar to fade the panel out
+/* // HACK: assuming tooltip background is in ToolTipBGColor, perform fade out
+ LLColor4 bg_color = LLUIColorTable::instance().getColor( "ToolTipBgColor" );
+ if (tooltip_vis)
+ {
+ mToolTipFadeTimer.stop();
+ mToolTip->setBackgroundColor(bg_color);
+ }
+ else
+ {
+ if (!mToolTipFadeTimer.getStarted())
+ {
+ mToolTipFadeTimer.start();
+ }
+ F32 tool_tip_fade_time = gSavedSettings.getF32("ToolTipFadeTime");
+ bg_color.mV[VALPHA] = clamp_rescale(mToolTipFadeTimer.getElapsedTimeF32(), 0.f, tool_tip_fade_time, bg_color.mV[VALPHA], 0.f);
+ mToolTip->setBackgroundColor(bg_color);
+ }
+
+ // above interpolation of bg_color alpha is guaranteed to reach 0.f exactly
+ mToolTip->setVisible( bg_color.mV[VALPHA] != 0.f );
+ */
+}
+void LLPanelAvatarTag::setName(const std::string& name)
+{
+ if (mName)
+ mName->setText(name);
+}
+
+void LLPanelAvatarTag::setTime(const std::string& time)
+{
+ if (mTime)
+ mTime->setText(time);
+}
+
+
+void LLPanelAvatarTag::setAvatarId(const LLUUID& avatar_id)
+{
+ mAvatarId = avatar_id;
+ if (mIcon)
+ {
+ mIcon->setValue(avatar_id);
+ }
+ setName(std::string(mIcon->getFirstName()+ " "+ mIcon->getLastName()));
+}
+
+boost::signals2::connection LLPanelAvatarTag::setLeftButtonClickCallback(
+ const commit_callback_t& cb)
+{
+ return mCommitSignal.connect(cb);
+}
+
+BOOL LLPanelAvatarTag::handleMouseDown(S32 x, S32 y, MASK mask)
+{
+ onCommit();
+ return TRUE;
+}
+
+void LLPanelAvatarTag::onClick()
+{
+ // Do the on click stuff.
+}
diff --git a/indra/newview/llpanelavatartag.h b/indra/newview/llpanelavatartag.h
new file mode 100644
index 0000000000..d68b0d7299
--- /dev/null
+++ b/indra/newview/llpanelavatartag.h
@@ -0,0 +1,93 @@
+/**
+ * @file llpanelavatartag.h
+ * @brief Avatar row panel
+ *
+ * $LicenseInfo:firstyear=2009&license=viewergpl$
+ *
+ * Copyright (c) 2009, Linden Research, Inc.
+ *
+ * Second Life Viewer Source Code
+ * The source code in this file ("Source Code") is provided by Linden Lab
+ * to you under the terms of the GNU General Public License, version 2.0
+ * ("GPL"), unless you have obtained a separate licensing agreement
+ * ("Other License"), formally executed by you and Linden Lab. Terms of
+ * the GPL can be found in doc/GPL-license.txt in this distribution, or
+ * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
+ *
+ * There are special exceptions to the terms and conditions of the GPL as
+ * it is applied to this Source Code. View the full text of the exception
+ * in the file doc/FLOSS-exception.txt in this software distribution, or
+ * online at
+ * http://secondlifegrid.net/programs/open_source/licensing/flossexception
+ *
+ * By copying, modifying or distributing this software, you acknowledge
+ * that you have read and understood your obligations described above,
+ * and agree to abide by those obligations.
+ *
+ * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+ * COMPLETENESS OR PERFORMANCE.
+ * $/LicenseInfo$
+ */
+
+#ifndef LL_LLPANELAVATARTAG_H
+#define LL_LLPANELAVATARTAG_H
+
+#include "llpanel.h"
+#include "llavatarpropertiesprocessor.h"
+
+class LLAvatarIconCtrl;
+class LLTextBox;
+
+/**
+ * Avatar Tag panel.
+ *
+ * Test.
+ *
+ * Contains avatar name
+ * Provide methods for setting avatar id, state, muted status and speech power.
+ */
+class LLPanelAvatarTag : public LLPanel
+{
+public:
+ LLPanelAvatarTag(const LLUUID& key, const std::string im_time);
+ virtual ~LLPanelAvatarTag();
+
+ /**
+ * Set avatar ID.
+ *
+ * After the ID is set, it is possible to track the avatar status and get its name.
+ */
+ void setAvatarId(const LLUUID& avatar_id);
+ void setTime (const std::string& time);
+
+ const LLUUID& getAvatarId() const { return mAvatarId; }
+
+ /*virtual*/ BOOL postBuild();
+ /*virtual*/ void draw();
+
+ virtual boost::signals2::connection setLeftButtonClickCallback(
+ const commit_callback_t& cb);
+ virtual BOOL handleMouseDown(S32 x, S32 y, MASK mask);
+
+ void onClick();
+private:
+ void setName(const std::string& name);
+
+ /**
+ * Called by LLCacheName when the avatar name gets updated.
+ */
+ void nameUpdatedCallback(
+ const LLUUID& id,
+ const std::string& first,
+ const std::string& last,
+ BOOL is_group);
+
+ LLAvatarIconCtrl* mIcon; /// status tracking avatar icon
+ LLTextBox* mName; /// displays avatar name
+ LLTextBox* mTime; /// displays time
+ LLUUID mAvatarId;
+// LLFrameTimer mFadeTimer;
+};
+
+#endif
diff --git a/indra/newview/llpanelclassified.cpp b/indra/newview/llpanelclassified.cpp
index 9e4f9709a8..c77d089af7 100644
--- a/indra/newview/llpanelclassified.cpp
+++ b/indra/newview/llpanelclassified.cpp
@@ -40,11 +40,14 @@
#include "lldir.h"
#include "lldispatcher.h"
+#include "llfloaterreg.h"
#include "llparcel.h"
+#include "lltabcontainer.h"
#include "message.h"
#include "llagent.h"
#include "llalertdialog.h"
+#include "llavataractions.h"
#include "llbutton.h"
#include "llcheckboxctrl.h"
#include "llclassifiedflags.h"
@@ -52,13 +55,10 @@
#include "llcommandhandler.h" // for classified HTML detail page click tracking
#include "llviewercontrol.h"
#include "lllineeditor.h"
-#include "llfloateravatarinfo.h"
-#include "llfloaterclassified.h"
-#include "lltabcontainervertical.h"
#include "lltextbox.h"
#include "llcombobox.h"
-#include "llviewertexteditor.h"
#include "lltexturectrl.h"
+#include "lltexteditor.h"
#include "lluiconstants.h"
#include "llurldispatcher.h" // for classified HTML detail click teleports
#include "lluictrlfactory.h"
@@ -70,6 +70,7 @@
#include "llviewerregion.h"
#include "llviewerwindow.h" // for window width, height
#include "llappviewer.h" // abortQuit()
+#include "lltrans.h"
const S32 MINIMUM_PRICE_FOR_LISTING = 50; // L$
const S32 MATURE_UNDEFINED = -1;
@@ -141,7 +142,7 @@ public:
const bool from_search = true;
LLPanelClassified::sendClassifiedClickMessage(classified_id, "teleport", from_search);
// Invoke teleport
- LLWebBrowserCtrl* web = NULL;
+ LLMediaCtrl* web = NULL;
const bool trusted_browser = true;
return LLURLDispatcher::dispatch(url, web, trusted_browser);
}
@@ -151,7 +152,7 @@ LLClassifiedTeleportHandler gClassifiedTeleportHandler;
*/
LLPanelClassified::LLPanelClassified(bool in_finder, bool from_search)
-: LLPanel(std::string("Classified Panel")),
+: LLPanel(),
mInFinder(in_finder),
mFromSearch(from_search),
mDirty(false),
@@ -231,44 +232,36 @@ void LLPanelClassified::reset()
BOOL LLPanelClassified::postBuild()
{
mSnapshotCtrl = getChild<LLTextureCtrl>("snapshot_ctrl");
- mSnapshotCtrl->setCommitCallback(onCommitAny);
- mSnapshotCtrl->setCallbackUserData(this);
+ mSnapshotCtrl->setCommitCallback(onCommitAny, this);
mSnapshotSize = mSnapshotCtrl->getRect();
mNameEditor = getChild<LLLineEditor>("given_name_editor");
mNameEditor->setMaxTextLength(DB_PARCEL_NAME_LEN);
mNameEditor->setCommitOnFocusLost(TRUE);
mNameEditor->setFocusReceivedCallback(focusReceived, this);
- mNameEditor->setCommitCallback(onCommitAny);
- mNameEditor->setCallbackUserData(this);
+ mNameEditor->setCommitCallback(onCommitAny, this);
mNameEditor->setPrevalidate( LLLineEditor::prevalidateASCII );
mDescEditor = getChild<LLTextEditor>("desc_editor");
mDescEditor->setCommitOnFocusLost(TRUE);
mDescEditor->setFocusReceivedCallback(focusReceived, this);
- mDescEditor->setCommitCallback(onCommitAny);
- mDescEditor->setCallbackUserData(this);
- mDescEditor->setTabsToNextField(TRUE);
-
+ mDescEditor->setCommitCallback(onCommitAny, this);
+
mLocationEditor = getChild<LLLineEditor>("location_editor");
mSetBtn = getChild<LLButton>( "set_location_btn");
- mSetBtn->setClickedCallback(onClickSet);
- mSetBtn->setCallbackUserData(this);
+ mSetBtn->setClickedCallback(onClickSet, this);
mTeleportBtn = getChild<LLButton>( "classified_teleport_btn");
- mTeleportBtn->setClickedCallback(onClickTeleport);
- mTeleportBtn->setCallbackUserData(this);
+ mTeleportBtn->setClickedCallback(onClickTeleport, this);
mMapBtn = getChild<LLButton>( "classified_map_btn");
- mMapBtn->setClickedCallback(onClickMap);
- mMapBtn->setCallbackUserData(this);
+ mMapBtn->setClickedCallback(onClickMap, this);
if(mInFinder)
{
mProfileBtn = getChild<LLButton>( "classified_profile_btn");
- mProfileBtn->setClickedCallback(onClickProfile);
- mProfileBtn->setCallbackUserData(this);
+ mProfileBtn->setClickedCallback(onClickProfile, this);
}
mCategoryCombo = getChild<LLComboBox>( "classified_category_combo");
@@ -277,16 +270,14 @@ BOOL LLPanelClassified::postBuild()
iter != LLClassifiedInfo::sCategories.end();
iter++)
{
- mCategoryCombo->add(iter->second, (void *)((intptr_t)iter->first), ADD_BOTTOM);
+ mCategoryCombo->add(LLTrans::getString(iter->second), (void *)((intptr_t)iter->first), ADD_BOTTOM);
}
mCategoryCombo->setCurrentByIndex(0);
- mCategoryCombo->setCommitCallback(onCommitAny);
- mCategoryCombo->setCallbackUserData(this);
+ mCategoryCombo->setCommitCallback(onCommitAny, this);
mMatureCombo = getChild<LLComboBox>( "classified_mature_check");
mMatureCombo->setCurrentByIndex(0);
- mMatureCombo->setCommitCallback(onCommitAny);
- mMatureCombo->setCallbackUserData(this);
+ mMatureCombo->setCommitCallback(onCommitAny, this);
if (gAgent.wantsPGOnly())
{
// Teens don't get to set mature flag. JC
@@ -297,13 +288,11 @@ BOOL LLPanelClassified::postBuild()
if (!mInFinder)
{
mAutoRenewCheck = getChild<LLCheckBoxCtrl>( "auto_renew_check");
- mAutoRenewCheck->setCommitCallback(onCommitAny);
- mAutoRenewCheck->setCallbackUserData(this);
+ mAutoRenewCheck->setCommitCallback(onCommitAny, this);
}
mUpdateBtn = getChild<LLButton>("classified_update_btn");
- mUpdateBtn->setClickedCallback(onClickUpdate);
- mUpdateBtn->setCallbackUserData(this);
+ mUpdateBtn->setClickedCallback(onClickUpdate, this);
if (!mInFinder)
{
@@ -360,7 +349,7 @@ bool LLPanelClassified::saveCallback(const LLSD& notification, const LLSD& respo
LLFloater* parent_floater = gFloaterView->getParentFloater(this);
if (parent_floater)
{
- parent_floater->close();
+ parent_floater->closeFloater();
}
}
break;
@@ -455,10 +444,11 @@ void LLPanelClassified::setClickThrough(const LLUUID& classified_id,
if (self->mClickThroughText)
{
- std::string msg = llformat("Clicks: %d teleport, %d map, %d profile",
- self->mTeleportClicksNew + self->mTeleportClicksOld,
- self->mMapClicksNew + self->mMapClicksOld,
- self->mProfileClicksNew + self->mProfileClicksOld);
+ LLStringUtil::format_map_t args;
+ args["[TELEPORT]"] = llformat ("%d", self->mTeleportClicksNew + self->mTeleportClicksOld);
+ args["[MAP]"] = llformat ("%d", self->mMapClicksNew + self->mMapClicksOld);
+ args["[PROFILE]"] = llformat ("%d", self->mProfileClicksNew + self->mProfileClicksOld);
+ std::string msg = LLTrans::getString ("ClassifiedClicksTxt", args);
self->mClickThroughText->setText(msg);
}
}
@@ -623,7 +613,6 @@ void LLPanelClassified::processClassifiedInfoReply(LLMessageSystem *msg, void **
U32 date = 0;
msg->getU32Fast(_PREHASH_Data, _PREHASH_CreationDate, date);
time_t tim = date;
- tm *now=localtime(&tim);
// future use
U32 expiration_date = 0;
@@ -674,9 +663,13 @@ void LLPanelClassified::processClassifiedInfoReply(LLMessageSystem *msg, void **
self->mAutoRenewCheck->set(auto_renew);
}
- std::string datestr = llformat("%02d/%02d/%d", now->tm_mon+1, now->tm_mday, now->tm_year+1900);
+ std::string dateStr = self->getString("dateStr");
+ LLSD substitution;
+ substitution["datetime"] = (S32) tim;
+ LLStringUtil::format (dateStr, substitution);
+
LLStringUtil::format_map_t string_args;
- string_args["[DATE]"] = datestr;
+ string_args["[DATE]"] = dateStr;
string_args["[AMT]"] = llformat("%d", price_for_listing);
self->childSetText("classified_info_text", self->getString("ad_placed_paid", string_args));
@@ -846,7 +839,7 @@ void LLPanelClassified::gotMature()
if (mPaidFor)
{
LLNotification::Params params("PublishClassified");
- params.functor(boost::bind(&LLPanelClassified::confirmPublish, this, _1, _2));
+ params.functor.function(boost::bind(&LLPanelClassified::confirmPublish, this, _1, _2));
LLNotifications::instance().forceResponse(params, 0);
}
else
@@ -937,12 +930,12 @@ bool LLPanelClassified::confirmPublish(const LLSD& notification, const LLSD& res
void LLPanelClassified::onClickTeleport(void* data)
{
LLPanelClassified* self = (LLPanelClassified*)data;
-
- if (!self->mPosGlobal.isExactlyZero())
+ LLFloaterWorldMap* worldmap_instance = LLFloaterWorldMap::getInstance();
+
+ if (!self->mPosGlobal.isExactlyZero()&&worldmap_instance)
{
- gAgent.teleportViaLocation(self->mPosGlobal);
- gFloaterWorldMap->trackLocation(self->mPosGlobal);
-
+ gAgent.teleportViaLocation(self->mPosGlobal);
+ worldmap_instance->trackLocation(self->mPosGlobal);
self->sendClassifiedClickMessage("teleport");
}
}
@@ -952,9 +945,12 @@ void LLPanelClassified::onClickTeleport(void* data)
void LLPanelClassified::onClickMap(void* data)
{
LLPanelClassified* self = (LLPanelClassified*)data;
- gFloaterWorldMap->trackLocation(self->mPosGlobal);
- LLFloaterWorldMap::show(NULL, TRUE);
-
+ LLFloaterWorldMap* worldmap_instance = LLFloaterWorldMap::getInstance();
+ if(worldmap_instance)
+ {
+ worldmap_instance->trackLocation(self->mPosGlobal);
+ LLFloaterReg::showInstance("world_map", "center");
+ }
self->sendClassifiedClickMessage("map");
}
@@ -962,7 +958,7 @@ void LLPanelClassified::onClickMap(void* data)
void LLPanelClassified::onClickProfile(void* data)
{
LLPanelClassified* self = (LLPanelClassified*)data;
- LLFloaterAvatarInfo::showFromDirectory(self->mCreatorID);
+ LLAvatarActions::showProfile(self->mCreatorID);
self->sendClassifiedClickMessage("profile");
}
@@ -984,7 +980,7 @@ void LLPanelClassified::onClickSet(void* data)
self->mPosGlobal = gAgent.getPositionGlobal();
std::string location_text;
- std::string regionName = "(will update after publish)";
+ std::string regionName = LLTrans::getString("ClassifiedUpdateAfterPublish");
LLViewerRegion* pRegion = gAgent.getRegion();
if (pRegion)
{
@@ -1065,7 +1061,7 @@ void LLPanelClassified::sendClassifiedClickMessage(const std::string& type)
////////////////////////////////////////////////////////////////////////////////////////////
LLFloaterPriceForListing::LLFloaterPriceForListing()
-: LLFloater(std::string("PriceForListing")),
+: LLFloater(LLSD()),
mCallback(NULL),
mUserData(NULL)
{ }
@@ -1101,7 +1097,7 @@ void LLFloaterPriceForListing::show( void (*callback)(S32, std::string, void*),
LLFloaterPriceForListing *self = new LLFloaterPriceForListing();
// Builds and adds to gFloaterView
- LLUICtrlFactory::getInstance()->buildFloater(self, "floater_price_for_listing.xml");
+ LLUICtrlFactory::getInstance()->buildFloater(self, "floater_price_for_listing.xml", NULL);
self->center();
self->mCallback = callback;
@@ -1129,7 +1125,7 @@ void LLFloaterPriceForListing::buttonCore(S32 button, void* data)
{
std::string text = self->childGetText("price_edit");
self->mCallback(button, text, self->mUserData);
- self->close();
+ self->closeFloater();
}
}
diff --git a/indra/newview/llpanelcontents.cpp b/indra/newview/llpanelcontents.cpp
index a2f3d9e12c..5da646497b 100644
--- a/indra/newview/llpanelcontents.cpp
+++ b/indra/newview/llpanelcontents.cpp
@@ -36,37 +36,33 @@
#include "llpanelcontents.h"
// linden library includes
+#include "lleconomy.h"
#include "llerror.h"
+#include "llfloaterreg.h"
+#include "llfontgl.h"
+#include "llmaterialtable.h"
+#include "llpermissionsflags.h"
#include "llrect.h"
#include "llstring.h"
-#include "llmaterialtable.h"
-#include "llfontgl.h"
+#include "llui.h"
#include "m3math.h"
-#include "llpermissionsflags.h"
-#include "lleconomy.h"
#include "material_codes.h"
// project includes
-#include "llui.h"
-#include "llspinctrl.h"
-#include "llcheckboxctrl.h"
-#include "lltextbox.h"
-#include "llbutton.h"
-#include "llcombobox.h"
-#include "llfloaterbulkpermission.h"
-
#include "llagent.h"
-#include "llviewerwindow.h"
-#include "llworld.h"
-#include "llviewerobject.h"
-#include "llviewerregion.h"
+#include "llfloaterbulkpermission.h"
+#include "llpanelinventory.h"
+#include "llpreviewscript.h"
#include "llresmgr.h"
#include "llselectmgr.h"
-#include "llpreviewscript.h"
#include "lltool.h"
-#include "lltoolmgr.h"
#include "lltoolcomp.h"
-#include "llpanelinventory.h"
+#include "lltoolmgr.h"
+#include "lltrans.h"
+#include "llviewerobject.h"
+#include "llviewerregion.h"
+#include "llviewerwindow.h"
+#include "llworld.h"
//
// Imported globals
@@ -86,11 +82,13 @@ BOOL LLPanelContents::postBuild()
childSetAction("button new script",&LLPanelContents::onClickNewScript, this);
childSetAction("button permissions",&LLPanelContents::onClickPermissions, this);
+ mPanelInventory = getChild<LLPanelInventory>("contents_inventory");
+
return TRUE;
}
-LLPanelContents::LLPanelContents(const std::string& name)
- : LLPanel(name),
+LLPanelContents::LLPanelContents()
+ : LLPanel(),
mPanelInventory(NULL)
{
}
@@ -171,7 +169,7 @@ void LLPanelContents::onClickNewScript(void *userdata)
LLUUID::null,
LLAssetType::AT_LSL_TEXT,
LLInventoryType::IT_LSL,
- std::string("New Script"),
+ LLTrans::getString("PanelContentsNewScript"),
desc,
LLSaleInfo::DEFAULT,
LLViewerInventoryItem::II_FLAGS_NONE,
@@ -185,21 +183,7 @@ void LLPanelContents::onClickNewScript(void *userdata)
// viewer so the viewer can auto-open the script and start
// editing ASAP.
#if 0
- S32 left, top;
- gFloaterView->getNewFloaterPosition(&left, &top);
- LLRect rect = gSavedSettings.getRect("PreviewScriptRect");
- rect.translate( left - rect.mLeft, top - rect.mTop );
-
- LLLiveLSLEditor* editor;
- editor = new LLLiveLSLEditor("script ed",
- rect,
- "Script: New Script",
- object->mID,
- LLUUID::null);
- editor->open(); /*Flawfinder: ignore*/
-
- // keep onscreen
- gFloaterView->adjustToFitScreen(editor, FALSE);
+ LLFloaterReg::showInstance("preview_scriptedit", LLSD(inv_item->getUUID()), TAKE_FOCUS_YES);
#endif
}
}
@@ -209,5 +193,5 @@ void LLPanelContents::onClickNewScript(void *userdata)
void LLPanelContents::onClickPermissions(void *userdata)
{
LLPanelContents* self = (LLPanelContents*)userdata;
- gFloaterView->getParentFloater(self)->addDependentFloater(LLFloaterBulkPermission::showInstance());
+ gFloaterView->getParentFloater(self)->addDependentFloater(LLFloaterReg::showInstance("bulk_perms"));
}
diff --git a/indra/newview/llpanelcontents.h b/indra/newview/llpanelcontents.h
index ea06707494..de1914bff9 100644
--- a/indra/newview/llpanelcontents.h
+++ b/indra/newview/llpanelcontents.h
@@ -46,7 +46,7 @@ class LLPanelContents : public LLPanel
{
public:
virtual BOOL postBuild();
- LLPanelContents(const std::string& name);
+ LLPanelContents();
virtual ~LLPanelContents();
void refresh();
diff --git a/indra/newview/llpanelface.cpp b/indra/newview/llpanelface.cpp
index e93a5be8ed..08a50d4b6e 100644
--- a/indra/newview/llpanelface.cpp
+++ b/indra/newview/llpanelface.cpp
@@ -62,6 +62,7 @@
#include "llviewerobject.h"
#include "llviewerstats.h"
#include "lluictrlfactory.h"
+#include "llpluginclassmedia.h"
//
// Methods
@@ -87,11 +88,10 @@ BOOL LLPanelFace::postBuild()
if(mTextureCtrl)
{
mTextureCtrl->setDefaultImageAssetID(LLUUID( gSavedSettings.getString( "DefaultObjectTexture" )));
- mTextureCtrl->setCommitCallback( LLPanelFace::onCommitTexture );
- mTextureCtrl->setOnCancelCallback( LLPanelFace::onCancelTexture );
- mTextureCtrl->setOnSelectCallback( LLPanelFace::onSelectTexture );
- mTextureCtrl->setDragCallback(LLPanelFace::onDragTexture);
- mTextureCtrl->setCallbackUserData( this );
+ mTextureCtrl->setCommitCallback( boost::bind(&LLPanelFace::onCommitTexture, this, _2) );
+ mTextureCtrl->setOnCancelCallback( boost::bind(&LLPanelFace::onCancelTexture, this, _2) );
+ mTextureCtrl->setOnSelectCallback( boost::bind(&LLPanelFace::onSelectTexture, this, _2) );
+ mTextureCtrl->setDragCallback(boost::bind(&LLPanelFace::onDragTexture, _2));
mTextureCtrl->setFollowsTop();
mTextureCtrl->setFollowsLeft();
// Don't allow (no copy) or (no transfer) textures to be selected during immediate mode
@@ -118,10 +118,9 @@ BOOL LLPanelFace::postBuild()
mColorSwatch = getChild<LLColorSwatchCtrl>("colorswatch");
if(mColorSwatch)
{
- mColorSwatch->setCommitCallback(LLPanelFace::onCommitColor);
- mColorSwatch->setOnCancelCallback(LLPanelFace::onCancelColor);
- mColorSwatch->setOnSelectCallback(LLPanelFace::onSelectColor);
- mColorSwatch->setCallbackUserData( this );
+ mColorSwatch->setCommitCallback(boost::bind(&LLPanelFace::onCommitColor, this, _2));
+ mColorSwatch->setOnCancelCallback(boost::bind(&LLPanelFace::onCancelColor, this, _2));
+ mColorSwatch->setOnSelectCallback(boost::bind(&LLPanelFace::onSelectColor, this, _2));
mColorSwatch->setFollowsTop();
mColorSwatch->setFollowsLeft();
mColorSwatch->setCanApplyImmediately(TRUE);
@@ -137,8 +136,7 @@ BOOL LLPanelFace::postBuild()
mCtrlColorTransp = getChild<LLSpinCtrl>("ColorTrans");
if(mCtrlColorTransp)
{
- mCtrlColorTransp->setCommitCallback(LLPanelFace::onCommitAlpha);
- mCtrlColorTransp->setCallbackUserData(this);
+ mCtrlColorTransp->setCommitCallback(boost::bind(&LLPanelFace::onCommitAlpha, this, _2));
mCtrlColorTransp->setPrecision(0);
mCtrlColorTransp->setFollowsTop();
mCtrlColorTransp->setFollowsLeft();
@@ -147,23 +145,20 @@ BOOL LLPanelFace::postBuild()
mCheckFullbright = getChild<LLCheckBoxCtrl>("checkbox fullbright");
if (mCheckFullbright)
{
- mCheckFullbright->setCommitCallback(LLPanelFace::onCommitFullbright);
- mCheckFullbright->setCallbackUserData( this );
+ mCheckFullbright->setCommitCallback(LLPanelFace::onCommitFullbright, this);
}
mComboTexGen = getChild<LLComboBox>("combobox texgen");
if(mComboTexGen)
{
- mComboTexGen->setCommitCallback(LLPanelFace::onCommitTexGen);
+ mComboTexGen->setCommitCallback(LLPanelFace::onCommitTexGen, this);
mComboTexGen->setFollows(FOLLOWS_LEFT | FOLLOWS_TOP);
- mComboTexGen->setCallbackUserData( this );
}
mCtrlGlow = getChild<LLSpinCtrl>("glow");
if(mCtrlGlow)
{
- mCtrlGlow->setCommitCallback(LLPanelFace::onCommitGlow);
- mCtrlGlow->setCallbackUserData(this);
+ mCtrlGlow->setCommitCallback(LLPanelFace::onCommitGlow, this);
}
childSetCommitCallback("combobox shininess",&LLPanelFace::onCommitShiny,this);
@@ -183,8 +178,8 @@ BOOL LLPanelFace::postBuild()
return TRUE;
}
-LLPanelFace::LLPanelFace(const std::string& name)
-: LLPanel(name)
+LLPanelFace::LLPanelFace()
+: LLPanel()
{
}
@@ -392,11 +387,6 @@ void LLPanelFace::getState()
childSetEnabled("button align",FALSE);
//mBtnAutoFix->setEnabled ( FALSE );
- if(LLViewerMedia::hasMedia())
- {
- childSetEnabled("textbox autofix",editable);
- childSetEnabled("button align",editable);
- }
//if ( LLMediaEngine::getInstance()->getMediaRenderer () )
// if ( LLMediaEngine::getInstance()->getMediaRenderer ()->isLoaded () )
// {
@@ -417,7 +407,7 @@ void LLPanelFace::getState()
{
LLUUID get(LLViewerObject* object, S32 te)
{
- LLViewerImage* image = object->getTEImage(te);
+ LLViewerTexture* image = object->getTEImage(te);
return image ? image->getID() : LLUUID::null;
}
} func;
@@ -453,7 +443,15 @@ void LLPanelFace::getState()
}
}
}
+
+ if(LLViewerMedia::textureHasMedia(id))
+ {
+ childSetEnabled("textbox autofix",editable);
+ childSetEnabled("button align",editable);
+ }
+
}
+
LLAggregatePermissions texture_perms;
if(texture_ctrl)
@@ -807,32 +805,25 @@ F32 LLPanelFace::valueGlow(LLViewerObject* object, S32 face)
}
-// static
-void LLPanelFace::onCommitColor(LLUICtrl* ctrl, void* userdata)
+void LLPanelFace::onCommitColor(const LLSD& data)
{
- LLPanelFace* self = (LLPanelFace*) userdata;
- self->sendColor();
+ sendColor();
}
-// static
-void LLPanelFace::onCommitAlpha(LLUICtrl* ctrl, void* userdata)
+void LLPanelFace::onCommitAlpha(const LLSD& data)
{
- LLPanelFace* self = (LLPanelFace*) userdata;
- self->sendAlpha();
+ sendAlpha();
}
-// static
-void LLPanelFace::onCancelColor(LLUICtrl* ctrl, void* userdata)
+void LLPanelFace::onCancelColor(const LLSD& data)
{
LLSelectMgr::getInstance()->selectionRevertColors();
}
-// static
-void LLPanelFace::onSelectColor(LLUICtrl* ctrl, void* userdata)
+void LLPanelFace::onSelectColor(const LLSD& data)
{
- LLPanelFace* self = (LLPanelFace*) userdata;
LLSelectMgr::getInstance()->saveSelectedObjectColors();
- self->sendColor();
+ sendColor();
}
// static
@@ -871,7 +862,7 @@ void LLPanelFace::onCommitGlow(LLUICtrl* ctrl, void* userdata)
}
// static
-BOOL LLPanelFace::onDragTexture(LLUICtrl*, LLInventoryItem* item, void*)
+BOOL LLPanelFace::onDragTexture(LLInventoryItem* item)
{
BOOL accept = TRUE;
for (LLObjectSelection::root_iterator iter = LLSelectMgr::getInstance()->getSelection()->root_begin();
@@ -888,28 +879,21 @@ BOOL LLPanelFace::onDragTexture(LLUICtrl*, LLInventoryItem* item, void*)
return accept;
}
-// static
-void LLPanelFace::onCommitTexture( LLUICtrl* ctrl, void* userdata )
+void LLPanelFace::onCommitTexture( const LLSD& data )
{
- LLPanelFace* self = (LLPanelFace*) userdata;
-
LLViewerStats::getInstance()->incStat(LLViewerStats::ST_EDIT_TEXTURE_COUNT );
-
- self->sendTexture();
+ sendTexture();
}
-// static
-void LLPanelFace::onCancelTexture(LLUICtrl* ctrl, void* userdata)
+void LLPanelFace::onCancelTexture(const LLSD& data)
{
LLSelectMgr::getInstance()->selectionRevertTextures();
}
-// static
-void LLPanelFace::onSelectTexture(LLUICtrl* ctrl, void* userdata)
+void LLPanelFace::onSelectTexture(const LLSD& data)
{
- LLPanelFace* self = (LLPanelFace*) userdata;
LLSelectMgr::getInstance()->saveSelectedObjectTextures();
- self->sendTexture();
+ sendTexture();
}
@@ -939,14 +923,18 @@ struct LLPanelFaceSetMediaFunctor : public LLSelectedTEFunctor
{
virtual bool apply(LLViewerObject* object, S32 te)
{
+ // TODO: the media impl pointer should actually be stored by the texture
+ viewer_media_t pMediaImpl = LLViewerMedia::getMediaImplFromTextureID(object->getTE ( te )->getID());
// only do this if it's a media texture
- if ( object->getTE ( te )->getID() == LLViewerMedia::getMediaTextureID() )
+ if ( pMediaImpl.notNull())
{
- S32 media_width, media_height;
- S32 texture_width, texture_height;
- if ( LLViewerMedia::getMediaSize( &media_width, &media_height )
- && LLViewerMedia::getTextureSize( &texture_width, &texture_height ) )
+ LLPluginClassMedia *media = pMediaImpl->getMediaPlugin();
+ if(media)
{
+ S32 media_width = media->getWidth();
+ S32 media_height = media->getHeight();
+ S32 texture_width = media->getTextureWidth();
+ S32 texture_height = media->getTextureHeight();
F32 scale_s = (F32)media_width / (F32)texture_width;
F32 scale_t = (F32)media_height / (F32)texture_height;
diff --git a/indra/newview/llpanelface.h b/indra/newview/llpanelface.h
index a2ead0c8a2..9600129696 100644
--- a/indra/newview/llpanelface.h
+++ b/indra/newview/llpanelface.h
@@ -52,7 +52,7 @@ class LLPanelFace : public LLPanel
{
public:
virtual BOOL postBuild();
- LLPanelFace(const std::string& name);
+ LLPanelFace();
virtual ~LLPanelFace();
void refresh();
@@ -70,17 +70,18 @@ protected:
void sendFullbright(); // applies and sends full bright
void sendGlow();
- // this function is to return TRUE if the dra should succeed.
- static BOOL onDragTexture(LLUICtrl* ctrl, LLInventoryItem* item, void* ud);
+ // this function is to return TRUE if the drag should succeed.
+ static BOOL onDragTexture(LLInventoryItem* item);
- static void onCommitTexture( LLUICtrl* ctrl, void* userdata);
- static void onCancelTexture( LLUICtrl* ctrl, void* userdata);
- static void onSelectTexture( LLUICtrl* ctrl, void* userdata);
- static void onCommitTextureInfo( LLUICtrl* ctrl, void* userdata);
- static void onCommitColor( LLUICtrl* ctrl, void* userdata);
- static void onCommitAlpha( LLUICtrl* ctrl, void* userdata);
- static void onCancelColor( LLUICtrl* ctrl, void* userdata);
- static void onSelectColor( LLUICtrl* ctrl, void* userdata);
+ void onCommitTexture(const LLSD& data);
+ void onCancelTexture(const LLSD& data);
+ void onSelectTexture(const LLSD& data);
+ void onCommitColor(const LLSD& data);
+ void onCommitAlpha(const LLSD& data);
+ void onCancelColor(const LLSD& data);
+ void onSelectColor(const LLSD& data);
+
+ static void onCommitTextureInfo( LLUICtrl* ctrl, void* userdata);
static void onCommitBump( LLUICtrl* ctrl, void* userdata);
static void onCommitTexGen( LLUICtrl* ctrl, void* userdata);
static void onCommitShiny( LLUICtrl* ctrl, void* userdata);
diff --git a/indra/newview/llpanelgroup.cpp b/indra/newview/llpanelgroup.cpp
index d9d796fd9e..4cbb018ce9 100644
--- a/indra/newview/llpanelgroup.cpp
+++ b/indra/newview/llpanelgroup.cpp
@@ -33,12 +33,7 @@
#include "llpanelgroup.h"
-#include "llagent.h"
#include "llbutton.h"
-#include "llpanelgroupgeneral.h"
-#include "llpanelgrouproles.h"
-#include "llpanelgrouplandmoney.h"
-#include "llpanelgroupnotices.h"
#include "lltabcontainer.h"
#include "lltextbox.h"
#include "llviewermessage.h"
@@ -46,17 +41,31 @@
#include "llviewerwindow.h"
#include "llappviewer.h"
#include "llnotifications.h"
+#include "llfloaterreg.h"
+#include "llfloater.h"
+
+#include "llsidetraypanelcontainer.h"
+
+#include "llpanelgroupnotices.h"
+#include "llpanelgroupgeneral.h"
+
+#include "llsidetray.h"
+#include "llaccordionctrltab.h"
-// static
-void* LLPanelGroupTab::createTab(void* data)
+static LLRegisterPanelClassWrapper<LLPanelGroup> t_panel_group("panel_group_info_sidetray");
+
+
+
+LLPanelGroupTab::LLPanelGroupTab()
+ : LLPanel(),
+ mAllowEdit(TRUE),
+ mHasModal(FALSE)
{
- LLUUID* group_id = static_cast<LLUUID*>(data);
- return new LLPanelGroupTab("panel group tab", *group_id);
+ mGroupID = LLUUID::null;
}
LLPanelGroupTab::~LLPanelGroupTab()
{
- mObservers.clear();
}
BOOL LLPanelGroupTab::isVisibleByAgent(LLAgent* agentp)
@@ -67,48 +76,10 @@ BOOL LLPanelGroupTab::isVisibleByAgent(LLAgent* agentp)
BOOL LLPanelGroupTab::postBuild()
{
- // Hook up the help button callback.
- LLButton* button = getChild<LLButton>("help_button");
- if (button)
- {
- button->setClickedCallback(onClickHelp);
- button->setCallbackUserData(this);
- }
-
- mHelpText = getString("help_text");
return TRUE;
}
-void LLPanelGroupTab::addObserver(LLPanelGroupTabObserver *obs)
-{
- mObservers.insert(obs);
-}
-void LLPanelGroupTab::removeObserver(LLPanelGroupTabObserver *obs)
-{
- mObservers.erase(obs);
-}
-
-void LLPanelGroupTab::notifyObservers()
-{
-
- for (observer_list_t::iterator iter = mObservers.begin();
- iter != mObservers.end(); )
- {
- LLPanelGroupTabObserver* observer = *iter;
- observer->tabChanged();
-
- // safe way to incrament since changed may delete entries! (@!##%@!@&*!)
- iter = mObservers.upper_bound(observer);
- }
-}
-
-// static
-void LLPanelGroupTab::onClickHelp(void* user_data)
-{
- LLPanelGroupTab* self = static_cast<LLPanelGroupTab*>(user_data);
- self->handleClickHelp();
-}
void LLPanelGroupTab::handleClickHelp()
{
@@ -125,450 +96,281 @@ void LLPanelGroupTab::handleClickHelp()
}
}
-LLPanelGroup::LLPanelGroup(const std::string& filename,
- const std::string& name,
- const LLUUID& group_id,
- const std::string& initial_tab_selected)
-: LLPanel(name, LLRect(), FALSE),
- LLGroupMgrObserver( group_id ),
- mCurrentTab( NULL ),
- mRequestedTab( NULL ),
- mTabContainer( NULL ),
- mIgnoreTransition( FALSE ),
- mForceClose( FALSE ),
- mInitialTab(initial_tab_selected),
- mAllowEdit( TRUE ),
- mShowingNotifyDialog( FALSE )
+LLPanelGroup::LLPanelGroup()
+: LLPanel()
+ ,LLGroupMgrObserver( LLUUID() )
+ ,mAllowEdit(TRUE)
{
// Set up the factory callbacks.
- mFactoryMap["general_tab"] = LLCallbackMap(LLPanelGroupGeneral::createTab,
- &mID);
- mFactoryMap["roles_tab"] = LLCallbackMap(LLPanelGroupRoles::createTab,
- &mID);
- mFactoryMap["notices_tab"] = LLCallbackMap(LLPanelGroupNotices::createTab,
- &mID);
- mFactoryMap["land_money_tab"]= LLCallbackMap(LLPanelGroupLandMoney::createTab,
- &mID);
// Roles sub tabs
- mFactoryMap["members_sub_tab"] = LLCallbackMap(LLPanelGroupMembersSubTab::createTab, &mID);
- mFactoryMap["roles_sub_tab"] = LLCallbackMap(LLPanelGroupRolesSubTab::createTab, &mID);
- mFactoryMap["actions_sub_tab"] = LLCallbackMap(LLPanelGroupActionsSubTab::createTab, &mID);
-
LLGroupMgr::getInstance()->addObserver(this);
- // Pass on construction of this panel to the control factory.
- LLUICtrlFactory::getInstance()->buildPanel(this, filename, &getFactoryMap());
- mFilename = filename;
}
+
LLPanelGroup::~LLPanelGroup()
{
LLGroupMgr::getInstance()->removeObserver(this);
-
- int i;
- int tab_count = mTabContainer->getTabCount();
-
- for (i = tab_count - 1; i >=0; --i)
- {
- LLPanelGroupTab* panelp =
- (LLPanelGroupTab*) mTabContainer->getPanelByIndex(i);
-
- if ( panelp ) panelp->removeObserver(this);
- }
}
-void LLPanelGroup::updateTabVisibility()
+void LLPanelGroup::onOpen(const LLSD& key)
{
- S32 i;
- S32 tab_count = mTabContainer->getTabCount();
-
- for (i = tab_count - 1; i >=0; --i)
+ if(!key.has("group_id"))
+ return;
+
+ LLUUID group_id = key["group_id"];
+ if(!key.has("action"))
{
- LLPanelGroupTab* panelp =
- (LLPanelGroupTab*) mTabContainer->getPanelByIndex(i);
+ setGroupID(group_id);
+ return;
+ }
- BOOL visible = panelp->isVisibleByAgent(&gAgent) || gAgent.isGodlike();
- mTabContainer->enableTabButton(i, visible);
+ std::string str_action = key["action"];
- if ( !visible && mCurrentTab == panelp )
- {
- //we are disabling the currently selected tab
- //select the previous one
- mTabContainer->selectPrevTab();
- mCurrentTab =
- (LLPanelGroupTab*) mTabContainer->getCurrentPanel();
- }
+ if(str_action == "refresh")
+ {
+ if(mID == group_id || group_id == LLUUID::null)
+ refreshData();
+ }
+ else if(str_action == "close")
+ {
+ onBackBtnClick();
+ }
+ else if(str_action == "create")
+ {
+ setGroupID(LLUUID::null);
+ }
+ else if(str_action == "refresh_notices")
+ {
+ LLPanelGroupNotices* panel_notices = findChild<LLPanelGroupNotices>("group_notices_tab_panel");
+ if(panel_notices)
+ panel_notices->refreshNotices();
}
-}
-
+}
BOOL LLPanelGroup::postBuild()
{
- mTabContainer = getChild<LLTabContainer>("group_tab_container");
+ mDefaultNeedsApplyMesg = getString("default_needs_apply_text");
+ mWantApplyMesg = getString("want_apply_text");
- if (mTabContainer)
- {
- // Select the initial tab specified via constructor
- const BOOL recurse = TRUE;
- LLPanelGroupTab* tabp =
- getChild<LLPanelGroupTab>(mInitialTab, recurse);
+ LLButton* button;
- if (!tabp)
- {
- //our initial tab selection was invalid, just select the
- //first tab then or default to selecting the initial
- //selected tab specified in the layout file
- tabp = (LLPanelGroupTab*) mTabContainer->getCurrentPanel();
-
- //no tab was initially selected through constructor
- //or the XML, select the first tab
- if (!tabp)
- {
- mTabContainer->selectFirstTab();
- tabp = (LLPanelGroupTab*) mTabContainer->getCurrentPanel();
- }
- }
- else
- {
- mTabContainer->selectTabPanel(tabp);
- }
-
- mCurrentTab = tabp;
+ button = getChild<LLButton>("btn_apply");
+ button->setClickedCallback(onBtnApply, this);
+ button->setVisible(true);
+ button->setEnabled(false);
- // Add click callbacks.
- S32 i;
- S32 tab_count = mTabContainer->getTabCount();
- for (i = tab_count - 1; i >=0; --i)
- {
- LLPanel* tab_panel = mTabContainer->getPanelByIndex(i);
- LLPanelGroupTab* panelp =(LLPanelGroupTab*)tab_panel; // bit of a hack
+ button = getChild<LLButton>("btn_refresh");
+ button->setClickedCallback(onBtnRefresh, this);
+ button->setVisible(mAllowEdit);
- // Pass on whether or not to allow edit to tabs.
- panelp->setAllowEdit(mAllowEdit);
- panelp->addObserver(this);
+ getChild<LLButton>("btn_create")->setVisible(false);
- mTabContainer->setTabChangeCallback(panelp, onClickTab);
- mTabContainer->setTabUserData(panelp, this);
- }
- updateTabVisibility();
+ childSetCommitCallback("btn_create",boost::bind(&LLPanelGroup::onBtnCreate,this),NULL);
+ childSetCommitCallback("back",boost::bind(&LLPanelGroup::onBackBtnClick,this),NULL);
- // Act as though this tab was just activated.
- mCurrentTab->activate();
- }
+ LLPanelGroupTab* panel_general = findChild<LLPanelGroupTab>("group_general_tab_panel");
+ LLPanelGroupTab* panel_roles = findChild<LLPanelGroupTab>("group_roles_tab_panel");
+ LLPanelGroupTab* panel_notices = findChild<LLPanelGroupTab>("group_notices_tab_panel");
+ LLPanelGroupTab* panel_land = findChild<LLPanelGroupTab>("group_land_tab_panel");
- mDefaultNeedsApplyMesg = getString("default_needs_apply_text");
- mWantApplyMesg = getString("want_apply_text");
+ if(panel_general) mTabs.push_back(panel_general);
+ if(panel_roles) mTabs.push_back(panel_roles);
+ if(panel_notices) mTabs.push_back(panel_notices);
+ if(panel_land) mTabs.push_back(panel_land);
- LLButton* button = getChild<LLButton>("btn_ok");
- if (button)
- {
- button->setClickedCallback(onBtnOK);
- button->setCallbackUserData(this);
- button->setVisible(mAllowEdit);
- }
+ panel_general->setupCtrls(this);
- button = getChild<LLButton>("btn_cancel");
- if (button)
+ return TRUE;
+}
+
+void LLPanelGroup::reshape(S32 width, S32 height, BOOL called_from_parent )
+{
+ LLPanel::reshape(width, height, called_from_parent );
+
+ LLRect btn_rect;
+
+ LLButton* button = findChild<LLButton>("btn_apply");
+ if(button)
{
- button->setClickedCallback(onBtnCancel);
- button->setCallbackUserData(this);
- button->setVisible(mAllowEdit);
+ btn_rect = button->getRect();
+ btn_rect.setLeftTopAndSize( btn_rect.mLeft, btn_rect.getHeight() + 2, btn_rect.getWidth(), btn_rect.getHeight());
+ button->setRect(btn_rect);
}
- button = getChild<LLButton>("btn_apply");
- if (button)
+ button = findChild<LLButton>("btn_create");
+ if(button)
{
- button->setClickedCallback(onBtnApply);
- button->setVisible(mAllowEdit);
- button->setEnabled(FALSE);
-
- mApplyBtn = button;
+ btn_rect = button->getRect();
+ btn_rect.setLeftTopAndSize( btn_rect.mLeft, btn_rect.getHeight() + 2, btn_rect.getWidth(), btn_rect.getHeight());
+ button->setRect(btn_rect);
}
- button = getChild<LLButton>("btn_refresh");
- if (button)
+
+ button = findChild<LLButton>("btn_refresh");
+ if(button)
{
- button->setClickedCallback(onBtnRefresh);
- button->setCallbackUserData(this);
- button->setVisible(mAllowEdit);
+ btn_rect = button->getRect();
+ btn_rect.setLeftTopAndSize( btn_rect.mLeft, btn_rect.getHeight() + 2, btn_rect.getWidth(), btn_rect.getHeight());
+ button->setRect(btn_rect);
}
-
- return TRUE;
}
-void LLPanelGroup::changed(LLGroupChange gc)
+void LLPanelGroup::onBackBtnClick()
{
- updateTabVisibility();
- // Notify the currently active panel that group manager information has changed.
- LLPanelGroupTab* panelp = (LLPanelGroupTab*) mTabContainer->getCurrentPanel();
-
- if (panelp)
+ LLSideTrayPanelContainer* parent = dynamic_cast<LLSideTrayPanelContainer*>(getParent());
+ if(parent)
{
- panelp->update(gc);
+ parent->openPreviousPanel();
}
}
-// PanelGroupTab observer trigger
-void LLPanelGroup::tabChanged()
+void LLPanelGroup::onBtnCreate()
{
- //some tab information has changed,....enable/disable the apply button
- //based on if they need an apply
- if ( mApplyBtn )
- {
- std::string mesg;
- mApplyBtn->setEnabled(mCurrentTab->needsApply(mesg));
- }
+ LLPanelGroupGeneral* panel_general = findChild<LLPanelGroupGeneral>("group_general_tab_panel");
+ if(!panel_general)
+ return;
+ std::string apply_mesg;
+ panel_general->apply(apply_mesg);//yes yes you need to call apply to create...
}
-// static
-void LLPanelGroup::onClickTab(void* user_data, bool from_click)
+void LLPanelGroup::onBtnRefresh(void* user_data)
{
LLPanelGroup* self = static_cast<LLPanelGroup*>(user_data);
- self->handleClickTab();
+ self->refreshData();
}
-void LLPanelGroup::handleClickTab()
+void LLPanelGroup::onBtnApply(void* user_data)
{
- // If we are already handling a transition,
- // ignore this.
- if (mIgnoreTransition)
- {
- return;
- }
+ LLPanelGroup* self = static_cast<LLPanelGroup*>(user_data);
+ self->apply();
+}
- mRequestedTab = (LLPanelGroupTab*) mTabContainer->getCurrentPanel();
- // Make sure they aren't just clicking the same tab...
- if (mRequestedTab == mCurrentTab)
- {
- return;
- }
+void LLPanelGroup::changed(LLGroupChange gc)
+{
+ for(std::vector<LLPanelGroupTab* >::iterator it = mTabs.begin();it!=mTabs.end();++it)
+ (*it)->update(gc);
- // Try to switch from the current panel to the panel the user selected.
- attemptTransition();
+ LLGroupMgrGroupData* gdatap = LLGroupMgr::getInstance()->getGroupData(mID);
+ if(gdatap)
+ childSetValue("group_name", gdatap->mName);
}
-void LLPanelGroup::setGroupID(const LLUUID& group_id)
+void LLPanelGroup::notifyObservers()
{
- LLRect rect(getRect());
+ for(std::vector<LLPanelGroupTab* >::iterator it = mTabs.begin();it!=mTabs.end();++it)
+ (*it)->update(GC_ALL);
+ LLGroupMgrGroupData* gdatap = LLGroupMgr::getInstance()->getGroupData(mID);
+ if(gdatap)
+ childSetValue("group_name", gdatap->mName);
+
+}
+
+
+
+void LLPanelGroup::setGroupID(const LLUUID& group_id)
+{
LLGroupMgr::getInstance()->removeObserver(this);
mID = group_id;
LLGroupMgr::getInstance()->addObserver(this);
- //TODO: this is really bad, we should add a method
- // where the panels can just update themselves
- // on a group id change. Similar to update() but with a group
- // id change.
-
- // For now, rebuild panel
- //delete children and rebuild panel
- deleteAllChildren();
- LLUICtrlFactory::getInstance()->buildPanel(this, mFilename, &getFactoryMap());
-}
-void LLPanelGroup::selectTab(std::string tab_name)
-{
- const BOOL recurse = TRUE;
+ for(std::vector<LLPanelGroupTab* >::iterator it = mTabs.begin();it!=mTabs.end();++it)
+ (*it)->setGroupID(group_id);
- LLPanelGroupTab* tabp =
- getChild<LLPanelGroupTab>(tab_name, recurse);
+ LLGroupMgrGroupData* gdatap = LLGroupMgr::getInstance()->getGroupData(mID);
+ if(gdatap)
+ childSetValue("group_name", gdatap->mName);
- if ( tabp && mTabContainer )
- {
- mTabContainer->selectTabPanel(tabp);
- onClickTab(this, false);
- }
-}
+ LLButton* button_apply = findChild<LLButton>("btn_apply");
+ LLButton* button_refresh = findChild<LLButton>("btn_refresh");
+ LLButton* button_create = findChild<LLButton>("btn_create");
-BOOL LLPanelGroup::canClose()
-{
- if (mShowingNotifyDialog) return FALSE;
- if (mCurrentTab && mCurrentTab->hasModal()) return FALSE;
- if (mForceClose || !mAllowEdit) return TRUE;
- // Try to switch from the current panel to nothing, indicating a close action.
- mRequestedTab = NULL;
- return attemptTransition();
-}
+ bool is_null_group_id = group_id == LLUUID::null;
+ if(button_apply)
+ button_apply->setVisible(!is_null_group_id);
+ if(button_refresh)
+ button_refresh->setVisible(!is_null_group_id);
+ if(button_create)
+ button_create->setVisible(is_null_group_id);
-BOOL LLPanelGroup::attemptTransition()
-{
- // Check if the current tab needs to be applied.
- std::string mesg;
- if (mCurrentTab && mCurrentTab->needsApply(mesg))
+ LLAccordionCtrlTab* tab_general = findChild<LLAccordionCtrlTab>("group_general_tab");
+ LLAccordionCtrlTab* tab_roles = findChild<LLAccordionCtrlTab>("group_roles_tab");
+ LLAccordionCtrlTab* tab_notices = findChild<LLAccordionCtrlTab>("group_notices_tab");
+ LLAccordionCtrlTab* tab_land = findChild<LLAccordionCtrlTab>("group_land_tab");
+
+ if(!tab_general || !tab_roles || !tab_notices || !tab_land)
+ return;
+
+ if(is_null_group_id)//creating new group
{
- // If no message was provided, give a generic one.
- if (mesg.empty())
- {
- mesg = mDefaultNeedsApplyMesg;
- }
- // Create a notify box, telling the user about the unapplied tab.
- LLSD args;
- args["NEEDS_APPLY_MESSAGE"] = mesg;
- args["WANT_APPLY_MESSAGE"] = mWantApplyMesg;
- LLNotifications::instance().add("PanelGroupApply", args, LLSD(),
- boost::bind(&LLPanelGroup::handleNotifyCallback, this, _1, _2));
- mShowingNotifyDialog = TRUE;
+ if(!tab_general->getDisplayChildren())
+ tab_general->changeOpenClose(tab_general->getDisplayChildren());
- // We need to reselect the current tab, since it isn't finished.
- if (mTabContainer)
- {
- // selectTabPanel is going to trigger another
- // click event. We want to ignore it so that
- // mRequestedTab is not updated.
- mIgnoreTransition = TRUE;
- mTabContainer->selectTabPanel( mCurrentTab );
- mIgnoreTransition = FALSE;
- }
- // Returning FALSE will block a close action from finishing until
- // we get a response back from the user.
- return FALSE;
+ if(tab_roles->getDisplayChildren())
+ tab_roles->changeOpenClose(tab_roles->getDisplayChildren());
+ if(tab_notices->getDisplayChildren())
+ tab_notices->changeOpenClose(tab_notices->getDisplayChildren());
+ if(tab_land->getDisplayChildren())
+ tab_land->changeOpenClose(tab_land->getDisplayChildren());
+
+ tab_roles->canOpenClose(false);
+ tab_notices->canOpenClose(false);
+ tab_land->canOpenClose(false);
}
else
{
- // The current panel didn't have anything it needed to apply.
- if ( mRequestedTab )
- {
- transitionToTab();
- }
- // Returning TRUE will allow any close action to proceed.
- return TRUE;
- }
-}
-
-void LLPanelGroup::transitionToTab()
-{
- // Tell the current panel that it is being deactivated.
- if (mCurrentTab)
- {
- mCurrentTab->deactivate();
- }
-
- // If the requested panel exists, activate it.
- if (mRequestedTab)
- {
- // This is now the current tab;
- mCurrentTab = mRequestedTab;
- mCurrentTab->activate();
- }
- else // NULL requested indicates a close action.
- {
- close();
- }
-}
-
-bool LLPanelGroup::handleNotifyCallback(const LLSD& notification, const LLSD& response)
-{
- S32 option = LLNotification::getSelectedOption(notification, response);
- mShowingNotifyDialog = FALSE;
- switch (option)
- {
- case 0: // "Apply Changes"
- // Try to apply changes, and switch to the requested tab.
- if ( !apply() )
- {
- // There was a problem doing the apply.
- // Skip switching tabs.
- break;
- }
-
- // This panel's info successfully applied.
- // Switch to the next panel.
- mIgnoreTransition = TRUE;
- mTabContainer->selectTabPanel( mRequestedTab );
- mIgnoreTransition = FALSE;
- transitionToTab();
- break;
- case 1: // "Ignore Changes"
- // Switch to the requested panel without applying changes
- // (Changes may already have been applied in the previous block)
- mCurrentTab->cancel();
- mIgnoreTransition = TRUE;
- mTabContainer->selectTabPanel( mRequestedTab );
- mIgnoreTransition = FALSE;
- transitionToTab();
- break;
- case 2: // "Cancel"
- default:
- // Do nothing. The user is canceling the action.
- // If we were quitting, we didn't really mean it.
- LLAppViewer::instance()->abortQuit();
- break;
+ if(!tab_general->getDisplayChildren())
+ tab_general->changeOpenClose(tab_general->getDisplayChildren());
+ if(!tab_roles->getDisplayChildren())
+ tab_roles->changeOpenClose(tab_roles->getDisplayChildren());
+ if(!tab_notices->getDisplayChildren())
+ tab_notices->changeOpenClose(tab_notices->getDisplayChildren());
+ if(!tab_land->getDisplayChildren())
+ tab_land->changeOpenClose(tab_land->getDisplayChildren());
+
+ tab_roles->canOpenClose(true);
+ tab_notices->canOpenClose(true);
+ tab_land->canOpenClose(true);
}
- return false;
}
-// static
-void LLPanelGroup::onBtnOK(void* user_data)
+bool LLPanelGroup::apply(LLPanelGroupTab* tab)
{
- LLPanelGroup* self = static_cast<LLPanelGroup*>(user_data);
- // If we are able to apply changes, then close.
- if(self->apply())
- {
- self->close();
- }
-}
+ if(!tab)
+ return false;
-// static
-void LLPanelGroup::onBtnCancel(void* user_data)
-{
- LLPanelGroup* self = static_cast<LLPanelGroup*>(user_data);
- self->close();
-}
-
-// static
-void LLPanelGroup::onBtnApply(void* user_data)
-{
- LLPanelGroup* self = static_cast<LLPanelGroup*>(user_data);
- self->apply();
-}
-
-bool LLPanelGroup::apply()
-{
- // Pass this along to the currently visible tab.
- if (!mTabContainer) return false;
-
- LLPanelGroupTab* panelp = (LLPanelGroupTab*) mTabContainer->getCurrentPanel();
- if (!panelp) return false;
-
std::string mesg;
- if ( !panelp->needsApply(mesg) )
- {
- // We don't need to apply anything.
- // We're done.
+ if ( !tab->needsApply(mesg) )
return true;
- }
-
- // Ignore the needs apply message.
- // Try to do the actual apply.
+
std::string apply_mesg;
- if ( panelp->apply( apply_mesg ) )
- {
- // Everything worked. We're done.
+ if(tab->apply( apply_mesg ) )
return true;
- }
-
- // There was a problem doing the actual apply.
- // Inform the user.
+
if ( !apply_mesg.empty() )
{
LLSD args;
args["MESSAGE"] = apply_mesg;
LLNotifications::instance().add("GenericAlert", args);
}
-
return false;
}
-// static
-void LLPanelGroup::onBtnRefresh(void* user_data)
+bool LLPanelGroup::apply()
{
- LLPanelGroup* self = static_cast<LLPanelGroup*>(user_data);
- self->refreshData();
+ return apply(findChild<LLPanelGroupTab>("group_general_tab_panel"))
+ && apply(findChild<LLPanelGroupTab>("group_roles_tab_panel"))
+ && apply(findChild<LLPanelGroupTab>("group_notices_tab_panel"))
+ && apply(findChild<LLPanelGroupTab>("group_land_tab_panel"))
+ ;
}
+
// virtual
void LLPanelGroup::draw()
{
@@ -579,18 +381,22 @@ void LLPanelGroup::draw()
mRefreshTimer.stop();
childEnable("btn_refresh");
}
- if (mCurrentTab)
- {
- std::string mesg;
- childSetEnabled("btn_apply", mCurrentTab->needsApply(mesg));
- }
+ bool enable = false;
+ std::string mesg;
+ for(std::vector<LLPanelGroupTab* >::iterator it = mTabs.begin();it!=mTabs.end();++it)
+ enable = enable || (*it)->needsApply(mesg);
+
+ childSetEnabled("btn_apply", enable);
}
void LLPanelGroup::refreshData()
{
LLGroupMgr::getInstance()->clearGroupData(getID());
- mCurrentTab->activate();
+
+ for(std::vector<LLPanelGroupTab* >::iterator it = mTabs.begin();it!=mTabs.end();++it)
+ (*it)->activate();
+
// 5 second timeout
childDisable("btn_refresh");
@@ -598,20 +404,6 @@ void LLPanelGroup::refreshData()
mRefreshTimer.setTimerExpirySec(5);
}
-void LLPanelGroup::close()
-{
- // Pass this to the parent, if it is a floater.
- LLView* viewp = getParent();
- LLFloater* floaterp = dynamic_cast<LLFloater*>(viewp);
- if (floaterp)
- {
- // First, set the force close flag, since the floater
- // will be asking us whether it can close.
- mForceClose = TRUE;
- // Tell the parent floater to close.
- floaterp->close();
- }
-}
void LLPanelGroup::showNotice(const std::string& subject,
const std::string& message,
@@ -619,7 +411,8 @@ void LLPanelGroup::showNotice(const std::string& subject,
const std::string& inventory_name,
LLOfferInfo* inventory_offer)
{
- if (mCurrentTab->getName() != "notices_tab")
+ LLPanelGroupNotices* panel_notices = findChild<LLPanelGroupNotices>("group_notices_tab_panel");
+ if(!panel_notices)
{
// We need to clean up that inventory offer.
if (inventory_offer)
@@ -628,8 +421,37 @@ void LLPanelGroup::showNotice(const std::string& subject,
}
return;
}
+ panel_notices->showNotice(subject,message,has_inventory,inventory_name,inventory_offer);
+}
+
- LLPanelGroupNotices* notices = static_cast<LLPanelGroupNotices*>(mCurrentTab);
- notices->showNotice(subject,message,has_inventory,inventory_name,inventory_offer);
+
+//static
+void LLPanelGroup::refreshCreatedGroup(const LLUUID& group_id)
+{
+ LLPanelGroup* panel = LLSideTray::getInstance()->findChild<LLPanelGroup>("panel_group_info_sidetray");
+ if(!panel)
+ return;
+ panel->setGroupID(group_id);
+}
+
+//static
+
+void LLPanelGroup::showNotice(const std::string& subject,
+ const std::string& message,
+ const LLUUID& group_id,
+ const bool& has_inventory,
+ const std::string& inventory_name,
+ LLOfferInfo* inventory_offer)
+{
+ LLPanelGroup* panel = LLSideTray::getInstance()->findChild<LLPanelGroup>("panel_group_info_sidetray");
+ if(!panel)
+ return;
+
+ if(panel->getID() != group_id)//???? only for current group_id or switch panels? FIXME
+ return;
+ panel->showNotice(subject,message,has_inventory,inventory_name,inventory_offer);
+
}
+
diff --git a/indra/newview/llpanelgroup.h b/indra/newview/llpanelgroup.h
index 445fb28502..6db6738d18 100644
--- a/indra/newview/llpanelgroup.h
+++ b/indra/newview/llpanelgroup.h
@@ -45,101 +45,79 @@ class LLPanelGroupTab;
class LLTabContainer;
class LLAgent;
-class LLPanelGroupTabObserver
-{
-public:
- LLPanelGroupTabObserver() {};
- virtual ~LLPanelGroupTabObserver(){};
- virtual void tabChanged() = 0;
-};
class LLPanelGroup : public LLPanel,
- public LLGroupMgrObserver,
- public LLPanelGroupTabObserver
+ public LLGroupMgrObserver
{
public:
- LLPanelGroup(const std::string& filename,
- const std::string& name,
- const LLUUID& group_id,
- const std::string& initial_tab_selected = std::string());
+ LLPanelGroup();
virtual ~LLPanelGroup();
virtual BOOL postBuild();
- static void onBtnOK(void*);
- static void onBtnCancel(void*);
- static void onBtnApply(void*);
- static void onBtnRefresh(void*);
- static void onClickTab(void*,bool);
- void handleClickTab();
-
void setGroupID(const LLUUID& group_id);
- void selectTab(std::string tab_name);
-
- // Called when embedded in a floater during a close attempt.
- BOOL canClose();
-
- // Checks if the current tab needs to be applied, and tries to switch to the requested tab.
- BOOL attemptTransition();
-
- // Switches to the requested tab (will close() if requested is NULL)
- void transitionToTab();
-
- void updateTabVisibility();
-
- // Used by attemptTransition to query the user's response to a tab that needs to apply.
- bool handleNotifyCallback(const LLSD& notification, const LLSD& response);
- bool apply();
- void refreshData();
- void close();
void draw();
+ void onOpen(const LLSD& key);
+
// Group manager observer trigger.
virtual void changed(LLGroupChange gc);
- // PanelGroupTab observer trigger
- virtual void tabChanged();
-
- void setAllowEdit(BOOL v) { mAllowEdit = v; }
-
void showNotice(const std::string& subject,
const std::string& message,
const bool& has_inventory,
const std::string& inventory_name,
LLOfferInfo* inventory_offer);
+
+ void notifyObservers();
+
+ bool apply();
+ void refreshData();
+
+ virtual void reshape(S32 width, S32 height, BOOL called_from_parent = TRUE);
+
+ void setAllowEdit(BOOL v) { mAllowEdit = v; }
+
+
+ static void refreshCreatedGroup(const LLUUID& group_id);
+
+ static void showNotice(const std::string& subject,
+ const std::string& message,
+ const LLUUID& group_id,
+ const bool& has_inventory,
+ const std::string& inventory_name,
+ LLOfferInfo* inventory_offer);
+
+
protected:
- LLPanelGroupTab* mCurrentTab;
- LLPanelGroupTab* mRequestedTab;
- LLTabContainer* mTabContainer;
- BOOL mIgnoreTransition;
+ void onBtnCreate();
+ void onBackBtnClick();
- LLButton* mApplyBtn;
+ static void onBtnApply(void*);
+ static void onBtnRefresh(void*);
- LLTimer mRefreshTimer;
- BOOL mForceClose;
+protected:
+ bool apply(LLPanelGroupTab* tab);
+
+ LLTimer mRefreshTimer;
- std::string mInitialTab;
- std::string mFilename;
+ BOOL mAllowEdit;
std::string mDefaultNeedsApplyMesg;
std::string mWantApplyMesg;
- BOOL mAllowEdit;
- BOOL mShowingNotifyDialog;
+ std::vector<LLPanelGroupTab* > mTabs;
+
};
class LLPanelGroupTab : public LLPanel
{
public:
- LLPanelGroupTab(const std::string& name, const LLUUID& group_id)
- : LLPanel(name), mGroupID(group_id), mAllowEdit(TRUE), mHasModal(FALSE) { }
+ LLPanelGroupTab();
virtual ~LLPanelGroupTab();
- // Factory that returns a new LLPanelGroupFoo tab.
- static void* createTab(void* data);
-
// Triggered when the tab becomes active.
virtual void activate() { }
@@ -167,7 +145,6 @@ public:
virtual std::string getHelpText() const { return mHelpText; }
// Display anything returned by getHelpText
- static void onClickHelp(void* data);
void handleClickHelp();
// This just connects the help button callback.
@@ -177,20 +154,21 @@ public:
void setAllowEdit(BOOL v) { mAllowEdit = v; }
- void addObserver(LLPanelGroupTabObserver *obs);
- void removeObserver(LLPanelGroupTabObserver *obs);
- void notifyObservers();
+ virtual void setGroupID(const LLUUID& id) {mGroupID = id;};
+
+ void notifyObservers() {};
+
+ const LLUUID& getGroupID() const { return mGroupID;}
+
+ virtual void setupCtrls (LLPanel* parent) {};
protected:
LLUUID mGroupID;
- LLTabContainer* mTabContainer;
std::string mHelpText;
BOOL mAllowEdit;
BOOL mHasModal;
- typedef std::set<LLPanelGroupTabObserver*> observer_list_t;
- observer_list_t mObservers;
};
#endif // LL_LLPANELGROUP_H
diff --git a/indra/newview/llpanelgroupgeneral.cpp b/indra/newview/llpanelgroupgeneral.cpp
index 3dc5e032c5..73ea990b3f 100644
--- a/indra/newview/llpanelgroupgeneral.cpp
+++ b/indra/newview/llpanelgroupgeneral.cpp
@@ -37,49 +37,43 @@
#include "lluictrlfactory.h"
#include "llagent.h"
#include "roles_constants.h"
-#include "llfloateravatarinfo.h"
-#include "llfloatergroupinfo.h"
// UI elements
#include "llbutton.h"
#include "llcheckboxctrl.h"
#include "llcombobox.h"
#include "lldbstrings.h"
+#include "llavataractions.h"
+#include "llgroupactions.h"
#include "lllineeditor.h"
#include "llnamebox.h"
#include "llnamelistctrl.h"
+#include "llscrolllistitem.h"
#include "llspinctrl.h"
#include "llstatusbar.h" // can_afford_transaction()
#include "lltextbox.h"
#include "lltexteditor.h"
#include "lltexturectrl.h"
+#include "lltrans.h"
#include "llviewerwindow.h"
+static LLRegisterPanelClassWrapper<LLPanelGroupGeneral> t_panel_group_general("panel_group_general");
+
// consts
const S32 MATURE_CONTENT = 1;
const S32 NON_MATURE_CONTENT = 2;
const S32 DECLINE_TO_STATE = 0;
-// static
-void* LLPanelGroupGeneral::createTab(void* data)
-{
- LLUUID* group_id = static_cast<LLUUID*>(data);
- return new LLPanelGroupGeneral("panel group general", *group_id);
-}
-
-LLPanelGroupGeneral::LLPanelGroupGeneral(const std::string& name,
- const LLUUID& group_id)
-: LLPanelGroupTab(name, group_id),
+LLPanelGroupGeneral::LLPanelGroupGeneral()
+: LLPanelGroupTab(),
mPendingMemberUpdate(FALSE),
mChanged(FALSE),
mFirstUse(TRUE),
mGroupNameEditor(NULL),
- mGroupName(NULL),
mFounderName(NULL),
mInsignia(NULL),
mEditCharter(NULL),
- mBtnJoinGroup(NULL),
mListVisibleMembers(NULL),
mCtrlShowInGroupList(NULL),
mComboMature(NULL),
@@ -100,74 +94,39 @@ LLPanelGroupGeneral::~LLPanelGroupGeneral()
BOOL LLPanelGroupGeneral::postBuild()
{
- llinfos << "LLPanelGroupGeneral::postBuild()" << llendl;
-
bool recurse = true;
// General info
mGroupNameEditor = getChild<LLLineEditor>("group_name_editor", recurse);
- mGroupName = getChild<LLTextBox>("group_name", recurse);
-
- mInsignia = getChild<LLTextureCtrl>("insignia", recurse);
- if (mInsignia)
- {
- mInsignia->setCommitCallback(onCommitAny);
- mInsignia->setCallbackUserData(this);
- mDefaultIconID = mInsignia->getImageAssetID();
- }
mEditCharter = getChild<LLTextEditor>("charter", recurse);
if(mEditCharter)
{
- mEditCharter->setCommitCallback(onCommitAny);
+ mEditCharter->setCommitCallback(onCommitAny, this);
mEditCharter->setFocusReceivedCallback(onFocusEdit, this);
mEditCharter->setFocusChangedCallback(onFocusEdit, this);
- mEditCharter->setCallbackUserData(this);
}
- mBtnJoinGroup = getChild<LLButton>("join_button", recurse);
- if ( mBtnJoinGroup )
- {
- mBtnJoinGroup->setClickedCallback(onClickJoin);
- mBtnJoinGroup->setCallbackUserData(this);
- }
- mBtnInfo = getChild<LLButton>("info_button", recurse);
- if ( mBtnInfo )
- {
- mBtnInfo->setClickedCallback(onClickInfo);
- mBtnInfo->setCallbackUserData(this);
- }
-
- LLTextBox* founder = getChild<LLTextBox>("founder_name");
- if (founder)
- {
- mFounderName = new LLNameBox(founder->getName(),founder->getRect(),LLUUID::null,FALSE,founder->getFont(),founder->getMouseOpaque());
- removeChild(founder, TRUE);
- addChild(mFounderName);
- }
mListVisibleMembers = getChild<LLNameListCtrl>("visible_members", recurse);
if (mListVisibleMembers)
{
- mListVisibleMembers->setDoubleClickCallback(openProfile);
- mListVisibleMembers->setCallbackUserData(this);
+ mListVisibleMembers->setDoubleClickCallback(openProfile, this);
}
// Options
mCtrlShowInGroupList = getChild<LLCheckBoxCtrl>("show_in_group_list", recurse);
if (mCtrlShowInGroupList)
{
- mCtrlShowInGroupList->setCommitCallback(onCommitAny);
- mCtrlShowInGroupList->setCallbackUserData(this);
+ mCtrlShowInGroupList->setCommitCallback(onCommitAny, this);
}
mComboMature = getChild<LLComboBox>("group_mature_check", recurse);
if(mComboMature)
{
mComboMature->setCurrentByIndex(0);
- mComboMature->setCommitCallback(onCommitAny);
- mComboMature->setCallbackUserData(this);
+ mComboMature->setCommitCallback(onCommitAny, this);
if (gAgent.isTeen())
{
// Teens don't get to set mature flag. JC
@@ -178,22 +137,19 @@ BOOL LLPanelGroupGeneral::postBuild()
mCtrlOpenEnrollment = getChild<LLCheckBoxCtrl>("open_enrollement", recurse);
if (mCtrlOpenEnrollment)
{
- mCtrlOpenEnrollment->setCommitCallback(onCommitAny);
- mCtrlOpenEnrollment->setCallbackUserData(this);
+ mCtrlOpenEnrollment->setCommitCallback(onCommitAny, this);
}
mCtrlEnrollmentFee = getChild<LLCheckBoxCtrl>("check_enrollment_fee", recurse);
if (mCtrlEnrollmentFee)
{
- mCtrlEnrollmentFee->setCommitCallback(onCommitEnrollment);
- mCtrlEnrollmentFee->setCallbackUserData(this);
+ mCtrlEnrollmentFee->setCommitCallback(onCommitEnrollment, this);
}
mSpinEnrollmentFee = getChild<LLSpinCtrl>("spin_enrollment_fee", recurse);
if (mSpinEnrollmentFee)
{
- mSpinEnrollmentFee->setCommitCallback(onCommitAny);
- mSpinEnrollmentFee->setCallbackUserData(this);
+ mSpinEnrollmentFee->setCommitCallback(onCommitAny, this);
mSpinEnrollmentFee->setPrecision(0);
mSpinEnrollmentFee->resetDirty();
}
@@ -209,8 +165,7 @@ BOOL LLPanelGroupGeneral::postBuild()
mCtrlReceiveNotices = getChild<LLCheckBoxCtrl>("receive_notices", recurse);
if (mCtrlReceiveNotices)
{
- mCtrlReceiveNotices->setCommitCallback(onCommitUserOnly);
- mCtrlReceiveNotices->setCallbackUserData(this);
+ mCtrlReceiveNotices->setCommitCallback(onCommitUserOnly, this);
mCtrlReceiveNotices->set(accept_notices);
mCtrlReceiveNotices->setEnabled(data.mID.notNull());
}
@@ -218,8 +173,7 @@ BOOL LLPanelGroupGeneral::postBuild()
mCtrlListGroup = getChild<LLCheckBoxCtrl>("list_groups_in_profile", recurse);
if (mCtrlListGroup)
{
- mCtrlListGroup->setCommitCallback(onCommitUserOnly);
- mCtrlListGroup->setCallbackUserData(this);
+ mCtrlListGroup->setCommitCallback(onCommitUserOnly, this);
mCtrlListGroup->set(list_in_profile);
mCtrlListGroup->setEnabled(data.mID.notNull());
mCtrlListGroup->resetDirty();
@@ -230,14 +184,12 @@ BOOL LLPanelGroupGeneral::postBuild()
mComboActiveTitle = getChild<LLComboBox>("active_title", recurse);
if (mComboActiveTitle)
{
- mComboActiveTitle->setCommitCallback(onCommitTitle);
- mComboActiveTitle->setCallbackUserData(this);
+ mComboActiveTitle->setCommitCallback(onCommitTitle, this);
mComboActiveTitle->resetDirty();
}
mIncompleteMemberDataStr = getString("incomplete_member_data_str");
- mConfirmGroupCreateStr = getString("confirm_group_create_str");
-
+
// If the group_id is null, then we are creating a new group
if (mGroupID.isNull())
{
@@ -250,14 +202,22 @@ BOOL LLPanelGroupGeneral::postBuild()
mCtrlEnrollmentFee->setEnabled(TRUE);
mSpinEnrollmentFee->setEnabled(TRUE);
- mBtnJoinGroup->setVisible(FALSE);
- mBtnInfo->setVisible(FALSE);
- mGroupName->setVisible(FALSE);
}
return LLPanelGroupTab::postBuild();
}
+void LLPanelGroupGeneral::setupCtrls(LLPanel* panel_group)
+{
+ mInsignia = panel_group->getChild<LLTextureCtrl>("insignia");
+ if (mInsignia)
+ {
+ mInsignia->setCommitCallback(onCommitAny, this);
+ mDefaultIconID = mInsignia->getImageAssetID();
+ }
+ mFounderName = panel_group->getChild<LLNameBox>("founder_name");
+}
+
// static
void LLPanelGroupGeneral::onFocusEdit(LLFocusableElement* ctrl, void* data)
{
@@ -332,7 +292,8 @@ void LLPanelGroupGeneral::onClickInfo(void *userdata)
lldebugs << "open group info: " << self->mGroupID << llendl;
- LLFloaterGroupInfo::showFromUUID(self->mGroupID);
+ LLGroupActions::show(self->mGroupID);
+
}
// static
@@ -395,7 +356,7 @@ void LLPanelGroupGeneral::openProfile(void* data)
LLScrollListItem* selected = self->mListVisibleMembers->getFirstSelected();
if (selected)
{
- LLFloaterAvatarInfo::showFromDirectory( selected->getUUID() );
+ LLAvatarActions::showProfile(selected->getUUID());
}
}
}
@@ -470,9 +431,7 @@ bool LLPanelGroupGeneral::apply(std::string& mesg)
return false;
}
- LLSD args;
- args["MESSAGE"] = mConfirmGroupCreateStr;
- LLNotifications::instance().add("GenericAlertYesCancel", args, LLSD(), boost::bind(&LLPanelGroupGeneral::createGroupCallback, this, _1, _2));
+ LLNotifications::instance().add("CreateGroupCost", LLSD(), LLSD(), boost::bind(&LLPanelGroupGeneral::createGroupCallback, this, _1, _2));
return false;
}
@@ -480,8 +439,7 @@ bool LLPanelGroupGeneral::apply(std::string& mesg)
LLGroupMgrGroupData* gdatap = LLGroupMgr::getInstance()->getGroupData(mGroupID);
if (!gdatap)
{
- // *TODO: Translate
- mesg = std::string("No group data found for group ");
+ mesg = LLTrans::getString("NoGroupDataFound");
mesg.append(mGroupID.asString());
return false;
}
@@ -720,26 +678,6 @@ void LLPanelGroupGeneral::update(LLGroupChange gc)
can_change_member_opts);
mSpinEnrollmentFee->resetDirty();
}
- if ( mBtnJoinGroup )
- {
- std::string fee_buff;
- bool visible;
-
- visible = !is_member && gdatap->mOpenEnrollment;
- mBtnJoinGroup->setVisible(visible);
-
- if ( visible )
- {
- fee_buff = llformat( "Join (L$%d)", gdatap->mMembershipFee);
- mBtnJoinGroup->setLabelSelected(fee_buff);
- mBtnJoinGroup->setLabelUnselected(fee_buff);
- }
- }
- if ( mBtnInfo )
- {
- mBtnInfo->setVisible(is_member && !mAllowEdit);
- }
-
if (mCtrlReceiveNotices)
{
mCtrlReceiveNotices->setVisible(is_member);
@@ -754,7 +692,6 @@ void LLPanelGroupGeneral::update(LLGroupChange gc)
if (mInsignia) mInsignia->setEnabled(mAllowEdit && can_change_ident);
if (mEditCharter) mEditCharter->setEnabled(mAllowEdit && can_change_ident);
- if (mGroupName) mGroupName->setText(gdatap->mName);
if (mGroupNameEditor) mGroupNameEditor->setVisible(FALSE);
if (mFounderName) mFounderName->setNameID(gdatap->mFounderID,FALSE);
if (mInsignia)
@@ -842,16 +779,16 @@ void LLPanelGroupGeneral::updateMembers()
row["id"] = member->getID();
row["columns"][0]["column"] = "name";
- row["columns"][0]["font-style"] = style;
+ row["columns"][0]["font"]["style"] = style;
// value is filled in by name list control
row["columns"][1]["column"] = "title";
row["columns"][1]["value"] = member->getTitle();
- row["columns"][1]["font-style"] = style;
+ row["columns"][1]["font"]["style"] = style;
row["columns"][2]["column"] = "online";
row["columns"][2]["value"] = member->getOnlineStatus();
- row["columns"][2]["font-style"] = style;
+ row["columns"][2]["font"]["style"] = style;
sSDTime += sd_timer.getElapsedTimeF32();
@@ -884,7 +821,6 @@ void LLPanelGroupGeneral::updateChanged()
LLUICtrl *check_list[] =
{
mGroupNameEditor,
- mGroupName,
mFounderName,
mInsignia,
mEditCharter,
@@ -910,3 +846,136 @@ void LLPanelGroupGeneral::updateChanged()
}
}
}
+
+void LLPanelGroupGeneral::reset()
+{
+ mFounderName->setVisible(false);
+
+
+ mCtrlReceiveNotices->set(false);
+
+
+ mCtrlListGroup->set(true);
+
+ mCtrlReceiveNotices->setEnabled(true);
+ mCtrlReceiveNotices->setVisible(true);
+
+ mCtrlListGroup->setEnabled(true);
+
+ mGroupNameEditor->setEnabled(TRUE);
+ mEditCharter->setEnabled(TRUE);
+
+ mCtrlShowInGroupList->setEnabled(TRUE);
+ mComboMature->setEnabled(TRUE);
+
+ mCtrlOpenEnrollment->setEnabled(TRUE);
+
+ mCtrlEnrollmentFee->setEnabled(TRUE);
+
+ mSpinEnrollmentFee->setEnabled(TRUE);
+ mSpinEnrollmentFee->set((F32)0);
+
+ mGroupNameEditor->setVisible(true);
+
+ mComboActiveTitle->setVisible(false);
+
+ mInsignia->setImageAssetID(LLUUID::null);
+
+ {
+ std::string empty_str = "";
+ mEditCharter->setText(empty_str);
+ }
+
+ {
+ LLSD row;
+ row["columns"][0]["value"] = "no members yet";
+
+ mListVisibleMembers->deleteAllItems();
+ mListVisibleMembers->setEnabled(FALSE);
+ mListVisibleMembers->addElement(row);
+ }
+
+
+ {
+ mComboMature->setEnabled(true);
+ mComboMature->setVisible( !gAgent.isTeen() );
+ }
+
+
+ resetDirty();
+}
+
+void LLPanelGroupGeneral::resetDirty()
+{
+ // List all the controls we want to check for changes...
+ LLUICtrl *check_list[] =
+ {
+ mGroupNameEditor,
+ mFounderName,
+ mInsignia,
+ mEditCharter,
+ mCtrlShowInGroupList,
+ mComboMature,
+ mCtrlOpenEnrollment,
+ mCtrlEnrollmentFee,
+ mSpinEnrollmentFee,
+ mCtrlReceiveNotices,
+ mCtrlListGroup,
+ mActiveTitleLabel,
+ mComboActiveTitle
+ };
+
+ for( size_t i=0; i<LL_ARRAY_SIZE(check_list); i++ )
+ {
+ if( check_list[i] )
+ check_list[i]->resetDirty() ;
+ }
+
+
+}
+
+void LLPanelGroupGeneral::setGroupID(const LLUUID& id)
+{
+ LLPanelGroupTab::setGroupID(id);
+
+ if(id == LLUUID::null)
+ {
+ reset();
+ return;
+ }
+
+ BOOL accept_notices = FALSE;
+ BOOL list_in_profile = FALSE;
+ LLGroupData data;
+ if(gAgent.getGroupData(mGroupID,data))
+ {
+ accept_notices = data.mAcceptNotices;
+ list_in_profile = data.mListInProfile;
+ }
+ mCtrlReceiveNotices = getChild<LLCheckBoxCtrl>("receive_notices");
+ if (mCtrlReceiveNotices)
+ {
+ mCtrlReceiveNotices->set(accept_notices);
+ mCtrlReceiveNotices->setEnabled(data.mID.notNull());
+ }
+
+ mCtrlListGroup = getChild<LLCheckBoxCtrl>("list_groups_in_profile");
+ if (mCtrlListGroup)
+ {
+ mCtrlListGroup->set(list_in_profile);
+ mCtrlListGroup->setEnabled(data.mID.notNull());
+ }
+
+ mActiveTitleLabel = getChild<LLTextBox>("active_title_label");
+
+ mComboActiveTitle = getChild<LLComboBox>("active_title");
+
+ mFounderName->setVisible(true);
+
+ mInsignia->setImageAssetID(LLUUID::null);
+
+ resetDirty();
+
+ activate();
+}
+
diff --git a/indra/newview/llpanelgroupgeneral.h b/indra/newview/llpanelgroupgeneral.h
index 71356677fc..b828480a12 100644
--- a/indra/newview/llpanelgroupgeneral.h
+++ b/indra/newview/llpanelgroupgeneral.h
@@ -49,11 +49,10 @@ class LLSpinCtrl;
class LLPanelGroupGeneral : public LLPanelGroupTab
{
public:
- LLPanelGroupGeneral(const std::string& name, const LLUUID& group_id);
+ LLPanelGroupGeneral();
virtual ~LLPanelGroupGeneral();
// LLPanelGroupTab
- static void* createTab(void* data);
virtual void activate();
virtual bool needsApply(std::string& mesg);
virtual bool apply(std::string& mesg);
@@ -66,7 +65,15 @@ public:
virtual void draw();
+ virtual void setGroupID(const LLUUID& id);
+
+ virtual void setupCtrls (LLPanel* parent);
+
private:
+ void reset();
+
+ void resetDirty();
+
static void onFocusEdit(LLFocusableElement* ctrl, void* data);
static void onCommitAny(LLUICtrl* ctrl, void* data);
static void onCommitUserOnly(LLUICtrl* ctrl, void* data);
@@ -87,17 +94,13 @@ private:
BOOL mChanged;
BOOL mFirstUse;
std::string mIncompleteMemberDataStr;
- std::string mConfirmGroupCreateStr;
LLUUID mDefaultIconID;
// Group information (include any updates in updateChanged)
LLLineEditor *mGroupNameEditor;
- LLTextBox *mGroupName;
LLNameBox *mFounderName;
LLTextureCtrl *mInsignia;
LLTextEditor *mEditCharter;
- LLButton *mBtnJoinGroup;
- LLButton *mBtnInfo;
LLNameListCtrl *mListVisibleMembers;
diff --git a/indra/newview/llpanelgroupinvite.cpp b/indra/newview/llpanelgroupinvite.cpp
index eedec9c8eb..c5eaa34204 100644
--- a/indra/newview/llpanelgroupinvite.cpp
+++ b/indra/newview/llpanelgroupinvite.cpp
@@ -37,8 +37,10 @@
#include "llfloateravatarpicker.h"
#include "llbutton.h"
#include "llcombobox.h"
+#include "llgroupactions.h"
#include "llgroupmgr.h"
#include "llnamelistctrl.h"
+#include "llscrolllistitem.h"
#include "llspinctrl.h"
#include "lltextbox.h"
#include "llviewerobject.h"
@@ -79,6 +81,7 @@ public:
LLButton *mRemoveButton;
LLTextBox *mGroupName;
std::string mOwnerWarning;
+ std::string mAlreadyInGroup;
bool mConfirmedOwnerInvite;
void (*mCloseCallback)(void* data);
@@ -166,16 +169,29 @@ void LLPanelGroupInvite::impl::submitInvitations()
}
}
+ bool already_in_group = false;
//loop over the users
std::vector<LLScrollListItem*> items = mInvitees->getAllData();
for (std::vector<LLScrollListItem*>::iterator iter = items.begin();
iter != items.end(); ++iter)
{
LLScrollListItem* item = *iter;
+ if(LLGroupActions::isAvatarMemberOfGroup(mGroupID, item->getUUID()))
+ {
+ already_in_group = true;
+ continue;
+ }
role_member_pairs[item->getUUID()] = role_id;
}
-
+
LLGroupMgr::getInstance()->sendGroupMemberInvites(mGroupID, role_member_pairs);
+
+ if(already_in_group)
+ {
+ LLSD msg;
+ msg["MESSAGE"] = mAlreadyInGroup;
+ LLNotifications::instance().add("GenericAlert", msg);
+ }
//then close
(*mCloseCallback)(mCloseCallbackUserData);
@@ -351,18 +367,13 @@ void LLPanelGroupInvite::impl::callbackAddUsers(const std::vector<std::string>&
if ( selfp) selfp->addUsers(names, ids);
}
-LLPanelGroupInvite::LLPanelGroupInvite(const std::string& name,
- const LLUUID& group_id)
- : LLPanel(name)
+LLPanelGroupInvite::LLPanelGroupInvite(const LLUUID& group_id)
+ : LLPanel(),
+ mImplementation(new impl(group_id)),
+ mPendingUpdate(FALSE)
{
- mImplementation = new impl(group_id);
- mPendingUpdate = FALSE;
- mStoreSelected = LLUUID::null;
-
- std::string panel_def_file;
-
// Pass on construction of this panel to the control factory.
- LLUICtrlFactory::getInstance()->buildPanel(this, "panel_group_invite.xml", &getFactoryMap());
+ LLUICtrlFactory::getInstance()->buildPanel(this, "panel_group_invite.xml");
}
LLPanelGroupInvite::~LLPanelGroupInvite()
@@ -519,9 +530,8 @@ BOOL LLPanelGroupInvite::postBuild()
getChild<LLNameListCtrl>("invitee_list", recurse);
if ( mImplementation->mInvitees )
{
- mImplementation->mInvitees->setCallbackUserData(mImplementation);
mImplementation->mInvitees->setCommitOnSelectionChange(TRUE);
- mImplementation->mInvitees->setCommitCallback(impl::callbackSelect);
+ mImplementation->mInvitees->setCommitCallback(impl::callbackSelect, mImplementation);
}
LLButton* button = getChild<LLButton>("add_button", recurse);
@@ -529,17 +539,14 @@ BOOL LLPanelGroupInvite::postBuild()
{
// default to opening avatarpicker automatically
// (*impl::callbackClickAdd)((void*)this);
- button->setClickedCallback(impl::callbackClickAdd);
- button->setCallbackUserData(this);
+ button->setClickedCallback(impl::callbackClickAdd, this);
}
mImplementation->mRemoveButton =
getChild<LLButton>("remove_button", recurse);
if ( mImplementation->mRemoveButton )
{
- mImplementation->mRemoveButton->
- setClickedCallback(impl::callbackClickRemove);
- mImplementation->mRemoveButton->setCallbackUserData(mImplementation);
+ mImplementation->mRemoveButton->setClickedCallback(impl::callbackClickRemove, mImplementation);
mImplementation->mRemoveButton->setEnabled(FALSE);
}
@@ -547,20 +554,18 @@ BOOL LLPanelGroupInvite::postBuild()
getChild<LLButton>("ok_button", recurse);
if ( mImplementation->mOKButton )
{
- mImplementation->mOKButton->
- setClickedCallback(impl::callbackClickOK);
- mImplementation->mOKButton->setCallbackUserData(mImplementation);
+ mImplementation->mOKButton->setClickedCallback(impl::callbackClickOK, mImplementation);
mImplementation->mOKButton->setEnabled(FALSE);
}
button = getChild<LLButton>("cancel_button", recurse);
if ( button )
{
- button->setClickedCallback(impl::callbackClickCancel);
- button->setCallbackUserData(mImplementation);
+ button->setClickedCallback(impl::callbackClickCancel, mImplementation);
}
mImplementation->mOwnerWarning = getString("confirm_invite_owner_str");
+ mImplementation->mAlreadyInGroup = getString("already_in_group");
update();
diff --git a/indra/newview/llpanelgroupinvite.h b/indra/newview/llpanelgroupinvite.h
index 9117b83e7d..37135b488a 100644
--- a/indra/newview/llpanelgroupinvite.h
+++ b/indra/newview/llpanelgroupinvite.h
@@ -39,7 +39,7 @@ class LLPanelGroupInvite
: public LLPanel
{
public:
- LLPanelGroupInvite(const std::string& name, const LLUUID& group_id);
+ LLPanelGroupInvite(const LLUUID& group_id);
~LLPanelGroupInvite();
void addUsers(std::vector<LLUUID>& agent_ids);
diff --git a/indra/newview/llpanelgrouplandmoney.cpp b/indra/newview/llpanelgrouplandmoney.cpp
index 73a9868962..e40fa19bb6 100644
--- a/indra/newview/llpanelgrouplandmoney.cpp
+++ b/indra/newview/llpanelgrouplandmoney.cpp
@@ -42,20 +42,72 @@
#include "llagent.h"
#include "lliconctrl.h"
+#include "llfloaterreg.h"
#include "lllineeditor.h"
#include "llproductinforequest.h"
#include "llscrolllistctrl.h"
+#include "llscrolllistitem.h"
+#include "llscrolllistcell.h"
#include "lltextbox.h"
#include "lltabcontainer.h"
+#include "lltexteditor.h"
#include "lltrans.h"
#include "lltransactiontypes.h"
+#include "lltrans.h"
#include "lluictrlfactory.h"
#include "llstatusbar.h"
#include "llfloaterworldmap.h"
#include "llviewermessage.h"
+static LLRegisterPanelClassWrapper<LLPanelGroupLandMoney> t_panel_group_money("panel_group_land_money");
+
+
+
////////////////////////////////////////////////////////////////////////////
+//*************************************************
+//** LLGroupMoneyTabEventHandler::impl Functions **
+//*************************************************
+
+class LLGroupMoneyTabEventHandlerImpl
+{
+public:
+ LLGroupMoneyTabEventHandlerImpl(LLButton* earlier_buttonp,
+ LLButton* later_buttonp,
+ LLTextEditor* text_editorp,
+ LLPanel* tabpanelp,
+ const std::string& loading_text,
+ S32 interval_length_days,
+ S32 max_interval_days);
+ ~LLGroupMoneyTabEventHandlerImpl();
+
+ bool getCanClickLater();
+ bool getCanClickEarlier();
+
+ void updateButtons();
+
+ void setGroupID(const LLUUID& group_id) { mGroupID = group_id; } ;
+ const LLUUID& getGroupID() const { return mGroupID;}
+
+
+//member variables
+public:
+ LLUUID mPanelID;
+ LLUUID mGroupID;
+
+ LLPanel* mTabPanelp;
+
+ int mIntervalLength;
+ int mMaxInterval;
+ int mCurrentInterval;
+
+ LLTextEditor* mTextEditorp;
+ LLButton* mEarlierButtonp;
+ LLButton* mLaterButtonp;
+
+ std::string mLoadingText;
+};
+
class LLGroupMoneyTabEventHandler
{
@@ -66,7 +118,6 @@ public:
LLTabContainer* tab_containerp,
LLPanel* panelp,
const std::string& loading_text,
- const LLUUID& group_id,
S32 interval_length_days,
S32 max_interval_days);
virtual ~LLGroupMoneyTabEventHandler();
@@ -78,15 +129,17 @@ public:
virtual void onClickLater();
virtual void onClickTab();
+ void setGroupID(const LLUUID& group_id) { if(mImplementationp) mImplementationp->setGroupID(group_id); } ;
+
static void clickEarlierCallback(void* data);
static void clickLaterCallback(void* data);
- static void clickTabCallback(void* user_data, bool from_click);
+
+
static LLMap<LLUUID, LLGroupMoneyTabEventHandler*> sInstanceIDs;
static std::map<LLPanel*, LLGroupMoneyTabEventHandler*> sTabsToHandlers;
protected:
- class impl;
- impl* mImplementationp;
+ LLGroupMoneyTabEventHandlerImpl* mImplementationp;
};
class LLGroupMoneyDetailsTabEventHandler : public LLGroupMoneyTabEventHandler
@@ -97,8 +150,8 @@ public:
LLTextEditor* text_editorp,
LLTabContainer* tab_containerp,
LLPanel* panelp,
- const std::string& loading_text,
- const LLUUID& group_id);
+ const std::string& loading_text
+ );
virtual ~LLGroupMoneyDetailsTabEventHandler();
virtual void requestData(LLMessageSystem* msg);
@@ -114,8 +167,8 @@ public:
LLTextEditor* text_editorp,
LLTabContainer* tab_containerp,
LLPanel* panelp,
- const std::string& loading_text,
- const LLUUID& group_id);
+ const std::string& loading_text
+ );
virtual ~LLGroupMoneySalesTabEventHandler();
virtual void requestData(LLMessageSystem* msg);
@@ -128,8 +181,8 @@ public:
LLGroupMoneyPlanningTabEventHandler(LLTextEditor* text_editor,
LLTabContainer* tab_containerp,
LLPanel* panelp,
- const std::string& loading_text,
- const LLUUID& group_id);
+ const std::string& loading_text
+ );
virtual ~LLGroupMoneyPlanningTabEventHandler();
virtual void requestData(LLMessageSystem* msg);
@@ -141,7 +194,7 @@ public:
class LLPanelGroupLandMoney::impl
{
public:
- impl(LLPanelGroupLandMoney& panel, const LLUUID& group_id); //constructor
+ impl(LLPanelGroupLandMoney& panel); //constructor
virtual ~impl();
void requestGroupLandInfo();
@@ -175,7 +228,6 @@ public:
LLScrollListCtrl* mGroupParcelsp;
- LLUUID mGroupID;
LLUUID mTransID;
bool mBeenActivated;
@@ -189,9 +241,8 @@ public:
//*******************************************
//** LLPanelGroupLandMoney::impl Functions **
//*******************************************
-LLPanelGroupLandMoney::impl::impl(LLPanelGroupLandMoney& panel, const LLUUID& group_id)
- : mPanel(panel),
- mGroupID(group_id)
+LLPanelGroupLandMoney::impl::impl(LLPanelGroupLandMoney& panel)
+ : mPanel(panel)
{
mTransID = LLUUID::null;
@@ -224,7 +275,7 @@ void LLPanelGroupLandMoney::impl::requestGroupLandInfo()
mTransID.generate();
mGroupParcelsp->deleteAllItems();
- send_places_query(mGroupID, mTransID, "", query_flags, LLParcel::C_ANY, "");
+ send_places_query(mPanel.mGroupID, mTransID, "", query_flags, LLParcel::C_ANY, "");
}
void LLPanelGroupLandMoney::impl::onMapButton()
@@ -244,9 +295,12 @@ void LLPanelGroupLandMoney::impl::onMapButton()
F64 global_z = gAgent.getPositionGlobal().mdV[VZ];
LLVector3d pos_global(global_x, global_y, global_z);
- gFloaterWorldMap->trackLocation(pos_global);
-
- LLFloaterWorldMap::show(NULL, TRUE);
+ LLFloaterWorldMap* worldmap_instance = LLFloaterWorldMap::getInstance();
+ if(worldmap_instance)
+ {
+ worldmap_instance->trackLocation(pos_global);
+ LLFloaterReg::showInstance("world_map", "center");
+ }
}
bool LLPanelGroupLandMoney::impl::applyContribution()
@@ -271,7 +325,7 @@ bool LLPanelGroupLandMoney::impl::applyContribution()
new_contribution <= sqm_avail )
{
// update group info and server
- if(!gAgent.setGroupContribution(mGroupID, new_contribution))
+ if(!gAgent.setGroupContribution(mPanel.mGroupID, new_contribution))
{
// should never happen...
llwarns << "Unable to set contribution." << llendl;
@@ -298,7 +352,7 @@ int LLPanelGroupLandMoney::impl::getStoredContribution()
LLGroupData group_data;
group_data.mContribution = 0;
- gAgent.getGroupData(mGroupID, group_data);
+ gAgent.getGroupData(mPanel.mGroupID, group_data);
return group_data.mContribution;
}
@@ -397,13 +451,7 @@ void LLPanelGroupLandMoney::impl::processGroupLand(LLMessageSystem* msg)
if ( trans_id != mTransID ) return;
// This power was removed to make group roles simpler
//if ( !gAgent.hasPowerInGroup(mGroupID, GP_LAND_VIEW_OWNED) ) return;
- if (!gAgent.isInGroup(mGroupID)) return;
-
- //we updated more than just the available area special block
- if ( count > 1)
- {
- mMapButtonp->setEnabled(TRUE);
- }
+ if (!gAgent.isInGroup(mPanel.mGroupID)) return;
std::string name;
std::string desc;
@@ -460,15 +508,15 @@ void LLPanelGroupLandMoney::impl::processGroupLand(LLMessageSystem* msg)
row["columns"][0]["column"] = "name";
row["columns"][0]["value"] = name;
- row["columns"][0]["font"] = "SANSSERIFSMALL";
+ row["columns"][0]["font"] = "SANSSERIF_SMALL";
row["columns"][1]["column"] = "location";
row["columns"][1]["value"] = location;
- row["columns"][1]["font"] = "SANSSERIFSMALL";
+ row["columns"][1]["font"] = "SANSSERIF_SMALL";
row["columns"][2]["column"] = "area";
row["columns"][2]["value"] = area;
- row["columns"][2]["font"] = "SANSSERIFSMALL";
+ row["columns"][2]["font"] = "SANSSERIF_SMALL";
row["columns"][3]["column"] = "type";
row["columns"][3]["value"] = land_type;
@@ -487,26 +535,22 @@ void LLPanelGroupLandMoney::impl::processGroupLand(LLMessageSystem* msg)
//** LLPanelGroupLandMoney Functions **
//*************************************
-//static
-void* LLPanelGroupLandMoney::createTab(void* data)
-{
- LLUUID* group_id = static_cast<LLUUID*>(data);
- return new LLPanelGroupLandMoney("panel group land money", *group_id);
-}
//static
LLMap<LLUUID, LLPanelGroupLandMoney*> LLPanelGroupLandMoney::sGroupIDs;
-LLPanelGroupLandMoney::LLPanelGroupLandMoney(const std::string& name,
- const LLUUID& group_id) :
- LLPanelGroupTab(name, group_id)
+LLPanelGroupLandMoney::LLPanelGroupLandMoney() :
+ LLPanelGroupTab()
{
- mImplementationp = new impl(*this, group_id);
+ //FIXME - add setGroupID();
+ mImplementationp = new impl(*this);
//problem what if someone has both the group floater open and the finder
//open to the same group? Some maps that map group ids to panels
//will then only be working for the last panel for a given group id :(
- LLPanelGroupLandMoney::sGroupIDs.addData(group_id, this);
+
+ //FIXME - add to setGroupID()
+ //LLPanelGroupLandMoney::sGroupIDs.addData(group_id, this);
}
LLPanelGroupLandMoney::~LLPanelGroupLandMoney()
@@ -553,6 +597,7 @@ void LLPanelGroupLandMoney::activate()
mImplementationp->setYourMaxContributionTextBox(max_avail);
}
+ mImplementationp->mMapButtonp->setEnabled(false);
update(GC_ALL);
}
@@ -634,9 +679,8 @@ BOOL LLPanelGroupLandMoney::postBuild()
{
LLLineEditor* editor = mImplementationp->mYourContributionEditorp;
- editor->setCommitCallback(mImplementationp->contributionCommitCallback);
- editor->setKeystrokeCallback(mImplementationp->contributionKeystrokeCallback);
- editor->setCallbackUserData(this);
+ editor->setCommitCallback(mImplementationp->contributionCommitCallback, this);
+ editor->setKeystrokeCallback(mImplementationp->contributionKeystrokeCallback, this);
}
mImplementationp->mMapButtonp = getChild<LLButton>("map_button");
@@ -644,6 +688,12 @@ BOOL LLPanelGroupLandMoney::postBuild()
mImplementationp->mGroupParcelsp =
getChild<LLScrollListCtrl>("group_parcel_list");
+ if ( mImplementationp->mGroupParcelsp )
+ {
+ mImplementationp->mGroupParcelsp->setCommitCallback(boost::bind(&LLButton::setEnabled, mImplementationp->mMapButtonp, true));
+ mImplementationp->mGroupParcelsp->setCommitOnSelectionChange(true);
+ }
+
mImplementationp->mCantViewParcelsText = getString("cant_view_group_land_text");
mImplementationp->mCantViewAccountsText = getString("cant_view_group_accounting_text");
@@ -662,16 +712,11 @@ BOOL LLPanelGroupLandMoney::postBuild()
mImplementationp->mGroupOverLimitIconp->setVisible(FALSE);
}
- if ( mImplementationp->mMapButtonp )
- {
- mImplementationp->mMapButtonp->setEnabled(FALSE);
- }
-
if ( !can_view )
{
if ( mImplementationp->mGroupParcelsp )
{
- mImplementationp->mGroupParcelsp->addCommentText(
+ mImplementationp->mGroupParcelsp->setCommentText(
mImplementationp->mCantViewParcelsText);
mImplementationp->mGroupParcelsp->setEnabled(FALSE);
}
@@ -719,8 +764,7 @@ BOOL LLPanelGroupLandMoney::postBuild()
textp,
tabcp,
panelp,
- loading_text,
- mGroupID);
+ loading_text);
}
textp = getChild<LLTextEditor>("group_money_planning_text", true);
@@ -737,8 +781,7 @@ BOOL LLPanelGroupLandMoney::postBuild()
new LLGroupMoneyPlanningTabEventHandler(textp,
tabcp,
panelp,
- loading_text,
- mGroupID);
+ loading_text);
}
//pull out the widgets for the L$ sales tab
@@ -759,8 +802,7 @@ BOOL LLPanelGroupLandMoney::postBuild()
textp,
tabcp,
panelp,
- loading_text,
- mGroupID);
+ loading_text);
}
return LLPanelGroupTab::postBuild();
@@ -787,56 +829,15 @@ void LLPanelGroupLandMoney::processPlacesReply(LLMessageSystem* msg, void**)
selfp->mImplementationp->processGroupLand(msg);
}
-//*************************************************
-//** LLGroupMoneyTabEventHandler::impl Functions **
-//*************************************************
-
-class LLGroupMoneyTabEventHandler::impl
-{
-public:
- impl(LLButton* earlier_buttonp,
- LLButton* later_buttonp,
- LLTextEditor* text_editorp,
- LLPanel* tabpanelp,
- const std::string& loading_text,
- const LLUUID& group_id,
- S32 interval_length_days,
- S32 max_interval_days);
- ~impl();
-
- bool getCanClickLater();
- bool getCanClickEarlier();
-
- void updateButtons();
-
-//member variables
-public:
- LLUUID mGroupID;
- LLUUID mPanelID;
-
- LLPanel* mTabPanelp;
-
- int mIntervalLength;
- int mMaxInterval;
- int mCurrentInterval;
-
- LLTextEditor* mTextEditorp;
- LLButton* mEarlierButtonp;
- LLButton* mLaterButtonp;
- std::string mLoadingText;
-};
-
-LLGroupMoneyTabEventHandler::impl::impl(LLButton* earlier_buttonp,
+LLGroupMoneyTabEventHandlerImpl::LLGroupMoneyTabEventHandlerImpl(LLButton* earlier_buttonp,
LLButton* later_buttonp,
LLTextEditor* text_editorp,
LLPanel* tabpanelp,
const std::string& loading_text,
- const LLUUID& group_id,
S32 interval_length_days,
S32 max_interval_days)
{
- mGroupID = group_id;
mPanelID.generate();
mIntervalLength = interval_length_days;
@@ -851,21 +852,21 @@ LLGroupMoneyTabEventHandler::impl::impl(LLButton* earlier_buttonp,
mLoadingText = loading_text;
}
-LLGroupMoneyTabEventHandler::impl::~impl()
+LLGroupMoneyTabEventHandlerImpl::~LLGroupMoneyTabEventHandlerImpl()
{
}
-bool LLGroupMoneyTabEventHandler::impl::getCanClickEarlier()
+bool LLGroupMoneyTabEventHandlerImpl::getCanClickEarlier()
{
return (mCurrentInterval < mMaxInterval);
}
-bool LLGroupMoneyTabEventHandler::impl::getCanClickLater()
+bool LLGroupMoneyTabEventHandlerImpl::getCanClickLater()
{
return ( mCurrentInterval > 0 );
}
-void LLGroupMoneyTabEventHandler::impl::updateButtons()
+void LLGroupMoneyTabEventHandlerImpl::updateButtons()
{
if ( mEarlierButtonp )
{
@@ -890,16 +891,14 @@ LLGroupMoneyTabEventHandler::LLGroupMoneyTabEventHandler(LLButton* earlier_butto
LLTabContainer* tab_containerp,
LLPanel* panelp,
const std::string& loading_text,
- const LLUUID& group_id,
S32 interval_length_days,
S32 max_interval_days)
{
- mImplementationp = new impl(earlier_buttonp,
+ mImplementationp = new LLGroupMoneyTabEventHandlerImpl(earlier_buttonp,
later_buttonp,
text_editorp,
panelp,
loading_text,
- group_id,
interval_length_days,
max_interval_days);
@@ -917,8 +916,7 @@ LLGroupMoneyTabEventHandler::LLGroupMoneyTabEventHandler(LLButton* earlier_butto
if ( tab_containerp && panelp )
{
- tab_containerp->setTabChangeCallback(panelp, clickTabCallback);
- tab_containerp->setTabUserData(panelp, this);
+ tab_containerp->setCommitCallback(boost::bind(&LLGroupMoneyTabEventHandler::onClickTab, this));
}
sInstanceIDs.addData(mImplementationp->mPanelID, this);
@@ -990,13 +988,6 @@ void LLGroupMoneyTabEventHandler::clickLaterCallback(void* data)
if ( selfp ) selfp->onClickLater();
}
-//static
-void LLGroupMoneyTabEventHandler::clickTabCallback(void* data, bool from_click)
-{
- LLGroupMoneyTabEventHandler* selfp = (LLGroupMoneyTabEventHandler*) data;
- if ( selfp && from_click ) selfp->onClickTab();
-}
-
//**************************************************
//** LLGroupMoneyDetailsTabEventHandler Functions **
//**************************************************
@@ -1006,15 +997,13 @@ LLGroupMoneyDetailsTabEventHandler::LLGroupMoneyDetailsTabEventHandler(LLButton*
LLTextEditor* text_editorp,
LLTabContainer* tab_containerp,
LLPanel* panelp,
- const std::string& loading_text,
- const LLUUID& group_id)
+ const std::string& loading_text)
: LLGroupMoneyTabEventHandler(earlier_buttonp,
later_buttonp,
text_editorp,
tab_containerp,
panelp,
loading_text,
- group_id,
SUMMARY_INTERVAL,
SUMMARY_MAX)
{
@@ -1030,7 +1019,7 @@ void LLGroupMoneyDetailsTabEventHandler::requestData(LLMessageSystem* msg)
msg->nextBlockFast(_PREHASH_AgentData);
msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID() );
msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID() );
- msg->addUUIDFast(_PREHASH_GroupID, mImplementationp->mGroupID );
+ msg->addUUIDFast(_PREHASH_GroupID, mImplementationp->getGroupID() );
msg->nextBlockFast(_PREHASH_MoneyData);
msg->addUUIDFast(_PREHASH_RequestID, mImplementationp->mPanelID );
msg->addS32Fast(_PREHASH_IntervalDays, mImplementationp->mIntervalLength );
@@ -1051,7 +1040,7 @@ void LLGroupMoneyDetailsTabEventHandler::processReply(LLMessageSystem* msg,
{
LLUUID group_id;
msg->getUUIDFast(_PREHASH_AgentData, _PREHASH_GroupID, group_id );
- if (mImplementationp->mGroupID != group_id)
+ if (mImplementationp->getGroupID() != group_id)
{
llwarns << "Group Account details not for this group!" << llendl;
return;
@@ -1100,7 +1089,7 @@ void LLGroupMoneyDetailsTabEventHandler::processReply(LLMessageSystem* msg,
text.append(1, '\n');
- text.append(llformat("%-24s %6d\n", "Total", total_amount));
+ text.append(llformat("%-24s %6d\n", LLTrans::getString("GroupMoneyTotal").c_str(), total_amount));
if ( mImplementationp->mTextEditorp )
{
@@ -1141,15 +1130,13 @@ LLGroupMoneySalesTabEventHandler::LLGroupMoneySalesTabEventHandler(LLButton* ear
LLTextEditor* text_editorp,
LLTabContainer* tab_containerp,
LLPanel* panelp,
- const std::string& loading_text,
- const LLUUID& group_id)
+ const std::string& loading_text)
: LLGroupMoneyTabEventHandler(earlier_buttonp,
later_buttonp,
text_editorp,
tab_containerp,
panelp,
loading_text,
- group_id,
SUMMARY_INTERVAL,
SUMMARY_MAX)
{
@@ -1165,7 +1152,7 @@ void LLGroupMoneySalesTabEventHandler::requestData(LLMessageSystem* msg)
msg->nextBlockFast(_PREHASH_AgentData);
msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID() );
msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID() );
- msg->addUUIDFast(_PREHASH_GroupID, mImplementationp->mGroupID );
+ msg->addUUIDFast(_PREHASH_GroupID, mImplementationp->getGroupID() );
msg->nextBlockFast(_PREHASH_MoneyData);
msg->addUUIDFast(_PREHASH_RequestID, mImplementationp->mPanelID );
msg->addS32Fast(_PREHASH_IntervalDays, mImplementationp->mIntervalLength );
@@ -1186,7 +1173,7 @@ void LLGroupMoneySalesTabEventHandler::processReply(LLMessageSystem* msg,
{
LLUUID group_id;
msg->getUUIDFast(_PREHASH_AgentData, _PREHASH_GroupID, group_id );
- if (mImplementationp->mGroupID != group_id)
+ if (mImplementationp->getGroupID() != group_id)
{
llwarns << "Group Account Transactions not for this group!" << llendl;
return;
@@ -1220,7 +1207,7 @@ void LLGroupMoneySalesTabEventHandler::processReply(LLMessageSystem* msg,
S32 transactions = msg->getNumberOfBlocksFast(_PREHASH_HistoryData);
if (transactions == 0)
{
- text.append("(none)");
+ text.append(LLTrans::getString("none_text"));
}
else
{
@@ -1245,22 +1232,22 @@ void LLGroupMoneySalesTabEventHandler::processReply(LLMessageSystem* msg,
switch(type)
{
case TRANS_OBJECT_SALE:
- verb = "bought";
+ verb = LLTrans::getString("GroupMoneyBought").c_str();
break;
case TRANS_GIFT:
- verb = "paid you";
+ verb = LLTrans::getString("GroupMoneyPaidYou").c_str();
break;
case TRANS_PAY_OBJECT:
- verb = "paid into";
+ verb = LLTrans::getString("GroupMoneyPaidInto").c_str();
break;
case TRANS_LAND_PASS_SALE:
- verb = "bought pass to";
+ verb = LLTrans::getString("GroupMoneyBoughtPassTo").c_str();
break;
case TRANS_EVENT_FEE:
- verb = "paid fee for event";
+ verb = LLTrans::getString("GroupMoneyPaidFeeForEvent").c_str();
break;
case TRANS_EVENT_PRIZE:
- verb = "paid prize for event";
+ verb = LLTrans::getString("GroupMoneyPaidPrizeForEvent").c_str();
break;
default:
verb = "";
@@ -1313,15 +1300,13 @@ void LLPanelGroupLandMoney::processGroupAccountTransactionsReply(LLMessageSystem
LLGroupMoneyPlanningTabEventHandler::LLGroupMoneyPlanningTabEventHandler(LLTextEditor* text_editorp,
LLTabContainer* tab_containerp,
LLPanel* panelp,
- const std::string& loading_text,
- const LLUUID& group_id)
+ const std::string& loading_text)
: LLGroupMoneyTabEventHandler(NULL,
NULL,
text_editorp,
tab_containerp,
panelp,
loading_text,
- group_id,
SUMMARY_INTERVAL,
SUMMARY_MAX)
{
@@ -1337,7 +1322,7 @@ void LLGroupMoneyPlanningTabEventHandler::requestData(LLMessageSystem* msg)
msg->nextBlockFast(_PREHASH_AgentData);
msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID() );
msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID() );
- msg->addUUIDFast(_PREHASH_GroupID, mImplementationp->mGroupID );
+ msg->addUUIDFast(_PREHASH_GroupID, mImplementationp->getGroupID() );
msg->nextBlockFast(_PREHASH_MoneyData);
msg->addUUIDFast(_PREHASH_RequestID, mImplementationp->mPanelID );
msg->addS32Fast(_PREHASH_IntervalDays, mImplementationp->mIntervalLength);
@@ -1358,7 +1343,7 @@ void LLGroupMoneyPlanningTabEventHandler::processReply(LLMessageSystem* msg,
{
LLUUID group_id;
msg->getUUIDFast(_PREHASH_AgentData, _PREHASH_GroupID, group_id );
- if (mImplementationp->mGroupID != group_id)
+ if (mImplementationp->getGroupID() != group_id)
{
llwarns << "Group Account Summary received not for this group!" << llendl;
return;
@@ -1420,24 +1405,24 @@ void LLGroupMoneyPlanningTabEventHandler::processReply(LLMessageSystem* msg,
return;
}
- text.append("Summary for this week, beginning on ");
+ text.append(LLTrans::getString("SummaryForTheWeek"));
text.append(start_date);
if (current_interval == 0)
{
- text.append("The next stipend day is ");
+ text.append(LLTrans::getString("NextStipendDay"));
text.append(next_stipend_date);
text.append("\n\n");
- text.append(llformat("%-24sL$%6d\n", "Balance", balance ));
+ text.append(llformat("%-24sL$%6d\n", LLTrans::getString("GroupMoneyBalance").c_str(), balance ));
text.append(1, '\n');
}
// [DEV-29503] Hide the individual info since
// non_exempt_member here is a wrong choice to calculate individual shares.
- // text.append( " Group Individual Share\n");
- // text.append(llformat( "%-24s %6d %6d \n", "Credits", total_credits, (S32)floor((F32)total_credits/(F32)non_exempt_members)));
- // text.append(llformat( "%-24s %6d %6d \n", "Debits", total_debits, (S32)floor((F32)total_debits/(F32)non_exempt_members)));
- // text.append(llformat( "%-24s %6d %6d \n", "Total", total_credits + total_debits, (S32)floor((F32)(total_credits + total_debits)/(F32)non_exempt_members)));
+// text.append( LLTrans::getString("GroupIndividualShare"));
+// text.append(llformat( "%-24s %6d %6d \n", LLTrans::getString("GroupMoneyCredits").c_str(), total_credits, (S32)floor((F32)total_credits/(F32)non_exempt_members)));
+// text.append(llformat( "%-24s %6d %6d \n", LLTrans::getString("GroupMoneyDebits").c_str(), total_debits, (S32)floor((F32)total_debits/(F32)non_exempt_members)));
+// text.append(llformat( "%-24s %6d %6d \n", LLTrans::getString("GroupMoneyTotal").c_str(), total_credits + total_debits, (S32)floor((F32)(total_credits + total_debits)/(F32)non_exempt_members)));
text.append( " Group\n");
text.append(llformat( "%-24s %6d\n", "Credits", total_credits));
@@ -1476,3 +1461,140 @@ void LLPanelGroupLandMoney::processGroupAccountSummaryReply(LLMessageSystem* msg
self->processReply(msg, data);
}
+
+void LLPanelGroupLandMoney::setGroupID(const LLUUID& id)
+{
+ LLPanelGroupLandMoney::sGroupIDs.removeData(mGroupID);
+ LLPanelGroupTab::setGroupID(id);
+ LLPanelGroupLandMoney::sGroupIDs.addData(mGroupID, this);
+
+
+ bool can_view = gAgent.isInGroup(mGroupID);
+
+ mImplementationp->mGroupOverLimitIconp =
+ getChild<LLIconCtrl>("group_over_limit_icon");
+ mImplementationp->mGroupOverLimitTextp =
+ getChild<LLTextBox>("group_over_limit_text");
+
+ mImplementationp->mYourContributionEditorp
+ = getChild<LLLineEditor>("your_contribution_line_editor");
+ if ( mImplementationp->mYourContributionEditorp )
+ {
+ LLLineEditor* editor = mImplementationp->mYourContributionEditorp;
+
+ editor->setCommitCallback(mImplementationp->contributionCommitCallback, this);
+ editor->setKeystrokeCallback(mImplementationp->contributionKeystrokeCallback, this);
+ }
+
+ mImplementationp->mMapButtonp = getChild<LLButton>("map_button");
+
+ mImplementationp->mGroupParcelsp =
+ getChild<LLScrollListCtrl>("group_parcel_list");
+
+ if ( mImplementationp->mGroupParcelsp )
+ {
+ mImplementationp->mGroupParcelsp->setCommitCallback(boost::bind(&LLButton::setEnabled, mImplementationp->mMapButtonp, true));
+ mImplementationp->mGroupParcelsp->setCommitOnSelectionChange(true);
+ }
+
+ mImplementationp->mCantViewParcelsText = getString("cant_view_group_land_text");
+ mImplementationp->mCantViewAccountsText = getString("cant_view_group_accounting_text");
+
+ if ( mImplementationp->mMapButtonp )
+ {
+ mImplementationp->mMapButtonp->setClickedCallback(LLPanelGroupLandMoney::impl::mapCallback, mImplementationp);
+ }
+
+ if ( mImplementationp->mGroupOverLimitTextp )
+ {
+ mImplementationp->mGroupOverLimitTextp->setVisible(FALSE);
+ }
+
+ if ( mImplementationp->mGroupOverLimitIconp )
+ {
+ mImplementationp->mGroupOverLimitIconp->setVisible(FALSE);
+ }
+
+ if ( mImplementationp->mGroupParcelsp )
+ {
+ mImplementationp->mGroupParcelsp->setEnabled(can_view);
+ }
+
+ if ( !can_view && mImplementationp->mGroupParcelsp )
+ {
+ mImplementationp->mGroupParcelsp->setEnabled(FALSE);
+ }
+
+
+ LLButton* earlierp, *laterp;
+ LLTextEditor* textp;
+ LLPanel* panelp;
+
+ LLTabContainer* tabcp = getChild<LLTabContainer>("group_money_tab_container");
+
+ if ( tabcp )
+ {
+ S32 i;
+ S32 tab_count = tabcp->getTabCount();
+
+ for (i = tab_count - 1; i >=0; --i)
+ {
+ tabcp->enableTabButton(i, can_view );
+ }
+ }
+
+ std::string loading_text = getString("loading_txt");
+
+ //pull out the widgets for the L$ details tab
+ earlierp = getChild<LLButton>("earlier_details_button", true);
+ laterp = getChild<LLButton>("later_details_button", true);
+ textp = getChild<LLTextEditor>("group_money_details_text", true);
+ panelp = getChild<LLPanel>("group_money_details_tab", true);
+
+ if ( !can_view )
+ {
+ textp->setText(mImplementationp->mCantViewAccountsText);
+ }
+ else
+ {
+ if(mImplementationp->mMoneyDetailsTabEHp == 0)
+ mImplementationp->mMoneyDetailsTabEHp = new LLGroupMoneyDetailsTabEventHandler(earlierp,laterp,textp,tabcp,panelp,loading_text);
+ mImplementationp->mMoneyDetailsTabEHp->setGroupID(mGroupID);
+ }
+
+ textp = getChild<LLTextEditor>("group_money_planning_text", true);
+
+
+ if ( !can_view )
+ {
+ textp->setText(mImplementationp->mCantViewAccountsText);
+ }
+ else
+ {
+ panelp = getChild<LLPanel>("group_money_planning_tab", true);
+ if(mImplementationp->mMoneyPlanningTabEHp == 0)
+ mImplementationp->mMoneyPlanningTabEHp = new LLGroupMoneyPlanningTabEventHandler(textp,tabcp,panelp,loading_text);
+ mImplementationp->mMoneyPlanningTabEHp->setGroupID(mGroupID);
+ }
+
+ //pull out the widgets for the L$ sales tab
+ textp = getChild<LLTextEditor>("group_money_sales_text", true);
+
+
+ if ( !can_view )
+ {
+ textp->setText(mImplementationp->mCantViewAccountsText);
+ }
+ else
+ {
+ earlierp = getChild<LLButton>("earlier_sales_button", true);
+ laterp = getChild<LLButton>("later_sales_button", true);
+ panelp = getChild<LLPanel>("group_money_sales_tab", true);
+ if(mImplementationp->mMoneySalesTabEHp == NULL)
+ mImplementationp->mMoneySalesTabEHp = new LLGroupMoneySalesTabEventHandler(earlierp,laterp,textp,tabcp,panelp,loading_text);
+ mImplementationp->mMoneySalesTabEHp->setGroupID(mGroupID);
+ }
+
+ activate();
+}
+
diff --git a/indra/newview/llpanelgrouplandmoney.h b/indra/newview/llpanelgrouplandmoney.h
index 591511a5fb..0f275ea9a8 100644
--- a/indra/newview/llpanelgrouplandmoney.h
+++ b/indra/newview/llpanelgrouplandmoney.h
@@ -37,20 +37,14 @@
#include "llmap.h"
#include "lluuid.h"
-#include "llbutton.h"
-#include "lltexteditor.h"
-#include "llpanel.h"
-
class LLPanelGroupLandMoney : public LLPanelGroupTab
{
public:
- LLPanelGroupLandMoney(const std::string& name, const LLUUID& group_id);
+ LLPanelGroupLandMoney();
virtual ~LLPanelGroupLandMoney();
virtual BOOL postBuild();
virtual BOOL isVisibleByAgent(LLAgent* agentp);
- static void* createTab(void* data);
-
virtual void activate();
virtual bool needsApply(std::string& mesg);
virtual bool apply(std::string& mesg);
@@ -64,6 +58,8 @@ public:
static void processGroupAccountDetailsReply(LLMessageSystem* msg, void** data);
static void processGroupAccountTransactionsReply(LLMessageSystem* msg, void** data);
static void processGroupAccountSummaryReply(LLMessageSystem* msg, void** data);
+
+ virtual void setGroupID(const LLUUID& id);
protected:
class impl;
diff --git a/indra/newview/llpanelgroupnotices.cpp b/indra/newview/llpanelgroupnotices.cpp
index 5824df46e2..0ce85818dd 100644
--- a/indra/newview/llpanelgroupnotices.cpp
+++ b/indra/newview/llpanelgroupnotices.cpp
@@ -39,8 +39,9 @@
#include "llinventory.h"
#include "llviewerinventory.h"
#include "llinventorymodel.h"
-#include "llinventoryview.h"
+#include "llfloaterinventory.h"
#include "llagent.h"
+#include "llagentui.h"
#include "lltooldraganddrop.h"
#include "lllineeditor.h"
@@ -49,13 +50,18 @@
#include "lliconctrl.h"
#include "llcheckboxctrl.h"
#include "llscrolllistctrl.h"
+#include "llscrolllistitem.h"
#include "lltextbox.h"
+#include "lltrans.h"
#include "roles_constants.h"
#include "llviewerwindow.h"
#include "llviewermessage.h"
#include "llnotifications.h"
+static LLRegisterPanelClassWrapper<LLPanelGroupNotices> t_panel_group_notices("panel_group_notices");
+
+
/////////////////////////
// LLPanelGroupNotices //
/////////////////////////
@@ -69,7 +75,21 @@
class LLGroupDropTarget : public LLView
{
public:
- LLGroupDropTarget(const std::string& name, const LLRect& rect, LLPanelGroupNotices* panel, const LLUUID& group_id);
+ struct Params : public LLInitParam::Block<Params, LLView::Params>
+ {
+ // *NOTE: These parameters logically Mandatory, but are not
+ // specified in XML files, hence Optional
+ Optional<LLPanelGroupNotices*> panel;
+ Optional<LLUUID> group_id;
+ Params()
+ : panel("panel"),
+ group_id("group_id")
+ {
+ mouse_opaque(false);
+ follows.flags(FOLLOWS_ALL);
+ }
+ };
+ LLGroupDropTarget(const Params&);
~LLGroupDropTarget() {};
void doDrop(EDragAndDropType cargo_type, void* cargo_data);
@@ -81,18 +101,21 @@ public:
void* cargo_data,
EAcceptance* accept,
std::string& tooltip_msg);
+ void setPanel (LLPanelGroupNotices* panel) {mGroupNoticesPanel = panel;};
+ void setGroup (LLUUID group) {mGroupID = group;};
+
protected:
LLPanelGroupNotices* mGroupNoticesPanel;
LLUUID mGroupID;
};
-LLGroupDropTarget::LLGroupDropTarget(const std::string& name, const LLRect& rect,
- LLPanelGroupNotices* panel, const LLUUID& group_id) :
- LLView(name, rect, NOT_MOUSE_OPAQUE, FOLLOWS_ALL),
- mGroupNoticesPanel(panel),
- mGroupID(group_id)
-{
-}
+static LLDefaultChildRegistry::Register<LLGroupDropTarget> r("group_drop_target");
+
+LLGroupDropTarget::LLGroupDropTarget(const LLGroupDropTarget::Params& p)
+: LLView(p),
+ mGroupNoticesPanel(p.panel),
+ mGroupID(p.group_id)
+{}
void LLGroupDropTarget::doDrop(EDragAndDropType cargo_type, void* cargo_data)
{
@@ -133,6 +156,7 @@ BOOL LLGroupDropTarget::handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop,
case DAD_BODYPART:
case DAD_ANIMATION:
case DAD_GESTURE:
+ case DAD_CALLINGCARD:
{
LLViewerInventoryItem* inv_item = (LLViewerInventoryItem*)cargo_data;
if(gInventory.getItem(inv_item->getUUID())
@@ -156,7 +180,6 @@ BOOL LLGroupDropTarget::handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop,
break;
}
case DAD_CATEGORY:
- case DAD_CALLINGCARD:
default:
*accept = ACCEPT_NO;
break;
@@ -179,22 +202,22 @@ std::string build_notice_date(const U32& the_time)
time(&t);
}
- tm* lt = localtime(&t);
-
- //for some reason, the month is off by 1. See other uses of
- //"local" time in the code...
- std::string buffer = llformat("%04i-%02i-%02i", lt->tm_year + 1900, lt->tm_mon + 1, lt->tm_mday);
-
- return buffer;
+ std::string dateStr = "["+LLTrans::getString("LTimeMthNum")+"]/["
+ +LLTrans::getString("LTimeDay")+"]/["
+ +LLTrans::getString("LTimeYear")+"]";
+ LLSD substitution;
+ substitution["datetime"] = (S32) t;
+ LLStringUtil::format (dateStr, substitution);
+ return dateStr;
}
-LLPanelGroupNotices::LLPanelGroupNotices(const std::string& name,
- const LLUUID& group_id) :
- LLPanelGroupTab(name,group_id),
+LLPanelGroupNotices::LLPanelGroupNotices() :
+ LLPanelGroupTab(),
mInventoryItem(NULL),
mInventoryOffer(NULL)
{
- sInstances[group_id] = this;
+
+
}
LLPanelGroupNotices::~LLPanelGroupNotices()
@@ -210,12 +233,6 @@ LLPanelGroupNotices::~LLPanelGroupNotices()
}
}
-// static
-void* LLPanelGroupNotices::createTab(void* data)
-{
- LLUUID* group_id = static_cast<LLUUID*>(data);
- return new LLPanelGroupNotices("panel group notices", *group_id);
-}
BOOL LLPanelGroupNotices::isVisibleByAgent(LLAgent* agentp)
{
@@ -229,17 +246,14 @@ BOOL LLPanelGroupNotices::postBuild()
mNoticesList = getChild<LLScrollListCtrl>("notice_list",recurse);
mNoticesList->setCommitOnSelectionChange(TRUE);
- mNoticesList->setCommitCallback(onSelectNotice);
- mNoticesList->setCallbackUserData(this);
+ mNoticesList->setCommitCallback(onSelectNotice, this);
mBtnNewMessage = getChild<LLButton>("create_new_notice",recurse);
- mBtnNewMessage->setClickedCallback(onClickNewMessage);
- mBtnNewMessage->setCallbackUserData(this);
+ mBtnNewMessage->setClickedCallback(onClickNewMessage, this);
mBtnNewMessage->setEnabled(gAgent.hasPowerInGroup(mGroupID, GP_NOTICES_SEND));
mBtnGetPastNotices = getChild<LLButton>("refresh_notices",recurse);
- mBtnGetPastNotices->setClickedCallback(onClickRefreshNotices);
- mBtnGetPastNotices->setCallbackUserData(this);
+ mBtnGetPastNotices->setClickedCallback(onClickRefreshNotices, this);
// Create
mCreateSubject = getChild<LLLineEditor>("create_subject",recurse);
@@ -253,12 +267,10 @@ BOOL LLPanelGroupNotices::postBuild()
mCreateInventoryIcon->setVisible(FALSE);
mBtnSendMessage = getChild<LLButton>("send_notice",recurse);
- mBtnSendMessage->setClickedCallback(onClickSendMessage);
- mBtnSendMessage->setCallbackUserData(this);
+ mBtnSendMessage->setClickedCallback(onClickSendMessage, this);
mBtnRemoveAttachment = getChild<LLButton>("remove_attachment",recurse);
- mBtnRemoveAttachment->setClickedCallback(onClickRemoveAttachment);
- mBtnRemoveAttachment->setCallbackUserData(this);
+ mBtnRemoveAttachment->setClickedCallback(onClickRemoveAttachment, this);
mBtnRemoveAttachment->setEnabled(FALSE);
// View
@@ -273,24 +285,16 @@ BOOL LLPanelGroupNotices::postBuild()
mViewInventoryIcon->setVisible(FALSE);
mBtnOpenAttachment = getChild<LLButton>("open_attachment",recurse);
- mBtnOpenAttachment->setClickedCallback(onClickOpenAttachment);
- mBtnOpenAttachment->setCallbackUserData(this);
+ mBtnOpenAttachment->setClickedCallback(onClickOpenAttachment, this);
mNoNoticesStr = getString("no_notices_text");
mPanelCreateNotice = getChild<LLPanel>("panel_create_new_notice",recurse);
mPanelViewNotice = getChild<LLPanel>("panel_view_past_notice",recurse);
- // Must be in front of all other UI elements.
- LLPanel* dtv = getChild<LLPanel>("drop_target",recurse);
- LLGroupDropTarget* target = new LLGroupDropTarget("drop_target",
- dtv->getRect(),
- this, mGroupID);
- target->setEnabled(TRUE);
- target->setToolTip(dtv->getToolTip());
-
- mPanelCreateNotice->addChild(target);
- mPanelCreateNotice->removeChild(dtv, TRUE);
+ LLGroupDropTarget* target = getChild<LLGroupDropTarget> ("drop_target");
+ target->setPanel (this);
+ target->setGroup (mGroupID);
arrangeNoticeView(VIEW_PAST_NOTICE);
@@ -331,7 +335,7 @@ void LLPanelGroupNotices::setItem(LLPointer<LLInventoryItem> inv_item)
inv_item->getFlags(),
item_is_multi );
- mCreateInventoryIcon->setImage(icon_name);
+ mCreateInventoryIcon->setValue(icon_name);
mCreateInventoryIcon->setVisible(TRUE);
std::stringstream ss;
@@ -376,13 +380,38 @@ void LLPanelGroupNotices::onClickSendMessage(void* data)
self->mCreateMessage->getText(),
self->mInventoryItem);
+
+ //instantly add new notice. actual notice will be added after ferreshNotices call
+ LLUUID id = LLUUID::generateNewID();
+ std::string subj = self->mCreateSubject->getText();
+ std::string name ;
+ LLAgentUI::buildFullname(name);
+ U32 timestamp = 0;
+
+ LLSD row;
+ row["id"] = id;
+
+ row["columns"][0]["column"] = "icon";
+
+ row["columns"][1]["column"] = "subject";
+ row["columns"][1]["value"] = subj;
+
+ row["columns"][2]["column"] = "from";
+ row["columns"][2]["value"] = name;
+
+ row["columns"][3]["column"] = "date";
+ row["columns"][3]["value"] = build_notice_date(timestamp);
+
+ row["columns"][4]["column"] = "sort";
+ row["columns"][4]["value"] = llformat( "%u", timestamp);
+
+ self->mNoticesList->addElement(row, ADD_BOTTOM);
+
self->mCreateMessage->clear();
self->mCreateSubject->clear();
onClickRemoveAttachment(data);
self->arrangeNoticeView(VIEW_PAST_NOTICE);
- onClickRefreshNotices(self);
-
}
//static
@@ -404,6 +433,26 @@ void LLPanelGroupNotices::onClickNewMessage(void* data)
self->mNoticesList->deselectAllItems(TRUE); // TRUE == don't commit on chnage
}
+void LLPanelGroupNotices::refreshNotices()
+{
+ onClickRefreshNotices(this);
+ /*
+ lldebugs << "LLPanelGroupNotices::onClickGetPastNotices" << llendl;
+
+ mNoticesList->deleteAllItems();
+
+ LLMessageSystem* msg = gMessageSystem;
+ msg->newMessage("GroupNoticesListRequest");
+ msg->nextBlock("AgentData");
+ msg->addUUID("AgentID",gAgent.getID());
+ msg->addUUID("SessionID",gAgent.getSessionID());
+ msg->nextBlock("Data");
+ msg->addUUID("GroupID",self->mGroupID);
+ gAgent.sendReliableMessage();
+ */
+
+}
+
void LLPanelGroupNotices::onClickRefreshNotices(void* data)
{
lldebugs << "LLPanelGroupNotices::onClickGetPastNotices" << llendl;
@@ -466,7 +515,7 @@ void LLPanelGroupNotices::processNotices(LLMessageSystem* msg)
if (1 == count && id.isNull())
{
// Only one entry, the dummy entry.
- mNoticesList->addCommentText(mNoNoticesStr);
+ mNoticesList->setCommentText(mNoNoticesStr);
mNoticesList->setEnabled(FALSE);
return;
}
@@ -505,7 +554,7 @@ void LLPanelGroupNotices::processNotices(LLMessageSystem* msg)
mNoticesList->addElement(row, ADD_BOTTOM);
}
- mNoticesList->sortItems();
+ mNoticesList->updateSort();
}
void LLPanelGroupNotices::onSelectNotice(LLUICtrl* ctrl, void* data)
@@ -554,7 +603,7 @@ void LLPanelGroupNotices::showNotice(const std::string& subject,
LLInventoryType::IT_TEXTURE,
0, FALSE);
- mViewInventoryIcon->setImage(icon_name);
+ mViewInventoryIcon->setValue(icon_name);
mViewInventoryIcon->setVisible(TRUE);
std::stringstream ss;
@@ -585,3 +634,17 @@ void LLPanelGroupNotices::arrangeNoticeView(ENoticeView view_type)
mBtnOpenAttachment->setEnabled(FALSE);
}
}
+void LLPanelGroupNotices::setGroupID(const LLUUID& id)
+{
+ sInstances.erase(mGroupID);
+ LLPanelGroupTab::setGroupID(id);
+ sInstances[mGroupID] = this;
+
+ mBtnNewMessage->setEnabled(gAgent.hasPowerInGroup(mGroupID, GP_NOTICES_SEND));
+
+ LLGroupDropTarget* target = getChild<LLGroupDropTarget> ("drop_target");
+ target->setPanel (this);
+ target->setGroup (mGroupID);
+
+ activate();
+}
diff --git a/indra/newview/llpanelgroupnotices.h b/indra/newview/llpanelgroupnotices.h
index 916032c1b6..4bda38c897 100644
--- a/indra/newview/llpanelgroupnotices.h
+++ b/indra/newview/llpanelgroupnotices.h
@@ -34,7 +34,7 @@
#define LL_LLPANELGROUPNOTICES_H
#include "llpanelgroup.h"
-#include "llmemory.h"
+#include "llpointer.h"
#include "llinventory.h"
class LLLineEditor;
@@ -47,11 +47,10 @@ class LLScrollListCtrl;
class LLPanelGroupNotices : public LLPanelGroupTab
{
public:
- LLPanelGroupNotices(const std::string& name, const LLUUID& group_id);
+ LLPanelGroupNotices();
virtual ~LLPanelGroupNotices();
// LLPanelGroupTab
- static void* createTab(void* data);
virtual void activate();
//virtual bool needsApply(std::string& mesg);
//virtual bool apply(std::string& mesg);
@@ -70,6 +69,10 @@ public:
const std::string& inventory_name,
LLOfferInfo* inventory_offer);
+ void refreshNotices();
+
+ virtual void setGroupID(const LLUUID& id);
+
private:
static void onClickRemoveAttachment(void* data);
static void onClickOpenAttachment(void* data);
diff --git a/indra/newview/llpanelgrouproles.cpp b/indra/newview/llpanelgrouproles.cpp
index 6e65181f99..4618b49df4 100644
--- a/indra/newview/llpanelgrouproles.cpp
+++ b/indra/newview/llpanelgrouproles.cpp
@@ -36,23 +36,28 @@
#include "llagent.h"
#include "llbutton.h"
-#include "llfloateravatarinfo.h"
#include "llfloatergroupinvite.h"
+#include "llavataractions.h"
#include "lliconctrl.h"
#include "lllineeditor.h"
#include "llnamelistctrl.h"
#include "llnotify.h"
#include "llpanelgrouproles.h"
#include "llscrolllistctrl.h"
+#include "llscrolllistitem.h"
+#include "llscrolllistcell.h"
#include "lltabcontainer.h"
#include "lltextbox.h"
#include "lltexteditor.h"
-#include "llviewerimagelist.h"
+#include "llsearcheditor.h"
+#include "llviewertexturelist.h"
#include "llviewerwindow.h"
#include "llfocusmgr.h"
#include "roles_constants.h"
+static LLRegisterPanelClassWrapper<LLPanelGroupRoles> t_panel_group_roles("panel_group_roles");
+
bool agentCanRemoveFromRole(const LLUUID& group_id,
const LLUUID& role_id)
{
@@ -106,14 +111,9 @@ bool agentCanAddToRole(const LLUUID& group_id,
}
// static
-void* LLPanelGroupRoles::createTab(void* data)
-{
- LLUUID* group_id = static_cast<LLUUID*>(data);
- return new LLPanelGroupRoles("panel group roles", *group_id);
-}
-LLPanelGroupRoles::LLPanelGroupRoles(const std::string& name, const LLUUID& group_id)
-: LLPanelGroupTab(name, group_id),
+LLPanelGroupRoles::LLPanelGroupRoles()
+: LLPanelGroupTab(),
mCurrentTab(NULL),
mRequestedTab( NULL ),
mSubTabContainer( NULL ),
@@ -124,13 +124,6 @@ LLPanelGroupRoles::LLPanelGroupRoles(const std::string& name, const LLUUID& grou
LLPanelGroupRoles::~LLPanelGroupRoles()
{
- int i;
- for (i = 0; i < mSubTabContainer->getTabCount(); ++i)
- {
- LLPanelGroupSubTab* subtabp = (LLPanelGroupSubTab*) mSubTabContainer->getPanelByIndex(i);
-
- subtabp->removeObserver(this);
- }
}
BOOL LLPanelGroupRoles::postBuild()
@@ -142,20 +135,24 @@ BOOL LLPanelGroupRoles::postBuild()
if (!mSubTabContainer) return FALSE;
// Hook up each sub-tabs callback and widgets.
- S32 i;
- for (i = 0; i < mSubTabContainer->getTabCount(); ++i)
+ for (S32 i = 0; i < mSubTabContainer->getTabCount(); ++i)
{
- LLPanelGroupSubTab* subtabp = (LLPanelGroupSubTab*) mSubTabContainer->getPanelByIndex(i);
-
+ LLPanel* panel = mSubTabContainer->getPanelByIndex(i);
+ LLPanelGroupSubTab* subtabp = dynamic_cast<LLPanelGroupSubTab*>(panel);
+ if (!subtabp)
+ {
+ llwarns << "Invalid subtab panel: " << panel->getName() << llendl;
+ return FALSE;
+ }
// Add click callbacks to all the tabs.
- mSubTabContainer->setTabChangeCallback(subtabp, onClickSubTab);
- mSubTabContainer->setTabUserData(subtabp, this);
+ mSubTabContainer->setCommitCallback(boost::bind(&LLPanelGroupRoles::handleClickSubTab, this));
// Hand the subtab a pointer to this LLPanelGroupRoles, so that it can
// look around for the widgets it is interested in.
- if (!subtabp->postBuildSubTab(this)) return FALSE;
+ if (!subtabp->postBuildSubTab(this))
+ return FALSE;
- subtabp->addObserver(this);
+ //subtabp->addObserver(this);
}
// Set the current tab to whatever is currently being shown.
@@ -198,13 +195,6 @@ BOOL LLPanelGroupRoles::isVisibleByAgent(LLAgent* agentp)
}
-// static
-void LLPanelGroupRoles::onClickSubTab(void* user_data, bool from_click)
-{
- LLPanelGroupRoles* self = static_cast<LLPanelGroupRoles*>(user_data);
- self->handleClickSubTab();
-}
-
void LLPanelGroupRoles::handleClickSubTab()
{
// If we are already handling a transition,
@@ -388,7 +378,8 @@ std::string LLPanelGroupRoles::getHelpText() const
void LLPanelGroupRoles::update(LLGroupChange gc)
{
if (mGroupID.isNull()) return;
-
+
+
LLPanelGroupTab* panelp = (LLPanelGroupTab*) mSubTabContainer->getCurrentPanel();
if (panelp)
{
@@ -398,6 +389,7 @@ void LLPanelGroupRoles::update(LLGroupChange gc)
{
llwarns << "LLPanelGroupRoles::update() -- No subtab to update!" << llendl;
}
+
}
void LLPanelGroupRoles::activate()
@@ -465,22 +457,15 @@ BOOL LLPanelGroupRoles::hasModal()
return panelp->hasModal();
}
-// PanelGroupTab observer trigger
-void LLPanelGroupRoles::tabChanged()
-{
- notifyObservers();
-}
////////////////////////////
// LLPanelGroupSubTab
////////////////////////////
-LLPanelGroupSubTab::LLPanelGroupSubTab(const std::string& name, const LLUUID& group_id)
-: LLPanelGroupTab(name, group_id),
+LLPanelGroupSubTab::LLPanelGroupSubTab()
+: LLPanelGroupTab(),
mHeader(NULL),
mFooter(NULL),
- mSearchLineEditor(NULL),
- mSearchButton(NULL),
- mShowAllButton(NULL)
+ mSearchEditor(NULL)
{
}
@@ -492,112 +477,65 @@ BOOL LLPanelGroupSubTab::postBuild()
{
// Hook up the search widgets.
bool recurse = true;
- mSearchLineEditor = getChild<LLLineEditor>("search_text", recurse);
-
- if (!mSearchLineEditor) return FALSE;
- mSearchLineEditor->setKeystrokeCallback(onSearchKeystroke);
- mSearchLineEditor->setCallbackUserData(this);
+ mSearchEditor = getChild<LLSearchEditor>("filter_input", recurse);
- mSearchButton = getChild<LLButton>("search_button", recurse);
-
- if (!mSearchButton) return FALSE;
- mSearchButton->setClickedCallback(onClickSearch);
- mSearchButton->setCallbackUserData(this);
- mSearchButton->setEnabled(FALSE);
+ if (!mSearchEditor)
+ return FALSE;
- mShowAllButton = getChild<LLButton>("show_all_button", recurse);
+ mSearchEditor->setCommitCallback(boost::bind(&LLPanelGroupSubTab::onClickSearch, this));
+ mSearchEditor->setKeystrokeCallback(onSearchKeystroke, this);
- if (!mShowAllButton) return FALSE;
- mShowAllButton->setClickedCallback(onClickShowAll);
- mShowAllButton->setCallbackUserData(this);
- mShowAllButton->setEnabled(FALSE);
// Get icons for later use.
mActionIcons.clear();
- bool no_recurse = false;
-
- LLIconCtrl* icon = getChild<LLIconCtrl>("power_folder_icon",no_recurse);
- if (icon && !icon->getImageName().empty())
+ if (hasString("power_folder_icon"))
{
- mActionIcons["folder"] = icon->getImageName();
- removeChild(icon, TRUE);
+ mActionIcons["folder"] = getString("power_folder_icon");
}
- icon = getChild<LLIconCtrl>("power_all_have_icon",no_recurse);
- if (icon && !icon->getImageName().empty())
+ if (hasString("power_all_have_icon"))
{
- mActionIcons["full"] = icon->getImageName();
- removeChild(icon, TRUE);
+ mActionIcons["full"] = getString("power_all_have_icon");
}
- icon = getChild<LLIconCtrl>("power_partial_icon",no_recurse);
- if (icon && !icon->getImageName().empty())
+ if (hasString("power_partial_icon"))
{
- mActionIcons["partial"] = icon->getImageName();
- removeChild(icon, TRUE);
+ mActionIcons["partial"] = getString("power_partial_icon");
}
return LLPanelGroupTab::postBuild();
}
-// static
-void LLPanelGroupSubTab::onSearchKeystroke(LLLineEditor* caller, void* user_data)
-{
- LLPanelGroupSubTab* self = static_cast<LLPanelGroupSubTab*>(user_data);
- self->handleSearchKeystroke(caller);
-}
-
-void LLPanelGroupSubTab::handleSearchKeystroke(LLLineEditor* caller)
+void LLPanelGroupSubTab::setGroupID(const LLUUID& id)
{
- if (caller->getText().size())
- {
- setDefaultBtn( mSearchButton );
- mSearchButton->setEnabled(TRUE);
- }
- else
+ LLPanelGroupTab::setGroupID(id);
+ if(mSearchEditor)
{
- setDefaultBtn( NULL );
- mSearchButton->setEnabled(FALSE);
+ mSearchEditor->clear();
+ setSearchFilter("");
}
}
-// static
-void LLPanelGroupSubTab::onClickSearch(void* user_data)
+// static
+void LLPanelGroupSubTab::onSearchKeystroke(LLLineEditor* caller, void* user_data)
{
LLPanelGroupSubTab* self = static_cast<LLPanelGroupSubTab*>(user_data);
- self->handleClickSearch();
-}
-
-void LLPanelGroupSubTab::handleClickSearch()
-{
- lldebugs << "LLPanelGroupSubTab::handleClickSearch()" << llendl;
-
- if (0 == mSearchLineEditor->getText().size())
- {
- // No search text. (This shouldn't happen... the search button should have been disabled).
- llwarns << "handleClickSearch with no search text!" << llendl;
- mSearchButton->setEnabled(FALSE);
- return;
- }
+ self->handleSearchKeystroke(caller);
- setSearchFilter( mSearchLineEditor->getText() );
- mShowAllButton->setEnabled(TRUE);
}
-// static
-void LLPanelGroupSubTab::onClickShowAll(void* user_data)
+void LLPanelGroupSubTab::handleSearchKeystroke(LLLineEditor* caller)
{
- LLPanelGroupSubTab* self = static_cast<LLPanelGroupSubTab*>(user_data);
- self->handleClickShowAll();
+ setSearchFilter( caller->getText() );
}
-void LLPanelGroupSubTab::handleClickShowAll()
+// static
+void LLPanelGroupSubTab::onClickSearch()
{
- lldebugs << "LLPanelGroupSubTab::handleClickShowAll()" << llendl;
- setSearchFilter( LLStringUtil::null );
- mShowAllButton->setEnabled(FALSE);
+ setSearchFilter( mSearchEditor->getText() );
}
+
void LLPanelGroupSubTab::setSearchFilter(const std::string& filter)
{
@@ -663,7 +601,7 @@ void LLPanelGroupSubTab::buildActionsList(LLScrollListCtrl* ctrl,
U64 allowed_by_some,
U64 allowed_by_all,
icon_map_t& icons,
- void (*commit_callback)(LLUICtrl*,void*),
+ LLUICtrl::commit_callback_t commit_callback,
BOOL show_all,
BOOL filter,
BOOL is_owner_role)
@@ -696,7 +634,7 @@ void LLPanelGroupSubTab::buildActionCategory(LLScrollListCtrl* ctrl,
U64 allowed_by_all,
LLRoleActionSet* action_set,
icon_map_t& icons,
- void (*commit_callback)(LLUICtrl*,void*),
+ LLUICtrl::commit_callback_t commit_callback,
BOOL show_all,
BOOL filter,
BOOL is_owner_role)
@@ -718,7 +656,7 @@ void LLPanelGroupSubTab::buildActionCategory(LLScrollListCtrl* ctrl,
row["columns"][1]["column"] = "action";
row["columns"][1]["value"] = action_set->mActionSetData->mName;
- row["columns"][1]["font-style"] = "BOLD";
+ row["columns"][1]["font"]["style"] = "BOLD";
LLScrollListItem* title_row = ctrl->addElement(row, ADD_BOTTOM, action_set->mActionSetData);
@@ -799,7 +737,7 @@ void LLPanelGroupSubTab::buildActionCategory(LLScrollListCtrl* ctrl,
row["columns"][column_index]["column"] = "action";
row["columns"][column_index]["value"] = (*ra_it)->mDescription;
- row["columns"][column_index]["font"] = "SANSSERIFSMALL";
+ row["columns"][column_index]["font"] = "SANSSERIF_SMALL";
LLScrollListItem* item = ctrl->addElement(row, ADD_BOTTOM, (*ra_it));
@@ -810,7 +748,6 @@ void LLPanelGroupSubTab::buildActionCategory(LLScrollListCtrl* ctrl,
LLCheckBoxCtrl* check = check_cell->getCheckBox();
check->setEnabled(can_change_actions);
check->setCommitCallback(commit_callback);
- check->setCallbackUserData(ctrl->getCallbackUserData());
check->setToolTip( check->getLabel() );
if (show_all)
@@ -860,15 +797,11 @@ void LLPanelGroupSubTab::setFooterEnabled(BOOL enable)
// LLPanelGroupMembersSubTab
////////////////////////////
-// static
-void* LLPanelGroupMembersSubTab::createTab(void* data)
-{
- LLUUID* group_id = static_cast<LLUUID*>(data);
- return new LLPanelGroupMembersSubTab("panel group members sub tab", *group_id);
-}
-LLPanelGroupMembersSubTab::LLPanelGroupMembersSubTab(const std::string& name, const LLUUID& group_id)
-: LLPanelGroupSubTab(name, group_id),
+static LLRegisterPanelClassWrapper<LLPanelGroupMembersSubTab> t_panel_group_members_subtab("panel_group_members_subtab");
+
+LLPanelGroupMembersSubTab::LLPanelGroupMembersSubTab()
+: LLPanelGroupSubTab(),
mMembersList(NULL),
mAssignedRolesList(NULL),
mAllowedActionsList(NULL),
@@ -900,31 +833,34 @@ BOOL LLPanelGroupMembersSubTab::postBuildSubTab(LLView* root)
if (!mMembersList || !mAssignedRolesList || !mAllowedActionsList) return FALSE;
// We want to be notified whenever a member is selected.
- mMembersList->setCallbackUserData(this);
mMembersList->setCommitOnSelectionChange(TRUE);
- mMembersList->setCommitCallback(onMemberSelect);
+ mMembersList->setCommitCallback(onMemberSelect, this);
// Show the member's profile on double click.
- mMembersList->setDoubleClickCallback(onMemberDoubleClick);
+ mMembersList->setDoubleClickCallback(onMemberDoubleClick, this);
LLButton* button = parent->getChild<LLButton>("member_invite", recurse);
if ( button )
{
- button->setClickedCallback(onInviteMember);
- button->setCallbackUserData(this);
+ button->setClickedCallback(onInviteMember, this);
button->setEnabled(gAgent.hasPowerInGroup(mGroupID, GP_MEMBER_INVITE));
}
mEjectBtn = parent->getChild<LLButton>("member_eject", recurse);
if ( mEjectBtn )
{
- mEjectBtn->setClickedCallback(onEjectMembers);
- mEjectBtn->setCallbackUserData(this);
+ mEjectBtn->setClickedCallback(onEjectMembers, this);
mEjectBtn->setEnabled(FALSE);
}
return TRUE;
}
+void LLPanelGroupMembersSubTab::setGroupID(const LLUUID& id)
+{
+ LLPanelGroupSubTab::setGroupID(id);
+
+}
+
// static
void LLPanelGroupMembersSubTab::onMemberSelect(LLUICtrl* ctrl, void* user_data)
@@ -1097,8 +1033,7 @@ void LLPanelGroupMembersSubTab::handleMemberSelect()
// Extract the checkbox that was created.
LLScrollListCheck* check_cell = (LLScrollListCheck*) item->getColumn(0);
LLCheckBoxCtrl* check = check_cell->getCheckBox();
- check->setCommitCallback(onRoleCheck);
- check->setCallbackUserData(this);
+ check->setCommitCallback(onRoleCheck, this);
check->set( count > 0 );
check->setTentative(
(0 != count)
@@ -1311,7 +1246,7 @@ void LLPanelGroupMembersSubTab::handleMemberDoubleClick()
LLScrollListItem* selected = mMembersList->getFirstSelected();
if (selected)
{
- LLFloaterAvatarInfo::showFromDirectory( selected->getUUID() );
+ LLAvatarActions::showProfile(selected->getUUID());
}
}
@@ -1628,7 +1563,7 @@ void LLPanelGroupMembersSubTab::update(LLGroupChange gc)
retrieved << "Retrieving role member mappings...";
}
mMembersList->setEnabled(FALSE);
- mMembersList->addCommentText(retrieved.str());
+ mMembersList->setCommentText(retrieved.str());
}
}
@@ -1691,7 +1626,7 @@ void LLPanelGroupMembersSubTab::updateMembers()
row["columns"][2]["column"] = "online";
row["columns"][2]["value"] = mMemberProgress->second->getOnlineStatus();
- row["columns"][2]["font"] = "SANSSERIFSMALL";
+ row["columns"][2]["font"] = "SANSSERIF_SMALL";
mMembersList->addElement(row);//, ADD_SORTED);
mHasMatch = TRUE;
@@ -1707,7 +1642,7 @@ void LLPanelGroupMembersSubTab::updateMembers()
else
{
mMembersList->setEnabled(FALSE);
- mMembersList->addCommentText(std::string("No match."));
+ mMembersList->setCommentText(std::string("No match."));
}
}
else
@@ -1725,15 +1660,21 @@ void LLPanelGroupMembersSubTab::updateMembers()
// LLPanelGroupRolesSubTab
////////////////////////////
-// static
-void* LLPanelGroupRolesSubTab::createTab(void* data)
-{
- LLUUID* group_id = static_cast<LLUUID*>(data);
- return new LLPanelGroupRolesSubTab("panel group roles sub tab", *group_id);
-}
+static LLRegisterPanelClassWrapper<LLPanelGroupRolesSubTab> t_panel_group_roles_subtab("panel_group_roles_subtab");
-LLPanelGroupRolesSubTab::LLPanelGroupRolesSubTab(const std::string& name, const LLUUID& group_id)
-: LLPanelGroupSubTab(name, group_id), mHasRoleChange(FALSE)
+LLPanelGroupRolesSubTab::LLPanelGroupRolesSubTab()
+ : LLPanelGroupSubTab(),
+ mRolesList(NULL),
+ mAssignedMembersList(NULL),
+ mAllowedActionsList(NULL),
+ mRoleName(NULL),
+ mRoleTitle(NULL),
+ mRoleDescription(NULL),
+ mMemberVisibleCheck(NULL),
+ mDeleteRoleButton(NULL),
+ mCreateRoleButton(NULL),
+
+ mHasRoleChange(FALSE)
{
}
@@ -1775,8 +1716,7 @@ BOOL LLPanelGroupRolesSubTab::postBuildSubTab(LLView* root)
parent->getChild<LLButton>("role_create", recurse);
if ( mCreateRoleButton )
{
- mCreateRoleButton->setCallbackUserData(this);
- mCreateRoleButton->setClickedCallback(onCreateRole);
+ mCreateRoleButton->setClickedCallback(onCreateRole, this);
mCreateRoleButton->setEnabled(FALSE);
}
@@ -1784,32 +1724,25 @@ BOOL LLPanelGroupRolesSubTab::postBuildSubTab(LLView* root)
parent->getChild<LLButton>("role_delete", recurse);
if ( mDeleteRoleButton )
{
- mDeleteRoleButton->setCallbackUserData(this);
- mDeleteRoleButton->setClickedCallback(onDeleteRole);
+ mDeleteRoleButton->setClickedCallback(onDeleteRole, this);
mDeleteRoleButton->setEnabled(FALSE);
}
mRolesList->setCommitOnSelectionChange(TRUE);
- mRolesList->setCallbackUserData(this);
- mRolesList->setCommitCallback(onRoleSelect);
+ mRolesList->setCommitCallback(onRoleSelect, this);
- mMemberVisibleCheck->setCallbackUserData(this);
- mMemberVisibleCheck->setCommitCallback(onMemberVisibilityChange);
+ mMemberVisibleCheck->setCommitCallback(onMemberVisibilityChange, this);
mAllowedActionsList->setCommitOnSelectionChange(TRUE);
- mAllowedActionsList->setCallbackUserData(this);
mRoleName->setCommitOnFocusLost(TRUE);
- mRoleName->setCallbackUserData(this);
- mRoleName->setKeystrokeCallback(onPropertiesKey);
+ mRoleName->setKeystrokeCallback(onPropertiesKey, this);
mRoleTitle->setCommitOnFocusLost(TRUE);
- mRoleTitle->setCallbackUserData(this);
- mRoleTitle->setKeystrokeCallback(onPropertiesKey);
+ mRoleTitle->setKeystrokeCallback(onPropertiesKey, this);
mRoleDescription->setCommitOnFocusLost(TRUE);
- mRoleDescription->setCallbackUserData(this);
- mRoleDescription->setCommitCallback(onDescriptionCommit);
+ mRoleDescription->setCommitCallback(onDescriptionCommit, this);
mRoleDescription->setFocusReceivedCallback(onDescriptionFocus, this);
setFooterEnabled(FALSE);
@@ -2060,7 +1993,7 @@ void LLPanelGroupRolesSubTab::handleRoleSelect()
rd.mRolePowers,
0LL,
mActionIcons,
- onActionCheck,
+ boost::bind(&LLPanelGroupRolesSubTab::handleActionCheck, this, _1, false),
TRUE,
FALSE,
is_owner_role);
@@ -2157,24 +2090,18 @@ void LLPanelGroupRolesSubTab::buildMembersList()
}
}
-// static
-void LLPanelGroupRolesSubTab::onActionCheck(LLUICtrl* ctrl, void* user_data)
-{
- LLPanelGroupRolesSubTab* self = static_cast<LLPanelGroupRolesSubTab*>(user_data);
- LLCheckBoxCtrl* check = static_cast<LLCheckBoxCtrl*>(ctrl);
- if (!check || !self) return;
-
- self->handleActionCheck(check);
-}
-
struct ActionCBData
{
LLPanelGroupRolesSubTab* mSelf;
LLCheckBoxCtrl* mCheck;
};
-void LLPanelGroupRolesSubTab::handleActionCheck(LLCheckBoxCtrl* check, bool force)
+void LLPanelGroupRolesSubTab::handleActionCheck(LLUICtrl* ctrl, bool force)
{
+ LLCheckBoxCtrl* check = dynamic_cast<LLCheckBoxCtrl*>(ctrl);
+ if (!check)
+ return;
+
lldebugs << "LLPanelGroupRolesSubTab::handleActionSelect()" << llendl;
LLGroupMgrGroupData* gdatap = LLGroupMgr::getInstance()->getGroupData(mGroupID);
@@ -2438,15 +2365,11 @@ void LLPanelGroupRolesSubTab::saveRoleChanges()
// LLPanelGroupActionsSubTab
////////////////////////////
-// static
-void* LLPanelGroupActionsSubTab::createTab(void* data)
-{
- LLUUID* group_id = static_cast<LLUUID*>(data);
- return new LLPanelGroupActionsSubTab("panel group actions sub tab", *group_id);
-}
+static LLRegisterPanelClassWrapper<LLPanelGroupActionsSubTab> t_panel_group_actions_subtab("panel_group_actions_subtab");
-LLPanelGroupActionsSubTab::LLPanelGroupActionsSubTab(const std::string& name, const LLUUID& group_id)
-: LLPanelGroupSubTab(name, group_id)
+
+LLPanelGroupActionsSubTab::LLPanelGroupActionsSubTab()
+: LLPanelGroupSubTab()
{
}
@@ -2472,12 +2395,8 @@ BOOL LLPanelGroupActionsSubTab::postBuildSubTab(LLView* root)
if (!mActionList || !mActionDescription || !mActionRoles || !mActionMembers) return FALSE;
- mActionList->setCallbackUserData(this);
mActionList->setCommitOnSelectionChange(TRUE);
- mActionList->setCommitCallback(onActionSelect);
-
- mActionMembers->setCallbackUserData(this);
- mActionRoles->setCallbackUserData(this);
+ mActionList->setCommitCallback(boost::bind(&LLPanelGroupActionsSubTab::handleActionSelect, this));
update(GC_ALL);
@@ -2537,13 +2456,6 @@ void LLPanelGroupActionsSubTab::update(LLGroupChange gc)
FALSE);
}
-// static
-void LLPanelGroupActionsSubTab::onActionSelect(LLUICtrl* scroll, void* data)
-{
- LLPanelGroupActionsSubTab* self = static_cast<LLPanelGroupActionsSubTab*>(data);
- self->handleActionSelect();
-}
-
void LLPanelGroupActionsSubTab::handleActionSelect()
{
mActionMembers->deleteAllItems();
@@ -2629,3 +2541,26 @@ void LLPanelGroupActionsSubTab::handleActionSelect()
LLGroupMgr::getInstance()->sendGroupRoleDataRequest(mGroupID);
}
}
+void LLPanelGroupRoles::setGroupID(const LLUUID& id)
+{
+ LLPanelGroupTab::setGroupID(id);
+
+ LLPanelGroupMembersSubTab* group_members_tab = findChild<LLPanelGroupMembersSubTab>("members_sub_tab");
+ LLPanelGroupRolesSubTab* group_roles_tab = findChild<LLPanelGroupRolesSubTab>("roles_sub_tab");
+ LLPanelGroupActionsSubTab* group_actions_tab = findChild<LLPanelGroupActionsSubTab>("actions_sub_tab");
+
+ if(group_members_tab) group_members_tab->setGroupID(id);
+ if(group_roles_tab) group_roles_tab->setGroupID(id);
+ if(group_actions_tab) group_actions_tab->setGroupID(id);
+
+ LLButton* button = getChild<LLButton>("member_invite");
+ if ( button )
+ button->setEnabled(gAgent.hasPowerInGroup(mGroupID, GP_MEMBER_INVITE));
+
+ if(mSubTabContainer)
+ mSubTabContainer->selectTab(0);
+
+ activate();
+}
+
+
diff --git a/indra/newview/llpanelgrouproles.h b/indra/newview/llpanelgrouproles.h
index 95057bbfaf..2a0f31fa0f 100644
--- a/indra/newview/llpanelgrouproles.h
+++ b/indra/newview/llpanelgrouproles.h
@@ -42,17 +42,18 @@ class LLPanelGroupRolesSubTab;
class LLPanelGroupActionsSubTab;
class LLScrollListCtrl;
class LLScrollListItem;
+class LLTextEditor;
+class LLSearchEditor;
// Forward declare for friend usage.
//virtual BOOL LLPanelGroupSubTab::postBuildSubTab(LLView*);
typedef std::map<std::string,std::string> icon_map_t;
-class LLPanelGroupRoles : public LLPanelGroupTab,
- public LLPanelGroupTabObserver
+class LLPanelGroupRoles : public LLPanelGroupTab
{
public:
- LLPanelGroupRoles(const std::string& name, const LLUUID& group_id);
+ LLPanelGroupRoles();
virtual ~LLPanelGroupRoles();
// Allow sub tabs to ask for sibling controls.
@@ -63,8 +64,7 @@ public:
virtual BOOL postBuild();
virtual BOOL isVisibleByAgent(LLAgent* agentp);
- static void* createTab(void* data);
- static void onClickSubTab(void*,bool);
+
void handleClickSubTab();
// Checks if the current tab needs to be applied, and tries to switch to the requested tab.
@@ -87,8 +87,7 @@ public:
virtual void cancel();
virtual void update(LLGroupChange gc);
- // PanelGroupTab observer trigger
- virtual void tabChanged();
+ virtual void setGroupID(const LLUUID& id);
protected:
LLPanelGroupTab* mCurrentTab;
@@ -104,7 +103,7 @@ protected:
class LLPanelGroupSubTab : public LLPanelGroupTab
{
public:
- LLPanelGroupSubTab(const std::string& name, const LLUUID& group_id);
+ LLPanelGroupSubTab();
virtual ~LLPanelGroupSubTab();
virtual BOOL postBuild();
@@ -115,10 +114,7 @@ public:
static void onSearchKeystroke(LLLineEditor* caller, void* user_data);
void handleSearchKeystroke(LLLineEditor* caller);
- static void onClickSearch(void*);
- void handleClickSearch();
- static void onClickShowAll(void*);
- void handleClickShowAll();
+ void onClickSearch();
virtual void setSearchFilter( const std::string& filter );
@@ -131,7 +127,7 @@ public:
U64 allowed_by_some,
U64 allowed_by_all,
icon_map_t& icons,
- void (*commit_callback)(LLUICtrl*,void*),
+ LLUICtrl::commit_callback_t commit_callback,
BOOL show_all,
BOOL filter,
BOOL is_owner_role);
@@ -140,19 +136,19 @@ public:
U64 allowed_by_all,
LLRoleActionSet* action_set,
icon_map_t& icons,
- void (*commit_callback)(LLUICtrl*,void*),
+ LLUICtrl::commit_callback_t commit_callback,
BOOL show_all,
BOOL filter,
BOOL is_owner_role);
void setFooterEnabled(BOOL enable);
+
+ virtual void setGroupID(const LLUUID& id);
protected:
LLPanel* mHeader;
LLPanel* mFooter;
- LLLineEditor* mSearchLineEditor;
- LLButton* mSearchButton;
- LLButton* mShowAllButton;
+ LLSearchEditor* mSearchEditor;
std::string mSearchFilter;
@@ -164,13 +160,11 @@ protected:
class LLPanelGroupMembersSubTab : public LLPanelGroupSubTab
{
public:
- LLPanelGroupMembersSubTab(const std::string& name, const LLUUID& group_id);
+ LLPanelGroupMembersSubTab();
virtual ~LLPanelGroupMembersSubTab();
virtual BOOL postBuildSubTab(LLView* root);
- static void* createTab(void* data);
-
static void onMemberSelect(LLUICtrl*, void*);
void handleMemberSelect();
@@ -200,6 +194,8 @@ public:
virtual void draw();
+ virtual void setGroupID(const LLUUID& id);
+
protected:
typedef std::map<LLUUID, LLRoleMemberChangeType> role_change_data_map_t;
typedef std::map<LLUUID, role_change_data_map_t*> member_role_changes_map_t;
@@ -229,13 +225,11 @@ protected:
class LLPanelGroupRolesSubTab : public LLPanelGroupSubTab
{
public:
- LLPanelGroupRolesSubTab(const std::string& name, const LLUUID& group_id);
+ LLPanelGroupRolesSubTab();
virtual ~LLPanelGroupRolesSubTab();
virtual BOOL postBuildSubTab(LLView* root);
- static void* createTab(void* data);
-
virtual void activate();
virtual void deactivate();
virtual bool needsApply(std::string& mesg);
@@ -249,7 +243,6 @@ public:
void buildMembersList();
static void onActionCheck(LLUICtrl*, void*);
- void handleActionCheck(LLCheckBoxCtrl*, bool force=false);
bool addActionCB(const LLSD& notification, const LLSD& response, LLCheckBoxCtrl* check);
static void onPropertiesKey(LLLineEditor*, void*);
@@ -268,10 +261,8 @@ public:
void saveRoleChanges();
protected:
- LLSD createRoleItem(const LLUUID& role_id,
- std::string name,
- std::string title,
- S32 members);
+ void handleActionCheck(LLUICtrl* ctrl, bool force);
+ LLSD createRoleItem(const LLUUID& role_id, std::string name, std::string title, S32 members);
LLScrollListCtrl* mRolesList;
LLNameListCtrl* mAssignedMembersList;
@@ -293,12 +284,11 @@ protected:
class LLPanelGroupActionsSubTab : public LLPanelGroupSubTab
{
public:
- LLPanelGroupActionsSubTab(const std::string& name, const LLUUID& group_id);
+ LLPanelGroupActionsSubTab();
virtual ~LLPanelGroupActionsSubTab();
virtual BOOL postBuildSubTab(LLView* root);
- static void* createTab(void* data);
virtual void activate();
virtual void deactivate();
@@ -306,7 +296,6 @@ public:
virtual bool apply(std::string& mesg);
virtual void update(LLGroupChange gc);
- static void onActionSelect(LLUICtrl*, void*);
void handleActionSelect();
protected:
LLScrollListCtrl* mActionList;
diff --git a/indra/newview/llpanelimcontrolpanel.cpp b/indra/newview/llpanelimcontrolpanel.cpp
new file mode 100644
index 0000000000..51cdc5af93
--- /dev/null
+++ b/indra/newview/llpanelimcontrolpanel.cpp
@@ -0,0 +1,113 @@
+/**
+ * @file llpanelavatar.cpp
+ * @brief LLPanelAvatar and related class implementations
+ *
+ * $LicenseInfo:firstyear=2004&license=viewergpl$
+ *
+ * Copyright (c) 2004-2009, Linden Research, Inc.
+ *
+ * Second Life Viewer Source Code
+ * The source code in this file ("Source Code") is provided by Linden Lab
+ * to you under the terms of the GNU General Public License, version 2.0
+ * ("GPL"), unless you have obtained a separate licensing agreement
+ * ("Other License"), formally executed by you and Linden Lab. Terms of
+ * the GPL can be found in doc/GPL-license.txt in this distribution, or
+ * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
+ *
+ * There are special exceptions to the terms and conditions of the GPL as
+ * it is applied to this Source Code. View the full text of the exception
+ * in the file doc/FLOSS-exception.txt in this software distribution, or
+ * online at
+ * http://secondlifegrid.net/programs/open_source/licensing/flossexception
+ *
+ * By copying, modifying or distributing this software, you acknowledge
+ * that you have read and understood your obligations described above,
+ * and agree to abide by those obligations.
+ *
+ * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+ * COMPLETENESS OR PERFORMANCE.
+ * $/LicenseInfo$
+ */
+
+#include "llviewerprecompiledheaders.h"
+
+#include "llpanelimcontrolpanel.h"
+
+#include "llavataractions.h"
+#include "llavatariconctrl.h"
+#include "llbutton.h"
+#include "llgroupactions.h"
+
+LLPanelIMControlPanel::LLPanelIMControlPanel()
+{
+}
+
+LLPanelIMControlPanel::~LLPanelIMControlPanel()
+{
+}
+
+BOOL LLPanelIMControlPanel::postBuild()
+{
+ childSetAction("view_profile_btn", boost::bind(&LLPanelIMControlPanel::onViewProfileButtonClicked, this));
+ childSetAction("add_friend_btn", boost::bind(&LLPanelIMControlPanel::onAddFriendButtonClicked, this));
+ childSetAction("call_btn", boost::bind(&LLPanelIMControlPanel::onCallButtonClicked, this));
+ childSetAction("share_btn", boost::bind(&LLPanelIMControlPanel::onShareButtonClicked, this));
+ childSetEnabled("add_friend_btn", !LLAvatarActions::isFriend(getChild<LLAvatarIconCtrl>("avatar_icon")->getAvatarId()));
+
+ return TRUE;
+}
+
+void LLPanelIMControlPanel::onViewProfileButtonClicked()
+{
+ LLAvatarActions::showProfile(getChild<LLAvatarIconCtrl>("avatar_icon")->getAvatarId());
+}
+
+void LLPanelIMControlPanel::onAddFriendButtonClicked()
+{
+ LLAvatarIconCtrl* avatar_icon = getChild<LLAvatarIconCtrl>("avatar_icon");
+ std::string full_name = avatar_icon->getFirstName() + " " + avatar_icon->getLastName();
+ LLAvatarActions::requestFriendshipDialog(avatar_icon->getAvatarId(), full_name);
+}
+
+void LLPanelIMControlPanel::onCallButtonClicked()
+{
+ // *TODO: Implement
+}
+
+void LLPanelIMControlPanel::onShareButtonClicked()
+{
+ // *TODO: Implement
+}
+
+void LLPanelIMControlPanel::setID(const LLUUID& avatar_id)
+{
+ getChild<LLAvatarIconCtrl>("avatar_icon")->setValue(avatar_id);
+}
+
+
+
+BOOL LLPanelGroupControlPanel::postBuild()
+{
+ childSetAction("group_info_btn", boost::bind(&LLPanelGroupControlPanel::onGroupInfoButtonClicked, this));
+ childSetAction("call_btn", boost::bind(&LLPanelGroupControlPanel::onCallButtonClicked, this));
+
+ return TRUE;
+}
+
+void LLPanelGroupControlPanel::onGroupInfoButtonClicked()
+{
+ LLGroupActions::show(mGroupID);
+}
+
+
+void LLPanelGroupControlPanel::onCallButtonClicked()
+{
+ // *TODO: Implement
+}
+
+
+void LLPanelGroupControlPanel::setID(const LLUUID& id)
+{
+ mGroupID = id;
+}
diff --git a/indra/newview/llpanelimcontrolpanel.h b/indra/newview/llpanelimcontrolpanel.h
new file mode 100644
index 0000000000..e82942a31d
--- /dev/null
+++ b/indra/newview/llpanelimcontrolpanel.h
@@ -0,0 +1,87 @@
+/**
+ * @file llpanelimcontrolpanel.h
+ * @brief LLPanelIMControlPanel and related class definitions
+ *
+ * $LicenseInfo:firstyear=2004&license=viewergpl$
+ *
+ * Copyright (c) 2004-2009, Linden Research, Inc.
+ *
+ * Second Life Viewer Source Code
+ * The source code in this file ("Source Code") is provided by Linden Lab
+ * to you under the terms of the GNU General Public License, version 2.0
+ * ("GPL"), unless you have obtained a separate licensing agreement
+ * ("Other License"), formally executed by you and Linden Lab. Terms of
+ * the GPL can be found in doc/GPL-license.txt in this distribution, or
+ * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
+ *
+ * There are special exceptions to the terms and conditions of the GPL as
+ * it is applied to this Source Code. View the full text of the exception
+ * in the file doc/FLOSS-exception.txt in this software distribution, or
+ * online at
+ * http://secondlifegrid.net/programs/open_source/licensing/flossexception
+ *
+ * By copying, modifying or distributing this software, you acknowledge
+ * that you have read and understood your obligations described above,
+ * and agree to abide by those obligations.
+ *
+ * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+ * COMPLETENESS OR PERFORMANCE.
+ * $/LicenseInfo$
+ */
+
+#ifndef LL_LLPANELIMCONTROLPANEL_H
+#define LL_LLPANELIMCONTROLPANEL_H
+
+#include "llpanel.h"
+
+
+class LLPanelChatControlPanel : public LLPanel
+{
+public:
+ LLPanelChatControlPanel() {};
+ ~LLPanelChatControlPanel() {};
+
+ // sets the group or avatar UUID
+ virtual void setID(const LLUUID& avatar_id)= 0;
+};
+
+
+class LLPanelIMControlPanel : public LLPanelChatControlPanel
+{
+public:
+ LLPanelIMControlPanel();
+ ~LLPanelIMControlPanel();
+
+ BOOL postBuild();
+
+ void setID(const LLUUID& avatar_id);
+
+private:
+ void onViewProfileButtonClicked();
+ void onAddFriendButtonClicked();
+ void onCallButtonClicked();
+ void onShareButtonClicked();
+};
+
+
+class LLPanelGroupControlPanel : public LLPanelChatControlPanel
+{
+public:
+ LLPanelGroupControlPanel() {};
+ ~LLPanelGroupControlPanel() {};
+
+ BOOL postBuild();
+
+ void setID(const LLUUID& id);
+
+private:
+ void onGroupInfoButtonClicked();
+ void onCallButtonClicked();
+
+ LLUUID mGroupID;
+};
+
+
+
+#endif // LL_LLPANELIMCONTROLPANEL_H
diff --git a/indra/newview/llpanelland.cpp b/indra/newview/llpanelland.cpp
index 8bb100d335..bce5525a40 100644
--- a/indra/newview/llpanelland.cpp
+++ b/indra/newview/llpanelland.cpp
@@ -40,6 +40,7 @@
#include "llbutton.h"
#include "llcheckboxctrl.h"
#include "llfloaterland.h"
+#include "llfloaterreg.h"
#include "lltextbox.h"
#include "llviewercontrol.h"
#include "llviewerparcelmgr.h"
@@ -79,8 +80,8 @@ BOOL LLPanelLandInfo::postBuild()
//
// Methods
//
-LLPanelLandInfo::LLPanelLandInfo(const std::string& name)
-: LLPanel(name),
+LLPanelLandInfo::LLPanelLandInfo()
+: LLPanel(),
mCheckShowOwners(NULL)
{
if (!sInstance)
@@ -262,7 +263,7 @@ void LLPanelLandInfo::onClickAbout(void*)
LLViewerParcelMgr::getInstance()->selectParcelInRectangle();
}
- LLFloaterLand::showInstance();
+ LLFloaterReg::showInstance("about_land");
}
void LLPanelLandInfo::onShowOwnersHelp(void* user_data)
diff --git a/indra/newview/llpanelland.h b/indra/newview/llpanelland.h
index 9a7e977711..92fe313405 100644
--- a/indra/newview/llpanelland.h
+++ b/indra/newview/llpanelland.h
@@ -46,7 +46,7 @@ class LLPanelLandInfo
: public LLPanel
{
public:
- LLPanelLandInfo(const std::string& name);
+ LLPanelLandInfo();
virtual ~LLPanelLandInfo();
void refresh();
diff --git a/indra/newview/llpanellandaudio.cpp b/indra/newview/llpanellandaudio.cpp
new file mode 100644
index 0000000000..920fca66f2
--- /dev/null
+++ b/indra/newview/llpanellandaudio.cpp
@@ -0,0 +1,192 @@
+/**
+ * @file llpanellandaudio.cpp
+ * @brief Allows configuration of "media" for a land parcel,
+ * for example movies, web pages, and audio.
+ *
+ * $LicenseInfo:firstyear=2007&license=viewergpl$
+ *
+ * Copyright (c) 2007-2008, Linden Research, Inc.
+ *
+ * Second Life Viewer Source Code
+ * The source code in this file ("Source Code") is provided by Linden Lab
+ * to you under the terms of the GNU General Public License, version 2.0
+ * ("GPL"), unless you have obtained a separate licensing agreement
+ * ("Other License"), formally executed by you and Linden Lab. Terms of
+ * the GPL can be found in doc/GPL-license.txt in this distribution, or
+ * online at http://secondlife.com/developers/opensource/gplv2
+ *
+ * There are special exceptions to the terms and conditions of the GPL as
+ * it is applied to this Source Code. View the full text of the exception
+ * in the file doc/FLOSS-exception.txt in this software distribution, or
+ * online at http://secondlife.com/developers/opensource/flossexception
+ *
+ * By copying, modifying or distributing this software, you acknowledge
+ * that you have read and understood your obligations described above,
+ * and agree to abide by those obligations.
+ *
+ * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+ * COMPLETENESS OR PERFORMANCE.
+ * $/LicenseInfo$
+ */
+
+#include "llviewerprecompiledheaders.h"
+
+#include "llpanellandaudio.h"
+
+// viewer includes
+#include "llmimetypes.h"
+#include "llviewerparcelmgr.h"
+#include "lluictrlfactory.h"
+
+// library includes
+#include "llcheckboxctrl.h"
+#include "llcombobox.h"
+#include "llfloaterurlentry.h"
+#include "llfocusmgr.h"
+#include "lllineeditor.h"
+#include "llparcel.h"
+#include "lltextbox.h"
+#include "llradiogroup.h"
+#include "llspinctrl.h"
+#include "llsdutil.h"
+#include "lltexturectrl.h"
+#include "roles_constants.h"
+#include "llscrolllistctrl.h"
+
+// Values for the parcel voice settings radio group
+enum
+{
+ kRadioVoiceChatEstate = 0,
+ kRadioVoiceChatPrivate = 1,
+ kRadioVoiceChatDisable = 2
+};
+
+//---------------------------------------------------------------------------
+// LLPanelLandAudio
+//---------------------------------------------------------------------------
+
+LLPanelLandAudio::LLPanelLandAudio(LLParcelSelectionHandle& parcel)
+: LLPanel(/*std::string("land_media_panel")*/), mParcel(parcel)
+{
+}
+
+
+// virtual
+LLPanelLandAudio::~LLPanelLandAudio()
+{
+}
+
+
+BOOL LLPanelLandAudio::postBuild()
+{
+ mCheckSoundLocal = getChild<LLCheckBoxCtrl>("check sound local");
+ childSetCommitCallback("check sound local", onCommitAny, this);
+
+ mRadioVoiceChat = getChild<LLRadioGroup>("parcel_voice_channel");
+ childSetCommitCallback("parcel_voice_channel", onCommitAny, this);
+
+ mMusicURLEdit = getChild<LLLineEditor>("music_url");
+ childSetCommitCallback("music_url", onCommitAny, this);
+
+ mMusicUrlCheck = getChild<LLCheckBoxCtrl>("hide_music_url");
+ childSetCommitCallback("hide_music_url", onCommitAny, this);
+
+ return TRUE;
+}
+
+
+// public
+void LLPanelLandAudio::refresh()
+{
+ LLParcel *parcel = mParcel->getParcel();
+
+ if (!parcel)
+ {
+ clearCtrls();
+ }
+ else
+ {
+ // something selected, hooray!
+
+ // Display options
+ BOOL can_change_media = LLViewerParcelMgr::isParcelModifiableByAgent(parcel, GP_LAND_CHANGE_MEDIA);
+
+ mCheckSoundLocal->set( parcel->getSoundLocal() );
+ mCheckSoundLocal->setEnabled( can_change_media );
+
+ mMusicUrlCheck->set( parcel->getObscureMusic() );
+ mMusicUrlCheck->setEnabled( can_change_media );
+
+ if(parcel->getParcelFlagAllowVoice())
+ {
+ if(parcel->getParcelFlagUseEstateVoiceChannel())
+ mRadioVoiceChat->setSelectedIndex(kRadioVoiceChatEstate);
+ else
+ mRadioVoiceChat->setSelectedIndex(kRadioVoiceChatPrivate);
+ }
+ else
+ {
+ mRadioVoiceChat->setSelectedIndex(kRadioVoiceChatDisable);
+ }
+
+ mRadioVoiceChat->setEnabled( can_change_media );
+
+ mMusicURLEdit->setText(parcel->getMusicURL());
+ mMusicURLEdit->setEnabled( can_change_media );
+ }
+}
+// static
+void LLPanelLandAudio::onCommitAny(LLUICtrl*, void *userdata)
+{
+ LLPanelLandAudio *self = (LLPanelLandAudio *)userdata;
+
+ LLParcel* parcel = self->mParcel->getParcel();
+ if (!parcel)
+ {
+ return;
+ }
+
+ // Extract data from UI
+ BOOL sound_local = self->mCheckSoundLocal->get();
+ int voice_setting = self->mRadioVoiceChat->getSelectedIndex();
+ std::string music_url = self->mMusicURLEdit->getText();
+ U8 obscure_music = self->mMusicUrlCheck->get();
+
+
+ BOOL voice_enabled;
+ BOOL voice_estate_chan;
+
+ switch(voice_setting)
+ {
+ default:
+ case kRadioVoiceChatEstate:
+ voice_enabled = TRUE;
+ voice_estate_chan = TRUE;
+ break;
+ case kRadioVoiceChatPrivate:
+ voice_enabled = TRUE;
+ voice_estate_chan = FALSE;
+ break;
+ case kRadioVoiceChatDisable:
+ voice_enabled = FALSE;
+ voice_estate_chan = FALSE;
+ break;
+ }
+
+ // Remove leading/trailing whitespace (common when copying/pasting)
+ LLStringUtil::trim(music_url);
+
+ // Push data into current parcel
+ parcel->setParcelFlag(PF_ALLOW_VOICE_CHAT, voice_enabled);
+ parcel->setParcelFlag(PF_USE_ESTATE_VOICE_CHAN, voice_estate_chan);
+ parcel->setParcelFlag(PF_SOUND_LOCAL, sound_local);
+ parcel->setMusicURL(music_url);
+ parcel->setObscureMusic(obscure_music);
+
+ // Send current parcel data upstream to server
+ LLViewerParcelMgr::getInstance()->sendParcelPropertiesUpdate( parcel );
+
+ // Might have changed properties, so let's redraw!
+ self->refresh();
+}
diff --git a/indra/newview/llpanellandaudio.h b/indra/newview/llpanellandaudio.h
new file mode 100644
index 0000000000..de5da95fa4
--- /dev/null
+++ b/indra/newview/llpanellandaudio.h
@@ -0,0 +1,62 @@
+/**
+ * @file llpanellandaudio.h
+ * @brief Allows configuration of "audio" for a land parcel.
+ *
+ *
+ * $LicenseInfo:firstyear=2007&license=viewergpl$
+ *
+ * Copyright (c) 2007-2008, Linden Research, Inc.
+ *
+ * Second Life Viewer Source Code
+ * The source code in this file ("Source Code") is provided by Linden Lab
+ * to you under the terms of the GNU General Public License, version 2.0
+ * ("GPL"), unless you have obtained a separate licensing agreement
+ * ("Other License"), formally executed by you and Linden Lab. Terms of
+ * the GPL can be found in doc/GPL-license.txt in this distribution, or
+ * online at http://secondlife.com/developers/opensource/gplv2
+ *
+ * There are special exceptions to the terms and conditions of the GPL as
+ * it is applied to this Source Code. View the full text of the exception
+ * in the file doc/FLOSS-exception.txt in this software distribution, or
+ * online at http://secondlife.com/developers/opensource/flossexception
+ *
+ * By copying, modifying or distributing this software, you acknowledge
+ * that you have read and understood your obligations described above,
+ * and agree to abide by those obligations.
+ *
+ * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+ * COMPLETENESS OR PERFORMANCE.
+ * $/LicenseInfo$
+ */
+
+#ifndef LLPANELLANDAUDIO_H
+#define LLPANELLANDAUDIO_H
+
+#include "lllineeditor.h"
+#include "llpanel.h"
+#include "llparcelselection.h"
+#include "lluifwd.h" // widget pointer types
+
+class LLPanelLandAudio
+ : public LLPanel
+{
+public:
+ LLPanelLandAudio(LLSafeHandle<LLParcelSelection>& parcelp);
+ /*virtual*/ ~LLPanelLandAudio();
+ /*virtual*/ BOOL postBuild();
+ void refresh();
+
+private:
+ static void onCommitAny(LLUICtrl* ctrl, void *userdata);
+
+private:
+ LLCheckBoxCtrl* mCheckSoundLocal;
+ LLRadioGroup* mRadioVoiceChat;
+ LLLineEditor* mMusicURLEdit;
+ LLCheckBoxCtrl* mMusicUrlCheck;
+
+ LLSafeHandle<LLParcelSelection>& mParcel;
+};
+
+#endif
diff --git a/indra/newview/llpanellandmarks.cpp b/indra/newview/llpanellandmarks.cpp
new file mode 100644
index 0000000000..1d79ea4a21
--- /dev/null
+++ b/indra/newview/llpanellandmarks.cpp
@@ -0,0 +1,280 @@
+/**
+ * @file llpanellandmarks.cpp
+ * @brief Landmarks tab for Side Bar "Places" panel
+ *
+ * $LicenseInfo:firstyear=2009&license=viewergpl$
+ *
+ * Copyright (c) 2001-2009, Linden Research, Inc.
+ *
+ * Second Life Viewer Source Code
+ * The source code in this file ("Source Code") is provided by Linden Lab
+ * to you under the terms of the GNU General Public License, version 2.0
+ * ("GPL"), unless you have obtained a separate licensing agreement
+ * ("Other License"), formally executed by you and Linden Lab. Terms of
+ * the GPL can be found in doc/GPL-license.txt in this distribution, or
+ * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
+ *
+ * There are special exceptions to the terms and conditions of the GPL as
+ * it is applied to this Source Code. View the full text of the exception
+ * in the file doc/FLOSS-exception.txt in this software distribution, or
+ * online at http://secondlifegrid.net/programs/open_source/licensing/flossexception
+ *
+ * By copying, modifying or distributing this software, you acknowledge
+ * that you have read and understood your obligations described above,
+ * and agree to abide by those obligations.
+ *
+ * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+ * COMPLETENESS OR PERFORMANCE.
+ * $/LicenseInfo$
+ */
+
+#include "llviewerprecompiledheaders.h"
+
+#include "llpanellandmarks.h"
+
+#include "llbutton.h"
+#include "llfloaterreg.h"
+#include "lllandmark.h"
+
+#include "llfloaterworldmap.h"
+#include "llfloaterinventory.h"
+#include "llfoldervieweventlistener.h"
+#include "lllandmarklist.h"
+#include "llsidetray.h"
+#include "lltabcontainer.h"
+#include "llworldmap.h"
+
+// Not yet implemented; need to remove buildPanel() from constructor when we switch
+//static LLRegisterPanelClassWrapper<LLLandmarksPanel> t_landmarks("panel_landmarks");
+
+LLLandmarksPanel::LLLandmarksPanel()
+ : LLPanelPlacesTab(),
+ mInventoryPanel(NULL)
+{
+ mSavedFolderState = new LLSaveFolderState();
+ mSavedFolderState->setApply(FALSE);
+
+ LLUICtrlFactory::getInstance()->buildPanel(this, "panel_landmarks.xml");
+}
+
+LLLandmarksPanel::~LLLandmarksPanel()
+{
+ delete mSavedFolderState;
+}
+
+BOOL LLLandmarksPanel::postBuild()
+{
+ if (!gInventory.isInventoryUsable())
+ return FALSE;
+
+ mInventoryPanel = getChild<LLInventoryPanel>("landmarks_list");
+ mInventoryPanel->setFilterTypes(0x1 << LLInventoryType::IT_LANDMARK);
+ mInventoryPanel->setShowFolderState(LLInventoryFilter::SHOW_NON_EMPTY_FOLDERS);
+ mInventoryPanel->openDefaultFolderForType(LLAssetType::AT_LANDMARK);
+ mInventoryPanel->setSelectCallback(boost::bind(&LLLandmarksPanel::onSelectionChange, this, _1, _2));
+
+ LLFolderView* root_folder = mInventoryPanel->getRootFolder();
+ root_folder->setReshapeCallback(boost::bind(&LLLandmarksPanel::onSelectionChange, this, _1, _2));
+
+ mActionBtn = getChild<LLButton>("selector");
+ root_folder->addChild(mActionBtn);
+ mActionBtn->setEnabled(TRUE);
+ childSetAction("selector", boost::bind(&LLLandmarksPanel::onSelectorButtonClicked, this), this);
+
+ return TRUE;
+}
+
+// virtual
+void LLLandmarksPanel::onSearchEdit(const std::string& string)
+{
+ if (string == "")
+ {
+ mInventoryPanel->setFilterSubString(LLStringUtil::null);
+
+ // re-open folders that were initially open
+ mSavedFolderState->setApply(TRUE);
+ mInventoryPanel->getRootFolder()->applyFunctorRecursively(*mSavedFolderState);
+ LLOpenFoldersWithSelection opener;
+ mInventoryPanel->getRootFolder()->applyFunctorRecursively(opener);
+ mInventoryPanel->getRootFolder()->scrollToShowSelection();
+ }
+
+ gInventory.startBackgroundFetch();
+
+ if (mInventoryPanel->getFilterSubString().empty() && string.empty())
+ {
+ // current filter and new filter empty, do nothing
+ return;
+ }
+
+ // save current folder open state if no filter currently applied
+ if (mInventoryPanel->getRootFolder()->getFilterSubString().empty())
+ {
+ mSavedFolderState->setApply(FALSE);
+ mInventoryPanel->getRootFolder()->applyFunctorRecursively(*mSavedFolderState);
+ }
+
+ // set new filter string
+ mInventoryPanel->setFilterSubString(string);
+}
+
+// virtual
+void LLLandmarksPanel::onShowOnMap()
+{
+ LLFolderViewItem* current_item = mInventoryPanel->getRootFolder()->getCurSelectedItem();
+ if (!current_item)
+ return;
+
+ LLFolderViewEventListener* listenerp = current_item->getListener();
+ if (listenerp->getInventoryType() != LLInventoryType::IT_LANDMARK)
+ return;
+
+ LLInventoryItem* inventory_item = gInventory.getItem(listenerp->getUUID());
+ if (!inventory_item)
+ return;
+
+ LLLandmark* landmark = gLandmarkList.getAsset(inventory_item->getAssetUUID());
+ if (!landmark)
+ return;
+
+ LLVector3d landmark_global_pos;
+ if (!landmark->getGlobalPos(landmark_global_pos))
+ return;
+
+ LLFloaterWorldMap* worldmap_instance = LLFloaterWorldMap::getInstance();
+ if (!landmark_global_pos.isExactlyZero() && worldmap_instance)
+ {
+ worldmap_instance->trackLocation(landmark_global_pos);
+ LLFloaterReg::showInstance("world_map", "center");
+ }
+}
+
+// virtual
+void LLLandmarksPanel::onTeleport()
+{
+ LLFolderViewItem* current_item = mInventoryPanel->getRootFolder()->getCurSelectedItem();
+ if (!current_item)
+ return;
+
+ LLFolderViewEventListener* listenerp = current_item->getListener();
+ if (listenerp->getInventoryType() == LLInventoryType::IT_LANDMARK)
+ {
+ listenerp->openItem();
+ }
+}
+
+/*
+// virtual
+void LLLandmarksPanel::onCopySLURL()
+{
+ LLFolderViewItem* current_item = mInventoryPanel->getRootFolder()->getCurSelectedItem();
+ if (!current_item)
+ return;
+
+ LLFolderViewEventListener* listenerp = current_item->getListener();
+ if (listenerp->getInventoryType() != LLInventoryType::IT_LANDMARK)
+ return;
+
+ LLInventoryItem* inventory_item = gInventory.getItem(listenerp->getUUID());
+ if (!inventory_item)
+ return;
+
+ LLLandmark* landmark = gLandmarkList.getAsset(inventory_item->getAssetUUID());
+ if (!landmark)
+ return;
+
+ LLVector3d landmark_global_pos;
+ if (!landmark->getGlobalPos(landmark_global_pos))
+ return;
+
+ U64 new_region_handle = to_region_handle(landmark_global_pos);
+
+ LLWorldMap::url_callback_t cb = boost::bind(
+ &LLPanelPlacesTab::onRegionResponse, this,
+ landmark_global_pos, _1, _2, _3, _4);
+
+ LLWorldMap::getInstance()->sendHandleRegionRequest(new_region_handle, cb, std::string("unused"), false);
+}
+*/
+
+// virtual
+void LLLandmarksPanel::updateVerbs()
+{
+ if (!isTabVisible())
+ return;
+
+ BOOL enabled = FALSE;
+
+ LLFolderViewItem* current_item = mInventoryPanel->getRootFolder()->getCurSelectedItem();
+ if (current_item)
+ {
+ LLFolderViewEventListener* listenerp = current_item->getListener();
+ if (listenerp->getInventoryType() == LLInventoryType::IT_LANDMARK)
+ {
+ enabled = TRUE;
+ }
+ }
+
+ mTeleportBtn->setEnabled(enabled);
+ mShowOnMapBtn->setEnabled(enabled);
+}
+
+void LLLandmarksPanel::onSelectionChange(const std::deque<LLFolderViewItem*> &items, BOOL user_action)
+{
+ LLFolderViewItem* current_item = mInventoryPanel->getRootFolder()->getCurSelectedItem();
+ if (!current_item)
+ return;
+
+ LLFolderViewEventListener* listenerp = current_item->getListener();
+ if (listenerp->getInventoryType() == LLInventoryType::IT_LANDMARK)
+ {
+ S32 bottom = 0;
+ LLFolderViewItem* folder = current_item->getParentFolder();
+
+ while ( folder->getParentFolder() != NULL )
+ {
+ bottom += folder->getRect().mBottom;
+ folder = folder->getParentFolder();
+ }
+
+ LLRect rect = current_item->getRect();
+ LLRect btn_rect(
+ rect.mRight - mActionBtn->getRect().getWidth(),
+ bottom + rect.mTop,
+ rect.mRight,
+ bottom + rect.mBottom);
+
+ mActionBtn->setRect(btn_rect);
+
+ if (!mActionBtn->getVisible())
+ mActionBtn->setVisible(TRUE);
+ }
+ else
+ {
+ if (mActionBtn->getVisible())
+ mActionBtn->setVisible(FALSE);
+ }
+
+ updateVerbs();
+}
+
+void LLLandmarksPanel::onSelectorButtonClicked()
+{
+ LLFolderViewItem* cur_item = mInventoryPanel->getRootFolder()->getCurSelectedItem();
+
+ LLFolderViewEventListener* listenerp = cur_item->getListener();
+ if (listenerp->getInventoryType() == LLInventoryType::IT_LANDMARK)
+ {
+ LLSD key;
+ key["type"] = "landmark";
+ key["id"] = listenerp->getUUID();
+
+ LLSideTray::getInstance()->showPanel("panel_places", key);
+ }
+}
+
+void LLLandmarksPanel::setSelectedItem(const LLUUID& obj_id)
+{
+ mInventoryPanel->setSelection(obj_id, FALSE);
+}
diff --git a/indra/newview/llpanellandmarks.h b/indra/newview/llpanellandmarks.h
new file mode 100644
index 0000000000..14cbbd6123
--- /dev/null
+++ b/indra/newview/llpanellandmarks.h
@@ -0,0 +1,66 @@
+/**
+ * @file llpanellandmarks.h
+ * @brief Landmarks tab for Side Bar "Places" panel
+ * class definition
+ *
+ * $LicenseInfo:firstyear=2009&license=viewergpl$
+ *
+ * Copyright (c) 2001-2009, Linden Research, Inc.
+ *
+ * Second Life Viewer Source Code
+ * The source code in this file ("Source Code") is provided by Linden Lab
+ * to you under the terms of the GNU General Public License, version 2.0
+ * ("GPL"), unless you have obtained a separate licensing agreement
+ * ("Other License"), formally executed by you and Linden Lab. Terms of
+ * the GPL can be found in doc/GPL-license.txt in this distribution, or
+ * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
+ *
+ * There are special exceptions to the terms and conditions of the GPL as
+ * it is applied to this Source Code. View the full text of the exception
+ * in the file doc/FLOSS-exception.txt in this software distribution, or
+ * online at http://secondlifegrid.net/programs/open_source/licensing/flossexception
+ *
+ * By copying, modifying or distributing this software, you acknowledge
+ * that you have read and understood your obligations described above,
+ * and agree to abide by those obligations.
+ *
+ * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+ * COMPLETENESS OR PERFORMANCE.
+ * $/LicenseInfo$
+ */
+
+#ifndef LL_LLPANELLANDMARKS_H
+#define LL_LLPANELLANDMARKS_H
+
+#include "llinventorymodel.h"
+#include "llpanelplacestab.h"
+
+class LLFolderViewItem;
+class LLInventoryPanel;
+class LLSaveFolderState;
+
+class LLLandmarksPanel : public LLPanelPlacesTab
+{
+public:
+ LLLandmarksPanel();
+ virtual ~LLLandmarksPanel();
+
+ /*virtual*/ BOOL postBuild();
+ /*virtual*/ void onSearchEdit(const std::string& string);
+ /*virtual*/ void onShowOnMap();
+ /*virtual*/ void onTeleport();
+ ///*virtual*/ void onCopySLURL();
+ /*virtual*/ void updateVerbs();
+
+ void onSelectionChange(const std::deque<LLFolderViewItem*> &items, BOOL user_action);
+ void onSelectorButtonClicked();
+ void setSelectedItem(const LLUUID& obj_id);
+
+private:
+ LLInventoryPanel* mInventoryPanel;
+ LLSaveFolderState* mSavedFolderState;
+ LLButton* mActionBtn;
+};
+
+#endif //LL_LLPANELLANDMARKS_H
diff --git a/indra/newview/llpanellandmedia.cpp b/indra/newview/llpanellandmedia.cpp
index b8886c9493..994bf7e3f9 100644
--- a/indra/newview/llpanellandmedia.cpp
+++ b/indra/newview/llpanellandmedia.cpp
@@ -39,6 +39,8 @@
#include "llmimetypes.h"
#include "llviewerparcelmgr.h"
#include "llviewerregion.h"
+#include "llviewermedia.h"
+#include "llviewerparcelmedia.h"
#include "lluictrlfactory.h"
// library includes
@@ -54,21 +56,15 @@
#include "llsdutil.h"
#include "lltexturectrl.h"
#include "roles_constants.h"
+#include "llscrolllistctrl.h"
//---------------------------------------------------------------------------
// LLPanelLandMedia
//---------------------------------------------------------------------------
LLPanelLandMedia::LLPanelLandMedia(LLParcelSelectionHandle& parcel)
-: LLPanel(std::string("land_media_panel")),
-
+: LLPanel(),
mParcel(parcel),
- mCheckSoundLocal(NULL),
- mSoundHelpButton(NULL),
- mCheckEnableVoiceChat(NULL),
- mCheckEnableVoiceChatIsEstateDisabled(NULL),
- mCheckEnableVoiceChatParcel(NULL),
- mMusicURLEdit(NULL),
mMediaURLEdit(NULL),
mMediaDescEdit(NULL),
mMediaTypeCombo(NULL),
@@ -79,8 +75,7 @@ LLPanelLandMedia::LLPanelLandMedia(LLParcelSelectionHandle& parcel)
mMediaTextureCtrl(NULL),
mMediaAutoScaleCheck(NULL),
mMediaLoopCheck(NULL),
- mMediaUrlCheck(NULL),
- mMusicUrlCheck(NULL)
+ mMediaUrlCheck(NULL)
{
}
@@ -88,38 +83,13 @@ LLPanelLandMedia::LLPanelLandMedia(LLParcelSelectionHandle& parcel)
// virtual
LLPanelLandMedia::~LLPanelLandMedia()
{
- // close LLFloaterURLEntry?
}
-
-// static
-void LLPanelLandMedia::onClickSoundHelp(void*)
-{
- LLNotifications::instance().add("ClickSoundHelpLand");
-}
-
-
BOOL LLPanelLandMedia::postBuild()
{
- mCheckSoundLocal = getChild<LLCheckBoxCtrl>("check sound local");
- childSetCommitCallback("check sound local", onCommitAny, this);
-
- mSoundHelpButton = getChild<LLButton>("?");
- mSoundHelpButton->setClickedCallback(onClickSoundHelp, this);
-
- mCheckEnableVoiceChat = getChild<LLCheckBoxCtrl>("parcel_enable_voice_channel");
- childSetCommitCallback("parcel_enable_voice_channel", onCommitAny, this);
- mCheckEnableVoiceChatIsEstateDisabled = getChild<LLCheckBoxCtrl>("parcel_enable_voice_channel_is_estate_disabled");
- childSetCommitCallback("parcel_enable_voice_channel_is_estate_disabled", onCommitAny, this);
- mCheckEnableVoiceChatParcel = getChild<LLCheckBoxCtrl>("parcel_enable_voice_channel_parcel");
- childSetCommitCallback("parcel_enable_voice_channel_parcel", onCommitAny, this);
-
- mMusicURLEdit = getChild<LLLineEditor>("music_url");
- childSetCommitCallback("music_url", onCommitAny, this);
mMediaTextureCtrl = getChild<LLTextureCtrl>("media texture");
- mMediaTextureCtrl->setCommitCallback( onCommitAny );
- mMediaTextureCtrl->setCallbackUserData( this );
+ mMediaTextureCtrl->setCommitCallback( onCommitAny, this );
mMediaTextureCtrl->setAllowNoTexture ( TRUE );
mMediaTextureCtrl->setImmediateFilterPermMask(PERM_COPY | PERM_TRANSFER);
mMediaTextureCtrl->setNonImmediateFilterPermMask(PERM_COPY | PERM_TRANSFER);
@@ -128,16 +98,13 @@ BOOL LLPanelLandMedia::postBuild()
childSetCommitCallback("media_auto_scale", onCommitAny, this);
mMediaLoopCheck = getChild<LLCheckBoxCtrl>("media_loop");
- childSetCommitCallback("media_loop", onCommitAny, this);
+ childSetCommitCallback("media_loop", onCommitAny, this );
mMediaUrlCheck = getChild<LLCheckBoxCtrl>("hide_media_url");
- childSetCommitCallback("hide_media_url", onCommitAny, this);
-
- mMusicUrlCheck = getChild<LLCheckBoxCtrl>("hide_music_url");
- childSetCommitCallback("hide_music_url", onCommitAny, this);
+ childSetCommitCallback("hide_media_url", onCommitAny, this );
mMediaURLEdit = getChild<LLLineEditor>("media_url");
- childSetCommitCallback("media_url", onCommitAny, this);
+ childSetCommitCallback("media_url", onCommitAny, this );
mMediaDescEdit = getChild<LLLineEditor>("url_description");
childSetCommitCallback("url_description", onCommitAny, this);
@@ -155,6 +122,9 @@ BOOL LLPanelLandMedia::postBuild()
mSetURLButton = getChild<LLButton>("set_media_url");
childSetAction("set_media_url", onSetBtn, this);
+ mResetURLButton = getChild<LLButton>("reset_media_url");
+ childSetAction("reset_media_url", onResetBtn, this);
+
return TRUE;
}
@@ -175,46 +145,11 @@ void LLPanelLandMedia::refresh()
// Display options
BOOL can_change_media = LLViewerParcelMgr::isParcelModifiableByAgent(parcel, GP_LAND_CHANGE_MEDIA);
- mCheckSoundLocal->set( parcel->getSoundLocal() );
- mCheckSoundLocal->setEnabled( can_change_media );
-
- LLViewerRegion* region = LLViewerParcelMgr::getInstance()->getSelectionRegion();
- if (!region)
- {
- // never seen this happen, but log it
- llwarns << "Couldn't get selected region." << llendl;
- }
-
- if (region && region->isVoiceEnabled()) // estate-wide voice-disable overrides all
- {
- bool allow_voice = parcel->getParcelFlagAllowVoice();
-
- mCheckEnableVoiceChatIsEstateDisabled->setVisible(false);
-
- mCheckEnableVoiceChat->setVisible(true);
- mCheckEnableVoiceChat->setEnabled( can_change_media );
- mCheckEnableVoiceChat->set(allow_voice);
-
- mCheckEnableVoiceChatParcel->setEnabled( can_change_media && allow_voice );
- }
- else // disabled at region level
- {
- mCheckEnableVoiceChatIsEstateDisabled->setVisible(true); // always disabled
- mCheckEnableVoiceChat->setVisible(false);
- mCheckEnableVoiceChat->setEnabled(false);
- mCheckEnableVoiceChat->set(false);
-
- mCheckEnableVoiceChatParcel->setEnabled(false);
- }
-
- mCheckEnableVoiceChatParcel->set(!parcel->getParcelFlagUseEstateVoiceChannel());
-
- mMusicURLEdit->setText(parcel->getMusicURL());
- mMusicURLEdit->setEnabled( can_change_media );
-
mMediaURLEdit->setText(parcel->getMediaURL());
mMediaURLEdit->setEnabled( FALSE );
+ childSetText("current_url", parcel->getMediaCurrentURL());
+
mMediaDescEdit->setText(parcel->getMediaDesc());
mMediaDescEdit->setEnabled( can_change_media );
@@ -230,15 +165,11 @@ void LLPanelLandMedia::refresh()
mMediaUrlCheck->set( parcel->getObscureMedia() );
mMediaUrlCheck->setEnabled( can_change_media );
- mMusicUrlCheck->set( parcel->getObscureMusic() );
- mMusicUrlCheck->setEnabled( can_change_media );
-
// don't display urls if you're not able to change it
// much requested change in forums so people can't 'steal' urls
// NOTE: bug#2009 means this is still vunerable - however, bug
// should be closed since this bug opens up major security issues elsewhere.
bool obscure_media = ! can_change_media && parcel->getObscureMedia();
- bool obscure_music = ! can_change_media && parcel->getObscureMusic();
// Special code to disable asterixes for html type
if(mime_type == "text/html")
@@ -248,7 +179,6 @@ void LLPanelLandMedia::refresh()
mMediaUrlCheck->setEnabled( false );
}
- mMusicURLEdit->setDrawAsterixes( obscure_music );
mMediaURLEdit->setDrawAsterixes( obscure_media );
mMediaAutoScaleCheck->set( parcel->getMediaAutoScale () );
@@ -262,7 +192,7 @@ void LLPanelLandMedia::refresh()
else
mMediaLoopCheck->set( false );
mMediaLoopCheck->setEnabled ( can_change_media && allow_looping );
-
+
// disallow media size change for mime types that don't allow it
bool allow_resize = LLMIMETypes::findAllowResize( mime_type );
if ( allow_resize )
@@ -285,22 +215,7 @@ void LLPanelLandMedia::refresh()
mMediaTextureCtrl->setEnabled( can_change_media );
mSetURLButton->setEnabled( can_change_media );
-
- #if 0
- // there is a media url and a media texture selected
- if ( ( ! ( std::string ( parcel->getMediaURL() ).empty () ) ) && ( ! ( parcel->getMediaID ().isNull () ) ) )
- {
- // turn on transport controls if allowed for this parcel
- mMediaStopButton->setEnabled ( editable );
- mMediaStartButton->setEnabled ( editable );
- }
- else
- {
- // no media url or no media texture
- mMediaStopButton->setEnabled ( FALSE );
- mMediaStartButton->setEnabled ( FALSE );
- };
- #endif
+ mResetURLButton->setEnabled( can_change_media );
LLFloaterURLEntry* floater_url_entry = (LLFloaterURLEntry*)mURLEntryFloater.get();
if (floater_url_entry)
@@ -348,12 +263,19 @@ void LLPanelLandMedia::setMediaType(const std::string& mime_type)
void LLPanelLandMedia::setMediaURL(const std::string& media_url)
{
mMediaURLEdit->setText(media_url);
+ LLParcel *parcel = mParcel->getParcel();
+ if(parcel)
+ parcel->setMediaCurrentURL(media_url);
+ // LLViewerMedia::navigateHome();
+
+
mMediaURLEdit->onCommit();
+ // LLViewerParcelMedia::sendMediaNavigateMessage(media_url);
+ childSetText("current_url", media_url);
}
-
std::string LLPanelLandMedia::getMediaURL()
{
- return mMediaURLEdit->getText();
+ return mMediaURLEdit->getText();
}
// static
@@ -382,33 +304,23 @@ void LLPanelLandMedia::onCommitAny(LLUICtrl*, void *userdata)
}
// Extract data from UI
- BOOL sound_local = self->mCheckSoundLocal->get();
- std::string music_url = self->mMusicURLEdit->getText();
std::string media_url = self->mMediaURLEdit->getText();
std::string media_desc = self->mMediaDescEdit->getText();
std::string mime_type = self->childGetText("mime_type");
U8 media_auto_scale = self->mMediaAutoScaleCheck->get();
U8 media_loop = self->mMediaLoopCheck->get();
U8 obscure_media = self->mMediaUrlCheck->get();
- U8 obscure_music = self->mMusicUrlCheck->get();
S32 media_width = (S32)self->mMediaWidthCtrl->get();
S32 media_height = (S32)self->mMediaHeightCtrl->get();
LLUUID media_id = self->mMediaTextureCtrl->getImageAssetID();
- BOOL voice_enabled = self->mCheckEnableVoiceChat->get();
- BOOL voice_estate_chan = ! self->mCheckEnableVoiceChatParcel->get();
self->childSetText("mime_type", mime_type);
// Remove leading/trailing whitespace (common when copying/pasting)
- LLStringUtil::trim(music_url);
LLStringUtil::trim(media_url);
// Push data into current parcel
- parcel->setParcelFlag(PF_ALLOW_VOICE_CHAT, voice_enabled);
- parcel->setParcelFlag(PF_USE_ESTATE_VOICE_CHAN, voice_estate_chan);
- parcel->setParcelFlag(PF_SOUND_LOCAL, sound_local);
- parcel->setMusicURL(music_url);
parcel->setMediaURL(media_url);
parcel->setMediaType(mime_type);
parcel->setMediaDesc(media_desc);
@@ -418,7 +330,6 @@ void LLPanelLandMedia::onCommitAny(LLUICtrl*, void *userdata)
parcel->setMediaAutoScale ( media_auto_scale );
parcel->setMediaLoop ( media_loop );
parcel->setObscureMedia( obscure_media );
- parcel->setObscureMusic( obscure_music );
// Send current parcel data upstream to server
LLViewerParcelMgr::getInstance()->sendParcelPropertiesUpdate( parcel );
@@ -437,3 +348,16 @@ void LLPanelLandMedia::onSetBtn(void *userdata)
parent_floater->addDependentFloater(self->mURLEntryFloater.get());
}
}
+
+// static
+void LLPanelLandMedia::onResetBtn(void *userdata)
+{
+ LLPanelLandMedia *self = (LLPanelLandMedia *)userdata;
+ LLParcel* parcel = self->mParcel->getParcel();
+ // LLViewerMedia::navigateHome();
+ self->refresh();
+ self->childSetText("current_url", parcel->getMediaURL());
+ // LLViewerParcelMedia::sendMediaNavigateMessage(parcel->getMediaURL());
+
+}
+
diff --git a/indra/newview/llpanellandmedia.h b/indra/newview/llpanellandmedia.h
index 6a53dd42a5..5ad1f9758d 100644
--- a/indra/newview/llpanellandmedia.h
+++ b/indra/newview/llpanellandmedia.h
@@ -56,29 +56,34 @@ private:
static void onCommitAny(LLUICtrl* ctrl, void *userdata);
static void onCommitType(LLUICtrl* ctrl, void *userdata);
static void onSetBtn(void* userdata);
- static void onClickSoundHelp(void*);
-
+ static void onResetBtn(void* userdata);
+
private:
- LLCheckBoxCtrl* mCheckSoundLocal;
- LLButton* mSoundHelpButton;
- LLCheckBoxCtrl* mCheckEnableVoiceChat;
- LLCheckBoxCtrl* mCheckEnableVoiceChatIsEstateDisabled;
- LLCheckBoxCtrl* mCheckEnableVoiceChatParcel;
- LLLineEditor* mMusicURLEdit;
LLLineEditor* mMediaURLEdit;
LLLineEditor* mMediaDescEdit;
LLComboBox* mMediaTypeCombo;
LLButton* mSetURLButton;
+ LLButton* mResetURLButton;
+ LLSpinCtrl* mMediaResetCtrl;
LLSpinCtrl* mMediaHeightCtrl;
LLSpinCtrl* mMediaWidthCtrl;
+ LLTextBox* mMediaResetCtrlLabel;
LLTextBox* mMediaSizeCtrlLabel;
LLTextureCtrl* mMediaTextureCtrl;
LLCheckBoxCtrl* mMediaAutoScaleCheck;
LLCheckBoxCtrl* mMediaLoopCheck;
LLCheckBoxCtrl* mMediaUrlCheck;
- LLCheckBoxCtrl* mMusicUrlCheck;
LLHandle<LLFloater> mURLEntryFloater;
+ LLCheckBoxCtrl* mMediaNavigateAllowCheck;
+ LLCheckBoxCtrl* mMediaURLFilterCheck;
+ LLLineEditor* mMediaURLFilterDomainEdit;
+ LLButton* mMediaURLFilterAddButton;
+ LLButton* mMediaURLFilterRemoveButton;
+ LLScrollListCtrl* mURLFilterList;
+ LLRadioGroup* mRadioNavigateControl;
+
+
LLSafeHandle<LLParcelSelection>& mParcel;
};
diff --git a/indra/newview/llpanellogin.cpp b/indra/newview/llpanellogin.cpp
index bc5e8f2482..ef830d5f03 100644
--- a/indra/newview/llpanellogin.cpp
+++ b/indra/newview/llpanellogin.cpp
@@ -34,9 +34,8 @@
#include "llpanellogin.h"
-#include "llpanelgeneral.h"
-
#include "indra_constants.h" // for key and mask constants
+#include "llfloaterreg.h"
#include "llfontgl.h"
#include "llmd5.h"
#include "llsecondlifeurls.h"
@@ -49,8 +48,6 @@
#include "llcombobox.h"
#include "llcurl.h"
#include "llviewercontrol.h"
-#include "llfloaterabout.h"
-#include "llfloatertest.h"
#include "llfloaterpreference.h"
#include "llfocusmgr.h"
#include "lllineeditor.h"
@@ -60,7 +57,7 @@
#include "lluiconstants.h"
#include "llurlsimstring.h"
#include "llviewerbuild.h"
-#include "llviewerimagelist.h"
+#include "llviewertexturelist.h"
#include "llviewermenu.h" // for handle_preferences()
#include "llviewernetwork.h"
#include "llviewerwindow.h" // to link into child list
@@ -69,13 +66,12 @@
#include "lluictrlfactory.h"
#include "llhttpclient.h"
#include "llweb.h"
-#include "llwebbrowserctrl.h"
-
-#include "llfloaterhtml.h"
+#include "llmediactrl.h"
+#include "llrootview.h"
-#include "llfloaterhtmlhelp.h"
+#include "llfloatermediabrowser.h"
#include "llfloatertos.h"
-
+#include "lltrans.h"
#include "llglheaders.h"
#define USE_VIEWER_AUTH 0
@@ -92,7 +88,7 @@ class LLLoginRefreshHandler : public LLCommandHandler
public:
// don't allow from external browsers
LLLoginRefreshHandler() : LLCommandHandler("login_refresh", true) { }
- bool handle(const LLSD& tokens, const LLSD& query_map, LLWebBrowserCtrl* web)
+ bool handle(const LLSD& tokens, const LLSD& query_map, LLMediaCtrl* web)
{
if (LLStartUp::getStartupState() < STATE_LOGIN_CLEANUP)
{
@@ -166,7 +162,7 @@ LLPanelLogin::LLPanelLogin(const LLRect &rect,
BOOL show_server,
void (*callback)(S32 option, void* user_data),
void *cb_data)
-: LLPanel(std::string("panel_login"), LLRect(0,600,800,0), FALSE), // not bordered
+: LLPanel(),
mLogoImage(),
mCallback(callback),
mCallbackData(cb_data),
@@ -190,7 +186,7 @@ LLPanelLogin::LLPanelLogin(const LLRect &rect,
LLPanelLogin::sInstance = this;
// add to front so we are the bottom-most child
- gViewerWindow->getRootView()->addChildAtEnd(this);
+ gViewerWindow->getRootView()->addChildInBack(this);
// Logo
mLogoImage = LLUI::getUIImage("startup_logo.j2c");
@@ -207,9 +203,8 @@ LLPanelLogin::LLPanelLogin(const LLRect &rect,
childSetPrevalidate("first_name_edit", LLLineEditor::prevalidatePrintableNoSpace);
childSetPrevalidate("last_name_edit", LLLineEditor::prevalidatePrintableNoSpace);
- childSetCommitCallback("password_edit", mungePassword);
- childSetKeystrokeCallback("password_edit", onPassKey, this);
- childSetUserData("password_edit", this);
+ childSetCommitCallback("password_edit", mungePassword, this);
+ getChild<LLLineEditor>("password_edit")->setKeystrokeCallback(onPassKey, this);
// change z sort of clickable text to be behind buttons
sendChildToBack(getChildView("channel_text"));
@@ -219,14 +214,7 @@ LLPanelLogin::LLPanelLogin(const LLRect &rect,
if (edit) edit->setDrawAsterixes(TRUE);
LLComboBox* combo = getChild<LLComboBox>("start_location_combo");
- combo->setAllowTextEntry(TRUE, 128, FALSE);
- // The XML file loads the combo with the following labels:
- // 0 - "My Home"
- // 1 - "My Last Location"
- // 2 - "<Type region name>"
-
- BOOL login_last = gSavedSettings.getBOOL("LoginLastLocation");
std::string sim_string = LLURLSimString::sInstance.mSimString;
if (!sim_string.empty())
{
@@ -236,19 +224,11 @@ LLPanelLogin::LLPanelLogin(const LLRect &rect,
combo->setTextEntry(sim_string);
combo->setCurrentByIndex( 2 );
}
- else if (login_last)
- {
- combo->setCurrentByIndex( 1 );
- }
- else
- {
- combo->setCurrentByIndex( 0 );
- }
- combo->setCommitCallback( &set_start_location );
+ combo->setCommitCallback( &set_start_location, NULL );
LLComboBox* server_choice_combo = sInstance->getChild<LLComboBox>("server_combo");
- server_choice_combo->setCommitCallback(onSelectServer);
+ server_choice_combo->setCommitCallback(onSelectServer, NULL);
server_choice_combo->setFocusLostCallback(onServerComboLostFocus);
childSetAction("connect_btn", onClickConnect, this);
@@ -266,27 +246,25 @@ LLPanelLogin::LLPanelLogin(const LLRect &rect,
LLTextBox* channel_text = getChild<LLTextBox>("channel_text");
channel_text->setTextArg("[CHANNEL]", channel); // though not displayed
channel_text->setTextArg("[VERSION]", version);
- channel_text->setClickedCallback(onClickVersion);
- channel_text->setCallbackUserData(this);
+ channel_text->setClickedCallback(onClickVersion, this);
LLTextBox* forgot_password_text = getChild<LLTextBox>("forgot_password_text");
- forgot_password_text->setClickedCallback(onClickForgotPassword);
+ forgot_password_text->setClickedCallback(onClickForgotPassword, NULL);
LLTextBox* create_new_account_text = getChild<LLTextBox>("create_new_account_text");
- create_new_account_text->setClickedCallback(onClickNewAccount);
+ create_new_account_text->setClickedCallback(onClickNewAccount, NULL);
#endif
// get the web browser control
- LLWebBrowserCtrl* web_browser = getChild<LLWebBrowserCtrl>("login_html");
+ LLMediaCtrl* web_browser = getChild<LLMediaCtrl>("login_html");
+ web_browser->addObserver(this);
+
// Need to handle login secondlife:///app/ URLs
web_browser->setTrusted( true );
- // observe browser events
- web_browser->addObserver( this );
-
// don't make it a tab stop until SL-27594 is fixed
web_browser->setTabStop(FALSE);
- web_browser->navigateToLocalPage( "loading", "loading.html" );
+ // web_browser->navigateToLocalPage( "loading", "loading.html" );
// make links open in external browser
web_browser->setOpenInExternalBrowser( true );
@@ -320,7 +298,7 @@ LLPanelLogin::LLPanelLogin(const LLRect &rect,
void LLPanelLogin::setSiteIsAlive( bool alive )
{
- LLWebBrowserCtrl* web_browser = getChild<LLWebBrowserCtrl>("login_html");
+ LLMediaCtrl* web_browser = getChild<LLMediaCtrl>("login_html");
// if the contents of the site was retrieved
if ( alive )
{
@@ -382,7 +360,7 @@ LLPanelLogin::~LLPanelLogin()
gResponsePtr->setParent( 0 );
//// We know we're done with the image, so be rid of it.
- //gImageList.deleteImage( mLogoImage );
+ //gTextureList.deleteImage( mLogoImage );
}
// virtual
@@ -432,18 +410,6 @@ BOOL LLPanelLogin::handleKeyHere(KEY key, MASK mask)
return TRUE;
}
- if (('P' == key) && (MASK_CONTROL == mask))
- {
- LLFloaterPreference::show(NULL);
- return TRUE;
- }
-
- if (('T' == key) && (MASK_CONTROL == mask))
- {
- new LLFloaterSimple("floater_test.xml");
- return TRUE;
- }
-
if ( KEY_F1 == key )
{
llinfos << "Spawning HTML help window" << llendl;
@@ -451,16 +417,6 @@ BOOL LLPanelLogin::handleKeyHere(KEY key, MASK mask)
return TRUE;
}
-# if !LL_RELEASE_FOR_DOWNLOAD
- if ( KEY_F2 == key )
- {
- llinfos << "Spawning floater TOS window" << llendl;
- LLFloaterTOS* tos_dialog = LLFloaterTOS::show(LLFloaterTOS::TOS_TOS,"");
- tos_dialog->startModal();
- return TRUE;
- }
-#endif
-
if (KEY_RETURN == key && MASK_NONE == mask)
{
// let the panel handle UICtrl processing: calls onClickConnect()
@@ -656,23 +612,15 @@ void LLPanelLogin::refreshLocation( bool force_visible )
#if USE_VIEWER_AUTH
loadLoginPage();
#else
- LLComboBox* combo = sInstance->getChild<LLComboBox>("start_location_combo");
-
- if (LLURLSimString::parse())
- {
- combo->setCurrentByIndex( 3 ); // BUG? Maybe 2?
- combo->setTextEntry(LLURLSimString::sInstance.mSimString);
- }
- else
- {
- BOOL login_last = gSavedSettings.getBOOL("LoginLastLocation");
- combo->setCurrentByIndex( login_last ? 1 : 0 );
- }
-
BOOL show_start = TRUE;
if ( ! force_visible )
- show_start = gSavedSettings.getBOOL("ShowStartLocation");
+ {
+ // Don't show on first run after install
+ // Otherwise ShowStartLocation defaults to true.
+ show_start = gSavedSettings.getBOOL("ShowStartLocation")
+ && !gSavedSettings.getBOOL("FirstRunThisInstall");
+ }
sInstance->childSetVisible("start_location_combo", show_start);
sInstance->childSetVisible("start_location_text", show_start);
@@ -688,7 +636,7 @@ void LLPanelLogin::refreshLocation( bool force_visible )
}
// static
-void LLPanelLogin::close()
+void LLPanelLogin::closePanel()
{
if (sInstance)
{
@@ -706,7 +654,7 @@ void LLPanelLogin::setAlwaysRefresh(bool refresh)
{
if (LLStartUp::getStartupState() >= STATE_LOGIN_CLEANUP) return;
- LLWebBrowserCtrl* web_browser = sInstance->getChild<LLWebBrowserCtrl>("login_html");
+ LLMediaCtrl* web_browser = sInstance->getChild<LLMediaCtrl>("login_html");
if (web_browser)
{
@@ -787,14 +735,7 @@ void LLPanelLogin::loadLoginPage()
}
else
{
- if (gSavedSettings.getBOOL("LoginLastLocation"))
- {
- location = "last";
- }
- else
- {
- location = "home";
- }
+ location = gSavedSettings.getString("LoginLocation");
}
std::string firstname, lastname;
@@ -836,7 +777,8 @@ void LLPanelLogin::loadLoginPage()
{
oStr << "&auto_login=TRUE";
}
- if (gSavedSettings.getBOOL("ShowStartLocation"))
+ if (gSavedSettings.getBOOL("ShowStartLocation")
+ && !gSavedSettings.getBOOL("FirstRunThisInstall"))
{
oStr << "&show_start_location=TRUE";
}
@@ -852,25 +794,28 @@ void LLPanelLogin::loadLoginPage()
#endif
#endif
- LLWebBrowserCtrl* web_browser = sInstance->getChild<LLWebBrowserCtrl>("login_html");
+ LLMediaCtrl* web_browser = sInstance->getChild<LLMediaCtrl>("login_html");
// navigate to the "real" page
- web_browser->navigateTo( oStr.str() );
+ web_browser->navigateTo( oStr.str(), "text/html" );
}
-void LLPanelLogin::onNavigateComplete( const EventType& eventIn )
+void LLPanelLogin::handleMediaEvent(LLPluginClassMedia* /*self*/, EMediaEvent event)
{
- LLWebBrowserCtrl* web_browser = sInstance->getChild<LLWebBrowserCtrl>("login_html");
- if (web_browser)
+ if(event == MEDIA_EVENT_NAVIGATE_COMPLETE)
{
- // *HACK HACK HACK HACK!
- /* Stuff a Tab key into the browser now so that the first field will
- ** get the focus! The embedded javascript on the page that properly
- ** sets the initial focus in a real web browser is not working inside
- ** the viewer, so this is an UGLY HACK WORKAROUND for now.
- */
- // Commented out as it's not reliable
- //web_browser->handleKey(KEY_TAB, MASK_NONE, false);
+ LLMediaCtrl* web_browser = sInstance->getChild<LLMediaCtrl>("login_html");
+ if (web_browser)
+ {
+ // *HACK HACK HACK HACK!
+ /* Stuff a Tab key into the browser now so that the first field will
+ ** get the focus! The embedded javascript on the page that properly
+ ** sets the initial focus in a real web browser is not working inside
+ ** the viewer, so this is an UGLY HACK WORKAROUND for now.
+ */
+ // Commented out as it's not reliable
+ //web_browser->handleKey(KEY_TAB, MASK_NONE, false);
+ }
}
}
@@ -899,13 +844,12 @@ void LLPanelLogin::onClickConnect(void *)
}
else
{
- LLNotifications::instance().add("MustHaveAccountToLogIn", LLSD(), LLSD(),
- LLPanelLogin::newAccountAlertCallback);
+ LLNotifications::instance().add("MustHaveAccountToLogIn");
}
}
}
-
+/*
// static
bool LLPanelLogin::newAccountAlertCallback(const LLSD& notification, const LLSD& response)
{
@@ -913,7 +857,7 @@ bool LLPanelLogin::newAccountAlertCallback(const LLSD& notification, const LLSD&
if (0 == option)
{
llinfos << "Going to account creation URL" << llendl;
- LLWeb::loadURLExternal( CREATE_ACCOUNT_URL );
+ LLWeb::loadURLExternal( LLNotifications::instance().getGlobalString("CREATE_ACCOUNT_URL"));
}
else
{
@@ -921,12 +865,12 @@ bool LLPanelLogin::newAccountAlertCallback(const LLSD& notification, const LLSD&
}
return false;
}
-
+*/
// static
void LLPanelLogin::onClickNewAccount(void*)
{
- LLWeb::loadURLExternal( CREATE_ACCOUNT_URL );
+ LLWeb::loadURLExternal(sInstance->getString("create_account_url"));
}
@@ -949,7 +893,7 @@ void LLPanelLogin::onClickQuit(void*)
// static
void LLPanelLogin::onClickVersion(void*)
{
- LLFloaterAbout::show(NULL);
+ LLFloaterReg::showInstance("sl_about");
}
//static
@@ -1023,6 +967,8 @@ void LLPanelLogin::onSelectServer(LLUICtrl*, void*)
void LLPanelLogin::onServerComboLostFocus(LLFocusableElement* fe, void*)
{
+ if (!sInstance) return;
+
LLComboBox* combo = sInstance->getChild<LLComboBox>("server_combo");
if(fe == combo)
{
diff --git a/indra/newview/llpanellogin.h b/indra/newview/llpanellogin.h
index 47d42da7f1..ffcf6a9b70 100644
--- a/indra/newview/llpanellogin.h
+++ b/indra/newview/llpanellogin.h
@@ -34,15 +34,16 @@
#define LL_LLPANELLOGIN_H
#include "llpanel.h"
-#include "llmemory.h" // LLPointer<>
-#include "llwebbrowserctrl.h" // LLWebBrowserCtrlObserver
+#include "llpointer.h" // LLPointer<>
+#include "llmediactrl.h" // LLMediaCtrlObserver
+class LLLineEditor;
class LLUIImage;
class LLPanelLogin:
public LLPanel,
- public LLWebBrowserCtrlObserver
+ public LLViewerMediaObserver
{
LOG_CLASS(LLPanelLogin);
public:
@@ -72,7 +73,7 @@ public:
static BOOL isGridComboDirty();
static void getLocation(std::string &location);
- static void close();
+ static void closePanel();
void setSiteIsAlive( bool alive );
@@ -81,13 +82,15 @@ public:
static void setAlwaysRefresh(bool refresh);
static void mungePassword(LLUICtrl* caller, void* user_data);
+ // inherited from LLViewerMediaObserver
+ /*virtual*/ void handleMediaEvent(LLPluginClassMedia* self, EMediaEvent event);
+
private:
static void onClickConnect(void*);
static void onClickNewAccount(void*);
- static bool newAccountAlertCallback(const LLSD& notification, const LLSD& response);
+// static bool newAccountAlertCallback(const LLSD& notification, const LLSD& response);
static void onClickQuit(void*);
static void onClickVersion(void*);
- virtual void onNavigateComplete( const EventType& eventIn );
static void onClickForgotPassword(void*);
static void onPassKey(LLLineEditor* caller, void* user_data);
static void onSelectServer(LLUICtrl*, void*);
diff --git a/indra/newview/llpanelobject.cpp b/indra/newview/llpanelobject.cpp
index 75f479c16f..9ec9874384 100644
--- a/indra/newview/llpanelobject.cpp
+++ b/indra/newview/llpanelobject.cpp
@@ -52,7 +52,6 @@
#include "llcombobox.h"
#include "llfocusmgr.h"
#include "llmanipscale.h"
-#include "llpanelinventory.h"
#include "llpreviewscript.h"
#include "llresmgr.h"
#include "llselectmgr.h"
@@ -62,6 +61,7 @@
#include "lltool.h"
#include "lltoolcomp.h"
#include "lltoolmgr.h"
+#include "lltrans.h"
#include "llui.h"
#include "llviewerobject.h"
#include "llviewerregion.h"
@@ -99,13 +99,23 @@ enum {
MI_HOLE_COUNT
};
-//*TODO:translate (depricated, so very low priority)
-static const std::string LEGACY_FULLBRIGHT_DESC("Fullbright (Legacy)");
+//static const std::string LEGACY_FULLBRIGHT_DESC =LLTrans::getString("Fullbright");
BOOL LLPanelObject::postBuild()
{
setMouseOpaque(FALSE);
-
+
+ std::map<std::string, std::string> material_name_map;
+ material_name_map["Stone"]= LLTrans::getString("Stone");
+ material_name_map["Metal"]= LLTrans::getString("Metal");
+ material_name_map["Glass"]= LLTrans::getString("Glass");
+ material_name_map["Wood"]= LLTrans::getString("Wood");
+ material_name_map["Flesh"]= LLTrans::getString("Flesh");
+ material_name_map["Plastic"]= LLTrans::getString("Plastic");
+ material_name_map["Rubber"]= LLTrans::getString("Rubber");
+ material_name_map["Light"]= LLTrans::getString("Light");
+
+ LLMaterialTable::basic.initTableTransNames(material_name_map);
//--------------------------------------------------------
// Top
//--------------------------------------------------------
@@ -164,14 +174,14 @@ BOOL LLPanelObject::postBuild()
mComboMaterial = getChild<LLComboBox>("material");
childSetCommitCallback("material",onCommitMaterial,this);
mComboMaterial->removeall();
- // *TODO:translate
+
for (LLMaterialTable::info_list_t::iterator iter = LLMaterialTable::basic.mMaterialInfoList.begin();
iter != LLMaterialTable::basic.mMaterialInfoList.end(); ++iter)
{
LLMaterialInfo* minfop = *iter;
if (minfop->mMCode != LL_MCODE_LIGHT)
{
- mComboMaterial->add(minfop->mName);
+ mComboMaterial->add(minfop->mName);
}
}
mComboMaterialItemCount = mComboMaterial->getItemCount();
@@ -263,11 +273,10 @@ BOOL LLPanelObject::postBuild()
if (mCtrlSculptTexture)
{
mCtrlSculptTexture->setDefaultImageAssetID(LLUUID(SCULPT_DEFAULT_TEXTURE));
- mCtrlSculptTexture->setCommitCallback( LLPanelObject::onCommitSculpt );
- mCtrlSculptTexture->setOnCancelCallback( LLPanelObject::onCancelSculpt );
- mCtrlSculptTexture->setOnSelectCallback( LLPanelObject::onSelectSculpt );
- mCtrlSculptTexture->setDropCallback(LLPanelObject::onDropSculpt);
- mCtrlSculptTexture->setCallbackUserData( this );
+ mCtrlSculptTexture->setCommitCallback( boost::bind(&LLPanelObject::onCommitSculpt, this, _2 ));
+ mCtrlSculptTexture->setOnCancelCallback( boost::bind(&LLPanelObject::onCancelSculpt, this, _2 ));
+ mCtrlSculptTexture->setOnSelectCallback( boost::bind(&LLPanelObject::onSelectSculpt, this, _2 ));
+ mCtrlSculptTexture->setDropCallback( boost::bind(&LLPanelObject::onDropSculpt, this, _2 ));
// Don't allow (no copy) or (no transfer) textures to be selected during immediate mode
mCtrlSculptTexture->setImmediateFilterPermMask(PERM_COPY | PERM_TRANSFER);
// Allow any texture to be used during non-immediate mode.
@@ -303,8 +312,8 @@ BOOL LLPanelObject::postBuild()
return TRUE;
}
-LLPanelObject::LLPanelObject(const std::string& name)
-: LLPanel(name),
+LLPanelObject::LLPanelObject()
+: LLPanel(),
mIsPhysical(FALSE),
mIsTemporary(FALSE),
mIsPhantom(FALSE),
@@ -530,7 +539,7 @@ void LLPanelObject::getState( )
}
} func;
bool material_same = LLSelectMgr::getInstance()->getSelection()->getSelectedTEValue( &func, material_code );
-
+ std::string LEGACY_FULLBRIGHT_DESC = LLTrans::getString("Fullbright");
if (editable && single_volume && material_same)
{
mComboMaterial->setEnabled( TRUE );
@@ -549,7 +558,7 @@ void LLPanelObject::getState( )
{
mComboMaterial->remove(LEGACY_FULLBRIGHT_DESC);
}
- // *TODO:Translate
+
mComboMaterial->setSimple(std::string(LLMaterialTable::basic.getName(material_code)));
}
}
@@ -1163,7 +1172,7 @@ void LLPanelObject::getState( )
}
// static
-BOOL LLPanelObject::precommitValidate( LLUICtrl* ctrl, void* userdata )
+bool LLPanelObject::precommitValidate( const LLSD& data )
{
// TODO: Richard will fill this in later.
return TRUE; // FALSE means that validation failed and new value should not be commited.
@@ -1244,6 +1253,7 @@ void LLPanelObject::onCommitMaterial( LLUICtrl* ctrl, void* userdata )
{
// apply the currently selected material to the object
const std::string& material_name = box->getSimple();
+ std::string LEGACY_FULLBRIGHT_DESC = LLTrans::getString("Fullbright");
if (material_name != LEGACY_FULLBRIGHT_DESC)
{
U8 material_code = LLMaterialTable::basic.getMCode(material_name);
@@ -1992,60 +2002,49 @@ void LLPanelObject::onCommitCastShadows( LLUICtrl* ctrl, void* userdata )
}
-// static
-void LLPanelObject::onSelectSculpt(LLUICtrl* ctrl, void* userdata)
+void LLPanelObject::onSelectSculpt(const LLSD& data)
{
- LLPanelObject* self = (LLPanelObject*) userdata;
-
- LLTextureCtrl* mTextureCtrl = self->getChild<LLTextureCtrl>("sculpt texture control");
+ LLTextureCtrl* mTextureCtrl = getChild<LLTextureCtrl>("sculpt texture control");
if (mTextureCtrl)
{
- self->mSculptTextureRevert = mTextureCtrl->getImageAssetID();
+ mSculptTextureRevert = mTextureCtrl->getImageAssetID();
}
- self->sendSculpt();
+ sendSculpt();
}
-void LLPanelObject::onCommitSculpt( LLUICtrl* ctrl, void* userdata )
+void LLPanelObject::onCommitSculpt( const LLSD& data )
{
- LLPanelObject* self = (LLPanelObject*) userdata;
-
- self->sendSculpt();
+ sendSculpt();
}
-// static
-BOOL LLPanelObject::onDropSculpt(LLUICtrl*, LLInventoryItem* item, void* userdata)
+BOOL LLPanelObject::onDropSculpt(LLInventoryItem* item)
{
- LLPanelObject* self = (LLPanelObject*) userdata;
-
- LLTextureCtrl* mTextureCtrl = self->getChild<LLTextureCtrl>("sculpt texture control");
+ LLTextureCtrl* mTextureCtrl = getChild<LLTextureCtrl>("sculpt texture control");
if (mTextureCtrl)
{
LLUUID asset = item->getAssetUUID();
mTextureCtrl->setImageAssetID(asset);
- self->mSculptTextureRevert = asset;
+ mSculptTextureRevert = asset;
}
return TRUE;
}
-// static
-void LLPanelObject::onCancelSculpt(LLUICtrl* ctrl, void* userdata)
+void LLPanelObject::onCancelSculpt(const LLSD& data)
{
- LLPanelObject* self = (LLPanelObject*) userdata;
-
- LLTextureCtrl* mTextureCtrl = self->getChild<LLTextureCtrl>("sculpt texture control");
+ LLTextureCtrl* mTextureCtrl = getChild<LLTextureCtrl>("sculpt texture control");
if(!mTextureCtrl)
return;
- mTextureCtrl->setImageAssetID(self->mSculptTextureRevert);
+ mTextureCtrl->setImageAssetID(mSculptTextureRevert);
- self->sendSculpt();
+ sendSculpt();
}
// static
diff --git a/indra/newview/llpanelobject.h b/indra/newview/llpanelobject.h
index 9ed091ed5f..1ab4ff581e 100644
--- a/indra/newview/llpanelobject.h
+++ b/indra/newview/llpanelobject.h
@@ -35,7 +35,7 @@
#include "v3math.h"
#include "llpanel.h"
-#include "llmemory.h"
+#include "llpointer.h"
#include "llvolume.h"
class LLSpinCtrl;
@@ -54,7 +54,7 @@ class LLUUID;
class LLPanelObject : public LLPanel
{
public:
- LLPanelObject(const std::string& name);
+ LLPanelObject();
virtual ~LLPanelObject();
virtual BOOL postBuild();
@@ -63,7 +63,7 @@ public:
void refresh();
- static BOOL precommitValidate(LLUICtrl* ctrl,void* userdata);
+ static bool precommitValidate(const LLSD& data);
static void onCommitLock(LLUICtrl *ctrl, void *data);
static void onCommitPosition( LLUICtrl* ctrl, void* userdata);
@@ -78,10 +78,10 @@ public:
static void onCommitMaterial( LLUICtrl* ctrl, void* userdata);
- static void onCommitSculpt( LLUICtrl* ctrl, void* userdata);
- static void onCancelSculpt( LLUICtrl* ctrl, void* userdata);
- static void onSelectSculpt( LLUICtrl* ctrl, void* userdata);
- static BOOL onDropSculpt( LLUICtrl* ctrl, LLInventoryItem* item, void* ud);
+ void onCommitSculpt(const LLSD& data);
+ void onCancelSculpt(const LLSD& data);
+ void onSelectSculpt(const LLSD& data);
+ BOOL onDropSculpt(LLInventoryItem* item);
static void onCommitSculptType( LLUICtrl *ctrl, void* userdata);
diff --git a/indra/newview/llpanelpeople.cpp b/indra/newview/llpanelpeople.cpp
new file mode 100644
index 0000000000..697182c8fc
--- /dev/null
+++ b/indra/newview/llpanelpeople.cpp
@@ -0,0 +1,952 @@
+/**
+ * @file llpanelpeople.cpp
+ * @brief Side tray "People" panel
+ *
+ * $LicenseInfo:firstyear=2009&license=viewergpl$
+ *
+ * Copyright (c) 2009, Linden Research, Inc.
+ *
+ * Second Life Viewer Source Code
+ * The source code in this file ("Source Code") is provided by Linden Lab
+ * to you under the terms of the GNU General Public License, version 2.0
+ * ("GPL"), unless you have obtained a separate licensing agreement
+ * ("Other License"), formally executed by you and Linden Lab. Terms of
+ * the GPL can be found in doc/GPL-license.txt in this distribution, or
+ * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
+ *
+ * There are special exceptions to the terms and conditions of the GPL as
+ * it is applied to this Source Code. View the full text of the exception
+ * in the file doc/FLOSS-exception.txt in this software distribution, or
+ * online at
+ * http://secondlifegrid.net/programs/open_source/licensing/flossexception
+ *
+ * By copying, modifying or distributing this software, you acknowledge
+ * that you have read and understood your obligations described above,
+ * and agree to abide by those obligations.
+ *
+ * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+ * COMPLETENESS OR PERFORMANCE.
+ * $/LicenseInfo$
+ */
+
+#include "llviewerprecompiledheaders.h"
+
+// libs
+#include "llfloaterreg.h"
+#include "llmenugl.h"
+#include "llfiltereditor.h"
+#include "lltabcontainer.h"
+#include "lluictrlfactory.h"
+
+#include "llpanelpeople.h"
+
+// newview
+#include "llagent.h"
+#include "llavatarlist.h"
+#include "llcallingcard.h" // for LLAvatarTracker
+#include "llfloateravatarpicker.h"
+//#include "llfloaterminiinspector.h"
+#include "llfriendcard.h"
+#include "llavataractions.h"
+#include "llgroupactions.h"
+#include "llgrouplist.h"
+#include "llrecentpeople.h"
+#include "llviewercontrol.h" // for gSavedSettings
+#include "llviewermenu.h" // for gMenuHolder
+#include "llvoiceclient.h"
+#include "llworld.h"
+
+using namespace LLOldEvents;
+
+#define FRIEND_LIST_UPDATE_TIMEOUT 0.5
+#define NEARBY_LIST_UPDATE_INTERVAL 1
+#define RECENT_LIST_UPDATE_DELAY 1
+
+static const std::string NEARBY_TAB_NAME = "nearby_panel";
+static const std::string FRIENDS_TAB_NAME = "friends_panel";
+static const std::string GROUP_TAB_NAME = "groups_panel";
+static const std::string RECENT_TAB_NAME = "recent_panel";
+
+static LLRegisterPanelClassWrapper<LLPanelPeople> t_people("panel_people");
+
+//=============================================================================
+
+/**
+ * Updates given list either on regular basis or on external events (up to implementation).
+ */
+class LLPanelPeople::Updater
+{
+public:
+ typedef boost::function<bool(U32)> callback_t;
+ Updater(callback_t cb)
+ : mCallback(cb)
+ {
+ }
+
+ virtual ~Updater()
+ {
+ }
+
+ /**
+ * Force the list updates.
+ *
+ * This may start repeated updates until all names are complete.
+ */
+ virtual void forceUpdate()
+ {
+ updateList();
+ }
+
+ /**
+ * Activate/deactivate updater.
+ *
+ * This may start/stop regular updates.
+ */
+ virtual void setActive(bool) {}
+
+protected:
+ bool updateList(U32 mask = 0)
+ {
+ return mCallback(mask);
+ }
+
+ callback_t mCallback;
+};
+
+class LLAvatarListUpdater : public LLPanelPeople::Updater, public LLEventTimer
+{
+public:
+ LLAvatarListUpdater(callback_t cb, F32 period)
+ : LLEventTimer(period),
+ LLPanelPeople::Updater(cb)
+ {
+ mEventTimer.stop();
+ }
+};
+
+/**
+ * Updates the friends list.
+ *
+ * Updates the list on external events which trigger the changed() method.
+ */
+class LLFriendListUpdater : public LLAvatarListUpdater, public LLFriendObserver
+{
+ LOG_CLASS(LLFriendListUpdater);
+
+public:
+ LLFriendListUpdater(callback_t cb)
+ : LLAvatarListUpdater(cb, FRIEND_LIST_UPDATE_TIMEOUT)
+ {
+ LLAvatarTracker::instance().addObserver(this);
+ // For notification when SIP online status changes.
+ LLVoiceClient::getInstance()->addObserver(this);
+ }
+
+ ~LLFriendListUpdater()
+ {
+ LLVoiceClient::getInstance()->removeObserver(this);
+ LLAvatarTracker::instance().removeObserver(this);
+ }
+
+ /*virtual*/ void forceUpdate()
+ {
+ // Perform updates until all names are loaded.
+ if (!updateList(LLFriendObserver::ADD))
+ changed(LLFriendObserver::ADD);
+ }
+
+ /*virtual*/ void changed(U32 mask)
+ {
+ // events can arrive quickly in bulk - we need not process EVERY one of them -
+ // so we wait a short while to let others pile-in, and process them in aggregate.
+ mEventTimer.start();
+
+ // save-up all the mask-bits which have come-in
+ mMask |= mask;
+ }
+
+ /*virtual*/ BOOL tick()
+ {
+ if (updateList(mMask))
+ {
+ // Got all names, stop updates.
+ mEventTimer.stop();
+ mMask = 0;
+ }
+
+ return FALSE;
+ }
+
+private:
+ U32 mMask;
+};
+
+/**
+ * Periodically updates the nearby people list while the Nearby tab is active.
+ *
+ * The period is defined by NEARBY_LIST_UPDATE_INTERVAL constant.
+ */
+class LLNearbyListUpdater : public LLAvatarListUpdater
+{
+ LOG_CLASS(LLNearbyListUpdater);
+
+public:
+ LLNearbyListUpdater(callback_t cb)
+ : LLAvatarListUpdater(cb, NEARBY_LIST_UPDATE_INTERVAL)
+ {
+ setActive(false);
+ }
+
+ /*virtual*/ void setActive(bool val)
+ {
+ if (val)
+ {
+ // update immediately and start regular updates
+ updateList();
+ mEventTimer.start();
+ }
+ else
+ {
+ // stop regular updates
+ mEventTimer.stop();
+ }
+ }
+
+ /*virtual*/ BOOL tick()
+ {
+ updateList();
+ return FALSE;
+ }
+private:
+};
+
+/**
+ * Updates the recent people list (those the agent has recently interacted with).
+ */
+class LLRecentListUpdater : public LLAvatarListUpdater
+{
+ LOG_CLASS(LLRecentListUpdater);
+
+public:
+ LLRecentListUpdater(callback_t cb)
+ : LLAvatarListUpdater(cb, RECENT_LIST_UPDATE_DELAY)
+ {
+ LLRecentPeople::instance().setChangedCallback(boost::bind(&LLRecentListUpdater::onRecentPeopleChanged, this));
+ }
+
+private:
+ /*virtual*/ void forceUpdate()
+ {
+ onRecentPeopleChanged();
+ }
+
+ /*virtual*/ BOOL tick()
+ {
+ // Update the list until we get all the names.
+ if (updateList())
+ {
+ // Got all names, stop updates.
+ mEventTimer.stop();
+ }
+
+ return FALSE;
+ }
+
+ void onRecentPeopleChanged()
+ {
+ if (!updateList())
+ {
+ // Some names are incomplete, schedule another update.
+ mEventTimer.start();
+ }
+ }
+};
+
+/**
+ * Updates the group list on events from LLAgent.
+ */
+class LLGroupListUpdater : public LLPanelPeople::Updater, public LLSimpleListener
+{
+ LOG_CLASS(LLGroupListUpdater);
+
+public:
+ LLGroupListUpdater(callback_t cb)
+ : LLPanelPeople::Updater(cb)
+ {
+ gAgent.addListener(this, "new group");
+ }
+
+ ~LLGroupListUpdater()
+ {
+ gAgent.removeListener(this);
+ }
+
+ /*virtual*/ bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
+ {
+ // Why is "new group" sufficient?
+ if (event->desc() == "new group")
+ {
+ updateList();
+ return true;
+ }
+
+ return false;
+ }
+};
+
+//=============================================================================
+
+LLPanelPeople::LLPanelPeople()
+ : LLPanel(),
+ mFilterSubString(LLStringUtil::null),
+ mFilterEditor(NULL),
+ mTabContainer(NULL),
+ mOnlineFriendList(NULL),
+ mAllFriendList(NULL),
+ mNearbyList(NULL),
+ mRecentList(NULL)
+{
+ mFriendListUpdater = new LLFriendListUpdater(boost::bind(&LLPanelPeople::onFriendListUpdate,this, _1));
+ mNearbyListUpdater = new LLNearbyListUpdater(boost::bind(&LLPanelPeople::updateNearbyList, this));
+ mRecentListUpdater = new LLRecentListUpdater(boost::bind(&LLPanelPeople::updateRecentList, this));
+ mGroupListUpdater = new LLGroupListUpdater (boost::bind(&LLPanelPeople::updateGroupList, this));
+}
+
+LLPanelPeople::~LLPanelPeople()
+{
+ delete mNearbyListUpdater;
+ delete mFriendListUpdater;
+ delete mRecentListUpdater;
+ delete mGroupListUpdater;
+
+ LLView::deleteViewByHandle(mGroupPlusMenuHandle);
+ LLView::deleteViewByHandle(mNearbyViewSortMenuHandle);
+ LLView::deleteViewByHandle(mFriendsViewSortMenuHandle);
+ LLView::deleteViewByHandle(mRecentViewSortMenuHandle);
+
+}
+
+BOOL LLPanelPeople::postBuild()
+{
+ mVisibleSignal.connect(boost::bind(&LLPanelPeople::onVisibilityChange, this, _2));
+
+ mFilterEditor = getChild<LLFilterEditor>("filter_input");
+ mFilterEditor->setCommitCallback(boost::bind(&LLPanelPeople::onFilterEdit, this, _2));
+
+ mTabContainer = getChild<LLTabContainer>("tabs");
+ mTabContainer->setCommitCallback(boost::bind(&LLPanelPeople::onTabSelected, this, _2));
+
+ mOnlineFriendList = getChild<LLPanel>(FRIENDS_TAB_NAME)->getChild<LLAvatarList>("avatars_online");
+ mAllFriendList = getChild<LLPanel>(FRIENDS_TAB_NAME)->getChild<LLAvatarList>("avatars_all");
+
+ mNearbyList = getChild<LLPanel>(NEARBY_TAB_NAME)->getChild<LLAvatarList>("avatar_list");
+
+ mRecentList = getChild<LLPanel>(RECENT_TAB_NAME)->getChild<LLAvatarList>("avatar_list");
+ mGroupList = getChild<LLGroupList>("group_list");
+
+ LLPanel* groups_panel = getChild<LLPanel>(GROUP_TAB_NAME);
+ groups_panel->childSetAction("activate_btn", boost::bind(&LLPanelPeople::onActivateButtonClicked, this));
+ groups_panel->childSetAction("plus_btn", boost::bind(&LLPanelPeople::onGroupPlusButtonClicked, this));
+ groups_panel->childSetAction("minus_btn", boost::bind(&LLPanelPeople::onGroupMinusButtonClicked, this));
+
+ LLPanel* friends_panel = getChild<LLPanel>(FRIENDS_TAB_NAME);
+ friends_panel->childSetAction("add_btn", boost::bind(&LLPanelPeople::onAddFriendWizButtonClicked, this));
+ friends_panel->childSetAction("del_btn", boost::bind(&LLPanelPeople::onDeleteFriendButtonClicked, this));
+
+ mOnlineFriendList->setDoubleClickCallback(boost::bind(&LLPanelPeople::onAvatarListDoubleClicked, this, mOnlineFriendList));
+ mAllFriendList->setDoubleClickCallback(boost::bind(&LLPanelPeople::onAvatarListDoubleClicked, this, mAllFriendList));
+ mNearbyList->setDoubleClickCallback(boost::bind(&LLPanelPeople::onAvatarListDoubleClicked, this, mNearbyList));
+ mRecentList->setDoubleClickCallback(boost::bind(&LLPanelPeople::onAvatarListDoubleClicked, this, mRecentList));
+ mOnlineFriendList->setCommitCallback(boost::bind(&LLPanelPeople::onAvatarListCommitted, this, mOnlineFriendList));
+ mAllFriendList->setCommitCallback(boost::bind(&LLPanelPeople::onAvatarListCommitted, this, mAllFriendList));
+ mNearbyList->setCommitCallback(boost::bind(&LLPanelPeople::onAvatarListCommitted, this, mNearbyList));
+ mRecentList->setCommitCallback(boost::bind(&LLPanelPeople::onAvatarListCommitted, this, mRecentList));
+
+ mGroupList->setDoubleClickCallback(boost::bind(&LLPanelPeople::onGroupInfoButtonClicked, this));
+ mGroupList->setCommitCallback(boost::bind(&LLPanelPeople::updateButtons, this));
+
+ buttonSetAction("view_profile_btn", boost::bind(&LLPanelPeople::onViewProfileButtonClicked, this));
+ buttonSetAction("add_friend_btn", boost::bind(&LLPanelPeople::onAddFriendButtonClicked, this));
+ buttonSetAction("group_info_btn", boost::bind(&LLPanelPeople::onGroupInfoButtonClicked, this));
+ buttonSetAction("chat_btn", boost::bind(&LLPanelPeople::onChatButtonClicked, this));
+ buttonSetAction("im_btn", boost::bind(&LLPanelPeople::onImButtonClicked, this));
+ buttonSetAction("call_btn", boost::bind(&LLPanelPeople::onCallButtonClicked, this));
+ buttonSetAction("teleport_btn", boost::bind(&LLPanelPeople::onTeleportButtonClicked, this));
+ buttonSetAction("share_btn", boost::bind(&LLPanelPeople::onShareButtonClicked, this));
+
+ getChild<LLPanel>(NEARBY_TAB_NAME)->childSetAction("nearby_view_sort_btn",boost::bind(&LLPanelPeople::onNearbyViewSortButtonClicked, this));
+ getChild<LLPanel>(RECENT_TAB_NAME)->childSetAction("recent_viewsort_btn",boost::bind(&LLPanelPeople::onRecentViewSortButtonClicked, this));
+ getChild<LLPanel>(FRIENDS_TAB_NAME)->childSetAction("friends_viewsort_btn",boost::bind(&LLPanelPeople::onFriendsViewSortButtonClicked, this));
+
+ // Must go after setting commit callback and initializing all pointers to children.
+ mTabContainer->selectTabByName(FRIENDS_TAB_NAME);
+
+ // Create menus.
+ LLUICtrl::CommitCallbackRegistry::ScopedRegistrar registrar;
+
+ registrar.add("People.Group.Plus.Action", boost::bind(&LLPanelPeople::onGroupPlusMenuItemClicked, this, _2));
+ registrar.add("People.Friends.ViewSort.Action", boost::bind(&LLPanelPeople::onFriendsViewSortMenuItemClicked, this, _2));
+ registrar.add("People.Nearby.ViewSort.Action", boost::bind(&LLPanelPeople::onNearbyViewSortMenuItemClicked, this, _2));
+ registrar.add("People.Recent.ViewSort.Action", boost::bind(&LLPanelPeople::onRecentViewSortMenuItemClicked, this, _2));
+
+ LLMenuGL* plus_menu = LLUICtrlFactory::getInstance()->createFromFile<LLMenuGL>("menu_group_plus.xml", gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance());
+ mGroupPlusMenuHandle = plus_menu->getHandle();
+
+ LLMenuGL* nearby_view_sort = LLUICtrlFactory::getInstance()->createFromFile<LLMenuGL>("menu_people_nearby_view_sort.xml", gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance());
+ if(nearby_view_sort)
+ mNearbyViewSortMenuHandle = nearby_view_sort->getHandle();
+
+ LLMenuGL* friend_view_sort = LLUICtrlFactory::getInstance()->createFromFile<LLMenuGL>("menu_people_friends_view_sort.xml", gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance());
+ if(friend_view_sort)
+ mFriendsViewSortMenuHandle = friend_view_sort->getHandle();
+
+ LLMenuGL* recent_view_sort = LLUICtrlFactory::getInstance()->createFromFile<LLMenuGL>("menu_people_recent_view_sort.xml", gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance());
+ if(recent_view_sort)
+ mRecentViewSortMenuHandle = recent_view_sort->getHandle();
+
+
+
+ // Perform initial update.
+ mFriendListUpdater->forceUpdate();
+ mRecentListUpdater->forceUpdate();
+ mGroupListUpdater->forceUpdate();
+ mRecentListUpdater->forceUpdate();
+
+ return TRUE;
+}
+
+bool LLPanelPeople::updateFriendList(U32 changed_mask)
+{
+ // Refresh names.
+ if (changed_mask & (LLFriendObserver::ADD | LLFriendObserver::REMOVE | LLFriendObserver::ONLINE))
+ {
+ // get all buddies we know about
+ const LLAvatarTracker& av_tracker = LLAvatarTracker::instance();
+ LLAvatarTracker::buddy_map_t all_buddies;
+ av_tracker.copyBuddyList(all_buddies);
+
+ // *TODO: it's suboptimal to rebuild the whole lists on online status change.
+
+ // save them to the online and all friends vectors
+ mOnlineFriendVec.clear();
+ mAllFriendVec.clear();
+
+ LLFriendCardsManager::folderid_buddies_map_t listMap;
+
+ // *NOTE: For now collectFriendsLists returns data only for Friends/All folder. EXT-694.
+ LLFriendCardsManager::instance().collectFriendsLists(listMap);
+ if (listMap.size() > 0)
+ {
+ mAllFriendVec = listMap.begin()->second;
+ }
+
+ LLAvatarTracker::buddy_map_t::const_iterator buddy_it = all_buddies.begin();
+ for (; buddy_it != all_buddies.end(); ++buddy_it)
+ {
+ LLUUID buddy_id = buddy_it->first;
+ if (av_tracker.isBuddyOnline(buddy_id))
+ mOnlineFriendVec.push_back(buddy_id);
+ }
+
+ return filterFriendList();
+ }
+
+ return true;
+}
+
+bool LLPanelPeople::updateNearbyList()
+{
+ LLWorld::getInstance()->getAvatars(&mNearbyVec, NULL, gAgent.getPositionGlobal(), gSavedSettings.getF32("NearMeRange"));
+ filterNearbyList();
+
+ return true;
+}
+
+bool LLPanelPeople::updateRecentList()
+{
+ LLRecentPeople::instance().get(mRecentVec);
+ filterRecentList();
+
+ return true;
+}
+
+bool LLPanelPeople::updateGroupList()
+{
+ if (!mGroupList)
+ return true; // there's no point in further updates
+
+ bool have_names = mGroupList->update(mFilterSubString);
+
+ if (mGroupList->isEmpty())
+ mGroupList->setCommentText(getString("no_groups"));
+
+ return have_names;
+}
+
+bool LLPanelPeople::filterFriendList()
+{
+ if (!mOnlineFriendList || !mAllFriendList)
+ return true; // there's no point in further updates
+
+ // We must always update Friends list to clear the latest removed friend.
+ bool have_names =
+ mOnlineFriendList->update(mOnlineFriendVec, mFilterSubString) &
+ mAllFriendList->update(mAllFriendVec, mFilterSubString);
+
+ if (mOnlineFriendVec.size() == 0)
+ mOnlineFriendList->setCommentText(getString("no_friends_online"));
+
+ if (mAllFriendVec.size() == 0)
+ mAllFriendList->setCommentText(getString("no_friends"));
+
+ return have_names;
+}
+
+bool LLPanelPeople::filterNearbyList()
+{
+ bool have_names = mNearbyList->update(mNearbyVec, mFilterSubString);
+
+ if (mNearbyVec.size() == 0)
+ mNearbyList->setCommentText(getString("no_one_near"));
+
+ return have_names;
+}
+
+bool LLPanelPeople::filterRecentList()
+{
+ if (!mRecentList)
+ return true;
+
+ if (mRecentVec.size() > 0)
+ return mRecentList->update(mRecentVec, mFilterSubString);
+
+ mRecentList->setCommentText(getString("no_people"));
+
+ return true;
+}
+
+void LLPanelPeople::buttonSetVisible(std::string btn_name, BOOL visible)
+{
+ // Currently all bottom buttons are wrapped with layout panels.
+ // Hiding a button has no effect: the panel still occupies its space.
+ // So we have to hide the whole panel (along with its button)
+ // to free some space up.
+ LLButton* btn = getChild<LLView>("button_bar")->getChild<LLButton>(btn_name);
+ LLPanel* btn_parent = dynamic_cast<LLPanel*>(btn->getParent());
+ if (btn_parent)
+ btn_parent->setVisible(visible);
+}
+
+void LLPanelPeople::buttonSetEnabled(const std::string& btn_name, bool enabled)
+{
+ // To make sure we're referencing the right widget (a child of the button bar).
+ LLButton* button = getChild<LLView>("button_bar")->getChild<LLButton>(btn_name);
+ button->setEnabled(enabled);
+}
+
+void LLPanelPeople::buttonSetAction(const std::string& btn_name, const commit_signal_t::slot_type& cb)
+{
+ // To make sure we're referencing the right widget (a child of the button bar).
+ LLButton* button = getChild<LLView>("button_bar")->getChild<LLButton>(btn_name);
+ button->setClickedCallback(cb);
+}
+
+void LLPanelPeople::updateButtons()
+{
+ std::string cur_tab = getActiveTabName();
+ bool nearby_tab_active = (cur_tab == NEARBY_TAB_NAME);
+ bool friends_tab_active = (cur_tab == FRIENDS_TAB_NAME);
+ bool group_tab_active = (cur_tab == GROUP_TAB_NAME);
+ bool recent_tab_active = (cur_tab == RECENT_TAB_NAME);
+ LLUUID selected_id;
+
+ buttonSetVisible("group_info_btn", group_tab_active);
+ buttonSetVisible("chat_btn", group_tab_active);
+ buttonSetVisible("add_friend_btn", nearby_tab_active || recent_tab_active);
+ buttonSetVisible("view_profile_btn", !group_tab_active);
+ buttonSetVisible("im_btn", !group_tab_active);
+ buttonSetVisible("teleport_btn", friends_tab_active);
+ buttonSetVisible("share_btn", !recent_tab_active && false); // not implemented yet
+
+ if (group_tab_active)
+ {
+ bool item_selected = mGroupList->getFirstSelected() != NULL;
+ bool cur_group_active = true;
+
+ if (item_selected)
+ {
+ selected_id = mGroupList->getCurrentID();
+ cur_group_active = (gAgent.getGroupID() == selected_id);
+ }
+
+ LLPanel* groups_panel = mTabContainer->getCurrentPanel();
+ groups_panel->childSetEnabled("activate_btn", item_selected && !cur_group_active); // "none" or a non-active group selected
+ groups_panel->childSetEnabled("plus_btn", item_selected);
+ groups_panel->childSetEnabled("minus_btn", item_selected && selected_id.notNull());
+ }
+ else
+ {
+ bool is_friend = true;
+
+ // Check whether selected avatar is our friend.
+ if ((selected_id = getCurrentItemID()).notNull())
+ {
+ is_friend = LLAvatarTracker::instance().getBuddyInfo(selected_id) != NULL;
+ }
+
+ childSetEnabled("add_friend_btn", !is_friend);
+ }
+
+ bool item_selected = selected_id.notNull();
+ buttonSetEnabled("teleport_btn", friends_tab_active && item_selected);
+ buttonSetEnabled("view_profile_btn", item_selected);
+ buttonSetEnabled("im_btn", item_selected);
+ buttonSetEnabled("call_btn", item_selected && false); // not implemented yet
+ buttonSetEnabled("share_btn", item_selected && false); // not implemented yet
+ buttonSetEnabled("group_info_btn", item_selected);
+ buttonSetEnabled("chat_btn", item_selected);
+}
+
+const std::string& LLPanelPeople::getActiveTabName() const
+{
+ return mTabContainer->getCurrentPanel()->getName();
+}
+
+LLUUID LLPanelPeople::getCurrentItemID() const
+{
+ std::string cur_tab = getActiveTabName();
+
+ if (cur_tab == FRIENDS_TAB_NAME) // this tab has two lists
+ {
+ LLUUID cur_online_friend;
+
+ if ((cur_online_friend = mOnlineFriendList->getCurrentID()).notNull())
+ return cur_online_friend;
+
+ return mAllFriendList->getCurrentID();
+ }
+
+ if (cur_tab == NEARBY_TAB_NAME)
+ return mNearbyList->getCurrentID();
+
+ if (cur_tab == RECENT_TAB_NAME)
+ return mRecentList->getCurrentID();
+
+ if (cur_tab == GROUP_TAB_NAME)
+ return mGroupList->getCurrentID();
+
+ llassert(0 && "unknown tab selected");
+ return LLUUID::null;
+}
+
+void LLPanelPeople::showGroupMenu(LLMenuGL* menu)
+{
+ // Shows the menu at the top of the button bar.
+
+ // Calculate its coordinates.
+ // (assumes that groups panel is the current tab)
+ LLPanel* bottom_panel = mTabContainer->getCurrentPanel()->getChild<LLPanel>("bottom_panel");
+ LLPanel* parent_panel = mTabContainer->getCurrentPanel();
+ menu->arrangeAndClear();
+ S32 menu_height = menu->getRect().getHeight();
+ S32 menu_x = -2; // *HACK: compensates HPAD in showPopup()
+ S32 menu_y = bottom_panel->getRect().mTop + menu_height;
+
+ // Actually show the menu.
+ menu->buildDrawLabels();
+ menu->updateParent(LLMenuGL::sMenuContainer);
+ LLMenuGL::showPopup(parent_panel, menu, menu_x, menu_y);
+}
+
+void LLPanelPeople::onVisibilityChange(const LLSD& new_visibility)
+{
+ if (new_visibility.asBoolean() == FALSE)
+ {
+ // Don't update anything while we're invisible.
+ mNearbyListUpdater->setActive(FALSE);
+ }
+ else
+ {
+ reSelectedCurrentTab();
+ }
+}
+
+// Make the tab-container re-select current tab
+// for onTabSelected() callback to get called.
+// (currently this is needed to reactivate nearby list updates
+// when we get visible)
+void LLPanelPeople::reSelectedCurrentTab()
+{
+ mTabContainer->selectTab(mTabContainer->getCurrentPanelIndex());
+}
+
+void LLPanelPeople::onFilterEdit(const std::string& search_string)
+{
+ if (mFilterSubString == search_string)
+ return;
+
+ mFilterSubString = search_string;
+
+ // Searches are case-insensitive
+ LLStringUtil::toUpper(mFilterSubString);
+ LLStringUtil::trimHead(mFilterSubString);
+
+ // Apply new filter to all tabs.
+ filterNearbyList();
+ filterFriendList();
+ filterRecentList();
+ updateGroupList();
+
+ updateButtons();
+}
+
+void LLPanelPeople::onTabSelected(const LLSD& param)
+{
+ std::string tab_name = getChild<LLPanel>(param.asString())->getName();
+ mNearbyListUpdater->setActive(tab_name == NEARBY_TAB_NAME);
+ updateButtons();
+
+ if (GROUP_TAB_NAME == tab_name)
+ mFilterEditor->setLabel(getString("groups_filter_label"));
+ else
+ mFilterEditor->setLabel(getString("people_filter_label"));
+}
+
+void LLPanelPeople::onAvatarListDoubleClicked(LLAvatarList* list)
+{
+ LLUUID clicked_id = list->getCurrentID();
+
+ if (clicked_id.isNull())
+ return;
+
+#if 0 // SJB: Useful for testing, but not currently functional or to spec
+ LLAvatarActions::showProfile(clicked_id);
+#else // spec says open IM window
+ LLAvatarActions::startIM(clicked_id);
+#endif
+}
+
+void LLPanelPeople::onAvatarListCommitted(LLAvatarList* list)
+{
+ // Make sure only one of the friends lists (online/all) has selection.
+ if (getActiveTabName() == FRIENDS_TAB_NAME)
+ {
+ if (list == mOnlineFriendList)
+ mAllFriendList->deselectAllItems(TRUE);
+ else if (list == mAllFriendList)
+ mOnlineFriendList->deselectAllItems(TRUE);
+ else
+ llassert(0 && "commit on unknown friends list");
+ }
+
+ updateButtons();
+}
+
+void LLPanelPeople::onViewProfileButtonClicked()
+{
+ LLUUID id = getCurrentItemID();
+ LLAvatarActions::showProfile(id);
+}
+
+void LLPanelPeople::onAddFriendButtonClicked()
+{
+ LLUUID id = getCurrentItemID();
+ if (id.notNull())
+ {
+ LLAvatarActions::requestFriendshipDialog(id);
+ }
+}
+
+void LLPanelPeople::onAddFriendWizButtonClicked()
+{
+ // Show add friend wizard.
+ LLFloaterAvatarPicker* picker = LLFloaterAvatarPicker::show(onAvatarPicked, NULL, FALSE, TRUE);
+ LLFloater* root_floater = gFloaterView->getParentFloater(this);
+ if (root_floater)
+ {
+ root_floater->addDependentFloater(picker);
+ }
+}
+
+void LLPanelPeople::onDeleteFriendButtonClicked()
+{
+ LLAvatarActions::removeFriendDialog(getCurrentItemID());
+}
+
+void LLPanelPeople::onGroupInfoButtonClicked()
+{
+ LLGroupActions::show(getCurrentItemID());
+}
+
+void LLPanelPeople::onChatButtonClicked()
+{
+ LLUUID group_id = getCurrentItemID();
+ if (group_id.notNull())
+ LLGroupActions::startChat(group_id);
+}
+
+void LLPanelPeople::onImButtonClicked()
+{
+ LLUUID id = getCurrentItemID();
+ if (id.notNull())
+ {
+ LLAvatarActions::startIM(id);
+ }
+}
+
+void LLPanelPeople::onActivateButtonClicked()
+{
+ LLGroupActions::activate(mGroupList->getCurrentID());
+}
+
+// static
+void LLPanelPeople::onAvatarPicked(
+ const std::vector<std::string>& names,
+ const std::vector<LLUUID>& ids,
+ void*)
+{
+ if (!names.empty() && !ids.empty())
+ LLAvatarActions::requestFriendshipDialog(ids[0], names[0]);
+}
+
+bool LLPanelPeople::onFriendListUpdate(U32 changed_mask)
+{
+ bool have_names = updateFriendList(changed_mask);
+
+ // Update online status in the Recent tab.
+ // *TODO: isn't it too much to update the whole list?
+ updateRecentList();
+
+ return have_names;
+}
+
+void LLPanelPeople::onGroupPlusButtonClicked()
+{
+ LLMenuGL* plus_menu = (LLMenuGL*)mGroupPlusMenuHandle.get();
+ if (!plus_menu)
+ return;
+
+ showGroupMenu(plus_menu);
+}
+
+void LLPanelPeople::onGroupMinusButtonClicked()
+{
+ LLUUID group_id = getCurrentItemID();
+ if (group_id.notNull())
+ LLGroupActions::leave(group_id);
+}
+
+void LLPanelPeople::onGroupPlusMenuItemClicked(const LLSD& userdata)
+{
+ std::string chosen_item = userdata.asString();
+
+ if (chosen_item == "join_group")
+ LLGroupActions::search();
+ else if (chosen_item == "new_group")
+ LLGroupActions::createGroup();
+}
+
+void LLPanelPeople::onFriendsViewSortMenuItemClicked(const LLSD& userdata)
+{
+ std::string chosen_item = userdata.asString();
+
+ if (chosen_item == "sort_name")
+ {
+ }
+ else if (chosen_item == "sort_status")
+ {
+ }
+ else if (chosen_item == "view_icons")
+ {
+ }
+ else if (chosen_item == "organize_offline")
+ {
+ }
+}
+void LLPanelPeople::onNearbyViewSortMenuItemClicked(const LLSD& userdata)
+{
+ std::string chosen_item = userdata.asString();
+
+ if (chosen_item == "sort_recent")
+ {
+ }
+ else if (chosen_item == "sort_name")
+ {
+ }
+ else if (chosen_item == "view_icons")
+ {
+ }
+ else if (chosen_item == "sort_distance")
+ {
+ }
+}
+void LLPanelPeople::onRecentViewSortMenuItemClicked(const LLSD& userdata)
+{
+ std::string chosen_item = userdata.asString();
+
+ if (chosen_item == "sort_most")
+ {
+ }
+ else if (chosen_item == "sort_name")
+ {
+ }
+ else if (chosen_item == "view_icons")
+ {
+ }
+}
+
+
+void LLPanelPeople::onCallButtonClicked()
+{
+ // *TODO: not implemented yet
+}
+
+void LLPanelPeople::onTeleportButtonClicked()
+{
+ LLAvatarActions::offerTeleport(getCurrentItemID());
+}
+
+void LLPanelPeople::onShareButtonClicked()
+{
+ // *TODO: not implemented yet
+}
+
+void LLPanelPeople::onMoreButtonClicked()
+{
+ // *TODO: not implemented yet
+}
+void LLPanelPeople::onFriendsViewSortButtonClicked()
+{
+ LLMenuGL* menu = (LLMenuGL*)mFriendsViewSortMenuHandle.get();
+ if (!menu)
+ return;
+ showGroupMenu(menu);
+}
+void LLPanelPeople::onRecentViewSortButtonClicked()
+{
+ LLMenuGL* menu = (LLMenuGL*)mRecentViewSortMenuHandle.get();
+ if (!menu)
+ return;
+ showGroupMenu(menu);
+}
+void LLPanelPeople::onNearbyViewSortButtonClicked()
+{
+ LLMenuGL* menu = (LLMenuGL*)mNearbyViewSortMenuHandle.get();
+ if (!menu)
+ return;
+ showGroupMenu(menu);
+}
+
+void LLPanelPeople::onOpen(const LLSD& key)
+{
+ std::string tab_name = key["people_panel_tab_name"];
+ mFilterEditor -> clear();
+ onFilterEdit("");
+
+ if (!tab_name.empty())
+ mTabContainer->selectTabByName(tab_name);
+ else
+ reSelectedCurrentTab();
+}
+
diff --git a/indra/newview/llpanelpeople.h b/indra/newview/llpanelpeople.h
new file mode 100644
index 0000000000..3358a70bac
--- /dev/null
+++ b/indra/newview/llpanelpeople.h
@@ -0,0 +1,149 @@
+/**
+ * @file llpanelpeople.h
+ * @brief Side tray "People" panel
+ *
+ * $LicenseInfo:firstyear=2009&license=viewergpl$
+ *
+ * Copyright (c) 2009, Linden Research, Inc.
+ *
+ * Second Life Viewer Source Code
+ * The source code in this file ("Source Code") is provided by Linden Lab
+ * to you under the terms of the GNU General Public License, version 2.0
+ * ("GPL"), unless you have obtained a separate licensing agreement
+ * ("Other License"), formally executed by you and Linden Lab. Terms of
+ * the GPL can be found in doc/GPL-license.txt in this distribution, or
+ * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
+ *
+ * There are special exceptions to the terms and conditions of the GPL as
+ * it is applied to this Source Code. View the full text of the exception
+ * in the file doc/FLOSS-exception.txt in this software distribution, or
+ * online at
+ * http://secondlifegrid.net/programs/open_source/licensing/flossexception
+ *
+ * By copying, modifying or distributing this software, you acknowledge
+ * that you have read and understood your obligations described above,
+ * and agree to abide by those obligations.
+ *
+ * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+ * COMPLETENESS OR PERFORMANCE.
+ * $/LicenseInfo$
+ */
+
+#ifndef LL_LLPANELPEOPLE_H
+#define LL_LLPANELPEOPLE_H
+
+#include <llpanel.h>
+
+#include "llcallingcard.h" // for avatar tracker
+
+class LLFilterEditor;
+class LLTabContainer;
+class LLAvatarList;
+class LLGroupList;
+
+class LLPanelPeople : public LLPanel
+{
+ LOG_CLASS(LLPanelPeople);
+public:
+ LLPanelPeople();
+ virtual ~LLPanelPeople();
+
+ /*virtual*/ BOOL postBuild();
+
+ virtual void onOpen(const LLSD& key);
+
+ // internals
+ class Updater;
+
+private:
+ // methods indirectly called by the updaters
+ bool updateFriendList(U32 changed_mask);
+ bool updateNearbyList();
+ bool updateRecentList();
+ bool updateGroupList();
+
+ bool filterFriendList();
+ bool filterNearbyList();
+ bool filterRecentList();
+ void updateButtons();
+ const std::string& getActiveTabName() const;
+ LLUUID getCurrentItemID() const;
+ void buttonSetVisible(std::string btn_name, BOOL visible);
+ void buttonSetEnabled(const std::string& btn_name, bool enabled);
+ void buttonSetAction(const std::string& btn_name, const commit_signal_t::slot_type& cb);
+ void showGroupMenu(LLMenuGL* menu);
+
+ void onVisibilityChange( const LLSD& new_visibility);
+
+ void reSelectedCurrentTab();
+
+ // UI callbacks
+ void onFilterEdit(const std::string& search_string);
+ void onTabSelected(const LLSD& param);
+ void onViewProfileButtonClicked();
+ void onAddFriendButtonClicked();
+ void onAddFriendWizButtonClicked();
+ void onDeleteFriendButtonClicked();
+ void onGroupInfoButtonClicked();
+ void onChatButtonClicked();
+ void onImButtonClicked();
+ void onCallButtonClicked();
+ void onTeleportButtonClicked();
+ void onShareButtonClicked();
+ void onMoreButtonClicked();
+ void onActivateButtonClicked();
+ void onRecentViewSortButtonClicked();
+ void onNearbyViewSortButtonClicked();
+ void onFriendsViewSortButtonClicked();
+ void onAvatarListDoubleClicked(LLAvatarList* list);
+ void onAvatarListCommitted(LLAvatarList* list);
+ void onGroupPlusButtonClicked();
+ void onGroupMinusButtonClicked();
+ void onGroupPlusMenuItemClicked(const LLSD& userdata);
+
+ void onFriendsViewSortMenuItemClicked(const LLSD& userdata);
+ void onNearbyViewSortMenuItemClicked(const LLSD& userdata);
+ void onRecentViewSortMenuItemClicked(const LLSD& userdata);
+
+ // misc callbacks
+ bool onFriendListUpdate(U32 changed_mask);
+ static void onAvatarPicked(
+ const std::vector<std::string>& names,
+ const std::vector<LLUUID>& ids,
+ void*);
+
+ LLFilterEditor* mFilterEditor;
+ LLTabContainer* mTabContainer;
+ LLAvatarList* mOnlineFriendList;
+ LLAvatarList* mAllFriendList;
+ LLAvatarList* mNearbyList;
+ LLAvatarList* mRecentList;
+ LLGroupList* mGroupList;
+
+ LLHandle<LLView> mGroupPlusMenuHandle;
+ LLHandle<LLView> mNearbyViewSortMenuHandle;
+ LLHandle<LLView> mFriendsViewSortMenuHandle;
+ LLHandle<LLView> mRecentViewSortMenuHandle;
+
+ Updater* mFriendListUpdater;
+ Updater* mNearbyListUpdater;
+ Updater* mRecentListUpdater;
+ Updater* mGroupListUpdater;
+
+ std::string mFilterSubString;
+
+ // The vectors below contain up-to date avatar lists
+ // for the corresponding tabs.
+ // When the user enters a filter, it gets applied
+ // to all the vectors and the result is shown in the tabs.
+ // We don't need to have such a vector for the groups tab
+ // since re-fetching the groups list is always fast.
+ typedef std::vector<LLUUID> uuid_vector_t;
+ uuid_vector_t mNearbyVec;
+ uuid_vector_t mOnlineFriendVec;
+ uuid_vector_t mAllFriendVec;
+ uuid_vector_t mRecentVec;
+};
+
+#endif //LL_LLPANELPEOPLE_H
diff --git a/indra/newview/llpanelpermissions.cpp b/indra/newview/llpanelpermissions.cpp
index 389f06f355..42f9906409 100644
--- a/indra/newview/llpanelpermissions.cpp
+++ b/indra/newview/llpanelpermissions.cpp
@@ -53,73 +53,64 @@
#include "llagent.h"
#include "llstatusbar.h" // for getBalance()
#include "lllineeditor.h"
-#include "llradiogroup.h"
#include "llcombobox.h"
-#include "llfloateravatarinfo.h"
#include "lluiconstants.h"
#include "lldbstrings.h"
-#include "llfloatergroupinfo.h"
#include "llfloatergroups.h"
+#include "llfloaterreg.h"
+#include "llavataractions.h"
#include "llnamebox.h"
#include "llviewercontrol.h"
#include "lluictrlfactory.h"
+#include "llspinctrl.h"
#include "roles_constants.h"
+#include "llgroupactions.h"
///----------------------------------------------------------------------------
/// Class llpanelpermissions
///----------------------------------------------------------------------------
// Default constructor
-LLPanelPermissions::LLPanelPermissions(const std::string& title) :
- LLPanel(title)
+LLPanelPermissions::LLPanelPermissions() :
+ LLPanel()
{
setMouseOpaque(FALSE);
}
BOOL LLPanelPermissions::postBuild()
{
- this->childSetCommitCallback("Object Name",LLPanelPermissions::onCommitName,this);
- this->childSetPrevalidate("Object Name",LLLineEditor::prevalidatePrintableNotPipe);
- this->childSetCommitCallback("Object Description",LLPanelPermissions::onCommitDesc,this);
- this->childSetPrevalidate("Object Description",LLLineEditor::prevalidatePrintableNotPipe);
+ childSetCommitCallback("Object Name",LLPanelPermissions::onCommitName,this);
+ childSetPrevalidate("Object Name",LLLineEditor::prevalidatePrintableNotPipe);
+ childSetCommitCallback("Object Description",LLPanelPermissions::onCommitDesc,this);
+ childSetPrevalidate("Object Description",LLLineEditor::prevalidatePrintableNotPipe);
- this->childSetAction("button owner profile",LLPanelPermissions::onClickOwner,this);
- this->childSetAction("button creator profile",LLPanelPermissions::onClickCreator,this);
+ childSetAction("button owner profile",LLPanelPermissions::onClickOwner,this);
+ childSetAction("button creator profile",LLPanelPermissions::onClickCreator,this);
- this->childSetAction("button set group",LLPanelPermissions::onClickGroup,this);
+ getChild<LLUICtrl>("button set group")->setCommitCallback(boost::bind(&LLPanelPermissions::onClickGroup,this));
- this->childSetCommitCallback("checkbox share with group",LLPanelPermissions::onCommitGroupShare,this);
+ childSetCommitCallback("checkbox share with group",LLPanelPermissions::onCommitGroupShare,this);
- this->childSetAction("button deed",LLPanelPermissions::onClickDeedToGroup,this);
+ childSetAction("button deed",LLPanelPermissions::onClickDeedToGroup,this);
- this->childSetCommitCallback("checkbox allow everyone move",LLPanelPermissions::onCommitEveryoneMove,this);
+ childSetCommitCallback("checkbox allow everyone move",LLPanelPermissions::onCommitEveryoneMove,this);
- this->childSetCommitCallback("checkbox allow everyone copy",LLPanelPermissions::onCommitEveryoneCopy,this);
+ childSetCommitCallback("checkbox allow everyone copy",LLPanelPermissions::onCommitEveryoneCopy,this);
- this->childSetCommitCallback("checkbox for sale",LLPanelPermissions::onCommitSaleInfo,this);
+ childSetCommitCallback("checkbox for sale",LLPanelPermissions::onCommitSaleInfo,this);
- this->childSetCommitCallback("Edit Cost",LLPanelPermissions::onCommitSaleInfo,this);
- this->childSetPrevalidate("Edit Cost",LLLineEditor::prevalidateNonNegativeS32);
+ childSetCommitCallback("sale type",LLPanelPermissions::onCommitSaleType,this);
- this->childSetCommitCallback("sale type",LLPanelPermissions::onCommitSaleType,this);
+ childSetCommitCallback("Edit Cost", LLPanelPermissions::onCommitSaleInfo, this);
- this->childSetCommitCallback("checkbox next owner can modify",LLPanelPermissions::onCommitNextOwnerModify,this);
- this->childSetCommitCallback("checkbox next owner can copy",LLPanelPermissions::onCommitNextOwnerCopy,this);
- this->childSetCommitCallback("checkbox next owner can transfer",LLPanelPermissions::onCommitNextOwnerTransfer,this);
- this->childSetCommitCallback("clickaction",LLPanelPermissions::onCommitClickAction,this);
- this->childSetCommitCallback("search_check",LLPanelPermissions::onCommitIncludeInSearch,this);
+ childSetCommitCallback("checkbox next owner can modify",LLPanelPermissions::onCommitNextOwnerModify,this);
+ childSetCommitCallback("checkbox next owner can copy",LLPanelPermissions::onCommitNextOwnerCopy,this);
+ childSetCommitCallback("checkbox next owner can transfer",LLPanelPermissions::onCommitNextOwnerTransfer,this);
+ childSetCommitCallback("clickaction",LLPanelPermissions::onCommitClickAction,this);
+ childSetCommitCallback("search_check",LLPanelPermissions::onCommitIncludeInSearch,this);
- LLTextBox* group_rect_proxy = getChild<LLTextBox>("Group Name Proxy");
- if(group_rect_proxy )
- {
- mLabelGroupName = new LLNameBox("Group Name", group_rect_proxy->getRect());
- addChild(mLabelGroupName);
- }
- else
- {
- mLabelGroupName = NULL;
- }
+ mLabelGroupName = getChild<LLNameBox>("Group Name Proxy");
return TRUE;
}
@@ -137,7 +128,7 @@ void LLPanelPermissions::refresh()
if(BtnDeedToGroup)
{
std::string deedText;
- if (gSavedSettings.getWarning("DeedObject"))
+ if (gWarningSettings.getBOOL("DeedObject"))
{
deedText = getString("text deed continued");
}
@@ -220,12 +211,9 @@ void LLPanelPermissions::refresh()
childSetValue("search_check", FALSE);
childSetEnabled("search_check", false);
- LLRadioGroup* RadioSaleType = getChild<LLRadioGroup>("sale type");
- if(RadioSaleType)
- {
- RadioSaleType->setSelectedIndex(-1);
- RadioSaleType->setEnabled(FALSE);
- }
+ LLComboBox* combo_sale_type = getChild<LLComboBox>("sale type");
+ combo_sale_type->setValue(LLSaleInfo::FS_COPY);
+ combo_sale_type->setEnabled(FALSE);
childSetEnabled("Cost",false);
childSetText("Cost",getString("Cost Default"));
@@ -256,7 +244,7 @@ void LLPanelPermissions::refresh()
BOOL is_perm_modify = (LLSelectMgr::getInstance()->getSelection()->getFirstRootNode()
&& LLSelectMgr::getInstance()->selectGetRootsModify())
|| LLSelectMgr::getInstance()->selectGetModify();
- const LLView* keyboard_focus_view = gFocusMgr.getKeyboardFocus();
+ const LLFocusableElement* keyboard_focus_view = gFocusMgr.getKeyboardFocus();
S32 string_index = 0;
std::string MODIFY_INFO_STRINGS[] =
{
@@ -429,22 +417,22 @@ void LLPanelPermissions::refresh()
childSetText("Cost",getString("Cost Default"));
}
- LLLineEditor *editPrice = getChild<LLLineEditor>("Edit Cost");
- if(keyboard_focus_view != editPrice)
+ LLSpinCtrl *edit_price = getChild<LLSpinCtrl>("Edit Cost");
+ if(!edit_price->hasFocus())
{
// If the sale price is mixed then set the cost to MIXED, otherwise
// set to the actual cost.
if (num_for_sale > 0 && is_for_sale_mixed)
{
- childSetText("Edit Cost",getString("Sale Mixed"));
+ edit_price->setTentative(TRUE);
}
else if (num_for_sale > 0 && is_sale_price_mixed)
{
- childSetText("Edit Cost",getString("Cost Mixed"));
+ edit_price->setTentative(TRUE);
}
else
{
- childSetText("Edit Cost",llformat("%d",individual_sale_price));
+ edit_price->setValue(individual_sale_price);
}
}
// The edit fields are only enabled if you can sell this object
@@ -754,20 +742,17 @@ void LLPanelPermissions::refresh()
BOOL valid_sale_info = LLSelectMgr::getInstance()->selectGetSaleInfo(sale_info);
LLSaleInfo::EForSale sale_type = sale_info.getSaleType();
- LLRadioGroup* RadioSaleType = getChild<LLRadioGroup>("sale type");
- if(RadioSaleType)
+ LLComboBox* combo_sale_type = getChild<LLComboBox>("sale type");
+ if (valid_sale_info)
{
- if (valid_sale_info)
- {
- RadioSaleType->setSelectedIndex((S32)sale_type - 1);
- RadioSaleType->setTentative(FALSE); // unfortunately this doesn't do anything at the moment.
- }
- else
- {
- // default option is sell copy, determined to be safest
- RadioSaleType->setSelectedIndex((S32)LLSaleInfo::FS_COPY - 1);
- RadioSaleType->setTentative(TRUE); // unfortunately this doesn't do anything at the moment.
- }
+ combo_sale_type->setValue(sale_type == LLSaleInfo::FS_NOT ? LLSaleInfo::FS_COPY : sale_type);
+ combo_sale_type->setTentative(FALSE); // unfortunately this doesn't do anything at the moment.
+ }
+ else
+ {
+ // default option is sell copy, determined to be safest
+ combo_sale_type->setValue(LLSaleInfo::FS_COPY);
+ combo_sale_type->setTentative(TRUE); // unfortunately this doesn't do anything at the moment.
}
childSetValue("checkbox for sale", num_for_sale != 0);
@@ -823,7 +808,7 @@ void LLPanelPermissions::onClickCreator(void *data)
{
LLPanelPermissions *self = (LLPanelPermissions *)data;
- LLFloaterAvatarInfo::showFromObject(self->mCreatorID);
+ LLAvatarActions::showProfile(self->mCreatorID);
}
// static
@@ -835,44 +820,43 @@ void LLPanelPermissions::onClickOwner(void *data)
{
LLUUID group_id;
LLSelectMgr::getInstance()->selectGetGroup(group_id);
- LLFloaterGroupInfo::showFromUUID(group_id);
+ LLGroupActions::show(group_id);
}
else
{
- LLFloaterAvatarInfo::showFromObject(self->mOwnerID);
+ LLAvatarActions::showProfile(self->mOwnerID);
}
}
-void LLPanelPermissions::onClickGroup(void* data)
+void LLPanelPermissions::onClickGroup()
{
- LLPanelPermissions* panelp = (LLPanelPermissions*)data;
LLUUID owner_id;
std::string name;
BOOL owners_identical = LLSelectMgr::getInstance()->selectGetOwner(owner_id, name);
- LLFloater* parent_floater = gFloaterView->getParentFloater(panelp);
+ LLFloater* parent_floater = gFloaterView->getParentFloater(this);
if(owners_identical && (owner_id == gAgent.getID()))
{
- LLFloaterGroupPicker* fg;
- fg = LLFloaterGroupPicker::showInstance(LLSD(gAgent.getID()));
- fg->setSelectCallback( cbGroupID, data );
-
- if (parent_floater)
+ LLFloaterGroupPicker* fg = LLFloaterReg::showTypedInstance<LLFloaterGroupPicker>("group_picker", LLSD(gAgent.getID()));
+ if (fg)
{
- LLRect new_rect = gFloaterView->findNeighboringPosition(parent_floater, fg);
- fg->setOrigin(new_rect.mLeft, new_rect.mBottom);
- parent_floater->addDependentFloater(fg);
+ fg->setSelectGroupCallback( boost::bind(&LLPanelPermissions::cbGroupID, this, _1) );
+
+ if (parent_floater)
+ {
+ LLRect new_rect = gFloaterView->findNeighboringPosition(parent_floater, fg);
+ fg->setOrigin(new_rect.mLeft, new_rect.mBottom);
+ parent_floater->addDependentFloater(fg);
+ }
}
}
}
-// static
-void LLPanelPermissions::cbGroupID(LLUUID group_id, void* userdata)
+void LLPanelPermissions::cbGroupID(LLUUID group_id)
{
- LLPanelPermissions* self = (LLPanelPermissions*)userdata;
- if(self->mLabelGroupName)
+ if(mLabelGroupName)
{
- self->mLabelGroupName->setNameID(group_id, TRUE);
+ mLabelGroupName->setNameID(group_id, TRUE);
}
LLSelectMgr::getInstance()->sendGroup(group_id);
}
@@ -1006,44 +990,14 @@ void LLPanelPermissions::setAllSaleInfo()
// Set the sale type if the object(s) are for sale.
if(checkPurchase && checkPurchase->get())
{
- LLRadioGroup* RadioSaleType = getChild<LLRadioGroup>("sale type");
- if(RadioSaleType)
- {
- switch(RadioSaleType->getSelectedIndex())
- {
- case 0:
- sale_type = LLSaleInfo::FS_ORIGINAL;
- break;
- case 1:
- sale_type = LLSaleInfo::FS_COPY;
- break;
- case 2:
- sale_type = LLSaleInfo::FS_CONTENTS;
- break;
- default:
- sale_type = LLSaleInfo::FS_COPY;
- break;
- }
- }
+ sale_type = static_cast<LLSaleInfo::EForSale>(getChild<LLComboBox>("sale type")->getValue().asInteger());
}
S32 price = -1;
- LLLineEditor *editPrice = getChild<LLLineEditor>("Edit Cost");
- if (editPrice)
- {
- // Don't extract the price if it's labeled as MIXED or is empty.
- const std::string& editPriceString = editPrice->getText();
- if (editPriceString != getString("Cost Mixed") && editPriceString != getString("Sale Mixed") &&
- !editPriceString.empty())
- {
- price = atoi(editPriceString.c_str());
- }
- else
- {
- price = DEFAULT_PRICE;
- }
- }
+ LLSpinCtrl *edit_price = getChild<LLSpinCtrl>("Edit Cost");
+ price = (edit_price->getTentative()) ? DEFAULT_PRICE : edit_price->getValue().asInteger();
+
// If somehow an invalid price, turn the sale off.
if (price < 0)
sale_type = LLSaleInfo::FS_NOT;
diff --git a/indra/newview/llpanelpermissions.h b/indra/newview/llpanelpermissions.h
index bb816acd07..481efe178e 100644
--- a/indra/newview/llpanelpermissions.h
+++ b/indra/newview/llpanelpermissions.h
@@ -53,24 +53,22 @@ class LLNameBox;
class LLPanelPermissions : public LLPanel
{
public:
- LLPanelPermissions(const std::string& title);
+ LLPanelPermissions();
virtual ~LLPanelPermissions();
virtual BOOL postBuild();
// MANIPULATORS
void refresh(); // refresh all labels as needed
-// void setPermCheckboxes(U32 mask_on, U32 mask_off,
-// LLCheckBoxCtrl* move, LLCheckboxCtrl* edit,
-// LLCheckBoxCtrl* copy);
+
protected:
// statics
static void onClickClaim(void*);
static void onClickRelease(void*);
static void onClickCreator(void*);
static void onClickOwner(void*);
- static void onClickGroup(void*);
- static void cbGroupID(LLUUID group_id, void* userdata);
+ void onClickGroup();
+ void cbGroupID(LLUUID group_id);
static void onClickDeedToGroup(void*);
static void onCommitPerm(LLUICtrl *ctrl, void *data, U8 field, U32 perm);
@@ -101,10 +99,6 @@ protected:
protected:
LLNameBox* mLabelGroupName; // group name
- //LLTextBox* mBuyerLabel;
- //LLCheckBoxCtrl* mCheckBuyerModify;
- //LLCheckBoxCtrl* mCheckBuyerCopy;
-
LLUUID mCreatorID;
LLUUID mOwnerID;
LLUUID mLastOwnerID;
diff --git a/indra/newview/llpanelpick.cpp b/indra/newview/llpanelpick.cpp
index 43ecd273c2..f7ca54c732 100644
--- a/indra/newview/llpanelpick.cpp
+++ b/indra/newview/llpanelpick.cpp
@@ -35,481 +35,447 @@
// profile.
#include "llviewerprecompiledheaders.h"
-
-#include "llpanelpick.h"
-
-#include "lldir.h"
-#include "llparcel.h"
+#include "llpanel.h"
#include "message.h"
-
#include "llagent.h"
#include "llbutton.h"
-#include "llcheckboxctrl.h"
-#include "llviewercontrol.h"
-#include "lllineeditor.h"
-#include "lltabcontainervertical.h"
-#include "lltextbox.h"
-#include "llviewertexteditor.h"
+#include "llparcel.h"
+#include "llviewerparcelmgr.h"
#include "lltexturectrl.h"
#include "lluiconstants.h"
-#include "llviewergenericmessage.h"
-#include "lluictrlfactory.h"
-#include "llviewerparcelmgr.h"
#include "llworldmap.h"
#include "llfloaterworldmap.h"
-#include "llviewerregion.h"
-#include "llviewerwindow.h"
+#include "llfloaterreg.h"
+#include "llavatarpropertiesprocessor.h"
+#include "llpanelpick.h"
-//static
-std::list<LLPanelPick*> LLPanelPick::sAllPanels;
-
-LLPanelPick::LLPanelPick(BOOL top_pick)
-: LLPanel(std::string("Top Picks Panel")),
- mTopPick(top_pick),
- mPickID(),
- mCreatorID(),
- mParcelID(),
- mDataRequested(FALSE),
- mDataReceived(FALSE),
- mPosGlobal(),
- mSnapshotCtrl(NULL),
- mNameEditor(NULL),
- mDescEditor(NULL),
- mLocationEditor(NULL),
- mTeleportBtn(NULL),
- mMapBtn(NULL),
- //mLandmarkBtn(NULL),
- mSortOrderText(NULL),
- mSortOrderEditor(NULL),
- mEnabledCheck(NULL),
- mSetBtn(NULL)
-{
- sAllPanels.push_back(this);
- std::string pick_def_file;
- if (top_pick)
+#define XML_PANEL_EDIT_PICK "panel_edit_pick.xml"
+#define XML_PANEL_PICK_INFO "panel_pick_info.xml"
+
+#define XML_NAME "pick_name"
+#define XML_DESC "pick_desc"
+#define XML_SNAPSHOT "pick_snapshot"
+#define XML_LOCATION "pick_location"
+
+#define XML_BTN_SAVE "save_changes_btn"
+
+#define SAVE_BTN_LABEL "[WHAT]"
+#define LABEL_PICK = "Pick"
+#define LABEL_CHANGES = "Changes"
+
+
+LLPanelPick::LLPanelPick(BOOL edit_mode/* = FALSE */)
+: LLPanel(), LLAvatarPropertiesObserver(), LLRemoteParcelInfoObserver(),
+ mEditMode(edit_mode),
+ mSnapshotCtrl(NULL),
+ mPickId(LLUUID::null),
+ mCreatorId(LLUUID::null),
+ mDataReceived(FALSE)
+{
+ if (edit_mode)
{
- LLUICtrlFactory::getInstance()->buildPanel(this, "panel_top_pick.xml");
+ LLUICtrlFactory::getInstance()->buildPanel(this, XML_PANEL_EDIT_PICK);
+ LLAvatarPropertiesProcessor::instance().addObserver(gAgentID, this);
}
else
{
- LLUICtrlFactory::getInstance()->buildPanel(this, "panel_avatar_pick.xml");
- }
-}
+ LLUICtrlFactory::getInstance()->buildPanel(this, XML_PANEL_PICK_INFO);
+ }
+}
LLPanelPick::~LLPanelPick()
{
- sAllPanels.remove(this);
+ if (mCreatorId.notNull()) LLAvatarPropertiesProcessor::instance().removeObserver(mCreatorId, this);
}
-
void LLPanelPick::reset()
{
- mPickID.setNull();
- mCreatorID.setNull();
- mParcelID.setNull();
+ setEditMode(FALSE);
+
+ mPickId.setNull();
+ mCreatorId.setNull();
+ mParcelId.setNull();
+
+ setPickName("");
+ setPickDesc("");
+ setPickLocation("");
+ mSnapshotCtrl->setImageAssetID(LLUUID::null);
+
+ //*HACK just setting asset id to NULL not enough to clear
+ //the texture controls, w/o setValid(FALSE) it continues to
+ //draw the previously set image
+ mSnapshotCtrl->setValid(FALSE);
- // Don't request data, this isn't valid
- mDataRequested = TRUE;
mDataReceived = FALSE;
mPosGlobal.clearVec();
- clearCtrls();
+ childSetValue("maturity", "");
}
-
BOOL LLPanelPick::postBuild()
{
- mSnapshotCtrl = getChild<LLTextureCtrl>("snapshot_ctrl");
- mSnapshotCtrl->setCommitCallback(onCommitAny);
- mSnapshotCtrl->setCallbackUserData(this);
+ mSnapshotCtrl = getChild<LLTextureCtrl>(XML_SNAPSHOT);
- mNameEditor = getChild<LLLineEditor>("given_name_editor");
- mNameEditor->setCommitOnFocusLost(TRUE);
- mNameEditor->setCommitCallback(onCommitAny);
- mNameEditor->setCallbackUserData(this);
+ if (mEditMode)
+ {
+ childSetAction("cancel_btn", boost::bind(&LLPanelPick::onClickCancel, this));
+ childSetAction("set_to_curr_location_btn", boost::bind(&LLPanelPick::onClickSet, this));
+ childSetAction(XML_BTN_SAVE, boost::bind(&LLPanelPick::onClickSave, this));
- mDescEditor = getChild<LLTextEditor>("desc_editor");
- mDescEditor->setCommitOnFocusLost(TRUE);
- mDescEditor->setCommitCallback(onCommitAny);
- mDescEditor->setCallbackUserData(this);
- mDescEditor->setTabsToNextField(TRUE);
+ mSnapshotCtrl->setMouseEnterCallback(boost::bind(&LLPanelPick::childSetVisible, this, "edit_icon", true));
+ mSnapshotCtrl->setMouseLeaveCallback(boost::bind(&LLPanelPick::childSetVisible, this, "edit_icon", false));
+ }
+ else
+ {
+ childSetAction("edit_btn", boost::bind(&LLPanelPick::onClickEdit, this));
+ childSetAction("teleport_btn", boost::bind(&LLPanelPick::onClickTeleport, this));
+ childSetAction("show_on_map_btn", boost::bind(&LLPanelPick::onClickMap, this));
- mLocationEditor = getChild<LLLineEditor>("location_editor");
+ if (!mBackCb.empty())
+ {
+ LLButton* button = findChild<LLButton>("back_btn");
+ if (button) button->setClickedCallback(mBackCb);
+ }
+ }
- mSetBtn = getChild<LLButton>( "set_location_btn");
- mSetBtn->setClickedCallback(onClickSet);
- mSetBtn->setCallbackUserData(this);
+ return TRUE;
+}
+
+void LLPanelPick::init(LLUUID creator_id, LLUUID pick_id)
+{
+ mCreatorId = creator_id;
+ mPickId = pick_id;
- mTeleportBtn = getChild<LLButton>( "pick_teleport_btn");
- mTeleportBtn->setClickedCallback(onClickTeleport);
- mTeleportBtn->setCallbackUserData(this);
+ //*TODO consider removing this, already called by setEditMode()
+ updateButtons();
- mMapBtn = getChild<LLButton>( "pick_map_btn");
- mMapBtn->setClickedCallback(onClickMap);
- mMapBtn->setCallbackUserData(this);
+ requestData();
+}
+
+void LLPanelPick::requestData()
+{
+ mDataReceived = FALSE;
+ LLAvatarPropertiesProcessor::instance().addObserver(mCreatorId, this);
+ LLAvatarPropertiesProcessor::instance().sendDataRequest(mCreatorId, APT_PICK_INFO, &mPickId);
+}
- mSortOrderText = getChild<LLTextBox>("sort_order_text");
+void LLPanelPick::init(LLPickData *pick_data)
+{
+ mPickId = pick_data->pick_id;
+ mCreatorId = pick_data->creator_id;
- mSortOrderEditor = getChild<LLLineEditor>("sort_order_editor");
- mSortOrderEditor->setPrevalidate(LLLineEditor::prevalidateInt);
- mSortOrderEditor->setCommitOnFocusLost(TRUE);
- mSortOrderEditor->setCommitCallback(onCommitAny);
- mSortOrderEditor->setCallbackUserData(this);
+ setPickName(pick_data->name);
+ setPickDesc(pick_data->desc);
+ setPickLocation(pick_data->location_text);
+ mSnapshotCtrl->setImageAssetID(pick_data->snapshot_id);
- mEnabledCheck = getChild<LLCheckBoxCtrl>( "enabled_check");
- mEnabledCheck->setCommitCallback(onCommitAny);
- mEnabledCheck->setCallbackUserData(this);
+ //*HACK see reset() where the texture control was set to FALSE
+ mSnapshotCtrl->setValid(TRUE);
- return TRUE;
+ mPosGlobal = pick_data->pos_global;
+ mSimName = pick_data->sim_name;
+ mParcelId = pick_data->parcel_id;
}
-
// Fill in some reasonable defaults for a new pick.
-void LLPanelPick::initNewPick()
+void LLPanelPick::createNewPick()
{
- mPickID.generate();
-
- mCreatorID = gAgent.getID();
-
+ mPickId.generate();
+ mCreatorId = gAgent.getID();
mPosGlobal = gAgent.getPositionGlobal();
// Try to fill in the current parcel
LLParcel* parcel = LLViewerParcelMgr::getInstance()->getAgentParcel();
if (parcel)
{
- mNameEditor->setText(parcel->getName());
- mDescEditor->setText(parcel->getDesc());
+ setPickName(parcel->getName());
+ setPickDesc(parcel->getDesc());
mSnapshotCtrl->setImageAssetID(parcel->getSnapshotID());
}
- // Commit to the database, since we've got "new" values.
- sendPickInfoUpdate();
-}
-
+ sendUpdate();
-void LLPanelPick::setPickID(const LLUUID& pick_id, const LLUUID& creator_id)
-{
- mPickID = pick_id;
- mCreatorID = creator_id;
+ childSetLabelArg(XML_BTN_SAVE, SAVE_BTN_LABEL, std::string("Pick"));
}
-
-// Schedules the panel to request data
-// from the server next time it is drawn.
-void LLPanelPick::markForServerRequest()
+/*virtual*/ void LLPanelPick::processProperties(void* data, EAvatarProcessorType type)
{
- mDataRequested = FALSE;
- mDataReceived = FALSE;
-}
+ if (APT_PICK_INFO != type) return;
+ if (!data) return;
+ LLPickData* pick_data = static_cast<LLPickData *>(data);
+ if (!pick_data) return;
+ if (mPickId != pick_data->pick_id) return;
-std::string LLPanelPick::getPickName()
-{
- return mNameEditor->getText();
+ init(pick_data);
+ mDataReceived = TRUE;
+ LLAvatarPropertiesProcessor::instance().removeObserver(mCreatorId, this);
+
+ if (!mEditMode)
+ {
+ LLRemoteParcelInfoProcessor::getInstance()->addObserver(pick_data->parcel_id, this);
+ LLRemoteParcelInfoProcessor::getInstance()->sendParcelInfoRequest(pick_data->parcel_id);
+ }
}
-void LLPanelPick::sendPickInfoRequest()
+void LLPanelPick::setEditMode( BOOL edit_mode )
{
- // Must ask for a pick based on the creator id because
- // the pick database is distributed to the inventory cluster. JC
- std::vector<std::string> strings;
- strings.push_back( mCreatorID.asString() );
- strings.push_back( mPickID.asString() );
- send_generic_message("pickinforequest", strings);
-
- mDataRequested = TRUE;
-}
+ if (mEditMode == edit_mode) return;
+ mEditMode = edit_mode;
+ // preserve data before killing controls
+ LLUUID snapshot_id = mSnapshotCtrl->getImageAssetID();
+ LLRect old_rect = getRect();
-void LLPanelPick::sendPickInfoUpdate()
-{
- // If we don't have a pick id yet, we'll need to generate one,
- // otherwise we'll keep overwriting pick_id 00000 in the database.
- if (mPickID.isNull())
+ deleteAllChildren();
+
+ if (edit_mode)
{
- mPickID.generate();
+ LLUICtrlFactory::getInstance()->buildPanel(this, XML_PANEL_EDIT_PICK);
+ }
+ else
+ {
+ LLUICtrlFactory::getInstance()->buildPanel(this, XML_PANEL_PICK_INFO);
}
- LLMessageSystem* msg = gMessageSystem;
-
- msg->newMessage("PickInfoUpdate");
- msg->nextBlock("AgentData");
- msg->addUUID("AgentID", gAgent.getID());
- msg->addUUID("SessionID", gAgent.getSessionID());
- msg->nextBlock("Data");
- msg->addUUID("PickID", mPickID);
- msg->addUUID("CreatorID", mCreatorID);
- msg->addBOOL("TopPick", mTopPick);
- // fills in on simulator if null
- msg->addUUID("ParcelID", mParcelID);
- msg->addString("Name", mNameEditor->getText());
- msg->addString("Desc", mDescEditor->getText());
- msg->addUUID("SnapshotID", mSnapshotCtrl->getImageAssetID());
- msg->addVector3d("PosGlobal", mPosGlobal);
-
- // Only top picks have a sort order
- S32 sort_order;
- if (mTopPick)
+ //*NOTE this code is from LLPanelMeProfile.togglePanel()... doubt this is a right way to do things
+ reshape(old_rect.getWidth(), old_rect.getHeight());
+ old_rect.setLeftTopAndSize(0, old_rect.getHeight(), old_rect.getWidth(), old_rect.getHeight());
+ setRect(old_rect);
+
+ // time to restore data
+ setPickName(mName);
+ setPickDesc(mDesc);
+ setPickLocation(mLocation);
+ mSnapshotCtrl->setImageAssetID(snapshot_id);
+
+ updateButtons();
+}
+
+void LLPanelPick::setPickName(std::string name)
+{
+ if (mEditMode)
{
- sort_order = atoi(mSortOrderEditor->getText().c_str());
+ childSetValue(XML_NAME, name);
}
else
{
- sort_order = 0;
+ childSetWrappedText(XML_NAME, name);
}
- msg->addS32("SortOrder", sort_order);
- msg->addBOOL("Enabled", mEnabledCheck->get());
- gAgent.sendReliableMessage();
+
+ //preserving non-wrapped text for info/edit modes switching
+ mName = name;
}
-
-//static
-void LLPanelPick::processPickInfoReply(LLMessageSystem *msg, void **)
+void LLPanelPick::setPickDesc(std::string desc)
{
- // Extract the agent id and verify the message is for this
- // client.
- LLUUID agent_id;
- msg->getUUID("AgentData", "AgentID", agent_id );
- if (agent_id != gAgent.getID())
- {
- llwarns << "Agent ID mismatch in processPickInfoReply"
- << llendl;
- return;
- }
-
- LLUUID pick_id;
- msg->getUUID("Data", "PickID", pick_id);
-
- LLUUID creator_id;
- msg->getUUID("Data", "CreatorID", creator_id);
-
- BOOL top_pick;
- msg->getBOOL("Data", "TopPick", top_pick);
-
- LLUUID parcel_id;
- msg->getUUID("Data", "ParcelID", parcel_id);
-
- std::string name;
- msg->getString("Data", "Name", name);
-
- std::string desc;
- msg->getString("Data", "Desc", desc);
-
- LLUUID snapshot_id;
- msg->getUUID("Data", "SnapshotID", snapshot_id);
-
- // "Location text" is actually the owner name, the original
- // name that owner gave the parcel, and the location.
- std::string location_text;
- msg->getString("Data", "User", location_text);
- location_text.append(", ");
-
- std::string original_name;
- msg->getString("Data", "OriginalName", original_name);
- if (!original_name.empty())
+ if (mEditMode)
{
- location_text.append(original_name);
- location_text.append(", ");
+ childSetValue(XML_DESC, desc);
}
-
- std::string sim_name;
- msg->getString("Data", "SimName", sim_name);
- location_text.append(sim_name);
- location_text.append(" ");
-
- LLVector3d pos_global;
- msg->getVector3d("Data", "PosGlobal", pos_global);
-
- S32 region_x = llround((F32)pos_global.mdV[VX]) % REGION_WIDTH_UNITS;
- S32 region_y = llround((F32)pos_global.mdV[VY]) % REGION_WIDTH_UNITS;
- S32 region_z = llround((F32)pos_global.mdV[VZ]);
-
- location_text.append(llformat("(%d, %d, %d)", region_x, region_y, region_z));
-
- S32 sort_order;
- msg->getS32("Data", "SortOrder", sort_order);
-
- BOOL enabled;
- msg->getBOOL("Data", "Enabled", enabled);
-
- // Look up the panel to fill in
- for (panel_list_t::iterator iter = sAllPanels.begin(); iter != sAllPanels.end(); ++iter)
+ else
{
- LLPanelPick* self = *iter;
- // For top picks, must match pick id
- if (self->mPickID != pick_id)
- {
- continue;
- }
-
- self->mDataReceived = TRUE;
-
- // Found the panel, now fill in the information
- self->mPickID = pick_id;
- self->mCreatorID = creator_id;
- self->mParcelID = parcel_id;
- self->mSimName.assign(sim_name);
- self->mPosGlobal = pos_global;
-
- // Update UI controls
- self->mNameEditor->setText(std::string(name));
- self->mDescEditor->setText(std::string(desc));
- self->mSnapshotCtrl->setImageAssetID(snapshot_id);
- self->mLocationEditor->setText(location_text);
- self->mEnabledCheck->set(enabled);
+ childSetWrappedText(XML_DESC, desc);
+ }
- self->mSortOrderEditor->setText(llformat("%d", sort_order));
- }
+ //preserving non-wrapped text for info/edit modes switching
+ mDesc = desc;
}
-void LLPanelPick::draw()
+void LLPanelPick::setPickLocation(std::string location)
{
- refresh();
+ childSetWrappedText(XML_LOCATION, location);
- LLPanel::draw();
+ //preserving non-wrapped text for info/edit modes switching
+ mLocation = location;
}
-
-void LLPanelPick::refresh()
+std::string LLPanelPick::getPickName()
{
- if (!mDataRequested)
- {
- sendPickInfoRequest();
- }
-
- // Check for god mode
- BOOL godlike = gAgent.isGodlike();
- BOOL is_self = (gAgent.getID() == mCreatorID);
+ return childGetValue(XML_NAME).asString();
+}
- // Set button visibility/enablement appropriately
- if (mTopPick)
- {
- mSnapshotCtrl->setEnabled(godlike);
- mNameEditor->setEnabled(godlike);
- mDescEditor->setEnabled(godlike);
+std::string LLPanelPick::getPickDesc()
+{
+ return childGetValue(XML_DESC).asString();
+}
- mSortOrderText->setVisible(godlike);
+std::string LLPanelPick::getPickLocation()
+{
+ return childGetValue(XML_LOCATION).asString();
+}
- mSortOrderEditor->setVisible(godlike);
- mSortOrderEditor->setEnabled(godlike);
+void LLPanelPick::sendUpdate()
+{
+ LLPickData pick_data;
- mEnabledCheck->setVisible(godlike);
- mEnabledCheck->setEnabled(godlike);
+ // If we don't have a pick id yet, we'll need to generate one,
+ // otherwise we'll keep overwriting pick_id 00000 in the database.
+ if (mPickId.isNull()) mPickId.generate();
+
+ pick_data.agent_id = gAgent.getID();
+ pick_data.session_id = gAgent.getSessionID();
+ pick_data.pick_id = mPickId;
+ pick_data.creator_id = gAgentID;
+
+ //legacy var need to be deleted
+ pick_data.top_pick = FALSE;
+ pick_data.parcel_id = mParcelId;
+ pick_data.name = getPickName();
+ pick_data.desc = getPickDesc();
+ pick_data.snapshot_id = mSnapshotCtrl->getImageAssetID();
+ pick_data.pos_global = mPosGlobal;
+ pick_data.sort_order = 0;
+ pick_data.enabled = TRUE;
- mSetBtn->setVisible(godlike);
- mSetBtn->setEnabled(godlike);
- }
- else
- {
- mSnapshotCtrl->setEnabled(is_self);
- mNameEditor->setEnabled(is_self);
- mDescEditor->setEnabled(is_self);
+ mDataReceived = FALSE;
+ LLAvatarPropertiesProcessor::instance().addObserver(gAgentID, this);
- mSortOrderText->setVisible(FALSE);
+ LLAvatarPropertiesProcessor::instance().sendDataUpdate(&pick_data, APT_PICK_INFO);
+}
- mSortOrderEditor->setVisible(FALSE);
- mSortOrderEditor->setEnabled(FALSE);
- mEnabledCheck->setVisible(FALSE);
- mEnabledCheck->setEnabled(FALSE);
+//-----------------------------------------
+// "PICK INFO" (VIEW MODE) BUTTON HANDLERS
+//-----------------------------------------
- mSetBtn->setVisible(is_self);
- mSetBtn->setEnabled(is_self);
- }
+//static
+void LLPanelPick::onClickEdit()
+{
+ if (mEditMode) return;
+ if (!mDataReceived) return;
+ setEditMode(TRUE);
}
-
-// static
-void LLPanelPick::onClickTeleport(void* data)
+//static
+void LLPanelPick::onClickTeleport()
{
- LLPanelPick* self = (LLPanelPick*)data;
-
- if (!self->mPosGlobal.isExactlyZero())
- {
- gAgent.teleportViaLocation(self->mPosGlobal);
- gFloaterWorldMap->trackLocation(self->mPosGlobal);
- }
+ teleport(mPosGlobal);
}
-
-// static
-void LLPanelPick::onClickMap(void* data)
+//static
+void LLPanelPick::onClickMap()
{
- LLPanelPick* self = (LLPanelPick*)data;
- gFloaterWorldMap->trackLocation(self->mPosGlobal);
- LLFloaterWorldMap::show(NULL, TRUE);
+ showOnMap(mPosGlobal);
}
-// static
-/*
-void LLPanelPick::onClickLandmark(void* data)
+
+//-----------------------------------------
+// "EDIT PICK" (EDIT MODE) BUTTON HANDLERS
+//-----------------------------------------
+
+//static
+void LLPanelPick::onClickCancel()
{
- LLPanelPick* self = (LLPanelPick*)data;
- create_landmark(self->mNameEditor->getText(), "", self->mPosGlobal);
+ if (!mEditMode) return;
+
+ LLUUID pick_id = mPickId;
+ LLUUID creator_id = mCreatorId;
+ reset();
+ init(creator_id, pick_id);
}
-*/
// static
-void LLPanelPick::onClickSet(void* data)
+void LLPanelPick::onClickSet()
{
- LLPanelPick* self = (LLPanelPick*)data;
+ if (!mEditMode) return;
+ if (!mDataReceived) return;
// Save location for later.
- self->mPosGlobal = gAgent.getPositionGlobal();
-
- std::string location_text;
- location_text.assign("(will update after save)");
- location_text.append(", ");
+ mPosGlobal = gAgent.getPositionGlobal();
- S32 region_x = llround((F32)self->mPosGlobal.mdV[VX]) % REGION_WIDTH_UNITS;
- S32 region_y = llround((F32)self->mPosGlobal.mdV[VY]) % REGION_WIDTH_UNITS;
- S32 region_z = llround((F32)self->mPosGlobal.mdV[VZ]);
+ S32 region_x = llround((F32)mPosGlobal.mdV[VX]) % REGION_WIDTH_UNITS;
+ S32 region_y = llround((F32)mPosGlobal.mdV[VY]) % REGION_WIDTH_UNITS;
+ S32 region_z = llround((F32)mPosGlobal.mdV[VZ]);
- location_text.append(self->mSimName);
- location_text.append(llformat(" (%d, %d, %d)", region_x, region_y, region_z));
+ std::string location_text = "(will update after save), ";
+ location_text.append(mSimName);
+ location_text.append(llformat(" (%d, %d, %d)", region_x, region_y, region_z));
- // if sim name in pick is different from current sim name
- // make sure it's clear that all that's being changed
- // is the location and nothing else
- if ( gAgent.getRegion ()->getName () != self->mSimName )
- {
- LLNotifications::instance().add("SetPickLocation");
- };
+ setPickLocation(location_text);
+}
- self->mLocationEditor->setText(location_text);
+// static
+void LLPanelPick::onClickSave()
+{
+ if (!mEditMode) return;
+ if (!mDataReceived) return;
- onCommitAny(NULL, data);
+ sendUpdate();
+ setEditMode(FALSE);
}
-
-// static
-void LLPanelPick::onCommitAny(LLUICtrl* ctrl, void* data)
+void LLPanelPick::updateButtons()
{
- LLPanelPick* self = (LLPanelPick*)data;
- // have we received up to date data for this pick?
- if (self->mDataReceived)
+ // on Pick Info panel (for non-Agent picks) edit_btn should be invisible
+ if (mEditMode)
{
- self->sendPickInfoUpdate();
-
- // Big hack - assume that top picks are always in a browser,
- // and non-top-picks are always in a tab container.
- /*if (self->mTopPick)
+ childSetLabelArg(XML_BTN_SAVE, SAVE_BTN_LABEL, std::string("Changes"));
+ }
+ else
+ {
+ if (mCreatorId != gAgentID)
{
- LLPanelDirPicks* panel = (LLPanelDirPicks*)self->getParent();
- panel->renamePick(self->mPickID, self->mNameEditor->getText());
+ childSetEnabled("edit_btn", FALSE);
+ childSetVisible("edit_btn", FALSE);
}
- else
- {*/
- LLTabContainer* tab = (LLTabContainer*)self->getParent();
- if (tab)
+ else
{
- if(tab) tab->setCurrentTabName(self->mNameEditor->getText());
+ childSetEnabled("edit_btn", TRUE);
+ childSetVisible("edit_btn", TRUE);
}
- //}
}
}
+
+void LLPanelPick::setExitCallback(commit_callback_t cb)
+{
+ mBackCb = cb;
+ if (!mEditMode)
+ {
+ LLButton* button = findChild<LLButton>("back_btn");
+ if (button) button->setClickedCallback(mBackCb);
+ }
+}
+
+//static
+void LLPanelPick::teleport(const LLVector3d& position)
+{
+ if (!position.isExactlyZero())
+ {
+ gAgent.teleportViaLocation(position);
+ LLFloaterWorldMap::getInstance()->trackLocation(position);
+ }
+}
+
+//static
+void LLPanelPick::showOnMap(const LLVector3d& position)
+{
+ LLFloaterWorldMap::getInstance()->trackLocation(position);
+ LLFloaterReg::showInstance("world_map", "center");
+}
+
+void LLPanelPick::processParcelInfo(const LLParcelData& parcel_data)
+{
+ if (mEditMode) return;
+
+ // HACK: Flag 0x2 == adult region,
+ // Flag 0x1 == mature region, otherwise assume PG
+ std::string rating_icon = "icon_event.tga";
+ if (parcel_data.flags & 0x2)
+ {
+ rating_icon = "icon_event_adult.tga";
+ }
+ else if (parcel_data.flags & 0x1)
+ {
+ rating_icon = "icon_event_mature.tga";
+ }
+
+ childSetValue("maturity", rating_icon);
+
+ //*NOTE we don't removeObserver(...) ourselves cause LLRemoveParcelProcessor does it for us
+}
diff --git a/indra/newview/llpanelpick.h b/indra/newview/llpanelpick.h
index 450fa78801..2cd4706dfe 100644
--- a/indra/newview/llpanelpick.h
+++ b/indra/newview/llpanelpick.h
@@ -38,90 +38,101 @@
#define LL_LLPANELPICK_H
#include "llpanel.h"
-#include "v3dmath.h"
-#include "lluuid.h"
-
-class LLButton;
-class LLCheckBoxCtrl;
-class LLIconCtrl;
-class LLLineEditor;
-class LLTextBox;
-class LLTextEditor;
+#include "llremoteparcelrequest.h"
+
class LLTextureCtrl;
-class LLUICtrl;
class LLMessageSystem;
+class LLAvatarPropertiesObserver;
-class LLPanelPick : public LLPanel
+class LLPanelPick : public LLPanel, public LLAvatarPropertiesObserver, LLRemoteParcelInfoObserver
{
+ LOG_CLASS(LLPanelPick);
public:
- LLPanelPick(BOOL top_pick);
- /*virtual*/ ~LLPanelPick();
+ LLPanelPick(BOOL edit_mode = FALSE);
+ /*virtual*/ ~LLPanelPick();
+ // switches the panel to the VIEW mode and resets controls
void reset();
- /*virtual*/ BOOL postBuild();
+ /*virtual*/ BOOL postBuild();
+
+ // Create a new pick, including creating an id, giving a sane
+ // initial position, etc.
+ void createNewPick();
- /*virtual*/ void draw();
+ //initializes the panel with data of the pick with id = pick_id
+ //owned by the avatar with id = creator_id
+ void init(LLUUID creator_id, LLUUID pick_id);
- /*virtual*/ void refresh();
+ /*virtual*/ void processProperties(void* data, EAvatarProcessorType type);
- // Setup a new pick, including creating an id, giving a sane
- // initial position, etc.
- void initNewPick();
+ // switches the panel to either View or Edit mode
+ void setEditMode(BOOL edit_mode);
- // We need to know the creator id so the database knows which partition
- // to query for the pick data.
- void setPickID(const LLUUID& pick_id, const LLUUID& creator_id);
+ // because this panel works in two modes (edit/view) we are
+ // free from managing two panel for editing and viewing picks and so
+ // are free from controlling switching between them in the parent panel (e.g. Me Profile)
+ // but that causes such a complication that we cannot set a callback for a "Back" button
+ // from the parent panel only once, so we have to preserve that callback
+ // in the pick panel and set it for the back button everytime postBuild() is called.
+ void setExitCallback(commit_callback_t cb);
- // Schedules the panel to request data
- // from the server next time it is drawn.
- void markForServerRequest();
+ static void teleport(const LLVector3d& position);
+ static void showOnMap(const LLVector3d& position);
+
+ //This stuff we got from LLRemoteParcelObserver, in the last two we intentionally do nothing
+ /*virtual*/ void processParcelInfo(const LLParcelData& parcel_data);
+ /*virtual*/ void setParcelID(const LLUUID& parcel_id) {};
+ /*virtual*/ void setErrorStatus(U32 status, const std::string& reason) {};
+
+protected:
+
+ void setPickName(std::string name);
+ void setPickDesc(std::string desc);
+ void setPickLocation(std::string location);
std::string getPickName();
- const LLUUID& getPickID() const { return mPickID; }
- const LLUUID& getPickCreatorID() const { return mCreatorID; }
+ std::string getPickDesc();
+ std::string getPickLocation();
- void sendPickInfoRequest();
- void sendPickInfoUpdate();
+ void sendUpdate();
+ void requestData();
- static void processPickInfoReply(LLMessageSystem* msg, void**);
+ void init(LLPickData *pick_data);
-protected:
- static void onClickTeleport(void* data);
- static void onClickMap(void* data);
- //static void onClickLandmark(void* data);
- static void onClickSet(void* data);
+ void updateButtons();
- static void onCommitAny(LLUICtrl* ctrl, void* data);
+ //-----------------------------------------
+ // "PICK INFO" (VIEW MODE) BUTTON HANDLERS
+ //-----------------------------------------
+ void onClickEdit();
+ void onClickTeleport();
+ void onClickMap();
-protected:
- BOOL mTopPick;
- LLUUID mPickID;
- LLUUID mCreatorID;
- LLUUID mParcelID;
+ //-----------------------------------------
+ // "EDIT PICK" (EDIT MODE) BUTTON HANDLERS
+ //-----------------------------------------
+ void onClickSet();
+ void onClickSave();
+ void onClickCancel();
- // Data will be requested on first draw
- BOOL mDataRequested;
+protected:
+ BOOL mEditMode;
+ LLTextureCtrl* mSnapshotCtrl;
BOOL mDataReceived;
+ LLUUID mPickId;
+ LLUUID mCreatorId;
+ LLVector3d mPosGlobal;
+ LLUUID mParcelId;
std::string mSimName;
- LLVector3d mPosGlobal;
-
- LLTextureCtrl* mSnapshotCtrl;
- LLLineEditor* mNameEditor;
- LLTextEditor* mDescEditor;
- LLLineEditor* mLocationEditor;
-
- LLButton* mTeleportBtn;
- LLButton* mMapBtn;
- LLTextBox* mSortOrderText;
- LLLineEditor* mSortOrderEditor;
- LLCheckBoxCtrl* mEnabledCheck;
- LLButton* mSetBtn;
+ //These strings are used to keep non-wrapped text
+ std::string mName;
+ std::string mDesc;
+ std::string mLocation;
- typedef std::list<LLPanelPick*> panel_list_t;
- static panel_list_t sAllPanels;
+ commit_callback_t mBackCb;
};
#endif // LL_LLPANELPICK_H
diff --git a/indra/newview/llpanelpicks.cpp b/indra/newview/llpanelpicks.cpp
new file mode 100644
index 0000000000..973afae73b
--- /dev/null
+++ b/indra/newview/llpanelpicks.cpp
@@ -0,0 +1,603 @@
+/**
+ * @file llpanelpicks.cpp
+ * @brief LLPanelPicks and related class implementations
+ *
+ * $LicenseInfo:firstyear=2009&license=viewergpl$
+ *
+ * Copyright (c) 2004-2009, Linden Research, Inc.
+ *
+ * Second Life Viewer Source Code
+ * The source code in this file ("Source Code") is provided by Linden Lab
+ * to you under the terms of the GNU General Public License, version 2.0
+ * ("GPL"), unless you have obtained a separate licensing agreement
+ * ("Other License"), formally executed by you and Linden Lab. Terms of
+ * the GPL can be found in doc/GPL-license.txt in this distribution, or
+ * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
+ *
+ * There are special exceptions to the terms and conditions of the GPL as
+ * it is applied to this Source Code. View the full text of the exception
+ * in the file doc/FLOSS-exception.txt in this software distribution, or
+ * online at
+ * http://secondlifegrid.net/programs/open_source/licensing/flossexception
+ *
+ * By copying, modifying or distributing this software, you acknowledge
+ * that you have read and understood your obligations described above,
+ * and agree to abide by those obligations.
+ *
+ * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+ * COMPLETENESS OR PERFORMANCE.
+ * $/LicenseInfo$
+ */
+
+#include "llviewerprecompiledheaders.h"
+
+#include "llagent.h"
+#include "llavatarconstants.h"
+#include "lltexturectrl.h"
+#include "llviewergenericmessage.h" // send_generic_message
+#include "llmenugl.h"
+#include "llviewermenu.h"
+#include "llregistry.h"
+
+#include "llpanelpicks.h"
+#include "llavatarpropertiesprocessor.h"
+#include "llpanelavatar.h"
+#include "llpanelprofile.h"
+#include "llpanelpick.h"
+#include "llscrollcontainer.h"
+
+static const std::string XML_BTN_NEW = "new_btn";
+static const std::string XML_BTN_DELETE = "trash_btn";
+static const std::string XML_BTN_INFO = "info_btn";
+static const std::string XML_BTN_TELEPORT = "teleport_btn";
+static const std::string XML_BTN_SHOW_ON_MAP = "show_on_map_btn";
+
+static const std::string XML_PICKS_LIST = "back_panel";
+
+#define PICK_ITEMS_BETWEEN 5
+
+static LLRegisterPanelClassWrapper<LLPanelPicks> t_panel_picks("panel_picks");
+
+//-----------------------------------------------------------------------------
+// LLPanelPicks
+//-----------------------------------------------------------------------------
+LLPanelPicks::LLPanelPicks()
+: LLPanelProfileTab(),
+ mPopupMenu(NULL),
+ mSelectedPickItem(NULL),
+ mProfilePanel(NULL),
+ mPickPanel(NULL)
+{
+}
+
+LLPanelPicks::~LLPanelPicks()
+{
+ if(getAvatarId().notNull())
+ {
+ LLAvatarPropertiesProcessor::getInstance()->removeObserver(getAvatarId(),this);
+ }
+}
+
+void* LLPanelPicks::create(void* data /* = NULL */)
+{
+ return new LLPanelPicks();
+}
+
+void LLPanelPicks::updateData()
+{
+ LLAvatarPropertiesProcessor::getInstance()->sendDataRequest(getAvatarId(),APT_PICKS);
+}
+
+void LLPanelPicks::processProperties(void* data, EAvatarProcessorType type)
+{
+ if(APT_PICKS == type)
+ {
+ LLAvatarPicks* avatar_picks = static_cast<LLAvatarPicks*>(data);
+ if(avatar_picks && getAvatarId() == avatar_picks->target_id)
+ {
+ std::string name, second_name;
+ gCacheName->getName(getAvatarId(),name,second_name);
+ childSetTextArg("pick_title", "[NAME]",name);
+
+ LLView* picks_list = getPicksList();
+
+ // to restore selection of the same item later
+ LLUUID pick_id_selected(LLUUID::null);
+ if (mSelectedPickItem) pick_id_selected = mSelectedPickItem->getPickId();
+
+ clear();
+
+ //*TODO move it somewhere else?
+ picks_list->setEnabled(FALSE);
+ childSetEnabled(XML_BTN_NEW, false);
+ childSetEnabled(XML_BTN_DELETE, false);
+ childSetEnabled(XML_BTN_INFO, false);
+ childSetEnabled(XML_BTN_TELEPORT,!avatar_picks->picks_list.empty());
+ childSetEnabled(XML_BTN_SHOW_ON_MAP,!avatar_picks->picks_list.empty());
+
+ LLAvatarPicks::picks_list_t::const_iterator it = avatar_picks->picks_list.begin();
+ for(; avatar_picks->picks_list.end() != it; ++it)
+ {
+ LLUUID pick_id = it->first;
+ std::string pick_name = it->second;
+
+ LLPickItem* picture = LLPickItem::create();
+ picture->childSetAction("info_chevron", boost::bind(&LLPanelPicks::onClickInfo, this));
+
+ picks_list->addChild(picture);
+
+ picture->setPickName(pick_name);
+ picture->setPickId(pick_id);
+ picture->setCreatorId(getAvatarId());
+
+ LLAvatarPropertiesProcessor::instance().addObserver(getAvatarId(), picture);
+ picture->update();
+ mPickItemList.push_back(picture);
+ if (pick_id_selected != LLUUID::null &&
+ pick_id == pick_id_selected) setSelectedPickItem(picture);
+ }
+
+ reshapePicksList();
+ LLAvatarPropertiesProcessor::getInstance()->removeObserver(getAvatarId(),this);
+
+ updateButtons();
+ if (!mSelectedPickItem && mPickItemList.size()) setSelectedPickItem(mPickItemList.back());
+ picks_list->setEnabled(TRUE);
+
+ }
+ }
+}
+
+void LLPanelPicks::clear()
+{
+ LLView* scroll = getPicksList();
+ picture_list_t::const_iterator it = mPickItemList.begin();
+ for(; mPickItemList.end() != it; ++it)
+ {
+ scroll->removeChild(*it);
+ delete *it;
+ }
+ mPickItemList.clear();
+ mSelectedPickItem = NULL;
+}
+
+
+LLPickItem* LLPanelPicks::getSelectedPickItem()
+{
+ return mSelectedPickItem;
+}
+
+
+void LLPanelPicks::removePickItem( LLPickItem* pick_item )
+{
+ LLView* scroll = getPicksList();
+ scroll->removeChild(pick_item);
+ mPickItemList.remove(pick_item);
+ if (mPickItemList.size() == 0)
+ {
+ mSelectedPickItem = NULL;
+ }
+ else
+ {
+ setSelectedPickItem(mPickItemList.back());
+ }
+
+ reshapePicksList();
+}
+
+void LLPanelPicks::reshapePicksList()
+{
+ if (!mPickItemList.size()) return;
+ LLView* pickList = getPicksList();
+
+ //We don't need to update size of the 'pick list' before reshaping pick items. Don't need to reshape the pick list
+ S32 height = mPickItemList.size() * (mPickItemList.front()->getRect().getHeight() + PICK_ITEMS_BETWEEN);
+ LLRect rc = pickList->getRect();
+ rc.setLeftTopAndSize(rc.mLeft, rc.mTop, rc.getWidth(), height);
+ pickList->setRect(rc);
+
+ S32 last_bottom = pickList->getRect().getHeight();
+ std::list<LLPickItem*>::const_iterator pick_it, pick_first_it = mPickItemList.begin();
+ for ( pick_it = pick_first_it; pick_it != mPickItemList.end(); ++pick_it)
+ {
+ LLView* const pick = *pick_it;
+ if(pick_it != pick_first_it)
+ {
+ last_bottom -= pick->getRect().getHeight();
+ last_bottom -= PICK_ITEMS_BETWEEN;
+ }
+ reshapePickItem(pick, last_bottom,pickList->getRect().getWidth());
+ }
+}
+
+void LLPanelPicks::reshapePickItem(LLView* const pick_item, const S32 last_bottom, const S32 newWidth)
+{
+ LLRect rc = pick_item->getRect();
+ rc.mBottom = last_bottom - rc.getHeight();
+ rc.mTop = last_bottom;
+ pick_item->setRect(rc);
+ pick_item->reshape(newWidth, rc.getHeight());
+}
+
+LLView* LLPanelPicks::getPicksList() const
+{
+ return getChild<LLView>(XML_PICKS_LIST);
+}
+
+BOOL LLPanelPicks::postBuild()
+{
+ childSetAction(XML_BTN_DELETE, boost::bind(&LLPanelPicks::onClickDelete, this));
+
+ childSetAction("teleport_btn", boost::bind(&LLPanelPicks::onClickTeleport, this));
+ childSetAction("show_on_map_btn", boost::bind(&LLPanelPicks::onClickMap, this));
+
+ childSetAction("info_btn", boost::bind(&LLPanelPicks::onClickInfo, this));
+ childSetAction("new_btn", boost::bind(&LLPanelPicks::onClickNew, this));
+
+ CommitCallbackRegistry::ScopedRegistrar registar;
+ registar.add("Pick.Info", boost::bind(&LLPanelPicks::onClickInfo, this));
+ registar.add("Pick.Edit", boost::bind(&LLPanelPicks::onClickMenuEdit, this));
+ registar.add("Pick.Teleport", boost::bind(&LLPanelPicks::onClickTeleport, this));
+ registar.add("Pick.Map", boost::bind(&LLPanelPicks::onClickMap, this));
+ registar.add("Pick.Delete", boost::bind(&LLPanelPicks::onClickDelete, this));
+ mPopupMenu = LLUICtrlFactory::getInstance()->createFromFile<LLContextMenu>("menu_picks.xml", gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance());
+
+ return TRUE;
+}
+
+void LLPanelPicks::onOpen(const LLSD& key)
+{
+ const LLUUID id(key.asUUID());
+ BOOL self = (gAgent.getID() == id);
+
+ // only agent can edit her picks
+ childSetEnabled("edit_panel", self);
+ childSetVisible("edit_panel", self);
+
+ // Disable buttons when viewing profile for first time
+ if(getAvatarId() != id)
+ {
+ clear();
+
+ childSetEnabled(XML_BTN_INFO,FALSE);
+ childSetEnabled(XML_BTN_TELEPORT,FALSE);
+ childSetEnabled(XML_BTN_SHOW_ON_MAP,FALSE);
+ }
+
+ // and see a special title - set as invisible by default in xml file
+ if (self)
+ {
+ childSetVisible("pick_title", !self);
+ childSetVisible("pick_title_agent", self);
+ }
+
+ LLPanelProfileTab::onOpen(key);
+}
+
+//static
+void LLPanelPicks::onClickDelete()
+{
+ LLPickItem* pick_item = getSelectedPickItem();
+ if (!pick_item) return;
+
+ LLSD args;
+ args["PICK"] = pick_item->getPickName();
+ LLNotifications::instance().add("DeleteAvatarPick", args, LLSD(), boost::bind(&LLPanelPicks::callbackDelete, this, _1, _2));
+}
+
+bool LLPanelPicks::callbackDelete(const LLSD& notification, const LLSD& response)
+{
+ S32 option = LLNotification::getSelectedOption(notification, response);
+
+ LLPickItem* pick_item = getSelectedPickItem();
+
+ if (0 == option)
+ {
+ LLAvatarPropertiesProcessor::instance().sendPickDelete(pick_item->getPickId());
+ removePickItem(pick_item);
+ }
+ updateButtons();
+ return false;
+}
+
+bool LLPanelPicks::callbackTeleport( const LLSD& notification, const LLSD& response )
+{
+ S32 option = LLNotification::getSelectedOption(notification, response);
+
+ if (0 == option)
+ {
+ onClickTeleport();
+ }
+ return false;
+}
+
+//static
+void LLPanelPicks::onClickTeleport()
+{
+ LLPickItem* pick_item = getSelectedPickItem();
+ if (!pick_item) return;
+ LLPanelPick::teleport(pick_item->getPosGlobal());
+}
+
+//static
+void LLPanelPicks::onClickMap()
+{
+ LLPickItem* pick_item = getSelectedPickItem();
+ if (!pick_item) return;
+ LLPanelPick::showOnMap(pick_item->getPosGlobal());
+}
+
+
+BOOL LLPanelPicks::handleRightMouseDown(S32 x, S32 y, MASK mask)
+{
+ if (isMouseInPick(x, y))
+ {
+ if (mPopupMenu)
+ {
+ mPopupMenu->buildDrawLabels();
+ mPopupMenu->updateParent(LLMenuGL::sMenuContainer);
+ ((LLContextMenu*)mPopupMenu)->show(x, y);
+ LLMenuGL::showPopup(this, mPopupMenu, x, y);
+ }
+ return TRUE;
+ }
+ return LLPanel::handleRightMouseDown(x, y, mask);
+}
+
+BOOL LLPanelPicks::handleMouseDown( S32 x, S32 y, MASK mask )
+{
+ isMouseInPick(x, y);
+ return LLPanel::handleMouseDown(x, y, mask);
+}
+
+BOOL LLPanelPicks::handleDoubleClick(S32 x, S32 y, MASK mask)
+{
+ if (isMouseInPick(x, y))
+ {
+ LLPickItem* pick_item = getSelectedPickItem();
+ if (pick_item)
+ {
+ LLSD args;
+ args["PICK"] = pick_item->getPickName();
+ LLNotifications::instance().add("TeleportToPick", args, LLSD(), boost::bind(&LLPanelPicks::callbackTeleport, this, _1, _2));
+ }
+ return TRUE;
+ }
+ return LLPanel::handleDoubleClick(x, y, mask);
+}
+
+void LLPanelPicks::updateButtons()
+{
+ int picks_num = mPickItemList.size();
+ childSetEnabled(XML_BTN_INFO, picks_num > 0);
+
+ if (getAvatarId() == gAgentID)
+ {
+ childSetEnabled(XML_BTN_NEW, picks_num < MAX_AVATAR_PICKS);
+ childSetEnabled(XML_BTN_DELETE, picks_num > 0);
+
+ //*TODO move somewhere this calls
+ // we'd better set them up earlier when a panel was being constructed
+ mPopupMenu->setItemVisible("pick_delete", TRUE);
+ mPopupMenu->setItemVisible("pick_edit", TRUE);
+ mPopupMenu->setItemVisible("pick_separator", TRUE);
+ }
+
+ //*TODO update buttons like Show on Map, Teleport etc.
+
+}
+
+void LLPanelPicks::setSelectedPickItem(LLPickItem* item)
+{
+ if (!item) return;
+ if (mSelectedPickItem == item) return;
+ if (mSelectedPickItem && mSelectedPickItem->isBackgroundVisible())
+ {
+ mSelectedPickItem->setBackgroundVisible(FALSE);
+ }
+ item->setBackgroundVisible(TRUE);
+ mSelectedPickItem = item;
+}
+
+BOOL LLPanelPicks::isMouseInPick( S32 x, S32 y )
+{
+ S32 x_l = x;
+ S32 y_l = y;
+
+ if(!getChild<LLUICtrl>("profile_scroll")->getRect().pointInRect(x, y))
+ {
+ return FALSE;
+ }
+
+ picture_list_t::const_iterator it = mPickItemList.begin();
+ for(; mPickItemList.end() != it; ++it)
+ {
+ localPointToOtherView(x, y, &x_l, &y_l, (*it));
+ if ((*it)->pointInView(x_l, y_l))
+ {
+ setSelectedPickItem(*it);
+ return TRUE;
+ }
+ }
+ return FALSE;
+}
+
+
+void LLPanelPicks::setProfilePanel(LLPanelProfile* profile_panel)
+{
+ mProfilePanel = profile_panel;
+}
+
+
+void LLPanelPicks::buildPickPanel()
+{
+ if (mPickPanel == NULL)
+ {
+ mPickPanel = new LLPanelPick();
+ mPickPanel->setExitCallback(boost::bind(&LLPanelPicks::onClickBack, this));
+ }
+}
+
+void LLPanelPicks::onClickNew()
+{
+ buildPickPanel();
+ mPickPanel->setEditMode(TRUE);
+ mPickPanel->createNewPick();
+ getProfilePanel()->togglePanel(mPickPanel);
+}
+
+void LLPanelPicks::onClickInfo()
+{
+ LLPickItem* pick = getSelectedPickItem();
+ if (!pick) return;
+
+ buildPickPanel();
+ mPickPanel->reset();
+ mPickPanel->init(pick->getCreatorId(), pick->getPickId());
+ getProfilePanel()->togglePanel(mPickPanel);
+}
+
+void LLPanelPicks::onClickBack()
+{
+ getProfilePanel()->togglePanel(mPickPanel);
+}
+
+void LLPanelPicks::onClickMenuEdit()
+{
+ //*TODO, refactor - most of that is similar to onClickInfo
+ LLPickItem* pick = getSelectedPickItem();
+ if (!pick) return;
+
+ buildPickPanel();
+ mPickPanel->reset();
+ mPickPanel->init(pick->getCreatorId(), pick->getPickId());
+ mPickPanel->setEditMode(TRUE);
+ getProfilePanel()->togglePanel(mPickPanel);
+}
+
+inline LLPanelProfile* LLPanelPicks::getProfilePanel()
+{
+ llassert_always(NULL != mProfilePanel);
+ return mProfilePanel;
+}
+
+//-----------------------------------------------------------------------------
+// LLPanelPicks
+//-----------------------------------------------------------------------------
+LLPickItem::LLPickItem()
+: LLPanel()
+, mPickID(LLUUID::null)
+, mCreatorID(LLUUID::null)
+, mParcelID(LLUUID::null)
+, mSnapshotID(LLUUID::null)
+, mNeedData(true)
+{
+ LLUICtrlFactory::getInstance()->buildPanel(this,"panel_pick_list_item.xml");
+}
+
+LLPickItem::~LLPickItem()
+{
+ if (mCreatorID.notNull())
+ {
+ LLAvatarPropertiesProcessor::instance().removeObserver(mCreatorID, this);
+ }
+
+}
+
+LLPickItem* LLPickItem::create()
+{
+ return new LLPickItem();
+}
+
+void LLPickItem::init(LLPickData* pick_data)
+{
+ setPickDesc(pick_data->desc);
+ setSnapshotId(pick_data->snapshot_id);
+ mPosGlobal = pick_data->pos_global;
+ mLocation = pick_data->location_text;
+
+ LLTextureCtrl* picture = getChild<LLTextureCtrl>("picture");
+ picture->setImageAssetID(pick_data->snapshot_id);
+}
+
+void LLPickItem::setPickName(const std::string& name)
+{
+ mPickName = name;
+ childSetValue("picture_name",name);
+
+}
+
+const std::string& LLPickItem::getPickName()
+{
+ return mPickName;
+}
+
+const LLUUID& LLPickItem::getCreatorId()
+{
+ return mCreatorID;
+}
+
+const LLUUID& LLPickItem::getSnapshotId()
+{
+ return mSnapshotID;
+}
+
+void LLPickItem::setPickDesc(const std::string& descr)
+{
+ childSetValue("picture_descr",descr);
+}
+
+void LLPickItem::setPickId(const LLUUID& id)
+{
+ mPickID = id;
+}
+
+const LLUUID& LLPickItem::getPickId()
+{
+ return mPickID;
+}
+
+const LLVector3d& LLPickItem::getPosGlobal()
+{
+ return mPosGlobal;
+}
+
+const std::string& LLPickItem::getLocation()
+{
+ return mLocation;
+}
+
+const std::string LLPickItem::getDescription()
+{
+ return childGetValue("picture_descr").asString();
+}
+
+void LLPickItem::update()
+{
+ mNeedData = true;
+ LLAvatarPropertiesProcessor::instance().sendDataRequest(mCreatorID, APT_PICK_INFO, &mPickID);
+ mNeedData = false;
+}
+
+void LLPickItem::processProperties(void *data, EAvatarProcessorType type)
+{
+ if (APT_PICK_INFO != type) return;
+ if (!data) return;
+
+ LLPickData* pick_data = static_cast<LLPickData *>(data);
+ if (!pick_data) return;
+ if (mPickID != pick_data->pick_id) return;
+
+ init(pick_data);
+ LLAvatarPropertiesProcessor::instance().removeObserver(mCreatorID, this);
+}
+
+void LLPanelPicks::onClose()
+{
+ // Toggle off Pick Info panel if it is visible.
+ if(mPickPanel && mPickPanel->getVisible())
+ {
+ getProfilePanel()->togglePanel(mPickPanel);
+ }
+}
diff --git a/indra/newview/llpanelpicks.h b/indra/newview/llpanelpicks.h
new file mode 100644
index 0000000000..da7bc32ab1
--- /dev/null
+++ b/indra/newview/llpanelpicks.h
@@ -0,0 +1,185 @@
+/**
+ * @file llpanelpicks.h
+ * @brief LLPanelPicks and related class definitions
+ *
+ * $LicenseInfo:firstyear=2009&license=viewergpl$
+ *
+ * Copyright (c) 2004-2009, Linden Research, Inc.
+ *
+ * Second Life Viewer Source Code
+ * The source code in this file ("Source Code") is provided by Linden Lab
+ * to you under the terms of the GNU General Public License, version 2.0
+ * ("GPL"), unless you have obtained a separate licensing agreement
+ * ("Other License"), formally executed by you and Linden Lab. Terms of
+ * the GPL can be found in doc/GPL-license.txt in this distribution, or
+ * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
+ *
+ * There are special exceptions to the terms and conditions of the GPL as
+ * it is applied to this Source Code. View the full text of the exception
+ * in the file doc/FLOSS-exception.txt in this software distribution, or
+ * online at
+ * http://secondlifegrid.net/programs/open_source/licensing/flossexception
+ *
+ * By copying, modifying or distributing this software, you acknowledge
+ * that you have read and understood your obligations described above,
+ * and agree to abide by those obligations.
+ *
+ * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+ * COMPLETENESS OR PERFORMANCE.
+ * $/LicenseInfo$
+ */
+
+#ifndef LL_LLPANELPICKS_H
+#define LL_LLPANELPICKS_H
+
+#include "llpanel.h"
+#include "v3dmath.h"
+#include "lluuid.h"
+#include "llavatarpropertiesprocessor.h"
+#include "llpanelavatar.h"
+#include "llregistry.h"
+
+class LLPanelProfile;
+class LLMessageSystem;
+class LLVector3d;
+class LLPanelProfileTab;
+class LLPanelPick;
+class LLAgent;
+class LLMenuGL;
+class LLPickItem;
+
+
+class LLPanelPicks
+ : public LLPanelProfileTab
+{
+public:
+ LLPanelPicks();
+ ~LLPanelPicks();
+
+ static void* create(void* data);
+
+ /*virtual*/ BOOL postBuild(void);
+
+ /*virtual*/ void onOpen(const LLSD& key);
+
+ void processProperties(void* data, EAvatarProcessorType type);
+
+ void updateData();
+
+ void clear();
+
+ // returns the selected pick item
+ LLPickItem* getSelectedPickItem();
+
+ // removes the specified pick item
+ void removePickItem(LLPickItem* pick_item);
+
+ /*virtual*/ BOOL handleRightMouseDown(S32 x, S32 y, MASK mask);
+ /*virtual*/ BOOL handleMouseDown(S32 x, S32 y, MASK mask);
+ /*virtual*/ BOOL handleDoubleClick(S32 x, S32 y, MASK mask);
+
+ //*NOTE top down approch when panel toggling is done only by
+ // parent panels failed to work (picks related code was in me profile panel)
+ void setProfilePanel(LLPanelProfile* profile_panel);
+
+ /**
+ * Closes LLPanelPick if it is visible.
+ */
+ /*virtual*/ void onClose();
+
+private:
+ void onClickDelete();
+ void onClickTeleport();
+ void onClickMap();
+
+ //------------------------------------------------
+ // Callbacks which require panel toggling
+ //------------------------------------------------
+ void onClickNew();
+ void onClickInfo();
+ void onClickBack();
+ void onClickMenuEdit();
+
+ void buildPickPanel();
+
+ bool callbackDelete(const LLSD& notification, const LLSD& response);
+ bool callbackTeleport(const LLSD& notification, const LLSD& response);
+
+ void reshapePicksList();
+ void reshapePickItem(LLView* const pick_item, const S32 last_bottom, const S32 newWidth);
+ LLView* getPicksList() const;
+ void updateButtons();
+
+ void setSelectedPickItem(LLPickItem* item);
+
+ BOOL isMouseInPick(S32 x, S32 y);
+
+ LLPanelProfile* getProfilePanel();
+
+
+ typedef std::list<LLPickItem*> picture_list_t;
+ picture_list_t mPickItemList;
+
+ LLMenuGL* mPopupMenu;
+ LLPickItem* mSelectedPickItem;
+ LLPanelProfile* mProfilePanel;
+ LLPanelPick* mPickPanel;
+};
+
+class LLPickItem : public LLPanel, public LLAvatarPropertiesObserver
+{
+public:
+
+ LLPickItem();
+
+ static LLPickItem* create();
+
+ void init(LLPickData* pick_data);
+
+ void setPickName(const std::string& name);
+
+ void setPickDesc(const std::string& descr);
+
+ void setPickId(const LLUUID& id);
+
+ void setCreatorId(const LLUUID& id) {mCreatorID = id;};
+
+ void setSnapshotId(const LLUUID& id) {mSnapshotID = id;};
+
+ void setNeedData(bool need){mNeedData = need;};
+
+ const LLUUID& getPickId();
+
+ const std::string& getPickName();
+
+ const LLUUID& getCreatorId();
+
+ const LLUUID& getSnapshotId();
+
+ const LLVector3d& getPosGlobal();
+
+ const std::string& getLocation();
+
+ const std::string getDescription();
+
+ /*virtual*/ void processProperties(void* data, EAvatarProcessorType type);
+
+ void update();
+
+ ~LLPickItem();
+
+protected:
+
+ LLUUID mPickID;
+ LLUUID mCreatorID;
+ LLUUID mParcelID;
+ LLUUID mSnapshotID;
+ LLVector3d mPosGlobal;
+ bool mNeedData;
+
+ std::string mPickName;
+ std::string mLocation;
+};
+
+#endif // LL_LLPANELPICKS_H
diff --git a/indra/newview/llpanelplace.cpp b/indra/newview/llpanelplace.cpp
index 7ca3622634..c6840721a3 100644
--- a/indra/newview/llpanelplace.cpp
+++ b/indra/newview/llpanelplace.cpp
@@ -36,11 +36,10 @@
#include "llviewercontrol.h"
#include "llqueryflags.h"
-#include "message.h"
#include "llui.h"
#include "llsecondlifeurls.h"
-#include "llremoteparcelrequest.h"
#include "llfloater.h"
+#include "llfloaterreg.h"
#include "llagent.h"
#include "llviewerwindow.h"
@@ -49,20 +48,19 @@
#include "lllineeditor.h"
#include "lluiconstants.h"
#include "lltextbox.h"
-#include "llviewertexteditor.h"
+#include "lltexteditor.h"
#include "lltexturectrl.h"
+#include "lltrans.h"
#include "llworldmap.h"
#include "llviewerregion.h"
+#include "llvoavatarself.h"
#include "lluictrlfactory.h"
//#include "llviewermenu.h" // create_landmark()
#include "llweb.h"
#include "llsdutil.h"
-//static
-std::list<LLPanelPlace*> LLPanelPlace::sAllPanels;
-
LLPanelPlace::LLPanelPlace()
-: LLPanel(std::string("Places Panel")),
+: LLPanel(),
mParcelID(),
mRequestedID(),
mRegionID(),
@@ -70,17 +68,16 @@ LLPanelPlace::LLPanelPlace()
mPosRegion(),
mAuctionID(0),
mLandmarkAssetID()
-{
- sAllPanels.push_back(this);
-}
-
+{}
LLPanelPlace::~LLPanelPlace()
{
- sAllPanels.remove(this);
+ if (mParcelID.notNull())
+ {
+ LLRemoteParcelInfoProcessor::getInstance()->removeObserver(mParcelID, this);
+ }
}
-
BOOL LLPanelPlace::postBuild()
{
// Since this is only used in the directory browser, always
@@ -102,20 +99,16 @@ BOOL LLPanelPlace::postBuild()
mLocationDisplay = getChild<LLTextBox>("location_editor");
mTeleportBtn = getChild<LLButton>( "teleport_btn");
- mTeleportBtn->setClickedCallback(onClickTeleport);
- mTeleportBtn->setCallbackUserData(this);
+ mTeleportBtn->setClickedCallback(onClickTeleport, this);
mMapBtn = getChild<LLButton>( "map_btn");
- mMapBtn->setClickedCallback(onClickMap);
- mMapBtn->setCallbackUserData(this);
+ mMapBtn->setClickedCallback(onClickMap, this);
//mLandmarkBtn = getChild<LLButton>( "landmark_btn");
- //mLandmarkBtn->setClickedCallback(onClickLandmark);
- //mLandmarkBtn->setCallbackUserData(this);
+ //mLandmarkBtn->setClickedCallback(onClickLandmark, this);
mAuctionBtn = getChild<LLButton>( "auction_btn");
- mAuctionBtn->setClickedCallback(onClickAuction);
- mAuctionBtn->setCallbackUserData(this);
+ mAuctionBtn->setClickedCallback(onClickAuction, this);
// Default to no auction button. We'll show it if we get an auction id
mAuctionBtn->setVisible(FALSE);
@@ -128,8 +121,11 @@ BOOL LLPanelPlace::postBuild()
void LLPanelPlace::displayItemInfo(const LLInventoryItem* pItem)
{
- mNameEditor->setText(pItem->getName());
- mDescEditor->setText(pItem->getDescription());
+ if (pItem)
+ {
+ mNameEditor->setText(pItem->getName());
+ mDescEditor->setText(pItem->getDescription());
+ }
}
// Use this for search directory clicks, because we are totally
@@ -177,6 +173,7 @@ void LLPanelPlace::resetName(const std::string& name)
}
}
+//virtual
void LLPanelPlace::setParcelID(const LLUUID& parcel_id)
{
mParcelID = parcel_id;
@@ -188,7 +185,6 @@ void LLPanelPlace::setSnapshot(const LLUUID& snapshot_id)
mSnapshotCtrl->setImageAssetID(snapshot_id);
}
-
void LLPanelPlace::setLocationString(const std::string& location)
{
mLocationDisplay->setText(location);
@@ -201,27 +197,22 @@ void LLPanelPlace::setLandTypeString(const std::string& land_type)
void LLPanelPlace::sendParcelInfoRequest()
{
- LLMessageSystem *msg = gMessageSystem;
-
if (mParcelID != mRequestedID)
{
- msg->newMessage("ParcelInfoRequest");
- msg->nextBlockFast(_PREHASH_AgentData);
- msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID() );
- msg->addUUID("SessionID", gAgent.getSessionID());
- msg->nextBlock("Data");
- msg->addUUID("ParcelID", mParcelID);
- gAgent.sendReliableMessage();
+ LLRemoteParcelInfoProcessor::getInstance()->addObserver(mParcelID, this);
+ LLRemoteParcelInfoProcessor::getInstance()->sendParcelInfoRequest(mParcelID);
+
mRequestedID = mParcelID;
}
}
+//virtual
void LLPanelPlace::setErrorStatus(U32 status, const std::string& reason)
{
// We only really handle 404 and 499 errors
std::string error_text;
if(status == 404)
- {
+ {
error_text = getString("server_error_text");
}
else if(status == 499)
@@ -231,140 +222,91 @@ void LLPanelPlace::setErrorStatus(U32 status, const std::string& reason)
mDescEditor->setText(error_text);
}
-//static
-void LLPanelPlace::processParcelInfoReply(LLMessageSystem *msg, void **)
+//virtual
+void LLPanelPlace::processParcelInfo(const LLParcelData& parcel_data)
{
- LLUUID agent_id;
- LLUUID parcel_id;
- LLUUID owner_id;
- std::string name;
- std::string desc;
- S32 actual_area;
- S32 billable_area;
- U8 flags;
- F32 global_x;
- F32 global_y;
- F32 global_z;
- std::string sim_name;
- LLUUID snapshot_id;
- F32 dwell;
- S32 sale_price;
- S32 auction_id;
-
- msg->getUUID("AgentData", "AgentID", agent_id );
- msg->getUUID("Data", "ParcelID", parcel_id);
-
- // look up all panels which have this avatar
- for (panel_list_t::iterator iter = sAllPanels.begin(); iter != sAllPanels.end(); ++iter)
- {
- LLPanelPlace* self = *iter;
- if (self->mParcelID != parcel_id)
- {
- continue;
- }
-
- msg->getUUID ("Data", "OwnerID", owner_id);
- msg->getString ("Data", "Name", name);
- msg->getString ("Data", "Desc", desc);
- msg->getS32 ("Data", "ActualArea", actual_area);
- msg->getS32 ("Data", "BillableArea", billable_area);
- msg->getU8 ("Data", "Flags", flags);
- msg->getF32 ("Data", "GlobalX", global_x);
- msg->getF32 ("Data", "GlobalY", global_y);
- msg->getF32 ("Data", "GlobalZ", global_z);
- msg->getString ("Data", "SimName", sim_name);
- msg->getUUID ("Data", "SnapshotID", snapshot_id);
- msg->getF32 ("Data", "Dwell", dwell);
- msg->getS32 ("Data", "SalePrice", sale_price);
- msg->getS32 ("Data", "AuctionID", auction_id);
-
-
- self->mAuctionID = auction_id;
-
- if(snapshot_id.notNull())
- {
- self->mSnapshotCtrl->setImageAssetID(snapshot_id);
- }
-
- // Only assign the name and description if they are not empty and there is not a
- // value present (passed in from a landmark, e.g.)
+ mAuctionID = parcel_data.auction_id;
- if( !name.empty()
- && self->mNameEditor && self->mNameEditor->getText().empty())
- {
- self->mNameEditor->setText(name);
- }
+ if(parcel_data.snapshot_id.notNull())
+ {
+ mSnapshotCtrl->setImageAssetID(parcel_data.snapshot_id);
+ }
- if( !desc.empty()
- && self->mDescEditor && self->mDescEditor->getText().empty())
- {
- self->mDescEditor->setText(desc);
- }
+ if( !parcel_data.name.empty()
+ && mNameEditor && mNameEditor->getText().empty())
+ {
+ mNameEditor->setText(parcel_data.name);
+ }
- std::string info_text;
- LLUIString traffic = self->getString("traffic_text");
- traffic.setArg("[TRAFFIC]", llformat("%d ", (int)dwell));
- info_text = traffic;
- LLUIString area = self->getString("area_text");
- area.setArg("[AREA]", llformat("%d", actual_area));
- info_text += area;
- if (flags & DFQ_FOR_SALE)
- {
- LLUIString forsale = self->getString("forsale_text");
- forsale.setArg("[PRICE]", llformat("%d", sale_price));
- info_text += forsale;
- }
- if (auction_id != 0)
- {
- LLUIString auction = self->getString("auction_text");
- auction.setArg("[ID]", llformat("%010d ", auction_id));
- info_text += auction;
- }
- if (self->mInfoEditor)
- {
- self->mInfoEditor->setText(info_text);
- }
+ if( !parcel_data.desc.empty()
+ && mDescEditor && mDescEditor->getText().empty())
+ {
+ mDescEditor->setText(parcel_data.desc);
+ }
- // HACK: Flag 0x2 == adult region,
- // Flag 0x1 == mature region, otherwise assume PG
- std::string rating = LLViewerRegion::accessToString(SIM_ACCESS_PG);
- if (flags & 0x2)
- {
- rating = LLViewerRegion::accessToString(SIM_ACCESS_ADULT);
- }
- else if (flags & 0x1)
- {
- rating = LLViewerRegion::accessToString(SIM_ACCESS_MATURE);
- }
+ std::string info_text;
+ LLUIString traffic = getString("traffic_text");
+ traffic.setArg("[TRAFFIC]", llformat("%d ", (int)parcel_data.dwell));
+ info_text = traffic;
+ LLUIString area = getString("area_text");
+ area.setArg("[AREA]", llformat("%d", parcel_data.actual_area));
+ info_text += area;
+ if (parcel_data.flags & DFQ_FOR_SALE)
+ {
+ LLUIString forsale = getString("forsale_text");
+ forsale.setArg("[PRICE]", llformat("%d", parcel_data.sale_price));
+ info_text += forsale;
+ }
+ if (parcel_data.auction_id != 0)
+ {
+ LLUIString auction = getString("auction_text");
+ auction.setArg("[ID]", llformat("%010d ", parcel_data.auction_id));
+ info_text += auction;
+ }
+ if (mInfoEditor)
+ {
+ mInfoEditor->setText(info_text);
+ }
- // Just use given region position for display
- S32 region_x = llround(self->mPosRegion.mV[0]);
- S32 region_y = llround(self->mPosRegion.mV[1]);
- S32 region_z = llround(self->mPosRegion.mV[2]);
+ // HACK: Flag 0x2 == adult region,
+ // Flag 0x1 == mature region, otherwise assume PG
+ std::string rating = LLViewerRegion::accessToString(SIM_ACCESS_PG);
+ if (parcel_data.flags & 0x2)
+ {
+ rating = LLViewerRegion::accessToString(SIM_ACCESS_ADULT);
+ }
+ else if (parcel_data.flags & 0x1)
+ {
+ rating = LLViewerRegion::accessToString(SIM_ACCESS_MATURE);
+ }
- // If the region position is zero, grab position from the global
- if(self->mPosRegion.isExactlyZero())
- {
- region_x = llround(global_x) % REGION_WIDTH_UNITS;
- region_y = llround(global_y) % REGION_WIDTH_UNITS;
- region_z = llround(global_z);
- }
+ // Just use given region position for display
+ S32 region_x = llround(mPosRegion.mV[0]);
+ S32 region_y = llround(mPosRegion.mV[1]);
+ S32 region_z = llround(mPosRegion.mV[2]);
- if(self->mPosGlobal.isExactlyZero())
- {
- self->mPosGlobal.setVec(global_x, global_y, global_z);
- }
+ // If the region position is zero, grab position from the global
+ if(mPosRegion.isExactlyZero())
+ {
+ region_x = llround(parcel_data.global_x) % REGION_WIDTH_UNITS;
+ region_y = llround(parcel_data.global_y) % REGION_WIDTH_UNITS;
+ region_z = llround(parcel_data.global_z);
+ }
- std::string location = llformat("%s %d, %d, %d (%s)",
- sim_name.c_str(), region_x, region_y, region_z, rating.c_str());
- if (self->mLocationDisplay)
- {
- self->mLocationDisplay->setText(location);
- }
+ if(mPosGlobal.isExactlyZero())
+ {
+ mPosGlobal.setVec(parcel_data.global_x, parcel_data.global_y, parcel_data.global_z);
+ }
- BOOL show_auction = (auction_id > 0);
- self->mAuctionBtn->setVisible(show_auction);
+ std::string location = llformat("%s %d, %d, %d (%s)",
+ parcel_data.sim_name.c_str(), region_x, region_y, region_z, rating.c_str());
+ if (mLocationDisplay)
+ {
+ mLocationDisplay->setText(location);
}
+
+ BOOL show_auction = (parcel_data.auction_id > 0);
+ mAuctionBtn->setVisible(show_auction);
}
@@ -390,7 +332,7 @@ void LLPanelPlace::displayParcelInfo(const LLVector3& pos_region,
U64 region_handle = to_region_handle(pos_global);
body["region_handle"] = ll_sd_from_U64(region_handle);
}
- LLHTTPClient::post(url, body, new LLRemoteParcelRequestResponder(this->getHandle()));
+ LLHTTPClient::post(url, body, new LLRemoteParcelRequestResponder(getObserverHandle()));
}
else
{
@@ -400,7 +342,6 @@ void LLPanelPlace::displayParcelInfo(const LLVector3& pos_region,
mSnapshotCtrl->setFallbackImageName("default_land_picture.j2c");
}
-
// static
void LLPanelPlace::onClickTeleport(void* data)
{
@@ -410,20 +351,21 @@ void LLPanelPlace::onClickTeleport(void* data)
LLFloater* parent_floaterp = dynamic_cast<LLFloater*>(parent_viewp);
if (parent_floaterp)
{
- parent_floaterp->close();
+ parent_floaterp->closeFloater();
}
// LLFloater* parent_floaterp = (LLFloater*)self->getParent();
parent_viewp->setVisible(false);
- if(self->mLandmarkAssetID.notNull())
+ LLFloaterWorldMap* worldmap_instance = LLFloaterWorldMap::getInstance();
+ if(self->mLandmarkAssetID.notNull() && worldmap_instance)
{
gAgent.teleportViaLandmark(self->mLandmarkAssetID);
- gFloaterWorldMap->trackLandmark(self->mLandmarkAssetID);
+ worldmap_instance->trackLandmark(self->mLandmarkAssetID);
}
- else if (!self->mPosGlobal.isExactlyZero())
+ else if (!self->mPosGlobal.isExactlyZero() && worldmap_instance)
{
gAgent.teleportViaLocation(self->mPosGlobal);
- gFloaterWorldMap->trackLocation(self->mPosGlobal);
+ worldmap_instance->trackLocation(self->mPosGlobal);
}
}
@@ -431,10 +373,12 @@ void LLPanelPlace::onClickTeleport(void* data)
void LLPanelPlace::onClickMap(void* data)
{
LLPanelPlace* self = (LLPanelPlace*)data;
- if (!self->mPosGlobal.isExactlyZero())
+ LLFloaterWorldMap* worldmap_instance = LLFloaterWorldMap::getInstance();
+
+ if (!self->mPosGlobal.isExactlyZero() && worldmap_instance)
{
- gFloaterWorldMap->trackLocation(self->mPosGlobal);
- LLFloaterWorldMap::show(NULL, TRUE);
+ worldmap_instance->trackLocation(self->mPosGlobal);
+ LLFloaterReg::showInstance("world_map", "center");
}
}
@@ -453,12 +397,12 @@ void LLPanelPlace::onClickLandmark(void* data)
void LLPanelPlace::onClickAuction(void* data)
{
LLPanelPlace* self = (LLPanelPlace*)data;
- LLSD payload;
- payload["auction_id"] = self->mAuctionID;
+ LLSD args;
+ args["AUCTION_ID"] = self->mAuctionID;
- LLNotifications::instance().add("GoToAuctionPage", LLSD(), payload, callbackAuctionWebPage);
+ LLNotifications::instance().add("GoToAuctionPage", args);
}
-
+/*
// static
bool LLPanelPlace::callbackAuctionWebPage(const LLSD& notification, const LLSD& response)
{
@@ -466,8 +410,7 @@ bool LLPanelPlace::callbackAuctionWebPage(const LLSD& notification, const LLSD&
if (0 == option)
{
std::string url;
- S32 auction_id = notification["payload"]["auction_id"].asInteger();
- url = AUCTION_URL + llformat("%010d", auction_id );
+ url = LLNotifications::instance().getGlobalString("AUCTION_URL") + llformat("%010d", response["auction_id"].asInteger());
llinfos << "Loading auction page " << url << llendl;
@@ -475,3 +418,5 @@ bool LLPanelPlace::callbackAuctionWebPage(const LLSD& notification, const LLSD&
}
return false;
}
+*/
+
diff --git a/indra/newview/llpanelplace.h b/indra/newview/llpanelplace.h
index b11290493a..f90a1b0567 100644
--- a/indra/newview/llpanelplace.h
+++ b/indra/newview/llpanelplace.h
@@ -38,6 +38,8 @@
#include "v3dmath.h"
#include "lluuid.h"
+#include "llremoteparcelrequest.h"
+
class LLButton;
class LLTextBox;
class LLLineEditor;
@@ -46,7 +48,7 @@ class LLTextureCtrl;
class LLMessageSystem;
class LLInventoryItem;
-class LLPanelPlace : public LLPanel
+class LLPanelPlace : public LLPanel, LLRemoteParcelInfoObserver
{
public:
LLPanelPlace();
@@ -58,7 +60,7 @@ public:
// Ignore all old location information, useful if you are
// recycling an existing dialog and need to clear it.
- void setParcelID(const LLUUID& parcel_id);
+ /*virtual*/ void setParcelID(const LLUUID& parcel_id);
// Sends a request for data about the given parcel, which will
// only update the location if there is none already available.
@@ -67,7 +69,7 @@ public:
void setSnapshot(const LLUUID& snapshot_id);
void setLocationString(const std::string& location);
void setLandTypeString(const std::string& land_type);
- void setErrorStatus(U32 status, const std::string& reason);
+ /*virtual*/ void setErrorStatus(U32 status, const std::string& reason);
void resetName(const std::string& name);
void sendParcelInfoRequest();
@@ -75,7 +77,7 @@ public:
const LLUUID& landmark_asset_id,
const LLUUID& region_id,
const LLVector3d& pos_global);
- static void processParcelInfoReply(LLMessageSystem* msg, void**);
+ /*virtual*/ void processParcelInfo(const LLParcelData& parcel_data);
LLTextureCtrl *getSnapshotCtrl() const { return mSnapshotCtrl; }
@@ -113,9 +115,6 @@ protected:
LLButton* mMapBtn;
//LLButton* mLandmarkBtn;
LLButton* mAuctionBtn;
-
- typedef std::list<LLPanelPlace*> panel_list_t;
- static panel_list_t sAllPanels;
};
#endif // LL_LLPANELPLACE_H
diff --git a/indra/newview/llpanelplaceinfo.cpp b/indra/newview/llpanelplaceinfo.cpp
new file mode 100644
index 0000000000..a01977c9b5
--- /dev/null
+++ b/indra/newview/llpanelplaceinfo.cpp
@@ -0,0 +1,584 @@
+/**
+ * @file llpanelplaceinfo.cpp
+ * @brief Displays place information in Side Tray.
+ *
+ * $LicenseInfo:firstyear=2009&license=viewergpl$
+ *
+ * Copyright (c) 2004-2009, Linden Research, Inc.
+ *
+ * Second Life Viewer Source Code
+ * The source code in this file ("Source Code") is provided by Linden Lab
+ * to you under the terms of the GNU General Public License, version 2.0
+ * ("GPL"), unless you have obtained a separate licensing agreement
+ * ("Other License"), formally executed by you and Linden Lab. Terms of
+ * the GPL can be found in doc/GPL-license.txt in this distribution, or
+ * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
+ *
+ * There are special exceptions to the terms and conditions of the GPL as
+ * it is applied to this Source Code. View the full text of the exception
+ * in the file doc/FLOSS-exception.txt in this software distribution, or
+ * online at
+ * http://secondlifegrid.net/programs/open_source/licensing/flossexception
+ *
+ * By copying, modifying or distributing this software, you acknowledge
+ * that you have read and understood your obligations described above,
+ * and agree to abide by those obligations.
+ *
+ * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+ * COMPLETENESS OR PERFORMANCE.
+ * $/LicenseInfo$
+ */
+
+#include "llviewerprecompiledheaders.h"
+
+#include "llpanelplaceinfo.h"
+
+#include "roles_constants.h"
+#include "llsdutil.h"
+#include "llsecondlifeurls.h"
+
+#include "llinventory.h"
+#include "llparcel.h"
+
+#include "llqueryflags.h"
+
+#include "llbutton.h"
+#include "lllineeditor.h"
+#include "llscrollcontainer.h"
+#include "lltextbox.h"
+
+#include "llagent.h"
+#include "llavatarpropertiesprocessor.h"
+#include "llfloaterworldmap.h"
+#include "llinventorymodel.h"
+#include "lllandmarkactions.h"
+#include "lltexturectrl.h"
+#include "llviewerinventory.h"
+#include "llviewerparcelmgr.h"
+#include "llviewerregion.h"
+#include "llviewertexteditor.h"
+#include "llworldmap.h"
+
+static LLRegisterPanelClassWrapper<LLPanelPlaceInfo> t_place_info("panel_place_info");
+
+LLPanelPlaceInfo::LLPanelPlaceInfo()
+: LLPanel(),
+ mParcelID(),
+ mRequestedID(),
+ mPosRegion(),
+ mLandmarkID(),
+ mMinHeight(0),
+ mScrollingPanel(NULL),
+ mInfoPanel(NULL),
+ mMediaPanel(NULL)
+{}
+
+LLPanelPlaceInfo::~LLPanelPlaceInfo()
+{
+ if (mParcelID.notNull())
+ {
+ LLRemoteParcelInfoProcessor::getInstance()->removeObserver(mParcelID, this);
+ }
+}
+
+BOOL LLPanelPlaceInfo::postBuild()
+{
+ mTitle = getChild<LLTextBox>("panel_title");
+ mCurrentTitle = mTitle->getText();
+
+ // Since this is only used in the directory browser, always
+ // disable the snapshot control. Otherwise clicking on it will
+ // open a texture picker.
+ mSnapshotCtrl = getChild<LLTextureCtrl>("logo");
+ mSnapshotCtrl->setEnabled(FALSE);
+
+ mRegionName = getChild<LLTextBox>("region_name");
+ mParcelName = getChild<LLTextBox>("parcel_name");
+ mDescEditor = getChild<LLTextEditor>("description");
+ mRating = getChild<LLIconCtrl>("maturity");
+
+ mRegionInfoDrillIn = getChild<LLButton>("region_info_drill_in");
+ mMediaDrillIn = getChild<LLButton>("media_drill_in");
+ mMediaDrillIn->setClickedCallback(boost::bind(&LLPanelPlaceInfo::toggleMediaPanel, this, TRUE));
+
+ mOwner = getChild<LLTextBox>("owner");
+ mCreator = getChild<LLTextBox>("creator");
+ mCreated = getChild<LLTextBox>("created");
+
+ mTitleEditor = getChild<LLLineEditor>("title_editor");
+ mTitleEditor->setCommitCallback(boost::bind(&LLPanelPlaceInfo::onCommitTitleOrNote, this, TITLE));
+
+ mNotesEditor = getChild<LLTextEditor>("notes_editor");
+ mNotesEditor->setCommitCallback(boost::bind(&LLPanelPlaceInfo::onCommitTitleOrNote, this, NOTE));
+ mNotesEditor->setCommitOnFocusLost(true);
+
+ LLScrollContainer* scroll_container = getChild<LLScrollContainer>("scroll_container");
+ scroll_container->setBorderVisible(FALSE);
+ mMinHeight = scroll_container->getScrolledViewRect().getHeight();
+
+ mScrollingPanel = getChild<LLPanel>("scrolling_panel");
+ mInfoPanel = getChild<LLPanel>("info_panel");
+ mMediaPanel = getChild<LLMediaPanel>("media_panel");
+ if (!mMediaPanel)
+ return FALSE;
+
+ return TRUE;
+}
+
+void LLPanelPlaceInfo::displayItemInfo(const LLInventoryItem* pItem)
+{
+ if (!pItem)
+ return;
+
+ mLandmarkID = pItem->getUUID();
+
+ if(!gCacheName)
+ return;
+
+ const LLPermissions& perm = pItem->getPermissions();
+
+ //////////////////
+ // CREATOR NAME //
+ //////////////////
+ if (pItem->getCreatorUUID().notNull())
+ {
+ std::string name;
+ LLUUID creator_id = pItem->getCreatorUUID();
+ if (!gCacheName->getFullName(creator_id, name))
+ {
+ gCacheName->get(creator_id, FALSE,
+ boost::bind(&LLPanelPlaceInfo::nameUpdatedCallback, this, mCreator, _2, _3));
+ }
+ mCreator->setText(name);
+ }
+ else
+ {
+ mCreator->setText(getString("unknown"));
+ }
+
+ ////////////////
+ // OWNER NAME //
+ ////////////////
+ if(perm.isOwned())
+ {
+ std::string name;
+ if (perm.isGroupOwned())
+ {
+ LLUUID group_id = perm.getGroup();
+ if (!gCacheName->getGroupName(group_id, name))
+ {
+ gCacheName->get(group_id, TRUE,
+ boost::bind(&LLPanelPlaceInfo::nameUpdatedCallback, this, mOwner, _2, _3));
+ }
+ }
+ else
+ {
+ LLUUID owner_id = perm.getOwner();
+ if (!gCacheName->getFullName(owner_id, name))
+ {
+ gCacheName->get(owner_id, FALSE,
+ boost::bind(&LLPanelPlaceInfo::nameUpdatedCallback, this, mOwner, _2, _3));
+ }
+ }
+ mOwner->setText(name);
+ }
+ else
+ {
+ mOwner->setText(getString("public"));
+ }
+
+ //////////////////
+ // ACQUIRE DATE //
+ //////////////////
+ time_t time_utc = pItem->getCreationDate();
+ if (0 == time_utc)
+ {
+ mCreated->setText(getString("unknown"));
+ }
+ else
+ {
+ std::string timeStr = getString("acquired_date");
+ LLSD substitution;
+ substitution["datetime"] = (S32) time_utc;
+ LLStringUtil::format (timeStr, substitution);
+ mCreated->setText(timeStr);
+ }
+
+ mTitleEditor->setText(pItem->getName());
+ mNotesEditor->setText(pItem->getDescription());
+}
+
+void LLPanelPlaceInfo::nameUpdatedCallback(
+ LLTextBox* text,
+ const std::string& first,
+ const std::string& last)
+{
+ text->setText(first + " " + last);
+}
+
+void LLPanelPlaceInfo::resetLocation()
+{
+ mParcelID.setNull();
+ mRequestedID.setNull();
+ mLandmarkID.setNull();
+ mPosRegion.clearVec();
+ std::string not_available = getString("not_available");
+ mRating->setValue(not_available);
+ mRegionName->setText(not_available);
+ mParcelName->setText(not_available);
+ mDescEditor->setText(not_available);
+ mCreator->setText(not_available);
+ mOwner->setText(not_available);
+ mCreated->setText(not_available);
+ mTitleEditor->setText(LLStringUtil::null);
+ mNotesEditor->setText(LLStringUtil::null);
+ mSnapshotCtrl->setImageAssetID(LLUUID::null);
+ mSnapshotCtrl->setFallbackImageName("default_land_picture.j2c");
+}
+
+//virtual
+void LLPanelPlaceInfo::setParcelID(const LLUUID& parcel_id)
+{
+ mParcelID = parcel_id;
+ sendParcelInfoRequest();
+}
+
+void LLPanelPlaceInfo::setInfoType(INFO_TYPE type)
+{
+ LLPanel* landmark_info_panel = getChild<LLPanel>("landmark_info_panel");
+ LLPanel* landmark_edit_panel = getChild<LLPanel>("landmark_edit_panel");
+
+ bool is_info_type_agent = type == AGENT;
+ bool is_info_type_landmark = type == LANDMARK;
+
+ landmark_info_panel->setVisible(is_info_type_landmark);
+ landmark_edit_panel->setVisible(is_info_type_landmark || type == CREATE_LANDMARK);
+
+ mRegionInfoDrillIn->setVisible(is_info_type_agent);
+ mMediaDrillIn->setVisible(is_info_type_agent);
+
+ switch(type)
+ {
+ case CREATE_LANDMARK:
+ mCurrentTitle = getString("title_create_landmark");
+ break;
+
+ case AGENT:
+ case PLACE:
+ mCurrentTitle = getString("title_place");
+
+ if (!isMediaPanelVisible())
+ {
+ mTitle->setText(mCurrentTitle);
+ }
+ break;
+
+ // Hide Media Panel if showing information about
+ // a landmark or a teleport history item
+ case LANDMARK:
+ mCurrentTitle = getString("title_landmark");
+ break;
+
+ case TELEPORT_HISTORY:
+ mCurrentTitle = getString("title_place");
+ break;
+ }
+
+ if (type != PLACE)
+ toggleMediaPanel(FALSE);
+}
+
+BOOL LLPanelPlaceInfo::isMediaPanelVisible()
+{
+ if (!mMediaPanel)
+ return FALSE;
+
+ return mMediaPanel->getVisible();
+}
+
+void LLPanelPlaceInfo::toggleMediaPanel(BOOL visible)
+{
+ if (!mMediaPanel)
+ return;
+
+ if (visible)
+ {
+ mTitle->setText(getString("title_media"));
+ }
+ else
+ {
+ mTitle->setText(mCurrentTitle);
+ }
+
+ mInfoPanel->setVisible(!visible);
+ mMediaPanel->setVisible(visible);
+}
+
+void LLPanelPlaceInfo::sendParcelInfoRequest()
+{
+ if (mParcelID != mRequestedID)
+ {
+ LLRemoteParcelInfoProcessor::getInstance()->addObserver(mParcelID, this);
+ LLRemoteParcelInfoProcessor::getInstance()->sendParcelInfoRequest(mParcelID);
+
+ mRequestedID = mParcelID;
+ }
+}
+
+// virtual
+void LLPanelPlaceInfo::setErrorStatus(U32 status, const std::string& reason)
+{
+ // We only really handle 404 and 499 errors
+ std::string error_text;
+ if(status == 404)
+ {
+ error_text = getString("server_error_text");
+ }
+ else if(status == 499)
+ {
+ error_text = getString("server_forbidden_text");
+ }
+ mDescEditor->setText(error_text);
+}
+
+// virtual
+void LLPanelPlaceInfo::processParcelInfo(const LLParcelData& parcel_data)
+{
+ if(parcel_data.snapshot_id.notNull())
+ {
+ mSnapshotCtrl->setImageAssetID(parcel_data.snapshot_id);
+ }
+
+ if( !parcel_data.name.empty())
+ {
+ mParcelName->setText(parcel_data.name);
+ }
+
+ if( !parcel_data.desc.empty())
+ {
+ mDescEditor->setText(parcel_data.desc);
+ }
+
+ // HACK: Flag 0x2 == adult region,
+ // Flag 0x1 == mature region, otherwise assume PG
+ std::string rating = LLViewerRegion::accessToString(SIM_ACCESS_PG);
+ std::string rating_icon = "icon_event.tga";
+ if (parcel_data.flags & 0x2)
+ {
+ rating = LLViewerRegion::accessToString(SIM_ACCESS_ADULT);
+ rating_icon = "icon_event_adult.tga";
+ }
+ else if (parcel_data.flags & 0x1)
+ {
+ rating = LLViewerRegion::accessToString(SIM_ACCESS_MATURE);
+ rating_icon = "icon_event_mature.tga";
+ }
+ mRating->setValue(rating_icon);
+
+ //update for_sale banner, here we should use DFQ_FOR_SALE instead of PF_FOR_SALE
+ //because we deal with remote parcel response format
+ bool isForSale = (parcel_data.flags & DFQ_FOR_SALE)? TRUE : FALSE;
+ getChild<LLIconCtrl>("icon_for_sale")->setVisible(isForSale);
+
+ // Just use given region position for display
+ S32 region_x = llround(mPosRegion.mV[0]);
+ S32 region_y = llround(mPosRegion.mV[1]);
+ S32 region_z = llround(mPosRegion.mV[2]);
+
+ // If the region position is zero, grab position from the global
+ if(mPosRegion.isExactlyZero())
+ {
+ region_x = llround(parcel_data.global_x) % REGION_WIDTH_UNITS;
+ region_y = llround(parcel_data.global_y) % REGION_WIDTH_UNITS;
+ region_z = llround(parcel_data.global_z);
+ }
+
+ std::string name;
+ if (!parcel_data.sim_name.empty())
+ {
+ name = llformat("%s (%d, %d, %d)",
+ parcel_data.sim_name.c_str(), region_x, region_y, region_z);
+ mRegionName->setText(name);
+ }
+
+ if (mCurrentTitle != getString("title_landmark"))
+ {
+ mTitleEditor->setText(parcel_data.name);
+ mNotesEditor->setText(LLStringUtil::null);
+ }
+}
+
+void LLPanelPlaceInfo::displayParcelInfo(const LLVector3& pos_region,
+ const LLUUID& region_id,
+ const LLVector3d& pos_global)
+{
+ mPosRegion = pos_region;
+
+ LLViewerRegion* region = gAgent.getRegion();
+ if (!region)
+ return;
+
+ LLSD body;
+ std::string url = region->getCapability("RemoteParcelRequest");
+ if (!url.empty())
+ {
+ body["location"] = ll_sd_from_vector3(pos_region);
+ if (!region_id.isNull())
+ {
+ body["region_id"] = region_id;
+ }
+ if (!pos_global.isExactlyZero())
+ {
+ U64 region_handle = to_region_handle(pos_global);
+ body["region_handle"] = ll_sd_from_U64(region_handle);
+ }
+ LLHTTPClient::post(url, body, new LLRemoteParcelRequestResponder(getObserverHandle()));
+ }
+ else
+ {
+ mDescEditor->setText(getString("server_update_text"));
+ }
+}
+
+void LLPanelPlaceInfo::displayAgentParcelInfo()
+{
+ mPosRegion = gAgent.getPositionAgent();
+
+ LLViewerRegion* region = gAgent.getRegion();
+ LLParcel* parcel = LLViewerParcelMgr::getInstance()->getAgentParcel();
+ if (!region || !parcel)
+ return;
+
+ LLParcelData parcel_data;
+
+ // HACK: Converting sim access flags to the format
+ // returned by remote parcel response.
+ switch(region->getSimAccess())
+ {
+ case SIM_ACCESS_MATURE:
+ parcel_data.flags = 0x1;
+
+ case SIM_ACCESS_ADULT:
+ parcel_data.flags = 0x2;
+
+ default:
+ parcel_data.flags = 0;
+ }
+
+ // Adding "For Sale" flag in remote parcel response format.
+ if (parcel->getForSale())
+ {
+ parcel_data.flags |= DFQ_FOR_SALE;
+ }
+
+ parcel_data.desc = parcel->getDesc();
+ parcel_data.name = parcel->getName();
+ parcel_data.sim_name = gAgent.getRegion()->getName();
+ parcel_data.snapshot_id = parcel->getSnapshotID();
+ LLVector3d global_pos = gAgent.getPositionGlobal();
+ parcel_data.global_x = global_pos.mdV[0];
+ parcel_data.global_y = global_pos.mdV[1];
+ parcel_data.global_z = global_pos.mdV[2];
+
+
+
+ processParcelInfo(parcel_data);
+}
+
+void LLPanelPlaceInfo::onCommitTitleOrNote(LANDMARK_INFO_TYPE type)
+{
+ LLInventoryItem* item = gInventory.getItem(mLandmarkID);
+ if (!item)
+ return;
+
+ std::string current_value;
+ std::string item_value;
+ if (type == TITLE)
+ {
+ if (mTitleEditor)
+ {
+ current_value = mTitleEditor->getText();
+ item_value = item->getName();
+ }
+ }
+ else
+ {
+ if (mNotesEditor)
+ {
+ current_value = mNotesEditor->getText();
+ item_value = item->getDescription();
+ }
+ }
+
+ if (item_value != current_value &&
+ gAgent.allowOperation(PERM_MODIFY, item->getPermissions(), GP_OBJECT_MANIPULATE))
+ {
+ LLPointer<LLViewerInventoryItem> new_item = new LLViewerInventoryItem(item);
+
+ if (type == TITLE)
+ {
+ new_item->rename(current_value);
+ }
+ else
+ {
+ new_item->setDescription(current_value);
+ }
+
+ new_item->updateServer(FALSE);
+ gInventory.updateItem(new_item);
+ gInventory.notifyObservers();
+ }
+}
+
+void LLPanelPlaceInfo::createLandmark(const LLUUID& folder_id)
+{
+ std::string name = mTitleEditor->getText();
+ std::string desc = mNotesEditor->getText();
+
+ LLStringUtil::trim(name);
+ LLStringUtil::trim(desc);
+
+ // If typed name is empty use the parcel name instead.
+ if (name.empty())
+ {
+ name = mParcelName->getText();
+ }
+
+ LLStringUtil::replaceChar(desc, '\n', ' ');
+ // If no folder chosen use the "Landmarks" folder.
+ LLLandmarkActions::createLandmarkHere(name, desc,
+ folder_id.notNull() ? folder_id : gInventory.findCategoryUUIDForType(LLAssetType::AT_LANDMARK));
+}
+
+void LLPanelPlaceInfo::createPick(const LLVector3d& global_pos)
+{
+ LLPickData pick_data;
+
+ pick_data.agent_id = gAgent.getID();
+ pick_data.session_id = gAgent.getSessionID();
+ pick_data.pick_id = LLUUID::generateNewID();
+ pick_data.creator_id = gAgentID;
+
+ //legacy var need to be deleted
+ pick_data.top_pick = FALSE;
+ pick_data.parcel_id = mParcelID;
+ pick_data.name = mParcelName->getText();
+ pick_data.desc = mDescEditor->getText();
+ pick_data.snapshot_id = mSnapshotCtrl->getImageAssetID();
+ pick_data.pos_global = global_pos;
+ pick_data.sort_order = 0;
+ pick_data.enabled = TRUE;
+
+ LLAvatarPropertiesProcessor::instance().sendDataUpdate(&pick_data, APT_PICK_INFO);
+}
+
+void LLPanelPlaceInfo::reshape(S32 width, S32 height, BOOL called_from_parent)
+{
+ if (mMinHeight > 0 && mScrollingPanel != NULL)
+ {
+ mScrollingPanel->reshape(mScrollingPanel->getRect().getWidth(), mMinHeight);
+ }
+
+ LLView::reshape(width, height, called_from_parent);
+}
diff --git a/indra/newview/llpanelplaceinfo.h b/indra/newview/llpanelplaceinfo.h
new file mode 100644
index 0000000000..77ce2c6619
--- /dev/null
+++ b/indra/newview/llpanelplaceinfo.h
@@ -0,0 +1,150 @@
+/**
+ * @file llpanelplaceinfo.h
+ * @brief Displays place information in Side Tray.
+ *
+ * $LicenseInfo:firstyear=2009&license=viewergpl$
+ *
+ * Copyright (c) 2004-2009, Linden Research, Inc.
+ *
+ * Second Life Viewer Source Code
+ * The source code in this file ("Source Code") is provided by Linden Lab
+ * to you under the terms of the GNU General Public License, version 2.0
+ * ("GPL"), unless you have obtained a separate licensing agreement
+ * ("Other License"), formally executed by you and Linden Lab. Terms of
+ * the GPL can be found in doc/GPL-license.txt in this distribution, or
+ * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
+ *
+ * There are special exceptions to the terms and conditions of the GPL as
+ * it is applied to this Source Code. View the full text of the exception
+ * in the file doc/FLOSS-exception.txt in this software distribution, or
+ * online at
+ * http://secondlifegrid.net/programs/open_source/licensing/flossexception
+ *
+ * By copying, modifying or distributing this software, you acknowledge
+ * that you have read and understood your obligations described above,
+ * and agree to abide by those obligations.
+ *
+ * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+ * COMPLETENESS OR PERFORMANCE.
+ * $/LicenseInfo$
+ */
+
+#ifndef LL_LLPANELPLACEINFO_H
+#define LL_LLPANELPLACEINFO_H
+
+#include "llpanel.h"
+
+#include "v3dmath.h"
+#include "lluuid.h"
+
+#include "lliconctrl.h"
+
+#include "llpanelmedia.h"
+#include "llremoteparcelrequest.h"
+
+class LLButton;
+class LLInventoryItem;
+class LLLineEditor;
+class LLTextBox;
+class LLTextEditor;
+class LLTextureCtrl;
+
+class LLPanelPlaceInfo : public LLPanel, LLRemoteParcelInfoObserver
+{
+public:
+ enum INFO_TYPE
+ {
+ AGENT,
+ CREATE_LANDMARK,
+ LANDMARK,
+ PLACE,
+ TELEPORT_HISTORY
+ };
+
+ LLPanelPlaceInfo();
+ /*virtual*/ ~LLPanelPlaceInfo();
+
+ /*virtual*/ BOOL postBuild();
+
+ // Ignore all old location information, useful if you are
+ // recycling an existing dialog and need to clear it.
+ void resetLocation();
+
+ // Sends a request for data about the given parcel, which will
+ // only update the location if there is none already available.
+ /*virtual*/ void setParcelID(const LLUUID& parcel_id);
+
+ // Depending on how the panel was triggered
+ // (from landmark or current location, or other)
+ // sets a corresponding title and contents.
+ void setInfoType(INFO_TYPE type);
+
+ // Create a landmark for the current location
+ // in a folder specified by folder_id.
+ void createLandmark(const LLUUID& folder_id);
+
+ // Create a pick for the location specified
+ // by global_pos.
+ void createPick(const LLVector3d& global_pos);
+
+ BOOL isMediaPanelVisible();
+ void toggleMediaPanel(BOOL visible);
+ void displayItemInfo(const LLInventoryItem* pItem);
+ /*virtual*/ void setErrorStatus(U32 status, const std::string& reason);
+
+ void sendParcelInfoRequest();
+
+ // Displays information about a remote parcel.
+ // Sends a request to the server.
+ void displayParcelInfo(const LLVector3& pos_region,
+ const LLUUID& region_id,
+ const LLVector3d& pos_global);
+
+ // Displays information about the parcel the agent is currently on
+ // without sending a request to the server.
+ void displayAgentParcelInfo();
+
+ void nameUpdatedCallback(LLTextBox* text,
+ const std::string& first,
+ const std::string& last);
+
+ /*virtual*/ void processParcelInfo(const LLParcelData& parcel_data);
+ /*virtual*/ void reshape(S32 width, S32 height, BOOL called_from_parent = TRUE);
+
+private:
+ enum LANDMARK_INFO_TYPE
+ {
+ TITLE,
+ NOTE
+ };
+
+ void onCommitTitleOrNote(LANDMARK_INFO_TYPE type);
+
+ LLUUID mParcelID;
+ LLUUID mRequestedID;
+ LLUUID mLandmarkID;
+ LLVector3 mPosRegion;
+ std::string mCurrentTitle;
+ S32 mMinHeight;
+
+ LLTextBox* mTitle;
+ LLTextureCtrl* mSnapshotCtrl;
+ LLTextBox* mRegionName;
+ LLTextBox* mParcelName;
+ LLTextEditor* mDescEditor;
+ LLIconCtrl* mRating;
+ LLButton* mRegionInfoDrillIn;
+ LLButton* mMediaDrillIn;
+ LLTextBox* mOwner;
+ LLTextBox* mCreator;
+ LLTextBox* mCreated;
+ LLLineEditor* mTitleEditor;
+ LLTextEditor* mNotesEditor;
+ LLTextBox* mLocationEditor;
+ LLPanel* mScrollingPanel;
+ LLPanel* mInfoPanel;
+ LLMediaPanel* mMediaPanel;
+};
+
+#endif // LL_LLPANELPLACEINFO_H
diff --git a/indra/newview/llpanelplaces.cpp b/indra/newview/llpanelplaces.cpp
new file mode 100644
index 0000000000..7cb9e61e72
--- /dev/null
+++ b/indra/newview/llpanelplaces.cpp
@@ -0,0 +1,827 @@
+/**
+ * @file llpanelplaces.cpp
+ * @brief Side Bar "Places" panel
+ *
+ * $LicenseInfo:firstyear=2009&license=viewergpl$
+ *
+ * Copyright (c) 2004-2009, Linden Research, Inc.
+ *
+ * Second Life Viewer Source Code
+ * The source code in this file ("Source Code") is provided by Linden Lab
+ * to you under the terms of the GNU General Public License, version 2.0
+ * ("GPL"), unless you have obtained a separate licensing agreement
+ * ("Other License"), formally executed by you and Linden Lab. Terms of
+ * the GPL can be found in doc/GPL-license.txt in this distribution, or
+ * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
+ *
+ * There are special exceptions to the terms and conditions of the GPL as
+ * it is applied to this Source Code. View the full text of the exception
+ * in the file doc/FLOSS-exception.txt in this software distribution, or
+ * online at http://secondlifegrid.net/programs/open_source/licensing/flossexception
+ *
+ * By copying, modifying or distributing this software, you acknowledge
+ * that you have read and understood your obligations described above,
+ * and agree to abide by those obligations.
+ *
+ * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+ * COMPLETENESS OR PERFORMANCE.
+ * $/LicenseInfo$
+ */
+
+#include "llviewerprecompiledheaders.h"
+
+#include "llassettype.h"
+#include "llwindow.h"
+
+#include "lllandmark.h"
+
+#include "llfloaterreg.h"
+#include "llnotifications.h"
+#include "llfiltereditor.h"
+#include "lltabcontainer.h"
+#include "lltrans.h"
+#include "lluictrlfactory.h"
+
+#include "llagent.h"
+#include "lllandmarkactions.h"
+#include "lllandmarklist.h"
+#include "llfloaterworldmap.h"
+#include "llpanelplaces.h"
+#include "llpanellandmarks.h"
+#include "llpanelteleporthistory.h"
+#include "llsidetray.h"
+#include "lltoggleablemenu.h"
+#include "llviewerinventory.h"
+#include "llviewermenu.h"
+#include "llviewerparcelmgr.h"
+#include "llviewerregion.h"
+
+static const S32 LANDMARK_FOLDERS_MENU_WIDTH = 250;
+static const std::string AGENT_INFO_TYPE = "agent";
+static const std::string CREATE_LANDMARK_INFO_TYPE = "create_landmark";
+static const std::string LANDMARK_INFO_TYPE = "landmark";
+static const std::string REMOTE_PLACE_INFO_TYPE = "remote_place";
+static const std::string TELEPORT_HISTORY_INFO_TYPE = "teleport_history";
+
+// Helper functions
+static bool cmp_folders(const folder_pair_t& left, const folder_pair_t& right);
+static std::string getFullFolderName(const LLViewerInventoryCategory* cat);
+static void collectLandmarkFolders(LLInventoryModel::cat_array_t& cats);
+static const LLVector3 get_pos_local_from_global(const LLVector3d &pos_global);
+static void onSLURLBuilt(std::string& slurl);
+
+static LLRegisterPanelClassWrapper<LLPanelPlaces> t_places("panel_places");
+
+LLPanelPlaces::LLPanelPlaces()
+ : LLPanel(),
+ mFilterSubString(LLStringUtil::null),
+ mActivePanel(NULL),
+ mFilterEditor(NULL),
+ mPlaceInfo(NULL),
+ mItem(NULL),
+ mPlaceMenu(NULL),
+ mLandmarkMenu(NULL),
+ mLandmarkFoldersMenuHandle(),
+ mPosGlobal()
+{
+ gInventory.addObserver(this);
+
+ LLViewerParcelMgr::getInstance()->addAgentParcelChangedCallback(
+ boost::bind(&LLPanelPlaces::onAgentParcelChange, this));
+
+ //LLUICtrlFactory::getInstance()->buildPanel(this, "panel_places.xml"); // Called from LLRegisterPanelClass::defaultPanelClassBuilder()
+}
+
+LLPanelPlaces::~LLPanelPlaces()
+{
+ if (gInventory.containsObserver(this))
+ gInventory.removeObserver(this);
+
+ LLView::deleteViewByHandle(mLandmarkFoldersMenuHandle);
+}
+
+BOOL LLPanelPlaces::postBuild()
+{
+ mCreateLandmarkBtn = getChild<LLButton>("create_landmark_btn");
+ mCreateLandmarkBtn->setClickedCallback(boost::bind(&LLPanelPlaces::onCreateLandmarkButtonClicked, this, LLUUID()));
+
+ mFolderMenuBtn = getChild<LLButton>("folder_menu_btn");
+ mFolderMenuBtn->setClickedCallback(boost::bind(&LLPanelPlaces::showLandmarkFoldersMenu, this));
+
+ mTeleportBtn = getChild<LLButton>("teleport_btn");
+ mTeleportBtn->setClickedCallback(boost::bind(&LLPanelPlaces::onTeleportButtonClicked, this));
+
+ mShowOnMapBtn = getChild<LLButton>("map_btn");
+ mShowOnMapBtn->setClickedCallback(boost::bind(&LLPanelPlaces::onShowOnMapButtonClicked, this));
+
+ mShareBtn = getChild<LLButton>("share_btn");
+ //mShareBtn->setClickedCallback(boost::bind(&LLPanelPlaces::onShareButtonClicked, this));
+
+ mOverflowBtn = getChild<LLButton>("overflow_btn");
+
+ // *TODO: Assign the action to an appropriate event.
+ //mOverflowBtn->setClickedCallback(boost::bind(&LLPanelPlaces::toggleMediaPanel, this));
+ mOverflowBtn->setClickedCallback(boost::bind(&LLPanelPlaces::onOverflowButtonClicked, this));
+
+ LLUICtrl::CommitCallbackRegistry::ScopedRegistrar registrar;
+ registrar.add("Places.OverflowMenu.Action", boost::bind(&LLPanelPlaces::onOverflowMenuItemClicked, this, _2));
+
+ mPlaceMenu = LLUICtrlFactory::getInstance()->createFromFile<LLToggleableMenu>("menu_place.xml", gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance());
+ if (!mPlaceMenu)
+ {
+ llwarns << "Error loading Place menu" << llendl;
+ }
+
+ mLandmarkMenu = LLUICtrlFactory::getInstance()->createFromFile<LLToggleableMenu>("menu_landmark.xml", gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance());
+ if (!mLandmarkMenu)
+ {
+ llwarns << "Error loading Landmark menu" << llendl;
+ }
+
+ mTabContainer = getChild<LLTabContainer>("Places Tabs");
+ if (mTabContainer)
+ {
+ mTabContainer->setCommitCallback(boost::bind(&LLPanelPlaces::onTabSelected, this));
+ }
+
+ mFilterEditor = getChild<LLFilterEditor>("Filter");
+ if (mFilterEditor)
+ {
+ mFilterEditor->setCommitCallback(boost::bind(&LLPanelPlaces::onFilterEdit, this, _2));
+ }
+
+ mPlaceInfo = getChild<LLPanelPlaceInfo>("panel_place_info");
+
+ LLButton* back_btn = mPlaceInfo->getChild<LLButton>("back_btn");
+ back_btn->setClickedCallback(boost::bind(&LLPanelPlaces::onBackButtonClicked, this));
+
+ // *TODO: Assign the action to an appropriate event.
+ mOverflowBtn->setClickedCallback(boost::bind(&LLPanelPlaces::toggleMediaPanel, this));
+
+ return TRUE;
+}
+
+void LLPanelPlaces::onOpen(const LLSD& key)
+{
+ mFilterEditor->clear();
+ onFilterEdit("");
+
+ if(mPlaceInfo == NULL || key.size() == 0)
+ return;
+
+ mPlaceInfoType = key["type"].asString();
+ mPosGlobal.setZero();
+ togglePlaceInfoPanel(TRUE);
+ updateVerbs();
+
+ if (mPlaceInfoType == AGENT_INFO_TYPE)
+ {
+ mPlaceInfo->setInfoType(LLPanelPlaceInfo::AGENT);
+ mPlaceInfo->displayAgentParcelInfo();
+
+ mPosGlobal = gAgent.getPositionGlobal();
+ }
+ else if (mPlaceInfoType == CREATE_LANDMARK_INFO_TYPE)
+ {
+ mPlaceInfo->setInfoType(LLPanelPlaceInfo::CREATE_LANDMARK);
+ mPlaceInfo->displayAgentParcelInfo();
+
+ mPosGlobal = gAgent.getPositionGlobal();
+ }
+ else if (mPlaceInfoType == LANDMARK_INFO_TYPE)
+ {
+ LLUUID item_uuid = key["id"].asUUID();
+ LLInventoryItem* item = gInventory.getItem(item_uuid);
+ if (!item)
+ return;
+
+ setItem(item);
+ }
+ else if (mPlaceInfoType == REMOTE_PLACE_INFO_TYPE)
+ {
+ if (mPlaceInfo->isMediaPanelVisible())
+ {
+ toggleMediaPanel();
+ }
+
+ mPosGlobal = LLVector3d(key["x"].asReal(),
+ key["y"].asReal(),
+ key["z"].asReal());
+
+ mPlaceInfo->setInfoType(LLPanelPlaceInfo::PLACE);
+ mPlaceInfo->displayParcelInfo(get_pos_local_from_global(mPosGlobal),
+ LLUUID(),
+ mPosGlobal);
+ }
+ else if (mPlaceInfoType == TELEPORT_HISTORY_INFO_TYPE)
+ {
+ S32 index = key["id"].asInteger();
+
+ const LLTeleportHistory::slurl_list_t& hist_items =
+ LLTeleportHistory::getInstance()->getItems();
+
+ mPosGlobal = hist_items[index].mGlobalPos;
+
+ mPlaceInfo->setInfoType(LLPanelPlaceInfo::TELEPORT_HISTORY);
+ mPlaceInfo->displayParcelInfo(get_pos_local_from_global(mPosGlobal),
+ hist_items[index].mRegionID,
+ mPosGlobal);
+ }
+
+
+}
+
+void LLPanelPlaces::setItem(LLInventoryItem* item)
+{
+ if (!mPlaceInfo)
+ return;
+
+ mItem = item;
+
+ // If the item is a link get a linked item
+ if (mItem->getType() == LLAssetType::AT_LINK)
+ {
+ mItem = gInventory.getItem(mItem->getAssetUUID());
+ if (mItem.isNull())
+ return;
+ }
+
+ mPlaceInfo->setInfoType(LLPanelPlaceInfo::LANDMARK);
+ mPlaceInfo->displayItemInfo(mItem);
+
+ LLLandmark* lm = gLandmarkList.getAsset(mItem->getAssetUUID(),
+ boost::bind(&LLPanelPlaces::onLandmarkLoaded, this, _1));
+ if (lm)
+ {
+ onLandmarkLoaded(lm);
+ }
+}
+
+void LLPanelPlaces::onLandmarkLoaded(LLLandmark* landmark)
+{
+ if (!mPlaceInfo)
+ return;
+
+ LLUUID region_id;
+ landmark->getRegionID(region_id);
+ landmark->getGlobalPos(mPosGlobal);
+ mPlaceInfo->displayParcelInfo(landmark->getRegionPos(),
+ region_id,
+ mPosGlobal);
+}
+
+void LLPanelPlaces::onFilterEdit(const std::string& search_string)
+{
+ if (mFilterSubString != search_string)
+ {
+ mFilterSubString = search_string;
+
+ // Searches are case-insensitive
+ LLStringUtil::toUpper(mFilterSubString);
+ LLStringUtil::trimHead(mFilterSubString);
+
+ mActivePanel->onSearchEdit(mFilterSubString);
+ }
+}
+
+void LLPanelPlaces::onTabSelected()
+{
+ mActivePanel = dynamic_cast<LLPanelPlacesTab*>(mTabContainer->getCurrentPanel());
+ if (!mActivePanel)
+ return;
+
+ onFilterEdit(mFilterSubString);
+ mActivePanel->updateVerbs();
+}
+
+/*
+void LLPanelPlaces::onShareButtonClicked()
+{
+ // TODO: Launch the "Things" Share wizard
+}
+*/
+
+void LLPanelPlaces::onTeleportButtonClicked()
+{
+ if (!mPlaceInfo)
+ return;
+
+ if (mPlaceInfo->getVisible())
+ {
+ if (mPlaceInfoType == LANDMARK_INFO_TYPE)
+ {
+ LLSD payload;
+ payload["asset_id"] = mItem->getAssetUUID();
+ LLNotifications::instance().add("TeleportFromLandmark", LLSD(), payload);
+ }
+ else if (mPlaceInfoType == AGENT_INFO_TYPE ||
+ mPlaceInfoType == REMOTE_PLACE_INFO_TYPE ||
+ mPlaceInfoType == TELEPORT_HISTORY_INFO_TYPE)
+ {
+ LLFloaterWorldMap* worldmap_instance = LLFloaterWorldMap::getInstance();
+ if (!mPosGlobal.isExactlyZero() && worldmap_instance)
+ {
+ gAgent.teleportViaLocation(mPosGlobal);
+ worldmap_instance->trackLocation(mPosGlobal);
+ }
+ }
+ }
+ else
+ {
+ mActivePanel->onTeleport();
+ }
+}
+
+void LLPanelPlaces::onShowOnMapButtonClicked()
+{
+ if (!mPlaceInfo)
+ return;
+
+ if (mPlaceInfo->getVisible())
+ {
+ LLFloaterWorldMap* worldmap_instance = LLFloaterWorldMap::getInstance();
+ if(!worldmap_instance)
+ return;
+
+ if (mPlaceInfoType == AGENT_INFO_TYPE ||
+ mPlaceInfoType == CREATE_LANDMARK_INFO_TYPE ||
+ mPlaceInfoType == REMOTE_PLACE_INFO_TYPE ||
+ mPlaceInfoType == TELEPORT_HISTORY_INFO_TYPE)
+ {
+ if (!mPosGlobal.isExactlyZero())
+ {
+ worldmap_instance->trackLocation(mPosGlobal);
+ LLFloaterReg::showInstance("world_map", "center");
+ }
+ }
+ else if (mPlaceInfoType == LANDMARK_INFO_TYPE)
+ {
+ LLLandmark* landmark = gLandmarkList.getAsset(mItem->getAssetUUID());
+ if (!landmark)
+ return;
+
+ LLVector3d landmark_global_pos;
+ if (!landmark->getGlobalPos(landmark_global_pos))
+ return;
+
+ if (!landmark_global_pos.isExactlyZero())
+ {
+ worldmap_instance->trackLocation(landmark_global_pos);
+ LLFloaterReg::showInstance("world_map", "center");
+ }
+ }
+ }
+ else
+ {
+ mActivePanel->onShowOnMap();
+ }
+}
+
+void LLPanelPlaces::onOverflowButtonClicked()
+{
+ LLToggleableMenu* menu;
+
+ bool is_agent_place_info_visible = mPlaceInfoType == AGENT_INFO_TYPE;
+
+ if ((is_agent_place_info_visible ||
+ mPlaceInfoType == "remote_place" ||
+ mPlaceInfoType == "teleport_history") && mPlaceMenu != NULL)
+ {
+ menu = mPlaceMenu;
+
+ // Enable adding a landmark only for agent current parcel and if
+ // there is no landmark already pointing to that parcel in agent's inventory.
+ menu->getChild<LLMenuItemCallGL>("landmark")->setEnabled(is_agent_place_info_visible &&
+ !LLLandmarkActions::landmarkAlreadyExists());
+ }
+ else if (mPlaceInfoType == LANDMARK_INFO_TYPE && mLandmarkMenu != NULL)
+ {
+ menu = mLandmarkMenu;
+
+ BOOL is_landmark_removable = FALSE;
+ if (mItem.notNull())
+ {
+ const LLUUID& item_id = mItem->getUUID();
+ const LLUUID& trash_id = gInventory.findCategoryUUIDForType(LLAssetType::AT_TRASH);
+ is_landmark_removable = gInventory.isObjectDescendentOf(item_id, gInventory.getRootFolderID()) &&
+ !gInventory.isObjectDescendentOf(item_id, trash_id);
+ }
+
+ menu->getChild<LLMenuItemCallGL>("delete")->setEnabled(is_landmark_removable);
+ }
+ else
+ {
+ return;
+ }
+
+ if (!menu->toggleVisibility())
+ return;
+
+ menu->updateParent(LLMenuGL::sMenuContainer);
+ LLRect rect = mOverflowBtn->getRect();
+ menu->setButtonRect(rect, this);
+ LLMenuGL::showPopup(this, menu, rect.mRight, rect.mTop);
+}
+
+void LLPanelPlaces::onOverflowMenuItemClicked(const LLSD& param)
+{
+ std::string item = param.asString();
+ if (item == "landmark")
+ {
+ onOpen(LLSD().insert("type", CREATE_LANDMARK_INFO_TYPE));
+ }
+ else if (item == "copy")
+ {
+ LLLandmarkActions::getSLURLfromPosGlobal(mPosGlobal, boost::bind(&onSLURLBuilt, _1));
+ }
+ else if (item == "delete")
+ {
+ gInventory.removeItem(mItem->getUUID());
+
+ onBackButtonClicked();
+ }
+ else if (item == "pick")
+ {
+ if (!mPlaceInfo)
+ return;
+
+ mPlaceInfo->createPick(mPosGlobal);
+
+ onBackButtonClicked();
+ }
+}
+
+void LLPanelPlaces::onCreateLandmarkButtonClicked(const LLUUID& folder_id)
+{
+ if (!mPlaceInfo)
+ return;
+
+ mPlaceInfo->createLandmark(folder_id);
+}
+
+void LLPanelPlaces::onBackButtonClicked()
+{
+ if (!mPlaceInfo)
+ return;
+
+ if (mPlaceInfo->isMediaPanelVisible())
+ {
+ toggleMediaPanel();
+ }
+ else
+ {
+ togglePlaceInfoPanel(FALSE);
+
+ // Resetting mPlaceInfoType when Place Info panel is closed.
+ mPlaceInfoType = LLStringUtil::null;
+ }
+
+ updateVerbs();
+}
+
+void LLPanelPlaces::toggleMediaPanel()
+{
+ if (!mPlaceInfo)
+ return;
+
+ mPlaceInfo->toggleMediaPanel(!mPlaceInfo->isMediaPanelVisible());
+
+ // Refresh the current place info because
+ // the media panel controls can't refer to
+ // the remote parcel media.
+ onOpen(LLSD().insert("type", AGENT_INFO_TYPE));
+}
+
+void LLPanelPlaces::togglePlaceInfoPanel(BOOL visible)
+{
+ if (!mPlaceInfo)
+ return;
+
+ mPlaceInfo->setVisible(visible);
+ mFilterEditor->setVisible(!visible);
+ mTabContainer->setVisible(!visible);
+
+ if (visible)
+ {
+ mPlaceInfo->resetLocation();
+
+ LLRect rect = getRect();
+ LLRect new_rect = LLRect(rect.mLeft, rect.mTop, rect.mRight, mTabContainer->getRect().mBottom);
+ mPlaceInfo->reshape(new_rect.getWidth(),new_rect.getHeight());
+ }
+}
+
+//virtual
+void LLPanelPlaces::changed(U32 mask)
+{
+ if (!(gInventory.isInventoryUsable() && LLTeleportHistory::getInstance()))
+ return;
+
+ LLLandmarksPanel* landmarks_panel = new LLLandmarksPanel();
+ if (landmarks_panel)
+ {
+ landmarks_panel->setPanelPlacesButtons(this);
+
+ mTabContainer->addTabPanel(
+ LLTabContainer::TabPanelParams().
+ panel(landmarks_panel).
+ label(getString("landmarks_tab_title")).
+ insert_at(LLTabContainer::END));
+ }
+
+ LLTeleportHistoryPanel* teleport_history_panel = new LLTeleportHistoryPanel();
+ if (teleport_history_panel)
+ {
+ teleport_history_panel->setPanelPlacesButtons(this);
+
+ mTabContainer->addTabPanel(
+ LLTabContainer::TabPanelParams().
+ panel(teleport_history_panel).
+ label(getString("teleport_history_tab_title")).
+ insert_at(LLTabContainer::END));
+ }
+
+ mTabContainer->selectFirstTab();
+
+ mActivePanel = dynamic_cast<LLPanelPlacesTab*>(mTabContainer->getCurrentPanel());
+
+ // we don't need to monitor inventory changes anymore,
+ // so remove the observer
+ gInventory.removeObserver(this);
+}
+
+void LLPanelPlaces::onAgentParcelChange()
+{
+ if (!mPlaceInfo)
+ return;
+
+ if (mPlaceInfo->getVisible() && mPlaceInfoType == CREATE_LANDMARK_INFO_TYPE)
+ {
+ onOpen(LLSD().insert("type", mPlaceInfoType));
+ }
+ else if (mPlaceInfo->isMediaPanelVisible())
+ {
+ onOpen(LLSD().insert("type", AGENT_INFO_TYPE));
+ }
+ else
+ {
+ updateVerbs();
+ }
+}
+
+void LLPanelPlaces::updateVerbs()
+{
+ if (!mPlaceInfo)
+ return;
+
+ bool is_place_info_visible = mPlaceInfo->getVisible();
+ bool is_agent_place_info_visible = mPlaceInfoType == AGENT_INFO_TYPE;
+ bool is_create_landmark_visible = mPlaceInfoType == CREATE_LANDMARK_INFO_TYPE;
+ bool is_media_panel_visible = mPlaceInfo->isMediaPanelVisible();
+
+ mTeleportBtn->setVisible(!is_create_landmark_visible);
+ mShareBtn->setVisible(!is_create_landmark_visible);
+ mCreateLandmarkBtn->setVisible(is_create_landmark_visible);
+ mFolderMenuBtn->setVisible(is_create_landmark_visible);
+
+ mOverflowBtn->setEnabled(is_place_info_visible && !is_media_panel_visible && !is_create_landmark_visible);
+
+ if (is_place_info_visible)
+ {
+ if (is_agent_place_info_visible)
+ {
+ // We don't need to teleport to the current location
+ // so check if the location is not within the current parcel.
+ mTeleportBtn->setEnabled(!is_media_panel_visible &&
+ !mPosGlobal.isExactlyZero() &&
+ !LLViewerParcelMgr::getInstance()->inAgentParcel(mPosGlobal));
+ }
+ else if (is_create_landmark_visible)
+ {
+ // Enable "Create Landmark" only if there is no landmark
+ // for the current parcel.
+ bool no_landmark = !LLLandmarkActions::landmarkAlreadyExists();
+ mCreateLandmarkBtn->setEnabled(no_landmark);
+ mFolderMenuBtn->setEnabled(no_landmark);
+ }
+ else if (mPlaceInfoType == LANDMARK_INFO_TYPE || mPlaceInfoType == REMOTE_PLACE_INFO_TYPE)
+ {
+ mTeleportBtn->setEnabled(TRUE);
+ }
+
+ mShowOnMapBtn->setEnabled(!is_media_panel_visible);
+ }
+ else
+ {
+ mActivePanel->updateVerbs();
+ }
+}
+
+void LLPanelPlaces::showLandmarkFoldersMenu()
+{
+ if (mLandmarkFoldersMenuHandle.isDead())
+ {
+ LLToggleableMenu::Params menu_p;
+ menu_p.name("landmarks_folders_menu");
+ menu_p.can_tear_off(false);
+ menu_p.visible(false);
+ menu_p.scrollable(true);
+ menu_p.max_scrollable_items = 10;
+
+ LLToggleableMenu* menu = LLUICtrlFactory::create<LLToggleableMenu>(menu_p);
+
+ mLandmarkFoldersMenuHandle = menu->getHandle();
+ }
+
+ LLToggleableMenu* menu = (LLToggleableMenu*)mLandmarkFoldersMenuHandle.get();
+ if(!menu)
+ return;
+
+ if (!menu->toggleVisibility())
+ return;
+
+ // Collect all folders that can contain landmarks.
+ LLInventoryModel::cat_array_t cats;
+ collectLandmarkFolders(cats);
+
+ // Sort the folders by their full name.
+ folder_vec_t folders;
+ S32 count = cats.count();
+ for (S32 i = 0; i < count; i++)
+ {
+ const LLViewerInventoryCategory* cat = cats.get(i);
+ std::string cat_full_name = getFullFolderName(cat);
+ folders.push_back(folder_pair_t(cat->getUUID(), cat_full_name));
+ }
+ sort(folders.begin(), folders.end(), cmp_folders);
+
+ LLRect btn_rect = mFolderMenuBtn->getRect();
+
+ LLRect root_rect = getRootView()->getRect();
+
+ // Check it there are changed items or viewer dimensions
+ // have changed since last call
+ if (mLandmarkFoldersCache.size() == count &&
+ mRootViewWidth == root_rect.getWidth() &&
+ mRootViewHeight == root_rect.getHeight())
+ {
+ S32 i;
+ for (i = 0; i < count; i++)
+ {
+ if (mLandmarkFoldersCache[i].second != folders[i].second)
+ {
+ break;
+ }
+ }
+
+ // Check passed, just show the menu
+ if (i == count)
+ {
+ menu->buildDrawLabels();
+ menu->updateParent(LLMenuGL::sMenuContainer);
+
+ menu->setButtonRect(btn_rect, this);
+ LLMenuGL::showPopup(this, menu, btn_rect.mRight, btn_rect.mTop);
+ return;
+ }
+ }
+
+ // If there are changes, store the new viewer dimensions
+ // and a list of folders
+ mRootViewWidth = root_rect.getWidth();
+ mRootViewHeight = root_rect.getHeight();
+ mLandmarkFoldersCache = folders;
+
+ menu->empty();
+
+ // Menu width must not exceed the root view limits,
+ // so we assume the space between the left edge of
+ // the root view and
+ LLRect screen_btn_rect;
+ localRectToScreen(btn_rect, &screen_btn_rect);
+ S32 free_space = screen_btn_rect.mRight;
+ U32 max_width = llmin(LANDMARK_FOLDERS_MENU_WIDTH, free_space);
+
+ for(folder_vec_t::const_iterator it = mLandmarkFoldersCache.begin(); it != mLandmarkFoldersCache.end(); it++)
+ {
+ const std::string& item_name = it->second;
+
+ LLMenuItemCallGL::Params item_params;
+ item_params.name(item_name);
+ item_params.label(item_name);
+
+ item_params.on_click.function(boost::bind(&LLPanelPlaces::onCreateLandmarkButtonClicked, this, it->first));
+
+ LLMenuItemCallGL *menu_item = LLUICtrlFactory::create<LLMenuItemCallGL>(item_params);
+
+ // *TODO: Use a separate method for menu width calculation.
+ // Check whether item name wider than menu
+ if (menu_item->getNominalWidth() > max_width)
+ {
+ S32 chars_total = item_name.length();
+ S32 chars_fitted = 1;
+ menu_item->setLabel(LLStringExplicit(""));
+ S32 label_space = max_width - menu_item->getFont()->getWidth("...") -
+ menu_item->getNominalWidth(); // This returns width of menu item with empty label (pad pixels)
+
+ while (chars_fitted < chars_total && menu_item->getFont()->getWidth(item_name, 0, chars_fitted) < label_space)
+ {
+ chars_fitted++;
+ }
+ chars_fitted--; // Rolling back one char, that doesn't fit
+
+ menu_item->setLabel(item_name.substr(0, chars_fitted) + "...");
+ }
+
+ menu->addChild(menu_item);
+ }
+
+ menu->buildDrawLabels();
+ menu->updateParent(LLMenuGL::sMenuContainer);
+ menu->setButtonRect(btn_rect, this);
+ LLMenuGL::showPopup(this, menu, btn_rect.mRight, btn_rect.mTop);
+}
+
+static bool cmp_folders(const folder_pair_t& left, const folder_pair_t& right)
+{
+ return left.second < right.second;
+}
+
+static std::string getFullFolderName(const LLViewerInventoryCategory* cat)
+{
+ std::string name = cat->getName();
+ LLUUID parent_id;
+
+ // translate category name, if it's right below the root
+ // FIXME: it can throw notification about non existent string in strings.xml
+ if (cat->getParentUUID().notNull() && cat->getParentUUID() == gInventory.getRootFolderID())
+ {
+ LLTrans::findString(name, "InvFolder " + name);
+ }
+
+ // we don't want "My Inventory" to appear in the name
+ while ((parent_id = cat->getParentUUID()).notNull() && parent_id != gInventory.getRootFolderID())
+ {
+ cat = gInventory.getCategory(parent_id);
+ name = cat->getName() + "/" + name;
+ }
+
+ return name;
+}
+
+static void collectLandmarkFolders(LLInventoryModel::cat_array_t& cats)
+{
+ // Add the "Landmarks" category itself.
+ LLUUID landmarks_id = gInventory.findCategoryUUIDForType(LLAssetType::AT_LANDMARK);
+ LLViewerInventoryCategory* landmarks_cat = gInventory.getCategory(landmarks_id);
+ if (!landmarks_cat)
+ {
+ llwarns << "Cannot find the landmarks folder" << llendl;
+ }
+ else
+ {
+ cats.put(landmarks_cat);
+ }
+
+ // Add descendent folders of the "Landmarks" category.
+ LLInventoryModel::item_array_t items; // unused
+ LLIsType is_category(LLAssetType::AT_CATEGORY);
+ gInventory.collectDescendentsIf(
+ landmarks_id,
+ cats,
+ items,
+ LLInventoryModel::EXCLUDE_TRASH,
+ is_category);
+
+ // Add the "My Favorites" category.
+ LLUUID favorites_id = gInventory.findCategoryUUIDForType(LLAssetType::AT_FAVORITE);
+ LLViewerInventoryCategory* favorites_cat = gInventory.getCategory(favorites_id);
+ if (!favorites_cat)
+ {
+ llwarns << "Cannot find the favorites folder" << llendl;
+ }
+ else
+ {
+ cats.put(favorites_cat);
+ }
+}
+
+static const LLVector3 get_pos_local_from_global(const LLVector3d &pos_global)
+{
+ F32 region_x = (F32)fmod( pos_global.mdV[VX], (F64)REGION_WIDTH_METERS );
+ F32 region_y = (F32)fmod( pos_global.mdV[VY], (F64)REGION_WIDTH_METERS );
+
+ LLVector3 pos_local(region_x, region_y, (F32)pos_global.mdV[VZ]);
+ return pos_local;
+}
+
+static void onSLURLBuilt(std::string& slurl)
+{
+ LLView::getWindow()->copyTextToClipboard(utf8str_to_wstring(slurl));
+
+ LLSD args;
+ args["SLURL"] = slurl;
+
+ LLNotifications::instance().add("CopySLURL", args);
+}
diff --git a/indra/newview/llpanelplaces.h b/indra/newview/llpanelplaces.h
new file mode 100644
index 0000000000..089a854762
--- /dev/null
+++ b/indra/newview/llpanelplaces.h
@@ -0,0 +1,128 @@
+/**
+ * @file llpanelplaces.h
+ * @brief Side Bar "Places" panel
+ *
+ * $LicenseInfo:firstyear=2009&license=viewergpl$
+ *
+ * Copyright (c) 2004-2009, Linden Research, Inc.
+ *
+ * Second Life Viewer Source Code
+ * The source code in this file ("Source Code") is provided by Linden Lab
+ * to you under the terms of the GNU General Public License, version 2.0
+ * ("GPL"), unless you have obtained a separate licensing agreement
+ * ("Other License"), formally executed by you and Linden Lab. Terms of
+ * the GPL can be found in doc/GPL-license.txt in this distribution, or
+ * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
+ *
+ * There are special exceptions to the terms and conditions of the GPL as
+ * it is applied to this Source Code. View the full text of the exception
+ * in the file doc/FLOSS-exception.txt in this software distribution, or
+ * online at http://secondlifegrid.net/programs/open_source/licensing/flossexception
+ *
+ * By copying, modifying or distributing this software, you acknowledge
+ * that you have read and understood your obligations described above,
+ * and agree to abide by those obligations.
+ *
+ * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+ * COMPLETENESS OR PERFORMANCE.
+ * $/LicenseInfo$
+ */
+
+#ifndef LL_LLPANELPLACES_H
+#define LL_LLPANELPLACES_H
+
+#include "lltimer.h"
+
+#include "llpanel.h"
+
+#include "llinventory.h"
+
+#include "llinventorymodel.h"
+#include "llpanelplaceinfo.h"
+
+class LLInventoryItem;
+class LLLandmark;
+class LLPanelPlacesTab;
+class LLFilterEditor;
+class LLTabContainer;
+
+typedef std::pair<LLUUID, std::string> folder_pair_t;
+
+class LLPanelPlaces : public LLPanel, LLInventoryObserver
+{
+public:
+ LLPanelPlaces();
+ virtual ~LLPanelPlaces();
+
+ /*virtual*/ BOOL postBuild();
+ /*virtual*/ void changed(U32 mask);
+ /*virtual*/ void onOpen(const LLSD& key);
+
+ void setItem(LLInventoryItem* item);
+
+private:
+ void onLandmarkLoaded(LLLandmark* landmark);
+ void onFilterEdit(const std::string& search_string);
+ void onTabSelected();
+
+ //void onShareButtonClicked();
+ void onTeleportButtonClicked();
+ void onShowOnMapButtonClicked();
+ void onOverflowButtonClicked();
+ void onOverflowMenuItemClicked(const LLSD& param);
+ void onCreateLandmarkButtonClicked(const LLUUID& folder_id);
+ void onBackButtonClicked();
+
+ void toggleMediaPanel();
+ void togglePlaceInfoPanel(BOOL visible);
+
+ void onAgentParcelChange();
+ void updateVerbs();
+
+ void showLandmarkFoldersMenu();
+
+ LLFilterEditor* mFilterEditor;
+ LLPanelPlacesTab* mActivePanel;
+ LLTabContainer* mTabContainer;
+ LLPanelPlaceInfo* mPlaceInfo;
+ LLToggleableMenu* mPlaceMenu;
+ LLToggleableMenu* mLandmarkMenu;
+
+ LLButton* mCreateLandmarkBtn;
+ LLButton* mFolderMenuBtn;
+ LLButton* mTeleportBtn;
+ LLButton* mShowOnMapBtn;
+ LLButton* mShareBtn;
+ LLButton* mOverflowBtn;
+
+ // Pointer to a landmark item or to a linked landmark
+ LLPointer<LLInventoryItem> mItem;
+
+ // Absolute position of the location for teleport, may not
+ // be available (hence zero)
+ LLVector3d mPosGlobal;
+
+ // Search string for filtering landmarks and teleport
+ // history locations
+ std::string mFilterSubString;
+
+ // Information type currently shown in Place Information panel
+ std::string mPlaceInfoType;
+
+ // Menu handle for pop-up menu to chose a landmark saving
+ // folder when creating a new landmark
+ LLHandle<LLView> mLandmarkFoldersMenuHandle;
+
+ typedef std::vector<folder_pair_t> folder_vec_t;
+
+ // List of folders to choose from when creating a landmark
+ folder_vec_t mLandmarkFoldersCache;
+
+ // If root view width or height is changed
+ // the pop-up menu must be updated
+ S32 mRootViewWidth;
+ S32 mRootViewHeight;
+};
+
+#endif //LL_LLPANELPLACES_H
diff --git a/indra/newview/llpanelplacestab.cpp b/indra/newview/llpanelplacestab.cpp
new file mode 100644
index 0000000000..7c0a7b0cc4
--- /dev/null
+++ b/indra/newview/llpanelplacestab.cpp
@@ -0,0 +1,87 @@
+/**
+ * @file llpanelplacestab.cpp
+ * @brief Tabs interface for Side Bar "Places" panel
+ *
+ * $LicenseInfo:firstyear=2009&license=viewergpl$
+ *
+ * Copyright (c) 2004-2009, Linden Research, Inc.
+ *
+ * Second Life Viewer Source Code
+ * The source code in this file ("Source Code") is provided by Linden Lab
+ * to you under the terms of the GNU General Public License, version 2.0
+ * ("GPL"), unless you have obtained a separate licensing agreement
+ * ("Other License"), formally executed by you and Linden Lab. Terms of
+ * the GPL can be found in doc/GPL-license.txt in this distribution, or
+ * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
+ *
+ * There are special exceptions to the terms and conditions of the GPL as
+ * it is applied to this Source Code. View the full text of the exception
+ * in the file doc/FLOSS-exception.txt in this software distribution, or
+ * online at http://secondlifegrid.net/programs/open_source/licensing/flossexception
+ *
+ * By copying, modifying or distributing this software, you acknowledge
+ * that you have read and understood your obligations described above,
+ * and agree to abide by those obligations.
+ *
+ * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+ * COMPLETENESS OR PERFORMANCE.
+ * $/LicenseInfo$
+ */
+
+#include "llviewerprecompiledheaders.h"
+
+#include "llpanelplacestab.h"
+
+#include "llwindow.h"
+
+#include "llnotifications.h"
+
+#include "llbutton.h"
+#include "llslurl.h"
+#include "llworldmap.h"
+
+bool LLPanelPlacesTab::isTabVisible()
+{
+ LLUICtrl* parent = getParentUICtrl();
+ if (!parent) return false;
+ if (!parent->getVisible()) return false;
+ return true;
+}
+
+void LLPanelPlacesTab::setPanelPlacesButtons(LLPanelPlaces* panel)
+{
+ //mShareBtn = panel->getChild<LLButton>("share_btn");
+ mTeleportBtn = panel->getChild<LLButton>("teleport_btn");
+ mShowOnMapBtn = panel->getChild<LLButton>("map_btn");
+}
+
+void LLPanelPlacesTab::onRegionResponse(const LLVector3d& landmark_global_pos,
+ U64 region_handle,
+ const std::string& url,
+ const LLUUID& snapshot_id,
+ bool teleport)
+{
+ std::string sim_name;
+ bool gotSimName = LLWorldMap::getInstance()->simNameFromPosGlobal( landmark_global_pos, sim_name );
+
+ std::string sl_url;
+ if ( gotSimName )
+ {
+ F32 region_x = (F32)fmod( landmark_global_pos.mdV[VX], (F64)REGION_WIDTH_METERS );
+ F32 region_y = (F32)fmod( landmark_global_pos.mdV[VY], (F64)REGION_WIDTH_METERS );
+
+ sl_url = LLSLURL::buildSLURL(sim_name, llround(region_x), llround(region_y), llround((F32)landmark_global_pos.mdV[VZ]));
+ }
+ else
+ {
+ sl_url = "";
+ }
+
+ LLView::getWindow()->copyTextToClipboard(utf8str_to_wstring(sl_url));
+
+ LLSD args;
+ args["SLURL"] = sl_url;
+
+ LLNotifications::instance().add("CopySLURL", args);
+}
diff --git a/indra/newview/llpanelplacestab.h b/indra/newview/llpanelplacestab.h
new file mode 100644
index 0000000000..1c70869414
--- /dev/null
+++ b/indra/newview/llpanelplacestab.h
@@ -0,0 +1,66 @@
+/**
+ * @file llpanelplacestab.h
+ * @brief Tabs interface for Side Bar "Places" panel
+ *
+ * $LicenseInfo:firstyear=2009&license=viewergpl$
+ *
+ * Copyright (c) 2004-2009, Linden Research, Inc.
+ *
+ * Second Life Viewer Source Code
+ * The source code in this file ("Source Code") is provided by Linden Lab
+ * to you under the terms of the GNU General Public License, version 2.0
+ * ("GPL"), unless you have obtained a separate licensing agreement
+ * ("Other License"), formally executed by you and Linden Lab. Terms of
+ * the GPL can be found in doc/GPL-license.txt in this distribution, or
+ * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
+ *
+ * There are special exceptions to the terms and conditions of the GPL as
+ * it is applied to this Source Code. View the full text of the exception
+ * in the file doc/FLOSS-exception.txt in this software distribution, or
+ * online at http://secondlifegrid.net/programs/open_source/licensing/flossexception
+ *
+ * By copying, modifying or distributing this software, you acknowledge
+ * that you have read and understood your obligations described above,
+ * and agree to abide by those obligations.
+ *
+ * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+ * COMPLETENESS OR PERFORMANCE.
+ * $/LicenseInfo$
+ */
+
+#ifndef LL_LLPANELPLACESTAB_H
+#define LL_LLPANELPLACESTAB_H
+
+#include "llpanel.h"
+
+#include "llpanelplaces.h"
+
+class LLPanelPlacesTab : public LLPanel
+{
+public:
+ LLPanelPlacesTab() : LLPanel() {}
+ virtual ~LLPanelPlacesTab() {}
+
+ virtual void onSearchEdit(const std::string& string) = 0;
+ virtual void updateVerbs() = 0; // Updates buttons at the bottom of Places panel
+ //virtual void onShare() = 0;
+ virtual void onShowOnMap() = 0;
+ virtual void onTeleport() = 0;
+ //virtual void onCopySLURL() = 0;
+
+ bool isTabVisible(); // Check if parent TabContainer is visible.
+
+ void setPanelPlacesButtons(LLPanelPlaces* panel);
+ void onRegionResponse(const LLVector3d& landmark_global_pos,
+ U64 region_handle,
+ const std::string& url,
+ const LLUUID& snapshot_id,
+ bool teleport);
+protected:
+ //LLButton* mShareBtn;
+ LLButton* mTeleportBtn;
+ LLButton* mShowOnMapBtn;
+};
+
+#endif //LL_LLPANELPLACESTAB_H
diff --git a/indra/newview/llpanelprofile.cpp b/indra/newview/llpanelprofile.cpp
new file mode 100644
index 0000000000..6d3d307526
--- /dev/null
+++ b/indra/newview/llpanelprofile.cpp
@@ -0,0 +1,178 @@
+/**
+* @file llpanelprofile.cpp
+* @brief Profile panel implementation
+*
+* $LicenseInfo:firstyear=2009&license=viewergpl$
+*
+* Copyright (c) 2009, Linden Research, Inc.
+*
+* Second Life Viewer Source Code
+* The source code in this file ("Source Code") is provided by Linden Lab
+* to you under the terms of the GNU General Public License, version 2.0
+* ("GPL"), unless you have obtained a separate licensing agreement
+* ("Other License"), formally executed by you and Linden Lab. Terms of
+* the GPL can be found in doc/GPL-license.txt in this distribution, or
+* online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
+*
+* There are special exceptions to the terms and conditions of the GPL as
+* it is applied to this Source Code. View the full text of the exception
+* in the file doc/FLOSS-exception.txt in this software distribution, or
+* online at
+* http://secondlifegrid.net/programs/open_source/licensing/flossexception
+*
+* By copying, modifying or distributing this software, you acknowledge
+* that you have read and understood your obligations described above,
+* and agree to abide by those obligations.
+*
+* ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+* COMPLETENESS OR PERFORMANCE.
+* $/LicenseInfo$
+*/
+
+#include "llviewerprecompiledheaders.h"
+#include "llpanelprofile.h"
+
+#include "llagent.h"
+#include "llavataractions.h"
+#include "llcommandhandler.h"
+#include "llpanelpicks.h"
+#include "lltabcontainer.h"
+
+static const std::string PANEL_PICKS = "panel_picks";
+static const std::string PANEL_PROFILE = "panel_profile";
+
+class LLAgentHandler : public LLCommandHandler
+{
+public:
+ // requires trusted browser to trigger
+ LLAgentHandler() : LLCommandHandler("agent", true) { }
+
+ bool handle(const LLSD& params, const LLSD& query_map,
+ LLMediaCtrl* web)
+ {
+ if (params.size() < 2) return false;
+ LLUUID agent_id;
+ if (!agent_id.set(params[0], FALSE))
+ {
+ return false;
+ }
+
+ if (params[1].asString() == "about")
+ {
+ LLAvatarActions::showProfile(agent_id);
+ return true;
+ }
+ return false;
+ }
+};
+LLAgentHandler gAgentHandler;
+
+
+LLPanelProfile::LLPanelProfile()
+ : LLPanel()
+ , mTabCtrl(NULL)
+ , mAvatarId(LLUUID::null)
+{
+}
+
+BOOL LLPanelProfile::postBuild()
+{
+ mTabCtrl = getChild<LLTabContainer>("tabs");
+
+ getTabCtrl()->setCommitCallback(boost::bind(&LLPanelProfile::onTabSelected, this, _2));
+
+ LLPanelPicks* panel_picks = getChild<LLPanelPicks>(PANEL_PICKS);
+ panel_picks->setProfilePanel(this);
+
+ getTabContainer()[PANEL_PICKS] = panel_picks;
+ getTabContainer()[PANEL_PROFILE] = getChild<LLPanelAvatarProfile>(PANEL_PROFILE);
+
+ return TRUE;
+}
+
+void LLPanelProfile::onOpen(const LLSD& key)
+{
+ if (key.has("open_tab_name"))
+ {
+ getTabContainer()[PANEL_PICKS]->onClose();
+
+ // onOpen from selected panel will be called from onTabSelected callback
+ getTabCtrl()->selectTabByName(key["open_tab_name"]);
+ }
+ else
+ {
+ getTabCtrl()->getCurrentPanel()->onOpen(getAvatarId());
+ }
+
+ // Update the avatar name.
+ gCacheName->get(getAvatarId(), FALSE,
+ boost::bind(&LLPanelProfile::onAvatarNameCached, this, _1, _2, _3, _4));
+}
+
+//*TODO redo panel toggling
+void LLPanelProfile::togglePanel(LLPanel* panel)
+{
+ // TRUE - we need to open/expand "panel"
+ bool expand = getChildList()->back() != panel; // mTabCtrl->getVisible();
+
+ if (expand)
+ {
+ //*NOTE on view profile panel along with tabcontainer there is
+ // a backbutton that will be shown when there will be a panel over it even
+ //if that panel has visible backgroud
+ setAllChildrenVisible(FALSE);
+
+ panel->setVisible(TRUE);
+ if (panel->getParent() != this)
+ {
+ addChildInBack(panel);
+ }
+ else
+ {
+ sendChildToBack(panel);
+ }
+
+ LLRect new_rect = getRect();
+ panel->reshape(new_rect.getWidth(), new_rect.getHeight());
+ new_rect.setLeftTopAndSize(0, new_rect.getHeight(), new_rect.getWidth(), new_rect.getHeight());
+ panel->setRect(new_rect);
+ }
+ else
+ {
+ this->setAllChildrenVisible(TRUE);
+ panel->setVisible(FALSE);
+ if (panel->getParent() == this)
+ {
+ removeChild(panel);
+ }
+ sendChildToBack(getTabCtrl());
+ getTabCtrl()->getCurrentPanel()->onOpen(getAvatarId());
+ }
+}
+
+void LLPanelProfile::onTabSelected(const LLSD& param)
+{
+ std::string tab_name = param.asString();
+ if (NULL != getTabContainer()[tab_name])
+ {
+ getTabContainer()[tab_name]->onOpen(getAvatarId());
+ }
+}
+
+void LLPanelProfile::setAllChildrenVisible(BOOL visible)
+{
+ const child_list_t* child_list = getChildList();
+ child_list_const_iter_t child_it = child_list->begin();
+ for (; child_it != child_list->end(); ++child_it)
+ {
+ LLView* viewp = *child_it;
+ viewp->setVisible(visible);
+ }
+}
+
+void LLPanelProfile::onAvatarNameCached(const LLUUID& id, const std::string& first_name, const std::string& last_name, BOOL is_group)
+{
+ llassert(getAvatarId() == id);
+ getChild<LLTextBox>("user_name", FALSE)->setValue(first_name + " " + last_name);
+}
diff --git a/indra/newview/llpanelprofile.h b/indra/newview/llpanelprofile.h
new file mode 100644
index 0000000000..0864ec1bc3
--- /dev/null
+++ b/indra/newview/llpanelprofile.h
@@ -0,0 +1,88 @@
+/**
+* @file llpanelprofile.h
+* @brief Profile panel
+*
+* $LicenseInfo:firstyear=2009&license=viewergpl$
+*
+* Copyright (c) 2009, Linden Research, Inc.
+*
+* Second Life Viewer Source Code
+* The source code in this file ("Source Code") is provided by Linden Lab
+* to you under the terms of the GNU General Public License, version 2.0
+* ("GPL"), unless you have obtained a separate licensing agreement
+* ("Other License"), formally executed by you and Linden Lab. Terms of
+* the GPL can be found in doc/GPL-license.txt in this distribution, or
+* online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
+*
+* There are special exceptions to the terms and conditions of the GPL as
+* it is applied to this Source Code. View the full text of the exception
+* in the file doc/FLOSS-exception.txt in this software distribution, or
+* online at
+* http://secondlifegrid.net/programs/open_source/licensing/flossexception
+*
+* By copying, modifying or distributing this software, you acknowledge
+* that you have read and understood your obligations described above,
+* and agree to abide by those obligations.
+*
+* ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+* COMPLETENESS OR PERFORMANCE.
+* $/LicenseInfo$
+*/
+
+#ifndef LL_LLPANELPROFILE_H
+#define LL_LLPANELPROFILE_H
+
+#include "llviewerprecompiledheaders.h"
+#include "llpanel.h"
+#include "llpanelavatar.h"
+
+class LLTabContainer;
+
+/**
+* Base class for Profile View and Me Profile.
+*/
+class LLPanelProfile : public LLPanel
+{
+ LOG_CLASS(LLPanelProfile);
+
+public:
+ /*virtual*/ BOOL postBuild();
+
+ /*virtual*/ void onOpen(const LLSD& key);
+
+ virtual void togglePanel(LLPanel*);
+
+protected:
+
+ LLPanelProfile();
+
+ virtual void onTabSelected(const LLSD& param);
+
+ virtual void setAllChildrenVisible(BOOL visible);
+
+ LLTabContainer* getTabCtrl() { return mTabCtrl; }
+
+ const LLUUID& getAvatarId() { return mAvatarId; }
+
+ void setAvatarId(const LLUUID& avatar_id) { mAvatarId = avatar_id; }
+
+ typedef std::map<std::string, LLPanelProfileTab*> profile_tabs_t;
+
+ profile_tabs_t& getTabContainer() { return mTabContainer; }
+
+private:
+ // LLCacheName will call this function when avatar name is loaded from server.
+ // This is required to display names that have not been cached yet.
+ void onAvatarNameCached(
+ const LLUUID& id,
+ const std::string& first_name,
+ const std::string& last_name,
+ BOOL is_group);
+
+ LLTabContainer* mTabCtrl;
+ profile_tabs_t mTabContainer;
+ LLUUID mAvatarId;
+};
+
+#endif //LL_LLPANELPROFILE_H
diff --git a/indra/newview/llpanelprofileview.cpp b/indra/newview/llpanelprofileview.cpp
new file mode 100644
index 0000000000..18184a6476
--- /dev/null
+++ b/indra/newview/llpanelprofileview.cpp
@@ -0,0 +1,96 @@
+/**
+* @file llpanelprofileview.cpp
+* @brief Side tray "Profile View" panel
+*
+* $LicenseInfo:firstyear=2009&license=viewergpl$
+*
+* Copyright (c) 2009, Linden Research, Inc.
+*
+* Second Life Viewer Source Code
+* The source code in this file ("Source Code") is provided by Linden Lab
+* to you under the terms of the GNU General Public License, version 2.0
+* ("GPL"), unless you have obtained a separate licensing agreement
+* ("Other License"), formally executed by you and Linden Lab. Terms of
+* the GPL can be found in doc/GPL-license.txt in this distribution, or
+* online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
+*
+* There are special exceptions to the terms and conditions of the GPL as
+* it is applied to this Source Code. View the full text of the exception
+* in the file doc/FLOSS-exception.txt in this software distribution, or
+* online at
+* http://secondlifegrid.net/programs/open_source/licensing/flossexception
+*
+* By copying, modifying or distributing this software, you acknowledge
+* that you have read and understood your obligations described above,
+* and agree to abide by those obligations.
+*
+* ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+* COMPLETENESS OR PERFORMANCE.
+* $/LicenseInfo$
+*/
+
+#include "llviewerprecompiledheaders.h"
+#include "llpanelprofileview.h"
+
+#include "llpanelavatar.h"
+#include "llpanelpicks.h"
+#include "llsidetraypanelcontainer.h"
+#include "llpanelprofile.h"
+
+static LLRegisterPanelClassWrapper<LLPanelProfileView> t_panel_target_profile("panel_profile_view");
+
+static std::string PANEL_NOTES = "panel_notes";
+static const std::string PANEL_PROFILE = "panel_profile";
+
+LLPanelProfileView::LLPanelProfileView()
+: LLPanelProfile()
+{
+}
+
+LLPanelProfileView::~LLPanelProfileView(void)
+{
+}
+
+/*virtual*/
+void LLPanelProfileView::onOpen(const LLSD& key)
+{
+ LLUUID id;
+ if(key.has("id"))
+ {
+ id = key["id"];
+ }
+ if(id.notNull() && getAvatarId() != id)
+ {
+ setAvatarId(id);
+ }
+
+ LLPanelProfile::onOpen(key);
+}
+
+BOOL LLPanelProfileView::postBuild()
+{
+ LLPanelProfile::postBuild();
+
+ getTabContainer()[PANEL_NOTES] = getChild<LLPanelAvatarNotes>(PANEL_NOTES);
+
+ //*TODO remove this, according to style guide we don't use status combobox
+ getTabContainer()[PANEL_PROFILE]->childSetVisible("online_me_status_text", FALSE);
+ getTabContainer()[PANEL_PROFILE]->childSetVisible("status_combo", FALSE);
+
+ childSetCommitCallback("back",boost::bind(&LLPanelProfileView::onBackBtnClick,this),NULL);
+
+ return TRUE;
+}
+
+
+//private
+
+void LLPanelProfileView::onBackBtnClick()
+{
+ LLSideTrayPanelContainer* parent = dynamic_cast<LLSideTrayPanelContainer*>(getParent());
+ if(parent)
+ {
+ parent->openPreviousPanel();
+ }
+}
diff --git a/indra/newview/llpanelprofileview.h b/indra/newview/llpanelprofileview.h
new file mode 100644
index 0000000000..92def7b7ca
--- /dev/null
+++ b/indra/newview/llpanelprofileview.h
@@ -0,0 +1,68 @@
+/**
+* @file llpanelprofileview.h
+* @brief Side tray "Profile View" panel
+*
+* $LicenseInfo:firstyear=2009&license=viewergpl$
+*
+* Copyright (c) 2009, Linden Research, Inc.
+*
+* Second Life Viewer Source Code
+* The source code in this file ("Source Code") is provided by Linden Lab
+* to you under the terms of the GNU General Public License, version 2.0
+* ("GPL"), unless you have obtained a separate licensing agreement
+* ("Other License"), formally executed by you and Linden Lab. Terms of
+* the GPL can be found in doc/GPL-license.txt in this distribution, or
+* online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
+*
+* There are special exceptions to the terms and conditions of the GPL as
+* it is applied to this Source Code. View the full text of the exception
+* in the file doc/FLOSS-exception.txt in this software distribution, or
+* online at
+* http://secondlifegrid.net/programs/open_source/licensing/flossexception
+*
+* By copying, modifying or distributing this software, you acknowledge
+* that you have read and understood your obligations described above,
+* and agree to abide by those obligations.
+*
+* ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+* COMPLETENESS OR PERFORMANCE.
+* $/LicenseInfo$
+*/
+
+#ifndef LL_LLPANELPROFILEVIEW_H
+#define LL_LLPANELPROFILEVIEW_H
+
+#include "llpanel.h"
+#include "llpanelprofile.h"
+#include "llavatarpropertiesprocessor.h"
+
+class LLPanelProfile;
+class LLPanelProfileTab;
+
+
+/**
+* Panel for displaying Avatar's profile. It consists of three sub panels - Profile,
+* Picks and Notes.
+*/
+class LLPanelProfileView : public LLPanelProfile
+{
+ LOG_CLASS(LLPanelProfileView);
+ friend class LLUICtrlFactory;
+
+public:
+
+ LLPanelProfileView();
+
+ /*virtual*/ ~LLPanelProfileView();
+
+ /*virtual*/ void onOpen(const LLSD& key);
+
+ /*virtual*/ BOOL postBuild();
+
+protected:
+
+ void onBackBtnClick();
+};
+
+#endif //LL_LLPANELPROFILEVIEW_H
diff --git a/indra/newview/llpanelteleporthistory.cpp b/indra/newview/llpanelteleporthistory.cpp
new file mode 100644
index 0000000000..8b378c33e3
--- /dev/null
+++ b/indra/newview/llpanelteleporthistory.cpp
@@ -0,0 +1,234 @@
+/**
+ * @file llpanelteleporthistory.cpp
+ * @brief Teleport history represented by a scrolling list
+ *
+ * $LicenseInfo:firstyear=2009&license=viewergpl$
+ *
+ * Copyright (c) 2001-2009, Linden Research, Inc.
+ *
+ * Second Life Viewer Source Code
+ * The source code in this file ("Source Code") is provided by Linden Lab
+ * to you under the terms of the GNU General Public License, version 2.0
+ * ("GPL"), unless you have obtained a separate licensing agreement
+ * ("Other License"), formally executed by you and Linden Lab. Terms of
+ * the GPL can be found in doc/GPL-license.txt in this distribution, or
+ * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
+ *
+ * There are special exceptions to the terms and conditions of the GPL as
+ * it is applied to this Source Code. View the full text of the exception
+ * in the file doc/FLOSS-exception.txt in this software distribution, or
+ * online at http://secondlifegrid.net/programs/open_source/licensing/flossexception
+ *
+ * By copying, modifying or distributing this software, you acknowledge
+ * that you have read and understood your obligations described above,
+ * and agree to abide by those obligations.
+ *
+ * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+ * COMPLETENESS OR PERFORMANCE.
+ * $/LicenseInfo$
+ */
+
+#include "llviewerprecompiledheaders.h"
+
+#include "llfloaterreg.h"
+
+#include "llfloaterworldmap.h"
+#include "llpanelteleporthistory.h"
+#include "llsidetray.h"
+#include "llworldmap.h"
+
+// Not yet implemented; need to remove buildPanel() from constructor when we switch
+//static LLRegisterPanelClassWrapper<LLTeleportHistoryPanel> t_teleport_history("panel_teleport_history");
+
+LLTeleportHistoryPanel::LLTeleportHistoryPanel()
+ : LLPanelPlacesTab(),
+ mFilterSubString(LLStringUtil::null),
+ mTeleportHistory(NULL),
+ mHistoryItems(NULL)
+{
+ LLUICtrlFactory::getInstance()->buildPanel(this, "panel_teleport_history.xml");
+}
+
+LLTeleportHistoryPanel::~LLTeleportHistoryPanel()
+{
+}
+
+BOOL LLTeleportHistoryPanel::postBuild()
+{
+ mTeleportHistory = LLTeleportHistory::getInstance();
+ if (mTeleportHistory)
+ {
+ mTeleportHistory->setHistoryChangedCallback(boost::bind(&LLTeleportHistoryPanel::showTeleportHistory, this));
+ }
+
+ mHistoryItems = getChild<LLScrollListCtrl>("history_items");
+ if (mHistoryItems)
+ {
+ mHistoryItems->setDoubleClickCallback(onDoubleClickItem, this);
+ mHistoryItems->setCommitOnSelectionChange(FALSE);
+ mHistoryItems->setCommitCallback(boost::bind(&LLTeleportHistoryPanel::handleItemSelect, this, _2));
+ }
+
+ return TRUE;
+}
+
+// virtual
+void LLTeleportHistoryPanel::onSearchEdit(const std::string& string)
+{
+ if (mFilterSubString != string)
+ {
+ mFilterSubString = string;
+ showTeleportHistory();
+ }
+}
+
+// virtual
+void LLTeleportHistoryPanel::onShowOnMap()
+{
+ LLScrollListItem* itemp = mHistoryItems->getFirstSelected();
+ if(!itemp)
+ return;
+
+ S32 index = itemp->getColumn(LIST_INDEX)->getValue().asInteger();
+
+ const LLTeleportHistory::slurl_list_t& hist_items = mTeleportHistory->getItems();
+
+ LLVector3d global_pos = hist_items[index].mGlobalPos;
+
+ if (!global_pos.isExactlyZero())
+ {
+ LLFloaterWorldMap::getInstance()->trackLocation(global_pos);
+ LLFloaterReg::showInstance("world_map", "center");
+ }
+}
+
+// virtual
+void LLTeleportHistoryPanel::onTeleport()
+{
+ LLScrollListItem* itemp = mHistoryItems->getFirstSelected();
+ if(!itemp)
+ return;
+
+ S32 index = itemp->getColumn(LIST_INDEX)->getValue().asInteger();
+
+ // teleport to existing item in history, so we don't add it again
+ mTeleportHistory->goToItem(index);
+}
+
+/*
+// virtual
+void LLTeleportHistoryPanel::onCopySLURL()
+{
+ LLScrollListItem* itemp = mHistoryItems->getFirstSelected();
+ if(!itemp)
+ return;
+
+ S32 index = itemp->getColumn(LIST_INDEX)->getValue().asInteger();
+
+ const LLTeleportHistory::slurl_list_t& hist_items = mTeleportHistory->getItems();
+
+ LLVector3d global_pos = hist_items[index].mGlobalPos;
+
+ U64 new_region_handle = to_region_handle(global_pos);
+
+ LLWorldMap::url_callback_t cb = boost::bind(
+ &LLPanelPlacesTab::onRegionResponse, this,
+ global_pos, _1, _2, _3, _4);
+
+ LLWorldMap::getInstance()->sendHandleRegionRequest(new_region_handle, cb, std::string("unused"), false);
+}
+*/
+
+// virtual
+void LLTeleportHistoryPanel::updateVerbs()
+{
+ if (!isTabVisible())
+ return;
+
+ S32 index = 0;
+ S32 cur_item = 0;
+
+ LLScrollListItem* itemp = mHistoryItems->getFirstSelected();
+ if (itemp)
+ {
+ index = itemp->getColumn(LIST_INDEX)->getValue().asInteger();
+ cur_item = mTeleportHistory->getCurrentItemIndex();
+ }
+
+ mTeleportBtn->setEnabled(index != cur_item);
+ mShowOnMapBtn->setEnabled(itemp != NULL);
+}
+
+void LLTeleportHistoryPanel::showTeleportHistory()
+{
+ const LLTeleportHistory::slurl_list_t& hist_items = mTeleportHistory->getItems();
+
+ mHistoryItems->deleteAllItems();
+
+ S32 cur_item = mTeleportHistory->getCurrentItemIndex();
+
+ for (LLTeleportHistory::slurl_list_t::const_iterator iter = hist_items.begin();
+ iter != hist_items.end(); ++iter)
+ {
+ std::string landmark_title = (*iter).mTitle;
+ LLStringUtil::toUpper(landmark_title);
+
+ std::string::size_type match_offset = mFilterSubString.size() ? landmark_title.find(mFilterSubString) : std::string::npos;
+ bool passed = mFilterSubString.size() == 0 || match_offset != std::string::npos;
+
+ if (!passed)
+ continue;
+
+ S32 index = iter - hist_items.begin();
+
+ LLSD row;
+ row["id"] = index;
+
+ LLSD& icon_column = row["columns"][LIST_ICON];
+ icon_column["column"] = "landmark_icon";
+ icon_column["type"] = "icon";
+ icon_column["value"] = "inv_item_landmark.tga";
+
+ LLSD& region_column = row["columns"][LIST_ITEM_TITLE];
+ region_column["column"] = "region";
+ region_column["type"] = "text";
+ region_column["value"] = (*iter).mTitle;
+
+ LLSD& index_column = row["columns"][LIST_INDEX];
+ index_column["column"] = "index";
+ index_column["type"] = "text";
+ index_column["value"] = index;
+
+ mHistoryItems->addElement(row, ADD_TOP);
+
+ if (cur_item == index)
+ {
+ LLScrollListItem* itemp = mHistoryItems->getItem(index);
+ ((LLScrollListText*)itemp->getColumn(LIST_ITEM_TITLE))->setFontStyle(LLFontGL::BOLD);
+ }
+ }
+
+ updateVerbs();
+}
+
+void LLTeleportHistoryPanel::handleItemSelect(const LLSD& data)
+{
+ updateVerbs();
+}
+
+//static
+void LLTeleportHistoryPanel::onDoubleClickItem(void* user_data)
+{
+ LLTeleportHistoryPanel* self = (LLTeleportHistoryPanel*)user_data;
+
+ LLScrollListItem* itemp = self->mHistoryItems->getFirstSelected();
+ if(!itemp)
+ return;
+
+ LLSD key;
+ key["type"] = "teleport_history";
+ key["id"] = itemp->getColumn(LIST_INDEX)->getValue().asInteger();
+
+ LLSideTray::getInstance()->showPanel("panel_places", key);
+}
diff --git a/indra/newview/llpanelteleporthistory.h b/indra/newview/llpanelteleporthistory.h
new file mode 100644
index 0000000000..553385b37e
--- /dev/null
+++ b/indra/newview/llpanelteleporthistory.h
@@ -0,0 +1,73 @@
+/**
+ * @file llpanelteleporthistory.h
+ * @brief Teleport history represented by a scrolling list
+ * class definition
+ *
+ * $LicenseInfo:firstyear=2009&license=viewergpl$
+ *
+ * Copyright (c) 2001-2009, Linden Research, Inc.
+ *
+ * Second Life Viewer Source Code
+ * The source code in this file ("Source Code") is provided by Linden Lab
+ * to you under the terms of the GNU General Public License, version 2.0
+ * ("GPL"), unless you have obtained a separate licensing agreement
+ * ("Other License"), formally executed by you and Linden Lab. Terms of
+ * the GPL can be found in doc/GPL-license.txt in this distribution, or
+ * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
+ *
+ * There are special exceptions to the terms and conditions of the GPL as
+ * it is applied to this Source Code. View the full text of the exception
+ * in the file doc/FLOSS-exception.txt in this software distribution, or
+ * online at http://secondlifegrid.net/programs/open_source/licensing/flossexception
+ *
+ * By copying, modifying or distributing this software, you acknowledge
+ * that you have read and understood your obligations described above,
+ * and agree to abide by those obligations.
+ *
+ * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+ * COMPLETENESS OR PERFORMANCE.
+ * $/LicenseInfo$
+ */
+
+#ifndef LL_LLPANELTELEPORTHISTORY_H
+#define LL_LLPANELTELEPORTHISTORY_H
+
+#include "lluictrlfactory.h"
+#include "llscrolllistctrl.h"
+
+#include "llpanelplacestab.h"
+#include "llteleporthistory.h"
+
+class LLTeleportHistoryPanel : public LLPanelPlacesTab
+{
+public:
+ LLTeleportHistoryPanel();
+ virtual ~LLTeleportHistoryPanel();
+
+ /*virtual*/ BOOL postBuild();
+ /*virtual*/ void onSearchEdit(const std::string& string);
+ /*virtual*/ void onShowOnMap();
+ /*virtual*/ void onTeleport();
+ ///*virtual*/ void onCopySLURL();
+ /*virtual*/ void updateVerbs();
+
+ void showTeleportHistory();
+ void handleItemSelect(const LLSD& data);
+
+ static void onDoubleClickItem(void* user_data);
+
+private:
+ enum TELEPORT_HISTORY_COLUMN_ORDER
+ {
+ LIST_ICON,
+ LIST_ITEM_TITLE,
+ LIST_INDEX
+ };
+
+ LLTeleportHistory* mTeleportHistory;
+ LLScrollListCtrl* mHistoryItems;
+ std::string mFilterSubString;
+};
+
+#endif //LL_LLPANELTELEPORTHISTORY_H
diff --git a/indra/newview/llpanelvolume.cpp b/indra/newview/llpanelvolume.cpp
index 6d014a23de..ce16b95bc0 100644
--- a/indra/newview/llpanelvolume.cpp
+++ b/indra/newview/llpanelvolume.cpp
@@ -49,7 +49,6 @@
#include "material_codes.h"
// project includes
-#include "llagent.h"
#include "llbutton.h"
#include "llcheckboxctrl.h"
#include "llcolorswatch.h"
@@ -107,8 +106,8 @@ BOOL LLPanelVolume::postBuild()
childSetCommitCallback("Light Checkbox Ctrl",onCommitIsLight,this);
LLColorSwatchCtrl* LightColorSwatch = getChild<LLColorSwatchCtrl>("colorswatch");
if(LightColorSwatch){
- LightColorSwatch->setOnCancelCallback(onLightCancelColor);
- LightColorSwatch->setOnSelectCallback(onLightSelectColor);
+ LightColorSwatch->setOnCancelCallback(boost::bind(&LLPanelVolume::onLightCancelColor, this, _2));
+ LightColorSwatch->setOnSelectCallback(boost::bind(&LLPanelVolume::onLightSelectColor, this, _2));
childSetCommitCallback("colorswatch",onCommitLight,this);
}
childSetCommitCallback("Light Intensity",onCommitLight,this);
@@ -125,8 +124,8 @@ BOOL LLPanelVolume::postBuild()
return TRUE;
}
-LLPanelVolume::LLPanelVolume(const std::string& name)
- : LLPanel(name)
+LLPanelVolume::LLPanelVolume()
+ : LLPanel()
{
setMouseOpaque(FALSE);
@@ -317,7 +316,7 @@ void LLPanelVolume::getState( )
}
// static
-BOOL LLPanelVolume::precommitValidate( LLUICtrl* ctrl, void* userdata )
+bool LLPanelVolume::precommitValidate( const LLSD& data )
{
// TODO: Richard will fill this in later.
return TRUE; // FALSE means that validation failed and new value should not be commited.
@@ -427,21 +426,19 @@ void LLPanelVolume::sendIsFlexible()
llinfos << "update flexible sent" << llendl;
}
-void LLPanelVolume::onLightCancelColor(LLUICtrl* ctrl, void* userdata)
+void LLPanelVolume::onLightCancelColor(const LLSD& data)
{
- LLPanelVolume* self = (LLPanelVolume*) userdata;
- LLColorSwatchCtrl* LightColorSwatch = self->getChild<LLColorSwatchCtrl>("colorswatch");
+ LLColorSwatchCtrl* LightColorSwatch = getChild<LLColorSwatchCtrl>("colorswatch");
if(LightColorSwatch)
{
- LightColorSwatch->setColor(self->mLightSavedColor);
+ LightColorSwatch->setColor(mLightSavedColor);
}
- onLightSelectColor(NULL, userdata);
+ onLightSelectColor(data);
}
-void LLPanelVolume::onLightSelectColor(LLUICtrl* ctrl, void* userdata)
+void LLPanelVolume::onLightSelectColor(const LLSD& data)
{
- LLPanelVolume* self = (LLPanelVolume*) userdata;
- LLViewerObject* objectp = self->mObject;
+ LLViewerObject* objectp = mObject;
if (!objectp || (objectp->getPCode() != LL_PCODE_VOLUME))
{
return;
@@ -449,13 +446,13 @@ void LLPanelVolume::onLightSelectColor(LLUICtrl* ctrl, void* userdata)
LLVOVolume *volobjp = (LLVOVolume *)objectp;
- LLColorSwatchCtrl* LightColorSwatch = self->getChild<LLColorSwatchCtrl>("colorswatch");
+ LLColorSwatchCtrl* LightColorSwatch = getChild<LLColorSwatchCtrl>("colorswatch");
if(LightColorSwatch)
{
LLColor4 clr = LightColorSwatch->get();
LLColor3 clr3( clr );
volobjp->setLightColor(clr3);
- self->mLightSavedColor = clr;
+ mLightSavedColor = clr;
}
}
diff --git a/indra/newview/llpanelvolume.h b/indra/newview/llpanelvolume.h
index 841880b147..f285141bbe 100644
--- a/indra/newview/llpanelvolume.h
+++ b/indra/newview/llpanelvolume.h
@@ -35,7 +35,7 @@
#include "v3math.h"
#include "llpanel.h"
-#include "llmemory.h"
+#include "llpointer.h"
#include "llvolume.h"
class LLSpinCtrl;
@@ -51,7 +51,7 @@ class LLColorSwatchCtrl;
class LLPanelVolume : public LLPanel
{
public:
- LLPanelVolume(const std::string& name);
+ LLPanelVolume();
virtual ~LLPanelVolume();
virtual void draw();
@@ -64,15 +64,15 @@ public:
void sendIsLight();
void sendIsFlexible();
- static BOOL precommitValidate(LLUICtrl* ctrl,void* userdata);
+ static bool precommitValidate(const LLSD& data);
static void onCommitIsLight( LLUICtrl* ctrl, void* userdata);
static void onCommitLight( LLUICtrl* ctrl, void* userdata);
static void onCommitIsFlexible( LLUICtrl* ctrl, void* userdata);
static void onCommitFlexible( LLUICtrl* ctrl, void* userdata);
- static void onLightCancelColor(LLUICtrl* ctrl, void* userdata);
- static void onLightSelectColor(LLUICtrl* ctrl, void* userdata);
+ void onLightCancelColor(const LLSD& data);
+ void onLightSelectColor(const LLSD& data);
protected:
void getState();
diff --git a/indra/newview/llparcelselection.h b/indra/newview/llparcelselection.h
index 5f26fafc33..0481bea6f7 100644
--- a/indra/newview/llparcelselection.h
+++ b/indra/newview/llparcelselection.h
@@ -33,7 +33,8 @@
#ifndef LLPARCELSELECTION_H
#define LLPARCELSELECTION_H
-#include "llmemory.h"
+#include "llrefcount.h"
+#include "llsafehandle.h"
class LLParcel;
diff --git a/indra/newview/llpreview.cpp b/indra/newview/llpreview.cpp
index 6d7082bf9a..ab253e012d 100644
--- a/indra/newview/llpreview.cpp
+++ b/indra/newview/llpreview.cpp
@@ -34,11 +34,13 @@
#include "stdenums.h"
#include "llpreview.h"
+
#include "lllineeditor.h"
#include "llinventory.h"
#include "llinventorymodel.h"
#include "llresmgr.h"
#include "lltextbox.h"
+#include "llfloaterreg.h"
#include "llfocusmgr.h"
#include "lltooldraganddrop.h"
#include "llradiogroup.h"
@@ -47,129 +49,72 @@
#include "llviewerobjectlist.h"
#include "lldbstrings.h"
#include "llagent.h"
-#include "llvoavatar.h"
+#include "llvoavatarself.h"
#include "llselectmgr.h"
-#include "llinventoryview.h"
#include "llviewerinventory.h"
+#include "llviewerwindow.h"
+#include "lltrans.h"
// Constants
-// Globals and statics
-LLPreview::preview_multimap_t LLPreview::sPreviewsBySource;
-LLPreview::preview_map_t LLPreview::sInstances;
-std::map<LLUUID, LLHandle<LLFloater> > LLMultiPreview::sAutoOpenPreviewHandles;
-
-// Functions
-LLPreview::LLPreview(const std::string& name) :
- LLFloater(name),
- mCopyToInvBtn(NULL),
+LLPreview::LLPreview(const LLSD& key)
+: LLFloater(key),
+ mItemUUID(key.asUUID()),
+ mObjectUUID(), // set later by setObjectID()
+ mCopyToInvBtn( NULL ),
mForceClose(FALSE),
mUserResized(FALSE),
mCloseAfterSave(FALSE),
mAssetStatus(PREVIEW_ASSET_UNLOADED),
- mItem(NULL),
mDirty(TRUE)
{
- // don't add to instance list, since ItemID is null
- mAuxItem = new LLInventoryItem; // (LLPointer is auto-deleted)
+ mAuxItem = new LLInventoryItem;
// don't necessarily steal focus on creation -- sometimes these guys pop up without user action
setAutoFocus(FALSE);
+
gInventory.addObserver(this);
+
+ refreshFromItem();
}
-LLPreview::LLPreview(const std::string& name, const LLRect& rect, const std::string& title, const LLUUID& item_uuid, const LLUUID& object_uuid, BOOL allow_resize, S32 min_width, S32 min_height, LLPointer<LLViewerInventoryItem> inv_item )
-: LLFloater(name, rect, title, allow_resize, min_width, min_height ),
- mItemUUID(item_uuid),
- mSourceID(LLUUID::null),
- mObjectUUID(object_uuid),
- mCopyToInvBtn( NULL ),
- mForceClose( FALSE ),
- mUserResized(FALSE),
- mCloseAfterSave(FALSE),
- mAssetStatus(PREVIEW_ASSET_UNLOADED),
- mItem(inv_item),
- mDirty(TRUE)
+BOOL LLPreview::postBuild()
{
- mAuxItem = new LLInventoryItem;
- // don't necessarily steal focus on creation -- sometimes these guys pop up without user action
- setAutoFocus(FALSE);
-
- if (mItemUUID.notNull())
- {
- sInstances[mItemUUID] = this;
- }
- gInventory.addObserver(this);
+ refreshFromItem();
+ return TRUE;
}
LLPreview::~LLPreview()
{
gFocusMgr.releaseFocusIfNeeded( this ); // calls onCommit()
-
- if (mItemUUID.notNull())
- {
- sInstances.erase( mItemUUID );
- }
-
- if (mSourceID.notNull())
- {
- preview_multimap_t::iterator found_it = sPreviewsBySource.find(mSourceID);
- for (; found_it != sPreviewsBySource.end(); ++found_it)
- {
- if (found_it->second == getHandle())
- {
- sPreviewsBySource.erase(found_it);
- break;
- }
- }
- }
gInventory.removeObserver(this);
}
-void LLPreview::setItemID(const LLUUID& item_id)
-{
- if (mItemUUID.notNull())
- {
- sInstances.erase(mItemUUID);
- }
-
- mItemUUID = item_id;
-
- if (mItemUUID.notNull())
- {
- sInstances[mItemUUID] = this;
- }
-}
-
void LLPreview::setObjectID(const LLUUID& object_id)
{
mObjectUUID = object_id;
+ if (getAssetStatus() == PREVIEW_ASSET_UNLOADED)
+ {
+ loadAsset();
+ }
}
-void LLPreview::setSourceID(const LLUUID& source_id)
+void LLPreview::setItem( LLInventoryItem* item )
{
- if (mSourceID.notNull())
+ mItem = item;
+ if (mItem && getAssetStatus() == PREVIEW_ASSET_UNLOADED)
{
- // erase old one
- preview_multimap_t::iterator found_it = sPreviewsBySource.find(mSourceID);
- for (; found_it != sPreviewsBySource.end(); ++found_it)
- {
- if (found_it->second == getHandle())
- {
- sPreviewsBySource.erase(found_it);
- break;
- }
- }
+ loadAsset();
}
- mSourceID = source_id;
- sPreviewsBySource.insert(preview_multimap_t::value_type(mSourceID, getHandle()));
}
-const LLViewerInventoryItem *LLPreview::getItem() const
+const LLInventoryItem *LLPreview::getItem() const
{
- if(mItem)
- return mItem;
- const LLViewerInventoryItem *item = NULL;
- if(mObjectUUID.isNull())
+ const LLInventoryItem *item = NULL;
+ if (mItem.notNull())
+ {
+ item = mItem;
+ }
+ else if (mObjectUUID.isNull())
{
// it's an inventory item, so get the item.
item = gInventory.getItem(mItemUUID);
@@ -180,7 +125,7 @@ const LLViewerInventoryItem *LLPreview::getItem() const
LLViewerObject* object = gObjectList.findObject(mObjectUUID);
if(object)
{
- item = (LLViewerInventoryItem*)object->getInventoryObject(mItemUUID);
+ item = dynamic_cast<LLInventoryItem*>(object->getInventoryObject(mItemUUID));
}
}
return item;
@@ -189,7 +134,7 @@ const LLViewerInventoryItem *LLPreview::getItem() const
// Sub-classes should override this function if they allow editing
void LLPreview::onCommit()
{
- const LLViewerInventoryItem *item = getItem();
+ const LLViewerInventoryItem *item = dynamic_cast<const LLViewerInventoryItem*>(getItem());
if(item)
{
if (!item->isComplete())
@@ -226,7 +171,7 @@ void LLPreview::onCommit()
// update the object itself.
if( item->getType() == LLAssetType::AT_OBJECT )
{
- LLVOAvatar* avatar = gAgent.getAvatarObject();
+ LLVOAvatarSelf* avatar = gAgent.getAvatarObject();
if( avatar )
{
LLViewerObject* obj = avatar->getWornAttachment( item->getUUID() );
@@ -249,23 +194,37 @@ void LLPreview::changed(U32 mask)
mDirty = TRUE;
}
+void LLPreview::setNotecardInfo(const LLUUID& notecard_inv_id,
+ const LLUUID& object_id)
+{
+ mNotecardInventoryID = notecard_inv_id;
+ mNotecardObjectID = object_id;
+}
+
void LLPreview::draw()
{
LLFloater::draw();
if (mDirty)
{
mDirty = FALSE;
- const LLViewerInventoryItem *item = getItem();
- if (item)
- {
- refreshFromItem(item);
- }
+ refreshFromItem();
}
}
-void LLPreview::refreshFromItem(const LLInventoryItem* item)
+void LLPreview::refreshFromItem()
{
- setTitle(llformat("%s: %s",getTitleName(),item->getName().c_str()));
+ const LLInventoryItem* item = getItem();
+ if (!item)
+ {
+ return;
+ }
+ if (hasString("Title"))
+ {
+ LLStringUtil::format_map_t args;
+ args["[NAME]"] = item->getName();
+ LLUIString title = getString("Title", args);
+ setTitle(title.getString());
+ }
childSetText("desc",item->getDescription());
BOOL can_agent_manipulate = item->getPermissions().allowModifyBy(gAgent.getID());
@@ -287,80 +246,32 @@ void LLPreview::onRadio(LLUICtrl*, void* userdata)
}
// static
-LLPreview* LLPreview::find(const LLUUID& item_uuid)
-{
- LLPreview* instance = NULL;
- preview_map_t::iterator found_it = LLPreview::sInstances.find(item_uuid);
- if(found_it != LLPreview::sInstances.end())
- {
- instance = found_it->second;
- }
- return instance;
-}
-
-// static
-LLPreview* LLPreview::show( const LLUUID& item_uuid, BOOL take_focus )
-{
- LLPreview* instance = LLPreview::find(item_uuid);
- if(instance)
- {
- if (LLFloater::getFloaterHost() && LLFloater::getFloaterHost() != instance->getHost())
- {
- // this preview window is being opened in a new context
- // needs to be rehosted
- LLFloater::getFloaterHost()->addFloater(instance, TRUE);
- }
- instance->open(); /*Flawfinder: ignore*/
- if (take_focus)
- {
- instance->setFocus(TRUE);
- }
- }
-
- return instance;
-}
-
-// static
-bool LLPreview::save( const LLUUID& item_uuid, LLPointer<LLInventoryItem>* itemptr )
-{
- bool res = false;
- LLPreview* instance = LLPreview::find(item_uuid);
- if(instance)
- {
- res = instance->saveItem(itemptr);
- }
- if (!res)
- {
- delete itemptr;
- }
- return res;
-}
-
-// static
void LLPreview::hide(const LLUUID& item_uuid, BOOL no_saving /* = FALSE */ )
{
- preview_map_t::iterator found_it = LLPreview::sInstances.find(item_uuid);
- if(found_it != LLPreview::sInstances.end())
+ LLFloater* floater = LLFloaterReg::findInstance("preview", LLSD(item_uuid));
+ if (!floater) floater = LLFloaterReg::findInstance("preview_avatar", LLSD(item_uuid));
+
+ LLPreview* preview = dynamic_cast<LLPreview*>(floater);
+ if (preview)
{
- LLPreview* instance = found_it->second;
-
if ( no_saving )
{
- instance->mForceClose = TRUE;
+ preview->mForceClose = TRUE;
}
-
- instance->close();
+ preview->closeFloater();
}
}
// static
-void LLPreview::rename(const LLUUID& item_uuid, const std::string& new_name)
+void LLPreview::dirty(const LLUUID& item_uuid)
{
- preview_map_t::iterator found_it = LLPreview::sInstances.find(item_uuid);
- if(found_it != LLPreview::sInstances.end())
+ LLFloater* floater = LLFloaterReg::findInstance("preview", LLSD(item_uuid));
+ if (!floater) floater = LLFloaterReg::findInstance("preview_avatar", LLSD(item_uuid));
+
+ LLPreview* preview = dynamic_cast<LLPreview*>(floater);
+ if(preview)
{
- LLPreview* instance = found_it->second;
- instance->setTitle( new_name );
+ preview->mDirty = TRUE;
}
}
@@ -397,7 +308,7 @@ BOOL LLPreview::handleHover(S32 x, S32 y, MASK mask)
{
S32 screen_x;
S32 screen_y;
- const LLViewerInventoryItem *item = getItem();
+ const LLInventoryItem *item = getItem();
localPointToScreen(x, y, &screen_x, &screen_y );
if(item
@@ -426,22 +337,20 @@ BOOL LLPreview::handleHover(S32 x, S32 y, MASK mask)
return LLFloater::handleHover(x,y,mask);
}
-void LLPreview::open() /*Flawfinder: ignore*/
+void LLPreview::onOpen(const LLSD& key)
{
if (!getFloaterHost() && !getHost() && getAssetStatus() == PREVIEW_ASSET_UNLOADED)
{
loadAsset();
}
- LLFloater::open(); /*Flawfinder: ignore*/
}
-// virtual
-bool LLPreview::saveItem(LLPointer<LLInventoryItem>* itemptr)
+void LLPreview::setAuxItem( const LLInventoryItem* item )
{
- return false;
+ if ( mAuxItem )
+ mAuxItem->copyItem(item);
}
-
// static
void LLPreview::onBtnCopyToInv(void* userdata)
{
@@ -453,7 +362,7 @@ void LLPreview::onBtnCopyToInv(void* userdata)
// Copy to inventory
if (self->mNotecardInventoryID.notNull())
{
- copy_inventory_from_notecard(self->mObjectID,
+ copy_inventory_from_notecard(self->mNotecardObjectID,
self->mNotecardInventoryID, item);
}
else
@@ -468,14 +377,14 @@ void LLPreview::onBtnCopyToInv(void* userdata)
cb);
}
}
- self->close();
+ self->closeFloater();
}
// static
void LLPreview::onKeepBtn(void* data)
{
LLPreview* self = (LLPreview*)data;
- self->close();
+ self->closeFloater();
}
// static
@@ -483,11 +392,11 @@ void LLPreview::onDiscardBtn(void* data)
{
LLPreview* self = (LLPreview*)data;
- const LLViewerInventoryItem* item = self->getItem();
+ const LLInventoryItem* item = self->getItem();
if (!item) return;
self->mForceClose = TRUE;
- self->close();
+ self->closeFloater();
// Delete the item entirely
/*
@@ -517,55 +426,60 @@ void LLPreview::onDiscardBtn(void* data)
}
}
-//static
-LLPreview* LLPreview::getFirstPreviewForSource(const LLUUID& source_id)
+void LLPreview::handleReshape(const LLRect& new_rect, bool by_user)
{
- preview_multimap_t::iterator found_it = sPreviewsBySource.find(source_id);
- if (found_it != sPreviewsBySource.end())
- {
- // just return first one
- return (LLPreview*)found_it->second.get();
- }
- return NULL;
-}
-
-void LLPreview::userSetShape(const LLRect& new_rect)
-{
- if(new_rect.getWidth() != getRect().getWidth() || new_rect.getHeight() != getRect().getHeight())
+ if(by_user
+ && (new_rect.getWidth() != getRect().getWidth() || new_rect.getHeight() != getRect().getHeight()))
{
userResized();
}
- LLFloater::userSetShape(new_rect);
+ LLFloater::handleReshape(new_rect, by_user);
}
//
// LLMultiPreview
//
-LLMultiPreview::LLMultiPreview(const LLRect& rect) : LLMultiFloater(std::string("Preview"), rect)
+LLMultiPreview::LLMultiPreview()
+ : LLMultiFloater(LLSD())
{
+ // *TODO: There should be a .xml file for this
+ const LLRect& nextrect = LLFloaterReg::getFloaterRect("preview"); // place where the next preview should show up
+ if (nextrect.getWidth() > 0)
+ {
+ setRect(nextrect);
+ }
+ else
+ {
+ // start with a rect in the top-left corner ; will get resized
+ LLRect rect;
+ rect.setLeftTopAndSize(0, gViewerWindow->getWindowHeight(), 200, 200);
+ setRect(rect);
+ }
+ setTitle(LLTrans::getString("MultiPreviewTitle"));
+ buildTabContainer();
setCanResize(TRUE);
}
-void LLMultiPreview::open() /*Flawfinder: ignore*/
+void LLMultiPreview::onOpen(const LLSD& key)
{
- LLMultiFloater::open(); /*Flawfinder: ignore*/
LLPreview* frontmost_preview = (LLPreview*)mTabContainer->getCurrentPanel();
if (frontmost_preview && frontmost_preview->getAssetStatus() == LLPreview::PREVIEW_ASSET_UNLOADED)
{
frontmost_preview->loadAsset();
}
+ LLMultiFloater::onOpen(key);
}
-void LLMultiPreview::userSetShape(const LLRect& new_rect)
+void LLMultiPreview::handleReshape(const LLRect& new_rect, bool by_user)
{
if(new_rect.getWidth() != getRect().getWidth() || new_rect.getHeight() != getRect().getHeight())
{
LLPreview* frontmost_preview = (LLPreview*)mTabContainer->getCurrentPanel();
if (frontmost_preview) frontmost_preview->userResized();
}
- LLFloater::userSetShape(new_rect);
+ LLFloater::handleReshape(new_rect, by_user);
}
@@ -578,22 +492,3 @@ void LLMultiPreview::tabOpen(LLFloater* opened_floater, bool from_click)
}
}
-//static
-LLMultiPreview* LLMultiPreview::getAutoOpenInstance(const LLUUID& id)
-{
- handle_map_t::iterator found_it = sAutoOpenPreviewHandles.find(id);
- if (found_it != sAutoOpenPreviewHandles.end())
- {
- return (LLMultiPreview*)found_it->second.get();
- }
- return NULL;
-}
-
-//static
-void LLMultiPreview::setAutoOpenInstance(LLMultiPreview* previewp, const LLUUID& id)
-{
- if (previewp)
- {
- sAutoOpenPreviewHandles[id] = previewp->getHandle();
- }
-}
diff --git a/indra/newview/llpreview.h b/indra/newview/llpreview.h
index ff084bea27..c5f2bfcf47 100644
--- a/indra/newview/llpreview.h
+++ b/indra/newview/llpreview.h
@@ -33,15 +33,14 @@
#ifndef LL_LLPREVIEW_H
#define LL_LLPREVIEW_H
-#include "llfloater.h"
+#include "llmultifloater.h"
#include "llresizehandle.h"
-#include "llmap.h"
+#include "llpointer.h"
#include "lluuid.h"
-#include "llviewerinventory.h"
-#include "lltabcontainer.h"
-#include "llinventorymodel.h"
+#include "llinventorymodel.h" // LLInventoryObserver
#include <map>
+class LLInventoryItem;
class LLLineEditor;
class LLRadioGroup;
class LLPreview;
@@ -49,18 +48,12 @@ class LLPreview;
class LLMultiPreview : public LLMultiFloater
{
public:
- LLMultiPreview(const LLRect& rect);
+ LLMultiPreview();
- /*virtual*/void open(); /*Flawfinder: ignore*/
+ /*virtual*/void onOpen(const LLSD& key);
/*virtual*/void tabOpen(LLFloater* opened_floater, bool from_click);
- /*virtual*/ void userSetShape(const LLRect& new_rect);
+ /*virtual*/ void handleReshape(const LLRect& new_rect, bool by_user = false);
- static LLMultiPreview* getAutoOpenInstance(const LLUUID& id);
- static void setAutoOpenInstance(LLMultiPreview* previewp, const LLUUID& id);
-
-protected:
- typedef std::map<LLUUID, LLHandle<LLFloater> > handle_map_t;
- static handle_map_t sAutoOpenPreviewHandles;
};
// https://wiki.lindenlab.com/mediawiki/index.php?title=LLPreview&oldid=81373
@@ -76,40 +69,32 @@ public:
PREVIEW_ASSET_LOADED
} EAssetStatus;
public:
- // Used for XML-based construction.
- LLPreview(const std::string& name);
- LLPreview(const std::string& name, const LLRect& rect, const std::string& title, const LLUUID& item_uuid, const LLUUID& object_uuid, BOOL allow_resize = FALSE, S32 min_width = 0, S32 min_height = 0, LLPointer<LLViewerInventoryItem> inv_item = NULL );
+ LLPreview(const LLSD& key );
virtual ~LLPreview();
-
- void setItemID(const LLUUID& item_id);
+
+ /*virtual*/ BOOL postBuild();
+
void setObjectID(const LLUUID& object_id);
- void setSourceID(const LLUUID& source_id);
- const LLViewerInventoryItem *getItem() const; // searches if not constructed with it
-
- static LLPreview* find(const LLUUID& item_uuid);
- static LLPreview* show(const LLUUID& item_uuid, BOOL take_focus = TRUE );
- static void hide(const LLUUID& item_uuid, BOOL no_saving = FALSE );
- static void rename(const LLUUID& item_uuid, const std::string& new_name);
- static bool save(const LLUUID& item_uuid, LLPointer<LLInventoryItem>* itemptr);
+ void setItem( LLInventoryItem* item );
+
+ const LLInventoryItem* getItem() const; // searches if not constructed with it
+ static void hide(const LLUUID& item_uuid, BOOL no_saving = FALSE );
+ static void dirty(const LLUUID& item_uuid);
+
virtual BOOL handleMouseDown(S32 x, S32 y, MASK mask);
virtual BOOL handleMouseUp(S32 x, S32 y, MASK mask);
virtual BOOL handleHover(S32 x, S32 y, MASK mask);
- virtual void open(); /*Flawfinder: ignore*/
- virtual bool saveItem(LLPointer<LLInventoryItem>* itemptr);
-
- void setAuxItem( const LLInventoryItem* item )
- {
- if ( mAuxItem )
- mAuxItem->copyItem(item);
- }
+ virtual void onOpen(const LLSD& key);
+
+ void setAuxItem( const LLInventoryItem* item );
static void onBtnCopyToInv(void* userdata);
void addKeepDiscardButtons();
static void onKeepBtn(void* data);
static void onDiscardBtn(void* data);
- /*virtual*/ void userSetShape(const LLRect& new_rect);
+ /*virtual*/ void handleReshape(const LLRect& new_rect, bool by_user = false);
void userResized() { mUserResized = TRUE; };
@@ -117,12 +102,13 @@ public:
virtual EAssetStatus getAssetStatus() { return mAssetStatus;}
static LLPreview* getFirstPreviewForSource(const LLUUID& source_id);
- void setNotecardInfo(const LLUUID& notecard_inv_id, const LLUUID& object_id)
- { mNotecardInventoryID = notecard_inv_id; mObjectID = object_id; }
+
+ // Why is this at the LLPreview level? JC
+ void setNotecardInfo(const LLUUID& notecard_inv_id, const LLUUID& object_id);
// llview
- virtual void draw();
- void refreshFromItem(const LLInventoryItem* item);
+ /*virtual*/ void draw();
+ void refreshFromItem();
protected:
virtual void onCommit();
@@ -135,13 +121,11 @@ protected:
// for LLInventoryObserver
virtual void changed(U32 mask);
BOOL mDirty;
- virtual const char *getTitleName() const { return "Preview"; }
protected:
LLUUID mItemUUID;
- LLUUID mSourceID;
- // mObjectID will have a value if it is associated with a task in
+ // mObjectUUID will have a value if it is associated with a task in
// the world, and will be == LLUUID::null if it's in the agent
// inventory.
LLUUID mObjectUUID;
@@ -149,6 +133,7 @@ protected:
LLRect mClientRect;
LLPointer<LLInventoryItem> mAuxItem; // HACK!
+ LLPointer<LLInventoryItem> mItem; // For embedded items (Landmarks)
LLButton* mCopyToInvBtn;
// Close without saving changes
@@ -162,27 +147,20 @@ protected:
EAssetStatus mAssetStatus;
- typedef std::map<LLUUID, LLPreview*> preview_map_t;
- typedef std::multimap<LLUUID, LLHandle<LLFloater> > preview_multimap_t;
-
- static preview_multimap_t sPreviewsBySource;
- static preview_map_t sInstances;
LLUUID mNotecardInventoryID;
- LLUUID mObjectID;
- LLPointer<LLViewerInventoryItem> mItem;
+ // I am unsure if this is always the same as mObjectUUID, or why it exists
+ // at the LLPreview level. JC 2009-06-24
+ LLUUID mNotecardObjectID;
};
const S32 PREVIEW_BORDER = 4;
const S32 PREVIEW_PAD = 5;
-const S32 PREVIEW_BUTTON_WIDTH = 100;
const S32 PREVIEW_LINE_HEIGHT = 19;
-const S32 PREVIEW_CLOSE_BOX_SIZE = 16;
const S32 PREVIEW_BORDER_WIDTH = 2;
const S32 PREVIEW_RESIZE_HANDLE_SIZE = S32(RESIZE_HANDLE_WIDTH * OO_SQRT2) + PREVIEW_BORDER_WIDTH;
const S32 PREVIEW_VPAD = 2;
-const S32 PREVIEW_HPAD = PREVIEW_RESIZE_HANDLE_SIZE;
const S32 PREVIEW_HEADER_SIZE = 2*PREVIEW_LINE_HEIGHT + 2 * PREVIEW_VPAD;
#endif // LL_LLPREVIEW_H
diff --git a/indra/newview/llpreviewanim.cpp b/indra/newview/llpreviewanim.cpp
index 3212de0639..3bda30e0c6 100644
--- a/indra/newview/llpreviewanim.cpp
+++ b/indra/newview/llpreviewanim.cpp
@@ -36,8 +36,7 @@
#include "llbutton.h"
#include "llresmgr.h"
#include "llinventory.h"
-#include "llinventoryview.h"
-#include "llvoavatar.h"
+#include "llvoavatarself.h"
#include "llagent.h" // gAgent
#include "llkeyframemotion.h"
#include "llfilepicker.h"
@@ -47,42 +46,56 @@
extern LLAgent gAgent;
-LLPreviewAnim::LLPreviewAnim(const std::string& name, const LLRect& rect, const std::string& title, const LLUUID& item_uuid, const S32& activate, const LLUUID& object_uuid ) :
- LLPreview( name, rect, title, item_uuid, object_uuid)
+LLPreviewAnim::LLPreviewAnim(const LLSD& key)
+ : LLPreview( key )
{
- LLUICtrlFactory::getInstance()->buildFloater(this,"floater_preview_animation.xml");
-
- childSetAction("Anim play btn",playAnim,this);
- childSetAction("Anim audition btn",auditionAnim,this);
-
- const LLInventoryItem* item = getItem();
-
- childSetCommitCallback("desc", LLPreview::onText, this);
- childSetText("desc", item->getDescription());
- childSetPrevalidate("desc", &LLLineEditor::prevalidatePrintableNotPipe);
-
- setTitle(title);
+ //Called from floater reg: LLUICtrlFactory::getInstance()->buildFloater(this,"floater_preview_animation.xml", FALSE);
+}
- if (!getHost())
+// static
+void LLPreviewAnim::endAnimCallback( void *userdata )
+{
+ LLHandle<LLFloater>* handlep = ((LLHandle<LLFloater>*)userdata);
+ LLFloater* self = handlep->get();
+ delete handlep; // done with the handle
+ if (self)
{
- LLRect curRect = getRect();
- translate(rect.mLeft - curRect.mLeft, rect.mTop - curRect.mTop);
+ self->childSetValue("Anim play btn", FALSE);
+ self->childSetValue("Anim audition btn", FALSE);
}
+}
- // preload the animation
+// virtual
+BOOL LLPreviewAnim::postBuild()
+{
+ mCloseSignal.connect(boost::bind(&LLPreviewAnim::onClose, this));
+
+ const LLInventoryItem* item = getItem();
if(item)
{
- gAgent.getAvatarObject()->createMotion(item->getAssetUUID());
+ gAgent.getAvatarObject()->createMotion(item->getAssetUUID()); // preload the animation
+ childSetText("desc", item->getDescription());
}
+
+ childSetAction("Anim play btn",playAnim, this);
+ childSetAction("Anim audition btn",auditionAnim, this);
+
+ childSetCommitCallback("desc", LLPreview::onText, this);
+ childSetPrevalidate("desc", &LLLineEditor::prevalidatePrintableNotPipe);
- switch ( activate )
+ return LLPreview::postBuild();
+}
+
+void LLPreviewAnim::activate(e_activation_type type)
+{
+ switch ( type )
{
- case 1:
+ case PLAY:
{
playAnim( (void *) this );
break;
}
- case 2:
+ case AUDITION:
{
auditionAnim( (void *) this );
break;
@@ -95,19 +108,6 @@ LLPreviewAnim::LLPreviewAnim(const std::string& name, const LLRect& rect, const
}
// static
-void LLPreviewAnim::endAnimCallback( void *userdata )
-{
- LLHandle<LLFloater>* handlep = ((LLHandle<LLFloater>*)userdata);
- LLFloater* self = handlep->get();
- delete handlep; // done with the handle
- if (self)
- {
- self->childSetValue("Anim play btn", FALSE);
- self->childSetValue("Anim audition btn", FALSE);
- }
-}
-
-// static
void LLPreviewAnim::playAnim( void *userdata )
{
LLPreviewAnim* self = (LLPreviewAnim*) userdata;
@@ -181,7 +181,7 @@ void LLPreviewAnim::auditionAnim( void *userdata )
}
}
-void LLPreviewAnim::onClose(bool app_quitting)
+void LLPreviewAnim::onClose()
{
const LLInventoryItem *item = getItem();
@@ -199,5 +199,4 @@ void LLPreviewAnim::onClose(bool app_quitting)
motion->setDeactivateCallback(NULL, (void *)NULL);
}
}
- destroy();
}
diff --git a/indra/newview/llpreviewanim.h b/indra/newview/llpreviewanim.h
index fe794d4283..d24e624c32 100644
--- a/indra/newview/llpreviewanim.h
+++ b/indra/newview/llpreviewanim.h
@@ -39,18 +39,17 @@
class LLPreviewAnim : public LLPreview
{
public:
- LLPreviewAnim(const std::string& name, const LLRect& rect, const std::string& title,
- const LLUUID& item_uuid,
- const S32& activate,
- const LLUUID& object_uuid = LLUUID::null);
+ enum e_activation_type { NONE = 0, PLAY = 1, AUDITION = 2 };
+ LLPreviewAnim(const LLSD& key);
static void playAnim( void* userdata );
static void auditionAnim( void* userdata );
static void endAnimCallback( void *userdata );
-
+ /*virtual*/ BOOL postBuild();
+ void activate(e_activation_type type);
+
protected:
- virtual void onClose(bool app_quitting);
- virtual const char *getTitleName() const { return "Animation"; }
+ void onClose();
LLAnimPauseRequest mPauseRequest;
LLUUID mItemID;
diff --git a/indra/newview/llpreviewgesture.cpp b/indra/newview/llpreviewgesture.cpp
index 76a9b80645..04827e3a78 100644
--- a/indra/newview/llpreviewgesture.cpp
+++ b/indra/newview/llpreviewgesture.cpp
@@ -41,11 +41,13 @@
#include "lldarray.h"
#include "llstring.h"
#include "lldir.h"
+#include "llfloaterreg.h"
#include "llmultigesture.h"
#include "llvfile.h"
// newview
#include "llagent.h" // todo: remove
+#include "llanimationstates.h"
#include "llassetuploadresponders.h"
#include "llbutton.h"
#include "llcheckboxctrl.h"
@@ -59,6 +61,8 @@
#include "llnotify.h"
#include "llradiogroup.h"
#include "llscrolllistctrl.h"
+#include "llscrolllistitem.h"
+#include "llscrolllistcell.h"
#include "lltextbox.h"
#include "lluictrlfactory.h"
#include "llviewerinventory.h"
@@ -67,15 +71,16 @@
#include "llviewerregion.h"
#include "llviewerstats.h"
#include "llviewerwindow.h" // busycount
+#include "llvoavatarself.h"
#include "llappviewer.h" // gVFS
#include "llanimstatelabels.h"
#include "llresmgr.h"
+#include "lltrans.h"
-// *TODO: Translate?
-const std::string NONE_LABEL = "---";
-const std::string SHIFT_LABEL = "Shift";
-const std::string CTRL_LABEL = "Ctrl";
+std::string NONE_LABEL;
+std::string SHIFT_LABEL;
+std::string CTRL_LABEL;
void dialog_refresh_all();
@@ -92,12 +97,9 @@ protected:
void LLInventoryGestureAvailable::done()
{
- LLPreview* preview = NULL;
- item_ref_t::iterator it = mComplete.begin();
- item_ref_t::iterator end = mComplete.end();
- for(; it < end; ++it)
+ for(item_ref_t::iterator it = mComplete.begin(); it != mComplete.end(); ++it)
{
- preview = LLPreview::find((*it));
+ LLPreviewGesture* preview = LLFloaterReg::findTypedInstance<LLPreviewGesture>("preview_gesture", *it);
if(preview)
{
preview->refresh();
@@ -117,43 +119,16 @@ struct SortItemPtrsByName
};
// static
-LLPreviewGesture* LLPreviewGesture::show(const std::string& title, const LLUUID& item_id, const LLUUID& object_id, BOOL take_focus)
+LLPreviewGesture* LLPreviewGesture::show(const LLUUID& item_id, const LLUUID& object_id)
{
- LLPreviewGesture* previewp = (LLPreviewGesture*)LLPreview::find(item_id);
- if (previewp)
+ LLPreviewGesture* preview = LLFloaterReg::showTypedInstance<LLPreviewGesture>("preview_gesture", LLSD(item_id), TAKE_FOCUS_YES);
+ if (!preview)
{
- previewp->open(); /*Flawfinder: ignore*/
- if (take_focus)
- {
- previewp->setFocus(TRUE);
- }
- return previewp;
- }
-
- LLPreviewGesture* self = new LLPreviewGesture();
-
- // Finish internal construction
- self->init(item_id, object_id);
-
- // Builds and adds to gFloaterView
- LLUICtrlFactory::getInstance()->buildFloater(self, "floater_preview_gesture.xml");
- self->setTitle(title);
-
- // Move window to top-left of screen
- LLMultiFloater* hostp = self->getHost();
- if (hostp == NULL)
- {
- LLRect r = self->getRect();
- LLRect screen = gFloaterView->getRect();
- r.setLeftTopAndSize(0, screen.getHeight(), r.getWidth(), r.getHeight());
- self->setRect(r);
+ return NULL;
}
- else
- {
- // re-add to host to update title
- hostp->addFloater(self, TRUE);
- }
-
+
+ preview->setObjectID(object_id);
+
// Start speculative download of sounds and animations
LLUUID animation_folder_id = gInventory.findCategoryUUIDForType(LLAssetType::AT_ANIMATION);
gInventory.startBackgroundFetch(animation_folder_id);
@@ -162,8 +137,8 @@ LLPreviewGesture* LLPreviewGesture::show(const std::string& title, const LLUUID&
gInventory.startBackgroundFetch(sound_folder_id);
// this will call refresh when we have everything.
- LLViewerInventoryItem* item = (LLViewerInventoryItem*)self->getItem();
- if(item && !item->isComplete())
+ LLViewerInventoryItem* item = (LLViewerInventoryItem*)preview->getItem();
+ if (item && !item->isComplete())
{
LLInventoryGestureAvailable* observer;
observer = new LLInventoryGestureAvailable();
@@ -174,18 +149,12 @@ LLPreviewGesture* LLPreviewGesture::show(const std::string& title, const LLUUID&
else
{
// not sure this is necessary.
- self->refresh();
+ preview->refresh();
}
- if (take_focus)
- {
- self->setFocus(TRUE);
- }
-
- return self;
+ return preview;
}
-
// virtual
BOOL LLPreviewGesture::handleKeyHere(KEY key, MASK mask)
{
@@ -291,11 +260,9 @@ BOOL LLPreviewGesture::canClose()
}
}
-// virtual
-void LLPreviewGesture::onClose(bool app_quitting)
+void LLPreviewGesture::onClose()
{
- gGestureManager.stopGesture(mPreviewGesture);
- LLPreview::onClose(app_quitting);
+ LLGestureManager::instance().stopGesture(mPreviewGesture);
}
// virtual
@@ -304,18 +271,11 @@ void LLPreviewGesture::onUpdateSucceeded()
refresh();
}
-// virtual
-void LLPreviewGesture::setMinimized(BOOL minimize)
+void LLPreviewGesture::onVisibilityChange ( const LLSD& new_visibility )
{
- if (minimize != isMinimized())
+ if (new_visibility.asBoolean())
{
- LLFloater::setMinimized(minimize);
-
- // We're being restored
- if (!minimize)
- {
- refresh();
- }
+ refresh();
}
}
@@ -326,15 +286,15 @@ bool LLPreviewGesture::handleSaveChangesDialog(const LLSD& notification, const L
switch(option)
{
case 0: // "Yes"
- gGestureManager.stopGesture(mPreviewGesture);
+ LLGestureManager::instance().stopGesture(mPreviewGesture);
mCloseAfterSave = TRUE;
onClickSave(this);
break;
case 1: // "No"
- gGestureManager.stopGesture(mPreviewGesture);
+ LLGestureManager::instance().stopGesture(mPreviewGesture);
mDirty = FALSE; // Force the dirty flag because user has clicked NO on confirm save dialog...
- close();
+ closeFloater();
break;
case 2: // "Cancel"
@@ -347,8 +307,8 @@ bool LLPreviewGesture::handleSaveChangesDialog(const LLSD& notification, const L
}
-LLPreviewGesture::LLPreviewGesture()
-: LLPreview("Gesture Preview"),
+LLPreviewGesture::LLPreviewGesture(const LLSD& key)
+: LLPreview(key),
mTriggerEditor(NULL),
mModifierCombo(NULL),
mKeyCombo(NULL),
@@ -368,6 +328,12 @@ LLPreviewGesture::LLPreviewGesture()
mPreviewGesture(NULL),
mDirty(FALSE)
{
+ NONE_LABEL = LLTrans::getString("---");
+ SHIFT_LABEL = LLTrans::getString("KBShift");
+ CTRL_LABEL = LLTrans::getString("KBCtrl");
+
+ //Called from floater reg: LLUICtrlFactory::getInstance()->buildFloater(this, "floater_preview_gesture.xml", FALSE);
+
}
@@ -388,6 +354,9 @@ LLPreviewGesture::~LLPreviewGesture()
BOOL LLPreviewGesture::postBuild()
{
+ mCloseSignal.connect(boost::bind(&LLPreviewGesture::onClose, this));
+ mVisibleSignal.connect(boost::bind(&LLPreviewGesture::onVisibilityChange, this, _2));
+
LLLineEditor* edit;
LLComboBox* combo;
LLButton* btn;
@@ -396,10 +365,9 @@ BOOL LLPreviewGesture::postBuild()
LLCheckBoxCtrl* check;
edit = getChild<LLLineEditor>("trigger_editor");
- edit->setKeystrokeCallback(onKeystrokeCommit);
- edit->setCommitCallback(onCommitSetDirty);
+ edit->setKeystrokeCallback(onKeystrokeCommit, this);
+ edit->setCommitCallback(onCommitSetDirty, this);
edit->setCommitOnFocusLost(TRUE);
- edit->setCallbackUserData(this);
edit->setIgnoreTab(TRUE);
mTriggerEditor = edit;
@@ -409,56 +377,47 @@ BOOL LLPreviewGesture::postBuild()
edit = getChild<LLLineEditor>("replace_editor");
edit->setEnabled(FALSE);
- edit->setKeystrokeCallback(onKeystrokeCommit);
- edit->setCommitCallback(onCommitSetDirty);
+ edit->setKeystrokeCallback(onKeystrokeCommit, this);
+ edit->setCommitCallback(onCommitSetDirty, this);
edit->setCommitOnFocusLost(TRUE);
- edit->setCallbackUserData(this);
edit->setIgnoreTab(TRUE);
mReplaceEditor = edit;
combo = getChild<LLComboBox>( "modifier_combo");
- combo->setCommitCallback(onCommitSetDirty);
- combo->setCallbackUserData(this);
+ combo->setCommitCallback(onCommitSetDirty, this);
mModifierCombo = combo;
combo = getChild<LLComboBox>( "key_combo");
- combo->setCommitCallback(onCommitSetDirty);
- combo->setCallbackUserData(this);
+ combo->setCommitCallback(onCommitSetDirty, this);
mKeyCombo = combo;
list = getChild<LLScrollListCtrl>("library_list");
- list->setCommitCallback(onCommitLibrary);
- list->setDoubleClickCallback(onClickAdd);
- list->setCallbackUserData(this);
+ list->setCommitCallback(onCommitLibrary, this);
+ list->setDoubleClickCallback(onClickAdd, this);
mLibraryList = list;
btn = getChild<LLButton>( "add_btn");
- btn->setClickedCallback(onClickAdd);
- btn->setCallbackUserData(this);
+ btn->setClickedCallback(onClickAdd, this);
btn->setEnabled(FALSE);
mAddBtn = btn;
btn = getChild<LLButton>( "up_btn");
- btn->setClickedCallback(onClickUp);
- btn->setCallbackUserData(this);
+ btn->setClickedCallback(onClickUp, this);
btn->setEnabled(FALSE);
mUpBtn = btn;
btn = getChild<LLButton>( "down_btn");
- btn->setClickedCallback(onClickDown);
- btn->setCallbackUserData(this);
+ btn->setClickedCallback(onClickDown, this);
btn->setEnabled(FALSE);
mDownBtn = btn;
btn = getChild<LLButton>( "delete_btn");
- btn->setClickedCallback(onClickDelete);
- btn->setCallbackUserData(this);
+ btn->setClickedCallback(onClickDelete, this);
btn->setEnabled(FALSE);
mDeleteBtn = btn;
list = getChild<LLScrollListCtrl>("step_list");
- list->setCommitCallback(onCommitStep);
- list->setCallbackUserData(this);
+ list->setCommitCallback(onCommitStep, this);
mStepList = list;
// Options
@@ -468,69 +427,59 @@ BOOL LLPreviewGesture::postBuild()
combo = getChild<LLComboBox>( "animation_list");
combo->setVisible(FALSE);
- combo->setCommitCallback(onCommitAnimation);
- combo->setCallbackUserData(this);
+ combo->setCommitCallback(onCommitAnimation, this);
mAnimationCombo = combo;
LLRadioGroup* group;
group = getChild<LLRadioGroup>("animation_trigger_type");
group->setVisible(FALSE);
- group->setCommitCallback(onCommitAnimationTrigger);
- group->setCallbackUserData(this);
+ group->setCommitCallback(onCommitAnimationTrigger, this);
mAnimationRadio = group;
combo = getChild<LLComboBox>( "sound_list");
combo->setVisible(FALSE);
- combo->setCommitCallback(onCommitSound);
- combo->setCallbackUserData(this);
+ combo->setCommitCallback(onCommitSound, this);
mSoundCombo = combo;
edit = getChild<LLLineEditor>("chat_editor");
edit->setVisible(FALSE);
- edit->setCommitCallback(onCommitChat);
- //edit->setKeystrokeCallback(onKeystrokeCommit);
+ edit->setCommitCallback(onCommitChat, this);
+ //edit->setKeystrokeCallback(onKeystrokeCommit, this);
edit->setCommitOnFocusLost(TRUE);
- edit->setCallbackUserData(this);
edit->setIgnoreTab(TRUE);
mChatEditor = edit;
check = getChild<LLCheckBoxCtrl>( "wait_anim_check");
check->setVisible(FALSE);
- check->setCommitCallback(onCommitWait);
- check->setCallbackUserData(this);
+ check->setCommitCallback(onCommitWait, this);
mWaitAnimCheck = check;
check = getChild<LLCheckBoxCtrl>( "wait_time_check");
check->setVisible(FALSE);
- check->setCommitCallback(onCommitWait);
- check->setCallbackUserData(this);
+ check->setCommitCallback(onCommitWait, this);
mWaitTimeCheck = check;
edit = getChild<LLLineEditor>("wait_time_editor");
edit->setEnabled(FALSE);
edit->setVisible(FALSE);
edit->setPrevalidate(LLLineEditor::prevalidateFloat);
-// edit->setKeystrokeCallback(onKeystrokeCommit);
+// edit->setKeystrokeCallback(onKeystrokeCommit, this);
edit->setCommitOnFocusLost(TRUE);
- edit->setCommitCallback(onCommitWaitTime);
- edit->setCallbackUserData(this);
+ edit->setCommitCallback(onCommitWaitTime, this);
edit->setIgnoreTab(TRUE);
mWaitTimeEditor = edit;
// Buttons at the bottom
check = getChild<LLCheckBoxCtrl>( "active_check");
- check->setCommitCallback(onCommitActive);
- check->setCallbackUserData(this);
+ check->setCommitCallback(onCommitActive, this);
mActiveCheck = check;
btn = getChild<LLButton>( "save_btn");
- btn->setClickedCallback(onClickSave);
- btn->setCallbackUserData(this);
+ btn->setClickedCallback(onClickSave, this);
mSaveBtn = btn;
btn = getChild<LLButton>( "preview_btn");
- btn->setClickedCallback(onClickPreview);
- btn->setCallbackUserData(this);
+ btn->setClickedCallback(onClickPreview, this);
mPreviewBtn = btn;
@@ -540,7 +489,6 @@ BOOL LLPreviewGesture::postBuild()
addAnimations();
addSounds();
-
const LLInventoryItem* item = getItem();
if (item)
@@ -550,7 +498,7 @@ BOOL LLPreviewGesture::postBuild()
childSetPrevalidate("desc", &LLLineEditor::prevalidatePrintableNotPipe);
}
- return TRUE;
+ return LLPreview::postBuild();
}
@@ -605,7 +553,7 @@ void LLPreviewGesture::addAnimations()
PERM_ITEM_UNRESTRICTED,
gAgent.getID(),
gAgent.getGroupID());
- gInventory.collectDescendentsIf(gAgent.getInventoryRootID(),
+ gInventory.collectDescendentsIf(gInventory.getRootFolderID(),
cats,
items,
LLInventoryModel::EXCLUDE_TRASH,
@@ -650,7 +598,7 @@ void LLPreviewGesture::addSounds()
PERM_ITEM_UNRESTRICTED,
gAgent.getID(),
gAgent.getGroupID());
- gInventory.collectDescendentsIf(gAgent.getInventoryRootID(),
+ gInventory.collectDescendentsIf(gInventory.getRootFolderID(),
cats,
items,
LLInventoryModel::EXCLUDE_TRASH,
@@ -680,16 +628,9 @@ void LLPreviewGesture::addSounds()
}
-void LLPreviewGesture::init(const LLUUID& item_id, const LLUUID& object_id)
-{
- // Sets ID and adds to instance list
- setItemID(item_id);
- setObjectID(object_id);
-}
-
-
void LLPreviewGesture::refresh()
{
+ LLPreview::refresh();
// If previewing or item is incomplete, all controls are disabled
LLViewerInventoryItem* item = (LLViewerInventoryItem*)getItem();
bool is_complete = (item && item->isComplete()) ? true : false;
@@ -831,7 +772,7 @@ void LLPreviewGesture::refresh()
mOptionsText->setText(optionstext);
- BOOL active = gGestureManager.isGestureActive(mItemUUID);
+ BOOL active = LLGestureManager::instance().isGestureActive(mItemUUID);
mActiveCheck->set(active);
// Can only preview if there are steps
@@ -850,7 +791,7 @@ void LLPreviewGesture::initDefaultGesture()
item = addStep( STEP_ANIMATION );
LLGestureStepAnimation* anim = (LLGestureStepAnimation*)item->getUserdata();
anim->mAnimAssetID = ANIM_AGENT_HELLO;
- anim->mAnimName = "Wave";
+ anim->mAnimName = LLTrans::getString("Wave");
updateLabel(item);
item = addStep( STEP_WAIT );
@@ -860,7 +801,7 @@ void LLPreviewGesture::initDefaultGesture()
item = addStep( STEP_CHAT );
LLGestureStepChat* chat_step = (LLGestureStepChat*)item->getUserdata();
- chat_step->mChatText = "Hello, avatar!";
+ chat_step->mChatText = LLTrans::getString("HelloAvatar");
updateLabel(item);
// Start with item list selected
@@ -874,7 +815,11 @@ void LLPreviewGesture::initDefaultGesture()
void LLPreviewGesture::loadAsset()
{
const LLInventoryItem* item = getItem();
- if (!item) return;
+ if (!item)
+ {
+ mAssetStatus = PREVIEW_ASSET_ERROR;
+ return;
+ }
LLUUID asset_id = item->getAssetUUID();
if (asset_id.isNull())
@@ -883,6 +828,7 @@ void LLPreviewGesture::loadAsset()
// Blank gesture will be fine.
initDefaultGesture();
refresh();
+ mAssetStatus = PREVIEW_ASSET_LOADED;
return;
}
@@ -910,11 +856,10 @@ void LLPreviewGesture::onLoadComplete(LLVFS *vfs,
void* user_data, S32 status, LLExtStat ext_status)
{
LLUUID* item_idp = (LLUUID*)user_data;
- LLPreview* preview = LLPreview::find(*item_idp);
- if (preview)
- {
- LLPreviewGesture* self = (LLPreviewGesture*)preview;
+ LLPreviewGesture* self = LLFloaterReg::findTypedInstance<LLPreviewGesture>("preview_gesture", *item_idp);
+ if (self)
+ {
if (0 == status)
{
LLVFile file(vfs, asset_uuid, type, LLVFile::READ);
@@ -1016,7 +961,7 @@ void LLPreviewGesture::loadUIFromGesture(LLMultiGesture* gesture)
LLGestureStep* step = gesture->mSteps[i];
LLGestureStep* new_step = NULL;
-
+
switch(step->getType())
{
case STEP_ANIMATION:
@@ -1061,7 +1006,7 @@ void LLPreviewGesture::loadUIFromGesture(LLMultiGesture* gesture)
// Create an enabled item with this step
LLSD row;
- row["columns"][0]["value"] = new_step->getLabel();
+ row["columns"][0]["value"] = getLabel( new_step->getLabel());
row["columns"][0]["font"] = "SANSSERIF_SMALL";
LLScrollListItem* item = mStepList->addElement(row);
item->setUserdata(new_step);
@@ -1179,10 +1124,10 @@ void LLPreviewGesture::saveIfNeeded()
// If this gesture is active, then we need to update the in-memory
// active map with the new pointer.
- if (!delayedUpload && gGestureManager.isGestureActive(mItemUUID))
+ if (!delayedUpload && LLGestureManager::instance().isGestureActive(mItemUUID))
{
// gesture manager now owns the pointer
- gGestureManager.replaceGesture(mItemUUID, gesture, asset_id);
+ LLGestureManager::instance().replaceGesture(mItemUUID, gesture, asset_id);
// replaceGesture may deactivate other gestures so let the
// inventory know.
@@ -1262,10 +1207,10 @@ void LLPreviewGesture::onSaveComplete(const LLUUID& asset_uuid, void* user_data,
}
// Find our window and close it if requested.
- LLPreviewGesture* previewp = (LLPreviewGesture*)LLPreview::find(info->mItemUUID);
+ LLPreviewGesture* previewp = LLFloaterReg::findTypedInstance<LLPreviewGesture>("preview_gesture", info->mItemUUID);
if (previewp && previewp->mCloseAfterSave)
{
- previewp->close();
+ previewp->closeFloater();
}
}
else
@@ -1374,7 +1319,7 @@ void LLPreviewGesture::updateLabel(LLScrollListItem* item)
LLScrollListCell* cell = item->getColumn(0);
LLScrollListText* text_cell = (LLScrollListText*)cell;
- std::string label = step->getLabel();
+ std::string label = getLabel( step->getLabel());
text_cell->setText(label);
}
@@ -1619,24 +1564,26 @@ LLScrollListItem* LLPreviewGesture::addStep( const EStepType step_type )
{
case STEP_ANIMATION:
step = new LLGestureStepAnimation();
+
break;
case STEP_SOUND:
step = new LLGestureStepSound();
break;
case STEP_CHAT:
- step = new LLGestureStepChat();
+ step = new LLGestureStepChat();
break;
case STEP_WAIT:
- step = new LLGestureStepWait();
+ step = new LLGestureStepWait();
break;
default:
llerrs << "Unknown step type: " << (S32)step_type << llendl;
return NULL;
}
+
// Create an enabled item with this step
LLSD row;
- row["columns"][0]["value"] = step->getLabel();
+ row["columns"][0]["value"] = getLabel(step->getLabel());
row["columns"][0]["font"] = "SANSSERIF_SMALL";
LLScrollListItem* step_item = mStepList->addElement(row);
step_item->setUserdata(step);
@@ -1651,6 +1598,42 @@ LLScrollListItem* LLPreviewGesture::addStep( const EStepType step_type )
}
// static
+std::string LLPreviewGesture::getLabel(std::vector<std::string> labels)
+{
+ std::vector<std::string> v_labels = labels ;
+ std::string result("");
+
+ if( v_labels.size() != 2)
+ {
+ return result;
+ }
+
+ if(v_labels[0]=="Chat")
+ {
+ result=LLTrans::getString("Chat");
+ }
+ else if(v_labels[0]=="Sound")
+ {
+ result=LLTrans::getString("Sound");
+ }
+ else if(v_labels[0]=="Wait")
+ {
+ result=LLTrans::getString("Wait");
+ }
+ else if(v_labels[0]=="AnimFlagStop")
+ {
+ result=LLTrans::getString("AnimFlagStop");
+ }
+ else if(v_labels[0]=="AnimFlagStart")
+ {
+ result=LLTrans::getString("AnimFlagStart");
+ }
+
+ result.append(v_labels[1]);
+ return result;
+
+}
+// static
void LLPreviewGesture::onClickUp(void* data)
{
LLPreviewGesture* self = (LLPreviewGesture*)data;
@@ -1705,13 +1688,13 @@ void LLPreviewGesture::onClickDelete(void* data)
void LLPreviewGesture::onCommitActive(LLUICtrl* ctrl, void* data)
{
LLPreviewGesture* self = (LLPreviewGesture*)data;
- if (!gGestureManager.isGestureActive(self->mItemUUID))
+ if (!LLGestureManager::instance().isGestureActive(self->mItemUUID))
{
- gGestureManager.activateGesture(self->mItemUUID);
+ LLGestureManager::instance().activateGesture(self->mItemUUID);
}
else
{
- gGestureManager.deactivateGesture(self->mItemUUID);
+ LLGestureManager::instance().deactivateGesture(self->mItemUUID);
}
// Make sure the (active) label in the inventory gets updated.
@@ -1750,14 +1733,14 @@ void LLPreviewGesture::onClickPreview(void* data)
self->mPreviewBtn->setLabel(self->getString("stop_txt"));
// play it, and delete when done
- gGestureManager.playGesture(self->mPreviewGesture);
+ LLGestureManager::instance().playGesture(self->mPreviewGesture);
self->refresh();
}
else
{
// Will call onDonePreview() below
- gGestureManager.stopGesture(self->mPreviewGesture);
+ LLGestureManager::instance().stopGesture(self->mPreviewGesture);
self->refresh();
}
diff --git a/indra/newview/llpreviewgesture.h b/indra/newview/llpreviewgesture.h
index c245c0e8da..16ac935775 100644
--- a/indra/newview/llpreviewgesture.h
+++ b/indra/newview/llpreviewgesture.h
@@ -52,40 +52,36 @@ class LLPreviewGesture : public LLPreview
public:
// Pass an object_id if this gesture is inside an object in the world,
// otherwise use LLUUID::null.
- static LLPreviewGesture* show(const std::string& title, const LLUUID& item_id, const LLUUID& object_id, BOOL take_focus = TRUE);
+ static LLPreviewGesture* show(const LLUUID& item_id, const LLUUID& object_id);
+
+ LLPreviewGesture(const LLSD& key);
+ virtual ~LLPreviewGesture();
// LLView
- virtual BOOL handleKeyHere(KEY key, MASK mask);
- virtual BOOL handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop,
+ /*virtual*/ BOOL handleKeyHere(KEY key, MASK mask);
+ /*virtual*/ BOOL handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop,
EDragAndDropType cargo_type,
void* cargo_data,
EAcceptance* accept,
std::string& tooltip_msg);
// LLPanel
- virtual BOOL postBuild();
+ /*virtual*/ BOOL postBuild();
// LLFloater
- virtual BOOL canClose();
- virtual void setMinimized(BOOL minimize);
- virtual void onClose(bool app_quitting);
- virtual void onUpdateSucceeded();
+ /*virtual*/ BOOL canClose();
+ /*virtual*/ void onUpdateSucceeded();
+ /*virtual*/ void refresh();
+
protected:
- LLPreviewGesture();
- virtual ~LLPreviewGesture();
-
- void init(const LLUUID& item_id, const LLUUID& object_id);
-
// Populate various comboboxes
void addModifiers();
void addKeys();
void addAnimations();
void addSounds();
- void refresh();
-
void initDefaultGesture();
void loadAsset();
@@ -111,7 +107,11 @@ protected:
// Add a step. Pass the name of the step, like "Animation",
// "Sound", "Chat", or "Wait"
LLScrollListItem* addStep(const enum EStepType step_type);
-
+
+ void onClose();
+ void onVisibilityChange ( const LLSD& new_visibility );
+
+ static std::string getLabel(std::vector<std::string> labels);
static void updateLabel(LLScrollListItem* item);
static void onCommitSetDirty(LLUICtrl* ctrl, void* data);
@@ -139,8 +139,6 @@ protected:
static void onDonePreview(LLMultiGesture* gesture, void* data);
- virtual const char *getTitleName() const { return "Gesture"; }
-
protected:
// LLPreview contains mDescEditor
LLLineEditor* mTriggerEditor;
diff --git a/indra/newview/llpreviewnotecard.cpp b/indra/newview/llpreviewnotecard.cpp
index 4abe390bc5..cadab71ba8 100644
--- a/indra/newview/llpreviewnotecard.cpp
+++ b/indra/newview/llpreviewnotecard.cpp
@@ -40,6 +40,7 @@
#include "llassetuploadresponders.h"
#include "llviewerwindow.h"
#include "llbutton.h"
+#include "llfloaterreg.h"
#include "llinventorymodel.h"
#include "lllineeditor.h"
#include "llnotify.h"
@@ -62,91 +63,19 @@
#include "lluictrlfactory.h"
///----------------------------------------------------------------------------
-/// Local function declarations, constants, enums, and typedefs
-///----------------------------------------------------------------------------
-
-const S32 PREVIEW_MIN_WIDTH =
- 2 * PREVIEW_BORDER +
- 2 * PREVIEW_BUTTON_WIDTH +
- PREVIEW_PAD + RESIZE_HANDLE_WIDTH +
- PREVIEW_PAD;
-const S32 PREVIEW_MIN_HEIGHT =
- 2 * PREVIEW_BORDER +
- 3*(20 + PREVIEW_PAD) +
- 2 * SCROLLBAR_SIZE + 128;
-
-///----------------------------------------------------------------------------
/// Class LLPreviewNotecard
///----------------------------------------------------------------------------
// Default constructor
-LLPreviewNotecard::LLPreviewNotecard(const std::string& name,
- const LLRect& rect,
- const std::string& title,
- const LLUUID& item_id,
- const LLUUID& object_id,
- const LLUUID& asset_id,
- BOOL show_keep_discard,
- LLPointer<LLViewerInventoryItem> inv_item) :
- LLPreview(name, rect, title, item_id, object_id, TRUE,
- PREVIEW_MIN_WIDTH,
- PREVIEW_MIN_HEIGHT,
- inv_item),
- mAssetID( asset_id ),
- mNotecardItemID(item_id),
- mObjectID(object_id)
+LLPreviewNotecard::LLPreviewNotecard(const LLSD& key) //const LLUUID& item_id,
+ : LLPreview( key )
{
- LLRect curRect = rect;
-
- if (show_keep_discard)
- {
- LLUICtrlFactory::getInstance()->buildFloater(this,"floater_preview_notecard_keep_discard.xml");
- childSetAction("Keep",onKeepBtn,this);
- childSetAction("Discard",onDiscardBtn,this);
- }
- else
- {
- LLUICtrlFactory::getInstance()->buildFloater(this,"floater_preview_notecard.xml");
- childSetAction("Save",onClickSave,this);
-
- if( mAssetID.isNull() )
- {
- const LLInventoryItem* item = getItem();
- if( item )
- {
- mAssetID = item->getAssetUUID();
- }
- }
- }
-
- // only assert shape if not hosted in a multifloater
- if (!getHost())
- {
- reshape(curRect.getWidth(), curRect.getHeight(), TRUE);
- setRect(curRect);
- }
-
- childSetVisible("lock", FALSE);
-
- const LLInventoryItem* item = getItem();
-
- childSetCommitCallback("desc", LLPreview::onText, this);
+ const LLInventoryItem *item = getItem();
if (item)
- childSetText("desc", item->getDescription());
- childSetPrevalidate("desc", &LLLineEditor::prevalidatePrintableNotPipe);
-
- setTitle(title);
-
- LLViewerTextEditor* editor = getChild<LLViewerTextEditor>("Notecard Editor");
-
- if (editor)
{
- editor->setWordWrap(TRUE);
- editor->setSourceID(item_id);
- editor->setHandleEditKeysDirectly(TRUE);
- }
-
- gAgent.changeCameraToDefault();
+ mAssetID = item->getAssetUUID();
+ }
+ //Called from floater reg: LLUICtrlFactory::getInstance()->buildFloater(this,"floater_preview_notecard.xml", FALSE);
}
LLPreviewNotecard::~LLPreviewNotecard()
@@ -158,25 +87,27 @@ BOOL LLPreviewNotecard::postBuild()
LLViewerTextEditor *ed = getChild<LLViewerTextEditor>("Notecard Editor");
if (ed)
{
- ed->setNotecardInfo(mNotecardItemID, mObjectID);
+ ed->setNotecardInfo(mItemUUID, mObjectID, getKey());
ed->makePristine();
}
- return TRUE;
+
+ childSetAction("Save", onClickSave, this);
+ childSetVisible("lock", FALSE);
+
+ const LLInventoryItem* item = getItem();
+
+ childSetCommitCallback("desc", LLPreview::onText, this);
+ if (item)
+ childSetText("desc", item->getDescription());
+ childSetPrevalidate("desc", &LLLineEditor::prevalidatePrintableNotPipe);
+
+ return LLPreview::postBuild();
}
-bool LLPreviewNotecard::saveItem(LLPointer<LLInventoryItem>* itemptr)
+bool LLPreviewNotecard::saveItem()
{
- LLInventoryItem* item = NULL;
- if (itemptr && itemptr->notNull())
- {
- item = (LLInventoryItem*)(*itemptr);
- }
- bool res = saveIfNeeded(item);
- if (res)
- {
- delete itemptr;
- }
- return res;
+ LLInventoryItem* item = gInventory.getItem(mItemUUID);
+ return saveIfNeeded(item);
}
void LLPreviewNotecard::setEnabled( BOOL enabled )
@@ -188,20 +119,15 @@ void LLPreviewNotecard::setEnabled( BOOL enabled )
childSetVisible("lock", !enabled);
childSetEnabled("desc", enabled);
childSetEnabled("Save", enabled && editor && (!editor->isPristine()));
-
}
void LLPreviewNotecard::draw()
{
-
-
- //childSetFocus("Save", FALSE);
-
LLViewerTextEditor* editor = getChild<LLViewerTextEditor>("Notecard Editor");
- BOOL script_changed = !editor->isPristine();
+ BOOL changed = !editor->isPristine();
- childSetEnabled("Save", script_changed && getEnabled());
+ childSetEnabled("Save", changed && getEnabled());
LLPreview::draw();
}
@@ -255,8 +181,13 @@ bool LLPreviewNotecard::hasEmbeddedInventory()
return editor->hasEmbeddedInventory();
}
-void LLPreviewNotecard::refreshFromInventory()
+void LLPreviewNotecard::refreshFromInventory(const LLUUID& new_item_id)
{
+ if (new_item_id.notNull())
+ {
+ mItemUUID = new_item_id;
+ setKey(LLSD(new_item_id));
+ }
lldebugs << "LLPreviewNotecard::refreshFromInventory()" << llendl;
loadAsset();
}
@@ -287,7 +218,6 @@ void LLPreviewNotecard::loadAsset()
}
else
{
- LLUUID* new_uuid = new LLUUID(mItemUUID);
LLHost source_sim = LLHost::invalid;
if (mObjectUUID.notNull())
{
@@ -305,7 +235,6 @@ void LLPreviewNotecard::loadAsset()
editor->makePristine();
editor->setEnabled(FALSE);
mAssetStatus = PREVIEW_ASSET_LOADED;
- delete new_uuid;
return;
}
}
@@ -318,7 +247,7 @@ void LLPreviewNotecard::loadAsset()
item->getAssetUUID(),
item->getType(),
&onLoadComplete,
- (void*)new_uuid,
+ (void*)new LLUUID(mItemUUID),
TRUE);
mAssetStatus = PREVIEW_ASSET_LOADING;
}
@@ -343,7 +272,9 @@ void LLPreviewNotecard::loadAsset()
editor->setText(LLStringUtil::null);
editor->makePristine();
editor->setEnabled(TRUE);
- mAssetStatus = PREVIEW_ASSET_LOADED;
+ // Don't set asset status here; we may not have set the item id yet
+ // (e.g. when this gets called initially)
+ //mAssetStatus = PREVIEW_ASSET_LOADED;
}
}
@@ -355,7 +286,8 @@ void LLPreviewNotecard::onLoadComplete(LLVFS *vfs,
{
llinfos << "LLPreviewNotecard::onLoadComplete()" << llendl;
LLUUID* item_id = (LLUUID*)user_data;
- LLPreviewNotecard* preview = LLPreviewNotecard::getInstance(*item_id);
+
+ LLPreviewNotecard* preview = LLFloaterReg::findTypedInstance<LLPreviewNotecard>("preview_notecard", LLSD(*item_id));
if( preview )
{
if(0 == status)
@@ -420,18 +352,6 @@ void LLPreviewNotecard::onLoadComplete(LLVFS *vfs,
}
// static
-LLPreviewNotecard* LLPreviewNotecard::getInstance(const LLUUID& item_id)
-{
- LLPreview* instance = NULL;
- preview_map_t::iterator found_it = LLPreview::sInstances.find(item_id);
- if(found_it != LLPreview::sInstances.end())
- {
- instance = found_it->second;
- }
- return (LLPreviewNotecard*)instance;
-}
-
-// static
void LLPreviewNotecard::onClickSave(void* user_data)
{
//llinfos << "LLPreviewNotecard::onBtnSave()" << llendl;
@@ -590,10 +510,11 @@ void LLPreviewNotecard::onSaveComplete(const LLUUID& asset_uuid, void* user_data
}
// Find our window and close it if requested.
- LLPreviewNotecard* previewp = (LLPreviewNotecard*)LLPreview::find(info->mItemUUID);
+
+ LLPreviewNotecard* previewp = LLFloaterReg::findTypedInstance<LLPreviewNotecard>("preview_notecard", info->mItemUUID);
if (previewp && previewp->mCloseAfterSave)
{
- previewp->close();
+ previewp->closeFloater();
}
}
else
@@ -624,7 +545,7 @@ bool LLPreviewNotecard::handleSaveChangesDialog(const LLSD& notification, const
case 1: // "No"
mForceClose = TRUE;
- close();
+ closeFloater();
break;
case 2: // "Cancel"
@@ -636,16 +557,4 @@ bool LLPreviewNotecard::handleSaveChangesDialog(const LLSD& notification, const
return false;
}
-void LLPreviewNotecard::reshape(S32 width, S32 height, BOOL called_from_parent)
-{
- LLPreview::reshape( width, height, called_from_parent );
-
- if( !isMinimized() )
- {
- // So that next time you open a script it will have the same height and width
- // (although not the same position).
- gSavedSettings.setRect("NotecardEditorRect", getRect());
- }
-}
-
// EOF
diff --git a/indra/newview/llpreviewnotecard.h b/indra/newview/llpreviewnotecard.h
index f5cd2bb2a9..5b8cf1c2f6 100644
--- a/indra/newview/llpreviewnotecard.h
+++ b/indra/newview/llpreviewnotecard.h
@@ -49,28 +49,21 @@ class LLButton;
class LLPreviewNotecard : public LLPreview
{
public:
- LLPreviewNotecard(const std::string& name, const LLRect& rect, const std::string& title,
- const LLUUID& item_id,
- const LLUUID& object_id = LLUUID::null,
- const LLUUID& asset_id = LLUUID::null,
- BOOL show_keep_discard = FALSE,
- LLPointer<LLViewerInventoryItem> inv_item = NULL);
+ LLPreviewNotecard(const LLSD& key);
virtual ~LLPreviewNotecard();
- // llpreview
- virtual bool saveItem(LLPointer<LLInventoryItem>* itemptr);
+ bool saveItem();
// llview
virtual void draw();
virtual BOOL handleKeyHere(KEY key, MASK mask);
virtual void setEnabled( BOOL enabled );
- virtual void reshape(S32 width, S32 height, BOOL called_from_parent = TRUE);
// llfloater
virtual BOOL canClose();
// llpanel
- virtual BOOL postBuild();
+ virtual BOOL postBuild();
// reach into the text editor, and grab the drag item
const LLInventoryItem* getDragItem();
@@ -82,15 +75,13 @@ public:
// After saving a notecard, the tcp based upload system will
// change the asset, therefore, we need to re-fetch it from the
// asset system. :(
- void refreshFromInventory();
+ void refreshFromInventory(const LLUUID& item_id = LLUUID::null);
protected:
virtual void loadAsset();
bool saveIfNeeded(LLInventoryItem* copyitem = NULL);
- static LLPreviewNotecard* getInstance(const LLUUID& uuid);
-
static void onLoadComplete(LLVFS *vfs,
const LLUUID& asset_uuid,
LLAssetType::EType type,
@@ -104,15 +95,12 @@ protected:
bool handleSaveChangesDialog(const LLSD& notification, const LLSD& response);
- virtual const char *getTitleName() const { return "Note"; }
-
protected:
LLViewerTextEditor* mEditor;
LLButton* mSaveBtn;
LLUUID mAssetID;
- LLUUID mNotecardItemID;
LLUUID mObjectID;
};
diff --git a/indra/newview/llpreviewscript.cpp b/indra/newview/llpreviewscript.cpp
index 0bacb95d2d..b256914d29 100644
--- a/indra/newview/llpreviewscript.cpp
+++ b/indra/newview/llpreviewscript.cpp
@@ -40,6 +40,7 @@
#include "llcheckboxctrl.h"
#include "llcombobox.h"
#include "lldir.h"
+#include "llfloaterreg.h"
#include "llinventorymodel.h"
#include "llkeyboard.h"
#include "lllineeditor.h"
@@ -48,6 +49,8 @@
#include "llscrollbar.h"
#include "llscrollcontainer.h"
#include "llscrolllistctrl.h"
+#include "llscrolllistitem.h"
+#include "llscrolllistcell.h"
#include "llslider.h"
#include "lscript_rt_interface.h"
#include "lscript_export.h"
@@ -80,15 +83,13 @@
#include "llviewertexteditor.h"
#include "llviewerwindow.h"
#include "lluictrlfactory.h"
-#include "llwebbrowserctrl.h"
+#include "llmediactrl.h"
#include "lluictrlfactory.h"
-
+#include "lltrans.h"
#include "llviewercontrol.h"
#include "llappviewer.h"
-
#include "llpanelinventory.h"
-
const std::string HELLO_LSL =
"default\n"
"{\n"
@@ -109,34 +110,8 @@ const std::string DEFAULT_SCRIPT_DESC = "(No Description)"; // *TODO:Translate?
// Description and header information
-const S32 SCRIPT_BORDER = 4;
-const S32 SCRIPT_PAD = 5;
-const S32 SCRIPT_BUTTON_WIDTH = 128;
-const S32 SCRIPT_BUTTON_HEIGHT = 24; // HACK: Use BTN_HEIGHT where possible.
-const S32 LINE_COLUMN_HEIGHT = 14;
-const S32 BTN_PAD = 8;
-
-const S32 SCRIPT_EDITOR_MIN_HEIGHT = 2 * SCROLLBAR_SIZE + 2 * LLPANEL_BORDER_WIDTH + 128;
-
-const S32 SCRIPT_MIN_WIDTH =
- 2 * SCRIPT_BORDER +
- 2 * SCRIPT_BUTTON_WIDTH +
- SCRIPT_PAD + RESIZE_HANDLE_WIDTH +
- SCRIPT_PAD;
-
-const S32 SCRIPT_MIN_HEIGHT =
- 2 * SCRIPT_BORDER +
- 3*(SCRIPT_BUTTON_HEIGHT + SCRIPT_PAD) +
- LINE_COLUMN_HEIGHT +
- SCRIPT_EDITOR_MIN_HEIGHT;
-
const S32 MAX_EXPORT_SIZE = 1000;
-const S32 SCRIPT_SEARCH_WIDTH = 300;
-const S32 SCRIPT_SEARCH_HEIGHT = 120;
-const S32 SCRIPT_SEARCH_LABEL_WIDTH = 50;
-const S32 SCRIPT_SEARCH_BUTTON_WIDTH = 80;
-const S32 TEXT_EDIT_COLUMN_HEIGHT = 16;
const S32 MAX_HISTORY_COUNT = 10;
const F32 LIVE_HELP_REFRESH_TIME = 1.f;
@@ -152,9 +127,10 @@ static bool have_script_upload_cap(LLUUID& object_id)
class LLFloaterScriptSearch : public LLFloater
{
public:
- LLFloaterScriptSearch(std::string title, LLRect rect, LLScriptEdCore* editor_core);
+ LLFloaterScriptSearch(LLScriptEdCore* editor_core);
~LLFloaterScriptSearch();
+ /*virtual*/ BOOL postBuild();
static void show(LLScriptEdCore* editor_core);
static void onBtnSearch(void* userdata);
void handleBtnSearch();
@@ -168,8 +144,6 @@ public:
LLScriptEdCore* getEditorCore() { return mEditorCore; }
static LLFloaterScriptSearch* getInstance() { return sInstance; }
- void open(); /*Flawfinder: ignore*/
-
private:
LLScriptEdCore* mEditorCore;
@@ -179,28 +153,14 @@ private:
LLFloaterScriptSearch* LLFloaterScriptSearch::sInstance = NULL;
-LLFloaterScriptSearch::LLFloaterScriptSearch(std::string title, LLRect rect, LLScriptEdCore* editor_core)
- : LLFloater("script search",rect,title), mEditorCore(editor_core)
+LLFloaterScriptSearch::LLFloaterScriptSearch(LLScriptEdCore* editor_core)
+: LLFloater(LLSD()),
+ mEditorCore(editor_core)
{
-
- LLUICtrlFactory::getInstance()->buildFloater(this,"floater_script_search.xml");
+ LLUICtrlFactory::getInstance()->buildFloater(this,"floater_script_search.xml", NULL);
- childSetAction("search_btn", onBtnSearch,this);
- childSetAction("replace_btn", onBtnReplace,this);
- childSetAction("replace_all_btn", onBtnReplaceAll,this);
-
- setDefaultBtn("search_btn");
-
- if (!getHost())
- {
- LLRect curRect = getRect();
- translate(rect.mLeft - curRect.mLeft, rect.mTop - curRect.mTop);
- }
-
sInstance = this;
-
- childSetFocus("search_text", TRUE);
-
+
// find floater in which script panel is embedded
LLView* viewp = (LLView*)editor_core;
while(viewp)
@@ -215,26 +175,33 @@ LLFloaterScriptSearch::LLFloaterScriptSearch(std::string title, LLRect rect, LLS
}
}
+BOOL LLFloaterScriptSearch::postBuild()
+{
+ childSetAction("search_btn", onBtnSearch,this);
+ childSetAction("replace_btn", onBtnReplace,this);
+ childSetAction("replace_all_btn", onBtnReplaceAll,this);
+
+ setDefaultBtn("search_btn");
+
+ return TRUE;
+}
+
//static
void LLFloaterScriptSearch::show(LLScriptEdCore* editor_core)
{
if (sInstance && sInstance->mEditorCore && sInstance->mEditorCore != editor_core)
{
- sInstance->close();
+ sInstance->closeFloater();
delete sInstance;
}
if (!sInstance)
{
- S32 left = 0;
- S32 top = 0;
- gFloaterView->getNewFloaterPosition(&left,&top);
-
// sInstance will be assigned in the constructor.
- new LLFloaterScriptSearch("Script Search",LLRect(left,top,left + SCRIPT_SEARCH_WIDTH,top - SCRIPT_SEARCH_HEIGHT),editor_core);
+ new LLFloaterScriptSearch(editor_core);
}
- sInstance->open(); /*Flawfinder: ignore*/
+ sInstance->openFloater();
}
LLFloaterScriptSearch::~LLFloaterScriptSearch()
@@ -281,19 +248,21 @@ void LLFloaterScriptSearch::handleBtnReplaceAll()
mEditorCore->mEditor->replaceTextAll(childGetText("search_text"), childGetText("replace_text"), caseChk->get());
}
-void LLFloaterScriptSearch::open() /*Flawfinder: ignore*/
-{
- LLFloater::open(); /*Flawfinder: ignore*/
- childSetFocus("search_text", TRUE);
-}
+
/// ---------------------------------------------------------------------------
/// LLScriptEdCore
/// ---------------------------------------------------------------------------
+struct LLSECKeywordCompare
+{
+ bool operator()(const std::string& lhs, const std::string& rhs)
+ {
+ return (LLStringUtil::compareDictInsensitive( lhs, rhs ) < 0 );
+ }
+};
+
LLScriptEdCore::LLScriptEdCore(
- const std::string& name,
- const LLRect& rect,
const std::string& sample,
const std::string& help_url,
const LLHandle<LLFloater>& floater_handle,
@@ -303,7 +272,7 @@ LLScriptEdCore::LLScriptEdCore(
void* userdata,
S32 bottom_pad)
:
- LLPanel( std::string("name"), rect ),
+ LLPanel(),
mSampleText(sample),
mHelpURL(help_url),
mEditor( NULL ),
@@ -321,65 +290,76 @@ LLScriptEdCore::LLScriptEdCore(
setBorderVisible(FALSE);
- LLUICtrlFactory::getInstance()->buildPanel(this, "floater_script_ed_panel.xml");
-
- mErrorList = getChild<LLScrollListCtrl>("lsl errors");
-
- mFunctions = getChild<LLComboBox>( "Insert...");
-
- childSetCommitCallback("Insert...", &LLScriptEdCore::onBtnInsertFunction, this);
-
- mEditor = getChild<LLViewerTextEditor>("Script Editor");
- mEditor->setFollowsAll();
- mEditor->setHandleEditKeysDirectly(TRUE);
- mEditor->setEnabled(TRUE);
- mEditor->setWordWrap(TRUE);
+ LLUICtrlFactory::getInstance()->buildPanel(this, "panel_script_ed.xml");
std::vector<std::string> funcs;
std::vector<std::string> tooltips;
- for (S32 i = 0; i < gScriptLibrary.mNextNumber; i++)
+ for (std::vector<LLScriptLibraryFunction>::const_iterator i = gScriptLibrary.mFunctions.begin();
+ i != gScriptLibrary.mFunctions.end(); ++i)
{
// Make sure this isn't a god only function, or the agent is a god.
- if (!gScriptLibrary.mFunctions[i]->mGodOnly || gAgent.isGodlike())
+ if (!i->mGodOnly || gAgent.isGodlike())
{
- funcs.push_back(ll_safe_string(gScriptLibrary.mFunctions[i]->mName));
- tooltips.push_back(ll_safe_string(gScriptLibrary.mFunctions[i]->mDesc));
+ std::string name = i->mName;
+ funcs.push_back(name);
+
+ std::string desc_name = "LSLTipText_";
+ desc_name += name;
+ std::string desc = LLTrans::getString(desc_name);
+
+ F32 sleep_time = i->mSleepTime;
+ if( sleep_time )
+ {
+ desc += "\n";
+
+ LLStringUtil::format_map_t args;
+ args["[SLEEP_TIME]"] = llformat("%.1f", sleep_time );
+ desc += LLTrans::getString("LSLTipSleepTime", args);
+ }
+
+ // A \n linefeed is not part of xml. Let's add one to keep all
+ // the tips one-per-line in strings.xml
+ LLStringUtil::replaceString( desc, "\\n", "\n" );
+
+ tooltips.push_back(desc);
}
}
+
LLColor3 color(0.5f, 0.0f, 0.15f);
-
mEditor->loadKeywords(gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS,"keywords.ini"), funcs, tooltips, color);
-
+ std::vector<std::string> primary_keywords;
+ std::vector<std::string> secondary_keywords;
LLKeywordToken *token;
LLKeywords::keyword_iterator_t token_it;
for (token_it = mEditor->keywordsBegin(); token_it != mEditor->keywordsEnd(); ++token_it)
{
token = token_it->second;
- if (token->getColor() == color)
- mFunctions->add(wstring_to_utf8str(token->getToken()));
+ if (token->getColor() == color) // Wow, what a disgusting hack.
+ {
+ primary_keywords.push_back( wstring_to_utf8str(token->getToken()) );
+ }
+ else
+ {
+ secondary_keywords.push_back( wstring_to_utf8str(token->getToken()) );
+ }
}
- for (token_it = mEditor->keywordsBegin(); token_it != mEditor->keywordsEnd(); ++token_it)
+ // Case-insensitive dictionary sort for primary keywords. We don't sort the secondary
+ // keywords. They're intelligently grouped in keywords.ini.
+ std::stable_sort( primary_keywords.begin(), primary_keywords.end(), LLSECKeywordCompare() );
+
+ for (std::vector<std::string>::const_iterator iter= primary_keywords.begin();
+ iter!= primary_keywords.end(); ++iter)
{
- token = token_it->second;
- if (token->getColor() != color)
- mFunctions->add(wstring_to_utf8str(token->getToken()));
+ mFunctions->add(*iter);
}
-
- childSetCommitCallback("lsl errors", &LLScriptEdCore::onErrorList, this);
- childSetAction("Save_btn", onBtnSave,this);
-
- initMenu();
-
- // Do the work that addTabPanel() normally does.
- //LLRect tab_panel_rect( 0, getRect().getHeight(), getRect().getWidth(), 0 );
- //tab_panel_rect.stretch( -LLPANEL_BORDER_WIDTH );
- //mCodePanel->setFollowsAll();
- //mCodePanel->translate( tab_panel_rect.mLeft - mCodePanel->getRect().mLeft, tab_panel_rect.mBottom - mCodePanel->getRect().mBottom);
- //mCodePanel->reshape( tab_panel_rect.getWidth(), tab_panel_rect.getHeight(), TRUE );
-
+ for (std::vector<std::string>::const_iterator iter= secondary_keywords.begin();
+ iter!= secondary_keywords.end(); ++iter)
+ {
+ mFunctions->add(*iter);
+ }
}
LLScriptEdCore::~LLScriptEdCore()
@@ -390,57 +370,74 @@ LLScriptEdCore::~LLScriptEdCore()
LLFloaterScriptSearch* script_search = LLFloaterScriptSearch::getInstance();
if (script_search && script_search->getEditorCore() == this)
{
- script_search->close();
+ script_search->closeFloater();
delete script_search;
}
}
-void LLScriptEdCore::initMenu()
+BOOL LLScriptEdCore::postBuild()
{
- LLMenuItemCallGL* menuItem = getChild<LLMenuItemCallGL>("Save");
- menuItem->setMenuCallback(onBtnSave, this);
- menuItem->setEnabledCallback(hasChanged);
+ mErrorList = getChild<LLScrollListCtrl>("lsl errors");
+
+ mFunctions = getChild<LLComboBox>( "Insert...");
+
+ childSetCommitCallback("Insert...", &LLScriptEdCore::onBtnInsertFunction, this);
+
+ mEditor = getChild<LLViewerTextEditor>("Script Editor");
+
+ childSetCommitCallback("lsl errors", &LLScriptEdCore::onErrorList, this);
+ childSetAction("Save_btn", boost::bind(&LLScriptEdCore::doSave,this,FALSE));
+
+ initMenu();
+ return TRUE;
+}
+
+void LLScriptEdCore::initMenu()
+{
+ // *TODO: Skinning - make these callbacks data driven
+ LLMenuItemCallGL* menuItem;
+
+ menuItem = getChild<LLMenuItemCallGL>("Save");
+ menuItem->setClickCallback(boost::bind(&LLScriptEdCore::doSave, this, FALSE));
+ menuItem->setEnableCallback(boost::bind(&LLScriptEdCore::hasChanged, this));
menuItem = getChild<LLMenuItemCallGL>("Revert All Changes");
- menuItem->setMenuCallback(onBtnUndoChanges, this);
- menuItem->setEnabledCallback(hasChanged);
+ menuItem->setClickCallback(boost::bind(&LLScriptEdCore::onBtnUndoChanges, this));
+ menuItem->setEnableCallback(boost::bind(&LLScriptEdCore::hasChanged, this));
menuItem = getChild<LLMenuItemCallGL>("Undo");
- menuItem->setMenuCallback(onUndoMenu, this);
- menuItem->setEnabledCallback(enableUndoMenu);
+ menuItem->setClickCallback(boost::bind(&LLTextEditor::undo, mEditor));
+ menuItem->setEnableCallback(boost::bind(&LLTextEditor::canUndo, mEditor));
menuItem = getChild<LLMenuItemCallGL>("Redo");
- menuItem->setMenuCallback(onRedoMenu, this);
- menuItem->setEnabledCallback(enableRedoMenu);
+ menuItem->setClickCallback(boost::bind(&LLTextEditor::redo, mEditor));
+ menuItem->setEnableCallback(boost::bind(&LLTextEditor::canRedo, mEditor));
menuItem = getChild<LLMenuItemCallGL>("Cut");
- menuItem->setMenuCallback(onCutMenu, this);
- menuItem->setEnabledCallback(enableCutMenu);
+ menuItem->setClickCallback(boost::bind(&LLTextEditor::cut, mEditor));
+ menuItem->setEnableCallback(boost::bind(&LLTextEditor::canCut, mEditor));
menuItem = getChild<LLMenuItemCallGL>("Copy");
- menuItem->setMenuCallback(onCopyMenu, this);
- menuItem->setEnabledCallback(enableCopyMenu);
+ menuItem->setClickCallback(boost::bind(&LLTextEditor::copy, mEditor));
+ menuItem->setEnableCallback(boost::bind(&LLTextEditor::canCopy, mEditor));
menuItem = getChild<LLMenuItemCallGL>("Paste");
- menuItem->setMenuCallback(onPasteMenu, this);
- menuItem->setEnabledCallback(enablePasteMenu);
+ menuItem->setClickCallback(boost::bind(&LLTextEditor::paste, mEditor));
+ menuItem->setEnableCallback(boost::bind(&LLTextEditor::canPaste, mEditor));
menuItem = getChild<LLMenuItemCallGL>("Select All");
- menuItem->setMenuCallback(onSelectAllMenu, this);
- menuItem->setEnabledCallback(enableSelectAllMenu);
+ menuItem->setClickCallback(boost::bind(&LLTextEditor::selectAll, mEditor));
+ menuItem->setEnableCallback(boost::bind(&LLTextEditor::canSelectAll, mEditor));
menuItem = getChild<LLMenuItemCallGL>("Search / Replace...");
- menuItem->setMenuCallback(onSearchMenu, this);
- menuItem->setEnabledCallback(NULL);
+ menuItem->setClickCallback(boost::bind(&LLFloaterScriptSearch::show, this));
menuItem = getChild<LLMenuItemCallGL>("Help...");
- menuItem->setMenuCallback(onBtnHelp, this);
- menuItem->setEnabledCallback(NULL);
+ menuItem->setClickCallback(boost::bind(&LLScriptEdCore::onBtnHelp, this));
menuItem = getChild<LLMenuItemCallGL>("LSL Wiki Help...");
- menuItem->setMenuCallback(onBtnDynamicHelp, this);
- menuItem->setEnabledCallback(NULL);
+ menuItem->setClickCallback(boost::bind(&LLScriptEdCore::onBtnDynamicHelp, this));
}
void LLScriptEdCore::setScriptText(const std::string& text, BOOL is_valid)
@@ -452,17 +449,16 @@ void LLScriptEdCore::setScriptText(const std::string& text, BOOL is_valid)
}
}
-BOOL LLScriptEdCore::hasChanged(void* userdata)
+bool LLScriptEdCore::hasChanged()
{
- LLScriptEdCore* self = (LLScriptEdCore*)userdata;
- if (!self || !self->mEditor) return FALSE;
+ if (!mEditor) return false;
- return ((!self->mEditor->isPristine() || self->mEnableSave) && self->mHasScriptData);
+ return !mEditor->isPristine();
}
void LLScriptEdCore::draw()
{
- BOOL script_changed = hasChanged(this);
+ BOOL script_changed = hasChanged();
childSetEnabled("Save_btn", script_changed);
if( mEditor->hasFocus() )
@@ -470,8 +466,11 @@ void LLScriptEdCore::draw()
S32 line = 0;
S32 column = 0;
mEditor->getCurrentLineAndColumn( &line, &column, FALSE ); // don't include wordwrap
+ LLStringUtil::format_map_t args;
std::string cursor_pos;
- cursor_pos = llformat("Line %d, Column %d", line, column );
+ args["[LINE]"] = llformat ("%d", line);
+ args["[COLUMN]"] = llformat ("%d", column);
+ cursor_pos = LLTrans::getString("CursorPos", args);
childSetText("line_col", cursor_pos);
}
else
@@ -492,7 +491,7 @@ void LLScriptEdCore::updateDynamicHelp(BOOL immediate)
// update back and forward buttons
LLButton* fwd_button = help_floater->getChild<LLButton>("fwd_btn");
LLButton* back_button = help_floater->getChild<LLButton>("back_btn");
- LLWebBrowserCtrl* browser = help_floater->getChild<LLWebBrowserCtrl>("lsl_guide_html");
+ LLMediaCtrl* browser = help_floater->getChild<LLMediaCtrl>("lsl_guide_html");
back_button->setEnabled(browser->canNavigateBack());
fwd_button->setEnabled(browser->canNavigateForward());
@@ -501,12 +500,12 @@ void LLScriptEdCore::updateDynamicHelp(BOOL immediate)
return;
}
- const LLTextSegment* segment = NULL;
- std::vector<const LLTextSegment*> selected_segments;
+ LLTextSegmentPtr segment = NULL;
+ std::vector<LLTextSegmentPtr> selected_segments;
mEditor->getSelectedSegments(selected_segments);
// try segments in selection range first
- std::vector<const LLTextSegment*>::iterator segment_iter;
+ std::vector<LLTextSegmentPtr>::iterator segment_iter;
for (segment_iter = selected_segments.begin(); segment_iter != selected_segments.end(); ++segment_iter)
{
if((*segment_iter)->getToken() && (*segment_iter)->getToken()->getType() == LLKeywordToken::WORD)
@@ -519,7 +518,7 @@ void LLScriptEdCore::updateDynamicHelp(BOOL immediate)
// then try previous segment in case we just typed it
if (!segment)
{
- const LLTextSegment* test_segment = mEditor->getPreviousSegment();
+ const LLTextSegmentPtr test_segment = mEditor->getPreviousSegment();
if(test_segment->getToken() && test_segment->getToken()->getType() == LLKeywordToken::WORD)
{
segment = test_segment;
@@ -551,7 +550,7 @@ void LLScriptEdCore::setHelpPage(const std::string& help_string)
LLFloater* help_floater = mLiveHelpHandle.get();
if (!help_floater) return;
- LLWebBrowserCtrl* web_browser = help_floater->getChild<LLWebBrowserCtrl>("lsl_guide_html");
+ LLMediaCtrl* web_browser = help_floater->getChild<LLMediaCtrl>("lsl_guide_html");
if (!web_browser) return;
LLComboBox* history_combo = help_floater->getChild<LLComboBox>("history_combo");
@@ -580,9 +579,7 @@ void LLScriptEdCore::addHelpItemToHistory(const std::string& help_string)
// separate history items from full item list
if (mLiveHelpHistorySize == 0)
{
- LLSD row;
- row["columns"][0]["type"] = "separator";
- history_combo->addElement(row, ADD_TOP);
+ history_combo->addSeparator(ADD_TOP);
}
// delete all history items over history limit
while(mLiveHelpHistorySize > MAX_HISTORY_COUNT - 1)
@@ -612,7 +609,7 @@ void LLScriptEdCore::addHelpItemToHistory(const std::string& help_string)
BOOL LLScriptEdCore::canClose()
{
- if(mForceClose || !hasChanged(this))
+ if(mForceClose || !hasChanged())
{
return TRUE;
}
@@ -631,14 +628,14 @@ bool LLScriptEdCore::handleSaveChangesDialog(const LLSD& notification, const LLS
{
case 0: // "Yes"
// close after saving
- LLScriptEdCore::doSave( this, TRUE );
+ doSave( TRUE );
break;
case 1: // "No"
mForceClose = TRUE;
// This will close immediately because mForceClose is true, so we won't
// infinite loop with these dialogs. JC
- ((LLFloater*) getParent())->close();
+ ((LLFloater*) getParent())->closeFloater();
break;
case 2: // "Cancel"
@@ -666,46 +663,42 @@ bool LLScriptEdCore::onHelpWebDialog(const LLSD& notification, const LLSD& respo
return false;
}
-// static
-void LLScriptEdCore::onBtnHelp(void* userdata)
+void LLScriptEdCore::onBtnHelp()
{
- LLScriptEdCore* corep = (LLScriptEdCore*)userdata;
LLSD payload;
- payload["help_url"] = corep->mHelpURL;
+ payload["help_url"] = mHelpURL;
LLNotifications::instance().add("WebLaunchLSLGuide", LLSD(), payload, onHelpWebDialog);
}
-// static
-void LLScriptEdCore::onBtnDynamicHelp(void* userdata)
+void LLScriptEdCore::onBtnDynamicHelp()
{
- LLScriptEdCore* corep = (LLScriptEdCore*)userdata;
-
- LLFloater* live_help_floater = corep->mLiveHelpHandle.get();
+ LLFloater* live_help_floater = mLiveHelpHandle.get();
if (live_help_floater)
{
live_help_floater->setFocus(TRUE);
- corep->updateDynamicHelp(TRUE);
+ updateDynamicHelp(TRUE);
return;
}
- live_help_floater = new LLFloater(std::string("lsl_help"));
- LLUICtrlFactory::getInstance()->buildFloater(live_help_floater, "floater_lsl_guide.xml");
- ((LLFloater*)corep->getParent())->addDependentFloater(live_help_floater, TRUE);
- live_help_floater->childSetCommitCallback("lock_check", onCheckLock, userdata);
+ live_help_floater = new LLFloater(LLSD());
+ LLUICtrlFactory::getInstance()->buildFloater(live_help_floater, "floater_lsl_guide.xml", NULL);
+ LLFloater* parent = dynamic_cast<LLFloater*>(getParent());
+ parent->addDependentFloater(live_help_floater, TRUE);
+ live_help_floater->childSetCommitCallback("lock_check", onCheckLock, this);
live_help_floater->childSetValue("lock_check", gSavedSettings.getBOOL("ScriptHelpFollowsCursor"));
- live_help_floater->childSetCommitCallback("history_combo", onHelpComboCommit, userdata);
- live_help_floater->childSetAction("back_btn", onClickBack, userdata);
- live_help_floater->childSetAction("fwd_btn", onClickForward, userdata);
+ live_help_floater->childSetCommitCallback("history_combo", onHelpComboCommit, this);
+ live_help_floater->childSetAction("back_btn", onClickBack, this);
+ live_help_floater->childSetAction("fwd_btn", onClickForward, this);
- LLWebBrowserCtrl* browser = live_help_floater->getChild<LLWebBrowserCtrl>("lsl_guide_html");
+ LLMediaCtrl* browser = live_help_floater->getChild<LLMediaCtrl>("lsl_guide_html");
browser->setAlwaysRefresh(TRUE);
LLComboBox* help_combo = live_help_floater->getChild<LLComboBox>("history_combo");
LLKeywordToken *token;
LLKeywords::keyword_iterator_t token_it;
- for (token_it = corep->mEditor->keywordsBegin();
- token_it != corep->mEditor->keywordsEnd();
+ for (token_it = mEditor->keywordsBegin();
+ token_it != mEditor->keywordsEnd();
++token_it)
{
token = token_it->second;
@@ -714,10 +707,10 @@ void LLScriptEdCore::onBtnDynamicHelp(void* userdata)
help_combo->sortByName();
// re-initialize help variables
- corep->mLastHelpToken = NULL;
- corep->mLiveHelpHandle = live_help_floater->getHandle();
- corep->mLiveHelpHistorySize = 0;
- corep->updateDynamicHelp(TRUE);
+ mLastHelpToken = NULL;
+ mLiveHelpHandle = live_help_floater->getHandle();
+ mLiveHelpHistorySize = 0;
+ updateDynamicHelp(TRUE);
}
//static
@@ -727,7 +720,7 @@ void LLScriptEdCore::onClickBack(void* userdata)
LLFloater* live_help_floater = corep->mLiveHelpHandle.get();
if (live_help_floater)
{
- LLWebBrowserCtrl* browserp = live_help_floater->getChild<LLWebBrowserCtrl>("lsl_guide_html");
+ LLMediaCtrl* browserp = live_help_floater->getChild<LLMediaCtrl>("lsl_guide_html");
if (browserp)
{
browserp->navigateBack();
@@ -742,7 +735,7 @@ void LLScriptEdCore::onClickForward(void* userdata)
LLFloater* live_help_floater = corep->mLiveHelpHandle.get();
if (live_help_floater)
{
- LLWebBrowserCtrl* browserp = live_help_floater->getChild<LLWebBrowserCtrl>("lsl_guide_html");
+ LLMediaCtrl* browserp = live_help_floater->getChild<LLMediaCtrl>("lsl_guide_html");
if (browserp)
{
browserp->navigateForward();
@@ -784,7 +777,7 @@ void LLScriptEdCore::onHelpComboCommit(LLUICtrl* ctrl, void* userdata)
corep->addHelpItemToHistory(help_string);
- LLWebBrowserCtrl* web_browser = live_help_floater->getChild<LLWebBrowserCtrl>("lsl_guide_html");
+ LLMediaCtrl* web_browser = live_help_floater->getChild<LLMediaCtrl>("lsl_guide_html");
LLUIString url_string = gSavedSettings.getString("LSLHelpURL");
url_string.setArg("[LSL_STRING]", help_string);
web_browser->navigateTo(url_string);
@@ -805,154 +798,25 @@ void LLScriptEdCore::onBtnInsertFunction(LLUICtrl *ui, void* userdata)
self->setHelpPage(self->mFunctions->getSimple());
}
-// static
-void LLScriptEdCore::doSave( void* userdata, BOOL close_after_save )
+void LLScriptEdCore::doSave( BOOL close_after_save )
{
LLViewerStats::getInstance()->incStat( LLViewerStats::ST_LSL_SAVE_COUNT );
- LLScriptEdCore* self = (LLScriptEdCore*) userdata;
-
- if( self->mSaveCallback )
+ if( mSaveCallback )
{
- self->mSaveCallback( self->mUserdata, close_after_save );
+ mSaveCallback( mUserdata, close_after_save );
}
}
-// static
-void LLScriptEdCore::onBtnSave(void* data)
-{
- // do the save, but don't close afterwards
- doSave(data, FALSE);
-}
-// static
-void LLScriptEdCore::onBtnUndoChanges( void* userdata )
+void LLScriptEdCore::onBtnUndoChanges()
{
- LLScriptEdCore* self = (LLScriptEdCore*) userdata;
- if( !self->mEditor->tryToRevertToPristineState() )
+ if( !mEditor->tryToRevertToPristineState() )
{
- LLNotifications::instance().add("ScriptCannotUndo", LLSD(), LLSD(), boost::bind(&LLScriptEdCore::handleReloadFromServerDialog, self, _1, _2));
+ LLNotifications::instance().add("ScriptCannotUndo", LLSD(), LLSD(), boost::bind(&LLScriptEdCore::handleReloadFromServerDialog, this, _1, _2));
}
}
-void LLScriptEdCore::onSearchMenu(void* userdata)
-{
- LLScriptEdCore* sec = (LLScriptEdCore*)userdata;
- LLFloaterScriptSearch::show(sec);
-}
-
-// static
-void LLScriptEdCore::onUndoMenu(void* userdata)
-{
- LLScriptEdCore* self = (LLScriptEdCore*)userdata;
- if (!self || !self->mEditor) return;
- self->mEditor->undo();
-}
-
-// static
-void LLScriptEdCore::onRedoMenu(void* userdata)
-{
- LLScriptEdCore* self = (LLScriptEdCore*)userdata;
- if (!self || !self->mEditor) return;
- self->mEditor->redo();
-}
-
-// static
-void LLScriptEdCore::onCutMenu(void* userdata)
-{
- LLScriptEdCore* self = (LLScriptEdCore*)userdata;
- if (!self || !self->mEditor) return;
- self->mEditor->cut();
-}
-
-// static
-void LLScriptEdCore::onCopyMenu(void* userdata)
-{
- LLScriptEdCore* self = (LLScriptEdCore*)userdata;
- if (!self || !self->mEditor) return;
- self->mEditor->copy();
-}
-
-// static
-void LLScriptEdCore::onPasteMenu(void* userdata)
-{
- LLScriptEdCore* self = (LLScriptEdCore*)userdata;
- if (!self || !self->mEditor) return;
- self->mEditor->paste();
-}
-
-// static
-void LLScriptEdCore::onSelectAllMenu(void* userdata)
-{
- LLScriptEdCore* self = (LLScriptEdCore*)userdata;
- if (!self || !self->mEditor) return;
- self->mEditor->selectAll();
-}
-
-// static
-void LLScriptEdCore::onDeselectMenu(void* userdata)
-{
- LLScriptEdCore* self = (LLScriptEdCore*)userdata;
- if (!self || !self->mEditor) return;
- self->mEditor->deselect();
-}
-
-// static
-BOOL LLScriptEdCore::enableUndoMenu(void* userdata)
-{
- LLScriptEdCore* self = (LLScriptEdCore*)userdata;
- if (!self || !self->mEditor) return FALSE;
- return self->mEditor->canUndo();
-}
-
-// static
-BOOL LLScriptEdCore::enableRedoMenu(void* userdata)
-{
- LLScriptEdCore* self = (LLScriptEdCore*)userdata;
- if (!self || !self->mEditor) return FALSE;
- return self->mEditor->canRedo();
-}
-
-// static
-BOOL LLScriptEdCore::enableCutMenu(void* userdata)
-{
- LLScriptEdCore* self = (LLScriptEdCore*)userdata;
- if (!self || !self->mEditor) return FALSE;
- return self->mEditor->canCut();
-}
-
-// static
-BOOL LLScriptEdCore::enableCopyMenu(void* userdata)
-{
- LLScriptEdCore* self = (LLScriptEdCore*)userdata;
- if (!self || !self->mEditor) return FALSE;
- return self->mEditor->canCopy();
-}
-
-// static
-BOOL LLScriptEdCore::enablePasteMenu(void* userdata)
-{
- LLScriptEdCore* self = (LLScriptEdCore*)userdata;
- if (!self || !self->mEditor) return FALSE;
- return self->mEditor->canPaste();
-}
-
-// static
-BOOL LLScriptEdCore::enableSelectAllMenu(void* userdata)
-{
- LLScriptEdCore* self = (LLScriptEdCore*)userdata;
- if (!self || !self->mEditor) return FALSE;
- return self->mEditor->canSelectAll();
-}
-
-// static
-BOOL LLScriptEdCore::enableDeselectMenu(void* userdata)
-{
- LLScriptEdCore* self = (LLScriptEdCore*)userdata;
- if (!self || !self->mEditor) return FALSE;
- return self->mEditor->canDeselect();
-}
-
// static
void LLScriptEdCore::onErrorList(LLUICtrl*, void* user_data)
{
@@ -960,8 +824,7 @@ void LLScriptEdCore::onErrorList(LLUICtrl*, void* user_data)
LLScrollListItem* item = self->mErrorList->getFirstSelected();
if(item)
{
- // *FIX: This fucked up little hack is here because we don't
- // have a grep library. This is very brittle code.
+ // *FIX: replace with boost grep
S32 row = 0;
S32 column = 0;
const LLScrollListCell* cell = item->getColumn(0);
@@ -1080,8 +943,7 @@ void* LLPreviewLSL::createScriptEdPanel(void* userdata)
LLPreviewLSL *self = (LLPreviewLSL*)userdata;
- self->mScriptEd = new LLScriptEdCore("script panel",
- LLRect(),
+ self->mScriptEd = new LLScriptEdCore(
HELLO_LSL,
HELP_LSL_URL,
self->getHandle(),
@@ -1095,49 +957,32 @@ void* LLPreviewLSL::createScriptEdPanel(void* userdata)
}
-LLPreviewLSL::LLPreviewLSL(const std::string& name, const LLRect& rect,
- const std::string& title, const LLUUID& item_id )
-: LLPreview( name, rect, title, item_id, LLUUID::null, TRUE,
- SCRIPT_MIN_WIDTH, SCRIPT_MIN_HEIGHT ),
- mPendingUploads(0)
+LLPreviewLSL::LLPreviewLSL(const LLSD& key )
+ : LLPreview( key ),
+ mPendingUploads(0)
{
+ mFactoryMap["script panel"] = LLCallbackMap(LLPreviewLSL::createScriptEdPanel, this);
+ //Called from floater reg: LLUICtrlFactory::getInstance()->buildFloater(this,"floater_script_preview.xml", FALSE);
+}
- LLRect curRect = rect;
-
-
- LLCallbackMap::map_t factory_map;
- factory_map["script panel"] = LLCallbackMap(LLPreviewLSL::createScriptEdPanel, this);
-
-
- LLUICtrlFactory::getInstance()->buildFloater(this,"floater_script_preview.xml", &factory_map);
-
+// virtual
+BOOL LLPreviewLSL::postBuild()
+{
const LLInventoryItem* item = getItem();
childSetCommitCallback("desc", LLPreview::onText, this);
childSetText("desc", item->getDescription());
childSetPrevalidate("desc", &LLLineEditor::prevalidatePrintableNotPipe);
- if (!getFloaterHost() && !getHost() && getAssetStatus() == PREVIEW_ASSET_UNLOADED)
- {
- loadAsset();
- }
-
- setTitle(title);
-
- if (!getHost())
- {
- reshape(curRect.getWidth(), curRect.getHeight(), TRUE);
- setRect(curRect);
- }
+ return LLPreview::postBuild();
}
// virtual
void LLPreviewLSL::callbackLSLCompileSucceeded()
{
llinfos << "LSL Bytecode saved" << llendl;
- // *TODO: Translate
- mScriptEd->mErrorList->addCommentText(std::string("Compile successful!"));
- mScriptEd->mErrorList->addCommentText(std::string("Save complete."));
+ mScriptEd->mErrorList->setCommentText(LLTrans::getString("CompileSuccessful"));
+ mScriptEd->mErrorList->setCommentText(LLTrans::getString("SaveComplete"));
closeIfNeeded();
}
@@ -1169,7 +1014,7 @@ void LLPreviewLSL::loadAsset()
const LLInventoryItem* item = gInventory.getItem(mItemUUID);
BOOL is_library = item
&& !gInventory.isObjectDescendentOf(mItemUUID,
- gAgent.getInventoryRootID());
+ gInventory.getRootFolderID());
if(!item)
{
// do the more generic search.
@@ -1228,16 +1073,10 @@ void LLPreviewLSL::closeIfNeeded()
mPendingUploads--;
if (mPendingUploads <= 0 && mCloseAfterSave)
{
- close();
+ closeFloater();
}
}
-//override the llpreview open which attempts to load asset, load after xml ui made
-void LLPreviewLSL::open() /*Flawfinder: ignore*/
-{
- LLFloater::open(); /*Flawfinder: ignore*/
-}
-
void LLPreviewLSL::onSearchReplace(void* userdata)
{
LLPreviewLSL* self = (LLPreviewLSL*)userdata;
@@ -1267,7 +1106,7 @@ void LLPreviewLSL::onSave(void* userdata, BOOL close_after_save)
void LLPreviewLSL::saveIfNeeded()
{
// llinfos << "LLPreviewLSL::saveIfNeeded()" << llendl;
- if(!LLScriptEdCore::hasChanged(mScriptEd))
+ if(!mScriptEd->hasChanged())
{
return;
}
@@ -1440,7 +1279,7 @@ void LLPreviewLSL::onSaveComplete(const LLUUID& asset_uuid, void* user_data, S32
}
// Find our window and close it if requested.
- LLPreviewLSL* self = (LLPreviewLSL*)LLPreview::find(info->mItemUUID);
+ LLPreviewLSL* self = LLFloaterReg::findTypedInstance<LLPreviewLSL>("preview_script", info->mItemUUID);
if (self)
{
getWindow()->decBusyCount();
@@ -1448,7 +1287,7 @@ void LLPreviewLSL::onSaveComplete(const LLUUID& asset_uuid, void* user_data, S32
if (self->mPendingUploads <= 0
&& self->mCloseAfterSave)
{
- self->close();
+ self->closeFloater();
}
}
}
@@ -1470,7 +1309,7 @@ void LLPreviewLSL::onSaveBytecodeComplete(const LLUUID& asset_uuid, void* user_d
LLPreviewLSL* self = NULL;
if(instance_uuid)
{
- self = LLPreviewLSL::getInstance(*instance_uuid);
+ self = LLFloaterReg::findTypedInstance<LLPreviewLSL>("preview_script", *instance_uuid);
}
if (0 == status)
{
@@ -1487,7 +1326,7 @@ void LLPreviewLSL::onSaveBytecodeComplete(const LLUUID& asset_uuid, void* user_d
if (self->mPendingUploads <= 0
&& self->mCloseAfterSave)
{
- self->close();
+ self->closeFloater();
}
}
}
@@ -1508,7 +1347,7 @@ void LLPreviewLSL::onLoadComplete( LLVFS *vfs, const LLUUID& asset_uuid, LLAsset
lldebugs << "LLPreviewLSL::onLoadComplete: got uuid " << asset_uuid
<< llendl;
LLUUID* item_uuid = (LLUUID*)user_data;
- LLPreviewLSL* preview = LLPreviewLSL::getInstance(*item_uuid);
+ LLPreviewLSL* preview = LLFloaterReg::findTypedInstance<LLPreviewLSL>("preview_script", *item_uuid);
if( preview )
{
if(0 == status)
@@ -1559,37 +1398,10 @@ void LLPreviewLSL::onLoadComplete( LLVFS *vfs, const LLUUID& asset_uuid, LLAsset
delete item_uuid;
}
-// static
-LLPreviewLSL* LLPreviewLSL::getInstance( const LLUUID& item_uuid )
-{
- LLPreview* instance = NULL;
- preview_map_t::iterator found_it = LLPreview::sInstances.find(item_uuid);
- if(found_it != LLPreview::sInstances.end())
- {
- instance = found_it->second;
- }
- return (LLPreviewLSL*)instance;
-}
-
-void LLPreviewLSL::reshape(S32 width, S32 height, BOOL called_from_parent)
-{
- LLPreview::reshape( width, height, called_from_parent );
-
- if( !isMinimized() )
- {
- // So that next time you open a script it will have the same height and width
- // (although not the same position).
- gSavedSettings.setRect("PreviewScriptRect", getRect());
- }
-}
-
/// ---------------------------------------------------------------------------
/// LLLiveLSLEditor
/// ---------------------------------------------------------------------------
-LLMap<LLUUID, LLLiveLSLEditor*> LLLiveLSLEditor::sInstances;
-
-
//static
void* LLLiveLSLEditor::createScriptEdPanel(void* userdata)
@@ -1597,8 +1409,7 @@ void* LLLiveLSLEditor::createScriptEdPanel(void* userdata)
LLLiveLSLEditor *self = (LLLiveLSLEditor*)userdata;
- self->mScriptEd = new LLScriptEdCore("script ed panel",
- LLRect(),
+ self->mScriptEd = new LLScriptEdCore(
HELLO_LSL,
HELP_LSL_URL,
self->getHandle(),
@@ -1612,72 +1423,40 @@ void* LLLiveLSLEditor::createScriptEdPanel(void* userdata)
}
-LLLiveLSLEditor::LLLiveLSLEditor(const std::string& name,
- const LLRect& rect,
- const std::string& title,
- const LLUUID& object_id,
- const LLUUID& item_id) :
- LLPreview(name, rect, title, item_id, object_id, TRUE, SCRIPT_MIN_WIDTH, SCRIPT_MIN_HEIGHT),
- mObjectID(object_id),
- mItemID(item_id),
+LLLiveLSLEditor::LLLiveLSLEditor(const LLSD& key) :
+ LLPreview(key),
mScriptEd(NULL),
mAskedForRunningInfo(FALSE),
mHaveRunningInfo(FALSE),
mCloseAfterSave(FALSE),
mPendingUploads(0),
- mIsModifiable(FALSE)
+ mIsModifiable(FALSE),
+ mIsNew(false)
{
+ mFactoryMap["script ed panel"] = LLCallbackMap(LLLiveLSLEditor::createScriptEdPanel, this);
+ //Called from floater reg: LLUICtrlFactory::getInstance()->buildFloater(this,"floater_live_lsleditor.xml", FALSE);
+}
-
- BOOL is_new = FALSE;
- if(mItemID.isNull())
- {
- mItemID.generate();
- is_new = TRUE;
- }
-
-
- LLLiveLSLEditor::sInstances.addData(mItemID ^ mObjectID, this);
-
- LLCallbackMap::map_t factory_map;
- factory_map["script ed panel"] = LLCallbackMap(LLLiveLSLEditor::createScriptEdPanel, this);
-
- LLUICtrlFactory::getInstance()->buildFloater(this,"floater_live_lsleditor.xml", &factory_map);
-
- mMonoCheckbox = getChild<LLCheckBoxCtrl>("mono");
- childSetCommitCallback("mono", &LLLiveLSLEditor::onMonoCheckboxClicked, this);
- childSetEnabled("mono", FALSE);
-
+BOOL LLLiveLSLEditor::postBuild()
+{
childSetCommitCallback("running", LLLiveLSLEditor::onRunningCheckboxClicked, this);
childSetEnabled("running", FALSE);
childSetAction("Reset",&LLLiveLSLEditor::onReset,this);
childSetEnabled("Reset", TRUE);
+ mMonoCheckbox = getChild<LLCheckBoxCtrl>("mono");
+ childSetCommitCallback("mono", &LLLiveLSLEditor::onMonoCheckboxClicked, this);
+ childSetEnabled("mono", FALSE);
mScriptEd->mEditor->makePristine();
- loadAsset(is_new);
mScriptEd->mEditor->setFocus(TRUE);
-
- if (!getHost())
- {
- LLRect curRect = getRect();
- translate(rect.mLeft - curRect.mLeft, rect.mTop - curRect.mTop);
- }
-
- setTitle(title);
+ return LLPreview::postBuild();
}
LLLiveLSLEditor::~LLLiveLSLEditor()
{
- LLLiveLSLEditor::sInstances.removeData(mItemID ^ mObjectID);
-}
-
-// this is called via LLPreview::loadAsset() virtual method
-void LLLiveLSLEditor::loadAsset()
-{
- loadAsset(FALSE);
}
// virtual
@@ -1686,9 +1465,8 @@ void LLLiveLSLEditor::callbackLSLCompileSucceeded(const LLUUID& task_id,
bool is_script_running)
{
lldebugs << "LSL Bytecode saved" << llendl;
- // *TODO: Translate
- mScriptEd->mErrorList->addCommentText(std::string("Compile successful!"));
- mScriptEd->mErrorList->addCommentText(std::string("Save complete."));
+ mScriptEd->mErrorList->setCommentText(LLTrans::getString("CompileSuccessful"));
+ mScriptEd->mErrorList->setCommentText(LLTrans::getString("SaveComplete"));
closeIfNeeded();
}
@@ -1704,6 +1482,7 @@ void LLLiveLSLEditor::callbackLSLCompileFailed(const LLSD& compile_errors)
std::string error_message = line->asString();
LLStringUtil::stripNonprintable(error_message);
row["columns"][0]["value"] = error_message;
+ // *TODO: change to "MONOSPACE" and change llfontgl.cpp?
row["columns"][0]["font"] = "OCRA";
mScriptEd->mErrorList->addElement(row);
}
@@ -1711,16 +1490,15 @@ void LLLiveLSLEditor::callbackLSLCompileFailed(const LLSD& compile_errors)
closeIfNeeded();
}
-void LLLiveLSLEditor::loadAsset(BOOL is_new)
+void LLLiveLSLEditor::loadAsset()
{
//llinfos << "LLLiveLSLEditor::loadAsset()" << llendl;
- if(!is_new)
+ if(!mIsNew)
{
- LLViewerObject* object = gObjectList.findObject(mObjectID);
+ LLViewerObject* object = gObjectList.findObject(mObjectUUID);
if(object)
{
- // HACK! we "know" that mItemID refers to a LLViewerInventoryItem...
- LLViewerInventoryItem* item = (LLViewerInventoryItem*)object->getInventoryObject(mItemID);
+ LLViewerInventoryItem* item = dynamic_cast<LLViewerInventoryItem*>(object->getInventoryObject(mItemUUID));
if(item
&& (gAgent.allowOperation(PERM_COPY, item->getPermissions(), GP_OBJECT_MANIPULATE)
|| gAgent.isGodlike()))
@@ -1744,23 +1522,23 @@ void LLLiveLSLEditor::loadAsset(BOOL is_new)
else if(item && mItem.notNull())
{
// request the text from the object
- LLUUID* user_data = new LLUUID(mItemID ^ mObjectID);
+ LLUUID* user_data = new LLUUID(mItemUUID); // ^ mObjectUUID
gAssetStorage->getInvItemAsset(object->getRegion()->getHost(),
- gAgent.getID(),
- gAgent.getSessionID(),
- item->getPermissions().getOwner(),
- object->getID(),
- item->getUUID(),
- item->getAssetUUID(),
- item->getType(),
- &LLLiveLSLEditor::onLoadComplete,
- (void*)user_data,
- TRUE);
+ gAgent.getID(),
+ gAgent.getSessionID(),
+ item->getPermissions().getOwner(),
+ object->getID(),
+ item->getUUID(),
+ item->getAssetUUID(),
+ item->getType(),
+ &LLLiveLSLEditor::onLoadComplete,
+ (void*)user_data,
+ TRUE);
LLMessageSystem* msg = gMessageSystem;
msg->newMessageFast(_PREHASH_GetScriptRunning);
msg->nextBlockFast(_PREHASH_Script);
- msg->addUUIDFast(_PREHASH_ObjectID, mObjectID);
- msg->addUUIDFast(_PREHASH_ItemID, mItemID);
+ msg->addUUIDFast(_PREHASH_ObjectID, mObjectUUID);
+ msg->addUUIDFast(_PREHASH_ItemID, mItemUUID);
msg->sendReliable(object->getRegion()->getHost());
mAskedForRunningInfo = TRUE;
mAssetStatus = PREVIEW_ASSET_LOADING;
@@ -1789,26 +1567,12 @@ void LLLiveLSLEditor::loadAsset(BOOL is_new)
gMessageSystem->addUUID("AgentID", gAgent.getID());
U32 local_id = object->getLocalID();
gMessageSystem->addData("LocalID", &local_id);
- gMessageSystem->addUUID("ItemID", mItemID);
+ gMessageSystem->addUUID("ItemID", mItemUUID);
LLHost host(object->getRegion()->getIP(),
object->getRegion()->getPort());
gMessageSystem->sendReliable(host);
*/
}
-
- // Initialization of the asset failed. Probably the result
- // of a bug somewhere else. Set up this editor in a no-go mode.
- if(mItem.isNull())
- {
- // Set the inventory item to an incomplete item.
- // This may be better than having a accessible null pointer around,
- // though this newly allocated object will most likely be replaced.
- mItem = new LLViewerInventoryItem();
- mScriptEd->setScriptText(LLStringUtil::null, FALSE);
- mScriptEd->mEditor->makePristine();
- mScriptEd->mEditor->setEnabled(FALSE);
- mAssetStatus = PREVIEW_ASSET_LOADED;
- }
}
else
{
@@ -1817,17 +1581,17 @@ void LLLiveLSLEditor::loadAsset(BOOL is_new)
LLPermissions perm;
perm.init(gAgent.getID(), gAgent.getID(), LLUUID::null, gAgent.getGroupID());
perm.initMasks(PERM_ALL, PERM_ALL, PERM_NONE, PERM_NONE, PERM_MOVE | PERM_TRANSFER);
- mItem = new LLViewerInventoryItem(mItemID,
- mObjectID,
- perm,
- LLUUID::null,
- LLAssetType::AT_LSL_TEXT,
- LLInventoryType::IT_LSL,
- DEFAULT_SCRIPT_NAME,
- DEFAULT_SCRIPT_DESC,
- LLSaleInfo::DEFAULT,
- LLInventoryItem::II_FLAGS_NONE,
- time_corrected());
+ mItem = new LLViewerInventoryItem(mItemUUID,
+ mObjectUUID,
+ perm,
+ LLUUID::null,
+ LLAssetType::AT_LSL_TEXT,
+ LLInventoryType::IT_LSL,
+ DEFAULT_SCRIPT_NAME,
+ DEFAULT_SCRIPT_DESC,
+ LLSaleInfo::DEFAULT,
+ LLInventoryItem::II_FLAGS_NONE,
+ time_corrected());
mAssetStatus = PREVIEW_ASSET_LOADED;
}
}
@@ -1839,12 +1603,12 @@ void LLLiveLSLEditor::onLoadComplete(LLVFS *vfs, const LLUUID& asset_id,
{
lldebugs << "LLLiveLSLEditor::onLoadComplete: got uuid " << asset_id
<< llendl;
- LLLiveLSLEditor* instance = NULL;
LLUUID* xored_id = (LLUUID*)user_data;
-
- if( LLLiveLSLEditor::sInstances.checkData(*xored_id) )
+
+ LLLiveLSLEditor* instance = LLFloaterReg::findTypedInstance<LLLiveLSLEditor>("preview_scriptedit", *xored_id);
+
+ if(instance )
{
- instance = LLLiveLSLEditor::sInstances[*xored_id];
if( LL_ERR_NOERR == status )
{
instance->loadScriptText(vfs, asset_id, type);
@@ -1930,7 +1694,7 @@ void LLLiveLSLEditor::loadScriptText(LLVFS *vfs, const LLUUID &uuid, LLAssetType
void LLLiveLSLEditor::onRunningCheckboxClicked( LLUICtrl*, void* userdata )
{
LLLiveLSLEditor* self = (LLLiveLSLEditor*) userdata;
- LLViewerObject* object = gObjectList.findObject( self->mObjectID );
+ LLViewerObject* object = gObjectList.findObject( self->mObjectUUID );
LLCheckBoxCtrl* runningCheckbox = self->getChild<LLCheckBoxCtrl>("running");
BOOL running = runningCheckbox->get();
//self->mRunningCheckbox->get();
@@ -1942,8 +1706,8 @@ void LLLiveLSLEditor::onRunningCheckboxClicked( LLUICtrl*, void* userdata )
msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
msg->nextBlockFast(_PREHASH_Script);
- msg->addUUIDFast(_PREHASH_ObjectID, self->mObjectID);
- msg->addUUIDFast(_PREHASH_ItemID, self->mItemID);
+ msg->addUUIDFast(_PREHASH_ObjectID, self->mObjectUUID);
+ msg->addUUIDFast(_PREHASH_ItemID, self->mItemUUID);
msg->addBOOLFast(_PREHASH_Running, running);
msg->sendReliable(object->getRegion()->getHost());
}
@@ -1958,7 +1722,7 @@ void LLLiveLSLEditor::onReset(void *userdata)
{
LLLiveLSLEditor* self = (LLLiveLSLEditor*) userdata;
- LLViewerObject* object = gObjectList.findObject( self->mObjectID );
+ LLViewerObject* object = gObjectList.findObject( self->mObjectUUID );
if(object)
{
LLMessageSystem* msg = gMessageSystem;
@@ -1967,8 +1731,8 @@ void LLLiveLSLEditor::onReset(void *userdata)
msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
msg->nextBlockFast(_PREHASH_Script);
- msg->addUUIDFast(_PREHASH_ObjectID, self->mObjectID);
- msg->addUUIDFast(_PREHASH_ItemID, self->mItemID);
+ msg->addUUIDFast(_PREHASH_ObjectID, self->mObjectUUID);
+ msg->addUUIDFast(_PREHASH_ItemID, self->mItemUUID);
msg->sendReliable(object->getRegion()->getHost());
}
else
@@ -1979,7 +1743,7 @@ void LLLiveLSLEditor::onReset(void *userdata)
void LLLiveLSLEditor::draw()
{
- LLViewerObject* object = gObjectList.findObject(mObjectID);
+ LLViewerObject* object = gObjectList.findObject(mObjectUUID);
LLCheckBoxCtrl* runningCheckbox = getChild<LLCheckBoxCtrl>( "running");
if(object && mAskedForRunningInfo && mHaveRunningInfo)
{
@@ -2024,14 +1788,13 @@ void LLLiveLSLEditor::draw()
{
// HACK: Display this information in the title bar.
// Really ought to put in main window.
- // *TODO: Translate
- setTitle(std::string("Script (object out of range)"));
+ setTitle(LLTrans::getString("ObjectOutOfRange"));
runningCheckbox->setEnabled(FALSE);
// object may have fallen out of range.
mHaveRunningInfo = FALSE;
}
- LLFloater::draw();
+ LLPreview::draw();
}
@@ -2046,7 +1809,7 @@ void LLLiveLSLEditor::onSearchReplace(void* userdata)
struct LLLiveLSLSaveData
{
LLLiveLSLSaveData(const LLUUID& id, const LLViewerInventoryItem* item, BOOL active);
- LLUUID mObjectID;
+ LLUUID mSaveObjectID;
LLPointer<LLViewerInventoryItem> mItem;
BOOL mActive;
};
@@ -2054,7 +1817,7 @@ struct LLLiveLSLSaveData
LLLiveLSLSaveData::LLLiveLSLSaveData(const LLUUID& id,
const LLViewerInventoryItem* item,
BOOL active) :
- mObjectID(id),
+ mSaveObjectID(id),
mActive(active)
{
llassert(item);
@@ -2064,7 +1827,7 @@ LLLiveLSLSaveData::LLLiveLSLSaveData(const LLUUID& id,
void LLLiveLSLEditor::saveIfNeeded()
{
llinfos << "LLLiveLSLEditor::saveIfNeeded()" << llendl;
- LLViewerObject* object = gObjectList.findObject(mObjectID);
+ LLViewerObject* object = gObjectList.findObject(mObjectUUID);
if(!object)
{
LLNotifications::instance().add("SaveScriptFailObjectNotFound");
@@ -2083,15 +1846,14 @@ void LLLiveLSLEditor::saveIfNeeded()
// name on save, because the viewer object version of the item,
// and the editor version would get out of synch. Here's a good
// place to synch them back up.
- // HACK! we "know" that mItemID refers to a LLInventoryItem...
- LLInventoryItem* inv_item = (LLInventoryItem*)object->getInventoryObject(mItemID);
+ LLInventoryItem* inv_item = dynamic_cast<LLInventoryItem*>(object->getInventoryObject(mItemUUID));
if(inv_item)
{
mItem->copyItem(inv_item);
}
// Don't need to save if we're pristine
- if(!LLScriptEdCore::hasChanged(mScriptEd))
+ if(!mScriptEd->hasChanged())
{
return;
}
@@ -2145,8 +1907,7 @@ void LLLiveLSLEditor::saveIfNeeded()
BOOL is_running = getChild<LLCheckBoxCtrl>( "running")->get();
if (!url.empty())
{
- uploadAssetViaCaps(url, filename, mObjectID,
- mItemID, is_running);
+ uploadAssetViaCaps(url, filename, mObjectUUID, mItemUUID, is_running);
}
else if (gAssetStorage)
{
@@ -2175,7 +1936,7 @@ void LLLiveLSLEditor::uploadAssetLegacy(const std::string& filename,
const LLTransactionID& tid,
BOOL is_running)
{
- LLLiveLSLSaveData* data = new LLLiveLSLSaveData(mObjectID,
+ LLLiveLSLSaveData* data = new LLLiveLSLSaveData(mObjectUUID,
mItem,
is_running);
gAssetStorage->storeAssetData(filename, tid,
@@ -2238,8 +1999,7 @@ void LLLiveLSLEditor::uploadAssetLegacy(const std::string& filename,
else
{
llinfos << "Compile worked!" << llendl;
- // *TODO: Translate
- mScriptEd->mErrorList->addCommentText(std::string("Compile successful, saving..."));
+ mScriptEd->mErrorList->setCommentText(LLTrans::getString("CompileSuccessfulSaving"));
if(gAssetStorage)
{
llinfos << "LLLiveLSLEditor::saveAsset "
@@ -2247,7 +2007,7 @@ void LLLiveLSLEditor::uploadAssetLegacy(const std::string& filename,
getWindow()->incBusyCount();
mPendingUploads++;
LLLiveLSLSaveData* data = NULL;
- data = new LLLiveLSLSaveData(mObjectID,
+ data = new LLLiveLSLSaveData(mObjectUUID,
mItem,
is_running);
gAssetStorage->storeAssetData(dst_filename,
@@ -2283,7 +2043,7 @@ void LLLiveLSLEditor::onSaveTextComplete(const LLUUID& asset_uuid, void* user_da
}
else
{
- LLLiveLSLEditor* self = sInstances.getIfThere(data->mItem->getUUID() ^ data->mObjectID);
+ LLLiveLSLEditor* self = LLFloaterReg::findTypedInstance<LLLiveLSLEditor>("preview_scriptedit", data->mItem->getUUID()); // ^ data->mSaveObjectID
if (self)
{
self->getWindow()->decBusyCount();
@@ -2291,7 +2051,7 @@ void LLLiveLSLEditor::onSaveTextComplete(const LLUUID& asset_uuid, void* user_da
if (self->mPendingUploads <= 0
&& self->mCloseAfterSave)
{
- self->close();
+ self->closeFloater();
}
}
}
@@ -2308,23 +2068,21 @@ void LLLiveLSLEditor::onSaveBytecodeComplete(const LLUUID& asset_uuid, void* use
if(0 ==status)
{
llinfos << "LSL Bytecode saved" << llendl;
- LLUUID xor_id = data->mItem->getUUID() ^ data->mObjectID;
- LLLiveLSLEditor* self = sInstances.getIfThere(xor_id);
- if(self)
+ LLLiveLSLEditor* self = LLFloaterReg::findTypedInstance<LLLiveLSLEditor>("preview_scriptedit", data->mItem->getUUID()); // ^ data->mSaveObjectID
+ if (self)
{
// Tell the user that the compile worked.
- // *TODO: Translate
- self->mScriptEd->mErrorList->addCommentText(std::string("Save complete."));
+ self->mScriptEd->mErrorList->setCommentText(LLTrans::getString("SaveComplete"));
// close the window if this completes both uploads
self->getWindow()->decBusyCount();
self->mPendingUploads--;
if (self->mPendingUploads <= 0
&& self->mCloseAfterSave)
{
- self->close();
+ self->closeFloater();
}
}
- LLViewerObject* object = gObjectList.findObject(data->mObjectID);
+ LLViewerObject* object = gObjectList.findObject(data->mSaveObjectID);
if(object)
{
object->saveScript(data->mItem, data->mActive, false);
@@ -2349,11 +2107,6 @@ void LLLiveLSLEditor::onSaveBytecodeComplete(const LLUUID& asset_uuid, void* use
delete data;
}
-void LLLiveLSLEditor::open()
-{
- LLFloater::open(); /*Flawfinder: ignore*/
-}
-
BOOL LLLiveLSLEditor::canClose()
{
return (mScriptEd->canClose());
@@ -2365,7 +2118,7 @@ void LLLiveLSLEditor::closeIfNeeded()
mPendingUploads--;
if (mPendingUploads <= 0 && mCloseAfterSave)
{
- close();
+ closeFloater();
}
}
@@ -2385,52 +2138,16 @@ void LLLiveLSLEditor::onSave(void* userdata, BOOL close_after_save)
}
// static
-LLLiveLSLEditor* LLLiveLSLEditor::show(const LLUUID& script_id, const LLUUID& object_id)
-{
- LLLiveLSLEditor* instance = NULL;
- LLUUID xored_id = script_id ^ object_id;
- if(LLLiveLSLEditor::sInstances.checkData(xored_id))
- {
- // Move the existing view to the front
- instance = LLLiveLSLEditor::sInstances[xored_id];
- instance->open(); /*Flawfinder: ignore*/
- }
- return instance;
-}
-
-// static
-void LLLiveLSLEditor::hide(const LLUUID& script_id, const LLUUID& object_id)
-{
- LLUUID xored_id = script_id ^ object_id;
- if( LLLiveLSLEditor::sInstances.checkData( xored_id ) )
- {
- LLLiveLSLEditor* instance = LLLiveLSLEditor::sInstances[xored_id];
- if(instance->getParent())
- {
- instance->getParent()->removeChild(instance);
- }
- delete instance;
- }
-}
-// static
-LLLiveLSLEditor* LLLiveLSLEditor::find(const LLUUID& script_id, const LLUUID& object_id)
-{
- LLUUID xored_id = script_id ^ object_id;
- return sInstances.getIfThere(xored_id);
-}
-
-
-// static
void LLLiveLSLEditor::processScriptRunningReply(LLMessageSystem* msg, void**)
{
LLUUID item_id;
LLUUID object_id;
msg->getUUIDFast(_PREHASH_Script, _PREHASH_ObjectID, object_id);
msg->getUUIDFast(_PREHASH_Script, _PREHASH_ItemID, item_id);
- LLUUID xored_id = item_id ^ object_id;
- if(LLLiveLSLEditor::sInstances.checkData(xored_id))
+
+ LLLiveLSLEditor* instance = LLFloaterReg::findTypedInstance<LLLiveLSLEditor>("preview_scriptedit", item_id); // ^ object_id
+ if(instance)
{
- LLLiveLSLEditor* instance = LLLiveLSLEditor::sInstances[xored_id];
instance->mHaveRunningInfo = TRUE;
BOOL running;
msg->getBOOLFast(_PREHASH_Script, _PREHASH_Running, running);
@@ -2444,22 +2161,10 @@ void LLLiveLSLEditor::processScriptRunningReply(LLMessageSystem* msg, void**)
}
}
-void LLLiveLSLEditor::reshape(S32 width, S32 height, BOOL called_from_parent)
-{
- LLFloater::reshape( width, height, called_from_parent );
-
- if( !isMinimized() )
- {
- // So that next time you open a script it will have the same height and width
- // (although not the same position).
- gSavedSettings.setRect("PreviewScriptRect", getRect());
- }
-}
-
void LLLiveLSLEditor::onMonoCheckboxClicked(LLUICtrl*, void* userdata)
{
LLLiveLSLEditor* self = static_cast<LLLiveLSLEditor*>(userdata);
- self->mMonoCheckbox->setEnabled(have_script_upload_cap(self->mObjectID));
+ self->mMonoCheckbox->setEnabled(have_script_upload_cap(self->mObjectUUID));
self->mScriptEd->enableSave(self->getIsModifiable());
}
diff --git a/indra/newview/llpreviewscript.h b/indra/newview/llpreviewscript.h
index eb8b414709..623886101a 100644
--- a/indra/newview/llpreviewscript.h
+++ b/indra/newview/llpreviewscript.h
@@ -63,8 +63,6 @@ class LLScriptEdCore : public LLPanel
public:
LLScriptEdCore(
- const std::string& name,
- const LLRect& rect,
const std::string& sample,
const std::string& help_url,
const LLHandle<LLFloater>& floater_handle,
@@ -78,45 +76,30 @@ public:
void initMenu();
virtual void draw();
-
+ /*virtual*/ BOOL postBuild();
BOOL canClose();
void setScriptText(const std::string& text, BOOL is_valid);
+
+ void doSave( BOOL close_after_save );
bool handleSaveChangesDialog(const LLSD& notification, const LLSD& response);
bool handleReloadFromServerDialog(const LLSD& notification, const LLSD& response);
static bool onHelpWebDialog(const LLSD& notification, const LLSD& response);
- static void onBtnHelp(void* userdata);
- static void onBtnDynamicHelp(void* userdata);
static void onCheckLock(LLUICtrl*, void*);
static void onHelpComboCommit(LLUICtrl* ctrl, void* userdata);
static void onClickBack(void* userdata);
static void onClickForward(void* userdata);
static void onBtnInsertSample(void*);
static void onBtnInsertFunction(LLUICtrl*, void*);
- static void doSave( void* userdata, BOOL close_after_save );
- static void onBtnSave(void*);
- static void onBtnUndoChanges(void*);
- static void onSearchMenu(void* userdata);
-
- static void onUndoMenu(void* userdata);
- static void onRedoMenu(void* userdata);
- static void onCutMenu(void* userdata);
- static void onCopyMenu(void* userdata);
- static void onPasteMenu(void* userdata);
- static void onSelectAllMenu(void* userdata);
- static void onDeselectMenu(void* userdata);
-
- static BOOL enableUndoMenu(void* userdata);
- static BOOL enableRedoMenu(void* userdata);
- static BOOL enableCutMenu(void* userdata);
- static BOOL enableCopyMenu(void* userdata);
- static BOOL enablePasteMenu(void* userdata);
- static BOOL enableSelectAllMenu(void* userdata);
- static BOOL enableDeselectMenu(void* userdata);
-
- static BOOL hasChanged(void* userdata);
+
+private:
+ void onBtnHelp();
+ void onBtnDynamicHelp();
+ void onBtnUndoChanges();
+
+ bool hasChanged();
void selectFirstError();
@@ -131,8 +114,6 @@ protected:
void addHelpItemToHistory(const std::string& help_string);
static void onErrorList(LLUICtrl*, void* user_data);
- virtual const char *getTitleName() const { return "Script"; }
-
private:
std::string mSampleText;
std::string mHelpURL;
@@ -160,17 +141,15 @@ private:
class LLPreviewLSL : public LLPreview
{
public:
- LLPreviewLSL(const std::string& name, const LLRect& rect, const std::string& title,
- const LLUUID& item_uuid );
+ LLPreviewLSL(const LLSD& key );
virtual void callbackLSLCompileSucceeded();
virtual void callbackLSLCompileFailed(const LLSD& compile_errors);
- /*virtual*/ void open(); /*Flawfinder: ignore*/
+ /*virtual*/ BOOL postBuild();
protected:
virtual BOOL canClose();
void closeIfNeeded();
- virtual void reshape(S32 width, S32 height, BOOL called_from_parent = TRUE);
virtual void loadAsset();
void saveIfNeeded();
@@ -190,15 +169,13 @@ protected:
void* user_data, S32 status, LLExtStat ext_status);
static void onSaveComplete(const LLUUID& uuid, void* user_data, S32 status, LLExtStat ext_status);
static void onSaveBytecodeComplete(const LLUUID& asset_uuid, void* user_data, S32 status, LLExtStat ext_status);
-public:
- static LLPreviewLSL* getInstance(const LLUUID& uuid);
+
protected:
static void* createScriptEdPanel(void* userdata);
protected:
- virtual const char *getTitleName() const { return "Script"; }
LLScriptEdCore* mScriptEd;
// Can safely close only after both text and bytecode are uploaded
S32 mPendingUploads;
@@ -210,16 +187,10 @@ protected:
class LLLiveLSLEditor : public LLPreview
{
public:
- LLLiveLSLEditor(const std::string& name, const LLRect& rect,
- const std::string& title,
- const LLUUID& object_id, const LLUUID& item_id);
+ LLLiveLSLEditor(const LLSD& key);
~LLLiveLSLEditor();
- static LLLiveLSLEditor* show(const LLUUID& item_id, const LLUUID& object_id);
- static void hide(const LLUUID& item_id, const LLUUID& object_id);
- static LLLiveLSLEditor* find(const LLUUID& item_id, const LLUUID& object_id);
-
static void processScriptRunningReply(LLMessageSystem* msg, void**);
virtual void callbackLSLCompileSucceeded(const LLUUID& task_id,
@@ -227,14 +198,14 @@ public:
bool is_script_running);
virtual void callbackLSLCompileFailed(const LLSD& compile_errors);
- // Overide LLPreview::open() to avoid calling loadAsset twice.
- /*virtual*/ void open(); /*Flawfinder: ignore*/
-
-protected:
+ /*virtual*/ BOOL postBuild();
+
+ void setIsNew() { mIsNew = TRUE; }
+
+private:
virtual BOOL canClose();
void closeIfNeeded();
virtual void draw();
- virtual void reshape(S32 width, S32 height, BOOL called_from_parent = TRUE);
virtual void loadAsset();
void loadAsset(BOOL is_new);
@@ -248,6 +219,8 @@ protected:
LLViewerObject* object,
const LLTransactionID& tid,
BOOL is_running);
+ BOOL monoChecked() const;
+
static void onSearchReplace(void* userdata);
static void onLoad(void* userdata);
@@ -268,30 +241,23 @@ protected:
static void* createScriptEdPanel(void* userdata);
+ static void onMonoCheckboxClicked(LLUICtrl*, void* userdata);
-protected:
- LLUUID mObjectID;
- LLUUID mItemID; // The inventory item this script is associated with
- BOOL mIsNew;
- LLScriptEdCore* mScriptEd;
+private:
+ bool mIsNew;
+ LLScriptEdCore* mScriptEd;
//LLUUID mTransmitID;
- LLCheckBoxCtrl *mRunningCheckbox;
- BOOL mAskedForRunningInfo;
- BOOL mHaveRunningInfo;
- LLButton *mResetButton;
+ LLCheckBoxCtrl* mRunningCheckbox;
+ BOOL mAskedForRunningInfo;
+ BOOL mHaveRunningInfo;
+ LLButton* mResetButton;
LLPointer<LLViewerInventoryItem> mItem;
- BOOL mCloseAfterSave;
+ BOOL mCloseAfterSave;
// need to save both text and script, so need to decide when done
- S32 mPendingUploads;
+ S32 mPendingUploads;
- static LLMap<LLUUID, LLLiveLSLEditor*> sInstances;
BOOL getIsModifiable() const { return mIsModifiable; } // Evaluated on load assert
-private:
-
- static void onMonoCheckboxClicked(LLUICtrl*, void* userdata);
- BOOL monoChecked() const;
-
LLCheckBoxCtrl* mMonoCheckbox;
BOOL mIsModifiable;
};
diff --git a/indra/newview/llpreviewsound.cpp b/indra/newview/llpreviewsound.cpp
index 26d8da5a6b..7659c50ed3 100644
--- a/indra/newview/llpreviewsound.cpp
+++ b/indra/newview/llpreviewsound.cpp
@@ -32,11 +32,10 @@
#include "llviewerprecompiledheaders.h"
-#include "audioengine.h"
+#include "llaudioengine.h"
#include "llagent.h" // gAgent
#include "llbutton.h"
#include "llinventory.h"
-#include "llinventoryview.h"
#include "lllineeditor.h"
#include "llpreviewsound.h"
#include "llresmgr.h"
@@ -49,12 +48,23 @@ extern LLAgent gAgent;
const F32 SOUND_GAIN = 1.0f;
-LLPreviewSound::LLPreviewSound(const std::string& name, const LLRect& rect, const std::string& title, const LLUUID& item_uuid, const LLUUID& object_uuid) :
- LLPreview( name, rect, title, item_uuid, object_uuid)
+LLPreviewSound::LLPreviewSound(const LLSD& key)
+ : LLPreview( key )
{
-
- LLUICtrlFactory::getInstance()->buildFloater(this,"floater_preview_sound.xml");
+ //Called from floater reg: LLUICtrlFactory::getInstance()->buildFloater(this,"floater_preview_sound.xml", FALSE);
+}
+// virtual
+BOOL LLPreviewSound::postBuild()
+{
+ const LLInventoryItem* item = getItem();
+ if (item)
+ {
+ childSetText("desc", item->getDescription());
+ if (gAudiop)
+ gAudiop->preloadSound(item->getAssetUUID()); // preload the sound
+ }
+
childSetAction("Sound play btn",&LLPreviewSound::playSound,this);
childSetAction("Sound audition btn",&LLPreviewSound::auditionSound,this);
@@ -64,26 +74,10 @@ LLPreviewSound::LLPreviewSound(const std::string& name, const LLRect& rect, cons
button = getChild<LLButton>("Sound audition btn");
button->setSoundFlags(LLView::SILENT);
- const LLInventoryItem* item = getItem();
-
childSetCommitCallback("desc", LLPreview::onText, this);
- childSetText("desc", item->getDescription());
childSetPrevalidate("desc", &LLLineEditor::prevalidatePrintableNotPipe);
-
- // preload the sound
- if(item && gAudiop)
- {
- gAudiop->preloadSound(item->getAssetUUID());
- }
-
- setTitle(title);
-
- if (!getHost())
- {
- LLRect curRect = getRect();
- translate(rect.mLeft - curRect.mLeft, rect.mTop - curRect.mTop);
- }
+ return LLPreview::postBuild();
}
// static
diff --git a/indra/newview/llpreviewsound.h b/indra/newview/llpreviewsound.h
index 061fbdf685..c4bf8c9a30 100644
--- a/indra/newview/llpreviewsound.h
+++ b/indra/newview/llpreviewsound.h
@@ -38,16 +38,13 @@
class LLPreviewSound : public LLPreview
{
public:
- LLPreviewSound(const std::string& name, const LLRect& rect, const std::string& title,
- const LLUUID& item_uuid,
- const LLUUID& object_uuid = LLUUID::null);
+ LLPreviewSound(const LLSD& key);
static void playSound( void* userdata );
static void auditionSound( void* userdata );
protected:
- virtual const char *getTitleName() const { return "Sound"; }
-
+ /* virtual */ BOOL postBuild();
};
#endif // LL_LLPREVIEWSOUND_H
diff --git a/indra/newview/llpreviewtexture.cpp b/indra/newview/llpreviewtexture.cpp
index 13e7cca464..9d7338c111 100644
--- a/indra/newview/llpreviewtexture.cpp
+++ b/indra/newview/llpreviewtexture.cpp
@@ -32,48 +32,45 @@
#include "llviewerprecompiledheaders.h"
+#include "llwindow.h"
+
#include "llpreviewtexture.h"
#include "llagent.h"
#include "llbutton.h"
#include "llfilepicker.h"
+#include "llfloaterreg.h"
#include "llimagetga.h"
-#include "llinventoryview.h"
#include "llinventory.h"
#include "llresmgr.h"
+#include "lltrans.h"
#include "lltextbox.h"
#include "lltextureview.h"
#include "llui.h"
-#include "llviewerimage.h"
-#include "llviewerimagelist.h"
+#include "llviewertexture.h"
+#include "llviewertexturelist.h"
#include "lluictrlfactory.h"
#include "llviewerwindow.h"
#include "lllineeditor.h"
-const S32 PREVIEW_TEXTURE_MIN_WIDTH = 300;
-const S32 PREVIEW_TEXTURE_MIN_HEIGHT = 120;
-
const S32 CLIENT_RECT_VPAD = 4;
const F32 SECONDS_TO_SHOW_FILE_SAVED_MSG = 8.f;
-LLPreviewTexture::LLPreviewTexture(const std::string& name,
- const LLRect& rect,
- const std::string& title,
- const LLUUID& item_uuid,
- const LLUUID& object_id,
- BOOL show_keep_discard)
-: LLPreview(name, rect, title, item_uuid, object_id, TRUE, PREVIEW_TEXTURE_MIN_WIDTH, PREVIEW_TEXTURE_MIN_HEIGHT ),
- mLoadingFullImage( FALSE ),
- mShowKeepDiscard(show_keep_discard),
- mCopyToInv(FALSE),
- mIsCopyable(FALSE),
- mLastHeight(0),
- mLastWidth(0)
+LLPreviewTexture::LLPreviewTexture(const LLSD& key)
+ : LLPreview( key ),
+ mLoadingFullImage( FALSE ),
+ mShowKeepDiscard(FALSE),
+ mCopyToInv(FALSE),
+ mIsCopyable(FALSE),
+ mUpdateDimensions(TRUE),
+ mLastHeight(0),
+ mLastWidth(0)
{
const LLInventoryItem *item = getItem();
if(item)
{
+ mShowKeepDiscard = item->getPermissions().getCreator() != gAgent.getID();
mImageID = item->getAssetUUID();
const LLPermissions& perm = item->getPermissions();
U32 mask = PERM_NONE;
@@ -94,52 +91,14 @@ LLPreviewTexture::LLPreviewTexture(const std::string& name,
mIsCopyable = TRUE;
}
}
-
- init();
-
- setTitle(title);
-
- if (!getHost())
+ else // not an item, assume it's an asset id
{
- LLRect curRect = getRect();
- translate(rect.mLeft - curRect.mLeft, rect.mTop - curRect.mTop);
+ mImageID = mItemUUID;
+ mCopyToInv = TRUE;
+ mIsCopyable = TRUE;
}
-}
-
-// Note: uses asset_id as a dummy item id.
-LLPreviewTexture::LLPreviewTexture(
- const std::string& name,
- const LLRect& rect,
- const std::string& title,
- const LLUUID& asset_id,
- BOOL copy_to_inv)
- :
- LLPreview(
- name,
- rect,
- title,
- asset_id,
- LLUUID::null,
- TRUE,
- PREVIEW_TEXTURE_MIN_WIDTH,
- PREVIEW_TEXTURE_MIN_HEIGHT ),
- mImageID(asset_id),
- mLoadingFullImage( FALSE ),
- mShowKeepDiscard(FALSE),
- mCopyToInv(copy_to_inv),
- mIsCopyable(TRUE),
- mLastHeight(0),
- mLastWidth(0)
-{
-
- init();
-
- setTitle(title);
-
- LLRect curRect = getRect();
- translate(curRect.mLeft - rect.mLeft, curRect.mTop - rect.mTop);
-
+ //Called from floater reg: LLUICtrlFactory::getInstance()->buildFloater(this, "floater_preview_texture.xml", FALSE);
}
@@ -153,32 +112,26 @@ LLPreviewTexture::~LLPreviewTexture()
mImage = NULL;
}
-
-void LLPreviewTexture::init()
+// virtual
+BOOL LLPreviewTexture::postBuild()
{
-
-
if (mCopyToInv)
{
- LLUICtrlFactory::getInstance()->buildFloater(this,"floater_preview_embedded_texture.xml");
-
- childSetAction("Copy To Inventory",LLPreview::onBtnCopyToInv,this);
+ getChild<LLButton>("Keep")->setLabel(getString("Copy"));
+ childSetAction("Keep",LLPreview::onBtnCopyToInv,this);
+ childSetVisible("Discard", false);
}
-
else if (mShowKeepDiscard)
{
- LLUICtrlFactory::getInstance()->buildFloater(this,"floater_preview_texture_keep_discard.xml");
-
childSetAction("Keep",onKeepBtn,this);
childSetAction("Discard",onDiscardBtn,this);
}
-
- else
+ else
{
- LLUICtrlFactory::getInstance()->buildFloater(this,"floater_preview_texture.xml");
+ childSetVisible("Keep", false);
+ childSetVisible("Discard", false);
}
-
-
+
if (!mCopyToInv)
{
const LLInventoryItem* item = getItem();
@@ -190,12 +143,17 @@ void LLPreviewTexture::init()
childSetPrevalidate("desc", &LLLineEditor::prevalidatePrintableNotPipe);
}
}
+
+ return LLPreview::postBuild();
}
void LLPreviewTexture::draw()
{
- updateDimensions();
-
+ if (mUpdateDimensions)
+ {
+ updateDimensions();
+ }
+
LLPreview::draw();
if (!isMinimized())
@@ -241,14 +199,14 @@ void LLPreviewTexture::draw()
if( mLoadingFullImage )
{
- // *TODO: Translate
- LLFontGL::getFontSansSerif()->renderUTF8(std::string("Receiving:"), 0,
+ LLFontGL::getFontSansSerif()->renderUTF8(LLTrans::getString("Receiving:"), 0,
interior.mLeft + 4,
interior.mBottom + 4,
LLColor4::white, LLFontGL::LEFT, LLFontGL::BOTTOM,
+ LLFontGL::NORMAL,
LLFontGL::DROP_SHADOW);
- F32 data_progress = mImage->mDownloadProgress;
+ F32 data_progress = mImage->getDownloadProgress() ;
// Draw the progress bar.
const S32 BAR_HEIGHT = 12;
@@ -278,11 +236,11 @@ void LLPreviewTexture::draw()
else
if( !mSavedFileTimer.hasExpired() )
{
- // *TODO: Translate
- LLFontGL::getFontSansSerif()->renderUTF8(std::string("File Saved"), 0,
+ LLFontGL::getFontSansSerif()->renderUTF8(LLTrans::getString("FileSaved"), 0,
interior.mLeft + 4,
interior.mBottom + 4,
LLColor4::white, LLFontGL::LEFT, LLFontGL::BOTTOM,
+ LLFontGL::NORMAL,
LLFontGL::DROP_SHADOW);
}
}
@@ -300,10 +258,11 @@ BOOL LLPreviewTexture::canSaveAs() const
// virtual
void LLPreviewTexture::saveAs()
{
- if( mLoadingFullImage ) return;
+ if( mLoadingFullImage )
+ return;
LLFilePicker& file_picker = LLFilePicker::instance();
- const LLViewerInventoryItem* item = getItem() ;
+ const LLInventoryItem* item = getItem() ;
if( !file_picker.getSaveFile( LLFilePicker::FFSAVE_TGA, item ? LLDir::getScrubbedFileName(item->getName()) : LLStringUtil::null) )
{
// User canceled or we failed to acquire save file.
@@ -317,10 +276,27 @@ void LLPreviewTexture::saveAs()
0, TRUE, FALSE, new LLUUID( mItemUUID ) );
}
+// virtual
+void LLPreviewTexture::reshape(S32 width, S32 height, BOOL called_from_parent)
+{
+// mLastHeight = 0;
+// mLastWidth = 0;
+ mUpdateDimensions = TRUE;
+ LLPreview::reshape(width, height, called_from_parent);
+}
+
+// virtual
+void LLPreviewTexture::onFocusReceived()
+{
+ mLastHeight = 0;
+ mLastWidth = 0;
+ mUpdateDimensions = TRUE;
+ LLPreview::onFocusReceived();
+}
// static
void LLPreviewTexture::onFileLoadedForSave(BOOL success,
- LLViewerImage *src_vi,
+ LLViewerFetchedTexture *src_vi,
LLImageRaw* src,
LLImageRaw* aux_src,
S32 discard_level,
@@ -328,12 +304,8 @@ void LLPreviewTexture::onFileLoadedForSave(BOOL success,
void* userdata)
{
LLUUID* item_uuid = (LLUUID*) userdata;
- LLPreviewTexture* self = NULL;
- preview_map_t::iterator found_it = LLPreview::sInstances.find(*item_uuid);
- if(found_it != LLPreview::sInstances.end())
- {
- self = (LLPreviewTexture*) found_it->second;
- }
+
+ LLPreviewTexture* self = LLFloaterReg::findTypedInstance<LLPreviewTexture>("preview_texture", *item_uuid);
if( final || !success )
{
@@ -381,10 +353,13 @@ void LLPreviewTexture::onFileLoadedForSave(BOOL success,
// When we receive it, reshape the window accordingly.
void LLPreviewTexture::updateDimensions()
{
- if (!mImage) return;
-
- S32 image_height = llmax(1, mImage->getHeight(0));
- S32 image_width = llmax(1, mImage->getWidth(0));
+ if (!mImage)
+ return;
+
+ mUpdateDimensions = FALSE;
+
+ S32 image_height = llmax(1, mImage->getFullHeight());
+ S32 image_width = llmax(1, mImage->getFullWidth());
// Attempt to make the image 1:1 on screen.
// If that fails, cut width by half.
S32 client_width = image_width;
@@ -400,13 +375,13 @@ void LLPreviewTexture::updateDimensions()
client_width /= 2;
client_height /= 2;
}
-
+
S32 view_width = client_width + horiz_pad;
S32 view_height = client_height + vert_pad;
// set text on dimensions display (should be moved out of here and into a callback of some sort)
- childSetTextArg("dimensions", "[WIDTH]", llformat("%d", mImage->mFullWidth));
- childSetTextArg("dimensions", "[HEIGHT]", llformat("%d", mImage->mFullHeight));
+ childSetTextArg("dimensions", "[WIDTH]", llformat("%d", mImage->getFullWidth()));
+ childSetTextArg("dimensions", "[HEIGHT]", llformat("%d", mImage->getFullHeight()));
// add space for dimensions
S32 info_height = 0;
@@ -427,27 +402,36 @@ void LLPreviewTexture::updateDimensions()
view_width = llmax(view_width, getMinWidth());
view_height = llmax(view_height, getMinHeight());
- if (client_height != mLastHeight || client_width != mLastWidth)
+ if (view_height != mLastHeight || view_width != mLastWidth)
{
- mLastWidth = client_width;
- mLastHeight = client_height;
-
- S32 old_top = getRect().mTop;
- S32 old_left = getRect().mLeft;
if (getHost())
{
getHost()->growToFit(view_width, view_height);
+ reshape( view_width, view_height );
+ setOrigin( 0, getHost()->getRect().getHeight() - (view_height + PREVIEW_HEADER_SIZE) );
}
else
{
+ S32 old_top = getRect().mTop;
+ S32 old_left = getRect().mLeft;
reshape( view_width, view_height );
S32 new_bottom = old_top - getRect().getHeight();
setOrigin( old_left, new_bottom );
- // Try to keep whole view onscreen, don't allow partial offscreen.
+ }
+
+ // Try to keep whole view onscreen, don't allow partial offscreen.
+ if (getHost())
+ gFloaterView->adjustToFitScreen(getHost(), FALSE);
+ else
gFloaterView->adjustToFitScreen(this, FALSE);
+
+ if (image_height > 1 && image_width > 1)
+ {
+ // Resize until we know the image's height
+ mLastWidth = view_width;
+ mLastHeight = view_height;
}
}
-
if (!mUserResized)
{
@@ -481,14 +465,15 @@ void LLPreviewTexture::updateDimensions()
void LLPreviewTexture::loadAsset()
{
- mImage = gImageList.getImage(mImageID, MIPMAP_TRUE, FALSE);
- mImage->setBoostLevel(LLViewerImage::BOOST_PREVIEW);
+ mImage = LLViewerTextureManager::getFetchedTexture(mImageID, MIPMAP_TRUE, FALSE, LLViewerTexture::LOD_TEXTURE);
+ mImage->setBoostLevel(LLViewerTexture::BOOST_PREVIEW);
mAssetStatus = PREVIEW_ASSET_LOADING;
+ updateDimensions();
}
LLPreview::EAssetStatus LLPreviewTexture::getAssetStatus()
{
- if (mImage.notNull() && (mImage->mFullWidth * mImage->mFullHeight > 0))
+ if (mImage.notNull() && (mImage->getFullWidth() * mImage->getFullHeight() > 0))
{
mAssetStatus = PREVIEW_ASSET_LOADED;
}
diff --git a/indra/newview/llpreviewtexture.h b/indra/newview/llpreviewtexture.h
index 75fd39eab0..9ace304fa6 100644
--- a/indra/newview/llpreviewtexture.h
+++ b/indra/newview/llpreviewtexture.h
@@ -36,26 +36,14 @@
#include "llpreview.h"
#include "llbutton.h"
#include "llframetimer.h"
-#include "llviewerimage.h"
+#include "llviewertexture.h"
class LLImageRaw;
class LLPreviewTexture : public LLPreview
{
public:
- LLPreviewTexture(
- const std::string& name,
- const LLRect& rect,
- const std::string& title,
- const LLUUID& item_uuid,
- const LLUUID& object_id,
- BOOL show_keep_discard = FALSE);
- LLPreviewTexture(
- const std::string& name,
- const LLRect& rect,
- const std::string& title,
- const LLUUID& asset_id,
- BOOL copy_to_inv = FALSE);
+ LLPreviewTexture(const LLSD& key);
~LLPreviewTexture();
virtual void draw();
@@ -65,11 +53,14 @@ public:
virtual void loadAsset();
virtual EAssetStatus getAssetStatus();
-
+
+ virtual void reshape(S32 width, S32 height, BOOL called_from_parent = TRUE);
+ virtual void onFocusReceived();
+
static void saveToFile(void* userdata);
static void onFileLoadedForSave(
BOOL success,
- LLViewerImage *src_vi,
+ LLViewerFetchedTexture *src_vi,
LLImageRaw* src,
LLImageRaw* aux_src,
S32 discard_level,
@@ -79,25 +70,25 @@ public:
protected:
void init();
+ /* virtual */ BOOL postBuild();
- virtual const char *getTitleName() const { return "Texture"; }
-
private:
void updateDimensions();
LLUUID mImageID;
- LLPointer<LLViewerImage> mImage;
+ LLPointer<LLViewerFetchedTexture> mImage;
BOOL mLoadingFullImage;
std::string mSaveFileName;
LLFrameTimer mSavedFileTimer;
BOOL mShowKeepDiscard;
BOOL mCopyToInv;
-
+
// This is stored off in a member variable, because the save-as
// button and drag and drop functionality need to know.
BOOL mIsCopyable;
S32 mLastHeight;
S32 mLastWidth;
+ BOOL mUpdateDimensions;
};
diff --git a/indra/newview/llprogressview.cpp b/indra/newview/llprogressview.cpp
index bfd14f709a..f70cfc59ec 100644
--- a/indra/newview/llprogressview.cpp
+++ b/indra/newview/llprogressview.cpp
@@ -40,8 +40,8 @@
#include "llrender.h"
#include "llui.h"
#include "llfontgl.h"
-#include "llimagegl.h"
#include "lltimer.h"
+#include "lltextbox.h"
#include "llglheaders.h"
#include "llagent.h"
@@ -50,7 +50,7 @@
#include "llprogressbar.h"
#include "llstartup.h"
#include "llviewercontrol.h"
-#include "llviewerimagelist.h"
+#include "llviewertexturelist.h"
#include "llviewerwindow.h"
#include "llappviewer.h"
#include "llweb.h"
@@ -68,9 +68,9 @@ const F32 TOTAL_LOGIN_TIME = 10.f; // seconds, wild guess at time from GL contex
S32 gLastStartAnimationFrame = 0; // human-style indexing, first image = 1
const S32 ANIMATION_FRAMES = 1; //13;
-// XUI:translate
-LLProgressView::LLProgressView(const std::string& name, const LLRect &rect)
-: LLPanel(name, rect, FALSE),
+// XUI: Translate
+LLProgressView::LLProgressView(const LLRect &rect)
+: LLPanel(),
mPercentDone( 0.f ),
mURLInMessage(false),
mMouseDownInActiveArea( false )
@@ -84,7 +84,7 @@ BOOL LLProgressView::postBuild()
mProgressBar = getChild<LLProgressBar>("login_progress_bar");
mCancelBtn = getChild<LLButton>("cancel_btn");
- mCancelBtn->setClickedCallback( LLProgressView::onCancelButtonClicked );
+ mCancelBtn->setClickedCallback( LLProgressView::onCancelButtonClicked, NULL );
mFadeTimer.stop();
getChild<LLTextBox>("title_text")->setText(LLStringExplicit(LLAppViewer::instance()->getSecondLifeTitle()));
@@ -146,10 +146,10 @@ void LLProgressView::draw()
// Paint bitmap if we've got one
glPushMatrix();
- if (gStartImageGL)
+ if (gStartTexture)
{
LLGLSUIDefault gls_ui;
- gGL.getTexUnit(0)->bind(gStartImageGL);
+ gGL.getTexUnit(0)->bind(gStartTexture.get());
gGL.color4f(1.f, 1.f, 1.f, mFadeTimer.getStarted() ? clamp_rescale(mFadeTimer.getElapsedTimeF32(), 0.f, FADE_IN_TIME, 1.f, 0.f) : 1.f);
F32 image_aspect = (F32)gStartImageWidth / (F32)gStartImageHeight;
S32 width = getRect().getWidth();
@@ -185,7 +185,7 @@ void LLProgressView::draw()
{
gFocusMgr.removeTopCtrlWithoutCallback(this);
LLPanel::setVisible(FALSE);
- gStartImageGL = NULL;
+ gStartTexture = NULL;
}
return;
}
diff --git a/indra/newview/llprogressview.h b/indra/newview/llprogressview.h
index 9517ee1321..83574ff52a 100644
--- a/indra/newview/llprogressview.h
+++ b/indra/newview/llprogressview.h
@@ -43,7 +43,7 @@ class LLProgressBar;
class LLProgressView : public LLPanel
{
public:
- LLProgressView(const std::string& name, const LLRect& rect);
+ LLProgressView(const LLRect& rect);
virtual ~LLProgressView();
BOOL postBuild();
diff --git a/indra/newview/llrecentpeople.cpp b/indra/newview/llrecentpeople.cpp
new file mode 100644
index 0000000000..0c16cea004
--- /dev/null
+++ b/indra/newview/llrecentpeople.cpp
@@ -0,0 +1,69 @@
+/**
+ * @file llrecentpeople.cpp
+ * @brief List of people with which the user has recently interacted.
+ *
+ * $LicenseInfo:firstyear=2009&license=viewergpl$
+ *
+ * Copyright (c) 2009, Linden Research, Inc.
+ *
+ * Second Life Viewer Source Code
+ * The source code in this file ("Source Code") is provided by Linden Lab
+ * to you under the terms of the GNU General Public License, version 2.0
+ * ("GPL"), unless you have obtained a separate licensing agreement
+ * ("Other License"), formally executed by you and Linden Lab. Terms of
+ * the GPL can be found in doc/GPL-license.txt in this distribution, or
+ * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
+ *
+ * There are special exceptions to the terms and conditions of the GPL as
+ * it is applied to this Source Code. View the full text of the exception
+ * in the file doc/FLOSS-exception.txt in this software distribution, or
+ * online at
+ * http://secondlifegrid.net/programs/open_source/licensing/flossexception
+ *
+ * By copying, modifying or distributing this software, you acknowledge
+ * that you have read and understood your obligations described above,
+ * and agree to abide by those obligations.
+ *
+ * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+ * COMPLETENESS OR PERFORMANCE.
+ * $/LicenseInfo$
+ */
+
+#include "llviewerprecompiledheaders.h"
+
+#include "llrecentpeople.h"
+
+#include "llagent.h"
+
+using namespace LLOldEvents;
+
+bool LLRecentPeople::add(const LLUUID& id)
+{
+ if (contains(id) || id == gAgent.getID())
+ return false;
+
+ mList.insert(id);
+ mChangedSignal();
+ return true;
+}
+
+bool LLRecentPeople::contains(const LLUUID& id) const
+{
+ return mList.find(id) != mList.end();
+}
+
+void LLRecentPeople::get(std::vector<LLUUID>& result) const
+{
+ result.clear();
+ for (std::set<LLUUID>::const_iterator pos = mList.begin(); pos != mList.end(); ++pos)
+ result.push_back(*pos);
+}
+
+// virtual
+bool LLRecentPeople::handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
+{
+ (void) userdata;
+ add(event->getValue().asUUID());
+ return true;
+}
diff --git a/indra/newview/llrecentpeople.h b/indra/newview/llrecentpeople.h
new file mode 100644
index 0000000000..40ac80e8bc
--- /dev/null
+++ b/indra/newview/llrecentpeople.h
@@ -0,0 +1,101 @@
+/**
+ * @file llrecentpeople.h
+ * @brief List of people with which the user has recently interacted.
+ *
+ * $LicenseInfo:firstyear=2009&license=viewergpl$
+ *
+ * Copyright (c) 2009, Linden Research, Inc.
+ *
+ * Second Life Viewer Source Code
+ * The source code in this file ("Source Code") is provided by Linden Lab
+ * to you under the terms of the GNU General Public License, version 2.0
+ * ("GPL"), unless you have obtained a separate licensing agreement
+ * ("Other License"), formally executed by you and Linden Lab. Terms of
+ * the GPL can be found in doc/GPL-license.txt in this distribution, or
+ * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
+ *
+ * There are special exceptions to the terms and conditions of the GPL as
+ * it is applied to this Source Code. View the full text of the exception
+ * in the file doc/FLOSS-exception.txt in this software distribution, or
+ * online at
+ * http://secondlifegrid.net/programs/open_source/licensing/flossexception
+ *
+ * By copying, modifying or distributing this software, you acknowledge
+ * that you have read and understood your obligations described above,
+ * and agree to abide by those obligations.
+ *
+ * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+ * COMPLETENESS OR PERFORMANCE.
+ * $/LicenseInfo$
+ */
+
+#ifndef LL_LLRECENTPEOPLE_H
+#define LL_LLRECENTPEOPLE_H
+
+#include "llevent.h"
+#include "llsingleton.h"
+#include "lluuid.h"
+
+#include <vector>
+#include <set>
+#include <boost/signals2.hpp>
+
+/**
+ * List of people the agent recently interacted with.
+ *
+ * Includes: anyone with whom the user IM'd or called
+ * (1:1 and ad-hoc but not SL Group chat),
+ * anyone with whom the user has had a transaction
+ * (inventory offer, friend request, etc),
+ * and anyone that has chatted within chat range of the user in-world.
+ *
+ *TODO: purge least recently added items?
+ */
+class LLRecentPeople: public LLSingleton<LLRecentPeople>, public LLOldEvents::LLSimpleListener
+{
+ LOG_CLASS(LLRecentPeople);
+public:
+ typedef boost::signals2::signal<void ()> signal_t;
+
+ /**
+ * Add specified avatar to the list if it's not there already.
+ *
+ * @param id avatar to add.
+ * @return false if the avatar is in the list already, true otherwisr
+ */
+ bool add(const LLUUID& id);
+
+ /**
+ * @param id avatar to search.
+ * @return true if the avatar is in the list, false otherwise.
+ */
+ bool contains(const LLUUID& id) const;
+
+ /**
+ * Get the whole list.
+ *
+ * @param result where to put the result.
+ */
+ void get(std::vector<LLUUID>& result) const;
+
+ /**
+ * Set callback to be called when the list changed.
+ *
+ * Multiple callbacks can be set.
+ *
+ * @return no connection; use boost::bind + boost::signals2::trackable to disconnect slots.
+ */
+ void setChangedCallback(const signal_t::slot_type& cb) { mChangedSignal.connect(cb); }
+
+ /**
+ * LLSimpleListener interface.
+ */
+ /*virtual*/ bool handleEvent(LLPointer<LLOldEvents::LLEvent> event, const LLSD& userdata);
+
+private:
+ std::set<LLUUID> mList;
+ signal_t mChangedSignal;
+};
+
+#endif // LL_LLRECENTPEOPLE_H
diff --git a/indra/newview/llremoteparcelrequest.cpp b/indra/newview/llremoteparcelrequest.cpp
index 8ff4dea2b1..1ac0175b83 100644
--- a/indra/newview/llremoteparcelrequest.cpp
+++ b/indra/newview/llremoteparcelrequest.cpp
@@ -34,8 +34,7 @@
#include "llviewerprecompiledheaders.h"
-#include "llagent.h"
-#include "llremoteparcelrequest.h"
+#include "message.h"
#include "llpanelplace.h"
#include "llpanel.h"
@@ -43,37 +42,132 @@
#include "llsdserialize.h"
#include "llviewerregion.h"
#include "llview.h"
-#include "message.h"
-LLRemoteParcelRequestResponder::LLRemoteParcelRequestResponder(LLHandle<LLPanel> place_panel_handle)
-{
- mPlacePanelHandle = place_panel_handle;
-}
-/*virtual*/
+#include "llagent.h"
+#include "llremoteparcelrequest.h"
+
+
+LLRemoteParcelRequestResponder::LLRemoteParcelRequestResponder(LLHandle<LLRemoteParcelInfoObserver> observer_handle)
+ : mObserverHandle(observer_handle)
+{}
+
+//If we get back a normal response, handle it here
+//virtual
void LLRemoteParcelRequestResponder::result(const LLSD& content)
{
LLUUID parcel_id = content["parcel_id"];
- LLPanelPlace* place_panelp = (LLPanelPlace*)mPlacePanelHandle.get();
-
- if(place_panelp)
+ // Panel inspecting the information may be closed and destroyed
+ // before this response is received.
+ LLRemoteParcelInfoObserver* observer = mObserverHandle.get();
+ if (observer)
{
- place_panelp->setParcelID(parcel_id);
+ observer->setParcelID(parcel_id);
}
-
}
-/*virtual*/
+//If we get back an error (not found, etc...), handle it here
+//virtual
void LLRemoteParcelRequestResponder::error(U32 status, const std::string& reason)
{
llinfos << "LLRemoteParcelRequest::error("
<< status << ": " << reason << ")" << llendl;
- LLPanelPlace* place_panelp = (LLPanelPlace*)mPlacePanelHandle.get();
- if(place_panelp)
+ // Panel inspecting the information may be closed and destroyed
+ // before this response is received.
+ LLRemoteParcelInfoObserver* observer = mObserverHandle.get();
+ if (observer)
+ {
+ observer->setErrorStatus(status, reason);
+ }
+}
+
+void LLRemoteParcelInfoProcessor::addObserver(const LLUUID& parcel_id, LLRemoteParcelInfoObserver* observer)
+{
+ // Check if the observer is alredy in observsrs list for this UUID
+ observer_multimap_t::iterator it;
+
+ it = mObservers.find(parcel_id);
+ while (it != mObservers.end())
{
- place_panelp->setErrorStatus(status, reason);
+ if (it->second == observer)
+ {
+ return;
+ }
+ else
+ {
+ ++it;
+ }
}
+ mObservers.insert(std::pair<LLUUID, LLRemoteParcelInfoObserver*>(parcel_id, observer));
}
+void LLRemoteParcelInfoProcessor::removeObserver(const LLUUID& parcel_id, LLRemoteParcelInfoObserver* observer)
+{
+ if (!observer)
+ {
+ return;
+ }
+
+ observer_multimap_t::iterator it;
+
+ it = mObservers.find(parcel_id);
+ while (it != mObservers.end())
+ {
+ if (it->second == observer)
+ {
+ mObservers.erase(it);
+ break;
+ }
+ else
+ {
+ ++it;
+ }
+ }
+}
+
+//static
+void LLRemoteParcelInfoProcessor::processParcelInfoReply(LLMessageSystem* msg, void**)
+{
+ LLParcelData parcel_data;
+
+ msg->getUUID ("Data", "ParcelID", parcel_data.parcel_id);
+ msg->getUUID ("Data", "OwnerID", parcel_data.owner_id);
+ msg->getString ("Data", "Name", parcel_data.name);
+ msg->getString ("Data", "Desc", parcel_data.desc);
+ msg->getS32 ("Data", "ActualArea", parcel_data.actual_area);
+ msg->getS32 ("Data", "BillableArea", parcel_data.billable_area);
+ msg->getU8 ("Data", "Flags", parcel_data.flags);
+ msg->getF32 ("Data", "GlobalX", parcel_data.global_x);
+ msg->getF32 ("Data", "GlobalY", parcel_data.global_y);
+ msg->getF32 ("Data", "GlobalZ", parcel_data.global_z);
+ msg->getString ("Data", "SimName", parcel_data.sim_name);
+ msg->getUUID ("Data", "SnapshotID", parcel_data.snapshot_id);
+ msg->getF32 ("Data", "Dwell", parcel_data.dwell);
+ msg->getS32 ("Data", "SalePrice", parcel_data.sale_price);
+ msg->getS32 ("Data", "AuctionID", parcel_data.auction_id);
+
+ LLRemoteParcelInfoProcessor::observer_multimap_t observers = LLRemoteParcelInfoProcessor::getInstance()->mObservers;
+
+ observer_multimap_t::iterator oi = observers.find(parcel_data.parcel_id);
+ observer_multimap_t::iterator end = observers.upper_bound(parcel_data.parcel_id);
+ for (; oi != end; ++oi)
+ {
+ oi->second->processParcelInfo(parcel_data);
+ LLRemoteParcelInfoProcessor::getInstance()->removeObserver(parcel_data.parcel_id, oi->second);
+ }
+}
+
+void LLRemoteParcelInfoProcessor::sendParcelInfoRequest(const LLUUID& parcel_id)
+{
+ LLMessageSystem *msg = gMessageSystem;
+
+ msg->newMessage("ParcelInfoRequest");
+ msg->nextBlockFast(_PREHASH_AgentData);
+ msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID() );
+ msg->addUUID("SessionID", gAgent.getSessionID());
+ msg->nextBlock("Data");
+ msg->addUUID("ParcelID", parcel_id);
+ gAgent.sendReliableMessage();
+}
diff --git a/indra/newview/llremoteparcelrequest.h b/indra/newview/llremoteparcelrequest.h
index c92ee3ff3a..3a16e25ef6 100644
--- a/indra/newview/llremoteparcelrequest.h
+++ b/indra/newview/llremoteparcelrequest.h
@@ -38,17 +38,73 @@
#include "llhttpclient.h"
#include "llpanel.h"
+class LLRemoteParcelInfoObserver;
+
class LLRemoteParcelRequestResponder : public LLHTTPClient::Responder
{
public:
- LLRemoteParcelRequestResponder(LLHandle<LLPanel> place_panel_handle);
+ LLRemoteParcelRequestResponder(LLHandle<LLRemoteParcelInfoObserver> observer_handle);
+
//If we get back a normal response, handle it here
- virtual void result(const LLSD& content);
+ /*virtual*/ void result(const LLSD& content);
+
//If we get back an error (not found, etc...), handle it here
- virtual void error(U32 status, const std::string& reason);
+ /*virtual*/ void error(U32 status, const std::string& reason);
+
+protected:
+ LLHandle<LLRemoteParcelInfoObserver> mObserverHandle;
+};
+
+struct LLParcelData
+{
+ LLUUID parcel_id;
+ LLUUID owner_id;
+ std::string name;
+ std::string desc;
+ S32 actual_area;
+ S32 billable_area;
+ U8 flags;
+ F32 global_x;
+ F32 global_y;
+ F32 global_z;
+ std::string sim_name;
+ LLUUID snapshot_id;
+ F32 dwell;
+ S32 sale_price;
+ S32 auction_id;
+};
+
+// An interface class for panels which display parcel information
+// like name, description, area, snapshot etc.
+class LLRemoteParcelInfoObserver
+{
+public:
+ LLRemoteParcelInfoObserver() { mObserverHandle.bind(this); }
+ virtual ~LLRemoteParcelInfoObserver() {}
+ virtual void processParcelInfo(const LLParcelData& parcel_data) = 0;
+ virtual void setParcelID(const LLUUID& parcel_id) = 0;
+ virtual void setErrorStatus(U32 status, const std::string& reason) = 0;
+ LLHandle<LLRemoteParcelInfoObserver> getObserverHandle() const { return mObserverHandle; }
protected:
- LLHandle<LLPanel> mPlacePanelHandle;
+ LLRootHandle<LLRemoteParcelInfoObserver> mObserverHandle;
+};
+
+class LLRemoteParcelInfoProcessor : public LLSingleton<LLRemoteParcelInfoProcessor>
+{
+public:
+ virtual ~LLRemoteParcelInfoProcessor() {}
+
+ void addObserver(const LLUUID& parcel_id, LLRemoteParcelInfoObserver* observer);
+ void removeObserver(const LLUUID& parcel_id, LLRemoteParcelInfoObserver* observer);
+
+ void sendParcelInfoRequest(const LLUUID& parcel_id);
+
+ static void processParcelInfoReply(LLMessageSystem* msg, void**);
+
+private:
+ typedef std::multimap<LLUUID, LLRemoteParcelInfoObserver*> observer_multimap_t;
+ observer_multimap_t mObservers;
};
#endif // LL_LLREMOTEPARCELREQUEST_H
diff --git a/indra/newview/llrootview.h b/indra/newview/llrootview.h
new file mode 100644
index 0000000000..f704fecddd
--- /dev/null
+++ b/indra/newview/llrootview.h
@@ -0,0 +1,51 @@
+/**
+ * @file llrootview.h
+ * @brief Mother of all Views
+ *
+ * $LicenseInfo:firstyear=2001&license=viewergpl$
+ *
+ * Copyright (c) 2001-2009, Linden Research, Inc.
+ *
+ * Second Life Viewer Source Code
+ * The source code in this file ("Source Code") is provided by Linden Lab
+ * to you under the terms of the GNU General Public License, version 2.0
+ * ("GPL"), unless you have obtained a separate licensing agreement
+ * ("Other License"), formally executed by you and Linden Lab. Terms of
+ * the GPL can be found in doc/GPL-license.txt in this distribution, or
+ * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
+ *
+ * There are special exceptions to the terms and conditions of the GPL as
+ * it is applied to this Source Code. View the full text of the exception
+ * in the file doc/FLOSS-exception.txt in this software distribution, or
+ * online at
+ * http://secondlifegrid.net/programs/open_source/licensing/flossexception
+ *
+ * By copying, modifying or distributing this software, you acknowledge
+ * that you have read and understood your obligations described above,
+ * and agree to abide by those obligations.
+ *
+ * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+ * COMPLETENESS OR PERFORMANCE.
+ * $/LicenseInfo$
+ */
+
+#ifndef LL_LLROOTVIEW_H
+#define LL_LLROOTVIEW_H
+
+#include "llview.h"
+#include "lluictrlfactory.h"
+
+class LLRootViewRegistry : public LLChildRegistry<LLRootViewRegistry>
+{};
+
+class LLRootView : public LLView
+{
+public:
+ typedef LLRootViewRegistry child_registry_t;
+
+ LLRootView(const Params& p)
+ : LLView(p)
+ {}
+};
+#endif //LL_LLROOTVIEW_H
diff --git a/indra/newview/llsavedsettingsglue.cpp b/indra/newview/llsavedsettingsglue.cpp
index 073b51f80e..4736afa7ba 100644
--- a/indra/newview/llsavedsettingsglue.cpp
+++ b/indra/newview/llsavedsettingsglue.cpp
@@ -39,37 +39,27 @@
#include "llviewercontrol.h"
-void LLSavedSettingsGlue::setBOOL(LLUICtrl* ctrl, void* data)
+void LLSavedSettingsGlue::setBOOL(LLUICtrl* ctrl, const std::string& name)
{
- const char* name = (const char*)data;
- LLSD value = ctrl->getValue();
- gSavedSettings.setBOOL(name, value.asBoolean());
+ gSavedSettings.setBOOL(name, ctrl->getValue().asBoolean());
}
-void LLSavedSettingsGlue::setS32(LLUICtrl* ctrl, void* data)
+void LLSavedSettingsGlue::setS32(LLUICtrl* ctrl, const std::string& name)
{
- const char* name = (const char*)data;
- LLSD value = ctrl->getValue();
- gSavedSettings.setS32(name, value.asInteger());
+ gSavedSettings.setS32(name, ctrl->getValue().asInteger());
}
-void LLSavedSettingsGlue::setF32(LLUICtrl* ctrl, void* data)
+void LLSavedSettingsGlue::setF32(LLUICtrl* ctrl, const std::string& name)
{
- const char* name = (const char*)data;
- LLSD value = ctrl->getValue();
- gSavedSettings.setF32(name, (F32)value.asReal());
+ gSavedSettings.setF32(name, (F32)ctrl->getValue().asReal());
}
-void LLSavedSettingsGlue::setU32(LLUICtrl* ctrl, void* data)
+void LLSavedSettingsGlue::setU32(LLUICtrl* ctrl, const std::string& name)
{
- const char* name = (const char*)data;
- LLSD value = ctrl->getValue();
- gSavedSettings.setU32(name, (U32)value.asInteger());
+ gSavedSettings.setU32(name, (U32)ctrl->getValue().asInteger());
}
-void LLSavedSettingsGlue::setString(LLUICtrl* ctrl, void* data)
+void LLSavedSettingsGlue::setString(LLUICtrl* ctrl, const std::string& name)
{
- const char* name = (const char*)data;
- LLSD value = ctrl->getValue();
- gSavedSettings.setString(name, value.asString());
+ gSavedSettings.setString(name, ctrl->getValue().asString());
}
diff --git a/indra/newview/llsavedsettingsglue.h b/indra/newview/llsavedsettingsglue.h
index 8a0f36945c..6c8662dd58 100644
--- a/indra/newview/llsavedsettingsglue.h
+++ b/indra/newview/llsavedsettingsglue.h
@@ -42,11 +42,11 @@ class LLUICtrl;
class LLSavedSettingsGlue
{
public:
- static void setBOOL(LLUICtrl* ctrl, void* name);
- static void setS32(LLUICtrl* ctrl, void* name);
- static void setF32(LLUICtrl* ctrl, void* name);
- static void setU32(LLUICtrl* ctrl, void* name);
- static void setString(LLUICtrl* ctrl, void* name);
+ static void setBOOL(LLUICtrl* ctrl, const std::string& name);
+ static void setS32(LLUICtrl* ctrl, const std::string& name);
+ static void setF32(LLUICtrl* ctrl, const std::string& name);
+ static void setU32(LLUICtrl* ctrl, const std::string& name);
+ static void setString(LLUICtrl* ctrl, const std::string& name);
};
#endif
diff --git a/indra/newview/llscreenchannel.cpp b/indra/newview/llscreenchannel.cpp
new file mode 100644
index 0000000000..68996673be
--- /dev/null
+++ b/indra/newview/llscreenchannel.cpp
@@ -0,0 +1,551 @@
+/**
+ * @file llscreenchannel.cpp
+ * @brief Class implements a channel on a screen in which appropriate toasts may appear.
+ *
+ * $LicenseInfo:firstyear=2000&license=viewergpl$
+ *
+ * Copyright (c) 2000-2009, Linden Research, Inc.
+ *
+ * Second Life Viewer Source Code
+ * The source code in this file ("Source Code") is provided by Linden Lab
+ * to you under the terms of the GNU General Public License, version 2.0
+ * ("GPL"), unless you have obtained a separate licensing agreement
+ * ("Other License"), formally executed by you and Linden Lab. Terms of
+ * the GPL can be found in doc/GPL-license.txt in this distribution, or
+ * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
+ *
+ * There are special exceptions to the terms and conditions of the GPL as
+ * it is applied to this Source Code. View the full text of the exception
+ * in the file doc/FLOSS-exception.txt in this software distribution, or
+ * online at
+ * http://secondlifegrid.net/programs/open_source/licensing/flossexception
+ *
+ * By copying, modifying or distributing this software, you acknowledge
+ * that you have read and understood your obligations described above,
+ * and agree to abide by those obligations.
+ *
+ * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+ * COMPLETENESS OR PERFORMANCE.
+ * $/LicenseInfo$
+ */
+
+
+#include "llviewerprecompiledheaders.h" // must be first include
+
+#include "lliconctrl.h"
+#include "lltextbox.h"
+#include "llscreenchannel.h"
+
+#include "lltoastpanel.h"
+#include "llviewercontrol.h"
+#include "llfloaterreg.h"
+#include "lltrans.h"
+
+#include <algorithm>
+
+using namespace LLNotificationsUI;
+
+bool LLScreenChannel::mWasStartUpToastShown = false;
+
+//--------------------------------------------------------------------------
+LLScreenChannel::LLScreenChannel(LLUUID& id): mOverflowToastPanel(NULL), mStartUpToastPanel(NULL),
+ mToastAlignment(NA_BOTTOM), mCanStoreToasts(true),
+ mHiddenToastsNum(0), mOverflowToastHidden(false),
+ mIsHovering(false), mControlHovering(false),
+ mShowToasts(false)
+{
+ mID = id;
+
+ setFollows(FOLLOWS_RIGHT | FOLLOWS_BOTTOM | FOLLOWS_TOP);
+
+ mOverflowFormatString = LLTrans::getString("OverflowInfoChannelString");
+
+ setMouseOpaque( false );
+}
+
+void LLScreenChannel::init(S32 channel_left, S32 channel_right)
+{
+ S32 channel_top = getRootView()->getRect().getHeight() - gSavedSettings.getS32("NavBarMargin");
+ S32 channel_bottom = getRootView()->getRect().mBottom + gSavedSettings.getS32("ChannelBottomPanelMargin");
+ setRect(LLRect(channel_left, channel_top, channel_right, channel_bottom));
+
+}
+
+//--------------------------------------------------------------------------
+LLScreenChannel::~LLScreenChannel()
+{
+}
+
+//--------------------------------------------------------------------------
+void LLScreenChannel::reshape(S32 width, S32 height, BOOL called_from_parent)
+{
+ LLUICtrl::reshape(width, height, called_from_parent);
+ if(mToastAlignment != NA_CENTRE)
+ showToasts();
+}
+
+//--------------------------------------------------------------------------
+void LLScreenChannel::addToast(LLToast::Params p)
+{
+ bool store_toast = !mShowToasts && p.can_be_stored && mCanStoreToasts;
+
+ if(!mShowToasts && !store_toast)
+ {
+ mOnRejectToast(p);
+ return;
+ }
+
+ ToastElem new_toast_elem(p);
+
+ mOverflowToastHidden = false;
+
+ new_toast_elem.toast->setOnFadeCallback(boost::bind(&LLScreenChannel::onToastFade, this, new_toast_elem.toast));
+ if(mControlHovering)
+ {
+ new_toast_elem.toast->setOnToastHoverCallback(boost::bind(&LLScreenChannel::onToastHover, this, _1, _2));
+ }
+
+ if(mShowToasts)
+ {
+ mToastList.push_back(new_toast_elem);
+ showToasts();
+ }
+ else // store_toast
+ {
+ mHiddenToastsNum++;
+ storeToast(new_toast_elem);
+ }
+}
+
+//--------------------------------------------------------------------------
+void LLScreenChannel::onToastFade(LLToast* toast)
+{
+ std::vector<ToastElem>::iterator it = find(mToastList.begin(), mToastList.end(), static_cast<LLPanel*>(toast));
+
+ bool destroy_toast = !mCanStoreToasts || !toast->getCanBeStored();
+ if(destroy_toast)
+ {
+ mToastList.erase(it);
+ toast->mOnToastDestroy(toast);
+ }
+ else
+ {
+ storeToast((*it));
+ mToastList.erase(it);
+ }
+
+ showToasts();
+}
+
+//--------------------------------------------------------------------------
+
+void LLScreenChannel::storeToast(ToastElem& toast_elem)
+{
+ // do not store clones
+ std::vector<ToastElem>::iterator it = find(mStoredToastList.begin(), mStoredToastList.end(), toast_elem.id);
+ if( it != mStoredToastList.end() )
+ return;
+
+ toast_elem.toast->stopTimer();
+ mStoredToastList.push_back(toast_elem);
+ mOnStoreToast(toast_elem.toast->getPanel(), toast_elem.id);
+}
+
+//--------------------------------------------------------------------------
+void LLScreenChannel::loadStoredToastsToChannel()
+{
+ std::vector<ToastElem>::iterator it;
+
+ if(mStoredToastList.size() == 0)
+ return;
+
+ mOverflowToastHidden = false;
+
+ for(it = mStoredToastList.begin(); it != mStoredToastList.end(); ++it)
+ {
+ (*it).toast->resetTimer();
+ mToastList.push_back((*it));
+ }
+
+ mStoredToastList.clear();
+ showToasts();
+}
+
+//--------------------------------------------------------------------------
+void LLScreenChannel::loadStoredToastByIDToChannel(LLUUID id)
+{
+ std::vector<ToastElem>::iterator it = find(mStoredToastList.begin(), mStoredToastList.end(), id);
+
+ if( it == mStoredToastList.end() )
+ return;
+
+ mOverflowToastHidden = false;
+
+ LLToast* toast = (*it).toast;
+ toast->resetTimer();
+ mToastList.push_back((*it));
+ mStoredToastList.erase(it);
+
+ showToasts();
+}
+
+//--------------------------------------------------------------------------
+void LLScreenChannel::removeStoredToastByID(LLUUID id)
+{
+ // *TODO: may be remove this function
+ std::vector<ToastElem>::iterator it = find(mStoredToastList.begin(), mStoredToastList.end(), id);
+
+ if( it == mStoredToastList.end() )
+ return;
+
+ LLToast* toast = (*it).toast;
+ mStoredToastList.erase(it);
+ toast->discardNotification();
+}
+
+//--------------------------------------------------------------------------
+void LLScreenChannel::killToastByNotificationID(LLUUID id)
+{
+ // searching among toasts on a screen
+ std::vector<ToastElem>::iterator it = find(mToastList.begin(), mToastList.end(), id);
+
+ if( it != mToastList.end())
+ {
+ LLToast* toast = (*it).toast;
+ // if it is a notification toast and notification is UnResponded - then respond on it
+ // else - simply destroy a toast
+ //
+ // NOTE: if a notification is unresponded this function will be called twice for the same toast.
+ // At first, the notification will be discarded, at second (it will be caused by discarding),
+ // the toast will be destroyed.
+ if(toast->getIsNotificationUnResponded())
+ {
+ toast->discardNotification();
+ }
+ else
+ {
+ mToastList.erase(it);
+ toast->mOnToastDestroy(toast);
+ showToasts();
+ }
+ return;
+ }
+
+ // searching among stored toasts
+ it = find(mStoredToastList.begin(), mStoredToastList.end(), id);
+
+ if( it != mStoredToastList.end() )
+ {
+ LLToast* toast = (*it).toast;
+ mStoredToastList.erase(it);
+ toast->discardNotification();
+ toast->mOnToastDestroy(toast);
+ }
+}
+
+//--------------------------------------------------------------------------
+void LLScreenChannel::modifyToastByNotificationID(LLUUID id, LLPanel* panel)
+{
+ std::vector<ToastElem>::iterator it = find(mToastList.begin(), mToastList.end(), id);
+
+ if( it != mToastList.end() && panel)
+ {
+ LLToast* toast = (*it).toast;
+ LLPanel* old_panel = toast->getPanel();
+ toast->removeChild(old_panel);
+ delete old_panel;
+ toast->insertPanel(panel);
+ toast->resetTimer();
+ showToasts();
+ }
+}
+
+//--------------------------------------------------------------------------
+void LLScreenChannel::showToasts()
+{
+ if(mToastList.size() == 0 || mIsHovering)
+ return;
+
+ hideToastsFromScreen();
+
+ switch(mToastAlignment)
+ {
+ case NA_TOP :
+ showToastsTop();
+ break;
+
+ case NA_CENTRE :
+ showToastsCentre();
+ break;
+
+ case NA_BOTTOM :
+ showToastsBottom();
+ }
+}
+
+//--------------------------------------------------------------------------
+void LLScreenChannel::showToastsBottom()
+{
+ LLRect toast_rect;
+ S32 bottom = getRect().mBottom;
+ std::vector<ToastElem>::reverse_iterator it;
+
+ for(it = mToastList.rbegin(); it != mToastList.rend(); ++it)
+ {
+ if(it != mToastList.rbegin())
+ {
+ bottom = (*(it-1)).toast->getRect().mTop;
+ }
+
+ toast_rect = (*it).toast->getRect();
+ toast_rect.setLeftTopAndSize(getRect().mLeft, bottom + toast_rect.getHeight()+gSavedSettings.getS32("ToastMargin"), toast_rect.getWidth() ,toast_rect.getHeight());
+ (*it).toast->setRect(toast_rect);
+
+ bool stop_showing_toasts = (*it).toast->getRect().mTop > getRect().getHeight();
+
+ if(!stop_showing_toasts)
+ {
+ if( it != mToastList.rend()-1)
+ {
+ stop_showing_toasts = ((*it).toast->getRect().mTop + gSavedSettings.getS32("OverflowToastHeight") + gSavedSettings.getS32("ToastMargin")) > getRect().getHeight();
+ }
+ }
+
+ if(stop_showing_toasts)
+ break;
+
+ (*it).toast->setVisible(TRUE);
+ }
+
+ if(it != mToastList.rend() && !mOverflowToastHidden)
+ {
+ mHiddenToastsNum = 0;
+ for(; it != mToastList.rend(); it++)
+ {
+ mHiddenToastsNum++;
+ }
+ createOverflowToast(bottom, gSavedSettings.getS32("NotificationToastTime"));
+ }
+}
+
+//--------------------------------------------------------------------------
+void LLScreenChannel::showToastsCentre()
+{
+ LLRect toast_rect;
+ S32 bottom = (getRect().mTop - getRect().mBottom)/2 + mToastList[0].toast->getRect().getHeight()/2;
+ std::vector<ToastElem>::reverse_iterator it;
+
+ for(it = mToastList.rbegin(); it != mToastList.rend(); ++it)
+ {
+ toast_rect = (*it).toast->getRect();
+ toast_rect.setLeftTopAndSize(getRect().mLeft - toast_rect.getWidth() / 2, bottom + toast_rect.getHeight() / 2 + gSavedSettings.getS32("ToastMargin"), toast_rect.getWidth() ,toast_rect.getHeight());
+ (*it).toast->setRect(toast_rect);
+
+ (*it).toast->setVisible(TRUE);
+ }
+}
+
+//--------------------------------------------------------------------------
+void LLScreenChannel::showToastsTop()
+{
+}
+
+//--------------------------------------------------------------------------
+void LLScreenChannel::createOverflowToast(S32 bottom, F32 timer)
+{
+ LLRect toast_rect;
+ LLToast::Params p;
+ p.timer_period = timer;
+ mOverflowToastPanel = new LLToast(p);
+
+ if(!mOverflowToastPanel)
+ return;
+
+ mOverflowToastPanel->setOnFadeCallback(boost::bind(&LLScreenChannel::onOverflowToastHide, this));
+
+ LLTextBox* text_box = mOverflowToastPanel->getChild<LLTextBox>("toast_text");
+ LLIconCtrl* icon = mOverflowToastPanel->getChild<LLIconCtrl>("icon");
+ std::string text = llformat(mOverflowFormatString.c_str(),mHiddenToastsNum);
+ if(mHiddenToastsNum == 1)
+ {
+ text += ".";
+ }
+ else
+ {
+ text += "s.";
+ }
+
+ toast_rect = mOverflowToastPanel->getRect();
+ mOverflowToastPanel->reshape(getRect().getWidth(), toast_rect.getHeight(), true);
+ toast_rect.setLeftTopAndSize(getRect().mLeft, bottom + toast_rect.getHeight()+gSavedSettings.getS32("ToastMargin"), getRect().getWidth(), toast_rect.getHeight());
+ mOverflowToastPanel->setRect(toast_rect);
+
+ text_box->setValue(text);
+ text_box->setVisible(TRUE);
+ icon->setVisible(TRUE);
+
+ mOverflowToastPanel->setVisible(TRUE);
+}
+
+//--------------------------------------------------------------------------
+void LLScreenChannel::onOverflowToastHide()
+{
+ mOverflowToastHidden = true;
+}
+
+//--------------------------------------------------------------------------
+void LLScreenChannel::closeOverflowToastPanel()
+{
+ if(mOverflowToastPanel != NULL)
+ {
+ mOverflowToastPanel->closeFloater();
+ mOverflowToastPanel = NULL;
+ }
+}
+
+//--------------------------------------------------------------------------
+void LLScreenChannel::createStartUpToast(S32 notif_num, S32 bottom, F32 timer)
+{
+ LLRect toast_rect;
+ LLToast::Params p;
+ p.timer_period = timer;
+ mStartUpToastPanel = new LLToast(p);
+
+ if(!mStartUpToastPanel)
+ return;
+
+ mStartUpToastPanel->setOnFadeCallback(boost::bind(&LLScreenChannel::onStartUpToastHide, this));
+
+ LLTextBox* text_box = mStartUpToastPanel->getChild<LLTextBox>("toast_text");
+ LLIconCtrl* icon = mStartUpToastPanel->getChild<LLIconCtrl>("icon");
+
+ std::string mStartUpFormatString;
+
+ if(notif_num == 1)
+ {
+ mStartUpFormatString = LLTrans::getString("StartUpNotification");
+ }
+ else
+ {
+ mStartUpFormatString = LLTrans::getString("StartUpNotifications");
+ }
+
+
+ std::string text = llformat(mStartUpFormatString.c_str(), notif_num);
+
+ toast_rect = mStartUpToastPanel->getRect();
+ mStartUpToastPanel->reshape(getRect().getWidth(), toast_rect.getHeight(), true);
+ toast_rect.setLeftTopAndSize(getRect().mLeft, bottom + toast_rect.getHeight()+gSavedSettings.getS32("ToastMargin"), getRect().getWidth(), toast_rect.getHeight());
+ mStartUpToastPanel->setRect(toast_rect);
+
+ text_box->setValue(text);
+ text_box->setVisible(TRUE);
+ icon->setVisible(TRUE);
+
+ mStartUpToastPanel->setVisible(TRUE);
+}
+
+//--------------------------------------------------------------------------
+void LLScreenChannel::updateStartUpString(S32 num)
+{
+ // *TODO: update string if notifications are arriving while the StartUp toast is on a screen
+}
+
+//--------------------------------------------------------------------------
+void LLScreenChannel::onStartUpToastHide()
+{
+ onCommit();
+}
+
+//--------------------------------------------------------------------------
+void LLScreenChannel::closeStartUpToast()
+{
+ if(mStartUpToastPanel != NULL)
+ {
+ mStartUpToastPanel->closeFloater();
+ mStartUpToastPanel = NULL;
+ }
+}
+
+//--------------------------------------------------------------------------
+void LLScreenChannel::hideToastsFromScreen()
+{
+ closeOverflowToastPanel();
+ for(std::vector<ToastElem>::iterator it = mToastList.begin(); it != mToastList.end(); it++)
+ (*it).toast->setVisible(FALSE);
+}
+
+//--------------------------------------------------------------------------
+void LLScreenChannel::removeToastsFromChannel()
+{
+ hideToastsFromScreen();
+ for(std::vector<ToastElem>::iterator it = mToastList.begin(); it != mToastList.end(); it++)
+ {
+ // *TODO: ivestigate mOnToastDestroy callback - change name or/and place
+ (*it).toast->mOnToastDestroy((*it).toast);
+ }
+ mToastList.clear();
+}
+
+//--------------------------------------------------------------------------
+void LLScreenChannel::removeAndStoreAllVisibleToasts()
+{
+ if(mToastList.size() == 0)
+ return;
+
+ hideToastsFromScreen();
+ for(std::vector<ToastElem>::iterator it = mToastList.begin(); it != mToastList.end(); it++)
+ {
+ if((*it).toast->getCanBeStored())
+ {
+ mStoredToastList.push_back(*it);
+ mOnStoreToast((*it).toast->getPanel(), (*it).id);
+ (*it).toast->stopTimer();
+ }
+ (*it).toast->setVisible(FALSE);
+ }
+
+ mToastList.clear();
+}
+
+//--------------------------------------------------------------------------
+void LLScreenChannel::onToastHover(LLToast* toast, bool mouse_enter)
+{
+ // because of LLViewerWindow::updateUI() that ALWAYS calls onMouseEnter BEFORE onMouseLeave
+ // we must check this to prevent incorrect setting for hovering in a channel
+ std::map<LLToast*, bool>::iterator it_first, it_second;
+ S32 stack_size = mToastEventStack.size();
+ mIsHovering = mouse_enter;
+
+ switch(stack_size)
+ {
+ case 0:
+ mToastEventStack.insert(std::pair<LLToast*, bool>(toast, mouse_enter));
+ break;
+ case 1:
+ it_first = mToastEventStack.begin();
+ if((*it_first).second && !mouse_enter && ((*it_first).first != toast) )
+ {
+ mToastEventStack.clear();
+ mIsHovering = true;
+ }
+ else
+ {
+ mToastEventStack.clear();
+ mToastEventStack.insert(std::pair<LLToast*, bool>(toast, mouse_enter));
+ }
+ break;
+ default:
+ LL_ERRS ("LLScreenChannel::onToastHover: stack size error " ) << stack_size << llendl;
+ }
+
+ if(!mIsHovering)
+ showToasts();
+}
+
+//--------------------------------------------------------------------------
+
+
+
+
diff --git a/indra/newview/llscreenchannel.h b/indra/newview/llscreenchannel.h
new file mode 100644
index 0000000000..746580b574
--- /dev/null
+++ b/indra/newview/llscreenchannel.h
@@ -0,0 +1,216 @@
+/**
+ * @file llscreenchannel.h
+ * @brief Class implements a channel on a screen in which appropriate toasts may appear.
+ *
+ * $LicenseInfo:firstyear=2003&license=viewergpl$
+ *
+ * Copyright (c) 2003-2009, Linden Research, Inc.
+ *
+ * Second Life Viewer Source Code
+ * The source code in this file ("Source Code") is provided by Linden Lab
+ * to you under the terms of the GNU General Public License, version 2.0
+ * ("GPL"), unless you have obtained a separate licensing agreement
+ * ("Other License"), formally executed by you and Linden Lab. Terms of
+ * the GPL can be found in doc/GPL-license.txt in this distribution, or
+ * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
+ *
+ * There are special exceptions to the terms and conditions of the GPL as
+ * it is applied to this Source Code. View the full text of the exception
+ * in the file doc/FLOSS-exception.txt in this software distribution, or
+ * online at
+ * http://secondlifegrid.net/programs/open_source/licensing/flossexception
+ *
+ * By copying, modifying or distributing this software, you acknowledge
+ * that you have read and understood your obligations described above,
+ * and agree to abide by those obligations.
+ *
+ * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+ * COMPLETENESS OR PERFORMANCE.
+ * $/LicenseInfo$
+ */
+
+#ifndef LL_LLSCREENCHANNEL_H
+#define LL_LLSCREENCHANNEL_H
+
+#include "lltoast.h"
+
+#include <map>
+#include <boost/shared_ptr.hpp>
+
+namespace LLNotificationsUI
+{
+
+typedef enum e_notification_toast_alignment
+{
+ NA_TOP,
+ NA_CENTRE,
+ NA_BOTTOM,
+} EToastAlignment;
+
+
+/**
+ * Screen channel manages toasts visibility and positioning on the screen.
+ */
+class LLScreenChannel : public LLUICtrl
+{
+ friend class LLChannelManager;
+public:
+ LLScreenChannel(LLUUID& id);
+ virtual ~LLScreenChannel();
+
+ // Channel's outfit-functions
+ // classic reshape
+ void reshape(S32 width, S32 height, BOOL called_from_parent = TRUE);
+ // initialization of channel's shape and position
+ void init(S32 channel_left, S32 channel_right);
+ // set allignment of toasts inside a channel
+ void setToastAlignment(e_notification_toast_alignment align) {mToastAlignment = align;}
+ // set a template for a string in the OverflowToast
+ void setOverflowFormatString ( std::string str) { mOverflowFormatString = str; }
+
+ // Operating with toasts
+ // add a toast to a channel
+ void addToast(LLToast::Params p);
+ // kill or modify a toast by its ID
+ void killToastByNotificationID(LLUUID id);
+ void modifyToastByNotificationID(LLUUID id, LLPanel* panel);
+ // hide all toasts from screen, but not remove them from a channel
+ void hideToastsFromScreen();
+ // removes all toasts from a channel
+ void removeToastsFromChannel();
+ // show all toasts in a channel
+ void showToasts();
+ //
+ void loadStoredToastsToChannel();
+ // finds a toast among stored by its ID and throws it on a screen to a channel
+ void loadStoredToastByIDToChannel(LLUUID id);
+ // removes a toast from stored finding it by its ID
+ void removeStoredToastByID(LLUUID id);
+ // remove all toasts from screen and store them
+ void removeAndStoreAllVisibleToasts();
+ // close the Overflow Toast
+ void closeOverflowToastPanel();
+ // close the StartUp Toast
+ void closeStartUpToast();
+
+ // Channel's behavior-functions
+ // set whether a channel will control hovering inside itself or not
+ void setControlHovering(bool control) { mControlHovering = control; }
+ // set Hovering flag for a channel
+ void setHovering(bool hovering) { mIsHovering = hovering; }
+ // set whether a channel will store faded toasts or not
+ void setCanStoreToasts(bool store) { mCanStoreToasts = store; }
+ // tell all channels that the StartUp toast was shown and allow them showing of toasts
+ static void setStartUpToastShown() { mWasStartUpToastShown = true; }
+ // get StartUp Toast's state
+ static bool getStartUpToastShown() { return mWasStartUpToastShown; }
+ // set mode for dislaying of toasts
+ void setDisplayToastsAlways(bool display_toasts) { mDisplayToastsAlways = display_toasts; }
+ // get mode for dislaying of toasts
+ bool getDisplayToastsAlways() { return mDisplayToastsAlways; }
+ // tell a channel to show toasts or not
+ void setShowToasts(bool show) { mShowToasts = show; }
+ // determine whether channel shows toasts or not
+ bool getShowToasts() { return mShowToasts; }
+
+ // Channel's other interface functions functions
+ // get number of hidden notifications from a channel
+ S32 getNumberOfHiddenToasts() { return mHiddenToastsNum;}
+ // update number of notifications in the StartUp Toast
+ void updateStartUpString(S32 num);
+ // get toast allignment preset for a channel
+ e_notification_toast_alignment getToastAlignment() {return mToastAlignment;}
+ // get ID of a channel
+ LLUUID getChannelID() { return mID; }
+
+ // Channel's callbacks
+ // callback for storing of faded toasts
+ typedef boost::function<void (LLPanel* info_panel, const LLUUID id)> store_tost_callback_t;
+ typedef boost::signals2::signal<void (LLPanel* info_panel, const LLUUID id)> store_tost_signal_t;
+ store_tost_signal_t mOnStoreToast;
+ boost::signals2::connection setOnStoreToastCallback(store_tost_callback_t cb) { return mOnStoreToast.connect(cb); }
+ // callback for discarding of a rejected toast
+ typedef boost::function<void (LLToast::Params p)> reject_tost_callback_t;
+ typedef boost::signals2::signal<void (LLToast::Params p)> reject_tost_signal_t;
+ reject_tost_signal_t mOnRejectToast;
+ boost::signals2::connection setOnRejectToastCallback(reject_tost_callback_t cb) { return mOnRejectToast.connect(cb); }
+
+private:
+ struct ToastElem
+ {
+ LLUUID id;
+ LLToast* toast;
+
+ ToastElem(LLToast::Params p) : id(p.id)
+ {
+ toast = new LLToast(p);
+ }
+
+ ToastElem(const ToastElem& toast_elem)
+ {
+ id = toast_elem.id;
+ toast = toast_elem.toast;
+ }
+
+ bool operator == (const LLUUID &id_op) const
+ {
+ return (id == id_op);
+ }
+
+ bool operator == (LLPanel* panel_op) const
+ {
+ return (toast == panel_op);
+ }
+ };
+
+ // Channel's handlers
+ void onToastHover(LLToast* toast, bool mouse_enter);
+ void onToastFade(LLToast* toast);
+ void onOverflowToastHide();
+ void onStartUpToastHide();
+
+ //
+ void storeToast(ToastElem& toast_elem);
+
+ // show-functions depending on allignment of toasts
+ void showToastsBottom();
+ void showToastsCentre();
+ void showToastsTop();
+
+ // create the Overflow Toast
+ void createOverflowToast(S32 bottom, F32 timer);
+
+ // create the StartUp Toast
+ void createStartUpToast(S32 notif_num, S32 bottom, F32 timer);
+
+ // Channel's flags
+ static bool mWasStartUpToastShown;
+ bool mControlHovering;
+ bool mIsHovering;
+ bool mCanStoreToasts;
+ bool mDisplayToastsAlways;
+ bool mOverflowToastHidden;
+ // controls whether a channel shows toasts or not
+ bool mShowToasts;
+ //
+ e_notification_toast_alignment mToastAlignment;
+
+ // attributes for the Overflow Toast
+ S32 mHiddenToastsNum;
+ LLToast* mOverflowToastPanel;
+ std::string mOverflowFormatString;
+
+ // attributes for the StartUp Toast
+ LLToast* mStartUpToastPanel;
+
+ // channel's ID
+ LLUUID mID;
+
+ std::vector<ToastElem> mToastList;
+ std::vector<ToastElem> mStoredToastList;
+ std::map<LLToast*, bool> mToastEventStack;
+};
+
+}
+#endif
diff --git a/indra/newview/llselectmgr.cpp b/indra/newview/llselectmgr.cpp
index 0c6b2980dc..32fe996125 100644
--- a/indra/newview/llselectmgr.cpp
+++ b/indra/newview/llselectmgr.cpp
@@ -57,8 +57,10 @@
#include "llfloaterinspect.h"
#include "llfloaterproperties.h"
#include "llfloaterreporter.h"
+#include "llfloaterreg.h"
#include "llfloatertools.h"
#include "llframetimer.h"
+#include "llfocusmgr.h"
#include "llhudeffecttrail.h"
#include "llhudmanager.h"
#include "llinventorymodel.h"
@@ -73,13 +75,15 @@
#include "llui.h"
#include "llviewercamera.h"
#include "llviewercontrol.h"
-#include "llviewerimagelist.h"
+#include "llviewertexturelist.h"
+#include "llviewermedia.h"
+#include "llviewermediafocus.h"
#include "llviewermenu.h"
#include "llviewerobject.h"
#include "llviewerobjectlist.h"
#include "llviewerregion.h"
#include "llviewerstats.h"
-#include "llvoavatar.h"
+#include "llvoavatarself.h"
#include "llvovolume.h"
#include "pipeline.h"
@@ -100,10 +104,10 @@ const S32 MAX_OBJECTS_PER_PACKET = 254;
// Globals
//
-BOOL gDebugSelectMgr = FALSE;
+//BOOL gDebugSelectMgr = FALSE;
-BOOL gHideSelectedObjects = FALSE;
-BOOL gAllowSelectAvatar = FALSE;
+//BOOL gHideSelectedObjects = FALSE;
+//BOOL gAllowSelectAvatar = FALSE;
BOOL LLSelectMgr::sRectSelectInclusive = TRUE;
BOOL LLSelectMgr::sRenderHiddenSelections = TRUE;
@@ -172,6 +176,9 @@ LLObjectSelection *get_null_object_selection()
// LLSelectMgr()
//-----------------------------------------------------------------------------
LLSelectMgr::LLSelectMgr()
+ : mHideSelectedObjects(LLCachedControl<bool>(gSavedSettings, "HideSelectedObjects", FALSE)),
+ mAllowSelectAvatar( LLCachedControl<bool>(gSavedSettings, "AllowSelectAvatar", FALSE)),
+ mDebugSelectMgr(LLCachedControl<bool>(gSavedSettings, "DebugSelectMgr", FALSE))
{
mTEMode = FALSE;
mLastCameraPos.clearVec();
@@ -184,12 +191,12 @@ LLSelectMgr::LLSelectMgr()
sHighlightUAnim = gSavedSettings.getF32("SelectionHighlightUAnim");
sHighlightVAnim = gSavedSettings.getF32("SelectionHighlightVAnim");
- sSilhouetteParentColor = gColors.getColor("SilhouetteParentColor");
- sSilhouetteChildColor = gColors.getColor("SilhouetteChildColor");
- sHighlightParentColor = gColors.getColor("HighlightParentColor");
- sHighlightChildColor = gColors.getColor("HighlightChildColor");
- sHighlightInspectColor = gColors.getColor("HighlightInspectColor");
- sContextSilhouetteColor = gColors.getColor("ContextSilhouetteColor")*0.5f;
+ sSilhouetteParentColor =LLUIColorTable::instance().getColor("SilhouetteParentColor");
+ sSilhouetteChildColor = LLUIColorTable::instance().getColor("SilhouetteChildColor");
+ sHighlightParentColor = LLUIColorTable::instance().getColor("HighlightParentColor");
+ sHighlightChildColor = LLUIColorTable::instance().getColor("HighlightChildColor");
+ sHighlightInspectColor = LLUIColorTable::instance().getColor("HighlightInspectColor");
+ sContextSilhouetteColor = LLUIColorTable::instance().getColor("ContextSilhouetteColor")*0.5f;
sRenderLightRadius = gSavedSettings.getBOOL("RenderLightRadius");
@@ -202,6 +209,8 @@ LLSelectMgr::LLSelectMgr()
mSelectedObjects = new LLObjectSelection();
mHoverObjects = new LLObjectSelection();
mHighlightedObjects = new LLObjectSelection();
+
+
}
@@ -673,7 +682,7 @@ void LLSelectMgr::addAsFamily(std::vector<LLViewerObject*>& objects, BOOL add_to
// Can't select yourself
if (objectp->mID == gAgentID
- && !gAllowSelectAvatar)
+ && !LLSelectMgr::getInstance()->mAllowSelectAvatar)
{
continue;
}
@@ -768,7 +777,7 @@ void LLSelectMgr::addAsIndividual(LLViewerObject *objectp, S32 face, BOOL undoab
}
-LLObjectSelectionHandle LLSelectMgr::setHoverObject(LLViewerObject *objectp)
+LLObjectSelectionHandle LLSelectMgr::setHoverObject(LLViewerObject *objectp, S32 face)
{
// Always blitz hover list when setting
mHoverObjects->deleteAllNodes();
@@ -800,6 +809,7 @@ LLObjectSelectionHandle LLSelectMgr::setHoverObject(LLViewerObject *objectp)
{
LLViewerObject* cur_objectp = *iter;
LLSelectNode* nodep = new LLSelectNode(cur_objectp, FALSE);
+ nodep->selectTE(face, TRUE);
mHoverObjects->addNodeAtEnd(nodep);
}
@@ -824,8 +834,8 @@ void LLSelectMgr::highlightObjectOnly(LLViewerObject* objectp)
return;
}
- if ((gSavedSettings.getBOOL("SelectOwnedOnly") && !objectp->permYouOwner()) ||
- (gSavedSettings.getBOOL("SelectMovableOnly") && !objectp->permMove()))
+ if ((gSavedSettings.getBOOL("SelectOwnedOnly") && !objectp->permYouOwner())
+ || (gSavedSettings.getBOOL("SelectMovableOnly") && !objectp->permMove()))
{
// only select my own objects
return;
@@ -1419,7 +1429,7 @@ void LLSelectMgr::selectionSetImage(const LLUUID& imageid)
// Texture picker defaults aren't inventory items
// * Don't need to worry about permissions for them
// * Can just apply the texture and be done with it.
- objectp->setTEImage(te, gImageList.getImage(mImageID, TRUE, FALSE));
+ objectp->setTEImage(te, LLViewerTextureManager::getFetchedTexture(mImageID, TRUE, FALSE, LLViewerTexture::LOD_TEXTURE));
}
return true;
}
@@ -1575,7 +1585,7 @@ BOOL LLSelectMgr::selectionRevertTextures()
}
else
{
- object->setTEImage(te, gImageList.getImage(id));
+ object->setTEImage(te, LLViewerTextureManager::getFetchedTexture(id, TRUE, FALSE, LLViewerTexture::LOD_TEXTURE));
}
}
}
@@ -2691,7 +2701,7 @@ void LLSelectMgr::selectDelete()
}
LLNotification::Params params("ConfirmObjectDeleteLock");
- params.functor(boost::bind(&LLSelectMgr::confirmDelete, _1, _2, getSelection()));
+ params.functor.function(boost::bind(&LLSelectMgr::confirmDelete, _1, _2, getSelection()));
if(locked_but_deleteable_object ||
no_copy_but_deleteable_object ||
@@ -3443,7 +3453,7 @@ void LLSelectMgr::deselectAllIfTooFar()
if (select_dist_sq > deselect_dist_sq)
{
- if (gDebugSelectMgr)
+ if (mDebugSelectMgr)
{
llinfos << "Selection manager: auto-deselecting, select_dist = " << fsqrtf(select_dist_sq) << llendl;
llinfos << "agent pos global = " << gAgent.getPositionGlobal() << llendl;
@@ -4444,10 +4454,9 @@ void LLSelectMgr::processObjectPropertiesFamily(LLMessageSystem* msg, void** use
msg->getStringFast(_PREHASH_ObjectData, _PREHASH_Description, desc);
// the reporter widget askes the server for info about picked objects
- if (request_flags & (COMPLAINT_REPORT_REQUEST | BUG_REPORT_REQUEST))
+ if (request_flags & COMPLAINT_REPORT_REQUEST )
{
- EReportType report_type = (COMPLAINT_REPORT_REQUEST & request_flags) ? COMPLAINT_REPORT : BUG_REPORT;
- LLFloaterReporter *reporterp = LLFloaterReporter::getReporter(report_type);
+ LLFloaterReporter *reporterp = LLFloaterReg::findTypedInstance<LLFloaterReporter>("reporter");
if (reporterp)
{
std::string fullname;
@@ -4538,7 +4547,7 @@ void LLSelectMgr::updateSilhouettes()
if (!mSilhouetteImagep)
{
- mSilhouetteImagep = gImageList.getImageFromFile("silhouette.j2c", TRUE, TRUE);
+ mSilhouetteImagep = LLViewerTextureManager::getFetchedTextureFromFile("silhouette.j2c", TRUE, TRUE);
}
mHighlightedObjects->cleanupNodes();
@@ -4560,54 +4569,7 @@ void LLSelectMgr::updateSilhouettes()
std::vector<LLViewerObject*> changed_objects;
- if (mSelectedObjects->getNumNodes())
- {
- //gGLSPipelineSelection.set();
-
- //mSilhouetteImagep->bindTexture();
- //glAlphaFunc(GL_GREATER, sHighlightAlphaTest);
-
- for (S32 pass = 0; pass < 2; pass++)
- {
- for (LLObjectSelection::iterator iter = mSelectedObjects->begin();
- iter != mSelectedObjects->end(); iter++)
- {
- LLSelectNode* node = *iter;
- LLViewerObject* objectp = node->getObject();
- if (!objectp)
- continue;
- // do roots first, then children so that root flags are cleared ASAP
- BOOL roots_only = (pass == 0);
- BOOL is_root = (objectp->isRootEdit());
- if (roots_only != is_root || objectp->mDrawable.isNull())
- {
- continue;
- }
-
- if (!node->mSilhouetteExists
- || objectp->isChanged(LLXform::SILHOUETTE)
- || (objectp->getParent() && objectp->getParent()->isChanged(LLXform::SILHOUETTE)))
- {
- if (num_sils_genned++ < MAX_SILS_PER_FRAME)// && objectp->mDrawable->isVisible())
- {
- generateSilhouette(node, LLViewerCamera::getInstance()->getOrigin());
- changed_objects.push_back(objectp);
- }
- else if (objectp->isAttachment())
- {
- //RN: hack for orthogonal projection of HUD attachments
- LLViewerJointAttachment* attachment_pt = (LLViewerJointAttachment*)objectp->getRootEdit()->mDrawable->getParent();
- if (attachment_pt && attachment_pt->getIsHUDAttachment())
- {
- LLVector3 camera_pos = LLVector3(-10000.f, 0.f, 0.f);
- generateSilhouette(node, camera_pos);
- }
- }
- }
- }
- }
- }
-
+ updateSelectionSilhouette(mSelectedObjects, num_sils_genned, changed_objects);
if (mRectSelectedObjects.size() > 0)
{
//gGLSPipelineSelection.set();
@@ -4801,6 +4763,56 @@ void LLSelectMgr::updateSilhouettes()
//gGL.setAlphaRejectSettings(LLRender::CF_DEFAULT);
}
+void LLSelectMgr::updateSelectionSilhouette(LLObjectSelectionHandle object_handle, S32& num_sils_genned, std::vector<LLViewerObject*>& changed_objects)
+{
+ if (object_handle->getNumNodes())
+ {
+ //gGLSPipelineSelection.set();
+
+ //mSilhouetteImagep->bindTexture();
+ //glAlphaFunc(GL_GREATER, sHighlightAlphaTest);
+
+ for (S32 pass = 0; pass < 2; pass++)
+ {
+ for (LLObjectSelection::iterator iter = object_handle->begin();
+ iter != object_handle->end(); iter++)
+ {
+ LLSelectNode* node = *iter;
+ LLViewerObject* objectp = node->getObject();
+ if (!objectp)
+ continue;
+ // do roots first, then children so that root flags are cleared ASAP
+ BOOL roots_only = (pass == 0);
+ BOOL is_root = (objectp->isRootEdit());
+ if (roots_only != is_root || objectp->mDrawable.isNull())
+ {
+ continue;
+ }
+
+ if (!node->mSilhouetteExists
+ || objectp->isChanged(LLXform::SILHOUETTE)
+ || (objectp->getParent() && objectp->getParent()->isChanged(LLXform::SILHOUETTE)))
+ {
+ if (num_sils_genned++ < MAX_SILS_PER_FRAME)// && objectp->mDrawable->isVisible())
+ {
+ generateSilhouette(node, LLViewerCamera::getInstance()->getOrigin());
+ changed_objects.push_back(objectp);
+ }
+ else if (objectp->isAttachment())
+ {
+ //RN: hack for orthogonal projection of HUD attachments
+ LLViewerJointAttachment* attachment_pt = (LLViewerJointAttachment*)objectp->getRootEdit()->mDrawable->getParent();
+ if (attachment_pt && attachment_pt->getIsHUDAttachment())
+ {
+ LLVector3 camera_pos = LLVector3(-10000.f, 0.f, 0.f);
+ generateSilhouette(node, camera_pos);
+ }
+ }
+ }
+ }
+ }
+ }
+}
void LLSelectMgr::renderSilhouettes(BOOL for_hud)
{
if (!mRenderSilhouettes)
@@ -4808,7 +4820,7 @@ void LLSelectMgr::renderSilhouettes(BOOL for_hud)
return;
}
- gGL.getTexUnit(0)->bind(mSilhouetteImagep.get());
+ gGL.getTexUnit(0)->bind(mSilhouetteImagep);
LLGLSPipelineSelection gls_select;
gGL.setAlphaRejectSettings(LLRender::CF_GREATER, 0.f);
LLGLEnable blend(GL_BLEND);
@@ -4837,8 +4849,13 @@ void LLSelectMgr::renderSilhouettes(BOOL for_hud)
}
if (mSelectedObjects->getNumNodes())
{
- LLUUID inspect_item_id = LLFloaterInspect::getSelectedUUID();
-
+ LLFloaterInspect* inspect_instance = LLFloaterReg::getTypedInstance<LLFloaterInspect>("inspect");
+ LLUUID inspect_item_id= LLUUID::null;
+ if(inspect_instance)
+ {
+ inspect_item_id = inspect_instance->getSelectedUUID();
+ }
+ LLUUID focus_item_id = LLViewerMediaFocus::getInstance()->getSelectedUUID();
for (S32 pass = 0; pass < 2; pass++)
{
for (LLObjectSelection::iterator iter = mSelectedObjects->begin();
@@ -4852,7 +4869,11 @@ void LLSelectMgr::renderSilhouettes(BOOL for_hud)
{
continue;
}
- if(objectp->getID() == inspect_item_id)
+ if (objectp->getID() == focus_item_id)
+ {
+ node->renderOneSilhouette(gFocusMgr.getFocusColor());
+ }
+ else if(objectp->getID() == inspect_item_id)
{
node->renderOneSilhouette(sHighlightInspectColor);
}
@@ -4934,6 +4955,16 @@ void LLSelectMgr::generateSilhouette(LLSelectNode* nodep, const LLVector3& view_
// Utility classes
//
LLSelectNode::LLSelectNode(LLViewerObject* object, BOOL glow)
+: mObject(object),
+ mIndividualSelection(FALSE),
+ mTransient(FALSE),
+ mValid(FALSE),
+ mPermissions(new LLPermissions()),
+ mInventorySerial(0),
+ mSilhouetteExists(FALSE),
+ mDuplicated(FALSE),
+ mTESelectMask(0),
+ mLastTESelected(0)
{
mObject = object;
selectAllTEs(FALSE);
@@ -4955,11 +4986,7 @@ LLSelectNode::LLSelectNode(LLViewerObject* object, BOOL glow)
LLSelectNode::LLSelectNode(const LLSelectNode& nodep)
{
- S32 i;
- for (i = 0; i < SELECT_MAX_TES; i++)
- {
- mTESelected[i] = nodep.mTESelected[i];
- }
+ mTESelectMask = nodep.mTESelectMask;
mLastTESelected = nodep.mLastTESelected;
mIndividualSelection = nodep.mIndividualSelection;
@@ -5012,10 +5039,7 @@ LLSelectNode::~LLSelectNode()
void LLSelectNode::selectAllTEs(BOOL b)
{
- for (S32 i = 0; i < SELECT_MAX_TES; i++)
- {
- mTESelected[i] = b;
- }
+ mTESelectMask = b ? 0xFFFFFFFF : 0x0;
mLastTESelected = 0;
}
@@ -5025,7 +5049,7 @@ void LLSelectNode::selectTE(S32 te_index, BOOL selected)
{
return;
}
- mTESelected[te_index] = selected;
+ mTESelectMask |= 0x1 << te_index;
mLastTESelected = te_index;
}
@@ -5035,7 +5059,7 @@ BOOL LLSelectNode::isTESelected(S32 te_index)
{
return FALSE;
}
- return mTESelected[te_index];
+ return (mTESelectMask & (0x1 << te_index)) != 0;
}
S32 LLSelectNode::getLastSelectedTE()
@@ -5387,10 +5411,7 @@ void dialog_refresh_all()
gFloaterTools->dirty();
- if( gPieObject->getVisible() )
- {
- gPieObject->arrange();
- }
+ gPieObject->needsArrange();
if( gPieAttachment->getVisible() )
{
@@ -5398,7 +5419,12 @@ void dialog_refresh_all()
}
LLFloaterProperties::dirtyAll();
- LLFloaterInspect::dirty();
+
+ LLFloaterInspect* inspect_instance = LLFloaterReg::getTypedInstance<LLFloaterInspect>("inspect");
+ if(inspect_instance)
+ {
+ inspect_instance->dirty();
+ }
}
S32 get_family_count(LLViewerObject *parent)
diff --git a/indra/newview/llselectmgr.h b/indra/newview/llselectmgr.h
index d6c4b5485d..c41a86e355 100644
--- a/indra/newview/llselectmgr.h
+++ b/indra/newview/llselectmgr.h
@@ -38,7 +38,8 @@
#include "llstring.h"
#include "llundo.h"
#include "lluuid.h"
-#include "llmemory.h"
+#include "llpointer.h"
+#include "llsafehandle.h"
#include "llsaleinfo.h"
#include "llcategory.h"
#include "v3dmath.h"
@@ -48,12 +49,12 @@
#include "llbbox.h"
#include "llpermissions.h"
#include "llviewerobject.h"
-
+#include "llcontrol.h"
#include <deque>
#include "boost/iterator/filter_iterator.hpp"
class LLMessageSystem;
-class LLViewerImage;
+class LLViewerTexture;
class LLViewerObject;
class LLColor4;
class LLVector3;
@@ -138,6 +139,7 @@ public:
void selectTE(S32 te_index, BOOL selected);
BOOL isTESelected(S32 te_index);
S32 getLastSelectedTE();
+ S32 getTESelectMask() { return mTESelectMask; }
void renderOneSilhouette(const LLColor4 &color);
void setTransient(BOOL transient) { mTransient = transient; }
BOOL isTransient() { return mTransient; }
@@ -190,7 +192,7 @@ public:
protected:
LLPointer<LLViewerObject> mObject;
- BOOL mTESelected[SELECT_MAX_TES];
+ S32 mTESelectMask;
S32 mLastTESelected;
};
@@ -338,6 +340,7 @@ public:
static BOOL sRectSelectInclusive; // do we need to surround an object to pick it?
static BOOL sRenderHiddenSelections; // do we show selection silhouettes that are occluded?
static BOOL sRenderLightRadius; // do we show the radius of selected lights?
+
static F32 sHighlightThickness;
static F32 sHighlightUScale;
static F32 sHighlightVScale;
@@ -352,6 +355,10 @@ public:
static LLColor4 sHighlightInspectColor;
static LLColor4 sContextSilhouetteColor;
+ LLCachedControl<bool> mHideSelectedObjects;
+ LLCachedControl<bool> mAllowSelectAvatar;
+ LLCachedControl<bool> mDebugSelectMgr;
+
public:
LLSelectMgr();
~LLSelectMgr();
@@ -403,7 +410,7 @@ public:
// converts all objects currently highlighted to a selection, and returns it
LLObjectSelectionHandle selectHighlightedObjects();
- LLObjectSelectionHandle setHoverObject(LLViewerObject *objectp);
+ LLObjectSelectionHandle setHoverObject(LLViewerObject *objectp, S32 face = -1);
void highlightObjectOnly(LLViewerObject *objectp);
void highlightObjectAndFamily(LLViewerObject *objectp);
@@ -643,6 +650,7 @@ private:
ESelectType getSelectTypeForObject(LLViewerObject* object);
void addAsFamily(std::vector<LLViewerObject*>& objects, BOOL add_to_end = FALSE);
void generateSilhouette(LLSelectNode *nodep, const LLVector3& view_point);
+ void updateSelectionSilhouette(LLObjectSelectionHandle object_handle, S32& num_sils_genned, std::vector<LLViewerObject*>& changed_objects);
// Send one message to each region containing an object on selection list.
void sendListToRegions( const std::string& message_name,
void (*pack_header)(void *user_data),
@@ -650,6 +658,7 @@ private:
void *user_data,
ESendType send_type);
+
static void packAgentID( void *);
static void packAgentAndSessionID(void* user_data);
static void packAgentAndGroupID(void* user_data);
@@ -684,7 +693,7 @@ private:
static bool confirmDelete(const LLSD& notification, const LLSD& response, LLObjectSelectionHandle handle);
private:
- LLPointer<LLViewerImage> mSilhouetteImagep;
+ LLPointer<LLViewerTexture> mSilhouetteImagep;
LLObjectSelectionHandle mSelectedObjects;
LLObjectSelectionHandle mHoverObjects;
LLObjectSelectionHandle mHighlightedObjects;
diff --git a/indra/newview/llsidetray.cpp b/indra/newview/llsidetray.cpp
new file mode 100644
index 0000000000..afa8e5f072
--- /dev/null
+++ b/indra/newview/llsidetray.cpp
@@ -0,0 +1,687 @@
+/**
+ * @file llsidetray.cpp
+ * @brief SideBar implementation
+ *
+ * $LicenseInfo:firstyear=2009&license=viewergpl$
+ *
+ * Copyright (c) 2009, Linden Research, Inc.
+ *
+ * Second Life Viewer Source Code
+ * The source code in this file ("Source Code") is provided by Linden Lab
+ * to you under the terms of the GNU General Public License, version 2.0
+ * ("GPL"), unless you have obtained a separate licensing agreement
+ * ("Other License"), formally executed by you and Linden Lab. Terms of
+ * the GPL can be found in doc/GPL-license.txt in this distribution, or
+ * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
+ *
+ * There are special exceptions to the terms and conditions of the GPL as
+ * it is applied to this Source Code. View the full text of the exception
+ * in the file doc/FLOSS-exception.txt in this software distribution, or
+ * online at
+ * http://secondlifegrid.net/programs/open_source/licensing/flossexception
+ *
+ * By copying, modifying or distributing this software, you acknowledge
+ * that you have read and understood your obligations described above,
+ * and agree to abide by those obligations.
+ *
+ * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+ * COMPLETENESS OR PERFORMANCE.
+ * $/LicenseInfo$
+ */
+
+#include "llviewerprecompiledheaders.h"
+
+#include "lltextbox.h"
+
+#include "llbottomtray.h"
+#include "llsidetray.h"
+#include "llviewerwindow.h"
+#include "llaccordionctrl.h"
+#include "llfocusmgr.h"
+#include "llrootview.h"
+#include "llnavigationbar.h"
+
+#include "llaccordionctrltab.h"
+
+#include "llfloater.h" //for gFloaterView
+#include "lliconctrl.h"//for Home tab icon
+#include "llsidetraypanelcontainer.h"
+#include "llwindow.h"//for SetCursor
+
+//#include "llscrollcontainer.h"
+
+using namespace std;
+
+static LLRootViewRegistry::Register<LLSideTray> t1("side_tray");
+static LLDefaultChildRegistry::Register<LLSideTrayTab> t2("sidetray_tab");
+
+static const std::string COLLAPSED_NAME = "<<";
+static const std::string EXPANDED_NAME = ">>";
+
+static const std::string TAB_PANEL_CAPTION_NAME = "sidetray_tab_panel";
+static const std::string TAB_PANEL_CAPTION_TITLE_BOX = "sidetray_tab_title";
+
+LLSideTray* LLSideTray::sInstance = 0;
+
+class LLSideTrayInfoPanel: public LLPanel
+{
+
+public:
+ LLSideTrayInfoPanel():LLPanel()
+ {
+ setBorderVisible(true);
+ }
+
+ BOOL handleHover(S32 x, S32 y, MASK mask)
+ {
+ getWindow()->setCursor(UI_CURSOR_HAND);
+ return TRUE;
+ }
+
+ BOOL handleMouseUp(S32 x, S32 y, MASK mask)
+ {
+ std::string name = getName();
+ onCommit();
+ LLSideTray::getInstance()->selectTabByName(name);
+ return LLPanel::handleMouseUp(x,y,mask);
+ }
+ void reshape (S32 width, S32 height, BOOL called_from_parent )
+ {
+ return LLPanel::reshape(width, height, called_from_parent);
+ }
+
+};
+
+static LLRegisterPanelClassWrapper<LLSideTrayInfoPanel> t_people("panel_sidetray_home_info");
+
+LLSideTray* LLSideTray::getInstance()
+{
+ if (!sInstance)
+ {
+ sInstance = LLUICtrlFactory::createFromFile<LLSideTray>("panel_side_tray.xml",gViewerWindow->getRootView(), LLRootView::child_registry_t::instance());
+ }
+
+ return sInstance;
+}
+
+bool LLSideTray::instanceCreated ()
+{
+ return sInstance!=0;
+}
+
+LLSideTrayTab::LLSideTrayTab(const Params& params):mMainPanel(0)
+{
+ mImagePath = params.image_path;
+ mTabTitle = params.tab_title;
+ mDescription = params.description;
+
+ // Necessary for focus movement among child controls
+ setFocusRoot(TRUE);
+}
+
+LLSideTrayTab::~LLSideTrayTab()
+{
+}
+
+bool LLSideTrayTab::addChild(LLView* view, S32 tab_group)
+{
+ if(mMainPanel == 0 && TAB_PANEL_CAPTION_NAME != view->getName())//skip our caption panel
+ mMainPanel = view;
+ return LLPanel::addChild(view,tab_group);
+ //return res;
+}
+
+
+
+//virtual
+BOOL LLSideTrayTab::postBuild()
+{
+ LLPanel* title_panel = LLUICtrlFactory::getInstance()->createFromFile<LLPanel>("panel_side_tray_tab_caption.xml",this, child_registry_t::instance());
+ string name = title_panel->getName();
+ LLPanel::addChild(title_panel);
+
+ title_panel->getChild<LLTextBox>(TAB_PANEL_CAPTION_TITLE_BOX)->setValue(mTabTitle);
+
+ static LLUIColor default_background_color = LLUIColorTable::instance().getColor("FloaterDefaultBackgroundColor");
+ static LLUIColor focus_background_color = LLUIColorTable::instance().getColor("FloaterFocusBackgroundColor");
+
+ setTransparentColor(default_background_color);
+ setBackgroundColor(focus_background_color);
+
+ return true;
+}
+
+static const S32 splitter_margin = 1;
+
+//virtual
+void LLSideTrayTab::arrange(S32 width, S32 height )
+{
+ if(!mMainPanel)
+ return;
+
+ S32 offset = 0;
+
+ LLView* title_panel = findChildView(TAB_PANEL_CAPTION_NAME, true);
+
+ if(title_panel)
+ {
+ title_panel->setOrigin( 0, height - title_panel->getRect().getHeight() );
+ offset = title_panel->getRect().getHeight();
+ }
+
+ LLRect sRect = mMainPanel->getRect();
+ sRect.setLeftTopAndSize( splitter_margin, height - offset - splitter_margin, width - 2*splitter_margin, height - offset - 2*splitter_margin);
+ mMainPanel->reshape(sRect.getWidth(),sRect.getHeight());
+ mMainPanel->setRect(sRect);
+
+
+
+}
+
+void LLSideTrayTab::reshape (S32 width, S32 height, BOOL called_from_parent )
+{
+ if(!mMainPanel)
+ return;
+ S32 offset = 0;
+
+ LLView* title_panel = findChildView(TAB_PANEL_CAPTION_NAME, true);
+
+ if(title_panel)
+ {
+ title_panel->setOrigin( 0, height - title_panel->getRect().getHeight() );
+ title_panel->reshape(width,title_panel->getRect().getHeight());
+ offset = title_panel->getRect().getHeight();
+ }
+
+
+
+ LLRect sRect = mMainPanel->getRect();
+ sRect.setLeftTopAndSize( splitter_margin, height - offset - splitter_margin, width - 2*splitter_margin, height - offset - 2*splitter_margin);
+ //mMainPanel->setMaxWidth(sRect.getWidth());
+ mMainPanel->reshape(sRect.getWidth(), sRect.getHeight());
+
+ mMainPanel->setRect(sRect);
+
+}
+
+void LLSideTrayTab::draw()
+{
+ LLPanel::draw();
+
+ //border
+ gl_rect_2d(0,0,getRect().getWidth() - 1,getRect().getHeight() - 1,LLColor4::black,false);
+
+
+}
+
+void LLSideTrayTab::onOpen (const LLSD& key)
+{
+ LLPanel* panel = dynamic_cast<LLPanel*>(mMainPanel);
+ if(panel)
+ panel->onOpen(key);
+}
+
+LLSideTrayTab* LLSideTrayTab::createInstance ()
+{
+ LLSideTrayTab::Params tab_params;
+ tab_params.tab_title("Home");
+
+ LLSideTrayTab* tab = LLUICtrlFactory::create<LLSideTrayTab>(tab_params);
+ return tab;
+}
+
+
+//virtual
+LLSideTray::LLSideTray(Params& params)
+ : LLPanel(params)
+ ,mActiveTab(0)
+ ,mCollapsed(false)
+ ,mCollapseButton(0)
+ ,mMaxBarWidth(params.rect.width)
+{
+ mCollapsed=params.collapsed;
+}
+
+
+BOOL LLSideTray::postBuild()
+{
+ createButtons();
+
+ arrange();
+ selectTabByName("sidebar_home");
+
+ if(mCollapsed)
+ collapseSideBar();
+
+ setMouseOpaque(false);
+ return true;
+}
+
+/**
+ * add new panel to tab with tab_name name
+ * @param tab_name - name of sidebar tab to add new panel
+ * @param panel - pointer to panel
+ */
+bool LLSideTray::addPanel ( const std::string& tab_name
+ ,LLPanel* panel )
+{
+ return false;
+}
+/**
+ * Add new tab to side bar
+ * @param tab_name - name of the new tab
+ * @param image - image for new sidebar button
+ * @param title - title for new tab
+ */
+bool LLSideTray::addTab ( const std::string& tab_name
+ ,const std::string& image
+ ,const std::string& title)
+{
+ LLSideTrayTab::Params params;
+ params.image_path = image;
+ params.tab_title = title;
+ LLSideTrayTab* tab = LLUICtrlFactory::create<LLSideTrayTab> (params);
+ addChild(tab,1);
+ return true;
+}
+
+
+LLSideTrayTab* LLSideTray::getTab(const std::string& name)
+{
+ return getChild<LLSideTrayTab>(name,false);
+}
+
+
+
+void LLSideTray::toggleTabButton (LLSideTrayTab* tab)
+{
+ if(tab == NULL)
+ return;
+ string name = tab->getName();
+ std::map<std::string,LLButton*>::iterator tIt = mTabButtons.find(name);
+ if(tIt!=mTabButtons.end())
+ tIt->second->setToggleState(!tIt->second->getToggleState());
+}
+
+bool LLSideTray::selectTabByIndex(size_t index)
+{
+ if(index>=mTabs.size())
+ return false;
+
+ LLSideTrayTab* sidebar_tab = dynamic_cast<LLSideTrayTab*>(mTabs[index]);
+ if(sidebar_tab == NULL)
+ return false;
+ return selectTabByName(sidebar_tab->getName());
+}
+
+bool LLSideTray::selectTabByName (const std::string& name)
+{
+ LLSideTrayTab* side_bar = getTab(name);
+
+ if(side_bar == mActiveTab)
+ return false;
+ //deselect old tab
+ toggleTabButton(mActiveTab);
+ if(mActiveTab)
+ mActiveTab->setVisible(false);
+
+ //select new tab
+ mActiveTab = side_bar;
+ toggleTabButton(mActiveTab);
+ LLSD key;//empty
+ mActiveTab->onOpen(key);
+
+ mActiveTab->setVisible(true);
+
+ //arrange();
+
+ //hide all tabs - show active tab
+ child_vector_const_iter_t child_it;
+ for ( child_it = mTabs.begin(); child_it != mTabs.end(); ++child_it)
+ {
+ LLSideTrayTab* sidebar_tab = dynamic_cast<LLSideTrayTab*>(*child_it);
+ if(sidebar_tab == NULL)
+ continue;
+ sidebar_tab->setVisible(sidebar_tab == mActiveTab);
+ }
+ return true;
+}
+
+LLButton* LLSideTray::createButton (const std::string& name,const std::string& image,LLUICtrl::commit_callback_t callback)
+{
+ static LLSideTray::Params sidetray_params(LLUICtrlFactory::getDefaultParams<LLSideTray>());
+
+ LLButton::Params bparams;
+
+ LLRect rect;
+ rect.setOriginAndSize(0, 0, sidetray_params.default_button_width, sidetray_params.default_button_height);
+
+ bparams.name(name);
+ bparams.follows.flags (FOLLOWS_LEFT | FOLLOWS_BOTTOM);
+ bparams.rect (rect);
+ bparams.tab_stop(false);
+ bparams.image_unselected.name(sidetray_params.tab_btn_image_normal);
+ bparams.image_selected.name(sidetray_params.tab_btn_image_selected);
+ bparams.image_disabled.name(sidetray_params.tab_btn_image_normal);
+ bparams.image_disabled_selected.name(sidetray_params.tab_btn_image_selected);
+
+ LLButton* button = LLUICtrlFactory::create<LLButton> (bparams);
+ button->setLabel(name);
+ button->setClickedCallback(callback);
+
+ if(image.length())
+ {
+ button->setImageOverlay(image);
+ }
+
+ addChildInBack(button);
+
+ return button;
+}
+
+bool LLSideTray::addChild(LLView* view, S32 tab_group)
+{
+ LLSideTrayTab* tab_panel = dynamic_cast<LLSideTrayTab*>(view);
+
+ if (tab_panel)
+ {
+ mTabs.push_back(tab_panel);
+ }
+
+ return LLUICtrl::addChild(view, tab_group);
+}
+
+
+void LLSideTray::createButtons ()
+{
+ //create show/hide button
+ mCollapseButton = createButton(EXPANDED_NAME,"",boost::bind(&LLSideTray::onToggleCollapse, this));
+
+ //create buttons for tabs
+ child_vector_const_iter_t child_it = mTabs.begin();
+ ++child_it;
+
+ for ( ; child_it != mTabs.end(); ++child_it)
+ {
+ LLSideTrayTab* sidebar_tab = dynamic_cast<LLSideTrayTab*>(*child_it);
+ if(sidebar_tab == NULL)
+ continue;
+
+ string name = sidebar_tab->getName();
+
+ LLButton* button = createButton("",sidebar_tab->mImagePath,boost::bind(&LLSideTray::onTabButtonClick, this, sidebar_tab->getName()));
+ mTabButtons[sidebar_tab->getName()] = button;
+ }
+
+}
+
+void LLSideTray::onTabButtonClick(string name)
+{
+
+ selectTabByName (name);
+ if(mCollapsed)
+ expandSideBar();
+}
+
+void LLSideTray::onToggleCollapse()
+{
+ if(mCollapsed)
+ {
+ expandSideBar();
+ selectTabByName("sidebar_home");
+ }
+ else
+ collapseSideBar();
+}
+
+
+void LLSideTray::reflectCollapseChange()
+{
+ setPanelRect();
+
+ if(mCollapsed)
+ gFloaterView->setSnapOffsetRight(0);
+ else
+ gFloaterView->setSnapOffsetRight(mMaxBarWidth);
+
+ gFloaterView->refresh();
+
+ setFocus( FALSE );
+}
+
+void LLSideTray::arrange ()
+{
+ static LLSideTray::Params sidetray_params(LLUICtrlFactory::getDefaultParams<LLSideTray>());
+
+ setPanelRect();
+
+ LLRect ctrl_rect;
+ ctrl_rect.setLeftTopAndSize(0,getRect().getHeight()-sidetray_params.default_button_width
+ ,sidetray_params.default_button_width
+ ,sidetray_params.default_button_height);
+
+ mCollapseButton->setRect(ctrl_rect);
+
+ //arrange tab buttons
+ //arrange tab buttons
+ child_vector_const_iter_t child_it;
+ int offset = (sidetray_params.default_button_height+sidetray_params.default_button_margin)*2;
+ for ( child_it = mTabs.begin(); child_it != mTabs.end(); ++child_it)
+ {
+ LLSideTrayTab* sidebar_tab = dynamic_cast<LLSideTrayTab*>(*child_it);
+ if(sidebar_tab == NULL)
+ continue;
+
+ ctrl_rect.setLeftTopAndSize(0,getRect().getHeight()-offset
+ ,sidetray_params.default_button_width
+ ,sidetray_params.default_button_height);
+
+ if(mTabButtons.find(sidebar_tab->getName()) == mTabButtons.end())
+ continue;
+
+ LLButton* btn = mTabButtons[sidebar_tab->getName()];
+
+ btn->setRect(ctrl_rect);
+ offset+=sidetray_params.default_button_height;
+ offset+=sidetray_params.default_button_margin;
+
+ btn->setVisible(ctrl_rect.mBottom > 0);
+ }
+
+ ctrl_rect.setLeftTopAndSize(sidetray_params.default_button_width,getRect().getHeight(),mMaxBarWidth,getRect().getHeight());
+
+ //arrange tabs
+ for ( child_it = mTabs.begin(); child_it != mTabs.end(); ++child_it)
+ {
+ LLSideTrayTab* sidebar_tab = dynamic_cast<LLSideTrayTab*>(*child_it);
+ if(sidebar_tab == NULL)
+ continue;
+
+ sidebar_tab->setRect(ctrl_rect);
+ sidebar_tab->arrange(mMaxBarWidth,getRect().getHeight());
+ }
+}
+
+void LLSideTray::collapseSideBar ()
+{
+ mCollapsed = true;
+ mCollapseButton->setLabel(COLLAPSED_NAME);
+ mActiveTab->setVisible(FALSE);
+ reflectCollapseChange();
+ setFocus( FALSE );
+
+}
+void LLSideTray::expandSideBar ()
+{
+ mCollapsed = false;
+ mCollapseButton->setLabel(EXPANDED_NAME);
+ LLSD key;//empty
+ mActiveTab->onOpen(key);
+ mActiveTab->setVisible(TRUE);
+
+ reflectCollapseChange();
+
+}
+
+void LLSideTray::highlightFocused()
+{
+ if(!mActiveTab)
+ return;
+ /* uncomment in case something change
+ BOOL dependent_has_focus = gFocusMgr.childHasKeyboardFocus(this);
+ setBackgroundOpaque( dependent_has_focus );
+ mActiveTab->setBackgroundOpaque( dependent_has_focus );
+ */
+ mActiveTab->setBackgroundOpaque( true );
+
+
+}
+//virtual
+BOOL LLSideTray::handleMouseDown (S32 x, S32 y, MASK mask)
+{
+ BOOL ret = LLPanel::handleMouseDown(x,y,mask);
+ if(ret)
+ setFocus(true);
+ return ret;
+}
+void LLSideTray::reshape (S32 width, S32 height, BOOL called_from_parent)
+{
+
+ LLPanel::reshape(width, height, called_from_parent);
+ if(!mActiveTab)
+ return;
+
+ static LLSideTray::Params sidetray_params(LLUICtrlFactory::getDefaultParams<LLSideTray>());
+
+ setPanelRect();
+
+ LLRect ctrl_rect;
+ ctrl_rect.setLeftTopAndSize(0
+ ,getRect().getHeight()-sidetray_params.default_button_width
+ ,sidetray_params.default_button_width
+ ,sidetray_params.default_button_height);
+
+ mCollapseButton->setRect(ctrl_rect);
+
+ //arrange tab buttons
+ child_vector_const_iter_t child_it;
+ int offset = (sidetray_params.default_button_height+sidetray_params.default_button_margin)*2;
+ for ( child_it = mTabs.begin(); child_it != mTabs.end(); ++child_it)
+ {
+ LLSideTrayTab* sidebar_tab = dynamic_cast<LLSideTrayTab*>(*child_it);
+ if(sidebar_tab == NULL)
+ continue;
+
+ ctrl_rect.setLeftTopAndSize(0,getRect().getHeight()-offset
+ ,sidetray_params.default_button_width
+ ,sidetray_params.default_button_height);
+
+ if(mTabButtons.find(sidebar_tab->getName()) == mTabButtons.end())
+ continue;
+
+ LLButton* btn = mTabButtons[sidebar_tab->getName()];
+
+ btn->setRect(ctrl_rect);
+ offset+=sidetray_params.default_button_height;
+ offset+=sidetray_params.default_button_margin;
+
+ btn->setVisible(ctrl_rect.mBottom > 0);
+ }
+
+ //arrange tabs
+
+ for ( child_it = mTabs.begin(); child_it != mTabs.end(); ++child_it)
+ {
+ LLSideTrayTab* sidebar_tab = dynamic_cast<LLSideTrayTab*>(*child_it);
+ if(sidebar_tab == NULL)
+ continue;
+ sidebar_tab->reshape(mMaxBarWidth,getRect().getHeight());
+ ctrl_rect.setLeftTopAndSize(sidetray_params.default_button_width,getRect().getHeight(),mMaxBarWidth,getRect().getHeight());
+ sidebar_tab->setRect(ctrl_rect);
+
+ }
+}
+
+/**
+ * Activate tab with "panel_name" panel
+ * if no such tab - return false, otherwise true.
+ * TODO* In some cases a pointer to a panel of
+ * a specific class may be needed so this method
+ * would need to use templates.
+ */
+LLPanel* LLSideTray::showPanel (const std::string& panel_name, const LLSD& params)
+{
+ //arrange tabs
+ child_vector_const_iter_t child_it;
+ for ( child_it = mTabs.begin(); child_it != mTabs.end(); ++child_it)
+ {
+ LLView* view = (*child_it)->findChildView(panel_name,true);
+ if(view)
+ {
+ onTabButtonClick((*child_it)->getName());
+
+ LLSideTrayPanelContainer* container = dynamic_cast<LLSideTrayPanelContainer*>(view->getParent());
+ if(container)
+ {
+ LLSD new_params = params;
+ new_params[LLSideTrayPanelContainer::PARAM_SUB_PANEL_NAME] = panel_name;
+ container->onOpen(new_params);
+
+ return container->getCurrentPanel();
+ }
+
+ LLPanel* panel = dynamic_cast<LLPanel*>(view);
+ if(panel)
+ {
+ panel->onOpen(params);
+ }
+ return panel;
+ }
+ }
+ return NULL;
+}
+
+// *TODO: Eliminate magic constants.
+static const S32 fake_offset = 132;
+static const S32 fake_top_offset = 18;
+
+void LLSideTray::resetPanelRect ()
+{
+ const LLRect& parent_rect = gViewerWindow->getRootView()->getRect();
+
+ static LLSideTray::Params sidetray_params(LLUICtrlFactory::getDefaultParams<LLSideTray>());
+
+ S32 panel_width = sidetray_params.default_button_width;
+ panel_width += mCollapsed ? sidetray_params.default_button_margin : mMaxBarWidth;
+
+ S32 panel_height = parent_rect.getHeight()-fake_top_offset;
+
+ reshape(panel_width,panel_height);
+}
+
+void LLSideTray::setPanelRect ()
+{
+ LLNavigationBar* nav_bar = LLNavigationBar::getInstance();
+ LLRect nav_rect = nav_bar->getRect();
+
+ static LLSideTray::Params sidetray_params(LLUICtrlFactory::getDefaultParams<LLSideTray>());
+
+ const LLRect& parent_rect = gViewerWindow->getRootView()->getRect();
+
+ S32 panel_width = sidetray_params.default_button_width;
+ panel_width += mCollapsed ? sidetray_params.default_button_margin : mMaxBarWidth;
+
+ S32 panel_height = parent_rect.getHeight()-fake_top_offset - nav_rect.getHeight();
+ S32 panel_top = parent_rect.mTop-fake_top_offset - nav_rect.getHeight();
+
+ LLRect panel_rect;
+ panel_rect.setLeftTopAndSize( parent_rect.mRight-panel_width, panel_top, panel_width, panel_height);
+ setRect(panel_rect);
+}
+
+S32 LLSideTray::getTrayWidth()
+{
+ static LLSideTray::Params sidetray_params(LLUICtrlFactory::getDefaultParams<LLSideTray>());
+ return getRect().getWidth() - (sidetray_params.default_button_width + sidetray_params.default_button_margin);
+}
diff --git a/indra/newview/llsidetray.h b/indra/newview/llsidetray.h
new file mode 100644
index 0000000000..13acbbb659
--- /dev/null
+++ b/indra/newview/llsidetray.h
@@ -0,0 +1,252 @@
+/**
+ * @file LLSideTray.h
+ * @brief SideBar header file
+ *
+ * $LicenseInfo:firstyear=2004&license=viewergpl$
+ *
+ * Copyright (c) 2009, Linden Research, Inc.
+ *
+ * Second Life Viewer Source Code
+ * The source code in this file ("Source Code") is provided by Linden Lab
+ * to you under the terms of the GNU General Public License, version 2.0
+ * ("GPL"), unless you have obtained a separate licensing agreement
+ * ("Other License"), formally executed by you and Linden Lab. Terms of
+ * the GPL can be found in doc/GPL-license.txt in this distribution, or
+ * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
+ *
+ * There are special exceptions to the terms and conditions of the GPL as
+ * it is applied to this Source Code. View the full text of the exception
+ * in the file doc/FLOSS-exception.txt in this software distribution, or
+ * online at
+ * http://secondlifegrid.net/programs/open_source/licensing/flossexception
+ *
+ * By copying, modifying or distributing this software, you acknowledge
+ * that you have read and understood your obligations described above,
+ * and agree to abide by those obligations.
+ *
+ * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+ * COMPLETENESS OR PERFORMANCE.
+ * $/LicenseInfo$
+ */
+
+#ifndef LL_LLSIDETRAY_H_
+#define LL_LLSIDETRAY_H_
+
+#include "llpanel.h"
+#include "string"
+
+class LLSideTray;
+class LLAccordionCtrl;
+
+class LLSideTrayTab: public LLPanel
+{
+ friend class LLUICtrlFactory;
+ friend class LLSideTray;
+public:
+
+ struct Params
+ : public LLInitParam::Block<Params, LLPanel::Params>
+ {
+ // image name
+ Optional<std::string> image_path;
+ Optional<std::string> tab_title;
+ Optional<std::string> description;
+ Params()
+ : image_path("image"),
+ tab_title("tab_title","no title"),
+ description("description","no description")
+ {};
+ };
+protected:
+ LLSideTrayTab(const Params& params);
+
+
+public:
+ virtual ~LLSideTrayTab();
+
+ /*virtual*/ BOOL postBuild ();
+ /*virtual*/ bool addChild (LLView* view, S32 tab_group);
+
+
+ void arrange (S32 width, S32 height);
+ void reshape (S32 width, S32 height, BOOL called_from_parent = TRUE);
+
+ static LLSideTrayTab* createInstance ();
+
+ const std::string& getDescription () const { return mDescription;}
+ const std::string& getTabTitle() const { return mTabTitle;}
+
+ void draw();
+
+ void onOpen (const LLSD& key);
+
+private:
+ std::string mTabTitle;
+ std::string mImagePath;
+ std::string mDescription;
+
+ LLView* mMainPanel;
+};
+
+// added inheritance from LLDestroyClass<LLSideTray> to enable Side Tray perform necessary actions
+// while disconnecting viewer in LLAppViewer::disconnectViewer().
+// LLDestroyClassList::instance().fireCallbacks() calls destroyClass method. See EXT-245.
+class LLSideTray : public LLPanel, private LLDestroyClass<LLSideTray>
+{
+ friend class LLUICtrlFactory;
+ friend class LLDestroyClass<LLSideTray>;
+public:
+
+ LOG_CLASS(LLSideTray);
+
+ struct Params
+ : public LLInitParam::Block<Params, LLPanel::Params>
+ {
+ // initial state
+ Optional<bool> collapsed;
+ Optional<std::string> tab_btn_image_normal;
+ Optional<std::string> tab_btn_image_selected;
+
+ Optional<S32> default_button_width;
+ Optional<S32> default_button_height;
+ Optional<S32> default_button_margin;
+
+ Params()
+ : collapsed("collapsed",false),
+ tab_btn_image_normal("tab_btn_image","sidebar_tab_left.tga"),
+ tab_btn_image_selected("tab_btn_image_selected","button_enabled_selected_32x128.tga"),
+ default_button_width("tab_btn_width",32),
+ default_button_height("tab_btn_height",32),
+ default_button_margin("tab_btn_margin",0)
+ {};
+ };
+
+ static LLSideTray* getInstance ();
+ static bool instanceCreated ();
+protected:
+ LLSideTray(Params& params);
+ typedef std::vector<LLView*> child_vector_t;
+ typedef child_vector_t::iterator child_vector_iter_t;
+ typedef child_vector_t::const_iterator child_vector_const_iter_t;
+ typedef child_vector_t::reverse_iterator child_vector_reverse_iter_t;
+ typedef child_vector_t::const_reverse_iterator child_vector_const_reverse_iter_t;
+
+public:
+
+ // interface functions
+
+ /**
+ * Select tab with specific name and set it active
+ */
+ bool selectTabByName (const std::string& name);
+
+ /**
+ * Select tab with specific index and set it active
+ */
+ bool selectTabByIndex(size_t index);
+
+ /**
+ * add new panel to tab with tab_name name
+ * @param tab_name - name of sidebar tab to add new panel
+ * @param panel - pointer to panel
+ */
+ bool addPanel ( const std::string& tab_name
+ ,LLPanel* panel );
+ /**
+ * Add new tab to side bar
+ * @param tab_name - name of the new tab
+ * @param image - image for new sidebar button
+ * @param title - title for new tab
+ */
+ bool addTab ( const std::string& tab_name
+ ,const std::string& image
+ ,const std::string& title);
+
+ /**
+ * Activate tab with "panel_name" panel
+ * if no such tab - return NULL, otherwise a pointer to the panel
+ * Pass params as array, or they may be overwritten(example - params["name"]="nearby")
+ */
+ LLPanel* showPanel (const std::string& panel_name, const LLSD& params);
+
+ /*
+ * collapse SideBar, hiding visible tab and moving tab buttons
+ * to the right corner of the screen
+ */
+ void collapseSideBar ();
+
+ /*
+ * expand SideBar
+ */
+ void expandSideBar ();
+
+
+ /**
+ *hightlight if focused. manly copypaste from highlightFocusedFloater
+ */
+ void highlightFocused();
+
+ void setVisible(BOOL visible)
+ {
+ LLPanel::setVisible(visible);
+ }
+
+public:
+ virtual ~LLSideTray(){};
+
+ virtual BOOL postBuild();
+
+ void onTabButtonClick(std::string name);
+ void onToggleCollapse();
+
+ bool addChild (LLView* view, S32 tab_group);
+
+ BOOL handleMouseDown (S32 x, S32 y, MASK mask);
+
+ void reshape (S32 width, S32 height, BOOL called_from_parent = TRUE);
+ S32 getTrayWidth();
+
+ void resetPanelRect ();
+
+
+protected:
+ LLSideTrayTab* getTab (const std::string& name);
+
+ void createButtons ();
+ LLButton* createButton (const std::string& name,const std::string& image,LLUICtrl::commit_callback_t callback);
+ void arrange ();
+ void reflectCollapseChange();
+
+ void toggleTabButton (LLSideTrayTab* tab);
+
+ void setPanelRect ();
+
+
+
+private:
+ // Implementation of LLDestroyClass<LLSideTray>
+ static void destroyClass()
+ {
+ // Disable SideTray to avoid crashes. EXT-245
+ if (LLSideTray::instanceCreated())
+ LLSideTray::getInstance()->setEnabled(FALSE);
+ }
+
+
+private:
+
+ std::map<std::string,LLButton*> mTabButtons;
+ child_vector_t mTabs;
+ LLSideTrayTab* mActiveTab;
+
+ LLButton* mCollapseButton;
+ bool mCollapsed;
+
+ S32 mMaxBarWidth;
+
+ static LLSideTray* sInstance;
+};
+
+#endif
+
diff --git a/indra/newview/llsidetraypanelcontainer.cpp b/indra/newview/llsidetraypanelcontainer.cpp
new file mode 100644
index 0000000000..3024492ab9
--- /dev/null
+++ b/indra/newview/llsidetraypanelcontainer.cpp
@@ -0,0 +1,93 @@
+/**
+* @file llsidetraypanelcontainer.cpp
+* @brief LLSideTrayPanelContainer implementation
+*
+* $LicenseInfo:firstyear=2001&license=viewergpl$
+*
+* Copyright (c) 2001-2009, Linden Research, Inc.
+*
+* Second Life Viewer Source Code
+* The source code in this file ("Source Code") is provided by Linden Lab
+* to you under the terms of the GNU General Public License, version 2.0
+* ("GPL"), unless you have obtained a separate licensing agreement
+* ("Other License"), formally executed by you and Linden Lab. Terms of
+* the GPL can be found in doc/GPL-license.txt in this distribution, or
+* online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
+*
+* There are special exceptions to the terms and conditions of the GPL as
+* it is applied to this Source Code. View the full text of the exception
+* in the file doc/FLOSS-exception.txt in this software distribution, or
+* online at
+* http://secondlifegrid.net/programs/open_source/licensing/flossexception
+*
+* By copying, modifying or distributing this software, you acknowledge
+* that you have read and understood your obligations described above,
+* and agree to abide by those obligations.
+*
+* ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+* COMPLETENESS OR PERFORMANCE.
+* $/LicenseInfo$
+*/
+
+#include "llviewerprecompiledheaders.h"
+#include "llsidetraypanelcontainer.h"
+
+static LLDefaultChildRegistry::Register<LLSideTrayPanelContainer> r2("panel_container");
+
+std::string LLSideTrayPanelContainer::PARAM_SUB_PANEL_NAME = "sub_panel_name";
+
+LLSideTrayPanelContainer::Params::Params()
+{
+ // Always hide tabs.
+ hide_tabs(true);
+}
+
+LLSideTrayPanelContainer::LLSideTrayPanelContainer(const Params& p)
+ : LLTabContainer(p)
+{
+}
+
+void LLSideTrayPanelContainer::onOpen(const LLSD& key)
+{
+ // Select specified panel and save navigation history.
+ if(key.has(PARAM_SUB_PANEL_NAME))
+ {
+ // Save panel navigation history
+ std::string panel_name = key[PARAM_SUB_PANEL_NAME];
+ S32 old_index = getCurrentPanelIndex();
+
+ selectTabByName(panel_name);
+
+ S32 new_index = getCurrentPanelIndex();
+
+ // Don't update navigation history if we are opening same panel again.
+ if(old_index != new_index)
+ {
+ mPanelHistory[panel_name] = old_index;
+ }
+ }
+ // Will reopen current panel if no panel name was passed.
+ getCurrentPanel()->onOpen(key);
+}
+
+void LLSideTrayPanelContainer::openPreviousPanel()
+{
+ std::string current_panel_name = getCurrentPanel()->getName();
+ panel_navigation_history_t::const_iterator it = mPanelHistory.find(current_panel_name);
+ if(mPanelHistory.end() != it)
+ {
+ selectTab(it->second);
+ }
+}
+
+BOOL LLSideTrayPanelContainer::handleKeyHere(KEY key, MASK mask)
+{
+ // No key press handling code for Panel Container - this disables
+ // Tab Container's Alt + Left/Right Button tab switching.
+
+ // Let default handler process key presses, don't simply return TRUE or FALSE
+ // as this may brake some functionality as it did with Copy/Paste for
+ // text_editor (ticket EXT-642).
+ return LLPanel::handleKeyHere(key, mask);
+}
diff --git a/indra/newview/llsidetraypanelcontainer.h b/indra/newview/llsidetraypanelcontainer.h
new file mode 100644
index 0000000000..3f3cb552f8
--- /dev/null
+++ b/indra/newview/llsidetraypanelcontainer.h
@@ -0,0 +1,95 @@
+/**
+* @file llsidetraypanelcontainer.h
+* @brief LLSideTrayPanelContainer class declaration
+*
+* $LicenseInfo:firstyear=2009&license=viewergpl$
+*
+* Copyright (c) 2009, Linden Research, Inc.
+*
+* Second Life Viewer Source Code
+* The source code in this file ("Source Code") is provided by Linden Lab
+* to you under the terms of the GNU General Public License, version 2.0
+* ("GPL"), unless you have obtained a separate licensing agreement
+* ("Other License"), formally executed by you and Linden Lab. Terms of
+* the GPL can be found in doc/GPL-license.txt in this distribution, or
+* online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
+*
+* There are special exceptions to the terms and conditions of the GPL as
+* it is applied to this Source Code. View the full text of the exception
+* in the file doc/FLOSS-exception.txt in this software distribution, or
+* online at
+* http://secondlifegrid.net/programs/open_source/licensing/flossexception
+*
+* By copying, modifying or distributing this software, you acknowledge
+* that you have read and understood your obligations described above,
+* and agree to abide by those obligations.
+*
+* ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+* COMPLETENESS OR PERFORMANCE.
+* $/LicenseInfo$
+*/
+
+#ifndef LL_LLSIDETRAY_PANEL_CONTAINER_H
+#define LL_LLSIDETRAY_PANEL_CONTAINER_H
+
+#include "lltabcontainer.h"
+
+/**
+* LLSideTrayPanelContainer class acts like LLTabContainer with invisible tabs.
+* It is designed to make panel switching easier, avoid setVisible(TRUE) setVisible(FALSE)
+* calls and related workarounds.
+* use onOpen to open sub panel, pass the name of panel to open
+* in key[PARAM_SUB_PANEL_NAME].
+* LLSideTrayPanelContainer also implements panel navigation history - it allows to
+* open previous or next panel if navigation history is available(after user
+* has opened two or more panels). *NOTE - only back navigation is implemented so far.
+*/
+class LLSideTrayPanelContainer : public LLTabContainer
+{
+public:
+
+ struct Params : public LLInitParam::Block<Params, LLTabContainer::Params>
+ {
+ Params();
+ };
+
+ /**
+ * Opens sub panel
+ * @param key - params to be passed to panel, use key[PARAM_SUB_PANEL_NAME]
+ * to specify panel name to be opened.
+ */
+ /*virtual*/ void onOpen(const LLSD& key);
+
+ /**
+ * Opens previous panel from panel navigation history.
+ */
+ void openPreviousPanel();
+
+ /**
+ * Overrides LLTabContainer::handleKeyHere to disable panel switch on
+ * Alt + Left/Right button press.
+ */
+ BOOL handleKeyHere(KEY key, MASK mask);
+
+ /**
+ * Name of parameter that stores panel name to open.
+ */
+ static std::string PARAM_SUB_PANEL_NAME;
+
+protected:
+ LLSideTrayPanelContainer(const Params& p);
+ friend class LLUICtrlFactory;
+
+ /**
+ * std::string - name of panel
+ * S32 - index of previous panel
+ * *NOTE - no forward navigation implemented yet
+ */
+ typedef std::map<std::string, S32> panel_navigation_history_t;
+
+ // Navigation history
+ panel_navigation_history_t mPanelHistory;
+};
+
+#endif //LL_LLSIDETRAY_PANEL_CONTAINER_H
diff --git a/indra/newview/llsky.cpp b/indra/newview/llsky.cpp
index ac7e865de0..a49b07c5d9 100644
--- a/indra/newview/llsky.cpp
+++ b/indra/newview/llsky.cpp
@@ -52,7 +52,6 @@
#include "llviewerobject.h"
#include "llviewercamera.h"
#include "pipeline.h"
-#include "llagent.h"
#include "lldrawpool.h"
#include "llvosky.h"
diff --git a/indra/newview/llslurl.cpp b/indra/newview/llslurl.cpp
new file mode 100644
index 0000000000..836fe9729d
--- /dev/null
+++ b/indra/newview/llslurl.cpp
@@ -0,0 +1,145 @@
+/**
+ * @file llslurl.cpp
+ * @brief SLURL manipulation
+ *
+ * $LicenseInfo:firstyear=2009&license=viewergpl$
+ *
+ * Copyright (c) 2009, Linden Research, Inc.
+ *
+ * Second Life Viewer Source Code
+ * The source code in this file ("Source Code") is provided by Linden Lab
+ * to you under the terms of the GNU General Public License, version 2.0
+ * ("GPL"), unless you have obtained a separate licensing agreement
+ * ("Other License"), formally executed by you and Linden Lab. Terms of
+ * the GPL can be found in doc/GPL-license.txt in this distribution, or
+ * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
+ *
+ * There are special exceptions to the terms and conditions of the GPL as
+ * it is applied to this Source Code. View the full text of the exception
+ * in the file doc/FLOSS-exception.txt in this software distribution, or
+ * online at
+ * http://secondlifegrid.net/programs/open_source/licensing/flossexception
+ *
+ * By copying, modifying or distributing this software, you acknowledge
+ * that you have read and understood your obligations described above,
+ * and agree to abide by those obligations.
+ *
+ * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+ * COMPLETENESS OR PERFORMANCE.
+ * $/LicenseInfo$
+ */
+
+#include "llviewerprecompiledheaders.h"
+
+#include "llslurl.h"
+
+#include "llweb.h"
+
+const std::string LLSLURL::PREFIX_SL_HELP = "secondlife://app.";
+const std::string LLSLURL::PREFIX_SL = "sl://";
+const std::string LLSLURL::PREFIX_SECONDLIFE = "secondlife://";
+const std::string LLSLURL::PREFIX_SLURL = "http://slurl.com/secondlife/";
+
+const std::string LLSLURL::APP_TOKEN = "app/";
+
+// static
+std::string LLSLURL::stripProtocol(const std::string& url)
+{
+ std::string stripped = url;
+ if (matchPrefix(stripped, PREFIX_SL_HELP))
+ {
+ stripped.erase(0, PREFIX_SL_HELP.length());
+ }
+ else if (matchPrefix(stripped, PREFIX_SL))
+ {
+ stripped.erase(0, PREFIX_SL.length());
+ }
+ else if (matchPrefix(stripped, PREFIX_SECONDLIFE))
+ {
+ stripped.erase(0, PREFIX_SECONDLIFE.length());
+ }
+ else if (matchPrefix(stripped, PREFIX_SLURL))
+ {
+ stripped.erase(0, PREFIX_SLURL.length());
+ }
+
+ return stripped;
+}
+
+// static
+bool LLSLURL::isSLURL(const std::string& url)
+{
+ if (matchPrefix(url, PREFIX_SL_HELP)) return true;
+ if (matchPrefix(url, PREFIX_SL)) return true;
+ if (matchPrefix(url, PREFIX_SECONDLIFE)) return true;
+ if (matchPrefix(url, PREFIX_SLURL)) return true;
+
+ return false;
+}
+
+// static
+bool LLSLURL::isSLURLCommand(const std::string& url)
+{
+ if (matchPrefix(url, PREFIX_SL + APP_TOKEN) ||
+ matchPrefix(url, PREFIX_SECONDLIFE + "/" + APP_TOKEN) ||
+ matchPrefix(url, PREFIX_SLURL + APP_TOKEN) )
+ {
+ return true;
+ }
+
+ return false;
+}
+
+// static
+bool LLSLURL::isSLURLHelp(const std::string& url)
+{
+ return matchPrefix(url, PREFIX_SL_HELP);
+}
+
+// static
+std::string LLSLURL::buildSLURL(const std::string& regionname, S32 x, S32 y, S32 z)
+{
+ std::string slurl = PREFIX_SLURL + regionname + llformat("/%d/%d/%d",x,y,z);
+ slurl = LLWeb::escapeURL( slurl );
+ return slurl;
+}
+
+// static
+std::string LLSLURL::buildUnescapedSLURL(const std::string& regionname, S32 x, S32 y, S32 z)
+{
+ std::string unescapedslurl = PREFIX_SLURL + regionname + llformat("/%d/%d/%d",x,y,z);
+ return unescapedslurl;
+}
+
+// static
+std::string LLSLURL::buildSLURLfromPosGlobal(const std::string& regionname,
+ const LLVector3d& global_pos,
+ bool escaped /*= true*/)
+{
+ S32 x, y, z;
+ globalPosToXYZ(global_pos, x, y, z);
+ if(escaped)
+ {
+ return buildSLURL(regionname, x, y, z);
+ }
+ else
+ {
+ return buildUnescapedSLURL(regionname, x, y, z);
+ }
+}
+
+// static
+bool LLSLURL::matchPrefix(const std::string& url, const std::string& prefix)
+{
+ std::string test_prefix = url.substr(0, prefix.length());
+ LLStringUtil::toLower(test_prefix);
+ return test_prefix == prefix;
+}
+
+void LLSLURL::globalPosToXYZ(const LLVector3d& pos, S32& x, S32& y, S32& z)
+{
+ x = llround((F32)fmod(pos.mdV[VX], (F64)REGION_WIDTH_METERS));
+ y = llround((F32)fmod(pos.mdV[VY], (F64)REGION_WIDTH_METERS));
+ z = llround((F32)pos.mdV[VZ]);
+}
diff --git a/indra/newview/llslurl.h b/indra/newview/llslurl.h
new file mode 100644
index 0000000000..8af2bdfb83
--- /dev/null
+++ b/indra/newview/llslurl.h
@@ -0,0 +1,103 @@
+/**
+ * @file llslurl.h
+ * @brief SLURL manipulation
+ *
+ * $LicenseInfo:firstyear=2009&license=viewergpl$
+ *
+ * Copyright (c) 2009, Linden Research, Inc.
+ *
+ * Second Life Viewer Source Code
+ * The source code in this file ("Source Code") is provided by Linden Lab
+ * to you under the terms of the GNU General Public License, version 2.0
+ * ("GPL"), unless you have obtained a separate licensing agreement
+ * ("Other License"), formally executed by you and Linden Lab. Terms of
+ * the GPL can be found in doc/GPL-license.txt in this distribution, or
+ * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
+ *
+ * There are special exceptions to the terms and conditions of the GPL as
+ * it is applied to this Source Code. View the full text of the exception
+ * in the file doc/FLOSS-exception.txt in this software distribution, or
+ * online at
+ * http://secondlifegrid.net/programs/open_source/licensing/flossexception
+ *
+ * By copying, modifying or distributing this software, you acknowledge
+ * that you have read and understood your obligations described above,
+ * and agree to abide by those obligations.
+ *
+ * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+ * COMPLETENESS OR PERFORMANCE.
+ * $/LicenseInfo$
+ */
+
+#ifndef LL_SLURL_H
+#define LL_SLURL_H
+
+#include <string>
+
+// IAN BUG: where should this live?
+// IAN BUG: are static utility functions right? See LLUUID.
+// question of whether to have a LLSLURL object or a
+// some of this was moved from LLURLDispatcher
+
+/**
+ * SLURL manipulation
+ */
+class LLSLURL
+{
+public:
+ static const std::string PREFIX_SL_HELP;
+ static const std::string PREFIX_SL;
+ static const std::string PREFIX_SECONDLIFE;
+ static const std::string PREFIX_SLURL;
+
+ static const std::string APP_TOKEN;
+
+ /**
+ * Is this any sort of secondlife:// or sl:// URL?
+ */
+ static bool isSLURL(const std::string& url);
+
+ /**
+ * Is this a special secondlife://app/ URL?
+ */
+ static bool isSLURLCommand(const std::string& url);
+
+ /**
+ * Not sure what it is.
+ */
+ static bool isSLURLHelp(const std::string& url);
+
+ /**
+ * builds: http://slurl.com/secondlife/Region%20Name/x/y/z/ escaping result url.
+ */
+ static std::string buildSLURL(const std::string& regionname, S32 x, S32 y, S32 z);
+
+ /**
+ * builds: http://slurl.com/secondlife/Region Name/x/y/z/ without escaping result url.
+ */
+ static std::string buildUnescapedSLURL(const std::string& regionname, S32 x, S32 y, S32 z);
+
+ /**
+ * builds SLURL from global position. Returns escaped or unescaped url.
+ * Returns escaped url by default.
+ */
+ static std::string buildSLURLfromPosGlobal(const std::string& regionname,
+ const LLVector3d& global_pos,
+ bool escaped = true);
+ /**
+ * Strip protocol part from the URL.
+ */
+ static std::string stripProtocol(const std::string& url);
+
+ /**
+ * Convert global position to X, Y Z
+ */
+ static void globalPosToXYZ(const LLVector3d& pos, S32& x, S32& y, S32& z);
+
+private:
+ static bool matchPrefix(const std::string& url, const std::string& prefix);
+
+};
+
+#endif
diff --git a/indra/newview/llspatialpartition.cpp b/indra/newview/llspatialpartition.cpp
index f8b824732f..dea9af0657 100644
--- a/indra/newview/llspatialpartition.cpp
+++ b/indra/newview/llspatialpartition.cpp
@@ -41,7 +41,6 @@
#include "llviewercamera.h"
#include "llface.h"
#include "llviewercontrol.h"
-#include "llagent.h"
#include "llviewerregion.h"
#include "llcamera.h"
#include "pipeline.h"
@@ -49,6 +48,9 @@
#include "lloctree.h"
#include "llvoavatar.h"
+static LLFastTimer::DeclareTimer FTM_FRUSTUM_CULL("Frustum Culling");
+static LLFastTimer::DeclareTimer FTM_CULL_REBOUND("Cull Rebound");
+
const F32 SG_OCCLUSION_FUDGE = 0.25f;
#define SG_DISCARD_TOLERANCE 0.01f
@@ -570,6 +572,8 @@ void LLSpatialGroup::rebuildMesh()
}
}
+static LLFastTimer::DeclareTimer FTM_REBUILD_VBO("VBO Rebuilt");
+
void LLSpatialPartition::rebuildGeom(LLSpatialGroup* group)
{
if (!gPipeline.hasRenderType(mDrawableType))
@@ -577,7 +581,7 @@ void LLSpatialPartition::rebuildGeom(LLSpatialGroup* group)
return;
}
- if (group->changeLOD())
+ if (!LLPipeline::sSkipUpdate && group->changeLOD())
{
group->mLastUpdateDistance = group->mDistance;
group->mLastUpdateViewAngle = group->mViewAngle;
@@ -588,7 +592,7 @@ void LLSpatialPartition::rebuildGeom(LLSpatialGroup* group)
return;
}
- LLFastTimer ftm(LLFastTimer::FTM_REBUILD_VBO);
+ LLFastTimer ftm(FTM_REBUILD_VBO);
group->clearDrawMap();
@@ -826,7 +830,7 @@ class LLSpatialSetStateDiff : public LLSpatialSetState
public:
LLSpatialSetStateDiff(U32 state) : LLSpatialSetState(state) { }
- virtual void traverse(const LLSpatialGroup::TreeNode* n)
+ virtual void traverse(const LLSpatialGroup::OctreeNode* n)
{
LLSpatialGroup* group = (LLSpatialGroup*) n->getListener(0);
@@ -885,7 +889,7 @@ class LLSpatialClearStateDiff : public LLSpatialClearState
public:
LLSpatialClearStateDiff(U32 state) : LLSpatialClearState(state) { }
- virtual void traverse(const LLSpatialGroup::TreeNode* n)
+ virtual void traverse(const LLSpatialGroup::OctreeNode* n)
{
LLSpatialGroup* group = (LLSpatialGroup*) n->getListener(0);
@@ -1256,6 +1260,7 @@ BOOL LLSpatialGroup::rebound()
return TRUE;
}
+static LLFastTimer::DeclareTimer FTM_OCCLUSION_READBACK("Readback Occlusion");
void LLSpatialGroup::checkOcclusion()
{
if (LLPipeline::sUseOcclusion > 1)
@@ -1267,7 +1272,7 @@ void LLSpatialGroup::checkOcclusion()
}
else if (isState(QUERY_PENDING))
{ //otherwise, if a query is pending, read it back
- LLFastTimer t(LLFastTimer::FTM_OCCLUSION_READBACK);
+ LLFastTimer t(FTM_OCCLUSION_READBACK);
GLuint res = 1;
if (!isState(DISCARD_QUERY) && mOcclusionQuery)
{
@@ -1312,7 +1317,7 @@ void LLSpatialGroup::doOcclusion(LLCamera* camera)
else
{
{
- LLFastTimer t(LLFastTimer::FTM_RENDER_OCCLUSION);
+ LLFastTimer t(FTM_RENDER_OCCLUSION);
if (!mOcclusionQuery)
{
@@ -1498,7 +1503,7 @@ public:
return false;
}
- virtual void traverse(const LLSpatialGroup::TreeNode* n)
+ virtual void traverse(const LLSpatialGroup::OctreeNode* n)
{
LLSpatialGroup* group = (LLSpatialGroup*) n->getListener(0);
@@ -1873,7 +1878,7 @@ S32 LLSpatialPartition::cull(LLCamera &camera, std::vector<LLDrawable *>* result
{
BOOL temp = sFreezeState;
sFreezeState = FALSE;
- LLFastTimer ftm(LLFastTimer::FTM_CULL_REBOUND);
+ LLFastTimer ftm(FTM_CULL_REBOUND);
LLSpatialGroup* group = (LLSpatialGroup*) mOctree->getListener(0);
group->rebound();
sFreezeState = temp;
@@ -1891,19 +1896,19 @@ S32 LLSpatialPartition::cull(LLCamera &camera, std::vector<LLDrawable *>* result
}
else if (LLPipeline::sShadowRender)
{
- LLFastTimer ftm(LLFastTimer::FTM_FRUSTUM_CULL);
+ LLFastTimer ftm(FTM_FRUSTUM_CULL);
LLOctreeCullShadow culler(&camera);
culler.traverse(mOctree);
}
else if (mInfiniteFarClip || !LLPipeline::sUseFarClip)
{
- LLFastTimer ftm(LLFastTimer::FTM_FRUSTUM_CULL);
+ LLFastTimer ftm(FTM_FRUSTUM_CULL);
LLOctreeCullNoFarClip culler(&camera);
culler.traverse(mOctree);
}
else
{
- LLFastTimer ftm(LLFastTimer::FTM_FRUSTUM_CULL);
+ LLFastTimer ftm(FTM_FRUSTUM_CULL);
LLOctreeCull culler(&camera);
culler.traverse(mOctree);
}
@@ -2356,7 +2361,7 @@ void renderTexturePriority(LLDrawable* drawable)
LLGLDisable blend(GL_BLEND);
- //LLViewerImage* imagep = facep->getTexture();
+ //LLViewerTexture* imagep = facep->getTexture();
//if (imagep)
{
@@ -2386,7 +2391,7 @@ void renderTexturePriority(LLDrawable* drawable)
/*S32 boost = imagep->getBoostLevel();
if (boost)
{
- F32 t = (F32) boost / (F32) (LLViewerImage::BOOST_MAX_LEVEL-1);
+ F32 t = (F32) boost / (F32) (LLViewerTexture::BOOST_MAX_LEVEL-1);
LLVector4 col = lerp(boost_cold, boost_hot, t);
LLGLEnable blend_on(GL_BLEND);
gGL.blendFunc(GL_SRC_ALPHA, GL_ONE);
@@ -2896,7 +2901,7 @@ LLDrawable* LLSpatialPartition::lineSegmentIntersect(const LLVector3& start, con
}
LLDrawInfo::LLDrawInfo(U16 start, U16 end, U32 count, U32 offset,
- LLViewerImage* texture, LLVertexBuffer* buffer,
+ LLViewerTexture* texture, LLVertexBuffer* buffer,
BOOL fullbright, U8 bump, BOOL particle, F32 part_size)
:
mVertexBuffer(buffer),
diff --git a/indra/newview/llspatialpartition.h b/indra/newview/llspatialpartition.h
index df96152dfe..13ab35402c 100644
--- a/indra/newview/llspatialpartition.h
+++ b/indra/newview/llspatialpartition.h
@@ -35,9 +35,10 @@
#define SG_MIN_DIST_RATIO 0.00001f
-#include "llmemory.h"
#include "lldrawable.h"
#include "lloctree.h"
+#include "llpointer.h"
+#include "llrefcount.h"
#include "llvertexbuffer.h"
#include "llgltypes.h"
#include "llcubemap.h"
@@ -66,12 +67,12 @@ protected:
public:
LLDrawInfo(U16 start, U16 end, U32 count, U32 offset,
- LLViewerImage* image, LLVertexBuffer* buffer,
+ LLViewerTexture* image, LLVertexBuffer* buffer,
BOOL fullbright = FALSE, U8 bump = 0, BOOL particle = FALSE, F32 part_size = 0);
LLPointer<LLVertexBuffer> mVertexBuffer;
- LLPointer<LLViewerImage> mTexture;
+ LLPointer<LLViewerTexture> mTexture;
LLColor4U mGlowColor;
S32 mDebugColor;
const LLMatrix4* mTextureMatrix;
@@ -163,7 +164,7 @@ public:
typedef std::vector<LLPointer<LLDrawInfo> > drawmap_elem_t;
typedef std::map<U32, drawmap_elem_t > draw_map_t;
typedef std::vector<LLPointer<LLVertexBuffer> > buffer_list_t;
- typedef std::map<LLPointer<LLViewerImage>, buffer_list_t> buffer_texture_map_t;
+ typedef std::map<LLPointer<LLViewerTexture>, buffer_list_t> buffer_texture_map_t;
typedef std::map<U32, buffer_texture_map_t> buffer_map_t;
typedef LLOctreeListener<LLDrawable> BaseType;
diff --git a/indra/newview/llsplitbutton.cpp b/indra/newview/llsplitbutton.cpp
new file mode 100644
index 0000000000..ffd9bc7624
--- /dev/null
+++ b/indra/newview/llsplitbutton.cpp
@@ -0,0 +1,275 @@
+/**
+ * @file llsplitbutton.cpp
+ * @brief LLSplitButton base class
+ *
+ * $LicenseInfo:firstyear=2009&license=viewergpl$
+ *
+ * Copyright (c) 2009, Linden Research, Inc.
+ *
+ * Second Life Viewer Source Code
+ * The source code in this file ("Source Code") is provided by Linden Lab
+ * to you under the terms of the GNU General Public License, version 2.0
+ * ("GPL"), unless you have obtained a separate licensing agreement
+ * ("Other License"), formally executed by you and Linden Lab. Terms of
+ * the GPL can be found in doc/GPL-license.txt in this distribution, or
+ * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
+ *
+ * There are special exceptions to the terms and conditions of the GPL as
+ * it is applied to this Source Code. View the full text of the exception
+ * in the file doc/FLOSS-exception.txt in this software distribution, or
+ * online at
+ * http://secondlifegrid.net/programs/open_source/licensing/flossexception
+ *
+ * By copying, modifying or distributing this software, you acknowledge
+ * that you have read and understood your obligations described above,
+ * and agree to abide by those obligations.
+ *
+ * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+ * COMPLETENESS OR PERFORMANCE.
+ * $/LicenseInfo$
+ */
+
+// A control that consolidates several buttons as options
+
+#include "llviewerprecompiledheaders.h"
+
+#include "llsplitbutton.h"
+
+#include "llinitparam.h"
+#include "llpanel.h"
+#include "llfocusmgr.h"
+#include "llviewerwindow.h"
+#include "llrootview.h"
+
+
+S32 BUTTON_PAD = 2; //pad between buttons on an items panel
+
+
+static LLDefaultChildRegistry::Register<LLSplitButton> split_button("split_button");
+
+void LLSplitButton::ArrowPositionValues::declareValues()
+{
+ declare("left", LEFT);
+ declare("right", RIGHT);
+}
+
+LLSplitButton::ItemParams::ItemParams()
+{
+}
+
+LLSplitButton::Params::Params()
+: arrow_position("arrow_position", LEFT),
+ items("item"),
+ arrow_button("arrow_button"),
+ items_panel("items_panel")
+{
+}
+
+
+void LLSplitButton::onFocusLost()
+{
+ hideButtons();
+ LLUICtrl::onFocusLost();
+}
+
+void LLSplitButton::setFocus(BOOL b)
+{
+ LLUICtrl::setFocus(b);
+
+ if (b)
+ {
+ if (mItemsPanel && mItemsPanel->getVisible())
+ {
+ mItemsPanel->setFocus(TRUE);
+ }
+ }
+}
+
+void LLSplitButton::setEnabled(BOOL enabled)
+{
+ LLView::setEnabled(enabled);
+ mArrowBtn->setEnabled(enabled);
+}
+
+
+void LLSplitButton::onArrowBtnDown()
+{
+ if (!mItemsPanel->getVisible())
+ {
+ showButtons();
+
+ setFocus(TRUE);
+
+ if (mArrowBtn->hasMouseCapture() || mShownItem->hasMouseCapture())
+ {
+ gFocusMgr.setMouseCapture(this);
+ }
+ }
+ else
+ {
+ hideButtons();
+ }
+}
+
+void LLSplitButton::onHeldDownShownButton()
+{
+ if (!mItemsPanel->getVisible()) onArrowBtnDown();
+}
+
+void LLSplitButton::onItemSelected(LLUICtrl* ctrl)
+{
+ if (!ctrl) return;
+
+ hideButtons();
+
+ // call the callback if it exists
+ if(!mSelectionCallback.empty())
+ {
+ mSelectionCallback(this, ctrl->getName());
+ }
+
+ gFocusMgr.setKeyboardFocus(NULL);
+}
+
+BOOL LLSplitButton::handleMouseUp(S32 x, S32 y, MASK mask)
+{
+ gFocusMgr.setMouseCapture(NULL);
+
+ if (mShownItem->parentPointInView(x, y))
+ {
+ onItemSelected(mShownItem);
+ return TRUE;
+ }
+
+ for (std::list<LLButton*>::const_iterator it = mHidenItems.begin(); it != mHidenItems.end(); ++it)
+ {
+ LLButton* item = *it;
+
+ S32 panel_x = 0;
+ S32 panel_y = 0;
+ localPointToOtherView(x, y, &panel_x, &panel_y, mItemsPanel);
+
+ if (item->parentPointInView(panel_x, panel_y))
+ {
+ onItemSelected(item);
+ return TRUE;
+ }
+ }
+ return TRUE;
+}
+
+void LLSplitButton::showButtons()
+{
+ mItemsPanel->setOrigin(0, getRect().getHeight());
+
+ // register ourselves as a "top" control
+ // effectively putting us into a special draw layer
+ gFocusMgr.setTopCtrl(this);
+
+ mItemsPanel->setFocus(TRUE);
+
+ //push arrow button down and show the item buttons
+ mArrowBtn->setToggleState(TRUE);
+ mItemsPanel->setVisible(TRUE);
+
+ setUseBoundingRect(TRUE);
+}
+
+void LLSplitButton::hideButtons()
+{
+ mItemsPanel->setVisible(FALSE);
+ mArrowBtn->setToggleState(FALSE);
+
+ setUseBoundingRect(FALSE);
+ if(gFocusMgr.getTopCtrl() == this)
+ {
+ gFocusMgr.setTopCtrl(NULL);
+ }
+}
+
+
+// protected/private
+
+LLSplitButton::LLSplitButton(const LLSplitButton::Params& p)
+: LLUICtrl(p),
+ mArrowBtn(NULL),
+ mShownItem(NULL),
+ mItemsPanel(NULL),
+ mArrowPosition(p.arrow_position)
+{
+ LLRect rc(p.rect);
+
+ LLButton::Params arrow_params = p.arrow_button;
+ S32 arrow_width = p.arrow_button.rect.width;
+
+ //Default arrow rect values for LEFT arrow position
+ S32 arrow_left = 0;
+ S32 arrow_right = arrow_width;
+ S32 btn_left = arrow_width;
+ S32 btn_right = rc.getWidth();
+
+ if (mArrowPosition == RIGHT)
+ {
+ arrow_left = rc.getWidth()- arrow_width;
+ arrow_right = rc.getWidth();
+ btn_left = 0;
+ btn_right = arrow_left;
+ }
+
+ arrow_params.rect(LLRect(arrow_left, rc.getHeight(), arrow_right, 0));
+ arrow_params.label("");
+ arrow_params.mouse_down_callback.function(boost::bind(&LLSplitButton::onArrowBtnDown, this));
+ mArrowBtn = LLUICtrlFactory::create<LLButton>(arrow_params);
+ addChild(mArrowBtn);
+
+ //a panel for hidden item buttons
+ LLPanel::Params panel_params = p.items_panel;
+ mItemsPanel= prepareItemsPanel(panel_params, p.items.numValidElements());
+ addChild(mItemsPanel);
+
+
+ LLInitParam::ParamIterator<ItemParams>::const_iterator it = p.items().begin();
+
+ //processing shown item button
+ mShownItem = prepareItemButton(*it);
+ mShownItem->setHeldDownCallback(boost::bind(&LLSplitButton::onHeldDownShownButton, this));
+ mShownItem->setMouseUpCallback(boost::bind(&LLSplitButton::onItemSelected, this, _1));
+ mShownItem->setRect(LLRect(btn_left, rc.getHeight(), btn_right, 0));
+ addChild(mShownItem);
+
+ //processing hidden item buttons
+ S32 item_top = mItemsPanel->getRect().getHeight();
+ for (++it; it != p.items().end(); ++it)
+ {
+ LLButton* hidden_button = prepareItemButton(*it);
+ hidden_button->setRect(LLRect(btn_left, item_top, btn_right, item_top - rc.getHeight()));
+ hidden_button->setMouseDownCallback(boost::bind(&LLSplitButton::onItemSelected, this, _1));
+ mHidenItems.push_back(hidden_button);
+ mItemsPanel->addChild(hidden_button);
+
+ //calculate next button's top
+ item_top -= (rc.getHeight() + BUTTON_PAD);
+ }
+
+ setTopLostCallback(boost::bind(&LLSplitButton::hideButtons, this));
+}
+
+
+LLButton* LLSplitButton::prepareItemButton(LLButton::Params params)
+{
+ params.label("");
+ params.is_toggle(false);
+ return LLUICtrlFactory::create<LLButton>(params);
+}
+
+LLPanel* LLSplitButton::prepareItemsPanel(LLPanel::Params params, S32 items_count)
+{
+ S32 num_hiden_btns = items_count - 1;
+ S32 panel_height = num_hiden_btns * (getRect().getHeight() + BUTTON_PAD);
+ params.visible(false);
+ params.rect.width(getRect().getWidth());
+ params.rect.height(panel_height);
+ return LLUICtrlFactory::create<LLPanel>(params);
+}
+
diff --git a/indra/newview/llsplitbutton.h b/indra/newview/llsplitbutton.h
new file mode 100644
index 0000000000..0fb5f6594e
--- /dev/null
+++ b/indra/newview/llsplitbutton.h
@@ -0,0 +1,112 @@
+/**
+ * @file llsplitbutton.h
+ * @brief LLSplitButton base class
+ *
+ * $LicenseInfo:firstyear=2009&license=viewergpl$
+ *
+ * Copyright (c) 2009, Linden Research, Inc.
+ *
+ * Second Life Viewer Source Code
+ * The source code in this file ("Source Code") is provided by Linden Lab
+ * to you under the terms of the GNU General Public License, version 2.0
+ * ("GPL"), unless you have obtained a separate licensing agreement
+ * ("Other License"), formally executed by you and Linden Lab. Terms of
+ * the GPL can be found in doc/GPL-license.txt in this distribution, or
+ * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
+ *
+ * There are special exceptions to the terms and conditions of the GPL as
+ * it is applied to this Source Code. View the full text of the exception
+ * in the file doc/FLOSS-exception.txt in this software distribution, or
+ * online at
+ * http://secondlifegrid.net/programs/open_source/licensing/flossexception
+ *
+ * By copying, modifying or distributing this software, you acknowledge
+ * that you have read and understood your obligations described above,
+ * and agree to abide by those obligations.
+ *
+ * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+ * COMPLETENESS OR PERFORMANCE.
+ * $/LicenseInfo$
+ */
+
+// A control that displays the name of the chosen item, which when clicked
+// shows a scrolling box of choices.
+
+
+#include "llbutton.h"
+#include "llpanel.h"
+#include "lluictrl.h"
+
+
+#ifndef LL_LLSPLITBUTTON_H
+#define LL_LLSPLITBUTTON_H
+
+class LLSplitButton
+ : public LLUICtrl
+{
+public:
+ typedef enum e_arrow_position
+ {
+ LEFT,
+ RIGHT
+ } EArrowPosition;
+
+ struct ArrowPositionValues : public LLInitParam::TypeValuesHelper<EArrowPosition, ArrowPositionValues>
+ {
+ static void declareValues();
+ };
+
+ struct ItemParams : public LLInitParam::Block<ItemParams, LLButton::Params>
+ {
+ ItemParams();
+ };
+
+ struct Params : public LLInitParam::Block<Params, LLUICtrl::Params>
+ {
+ Optional<EArrowPosition, ArrowPositionValues> arrow_position;
+ Optional<LLButton::Params> arrow_button;
+ Optional<LLPanel::Params> items_panel;
+ Multiple<ItemParams> items;
+
+ Params();
+ };
+
+
+ virtual ~LLSplitButton() {};
+
+ //Overridden
+ virtual void onFocusLost();
+ virtual void setFocus(BOOL b);
+ virtual void setEnabled(BOOL enabled);
+
+ //Callbacks
+ void onArrowBtnDown();
+ void onHeldDownShownButton();
+ void onItemSelected(LLUICtrl* ctrl);
+ void setSelectionCallback(commit_callback_t cb) { mSelectionCallback = cb; }
+
+ virtual BOOL handleMouseUp(S32 x, S32 y, MASK mask);
+
+ virtual void showButtons();
+ virtual void hideButtons();
+
+
+protected:
+ friend class LLUICtrlFactory;
+ LLSplitButton(const LLSplitButton::Params& p);
+
+ LLButton* prepareItemButton(LLButton::Params params);
+ LLPanel* prepareItemsPanel(LLPanel::Params params, S32 items_count);
+
+ LLPanel* mItemsPanel;
+ std::list<LLButton*> mHidenItems;
+ LLButton* mArrowBtn;
+ LLButton* mShownItem;
+ EArrowPosition mArrowPosition;
+
+ commit_callback_t mSelectionCallback;
+};
+
+
+#endif
diff --git a/indra/newview/llsprite.cpp b/indra/newview/llsprite.cpp
index 893ed22297..dce4e9d144 100644
--- a/indra/newview/llsprite.cpp
+++ b/indra/newview/llsprite.cpp
@@ -48,7 +48,7 @@
#include "lldrawable.h"
#include "llface.h"
#include "llviewercamera.h"
-#include "llviewerimagelist.h"
+#include "llviewertexturelist.h"
LLVector3 LLSprite::sCameraUp(0.0f,0.0f,1.0f);
LLVector3 LLSprite::sCameraRight(1.0f,0.0f,0.0f);
diff --git a/indra/newview/llsprite.h b/indra/newview/llsprite.h
index 28f4ec5d03..eefe2a2386 100644
--- a/indra/newview/llsprite.h
+++ b/indra/newview/llsprite.h
@@ -40,7 +40,7 @@
#include "v4color.h"
#include "lluuid.h"
#include "llgl.h"
-#include "llviewerimage.h"
+#include "llviewertexture.h"
class LLViewerCamera;
@@ -82,7 +82,7 @@ public:
public:
LLUUID mImageID;
- LLPointer<LLViewerImage> mImagep;
+ LLPointer<LLViewerTexture> mImagep;
private:
F32 mWidth;
F32 mHeight;
diff --git a/indra/newview/llstartup.cpp b/indra/newview/llstartup.cpp
index 2c0d11baab..6c0481feaa 100644
--- a/indra/newview/llstartup.cpp
+++ b/indra/newview/llstartup.cpp
@@ -40,26 +40,27 @@
# include <sys/stat.h> // mkdir()
#endif
-#include "audioengine.h"
+#include "llviewermedia_streamingaudio.h"
+#include "llaudioengine.h"
#ifdef LL_FMOD
-# include "audioengine_fmod.h"
+# include "llaudioengine_fmod.h"
#endif
#ifdef LL_OPENAL
-#include "audioengine_openal.h"
+#include "llaudioengine_openal.h"
#endif
#include "llares.h"
+#include "lllandmark.h"
#include "llcachename.h"
-#include "llviewercontrol.h"
#include "lldir.h"
#include "llerrorcontrol.h"
#include "llfiltersd2xmlrpc.h"
+#include "llfloaterreg.h"
#include "llfocusmgr.h"
#include "llhttpsender.h"
-#include "imageids.h"
-#include "lllandmark.h"
+#include "lllocationhistory.h"
#include "llloginflags.h"
#include "llmd5.h"
#include "llmemorystream.h"
@@ -73,53 +74,52 @@
#include "llstring.h"
#include "lluserrelations.h"
#include "llversionviewer.h"
+#include "llviewercontrol.h"
#include "llvfs.h"
#include "llxorcipher.h" // saved password, MAC address
+#include "llwindow.h"
+#include "imageids.h"
#include "message.h"
#include "v3math.h"
#include "llagent.h"
+#include "llagentwearables.h"
#include "llagentpilot.h"
#include "llfloateravatarpicker.h"
#include "llcallbacklist.h"
#include "llcallingcard.h"
-#include "llcolorscheme.h"
#include "llconsole.h"
#include "llcontainerview.h"
-#include "llfloaterstats.h"
#include "lldebugview.h"
#include "lldrawable.h"
#include "lleventnotifier.h"
#include "llface.h"
#include "llfeaturemanager.h"
#include "llfirstuse.h"
-#include "llfloateractivespeakers.h"
-#include "llfloaterbeacons.h"
-#include "llfloatercamera.h"
#include "llfloaterchat.h"
#include "llfloatergesture.h"
#include "llfloaterhud.h"
#include "llfloaterland.h"
+#include "llfloaterpreference.h"
#include "llfloatertopobjects.h"
#include "llfloatertos.h"
#include "llfloaterworldmap.h"
-#include "llframestats.h"
-#include "llframestatview.h"
#include "llgesturemgr.h"
#include "llgroupmgr.h"
#include "llhudeffecttrail.h"
#include "llhudmanager.h"
#include "llhttpclient.h"
#include "llimagebmp.h"
+#include "llinventorybridge.h"
#include "llinventorymodel.h"
-#include "llinventoryview.h"
+#include "llfriendcard.h"
#include "llkeyboard.h"
#include "llloginhandler.h" // gLoginHandler, SLURL support
#include "llpanellogin.h"
-#include "llprefsim.h"
#include "llmutelist.h"
#include "llnotify.h"
#include "llpanelavatar.h"
+#include "llavatarpropertiesprocessor.h"
#include "llpaneldirbrowser.h"
#include "llpaneldirland.h"
#include "llpanelevent.h"
@@ -154,7 +154,7 @@
#include "llviewerdisplay.h"
#include "llviewergenericmessage.h"
#include "llviewergesture.h"
-#include "llviewerimagelist.h"
+#include "llviewertexturelist.h"
#include "llviewermedia.h"
#include "llviewermenu.h"
#include "llviewermessage.h"
@@ -167,6 +167,7 @@
#include "llviewerthrottle.h"
#include "llviewerwindow.h"
#include "llvoavatar.h"
+#include "llvoavatarself.h"
#include "llvoclouds.h"
#include "llweb.h"
#include "llworld.h"
@@ -185,10 +186,8 @@
#include "llwlparammanager.h"
#include "llwaterparammanager.h"
#include "llagentlanguage.h"
-
-#if LL_LIBXUL_ENABLED
-#include "llmozlib.h"
-#endif // LL_LIBXUL_ENABLED
+#include "llwearable.h"
+#include "llinventorybridge.h"
#if LL_WINDOWS
#include "llwindebug.h"
@@ -215,7 +214,7 @@ extern S32 gStartImageHeight;
// local globals
//
-LLPointer<LLImageGL> gStartImageGL;
+LLPointer<LLViewerTexture> gStartTexture;
static LLHost gAgentSimHost;
static BOOL gSkipOptionalUpdate = FALSE;
@@ -245,7 +244,6 @@ bool update_dialog_callback(const LLSD& notification, const LLSD& response);
void login_packet_failed(void**, S32 result);
void use_circuit_callback(void**, S32 result);
void register_viewer_callbacks(LLMessageSystem* msg);
-void init_stat_view();
void asset_callback_nothing(LLVFS*, const LLUUID&, LLAssetType::EType, void*, S32);
bool callback_choose_gender(const LLSD& notification, const LLSD& response);
void init_start_screen(S32 location_id);
@@ -253,7 +251,7 @@ void release_start_screen();
void reset_login();
void apply_udp_blacklist(const std::string& csv);
-void callback_cache_name(const LLUUID& id, const std::string& firstname, const std::string& lastname, BOOL is_group, void* data)
+void callback_cache_name(const LLUUID& id, const std::string& firstname, const std::string& lastname, BOOL is_group)
{
LLNameListCtrl::refreshAll(id, firstname, lastname, is_group);
LLNameBox::refreshAll(id, firstname, lastname, is_group);
@@ -293,8 +291,11 @@ public:
virtual void done()
{
// we've downloaded all the items, so repaint the dialog
- LLFloaterGesture::refreshAll();
-
+ LLFloaterGesture* floater = LLFloaterReg::findTypedInstance<LLFloaterGesture>("gestures");
+ if (floater)
+ {
+ floater->refreshAll();
+ }
gInventory.removeObserver(this);
delete this;
}
@@ -305,12 +306,65 @@ void update_texture_fetch()
LLAppViewer::getTextureCache()->update(1); // unpauses the texture cache thread
LLAppViewer::getImageDecodeThread()->update(1); // unpauses the image thread
LLAppViewer::getTextureFetch()->update(1); // unpauses the texture fetch thread
- gImageList.updateImages(0.10f);
+ gTextureList.updateImages(0.10f);
}
static std::vector<std::string> sAuthUris;
static S32 sAuthUriNum = -1;
+//Copies landmarks from the "Library" to "My Favorites"
+void populate_favorites_bar()
+{
+ //*TODO consider extending LLInventoryModel::findCategoryUUIDForType(...) to support both root's
+ LLInventoryModel::cat_array_t* lib_cats = NULL;
+ LLInventoryModel::item_array_t* lib_items = NULL;
+ gInventory.getDirectDescendentsOf(gInventory.getLibraryRootFolderID(), lib_cats, lib_items);
+ if (!lib_cats) return;
+
+ LLUUID lib_landmarks(LLUUID::null);
+ S32 count = lib_cats->count();
+ for(S32 i = 0; i < count; ++i)
+ {
+ if(lib_cats->get(i)->getPreferredType() == LLAssetType::AT_LANDMARK)
+ {
+ lib_landmarks = lib_cats->get(i)->getUUID();
+ break;
+ }
+ }
+ if (lib_landmarks.isNull())
+ {
+ llerror("Library inventory is missing Landmarks", 0);
+ return;
+ }
+
+ LLInventoryModel::cat_array_t* lm_cats = NULL;
+ LLInventoryModel::item_array_t* lm_items = NULL;
+ gInventory.getDirectDescendentsOf(lib_landmarks, lm_cats, lm_items);
+ if (!lm_items) return;
+
+ LLUUID favorites_id = gInventory.findCategoryUUIDForType(LLAssetType::AT_FAVORITE);
+ if (favorites_id.isNull())
+ {
+ llerror("My Inventory is missing My Favorites", 0);
+ return;
+ }
+
+ S32 lm_count = lm_items->count();
+ for (S32 i = 0; i < lm_count; ++i)
+ {
+ LLInventoryItem* item = lm_items->get(i);
+ if (item->getUUID().isNull()) continue;
+
+ copy_inventory_item(gAgent.getID(),
+ item->getPermissions().getOwner(),
+ item->getUUID(),
+ favorites_id,
+ std::string(),
+ LLPointer<LLInventoryCallback>(NULL));
+ }
+}
+
+
// Returns false to skip other idle processing. Should only return
// true when all initialization done.
bool idle_startup()
@@ -355,15 +409,25 @@ bool idle_startup()
static bool stipend_since_login = false;
- static bool samename = false;
-
// HACK: These are things from the main loop that usually aren't done
// until initialization is complete, but need to be done here for things
// to work.
gIdleCallbacks.callFunctions();
- gViewerWindow->handlePerFrameHover();
+ gViewerWindow->updateUI();
LLMortician::updateClass();
+ const std::string delims (" ");
+ std::string system;
+ int begIdx, endIdx;
+ std::string osString = LLAppViewer::instance()->getOSInfo().getOSStringSimple();
+
+ begIdx = osString.find_first_not_of (delims);
+ endIdx = osString.find_first_of (delims, begIdx);
+ system = osString.substr (begIdx, endIdx - begIdx);
+ system += "Locale";
+
+ LLStringUtil::setLocale (LLTrans::getString(system));
+
if (gNoRender)
{
// HACK, skip optional updates if you're running drones
@@ -372,7 +436,7 @@ bool idle_startup()
else
{
// Update images?
- gImageList.updateImages(0.01f);
+ gTextureList.updateImages(0.01f);
}
if ( STATE_FIRST == LLStartUp::getStartupState() )
@@ -431,8 +495,6 @@ bool idle_startup()
// Load autopilot and stats stuff
gAgentPilot.load(gSavedSettings.getString("StatsPilotFile"));
- gFrameStats.setFilename(gSavedSettings.getString("StatsFile"));
- gFrameStats.setSummaryFilename(gSavedSettings.getString("StatsSummaryFile"));
//gErrorStream.setTime(gSavedSettings.getBOOL("LogTimestamps"));
@@ -458,13 +520,24 @@ bool idle_startup()
#if LL_WINDOWS
// On the windows dev builds, unpackaged, the message_template.msg
- // file will be located in
- // indra/build-vc**/newview/<config>/app_settings.
+ // file will be located in:
+ // build-vc**/newview/<config>/app_settings
if (!found_template)
{
message_template_path = gDirUtilp->getExpandedFilename(LL_PATH_EXECUTABLE, "app_settings", "message_template.msg");
found_template = LLFile::fopen(message_template_path.c_str(), "r"); /* Flawfinder: ignore */
}
+ #elif LL_DARWIN
+ // On Mac dev builds, message_template.msg lives in:
+ // indra/build-*/newview/<config>/Second Life/Contents/Resources/app_settings
+ if (!found_template)
+ {
+ message_template_path =
+ gDirUtilp->getExpandedFilename(LL_PATH_EXECUTABLE,
+ "../Resources/app_settings",
+ "message_template.msg");
+ found_template = LLFile::fopen(message_template_path.c_str(), "r"); /* Flawfinder: ignore */
+ }
#endif
if (found_template)
@@ -643,6 +716,16 @@ bool idle_startup()
delete gAudiop;
gAudiop = NULL;
}
+
+ if (gAudiop)
+ {
+ // if the audio engine hasn't set up its own preferred handler for streaming audio then set up the generic streaming audio implementation which uses media plugins
+ if (NULL == gAudiop->getStreamingAudioImpl())
+ {
+ LL_INFOS("AppInit") << "Using media plugins to render streaming audio" << LL_ENDL;
+ gAudiop->setStreamingAudioImpl(new LLStreamingAudio_MediaPlugins());
+ }
+ }
}
}
@@ -728,8 +811,7 @@ bool idle_startup()
std::string msg = LLTrans::getString("LoginInitializingBrowser");
set_startup_status(0.03f, msg.c_str(), gAgent.mMOTD.c_str());
display_startup();
- LLViewerMedia::initBrowser();
-
+ // LLViewerMedia::initBrowser();
LLStartUp::setStartupState( STATE_LOGIN_SHOW );
return FALSE;
}
@@ -780,15 +862,11 @@ bool idle_startup()
// *NOTE: This is where gMuteList used to get allocated before becoming LLMuteList::getInstance().
- // Initialize UI
- if (!gNoRender)
+ // Login screen needs menus for preferences, but we can enter
+ // this startup phase more than once.
+ if (gLoginMenuBarView == NULL)
{
- // Initialize all our tools. Must be done after saved settings loaded.
- // NOTE: This also is where gToolMgr used to be instantiated before being turned into a singleton.
- LLToolMgr::getInstance()->initTools();
-
- // Quickly get something onscreen to look at.
- gViewerWindow->initWorldUI();
+ init_menus();
}
gViewerWindow->setNormalControlsVisible( FALSE );
@@ -857,10 +935,10 @@ bool idle_startup()
// Set PerAccountSettingsFile to the default value.
gSavedSettings.setString("PerAccountSettingsFile",
gDirUtilp->getExpandedFilename(LL_PATH_PER_SL_ACCOUNT,
- LLAppViewer::instance()->getSettingsFilename("Default", "PerAccount")
- )
- );
+ LLAppViewer::instance()->getSettingsFilename("Default", "PerAccount")));
+ // Note: can't store warnings files per account because some come up before login
+
// Overwrite default user settings with user settings
LLAppViewer::instance()->loadSettingsFromDirectory("Account");
@@ -872,10 +950,13 @@ bool idle_startup()
}
//Default the path if one isn't set.
- if (gSavedPerAccountSettings.getString("InstantMessageLogPath").empty())
+ if (gSavedPerAccountSettings.getString("InstantMessageLogFolder").empty())
{
gDirUtilp->setChatLogsDir(gDirUtilp->getOSUserAppDir());
- gSavedPerAccountSettings.setString("InstantMessageLogPath",gDirUtilp->getChatLogsDir());
+ std::string chat_log_dir = gDirUtilp->getChatLogsDir();
+ std::string chat_log_top_folder=gDirUtilp->getBaseFileName(chat_log_dir);
+ gSavedPerAccountSettings.setString("InstantMessageLogPath",chat_log_dir);
+ gSavedPerAccountSettings.setString("InstantMessageLogFolder",chat_log_top_folder);
}
else
{
@@ -915,15 +996,14 @@ bool idle_startup()
LLURLSimString::setString( location );
// END TODO
- LLPanelLogin::close();
+ LLPanelLogin::closePanel();
}
- //For HTML parsing in text boxes.
- LLTextEditor::setLinkColor( gSavedSettings.getColor4("HTMLLinkColor") );
-
// Load URL History File
LLURLHistory::loadFile("url_history.xml");
+ // Load location history
+ LLLocationHistory::getInstance()->load();
//-------------------------------------------------
// Handle startup progress screen
@@ -943,7 +1023,7 @@ bool idle_startup()
// UserLoginLocationReply arrives
location_which = START_LOCATION_ID_LAST;
}
- else if (gSavedSettings.getBOOL("LoginLastLocation"))
+ else if (gSavedSettings.getString("LoginLocation") == "last" )
{
agent_location_id = START_LOCATION_ID_LAST; // last location
location_which = START_LOCATION_ID_LAST;
@@ -963,7 +1043,7 @@ bool idle_startup()
// Display the startup progress bar.
gViewerWindow->setShowProgress(TRUE);
- gViewerWindow->setProgressCancelButtonVisible(TRUE, std::string("Quit")); // *TODO: Translate
+ gViewerWindow->setProgressCancelButtonVisible(TRUE, LLTrans::getString("Quit"));
// Poke the VFS, which could potentially block for a while if
// Windows XP is acting up
@@ -972,9 +1052,6 @@ bool idle_startup()
gVFS->pokeFiles();
- // color init must be after saved settings loaded
- init_colors();
-
// skipping over STATE_UPDATE_CHECK because that just waits for input
LLStartUp::setStartupState( STATE_LOGIN_AUTH_INIT );
@@ -1012,6 +1089,7 @@ bool idle_startup()
requested_options.push_back("event_categories");
requested_options.push_back("event_notifications");
requested_options.push_back("classified_categories");
+ requested_options.push_back("adult_compliant");
//requested_options.push_back("inventory-targets");
requested_options.push_back("buddy-list");
requested_options.push_back("ui-config");
@@ -1037,9 +1115,7 @@ bool idle_startup()
sAuthUriNum = 0;
auth_method = "login_to_simulator";
- LLStringUtil::format_map_t args;
- args["[APP_NAME]"] = LLAppViewer::instance()->getSecondLifeTitle();
- auth_desc = LLTrans::getString("LoginInProgress", args);
+ auth_desc = LLTrans::getString("LoginInProgress");
LLStartUp::setStartupState( STATE_LOGIN_AUTHENTICATE );
}
@@ -1063,13 +1139,9 @@ bool idle_startup()
start << xml_escape_string(unescaped_start.str());
}
- else if (gSavedSettings.getBOOL("LoginLastLocation"))
- {
- start << "last";
- }
else
{
- start << "home";
+ start << gSavedSettings.getString("LoginLocation");
}
char hashed_mac_string[MD5HEX_STR_SIZE]; /* Flawfinder: ignore */
@@ -1107,7 +1179,7 @@ bool idle_startup()
LL_DEBUGS("AppInit") << "STATE_LOGIN_NO_DATA_YET" << LL_ENDL;
// If we get here we have gotten past the potential stall
// in curl, so take "may appear frozen" out of progress bar. JC
- auth_desc = "Logging in...";
+ auth_desc = LLTrans::getString("LoginInProgressNoFrozen");
set_startup_status(progress, auth_desc, auth_message);
// Process messages to keep from dropping circuit.
LLMessageSystem* msg = gMessageSystem;
@@ -1218,9 +1290,7 @@ bool idle_startup()
{
LL_DEBUGS("AppInit") << "Need tos agreement" << LL_ENDL;
LLStartUp::setStartupState( STATE_UPDATE_CHECK );
- LLFloaterTOS* tos_dialog = LLFloaterTOS::show(LLFloaterTOS::TOS_TOS,
- message_response);
- tos_dialog->startModal();
+ LLFloaterReg::showInstance("message_tos", LLSD(message_response));
// LLFloaterTOS deletes itself.
return false;
}
@@ -1235,9 +1305,7 @@ bool idle_startup()
{
LL_DEBUGS("AppInit") << "Need critical message" << LL_ENDL;
LLStartUp::setStartupState( STATE_UPDATE_CHECK );
- LLFloaterTOS* tos_dialog = LLFloaterTOS::show(LLFloaterTOS::TOS_CRITICAL_MESSAGE,
- message_response);
- tos_dialog->startModal();
+ LLFloaterReg::showInstance("message_critical", LLSD(message_response));
// LLFloaterTOS deletes itself.
return false;
}
@@ -1455,8 +1523,7 @@ bool idle_startup()
it = options[0].find("folder_id");
if(it != options[0].end())
{
- gAgent.mInventoryRootID.set((*it).second);
- //gInventory.mock(gAgent.getInventoryRootID());
+ gInventory.setRootFolderID( LLUUID( (*it).second ) );
}
}
@@ -1487,6 +1554,9 @@ bool idle_startup()
if((*it).second == "Y") gPacificDaylightTime = TRUE;
else gPacificDaylightTime = FALSE;
}
+
+ //setup map of datetime strings to codes and slt & local time offset from utc
+ LLStringOps::setupDatetimeInfo (gPacificDaylightTime);
}
options.clear();
if (LLUserAuth::getInstance()->getOptions("initial-outfit", options)
@@ -1541,7 +1611,7 @@ bool idle_startup()
&& gAgentSessionID.notNull()
&& gMessageSystem->mOurCircuitCode
&& first_sim.isOk()
- && gAgent.mInventoryRootID.notNull())
+ && gInventory.getRootFolderID().notNull())
{
LLStartUp::setStartupState( STATE_WORLD_INIT );
}
@@ -1589,7 +1659,7 @@ bool idle_startup()
//---------------------------------------------------------------------
if (STATE_WORLD_INIT == LLStartUp::getStartupState())
{
- set_startup_status(0.40f, LLTrans::getString("LoginInitializingWorld"), gAgent.mMOTD);
+ set_startup_status(0.30f, LLTrans::getString("LoginInitializingWorld"), gAgent.mMOTD);
display_startup();
// We should have an agent id by this point.
llassert(!(gAgentID == LLUUID::null));
@@ -1601,11 +1671,12 @@ bool idle_startup()
// Since we connected, save off the settings so the user doesn't have to
// type the name/password again if we crash.
gSavedSettings.saveToFile(gSavedSettings.getString("ClientSettingsFile"), TRUE);
+ LLUIColorTable::instance().saveUserSettings();
//
// Initialize classes w/graphics stuff.
//
- gImageList.doPrefetchImages();
+ gTextureList.doPrefetchImages();
LLSurface::initClasses();
LLFace::initClass();
@@ -1617,9 +1688,16 @@ bool idle_startup()
LLWLParamManager::initClass();
LLWaterParamManager::initClass();
- // RN: don't initialize VO classes in drone mode, they are too closely tied to rendering
LLViewerObject::initVOClasses();
+ // Initialize all our tools. Must be done after saved settings loaded.
+ // NOTE: This also is where gToolMgr used to be instantiated before being turned into a singleton.
+ LLToolMgr::getInstance()->initTools();
+
+ // Pre-load floaters, like the world map, that are slow to spawn
+ // due to XML complexity.
+ gViewerWindow->initWorldUI();
+
display_startup();
// This is where we used to initialize gWorldp. Original comment said:
@@ -1662,6 +1740,14 @@ bool idle_startup()
if (STATE_MULTIMEDIA_INIT == LLStartUp::getStartupState())
{
LLStartUp::multimediaInit();
+ LLStartUp::setStartupState( STATE_FONT_INIT );
+ return FALSE;
+ }
+
+ // Loading fonts takes several seconds
+ if (STATE_FONT_INIT == LLStartUp::getStartupState())
+ {
+ LLStartUp::fontInit();
LLStartUp::setStartupState( STATE_SEED_GRANTED_WAIT );
return FALSE;
}
@@ -1690,33 +1776,6 @@ bool idle_startup()
gLoginMenuBarView->setVisible( FALSE );
gLoginMenuBarView->setEnabled( FALSE );
- LLRect window(0, gViewerWindow->getWindowHeight(), gViewerWindow->getWindowWidth(), 0);
- gViewerWindow->adjustControlRectanglesForFirstUse(window);
-
- if(gSavedSettings.getBOOL("ShowMiniMap"))
- {
- LLFloaterMap::showInstance();
- }
-
- if (gSavedSettings.getBOOL("ShowCameraControls"))
- {
- LLFloaterCamera::showInstance();
- }
- if (gSavedSettings.getBOOL("ShowMovementControls"))
- {
- LLFloaterMove::showInstance();
- }
-
- if (gSavedSettings.getBOOL("ShowActiveSpeakers"))
- {
- LLFloaterActiveSpeakers::showInstance();
- }
-
- if (gSavedSettings.getBOOL("BeaconAlwaysOn"))
- {
- LLFloaterBeacons::showInstance();
- }
-
if (!gNoRender)
{
// Move the progress view in front of the UI
@@ -1725,10 +1784,6 @@ bool idle_startup()
LLError::logToFixedBuffer(gDebugView->mDebugConsolep);
// set initial visibility of debug console
gDebugView->mDebugConsolep->setVisible(gSavedSettings.getBOOL("ShowDebugConsole"));
- if (gSavedSettings.getBOOL("ShowDebugStats"))
- {
- LLFloaterStats::showInstance();
- }
}
//
@@ -1752,8 +1807,10 @@ bool idle_startup()
if ( gCacheName == NULL )
{
gCacheName = new LLCacheName(gMessageSystem);
- gCacheName->addObserver(callback_cache_name);
-
+ gCacheName->addObserver(&callback_cache_name);
+ gCacheName->LocalizeCacheName("waiting", LLTrans::getString("CacheWaiting"));
+ gCacheName->LocalizeCacheName("nobody", LLTrans::getString("CacheNobody"));
+ gCacheName->LocalizeCacheName("none", LLTrans::getString("CacheNone"));
// Load stored cache if possible
LLAppViewer::instance()->loadNameCache();
}
@@ -1767,14 +1824,6 @@ bool idle_startup()
//reset statistics
LLViewerStats::getInstance()->resetStats();
- if (!gNoRender)
- {
- //
- // Set up all of our statistics UI stuff.
- //
- init_stat_view();
- }
-
display_startup();
//
// Set up region and surface defaults
@@ -1796,15 +1845,8 @@ bool idle_startup()
// Make sure agent knows correct aspect ratio
// FOV limits depend upon aspect ratio so this needs to happen before initializing the FOV below
- LLViewerCamera::getInstance()->setViewHeightInPixels(gViewerWindow->getWindowDisplayHeight());
- if (gViewerWindow->mWindow->getFullscreen())
- {
- LLViewerCamera::getInstance()->setAspect(gViewerWindow->getDisplayAspectRatio());
- }
- else
- {
- LLViewerCamera::getInstance()->setAspect( (F32) gViewerWindow->getWindowWidth() / (F32) gViewerWindow->getWindowHeight());
- }
+ LLViewerCamera::getInstance()->setViewHeightInPixels(gViewerWindow->getWorldViewHeight());
+ LLViewerCamera::getInstance()->setAspect(gViewerWindow->getWorldViewAspectRatio());
// Initialize FOV
LLViewerCamera::getInstance()->setDefaultFOV(gSavedSettings.getF32("CameraAngle"));
@@ -1841,7 +1883,7 @@ bool idle_startup()
F32 frac = (F32)i / (F32)DECODE_TIME_SEC;
set_startup_status(0.45f + frac*0.1f, LLTrans::getString("LoginDecodingImages"), gAgent.mMOTD);
display_startup();
- gImageList.decodeAllImages(1.f);
+ gTextureList.decodeAllImages(1.f);
}
LLStartUp::setStartupState( STATE_WORLD_WAIT );
@@ -1987,7 +2029,7 @@ bool idle_startup()
it = options[0].find("folder_id");
if(it != options[0].end())
{
- gInventoryLibraryRoot.set((*it).second);
+ gInventory.setLibraryRootFolderID( LLUUID( (*it).second ) );
}
}
options.clear();
@@ -1999,14 +2041,14 @@ bool idle_startup()
it = options[0].find("agent_id");
if(it != options[0].end())
{
- gInventoryLibraryOwner.set((*it).second);
+ gInventory.setLibraryOwnerID( LLUUID( (*it).second ) );
}
}
options.clear();
if(LLUserAuth::getInstance()->getOptions("inventory-skel-lib", options)
- && gInventoryLibraryOwner.notNull())
+ && gInventory.getLibraryOwnerID().notNull())
{
- if(!gInventory.loadSkeleton(options, gInventoryLibraryOwner))
+ if(!gInventory.loadSkeleton(options, gInventory.getLibraryOwnerID()))
{
LL_WARNS("AppInit") << "Problem loading inventory-skel-lib" << LL_ENDL;
}
@@ -2052,24 +2094,7 @@ bool idle_startup()
}
options.clear();
- if(LLUserAuth::getInstance()->getOptions("ui-config", options))
- {
- LLUserAuth::options_t::iterator it = options.begin();
- LLUserAuth::options_t::iterator end = options.end();
- for (; it != end; ++it)
- {
- LLUserAuth::response_t::const_iterator option_it;
- option_it = (*it).find("allow_first_life");
- if(option_it != (*it).end())
- {
- if (option_it->second == "Y")
- {
- LLPanelAvatar::sAllowFirstLife = TRUE;
- }
- }
- }
- }
- options.clear();
+
bool show_hud = false;
if(LLUserAuth::getInstance()->getOptions("tutorial_setting", options))
{
@@ -2097,10 +2122,9 @@ bool idle_startup()
// Either we want to show tutorial because this is the first login
// to a Linden Help Island or the user quit with the tutorial
// visible. JC
- if (show_hud
- || gSavedSettings.getBOOL("ShowTutorial"))
+ if (show_hud || gSavedSettings.getBOOL("ShowTutorial"))
{
- LLFloaterHUD::showHUD();
+ LLFloaterReg::showInstance("hud", LLSD(), FALSE);
}
options.clear();
@@ -2117,8 +2141,18 @@ bool idle_startup()
{
LLClassifiedInfo::loadCategories(options);
}
+
+
+ // This method MUST be called before gInventory.findCategoryUUIDForType because of
+ // gInventory.mIsAgentInvUsable is set to true in the gInventory.buildParentChildMap.
gInventory.buildParentChildMap();
+ //all categories loaded. lets create "My Favorites" category
+ gInventory.findCategoryUUIDForType(LLAssetType::AT_FAVORITE,true);
+
+ // lets create "Friends" and "Friends/All" in the Inventory "Calling Cards" and fill it with buddies
+ LLFriendCardsManager::instance().syncFriendsFolder();
+
llinfos << "Setting Inventory changed mask and notifying observers" << llendl;
gInventory.addChangedMask(LLInventoryObserver::ALL, LLUUID::null);
gInventory.notifyObservers();
@@ -2145,16 +2179,14 @@ bool idle_startup()
llinfos << "Requesting Agent Data" << llendl;
gAgent.sendAgentDataUpdateRequest();
- bool shown_at_exit = gSavedSettings.getBOOL("ShowInventory");
-
// Create the inventory views
llinfos << "Creating Inventory Views" << llendl;
- LLInventoryView::showAgentInventory();
+ LLFloaterReg::getInstance("inventory");
- // Hide the inventory if it wasn't shown at exit
- if(!shown_at_exit)
+ //default initial content for Favorites Bar
+ if (gAgent.isFirstLogin())
{
- LLInventoryView::toggleVisibility(NULL);
+ populate_favorites_bar();
}
LLStartUp::setStartupState( STATE_MISC );
@@ -2200,6 +2232,7 @@ bool idle_startup()
// We're successfully logged in.
gSavedSettings.setBOOL("FirstLoginThisInstall", FALSE);
+ LLFloaterReg::showInitialVisibleInstances();
// based on the comments, we've successfully logged in so we can delete the 'forced'
// URL that the updater set in settings.ini (in a mostly paranoid fashion)
@@ -2211,6 +2244,7 @@ bool idle_startup()
// and make sure it's saved
gSavedSettings.saveToFile( gSavedSettings.getString("ClientSettingsFile") , TRUE );
+ LLUIColorTable::instance().saveUserSettings();
};
if (!gNoRender)
@@ -2255,7 +2289,7 @@ bool idle_startup()
// Could schedule and delay these for later.
const BOOL no_inform_server = FALSE;
const BOOL no_deactivate_similar = FALSE;
- gGestureManager.activateGestureWithAsset(item_id, asset_id,
+ LLGestureManager::instance().activateGestureWithAsset(item_id, asset_id,
no_inform_server,
no_deactivate_similar);
// We need to fetch the inventory items for these gestures
@@ -2296,38 +2330,20 @@ bool idle_startup()
//{
//}
+ // The reason we show the alert is because we want to
+ // reduce confusion for when you log in and your provided
+ // location is not your expected location. So, if this is
+ // your first login, then you do not have an expectation,
+ // thus, do not show this alert.
if (!gAgent.isFirstLogin())
{
bool url_ok = LLURLSimString::sInstance.parse();
- if (!((agent_start_location == "url" && url_ok) ||
- (!url_ok && ((agent_start_location == "last" && gSavedSettings.getBOOL("LoginLastLocation")) ||
- (agent_start_location == "home" && !gSavedSettings.getBOOL("LoginLastLocation"))))))
- {
- // The reason we show the alert is because we want to
- // reduce confusion for when you log in and your provided
- // location is not your expected location. So, if this is
- // your first login, then you do not have an expectation,
- // thus, do not show this alert.
- LLSD args;
- if (url_ok)
- {
- args["TYPE"] = "desired";
- args["HELP"] = "";
- }
- else if (gSavedSettings.getBOOL("LoginLastLocation"))
- {
- args["TYPE"] = "last";
- args["HELP"] = "";
- }
- else
- {
- args["TYPE"] = "home";
- args["HELP"] = "You may want to set a new home location.";
- }
- LLNotifications::instance().add("AvatarMoved", args);
- }
- else
+ if ((url_ok && agent_start_location == "url") ||
+ (!url_ok && ((agent_start_location == gSavedSettings.getString("LoginLocation")))))
{
+ // Start location is OK
+ // Disabled code to restore camera location and focus if logging in to default location
+ static bool samename = false;
if (samename)
{
// restore old camera pos
@@ -2342,13 +2358,30 @@ bool idle_startup()
gAgent.stopCameraAnimation();
}
}
+ else
+ {
+ std::string msg;
+ if (url_ok)
+ {
+ msg = "AvatarMovedDesired";
+ }
+ else if (gSavedSettings.getString("LoginLocation") == "home")
+ {
+ msg = "AvatarMovedHome";
+ }
+ else
+ {
+ msg = "AvatarMovedLast";
+ }
+ LLNotifications::instance().add(msg);
+ }
}
//DEV-17797. get null folder. Any items found here moved to Lost and Found
LLInventoryModel::findLostItems();
//DEV-10530. do cleanup. remove at some later date. jan-2009
- LLPrefsIM::cleanupBadSetting();
+ LLFloaterPreference::cleanupBadSetting();
LLStartUp::setStartupState( STATE_PRECACHE );
timeout.reset();
@@ -2456,7 +2489,7 @@ bool idle_startup()
else
{
// OK to just get the wearables
- if ( gAgent.areWearablesLoaded() )
+ if ( gAgentWearables.areWearablesLoaded() )
{
// We have our clothing, proceed.
//llinfos << "wearables loaded" << llendl;
@@ -2477,12 +2510,12 @@ bool idle_startup()
set_startup_status(1.0, "", "");
// Let the map know about the inventory.
- if(gFloaterWorldMap)
+ LLFloaterWorldMap* floater_world_map = LLFloaterWorldMap::getInstance();
+ if(floater_world_map)
{
- gFloaterWorldMap->observeInventory(&gInventory);
- gFloaterWorldMap->observeFriends();
+ floater_world_map->observeInventory(&gInventory);
+ floater_world_map->observeFriends();
}
-
gViewerWindow->showCursor();
gViewerWindow->getWindow()->resetBusyCount();
gViewerWindow->getWindow()->setCursor(UI_CURSOR_ARROW);
@@ -2502,13 +2535,15 @@ bool idle_startup()
}
// Start automatic replay if the flag is set.
- if (gSavedSettings.getBOOL("StatsAutoRun"))
+ if (gSavedSettings.getBOOL("StatsAutoRun") || LLAgentPilot::sReplaySession)
{
LLUUID id;
LL_DEBUGS("AppInit") << "Starting automatic playback" << LL_ENDL;
gAgentPilot.startPlayback();
}
+ show_debug_menus(); // Debug menu visiblity and First Use trigger
+
// If we've got a startup URL, dispatch it
LLStartUp::dispatchURL();
@@ -2539,6 +2574,11 @@ bool idle_startup()
LLAppViewer::instance()->handleLoginComplete();
+ // reset timers now that we are running "logged in" logic
+ LLFastTimer::reset();
+
+
+
return TRUE;
}
@@ -2597,6 +2637,7 @@ void login_callback(S32 option, void *userdata)
{
// turn off the setting and write out to disk
gSavedSettings.saveToFile( gSavedSettings.getString("ClientSettingsFile") , TRUE );
+ LLUIColorTable::instance().saveUserSettings();
}
// Next iteration through main loop should shut down the app cleanly.
@@ -2604,7 +2645,7 @@ void login_callback(S32 option, void *userdata)
if (LLAppViewer::instance()->quitRequested())
{
- LLPanelLogin::close();
+ LLPanelLogin::closePanel();
}
return;
}
@@ -2761,7 +2802,7 @@ bool first_run_dialog_callback(const LLSD& notification, const LLSD& response)
if (0 == option)
{
LL_DEBUGS("AppInit") << "First run dialog cancelling" << LL_ENDL;
- LLWeb::loadURL( CREATE_ACCOUNT_URL );
+ LLWeb::loadURLExternal(LLTrans::getString("create_account_url") );
}
LLPanelLogin::giveFocus();
@@ -2786,12 +2827,12 @@ bool login_alert_status(const LLSD& notification, const LLSD& response)
{
case 0: // OK
break;
- case 1: // Help
- LLWeb::loadURL( SUPPORT_URL );
- break;
+ // case 1: // Help
+ // LLWeb::loadURL(LLNotifications::instance().getGlobalString("SUPPORT_URL") );
+ // break;
case 2: // Teleport
// Restart the login process, starting at our home locaton
- LLURLSimString::setString(LLURLSimString::sLocationStringHome);
+ LLURLSimString::setString("home");
LLStartUp::setStartupState( STATE_LOGIN_CLEANUP );
break;
default:
@@ -2806,14 +2847,13 @@ void update_app(BOOL mandatory, const std::string& auth_msg)
{
// store off config state, as we might quit soon
gSavedSettings.saveToFile(gSavedSettings.getString("ClientSettingsFile"), TRUE);
-
+ LLUIColorTable::instance().saveUserSettings();
std::ostringstream message;
- //*TODO:translate
std::string msg;
if (!auth_msg.empty())
{
- msg = "(" + auth_msg + ") \n";
+ msg = "("+ auth_msg + ") \n";
}
LLSD args;
@@ -2842,10 +2882,12 @@ void update_app(BOOL mandatory, const std::string& auth_msg)
#if LL_WINDOWS
notification_name += "Windows";
-#else
+#elif LL_DARWIN
notification_name += "Mac";
+#else
+ notification_name += "Linux";
#endif
-
+
if (mandatory)
{
notification_name += "Mandatory";
@@ -2858,7 +2900,6 @@ void update_app(BOOL mandatory, const std::string& auth_msg)
}
LLNotifications::instance().add(notification_name, args, payload, update_dialog_callback);
-
}
bool update_dialog_callback(const LLSD& notification, const LLSD& response)
@@ -2890,6 +2931,13 @@ bool update_dialog_callback(const LLSD& notification, const LLSD& response)
}
return false;
}
+
+ // if a sim name was passed in via command line parameter (typically through a SLURL)
+ if ( LLURLSimString::sInstance.mSimString.length() )
+ {
+ // record the location to start at next time
+ gSavedSettings.setString("NextLoginLocation", LLURLSimString::sInstance.mSimString);
+ }
LLSD query_map = LLSD::emptyMap();
// *TODO place os string in a global constant
@@ -2950,13 +2998,6 @@ bool update_dialog_callback(const LLSD& notification, const LLSD& response)
return false;
}
- // if a sim name was passed in via command line parameter (typically through a SLURL)
- if ( LLURLSimString::sInstance.mSimString.length() )
- {
- // record the location to start at next time
- gSavedSettings.setString( "NextLoginLocation", LLURLSimString::sInstance.mSimString );
- };
-
LLAppViewer::sUpdaterInfo->mParams << "-url \"" << update_url.asString() << "\"";
LL_DEBUGS("AppInit") << "Calling updater: " << LLAppViewer::sUpdaterInfo->mUpdateExePath << " " << LLAppViewer::sUpdaterInfo->mParams.str() << LL_ENDL;
@@ -2965,13 +3006,6 @@ bool update_dialog_callback(const LLSD& notification, const LLSD& response)
LLAppViewer::instance()->removeMarkerFile(); // In case updater fails
#elif LL_DARWIN
- // if a sim name was passed in via command line parameter (typically through a SLURL)
- if ( LLURLSimString::sInstance.mSimString.length() )
- {
- // record the location to start at next time
- gSavedSettings.setString( "NextLoginLocation", LLURLSimString::sInstance.mSimString );
- };
-
LLAppViewer::sUpdaterInfo->mUpdateExePath = "'";
LLAppViewer::sUpdaterInfo->mUpdateExePath += gDirUtilp->getAppRODataDir();
LLAppViewer::sUpdaterInfo->mUpdateExePath += "/mac-updater.app/Contents/MacOS/mac-updater' -url \"";
@@ -2985,10 +3019,50 @@ bool update_dialog_callback(const LLSD& notification, const LLSD& response)
// Run the auto-updater.
system(LLAppViewer::sUpdaterInfo->mUpdateExePath.c_str()); /* Flawfinder: ignore */
-#elif LL_LINUX || LL_SOLARIS
- OSMessageBox("Automatic updating is not yet implemented for Linux.\n"
- "Please download the latest version from www.secondlife.com.",
- LLStringUtil::null, OSMB_OK);
+#elif (LL_LINUX || LL_SOLARIS) && LL_GTK
+ // we tell the updater where to find the xml containing string
+ // translations which it can use for its own UI
+ std::string xml_strings_file = "strings.xml";
+ std::vector<std::string> xui_path_vec = LLUI::getXUIPaths();
+ std::string xml_search_paths;
+ std::vector<std::string>::const_iterator iter;
+ // build comma-delimited list of xml paths to pass to updater
+ for (iter = xui_path_vec.begin(); iter != xui_path_vec.end(); )
+ {
+ std::string this_skin_dir = gDirUtilp->getDefaultSkinDir()
+ + gDirUtilp->getDirDelimiter()
+ + (*iter);
+ llinfos << "Got a XUI path: " << this_skin_dir << llendl;
+ xml_search_paths.append(this_skin_dir);
+ ++iter;
+ if (iter != xui_path_vec.end())
+ xml_search_paths.append(","); // comma-delimit
+ }
+ // build the overall command-line to run the updater correctly
+ update_exe_path =
+ gDirUtilp->getExecutableDir() + "/" + "linux-updater.bin" +
+ " --url \"" + update_url.asString() + "\"" +
+ " --name \"" + LLAppViewer::instance()->getSecondLifeTitle() + "\"" +
+ " --dest \"" + gDirUtilp->getAppRODataDir() + "\"" +
+ " --stringsdir \"" + xml_search_paths + "\"" +
+ " --stringsfile \"" + xml_strings_file + "\"";
+
+ LL_INFOS("AppInit") << "Calling updater: "
+ << update_exe_path << LL_ENDL;
+
+ // *TODO: we could use the gdk equivilant to ensure the updater
+ // gets started on the same screen.
+ GError *error = NULL;
+ if (!g_spawn_command_line_async(update_exe_path.c_str(), &error))
+ {
+ llerrs << "Failed to launch updater: "
+ << error->message
+ << llendl;
+ }
+ if (error)
+ g_error_free(error);
+#else
+ OSMessageBox(LLTrans::getString("MBNoAutoUpdate"), LLStringUtil::null, OSMB_OK);
#endif
LLAppViewer::instance()->forceQuit();
return false;
@@ -3018,8 +3092,8 @@ void use_circuit_callback(void**, S32 result)
void register_viewer_callbacks(LLMessageSystem* msg)
{
msg->setHandlerFuncFast(_PREHASH_LayerData, process_layer_data );
- msg->setHandlerFuncFast(_PREHASH_ImageData, LLViewerImageList::receiveImageHeader );
- msg->setHandlerFuncFast(_PREHASH_ImagePacket, LLViewerImageList::receiveImagePacket );
+ msg->setHandlerFuncFast(_PREHASH_ImageData, LLViewerTextureList::receiveImageHeader );
+ msg->setHandlerFuncFast(_PREHASH_ImagePacket, LLViewerTextureList::receiveImagePacket );
msg->setHandlerFuncFast(_PREHASH_ObjectUpdate, process_object_update );
msg->setHandlerFunc("ObjectUpdateCompressed", process_compressed_object_update );
msg->setHandlerFunc("ObjectUpdateCached", process_cached_object_update );
@@ -3049,7 +3123,7 @@ void register_viewer_callbacks(LLMessageSystem* msg)
msg->setHandlerFuncFast(_PREHASH_AvatarAnimation, process_avatar_animation);
msg->setHandlerFuncFast(_PREHASH_AvatarAppearance, process_avatar_appearance);
msg->setHandlerFunc("AgentCachedTextureResponse", LLAgent::processAgentCachedTextureResponse);
- msg->setHandlerFunc("RebakeAvatarTextures", LLVOAvatar::processRebakeAvatarTextures);
+ msg->setHandlerFunc("RebakeAvatarTextures", LLVOAvatarSelf::processRebakeAvatarTextures);
msg->setHandlerFuncFast(_PREHASH_CameraConstraint, process_camera_constraint);
msg->setHandlerFuncFast(_PREHASH_AvatarSitResponse, process_avatar_sit_response);
msg->setHandlerFunc("SetFollowCamProperties", process_set_follow_cam_properties);
@@ -3093,20 +3167,20 @@ void register_viewer_callbacks(LLMessageSystem* msg)
LLViewerParcelMgr::processParcelDwellReply);
msg->setHandlerFunc("AvatarPropertiesReply",
- LLPanelAvatar::processAvatarPropertiesReply);
+ &LLAvatarPropertiesProcessor::processAvatarPropertiesReply);
msg->setHandlerFunc("AvatarInterestsReply",
- LLPanelAvatar::processAvatarInterestsReply);
+ &LLAvatarPropertiesProcessor::processAvatarInterestsReply);
msg->setHandlerFunc("AvatarGroupsReply",
- LLPanelAvatar::processAvatarGroupsReply);
+ &LLAvatarPropertiesProcessor::processAvatarGroupsReply);
// ratings deprecated
//msg->setHandlerFuncFast(_PREHASH_AvatarStatisticsReply,
// LLPanelAvatar::processAvatarStatisticsReply);
msg->setHandlerFunc("AvatarNotesReply",
- LLPanelAvatar::processAvatarNotesReply);
+ &LLAvatarPropertiesProcessor::processAvatarNotesReply);
msg->setHandlerFunc("AvatarPicksReply",
- LLPanelAvatar::processAvatarPicksReply);
- msg->setHandlerFunc("AvatarClassifiedReply",
- LLPanelAvatar::processAvatarClassifiedReply);
+ &LLAvatarPropertiesProcessor::processAvatarPicksReply);
+ msg->setHandlerFunc("AvatarClassifiedReply",
+ &LLAvatarPropertiesProcessor::processAvatarClassifiedReply);
msg->setHandlerFuncFast(_PREHASH_CreateGroupReply,
LLGroupMgr::processCreateGroupReply);
@@ -3124,7 +3198,7 @@ void register_viewer_callbacks(LLMessageSystem* msg)
// LLFloaterRate::processReputationIndividualReply);
msg->setHandlerFuncFast(_PREHASH_AgentWearablesUpdate,
- LLAgent::processAgentInitialWearablesUpdate );
+ LLAgentWearables::processAgentInitialWearablesUpdate );
msg->setHandlerFunc("ScriptControlChange",
LLAgent::processScriptControlChange );
@@ -3150,7 +3224,7 @@ void register_viewer_callbacks(LLMessageSystem* msg)
msg->setHandlerFunc("TeleportFailed", process_teleport_failed, NULL);
msg->setHandlerFunc("TeleportLocal", process_teleport_local, NULL);
- msg->setHandlerFunc("ImageNotInDatabase", LLViewerImageList::processImageNotInDatabase, NULL);
+ msg->setHandlerFunc("ImageNotInDatabase", LLViewerTextureList::processImageNotInDatabase, NULL);
msg->setHandlerFuncFast(_PREHASH_GroupMembersReply,
LLGroupMgr::processGroupMembersReply);
@@ -3180,9 +3254,9 @@ void register_viewer_callbacks(LLMessageSystem* msg)
msg->setHandlerFunc("MapItemReply", LLWorldMap::processMapItemReply);
msg->setHandlerFunc("EventInfoReply", LLPanelEvent::processEventInfoReply);
- msg->setHandlerFunc("PickInfoReply", LLPanelPick::processPickInfoReply);
+ msg->setHandlerFunc("PickInfoReply", &LLAvatarPropertiesProcessor::processPickInfoReply);
msg->setHandlerFunc("ClassifiedInfoReply", LLPanelClassified::processClassifiedInfoReply);
- msg->setHandlerFunc("ParcelInfoReply", LLPanelPlace::processParcelInfoReply);
+ msg->setHandlerFunc("ParcelInfoReply", LLRemoteParcelInfoProcessor::processParcelInfoReply);
msg->setHandlerFunc("ScriptDialog", process_script_dialog);
msg->setHandlerFunc("LoadURL", process_load_url);
msg->setHandlerFunc("ScriptTeleportRequest", process_script_teleport_request);
@@ -3202,14 +3276,6 @@ void register_viewer_callbacks(LLMessageSystem* msg)
msg->setHandlerFuncFast(_PREHASH_FeatureDisabled, process_feature_disabled_message);
}
-
-void init_stat_view()
-{
- LLFrameStatView *frameviewp = gDebugView->mFrameStatView;
- frameviewp->setup(gFrameStats);
- frameviewp->mShowPercent = FALSE;
-}
-
void asset_callback_nothing(LLVFS*, const LLUUID&, LLAssetType::EType, void*, S32)
{
// nothing
@@ -3271,7 +3337,7 @@ void LLStartUp::loadInitialOutfit( const std::string& outfit_folder_name,
has_name);
if (0 == cat_array.count())
{
- gAgent.createStandardWearables(gender);
+ gAgentWearables.createStandardWearables(gender);
}
else
{
@@ -3287,13 +3353,11 @@ void LLStartUp::loadInitialOutfit( const std::string& outfit_folder_name,
}
// Loads a bitmap to display during load
-// location_id = 0 => last position
-// location_id = 1 => home position
void init_start_screen(S32 location_id)
{
- if (gStartImageGL.notNull())
+ if (gStartTexture.notNull())
{
- gStartImageGL = NULL;
+ gStartTexture = NULL;
LL_INFOS("AppInit") << "re-initializing start screen" << LL_ENDL;
}
@@ -3325,7 +3389,6 @@ void init_start_screen(S32 location_id)
return;
}
- gStartImageGL = new LLImageGL(FALSE);
gStartImageWidth = start_image_bmp->getWidth();
gStartImageHeight = start_image_bmp->getHeight();
@@ -3333,12 +3396,12 @@ void init_start_screen(S32 location_id)
if (!start_image_bmp->decode(raw, 0.0f))
{
LL_WARNS("AppInit") << "Bitmap decode failed" << LL_ENDL;
- gStartImageGL = NULL;
+ gStartTexture = NULL;
return;
}
raw->expandToPowerOfTwo();
- gStartImageGL->createGLTexture(0, raw);
+ gStartTexture = LLViewerTextureManager::getLocalTexture(raw.get(), FALSE) ;
}
@@ -3346,7 +3409,7 @@ void init_start_screen(S32 location_id)
void release_start_screen()
{
LL_DEBUGS("AppInit") << "Releasing bitmap..." << LL_ENDL;
- gStartImageGL = NULL;
+ gStartTexture = NULL;
}
@@ -3406,7 +3469,7 @@ void reset_login()
}
// Hide any other stuff
- LLFloaterMap::hideInstance();
+ LLFloaterReg::hideVisibleInstances();
}
//---------------------------------------------------------------------------
@@ -3427,16 +3490,26 @@ void LLStartUp::multimediaInit()
set_startup_status(0.42f, msg.c_str(), gAgent.mMOTD.c_str());
display_startup();
- LLViewerMedia::initClass();
+ // LLViewerMedia::initClass();
LLViewerParcelMedia::initClass();
}
+void LLStartUp::fontInit()
+{
+ LL_DEBUGS("AppInit") << "Initializing fonts...." << LL_ENDL;
+ std::string msg = LLTrans::getString("LoginInitializingFonts");
+ set_startup_status(0.45f, msg.c_str(), gAgent.mMOTD.c_str());
+ display_startup();
+
+ LLFontGL::loadDefaultFonts();
+}
+
bool LLStartUp::dispatchURL()
{
// ok, if we've gotten this far and have a startup URL
if (!sSLURLCommand.empty())
{
- LLWebBrowserCtrl* web = NULL;
+ LLMediaCtrl* web = NULL;
const bool trusted_browser = false;
LLURLDispatcher::dispatch(sSLURLCommand, web, trusted_browser);
}
@@ -3454,7 +3527,7 @@ bool LLStartUp::dispatchURL()
|| (dy*dy > SLOP*SLOP) )
{
std::string url = LLURLSimString::getURL();
- LLWebBrowserCtrl* web = NULL;
+ LLMediaCtrl* web = NULL;
const bool trusted_browser = false;
LLURLDispatcher::dispatch(url, web, trusted_browser);
}
diff --git a/indra/newview/llstartup.h b/indra/newview/llstartup.h
index fe347e9efe..4532c5e586 100644
--- a/indra/newview/llstartup.h
+++ b/indra/newview/llstartup.h
@@ -33,7 +33,7 @@
#ifndef LL_LLSTARTUP_H
#define LL_LLSTARTUP_H
-#include "llimagegl.h"
+class LLViewerTexture ;
// functions
bool idle_startup();
@@ -58,6 +58,7 @@ typedef enum {
STATE_LOGIN_PROCESS_RESPONSE, // Check authentication reply
STATE_WORLD_INIT, // Start building the world
STATE_MULTIMEDIA_INIT, // Init the rest of multimedia library
+ STATE_FONT_INIT, // Load default fonts
STATE_SEED_GRANTED_WAIT, // Wait for seed cap grant
STATE_SEED_CAP_GRANTED, // Have seed cap grant
STATE_WORLD_WAIT, // Waiting for simulator
@@ -73,7 +74,7 @@ typedef enum {
// exported symbols
extern bool gAgentMovementCompleted;
-extern LLPointer<LLImageGL> gStartImageGL;
+extern LLPointer<LLViewerTexture> gStartTexture;
extern std::string gInitialOutfit;
extern std::string gInitialOutfitGender; // "male" or "female"
@@ -92,6 +93,9 @@ public:
static void multimediaInit();
// Initialize LLViewerMedia multimedia engine.
+ // Load default fonts not already loaded at start screen
+ static void fontInit();
+
// outfit_folder_name can be a folder anywhere in your inventory,
// but the name must be a case-sensitive exact match.
// gender_name is either "male" or "female"
diff --git a/indra/newview/llstatusbar.cpp b/indra/newview/llstatusbar.cpp
index f36d12d638..c724fb5315 100644
--- a/indra/newview/llstatusbar.cpp
+++ b/indra/newview/llstatusbar.cpp
@@ -43,16 +43,16 @@
#include "llfloaterchat.h"
#include "llfloaterdirectory.h" // to spawn search
#include "llfloaterlagmeter.h"
-#include "llfloaterland.h"
#include "llfloaterregioninfo.h"
#include "llfloaterscriptdebug.h"
#include "llhudicon.h"
-#include "llinventoryview.h"
+#include "llnavigationbar.h"
#include "llkeyboard.h"
#include "lllineeditor.h"
#include "llmenugl.h"
#include "llnotify.h"
#include "llimview.h"
+#include "llsd.h"
#include "lltextbox.h"
#include "llui.h"
#include "llviewerparceloverlay.h"
@@ -60,7 +60,7 @@
#include "llviewerstats.h"
#include "llviewerwindow.h"
#include "llframetimer.h"
-#include "llvoavatar.h"
+#include "llvoavatarself.h"
#include "llresmgr.h"
#include "llworld.h"
#include "llstatgraph.h"
@@ -68,14 +68,14 @@
#include "llviewerparcelmgr.h"
#include "llviewerthrottle.h"
#include "lluictrlfactory.h"
-#include "llvoiceclient.h" // for gVoiceClient
#include "lltoolmgr.h"
#include "llfocusmgr.h"
#include "llappviewer.h"
-
+#include "lltrans.h"
// library includes
#include "imageids.h"
+#include "llfloaterreg.h"
#include "llfontgl.h"
#include "llrect.h"
#include "llerror.h"
@@ -91,7 +91,7 @@
// Globals
//
LLStatusBar *gStatusBar = NULL;
-S32 STATUS_BAR_HEIGHT = 0;
+S32 STATUS_BAR_HEIGHT = 26;
extern S32 MENU_BAR_HEIGHT;
@@ -107,29 +107,23 @@ const F32 ICON_TIMER_EXPIRY = 3.f; // How long the balance and health icons sho
const F32 ICON_FLASH_FREQUENCY = 2.f;
const S32 TEXT_HEIGHT = 18;
-static void onClickParcelInfo(void*);
-static void onClickBalance(void*);
static void onClickBuyCurrency(void*);
static void onClickHealth(void*);
-static void onClickFly(void*);
-static void onClickPush(void*);
-static void onClickVoice(void*);
-static void onClickBuild(void*);
-static void onClickScripts(void*);
-static void onClickBuyLand(void*);
static void onClickScriptDebug(void*);
std::vector<std::string> LLStatusBar::sDays;
std::vector<std::string> LLStatusBar::sMonths;
const U32 LLStatusBar::MAX_DATE_STRING_LENGTH = 2000;
-LLStatusBar::LLStatusBar(const std::string& name, const LLRect& rect)
-: LLPanel(name, LLRect(), FALSE), // not mouse opaque
-mBalance(0),
-mHealth(100),
-mSquareMetersCredit(0),
-mSquareMetersCommitted(0)
+LLStatusBar::LLStatusBar(const LLRect& rect)
+: LLPanel(),
+ mBalance(0),
+ mHealth(100),
+ mSquareMetersCredit(0),
+ mSquareMetersCommitted(0)
{
+ setRect(rect);
+
// status bar can possible overlay menus?
setMouseOpaque(FALSE);
setIsChrome(TRUE);
@@ -149,56 +143,42 @@ mSquareMetersCommitted(0)
// build date necessary data (must do after panel built)
setupDate();
- mTextParcelName = getChild<LLTextBox>("ParcelNameText" );
- mTextBalance = getChild<LLTextBox>("BalanceText" );
-
mTextHealth = getChild<LLTextBox>("HealthText" );
mTextTime = getChild<LLTextBox>("TimeText" );
+
+ mBtnBuyCurrency = getChild<LLButton>( "buycurrency" );
+ mBtnBuyCurrency->setClickedCallback( onClickBuyCurrency, this );
childSetAction("scriptout", onClickScriptDebug, this);
childSetAction("health", onClickHealth, this);
- childSetAction("no_fly", onClickFly, this);
- childSetAction("buyland", onClickBuyLand, this );
- childSetAction("buycurrency", onClickBuyCurrency, this );
- childSetAction("no_build", onClickBuild, this );
- childSetAction("no_scripts", onClickScripts, this );
- childSetAction("restrictpush", onClickPush, this );
- childSetAction("status_no_voice", onClickVoice, this );
-
- childSetCommitCallback("search_editor", onCommitSearch, this);
- childSetAction("search_btn", onClickSearch, this);
-
- childSetVisible("search_editor", gSavedSettings.getBOOL("ShowSearchBar"));
- childSetVisible("search_btn", gSavedSettings.getBOOL("ShowSearchBar"));
- childSetVisible("menubar_search_bevel_bg", gSavedSettings.getBOOL("ShowSearchBar"));
-
- childSetActionTextbox("ParcelNameText", onClickParcelInfo );
- childSetActionTextbox("BalanceText", onClickBalance );
// Adding Net Stat Graph
S32 x = getRect().getWidth() - 2;
S32 y = 0;
LLRect r;
r.set( x-SIM_STAT_WIDTH, y+MENU_BAR_HEIGHT-1, x, y+1);
- mSGBandwidth = new LLStatGraph("BandwidthGraph", r);
- mSGBandwidth->setFollows(FOLLOWS_BOTTOM | FOLLOWS_RIGHT);
+ LLStatGraph::Params sgp;
+ sgp.name("BandwidthGraph");
+ sgp.rect(r);
+ sgp.follows.flags(FOLLOWS_BOTTOM | FOLLOWS_RIGHT);
+ sgp.mouse_opaque(false);
+ mSGBandwidth = LLUICtrlFactory::create<LLStatGraph>(sgp);
mSGBandwidth->setStat(&LLViewerStats::getInstance()->mKBitStat);
- std::string text = childGetText("bandwidth_tooltip") + " ";
- LLUIString bandwidth_tooltip = text; // get the text from XML until this widget is XML driven
- mSGBandwidth->setLabel(bandwidth_tooltip.getString());
mSGBandwidth->setUnits("Kbps");
mSGBandwidth->setPrecision(0);
- mSGBandwidth->setMouseOpaque(FALSE);
addChild(mSGBandwidth);
x -= SIM_STAT_WIDTH + 2;
r.set( x-SIM_STAT_WIDTH, y+MENU_BAR_HEIGHT-1, x, y+1);
- mSGPacketLoss = new LLStatGraph("PacketLossPercent", r);
- mSGPacketLoss->setFollows(FOLLOWS_BOTTOM | FOLLOWS_RIGHT);
+ //these don't seem to like being reused
+ LLStatGraph::Params pgp;
+ pgp.name("PacketLossPercent");
+ pgp.rect(r);
+ pgp.follows.flags(FOLLOWS_BOTTOM | FOLLOWS_RIGHT);
+ pgp.mouse_opaque(false);
+
+ mSGPacketLoss = LLUICtrlFactory::create<LLStatGraph>(pgp);
mSGPacketLoss->setStat(&LLViewerStats::getInstance()->mPacketsLostPercentStat);
- text = childGetText("packet_loss_tooltip") + " ";
- LLUIString packet_loss_tooltip = text; // get the text from XML until this widget is XML driven
- mSGPacketLoss->setLabel(packet_loss_tooltip.getString());
mSGPacketLoss->setUnits("%");
mSGPacketLoss->setMin(0.f);
mSGPacketLoss->setMax(5.f);
@@ -206,7 +186,6 @@ mSquareMetersCommitted(0)
mSGPacketLoss->setThreshold(1, 1.f);
mSGPacketLoss->setThreshold(2, 3.f);
mSGPacketLoss->setPrecision(1);
- mSGPacketLoss->setMouseOpaque(FALSE);
mSGPacketLoss->mPerSec = FALSE;
addChild(mSGPacketLoss);
@@ -236,77 +215,76 @@ void LLStatusBar::draw()
if (isBackgroundVisible())
{
+ static LLUICachedControl<S32> drop_shadow_floater ("DropShadowFloater", 0);
+ static LLUIColor color_drop_shadow = LLUIColorTable::instance().getColor("ColorDropShadow");
gl_drop_shadow(0, getRect().getHeight(), getRect().getWidth(), 0,
- LLUI::sColorsGroup->getColor("ColorDropShadow"),
- LLUI::sConfigGroup->getS32("DropShadowFloater") );
+ color_drop_shadow, drop_shadow_floater );
}
LLPanel::draw();
}
-
-// Per-frame updates of visibility
-void LLStatusBar::refresh()
+BOOL LLStatusBar::handleRightMouseDown(S32 x, S32 y, MASK mask)
{
- // Adding Net Stat Meter back in
- F32 bwtotal = gViewerThrottle.getMaxBandwidth() / 1000.f;
- mSGBandwidth->setMin(0.f);
- mSGBandwidth->setMax(bwtotal*1.25f);
- mSGBandwidth->setThreshold(0, bwtotal*0.75f);
- mSGBandwidth->setThreshold(1, bwtotal);
- mSGBandwidth->setThreshold(2, bwtotal);
+ if (mHideNavbarContextMenu)
+ {
+ mHideNavbarContextMenu->buildDrawLabels();
+ mHideNavbarContextMenu->updateParent(LLMenuGL::sMenuContainer);
+ LLMenuGL::showPopup(this, mHideNavbarContextMenu, x, y);
+ }
- // *TODO: Localize / translate time
+ return TRUE;
+}
- // Get current UTC time, adjusted for the user's clock
- // being off.
- time_t utc_time;
- utc_time = time_corrected();
+BOOL LLStatusBar::postBuild()
+{
+ mCommitCallbackRegistrar.add("HideNavbarMenu.Action", boost::bind(&LLStatusBar::onHideNavbarContextMenuItemClicked, this, _2));
+ mEnableCallbackRegistrar.add("HideNavbarMenu.EnableMenuItem", boost::bind(&LLStatusBar::onHideNavbarContextMenuItemEnabled, this, _2));
- // There's only one internal tm buffer.
- struct tm* internal_time;
+ mHideNavbarContextMenu = LLUICtrlFactory::getInstance()->createFromFile<LLMenuGL>("menu_hide_navbar.xml", gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance());
+ gMenuHolder->addChild(mHideNavbarContextMenu);
- // Convert to Pacific, based on server's opinion of whether
- // it's daylight savings time there.
- internal_time = utc_to_pacific_time(utc_time, gPacificDaylightTime);
+ gMenuBarView->setRightMouseDownCallback(boost::bind(&LLStatusBar::onMainMenuRightClicked, this, _1, _2, _3, _4));
- S32 hour = internal_time->tm_hour;
- S32 min = internal_time->tm_min;
+ return TRUE;
+}
- std::string am_pm = "AM";
- if (hour > 11)
+// Per-frame updates of visibility
+void LLStatusBar::refresh()
+{
+ bool net_stats_visible = gSavedSettings.getBOOL("ShowNetStats");
+
+ if (net_stats_visible)
{
- hour -= 12;
- am_pm = "PM";
+ // Adding Net Stat Meter back in
+ F32 bwtotal = gViewerThrottle.getMaxBandwidth() / 1000.f;
+ mSGBandwidth->setMin(0.f);
+ mSGBandwidth->setMax(bwtotal*1.25f);
+ mSGBandwidth->setThreshold(0, bwtotal*0.75f);
+ mSGBandwidth->setThreshold(1, bwtotal);
+ mSGBandwidth->setThreshold(2, bwtotal);
}
+
+ // Get current UTC time, adjusted for the user's clock
+ // being off.
+ time_t utc_time;
+ utc_time = time_corrected();
- std::string tz = "PST";
- if (gPacificDaylightTime)
- {
- tz = "PDT";
- }
- // Zero hour is 12 AM
- if (hour == 0) hour = 12;
- std::ostringstream t;
- t << std::setfill(' ') << std::setw(2) << hour << ":"
- << std::setfill('0') << std::setw(2) << min
- << " " << am_pm << " " << tz;
- mTextTime->setText(t.str());
-
- // Year starts at 1900, set the tooltip to have the date
- std::ostringstream date;
- date << sDays[internal_time->tm_wday] << ", "
- << std::setfill('0') << std::setw(2) << internal_time->tm_mday << " "
- << sMonths[internal_time->tm_mon] << " "
- << internal_time->tm_year + 1900;
- mTextTime->setToolTip(date.str());
+ std::string timeStr = getString("time");
+ LLSD substitution;
+ substitution["datetime"] = (S32) utc_time;
+ LLStringUtil::format (timeStr, substitution);
+ mTextTime->setText(timeStr);
+
+ // set the tooltip to have the date
+ std::string dtStr = getString("timeTooltip");
+ LLStringUtil::format (dtStr, substitution);
+ mTextTime->setToolTip (dtStr);
LLRect r;
const S32 MENU_RIGHT = gMenuBarView->getRightmostMenuEdge();
S32 x = MENU_RIGHT + MENU_PARCEL_SPACING;
S32 y = 0;
- bool search_visible = gSavedSettings.getBOOL("ShowSearchBar");
-
// reshape menu bar to its content's width
if (MENU_RIGHT != gMenuBarView->getRect().getWidth())
{
@@ -331,8 +309,8 @@ void LLStatusBar::refresh()
childSetVisible("scriptout", false);
}
- if ((region && region->getAllowDamage()) ||
- (parcel && parcel->getAllowDamage()) )
+ if (gAgent.getCameraMode() == CAMERA_MODE_MOUSELOOK &&
+ ((region && region->getAllowDamage()) || (parcel && parcel->getAllowDamage())))
{
// set visibility based on flashing
if( mHealthTimer->hasExpired() )
@@ -364,293 +342,15 @@ void LLStatusBar::refresh()
mTextHealth->setVisible(FALSE);
}
- if ((region && region->getBlockFly()) ||
- (parcel && !parcel->getAllowFly()) )
- {
- // No Fly Zone
- childGetRect( "no_fly", buttonRect );
- childSetVisible( "no_fly", true );
- r.setOriginAndSize( x, y, buttonRect.getWidth(), buttonRect.getHeight());
- childSetRect( "no_fly", r );
- x += buttonRect.getWidth();
- }
- else
- {
- // Fly Zone
- childSetVisible("no_fly", false);
- }
-
- BOOL no_build = parcel && !parcel->getAllowModify();
- if (no_build)
- {
- childSetVisible("no_build", TRUE);
- childGetRect( "no_build", buttonRect );
- // No Build Zone
- r.setOriginAndSize( x, y, buttonRect.getWidth(), buttonRect.getHeight());
- childSetRect( "no_build", r );
- x += buttonRect.getWidth();
- }
- else
- {
- childSetVisible("no_build", FALSE);
- }
-
- BOOL no_scripts = FALSE;
- if((region
- && ((region->getRegionFlags() & REGION_FLAGS_SKIP_SCRIPTS)
- || (region->getRegionFlags() & REGION_FLAGS_ESTATE_SKIP_SCRIPTS)))
- || (parcel && !parcel->getAllowOtherScripts()))
- {
- no_scripts = TRUE;
- }
- if (no_scripts)
- {
- // No scripts
- childSetVisible("no_scripts", TRUE);
- childGetRect( "no_scripts", buttonRect );
- r.setOriginAndSize( x, y, buttonRect.getWidth(), buttonRect.getHeight());
- childSetRect( "no_scripts", r );
- x += buttonRect.getWidth();
- }
- else
- {
- // Yes scripts
- childSetVisible("no_scripts", FALSE);
- }
-
- BOOL no_region_push = (region && region->getRestrictPushObject());
- BOOL no_push = no_region_push || (parcel && parcel->getRestrictPushObject());
- if (no_push)
- {
- childSetVisible("restrictpush", TRUE);
- childGetRect( "restrictpush", buttonRect );
- r.setOriginAndSize( x, y, buttonRect.getWidth(), buttonRect.getHeight());
- childSetRect( "restrictpush", r );
- x += buttonRect.getWidth();
- }
- else
- {
- childSetVisible("restrictpush", FALSE);
- }
-
- BOOL have_voice = parcel && parcel->getParcelFlagAllowVoice();
- if (have_voice)
- {
- childSetVisible("status_no_voice", FALSE);
- }
- else
- {
- childSetVisible("status_no_voice", TRUE);
- childGetRect( "status_no_voice", buttonRect );
- r.setOriginAndSize( x, y, buttonRect.getWidth(), buttonRect.getHeight());
- childSetRect( "status_no_voice", r );
- x += buttonRect.getWidth();
- }
-
- BOOL canBuyLand = parcel
- && !parcel->isPublic()
- && LLViewerParcelMgr::getInstance()->canAgentBuyParcel(parcel, false);
- childSetVisible("buyland", canBuyLand);
- if (canBuyLand)
- {
- //HACK: layout tweak until this is all xml
- x += 9;
- childGetRect( "buyland", buttonRect );
- r.setOriginAndSize( x, y, buttonRect.getWidth(), buttonRect.getHeight());
- childSetRect( "buyland", r );
- x += buttonRect.getWidth();
- }
-
- std::string location_name;
- if (region)
- {
- const LLVector3& agent_pos_region = gAgent.getPositionAgent();
- S32 pos_x = lltrunc( agent_pos_region.mV[VX] );
- S32 pos_y = lltrunc( agent_pos_region.mV[VY] );
- S32 pos_z = lltrunc( agent_pos_region.mV[VZ] );
-
- // Round the numbers based on the velocity
- LLVector3 agent_velocity = gAgent.getVelocity();
- F32 velocity_mag_sq = agent_velocity.magVecSquared();
-
- const F32 FLY_CUTOFF = 6.f; // meters/sec
- const F32 FLY_CUTOFF_SQ = FLY_CUTOFF * FLY_CUTOFF;
- const F32 WALK_CUTOFF = 1.5f; // meters/sec
- const F32 WALK_CUTOFF_SQ = WALK_CUTOFF * WALK_CUTOFF;
-
- if (velocity_mag_sq > FLY_CUTOFF_SQ)
- {
- pos_x -= pos_x % 4;
- pos_y -= pos_y % 4;
- }
- else if (velocity_mag_sq > WALK_CUTOFF_SQ)
- {
- pos_x -= pos_x % 2;
- pos_y -= pos_y % 2;
- }
-
- mRegionDetails.mTime = mTextTime->getText();
- mRegionDetails.mBalance = mBalance;
- mRegionDetails.mAccessString = region->getSimAccessString();
- mRegionDetails.mPing = region->getNetDetailsForLCD();
- if (parcel)
- {
- location_name = region->getName()
- + llformat(" %d, %d, %d (%s) - %s",
- pos_x, pos_y, pos_z,
- region->getSimAccessString().c_str(),
- parcel->getName().c_str());
-
- // keep these around for the LCD to use
- mRegionDetails.mRegionName = region->getName();
- mRegionDetails.mParcelName = parcel->getName();
- mRegionDetails.mX = pos_x;
- mRegionDetails.mY = pos_y;
- mRegionDetails.mZ = pos_z;
-
- mRegionDetails.mArea = parcel->getArea();
- mRegionDetails.mForSale = parcel->getForSale();
- mRegionDetails.mTraffic = LLViewerParcelMgr::getInstance()->getDwelling();
-
- if (parcel->isPublic())
- {
- mRegionDetails.mOwner = "Public";
- }
- else
- {
- if (parcel->getIsGroupOwned())
- {
- if(!parcel->getGroupID().isNull())
- {
- gCacheName->getGroupName(parcel->getGroupID(), mRegionDetails.mOwner);
- }
- else
- {
- mRegionDetails.mOwner = "Group Owned";
- }
- }
- else
- {
- // Figure out the owner's name
- gCacheName->getFullName(parcel->getOwnerID(), mRegionDetails.mOwner);
- }
- }
- }
- else
- {
- location_name = region->getName()
- + llformat(" %d, %d, %d (%s)",
- pos_x, pos_y, pos_z,
- region->getSimAccessString().c_str());
- // keep these around for the LCD to use
- mRegionDetails.mRegionName = region->getName();
- mRegionDetails.mParcelName = "Unknown";
-
- mRegionDetails.mX = pos_x;
- mRegionDetails.mY = pos_y;
- mRegionDetails.mZ = pos_z;
- mRegionDetails.mArea = 0;
- mRegionDetails.mForSale = FALSE;
- mRegionDetails.mOwner = "Unknown";
- mRegionDetails.mTraffic = 0.0f;
- }
- }
- else
- {
- // no region
- location_name = "(Unknown)";
- // keep these around for the LCD to use
- mRegionDetails.mRegionName = "Unknown";
- mRegionDetails.mParcelName = "Unknown";
- mRegionDetails.mAccessString = "Unknown";
- mRegionDetails.mX = 0;
- mRegionDetails.mY = 0;
- mRegionDetails.mZ = 0;
- mRegionDetails.mArea = 0;
- mRegionDetails.mForSale = FALSE;
- mRegionDetails.mOwner = "Unknown";
- mRegionDetails.mTraffic = 0.0f;
- }
-
- mTextParcelName->setText(location_name);
-
-
-
- // x = right edge
- // loop through: stat graphs, search btn, search text editor, money, buy money, clock
- // adjust rect
- // finally adjust parcel name rect
-
- S32 new_right = getRect().getWidth();
- if (search_visible)
- {
- childGetRect("search_btn", r);
- //r.translate( new_right - r.mRight, 0);
- //childSetRect("search_btn", r);
- new_right -= r.getWidth();
-
- childGetRect("search_editor", r);
- //r.translate( new_right - r.mRight, 0);
- //childSetRect("search_editor", r);
- new_right -= r.getWidth() + 6;
- }
- else
- {
- childGetRect("stat_btn", r);
- r.translate( new_right - r.mRight, 0);
- childSetRect("stat_btn", r);
- new_right -= r.getWidth() + 6;
- }
-
- // Set rects of money, buy money, time
- childGetRect("BalanceText", r);
- r.translate( new_right - r.mRight, 0);
- childSetRect("BalanceText", r);
- new_right -= r.getWidth() - 18;
-
- childGetRect("buycurrency", r);
- r.translate( new_right - r.mRight, 0);
- childSetRect("buycurrency", r);
- new_right -= r.getWidth() + 6;
-
- childGetRect("TimeText", r);
- // mTextTime->getTextPixelWidth();
- r.translate( new_right - r.mRight, 0);
- childSetRect("TimeText", r);
- // new_right -= r.getWidth() + MENU_PARCEL_SPACING;
-
-
- // Adjust region name and parcel name
- x += 8;
-
- const S32 PARCEL_RIGHT = llmin(mTextTime->getRect().mLeft, mTextParcelName->getTextPixelWidth() + x + 5);
- r.set(x+4, getRect().getHeight() - 2, PARCEL_RIGHT, 0);
- mTextParcelName->setRect(r);
-
- // Set search bar visibility
-
- if (gAgent.getCameraMode() != CAMERA_MODE_MOUSELOOK)
- {
- // don't monkey with search visibility in mouselook - it will be set
- // with setVisibleForMouselook() below
- childSetVisible("search_editor", search_visible);
- childSetVisible("search_btn", search_visible);
- childSetVisible("menubar_search_bevel_bg", search_visible);
- }
-
- mSGBandwidth->setVisible(! search_visible);
- mSGPacketLoss->setVisible(! search_visible);
- childSetEnabled("stat_btn", ! search_visible);
+ mSGBandwidth->setVisible(net_stats_visible);
+ mSGPacketLoss->setVisible(net_stats_visible);
+ childSetEnabled("stat_btn", net_stats_visible);
}
void LLStatusBar::setVisibleForMouselook(bool visible)
{
- mTextBalance->setVisible(visible);
mTextTime->setVisible(visible);
- childSetVisible("buycurrency", visible);
- childSetVisible("search_editor", visible);
- childSetVisible("search_btn", visible);
- childSetVisible("menubar_search_bevel_bg", visible);
+ mBtnBuyCurrency->setVisible(visible);
mSGBandwidth->setVisible(visible);
mSGPacketLoss->setVisible(visible);
setBackgroundVisible(visible);
@@ -669,9 +369,19 @@ void LLStatusBar::creditBalance(S32 credit)
void LLStatusBar::setBalance(S32 balance)
{
std::string money_str = LLResMgr::getInstance()->getMonetaryString( balance );
- std::string balance_str = "L$";
- balance_str += money_str;
- mTextBalance->setText( balance_str );
+
+ LLStringUtil::format_map_t string_args;
+ string_args["[AMT]"] = llformat("%s", money_str.c_str());
+ std::string labe_str = getString("buycurrencylabel", string_args);
+ mBtnBuyCurrency->setLabel(labe_str);
+
+ // Resize the balance button so that the label fits it, and the button expands to the left.
+ // *TODO: LLButton should have an option where to expand.
+ {
+ S32 saved_right = mBtnBuyCurrency->getRect().mRight;
+ mBtnBuyCurrency->autoResize();
+ mBtnBuyCurrency->translate(saved_right - mBtnBuyCurrency->getRect().mRight, 0);
+ }
if (mBalance && (fabs((F32)(mBalance - balance)) > gSavedSettings.getF32("UISndMoneyChangeThreshold")))
{
@@ -775,18 +485,6 @@ S32 LLStatusBar::getSquareMetersLeft() const
return mSquareMetersCredit - mSquareMetersCommitted;
}
-static void onClickParcelInfo(void* data)
-{
- LLViewerParcelMgr::getInstance()->selectParcelAt(gAgent.getPositionGlobal());
-
- LLFloaterLand::showInstance();
-}
-
-static void onClickBalance(void* data)
-{
- onClickBuyCurrency(data);
-}
-
static void onClickBuyCurrency(void* data)
{
LLFloaterBuyCurrency::buyCurrency();
@@ -802,49 +500,6 @@ static void onClickScriptDebug(void*)
LLFloaterScriptDebug::show(LLUUID::null);
}
-static void onClickFly(void* )
-{
- LLNotifications::instance().add("NoFly");
-}
-
-static void onClickPush(void* )
-{
- LLNotifications::instance().add("PushRestricted");
-}
-
-static void onClickVoice(void* )
-{
- LLNotifications::instance().add("NoVoice");
-}
-
-static void onClickBuild(void*)
-{
- LLNotifications::instance().add("NoBuild");
-}
-
-static void onClickScripts(void*)
-{
- LLViewerRegion* region = gAgent.getRegion();
- if(region && region->getRegionFlags() & REGION_FLAGS_ESTATE_SKIP_SCRIPTS)
- {
- LLNotifications::instance().add("ScriptsStopped");
- }
- else if(region && region->getRegionFlags() & REGION_FLAGS_SKIP_SCRIPTS)
- {
- LLNotifications::instance().add("ScriptsNotRunning");
- }
- else
- {
- LLNotifications::instance().add("NoOutsideScripts");
- }
-}
-
-static void onClickBuyLand(void*)
-{
- LLViewerParcelMgr::getInstance()->selectParcelAt(gAgent.getPositionGlobal());
- LLViewerParcelMgr::getInstance()->startBuyLand();
-}
-
// sets the static variables necessary for the date
void LLStatusBar::setupDate()
{
@@ -908,25 +563,52 @@ void LLStatusBar::setupDate()
}
}
-// static
-void LLStatusBar::onCommitSearch(LLUICtrl*, void* data)
+bool LLStatusBar::onHideNavbarContextMenuItemEnabled(const LLSD& userdata)
{
- // committing is the same as clicking "search"
- onClickSearch(data);
+ std::string item = userdata.asString();
+
+ if (item == "show_navbar_navigation_panel")
+ {
+ return gSavedSettings.getBOOL("ShowNavbarNavigationPanel");
+ }
+ else if (item == "show_navbar_favorites_panel")
+ {
+ return gSavedSettings.getBOOL("ShowNavbarFavoritesPanel");
+ }
+
+ return FALSE;
}
-// static
-void LLStatusBar::onClickSearch(void* data)
+void LLStatusBar::onHideNavbarContextMenuItemClicked(const LLSD& userdata)
+{
+ std::string item = userdata.asString();
+
+ if (item == "show_navbar_navigation_panel")
+ {
+ BOOL state = !gSavedSettings.getBOOL("ShowNavbarNavigationPanel");
+
+ LLNavigationBar::getInstance()->showNavigationPanel(state);
+ gSavedSettings.setBOOL("ShowNavbarNavigationPanel", state);
+ }
+ else if (item == "show_navbar_favorites_panel")
+ {
+ BOOL state = !gSavedSettings.getBOOL("ShowNavbarFavoritesPanel");
+
+ LLNavigationBar::getInstance()->showFavoritesPanel(state);
+ gSavedSettings.setBOOL("ShowNavbarFavoritesPanel", state);
+ }
+}
+
+
+void LLStatusBar::onMainMenuRightClicked(LLUICtrl* ctrl, S32 x, S32 y, MASK mask)
{
- LLStatusBar* self = (LLStatusBar*)data;
- std::string search_text = self->childGetText("search_editor");
- LLFloaterDirectory::showFindAll(search_text);
+ handleRightMouseDown(x, y, mask);
}
// static
void LLStatusBar::onClickStatGraph(void* data)
{
- LLFloaterLagMeter::showInstance();
+ LLFloaterReg::showInstance("lagmeter");
}
BOOL can_afford_transaction(S32 cost)
@@ -942,7 +624,7 @@ class LLBalanceHandler : public LLCommandHandler
public:
// Requires "trusted" browser/URL source
LLBalanceHandler() : LLCommandHandler("balance", true) { }
- bool handle(const LLSD& tokens, const LLSD& query_map, LLWebBrowserCtrl* web)
+ bool handle(const LLSD& tokens, const LLSD& query_map, LLMediaCtrl* web)
{
if (tokens.size() == 1
&& tokens[0].asString() == "request")
diff --git a/indra/newview/llstatusbar.h b/indra/newview/llstatusbar.h
index c5b4be035a..b77db2c525 100644
--- a/indra/newview/llstatusbar.h
+++ b/indra/newview/llstatusbar.h
@@ -34,6 +34,7 @@
#define LL_LLSTATUSBAR_H
#include "llpanel.h"
+#include <llmenugl.h>
// "Constants" loaded from settings.xml at start time
extern S32 STATUS_BAR_HEIGHT;
@@ -48,49 +49,18 @@ class LLUUID;
class LLFrameTimer;
class LLStatGraph;
-// used by LCD screen
-class LLRegionDetails
-{
-public:
- LLRegionDetails() :
- mRegionName("Unknown"),
- mParcelName("Unknown"),
- mAccessString("Unknown"),
- mX(0),
- mY(0),
- mZ(0),
- mArea (0),
- mForSale(FALSE),
- mOwner("Unknown"),
- mTraffic(0),
- mBalance(0),
- mPing(0)
- {
- }
- std::string mRegionName;
- std::string mParcelName;
- std::string mAccessString;
- S32 mX;
- S32 mY;
- S32 mZ;
- S32 mArea;
- BOOL mForSale;
- std::string mOwner;
- F32 mTraffic;
- S32 mBalance;
- std::string mTime;
- U32 mPing;
-};
-
class LLStatusBar
: public LLPanel
{
public:
- LLStatusBar(const std::string& name, const LLRect& rect );
+ LLStatusBar(const LLRect& rect );
/*virtual*/ ~LLStatusBar();
/*virtual*/ void draw();
+ /*virtual*/ BOOL handleRightMouseDown(S32 x, S32 y, MASK mask);
+ /*virtual*/ BOOL postBuild();
+
// MANIPULATORS
void setBalance(S32 balance);
void debitBalance(S32 debit);
@@ -116,23 +86,23 @@ public:
S32 getSquareMetersCredit() const;
S32 getSquareMetersCommitted() const;
S32 getSquareMetersLeft() const;
- LLRegionDetails mRegionDetails;
private:
// simple method to setup the part that holds the date
void setupDate();
+ bool onHideNavbarContextMenuItemEnabled(const LLSD& userdata);
+ void onHideNavbarContextMenuItemClicked(const LLSD& userdata);
+
+ void onMainMenuRightClicked(LLUICtrl* ctrl, S32 x, S32 y, MASK mask);
static void onCommitSearch(LLUICtrl*, void* data);
static void onClickSearch(void* data);
static void onClickStatGraph(void* data);
private:
- LLTextBox *mTextBalance;
LLTextBox *mTextHealth;
LLTextBox *mTextTime;
- LLTextBox* mTextParcelName;
-
LLStatGraph *mSGBandwidth;
LLStatGraph *mSGPacketLoss;
@@ -144,6 +114,7 @@ private:
S32 mSquareMetersCommitted;
LLFrameTimer* mBalanceTimer;
LLFrameTimer* mHealthTimer;
+ LLMenuGL* mHideNavbarContextMenu;
static std::vector<std::string> sDays;
static std::vector<std::string> sMonths;
diff --git a/indra/newview/llstylemap.cpp b/indra/newview/llstylemap.cpp
index a34b4b83f3..fc125dcf9c 100644
--- a/indra/newview/llstylemap.cpp
+++ b/indra/newview/llstylemap.cpp
@@ -38,83 +38,53 @@
#include "llviewercontrol.h"
#include "llagent.h"
-LLStyleMap::LLStyleMap()
-{
-}
-
-LLStyleMap::~LLStyleMap()
-{
-}
-
-LLStyleMap &LLStyleMap::instance()
-{
- static LLStyleMap style_map;
- return style_map;
-}
-
-// This is similar to the [] accessor except that if the entry doesn't already exist,
-// then this will create the entry.
-const LLStyleSP &LLStyleMap::lookupAgent(const LLUUID &source)
+const LLStyle::Params &LLStyleMap::lookupAgent(const LLUUID &source)
{
// Find this style in the map or add it if not. This map holds links to residents' profiles.
- if (find(source) == end())
+ if (mMap.find(source) == mMap.end())
{
- LLStyleSP style(new LLStyle);
- style->setVisible(true);
- style->setFontName(LLStringUtil::null);
+ LLStyle::Params style_params;
if (source != LLUUID::null && source != gAgent.getID() )
{
- style->setColor(gSavedSettings.getColor4("HTMLLinkColor"));
- std::string link = llformat("secondlife:///app/agent/%s/about",source.asString().c_str());
- style->setLinkHREF(link);
+ style_params.color.control = "HTMLLinkColor";
+ style_params.link_href = llformat("secondlife:///app/agent/%s/about",source.asString().c_str());
}
else
{
// Make the resident's own name white and don't make the name clickable.
- style->setColor(LLColor4::white);
+ style_params.color = LLColor4::white;
}
- (*this)[source] = style;
+
+ mMap[source] = LLStyle::Params();
}
- return (*this)[source];
+ return mMap[source];
}
// This is similar to lookupAgent for any generic URL encoded style.
-const LLStyleSP &LLStyleMap::lookup(const LLUUID& id, const std::string& link)
+const LLStyle::Params &LLStyleMap::lookup(const LLUUID& id, const std::string& link)
{
// Find this style in the map or add it if not.
- iterator iter = find(id);
- if (iter == end())
+ style_map_t::iterator iter = mMap.find(id);
+ if (iter == mMap.end())
{
- LLStyleSP style(new LLStyle);
- style->setVisible(true);
- style->setFontName(LLStringUtil::null);
+ LLStyle::Params style_params;
+
if (id != LLUUID::null && !link.empty())
{
- style->setColor(gSavedSettings.getColor4("HTMLLinkColor"));
- style->setLinkHREF(link);
+ style_params.color.control = "HTMLLinkColor";
+ style_params.link_href = link;
}
else
- style->setColor(LLColor4::white);
- (*this)[id] = style;
+ {
+ style_params.color = LLColor4::white;
+ }
+ mMap[id] = style_params;
}
else
{
- LLStyleSP style = (*iter).second;
- if ( style->getLinkHREF() != link )
- {
- style->setLinkHREF(link);
- }
+ iter->second.link_href = link;
}
- return (*this)[id];
+ return mMap[id];
}
-void LLStyleMap::update()
-{
- for (style_map_t::iterator iter = begin(); iter != end(); ++iter)
- {
- LLStyleSP &style = iter->second;
- // Update the link color in case it has been changed.
- style->setColor(gSavedSettings.getColor4("HTMLLinkColor"));
- }
-}
diff --git a/indra/newview/llstylemap.h b/indra/newview/llstylemap.h
index 254509ea1d..d29ff1ae28 100644
--- a/indra/newview/llstylemap.h
+++ b/indra/newview/llstylemap.h
@@ -36,24 +36,22 @@
#include "llstyle.h"
#include "lluuid.h"
+#include "llsingleton.h"
// Lightweight class for holding and managing mappings between UUIDs and links.
// Used (for example) to create clickable name links off of IM chat.
-typedef std::map<LLUUID, LLStyleSP> style_map_t;
+typedef std::map<LLUUID, LLStyle::Params> style_map_t;
-class LLStyleMap : public style_map_t
+class LLStyleMap : public LLSingleton<LLStyleMap>
{
public:
- LLStyleMap();
- ~LLStyleMap();
// Just like the [] accessor but it will add the entry in if it doesn't exist.
- const LLStyleSP &lookupAgent(const LLUUID &source);
- const LLStyleSP &lookup(const LLUUID &source, const std::string& link);
- static LLStyleMap &instance();
+ const LLStyle::Params &lookupAgent(const LLUUID &source);
+ const LLStyle::Params &lookup(const LLUUID &source, const std::string& link);
- // Forces refresh of the entries, call when something changes (e.g. link color).
- void update();
+private:
+ style_map_t mMap;
};
#endif // LL_LLSTYLE_MAP_H
diff --git a/indra/newview/llsurface.cpp b/indra/newview/llsurface.cpp
index a27f0e2254..de3d80f044 100644
--- a/indra/newview/llsurface.cpp
+++ b/indra/newview/llsurface.cpp
@@ -36,7 +36,7 @@
#include "llrender.h"
-#include "llviewerimagelist.h"
+#include "llviewertexturelist.h"
#include "llpatchvertexarray.h"
#include "patch_dct.h"
#include "patch_code.h"
@@ -47,7 +47,7 @@
#include "llappviewer.h"
#include "llworld.h"
#include "llviewercontrol.h"
-#include "llviewerimage.h"
+#include "llviewertexture.h"
#include "llsurfacepatch.h"
#include "llvosurfacepatch.h"
#include "llvowater.h"
@@ -68,7 +68,6 @@ LLColor4U MAX_WATER_COLOR(0, 48, 96, 240);
S32 LLSurface::sTextureSize = 256;
S32 LLSurface::sTexelsUpdated = 0;
F32 LLSurface::sTextureUpdateTime = 0.f;
-LLStat LLSurface::sTexelsUpdatedPerSecStat;
// ---------------- LLSurface:: Public Members ---------------
@@ -138,12 +137,10 @@ LLSurface::~LLSurface()
// Don't enable this until we blitz the draw pool for it as well. -- djs
if (mSTexturep)
{
- gImageList.deleteImage(mSTexturep);
mSTexturep = NULL;
}
if (mWaterTexturep)
{
- gImageList.deleteImage(mWaterTexturep);
mWaterTexturep = NULL;
}
}
@@ -215,18 +212,18 @@ void LLSurface::create(const S32 grids_per_edge,
createPatchData();
}
-LLViewerImage* LLSurface::getSTexture()
+LLViewerTexture* LLSurface::getSTexture()
{
- if (mSTexturep.notNull() && !mSTexturep->getHasGLTexture())
+ if (mSTexturep.notNull() && !mSTexturep->hasValidGLTexture())
{
createSTexture();
}
return mSTexturep;
}
-LLViewerImage* LLSurface::getWaterTexture()
+LLViewerTexture* LLSurface::getWaterTexture()
{
- if (mWaterTexturep.notNull() && !mWaterTexturep->getHasGLTexture())
+ if (mWaterTexturep.notNull() && !mWaterTexturep->hasValidGLTexture())
{
createWaterTexture();
}
@@ -250,11 +247,10 @@ void LLSurface::createSTexture()
}
}
- mSTexturep = new LLViewerImage(raw, FALSE);
+ mSTexturep = LLViewerTextureManager::getLocalTexture(raw.get(), FALSE);
mSTexturep->dontDiscard();
- gGL.getTexUnit(0)->bind(mSTexturep.get());
- mSTexturep->setAddressMode(LLTexUnit::TAM_CLAMP);
- gImageList.addImage(mSTexturep);
+ gGL.getTexUnit(0)->bind(mSTexturep);
+ mSTexturep->setAddressMode(LLTexUnit::TAM_CLAMP);
}
}
@@ -275,11 +271,10 @@ void LLSurface::createWaterTexture()
*(default_texture + (i*sTextureSize/2 + j)*4 + 3) = MAX_WATER_COLOR.mV[3];
}
}
- mWaterTexturep = new LLViewerImage(raw, FALSE);
+ mWaterTexturep = LLViewerTextureManager::getLocalTexture(raw.get(), FALSE);
mWaterTexturep->dontDiscard();
- gGL.getTexUnit(0)->bind(mWaterTexturep.get());
+ gGL.getTexUnit(0)->bind(mWaterTexturep);
mWaterTexturep->setAddressMode(LLTexUnit::TAM_CLAMP);
- gImageList.addImage(mWaterTexturep);
}
}
@@ -629,6 +624,7 @@ void LLSurface::updatePatchVisibilities(LLAgent &agent)
BOOL LLSurface::idleUpdate(F32 max_update_time)
{
+ LLMemType mt_ius(LLMemType::MTYPE_IDLE_UPDATE_SURFACE);
if (!gPipeline.hasRenderType(LLPipeline::RENDER_TYPE_TERRAIN))
{
return FALSE;
@@ -1193,7 +1189,7 @@ F32 LLSurface::getWaterHeight() const
BOOL LLSurface::generateWaterTexture(const F32 x, const F32 y,
const F32 width, const F32 height)
{
- if (!getWaterTexture())
+ if (!getWaterTexture() || !mWaterTexturep->hasGLTexture())
{
return FALSE;
}
diff --git a/indra/newview/llsurface.h b/indra/newview/llsurface.h
index 003b2f2505..1f672d2250 100644
--- a/indra/newview/llsurface.h
+++ b/indra/newview/llsurface.h
@@ -46,7 +46,7 @@
#include "llvowater.h"
#include "llpatchvertexarray.h"
-#include "llviewerimage.h"
+#include "llviewertexture.h"
class LLTimer;
class LLUUID;
@@ -133,8 +133,8 @@ public:
void setWaterHeight(F32 height);
F32 getWaterHeight() const;
- LLViewerImage *getSTexture();
- LLViewerImage *getWaterTexture();
+ LLViewerTexture *getSTexture();
+ LLViewerTexture *getWaterTexture();
BOOL hasZData() const { return mHasZData; }
void dirtyAllPatches(); // Use this to dirty all patches when changing terrain parameters
@@ -173,7 +173,6 @@ public:
static F32 sTextureUpdateTime;
static S32 sTexelsUpdated;
- static LLStat sTexelsUpdatedPerSecStat;
protected:
void createSTexture();
@@ -206,8 +205,8 @@ protected:
// The textures should never be directly initialized - use the setter methods!
- LLPointer<LLViewerImage> mSTexturep; // Texture for surface
- LLPointer<LLViewerImage> mWaterTexturep; // Water texture
+ LLPointer<LLViewerTexture> mSTexturep; // Texture for surface
+ LLPointer<LLViewerTexture> mWaterTexturep; // Water texture
LLPointer<LLVOWater> mWaterObjp;
diff --git a/indra/newview/llsurfacepatch.h b/indra/newview/llsurfacepatch.h
index 7e84f7f6c5..4cac977305 100644
--- a/indra/newview/llsurfacepatch.h
+++ b/indra/newview/llsurfacepatch.h
@@ -35,7 +35,7 @@
#include "v3math.h"
#include "v3dmath.h"
-#include "llmemory.h"
+#include "llpointer.h"
class LLSurface;
class LLVOSurfacePatch;
diff --git a/indra/newview/llsyswellitem.cpp b/indra/newview/llsyswellitem.cpp
new file mode 100644
index 0000000000..7d9ebc7208
--- /dev/null
+++ b/indra/newview/llsyswellitem.cpp
@@ -0,0 +1,109 @@
+/**
+ * @file llsyswellitem.cpp
+ * @brief // TODO
+ *
+ * $LicenseInfo:firstyear=2000&license=viewergpl$
+ *
+ * Copyright (c) 2000-2009, Linden Research, Inc.
+ *
+ * Second Life Viewer Source Code
+ * The source code in this file ("Source Code") is provided by Linden Lab
+ * to you under the terms of the GNU General Public License, version 2.0
+ * ("GPL"), unless you have obtained a separate licensing agreement
+ * ("Other License"), formally executed by you and Linden Lab. Terms of
+ * the GPL can be found in doc/GPL-license.txt in this distribution, or
+ * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
+ *
+ * There are special exceptions to the terms and conditions of the GPL as
+ * it is applied to this Source Code. View the full text of the exception
+ * in the file doc/FLOSS-exception.txt in this software distribution, or
+ * online at
+ * http://secondlifegrid.net/programs/open_source/licensing/flossexception
+ *
+ * By copying, modifying or distributing this software, you acknowledge
+ * that you have read and understood your obligations described above,
+ * and agree to abide by those obligations.
+ *
+ * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+ * COMPLETENESS OR PERFORMANCE.
+ * $/LicenseInfo$
+ */
+
+
+#include "llviewerprecompiledheaders.h" // must be first include
+
+#include "llsyswellitem.h"
+
+#include "llwindow.h"
+#include "v4color.h"
+#include "lluicolortable.h"
+
+//---------------------------------------------------------------------------------
+LLSysWellItem::LLSysWellItem(const Params& p) : LLScrollingPanel(p),
+ mTitle(NULL),
+ mCloseBtn(NULL),
+ mIcon(NULL)
+{
+ LLUICtrlFactory::getInstance()->buildPanel(this, "panel_sys_well_item.xml");
+
+ mTitle = getChild<LLTextBox>("title");
+ mCloseBtn = getChild<LLButton>("close_btn");
+ mIcon = getChild<LLIconCtrl>("icon");
+
+ mTitle->setValue(p.title);
+ mCloseBtn->setClickedCallback(boost::bind(&LLSysWellItem::onClickCloseBtn,this));
+
+ mID = p.notification_id;
+}
+
+//---------------------------------------------------------------------------------
+LLSysWellItem::~LLSysWellItem()
+{
+}
+
+//---------------------------------------------------------------------------------
+void LLSysWellItem::setTitle( std::string title )
+{
+ mTitle->setValue(title);
+}
+
+//---------------------------------------------------------------------------------
+void LLSysWellItem::onClickCloseBtn()
+{
+ mOnItemClose(this);
+}
+
+//---------------------------------------------------------------------------------
+void LLSysWellItem::updatePanel(BOOL allow_modify)
+{
+ S32 parent_width = getParent()->getRect().getWidth();
+ S32 panel_height = getRect().getHeight();
+
+ reshape(parent_width, panel_height, TRUE);
+}
+
+//---------------------------------------------------------------------------------
+BOOL LLSysWellItem::handleMouseDown(S32 x, S32 y, MASK mask)
+{
+ if(!mCloseBtn->getRect().pointInRect(x, y))
+ mOnItemClick(this);
+
+ return LLPanel::handleMouseDown(x, y, mask);
+}
+
+//---------------------------------------------------------------------------------
+void LLSysWellItem::onMouseEnter(S32 x, S32 y, MASK mask)
+{
+ setTransparentColor(LLUIColorTable::instance().getColor( "SysWellItemSelected" ));
+}
+
+//---------------------------------------------------------------------------------
+void LLSysWellItem::onMouseLeave(S32 x, S32 y, MASK mask)
+{
+ setTransparentColor(LLUIColorTable::instance().getColor( "SysWellItemUnselected" ));
+}
+
+//---------------------------------------------------------------------------------
+
+
diff --git a/indra/newview/llsyswellitem.h b/indra/newview/llsyswellitem.h
new file mode 100644
index 0000000000..b0761f2790
--- /dev/null
+++ b/indra/newview/llsyswellitem.h
@@ -0,0 +1,90 @@
+/**
+ * @file llsyswellitem.h
+ * @brief // TODO
+ *
+ * $LicenseInfo:firstyear=2003&license=viewergpl$
+ *
+ * Copyright (c) 2003-2009, Linden Research, Inc.
+ *
+ * Second Life Viewer Source Code
+ * The source code in this file ("Source Code") is provided by Linden Lab
+ * to you under the terms of the GNU General Public License, version 2.0
+ * ("GPL"), unless you have obtained a separate licensing agreement
+ * ("Other License"), formally executed by you and Linden Lab. Terms of
+ * the GPL can be found in doc/GPL-license.txt in this distribution, or
+ * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
+ *
+ * There are special exceptions to the terms and conditions of the GPL as
+ * it is applied to this Source Code. View the full text of the exception
+ * in the file doc/FLOSS-exception.txt in this software distribution, or
+ * online at
+ * http://secondlifegrid.net/programs/open_source/licensing/flossexception
+ *
+ * By copying, modifying or distributing this software, you acknowledge
+ * that you have read and understood your obligations described above,
+ * and agree to abide by those obligations.
+ *
+ * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+ * COMPLETENESS OR PERFORMANCE.
+ * $/LicenseInfo$
+ */
+
+#ifndef LL_LLSYSWELLITEM_H
+#define LL_LLSYSWELLITEM_H
+
+#include "llscrollingpanellist.h"
+#include "lltextbox.h"
+#include "llbutton.h"
+#include "lliconctrl.h"
+
+#include <string>
+
+class LLSysWellItem : public LLScrollingPanel
+{
+public:
+ struct Params : public LLInitParam::Block<Params, LLPanel::Params>
+ {
+ LLUUID notification_id;
+ std::string title;
+ Params() {};
+ };
+
+
+ LLSysWellItem(const Params& p);
+ virtual ~LLSysWellItem();
+
+ void updatePanel(BOOL allow_modify);
+
+ // title
+ void setTitle( std::string title );
+
+ // get item's ID
+ LLUUID getID() { return mID; }
+
+ // handlers
+ virtual BOOL handleMouseDown(S32 x, S32 y, MASK mask);
+ virtual void onMouseEnter(S32 x, S32 y, MASK mask);
+ virtual void onMouseLeave(S32 x, S32 y, MASK mask);
+
+ //callbacks
+ typedef boost::function<void (LLSysWellItem* item)> syswell_item_callback_t;
+ typedef boost::signals2::signal<void (LLSysWellItem* item)> syswell_item_signal_t;
+ syswell_item_signal_t mOnItemClose;
+ syswell_item_signal_t mOnItemClick;
+ boost::signals2::connection setOnItemCloseCallback(syswell_item_callback_t cb) { return mOnItemClose.connect(cb); }
+ boost::signals2::connection setOnItemClickCallback(syswell_item_callback_t cb) { return mOnItemClick.connect(cb); }
+
+private:
+
+ void onClickCloseBtn();
+
+ LLTextBox* mTitle;
+ LLButton* mCloseBtn;
+ LLIconCtrl* mIcon;
+ LLUUID mID;
+};
+
+#endif // LL_LLSYSWELLITEM_H
+
+
diff --git a/indra/newview/llsyswellwindow.cpp b/indra/newview/llsyswellwindow.cpp
new file mode 100644
index 0000000000..2bbb5a2767
--- /dev/null
+++ b/indra/newview/llsyswellwindow.cpp
@@ -0,0 +1,213 @@
+/**
+ * @file llsyswellwindow.cpp
+ * @brief // TODO
+ * $LicenseInfo:firstyear=2000&license=viewergpl$
+ *
+ * Copyright (c) 2000-2009, Linden Research, Inc.
+ *
+ * Second Life Viewer Source Code
+ * The source code in this file ("Source Code") is provided by Linden Lab
+ * to you under the terms of the GNU General Public License, version 2.0
+ * ("GPL"), unless you have obtained a separate licensing agreement
+ * ("Other License"), formally executed by you and Linden Lab. Terms of
+ * the GPL can be found in doc/GPL-license.txt in this distribution, or
+ * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
+ *
+ * There are special exceptions to the terms and conditions of the GPL as
+ * it is applied to this Source Code. View the full text of the exception
+ * in the file doc/FLOSS-exception.txt in this software distribution, or
+ * online at
+ * http://secondlifegrid.net/programs/open_source/licensing/flossexception
+ *
+ * By copying, modifying or distributing this software, you acknowledge
+ * that you have read and understood your obligations described above,
+ * and agree to abide by those obligations.
+ *
+ * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+ * COMPLETENESS OR PERFORMANCE.
+ * $/LicenseInfo$
+ */
+
+
+#include "llviewerprecompiledheaders.h" // must be first include
+
+#include "llsyswellwindow.h"
+
+#include "llbottomtray.h"
+#include "llviewercontrol.h"
+#include "llviewerwindow.h"
+
+//---------------------------------------------------------------------------------
+LLSysWellWindow::LLSysWellWindow(const LLSD& key) : LLFloater(LLSD()),
+ mChannel(NULL),
+ mScrollContainer(NULL),
+ mNotificationList(NULL)
+{
+}
+
+//---------------------------------------------------------------------------------
+BOOL LLSysWellWindow::postBuild()
+{
+ mScrollContainer = getChild<LLScrollContainer>("notification_list_container");
+ mNotificationList = getChild<LLScrollingPanelList>("notification_list");
+
+ gViewerWindow->setOnBottomTrayWidthChanged(boost::bind(&LLSysWellWindow::adjustWindowPosition, this)); // *TODO: won't be necessary after docking is realized
+ mScrollContainer->setBorderVisible(FALSE);
+
+ mDockTongue = LLUI::getUIImage("windows/Flyout_Pointer.png");
+
+ return TRUE;
+}
+
+//---------------------------------------------------------------------------------
+LLSysWellWindow::~LLSysWellWindow()
+{
+}
+
+//---------------------------------------------------------------------------------
+void LLSysWellWindow::addItem(LLSysWellItem::Params p)
+{
+ // do not add clones
+ if( findItemByID(p.notification_id) >= 0 )
+ return;
+
+ LLSysWellItem* new_item = new LLSysWellItem(p);
+ mNotificationList->addPanel(dynamic_cast<LLScrollingPanel*>(new_item));
+ reshapeWindow();
+ adjustWindowPosition(); // *TODO: won't be necessary after docking is realized
+
+ new_item->setOnItemCloseCallback(boost::bind(&LLSysWellWindow::onItemClose, this, _1));
+ new_item->setOnItemClickCallback(boost::bind(&LLSysWellWindow::onItemClick, this, _1));
+}
+
+//---------------------------------------------------------------------------------
+void LLSysWellWindow::clear()
+{
+ // *TODO: fill later
+}
+
+//---------------------------------------------------------------------------------
+S32 LLSysWellWindow::findItemByID(const LLUUID& id)
+{
+ const LLScrollingPanelList::panel_list_t list = mNotificationList->getPanelList();
+ if(list.size() == 0)
+ return -1;
+
+ LLScrollingPanelList::panel_list_t::const_iterator it;
+ S32 index = 0;
+ for(it = list.begin(); it != list.end(); ++it, ++index)
+ {
+ if( dynamic_cast<LLSysWellItem*>(*it)->getID() == id )
+ break;
+ }
+
+ if(it == list.end())
+ return -1;
+ else
+ return index;
+
+}
+
+//---------------------------------------------------------------------------------
+void LLSysWellWindow::removeItemByID(const LLUUID& id)
+{
+ S32 index = findItemByID(id);
+
+ if(index >= 0)
+ mNotificationList->removePanel(index);
+ else
+ return;
+
+ reshapeWindow();
+ adjustWindowPosition(); // *TODO: won't be necessary after docking is realized
+ // hide chiclet window if there are no items left
+ S32 items_left = mNotificationList->getPanelList().size();
+ if(items_left == 0)
+ setVisible(FALSE);
+}
+
+//---------------------------------------------------------------------------------
+void LLSysWellWindow::onItemClick(LLSysWellItem* item)
+{
+ LLUUID id = item->getID();
+ if(mChannel)
+ mChannel->loadStoredToastByIDToChannel(id);
+}
+
+//---------------------------------------------------------------------------------
+void LLSysWellWindow::onItemClose(LLSysWellItem* item)
+{
+ LLUUID id = item->getID();
+ removeItemByID(id);
+ if(mChannel)
+ mChannel->killToastByNotificationID(id);
+}
+
+//---------------------------------------------------------------------------------
+void LLSysWellWindow::toggleWindow()
+{
+ setVisible(!getVisible());
+}
+
+//---------------------------------------------------------------------------------
+void LLSysWellWindow::setVisible(BOOL visible)
+{
+ // on Show adjust position of SysWell chiclet's window
+ if(visible)
+ {
+ if(mChannel)
+ mChannel->removeAndStoreAllVisibleToasts();
+
+ adjustWindowPosition(); // *TODO: won't be necessary after docking is realized
+ }
+
+ if(mChannel)
+ mChannel->setShowToasts(!visible);
+
+ LLFloater::setVisible(visible);
+}
+
+//---------------------------------------------------------------------------------
+void LLSysWellWindow::adjustWindowPosition() // *TODO: won't be necessary after docking is realized
+{
+ const S32 WINDOW_MARGIN = 5;
+
+ LLRect btm_rect = LLBottomTray::getInstance()->getRect();
+ LLRect this_rect = getRect();
+ setOrigin(btm_rect.mRight - this_rect.getWidth() - WINDOW_MARGIN, WINDOW_MARGIN);
+}
+//---------------------------------------------------------------------------------
+void LLSysWellWindow::reshapeWindow()
+{
+ // Get size for scrollbar and floater's header
+ const LLUICachedControl<S32> SCROLLBAR_SIZE("UIScrollbarSize", 0);
+ const LLUICachedControl<S32> HEADER_SIZE("UIFloaterHeaderSize", 0);
+
+ // Get item list
+ const LLScrollingPanelList::panel_list_t list = mNotificationList->getPanelList();
+
+ // Get height for a scrolling panel list
+ S32 list_height = mNotificationList->getRect().getHeight();
+
+ // Check that the floater doesn't exceed its parent view limits after reshape
+ S32 new_height = list_height + LLScrollingPanelList::GAP_BETWEEN_PANELS + HEADER_SIZE;
+
+ if(new_height > MAX_WINDOW_HEIGHT)
+ {
+ reshape(MIN_WINDOW_WIDTH, MAX_WINDOW_HEIGHT, FALSE);
+ mNotificationList->reshape(MIN_PANELLIST_WIDTH - SCROLLBAR_SIZE, list_height, TRUE);
+ }
+ else
+ {
+ reshape(MIN_WINDOW_WIDTH, new_height, FALSE);
+ mNotificationList->reshape(MIN_PANELLIST_WIDTH, list_height, TRUE);
+ }
+
+ mNotificationList->updatePanels(TRUE);
+}
+
+//---------------------------------------------------------------------------------
+
+
+
diff --git a/indra/newview/llsyswellwindow.h b/indra/newview/llsyswellwindow.h
new file mode 100644
index 0000000000..7a107af0d1
--- /dev/null
+++ b/indra/newview/llsyswellwindow.h
@@ -0,0 +1,92 @@
+/**
+ * @file llsyswellwindow.h
+ * @brief // TODO
+ *
+ * $LicenseInfo:firstyear=2003&license=viewergpl$
+ *
+ * Copyright (c) 2003-2009, Linden Research, Inc.
+ *
+ * Second Life Viewer Source Code
+ * The source code in this file ("Source Code") is provided by Linden Lab
+ * to you under the terms of the GNU General Public License, version 2.0
+ * ("GPL"), unless you have obtained a separate licensing agreement
+ * ("Other License"), formally executed by you and Linden Lab. Terms of
+ * the GPL can be found in doc/GPL-license.txt in this distribution, or
+ * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
+ *
+ * There are special exceptions to the terms and conditions of the GPL as
+ * it is applied to this Source Code. View the full text of the exception
+ * in the file doc/FLOSS-exception.txt in this software distribution, or
+ * online at
+ * http://secondlifegrid.net/programs/open_source/licensing/flossexception
+ *
+ * By copying, modifying or distributing this software, you acknowledge
+ * that you have read and understood your obligations described above,
+ * and agree to abide by those obligations.
+ *
+ * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+ * COMPLETENESS OR PERFORMANCE.
+ * $/LicenseInfo$
+ */
+
+#ifndef LL_LLSYSWELLWINDOW_H
+#define LL_LLSYSWELLWINDOW_H
+
+#include "llsyswellitem.h"
+
+#include "llfloater.h"
+#include "llbutton.h"
+#include "llscreenchannel.h"
+#include "llscrollcontainer.h"
+
+#include "boost/shared_ptr.hpp"
+
+
+
+class LLSysWellWindow : public LLFloater
+{
+public:
+ LLSysWellWindow(const LLSD& key);
+ ~LLSysWellWindow();
+ BOOL postBuild();
+
+ // change attributes
+ void setChannel(LLNotificationsUI::LLScreenChannel* channel) {mChannel = channel;}
+
+ // Operating with items
+ void addItem(LLSysWellItem::Params p);
+ void clear( void );
+ void removeItemByID(const LLUUID& id);
+ S32 findItemByID(const LLUUID& id);
+
+ // Operating with outfit
+ virtual void setVisible(BOOL visible);
+ void adjustWindowPosition();
+ void toggleWindow();
+
+ // Handlers
+ void onItemClick(LLSysWellItem* item);
+ void onItemClose(LLSysWellItem* item);
+
+ // size constants for the window and for its elements
+ static const S32 MAX_WINDOW_HEIGHT = 200;
+ static const S32 MIN_WINDOW_WIDTH = 320;
+ static const S32 MIN_PANELLIST_WIDTH = 318;
+
+private:
+
+ void reshapeWindow();
+
+ // pointer to a corresponding channel's instance
+ LLNotificationsUI::LLScreenChannel* mChannel;
+
+ LLUIImagePtr mDockTongue;
+ LLScrollContainer* mScrollContainer;
+ LLScrollingPanelList* mNotificationList;
+};
+
+#endif // LL_LLSYSWELLWINDOW_H
+
+
+
diff --git a/indra/newview/llteleporthistory.cpp b/indra/newview/llteleporthistory.cpp
new file mode 100644
index 0000000000..bc886d5743
--- /dev/null
+++ b/indra/newview/llteleporthistory.cpp
@@ -0,0 +1,199 @@
+/**
+ * @file llteleporthistory.cpp
+ * @brief Teleport history
+ *
+ * $LicenseInfo:firstyear=2009&license=viewergpl$
+ *
+ * Copyright (c) 2009, Linden Research, Inc.
+ *
+ * Second Life Viewer Source Code
+ * The source code in this file ("Source Code") is provided by Linden Lab
+ * to you under the terms of the GNU General Public License, version 2.0
+ * ("GPL"), unless you have obtained a separate licensing agreement
+ * ("Other License"), formally executed by you and Linden Lab. Terms of
+ * the GPL can be found in doc/GPL-license.txt in this distribution, or
+ * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
+ *
+ * There are special exceptions to the terms and conditions of the GPL as
+ * it is applied to this Source Code. View the full text of the exception
+ * in the file doc/FLOSS-exception.txt in this software distribution, or
+ * online at
+ * http://secondlifegrid.net/programs/open_source/licensing/flossexception
+ *
+ * By copying, modifying or distributing this software, you acknowledge
+ * that you have read and understood your obligations described above,
+ * and agree to abide by those obligations.
+ *
+ * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+ * COMPLETENESS OR PERFORMANCE.
+ * $/LicenseInfo$
+ */
+
+#include "llviewerprecompiledheaders.h"
+
+#include "llteleporthistory.h"
+
+#include "llparcel.h"
+#include "llsdserialize.h"
+
+#include "llagent.h"
+#include "llslurl.h"
+#include "llurlsimstring.h"
+#include "llviewercontrol.h" // for gSavedSettings
+#include "llviewerparcelmgr.h"
+#include "llviewerregion.h"
+#include "llworldmap.h"
+#include "llagentui.h"
+
+//////////////////////////////////////////////////////////////////////////////
+// LLTeleportHistoryItem
+//////////////////////////////////////////////////////////////////////////////
+
+const std::string& LLTeleportHistoryItem::getTitle() const
+{
+ return gSavedSettings.getBOOL("ShowCoordinatesOption") ? mFullTitle : mTitle;
+}
+
+//////////////////////////////////////////////////////////////////////////////
+// LLTeleportHistory
+//////////////////////////////////////////////////////////////////////////////
+
+LLTeleportHistory::LLTeleportHistory():
+ mCurrentItem(-1),
+ mRequestedItem(-1),
+ mGotInitialUpdate(false)
+{
+ mTeleportFinishedConn = LLViewerParcelMgr::getInstance()->
+ setTeleportFinishedCallback(boost::bind(&LLTeleportHistory::updateCurrentLocation, this, _1));
+ mTeleportFailedConn = LLViewerParcelMgr::getInstance()->
+ setTeleportFailedCallback(boost::bind(&LLTeleportHistory::onTeleportFailed, this));
+}
+
+LLTeleportHistory::~LLTeleportHistory()
+{
+ mTeleportFinishedConn.disconnect();
+ mTeleportFailedConn.disconnect();
+}
+
+void LLTeleportHistory::goToItem(int idx)
+
+{
+ // Validate specified index.
+ if (idx < 0 || idx >= (int)mItems.size())
+ {
+ llwarns << "Invalid teleport history index (" << idx << ") specified" << llendl;
+ dump();
+ return;
+ }
+
+ if (idx == mCurrentItem)
+ {
+ llwarns << "Will not teleport to the same location." << llendl;
+ dump();
+ return;
+ }
+
+ // Attempt to teleport to the requested item.
+ gAgent.teleportViaLocation(mItems[idx].mGlobalPos);
+ mRequestedItem = idx;
+}
+
+void LLTeleportHistory::onTeleportFailed()
+{
+ // Are we trying to teleport within the history?
+ if (mRequestedItem != -1)
+ {
+ // Not anymore.
+ mRequestedItem = -1;
+ }
+}
+
+void LLTeleportHistory::updateCurrentLocation(const LLVector3d& new_pos)
+{
+ if (mRequestedItem != -1) // teleport within the history in progress?
+ {
+ mCurrentItem = mRequestedItem;
+ mRequestedItem = -1;
+ }
+ else
+ {
+ // If we're getting the initial location update
+ // while we already have a (loaded) non-empty history,
+ // there's no need to purge forward items or add a new item.
+
+ if (mGotInitialUpdate || mItems.size() == 0)
+ {
+ // Purge forward items (if any).
+ if(mItems.size())
+ mItems.erase (mItems.begin() + mCurrentItem + 1, mItems.end());
+
+ // Append an empty item to the history and make it current.
+ mItems.push_back(LLTeleportHistoryItem("", LLVector3d()));
+ mCurrentItem++;
+ }
+
+ // Update current history item.
+ if (mCurrentItem < 0 || mCurrentItem >= (int) mItems.size()) // sanity check
+ {
+ llwarns << "Invalid current item. (this should not happen)" << llendl;
+ return;
+ }
+ LLVector3 new_pos_local = gAgent.getPosAgentFromGlobal(new_pos);
+ mItems[mCurrentItem].mFullTitle = getCurrentLocationTitle(true, new_pos_local);
+ mItems[mCurrentItem].mTitle = getCurrentLocationTitle(false, new_pos_local);
+ mItems[mCurrentItem].mGlobalPos = new_pos;
+ mItems[mCurrentItem].mRegionID = gAgent.getRegion()->getRegionID();
+ }
+
+ dump();
+
+ if (!mGotInitialUpdate)
+ mGotInitialUpdate = true;
+
+ // Signal the interesting party that we've changed.
+ onHistoryChanged();
+}
+
+boost::signals2::connection LLTeleportHistory::setHistoryChangedCallback(history_callback_t cb)
+{
+ return mHistoryChangedSignal.connect(cb);
+}
+
+void LLTeleportHistory::onHistoryChanged()
+{
+ mHistoryChangedSignal();
+}
+
+void LLTeleportHistory::purgeItems()
+{
+ mItems.erase(mItems.begin(), mItems.end()-1);
+ // reset the count
+ mRequestedItem = -1;
+ mCurrentItem = 0;
+}
+
+// static
+std::string LLTeleportHistory::getCurrentLocationTitle(bool full, const LLVector3& local_pos_override)
+{
+ std::string location_name;
+ LLAgentUI::ELocationFormat fmt = full ? LLAgentUI::LOCATION_FORMAT_WITHOUT_SIM : LLAgentUI::LOCATION_FORMAT_NORMAL;
+
+ if (!LLAgentUI::buildLocationString(location_name, fmt, local_pos_override)) location_name = "Unknown";
+ return location_name;
+}
+
+void LLTeleportHistory::dump() const
+{
+ llinfos << "Teleport history dump (" << mItems.size() << " items):" << llendl;
+
+ for (size_t i=0; i<mItems.size(); i++)
+ {
+ std::stringstream line;
+ line << ((i == mCurrentItem) ? " * " : " ");
+ line << i << ": " << mItems[i].mTitle;
+ line << " REGION_ID: " << mItems[i].mRegionID;
+ line << ", pos: " << mItems[i].mGlobalPos;
+ llinfos << line.str() << llendl;
+ }
+}
diff --git a/indra/newview/llteleporthistory.h b/indra/newview/llteleporthistory.h
new file mode 100644
index 0000000000..9f5563ed0b
--- /dev/null
+++ b/indra/newview/llteleporthistory.h
@@ -0,0 +1,237 @@
+/**
+ * @file llteleporthistory.h
+ * @brief Teleport history
+ *
+ * $LicenseInfo:firstyear=2009&license=viewergpl$
+ *
+ * Copyright (c) 2009, Linden Research, Inc.
+ *
+ * Second Life Viewer Source Code
+ * The source code in this file ("Source Code") is provided by Linden Lab
+ * to you under the terms of the GNU General Public License, version 2.0
+ * ("GPL"), unless you have obtained a separate licensing agreement
+ * ("Other License"), formally executed by you and Linden Lab. Terms of
+ * the GPL can be found in doc/GPL-license.txt in this distribution, or
+ * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
+ *
+ * There are special exceptions to the terms and conditions of the GPL as
+ * it is applied to this Source Code. View the full text of the exception
+ * in the file doc/FLOSS-exception.txt in this software distribution, or
+ * online at
+ * http://secondlifegrid.net/programs/open_source/licensing/flossexception
+ *
+ * By copying, modifying or distributing this software, you acknowledge
+ * that you have read and understood your obligations described above,
+ * and agree to abide by those obligations.
+ *
+ * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+ * COMPLETENESS OR PERFORMANCE.
+ * $/LicenseInfo$
+ */
+
+#ifndef LL_LLTELEPORTHISTORY_H
+#define LL_LLTELEPORTHISTORY_H
+
+#include "llsingleton.h" // for LLSingleton
+
+#include <vector>
+#include <string>
+#include <boost/function.hpp>
+#include <boost/signals2.hpp>
+
+
+/**
+ * An item of the teleport history.
+ *
+ * Contains the location's global coordinates and its title.
+ */
+class LLTeleportHistoryItem
+{
+public:
+ LLTeleportHistoryItem()
+ {}
+
+ LLTeleportHistoryItem(std::string title, LLVector3d global_pos)
+ : mTitle(title), mGlobalPos(global_pos)
+ {}
+
+ /**
+ * @return title formatted according to the current value of the ShowCoordinatesOption setting.
+ */
+ const std::string& getTitle() const;
+
+ std::string mTitle; // human-readable location title
+ std::string mFullTitle; // human-readable location title including coordinates
+ LLVector3d mGlobalPos; // global position
+ LLUUID mRegionID; // region ID for getting the region info
+};
+
+/**
+ * Teleport history.
+ *
+ * Along with the navigation bar "Back" and "Forward" buttons
+ * implements web browser-like navigation functionality.
+ *
+ * @see LLNavigationBar
+ */
+class LLTeleportHistory: public LLSingleton<LLTeleportHistory>
+{
+ LOG_CLASS(LLTeleportHistory);
+
+public:
+
+ typedef std::vector<LLTeleportHistoryItem> slurl_list_t;
+ typedef boost::function<void()> history_callback_t;
+ typedef boost::signals2::signal<void()> history_signal_t;
+
+ LLTeleportHistory();
+ ~LLTeleportHistory();
+
+ /**
+ * Go back in the history.
+ */
+ void goBack() { goToItem(getCurrentItemIndex() - 1); }
+
+ /**
+ * Go forward in the history.
+ */
+ void goForward() { goToItem(getCurrentItemIndex() + 1); }
+
+ /**
+ * Go to specific item in the history.
+ *
+ * The item is specified by its index (starting from 0).
+ */
+ void goToItem(int idx);
+
+ /**
+ * @return history items.
+ */
+ const slurl_list_t& getItems() const { return mItems; }
+ void purgeItems();
+ /**
+ * Is the history empty?
+ *
+ * History containing single item is treated as empty
+ * because the item points to the current location.
+ */
+ bool isEmpty() const { return mItems.size() <= 1; }
+
+ /**
+ * Get index of the current location in the history.
+ */
+ int getCurrentItemIndex() const { return mCurrentItem; }
+ /**
+ * Set a callback to be called upon history changes.
+ *
+ * Multiple callbacks can be set.
+ */
+ boost::signals2::connection setHistoryChangedCallback(history_callback_t cb);
+
+ /**
+ * Save history to a file so that we can restore it on startup.
+ *
+ * @see load()
+ */
+ void dump() const;
+
+private:
+
+ /**
+ * Called by when a teleport fails.
+ *
+ * Called via callback set on the LLViewerParcelMgr "teleport failed" signal.
+ *
+ * @see mTeleportFailedConn
+ */
+ void onTeleportFailed();
+
+ /**
+ * Update current location.
+ *
+ * @param new_pos Current agent global position. After local teleports we
+ * cannot rely on gAgent.getPositionGlobal(),
+ * so the new position gets passed explicitly.
+ *
+ * Called when a teleport finishes.
+ * Called via callback set on the LLViewerParcelMgr "teleport finished" signal.
+ *
+ * Takes mRequestedItem into consideration: if it's not -1
+ * (i.e. user is teleporting to an arbitrary location, not to a history item)
+ * we purge forward items and append a new one, making it current. Otherwise
+ * we just modify mCurrentItem.
+ *
+ * @see mRequestedItem
+ * @see mGotInitialUpdate
+ */
+ void updateCurrentLocation(const LLVector3d& new_pos);
+
+ /**
+ * Invokes the "history changed" callback(s).
+ */
+ void onHistoryChanged();
+
+ /**
+ * Format current agent location in a human-readable manner.
+ *
+ * @param full whether to include coordinates
+ * @param local_pos_override hack: see description of updateCurrentLocation()
+ * @return
+ */
+ static std::string getCurrentLocationTitle(bool full, const LLVector3& local_pos_override);
+
+ /**
+ * Actually, the teleport history.
+ */
+ slurl_list_t mItems;
+
+ /**
+ * Current position within the history.
+ */
+ int mCurrentItem;
+
+ /**
+ * Requested position within the history.
+ *
+ * When a teleport succeeds, this is checked by updateCurrentLocation() to tell
+ * if this is a teleport within the history (mRequestedItem >=0) or not (-1).
+ *
+ * Set by goToItem(); reset by onTeleportFailed() (if teleport fails).
+ *
+ * @see goToItem()
+ * @see updateCurrentLocation()
+ */
+ int mRequestedItem;
+
+ /**
+ * Have we received the initial location update?
+ *
+ * @see updateCurrentLocation()
+ */
+ bool mGotInitialUpdate;
+
+ /**
+ * Signal emitted when the history gets changed.
+ *
+ * Invokes callbacks set with setHistoryChangedCallback().
+ */
+ history_signal_t mHistoryChangedSignal;
+
+ /**
+ * Teleport success notification connection.
+ *
+ * Using this connection we get notified when a teleport finishes
+ * or initial location update occurs.
+ */
+ boost::signals2::connection mTeleportFinishedConn;
+
+ /**
+ * Teleport failure notification connection.
+ *
+ * Using this connection we get notified when a teleport fails.
+ */
+ boost::signals2::connection mTeleportFailedConn;
+};
+
+#endif
diff --git a/indra/newview/llteleporthistorystorage.cpp b/indra/newview/llteleporthistorystorage.cpp
new file mode 100644
index 0000000000..b31edf1e5d
--- /dev/null
+++ b/indra/newview/llteleporthistorystorage.cpp
@@ -0,0 +1,164 @@
+/**
+ * @file llteleporthistorystorage.cpp
+ * @brief Teleport history
+ *
+ * $LicenseInfo:firstyear=2009&license=viewergpl$
+ *
+ * Copyright (c) 2009, Linden Research, Inc.
+ *
+ * Second Life Viewer Source Code
+ * The source code in this file ("Source Code") is provided by Linden Lab
+ * to you under the terms of the GNU General Public License, version 2.0
+ * ("GPL"), unless you have obtained a separate licensing agreement
+ * ("Other License"), formally executed by you and Linden Lab. Terms of
+ * the GPL can be found in doc/GPL-license.txt in this distribution, or
+ * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
+ *
+ * There are special exceptions to the terms and conditions of the GPL as
+ * it is applied to this Source Code. View the full text of the exception
+ * in the file doc/FLOSS-exception.txt in this software distribution, or
+ * online at
+ * http://secondlifegrid.net/programs/open_source/licensing/flossexception
+ *
+ * By copying, modifying or distributing this software, you acknowledge
+ * that you have read and understood your obligations described above,
+ * and agree to abide by those obligations.
+ *
+ * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+ * COMPLETENESS OR PERFORMANCE.
+ * $/LicenseInfo$
+ */
+
+#include "llviewerprecompiledheaders.h"
+
+#include "llteleporthistorystorage.h"
+
+#include "llsd.h"
+#include "llsdserialize.h"
+#include "lldir.h"
+
+static LLTeleportHistoryStorage tpstorage;
+
+LLTeleportHistoryPersistentItem::LLTeleportHistoryPersistentItem(const LLSD& val)
+{
+ mTitle = val["title"].asString();
+ mGlobalPos.setValue(val["global_pos"]);
+ mDate = val["date"];
+}
+
+LLSD LLTeleportHistoryPersistentItem::toLLSD() const
+{
+ LLSD val;
+
+ val["title"] = mTitle;
+ val["global_pos"] = mGlobalPos.getValue();
+ val["date"] = mDate;
+
+ return val;
+}
+
+LLTeleportHistoryStorage::LLTeleportHistoryStorage() :
+ mFilename("teleport_history.txt")
+{
+}
+
+LLTeleportHistoryStorage::~LLTeleportHistoryStorage()
+{
+}
+
+void LLTeleportHistoryStorage::purgeItems()
+{
+ mItems.clear();
+}
+
+void LLTeleportHistoryStorage::addItem(const std::string title, const LLVector3d& global_pos)
+{
+ mItems.push_back(LLTeleportHistoryPersistentItem(title, global_pos));
+}
+
+void LLTeleportHistoryStorage::addItem(const std::string title, const LLVector3d& global_pos, const LLDate& date)
+{
+ mItems.push_back(LLTeleportHistoryPersistentItem(title, global_pos, date));
+}
+
+void LLTeleportHistoryStorage::removeItem(S32 idx)
+{
+ if (idx < 0 || idx >= (S32)mItems.size())
+ return;
+
+ mItems.erase (mItems.begin() + idx);
+}
+
+void LLTeleportHistoryStorage::save()
+{
+ // build filename for each user
+ std::string resolvedFilename = gDirUtilp->getExpandedFilename(LL_PATH_PER_SL_ACCOUNT, mFilename);
+
+ // open the history file for writing
+ llofstream file (resolvedFilename);
+ if (!file.is_open())
+ {
+ llwarns << "can't open teleport history file \"" << mFilename << "\" for writing" << llendl;
+ return;
+ }
+
+ for (size_t i=0; i<mItems.size(); i++)
+ {
+ LLSD s_item = mItems[i].toLLSD();
+ file << LLSDOStreamer<LLSDNotationFormatter>(s_item) << std::endl;
+ }
+
+ file.close();
+}
+
+void LLTeleportHistoryStorage::load()
+{
+ // build filename for each user
+ std::string resolved_filename = gDirUtilp->getExpandedFilename(LL_PATH_PER_SL_ACCOUNT, mFilename);
+
+ // open the history file for reading
+ llifstream file(resolved_filename);
+ if (!file.is_open())
+ {
+ llwarns << "can't load teleport history from file \"" << mFilename << "\"" << llendl;
+ return;
+ }
+
+ // remove current entries before we load over them
+ mItems.clear();
+
+ // the parser's destructor is protected so we cannot create in the stack.
+ LLPointer<LLSDParser> parser = new LLSDNotationParser();
+ std::string line;
+ while (std::getline(file, line))
+ {
+ LLSD s_item;
+ std::istringstream iss(line);
+ if (parser->parse(iss, s_item, line.length()) == LLSDParser::PARSE_FAILURE)
+ {
+ llinfos << "Parsing saved teleport history failed" << llendl;
+ break;
+ }
+
+ mItems.push_back(s_item);
+ }
+
+ file.close();
+}
+
+void LLTeleportHistoryStorage::dump() const
+{
+ llinfos << "Teleport history storage dump (" << mItems.size() << " items):" << llendl;
+
+ for (size_t i=0; i<mItems.size(); i++)
+ {
+ std::stringstream line;
+ line << i << ": " << mItems[i].mTitle;
+ line << " global pos: " << mItems[i].mGlobalPos;
+ line << " date: " << mItems[i].mDate;
+
+ llinfos << line.str() << llendl;
+ }
+}
+
diff --git a/indra/newview/llteleporthistorystorage.h b/indra/newview/llteleporthistorystorage.h
new file mode 100644
index 0000000000..fa836c0326
--- /dev/null
+++ b/indra/newview/llteleporthistorystorage.h
@@ -0,0 +1,108 @@
+/**
+ * @file llteleporthistorystorage.h
+ * @brief Saving/restoring of teleport history.
+ *
+ * $LicenseInfo:firstyear=2009&license=viewergpl$
+ *
+ * Copyright (c) 2009, Linden Research, Inc.
+ *
+ * Second Life Viewer Source Code
+ * The source code in this file ("Source Code") is provided by Linden Lab
+ * to you under the terms of the GNU General Public License, version 2.0
+ * ("GPL"), unless you have obtained a separate licensing agreement
+ * ("Other License"), formally executed by you and Linden Lab. Terms of
+ * the GPL can be found in doc/GPL-license.txt in this distribution, or
+ * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
+ *
+ * There are special exceptions to the terms and conditions of the GPL as
+ * it is applied to this Source Code. View the full text of the exception
+ * in the file doc/FLOSS-exception.txt in this software distribution, or
+ * online at
+ * http://secondlifegrid.net/programs/open_source/licensing/flossexception
+ *
+ * By copying, modifying or distributing this software, you acknowledge
+ * that you have read and understood your obligations described above,
+ * and agree to abide by those obligations.
+ *
+ * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+ * COMPLETENESS OR PERFORMANCE.
+ * $/LicenseInfo$
+ */
+
+#ifndef LL_LLTELEPORTHISTORYSTORAGE_H
+#define LL_LLTELEPORTHISTORYSTORAGE_H
+
+#include <vector>
+
+#include "llsingleton.h"
+#include "lldate.h"
+#include "v3dmath.h"
+
+class LLSD;
+
+/**
+ * An item of the teleport history, stored in file
+ *
+ * Contains the location's global coordinates, title and date.
+ */
+class LLTeleportHistoryPersistentItem
+{
+public:
+ LLTeleportHistoryPersistentItem()
+ {}
+
+ LLTeleportHistoryPersistentItem(const std::string title, const LLVector3d& global_pos)
+ : mTitle(title), mGlobalPos(global_pos), mDate(LLDate::now())
+ {}
+
+ LLTeleportHistoryPersistentItem(const std::string title, const LLVector3d& global_pos, const LLDate& date)
+ : mTitle(title), mGlobalPos(global_pos), mDate(date)
+ {}
+
+ LLTeleportHistoryPersistentItem(const LLSD& val);
+ LLSD toLLSD() const;
+
+ std::string mTitle;
+ LLVector3d mGlobalPos;
+ LLDate mDate;
+};
+
+/**
+ * Persistent teleport history.
+ *
+ */
+class LLTeleportHistoryStorage: public LLSingleton<LLTeleportHistoryStorage>
+{
+ LOG_CLASS(LLTeleportHistoryStorage);
+
+public:
+
+ typedef std::vector<LLTeleportHistoryPersistentItem> item_list_list_t;
+
+ LLTeleportHistoryStorage();
+ ~LLTeleportHistoryStorage();
+
+ /**
+ * @return history items.
+ */
+ const item_list_list_t& getItems() const { return mItems; }
+ void purgeItems();
+
+ void addItem(const std::string title, const LLVector3d& global_pos);
+ void addItem(const std::string title, const LLVector3d& global_pos, const LLDate& date);
+
+ void removeItem(S32 idx);
+
+ void save();
+ void load();
+
+ void dump() const;
+
+private:
+
+ item_list_list_t mItems;
+ std::string mFilename;
+};
+
+#endif //LL_LLTELEPORTHISTORYSTORAGE_H
diff --git a/indra/newview/lltexglobalcolor.cpp b/indra/newview/lltexglobalcolor.cpp
new file mode 100644
index 0000000000..e81c3731f7
--- /dev/null
+++ b/indra/newview/lltexglobalcolor.cpp
@@ -0,0 +1,150 @@
+/**
+ * @file lltexlayerglobalcolor.cpp
+ * @brief SERAPH - ADD IN
+ *
+ * $LicenseInfo:firstyear=2008&license=viewergpl$
+ *
+ * Copyright (c) 2008-2009, Linden Research, Inc.
+ *
+ * Second Life Viewer Source Code
+ * The source code in this file ("Source Code") is provided by Linden Lab
+ * to you under the terms of the GNU General Public License, version 2.0
+ * ("GPL"), unless you have obtained a separate licensing agreement
+ * ("Other License"), formally executed by you and Linden Lab. Terms of
+ * the GPL can be found in doc/GPL-license.txt in this distribution, or
+ * online at http://secondlife.com/developers/opensource/gplv2
+ *
+ * There are special exceptions to the terms and conditions of the GPL as
+ * it is applied to this Source Code. View the full text of the exception
+ * in the file doc/FLOSS-exception.txt in this software distribution, or
+ * online at http://secondlife.com/developers/opensource/flossexception
+ *
+ * By copying, modifying or distributing this software, you acknowledge
+ * that you have read and understood your obligations described above,
+ * and agree to abide by those obligations.
+ *
+ * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+ * COMPLETENESS OR PERFORMANCE.
+ * $/LicenseInfo$
+ */
+
+#include "llviewerprecompiledheaders.h"
+#include "llagent.h"
+#include "lltexlayer.h"
+#include "llvoavatar.h"
+#include "lltexglobalcolor.h"
+
+//-----------------------------------------------------------------------------
+// LLTexGlobalColor
+//-----------------------------------------------------------------------------
+
+LLTexGlobalColor::LLTexGlobalColor(LLVOAvatar* avatar)
+ :
+ mAvatar(avatar),
+ mInfo(NULL)
+{
+}
+
+LLTexGlobalColor::~LLTexGlobalColor()
+{
+ // mParamColorList are LLViewerVisualParam's and get deleted with ~LLCharacter()
+ //std::for_each(mParamColorList.begin(), mParamColorList.end(), DeletePointer());
+}
+
+BOOL LLTexGlobalColor::setInfo(LLTexGlobalColorInfo *info)
+{
+ llassert(mInfo == NULL);
+ mInfo = info;
+ //mID = info->mID; // No ID
+
+ mParamGlobalColorList.reserve(mInfo->mParamColorInfoList.size());
+ for (param_color_info_list_t::iterator iter = mInfo->mParamColorInfoList.begin();
+ iter != mInfo->mParamColorInfoList.end();
+ iter++)
+ {
+ LLTexParamGlobalColor* param_color = new LLTexParamGlobalColor(this);
+ if (!param_color->setInfo(*iter))
+ {
+ mInfo = NULL;
+ return FALSE;
+ }
+ mParamGlobalColorList.push_back(param_color);
+ }
+
+ return TRUE;
+}
+
+LLColor4 LLTexGlobalColor::getColor() const
+{
+ // Sum of color params
+ if (mParamGlobalColorList.empty())
+ return LLColor4(1.f, 1.f, 1.f, 1.f);
+
+ LLColor4 net_color(0.f, 0.f, 0.f, 0.f);
+ LLTexLayer::calculateTexLayerColor(mParamGlobalColorList, net_color);
+ return net_color;
+}
+
+const std::string& LLTexGlobalColor::getName() const
+{
+ return mInfo->mName;
+}
+
+//-----------------------------------------------------------------------------
+// LLTexParamGlobalColor
+//-----------------------------------------------------------------------------
+LLTexParamGlobalColor::LLTexParamGlobalColor(LLTexGlobalColor* tex_global_color) :
+ LLTexLayerParamColor((LLTexLayer*)NULL),
+ mTexGlobalColor(tex_global_color)
+{
+ mAvatar = tex_global_color->getAvatar();
+}
+
+void LLTexParamGlobalColor::onGlobalColorChanged(bool set_by_user)
+{
+ mAvatar->onGlobalColorChanged(mTexGlobalColor, set_by_user);
+}
+
+//-----------------------------------------------------------------------------
+// LLTexGlobalColorInfo
+//-----------------------------------------------------------------------------
+
+LLTexGlobalColorInfo::LLTexGlobalColorInfo()
+{
+}
+
+
+LLTexGlobalColorInfo::~LLTexGlobalColorInfo()
+{
+ for_each(mParamColorInfoList.begin(), mParamColorInfoList.end(), DeletePointer());
+}
+
+BOOL LLTexGlobalColorInfo::parseXml(LLXmlTreeNode* node)
+{
+ // name attribute
+ static LLStdStringHandle name_string = LLXmlTree::addAttributeString("name");
+ if (!node->getFastAttributeString(name_string, mName))
+ {
+ llwarns << "<global_color> element is missing name attribute." << llendl;
+ return FALSE;
+ }
+ // <param> sub-element
+ for (LLXmlTreeNode* child = node->getChildByName("param");
+ child;
+ child = node->getNextNamedChild())
+ {
+ if (child->getChildByName("param_color"))
+ {
+ // <param><param_color/></param>
+ LLTexLayerParamColorInfo* info = new LLTexLayerParamColorInfo();
+ if (!info->parseXml(child))
+ {
+ delete info;
+ return FALSE;
+ }
+ mParamColorInfoList.push_back(info);
+ }
+ }
+ return TRUE;
+}
diff --git a/indra/newview/lltexglobalcolor.h b/indra/newview/lltexglobalcolor.h
new file mode 100644
index 0000000000..154b814392
--- /dev/null
+++ b/indra/newview/lltexglobalcolor.h
@@ -0,0 +1,86 @@
+/**
+ * @file lltexglobalcolor.h
+ * @brief This is global texture color info used by llvoavatar.
+ *
+ * $LicenseInfo:firstyear=2008&license=viewergpl$
+ *
+ * Copyright (c) 2008-2009, Linden Research, Inc.
+ *
+ * Second Life Viewer Source Code
+ * The source code in this file ("Source Code") is provided by Linden Lab
+ * to you under the terms of the GNU General Public License, version 2.0
+ * ("GPL"), unless you have obtained a separate licensing agreement
+ * ("Other License"), formally executed by you and Linden Lab. Terms of
+ * the GPL can be found in doc/GPL-license.txt in this distribution, or
+ * online at http://secondlife.com/developers/opensource/gplv2
+ *
+ * There are special exceptions to the terms and conditions of the GPL as
+ * it is applied to this Source Code. View the full text of the exception
+ * in the file doc/FLOSS-exception.txt in this software distribution, or
+ * online at http://secondlife.com/developers/opensource/flossexception
+ *
+ * By copying, modifying or distributing this software, you acknowledge
+ * that you have read and understood your obligations described above,
+ * and agree to abide by those obligations.
+ *
+ * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+ * COMPLETENESS OR PERFORMANCE.
+ * $/LicenseInfo$
+ */
+
+#ifndef LL_LLTEXGLOBALCOLOR_H
+#define LL_LLTEXGLOBALCOLOR_H
+
+#include "lltexlayer.h"
+#include "lltexlayerparams.h"
+
+class LLVOAvatar;
+class LLTexGlobalColorInfo;
+
+class LLTexGlobalColor
+{
+public:
+ LLTexGlobalColor( LLVOAvatar* avatar );
+ ~LLTexGlobalColor();
+
+ LLTexGlobalColorInfo* getInfo() const { return mInfo; }
+ // This sets mInfo and calls initialization functions
+ BOOL setInfo(LLTexGlobalColorInfo *info);
+
+ LLVOAvatar* getAvatar() const { return mAvatar; }
+ LLColor4 getColor() const;
+ const std::string& getName() const;
+
+private:
+ param_color_list_t mParamGlobalColorList;
+ LLVOAvatar* mAvatar; // just backlink, don't LLPointer
+ LLTexGlobalColorInfo *mInfo;
+};
+
+// Used by llvoavatar to determine skin/eye/hair color.
+class LLTexGlobalColorInfo
+{
+ friend class LLTexGlobalColor;
+public:
+ LLTexGlobalColorInfo();
+ ~LLTexGlobalColorInfo();
+
+ BOOL parseXml(LLXmlTreeNode* node);
+
+private:
+ param_color_info_list_t mParamColorInfoList;
+ std::string mName;
+};
+
+class LLTexParamGlobalColor : public LLTexLayerParamColor
+{
+public:
+ LLTexParamGlobalColor(LLTexGlobalColor *tex_color);
+protected:
+ /*virtual*/ void onGlobalColorChanged(bool set_by_user);
+private:
+ LLTexGlobalColor* mTexGlobalColor;
+};
+
+#endif
diff --git a/indra/newview/lltexlayer.cpp b/indra/newview/lltexlayer.cpp
index 424c525870..5a5f187415 100644
--- a/indra/newview/lltexlayer.cpp
+++ b/indra/newview/lltexlayer.cpp
@@ -31,80 +31,56 @@
*/
#include "llviewerprecompiledheaders.h"
-
-#include "imageids.h"
#include "llagent.h"
-#include "llcrc.h"
-#include "lldir.h"
-#include "llglheaders.h"
-#include "llimagebmp.h"
-#include "llimagej2c.h"
-#include "llimagetga.h"
-#include "llpolymorph.h"
-#include "llquantize.h"
#include "lltexlayer.h"
-#include "llui.h"
-#include "llvfile.h"
-#include "llviewerimagelist.h"
-#include "llviewerimagelist.h"
-#include "llviewerregion.h"
#include "llviewerstats.h"
-#include "llviewerwindow.h"
+#include "llviewerregion.h"
#include "llvoavatar.h"
-#include "llxmltree.h"
+#include "llvoavatarself.h"
#include "pipeline.h"
-#include "v4coloru.h"
-#include "llrender.h"
#include "llassetuploadresponders.h"
+#include "lltexlayerparams.h"
+#include "llui.h"
//#include "../tools/imdebug/imdebug.h"
using namespace LLVOAvatarDefines;
-// static
-S32 LLTexLayerSetBuffer::sGLByteCount = 0;
-S32 LLTexLayerSetBuffer::sGLBumpByteCount = 0;
-
//-----------------------------------------------------------------------------
// LLBakedUploadData()
//-----------------------------------------------------------------------------
-LLBakedUploadData::LLBakedUploadData( LLVOAvatar* avatar,
- LLTexLayerSet* layerset,
- LLTexLayerSetBuffer* layerset_buffer,
- const LLUUID & id ) :
- mAvatar( avatar ),
- mLayerSet( layerset ),
- mLayerSetBuffer( layerset_buffer ),
- mID(id)
+LLBakedUploadData::LLBakedUploadData(const LLVOAvatarSelf* avatar,
+ LLTexLayerSet* layerset,
+ const LLUUID& id) :
+ mAvatar(avatar),
+ mTexLayerSet(layerset),
+ mID(id),
+ mStartTime(LLFrameTimer::getTotalTime()) // Record starting time
{
- mStartTime = LLFrameTimer::getTotalTime(); // Record starting time
- for( S32 i = 0; i < WT_COUNT; i++ )
- {
- LLWearable* wearable = gAgent.getWearable( (EWearableType)i);
- if( wearable )
- {
- mWearableAssets[i] = wearable->getID();
- }
- }
}
//-----------------------------------------------------------------------------
// LLTexLayerSetBuffer
// The composite image that a LLTexLayerSet writes to. Each LLTexLayerSet has one.
//-----------------------------------------------------------------------------
-LLTexLayerSetBuffer::LLTexLayerSetBuffer( LLTexLayerSet* owner, S32 width, S32 height, BOOL has_bump )
- :
+
+// static
+S32 LLTexLayerSetBuffer::sGLByteCount = 0;
+S32 LLTexLayerSetBuffer::sGLBumpByteCount = 0;
+
+LLTexLayerSetBuffer::LLTexLayerSetBuffer(LLTexLayerSet* const owner,
+ S32 width, S32 height,
+ BOOL has_bump) :
// ORDER_LAST => must render these after the hints are created.
- LLDynamicTexture( width, height, 4, LLDynamicTexture::ORDER_LAST, TRUE ),
+ LLViewerDynamicTexture( width, height, 4, LLViewerDynamicTexture::ORDER_LAST, TRUE ),
mNeedsUpdate( TRUE ),
mNeedsUpload( FALSE ),
mUploadPending( FALSE ), // Not used for any logic here, just to sync sending of updates
- mTexLayerSet( owner )
+ mTexLayerSet(owner),
+ mHasBump(has_bump),
+ mBumpTex(NULL)
{
LLTexLayerSetBuffer::sGLByteCount += getSize();
- mHasBump = has_bump ;
- mBumpTex = NULL ;
-
createBumpTexture() ;
}
@@ -115,15 +91,16 @@ LLTexLayerSetBuffer::~LLTexLayerSetBuffer()
if( mBumpTex.notNull())
{
mBumpTex = NULL ;
- LLImageGL::sGlobalTextureMemoryInBytes -= mWidth * mHeight * 4;
- LLTexLayerSetBuffer::sGLBumpByteCount -= mWidth * mHeight * 4;
+ LLImageGL::sGlobalTextureMemoryInBytes -= mFullWidth * mFullHeight * 4;
+ LLTexLayerSetBuffer::sGLBumpByteCount -= mFullWidth * mFullHeight * 4;
}
}
+
//virtual
void LLTexLayerSetBuffer::restoreGLTexture()
{
createBumpTexture() ;
- LLDynamicTexture::restoreGLTexture() ;
+ LLViewerDynamicTexture::restoreGLTexture() ;
}
//virtual
@@ -132,11 +109,11 @@ void LLTexLayerSetBuffer::destroyGLTexture()
if( mBumpTex.notNull() )
{
mBumpTex = NULL ;
- LLImageGL::sGlobalTextureMemoryInBytes -= mWidth * mHeight * 4;
- LLTexLayerSetBuffer::sGLBumpByteCount -= mWidth * mHeight * 4;
+ LLImageGL::sGlobalTextureMemoryInBytes -= mFullWidth * mFullHeight * 4;
+ LLTexLayerSetBuffer::sGLBumpByteCount -= mFullWidth * mFullHeight * 4;
}
- LLDynamicTexture::destroyGLTexture() ;
+ LLViewerDynamicTexture::destroyGLTexture() ;
}
void LLTexLayerSetBuffer::createBumpTexture()
@@ -144,7 +121,7 @@ void LLTexLayerSetBuffer::createBumpTexture()
if( mHasBump )
{
LLGLSUIDefault gls_ui;
- mBumpTex = new LLImageGL(FALSE) ;
+ mBumpTex = LLViewerTextureManager::getLocalTexture(FALSE) ;
if(!mBumpTex->createGLTexture())
{
mBumpTex = NULL ;
@@ -158,13 +135,13 @@ void LLTexLayerSetBuffer::createBumpTexture()
gGL.getTexUnit(0)->setTextureFilteringOption(LLTexUnit::TFO_BILINEAR);
- LLImageGL::setManualImage(GL_TEXTURE_2D, 0, GL_RGBA8, mWidth, mHeight, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
+ LLImageGL::setManualImage(GL_TEXTURE_2D, 0, GL_RGBA8, mFullWidth, mFullHeight, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
stop_glerror();
gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
- LLImageGL::sGlobalTextureMemoryInBytes += mWidth * mHeight * 4;
- LLTexLayerSetBuffer::sGLBumpByteCount += mWidth * mHeight * 4;
+ LLImageGL::sGlobalTextureMemoryInBytes += mFullWidth * mFullHeight * 4;
+ LLTexLayerSetBuffer::sGLBumpByteCount += mFullWidth * mFullHeight * 4;
}
}
@@ -202,19 +179,19 @@ void LLTexLayerSetBuffer::cancelUpload()
mUploadPending = FALSE;
}
-void LLTexLayerSetBuffer::pushProjection()
+void LLTexLayerSetBuffer::pushProjection() const
{
glMatrixMode(GL_PROJECTION);
gGL.pushMatrix();
glLoadIdentity();
- glOrtho(0.0f, mWidth, 0.0f, mHeight, -1.0f, 1.0f);
+ glOrtho(0.0f, mFullWidth, 0.0f, mFullHeight, -1.0f, 1.0f);
glMatrixMode(GL_MODELVIEW);
gGL.pushMatrix();
glLoadIdentity();
}
-void LLTexLayerSetBuffer::popProjection()
+void LLTexLayerSetBuffer::popProjection() const
{
glMatrixMode(GL_PROJECTION);
gGL.popMatrix();
@@ -225,12 +202,12 @@ void LLTexLayerSetBuffer::popProjection()
BOOL LLTexLayerSetBuffer::needsRender()
{
- LLVOAvatar* avatar = mTexLayerSet->getAvatar();
+ const LLVOAvatarSelf* avatar = mTexLayerSet->getAvatar();
BOOL upload_now = mNeedsUpload && mTexLayerSet->isLocalTextureDataFinal();
- BOOL needs_update = gAgent.mNumPendingQueries == 0 && (mNeedsUpdate || upload_now) && !avatar->mAppearanceAnimating;
+ BOOL needs_update = gAgentQueryManager.hasNoPendingQueries() && (mNeedsUpdate || upload_now) && !avatar->mAppearanceAnimating;
if (needs_update)
{
- BOOL invalid_skirt = avatar->getBakedTE(mTexLayerSet) == TEX_SKIRT_BAKED && !avatar->isWearingWearableType(WT_SKIRT);
+ BOOL invalid_skirt = avatar->getBakedTE(mTexLayerSet) == LLVOAvatarDefines::TEX_SKIRT_BAKED && !avatar->isWearingWearableType(WT_SKIRT);
if (invalid_skirt)
{
// we were trying to create a skirt texture
@@ -253,14 +230,14 @@ void LLTexLayerSetBuffer::preRender(BOOL clear_depth)
pushProjection();
// keep depth buffer, we don't need to clear it
- LLDynamicTexture::preRender(FALSE);
+ LLViewerDynamicTexture::preRender(FALSE);
}
void LLTexLayerSetBuffer::postRender(BOOL success)
{
popProjection();
- LLDynamicTexture::postRender(success);
+ LLViewerDynamicTexture::postRender(success);
}
BOOL LLTexLayerSetBuffer::render()
@@ -272,14 +249,14 @@ BOOL LLTexLayerSetBuffer::render()
// do we need to upload, and do we have sufficient data to create an uploadable composite?
// When do we upload the texture if gAgent.mNumPendingQueries is non-zero?
- BOOL upload_now = (gAgent.mNumPendingQueries == 0 && mNeedsUpload && mTexLayerSet->isLocalTextureDataFinal());
+ BOOL upload_now = (gAgentQueryManager.hasNoPendingQueries() && mNeedsUpload && mTexLayerSet->isLocalTextureDataFinal());
BOOL success = TRUE;
// Composite bump
if( mBumpTex.notNull() )
{
// Composite the bump data
- success &= mTexLayerSet->renderBump( mOrigin.mX, mOrigin.mY, mWidth, mHeight );
+ success &= mTexLayerSet->renderBump( mOrigin.mX, mOrigin.mY, mFullWidth, mFullHeight );
stop_glerror();
if (success)
@@ -290,14 +267,14 @@ BOOL LLTexLayerSetBuffer::render()
gGL.getTexUnit(0)->bindManual(LLTexUnit::TT_TEXTURE, mBumpTex->getTexName());
stop_glerror();
- glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, mOrigin.mX, mOrigin.mY, mWidth, mHeight);
+ glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, mOrigin.mX, mOrigin.mY, mFullWidth, mFullHeight);
stop_glerror();
// if we need to upload the data, read it back into a buffer
if( upload_now )
{
- baked_bump_data = new U8[ mWidth * mHeight * 4 ];
- glReadPixels(mOrigin.mX, mOrigin.mY, mWidth, mHeight, GL_RGBA, GL_UNSIGNED_BYTE, baked_bump_data );
+ baked_bump_data = new U8[ mFullWidth * mFullHeight * 4 ];
+ glReadPixels(mOrigin.mX, mOrigin.mY, mFullWidth, mFullHeight, GL_RGBA, GL_UNSIGNED_BYTE, baked_bump_data );
stop_glerror();
}
}
@@ -305,14 +282,13 @@ BOOL LLTexLayerSetBuffer::render()
// Composite the color data
LLGLSUIDefault gls_ui;
- success &= mTexLayerSet->render( mOrigin.mX, mOrigin.mY, mWidth, mHeight );
+ success &= mTexLayerSet->render( mOrigin.mX, mOrigin.mY, mFullWidth, mFullHeight );
gGL.flush();
if( upload_now )
{
if (!success)
{
- delete [] baked_bump_data;
llinfos << "Failed attempt to bake " << mTexLayerSet->getBodyRegion() << llendl;
mUploadPending = FALSE;
}
@@ -327,15 +303,16 @@ BOOL LLTexLayerSetBuffer::render()
gGL.setSceneBlendType(LLRender::BT_ALPHA);
// we have valid texture data now
- mTexture->setGLTextureCreated(true);
+ mGLTexturep->setGLTextureCreated(true);
mNeedsUpdate = FALSE;
+ delete [] baked_bump_data;
return success;
}
bool LLTexLayerSetBuffer::isInitialized(void) const
{
- return mTexture.notNull() && mTexture->isGLTextureCreated();
+ return mGLTexturep.notNull() && mGLTexturep->isGLTextureCreated();
}
BOOL LLTexLayerSetBuffer::updateImmediate()
@@ -353,12 +330,12 @@ BOOL LLTexLayerSetBuffer::updateImmediate()
return result;
}
-void LLTexLayerSetBuffer::readBackAndUpload(U8* baked_bump_data)
+void LLTexLayerSetBuffer::readBackAndUpload(const U8* baked_bump_data)
{
// pointers for storing data to upload
- U8* baked_color_data = new U8[ mWidth * mHeight * 4 ];
+ U8* baked_color_data = new U8[ mFullWidth * mFullHeight * 4 ];
- glReadPixels(mOrigin.mX, mOrigin.mY, mWidth, mHeight, GL_RGBA, GL_UNSIGNED_BYTE, baked_color_data );
+ glReadPixels(mOrigin.mX, mOrigin.mY, mFullWidth, mFullHeight, GL_RGBA, GL_UNSIGNED_BYTE, baked_color_data );
stop_glerror();
llinfos << "Baked " << mTexLayerSet->getBodyRegion() << llendl;
@@ -373,31 +350,27 @@ void LLTexLayerSetBuffer::readBackAndUpload(U8* baked_bump_data)
LLGLSUIDefault gls_ui;
- LLPointer<LLImageRaw> baked_mask_image = new LLImageRaw(mWidth, mHeight, 1 );
+ LLPointer<LLImageRaw> baked_mask_image = new LLImageRaw(mFullWidth, mFullHeight, 1 );
U8* baked_mask_data = baked_mask_image->getData();
-
- mTexLayerSet->gatherAlphaMasks(baked_mask_data, mWidth, mHeight);
-// imdebug("lum b=8 w=%d h=%d %p", mWidth, mHeight, baked_mask_data);
-
+
+ mTexLayerSet->gatherMorphMaskAlpha(baked_mask_data, mFullWidth, mFullHeight);
// writes into baked_color_data
const char* comment_text = NULL;
S32 baked_image_components = mBumpTex.notNull() ? 5 : 4; // red green blue [bump] clothing
- LLPointer<LLImageRaw> baked_image = new LLImageRaw( mWidth, mHeight, baked_image_components );
+ LLPointer<LLImageRaw> baked_image = new LLImageRaw( mFullWidth, mFullHeight, baked_image_components );
U8* baked_image_data = baked_image->getData();
+
if( mBumpTex.notNull() )
{
comment_text = LINDEN_J2C_COMMENT_PREFIX "RGBHM"; // 5 channels: rgb, heightfield/alpha, mask
- // Hide the alpha for the eyelashes in a corner of the bump map
- if (mTexLayerSet->getBodyRegion() == "head")
- {
S32 i = 0;
- for( S32 u = 0; u < mWidth; u++ )
+ for( S32 u = 0; u < mFullWidth; u++ )
{
- for( S32 v = 0; v < mHeight; v++ )
+ for( S32 v = 0; v < mFullHeight; v++ )
{
baked_image_data[5*i + 0] = baked_color_data[4*i + 0];
baked_image_data[5*i + 1] = baked_color_data[4*i + 1];
@@ -411,28 +384,9 @@ void LLTexLayerSetBuffer::readBackAndUpload(U8* baked_bump_data)
else
{
S32 i = 0;
- for( S32 u = 0; u < mWidth; u++ )
+ for( S32 u = 0; u < mFullWidth; u++ )
{
- for( S32 v = 0; v < mHeight; v++ )
- {
- baked_image_data[5*i + 0] = baked_color_data[4*i + 0];
- baked_image_data[5*i + 1] = baked_color_data[4*i + 1];
- baked_image_data[5*i + 2] = baked_color_data[4*i + 2];
- baked_image_data[5*i + 3] = 255; // reserve for alpha
- baked_image_data[5*i + 4] = baked_mask_data[i];
- i++;
- }
- }
- }
- }
- else
- {
- if (mTexLayerSet->getBodyRegion() == "skirt" || mTexLayerSet->getBodyRegion() == "hair")
- {
- S32 i = 0;
- for( S32 u = 0; u < mWidth; u++ )
- {
- for( S32 v = 0; v < mHeight; v++ )
+ for( S32 v = 0; v < mFullHeight; v++ )
{
baked_image_data[4*i + 0] = baked_color_data[4*i + 0];
baked_image_data[4*i + 1] = baked_color_data[4*i + 1];
@@ -442,22 +396,6 @@ void LLTexLayerSetBuffer::readBackAndUpload(U8* baked_bump_data)
}
}
}
- else
- {
- S32 i = 0;
- for( S32 u = 0; u < mWidth; u++ )
- {
- for( S32 v = 0; v < mHeight; v++ )
- {
- baked_image_data[4*i + 0] = baked_color_data[4*i + 0];
- baked_image_data[4*i + 1] = baked_color_data[4*i + 1];
- baked_image_data[4*i + 2] = baked_color_data[4*i + 2];
- baked_image_data[4*i + 3] = 255; // eyes should have no mask - reserve for alpha
- i++;
- }
- }
- }
- }
LLPointer<LLImageJ2C> compressedImage = new LLImageJ2C;
compressedImage->setRate(0.f);
@@ -490,7 +428,7 @@ void LLTexLayerSetBuffer::readBackAndUpload(U8* baked_bump_data)
{
// baked_upload_data is owned by the responder and deleted after the request completes
LLBakedUploadData* baked_upload_data =
- new LLBakedUploadData( gAgent.getAvatarObject(), this->mTexLayerSet, this, asset_id );
+ new LLBakedUploadData(gAgent.getAvatarObject(), this->mTexLayerSet, asset_id);
mUploadID = asset_id;
// upload the image
@@ -536,73 +474,74 @@ void LLTexLayerSetBuffer::readBackAndUpload(U8* baked_bump_data)
}
delete [] baked_color_data;
- delete [] baked_bump_data;
}
// static
-void LLTexLayerSetBuffer::onTextureUploadComplete(const LLUUID& uuid, void* userdata, S32 result, LLExtStat ext_status) // StoreAssetData callback (not fixed)
+void LLTexLayerSetBuffer::onTextureUploadComplete(const LLUUID& uuid,
+ void* userdata,
+ S32 result,
+ LLExtStat ext_status) // StoreAssetData callback (not fixed)
{
LLBakedUploadData* baked_upload_data = (LLBakedUploadData*)userdata;
- LLVOAvatar* avatar = gAgent.getAvatarObject();
+ LLVOAvatarSelf* avatar = gAgent.getAvatarObject();
- if (0 == result && avatar && !avatar->isDead())
+ if (0 == result &&
+ avatar &&
+ !avatar->isDead() &&
+ baked_upload_data->mAvatar == avatar && // Sanity check: only the user's avatar should be uploading textures.
+ baked_upload_data->mTexLayerSet->hasComposite()
+ )
{
- // Sanity check: only the user's avatar should be uploading textures.
- if( baked_upload_data->mAvatar == avatar )
+ LLTexLayerSetBuffer* layerset_buffer = baked_upload_data->mTexLayerSet->getComposite();
+
+ if (layerset_buffer->mUploadID.isNull())
+ {
+ // The upload got canceled, we should be in the
+ // process of baking a new texture so request an
+ // upload with the new data
+
+ // BAP: does this really belong in this callback, as
+ // opposed to where the cancellation takes place?
+ // suspect this does nothing.
+ layerset_buffer->requestUpload();
+ }
+ else if (baked_upload_data->mID == layerset_buffer->mUploadID)
{
- // Composite may have changed since the pointer was stored - need to do some checking.
- LLTexLayerSetBuffer* prev_layerset_buffer = baked_upload_data->mLayerSetBuffer;
- // Can't just call getComposite() because this will trigger creation if none exists.
- LLTexLayerSetBuffer* curr_layerset_buffer =
- baked_upload_data->mLayerSet->hasComposite()?baked_upload_data->mLayerSet->getComposite():NULL;
+ // This is the upload we're currently waiting for.
+ layerset_buffer->mUploadID.setNull();
+ layerset_buffer->mUploadPending = FALSE;
- if (prev_layerset_buffer != curr_layerset_buffer)
+ if (result >= 0)
{
- llinfos << "Baked texture out of date, composite no longer valid, ignored" << llendl;
+ LLVOAvatarDefines::ETextureIndex baked_te = avatar->getBakedTE(layerset_buffer->mTexLayerSet);
+ // Update baked texture info with the new UUID
+ U64 now = LLFrameTimer::getTotalTime(); // Record starting time
+ llinfos << "Baked texture upload took " << (S32)((now - baked_upload_data->mStartTime) / 1000) << " ms" << llendl;
+ avatar->setNewBakedTexture(baked_te, uuid);
}
else
- {
- curr_layerset_buffer->mUploadPending = FALSE;
-
- if (curr_layerset_buffer->mUploadID.isNull())
- {
- // The upload got canceled, we should be in the process of baking a new texture
- // so request an upload with the new data
- curr_layerset_buffer->requestUpload();
- }
- else if( baked_upload_data->mID == curr_layerset_buffer->mUploadID )
- {
- // This is the upload we're currently waiting for.
- curr_layerset_buffer->mUploadID.setNull();
-
- if( result >= 0 )
- {
- ETextureIndex baked_te = avatar->getBakedTE( curr_layerset_buffer->mTexLayerSet );
- U64 now = LLFrameTimer::getTotalTime(); // Record starting time
- llinfos << "Baked texture upload took " << (S32)((now - baked_upload_data->mStartTime) / 1000) << " ms" << llendl;
- avatar->setNewBakedTexture( baked_te, uuid );
- }
- else
- {
- llinfos << "Baked upload failed. Reason: " << result << llendl;
- // *FIX: retry upload after n seconds, asset server could be busy
- }
- }
- else
- {
- llinfos << "Received baked texture out of date, ignored." << llendl;
- }
-
- avatar->dirtyMesh();
+ {
+ // Avatar appearance is changing, ignore the upload results
+ llinfos << "Baked upload failed. Reason: " << result << llendl;
+ // *FIX: retry upload after n seconds, asset server could be busy
}
}
+ else
+ {
+ llinfos << "Received baked texture out of date, ignored." << llendl;
+ }
+
+ avatar->dirtyMesh();
}
else
{
- // Baked texture failed to upload, but since we didn't set the new baked texture, it means that they'll
- // try and rebake it at some point in the future (after login?)
+ // Baked texture failed to upload (in which case since we
+ // didn't set the new baked texture, it means that they'll try
+ // and rebake it at some point in the future (after login?)),
+ // or this response to upload is out of date, in which case a
+ // current response should be on the way or already processed.
llwarns << "Baked upload failed" << llendl;
}
@@ -616,11 +555,7 @@ void LLTexLayerSetBuffer::bindBumpTexture( U32 stage )
gGL.getTexUnit(stage)->bindManual(LLTexUnit::TT_TEXTURE, mBumpTex->getTexName());
gGL.getTexUnit(0)->activate();
- if( mLastBindTime != LLImageGL::sLastFrameTime )
- {
- mLastBindTime = LLImageGL::sLastFrameTime;
- LLImageGL::updateBoundTexMem(mWidth * mHeight * 4);
- }
+ mGLTexturep->updateBindStats(mFullWidth * mFullHeight * 4);
}
else
{
@@ -635,8 +570,7 @@ void LLTexLayerSetBuffer::bindBumpTexture( U32 stage )
// An ordered set of texture layers that get composited into a single texture.
//-----------------------------------------------------------------------------
-LLTexLayerSetInfo::LLTexLayerSetInfo( )
- :
+LLTexLayerSetInfo::LLTexLayerSetInfo() :
mBodyRegion( "" ),
mWidth( 512 ),
mHeight( 512 ),
@@ -701,6 +635,19 @@ BOOL LLTexLayerSetInfo::parseXml(LLXmlTreeNode* node)
return TRUE;
}
+// creates visual params without generating layersets or layers
+void LLTexLayerSetInfo::createVisualParams(LLVOAvatar *avatar)
+{
+ //layer_info_list_t mLayerInfoList;
+ for (layer_info_list_t::iterator layer_iter = mLayerInfoList.begin();
+ layer_iter != mLayerInfoList.end();
+ layer_iter++)
+ {
+ LLTexLayerInfo *layer_info = *layer_iter;
+ layer_info->createVisualParams(avatar);
+ }
+}
+
//-----------------------------------------------------------------------------
// LLTexLayerSet
// An ordered set of texture layers that get composited into a single texture.
@@ -708,8 +655,7 @@ BOOL LLTexLayerSetInfo::parseXml(LLXmlTreeNode* node)
BOOL LLTexLayerSet::sHasCaches = FALSE;
-LLTexLayerSet::LLTexLayerSet( LLVOAvatar* avatar )
- :
+LLTexLayerSet::LLTexLayerSet(LLVOAvatarSelf* const avatar) :
mComposite( NULL ),
mAvatar( avatar ),
mUpdatesEnabled( FALSE ),
@@ -720,23 +666,25 @@ LLTexLayerSet::LLTexLayerSet( LLVOAvatar* avatar )
LLTexLayerSet::~LLTexLayerSet()
{
+ deleteCaches();
std::for_each(mLayerList.begin(), mLayerList.end(), DeletePointer());
- delete mComposite;
+ std::for_each(mMaskLayerList.begin(), mMaskLayerList.end(), DeletePointer());
}
//-----------------------------------------------------------------------------
// setInfo
//-----------------------------------------------------------------------------
-BOOL LLTexLayerSet::setInfo(LLTexLayerSetInfo *info)
+BOOL LLTexLayerSet::setInfo(const LLTexLayerSetInfo *info)
{
llassert(mInfo == NULL);
mInfo = info;
//mID = info->mID; // No ID
- LLTexLayerSetInfo::layer_info_list_t::iterator iter;
mLayerList.reserve(info->mLayerInfoList.size());
- for (iter = info->mLayerInfoList.begin(); iter != info->mLayerInfoList.end(); iter++)
+ for (LLTexLayerSetInfo::layer_info_list_t::const_iterator iter = info->mLayerInfoList.begin();
+ iter != info->mLayerInfoList.end();
+ iter++)
{
LLTexLayer* layer = new LLTexLayer( this );
if (!layer->setInfo(*iter))
@@ -744,8 +692,15 @@ BOOL LLTexLayerSet::setInfo(LLTexLayerSetInfo *info)
mInfo = NULL;
return FALSE;
}
+ if (!layer->isVisibilityMask())
+ {
mLayerList.push_back( layer );
}
+ else
+ {
+ mMaskLayerList.push_back(layer);
+ }
+ }
requestUpdate();
@@ -784,19 +739,26 @@ void LLTexLayerSet::deleteCaches()
LLTexLayer* layer = *iter;
layer->deleteCaches();
}
+ for (layer_list_t::iterator iter = mMaskLayerList.begin(); iter != mMaskLayerList.end(); iter++)
+ {
+ LLTexLayer* layer = *iter;
+ layer->deleteCaches();
+ }
}
// Returns TRUE if at least one packet of data has been received for each of the textures that this layerset depends on.
-BOOL LLTexLayerSet::isLocalTextureDataAvailable()
+BOOL LLTexLayerSet::isLocalTextureDataAvailable() const
{
- return mAvatar->isLocalTextureDataAvailable( this );
+ if (!mAvatar->isSelf()) return FALSE;
+ return ((LLVOAvatarSelf *)mAvatar)->isLocalTextureDataAvailable(this);
}
// Returns TRUE if all of the data for the textures that this layerset depends on have arrived.
-BOOL LLTexLayerSet::isLocalTextureDataFinal()
+BOOL LLTexLayerSet::isLocalTextureDataFinal() const
{
- return mAvatar->isLocalTextureDataFinal( this );
+ if (!mAvatar->isSelf()) return FALSE;
+ return ((LLVOAvatarSelf *)mAvatar)->isLocalTextureDataFinal(this);
}
@@ -808,62 +770,26 @@ BOOL LLTexLayerSet::render( S32 x, S32 y, S32 width, S32 height )
LLGLDepthTest gls_depth(GL_FALSE, GL_FALSE);
gGL.setColorMask(true, true);
+ BOOL render_morph = mAvatar->morphMaskNeedsUpdate(mBakedTexIndex);
+
// composite color layers
for( layer_list_t::iterator iter = mLayerList.begin(); iter != mLayerList.end(); iter++ )
{
LLTexLayer* layer = *iter;
- if( layer->getRenderPass() == RP_COLOR )
+ if (layer->getRenderPass() == LLTexLayer::RP_COLOR)
{
gGL.flush();
- success &= layer->render( x, y, width, height );
+ success &= layer->render(x, y, width, height, render_morph);
gGL.flush();
- }
- }
-
- // (Optionally) replace alpha with a single component image from a tga file.
- if( !getInfo()->mStaticAlphaFileName.empty() )
- {
- LLGLSNoAlphaTest gls_no_alpha_test;
- gGL.flush();
- gGL.setColorMask(false, true);
- gGL.setSceneBlendType(LLRender::BT_REPLACE);
-
- {
- LLImageGL* image_gl = gTexStaticImageList.getImageGL( getInfo()->mStaticAlphaFileName, TRUE );
- if( image_gl )
+ if (layer->isMorphValid())
{
- LLGLSUIDefault gls_ui;
- gGL.getTexUnit(0)->bind(image_gl);
- gGL.getTexUnit(0)->setTextureBlendType( LLTexUnit::TB_REPLACE );
- gl_rect_2d_simple_tex( width, height );
- }
- else
- {
- success = FALSE;
+ mAvatar->setMorphMasksValid(TRUE, mBakedTexIndex);
}
}
- gGL.flush();
- gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
-
- gGL.getTexUnit(0)->setTextureBlendType(LLTexUnit::TB_MULT);
- gGL.setColorMask(true, true);
- gGL.setSceneBlendType(LLRender::BT_ALPHA);
}
- else
- if( getInfo()->mClearAlpha )
- {
- // Set the alpha channel to one (clean up after previous blending)
- LLGLDisable no_alpha(GL_ALPHA_TEST);
- gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
- gGL.color4f( 0.f, 0.f, 0.f, 1.f );
- gGL.flush();
- gGL.setColorMask(false, true);
+
+ renderAlphaMaskTextures(width, height, false);
- gl_rect_2d_simple( width, height );
-
- gGL.flush();
- gGL.setColorMask(true, true);
- }
stop_glerror();
return success;
@@ -881,9 +807,9 @@ BOOL LLTexLayerSet::renderBump( S32 x, S32 y, S32 width, S32 height )
for( layer_list_t::iterator iter = mLayerList.begin(); iter != mLayerList.end(); iter++ )
{
LLTexLayer* layer = *iter;
- if( layer->getRenderPass() == RP_BUMP )
+ if (layer->getRenderPass() == LLTexLayer::RP_BUMP)
{
- success &= layer->render( x, y, width, height );
+// success &= layer->render(x, y, width, height);
}
}
@@ -901,6 +827,16 @@ BOOL LLTexLayerSet::renderBump( S32 x, S32 y, S32 width, S32 height )
return success;
}
+BOOL LLTexLayerSet::isBodyRegion(const std::string& region) const
+{
+ return mInfo->mBodyRegion == region;
+}
+
+const std::string LLTexLayerSet::getBodyRegion() const
+{
+ return mInfo->mBodyRegion;
+}
+
void LLTexLayerSet::requestUpdate()
{
if( mUpdatesEnabled )
@@ -933,8 +869,9 @@ void LLTexLayerSet::createComposite()
// Composite other avatars at reduced resolution
if( !mAvatar->isSelf() )
{
- width /= 2;
- height /= 2;
+ // TODO: replace with sanity check to ensure not called for non-self avatars
+// width /= 2;
+// height /= 2;
}
mComposite = new LLTexLayerSetBuffer( this, width, height, mHasBump );
}
@@ -944,7 +881,6 @@ void LLTexLayerSet::destroyComposite()
{
if( mComposite )
{
- delete mComposite;
mComposite = NULL;
}
}
@@ -967,12 +903,14 @@ LLTexLayerSetBuffer* LLTexLayerSet::getComposite()
return mComposite;
}
-void LLTexLayerSet::gatherAlphaMasks(U8 *data, S32 width, S32 height)
+void LLTexLayerSet::gatherMorphMaskAlpha(U8 *data, S32 width, S32 height)
{
S32 size = width * height;
memset(data, 255, width * height);
+ BOOL render_morph = mAvatar->morphMaskNeedsUpdate(mBakedTexIndex);
+
for( layer_list_t::iterator iter = mLayerList.begin(); iter != mLayerList.end(); iter++ )
{
LLTexLayer* layer = *iter;
@@ -981,8 +919,10 @@ void LLTexLayerSet::gatherAlphaMasks(U8 *data, S32 width, S32 height)
{
LLColor4 net_color;
layer->findNetColor( &net_color );
+ // TODO: eliminate need for layer morph mask valid flag
layer->invalidateMorphMasks();
- layer->renderAlphaMasks(mComposite->getOriginX(), mComposite->getOriginY(), width, height, &net_color);
+ mAvatar->invalidateMorphMasks(mBakedTexIndex);
+ layer->renderMorphMasks(mComposite->getOriginX(), mComposite->getOriginY(), width, height, net_color, render_morph);
alphaData = layer->getAlphaData();
}
if (alphaData)
@@ -997,35 +937,111 @@ void LLTexLayerSet::gatherAlphaMasks(U8 *data, S32 width, S32 height)
}
}
}
+
+ // Set alpha back to that of our alpha masks.
+ renderAlphaMaskTextures(width, height, true);
+}
+
+void LLTexLayerSet::renderAlphaMaskTextures(S32 width, S32 height, bool forceClear)
+{
+ const LLTexLayerSetInfo *info = getInfo();
+
+ gGL.setColorMask(false, true);
+ gGL.setSceneBlendType(LLRender::BT_REPLACE);
+ // (Optionally) replace alpha with a single component image from a tga file.
+ if (!info->mStaticAlphaFileName.empty() && mMaskLayerList.empty())
+ {
+ LLGLSNoAlphaTest gls_no_alpha_test;
+ gGL.flush();
+ {
+ LLViewerTexture* tex = LLTexLayerStaticImageList::getInstance()->getTexture(info->mStaticAlphaFileName, TRUE);
+ if( tex )
+ {
+ LLGLSUIDefault gls_ui;
+ gGL.getTexUnit(0)->bind(tex);
+ gGL.getTexUnit(0)->setTextureBlendType( LLTexUnit::TB_REPLACE );
+ gl_rect_2d_simple_tex( width, height );
+ }
+ }
+ gGL.flush();
+ }
+ else if (forceClear || info->mClearAlpha || (mMaskLayerList.size() > 0))
+ {
+ // Set the alpha channel to one (clean up after previous blending)
+ gGL.flush();
+ LLGLDisable no_alpha(GL_ALPHA_TEST);
+ gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
+ gGL.color4f( 0.f, 0.f, 0.f, 1.f );
+
+ gl_rect_2d_simple( width, height );
+
+ gGL.flush();
+ }
+
+ // (Optional) Mask out part of the baked texture with alpha masks
+ // will still have an effect even if mClearAlpha is set or the alpha component was replaced
+ if (mMaskLayerList.size() > 0)
+ {
+ gGL.setSceneBlendType(LLRender::BT_MULT_ALPHA);
+ gGL.getTexUnit(0)->setTextureBlendType( LLTexUnit::TB_REPLACE );
+ for (layer_list_t::iterator iter = mMaskLayerList.begin(); iter != mMaskLayerList.end(); iter++)
+ {
+ LLTexLayer* layer = *iter;
+ gGL.flush();
+ layer->blendAlphaTexture(width, height);
+ gGL.flush();
+ }
+
+ }
+
+ gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
+
+ gGL.getTexUnit(0)->setTextureBlendType(LLTexUnit::TB_MULT);
+ gGL.setColorMask(true, true);
+ gGL.setSceneBlendType(LLRender::BT_ALPHA);
}
void LLTexLayerSet::applyMorphMask(U8* tex_data, S32 width, S32 height, S32 num_components)
{
+ mAvatar->applyMorphMask(tex_data, width, height, num_components, mBakedTexIndex);
+}
+
+//-----------------------------------------------------------------------------
+// finds a specific layer based on a passed in name
+//-----------------------------------------------------------------------------
+LLTexLayer* LLTexLayerSet::findLayerByName(std::string name)
+{
for( layer_list_t::iterator iter = mLayerList.begin(); iter != mLayerList.end(); iter++ )
{
LLTexLayer* layer = *iter;
- layer->applyMorphMask(tex_data, width, height, num_components);
+
+ if (layer->getName().compare(name) == 0)
+ {
+ return layer;
+ }
}
+ return NULL;
}
+
//-----------------------------------------------------------------------------
// LLTexLayerInfo
//-----------------------------------------------------------------------------
-LLTexLayerInfo::LLTexLayerInfo( )
- :
+LLTexLayerInfo::LLTexLayerInfo() :
mWriteAllChannels( FALSE ),
- mRenderPass( RP_COLOR ),
+ mRenderPass(LLTexLayer::RP_COLOR),
mFixedColor( 0.f, 0.f, 0.f, 0.f ),
mLocalTexture( -1 ),
mStaticImageIsMask( FALSE ),
- mUseLocalTextureAlphaOnly( FALSE )
+ mUseLocalTextureAlphaOnly(FALSE),
+ mIsVisibilityMask(FALSE)
{
}
LLTexLayerInfo::~LLTexLayerInfo( )
{
- std::for_each(mColorInfoList.begin(), mColorInfoList.end(), DeletePointer());
- std::for_each(mAlphaInfoList.begin(), mAlphaInfoList.end(), DeletePointer());
+ std::for_each(mParamColorInfoList.begin(), mParamColorInfoList.end(), DeletePointer());
+ std::for_each(mParamAlphaInfoList.begin(), mParamAlphaInfoList.end(), DeletePointer());
}
BOOL LLTexLayerInfo::parseXml(LLXmlTreeNode* node)
@@ -1048,7 +1064,7 @@ BOOL LLTexLayerInfo::parseXml(LLXmlTreeNode* node)
{
if( render_pass_name == "bump" )
{
- mRenderPass = RP_BUMP;
+ mRenderPass = LLTexLayer::RP_BUMP;
}
}
@@ -1057,6 +1073,14 @@ BOOL LLTexLayerInfo::parseXml(LLXmlTreeNode* node)
static LLStdStringHandle global_color_string = LLXmlTree::addAttributeString("global_color");
node->getFastAttributeString( global_color_string, mGlobalColor );
+ // Visibility mask (optional)
+ BOOL is_visibility;
+ static LLStdStringHandle visibility_mask_string = LLXmlTree::addAttributeString("visibility_mask");
+ if (node->getFastAttributeBOOL(visibility_mask_string, is_visibility))
+ {
+ mIsVisibilityMask = is_visibility;
+ }
+
// color attribute (optional)
LLColor4U color4u;
static LLStdStringHandle fixed_color_string = LLXmlTree::addAttributeString("fixed_color");
@@ -1070,7 +1094,7 @@ BOOL LLTexLayerInfo::parseXml(LLXmlTreeNode* node)
texture_node;
texture_node = node->getNextNamedChild())
{
- std::string local_texture;
+ std::string local_texture_name;
static LLStdStringHandle tga_file_string = LLXmlTree::addAttributeString("tga_file");
static LLStdStringHandle local_texture_string = LLXmlTree::addAttributeString("local_texture");
static LLStdStringHandle file_is_mask_string = LLXmlTree::addAttributeString("file_is_mask");
@@ -1079,73 +1103,27 @@ BOOL LLTexLayerInfo::parseXml(LLXmlTreeNode* node)
{
texture_node->getFastAttributeBOOL( file_is_mask_string, mStaticImageIsMask );
}
- else if( texture_node->getFastAttributeString( local_texture_string, local_texture ) )
+ else if (texture_node->getFastAttributeString(local_texture_string, local_texture_name))
{
texture_node->getFastAttributeBOOL( local_texture_alpha_only_string, mUseLocalTextureAlphaOnly );
- if( "upper_shirt" == local_texture )
- {
- mLocalTexture = TEX_UPPER_SHIRT;
- }
- else if( "upper_bodypaint" == local_texture )
+ /* if ("upper_shirt" == local_texture_name)
+ mLocalTexture = TEX_UPPER_SHIRT; */
+ mLocalTexture = TEX_NUM_INDICES;
+ for (LLVOAvatarDictionary::Textures::const_iterator iter = LLVOAvatarDictionary::getInstance()->getTextures().begin();
+ iter != LLVOAvatarDictionary::getInstance()->getTextures().end();
+ iter++)
{
- mLocalTexture = TEX_UPPER_BODYPAINT;
- }
- else if( "lower_pants" == local_texture )
- {
- mLocalTexture = TEX_LOWER_PANTS;
- }
- else if( "lower_bodypaint" == local_texture )
- {
- mLocalTexture = TEX_LOWER_BODYPAINT;
- }
- else if( "lower_shoes" == local_texture )
+ const LLVOAvatarDictionary::TextureEntry *texture_dict = iter->second;
+ if (local_texture_name == texture_dict->mName)
{
- mLocalTexture = TEX_LOWER_SHOES;
- }
- else if( "head_bodypaint" == local_texture )
- {
- mLocalTexture = TEX_HEAD_BODYPAINT;
- }
- else if( "lower_socks" == local_texture )
- {
- mLocalTexture = TEX_LOWER_SOCKS;
- }
- else if( "upper_jacket" == local_texture )
- {
- mLocalTexture = TEX_UPPER_JACKET;
- }
- else if( "lower_jacket" == local_texture )
- {
- mLocalTexture = TEX_LOWER_JACKET;
- }
- else if( "upper_gloves" == local_texture )
- {
- mLocalTexture = TEX_UPPER_GLOVES;
- }
- else if( "upper_undershirt" == local_texture )
- {
- mLocalTexture = TEX_UPPER_UNDERSHIRT;
- }
- else if( "lower_underpants" == local_texture )
- {
- mLocalTexture = TEX_LOWER_UNDERPANTS;
- }
- else if( "eyes_iris" == local_texture )
- {
- mLocalTexture = TEX_EYES_IRIS;
+ mLocalTexture = iter->first;
+ break;
}
- else if( "skirt" == local_texture )
- {
- mLocalTexture = TEX_SKIRT;
- }
- else if( "hair_grain" == local_texture )
- {
- mLocalTexture = TEX_HAIR;
}
- else
+ if (mLocalTexture == TEX_NUM_INDICES)
{
- llwarns << "<texture> element has invalid local_texure attribute: " << mName << " " << local_texture << llendl;
+ llwarns << "<texture> element has invalid local_texure attribute: " << mName << " " << local_texture_name << llendl;
return FALSE;
}
}
@@ -1179,13 +1157,13 @@ BOOL LLTexLayerInfo::parseXml(LLXmlTreeNode* node)
if( child->getChildByName( "param_color" ) )
{
// <param><param_color/></param>
- LLTexParamColorInfo* info = new LLTexParamColorInfo( );
+ LLTexLayerParamColorInfo* info = new LLTexLayerParamColorInfo();
if (!info->parseXml(child))
{
delete info;
return FALSE;
}
- mColorInfoList.push_back( info );
+ mParamColorInfoList.push_back(info);
}
else if( child->getChildByName( "param_alpha" ) )
{
@@ -1196,13 +1174,47 @@ BOOL LLTexLayerInfo::parseXml(LLXmlTreeNode* node)
delete info;
return FALSE;
}
- mAlphaInfoList.push_back( info );
+ mParamAlphaInfoList.push_back(info);
}
}
return TRUE;
}
+BOOL LLTexLayerInfo::createVisualParams(LLVOAvatar *avatar)
+{
+ BOOL success = TRUE;
+ for (param_color_info_list_t::iterator color_info_iter = mParamColorInfoList.begin();
+ color_info_iter != mParamColorInfoList.end();
+ color_info_iter++)
+ {
+ LLTexLayerParamColorInfo * color_info = *color_info_iter;
+ LLTexLayerParamColor* param_color = new LLTexLayerParamColor(avatar);
+ if (!param_color->setInfo(color_info))
+ {
+ llwarns << "NULL TexLayer Color Param could not be added to visual param list. Deleting." << llendl;
+ delete param_color;
+ success = FALSE;
+ }
+ }
+
+ for (param_alpha_info_list_t::iterator alpha_info_iter = mParamAlphaInfoList.begin();
+ alpha_info_iter != mParamAlphaInfoList.end();
+ alpha_info_iter++)
+ {
+ LLTexLayerParamAlphaInfo * alpha_info = *alpha_info_iter;
+ LLTexLayerParamAlpha* param_alpha = new LLTexLayerParamAlpha(avatar);
+ if (!param_alpha->setInfo(alpha_info))
+ {
+ llwarns << "NULL TexLayer Alpha Param could not be added to visual param list. Deleting." << llendl;
+ delete param_alpha;
+ success = FALSE;
+ }
+ }
+
+ return success;
+}
+
//-----------------------------------------------------------------------------
// LLTexLayer
// A single texture layer, consisting of:
@@ -1216,13 +1228,23 @@ BOOL LLTexLayerInfo::parseXml(LLXmlTreeNode* node)
// * a texture entry index (TE)
// * (optional) one or more alpha parameters (weighted alpha textures)
//-----------------------------------------------------------------------------
-LLTexLayer::LLTexLayer( LLTexLayerSet* layer_set )
- :
+LLTexLayer::LLTexLayer(LLTexLayerSet* layer_set) :
mTexLayerSet( layer_set ),
mMorphMasksValid( FALSE ),
mStaticImageInvalid( FALSE ),
- mInfo( NULL )
+ mInfo(NULL),
+ mHasMorph(FALSE)
+{
+}
+
+LLTexLayer::LLTexLayer(const LLTexLayer &layer) :
+ mTexLayerSet( layer.mTexLayerSet )
{
+ setInfo(layer.getInfo());
+
+
+ mHasMorph = layer.mHasMorph;
+
}
LLTexLayer::~LLTexLayer()
@@ -1238,45 +1260,28 @@ LLTexLayer::~LLTexLayer()
U8* alpha_data = iter->second;
delete [] alpha_data;
}
+
}
//-----------------------------------------------------------------------------
// setInfo
//-----------------------------------------------------------------------------
-BOOL LLTexLayer::setInfo(LLTexLayerInfo* info)
+BOOL LLTexLayer::setInfo(const LLTexLayerInfo* info)
{
llassert(mInfo == NULL);
mInfo = info;
//mID = info->mID; // No ID
- if (info->mRenderPass == RP_BUMP)
+ if (info->mRenderPass == LLTexLayer::RP_BUMP)
mTexLayerSet->setBump(TRUE);
+ mParamColorList.reserve(mInfo->mParamColorInfoList.size());
+ for (param_color_info_list_t::const_iterator iter = mInfo->mParamColorInfoList.begin();
+ iter != mInfo->mParamColorInfoList.end();
+ iter++)
{
- LLTexLayerInfo::morph_name_list_t::iterator iter;
- for (iter = mInfo->mMorphNameList.begin(); iter != mInfo->mMorphNameList.end(); iter++)
- {
- // *FIX: we assume that the referenced visual param is a
- // morph target, need a better way of actually looking
- // this up.
- LLPolyMorphTarget *morph_param;
- std::string *name = &(iter->first);
- morph_param = (LLPolyMorphTarget *)(getTexLayerSet()->getAvatar()->getVisualParam(name->c_str()));
- if (morph_param)
- {
- BOOL invert = iter->second;
- addMaskedMorph(morph_param, invert);
- }
- }
- }
-
- {
- LLTexLayerInfo::color_info_list_t::iterator iter;
- mParamColorList.reserve(mInfo->mColorInfoList.size());
- for (iter = mInfo->mColorInfoList.begin(); iter != mInfo->mColorInfoList.end(); iter++)
- {
- LLTexParamColor* param_color = new LLTexParamColor( this );
+ LLTexLayerParamColor* param_color = new LLTexLayerParamColor(this);
if (!param_color->setInfo(*iter))
{
mInfo = NULL;
@@ -1284,11 +1289,11 @@ BOOL LLTexLayer::setInfo(LLTexLayerInfo* info)
}
mParamColorList.push_back( param_color );
}
- }
- {
- LLTexLayerInfo::alpha_info_list_t::iterator iter;
- mParamAlphaList.reserve(mInfo->mAlphaInfoList.size());
- for (iter = mInfo->mAlphaInfoList.begin(); iter != mInfo->mAlphaInfoList.end(); iter++)
+
+ mParamAlphaList.reserve(mInfo->mParamAlphaInfoList.size());
+ for (param_alpha_info_list_t::const_iterator iter = mInfo->mParamAlphaInfoList.begin();
+ iter != mInfo->mParamAlphaInfoList.end();
+ iter++)
{
LLTexLayerParamAlpha* param_alpha = new LLTexLayerParamAlpha( this );
if (!param_alpha->setInfo(*iter))
@@ -1298,84 +1303,83 @@ BOOL LLTexLayer::setInfo(LLTexLayerInfo* info)
}
mParamAlphaList.push_back( param_alpha );
}
- }
return TRUE;
}
-#if 0 // obsolete
-//-----------------------------------------------------------------------------
-// parseData
-//-----------------------------------------------------------------------------
-BOOL LLTexLayer::parseData( LLXmlTreeNode* node )
+//static
+void LLTexLayer::calculateTexLayerColor(const param_color_list_t &param_list, LLColor4 &net_color)
{
- LLTexLayerInfo *info = new LLTexLayerInfo;
-
- if (!info->parseXml(node))
+ for (param_color_list_t::const_iterator iter = param_list.begin();
+ iter != param_list.end(); iter++)
+{
+ const LLTexLayerParamColor* param = *iter;
+ LLColor4 param_net = param->getNetColor();
+ const LLTexLayerParamColorInfo *info = (LLTexLayerParamColorInfo *)param->getInfo();
+ switch(info->getOperation())
{
- delete info;
- return FALSE;
+ case LLTexLayerParamColor::OP_ADD:
+ net_color += param_net;
+ break;
+ case LLTexLayerParamColor::OP_MULTIPLY:
+ net_color = net_color * param_net;
+ break;
+ case LLTexLayerParamColor::OP_BLEND:
+ net_color = lerp(net_color, param_net, param->getWeight());
+ break;
+ default:
+ llassert(0);
+ break;
}
- if (!setInfo(info))
- {
- delete info;
- return FALSE;
}
- return TRUE;
+ net_color.clamp();
}
-#endif
-
-//-----------------------------------------------------------------------------
-
void LLTexLayer::deleteCaches()
{
- for( alpha_list_t::iterator iter = mParamAlphaList.begin();
+ for (param_alpha_list_t::iterator iter = mParamAlphaList.begin();
iter != mParamAlphaList.end(); iter++ )
{
LLTexLayerParamAlpha* param = *iter;
param->deleteCaches();
}
- mStaticImageRaw = NULL;
}
-BOOL LLTexLayer::render( S32 x, S32 y, S32 width, S32 height )
+BOOL LLTexLayer::render(S32 x, S32 y, S32 width, S32 height, BOOL render_morph)
{
LLGLEnable color_mat(GL_COLOR_MATERIAL);
gPipeline.disableLights();
- BOOL success = TRUE;
-
- BOOL color_specified = FALSE;
- BOOL alpha_mask_specified = FALSE;
-
LLColor4 net_color;
- color_specified = findNetColor( &net_color );
-
+ BOOL color_specified = findNetColor(&net_color);
+
if (mTexLayerSet->getAvatar()->mIsDummy)
{
color_specified = true;
net_color = LLVOAvatar::getDummyColor();
}
+ BOOL success = TRUE;
+
// If you can't see the layer, don't render it.
if( is_approx_zero( net_color.mV[VW] ) )
{
return success;
}
- alpha_list_t::iterator iter = mParamAlphaList.begin();
+ BOOL alpha_mask_specified = FALSE;
+ param_alpha_list_t::const_iterator iter = mParamAlphaList.begin();
if( iter != mParamAlphaList.end() )
{
// If we have alpha masks, but we're skipping all of them, skip the whole layer.
// However, we can't do this optimization if we have morph masks that need updating.
- if( mMaskedMorphs.empty() )
+ if (!mHasMorph)
{
BOOL skip_layer = TRUE;
while( iter != mParamAlphaList.end() )
{
- LLTexLayerParamAlpha* param = *iter;
+ const LLTexLayerParamAlpha* param = *iter;
if( !param->getSkip() )
{
@@ -1392,7 +1396,7 @@ BOOL LLTexLayer::render( S32 x, S32 y, S32 width, S32 height )
}
}
- renderAlphaMasks( x, y, width, height, &net_color );
+ renderMorphMasks(x, y, width, height, net_color, render_morph);
alpha_mask_specified = TRUE;
gGL.flush();
gGL.blendFunc(LLRender::BF_DEST_ALPHA, LLRender::BF_ONE_MINUS_DEST_ALPHA);
@@ -1409,16 +1413,16 @@ BOOL LLTexLayer::render( S32 x, S32 y, S32 width, S32 height )
if( (getInfo()->mLocalTexture != -1) && !getInfo()->mUseLocalTextureAlphaOnly )
{
{
- LLImageGL* image_gl = NULL;
- if( mTexLayerSet->getAvatar()->getLocalTextureGL((ETextureIndex)getInfo()->mLocalTexture, &image_gl ) )
+ LLViewerTexture* tex = NULL;
+ if( mTexLayerSet->getAvatar()->getLocalTextureGL((ETextureIndex)getInfo()->mLocalTexture, &tex ) )
{
- if( image_gl )
+ if( tex )
{
LLGLDisable alpha_test(getInfo()->mWriteAllChannels ? GL_ALPHA_TEST : 0);
- LLTexUnit::eTextureAddressMode old_mode = image_gl->getAddressMode();
+ LLTexUnit::eTextureAddressMode old_mode = tex->getAddressMode();
- gGL.getTexUnit(0)->bind(image_gl);
+ gGL.getTexUnit(0)->bind(tex);
gGL.getTexUnit(0)->setTextureAddressMode(LLTexUnit::TAM_CLAMP);
gl_rect_2d_simple_tex( width, height );
@@ -1437,10 +1441,10 @@ BOOL LLTexLayer::render( S32 x, S32 y, S32 width, S32 height )
if( !getInfo()->mStaticImageFileName.empty() )
{
{
- LLImageGL* image_gl = gTexStaticImageList.getImageGL( getInfo()->mStaticImageFileName, getInfo()->mStaticImageIsMask );
- if( image_gl )
+ LLViewerTexture* tex = LLTexLayerStaticImageList::getInstance()->getTexture(getInfo()->mStaticImageFileName, getInfo()->mStaticImageIsMask);
+ if( tex )
{
- gGL.getTexUnit(0)->bind(image_gl);
+ gGL.getTexUnit(0)->bind(tex);
gl_rect_2d_simple_tex( width, height );
gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
}
@@ -1451,14 +1455,14 @@ BOOL LLTexLayer::render( S32 x, S32 y, S32 width, S32 height )
}
}
- if( ((-1 == getInfo()->mLocalTexture) ||
+ if(((-1 == getInfo()->mLocalTexture) ||
getInfo()->mUseLocalTextureAlphaOnly) &&
getInfo()->mStaticImageFileName.empty() &&
color_specified )
{
LLGLDisable no_alpha(GL_ALPHA_TEST);
gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
- gGL.color4fv( net_color.mV);
+ gGL.color4fv( net_color.mV );
gl_rect_2d_simple( width, height );
}
@@ -1483,9 +1487,9 @@ U8* LLTexLayer::getAlphaData()
const LLUUID& uuid = mTexLayerSet->getAvatar()->getLocalTextureID((ETextureIndex)getInfo()->mLocalTexture);
alpha_mask_crc.update((U8*)(&uuid.mData), UUID_BYTES);
- for( alpha_list_t::iterator iter = mParamAlphaList.begin(); iter != mParamAlphaList.end(); iter++ )
+ for (param_alpha_list_t::const_iterator iter = mParamAlphaList.begin(); iter != mParamAlphaList.end(); iter++)
{
- LLTexLayerParamAlpha* param = *iter;
+ const LLTexLayerParamAlpha* param = *iter;
F32 param_weight = param->getWeight();
alpha_mask_crc.update((U8*)&param_weight, sizeof(F32));
}
@@ -1496,7 +1500,7 @@ U8* LLTexLayer::getAlphaData()
return (iter2 == mAlphaCache.end()) ? 0 : iter2->second;
}
-BOOL LLTexLayer::findNetColor( LLColor4* net_color )
+BOOL LLTexLayer::findNetColor(LLColor4* net_color) const
{
// Color is either:
// * one or more color parameters (weighted colors) (which may make use of a global color or fixed color)
@@ -1510,8 +1514,7 @@ BOOL LLTexLayer::findNetColor( LLColor4* net_color )
{
net_color->setVec( mTexLayerSet->getAvatar()->getGlobalColor( getInfo()->mGlobalColor ) );
}
- else
- if( getInfo()->mFixedColor.mV[VW] )
+ else if (getInfo()->mFixedColor.mV[VW])
{
net_color->setVec( getInfo()->mFixedColor );
}
@@ -1520,30 +1523,7 @@ BOOL LLTexLayer::findNetColor( LLColor4* net_color )
net_color->setVec( 0.f, 0.f, 0.f, 0.f );
}
- for( color_list_t::iterator iter = mParamColorList.begin();
- iter != mParamColorList.end(); iter++ )
- {
- LLTexParamColor* param = *iter;
- LLColor4 param_net = param->getNetColor();
- switch( param->getOperation() )
- {
- case OP_ADD:
- *net_color += param_net;
- break;
- case OP_MULTIPLY:
- net_color->mV[VX] *= param_net.mV[VX];
- net_color->mV[VY] *= param_net.mV[VY];
- net_color->mV[VZ] *= param_net.mV[VZ];
- net_color->mV[VW] *= param_net.mV[VW];
- break;
- case OP_BLEND:
- net_color->setVec( lerp(*net_color, param_net, param->getWeight()) );
- break;
- default:
- llassert(0);
- break;
- }
- }
+ calculateTexLayerColor(mParamColorList, *net_color);
return TRUE;
}
@@ -1564,8 +1544,51 @@ BOOL LLTexLayer::findNetColor( LLColor4* net_color )
return FALSE; // No need to draw a separate colored polygon
}
+BOOL LLTexLayer::blendAlphaTexture(S32 width, S32 height)
+{
+ BOOL success = TRUE;
-BOOL LLTexLayer::renderAlphaMasks( S32 x, S32 y, S32 width, S32 height, LLColor4* colorp )
+ gGL.flush();
+
+ if( !getInfo()->mStaticImageFileName.empty() )
+ {
+ LLViewerTexture* tex = LLTexLayerStaticImageList::getInstance()->getTexture( getInfo()->mStaticImageFileName, getInfo()->mStaticImageIsMask );
+ if( tex )
+ {
+ LLGLSNoAlphaTest gls_no_alpha_test;
+ gGL.getTexUnit(0)->bind(tex);
+ gl_rect_2d_simple_tex( width, height );
+ gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
+ }
+ else
+ {
+ success = FALSE;
+ }
+ }
+ else
+ {
+ if (getInfo()->mLocalTexture >=0 && getInfo()->mLocalTexture < TEX_NUM_INDICES)
+ {
+ LLViewerTexture* tex = NULL;
+ if (mTexLayerSet->getAvatar()->getLocalTextureGL((ETextureIndex)getInfo()->mLocalTexture, &tex))
+ {
+ if (tex)
+ {
+ LLGLSNoAlphaTest gls_no_alpha_test;
+ gGL.getTexUnit(0)->bind(tex);
+ gl_rect_2d_simple_tex( width, height );
+ gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
+ success = TRUE;
+ }
+ }
+ }
+ }
+
+ return success;
+}
+
+
+BOOL LLTexLayer::renderMorphMasks(S32 x, S32 y, S32 width, S32 height, const LLColor4 &layer_color, BOOL render_morph)
{
BOOL success = TRUE;
@@ -1573,9 +1596,7 @@ BOOL LLTexLayer::renderAlphaMasks( S32 x, S32 y, S32 width, S32 height, LLColor4
gGL.setColorMask(false, true);
- alpha_list_t::iterator iter = mParamAlphaList.begin();
- LLTexLayerParamAlpha* first_param = *iter;
-
+ LLTexLayerParamAlpha* first_param = *mParamAlphaList.begin();
// Note: if the first param is a mulitply, multiply against the current buffer's alpha
if( !first_param || !first_param->getMultiplyBlend() )
{
@@ -1593,8 +1614,7 @@ BOOL LLTexLayer::renderAlphaMasks( S32 x, S32 y, S32 width, S32 height, LLColor4
// Accumulate alphas
LLGLSNoAlphaTest gls_no_alpha_test;
gGL.color4f( 1.f, 1.f, 1.f, 1.f );
-
- for( iter = mParamAlphaList.begin(); iter != mParamAlphaList.end(); iter++ )
+ for (param_alpha_list_t::iterator iter = mParamAlphaList.begin(); iter != mParamAlphaList.end(); iter++)
{
LLTexLayerParamAlpha* param = *iter;
success &= param->render( x, y, width, height );
@@ -1602,22 +1622,21 @@ BOOL LLTexLayer::renderAlphaMasks( S32 x, S32 y, S32 width, S32 height, LLColor4
// Approximates a min() function
gGL.flush();
- gGL.blendFunc(LLRender::BF_DEST_ALPHA, LLRender::BF_ZERO);
+ gGL.setSceneBlendType(LLRender::BT_MULT_ALPHA);
// Accumulate the alpha component of the texture
if( getInfo()->mLocalTexture != -1 )
{
- {
- LLImageGL* image_gl = NULL;
- if( mTexLayerSet->getAvatar()->getLocalTextureGL((ETextureIndex)getInfo()->mLocalTexture, &image_gl ) )
+ LLViewerTexture* tex = NULL;
+ if( mTexLayerSet->getAvatar()->getLocalTextureGL((ETextureIndex)getInfo()->mLocalTexture, &tex ) )
{
- if( image_gl && (image_gl->getComponents() == 4) )
+ if( tex && (tex->getComponents() == 4) )
{
LLGLSNoAlphaTest gls_no_alpha_test;
- LLTexUnit::eTextureAddressMode old_mode = image_gl->getAddressMode();
+ LLTexUnit::eTextureAddressMode old_mode = tex->getAddressMode();
- gGL.getTexUnit(0)->bind(image_gl);
+ gGL.getTexUnit(0)->bind(tex);
gGL.getTexUnit(0)->setTextureAddressMode(LLTexUnit::TAM_CLAMP);
gl_rect_2d_simple_tex( width, height );
@@ -1631,19 +1650,17 @@ BOOL LLTexLayer::renderAlphaMasks( S32 x, S32 y, S32 width, S32 height, LLColor4
success = FALSE;
}
}
- }
if( !getInfo()->mStaticImageFileName.empty() )
{
- {
- LLImageGL* image_gl = gTexStaticImageList.getImageGL( getInfo()->mStaticImageFileName, getInfo()->mStaticImageIsMask );
- if( image_gl )
+ LLViewerTexture* tex = LLTexLayerStaticImageList::getInstance()->getTexture(getInfo()->mStaticImageFileName, getInfo()->mStaticImageIsMask);
+ if( tex )
{
- if( (image_gl->getComponents() == 4) ||
- ( (image_gl->getComponents() == 1) && getInfo()->mStaticImageIsMask ) )
+ if( (tex->getComponents() == 4) ||
+ ( (tex->getComponents() == 1) && getInfo()->mStaticImageIsMask ) )
{
LLGLSNoAlphaTest gls_no_alpha_test;
- gGL.getTexUnit(0)->bind(image_gl);
+ gGL.getTexUnit(0)->bind(tex);
gl_rect_2d_simple_tex( width, height );
gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
}
@@ -1653,15 +1670,14 @@ BOOL LLTexLayer::renderAlphaMasks( S32 x, S32 y, S32 width, S32 height, LLColor4
success = FALSE;
}
}
- }
// Draw a rectangle with the layer color to multiply the alpha by that color's alpha.
// Note: we're still using gGL.blendFunc( GL_DST_ALPHA, GL_ZERO );
- if( colorp->mV[VW] != 1.f )
+ if (layer_color.mV[VW] != 1.f)
{
LLGLDisable no_alpha(GL_ALPHA_TEST);
gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
- gGL.color4fv( colorp->mV );
+ gGL.color4fv(layer_color.mV);
gl_rect_2d_simple( width, height );
}
@@ -1670,34 +1686,28 @@ BOOL LLTexLayer::renderAlphaMasks( S32 x, S32 y, S32 width, S32 height, LLColor4
gGL.setColorMask(true, true);
- if (!mMorphMasksValid && !mMaskedMorphs.empty())
+ if (render_morph && mHasMorph)
{
LLCRC alpha_mask_crc;
const LLUUID& uuid = mTexLayerSet->getAvatar()->getLocalTextureID((ETextureIndex)getInfo()->mLocalTexture);
alpha_mask_crc.update((U8*)(&uuid.mData), UUID_BYTES);
- for( alpha_list_t::iterator iter = mParamAlphaList.begin(); iter != mParamAlphaList.end(); iter++ )
+ for (param_alpha_list_t::const_iterator iter = mParamAlphaList.begin(); iter != mParamAlphaList.end(); iter++)
{
- LLTexLayerParamAlpha* param = *iter;
+ const LLTexLayerParamAlpha* param = *iter;
F32 param_weight = param->getWeight();
alpha_mask_crc.update((U8*)&param_weight, sizeof(F32));
}
U32 cache_index = alpha_mask_crc.getCRC();
-
- alpha_cache_t::iterator iter2 = mAlphaCache.find(cache_index);
- U8* alpha_data;
- if (iter2 != mAlphaCache.end())
- {
- alpha_data = iter2->second;
- }
- else
+ U8* alpha_data = get_if_there(mAlphaCache,cache_index,(U8*)NULL);
+ if (!alpha_data)
{
// clear out a slot if we have filled our cache
S32 max_cache_entries = getTexLayerSet()->getAvatar()->isSelf() ? 4 : 1;
while ((S32)mAlphaCache.size() >= max_cache_entries)
{
- iter2 = mAlphaCache.begin(); // arbitrarily grab the first entry
+ alpha_cache_t::iterator iter2 = mAlphaCache.begin(); // arbitrarily grab the first entry
alpha_data = iter2->second;
delete [] alpha_data;
mAlphaCache.erase(iter2);
@@ -1710,28 +1720,12 @@ BOOL LLTexLayer::renderAlphaMasks( S32 x, S32 y, S32 width, S32 height, LLColor4
getTexLayerSet()->getAvatar()->dirtyMesh();
mMorphMasksValid = TRUE;
-
- for( morph_list_t::iterator iter3 = mMaskedMorphs.begin();
- iter3 != mMaskedMorphs.end(); iter3++ )
- {
- LLMaskedMorph* maskedMorph = &(*iter3);
- maskedMorph->mMorphTarget->applyMask(alpha_data, width, height, 1, maskedMorph->mInvert);
- }
+ getTexLayerSet()->applyMorphMask(alpha_data, width, height, 1);
}
return success;
}
-void LLTexLayer::applyMorphMask(U8* tex_data, S32 width, S32 height, S32 num_components)
-{
- for( morph_list_t::iterator iter = mMaskedMorphs.begin();
- iter != mMaskedMorphs.end(); iter++ )
- {
- LLMaskedMorph* maskedMorph = &(*iter);
- maskedMorph->mMorphTarget->applyMask(tex_data, width, height, num_components, maskedMorph->mInvert);
- }
-}
-
// Returns TRUE on success.
BOOL LLTexLayer::renderImageRaw( U8* in_data, S32 in_width, S32 in_height, S32 in_components, S32 width, S32 height, BOOL is_mask )
{
@@ -1808,666 +1802,54 @@ void LLTexLayer::requestUpdate()
mTexLayerSet->requestUpdate();
}
-void LLTexLayer::addMaskedMorph(LLPolyMorphTarget* morph_target, BOOL invert)
-{
- mMaskedMorphs.push_front(LLMaskedMorph(morph_target, invert));
-}
-
-void LLTexLayer::invalidateMorphMasks()
-{
- mMorphMasksValid = FALSE;
-}
-
-//-----------------------------------------------------------------------------
-// LLTexLayerParamAlphaInfo
-//-----------------------------------------------------------------------------
-LLTexLayerParamAlphaInfo::LLTexLayerParamAlphaInfo( )
- :
- mMultiplyBlend( FALSE ),
- mSkipIfZeroWeight( FALSE ),
- mDomain( 0.f )
-{
-}
-
-BOOL LLTexLayerParamAlphaInfo::parseXml(LLXmlTreeNode* node)
-{
- llassert( node->hasName( "param" ) && node->getChildByName( "param_alpha" ) );
-
- if( !LLViewerVisualParamInfo::parseXml(node) )
- return FALSE;
-
- LLXmlTreeNode* param_alpha_node = node->getChildByName( "param_alpha" );
- if( !param_alpha_node )
- {
- return FALSE;
- }
-
- static LLStdStringHandle tga_file_string = LLXmlTree::addAttributeString("tga_file");
- if( param_alpha_node->getFastAttributeString( tga_file_string, mStaticImageFileName ) )
- {
- // Don't load the image file until it's actually needed.
- }
-// else
-// {
-// llwarns << "<param_alpha> element is missing tga_file attribute." << llendl;
-// }
-
- static LLStdStringHandle multiply_blend_string = LLXmlTree::addAttributeString("multiply_blend");
- param_alpha_node->getFastAttributeBOOL( multiply_blend_string, mMultiplyBlend );
-
- static LLStdStringHandle skip_if_zero_string = LLXmlTree::addAttributeString("skip_if_zero");
- param_alpha_node->getFastAttributeBOOL( skip_if_zero_string, mSkipIfZeroWeight );
-
- static LLStdStringHandle domain_string = LLXmlTree::addAttributeString("domain");
- param_alpha_node->getFastAttributeF32( domain_string, mDomain );
-
- return TRUE;
-}
-
-//-----------------------------------------------------------------------------
-// LLTexLayerParamAlpha
-//-----------------------------------------------------------------------------
-
-// static
-LLTexLayerParamAlpha::param_alpha_ptr_list_t LLTexLayerParamAlpha::sInstances;
-
-// static
-void LLTexLayerParamAlpha::dumpCacheByteCount()
-{
- S32 gl_bytes = 0;
- getCacheByteCount( &gl_bytes );
- llinfos << "Processed Alpha Texture Cache GL:" << (gl_bytes/1024) << "KB" << llendl;
-}
-
-// static
-void LLTexLayerParamAlpha::getCacheByteCount( S32* gl_bytes )
-{
- *gl_bytes = 0;
-
- for( param_alpha_ptr_list_t::iterator iter = sInstances.begin();
- iter != sInstances.end(); iter++ )
- {
- LLTexLayerParamAlpha* instance = *iter;
- LLImageGL* image_gl = instance->mCachedProcessedImageGL;
- if( image_gl )
- {
- S32 bytes = (S32)image_gl->getWidth() * image_gl->getHeight() * image_gl->getComponents();
-
- if( image_gl->getHasGLTexture() )
- {
- *gl_bytes += bytes;
- }
- }
- }
-}
-
-LLTexLayerParamAlpha::LLTexLayerParamAlpha( LLTexLayer* layer )
- :
- mCachedProcessedImageGL( NULL ),
- mTexLayer( layer ),
- mNeedsCreateTexture( FALSE ),
- mStaticImageInvalid( FALSE ),
- mAvgDistortionVec(1.f, 1.f, 1.f),
- mCachedEffectiveWeight(0.f)
-{
- sInstances.push_front( this );
-}
-
-LLTexLayerParamAlpha::~LLTexLayerParamAlpha()
-{
- deleteCaches();
- sInstances.remove( this );
-}
-
-//-----------------------------------------------------------------------------
-// setInfo()
-//-----------------------------------------------------------------------------
-BOOL LLTexLayerParamAlpha::setInfo(LLTexLayerParamAlphaInfo *info)
-{
- llassert(mInfo == NULL);
- if (info->mID < 0)
- return FALSE;
- mInfo = info;
- mID = info->mID;
-
- mTexLayer->getTexLayerSet()->getAvatar()->addVisualParam( this );
- setWeight(getDefaultWeight(), FALSE );
-
- return TRUE;
-}
-
-//-----------------------------------------------------------------------------
-
-void LLTexLayerParamAlpha::deleteCaches()
-{
- mStaticImageTGA = NULL; // deletes image
- mCachedProcessedImageGL = NULL;
- mStaticImageRaw = NULL;
- mNeedsCreateTexture = FALSE;
-}
-
-void LLTexLayerParamAlpha::setWeight(F32 weight, BOOL set_by_user)
-{
- if (mIsAnimating)
- {
- return;
- }
- F32 min_weight = getMinWeight();
- F32 max_weight = getMaxWeight();
- F32 new_weight = llclamp(weight, min_weight, max_weight);
- U8 cur_u8 = F32_to_U8( mCurWeight, min_weight, max_weight );
- U8 new_u8 = F32_to_U8( new_weight, min_weight, max_weight );
- if( cur_u8 != new_u8)
- {
- mCurWeight = new_weight;
-
- LLVOAvatar* avatar = mTexLayer->getTexLayerSet()->getAvatar();
- if( avatar->getSex() & getSex() )
- {
- if ( gAgent.cameraCustomizeAvatar() )
- {
- set_by_user = FALSE;
- }
- avatar->invalidateComposite( mTexLayer->getTexLayerSet(), set_by_user );
- mTexLayer->invalidateMorphMasks();
- avatar->updateMeshTextures();
- }
- }
-}
-
-void LLTexLayerParamAlpha::setAnimationTarget(F32 target_value, BOOL set_by_user)
+const std::string& LLTexLayer::getName() const
{
- mTargetWeight = target_value;
- setWeight(target_value, set_by_user);
- mIsAnimating = TRUE;
- if (mNext)
- {
- mNext->setAnimationTarget(target_value, set_by_user);
- }
-}
-
-void LLTexLayerParamAlpha::animate(F32 delta, BOOL set_by_user)
-{
- if (mNext)
- {
- mNext->animate(delta, set_by_user);
- }
-}
-
-BOOL LLTexLayerParamAlpha::getSkip()
-{
- LLVOAvatar *avatar = mTexLayer->getTexLayerSet()->getAvatar();
-
- if( getInfo()->mSkipIfZeroWeight )
- {
- F32 effective_weight = ( avatar->getSex() & getSex() ) ? mCurWeight : getDefaultWeight();
- if (is_approx_zero( effective_weight ))
- {
- return TRUE;
- }
- }
-
- EWearableType type = (EWearableType)getWearableType();
- if( (type != WT_INVALID) && !avatar->isWearingWearableType( type ) )
- {
- return TRUE;
- }
-
- return FALSE;
-}
-
-
-BOOL LLTexLayerParamAlpha::render( S32 x, S32 y, S32 width, S32 height )
-{
- BOOL success = TRUE;
-
- F32 effective_weight = ( mTexLayer->getTexLayerSet()->getAvatar()->getSex() & getSex() ) ? mCurWeight : getDefaultWeight();
- BOOL weight_changed = effective_weight != mCachedEffectiveWeight;
- if( getSkip() )
- {
- return success;
- }
-
- gGL.flush();
- if( getInfo()->mMultiplyBlend )
- {
- gGL.blendFunc(LLRender::BF_DEST_ALPHA, LLRender::BF_ZERO); // Multiplication: approximates a min() function
- }
- else
- {
- gGL.setSceneBlendType(LLRender::BT_ADD); // Addition: approximates a max() function
- }
-
- if( !getInfo()->mStaticImageFileName.empty() && !mStaticImageInvalid)
- {
- if( mStaticImageTGA.isNull() )
- {
- // Don't load the image file until we actually need it the first time. Like now.
- mStaticImageTGA = gTexStaticImageList.getImageTGA( getInfo()->mStaticImageFileName );
- // We now have something in one of our caches
- LLTexLayerSet::sHasCaches |= mStaticImageTGA.notNull() ? TRUE : FALSE;
-
- if( mStaticImageTGA.isNull() )
- {
- llwarns << "Unable to load static file: " << getInfo()->mStaticImageFileName << llendl;
- mStaticImageInvalid = TRUE; // don't try again.
- return FALSE;
- }
- }
-
- const S32 image_tga_width = mStaticImageTGA->getWidth();
- const S32 image_tga_height = mStaticImageTGA->getHeight();
- if( !mCachedProcessedImageGL ||
- (mCachedProcessedImageGL->getWidth() != image_tga_width) ||
- (mCachedProcessedImageGL->getHeight() != image_tga_height) ||
- (weight_changed) )
- {
-// llinfos << "Building Cached Alpha: " << mName << ": (" << mStaticImageRaw->getWidth() << ", " << mStaticImageRaw->getHeight() << ") " << effective_weight << llendl;
- mCachedEffectiveWeight = effective_weight;
-
- if( !mCachedProcessedImageGL )
- {
- mCachedProcessedImageGL = new LLImageGL( image_tga_width, image_tga_height, 1, FALSE);
-
- // We now have something in one of our caches
- LLTexLayerSet::sHasCaches |= mCachedProcessedImageGL ? TRUE : FALSE;
-
- mCachedProcessedImageGL->setExplicitFormat( GL_ALPHA8, GL_ALPHA );
- }
-
- // Applies domain and effective weight to data as it is decoded. Also resizes the raw image if needed.
- mStaticImageRaw = NULL;
- mStaticImageRaw = new LLImageRaw;
- mStaticImageTGA->decodeAndProcess( mStaticImageRaw, getInfo()->mDomain, effective_weight );
- mNeedsCreateTexture = TRUE;
- }
-
- if( mCachedProcessedImageGL )
- {
- {
- // Create the GL texture, and then hang onto it for future use.
- if( mNeedsCreateTexture )
- {
- mCachedProcessedImageGL->createGLTexture(0, mStaticImageRaw);
- mNeedsCreateTexture = FALSE;
- gGL.getTexUnit(0)->bind(mCachedProcessedImageGL);
- mCachedProcessedImageGL->setAddressMode(LLTexUnit::TAM_CLAMP);
- }
-
- LLGLSNoAlphaTest gls_no_alpha_test;
- gGL.getTexUnit(0)->bind(mCachedProcessedImageGL);
- gl_rect_2d_simple_tex( width, height );
- gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
- stop_glerror();
- }
- }
-
- // Don't keep the cache for other people's avatars
- // (It's not really a "cache" in that case, but the logic is the same)
- if( !mTexLayer->getTexLayerSet()->getAvatar()->isSelf() )
- {
- mCachedProcessedImageGL = NULL;
- }
- }
- else
- {
- LLGLDisable no_alpha(GL_ALPHA_TEST);
- gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
- gGL.color4f( 0.f, 0.f, 0.f, effective_weight );
- gl_rect_2d_simple( width, height );
- }
-
- return success;
-}
-
-//-----------------------------------------------------------------------------
-// LLTexGlobalColorInfo
-//-----------------------------------------------------------------------------
-
-LLTexGlobalColorInfo::LLTexGlobalColorInfo()
-{
-}
-
-
-LLTexGlobalColorInfo::~LLTexGlobalColorInfo()
-{
- for_each(mColorInfoList.begin(), mColorInfoList.end(), DeletePointer());
+ return mInfo->mName;
}
-BOOL LLTexGlobalColorInfo::parseXml(LLXmlTreeNode* node)
+LLTexLayer::ERenderPass LLTexLayer::getRenderPass() const
{
- // name attribute
- static LLStdStringHandle name_string = LLXmlTree::addAttributeString("name");
- if( !node->getFastAttributeString( name_string, mName ) )
- {
- llwarns << "<global_color> element is missing name attribute." << llendl;
- return FALSE;
- }
- // <param> sub-element
- for (LLXmlTreeNode* child = node->getChildByName( "param" );
- child;
- child = node->getNextNamedChild())
- {
- if( child->getChildByName( "param_color" ) )
- {
- // <param><param_color/></param>
- LLTexParamColorInfo* info = new LLTexParamColorInfo();
- if (!info->parseXml(child))
- {
- delete info;
- return FALSE;
- }
- mColorInfoList.push_back( info );
- }
- }
- return TRUE;
+ return mInfo->mRenderPass;
}
-
-//-----------------------------------------------------------------------------
-// LLTexGlobalColor
-//-----------------------------------------------------------------------------
-
-LLTexGlobalColor::LLTexGlobalColor( LLVOAvatar* avatar )
- :
- mAvatar( avatar ),
- mInfo( NULL )
+const std::string& LLTexLayer::getGlobalColor() const
{
+ return mInfo->mGlobalColor;
}
-
-LLTexGlobalColor::~LLTexGlobalColor()
-{
- // mParamList are LLViewerVisualParam's and get deleted with ~LLCharacter()
- //std::for_each(mParamList.begin(), mParamList.end(), DeletePointer());
-}
-
-BOOL LLTexGlobalColor::setInfo(LLTexGlobalColorInfo *info)
-{
- llassert(mInfo == NULL);
- mInfo = info;
- //mID = info->mID; // No ID
-
- LLTexGlobalColorInfo::color_info_list_t::iterator iter;
- mParamList.reserve(mInfo->mColorInfoList.size());
- for (iter = mInfo->mColorInfoList.begin(); iter != mInfo->mColorInfoList.end(); iter++)
- {
- LLTexParamColor* param_color = new LLTexParamColor( this );
- if (!param_color->setInfo(*iter))
- {
- mInfo = NULL;
- return FALSE;
- }
- mParamList.push_back( param_color );
- }
-
- return TRUE;
-}
-
-//-----------------------------------------------------------------------------
-
-LLColor4 LLTexGlobalColor::getColor()
-{
- // Sum of color params
- if( !mParamList.empty() )
- {
- LLColor4 net_color( 0.f, 0.f, 0.f, 0.f );
-
- for( param_list_t::iterator iter = mParamList.begin();
- iter != mParamList.end(); iter++ )
- {
- LLTexParamColor* param = *iter;
- LLColor4 param_net = param->getNetColor();
- switch( param->getOperation() )
- {
- case OP_ADD:
- net_color += param_net;
- break;
- case OP_MULTIPLY:
- net_color.mV[VX] *= param_net.mV[VX];
- net_color.mV[VY] *= param_net.mV[VY];
- net_color.mV[VZ] *= param_net.mV[VZ];
- net_color.mV[VW] *= param_net.mV[VW];
- break;
- case OP_BLEND:
- net_color = lerp(net_color, param_net, param->getWeight());
- break;
- default:
- llassert(0);
- break;
- }
- }
-
- net_color.mV[VX] = llclampf( net_color.mV[VX] );
- net_color.mV[VY] = llclampf( net_color.mV[VY] );
- net_color.mV[VZ] = llclampf( net_color.mV[VZ] );
- net_color.mV[VW] = llclampf( net_color.mV[VW] );
-
- return net_color;
- }
- return LLColor4( 1.f, 1.f, 1.f, 1.f );
-}
-
-//-----------------------------------------------------------------------------
-// LLTexParamColorInfo
-//-----------------------------------------------------------------------------
-LLTexParamColorInfo::LLTexParamColorInfo()
- :
- mOperation( OP_ADD ),
- mNumColors( 0 )
-{
-}
-
-BOOL LLTexParamColorInfo::parseXml(LLXmlTreeNode *node)
+void LLTexLayer::invalidateMorphMasks()
{
- llassert( node->hasName( "param" ) && node->getChildByName( "param_color" ) );
-
- if (!LLViewerVisualParamInfo::parseXml(node))
- return FALSE;
-
- LLXmlTreeNode* param_color_node = node->getChildByName( "param_color" );
- if( !param_color_node )
- {
- return FALSE;
- }
-
- std::string op_string;
- static LLStdStringHandle operation_string = LLXmlTree::addAttributeString("operation");
- if( param_color_node->getFastAttributeString( operation_string, op_string ) )
- {
- LLStringUtil::toLower(op_string);
- if ( op_string == "add" ) mOperation = OP_ADD;
- else if ( op_string == "multiply" ) mOperation = OP_MULTIPLY;
- else if ( op_string == "blend" ) mOperation = OP_BLEND;
- }
-
- mNumColors = 0;
-
- LLColor4U color4u;
- for (LLXmlTreeNode* child = param_color_node->getChildByName( "value" );
- child;
- child = param_color_node->getNextNamedChild())
- {
- if( (mNumColors < MAX_COLOR_VALUES) )
- {
- static LLStdStringHandle color_string = LLXmlTree::addAttributeString("color");
- if( child->getFastAttributeColor4U( color_string, color4u ) )
- {
- mColors[ mNumColors ].setVec(color4u);
- mNumColors++;
- }
- }
- }
- if( !mNumColors )
- {
- llwarns << "<param_color> is missing <value> sub-elements" << llendl;
- return FALSE;
+ mMorphMasksValid = FALSE;
}
- if( (mOperation == OP_BLEND) && (mNumColors != 1) )
+BOOL LLTexLayer::isVisibilityMask() const
{
- llwarns << "<param_color> with operation\"blend\" must have exactly one <value>" << llendl;
- return FALSE;
- }
-
- return TRUE;
+ return mInfo->mIsVisibilityMask;
}
//-----------------------------------------------------------------------------
-// LLTexParamColor
+// LLTexLayerStaticImageList
//-----------------------------------------------------------------------------
-LLTexParamColor::LLTexParamColor( LLTexGlobalColor* tex_global_color )
- :
- mAvgDistortionVec(1.f, 1.f, 1.f),
- mTexGlobalColor( tex_global_color ),
- mTexLayer( NULL ),
- mAvatar( tex_global_color->getAvatar() )
-{
-}
-LLTexParamColor::LLTexParamColor( LLTexLayer* layer )
- :
- mAvgDistortionVec(1.f, 1.f, 1.f),
- mTexGlobalColor( NULL ),
- mTexLayer( layer ),
- mAvatar( layer->getTexLayerSet()->getAvatar() )
+LLTexLayerStaticImageList::LLTexLayerStaticImageList() :
+ mGLBytes(0),
+ mTGABytes(0),
+ mImageNames(16384)
{
}
-
-LLTexParamColor::~LLTexParamColor()
-{
-}
-
-//-----------------------------------------------------------------------------
-// setInfo()
-//-----------------------------------------------------------------------------
-
-BOOL LLTexParamColor::setInfo(LLTexParamColorInfo *info)
-{
- llassert(mInfo == NULL);
- if (info->mID < 0)
- return FALSE;
- mID = info->mID;
- mInfo = info;
-
- mAvatar->addVisualParam( this );
- setWeight( getDefaultWeight(), FALSE );
-
- return TRUE;
-}
-
-LLColor4 LLTexParamColor::getNetColor()
-{
- llassert( getInfo()->mNumColors >= 1 );
-
- F32 effective_weight = ( mAvatar && (mAvatar->getSex() & getSex()) ) ? mCurWeight : getDefaultWeight();
-
- S32 index_last = getInfo()->mNumColors - 1;
- F32 scaled_weight = effective_weight * index_last;
- S32 index_start = (S32) scaled_weight;
- S32 index_end = index_start + 1;
- if( index_start == index_last )
- {
- return getInfo()->mColors[index_last];
- }
- else
- {
- F32 weight = scaled_weight - index_start;
- const LLColor4 *start = &getInfo()->mColors[ index_start ];
- const LLColor4 *end = &getInfo()->mColors[ index_end ];
- return LLColor4(
- (1.f - weight) * start->mV[VX] + weight * end->mV[VX],
- (1.f - weight) * start->mV[VY] + weight * end->mV[VY],
- (1.f - weight) * start->mV[VZ] + weight * end->mV[VZ],
- (1.f - weight) * start->mV[VW] + weight * end->mV[VW] );
- }
-}
-
-void LLTexParamColor::setWeight(F32 weight, BOOL set_by_user)
-{
- if (mIsAnimating)
- {
- return;
- }
- F32 min_weight = getMinWeight();
- F32 max_weight = getMaxWeight();
- F32 new_weight = llclamp(weight, min_weight, max_weight);
- U8 cur_u8 = F32_to_U8( mCurWeight, min_weight, max_weight );
- U8 new_u8 = F32_to_U8( new_weight, min_weight, max_weight );
- if( cur_u8 != new_u8)
- {
- mCurWeight = new_weight;
-
- if( getInfo()->mNumColors <= 0 )
- {
- // This will happen when we set the default weight the first time.
- return;
- }
-
- if( mAvatar->getSex() & getSex() )
- {
- if( mTexGlobalColor )
- {
- mAvatar->onGlobalColorChanged( mTexGlobalColor, set_by_user );
- }
- else
- if( mTexLayer )
- {
- mAvatar->invalidateComposite( mTexLayer->getTexLayerSet(), set_by_user );
- }
- }
-// llinfos << "param " << mName << " = " << new_weight << llendl;
- }
-}
-
-void LLTexParamColor::setAnimationTarget(F32 target_value, BOOL set_by_user)
-{
- // set value first then set interpolating flag to ignore further updates
- mTargetWeight = target_value;
- setWeight(target_value, set_by_user);
- mIsAnimating = TRUE;
- if (mNext)
- {
- mNext->setAnimationTarget(target_value, set_by_user);
- }
-}
-
-void LLTexParamColor::animate(F32 delta, BOOL set_by_user)
-{
- if (mNext)
- {
- mNext->animate(delta, set_by_user);
- }
-}
-
-
-//-----------------------------------------------------------------------------
-// LLTexStaticImageList
-//-----------------------------------------------------------------------------
-
-// static
-LLTexStaticImageList gTexStaticImageList;
-LLStringTable LLTexStaticImageList::sImageNames(16384);
-
-LLTexStaticImageList::LLTexStaticImageList()
- :
- mGLBytes( 0 ),
- mTGABytes( 0 )
-{}
-
-LLTexStaticImageList::~LLTexStaticImageList()
+LLTexLayerStaticImageList::~LLTexLayerStaticImageList()
{
deleteCachedImages();
}
-void LLTexStaticImageList::dumpByteCount()
+void LLTexLayerStaticImageList::dumpByteCount()
{
llinfos << "Avatar Static Textures " <<
"KB GL:" << (mGLBytes / 1024) <<
"KB TGA:" << (mTGABytes / 1024) << "KB" << llendl;
}
-void LLTexStaticImageList::deleteCachedImages()
+void LLTexLayerStaticImageList::deleteCachedImages()
{
if( mGLBytes || mTGABytes )
{
@@ -2478,23 +1860,23 @@ void LLTexStaticImageList::deleteCachedImages()
//mStaticImageLists uses LLPointers, clear() will cause deletion
mStaticImageListTGA.clear();
- mStaticImageListGL.clear();
+ mStaticImageList.clear();
mGLBytes = 0;
mTGABytes = 0;
}
}
-// Note: in general, for a given image image we'll call either getImageTga() or getImageGL().
+// Note: in general, for a given image image we'll call either getImageTga() or getTexture().
// We call getImageTga() if the image is used as an alpha gradient.
-// Otherwise, we call getImageGL()
+// Otherwise, we call getTexture()
// Returns an LLImageTGA that contains the encoded data from a tga file named file_name.
// Caches the result to speed identical subsequent requests.
-LLImageTGA* LLTexStaticImageList::getImageTGA(const std::string& file_name)
+LLImageTGA* LLTexLayerStaticImageList::getImageTGA(const std::string& file_name)
{
- const char *namekey = sImageNames.addString(file_name);
- image_tga_map_t::iterator iter = mStaticImageListTGA.find(namekey);
+ const char *namekey = mImageNames.addString(file_name);
+ image_tga_map_t::const_iterator iter = mStaticImageListTGA.find(namekey);
if( iter != mStaticImageListTGA.end() )
{
return iter->second;
@@ -2517,23 +1899,21 @@ LLImageTGA* LLTexStaticImageList::getImageTGA(const std::string& file_name)
}
}
-
-
// Returns a GL Image (without a backing ImageRaw) that contains the decoded data from a tga file named file_name.
// Caches the result to speed identical subsequent requests.
-LLImageGL* LLTexStaticImageList::getImageGL(const std::string& file_name, BOOL is_mask )
+LLViewerTexture* LLTexLayerStaticImageList::getTexture(const std::string& file_name, BOOL is_mask)
{
- LLPointer<LLImageGL> image_gl;
- const char *namekey = sImageNames.addString(file_name);
+ LLPointer<LLViewerTexture> tex;
+ const char *namekey = mImageNames.addString(file_name);
- image_gl_map_t::iterator iter = mStaticImageListGL.find(namekey);
- if( iter != mStaticImageListGL.end() )
+ texture_map_t::const_iterator iter = mStaticImageList.find(namekey);
+ if( iter != mStaticImageList.end() )
{
- image_gl = iter->second;
+ tex = iter->second;
}
else
{
- image_gl = new LLImageGL( FALSE );
+ tex = LLViewerTextureManager::getLocalTexture( FALSE );
LLPointer<LLImageRaw> image_raw = new LLImageRaw;
if( loadImageRaw( file_name, image_raw ) )
{
@@ -2541,28 +1921,28 @@ LLImageGL* LLTexStaticImageList::getImageGL(const std::string& file_name, BOOL i
{
// Note: these are static, unchanging images so it's ok to assume
// that once an image is a mask it's always a mask.
- image_gl->setExplicitFormat( GL_ALPHA8, GL_ALPHA );
+ tex->setExplicitFormat( GL_ALPHA8, GL_ALPHA );
}
- image_gl->createGLTexture(0, image_raw);
+ tex->createGLTexture(0, image_raw);
- gGL.getTexUnit(0)->bind(image_gl);
- image_gl->setAddressMode(LLTexUnit::TAM_CLAMP);
+ gGL.getTexUnit(0)->bind(tex);
+ tex->setAddressMode(LLTexUnit::TAM_CLAMP);
- mStaticImageListGL [ namekey ] = image_gl;
- mGLBytes += (S32)image_gl->getWidth() * image_gl->getHeight() * image_gl->getComponents();
+ mStaticImageList [ namekey ] = tex;
+ mGLBytes += (S32)tex->getWidth() * tex->getHeight() * tex->getComponents();
}
else
{
- image_gl = NULL;
+ tex = NULL;
}
}
- return image_gl;
+ return tex;
}
// Reads a .tga file, decodes it, and puts the decoded data in image_raw.
// Returns TRUE if successful.
-BOOL LLTexStaticImageList::loadImageRaw( const std::string& file_name, LLImageRaw* image_raw )
+BOOL LLTexLayerStaticImageList::loadImageRaw(const std::string& file_name, LLImageRaw* image_raw)
{
BOOL success = FALSE;
std::string path;
@@ -2577,11 +1957,4 @@ BOOL LLTexStaticImageList::loadImageRaw( const std::string& file_name, LLImageRa
return success;
}
-//-----------------------------------------------------------------------------
-// LLMaskedMorph()
-//-----------------------------------------------------------------------------
-LLMaskedMorph::LLMaskedMorph( LLPolyMorphTarget *morph_target, BOOL invert ) : mMorphTarget(morph_target), mInvert(invert)
-{
- morph_target->addPendingMorphMask();
-}
diff --git a/indra/newview/lltexlayer.h b/indra/newview/lltexlayer.h
index 1924d0bee3..b0ac13913e 100644
--- a/indra/newview/lltexlayer.h
+++ b/indra/newview/lltexlayer.h
@@ -34,136 +34,95 @@
#define LL_LLTEXLAYER_H
#include <deque>
-#include "llassetstorage.h"
#include "lldynamictexture.h"
-#include "llrect.h"
-#include "llstring.h"
-#include "lluuid.h"
-#include "llviewerimage.h"
-#include "llviewervisualparam.h"
#include "llwearable.h"
-#include "v4color.h"
-#include "llfloater.h"
+#include "llvoavatardefines.h"
-class LLTexLayerSetInfo;
-class LLTexLayerSet;
-class LLTexLayerInfo;
-class LLTexLayer;
-class LLImageGL;
+class LLVOAvatar;
+class LLVOAvatarSelf;
class LLImageTGA;
-class LLTexGlobalColorInfo;
-class LLTexLayerParamAlphaInfo;
-class LLTexLayerParamAlpha;
-class LLTexParamColorInfo;
-class LLTexParamColor;
-class LLPolyMesh;
-class LLXmlTreeNode;
class LLImageRaw;
+class LLXmlTreeNode;
class LLPolyMorphTarget;
+class LLTexLayerSet;
+class LLTexLayerSetInfo;
+class LLTexLayerInfo;
+class LLTexLayerSetBuffer;
+class LLTexLayerParamColor;
+class LLTexLayerParamColorInfo;
+class LLTexLayerParamAlpha;
+class LLTexLayerParamAlphaInfo;
-class LLTextureCtrl;
-class LLVOAvatar;
-
-
-enum EColorOperation
-{
- OP_ADD = 0,
- OP_MULTIPLY = 1,
- OP_BLEND = 2,
- OP_COUNT = 3 // Number of operations
-};
+typedef std::vector<LLTexLayerParamColor *> param_color_list_t;
+typedef std::vector<LLTexLayerParamAlpha *> param_alpha_list_t;
+typedef std::vector<LLTexLayerParamColorInfo *> param_color_info_list_t;
+typedef std::vector<LLTexLayerParamAlphaInfo *> param_alpha_info_list_t;
//-----------------------------------------------------------------------------
-// LLTexLayerParamAlphaInfo
-//-----------------------------------------------------------------------------
-class LLTexLayerParamAlphaInfo : public LLViewerVisualParamInfo
+// LLTexLayer
+// A single texture layer
+// Only exists for llvoavatarself
+
+class LLTexLayer
{
- friend class LLTexLayerParamAlpha;
public:
- LLTexLayerParamAlphaInfo();
- /*virtual*/ ~LLTexLayerParamAlphaInfo() {};
+ enum ERenderPass
+ {
+ RP_COLOR,
+ RP_BUMP,
+ RP_SHINE
+ };
+
+ LLTexLayer(LLTexLayerSet* const layer_set);
+ LLTexLayer(const LLTexLayer &layer);
+ ~LLTexLayer();
- /*virtual*/ BOOL parseXml(LLXmlTreeNode* node);
+ const LLTexLayerInfo* getInfo() const { return mInfo; }
+ BOOL setInfo(const LLTexLayerInfo *info); // This sets mInfo and calls initialization functions
+ BOOL render(S32 x, S32 y, S32 width, S32 height, BOOL render_morph);
+ void requestUpdate();
+ LLTexLayerSet* const getTexLayerSet() const { return mTexLayerSet; }
-protected:
- std::string mStaticImageFileName;
- BOOL mMultiplyBlend;
- BOOL mSkipIfZeroWeight;
- F32 mDomain;
-};
+ void deleteCaches();
+ U8* getAlphaData();
+ void invalidateMorphMasks();
+ void setHasMorph(BOOL newval) { mHasMorph = newval; }
+ BOOL isMorphValid() { return mMorphMasksValid; }
-//-----------------------------------------------------------------------------
-// LLTexParamColorInfo
-//-----------------------------------------------------------------------------
-class LLTexParamColorInfo : public LLViewerVisualParamInfo
-{
- friend class LLTexParamColor;
+ const std::string& getName() const;
+ ERenderPass getRenderPass() const;
+ const std::string& getGlobalColor() const;
-public:
- LLTexParamColorInfo();
- virtual ~LLTexParamColorInfo() {};
- BOOL parseXml( LLXmlTreeNode* node );
-
-protected:
- enum { MAX_COLOR_VALUES = 20 };
- EColorOperation mOperation;
- LLColor4 mColors[MAX_COLOR_VALUES];
- S32 mNumColors;
-};
+ BOOL findNetColor(LLColor4* color) const;
+ BOOL renderImageRaw(U8* in_data, S32 in_width, S32 in_height, S32 in_components, S32 width, S32 height, BOOL is_mask);
+ BOOL blendAlphaTexture(S32 width, S32 height); // Multiplies a single alpha texture against the frame buffer
+ BOOL renderMorphMasks(S32 x, S32 y, S32 width, S32 height, const LLColor4 &layer_color, BOOL render_morph);
+ BOOL hasAlphaParams() const { return !mParamAlphaList.empty(); }
+ BOOL isVisibilityMask() const;
-//-----------------------------------------------------------------------------
-// LLTexGlobalColorInfo
-//-----------------------------------------------------------------------------
-class LLTexGlobalColorInfo
-{
- friend class LLTexGlobalColor;
-public:
- LLTexGlobalColorInfo();
- ~LLTexGlobalColorInfo();
+ static void calculateTexLayerColor(const param_color_list_t &param_list, LLColor4 &net_color);
- BOOL parseXml(LLXmlTreeNode* node);
-
-protected:
- typedef std::vector<LLTexParamColorInfo *> color_info_list_t;
- color_info_list_t mColorInfoList;
- std::string mName;
-};
+private:
+ LLTexLayerSet* const mTexLayerSet;
-//-----------------------------------------------------------------------------
-// LLTexLayerSetInfo
-// Containes shared layer set data
-//-----------------------------------------------------------------------------
-class LLTexLayerSetInfo
-{
- friend class LLTexLayerSet;
-public:
- LLTexLayerSetInfo();
- ~LLTexLayerSetInfo();
+ // Layers can have either mParamColorList, mGlobalColor, or mFixedColor. They are looked for in that order.
+ param_color_list_t mParamColorList;
+ // mGlobalColor name stored in mInfo
+ // mFixedColor value stored in mInfo
+ param_alpha_list_t mParamAlphaList;
- BOOL parseXml(LLXmlTreeNode* node);
+ BOOL mMorphMasksValid;
+ typedef std::map<U32, U8*> alpha_cache_t;
+ alpha_cache_t mAlphaCache;
+ BOOL mStaticImageInvalid;
-protected:
- std::string mBodyRegion;
- S32 mWidth;
- S32 mHeight;
- std::string mStaticAlphaFileName;
- BOOL mClearAlpha; // Set alpha to 1 for this layerset (if there is no mStaticAlphaFileName)
-
- typedef std::vector<LLTexLayerInfo*> layer_info_list_t;
- layer_info_list_t mLayerInfoList;
-};
+ BOOL mHasMorph;
-//-----------------------------------------------------------------------------
-// LLTexLayerInfo
-//-----------------------------------------------------------------------------
-enum ERenderPass
-{
- RP_COLOR,
- RP_BUMP,
- RP_SHINE
+ const LLTexLayerInfo *mInfo;
};
+// Make private
class LLTexLayerInfo
{
friend class LLTexLayer;
@@ -172,12 +131,13 @@ public:
~LLTexLayerInfo();
BOOL parseXml(LLXmlTreeNode* node);
+ BOOL createVisualParams(LLVOAvatar *avatar);
-protected:
+private:
std::string mName;
- BOOL mWriteAllChannels; // Don't use masking. Just write RGBA into buffer,
- ERenderPass mRenderPass;
+ BOOL mWriteAllChannels; // Don't use masking. Just write RGBA into buffer,
+ LLTexLayer::ERenderPass mRenderPass;
std::string mGlobalColor;
LLColor4 mFixedColor;
@@ -185,377 +145,200 @@ protected:
S32 mLocalTexture;
std::string mStaticImageFileName;
BOOL mStaticImageIsMask;
- BOOL mUseLocalTextureAlphaOnly; // Ignore RGB channels from the input texture. Use alpha as a mask
+ BOOL mUseLocalTextureAlphaOnly; // Ignore RGB channels from the input texture. Use alpha as a mask
+ BOOL mIsVisibilityMask;
- typedef std::vector<std::pair<std::string,BOOL> > morph_name_list_t;
- morph_name_list_t mMorphNameList;
-
- typedef std::vector<LLTexParamColorInfo*> color_info_list_t;
- color_info_list_t mColorInfoList;
-
- typedef std::vector<LLTexLayerParamAlphaInfo*> alpha_info_list_t;
- alpha_info_list_t mAlphaInfoList;
-
+ typedef std::vector< std::pair< std::string,BOOL > > morph_name_list_t;
+ morph_name_list_t mMorphNameList;
+ param_color_info_list_t mParamColorInfoList;
+ param_alpha_info_list_t mParamAlphaInfoList;
};
+//
+// LLTexLayer
//-----------------------------------------------------------------------------
-// LLTexLayerSetBuffer
-// The composite image that a LLTexLayerSet writes to. Each LLTexLayerSet has one.
-//-----------------------------------------------------------------------------
-class LLTexLayerSetBuffer : public LLDynamicTexture
-{
-public:
- LLTexLayerSetBuffer( LLTexLayerSet* owner, S32 width, S32 height, BOOL has_bump );
- virtual ~LLTexLayerSetBuffer();
-
- virtual void preRender(BOOL clear_depth);
- virtual void postRender(BOOL success);
- virtual BOOL render();
- BOOL updateImmediate();
- void bindBumpTexture( U32 stage );
- bool isInitialized(void) const;
- BOOL needsRender();
- void requestUpdate();
- void requestUpload();
- void cancelUpload();
- BOOL uploadPending() { return mUploadPending; }
- BOOL render( S32 x, S32 y, S32 width, S32 height );
- void readBackAndUpload(U8* baked_bump_data);
- void createBumpTexture() ;
-
- static void onTextureUploadComplete( const LLUUID& uuid,
- void* userdata,
- S32 result, LLExtStat ext_status);
- static void dumpTotalByteCount();
-
- virtual void restoreGLTexture() ;
- virtual void destroyGLTexture() ;
-
-private:
- void pushProjection();
- void popProjection();
-
-private:
- BOOL mHasBump ;
- BOOL mNeedsUpdate;
- BOOL mNeedsUpload;
- BOOL mUploadPending;
- LLUUID mUploadID; // Identifys the current upload process (null if none). Used to avoid overlaps (eg, when the user rapidly makes two changes outside of Face Edit)
- LLTexLayerSet* mTexLayerSet;
- LLPointer<LLImageGL> mBumpTex; // zero if none
-
- static S32 sGLByteCount;
- static S32 sGLBumpByteCount;
-};
//-----------------------------------------------------------------------------
// LLTexLayerSet
// An ordered set of texture layers that get composited into a single texture.
-//-----------------------------------------------------------------------------
+// Only exists for llvoavatarself
+
class LLTexLayerSet
{
+ friend class LLTexLayerSetBuffer;
public:
- LLTexLayerSet( LLVOAvatar* avatar );
+ LLTexLayerSet(LLVOAvatarSelf* const avatar);
~LLTexLayerSet();
- //BOOL parseData(LLXmlTreeNode* node);
- LLTexLayerSetInfo* getInfo() const { return mInfo; }
- // This sets mInfo and calls initialization functions
- BOOL setInfo(LLTexLayerSetInfo *info);
-
- BOOL render( S32 x, S32 y, S32 width, S32 height );
- BOOL renderBump( S32 x, S32 y, S32 width,S32 height );
- BOOL isBodyRegion( const std::string& region ) { return mInfo->mBodyRegion == region; }
+ const LLTexLayerSetInfo* getInfo() const { return mInfo; }
+ BOOL setInfo(const LLTexLayerSetInfo *info); // This sets mInfo and calls initialization functions
+
+ BOOL render(S32 x, S32 y, S32 width, S32 height);
+ BOOL renderBump(S32 x, S32 y, S32 width,S32 height);
+
+ BOOL isBodyRegion(const std::string& region) const;
LLTexLayerSetBuffer* getComposite();
void requestUpdate();
void requestUpload();
void cancelUpload();
- LLVOAvatar* getAvatar() { return mAvatar; }
void updateComposite();
- BOOL isLocalTextureDataAvailable();
- BOOL isLocalTextureDataFinal();
+ BOOL isLocalTextureDataAvailable() const;
+ BOOL isLocalTextureDataFinal() const;
void createComposite();
void destroyComposite();
- void setUpdatesEnabled( BOOL b );
- BOOL getUpdatesEnabled() { return mUpdatesEnabled; }
+ void setUpdatesEnabled(BOOL b);
+ BOOL getUpdatesEnabled() const { return mUpdatesEnabled; }
void deleteCaches();
- void gatherAlphaMasks(U8 *data, S32 width, S32 height);
+ void gatherMorphMaskAlpha(U8 *data, S32 width, S32 height);
void applyMorphMask(U8* tex_data, S32 width, S32 height, S32 num_components);
- const std::string getBodyRegion() { return mInfo->mBodyRegion; }
- BOOL hasComposite() { return (mComposite != NULL); }
- void setBump( BOOL b ) { mHasBump = b; }
- BOOL hasBump() { return mHasBump; }
+ void renderAlphaMaskTextures(S32 width, S32 height, bool forceClear = false);
+ LLTexLayer* findLayerByName(std::string name);
+
+ LLVOAvatarSelf* getAvatar() const { return mAvatar; }
+ const std::string getBodyRegion() const;
+ BOOL hasComposite() const { return (mComposite.notNull()); }
+ void setBump(BOOL b) { mHasBump = b; }
+ BOOL hasBump() const { return mHasBump; }
+ LLVOAvatarDefines::EBakedTextureIndex getBakedTexIndex() { return mBakedTexIndex; }
+ void setBakedTexIndex( LLVOAvatarDefines::EBakedTextureIndex index) { mBakedTexIndex = index; }
public:
static BOOL sHasCaches;
-protected:
+private:
typedef std::vector<LLTexLayer *> layer_list_t;
layer_list_t mLayerList;
- LLTexLayerSetBuffer* mComposite;
- // Backlink only; don't make this an LLPointer.
- LLVOAvatar* mAvatar;
+ layer_list_t mMaskLayerList;
+ LLPointer<LLTexLayerSetBuffer> mComposite;
+ LLVOAvatarSelf* const mAvatar; // Backlink only; don't make this an LLPointer.
BOOL mUpdatesEnabled;
BOOL mHasBump;
- LLTexLayerSetInfo *mInfo;
-};
-
-//-----------------------------------------------------------------------------
-// LLMaskedMorph
-//-----------------------------------------------------------------------------
+ LLVOAvatarDefines::EBakedTextureIndex mBakedTexIndex;
-class LLMaskedMorph
-{
-public:
- LLMaskedMorph( LLPolyMorphTarget *morph_target, BOOL invert );
-
-public:
- LLPolyMorphTarget *mMorphTarget;
- BOOL mInvert;
+ const LLTexLayerSetInfo *mInfo;
};
-//-----------------------------------------------------------------------------
-// LLTexLayer
-// A single texture layer
-//-----------------------------------------------------------------------------
-class LLTexLayer
+// Contains shared layer set data
+class LLTexLayerSetInfo
{
+ friend class LLTexLayerSet;
public:
- LLTexLayer( LLTexLayerSet* layer_set );
- ~LLTexLayer();
-
- //BOOL parseData(LLXmlTreeNode* node);
- LLTexLayerInfo* getInfo() const { return mInfo; }
- // This sets mInfo and calls initialization functions
- BOOL setInfo(LLTexLayerInfo *info);
+ LLTexLayerSetInfo();
+ ~LLTexLayerSetInfo();
- BOOL render( S32 x, S32 y, S32 width, S32 height );
- void requestUpdate();
- LLTexLayerSet* getTexLayerSet() { return mTexLayerSet; }
-
- const std::string& getName() { return mInfo->mName; }
-
- void addMaskedMorph(LLPolyMorphTarget* morph_target, BOOL invert);
- void deleteCaches();
- U8* getAlphaData();
- void applyMorphMask(U8* tex_data, S32 width, S32 height, S32 num_components);
-
- void invalidateMorphMasks();
- ERenderPass getRenderPass() { return mInfo->mRenderPass; }
- const std::string& getGlobalColor() { return mInfo->mGlobalColor; }
- BOOL findNetColor( LLColor4* color );
- BOOL renderImageRaw( U8* in_data, S32 in_width, S32 in_height, S32 in_components, S32 width, S32 height, BOOL is_mask );
- BOOL renderAlphaMasks( S32 x, S32 y, S32 width, S32 height, LLColor4* colorp );
- BOOL hasAlphaParams() { return (!mParamAlphaList.empty());}
-
-protected:
- LLTexLayerSet* mTexLayerSet;
- LLPointer<LLImageRaw> mStaticImageRaw;
-
- // Layers can have either mParamColorList, mGlobalColor, or mFixedColor. They are looked for in that order.
- typedef std::vector<LLTexParamColor *> color_list_t;
- color_list_t mParamColorList;
- // mGlobalColor name stored in mInfo
- // mFixedColor value stored in mInfo
+ BOOL parseXml(LLXmlTreeNode* node);
+ void createVisualParams(LLVOAvatar *avatar);
- typedef std::vector<LLTexLayerParamAlpha *> alpha_list_t;
- alpha_list_t mParamAlphaList;
-
+private:
+ std::string mBodyRegion;
+ S32 mWidth;
+ S32 mHeight;
+ std::string mStaticAlphaFileName;
+ BOOL mClearAlpha; // Set alpha to 1 for this layerset (if there is no mStaticAlphaFileName)
- typedef std::deque<LLMaskedMorph> morph_list_t;
- morph_list_t mMaskedMorphs;
- typedef std::map<U32, U8*> alpha_cache_t;
- alpha_cache_t mAlphaCache;
- BOOL mMorphMasksValid;
- BOOL mStaticImageInvalid;
-
- LLTexLayerInfo *mInfo;
+ typedef std::vector<LLTexLayerInfo*> layer_info_list_t;
+ layer_info_list_t mLayerInfoList;
};
-//-----------------------------------------------------------------------------
-// LLTexLayerParamAlpha
-//-----------------------------------------------------------------------------
-class LLTexLayerParamAlpha : public LLViewerVisualParam
+// The composite image that a LLTexLayerSet writes to. Each LLTexLayerSet has one.
+class LLTexLayerSetBuffer : public LLViewerDynamicTexture
{
public:
- LLTexLayerParamAlpha( LLTexLayer* layer );
- /*virtual*/ ~LLTexLayerParamAlpha();
+ LLTexLayerSetBuffer(LLTexLayerSet* const owner, S32 width, S32 height, BOOL has_bump);
+ virtual ~LLTexLayerSetBuffer();
- // Special: These functions are overridden by child classes
- LLTexLayerParamAlphaInfo* getInfo() const { return (LLTexLayerParamAlphaInfo*)mInfo; }
- // This sets mInfo and calls initialization functions
- BOOL setInfo(LLTexLayerParamAlphaInfo *info);
-
- // LLVisualParam Virtual functions
- ///*virtual*/ BOOL parseData(LLXmlTreeNode* node);
- /*virtual*/ void apply( ESex avatar_sex ) {}
- /*virtual*/ void setWeight(F32 weight, BOOL set_by_user);
- /*virtual*/ void setAnimationTarget(F32 target_value, BOOL set_by_user);
- /*virtual*/ void animate(F32 delta, BOOL set_by_user);
-
- // LLViewerVisualParam Virtual functions
- /*virtual*/ F32 getTotalDistortion() { return 1.f; }
- /*virtual*/ const LLVector3& getAvgDistortion() { return mAvgDistortionVec; }
- /*virtual*/ F32 getMaxDistortion() { return 3.f; }
- /*virtual*/ LLVector3 getVertexDistortion(S32 index, LLPolyMesh *poly_mesh) { return LLVector3(1.f, 1.f, 1.f);}
- /*virtual*/ const LLVector3* getFirstDistortion(U32 *index, LLPolyMesh **poly_mesh) { index = 0; poly_mesh = NULL; return &mAvgDistortionVec;};
- /*virtual*/ const LLVector3* getNextDistortion(U32 *index, LLPolyMesh **poly_mesh) { index = 0; poly_mesh = NULL; return NULL;};
-
- // New functions
+ virtual void preRender(BOOL clear_depth);
+ virtual void postRender(BOOL success);
+ virtual BOOL render();
+ BOOL updateImmediate();
+ void bindBumpTexture(U32 stage);
+ bool isInitialized(void) const;
+ BOOL needsRender();
+ void requestUpdate();
+ void requestUpload();
+ void cancelUpload();
+ BOOL uploadPending() { return mUploadPending; }
BOOL render( S32 x, S32 y, S32 width, S32 height );
- BOOL getSkip();
- void deleteCaches();
- LLTexLayer* getTexLayer() { return mTexLayer; }
- BOOL getMultiplyBlend() { return getInfo()->mMultiplyBlend; }
-
-protected:
- LLPointer<LLImageGL> mCachedProcessedImageGL;
- LLTexLayer* mTexLayer;
- LLPointer<LLImageTGA> mStaticImageTGA;
- LLPointer<LLImageRaw> mStaticImageRaw;
- BOOL mNeedsCreateTexture;
- BOOL mStaticImageInvalid;
- LLVector3 mAvgDistortionVec;
- F32 mCachedEffectiveWeight;
+ void readBackAndUpload(const U8* baked_bump_data);
+ void createBumpTexture();
-public:
- // Global list of instances for gathering statistics
- static void dumpCacheByteCount();
- static void getCacheByteCount( S32* gl_bytes );
-
- typedef std::list< LLTexLayerParamAlpha* > param_alpha_ptr_list_t;
- static param_alpha_ptr_list_t sInstances;
-};
+ static void onTextureUploadComplete(const LLUUID& uuid,
+ void* userdata,
+ S32 result, LLExtStat ext_status);
+ static void dumpTotalByteCount();
+ virtual void restoreGLTexture();
+ virtual void destroyGLTexture();
-//-----------------------------------------------------------------------------
-// LLTexGlobalColor
-//-----------------------------------------------------------------------------
-class LLTexGlobalColor
-{
-public:
- LLTexGlobalColor( LLVOAvatar* avatar );
- ~LLTexGlobalColor();
+private:
+ void pushProjection() const;
+ void popProjection() const;
- //BOOL parseData(LLXmlTreeNode* node);
- LLTexGlobalColorInfo* getInfo() const { return mInfo; }
- // This sets mInfo and calls initialization functions
- BOOL setInfo(LLTexGlobalColorInfo *info);
-
- void requstUpdate();
- LLVOAvatar* getAvatar() { return mAvatar; }
- LLColor4 getColor();
- const std::string& getName() { return mInfo->mName; }
+private:
+ const BOOL mHasBump;
+ LLTexLayerSet* const mTexLayerSet;
-protected:
- typedef std::vector<LLTexParamColor *> param_list_t;
- param_list_t mParamList;
- LLVOAvatar* mAvatar; // just backlink, don't LLPointer
+ BOOL mNeedsUpdate;
+ BOOL mNeedsUpload;
+ BOOL mUploadPending;
+ LLUUID mUploadID; // Identifys the current upload process (null if none). Used to avoid overlaps (eg, when the user rapidly makes two changes outside of Face Edit)
+ LLPointer<LLViewerTexture> mBumpTex; // zero if none
- LLTexGlobalColorInfo *mInfo;
+ static S32 sGLByteCount;
+ static S32 sGLBumpByteCount;
};
-
-//-----------------------------------------------------------------------------
-// LLTexParamColor
+//
+// LLTexLayerSet
//-----------------------------------------------------------------------------
-class LLTexParamColor : public LLViewerVisualParam
-{
-public:
- LLTexParamColor( LLTexGlobalColor* tex_color );
- LLTexParamColor( LLTexLayer* layer );
- /* virtual */ ~LLTexParamColor();
-
- // Special: These functions are overridden by child classes
- LLTexParamColorInfo* getInfo() const { return (LLTexParamColorInfo*)mInfo; }
- // This sets mInfo and calls initialization functions
- BOOL setInfo(LLTexParamColorInfo *info);
-
- // LLVisualParam Virtual functions
- ///*virtual*/ BOOL parseData(LLXmlTreeNode* node);
- /*virtual*/ void apply( ESex avatar_sex ) {}
- /*virtual*/ void setWeight(F32 weight, BOOL set_by_user);
- /*virtual*/ void setAnimationTarget(F32 target_value, BOOL set_by_user);
- /*virtual*/ void animate(F32 delta, BOOL set_by_user);
-
-
- // LLViewerVisualParam Virtual functions
- /*virtual*/ F32 getTotalDistortion() { return 1.f; }
- /*virtual*/ const LLVector3& getAvgDistortion() { return mAvgDistortionVec; }
- /*virtual*/ F32 getMaxDistortion() { return 3.f; }
- /*virtual*/ LLVector3 getVertexDistortion(S32 index, LLPolyMesh *poly_mesh) { return LLVector3(1.f, 1.f, 1.f); }
- /*virtual*/ const LLVector3* getFirstDistortion(U32 *index, LLPolyMesh **poly_mesh) { index = 0; poly_mesh = NULL; return &mAvgDistortionVec;};
- /*virtual*/ const LLVector3* getNextDistortion(U32 *index, LLPolyMesh **poly_mesh) { index = 0; poly_mesh = NULL; return NULL;};
-
- // New functions
- LLColor4 getNetColor();
- EColorOperation getOperation() const { return getInfo()->mOperation; }
-
-protected:
- LLVector3 mAvgDistortionVec;
- LLTexGlobalColor* mTexGlobalColor; // either has mTexGlobalColor or mTexLayer as its parent
- LLTexLayer* mTexLayer;
- LLVOAvatar* mAvatar; // redundant, but simplifies the code (don't LLPointer)
-};
-
-//-----------------------------------------------------------------------------
-// LLTexStaticImageList
//-----------------------------------------------------------------------------
+// LLTexLayerStaticImageList
+//
-class LLTexStaticImageList
+class LLTexLayerStaticImageList : public LLSingleton<LLTexLayerStaticImageList>
{
public:
- LLTexStaticImageList();
- ~LLTexStaticImageList();
+ LLTexLayerStaticImageList();
+ ~LLTexLayerStaticImageList();
- LLImageRaw* getImageRaw( const std::string& file_name );
- LLImageGL* getImageGL( const std::string& file_name, BOOL is_mask );
- LLImageTGA* getImageTGA( const std::string& file_name );
+ LLViewerTexture* getTexture(const std::string& file_name, BOOL is_mask);
+ LLImageTGA* getImageTGA(const std::string& file_name);
void deleteCachedImages();
void dumpByteCount();
private:
- BOOL loadImageRaw( const std::string& file_name, LLImageRaw* image_raw );
+ BOOL loadImageRaw(const std::string& file_name, LLImageRaw* image_raw);
private:
- static LLStringTable sImageNames;
+ LLStringTable mImageNames;
- typedef std::map< const char *, LLPointer<LLImageGL> > image_gl_map_t;
- typedef std::map< const char *, LLPointer<LLImageTGA> > image_tga_map_t;
- image_gl_map_t mStaticImageListGL;
+ typedef std::map< const char*, LLPointer<LLViewerTexture> > texture_map_t;
+ texture_map_t mStaticImageList;
+ typedef std::map< const char*, LLPointer<LLImageTGA> > image_tga_map_t;
image_tga_map_t mStaticImageListTGA;
-public:
S32 mGLBytes;
S32 mTGABytes;
};
// Used by LLTexLayerSetBuffer for a callback.
-
-// For DEV-DEV-31590, "Heap corruption and crash after outfit
-// changes", added the mLayerSet member. The current
-// LLTexLayerSetBuffer can be found by querying mLayerSet->mComposite,
-// but we still store the original mLayerSetBuffer here so we can
-// detect when an upload is out of date. This prevents a memory
-// stomp. See LLTexLayerSetBuffer::onTextureUploadComplete() for usage.
+// Note to anyone merging branches - this supercedes the previous fix
+// for DEV-31590 "Heap corruption and crash after outfit changes",
+// here and in lltexlayer.cpp. Equally correct and a bit simpler.
class LLBakedUploadData
{
public:
- LLBakedUploadData( LLVOAvatar* avatar, LLTexLayerSet* layerset, LLTexLayerSetBuffer* layerset_buffer, const LLUUID & id);
+ LLBakedUploadData(const LLVOAvatarSelf* avatar, LLTexLayerSet* layerset, const LLUUID& id);
~LLBakedUploadData() {}
- LLUUID mID;
- LLVOAvatar* mAvatar; // just backlink, don't LLPointer
- LLTexLayerSet* mLayerSet;
- LLTexLayerSetBuffer* mLayerSetBuffer;
- LLUUID mWearableAssets[WT_COUNT];
- U64 mStartTime; // Used to measure time baked texture upload requires
+ const LLUUID mID;
+ const LLVOAvatarSelf* mAvatar; // just backlink, don't LLPointer
+ LLTexLayerSet* mTexLayerSet;
+ const U64 mStartTime; // Used to measure time baked texture upload requires
};
-extern LLTexStaticImageList gTexStaticImageList;
-
#endif // LL_LLTEXLAYER_H
diff --git a/indra/newview/lltexlayerparams.cpp b/indra/newview/lltexlayerparams.cpp
new file mode 100644
index 0000000000..c9117a84a5
--- /dev/null
+++ b/indra/newview/lltexlayerparams.cpp
@@ -0,0 +1,541 @@
+/**
+ * @file lltexlayerparams.cpp
+ * @brief SERAPH - ADD IN
+ *
+ * $LicenseInfo:firstyear=2002&license=viewergpl$
+ *
+ * Copyright (c) 2002-2007, Linden Research, Inc.
+ *
+ * Second Life Viewer Source Code
+ * The source code in this file ("Source Code") is provided by Linden Lab
+ * to you under the terms of the GNU General Public License, version 2.0
+ * ("GPL"), unless you have obtained a separate licensing agreement
+ * ("Other License"), formally executed by you and Linden Lab. Terms of
+ * the GPL can be found in doc/GPL-license.txt in this distribution, or
+ * online at http://secondlife.com/developers/opensource/gplv2
+ *
+ * There are special exceptions to the terms and conditions of the GPL as
+ * it is applied to this Source Code. View the full text of the exception
+ * in the file doc/FLOSS-exception.txt in this software distribution, or
+ * online at http://secondlife.com/developers/opensource/flossexception
+ *
+ * By copying, modifying or distributing this software, you acknowledge
+ * that you have read and understood your obligations described above,
+ * and agree to abide by those obligations.
+ *
+ * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+ * COMPLETENESS OR PERFORMANCE.
+ * $/LicenseInfo$
+ */
+
+#include "llviewerprecompiledheaders.h"
+#include "llagent.h"
+#include "lltexlayer.h"
+#include "llvoavatarself.h"
+#include "lltexlayerparams.h"
+#include "llui.h"
+
+//-----------------------------------------------------------------------------
+// LLTexLayerParam
+//-----------------------------------------------------------------------------
+LLTexLayerParam::LLTexLayerParam(LLTexLayer *layer) :
+ mTexLayer(layer),
+ mAvatar(NULL)
+{
+ if (mTexLayer != NULL)
+ {
+ mAvatar = mTexLayer->getTexLayerSet()->getAvatar();
+ }
+}
+
+LLTexLayerParam::LLTexLayerParam(LLVOAvatar *avatar) :
+ mTexLayer(NULL)
+{
+ mAvatar = avatar;
+}
+
+
+BOOL LLTexLayerParam::setInfo(LLViewerVisualParamInfo *info)
+{
+ LLViewerVisualParam::setInfo(info);
+ mAvatar->addVisualParam( this);
+ return TRUE;
+}
+
+
+
+//-----------------------------------------------------------------------------
+// LLTexLayerParamAlpha
+//-----------------------------------------------------------------------------
+
+// static
+LLTexLayerParamAlpha::param_alpha_ptr_list_t LLTexLayerParamAlpha::sInstances;
+
+// static
+void LLTexLayerParamAlpha::dumpCacheByteCount()
+{
+ S32 gl_bytes = 0;
+ getCacheByteCount( &gl_bytes);
+ llinfos << "Processed Alpha Texture Cache GL:" << (gl_bytes/1024) << "KB" << llendl;
+}
+
+// static
+void LLTexLayerParamAlpha::getCacheByteCount(S32* gl_bytes)
+{
+ *gl_bytes = 0;
+
+ for (param_alpha_ptr_list_t::iterator iter = sInstances.begin();
+ iter != sInstances.end(); iter++)
+ {
+ LLTexLayerParamAlpha* instance = *iter;
+ LLViewerTexture* tex = instance->mCachedProcessedTexture;
+ if (tex)
+ {
+ S32 bytes = (S32)tex->getWidth() * tex->getHeight() * tex->getComponents();
+
+ if (tex->hasValidGLTexture())
+ {
+ *gl_bytes += bytes;
+ }
+ }
+ }
+}
+
+LLTexLayerParamAlpha::LLTexLayerParamAlpha(LLTexLayer* layer) :
+ LLTexLayerParam(layer),
+ mCachedProcessedTexture(NULL),
+ mNeedsCreateTexture(FALSE),
+ mStaticImageInvalid(FALSE),
+ mAvgDistortionVec(1.f, 1.f, 1.f),
+ mCachedEffectiveWeight(0.f)
+{
+ sInstances.push_front(this);
+}
+
+LLTexLayerParamAlpha::LLTexLayerParamAlpha(LLVOAvatar* avatar) :
+ LLTexLayerParam(avatar),
+ mCachedProcessedTexture(NULL),
+ mNeedsCreateTexture(FALSE),
+ mStaticImageInvalid(FALSE),
+ mAvgDistortionVec(1.f, 1.f, 1.f),
+ mCachedEffectiveWeight(0.f)
+{
+ sInstances.push_front(this);
+}
+
+
+LLTexLayerParamAlpha::~LLTexLayerParamAlpha()
+{
+ deleteCaches();
+ sInstances.remove(this);
+}
+
+void LLTexLayerParamAlpha::deleteCaches()
+{
+ mStaticImageTGA = NULL; // deletes image
+ mCachedProcessedTexture = NULL;
+ mStaticImageRaw = NULL;
+ mNeedsCreateTexture = FALSE;
+}
+
+BOOL LLTexLayerParamAlpha::getMultiplyBlend() const
+{
+ return ((LLTexLayerParamAlphaInfo *)getInfo())->mMultiplyBlend;
+}
+
+void LLTexLayerParamAlpha::setWeight(F32 weight, BOOL set_by_user)
+{
+ if (mIsAnimating || mTexLayer == NULL)
+ {
+ return;
+ }
+ F32 min_weight = getMinWeight();
+ F32 max_weight = getMaxWeight();
+ F32 new_weight = llclamp(weight, min_weight, max_weight);
+ U8 cur_u8 = F32_to_U8(mCurWeight, min_weight, max_weight);
+ U8 new_u8 = F32_to_U8(new_weight, min_weight, max_weight);
+ if (cur_u8 != new_u8)
+ {
+ mCurWeight = new_weight;
+
+ LLVOAvatar* avatar = mTexLayer->getTexLayerSet()->getAvatar();
+ if (avatar->getSex() & getSex())
+ {
+ if (gAgent.cameraCustomizeAvatar())
+ {
+ set_by_user = FALSE;
+ }
+ avatar->invalidateComposite(mTexLayer->getTexLayerSet(), set_by_user);
+ mTexLayer->invalidateMorphMasks();
+ avatar->updateMeshTextures();
+ }
+ }
+}
+
+void LLTexLayerParamAlpha::setAnimationTarget(F32 target_value, BOOL set_by_user)
+{
+ mTargetWeight = target_value;
+ setWeight(target_value, set_by_user);
+ mIsAnimating = TRUE;
+ if (mNext)
+ {
+ mNext->setAnimationTarget(target_value, set_by_user);
+ }
+}
+
+void LLTexLayerParamAlpha::animate(F32 delta, BOOL set_by_user)
+{
+ if (mNext)
+ {
+ mNext->animate(delta, set_by_user);
+ }
+}
+
+BOOL LLTexLayerParamAlpha::getSkip() const
+{
+ if (!mTexLayer)
+ {
+ return TRUE;
+ }
+
+ const LLVOAvatar *avatar = mTexLayer->getTexLayerSet()->getAvatar();
+
+ if (((LLTexLayerParamAlphaInfo *)getInfo())->mSkipIfZeroWeight)
+ {
+ F32 effective_weight = (avatar->getSex() & getSex()) ? mCurWeight : getDefaultWeight();
+ if (is_approx_zero(effective_weight))
+ {
+ return TRUE;
+ }
+ }
+
+ EWearableType type = (EWearableType)getWearableType();
+ if ((type != WT_INVALID) && !avatar->isWearingWearableType(type))
+ {
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+
+BOOL LLTexLayerParamAlpha::render(S32 x, S32 y, S32 width, S32 height)
+{
+ BOOL success = TRUE;
+
+ if (!mTexLayer)
+ {
+ return success;
+ }
+
+ F32 effective_weight = (mTexLayer->getTexLayerSet()->getAvatar()->getSex() & getSex()) ? mCurWeight : getDefaultWeight();
+ BOOL weight_changed = effective_weight != mCachedEffectiveWeight;
+ if (getSkip())
+ {
+ return success;
+ }
+
+ LLTexLayerParamAlphaInfo *info = (LLTexLayerParamAlphaInfo *)getInfo();
+ gGL.flush();
+ if (info->mMultiplyBlend)
+ {
+ gGL.blendFunc(LLRender::BF_DEST_ALPHA, LLRender::BF_ZERO); // Multiplication: approximates a min() function
+ }
+ else
+ {
+ gGL.setSceneBlendType(LLRender::BT_ADD); // Addition: approximates a max() function
+ }
+
+ if (!info->mStaticImageFileName.empty() && !mStaticImageInvalid)
+ {
+ if (mStaticImageTGA.isNull())
+ {
+ // Don't load the image file until we actually need it the first time. Like now.
+ mStaticImageTGA = LLTexLayerStaticImageList::getInstance()->getImageTGA(info->mStaticImageFileName);
+ // We now have something in one of our caches
+ LLTexLayerSet::sHasCaches |= mStaticImageTGA.notNull() ? TRUE : FALSE;
+
+ if (mStaticImageTGA.isNull())
+ {
+ llwarns << "Unable to load static file: " << info->mStaticImageFileName << llendl;
+ mStaticImageInvalid = TRUE; // don't try again.
+ return FALSE;
+ }
+ }
+
+ const S32 image_tga_width = mStaticImageTGA->getWidth();
+ const S32 image_tga_height = mStaticImageTGA->getHeight();
+ if (!mCachedProcessedTexture ||
+ (mCachedProcessedTexture->getWidth() != image_tga_width) ||
+ (mCachedProcessedTexture->getHeight() != image_tga_height) ||
+ (weight_changed))
+ {
+// llinfos << "Building Cached Alpha: " << mName << ": (" << mStaticImageRaw->getWidth() << ", " << mStaticImageRaw->getHeight() << ") " << effective_weight << llendl;
+ mCachedEffectiveWeight = effective_weight;
+
+ if (!mCachedProcessedTexture)
+ {
+ mCachedProcessedTexture = LLViewerTextureManager::getLocalTexture(image_tga_width, image_tga_height, 1, FALSE);
+
+ // We now have something in one of our caches
+ LLTexLayerSet::sHasCaches |= mCachedProcessedTexture ? TRUE : FALSE;
+
+ mCachedProcessedTexture->setExplicitFormat(GL_ALPHA8, GL_ALPHA);
+ }
+
+ // Applies domain and effective weight to data as it is decoded. Also resizes the raw image if needed.
+ mStaticImageRaw = NULL;
+ mStaticImageRaw = new LLImageRaw;
+ mStaticImageTGA->decodeAndProcess(mStaticImageRaw, info->mDomain, effective_weight);
+ mNeedsCreateTexture = TRUE;
+ }
+
+ if (mCachedProcessedTexture)
+ {
+ {
+ // Create the GL texture, and then hang onto it for future use.
+ if (mNeedsCreateTexture)
+ {
+ mCachedProcessedTexture->createGLTexture(0, mStaticImageRaw);
+ mNeedsCreateTexture = FALSE;
+ gGL.getTexUnit(0)->bind(mCachedProcessedTexture);
+ mCachedProcessedTexture->setAddressMode(LLTexUnit::TAM_CLAMP);
+ }
+
+ LLGLSNoAlphaTest gls_no_alpha_test;
+ gGL.getTexUnit(0)->bind(mCachedProcessedTexture);
+ gl_rect_2d_simple_tex(width, height);
+ gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
+ stop_glerror();
+ }
+ }
+
+ // Don't keep the cache for other people's avatars
+ // (It's not really a "cache" in that case, but the logic is the same)
+ if (mAvatar->isSelf())
+ {
+ mCachedProcessedTexture = NULL;
+ }
+ }
+ else
+ {
+ LLGLDisable no_alpha(GL_ALPHA_TEST);
+ gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
+ gGL.color4f(0.f, 0.f, 0.f, effective_weight);
+ gl_rect_2d_simple(width, height);
+ }
+
+ return success;
+}
+
+//-----------------------------------------------------------------------------
+// LLTexLayerParamAlphaInfo
+//-----------------------------------------------------------------------------
+LLTexLayerParamAlphaInfo::LLTexLayerParamAlphaInfo() :
+ mMultiplyBlend(FALSE),
+ mSkipIfZeroWeight(FALSE),
+ mDomain(0.f)
+{
+}
+
+BOOL LLTexLayerParamAlphaInfo::parseXml(LLXmlTreeNode* node)
+{
+ llassert(node->hasName("param") && node->getChildByName("param_alpha"));
+
+ if (!LLViewerVisualParamInfo::parseXml(node))
+ return FALSE;
+
+ LLXmlTreeNode* param_alpha_node = node->getChildByName("param_alpha");
+ if (!param_alpha_node)
+ {
+ return FALSE;
+ }
+
+ static LLStdStringHandle tga_file_string = LLXmlTree::addAttributeString("tga_file");
+ if (param_alpha_node->getFastAttributeString(tga_file_string, mStaticImageFileName))
+ {
+ // Don't load the image file until it's actually needed.
+ }
+// else
+// {
+// llwarns << "<param_alpha> element is missing tga_file attribute." << llendl;
+// }
+
+ static LLStdStringHandle multiply_blend_string = LLXmlTree::addAttributeString("multiply_blend");
+ param_alpha_node->getFastAttributeBOOL(multiply_blend_string, mMultiplyBlend);
+
+ static LLStdStringHandle skip_if_zero_string = LLXmlTree::addAttributeString("skip_if_zero");
+ param_alpha_node->getFastAttributeBOOL(skip_if_zero_string, mSkipIfZeroWeight);
+
+ static LLStdStringHandle domain_string = LLXmlTree::addAttributeString("domain");
+ param_alpha_node->getFastAttributeF32(domain_string, mDomain);
+
+ return TRUE;
+}
+
+
+
+
+LLTexLayerParamColor::LLTexLayerParamColor(LLTexLayer* layer) :
+ LLTexLayerParam(layer),
+ mAvgDistortionVec(1.f, 1.f, 1.f)
+{
+}
+
+LLTexLayerParamColor::LLTexLayerParamColor(LLVOAvatar *avatar) :
+ LLTexLayerParam(avatar),
+ mAvgDistortionVec(1.f, 1.f, 1.f)
+{
+}
+
+LLTexLayerParamColor::~LLTexLayerParamColor()
+{
+}
+
+LLColor4 LLTexLayerParamColor::getNetColor() const
+{
+ const LLTexLayerParamColorInfo *info = (LLTexLayerParamColorInfo *)getInfo();
+
+ llassert(info->mNumColors >= 1);
+
+ F32 effective_weight = (mAvatar && (mAvatar->getSex() & getSex())) ? mCurWeight : getDefaultWeight();
+
+ S32 index_last = info->mNumColors - 1;
+ F32 scaled_weight = effective_weight * index_last;
+ S32 index_start = (S32) scaled_weight;
+ S32 index_end = index_start + 1;
+ if (index_start == index_last)
+ {
+ return info->mColors[index_last];
+ }
+ else
+ {
+ F32 weight = scaled_weight - index_start;
+ const LLColor4 *start = &info->mColors[ index_start ];
+ const LLColor4 *end = &info->mColors[ index_end ];
+ return LLColor4((1.f - weight) * start->mV[VX] + weight * end->mV[VX],
+ (1.f - weight) * start->mV[VY] + weight * end->mV[VY],
+ (1.f - weight) * start->mV[VZ] + weight * end->mV[VZ],
+ (1.f - weight) * start->mV[VW] + weight * end->mV[VW]);
+ }
+}
+
+void LLTexLayerParamColor::setWeight(F32 weight, BOOL set_by_user)
+{
+ if (mIsAnimating)
+ {
+ return;
+ }
+
+ const LLTexLayerParamColorInfo *info = (LLTexLayerParamColorInfo *)getInfo();
+ F32 min_weight = getMinWeight();
+ F32 max_weight = getMaxWeight();
+ F32 new_weight = llclamp(weight, min_weight, max_weight);
+ U8 cur_u8 = F32_to_U8(mCurWeight, min_weight, max_weight);
+ U8 new_u8 = F32_to_U8(new_weight, min_weight, max_weight);
+ if (cur_u8 != new_u8)
+ {
+ mCurWeight = new_weight;
+
+ if (info->mNumColors <= 0)
+ {
+ // This will happen when we set the default weight the first time.
+ return;
+ }
+
+ if (mAvatar->getSex() & getSex())
+ {
+ onGlobalColorChanged(set_by_user);
+ if (mTexLayer)
+ {
+ mAvatar->invalidateComposite(mTexLayer->getTexLayerSet(), set_by_user);
+ }
+ }
+// llinfos << "param " << mName << " = " << new_weight << llendl;
+ }
+}
+
+void LLTexLayerParamColor::setAnimationTarget(F32 target_value, BOOL set_by_user)
+{
+ // set value first then set interpolating flag to ignore further updates
+ mTargetWeight = target_value;
+ setWeight(target_value, set_by_user);
+ mIsAnimating = TRUE;
+ if (mNext)
+ {
+ mNext->setAnimationTarget(target_value, set_by_user);
+ }
+}
+
+void LLTexLayerParamColor::animate(F32 delta, BOOL set_by_user)
+{
+ if (mNext)
+ {
+ mNext->animate(delta, set_by_user);
+ }
+}
+
+//-----------------------------------------------------------------------------
+// LLTexLayerParamColorInfo
+//-----------------------------------------------------------------------------
+LLTexLayerParamColorInfo::LLTexLayerParamColorInfo() :
+ mOperation(LLTexLayerParamColor::OP_ADD),
+ mNumColors(0)
+{
+}
+
+BOOL LLTexLayerParamColorInfo::parseXml(LLXmlTreeNode *node)
+{
+ llassert(node->hasName("param") && node->getChildByName("param_color"));
+
+ if (!LLViewerVisualParamInfo::parseXml(node))
+ return FALSE;
+
+ LLXmlTreeNode* param_color_node = node->getChildByName("param_color");
+ if (!param_color_node)
+ {
+ return FALSE;
+ }
+
+ std::string op_string;
+ static LLStdStringHandle operation_string = LLXmlTree::addAttributeString("operation");
+ if (param_color_node->getFastAttributeString(operation_string, op_string))
+ {
+ LLStringUtil::toLower(op_string);
+ if (op_string == "add") mOperation = LLTexLayerParamColor::OP_ADD;
+ else if (op_string == "multiply") mOperation = LLTexLayerParamColor::OP_MULTIPLY;
+ else if (op_string == "blend") mOperation = LLTexLayerParamColor::OP_BLEND;
+ }
+
+ mNumColors = 0;
+
+ LLColor4U color4u;
+ for (LLXmlTreeNode* child = param_color_node->getChildByName("value");
+ child;
+ child = param_color_node->getNextNamedChild())
+ {
+ if ((mNumColors < MAX_COLOR_VALUES))
+ {
+ static LLStdStringHandle color_string = LLXmlTree::addAttributeString("color");
+ if (child->getFastAttributeColor4U(color_string, color4u))
+ {
+ mColors[ mNumColors ].setVec(color4u);
+ mNumColors++;
+ }
+ }
+ }
+ if (!mNumColors)
+ {
+ llwarns << "<param_color> is missing <value> sub-elements" << llendl;
+ return FALSE;
+ }
+
+ if ((mOperation == LLTexLayerParamColor::OP_BLEND) && (mNumColors != 1))
+ {
+ llwarns << "<param_color> with operation\"blend\" must have exactly one <value>" << llendl;
+ return FALSE;
+ }
+
+ return TRUE;
+}
diff --git a/indra/newview/lltexlayerparams.h b/indra/newview/lltexlayerparams.h
new file mode 100644
index 0000000000..49feb01b5e
--- /dev/null
+++ b/indra/newview/lltexlayerparams.h
@@ -0,0 +1,180 @@
+/**
+ * @file lltexlayerparams.h
+ * @brief Texture layer parameters, used by lltexlayer.
+ *
+ * $LicenseInfo:firstyear=2002&license=viewergpl$
+ *
+ * Copyright (c) 2002-2007, Linden Research, Inc.
+ *
+ * Second Life Viewer Source Code
+ * The source code in this file ("Source Code") is provided by Linden Lab
+ * to you under the terms of the GNU General Public License, version 2.0
+ * ("GPL"), unless you have obtained a separate licensing agreement
+ * ("Other License"), formally executed by you and Linden Lab. Terms of
+ * the GPL can be found in doc/GPL-license.txt in this distribution, or
+ * online at http://secondlife.com/developers/opensource/gplv2
+ *
+ * There are special exceptions to the terms and conditions of the GPL as
+ * it is applied to this Source Code. View the full text of the exception
+ * in the file doc/FLOSS-exception.txt in this software distribution, or
+ * online at http://secondlife.com/developers/opensource/flossexception
+ *
+ * By copying, modifying or distributing this software, you acknowledge
+ * that you have read and understood your obligations described above,
+ * and agree to abide by those obligations.
+ *
+ * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+ * COMPLETENESS OR PERFORMANCE.
+ * $/LicenseInfo$
+ */
+
+#ifndef LL_LLTEXLAYERPARAMS_H
+#define LL_LLTEXLAYERPARAMS_H
+
+#include "llviewervisualparam.h"
+
+class LLTexLayer;
+class LLVOAvatar;
+
+class LLTexLayerParam : public LLViewerVisualParam
+{
+public:
+ LLTexLayerParam(LLTexLayer *layer);
+ LLTexLayerParam(LLVOAvatar *avatar);
+ /* Virtual */ BOOL setInfo(LLViewerVisualParamInfo *info);
+protected:
+ LLTexLayer* mTexLayer;
+ LLVOAvatar* mAvatar;
+};
+
+//-----------------------------------------------------------------------------
+// LLTexLayerParamAlpha
+//
+class LLTexLayerParamAlpha : public LLTexLayerParam
+{
+public:
+ LLTexLayerParamAlpha( LLTexLayer* layer );
+ LLTexLayerParamAlpha( LLVOAvatar* avatar );
+ /*virtual*/ ~LLTexLayerParamAlpha();
+
+ // LLVisualParam Virtual functions
+ ///*virtual*/ BOOL parseData(LLXmlTreeNode* node);
+ /*virtual*/ void apply( ESex avatar_sex ) {}
+ /*virtual*/ void setWeight(F32 weight, BOOL set_by_user);
+ /*virtual*/ void setAnimationTarget(F32 target_value, BOOL set_by_user);
+ /*virtual*/ void animate(F32 delta, BOOL set_by_user);
+
+ // LLViewerVisualParam Virtual functions
+ /*virtual*/ F32 getTotalDistortion() { return 1.f; }
+ /*virtual*/ const LLVector3& getAvgDistortion() { return mAvgDistortionVec; }
+ /*virtual*/ F32 getMaxDistortion() { return 3.f; }
+ /*virtual*/ LLVector3 getVertexDistortion(S32 index, LLPolyMesh *poly_mesh) { return LLVector3(1.f, 1.f, 1.f);}
+ /*virtual*/ const LLVector3* getFirstDistortion(U32 *index, LLPolyMesh **poly_mesh) { index = 0; poly_mesh = NULL; return &mAvgDistortionVec;};
+ /*virtual*/ const LLVector3* getNextDistortion(U32 *index, LLPolyMesh **poly_mesh) { index = 0; poly_mesh = NULL; return NULL;};
+
+ // New functions
+ BOOL render( S32 x, S32 y, S32 width, S32 height );
+ BOOL getSkip() const;
+ void deleteCaches();
+ BOOL getMultiplyBlend() const;
+
+private:
+ LLPointer<LLViewerTexture> mCachedProcessedTexture;
+ LLPointer<LLImageTGA> mStaticImageTGA;
+ LLPointer<LLImageRaw> mStaticImageRaw;
+ BOOL mNeedsCreateTexture;
+ BOOL mStaticImageInvalid;
+ LLVector3 mAvgDistortionVec;
+ F32 mCachedEffectiveWeight;
+
+public:
+ // Global list of instances for gathering statistics
+ static void dumpCacheByteCount();
+ static void getCacheByteCount( S32* gl_bytes );
+
+ typedef std::list< LLTexLayerParamAlpha* > param_alpha_ptr_list_t;
+ static param_alpha_ptr_list_t sInstances;
+};
+class LLTexLayerParamAlphaInfo : public LLViewerVisualParamInfo
+{
+ friend class LLTexLayerParamAlpha;
+public:
+ LLTexLayerParamAlphaInfo();
+ /*virtual*/ ~LLTexLayerParamAlphaInfo() {};
+
+ /*virtual*/ BOOL parseXml(LLXmlTreeNode* node);
+
+private:
+ std::string mStaticImageFileName;
+ BOOL mMultiplyBlend;
+ BOOL mSkipIfZeroWeight;
+ F32 mDomain;
+};
+//
+// LLTexLayerParamAlpha
+//-----------------------------------------------------------------------------
+
+//-----------------------------------------------------------------------------
+// LLTexLayerParamColor
+//
+class LLTexLayerParamColor : public LLTexLayerParam
+{
+public:
+ enum EColorOperation
+ {
+ OP_ADD = 0,
+ OP_MULTIPLY = 1,
+ OP_BLEND = 2,
+ OP_COUNT = 3 // Number of operations
+ };
+
+ LLTexLayerParamColor( LLTexLayer* layer );
+ LLTexLayerParamColor( LLVOAvatar* avatar );
+ /* virtual */ ~LLTexLayerParamColor();
+
+ // LLVisualParam Virtual functions
+ ///*virtual*/ BOOL parseData(LLXmlTreeNode* node);
+ /*virtual*/ void apply( ESex avatar_sex ) {}
+ /*virtual*/ void setWeight(F32 weight, BOOL set_by_user);
+ /*virtual*/ void setAnimationTarget(F32 target_value, BOOL set_by_user);
+ /*virtual*/ void animate(F32 delta, BOOL set_by_user);
+
+
+ // LLViewerVisualParam Virtual functions
+ /*virtual*/ F32 getTotalDistortion() { return 1.f; }
+ /*virtual*/ const LLVector3& getAvgDistortion() { return mAvgDistortionVec; }
+ /*virtual*/ F32 getMaxDistortion() { return 3.f; }
+ /*virtual*/ LLVector3 getVertexDistortion(S32 index, LLPolyMesh *poly_mesh) { return LLVector3(1.f, 1.f, 1.f); }
+ /*virtual*/ const LLVector3* getFirstDistortion(U32 *index, LLPolyMesh **poly_mesh) { index = 0; poly_mesh = NULL; return &mAvgDistortionVec;};
+ /*virtual*/ const LLVector3* getNextDistortion(U32 *index, LLPolyMesh **poly_mesh) { index = 0; poly_mesh = NULL; return NULL;};
+
+ // New functions
+ LLColor4 getNetColor() const;
+protected:
+ virtual void onGlobalColorChanged(bool set_by_user) {}
+private:
+ LLVector3 mAvgDistortionVec;
+};
+
+class LLTexLayerParamColorInfo : public LLViewerVisualParamInfo
+{
+ friend class LLTexLayerParamColor;
+
+public:
+ LLTexLayerParamColorInfo();
+ virtual ~LLTexLayerParamColorInfo() {};
+ BOOL parseXml( LLXmlTreeNode* node );
+ LLTexLayerParamColor::EColorOperation getOperation() const { return mOperation; }
+private:
+ enum { MAX_COLOR_VALUES = 20 };
+ LLTexLayerParamColor::EColorOperation mOperation;
+ LLColor4 mColors[MAX_COLOR_VALUES];
+ S32 mNumColors;
+};
+
+//
+// LLTexLayerParamColor
+//-----------------------------------------------------------------------------
+
+#endif
diff --git a/indra/newview/lltexturecache.cpp b/indra/newview/lltexturecache.cpp
index a3966ed666..1b249d75d1 100644
--- a/indra/newview/lltexturecache.cpp
+++ b/indra/newview/lltexturecache.cpp
@@ -946,7 +946,7 @@ std::string LLTextureCache::getLocalFileName(const LLUUID& id)
// Does not include extension
std::string idstr = id.asString();
// TODO: should we be storing cached textures in skin directory?
- std::string filename = gDirUtilp->getExpandedFilename(LL_PATH_SKINS, "default", "textures", idstr);
+ std::string filename = gDirUtilp->getExpandedFilename(LL_PATH_LOCAL_ASSETS, idstr);
return filename;
}
diff --git a/indra/newview/lltexturectrl.cpp b/indra/newview/lltexturectrl.cpp
index dc34c5ad37..1b47fa43c7 100644
--- a/indra/newview/lltexturectrl.cpp
+++ b/indra/newview/lltexturectrl.cpp
@@ -37,17 +37,18 @@
#include "llrender.h"
#include "llagent.h"
-#include "llviewerimagelist.h"
+#include "llviewertexturelist.h"
#include "llcheckboxctrl.h"
#include "llcombobox.h"
#include "llbutton.h"
#include "lldraghandle.h"
#include "llfocusmgr.h"
-#include "llviewerimage.h"
+#include "llviewertexture.h"
#include "llfolderview.h"
+#include "llfoldervieweventlistener.h"
#include "llinventory.h"
#include "llinventorymodel.h"
-#include "llinventoryview.h"
+#include "llfloaterinventory.h"
#include "lllineeditor.h"
#include "llui.h"
#include "llviewerinventory.h"
@@ -59,6 +60,7 @@
#include "llscrollcontainer.h"
#include "lltoolmgr.h"
#include "lltoolpipette.h"
+#include "llfiltereditor.h"
#include "lltool.h"
#include "llviewerwindow.h"
@@ -69,26 +71,9 @@
#include "lltrans.h"
-static const S32 CLOSE_BTN_WIDTH = 100;
-const S32 PIPETTE_BTN_WIDTH = 32;
static const S32 HPAD = 4;
static const S32 VPAD = 4;
static const S32 LINE = 16;
-static const S32 SMALL_BTN_WIDTH = 64;
-static const S32 TEX_PICKER_MIN_WIDTH =
- (HPAD +
- CLOSE_BTN_WIDTH +
- HPAD +
- CLOSE_BTN_WIDTH +
- HPAD +
- SMALL_BTN_WIDTH +
- HPAD +
- SMALL_BTN_WIDTH +
- HPAD +
- 30 +
- RESIZE_HANDLE_WIDTH * 2);
-static const S32 CLEAR_BTN_WIDTH = 50;
-static const S32 TEX_PICKER_MIN_HEIGHT = 290;
static const S32 FOOTER_HEIGHT = 100;
static const S32 BORDER_PAD = HPAD;
static const S32 TEXTURE_INVENTORY_PADDING = 30;
@@ -108,7 +93,6 @@ class LLFloaterTexturePicker : public LLFloater
public:
LLFloaterTexturePicker(
LLTextureCtrl* owner,
- const LLRect& rect,
const std::string& label,
PermissionMask immediate_filter_perm_mask,
PermissionMask non_immediate_filter_perm_mask,
@@ -126,7 +110,6 @@ public:
virtual BOOL handleKeyHere(KEY key, MASK mask);
// LLFloater overrides
- virtual void onClose(bool app_quitting);
virtual BOOL postBuild();
// New functions
@@ -136,8 +119,6 @@ public:
const LLUUID& findItemID(const LLUUID& asset_id, BOOL copyable_only);
void setCanApplyImmediately(BOOL b);
- void setDirty( BOOL b ) { mIsDirty = b; }
- BOOL isDirty() const { return mIsDirty; }
void setActive( BOOL active );
LLTextureCtrl* getOwner() const { return mOwner; }
@@ -147,23 +128,25 @@ public:
PermissionMask getFilterPermMask();
void updateFilterPermMask();
void commitIfImmediateSet();
-
+
+ void onFilterEdit(const std::string& search_string );
+ void onClose();
+
static void onBtnSetToDefault( void* userdata );
static void onBtnSelect( void* userdata );
static void onBtnCancel( void* userdata );
- static void onBtnPipette( void* userdata );
+ void onBtnPipette( );
//static void onBtnRevert( void* userdata );
static void onBtnWhite( void* userdata );
static void onBtnNone( void* userdata );
static void onBtnClear( void* userdata );
- static void onSelectionChange(const std::deque<LLFolderViewItem*> &items, BOOL user_action, void* data);
+ void onSelectionChange(const std::deque<LLFolderViewItem*> &items, BOOL user_action);
static void onShowFolders(LLUICtrl* ctrl, void* userdata);
static void onApplyImmediateCheck(LLUICtrl* ctrl, void* userdata);
- static void onSearchEdit(const std::string& search_string, void* user_data );
- static void onTextureSelect( const LLTextureEntry& te, void *data );
+ void onTextureSelect( const LLTextureEntry& te );
protected:
- LLPointer<LLViewerImage> mTexturep;
+ LLPointer<LLViewerTexture> mTexturep;
LLTextureCtrl* mOwner;
LLUUID mImageAssetID; // Currently selected texture
@@ -179,10 +162,9 @@ protected:
LLTextBox* mResolutionLabel;
std::string mPendingName;
- BOOL mIsDirty;
BOOL mActive;
- LLSearchEditor* mSearchEdit;
+ LLFilterEditor* mFilterEdit;
LLInventoryPanel* mInventoryPanel;
PermissionMask mImmediateFilterPermMask;
PermissionMask mNonImmediateFilterPermMask;
@@ -194,18 +176,12 @@ protected:
LLFloaterTexturePicker::LLFloaterTexturePicker(
LLTextureCtrl* owner,
- const LLRect& rect,
const std::string& label,
PermissionMask immediate_filter_perm_mask,
PermissionMask non_immediate_filter_perm_mask,
BOOL can_apply_immediately,
const std::string& fallback_image_name)
- :
- LLFloater( std::string("texture picker"),
- rect,
- std::string( "Pick: " ) + label,
- TRUE,
- TEX_PICKER_MIN_WIDTH, TEX_PICKER_MIN_HEIGHT ),
+: LLFloater(LLSD()),
mOwner( owner ),
mImageAssetID( owner->getImageAssetID() ),
mFallbackImageName( fallback_image_name ),
@@ -214,78 +190,15 @@ LLFloaterTexturePicker::LLFloaterTexturePicker(
mLabel(label),
mTentativeLabel(NULL),
mResolutionLabel(NULL),
- mIsDirty( FALSE ),
mActive( TRUE ),
- mSearchEdit(NULL),
+ mFilterEdit(NULL),
mImmediateFilterPermMask(immediate_filter_perm_mask),
mNonImmediateFilterPermMask(non_immediate_filter_perm_mask),
mContextConeOpacity(0.f)
{
- LLUICtrlFactory::getInstance()->buildFloater(this,"floater_texture_ctrl.xml");
-
- mTentativeLabel = getChild<LLTextBox>("Multiple");
-
- mResolutionLabel = getChild<LLTextBox>("unknown");
-
-
- childSetAction("Default",LLFloaterTexturePicker::onBtnSetToDefault,this);
- childSetAction("None", LLFloaterTexturePicker::onBtnNone,this);
- childSetAction("Blank", LLFloaterTexturePicker::onBtnWhite,this);
-
-
- childSetCommitCallback("show_folders_check", onShowFolders, this);
- childSetVisible("show_folders_check", FALSE);
-
- mSearchEdit = getChild<LLSearchEditor>("inventory search editor");
- mSearchEdit->setSearchCallback(onSearchEdit, this);
-
- mInventoryPanel = getChild<LLInventoryPanel>("inventory panel");
-
- if(mInventoryPanel)
- {
- U32 filter_types = 0x0;
- filter_types |= 0x1 << LLInventoryType::IT_TEXTURE;
- filter_types |= 0x1 << LLInventoryType::IT_SNAPSHOT;
-
- mInventoryPanel->setFilterTypes(filter_types);
- //mInventoryPanel->setFilterPermMask(getFilterPermMask()); //Commented out due to no-copy texture loss.
- mInventoryPanel->setFilterPermMask(immediate_filter_perm_mask);
- mInventoryPanel->setSelectCallback(onSelectionChange, this);
- mInventoryPanel->setShowFolderState(LLInventoryFilter::SHOW_NON_EMPTY_FOLDERS);
- mInventoryPanel->setAllowMultiSelect(FALSE);
-
- // store this filter as the default one
- mInventoryPanel->getRootFolder()->getFilter()->markDefault();
-
- // Commented out to stop opening all folders with textures
- // mInventoryPanel->openDefaultFolderForType(LLAssetType::AT_TEXTURE);
-
- // don't put keyboard focus on selected item, because the selection callback
- // will assume that this was user input
- mInventoryPanel->setSelection(findItemID(mImageAssetID, FALSE), TAKE_FOCUS_NO);
- }
-
mCanApplyImmediately = can_apply_immediately;
- mNoCopyTextureSelected = FALSE;
-
- childSetValue("apply_immediate_check", gSavedSettings.getBOOL("ApplyTextureImmediately"));
- childSetCommitCallback("apply_immediate_check", onApplyImmediateCheck, this);
-
- if (!can_apply_immediately)
- {
- childSetEnabled("show_folders_check", FALSE);
- }
-
- childSetAction("Pipette", LLFloaterTexturePicker::onBtnPipette,this);
- childSetAction("Cancel", LLFloaterTexturePicker::onBtnCancel,this);
- childSetAction("Select", LLFloaterTexturePicker::onBtnSelect,this);
-
- // update permission filter once UI is fully initialized
- updateFilterPermMask();
-
+ LLUICtrlFactory::getInstance()->buildFloater(this,"floater_texture_ctrl.xml",NULL);
setCanMinimize(FALSE);
-
- mSavedFolderState.setApply(FALSE);
}
LLFloaterTexturePicker::~LLFloaterTexturePicker()
@@ -297,7 +210,7 @@ void LLFloaterTexturePicker::setImageID(const LLUUID& image_id)
if( mImageAssetID != image_id && mActive)
{
mNoCopyTextureSelected = FALSE;
- mIsDirty = TRUE;
+ mViewModel->setDirty(); // *TODO: shouldn't we be using setValue() here?
mImageAssetID = image_id;
LLUUID item_id = findItemID(mImageAssetID, FALSE);
if (item_id.isNull())
@@ -350,9 +263,9 @@ void LLFloaterTexturePicker::updateImageStats()
if (mTexturep.notNull())
{
//RN: have we received header data for this image?
- if (mTexturep->getWidth(0) > 0 && mTexturep->getHeight(0) > 0)
+ if (mTexturep->getFullWidth() > 0 && mTexturep->getFullHeight() > 0)
{
- std::string formatted_dims = llformat("%d x %d", mTexturep->getWidth(0),mTexturep->getHeight(0));
+ std::string formatted_dims = llformat("%d x %d", mTexturep->getFullWidth(),mTexturep->getFullHeight());
mResolutionLabel->setTextArg("[DIMENSIONS]", formatted_dims);
}
else
@@ -360,6 +273,10 @@ void LLFloaterTexturePicker::updateImageStats()
mResolutionLabel->setTextArg("[DIMENSIONS]", std::string("[? x ?]"));
}
}
+ else
+ {
+ mResolutionLabel->setTextArg("[DIMENSIONS]", std::string(""));
+ }
}
// virtual
@@ -418,15 +335,15 @@ BOOL LLFloaterTexturePicker::handleKeyHere(KEY key, MASK mask)
{
LLFolderView* root_folder = mInventoryPanel->getRootFolder();
- if (root_folder && mSearchEdit)
+ if (root_folder && mFilterEdit)
{
- if (mSearchEdit->hasFocus()
+ if (mFilterEdit->hasFocus()
&& (key == KEY_RETURN || key == KEY_DOWN)
&& mask == MASK_NONE)
{
if (!root_folder->getCurSelectedItem())
{
- LLFolderViewItem* itemp = root_folder->getItemByID(gAgent.getInventoryRootID());
+ LLFolderViewItem* itemp = root_folder->getItemByID(gInventory.getRootFolderID());
if (itemp)
{
root_folder->setSelection(itemp, FALSE, FALSE);
@@ -435,7 +352,7 @@ BOOL LLFloaterTexturePicker::handleKeyHere(KEY key, MASK mask)
root_folder->scrollToShowSelection();
// move focus to inventory proper
- root_folder->setFocus(TRUE);
+ mInventoryPanel->setFocus(TRUE);
// treat this as a user selection of the first filtered result
commitIfImmediateSet();
@@ -443,29 +360,29 @@ BOOL LLFloaterTexturePicker::handleKeyHere(KEY key, MASK mask)
return TRUE;
}
- if (root_folder->hasFocus() && key == KEY_UP)
+ if (mInventoryPanel->hasFocus() && key == KEY_UP)
{
- mSearchEdit->focusFirstItem(TRUE);
+ mFilterEdit->focusFirstItem(TRUE);
}
}
return LLFloater::handleKeyHere(key, mask);
}
-// virtual
-void LLFloaterTexturePicker::onClose(bool app_quitting)
+void LLFloaterTexturePicker::onClose()
{
if (mOwner)
{
mOwner->onFloaterClose();
}
stopUsingPipette();
- destroy();
}
// virtual
BOOL LLFloaterTexturePicker::postBuild()
{
+ mCloseSignal.connect(boost::bind(&LLFloaterTexturePicker::onClose, this));
+
LLFloater::postBuild();
if (!mLabel.empty())
@@ -474,13 +391,76 @@ BOOL LLFloaterTexturePicker::postBuild()
setTitle(pick + mLabel);
}
+ mTentativeLabel = getChild<LLTextBox>("Multiple");
+
+ mResolutionLabel = getChild<LLTextBox>("unknown");
+
+
+ childSetAction("Default",LLFloaterTexturePicker::onBtnSetToDefault,this);
+ childSetAction("None", LLFloaterTexturePicker::onBtnNone,this);
+ childSetAction("Blank", LLFloaterTexturePicker::onBtnWhite,this);
+
+
+ childSetCommitCallback("show_folders_check", onShowFolders, this);
+ childSetVisible("show_folders_check", FALSE);
+
+ mFilterEdit = getChild<LLFilterEditor>("inventory search editor");
+ mFilterEdit->setCommitCallback(boost::bind(&LLFloaterTexturePicker::onFilterEdit, this, _2));
+
+ mInventoryPanel = getChild<LLInventoryPanel>("inventory panel");
+
+ if(mInventoryPanel)
+ {
+ U32 filter_types = 0x0;
+ filter_types |= 0x1 << LLInventoryType::IT_TEXTURE;
+ filter_types |= 0x1 << LLInventoryType::IT_SNAPSHOT;
+
+ mInventoryPanel->setFilterTypes(filter_types);
+ //mInventoryPanel->setFilterPermMask(getFilterPermMask()); //Commented out due to no-copy texture loss.
+ mInventoryPanel->setFilterPermMask(mImmediateFilterPermMask);
+ mInventoryPanel->setSelectCallback(boost::bind(&LLFloaterTexturePicker::onSelectionChange, this, _1, _2));
+ mInventoryPanel->setShowFolderState(LLInventoryFilter::SHOW_NON_EMPTY_FOLDERS);
+ mInventoryPanel->setAllowMultiSelect(FALSE);
+
+ // store this filter as the default one
+ mInventoryPanel->getRootFolder()->getFilter()->markDefault();
+
+ // Commented out to stop opening all folders with textures
+ // mInventoryPanel->openDefaultFolderForType(LLAssetType::AT_TEXTURE);
+
+ // don't put keyboard focus on selected item, because the selection callback
+ // will assume that this was user input
+ mInventoryPanel->setSelection(findItemID(mImageAssetID, FALSE), TAKE_FOCUS_NO);
+ }
+
+
+ mNoCopyTextureSelected = FALSE;
+
+ childSetValue("apply_immediate_check", gSavedSettings.getBOOL("ApplyTextureImmediately"));
+ childSetCommitCallback("apply_immediate_check", onApplyImmediateCheck, this);
+
+ if (!mCanApplyImmediately)
+ {
+ childSetEnabled("show_folders_check", FALSE);
+ }
+
+ getChild<LLUICtrl>("Pipette")->setCommitCallback( boost::bind(&LLFloaterTexturePicker::onBtnPipette, this));
+ childSetAction("Cancel", LLFloaterTexturePicker::onBtnCancel,this);
+ childSetAction("Select", LLFloaterTexturePicker::onBtnSelect,this);
+
+ // update permission filter once UI is fully initialized
+ updateFilterPermMask();
+ mSavedFolderState.setApply(FALSE);
+ LLToolPipette::getInstance()->setToolSelectCallback(boost::bind(&LLFloaterTexturePicker::onTextureSelect, this, _1));
+
return TRUE;
}
// virtual
void LLFloaterTexturePicker::draw()
{
+ static LLUICachedControl<S32> floater_header_size ("UIFloaterHeaderSize", 0);
if (mOwner)
{
// draw cone of context pointing back to texture swatch
@@ -543,22 +523,19 @@ void LLFloaterTexturePicker::draw()
childSetEnabled("Pipette", mActive);
childSetValue("Pipette", LLToolMgr::getInstance()->getCurrentTool() == LLToolPipette::getInstance());
- //RN: reset search bar to reflect actual search query (all caps, for example)
- mSearchEdit->setText(mInventoryPanel->getFilterSubString());
-
//BOOL allow_copy = FALSE;
if( mOwner )
{
mTexturep = NULL;
if(mImageAssetID.notNull())
{
- mTexturep = gImageList.getImage(mImageAssetID, MIPMAP_YES, IMMEDIATE_NO);
- mTexturep->setBoostLevel(LLViewerImage::BOOST_PREVIEW);
+ mTexturep = LLViewerTextureManager::getFetchedTexture(mImageAssetID, MIPMAP_YES, IMMEDIATE_NO);
+ mTexturep->setBoostLevel(LLViewerTexture::BOOST_PREVIEW);
}
else if (!mFallbackImageName.empty())
{
- mTexturep = gImageList.getImageFromFile(mFallbackImageName);
- mTexturep->setBoostLevel(LLViewerImage::BOOST_PREVIEW);
+ mTexturep = LLViewerTextureManager::getFetchedTextureFromFile(mFallbackImageName);
+ mTexturep->setBoostLevel(LLViewerTexture::BOOST_PREVIEW);
}
if (mTentativeLabel)
@@ -579,9 +556,9 @@ void LLFloaterTexturePicker::draw()
// Border
LLRect border( BORDER_PAD,
- getRect().getHeight() - LLFLOATER_HEADER_SIZE - BORDER_PAD,
- ((TEX_PICKER_MIN_WIDTH / 2) - TEXTURE_INVENTORY_PADDING - HPAD) - BORDER_PAD,
- BORDER_PAD + FOOTER_HEIGHT + (getRect().getHeight() - TEX_PICKER_MIN_HEIGHT));
+ getRect().getHeight() - floater_header_size - BORDER_PAD,
+ ((getMinWidth() / 2) - TEXTURE_INVENTORY_PADDING - HPAD) - BORDER_PAD,
+ BORDER_PAD + FOOTER_HEIGHT + (getRect().getHeight() - getMinHeight()));
gl_rect_2d( border, LLColor4::black, FALSE );
@@ -602,7 +579,7 @@ void LLFloaterTexturePicker::draw()
mTexturep->addTextureStats( (F32)(interior.getWidth() * interior.getHeight()) );
// Draw Tentative Label over the image
- if( mOwner->getTentative() && !mIsDirty )
+ if( mOwner->getTentative() && !mViewModel->isDirty() )
{
mTentativeLabel->setVisible( TRUE );
drawChild(mTentativeLabel);
@@ -719,7 +696,7 @@ void LLFloaterTexturePicker::onBtnRevert(void* userdata)
// TODO: Change this to tell the owner to cancel. It needs to be
// smart enough to restore multi-texture selections.
self->mOwner->onFloaterCommit();
- self->mIsDirty = FALSE;
+ self->mViewModel->resetDirty();
}*/
// static
@@ -731,8 +708,8 @@ void LLFloaterTexturePicker::onBtnCancel(void* userdata)
{
self->mOwner->onFloaterCommit(LLTextureCtrl::TEXTURE_CANCEL);
}
- self->mIsDirty = FALSE;
- self->close();
+ self->mViewModel->resetDirty();
+ self->closeFloater();
}
// static
@@ -743,52 +720,42 @@ void LLFloaterTexturePicker::onBtnSelect(void* userdata)
{
self->mOwner->onFloaterCommit(LLTextureCtrl::TEXTURE_SELECT);
}
- self->close();
+ self->closeFloater();
}
-// static
-void LLFloaterTexturePicker::onBtnPipette( void* userdata )
+void LLFloaterTexturePicker::onBtnPipette()
{
- LLFloaterTexturePicker* self = (LLFloaterTexturePicker*) userdata;
-
- if ( self)
+ BOOL pipette_active = childGetValue("Pipette").asBoolean();
+ pipette_active = !pipette_active;
+ if (pipette_active)
{
- BOOL pipette_active = self->childGetValue("Pipette").asBoolean();
- pipette_active = !pipette_active;
- if (pipette_active)
- {
- LLToolPipette::getInstance()->setSelectCallback(onTextureSelect, self);
- LLToolMgr::getInstance()->setTransientTool(LLToolPipette::getInstance());
- }
- else
- {
- LLToolMgr::getInstance()->clearTransientTool();
- }
+ LLToolMgr::getInstance()->setTransientTool(LLToolPipette::getInstance());
+ }
+ else
+ {
+ LLToolMgr::getInstance()->clearTransientTool();
}
-
}
-// static
-void LLFloaterTexturePicker::onSelectionChange(const std::deque<LLFolderViewItem*> &items, BOOL user_action, void* data)
+void LLFloaterTexturePicker::onSelectionChange(const std::deque<LLFolderViewItem*> &items, BOOL user_action)
{
- LLFloaterTexturePicker* self = (LLFloaterTexturePicker*)data;
if (items.size())
{
LLFolderViewItem* first_item = items.front();
LLInventoryItem* itemp = gInventory.getItem(first_item->getListener()->getUUID());
- self->mNoCopyTextureSelected = FALSE;
+ mNoCopyTextureSelected = FALSE;
if (itemp)
{
if (!itemp->getPermissions().allowCopyBy(gAgent.getID()))
{
- self->mNoCopyTextureSelected = TRUE;
+ mNoCopyTextureSelected = TRUE;
}
- self->mImageAssetID = itemp->getAssetUUID();
- self->mIsDirty = TRUE;
+ mImageAssetID = itemp->getAssetUUID();
+ mViewModel->setDirty(); // *TODO: shouldn't we be using setValue() here?
if (user_action)
{
// only commit intentional selections, not implicit ones
- self->commitIfImmediateSet();
+ commitIfImmediateSet();
}
}
}
@@ -827,107 +794,97 @@ void LLFloaterTexturePicker::updateFilterPermMask()
//mInventoryPanel->setFilterPermMask( getFilterPermMask() ); Commented out due to no-copy texture loss.
}
-void LLFloaterTexturePicker::onSearchEdit(const std::string& search_string, void* user_data )
+void LLFloaterTexturePicker::onFilterEdit(const std::string& search_string )
{
- LLFloaterTexturePicker* picker = (LLFloaterTexturePicker*)user_data;
-
std::string upper_case_search_string = search_string;
LLStringUtil::toUpper(upper_case_search_string);
if (upper_case_search_string.empty())
{
- if (picker->mInventoryPanel->getFilterSubString().empty())
+ if (mInventoryPanel->getFilterSubString().empty())
{
// current filter and new filter empty, do nothing
return;
}
- picker->mSavedFolderState.setApply(TRUE);
- picker->mInventoryPanel->getRootFolder()->applyFunctorRecursively(picker->mSavedFolderState);
+ mSavedFolderState.setApply(TRUE);
+ mInventoryPanel->getRootFolder()->applyFunctorRecursively(mSavedFolderState);
// add folder with current item to list of previously opened folders
LLOpenFoldersWithSelection opener;
- picker->mInventoryPanel->getRootFolder()->applyFunctorRecursively(opener);
- picker->mInventoryPanel->getRootFolder()->scrollToShowSelection();
+ mInventoryPanel->getRootFolder()->applyFunctorRecursively(opener);
+ mInventoryPanel->getRootFolder()->scrollToShowSelection();
}
- else if (picker->mInventoryPanel->getFilterSubString().empty())
+ else if (mInventoryPanel->getFilterSubString().empty())
{
// first letter in search term, save existing folder open state
- if (!picker->mInventoryPanel->getRootFolder()->isFilterModified())
+ if (!mInventoryPanel->getRootFolder()->isFilterModified())
{
- picker->mSavedFolderState.setApply(FALSE);
- picker->mInventoryPanel->getRootFolder()->applyFunctorRecursively(picker->mSavedFolderState);
+ mSavedFolderState.setApply(FALSE);
+ mInventoryPanel->getRootFolder()->applyFunctorRecursively(mSavedFolderState);
}
}
- picker->mInventoryPanel->setFilterSubString(upper_case_search_string);
+ mInventoryPanel->setFilterSubString(upper_case_search_string);
}
-//static
-void LLFloaterTexturePicker::onTextureSelect( const LLTextureEntry& te, void *data )
+void LLFloaterTexturePicker::onTextureSelect( const LLTextureEntry& te )
{
- LLFloaterTexturePicker* self = (LLFloaterTexturePicker*)data;
-
- LLUUID inventory_item_id = self->findItemID(te.getID(), TRUE);
- if (self && inventory_item_id.notNull())
+ LLUUID inventory_item_id = findItemID(te.getID(), TRUE);
+ if (inventory_item_id.notNull())
{
LLToolPipette::getInstance()->setResult(TRUE, "");
- self->setImageID(te.getID());
+ setImageID(te.getID());
- self->mNoCopyTextureSelected = FALSE;
+ mNoCopyTextureSelected = FALSE;
LLInventoryItem* itemp = gInventory.getItem(inventory_item_id);
if (itemp && !itemp->getPermissions().allowCopyBy(gAgent.getID()))
{
// no copy texture
- self->mNoCopyTextureSelected = TRUE;
+ mNoCopyTextureSelected = TRUE;
}
- self->commitIfImmediateSet();
+ commitIfImmediateSet();
}
else
{
- LLToolPipette::getInstance()->setResult(FALSE, "You do not have a copy this \nof texture in your inventory");
+ LLToolPipette::getInstance()->setResult(FALSE, LLTrans::getString("InventoryNoTexture"));
}
}
///////////////////////////////////////////////////////////////////////
// LLTextureCtrl
-static LLRegisterWidget<LLTextureCtrl> r("texture_picker");
+static LLDefaultChildRegistry::Register<LLTextureCtrl> r("texture_picker");
-LLTextureCtrl::LLTextureCtrl(
- const std::string& name,
- const LLRect &rect,
- const std::string& label,
- const LLUUID &image_id,
- const LLUUID &default_image_id,
- const std::string& default_image_name )
- :
- LLUICtrl(name, rect, TRUE, NULL, NULL, FOLLOWS_LEFT | FOLLOWS_TOP),
+LLTextureCtrl::LLTextureCtrl(const LLTextureCtrl::Params& p)
+: LLUICtrl(p),
mDragCallback(NULL),
mDropCallback(NULL),
mOnCancelCallback(NULL),
mOnSelectCallback(NULL),
- mBorderColor( gColors.getColor("DefaultHighlightLight") ),
- mImageAssetID( image_id ),
- mDefaultImageAssetID( default_image_id ),
- mDefaultImageName( default_image_name ),
- mLabel( label ),
+ mBorderColor( p.border_color() ),
mAllowNoTexture( FALSE ),
mImmediateFilterPermMask( PERM_NONE ),
mNonImmediateFilterPermMask( PERM_NONE ),
mCanApplyImmediately( FALSE ),
mNeedsRawImageData( FALSE ),
mValid( TRUE ),
- mDirty( FALSE ),
- mShowLoadingPlaceholder( TRUE )
+ mShowLoadingPlaceholder( TRUE ),
+ mImageAssetID(p.image_id),
+ mDefaultImageAssetID(p.default_image_id),
+ mDefaultImageName(p.default_image_name)
{
- mCaption = new LLTextBox( label,
- LLRect( 0, BTN_HEIGHT_SMALL, getRect().getWidth(), 0 ),
- label,
- LLFontGL::getFontSansSerifSmall() );
- mCaption->setFollows( FOLLOWS_LEFT | FOLLOWS_RIGHT | FOLLOWS_BOTTOM );
+ setAllowNoTexture(p.allow_no_texture);
+ setCanApplyImmediately(p.can_apply_immediately);
+
+ LLTextBox::Params params(p.caption_text);
+ params.name(p.label);
+ params.rect(LLRect( 0, BTN_HEIGHT_SMALL, getRect().getWidth(), 0 ));
+ params.text(p.label);
+ params.follows.flags(FOLLOWS_LEFT | FOLLOWS_RIGHT | FOLLOWS_BOTTOM);
+ mCaption = LLUICtrlFactory::create<LLTextBox> (params);
addChild( mCaption );
S32 image_top = getRect().getHeight();
@@ -935,92 +892,27 @@ LLTextureCtrl::LLTextureCtrl(
S32 image_middle = (image_top + image_bottom) / 2;
S32 line_height = llround(LLFontGL::getFontSansSerifSmall()->getLineHeight());
- mTentativeLabel = new LLTextBox( std::string("Multiple"),
- LLRect(
- 0, image_middle + line_height / 2,
- getRect().getWidth(), image_middle - line_height / 2 ),
- std::string("Multiple"),
- LLFontGL::getFontSansSerifSmall() );
- mTentativeLabel->setHAlign( LLFontGL::HCENTER );
- mTentativeLabel->setFollowsAll();
+ LLTextBox::Params tentative_label_p(p.multiselect_text);
+ tentative_label_p.name("Multiple");
+ tentative_label_p.rect(LLRect (0, image_middle + line_height / 2, getRect().getWidth(), image_middle - line_height / 2 ));
+ tentative_label_p.follows.flags(FOLLOWS_ALL);
+ mTentativeLabel = LLUICtrlFactory::create<LLTextBox> (tentative_label_p);
addChild( mTentativeLabel );
- LLRect border_rect(0, getRect().getHeight(), getRect().getWidth(), 0);
+ LLRect border_rect = getLocalRect();
border_rect.mBottom += BTN_HEIGHT_SMALL;
- mBorder = new LLViewBorder(std::string("border"), border_rect, LLViewBorder::BEVEL_IN);
- mBorder->setFollowsAll();
+ LLViewBorder::Params vbparams(p.border);
+ vbparams.name("border");
+ vbparams.rect(border_rect);
+ mBorder = LLUICtrlFactory::create<LLViewBorder> (vbparams);
addChild(mBorder);
- setEnabled(TRUE); // for the tooltip
mLoadingPlaceholderString = LLTrans::getString("texture_loading");
}
-
LLTextureCtrl::~LLTextureCtrl()
{
- closeFloater();
-}
-
-// virtual
-LLXMLNodePtr LLTextureCtrl::getXML(bool save_children) const
-{
- LLXMLNodePtr node = LLUICtrl::getXML();
-
- node->createChild("label", TRUE)->setStringValue(getLabel());
-
- node->createChild("default_image_name", TRUE)->setStringValue(getDefaultImageName());
-
- node->createChild("allow_no_texture", TRUE)->setBoolValue(mAllowNoTexture);
-
- node->createChild("can_apply_immediately", TRUE)->setBoolValue(mCanApplyImmediately );
-
- return node;
-}
-
-LLView* LLTextureCtrl::fromXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFactory *factory)
-{
- std::string name("texture_picker");
- node->getAttributeString("name", name);
-
- LLRect rect;
- createRect(node, rect, parent);
-
- std::string label;
- node->getAttributeString("label", label);
-
- std::string image_id("");
- node->getAttributeString("image", image_id);
-
- std::string default_image_id("");
- node->getAttributeString("default_image", default_image_id);
-
- std::string default_image_name("Default");
- node->getAttributeString("default_image_name", default_image_name);
-
- BOOL allow_no_texture = FALSE;
- node->getAttributeBOOL("allow_no_texture", allow_no_texture);
-
- BOOL can_apply_immediately = FALSE;
- node->getAttributeBOOL("can_apply_immediately", can_apply_immediately);
-
- if (label.empty())
- {
- label.assign(node->getValue());
- }
-
- LLTextureCtrl* texture_picker = new LLTextureCtrl(
- name,
- rect,
- label,
- LLUUID(image_id),
- LLUUID(default_image_id),
- default_image_name );
- texture_picker->setAllowNoTexture(allow_no_texture);
- texture_picker->setCanApplyImmediately(can_apply_immediately);
-
- texture_picker->initFromXML(node, parent);
-
- return texture_picker;
+ closeDependentFloater();
}
void LLTextureCtrl::setShowLoadingPlaceholder(BOOL showLoadingPlaceholder)
@@ -1047,7 +939,7 @@ void LLTextureCtrl::setVisible( BOOL visible )
{
if( !visible )
{
- closeFloater();
+ closeDependentFloater();
}
LLUICtrl::setVisible( visible );
}
@@ -1066,7 +958,7 @@ void LLTextureCtrl::setEnabled( BOOL enabled )
setToolTip( std::string() );
// *TODO: would be better to keep floater open and show
// disabled state.
- closeFloater();
+ closeDependentFloater();
}
if( floaterp )
@@ -1092,18 +984,6 @@ void LLTextureCtrl::setValid(BOOL valid )
}
}
-// virtual
-BOOL LLTextureCtrl::isDirty() const
-{
- return mDirty;
-}
-
-// virtual
-void LLTextureCtrl::resetDirty()
-{
- mDirty = FALSE;
-}
-
// virtual
void LLTextureCtrl::clear()
@@ -1119,25 +999,20 @@ void LLTextureCtrl::setLabel(const std::string& label)
void LLTextureCtrl::showPicker(BOOL take_focus)
{
+ // show hourglass cursor when loading inventory window
+ // because inventory construction is slooow
+ getWindow()->setCursor(UI_CURSOR_WAIT);
LLFloater* floaterp = mFloaterHandle.get();
// Show the dialog
if( floaterp )
{
- floaterp->open( ); /* Flawfinder: ignore */
+ floaterp->openFloater();
}
else
{
- if( !mLastFloaterLeftTop.mX && !mLastFloaterLeftTop.mY )
- {
- gFloaterView->getNewFloaterPosition(&mLastFloaterLeftTop.mX, &mLastFloaterLeftTop.mY);
- }
- LLRect rect = gSavedSettings.getRect("TexturePickerRect");
- rect.translate( mLastFloaterLeftTop.mX - rect.mLeft, mLastFloaterLeftTop.mY - rect.mTop );
-
floaterp = new LLFloaterTexturePicker(
this,
- rect,
mLabel,
mImmediateFilterPermMask,
mNonImmediateFilterPermMask,
@@ -1146,8 +1021,10 @@ void LLTextureCtrl::showPicker(BOOL take_focus)
mFloaterHandle = floaterp->getHandle();
- gFloaterView->getParentFloater(this)->addDependentFloater(floaterp);
- floaterp->open(); /* Flawfinder: ignore */
+ LLFloater* root_floater = gFloaterView->getParentFloater(this);
+ if (root_floater)
+ root_floater->addDependentFloater(floaterp);
+ floaterp->openFloater();
}
if (take_focus)
@@ -1157,13 +1034,13 @@ void LLTextureCtrl::showPicker(BOOL take_focus)
}
-void LLTextureCtrl::closeFloater()
+void LLTextureCtrl::closeDependentFloater()
{
LLFloaterTexturePicker* floaterp = (LLFloaterTexturePicker*)mFloaterHandle.get();
if( floaterp )
{
floaterp->setOwner(NULL);
- floaterp->close();
+ floaterp->closeFloater();
}
}
@@ -1210,7 +1087,6 @@ void LLTextureCtrl::onFloaterClose()
if (floaterp)
{
floaterp->setOwner(NULL);
- mLastFloaterLeftTop.set( floaterp->getRect().mLeft, floaterp->getRect().mTop );
}
mFloaterHandle.markDead();
@@ -1222,7 +1098,11 @@ void LLTextureCtrl::onFloaterCommit(ETexturePickOp op)
if( floaterp && getEnabled())
{
- mDirty = (op != TEXTURE_CANCEL);
+ if (op == TEXTURE_CANCEL)
+ mViewModel->resetDirty();
+ else
+ mViewModel->setDirty(); // *TODO: shouldn't we be using setValue() here?
+
if( floaterp->isDirty() )
{
setTentative( FALSE );
@@ -1232,11 +1112,11 @@ void LLTextureCtrl::onFloaterCommit(ETexturePickOp op)
lldebugs << "mImageAssetID: " << mImageAssetID << llendl;
if (op == TEXTURE_SELECT && mOnSelectCallback)
{
- mOnSelectCallback(this, mCallbackUserData);
+ mOnSelectCallback( this, LLSD() );
}
else if (op == TEXTURE_CANCEL && mOnCancelCallback)
{
- mOnCancelCallback(this, mCallbackUserData);
+ mOnCancelCallback( this, LLSD() );
}
else
{
@@ -1256,7 +1136,7 @@ void LLTextureCtrl::setImageAssetID( const LLUUID& asset_id )
if( floaterp && getEnabled() )
{
floaterp->setImageID( asset_id );
- floaterp->setDirty( FALSE );
+ floaterp->resetDirty();
}
}
}
@@ -1308,19 +1188,23 @@ void LLTextureCtrl::draw()
}
else if (!mImageAssetID.isNull())
{
- mTexturep = gImageList.getImage(mImageAssetID, MIPMAP_YES, IMMEDIATE_NO);
- mTexturep->setBoostLevel(LLViewerImage::BOOST_PREVIEW);
+ mTexturep = LLViewerTextureManager::getFetchedTexture(mImageAssetID, MIPMAP_YES, IMMEDIATE_NO);
+ mTexturep->setBoostLevel(LLViewerTexture::BOOST_PREVIEW);
}
else if (!mFallbackImageName.empty())
{
// Show fallback image.
- mTexturep = gImageList.getImageFromFile(mFallbackImageName);
- mTexturep->setBoostLevel(LLViewerImage::BOOST_PREVIEW);
+ mTexturep = LLViewerTextureManager::getFetchedTextureFromFile(mFallbackImageName);
+ mTexturep->setBoostLevel(LLViewerTexture::BOOST_PREVIEW);
+ }
+ else//mImageAssetID == LLUUID::null
+ {
+ mTexturep = NULL;
}
// Border
LLRect border( 0, getRect().getHeight(), getRect().getWidth(), BTN_HEIGHT_SMALL );
- gl_rect_2d( border, mBorderColor, FALSE );
+ gl_rect_2d( border, mBorderColor.get(), FALSE );
// Interior
LLRect interior = border;
@@ -1388,7 +1272,7 @@ BOOL LLTextureCtrl::allowDrop(LLInventoryItem* item)
{
if(mDragCallback)
{
- return mDragCallback(this, item, mCallbackUserData);
+ return mDragCallback(this, item);
}
else
{
@@ -1408,7 +1292,7 @@ BOOL LLTextureCtrl::doDrop(LLInventoryItem* item)
{
// if it returns TRUE, we return TRUE, and therefore the
// commit is called above.
- return mDropCallback(this, item, mCallbackUserData);
+ return mDropCallback(this, item);
}
// no callback installed, so just set the image ids and carry on.
@@ -1438,66 +1322,6 @@ LLSD LLTextureCtrl::getValue() const
}
-/////////////////////////////////////////////////////////////////////////////////
-// LLToolTexEyedropper
-
-class LLToolTexEyedropper : public LLTool
-{
-public:
- LLToolTexEyedropper( void (*callback)(const LLUUID& obj_id, const LLUUID& image_id, void* userdata ), void* userdata );
- virtual ~LLToolTexEyedropper();
- virtual BOOL handleMouseDown(S32 x, S32 y, MASK mask);
- virtual BOOL handleHover(S32 x, S32 y, MASK mask);
-
-protected:
- void (*mCallback)(const LLUUID& obj_id, const LLUUID& image_id, void* userdata );
- void* mCallbackUserData;
-};
-
-
-LLToolTexEyedropper::LLToolTexEyedropper(
- void (*callback)(const LLUUID& obj_id, const LLUUID& image_id, void* userdata ),
- void* userdata )
- : LLTool(std::string("texeyedropper")),
- mCallback( callback ),
- mCallbackUserData( userdata )
-{
-}
-
-LLToolTexEyedropper::~LLToolTexEyedropper()
-{
-}
-
-
-BOOL LLToolTexEyedropper::handleMouseDown(S32 x, S32 y, MASK mask)
-{
- // this will affect framerate on mouse down
- const LLPickInfo& pick = gViewerWindow->pickImmediate(x, y, FALSE);
- LLViewerObject* hit_obj = pick.getObject();
- if (hit_obj &&
- !hit_obj->isAvatar())
- {
- if( (0 <= pick.mObjectFace) && (pick.mObjectFace < hit_obj->getNumTEs()) )
- {
- LLViewerImage* image = hit_obj->getTEImage( pick.mObjectFace );
- if( image )
- {
- if( mCallback )
- {
- mCallback( hit_obj->getID(), image->getID(), mCallbackUserData );
- }
- }
- }
- }
- return TRUE;
-}
-
-BOOL LLToolTexEyedropper::handleHover(S32 x, S32 y, MASK mask)
-{
- lldebugst(LLERR_USER_INPUT) << "hover handled by LLToolTexEyedropper" << llendl;
- gViewerWindow->getWindow()->setCursor(UI_CURSOR_CROSS); // TODO: better cursor
- return TRUE;
-}
diff --git a/indra/newview/lltexturectrl.h b/indra/newview/lltexturectrl.h
index 623f15eef5..0b232da62b 100644
--- a/indra/newview/lltexturectrl.h
+++ b/indra/newview/lltexturectrl.h
@@ -39,16 +39,17 @@
#include "llstring.h"
#include "lluictrl.h"
#include "llpermissionsflags.h"
+#include "lltextbox.h" // for params
+#include "llviewborder.h" // for params
class LLButton;
class LLFloaterTexturePicker;
class LLInventoryItem;
-class LLTextBox;
-class LLViewBorder;
-class LLViewerImage;
+class LLViewerTexture;
// used for setting drag & drop callbacks.
-typedef BOOL (*drag_n_drop_callback)(LLUICtrl*, LLInventoryItem*, void*);
+typedef boost::function<BOOL (LLUICtrl*, LLInventoryItem*)> drag_n_drop_callback;
+
//////////////////////////////////////////////////////////////////////////////////////////
// LLTextureCtrl
@@ -66,17 +67,45 @@ public:
} ETexturePickOp;
public:
- LLTextureCtrl(
- const std::string& name, const LLRect& rect,
- const std::string& label,
- const LLUUID& image_id,
- const LLUUID& default_image_id,
- const std::string& default_image_name );
+ struct Params : public LLInitParam::Block<Params, LLUICtrl::Params>
+ {
+ Optional<LLUUID> image_id;
+ Optional<LLUUID> default_image_id;
+ Optional<std::string> default_image_name;
+ Optional<bool> allow_no_texture;
+ Optional<bool> can_apply_immediately;
+ Optional<S32> label_width;
+ Optional<LLUIColor> border_color;
+
+ Optional<LLTextBox::Params> multiselect_text,
+ caption_text;
+
+ Optional<LLViewBorder::Params> border;
+
+ Params()
+ : image_id("image"),
+ default_image_id("default_image_id"),
+ default_image_name("default_image_name"),
+ allow_no_texture("allow_no_texture"),
+ can_apply_immediately("can_apply_immediately"),
+ label_width("label_width", -1),
+ border_color("border_color"),
+ multiselect_text("multiselect_text"),
+ caption_text("caption_text"),
+ border("border")
+ {
+ name = "texture picker";
+ mouse_opaque(true);
+ follows.flags(FOLLOWS_LEFT | FOLLOWS_TOP);
+ }
+ };
+protected:
+ LLTextureCtrl(const Params&);
+ friend class LLUICtrlFactory;
+public:
virtual ~LLTextureCtrl();
// LLView interface
- virtual LLXMLNodePtr getXML(bool save_children = true) const;
- static LLView* fromXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFactory *factory);
virtual BOOL handleMouseDown(S32 x, S32 y, MASK mask);
virtual BOOL handleDragAndDrop(S32 x, S32 y, MASK mask,
@@ -90,9 +119,6 @@ public:
virtual void setVisible( BOOL visible );
virtual void setEnabled( BOOL enabled );
- virtual BOOL isDirty() const;
- virtual void resetDirty();
-
void setValid(BOOL valid);
// LLUICtrl interface
@@ -105,6 +131,7 @@ public:
// LLTextureCtrl interface
void showPicker(BOOL take_focus);
void setLabel(const std::string& label);
+ void setLabelWidth(S32 label_width) {mLabelWidth =label_width;}
const std::string& getLabel() const { return mLabel; }
void setAllowNoTexture( BOOL b ) { mAllowNoTexture = b; }
@@ -133,7 +160,7 @@ public:
PermissionMask getImmediateFilterPermMask() { return mImmediateFilterPermMask; }
PermissionMask getNonImmediateFilterPermMask() { return mNonImmediateFilterPermMask; }
- void closeFloater();
+ void closeDependentFloater();
void onFloaterClose();
void onFloaterCommit(ETexturePickOp op);
@@ -146,10 +173,10 @@ public:
// the drop happened - resulting in an on commit callback, but not
// necessariliy any other change.
void setDropCallback(drag_n_drop_callback cb) { mDropCallback = cb; }
-
- void setOnCancelCallback(LLUICtrlCallback cb) { mOnCancelCallback = cb; }
- void setOnSelectCallback(LLUICtrlCallback cb) { mOnSelectCallback = cb; }
+ void setOnCancelCallback(commit_callback_t cb) { mOnCancelCallback = cb; }
+
+ void setOnSelectCallback(commit_callback_t cb) { mOnSelectCallback = cb; }
void setShowLoadingPlaceholder(BOOL showLoadingPlaceholder);
@@ -160,10 +187,10 @@ private:
private:
drag_n_drop_callback mDragCallback;
drag_n_drop_callback mDropCallback;
- LLUICtrlCallback mOnCancelCallback;
- LLUICtrlCallback mOnSelectCallback;
- LLPointer<LLViewerImage> mTexturep;
- LLColor4 mBorderColor;
+ commit_callback_t mOnCancelCallback;
+ commit_callback_t mOnSelectCallback;
+ LLPointer<LLViewerTexture> mTexturep;
+ LLUIColor mBorderColor;
LLUUID mImageItemID;
LLUUID mImageAssetID;
LLUUID mDefaultImageAssetID;
@@ -174,16 +201,15 @@ private:
LLTextBox* mCaption;
std::string mLabel;
BOOL mAllowNoTexture; // If true, the user can select "none" as an option
- LLCoordGL mLastFloaterLeftTop;
PermissionMask mImmediateFilterPermMask;
PermissionMask mNonImmediateFilterPermMask;
BOOL mCanApplyImmediately;
BOOL mNeedsRawImageData;
LLViewBorder* mBorder;
BOOL mValid;
- BOOL mDirty;
BOOL mShowLoadingPlaceholder;
std::string mLoadingPlaceholderString;
+ S32 mLabelWidth;
};
// XUI HACK: When floaters converted, switch this file to lltexturepicker.h/cpp
diff --git a/indra/newview/lltexturefetch.cpp b/indra/newview/lltexturefetch.cpp
index e9dd7921cd..63af170fa9 100644
--- a/indra/newview/lltexturefetch.cpp
+++ b/indra/newview/lltexturefetch.cpp
@@ -44,8 +44,8 @@
#include "llagent.h"
#include "lltexturecache.h"
-#include "llviewerimagelist.h"
-#include "llviewerimage.h"
+#include "llviewertexturelist.h"
+#include "llviewertexture.h"
#include "llviewerregion.h"
//////////////////////////////////////////////////////////////////////////////
@@ -469,8 +469,8 @@ void LLTextureFetchWorker::clearPackets()
U32 LLTextureFetchWorker::calcWorkPriority()
{
-// llassert_always(mImagePriority >= 0 && mImagePriority <= LLViewerImage::maxDecodePriority());
- F32 priority_scale = (F32)LLWorkerThread::PRIORITY_LOWBITS / LLViewerImage::maxDecodePriority();
+// llassert_always(mImagePriority >= 0 && mImagePriority <= LLViewerTexture::maxDecodePriority());
+ F32 priority_scale = (F32)LLWorkerThread::PRIORITY_LOWBITS / LLViewerFetchedTexture::maxDecodePriority();
mWorkPriority = (U32)(mImagePriority * priority_scale);
return mWorkPriority;
}
@@ -512,7 +512,7 @@ void LLTextureFetchWorker::setDesiredDiscard(S32 discard, S32 size)
void LLTextureFetchWorker::setImagePriority(F32 priority)
{
-// llassert_always(priority >= 0 && priority <= LLViewerImage::maxDecodePriority());
+// llassert_always(priority >= 0 && priority <= LLViewerTexture::maxDecodePriority());
F32 delta = fabs(priority - mImagePriority);
if (delta > (mImagePriority * .05f) || mState == DONE)
{
@@ -542,7 +542,7 @@ void LLTextureFetchWorker::startWork(S32 param)
llassert(mFormattedImage.isNull());
}
-#include "llviewerimagelist.h" // debug
+#include "llviewertexturelist.h" // debug
// Called from LLWorkerThread::processRequest()
bool LLTextureFetchWorker::doWork(S32 param)
@@ -796,7 +796,7 @@ bool LLTextureFetchWorker::doWork(S32 param)
mFormattedImage->deleteData();
#endif
mRequestedSize -= cur_size;
- // F32 priority = mImagePriority / (F32)LLViewerImage::maxDecodePriority(); // 0-1
+ // F32 priority = mImagePriority / (F32)LLViewerTexture::maxDecodePriority(); // 0-1
S32 offset = cur_size;
mBufferSize = cur_size; // This will get modified by callbackHttpGet()
std::string url;
@@ -1877,6 +1877,21 @@ bool LLTextureFetch::receiveImagePacket(const LLHost& host, const LLUUID& id, U1
}
//////////////////////////////////////////////////////////////////////////////
+BOOL LLTextureFetch::isFromLocalCache(const LLUUID& id)
+{
+ BOOL from_cache = FALSE ;
+
+ LLMutexLock lock(&mQueueMutex);
+ LLTextureFetchWorker* worker = getWorker(id);
+ if (worker)
+ {
+ worker->lockWorkData();
+ from_cache = worker->mInLocalCache ;
+ worker->unlockWorkData();
+ }
+
+ return from_cache ;
+}
S32 LLTextureFetch::getFetchState(const LLUUID& id, F32& data_progress_p, F32& requested_priority_p,
U32& fetch_priority_p, F32& fetch_dtime_p, F32& request_dtime_p)
diff --git a/indra/newview/lltexturefetch.h b/indra/newview/lltexturefetch.h
index 56650e721c..97719a9468 100644
--- a/indra/newview/lltexturefetch.h
+++ b/indra/newview/lltexturefetch.h
@@ -38,7 +38,7 @@
#include "lluuid.h"
#include "llworkerthread.h"
-class LLViewerImage;
+class LLViewerTexture;
class LLTextureFetchWorker;
class LLTextureCache;
class LLHost;
@@ -67,6 +67,7 @@ public:
bool receiveImagePacket(const LLHost& host, const LLUUID& id, U16 packet_num, U16 data_size, U8* data);
// Debug
+ BOOL isFromLocalCache(const LLUUID& id);
S32 getFetchState(const LLUUID& id, F32& decode_progress_p, F32& requested_priority_p,
U32& fetch_priority_p, F32& fetch_dtime_p, F32& request_dtime_p);
void dump();
diff --git a/indra/newview/lltextureview.cpp b/indra/newview/lltextureview.cpp
index d356bf99ae..70a8ab9f61 100644
--- a/indra/newview/lltextureview.cpp
+++ b/indra/newview/lltextureview.cpp
@@ -49,8 +49,8 @@
#include "lltexturecache.h"
#include "lltexturefetch.h"
#include "llviewerobject.h"
-#include "llviewerimage.h"
-#include "llviewerimagelist.h"
+#include "llviewertexture.h"
+#include "llviewertexturelist.h"
#include "llappviewer.h"
extern F32 texmem_lower_bound_scale;
@@ -58,18 +58,18 @@ extern F32 texmem_lower_bound_scale;
LLTextureView *gTextureView = NULL;
//static
-std::set<LLViewerImage*> LLTextureView::sDebugImages;
+std::set<LLViewerFetchedTexture*> LLTextureView::sDebugImages;
////////////////////////////////////////////////////////////////////////////
-static std::string title_string1a("Tex UUID Area DDis(Req) DecodePri(Fetch) [download] pk/max");
-static std::string title_string1b("Tex UUID Area DDis(Req) Fetch(DecodePri) [download] pk/max");
+static std::string title_string1a("Tex UUID Area DDis(Req) DecodePri(Fetch) [download] pk/max");
+static std::string title_string1b("Tex UUID Area DDis(Req) Fetch(DecodePri) [download] pk/max");
static std::string title_string2("State");
static std::string title_string3("Pkt Bnd");
static std::string title_string4(" W x H (Dis) Mem");
static S32 title_x1 = 0;
-static S32 title_x2 = 440;
+static S32 title_x2 = 460;
static S32 title_x3 = title_x2 + 40;
static S32 title_x4 = title_x3 + 50;
static S32 texture_bar_height = 8;
@@ -79,16 +79,24 @@ static S32 texture_bar_height = 8;
class LLTextureBar : public LLView
{
public:
- LLPointer<LLViewerImage> mImagep;
+ LLPointer<LLViewerFetchedTexture> mImagep;
S32 mHilite;
public:
- LLTextureBar(const std::string& name, const LLRect& r, LLTextureView* texview)
- : LLView(name, r, FALSE),
- mHilite(0),
- mTextureView(texview)
+ struct Params : public LLInitParam::Block<Params, LLView::Params>
{
- }
+ Mandatory<LLTextureView*> texture_view;
+ Params()
+ : texture_view("texture_view")
+ {
+ mouse_opaque(false);
+ }
+ };
+ LLTextureBar(const Params& p)
+ : LLView(p),
+ mHilite(0),
+ mTextureView(p.texture_view)
+ {}
virtual void draw();
virtual BOOL handleMouseDown(S32 x, S32 y, MASK mask);
@@ -101,8 +109,8 @@ public:
{
LLTextureBar* bar1p = (LLTextureBar*)i1;
LLTextureBar* bar2p = (LLTextureBar*)i2;
- LLViewerImage *i1p = bar1p->mImagep;
- LLViewerImage *i2p = bar2p->mImagep;
+ LLViewerFetchedTexture *i1p = bar1p->mImagep;
+ LLViewerFetchedTexture *i2p = bar2p->mImagep;
F32 pri1 = i1p->getDecodePriority(); // i1p->mRequestedDownloadPriority
F32 pri2 = i2p->getDecodePriority(); // i2p->mRequestedDownloadPriority
if (pri1 > pri2)
@@ -120,10 +128,10 @@ public:
{
LLTextureBar* bar1p = (LLTextureBar*)i1;
LLTextureBar* bar2p = (LLTextureBar*)i2;
- LLViewerImage *i1p = bar1p->mImagep;
- LLViewerImage *i2p = bar2p->mImagep;
- U32 pri1 = i1p->mFetchPriority;
- U32 pri2 = i2p->mFetchPriority;
+ LLViewerFetchedTexture *i1p = bar1p->mImagep;
+ LLViewerFetchedTexture *i2p = bar2p->mImagep;
+ U32 pri1 = i1p->getFetchPriority() ;
+ U32 pri2 = i2p->getFetchPriority() ;
if (pri1 > pri2)
return true;
else if (pri2 > pri1)
@@ -307,10 +315,10 @@ void LLTextureBar::draw()
pip_x += pip_width + pip_space;
// we don't want to show bind/resident pips for textures using the default texture
- if (mImagep->getHasGLTexture())
+ if (mImagep->hasValidGLTexture())
{
// Draw the bound pip
- last_event = mImagep->sLastFrameTime - mImagep->mLastBindTime;
+ last_event = mImagep->getTimePassedSinceLastBound();
if (last_event < 1.f)
{
clr = mImagep->getMissed() ? LLColor4::red : LLColor4::magenta1;
@@ -334,7 +342,7 @@ void LLTextureBar::draw()
// draw the image size at the end
{
std::string num_str = llformat("%3dx%3d (%d) %7d", mImagep->getWidth(), mImagep->getHeight(),
- mImagep->getDiscardLevel(), mImagep->mTextureMemory);
+ mImagep->getDiscardLevel(), mImagep->hasGLTexture() ? mImagep->getTextureMemory() : 0);
LLFontGL::getFontMonospace()->renderUTF8(num_str, 0, title_x4, getRect().getHeight(), color,
LLFontGL::LEFT, LLFontGL::TOP);
}
@@ -366,13 +374,21 @@ LLRect LLTextureBar::getRequiredRect()
class LLGLTexMemBar : public LLView
{
public:
- LLGLTexMemBar(const std::string& name, LLTextureView* texview)
- : LLView(name, FALSE),
- mTextureView(texview)
+ struct Params : public LLInitParam::Block<Params, LLView::Params>
{
- S32 line_height = (S32)(LLFontGL::getFontMonospace()->getLineHeight() + .5f);
- setRect(LLRect(0,0,100,line_height * 4));
- }
+ Mandatory<LLTextureView*> texture_view;
+ Params()
+ : texture_view("texture_view")
+ {
+ S32 line_height = (S32)(LLFontGL::getFontMonospace()->getLineHeight() + .5f);
+ rect(LLRect(0,0,100,line_height * 4));
+ }
+ };
+
+ LLGLTexMemBar(const Params& p)
+ : LLView(p),
+ mTextureView(p.texture_view)
+ {}
virtual void draw();
virtual BOOL handleMouseDown(S32 x, S32 y, MASK mask);
@@ -384,13 +400,13 @@ private:
void LLGLTexMemBar::draw()
{
- S32 bound_mem = BYTES_TO_MEGA_BYTES(LLViewerImage::sBoundTextureMemoryInBytes);
- S32 max_bound_mem = LLViewerImage::sMaxBoundTextureMemInMegaBytes;
- S32 total_mem = BYTES_TO_MEGA_BYTES(LLViewerImage::sTotalTextureMemoryInBytes);
- S32 max_total_mem = LLViewerImage::sMaxTotalTextureMemInMegaBytes;
- F32 discard_bias = LLViewerImage::sDesiredDiscardBias;
+ S32 bound_mem = BYTES_TO_MEGA_BYTES(LLViewerTexture::sBoundTextureMemoryInBytes);
+ S32 max_bound_mem = LLViewerTexture::sMaxBoundTextureMemInMegaBytes;
+ S32 total_mem = BYTES_TO_MEGA_BYTES(LLViewerTexture::sTotalTextureMemoryInBytes);
+ S32 max_total_mem = LLViewerTexture::sMaxTotalTextureMemInMegaBytes;
+ F32 discard_bias = LLViewerTexture::sDesiredDiscardBias;
S32 line_height = (S32)(LLFontGL::getFontMonospace()->getLineHeight() + .5f);
-
+ S32 h_offset = (S32)((texture_bar_height + 2.5f) * mTextureView->mNumTextureBars + 2.5f);
//----------------------------------------------------------------------------
LLGLSUIDefault gls_ui;
F32 text_color[] = {1.f, 1.f, 1.f, 0.75f};
@@ -403,13 +419,13 @@ void LLGLTexMemBar::draw()
max_bound_mem,
discard_bias);
- LLFontGL::getFontMonospace()->renderUTF8(text, 0, 0, line_height*3,
+ LLFontGL::getFontMonospace()->renderUTF8(text, 0, 0, h_offset + line_height*3,
text_color, LLFontGL::LEFT, LLFontGL::TOP);
//----------------------------------------------------------------------------
S32 bar_left = 380;
S32 bar_width = 200;
- S32 top = line_height*3 - 2;
+ S32 top = line_height*3 - 2 + h_offset;
S32 bottom = top - 6;
S32 left = bar_left;
S32 right = left + bar_width;
@@ -461,49 +477,49 @@ void LLGLTexMemBar::draw()
//----------------------------------------------------------------------------
text = llformat("Textures: Count: %d Fetch: %d(%d) Pkts:%d(%d) Cache R/W: %d/%d LFS:%d IW:%d(%d) RAW:%d mRaw:%d mAux:%d CB:%d",
- gImageList.getNumImages(),
+ gTextureList.getNumImages(),
LLAppViewer::getTextureFetch()->getNumRequests(), LLAppViewer::getTextureFetch()->getNumDeletes(),
LLAppViewer::getTextureFetch()->mPacketCount, LLAppViewer::getTextureFetch()->mBadPacketCount,
LLAppViewer::getTextureCache()->getNumReads(), LLAppViewer::getTextureCache()->getNumWrites(),
LLLFSThread::sLocal->getPending(),
LLImageWorker::sCount, LLImageWorker::getWorkerThread()->getNumDeletes(),
- LLImageRaw::sRawImageCount, LLViewerImage::sRawCount, LLViewerImage::sAuxCount,
- gImageList.mCallbackList.size());
+ LLImageRaw::sRawImageCount, LLViewerFetchedTexture::sRawCount, LLViewerFetchedTexture::sAuxCount,
+ gTextureList.mCallbackList.size());
- LLFontGL::getFontMonospace()->renderUTF8(text, 0, 0, line_height*2,
+ LLFontGL::getFontMonospace()->renderUTF8(text, 0, 0, h_offset + line_height*2,
text_color, LLFontGL::LEFT, LLFontGL::TOP);
S32 dx1 = 0;
if (LLAppViewer::getTextureFetch()->mDebugPause)
{
- LLFontGL::getFontMonospace()->renderUTF8(std::string("!"), 0, title_x1, line_height,
+ LLFontGL::getFontMonospace()->renderUTF8(std::string("!"), 0, title_x1, h_offset + line_height,
text_color, LLFontGL::LEFT, LLFontGL::TOP);
dx1 += 8;
}
if (mTextureView->mFreezeView)
{
- LLFontGL::getFontMonospace()->renderUTF8(std::string("*"), 0, title_x1, line_height,
+ LLFontGL::getFontMonospace()->renderUTF8(std::string("*"), 0, title_x1, h_offset + line_height,
text_color, LLFontGL::LEFT, LLFontGL::TOP);
dx1 += 8;
}
if (mTextureView->mOrderFetch)
{
- LLFontGL::getFontMonospace()->renderUTF8(title_string1b, 0, title_x1+dx1, line_height,
+ LLFontGL::getFontMonospace()->renderUTF8(title_string1b, 0, title_x1+dx1, h_offset + line_height,
text_color, LLFontGL::LEFT, LLFontGL::TOP);
}
else
{
- LLFontGL::getFontMonospace()->renderUTF8(title_string1a, 0, title_x1+dx1, line_height,
+ LLFontGL::getFontMonospace()->renderUTF8(title_string1a, 0, title_x1+dx1, h_offset + line_height,
text_color, LLFontGL::LEFT, LLFontGL::TOP);
}
- LLFontGL::getFontMonospace()->renderUTF8(title_string2, 0, title_x2, line_height,
+ LLFontGL::getFontMonospace()->renderUTF8(title_string2, 0, title_x2, h_offset + line_height,
text_color, LLFontGL::LEFT, LLFontGL::TOP);
- LLFontGL::getFontMonospace()->renderUTF8(title_string3, 0, title_x3, line_height,
+ LLFontGL::getFontMonospace()->renderUTF8(title_string3, 0, title_x3, h_offset + line_height,
text_color, LLFontGL::LEFT, LLFontGL::TOP);
- LLFontGL::getFontMonospace()->renderUTF8(title_string4, 0, title_x4, line_height,
+ LLFontGL::getFontMonospace()->renderUTF8(title_string4, 0, title_x4, h_offset + line_height,
text_color, LLFontGL::LEFT, LLFontGL::TOP);
}
@@ -521,8 +537,8 @@ LLRect LLGLTexMemBar::getRequiredRect()
////////////////////////////////////////////////////////////////////////////
-LLTextureView::LLTextureView(const std::string& name, const LLRect& rect)
- : LLContainerView(name, rect),
+LLTextureView::LLTextureView(const LLTextureView::Params& p)
+ : LLContainerView(p),
mFreezeView(FALSE),
mOrderFetch(FALSE),
mPrintList(FALSE),
@@ -541,7 +557,7 @@ LLTextureView::~LLTextureView()
mGLTexMemBar = 0;
}
-typedef std::pair<F32,LLViewerImage*> decode_pair_t;
+typedef std::pair<F32,LLViewerFetchedTexture*> decode_pair_t;
struct compare_decode_pair
{
bool operator()(const decode_pair_t& a, const decode_pair_t& b)
@@ -571,18 +587,19 @@ void LLTextureView::draw()
llinfos << "ID\tMEM\tBOOST\tPRI\tWIDTH\tHEIGHT\tDISCARD" << llendl;
}
- for (LLViewerImageList::image_priority_list_t::iterator iter = gImageList.mImageList.begin();
- iter != gImageList.mImageList.end(); )
+ for (LLViewerTextureList::image_priority_list_t::iterator iter = gTextureList.mImageList.begin();
+ iter != gTextureList.mImageList.end(); )
{
- LLPointer<LLViewerImage> imagep = *iter++;
+ LLPointer<LLViewerFetchedTexture> imagep = *iter++;
S32 cur_discard = imagep->getDiscardLevel();
S32 desired_discard = imagep->mDesiredDiscardLevel;
if (mPrintList)
{
+ S32 tex_mem = imagep->hasGLTexture() ? imagep->getTextureMemory() : 0 ;
llinfos << imagep->getID()
- << "\t" << imagep->mTextureMemory
+ << "\t" << tex_mem
<< "\t" << imagep->getBoostLevel()
<< "\t" << imagep->getDecodePriority()
<< "\t" << imagep->getWidth()
@@ -627,8 +644,8 @@ void LLTextureView::draw()
{
struct f : public LLSelectedTEFunctor
{
- LLViewerImage* mImage;
- f(LLViewerImage* image) : mImage(image) {}
+ LLViewerFetchedTexture* mImage;
+ f(LLViewerFetchedTexture* image) : mImage(image) {}
virtual bool apply(LLViewerObject* object, S32 te)
{
return (mImage == object->getTEImage(te));
@@ -685,10 +702,11 @@ void LLTextureView::draw()
static S32 max_count = 50;
S32 count = 0;
+ mNumTextureBars = 0 ;
for (display_list_t::iterator iter = display_image_list.begin();
iter != display_image_list.end(); iter++)
{
- LLViewerImage* imagep = iter->second;
+ LLViewerFetchedTexture* imagep = iter->second;
S32 hilite = 0;
F32 pri = iter->first;
if (pri >= 1 * HIGH_PRIORITY)
@@ -709,13 +727,16 @@ void LLTextureView::draw()
else
sortChildren(LLTextureBar::sort());
- mGLTexMemBar = new LLGLTexMemBar("gl texmem bar", this);
+ LLGLTexMemBar::Params tmbp;
+ tmbp.name("gl texmem bar");
+ tmbp.texture_view(this);
+ mGLTexMemBar = LLUICtrlFactory::create<LLGLTexMemBar>(tmbp);
addChild(mGLTexMemBar);
reshape(getRect().getWidth(), getRect().getHeight(), TRUE);
/*
- count = gImageList.getNumImages();
+ count = gTextureList.getNumImages();
std::string info_string;
info_string = llformat("Global Info:\nTexture Count: %d", count);
mInfoTextp->setText(info_string);
@@ -737,7 +758,7 @@ void LLTextureView::draw()
}
-BOOL LLTextureView::addBar(LLViewerImage *imagep, S32 hilite)
+BOOL LLTextureView::addBar(LLViewerFetchedTexture *imagep, S32 hilite)
{
llassert(imagep);
@@ -746,7 +767,11 @@ BOOL LLTextureView::addBar(LLViewerImage *imagep, S32 hilite)
mNumTextureBars++;
- barp = new LLTextureBar("texture bar", r, this);
+ LLTextureBar::Params tbp;
+ tbp.name("texture bar");
+ tbp.rect(r);
+ tbp.texture_view(this);
+ barp = LLUICtrlFactory::create<LLTextureBar>(tbp);
barp->mImagep = imagep;
barp->mHilite = hilite;
diff --git a/indra/newview/lltextureview.h b/indra/newview/lltextureview.h
index f91a296b97..20be17aef4 100644
--- a/indra/newview/lltextureview.h
+++ b/indra/newview/lltextureview.h
@@ -35,7 +35,7 @@
#include "llcontainerview.h"
-class LLViewerImage;
+class LLViewerFetchedTexture;
class LLTextureBar;
class LLGLTexMemBar;
@@ -43,8 +43,10 @@ class LLTextureView : public LLContainerView
{
friend class LLTextureBar;
friend class LLGLTexMemBar;
+protected:
+ LLTextureView(const Params&);
+ friend class LLUICtrlFactory;
public:
- LLTextureView(const std::string& name, const LLRect& rect);
~LLTextureView();
/*virtual*/ void draw();
@@ -52,12 +54,12 @@ public:
/*virtual*/ BOOL handleMouseUp(S32 x, S32 y, MASK mask);
/*virtual*/ BOOL handleKey(KEY key, MASK mask, BOOL called_from_parent);
- static void addDebugImage(LLViewerImage* image) { sDebugImages.insert(image); }
- static void removeDebugImage(LLViewerImage* image) { sDebugImages.insert(image); }
+ static void addDebugImage(LLViewerFetchedTexture* image) { sDebugImages.insert(image); }
+ static void removeDebugImage(LLViewerFetchedTexture* image) { sDebugImages.insert(image); }
static void clearDebugImages() { sDebugImages.clear(); }
private:
- BOOL addBar(LLViewerImage *image, BOOL hilight = FALSE);
+ BOOL addBar(LLViewerFetchedTexture *image, BOOL hilight = FALSE);
void removeAllBars();
private:
@@ -73,7 +75,7 @@ private:
LLGLTexMemBar* mGLTexMemBar;
public:
- static std::set<LLViewerImage*> sDebugImages;
+ static std::set<LLViewerFetchedTexture*> sDebugImages;
};
extern LLTextureView *gTextureView;
diff --git a/indra/newview/lltoast.cpp b/indra/newview/lltoast.cpp
new file mode 100644
index 0000000000..85814a98c9
--- /dev/null
+++ b/indra/newview/lltoast.cpp
@@ -0,0 +1,294 @@
+/**
+ * @file lltoast.cpp
+ * @brief This class implements a placeholder for any notification panel.
+ *
+ * $LicenseInfo:firstyear=2000&license=viewergpl$
+ *
+ * Copyright (c) 2000-2009, Linden Research, Inc.
+ *
+ * Second Life Viewer Source Code
+ * The source code in this file ("Source Code") is provided by Linden Lab
+ * to you under the terms of the GNU General Public License, version 2.0
+ * ("GPL"), unless you have obtained a separate licensing agreement
+ * ("Other License"), formally executed by you and Linden Lab. Terms of
+ * the GPL can be found in doc/GPL-license.txt in this distribution, or
+ * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
+ *
+ * There are special exceptions to the terms and conditions of the GPL as
+ * it is applied to this Source Code. View the full text of the exception
+ * in the file doc/FLOSS-exception.txt in this software distribution, or
+ * online at
+ * http://secondlifegrid.net/programs/open_source/licensing/flossexception
+ *
+ * By copying, modifying or distributing this software, you acknowledge
+ * that you have read and understood your obligations described above,
+ * and agree to abide by those obligations.
+ *
+ * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+ * COMPLETENESS OR PERFORMANCE.
+ * $/LicenseInfo$
+ */
+
+#include "llviewerprecompiledheaders.h" // must be first include
+
+#include "lltoast.h"
+
+#include "llbutton.h"
+#include "llfocusmgr.h"
+#include "llviewercontrol.h"
+
+using namespace LLNotificationsUI;
+
+//--------------------------------------------------------------------------
+LLToast::LLToast(LLToast::Params p) : LLFloater(LLSD()),
+ mPanel(p.panel),
+ mTimerValue(p.timer_period),
+ mID(p.id),
+ mCanFade(p.can_fade),
+ mCanBeStored(p.can_be_stored),
+ mHideBtnEnabled(p.enable_hide_btn),
+ mIsModal(p.is_modal),
+ mHideBtn(NULL),
+ mNotification(p.notification),
+ mHideBtnPressed(false)
+{
+ LLUICtrlFactory::getInstance()->buildFloater(this, "panel_toast.xml", NULL);
+
+ if(mPanel)
+ {
+ insertPanel(mPanel);
+ }
+
+ if(mHideBtnEnabled)
+ {
+ mHideBtn = getChild<LLButton>("hide_btn");
+ mHideBtn->setClickedCallback(boost::bind(&LLToast::hide,this));
+ }
+
+ if(mIsModal)
+ {
+ gFocusMgr.setMouseCapture( this );
+ gFocusMgr.setTopCtrl( this );
+ setFocus(TRUE);
+ }
+
+
+ if(!p.on_toast_destroy.empty())
+ mOnToastDestroy.connect(p.on_toast_destroy);
+
+ if(!p.on_mouse_enter.empty())
+ mOnMousEnter.connect(p.on_mouse_enter);
+}
+
+//--------------------------------------------------------------------------
+BOOL LLToast::postBuild()
+{
+ if(mCanFade)
+ {
+ mTimer.start();
+ }
+ else
+ {
+ mTimer.stop();
+ }
+
+ return TRUE;
+}
+
+//--------------------------------------------------------------------------
+void LLToast::setHideButtonEnabled(bool enabled)
+{
+ if(mHideBtn)
+ mHideBtn->setEnabled(enabled);
+}
+
+//--------------------------------------------------------------------------
+LLToast::~LLToast()
+{
+ if(mIsModal)
+ {
+ gFocusMgr.unlockFocus();
+ gFocusMgr.releaseFocusIfNeeded( this );
+ }
+}
+
+//--------------------------------------------------------------------------
+void LLToast::setAndStartTimer(F32 period)
+{
+ if(mCanFade)
+ {
+ mTimerValue = period;
+ mTimer.start();
+ }
+}
+
+//--------------------------------------------------------------------------
+bool LLToast::timerHasExpired()
+{
+ if (mTimer.getStarted())
+ {
+ F32 elapsed_time = mTimer.getElapsedTimeF32();
+ if (elapsed_time > gSavedSettings.getS32("ToastOpaqueTime"))
+ {
+ setBackgroundOpaque(FALSE);
+ }
+ if (elapsed_time > mTimerValue)
+ {
+ return true;
+ }
+ }
+ return false;
+}
+
+//--------------------------------------------------------------------------
+void LLToast::hide()
+{
+ setVisible(FALSE);
+ mTimer.stop();
+ mOnFade(this);
+}
+
+//--------------------------------------------------------------------------
+void LLToast::setCanFade(bool can_fade)
+{
+ mCanFade = can_fade;
+ if(!mCanFade)
+ mTimer.stop();
+}
+
+//--------------------------------------------------------------------------
+void LLToast::tick()
+{
+ if(mCanFade)
+ {
+ setVisible(FALSE);
+ mTimer.stop();
+ mOnFade(this);
+ }
+}
+
+//--------------------------------------------------------------------------
+void LLToast::insertPanel(LLPanel* panel)
+{
+ LLRect panel_rect, toast_rect;
+
+ panel_rect = panel->getRect();
+ reshape(panel_rect.getWidth(), panel_rect.getHeight());
+ panel_rect.setLeftTopAndSize(0, panel_rect.getHeight(), panel_rect.getWidth(), panel_rect.getHeight());
+ panel->setRect(panel_rect);
+ addChild(panel);
+}
+
+//--------------------------------------------------------------------------
+void LLToast::draw()
+{
+ if(timerHasExpired())
+ {
+ tick();
+ }
+
+ LLFloater::draw();
+}
+
+//--------------------------------------------------------------------------
+void LLToast::setModal(bool modal)
+{
+ mIsModal = modal;
+ if(mIsModal)
+ {
+ gFocusMgr.setMouseCapture( this );
+ gFocusMgr.setTopCtrl( this );
+ setFocus(TRUE);
+ }
+}
+
+//--------------------------------------------------------------------------
+void LLToast::setVisible(BOOL show)
+{
+ if(show)
+ {
+ setBackgroundOpaque(TRUE);
+ }
+ LLPanel::setVisible(show);
+ if(mPanel)
+ {
+ if(!mPanel->isDead())
+ {
+ mPanel->setVisible(show);
+ }
+ }
+}
+
+//--------------------------------------------------------------------------
+void LLToast::onMouseEnter(S32 x, S32 y, MASK mask)
+{
+ mOnToastHover(this, MOUSE_ENTER);
+
+ setBackgroundOpaque(TRUE);
+ if(mCanFade)
+ {
+ mTimer.stop();
+ }
+
+ sendChildToFront(mHideBtn);
+ if(mHideBtn && mHideBtn->getEnabled())
+ mHideBtn->setVisible(TRUE);
+ mOnMousEnter(this);
+}
+
+//--------------------------------------------------------------------------
+void LLToast::onMouseLeave(S32 x, S32 y, MASK mask)
+{
+ mOnToastHover(this, MOUSE_LEAVE);
+
+ if(mCanFade)
+ {
+ mTimer.start();
+ }
+ if(mHideBtn && mHideBtn->getEnabled())
+ {
+ if( mHideBtnPressed )
+ {
+ mHideBtnPressed = false;
+ return;
+ }
+ mHideBtn->setVisible(FALSE);
+ }
+}
+
+//--------------------------------------------------------------------------
+
+BOOL LLToast::handleMouseDown(S32 x, S32 y, MASK mask)
+{
+ if(mHideBtn && mHideBtn->getEnabled())
+ {
+ mHideBtnPressed = mHideBtn->getRect().pointInRect(x, y);
+ }
+
+ return LLFloater::handleMouseDown(x, y, mask);
+}
+
+//--------------------------------------------------------------------------
+void LLToast::discardNotification()
+{
+ if(mNotification)
+ {
+ mNotification->setIgnored(TRUE);
+ mNotification->respond(mNotification->getResponseTemplate());
+ }
+}
+
+//--------------------------------------------------------------------------
+bool LLToast::getIsNotificationUnResponded()
+{
+ if(mNotification)
+ {
+ return !mNotification->isRespondedTo();
+ }
+ return false;
+}
+
+//--------------------------------------------------------------------------
+
+
diff --git a/indra/newview/lltoast.h b/indra/newview/lltoast.h
new file mode 100644
index 0000000000..969f3fd1cb
--- /dev/null
+++ b/indra/newview/lltoast.h
@@ -0,0 +1,170 @@
+/**
+ * @file lltoast.h
+ * @brief This class implements a placeholder for any notification panel.
+ *
+ * $LicenseInfo:firstyear=2003&license=viewergpl$
+ *
+ * Copyright (c) 2003-2009, Linden Research, Inc.
+ *
+ * Second Life Viewer Source Code
+ * The source code in this file ("Source Code") is provided by Linden Lab
+ * to you under the terms of the GNU General Public License, version 2.0
+ * ("GPL"), unless you have obtained a separate licensing agreement
+ * ("Other License"), formally executed by you and Linden Lab. Terms of
+ * the GPL can be found in doc/GPL-license.txt in this distribution, or
+ * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
+ *
+ * There are special exceptions to the terms and conditions of the GPL as
+ * it is applied to this Source Code. View the full text of the exception
+ * in the file doc/FLOSS-exception.txt in this software distribution, or
+ * online at
+ * http://secondlifegrid.net/programs/open_source/licensing/flossexception
+ *
+ * By copying, modifying or distributing this software, you acknowledge
+ * that you have read and understood your obligations described above,
+ * and agree to abide by those obligations.
+ *
+ * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+ * COMPLETENESS OR PERFORMANCE.
+ * $/LicenseInfo$
+ */
+
+#ifndef LL_LLTOAST_H
+#define LL_LLTOAST_H
+
+
+#include "llpanel.h"
+#include "llfloater.h"
+#include "lltimer.h"
+#include "llnotifications.h"
+
+#include "llviewercontrol.h"
+
+#define MOUSE_LEAVE false
+#define MOUSE_ENTER true
+
+namespace LLNotificationsUI
+{
+
+/**
+ * Represents toast pop-up.
+ * This is a parent view for all toast panels.
+ */
+class LLToast : public LLFloater
+{
+public:
+ typedef boost::function<void (LLToast* toast)> toast_callback_t;
+ typedef boost::signals2::signal<void (LLToast* toast)> toast_signal_t;
+
+ struct Params : public LLInitParam::Block<Params, LLFloater::Params>
+ {
+ LLPanel* panel;
+ LLUUID id; //notification or message ID
+ LLNotificationPtr notification;
+ F32 timer_period;
+ toast_callback_t on_toast_destroy;
+ toast_callback_t on_mouse_enter;
+ bool can_fade;
+ bool can_be_stored;
+ bool enable_hide_btn;
+ bool is_modal;
+ bool is_tip;
+
+ Params() : can_fade(true),
+ can_be_stored(true),
+ is_modal(false),
+ is_tip(false),
+ enable_hide_btn(true),
+ panel(NULL),
+ timer_period(gSavedSettings.getS32("NotificationToastTime"))
+
+ {};
+ };
+
+ LLToast(LLToast::Params p);
+ virtual ~LLToast();
+ BOOL postBuild();
+
+ // Toast handlers
+ virtual BOOL handleMouseDown(S32 x, S32 y, MASK mask);
+ virtual void onMouseEnter(S32 x, S32 y, MASK mask);
+ virtual void onMouseLeave(S32 x, S32 y, MASK mask);
+
+ // Operating with toasts
+ // insert a panel to a toast
+ void insertPanel(LLPanel* panel);
+ // get toast's panel
+ LLPanel* getPanel() { return mPanel; }
+ // discard notification
+ void discardNotification();
+ // enable/disable Toast's Hide button
+ void setHideButtonEnabled(bool enabled);
+ // initialize and start Toast's timer
+ void setAndStartTimer(F32 period);
+ //
+ void resetTimer() { mTimer.start(); }
+ //
+ void stopTimer() { mTimer.stop(); }
+ //
+ virtual void draw();
+ //
+ virtual void setVisible(BOOL show);
+ //
+ virtual void hide();
+
+
+
+ // get/set Toast's flags or states
+ // get information whether the notification corresponding to the toast is responded or not
+ bool getIsNotificationUnResponded();
+ //
+ void setCanFade(bool can_fade);
+ //
+ void setCanBeStored(bool can_be_stored) { mCanBeStored = can_be_stored; }
+ //
+ bool getCanBeStored() { return mCanBeStored; }
+ //
+ void setModal(bool modal);
+
+
+ // Registers callbacks for events
+ toast_signal_t mOnFade;
+ toast_signal_t mOnMousEnter;
+ toast_signal_t mOnToastDestroy;
+ boost::signals2::connection setOnFadeCallback(toast_callback_t cb) { return mOnFade.connect(cb); }
+ boost::signals2::connection setOnMouseEnterCallback(toast_callback_t cb) { return mOnMousEnter.connect(cb); }
+ boost::signals2::connection setOnToastDestroyCallback(toast_callback_t cb) { return mOnToastDestroy.connect(cb); }
+
+ typedef boost::function<void (LLToast* toast, bool mouse_enter)> toast_hover_check_callback_t;
+ typedef boost::signals2::signal<void (LLToast* toast, bool mouse_enter)> toast_hover_check_signal_t;
+ toast_hover_check_signal_t mOnToastHover;
+ boost::signals2::connection setOnToastHoverCallback(toast_hover_check_callback_t cb) { return mOnToastHover.connect(cb); }
+
+
+private:
+
+ // check timer
+ bool timerHasExpired();
+ // on timer finished function
+ void tick();
+
+ LLUUID mID;
+ LLNotificationPtr mNotification;
+
+ LLTimer mTimer;
+ F32 mTimerValue;
+
+ LLPanel* mPanel;
+ LLButton* mHideBtn;
+
+ LLColor4 mBgColor;
+ bool mCanFade;
+ bool mIsModal;
+ bool mCanBeStored;
+ bool mHideBtnEnabled;
+ bool mHideBtnPressed;
+};
+
+}
+#endif
diff --git a/indra/newview/lltoastalertpanel.cpp b/indra/newview/lltoastalertpanel.cpp
new file mode 100644
index 0000000000..4309f56710
--- /dev/null
+++ b/indra/newview/lltoastalertpanel.cpp
@@ -0,0 +1,474 @@
+/**
+ * @file lltoastalertpanel.cpp
+ * @brief Panel for alert toasts.
+ *
+ * $LicenseInfo:firstyear=2001&license=viewergpl$
+ *
+ * Copyright (c) 2001-2009, Linden Research, Inc.
+ *
+ * Second Life Viewer Source Code
+ * The source code in this file ("Source Code") is provided by Linden Lab
+ * to you under the terms of the GNU General Public License, version 2.0
+ * ("GPL"), unless you have obtained a separate licensing agreement
+ * ("Other License"), formally executed by you and Linden Lab. Terms of
+ * the GPL can be found in doc/GPL-license.txt in this distribution, or
+ * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
+ *
+ * There are special exceptions to the terms and conditions of the GPL as
+ * it is applied to this Source Code. View the full text of the exception
+ * in the file doc/FLOSS-exception.txt in this software distribution, or
+ * online at
+ * http://secondlifegrid.net/programs/open_source/licensing/flossexception
+ *
+ * By copying, modifying or distributing this software, you acknowledge
+ * that you have read and understood your obligations described above,
+ * and agree to abide by those obligations.
+ *
+ * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+ * COMPLETENESS OR PERFORMANCE.
+ * $/LicenseInfo$
+ */
+
+
+#include "llviewerprecompiledheaders.h" // must be first include
+
+#include "linden_common.h"
+
+#include "llboost.h"
+
+#include "lltoastalertpanel.h"
+#include "llfontgl.h"
+#include "lltextbox.h"
+#include "llbutton.h"
+#include "llcheckboxctrl.h"
+#include "llkeyboard.h"
+#include "llfocusmgr.h"
+#include "lliconctrl.h"
+#include "llui.h"
+#include "lllineeditor.h"
+#include "lluictrlfactory.h"
+#include "llnotifications.h"
+#include "llfunctorregistry.h"
+
+const S32 MAX_ALLOWED_MSG_WIDTH = 400;
+const F32 DEFAULT_BUTTON_DELAY = 0.5f;
+const S32 MSG_PAD = 8;
+
+/*static*/ LLControlGroup* LLToastAlertPanel::sSettings = NULL;
+/*static*/ LLToastAlertPanel::URLLoader* LLToastAlertPanel::sURLLoader;
+
+//-----------------------------------------------------------------------------
+// Private methods
+
+static const S32 VPAD = 16;
+static const S32 HPAD = 25;
+static const S32 BTN_HPAD = 8;
+
+LLToastAlertPanel::LLToastAlertPanel( LLNotificationPtr notification, bool modal)
+ : LLToastPanel(notification),
+ mDefaultOption( 0 ),
+ mCheck(NULL),
+ mCaution(notification->getPriority() >= NOTIFICATION_PRIORITY_HIGH),
+ mLabel(notification->getName()),
+ mLineEditor(NULL)
+{
+ const LLFontGL* font = LLFontGL::getFontSansSerif();
+ const S32 LINE_HEIGHT = llfloor(font->getLineHeight() + 0.99f);
+ const S32 EDITOR_HEIGHT = 20;
+
+ LLNotificationFormPtr form = mNotification->getForm();
+ std::string edit_text_name;
+ std::string edit_text_contents;
+ bool is_password = false;
+
+ LLToastPanel::setBackgroundVisible(FALSE);
+ LLToastPanel::setBackgroundOpaque(TRUE);
+
+
+ typedef std::vector<std::pair<std::string, std::string> > options_t;
+ options_t supplied_options;
+
+ // for now, get LLSD to iterator over form elements
+ LLSD form_sd = form->asLLSD();
+
+ S32 option_index = 0;
+ for (LLSD::array_const_iterator it = form_sd.beginArray(); it != form_sd.endArray(); ++it)
+ {
+ std::string type = (*it)["type"].asString();
+ if (type == "button")
+ {
+ if((*it)["default"])
+ {
+ mDefaultOption = option_index;
+ }
+
+ supplied_options.push_back(std::make_pair((*it)["name"].asString(), (*it)["text"].asString()));
+
+ ButtonData data;
+ if (option_index == mNotification->getURLOption())
+ {
+ data.mURL = mNotification->getURL();
+ data.mURLExternal = mNotification->getURLOpenExternally();
+ }
+
+ mButtonData.push_back(data);
+ option_index++;
+ }
+ else if (type == "text")
+ {
+ edit_text_contents = (*it)["value"].asString();
+ edit_text_name = (*it)["name"].asString();
+ }
+ else if (type == "password")
+ {
+ edit_text_contents = (*it)["value"].asString();
+ edit_text_name = (*it)["name"].asString();
+ is_password = true;
+ }
+ }
+
+ // Buttons
+ options_t options;
+ if (supplied_options.empty())
+ {
+ options.push_back(std::make_pair(std::string("close"), LLNotifications::instance().getGlobalString("implicitclosebutton")));
+
+ // add data for ok button.
+ ButtonData ok_button;
+ mButtonData.push_back(ok_button);
+ mDefaultOption = 0;
+ }
+ else
+ {
+ options = supplied_options;
+ }
+
+ S32 num_options = options.size();
+
+ // Calc total width of buttons
+ S32 button_width = 0;
+ S32 sp = font->getWidth(std::string("OO"));
+ for( S32 i = 0; i < num_options; i++ )
+ {
+ S32 w = S32(font->getWidth( options[i].second ) + 0.99f) + sp + 2 * LLBUTTON_H_PAD;
+ button_width = llmax( w, button_width );
+ }
+ S32 btn_total_width = button_width;
+ if( num_options > 1 )
+ {
+ btn_total_width = (num_options * button_width) + ((num_options - 1) * BTN_HPAD);
+ }
+
+ // Message: create text box using raw string, as text has been structure deliberately
+ // Use size of created text box to generate dialog box size
+ std::string msg = mNotification->getMessage();
+ llwarns << "Alert: " << msg << llendl;
+ LLTextBox::Params params;
+ params.name("Alert message");
+ params.font(font);
+ params.tab_stop(false);
+ params.follows.flags(FOLLOWS_LEFT | FOLLOWS_TOP);
+
+ LLTextBox * msg_box = LLUICtrlFactory::create<LLTextBox> (params);
+ // Compute max allowable height for the dialog text, so we can allocate
+ // space before wrapping the text to fit.
+ S32 max_allowed_msg_height =
+ gFloaterView->getRect().getHeight()
+ - LINE_HEIGHT // title bar
+ - 3*VPAD - BTN_HEIGHT;
+ msg_box->reshape( MAX_ALLOWED_MSG_WIDTH, max_allowed_msg_height );
+ msg_box->setWrappedText(msg, (F32)MAX_ALLOWED_MSG_WIDTH);
+ msg_box->reshapeToFitText();
+
+ const LLRect& text_rect = msg_box->getRect();
+ S32 dialog_width = llmax( btn_total_width, text_rect.getWidth() ) + 2 * HPAD;
+ S32 dialog_height = text_rect.getHeight() + 3 * VPAD + BTN_HEIGHT;
+
+ if (hasTitleBar())
+ {
+ dialog_height += LINE_HEIGHT; // room for title bar
+ }
+
+ // it's ok for the edit text body to be empty, but we want the name to exist if we're going to draw it
+ if (!edit_text_name.empty())
+ {
+ dialog_height += EDITOR_HEIGHT + VPAD;
+ dialog_width = llmax(dialog_width, (S32)(font->getWidth( edit_text_contents ) + 0.99f));
+ }
+
+ if (mCaution)
+ {
+ // Make room for the caution icon.
+ dialog_width += 32 + HPAD;
+ }
+
+ LLToastPanel::reshape( dialog_width, dialog_height, FALSE );
+
+ S32 msg_y = LLToastPanel::getRect().getHeight() - VPAD;
+ S32 msg_x = HPAD;
+ if (hasTitleBar())
+ {
+ msg_y -= LINE_HEIGHT; // room for title
+ }
+
+ static LLUIColor alert_caution_text_color = LLUIColorTable::instance().getColor("AlertCautionTextColor");
+ static LLUIColor alert_text_color = LLUIColorTable::instance().getColor("AlertTextColor");
+ if (mCaution)
+ {
+ LLIconCtrl::Params params;
+ params.name("icon");
+ params.rect(LLRect(msg_x, msg_y, msg_x+32, msg_y-32));
+ params.mouse_opaque(false);
+ params.follows.flags(FOLLOWS_LEFT | FOLLOWS_TOP);
+ params.tab_stop(false);
+ LLIconCtrl * icon = LLUICtrlFactory::create<LLIconCtrl> (params);
+ icon->setValue ("notify_caution_icon.tga");
+ icon->setMouseOpaque(FALSE);
+ LLToastPanel::addChild(icon);
+ msg_x += 32 + HPAD;
+ msg_box->setColor( alert_caution_text_color );
+ }
+ else
+ {
+ msg_box->setColor( alert_text_color );
+ }
+
+ LLRect rect;
+ rect.setLeftTopAndSize( msg_x, msg_y, text_rect.getWidth(), text_rect.getHeight() );
+ msg_box->setRect( rect );
+ LLToastPanel::addChild(msg_box);
+
+ // Buttons
+ S32 button_left = (LLToastPanel::getRect().getWidth() - btn_total_width) / 2;
+
+ for( S32 i = 0; i < num_options; i++ )
+ {
+ LLRect button_rect;
+ button_rect.setOriginAndSize( button_left, VPAD, button_width, BTN_HEIGHT );
+
+ LLButton::Params p;
+ p.name(options[i].first);
+ p.rect(button_rect);
+ p.click_callback.function(boost::bind(&LLToastAlertPanel::onButtonPressed, this, _2, i));
+ p.font(font);
+ p.label(options[i].second);
+
+ LLButton* btn = LLUICtrlFactory::create<LLButton>(p);
+ mButtonData[i].mButton = btn;
+
+ LLToastPanel::addChild(btn);
+
+ if( i == mDefaultOption )
+ {
+ btn->setFocus(TRUE);
+ }
+
+ button_left += button_width + BTN_HPAD;
+ }
+
+ // (Optional) Edit Box
+ if (!edit_text_name.empty())
+ {
+ S32 y = VPAD + BTN_HEIGHT + VPAD/2;
+
+ LLLineEditor::Params params;
+ params.name(edit_text_name);
+ params.rect(LLRect( HPAD, y+EDITOR_HEIGHT, dialog_width-HPAD, y));
+ params.default_text(edit_text_contents);
+ params.max_length_bytes(STD_STRING_STR_LEN);
+ mLineEditor = LLUICtrlFactory::create<LLLineEditor> (params);
+
+ // make sure all edit keys get handled properly (DEV-22396)
+ mLineEditor->setHandleEditKeysDirectly(TRUE);
+
+ LLToastPanel::addChild(mLineEditor);
+ }
+
+ if (mLineEditor)
+ {
+ mLineEditor->setDrawAsterixes(is_password);
+
+ setEditTextArgs(notification->getSubstitutions());
+ }
+
+ std::string ignore_label;
+
+ if (form->getIgnoreType() == LLNotificationForm::IGNORE_WITH_DEFAULT_RESPONSE)
+ {
+ setCheckBox(LLNotifications::instance().getGlobalString("skipnexttime"), ignore_label);
+ }
+ else if (form->getIgnoreType() == LLNotificationForm::IGNORE_WITH_LAST_RESPONSE)
+ {
+ setCheckBox(LLNotifications::instance().getGlobalString("alwayschoose"), ignore_label);
+ }
+
+ // *TODO: check necessity of this code
+ //gFloaterView->adjustToFitScreen(this, FALSE);
+ if (mLineEditor)
+ {
+ mLineEditor->setFocus(TRUE);
+ mLineEditor->selectAll();
+ }
+ if(mDefaultOption >= 0)
+ {
+ // delay before enabling default button
+ mDefaultBtnTimer.start();
+ mDefaultBtnTimer.setTimerExpirySec(DEFAULT_BUTTON_DELAY);
+ }
+}
+
+bool LLToastAlertPanel::setCheckBox( const std::string& check_title, const std::string& check_control )
+{
+ const LLFontGL* font = LLFontGL::getFontSansSerif();
+ const S32 LINE_HEIGHT = llfloor(font->getLineHeight() + 0.99f);
+
+ // Extend dialog for "check next time"
+ S32 max_msg_width = LLToastPanel::getRect().getWidth() - 2 * HPAD;
+ S32 check_width = S32(font->getWidth(check_title) + 0.99f) + 16;
+ max_msg_width = llmax(max_msg_width, check_width);
+ S32 dialog_width = max_msg_width + 2 * HPAD;
+
+ S32 dialog_height = LLToastPanel::getRect().getHeight();
+ dialog_height += LINE_HEIGHT;
+ dialog_height += LINE_HEIGHT / 2;
+
+ LLToastPanel::reshape( dialog_width, dialog_height, FALSE );
+
+ S32 msg_x = (LLToastPanel::getRect().getWidth() - max_msg_width) / 2;
+
+ LLCheckBoxCtrl::Params p;
+ p.name("check");
+ p.rect.left(msg_x).bottom(VPAD+BTN_HEIGHT+LINE_HEIGHT/2).width(max_msg_width).height(LINE_HEIGHT);
+ p.label(check_title);
+ p.font(font);
+ p.commit_callback.function(boost::bind(&LLToastAlertPanel::onClickIgnore, this, _1));
+ mCheck = LLUICtrlFactory::create<LLCheckBoxCtrl>(p);
+ LLToastPanel::addChild(mCheck);
+
+ return true;
+}
+
+void LLToastAlertPanel::setVisible( BOOL visible )
+{
+ // only make the "ding" sound if it's newly visible
+ if( visible && !LLToastPanel::getVisible() )
+ {
+ make_ui_sound("UISndAlert");
+ }
+
+ LLToastPanel::setVisible( visible );
+
+}
+
+LLToastAlertPanel::~LLToastAlertPanel()
+{
+}
+
+BOOL LLToastAlertPanel::hasTitleBar() const
+{
+ // *TODO: check necessity of this code
+ /*
+ return (getCurrentTitle() != "" && getCurrentTitle() != " ") // has title
+ || isMinimizeable()
+ || isCloseable();
+ */
+ return false;
+}
+
+BOOL LLToastAlertPanel::handleKeyHere(KEY key, MASK mask )
+{
+ if( KEY_RETURN == key && mask == MASK_NONE )
+ {
+ return TRUE;
+ }
+ else if (KEY_RIGHT == key)
+ {
+ LLToastPanel::focusNextItem(FALSE);
+ return TRUE;
+ }
+ else if (KEY_LEFT == key)
+ {
+ LLToastPanel::focusPrevItem(FALSE);
+ return TRUE;
+ }
+ else if (KEY_TAB == key && mask == MASK_NONE)
+ {
+ LLToastPanel::focusNextItem(FALSE);
+ return TRUE;
+ }
+ else if (KEY_TAB == key && mask == MASK_SHIFT)
+ {
+ LLToastPanel::focusPrevItem(FALSE);
+ return TRUE;
+ }
+ else
+ {
+ return TRUE;
+ }
+}
+
+// virtual
+void LLToastAlertPanel::draw()
+{
+ // if the default button timer has just expired, activate the default button
+ if(mDefaultBtnTimer.hasExpired() && mDefaultBtnTimer.getStarted())
+ {
+ mDefaultBtnTimer.stop(); // prevent this block from being run more than once
+ LLToastPanel::setDefaultBtn(mButtonData[mDefaultOption].mButton);
+ }
+
+ static LLUIColor shadow_color = LLUIColorTable::instance().getColor("ColorDropShadow");
+ static LLUICachedControl<S32> shadow_lines ("DropShadowFloater");
+
+ gl_drop_shadow( 0, LLToastPanel::getRect().getHeight(), LLToastPanel::getRect().getWidth(), 0,
+ shadow_color, shadow_lines);
+
+ LLToastPanel::draw();
+}
+
+void LLToastAlertPanel::setEditTextArgs(const LLSD& edit_args)
+{
+ if (mLineEditor)
+ {
+ std::string msg = mLineEditor->getText();
+ mLineEditor->setText(msg);
+ }
+ else
+ {
+ llwarns << "LLToastAlertPanel::setEditTextArgs called on dialog with no line editor" << llendl;
+ }
+}
+
+void LLToastAlertPanel::onButtonPressed( const LLSD& data, S32 button )
+{
+ ButtonData* button_data = &mButtonData[button];
+
+ LLSD response = mNotification->getResponseTemplate();
+ if (mLineEditor)
+ {
+ response[mLineEditor->getName()] = mLineEditor->getValue();
+ }
+ response[button_data->mButton->getName()] = true;
+
+ // If we declared a URL and chose the URL option, go to the url
+ if (!button_data->mURL.empty() && sURLLoader != NULL)
+ {
+ sURLLoader->load(button_data->mURL, button_data->mURLExternal);
+ }
+
+ mNotification->respond(response); // new notification reponse
+}
+
+void LLToastAlertPanel::onClickIgnore(LLUICtrl* ctrl)
+{
+ // checkbox sometimes means "hide and do the default" and
+ // other times means "warn me again". Yuck. JC
+ BOOL check = ctrl->getValue().asBoolean();
+ if (mNotification->getForm()->getIgnoreType() == LLNotificationForm::IGNORE_SHOW_AGAIN)
+ {
+ // question was "show again" so invert value to get "ignore"
+ check = !check;
+ }
+ mNotification->setIgnored(check);
+}
diff --git a/indra/newview/lltoastalertpanel.h b/indra/newview/lltoastalertpanel.h
new file mode 100644
index 0000000000..af0c9a9ddd
--- /dev/null
+++ b/indra/newview/lltoastalertpanel.h
@@ -0,0 +1,122 @@
+/**
+ * @file lltoastalertpanel.h
+ * @brief Panel for alert toasts.
+ *
+ * $LicenseInfo:firstyear=2001&license=viewergpl$
+ *
+ * Copyright (c) 2001-2009, Linden Research, Inc.
+ *
+ * Second Life Viewer Source Code
+ * The source code in this file ("Source Code") is provided by Linden Lab
+ * to you under the terms of the GNU General Public License, version 2.0
+ * ("GPL"), unless you have obtained a separate licensing agreement
+ * ("Other License"), formally executed by you and Linden Lab. Terms of
+ * the GPL can be found in doc/GPL-license.txt in this distribution, or
+ * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
+ *
+ * There are special exceptions to the terms and conditions of the GPL as
+ * it is applied to this Source Code. View the full text of the exception
+ * in the file doc/FLOSS-exception.txt in this software distribution, or
+ * online at
+ * http://secondlifegrid.net/programs/open_source/licensing/flossexception
+ *
+ * By copying, modifying or distributing this software, you acknowledge
+ * that you have read and understood your obligations described above,
+ * and agree to abide by those obligations.
+ *
+ * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+ * COMPLETENESS OR PERFORMANCE.
+ * $/LicenseInfo$
+ */
+
+#ifndef LL_TOASTALERTPANEL_H
+#define LL_TOASTALERTPANEL_H
+
+#include "lltoastpanel.h"
+#include "llfloater.h"
+#include "llui.h"
+#include "llnotifications.h"
+
+class LLButton;
+class LLCheckBoxCtrl;
+class LLAlertDialogTemplate;
+class LLLineEditor;
+
+/**
+ * Toast panel for alert notification.
+ * Alerts notifications doesn't require user interaction.
+ *
+ * Replaces class LLAlertDialog.
+ * https://wiki.lindenlab.com/mediawiki/index.php?title=LLAlertDialog&oldid=81388
+ */
+
+class LLToastAlertPanel
+ : public LLToastPanel
+{
+public:
+ typedef bool (*display_callback_t)(S32 modal);
+
+ class URLLoader
+ {
+ public:
+ virtual void load(const std::string& url, bool force_open_externally = 0 ) = 0;
+ virtual ~URLLoader() {}
+ };
+
+ static void setURLLoader(URLLoader* loader)
+ {
+ sURLLoader = loader;
+ }
+
+public:
+ // User's responsibility to call show() after creating these.
+ LLToastAlertPanel( LLNotificationPtr notep, bool is_modal );
+
+ virtual BOOL handleKeyHere(KEY key, MASK mask );
+
+ virtual void draw();
+ virtual void setVisible( BOOL visible );
+
+ bool setCheckBox( const std::string&, const std::string& );
+ void setCaution(BOOL val = TRUE) { mCaution = val; }
+ // If mUnique==TRUE only one copy of this message should exist
+ void setUnique(BOOL val = TRUE) { mUnique = val; }
+ void setEditTextArgs(const LLSD& edit_args);
+
+ void onClickIgnore(LLUICtrl* ctrl);
+ void onButtonPressed(const LLSD& data, S32 button);
+
+private:
+ static std::map<std::string, LLToastAlertPanel*> sUniqueActiveMap;
+
+ virtual ~LLToastAlertPanel();
+ // No you can't kill it. It can only kill itself.
+
+ // Does it have a readable title label, or minimize or close buttons?
+ BOOL hasTitleBar() const;
+
+private:
+ static URLLoader* sURLLoader;
+ static LLControlGroup* sSettings;
+
+ struct ButtonData
+ {
+ LLButton* mButton;
+ std::string mURL;
+ U32 mURLExternal;
+ };
+ std::vector<ButtonData> mButtonData;
+
+ S32 mDefaultOption;
+ LLCheckBoxCtrl* mCheck;
+ BOOL mCaution;
+ BOOL mUnique;
+ LLUIString mLabel;
+ LLFrameTimer mDefaultBtnTimer;
+ // For Dialogs that take a line as text as input:
+ LLLineEditor* mLineEditor;
+
+};
+
+#endif // LL_TOASTALERTPANEL_H
diff --git a/indra/newview/lltoastgroupnotifypanel.cpp b/indra/newview/lltoastgroupnotifypanel.cpp
new file mode 100644
index 0000000000..6f26b4077c
--- /dev/null
+++ b/indra/newview/lltoastgroupnotifypanel.cpp
@@ -0,0 +1,209 @@
+/**
+ * @file lltoastgroupnotifypanel.cpp
+ * @brief Panel for group notify toasts.
+ *
+ * $LicenseInfo:firstyear=2001&license=viewergpl$
+ *
+ * Copyright (c) 2001-2009, Linden Research, Inc.
+ *
+ * Second Life Viewer Source Code
+ * The source code in this file ("Source Code") is provided by Linden Lab
+ * to you under the terms of the GNU General Public License, version 2.0
+ * ("GPL"), unless you have obtained a separate licensing agreement
+ * ("Other License"), formally executed by you and Linden Lab. Terms of
+ * the GPL can be found in doc/GPL-license.txt in this distribution, or
+ * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
+ *
+ * There are special exceptions to the terms and conditions of the GPL as
+ * it is applied to this Source Code. View the full text of the exception
+ * in the file doc/FLOSS-exception.txt in this software distribution, or
+ * online at
+ * http://secondlifegrid.net/programs/open_source/licensing/flossexception
+ *
+ * By copying, modifying or distributing this software, you acknowledge
+ * that you have read and understood your obligations described above,
+ * and agree to abide by those obligations.
+ *
+ * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+ * COMPLETENESS OR PERFORMANCE.
+ * $/LicenseInfo$
+ */
+
+#include "llviewerprecompiledheaders.h"
+
+#include "lltoastgroupnotifypanel.h"
+
+#include "llfocusmgr.h"
+
+#include "llbutton.h"
+#include "lliconctrl.h"
+#include "llnotify.h"
+#include "lltextbox.h"
+#include "lltexteditor.h"
+#include "lluiconstants.h"
+#include "llui.h"
+#include "llviewercontrol.h"
+#include "lltrans.h"
+#include "llstyle.h"
+
+#include "llglheaders.h"
+#include "llagent.h"
+#include "llavatariconctrl.h"
+#include "llfloaterinventory.h"
+#include "llinventorytype.h"
+
+LLToastGroupNotifyPanel::LLToastGroupNotifyPanel(LLNotificationPtr& notification)
+: LLToastPanel(notification),
+ mInventoryOffer(NULL)
+{
+ LLUICtrlFactory::getInstance()->buildPanel(this, "panel_group_notify.xml");
+ const LLSD& payload = notification->getPayload();
+ LLGroupData groupData;
+ if (!gAgent.getGroupData(payload["group_id"].asUUID(),groupData))
+ {
+ llwarns << "Group notice for unkown group: " << payload["group_id"].asUUID() << llendl;
+ }
+
+ static const LLUIColor textColor = LLUIColorTable::instance().getColor("GroupNotifyTextColor");
+
+ //group icon
+ LLIconCtrl* pGroupIcon = getChild<LLIconCtrl>("group_icon", TRUE);
+ pGroupIcon->setValue(groupData.mInsigniaID);
+
+ //header title
+ const std::string& from_name = payload["sender_name"].asString();
+ std::stringstream from;
+ from << from_name << "/" << groupData.mName;
+ LLTextBox* pTitleText = getChild<LLTextBox>("title");
+ pTitleText->setValue(from.str());
+
+ //message body
+ const std::string& subject = payload["subject"].asString();
+ const std::string& message = payload["message"].asString();
+
+ LLTextEditor* pMessageText = getChild<LLTextEditor>("message");
+ pMessageText->setValue("");
+ pMessageText->setEnabled(FALSE);
+
+ LLStyle::Params date_style;
+ date_style.color = textColor;
+ date_style.font.name = "SANSSERIF";
+
+ LLStyle::Params header_style_params;
+ header_style_params.color = textColor;
+ header_style_params.font = LLFontGL::getFontSansSerifBig();
+ pMessageText->appendStyledText(subject + "\n",false,false,header_style_params);
+
+ std::string timeStr = "["+LLTrans::getString("UTCTimeWeek")+"],["
+ +LLTrans::getString("UTCTimeDay")+"] ["
+ +LLTrans::getString("UTCTimeMth")+"] ["
+ +LLTrans::getString("UTCTimeYr")+"] ["
+ +LLTrans::getString("UTCTimeHr")+"]:["
+ +LLTrans::getString("UTCTimeMin")+"]:["
+ +LLTrans::getString("UTCTimeSec")+"] ["
+ +LLTrans::getString("UTCTimeTimezone")+"]";
+ const LLDate timeStamp = notification->getDate();
+ LLDate notice_date = timeStamp.notNull() ? timeStamp : LLDate::now();
+ LLSD substitution;
+ substitution["datetime"] = (S32) notice_date.secondsSinceEpoch();
+ LLStringUtil::format(timeStr, substitution);
+ LLStyle::Params date_style_params;
+ date_style_params.color = textColor;
+ date_style_params.font = LLFontGL::getFontMonospace();
+ pMessageText->appendStyledText(timeStr, false, false, date_style);
+ pMessageText->appendColoredText(std::string("\n\n") + message, false,
+ false, textColor);
+
+ //attachment
+ BOOL hasInventory = payload["inventory_offer"].isDefined();
+ LLTextBox * pAttachLink = getChild<LLTextBox>("attachment");
+ pAttachLink->setVisible(hasInventory);
+ if (hasInventory) {
+ pAttachLink->setValue(payload["inventory_name"]);
+ mInventoryOffer = new LLOfferInfo(payload["inventory_offer"]);
+ childSetActionTextbox("attachment", boost::bind(
+ &LLToastGroupNotifyPanel::onClickAttachment, this));
+
+ //attachment icon
+ LLIconCtrl* pAttachIcon = getChild<LLIconCtrl>("attachment_icon", TRUE);
+ LLUIImagePtr attachIconImg = get_item_icon(mInventoryOffer->mType,
+ LLInventoryType::IT_TEXTURE,
+ 0, FALSE);
+ pAttachIcon->setValue(attachIconImg->getName());
+ }
+
+ //ok button
+ LLButton* pOkBtn = getChild<LLButton>("btn_ok");
+ pOkBtn->setClickedCallback((boost::bind(&LLToastGroupNotifyPanel::onClickOk, this)));
+ setDefaultBtn(pOkBtn);
+}
+
+
+// virtual
+LLToastGroupNotifyPanel::~LLToastGroupNotifyPanel()
+{
+}
+
+void LLToastGroupNotifyPanel::close()
+{
+ // The group notice dialog may be an inventory offer.
+ // If it has an inventory save button and that button is still enabled
+ // Then we need to send the inventory declined message
+ if(mInventoryOffer != NULL)
+ {
+ mInventoryOffer->forceResponse(IOR_DECLINE);
+ mInventoryOffer = NULL;
+ }
+
+ die();
+}
+
+void LLToastGroupNotifyPanel::onClickOk()
+{
+ LLSD response = mNotification->getResponseTemplate();
+ mNotification->respond(response);
+ close();
+}
+
+void LLToastGroupNotifyPanel::onClickAttachment()
+{
+ if (mInventoryOffer != NULL) {
+ mInventoryOffer->forceResponse(IOR_ACCEPT);
+
+ LLTextBox * pAttachLink = getChild<LLTextBox> ("attachment");
+ static const LLUIColor textColor = LLUIColorTable::instance().getColor(
+ "GroupNotifyDimmedTextColor");
+ pAttachLink->setColor(textColor);
+
+ LLIconCtrl* pAttachIcon =
+ getChild<LLIconCtrl> ("attachment_icon", TRUE);
+ pAttachIcon->setEnabled(FALSE);
+
+ //if attachment isn't openable - notify about saving
+ if (!isAttachmentOpenable(mInventoryOffer->mType)) {
+ LLNotifications::instance().add("AttachmentSaved");
+ }
+
+ mInventoryOffer = NULL;
+ }
+}
+
+//static
+bool LLToastGroupNotifyPanel::isAttachmentOpenable(LLAssetType::EType type)
+{
+ switch(type)
+ {
+ case LLAssetType::AT_LANDMARK:
+ case LLAssetType::AT_FAVORITE:
+ case LLAssetType::AT_NOTECARD:
+ case LLAssetType::AT_IMAGE_JPEG:
+ case LLAssetType::AT_IMAGE_TGA:
+ case LLAssetType::AT_TEXTURE:
+ case LLAssetType::AT_TEXTURE_TGA:
+ return true;
+ default:
+ return false;
+ }
+}
+
diff --git a/indra/newview/lltoastgroupnotifypanel.h b/indra/newview/lltoastgroupnotifypanel.h
new file mode 100644
index 0000000000..ba98531251
--- /dev/null
+++ b/indra/newview/lltoastgroupnotifypanel.h
@@ -0,0 +1,83 @@
+/**
+ * @file lltoastgroupnotifypanel.h
+ * @brief Panel for group notify toasts.
+ *
+ * $LicenseInfo:firstyear=2001&license=viewergpl$
+ *
+ * Copyright (c) 2001-2009, Linden Research, Inc.
+ *
+ * Second Life Viewer Source Code
+ * The source code in this file ("Source Code") is provided by Linden Lab
+ * to you under the terms of the GNU General Public License, version 2.0
+ * ("GPL"), unless you have obtained a separate licensing agreement
+ * ("Other License"), formally executed by you and Linden Lab. Terms of
+ * the GPL can be found in doc/GPL-license.txt in this distribution, or
+ * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
+ *
+ * There are special exceptions to the terms and conditions of the GPL as
+ * it is applied to this Source Code. View the full text of the exception
+ * in the file doc/FLOSS-exception.txt in this software distribution, or
+ * online at
+ * http://secondlifegrid.net/programs/open_source/licensing/flossexception
+ *
+ * By copying, modifying or distributing this software, you acknowledge
+ * that you have read and understood your obligations described above,
+ * and agree to abide by those obligations.
+ *
+ * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+ * COMPLETENESS OR PERFORMANCE.
+ * $/LicenseInfo$
+ */
+
+#ifndef LL_LLGROUPNOTIFY_H
+#define LL_LLGROUPNOTIFY_H
+
+#include "llfontgl.h"
+#include "lltoastpanel.h"
+#include "lldarray.h"
+#include "lltimer.h"
+#include "llviewermessage.h"
+#include "llnotifications.h"
+
+class LLButton;
+
+/**
+ * Toast panel for group notification.
+ *
+ * Replaces class LLGroupNotifyBox.
+ */
+class LLToastGroupNotifyPanel
+: public LLToastPanel
+{
+public:
+ void close();
+
+ static bool onNewNotification(const LLSD& notification);
+
+
+ // Non-transient messages. You can specify non-default button
+ // layouts (like one for script dialogs) by passing various
+ // numbers in for "layout".
+ LLToastGroupNotifyPanel(LLNotificationPtr& notification);
+
+ /*virtual*/ ~LLToastGroupNotifyPanel();
+protected:
+ void onClickOk();
+ void onClickAttachment();
+private:
+ static bool isAttachmentOpenable(LLAssetType::EType);
+
+ LLButton* mSaveInventoryBtn;
+
+ LLUUID mGroupID;
+ LLOfferInfo* mInventoryOffer;
+};
+
+// This view contains the stack of notification windows.
+//extern LLView* gGroupNotifyBoxView;
+
+const S32 GROUP_LAYOUT_DEFAULT = 0;
+const S32 GROUP_LAYOUT_SCRIPT_DIALOG = 1;
+
+#endif
diff --git a/indra/newview/lltoastimpanel.cpp b/indra/newview/lltoastimpanel.cpp
new file mode 100644
index 0000000000..e41181c9e1
--- /dev/null
+++ b/indra/newview/lltoastimpanel.cpp
@@ -0,0 +1,94 @@
+/**
+ * @file lltoastimpanel.cpp
+ * @brief Panel for IM toasts.
+ *
+ * $LicenseInfo:firstyear=2001&license=viewergpl$
+ *
+ * Copyright (c) 2001-2009, Linden Research, Inc.
+ *
+ * Second Life Viewer Source Code
+ * The source code in this file ("Source Code") is provided by Linden Lab
+ * to you under the terms of the GNU General Public License, version 2.0
+ * ("GPL"), unless you have obtained a separate licensing agreement
+ * ("Other License"), formally executed by you and Linden Lab. Terms of
+ * the GPL can be found in doc/GPL-license.txt in this distribution, or
+ * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
+ *
+ * There are special exceptions to the terms and conditions of the GPL as
+ * it is applied to this Source Code. View the full text of the exception
+ * in the file doc/FLOSS-exception.txt in this software distribution, or
+ * online at
+ * http://secondlifegrid.net/programs/open_source/licensing/flossexception
+ *
+ * By copying, modifying or distributing this software, you acknowledge
+ * that you have read and understood your obligations described above,
+ * and agree to abide by those obligations.
+ *
+ * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+ * COMPLETENESS OR PERFORMANCE.
+ * $/LicenseInfo$
+ */
+
+#include "llviewerprecompiledheaders.h"
+#include "lltoastimpanel.h"
+#include "llimpanel.h"
+
+const S32 LLToastIMPanel::MAX_MESSAGE_HEIGHT = 50;
+const S32 LLToastIMPanel::CAPTION_HEIGHT = 30;
+const S32 LLToastIMPanel::TOP_PAD = 5;
+
+//--------------------------------------------------------------------------
+LLToastIMPanel::LLToastIMPanel(LLToastIMPanel::Params &p) : LLToastPanel(p.notification),
+ mAvatar(NULL), mUserName(NULL),
+ mTime(NULL), mMessage(NULL),
+ mReplyBtn(NULL)
+{
+ LLUICtrlFactory::getInstance()->buildPanel(this, "panel_instant_message.xml");
+
+ mAvatar = getChild<LLAvatarIconCtrl>("avatar");
+ mUserName = getChild<LLTextBox>("user_name");
+ mTime = getChild<LLTextBox>("time_box");
+ mMessage = getChild<LLTextBox>("message");
+ mReplyBtn = getChild<LLButton>("reply");
+
+ mMessage->setValue(p.message);
+ mAvatar->setValue(p.avatar_id);
+ mUserName->setValue(p.from);
+ mTime->setValue(p.time);
+ mSessionID = p.session_id;
+
+ mReplyBtn->setClickedCallback(boost::bind(&LLToastIMPanel::onClickReplyBtn, this));
+
+ snapToMessageHeight();
+}
+
+//--------------------------------------------------------------------------
+LLToastIMPanel::~LLToastIMPanel()
+{
+}
+
+//--------------------------------------------------------------------------
+void LLToastIMPanel::snapToMessageHeight()
+{
+ S32 required_text_height = mMessage->getTextPixelHeight();
+ S32 text_height = llmin(required_text_height, MAX_MESSAGE_HEIGHT);
+ LLRect text_rect = mMessage->getRect();
+ LLRect btn_rect = mReplyBtn->getRect();
+
+
+ mMessage->reshape( text_rect.getWidth(), text_height, TRUE);
+ mMessage->setValue(mMessage->getText());
+
+ S32 panel_height = CAPTION_HEIGHT + text_height + btn_rect.getHeight() + TOP_PAD*5;
+ reshape( getRect().getWidth(), panel_height, TRUE);
+}
+
+//--------------------------------------------------------------------------
+void LLToastIMPanel::onClickReplyBtn()
+{
+ LLIMFloater::toggle(mSessionID);
+}
+
+//--------------------------------------------------------------------------
+
diff --git a/indra/newview/lltoastimpanel.h b/indra/newview/lltoastimpanel.h
new file mode 100644
index 0000000000..7f5d6eca1d
--- /dev/null
+++ b/indra/newview/lltoastimpanel.h
@@ -0,0 +1,79 @@
+/**
+ * @file lltoastimpanel.h
+ * @brief Panel for IM toasts.
+ *
+ * $LicenseInfo:firstyear=2001&license=viewergpl$
+ *
+ * Copyright (c) 2001-2009, Linden Research, Inc.
+ *
+ * Second Life Viewer Source Code
+ * The source code in this file ("Source Code") is provided by Linden Lab
+ * to you under the terms of the GNU General Public License, version 2.0
+ * ("GPL"), unless you have obtained a separate licensing agreement
+ * ("Other License"), formally executed by you and Linden Lab. Terms of
+ * the GPL can be found in doc/GPL-license.txt in this distribution, or
+ * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
+ *
+ * There are special exceptions to the terms and conditions of the GPL as
+ * it is applied to this Source Code. View the full text of the exception
+ * in the file doc/FLOSS-exception.txt in this software distribution, or
+ * online at
+ * http://secondlifegrid.net/programs/open_source/licensing/flossexception
+ *
+ * By copying, modifying or distributing this software, you acknowledge
+ * that you have read and understood your obligations described above,
+ * and agree to abide by those obligations.
+ *
+ * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+ * COMPLETENESS OR PERFORMANCE.
+ * $/LicenseInfo$
+ */
+
+#ifndef LLTOASTIMPANEL_H_
+#define LLTOASTIMPANEL_H_
+
+
+#include "lltoastpanel.h"
+#include "lltextbox.h"
+#include "llbutton.h"
+#include "llavatariconctrl.h"
+
+
+class LLToastIMPanel: public LLToastPanel
+{
+public:
+ struct Params : public LLInitParam::Block<Params>
+ {
+ LLNotificationPtr notification;
+ LLUUID avatar_id;
+ LLUUID session_id;
+ std::string from;
+ std::string time;
+ std::string message;
+
+ Params() {}
+ };
+
+ LLToastIMPanel(LLToastIMPanel::Params &p);
+ virtual ~LLToastIMPanel();
+
+private:
+ static const S32 MAX_MESSAGE_HEIGHT;
+ static const S32 CAPTION_HEIGHT;
+ static const S32 TOP_PAD;
+
+ void onClickReplyBtn();
+ void snapToMessageHeight();
+
+ LLUUID mSessionID;
+ LLAvatarIconCtrl* mAvatar;
+ LLTextBox* mUserName;
+ LLTextBox* mTime;
+ LLTextBox* mMessage;
+ LLButton* mReplyBtn;
+};
+
+#endif // LLTOASTIMPANEL_H_
+
+
diff --git a/indra/newview/lltoastnotifypanel.cpp b/indra/newview/lltoastnotifypanel.cpp
new file mode 100644
index 0000000000..844c54da6a
--- /dev/null
+++ b/indra/newview/lltoastnotifypanel.cpp
@@ -0,0 +1,432 @@
+/**
+ * @file lltoastnotifypanel.cpp
+ * @brief Panel for notify toasts.
+ *
+ * $LicenseInfo:firstyear=2001&license=viewergpl$
+ *
+ * Copyright (c) 2001-2009, Linden Research, Inc.
+ *
+ * Second Life Viewer Source Code
+ * The source code in this file ("Source Code") is provided by Linden Lab
+ * to you under the terms of the GNU General Public License, version 2.0
+ * ("GPL"), unless you have obtained a separate licensing agreement
+ * ("Other License"), formally executed by you and Linden Lab. Terms of
+ * the GPL can be found in doc/GPL-license.txt in this distribution, or
+ * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
+ *
+ * There are special exceptions to the terms and conditions of the GPL as
+ * it is applied to this Source Code. View the full text of the exception
+ * in the file doc/FLOSS-exception.txt in this software distribution, or
+ * online at
+ * http://secondlifegrid.net/programs/open_source/licensing/flossexception
+ *
+ * By copying, modifying or distributing this software, you acknowledge
+ * that you have read and understood your obligations described above,
+ * and agree to abide by those obligations.
+ *
+ * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+ * COMPLETENESS OR PERFORMANCE.
+ * $/LicenseInfo$
+ */
+
+#include "llviewerprecompiledheaders.h"
+
+#include "lltoastnotifypanel.h"
+#include "llviewercontrol.h"
+#include "lluiconstants.h"
+#include "llrect.h"
+#include "lliconctrl.h"
+#include "lltexteditor.h"
+#include "lltextbox.h"
+#include "lldbstrings.h"
+#include "llchat.h"
+#include "llfloaterchat.h"
+#include "lltrans.h"
+#include "lloverlaybar.h"
+
+
+const S32 BOTTOM_PAD = VPAD * 3;
+
+//static
+const LLFontGL* LLToastNotifyPanel::sFont = NULL;
+const LLFontGL* LLToastNotifyPanel::sFontSmall = NULL;
+
+LLToastNotifyPanel::LLToastNotifyPanel(LLNotificationPtr& notification) : LLToastPanel(notification) {
+ mIsTip = notification->getType() == "notifytip";
+ mNumOptions = 0;
+ mNumButtons = 0;
+ mIsScriptDialog = (notification->getName() == "ScriptDialog"
+ || notification->getName() == "ScriptDialogGroup");
+ mAddedDefaultBtn = false;
+
+ // clicking on a button does not steal current focus
+ setIsChrome(TRUE);
+
+ // class init
+ if (!sFont)
+ {
+ sFont = LLFontGL::getFontSansSerif();
+ sFontSmall = LLFontGL::getFontSansSerifSmall();
+ }
+
+ // setup paramaters
+ mMessage = notification->getMessage();
+
+ // initialize
+ setFocusRoot(!mIsTip);
+
+ // caution flag can be set explicitly by specifying it in the
+ // notification payload, or it can be set implicitly if the
+ // notify xml template specifies that it is a caution
+ //
+ // tip-style notification handle 'caution' differently -
+ // they display the tip in a different color
+ mIsCaution = notification->getPriority() >= NOTIFICATION_PRIORITY_HIGH;
+
+ LLNotificationFormPtr form(notification->getForm());
+
+ mNumOptions = form->getNumElements();
+
+ LLRect rect = mIsTip ? getNotifyTipRect(mMessage)
+ : getNotifyRect(mNumOptions, mIsScriptDialog, mIsCaution);
+ setRect(rect);
+ setFollows(mIsTip ? (FOLLOWS_BOTTOM|FOLLOWS_RIGHT) : (FOLLOWS_TOP|FOLLOWS_RIGHT));
+ setBackgroundVisible(FALSE);
+ setBackgroundOpaque(TRUE);
+
+ LLIconCtrl* icon;
+ LLTextEditor* text;
+
+ const S32 TOP = getRect().getHeight() - (mIsTip ? (S32)sFont->getLineHeight() : 32);
+ const S32 BOTTOM = (S32)sFont->getLineHeight();
+ S32 x = HPAD + HPAD;
+ S32 y = TOP;
+
+ LLIconCtrl::Params common_params;
+ common_params.rect(LLRect(x, y, x+32, TOP-32));
+ common_params.mouse_opaque(false);
+ common_params.follows.flags(FOLLOWS_LEFT | FOLLOWS_TOP);
+
+ if (mIsTip)
+ {
+ // use the tip notification icon
+ common_params.image(LLUI::getUIImage("notify_tip_icon.tga"));
+ icon = LLUICtrlFactory::create<LLIconCtrl> (common_params);
+ }
+ else if (mIsCaution)
+ {
+ // use the caution notification icon
+ common_params.image(LLUI::getUIImage("notify_caution_icon.tga"));
+ icon = LLUICtrlFactory::create<LLIconCtrl> (common_params);
+ }
+ else
+ {
+ // use the default notification icon
+ common_params.image(LLUI::getUIImage("notify_box_icon.tga"));
+ icon = LLUICtrlFactory::create<LLIconCtrl> (common_params);
+ }
+
+ icon->setMouseOpaque(FALSE);
+ addChild(icon);
+
+ x += HPAD + HPAD + 32;
+
+ // add a caution textbox at the top of a caution notification
+ LLTextBox* caution_box = NULL;
+ if (mIsCaution && !mIsTip)
+ {
+ S32 caution_height = ((S32)sFont->getLineHeight() * 2) + VPAD;
+ LLTextBox::Params params;
+ params.name("caution_box");
+ params.rect(LLRect(x, y, getRect().getWidth() - 2, caution_height));
+ params.font(sFont);
+ params.mouse_opaque(false);
+ params.font.style("BOLD");
+ params.text_color(LLUIColorTable::instance().getColor("NotifyCautionWarnColor"));
+ params.background_color(LLUIColorTable::instance().getColor("NotifyCautionBoxColor"));
+ params.border_visible(false);
+ caution_box = LLUICtrlFactory::create<LLTextBox> (params);
+ caution_box->setWrappedText(notification->getMessage());
+
+ addChild(caution_box);
+
+ // adjust the vertical position of the next control so that
+ // it appears below the caution textbox
+ y = y - caution_height;
+ }
+ else
+ {
+
+ const S32 BTN_TOP = BOTTOM_PAD + (((mNumOptions-1+2)/3)) * (BTN_HEIGHT+VPAD);
+
+ // Tokenization on \n is handled by LLTextBox
+
+ const S32 MAX_LENGTH = 512 + 20 +
+ DB_FIRST_NAME_BUF_SIZE +
+ DB_LAST_NAME_BUF_SIZE +
+ DB_INV_ITEM_NAME_BUF_SIZE; // For script dialogs: add space for title.
+
+ LLTextEditor::Params params;
+ params.name("box");
+ params.rect(LLRect(x, y, getRect().getWidth()-2, mIsTip ? BOTTOM : BTN_TOP+16));
+ params.max_text_length(MAX_LENGTH);
+ params.default_text(mMessage);
+ params.font(sFont);
+ params.embedded_items(false);
+ params.word_wrap(true);
+ params.tab_stop(false);
+ params.mouse_opaque(false);
+ params.bg_readonly_color(LLColor4::transparent);
+ params.text_readonly_color(LLUIColorTable::instance().getColor("NotifyTextColor"));
+ params.enabled(false);
+ params.hide_border(true);
+ text = LLUICtrlFactory::create<LLTextEditor> (params);
+ addChild(text);
+ }
+
+ if (mIsTip)
+ {
+ // TODO: Make a separate archive for these.
+ LLChat chat(mMessage);
+ chat.mSourceType = CHAT_SOURCE_SYSTEM;
+ LLFloaterChat::addChatHistory(chat);
+ }
+ else
+ {
+ LLButton::Params p;
+ p.name(std::string("next"));
+ p.rect(LLRect(getRect().getWidth()-26, BOTTOM_PAD + 20, getRect().getWidth()-2, BOTTOM_PAD));
+ p.image_selected.name("notify_next.png");
+ p.image_unselected.name("notify_next.png");
+ p.font(sFont);
+ p.scale_image(true);
+ p.tool_tip(LLTrans::getString("next").c_str());
+
+ for (S32 i = 0; i < mNumOptions; i++)
+ {
+
+ LLSD form_element = form->getElement(i);
+ if (form_element["type"].asString() != "button")
+ {
+ continue;
+ }
+
+ addButton(form_element["name"].asString(), form_element["text"].asString(), TRUE, form_element["default"].asBoolean());
+ }
+
+ if (mNumButtons == 0)
+ {
+ addButton("OK", LLTrans::getString("ok"), FALSE, TRUE);
+ mAddedDefaultBtn = true;
+ }
+
+
+ }
+}
+
+LLToastNotifyPanel::~LLToastNotifyPanel() {
+ std::for_each(mBtnCallbackData.begin(), mBtnCallbackData.end(), DeletePointer());
+}
+
+
+LLRect LLToastNotifyPanel::getNotifyRect(S32 num_options, BOOL mIsScriptDialog, BOOL is_caution)
+{
+ S32 notify_height = gSavedSettings.getS32("NotifyBoxHeight");
+ if (is_caution)
+ {
+ // make caution-style dialog taller to accomodate extra text,
+ // as well as causing the accept/decline buttons to be drawn
+ // in a different position, to help prevent "quick-click-through"
+ // of many permissions prompts
+ notify_height = gSavedSettings.getS32("PermissionsCautionNotifyBoxHeight");
+ }
+ const S32 NOTIFY_WIDTH = gSavedSettings.getS32("NotifyBoxWidth");
+
+ const S32 TOP = getRect().getHeight();
+ const S32 RIGHT =getRect().getWidth();
+ const S32 LEFT = RIGHT - NOTIFY_WIDTH;
+
+ if (num_options < 1)
+ {
+ num_options = 1;
+ }
+
+ // Add two "blank" option spaces.
+ if (mIsScriptDialog)
+ {
+ num_options += 2;
+ }
+
+ S32 additional_lines = (num_options-1) / 3;
+
+ notify_height += additional_lines * (BTN_HEIGHT + VPAD);
+
+ return LLRect(LEFT, TOP, RIGHT, TOP-notify_height);
+}
+
+// static
+LLRect LLToastNotifyPanel::getNotifyTipRect(const std::string &utf8message)
+{
+ S32 line_count = 1;
+ LLWString message = utf8str_to_wstring(utf8message);
+ S32 message_len = message.length();
+
+ const S32 NOTIFY_WIDTH = gSavedSettings.getS32("NotifyBoxWidth");
+ // Make room for the icon area.
+ const S32 text_area_width = NOTIFY_WIDTH - HPAD * 4 - 32;
+
+ const llwchar* wchars = message.c_str();
+ const llwchar* start = wchars;
+ const llwchar* end;
+ S32 total_drawn = 0;
+ BOOL done = FALSE;
+
+ do
+ {
+ line_count++;
+
+ for (end=start; *end != 0 && *end != '\n'; end++)
+ ;
+
+ if( *end == 0 )
+ {
+ end = wchars + message_len;
+ done = TRUE;
+ }
+
+ S32 remaining = end - start;
+ while( remaining )
+ {
+ S32 drawn = sFont->maxDrawableChars( start, (F32)text_area_width, remaining, TRUE );
+
+ if( 0 == drawn )
+ {
+ drawn = 1; // Draw at least one character, even if it doesn't all fit. (avoids an infinite loop)
+ }
+
+ total_drawn += drawn;
+ start += drawn;
+ remaining -= drawn;
+
+ if( total_drawn < message_len )
+ {
+ if( (wchars[ total_drawn ] != '\n') )
+ {
+ // wrap because line was too long
+ line_count++;
+ }
+ }
+ else
+ {
+ done = TRUE;
+ }
+ }
+
+ total_drawn++; // for '\n'
+ end++;
+ start = end;
+ } while( !done );
+
+ const S32 MIN_NOTIFY_HEIGHT = 72;
+ const S32 MAX_NOTIFY_HEIGHT = 600;
+ S32 notify_height = llceil((F32) (line_count+1) * sFont->getLineHeight());
+ if(gOverlayBar)
+ {
+ notify_height += gOverlayBar->getBoundingRect().mTop;
+ }
+ else
+ {
+ // *FIX: this is derived from the padding caused by the
+ // rounded rects, shouldn't be a const here.
+ notify_height += 10;
+ }
+ notify_height += VPAD;
+ notify_height = llclamp(notify_height, MIN_NOTIFY_HEIGHT, MAX_NOTIFY_HEIGHT);
+
+ const S32 RIGHT = getRect().getWidth();
+ const S32 LEFT = RIGHT - NOTIFY_WIDTH;
+
+ return LLRect(LEFT, notify_height, RIGHT, 0);
+}
+
+
+// static
+void LLToastNotifyPanel::onClickButton(void* data)
+{
+ InstanceAndS32* self_and_button = (InstanceAndS32*)data;
+ LLToastNotifyPanel* self = self_and_button->mSelf;
+ std::string button_name = self_and_button->mButtonName;
+
+ LLSD response = self->mNotification->getResponseTemplate();
+ if (!self->mAddedDefaultBtn && !button_name.empty())
+ {
+ response[button_name] = true;
+ }
+ self->mNotification->respond(response);
+}
+
+// virtual
+LLButton* LLToastNotifyPanel::addButton(const std::string& name, const std::string& label, BOOL is_option, BOOL is_default)
+{
+ // make caution notification buttons slightly narrower
+ // so that 3 of them can fit without overlapping the "next" button
+ S32 btn_width = mIsCaution? 84 : 90;
+
+ LLRect btn_rect;
+ LLButton* btn;
+ S32 btn_height= BTN_HEIGHT;
+ const LLFontGL* font = sFont;
+ S32 ignore_pad = 0;
+ S32 button_index = mNumButtons;
+ S32 index = button_index;
+ S32 x = (HPAD * 4) + 32;
+
+ if (mIsScriptDialog)
+ {
+ // Add two "blank" option spaces, before the "Ignore" button
+ index = button_index + 2;
+ if (button_index == 0)
+ {
+ // Ignore button is smaller, less wide
+ btn_height = BTN_HEIGHT_SMALL;
+ font = sFontSmall;
+ ignore_pad = 10;
+ }
+ }
+
+ btn_rect.setOriginAndSize(x + (index % 3) * (btn_width+HPAD+HPAD) + ignore_pad,
+ BOTTOM_PAD + (index / 3) * (BTN_HEIGHT+VPAD),
+ btn_width - 2*ignore_pad,
+ btn_height);
+
+ InstanceAndS32* userdata = new InstanceAndS32;
+ userdata->mSelf = this;
+ userdata->mButtonName = is_option ? name : "";
+
+ mBtnCallbackData.push_back(userdata);
+
+ LLButton::Params p;
+ p.name(name);
+ p.label(label);
+ p.rect(btn_rect);
+ p.click_callback.function(boost::bind(&LLToastNotifyPanel::onClickButton, userdata));
+ p.font(font);
+ if (mIsCaution)
+ {
+ p.image_color(LLUIColorTable::instance().getColor("ButtonCautionImageColor"));
+ p.image_color_disabled(LLUIColorTable::instance().getColor("ButtonCautionImageColor"));
+ }
+ btn = LLUICtrlFactory::create<LLButton>(p);
+
+
+ addChild(btn, -1);
+
+ if (is_default)
+ {
+ setDefaultBtn(btn);
+ }
+
+ mNumButtons++;
+ return btn;
+}
diff --git a/indra/newview/lltoastnotifypanel.h b/indra/newview/lltoastnotifypanel.h
new file mode 100644
index 0000000000..df58c06f25
--- /dev/null
+++ b/indra/newview/lltoastnotifypanel.h
@@ -0,0 +1,86 @@
+/**
+ * @file lltoastnotifypanel.h
+ * @brief Panel for notify toasts.
+ *
+ * $LicenseInfo:firstyear=2001&license=viewergpl$
+ *
+ * Copyright (c) 2001-2009, Linden Research, Inc.
+ *
+ * Second Life Viewer Source Code
+ * The source code in this file ("Source Code") is provided by Linden Lab
+ * to you under the terms of the GNU General Public License, version 2.0
+ * ("GPL"), unless you have obtained a separate licensing agreement
+ * ("Other License"), formally executed by you and Linden Lab. Terms of
+ * the GPL can be found in doc/GPL-license.txt in this distribution, or
+ * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
+ *
+ * There are special exceptions to the terms and conditions of the GPL as
+ * it is applied to this Source Code. View the full text of the exception
+ * in the file doc/FLOSS-exception.txt in this software distribution, or
+ * online at
+ * http://secondlifegrid.net/programs/open_source/licensing/flossexception
+ *
+ * By copying, modifying or distributing this software, you acknowledge
+ * that you have read and understood your obligations described above,
+ * and agree to abide by those obligations.
+ *
+ * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+ * COMPLETENESS OR PERFORMANCE.
+ * $/LicenseInfo$
+ */
+
+#ifndef LLTOASTNOTIFYPANEL_H_
+#define LLTOASTNOTIFYPANEL_H_
+
+#include "llpanel.h"
+#include "llfontgl.h"
+#include "llnotifications.h"
+#include "llbutton.h"
+#include "lltoastpanel.h"
+
+
+/**
+ * Toast panel for notification.
+ * Notification panel should be used for notifications that require a response from the user.
+ *
+ * Replaces class LLNotifyBox.
+ */
+class LLToastNotifyPanel: public LLToastPanel {
+public:
+ LLToastNotifyPanel(LLNotificationPtr&);
+ virtual ~LLToastNotifyPanel();
+ bool isTip() {return mIsTip;}
+ static LLToastNotifyPanel * buildNotifyPanel(LLNotificationPtr notification);
+
+protected:
+ LLButton* addButton(std::string const &name, const std::string& label, BOOL is_option, BOOL is_default);
+ // Used for callbacks
+ struct InstanceAndS32
+ {
+ LLToastNotifyPanel* mSelf;
+ std::string mButtonName;
+ };
+ std::vector<InstanceAndS32*> mBtnCallbackData;
+
+private:
+
+ // Returns the rect, relative to gNotifyView, where this
+ // notify box should be placed.
+ LLRect getNotifyRect(S32 num_options, BOOL layout_script_dialog, BOOL is_caution);
+ LLRect getNotifyTipRect(const std::string &message);
+ // internal handler for button being clicked
+ static void onClickButton(void* data);
+ bool mIsTip;
+ bool mAddedDefaultBtn;
+ bool mIsScriptDialog;
+ bool mIsCaution; // is this a caution notification?
+ std::string mMessage;
+ S32 mNumOptions;
+ S32 mNumButtons;
+
+ static const LLFontGL* sFont;
+ static const LLFontGL* sFontSmall;
+};
+
+#endif /* LLTOASTNOTIFYPANEL_H_ */
diff --git a/indra/newview/lltoastpanel.cpp b/indra/newview/lltoastpanel.cpp
new file mode 100644
index 0000000000..28052a33be
--- /dev/null
+++ b/indra/newview/lltoastpanel.cpp
@@ -0,0 +1,53 @@
+/**
+ * @file lltoastpanel.cpp
+ * @brief Creates a panel of a specific kind for a toast
+ *
+ * $LicenseInfo:firstyear=2000&license=viewergpl$
+ *
+ * Copyright (c) 2000-2009, Linden Research, Inc.
+ *
+ * Second Life Viewer Source Code
+ * The source code in this file ("Source Code") is provided by Linden Lab
+ * to you under the terms of the GNU General Public License, version 2.0
+ * ("GPL"), unless you have obtained a separate licensing agreement
+ * ("Other License"), formally executed by you and Linden Lab. Terms of
+ * the GPL can be found in doc/GPL-license.txt in this distribution, or
+ * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
+ *
+ * There are special exceptions to the terms and conditions of the GPL as
+ * it is applied to this Source Code. View the full text of the exception
+ * in the file doc/FLOSS-exception.txt in this software distribution, or
+ * online at
+ * http://secondlifegrid.net/programs/open_source/licensing/flossexception
+ *
+ * By copying, modifying or distributing this software, you acknowledge
+ * that you have read and understood your obligations described above,
+ * and agree to abide by those obligations.
+ *
+ * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+ * COMPLETENESS OR PERFORMANCE.
+ * $/LicenseInfo$
+ */
+
+#include "llviewerprecompiledheaders.h"
+
+#include "lltoastpanel.h"
+
+LLToastPanel::LLToastPanel(LLNotificationPtr& notification)
+{
+ mNotification = notification;
+}
+
+LLToastPanel::~LLToastPanel()
+{
+}
+
+std::string LLToastPanel::getTitle()
+{
+ // *TODO: create Title and localize it. If it will be required.
+ return mNotification->getMessage();
+}
+
+
+
diff --git a/indra/newview/lltoastpanel.h b/indra/newview/lltoastpanel.h
new file mode 100644
index 0000000000..2258eca273
--- /dev/null
+++ b/indra/newview/lltoastpanel.h
@@ -0,0 +1,58 @@
+/**
+ * @file lltoastpanel.h
+ * @brief Creates a panel of a specific kind for a toast.
+ *
+ * $LicenseInfo:firstyear=2003&license=viewergpl$
+ *
+ * Copyright (c) 2003-2009, Linden Research, Inc.
+ *
+ * Second Life Viewer Source Code
+ * The source code in this file ("Source Code") is provided by Linden Lab
+ * to you under the terms of the GNU General Public License, version 2.0
+ * ("GPL"), unless you have obtained a separate licensing agreement
+ * ("Other License"), formally executed by you and Linden Lab. Terms of
+ * the GPL can be found in doc/GPL-license.txt in this distribution, or
+ * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
+ *
+ * There are special exceptions to the terms and conditions of the GPL as
+ * it is applied to this Source Code. View the full text of the exception
+ * in the file doc/FLOSS-exception.txt in this software distribution, or
+ * online at
+ * http://secondlifegrid.net/programs/open_source/licensing/flossexception
+ *
+ * By copying, modifying or distributing this software, you acknowledge
+ * that you have read and understood your obligations described above,
+ * and agree to abide by those obligations.
+ *
+ * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+ * COMPLETENESS OR PERFORMANCE.
+ * $/LicenseInfo$
+ */
+
+#ifndef LL_LLTOASTPANEL_H
+#define LL_LLTOASTPANEL_H
+
+#include "llpanel.h"
+#include "llnotifications.h"
+
+#include <string>
+
+/**
+ * Base class for all panels that can be added to the toast.
+ * All toast panels should contain necessary logic for representing certain notification
+ * but shouldn't contain logic related to this panel lifetime control and positioning
+ * on the parent view.
+ */
+class LLToastPanel: public LLPanel {
+public:
+ LLToastPanel(LLNotificationPtr&);
+ virtual ~LLToastPanel() = 0;
+
+ virtual std::string getTitle();
+ virtual const LLUUID& getID() { return mNotification->id();}
+protected:
+ LLNotificationPtr mNotification;
+};
+
+#endif /* LL_TOASTPANEL_H */
diff --git a/indra/newview/lltool.cpp b/indra/newview/lltool.cpp
index 6a3ada0474..7b058e9efa 100644
--- a/indra/newview/lltool.cpp
+++ b/indra/newview/lltool.cpp
@@ -91,7 +91,7 @@ BOOL LLTool::handleMouseUp(S32 x, S32 y, MASK mask)
BOOL LLTool::handleHover(S32 x, S32 y, MASK mask)
{
- gViewerWindow->getWindow()->setCursor(UI_CURSOR_ARROW);
+ gViewerWindow->setCursor(UI_CURSOR_ARROW);
lldebugst(LLERR_USER_INPUT) << "hover handled by a tool" << llendl;
// by default, do nothing, say we handled it
return TRUE;
diff --git a/indra/newview/lltoolbar.cpp b/indra/newview/lltoolbar.cpp
index 33edb3ef27..5478e0005a 100644
--- a/indra/newview/lltoolbar.cpp
+++ b/indra/newview/lltoolbar.cpp
@@ -36,20 +36,23 @@
#include "lltoolbar.h"
#include "imageids.h"
+#include "llfloaterreg.h"
#include "llfontgl.h"
+#include "llflyoutbutton.h"
#include "llrect.h"
#include "llparcel.h"
#include "llagent.h"
+#include "llagentwearables.h"
#include "llbutton.h"
#include "llfocusmgr.h"
#include "llviewercontrol.h"
#include "llmenucommands.h"
#include "llimview.h"
#include "lluiconstants.h"
-#include "llvoavatar.h"
+#include "llvoavatarself.h"
#include "lltooldraganddrop.h"
-#include "llinventoryview.h"
+#include "llfloaterinventory.h"
#include "llfloaterchatterbox.h"
#include "llfloaterfriends.h"
#include "llfloatersnapshot.h"
@@ -57,6 +60,9 @@
#include "llui.h"
#include "llviewermenu.h"
#include "llfirstuse.h"
+#include "llscrolllistctrl.h"
+#include "llscrolllistitem.h"
+#include "llscrolllistcell.h"
#include "llviewerparcelmgr.h"
#include "lluictrlfactory.h"
#include "llviewerwindow.h"
@@ -65,29 +71,12 @@
#include "llfloaterchat.h"
#include "llfloatermute.h"
#include "llimpanel.h"
-#include "llscrolllistctrl.h"
+#include "lllayoutstack.h"
#if LL_DARWIN
#include "llresizehandle.h"
- // This class draws like an LLResizeHandle but has no interactivity.
- // It's just there to provide a cue to the user that the lower right corner of the window functions as a resize handle.
- class LLFakeResizeHandle : public LLResizeHandle
- {
- public:
- LLFakeResizeHandle(const std::string& name, const LLRect& rect, S32 min_width, S32 min_height, ECorner corner = RIGHT_BOTTOM )
- : LLResizeHandle(name, rect, min_width, min_height, corner )
- {
-
- }
-
- virtual BOOL handleHover(S32 x, S32 y, MASK mask) { return FALSE; };
- virtual BOOL handleMouseDown(S32 x, S32 y, MASK mask) { return FALSE; };
- virtual BOOL handleMouseUp(S32 x, S32 y, MASK mask) { return FALSE; };
-
- };
-
#endif // LL_DARWIN
//
@@ -95,7 +84,6 @@
//
LLToolBar *gToolBar = NULL;
-S32 TOOL_BAR_HEIGHT = 20;
//
// Statics
@@ -114,44 +102,13 @@ LLToolBar::LLToolBar()
{
setIsChrome(TRUE);
setFocusRoot(TRUE);
+
+ mCommitCallbackRegistrar.add("HandleCommunicate", &LLToolBar::onClickCommunicate);
}
BOOL LLToolBar::postBuild()
{
- childSetCommitCallback("communicate_btn", onClickCommunicate, this);
- childSetControlName("communicate_btn", "ShowCommunicate");
-
- childSetAction("chat_btn", onClickChat, this);
- childSetControlName("chat_btn", "ChatVisible");
-
- childSetAction("appearance_btn", onClickAppearance, this);
- childSetControlName("appearance_btn", "");
-
- childSetAction("fly_btn", onClickFly, this);
- childSetControlName("fly_btn", "FlyBtnState");
-
- childSetAction("sit_btn", onClickSit, this);
- childSetControlName("sit_btn", "SitBtnState");
-
- childSetAction("snapshot_btn", onClickSnapshot, this);
- childSetControlName("snapshot_btn", "");
-
- childSetAction("directory_btn", onClickDirectory, this);
- childSetControlName("directory_btn", "ShowDirectory");
-
- childSetAction("build_btn", onClickBuild, this);
- childSetControlName("build_btn", "BuildBtnState");
-
- childSetAction("radar_btn", onClickRadar, this);
- childSetControlName("radar_btn", "ShowMiniMap");
-
- childSetAction("map_btn", onClickMap, this);
- childSetControlName("map_btn", "ShowWorldMap");
-
- childSetAction("inventory_btn", onClickInventory, this);
- childSetControlName("inventory_btn", "ShowInventory");
-
for (child_list_const_iter_t child_iter = getChildList()->begin();
child_iter != getChildList()->end(); ++child_iter)
{
@@ -167,8 +124,14 @@ BOOL LLToolBar::postBuild()
if(mResizeHandle == NULL)
{
LLRect rect(0, 0, RESIZE_HANDLE_WIDTH, RESIZE_HANDLE_HEIGHT);
- mResizeHandle = new LLFakeResizeHandle(std::string(""), rect, RESIZE_HANDLE_WIDTH, RESIZE_HANDLE_HEIGHT);
- this->addChildAtEnd(mResizeHandle);
+ LLResizeHandle::Params p;
+ p.name("");
+ p.rect(rect);
+ p.min_width(RESIZE_HANDLE_WIDTH);
+ p.min_height(RESIZE_HANDLE_HEIGHT);
+ p.enabled(false);
+ mResizeHandle = LLUICtrlFactory::create<LLResizeHandle>(p);
+ addChildInBack(mResizeHandle);
LLLayoutStack* toolbar_stack = getChild<LLLayoutStack>("toolbar_stack");
toolbar_stack->reshape(toolbar_stack->getRect().getWidth() - RESIZE_HANDLE_WIDTH, toolbar_stack->getRect().getHeight());
}
@@ -194,20 +157,23 @@ BOOL LLToolBar::handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop,
LLButton* inventory_btn = getChild<LLButton>("inventory_btn");
if (!inventory_btn) return FALSE;
- LLInventoryView* active_inventory = LLInventoryView::getActiveInventory();
+ LLFloaterInventory* active_inventory = LLFloaterInventory::getActiveInventory();
+
+ LLRect button_screen_rect;
+ inventory_btn->localRectToScreen(inventory_btn->getRect(),&button_screen_rect);
if(active_inventory && active_inventory->getVisible())
{
mInventoryAutoOpen = FALSE;
}
- else if (inventory_btn->getRect().pointInRect(x, y))
+ else if (button_screen_rect.pointInRect(x, y))
{
if (mInventoryAutoOpen)
{
if (!(active_inventory && active_inventory->getVisible()) &&
mInventoryAutoOpenTimer.getElapsedTimeF32() > sInventoryAutoOpenTime)
{
- LLInventoryView::showAgentInventory();
+ LLFloaterInventory::showAgentInventory();
}
}
else
@@ -287,21 +253,37 @@ void LLToolBar::refresh()
BOOL sitting = FALSE;
if (gAgent.getAvatarObject())
{
- sitting = gAgent.getAvatarObject()->mIsSitting;
+ sitting = gAgent.getAvatarObject()->isSitting();
}
- childSetEnabled("fly_btn", (gAgent.canFly() || gAgent.getFlying()) && !sitting );
-
- childSetEnabled("build_btn", LLViewerParcelMgr::getInstance()->agentCanBuild() );
+ if (!gAgent.canFly())
+ {
+ gSavedSettings.setBOOL("FlyBtnEnabled", gAgent.getFlying() ? true : false);
+ gSavedSettings.setBOOL("FlyBtnState", false);
+ }
+ else
+ {
+ gSavedSettings.setBOOL("FlyBtnEnabled", sitting ? false : true);
+ }
// Check to see if we're in build mode
- BOOL build_mode = LLToolMgr::getInstance()->inEdit();
- // And not just clicking on a scripted object
- if (LLToolGrab::getInstance()->getHideBuildHighlight())
+ bool build_enabled = LLToolMgr::getInstance()->canEdit();
+ if (build_enabled)
+ {
+ gSavedSettings.setBOOL("BuildBtnEnabled", true);
+ bool build_mode = LLToolMgr::getInstance()->inEdit();
+ // HACK: Not in mouselook and not just clicking on a scripted object
+ if (gAgent.cameraMouselook() || LLToolGrab::getInstance()->getHideBuildHighlight())
{
build_mode = FALSE;
}
gSavedSettings.setBOOL("BuildBtnState", build_mode);
+ }
+ else
+ {
+ gSavedSettings.setBOOL("BuildBtnEnabled", false);
+ gSavedSettings.setBOOL("BuildBtnState", false);
+ }
if (isInVisibleChain())
{
@@ -319,30 +301,42 @@ void LLToolBar::updateCommunicateList()
LLFloater* frontmost_floater = LLFloaterChatterBox::getInstance()->getActiveFloater();
LLScrollListItem* itemp = NULL;
- itemp = communicate_button->add(LLFloaterMyFriends::getInstance()->getShortTitle(), LLSD("contacts"), ADD_TOP);
+ LLSD contact_sd;
+ contact_sd["value"] = "contacts";
+ contact_sd["columns"][0]["value"] = LLFloaterMyFriends::getInstance()->getShortTitle();
if (LLFloaterMyFriends::getInstance() == frontmost_floater)
{
- ((LLScrollListText*)itemp->getColumn(0))->setFontStyle(LLFontGL::BOLD);
+ contact_sd["columns"][0]["font"]["style"] = "BOLD";
// make sure current tab is selected in list
if (selected.isUndefined())
{
- selected = itemp->getValue();
+ selected = "contacts";
}
}
- itemp = communicate_button->add(LLFloaterChat::getInstance()->getShortTitle(), LLSD("local chat"), ADD_TOP);
+ itemp = communicate_button->addElement(contact_sd, ADD_TOP);
+
+ LLSD communicate_sd;
+ communicate_sd["value"] = "local chat";
+ communicate_sd["columns"][0]["value"] = LLFloaterChat::getInstance()->getShortTitle();
+
if (LLFloaterChat::getInstance() == frontmost_floater)
{
- ((LLScrollListText*)itemp->getColumn(0))->setFontStyle(LLFontGL::BOLD);
+ communicate_sd["columns"][0]["font"]["style"] = "BOLD";
if (selected.isUndefined())
{
- selected = itemp->getValue();
+ selected = "local chat";
}
}
+ itemp = communicate_button->addElement(communicate_sd, ADD_TOP);
+
communicate_button->addSeparator(ADD_TOP);
communicate_button->add(getString("Redock Windows"), LLSD("redock"), ADD_TOP);
communicate_button->addSeparator(ADD_TOP);
- communicate_button->add(LLFloaterMute::getInstance()->getShortTitle(), LLSD("mute list"), ADD_TOP);
-
+ LLFloaterMute* mute_instance = LLFloaterReg::getTypedInstance<LLFloaterMute>("mute");
+ if(mute_instance)
+ {
+ communicate_button->add(mute_instance->getShortTitle(), LLSD("mute list"), ADD_TOP);
+ }
std::set<LLHandle<LLFloater> >::const_iterator floater_handle_it;
if (gIMMgr->getIMFloaterHandles().size() > 0)
@@ -357,165 +351,79 @@ void LLToolBar::updateCommunicateList()
{
std::string floater_title = im_floaterp->getNumUnreadMessages() > 0 ? "*" : "";
floater_title.append(im_floaterp->getShortTitle());
- itemp = communicate_button->add(floater_title, im_floaterp->getSessionID(), ADD_TOP);
+ LLSD im_sd;
+ im_sd["value"] = im_floaterp->getSessionID();
+ im_sd["columns"][0]["value"] = floater_title;
if (im_floaterp == frontmost_floater)
{
- ((LLScrollListText*)itemp->getColumn(0))->setFontStyle(LLFontGL::BOLD);
+ im_sd["columns"][0]["font"]["style"] = "BOLD";
if (selected.isUndefined())
{
- selected = itemp->getValue();
+ selected = im_floaterp->getSessionID();
}
}
+ itemp = communicate_button->addElement(im_sd, ADD_TOP);
}
}
- communicate_button->setToggleState(gSavedSettings.getBOOL("ShowCommunicate"));
communicate_button->setValue(selected);
}
// static
-void LLToolBar::onClickCommunicate(LLUICtrl* ctrl, void* user_data)
+void LLToolBar::onClickCommunicate(LLUICtrl* ctrl, const LLSD& user_data)
{
- LLToolBar* toolbar = (LLToolBar*)user_data;
- LLFlyoutButton* communicate_button = toolbar->getChild<LLFlyoutButton>("communicate_btn");
+ LLFlyoutButton* communicate_button = dynamic_cast<LLFlyoutButton*>(ctrl);
+ llassert_always(communicate_button);
LLSD selected_option = communicate_button->getValue();
if (selected_option.asString() == "contacts")
{
- LLFloaterMyFriends::showInstance();
+ LLFloaterReg::showInstance("contacts", "friends");
}
else if (selected_option.asString() == "local chat")
{
- LLFloaterChat::showInstance();
+ LLFloaterReg::showInstance("communicate", "local");
}
else if (selected_option.asString() == "redock")
{
- LLFloaterChatterBox::getInstance()->addFloater(LLFloaterMyFriends::getInstance(), FALSE);
- LLFloaterChatterBox::getInstance()->addFloater(LLFloaterChat::getInstance(), FALSE);
- LLUUID session_to_show;
-
- std::set<LLHandle<LLFloater> >::const_iterator floater_handle_it;
- for(floater_handle_it = gIMMgr->getIMFloaterHandles().begin(); floater_handle_it != gIMMgr->getIMFloaterHandles().end(); ++floater_handle_it)
+ LLFloaterChatterBox* chatterbox_instance = LLFloaterChatterBox::getInstance();
+ if(chatterbox_instance)
{
- LLFloater* im_floaterp = floater_handle_it->get();
- if (im_floaterp)
+ chatterbox_instance->addFloater(LLFloaterMyFriends::getInstance(), FALSE);
+ chatterbox_instance->addFloater(LLFloaterChat::getInstance(), FALSE);
+
+ LLUUID session_to_show;
+
+ std::set<LLHandle<LLFloater> >::const_iterator floater_handle_it;
+ for(floater_handle_it = gIMMgr->getIMFloaterHandles().begin(); floater_handle_it != gIMMgr->getIMFloaterHandles().end(); ++floater_handle_it)
{
- if (im_floaterp->isFrontmost())
+ LLFloater* im_floaterp = floater_handle_it->get();
+ if (im_floaterp)
{
- session_to_show = ((LLFloaterIMPanel*)im_floaterp)->getSessionID();
+ if (im_floaterp->isFrontmost())
+ {
+ session_to_show = ((LLFloaterIMPanel*)im_floaterp)->getSessionID();
+ }
+ chatterbox_instance->addFloater(im_floaterp, FALSE);
}
- LLFloaterChatterBox::getInstance()->addFloater(im_floaterp, FALSE);
}
+ LLFloaterReg::showInstance("communicate", session_to_show);
}
-
- LLFloaterChatterBox::showInstance(session_to_show);
}
else if (selected_option.asString() == "mute list")
{
- LLFloaterMute::showInstance();
+ LLFloaterReg::showInstance("mute");
}
else if (selected_option.isUndefined()) // user just clicked the communicate button, treat as toggle
{
- if (LLFloaterChatterBox::getInstance()->getFloaterCount() == 0)
- {
- LLFloaterMyFriends::toggleInstance();
- }
- else
- {
- LLFloaterChatterBox::toggleInstance();
+ LLFloaterReg::toggleInstance("communicate");
}
- }
- else // otherwise selection_option is a specific IM session id
+ else // otherwise selection_option is undifined or a specific IM session id
{
- LLFloaterChatterBox::showInstance(selected_option);
+ LLFloaterReg::showInstance("communicate", selected_option);
}
}
-// static
-void LLToolBar::onClickChat(void* user_data)
-{
- handle_chat(NULL);
-}
-
-// static
-void LLToolBar::onClickAppearance(void*)
-{
- if (gAgent.areWearablesLoaded())
- {
- gAgent.changeCameraToCustomizeAvatar();
- }
-}
-
-
-// static
-void LLToolBar::onClickFly(void*)
-{
- gAgent.toggleFlying();
-}
-
-
-// static
-void LLToolBar::onClickSit(void*)
-{
- if (!(gAgent.getControlFlags() & AGENT_CONTROL_SIT_ON_GROUND))
- {
- // sit down
- gAgent.setFlying(FALSE);
- gAgent.setControlFlags(AGENT_CONTROL_SIT_ON_GROUND);
-
- // Might be first sit
- LLFirstUse::useSit();
- }
- else
- {
- // stand up
- gAgent.setFlying(FALSE);
- gAgent.setControlFlags(AGENT_CONTROL_STAND_UP);
- }
-}
-
-
-// static
-void LLToolBar::onClickSnapshot(void*)
-{
- LLFloaterSnapshot::show (0);
-}
-
-
-// static
-void LLToolBar::onClickDirectory(void*)
-{
- handle_find(NULL);
-}
-
-
-// static
-void LLToolBar::onClickBuild(void*)
-{
- toggle_build_mode();
-}
-
-
-// static
-void LLToolBar::onClickRadar(void*)
-{
- handle_mini_map(NULL);
-}
-
-
-// static
-void LLToolBar::onClickMap(void*)
-{
- handle_map(NULL);
-}
-
-
-// static
-void LLToolBar::onClickInventory(void*)
-{
- handle_inventory(NULL);
-}
-
diff --git a/indra/newview/lltoolbar.h b/indra/newview/lltoolbar.h
index 094d016e39..954c6270a6 100644
--- a/indra/newview/lltoolbar.h
+++ b/indra/newview/lltoolbar.h
@@ -37,12 +37,7 @@
#include "llframetimer.h"
-// "Constants" loaded from settings.xml at start time
-extern S32 TOOL_BAR_HEIGHT;
-
-#if LL_DARWIN
- class LLFakeResizeHandle;
-#endif // LL_DARWIN
+class LLResizeHandle;
class LLToolBar
: public LLPanel
@@ -71,17 +66,7 @@ public:
void refresh();
// callbacks
- static void onClickCommunicate(LLUICtrl*, void*);
- static void onClickChat(void* data);
- static void onClickAppearance(void* data);
- static void onClickFly(void*);
- static void onClickSit(void*);
- static void onClickSnapshot(void* data);
- static void onClickDirectory(void* data);
- static void onClickBuild(void* data);
- static void onClickRadar(void* data);
- static void onClickMap(void* data);
- static void onClickInventory(void* data);
+ static void onClickCommunicate(LLUICtrl*, const LLSD&);
static F32 sInventoryAutoOpenTime;
@@ -94,7 +79,7 @@ private:
LLFrameTimer mInventoryAutoOpenTimer;
S32 mNumUnreadIMs;
#if LL_DARWIN
- LLFakeResizeHandle *mResizeHandle;
+ LLResizeHandle *mResizeHandle;
#endif // LL_DARWIN
};
diff --git a/indra/newview/lltoolbrush.cpp b/indra/newview/lltoolbrush.cpp
index c42693d03f..0088a6a2a4 100644
--- a/indra/newview/lltoolbrush.cpp
+++ b/indra/newview/lltoolbrush.cpp
@@ -412,7 +412,7 @@ BOOL LLToolBrushLand::handleHover( S32 x, S32 y, MASK mask )
mMouseX = x;
mMouseY = y;
mGotHover = TRUE;
- gViewerWindow->getWindow()->setCursor(UI_CURSOR_TOOLLAND);
+ gViewerWindow->setCursor(UI_CURSOR_TOOLLAND);
return TRUE;
}
diff --git a/indra/newview/lltoolcomp.cpp b/indra/newview/lltoolcomp.cpp
index b6090bc986..fff18df442 100644
--- a/indra/newview/lltoolcomp.cpp
+++ b/indra/newview/lltoolcomp.cpp
@@ -34,6 +34,7 @@
#include "lltoolcomp.h"
+#include "llfloaterreg.h"
#include "llgl.h"
#include "indra_constants.h"
@@ -295,7 +296,7 @@ BOOL LLToolCompTranslate::handleDoubleClick(S32 x, S32 y, MASK mask)
{
// You should already have an object selected from the mousedown.
// If so, show its properties
- gFloaterTools->showPanel(LLFloaterTools::PANEL_CONTENTS);
+ LLFloaterReg::showInstance("build", "Content");
return TRUE;
}
// Nothing selected means the first mouse click was probably
@@ -412,8 +413,7 @@ BOOL LLToolCompScale::handleDoubleClick(S32 x, S32 y, MASK mask)
{
// You should already have an object selected from the mousedown.
// If so, show its properties
- gFloaterTools->showPanel(LLFloaterTools::PANEL_CONTENTS);
- //gBuildView->setPropertiesPanelOpen(TRUE);
+ LLFloaterReg::showInstance("build", "Content");
return TRUE;
}
else
@@ -610,8 +610,7 @@ BOOL LLToolCompRotate::handleDoubleClick(S32 x, S32 y, MASK mask)
{
// You should already have an object selected from the mousedown.
// If so, show its properties
- gFloaterTools->showPanel(LLFloaterTools::PANEL_CONTENTS);
- //gBuildView->setPropertiesPanelOpen(TRUE);
+ LLFloaterReg::showInstance("build", "Content");
return TRUE;
}
else
@@ -766,10 +765,6 @@ void LLToolCompGun::onMouseCaptureLost()
return;
}
mCur->onMouseCaptureLost();
-
- // JC - I don't know if this is necessary. Maybe we could lose capture
- // if someone ALT-Tab's out when in mouselook.
- setCurrentTool( (LLTool*) mGun );
}
void LLToolCompGun::handleSelect()
diff --git a/indra/newview/lltoolcomp.h b/indra/newview/lltoolcomp.h
index b24ba25d5a..81ed0ba8e4 100644
--- a/indra/newview/lltoolcomp.h
+++ b/indra/newview/lltoolcomp.h
@@ -229,6 +229,7 @@ public:
virtual void onMouseCaptureLost();
virtual void handleSelect();
virtual void handleDeselect();
+ virtual LLTool* getOverrideTool(MASK mask) { return NULL; }
protected:
LLToolGun* mGun;
diff --git a/indra/newview/lltooldraganddrop.cpp b/indra/newview/lltooldraganddrop.cpp
index 156093a21a..c58457d599 100644
--- a/indra/newview/lltooldraganddrop.cpp
+++ b/indra/newview/lltooldraganddrop.cpp
@@ -35,10 +35,12 @@
#include "message.h"
#include "lltooldraganddrop.h"
+#include "llfloaterreg.h"
#include "llinstantmessage.h"
#include "lldir.h"
#include "llagent.h"
+#include "llagentwearables.h"
#include "llviewercontrol.h"
#include "llfirstuse.h"
#include "llfloater.h"
@@ -47,8 +49,8 @@
#include "llgesturemgr.h"
#include "llhudeffecttrail.h"
#include "llhudmanager.h"
+#include "llinventorybridge.h"
#include "llinventorymodel.h"
-#include "llinventoryview.h"
#include "llmutelist.h"
#include "llnotify.h"
#include "llpreviewnotecard.h"
@@ -56,19 +58,20 @@
#include "lltoolmgr.h"
#include "lltrans.h"
#include "llui.h"
-#include "llviewerimagelist.h"
+#include "llviewertexturelist.h"
#include "llviewerinventory.h"
#include "llviewerobject.h"
#include "llviewerobjectlist.h"
#include "llviewerregion.h"
#include "llviewerstats.h"
#include "llviewerwindow.h"
-#include "llvoavatar.h"
+#include "llvoavatarself.h"
#include "llvolume.h"
#include "llworld.h"
#include "object_flags.h"
#include "llimview.h"
-
+#include "llrootview.h"
+#include "llagentui.h"
// MAX ITEMS is based on (sizeof(uuid)+2) * count must be < MTUBYTES
// or 18 * count < 1200 => count < 1200/18 => 66. I've cut it down a
@@ -383,8 +386,8 @@ LLToolDragAndDrop::dragOrDrop3dImpl LLToolDragAndDrop::sDragAndDrop3d[DAD_COUNT]
{
&LLToolDragAndDrop::dad3dNULL, // Dest: DT_NONE
&LLToolDragAndDrop::dad3dNULL, // Dest: DT_SELF
- &LLToolDragAndDrop::dad3dNULL, // Dest: DT_AVATAR
- &LLToolDragAndDrop::dad3dNULL, // Dest: DT_OBJECT
+ &LLToolDragAndDrop::dad3dGiveInventory, // Dest: DT_AVATAR
+ &LLToolDragAndDrop::dad3dUpdateInventory, // Dest: DT_OBJECT
&LLToolDragAndDrop::dad3dNULL, // Dest: DT_LAND
},
// Source: DAD_LANDMARK
@@ -469,6 +472,14 @@ LLToolDragAndDrop::dragOrDrop3dImpl LLToolDragAndDrop::sDragAndDrop3d[DAD_COUNT]
&LLToolDragAndDrop::dad3dUpdateInventory, // Dest: DT_OBJECT
&LLToolDragAndDrop::dad3dNULL,//dad3dAssetOnLand, // Dest: DT_LAND
},
+ // Source: DAD_LINK
+ {
+ &LLToolDragAndDrop::dad3dNULL, // Dest: DT_NONE
+ &LLToolDragAndDrop::dad3dNULL, // Dest: DT_SELF
+ &LLToolDragAndDrop::dad3dNULL, // Dest: DT_AVATAR
+ &LLToolDragAndDrop::dad3dNULL, // Dest: DT_OBJECT
+ &LLToolDragAndDrop::dad3dNULL,//dad3dAssetOnLand, // Dest: DT_LAND
+ },
};
LLToolDragAndDrop::LLToolDragAndDrop()
@@ -846,7 +857,7 @@ void LLToolDragAndDrop::dragOrDrop( S32 x, S32 y, MASK mask, BOOL drop,
{
handled = TRUE;
- LLView* root_view = gViewerWindow->getRootView();
+ LLRootView* root_view = gViewerWindow->getRootView();
for (mCurItemIndex = 0; mCurItemIndex < (S32)mCargoIDs.size(); mCurItemIndex++)
{
@@ -1142,7 +1153,7 @@ void LLToolDragAndDrop::dropTextureAllFaces(LLViewerObject* hit_obj,
{
return;
}
- LLViewerImage* image = gImageList.getImage(asset_id);
+ LLViewerTexture* image = LLViewerTextureManager::getFetchedTexture(asset_id);
LLViewerStats::getInstance()->incStat(LLViewerStats::ST_EDIT_TEXTURE_COUNT );
S32 num_faces = hit_obj->getNumTEs();
for( S32 face = 0; face < num_faces; face++ )
@@ -1160,7 +1171,7 @@ void LLToolDragAndDrop::dropTextureAllFaces(LLViewerObject* hit_obj,
void LLToolDragAndDrop::dropTextureOneFaceAvatar(LLVOAvatar* avatar, S32 hit_face, LLInventoryItem* item)
{
if (hit_face == -1) return;
- LLViewerImage* image = gImageList.getImage(item->getAssetUUID());
+ LLViewerTexture* image = LLViewerTextureManager::getFetchedTexture(item->getAssetUUID());
avatar->userSetOptionalTE( hit_face, image);
}
@@ -1185,7 +1196,7 @@ void LLToolDragAndDrop::dropTextureOneFace(LLViewerObject* hit_obj,
return;
}
// update viewer side image in anticipation of update from simulator
- LLViewerImage* image = gImageList.getImage(asset_id);
+ LLViewerTexture* image = LLViewerTextureManager::getFetchedTexture(asset_id);
LLViewerStats::getInstance()->incStat(LLViewerStats::ST_EDIT_TEXTURE_COUNT );
hit_obj->setTEImage(hit_face, image);
dialog_refresh_all();
@@ -1461,10 +1472,10 @@ void LLToolDragAndDrop::dropInventory(LLViewerObject* hit_obj,
}
}
hit_obj->updateInventory(new_item, TASK_INVENTORY_ITEM_KEY, true);
- if (gFloaterTools->getVisible())
+ if (LLFloaterReg::instanceVisible("build"))
{
// *FIX: only show this if panel not expanded?
- gFloaterTools->showPanel(LLFloaterTools::PANEL_CONTENTS);
+ LLFloaterReg::showInstance("build", "Content");
}
// VEFFECT: AddToInventory
@@ -1551,7 +1562,7 @@ void LLToolDragAndDrop::commitGiveInventoryItem(const LLUUID& to_agent,
{
if(!item) return;
std::string name;
- gAgent.buildFullname(name);
+ LLAgentUI::buildFullname(name);
LLUUID transaction_id;
transaction_id.generate();
const S32 BUCKET_SIZE = sizeof(U8) + UUID_BYTES;
@@ -1594,6 +1605,8 @@ void LLToolDragAndDrop::commitGiveInventoryItem(const LLUUID& to_agent,
gIMMgr->addSystemMessage(im_session_id, "inventory_item_offered", args);
}
+ // add buddy to recent people list
+ LLRecentPeople::instance().add(to_agent);
}
void LLToolDragAndDrop::giveInventoryCategory(const LLUUID& to_agent,
@@ -1718,6 +1731,9 @@ void LLToolDragAndDrop::commitGiveInventoryCategory(const LLUUID& to_agent,
llinfos << "LLToolDragAndDrop::commitGiveInventoryCategory() - "
<< cat->getUUID() << llendl;
+ // add buddy to recent people list
+ LLRecentPeople::instance().add(to_agent);
+
// Test out how many items are being given.
LLViewerInventoryCategory::cat_array_t cats;
LLViewerInventoryItem::item_array_t items;
@@ -1745,7 +1761,7 @@ void LLToolDragAndDrop::commitGiveInventoryCategory(const LLUUID& to_agent,
else
{
std::string name;
- gAgent.buildFullname(name);
+ LLAgentUI::buildFullname(name);
LLUUID transaction_id;
transaction_id.generate();
S32 bucket_size = (sizeof(U8) + UUID_BYTES) * (count + 1);
@@ -1827,7 +1843,7 @@ BOOL LLToolDragAndDrop::isInventoryGiveAcceptable(LLInventoryItem* item)
BOOL copyable = FALSE;
if(item->getPermissions().allowCopyBy(gAgent.getID())) copyable = TRUE;
- LLVOAvatar* my_avatar = gAgent.getAvatarObject();
+ LLVOAvatarSelf* my_avatar = gAgent.getAvatarObject();
if(!my_avatar)
{
return FALSE;
@@ -1836,9 +1852,6 @@ BOOL LLToolDragAndDrop::isInventoryGiveAcceptable(LLInventoryItem* item)
BOOL acceptable = TRUE;
switch(item->getType())
{
- case LLAssetType::AT_CALLINGCARD:
- acceptable = FALSE;
- break;
case LLAssetType::AT_OBJECT:
if(my_avatar->isWearingAttachment(item->getUUID()))
{
@@ -1847,7 +1860,7 @@ BOOL LLToolDragAndDrop::isInventoryGiveAcceptable(LLInventoryItem* item)
break;
case LLAssetType::AT_BODYPART:
case LLAssetType::AT_CLOTHING:
- if(!copyable && gAgent.isWearingItem(item->getUUID()))
+ if(!copyable && gAgentWearables.isWearingItem(item->getUUID()))
{
acceptable = FALSE;
}
@@ -1877,7 +1890,7 @@ BOOL LLToolDragAndDrop::isInventoryGroupGiveAcceptable(LLInventoryItem* item)
return FALSE;
}
- LLVOAvatar* my_avatar = gAgent.getAvatarObject();
+ LLVOAvatarSelf* my_avatar = gAgent.getAvatarObject();
if(!my_avatar)
{
return FALSE;
@@ -1886,11 +1899,8 @@ BOOL LLToolDragAndDrop::isInventoryGroupGiveAcceptable(LLInventoryItem* item)
BOOL acceptable = TRUE;
switch(item->getType())
{
- case LLAssetType::AT_CALLINGCARD:
- acceptable = FALSE;
- break;
case LLAssetType::AT_OBJECT:
- if(my_avatar->isWearingAttachment(item->getUUID()))
+ if(my_avatar->isWearingAttachment(item->getUUID(), TRUE))
{
acceptable = FALSE;
}
@@ -1924,7 +1934,7 @@ EAcceptance LLToolDragAndDrop::willObjectAcceptInventory(LLViewerObject* obj, LL
// gAgent.getGroupID())
// && (obj->mPermModify || obj->mFlagAllowInventoryAdd));
BOOL worn = FALSE;
- LLVOAvatar* my_avatar = NULL;
+ LLVOAvatarSelf* my_avatar = NULL;
switch(item->getType())
{
case LLAssetType::AT_OBJECT:
@@ -1936,7 +1946,7 @@ EAcceptance LLToolDragAndDrop::willObjectAcceptInventory(LLViewerObject* obj, LL
break;
case LLAssetType::AT_BODYPART:
case LLAssetType::AT_CLOTHING:
- if(gAgent.isWearingItem(item->getUUID()))
+ if(gAgentWearables.isWearingItem(item->getUUID()))
{
worn = TRUE;
}
@@ -1991,6 +2001,7 @@ bool LLToolDragAndDrop::handleGiveDragAndDrop(LLUUID dest_agent, LLUUID session_
case DAD_BODYPART:
case DAD_ANIMATION:
case DAD_GESTURE:
+ case DAD_CALLINGCARD:
{
LLViewerInventoryItem* inv_item = (LLViewerInventoryItem*)cargo_data;
if(gInventory.getItem(inv_item->getUUID())
@@ -2035,7 +2046,6 @@ bool LLToolDragAndDrop::handleGiveDragAndDrop(LLUUID dest_agent, LLUUID session_
}
break;
}
- case DAD_CALLINGCARD:
default:
*accept = ACCEPT_NO;
break;
@@ -2080,7 +2090,7 @@ EAcceptance LLToolDragAndDrop::dad3dRezAttachmentFromInv(
}
// must not be already wearing it
- LLVOAvatar* avatar = gAgent.getAvatarObject();
+ LLVOAvatarSelf* avatar = gAgent.getAvatarObject();
if( !avatar || avatar->isWearingAttachment(item->getUUID()) )
{
return ACCEPT_NO;
@@ -2122,7 +2132,7 @@ EAcceptance LLToolDragAndDrop::dad3dRezObjectOnLand(
locateInventory(item, cat);
if(!item || !item->isComplete()) return ACCEPT_NO;
- LLVOAvatar* my_avatar = gAgent.getAvatarObject();
+ LLVOAvatarSelf* my_avatar = gAgent.getAvatarObject();
if( !my_avatar || my_avatar->isWearingAttachment( item->getUUID() ) )
{
return ACCEPT_NO;
@@ -2185,7 +2195,7 @@ EAcceptance LLToolDragAndDrop::dad3dRezObjectOnObject(
LLViewerInventoryCategory* cat;
locateInventory(item, cat);
if(!item || !item->isComplete()) return ACCEPT_NO;
- LLVOAvatar* my_avatar = gAgent.getAvatarObject();
+ LLVOAvatarSelf* my_avatar = gAgent.getAvatarObject();
if( !my_avatar || my_avatar->isWearingAttachment( item->getUUID() ) )
{
return ACCEPT_NO;
@@ -2383,7 +2393,7 @@ EAcceptance LLToolDragAndDrop::dad3dWearItem(
{
// Don't wear anything until initial wearables are loaded, can
// destroy clothing items.
- if (!gAgent.areWearablesLoaded())
+ if (!gAgentWearables.areWearablesLoaded())
{
LLNotifications::instance().add("CanNotChangeAppearanceUntilLoaded");
return ACCEPT_NO;
@@ -2452,7 +2462,7 @@ EAcceptance LLToolDragAndDrop::dad3dActivateGesture(
}
else
{
- gGestureManager.activateGesture(item->getUUID());
+ LLGestureManager::instance().activateGesture(item->getUUID());
gInventory.updateItem(item);
gInventory.notifyObservers();
}
@@ -2478,7 +2488,7 @@ EAcceptance LLToolDragAndDrop::dad3dWearCategory(
{
// Don't wear anything until initial wearables are loaded, can
// destroy clothing items.
- if (!gAgent.areWearablesLoaded())
+ if (!gAgentWearables.areWearablesLoaded())
{
LLNotifications::instance().add("CanNotChangeAppearanceUntilLoaded");
return ACCEPT_NO;
@@ -2679,7 +2689,7 @@ EAcceptance LLToolDragAndDrop::dad3dGiveInventoryObject(
// cannot give away no-transfer objects
return ACCEPT_NO;
}
- LLVOAvatar* avatar = gAgent.getAvatarObject();
+ LLVOAvatarSelf* avatar = gAgent.getAvatarObject();
if(avatar && avatar->isWearingAttachment( item->getUUID() ) )
{
// You can't give objects that are attached to you
@@ -2897,11 +2907,10 @@ LLInventoryObject* LLToolDragAndDrop::locateInventory(
}
else if(mSource == SOURCE_NOTECARD)
{
- LLPreviewNotecard* card;
- card = (LLPreviewNotecard*)LLPreview::find(mSourceID);
- if(card)
+ LLPreviewNotecard* preview = LLFloaterReg::findTypedInstance<LLPreviewNotecard>("preview_notecard", mSourceID);
+ if(preview)
{
- item = (LLViewerInventoryItem*)card->getDragItem();
+ item = (LLViewerInventoryItem*)preview->getDragItem();
}
}
if(item) return item;
diff --git a/indra/newview/lltoolface.cpp b/indra/newview/lltoolface.cpp
index d06e41c771..1d78dc5019 100644
--- a/indra/newview/lltoolface.cpp
+++ b/indra/newview/lltoolface.cpp
@@ -36,14 +36,12 @@
#include "lltoolface.h"
// Library includes
+#include "llfloaterreg.h"
#include "v3math.h"
// Viewer includes
-#include "llagent.h"
-//#include "llbuildview.h"
#include "llviewercontrol.h"
#include "llselectmgr.h"
-#include "lltoolview.h"
#include "llviewerobject.h"
#include "llviewerwindow.h"
#include "llfloatertools.h"
@@ -67,9 +65,7 @@ BOOL LLToolFace::handleDoubleClick(S32 x, S32 y, MASK mask)
{
// You should already have an object selected from the mousedown.
// If so, show its properties
- //gBuildView->showFacePanel();
- gFloaterTools->showPanel( LLFloaterTools::PANEL_FACE );
- //gBuildView->showMore(LLBuildView::PANEL_FACE);
+ LLFloaterReg::showInstance("build", "Texture");
return TRUE;
}
else
diff --git a/indra/newview/lltoolfocus.cpp b/indra/newview/lltoolfocus.cpp
index 4e8274a6ef..297cf2c667 100644
--- a/indra/newview/lltoolfocus.cpp
+++ b/indra/newview/lltoolfocus.cpp
@@ -54,8 +54,10 @@
#include "llviewercamera.h"
#include "llviewerobject.h"
#include "llviewerwindow.h"
-#include "llvoavatar.h"
+#include "llvoavatarself.h"
#include "llmorphview.h"
+#include "llfloaterreg.h"
+#include "llfloatercamera.h"
// Globals
BOOL gCameraBtnZoom = TRUE;
@@ -254,7 +256,11 @@ void LLToolCamera::releaseMouse()
gViewerWindow->showCursor();
- LLToolMgr::getInstance()->clearTransientTool();
+ //for the situation when left click was performed on the Agent
+ if (!LLFloaterCamera::inFreeCameraMode())
+ {
+ LLToolMgr::getInstance()->clearTransientTool();
+ }
mMouseSteering = FALSE;
mValidClickPoint = FALSE;
@@ -359,7 +365,7 @@ BOOL LLToolCamera::handleHover(S32 x, S32 y, MASK mask)
// Orbit tool
if (hasMouseCapture())
{
- const F32 RADIANS_PER_PIXEL = 360.f * DEG_TO_RAD / gViewerWindow->getWindowWidth();
+ const F32 RADIANS_PER_PIXEL = 360.f * DEG_TO_RAD / gViewerWindow->getWorldViewWidth();
if (dx != 0)
{
@@ -387,7 +393,7 @@ BOOL LLToolCamera::handleHover(S32 x, S32 y, MASK mask)
F32 dist = (F32) camera_to_focus.normVec();
// Fudge factor for pan
- F32 meters_per_pixel = 3.f * dist / gViewerWindow->getWindowWidth();
+ F32 meters_per_pixel = 3.f * dist / gViewerWindow->getWorldViewWidth();
if (dx != 0)
{
@@ -409,7 +415,7 @@ BOOL LLToolCamera::handleHover(S32 x, S32 y, MASK mask)
if (hasMouseCapture())
{
- const F32 RADIANS_PER_PIXEL = 360.f * DEG_TO_RAD / gViewerWindow->getWindowWidth();
+ const F32 RADIANS_PER_PIXEL = 360.f * DEG_TO_RAD / gViewerWindow->getWorldViewWidth();
if (dx != 0)
{
diff --git a/indra/newview/lltoolgrab.cpp b/indra/newview/lltoolgrab.cpp
index d9811dac6c..abadd251c1 100644
--- a/indra/newview/lltoolgrab.cpp
+++ b/indra/newview/lltoolgrab.cpp
@@ -46,7 +46,6 @@
// newview headers
#include "llagent.h"
-//#include "llfloateravatarinfo.h"
#include "lldrawable.h"
#include "llfloatertools.h"
#include "llhudeffect.h"
@@ -61,7 +60,7 @@
#include "llviewerobjectlist.h"
#include "llviewerregion.h"
#include "llviewerwindow.h"
-#include "llvoavatar.h"
+#include "llvoavatarself.h"
#include "llworld.h"
const S32 SLOP_DIST_SQ = 4;
@@ -511,8 +510,8 @@ void LLToolGrab::handleHoverActive(S32 x, S32 y, MASK mask)
const F32 RADIANS_PER_PIXEL_X = 0.01f;
const F32 RADIANS_PER_PIXEL_Y = 0.01f;
- S32 dx = x - (gViewerWindow->getWindowWidth() / 2);
- S32 dy = y - (gViewerWindow->getWindowHeight() / 2);
+ S32 dx = x - (gViewerWindow->getWorldViewWidth() / 2);
+ S32 dy = y - (gViewerWindow->getWorldViewHeight() / 2);
if (dx != 0 || dy != 0)
{
@@ -632,10 +631,10 @@ void LLToolGrab::handleHoverActive(S32 x, S32 y, MASK mask)
// Handle auto-rotation at screen edge.
LLVector3 grab_pos_agent = gAgent.getPosAgentFromGlobal( grab_point_global );
- LLCoordGL grab_center_gl( gViewerWindow->getWindowWidth() / 2, gViewerWindow->getWindowHeight() / 2);
+ LLCoordGL grab_center_gl( gViewerWindow->getWorldViewWidth() / 2, gViewerWindow->getWorldViewHeight() / 2);
LLViewerCamera::getInstance()->projectPosAgentToScreen(grab_pos_agent, grab_center_gl);
- const S32 ROTATE_H_MARGIN = gViewerWindow->getWindowWidth() / 20;
+ const S32 ROTATE_H_MARGIN = gViewerWindow->getWorldViewWidth() / 20;
const F32 ROTATE_ANGLE_PER_SECOND = 30.f * DEG_TO_RAD;
const F32 rotate_angle = ROTATE_ANGLE_PER_SECOND / gFPSClamped;
// ...build mode moves camera about focus point
@@ -650,7 +649,7 @@ void LLToolGrab::handleHoverActive(S32 x, S32 y, MASK mask)
gAgent.cameraOrbitAround(rotate_angle);
}
}
- else if (grab_center_gl.mX > gViewerWindow->getWindowWidth() - ROTATE_H_MARGIN)
+ else if (grab_center_gl.mX > gViewerWindow->getWorldViewWidth() - ROTATE_H_MARGIN)
{
if (gAgent.getFocusOnAvatar())
{
@@ -663,7 +662,7 @@ void LLToolGrab::handleHoverActive(S32 x, S32 y, MASK mask)
}
// Don't move above top of screen or below bottom
- if ((grab_center_gl.mY < gViewerWindow->getWindowHeight() - 6)
+ if ((grab_center_gl.mY < gViewerWindow->getWorldViewHeight() - 6)
&& (grab_center_gl.mY > 24))
{
// Transmit update to simulator
@@ -885,7 +884,7 @@ void LLToolGrab::handleHoverInactive(S32 x, S32 y, MASK mask)
// Look for cursor against the edge of the screen
// Only works in fullscreen
- if (gSavedSettings.getBOOL("FullScreen"))
+ if (gSavedSettings.getBOOL("WindowFullScreen"))
{
if (gAgent.cameraThirdPerson() )
{
@@ -894,7 +893,7 @@ void LLToolGrab::handleHoverInactive(S32 x, S32 y, MASK mask)
gAgent.yaw(rotate_angle);
//gAgent.setControlFlags(AGENT_CONTROL_YAW_POS);
}
- else if (x == (gViewerWindow->getWindowWidth() - 1) )
+ else if (x == (gViewerWindow->getWorldViewWidth() - 1) )
{
gAgent.yaw(-rotate_angle);
//gAgent.setControlFlags(AGENT_CONTROL_YAW_NEG);
diff --git a/indra/newview/lltoolgrab.h b/indra/newview/lltoolgrab.h
index cf2405cafc..16ccb3f24f 100644
--- a/indra/newview/lltoolgrab.h
+++ b/indra/newview/lltoolgrab.h
@@ -36,7 +36,7 @@
#include "lltool.h"
#include "v3math.h"
#include "llquaternion.h"
-#include "llmemory.h"
+#include "llsingleton.h"
#include "lluuid.h"
#include "llviewerwindow.h" // for LLPickInfo
diff --git a/indra/newview/lltoolgun.cpp b/indra/newview/lltoolgun.cpp
index d21fd49647..8accf6babf 100644
--- a/indra/newview/lltoolgun.cpp
+++ b/indra/newview/lltoolgun.cpp
@@ -42,14 +42,18 @@
#include "llresmgr.h"
#include "llfontgl.h"
#include "llui.h"
-#include "llviewerimagelist.h"
+#include "llviewertexturelist.h"
#include "llviewercamera.h"
#include "llhudmanager.h"
#include "lltoolmgr.h"
#include "lltoolgrab.h"
+// Linden library includes
+#include "llwindow.h" // setMouseClipping()
+
LLToolGun::LLToolGun( LLToolComposite* composite )
-: LLTool( std::string("gun"), composite )
+: LLTool( std::string("gun"), composite ),
+ mIsSelected(FALSE)
{
}
@@ -58,6 +62,7 @@ void LLToolGun::handleSelect()
gViewerWindow->hideCursor();
gViewerWindow->moveCursorToCenter();
gViewerWindow->mWindow->setMouseClipping(TRUE);
+ mIsSelected = TRUE;
}
void LLToolGun::handleDeselect()
@@ -65,6 +70,7 @@ void LLToolGun::handleDeselect()
gViewerWindow->moveCursorToCenter();
gViewerWindow->showCursor();
gViewerWindow->mWindow->setMouseClipping(FALSE);
+ mIsSelected = FALSE;
}
BOOL LLToolGun::handleMouseDown(S32 x, S32 y, MASK mask)
@@ -77,7 +83,7 @@ BOOL LLToolGun::handleMouseDown(S32 x, S32 y, MASK mask)
BOOL LLToolGun::handleHover(S32 x, S32 y, MASK mask)
{
- if( gAgent.cameraMouselook() )
+ if( gAgent.cameraMouselook() && mIsSelected )
{
const F32 NOMINAL_MOUSE_SENSITIVITY = 0.0025f;
@@ -132,9 +138,9 @@ void LLToolGun::draw()
{
if( gSavedSettings.getBOOL("ShowCrosshairs") )
{
- LLUIImagePtr crosshair = LLUI::getUIImage("UIImgCrosshairsUUID");
+ LLUIImagePtr crosshair = LLUI::getUIImage("crosshairs.tga");
crosshair->draw(
- ( gViewerWindow->getWindowWidth() - crosshair->getWidth() ) / 2,
- ( gViewerWindow->getWindowHeight() - crosshair->getHeight() ) / 2);
+ ( gViewerWindow->getWorldViewWidth() - crosshair->getWidth() ) / 2,
+ ( gViewerWindow->getWorldViewHeight() - crosshair->getHeight() ) / 2);
}
}
diff --git a/indra/newview/lltoolgun.h b/indra/newview/lltoolgun.h
index 4e945d796c..4644e686b7 100644
--- a/indra/newview/lltoolgun.h
+++ b/indra/newview/lltoolgun.h
@@ -52,6 +52,8 @@ public:
virtual LLTool* getOverrideTool(MASK mask) { return NULL; }
virtual BOOL clipMouseWhenDown() { return FALSE; }
+private:
+ BOOL mIsSelected;
};
#endif
diff --git a/indra/newview/lltoolindividual.cpp b/indra/newview/lltoolindividual.cpp
index 8382e0d72d..163c7cbd9b 100644
--- a/indra/newview/lltoolindividual.cpp
+++ b/indra/newview/lltoolindividual.cpp
@@ -41,6 +41,7 @@
#include "llviewerprecompiledheaders.h"
#include "lltoolindividual.h"
+#include "llfloaterreg.h"
#include "llselectmgr.h"
#include "llviewerobject.h"
#include "llviewerwindow.h"
@@ -93,9 +94,7 @@ BOOL LLToolIndividual::handleDoubleClick(S32 x, S32 y, MASK mask)
{
// You should already have an object selected from the mousedown.
// If so, show its inventory.
- //gBuildView->showInventoryPanel();
- //gBuildView->showPanel(LLBuildView::PANEL_CONTENTS);
- gFloaterTools->showPanel(LLFloaterTools::PANEL_CONTENTS);
+ LLFloaterReg::showInstance("build", "Content");
return TRUE;
}
else
diff --git a/indra/newview/lltoolmgr.cpp b/indra/newview/lltoolmgr.cpp
index 5ba7217c99..d52e0b4b80 100644
--- a/indra/newview/lltoolmgr.cpp
+++ b/indra/newview/lltoolmgr.cpp
@@ -34,8 +34,13 @@
#include "lltoolmgr.h"
-#include "lltool.h"
+#include "lluictrl.h"
+#include "llmenugl.h"
+#include "llfloaterreg.h"
+
+#include "llfirstuse.h"
// tools and manipulators
+#include "lltool.h"
#include "llmanipscale.h"
#include "llselectmgr.h"
#include "lltoolbrush.h"
@@ -47,12 +52,14 @@
#include "lltoolindividual.h"
#include "lltoolmorph.h"
#include "lltoolpie.h"
-#include "lltoolplacer.h"
#include "lltoolselectland.h"
#include "lltoolobjpicker.h"
#include "lltoolpipette.h"
#include "llagent.h"
#include "llviewercontrol.h"
+#include "llviewerjoystick.h"
+#include "llviewermenu.h"
+#include "llviewerparcelmgr.h"
// Used when app not active to avoid processing hover.
@@ -76,6 +83,11 @@ LLToolMgr::LLToolMgr()
mSelectedTool( NULL ),
mCurrentToolset( NULL )
{
+ // Not a panel, register these callbacks globally.
+ LLUICtrl::EnableCallbackRegistry::currentRegistrar().add("Build.Active", boost::bind(&LLToolMgr::inEdit, this));
+ LLUICtrl::EnableCallbackRegistry::currentRegistrar().add("Build.Enabled", boost::bind(&LLToolMgr::canEdit, this));
+ LLUICtrl::CommitCallbackRegistry::currentRegistrar().add("Build.Toggle", boost::bind(&LLToolMgr::toggleBuildMode, this));
+
gToolNull = new LLTool(LLStringUtil::null); // Does nothing
setCurrentTool(gToolNull);
@@ -168,11 +180,13 @@ void LLToolMgr::setCurrentTool( LLTool* tool )
mBaseTool = tool;
updateToolStatus();
+
+ mSavedTool = NULL;
}
LLTool* LLToolMgr::getCurrentTool()
{
- MASK override_mask = gKeyboard->currentMask(TRUE);
+ MASK override_mask = gKeyboard ? gKeyboard->currentMask(TRUE) : 0;
LLTool* cur_tool = NULL;
// always use transient tools if available
@@ -226,11 +240,77 @@ void LLToolMgr::updateToolStatus()
getCurrentTool();
}
-BOOL LLToolMgr::inEdit()
+bool LLToolMgr::inEdit()
{
return mBaseTool != LLToolPie::getInstance() && mBaseTool != gToolNull;
}
+bool LLToolMgr::canEdit()
+{
+ return LLViewerParcelMgr::getInstance()->agentCanBuild();
+}
+
+void LLToolMgr::toggleBuildMode()
+{
+ if (inBuildMode())
+ {
+ if (gSavedSettings.getBOOL("EditCameraMovement"))
+ {
+ // just reset the view, will pull us out of edit mode
+ handle_reset_view();
+ }
+ else
+ {
+ // manually disable edit mode, but do not affect the camera
+ gAgent.resetView(false);
+ LLFloaterReg::hideInstance("build");
+ gViewerWindow->showCursor();
+ }
+ // avoid spurious avatar movements pulling out of edit mode
+ LLViewerJoystick::getInstance()->setNeedsReset();
+ }
+ else
+ {
+ ECameraMode camMode = gAgent.getCameraMode();
+ if (CAMERA_MODE_MOUSELOOK == camMode || CAMERA_MODE_CUSTOMIZE_AVATAR == camMode)
+ {
+ // pull the user out of mouselook or appearance mode when entering build mode
+ handle_reset_view();
+ }
+
+ if (gSavedSettings.getBOOL("EditCameraMovement"))
+ {
+ // camera should be set
+ if (LLViewerJoystick::getInstance()->getOverrideCamera())
+ {
+ handle_toggle_flycam();
+ }
+
+ if (gAgent.getFocusOnAvatar())
+ {
+ // zoom in if we're looking at the avatar
+ gAgent.setFocusOnAvatar(FALSE, ANIMATE);
+ gAgent.setFocusGlobal(gAgent.getPositionGlobal() + 2.0 * LLVector3d(gAgent.getAtAxis()));
+ gAgent.cameraZoomIn(0.666f);
+ gAgent.cameraOrbitOver( 30.f * DEG_TO_RAD );
+ }
+ }
+
+
+ setCurrentToolset(gBasicToolset);
+ getCurrentToolset()->selectTool( LLToolCompCreate::getInstance() );
+
+ // Could be first use
+ LLFirstUse::useBuild();
+
+ gAgent.resetView(false);
+
+ // avoid spurious avatar movements
+ LLViewerJoystick::getInstance()->setNeedsReset();
+
+ }
+}
+
bool LLToolMgr::inBuildMode()
{
// when entering mouselook inEdit() immediately returns true before
@@ -277,22 +357,20 @@ void LLToolMgr::clearTransientTool()
}
-// The "gun tool", used for handling mouselook, captures the mouse and
-// locks it within the window. When the app loses focus we need to
-// release this locking.
void LLToolMgr::onAppFocusLost()
{
- mSavedTool = mBaseTool;
- mBaseTool = gToolNull;
+ if (mSelectedTool)
+ {
+ mSelectedTool->handleDeselect();
+ }
updateToolStatus();
}
void LLToolMgr::onAppFocusGained()
{
- if (mSavedTool)
+ if (mSelectedTool)
{
- mBaseTool = mSavedTool;
- mSavedTool = NULL;
+ mSelectedTool->handleSelect();
}
updateToolStatus();
}
@@ -396,8 +474,6 @@ void LLToolset::selectPrevTool()
}
}
-void select_tool( void *tool_pointer )
-{
- LLTool *tool = (LLTool *)tool_pointer;
- LLToolMgr::getInstance()->getCurrentToolset()->selectTool( tool );
-}
+////////////////////////////////////////////////////////////////////////////
+
+
diff --git a/indra/newview/lltoolmgr.h b/indra/newview/lltoolmgr.h
index 92647c99de..22aec97864 100644
--- a/indra/newview/lltoolmgr.h
+++ b/indra/newview/lltoolmgr.h
@@ -58,7 +58,9 @@ public:
LLTool* getCurrentTool(); // returns active tool, taking into account keyboard state
LLTool* getBaseTool(); // returns active tool when overrides are deactivated
- BOOL inEdit();
+ bool inEdit();
+ bool canEdit();
+ void toggleBuildMode();
/* Determines if we are in Build mode or not. */
bool inBuildMode();
@@ -115,10 +117,6 @@ protected:
tool_list_t mToolList;
};
-// Handy callbacks for switching tools
-void select_tool(void *tool);
-
-
// Globals
extern LLToolset* gBasicToolset;
diff --git a/indra/newview/lltoolmorph.cpp b/indra/newview/lltoolmorph.cpp
index 75e19645a6..d7d7b5f44b 100644
--- a/indra/newview/lltoolmorph.cpp
+++ b/indra/newview/lltoolmorph.cpp
@@ -37,7 +37,7 @@
#include "llrender.h"
// Library includes
-#include "audioengine.h"
+#include "llaudioengine.h"
#include "llviewercontrol.h"
#include "llfontgl.h"
#include "sound_ids.h"
@@ -56,13 +56,12 @@
#include "llsky.h"
#include "lltexlayer.h"
#include "lltoolmgr.h"
-#include "lltoolview.h"
#include "llui.h"
#include "llviewercamera.h"
-#include "llviewerimagelist.h"
+#include "llviewertexturelist.h"
#include "llviewerobject.h"
#include "llviewerwindow.h"
-#include "llvoavatar.h"
+#include "llvoavatarself.h"
#include "pipeline.h"
@@ -82,7 +81,7 @@ LLVisualParamHint::LLVisualParamHint(
LLViewerVisualParam *param,
F32 param_weight)
:
- LLDynamicTexture(width, height, 3, LLDynamicTexture::ORDER_MIDDLE, TRUE ),
+ LLViewerDynamicTexture(width, height, 3, LLViewerDynamicTexture::ORDER_MIDDLE, TRUE ),
mNeedsUpdate( TRUE ),
mIsVisible( FALSE ),
mJointMesh( mesh ),
@@ -145,7 +144,7 @@ BOOL LLVisualParamHint::needsRender()
void LLVisualParamHint::preRender(BOOL clear_depth)
{
- LLVOAvatar* avatarp = gAgent.getAvatarObject();
+ LLVOAvatarSelf* avatarp = gAgent.getAvatarObject();
mLastParamWeight = avatarp->getVisualParamWeight(mVisualParam);
avatarp->setVisualParamWeight(mVisualParam, mVisualParamWeight);
@@ -156,7 +155,7 @@ void LLVisualParamHint::preRender(BOOL clear_depth)
avatarp->updateGeometry(avatarp->mDrawable);
avatarp->updateLOD();
- LLDynamicTexture::preRender(clear_depth);
+ LLViewerDynamicTexture::preRender(clear_depth);
}
//-----------------------------------------------------------------------------
@@ -170,7 +169,7 @@ BOOL LLVisualParamHint::render()
glMatrixMode(GL_PROJECTION);
glPushMatrix();
glLoadIdentity();
- glOrtho(0.0f, mWidth, 0.0f, mHeight, -1.0f, 1.0f);
+ glOrtho(0.0f, mFullWidth, 0.0f, mFullHeight, -1.0f, 1.0f);
glMatrixMode(GL_MODELVIEW);
glPushMatrix();
@@ -178,7 +177,7 @@ BOOL LLVisualParamHint::render()
LLGLSUIDefault gls_ui;
//LLGLState::verify(TRUE);
- mBackgroundp->draw(0, 0, mWidth, mHeight);
+ mBackgroundp->draw(0, 0, mFullWidth, mFullHeight);
glMatrixMode(GL_PROJECTION);
glPopMatrix();
@@ -225,13 +224,13 @@ BOOL LLVisualParamHint::render()
gGL.flush();
- LLViewerCamera::getInstance()->setAspect((F32)mWidth / (F32)mHeight);
+ LLViewerCamera::getInstance()->setAspect((F32)mFullWidth / (F32)mFullHeight);
LLViewerCamera::getInstance()->setOriginAndLookAt(
camera_pos, // camera
LLVector3(0.f, 0.f, 1.f), // up
target_pos ); // point of interest
- LLViewerCamera::getInstance()->setPerspective(FALSE, mOrigin.mX, mOrigin.mY, mWidth, mHeight, FALSE);
+ LLViewerCamera::getInstance()->setPerspective(FALSE, mOrigin.mX, mOrigin.mY, mFullWidth, mFullHeight, FALSE);
if (avatarp->mDrawable.notNull())
{
@@ -245,7 +244,7 @@ BOOL LLVisualParamHint::render()
}
avatarp->setVisualParamWeight(mVisualParam, mLastParamWeight);
gGL.color4f(1,1,1,1);
- mTexture->setGLTextureCreated(true);
+ mGLTexturep->setGLTextureCreated(true);
return TRUE;
}
@@ -257,7 +256,7 @@ void LLVisualParamHint::draw()
{
if (!mIsVisible) return;
- gGL.getTexUnit(0)->bind(getTexture());
+ gGL.getTexUnit(0)->bind(this);
gGL.color4f(1.f, 1.f, 1.f, 1.f);
@@ -265,13 +264,13 @@ void LLVisualParamHint::draw()
gGL.begin(LLRender::QUADS);
{
gGL.texCoord2i(0, 1);
- gGL.vertex2i(0, mHeight);
+ gGL.vertex2i(0, mFullHeight);
gGL.texCoord2i(0, 0);
gGL.vertex2i(0, 0);
gGL.texCoord2i(1, 0);
- gGL.vertex2i(mWidth, 0);
+ gGL.vertex2i(mFullWidth, 0);
gGL.texCoord2i(1, 1);
- gGL.vertex2i(mWidth, mHeight);
+ gGL.vertex2i(mFullWidth, mFullHeight);
}
gGL.end();
@@ -281,7 +280,7 @@ void LLVisualParamHint::draw()
//-----------------------------------------------------------------------------
// LLVisualParamReset()
//-----------------------------------------------------------------------------
-LLVisualParamReset::LLVisualParamReset() : LLDynamicTexture(1, 1, 1, ORDER_RESET, FALSE)
+LLVisualParamReset::LLVisualParamReset() : LLViewerDynamicTexture(1, 1, 1, ORDER_RESET, FALSE)
{
}
@@ -292,7 +291,7 @@ BOOL LLVisualParamReset::render()
{
if (sDirty)
{
- LLVOAvatar* avatarp = gAgent.getAvatarObject();
+ LLVOAvatarSelf* avatarp = gAgent.getAvatarObject();
avatarp->updateComposites();
avatarp->updateVisualParams();
avatarp->updateGeometry(avatarp->mDrawable);
diff --git a/indra/newview/lltoolmorph.h b/indra/newview/lltoolmorph.h
index 11de8160eb..b7df718ba2 100644
--- a/indra/newview/lltoolmorph.h
+++ b/indra/newview/lltoolmorph.h
@@ -42,7 +42,7 @@
#include "llstrider.h"
#include "llviewervisualparam.h"
#include "llframetimer.h"
-#include "llviewerimage.h"
+#include "llviewertexture.h"
class LLViewerJointMesh;
class LLPolyMesh;
@@ -51,17 +51,18 @@ class LLViewerObject;
//-----------------------------------------------------------------------------
// LLVisualParamHint
//-----------------------------------------------------------------------------
-class LLVisualParamHint
-: public LLDynamicTexture
+class LLVisualParamHint : public LLViewerDynamicTexture
{
+protected:
+ virtual ~LLVisualParamHint();
+
public:
LLVisualParamHint(
S32 pos_x, S32 pos_y,
S32 width, S32 height,
LLViewerJointMesh *mesh,
LLViewerVisualParam *param,
- F32 param_weight);
- virtual ~LLVisualParamHint();
+ F32 param_weight);
BOOL needsRender();
void preRender(BOOL clear_depth);
@@ -94,13 +95,15 @@ protected:
LLUIImagePtr mBackgroundp;
- typedef std::set<LLVisualParamHint*> instance_list_t;
+ typedef std::set< LLVisualParamHint* > instance_list_t;
static instance_list_t sInstances;
};
// this class resets avatar data at the end of an update cycle
-class LLVisualParamReset : public LLDynamicTexture
+class LLVisualParamReset : public LLViewerDynamicTexture
{
+protected:
+ /*virtual */ ~LLVisualParamReset(){}
public:
LLVisualParamReset();
/*virtual */ BOOL render();
diff --git a/indra/newview/lltoolobjpicker.cpp b/indra/newview/lltoolobjpicker.cpp
index d69688706f..b2088a8232 100644
--- a/indra/newview/lltoolobjpicker.cpp
+++ b/indra/newview/lltoolobjpicker.cpp
@@ -48,6 +48,7 @@
#include "llviewercamera.h"
#include "llviewerwindow.h"
#include "lldrawable.h"
+#include "llrootview.h"
LLToolObjPicker::LLToolObjPicker()
@@ -62,7 +63,7 @@ LLToolObjPicker::LLToolObjPicker()
// returns TRUE if an object was selected
BOOL LLToolObjPicker::handleMouseDown(S32 x, S32 y, MASK mask)
{
- LLView* viewp = gViewerWindow->getRootView();
+ LLRootView* viewp = gViewerWindow->getRootView();
BOOL handled = viewp->handleMouseDown(x, y, mask);
mHitObjectID.setNull();
@@ -131,7 +132,7 @@ BOOL LLToolObjPicker::handleHover(S32 x, S32 y, MASK mask)
cursor = UI_CURSOR_TOOLPICKOBJECT3;
- gViewerWindow->getWindow()->setCursor(cursor);
+ gViewerWindow->setCursor(cursor);
}
return handled;
}
diff --git a/indra/newview/lltoolpie.cpp b/indra/newview/lltoolpie.cpp
index 986555db49..235d4acf9d 100644
--- a/indra/newview/lltoolpie.cpp
+++ b/indra/newview/lltoolpie.cpp
@@ -36,14 +36,14 @@
#include "indra_constants.h"
#include "llclickaction.h"
-#include "llmediabase.h" // for status codes
#include "llparcel.h"
#include "llagent.h"
#include "llviewercontrol.h"
+#include "llfocusmgr.h"
#include "llfirstuse.h"
-#include "llfloateravatarinfo.h"
#include "llfloaterland.h"
+#include "llfloaterreg.h"
#include "llfloaterscriptdebug.h"
#include "llhoverview.h"
#include "llhudeffecttrail.h"
@@ -63,7 +63,8 @@
#include "llviewerparcelmgr.h"
#include "llviewerwindow.h"
#include "llviewermedia.h"
-#include "llvoavatar.h"
+#include "llvoavatarself.h"
+#include "llviewermediafocus.h"
#include "llworld.h"
#include "llui.h"
#include "llweb.h"
@@ -72,14 +73,15 @@ extern void handle_buy(void*);
extern BOOL gDebugClicks;
+static bool handle_media_click(const LLPickInfo& info);
+static bool handle_media_hover(const LLPickInfo& info);
static void handle_click_action_play();
static void handle_click_action_open_media(LLPointer<LLViewerObject> objectp);
static ECursorType cursor_from_parcel_media(U8 click_action);
LLToolPie::LLToolPie()
-: LLTool(std::string("Select")),
- mPieMouseButtonDown( FALSE ),
+: LLTool(std::string("Pie")),
mGrabMouseButtonDown( FALSE ),
mMouseOutsideSlop( FALSE ),
mClickAction(0)
@@ -98,32 +100,44 @@ BOOL LLToolPie::handleMouseDown(S32 x, S32 y, MASK mask)
void LLToolPie::leftMouseCallback(const LLPickInfo& pick_info)
{
LLToolPie::getInstance()->mPick = pick_info;
- LLToolPie::getInstance()->pickAndShowMenu(FALSE);
+ LLToolPie::getInstance()->pickLeftMouseDownCallback();
}
+// Spawn context menus on right mouse down so you can drag over and select
+// an item.
BOOL LLToolPie::handleRightMouseDown(S32 x, S32 y, MASK mask)
{
// don't pick transparent so users can't "pay" transparent objects
gViewerWindow->pickAsync(x, y, mask, rightMouseCallback, FALSE, TRUE);
- mPieMouseButtonDown = TRUE;
- // don't steal focus from UI
+ // claim not handled so UI focus stays same
return FALSE;
}
+BOOL LLToolPie::handleRightMouseUp(S32 x, S32 y, MASK mask)
+{
+ LLToolMgr::getInstance()->clearTransientTool();
+ return LLTool::handleRightMouseUp(x, y, mask);
+}
+
+BOOL LLToolPie::handleScrollWheel(S32 x, S32 y, S32 clicks)
+{
+ return LLViewerMediaFocus::getInstance()->handleScrollWheel(x, y, clicks);
+}
+
// static
void LLToolPie::rightMouseCallback(const LLPickInfo& pick_info)
{
LLToolPie::getInstance()->mPick = pick_info;
- LLToolPie::getInstance()->pickAndShowMenu(TRUE);
+ LLToolPie::getInstance()->pickRightMouseDownCallback();
}
// True if you selected an object.
-BOOL LLToolPie::pickAndShowMenu(BOOL always_show)
+BOOL LLToolPie::pickLeftMouseDownCallback()
{
S32 x = mPick.mMousePt.mX;
S32 y = mPick.mMousePt.mY;
MASK mask = mPick.mKeyMask;
- if (!always_show && mPick.mPickType == LLPickInfo::PICK_PARCEL_WALL)
+ if (mPick.mPickType == LLPickInfo::PICK_PARCEL_WALL)
{
LLParcel* parcel = LLViewerParcelMgr::getInstance()->getCollisionParcel();
if (parcel)
@@ -139,10 +153,11 @@ BOOL LLToolPie::pickAndShowMenu(BOOL always_show)
else
{
// not selling passes, get info
- LLFloaterLand::showInstance();
+ LLFloaterReg::showInstance("about_land");
}
}
+ gFocusMgr.setKeyboardFocus(NULL);
return LLTool::handleMouseDown(x, y, mask);
}
@@ -160,11 +175,13 @@ BOOL LLToolPie::pickAndShowMenu(BOOL always_show)
parent = object->getRootEdit();
}
+
BOOL touchable = (object && object->flagHandleTouch())
|| (parent && parent->flagHandleTouch());
+
// If it's a left-click, and we have a special action, do it.
- if (useClickAction(always_show, mask, object, parent))
+ if (useClickAction(mask, object, parent))
{
mClickAction = 0;
if (object && object->getClickAction())
@@ -182,9 +199,11 @@ BOOL LLToolPie::pickAndShowMenu(BOOL always_show)
// touch behavior down below...
break;
case CLICK_ACTION_SIT:
- if ((gAgent.getAvatarObject() != NULL) && (!gAgent.getAvatarObject()->mIsSitting)) // agent not already sitting
+ if ((gAgent.getAvatarObject() != NULL) && (!gAgent.getAvatarObject()->isSitting())) // agent not already sitting
{
handle_sit_or_stand();
+ // put focus in world when sitting on an object
+ gFocusMgr.setKeyboardFocus(NULL);
return TRUE;
} // else nothing (fall through to touch)
@@ -237,11 +256,19 @@ BOOL LLToolPie::pickAndShowMenu(BOOL always_show)
}
}
+ if (handle_media_click(mPick))
+ {
+ return FALSE;
+ }
+
+ // put focus back "in world"
+ gFocusMgr.setKeyboardFocus(NULL);
+
// Switch to grab tool if physical or triggerable
if (object &&
!object->isAvatar() &&
- ((object->usePhysics() || (parent && !parent->isAvatar() && parent->usePhysics())) || touchable) &&
- !always_show)
+ ((object->usePhysics() || (parent && !parent->isAvatar() && parent->usePhysics())) || touchable)
+ )
{
gGrabTransientTool = this;
LLToolMgr::getInstance()->getCurrentToolset()->selectTool( LLToolGrab::getInstance() );
@@ -256,8 +283,7 @@ BOOL LLToolPie::pickAndShowMenu(BOOL always_show)
// If left-click never selects or spawns a menu
// Eat the event.
- if (!gSavedSettings.getBOOL("LeftClickShowMenu")
- && !always_show)
+ if (!gSavedSettings.getBOOL("LeftClickShowMenu"))
{
// mouse already released
if (!mGrabMouseButtonDown)
@@ -285,14 +311,16 @@ BOOL LLToolPie::pickAndShowMenu(BOOL always_show)
return TRUE;
}
- // Could be first left-click on nothing
- LLFirstUse::useLeftClickNoHit();
-
+ //////////
+ // // Could be first left-click on nothing
+ // LLFirstUse::useLeftClickNoHit();
+ /////////
+
// Eat the event
return LLTool::handleMouseDown(x, y, mask);
}
- if (!always_show && gAgent.leftButtonGrabbed())
+ if (gAgent.leftButtonGrabbed())
{
// if the left button is grabbed, don't put up the pie menu
return LLTool::handleMouseDown(x, y, mask);
@@ -302,116 +330,15 @@ BOOL LLToolPie::pickAndShowMenu(BOOL always_show)
LLToolSelect::handleObjectSelection(mPick, FALSE, TRUE);
// Spawn pie menu
- if (mPick.mPickType == LLPickInfo::PICK_LAND)
- {
- LLParcelSelectionHandle selection = LLViewerParcelMgr::getInstance()->selectParcelAt( mPick.mPosGlobal );
- gMenuHolder->setParcelSelection(selection);
- gPieLand->show(x, y, mPieMouseButtonDown);
-
- // VEFFECT: ShowPie
- LLHUDEffectSpiral *effectp = (LLHUDEffectSpiral *)LLHUDManager::getInstance()->createViewerEffect(LLHUDObject::LL_HUD_EFFECT_SPHERE, TRUE);
- effectp->setPositionGlobal(mPick.mPosGlobal);
- effectp->setColor(LLColor4U(gAgent.getEffectColor()));
- effectp->setDuration(0.25f);
- }
- else if (mPick.mObjectID == gAgent.getID() )
- {
- if(!gPieSelf)
- {
- //either at very early startup stage or at late quitting stage,
- //this event is ignored.
- return TRUE ;
- }
-
- gPieSelf->show(x, y, mPieMouseButtonDown);
- }
- else if (object)
- {
- gMenuHolder->setObjectSelection(LLSelectMgr::getInstance()->getSelection());
-
- if (object->isAvatar()
- || (object->isAttachment() && !object->isHUDAttachment() && !object->permYouOwner()))
- {
- // Find the attachment's avatar
- while( object && object->isAttachment())
- {
- object = (LLViewerObject*)object->getParent();
- }
-
- // Object is an avatar, so check for mute by id.
- LLVOAvatar* avatar = (LLVOAvatar*)object;
- std::string name = avatar->getFullname();
- if (LLMuteList::getInstance()->isMuted(avatar->getID(), name))
- {
- gMenuHolder->childSetText("Avatar Mute", std::string("Unmute")); // *TODO:Translate
- //gMutePieMenu->setLabel("Unmute");
- }
- else
- {
- gMenuHolder->childSetText("Avatar Mute", std::string("Mute")); // *TODO:Translate
- //gMutePieMenu->setLabel("Mute");
- }
-
- gPieAvatar->show(x, y, mPieMouseButtonDown);
- }
- else if (object->isAttachment())
- {
- gPieAttachment->show(x, y, mPieMouseButtonDown);
- }
- else
- {
- // BUG: What about chatting child objects?
- std::string name;
- LLSelectNode* node = LLSelectMgr::getInstance()->getSelection()->getFirstRootNode();
- if (node)
- {
- name = node->mName;
- }
- if (LLMuteList::getInstance()->isMuted(object->getID(), name))
- {
- gMenuHolder->childSetText("Object Mute", std::string("Unmute")); // *TODO:Translate
- //gMuteObjectPieMenu->setLabel("Unmute");
- }
- else
- {
- gMenuHolder->childSetText("Object Mute", std::string("Mute")); // *TODO:Translate
- //gMuteObjectPieMenu->setLabel("Mute");
- }
-
- gPieObject->show(x, y, mPieMouseButtonDown);
-
- // VEFFECT: ShowPie object
- // Don't show when you click on someone else, it freaks them
- // out.
- LLHUDEffectSpiral *effectp = (LLHUDEffectSpiral *)LLHUDManager::getInstance()->createViewerEffect(LLHUDObject::LL_HUD_EFFECT_SPHERE, TRUE);
- effectp->setPositionGlobal(mPick.mPosGlobal);
- effectp->setColor(LLColor4U(gAgent.getEffectColor()));
- effectp->setDuration(0.25f);
- }
- }
-
- if (always_show)
- {
- // ignore return value
- LLTool::handleRightMouseDown(x, y, mask);
- }
- else
- {
- // ignore return value
- LLTool::handleMouseDown(x, y, mask);
- }
-
- // We handled the event.
+ LLTool::handleRightMouseDown(x, y, mask);
return TRUE;
}
-BOOL LLToolPie::useClickAction(BOOL always_show,
- MASK mask,
+BOOL LLToolPie::useClickAction(MASK mask,
LLViewerObject* object,
LLViewerObject* parent)
{
- return !always_show
- && mask == MASK_NONE
+ return mask == MASK_NONE
&& object
&& !object->isAttachment()
&& LLPrimitive::isPrimitive(object->getPCode())
@@ -454,7 +381,7 @@ ECursorType cursor_from_object(LLViewerObject* object)
switch(click_action)
{
case CLICK_ACTION_SIT:
- if ((gAgent.getAvatarObject() != NULL) && (!gAgent.getAvatarObject()->mIsSitting)) // not already sitting?
+ if ((gAgent.getAvatarObject() != NULL) && (!gAgent.getAvatarObject()->isSitting())) // not already sitting?
{
cursor = UI_CURSOR_TOOLSIT;
}
@@ -524,7 +451,7 @@ void LLToolPie::selectionPropertiesReceived()
handle_give_money_dialog();
break;
case CLICK_ACTION_OPEN:
- handle_object_open();
+ LLFloaterReg::showInstance("openobject");
break;
default:
break;
@@ -554,41 +481,55 @@ BOOL LLToolPie::handleHover(S32 x, S32 y, MASK mask)
mMouseOutsideSlop = TRUE;
}
*/
-
+
+ // FIXME: This was in the pluginapi branch, but I don't think it's correct.
+// gViewerWindow->getWindow()->setCursor(UI_CURSOR_ARROW);
+
LLViewerObject *object = NULL;
LLViewerObject *parent = NULL;
- if (gHoverView)
- {
- object = gViewerWindow->getHoverPick().getObject();
- }
+ object = gViewerWindow->getHoverPick().getObject();
if (object)
{
parent = object->getRootEdit();
}
- if (object && useClickAction(FALSE, mask, object, parent))
+ if (object && useClickAction(mask, object, parent))
{
ECursorType cursor = cursor_from_object(object);
- gViewerWindow->getWindow()->setCursor(cursor);
+ gViewerWindow->setCursor(cursor);
+ lldebugst(LLERR_USER_INPUT) << "hover handled by LLToolPie (inactive)" << llendl;
+ }
+ else if (handle_media_hover(gViewerWindow->getHoverPick()))
+ {
+ // cursor set by media object
lldebugst(LLERR_USER_INPUT) << "hover handled by LLToolPie (inactive)" << llendl;
}
else if ((object && !object->isAvatar() && object->usePhysics())
|| (parent && !parent->isAvatar() && parent->usePhysics()))
{
- gViewerWindow->getWindow()->setCursor(UI_CURSOR_TOOLGRAB);
+ gViewerWindow->setCursor(UI_CURSOR_TOOLGRAB);
lldebugst(LLERR_USER_INPUT) << "hover handled by LLToolPie (inactive)" << llendl;
}
else if ( (object && object->flagHandleTouch())
|| (parent && parent->flagHandleTouch()))
{
- gViewerWindow->getWindow()->setCursor(UI_CURSOR_HAND);
+ gViewerWindow->setCursor(UI_CURSOR_HAND);
lldebugst(LLERR_USER_INPUT) << "hover handled by LLToolPie (inactive)" << llendl;
}
else
{
- gViewerWindow->getWindow()->setCursor(UI_CURSOR_ARROW);
+ gViewerWindow->setCursor(UI_CURSOR_ARROW);
lldebugst(LLERR_USER_INPUT) << "hover handled by LLToolPie (inactive)" << llendl;
+
+ if(!object)
+ {
+ // We need to clear media hover flag
+ if (LLViewerMediaFocus::getInstance()->getMouseOverFlag())
+ {
+ LLViewerMediaFocus::getInstance()->setMouseOverFlag(false);
+ }
+ }
}
return TRUE;
@@ -610,7 +551,7 @@ BOOL LLToolPie::handleMouseUp(S32 x, S32 y, MASK mask)
// the world. Keep the cursor an arrow, assuming that
// after the user moves off the UI, they won't be on the
// same object anymore.
- gViewerWindow->getWindow()->setCursor(UI_CURSOR_ARROW);
+ gViewerWindow->setCursor(UI_CURSOR_ARROW);
// Make sure the hover-picked object is ignored.
gHoverView->resetLastHoverObject();
break;
@@ -624,13 +565,6 @@ BOOL LLToolPie::handleMouseUp(S32 x, S32 y, MASK mask)
return LLTool::handleMouseUp(x, y, mask);
}
-BOOL LLToolPie::handleRightMouseUp(S32 x, S32 y, MASK mask)
-{
- mPieMouseButtonDown = FALSE;
- LLToolMgr::getInstance()->clearTransientTool();
- return LLTool::handleRightMouseUp(x, y, mask);
-}
-
BOOL LLToolPie::handleDoubleClick(S32 x, S32 y, MASK mask)
{
@@ -744,14 +678,14 @@ static void handle_click_action_play()
LLParcel* parcel = LLViewerParcelMgr::getInstance()->getAgentParcel();
if (!parcel) return;
- LLMediaBase::EStatus status = LLViewerParcelMedia::getStatus();
+ LLViewerMediaImpl::EMediaStatus status = LLViewerParcelMedia::getStatus();
switch(status)
{
- case LLMediaBase::STATUS_STARTED:
+ case LLViewerMediaImpl::MEDIA_PLAYING:
LLViewerParcelMedia::pause();
break;
- case LLMediaBase::STATUS_PAUSED:
+ case LLViewerMediaImpl::MEDIA_PAUSED:
LLViewerParcelMedia::start();
break;
@@ -761,6 +695,111 @@ static void handle_click_action_play()
}
}
+static bool handle_media_click(const LLPickInfo& pick)
+{
+ //FIXME: how do we handle object in different parcel than us?
+ LLParcel* parcel = LLViewerParcelMgr::getInstance()->getAgentParcel();
+ LLPointer<LLViewerObject> objectp = pick.getObject();
+
+
+ if (!parcel ||
+ objectp.isNull() ||
+ pick.mObjectFace < 0 ||
+ pick.mObjectFace >= objectp->getNumTEs())
+ {
+ LLSelectMgr::getInstance()->deselect();
+ LLViewerMediaFocus::getInstance()->clearFocus();
+
+ return false;
+ }
+
+
+
+ // HACK: This is directly referencing an impl name. BAD!
+ // This can be removed when we have a truly generic media browser that only
+ // builds an impl based on the type of url it is passed.
+
+ // is media playing on this face?
+ const LLTextureEntry* tep = objectp->getTE(pick.mObjectFace);
+
+ viewer_media_t media_impl = LLViewerMedia::getMediaImplFromTextureID(tep->getID());
+ if (tep
+ && media_impl.notNull()
+ && media_impl->hasMedia()
+ && gSavedSettings.getBOOL("MediaOnAPrimUI"))
+ {
+ LLObjectSelectionHandle selection = LLViewerMediaFocus::getInstance()->getSelection();
+ if (! selection->contains(pick.getObject(), pick.mObjectFace))
+ {
+ LLViewerMediaFocus::getInstance()->setFocusFace(TRUE, pick.getObject(), pick.mObjectFace, media_impl);
+ }
+ else
+ {
+ media_impl->mouseDown(pick.mXYCoords.mX, pick.mXYCoords.mY);
+ media_impl->mouseCapture(); // the mouse-up will happen when capture is lost
+ }
+
+ return true;
+ }
+
+ LLSelectMgr::getInstance()->deselect();
+ LLViewerMediaFocus::getInstance()->clearFocus();
+
+ return false;
+}
+
+static bool handle_media_hover(const LLPickInfo& pick)
+{
+ //FIXME: how do we handle object in different parcel than us?
+ LLParcel* parcel = LLViewerParcelMgr::getInstance()->getAgentParcel();
+ if (!parcel) return false;
+
+ LLPointer<LLViewerObject> objectp = pick.getObject();
+
+ // Early out cases. Must clear mouse over media focus flag
+ // did not hit an object or did not hit a valid face
+ if ( objectp.isNull() ||
+ pick.mObjectFace < 0 ||
+ pick.mObjectFace >= objectp->getNumTEs() )
+ {
+ LLViewerMediaFocus::getInstance()->setMouseOverFlag(false);
+ return false;
+ }
+
+
+ // HACK: This is directly referencing an impl name. BAD!
+ // This can be removed when we have a truly generic media browser that only
+ // builds an impl based on the type of url it is passed.
+
+ // is media playing on this face?
+ const LLTextureEntry* tep = objectp->getTE(pick.mObjectFace);
+ viewer_media_t media_impl = LLViewerMedia::getMediaImplFromTextureID(tep->getID());
+ if (tep
+ && media_impl.notNull()
+ && media_impl->hasMedia()
+ && gSavedSettings.getBOOL("MediaOnAPrimUI"))
+ {
+ if(LLViewerMediaFocus::getInstance()->getFocus())
+ {
+ media_impl->mouseMove(pick.mXYCoords.mX, pick.mXYCoords.mY);
+ }
+
+ // Set mouse over flag if unset
+ if (! LLViewerMediaFocus::getInstance()->getMouseOverFlag())
+ {
+ LLSelectMgr::getInstance()->setHoverObject(objectp, pick.mObjectFace);
+ LLViewerMediaFocus::getInstance()->setMouseOverFlag(true, media_impl);
+ LLViewerMediaFocus::getInstance()->setPickInfo(pick);
+ }
+
+ return true;
+ }
+ LLViewerMediaFocus::getInstance()->setMouseOverFlag(false);
+
+ return false;
+}
+
+
static void handle_click_action_open_media(LLPointer<LLViewerObject> objectp)
{
//FIXME: how do we handle object in different parcel than us?
@@ -775,7 +814,7 @@ static void handle_click_action_open_media(LLPointer<LLViewerObject> objectp)
if( face < 0 || face >= objectp->getNumTEs() ) return;
// is media playing on this face?
- if (!LLViewerMedia::isActiveMediaTexture(objectp->getTE(face)->getID()))
+ if (LLViewerMedia::getMediaImplFromTextureID(objectp->getTE(face)->getID()) != NULL)
{
handle_click_action_play();
return;
@@ -785,18 +824,7 @@ static void handle_click_action_open_media(LLPointer<LLViewerObject> objectp)
std::string media_type = std::string ( parcel->getMediaType() );
LLStringUtil::trim(media_url);
- // Get the scheme, see if that is handled as well.
- LLURI uri(media_url);
- std::string media_scheme = uri.scheme() != "" ? uri.scheme() : "http";
-
- // HACK: This is directly referencing an impl name. BAD!
- // This can be removed when we have a truly generic media browser that only
- // builds an impl based on the type of url it is passed.
-
- if( LLMediaManager::getInstance()->supportsMediaType( "LLMediaImplLLMozLib", media_scheme, media_type ) )
- {
- LLWeb::loadURL(media_url);
- }
+ LLWeb::loadURL(media_url);
}
static ECursorType cursor_from_parcel_media(U8 click_action)
@@ -814,21 +842,127 @@ static ECursorType cursor_from_parcel_media(U8 click_action)
std::string media_type = std::string ( parcel->getMediaType() );
LLStringUtil::trim(media_url);
- // Get the scheme, see if that is handled as well.
- LLURI uri(media_url);
- std::string media_scheme = uri.scheme() != "" ? uri.scheme() : "http";
+ open_cursor = UI_CURSOR_TOOLMEDIAOPEN;
- if( LLMediaManager::getInstance()->supportsMediaType( "LLMediaImplLLMozLib", media_scheme, media_type ) )
- {
- open_cursor = UI_CURSOR_TOOLMEDIAOPEN;
- }
-
- LLMediaBase::EStatus status = LLViewerParcelMedia::getStatus();
+ LLViewerMediaImpl::EMediaStatus status = LLViewerParcelMedia::getStatus();
switch(status)
{
- case LLMediaBase::STATUS_STARTED:
+ case LLViewerMediaImpl::MEDIA_PLAYING:
return click_action == CLICK_ACTION_PLAY ? UI_CURSOR_TOOLPAUSE : open_cursor;
default:
return UI_CURSOR_TOOLPLAY;
}
}
+
+
+// True if we handled the event.
+BOOL LLToolPie::pickRightMouseDownCallback()
+{
+ S32 x = mPick.mMousePt.mX;
+ S32 y = mPick.mMousePt.mY;
+ MASK mask = mPick.mKeyMask;
+
+ if (mPick.mPickType != LLPickInfo::PICK_LAND)
+ {
+ LLViewerParcelMgr::getInstance()->deselectLand();
+ }
+
+ // didn't click in any UI object, so must have clicked in the world
+ LLViewerObject *object = mPick.getObject();
+ LLViewerObject *parent = NULL;
+ if(object)
+ parent = object->getRootEdit();
+
+ // Can't ignore children here.
+ LLToolSelect::handleObjectSelection(mPick, FALSE, TRUE);
+
+ // Spawn pie menu
+ if (mPick.mPickType == LLPickInfo::PICK_LAND)
+ {
+ LLParcelSelectionHandle selection = LLViewerParcelMgr::getInstance()->selectParcelAt( mPick.mPosGlobal );
+ gMenuHolder->setParcelSelection(selection);
+ gPieLand->show(x, y);
+
+ showVisualContextMenuEffect();
+
+ }
+ else if (mPick.mObjectID == gAgent.getID() )
+ {
+ if(!gPieSelf)
+ {
+ //either at very early startup stage or at late quitting stage,
+ //this event is ignored.
+ return TRUE ;
+ }
+
+ gPieSelf->show(x, y);
+ }
+ else if (object)
+ {
+ gMenuHolder->setObjectSelection(LLSelectMgr::getInstance()->getSelection());
+
+ if (object->isAvatar()
+ || (object->isAttachment() && !object->isHUDAttachment() && !object->permYouOwner()))
+ {
+ // Find the attachment's avatar
+ while( object && object->isAttachment())
+ {
+ object = (LLViewerObject*)object->getParent();
+ }
+
+ // Object is an avatar, so check for mute by id.
+ LLVOAvatar* avatar = (LLVOAvatar*)object;
+ std::string name = avatar->getFullname();
+ if (LLMuteList::getInstance()->isMuted(avatar->getID(), avatar->getFullname()))
+ {
+ gMenuHolder->childSetText("Avatar Mute", std::string("Unmute")); // *TODO:Translate
+ }
+ else
+ {
+ gMenuHolder->childSetText("Avatar Mute", std::string("Mute")); // *TODO:Translate
+ }
+
+ gPieAvatar->show(x, y);
+ }
+ else if (object->isAttachment())
+ {
+ gPieAttachment->show(x, y);
+ }
+ else
+ {
+ // BUG: What about chatting child objects?
+ std::string name;
+ LLSelectNode* node = LLSelectMgr::getInstance()->getSelection()->getFirstRootNode();
+ if (node)
+ {
+ name = node->mName;
+ }
+ if (LLMuteList::getInstance()->isMuted(object->getID(), name))
+ {
+ gMenuHolder->childSetText("Object Mute", std::string("Unmute")); // *TODO:Translate
+ }
+ else
+ {
+ gMenuHolder->childSetText("Object Mute", std::string("Mute")); // *TODO:Translate
+ }
+
+ gPieObject->show(x, y);
+
+ showVisualContextMenuEffect();
+ }
+ }
+
+ LLTool::handleRightMouseDown(x, y, mask);
+ // We handled the event.
+ return TRUE;
+}
+
+void LLToolPie::showVisualContextMenuEffect()
+{
+ // VEFFECT: ShowPie
+ LLHUDEffectSpiral *effectp = (LLHUDEffectSpiral *)LLHUDManager::getInstance()->createViewerEffect(LLHUDObject::LL_HUD_EFFECT_SPHERE, TRUE);
+ effectp->setPositionGlobal(mPick.mPosGlobal);
+ effectp->setColor(LLColor4U(gAgent.getEffectColor()));
+ effectp->setDuration(0.25f);
+
+}
diff --git a/indra/newview/lltoolpie.h b/indra/newview/lltoolpie.h
index 83df03cda2..a55e435282 100644
--- a/indra/newview/lltoolpie.h
+++ b/indra/newview/lltoolpie.h
@@ -51,6 +51,7 @@ public:
virtual BOOL handleRightMouseUp(S32 x, S32 y, MASK mask);
virtual BOOL handleHover(S32 x, S32 y, MASK mask);
virtual BOOL handleDoubleClick(S32 x, S32 y, MASK mask);
+ virtual BOOL handleScrollWheel(S32 x, S32 y, S32 clicks);
virtual void render();
@@ -73,13 +74,13 @@ public:
private:
- BOOL outsideSlop(S32 x, S32 y, S32 start_x, S32 start_y);
- BOOL pickAndShowMenu(BOOL edit_menu);
- BOOL useClickAction(BOOL always_show, MASK mask, LLViewerObject* object,
- LLViewerObject* parent);
+ BOOL outsideSlop (S32 x, S32 y, S32 start_x, S32 start_y);
+ BOOL pickLeftMouseDownCallback();
+ BOOL pickRightMouseDownCallback();
+ BOOL useClickAction (MASK mask, LLViewerObject* object,LLViewerObject* parent);
+ void showVisualContextMenuEffect();
private:
- BOOL mPieMouseButtonDown;
BOOL mGrabMouseButtonDown;
BOOL mMouseOutsideSlop; // for this drag, has mouse moved outside slop region
LLPickInfo mPick;
diff --git a/indra/newview/lltoolpipette.cpp b/indra/newview/lltoolpipette.cpp
index 9d95ccc06f..878ed0f9a9 100644
--- a/indra/newview/lltoolpipette.cpp
+++ b/indra/newview/lltoolpipette.cpp
@@ -55,8 +55,6 @@ LLToolPipette::LLToolPipette()
: LLTool(std::string("Pipette")),
mSuccess(TRUE)
{
- mSelectCallback = NULL;
- mUserData = NULL;
}
@@ -106,6 +104,15 @@ BOOL LLToolPipette::handleToolTip(S32 x, S32 y, std::string& msg, LLRect *sticky
return TRUE;
}
+void LLToolPipette::setTextureEntry(const LLTextureEntry* entry)
+{
+ if (entry)
+ {
+ mTextureEntry = *entry;
+ mSignal(mTextureEntry);
+ }
+}
+
void LLToolPipette::pickCallback(const LLPickInfo& pick_info)
{
LLViewerObject* hit_obj = pick_info.getObject();
@@ -118,20 +125,11 @@ void LLToolPipette::pickCallback(const LLPickInfo& pick_info)
{
//TODO: this should highlight the selected face only
LLSelectMgr::getInstance()->highlightObjectOnly(hit_obj);
- LLToolPipette::getInstance()->mTextureEntry = *hit_obj->getTE(pick_info.mObjectFace);
- if (LLToolPipette::getInstance()->mSelectCallback)
- {
- LLToolPipette::getInstance()->mSelectCallback(LLToolPipette::getInstance()->mTextureEntry, LLToolPipette::getInstance()->mUserData);
- }
+ const LLTextureEntry* entry = hit_obj->getTE(pick_info.mObjectFace);
+ LLToolPipette::getInstance()->setTextureEntry(entry);
}
}
-void LLToolPipette::setSelectCallback(select_callback callback, void* user_data)
-{
- mSelectCallback = callback;
- mUserData = user_data;
-}
-
void LLToolPipette::setResult(BOOL success, const std::string& msg)
{
mTooltipMsg = msg;
diff --git a/indra/newview/lltoolpipette.h b/indra/newview/lltoolpipette.h
index 54c24e9467..3b6ebec67e 100644
--- a/indra/newview/lltoolpipette.h
+++ b/indra/newview/lltoolpipette.h
@@ -40,6 +40,8 @@
#include "lltool.h"
#include "lltextureentry.h"
+#include <boost/function.hpp>
+#include <boost/signals2.hpp>
class LLViewerObject;
class LLPickInfo;
@@ -56,18 +58,19 @@ public:
virtual BOOL handleHover(S32 x, S32 y, MASK mask);
virtual BOOL handleToolTip(S32 x, S32 y, std::string& msg, LLRect *sticky_rect_screen);
- typedef void (*select_callback)(const LLTextureEntry& te, void *data);
- void setSelectCallback(select_callback callback, void* user_data);
+ // Note: Don't return connection; use boost::bind + boost::signals2::trackable to disconnect slots
+ typedef boost::signals2::signal<void (const LLTextureEntry& te)> signal_t;
+ void setToolSelectCallback(const signal_t::slot_type& cb) { mSignal.connect(cb); }
void setResult(BOOL success, const std::string& msg);
-
+
+ void setTextureEntry(const LLTextureEntry* entry);
static void pickCallback(const LLPickInfo& pick_info);
protected:
LLTextureEntry mTextureEntry;
- select_callback mSelectCallback;
+ signal_t mSignal;
BOOL mSuccess;
std::string mTooltipMsg;
- void* mUserData;
};
#endif //LL_LLTOOLPIPETTE_H
diff --git a/indra/newview/lltoolplacer.cpp b/indra/newview/lltoolplacer.cpp
index 88fddd9336..de68dd6153 100644
--- a/indra/newview/lltoolplacer.cpp
+++ b/indra/newview/lltoolplacer.cpp
@@ -35,9 +35,6 @@
// self header
#include "lltoolplacer.h"
-// linden library headers
-#include "llprimitive.h"
-
// viewer headers
#include "llbutton.h"
#include "llviewercontrol.h"
@@ -59,19 +56,23 @@
#include "llvolumemessage.h"
#include "llhudmanager.h"
#include "llagent.h"
-#include "audioengine.h"
+#include "llaudioengine.h"
#include "llhudeffecttrail.h"
#include "llviewerobjectlist.h"
#include "llviewercamera.h"
#include "llviewerstats.h"
+// linden library headers
+#include "llprimitive.h"
+#include "llwindow.h" // incBusyCount()
+
const LLVector3 DEFAULT_OBJECT_SCALE(0.5f, 0.5f, 0.5f);
//static
LLPCode LLToolPlacer::sObjectType = LL_PCODE_CUBE;
LLToolPlacer::LLToolPlacer()
-: LLTool( std::string("Create") )
+: LLTool( "Create" )
{
}
@@ -521,7 +522,7 @@ BOOL LLToolPlacer::placeObject(S32 x, S32 y, MASK mask)
BOOL LLToolPlacer::handleHover(S32 x, S32 y, MASK mask)
{
lldebugst(LLERR_USER_INPUT) << "hover handled by LLToolPlacer" << llendl;
- gViewerWindow->getWindow()->setCursor(UI_CURSOR_TOOLCREATE);
+ gViewerWindow->setCursor(UI_CURSOR_TOOLCREATE);
return TRUE;
}
@@ -534,92 +535,3 @@ void LLToolPlacer::handleDeselect()
{
}
-//////////////////////////////////////////////////////
-// LLToolPlacerPanel
-
-// static
-LLPCode LLToolPlacerPanel::sCube = LL_PCODE_CUBE;
-LLPCode LLToolPlacerPanel::sPrism = LL_PCODE_PRISM;
-LLPCode LLToolPlacerPanel::sPyramid = LL_PCODE_PYRAMID;
-LLPCode LLToolPlacerPanel::sTetrahedron = LL_PCODE_TETRAHEDRON;
-LLPCode LLToolPlacerPanel::sCylinder = LL_PCODE_CYLINDER;
-LLPCode LLToolPlacerPanel::sCylinderHemi= LL_PCODE_CYLINDER_HEMI;
-LLPCode LLToolPlacerPanel::sCone = LL_PCODE_CONE;
-LLPCode LLToolPlacerPanel::sConeHemi = LL_PCODE_CONE_HEMI;
-LLPCode LLToolPlacerPanel::sTorus = LL_PCODE_TORUS;
-LLPCode LLToolPlacerPanel::sSquareTorus = LLViewerObject::LL_VO_SQUARE_TORUS;
-LLPCode LLToolPlacerPanel::sTriangleTorus = LLViewerObject::LL_VO_TRIANGLE_TORUS;
-LLPCode LLToolPlacerPanel::sSphere = LL_PCODE_SPHERE;
-LLPCode LLToolPlacerPanel::sSphereHemi = LL_PCODE_SPHERE_HEMI;
-LLPCode LLToolPlacerPanel::sTree = LL_PCODE_LEGACY_TREE;
-LLPCode LLToolPlacerPanel::sGrass = LL_PCODE_LEGACY_GRASS;
-
-S32 LLToolPlacerPanel::sButtonsAdded = 0;
-LLButton* LLToolPlacerPanel::sButtons[ TOOL_PLACER_NUM_BUTTONS ];
-
-LLToolPlacerPanel::LLToolPlacerPanel(const std::string& name, const LLRect& rect)
- :
- LLPanel( name, rect )
-{
- /* DEPRECATED - JC
- addButton( "UIImgCubeUUID", "UIImgCubeSelectedUUID", &LLToolPlacerPanel::sCube );
- addButton( "UIImgPrismUUID", "UIImgPrismSelectedUUID", &LLToolPlacerPanel::sPrism );
- addButton( "UIImgPyramidUUID", "UIImgPyramidSelectedUUID", &LLToolPlacerPanel::sPyramid );
- addButton( "UIImgTetrahedronUUID", "UIImgTetrahedronSelectedUUID", &LLToolPlacerPanel::sTetrahedron );
- addButton( "UIImgCylinderUUID", "UIImgCylinderSelectedUUID", &LLToolPlacerPanel::sCylinder );
- addButton( "UIImgHalfCylinderUUID", "UIImgHalfCylinderSelectedUUID",&LLToolPlacerPanel::sCylinderHemi );
- addButton( "UIImgConeUUID", "UIImgConeSelectedUUID", &LLToolPlacerPanel::sCone );
- addButton( "UIImgHalfConeUUID", "UIImgHalfConeSelectedUUID", &LLToolPlacerPanel::sConeHemi );
- addButton( "UIImgSphereUUID", "UIImgSphereSelectedUUID", &LLToolPlacerPanel::sSphere );
- addButton( "UIImgHalfSphereUUID", "UIImgHalfSphereSelectedUUID", &LLToolPlacerPanel::sSphereHemi );
- addButton( "UIImgTreeUUID", "UIImgTreeSelectedUUID", &LLToolPlacerPanel::sTree );
- addButton( "UIImgGrassUUID", "UIImgGrassSelectedUUID", &LLToolPlacerPanel::sGrass );
- addButton( "ObjectTorusImageID", "ObjectTorusActiveImageID", &LLToolPlacerPanel::sTorus );
- addButton( "ObjectTubeImageID", "ObjectTubeActiveImageID", &LLToolPlacerPanel::sSquareTorus );
- */
-}
-
-void LLToolPlacerPanel::addButton( const std::string& up_state, const std::string& down_state, LLPCode* pcode )
-{
- const S32 TOOL_SIZE = 32;
- const S32 HORIZ_SPACING = TOOL_SIZE + 5;
- const S32 VERT_SPACING = TOOL_SIZE + 5;
- const S32 VPAD = 10;
- const S32 HPAD = 7;
-
- S32 row = sButtonsAdded / 4;
- S32 column = sButtonsAdded % 4;
-
- LLRect help_rect = gSavedSettings.getRect("ToolHelpRect");
-
- // Build the rectangle, recalling the origin is at lower left
- // and we want the icons to build down from the top.
- LLRect rect;
- rect.setLeftTopAndSize(
- HPAD + (column * HORIZ_SPACING),
- help_rect.mBottom - VPAD - (row * VERT_SPACING),
- TOOL_SIZE,
- TOOL_SIZE );
-
- LLButton* btn = new LLButton(
- std::string("ToolPlacerOptBtn"),
- rect,
- up_state,
- down_state,
- LLStringUtil::null, &LLToolPlacerPanel::setObjectType,
- pcode,
- LLFontGL::getFontSansSerif());
- btn->setFollowsBottom();
- btn->setFollowsLeft();
- addChild(btn);
-
- sButtons[sButtonsAdded] = btn;
- sButtonsAdded++;
-}
-
-// static
-void LLToolPlacerPanel::setObjectType( void* data )
-{
- LLPCode pcode = *(LLPCode*) data;
- LLToolPlacer::setObjectType( pcode );
-}
diff --git a/indra/newview/lltoolplacer.h b/indra/newview/lltoolplacer.h
index d478f7b1c2..b7422380d4 100644
--- a/indra/newview/lltoolplacer.h
+++ b/indra/newview/lltoolplacer.h
@@ -67,43 +67,4 @@ private:
BOOL addDuplicate(S32 x, S32 y);
};
-////////////////////////////////////////////////////
-// LLToolPlacerPanel
-
-
-const S32 TOOL_PLACER_NUM_BUTTONS = 14;
-
-
-class LLToolPlacerPanel : public LLPanel
-{
-public:
-
- LLToolPlacerPanel(const std::string& name, const LLRect& rect);
-
- static void setObjectType( void* data );
-
- static LLPCode sCube;
- static LLPCode sPrism;
- static LLPCode sPyramid;
- static LLPCode sTetrahedron;
- static LLPCode sCylinder;
- static LLPCode sCylinderHemi;
- static LLPCode sCone;
- static LLPCode sConeHemi;
- static LLPCode sTorus;
- static LLPCode sSquareTorus;
- static LLPCode sTriangleTorus;
- static LLPCode sSphere;
- static LLPCode sSphereHemi;
- static LLPCode sTree;
- static LLPCode sGrass;
-
-private:
- void addButton( const std::string& up_state, const std::string& down_state, LLPCode* pcode );
-
-private:
- static S32 sButtonsAdded;
- static LLButton* sButtons[ TOOL_PLACER_NUM_BUTTONS ];
-};
-
#endif
diff --git a/indra/newview/lltoolselect.cpp b/indra/newview/lltoolselect.cpp
index 80e99174c7..97e2865179 100644
--- a/indra/newview/lltoolselect.cpp
+++ b/indra/newview/lltoolselect.cpp
@@ -48,11 +48,11 @@
#include "llviewerobjectlist.h"
#include "llviewerregion.h"
#include "llviewerwindow.h"
-#include "llvoavatar.h"
+#include "llvoavatarself.h"
#include "llworld.h"
// Globals
-extern BOOL gAllowSelectAvatar;
+//extern BOOL gAllowSelectAvatar;
const F32 SELECTION_ROTATION_TRESHOLD = 0.1f;
@@ -87,7 +87,7 @@ LLObjectSelectionHandle LLToolSelect::handleObjectSelection(const LLPickInfo& pi
BOOL select_movable = gSavedSettings.getBOOL("SelectMovableOnly");
// *NOTE: These settings must be cleaned up at bottom of function.
- if (temp_select || gAllowSelectAvatar)
+ if (temp_select || LLSelectMgr::getInstance()->mAllowSelectAvatar)
{
gSavedSettings.setBOOL("SelectOwnedOnly", FALSE);
gSavedSettings.setBOOL("SelectMovableOnly", FALSE);
@@ -217,7 +217,7 @@ LLObjectSelectionHandle LLToolSelect::handleObjectSelection(const LLPickInfo& pi
} //if(!object)
// Cleanup temp select settings above.
- if (temp_select || gAllowSelectAvatar)
+ if (temp_select ||LLSelectMgr::getInstance()->mAllowSelectAvatar)
{
gSavedSettings.setBOOL("SelectOwnedOnly", select_owned);
gSavedSettings.setBOOL("SelectMovableOnly", select_movable);
diff --git a/indra/newview/lltoolselectland.cpp b/indra/newview/lltoolselectland.cpp
index 91223904b7..5c8b08db3b 100644
--- a/indra/newview/lltoolselectland.cpp
+++ b/indra/newview/lltoolselectland.cpp
@@ -38,12 +38,10 @@
#include "llparcel.h"
// Viewer includes
-#include "llagent.h"
#include "llviewercontrol.h"
#include "llfloatertools.h"
#include "llselectmgr.h"
#include "llstatusbar.h"
-#include "lltoolview.h"
#include "llviewerparcelmgr.h"
#include "llviewerwindow.h"
@@ -177,13 +175,13 @@ BOOL LLToolSelectLand::handleHover(S32 x, S32 y, MASK mask)
roundXY(mEastNorthTop);
lldebugst(LLERR_USER_INPUT) << "hover handled by LLToolSelectLand (active, land)" << llendl;
- gViewerWindow->getWindow()->setCursor(UI_CURSOR_ARROW);
+ gViewerWindow->setCursor(UI_CURSOR_ARROW);
}
else
{
mDragEndValid = FALSE;
lldebugst(LLERR_USER_INPUT) << "hover handled by LLToolSelectLand (active, no land)" << llendl;
- gViewerWindow->getWindow()->setCursor(UI_CURSOR_NO);
+ gViewerWindow->setCursor(UI_CURSOR_NO);
}
mDragEndX = x;
@@ -192,13 +190,13 @@ BOOL LLToolSelectLand::handleHover(S32 x, S32 y, MASK mask)
else
{
lldebugst(LLERR_USER_INPUT) << "hover handled by LLToolSelectLand (active, in slop)" << llendl;
- gViewerWindow->getWindow()->setCursor(UI_CURSOR_ARROW);
+ gViewerWindow->setCursor(UI_CURSOR_ARROW);
}
}
else
{
lldebugst(LLERR_USER_INPUT) << "hover handled by LLToolSelectLand (inactive)" << llendl;
- gViewerWindow->getWindow()->setCursor(UI_CURSOR_ARROW);
+ gViewerWindow->setCursor(UI_CURSOR_ARROW);
}
return TRUE;
diff --git a/indra/newview/lltoolselectrect.cpp b/indra/newview/lltoolselectrect.cpp
index d544bff992..f87d1480d7 100644
--- a/indra/newview/lltoolselectrect.cpp
+++ b/indra/newview/lltoolselectrect.cpp
@@ -44,7 +44,6 @@
#include "llviewercontrol.h"
#include "llui.h"
#include "llselectmgr.h"
-#include "lltoolview.h"
#include "lltoolmgr.h"
#include "llviewerobject.h"
#include "llviewerobjectlist.h"
@@ -159,7 +158,7 @@ BOOL LLToolSelectRect::handleHover(S32 x, S32 y, MASK mask)
lldebugst(LLERR_USER_INPUT) << "hover handled by LLToolSelectRect (inactive)" << llendl;
}
- gViewerWindow->getWindow()->setCursor(UI_CURSOR_ARROW);
+ gViewerWindow->setCursor(UI_CURSOR_ARROW);
return TRUE;
}
diff --git a/indra/newview/lltoolview.cpp b/indra/newview/lltoolview.cpp
index 9f6a77d245..f8393ebc47 100644
--- a/indra/newview/lltoolview.cpp
+++ b/indra/newview/lltoolview.cpp
@@ -65,9 +65,9 @@ LLToolContainer::~LLToolContainer()
LLToolView::LLToolView(const std::string& name, const LLRect& rect)
-: LLView(name, rect, MOUSE_OPAQUE),
- mButtonCount(0)
+: mButtonCount(0)
{
+ LLView::init(LLView::Params().name(name).rect(rect).mouse_opaque(true));
}
diff --git a/indra/newview/lltracker.cpp b/indra/newview/lltracker.cpp
index d54cc798d2..5929ecd928 100644
--- a/indra/newview/lltracker.cpp
+++ b/indra/newview/lltracker.cpp
@@ -39,7 +39,7 @@
#include "llgl.h"
#include "llrender.h"
#include "llinventory.h"
-#include "llmemory.h"
+#include "llpointer.h"
#include "llstring.h"
#include "lluuid.h"
#include "v3math.h"
@@ -51,7 +51,6 @@
#include "lltracker.h"
#include "llagent.h"
#include "llcallingcard.h"
-#include "llcolorscheme.h"
#include "llfloaterworldmap.h"
#include "llhudtext.h"
#include "llhudview.h"
@@ -113,12 +112,14 @@ void LLTracker::stopTracking(void* userdata)
// static virtual
void LLTracker::drawHUDArrow()
{
+ static LLUIColor map_track_color = LLUIColorTable::instance().getColor("MapTrackColor", LLColor4::white);
+
/* tracking autopilot destination has been disabled
-- 2004.01.09, Leviathan
// Draw dot for autopilot target
if (gAgent.getAutoPilot())
{
- instance()->drawMarker( gAgent.getAutoPilotTargetGlobal(), gTrackColor );
+ instance()->drawMarker( gAgent.getAutoPilotTargetGlobal(), map_track_color );
return;
}
*/
@@ -128,12 +129,12 @@ void LLTracker::drawHUDArrow()
// Tracked avatar
if(LLAvatarTracker::instance().haveTrackingInfo())
{
- instance()->drawMarker( LLAvatarTracker::instance().getGlobalPos(), gTrackColor );
+ instance()->drawMarker( LLAvatarTracker::instance().getGlobalPos(), map_track_color );
}
break;
case TRACKING_LANDMARK:
- instance()->drawMarker( getTrackedPositionGlobal(), gTrackColor );
+ instance()->drawMarker( getTrackedPositionGlobal(), map_track_color );
break;
case TRACKING_LOCATION:
@@ -145,7 +146,7 @@ void LLTracker::drawHUDArrow()
+ 0.1f * (LLWorld::getInstance()->resolveLandHeightGlobal(getTrackedPositionGlobal()) + 1.5f);
#endif
instance()->mTrackedPositionGlobal.mdV[VZ] = llclamp((F32)instance()->mTrackedPositionGlobal.mdV[VZ], LLWorld::getInstance()->resolveLandHeightGlobal(getTrackedPositionGlobal()) + 1.5f, (F32)instance()->getTrackedPositionGlobal().mdV[VZ]);
- instance()->drawMarker( getTrackedPositionGlobal(), gTrackColor );
+ instance()->drawMarker( getTrackedPositionGlobal(), map_track_color );
break;
default:
@@ -161,7 +162,9 @@ void LLTracker::render3D()
{
return;
}
-
+
+ static LLUIColor map_track_color = LLUIColorTable::instance().getColor("MapTrackColor", LLColor4::white);
+
// Arbitary location beacon
if( instance()->mIsTrackingLocation )
{
@@ -181,7 +184,7 @@ void LLTracker::render3D()
}
else
{
- renderBeacon( instance()->mTrackedPositionGlobal, gTrackColor,
+ renderBeacon( instance()->mTrackedPositionGlobal, map_track_color,
instance()->mBeaconText, instance()->mTrackedLocationName );
}
}
@@ -223,7 +226,7 @@ void LLTracker::render3D()
// and back again
instance()->mHasReachedLandmark = FALSE;
}
- renderBeacon( instance()->mTrackedPositionGlobal, gTrackColor,
+ renderBeacon( instance()->mTrackedPositionGlobal, map_track_color,
instance()->mBeaconText, instance()->mTrackedLandmarkName );
}
}
@@ -252,7 +255,7 @@ void LLTracker::render3D()
}
else
{
- renderBeacon( av_tracker.getGlobalPos(), gTrackColor,
+ renderBeacon( av_tracker.getGlobalPos(), map_track_color,
instance()->mBeaconText, av_tracker.getName() );
}
}
diff --git a/indra/newview/lltracker.h b/indra/newview/lltracker.h
index 2850365272..bfe9d6c6b5 100644
--- a/indra/newview/lltracker.h
+++ b/indra/newview/lltracker.h
@@ -40,7 +40,7 @@
#define LL_LLTRACKER_H
#include "lldarray.h"
-#include "llmemory.h"
+#include "llpointer.h"
#include "llstring.h"
#include "lluuid.h"
#include "v3dmath.h"
diff --git a/indra/newview/lluploaddialog.cpp b/indra/newview/lluploaddialog.cpp
index 7f63972c8d..153e3e7382 100644
--- a/indra/newview/lluploaddialog.cpp
+++ b/indra/newview/lluploaddialog.cpp
@@ -41,6 +41,7 @@
#include "llkeyboard.h"
#include "llfocusmgr.h"
#include "llviewercontrol.h"
+#include "llrootview.h"
// static
LLUploadDialog* LLUploadDialog::sDialog = NULL;
@@ -64,8 +65,7 @@ void LLUploadDialog::modalUploadFinished()
// Private methods
LLUploadDialog::LLUploadDialog( const std::string& msg)
- :
- LLPanel( std::string("Uploading..."), LLRect(0,100,100,0) ) // dummy rect. Will reshape below.
+ : LLPanel()
{
setBackgroundVisible( TRUE );
@@ -75,11 +75,16 @@ LLUploadDialog::LLUploadDialog( const std::string& msg)
}
LLUploadDialog::sDialog = this;
- const LLFontGL* font = LLResMgr::getInstance()->getRes( LLFONT_SANSSERIF );
+ const LLFontGL* font = LLFontGL::getFontSansSerif();
LLRect msg_rect;
for (int line_num=0; line_num<16; ++line_num)
{
- mLabelBox[line_num] = new LLTextBox( std::string("Filename"), msg_rect, std::string("Filename"), font );
+ LLTextBox::Params params;
+ params.name("Filename");
+ params.rect(msg_rect);
+ params.text("Filename");
+ params.font(font);
+ mLabelBox[line_num] = LLUICtrlFactory::create<LLTextBox> (params);
addChild(mLabelBox[line_num]);
}
@@ -91,7 +96,7 @@ LLUploadDialog::LLUploadDialog( const std::string& msg)
void LLUploadDialog::setMessage( const std::string& msg)
{
- const LLFontGL* font = LLResMgr::getInstance()->getRes( LLFONT_SANSSERIF );
+ const LLFontGL* font = LLFontGL::getFontSansSerif();
const S32 VPAD = 16;
const S32 HPAD = 25;
@@ -139,7 +144,7 @@ void LLUploadDialog::setMessage( const std::string& msg)
msg_rect.setOriginAndSize( msg_x, msg_y, max_msg_width, line_height );
mLabelBox[line_num]->setRect(msg_rect);
mLabelBox[line_num]->setText(cur_line);
- mLabelBox[line_num]->setColor( gColors.getColor( "LabelTextColor" ) );
+ mLabelBox[line_num]->setColor( LLUIColorTable::instance().getColor( "LabelTextColor" ) );
mLabelBox[line_num]->setVisible(TRUE);
msg_y -= line_height;
++line_num;
diff --git a/indra/newview/llurldispatcher.cpp b/indra/newview/llurldispatcher.cpp
index 85ab44bc13..cb68045310 100644
--- a/indra/newview/llurldispatcher.cpp
+++ b/indra/newview/llurldispatcher.cpp
@@ -36,12 +36,14 @@
// viewer includes
#include "llagent.h" // teleportViaLocation()
#include "llcommandhandler.h"
-#include "llfloaterurldisplay.h"
#include "llfloaterdirectory.h"
-#include "llfloaterhtml.h"
+#include "llfloatermediabrowser.h"
+#include "llfloaterreg.h"
+#include "llfloaterurldisplay.h"
#include "llfloaterworldmap.h"
-#include "llfloaterhtmlhelp.h"
#include "llpanellogin.h"
+#include "llsidetray.h"
+#include "llslurl.h"
#include "llstartup.h" // gStartupState
#include "llurlsimstring.h"
#include "llweb.h"
@@ -50,22 +52,11 @@
// library includes
#include "llsd.h"
-const std::string SLURL_SL_HELP_PREFIX = "secondlife://app.";
-const std::string SLURL_SL_PREFIX = "sl://";
-const std::string SLURL_SECONDLIFE_PREFIX = "secondlife://";
-const std::string SLURL_SLURL_PREFIX = "http://slurl.com/secondlife/";
-
-const std::string SLURL_APP_TOKEN = "app/";
-
class LLURLDispatcherImpl
{
public:
- static bool isSLURL(const std::string& url);
-
- static bool isSLURLCommand(const std::string& url);
-
static bool dispatch(const std::string& url,
- LLWebBrowserCtrl* web,
+ LLMediaCtrl* web,
bool trusted_browser);
// returns true if handled or explicitly blocked.
@@ -74,7 +65,7 @@ public:
private:
static bool dispatchCore(const std::string& url,
bool right_mouse,
- LLWebBrowserCtrl* web,
+ LLMediaCtrl* web,
bool trusted_browser);
// handles both left and right click
@@ -84,7 +75,7 @@ private:
static bool dispatchApp(const std::string& url,
bool right_mouse,
- LLWebBrowserCtrl* web,
+ LLMediaCtrl* web,
bool trusted_browser);
// Handles secondlife:///app/agent/<agent_id>/about and similar
// by showing panel in Search floater.
@@ -104,39 +95,13 @@ private:
// Called by LLWorldMap when a region name has been resolved to a
// location in-world, used by places-panel display.
- static bool matchPrefix(const std::string& url, const std::string& prefix);
-
- static std::string stripProtocol(const std::string& url);
-
friend class LLTeleportHandler;
};
// static
-bool LLURLDispatcherImpl::isSLURL(const std::string& url)
-{
- if (matchPrefix(url, SLURL_SL_HELP_PREFIX)) return true;
- if (matchPrefix(url, SLURL_SL_PREFIX)) return true;
- if (matchPrefix(url, SLURL_SECONDLIFE_PREFIX)) return true;
- if (matchPrefix(url, SLURL_SLURL_PREFIX)) return true;
- return false;
-}
-
-// static
-bool LLURLDispatcherImpl::isSLURLCommand(const std::string& url)
-{
- if (matchPrefix(url, SLURL_SL_PREFIX + SLURL_APP_TOKEN)
- || matchPrefix(url, SLURL_SECONDLIFE_PREFIX + "/" + SLURL_APP_TOKEN)
- || matchPrefix(url, SLURL_SLURL_PREFIX + SLURL_APP_TOKEN) )
- {
- return true;
- }
- return false;
-}
-
-// static
bool LLURLDispatcherImpl::dispatchCore(const std::string& url,
bool right_mouse,
- LLWebBrowserCtrl* web,
+ LLMediaCtrl* web,
bool trusted_browser)
{
if (url.empty()) return false;
@@ -156,7 +121,7 @@ bool LLURLDispatcherImpl::dispatchCore(const std::string& url,
// static
bool LLURLDispatcherImpl::dispatch(const std::string& url,
- LLWebBrowserCtrl* web,
+ LLMediaCtrl* web,
bool trusted_browser)
{
llinfos << "url: " << url << llendl;
@@ -169,7 +134,7 @@ bool LLURLDispatcherImpl::dispatchRightClick(const std::string& url)
{
llinfos << "url: " << url << llendl;
const bool right_click = true;
- LLWebBrowserCtrl* web = NULL;
+ LLMediaCtrl* web = NULL;
const bool trusted_browser = false;
return dispatchCore(url, right_click, web, trusted_browser);
}
@@ -178,7 +143,7 @@ bool LLURLDispatcherImpl::dispatchRightClick(const std::string& url)
bool LLURLDispatcherImpl::dispatchHelp(const std::string& url, bool right_mouse)
{
#if LL_LIBXUL_ENABLED
- if (matchPrefix(url, SLURL_SL_HELP_PREFIX))
+ if (LLSLURL::isURLHelp(url))
{
gViewerHtmlHelp.show();
return true;
@@ -190,10 +155,10 @@ bool LLURLDispatcherImpl::dispatchHelp(const std::string& url, bool right_mouse)
// static
bool LLURLDispatcherImpl::dispatchApp(const std::string& url,
bool right_mouse,
- LLWebBrowserCtrl* web,
+ LLMediaCtrl* web,
bool trusted_browser)
{
- if (!isSLURL(url))
+ if (!LLSLURL::isSLURL(url))
{
return false;
}
@@ -211,7 +176,7 @@ bool LLURLDispatcherImpl::dispatchApp(const std::string& url,
// static
bool LLURLDispatcherImpl::dispatchRegion(const std::string& url, bool right_mouse)
{
- if (!isSLURL(url))
+ if (!LLSLURL::isSLURL(url))
{
return false;
}
@@ -230,15 +195,16 @@ bool LLURLDispatcherImpl::dispatchRegion(const std::string& url, bool right_mous
return true;
}
- std::string sim_string = stripProtocol(url);
+ std::string sim_string = LLSLURL::stripProtocol(url);
std::string region_name;
S32 x = 128;
S32 y = 128;
S32 z = 0;
LLURLSimString::parse(sim_string, &region_name, &x, &y, &z);
- LLFloaterURLDisplay* url_displayp = LLFloaterURLDisplay::getInstance(LLSD());
- url_displayp->setName(region_name);
+ // LLFloaterURLDisplay functionality moved to LLPanelPlaces in Side Tray.
+ //LLFloaterURLDisplay* url_displayp = LLFloaterReg::getTypedInstance<LLFloaterURLDisplay>("preview_url",LLSD());
+ //if(url_displayp) url_displayp->setName(region_name);
// Request a region handle by name
LLWorldMap::getInstance()->sendNamedRegionRequest(region_name,
@@ -251,7 +217,7 @@ bool LLURLDispatcherImpl::dispatchRegion(const std::string& url, bool right_mous
/*static*/
void LLURLDispatcherImpl::regionNameCallback(U64 region_handle, const std::string& url, const LLUUID& snapshot_id, bool teleport)
{
- std::string sim_string = stripProtocol(url);
+ std::string sim_string = LLSLURL::stripProtocol(url);
std::string region_name;
S32 x = 128;
S32 y = 128;
@@ -289,7 +255,7 @@ void LLURLDispatcherImpl::regionNameCallback(U64 region_handle, const std::strin
/* static */
void LLURLDispatcherImpl::regionHandleCallback(U64 region_handle, const std::string& url, const LLUUID& snapshot_id, bool teleport)
{
- std::string sim_string = stripProtocol(url);
+ std::string sim_string = LLSLURL::stripProtocol(url);
std::string region_name;
S32 x = 128;
S32 y = 128;
@@ -309,63 +275,43 @@ void LLURLDispatcherImpl::regionHandleCallback(U64 region_handle, const std::str
local_pos.mV[VY] = (F32)local_y;
local_pos.mV[VZ] = (F32)z;
-
+ LLVector3d global_pos = from_region_handle(region_handle);
+ global_pos += LLVector3d(local_pos);
if (teleport)
- {
- LLVector3d global_pos = from_region_handle(region_handle);
- global_pos += LLVector3d(local_pos);
+ {
gAgent.teleportViaLocation(global_pos);
- if(gFloaterWorldMap)
+ LLFloaterWorldMap* instance = LLFloaterWorldMap::getInstance();
+ if(instance)
{
- gFloaterWorldMap->trackLocation(global_pos);
+ instance->trackLocation(global_pos);
}
}
else
{
- // display informational floater, allow user to click teleport btn
- LLFloaterURLDisplay* url_displayp = LLFloaterURLDisplay::getInstance(LLSD());
-
-
- url_displayp->displayParcelInfo(region_handle, local_pos);
- if(snapshot_id.notNull())
- {
- url_displayp->setSnapshotDisplay(snapshot_id);
- }
- std::string locationString = llformat("%s %d, %d, %d", region_name.c_str(), x, y, z);
- url_displayp->setLocationString(locationString);
- }
-}
-
-// static
-bool LLURLDispatcherImpl::matchPrefix(const std::string& url, const std::string& prefix)
-{
- std::string test_prefix = url.substr(0, prefix.length());
- LLStringUtil::toLower(test_prefix);
- return test_prefix == prefix;
-}
-
-// static
-std::string LLURLDispatcherImpl::stripProtocol(const std::string& url)
-{
- std::string stripped = url;
- if (matchPrefix(stripped, SLURL_SL_HELP_PREFIX))
- {
- stripped.erase(0, SLURL_SL_HELP_PREFIX.length());
- }
- else if (matchPrefix(stripped, SLURL_SL_PREFIX))
- {
- stripped.erase(0, SLURL_SL_PREFIX.length());
+ LLSD key;
+ key["type"] = "remote_place";
+ key["x"] = global_pos.mdV[VX];
+ key["y"] = global_pos.mdV[VY];
+ key["z"] = global_pos.mdV[VZ];
+
+ LLSideTray::getInstance()->showPanel("panel_places", key);
+
+ // LLFloaterURLDisplay functionality moved to LLPanelPlaces in Side Tray.
+
+// // display informational floater, allow user to click teleport btn
+// LLFloaterURLDisplay* url_displayp = LLFloaterReg::getTypedInstance<LLFloaterURLDisplay>("preview_url",LLSD());
+// if(url_displayp)
+// {
+// url_displayp->displayParcelInfo(region_handle, local_pos);
+// if(snapshot_id.notNull())
+// {
+// url_displayp->setSnapshotDisplay(snapshot_id);
+// }
+// std::string locationString = llformat("%s %d, %d, %d", region_name.c_str(), x, y, z);
+// url_displayp->setLocationString(locationString);
+// }
}
- else if (matchPrefix(stripped, SLURL_SECONDLIFE_PREFIX))
- {
- stripped.erase(0, SLURL_SECONDLIFE_PREFIX.length());
- }
- else if (matchPrefix(stripped, SLURL_SLURL_PREFIX))
- {
- stripped.erase(0, SLURL_SLURL_PREFIX.length());
- }
- return stripped;
}
//---------------------------------------------------------------------------
@@ -380,7 +326,7 @@ public:
LLTeleportHandler() : LLCommandHandler("teleport", true) { }
bool handle(const LLSD& tokens, const LLSD& query_map,
- LLWebBrowserCtrl* web)
+ LLMediaCtrl* web)
{
// construct a "normal" SLURL, resolve the region to
// a global position, and teleport to it
@@ -390,7 +336,7 @@ public:
std::string region_name = LLURLSimString::unescapeRegionName(tokens[0]);
// build secondlife://De%20Haro/123/45/67 for use in callback
- std::string url = SLURL_SECONDLIFE_PREFIX;
+ std::string url = LLSLURL::PREFIX_SECONDLIFE;
for (int i = 0; i < tokens.size(); ++i)
{
url += tokens[i].asString() + "/";
@@ -407,20 +353,8 @@ LLTeleportHandler gTeleportHandler;
//---------------------------------------------------------------------------
// static
-bool LLURLDispatcher::isSLURL(const std::string& url)
-{
- return LLURLDispatcherImpl::isSLURL(url);
-}
-
-// static
-bool LLURLDispatcher::isSLURLCommand(const std::string& url)
-{
- return LLURLDispatcherImpl::isSLURLCommand(url);
-}
-
-// static
bool LLURLDispatcher::dispatch(const std::string& url,
- LLWebBrowserCtrl* web,
+ LLMediaCtrl* web,
bool trusted_browser)
{
return LLURLDispatcherImpl::dispatch(url, web, trusted_browser);
@@ -442,15 +376,6 @@ bool LLURLDispatcher::dispatchFromTextEditor(const std::string& url)
// click on it.
// *TODO: Make this trust model more refined. JC
const bool trusted_browser = true;
- LLWebBrowserCtrl* web = NULL;
+ LLMediaCtrl* web = NULL;
return LLURLDispatcherImpl::dispatch(url, web, trusted_browser);
}
-
-// static
-std::string LLURLDispatcher::buildSLURL(const std::string& regionname,
- S32 x, S32 y, S32 z)
-{
- std::string slurl = SLURL_SLURL_PREFIX + regionname + llformat("/%d/%d/%d",x,y,z);
- slurl = LLWeb::escapeURL( slurl );
- return slurl;
-}
diff --git a/indra/newview/llurldispatcher.h b/indra/newview/llurldispatcher.h
index a4f6866a07..ff8a351253 100644
--- a/indra/newview/llurldispatcher.h
+++ b/indra/newview/llurldispatcher.h
@@ -32,20 +32,14 @@
#ifndef LLURLDISPATCHER_H
#define LLURLDISPATCHER_H
-class LLWebBrowserCtrl;
+class LLMediaCtrl;
class LLURLDispatcher
{
public:
- static bool isSLURL(const std::string& url);
- // Is this any sort of secondlife:// or sl:// URL?
-
- static bool isSLURLCommand(const std::string& url);
- // Is this a special secondlife://app/ URL?
-
static bool dispatch(const std::string& url,
- LLWebBrowserCtrl* web,
+ LLMediaCtrl* web,
bool trusted_browser);
// At startup time and on clicks in internal web browsers,
// teleport, open map, or run requested command.
@@ -54,7 +48,7 @@ public:
// secondlife:///app/agent/3d6181b0-6a4b-97ef-18d8-722652995cf1/show
// sl://app/foo/bar
// @param web
- // Pointer to LLWebBrowserCtrl sending URL, can be NULL
+ // Pointer to LLMediaCtrl sending URL, can be NULL
// @param trusted_browser
// True if coming inside the app AND from a brower instance
// that navigates to trusted (Linden Lab) pages.
@@ -63,9 +57,6 @@ public:
static bool dispatchRightClick(const std::string& url);
static bool dispatchFromTextEditor(const std::string& url);
-
- static std::string buildSLURL(const std::string& regionname, S32 x, S32 y, S32 z);
- // builds: http://slurl.com/secondlife/RegionName/x/y/z/
};
#endif
diff --git a/indra/newview/llurllineeditorctrl.cpp b/indra/newview/llurllineeditorctrl.cpp
new file mode 100644
index 0000000000..046b3e619b
--- /dev/null
+++ b/indra/newview/llurllineeditorctrl.cpp
@@ -0,0 +1,97 @@
+/**
+ * @file llurllineeditorctrl.cpp
+ * @brief LLURLLineEditor base class
+ *
+ * $LicenseInfo:firstyear=2001&license=viewergpl$
+ *
+ * Copyright (c) 2001-2009, Linden Research, Inc.
+ *
+ * Second Life Viewer Source Code
+ * The source code in this file ("Source Code") is provided by Linden Lab
+ * to you under the terms of the GNU General Public License, version 2.0
+ * ("GPL"), unless you have obtained a separate licensing agreement
+ * ("Other License"), formally executed by you and Linden Lab. Terms of
+ * the GPL can be found in doc/GPL-license.txt in this distribution, or
+ * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
+ *
+ * There are special exceptions to the terms and conditions of the GPL as
+ * it is applied to this Source Code. View the full text of the exception
+ * in the file doc/FLOSS-exception.txt in this software distribution, or
+ * online at
+ * http://secondlifegrid.net/programs/open_source/licensing/flossexception
+ *
+ * By copying, modifying or distributing this software, you acknowledge
+ * that you have read and understood your obligations described above,
+ * and agree to abide by those obligations.
+ *
+ * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+ * COMPLETENESS OR PERFORMANCE.
+ * $/LicenseInfo$
+ */
+
+#include "llviewerprecompiledheaders.h"
+
+#include "llclipboard.h"
+#include "lluictrlfactory.h"
+
+#include "llurllineeditorctrl.h"
+
+#include "llweb.h"
+
+//Constructor
+LLURLLineEditor::LLURLLineEditor(const LLLineEditor::Params& p)
+: LLLineEditor(p){
+
+}
+
+// copy selection to clipboard
+void LLURLLineEditor::copy()
+{
+ if( canCopy() )
+ {
+ copyEscapedURLToClipboard();
+ }
+}
+
+// cut selection to clipboard
+void LLURLLineEditor::cut()
+{
+ if( canCut() )
+ {
+ // Prepare for possible rollback
+ LLURLLineEditorRollback rollback( this );
+
+ copyEscapedURLToClipboard();
+
+ deleteSelection();
+
+ // Validate new string and rollback the if needed.
+ BOOL need_to_rollback = ( mPrevalidateFunc && !mPrevalidateFunc( mText.getWString() ) );
+ if( need_to_rollback )
+ {
+ rollback.doRollback( this );
+ reportBadKeystroke();
+ }
+ else
+ if( mKeystrokeCallback )
+ {
+ mKeystrokeCallback( this );
+ }
+ }
+}
+// Copies escaped URL to clipboard
+void LLURLLineEditor::copyEscapedURLToClipboard()
+{
+ S32 left_pos = llmin( mSelectionStart, mSelectionEnd );
+ S32 length = llabs( mSelectionStart - mSelectionEnd );
+
+ const std::string unescaped_text = wstring_to_utf8str(mText.getWString().substr(left_pos, length));
+ LLWString selected_escaped_text = utf8str_to_wstring(LLWeb::escapeURL(unescaped_text));
+ gClipboard.copyFromString( selected_escaped_text );
+}
+// Makes UISndBadKeystroke sound
+void LLURLLineEditor::reportBadKeystroke()
+{
+ make_ui_sound("UISndBadKeystroke");
+}
diff --git a/indra/newview/llurllineeditorctrl.h b/indra/newview/llurllineeditorctrl.h
new file mode 100644
index 0000000000..618f29dfbf
--- /dev/null
+++ b/indra/newview/llurllineeditorctrl.h
@@ -0,0 +1,100 @@
+/**
+ * @file llurllineeditorctrl.h
+ * @brief Combobox-like location input control
+ *
+ * $LicenseInfo:firstyear=2009&license=viewergpl$
+ *
+ * Copyright (c) 2009, Linden Research, Inc.
+ *
+ * Second Life Viewer Source Code
+ * The source code in this file ("Source Code") is provided by Linden Lab
+ * to you under the terms of the GNU General Public License, version 2.0
+ * ("GPL"), unless you have obtained a separate licensing agreement
+ * ("Other License"), formally executed by you and Linden Lab. Terms of
+ * the GPL can be found in doc/GPL-license.txt in this distribution, or
+ * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
+ *
+ * There are special exceptions to the terms and conditions of the GPL as
+ * it is applied to this Source Code. View the full text of the exception
+ * in the file doc/FLOSS-exception.txt in this software distribution, or
+ * online at
+ * http://secondlifegrid.net/programs/open_source/licensing/flossexception
+ *
+ * By copying, modifying or distributing this software, you acknowledge
+ * that you have read and understood your obligations described above,
+ * and agree to abide by those obligations.
+ *
+ * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+ * COMPLETENESS OR PERFORMANCE.
+ * $/LicenseInfo$
+ */
+
+#ifndef LLURLLINEEDITOR_H_
+#define LLURLLINEEDITOR_H_
+
+#include "linden_common.h"
+
+#include "lllineeditor.h"
+#include "lluictrl.h"
+
+// LLURLLineEditor class performing escaping of an URL while copying or cutting the target text
+class LLURLLineEditor: public LLLineEditor {
+ LOG_CLASS( LLURLLineEditor);
+
+public:
+ // LLLineEditor overrides to do necessary escaping
+ /*virtual*/ void copy();
+ /*virtual*/ void cut();
+
+protected:
+ LLURLLineEditor(const Params&);
+ friend class LLUICtrlFactory;
+ friend class LLFloaterEditUI;
+
+private:
+ // util function to escape selected text and copy it to clipboard
+ void copyEscapedURLToClipboard();
+ // send a beep signal if keystroke is bad. As it is private at LLLineEditor we need own function
+ void reportBadKeystroke();
+
+ // Helper class to do rollback if needed
+ class LLURLLineEditorRollback
+ {
+ public:
+ LLURLLineEditorRollback( LLURLLineEditor* ed )
+ :
+ mCursorPos( ed->mCursorPos ),
+ mScrollHPos( ed->mScrollHPos ),
+ mIsSelecting( ed->mIsSelecting ),
+ mSelectionStart( ed->mSelectionStart ),
+ mSelectionEnd( ed->mSelectionEnd )
+ {
+ mText = ed->getText();
+ }
+
+ void doRollback( LLURLLineEditor* ed )
+ {
+ ed->mCursorPos = mCursorPos;
+ ed->mScrollHPos = mScrollHPos;
+ ed->mIsSelecting = mIsSelecting;
+ ed->mSelectionStart = mSelectionStart;
+ ed->mSelectionEnd = mSelectionEnd;
+ ed->mText = mText;
+ ed->mPrevText = mText;
+ }
+
+ std::string getText() { return mText; }
+
+ private:
+ std::string mText;
+ S32 mCursorPos;
+ S32 mScrollHPos;
+ BOOL mIsSelecting;
+ S32 mSelectionStart;
+ S32 mSelectionEnd;
+ }; // end class LLURLLineEditorRollback
+
+};
+
+#endif /* LLURLLINEEDITOR_H_ */
diff --git a/indra/newview/llviewchildren.cpp b/indra/newview/llviewchildren.cpp
index 1a66b24891..842ffc7f9a 100644
--- a/indra/newview/llviewchildren.cpp
+++ b/indra/newview/llviewchildren.cpp
@@ -94,10 +94,10 @@ void LLViewChildren::setBadge(const std::string& id, Badge badge, bool visible)
switch (badge)
{
default:
- case BADGE_OK: child->setImage(std::string("badge_ok.j2c")); break;
- case BADGE_NOTE: child->setImage(std::string("badge_note.j2c")); break;
- case BADGE_WARN: child->setImage(std::string("badge_warn.j2c")); break;
- case BADGE_ERROR: child->setImage(std::string("badge_error.j2c")); break;
+ case BADGE_OK: child->setValue(std::string("badge_ok.j2c")); break;
+ case BADGE_NOTE: child->setValue(std::string("badge_note.j2c")); break;
+ case BADGE_WARN: child->setValue(std::string("badge_warn.j2c")); break;
+ case BADGE_ERROR: child->setValue(std::string("badge_error.j2c")); break;
}
}
}
diff --git a/indra/newview/llviewerassetstorage.h b/indra/newview/llviewerassetstorage.h
index 15c11c7025..512b590a1b 100644
--- a/indra/newview/llviewerassetstorage.h
+++ b/indra/newview/llviewerassetstorage.h
@@ -47,6 +47,7 @@ public:
LLViewerAssetStorage(LLMessageSystem *msg, LLXferManager *xfer,
LLVFS *vfs);
+ using LLAssetStorage::storeAssetData;
virtual void storeAssetData(
const LLTransactionID& tid,
LLAssetType::EType atype,
diff --git a/indra/newview/llvieweraudio.cpp b/indra/newview/llvieweraudio.cpp
index a1e55c1137..49506db173 100644
--- a/indra/newview/llvieweraudio.cpp
+++ b/indra/newview/llvieweraudio.cpp
@@ -32,7 +32,7 @@
#include "llviewerprecompiledheaders.h"
-#include "audioengine.h"
+#include "llaudioengine.h"
#include "llagent.h"
#include "llappviewer.h"
#include "llvieweraudio.h"
@@ -128,7 +128,6 @@ void audio_update_volume(bool force_update)
gAudiop->setMasterGain ( master_volume );
gAudiop->setDopplerFactor(gSavedSettings.getF32("AudioLevelDoppler"));
- gAudiop->setDistanceFactor(gSavedSettings.getF32("AudioLevelDistance"));
gAudiop->setRolloffFactor(gSavedSettings.getF32("AudioLevelRolloff"));
#ifdef kAUDIO_ENABLE_WIND
gAudiop->enableWind(!mute_audio);
diff --git a/indra/newview/llviewercamera.cpp b/indra/newview/llviewercamera.cpp
index 72d1494d96..3f3c10a7c7 100644
--- a/indra/newview/llviewercamera.cpp
+++ b/indra/newview/llviewercamera.cpp
@@ -31,18 +31,12 @@
*/
#include "llviewerprecompiledheaders.h"
-#include "llviewercamera.h"
-
-#include <iomanip> // for setprecision
-#include "llquaternion.h"
+#include "llviewercamera.h"
+// Viewer includes
#include "llagent.h"
#include "llviewercontrol.h"
-#include "lldrawable.h"
-#include "llface.h"
-#include "llgl.h"
-#include "llglheaders.h"
#include "llviewerobjectlist.h"
#include "llviewerregion.h"
#include "llviewerwindow.h"
@@ -51,6 +45,17 @@
#include "lltoolmgr.h"
#include "llviewerjoystick.h"
+// Linden library includes
+#include "lldrawable.h"
+#include "llface.h"
+#include "llgl.h"
+#include "llglheaders.h"
+#include "llquaternion.h"
+#include "llwindow.h" // getPixelAspectRatio()
+
+// System includes
+#include <iomanip> // for setprecision
+
//glu pick matrix implementation borrowed from Mesa3D
glh::matrix4f gl_pick_matrix(GLfloat x, GLfloat y, GLfloat width, GLfloat height, GLint* viewport)
{
@@ -106,6 +111,7 @@ LLViewerCamera::LLViewerCamera() : LLCamera()
mScreenPixelArea = 0;
mZoomFactor = 1.f;
mZoomSubregion = 1;
+ gSavedSettings.getControl("CameraAngle")->getCommitSignal()->connect(boost::bind(&LLViewerCamera::updateCameraAngle, this, _2));
}
void LLViewerCamera::updateCameraLocation(const LLVector3 &center,
@@ -452,8 +458,15 @@ BOOL LLViewerCamera::projectPosAgentToScreen(const LLVector3 &pos_agent, LLCoord
}
}
+ LLRect world_view_rect = gViewerWindow->getWorldViewRect();
+ S32 viewport[4];
+ viewport[0] = world_view_rect.mLeft;
+ viewport[1] = world_view_rect.mBottom;
+ viewport[2] = world_view_rect.getWidth();
+ viewport[3] = world_view_rect.getHeight();
+
if (GL_TRUE == gluProject(pos_agent.mV[VX], pos_agent.mV[VY], pos_agent.mV[VZ],
- gGLModelView, gGLProjection, (GLint*)gGLViewport,
+ gGLModelView, gGLProjection, (GLint*)viewport,
&x, &y, &z))
{
// convert screen coordinates to virtual UI coordinates
@@ -461,9 +474,9 @@ BOOL LLViewerCamera::projectPosAgentToScreen(const LLVector3 &pos_agent, LLCoord
y /= gViewerWindow->getDisplayScale().mV[VY];
// should now have the x,y coords of grab_point in screen space
- const LLRect& window_rect = gViewerWindow->getWindowRect();
+ LLRect world_view_rect = gViewerWindow->getVirtualWorldViewRect();
- // ...sanity check
+ // convert to pixel coordinates
S32 int_x = lltrunc(x);
S32 int_y = lltrunc(y);
@@ -471,14 +484,14 @@ BOOL LLViewerCamera::projectPosAgentToScreen(const LLVector3 &pos_agent, LLCoord
if (clamp)
{
- if (int_x < window_rect.mLeft)
+ if (int_x < world_view_rect.mLeft)
{
- out_point.mX = window_rect.mLeft;
+ out_point.mX = world_view_rect.mLeft;
valid = FALSE;
}
- else if (int_x > window_rect.mRight)
+ else if (int_x > world_view_rect.mRight)
{
- out_point.mX = window_rect.mRight;
+ out_point.mX = world_view_rect.mRight;
valid = FALSE;
}
else
@@ -486,14 +499,14 @@ BOOL LLViewerCamera::projectPosAgentToScreen(const LLVector3 &pos_agent, LLCoord
out_point.mX = int_x;
}
- if (int_y < window_rect.mBottom)
+ if (int_y < world_view_rect.mBottom)
{
- out_point.mY = window_rect.mBottom;
+ out_point.mY = world_view_rect.mBottom;
valid = FALSE;
}
- else if (int_y > window_rect.mTop)
+ else if (int_y > world_view_rect.mTop)
{
- out_point.mY = window_rect.mTop;
+ out_point.mY = world_view_rect.mTop;
valid = FALSE;
}
else
@@ -507,19 +520,19 @@ BOOL LLViewerCamera::projectPosAgentToScreen(const LLVector3 &pos_agent, LLCoord
out_point.mX = int_x;
out_point.mY = int_y;
- if (int_x < window_rect.mLeft)
+ if (int_x < world_view_rect.mLeft)
{
valid = FALSE;
}
- else if (int_x > window_rect.mRight)
+ else if (int_x > world_view_rect.mRight)
{
valid = FALSE;
}
- if (int_y < window_rect.mBottom)
+ if (int_y < world_view_rect.mBottom)
{
valid = FALSE;
}
- else if (int_y > window_rect.mTop)
+ else if (int_y > world_view_rect.mTop)
{
valid = FALSE;
}
@@ -548,24 +561,30 @@ BOOL LLViewerCamera::projectPosAgentToScreenEdge(const LLVector3 &pos_agent,
in_front = FALSE;
}
+ LLRect world_view_rect = gViewerWindow->getWorldViewRect();
+ S32 viewport[4];
+ viewport[0] = world_view_rect.mLeft;
+ viewport[1] = world_view_rect.mBottom;
+ viewport[2] = world_view_rect.getWidth();
+ viewport[3] = world_view_rect.getHeight();
GLdouble x, y, z; // object's window coords, GL-style
if (GL_TRUE == gluProject(pos_agent.mV[VX], pos_agent.mV[VY],
pos_agent.mV[VZ], gGLModelView,
- gGLProjection, (GLint*)gGLViewport,
+ gGLProjection, (GLint*)viewport,
&x, &y, &z))
{
x /= gViewerWindow->getDisplayScale().mV[VX];
y /= gViewerWindow->getDisplayScale().mV[VY];
// should now have the x,y coords of grab_point in screen space
- const LLRect& window_rect = gViewerWindow->getVirtualWindowRect();
+ const LLRect& world_rect = gViewerWindow->getVirtualWorldViewRect();
// ...sanity check
S32 int_x = lltrunc(x);
S32 int_y = lltrunc(y);
// find the center
- GLdouble center_x = (GLdouble)(0.5f * (window_rect.mLeft + window_rect.mRight));
- GLdouble center_y = (GLdouble)(0.5f * (window_rect.mBottom + window_rect.mTop));
+ GLdouble center_x = (GLdouble)world_rect.getCenterX();
+ GLdouble center_y = (GLdouble)world_rect.getCenterY();
if (x == center_x && y == center_y)
{
@@ -586,41 +605,41 @@ BOOL LLViewerCamera::projectPosAgentToScreenEdge(const LLVector3 &pos_agent,
// the slope of the line is undefined
if (line_y > 0.f)
{
- int_y = window_rect.mTop;
+ int_y = world_rect.mTop;
}
else
{
- int_y = window_rect.mBottom;
+ int_y = world_rect.mBottom;
}
}
- else if (0 == window_rect.getWidth())
+ else if (0 == world_rect.getWidth())
{
// the diagonal slope of the view is undefined
- if (y < window_rect.mBottom)
+ if (y < world_rect.mBottom)
{
- int_y = window_rect.mBottom;
+ int_y = world_rect.mBottom;
}
- else if ( y > window_rect.mTop)
+ else if ( y > world_rect.mTop)
{
- int_y = window_rect.mTop;
+ int_y = world_rect.mTop;
}
}
else
{
F32 line_slope = (F32)(line_y / line_x);
- F32 rect_slope = ((F32)window_rect.getHeight()) / ((F32)window_rect.getWidth());
+ F32 rect_slope = ((F32)world_rect.getHeight()) / ((F32)world_rect.getWidth());
if (fabs(line_slope) > rect_slope)
{
if (line_y < 0.f)
{
// bottom
- int_y = window_rect.mBottom;
+ int_y = world_rect.mBottom;
}
else
{
// top
- int_y = window_rect.mTop;
+ int_y = world_rect.mTop;
}
int_x = lltrunc(((GLdouble)int_y - center_y) / line_slope + center_x);
}
@@ -629,12 +648,12 @@ BOOL LLViewerCamera::projectPosAgentToScreenEdge(const LLVector3 &pos_agent,
if (line_x < 0.f)
{
// left
- int_x = window_rect.mLeft;
+ int_x = world_rect.mLeft;
}
else
{
// right
- int_x = window_rect.mRight;
+ int_x = world_rect.mRight;
}
int_y = lltrunc(((GLdouble)int_x - center_x) * line_slope + center_y);
}
@@ -643,29 +662,30 @@ BOOL LLViewerCamera::projectPosAgentToScreenEdge(const LLVector3 &pos_agent,
// exactly parallel ==> push to the corners
if (line_x > 0.f)
{
- int_x = window_rect.mRight;
+ int_x = world_rect.mRight;
}
else
{
- int_x = window_rect.mLeft;
+ int_x = world_rect.mLeft;
}
if (line_y > 0.0f)
{
- int_y = window_rect.mTop;
+ int_y = world_rect.mTop;
}
else
{
- int_y = window_rect.mBottom;
+ int_y = world_rect.mBottom;
}
}
}
if (!in_front)
{
- int_x = window_rect.mLeft + window_rect.mRight - int_x;
- int_y = window_rect.mBottom + window_rect.mTop - int_y;
+ int_x = world_rect.mLeft + world_rect.mRight - int_x;
+ int_y = world_rect.mBottom + world_rect.mTop - int_y;
}
- out_point.mX = int_x;
- out_point.mY = int_y;
+
+ out_point.mX = int_x + world_rect.mLeft;
+ out_point.mY = int_y + world_rect.mBottom;
return TRUE;
}
return FALSE;
@@ -803,3 +823,11 @@ void LLViewerCamera::setDefaultFOV(F32 vertical_fov_rads) {
mCameraFOVDefault = vertical_fov_rads;
}
+
+// static
+void LLViewerCamera::updateCameraAngle( void* user_data, const LLSD& value)
+{
+ LLViewerCamera* self=(LLViewerCamera*)user_data;
+ self->setDefaultFOV(value.asReal());
+}
+
diff --git a/indra/newview/llviewercamera.h b/indra/newview/llviewercamera.h
index 6a0c42beec..b99dd39584 100644
--- a/indra/newview/llviewercamera.h
+++ b/indra/newview/llviewercamera.h
@@ -34,8 +34,9 @@
#define LL_LLVIEWERCAMERA_H
#include "llcamera.h"
-#include "lltimer.h"
+#include "llsingleton.h"
#include "llstat.h"
+#include "lltimer.h"
#include "m4math.h"
class LLCoordGL;
@@ -61,6 +62,7 @@ public:
const LLVector3 &point_of_interest);
static void updateFrustumPlanes(LLCamera& camera, BOOL ortho = FALSE, BOOL zflip = FALSE, BOOL no_hacks = FALSE);
+ static void updateCameraAngle(void* user_data, const LLSD& value);
void setPerspective(BOOL for_selection, S32 x, S32 y_from_bot, S32 width, S32 height, BOOL limit_select_distance, F32 z_near = 0, F32 z_far = 0);
const LLMatrix4 &getProjection() const;
diff --git a/indra/newview/llviewercontrol.cpp b/indra/newview/llviewercontrol.cpp
index eb8cdd82b3..2c1707e49f 100644
--- a/indra/newview/llviewercontrol.cpp
+++ b/indra/newview/llviewercontrol.cpp
@@ -35,24 +35,25 @@
#include "llviewercontrol.h"
-#include "indra_constants.h"
+// Library includes
+#include "llwindow.h" // getGamma()
// For Listeners
-#include "audioengine.h"
+#include "llaudioengine.h"
#include "llagent.h"
#include "llconsole.h"
#include "lldrawpoolterrain.h"
#include "llflexibleobject.h"
#include "llfeaturemanager.h"
#include "llviewershadermgr.h"
-#include "llpanelgeneral.h"
-#include "llpanelinput.h"
+
#include "llsky.h"
#include "llvieweraudio.h"
-#include "llviewerimagelist.h"
+#include "llviewermenu.h"
+#include "llviewertexturelist.h"
#include "llviewerthrottle.h"
#include "llviewerwindow.h"
-#include "llvoavatar.h"
+#include "llvoavatarself.h"
#include "llvoiceclient.h"
#include "llvosky.h"
#include "llvotree.h"
@@ -77,11 +78,10 @@ BOOL gHackGodmode = FALSE;
#endif
-std::map<std::string, LLControlGroup*> gSettings;
-LLControlGroup gSavedSettings; // saved at end of session
-LLControlGroup gSavedPerAccountSettings; // saved at end of session
-LLControlGroup gColors; // read-only
-LLControlGroup gCrashSettings; // saved at end of session
+LLControlGroup gSavedSettings("Global"); // saved at end of session
+LLControlGroup gSavedPerAccountSettings("PerAccount"); // saved at end of session
+LLControlGroup gCrashSettings("CrashSettings"); // saved at end of session
+LLControlGroup gWarningSettings("Warnings"); // persists ignored dialogs/warnings
std::string gLastRunVersion;
std::string gCurrentVersion;
@@ -121,7 +121,7 @@ static bool handleSetShaderChanged(const LLSD& newvalue)
static bool handleSetSelfInvisible( const LLSD& newvalue)
{
- LLVOAvatar::onChangeSelfInvisible( newvalue.asBoolean() );
+ LLVOAvatarSelf::onChangeSelfInvisible( newvalue.asBoolean() );
return true;
}
@@ -213,7 +213,7 @@ static bool handleMaxPartCountChanged(const LLSD& newvalue)
static bool handleVideoMemoryChanged(const LLSD& newvalue)
{
- gImageList.updateMaxResidentTexMem(newvalue.asInteger());
+ gTextureList.updateMaxResidentTexMem(newvalue.asInteger());
return true;
}
@@ -378,7 +378,7 @@ static bool handleRenderUseImpostorsChanged(const LLSD& newvalue)
static bool handleRenderDebugGLChanged(const LLSD& newvalue)
{
- gDebugGL = newvalue.asBoolean();
+ gDebugGL = newvalue.asBoolean() || gDebugSession;
gGL.clearErrors();
return true;
}
@@ -427,6 +427,16 @@ bool handleVectorizeChanged(const LLSD& newvalue)
return true;
}
+bool handleHighResSnapshotChanged(const LLSD& newvalue)
+{
+ // High Res Snapshot active, must uncheck RenderUIInSnapshot
+ if (newvalue.asBoolean())
+ {
+ gSavedSettings.setBOOL( "RenderUIInSnapshot", FALSE );
+ }
+ return true;
+}
+
bool handleVoiceClientPrefsChanged(const LLSD& newvalue)
{
if(gVoiceClient)
@@ -436,217 +446,163 @@ bool handleVoiceClientPrefsChanged(const LLSD& newvalue)
return true;
}
+bool handleVelocityInterpolate(const LLSD& newvalue)
+{
+ LLMessageSystem* msg = gMessageSystem;
+ if ( newvalue.asBoolean() )
+ {
+ msg->newMessageFast(_PREHASH_VelocityInterpolateOn);
+ msg->nextBlockFast(_PREHASH_AgentData);
+ msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
+ msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
+ gAgent.sendReliableMessage();
+ llinfos << "Velocity Interpolation On" << llendl;
+ }
+ else
+ {
+ msg->newMessageFast(_PREHASH_VelocityInterpolateOff);
+ msg->nextBlockFast(_PREHASH_AgentData);
+ msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
+ msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
+ gAgent.sendReliableMessage();
+ llinfos << "Velocity Interpolation Off" << llendl;
+ }
+ return true;
+}
+
////////////////////////////////////////////////////////////////////////////
void settings_setup_listeners()
{
- gSavedSettings.getControl("FirstPersonAvatarVisible")->getSignal()->connect(boost::bind(&handleRenderAvatarMouselookChanged, _1));
- gSavedSettings.getControl("RenderFarClip")->getSignal()->connect(boost::bind(&handleRenderFarClipChanged, _1));
- gSavedSettings.getControl("RenderTerrainDetail")->getSignal()->connect(boost::bind(&handleTerrainDetailChanged, _1));
- gSavedSettings.getControl("RenderAnimateTrees")->getSignal()->connect(boost::bind(&handleResetVertexBuffersChanged, _1));
- gSavedSettings.getControl("RenderAvatarVP")->getSignal()->connect(boost::bind(&handleSetShaderChanged, _1));
- gSavedSettings.getControl("VertexShaderEnable")->getSignal()->connect(boost::bind(&handleSetShaderChanged, _1));
- gSavedSettings.getControl("RenderGlow")->getSignal()->connect(boost::bind(&handleReleaseGLBufferChanged, _1));
- gSavedSettings.getControl("RenderGlow")->getSignal()->connect(boost::bind(&handleSetShaderChanged, _1));
- gSavedSettings.getControl("EnableRippleWater")->getSignal()->connect(boost::bind(&handleSetShaderChanged, _1));
- gSavedSettings.getControl("RenderGlowResolutionPow")->getSignal()->connect(boost::bind(&handleReleaseGLBufferChanged, _1));
- gSavedSettings.getControl("RenderAvatarCloth")->getSignal()->connect(boost::bind(&handleSetShaderChanged, _1));
- gSavedSettings.getControl("WindLightUseAtmosShaders")->getSignal()->connect(boost::bind(&handleSetShaderChanged, _1));
- gSavedSettings.getControl("RenderGammaFull")->getSignal()->connect(boost::bind(&handleSetShaderChanged, _1));
- gSavedSettings.getControl("RenderAvatarMaxVisible")->getSignal()->connect(boost::bind(&handleAvatarMaxVisibleChanged, _1));
- gSavedSettings.getControl("RenderAvatarInvisible")->getSignal()->connect(boost::bind(&handleSetSelfInvisible, _1));
- gSavedSettings.getControl("RenderVolumeLODFactor")->getSignal()->connect(boost::bind(&handleVolumeLODChanged, _1));
- gSavedSettings.getControl("RenderAvatarLODFactor")->getSignal()->connect(boost::bind(&handleAvatarLODChanged, _1));
- gSavedSettings.getControl("RenderTerrainLODFactor")->getSignal()->connect(boost::bind(&handleTerrainLODChanged, _1));
- gSavedSettings.getControl("RenderTreeLODFactor")->getSignal()->connect(boost::bind(&handleTreeLODChanged, _1));
- gSavedSettings.getControl("RenderFlexTimeFactor")->getSignal()->connect(boost::bind(&handleFlexLODChanged, _1));
- gSavedSettings.getControl("ThrottleBandwidthKBPS")->getSignal()->connect(boost::bind(&handleBandwidthChanged, _1));
- gSavedSettings.getControl("RenderGamma")->getSignal()->connect(boost::bind(&handleGammaChanged, _1));
- gSavedSettings.getControl("RenderFogRatio")->getSignal()->connect(boost::bind(&handleFogRatioChanged, _1));
- gSavedSettings.getControl("RenderMaxPartCount")->getSignal()->connect(boost::bind(&handleMaxPartCountChanged, _1));
- gSavedSettings.getControl("RenderDynamicLOD")->getSignal()->connect(boost::bind(&handleRenderDynamicLODChanged, _1));
- gSavedSettings.getControl("RenderDebugTextureBind")->getSignal()->connect(boost::bind(&handleResetVertexBuffersChanged, _1));
- gSavedSettings.getControl("RenderFastAlpha")->getSignal()->connect(boost::bind(&handleResetVertexBuffersChanged, _1));
- gSavedSettings.getControl("RenderObjectBump")->getSignal()->connect(boost::bind(&handleResetVertexBuffersChanged, _1));
- gSavedSettings.getControl("RenderMaxVBOSize")->getSignal()->connect(boost::bind(&handleResetVertexBuffersChanged, _1));
- gSavedSettings.getControl("RenderUseFBO")->getSignal()->connect(boost::bind(&handleRenderUseFBOChanged, _1));
- gSavedSettings.getControl("RenderDeferredNoise")->getSignal()->connect(boost::bind(&handleReleaseGLBufferChanged, _1));
- gSavedSettings.getControl("RenderUseImpostors")->getSignal()->connect(boost::bind(&handleRenderUseImpostorsChanged, _1));
- gSavedSettings.getControl("RenderDebugGL")->getSignal()->connect(boost::bind(&handleRenderDebugGLChanged, _1));
- gSavedSettings.getControl("RenderDebugPipeline")->getSignal()->connect(boost::bind(&handleRenderDebugPipelineChanged, _1));
- gSavedSettings.getControl("RenderResolutionDivisor")->getSignal()->connect(boost::bind(&handleRenderResolutionDivisorChanged, _1));
- gSavedSettings.getControl("RenderDeferred")->getSignal()->connect(boost::bind(&handleSetShaderChanged, _1));
- gSavedSettings.getControl("TextureMemory")->getSignal()->connect(boost::bind(&handleVideoMemoryChanged, _1));
- gSavedSettings.getControl("ChatFontSize")->getSignal()->connect(boost::bind(&handleChatFontSizeChanged, _1));
- gSavedSettings.getControl("ChatPersistTime")->getSignal()->connect(boost::bind(&handleChatPersistTimeChanged, _1));
- gSavedSettings.getControl("ConsoleMaxLines")->getSignal()->connect(boost::bind(&handleConsoleMaxLinesChanged, _1));
- gSavedSettings.getControl("UploadBakedTexOld")->getSignal()->connect(boost::bind(&handleUploadBakedTexOldChanged, _1));
- gSavedSettings.getControl("UseOcclusion")->getSignal()->connect(boost::bind(&handleUseOcclusionChanged, _1));
- gSavedSettings.getControl("AudioLevelMaster")->getSignal()->connect(boost::bind(&handleAudioVolumeChanged, _1));
- gSavedSettings.getControl("AudioLevelSFX")->getSignal()->connect(boost::bind(&handleAudioVolumeChanged, _1));
- gSavedSettings.getControl("AudioLevelUI")->getSignal()->connect(boost::bind(&handleAudioVolumeChanged, _1));
- gSavedSettings.getControl("AudioLevelAmbient")->getSignal()->connect(boost::bind(&handleAudioVolumeChanged, _1));
- gSavedSettings.getControl("AudioLevelMusic")->getSignal()->connect(boost::bind(&handleAudioVolumeChanged, _1));
- gSavedSettings.getControl("AudioLevelMedia")->getSignal()->connect(boost::bind(&handleAudioVolumeChanged, _1));
- gSavedSettings.getControl("AudioLevelVoice")->getSignal()->connect(boost::bind(&handleAudioVolumeChanged, _1));
- gSavedSettings.getControl("AudioLevelDistance")->getSignal()->connect(boost::bind(&handleAudioVolumeChanged, _1));
- gSavedSettings.getControl("AudioLevelDoppler")->getSignal()->connect(boost::bind(&handleAudioVolumeChanged, _1));
- gSavedSettings.getControl("AudioLevelRolloff")->getSignal()->connect(boost::bind(&handleAudioVolumeChanged, _1));
- gSavedSettings.getControl("AudioStreamingMusic")->getSignal()->connect(boost::bind(&handleAudioStreamMusicChanged, _1));
- gSavedSettings.getControl("MuteAudio")->getSignal()->connect(boost::bind(&handleAudioVolumeChanged, _1));
- gSavedSettings.getControl("MuteMusic")->getSignal()->connect(boost::bind(&handleAudioVolumeChanged, _1));
- gSavedSettings.getControl("MuteMedia")->getSignal()->connect(boost::bind(&handleAudioVolumeChanged, _1));
- gSavedSettings.getControl("MuteVoice")->getSignal()->connect(boost::bind(&handleAudioVolumeChanged, _1));
- gSavedSettings.getControl("MuteAmbient")->getSignal()->connect(boost::bind(&handleAudioVolumeChanged, _1));
- gSavedSettings.getControl("MuteUI")->getSignal()->connect(boost::bind(&handleAudioVolumeChanged, _1));
- gSavedSettings.getControl("RenderVBOEnable")->getSignal()->connect(boost::bind(&handleRenderUseVBOChanged, _1));
- gSavedSettings.getControl("WLSkyDetail")->getSignal()->connect(boost::bind(&handleWLSkyDetailChanged, _1));
- gSavedSettings.getControl("RenderLightingDetail")->getSignal()->connect(boost::bind(&handleRenderLightingDetailChanged, _1));
- gSavedSettings.getControl("NumpadControl")->getSignal()->connect(boost::bind(&handleNumpadControlChanged, _1));
- gSavedSettings.getControl("JoystickAxis0")->getSignal()->connect(boost::bind(&handleJoystickChanged, _1));
- gSavedSettings.getControl("JoystickAxis1")->getSignal()->connect(boost::bind(&handleJoystickChanged, _1));
- gSavedSettings.getControl("JoystickAxis2")->getSignal()->connect(boost::bind(&handleJoystickChanged, _1));
- gSavedSettings.getControl("JoystickAxis3")->getSignal()->connect(boost::bind(&handleJoystickChanged, _1));
- gSavedSettings.getControl("JoystickAxis4")->getSignal()->connect(boost::bind(&handleJoystickChanged, _1));
- gSavedSettings.getControl("JoystickAxis5")->getSignal()->connect(boost::bind(&handleJoystickChanged, _1));
- gSavedSettings.getControl("JoystickAxis6")->getSignal()->connect(boost::bind(&handleJoystickChanged, _1));
- gSavedSettings.getControl("FlycamAxisScale0")->getSignal()->connect(boost::bind(&handleJoystickChanged, _1));
- gSavedSettings.getControl("FlycamAxisScale1")->getSignal()->connect(boost::bind(&handleJoystickChanged, _1));
- gSavedSettings.getControl("FlycamAxisScale2")->getSignal()->connect(boost::bind(&handleJoystickChanged, _1));
- gSavedSettings.getControl("FlycamAxisScale3")->getSignal()->connect(boost::bind(&handleJoystickChanged, _1));
- gSavedSettings.getControl("FlycamAxisScale4")->getSignal()->connect(boost::bind(&handleJoystickChanged, _1));
- gSavedSettings.getControl("FlycamAxisScale5")->getSignal()->connect(boost::bind(&handleJoystickChanged, _1));
- gSavedSettings.getControl("FlycamAxisScale6")->getSignal()->connect(boost::bind(&handleJoystickChanged, _1));
- gSavedSettings.getControl("FlycamAxisDeadZone0")->getSignal()->connect(boost::bind(&handleJoystickChanged, _1));
- gSavedSettings.getControl("FlycamAxisDeadZone1")->getSignal()->connect(boost::bind(&handleJoystickChanged, _1));
- gSavedSettings.getControl("FlycamAxisDeadZone2")->getSignal()->connect(boost::bind(&handleJoystickChanged, _1));
- gSavedSettings.getControl("FlycamAxisDeadZone3")->getSignal()->connect(boost::bind(&handleJoystickChanged, _1));
- gSavedSettings.getControl("FlycamAxisDeadZone4")->getSignal()->connect(boost::bind(&handleJoystickChanged, _1));
- gSavedSettings.getControl("FlycamAxisDeadZone5")->getSignal()->connect(boost::bind(&handleJoystickChanged, _1));
- gSavedSettings.getControl("FlycamAxisDeadZone6")->getSignal()->connect(boost::bind(&handleJoystickChanged, _1));
- gSavedSettings.getControl("AvatarAxisScale0")->getSignal()->connect(boost::bind(&handleJoystickChanged, _1));
- gSavedSettings.getControl("AvatarAxisScale1")->getSignal()->connect(boost::bind(&handleJoystickChanged, _1));
- gSavedSettings.getControl("AvatarAxisScale2")->getSignal()->connect(boost::bind(&handleJoystickChanged, _1));
- gSavedSettings.getControl("AvatarAxisScale3")->getSignal()->connect(boost::bind(&handleJoystickChanged, _1));
- gSavedSettings.getControl("AvatarAxisScale4")->getSignal()->connect(boost::bind(&handleJoystickChanged, _1));
- gSavedSettings.getControl("AvatarAxisScale5")->getSignal()->connect(boost::bind(&handleJoystickChanged, _1));
- gSavedSettings.getControl("AvatarAxisDeadZone0")->getSignal()->connect(boost::bind(&handleJoystickChanged, _1));
- gSavedSettings.getControl("AvatarAxisDeadZone1")->getSignal()->connect(boost::bind(&handleJoystickChanged, _1));
- gSavedSettings.getControl("AvatarAxisDeadZone2")->getSignal()->connect(boost::bind(&handleJoystickChanged, _1));
- gSavedSettings.getControl("AvatarAxisDeadZone3")->getSignal()->connect(boost::bind(&handleJoystickChanged, _1));
- gSavedSettings.getControl("AvatarAxisDeadZone4")->getSignal()->connect(boost::bind(&handleJoystickChanged, _1));
- gSavedSettings.getControl("AvatarAxisDeadZone5")->getSignal()->connect(boost::bind(&handleJoystickChanged, _1));
- gSavedSettings.getControl("BuildAxisScale0")->getSignal()->connect(boost::bind(&handleJoystickChanged, _1));
- gSavedSettings.getControl("BuildAxisScale1")->getSignal()->connect(boost::bind(&handleJoystickChanged, _1));
- gSavedSettings.getControl("BuildAxisScale2")->getSignal()->connect(boost::bind(&handleJoystickChanged, _1));
- gSavedSettings.getControl("BuildAxisScale3")->getSignal()->connect(boost::bind(&handleJoystickChanged, _1));
- gSavedSettings.getControl("BuildAxisScale4")->getSignal()->connect(boost::bind(&handleJoystickChanged, _1));
- gSavedSettings.getControl("BuildAxisScale5")->getSignal()->connect(boost::bind(&handleJoystickChanged, _1));
- gSavedSettings.getControl("BuildAxisDeadZone0")->getSignal()->connect(boost::bind(&handleJoystickChanged, _1));
- gSavedSettings.getControl("BuildAxisDeadZone1")->getSignal()->connect(boost::bind(&handleJoystickChanged, _1));
- gSavedSettings.getControl("BuildAxisDeadZone2")->getSignal()->connect(boost::bind(&handleJoystickChanged, _1));
- gSavedSettings.getControl("BuildAxisDeadZone3")->getSignal()->connect(boost::bind(&handleJoystickChanged, _1));
- gSavedSettings.getControl("BuildAxisDeadZone4")->getSignal()->connect(boost::bind(&handleJoystickChanged, _1));
- gSavedSettings.getControl("BuildAxisDeadZone5")->getSignal()->connect(boost::bind(&handleJoystickChanged, _1));
- gSavedSettings.getControl("DebugViews")->getSignal()->connect(boost::bind(&handleDebugViewsChanged, _1));
- gSavedSettings.getControl("UserLogFile")->getSignal()->connect(boost::bind(&handleLogFileChanged, _1));
- gSavedSettings.getControl("RenderHideGroupTitle")->getSignal()->connect(boost::bind(handleHideGroupTitleChanged, _1));
- gSavedSettings.getControl("EffectColor")->getSignal()->connect(boost::bind(handleEffectColorChanged, _1));
- gSavedSettings.getControl("VectorizePerfTest")->getSignal()->connect(boost::bind(&handleVectorizeChanged, _1));
- gSavedSettings.getControl("VectorizeEnable")->getSignal()->connect(boost::bind(&handleVectorizeChanged, _1));
- gSavedSettings.getControl("VectorizeProcessor")->getSignal()->connect(boost::bind(&handleVectorizeChanged, _1));
- gSavedSettings.getControl("VectorizeSkin")->getSignal()->connect(boost::bind(&handleVectorizeChanged, _1));
- gSavedSettings.getControl("EnableVoiceChat")->getSignal()->connect(boost::bind(&handleVoiceClientPrefsChanged, _1));
- gSavedSettings.getControl("PTTCurrentlyEnabled")->getSignal()->connect(boost::bind(&handleVoiceClientPrefsChanged, _1));
- gSavedSettings.getControl("PushToTalkButton")->getSignal()->connect(boost::bind(&handleVoiceClientPrefsChanged, _1));
- gSavedSettings.getControl("PushToTalkToggle")->getSignal()->connect(boost::bind(&handleVoiceClientPrefsChanged, _1));
- gSavedSettings.getControl("VoiceEarLocation")->getSignal()->connect(boost::bind(&handleVoiceClientPrefsChanged, _1));
- gSavedSettings.getControl("VoiceInputAudioDevice")->getSignal()->connect(boost::bind(&handleVoiceClientPrefsChanged, _1));
- gSavedSettings.getControl("VoiceOutputAudioDevice")->getSignal()->connect(boost::bind(&handleVoiceClientPrefsChanged, _1));
- gSavedSettings.getControl("AudioLevelMic")->getSignal()->connect(boost::bind(&handleVoiceClientPrefsChanged, _1));
- gSavedSettings.getControl("LipSyncEnabled")->getSignal()->connect(boost::bind(&handleVoiceClientPrefsChanged, _1));
-}
-
-template <> eControlType get_control_type<U32>(const U32& in, LLSD& out)
-{
- out = (LLSD::Integer)in;
- return TYPE_U32;
-}
-
-template <> eControlType get_control_type<S32>(const S32& in, LLSD& out)
-{
- out = in;
- return TYPE_S32;
-}
-
-template <> eControlType get_control_type<F32>(const F32& in, LLSD& out)
-{
- out = in;
- return TYPE_F32;
-}
-
-template <> eControlType get_control_type<bool> (const bool& in, LLSD& out)
-{
- out = in;
- return TYPE_BOOLEAN;
-}
-/*
-// Yay BOOL, its really an S32.
-template <> eControlType get_control_type<BOOL> (const BOOL& in, LLSD& out)
-{
- out = in;
- return TYPE_BOOLEAN;
-}
-*/
-template <> eControlType get_control_type<std::string>(const std::string& in, LLSD& out)
-{
- out = in;
- return TYPE_STRING;
-}
-
-template <> eControlType get_control_type<LLVector3>(const LLVector3& in, LLSD& out)
-{
- out = in.getValue();
- return TYPE_VEC3;
-}
-
-template <> eControlType get_control_type<LLVector3d>(const LLVector3d& in, LLSD& out)
-{
- out = in.getValue();
- return TYPE_VEC3D;
-}
-
-template <> eControlType get_control_type<LLRect>(const LLRect& in, LLSD& out)
-{
- out = in.getValue();
- return TYPE_RECT;
-}
-
-template <> eControlType get_control_type<LLColor4>(const LLColor4& in, LLSD& out)
-{
- out = in.getValue();
- return TYPE_COL4;
-}
-
-template <> eControlType get_control_type<LLColor3>(const LLColor3& in, LLSD& out)
-{
- out = in.getValue();
- return TYPE_COL3;
-}
-
-template <> eControlType get_control_type<LLColor4U>(const LLColor4U& in, LLSD& out)
-{
- out = in.getValue();
- return TYPE_COL4U;
-}
-
-template <> eControlType get_control_type<LLSD>(const LLSD& in, LLSD& out)
-{
- out = in;
- return TYPE_LLSD;
+ gSavedSettings.getControl("FirstPersonAvatarVisible")->getSignal()->connect(boost::bind(&handleRenderAvatarMouselookChanged, _2));
+ gSavedSettings.getControl("RenderFarClip")->getSignal()->connect(boost::bind(&handleRenderFarClipChanged, _2));
+ gSavedSettings.getControl("RenderTerrainDetail")->getSignal()->connect(boost::bind(&handleTerrainDetailChanged, _2));
+ gSavedSettings.getControl("RenderAnimateTrees")->getSignal()->connect(boost::bind(&handleResetVertexBuffersChanged, _2));
+ gSavedSettings.getControl("RenderAvatarVP")->getSignal()->connect(boost::bind(&handleSetShaderChanged, _2));
+ gSavedSettings.getControl("VertexShaderEnable")->getSignal()->connect(boost::bind(&handleSetShaderChanged, _2));
+ gSavedSettings.getControl("RenderGlow")->getSignal()->connect(boost::bind(&handleReleaseGLBufferChanged, _2));
+ gSavedSettings.getControl("RenderGlow")->getSignal()->connect(boost::bind(&handleSetShaderChanged, _2));
+ gSavedSettings.getControl("EnableRippleWater")->getSignal()->connect(boost::bind(&handleSetShaderChanged, _2));
+ gSavedSettings.getControl("RenderGlowResolutionPow")->getSignal()->connect(boost::bind(&handleReleaseGLBufferChanged, _2));
+ gSavedSettings.getControl("RenderAvatarCloth")->getSignal()->connect(boost::bind(&handleSetShaderChanged, _2));
+ gSavedSettings.getControl("WindLightUseAtmosShaders")->getSignal()->connect(boost::bind(&handleSetShaderChanged, _2));
+ gSavedSettings.getControl("RenderGammaFull")->getSignal()->connect(boost::bind(&handleSetShaderChanged, _2));
+ gSavedSettings.getControl("RenderAvatarMaxVisible")->getSignal()->connect(boost::bind(&handleAvatarMaxVisibleChanged, _2));
+ gSavedSettings.getControl("RenderAvatarInvisible")->getSignal()->connect(boost::bind(&handleSetSelfInvisible, _2));
+ gSavedSettings.getControl("RenderVolumeLODFactor")->getSignal()->connect(boost::bind(&handleVolumeLODChanged, _2));
+ gSavedSettings.getControl("RenderAvatarLODFactor")->getSignal()->connect(boost::bind(&handleAvatarLODChanged, _2));
+ gSavedSettings.getControl("RenderTerrainLODFactor")->getSignal()->connect(boost::bind(&handleTerrainLODChanged, _2));
+ gSavedSettings.getControl("RenderTreeLODFactor")->getSignal()->connect(boost::bind(&handleTreeLODChanged, _2));
+ gSavedSettings.getControl("RenderFlexTimeFactor")->getSignal()->connect(boost::bind(&handleFlexLODChanged, _2));
+ gSavedSettings.getControl("ThrottleBandwidthKBPS")->getSignal()->connect(boost::bind(&handleBandwidthChanged, _2));
+ gSavedSettings.getControl("RenderGamma")->getSignal()->connect(boost::bind(&handleGammaChanged, _2));
+ gSavedSettings.getControl("RenderFogRatio")->getSignal()->connect(boost::bind(&handleFogRatioChanged, _2));
+ gSavedSettings.getControl("RenderMaxPartCount")->getSignal()->connect(boost::bind(&handleMaxPartCountChanged, _2));
+ gSavedSettings.getControl("RenderDynamicLOD")->getSignal()->connect(boost::bind(&handleRenderDynamicLODChanged, _2));
+ gSavedSettings.getControl("RenderDebugTextureBind")->getSignal()->connect(boost::bind(&handleResetVertexBuffersChanged, _2));
+ gSavedSettings.getControl("RenderFastAlpha")->getSignal()->connect(boost::bind(&handleResetVertexBuffersChanged, _2));
+ gSavedSettings.getControl("RenderObjectBump")->getSignal()->connect(boost::bind(&handleResetVertexBuffersChanged, _2));
+ gSavedSettings.getControl("RenderMaxVBOSize")->getSignal()->connect(boost::bind(&handleResetVertexBuffersChanged, _2));
+ gSavedSettings.getControl("RenderUseFBO")->getSignal()->connect(boost::bind(&handleRenderUseFBOChanged, _2));
+ gSavedSettings.getControl("RenderDeferredNoise")->getSignal()->connect(boost::bind(&handleReleaseGLBufferChanged, _2));
+ gSavedSettings.getControl("RenderUseImpostors")->getSignal()->connect(boost::bind(&handleRenderUseImpostorsChanged, _2));
+ gSavedSettings.getControl("RenderDebugGL")->getSignal()->connect(boost::bind(&handleRenderDebugGLChanged, _2));
+ gSavedSettings.getControl("RenderDebugPipeline")->getSignal()->connect(boost::bind(&handleRenderDebugPipelineChanged, _2));
+ gSavedSettings.getControl("RenderResolutionDivisor")->getSignal()->connect(boost::bind(&handleRenderResolutionDivisorChanged, _2));
+ gSavedSettings.getControl("RenderDeferred")->getSignal()->connect(boost::bind(&handleSetShaderChanged, _2));
+ gSavedSettings.getControl("TextureMemory")->getSignal()->connect(boost::bind(&handleVideoMemoryChanged, _2));
+ gSavedSettings.getControl("ChatFontSize")->getSignal()->connect(boost::bind(&handleChatFontSizeChanged, _2));
+ gSavedSettings.getControl("ChatPersistTime")->getSignal()->connect(boost::bind(&handleChatPersistTimeChanged, _2));
+ gSavedSettings.getControl("ConsoleMaxLines")->getSignal()->connect(boost::bind(&handleConsoleMaxLinesChanged, _2));
+ gSavedSettings.getControl("UploadBakedTexOld")->getSignal()->connect(boost::bind(&handleUploadBakedTexOldChanged, _2));
+ gSavedSettings.getControl("UseOcclusion")->getSignal()->connect(boost::bind(&handleUseOcclusionChanged, _2));
+ gSavedSettings.getControl("AudioLevelMaster")->getSignal()->connect(boost::bind(&handleAudioVolumeChanged, _2));
+ gSavedSettings.getControl("AudioLevelSFX")->getSignal()->connect(boost::bind(&handleAudioVolumeChanged, _2));
+ gSavedSettings.getControl("AudioLevelUI")->getSignal()->connect(boost::bind(&handleAudioVolumeChanged, _2));
+ gSavedSettings.getControl("AudioLevelAmbient")->getSignal()->connect(boost::bind(&handleAudioVolumeChanged, _2));
+ gSavedSettings.getControl("AudioLevelMusic")->getSignal()->connect(boost::bind(&handleAudioVolumeChanged, _2));
+ gSavedSettings.getControl("AudioLevelMedia")->getSignal()->connect(boost::bind(&handleAudioVolumeChanged, _2));
+ gSavedSettings.getControl("AudioLevelVoice")->getSignal()->connect(boost::bind(&handleAudioVolumeChanged, _2));
+ gSavedSettings.getControl("AudioLevelDoppler")->getSignal()->connect(boost::bind(&handleAudioVolumeChanged, _2));
+ gSavedSettings.getControl("AudioLevelRolloff")->getSignal()->connect(boost::bind(&handleAudioVolumeChanged, _2));
+ gSavedSettings.getControl("AudioStreamingMusic")->getSignal()->connect(boost::bind(&handleAudioStreamMusicChanged, _2));
+ gSavedSettings.getControl("MuteAudio")->getSignal()->connect(boost::bind(&handleAudioVolumeChanged, _2));
+ gSavedSettings.getControl("MuteMusic")->getSignal()->connect(boost::bind(&handleAudioVolumeChanged, _2));
+ gSavedSettings.getControl("MuteMedia")->getSignal()->connect(boost::bind(&handleAudioVolumeChanged, _2));
+ gSavedSettings.getControl("MuteVoice")->getSignal()->connect(boost::bind(&handleAudioVolumeChanged, _2));
+ gSavedSettings.getControl("MuteAmbient")->getSignal()->connect(boost::bind(&handleAudioVolumeChanged, _2));
+ gSavedSettings.getControl("MuteUI")->getSignal()->connect(boost::bind(&handleAudioVolumeChanged, _2));
+ gSavedSettings.getControl("RenderVBOEnable")->getSignal()->connect(boost::bind(&handleRenderUseVBOChanged, _2));
+ gSavedSettings.getControl("WLSkyDetail")->getSignal()->connect(boost::bind(&handleWLSkyDetailChanged, _2));
+ gSavedSettings.getControl("RenderLightingDetail")->getSignal()->connect(boost::bind(&handleRenderLightingDetailChanged, _2));
+ gSavedSettings.getControl("NumpadControl")->getSignal()->connect(boost::bind(&handleNumpadControlChanged, _2));
+ gSavedSettings.getControl("JoystickAxis0")->getSignal()->connect(boost::bind(&handleJoystickChanged, _2));
+ gSavedSettings.getControl("JoystickAxis1")->getSignal()->connect(boost::bind(&handleJoystickChanged, _2));
+ gSavedSettings.getControl("JoystickAxis2")->getSignal()->connect(boost::bind(&handleJoystickChanged, _2));
+ gSavedSettings.getControl("JoystickAxis3")->getSignal()->connect(boost::bind(&handleJoystickChanged, _2));
+ gSavedSettings.getControl("JoystickAxis4")->getSignal()->connect(boost::bind(&handleJoystickChanged, _2));
+ gSavedSettings.getControl("JoystickAxis5")->getSignal()->connect(boost::bind(&handleJoystickChanged, _2));
+ gSavedSettings.getControl("JoystickAxis6")->getSignal()->connect(boost::bind(&handleJoystickChanged, _2));
+ gSavedSettings.getControl("FlycamAxisScale0")->getSignal()->connect(boost::bind(&handleJoystickChanged, _2));
+ gSavedSettings.getControl("FlycamAxisScale1")->getSignal()->connect(boost::bind(&handleJoystickChanged, _2));
+ gSavedSettings.getControl("FlycamAxisScale2")->getSignal()->connect(boost::bind(&handleJoystickChanged, _2));
+ gSavedSettings.getControl("FlycamAxisScale3")->getSignal()->connect(boost::bind(&handleJoystickChanged, _2));
+ gSavedSettings.getControl("FlycamAxisScale4")->getSignal()->connect(boost::bind(&handleJoystickChanged, _2));
+ gSavedSettings.getControl("FlycamAxisScale5")->getSignal()->connect(boost::bind(&handleJoystickChanged, _2));
+ gSavedSettings.getControl("FlycamAxisScale6")->getSignal()->connect(boost::bind(&handleJoystickChanged, _2));
+ gSavedSettings.getControl("FlycamAxisDeadZone0")->getSignal()->connect(boost::bind(&handleJoystickChanged, _2));
+ gSavedSettings.getControl("FlycamAxisDeadZone1")->getSignal()->connect(boost::bind(&handleJoystickChanged, _2));
+ gSavedSettings.getControl("FlycamAxisDeadZone2")->getSignal()->connect(boost::bind(&handleJoystickChanged, _2));
+ gSavedSettings.getControl("FlycamAxisDeadZone3")->getSignal()->connect(boost::bind(&handleJoystickChanged, _2));
+ gSavedSettings.getControl("FlycamAxisDeadZone4")->getSignal()->connect(boost::bind(&handleJoystickChanged, _2));
+ gSavedSettings.getControl("FlycamAxisDeadZone5")->getSignal()->connect(boost::bind(&handleJoystickChanged, _2));
+ gSavedSettings.getControl("FlycamAxisDeadZone6")->getSignal()->connect(boost::bind(&handleJoystickChanged, _2));
+ gSavedSettings.getControl("AvatarAxisScale0")->getSignal()->connect(boost::bind(&handleJoystickChanged, _2));
+ gSavedSettings.getControl("AvatarAxisScale1")->getSignal()->connect(boost::bind(&handleJoystickChanged, _2));
+ gSavedSettings.getControl("AvatarAxisScale2")->getSignal()->connect(boost::bind(&handleJoystickChanged, _2));
+ gSavedSettings.getControl("AvatarAxisScale3")->getSignal()->connect(boost::bind(&handleJoystickChanged, _2));
+ gSavedSettings.getControl("AvatarAxisScale4")->getSignal()->connect(boost::bind(&handleJoystickChanged, _2));
+ gSavedSettings.getControl("AvatarAxisScale5")->getSignal()->connect(boost::bind(&handleJoystickChanged, _2));
+ gSavedSettings.getControl("AvatarAxisDeadZone0")->getSignal()->connect(boost::bind(&handleJoystickChanged, _2));
+ gSavedSettings.getControl("AvatarAxisDeadZone1")->getSignal()->connect(boost::bind(&handleJoystickChanged, _2));
+ gSavedSettings.getControl("AvatarAxisDeadZone2")->getSignal()->connect(boost::bind(&handleJoystickChanged, _2));
+ gSavedSettings.getControl("AvatarAxisDeadZone3")->getSignal()->connect(boost::bind(&handleJoystickChanged, _2));
+ gSavedSettings.getControl("AvatarAxisDeadZone4")->getSignal()->connect(boost::bind(&handleJoystickChanged, _2));
+ gSavedSettings.getControl("AvatarAxisDeadZone5")->getSignal()->connect(boost::bind(&handleJoystickChanged, _2));
+ gSavedSettings.getControl("BuildAxisScale0")->getSignal()->connect(boost::bind(&handleJoystickChanged, _2));
+ gSavedSettings.getControl("BuildAxisScale1")->getSignal()->connect(boost::bind(&handleJoystickChanged, _2));
+ gSavedSettings.getControl("BuildAxisScale2")->getSignal()->connect(boost::bind(&handleJoystickChanged, _2));
+ gSavedSettings.getControl("BuildAxisScale3")->getSignal()->connect(boost::bind(&handleJoystickChanged, _2));
+ gSavedSettings.getControl("BuildAxisScale4")->getSignal()->connect(boost::bind(&handleJoystickChanged, _2));
+ gSavedSettings.getControl("BuildAxisScale5")->getSignal()->connect(boost::bind(&handleJoystickChanged, _2));
+ gSavedSettings.getControl("BuildAxisDeadZone0")->getSignal()->connect(boost::bind(&handleJoystickChanged, _2));
+ gSavedSettings.getControl("BuildAxisDeadZone1")->getSignal()->connect(boost::bind(&handleJoystickChanged, _2));
+ gSavedSettings.getControl("BuildAxisDeadZone2")->getSignal()->connect(boost::bind(&handleJoystickChanged, _2));
+ gSavedSettings.getControl("BuildAxisDeadZone3")->getSignal()->connect(boost::bind(&handleJoystickChanged, _2));
+ gSavedSettings.getControl("BuildAxisDeadZone4")->getSignal()->connect(boost::bind(&handleJoystickChanged, _2));
+ gSavedSettings.getControl("BuildAxisDeadZone5")->getSignal()->connect(boost::bind(&handleJoystickChanged, _2));
+ gSavedSettings.getControl("DebugViews")->getSignal()->connect(boost::bind(&handleDebugViewsChanged, _2));
+ gSavedSettings.getControl("UserLogFile")->getSignal()->connect(boost::bind(&handleLogFileChanged, _2));
+ gSavedSettings.getControl("RenderHideGroupTitle")->getSignal()->connect(boost::bind(handleHideGroupTitleChanged, _2));
+ gSavedSettings.getControl("HighResSnapshot")->getSignal()->connect(boost::bind(handleHighResSnapshotChanged, _2));
+ gSavedSettings.getControl("VectorizePerfTest")->getSignal()->connect(boost::bind(&handleVectorizeChanged, _2));
+ gSavedSettings.getControl("VectorizeEnable")->getSignal()->connect(boost::bind(&handleVectorizeChanged, _2));
+ gSavedSettings.getControl("VectorizeProcessor")->getSignal()->connect(boost::bind(&handleVectorizeChanged, _2));
+ gSavedSettings.getControl("VectorizeSkin")->getSignal()->connect(boost::bind(&handleVectorizeChanged, _2));
+ gSavedSettings.getControl("EnableVoiceChat")->getSignal()->connect(boost::bind(&handleVoiceClientPrefsChanged, _2));
+ gSavedSettings.getControl("PTTCurrentlyEnabled")->getSignal()->connect(boost::bind(&handleVoiceClientPrefsChanged, _2));
+ gSavedSettings.getControl("PushToTalkButton")->getSignal()->connect(boost::bind(&handleVoiceClientPrefsChanged, _2));
+ gSavedSettings.getControl("PushToTalkToggle")->getSignal()->connect(boost::bind(&handleVoiceClientPrefsChanged, _2));
+ gSavedSettings.getControl("VoiceEarLocation")->getSignal()->connect(boost::bind(&handleVoiceClientPrefsChanged, _2));
+ gSavedSettings.getControl("VoiceInputAudioDevice")->getSignal()->connect(boost::bind(&handleVoiceClientPrefsChanged, _2));
+ gSavedSettings.getControl("VoiceOutputAudioDevice")->getSignal()->connect(boost::bind(&handleVoiceClientPrefsChanged, _2));
+ gSavedSettings.getControl("AudioLevelMic")->getSignal()->connect(boost::bind(&handleVoiceClientPrefsChanged, _2));
+ gSavedSettings.getControl("LipSyncEnabled")->getSignal()->connect(boost::bind(&handleVoiceClientPrefsChanged, _2));
+ gSavedSettings.getControl("VelocityInterpolate")->getSignal()->connect(boost::bind(&handleVelocityInterpolate, _2));
+ gSavedSettings.getControl("QAMode")->getSignal()->connect(boost::bind(&show_debug_menus));
+ gSavedSettings.getControl("UseDebugMenus")->getSignal()->connect(boost::bind(&show_debug_menus));
}
-
#if TEST_CACHED_CONTROL
#define DECL_LLCC(T, V) static LLCachedControl<T> mySetting_##T("TestCachedControl"#T, V)
diff --git a/indra/newview/llviewercontrol.h b/indra/newview/llviewercontrol.h
index c4003111d3..b1f14eca7b 100644
--- a/indra/newview/llviewercontrol.h
+++ b/indra/newview/llviewercontrol.h
@@ -47,17 +47,13 @@ extern BOOL gHackGodmode;
//setting variables are declared in this function
void settings_setup_listeners();
-extern std::map<std::string, LLControlGroup*> gSettings;
-
// for the graphics settings
void create_graphics_group(LLControlGroup& group);
// saved at end of session
extern LLControlGroup gSavedSettings;
extern LLControlGroup gSavedPerAccountSettings;
-
-// Read-only
-extern LLControlGroup gColors;
+extern LLControlGroup gWarningSettings;
// Saved at end of session
extern LLControlGroup gCrashSettings;
@@ -66,110 +62,5 @@ extern LLControlGroup gCrashSettings;
extern std::string gLastRunVersion;
extern std::string gCurrentVersion;
-//! Helper function for LLCachedControl
-template <class T>
-eControlType get_control_type(const T& in, LLSD& out)
-{
- llerrs << "Usupported control type: " << typeid(T).name() << "." << llendl;
- return TYPE_COUNT;
-}
-
-//! Publish/Subscribe object to interact with LLControlGroups.
-
-//! An LLCachedControl instance to connect to a LLControlVariable
-//! without have to manually create and bind a listener to a local
-//! object.
-template <class T>
-class LLCachedControl
-{
- T mCachedValue;
- LLPointer<LLControlVariable> mControl;
- boost::signals2::scoped_connection mConnection;
-
-public:
- LLCachedControl(const std::string& name,
- const T& default_value,
- const std::string& comment = "Declared In Code")
- {
- mControl = gSavedSettings.getControl(name);
- if(mControl.isNull())
- {
- declareTypedControl(gSavedSettings, name, default_value, comment);
- mControl = gSavedSettings.getControl(name);
- if(mControl.isNull())
- {
- llerrs << "The control could not be created!!!" << llendl;
- }
-
- mCachedValue = default_value;
- }
- else
- {
- mCachedValue = (const T&)mControl->getValue();
- }
-
- // Add a listener to the controls signal...
- mConnection = mControl->getSignal()->connect(
- boost::bind(&LLCachedControl<T>::handleValueChange, this, _1)
- );
- }
-
- ~LLCachedControl()
- {
- }
-
- LLCachedControl& operator =(const T& newvalue)
- {
- setTypeValue(*mControl, newvalue);
- }
-
- operator const T&() { return mCachedValue; }
-
-private:
- void declareTypedControl(LLControlGroup& group,
- const std::string& name,
- const T& default_value,
- const std::string& comment)
- {
- LLSD init_value;
- eControlType type = get_control_type<T>(default_value, init_value);
- if(type < TYPE_COUNT)
- {
- group.declareControl(name, type, init_value, comment, FALSE);
- }
- }
-
- bool handleValueChange(const LLSD& newvalue)
- {
- mCachedValue = (const T &)newvalue;
- return true;
- }
-
- void setTypeValue(LLControlVariable& c, const T& v)
- {
- // Implicit conversion from T to LLSD...
- c.set(v);
- }
-};
-
-template <> eControlType get_control_type<U32>(const U32& in, LLSD& out);
-template <> eControlType get_control_type<S32>(const S32& in, LLSD& out);
-template <> eControlType get_control_type<F32>(const F32& in, LLSD& out);
-template <> eControlType get_control_type<bool> (const bool& in, LLSD& out);
-// Yay BOOL, its really an S32.
-//template <> eControlType get_control_type<BOOL> (const BOOL& in, LLSD& out)
-template <> eControlType get_control_type<std::string>(const std::string& in, LLSD& out);
-template <> eControlType get_control_type<LLVector3>(const LLVector3& in, LLSD& out);
-template <> eControlType get_control_type<LLVector3d>(const LLVector3d& in, LLSD& out);
-template <> eControlType get_control_type<LLRect>(const LLRect& in, LLSD& out);
-template <> eControlType get_control_type<LLColor4>(const LLColor4& in, LLSD& out);
-template <> eControlType get_control_type<LLColor3>(const LLColor3& in, LLSD& out);
-template <> eControlType get_control_type<LLColor4U>(const LLColor4U& in, LLSD& out);
-template <> eControlType get_control_type<LLSD>(const LLSD& in, LLSD& out);
-
-//#define TEST_CACHED_CONTROL 1
-#ifdef TEST_CACHED_CONTROL
-void test_cached_control();
-#endif // TEST_CACHED_CONTROL
#endif // LL_LLVIEWERCONTROL_H
diff --git a/indra/newview/llviewerdisplay.cpp b/indra/newview/llviewerdisplay.cpp
index 977582ba24..8e65c7e65e 100644
--- a/indra/newview/llviewerdisplay.cpp
+++ b/indra/newview/llviewerdisplay.cpp
@@ -46,10 +46,9 @@
#include "lldrawpoolalpha.h"
#include "llfeaturemanager.h"
#include "llfirstuse.h"
-#include "llframestats.h"
#include "llhudmanager.h"
#include "llimagebmp.h"
-#include "llimagegl.h"
+#include "llmemory.h"
#include "llselectmgr.h"
#include "llsky.h"
#include "llstartup.h"
@@ -58,12 +57,13 @@
#include "lltooldraganddrop.h"
#include "lltoolpie.h"
#include "lltracker.h"
+#include "lltrans.h"
#include "llui.h"
#include "llviewercamera.h"
#include "llviewerobjectlist.h"
#include "llviewerparcelmgr.h"
#include "llviewerwindow.h"
-#include "llvoavatar.h"
+#include "llvoavatarself.h"
#include "llvograss.h"
#include "llworld.h"
#include "pipeline.h"
@@ -73,7 +73,7 @@
#include "llviewershadermgr.h"
#include "llfasttimer.h"
#include "llfloatertools.h"
-#include "llviewerimagelist.h"
+#include "llviewertexturelist.h"
#include "llfocusmgr.h"
#include "llcubemap.h"
#include "llviewerregion.h"
@@ -83,9 +83,9 @@
#include "llwaterparammanager.h"
#include "llpostprocess.h"
-extern LLPointer<LLImageGL> gStartImageGL;
+extern LLPointer<LLViewerTexture> gStartTexture;
-LLPointer<LLImageGL> gDisconnectedImagep = NULL;
+LLPointer<LLViewerTexture> gDisconnectedImagep = NULL;
// used to toggle renderer back on after teleport
const F32 TELEPORT_RENDER_DELAY = 20.f; // Max time a teleport is allowed to take before we raise the curtain
@@ -135,7 +135,7 @@ void display_startup()
if (frame_count++ > 1) // make sure we have rendered a frame first
{
- LLDynamicTexture::updateAllInstances();
+ LLViewerDynamicTexture::updateAllInstances();
}
LLGLState::checkStates();
@@ -163,6 +163,7 @@ void display_startup()
void display_update_camera()
{
+ LLMemType mt_uc(LLMemType::MTYPE_DISPLAY_UPDATE_CAMERA);
llpushcallstacks ;
// TODO: cut draw distance down if customizing avatar?
// TODO: cut draw distance on per-parcel basis?
@@ -199,17 +200,24 @@ void display_stats()
F32 mem_log_freq = gSavedSettings.getF32("MemoryLogFrequency");
if (mem_log_freq > 0.f && gRecentMemoryTime.getElapsedTimeF32() >= mem_log_freq)
{
- gMemoryAllocated = getCurrentRSS();
+ gMemoryAllocated = LLMemory::getCurrentRSS();
U32 memory = (U32)(gMemoryAllocated / (1024*1024));
llinfos << llformat("MEMORY: %d MB", memory) << llendl;
gRecentMemoryTime.reset();
}
}
+static LLFastTimer::DeclareTimer FTM_PICK("Picking");
+static LLFastTimer::DeclareTimer FTM_RENDER("Render", true);
+static LLFastTimer::DeclareTimer FTM_UPDATE_SKY("Update Sky");
+static LLFastTimer::DeclareTimer FTM_UPDATE_TEXTURES("Update Textures");
+static LLFastTimer::DeclareTimer FTM_IMAGE_UPDATE("Update Images");
+
// Paint the display!
void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot)
{
- LLFastTimer t(LLFastTimer::FTM_RENDER);
+ LLMemType mt_render(LLMemType::MTYPE_RENDER);
+ LLFastTimer t(FTM_RENDER);
if (LLPipeline::sRenderFrameTest)
{
@@ -226,8 +234,12 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot)
LLGLState::checkStates();
LLGLState::checkTextureChannels();
+ stop_glerror();
+
gPipeline.disableLights();
+ stop_glerror();
+
// Don't draw if the window is hidden or minimized.
// In fact, must explicitly check the minimized state before drawing.
// Attempting to draw into a minimized window causes a GL error. JC
@@ -238,18 +250,21 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot)
// Clean up memory the pools may have allocated
if (rebuild)
{
- gFrameStats.start(LLFrameStats::REBUILD);
+ stop_glerror();
gPipeline.rebuildPools();
+ stop_glerror();
}
+ stop_glerror();
gViewerWindow->returnEmptyPicks();
+ stop_glerror();
return;
}
gViewerWindow->checkSettings();
{
- LLFastTimer ftm(LLFastTimer::FTM_PICK);
+ LLFastTimer ftm(FTM_PICK);
LLAppViewer::instance()->pingMainloopTimeout("Display:Pick");
gViewerWindow->performPick();
}
@@ -299,13 +314,12 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot)
//
LLAppViewer::instance()->pingMainloopTimeout("Display:TextureStats");
- gFrameStats.start(LLFrameStats::UPDATE_TEX_STATS);
stop_glerror();
LLImageGL::updateStats(gFrameTimeSeconds);
- LLVOAvatar::sRenderName = gSavedSettings.getS32("RenderName");
- LLVOAvatar::sRenderGroupTitles = !gSavedSettings.getBOOL("RenderHideGroupTitleAll");
+ LLVOAvatar::sRenderName = gSavedSettings.getS32("AvatarNameTagMode");
+ LLVOAvatar::sRenderGroupTitles = (gSavedSettings.getBOOL("RenderShowGroupTitleAll") && gSavedSettings.getS32("AvatarNameTagMode"));
gPipeline.mBackfaceCull = TRUE;
gFrameCount++;
@@ -369,12 +383,12 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot)
case LLAgent::TELEPORT_START_ARRIVAL:
// Transition to ARRIVING. Viewer has received avatar update, etc., from destination simulator
gTeleportArrivalTimer.reset();
- gViewerWindow->setProgressCancelButtonVisible(FALSE, std::string("Cancel")); //TODO: Translate
+ gViewerWindow->setProgressCancelButtonVisible(FALSE, LLTrans::getString("Cancel"));
gViewerWindow->setProgressPercent(75.f);
gAgent.setTeleportState( LLAgent::TELEPORT_ARRIVING );
gAgent.setTeleportMessage(
LLAgent::sTeleportProgressMessages["arriving"]);
- gImageList.mForceResetTextureStats = TRUE;
+ gTextureList.mForceResetTextureStats = TRUE;
gAgent.resetView(TRUE, TRUE);
break;
@@ -388,7 +402,7 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot)
LLFirstUse::useTeleport();
gAgent.setTeleportState( LLAgent::TELEPORT_NONE );
}
- gViewerWindow->setProgressCancelButtonVisible(FALSE, std::string("Cancel")); //TODO: Translate
+ gViewerWindow->setProgressCancelButtonVisible(FALSE, LLTrans::getString("Cancel"));
gViewerWindow->setProgressPercent( arrival_fraction * 25.f + 75.f);
gViewerWindow->setProgressString(message);
}
@@ -496,19 +510,20 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot)
if (gPipeline.hasRenderDebugFeatureMask(LLPipeline::RENDER_DEBUG_FEATURE_DYNAMIC_TEXTURES))
{
LLAppViewer::instance()->pingMainloopTimeout("Display:DynamicTextures");
- LLFastTimer t(LLFastTimer::FTM_UPDATE_TEXTURES);
- if (LLDynamicTexture::updateAllInstances())
+ LLFastTimer t(FTM_UPDATE_TEXTURES);
+ if (LLViewerDynamicTexture::updateAllInstances())
{
gGL.setColorMask(true, true);
glClear(GL_DEPTH_BUFFER_BIT);
}
}
- gViewerWindow->setupViewport();
+ gViewerWindow->setup3DViewport();
gPipeline.resetFrameStats(); // Reset per-frame statistics.
if (!gDisconnected)
{
+ LLMemType mt_du(LLMemType::MTYPE_DISPLAY_UPDATE);
LLAppViewer::instance()->pingMainloopTimeout("Display:Update");
if (gPipeline.hasRenderType(LLPipeline::RENDER_TYPE_HUD))
{ //don't draw hud objects in this frame
@@ -528,17 +543,21 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot)
stop_glerror();
// *TODO: merge these two methods
- LLHUDManager::getInstance()->updateEffects();
- LLHUDObject::updateAll();
- stop_glerror();
-
- gFrameStats.start(LLFrameStats::UPDATE_GEOM);
- const F32 max_geom_update_time = 0.005f*10.f*gFrameIntervalSeconds; // 50 ms/second update time
- gPipeline.createObjects(max_geom_update_time);
- gPipeline.updateGeom(max_geom_update_time);
- stop_glerror();
-
- gFrameStats.start(LLFrameStats::UPDATE_CULL);
+ {
+ LLMemType mt_uh(LLMemType::MTYPE_DISPLAY_UPDATE_HUD);
+ LLHUDManager::getInstance()->updateEffects();
+ LLHUDObject::updateAll();
+ stop_glerror();
+ }
+
+ {
+ LLMemType mt_ug(LLMemType::MTYPE_DISPLAY_UPDATE_GEOM);
+ const F32 max_geom_update_time = 0.005f*10.f*gFrameIntervalSeconds; // 50 ms/second update time
+ gPipeline.createObjects(max_geom_update_time);
+ gPipeline.updateGeom(max_geom_update_time);
+ stop_glerror();
+ }
+
S32 water_clip = 0;
if ((LLViewerShaderMgr::instance()->getVertexShaderLevel(LLViewerShaderMgr::SHADER_ENVIRONMENT) > 1) &&
gPipeline.hasRenderType(LLPipeline::RENDER_TYPE_WATER))
@@ -552,7 +571,7 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot)
water_clip = 1;
}
}
-
+
LLAppViewer::instance()->pingMainloopTimeout("Display:Cull");
//Increment drawable frame counter
@@ -601,8 +620,9 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot)
LLAppViewer::instance()->pingMainloopTimeout("Display:Swap");
{
+ LLMemType mt_ds(LLMemType::MTYPE_DISPLAY_SWAP);
{
- LLFastTimer ftm(LLFastTimer::FTM_CLIENT_COPY);
+ LLFastTimer ftm(FTM_CLIENT_COPY);
LLVertexBuffer::clientCopy(0.016);
}
@@ -643,7 +663,7 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot)
glLoadMatrixf(proj.m);
glMatrixMode(GL_MODELVIEW);
glLoadMatrixf(mod.m);
- gViewerWindow->setupViewport();
+ gViewerWindow->setup3DViewport();
LLGLState::checkStates();
LLGLState::checkTextureChannels();
@@ -655,6 +675,7 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot)
if (!for_snapshot)
{
+ LLMemType mt_gw(LLMemType::MTYPE_DISPLAY_GEN_REFLECTION);
LLAppViewer::instance()->pingMainloopTimeout("Display:Imagery");
gPipeline.generateWaterReflection(*LLViewerCamera::getInstance());
}
@@ -669,18 +690,18 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot)
LLAppViewer::instance()->pingMainloopTimeout("Display:UpdateImages");
LLError::LLCallStacks::clear() ;
llpushcallstacks ;
- gFrameStats.start(LLFrameStats::IMAGE_UPDATE);
{
- LLFastTimer t(LLFastTimer::FTM_IMAGE_UPDATE);
+ LLMemType mt_iu(LLMemType::MTYPE_DISPLAY_IMAGE_UPDATE);
+ LLFastTimer t(FTM_IMAGE_UPDATE);
- LLViewerImage::updateClass(LLViewerCamera::getInstance()->getVelocityStat()->getMean(),
+ LLViewerTexture::updateClass(LLViewerCamera::getInstance()->getVelocityStat()->getMean(),
LLViewerCamera::getInstance()->getAngularVelocityStat()->getMean());
- gBumpImageList.updateImages(); // must be called before gImageList version so that it's textures are thrown out first.
+ gBumpImageList.updateImages(); // must be called before gTextureList version so that it's textures are thrown out first.
const F32 max_image_decode_time = llmin(0.005f, 0.005f*10.f*gFrameIntervalSeconds); // 50 ms/second decode time (no more than 5ms/frame)
- gImageList.updateImages(max_image_decode_time);
+ gTextureList.updateImages(max_image_decode_time);
stop_glerror();
}
llpushcallstacks ;
@@ -694,7 +715,7 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot)
//
LLAppViewer::instance()->pingMainloopTimeout("Display:StateSort");
{
- gFrameStats.start(LLFrameStats::STATE_SORT);
+ LLMemType mt_ss(LLMemType::MTYPE_DISPLAY_STATE_SORT);
gPipeline.stateSort(*LLViewerCamera::getInstance(), result);
stop_glerror();
@@ -705,7 +726,6 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot)
// rebuildPools
//
//
- gFrameStats.start(LLFrameStats::REBUILD);
gPipeline.rebuildPools();
stop_glerror();
}
@@ -714,8 +734,9 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot)
LLPipeline::sUseOcclusion = occlusion;
{
+ LLMemType mt_ds(LLMemType::MTYPE_DISPLAY_SKY);
LLAppViewer::instance()->pingMainloopTimeout("Display:Sky");
- LLFastTimer t(LLFastTimer::FTM_UPDATE_SKY);
+ LLFastTimer t(FTM_UPDATE_SKY);
gSky.updateSky();
}
@@ -741,7 +762,7 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot)
// glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_TRUE);
// glLoadIdentity();
- // LLRect floater_rect = frontmost_floaterp->getScreenRect();
+ // LLRect floater_rect = frontmost_floaterp->calcScreenRect();
// // deflate by one pixel so rounding errors don't occlude outside of floater extents
// floater_rect.stretch(-1);
// LLRectf floater_3d_rect((F32)floater_rect.mLeft / (F32)gViewerWindow->getWindowWidth(),
@@ -792,7 +813,7 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot)
if (!(LLAppViewer::instance()->logoutRequestSent() && LLAppViewer::instance()->hasSavedFinalSnapshot())
&& !gRestoreGL)
{
-
+ LLMemType mt_rg(LLMemType::MTYPE_DISPLAY_RENDER_GEOM);
gGL.setColorMask(true, false);
if (LLPipeline::sRenderDeferred && !LLPipeline::sUnderWaterRender)
{
@@ -818,6 +839,7 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot)
if (to_texture)
{
+ LLMemType mt_rf(LLMemType::MTYPE_DISPLAY_RENDER_FLUSH);
if (LLPipeline::sRenderDeferred && !LLPipeline::sUnderWaterRender)
{
gPipeline.mDeferredScreen.flush();
@@ -844,16 +866,15 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot)
LLAppViewer::instance()->pingMainloopTimeout("Display:RenderUI");
if (!for_snapshot)
{
- gFrameStats.start(LLFrameStats::RENDER_UI);
+ LLFastTimer t(FTM_RENDER_UI);
render_ui();
}
LLSpatialGroup::sNoDelete = FALSE;
}
-
+
LLAppViewer::instance()->pingMainloopTimeout("Display:FrameStats");
- gFrameStats.start(LLFrameStats::MISC_END);
stop_glerror();
if (LLPipeline::sRenderFrameTest)
@@ -869,6 +890,7 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot)
void render_hud_attachments()
{
+ LLMemType mt_ra(LLMemType::MTYPE_DISPLAY_RENDER_ATTACHMENTS);
glMatrixMode(GL_PROJECTION);
glPushMatrix();
glMatrixMode(GL_MODELVIEW);
@@ -1024,9 +1046,11 @@ BOOL setup_hud_matrices(const LLRect& screen_region)
}
}
+static LLFastTimer::DeclareTimer FTM_SWAP("Swap");
void render_ui(F32 zoom_factor, int subfield)
{
+ LLMemType mt_ru(LLMemType::MTYPE_DISPLAY_RENDER_UI);
LLGLState::checkStates();
glPushMatrix();
@@ -1058,7 +1082,7 @@ void render_ui(F32 zoom_factor, int subfield)
gGL.color4f(1,1,1,1);
if (gPipeline.hasRenderDebugFeatureMask(LLPipeline::RENDER_DEBUG_FEATURE_UI))
{
- LLFastTimer t(LLFastTimer::FTM_RENDER_UI);
+ LLFastTimer t(FTM_RENDER_UI);
if (!gDisconnected)
{
@@ -1085,7 +1109,7 @@ void render_ui(F32 zoom_factor, int subfield)
if (gDisplaySwapBuffers)
{
- LLFastTimer t(LLFastTimer::FTM_SWAP);
+ LLFastTimer t(FTM_SWAP);
gViewerWindow->mWindow->swapBuffers();
}
gDisplaySwapBuffers = TRUE;
@@ -1261,8 +1285,7 @@ void render_disconnected_background()
//llinfos << "Bitmap load failed" << llendl;
return;
}
-
- gDisconnectedImagep = new LLImageGL( FALSE );
+
LLPointer<LLImageRaw> raw = new LLImageRaw;
if (!image_bmp->decode(raw, 0.0f))
{
@@ -1288,8 +1311,8 @@ void render_disconnected_background()
raw->expandToPowerOfTwo();
- gDisconnectedImagep->createGLTexture(0, raw);
- gStartImageGL = gDisconnectedImagep;
+ gDisconnectedImagep = LLViewerTextureManager::getLocalTexture(raw.get(), FALSE );
+ gStartTexture = gDisconnectedImagep;
gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
}
diff --git a/indra/newview/llviewerfloaterreg.cpp b/indra/newview/llviewerfloaterreg.cpp
new file mode 100644
index 0000000000..b85dc30e72
--- /dev/null
+++ b/indra/newview/llviewerfloaterreg.cpp
@@ -0,0 +1,250 @@
+/**
+ * @file llviewerfloaterreg.cpp
+ * @brief LLViewerFloaterReg class registers floaters used in the viewer
+ *
+ * $LicenseInfo:firstyear=2007&license=viewergpl$
+ *
+ * Copyright (c) 2007-2009, Linden Research, Inc.
+ *
+ * Second Life Viewer Source Code
+ * The source code in this file ("Source Code") is provided by Linden Lab
+ * to you under the terms of the GNU General Public License, version 2.0
+ * ("GPL"), unless you have obtained a separate licensing agreement
+ * ("Other License"), formally executed by you and Linden Lab. Terms of
+ * the GPL can be found in doc/GPL-license.txt in this distribution, or
+ * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
+ *
+ * There are special exceptions to the terms and conditions of the GPL as
+ * it is applied to this Source Code. View the full text of the exception
+ * in the file doc/FLOSS-exception.txt in this software distribution, or
+ * online at
+ * http://secondlifegrid.net/programs/open_source/licensing/flossexception
+ *
+ * By copying, modifying or distributing this software, you acknowledge
+ * that you have read and understood your obligations described above,
+ * and agree to abide by those obligations.
+ *
+ * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+ * COMPLETENESS OR PERFORMANCE.
+ * $/LicenseInfo$
+ */
+
+
+#include "llviewerprecompiledheaders.h"
+
+#include "llfloaterreg.h"
+
+#include "llviewerfloaterreg.h"
+
+#include "llcompilequeue.h"
+#include "llfloaterabout.h"
+#include "llfloateractivespeakers.h"
+#include "llfloateranimpreview.h"
+#include "llfloaterauction.h"
+#include "llfloateravatarpicker.h"
+#include "llfloateravatartextures.h"
+#include "llfloaterbeacons.h"
+#include "llfloaterbuildoptions.h"
+#include "llfloaterbuy.h"
+#include "llfloaterbuycontents.h"
+#include "llfloaterbuycurrency.h"
+#include "llfloaterbuyland.h"
+#include "llfloaterbulkpermission.h"
+#include "llfloaterbump.h"
+#include "llfloatercall.h"
+#include "llfloatercamera.h"
+#include "llfloaterchat.h"
+#include "llfloaterchatterbox.h"
+#include "llfloaterdaycycle.h"
+#include "llfloaterdirectory.h"
+#include "llfloaterfirsttimetip.h"
+#include "llfloaterenvsettings.h"
+#include "llfloaterfonttest.h"
+#include "llfloatergesture.h"
+#include "llfloatergodtools.h"
+#include "llfloatergroups.h"
+#include "llfloaterhardwaresettings.h"
+#include "llfloaterhtmlcurrency.h"
+#include "llfloatermediabrowser.h"
+#include "llfloaterhud.h"
+#include "llfloaterimagepreview.h"
+#include "llimpanel.h"
+#include "llfloaterinspect.h"
+#include "llfloaterinventory.h"
+#include "llfloaterjoystick.h"
+#include "llfloaterlagmeter.h"
+#include "llfloaterland.h"
+#include "llfloaterlandholdings.h"
+#include "llfloatermap.h"
+#include "llfloatermemleak.h"
+#include "llfloatermute.h"
+#include "llfloaternamedesc.h"
+#include "llfloaternotificationsconsole.h"
+#include "llfloateropenobject.h"
+#include "llgivemoney.h"
+#include "llfloaterparcel.h"
+#include "llfloaterperms.h"
+#include "llfloaterpostcard.h"
+#include "llfloaterpostprocess.h"
+#include "llfloaterpreference.h"
+#include "llfloaterproperties.h"
+#include "llfloaterregioninfo.h"
+#include "llfloaterreporter.h"
+#include "llfloaterscriptdebug.h"
+#include "llfloatersellland.h"
+#include "llfloatersettingsdebug.h"
+#include "llfloatersnapshot.h"
+#include "llfloatertelehub.h"
+#include "llfloatertestlistview.h"
+#include "llfloatertools.h"
+#include "llfloatertos.h"
+#include "llfloatertopobjects.h"
+#include "llfloateruipreview.h"
+#include "llfloaterurldisplay.h"
+#include "llfloatervoicedevicesettings.h"
+#include "llfloaterwater.h"
+#include "llfloaterwindlight.h"
+#include "llfloaterworldmap.h"
+#include "llinspectavatar.h"
+#include "llmediaremotectrl.h"
+#include "llmoveview.h"
+#include "llnearbychat.h"
+#include "llpreviewanim.h"
+#include "llpreviewgesture.h"
+#include "llpreviewnotecard.h"
+#include "llpreviewscript.h"
+#include "llpreviewsound.h"
+#include "llpreviewtexture.h"
+#include "llsyswellwindow.h"
+// *NOTE: Please add files in alphabetical order to keep merges easy.
+
+
+void LLViewerFloaterReg::registerFloaters()
+{
+ // *NOTE: Please keep these alphabetized for easier merges
+
+ LLFloaterReg::add("about_land", "floater_about_land.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterLand>);
+ LLFloaterReg::add("active_speakers", "floater_active_speakers.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterActiveSpeakers>);
+ LLFloaterReg::add("auction", "floater_auction.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterAuction>);
+ LLFloaterReg::add("avatar_picker", "floater_avatar_picker.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterAvatarPicker>);
+ LLFloaterReg::add("avatar_textures", "floater_avatar_textures.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterAvatarTextures>);
+
+ LLFloaterReg::add("beacons", "floater_beacons.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterBeacons>);
+ LLFloaterReg::add("bulk_perms", "floater_bulk_perms.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterBulkPermission>);
+ LLFloaterReg::add("buy_currency", "floater_buy_currency.xml", &LLFloaterBuyCurrency::buildFloater);
+ LLFloaterReg::add("buy_land", "floater_buy_land.xml", &LLFloaterBuyLand::buildFloater);
+ LLFloaterReg::add("buy_object", "floater_buy_object.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterBuy>);
+ LLFloaterReg::add("buy_object_contents", "floater_buy_contents.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterBuyContents>);
+ LLFloaterReg::add("build", "floater_tools.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterTools>);
+ LLFloaterReg::add("build_options", "floater_build_options.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterBuildOptions>);
+ LLFloaterReg::add("bumps", "floater_bumps.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterBump>);
+
+ LLFloaterReg::add("camera", "floater_camera.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterCamera>);
+ LLFloaterReg::add("chat", "floater_chat_history.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterChat>);
+ LLFloaterReg::add("nearby_chat", "floater_nearby_chat.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLNearbyChat>);
+ LLFloaterReg::add("communicate", "floater_chatterbox.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterChatterBox>);
+ LLFloaterReg::add("compile_queue", "floater_script_queue.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterCompileQueue>);
+ LLFloaterReg::add("contacts", "floater_my_friends.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterMyFriends>);
+
+ LLFloaterReg::add("first_time_tip", "floater_first_time_tip.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterFirstTimeTip>);
+ LLFloaterReg::add("env_day_cycle", "floater_day_cycle_options.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterDayCycle>);
+ LLFloaterReg::add("env_post_process", "floater_post_process.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterPostProcess>);
+ LLFloaterReg::add("env_settings", "floater_env_settings.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterEnvSettings>);
+ LLFloaterReg::add("env_water", "floater_water.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterWater>);
+ LLFloaterReg::add("env_windlight", "floater_windlight_options.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterWindLight>);
+
+ LLFloaterReg::add("font_test", "floater_font_test.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterFontTest>);
+
+ LLFloaterReg::add("gestures", "floater_gesture.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterGesture>);
+ LLFloaterReg::add("god_tools", "floater_god_tools.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterGodTools>);
+ LLFloaterReg::add("group_picker", "floater_choose_group.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterGroupPicker>);
+
+ LLFloaterReg::add("hud", "floater_hud.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterHUD>);
+ LLFloaterReg::add("html_simple", "floater_html_simple.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterHtmlSimple>);
+
+ LLFloaterReg::add("impanel", "floater_im_session.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLIMFloater>);
+ LLFloaterReg::add("inventory", "floater_inventory.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterInventory>);
+ LLFloaterReg::add("inspect", "floater_inspect.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterInspect>);
+ LLFloaterReg::add("inspect_avatar", "inspect_avatar.xml",
+ &LLFloaterReg::build<LLInspectAvatar>);
+
+ LLFloaterReg::add("lagmeter", "floater_lagmeter.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterLagMeter>);
+ LLFloaterReg::add("land_holdings", "floater_land_holdings.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterLandHoldings>);
+
+ LLFloaterReg::add("mem_leaking", "floater_mem_leaking.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterMemLeak>);
+ LLFloaterReg::add("media_browser", "floater_media_browser.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterMediaBrowser>);
+ LLFloaterReg::add("message_critical", "floater_critical.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterTOS>);
+ LLFloaterReg::add("message_tos", "floater_tos.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterTOS>);
+ LLFloaterReg::add("moveview", "floater_moveview.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterMove>);
+ LLFloaterReg::add("mute", "floater_mute.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterMute>);
+ LLFloaterReg::add("mute_object", "floater_mute_object.xml", &LLFloaterMute::buildFloaterMuteObjectUI);
+ LLFloaterReg::add("mini_map", "floater_map.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterMap>);
+ LLFloaterReg::add("syswell_window", "floater_sys_well.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLSysWellWindow>);
+
+ LLFloaterReg::add("notifications_console", "floater_notifications_console.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterNotificationConsole>);
+ LLFloaterReg::add("nearby_chat", "floater_nearby_chat.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLNearbyChat>);
+
+ LLFloaterReg::add("openobject", "floater_openobject.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterOpenObject>);
+
+ LLFloaterReg::add("parcel_info", "floater_preview_url.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterParcelInfo>);
+ LLFloaterReg::add("pay_resident", "floater_pay.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterPay>);
+ LLFloaterReg::add("pay_object", "floater_pay_object.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterPay>);
+
+ LLFloaterReg::add("postcard", "floater_postcard.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterPostcard>);
+ LLFloaterReg::add("preferences", "floater_preferences.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterPreference>);
+ LLFloaterReg::add("prefs_hardware_settings", "floater_hardware_settings.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterHardwareSettings>);
+ LLFloaterReg::add("perm_prefs", "floater_perm_prefs.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterPerms>);
+ LLFloaterReg::add("preview_url", "floater_preview_url.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterURLDisplay>);
+ LLFloaterReg::add("pref_joystick", "floater_joystick.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterJoystick>);
+ LLFloaterReg::add("pref_voicedevicesettings", "floater_device_settings.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterVoiceDeviceSettings>);
+ LLFloaterReg::add("preview_anim", "floater_preview_animation.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLPreviewAnim>, "preview");
+ LLFloaterReg::add("preview_gesture", "floater_preview_gesture.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLPreviewGesture>, "preview");
+ LLFloaterReg::add("preview_notecard", "floater_preview_notecard.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLPreviewNotecard>, "preview");
+ LLFloaterReg::add("preview_script", "floater_script_preview.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLPreviewLSL>, "preview");
+ LLFloaterReg::add("preview_scriptedit", "floater_live_lsleditor.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLLiveLSLEditor>, "preview");
+ LLFloaterReg::add("preview_sound", "floater_preview_sound.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLPreviewSound>, "preview");
+ LLFloaterReg::add("preview_texture", "floater_preview_texture.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLPreviewTexture>, "preview");
+ LLFloaterReg::add("properties", "floater_inventory_item_properties.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterProperties>);
+
+ LLFloaterReg::add("telehubs", "floater_telehub.xml",&LLFloaterReg::build<LLFloaterTelehub>);
+ LLFloaterReg::add("test_list_view", "floater_test_list_view.xml",&LLFloaterReg::build<LLFloaterTestListView>);
+ LLFloaterReg::add("test_widgets", "floater_test_widgets.xml", &LLFloaterReg::build<LLFloater>);
+ LLFloaterReg::add("top_objects", "floater_top_objects.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterTopObjects>);
+
+ LLFloaterReg::add("reporter", "floater_report_abuse.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterReporter>);
+ LLFloaterReg::add("reset_queue", "floater_script_queue.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterResetQueue>);
+ LLFloaterReg::add("region_info", "floater_region_info.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterRegionInfo>);
+
+ LLFloaterReg::add("script_debug", "floater_script_debug.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterScriptDebug>);
+ LLFloaterReg::add("script_debug_output", "floater_script_debug_panel.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterScriptDebugOutput>);
+ LLFloaterReg::add("sell_land", "floater_sell_land.xml", &LLFloaterSellLand::buildFloater);
+ LLFloaterReg::add("settings_debug", "floater_settings_debug.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterSettingsDebug>);
+ LLFloaterReg::add("stats", "floater_stats.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloater>);
+ LLFloaterReg::add("start_queue", "floater_script_queue.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterRunQueue>);
+ LLFloaterReg::add("stop_queue", "floater_script_queue.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterNotRunQueue>);
+ LLFloaterReg::add("sl_about", "floater_about.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterAbout>);
+ LLFloaterReg::add("snapshot", "floater_snapshot.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterSnapshot>);
+ LLFloaterReg::add("search", "floater_directory.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterDirectory>);
+
+ LLFloaterReg::add("ui_preview", "floater_ui_preview.xml", &LLFloaterReg::build<LLFloaterUIPreview>);
+ LLFloaterReg::add("upload_anim", "floater_animation_preview.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterAnimPreview>, "upload");
+ LLFloaterReg::add("upload_image", "floater_image_preview.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterImagePreview>, "upload");
+ LLFloaterReg::add("upload_sound", "floater_sound_preview.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterSoundPreview>, "upload");
+
+ LLFloaterReg::add("voice_call", "floater_call.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterCall>);
+
+ LLFloaterReg::add("world_map", "floater_world_map.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterWorldMap>);
+
+ // *NOTE: Please keep these alphabetized for easier merges
+
+ // debug use only
+ LLFloaterReg::add("media_remote_ctrl", "floater_media_remote.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterMediaRemoteCtrl>);
+
+ // Untested / dangerous - not for release
+#if !LL_RELEASE_FOR_DOWNLOAD
+ LLFloaterReg::add("buy_currency_html", "floater_html_simple.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterHtmlCurrency>);
+#endif
+
+ LLFloaterReg::registerControlVariables(); // Make sure visibility and rect controls get preserved when saving
+}
diff --git a/indra/newview/llfloaterevent.h b/indra/newview/llviewerfloaterreg.h
index 8f448b5fa2..08c9589ebb 100644
--- a/indra/newview/llfloaterevent.h
+++ b/indra/newview/llviewerfloaterreg.h
@@ -1,8 +1,6 @@
/**
- * @file llfloaterevent.h
- * @brief Event information as shown in a floating window from
- * secondlife:// command handler.
- * Just a wrapper for LLPanelEvent.
+ * @file llviewerfloaterreg.h
+ * @brief The LLViewerFloaterReg class declaration
*
* $LicenseInfo:firstyear=2007&license=viewergpl$
*
@@ -32,29 +30,14 @@
* $/LicenseInfo$
*/
-#ifndef LL_LLFLOATEREVENT_H
-#define LL_LLFLOATEREVENT_H
+#ifndef LL_LLVIEWERFLOATERREG_H
+#define LL_LLVIEWERFLOATERREG_H
-#include "llfloater.h"
-
-class LLPanelEvent;
-
-class LLFloaterEventInfo : public LLFloater
+class LLViewerFloaterReg
{
public:
- LLFloaterEventInfo(const std::string& name, const U32 event_id );
- /*virtual*/ ~LLFloaterEventInfo();
-
- void displayEventInfo(const U32 event_id);
-
- static LLFloaterEventInfo* show(const U32 event_id);
-
- static void* createEventDetail(void* userdata);
-
-private:
- U32 mEventID; // for which event is this window?
- LLPanelEvent* mPanelEventp;
-
+ static void registerFloaters();
};
-#endif // LL_LLFLOATEREVENT_H
+
+#endif // LL_LLVIEWERFLOATERREG_H
diff --git a/indra/newview/llviewergesture.cpp b/indra/newview/llviewergesture.cpp
index 168f9af1d1..93b126b67d 100644
--- a/indra/newview/llviewergesture.cpp
+++ b/indra/newview/llviewergesture.cpp
@@ -34,12 +34,11 @@
#include "llviewergesture.h"
-#include "audioengine.h"
+#include "llaudioengine.h"
#include "lldir.h"
#include "llviewerinventory.h"
#include "sound_ids.h" // for testing
-#include "llchatbar.h"
#include "llkeyboard.h" // for key shortcuts for testing
#include "llinventorymodel.h"
#include "llvoavatar.h"
@@ -47,6 +46,7 @@
#include "llviewermessage.h" // send_guid_sound_trigger
#include "llviewernetwork.h"
#include "llagent.h"
+#include "llnearbychatbar.h"
// Globals
LLViewerGestureList gGestureList;
@@ -132,11 +132,11 @@ void LLViewerGesture::doTrigger( BOOL send_chat )
}
}
- if ( send_chat && !mOutputString.empty())
+ if (send_chat && !mOutputString.empty())
{
// Don't play nodding animation, since that might not blend
// with the gesture animation.
- gChatBar->sendChatFromViewer(mOutputString, CHAT_TYPE_NORMAL, FALSE);
+ LLNearbyChatBar::getInstance()->sendChatFromViewer(mOutputString, CHAT_TYPE_NORMAL, FALSE);
}
}
diff --git a/indra/newview/llviewerinventory.cpp b/indra/newview/llviewerinventory.cpp
index bad2e174c9..95ab40f9bf 100644
--- a/indra/newview/llviewerinventory.cpp
+++ b/indra/newview/llviewerinventory.cpp
@@ -37,6 +37,7 @@
#include "indra_constants.h"
#include "llagent.h"
+#include "llfoldertype.h"
#include "llviewercontrol.h"
#include "llconsole.h"
#include "llinventorymodel.h"
@@ -44,12 +45,14 @@
#include "llimview.h"
#include "llgesturemgr.h"
-#include "llinventoryview.h"
+#include "llinventorybridge.h"
+#include "llfloaterinventory.h"
#include "llviewerregion.h"
#include "llviewerobjectlist.h"
#include "llpreviewgesture.h"
#include "llviewerwindow.h"
+#include "lltrans.h"
///----------------------------------------------------------------------------
/// Local function declarations, constants, enums, and typedefs
@@ -199,10 +202,19 @@ void LLViewerInventoryItem::fetchFromServer(void) const
{
std::string url;
- if( ALEXANDRIA_LINDEN_ID.getString() == mPermissions.getOwner().getString())
- url = gAgent.getRegion()->getCapability("FetchLib");
- else
- url = gAgent.getRegion()->getCapability("FetchInventory");
+ LLViewerRegion* region = gAgent.getRegion();
+ // we have to check region. It can be null after region was destroyed. See EXT-245
+ if (region)
+ {
+ if( ALEXANDRIA_LINDEN_ID.getString() == mPermissions.getOwner().getString())
+ url = region->getCapability("FetchLib");
+ else
+ url = region->getCapability("FetchInventory");
+ }
+ else
+ {
+ llwarns << "Agent Region is absent" << llendl;
+ }
if (!url.empty())
{
@@ -242,8 +254,7 @@ BOOL LLViewerInventoryItem::unpackMessage(LLSD item)
}
// virtual
-BOOL LLViewerInventoryItem::unpackMessage(
- LLMessageSystem* msg, const char* block, S32 block_num)
+BOOL LLViewerInventoryItem::unpackMessage(LLMessageSystem* msg, const char* block, S32 block_num)
{
BOOL rv = LLInventoryItem::unpackMessage(msg, block, block_num);
mIsComplete = TRUE;
@@ -402,7 +413,8 @@ void LLViewerInventoryCategory::updateParentOnServer(BOOL restamp) const
void LLViewerInventoryCategory::updateServer(BOOL is_new) const
{
// communicate that change with the server.
- if(LLAssetType::AT_NONE != mPreferredType)
+
+ if (LLAssetType::lookupIsProtectedCategoryType(mPreferredType))
{
LLNotifications::instance().add("CannotModifyProtectedCategories");
return;
@@ -426,7 +438,7 @@ void LLViewerInventoryCategory::removeFromServer( void )
llinfos << "Removing inventory category " << mUUID << " from server."
<< llendl;
// communicate that change with the server.
- if(LLAssetType::AT_NONE != mPreferredType)
+ if(LLAssetType::lookupIsProtectedCategoryType(mPreferredType))
{
LLNotifications::instance().add("CannotRemoveProtectedCategories");
return;
@@ -576,6 +588,76 @@ bool LLViewerInventoryCategory::exportFileLocal(LLFILE* fp) const
return true;
}
+void LLViewerInventoryCategory::determineFolderType()
+{
+ LLAssetType::EType original_type = getPreferredType();
+ if (LLAssetType::lookupIsProtectedCategoryType(original_type))
+ return;
+
+ U64 folder_valid = 0;
+ U64 folder_invalid = 0;
+ LLInventoryModel::cat_array_t category_array;
+ LLInventoryModel::item_array_t item_array;
+ gInventory.collectDescendents(getUUID(),category_array,item_array,FALSE);
+
+ // For ensembles
+ if (category_array.empty())
+ {
+ for (LLInventoryModel::item_array_t::iterator item_iter = item_array.begin();
+ item_iter != item_array.end();
+ item_iter++)
+ {
+ const LLViewerInventoryItem *item = (*item_iter);
+ if (item->getIsLinkType())
+ return;
+ if (item->getInventoryType() == LLInventoryType::IT_WEARABLE)
+ {
+ const EWearableType wearable_type = EWearableType(item->getFlags() & LLInventoryItem::II_FLAGS_WEARABLES_MASK);
+ const std::string& wearable_name = LLWearableDictionary::getTypeName(wearable_type);
+ U64 valid_folder_types = LLFolderType::lookupValidFolderTypes(wearable_name);
+ folder_valid |= valid_folder_types;
+ folder_invalid |= ~valid_folder_types;
+ }
+ }
+ for (U8 i = LLAssetType::AT_FOLDER_ENSEMBLE_START; i <= LLAssetType::AT_FOLDER_ENSEMBLE_END; i++)
+ {
+ if ((folder_valid & (1LL << i)) &&
+ !(folder_invalid & (1LL << i)))
+ {
+ changeType((LLAssetType::EType)i);
+ return;
+ }
+ }
+ }
+ if (LLAssetType::lookupIsEnsembleCategoryType(original_type))
+ {
+ changeType(LLAssetType::AT_NONE);
+ }
+}
+
+void LLViewerInventoryCategory::changeType(LLAssetType::EType new_folder_type)
+{
+ const LLUUID &folder_id = getUUID();
+ const LLUUID &parent_id = getParentUUID();
+ const std::string &name = getName();
+
+ LLMessageSystem* msg = gMessageSystem;
+ msg->newMessageFast(_PREHASH_UpdateInventoryFolder);
+ msg->nextBlockFast(_PREHASH_AgentData);
+ msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
+ msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
+ msg->nextBlockFast(_PREHASH_FolderData);
+ msg->addUUIDFast(_PREHASH_FolderID, folder_id);
+ msg->addUUIDFast(_PREHASH_ParentID, parent_id);
+ msg->addS8Fast(_PREHASH_Type, new_folder_type);
+ msg->addStringFast(_PREHASH_Name, name);
+ gAgent.sendReliableMessage();
+
+ setPreferredType(new_folder_type);
+ gInventory.addChangedMask(LLInventoryObserver::LABEL, folder_id);
+ gInventory.updateLinkedObjects(folder_id);
+}
+
///----------------------------------------------------------------------------
/// Local function definitions
///----------------------------------------------------------------------------
@@ -663,13 +745,12 @@ void RezAttachmentCallback::fire(const LLUUID& inv_item)
}
}
-extern LLGestureManager gGestureManager;
void ActivateGestureCallback::fire(const LLUUID& inv_item)
{
if (inv_item.isNull())
return;
- gGestureManager.activateGesture(inv_item);
+ LLGestureManager::instance().activateGesture(inv_item);
}
void CreateGestureCallback::fire(const LLUUID& inv_item)
@@ -677,19 +758,16 @@ void CreateGestureCallback::fire(const LLUUID& inv_item)
if (inv_item.isNull())
return;
- gGestureManager.activateGesture(inv_item);
+ LLGestureManager::instance().activateGesture(inv_item);
LLViewerInventoryItem* item = gInventory.getItem(inv_item);
if (!item) return;
gInventory.updateItem(item);
gInventory.notifyObservers();
- if(!LLPreview::show(inv_item,FALSE))
- {
- LLPreviewGesture* preview = LLPreviewGesture::show(std::string("Gesture: ") + item->getName(), inv_item, LLUUID::null);
- // Force to be entirely onscreen.
- gFloaterView->adjustToFitScreen(preview, FALSE);
- }
+ LLPreviewGesture* preview = LLPreviewGesture::show(inv_item, LLUUID::null);
+ // Force to be entirely onscreen.
+ gFloaterView->adjustToFitScreen(preview, FALSE);
}
LLInventoryCallbackManager gInventoryCallbacks;
@@ -721,6 +799,16 @@ void create_inventory_item(const LLUUID& agent_id, const LLUUID& session_id,
gAgent.sendReliableMessage();
}
+void create_inventory_callingcard(const LLUUID& avatar_id, const LLUUID& parent /*= LLUUID::null*/, LLPointer<LLInventoryCallback> cb/*=NULL*/)
+{
+ std::string item_desc = avatar_id.asString();
+ std::string item_name;
+ gCacheName->getFullName(avatar_id, item_name);
+ create_inventory_item(gAgent.getID(), gAgent.getSessionID(),
+ parent, LLTransactionID::tnull, item_name, item_desc, LLAssetType::AT_CALLINGCARD,
+ LLInventoryType::IT_CALLINGCARD, NOT_WEARABLE, PERM_MOVE | PERM_TRANSFER, cb);
+}
+
void copy_inventory_item(
const LLUUID& agent_id,
const LLUUID& current_owner,
@@ -743,6 +831,32 @@ void copy_inventory_item(
gAgent.sendReliableMessage();
}
+void link_inventory_item(
+ const LLUUID& agent_id,
+ const LLUUID& item_id,
+ const LLUUID& parent_id,
+ const std::string& new_name,
+ const LLAssetType::EType asset_type,
+ LLPointer<LLInventoryCallback> cb)
+{
+ LLMessageSystem* msg = gMessageSystem;
+ msg->newMessageFast(_PREHASH_LinkInventoryItem);
+ msg->nextBlockFast(_PREHASH_AgentData);
+ {
+ msg->addUUIDFast(_PREHASH_AgentID, agent_id);
+ msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
+ }
+ msg->nextBlockFast(_PREHASH_InventoryData);
+ {
+ msg->addU32Fast(_PREHASH_CallbackID, gInventoryCallbacks.registerCB(cb));
+ msg->addUUIDFast(_PREHASH_FolderID, parent_id);
+ msg->addUUIDFast(_PREHASH_OldItemID, item_id);
+ msg->addStringFast(_PREHASH_Name, new_name);
+ msg->addU8Fast(_PREHASH_AssetType, asset_type);
+ }
+ gAgent.sendReliableMessage();
+}
+
void move_inventory_item(
const LLUUID& agent_id,
const LLUUID& session_id,
@@ -800,3 +914,311 @@ void copy_inventory_from_notecard(const LLUUID& object_id, const LLUUID& notecar
viewer_region->getCapAPI().post(request);
}
+
+void create_new_item(const std::string& name,
+ const LLUUID& parent_id,
+ LLAssetType::EType asset_type,
+ LLInventoryType::EType inv_type,
+ U32 next_owner_perm)
+{
+ std::string desc;
+ LLAssetType::generateDescriptionFor(asset_type, desc);
+ next_owner_perm = (next_owner_perm) ? next_owner_perm : PERM_MOVE | PERM_TRANSFER;
+
+
+ if (inv_type == LLInventoryType::IT_GESTURE)
+ {
+ LLPointer<LLInventoryCallback> cb = new CreateGestureCallback();
+ create_inventory_item(gAgent.getID(), gAgent.getSessionID(),
+ parent_id, LLTransactionID::tnull, name, desc, asset_type, inv_type,
+ NOT_WEARABLE, next_owner_perm, cb);
+ }
+ else
+ {
+ LLPointer<LLInventoryCallback> cb = NULL;
+ create_inventory_item(gAgent.getID(), gAgent.getSessionID(),
+ parent_id, LLTransactionID::tnull, name, desc, asset_type, inv_type,
+ NOT_WEARABLE, next_owner_perm, cb);
+ }
+
+}
+
+const std::string NEW_LSL_NAME = "New Script"; // *TODO:Translate? (probably not)
+const std::string NEW_NOTECARD_NAME = "New Note"; // *TODO:Translate? (probably not)
+const std::string NEW_GESTURE_NAME = "New Gesture"; // *TODO:Translate? (probably not)
+
+void menu_create_inventory_item(LLFolderView* folder, LLFolderBridge *bridge, const LLSD& userdata)
+{
+ std::string type = userdata.asString();
+
+ if (("category" == type) || ("current" == type) || ("outfit" == type) || ("my_otfts" == type) )
+ {
+ LLAssetType::EType a_type = LLAssetType::AT_NONE;
+ if ("current" == type)
+ a_type = LLAssetType::AT_CURRENT_OUTFIT;
+ if ("outfit" == type)
+ a_type = LLAssetType::AT_OUTFIT;
+ if ("my_otfts" == type)
+ a_type = LLAssetType::AT_MY_OUTFITS;
+ LLUUID category;
+ if (bridge)
+ {
+ category = gInventory.createNewCategory(bridge->getUUID(), a_type, LLStringUtil::null);
+ }
+ else
+ {
+ category = gInventory.createNewCategory(gInventory.getRootFolderID(), a_type, LLStringUtil::null);
+ }
+ gInventory.notifyObservers();
+ folder->setSelectionByID(category, TRUE);
+ }
+ else if ("lsl" == type)
+ {
+ LLUUID parent_id = bridge ? bridge->getUUID() : gInventory.findCategoryUUIDForType(LLAssetType::AT_LSL_TEXT);
+ create_new_item(NEW_LSL_NAME,
+ parent_id,
+ LLAssetType::AT_LSL_TEXT,
+ LLInventoryType::IT_LSL,
+ PERM_MOVE | PERM_TRANSFER);
+ }
+ else if ("notecard" == type)
+ {
+ LLUUID parent_id = bridge ? bridge->getUUID() : gInventory.findCategoryUUIDForType(LLAssetType::AT_NOTECARD);
+ create_new_item(NEW_NOTECARD_NAME,
+ parent_id,
+ LLAssetType::AT_NOTECARD,
+ LLInventoryType::IT_NOTECARD,
+ PERM_ALL);
+ }
+ else if ("gesture" == type)
+ {
+ LLUUID parent_id = bridge ? bridge->getUUID() : gInventory.findCategoryUUIDForType(LLAssetType::AT_GESTURE);
+ create_new_item(NEW_GESTURE_NAME,
+ parent_id,
+ LLAssetType::AT_GESTURE,
+ LLInventoryType::IT_GESTURE,
+ PERM_ALL);
+ }
+ else if ("shirt" == type)
+ {
+ LLUUID parent_id = bridge ? bridge->getUUID() : gInventory.findCategoryUUIDForType(LLAssetType::AT_CLOTHING);
+ LLFolderBridge::createWearable(parent_id, WT_SHIRT);
+ }
+ else if ("pants" == type)
+ {
+ LLUUID parent_id = bridge ? bridge->getUUID() : gInventory.findCategoryUUIDForType(LLAssetType::AT_CLOTHING);
+ LLFolderBridge::createWearable(parent_id, WT_PANTS);
+ }
+ else if ("shoes" == type)
+ {
+ LLUUID parent_id = bridge ? bridge->getUUID() : gInventory.findCategoryUUIDForType(LLAssetType::AT_CLOTHING);
+ LLFolderBridge::createWearable(parent_id, WT_SHOES);
+ }
+ else if ("socks" == type)
+ {
+ LLUUID parent_id = bridge ? bridge->getUUID() : gInventory.findCategoryUUIDForType(LLAssetType::AT_CLOTHING);
+ LLFolderBridge::createWearable(parent_id, WT_SOCKS);
+ }
+ else if ("jacket" == type)
+ {
+ LLUUID parent_id = bridge ? bridge->getUUID() : gInventory.findCategoryUUIDForType(LLAssetType::AT_CLOTHING);
+ LLFolderBridge::createWearable(parent_id, WT_JACKET);
+ }
+ else if ("skirt" == type)
+ {
+ LLUUID parent_id = bridge ? bridge->getUUID() : gInventory.findCategoryUUIDForType(LLAssetType::AT_CLOTHING);
+ LLFolderBridge::createWearable(parent_id, WT_SKIRT);
+ }
+ else if ("gloves" == type)
+ {
+ LLUUID parent_id = bridge ? bridge->getUUID() : gInventory.findCategoryUUIDForType(LLAssetType::AT_CLOTHING);
+ LLFolderBridge::createWearable(parent_id, WT_GLOVES);
+ }
+ else if ("undershirt" == type)
+ {
+ LLUUID parent_id = bridge ? bridge->getUUID() : gInventory.findCategoryUUIDForType(LLAssetType::AT_CLOTHING);
+ LLFolderBridge::createWearable(parent_id, WT_UNDERSHIRT);
+ }
+ else if ("underpants" == type)
+ {
+ LLUUID parent_id = bridge ? bridge->getUUID() : gInventory.findCategoryUUIDForType(LLAssetType::AT_CLOTHING);
+ LLFolderBridge::createWearable(parent_id, WT_UNDERPANTS);
+ }
+ else if ("shape" == type)
+ {
+ LLUUID parent_id = bridge ? bridge->getUUID() : gInventory.findCategoryUUIDForType(LLAssetType::AT_BODYPART);
+ LLFolderBridge::createWearable(parent_id, WT_SHAPE);
+ }
+ else if ("skin" == type)
+ {
+ LLUUID parent_id = bridge ? bridge->getUUID() : gInventory.findCategoryUUIDForType(LLAssetType::AT_BODYPART);
+ LLFolderBridge::createWearable(parent_id, WT_SKIN);
+ }
+ else if ("hair" == type)
+ {
+ LLUUID parent_id = bridge ? bridge->getUUID() : gInventory.findCategoryUUIDForType(LLAssetType::AT_BODYPART);
+ LLFolderBridge::createWearable(parent_id, WT_HAIR);
+ }
+ else if ("eyes" == type)
+ {
+ LLUUID parent_id = bridge ? bridge->getUUID() : gInventory.findCategoryUUIDForType(LLAssetType::AT_BODYPART);
+ LLFolderBridge::createWearable(parent_id, WT_EYES);
+ }
+
+ folder->setNeedsAutoRename(TRUE);
+}
+
+LLAssetType::EType LLViewerInventoryItem::getType() const
+{
+ if (const LLViewerInventoryItem *linked_item = getLinkedItem())
+ {
+ return linked_item->getType();
+ }
+ if (const LLViewerInventoryCategory *linked_category = getLinkedCategory())
+ {
+ return linked_category->getType();
+ }
+ return LLInventoryItem::getType();
+}
+
+const LLUUID& LLViewerInventoryItem::getAssetUUID() const
+{
+ if (const LLViewerInventoryItem *linked_item = getLinkedItem())
+ {
+ return linked_item->getAssetUUID();
+ }
+
+ return LLInventoryItem::getAssetUUID();
+}
+
+const std::string& LLViewerInventoryItem::getName() const
+{
+ if (const LLViewerInventoryItem *linked_item = getLinkedItem())
+ {
+ return linked_item->getName();
+ }
+ if (const LLViewerInventoryCategory *linked_category = getLinkedCategory())
+ {
+ return linked_category->getName();
+ }
+
+ return LLInventoryItem::getName();
+}
+
+const LLPermissions& LLViewerInventoryItem::getPermissions() const
+{
+ if (const LLViewerInventoryItem *linked_item = getLinkedItem())
+ {
+ return linked_item->getPermissions();
+ }
+
+ // Use the actual permissions of the symlink, not its parent.
+ return LLInventoryItem::getPermissions();
+}
+
+const LLUUID& LLViewerInventoryItem::getCreatorUUID() const
+{
+ if (const LLViewerInventoryItem *linked_item = getLinkedItem())
+ {
+ return linked_item->getCreatorUUID();
+ }
+
+ return LLInventoryItem::getCreatorUUID();
+}
+
+const std::string& LLViewerInventoryItem::getDescription() const
+{
+ if (const LLViewerInventoryItem *linked_item = getLinkedItem())
+ {
+ return linked_item->getDescription();
+ }
+
+ return LLInventoryItem::getDescription();
+}
+
+const LLSaleInfo& LLViewerInventoryItem::getSaleInfo() const
+{
+ if (const LLViewerInventoryItem *linked_item = getLinkedItem())
+ {
+ return linked_item->getSaleInfo();
+ }
+
+ return LLInventoryItem::getSaleInfo();
+}
+
+LLInventoryType::EType LLViewerInventoryItem::getInventoryType() const
+{
+ if (const LLViewerInventoryItem *linked_item = getLinkedItem())
+ {
+ return linked_item->getInventoryType();
+ }
+
+ // Categories don't have types. If this item is an AT_FOLDER_LINK,
+ // treat it as a category.
+ if (getLinkedCategory())
+ {
+ return LLInventoryType::IT_CATEGORY;
+ }
+
+ return LLInventoryItem::getInventoryType();
+}
+
+U32 LLViewerInventoryItem::getFlags() const
+{
+ if (const LLViewerInventoryItem *linked_item = getLinkedItem())
+ {
+ return linked_item->getFlags();
+ }
+ return LLInventoryItem::getFlags();
+}
+
+time_t LLViewerInventoryItem::getCreationDate() const
+{
+ return LLInventoryItem::getCreationDate();
+}
+
+U32 LLViewerInventoryItem::getCRC32() const
+{
+ return LLInventoryItem::getCRC32();
+}
+
+// This returns true if the item that this item points to
+// doesn't exist in memory (i.e. LLInventoryModel). The baseitem
+// might still be in the database but just not loaded yet.
+bool LLViewerInventoryItem::getIsBrokenLink() const
+{
+ // If the item's type resolves to be a link, that means either:
+ // A. It wasn't able to perform indirection, i.e. the baseobj doesn't exist in memory.
+ // B. It's pointing to another link, which is illegal.
+ return LLAssetType::lookupIsLinkType(getType());
+}
+
+const LLViewerInventoryItem *LLViewerInventoryItem::getLinkedItem() const
+{
+ if (mType == LLAssetType::AT_LINK)
+ {
+ const LLViewerInventoryItem *linked_item = gInventory.getItem(mAssetUUID);
+ return linked_item;
+ }
+ return NULL;
+}
+
+const LLViewerInventoryCategory *LLViewerInventoryItem::getLinkedCategory() const
+{
+ if (mType == LLAssetType::AT_LINK_FOLDER)
+ {
+ const LLViewerInventoryCategory *linked_category = gInventory.getCategory(mAssetUUID);
+ return linked_category;
+ }
+ return NULL;
+}
+
+//----------
+
+void LLViewerInventoryItem::onCallingCardNameLookup(const LLUUID& id, const std::string& first_name, const std::string& last_name)
+{
+ rename(first_name + " " + last_name);
+ gInventory.addChangedMask(LLInventoryObserver::LABEL, getUUID());
+ gInventory.notifyObservers();
+}
+
diff --git a/indra/newview/llviewerinventory.h b/indra/newview/llviewerinventory.h
index 1ddf8a58f9..0bfb37f7e8 100644
--- a/indra/newview/llviewerinventory.h
+++ b/indra/newview/llviewerinventory.h
@@ -37,6 +37,10 @@
#include "llframetimer.h"
#include "llwearable.h"
+class LLFolderView;
+class LLFolderBridge;
+class LLViewerInventoryCategory;
+
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Class LLViewerInventoryItem
//
@@ -44,7 +48,7 @@
// their inventory.
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-class LLViewerInventoryItem : public LLInventoryItem
+class LLViewerInventoryItem : public LLInventoryItem, public boost::signals2::trackable
{
public:
typedef LLDynamicArray<LLPointer<LLViewerInventoryItem> > item_array_t;
@@ -53,6 +57,18 @@ protected:
~LLViewerInventoryItem( void ); // ref counted
public:
+ virtual LLAssetType::EType getType() const;
+ virtual const LLUUID& getAssetUUID() const;
+ virtual const std::string& getName() const;
+ virtual const LLPermissions& getPermissions() const;
+ virtual const LLUUID& getCreatorUUID() const;
+ virtual const std::string& getDescription() const;
+ virtual const LLSaleInfo& getSaleInfo() const;
+ virtual LLInventoryType::EType getInventoryType() const;
+ virtual U32 getFlags() const;
+ virtual time_t getCreationDate() const;
+ virtual U32 getCRC32() const; // really more of a checksum.
+
// construct a complete viewer inventory item
LLViewerInventoryItem(const LLUUID& uuid, const LLUUID& parent_uuid,
const LLPermissions& permissions,
@@ -125,7 +141,14 @@ public:
};
LLTransactionID getTransactionID() const { return mTransactionID; }
-protected:
+ bool getIsBrokenLink() const; // true if the baseitem this points to doesn't exist in memory.
+ const LLViewerInventoryItem *getLinkedItem() const;
+ const LLViewerInventoryCategory *getLinkedCategory() const;
+
+ // callback
+ void onCallingCardNameLookup(const LLUUID& id, const std::string& first_name, const std::string& last_name);
+
+public:
BOOL mIsComplete;
LLTransactionID mTransactionID;
};
@@ -184,7 +207,8 @@ public:
// other than cacheing.
bool exportFileLocal(LLFILE* fp) const;
bool importFileLocal(LLFILE* fp);
-
+ void determineFolderType();
+ void changeType(LLAssetType::EType new_folder_type);
protected:
LLUUID mOwnerID;
S32 mVersion;
@@ -253,6 +277,7 @@ extern LLInventoryCallbackManager gInventoryCallbacks;
#define NOT_WEARABLE (EWearableType)0
+// *TODO: Find a home for these
void create_inventory_item(const LLUUID& agent_id, const LLUUID& session_id,
const LLUUID& parent, const LLTransactionID& transaction_id,
const std::string& name,
@@ -261,6 +286,8 @@ void create_inventory_item(const LLUUID& agent_id, const LLUUID& session_id,
U32 next_owner_perm,
LLPointer<LLInventoryCallback> cb);
+void create_inventory_callingcard(const LLUUID& avatar_id, const LLUUID& parent = LLUUID::null, LLPointer<LLInventoryCallback> cb=NULL);
+
/**
* @brief Securely create a new inventory item by copying from another.
*/
@@ -272,6 +299,14 @@ void copy_inventory_item(
const std::string& new_name,
LLPointer<LLInventoryCallback> cb);
+void link_inventory_item(
+ const LLUUID& agent_id,
+ const LLUUID& item_id,
+ const LLUUID& parent_id,
+ const std::string& new_name,
+ const LLAssetType::EType asset_type,
+ LLPointer<LLInventoryCallback> cb);
+
void move_inventory_item(
const LLUUID& agent_id,
const LLUUID& session_id,
@@ -286,4 +321,8 @@ void copy_inventory_from_notecard(const LLUUID& object_id,
U32 callback_id = 0);
+void menu_create_inventory_item(LLFolderView* folder,
+ LLFolderBridge* bridge,
+ const LLSD& userdata);
+
#endif // LL_LLVIEWERINVENTORY_H
diff --git a/indra/newview/llviewerjointattachment.h b/indra/newview/llviewerjointattachment.h
index 4847ac7a72..c003579684 100644
--- a/indra/newview/llviewerjointattachment.h
+++ b/indra/newview/llviewerjointattachment.h
@@ -71,20 +71,20 @@ public:
void setPieSlice(S32 pie_slice) { mPieSlice = pie_slice; }
void setVisibleInFirstPerson(BOOL visibility) { mVisibleInFirst = visibility; }
- BOOL getVisibleInFirstPerson() { return mVisibleInFirst; }
+ BOOL getVisibleInFirstPerson() const { return mVisibleInFirst; }
void setGroup(S32 group) { mGroup = group; }
void setOriginalPosition(LLVector3 &position);
void setAttachmentVisibility(BOOL visible);
void setIsHUDAttachment(BOOL is_hud) { mIsHUDAttachment = is_hud; }
- BOOL getIsHUDAttachment() { return mIsHUDAttachment; }
+ BOOL getIsHUDAttachment() const { return mIsHUDAttachment; }
- BOOL isAnimatable() { return FALSE; }
+ BOOL isAnimatable() const { return FALSE; }
- S32 getGroup() { return mGroup; }
- S32 getPieSlice() { return mPieSlice; }
- LLViewerObject *getObject() { return mAttachedObject; }
- S32 getNumObjects() { return (mAttachedObject ? 1 : 0); }
- const LLUUID& getItemID() { return mItemID; }
+ S32 getGroup() const { return mGroup; }
+ S32 getPieSlice() const { return mPieSlice; }
+ LLViewerObject *getObject() const { return mAttachedObject; }
+ S32 getNumObjects() const { return (mAttachedObject ? 1 : 0); }
+ const LLUUID& getItemID() const { return mItemID; }
//
// unique methods
diff --git a/indra/newview/llviewerjointmesh.cpp b/indra/newview/llviewerjointmesh.cpp
index b6f0dafae6..28f883312a 100644
--- a/indra/newview/llviewerjointmesh.cpp
+++ b/indra/newview/llviewerjointmesh.cpp
@@ -39,7 +39,6 @@
#include "llfasttimer.h"
#include "llrender.h"
-#include "llagent.h"
#include "llapr.h"
#include "llbox.h"
#include "lldrawable.h"
@@ -52,7 +51,7 @@
#include "lltexlayer.h"
#include "llviewercamera.h"
#include "llviewercontrol.h"
-#include "llviewerimagelist.h"
+#include "llviewertexturelist.h"
#include "llviewerjointmesh.h"
#include "llvoavatar.h"
#include "llsky.h"
@@ -230,7 +229,7 @@ void LLViewerJointMesh::setColor( F32 red, F32 green, F32 blue, F32 alpha )
//--------------------------------------------------------------------
// LLViewerJointMesh::getTexture()
//--------------------------------------------------------------------
-//LLViewerImage *LLViewerJointMesh::getTexture()
+//LLViewerTexture *LLViewerJointMesh::getTexture()
//{
// return mTexture;
//}
@@ -238,7 +237,7 @@ void LLViewerJointMesh::setColor( F32 red, F32 green, F32 blue, F32 alpha )
//--------------------------------------------------------------------
// LLViewerJointMesh::setTexture()
//--------------------------------------------------------------------
-void LLViewerJointMesh::setTexture( LLViewerImage *texture )
+void LLViewerJointMesh::setTexture( LLViewerTexture *texture )
{
mTexture = texture;
@@ -557,7 +556,7 @@ U32 LLViewerJointMesh::drawShape( F32 pixelArea, BOOL first_pass, BOOL is_dummy)
{
if( mLayerSet->hasComposite() )
{
- gGL.getTexUnit(0)->bind(mLayerSet->getComposite()->getTexture());
+ gGL.getTexUnit(0)->bind(mLayerSet->getComposite());
}
else
{
@@ -567,19 +566,22 @@ U32 LLViewerJointMesh::drawShape( F32 pixelArea, BOOL first_pass, BOOL is_dummy)
{
llwarns << "Layerset without composite" << llendl;
}
- gGL.getTexUnit(0)->bind(gImageList.getImage(IMG_DEFAULT));
+ gGL.getTexUnit(0)->bind(LLViewerTextureManager::getFetchedTexture(IMG_DEFAULT));
}
}
else
if ( !is_dummy && mTexture.notNull() )
{
- old_mode = mTexture->getAddressMode();
- gGL.getTexUnit(0)->bind(mTexture.get());
+ if(mTexture->hasGLTexture())
+ {
+ old_mode = mTexture->getAddressMode();
+ }
+ gGL.getTexUnit(0)->bind(mTexture);
gGL.getTexUnit(0)->setTextureAddressMode(LLTexUnit::TAM_CLAMP);
}
else
{
- gGL.getTexUnit(0)->bind(gImageList.getImage(IMG_DEFAULT_AVATAR));
+ gGL.getTexUnit(0)->bind(LLViewerTextureManager::getFetchedTexture(IMG_DEFAULT_AVATAR));
}
if (gRenderForSelect)
@@ -633,7 +635,7 @@ U32 LLViewerJointMesh::drawShape( F32 pixelArea, BOOL first_pass, BOOL is_dummy)
if (mTexture.notNull() && !is_dummy)
{
- gGL.getTexUnit(0)->bind(mTexture.get());
+ gGL.getTexUnit(0)->bind(mTexture);
gGL.getTexUnit(0)->setTextureAddressMode(old_mode);
}
diff --git a/indra/newview/llviewerjointmesh.h b/indra/newview/llviewerjointmesh.h
index 0cae48df93..543679c44b 100644
--- a/indra/newview/llviewerjointmesh.h
+++ b/indra/newview/llviewerjointmesh.h
@@ -34,7 +34,7 @@
#define LL_LLVIEWERJOINTMESH_H
#include "llviewerjoint.h"
-#include "llviewerimage.h"
+#include "llviewertexture.h"
#include "llpolymesh.h"
#include "v4color.h"
#include "llapr.h"
@@ -72,7 +72,7 @@ protected:
LLColor4 mColor; // color value
// LLColor4 mSpecular; // specular color (always white for now)
F32 mShiny; // shiny value
- LLPointer<LLViewerImage> mTexture; // ptr to a global texture
+ LLPointer<LLViewerTexture> mTexture; // ptr to a global texture
LLTexLayerSet* mLayerSet; // ptr to a layer set owned by the avatar
U32 mTestImageName; // handle to a temporary texture for previewing uploads
LLPolyMesh* mMesh; // ptr to a global polymesh
@@ -110,7 +110,7 @@ public:
void setSpecular( const LLColor4& color, F32 shiny ) { /*mSpecular = color;*/ mShiny = shiny; };
// Sets the shape texture
- void setTexture( LLViewerImage *texture );
+ void setTexture( LLViewerTexture *texture );
void setTestTexture( U32 name ) { mTestImageName = name; }
@@ -148,7 +148,7 @@ public:
void setIsTransparent(BOOL is_transparent) { mIsTransparent = is_transparent; }
- /*virtual*/ BOOL isAnimatable() { return FALSE; }
+ /*virtual*/ BOOL isAnimatable() const { return FALSE; }
static void updateVectorize(); // Update globals when settings variables change
diff --git a/indra/newview/llviewerkeyboard.cpp b/indra/newview/llviewerkeyboard.cpp
index 15c814829c..fc2f00a2ea 100644
--- a/indra/newview/llviewerkeyboard.cpp
+++ b/indra/newview/llviewerkeyboard.cpp
@@ -36,14 +36,15 @@
#include "llviewerkeyboard.h"
#include "llmath.h"
#include "llagent.h"
-#include "llchatbar.h"
+#include "llnearbychatbar.h"
#include "llviewercontrol.h"
#include "llfocusmgr.h"
#include "llmorphview.h"
#include "llmoveview.h"
#include "lltoolfocus.h"
#include "llviewerwindow.h"
-#include "llvoavatar.h"
+#include "llvoavatarself.h"
+#include "llfloatercamera.h"
//
// Constants
@@ -135,14 +136,29 @@ static void agent_push_forwardbackward( EKeystate s, S32 direction, LLAgent::EDo
}
}
+void camera_move_forward( EKeystate s );
+
void agent_push_forward( EKeystate s )
{
+ //in free camera control mode we need to intercept keyboard events for avatar movements
+ if (LLFloaterCamera::inFreeCameraMode())
+ {
+ camera_move_forward(s);
+ return;
+ }
agent_push_forwardbackward(s, 1, LLAgent::DOUBLETAP_FORWARD);
}
+void camera_move_backward( EKeystate s );
void agent_push_backward( EKeystate s )
{
+ //in free camera control mode we need to intercept keyboard events for avatar movements
+ if (LLFloaterCamera::inFreeCameraMode())
+ {
+ camera_move_backward(s);
+ return;
+ }
agent_push_forwardbackward(s, -1, LLAgent::DOUBLETAP_BACKWARD);
}
@@ -175,8 +191,17 @@ void agent_slide_right( EKeystate s )
agent_slide_leftright(s, -1, LLAgent::DOUBLETAP_SLIDERIGHT);
}
+void camera_spin_around_cw( EKeystate s );
+
void agent_turn_left( EKeystate s )
{
+ //in free camera control mode we need to intercept keyboard events for avatar movements
+ if (LLFloaterCamera::inFreeCameraMode())
+ {
+ camera_spin_around_cw(s);
+ return;
+ }
+
if (LLToolCamera::getInstance()->mouseSteerMode())
{
agent_slide_left(s);
@@ -189,9 +214,17 @@ void agent_turn_left( EKeystate s )
}
}
+void camera_spin_around_ccw( EKeystate s );
void agent_turn_right( EKeystate s )
{
+ //in free camera control mode we need to intercept keyboard events for avatar movements
+ if (LLFloaterCamera::inFreeCameraMode())
+ {
+ camera_spin_around_ccw(s);
+ return;
+ }
+
if (LLToolCamera::getInstance()->mouseSteerMode())
{
agent_slide_right(s);
@@ -224,7 +257,7 @@ void agent_toggle_fly( EKeystate s )
// Only catch the edge
if (KEYSTATE_DOWN == s )
{
- gAgent.toggleFlying();
+ LLAgent::toggleFlying();
}
}
@@ -500,24 +533,24 @@ void stop_moving( EKeystate s )
void start_chat( EKeystate s )
{
// start chat
- gChatBar->startChat(NULL);
+ LLNearbyChatBar::startChat(NULL);
}
void start_gesture( EKeystate s )
{
if (KEYSTATE_UP == s &&
- !(gFocusMgr.getKeyboardFocus() && gFocusMgr.getKeyboardFocus()->acceptsTextInput()))
+ !(gFocusMgr.getKeyboardFocus() && dynamic_cast<LLUICtrl*>(gFocusMgr.getKeyboardFocus())->acceptsTextInput()))
{
- if (gChatBar->getCurrentChat().empty())
- {
- // No existing chat in chat editor, insert '/'
- gChatBar->startChat("/");
- }
- else
- {
- // Don't overwrite existing text in chat editor
- gChatBar->startChat(NULL);
- }
+ if (LLNearbyChatBar::getInstance()->getCurrentChat().empty())
+ {
+ // No existing chat in chat editor, insert '/'
+ LLNearbyChatBar::startChat("/");
+ }
+ else
+ {
+ // Don't overwrite existing text in chat editor
+ LLNearbyChatBar::startChat(NULL);
+ }
}
}
@@ -842,7 +875,7 @@ EKeyboardMode LLViewerKeyboard::getMode()
{
return MODE_EDIT_AVATAR;
}
- else if (gAgent.getAvatarObject() && gAgent.getAvatarObject()->mIsSitting)
+ else if (gAgent.getAvatarObject() && gAgent.getAvatarObject()->isSitting())
{
return MODE_SITTING;
}
diff --git a/indra/newview/llviewermedia.cpp b/indra/newview/llviewermedia.cpp
index 82f8359732..a06d913fd6 100644
--- a/indra/newview/llviewermedia.cpp
+++ b/indra/newview/llviewermedia.cpp
@@ -33,674 +33,1181 @@
#include "llviewerprecompiledheaders.h"
#include "llviewermedia.h"
-
+#include "llviewermediafocus.h"
+#include "llhoverview.h"
#include "llmimetypes.h"
#include "llviewercontrol.h"
-#include "llviewerimage.h"
+#include "llviewertexture.h"
+#include "llviewerparcelmedia.h"
+#include "llviewerparcelmgr.h"
#include "llviewerwindow.h"
#include "llversionviewer.h"
-#include "llviewerimagelist.h"
+#include "llviewertexturelist.h"
+#include "llpluginclassmedia.h"
#include "llevent.h" // LLSimpleListener
-#include "llmediamanager.h"
#include "lluuid.h"
#include <boost/bind.hpp> // for SkinFolder listener
#include <boost/signals2.hpp>
+// Move this to its own file.
-// Implementation functions not exported into header file
-class LLViewerMediaImpl
- : public LLMediaObserver
+LLViewerMediaEventEmitter::~LLViewerMediaEventEmitter()
{
- public:
- LLViewerMediaImpl()
- : mMediaSource( NULL ),
- mMovieImageID(),
- mMovieImageHasMips(false)
- { }
-
- void destroyMediaSource();
-
- void play(const std::string& media_url,
- const std::string& mime_type,
- const LLUUID& placeholder_texture_id,
- S32 media_width, S32 media_height, U8 media_auto_scale,
- U8 media_loop);
-
- void stop();
- void pause();
- void start();
- void seek(F32 time);
- void setVolume(F32 volume);
- LLMediaBase::EStatus getStatus();
-
- /*virtual*/ void onMediaSizeChange(const EventType& event_in);
- /*virtual*/ void onMediaContentsChange(const EventType& event_in);
-
- void updateMovieImage(const LLUUID& image_id, BOOL active);
- void updateImagesMediaStreams();
- LLUUID getMediaTextureID();
-
- // Internally set our desired browser user agent string, including
- // the Second Life version and skin name. Used because we can
- // switch skins without restarting the app.
- static void updateBrowserUserAgent();
-
- // Callback for when the SkinCurrent control is changed to
- // switch the user agent string to indicate the new skin.
- static bool handleSkinCurrentChanged(const LLSD& newvalue);
+ observerListType::iterator iter = mObservers.begin();
- public:
+ while( iter != mObservers.end() )
+ {
+ LLViewerMediaObserver *self = *iter;
+ iter++;
+ remObserver(self);
+ }
+}
- // a single media url with some data and an impl.
- LLMediaBase* mMediaSource;
- LLUUID mMovieImageID;
- bool mMovieImageHasMips;
- std::string mMediaURL;
- std::string mMimeType;
- private:
- void initializePlaceholderImage(LLViewerImage *placeholder_image, LLMediaBase *media_source);
-};
+///////////////////////////////////////////////////////////////////////////////
+//
+bool LLViewerMediaEventEmitter::addObserver( LLViewerMediaObserver* observer )
+{
+ if ( ! observer )
+ return false;
-static LLViewerMediaImpl sViewerMediaImpl;
+ if ( std::find( mObservers.begin(), mObservers.end(), observer ) != mObservers.end() )
+ return false;
-//////////////////////////////////////////////////////////////////////////////////////////
+ mObservers.push_back( observer );
+ observer->mEmitters.push_back( this );
-void LLViewerMediaImpl::destroyMediaSource()
+ return true;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+//
+bool LLViewerMediaEventEmitter::remObserver( LLViewerMediaObserver* observer )
{
- LLMediaManager* mgr = LLMediaManager::getInstance();
- if ( mMediaSource )
+ if ( ! observer )
+ return false;
+
+ mObservers.remove( observer );
+ observer->mEmitters.remove(this);
+
+ return true;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+//
+void LLViewerMediaEventEmitter::emitEvent( LLPluginClassMedia* media, LLPluginClassMediaOwner::EMediaEvent event )
+{
+ observerListType::iterator iter = mObservers.begin();
+
+ while( iter != mObservers.end() )
{
- bool was_playing = LLViewerMedia::isMediaPlaying();
- mMediaSource->remObserver(this);
- mgr->destroySource( mMediaSource );
+ LLViewerMediaObserver *self = *iter;
+ ++iter;
+ self->handleMediaEvent( media, event );
+ }
+}
- // Restore the texture
- updateMovieImage(LLUUID::null, was_playing);
+// Move this to its own file.
+LLViewerMediaObserver::~LLViewerMediaObserver()
+{
+ std::list<LLViewerMediaEventEmitter *>::iterator iter = mEmitters.begin();
+ while( iter != mEmitters.end() )
+ {
+ LLViewerMediaEventEmitter *self = *iter;
+ iter++;
+ self->remObserver( this );
}
- mMediaSource = NULL;
}
-void LLViewerMediaImpl::play(const std::string& media_url,
- const std::string& mime_type,
- const LLUUID& placeholder_texture_id,
- S32 media_width, S32 media_height, U8 media_auto_scale,
- U8 media_loop)
+
+// Move this to its own file.
+// helper class that tries to download a URL from a web site and calls a method
+// on the Panel Land Media and to discover the MIME type
+class LLMimeDiscoveryResponder : public LLHTTPClient::Responder
{
- // first stop any previously playing media
- stop();
+LOG_CLASS(LLMimeDiscoveryResponder);
+public:
+ LLMimeDiscoveryResponder( viewer_media_t media_impl)
+ : mMediaImpl(media_impl),
+ mInitialized(false)
+ {}
+
+
- // Save this first, as init/load below may fire events
- mMovieImageID = placeholder_texture_id;
+ virtual void completedHeader(U32 status, const std::string& reason, const LLSD& content)
+ {
+ std::string media_type = content["content-type"].asString();
+ std::string::size_type idx1 = media_type.find_first_of(";");
+ std::string mime_type = media_type.substr(0, idx1);
+ completeAny(status, mime_type);
+ }
- // If the mime_type passed in is different than the cached one, and
- // Auto-discovery is turned OFF, replace the cached mime_type with the new one.
- if(mime_type != mMimeType &&
- ! gSavedSettings.getBOOL("AutoMimeDiscovery"))
+ virtual void error( U32 status, const std::string& reason )
{
- mMimeType = mime_type;
+ // completeAny(status, "none/none");
}
- LLURI url(media_url);
- std::string scheme = url.scheme() != "" ? url.scheme() : "http";
- LLMediaManager* mgr = LLMediaManager::getInstance();
- mMediaSource = mgr->createSourceFromMimeType(scheme, mMimeType );
- if ( !mMediaSource )
+ void completeAny(U32 status, const std::string& mime_type)
{
- if (mMimeType != "none/none")
+ if(!mInitialized && ! mime_type.empty())
{
- llwarns << "media source create failed " << media_url
- << " type " << mMimeType
- << llendl;
+ if (mMediaImpl->initializeMedia(mime_type))
+ {
+ mInitialized = true;
+ mMediaImpl->play();
+ }
}
- return;
}
- // Store the URL and Mime Type
- mMediaURL = media_url;
+ public:
+ viewer_media_t mMediaImpl;
+ bool mInitialized;
+};
+typedef std::vector<LLViewerMediaImpl*> impl_list;
+static impl_list sViewerMediaImplList;
+
+//////////////////////////////////////////////////////////////////////////////////////////
+// LLViewerMedia
- if ((media_width != 0) && (media_height != 0))
+//////////////////////////////////////////////////////////////////////////////////////////
+// static
+viewer_media_t LLViewerMedia::newMediaImpl(const std::string& media_url,
+ const LLUUID& texture_id,
+ S32 media_width, S32 media_height, U8 media_auto_scale,
+ U8 media_loop,
+ std::string mime_type)
+{
+ LLViewerMediaImpl* media_impl = getMediaImplFromTextureID(texture_id);
+ if(media_impl == NULL || texture_id.isNull())
{
- mMediaSource->setRequestedMediaSize(media_width, media_height);
+ // Create the media impl
+ media_impl = new LLViewerMediaImpl(media_url, texture_id, media_width, media_height, media_auto_scale, media_loop, mime_type);
+ sViewerMediaImplList.push_back(media_impl);
}
-
- mMediaSource->setLooping(media_loop);
- mMediaSource->setAutoScaled(media_auto_scale);
- mMediaSource->addObserver( this );
- mMediaSource->navigateTo( media_url );
- mMediaSource->addCommand(LLMediaBase::COMMAND_START);
+ else
+ {
+ media_impl->stop();
+ media_impl->mTextureId = texture_id;
+ media_impl->mMediaURL = media_url;
+ media_impl->mMediaWidth = media_width;
+ media_impl->mMediaHeight = media_height;
+ media_impl->mMediaAutoScale = media_auto_scale;
+ media_impl->mMediaLoop = media_loop;
+ if(! media_url.empty())
+ media_impl->navigateTo(media_url, mime_type, true);
+ }
+ return media_impl;
}
-void LLViewerMediaImpl::stop()
+//////////////////////////////////////////////////////////////////////////////////////////
+// static
+void LLViewerMedia::removeMedia(LLViewerMediaImpl* media)
{
- destroyMediaSource();
+ impl_list::iterator iter = sViewerMediaImplList.begin();
+ impl_list::iterator end = sViewerMediaImplList.end();
+
+ for(; iter != end; iter++)
+ {
+ if(media == *iter)
+ {
+ sViewerMediaImplList.erase(iter);
+ return;
+ }
+ }
}
-void LLViewerMediaImpl::pause()
+//////////////////////////////////////////////////////////////////////////////////////////
+// static
+LLViewerMediaImpl* LLViewerMedia::getMediaImplFromTextureID(const LLUUID& texture_id)
{
- if(mMediaSource)
+ impl_list::iterator iter = sViewerMediaImplList.begin();
+ impl_list::iterator end = sViewerMediaImplList.end();
+
+ for(; iter != end; iter++)
{
- mMediaSource->addCommand(LLMediaBase::COMMAND_PAUSE);
+ LLViewerMediaImpl* media_impl = *iter;
+ if(media_impl->getMediaTextureID() == texture_id)
+ {
+ return media_impl;
+ }
}
+ return NULL;
}
-void LLViewerMediaImpl::start()
+//////////////////////////////////////////////////////////////////////////////////////////
+// static
+std::string LLViewerMedia::getCurrentUserAgent()
{
- if(mMediaSource)
+ // Don't use user-visible string to avoid
+ // punctuation and strange characters.
+ std::string skin_name = gSavedSettings.getString("SkinCurrent");
+
+ // Just in case we need to check browser differences in A/B test
+ // builds.
+ std::string channel = gSavedSettings.getString("VersionChannelName");
+
+ // append our magic version number string to the browser user agent id
+ // See the HTTP 1.0 and 1.1 specifications for allowed formats:
+ // http://www.ietf.org/rfc/rfc1945.txt section 10.15
+ // http://www.ietf.org/rfc/rfc2068.txt section 3.8
+ // This was also helpful:
+ // http://www.mozilla.org/build/revised-user-agent-strings.html
+ std::ostringstream codec;
+ codec << "SecondLife/";
+ codec << LL_VERSION_MAJOR << "." << LL_VERSION_MINOR << "." << LL_VERSION_PATCH << "." << LL_VERSION_BUILD;
+ codec << " (" << channel << "; " << skin_name << " skin)";
+ llinfos << codec.str() << llendl;
+
+ return codec.str();
+}
+
+//////////////////////////////////////////////////////////////////////////////////////////
+// static
+void LLViewerMedia::updateBrowserUserAgent()
+{
+ std::string user_agent = getCurrentUserAgent();
+
+ impl_list::iterator iter = sViewerMediaImplList.begin();
+ impl_list::iterator end = sViewerMediaImplList.end();
+
+ for(; iter != end; iter++)
{
- mMediaSource->addCommand(LLMediaBase::COMMAND_START);
+ LLViewerMediaImpl* pimpl = *iter;
+ if(pimpl->mMediaSource && pimpl->mMediaSource->pluginSupportsMediaBrowser())
+ {
+ pimpl->mMediaSource->setBrowserUserAgent(user_agent);
+ }
}
+
}
-void LLViewerMediaImpl::seek(F32 time)
+//////////////////////////////////////////////////////////////////////////////////////////
+// static
+bool LLViewerMedia::handleSkinCurrentChanged(const LLSD& /*newvalue*/)
{
- if(mMediaSource)
+ // gSavedSettings is already updated when this function is called.
+ updateBrowserUserAgent();
+ return true;
+}
+
+//////////////////////////////////////////////////////////////////////////////////////////
+// static
+bool LLViewerMedia::textureHasMedia(const LLUUID& texture_id)
+{
+ impl_list::iterator iter = sViewerMediaImplList.begin();
+ impl_list::iterator end = sViewerMediaImplList.end();
+
+ for(; iter != end; iter++)
{
- mMediaSource->seek(time);
+ LLViewerMediaImpl* pimpl = *iter;
+ if(pimpl->getMediaTextureID() == texture_id)
+ {
+ return true;
+ }
}
+ return false;
}
-void LLViewerMediaImpl::setVolume(F32 volume)
+//////////////////////////////////////////////////////////////////////////////////////////
+// static
+void LLViewerMedia::setVolume(F32 volume)
{
- if(mMediaSource)
+ impl_list::iterator iter = sViewerMediaImplList.begin();
+ impl_list::iterator end = sViewerMediaImplList.end();
+
+ for(; iter != end; iter++)
{
- mMediaSource->setVolume( volume);
+ LLViewerMediaImpl* pimpl = *iter;
+ pimpl->setVolume(volume);
}
}
-LLMediaBase::EStatus LLViewerMediaImpl::getStatus()
+//////////////////////////////////////////////////////////////////////////////////////////
+// static
+void LLViewerMedia::updateMedia()
{
- if (mMediaSource)
+ impl_list::iterator iter = sViewerMediaImplList.begin();
+ impl_list::iterator end = sViewerMediaImplList.end();
+
+ for(; iter != end; iter++)
{
- return mMediaSource->getStatus();
+ LLViewerMediaImpl* pimpl = *iter;
+ pimpl->update();
}
- else
+}
+
+//////////////////////////////////////////////////////////////////////////////////////////
+// static
+void LLViewerMedia::cleanupClass()
+{
+ // This is no longer necessary, since the list is no longer smart pointers.
+#if 0
+ while(!sViewerMediaImplList.empty())
{
- return LLMediaBase::STATUS_UNKNOWN;
+ sViewerMediaImplList.pop_back();
}
+#endif
}
//////////////////////////////////////////////////////////////////////////////////////////
-// static
-void LLViewerMediaImpl::updateMovieImage(const LLUUID& uuid, BOOL active)
+// LLViewerMediaImpl
+//////////////////////////////////////////////////////////////////////////////////////////
+LLViewerMediaImpl::LLViewerMediaImpl(const std::string& media_url,
+ const LLUUID& texture_id,
+ S32 media_width,
+ S32 media_height,
+ U8 media_auto_scale,
+ U8 media_loop,
+ const std::string& mime_type)
+:
+ mMediaSource( NULL ),
+ mMovieImageHasMips(false),
+ mTextureId(texture_id),
+ mMediaWidth(media_width),
+ mMediaHeight(media_height),
+ mMediaAutoScale(media_auto_scale),
+ mMediaLoop(media_loop),
+ mMediaURL(media_url),
+ mMimeType(mime_type),
+ mNeedsNewTexture(true),
+ mSuspendUpdates(false),
+ mVisible(true)
+{
+ createMediaSource();
+}
+
+//////////////////////////////////////////////////////////////////////////////////////////
+LLViewerMediaImpl::~LLViewerMediaImpl()
{
- // IF the media image hasn't changed, do nothing
- if (mMovieImageID == uuid)
+ if( gEditMenuHandler == this )
{
- return;
+ gEditMenuHandler = NULL;
}
- // If we have changed media uuid, restore the old one
- if (!mMovieImageID.isNull())
+
+ destroyMediaSource();
+ LLViewerMedia::removeMedia(this);
+}
+
+//////////////////////////////////////////////////////////////////////////////////////////
+bool LLViewerMediaImpl::initializeMedia(const std::string& mime_type)
+{
+ if((mMediaSource == NULL) || (mMimeType != mime_type))
{
- LLViewerImage* oldImage = LLViewerImage::getImage( mMovieImageID );
- if (oldImage)
+ if(! initializePlugin(mime_type))
{
- oldImage->reinit(mMovieImageHasMips);
- oldImage->mIsMediaTexture = FALSE;
+ LL_WARNS("Plugin") << "plugin intialization failed for mime type: " << mime_type << LL_ENDL;
+ LLSD args;
+ args["MIME_TYPE"] = mime_type;
+ LLNotifications::instance().add("NoPlugin", args);
+
+ return false;
}
- mMovieImageID.setNull();
}
- // If the movie is playing, set the new media image
- if (active && !uuid.isNull())
+
+ // play();
+ return (mMediaSource != NULL);
+}
+
+//////////////////////////////////////////////////////////////////////////////////////////
+void LLViewerMediaImpl::createMediaSource()
+{
+ if(! mMediaURL.empty())
{
- LLViewerImage* viewerImage = LLViewerImage::getImage( uuid );
- if( viewerImage )
- {
- mMovieImageID = uuid;
- // Can't use mipmaps for movies because they don't update the full image
- mMovieImageHasMips = viewerImage->getUseMipMaps();
- viewerImage->reinit(FALSE);
- viewerImage->mIsMediaTexture = TRUE;
- }
+ navigateTo(mMediaURL, mMimeType, true);
}
+ else if(! mMimeType.empty())
+ {
+ initializeMedia(mMimeType);
+ }
+
}
+//////////////////////////////////////////////////////////////////////////////////////////
+void LLViewerMediaImpl::destroyMediaSource()
+{
+ mNeedsNewTexture = true;
+ if(! mMediaSource)
+ {
+ return;
+ }
+ // Restore the texture
+ updateMovieImage(LLUUID::null, false);
+ delete mMediaSource;
+ mMediaSource = NULL;
+}
//////////////////////////////////////////////////////////////////////////////////////////
-// static
-void LLViewerMediaImpl::updateImagesMediaStreams()
+void LLViewerMediaImpl::setMediaType(const std::string& media_type)
{
- LLMediaManager::updateClass();
+ mMimeType = media_type;
}
-void LLViewerMediaImpl::initializePlaceholderImage(LLViewerImage *placeholder_image, LLMediaBase *media_source)
+//////////////////////////////////////////////////////////////////////////////////////////
+/*static*/
+LLPluginClassMedia* LLViewerMediaImpl::newSourceFromMediaType(std::string media_type, LLPluginClassMediaOwner *owner /* may be NULL */, S32 default_width, S32 default_height)
{
- int media_width = media_source->getMediaWidth();
- int media_height = media_source->getMediaHeight();
- //int media_rowspan = media_source->getMediaRowSpan();
+ std::string plugin_basename = LLMIMETypes::implType(media_type);
- // if width & height are invalid, don't bother doing anything
- if ( media_width < 1 || media_height < 1 )
- return;
+ if(plugin_basename.empty())
+ {
+ LL_WARNS("Media") << "Couldn't find plugin for media type " << media_type << LL_ENDL;
+ }
+ else
+ {
+ std::string plugins_path = gDirUtilp->getLLPluginDir();
+ plugins_path += gDirUtilp->getDirDelimiter();
+
+ std::string launcher_name = gDirUtilp->getLLPluginLauncher();
+ std::string plugin_name = gDirUtilp->getLLPluginFilename(plugin_basename);
+
+ // See if the plugin executable exists
+ llstat s;
+ if(LLFile::stat(launcher_name, &s))
+ {
+ LL_WARNS("Media") << "Couldn't find launcher at " << launcher_name << LL_ENDL;
+ }
+ else if(LLFile::stat(plugin_name, &s))
+ {
+ LL_WARNS("Media") << "Couldn't find plugin at " << plugin_name << LL_ENDL;
+ }
+ else
+ {
+ LLPluginClassMedia* media_source = new LLPluginClassMedia(owner);
+ media_source->setSize(default_width, default_height);
+ if (media_source->init(launcher_name, plugin_name))
+ {
+ return media_source;
+ }
+ else
+ {
+ LL_WARNS("Media") << "Failed to init plugin. Destroying." << LL_ENDL;
+ delete media_source;
+ }
+ }
+ }
+
+ return NULL;
+}
- llinfos << "initializing media placeholder" << llendl;
- llinfos << "movie image id " << mMovieImageID << llendl;
+//////////////////////////////////////////////////////////////////////////////////////////
+bool LLViewerMediaImpl::initializePlugin(const std::string& media_type)
+{
+ if(mMediaSource)
+ {
+ // Save the previous media source's last set size before destroying it.
+ mMediaWidth = mMediaSource->getSetWidth();
+ mMediaHeight = mMediaSource->getSetHeight();
+ }
+
+ // Always delete the old media impl first.
+ destroyMediaSource();
+
+ // and unconditionally set the mime type
+ mMimeType = media_type;
- int texture_width = LLMediaManager::textureWidthFromMediaWidth( media_width );
- int texture_height = LLMediaManager::textureHeightFromMediaHeight( media_height );
- int texture_depth = media_source->getMediaDepth();
+ LLPluginClassMedia* media_source = newSourceFromMediaType(media_type, this, mMediaWidth, mMediaHeight);
+
+ if (media_source)
+ {
+ media_source->setDisableTimeout(gSavedSettings.getBOOL("DebugPluginDisableTimeout"));
+ media_source->setLoop(mMediaLoop);
+ media_source->setAutoScale(mMediaAutoScale);
+ media_source->setBrowserUserAgent(LLViewerMedia::getCurrentUserAgent());
+
+ mMediaSource = media_source;
+ return true;
+ }
- // MEDIAOPT: check to see if size actually changed before doing work
- placeholder_image->destroyGLTexture();
- // MEDIAOPT: apparently just calling setUseMipMaps(FALSE) doesn't work?
- placeholder_image->reinit(FALSE); // probably not needed
+ return false;
+}
+
+void LLViewerMediaImpl::setSize(int width, int height)
+{
+ mMediaWidth = width;
+ mMediaHeight = height;
+ if(mMediaSource)
+ {
+ mMediaSource->setSize(width, height);
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////////////////////
+void LLViewerMediaImpl::play()
+{
+ // first stop any previously playing media
+ // stop();
- // MEDIAOPT: seems insane that we actually have to make an imageraw then
- // immediately discard it
- LLPointer<LLImageRaw> raw = new LLImageRaw(texture_width, texture_height, texture_depth);
- raw->clear(0x0f, 0x0f, 0x0f, 0xff);
- int discard_level = 0;
+ // mMediaSource->addObserver( this );
+ if(mMediaSource == NULL)
+ {
+ if(!initializePlugin(mMimeType))
+ {
+ // Plugin failed initialization... should assert or something
+ return;
+ }
+ }
+
+ // updateMovieImage(mTextureId, true);
- // ask media source for correct GL image format constants
- placeholder_image->setExplicitFormat(media_source->getTextureFormatInternal(),
- media_source->getTextureFormatPrimary(),
- media_source->getTextureFormatType());
+ mMediaSource->loadURI( mMediaURL );
+ if(/*mMediaSource->pluginSupportsMediaTime()*/ true)
+ {
+ start();
+ }
+}
- placeholder_image->createGLTexture(discard_level, raw);
+//////////////////////////////////////////////////////////////////////////////////////////
+void LLViewerMediaImpl::stop()
+{
+ if(mMediaSource)
+ {
+ mMediaSource->stop();
+ // destroyMediaSource();
+ }
+}
- // placeholder_image->setExplicitFormat()
- placeholder_image->setUseMipMaps(FALSE);
+//////////////////////////////////////////////////////////////////////////////////////////
+void LLViewerMediaImpl::pause()
+{
+ if(mMediaSource)
+ {
+ mMediaSource->pause();
+ }
+}
- // MEDIAOPT: set this dynamically on play/stop
- placeholder_image->mIsMediaTexture = true;
+//////////////////////////////////////////////////////////////////////////////////////////
+void LLViewerMediaImpl::start()
+{
+ if(mMediaSource)
+ {
+ mMediaSource->start();
+ }
}
+//////////////////////////////////////////////////////////////////////////////////////////
+void LLViewerMediaImpl::seek(F32 time)
+{
+ if(mMediaSource)
+ {
+ mMediaSource->seek(time);
+ }
+}
+//////////////////////////////////////////////////////////////////////////////////////////
+void LLViewerMediaImpl::setVolume(F32 volume)
+{
+ if(mMediaSource)
+ {
+ mMediaSource->setVolume(volume);
+ }
+}
-// virtual
-void LLViewerMediaImpl::onMediaContentsChange(const EventType& event_in)
+//////////////////////////////////////////////////////////////////////////////////////////
+void LLViewerMediaImpl::focus(bool focus)
{
- LLMediaBase* media_source = event_in.getSubject();
- LLViewerImage* placeholder_image = gImageList.getImage( mMovieImageID );
- if ((placeholder_image) && (placeholder_image->getHasGLTexture()))
+ if (mMediaSource)
{
- if (placeholder_image->getUseMipMaps())
+ // call focus just for the hell of it, even though this apopears to be a nop
+ mMediaSource->focus(focus);
+ if (focus)
{
- // bad image! NO MIPMAPS!
- initializePlaceholderImage(placeholder_image, media_source);
+ // spoof a mouse click to *actually* pass focus
+ // Don't do this anymore -- it actually clicks through now.
+// mMediaSource->mouseEvent(LLPluginClassMedia::MOUSE_EVENT_DOWN, 1, 1, 0);
+// mMediaSource->mouseEvent(LLPluginClassMedia::MOUSE_EVENT_UP, 1, 1, 0);
}
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////////////////////
+void LLViewerMediaImpl::mouseDown(S32 x, S32 y)
+{
+ scaleMouse(&x, &y);
+ mLastMouseX = x;
+ mLastMouseY = y;
+ if (mMediaSource)
+ {
+ mMediaSource->mouseEvent(LLPluginClassMedia::MOUSE_EVENT_DOWN, x, y, 0);
+ }
+}
- U8* data = media_source->getMediaData();
- S32 x_pos = 0;
- S32 y_pos = 0;
- S32 width = media_source->getMediaWidth();
- S32 height = media_source->getMediaHeight();
- S32 data_width = media_source->getMediaDataWidth();
- S32 data_height = media_source->getMediaDataHeight();
- placeholder_image->setSubImage(data, data_width, data_height,
- x_pos, y_pos, width, height);
+//////////////////////////////////////////////////////////////////////////////////////////
+void LLViewerMediaImpl::mouseUp(S32 x, S32 y)
+{
+ scaleMouse(&x, &y);
+ mLastMouseX = x;
+ mLastMouseY = y;
+ if (mMediaSource)
+ {
+ mMediaSource->mouseEvent(LLPluginClassMedia::MOUSE_EVENT_UP, x, y, 0);
}
}
+//////////////////////////////////////////////////////////////////////////////////////////
+void LLViewerMediaImpl::mouseMove(S32 x, S32 y)
+{
+ scaleMouse(&x, &y);
+ mLastMouseX = x;
+ mLastMouseY = y;
+ if (mMediaSource)
+ {
+ mMediaSource->mouseEvent(LLPluginClassMedia::MOUSE_EVENT_MOVE, x, y, 0);
+ }
+}
-// virtual
-void LLViewerMediaImpl::onMediaSizeChange(const EventType& event_in)
+//////////////////////////////////////////////////////////////////////////////////////////
+void LLViewerMediaImpl::mouseLeftDoubleClick(S32 x, S32 y)
{
- LLMediaBase* media_source = event_in.getSubject();
- LLViewerImage* placeholder_image = gImageList.getImage( mMovieImageID );
- if (placeholder_image)
+ scaleMouse(&x, &y);
+ mLastMouseX = x;
+ mLastMouseY = y;
+ if (mMediaSource)
{
- initializePlaceholderImage(placeholder_image, media_source);
+ mMediaSource->mouseEvent(LLPluginClassMedia::MOUSE_EVENT_DOUBLE_CLICK, x, y, 0);
}
- else
+}
+
+//////////////////////////////////////////////////////////////////////////////////////////
+void LLViewerMediaImpl::onMouseCaptureLost()
+{
+ if (mMediaSource)
{
- llinfos << "no placeholder image" << llendl;
+ mMediaSource->mouseEvent(LLPluginClassMedia::MOUSE_EVENT_UP, mLastMouseX, mLastMouseY, 0);
}
}
+//////////////////////////////////////////////////////////////////////////////////////////
+BOOL LLViewerMediaImpl::handleMouseUp(S32 x, S32 y, MASK mask)
+{
+ // NOTE: this is called when the mouse is released when we have capture.
+ // Due to the way mouse coordinates are mapped to the object, we can't use the x and y coordinates that come in with the event.
+
+ if(hasMouseCapture())
+ {
+ // Release the mouse -- this will also send a mouseup to the media
+ gFocusMgr.setMouseCapture( FALSE );
+ }
- // Get the image we're using
+ return TRUE;
+}
+//////////////////////////////////////////////////////////////////////////////////////////
+void LLViewerMediaImpl::navigateHome()
+{
+ if(mMediaSource)
+ {
+ mMediaSource->loadURI( mHomeURL );
+ }
+}
- /*
- // update media stream if required
- LLMediaEngine* media_engine = LLMediaEngine::getInstance();
- if (media_engine)
+//////////////////////////////////////////////////////////////////////////////////////////
+void LLViewerMediaImpl::navigateTo(const std::string& url, const std::string& mime_type, bool rediscover_type)
+{
+ if(rediscover_type)
{
- if ( media_engine->update() )
+
+ LLURI uri(url);
+ std::string scheme = uri.scheme();
+
+ if(scheme.empty() || "http" == scheme || "https" == scheme)
+ {
+ LLHTTPClient::getHeaderOnly( url, new LLMimeDiscoveryResponder(this));
+ }
+ else if("data" == scheme || "file" == scheme || "about" == scheme)
{
- LLUUID media_uuid = media_engine->getImageUUID();
- updateMovieImage(media_uuid, TRUE);
- if (!media_uuid.isNull())
+ // FIXME: figure out how to really discover the type for these schemes
+ // We use "data" internally for a text/html url for loading the login screen
+ if(initializeMedia("text/html"))
{
- LLViewerImage* viewerImage = getImage( media_uuid );
- if( viewerImage )
- {
- LLMediaBase* renderer = media_engine->getMediaRenderer();
- if ((renderer->getTextureWidth() != viewerImage->getWidth()) ||
- (renderer->getTextureHeight() != viewerImage->getHeight()) ||
- (renderer->getTextureDepth() != viewerImage->getComponents()) ||
- (viewerImage->getHasGLTexture() == FALSE))
- {
- // destroy existing GL image
- viewerImage->destroyGLTexture();
-
- // set new size
- viewerImage->setSize( renderer->getTextureWidth(),
- renderer->getTextureHeight(),
- renderer->getTextureDepth() );
-
- LLPointer<LLImageRaw> raw = new LLImageRaw(renderer->getTextureWidth(),
- renderer->getTextureHeight(),
- renderer->getTextureDepth());
- raw->clear(0x7f,0x7f,0x7f,0xff);
- viewerImage->createGLTexture(0, raw);
- }
-
- // Set the explicit format the instance wants
- viewerImage->setExplicitFormat(renderer->getTextureFormatInternal(),
- renderer->getTextureFormatPrimary(),
- renderer->getTextureFormatType(),
- renderer->getTextureFormatSwapBytes());
- // This should be redundant, but just in case:
- viewerImage->setUseMipMaps(FALSE);
-
- LLImageRaw* rawImage = media_engine->getImageRaw();
- if ( rawImage )
- {
- viewerImage->setSubImage(rawImage, 0, 0,
- renderer->getMediaWidth(),
- renderer->getMediaHeight());
- }
- }
- else
- {
- llwarns << "MediaEngine update unable to get viewer image for GL texture" << llendl;
- }
+ mMediaSource->loadURI( url );
}
}
else
{
- LLUUID media_uuid = media_engine->getImageUUID();
- updateMovieImage(media_uuid, FALSE);
+ // This catches 'rtsp://' urls
+ if(initializeMedia(scheme))
+ {
+ mMediaSource->loadURI( url );
+ }
}
}
- */
-
+ else if (mMediaSource)
+ {
+ mMediaSource->loadURI( url );
+ }
+ else if(initializeMedia(mime_type) && mMediaSource)
+ {
+ mMediaSource->loadURI( url );
+ }
+ else
+ {
+ LL_WARNS("Media") << "Couldn't navigate to: " << url << " as there is no media type for: " << mime_type << LL_ENDL;
+ return;
+ }
+ mMediaURL = url;
-LLUUID LLViewerMediaImpl::getMediaTextureID()
-{
- return mMovieImageID;
}
-// static
-void LLViewerMediaImpl::updateBrowserUserAgent()
+//////////////////////////////////////////////////////////////////////////////////////////
+void LLViewerMediaImpl::navigateStop()
{
- // Don't use user-visible string to avoid
- // punctuation and strange characters.
- std::string skin_name = gSavedSettings.getString("SkinCurrent");
-
- // Just in case we need to check browser differences in A/B test
- // builds.
- std::string channel = gSavedSettings.getString("VersionChannelName");
+ if(mMediaSource)
+ {
+ mMediaSource->browse_stop();
+ }
- // append our magic version number string to the browser user agent id
- // See the HTTP 1.0 and 1.1 specifications for allowed formats:
- // http://www.ietf.org/rfc/rfc1945.txt section 10.15
- // http://www.ietf.org/rfc/rfc2068.txt section 3.8
- // This was also helpful:
- // http://www.mozilla.org/build/revised-user-agent-strings.html
- std::ostringstream codec;
- codec << "SecondLife/";
- codec << LL_VERSION_MAJOR << "." << LL_VERSION_MINOR << "." << LL_VERSION_PATCH << "." << LL_VERSION_BUILD;
- codec << " (" << channel << "; " << skin_name << " skin)";
- llinfos << codec.str() << llendl;
- LLMediaManager::setBrowserUserAgent( codec.str() );
}
-// static
-bool LLViewerMediaImpl::handleSkinCurrentChanged(const LLSD& /*newvalue*/)
+//////////////////////////////////////////////////////////////////////////////////////////
+bool LLViewerMediaImpl::handleKeyHere(KEY key, MASK mask)
{
- // gSavedSettings is already updated when this function is called.
- updateBrowserUserAgent();
- return true;
+ bool result = false;
+
+ if (mMediaSource)
+ {
+ result = mMediaSource->keyEvent(LLPluginClassMedia::KEY_EVENT_DOWN ,key, mask);
+ }
+
+ return result;
}
//////////////////////////////////////////////////////////////////////////////////////////
-// Wrapper class
-//////////////////////////////////////////////////////////////////////////////////////////
-
+bool LLViewerMediaImpl::handleUnicodeCharHere(llwchar uni_char)
+{
+ bool result = false;
+
+ if (mMediaSource)
+ {
+ mMediaSource->textInput(wstring_to_utf8str(LLWString(1, uni_char)));
+ }
+
+ return result;
+}
//////////////////////////////////////////////////////////////////////////////////////////
-// The viewer takes a long time to load the start screen. Part of the problem
-// is media initialization -- in particular, QuickTime loads many DLLs and
-// hits the disk heavily. So we initialize only the browser component before
-// the login screen, then do the rest later when we have a progress bar. JC
-// static
-void LLViewerMedia::initBrowser()
+bool LLViewerMediaImpl::canNavigateForward()
{
- LLMediaManagerData* init_data = new LLMediaManagerData;
- buildMediaManagerData( init_data );
- LLMediaManager::initBrowser( init_data );
- delete init_data;
-
- // We use a custom user agent with viewer version and skin name.
- LLViewerMediaImpl::updateBrowserUserAgent();
+ BOOL result = FALSE;
+ if (mMediaSource)
+ {
+ result = mMediaSource->getHistoryForwardAvailable();
+ }
+ return result;
}
//////////////////////////////////////////////////////////////////////////////////////////
-// static
-void LLViewerMedia::initClass()
+bool LLViewerMediaImpl::canNavigateBack()
{
- // *TODO: This looks like a memory leak to me. JC
- LLMediaManagerData* init_data = new LLMediaManagerData;
- buildMediaManagerData( init_data );
- LLMediaManager::initClass( init_data );
- delete init_data;
-
- LLMediaManager* mm = LLMediaManager::getInstance();
- LLMIMETypes::mime_info_map_t::const_iterator it;
- for (it = LLMIMETypes::sMap.begin(); it != LLMIMETypes::sMap.end(); ++it)
+ BOOL result = FALSE;
+ if (mMediaSource)
{
- const std::string& mime_type = it->first;
- const LLMIMETypes::LLMIMEInfo& info = it->second;
- mm->addMimeTypeImplNameMap( mime_type, info.mImpl );
+ result = mMediaSource->getHistoryBackAvailable();
}
+ return result;
}
+
//////////////////////////////////////////////////////////////////////////////////////////
-// static
-void LLViewerMedia::buildMediaManagerData( LLMediaManagerData* init_data )
-{
-// std::string executable_dir = std::string( arg0 ).substr( 0, std::string( arg0 ).find_last_of("\\/") );
-// std::string component_dir = std::string( executable_dir ).substr( 0, std::string( executable_dir ).find_last_of("\\/") );
-// component_dir = std::string( component_dir ).substr( 0, std::string( component_dir ).find_last_of("\\/") );
-// component_dir = std::string( component_dir ).substr( 0, std::string( component_dir ).find_last_of("\\/") );
-// component_dir += "\\newview\\app_settings\\mozilla";
-
-
-#if LL_DARWIN
- // For Mac OS, we store both the shared libraries and the runtime files (chrome/, plugins/, etc) in
- // Second Life.app/Contents/MacOS/. This matches the way Firefox is distributed on the Mac.
- std::string component_dir(gDirUtilp->getExecutableDir());
-#elif LL_WINDOWS
- std::string component_dir( gDirUtilp->getExpandedFilename( LL_PATH_APP_SETTINGS, "" ) );
- component_dir += gDirUtilp->getDirDelimiter();
- #ifdef LL_DEBUG
- component_dir += "mozilla_debug";
- #else // LL_DEBUG
- component_dir += "mozilla";
- #endif // LL_DEBUG
-#elif LL_LINUX
- std::string component_dir( gDirUtilp->getExpandedFilename( LL_PATH_APP_SETTINGS, "" ) );
- component_dir += gDirUtilp->getDirDelimiter();
- component_dir += "mozilla-runtime-linux-i686";
-#elif LL_SOLARIS
- std::string component_dir( gDirUtilp->getExpandedFilename( LL_PATH_APP_SETTINGS, "" ) );
- component_dir += gDirUtilp->getDirDelimiter();
- #ifdef __sparc
- component_dir += "mozilla-solaris-sparc";
- #else
- component_dir += "mozilla-solaris-i686";
- #endif
-#else
- std::string component_dir( gDirUtilp->getExpandedFilename( LL_PATH_APP_SETTINGS, "" ) );
- component_dir += gDirUtilp->getDirDelimiter();
- component_dir += "mozilla";
-#endif
+void LLViewerMediaImpl::updateMovieImage(const LLUUID& uuid, BOOL active)
+{
+ // IF the media image hasn't changed, do nothing
+ if (mTextureId == uuid)
+ {
+ return;
+ }
+ // If we have changed media uuid, restore the old one
+ if (!mTextureId.isNull())
+ {
+ LLViewerMediaTexture* old_image = LLViewerTextureManager::findMediaTexture( mTextureId );
+ if (old_image)
+ {
+ old_image->setPlaying(FALSE);
+ LLViewerTexture* original_texture = old_image->getOldTexture();
+ if(original_texture)
+ {
+ old_image->switchToTexture(original_texture);
+ }
+ }
+ }
+ // If the movie is playing, set the new media image
+ if (active && !uuid.isNull())
+ {
+ LLViewerMediaTexture* viewerImage = LLViewerTextureManager::findMediaTexture( uuid );
+ if( viewerImage )
+ {
+ mTextureId = uuid;
+
+ // Can't use mipmaps for movies because they don't update the full image
+ mMovieImageHasMips = viewerImage->getUseMipMaps();
+ viewerImage->reinit(FALSE);
+ // FIXME
+// viewerImage->mIsMediaTexture = TRUE;
+ }
+ }
+}
- std::string application_dir = gDirUtilp->getExecutableDir();
+//////////////////////////////////////////////////////////////////////////////////////////
+void LLViewerMediaImpl::update()
+{
+ if(mMediaSource == NULL)
+ {
+ return;
+ }
+
+ mMediaSource->idle();
+
+ if(mMediaSource->isPluginExited())
+ {
+ destroyMediaSource();
+ return;
+ }
- init_data->setBrowserApplicationDir( application_dir );
- std::string profile_dir = gDirUtilp->getExpandedFilename( LL_PATH_MOZILLA_PROFILE, "" );
- init_data->setBrowserProfileDir( profile_dir );
- init_data->setBrowserComponentDir( component_dir );
- std::string profile_name("Second Life");
- init_data->setBrowserProfileName( profile_name );
- init_data->setBrowserParentWindow( gViewerWindow->getMediaWindow() );
+ if(!mMediaSource->textureValid())
+ {
+ return;
+ }
+
+ if(mSuspendUpdates || !mVisible)
+ {
+ return;
+ }
+
+ LLViewerMediaTexture* placeholder_image = updatePlaceholderImage();
+
+ if(placeholder_image)
+ {
+ LLRect dirty_rect;
+ if(mMediaSource->getDirty(&dirty_rect))
+ {
+ // Constrain the dirty rect to be inside the texture
+ S32 x_pos = llmax(dirty_rect.mLeft, 0);
+ S32 y_pos = llmax(dirty_rect.mBottom, 0);
+ S32 width = llmin(dirty_rect.mRight, placeholder_image->getWidth()) - x_pos;
+ S32 height = llmin(dirty_rect.mTop, placeholder_image->getHeight()) - y_pos;
+
+ if(width > 0 && height > 0)
+ {
- // Users can change skins while client is running, so make sure
- // we pick up on changes.
- gSavedSettings.getControl("SkinCurrent")->getSignal()->connect(
- boost::bind( LLViewerMediaImpl::handleSkinCurrentChanged, _1 ) );
+ U8* data = mMediaSource->getBitsData();
+
+ // Offset the pixels pointer to match x_pos and y_pos
+ data += ( x_pos * mMediaSource->getTextureDepth() * mMediaSource->getBitsWidth() );
+ data += ( y_pos * mMediaSource->getTextureDepth() );
+
+ placeholder_image->setSubImage(
+ data,
+ mMediaSource->getBitsWidth(),
+ mMediaSource->getBitsHeight(),
+ x_pos,
+ y_pos,
+ width,
+ height);
+ }
+
+ mMediaSource->resetDirty();
+ }
+ }
}
+
//////////////////////////////////////////////////////////////////////////////////////////
-// static
-void LLViewerMedia::cleanupClass()
+void LLViewerMediaImpl::updateImagesMediaStreams()
{
- stop() ;
- LLMediaManager::cleanupClass();
}
-// static
-void LLViewerMedia::play(const std::string& media_url,
- const std::string& mime_type,
- const LLUUID& placeholder_texture_id,
- S32 media_width, S32 media_height, U8 media_auto_scale,
- U8 media_loop)
-{
- sViewerMediaImpl.play(media_url, mime_type, placeholder_texture_id,
- media_width, media_height, media_auto_scale, media_loop);
-}
-// static
-void LLViewerMedia::stop()
+//////////////////////////////////////////////////////////////////////////////////////////
+LLViewerMediaTexture* LLViewerMediaImpl::updatePlaceholderImage()
{
- sViewerMediaImpl.stop();
+ if(mTextureId.isNull())
+ {
+ // The code that created this instance will read from the plugin's bits.
+ return NULL;
+ }
+
+ LLViewerMediaTexture* placeholder_image = LLViewerTextureManager::getMediaTexture( mTextureId );
+
+ if (mNeedsNewTexture
+ || placeholder_image->getUseMipMaps()
+// || ! placeholder_image->getType() == LLViewerTexture::MEDIA_TEXTURE
+ || placeholder_image->getWidth() != mMediaSource->getTextureWidth()
+ || placeholder_image->getHeight() != mMediaSource->getTextureHeight())
+ {
+ llinfos << "initializing media placeholder" << llendl;
+ llinfos << "movie image id " << mTextureId << llendl;
+
+ int texture_width = mMediaSource->getTextureWidth();
+ int texture_height = mMediaSource->getTextureHeight();
+ int texture_depth = mMediaSource->getTextureDepth();
+
+ // MEDIAOPT: check to see if size actually changed before doing work
+ placeholder_image->destroyGLTexture();
+ // MEDIAOPT: apparently just calling setUseMipMaps(FALSE) doesn't work?
+ placeholder_image->reinit(FALSE); // probably not needed
+
+ // MEDIAOPT: seems insane that we actually have to make an imageraw then
+ // immediately discard it
+ LLPointer<LLImageRaw> raw = new LLImageRaw(texture_width, texture_height, texture_depth);
+ raw->clear(0x0f, 0x0f, 0x0f, 0xff);
+ int discard_level = 0;
+
+ // ask media source for correct GL image format constants
+ placeholder_image->setExplicitFormat(mMediaSource->getTextureFormatInternal(),
+ mMediaSource->getTextureFormatPrimary(),
+ mMediaSource->getTextureFormatType(),
+ mMediaSource->getTextureFormatSwapBytes());
+
+ placeholder_image->createGLTexture(discard_level, raw);
+
+ // placeholder_image->setExplicitFormat()
+ placeholder_image->setUseMipMaps(FALSE);
+
+ // MEDIAOPT: set this dynamically on play/stop
+ // FIXME
+// placeholder_image->mIsMediaTexture = true;
+ mNeedsNewTexture = false;
+ }
+
+ return placeholder_image;
}
-// static
-void LLViewerMedia::pause()
-{
- sViewerMediaImpl.pause();
-}
-// static
-void LLViewerMedia::start()
+//////////////////////////////////////////////////////////////////////////////////////////
+LLUUID LLViewerMediaImpl::getMediaTextureID()
{
- sViewerMediaImpl.start();
+ return mTextureId;
}
-// static
-void LLViewerMedia::seek(F32 time)
+//////////////////////////////////////////////////////////////////////////////////////////
+void LLViewerMediaImpl::setVisible(bool visible)
{
- sViewerMediaImpl.seek(time);
+ mVisible = visible;
+
+ if(mVisible)
+ {
+ if(mMediaSource && mMediaSource->isPluginExited())
+ {
+ destroyMediaSource();
+ }
+
+ if(!mMediaSource)
+ {
+ createMediaSource();
+ }
+ }
+
+ if(mMediaSource)
+ {
+ mMediaSource->setPriority(mVisible?LLPluginClassMedia::PRIORITY_NORMAL:LLPluginClassMedia::PRIORITY_HIDDEN);
+ }
}
-// static
-void LLViewerMedia::setVolume(F32 volume)
+//////////////////////////////////////////////////////////////////////////////////////////
+void LLViewerMediaImpl::mouseCapture()
{
- sViewerMediaImpl.setVolume(volume);
+ gFocusMgr.setMouseCapture(this);
}
-// static
-LLMediaBase::EStatus LLViewerMedia::getStatus()
+//////////////////////////////////////////////////////////////////////////////////////////
+void LLViewerMediaImpl::scaleMouse(S32 *mouse_x, S32 *mouse_y)
{
- return sViewerMediaImpl.getStatus();
+#if 0
+ S32 media_width, media_height;
+ S32 texture_width, texture_height;
+ getMediaSize( &media_width, &media_height );
+ getTextureSize( &texture_width, &texture_height );
+ S32 y_delta = texture_height - media_height;
+
+ *mouse_y -= y_delta;
+#endif
}
//////////////////////////////////////////////////////////////////////////////////////////
-// static
-LLUUID LLViewerMedia::getMediaTextureID()
+bool LLViewerMediaImpl::isMediaPlaying()
{
- return sViewerMediaImpl.getMediaTextureID();
+ bool result = false;
+
+ if(mMediaSource)
+ {
+ EMediaStatus status = mMediaSource->getStatus();
+ if(status == MEDIA_PLAYING || status == MEDIA_LOADING)
+ result = true;
+ }
+
+ return result;
}
-
//////////////////////////////////////////////////////////////////////////////////////////
-// static
-bool LLViewerMedia::getMediaSize(S32 *media_width, S32 *media_height)
+bool LLViewerMediaImpl::isMediaPaused()
{
- // make sure we're valid
+ bool result = false;
- if ( sViewerMediaImpl.mMediaSource != NULL )
+ if(mMediaSource)
{
- *media_width = sViewerMediaImpl.mMediaSource->getMediaWidth();
- *media_height = sViewerMediaImpl.mMediaSource->getMediaHeight();
- return true;
+ if(mMediaSource->getStatus() == MEDIA_PAUSED)
+ result = true;
}
- return false;
+
+ return result;
}
//////////////////////////////////////////////////////////////////////////////////////////
-// static
-bool LLViewerMedia::getTextureSize(S32 *texture_width, S32 *texture_height)
+//
+bool LLViewerMediaImpl::hasMedia()
+{
+ return mMediaSource != NULL;
+}
+
+//////////////////////////////////////////////////////////////////////////////////////////
+void LLViewerMediaImpl::handleMediaEvent(LLPluginClassMedia* self, LLPluginClassMediaOwner::EMediaEvent event)
{
- if ( sViewerMediaImpl.mMediaSource != NULL )
+ switch(event)
{
- S32 media_width = sViewerMediaImpl.mMediaSource->getMediaWidth();
- S32 media_height = sViewerMediaImpl.mMediaSource->getMediaHeight();
- *texture_width = LLMediaManager::textureWidthFromMediaWidth( media_width );
- *texture_height = LLMediaManager::textureHeightFromMediaHeight( media_height );
- return true;
+ case MEDIA_EVENT_PLUGIN_FAILED:
+ {
+ LLSD args;
+ args["PLUGIN"] = LLMIMETypes::implType(mMimeType);
+ LLNotifications::instance().add("MediaPluginFailed", args);
+ }
+ break;
+ default:
+ break;
}
- return false;
+ // Just chain the event to observers.
+ emitEvent(self, event);
}
+////////////////////////////////////////////////////////////////////////////////
+// virtual
+void
+LLViewerMediaImpl::cut()
+{
+ if (mMediaSource)
+ mMediaSource->cut();
+}
-//////////////////////////////////////////////////////////////////////////////////////////
-// static
-void LLViewerMedia::updateImagesMediaStreams()
+////////////////////////////////////////////////////////////////////////////////
+// virtual
+BOOL
+LLViewerMediaImpl::canCut() const
{
- sViewerMediaImpl.updateImagesMediaStreams();
+ if (mMediaSource)
+ return mMediaSource->canCut();
+ else
+ return FALSE;
}
-//////////////////////////////////////////////////////////////////////////////////////////
-// static
-bool LLViewerMedia::isMediaPlaying()
+
+////////////////////////////////////////////////////////////////////////////////
+// virtual
+void
+LLViewerMediaImpl::copy()
{
- LLMediaBase::EStatus status = sViewerMediaImpl.getStatus();
- return (status == LLMediaBase::STATUS_STARTED );
+ if (mMediaSource)
+ mMediaSource->copy();
}
-//////////////////////////////////////////////////////////////////////////////////////////
-// static
-bool LLViewerMedia::isMediaPaused()
+
+////////////////////////////////////////////////////////////////////////////////
+// virtual
+BOOL
+LLViewerMediaImpl::canCopy() const
{
- LLMediaBase::EStatus status = sViewerMediaImpl.getStatus();
- return (status == LLMediaBase::STATUS_PAUSED);
+ if (mMediaSource)
+ return mMediaSource->canCopy();
+ else
+ return FALSE;
}
-//////////////////////////////////////////////////////////////////////////////////////////
-// static
-bool LLViewerMedia::hasMedia()
+
+////////////////////////////////////////////////////////////////////////////////
+// virtual
+void
+LLViewerMediaImpl::paste()
+{
+ if (mMediaSource)
+ mMediaSource->paste();
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// virtual
+BOOL
+LLViewerMediaImpl::canPaste() const
{
- return sViewerMediaImpl.mMediaSource != NULL;
+ if (mMediaSource)
+ return mMediaSource->canPaste();
+ else
+ return FALSE;
}
+
//////////////////////////////////////////////////////////////////////////////////////////
//static
-bool LLViewerMedia::isActiveMediaTexture(const LLUUID& id)
+void LLViewerMedia::toggleMusicPlay(void*)
{
- return (id.notNull()
- && id == getMediaTextureID()
- && isMediaPlaying());
+// FIXME: This probably doesn't belong here
+#if 0
+ if (mMusicState != PLAYING)
+ {
+ mMusicState = PLAYING; // desired state
+ if (gAudiop)
+ {
+ LLParcel* parcel = LLViewerParcelMgr::getInstance()->getAgentParcel();
+ if ( parcel )
+ {
+ gAudiop->startInternetStream(parcel->getMusicURL());
+ }
+ }
+ }
+ else
+ {
+ mMusicState = STOPPED; // desired state
+ if (gAudiop)
+ {
+ gAudiop->stopInternetStream();
+ }
+ }
+#endif
}
//////////////////////////////////////////////////////////////////////////////////////////
-// static
-std::string LLViewerMedia::getMediaURL()
+//static
+void LLViewerMedia::toggleMediaPlay(void*)
{
- return sViewerMediaImpl.mMediaURL;
+// FIXME: This probably doesn't belong here
+#if 0
+ if (LLViewerMedia::isMediaPaused())
+ {
+ LLViewerParcelMedia::start();
+ }
+ else if(LLViewerMedia::isMediaPlaying())
+ {
+ LLViewerParcelMedia::pause();
+ }
+ else
+ {
+ LLParcel* parcel = LLViewerParcelMgr::getInstance()->getAgentParcel();
+ if (parcel)
+ {
+ LLViewerParcelMedia::play(parcel);
+ }
+ }
+#endif
}
+
//////////////////////////////////////////////////////////////////////////////////////////
-// static
-std::string LLViewerMedia::getMimeType()
+//static
+void LLViewerMedia::mediaStop(void*)
{
- return sViewerMediaImpl.mMimeType;
+// FIXME: This probably doesn't belong here
+#if 0
+ LLViewerParcelMedia::stop();
+#endif
}
+
//////////////////////////////////////////////////////////////////////////////////////////
-// static
-void LLViewerMedia::setMimeType(std::string mime_type)
-{
- sViewerMediaImpl.mMimeType = mime_type;
+//static
+bool LLViewerMedia::isMusicPlaying()
+{
+// FIXME: This probably doesn't belong here
+// FIXME: make this work
+ return false;
}
diff --git a/indra/newview/llviewermedia.h b/indra/newview/llviewermedia.h
index 600d7409e2..68a49662e7 100644
--- a/indra/newview/llviewermedia.h
+++ b/indra/newview/llviewermedia.h
@@ -33,50 +33,196 @@
#ifndef LLVIEWERMEDIA_H
#define LLVIEWERMEDIA_H
-#include "llmediabase.h" // for status codes
+#include "llfocusmgr.h"
+#include "lleditmenuhandler.h"
-class LLMediaManagerData;
+#include "llpanel.h"
+#include "llpluginclassmediaowner.h"
+
+#include "llviewermediaobserver.h"
+
+class LLViewerMediaImpl;
class LLUUID;
+class LLViewerMediaTexture;
+
+typedef LLPointer<LLViewerMediaImpl> viewer_media_t;
+///////////////////////////////////////////////////////////////////////////////
+//
+class LLViewerMediaEventEmitter
+{
+public:
+ virtual ~LLViewerMediaEventEmitter();
+
+ bool addObserver( LLViewerMediaObserver* subject );
+ bool remObserver( LLViewerMediaObserver* subject );
+ void emitEvent(LLPluginClassMedia* self, LLPluginClassMediaOwner::EMediaEvent event);
+
+private:
+ typedef std::list< LLViewerMediaObserver* > observerListType;
+ observerListType mObservers;
+};
class LLViewerMedia
{
+ LOG_CLASS(LLViewerMedia);
public:
// Special case early init for just web browser component
// so we can show login screen. See .cpp file for details. JC
- static void initBrowser();
- static void initClass();
- static void cleanupClass();
+ static viewer_media_t newMediaImpl(const std::string& media_url,
+ const LLUUID& texture_id,
+ S32 media_width,
+ S32 media_height,
+ U8 media_auto_scale,
+ U8 media_loop,
+ std::string mime_type = "none/none");
- static void play(const std::string& media_url,
- const std::string& mime_type,
- const LLUUID& placeholder_texture_id,
- S32 media_width, S32 media_height, U8 media_auto_scale,
- U8 media_loop);
- static void stop();
- static void pause();
- static void start();
- static void seek(F32 time);
+ static void removeMedia(LLViewerMediaImpl* media);
+ static LLViewerMediaImpl* getMediaImplFromTextureID(const LLUUID& texture_id);
+ static std::string getCurrentUserAgent();
+ static void updateBrowserUserAgent();
+ static bool handleSkinCurrentChanged(const LLSD& /*newvalue*/);
+ static bool textureHasMedia(const LLUUID& texture_id);
static void setVolume(F32 volume);
- static LLMediaBase::EStatus getStatus();
- static LLUUID getMediaTextureID();
- static bool getMediaSize(S32 *media_width, S32 *media_height);
- static bool getTextureSize(S32 *texture_width, S32 *texture_height);
- static bool isMediaPlaying();
- static bool isMediaPaused();
- static bool hasMedia();
- static bool isActiveMediaTexture(const LLUUID& id);
+ static void updateMedia();
+ static bool isMusicPlaying();
+
+ static void cleanupClass();
+
+ static void toggleMusicPlay(void*);
+ static void toggleMediaPlay(void*);
+ static void mediaStop(void*);
+};
+
+// Implementation functions not exported into header file
+class LLViewerMediaImpl
+ : public LLMouseHandler, public LLRefCount, public LLPluginClassMediaOwner, public LLViewerMediaEventEmitter, public LLEditMenuHandler
+{
+ LOG_CLASS(LLViewerMediaImpl);
+public:
+
+ LLViewerMediaImpl(const std::string& media_url,
+ const LLUUID& texture_id,
+ S32 media_width,
+ S32 media_height,
+ U8 media_auto_scale,
+ U8 media_loop,
+ const std::string& mime_type);
+
+ ~LLViewerMediaImpl();
+ void createMediaSource();
+ void destroyMediaSource();
+ void setMediaType(const std::string& media_type);
+ bool initializeMedia(const std::string& mime_type);
+ bool initializePlugin(const std::string& media_type);
+ LLPluginClassMedia* getMediaPlugin() { return mMediaSource; }
+ void setSize(int width, int height);
+
+ void play();
+ void stop();
+ void pause();
+ void start();
+ void seek(F32 time);
+ void setVolume(F32 volume);
+ void focus(bool focus);
+ void mouseDown(S32 x, S32 y);
+ void mouseUp(S32 x, S32 y);
+ void mouseMove(S32 x, S32 y);
+ void mouseLeftDoubleClick(S32 x,S32 y );
+ void mouseCapture();
+
+ void navigateHome();
+ void navigateTo(const std::string& url, const std::string& mime_type = "", bool rediscover_type = false);
+ void navigateStop();
+ bool handleKeyHere(KEY key, MASK mask);
+ bool handleUnicodeCharHere(llwchar uni_char);
+ bool canNavigateForward();
+ bool canNavigateBack();
+ std::string getMediaURL() { return mMediaURL; }
+ std::string getMediaHomeURL() { return mHomeURL; }
+ std::string getMimeType() { return mMimeType; }
+ void scaleMouse(S32 *mouse_x, S32 *mouse_y);
+
+ void update();
+ void updateMovieImage(const LLUUID& image_id, BOOL active);
+ void updateImagesMediaStreams();
+ LLUUID getMediaTextureID();
+
+ void suspendUpdates(bool suspend) { mSuspendUpdates = suspend; };
+ void setVisible(bool visible);
+
+ bool isMediaPlaying();
+ bool isMediaPaused();
+ bool hasMedia();
+
+ // utility function to create a ready-to-use media instance from a desired media type.
+ static LLPluginClassMedia* newSourceFromMediaType(std::string media_type, LLPluginClassMediaOwner *owner /* may be NULL */, S32 default_width, S32 default_height);
+
+ // Internally set our desired browser user agent string, including
+ // the Second Life version and skin name. Used because we can
+ // switch skins without restarting the app.
+ static void updateBrowserUserAgent();
+
+ // Callback for when the SkinCurrent control is changed to
+ // switch the user agent string to indicate the new skin.
+ static bool handleSkinCurrentChanged(const LLSD& newvalue);
+
+ // need these to handle mouseup...
+ /*virtual*/ void onMouseCaptureLost();
+ /*virtual*/ BOOL handleMouseUp(S32 x, S32 y, MASK mask);
+
+ // Grr... the only thing I want as an LLMouseHandler are the onMouseCaptureLost and handleMouseUp calls.
+ // Sadly, these are all pure virtual, so I have to supply implementations here:
+ /*virtual*/ BOOL handleMouseDown(S32 x, S32 y, MASK mask) { return FALSE; };
+ /*virtual*/ BOOL handleHover(S32 x, S32 y, MASK mask) { return FALSE; };
+ /*virtual*/ BOOL handleScrollWheel(S32 x, S32 y, S32 clicks) { return FALSE; };
+ /*virtual*/ BOOL handleDoubleClick(S32 x, S32 y, MASK mask) { return FALSE; };
+ /*virtual*/ BOOL handleRightMouseDown(S32 x, S32 y, MASK mask) { return FALSE; };
+ /*virtual*/ BOOL handleRightMouseUp(S32 x, S32 y, MASK mask) { return FALSE; };
+ /*virtual*/ BOOL handleToolTip(S32 x, S32 y, std::string& msg, LLRect* sticky_rect_screen) { return FALSE; };
+ /*virtual*/ BOOL handleMiddleMouseDown(S32 x, S32 y, MASK mask) { return FALSE; };
+ /*virtual*/ BOOL handleMiddleMouseUp(S32 x, S32 y, MASK mask) {return FALSE; };
+ /*virtual*/ const std::string& getName() const { return LLStringUtil::null; };
+ /*virtual*/ BOOL isView() const { return FALSE; };
+ /*virtual*/ void screenPointToLocal(S32 screen_x, S32 screen_y, S32* local_x, S32* local_y) const {};
+ /*virtual*/ void localPointToScreen(S32 local_x, S32 local_y, S32* screen_x, S32* screen_y) const {};
+ /*virtual*/ BOOL hasMouseCapture() { return gFocusMgr.getMouseCapture() == this; };
+
+ // Inherited from LLPluginClassMediaOwner
+ /*virtual*/ void handleMediaEvent(LLPluginClassMedia* self, LLPluginClassMediaOwner::EMediaEvent);
+
+ // LLEditMenuHandler overrides
+ /*virtual*/ void cut();
+ /*virtual*/ BOOL canCut() const;
+
+ /*virtual*/ void copy();
+ /*virtual*/ BOOL canCopy() const;
- static std::string getMediaURL();
- static std::string getMimeType();
- static void setMimeType(std::string mime_type);
+ /*virtual*/ void paste();
+ /*virtual*/ BOOL canPaste() const;
+
+public:
+ // a single media url with some data and an impl.
+ LLPluginClassMedia* mMediaSource;
+ LLUUID mTextureId;
+ bool mMovieImageHasMips;
+ std::string mMediaURL;
+ std::string mHomeURL;
+ std::string mMimeType;
+ S32 mLastMouseX; // save the last mouse coord we get, so when we lose capture we can simulate a mouseup at that point.
+ S32 mLastMouseY;
+ S32 mMediaWidth;
+ S32 mMediaHeight;
+ bool mMediaAutoScale;
+ bool mMediaLoop;
+ bool mNeedsNewTexture;
+ bool mSuspendUpdates;
+ bool mVisible;
- static void updateImagesMediaStreams();
- private:
- // Fill in initialization data for LLMediaManager::initClass()
- static void buildMediaManagerData( LLMediaManagerData* init_data );
+private:
+ LLViewerMediaTexture *updatePlaceholderImage();
};
#endif // LLVIEWERMEDIA_H
diff --git a/indra/newview/llviewermedia_streamingaudio.cpp b/indra/newview/llviewermedia_streamingaudio.cpp
new file mode 100644
index 0000000000..90cfb85821
--- /dev/null
+++ b/indra/newview/llviewermedia_streamingaudio.cpp
@@ -0,0 +1,167 @@
+/**
+ * @file llviewermedia_streamingaudio.h
+ * @author Tofu Linden, Sam Kolb
+ * @brief LLStreamingAudio_MediaPlugins implementation - an implementation of the streaming audio interface which is implemented as a client of the media plugins API.
+ *
+ * $LicenseInfo:firstyear=2009&license=viewergpl$
+ *
+ * Copyright (c) 2009, Linden Research, Inc.
+ *
+ * Second Life Viewer Source Code
+ * The source code in this file ("Source Code") is provided by Linden Lab
+ * to you under the terms of the GNU General Public License, version 2.0
+ * ("GPL"), unless you have obtained a separate licensing agreement
+ * ("Other License"), formally executed by you and Linden Lab. Terms of
+ * the GPL can be found in doc/GPL-license.txt in this distribution, or
+ * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
+ *
+ * There are special exceptions to the terms and conditions of the GPL as
+ * it is applied to this Source Code. View the full text of the exception
+ * in the file doc/FLOSS-exception.txt in this software distribution, or
+ * online at
+ * http://secondlifegrid.net/programs/open_source/licensing/flossexception
+ *
+ * By copying, modifying or distributing this software, you acknowledge
+ * that you have read and understood your obligations described above,
+ * and agree to abide by those obligations.
+ *
+ * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+ * COMPLETENESS OR PERFORMANCE.
+ * $/LicenseInfo$
+ */
+#include "llviewerprecompiledheaders.h"
+#include "linden_common.h"
+#include "llpluginclassmedia.h"
+#include "llviewermedia.h"
+
+#include "llviewermedia_streamingaudio.h"
+
+#include "llmimetypes.h"
+#include "llvfs.h"
+#include "lldir.h"
+
+
+LLStreamingAudio_MediaPlugins::LLStreamingAudio_MediaPlugins() :
+ mMediaPlugin(NULL),
+ mGain(1.0)
+{
+ // nothing interesting to do?
+ // we will lazily create a media plugin at play-time, if none exists.
+}
+
+LLStreamingAudio_MediaPlugins::~LLStreamingAudio_MediaPlugins()
+{
+ delete mMediaPlugin;
+ mMediaPlugin = NULL;
+}
+
+void LLStreamingAudio_MediaPlugins::start(const std::string& url)
+{
+ if (!mMediaPlugin) // lazy-init the underlying media plugin
+ {
+ mMediaPlugin = initializeMedia("audio/mpeg"); // assumes that whatever media implementation supports mp3 also supports vorbis.
+ llinfos << "mMediaPlugin is now " << mMediaPlugin << llendl;
+ }
+
+ if(!mMediaPlugin)
+ return;
+
+ if (!url.empty()) {
+ llinfos << "Starting internet stream: " << url << llendl;
+ mURL = url;
+ mMediaPlugin->loadURI ( url );
+ mMediaPlugin->start();
+ llinfos << "Playing....." << llendl;
+ } else {
+ llinfos << "setting stream to NULL"<< llendl;
+ mURL.clear();
+ mMediaPlugin->stop();
+ }
+}
+
+void LLStreamingAudio_MediaPlugins::stop()
+{
+ if(mMediaPlugin)
+ {
+ mMediaPlugin->stop();
+ }
+
+ mURL.clear();
+}
+
+void LLStreamingAudio_MediaPlugins::pause(int pause)
+{
+ if(!mMediaPlugin)
+ return;
+
+ if(pause)
+ {
+ mMediaPlugin->pause();
+ }
+ else
+ {
+ mMediaPlugin->start();
+ }
+}
+
+void LLStreamingAudio_MediaPlugins::update()
+{
+ if (mMediaPlugin)
+ mMediaPlugin->idle();
+}
+
+int LLStreamingAudio_MediaPlugins::isPlaying()
+{
+ if (!mMediaPlugin)
+ return 0;
+
+ // *TODO: can probably do better than this
+ if (mMediaPlugin->isPluginRunning())
+ {
+ return 1; // Active and playing
+ }
+
+ if (mMediaPlugin->isPluginExited())
+ {
+ return 0; // stopped
+ }
+
+ return 2; // paused
+}
+
+void LLStreamingAudio_MediaPlugins::setGain(F32 vol)
+{
+ mGain = vol;
+
+ if(!mMediaPlugin)
+ return;
+
+ vol = llclamp(vol, 0.f, 1.f);
+ mMediaPlugin->setVolume(vol);
+}
+
+F32 LLStreamingAudio_MediaPlugins::getGain()
+{
+ return mGain;
+}
+
+std::string LLStreamingAudio_MediaPlugins::getURL()
+{
+ return mURL;
+}
+
+LLPluginClassMedia* LLStreamingAudio_MediaPlugins::initializeMedia(const std::string& media_type)
+{
+ LLPluginClassMediaOwner* owner = NULL;
+ S32 default_size = 1; // audio-only - be minimal, doesn't matter
+ LLPluginClassMedia* media_source = LLViewerMediaImpl::newSourceFromMediaType(media_type, owner, default_size, default_size);
+
+ if (media_source)
+ {
+ media_source->setLoop(false); // audio streams are not expected to loop
+ }
+
+ return media_source;
+}
+
diff --git a/indra/newview/llviewermedia_streamingaudio.h b/indra/newview/llviewermedia_streamingaudio.h
new file mode 100644
index 0000000000..270bab7625
--- /dev/null
+++ b/indra/newview/llviewermedia_streamingaudio.h
@@ -0,0 +1,69 @@
+/**
+ * @file llviewermedia_streamingaudio.h
+ * @author Tofu Linden
+ * @brief Definition of LLStreamingAudio_MediaPlugins implementation - an implementation of the streaming audio interface which is implemented as a client of the media plugins API.
+ *
+ * $LicenseInfo:firstyear=2009&license=viewergpl$
+ *
+ * Copyright (c) 2009, Linden Research, Inc.
+ *
+ * Second Life Viewer Source Code
+ * The source code in this file ("Source Code") is provided by Linden Lab
+ * to you under the terms of the GNU General Public License, version 2.0
+ * ("GPL"), unless you have obtained a separate licensing agreement
+ * ("Other License"), formally executed by you and Linden Lab. Terms of
+ * the GPL can be found in doc/GPL-license.txt in this distribution, or
+ * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
+ *
+ * There are special exceptions to the terms and conditions of the GPL as
+ * it is applied to this Source Code. View the full text of the exception
+ * in the file doc/FLOSS-exception.txt in this software distribution, or
+ * online at
+ * http://secondlifegrid.net/programs/open_source/licensing/flossexception
+ *
+ * By copying, modifying or distributing this software, you acknowledge
+ * that you have read and understood your obligations described above,
+ * and agree to abide by those obligations.
+ *
+ * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+ * COMPLETENESS OR PERFORMANCE.
+ * $/LicenseInfo$
+ */
+
+#ifndef LL_VIEWERMEDIA_STREAMINGAUDIO_H
+#define LL_VIEWERMEDIA_STREAMINGAUDIO_H
+
+
+#include "stdtypes.h" // from llcommon
+
+#include "llstreamingaudio.h"
+
+class LLPluginClassMedia;
+
+class LLStreamingAudio_MediaPlugins : public LLStreamingAudioInterface
+{
+ public:
+ LLStreamingAudio_MediaPlugins();
+ /*virtual*/ ~LLStreamingAudio_MediaPlugins();
+
+ /*virtual*/ void start(const std::string& url);
+ /*virtual*/ void stop();
+ /*virtual*/ void pause(int pause);
+ /*virtual*/ void update();
+ /*virtual*/ int isPlaying();
+ /*virtual*/ void setGain(F32 vol);
+ /*virtual*/ F32 getGain();
+ /*virtual*/ std::string getURL();
+
+private:
+ LLPluginClassMedia* initializeMedia(const std::string& media_type);
+
+ LLPluginClassMedia *mMediaPlugin;
+
+ std::string mURL;
+ F32 mGain;
+};
+
+
+#endif //LL_VIEWERMEDIA_STREAMINGAUDIO_H
diff --git a/indra/newview/llviewermediafocus.cpp b/indra/newview/llviewermediafocus.cpp
new file mode 100644
index 0000000000..60eabd730f
--- /dev/null
+++ b/indra/newview/llviewermediafocus.cpp
@@ -0,0 +1,355 @@
+/**
+ * @file llviewermediafocus.cpp
+ * @brief Governs focus on Media prims
+ *
+ * $LicenseInfo:firstyear=2003&license=viewergpl$
+ *
+ * Copyright (c) 2003-2007, Linden Research, Inc.
+ *
+ * Second Life Viewer Source Code
+ * The source code in this file ("Source Code") is provided by Linden Lab
+ * to you under the terms of the GNU General Public License, version 2.0
+ * ("GPL"), unless you have obtained a separate licensing agreement
+ * ("Other License"), formally executed by you and Linden Lab. Terms of
+ * the GPL can be found in doc/GPL-license.txt in this distribution, or
+ * online at http://secondlife.com/developers/opensource/gplv2
+ *
+ * There are special exceptions to the terms and conditions of the GPL as
+ * it is applied to this Source Code. View the full text of the exception
+ * in the file doc/FLOSS-exception.txt in this software distribution, or
+ * online at http://secondlife.com/developers/opensource/flossexception
+ *
+ * By copying, modifying or distributing this software, you acknowledge
+ * that you have read and understood your obligations described above,
+ * and agree to abide by those obligations.
+ *
+ * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+ * COMPLETENESS OR PERFORMANCE.
+ * $/LicenseInfo$
+ */
+
+#include "llviewerprecompiledheaders.h"
+
+#include "llviewermediafocus.h"
+
+//LLViewerMediaFocus
+#include "llviewerobjectlist.h"
+#include "llpanelmediahud.h"
+#include "llpluginclassmedia.h"
+#include "llagent.h"
+#include "lltoolpie.h"
+#include "llviewercamera.h"
+#include "llviewermedia.h"
+#include "llhudview.h"
+#include "lluictrlfactory.h"
+#include "lldrawable.h"
+#include "llparcel.h"
+#include "llviewerparcelmgr.h"
+#include "llweb.h"
+//
+// LLViewerMediaFocus
+//
+
+LLViewerMediaFocus::LLViewerMediaFocus()
+: mMouseOverFlag(false)
+{
+}
+
+LLViewerMediaFocus::~LLViewerMediaFocus()
+{
+ // The destructor for LLSingletons happens at atexit() time, which is too late to do much.
+ // Clean up in cleanupClass() instead.
+}
+
+void LLViewerMediaFocus::cleanupClass()
+{
+ LLViewerMediaFocus *self = LLViewerMediaFocus::getInstance();
+
+ if(self)
+ {
+ // mMediaHUD will have been deleted by this point -- don't try to delete it.
+
+ /* Richard says:
+ all widgets are supposed to be destroyed at the same time
+ you shouldn't hold on to pointer to them outside of ui code
+ you can use the LLHandle approach
+ if you want to be type safe, you'll need to add a LLRootHandle to whatever derived class you are pointing to
+ look at llview::gethandle
+ its our version of a weak pointer
+ */
+ if(self->mMediaHUD.get())
+ {
+ self->mMediaHUD.get()->setMediaImpl(NULL);
+ }
+ self->mMediaImpl = NULL;
+ }
+
+}
+
+
+void LLViewerMediaFocus::setFocusFace( BOOL b, LLPointer<LLViewerObject> objectp, S32 face, viewer_media_t media_impl )
+{
+ LLParcel *parcel = LLViewerParcelMgr::getInstance()->getAgentParcel();
+ if (b && media_impl.notNull())
+ {
+ mMediaImpl = media_impl;
+ LLSelectMgr::getInstance()->deselectAll();
+ LLSelectMgr::getInstance()->selectObjectOnly(objectp, face);
+
+ mFocus = LLSelectMgr::getInstance()->getSelection();
+ if(mMediaHUD.get() && ! parcel->getMediaPreventCameraZoom())
+ {
+ mMediaHUD.get()->resetZoomLevel();
+ mMediaHUD.get()->nextZoomLevel();
+ }
+ if (!mFocus->isEmpty())
+ {
+ gFocusMgr.setKeyboardFocus(this);
+ }
+ mObjectID = objectp->getID();
+ // LLViewerMedia::addObserver(this, mObjectID);
+
+
+ }
+ else
+ {
+ gFocusMgr.setKeyboardFocus(NULL);
+ mFocus = NULL;
+ if(! parcel->getMediaPreventCameraZoom())
+ {
+ gAgent.setFocusOnAvatar(TRUE, ANIMATE);
+ }
+ // LLViewerMedia::remObserver(this, mObjectID);
+
+ // Null out the media hud media pointer
+ if(mMediaHUD.get())
+ {
+ mMediaHUD.get()->setMediaImpl(NULL);
+ }
+
+ // and null out the media impl
+ mMediaImpl = NULL;
+ }
+ if(mMediaHUD.get())
+ {
+ mMediaHUD.get()->setMediaFocus(b);
+ }
+}
+bool LLViewerMediaFocus::getFocus()
+{
+ if (gFocusMgr.getKeyboardFocus() == this)
+ {
+ return true;
+ }
+ return false;
+}
+
+// This function selects an ideal viewing distance given a selection bounding box, normal, and padding value
+void LLViewerMediaFocus::setCameraZoom(F32 padding_factor)
+{
+ LLPickInfo& pick = LLToolPie::getInstance()->getPick();
+
+ if(LLSelectMgr::getInstance()->getSelection()->isEmpty())
+ {
+ pick = mPickInfo;
+ setFocusFace(true, pick.getObject(), pick.mObjectFace, mMediaImpl);
+ }
+
+ if (!LLSelectMgr::getInstance()->getSelection()->isEmpty())
+ {
+ gAgent.setFocusOnAvatar(FALSE, ANIMATE);
+
+ LLBBox selection_bbox = LLSelectMgr::getInstance()->getBBoxOfSelection();
+ F32 height;
+ F32 width;
+ F32 depth;
+ F32 angle_of_view;
+ F32 distance;
+
+ // We need the aspect ratio, and the 3 components of the bbox as height, width, and depth.
+ F32 aspect_ratio = getBBoxAspectRatio(selection_bbox, pick.mNormal, &height, &width, &depth);
+ F32 camera_aspect = LLViewerCamera::getInstance()->getAspect();
+
+ // We will normally use the side of the volume aligned with the short side of the screen (i.e. the height for
+ // a screen in a landscape aspect ratio), however there is an edge case where the aspect ratio of the object is
+ // more extreme than the screen. In this case we invert the logic, using the longer component of both the object
+ // and the screen.
+ bool invert = (camera_aspect > 1.0f && aspect_ratio > camera_aspect) ||
+ (camera_aspect < 1.0f && aspect_ratio < camera_aspect);
+
+ // To calculate the optimum viewing distance we will need the angle of the shorter side of the view rectangle.
+ // In portrait mode this is the width, and in landscape it is the height.
+ // We then calculate the distance based on the corresponding side of the object bbox (width for portrait, height for landscape)
+ // We will add half the depth of the bounding box, as the distance projection uses the center point of the bbox.
+ if(camera_aspect < 1.0f || invert)
+ {
+ angle_of_view = llmax(0.1f, LLViewerCamera::getInstance()->getView() * LLViewerCamera::getInstance()->getAspect());
+ distance = width * 0.5 * padding_factor / tan(angle_of_view * 0.5f );
+ }
+ else
+ {
+ angle_of_view = llmax(0.1f, LLViewerCamera::getInstance()->getView());
+ distance = height * 0.5 * padding_factor / tan(angle_of_view * 0.5f );
+ }
+
+ distance += depth * 0.5;
+
+ // Finally animate the camera to this new position and focal point
+ gAgent.setCameraPosAndFocusGlobal(LLSelectMgr::getInstance()->getSelectionCenterGlobal() + LLVector3d(pick.mNormal * distance),
+ LLSelectMgr::getInstance()->getSelectionCenterGlobal(), LLSelectMgr::getInstance()->getSelection()->getFirstObject()->mID );
+ }
+}
+void LLViewerMediaFocus::onFocusReceived()
+{
+ if(mMediaImpl.notNull())
+ mMediaImpl->focus(true);
+
+ LLFocusableElement::onFocusReceived();
+}
+
+void LLViewerMediaFocus::onFocusLost()
+{
+ if(mMediaImpl.notNull())
+ mMediaImpl->focus(false);
+ gViewerWindow->focusClient();
+ mFocus = NULL;
+ LLFocusableElement::onFocusLost();
+}
+void LLViewerMediaFocus::setMouseOverFlag(bool b, viewer_media_t media_impl)
+{
+ if (b && media_impl.notNull())
+ {
+ if(! mMediaHUD.get())
+ {
+ LLPanelMediaHUD* media_hud = new LLPanelMediaHUD(mMediaImpl);
+ mMediaHUD = media_hud->getHandle();
+ gHUDView->addChild(media_hud);
+ }
+ mMediaHUD.get()->setMediaImpl(media_impl);
+ mMediaImpl = media_impl;
+ }
+ mMouseOverFlag = b;
+}
+LLUUID LLViewerMediaFocus::getSelectedUUID()
+{
+ LLViewerObject* object = mFocus->getFirstObject();
+ return object ? object->getID() : LLUUID::null;
+}
+#if 0 // Must re-implement when the new media api event system is ready
+void LLViewerMediaFocus::onNavigateComplete( const EventType& event_in )
+{
+ if (hasFocus() && mLastURL != event_in.getStringValue())
+ {
+ LLViewerMedia::focus(true, mObjectID);
+ // spoof mouse event to reassert focus
+ LLViewerMedia::mouseDown(1,1, mObjectID);
+ LLViewerMedia::mouseUp(1,1, mObjectID);
+ }
+ mLastURL = event_in.getStringValue();
+}
+#endif
+BOOL LLViewerMediaFocus::handleKey(KEY key, MASK mask, BOOL called_from_parent)
+{
+ if(mMediaImpl.notNull())
+ mMediaImpl->handleKeyHere(key, mask);
+ return true;
+}
+
+BOOL LLViewerMediaFocus::handleUnicodeChar(llwchar uni_char, BOOL called_from_parent)
+{
+ if(mMediaImpl.notNull())
+ mMediaImpl->handleUnicodeCharHere(uni_char);
+ return true;
+}
+BOOL LLViewerMediaFocus::handleScrollWheel(S32 x, S32 y, S32 clicks)
+{
+ BOOL retval = FALSE;
+ if(mFocus.notNull() && mMediaImpl.notNull() && mMediaImpl->hasMedia())
+ {
+ mMediaImpl->getMediaPlugin()->scrollEvent(x, y, clicks);
+ retval = TRUE;
+ }
+ return retval;
+}
+
+void LLViewerMediaFocus::update()
+{
+ if (mMediaHUD.get())
+ {
+ if(mFocus.notNull() || mMouseOverFlag || mMediaHUD.get()->isMouseOver())
+ {
+ // mMediaHUD.get()->setVisible(true);
+ mMediaHUD.get()->updateShape();
+ }
+ else
+ {
+ mMediaHUD.get()->setVisible(false);
+ }
+ }
+}
+// This function calculates the aspect ratio and the world aligned components of a selection bounding box.
+F32 LLViewerMediaFocus::getBBoxAspectRatio(const LLBBox& bbox, const LLVector3& normal, F32* height, F32* width, F32* depth)
+{
+ // Convert the selection normal and an up vector to local coordinate space of the bbox
+ LLVector3 local_normal = bbox.agentToLocalBasis(normal);
+ LLVector3 z_vec = bbox.agentToLocalBasis(LLVector3(0.0f, 0.0f, 1.0f));
+
+ LLVector3 comp1(0.f,0.f,0.f);
+ LLVector3 comp2(0.f,0.f,0.f);
+ LLVector3 bbox_max = bbox.getExtentLocal();
+ F32 dot1 = 0.f;
+ F32 dot2 = 0.f;
+
+ // The largest component of the localized normal vector is the depth component
+ // meaning that the other two are the legs of the rectangle.
+ local_normal.abs();
+ if(local_normal.mV[VX] > local_normal.mV[VY])
+ {
+ if(local_normal.mV[VX] > local_normal.mV[VZ])
+ {
+ // Use the y and z comps
+ comp1.mV[VY] = bbox_max.mV[VY];
+ comp2.mV[VZ] = bbox_max.mV[VZ];
+ *depth = bbox_max.mV[VX];
+ }
+ else
+ {
+ // Use the x and y comps
+ comp1.mV[VY] = bbox_max.mV[VY];
+ comp2.mV[VZ] = bbox_max.mV[VZ];
+ *depth = bbox_max.mV[VZ];
+ }
+ }
+ else if(local_normal.mV[VY] > local_normal.mV[VZ])
+ {
+ // Use the x and z comps
+ comp1.mV[VX] = bbox_max.mV[VX];
+ comp2.mV[VZ] = bbox_max.mV[VZ];
+ *depth = bbox_max.mV[VY];
+ }
+ else
+ {
+ // Use the x and y comps
+ comp1.mV[VY] = bbox_max.mV[VY];
+ comp2.mV[VZ] = bbox_max.mV[VZ];
+ *depth = bbox_max.mV[VX];
+ }
+
+ // The height is the vector closest to vertical in the bbox coordinate space (highest dot product value)
+ dot1 = comp1 * z_vec;
+ dot2 = comp2 * z_vec;
+ if(fabs(dot1) > fabs(dot2))
+ {
+ *height = comp1.length();
+ *width = comp2.length();
+ }
+ else
+ {
+ *height = comp2.length();
+ *width = comp1.length();
+ }
+
+ // Return the aspect ratio.
+ return *width / *height;
+}
diff --git a/indra/newview/llviewermediafocus.h b/indra/newview/llviewermediafocus.h
new file mode 100644
index 0000000000..a078d24b6a
--- /dev/null
+++ b/indra/newview/llviewermediafocus.h
@@ -0,0 +1,90 @@
+/**
+ * @file llpanelmsgs.h
+ * @brief Message popup preferences panel
+ *
+ * $LicenseInfo:firstyear=2003&license=viewergpl$
+ *
+ * Copyright (c) 2003-2007, Linden Research, Inc.
+ *
+ * Second Life Viewer Source Code
+ * The source code in this file ("Source Code") is provided by Linden Lab
+ * to you under the terms of the GNU General Public License, version 2.0
+ * ("GPL"), unless you have obtained a separate licensing agreement
+ * ("Other License"), formally executed by you and Linden Lab. Terms of
+ * the GPL can be found in doc/GPL-license.txt in this distribution, or
+ * online at http://secondlife.com/developers/opensource/gplv2
+ *
+ * There are special exceptions to the terms and conditions of the GPL as
+ * it is applied to this Source Code. View the full text of the exception
+ * in the file doc/FLOSS-exception.txt in this software distribution, or
+ * online at http://secondlife.com/developers/opensource/flossexception
+ *
+ * By copying, modifying or distributing this software, you acknowledge
+ * that you have read and understood your obligations described above,
+ * and agree to abide by those obligations.
+ *
+ * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+ * COMPLETENESS OR PERFORMANCE.
+ * $/LicenseInfo$
+ */
+
+#ifndef LL_VIEWERMEDIAFOCUS_H
+#define LL_VIEWERMEDIAFOCUS_H
+
+// includes for LLViewerMediaFocus
+#include "llfocusmgr.h"
+#include "llviewermedia.h"
+#include "llviewerobject.h"
+#include "llviewerwindow.h"
+#include "llselectmgr.h"
+
+class LLViewerMediaImpl;
+class LLPanelMediaHUD;
+
+class LLViewerMediaFocus :
+ public LLFocusableElement,
+ public LLSingleton<LLViewerMediaFocus>
+{
+public:
+ LLViewerMediaFocus();
+ ~LLViewerMediaFocus();
+
+ static void cleanupClass();
+
+ void setFocusFace(BOOL b, LLPointer<LLViewerObject> objectp, S32 face, viewer_media_t media_impl);
+ void clearFocus() { setFocusFace(false, NULL, 0, NULL); }
+ /*virtual*/ bool getFocus();
+ /*virtual*/ // void onNavigateComplete( const EventType& event_in );
+
+ /*virtual*/ BOOL handleKey(KEY key, MASK mask, BOOL called_from_parent);
+ /*virtual*/ BOOL handleUnicodeChar(llwchar uni_char, BOOL called_from_parent);
+ BOOL handleScrollWheel(S32 x, S32 y, S32 clicks);
+
+ LLUUID getSelectedUUID();
+ LLObjectSelectionHandle getSelection() { return mFocus; }
+
+ void update();
+
+ void setCameraZoom(F32 padding_factor);
+ void setMouseOverFlag(bool b, viewer_media_t media_impl = NULL);
+ bool getMouseOverFlag() { return mMouseOverFlag; }
+ void setPickInfo(LLPickInfo pick_info) { mPickInfo = pick_info; }
+ F32 getBBoxAspectRatio(const LLBBox& bbox, const LLVector3& normal, F32* height, F32* width, F32* depth);
+
+protected:
+ /*virtual*/ void onFocusReceived();
+ /*virtual*/ void onFocusLost();
+
+private:
+ LLObjectSelectionHandle mFocus;
+ std::string mLastURL;
+ bool mMouseOverFlag;
+ LLPickInfo mPickInfo;
+ LLHandle<LLPanelMediaHUD> mMediaHUD;
+ LLUUID mObjectID;
+ viewer_media_t mMediaImpl;
+};
+
+
+#endif // LL_VIEWERMEDIAFOCUS_H
diff --git a/indra/newview/llviewermediaobserver.h b/indra/newview/llviewermediaobserver.h
new file mode 100644
index 0000000000..6667f982b6
--- /dev/null
+++ b/indra/newview/llviewermediaobserver.h
@@ -0,0 +1,71 @@
+/**
+ * @file llviewermediaobserver.h
+ * @brief Methods to override to catch events from LLViewerMedia class
+ *
+ * $LicenseInfo:firstyear=2007&license=viewergpl$
+ *
+ * Copyright (c) 2007-2009, Linden Research, Inc.
+ *
+ * Second Life Viewer Source Code
+ * The source code in this file ("Source Code") is provided by Linden Lab
+ * to you under the terms of the GNU General Public License, version 2.0
+ * ("GPL"), unless you have obtained a separate licensing agreement
+ * ("Other License"), formally executed by you and Linden Lab. Terms of
+ * the GPL can be found in doc/GPL-license.txt in this distribution, or
+ * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
+ *
+ * There are special exceptions to the terms and conditions of the GPL as
+ * it is applied to this Source Code. View the full text of the exception
+ * in the file doc/FLOSS-exception.txt in this software distribution, or
+ * online at
+ * http://secondlifegrid.net/programs/open_source/licensing/flossexception
+ *
+ * By copying, modifying or distributing this software, you acknowledge
+ * that you have read and understood your obligations described above,
+ * and agree to abide by those obligations.
+ *
+ * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+ * COMPLETENESS OR PERFORMANCE.
+ * $/LicenseInfo$
+ */
+
+#ifndef LLVIEWERMEDIAOBSERVER_H
+#define LLVIEWERMEDIAOBSERVER_H
+
+#include "llpluginclassmediaowner.h"
+
+class LLViewerMediaEventEmitter;
+
+class LLViewerMediaObserver : public LLPluginClassMediaOwner
+{
+public:
+ virtual ~LLViewerMediaObserver();
+
+private:
+ // Emitters will manage this list in addObserver/remObserver.
+ friend class LLViewerMediaEventEmitter;
+ std::list<LLViewerMediaEventEmitter *> mEmitters;
+};
+
+
+#if 0
+ // Classes that inherit from LLViewerMediaObserver should add this to their class declaration:
+
+ // inherited from LLViewerMediaObserver
+ /*virtual*/ void handleMediaEvent(LLPluginClassMedia* self, EMediaEvent event);
+
+ /* and will probably need to add this to their cpp file:
+
+ #include "llpluginclassmedia.h"
+
+ */
+
+ // The list of events is in llpluginclassmediaowner.h
+
+
+#endif
+
+
+#endif // LLVIEWERMEDIAOBSERVER_H
+
diff --git a/indra/newview/llviewermenu.cpp b/indra/newview/llviewermenu.cpp
index ac36cf7bb6..8a5928f4e9 100644
--- a/indra/newview/llviewermenu.cpp
+++ b/indra/newview/llviewermenu.cpp
@@ -40,10 +40,12 @@
#include <sstream>
// linden library includes
-#include "audioengine.h"
+#include "llaudioengine.h"
+#include "llfloaterreg.h"
#include "indra_constants.h"
#include "llassetstorage.h"
#include "llchat.h"
+#include "llcombobox.h"
#include "llfeaturemanager.h"
#include "llfocusmgr.h"
#include "llfontgl.h"
@@ -64,7 +66,7 @@
// newview includes
#include "llagent.h"
-
+#include "llagentwearables.h"
#include "llagentpilot.h"
#include "llbox.h"
#include "llcallingcard.h"
@@ -79,37 +81,31 @@
#include "lldrawpooltree.h"
#include "llface.h"
#include "llfirstuse.h"
+#include "llfirsttimetipmanager.h"
#include "llfloater.h"
#include "llfloaterabout.h"
#include "llfloaterbuycurrency.h"
#include "llfloateractivespeakers.h"
#include "llfloateranimpreview.h"
-#include "llfloateravatarinfo.h"
#include "llfloateravatartextures.h"
-#include "llfloaterbeacons.h"
#include "llfloaterbuildoptions.h"
#include "llfloaterbump.h"
#include "llfloaterbuy.h"
#include "llfloaterbuycontents.h"
#include "llfloaterbuycurrency.h"
#include "llfloaterbuyland.h"
-#include "llfloatercamera.h"
#include "llfloaterchat.h"
#include "llfloatercustomize.h"
#include "llfloaterdaycycle.h"
#include "llfloaterdirectory.h"
-#include "llfloatereditui.h"
#include "llfloaterchatterbox.h"
-#include "llfloaterfriends.h"
#include "llfloaterfonttest.h"
#include "llfloatergesture.h"
#include "llfloatergodtools.h"
-#include "llfloatergroupinfo.h"
#include "llfloatergroupinvite.h"
#include "llfloatergroups.h"
-#include "llfloaterhtml.h"
#include "llfloaterhtmlcurrency.h"
-#include "llfloaterhtmlhelp.h" // gViewerHtmlHelp
+#include "llfloatermediabrowser.h" // gViewerHtmlHelp
#include "llfloaterhtmlsimple.h"
#include "llfloaterhud.h"
#include "llfloaterinspect.h"
@@ -119,25 +115,23 @@
#include "llfloatermap.h"
#include "llfloatermute.h"
#include "llfloateropenobject.h"
-#include "llfloaterpermissionsmgr.h"
#include "llfloaterperms.h"
#include "llfloaterpostprocess.h"
#include "llfloaterpreference.h"
+#include "llfloaterreg.h"
#include "llfloaterregioninfo.h"
#include "llfloaterreporter.h"
#include "llfloaterscriptdebug.h"
#include "llfloatersettingsdebug.h"
#include "llfloaterenvsettings.h"
-#include "llfloaterstats.h"
-#include "llfloatertest.h"
#include "llfloatertools.h"
#include "llfloaterwater.h"
#include "llfloaterwindlight.h"
#include "llfloaterworldmap.h"
#include "llfloatermemleak.h"
-#include "llframestats.h"
-#include "llframestatview.h"
#include "llfasttimerview.h"
+#include "llavataractions.h"
+#include "lllandmarkactions.h"
#include "llmemoryview.h"
#include "llgivemoney.h"
#include "llgroupmgr.h"
@@ -148,12 +142,14 @@
#include "llimagebmp.h"
#include "llimagej2c.h"
#include "llimagetga.h"
+#include "llinventorybridge.h"
#include "llinventorymodel.h"
-#include "llinventoryview.h"
+#include "llfloaterinventory.h"
#include "llkeyboard.h"
#include "llpanellogin.h"
#include "llmenucommands.h"
#include "llmenugl.h"
+#include "llmimetypes.h"
#include "llmorphview.h"
#include "llmoveview.h"
#include "llmutelist.h"
@@ -162,7 +158,9 @@
#include "llparcel.h"
#include "llprimitive.h"
#include "llresmgr.h"
+#include "llrootview.h"
#include "llselectmgr.h"
+#include "llsidetray.h"
#include "llsky.h"
#include "llstatusbar.h"
#include "llstatview.h"
@@ -177,17 +175,16 @@
#include "lltoolgrab.h"
#include "lltoolmgr.h"
#include "lltoolpie.h"
-#include "lltoolplacer.h"
#include "lltoolselectland.h"
+#include "lltrans.h"
#include "lluictrlfactory.h"
#include "lluploaddialog.h"
#include "lluserauth.h"
#include "lluuid.h"
-#include "llvelocitybar.h"
#include "llviewercamera.h"
#include "llviewergenericmessage.h"
#include "llviewergesture.h"
-#include "llviewerimagelist.h" // gImageList
+#include "llviewertexturelist.h" // gTextureList
#include "llviewerinventory.h"
#include "llviewermenufile.h" // init_menu_file()
#include "llviewermessage.h"
@@ -199,6 +196,7 @@
#include "llviewerstats.h"
#include "llviewerwindow.h"
#include "llvoavatar.h"
+#include "llvoavatarself.h"
#include "llvolume.h"
#include "llweb.h"
#include "llworld.h"
@@ -216,17 +214,6 @@
#include "lltexlayer.h"
using namespace LLVOAvatarDefines;
-using namespace LLOldEvents;
-
-void init_client_menu(LLMenuGL* menu);
-void init_server_menu(LLMenuGL* menu);
-
-void init_debug_world_menu(LLMenuGL* menu);
-void init_debug_rendering_menu(LLMenuGL* menu);
-void init_debug_ui_menu(LLMenuGL* menu);
-void init_debug_xui_menu(LLMenuGL* menu);
-void init_debug_avatar_menu(LLMenuGL* menu);
-void init_debug_baked_texture_menu(LLMenuGL* menu);
BOOL enable_land_build(void*);
BOOL enable_object_build(void*);
@@ -238,13 +225,14 @@ void handle_test_load_url(void*);
//
// Evil hackish imported globals
-//
-extern BOOL gRenderLightGlows;
-extern BOOL gRenderAvatar;
-extern BOOL gHideSelectedObjects;
-extern BOOL gShowOverlayTitle;
-extern BOOL gOcclusionCull;
-extern BOOL gAllowSelectAvatar;
+
+//extern BOOL gHideSelectedObjects;
+//extern BOOL gAllowSelectAvatar;
+//extern BOOL gDebugAvatarRotation;
+extern BOOL gDebugClicks;
+extern BOOL gDebugWindowProc;
+//extern BOOL gDebugTextEditorTips;
+//extern BOOL gDebugSelectMgr;
//
// Globals
@@ -256,15 +244,11 @@ LLMenuGL *gPopupMenuView = NULL;
LLMenuBarGL *gLoginMenuBarView = NULL;
// Pie menus
-LLPieMenu *gPieSelf = NULL;
-LLPieMenu *gPieAvatar = NULL;
-LLPieMenu *gPieObject = NULL;
-LLPieMenu *gPieAttachment = NULL;
-LLPieMenu *gPieLand = NULL;
-
-// local constants
-const std::string CLIENT_MENU_NAME("Advanced");
-const std::string SERVER_MENU_NAME("Admin");
+LLContextMenu *gPieSelf = NULL;
+LLContextMenu *gPieAvatar = NULL;
+LLContextMenu *gPieObject = NULL;
+LLContextMenu *gPieAttachment = NULL;
+LLContextMenu *gPieLand = NULL;
const std::string SAVE_INTO_INVENTORY("Save Object Back to My Inventory");
const std::string SAVE_INTO_TASK_INVENTORY("Save Object Back to Object Contents");
@@ -272,27 +256,24 @@ const std::string SAVE_INTO_TASK_INVENTORY("Save Object Back to Object Contents"
LLMenuGL* gAttachSubMenu = NULL;
LLMenuGL* gDetachSubMenu = NULL;
LLMenuGL* gTakeOffClothes = NULL;
-LLPieMenu* gPieRate = NULL;
-LLPieMenu* gAttachScreenPieMenu = NULL;
-LLPieMenu* gAttachPieMenu = NULL;
-LLPieMenu* gAttachBodyPartPieMenus[8];
-LLPieMenu* gDetachPieMenu = NULL;
-LLPieMenu* gDetachScreenPieMenu = NULL;
-LLPieMenu* gDetachBodyPartPieMenus[8];
+LLContextMenu* gPieRate = NULL;
+LLContextMenu* gAttachScreenPieMenu = NULL;
+LLContextMenu* gAttachPieMenu = NULL;
+LLContextMenu* gAttachBodyPartPieMenus[8];
+LLContextMenu* gDetachPieMenu = NULL;
+LLContextMenu* gDetachScreenPieMenu = NULL;
+LLContextMenu* gDetachBodyPartPieMenus[8];
LLMenuItemCallGL* gAFKMenu = NULL;
LLMenuItemCallGL* gBusyMenu = NULL;
-typedef LLMemberListener<LLView> view_listener_t;
-
//
// Local prototypes
-//
-void handle_leave_group(void *);
// File Menu
+const char* upload_pick(void* data);
void handle_compress_image(void*);
-BOOL enable_save_as(void *);
+
// Edit menu
void handle_dump_group_info(void *);
@@ -300,7 +281,6 @@ void handle_dump_capabilities_info(void *);
void handle_dump_focus(void*);
// Advanced->Consoles menu
-void handle_show_notifications_console(void*);
void handle_region_dump_settings(void*);
void handle_region_dump_temp_asset_data(void*);
void handle_region_clear_temp_asset_data(void*);
@@ -309,7 +289,7 @@ void handle_region_clear_temp_asset_data(void*);
BOOL sitting_on_selection();
void near_sit_object();
-void label_sit_or_stand(std::string& label, void*);
+//void label_sit_or_stand(std::string& label, void*);
// buy and take alias into the same UI positions, so these
// declarations handle this mess.
BOOL is_selection_buy_not_take();
@@ -321,51 +301,31 @@ BOOL enable_buy(void*);
void handle_buy(void *);
void handle_buy_object(LLSaleInfo sale_info);
void handle_buy_contents(LLSaleInfo sale_info);
-void label_touch(std::string& label, void*);
// Land pie menu
void near_sit_down_point(BOOL success, void *);
// Avatar pie menu
-void handle_follow(void *userdata);
-void handle_talk_to(void *userdata);
// Debug menu
-void show_permissions_control(void*);
-void toggle_build_options(void* user_data);
-void reload_ui(void*);
-void handle_agent_stop_moving(void*);
-void print_packets_lost(void*);
-void drop_packet(void*);
-void velocity_interpolate( void* data );
-void toggle_wind_audio(void);
-void toggle_water_audio(void);
+
+
+void velocity_interpolate( void* );
+
void handle_rebake_textures(void*);
BOOL check_admin_override(void*);
void handle_admin_override_toggle(void*);
#ifdef TOGGLE_HACKED_GODLIKE_VIEWER
void handle_toggle_hacked_godmode(void*);
BOOL check_toggle_hacked_godmode(void*);
+bool enable_toggle_hacked_godmode(void*);
#endif
-void toggle_glow(void *);
-BOOL check_glow(void *);
-
-void toggle_vertex_shaders(void *);
-BOOL check_vertex_shaders(void *);
-
-void toggle_cull_small(void *);
-
void toggle_show_xui_names(void *);
BOOL check_show_xui_names(void *);
-void run_vectorize_perf_test(void *)
-{
- gSavedSettings.setBOOL("VectorizePerfTest", TRUE);
-}
-
// Debug UI
-void handle_web_search_demo(void*);
+
void handle_web_browser_test(void*);
void handle_buy_currency_test(void*);
void handle_save_to_xml(void*);
@@ -376,16 +336,12 @@ void handle_god_mode(void*);
// God menu
void handle_leave_god_mode(void*);
-BOOL is_inventory_visible( void* user_data );
+
void handle_reset_view();
-void disabled_duplicate(void*);
void handle_duplicate_in_place(void*);
-void handle_repeat_duplicate(void*);
-void handle_export(void*);
-// void handle_deed_object_to_group(void*);
-// BOOL enable_deed_object_to_group(void*);
+
void handle_object_owner_self(void*);
void handle_object_owner_permissive(void*);
void handle_object_lock(void*);
@@ -400,11 +356,8 @@ void handle_force_parcel_owner_to_me(void*);
void handle_force_parcel_to_content(void*);
void handle_claim_public_land(void*);
-void handle_god_request_havok(void *);
void handle_god_request_avatar_geometry(void *); // Hack for easy testing of new avatar geometry
-void reload_personal_settings_overrides(void *);
void reload_vertex_shader(void *);
-void slow_mo_animations(void *);
void handle_disconnect_viewer(void *);
void force_error_breakpoint(void *);
@@ -414,25 +367,13 @@ void force_error_infinite_loop(void *);
void force_error_software_exception(void *);
void force_error_driver_crash(void *);
-void handle_stopall(void*);
-//void handle_hinge(void*);
-//void handle_ptop(void*);
-//void handle_lptop(void*);
-//void handle_wheel(void*);
-//void handle_dehinge(void*);
-BOOL enable_dehinge(void*);
void handle_force_delete(void*);
void print_object_info(void*);
void print_agent_nvpairs(void*);
void toggle_debug_menus(void*);
-void export_info_callback(LLAssetInfo *info, void **user_data, S32 result);
-void export_data_callback(LLVFS *vfs, const LLUUID& uuid, LLAssetType::EType type, void **user_data, S32 result);
void upload_done_callback(const LLUUID& uuid, void* user_data, S32 result, LLExtStat ext_status);
-BOOL menu_check_build_tool( void* user_data );
-void handle_reload_settings(void*);
-void focus_here(void*);
void dump_select_mgr(void*);
-void dump_volume_mgr(void*);
+
void dump_inventory(void*);
void edit_ui(void*);
void toggle_visibility(void*);
@@ -442,52 +383,30 @@ BOOL get_visibility(void*);
void request_friendship(const LLUUID& agent_id);
// Tools menu
-void handle_force_unlock(void*);
void handle_selected_texture_info(void*);
-void handle_dump_image_list(void*);
-void handle_crash(void*);
void handle_dump_followcam(void*);
void handle_viewer_enable_message_log(void*);
void handle_viewer_disable_message_log(void*);
-void handle_send_postcard(void*);
-void handle_gestures_old(void*);
-void handle_focus(void *);
+
BOOL enable_buy_land(void*);
-void handle_move(void*);
-void handle_show_inventory(void*);
-void handle_activate(void*);
-BOOL enable_activate(void*);
// Help menu
-void handle_buy_currency(void*);
void handle_test_male(void *);
void handle_test_female(void *);
void handle_toggle_pg(void*);
void handle_dump_attachments(void *);
-void handle_show_overlay_title(void*);
void handle_dump_avatar_local_textures(void*);
void handle_debug_avatar_textures(void*);
void handle_grab_texture(void*);
BOOL enable_grab_texture(void*);
void handle_dump_region_object_cache(void*);
-BOOL menu_ui_enabled(void *user_data);
-BOOL menu_check_control( void* user_data);
-void menu_toggle_variable( void* user_data );
-BOOL menu_check_variable( void* user_data);
-BOOL enable_land_selected( void* );
-BOOL enable_more_than_one_selected(void* );
-BOOL enable_selection_you_own_all(void*);
-BOOL enable_selection_you_own_one(void*);
BOOL enable_save_into_inventory(void*);
BOOL enable_save_into_task_inventory(void*);
-BOOL enable_not_thirdperson(void*);
-// BOOL enable_export_selected(void *);
-BOOL enable_have_card(void*);
-BOOL enable_detach(void*);
-BOOL enable_region_owner(void*);
+
+BOOL enable_detach(const LLSD& = LLSD());
void menu_toggle_attached_lights(void* user_data);
void menu_toggle_attached_particles(void* user_data);
@@ -521,27 +440,6 @@ void LLMenuParcelObserver::changed()
}
-//-----------------------------------------------------------------------------
-// Menu Construction
-//-----------------------------------------------------------------------------
-
-// code required to calculate anything about the menus
-void pre_init_menus()
-{
- // static information
- LLColor4 color;
- color = gColors.getColor( "MenuDefaultBgColor" );
- LLMenuGL::setDefaultBackgroundColor( color );
- color = gColors.getColor( "MenuItemEnabledColor" );
- LLMenuItemGL::setEnabledColor( color );
- color = gColors.getColor( "MenuItemDisabledColor" );
- LLMenuItemGL::setDisabledColor( color );
- color = gColors.getColor( "MenuItemHighlightBgColor" );
- LLMenuItemGL::setHighlightBGColor( color );
- color = gColors.getColor( "MenuItemHighlightFgColor" );
- LLMenuItemGL::setHighlightFGColor( color );
-}
-
void initialize_menus();
//-----------------------------------------------------------------------------
@@ -560,13 +458,13 @@ void set_underclothes_menu_options()
{
if (gMenuHolder && gAgent.isTeen())
{
- gMenuHolder->getChild<LLView>("Self Underpants", TRUE)->setVisible(FALSE);
- gMenuHolder->getChild<LLView>("Self Undershirt", TRUE)->setVisible(FALSE);
+ gMenuHolder->getChild<LLView>("Self Underpants")->setVisible(FALSE);
+ gMenuHolder->getChild<LLView>("Self Undershirt")->setVisible(FALSE);
}
if (gMenuBarView && gAgent.isTeen())
{
- gMenuBarView->getChild<LLView>("Menu Underpants", TRUE)->setVisible(FALSE);
- gMenuBarView->getChild<LLView>("Menu Undershirt", TRUE)->setVisible(FALSE);
+ gMenuBarView->getChild<LLView>("Menu Underpants")->setVisible(FALSE);
+ gMenuBarView->getChild<LLView>("Menu Undershirt")->setVisible(FALSE);
}
}
@@ -593,62 +491,63 @@ void init_menus()
/// The popup menu is now populated by the show_context_menu()
/// method.
- gPopupMenuView = new LLMenuGL( "Popup" );
- gPopupMenuView->setVisible( FALSE );
+ LLMenuGL::Params menu_params;
+ menu_params.name = "Popup";
+ menu_params.visible = false;
+ gPopupMenuView = LLUICtrlFactory::create<LLMenuGL>(menu_params);
gMenuHolder->addChild( gPopupMenuView );
///
/// Pie menus
///
- gPieSelf = LLUICtrlFactory::getInstance()->buildPieMenu("menu_pie_self.xml", gMenuHolder);
+ gPieSelf = LLUICtrlFactory::getInstance()->createFromFile<LLContextMenu>("menu_pie_self.xml", gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance());
// TomY TODO: what shall we do about these?
- gDetachScreenPieMenu = gMenuHolder->getChild<LLPieMenu>("Object Detach HUD", true);
- gDetachPieMenu = gMenuHolder->getChild<LLPieMenu>("Object Detach", true);
+ gDetachScreenPieMenu = gMenuHolder->getChild<LLContextMenu>("Object Detach HUD", true);
+ gDetachPieMenu = gMenuHolder->getChild<LLContextMenu>("Object Detach", true);
- gPieAvatar = LLUICtrlFactory::getInstance()->buildPieMenu("menu_pie_avatar.xml", gMenuHolder);
+ gPieAvatar = LLUICtrlFactory::getInstance()->createFromFile<LLContextMenu>("menu_pie_avatar.xml", gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance());
- gPieObject = LLUICtrlFactory::getInstance()->buildPieMenu("menu_pie_object.xml", gMenuHolder);
+ gPieObject = LLUICtrlFactory::getInstance()->createFromFile<LLContextMenu>("menu_pie_object.xml", gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance());
- gAttachScreenPieMenu = gMenuHolder->getChild<LLPieMenu>("Object Attach HUD");
- gAttachPieMenu = gMenuHolder->getChild<LLPieMenu>("Object Attach");
- gPieRate = gMenuHolder->getChild<LLPieMenu>("Rate Menu");
+ gAttachScreenPieMenu = gMenuHolder->getChild<LLContextMenu>("Object Attach HUD");
+ gAttachPieMenu = gMenuHolder->getChild<LLContextMenu>("Object Attach");
+ gPieRate = gMenuHolder->getChild<LLContextMenu>("Rate Menu");
- gPieAttachment = LLUICtrlFactory::getInstance()->buildPieMenu("menu_pie_attachment.xml", gMenuHolder);
+ gPieAttachment = LLUICtrlFactory::getInstance()->createFromFile<LLContextMenu>("menu_pie_attachment.xml", gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance());
- gPieLand = LLUICtrlFactory::getInstance()->buildPieMenu("menu_pie_land.xml", gMenuHolder);
+ gPieLand = LLUICtrlFactory::getInstance()->createFromFile<LLContextMenu>("menu_pie_land.xml", gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance());
///
/// set up the colors
///
LLColor4 color;
- LLColor4 pie_color = gColors.getColor("PieMenuBgColor");
- gPieSelf->setBackgroundColor( pie_color );
- gPieAvatar->setBackgroundColor( pie_color );
- gPieObject->setBackgroundColor( pie_color );
- gPieAttachment->setBackgroundColor( pie_color );
- gPieLand->setBackgroundColor( pie_color );
+ LLColor4 context_menu_color = LLUIColorTable::instance().getColor("MenuPopupBgColor");
+
+ gPieSelf->setBackgroundColor( context_menu_color );
+ gPieAvatar->setBackgroundColor( context_menu_color );
+ gPieObject->setBackgroundColor( context_menu_color );
+ gPieAttachment->setBackgroundColor( context_menu_color );
+
+ gPieLand->setBackgroundColor( context_menu_color );
- color = gColors.getColor( "MenuPopupBgColor" );
+ color = LLUIColorTable::instance().getColor( "MenuPopupBgColor" );
gPopupMenuView->setBackgroundColor( color );
// If we are not in production, use a different color to make it apparent.
if (LLViewerLogin::getInstance()->isInProductionGrid())
{
- color = gColors.getColor( "MenuBarBgColor" );
+ color = LLUIColorTable::instance().getColor( "MenuBarBgColor" );
}
else
{
- color = gColors.getColor( "MenuNonProductionBgColor" );
+ color = LLUIColorTable::instance().getColor( "MenuNonProductionBgColor" );
}
- gMenuBarView = (LLMenuBarGL*)LLUICtrlFactory::getInstance()->buildMenu("menu_viewer.xml", gMenuHolder);
+ gMenuBarView = LLUICtrlFactory::getInstance()->createFromFile<LLMenuBarGL>("menu_viewer.xml", gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance());
gMenuBarView->setRect(LLRect(0, top, 0, top - MENU_BAR_HEIGHT));
gMenuBarView->setBackgroundColor( color );
- // gMenuBarView->setItemVisible("Tools", FALSE);
- gMenuBarView->arrange();
-
gMenuHolder->addChild(gMenuBarView);
// menu holder appears on top of menu bar so you can see the menu title
@@ -659,6 +558,7 @@ void init_menus()
LLViewerLogin::getInstance()->isInProductionGrid());
// Assume L$10 for now, the server will tell us the real cost at login
+ // *TODO:Also fix cost in llfolderview.cpp for Inventory menus
const std::string upload_cost("10");
gMenuHolder->childSetLabelArg("Upload Image", "[COST]", upload_cost);
gMenuHolder->childSetLabelArg("Upload Sound", "[COST]", upload_cost);
@@ -667,820 +567,1828 @@ void init_menus()
gAFKMenu = gMenuBarView->getChild<LLMenuItemCallGL>("Set Away", TRUE);
gBusyMenu = gMenuBarView->getChild<LLMenuItemCallGL>("Set Busy", TRUE);
- gAttachSubMenu = gMenuBarView->getChildMenuByName("Attach Object", TRUE);
- gDetachSubMenu = gMenuBarView->getChildMenuByName("Detach Object", TRUE);
-
- // TomY TODO convert these two
- LLMenuGL*menu;
-
- menu = new LLMenuGL(CLIENT_MENU_NAME);
- init_client_menu(menu);
- gMenuBarView->appendMenu( menu );
- menu->updateParent(LLMenuGL::sMenuContainer);
-
- menu = new LLMenuGL(SERVER_MENU_NAME);
- init_server_menu(menu);
- gMenuBarView->appendMenu( menu );
- menu->updateParent(LLMenuGL::sMenuContainer);
+ gAttachSubMenu = gMenuBarView->findChildMenuByName("Attach Object", TRUE);
+ gDetachSubMenu = gMenuBarView->findChildMenuByName("Detach Object", TRUE);
gMenuBarView->createJumpKeys();
// Let land based option enable when parcel changes
gMenuParcelObserver = new LLMenuParcelObserver();
- //
- // Debug menu visiblity
- //
- show_debug_menus();
-
- gLoginMenuBarView = (LLMenuBarGL*)LLUICtrlFactory::getInstance()->buildMenu("menu_login.xml", gMenuHolder);
+ gLoginMenuBarView = LLUICtrlFactory::getInstance()->createFromFile<LLMenuBarGL>("menu_login.xml", gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance());
+ gLoginMenuBarView->arrangeAndClear();
LLRect menuBarRect = gLoginMenuBarView->getRect();
gLoginMenuBarView->setRect(LLRect(menuBarRect.mLeft, menuBarRect.mTop, gViewerWindow->getRootView()->getRect().getWidth() - menuBarRect.mLeft, menuBarRect.mBottom));
-
gLoginMenuBarView->setBackgroundColor( color );
-
gMenuHolder->addChild(gLoginMenuBarView);
}
+///////////////////
+// SHOW CONSOLES //
+///////////////////
-void init_client_menu(LLMenuGL* menu)
+class LLAdvancedToggleConsole : public view_listener_t
{
- LLMenuGL* sub_menu = NULL;
-
- //menu->append(new LLMenuItemCallGL("Permissions Control", &show_permissions_control));
- // this is now in the view menu so we don't need it here!
-
+ bool handleEvent(const LLSD& userdata)
{
- // *TODO: Translate
- LLMenuGL* sub = new LLMenuGL("Consoles");
- menu->appendMenu(sub);
- sub->append(new LLMenuItemCheckGL("Frame Console",
- &toggle_visibility,
- NULL,
- &get_visibility,
- (void*)gDebugView->mFrameStatView,
- '2', MASK_CONTROL|MASK_SHIFT ) );
- sub->append(new LLMenuItemCheckGL("Texture Console",
- &toggle_visibility,
- NULL,
- &get_visibility,
- (void*)gTextureView,
- '3', MASK_CONTROL|MASK_SHIFT ) );
- LLView* debugview = gDebugView->mDebugConsolep;
- sub->append(new LLMenuItemCheckGL("Debug Console",
- &toggle_visibility,
- NULL,
- &get_visibility,
- debugview,
- '4', MASK_CONTROL|MASK_SHIFT ) );
-
- sub->append(new LLMenuItemCheckGL("Fast Timers",
- &toggle_visibility,
- NULL,
- &get_visibility,
- (void*)gDebugView->mFastTimerView,
- '9', MASK_CONTROL|MASK_SHIFT ) );
+ std::string console_type = userdata.asString();
+ if ("texture" == console_type)
+ {
+ toggle_visibility( (void*)gTextureView );
+ }
+ else if ("debug" == console_type)
+ {
+ toggle_visibility( (void*)((LLView*)gDebugView->mDebugConsolep) );
+ }
+ else if ("fast timers" == console_type)
+ {
+ toggle_visibility( (void*)gDebugView->mFastTimerView );
+ }
#if MEM_TRACK_MEM
- sub->append(new LLMenuItemCheckGL("Memory",
- &toggle_visibility,
- NULL,
- &get_visibility,
- (void*)gDebugView->mMemoryView,
- '0', MASK_CONTROL|MASK_SHIFT ) );
+ else if ("memory view" == console_type)
+ {
+ toggle_visibility( (void*)gDebugView->mMemoryView );
+ }
#endif
-
- sub->appendSeparator();
-
- // Debugging view for unified notifications
- sub->append(new LLMenuItemCallGL("Notifications Console...",
- &handle_show_notifications_console, NULL, NULL, '5', MASK_CONTROL|MASK_SHIFT ));
-
+ return true;
+ }
+};
+class LLAdvancedCheckConsole : public view_listener_t
+{
+ bool handleEvent(const LLSD& userdata)
+ {
+ std::string console_type = userdata.asString();
+ bool new_value = false;
+ if ("texture" == console_type)
+ {
+ new_value = get_visibility( (void*)gTextureView );
+ }
+ else if ("debug" == console_type)
+ {
+ new_value = get_visibility( (void*)((LLView*)gDebugView->mDebugConsolep) );
+ }
+ else if ("fast timers" == console_type)
+ {
+ new_value = get_visibility( (void*)gDebugView->mFastTimerView );
+ }
+#if MEM_TRACK_MEM
+ else if ("memory view" == console_type)
+ {
+ new_value = get_visibility( (void*)gDebugView->mMemoryView );
+ }
+#endif
+
+ return new_value;
+ }
+};
+
+
+//////////////////////////
+// DUMP INFO TO CONSOLE //
+//////////////////////////
+
+
+class LLAdvancedDumpInfoToConsole : public view_listener_t
+{
+ bool handleEvent(const LLSD& userdata)
+ {
+ std::string info_type = userdata.asString();
+ if ("region" == info_type)
+ {
+ handle_region_dump_settings(NULL);
+ }
+ else if ("group" == info_type)
+ {
+ handle_dump_group_info(NULL);
+ }
+ else if ("capabilities" == info_type)
+ {
+ handle_dump_capabilities_info(NULL);
+ }
+ return true;
+ }
+};
+
+
+//////////////
+// HUD INFO //
+//////////////
+
+
+class LLAdvancedToggleHUDInfo : public view_listener_t
+{
+ bool handleEvent(const LLSD& userdata)
+ {
+ std::string info_type = userdata.asString();
+
+ if ("camera" == info_type)
+ {
+ gDisplayCameraPos = !(gDisplayCameraPos);
+ }
+ else if ("wind" == info_type)
+ {
+ gDisplayWindInfo = !(gDisplayWindInfo);
+ }
+ else if ("fov" == info_type)
+ {
+ gDisplayFOV = !(gDisplayFOV);
+ }
+ return true;
+ }
+};
+
+class LLAdvancedCheckHUDInfo : public view_listener_t
+{
+ bool handleEvent(const LLSD& userdata)
+ {
+ std::string info_type = userdata.asString();
+ bool new_value = false;
+ if ("camera" == info_type)
+ {
+ new_value = gDisplayCameraPos;
+ }
+ else if ("wind" == info_type)
+ {
+ new_value = gDisplayWindInfo;
+ }
+ else if ("fov" == info_type)
+ {
+ new_value = gDisplayFOV;
+ }
+ return new_value;
+ }
+};
+
+///////////////////////
+// CLEAR GROUP CACHE //
+///////////////////////
+
+class LLAdvancedClearGroupCache : public view_listener_t
+{
+ bool handleEvent(const LLSD& userdata)
+ {
+ LLGroupMgr::debugClearAllGroups(NULL);
+ return true;
+ }
+};
+
+
+
+
+/////////////////
+// RENDER TYPE //
+/////////////////
+U32 render_type_from_string(std::string render_type)
+{
+ if ("simple" == render_type)
+ {
+ return LLPipeline::RENDER_TYPE_SIMPLE;
+ }
+ else if ("alpha" == render_type)
+ {
+ return LLPipeline::RENDER_TYPE_ALPHA;
+ }
+ else if ("tree" == render_type)
+ {
+ return LLPipeline::RENDER_TYPE_TREE;
+ }
+ else if ("character" == render_type)
+ {
+ return LLPipeline::RENDER_TYPE_AVATAR;
+ }
+ else if ("surfacePath" == render_type)
+ {
+ return LLPipeline::RENDER_TYPE_TERRAIN;
+ }
+ else if ("sky" == render_type)
+ {
+ return LLPipeline::RENDER_TYPE_SKY;
+ }
+ else if ("water" == render_type)
+ {
+ return LLPipeline::RENDER_TYPE_WATER;
+ }
+ else if ("ground" == render_type)
+ {
+ return LLPipeline::RENDER_TYPE_GROUND;
+ }
+ else if ("volume" == render_type)
+ {
+ return LLPipeline::RENDER_TYPE_VOLUME;
+ }
+ else if ("grass" == render_type)
+ {
+ return LLPipeline::RENDER_TYPE_GRASS;
+ }
+ else if ("clouds" == render_type)
+ {
+ return LLPipeline::RENDER_TYPE_CLOUDS;
+ }
+ else if ("particles" == render_type)
+ {
+ return LLPipeline::RENDER_TYPE_PARTICLES;
+ }
+ else if ("bump" == render_type)
+ {
+ return LLPipeline::RENDER_TYPE_BUMP;
+ }
+ else
+ {
+ return 0;
+ }
+}
+
+
+class LLAdvancedToggleRenderType : public view_listener_t
+{
+ bool handleEvent(const LLSD& userdata)
+ {
+ U32 render_type = render_type_from_string( userdata.asString() );
+ if ( render_type != 0 )
+ {
+ LLPipeline::toggleRenderTypeControl( (void*)render_type );
+ }
+ return true;
+ }
+};
+
+
+class LLAdvancedCheckRenderType : public view_listener_t
+{
+ bool handleEvent(const LLSD& userdata)
+ {
+ U32 render_type = render_type_from_string( userdata.asString() );
+ bool new_value = false;
+
+ if ( render_type != 0 )
+ {
+ new_value = LLPipeline::hasRenderTypeControl( (void*)render_type );
+ }
+
+ return new_value;
+ }
+};
+
+
+/////////////
+// FEATURE //
+/////////////
+U32 feature_from_string(std::string feature)
+{
+ if ("ui" == feature)
+ {
+ return LLPipeline::RENDER_DEBUG_FEATURE_UI;
+ }
+ else if ("selected" == feature)
+ {
+ return LLPipeline::RENDER_DEBUG_FEATURE_SELECTED;
+ }
+ else if ("highlighted" == feature)
+ {
+ return LLPipeline::RENDER_DEBUG_FEATURE_HIGHLIGHTED;
+ }
+ else if ("dynamic textures" == feature)
+ {
+ return LLPipeline::RENDER_DEBUG_FEATURE_DYNAMIC_TEXTURES;
+ }
+ else if ("foot shadows" == feature)
+ {
+ return LLPipeline::RENDER_DEBUG_FEATURE_FOOT_SHADOWS;
+ }
+ else if ("fog" == feature)
+ {
+ return LLPipeline::RENDER_DEBUG_FEATURE_FOG;
+ }
+ else if ("fr info" == feature)
+ {
+ return LLPipeline::RENDER_DEBUG_FEATURE_FR_INFO;
+ }
+ else if ("flexible" == feature)
+ {
+ return LLPipeline::RENDER_DEBUG_FEATURE_FLEXIBLE;
+ }
+ else
+ {
+ return 0;
+ }
+};
+
+
+class LLAdvancedToggleFeature : public view_listener_t{
+ bool handleEvent(const LLSD& userdata)
+ {
+ U32 feature = feature_from_string( userdata.asString() );
+ if ( feature != 0 )
+ {
+ LLPipeline::toggleRenderDebugFeature( (void*)feature );
+ }
+ return true;
+ }
+};
+
+class LLAdvancedCheckFeature : public view_listener_t
+{bool handleEvent(const LLSD& userdata)
+{
+ U32 feature = feature_from_string( userdata.asString() );
+ bool new_value = false;
+
+ if ( feature != 0 )
+ {
+ new_value = LLPipeline::toggleRenderDebugFeatureControl( (void*)feature );
+ }
+
+ return new_value;
+}
+};
+
+
+//////////////////
+// INFO DISPLAY //
+//////////////////
+U32 info_display_from_string(std::string info_display)
+{
+ if ("verify" == info_display)
+ {
+ return LLPipeline::RENDER_DEBUG_VERIFY;
+ }
+ else if ("bboxes" == info_display)
+ {
+ return LLPipeline::RENDER_DEBUG_BBOXES;
+ }
+ else if ("points" == info_display)
+ {
+ return LLPipeline::RENDER_DEBUG_POINTS;
+ }
+ else if ("octree" == info_display)
+ {
+ return LLPipeline::RENDER_DEBUG_OCTREE;
+ }
+ else if ("shadow frusta" == info_display)
+ {
+ return LLPipeline::RENDER_DEBUG_SHADOW_FRUSTA;
+ }
+ else if ("occlusion" == info_display)
+ {
+ return LLPipeline::RENDER_DEBUG_OCCLUSION;
+ }
+ else if ("render batches" == info_display)
+ {
+ return LLPipeline::RENDER_DEBUG_BATCH_SIZE;
+ }
+ else if ("texture anim" == info_display)
+ {
+ return LLPipeline::RENDER_DEBUG_TEXTURE_ANIM;
+ }
+ else if ("texture priority" == info_display)
+ {
+ return LLPipeline::RENDER_DEBUG_TEXTURE_PRIORITY;
+ }
+ else if ("shame" == info_display)
+ {
+ return LLPipeline::RENDER_DEBUG_SHAME;
+ }
+ else if ("texture area" == info_display)
+ {
+ return LLPipeline::RENDER_DEBUG_TEXTURE_AREA;
+ }
+ else if ("face area" == info_display)
+ {
+ return LLPipeline::RENDER_DEBUG_FACE_AREA;
+ }
+ else if ("lights" == info_display)
+ {
+ return LLPipeline::RENDER_DEBUG_LIGHTS;
+ }
+ else if ("particles" == info_display)
+ {
+ return LLPipeline::RENDER_DEBUG_PARTICLES;
+ }
+ else if ("composition" == info_display)
+ {
+ return LLPipeline::RENDER_DEBUG_COMPOSITION;
+ }
+ else if ("glow" == info_display)
+ {
+ return LLPipeline::RENDER_DEBUG_GLOW;
+ }
+ else if ("collision skeleton" == info_display)
+ {
+ return LLPipeline::RENDER_DEBUG_AVATAR_VOLUME;
+ }
+ else if ("agent target" == info_display)
+ {
+ return LLPipeline::RENDER_DEBUG_AGENT_TARGET;
+ }
+ else
+ {
+ return 0;
+ }
+};
+
+class LLAdvancedToggleInfoDisplay : public view_listener_t
+{
+ bool handleEvent(const LLSD& userdata)
+ {
+ U32 info_display = info_display_from_string( userdata.asString() );
+
+ if ( info_display != 0 )
+ {
+ LLPipeline::toggleRenderDebug( (void*)info_display );
+ }
+
+ return true;
+ }
+};
+
+
+class LLAdvancedCheckInfoDisplay : public view_listener_t
+{
+ bool handleEvent(const LLSD& userdata)
+ {
+ U32 info_display = info_display_from_string( userdata.asString() );
+ bool new_value = false;
+
+ if ( info_display != 0 )
+ {
+ new_value = LLPipeline::toggleRenderDebugControl( (void*)info_display );
+ }
+
+ return new_value;
+ }
+};
+
+
+///////////////////////////
+//// RANDOMIZE FRAMERATE //
+///////////////////////////
+
+
+class LLAdvancedToggleRandomizeFramerate : public view_listener_t
+{
+ bool handleEvent(const LLSD& userdata)
+ {
+ gRandomizeFramerate = !(gRandomizeFramerate);
+ return true;
+ }
+};
+
+class LLAdvancedCheckRandomizeFramerate : public view_listener_t
+{
+ bool handleEvent(const LLSD& userdata)
+ {
+ bool new_value = gRandomizeFramerate;
+ return new_value;
+ }
+};
+
+void run_vectorize_perf_test(void *)
+{
+ gSavedSettings.setBOOL("VectorizePerfTest", TRUE);
+}
+
+
+////////////////////////////////
+// RUN Vectorized Perform Test//
+////////////////////////////////
+
+
+class LLAdvancedVectorizePerfTest : public view_listener_t
+{
+ bool handleEvent(const LLSD& userdata)
+ {
+ run_vectorize_perf_test(NULL);
+ return true;
+ }
+};
+
+///////////////////////////
+//// PERIODIC SLOW FRAME //
+///////////////////////////
+
+
+class LLAdvancedTogglePeriodicSlowFrame : public view_listener_t
+{
+ bool handleEvent(const LLSD& userdata)
+ {
+ gPeriodicSlowFrame = !(gPeriodicSlowFrame);
+ return true;
+ }
+};
+
+class LLAdvancedCheckPeriodicSlowFrame : public view_listener_t
+{
+ bool handleEvent(const LLSD& userdata)
+ {
+ bool new_value = gPeriodicSlowFrame;
+ return new_value;
+ }
+};
+
+
+
+////////////////
+// FRAME TEST //
+////////////////
+
+
+class LLAdvancedToggleFrameTest : public view_listener_t
+{
+ bool handleEvent(const LLSD& userdata)
+ {
+ LLPipeline::sRenderFrameTest = !(LLPipeline::sRenderFrameTest);
+ return true;
+ }
+};
+
+class LLAdvancedCheckFrameTest : public view_listener_t
+{
+ bool handleEvent(const LLSD& userdata)
+ {
+ bool new_value = LLPipeline::sRenderFrameTest;
+ return new_value;
+ }
+};
+
+
+///////////////////////////
+// SELECTED TEXTURE INFO //
+///////////////////////////
+
+
+class LLAdvancedSelectedTextureInfo : public view_listener_t
+{
+ bool handleEvent(const LLSD& userdata)
+ {
+ handle_selected_texture_info(NULL);
+ return true;
+ }
+};
- sub->appendSeparator();
+//////////////////////
+// TOGGLE WIREFRAME //
+//////////////////////
- sub->append(new LLMenuItemCallGL("Region Info to Debug Console",
- &handle_region_dump_settings, NULL));
- sub->append(new LLMenuItemCallGL("Group Info to Debug Console",
- &handle_dump_group_info, NULL, NULL));
- sub->append(new LLMenuItemCallGL("Capabilities Info to Debug Console",
- &handle_dump_capabilities_info, NULL, NULL));
- sub->createJumpKeys();
+class LLAdvancedToggleWireframe : public view_listener_t
+{
+ bool handleEvent(const LLSD& userdata)
+ {
+ gUseWireframe = !(gUseWireframe);
+ return true;
+ }
+};
+
+class LLAdvancedCheckWireframe : public view_listener_t
+{
+ bool handleEvent(const LLSD& userdata)
+ {
+ bool new_value = gUseWireframe;
+ return new_value;
}
+};
- // neither of these works particularly well at the moment
- /*menu->append(new LLMenuItemCallGL( "Reload UI XML", &reload_ui,
- NULL, NULL) );*/
- /*menu->append(new LLMenuItemCallGL("Reload settings/colors",
- &handle_reload_settings, NULL, NULL));*/
- menu->append(new LLMenuItemCallGL("Reload personal setting overrides",
- &reload_personal_settings_overrides, NULL, NULL, KEY_F12, MASK_CONTROL|MASK_SHIFT));
-
- sub_menu = new LLMenuGL("HUD Info");
- {
- sub_menu->append(new LLMenuItemCheckGL("Velocity",
- &toggle_visibility,
- NULL,
- &get_visibility,
- (void*)gVelocityBar));
-
- sub_menu->append(new LLMenuItemToggleGL("Camera", &gDisplayCameraPos ) );
- sub_menu->append(new LLMenuItemToggleGL("Wind", &gDisplayWindInfo) );
- sub_menu->append(new LLMenuItemToggleGL("FOV", &gDisplayFOV ) );
- sub_menu->createJumpKeys();
- }
- menu->appendMenu(sub_menu);
-
- menu->appendSeparator();
-
- menu->append(new LLMenuItemCheckGL( "High-res Snapshot",
- &menu_toggle_control,
- NULL,
- &menu_check_control,
- (void*)"HighResSnapshot"));
+//////////////////////
+// DISABLE TEXTURES //
+//////////////////////
+
+class LLAdvancedToggleDisableTextures : public view_listener_t
+{
+ bool handleEvent(const LLSD& userdata)
+ {
+ LLViewerTexture::sDontLoadVolumeTextures = !LLViewerTexture::sDontLoadVolumeTextures;
+ return true;
+ }
+};
+
+class LLAdvancedCheckDisableTextures : public view_listener_t
+{
+ bool handleEvent(const LLSD& userdata)
+ {
+ bool new_value = LLViewerTexture::sDontLoadVolumeTextures; // <-- make this using LLCacheControl
+ return new_value;
+ }
+};
+
+//////////////////////////
+// DUMP SCRIPTED CAMERA //
+//////////////////////////
- menu->append(new LLMenuItemCheckGL( "Quiet Snapshots to Disk",
- &menu_toggle_control,
- NULL,
- &menu_check_control,
- (void*)"QuietSnapshotsToDisk"));
-
- menu->append(new LLMenuItemCheckGL("Show Mouselook Crosshairs",
- &menu_toggle_control,
- NULL,
- &menu_check_control,
- (void*)"ShowCrosshairs"));
-
- menu->append(new LLMenuItemCheckGL("Debug Permissions",
- &menu_toggle_control,
- NULL,
- &menu_check_control,
- (void*)"DebugPermissions"));
+class LLAdvancedDumpScriptedCamera : public view_listener_t
+{
+ bool handleEvent(const LLSD& userdata)
+ {
+ handle_dump_followcam(NULL);
+ return true;
+}
+};
+
+
+
+//////////////////////////////
+// DUMP REGION OBJECT CACHE //
+//////////////////////////////
+
+
+class LLAdvancedDumpRegionObjectCache : public view_listener_t
+{
+ bool handleEvent(const LLSD& userdata)
+{
+ handle_dump_region_object_cache(NULL);
+ return true;
+ }
+};
+
+class LLAdvancedWebBrowserTest : public view_listener_t
+{
+ bool handleEvent(const LLSD& userdata)
+ {
+ handle_web_browser_test(NULL);
+ return true;
+ }
+};
+class LLAdvancedBuyCurrencyTest : public view_listener_t
+ {
+ bool handleEvent(const LLSD& userdata)
+ {
+ handle_buy_currency_test(NULL);
+ return true;
+ }
+};
-#ifdef TOGGLE_HACKED_GODLIKE_VIEWER
- if (!LLViewerLogin::getInstance()->isInProductionGrid())
+////////////////////////
+// TOGGLE EDITABLE UI //
+////////////////////////
+
+
+class LLAdvancedToggleEditableUI : public view_listener_t
+{
+ bool handleEvent(const LLSD& userdata)
{
- menu->append(new LLMenuItemCheckGL("Hacked Godmode",
- &handle_toggle_hacked_godmode,
- NULL,
- &check_toggle_hacked_godmode,
- (void*)"HackedGodmode"));
+ edit_ui(NULL);
+ return true;
}
-#endif
+};
+
+
+/////////////////////
+// DUMP SELECT MGR //
+/////////////////////
- menu->append(new LLMenuItemCallGL("Clear Group Cache",
- LLGroupMgr::debugClearAllGroups));
- menu->appendSeparator();
- sub_menu = new LLMenuGL("Rendering");
- init_debug_rendering_menu(sub_menu);
- menu->appendMenu(sub_menu);
+class LLAdvancedDumpSelectMgr : public view_listener_t
+{
+ bool handleEvent(const LLSD& userdata)
+ {
+ dump_select_mgr(NULL);
+ return true;
+ }
+};
+
+
+
+////////////////////
+// DUMP INVENTORY //
+////////////////////
+
+
+class LLAdvancedDumpInventory : public view_listener_t
+{
+ bool handleEvent(const LLSD& userdata)
+ {
+ dump_inventory(NULL);
+ return true;
+ }
+};
+
+
+
+///////////////////////
+// DUMP FOCUS HOLDER //
+///////////////////////
+
+
+class LLAdvancedDumpFocusHolder : public view_listener_t
+{
+ bool handleEvent(const LLSD& userdata)
+ {
+ handle_dump_focus(NULL);
+ return true;
+ }
+};
+
+
+
+////////////////////////////////
+// PRINT SELECTED OBJECT INFO //
+////////////////////////////////
+
+
+class LLAdvancedPrintSelectedObjectInfo : public view_listener_t
+{
+ bool handleEvent(const LLSD& userdata)
+ {
+ print_object_info(NULL);
+ return true;
+ }
+};
+
+
+
+//////////////////////
+// PRINT AGENT INFO //
+//////////////////////
+
+
+class LLAdvancedPrintAgentInfo : public view_listener_t
+{
+ bool handleEvent(const LLSD& userdata)
+ {
+ print_agent_nvpairs(NULL);
+ return true;
+ }
+};
+
+
+
+////////////////////////////////
+// PRINT TEXTURE MEMORY STATS //
+////////////////////////////////
+
+
+class LLAdvancedPrintTextureMemoryStats : public view_listener_t
+{
+ bool handleEvent(const LLSD& userdata)
+ {
+ output_statistics(NULL);
+ return true;
+ }
+};
+
+//////////////////
+// DEBUG CLICKS //
+//////////////////
+
+
+class LLAdvancedToggleDebugClicks : public view_listener_t
+{
+ bool handleEvent(const LLSD& userdata)
+ {
+ gDebugClicks = !(gDebugClicks);
+ return true;
+ }
+};
+
+class LLAdvancedCheckDebugClicks : public view_listener_t
+{
+ bool handleEvent(const LLSD& userdata)
+ {
+ bool new_value = gDebugClicks;
+ return new_value;
+ }
+};
- sub_menu = new LLMenuGL("World");
- init_debug_world_menu(sub_menu);
- menu->appendMenu(sub_menu);
- sub_menu = new LLMenuGL("UI");
- init_debug_ui_menu(sub_menu);
- menu->appendMenu(sub_menu);
- sub_menu = new LLMenuGL("XUI");
- init_debug_xui_menu(sub_menu);
- menu->appendMenu(sub_menu);
+/////////////////
+// DEBUG VIEWS //
+/////////////////
- sub_menu = new LLMenuGL("Character");
- init_debug_avatar_menu(sub_menu);
- menu->appendMenu(sub_menu);
+class LLAdvancedToggleDebugViews : public view_listener_t
{
- LLMenuGL* sub = NULL;
- sub = new LLMenuGL("Network");
+ bool handleEvent(const LLSD& userdata)
+ {
+ LLView::sDebugRects = !(LLView::sDebugRects);
+ return true;
+ }
+};
- sub->append(new LLMenuItemCallGL("Enable Message Log",
- &handle_viewer_enable_message_log, NULL));
- sub->append(new LLMenuItemCallGL("Disable Message Log",
- &handle_viewer_disable_message_log, NULL));
+class LLAdvancedCheckDebugViews : public view_listener_t
+{
+ bool handleEvent(const LLSD& userdata)
+ {
+ bool new_value = LLView::sDebugRects;
+ return new_value;
+ }
+};
- sub->appendSeparator();
- sub->append(new LLMenuItemCheckGL("Velocity Interpolate Objects",
- &velocity_interpolate,
- NULL,
- &menu_check_control,
- (void*)"VelocityInterpolate"));
- sub->append(new LLMenuItemCheckGL("Ping Interpolate Object Positions",
- &menu_toggle_control,
- NULL,
- &menu_check_control,
- (void*)"PingInterpolate"));
- sub->appendSeparator();
+///////////////////////
+// XUI NAME TOOLTIPS //
+///////////////////////
- sub->append(new LLMenuItemCallGL("Drop a Packet",
- &drop_packet, NULL, NULL,
- 'L', MASK_ALT | MASK_CONTROL));
- menu->appendMenu( sub );
- sub->createJumpKeys();
+class LLAdvancedToggleXUINameTooltips : public view_listener_t
+{
+ bool handleEvent(const LLSD& userdata)
+ {
+ toggle_show_xui_names(NULL);
+ return true;
}
+};
+
+class LLAdvancedCheckXUINameTooltips : public view_listener_t
+{
+ bool handleEvent(const LLSD& userdata)
{
- LLMenuGL* sub = NULL;
- sub = new LLMenuGL("Recorder");
+ bool new_value = check_show_xui_names(NULL);
+ return new_value;
+ }
+};
- sub->append(new LLMenuItemCheckGL("Full Session Logging", &menu_toggle_control, NULL, &menu_check_control, (void*)"StatsSessionTrackFrameStats"));
- sub->append(new LLMenuItemCallGL("Start Logging", &LLFrameStats::startLogging, NULL));
- sub->append(new LLMenuItemCallGL("Stop Logging", &LLFrameStats::stopLogging, NULL));
- sub->append(new LLMenuItemCallGL("Log 10 Seconds", &LLFrameStats::timedLogging10, NULL));
- sub->append(new LLMenuItemCallGL("Log 30 Seconds", &LLFrameStats::timedLogging30, NULL));
- sub->append(new LLMenuItemCallGL("Log 60 Seconds", &LLFrameStats::timedLogging60, NULL));
- sub->appendSeparator();
- sub->append(new LLMenuItemCallGL("Start Playback", &LLAgentPilot::startPlayback, NULL));
- sub->append(new LLMenuItemCallGL("Stop Playback", &LLAgentPilot::stopPlayback, NULL));
- sub->append(new LLMenuItemToggleGL("Loop Playback", &LLAgentPilot::sLoop) );
- sub->append(new LLMenuItemCallGL("Start Record", &LLAgentPilot::startRecord, NULL));
- sub->append(new LLMenuItemCallGL("Stop Record", &LLAgentPilot::saveRecord, NULL));
- menu->appendMenu( sub );
- sub->createJumpKeys();
+////////////////////////
+// DEBUG MOUSE EVENTS //
+////////////////////////
+
+
+class LLAdvancedToggleDebugMouseEvents : public view_listener_t
+{
+ bool handleEvent(const LLSD& userdata)
+ {
+ LLView::sDebugMouseHandling = !(LLView::sDebugMouseHandling);
+ return true;
}
+};
+
+class LLAdvancedCheckDebugMouseEvents : public view_listener_t
+{
+ bool handleEvent(const LLSD& userdata)
+ {
+ bool new_value = LLView::sDebugMouseHandling;
+ return new_value;
+ }
+};
- menu->appendSeparator();
- menu->append(new LLMenuItemToggleGL("Show Updates",
- &gShowObjectUpdates));
+
+////////////////
+// DEBUG KEYS //
+////////////////
+
+
+class LLAdvancedToggleDebugKeys : public view_listener_t
+{
+ bool handleEvent(const LLSD& userdata)
+ {
+ LLView::sDebugKeys = !(LLView::sDebugKeys);
+ return true;
+ }
+};
- menu->appendSeparator();
+class LLAdvancedCheckDebugKeys : public view_listener_t
+{
+ bool handleEvent(const LLSD& userdata)
+ {
+ bool new_value = LLView::sDebugKeys;
+ return new_value;
+ }
+};
- menu->append(new LLMenuItemCallGL("Compress Images...",
- &handle_compress_image, NULL, NULL));
-
- menu->append(new LLMenuItemCheckGL("Limit Select Distance",
- &menu_toggle_control,
- NULL,
- &menu_check_control,
- (void*)"LimitSelectDistance"));
-
- menu->append(new LLMenuItemCheckGL("Disable Camera Constraints",
- &menu_toggle_control,
- NULL,
- &menu_check_control,
- (void*)"DisableCameraConstraints"));
-
- menu->append(new LLMenuItemCheckGL("Mouse Smoothing",
- &menu_toggle_control,
- NULL,
- &menu_check_control,
- (void*) "MouseSmooth"));
- menu->appendSeparator();
-
- menu->append(new LLMenuItemCheckGL( "Console Window",
- &menu_toggle_control,
- NULL,
- &menu_check_control,
- (void*)"ShowConsoleWindow"));
-
- if(gSavedSettings.getBOOL("QAMode"))
- {
- LLMenuGL* sub = NULL;
- sub = new LLMenuGL("Debugging");
-#if LL_WINDOWS
- sub->append(new LLMenuItemCallGL("Force Breakpoint", &force_error_breakpoint, NULL, NULL, 'B', MASK_CONTROL | MASK_ALT));
-#endif
- sub->append(new LLMenuItemCallGL("Force LLError And Crash", &force_error_llerror));
- sub->append(new LLMenuItemCallGL("Force Bad Memory Access", &force_error_bad_memory_access));
- sub->append(new LLMenuItemCallGL("Force Infinite Loop", &force_error_infinite_loop));
- sub->append(new LLMenuItemCallGL("Force Driver Crash", &force_error_driver_crash));
- sub->append(new LLMenuItemCallGL("Force Disconnect Viewer", &handle_disconnect_viewer));
- // *NOTE:Mani this isn't handled yet... sub->append(new LLMenuItemCallGL("Force Software Exception", &force_error_unhandled_exception));
- sub->createJumpKeys();
- menu->appendMenu(sub);
+
+
+///////////////////////
+// DEBUG WINDOW PROC //
+///////////////////////
+
+
+class LLAdvancedToggleDebugWindowProc : public view_listener_t
+{
+ bool handleEvent(const LLSD& userdata)
+ {
+ gDebugWindowProc = !(gDebugWindowProc);
+ return true;
}
+};
- menu->append(new LLMenuItemCheckGL( "Output Debug Minidump",
- &menu_toggle_control,
- NULL,
- &menu_check_control,
- (void*)"SaveMinidump"));
+class LLAdvancedCheckDebugWindowProc : public view_listener_t
+ {
+ bool handleEvent(const LLSD& userdata)
+ {
+ bool new_value = gDebugWindowProc;
+ return new_value;
+ }
+};
- menu->append(new LLMenuItemCallGL("Debug Settings...", LLFloaterSettingsDebug::show, NULL, NULL));
- menu->append(new LLMenuItemCheckGL("View Admin Options", &handle_admin_override_toggle, NULL, &check_admin_override, NULL, 'V', MASK_CONTROL | MASK_ALT));
+// ------------------------------XUI MENU ---------------------------
- menu->append(new LLMenuItemCallGL("Request Admin Status",
- &handle_god_mode, NULL, NULL, 'G', MASK_ALT | MASK_CONTROL));
+//////////////////////
+// LOAD UI FROM XML //
+//////////////////////
- menu->append(new LLMenuItemCallGL("Leave Admin Status",
- &handle_leave_god_mode, NULL, NULL, 'G', MASK_ALT | MASK_SHIFT | MASK_CONTROL));
- menu->createJumpKeys();
+class LLAdvancedLoadUIFromXML : public view_listener_t
+{
+ bool handleEvent(const LLSD& userdata)
+ {
+ handle_load_from_xml(NULL);
+ return true;
}
+};
+
+
+
+////////////////////
+// SAVE UI TO XML //
+////////////////////
+
-void init_debug_world_menu(LLMenuGL* menu)
+class LLAdvancedSaveUIToXML : public view_listener_t
{
-/* REMOVE mouse move sun from menu options
- menu->append(new LLMenuItemCheckGL("Mouse Moves Sun",
- &menu_toggle_control,
- NULL,
- &menu_check_control,
- (void*)"MouseSun",
- 'M', MASK_CONTROL|MASK_ALT));
-*/
- menu->append(new LLMenuItemCheckGL("Sim Sun Override",
- &menu_toggle_control,
- NULL,
- &menu_check_control,
- (void*)"SkyOverrideSimSunPosition"));
- menu->append(new LLMenuItemCallGL("Dump Scripted Camera",
- &handle_dump_followcam, NULL, NULL));
- menu->append(new LLMenuItemCheckGL("Fixed Weather",
- &menu_toggle_control,
- NULL,
- &menu_check_control,
- (void*)"FixedWeather"));
- menu->append(new LLMenuItemCallGL("Dump Region Object Cache",
- &handle_dump_region_object_cache, NULL, NULL));
- menu->createJumpKeys();
+ bool handleEvent(const LLSD& userdata)
+ {
+ handle_save_to_xml(NULL);
+ return true;
}
+};
-void handle_export_menus_to_xml(void*)
+class LLAdvancedSendTestIms : public view_listener_t
{
+ bool handleEvent(const LLSD& userdata)
+ {
+ LLIMModel::instance().testMessages();
+ return true;
+}
+};
- LLFilePicker& picker = LLFilePicker::instance();
- if(!picker.getSaveFile(LLFilePicker::FFSAVE_XML))
+class LLAdvancedAvatarInspector : public view_listener_t
+{
+ bool handleEvent(const LLSD& avatar_id)
{
- llwarns << "No file" << llendl;
- return;
+ LLFloaterReg::showInstance("inspect_avatar", avatar_id);
+ return true;
+ }
+};
+
+///////////////
+// XUI NAMES //
+///////////////
+
+
+class LLAdvancedToggleXUINames : public view_listener_t
+{
+ bool handleEvent(const LLSD& userdata)
+ {
+ toggle_show_xui_names(NULL);
+ return true;
+ }
+};
+
+class LLAdvancedCheckXUINames : public view_listener_t
+{
+ bool handleEvent(const LLSD& userdata)
+ {
+ bool new_value = check_show_xui_names(NULL);
+ return new_value;
}
- std::string filename = picker.getFirstFile();
+};
+
+
+////////////////////////
+// GRAB BAKED TEXTURE //
+////////////////////////
+
- llofstream out(filename);
- LLXMLNodePtr node = gMenuBarView->getXML();
- node->writeToOstream(out);
- out.close();
+class LLAdvancedGrabBakedTexture : public view_listener_t
+{
+ bool handleEvent(const LLSD& userdata)
+ {
+ std::string texture_type = userdata.asString();
+ if ("iris" == texture_type)
+ {
+ handle_grab_texture( (void*)TEX_EYES_BAKED );
+ }
+ else if ("head" == texture_type)
+ {
+ handle_grab_texture( (void*)TEX_HEAD_BAKED );
+ }
+ else if ("upper" == texture_type)
+ {
+ handle_grab_texture( (void*)TEX_UPPER_BAKED );
+ }
+ else if ("lower" == texture_type)
+ {
+ handle_grab_texture( (void*)TEX_SKIRT_BAKED );
+ }
+ else if ("skirt" == texture_type)
+ {
+ handle_grab_texture( (void*)TEX_SKIRT_BAKED );
+ }
+ else if ("hair" == texture_type)
+ {
+ handle_grab_texture( (void*)TEX_HAIR_BAKED );
}
-extern BOOL gDebugClicks;
-extern BOOL gDebugWindowProc;
-extern BOOL gDebugTextEditorTips;
-extern BOOL gDebugSelectMgr;
-
-void init_debug_ui_menu(LLMenuGL* menu)
-{
- menu->append(new LLMenuItemCheckGL("Rotate Mini-Map", menu_toggle_control, NULL, menu_check_control, (void*)"MiniMapRotate"));
- menu->append(new LLMenuItemCheckGL("Use default system color picker", menu_toggle_control, NULL, menu_check_control, (void*)"UseDefaultColorPicker"));
- menu->append(new LLMenuItemCheckGL("Show search panel in overlay bar", menu_toggle_control, NULL, menu_check_control, (void*)"ShowSearchBar"));
- menu->appendSeparator();
-
- menu->append(new LLMenuItemCallGL("Web Browser Test", &handle_web_browser_test));
- // commented out until work is complete: DEV-32268
- // menu->append(new LLMenuItemCallGL("Buy Currency Test", &handle_buy_currency_test));
- menu->append(new LLMenuItemCallGL("Editable UI", &edit_ui));
- menu->append(new LLMenuItemCallGL( "Dump SelectMgr", &dump_select_mgr));
- menu->append(new LLMenuItemCallGL( "Dump Inventory", &dump_inventory));
- menu->append(new LLMenuItemCallGL( "Dump Focus Holder", &handle_dump_focus, NULL, NULL, 'F', MASK_ALT | MASK_CONTROL));
- menu->append(new LLMenuItemCallGL( "Print Selected Object Info", &print_object_info, NULL, NULL, 'P', MASK_CONTROL|MASK_SHIFT ));
- menu->append(new LLMenuItemCallGL( "Print Agent Info", &print_agent_nvpairs, NULL, NULL, 'P', MASK_SHIFT ));
- menu->append(new LLMenuItemCallGL( "Memory Stats", &output_statistics, NULL, NULL, 'M', MASK_SHIFT | MASK_ALT | MASK_CONTROL));
- menu->append(new LLMenuItemCheckGL("Double-Click Auto-Pilot",
- menu_toggle_control, NULL, menu_check_control,
- (void*)"DoubleClickAutoPilot"));
- menu->appendSeparator();
-// menu->append(new LLMenuItemCallGL( "Print Packets Lost", &print_packets_lost, NULL, NULL, 'L', MASK_SHIFT ));
- menu->append(new LLMenuItemToggleGL("Debug SelectMgr", &gDebugSelectMgr));
- menu->append(new LLMenuItemToggleGL("Debug Clicks", &gDebugClicks));
- menu->append(new LLMenuItemToggleGL("Debug Views", &LLView::sDebugRects));
- menu->append(new LLMenuItemCheckGL("Show Name Tooltips", toggle_show_xui_names, NULL, check_show_xui_names, NULL));
- menu->append(new LLMenuItemToggleGL("Debug Mouse Events", &LLView::sDebugMouseHandling));
- menu->append(new LLMenuItemToggleGL("Debug Keys", &LLView::sDebugKeys));
- menu->append(new LLMenuItemToggleGL("Debug WindowProc", &gDebugWindowProc));
- menu->append(new LLMenuItemToggleGL("Debug Text Editor Tips", &gDebugTextEditorTips));
- menu->appendSeparator();
- menu->append(new LLMenuItemCheckGL("Show Time", menu_toggle_control, NULL, menu_check_control, (void*)"DebugShowTime"));
- menu->append(new LLMenuItemCheckGL("Show Render Info", menu_toggle_control, NULL, menu_check_control, (void*)"DebugShowRenderInfo"));
- menu->append(new LLMenuItemCheckGL("Show Matrices", menu_toggle_control, NULL, menu_check_control, (void*)"DebugShowRenderMatrices"));
- menu->append(new LLMenuItemCheckGL("Show Color Under Cursor", menu_toggle_control, NULL, menu_check_control, (void*)"DebugShowColor"));
+ return true;
+ }
+};
+
+class LLAdvancedEnableGrabBakedTexture : public view_listener_t
+{
+ bool handleEvent(const LLSD& userdata)
+{
+ std::string texture_type = userdata.asString();
+ bool new_value = false;
+
+ if ("iris" == texture_type)
+ {
+ new_value = enable_grab_texture( (void*)TEX_EYES_BAKED );
+ }
+ else if ("head" == texture_type)
+ {
+ new_value = enable_grab_texture( (void*)TEX_HEAD_BAKED );
+ }
+ else if ("upper" == texture_type)
+ {
+ new_value = enable_grab_texture( (void*)TEX_UPPER_BAKED );
+ }
+ else if ("lower" == texture_type)
+ {
+ new_value = enable_grab_texture( (void*)TEX_LOWER_BAKED );
+ }
+ else if ("skirt" == texture_type)
+ {
+ new_value = enable_grab_texture( (void*)TEX_SKIRT_BAKED );
+ }
- menu->createJumpKeys();
+ return new_value;
}
+};
+
+///////////////////////
+// APPEARANCE TO XML //
+///////////////////////
+
-void init_debug_xui_menu(LLMenuGL* menu)
+class LLAdvancedAppearanceToXML : public view_listener_t
{
- menu->append(new LLMenuItemCallGL("Floater Test...", LLFloaterTest::show));
- menu->append(new LLMenuItemCallGL("Font Test...", LLFloaterFontTest::show));
- menu->append(new LLMenuItemCallGL("Export Menus to XML...", handle_export_menus_to_xml));
- menu->append(new LLMenuItemCallGL("Edit UI...", LLFloaterEditUI::show));
- menu->append(new LLMenuItemCallGL("Load from XML...", handle_load_from_xml));
- menu->append(new LLMenuItemCallGL("Save to XML...", handle_save_to_xml));
- menu->append(new LLMenuItemCheckGL("Show XUI Names", toggle_show_xui_names, NULL, check_show_xui_names, NULL));
+ bool handleEvent(const LLSD& userdata)
+ {
+ LLVOAvatar::dumpArchetypeXML(NULL);
+ return true;
+ }
+};
+
+
+
+///////////////////////////////
+// TOGGLE CHARACTER GEOMETRY //
+///////////////////////////////
+
- //menu->append(new LLMenuItemCallGL("Buy Currency...", handle_buy_currency));
- menu->createJumpKeys();
+class LLAdvancedToggleCharacterGeometry : public view_listener_t
+{
+ bool handleEvent(const LLSD& userdata)
+ {
+ handle_god_request_avatar_geometry(NULL);
+ return true;
}
+};
-void init_debug_rendering_menu(LLMenuGL* menu)
+class LLEnableGodCustomerService : public view_listener_t
{
- LLMenuGL* sub_menu = NULL;
+ bool handleEvent(const LLSD& userdata)
+{
+ bool new_value = enable_god_customer_service(NULL);
+ return new_value;
+ }
+};
+
- ///////////////////////////
- //
- // Debug menu for types/pools
- //
- sub_menu = new LLMenuGL("Types");
- menu->appendMenu(sub_menu);
-
- sub_menu->append(new LLMenuItemCheckGL("Simple",
- &LLPipeline::toggleRenderTypeControl, NULL,
- &LLPipeline::hasRenderTypeControl,
- (void*)LLPipeline::RENDER_TYPE_SIMPLE, '1', MASK_ALT|MASK_SHIFT));
- sub_menu->append(new LLMenuItemCheckGL("Alpha",
- &LLPipeline::toggleRenderTypeControl, NULL,
- &LLPipeline::hasRenderTypeControl,
- (void*)LLPipeline::RENDER_TYPE_ALPHA, '2', MASK_ALT|MASK_SHIFT));
- sub_menu->append(new LLMenuItemCheckGL("Tree",
- &LLPipeline::toggleRenderTypeControl, NULL,
- &LLPipeline::hasRenderTypeControl,
- (void*)LLPipeline::RENDER_TYPE_TREE, '3', MASK_ALT|MASK_SHIFT));
- sub_menu->append(new LLMenuItemCheckGL("Character",
- &LLPipeline::toggleRenderTypeControl, NULL,
- &LLPipeline::hasRenderTypeControl,
- (void*)LLPipeline::RENDER_TYPE_AVATAR, '4', MASK_ALT|MASK_SHIFT));
- sub_menu->append(new LLMenuItemCheckGL("SurfacePatch",
- &LLPipeline::toggleRenderTypeControl, NULL,
- &LLPipeline::hasRenderTypeControl,
- (void*)LLPipeline::RENDER_TYPE_TERRAIN, '5', MASK_ALT|MASK_SHIFT));
- sub_menu->append(new LLMenuItemCheckGL("Sky",
- &LLPipeline::toggleRenderTypeControl, NULL,
- &LLPipeline::hasRenderTypeControl,
- (void*)LLPipeline::RENDER_TYPE_SKY, '6', MASK_ALT|MASK_SHIFT));
- sub_menu->append(new LLMenuItemCheckGL("Water",
- &LLPipeline::toggleRenderTypeControl, NULL,
- &LLPipeline::hasRenderTypeControl,
- (void*)LLPipeline::RENDER_TYPE_WATER, '7', MASK_ALT|MASK_SHIFT));
- sub_menu->append(new LLMenuItemCheckGL("Ground",
- &LLPipeline::toggleRenderTypeControl, NULL,
- &LLPipeline::hasRenderTypeControl,
- (void*)LLPipeline::RENDER_TYPE_GROUND, '8', MASK_ALT|MASK_SHIFT));
- sub_menu->append(new LLMenuItemCheckGL("Volume",
- &LLPipeline::toggleRenderTypeControl, NULL,
- &LLPipeline::hasRenderTypeControl,
- (void*)LLPipeline::RENDER_TYPE_VOLUME, '9', MASK_ALT|MASK_SHIFT));
- sub_menu->append(new LLMenuItemCheckGL("Grass",
- &LLPipeline::toggleRenderTypeControl, NULL,
- &LLPipeline::hasRenderTypeControl,
- (void*)LLPipeline::RENDER_TYPE_GRASS, '0', MASK_ALT|MASK_SHIFT));
- sub_menu->append(new LLMenuItemCheckGL("Clouds",
- &LLPipeline::toggleRenderTypeControl, NULL,
- &LLPipeline::hasRenderTypeControl,
- (void*)LLPipeline::RENDER_TYPE_CLOUDS, '-', MASK_ALT|MASK_SHIFT));
- sub_menu->append(new LLMenuItemCheckGL("Particles",
- &LLPipeline::toggleRenderTypeControl, NULL,
- &LLPipeline::hasRenderTypeControl,
- (void*)LLPipeline::RENDER_TYPE_PARTICLES, '`', MASK_ALT|MASK_SHIFT));
- sub_menu->append(new LLMenuItemCheckGL("Bump",
- &LLPipeline::toggleRenderTypeControl, NULL,
- &LLPipeline::hasRenderTypeControl,
- (void*)LLPipeline::RENDER_TYPE_BUMP, '\\', MASK_ALT|MASK_SHIFT));
-
- sub_menu->createJumpKeys();
- sub_menu = new LLMenuGL("Features");
- menu->appendMenu(sub_menu);
- sub_menu->append(new LLMenuItemCheckGL("UI",
- &LLPipeline::toggleRenderDebugFeature, NULL,
- &LLPipeline::toggleRenderDebugFeatureControl,
- (void*)LLPipeline::RENDER_DEBUG_FEATURE_UI, KEY_F1, MASK_CONTROL|MASK_SHIFT));
- sub_menu->append(new LLMenuItemCheckGL("Selected",
- &LLPipeline::toggleRenderDebugFeature, NULL,
- &LLPipeline::toggleRenderDebugFeatureControl,
- (void*)LLPipeline::RENDER_DEBUG_FEATURE_SELECTED, KEY_F2, MASK_CONTROL|MASK_SHIFT));
- sub_menu->append(new LLMenuItemCheckGL("Highlighted",
- &LLPipeline::toggleRenderDebugFeature, NULL,
- &LLPipeline::toggleRenderDebugFeatureControl,
- (void*)LLPipeline::RENDER_DEBUG_FEATURE_HIGHLIGHTED, KEY_F3, MASK_CONTROL|MASK_SHIFT));
- sub_menu->append(new LLMenuItemCheckGL("Dynamic Textures",
- &LLPipeline::toggleRenderDebugFeature, NULL,
- &LLPipeline::toggleRenderDebugFeatureControl,
- (void*)LLPipeline::RENDER_DEBUG_FEATURE_DYNAMIC_TEXTURES, KEY_F4, MASK_CONTROL|MASK_SHIFT));
- sub_menu->append(new LLMenuItemCheckGL( "Foot Shadows",
- &LLPipeline::toggleRenderDebugFeature, NULL,
- &LLPipeline::toggleRenderDebugFeatureControl,
- (void*)LLPipeline::RENDER_DEBUG_FEATURE_FOOT_SHADOWS, KEY_F5, MASK_CONTROL|MASK_SHIFT));
- sub_menu->append(new LLMenuItemCheckGL("Fog",
- &LLPipeline::toggleRenderDebugFeature, NULL,
- &LLPipeline::toggleRenderDebugFeatureControl,
- (void*)LLPipeline::RENDER_DEBUG_FEATURE_FOG, KEY_F6, MASK_CONTROL|MASK_SHIFT));
- sub_menu->append(new LLMenuItemCheckGL("Test FRInfo",
- &LLPipeline::toggleRenderDebugFeature, NULL,
- &LLPipeline::toggleRenderDebugFeatureControl,
- (void*)LLPipeline::RENDER_DEBUG_FEATURE_FR_INFO, KEY_F8, MASK_CONTROL|MASK_SHIFT));
- sub_menu->append(new LLMenuItemCheckGL( "Flexible Objects",
- &LLPipeline::toggleRenderDebugFeature, NULL,
- &LLPipeline::toggleRenderDebugFeatureControl,
- (void*)LLPipeline::RENDER_DEBUG_FEATURE_FLEXIBLE, KEY_F9, MASK_CONTROL|MASK_SHIFT));
- sub_menu->createJumpKeys();
/////////////////////////////
- //
- // Debug menu for info displays
- //
- sub_menu = new LLMenuGL("Info Displays");
- menu->appendMenu(sub_menu);
-
- sub_menu->append(new LLMenuItemCheckGL("Verify", &LLPipeline::toggleRenderDebug, NULL,
- &LLPipeline::toggleRenderDebugControl,
- (void*)LLPipeline::RENDER_DEBUG_VERIFY));
- sub_menu->append(new LLMenuItemCheckGL("BBoxes", &LLPipeline::toggleRenderDebug, NULL,
- &LLPipeline::toggleRenderDebugControl,
- (void*)LLPipeline::RENDER_DEBUG_BBOXES));
- sub_menu->append(new LLMenuItemCheckGL("Points", &LLPipeline::toggleRenderDebug, NULL,
- &LLPipeline::toggleRenderDebugControl,
- (void*)LLPipeline::RENDER_DEBUG_POINTS));
- sub_menu->append(new LLMenuItemCheckGL("Octree", &LLPipeline::toggleRenderDebug, NULL,
- &LLPipeline::toggleRenderDebugControl,
- (void*)LLPipeline::RENDER_DEBUG_OCTREE));
- sub_menu->append(new LLMenuItemCheckGL("Shadow Frusta", &LLPipeline::toggleRenderDebug, NULL,
- &LLPipeline::toggleRenderDebugControl,
- (void*)LLPipeline::RENDER_DEBUG_SHADOW_FRUSTA));
- sub_menu->append(new LLMenuItemCheckGL("Occlusion", &LLPipeline::toggleRenderDebug, NULL,
- &LLPipeline::toggleRenderDebugControl,
- (void*)LLPipeline::RENDER_DEBUG_OCCLUSION));
- sub_menu->append(new LLMenuItemCheckGL("Render Batches", &LLPipeline::toggleRenderDebug, NULL,
- &LLPipeline::toggleRenderDebugControl,
- (void*)LLPipeline::RENDER_DEBUG_BATCH_SIZE));
- sub_menu->append(new LLMenuItemCheckGL("Animated Textures", &LLPipeline::toggleRenderDebug, NULL,
- &LLPipeline::toggleRenderDebugControl,
- (void*)LLPipeline::RENDER_DEBUG_TEXTURE_ANIM));
- sub_menu->append(new LLMenuItemCheckGL("Texture Priority", &LLPipeline::toggleRenderDebug, NULL,
- &LLPipeline::toggleRenderDebugControl,
- (void*)LLPipeline::RENDER_DEBUG_TEXTURE_PRIORITY));
- sub_menu->append(new LLMenuItemCheckGL("Avatar Rendering Cost", &LLPipeline::toggleRenderDebug, NULL,
- &LLPipeline::toggleRenderDebugControl,
- (void*)LLPipeline::RENDER_DEBUG_SHAME));
- sub_menu->append(new LLMenuItemCheckGL("Texture Area (sqrt(A))",&LLPipeline::toggleRenderDebug, NULL,
- &LLPipeline::toggleRenderDebugControl,
- (void*)LLPipeline::RENDER_DEBUG_TEXTURE_AREA));
- sub_menu->append(new LLMenuItemCheckGL("Face Area (sqrt(A))",&LLPipeline::toggleRenderDebug, NULL,
- &LLPipeline::toggleRenderDebugControl,
- (void*)LLPipeline::RENDER_DEBUG_FACE_AREA));
- sub_menu->append(new LLMenuItemCheckGL("Lights", &LLPipeline::toggleRenderDebug, NULL,
- &LLPipeline::toggleRenderDebugControl,
- (void*)LLPipeline::RENDER_DEBUG_LIGHTS));
- sub_menu->append(new LLMenuItemCheckGL("Particles", &LLPipeline::toggleRenderDebug, NULL,
- &LLPipeline::toggleRenderDebugControl,
- (void*)LLPipeline::RENDER_DEBUG_PARTICLES));
- sub_menu->append(new LLMenuItemCheckGL("Composition", &LLPipeline::toggleRenderDebug, NULL,
- &LLPipeline::toggleRenderDebugControl,
- (void*)LLPipeline::RENDER_DEBUG_COMPOSITION));
- sub_menu->append(new LLMenuItemCheckGL("Glow",&LLPipeline::toggleRenderDebug, NULL,
- &LLPipeline::toggleRenderDebugControl,
- (void*)LLPipeline::RENDER_DEBUG_GLOW));
- sub_menu->append(new LLMenuItemCheckGL("Raycasting", &LLPipeline::toggleRenderDebug, NULL,
- &LLPipeline::toggleRenderDebugControl,
- (void*)LLPipeline::RENDER_DEBUG_RAYCAST));
- sub_menu->append(new LLMenuItemCheckGL("Sculpt", &LLPipeline::toggleRenderDebug, NULL,
- &LLPipeline::toggleRenderDebugControl,
- (void*)LLPipeline::RENDER_DEBUG_SCULPTED));
+// TEST MALE / TEST FEMALE //
+/////////////////////////////
+
+class LLAdvancedTestMale : public view_listener_t
+{
+ bool handleEvent(const LLSD& userdata)
+ {
+ handle_test_male(NULL);
+ return true;
+ }
+};
+
+
+class LLAdvancedTestFemale : public view_listener_t
+{
+ bool handleEvent(const LLSD& userdata)
+ {
+ handle_test_female(NULL);
+ return true;
+ }
+};
+
+
+
+///////////////
+// TOGGLE PG //
+///////////////
+
+
+class LLAdvancedTogglePG : public view_listener_t
+{
+ bool handleEvent(const LLSD& userdata)
+ {
+ handle_toggle_pg(NULL);
+ return true;
+ }
+};
+
+
+
+////////////////////////////
+// ALLOW TAP-TAP-HOLD RUN //
+////////////////////////////
+
+
+class LLAdvancedToggleAllowTapTapHoldRun : public view_listener_t
+{
+ bool handleEvent(const LLSD& userdata)
+ {
+ gAllowTapTapHoldRun = !(gAllowTapTapHoldRun);
+ return true;
+ }
+};
+
+class LLAdvancedCheckAllowTapTapHoldRun : public view_listener_t
+{
+ bool handleEvent(const LLSD& userdata)
+ {
+ bool new_value = gAllowTapTapHoldRun;
+ return new_value;
+ }
+};
+
+
+
+
+
+class LLAdvancedForceParamsToDefault : public view_listener_t
+{
+ bool handleEvent(const LLSD& userdata)
+ {
+ LLAgent::clearVisualParams(NULL);
+ return true;
+ }
+};
+
+
+
+//////////////////////////
+// RELOAD VERTEX SHADER //
+//////////////////////////
+
+
+class LLAdvancedReloadVertexShader : public view_listener_t
+{
+ bool handleEvent(const LLSD& userdata)
+ {
+ reload_vertex_shader(NULL);
+ return true;
+ }
+};
+
+
+
+////////////////////
+// ANIMATION INFO //
+////////////////////
+
+
+class LLAdvancedToggleAnimationInfo : public view_listener_t
+{
+ bool handleEvent(const LLSD& userdata)
+ {
+ LLVOAvatar::sShowAnimationDebug = !(LLVOAvatar::sShowAnimationDebug);
+ return true;
+ }
+};
+
+class LLAdvancedCheckAnimationInfo : public view_listener_t
+{
+ bool handleEvent(const LLSD& userdata)
+ {
+ bool new_value = LLVOAvatar::sShowAnimationDebug;
+ return new_value;
+ }
+};
+
+
+//////////////////
+// SHOW LOOK AT //
+//////////////////
+
+
+class LLAdvancedToggleShowLookAt : public view_listener_t
+{
+ bool handleEvent(const LLSD& userdata)
+ {
+ LLHUDEffectLookAt::sDebugLookAt = !(LLHUDEffectLookAt::sDebugLookAt);
+ return true;
+ }
+};
+
+class LLAdvancedCheckShowLookAt : public view_listener_t
+{
+ bool handleEvent(const LLSD& userdata)
+ {
+ bool new_value = LLHUDEffectLookAt::sDebugLookAt;
+ return new_value;
+ }
+};
+
+
+
+///////////////////
+// SHOW POINT AT //
+///////////////////
+
+
+class LLAdvancedToggleShowPointAt : public view_listener_t
+{
+ bool handleEvent(const LLSD& userdata)
+ {
+ LLHUDEffectPointAt::sDebugPointAt = !(LLHUDEffectPointAt::sDebugPointAt);
+ return true;
+ }
+};
+
+class LLAdvancedCheckShowPointAt : public view_listener_t
+{
+ bool handleEvent(const LLSD& userdata)
+ {
+ bool new_value = LLHUDEffectPointAt::sDebugPointAt;
+ return new_value;
+ }
+};
+
+
+
+/////////////////////////
+// DEBUG JOINT UPDATES //
+/////////////////////////
+
+
+class LLAdvancedToggleDebugJointUpdates : public view_listener_t
+{
+ bool handleEvent(const LLSD& userdata)
+ {
+ LLVOAvatar::sJointDebug = !(LLVOAvatar::sJointDebug);
+ return true;
+ }
+};
+
+class LLAdvancedCheckDebugJointUpdates : public view_listener_t
+{
+ bool handleEvent(const LLSD& userdata)
+ {
+ bool new_value = LLVOAvatar::sJointDebug;
+ return new_value;
+ }
+};
+
+
+
+/////////////////
+// DISABLE LOD //
+/////////////////
+
+
+class LLAdvancedToggleDisableLOD : public view_listener_t
+{
+ bool handleEvent(const LLSD& userdata)
+ {
+ LLViewerJoint::sDisableLOD = !(LLViewerJoint::sDisableLOD);
+ return true;
+ }
+};
- sub_menu->append(new LLMenuItemCallGL("Vectorize Perf Test", &run_vectorize_perf_test));
+class LLAdvancedCheckDisableLOD : public view_listener_t
+{
+ bool handleEvent(const LLSD& userdata)
+ {
+ bool new_value = LLViewerJoint::sDisableLOD;
+ return new_value;
+ }
+};
- sub_menu = new LLMenuGL("Render Tests");
- sub_menu->append(new LLMenuItemCheckGL("Camera Offset",
- &menu_toggle_control,
- NULL,
- &menu_check_control,
- (void*)"CameraOffset"));
- sub_menu->append(new LLMenuItemToggleGL("Randomize Framerate", &gRandomizeFramerate));
+/////////////////////////
+// DEBUG CHARACTER VIS //
+/////////////////////////
- sub_menu->append(new LLMenuItemToggleGL("Periodic Slow Frame", &gPeriodicSlowFrame));
- sub_menu->append(new LLMenuItemToggleGL("Frame Test", &LLPipeline::sRenderFrameTest));
+class LLAdvancedToggleDebugCharacterVis : public view_listener_t
+{
+ bool handleEvent(const LLSD& userdata)
+ {
+ LLVOAvatar::sDebugInvisible = !(LLVOAvatar::sDebugInvisible);
+ return true;
+ }
+};
- sub_menu->createJumpKeys();
+class LLAdvancedCheckDebugCharacterVis : public view_listener_t
+{
+ bool handleEvent(const LLSD& userdata)
+ {
+ bool new_value = LLVOAvatar::sDebugInvisible;
+ return new_value;
+ }
+};
- menu->appendMenu( sub_menu );
- menu->appendSeparator();
- menu->append(new LLMenuItemCheckGL("Axes", menu_toggle_control, NULL, menu_check_control, (void*)"ShowAxes"));
-// menu->append(new LLMenuItemCheckGL("Cull Small Objects", toggle_cull_small, NULL, menu_check_control, (void*)"RenderCullBySize"));
+//////////////////////
+// DUMP ATTACHMENTS //
+//////////////////////
- menu->appendSeparator();
- menu->append(new LLMenuItemToggleGL("Hide Selected", &gHideSelectedObjects));
- menu->appendSeparator();
- menu->append(new LLMenuItemCheckGL("Tangent Basis", menu_toggle_control, NULL, menu_check_control, (void*)"ShowTangentBasis"));
- menu->append(new LLMenuItemCallGL("Selected Texture Info", handle_selected_texture_info, NULL, NULL, 'T', MASK_CONTROL|MASK_SHIFT|MASK_ALT));
- //menu->append(new LLMenuItemCallGL("Dump Image List", handle_dump_image_list, NULL, NULL, 'I', MASK_CONTROL|MASK_SHIFT));
- menu->append(new LLMenuItemToggleGL("Wireframe", &gUseWireframe,
- 'R', MASK_CONTROL|MASK_SHIFT));
+class LLAdvancedDumpAttachments : public view_listener_t
+{
+ bool handleEvent(const LLSD& userdata)
+ {
+ handle_dump_attachments(NULL);
+ return true;
+ }
+};
- LLMenuItemCheckGL* item;
- item = new LLMenuItemCheckGL("Object-Object Occlusion", menu_toggle_control, NULL, menu_check_control, (void*)"UseOcclusion", 'O', MASK_CONTROL|MASK_SHIFT);
- item->setEnabled(gGLManager.mHasOcclusionQuery && LLFeatureManager::getInstance()->isFeatureAvailable("UseOcclusion"));
- menu->append(item);
- item = new LLMenuItemCheckGL("Debug GL", menu_toggle_control, NULL, menu_check_control, (void*)"RenderDebugGL");
- menu->append(item);
- item = new LLMenuItemCheckGL("Debug Pipeline", menu_toggle_control, NULL, menu_check_control, (void*)"RenderDebugPipeline");
- menu->append(item);
+/////////////////////
+// REBAKE TEXTURES //
+/////////////////////
- item = new LLMenuItemCheckGL("Fast Alpha", menu_toggle_control, NULL, menu_check_control, (void*)"RenderFastAlpha");
- menu->append(item);
- item = new LLMenuItemCheckGL("Animate Textures", menu_toggle_control, NULL, menu_check_control, (void*)"AnimateTextures");
- menu->append(item);
+class LLAdvancedRebakeTextures : public view_listener_t
+{
+ bool handleEvent(const LLSD& userdata)
+ {
+ handle_rebake_textures(NULL);
+ return true;
+ }
+};
- item = new LLMenuItemCheckGL("Disable Textures", menu_toggle_variable, NULL, menu_check_variable, (void*)&LLViewerImage::sDontLoadVolumeTextures);
- menu->append(item);
#ifndef LL_RELEASE_FOR_DOWNLOAD
- item = new LLMenuItemCheckGL("HTTP Get Textures", menu_toggle_control, NULL, menu_check_control, (void*)"ImagePipelineUseHTTP");
- menu->append(item);
+///////////////////////////
+// DEBUG AVATAR TEXTURES //
+///////////////////////////
+
+
+class LLAdvancedDebugAvatarTextures : public view_listener_t
+{
+ bool handleEvent(const LLSD& userdata)
+ {
+ handle_debug_avatar_textures(NULL);
+ return true;
+ }
+};
+
+////////////////////////////////
+// DUMP AVATAR LOCAL TEXTURES //
+////////////////////////////////
+
+
+class LLAdvancedDumpAvatarLocalTextures : public view_listener_t
+{
+ bool handleEvent(const LLSD& userdata)
+ {
+ handle_dump_avatar_local_textures(NULL);
+ return true;
+ }
+};
+
#endif
- item = new LLMenuItemCheckGL("Run Multiple Threads", menu_toggle_control, NULL, menu_check_control, (void*)"RunMultipleThreads");
- menu->append(item);
+/////////////////
+// MESSAGE LOG //
+/////////////////
+
+
+class LLAdvancedEnableMessageLog : public view_listener_t
+{
+ bool handleEvent(const LLSD& userdata)
+ {
+ handle_viewer_enable_message_log(NULL);
+ return true;
+ }
+};
- item = new LLMenuItemCheckGL("Cheesy Beacon", menu_toggle_control, NULL, menu_check_control, (void*)"CheesyBeacon");
- menu->append(item);
+class LLAdvancedDisableMessageLog : public view_listener_t
+{
+ bool handleEvent(const LLSD& userdata)
+ {
+ handle_viewer_disable_message_log(NULL);
+ return true;
+ }
+};
- item = new LLMenuItemCheckGL("Attached Lights", menu_toggle_attached_lights, NULL, menu_check_control, (void*)"RenderAttachedLights");
- menu->append(item);
+/////////////////
+// DROP PACKET //
+/////////////////
- item = new LLMenuItemCheckGL("Attached Particles", menu_toggle_attached_particles, NULL, menu_check_control, (void*)"RenderAttachedParticles");
- menu->append(item);
-#ifndef LL_RELEASE_FOR_DOWNLOAD
- menu->appendSeparator();
- menu->append(new LLMenuItemCallGL("Memory Leaking Simulation", LLFloaterMemLeak::show, NULL, NULL));
-#else
- if(gSavedSettings.getBOOL("QAMode"))
+class LLAdvancedDropPacket : public view_listener_t
+{
+ bool handleEvent(const LLSD& userdata)
{
- menu->appendSeparator();
- menu->append(new LLMenuItemCallGL("Memory Leaking Simulation", LLFloaterMemLeak::show, NULL, NULL));
+ gMessageSystem->mPacketRing.dropPackets(1);
+ return true;
}
-#endif
+};
+
+
+
+/////////////////
+// AGENT PILOT //
+/////////////////
+
+
+class LLAdvancedAgentPilot : public view_listener_t
+{
+ bool handleEvent(const LLSD& userdata)
+ {
+ std::string command = userdata.asString();
+ if ("start playback" == command)
+ {
+ LLAgentPilot::startPlayback(NULL);
+ }
+ else if ("stop playback" == command)
+ {
+ LLAgentPilot::stopPlayback(NULL);
+ }
+ else if ("start record" == command)
+ {
+ LLAgentPilot::startRecord(NULL);
+ }
+ else if ("stop record" == command)
+ {
+ LLAgentPilot::saveRecord(NULL);
+ }
+
+ return true;
+ }
+};
+
+
+
+//////////////////////
+// AGENT PILOT LOOP //
+//////////////////////
+
+
+class LLAdvancedToggleAgentPilotLoop : public view_listener_t
+{
+ bool handleEvent(const LLSD& userdata)
+ {
+ LLAgentPilot::sLoop = !(LLAgentPilot::sLoop);
+ return true;
+ }
+};
+
+class LLAdvancedCheckAgentPilotLoop : public view_listener_t
+{
+ bool handleEvent(const LLSD& userdata)
+ {
+ bool new_value = LLAgentPilot::sLoop;
+ return new_value;
+ }
+};
+
+
+/////////////////////////
+// SHOW OBJECT UPDATES //
+/////////////////////////
+
+
+class LLAdvancedToggleShowObjectUpdates : public view_listener_t
+{
+ bool handleEvent(const LLSD& userdata)
+ {
+ gShowObjectUpdates = !(gShowObjectUpdates);
+ return true;
+ }
+};
+
+class LLAdvancedCheckShowObjectUpdates : public view_listener_t
+{
+ bool handleEvent(const LLSD& userdata)
+ {
+ bool new_value = gShowObjectUpdates;
+ return new_value;
+ }
+};
+
+
+
+////////////////////
+// COMPRESS IMAGE //
+////////////////////
+
+
+class LLAdvancedCompressImage : public view_listener_t
+{
+ bool handleEvent(const LLSD& userdata)
+ {
+ handle_compress_image(NULL);
+ return true;
+ }
+};
+
+
+
+/////////////////////////
+// SHOW DEBUG SETTINGS //
+/////////////////////////
+
+
+class LLAdvancedShowDebugSettings : public view_listener_t
+{
+ bool handleEvent(const LLSD& userdata)
+ {
+ LLFloaterReg::showInstance("settings_debug",userdata);
+ return true;
+ }
+};
+
+
+
+////////////////////////
+// VIEW ADMIN OPTIONS //
+////////////////////////
+
+
+class LLAdvancedToggleViewAdminOptions : public view_listener_t
+{
+ bool handleEvent(const LLSD& userdata)
+ {
+ handle_admin_override_toggle(NULL);
+ return true;
+ }
+};
+
+class LLAdvancedCheckViewAdminOptions : public view_listener_t
+{
+ bool handleEvent(const LLSD& userdata)
+ {
+ bool new_value = check_admin_override(NULL);
+ return new_value;
+ }
+};
+
+/////////////////////////////////////
+// Enable Object Object Occlusion ///
+/////////////////////////////////////
+class LLAdvancedEnableObjectObjectOcclusion: public view_listener_t
+{
+ bool handleEvent(const LLSD& userdata)
+ {
- menu->createJumpKeys();
-}
-
-void init_debug_avatar_menu(LLMenuGL* menu)
-{
- LLMenuGL* sub_menu = new LLMenuGL("Grab Baked Texture");
- init_debug_baked_texture_menu(sub_menu);
- menu->appendMenu(sub_menu);
-
- sub_menu = new LLMenuGL("Character Tests");
- sub_menu->append(new LLMenuItemCheckGL("Go Away/AFK When Idle",
- menu_toggle_control,
- NULL,
- menu_check_control,
- (void*)"AllowIdleAFK"));
-
- sub_menu->append(new LLMenuItemCallGL("Appearance To XML",
- &LLVOAvatar::dumpArchetypeXML));
-
- // HACK for easy testing of avatar geometry
- sub_menu->append(new LLMenuItemCallGL( "Toggle Character Geometry",
- &handle_god_request_avatar_geometry, &enable_god_customer_service, NULL));
-
- sub_menu->append(new LLMenuItemCallGL("Test Male",
- handle_test_male));
-
- sub_menu->append(new LLMenuItemCallGL("Test Female",
- handle_test_female));
-
- sub_menu->append(new LLMenuItemCallGL("Toggle PG", handle_toggle_pg));
-
- sub_menu->append(new LLMenuItemToggleGL("Allow Select Avatar", &gAllowSelectAvatar));
- sub_menu->createJumpKeys();
-
- menu->appendMenu(sub_menu);
-
- menu->append(new LLMenuItemCheckGL("Enable Lip Sync (Beta)", menu_toggle_control, NULL, menu_check_control, (void*)"LipSyncEnabled"));
- menu->append(new LLMenuItemToggleGL("Tap-Tap-Hold To Run", &gAllowTapTapHoldRun));
- menu->append(new LLMenuItemCallGL("Force Params to Default", &LLAgent::clearVisualParams, NULL));
- menu->append(new LLMenuItemCallGL("Reload Vertex Shader", &reload_vertex_shader, NULL));
- menu->append(new LLMenuItemToggleGL("Animation Info", &LLVOAvatar::sShowAnimationDebug));
- menu->append(new LLMenuItemCallGL("Slow Motion Animations", &slow_mo_animations, NULL));
- menu->append(new LLMenuItemToggleGL("Show Look At", &LLHUDEffectLookAt::sDebugLookAt));
- menu->append(new LLMenuItemToggleGL("Show Point At", &LLHUDEffectPointAt::sDebugPointAt));
- menu->append(new LLMenuItemToggleGL("Debug Joint Updates", &LLVOAvatar::sJointDebug));
- menu->append(new LLMenuItemToggleGL("Disable LOD", &LLViewerJoint::sDisableLOD));
- menu->append(new LLMenuItemToggleGL("Debug Character Vis", &LLVOAvatar::sDebugInvisible));
- //menu->append(new LLMenuItemToggleGL("Show Attachment Points", &LLVOAvatar::sShowAttachmentPoints));
- //diabling collision plane due to DEV-14477 -brad
- //menu->append(new LLMenuItemToggleGL("Show Collision Plane", &LLVOAvatar::sShowFootPlane));
- menu->append(new LLMenuItemCheckGL("Show Collision Skeleton",
- &LLPipeline::toggleRenderDebug, NULL,
- &LLPipeline::toggleRenderDebugControl,
- (void*)LLPipeline::RENDER_DEBUG_AVATAR_VOLUME));
- menu->append(new LLMenuItemCheckGL("Display Agent Target",
- &LLPipeline::toggleRenderDebug, NULL,
- &LLPipeline::toggleRenderDebugControl,
- (void*)LLPipeline::RENDER_DEBUG_AGENT_TARGET));
- menu->append(new LLMenuItemToggleGL( "Debug Rotation", &LLVOAvatar::sDebugAvatarRotation));
- menu->append(new LLMenuItemCallGL("Dump Attachments", handle_dump_attachments));
- menu->append(new LLMenuItemCallGL("Rebake Textures", handle_rebake_textures, NULL, NULL, 'R', MASK_ALT | MASK_CONTROL ));
-#ifndef LL_RELEASE_FOR_DOWNLOAD
- menu->append(new LLMenuItemCallGL("Debug Avatar Textures", handle_debug_avatar_textures, NULL, NULL, 'A', MASK_SHIFT|MASK_CONTROL|MASK_ALT));
- menu->append(new LLMenuItemCallGL("Dump Local Textures", handle_dump_avatar_local_textures, NULL, NULL, 'M', MASK_SHIFT|MASK_ALT ));
-#endif
- menu->createJumpKeys();
+ bool new_value = gGLManager.mHasOcclusionQuery && LLFeatureManager::getInstance()->isFeatureAvailable(userdata.asString());
+ return new_value;
}
+};
+
+
+
+//////////////////
+// ADMIN STATUS //
+//////////////////
+
+
+class LLAdvancedRequestAdminStatus : public view_listener_t
+{
+ bool handleEvent(const LLSD& userdata)
+ {
+ handle_god_mode(NULL);
+ return true;
+ }
+};
+
+class LLAdvancedLeaveAdminStatus : public view_listener_t
+{
+ bool handleEvent(const LLSD& userdata)
+ {
+ handle_leave_god_mode(NULL);
+ return true;
+ }
+};
+
+//////////////////////////
+// Advanced > Debugging //
+//////////////////////////
+
+
+class LLAdvancedForceErrorBreakpoint : public view_listener_t
+{
+ bool handleEvent(const LLSD& userdata)
+ {
+ force_error_breakpoint(NULL);
+ return true;
+ }
+};
+
+class LLAdvancedForceErrorLlerror : public view_listener_t
+{
+ bool handleEvent(const LLSD& userdata)
+ {
+ force_error_llerror(NULL);
+ return true;
+ }
+};
+class LLAdvancedForceErrorBadMemoryAccess : public view_listener_t
+{
+ bool handleEvent(const LLSD& userdata)
+ {
+ force_error_bad_memory_access(NULL);
+ return true;
+ }
+};
+
+class LLAdvancedForceErrorInfiniteLoop : public view_listener_t
+{
+ bool handleEvent(const LLSD& userdata)
+ {
+ force_error_infinite_loop(NULL);
+ return true;
+ }
+};
+
+class LLAdvancedForceErrorSoftwareException : public view_listener_t
+{
+ bool handleEvent(const LLSD& userdata)
+ {
+ force_error_software_exception(NULL);
+ return true;
+ }
+};
-void init_debug_baked_texture_menu(LLMenuGL* menu)
+class LLAdvancedForceErrorDriverCrash : public view_listener_t
{
- menu->append(new LLMenuItemCallGL("Iris", handle_grab_texture, enable_grab_texture, (void*) TEX_EYES_BAKED));
- menu->append(new LLMenuItemCallGL("Head", handle_grab_texture, enable_grab_texture, (void*) TEX_HEAD_BAKED));
- menu->append(new LLMenuItemCallGL("Upper Body", handle_grab_texture, enable_grab_texture, (void*) TEX_UPPER_BAKED));
- menu->append(new LLMenuItemCallGL("Lower Body", handle_grab_texture, enable_grab_texture, (void*) TEX_LOWER_BAKED));
- menu->append(new LLMenuItemCallGL("Skirt", handle_grab_texture, enable_grab_texture, (void*) TEX_SKIRT_BAKED));
- menu->append(new LLMenuItemCallGL("Hair", handle_grab_texture, enable_grab_texture, (void*) TEX_HAIR_BAKED));
- menu->createJumpKeys();
+ bool handleEvent(const LLSD& userdata)
+ {
+ force_error_driver_crash(NULL);
+ return true;
+ }
+};
+
+class LLAdvancedForceErrorDisconnectViewer : public view_listener_t
+{
+ bool handleEvent(const LLSD& userdata)
+ {
+ handle_disconnect_viewer(NULL);
+ return true;
}
+};
+
-void init_server_menu(LLMenuGL* menu)
+#ifdef TOGGLE_HACKED_GODLIKE_VIEWER
+
+class LLAdvancedHandleToggleHackedGodmode : public view_listener_t
{
+ bool handleEvent(const LLSD& userdata)
{
- LLMenuGL* sub = new LLMenuGL("Object");
- menu->appendMenu(sub);
+ handle_toggle_hacked_godmode(NULL);
+ return true;
+ }
+};
- sub->append(new LLMenuItemCallGL( "Take Copy",
- &force_take_copy, &enable_god_customer_service, NULL,
- 'O', MASK_SHIFT | MASK_ALT | MASK_CONTROL));
-#ifdef _CORY_TESTING
- sub->append(new LLMenuItemCallGL( "Export Copy",
- &force_export_copy, NULL, NULL));
- sub->append(new LLMenuItemCallGL( "Import Geometry",
- &force_import_geometry, NULL, NULL));
+class LLAdvancedCheckToggleHackedGodmode : public view_listener_t
+{
+ bool handleEvent(const LLSD& userdata)
+ {
+ check_toggle_hacked_godmode(NULL);
+ return true;
+ }
+};
+
+class LLAdvancedEnableToggleHackedGodmode : public view_listener_t
+{
+ bool handleEvent(const LLSD& userdata)
+ {
+ bool new_value = enable_toggle_hacked_godmode(NULL);
+ return new_value;
+ }
+};
#endif
- //sub->append(new LLMenuItemCallGL( "Force Public",
- // &handle_object_owner_none, NULL, NULL));
- //sub->append(new LLMenuItemCallGL( "Force Ownership/Permissive",
- // &handle_object_owner_self_and_permissive, NULL, NULL, 'K', MASK_SHIFT | MASK_ALT | MASK_CONTROL));
- sub->append(new LLMenuItemCallGL( "Force Owner To Me",
- &handle_object_owner_self, &enable_god_customer_service));
- sub->append(new LLMenuItemCallGL( "Force Owner Permissive",
- &handle_object_owner_permissive, &enable_god_customer_service));
- //sub->append(new LLMenuItemCallGL( "Force Totally Permissive",
- // &handle_object_permissive));
- sub->append(new LLMenuItemCallGL( "Delete",
- &handle_force_delete, &enable_god_customer_service, NULL, KEY_DELETE, MASK_SHIFT | MASK_ALT | MASK_CONTROL));
- sub->append(new LLMenuItemCallGL( "Lock",
- &handle_object_lock, &enable_god_customer_service, NULL, 'L', MASK_SHIFT | MASK_ALT | MASK_CONTROL));
- sub->append(new LLMenuItemCallGL( "Get Asset IDs",
- &handle_object_asset_ids, &enable_god_customer_service, NULL, 'I', MASK_SHIFT | MASK_ALT | MASK_CONTROL));
- sub->createJumpKeys();
- }
- {
- LLMenuGL* sub = new LLMenuGL("Parcel");
- menu->appendMenu(sub);
-
- sub->append(new LLMenuItemCallGL("Owner To Me",
- &handle_force_parcel_owner_to_me,
- &enable_god_customer_service, NULL));
- sub->append(new LLMenuItemCallGL("Set to Linden Content",
- &handle_force_parcel_to_content,
- &enable_god_customer_service, NULL,
- 'C', MASK_SHIFT | MASK_ALT | MASK_CONTROL));
- sub->appendSeparator();
- sub->append(new LLMenuItemCallGL("Claim Public Land",
- &handle_claim_public_land, &enable_god_customer_service));
-
- sub->createJumpKeys();
- }
- {
- LLMenuGL* sub = new LLMenuGL("Region");
- menu->appendMenu(sub);
- sub->append(new LLMenuItemCallGL("Dump Temp Asset Data",
- &handle_region_dump_temp_asset_data,
- &enable_god_customer_service, NULL));
- sub->createJumpKeys();
+
+
+//
+////-------------------------------------------------------------------
+//// Advanced menu
+////-------------------------------------------------------------------
+
+//////////////////
+// ADMIN MENU //
+//////////////////
+
+// Admin > Object
+class LLAdminForceTakeCopy : public view_listener_t
+{
+ bool handleEvent(const LLSD& userdata)
+ {
+ force_take_copy(NULL);
+ return true;
+ }
+};
+
+class LLAdminHandleObjectOwnerSelf : public view_listener_t
+{
+ bool handleEvent(const LLSD& userdata)
+ {
+ handle_object_owner_self(NULL);
+ return true;
+ }
+};
+class LLAdminHandleObjectOwnerPermissive : public view_listener_t
+{
+ bool handleEvent(const LLSD& userdata)
+ {
+ handle_object_owner_permissive(NULL);
+ return true;
+ }
+};
+
+class LLAdminHandleForceDelete : public view_listener_t
+{
+ bool handleEvent(const LLSD& userdata)
+ {
+ handle_force_delete(NULL);
+ return true;
+ }
+};
+
+class LLAdminHandleObjectLock : public view_listener_t
+{
+ bool handleEvent(const LLSD& userdata)
+ {
+ handle_object_lock(NULL);
+ return true;
+ }
+};
+
+class LLAdminHandleObjectAssetIDs: public view_listener_t
+{
+ bool handleEvent(const LLSD& userdata)
+ {
+ handle_object_asset_ids(NULL);
+ return true;
}
- menu->append(new LLMenuItemCallGL( "God Tools...",
- &LLFloaterGodTools::show, &enable_god_basic, NULL));
+};
- menu->appendSeparator();
+//Admin >Parcel
+class LLAdminHandleForceParcelOwnerToMe: public view_listener_t
+{
+ bool handleEvent(const LLSD& userdata)
+ {
+ handle_force_parcel_owner_to_me(NULL);
+ return true;
+ }
+};
+class LLAdminHandleForceParcelToContent: public view_listener_t
+{
+ bool handleEvent(const LLSD& userdata)
+ {
+ handle_force_parcel_to_content(NULL);
+ return true;
+ }
+};
+class LLAdminHandleClaimPublicLand: public view_listener_t
+{
+ bool handleEvent(const LLSD& userdata)
+ {
+ handle_claim_public_land(NULL);
+ return true;
+ }
+};
- menu->append(new LLMenuItemCallGL("Save Region State",
- &LLPanelRegionTools::onSaveState, &enable_god_customer_service, NULL));
+// Admin > Region
+class LLAdminHandleRegionDumpTempAssetData: public view_listener_t
+{
+ bool handleEvent(const LLSD& userdata)
+ {
+ handle_region_dump_temp_asset_data(NULL);
+ return true;
+ }
+};
+//Admin (Top Level)
-// menu->append(new LLMenuItemCallGL("Force Join Group", handle_force_join_group));
-//
-// menu->appendSeparator();
-//
-// menu->append(new LLMenuItemCallGL( "OverlayTitle",
-// &handle_show_overlay_title, &enable_god_customer_service, NULL));
- menu->createJumpKeys();
+class LLAdminOnSaveState: public view_listener_t
+{
+ bool handleEvent(const LLSD& userdata)
+ {
+ LLPanelRegionTools::onSaveState(NULL);
+ return true;
}
+};
-static std::vector<LLPointer<view_listener_t> > sMenus;
//-----------------------------------------------------------------------------
// cleanup_menus()
@@ -1513,8 +2421,6 @@ void cleanup_menus()
delete gMenuHolder;
gMenuHolder = NULL;
-
- sMenus.clear();
}
//-----------------------------------------------------------------------------
@@ -1523,7 +2429,7 @@ void cleanup_menus()
class LLObjectReportAbuse : public view_listener_t
{
- bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
+ bool handleEvent(const LLSD& userdata)
{
LLViewerObject* objectp = LLSelectMgr::getInstance()->getSelection()->getPrimaryObject();
if (objectp)
@@ -1537,17 +2443,16 @@ class LLObjectReportAbuse : public view_listener_t
// Enabled it you clicked an object
class LLObjectEnableReportAbuse : public view_listener_t
{
- bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
+ bool handleEvent(const LLSD& userdata)
{
bool new_value = LLSelectMgr::getInstance()->getSelection()->getObjectCount() != 0;
- gMenuHolder->findControl(userdata["control"].asString())->setValue(new_value);
- return true;
+ return new_value;
}
};
class LLObjectTouch : public view_listener_t
{
- bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
+ bool handleEvent(const LLSD& userdata)
{
LLViewerObject* object = LLSelectMgr::getInstance()->getSelection()->getPrimaryObject();
if (!object) return true;
@@ -1598,45 +2503,42 @@ class LLObjectTouch : public view_listener_t
// One object must have touch sensor
class LLObjectEnableTouch : public view_listener_t
{
- bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
+ bool handleEvent(const LLSD& userdata)
{
LLViewerObject* obj = LLSelectMgr::getInstance()->getSelection()->getPrimaryObject();
bool new_value = obj && obj->flagHandleTouch();
- gMenuHolder->findControl(userdata["control"].asString())->setValue(new_value);
// Update label based on the node touch name if available.
- LLSelectNode* node = LLSelectMgr::getInstance()->getSelection()->getFirstRootNode();
-
std::string touch_text;
+ LLSelectNode* node = LLSelectMgr::getInstance()->getSelection()->getFirstRootNode();
if (node && node->mValid && !node->mTouchName.empty())
{
- touch_text = node->mTouchName;
+ touch_text = node->mTouchName;
}
else
{
- touch_text = userdata["data"].asString();
+ touch_text = userdata.asString();
}
-
gMenuHolder->childSetText("Object Touch", touch_text);
gMenuHolder->childSetText("Attachment Object Touch", touch_text);
- return true;
+ return new_value;
}
};
-void label_touch(std::string& label, void*)
-{
- LLSelectNode* node = LLSelectMgr::getInstance()->getSelection()->getFirstRootNode();
- if (node && node->mValid && !node->mTouchName.empty())
- {
- label.assign(node->mTouchName);
- }
- else
- {
- label.assign("Touch");
- }
-}
-
+//void label_touch(std::string& label, void*)
+//{
+// LLSelectNode* node = LLSelectMgr::getInstance()->getSelection()->getFirstRootNode();
+// if (node && node->mValid && !node->mTouchName.empty())
+// {
+// label.assign(node->mTouchName);
+// }
+// else
+// {
+// label.assign("Touch");
+// }
+//}
+/*
bool handle_object_open()
{
LLViewerObject* obj = LLSelectMgr::getInstance()->getSelection()->getPrimaryObject();
@@ -1648,15 +2550,15 @@ bool handle_object_open()
class LLObjectOpen : public view_listener_t
{
- bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
+ bool handleEvent(const LLSD& userdata)
{
return handle_object_open();
}
};
-
+*/
class LLObjectEnableOpen : public view_listener_t
{
- bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
+ bool handleEvent(const LLSD& userdata)
{
// Look for contents in root object, which is all the LLFloaterOpenObject
// understands.
@@ -1668,96 +2570,14 @@ class LLObjectEnableOpen : public view_listener_t
if (!root) new_value = false;
else new_value = root->allowOpen();
}
- gMenuHolder->findControl(userdata["control"].asString())->setValue(new_value);
- return true;
- }
-};
-
-
-class LLViewCheckBuildMode : public view_listener_t
-{
- bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
- {
- bool new_value = LLToolMgr::getInstance()->inEdit();
- gMenuHolder->findControl(userdata["control"].asString())->setValue(new_value);
- return true;
- }
-};
-
-bool toggle_build_mode()
-{
- if (LLToolMgr::getInstance()->inBuildMode())
- {
- if (gSavedSettings.getBOOL("EditCameraMovement"))
- {
- // just reset the view, will pull us out of edit mode
- handle_reset_view();
- }
- else
- {
- // manually disable edit mode, but do not affect the camera
- gAgent.resetView(false);
- gFloaterTools->close();
- gViewerWindow->showCursor();
- }
- // avoid spurious avatar movements pulling out of edit mode
- LLViewerJoystick::getInstance()->setNeedsReset();
- }
- else
- {
- ECameraMode camMode = gAgent.getCameraMode();
- if (CAMERA_MODE_MOUSELOOK == camMode || CAMERA_MODE_CUSTOMIZE_AVATAR == camMode)
- {
- // pull the user out of mouselook or appearance mode when entering build mode
- handle_reset_view();
- }
-
- if (gSavedSettings.getBOOL("EditCameraMovement"))
- {
- // camera should be set
- if (LLViewerJoystick::getInstance()->getOverrideCamera())
- {
- handle_toggle_flycam();
- }
-
- if (gAgent.getFocusOnAvatar())
- {
- // zoom in if we're looking at the avatar
- gAgent.setFocusOnAvatar(FALSE, ANIMATE);
- gAgent.setFocusGlobal(gAgent.getPositionGlobal() + 2.0 * LLVector3d(gAgent.getAtAxis()));
- gAgent.cameraZoomIn(0.666f);
- gAgent.cameraOrbitOver( 30.f * DEG_TO_RAD );
- }
- }
-
-
- LLToolMgr::getInstance()->setCurrentToolset(gBasicToolset);
- LLToolMgr::getInstance()->getCurrentToolset()->selectTool( LLToolCompCreate::getInstance() );
-
- // Could be first use
- LLFirstUse::useBuild();
-
- gAgent.resetView(false);
-
- // avoid spurious avatar movements
- LLViewerJoystick::getInstance()->setNeedsReset();
-
- }
- return true;
-}
-
-class LLViewBuildMode : public view_listener_t
-{
- bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
- {
- return toggle_build_mode();
+ return new_value;
}
};
class LLViewJoystickFlycam : public view_listener_t
{
- bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
+ bool handleEvent(const LLSD& userdata)
{
handle_toggle_flycam();
return true;
@@ -1766,31 +2586,13 @@ class LLViewJoystickFlycam : public view_listener_t
class LLViewCheckJoystickFlycam : public view_listener_t
{
- bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
- {
- bool new_val = LLViewerJoystick::getInstance()->getOverrideCamera();
- gMenuHolder->findControl(userdata["control"].asString())->setValue(new_val);
- return true;
- }
-};
-
-class LLViewCommunicate : public view_listener_t
-{
- bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
- {
- if (LLFloaterChatterBox::getInstance()->getFloaterCount() == 0)
- {
- LLFloaterMyFriends::toggleInstance();
- }
- else
+ bool handleEvent(const LLSD& userdata)
{
- LLFloaterChatterBox::toggleInstance();
- }
- return true;
+ bool new_value = LLViewerJoystick::getInstance()->getOverrideCamera();
+ return new_value;
}
};
-
void handle_toggle_flycam()
{
LLViewerJoystick::getInstance()->toggleFlycam();
@@ -1798,7 +2600,7 @@ void handle_toggle_flycam()
class LLObjectBuild : public view_listener_t
{
- bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
+ bool handleEvent(const LLSD& userdata)
{
if (gAgent.getFocusOnAvatar() && !LLToolMgr::getInstance()->inEdit() && gSavedSettings.getBOOL("EditCameraMovement") )
{
@@ -1826,7 +2628,7 @@ class LLObjectBuild : public view_listener_t
class LLObjectEdit : public view_listener_t
{
- bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
+ bool handleEvent(const LLSD& userdata)
{
LLViewerParcelMgr::getInstance()->deselectLand();
@@ -1856,7 +2658,7 @@ class LLObjectEdit : public view_listener_t
}
}
- gFloaterTools->open(); /* Flawfinder: ignore */
+ LLFloaterReg::showInstance("build");
LLToolMgr::getInstance()->setCurrentToolset(gBasicToolset);
gFloaterTools->setEditTool( LLToolCompTranslate::getInstance() );
@@ -1870,22 +2672,12 @@ class LLObjectEdit : public view_listener_t
}
};
-class LLObjectInspect : public view_listener_t
-{
- bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
- {
- LLFloaterInspect::show();
- return true;
- }
-};
-
-
//---------------------------------------------------------------------------
// Land pie menu
//---------------------------------------------------------------------------
class LLLandBuild : public view_listener_t
{
- bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
+ bool handleEvent(const LLSD& userdata)
{
LLViewerParcelMgr::getInstance()->deselectLand();
@@ -1917,7 +2709,7 @@ class LLLandBuild : public view_listener_t
class LLLandBuyPass : public view_listener_t
{
- bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
+ bool handleEvent(const LLSD& userdata)
{
LLPanelLandGeneral::onClickBuyPass((void *)FALSE);
return true;
@@ -1926,11 +2718,10 @@ class LLLandBuyPass : public view_listener_t
class LLLandEnableBuyPass : public view_listener_t
{
- bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
+ bool handleEvent(const LLSD& userdata)
{
bool new_value = LLPanelLandGeneral::enableBuyPass(NULL);
- gMenuHolder->findControl(userdata["control"].asString())->setValue(new_value);
- return true;
+ return new_value;
}
};
@@ -1966,7 +2757,7 @@ BOOL enable_object_build(void*)
class LLEnableEdit : public view_listener_t
{
- bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
+ bool handleEvent(const LLSD& userdata)
{
// *HACK: The new "prelude" Help Islands have a build sandbox area,
// so users need the Edit and Create pie menu options when they are
@@ -1979,23 +2770,22 @@ class LLEnableEdit : public view_listener_t
enable = LLViewerParcelMgr::getInstance()->agentCanBuild()
|| LLSelectMgr::getInstance()->getSelection()->isAttachment();
}
- gMenuHolder->findControl(userdata["control"].asString())->setValue(enable);
- return true;
+ return enable;
}
};
class LLSelfRemoveAllAttachments : public view_listener_t
{
- bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
+ bool handleEvent(const LLSD& userdata)
{
- LLAgent::userRemoveAllAttachments(NULL);
+ LLAgentWearables::userRemoveAllAttachments(NULL);
return true;
}
};
class LLSelfEnableRemoveAllAttachments : public view_listener_t
{
- bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
+ bool handleEvent(const LLSD& userdata)
{
bool new_value = false;
if (gAgent.getAvatarObject())
@@ -2013,8 +2803,7 @@ class LLSelfEnableRemoveAllAttachments : public view_listener_t
}
}
}
- gMenuHolder->findControl(userdata["control"].asString())->setValue(new_value);
- return true;
+ return new_value;
}
};
@@ -2027,19 +2816,19 @@ BOOL enable_has_attachments(void*)
//---------------------------------------------------------------------------
// Avatar pie menu
//---------------------------------------------------------------------------
-void handle_follow(void *userdata)
-{
- // follow a given avatar by ID
- LLViewerObject* objectp = LLSelectMgr::getInstance()->getSelection()->getPrimaryObject();
- if (objectp)
- {
- gAgent.startFollowPilot(objectp->getID());
- }
-}
+//void handle_follow(void *userdata)
+//{
+// // follow a given avatar by ID
+// LLViewerObject* objectp = LLSelectMgr::getInstance()->getSelection()->getPrimaryObject();
+// if (objectp)
+// {
+// gAgent.startFollowPilot(objectp->getID());
+// }
+//}
class LLObjectEnableMute : public view_listener_t
{
- bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
+ bool handleEvent(const LLSD& userdata)
{
LLViewerObject* object = LLSelectMgr::getInstance()->getSelection()->getPrimaryObject();
bool new_value = (object != NULL);
@@ -2055,14 +2844,13 @@ class LLObjectEnableMute : public view_listener_t
new_value = !is_linden && !is_self;
}
}
- gMenuHolder->findControl(userdata["control"].asString())->setValue(new_value);
- return true;
+ return new_value;
}
};
class LLObjectMute : public view_listener_t
{
- bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
+ bool handleEvent(const LLSD& userdata)
{
LLViewerObject* object = LLSelectMgr::getInstance()->getSelection()->getPrimaryObject();
if (!object) return true;
@@ -2108,7 +2896,7 @@ class LLObjectMute : public view_listener_t
else
{
LLMuteList::getInstance()->add(mute);
- LLFloaterMute::showInstance();
+ LLFloaterReg::showInstance("mute");
}
return true;
@@ -2148,12 +2936,26 @@ bool handle_go_to()
class LLGoToObject : public view_listener_t
{
- bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
+ bool handleEvent(const LLSD& userdata)
{
return handle_go_to();
}
};
+class LLAvatarReportAbuse : public view_listener_t
+{
+ bool handleEvent(const LLSD& userdata)
+ {
+ LLVOAvatar* avatar = find_avatar_from_object( LLSelectMgr::getInstance()->getSelection()->getPrimaryObject() );
+ if(avatar)
+ {
+ LLFloaterReporter::showFromObject(avatar->getID());
+ }
+ return true;
+ }
+};
+
+
//---------------------------------------------------------------------------
// Parcel freeze, eject, etc.
//---------------------------------------------------------------------------
@@ -2192,7 +2994,7 @@ bool callback_freeze(const LLSD& notification, const LLSD& response)
class LLAvatarFreeze : public view_listener_t
{
- bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
+ bool handleEvent(const LLSD& userdata)
{
LLVOAvatar* avatar = find_avatar_from_object( LLSelectMgr::getInstance()->getSelection()->getPrimaryObject() );
if( avatar )
@@ -2224,38 +3026,37 @@ class LLAvatarFreeze : public view_listener_t
class LLAvatarVisibleDebug : public view_listener_t
{
- bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
+ bool handleEvent(const LLSD& userdata)
{
- bool new_value = gAgent.isGodlike();
- gMenuHolder->findControl(userdata["control"].asString())->setValue(new_value);
- return true;
+ return gAgent.isGodlike();
}
};
class LLAvatarEnableDebug : public view_listener_t
{
- bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
+ bool handleEvent(const LLSD& userdata)
{
- bool new_value = gAgent.isGodlike();
- gMenuHolder->findControl(userdata["control"].asString())->setValue(new_value);
- return true;
+ return gAgent.isGodlike();
}
};
class LLAvatarDebug : public view_listener_t
{
- bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
+ bool handleEvent(const LLSD& userdata)
{
LLVOAvatar* avatar = find_avatar_from_object( LLSelectMgr::getInstance()->getSelection()->getPrimaryObject() );
if( avatar )
{
- avatar->dumpLocalTextures();
+ if (avatar->isSelf())
+ {
+ ((LLVOAvatarSelf *)avatar)->dumpLocalTextures();
+ }
llinfos << "Dumping temporary asset data to simulator logs for avatar " << avatar->getID() << llendl;
std::vector<std::string> strings;
strings.push_back(avatar->getID().asString());
LLUUID invoice;
send_generic_message("dumptempassetdata", strings, invoice);
- LLFloaterAvatarTextures::show( avatar->getID() );
+ LLFloaterReg::showInstance( "avatar_tetures", LLSD(avatar->getID()) );
}
return true;
}
@@ -2317,7 +3118,7 @@ bool callback_eject(const LLSD& notification, const LLSD& response)
class LLAvatarEject : public view_listener_t
{
- bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
+ bool handleEvent(const LLSD& userdata)
{
LLVOAvatar* avatar = find_avatar_from_object( LLSelectMgr::getInstance()->getSelection()->getPrimaryObject() );
if( avatar )
@@ -2376,7 +3177,7 @@ class LLAvatarEject : public view_listener_t
class LLAvatarEnableFreezeEject : public view_listener_t
{
- bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
+ bool handleEvent(const LLSD& userdata)
{
LLVOAvatar* avatar = find_avatar_from_object( LLSelectMgr::getInstance()->getSelection()->getPrimaryObject() );
bool new_value = (avatar != NULL);
@@ -2399,14 +3200,13 @@ class LLAvatarEnableFreezeEject : public view_listener_t
}
}
- gMenuHolder->findControl(userdata["control"].asString())->setValue(new_value);
- return true;
+ return new_value;
}
};
class LLAvatarGiveCard : public view_listener_t
{
- bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
+ bool handleEvent(const LLSD& userdata)
{
llinfos << "handle_give_card()" << llendl;
LLViewerObject* dest = LLSelectMgr::getInstance()->getSelection()->getPrimaryObject();
@@ -2461,7 +3261,7 @@ void login_done(S32 which, void *user)
{
llinfos << "Login done " << which << llendl;
- LLPanelLogin::close();
+ LLPanelLogin::closePanel();
}
@@ -2477,22 +3277,12 @@ bool callback_leave_group(const LLSD& notification, const LLSD& response)
msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID() );
msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
msg->nextBlockFast(_PREHASH_GroupData);
- msg->addUUIDFast(_PREHASH_GroupID, gAgent.mGroupID );
+ msg->addUUIDFast(_PREHASH_GroupID, gAgent.getGroupID() );
gAgent.sendReliableMessage();
}
return false;
}
-void handle_leave_group(void *)
-{
- if (gAgent.getGroupID() != LLUUID::null)
- {
- LLSD args;
- args["GROUP"] = gAgent.mGroupName;
- LLNotifications::instance().add("GroupLeaveConfirmMember", args, LLSD(), callback_leave_group);
- }
-}
-
void append_aggregate(std::string& string, const LLAggregatePermissions& ag_perm, PermissionBit bit, const char* txt)
{
LLAggregatePermissions::EValue val = ag_perm.getValue(bit);
@@ -2538,11 +3328,10 @@ BOOL enable_buy(void*)
class LLObjectEnableBuy : public view_listener_t
{
- bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
+ bool handleEvent(const LLSD& userdata)
{
bool new_value = enable_buy(NULL);
- gMenuHolder->findControl(userdata["control"].asString())->setValue(new_value);
- return true;
+ return new_value;
}
};
@@ -2624,18 +3413,9 @@ void handle_region_dump_settings(void*)
}
}
-void handle_show_notifications_console(void *)
-{
- LLFloaterNotificationConsole::showInstance();
-}
-
void handle_dump_group_info(void *)
{
- llinfos << "group " << gAgent.mGroupName << llendl;
- llinfos << "ID " << gAgent.mGroupID << llendl;
- llinfos << "powers " << gAgent.mGroupPowers << llendl;
- llinfos << "title " << gAgent.mGroupTitle << llendl;
- //llinfos << "insig " << gAgent.mGroupInsigniaID << llendl;
+ gAgent.dumpGroupInfo();
}
void handle_dump_capabilities_info(void *)
@@ -2665,19 +3445,43 @@ void handle_dump_focus(void *)
class LLSelfStandUp : public view_listener_t
{
- bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
+ bool handleEvent(const LLSD& userdata)
{
- gAgent.setControlFlags(AGENT_CONTROL_STAND_UP);
+ gAgent.standUp();
return true;
}
};
class LLSelfEnableStandUp : public view_listener_t
{
- bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
+ bool handleEvent(const LLSD& userdata)
+ {
+ bool new_value = gAgent.getAvatarObject() && gAgent.getAvatarObject()->isSitting();
+ return new_value;
+ }
+};
+
+class LLSelfFriends : public view_listener_t
+{
+ bool handleEvent(const LLSD& userdata)
+ {
+ // Open "Friends" tab of the "People" panel in side tray.
+ LLSD param;
+ param["people_panel_tab_name"] = "friends_panel";
+
+ LLSideTray::getInstance()->showPanel("panel_people", param);
+ return true;
+ }
+};
+
+class LLSelfGroups : public view_listener_t
+{
+ bool handleEvent(const LLSD& userdata)
{
- bool new_value = gAgent.getAvatarObject() && gAgent.getAvatarObject()->mIsSitting;
- gMenuHolder->findControl(userdata["control"].asString())->setValue(new_value);
+ // Open "Groups" tab of the "People" panel in side tray.
+ LLSD param;
+ param["people_panel_tab_name"] = "groups_panel";
+ LLSideTray::getInstance()->showPanel("panel_people", param);
return true;
}
};
@@ -2740,7 +3544,6 @@ void set_god_level(U8 god_level)
LLNotifications::instance().add("LeavingGodMode", args);
}
-
// changing god-level can affect which menus we see
show_debug_menus();
}
@@ -2756,6 +3559,11 @@ BOOL check_toggle_hacked_godmode(void*)
{
return gHackGodmode;
}
+
+bool enable_toggle_hacked_godmode(void*)
+{
+ return !LLViewerLogin::getInstance()->isInProductionGrid();
+}
#endif
void process_grant_godlike_powers(LLMessageSystem* msg, void**)
@@ -2811,48 +3619,23 @@ bool LLHaveCallingcard::operator()(LLInventoryCategory* cat,
}
*/
-BOOL is_agent_friend(const LLUUID& agent_id)
-{
- return (LLAvatarTracker::instance().getBuddyInfo(agent_id) != NULL);
-}
-
BOOL is_agent_mappable(const LLUUID& agent_id)
{
- return (is_agent_friend(agent_id) &&
+ return (LLAvatarActions::isFriend(agent_id) &&
LLAvatarTracker::instance().getBuddyInfo(agent_id)->isOnline() &&
LLAvatarTracker::instance().getBuddyInfo(agent_id)->isRightGrantedFrom(LLRelationship::GRANT_MAP_LOCATION)
);
}
-// Enable a menu item when you have someone's card.
-/*
-BOOL enable_have_card(void *userdata)
-{
- LLUUID* avatar_id = (LLUUID *)userdata;
- if (gAgent.isGodlike())
- {
- return TRUE;
- }
- else if(avatar_id)
- {
- return is_agent_friend(*avatar_id);
- }
- else
- {
- return FALSE;
- }
-}
-*/
// Enable a menu item when you don't have someone's card.
class LLAvatarEnableAddFriend : public view_listener_t
{
- bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
+ bool handleEvent(const LLSD& userdata)
{
LLVOAvatar* avatar = find_avatar_from_object(LLSelectMgr::getInstance()->getSelection()->getPrimaryObject());
- bool new_value = avatar && !is_agent_friend(avatar->getID());
- gMenuHolder->findControl(userdata["control"].asString())->setValue(new_value);
- return true;
+ bool new_value = avatar && !LLAvatarActions::isFriend(avatar->getID());
+ return new_value;
}
};
@@ -2875,7 +3658,7 @@ void request_friendship(const LLUUID& dest_id)
}
if (!fullname.empty())
{
- LLPanelFriends::requestFriendshipDialog(dest_id, fullname);
+ LLAvatarActions::requestFriendshipDialog(dest_id, fullname);
}
else
{
@@ -2887,13 +3670,10 @@ void request_friendship(const LLUUID& dest_id)
class LLEditEnableCustomizeAvatar : public view_listener_t
{
- bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
+ bool handleEvent(const LLSD& userdata)
{
- bool new_value = (gAgent.getAvatarObject() &&
- gAgent.getAvatarObject()->isFullyLoaded() &&
- gAgent.areWearablesLoaded());
- gMenuHolder->findControl(userdata["control"].asString())->setValue(new_value);
- return true;
+ bool new_value = gAgentWearables.areWearablesLoaded();
+ return new_value;
}
};
@@ -2909,7 +3689,7 @@ bool handle_sit_or_stand()
if (sitting_on_selection())
{
- gAgent.setControlFlags(AGENT_CONTROL_STAND_UP);
+ gAgent.standUp();
return true;
}
@@ -2917,6 +3697,7 @@ bool handle_sit_or_stand()
if (object && object->getPCode() == LL_PCODE_VOLUME)
{
+
gMessageSystem->newMessageFast(_PREHASH_AgentRequestSit);
gMessageSystem->nextBlockFast(_PREHASH_AgentData);
gMessageSystem->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
@@ -2932,7 +3713,7 @@ bool handle_sit_or_stand()
class LLObjectSitOrStand : public view_listener_t
{
- bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
+ bool handleEvent(const LLSD& userdata)
{
return handle_sit_or_stand();
}
@@ -2952,9 +3733,9 @@ void near_sit_down_point(BOOL success, void *)
class LLLandSit : public view_listener_t
{
- bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
+ bool handleEvent(const LLSD& userdata)
{
- gAgent.setControlFlags(AGENT_CONTROL_STAND_UP);
+ gAgent.standUp();
LLViewerParcelMgr::getInstance()->deselectLand();
LLVector3d posGlobal = LLToolPie::getInstance()->getPick().mPosGlobal;
@@ -2973,137 +3754,6 @@ class LLLandSit : public view_listener_t
}
};
-void show_permissions_control(void*)
-{
- LLFloaterPermissionsMgr* floaterp = LLFloaterPermissionsMgr::show();
- floaterp->mPermissions->addPermissionsData("foo1", LLUUID::null, 0);
- floaterp->mPermissions->addPermissionsData("foo2", LLUUID::null, 0);
- floaterp->mPermissions->addPermissionsData("foo3", LLUUID::null, 0);
-}
-
-
-class LLCreateLandmarkCallback : public LLInventoryCallback
-{
-public:
- /*virtual*/ void fire(const LLUUID& inv_item)
- {
- llinfos << "Created landmark with inventory id " << inv_item
- << llendl;
- }
-};
-
-void reload_ui(void *)
-{
- LLUICtrlFactory::getInstance()->rebuild();
-}
-
-class LLWorldFly : public view_listener_t
-{
- bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
- {
- gAgent.toggleFlying();
- return true;
- }
-};
-
-class LLWorldEnableFly : public view_listener_t
-{
- bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
- {
- BOOL sitting = FALSE;
- if (gAgent.getAvatarObject())
- {
- sitting = gAgent.getAvatarObject()->mIsSitting;
- }
- gMenuHolder->findControl(userdata["control"].asString())->setValue(!sitting);
- return true;
- }
-};
-
-
-void handle_agent_stop_moving(void*)
-{
- // stop agent
- gAgent.setControlFlags(AGENT_CONTROL_STOP);
-
- // cancel autopilot
- gAgent.stopAutoPilot();
-}
-
-void print_packets_lost(void*)
-{
- LLWorld::getInstance()->printPacketsLost();
-}
-
-
-void drop_packet(void*)
-{
- gMessageSystem->mPacketRing.dropPackets(1);
-}
-
-
-void velocity_interpolate( void* data )
-{
- BOOL toggle = gSavedSettings.getBOOL("VelocityInterpolate");
- LLMessageSystem* msg = gMessageSystem;
- if ( !toggle )
- {
- msg->newMessageFast(_PREHASH_VelocityInterpolateOn);
- msg->nextBlockFast(_PREHASH_AgentData);
- msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
- msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
- gAgent.sendReliableMessage();
- llinfos << "Velocity Interpolation On" << llendl;
- }
- else
- {
- msg->newMessageFast(_PREHASH_VelocityInterpolateOff);
- msg->nextBlockFast(_PREHASH_AgentData);
- msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
- msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
- gAgent.sendReliableMessage();
- llinfos << "Velocity Interpolation Off" << llendl;
- }
- // BUG this is a hack because of the change in menu behavior. The
- // old menu system would automatically change a control's value,
- // but the new LLMenuGL system doesn't know what a control
- // is. However, it's easy to distinguish between the two callers
- // because LLMenuGL passes in the name of the user data (the
- // control name) to the callback function, and the user data goes
- // unused in the old menu code. Thus, if data is not null, then we
- // need to swap the value of the control.
- if( data )
- {
- gSavedSettings.setBOOL( static_cast<char*>(data), !toggle );
- }
-}
-
-
-void toggle_wind_audio(void)
-{
- if (gAudiop)
- {
- gAudiop->enableWind(!(gAudiop->isWindEnabled()));
- }
-}
-
-
-// Callback for enablement
-BOOL is_inventory_visible( void* user_data )
-{
- LLInventoryView* iv = reinterpret_cast<LLInventoryView*>(user_data);
- if( iv )
- {
- return iv->getVisible();
- }
- return FALSE;
-}
-
-void handle_show_newest_map(void*)
-{
- LLFloaterWorldMap::show(NULL, FALSE);
-}
-
//-------------------------------------------------------------------
// Help menu functions
//-------------------------------------------------------------------
@@ -3111,24 +3761,24 @@ void handle_show_newest_map(void*)
//
// Major mode switching
//
-void reset_view_final( BOOL proceed, void* );
+void reset_view_final( BOOL proceed );
void handle_reset_view()
{
if( (CAMERA_MODE_CUSTOMIZE_AVATAR == gAgent.getCameraMode()) && gFloaterCustomize )
{
// Show dialog box if needed.
- gFloaterCustomize->askToSaveIfDirty( reset_view_final, NULL );
+ gFloaterCustomize->askToSaveIfDirty( reset_view_final );
}
else
{
- reset_view_final( TRUE, NULL );
+ reset_view_final( TRUE );
}
}
class LLViewResetView : public view_listener_t
{
- bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
+ bool handleEvent(const LLSD& userdata)
{
handle_reset_view();
return true;
@@ -3136,7 +3786,7 @@ class LLViewResetView : public view_listener_t
};
// Note: extra parameters allow this function to be called from dialog.
-void reset_view_final( BOOL proceed, void* )
+void reset_view_final( BOOL proceed )
{
if( !proceed )
{
@@ -3148,7 +3798,7 @@ void reset_view_final( BOOL proceed, void* )
class LLViewLookAtLastChatter : public view_listener_t
{
- bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
+ bool handleEvent(const LLSD& userdata)
{
gAgent.lookAtLastChat();
return true;
@@ -3157,7 +3807,7 @@ class LLViewLookAtLastChatter : public view_listener_t
class LLViewMouselook : public view_listener_t
{
- bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
+ bool handleEvent(const LLSD& userdata)
{
if (!gAgent.cameraMouselook())
{
@@ -3173,7 +3823,7 @@ class LLViewMouselook : public view_listener_t
class LLViewFullscreen : public view_listener_t
{
- bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
+ bool handleEvent(const LLSD& userdata)
{
gViewerWindow->toggleFullscreen(TRUE);
return true;
@@ -3182,7 +3832,7 @@ class LLViewFullscreen : public view_listener_t
class LLViewDefaultUISize : public view_listener_t
{
- bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
+ bool handleEvent(const LLSD& userdata)
{
gSavedSettings.setF32("UIScaleFactor", 1.0f);
gSavedSettings.setBOOL("UIAutoScale", FALSE);
@@ -3193,7 +3843,7 @@ class LLViewDefaultUISize : public view_listener_t
class LLEditDuplicate : public view_listener_t
{
- bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
+ bool handleEvent(const LLSD& userdata)
{
if(LLEditMenuHandler::gEditMenuHandler)
{
@@ -3205,23 +3855,13 @@ class LLEditDuplicate : public view_listener_t
class LLEditEnableDuplicate : public view_listener_t
{
- bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
+ bool handleEvent(const LLSD& userdata)
{
bool new_value = LLEditMenuHandler::gEditMenuHandler && LLEditMenuHandler::gEditMenuHandler->canDuplicate();
- gMenuHolder->findControl(userdata["control"].asString())->setValue(new_value);
- return true;
+ return new_value;
}
};
-
-void disabled_duplicate(void*)
-{
- if (LLSelectMgr::getInstance()->getSelection()->getPrimaryObject())
- {
- LLNotifications::instance().add("CopyFailed");
- }
-}
-
void handle_duplicate_in_place(void*)
{
llinfos << "handle_duplicate_in_place" << llendl;
@@ -3230,11 +3870,6 @@ void handle_duplicate_in_place(void*)
LLSelectMgr::getInstance()->selectDuplicate(offset, TRUE);
}
-void handle_repeat_duplicate(void*)
-{
- LLSelectMgr::getInstance()->repeatDuplicate();
-}
-
/* dead code 30-apr-2008
void handle_deed_object_to_group(void*)
{
@@ -3386,37 +4021,6 @@ void handle_claim_public_land(void*)
gAgent.sendReliableMessage();
}
-void handle_god_request_havok(void *)
-{
- if (gAgent.isGodlike())
- {
- LLSelectMgr::getInstance()->sendGodlikeRequest("havok", "infoverbose");
- }
-}
-
-//void handle_god_request_foo(void *)
-//{
-// if (gAgent.isGodlike())
-// {
-// LLSelectMgr::getInstance()->sendGodlikeRequest(GOD_WANTS_FOO);
-// }
-//}
-
-//void handle_god_request_terrain_save(void *)
-//{
-// if (gAgent.isGodlike())
-// {
-// LLSelectMgr::getInstance()->sendGodlikeRequest("terrain", "save");
-// }
-//}
-
-//void handle_god_request_terrain_load(void *)
-//{
-// if (gAgent.isGodlike())
-// {
-// LLSelectMgr::getInstance()->sendGodlikeRequest("terrain", "load");
-// }
-//}
// HACK for easily testing new avatar geometry
@@ -3429,12 +4033,6 @@ void handle_god_request_avatar_geometry(void *)
}
-void handle_show_overlay_title(void*)
-{
- gShowOverlayTitle = !gShowOverlayTitle;
- gSavedSettings.setBOOL("ShowOverlayTitle", gShowOverlayTitle);
-}
-
void derez_objects(EDeRezDestination dest, const LLUUID& dest_id)
{
if(gAgent.cameraMouselook())
@@ -3590,7 +4188,7 @@ void derez_objects(EDeRezDestination dest, const LLUUID& dest_id)
class LLToolsTakeCopy : public view_listener_t
{
- bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
+ bool handleEvent(const LLSD& userdata)
{
if (LLSelectMgr::getInstance()->getSelection()->isEmpty()) return true;
@@ -3605,7 +4203,7 @@ class LLToolsTakeCopy : public view_listener_t
// You can return an object to its owner if it is on your land.
class LLObjectReturn : public view_listener_t
{
- bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
+ bool handleEvent(const LLSD& userdata)
{
if (LLSelectMgr::getInstance()->getSelection()->isEmpty()) return true;
@@ -3638,7 +4236,7 @@ protected:
// over land you own.
class LLObjectEnableReturn : public view_listener_t
{
- bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
+ bool handleEvent(const LLSD& userdata)
{
#ifdef HACKED_GODLIKE_VIEWER
bool new_value = true;
@@ -3675,8 +4273,7 @@ class LLObjectEnableReturn : public view_listener_t
}
}
#endif
- gMenuHolder->findControl(userdata["control"].asString())->setValue(new_value);
- return true;
+ return new_value;
}
};
@@ -3752,7 +4349,7 @@ void handle_take()
}
// check library
- if(gInventory.isObjectDescendentOf(category_id, gInventoryLibraryRoot))
+ if(gInventory.isObjectDescendentOf(category_id, gInventory.getLibraryRootFolderID()))
{
category_id.setNull();
}
@@ -3767,8 +4364,8 @@ void handle_take()
payload["folder_id"] = category_id;
LLNotification::Params params("ConfirmObjectTakeLock");
- params.payload(payload)
- .functor(confirm_take);
+ params.payload(payload);
+ params.functor.function(confirm_take);
if(locked_but_takeable_object ||
!you_own_everything)
@@ -3776,7 +4373,6 @@ void handle_take()
if(locked_but_takeable_object && you_own_everything)
{
params.name("ConfirmObjectTakeLock");
-
}
else if(!locked_but_takeable_object && !you_own_everything)
{
@@ -3849,7 +4445,7 @@ BOOL enable_take()
class LLToolsBuyOrTake : public view_listener_t
{
- bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
+ bool handleEvent(const LLSD& userdata)
{
if (LLSelectMgr::getInstance()->getSelection()->isEmpty())
{
@@ -3880,17 +4476,16 @@ class LLToolsBuyOrTake : public view_listener_t
class LLToolsEnableBuyOrTake : public view_listener_t
{
- bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
+ bool handleEvent(const LLSD& userdata)
{
bool is_buy = is_selection_buy_not_take();
bool new_value = is_buy ? enable_buy(NULL) : enable_take();
- gMenuHolder->findControl(userdata["control"].asString())->setValue(new_value);
// Update label
std::string label;
std::string buy_text;
std::string take_text;
- std::string param = userdata["data"].asString();
+ std::string param = userdata.asString();
std::string::size_type offset = param.find(",");
if (offset != param.npos)
{
@@ -3908,7 +4503,7 @@ class LLToolsEnableBuyOrTake : public view_listener_t
gMenuHolder->childSetText("Pie Object Take", label);
gMenuHolder->childSetText("Menu Object Take", label);
- return true;
+ return new_value;
}
};
@@ -3963,42 +4558,36 @@ S32 selection_price()
return total_price;
}
-
+/*
bool callback_show_buy_currency(const LLSD& notification, const LLSD& response)
{
S32 option = LLNotification::getSelectedOption(notification, response);
if (0 == option)
{
- llinfos << "Loading page " << BUY_CURRENCY_URL << llendl;
- LLWeb::loadURL(BUY_CURRENCY_URL);
+ llinfos << "Loading page " << LLNotifications::instance().getGlobalString("BUY_CURRENCY_URL") << llendl;
+ LLWeb::loadURL(LLNotifications::instance().getGlobalString("BUY_CURRENCY_URL"));
}
return false;
}
-
+*/
void show_buy_currency(const char* extra)
{
// Don't show currency web page for branded clients.
-
+/*
std::ostringstream mesg;
if (extra != NULL)
{
mesg << extra << "\n \n";
}
- mesg << "Go to " << BUY_CURRENCY_URL << "\nfor information on purchasing currency?";
-
+ mesg << "Go to " << LLNotifications::instance().getGlobalString("BUY_CURRENCY_URL")<< "\nfor information on purchasing currency?";
+*/
LLSD args;
if (extra != NULL)
{
args["EXTRA"] = extra;
}
- args["URL"] = BUY_CURRENCY_URL;
- LLNotifications::instance().add("PromptGoToCurrencyPage", args, LLSD(), callback_show_buy_currency);
-}
-
-void handle_buy_currency(void*)
-{
-// LLFloaterBuyCurrency::buyCurrency();
+ LLNotifications::instance().add("PromptGoToCurrencyPage", args);//, LLSD(), callback_show_buy_currency);
}
void handle_buy(void*)
@@ -4021,7 +4610,7 @@ void handle_buy(void*)
class LLObjectBuy : public view_listener_t
{
- bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
+ bool handleEvent(const LLSD& userdata)
{
handle_buy(NULL);
return true;
@@ -4054,12 +4643,24 @@ BOOL sitting_on_selection()
return FALSE;
}
- return (avatar->mIsSitting && avatar->getRoot() == root_object);
+ return (avatar->isSitting() && avatar->getRoot() == root_object);
}
+class LLToolsSaveToInventory : public view_listener_t
+{
+ bool handleEvent(const LLSD& userdata)
+ {
+ if(enable_save_into_inventory(NULL))
+ {
+ derez_objects(DRD_SAVE_INTO_AGENT_INVENTORY, LLUUID::null);
+ }
+ return true;
+ }
+};
+
class LLToolsSaveToObjectInventory : public view_listener_t
{
- bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
+ bool handleEvent(const LLSD& userdata)
{
LLSelectNode* node = LLSelectMgr::getInstance()->getSelection()->getFirstRootNode();
if(node && (node->mValid) && (!node->mFromTaskID.isNull()))
@@ -4074,7 +4675,7 @@ class LLToolsSaveToObjectInventory : public view_listener_t
// Round the position of all root objects to the grid
class LLToolsSnapObjectXY : public view_listener_t
{
- bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
+ bool handleEvent(const LLSD& userdata)
{
F64 snap_size = (F64)gSavedSettings.getF32("GridResolution");
@@ -4128,7 +4729,7 @@ class LLToolsSnapObjectXY : public view_listener_t
// reasonable expectation for the link to work, but it will fail.
class LLToolsEnableLink : public view_listener_t
{
- bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
+ bool handleEvent(const LLSD& userdata)
{
bool new_value = false;
// check if there are at least 2 objects selected, and that the
@@ -4150,14 +4751,13 @@ class LLToolsEnableLink : public view_listener_t
new_value = LLSelectMgr::getInstance()->getSelection()->applyToRootObjects(&func, firstonly);
}
}
- gMenuHolder->findControl(userdata["control"].asString())->setValue(new_value);
- return true;
+ return new_value;
}
};
class LLToolsLink : public view_listener_t
{
- bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
+ bool handleEvent(const LLSD& userdata)
{
if(!LLSelectMgr::getInstance()->selectGetAllRootsValid())
{
@@ -4203,19 +4803,18 @@ class LLToolsLink : public view_listener_t
class LLToolsEnableUnlink : public view_listener_t
{
- bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
+ bool handleEvent(const LLSD& userdata)
{
bool new_value = LLSelectMgr::getInstance()->selectGetAllRootsValid() &&
LLSelectMgr::getInstance()->getSelection()->getFirstEditableObject() &&
!LLSelectMgr::getInstance()->getSelection()->getFirstEditableObject()->isAttachment();
- gMenuHolder->findControl(userdata["control"].asString())->setValue(new_value);
- return true;
+ return new_value;
}
};
class LLToolsUnlink : public view_listener_t
{
- bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
+ bool handleEvent(const LLSD& userdata)
{
LLSelectMgr::getInstance()->sendDelink();
return true;
@@ -4225,7 +4824,7 @@ class LLToolsUnlink : public view_listener_t
class LLToolsStopAllAnimations : public view_listener_t
{
- bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
+ bool handleEvent(const LLSD& userdata)
{
gAgent.stopCurrentAnimations();
return true;
@@ -4234,7 +4833,7 @@ class LLToolsStopAllAnimations : public view_listener_t
class LLToolsReleaseKeys : public view_listener_t
{
- bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
+ bool handleEvent(const LLSD& userdata)
{
gAgent.forceReleaseControls();
@@ -4244,58 +4843,25 @@ class LLToolsReleaseKeys : public view_listener_t
class LLToolsEnableReleaseKeys : public view_listener_t
{
- bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
+ bool handleEvent(const LLSD& userdata)
{
- gMenuHolder->findControl(userdata["control"].asString())->setValue( gAgent.anyControlGrabbed() );
- return true;
+ return gAgent.anyControlGrabbed();
}
};
-//void handle_hinge(void*)
-//{
-// LLSelectMgr::getInstance()->sendHinge(1);
-//}
-
-//void handle_ptop(void*)
-//{
-// LLSelectMgr::getInstance()->sendHinge(2);
-//}
-
-//void handle_lptop(void*)
-//{
-// LLSelectMgr::getInstance()->sendHinge(3);
-//}
-
-//void handle_wheel(void*)
-//{
-// LLSelectMgr::getInstance()->sendHinge(4);
-//}
-
-//void handle_dehinge(void*)
-//{
-// LLSelectMgr::getInstance()->sendDehinge();
-//}
-
-//BOOL enable_dehinge(void*)
-//{
-// LLViewerObject* obj = LLSelectMgr::getInstance()->getSelection()->getFirstEditableObject();
-// return obj && !obj->isAttachment();
-//}
-
class LLEditEnableCut : public view_listener_t
{
- bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
+ bool handleEvent(const LLSD& userdata)
{
bool new_value = LLEditMenuHandler::gEditMenuHandler && LLEditMenuHandler::gEditMenuHandler->canCut();
- gMenuHolder->findControl(userdata["control"].asString())->setValue(new_value);
- return true;
+ return new_value;
}
};
class LLEditCut : public view_listener_t
{
- bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
+ bool handleEvent(const LLSD& userdata)
{
if( LLEditMenuHandler::gEditMenuHandler )
{
@@ -4307,17 +4873,16 @@ class LLEditCut : public view_listener_t
class LLEditEnableCopy : public view_listener_t
{
- bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
+ bool handleEvent(const LLSD& userdata)
{
bool new_value = LLEditMenuHandler::gEditMenuHandler && LLEditMenuHandler::gEditMenuHandler->canCopy();
- gMenuHolder->findControl(userdata["control"].asString())->setValue(new_value);
- return true;
+ return new_value;
}
};
class LLEditCopy : public view_listener_t
{
- bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
+ bool handleEvent(const LLSD& userdata)
{
if( LLEditMenuHandler::gEditMenuHandler )
{
@@ -4329,17 +4894,16 @@ class LLEditCopy : public view_listener_t
class LLEditEnablePaste : public view_listener_t
{
- bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
+ bool handleEvent(const LLSD& userdata)
{
bool new_value = LLEditMenuHandler::gEditMenuHandler && LLEditMenuHandler::gEditMenuHandler->canPaste();
- gMenuHolder->findControl(userdata["control"].asString())->setValue(new_value);
- return true;
+ return new_value;
}
};
class LLEditPaste : public view_listener_t
{
- bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
+ bool handleEvent(const LLSD& userdata)
{
if( LLEditMenuHandler::gEditMenuHandler )
{
@@ -4351,17 +4915,16 @@ class LLEditPaste : public view_listener_t
class LLEditEnableDelete : public view_listener_t
{
- bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
+ bool handleEvent(const LLSD& userdata)
{
bool new_value = LLEditMenuHandler::gEditMenuHandler && LLEditMenuHandler::gEditMenuHandler->canDoDelete();
- gMenuHolder->findControl(userdata["control"].asString())->setValue(new_value);
- return true;
+ return new_value;
}
};
class LLEditDelete : public view_listener_t
{
- bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
+ bool handleEvent(const LLSD& userdata)
{
// If a text field can do a deletion, it gets precedence over deleting
// an object in the world.
@@ -4375,14 +4938,14 @@ class LLEditDelete : public view_listener_t
// When deleting an object we may not actually be done
// Keep selection so we know what to delete when confirmation is needed about the delete
- gPieObject->hide(TRUE);
+ gPieObject->hide();
return true;
}
};
class LLObjectEnableDelete : public view_listener_t
{
- bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
+ bool handleEvent(const LLSD& userdata)
{
bool new_value =
#ifdef HACKED_GODLIKE_VIEWER
@@ -4394,23 +4957,13 @@ class LLObjectEnableDelete : public view_listener_t
# endif
LLSelectMgr::getInstance()->canDoDelete();
#endif
- gMenuHolder->findControl(userdata["control"].asString())->setValue(new_value);
- return true;
- }
-};
-
-class LLEditSearch : public view_listener_t
-{
- bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
- {
- LLFloaterDirectory::toggleFind(NULL);
- return true;
+ return new_value;
}
};
class LLObjectDelete : public view_listener_t
{
- bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
+ bool handleEvent(const LLSD& userdata)
{
if (LLSelectMgr::getInstance())
{
@@ -4422,7 +4975,7 @@ class LLObjectDelete : public view_listener_t
// When deleting an object we may not actually be done
// Keep selection so we know what to delete when confirmation is needed about the delete
- gPieObject->hide(TRUE);
+ gPieObject->hide();
return true;
}
};
@@ -4434,38 +4987,35 @@ void handle_force_delete(void*)
class LLViewEnableJoystickFlycam : public view_listener_t
{
- bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
+ bool handleEvent(const LLSD& userdata)
{
bool new_value = (gSavedSettings.getBOOL("JoystickEnabled") && gSavedSettings.getBOOL("JoystickFlycamEnabled"));
- gMenuHolder->findControl(userdata["control"].asString())->setValue(new_value);
- return true;
+ return new_value;
}
};
class LLViewEnableLastChatter : public view_listener_t
{
- bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
+ bool handleEvent(const LLSD& userdata)
{
// *TODO: add check that last chatter is in range
bool new_value = (gAgent.cameraThirdPerson() && gAgent.getLastChatter().notNull());
- gMenuHolder->findControl(userdata["control"].asString())->setValue(new_value);
- return true;
+ return new_value;
}
};
class LLEditEnableDeselect : public view_listener_t
{
- bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
+ bool handleEvent(const LLSD& userdata)
{
bool new_value = LLEditMenuHandler::gEditMenuHandler && LLEditMenuHandler::gEditMenuHandler->canDeselect();
- gMenuHolder->findControl(userdata["control"].asString())->setValue(new_value);
- return true;
+ return new_value;
}
};
class LLEditDeselect : public view_listener_t
{
- bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
+ bool handleEvent(const LLSD& userdata)
{
if( LLEditMenuHandler::gEditMenuHandler )
{
@@ -4477,18 +5027,17 @@ class LLEditDeselect : public view_listener_t
class LLEditEnableSelectAll : public view_listener_t
{
- bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
+ bool handleEvent(const LLSD& userdata)
{
bool new_value = LLEditMenuHandler::gEditMenuHandler && LLEditMenuHandler::gEditMenuHandler->canSelectAll();
- gMenuHolder->findControl(userdata["control"].asString())->setValue(new_value);
- return true;
+ return new_value;
}
};
class LLEditSelectAll : public view_listener_t
{
- bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
+ bool handleEvent(const LLSD& userdata)
{
if( LLEditMenuHandler::gEditMenuHandler )
{
@@ -4501,17 +5050,16 @@ class LLEditSelectAll : public view_listener_t
class LLEditEnableUndo : public view_listener_t
{
- bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
+ bool handleEvent(const LLSD& userdata)
{
bool new_value = LLEditMenuHandler::gEditMenuHandler && LLEditMenuHandler::gEditMenuHandler->canUndo();
- gMenuHolder->findControl(userdata["control"].asString())->setValue(new_value);
- return true;
+ return new_value;
}
};
class LLEditUndo : public view_listener_t
{
- bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
+ bool handleEvent(const LLSD& userdata)
{
if( LLEditMenuHandler::gEditMenuHandler && LLEditMenuHandler::gEditMenuHandler->canUndo() )
{
@@ -4523,17 +5071,16 @@ class LLEditUndo : public view_listener_t
class LLEditEnableRedo : public view_listener_t
{
- bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
+ bool handleEvent(const LLSD& userdata)
{
bool new_value = LLEditMenuHandler::gEditMenuHandler && LLEditMenuHandler::gEditMenuHandler->canRedo();
- gMenuHolder->findControl(userdata["control"].asString())->setValue(new_value);
- return true;
+ return new_value;
}
};
class LLEditRedo : public view_listener_t
{
- bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
+ bool handleEvent(const LLSD& userdata)
{
if( LLEditMenuHandler::gEditMenuHandler && LLEditMenuHandler::gEditMenuHandler->canRedo() )
{
@@ -4571,35 +5118,42 @@ void print_agent_nvpairs(void*)
void show_debug_menus()
{
- // this can get called at login screen where there is no menu so only toggle it if one exists
+ // this might get called at login screen where there is no menu so only toggle it if one exists
if ( gMenuBarView )
{
BOOL debug = gSavedSettings.getBOOL("UseDebugMenus");
+ BOOL qamode = gSavedSettings.getBOOL("QAMode");
+
+ gMenuBarView->setItemVisible("Advanced", debug);
+// gMenuBarView->setItemEnabled("Advanced", debug); // Don't disable Advanced keyboard shortcuts when hidden
- if(debug)
- {
- LLFirstUse::useDebugMenus();
- }
+ gMenuBarView->setItemVisible("Debug", qamode);
+ gMenuBarView->setItemEnabled("Debug", qamode);
- gMenuBarView->setItemVisible(CLIENT_MENU_NAME, debug);
- gMenuBarView->setItemEnabled(CLIENT_MENU_NAME, debug);
+ gMenuBarView->setItemVisible("Develop", qamode);
+ gMenuBarView->setItemEnabled("Develop", qamode);
// Server ('Admin') menu hidden when not in godmode.
const bool show_server_menu = debug && (gAgent.getGodLevel() > GOD_NOT);
- gMenuBarView->setItemVisible(SERVER_MENU_NAME, show_server_menu);
- gMenuBarView->setItemEnabled(SERVER_MENU_NAME, show_server_menu);
-
- //gMenuBarView->setItemVisible("DebugOptions", visible);
- //gMenuBarView->setItemVisible(std::string(AVI_TOOLS), visible);
-
- gMenuBarView->arrange(); // clean-up positioning
- };
+ gMenuBarView->setItemVisible("Admin", show_server_menu);
+ gMenuBarView->setItemEnabled("Admin", show_server_menu);
+ }
+ if (gLoginMenuBarView)
+ {
+ BOOL debug = gSavedSettings.getBOOL("UseDebugMenus");
+ gLoginMenuBarView->setItemVisible("Debug", debug);
+ gLoginMenuBarView->setItemEnabled("Debug", debug);
+ }
}
void toggle_debug_menus(void*)
{
BOOL visible = ! gSavedSettings.getBOOL("UseDebugMenus");
gSavedSettings.setBOOL("UseDebugMenus", visible);
+ if(visible)
+ {
+ LLFirstUse::useDebugMenus();
+ }
show_debug_menus();
}
@@ -4641,27 +5195,12 @@ void toggle_debug_menus(void*)
// gExportDialog = LLUploadDialog::modalUploadDialog("Exporting selected objects...");
// }
+//
-BOOL menu_check_build_tool( void* user_data )
-{
- S32 index = (intptr_t) user_data;
- return LLToolMgr::getInstance()->getCurrentToolset()->isToolSelected( index );
-}
-
-void handle_reload_settings(void*)
-{
- gSavedSettings.resetToDefaults();
- gSavedSettings.loadFromFile(gSavedSettings.getString("ClientSettingsFile"));
-
- llinfos << "Loading colors from colors.xml" << llendl;
- std::string color_file = gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS,"colors.xml");
- gColors.resetToDefaults();
- gColors.loadFromFileLegacy(color_file, FALSE, TYPE_COL4U);
-}
class LLWorldSetHomeLocation : public view_listener_t
{
- bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
+ bool handleEvent(const LLSD& userdata)
{
// we just send the message and let the server check for failure cases
// server will echo back a "Home position set." alert if it succeeds
@@ -4673,7 +5212,7 @@ class LLWorldSetHomeLocation : public view_listener_t
class LLWorldTeleportHome : public view_listener_t
{
- bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
+ bool handleEvent(const LLSD& userdata)
{
gAgent.teleportHome();
return true;
@@ -4682,7 +5221,7 @@ class LLWorldTeleportHome : public view_listener_t
class LLWorldAlwaysRun : public view_listener_t
{
- bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
+ bool handleEvent(const LLSD& userdata)
{
// as well as altering the default walk-vs-run state,
// we also change the *current* walk-vs-run state.
@@ -4700,23 +5239,25 @@ class LLWorldAlwaysRun : public view_listener_t
// tell the simulator.
gAgent.sendWalkRun(gAgent.getAlwaysRun());
+ // Update Movement Controls according to AlwaysRun mode
+ LLFloaterMove::setAlwaysRunMode(gAgent.getAlwaysRun());
+
return true;
}
};
class LLWorldCheckAlwaysRun : public view_listener_t
{
- bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
+ bool handleEvent(const LLSD& userdata)
{
bool new_value = gAgent.getAlwaysRun();
- gMenuHolder->findControl(userdata["control"].asString())->setValue(new_value);
- return true;
+ return new_value;
}
};
class LLWorldSetAway : public view_listener_t
{
- bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
+ bool handleEvent(const LLSD& userdata)
{
if (gAgent.getAFK())
{
@@ -4732,7 +5273,7 @@ class LLWorldSetAway : public view_listener_t
class LLWorldSetBusy : public view_listener_t
{
- bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
+ bool handleEvent(const LLSD& userdata)
{
if (gAgent.getBusy())
{
@@ -4747,53 +5288,19 @@ class LLWorldSetBusy : public view_listener_t
}
};
-bool can_create_landmark()
-{
- BOOL can = FALSE;
-
- LLParcel* agent_parcel = LLViewerParcelMgr::getInstance()->getAgentParcel();
- if (agent_parcel)
- {
-
- if (agent_parcel->getAllowLandmark()
- || LLViewerParcelMgr::isParcelOwnedByAgent(agent_parcel, GP_LAND_ALLOW_LANDMARK))
- {
- can = TRUE;
- }
- }
-
- return can;
-}
-
class LLWorldCreateLandmark : public view_listener_t
{
- bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
+ bool handleEvent(const LLSD& userdata)
{
- if (!can_create_landmark())
- {
- LLNotifications::instance().add("CannotCreateLandmarkNotOwner");
- return true;
- }
+ LLSideTray::getInstance()->showPanel("panel_places", LLSD().insert("type", "create_landmark"));
- LLUUID folder_id;
- folder_id = gInventory.findCategoryUUIDForType(LLAssetType::AT_LANDMARK);
- std::string pos_string;
- gAgent.buildLocationString(pos_string);
-
- create_inventory_item(gAgent.getID(), gAgent.getSessionID(),
- folder_id, LLTransactionID::tnull,
- pos_string, pos_string, // name, desc
- LLAssetType::AT_LANDMARK,
- LLInventoryType::IT_LANDMARK,
- NOT_WEARABLE, PERM_ALL,
- new LLCreateLandmarkCallback);
return true;
}
};
class LLToolsLookAtSelection : public view_listener_t
{
- bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
+ bool handleEvent(const LLSD& userdata)
{
const F32 PADDING_FACTOR = 2.f;
BOOL zoom = (userdata.asString() == "zoom");
@@ -4828,10 +5335,10 @@ class LLToolsLookAtSelection : public view_listener_t
}
};
-void callback_invite_to_group(LLUUID group_id, void *user_data)
+void callback_invite_to_group(LLUUID group_id, LLUUID dest_id)
{
std::vector<LLUUID> agent_ids;
- agent_ids.push_back(*(LLUUID *)user_data);
+ agent_ids.push_back(dest_id);
LLFloaterGroupInvite::showForGroup(group_id, &agent_ids);
}
@@ -4841,20 +5348,19 @@ void invite_to_group(const LLUUID& dest_id)
LLViewerObject* dest = gObjectList.findObject(dest_id);
if(dest && dest->isAvatar())
{
- LLFloaterGroupPicker* widget;
- widget = LLFloaterGroupPicker::showInstance(LLSD(gAgent.getID()));
+ LLFloaterGroupPicker* widget = LLFloaterReg::showTypedInstance<LLFloaterGroupPicker>("group_picker", LLSD(gAgent.getID()));
if (widget)
{
widget->center();
widget->setPowersMask(GP_MEMBER_INVITE);
- widget->setSelectCallback(callback_invite_to_group, (void *)&dest_id);
+ widget->setSelectGroupCallback(boost::bind(callback_invite_to_group, _1, dest_id));
}
}
}
class LLAvatarInviteToGroup : public view_listener_t
{
- bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
+ bool handleEvent(const LLSD& userdata)
{
LLVOAvatar* avatar = find_avatar_from_object( LLSelectMgr::getInstance()->getSelection()->getPrimaryObject() );
if(avatar)
@@ -4867,10 +5373,10 @@ class LLAvatarInviteToGroup : public view_listener_t
class LLAvatarAddFriend : public view_listener_t
{
- bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
+ bool handleEvent(const LLSD& userdata)
{
LLVOAvatar* avatar = find_avatar_from_object( LLSelectMgr::getInstance()->getSelection()->getPrimaryObject() );
- if(avatar && !is_agent_friend(avatar->getID()))
+ if(avatar && !LLAvatarActions::isFriend(avatar->getID()))
{
request_friendship(avatar->getID());
}
@@ -4878,6 +5384,19 @@ class LLAvatarAddFriend : public view_listener_t
}
};
+class LLAvatarAddContact : public view_listener_t
+{
+ bool handleEvent(const LLSD& userdata)
+ {
+ LLVOAvatar* avatar = find_avatar_from_object( LLSelectMgr::getInstance()->getSelection()->getPrimaryObject() );
+ if(avatar)
+ {
+ create_inventory_callingcard(avatar->getID());
+ }
+ return true;
+ }
+};
+
bool complete_give_money(const LLSD& notification, const LLSD& response, LLObjectSelectionHandle handle)
{
S32 option = LLNotification::getSelectedOption(notification, response);
@@ -4917,7 +5436,7 @@ bool complete_give_money(const LLSD& notification, const LLSD& response, LLObjec
bool handle_give_money_dialog()
{
LLNotification::Params params("BusyModePay");
- params.functor(boost::bind(complete_give_money, _1, _2, LLSelectMgr::getInstance()->getSelection()));
+ params.functor.function(boost::bind(complete_give_money, _1, _2, LLSelectMgr::getInstance()->getSelection()));
if (gAgent.getBusy())
{
@@ -4933,7 +5452,7 @@ bool handle_give_money_dialog()
class LLPayObject : public view_listener_t
{
- bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
+ bool handleEvent(const LLSD& userdata)
{
return handle_give_money_dialog();
}
@@ -4941,7 +5460,7 @@ class LLPayObject : public view_listener_t
class LLEnablePayObject : public view_listener_t
{
- bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
+ bool handleEvent(const LLSD& userdata)
{
LLVOAvatar* avatar = find_avatar_from_object(LLSelectMgr::getInstance()->getSelection()->getPrimaryObject());
bool new_value = (avatar != NULL);
@@ -4957,14 +5476,13 @@ class LLEnablePayObject : public view_listener_t
}
}
}
- gMenuHolder->findControl(userdata["control"].asString())->setValue(new_value);
- return true;
+ return new_value;
}
};
class LLObjectEnableSitOrStand : public view_listener_t
{
- bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
+ bool handleEvent(const LLSD& userdata)
{
bool new_value = false;
LLViewerObject* dest_object = LLSelectMgr::getInstance()->getSelection()->getPrimaryObject();
@@ -4976,13 +5494,11 @@ class LLObjectEnableSitOrStand : public view_listener_t
new_value = true;
}
}
- gMenuHolder->findControl(userdata["control"].asString())->setValue(new_value);
-
// Update label
std::string label;
std::string sit_text;
std::string stand_text;
- std::string param = userdata["data"].asString();
+ std::string param = userdata.asString();
std::string::size_type offset = param.find(",");
if (offset != param.npos)
{
@@ -5007,7 +5523,7 @@ class LLObjectEnableSitOrStand : public view_listener_t
}
gMenuHolder->childSetText("Object Sit", label);
- return true;
+ return new_value;
}
};
@@ -5026,29 +5542,6 @@ void dump_inventory(void*)
gInventory.dumpInventory();
}
-// forcibly unlock an object
-void handle_force_unlock(void*)
-{
- // First, make it public.
- LLSelectMgr::getInstance()->sendOwner(LLUUID::null, LLUUID::null, TRUE);
-
- // Second, lie to the viewer and mark it editable and unowned
-
- struct f : public LLSelectedObjectFunctor
- {
- virtual bool apply(LLViewerObject* object)
- {
- object->mFlags |= FLAGS_OBJECT_MOVE;
- object->mFlags |= FLAGS_OBJECT_MODIFY;
- object->mFlags |= FLAGS_OBJECT_COPY;
-
- object->mFlags &= ~FLAGS_OBJECT_ANY_OWNER;
- object->mFlags &= ~FLAGS_OBJECT_YOU_OWNER;
- return true;
- }
- } func;
- LLSelectMgr::getInstance()->getSelection()->applyToObjects(&func);
-}
void handle_dump_followcam(void*)
{
@@ -5065,84 +5558,22 @@ void handle_viewer_disable_message_log(void*)
gMessageSystem->stopLogging();
}
-// TomY TODO: Move!
class LLShowFloater : public view_listener_t
{
- bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
+ bool handleEvent(const LLSD& userdata)
{
std::string floater_name = userdata.asString();
- if (floater_name == "gestures")
- {
- LLFloaterGesture::toggleVisibility();
- }
- else if (floater_name == "appearance")
+ if (floater_name == "appearance")
{
- if (gAgent.areWearablesLoaded())
+ if (gAgentWearables.areWearablesLoaded())
{
gAgent.changeCameraToCustomizeAvatar();
}
}
- else if (floater_name == "friends")
- {
- LLFloaterMyFriends::toggleInstance(0);
- }
- else if (floater_name == "preferences")
- {
- LLFloaterPreference::show(NULL);
- }
else if (floater_name == "toolbar")
{
LLToolBar::toggle(NULL);
}
- else if (floater_name == "chat history")
- {
- LLFloaterChat::toggleInstance(LLSD());
- }
- else if (floater_name == "im")
- {
- LLFloaterChatterBox::toggleInstance(LLSD());
- }
- else if (floater_name == "inventory")
- {
- LLInventoryView::toggleVisibility(NULL);
- }
- else if (floater_name == "mute list")
- {
- LLFloaterMute::toggleInstance();
- }
- else if (floater_name == "camera controls")
- {
- LLFloaterCamera::toggleInstance();
- }
- else if (floater_name == "movement controls")
- {
- LLFloaterMove::toggleInstance();
- }
- else if (floater_name == "world map")
- {
- LLFloaterWorldMap::toggle(NULL);
- }
- else if (floater_name == "mini map")
- {
- LLFloaterMap::toggleInstance();
- }
- else if (floater_name == "stat bar")
- {
- LLFloaterStats::toggleInstance();
- }
- else if (floater_name == "my land")
- {
- LLFloaterLandHoldings::show(NULL);
- }
- else if (floater_name == "about land")
- {
- if (LLViewerParcelMgr::getInstance()->selectionEmpty())
- {
- LLViewerParcelMgr::getInstance()->selectParcelAt(gAgent.getPositionGlobal());
- }
-
- LLFloaterLand::showInstance();
- }
else if (floater_name == "buy land")
{
if (LLViewerParcelMgr::getInstance()->selectionEmpty())
@@ -5152,68 +5583,28 @@ class LLShowFloater : public view_listener_t
LLViewerParcelMgr::getInstance()->startBuyLand();
}
- else if (floater_name == "about region")
- {
- LLFloaterRegionInfo::showInstance();
- }
- else if (floater_name == "grid options")
- {
- LLFloaterBuildOptions::show(NULL);
- }
else if (floater_name == "script errors")
{
LLFloaterScriptDebug::show(LLUUID::null);
}
else if (floater_name == "help f1")
{
+ llinfos << "Spawning HTML help window" << llendl;
gViewerHtmlHelp.show();
}
- else if (floater_name == "help tutorial")
- {
- LLFloaterHUD::showHUD();
- }
else if (floater_name == "complaint reporter")
{
// Prevent menu from appearing in screen shot.
gMenuHolder->hideMenus();
LLFloaterReporter::showFromMenu(COMPLAINT_REPORT);
}
- else if (floater_name == "mean events")
- {
- if (!gNoRender)
- {
- LLFloaterBump::show(NULL);
- }
- }
- else if (floater_name == "lag meter")
- {
- LLFloaterLagMeter::showInstance();
- }
- else if (floater_name == "bug reporter")
- {
- // Prevent menu from appearing in screen shot.
- gMenuHolder->hideMenus();
- LLFloaterReporter::showFromMenu(BUG_REPORT);
- }
else if (floater_name == "buy currency")
{
LLFloaterBuyCurrency::buyCurrency();
}
- else if (floater_name == "about")
- {
- LLFloaterAbout::show(NULL);
- }
- else if (floater_name == "active speakers")
- {
- LLFloaterActiveSpeakers::toggleInstance(LLSD());
- }
- else if (floater_name == "beacons")
- {
- LLFloaterBeacons::toggleInstance(LLSD());
- }
- else if (floater_name == "perm prefs")
+ else
{
- LLFloaterPerms::toggleInstance(LLSD());
+ LLFloaterReg::toggleInstance(floater_name);
}
return true;
}
@@ -5221,62 +5612,19 @@ class LLShowFloater : public view_listener_t
class LLFloaterVisible : public view_listener_t
{
- bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
+ bool handleEvent(const LLSD& userdata)
{
- std::string control_name = userdata["control"].asString();
- std::string floater_name = userdata["data"].asString();
+ std::string floater_name = userdata.asString();
bool new_value = false;
- if (floater_name == "friends")
- {
- new_value = LLFloaterMyFriends::instanceVisible(0);
- }
- else if (floater_name == "communicate")
- {
- new_value = LLFloaterChatterBox::instanceVisible();
- }
- else if (floater_name == "toolbar")
+ if (floater_name == "toolbar")
{
new_value = LLToolBar::visible(NULL);
}
- else if (floater_name == "chat history")
- {
- new_value = LLFloaterChat::instanceVisible();
- }
- else if (floater_name == "im")
- {
- new_value = LLFloaterMyFriends::instanceVisible(0);
- }
- else if (floater_name == "mute list")
- {
- new_value = LLFloaterMute::instanceVisible();
- }
- else if (floater_name == "camera controls")
- {
- new_value = LLFloaterCamera::instanceVisible();
- }
- else if (floater_name == "movement controls")
- {
- new_value = LLFloaterMove::instanceVisible();
- }
- else if (floater_name == "stat bar")
- {
- new_value = LLFloaterStats::instanceVisible();
- }
- else if (floater_name == "active speakers")
- {
- new_value = LLFloaterActiveSpeakers::instanceVisible(LLSD());
- }
- else if (floater_name == "beacons")
- {
- new_value = LLFloaterBeacons::instanceVisible(LLSD());
- }
- else if (floater_name == "inventory")
+ else
{
- LLInventoryView* iv = LLInventoryView::getActiveInventory();
- new_value = (NULL != iv && TRUE == iv->getVisible());
+ new_value = LLFloaterReg::instanceVisible(floater_name);
}
- gMenuHolder->findControl(control_name)->setValue(new_value);
- return true;
+ return new_value;
}
};
@@ -5292,7 +5640,7 @@ bool callback_show_url(const LLSD& notification, const LLSD& response)
class LLPromptShowURL : public view_listener_t
{
- bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
+ bool handleEvent(const LLSD& userdata)
{
std::string param = userdata.asString();
std::string::size_type offset = param.find(",");
@@ -5332,7 +5680,7 @@ bool callback_show_file(const LLSD& notification, const LLSD& response)
class LLPromptShowFile : public view_listener_t
{
- bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
+ bool handleEvent(const LLSD& userdata)
{
std::string param = userdata.asString();
std::string::size_type offset = param.find(",");
@@ -5355,7 +5703,7 @@ class LLPromptShowFile : public view_listener_t
class LLShowAgentProfile : public view_listener_t
{
- bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
+ bool handleEvent(const LLSD& userdata)
{
LLUUID agent_id;
if (userdata.asString() == "agent")
@@ -5378,50 +5726,15 @@ class LLShowAgentProfile : public view_listener_t
LLVOAvatar* avatar = find_avatar_from_object(agent_id);
if (avatar)
{
- LLFloaterAvatarInfo::show( avatar->getID() );
+ LLAvatarActions::showProfile(avatar->getID());
}
return true;
}
};
-class LLShowAgentGroups : public view_listener_t
-{
- bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
- {
- LLFloaterMyFriends::toggleInstance(1);
- return true;
- }
-};
-
-void handle_focus(void *)
-{
- if (gDisconnected)
- {
- return;
- }
-
- if (gAgent.getFocusOnAvatar())
- {
- // zoom in if we're looking at the avatar
- gAgent.setFocusOnAvatar(FALSE, ANIMATE);
- gAgent.setFocusGlobal(LLToolPie::getInstance()->getPick());
- gAgent.cameraZoomIn(0.666f);
- }
- else
- {
- gAgent.setFocusGlobal(LLToolPie::getInstance()->getPick());
- }
-
- gViewerWindow->moveCursorToCenter();
-
- // Switch to camera toolset
-// LLToolMgr::getInstance()->setCurrentToolset(gCameraToolset);
- LLToolMgr::getInstance()->getCurrentToolset()->selectTool( LLToolCamera::getInstance() );
-}
-
class LLLandEdit : public view_listener_t
{
- bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
+ bool handleEvent(const LLSD& userdata)
{
if (gAgent.getFocusOnAvatar() && gSavedSettings.getBOOL("EditCameraMovement") )
{
@@ -5441,7 +5754,7 @@ class LLLandEdit : public view_listener_t
LLViewerParcelMgr::getInstance()->selectParcelAt( LLToolPie::getInstance()->getPick().mPosGlobal );
- gFloaterView->bringToFront( gFloaterTools );
+ LLFloaterReg::showInstance("build");
// Switch to land edit toolset
LLToolMgr::getInstance()->getCurrentToolset()->selectTool( LLToolSelectLand::getInstance() );
@@ -5451,15 +5764,14 @@ class LLLandEdit : public view_listener_t
class LLWorldEnableBuyLand : public view_listener_t
{
- bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
+ bool handleEvent(const LLSD& userdata)
{
bool new_value = LLViewerParcelMgr::getInstance()->canAgentBuyParcel(
LLViewerParcelMgr::getInstance()->selectionEmpty()
? LLViewerParcelMgr::getInstance()->getAgentParcel()
: LLViewerParcelMgr::getInstance()->getParcelSelection()->getParcel(),
false);
- gMenuHolder->findControl(userdata["control"].asString())->setValue(new_value);
- return true;
+ return new_value;
}
};
@@ -5470,26 +5782,6 @@ BOOL enable_buy_land(void*)
}
-void handle_move(void*)
-{
- if (gAgent.getFocusOnAvatar())
- {
- // zoom in if we're looking at the avatar
- gAgent.setFocusOnAvatar(FALSE, ANIMATE);
- gAgent.setFocusGlobal(LLToolPie::getInstance()->getPick());
-
- gAgent.cameraZoomIn(0.666f);
- }
- else
- {
- gAgent.setFocusGlobal(LLToolPie::getInstance()->getPick());
- }
-
- gViewerWindow->moveCursorToCenter();
-
- LLToolMgr::getInstance()->setCurrentToolset(gBasicToolset);
- LLToolMgr::getInstance()->getCurrentToolset()->selectTool( LLToolGrab::getInstance() );
-}
class LLObjectAttachToAvatar : public view_listener_t
{
@@ -5497,7 +5789,7 @@ public:
static void setObjectSelection(LLObjectSelectionHandle selection) { sObjectSelection = selection; }
private:
- bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
+ bool handleEvent(const LLSD& userdata)
{
setObjectSelection(LLSelectMgr::getInstance()->getSelection());
LLViewerObject* selectedObject = sObjectSelection->getFirstRootObject();
@@ -5580,7 +5872,7 @@ void confirm_replace_attachment(S32 option, void* user_data)
class LLAttachmentDrop : public view_listener_t
{
- bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
+ bool handleEvent(const LLSD& userdata)
{
// Called when the user clicked on an object attached to them
// and selected "Drop".
@@ -5624,11 +5916,13 @@ class LLAttachmentDrop : public view_listener_t
};
// called from avatar pie menu
-void handle_detach_from_avatar(void* user_data)
+class LLAttachmentDetachFromPoint : public view_listener_t
+{
+ bool handleEvent(const LLSD& user_data)
{
- LLViewerJointAttachment *attachment = (LLViewerJointAttachment *)user_data;
+ LLViewerJointAttachment *attachment = get_if_there(gAgent.getAvatarObject()->mAttachmentPoints, user_data.asInteger(), (LLViewerJointAttachment*)NULL);
- LLViewerObject* attached_object = attachment->getObject();
+ LLViewerObject* attached_object = attachment ? attachment->getObject() : NULL;
if (attached_object)
{
@@ -5641,31 +5935,20 @@ void handle_detach_from_avatar(void* user_data)
gMessageSystem->addU32Fast(_PREHASH_ObjectLocalID, attached_object->getLocalID());
gMessageSystem->sendReliable( gAgent.getRegionHost() );
}
+ return true;
}
+};
-void attach_label(std::string& label, void* user_data)
+static bool onEnableAttachmentLabel(LLUICtrl* ctrl, const LLSD& data)
{
- LLViewerJointAttachment* attachmentp = (LLViewerJointAttachment*)user_data;
- if (attachmentp)
+ std::string label;
+ LLMenuItemGL* menu = dynamic_cast<LLMenuItemGL*>(ctrl);
+ if (menu)
{
- label = attachmentp->getName();
- if (attachmentp->getObject())
- {
- LLViewerInventoryItem* itemp = gInventory.getItem(attachmentp->getItemID());
- if (itemp)
- {
- label += std::string(" (") + itemp->getName() + std::string(")");
- }
- }
- }
-}
-
-void detach_label(std::string& label, void* user_data)
-{
- LLViewerJointAttachment* attachmentp = (LLViewerJointAttachment*)user_data;
+ LLViewerJointAttachment *attachmentp = get_if_there(gAgent.getAvatarObject()->mAttachmentPoints, data["index"].asInteger(), (LLViewerJointAttachment*)NULL);
if (attachmentp)
{
- label = attachmentp->getName();
+ label = data["label"].asString();
if (attachmentp->getObject())
{
LLViewerInventoryItem* itemp = gInventory.getItem(attachmentp->getItemID());
@@ -5675,12 +5958,15 @@ void detach_label(std::string& label, void* user_data)
}
}
}
+ menu->setLabel(label);
+}
+ return true;
}
class LLAttachmentDetach : public view_listener_t
{
- bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
+ bool handleEvent(const LLSD& userdata)
{
// Called when the user clicked on an object attached to them
// and selected "Detach".
@@ -5749,7 +6035,7 @@ protected:
// You can only drop items on parcels where you can build.
class LLAttachmentEnableDrop : public view_listener_t
{
- bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
+ bool handleEvent(const LLSD& userdata)
{
BOOL can_build = gAgent.isGodlike() || (LLViewerParcelMgr::getInstance()->agentCanBuild());
@@ -5796,14 +6082,13 @@ class LLAttachmentEnableDrop : public view_listener_t
}
//now check to make sure that the item is actually in the inventory before we enable dropping it
- bool new_value = enable_detach(NULL) && can_build && item;
+ bool new_value = enable_detach() && can_build && item;
- gMenuHolder->findControl(userdata["control"].asString())->setValue(new_value);
- return true;
+ return new_value;
}
};
-BOOL enable_detach(void*)
+BOOL enable_detach(const LLSD&)
{
LLViewerObject* object = LLSelectMgr::getInstance()->getSelection()->getPrimaryObject();
if (!object) return FALSE;
@@ -5827,18 +6112,16 @@ BOOL enable_detach(void*)
class LLAttachmentEnableDetach : public view_listener_t
{
- bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
+ bool handleEvent(const LLSD& userdata)
{
- bool new_value = enable_detach(NULL);
- gMenuHolder->findControl(userdata["control"].asString())->setValue(new_value);
- return true;
+ bool new_value = enable_detach();
+ return new_value;
}
};
// Used to tell if the selected object can be attached to your avatar.
-BOOL object_selected_and_point_valid(void *user_data)
+BOOL object_selected_and_point_valid(const LLSD&)
{
- //LLViewerJointAttachment *attachment = (LLViewerJointAttachment *)user_data;
LLObjectSelectionHandle selection = LLSelectMgr::getInstance()->getSelection();
for (LLObjectSelection::root_iterator iter = selection->root_begin();
iter != selection->root_end(); iter++)
@@ -5867,7 +6150,7 @@ BOOL object_selected_and_point_valid(void *user_data)
BOOL object_is_wearable()
{
- if (!object_selected_and_point_valid(NULL))
+ if (!object_selected_and_point_valid(LLSD()))
{
return FALSE;
}
@@ -5892,25 +6175,29 @@ BOOL object_is_wearable()
// Also for seeing if object can be attached. See above.
class LLObjectEnableWear : public view_listener_t
{
- bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
+ bool handleEvent(const LLSD& userdata)
{
- bool is_wearable = object_selected_and_point_valid(NULL);
- gMenuHolder->findControl(userdata["control"].asString())->setValue(is_wearable);
- return TRUE;
+ return object_selected_and_point_valid(LLSD());
}
};
-
-BOOL object_attached(void *user_data)
+class LLAttachmentPointFilled : public view_listener_t
{
- LLViewerJointAttachment *attachment = (LLViewerJointAttachment *)user_data;
-
- return attachment->getObject() != NULL;
+ bool handleEvent(const LLSD& user_data)
+ {
+ bool enable = false;
+ LLVOAvatar::attachment_map_t::iterator found_it = gAgent.getAvatarObject()->mAttachmentPoints.find(user_data.asInteger());
+ if (found_it != gAgent.getAvatarObject()->mAttachmentPoints.end())
+{
+ enable = found_it->second->getObject() != NULL;
+ }
+ return enable;
}
+};
class LLAvatarSendIM : public view_listener_t
{
- bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
+ bool handleEvent(const LLSD& userdata)
{
LLVOAvatar* avatar = find_avatar_from_object( LLSelectMgr::getInstance()->getSelection()->getPrimaryObject() );
if(avatar)
@@ -5925,7 +6212,6 @@ class LLAvatarSendIM : public view_listener_t
name.append( last->getString() );
}
- gIMMgr->setFloaterOpen(TRUE);
//EInstantMessage type = have_agent_callingcard(gLastHitObjectID)
// ? IM_SESSION_ADD : IM_SESSION_CARDLESS_START;
gIMMgr->addSession(name,
@@ -5936,16 +6222,6 @@ class LLAvatarSendIM : public view_listener_t
}
};
-
-void handle_activate(void*)
-{
-}
-
-BOOL enable_activate(void*)
-{
- return FALSE;
-}
-
namespace
{
struct QueueObjects : public LLSelectedObjectFunctor
@@ -5972,7 +6248,7 @@ namespace
};
}
-void queue_actions(LLFloaterScriptQueue* q, const std::string& noscriptmsg, const std::string& nomodmsg)
+void queue_actions(LLFloaterScriptQueue* q, const std::string& msg)
{
QueueObjects func(q);
LLSelectMgr *mgr = LLSelectMgr::getInstance();
@@ -5982,10 +6258,12 @@ void queue_actions(LLFloaterScriptQueue* q, const std::string& noscriptmsg, cons
{
if ( !func.scripted )
{
+ std::string noscriptmsg = std::string("Cannot") + msg + "SelectObjectsNoScripts";
LLNotifications::instance().add(noscriptmsg);
}
else if ( !func.modifiable )
{
+ std::string nomodmsg = std::string("Cannot") + msg + "SelectObjectsNoPermission";
LLNotifications::instance().add(nomodmsg);
}
else
@@ -6002,62 +6280,51 @@ void queue_actions(LLFloaterScriptQueue* q, const std::string& noscriptmsg, cons
}
}
-void handle_compile_queue(std::string to_lang)
-{
- LLFloaterCompileQueue* queue;
- if (to_lang == "mono")
- {
- queue = LLFloaterCompileQueue::create(TRUE);
- }
- else
- {
- queue = LLFloaterCompileQueue::create(FALSE);
- }
- queue_actions(queue, "CannotRecompileSelectObjectsNoScripts", "CannotRecompileSelectObjectsNoPermission");
-}
-
-void handle_reset_selection(void)
-{
- LLFloaterResetQueue* queue = LLFloaterResetQueue::create();
- queue_actions(queue, "CannotResetSelectObjectsNoScripts", "CannotResetSelectObjectsNoPermission");
-}
-
-void handle_set_run_selection(void)
-{
- LLFloaterRunQueue* queue = LLFloaterRunQueue::create();
- queue_actions(queue, "CannotSetRunningSelectObjectsNoScripts", "CannotSerRunningSelectObjectsNoPermission");
-}
-
-void handle_set_not_run_selection(void)
-{
- LLFloaterNotRunQueue* queue = LLFloaterNotRunQueue::create();
- queue_actions(queue, "CannotSetRunningNotSelectObjectsNoScripts", "CannotSerRunningNotSelectObjectsNoPermission");
-}
-
class LLToolsSelectedScriptAction : public view_listener_t
{
- bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
+ bool handleEvent(const LLSD& userdata)
{
std::string action = userdata.asString();
+ bool mono = false;
+ std::string msg, name;
if (action == "compile mono")
{
- handle_compile_queue("mono");
+ name = "compile_queue";
+ mono = true;
+ msg = "Recompile";
}
if (action == "compile lsl")
{
- handle_compile_queue("lsl");
+ name = "compile_queue";
+ msg = "Recompile";
}
else if (action == "reset")
{
- handle_reset_selection();
+ name = "reset_queue";
+ msg = "Reset";
}
else if (action == "start")
{
- handle_set_run_selection();
+ name = "start_queue";
+ msg = "Running";
}
else if (action == "stop")
{
- handle_set_not_run_selection();
+ name = "stop_queue";
+ msg = "RunningNot";
+ }
+ LLUUID id; id.generate();
+
+ LLFloaterScriptQueue* queue =LLFloaterReg::getTypedInstance<LLFloaterScriptQueue>(name, LLSD(id));
+ if (queue)
+ {
+ queue->setMono(mono);
+ queue_actions(queue, msg);
+ }
+ else
+ {
+ llwarns << "Failed to generate LLFloaterScriptQueue with action: " << action << llendl;
+ delete queue;
}
return true;
}
@@ -6084,7 +6351,7 @@ void handle_selected_texture_info(void*)
{
if (!node->isTESelected(i)) continue;
- LLViewerImage* img = node->getObject()->getTEImage(i);
+ LLViewerTexture* img = node->getObject()->getTEImage(i);
LLUUID image_id = img->getID();
faces_per_texture[image_id].push_back(i);
}
@@ -6094,7 +6361,7 @@ void handle_selected_texture_info(void*)
{
LLUUID image_id = it->first;
U8 te = it->second[0];
- LLViewerImage* img = node->getObject()->getTEImage(te);
+ LLViewerTexture* img = node->getObject()->getTEImage(te);
S32 height = img->getHeight();
S32 width = img->getWidth();
S32 components = img->getComponents();
@@ -6112,11 +6379,6 @@ void handle_selected_texture_info(void*)
}
}
-void handle_dump_image_list(void*)
-{
- gImageList.dump();
-}
-
void handle_test_male(void*)
{
wear_outfit_by_name("Male Shape & Outfit");
@@ -6167,107 +6429,76 @@ void handle_dump_attachments(void*)
}
}
-//---------------------------------------------------------------------
-// Callbacks for enabling/disabling items
-//---------------------------------------------------------------------
-
-BOOL menu_ui_enabled(void *user_data)
-{
- BOOL high_res = gSavedSettings.getBOOL( "HighResSnapshot" );
- return !high_res;
-}
-
-// TomY TODO DEPRECATE & REMOVE
-void menu_toggle_control( void* user_data )
-{
- BOOL checked = gSavedSettings.getBOOL( static_cast<char*>(user_data) );
- if (std::string(static_cast<char*>(user_data)) == "HighResSnapshot" && !checked)
- {
- // High Res Snapshot active, must uncheck RenderUIInSnapshot
- gSavedSettings.setBOOL( "RenderUIInSnapshot", FALSE );
- }
- gSavedSettings.setBOOL( static_cast<char*>(user_data), !checked );
-}
-
// these are used in the gl menus to set control values.
class LLToggleControl : public view_listener_t
{
- bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
+ bool handleEvent(const LLSD& userdata)
{
std::string control_name = userdata.asString();
BOOL checked = gSavedSettings.getBOOL( control_name );
- if (control_name == "HighResSnapshot" && !checked)
- {
- // High Res Snapshot active, must uncheck RenderUIInSnapshot
- gSavedSettings.setBOOL( "RenderUIInSnapshot", FALSE );
- }
gSavedSettings.setBOOL( control_name, !checked );
return true;
}
};
-BOOL menu_check_control( void* user_data)
+class LLCheckControl : public view_listener_t
{
- return gSavedSettings.getBOOL((char*)user_data);
+ bool handleEvent( const LLSD& userdata)
+ {
+ std::string callback_data = userdata.asString();
+ bool new_value = gSavedSettings.getBOOL(callback_data);
+ return new_value;
}
-//
-void menu_toggle_variable( void* user_data )
-{
- BOOL checked = *(BOOL*)user_data;
- *(BOOL*)user_data = !checked;
-}
+};
-BOOL menu_check_variable( void* user_data)
+void menu_toggle_attached_lights(void* user_data)
{
- return *(BOOL*)user_data;
+ LLPipeline::sRenderAttachedLights = gSavedSettings.getBOOL("RenderAttachedLights");
}
-
-BOOL enable_land_selected( void* )
+void menu_toggle_attached_particles(void* user_data)
{
- return !(LLViewerParcelMgr::getInstance()->selectionEmpty());
+ LLPipeline::sRenderAttachedParticles = gSavedSettings.getBOOL("RenderAttachedParticles");
}
-void menu_toggle_attached_lights(void* user_data)
+class LLAdvancedHandleAttchedLightParticles: public view_listener_t
{
- menu_toggle_control(user_data);
- LLPipeline::sRenderAttachedLights = gSavedSettings.getBOOL("RenderAttachedLights");
+ bool handleEvent(const LLSD& userdata)
+ {
+ std::string control_name = userdata.asString();
+ if (control_name == "RenderAttachedLights")
+{
+ menu_toggle_attached_lights(NULL);
}
-
-void menu_toggle_attached_particles(void* user_data)
+ else if (control_name == "RenderAttachedParticles")
{
- menu_toggle_control(user_data);
- LLPipeline::sRenderAttachedParticles = gSavedSettings.getBOOL("RenderAttachedParticles");
+ menu_toggle_attached_particles(NULL);
+}
+ return true;
}
+};
class LLSomethingSelected : public view_listener_t
{
- bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
+ bool handleEvent(const LLSD& userdata)
{
bool new_value = !(LLSelectMgr::getInstance()->getSelection()->isEmpty());
- gMenuHolder->findControl(userdata["control"].asString())->setValue(new_value);
- return true;
+ return new_value;
}
};
class LLSomethingSelectedNoHUD : public view_listener_t
{
- bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
+ bool handleEvent(const LLSD& userdata)
{
LLObjectSelectionHandle selection = LLSelectMgr::getInstance()->getSelection();
bool new_value = !(selection->isEmpty()) && !(selection->getSelectType() == SELECT_TYPE_HUD);
- gMenuHolder->findControl(userdata["control"].asString())->setValue(new_value);
- return true;
+ return new_value;
}
};
-BOOL enable_more_than_one_selected(void* )
-{
- return (LLSelectMgr::getInstance()->getSelection()->getObjectCount() > 1);
-}
-
static bool is_editable_selected()
{
return (LLSelectMgr::getInstance()->getSelection()->getFirstEditableObject() != NULL);
@@ -6275,106 +6506,62 @@ static bool is_editable_selected()
class LLEditableSelected : public view_listener_t
{
- bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
+ bool handleEvent(const LLSD& userdata)
{
- gMenuHolder->findControl(userdata["control"].asString())->setValue(is_editable_selected());
- return true;
+ return is_editable_selected();
}
};
class LLEditableSelectedMono : public view_listener_t
{
- bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
+ bool handleEvent(const LLSD& userdata)
{
+ bool new_value = false;
LLViewerRegion* region = gAgent.getRegion();
- if(region && gMenuHolder && gMenuHolder->findControl(userdata["control"].asString()))
+ if(region && gMenuHolder)
{
bool have_cap = (! region->getCapability("UpdateScriptTask").empty());
- bool selected = is_editable_selected() && have_cap;
- gMenuHolder->findControl(userdata["control"].asString())->setValue(selected);
- return true;
+ new_value = is_editable_selected() && have_cap;
}
- return false;
+ return new_value;
}
};
class LLToolsEnableTakeCopy : public view_listener_t
{
- bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
+ bool handleEvent(const LLSD& userdata)
{
bool all_valid = false;
if (LLSelectMgr::getInstance())
{
if (!LLSelectMgr::getInstance()->getSelection()->isEmpty())
{
- all_valid = true;
+ all_valid = true;
#ifndef HACKED_GODLIKE_VIEWER
# ifdef TOGGLE_HACKED_GODLIKE_VIEWER
- if (LLViewerLogin::getInstance()->isInProductionGrid()
- || !gAgent.isGodlike())
+ if (LLViewerLogin::getInstance()->isInProductionGrid()
+ || !gAgent.isGodlike())
# endif
+ {
+ struct f : public LLSelectedObjectFunctor
{
- struct f : public LLSelectedObjectFunctor
+ virtual bool apply(LLViewerObject* obj)
{
- virtual bool apply(LLViewerObject* obj)
- {
- return (!obj->permCopy() || obj->isAttachment());
- }
- } func;
- const bool firstonly = true;
- bool any_invalid = LLSelectMgr::getInstance()->getSelection()->applyToRootObjects(&func, firstonly);
- all_valid = !any_invalid;
- }
-#endif // HACKED_GODLIKE_VIEWER
+ return (!obj->permCopy() || obj->isAttachment());
+ }
+ } func;
+ const bool firstonly = true;
+ bool any_invalid = LLSelectMgr::getInstance()->getSelection()->applyToRootObjects(&func, firstonly);
+ all_valid = !any_invalid;
}
+#endif // HACKED_GODLIKE_VIEWER
+ }
}
- gMenuHolder->findControl(userdata["control"].asString())->setValue(all_valid);
- return true;
+ return all_valid;
}
};
-BOOL enable_selection_you_own_all(void*)
-{
- if (LLSelectMgr::getInstance())
- {
- struct f : public LLSelectedObjectFunctor
- {
- virtual bool apply(LLViewerObject* obj)
- {
- return (!obj->permYouOwner());
- }
- } func;
- const bool firstonly = true;
- bool no_perms = LLSelectMgr::getInstance()->getSelection()->applyToRootObjects(&func, firstonly);
- if (no_perms)
- {
- return FALSE;
- }
- }
- return TRUE;
-}
-
-BOOL enable_selection_you_own_one(void*)
-{
- if (LLSelectMgr::getInstance())
- {
- struct f : public LLSelectedObjectFunctor
- {
- virtual bool apply(LLViewerObject* obj)
- {
- return (obj->permYouOwner());
- }
- } func;
- const bool firstonly = true;
- bool any_perms = LLSelectMgr::getInstance()->getSelection()->applyToRootObjects(&func, firstonly);
- if (!any_perms)
- {
- return FALSE;
- }
- }
- return TRUE;
-}
class LLHasAsset : public LLInventoryCollectFunctor
{
@@ -6436,6 +6623,15 @@ BOOL enable_save_into_inventory(void*)
return FALSE;
}
+class LLToolsEnableSaveToInventory : public view_listener_t
+{
+ bool handleEvent(const LLSD& userdata)
+ {
+ bool new_value = enable_save_into_inventory(NULL);
+ return new_value;
+ }
+};
+
BOOL enable_save_into_task_inventory(void*)
{
LLSelectNode* node = LLSelectMgr::getInstance()->getSelection()->getFirstRootNode();
@@ -6453,101 +6649,63 @@ BOOL enable_save_into_task_inventory(void*)
class LLToolsEnableSaveToObjectInventory : public view_listener_t
{
- bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
+ bool handleEvent(const LLSD& userdata)
{
bool new_value = enable_save_into_task_inventory(NULL);
- gMenuHolder->findControl(userdata["control"].asString())->setValue(new_value);
- return true;
+ return new_value;
}
};
-BOOL enable_not_thirdperson(void*)
-{
- return !gAgent.cameraThirdPerson();
-}
-
-
-// BOOL enable_export_selected(void *)
-// {
-// if (LLSelectMgr::getInstance()->getSelection()->isEmpty())
-// {
-// return FALSE;
-// }
-// if (!gExporterRequestID.isNull())
-// {
-// return FALSE;
-// }
-// if (!LLUploadDialog::modalUploadIsFinished())
-// {
-// return FALSE;
-// }
-// return TRUE;
-// }
class LLViewEnableMouselook : public view_listener_t
{
- bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
+ bool handleEvent(const LLSD& userdata)
{
// You can't go directly from customize avatar to mouselook.
// TODO: write code with appropriate dialogs to handle this transition.
bool new_value = (CAMERA_MODE_CUSTOMIZE_AVATAR != gAgent.getCameraMode() && !gSavedSettings.getBOOL("FreezeTime"));
- gMenuHolder->findControl(userdata["control"].asString())->setValue(new_value);
- return true;
+ return new_value;
}
};
class LLToolsEnableToolNotPie : public view_listener_t
{
- bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
+ bool handleEvent(const LLSD& userdata)
{
bool new_value = ( LLToolMgr::getInstance()->getBaseTool() != LLToolPie::getInstance() );
- gMenuHolder->findControl(userdata["control"].asString())->setValue(new_value);
- return true;
+ return new_value;
}
};
class LLWorldEnableCreateLandmark : public view_listener_t
{
- bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
+ bool handleEvent(const LLSD& userdata)
{
- bool new_value = can_create_landmark();
-
- gMenuHolder->findControl(userdata["control"].asString())->setValue(new_value);
-
- return true;
+ return !LLLandmarkActions::landmarkAlreadyExists();
}
};
class LLWorldEnableSetHomeLocation : public view_listener_t
{
- bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
+ bool handleEvent(const LLSD& userdata)
{
bool new_value = gAgent.isGodlike() ||
(gAgent.getRegion() && gAgent.getRegion()->getAllowSetHome());
- gMenuHolder->findControl(userdata["control"].asString())->setValue(new_value);
- return true;
+ return new_value;
}
};
class LLWorldEnableTeleportHome : public view_listener_t
{
- bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
+ bool handleEvent(const LLSD& userdata)
{
LLViewerRegion* regionp = gAgent.getRegion();
bool agent_on_prelude = (regionp && regionp->isPrelude());
bool enable_teleport_home = gAgent.isGodlike() || !agent_on_prelude;
- gMenuHolder->findControl(userdata["control"].asString())->setValue(enable_teleport_home);
- return true;
+ return enable_teleport_home;
}
};
-BOOL enable_region_owner(void*)
-{
- if(gAgent.getRegion() && gAgent.getRegion()->getOwner() == gAgent.getID())
- return TRUE;
- return enable_god_customer_service(NULL);
-}
-
BOOL enable_god_full(void*)
{
return gAgent.getGodLevel() >= GOD_FULL;
@@ -6568,18 +6726,6 @@ BOOL enable_god_basic(void*)
return gAgent.getGodLevel() > GOD_NOT;
}
-#if 0 // 1.9.2
-void toggle_vertex_shaders(void *)
-{
- BOOL use_shaders = gPipeline.getUseVertexShaders();
- gPipeline.setUseVertexShaders(use_shaders);
-}
-
-BOOL check_vertex_shaders(void *)
-{
- return gPipeline.getUseVertexShaders();
-}
-#endif
void toggle_show_xui_names(void *)
{
@@ -6594,18 +6740,9 @@ BOOL check_show_xui_names(void *)
return gSavedSettings.getBOOL("ShowXUINames");
}
-
-
-void toggle_cull_small(void *)
-{
-// gPipeline.mCullBySize = !gPipeline.mCullBySize;
-//
-// gSavedSettings.setBOOL("RenderCullBySize", gPipeline.mCullBySize);
-}
-
class LLToolsSelectOnlyMyObjects : public view_listener_t
{
- bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
+ bool handleEvent(const LLSD& userdata)
{
BOOL cur_val = gSavedSettings.getBOOL("SelectOwnedOnly");
@@ -6617,7 +6754,7 @@ class LLToolsSelectOnlyMyObjects : public view_listener_t
class LLToolsSelectOnlyMovableObjects : public view_listener_t
{
- bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
+ bool handleEvent(const LLSD& userdata)
{
BOOL cur_val = gSavedSettings.getBOOL("SelectMovableOnly");
@@ -6629,7 +6766,7 @@ class LLToolsSelectOnlyMovableObjects : public view_listener_t
class LLToolsSelectBySurrounding : public view_listener_t
{
- bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
+ bool handleEvent(const LLSD& userdata)
{
LLSelectMgr::sRectSelectInclusive = !LLSelectMgr::sRectSelectInclusive;
@@ -6640,7 +6777,7 @@ class LLToolsSelectBySurrounding : public view_listener_t
class LLToolsShowHiddenSelection : public view_listener_t
{
- bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
+ bool handleEvent(const LLSD& userdata)
{
// TomY TODO Merge these
LLSelectMgr::sRenderHiddenSelections = !LLSelectMgr::sRenderHiddenSelections;
@@ -6652,7 +6789,7 @@ class LLToolsShowHiddenSelection : public view_listener_t
class LLToolsShowSelectionLightRadius : public view_listener_t
{
- bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
+ bool handleEvent(const LLSD& userdata)
{
// TomY TODO merge these
LLSelectMgr::sRenderLightRadius = !LLSelectMgr::sRenderLightRadius;
@@ -6664,7 +6801,7 @@ class LLToolsShowSelectionLightRadius : public view_listener_t
class LLToolsEditLinkedParts : public view_listener_t
{
- bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
+ bool handleEvent(const LLSD& userdata)
{
BOOL select_individuals = gSavedSettings.getBOOL("EditLinkedParts");
if (select_individuals)
@@ -6679,40 +6816,14 @@ class LLToolsEditLinkedParts : public view_listener_t
}
};
-void reload_personal_settings_overrides(void *)
-{
- llinfos << "Loading overrides from " << gDirUtilp->getExpandedFilename(LL_PATH_PER_SL_ACCOUNT,"overrides.xml") << llendl;
-
- gSavedSettings.loadFromFile(gDirUtilp->getExpandedFilename(LL_PATH_PER_SL_ACCOUNT,"overrides.xml"));
-}
-
void reload_vertex_shader(void *)
{
//THIS WOULD BE AN AWESOME PLACE TO RELOAD SHADERS... just a thought - DaveP
}
-void slow_mo_animations(void*)
-{
- static BOOL slow_mo = FALSE;
- if (slow_mo)
- {
- gAgent.getAvatarObject()->setAnimTimeFactor(1.f);
- slow_mo = FALSE;
- }
- else
- {
- gAgent.getAvatarObject()->setAnimTimeFactor(0.2f);
- slow_mo = TRUE;
- }
-}
-
void handle_dump_avatar_local_textures(void*)
{
- LLVOAvatar* avatar = gAgent.getAvatarObject();
- if( avatar )
- {
- avatar->dumpLocalTextures();
- }
+ gAgent.getAvatarObject()->dumpLocalTextures();
}
void handle_debug_avatar_textures(void*)
@@ -6720,14 +6831,14 @@ void handle_debug_avatar_textures(void*)
LLViewerObject* objectp = LLSelectMgr::getInstance()->getSelection()->getPrimaryObject();
if (objectp)
{
- LLFloaterAvatarTextures::show(objectp->getID());
+ LLFloaterReg::showInstance( "avatar_tetures", LLSD(objectp->getID()) );
}
}
void handle_grab_texture(void* data)
{
ETextureIndex index = (ETextureIndex)((intptr_t)data);
- LLVOAvatar* avatar = gAgent.getAvatarObject();
+ const LLVOAvatarSelf* avatar = gAgent.getAvatarObject();
if ( avatar )
{
const LLUUID& asset_id = avatar->grabLocalTexture(index);
@@ -6737,32 +6848,14 @@ void handle_grab_texture(void* data)
LLUUID folder_id(gInventory.findCategoryUUIDForType(asset_type));
if(folder_id.notNull())
{
- std::string name = "Baked ";
- switch (index)
+ std::string name = "Unknown";
+ const LLVOAvatarDictionary::TextureEntry *texture_dict = LLVOAvatarDictionary::getInstance()->getTexture(index);
+ if (texture_dict->mIsBakedTexture)
{
- case TEX_EYES_BAKED:
- name.append("Iris");
- break;
- case TEX_HEAD_BAKED:
- name.append("Head");
- break;
- case TEX_UPPER_BAKED:
- name.append("Upper Body");
- break;
- case TEX_LOWER_BAKED:
- name.append("Lower Body");
- break;
- case TEX_SKIRT_BAKED:
- name.append("Skirt");
- break;
- case TEX_HAIR_BAKED:
- name.append("Hair");
- break;
- default:
- name.append("Unknown");
- break;
+ EBakedTextureIndex baked_index = texture_dict->mBakedTextureIndex;
+ name = "Baked " + LLVOAvatarDictionary::getInstance()->getBakedTexture(baked_index)->mNameCapitalized;
}
- name.append(" Texture");
+ name += " Texture";
LLUUID item_id;
item_id.generate();
@@ -6795,17 +6888,17 @@ void handle_grab_texture(void* data)
gInventory.updateItem(item);
gInventory.notifyObservers();
- LLInventoryView* view = LLInventoryView::getActiveInventory();
+ LLFloaterInventory* view = LLFloaterInventory::getActiveInventory();
// Show the preview panel for textures to let
// user know that the image is now in inventory.
if(view)
{
- LLUICtrl* focus_ctrl = gFocusMgr.getKeyboardFocus();
+ LLFocusableElement* focus_ctrl = gFocusMgr.getKeyboardFocus();
view->getPanel()->setSelection(item_id, TAKE_FOCUS_NO);
view->getPanel()->openSelected();
- //LLInventoryView::dumpSelectionInformation((void*)view);
+ //LLFloaterInventory::dumpSelectionInformation((void*)view);
// restore keyboard focus
gFocusMgr.setKeyboardFocus(focus_ctrl);
}
@@ -6820,7 +6913,7 @@ void handle_grab_texture(void* data)
BOOL enable_grab_texture(void* data)
{
ETextureIndex index = (ETextureIndex)((intptr_t)data);
- LLVOAvatar* avatar = gAgent.getAvatarObject();
+ const LLVOAvatarSelf* avatar = gAgent.getAvatarObject();
if ( avatar )
{
return avatar->canGrabLocalTexture(index);
@@ -6842,8 +6935,7 @@ LLVOAvatar* find_avatar_from_object( LLViewerObject* object )
}
while( object && !object->isAvatar() );
}
- else
- if( !object->isAvatar() )
+ else if( !object->isAvatar() )
{
object = NULL;
}
@@ -6898,7 +6990,7 @@ void force_error_driver_crash(void *)
class LLToolsUseSelectionForGrid : public view_listener_t
{
- bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
+ bool handleEvent(const LLSD& userdata)
{
LLSelectMgr::getInstance()->clearGridObjects();
struct f : public LLSelectedObjectFunctor
@@ -6931,10 +7023,6 @@ void handle_test_load_url(void*)
// LLViewerMenuHolderGL
//
-LLViewerMenuHolderGL::LLViewerMenuHolderGL() : LLMenuHolderGL()
-{
-}
-
BOOL LLViewerMenuHolderGL::hideMenus()
{
BOOL handled = LLMenuHolderGL::hideMenus();
@@ -6998,20 +7086,14 @@ void handle_load_from_xml(void*)
if (picker.getOpenFile(LLFilePicker::FFLOAD_XML))
{
std::string filename = picker.getFirstFile();
- LLFloater* floater = new LLFloater("sample_floater");
- LLUICtrlFactory::getInstance()->buildFloater(floater, filename);
+ LLFloater* floater = new LLFloater(LLSD());
+ LLUICtrlFactory::getInstance()->buildFloater(floater, filename, NULL);
}
}
void handle_web_browser_test(void*)
{
- const bool open_links_externally = false;
- const bool open_app_slurls = true;
- LLFloaterHtml::getInstance()->show(
- "http://secondlife.com/app/search/slurls.html",
- "Web Browser Test",
- open_links_externally,
- open_app_slurls);
+ LLWeb::loadURL("http://secondlife.com/app/search/slurls.html");
}
void handle_buy_currency_test(void*)
@@ -7025,7 +7107,7 @@ void handle_buy_currency_test(void*)
// *TODO: Replace with call to LLUI::getLanguage() after windows-setup
// branch merges in. JC
- std::string language = "en-us";
+ std::string language = "en";
language = gSavedSettings.getString("Language");
if (language.empty() || language == "default")
{
@@ -7037,7 +7119,7 @@ void handle_buy_currency_test(void*)
}
if (language.empty() || language == "default")
{
- language = "en-us";
+ language = "en";
}
replace["[LANGUAGE]"] = language;
@@ -7045,15 +7127,12 @@ void handle_buy_currency_test(void*)
llinfos << "buy currency url " << url << llendl;
- LLFloaterHtmlCurrency* floater = LLFloaterHtmlCurrency::showInstance(url);
- // Needed so we can use secondlife:///app/floater/self/close SLURLs
- floater->setTrusted(true);
- floater->center();
+ LLFloaterReg::showInstance("buy_currency_html", LLSD(url));
}
void handle_rebake_textures(void*)
{
- LLVOAvatar* avatar = gAgent.getAvatarObject();
+ LLVOAvatarSelf* avatar = gAgent.getAvatarObject();
if (!avatar) return;
// Slam pending upload count to "unstick" things
@@ -7076,7 +7155,7 @@ BOOL get_visibility(void* user_data)
// TomY TODO: Get rid of these?
class LLViewShowHoverTips : public view_listener_t
{
- bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
+ bool handleEvent(const LLSD& userdata)
{
LLHoverView::sShowHoverTips = !LLHoverView::sShowHoverTips;
return true;
@@ -7085,18 +7164,17 @@ class LLViewShowHoverTips : public view_listener_t
class LLViewCheckShowHoverTips : public view_listener_t
{
- bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
+ bool handleEvent(const LLSD& userdata)
{
bool new_value = LLHoverView::sShowHoverTips;
- gMenuHolder->findControl(userdata["control"].asString())->setValue(new_value);
- return true;
+ return new_value;
}
};
// TomY TODO: Get rid of these?
class LLViewHighlightTransparent : public view_listener_t
{
- bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
+ bool handleEvent(const LLSD& userdata)
{
LLDrawPoolAlpha::sShowDebugAlpha = !LLDrawPoolAlpha::sShowDebugAlpha;
return true;
@@ -7105,17 +7183,157 @@ class LLViewHighlightTransparent : public view_listener_t
class LLViewCheckHighlightTransparent : public view_listener_t
{
- bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
+ bool handleEvent(const LLSD& userdata)
{
bool new_value = LLDrawPoolAlpha::sShowDebugAlpha;
- gMenuHolder->findControl(userdata["control"].asString())->setValue(new_value);
+ return new_value;
+ }
+};
+
+class LLViewBeaconWidth : public view_listener_t
+{
+ bool handleEvent(const LLSD& userdata)
+ {
+ std::string width = userdata.asString();
+ if(width == "1")
+ {
+ gSavedSettings.setS32("DebugBeaconLineWidth", 1);
+ }
+ else if(width == "4")
+ {
+ gSavedSettings.setS32("DebugBeaconLineWidth", 4);
+ }
+ else if(width == "16")
+ {
+ gSavedSettings.setS32("DebugBeaconLineWidth", 16);
+ }
+ else if(width == "32")
+ {
+ gSavedSettings.setS32("DebugBeaconLineWidth", 32);
+ }
+
return true;
}
};
+
+class LLViewToggleBeacon : public view_listener_t
+{
+ bool handleEvent(const LLSD& userdata)
+ {
+ std::string beacon = userdata.asString();
+ if (beacon == "scriptsbeacon")
+ {
+ LLPipeline::toggleRenderScriptedBeacons(NULL);
+ gSavedSettings.setBOOL( "scriptsbeacon", LLPipeline::getRenderScriptedBeacons(NULL) );
+ // toggle the other one off if it's on
+ if (LLPipeline::getRenderScriptedBeacons(NULL) && LLPipeline::getRenderScriptedTouchBeacons(NULL))
+ {
+ LLPipeline::toggleRenderScriptedTouchBeacons(NULL);
+ gSavedSettings.setBOOL( "scripttouchbeacon", LLPipeline::getRenderScriptedTouchBeacons(NULL) );
+ }
+ }
+ else if (beacon == "physicalbeacon")
+ {
+ LLPipeline::toggleRenderPhysicalBeacons(NULL);
+ gSavedSettings.setBOOL( "physicalbeacon", LLPipeline::getRenderPhysicalBeacons(NULL) );
+ }
+ else if (beacon == "soundsbeacon")
+ {
+ LLPipeline::toggleRenderSoundBeacons(NULL);
+ gSavedSettings.setBOOL( "soundsbeacon", LLPipeline::getRenderSoundBeacons(NULL) );
+ }
+ else if (beacon == "particlesbeacon")
+ {
+ LLPipeline::toggleRenderParticleBeacons(NULL);
+ gSavedSettings.setBOOL( "particlesbeacon", LLPipeline::getRenderParticleBeacons(NULL) );
+ }
+ else if (beacon == "scripttouchbeacon")
+ {
+ LLPipeline::toggleRenderScriptedTouchBeacons(NULL);
+ gSavedSettings.setBOOL( "scripttouchbeacon", LLPipeline::getRenderScriptedTouchBeacons(NULL) );
+ // toggle the other one off if it's on
+ if (LLPipeline::getRenderScriptedBeacons(NULL) && LLPipeline::getRenderScriptedTouchBeacons(NULL))
+ {
+ LLPipeline::toggleRenderScriptedBeacons(NULL);
+ gSavedSettings.setBOOL( "scriptsbeacon", LLPipeline::getRenderScriptedBeacons(NULL) );
+ }
+ }
+ else if (beacon == "renderbeacons")
+ {
+ LLPipeline::toggleRenderBeacons(NULL);
+ gSavedSettings.setBOOL( "renderbeacons", LLPipeline::getRenderBeacons(NULL) );
+ // toggle the other one on if it's not
+ if (!LLPipeline::getRenderBeacons(NULL) && !LLPipeline::getRenderHighlights(NULL))
+ {
+ LLPipeline::toggleRenderHighlights(NULL);
+ gSavedSettings.setBOOL( "renderhighlights", LLPipeline::getRenderHighlights(NULL) );
+ }
+ }
+ else if (beacon == "renderhighlights")
+ {
+ LLPipeline::toggleRenderHighlights(NULL);
+ gSavedSettings.setBOOL( "renderhighlights", LLPipeline::getRenderHighlights(NULL) );
+ // toggle the other one on if it's not
+ if (!LLPipeline::getRenderBeacons(NULL) && !LLPipeline::getRenderHighlights(NULL))
+ {
+ LLPipeline::toggleRenderBeacons(NULL);
+ gSavedSettings.setBOOL( "renderbeacons", LLPipeline::getRenderBeacons(NULL) );
+ }
+ }
+
+ return true;
+ }
+};
+
+class LLViewCheckBeaconEnabled : public view_listener_t
+{
+ bool handleEvent(const LLSD& userdata)
+ {
+ std::string beacon = userdata.asString();
+ bool new_value = false;
+ if (beacon == "scriptsbeacon")
+ {
+ new_value = gSavedSettings.getBOOL( "scriptsbeacon");
+ LLPipeline::setRenderScriptedBeacons(new_value);
+ }
+ else if (beacon == "physicalbeacon")
+ {
+ new_value = gSavedSettings.getBOOL( "physicalbeacon");
+ LLPipeline::setRenderPhysicalBeacons(new_value);
+ }
+ else if (beacon == "soundsbeacon")
+ {
+ new_value = gSavedSettings.getBOOL( "soundsbeacon");
+ LLPipeline::setRenderSoundBeacons(new_value);
+ }
+ else if (beacon == "particlesbeacon")
+ {
+ new_value = gSavedSettings.getBOOL( "particlesbeacon");
+ LLPipeline::setRenderParticleBeacons(new_value);
+ }
+ else if (beacon == "scripttouchbeacon")
+ {
+ new_value = gSavedSettings.getBOOL( "scripttouchbeacon");
+ LLPipeline::setRenderScriptedTouchBeacons(new_value);
+ }
+ else if (beacon == "renderbeacons")
+ {
+ new_value = gSavedSettings.getBOOL( "renderbeacons");
+ LLPipeline::setRenderBeacons(new_value);
+ }
+ else if (beacon == "renderhighlights")
+ {
+ new_value = gSavedSettings.getBOOL( "renderhighlights");
+ LLPipeline::setRenderHighlights(new_value);
+ }
+ return new_value;
+ }
+};
+
class LLViewToggleRenderType : public view_listener_t
{
- bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
+ bool handleEvent(const LLSD& userdata)
{
std::string type = userdata.asString();
if (type == "hideparticles")
@@ -7128,22 +7346,21 @@ class LLViewToggleRenderType : public view_listener_t
class LLViewCheckRenderType : public view_listener_t
{
- bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
+ bool handleEvent(const LLSD& userdata)
{
- std::string type = userdata["data"].asString();
+ std::string type = userdata.asString();
bool new_value = false;
if (type == "hideparticles")
{
new_value = LLPipeline::toggleRenderTypeControlNegated((void *)LLPipeline::RENDER_TYPE_PARTICLES);
}
- gMenuHolder->findControl(userdata["control"].asString())->setValue(new_value);
- return true;
+ return new_value;
}
};
class LLViewShowHUDAttachments : public view_listener_t
{
- bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
+ bool handleEvent(const LLSD& userdata)
{
LLPipeline::sShowHUDAttachments = !LLPipeline::sShowHUDAttachments;
return true;
@@ -7152,123 +7369,127 @@ class LLViewShowHUDAttachments : public view_listener_t
class LLViewCheckHUDAttachments : public view_listener_t
{
- bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
+ bool handleEvent(const LLSD& userdata)
{
bool new_value = LLPipeline::sShowHUDAttachments;
- gMenuHolder->findControl(userdata["control"].asString())->setValue(new_value);
- return true;
+ return new_value;
}
};
class LLEditEnableTakeOff : public view_listener_t
{
- bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
+ bool handleEvent(const LLSD& userdata)
{
- std::string control_name = userdata["control"].asString();
- std::string clothing = userdata["data"].asString();
+ std::string clothing = userdata.asString();
bool new_value = false;
if (clothing == "shirt")
{
- new_value = LLAgent::selfHasWearable((void *)WT_SHIRT);
+ new_value = LLAgentWearables::selfHasWearable(WT_SHIRT);
}
if (clothing == "pants")
{
- new_value = LLAgent::selfHasWearable((void *)WT_PANTS);
+ new_value = LLAgentWearables::selfHasWearable(WT_PANTS);
}
if (clothing == "shoes")
{
- new_value = LLAgent::selfHasWearable((void *)WT_SHOES);
+ new_value = LLAgentWearables::selfHasWearable(WT_SHOES);
}
if (clothing == "socks")
{
- new_value = LLAgent::selfHasWearable((void *)WT_SOCKS);
+ new_value = LLAgentWearables::selfHasWearable(WT_SOCKS);
}
if (clothing == "jacket")
{
- new_value = LLAgent::selfHasWearable((void *)WT_JACKET);
+ new_value = LLAgentWearables::selfHasWearable(WT_JACKET);
}
if (clothing == "gloves")
{
- new_value = LLAgent::selfHasWearable((void *)WT_GLOVES);
+ new_value = LLAgentWearables::selfHasWearable(WT_GLOVES);
}
if (clothing == "undershirt")
{
- new_value = LLAgent::selfHasWearable((void *)WT_UNDERSHIRT);
+ new_value = LLAgentWearables::selfHasWearable(WT_UNDERSHIRT);
}
if (clothing == "underpants")
{
- new_value = LLAgent::selfHasWearable((void *)WT_UNDERPANTS);
+ new_value = LLAgentWearables::selfHasWearable(WT_UNDERPANTS);
}
if (clothing == "skirt")
{
- new_value = LLAgent::selfHasWearable((void *)WT_SKIRT);
+ new_value = LLAgentWearables::selfHasWearable(WT_SKIRT);
}
- gMenuHolder->findControl(control_name)->setValue(new_value);
- return true;
+ if (clothing == "alpha")
+ {
+ new_value = LLAgentWearables::selfHasWearable(WT_ALPHA);
+ }
+ if (clothing == "tattoo")
+ {
+ new_value = LLAgentWearables::selfHasWearable(WT_TATTOO);
+ }
+ return new_value;
}
};
class LLEditTakeOff : public view_listener_t
{
- bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
+ bool handleEvent(const LLSD& userdata)
{
std::string clothing = userdata.asString();
if (clothing == "shirt")
{
- LLAgent::userRemoveWearable((void*)WT_SHIRT);
+ LLAgentWearables::userRemoveWearable((void*)WT_SHIRT);
}
else if (clothing == "pants")
{
- LLAgent::userRemoveWearable((void*)WT_PANTS);
+ LLAgentWearables::userRemoveWearable((void*)WT_PANTS);
}
else if (clothing == "shoes")
{
- LLAgent::userRemoveWearable((void*)WT_SHOES);
+ LLAgentWearables::userRemoveWearable((void*)WT_SHOES);
}
else if (clothing == "socks")
{
- LLAgent::userRemoveWearable((void*)WT_SOCKS);
+ LLAgentWearables::userRemoveWearable((void*)WT_SOCKS);
}
else if (clothing == "jacket")
{
- LLAgent::userRemoveWearable((void*)WT_JACKET);
+ LLAgentWearables::userRemoveWearable((void*)WT_JACKET);
}
else if (clothing == "gloves")
{
- LLAgent::userRemoveWearable((void*)WT_GLOVES);
+ LLAgentWearables::userRemoveWearable((void*)WT_GLOVES);
}
else if (clothing == "undershirt")
{
- LLAgent::userRemoveWearable((void*)WT_UNDERSHIRT);
+ LLAgentWearables::userRemoveWearable((void*)WT_UNDERSHIRT);
}
else if (clothing == "underpants")
{
- LLAgent::userRemoveWearable((void*)WT_UNDERPANTS);
+ LLAgentWearables::userRemoveWearable((void*)WT_UNDERPANTS);
}
else if (clothing == "skirt")
{
- LLAgent::userRemoveWearable((void*)WT_SKIRT);
+ LLAgentWearables::userRemoveWearable((void*)WT_SKIRT);
+ }
+ else if (clothing == "alpha")
+ {
+ LLAgentWearables::userRemoveWearable((void*)WT_ALPHA);
+ }
+ else if (clothing == "tattoo")
+ {
+ LLAgentWearables::userRemoveWearable((void*)WT_TATTOO);
}
else if (clothing == "all")
{
- LLAgent::userRemoveAllClothes(NULL);
+ LLAgentWearables::userRemoveAllClothes(NULL);
}
return true;
}
};
-class LLWorldChat : public view_listener_t
-{
- bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
- {
- handle_chat(NULL);
- return true;
- }
-};
-
class LLToolsSelectTool : public view_listener_t
{
- bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
+ bool handleEvent(const LLSD& userdata)
{
std::string tool_name = userdata.asString();
if (tool_name == "focus")
@@ -7298,7 +7519,7 @@ class LLToolsSelectTool : public view_listener_t
/// WINDLIGHT callbacks
class LLWorldEnvSettings : public view_listener_t
{
- bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
+ bool handleEvent(const LLSD& userdata)
{
std::string tod = userdata.asString();
LLVector3 sun_direction;
@@ -7306,16 +7527,7 @@ class LLWorldEnvSettings : public view_listener_t
if (tod == "editor")
{
// if not there or is hidden, show it
- if( !LLFloaterEnvSettings::isOpen() ||
- !LLFloaterEnvSettings::instance()->getVisible()) {
- LLFloaterEnvSettings::show();
-
- // otherwise, close it button acts like a toggle
- }
- else
- {
- LLFloaterEnvSettings::instance()->close();
- }
+ LLFloaterReg::toggleInstance("env_settings");
return true;
}
@@ -7375,19 +7587,9 @@ class LLWorldEnvSettings : public view_listener_t
/// Water Menu callbacks
class LLWorldWaterSettings : public view_listener_t
{
- bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
+ bool handleEvent(const LLSD& userdata)
{
- // if not there or is hidden, show it
- if( !LLFloaterWater::isOpen() ||
- !LLFloaterWater::instance()->getVisible()) {
- LLFloaterWater::show();
-
- // otherwise, close it button acts like a toggle
- }
- else
- {
- LLFloaterWater::instance()->close();
- }
+ LLFloaterReg::toggleInstance("env_water");
return true;
}
};
@@ -7395,9 +7597,9 @@ class LLWorldWaterSettings : public view_listener_t
/// Post-Process callbacks
class LLWorldPostProcess : public view_listener_t
{
- bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
+ bool handleEvent(const LLSD& userdata)
{
- LLFloaterPostProcess::show();
+ LLFloaterReg::showInstance("env_post_process");
return true;
}
};
@@ -7405,20 +7607,30 @@ class LLWorldPostProcess : public view_listener_t
/// Day Cycle callbacks
class LLWorldDayCycle : public view_listener_t
{
- bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
+ bool handleEvent(const LLSD& userdata)
{
- LLFloaterDayCycle::show();
+ LLFloaterReg::showInstance("env_day_cycle");
return true;
}
};
+/// Show First Time Tips calbacks
+class LLHelpCheckShowFirstTimeTip : public view_listener_t
+{
+ bool handleEvent(const LLSD& userdata)
+ {
+ return LLFirstTimeTipsManager::tipsEnabled();
+ }
+};
-
-static void addMenu(view_listener_t *menu, const std::string& name)
+class LLHelpShowFirstTimeTip : public view_listener_t
{
- sMenus.push_back(menu);
- menu->registerListener(gMenuHolder, name);
-}
+ bool handleEvent(const LLSD& userdata)
+ {
+ LLFirstTimeTipsManager::enabledTip(!userdata.asBoolean());
+ return true;
+ }
+};
void initialize_menus()
{
@@ -7428,7 +7640,7 @@ void initialize_menus()
public:
// The "mult" parameter says whether "val" is a multiplier or used to set the value.
LLZoomer(F32 val, bool mult=true) : mVal(val), mMult(mult) {}
- bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
+ bool handleEvent(const LLSD& userdata)
{
F32 new_fov_rad = mMult ? LLViewerCamera::getInstance()->getDefaultFOV() * mVal : mVal;
LLViewerCamera::getInstance()->setDefaultFOV(new_fov_rad);
@@ -7440,217 +7652,381 @@ void initialize_menus()
bool mMult;
};
- class LLAvatarReportAbuse : public view_listener_t
- {
- bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
- {
- LLVOAvatar* avatar = find_avatar_from_object( LLSelectMgr::getInstance()->getSelection()->getPrimaryObject() );
- if(avatar)
- {
- LLFloaterReporter::showFromObject(avatar->getID());
- }
- return true;
- }
- };
+ LLUICtrl::EnableCallbackRegistry::Registrar& enable = LLUICtrl::EnableCallbackRegistry::currentRegistrar();
+ LLUICtrl::CommitCallbackRegistry::Registrar& commit = LLUICtrl::CommitCallbackRegistry::currentRegistrar();
+
+ // Enable God Mode
+ view_listener_t::addMenu(new LLEnableGodCustomerService(), "EnableGodCustomerService");
+
+ // Agent
+ commit.add("Agent.toggleFlying", boost::bind(&LLAgent::toggleFlying));
+ enable.add("Agent.emableFlying", boost::bind(&LLAgent::enableFlying));
// File menu
init_menu_file();
// Edit menu
- addMenu(new LLEditUndo(), "Edit.Undo");
- addMenu(new LLEditRedo(), "Edit.Redo");
- addMenu(new LLEditCut(), "Edit.Cut");
- addMenu(new LLEditCopy(), "Edit.Copy");
- addMenu(new LLEditPaste(), "Edit.Paste");
- addMenu(new LLEditDelete(), "Edit.Delete");
- addMenu(new LLEditSearch(), "Edit.Search");
- addMenu(new LLEditSelectAll(), "Edit.SelectAll");
- addMenu(new LLEditDeselect(), "Edit.Deselect");
- addMenu(new LLEditDuplicate(), "Edit.Duplicate");
- addMenu(new LLEditTakeOff(), "Edit.TakeOff");
-
- addMenu(new LLEditEnableUndo(), "Edit.EnableUndo");
- addMenu(new LLEditEnableRedo(), "Edit.EnableRedo");
- addMenu(new LLEditEnableCut(), "Edit.EnableCut");
- addMenu(new LLEditEnableCopy(), "Edit.EnableCopy");
- addMenu(new LLEditEnablePaste(), "Edit.EnablePaste");
- addMenu(new LLEditEnableDelete(), "Edit.EnableDelete");
- addMenu(new LLEditEnableSelectAll(), "Edit.EnableSelectAll");
- addMenu(new LLEditEnableDeselect(), "Edit.EnableDeselect");
- addMenu(new LLEditEnableDuplicate(), "Edit.EnableDuplicate");
- addMenu(new LLEditEnableTakeOff(), "Edit.EnableTakeOff");
- addMenu(new LLEditEnableCustomizeAvatar(), "Edit.EnableCustomizeAvatar");
+ view_listener_t::addMenu(new LLEditUndo(), "Edit.Undo");
+ view_listener_t::addMenu(new LLEditRedo(), "Edit.Redo");
+ view_listener_t::addMenu(new LLEditCut(), "Edit.Cut");
+ view_listener_t::addMenu(new LLEditCopy(), "Edit.Copy");
+ view_listener_t::addMenu(new LLEditPaste(), "Edit.Paste");
+ view_listener_t::addMenu(new LLEditDelete(), "Edit.Delete");
+ view_listener_t::addMenu(new LLEditSelectAll(), "Edit.SelectAll");
+ view_listener_t::addMenu(new LLEditDeselect(), "Edit.Deselect");
+ view_listener_t::addMenu(new LLEditDuplicate(), "Edit.Duplicate");
+ view_listener_t::addMenu(new LLEditTakeOff(), "Edit.TakeOff");
+
+ view_listener_t::addMenu(new LLEditEnableUndo(), "Edit.EnableUndo");
+ view_listener_t::addMenu(new LLEditEnableRedo(), "Edit.EnableRedo");
+ view_listener_t::addMenu(new LLEditEnableCut(), "Edit.EnableCut");
+ view_listener_t::addMenu(new LLEditEnableCopy(), "Edit.EnableCopy");
+ view_listener_t::addMenu(new LLEditEnablePaste(), "Edit.EnablePaste");
+ view_listener_t::addMenu(new LLEditEnableDelete(), "Edit.EnableDelete");
+ view_listener_t::addMenu(new LLEditEnableSelectAll(), "Edit.EnableSelectAll");
+ view_listener_t::addMenu(new LLEditEnableDeselect(), "Edit.EnableDeselect");
+ view_listener_t::addMenu(new LLEditEnableDuplicate(), "Edit.EnableDuplicate");
+ view_listener_t::addMenu(new LLEditEnableTakeOff(), "Edit.EnableTakeOff");
+ view_listener_t::addMenu(new LLEditEnableCustomizeAvatar(), "Edit.EnableCustomizeAvatar");
// View menu
- addMenu(new LLViewMouselook(), "View.Mouselook");
- addMenu(new LLViewBuildMode(), "View.BuildMode");
- addMenu(new LLViewJoystickFlycam(), "View.JoystickFlycam");
- addMenu(new LLViewCommunicate(), "View.Communicate");
- addMenu(new LLViewResetView(), "View.ResetView");
- addMenu(new LLViewLookAtLastChatter(), "View.LookAtLastChatter");
- addMenu(new LLViewShowHoverTips(), "View.ShowHoverTips");
- addMenu(new LLViewHighlightTransparent(), "View.HighlightTransparent");
- addMenu(new LLViewToggleRenderType(), "View.ToggleRenderType");
- addMenu(new LLViewShowHUDAttachments(), "View.ShowHUDAttachments");
- addMenu(new LLZoomer(1.2f), "View.ZoomOut");
- addMenu(new LLZoomer(1/1.2f), "View.ZoomIn");
- addMenu(new LLZoomer(DEFAULT_FIELD_OF_VIEW, false), "View.ZoomDefault");
- addMenu(new LLViewFullscreen(), "View.Fullscreen");
- addMenu(new LLViewDefaultUISize(), "View.DefaultUISize");
-
- addMenu(new LLViewEnableMouselook(), "View.EnableMouselook");
- addMenu(new LLViewEnableJoystickFlycam(), "View.EnableJoystickFlycam");
- addMenu(new LLViewEnableLastChatter(), "View.EnableLastChatter");
-
- addMenu(new LLViewCheckBuildMode(), "View.CheckBuildMode");
- addMenu(new LLViewCheckJoystickFlycam(), "View.CheckJoystickFlycam");
- addMenu(new LLViewCheckShowHoverTips(), "View.CheckShowHoverTips");
- addMenu(new LLViewCheckHighlightTransparent(), "View.CheckHighlightTransparent");
- addMenu(new LLViewCheckRenderType(), "View.CheckRenderType");
- addMenu(new LLViewCheckHUDAttachments(), "View.CheckHUDAttachments");
+ view_listener_t::addMenu(new LLViewMouselook(), "View.Mouselook");
+ view_listener_t::addMenu(new LLViewJoystickFlycam(), "View.JoystickFlycam");
+ view_listener_t::addMenu(new LLViewResetView(), "View.ResetView");
+ view_listener_t::addMenu(new LLViewLookAtLastChatter(), "View.LookAtLastChatter");
+ view_listener_t::addMenu(new LLViewShowHoverTips(), "View.ShowHoverTips");
+ view_listener_t::addMenu(new LLViewHighlightTransparent(), "View.HighlightTransparent");
+ view_listener_t::addMenu(new LLViewToggleRenderType(), "View.ToggleRenderType");
+ view_listener_t::addMenu(new LLViewShowHUDAttachments(), "View.ShowHUDAttachments");
+ view_listener_t::addMenu(new LLZoomer(1.2f), "View.ZoomOut");
+ view_listener_t::addMenu(new LLZoomer(1/1.2f), "View.ZoomIn");
+ view_listener_t::addMenu(new LLZoomer(DEFAULT_FIELD_OF_VIEW, false), "View.ZoomDefault");
+ view_listener_t::addMenu(new LLViewFullscreen(), "View.Fullscreen");
+ view_listener_t::addMenu(new LLViewDefaultUISize(), "View.DefaultUISize");
+
+ view_listener_t::addMenu(new LLViewEnableMouselook(), "View.EnableMouselook");
+ view_listener_t::addMenu(new LLViewEnableJoystickFlycam(), "View.EnableJoystickFlycam");
+ view_listener_t::addMenu(new LLViewEnableLastChatter(), "View.EnableLastChatter");
+
+ view_listener_t::addMenu(new LLViewCheckJoystickFlycam(), "View.CheckJoystickFlycam");
+ view_listener_t::addMenu(new LLViewCheckShowHoverTips(), "View.CheckShowHoverTips");
+ view_listener_t::addMenu(new LLViewCheckHighlightTransparent(), "View.CheckHighlightTransparent");
+ view_listener_t::addMenu(new LLViewCheckRenderType(), "View.CheckRenderType");
+ view_listener_t::addMenu(new LLViewCheckHUDAttachments(), "View.CheckHUDAttachments");
// World menu
- addMenu(new LLWorldChat(), "World.Chat");
- addMenu(new LLWorldAlwaysRun(), "World.AlwaysRun");
- addMenu(new LLWorldFly(), "World.Fly");
- addMenu(new LLWorldEnableFly(), "World.EnableFly");
- addMenu(new LLWorldCreateLandmark(), "World.CreateLandmark");
- addMenu(new LLWorldSetHomeLocation(), "World.SetHomeLocation");
- addMenu(new LLWorldTeleportHome(), "World.TeleportHome");
- addMenu(new LLWorldSetAway(), "World.SetAway");
- addMenu(new LLWorldSetBusy(), "World.SetBusy");
-
- addMenu(new LLWorldEnableCreateLandmark(), "World.EnableCreateLandmark");
- addMenu(new LLWorldEnableSetHomeLocation(), "World.EnableSetHomeLocation");
- addMenu(new LLWorldEnableTeleportHome(), "World.EnableTeleportHome");
- addMenu(new LLWorldEnableBuyLand(), "World.EnableBuyLand");
-
- addMenu(new LLWorldCheckAlwaysRun(), "World.CheckAlwaysRun");
+ commit.add("World.Chat", boost::bind(&handle_chat, (void*)NULL));
+ view_listener_t::addMenu(new LLWorldAlwaysRun(), "World.AlwaysRun");
+ view_listener_t::addMenu(new LLWorldCreateLandmark(), "World.CreateLandmark");
+ view_listener_t::addMenu(new LLWorldSetHomeLocation(), "World.SetHomeLocation");
+ view_listener_t::addMenu(new LLWorldTeleportHome(), "World.TeleportHome");
+ view_listener_t::addMenu(new LLWorldSetAway(), "World.SetAway");
+ view_listener_t::addMenu(new LLWorldSetBusy(), "World.SetBusy");
+
+ view_listener_t::addMenu(new LLWorldEnableCreateLandmark(), "World.EnableCreateLandmark");
+ view_listener_t::addMenu(new LLWorldEnableSetHomeLocation(), "World.EnableSetHomeLocation");
+ view_listener_t::addMenu(new LLWorldEnableTeleportHome(), "World.EnableTeleportHome");
+ view_listener_t::addMenu(new LLWorldEnableBuyLand(), "World.EnableBuyLand");
+
+ view_listener_t::addMenu(new LLWorldCheckAlwaysRun(), "World.CheckAlwaysRun");
- (new LLWorldEnvSettings())->registerListener(gMenuHolder, "World.EnvSettings");
- (new LLWorldWaterSettings())->registerListener(gMenuHolder, "World.WaterSettings");
- (new LLWorldPostProcess())->registerListener(gMenuHolder, "World.PostProcess");
- (new LLWorldDayCycle())->registerListener(gMenuHolder, "World.DayCycle");
+ view_listener_t::addMenu(new LLWorldEnvSettings(), "World.EnvSettings");
+ view_listener_t::addMenu(new LLWorldWaterSettings(), "World.WaterSettings");
+ view_listener_t::addMenu(new LLWorldPostProcess(), "World.PostProcess");
+ view_listener_t::addMenu(new LLWorldDayCycle(), "World.DayCycle");
+
+ view_listener_t::addMenu(new LLHelpCheckShowFirstTimeTip(), "Help.CheckShowFirstTimeTip");
+ view_listener_t::addMenu(new LLHelpShowFirstTimeTip(), "Help.ShowQuickTips");
// Tools menu
- addMenu(new LLToolsSelectTool(), "Tools.SelectTool");
- addMenu(new LLToolsSelectOnlyMyObjects(), "Tools.SelectOnlyMyObjects");
- addMenu(new LLToolsSelectOnlyMovableObjects(), "Tools.SelectOnlyMovableObjects");
- addMenu(new LLToolsSelectBySurrounding(), "Tools.SelectBySurrounding");
- addMenu(new LLToolsShowHiddenSelection(), "Tools.ShowHiddenSelection");
- addMenu(new LLToolsShowSelectionLightRadius(), "Tools.ShowSelectionLightRadius");
- addMenu(new LLToolsEditLinkedParts(), "Tools.EditLinkedParts");
- addMenu(new LLToolsSnapObjectXY(), "Tools.SnapObjectXY");
- addMenu(new LLToolsUseSelectionForGrid(), "Tools.UseSelectionForGrid");
- addMenu(new LLToolsLink(), "Tools.Link");
- addMenu(new LLToolsUnlink(), "Tools.Unlink");
- addMenu(new LLToolsStopAllAnimations(), "Tools.StopAllAnimations");
- addMenu(new LLToolsReleaseKeys(), "Tools.ReleaseKeys");
- addMenu(new LLToolsEnableReleaseKeys(), "Tools.EnableReleaseKeys");
- addMenu(new LLToolsLookAtSelection(), "Tools.LookAtSelection");
- addMenu(new LLToolsBuyOrTake(), "Tools.BuyOrTake");
- addMenu(new LLToolsTakeCopy(), "Tools.TakeCopy");
- addMenu(new LLToolsSaveToObjectInventory(), "Tools.SaveToObjectInventory");
- addMenu(new LLToolsSelectedScriptAction(), "Tools.SelectedScriptAction");
-
- addMenu(new LLToolsEnableToolNotPie(), "Tools.EnableToolNotPie");
- addMenu(new LLToolsEnableLink(), "Tools.EnableLink");
- addMenu(new LLToolsEnableUnlink(), "Tools.EnableUnlink");
- addMenu(new LLToolsEnableBuyOrTake(), "Tools.EnableBuyOrTake");
- addMenu(new LLToolsEnableTakeCopy(), "Tools.EnableTakeCopy");
- addMenu(new LLToolsEnableSaveToObjectInventory(), "Tools.EnableSaveToObjectInventory");
-
- /*addMenu(new LLToolsVisibleBuyObject(), "Tools.VisibleBuyObject");
- addMenu(new LLToolsVisibleTakeObject(), "Tools.VisibleTakeObject");*/
+ view_listener_t::addMenu(new LLToolsSelectTool(), "Tools.SelectTool");
+ view_listener_t::addMenu(new LLToolsSelectOnlyMyObjects(), "Tools.SelectOnlyMyObjects");
+ view_listener_t::addMenu(new LLToolsSelectOnlyMovableObjects(), "Tools.SelectOnlyMovableObjects");
+ view_listener_t::addMenu(new LLToolsSelectBySurrounding(), "Tools.SelectBySurrounding");
+ view_listener_t::addMenu(new LLToolsShowHiddenSelection(), "Tools.ShowHiddenSelection");
+ view_listener_t::addMenu(new LLToolsShowSelectionLightRadius(), "Tools.ShowSelectionLightRadius");
+ view_listener_t::addMenu(new LLToolsEditLinkedParts(), "Tools.EditLinkedParts");
+ view_listener_t::addMenu(new LLToolsSnapObjectXY(), "Tools.SnapObjectXY");
+ view_listener_t::addMenu(new LLToolsUseSelectionForGrid(), "Tools.UseSelectionForGrid");
+ view_listener_t::addMenu(new LLToolsLink(), "Tools.Link");
+ view_listener_t::addMenu(new LLToolsUnlink(), "Tools.Unlink");
+ view_listener_t::addMenu(new LLToolsStopAllAnimations(), "Tools.StopAllAnimations");
+ view_listener_t::addMenu(new LLToolsReleaseKeys(), "Tools.ReleaseKeys");
+ view_listener_t::addMenu(new LLToolsEnableReleaseKeys(), "Tools.EnableReleaseKeys");
+ view_listener_t::addMenu(new LLToolsLookAtSelection(), "Tools.LookAtSelection");
+ view_listener_t::addMenu(new LLToolsBuyOrTake(), "Tools.BuyOrTake");
+ view_listener_t::addMenu(new LLToolsTakeCopy(), "Tools.TakeCopy");
+ view_listener_t::addMenu(new LLToolsSaveToInventory(), "Tools.SaveToInventory");
+ view_listener_t::addMenu(new LLToolsSaveToObjectInventory(), "Tools.SaveToObjectInventory");
+ view_listener_t::addMenu(new LLToolsSelectedScriptAction(), "Tools.SelectedScriptAction");
+
+ view_listener_t::addMenu(new LLToolsEnableToolNotPie(), "Tools.EnableToolNotPie");
+ view_listener_t::addMenu(new LLToolsEnableLink(), "Tools.EnableLink");
+ view_listener_t::addMenu(new LLToolsEnableUnlink(), "Tools.EnableUnlink");
+ view_listener_t::addMenu(new LLToolsEnableBuyOrTake(), "Tools.EnableBuyOrTake");
+ view_listener_t::addMenu(new LLToolsEnableTakeCopy(), "Tools.EnableTakeCopy");
+ view_listener_t::addMenu(new LLToolsEnableSaveToInventory(), "Tools.EnableSaveToInventory");
+ view_listener_t::addMenu(new LLToolsEnableSaveToObjectInventory(), "Tools.EnableSaveToObjectInventory");
+
+ /*view_listener_t::addMenu(new LLToolsVisibleBuyObject(), "Tools.VisibleBuyObject");
+ view_listener_t::addMenu(new LLToolsVisibleTakeObject(), "Tools.VisibleTakeObject");*/
// Help menu
// most items use the ShowFloater method
+ // Advance menu
+ view_listener_t::addMenu(new LLAdvancedToggleConsole(), "Advanced.ToggleConsole");
+ view_listener_t::addMenu(new LLAdvancedCheckConsole(), "Advanced.CheckConsole");
+ view_listener_t::addMenu(new LLAdvancedDumpInfoToConsole(), "Advanced.DumpInfoToConsole");
+ // Advanced > HUD Info
+ view_listener_t::addMenu(new LLAdvancedToggleHUDInfo(), "Advanced.ToggleHUDInfo");
+ view_listener_t::addMenu(new LLAdvancedCheckHUDInfo(), "Advanced.CheckHUDInfo");
+
+ // Advanced Other Settings
+ view_listener_t::addMenu(new LLAdvancedClearGroupCache(), "Advanced.ClearGroupCache");
+
+ // Advanced > Render > Types
+ view_listener_t::addMenu(new LLAdvancedToggleRenderType(), "Advanced.ToggleRenderType");
+ view_listener_t::addMenu(new LLAdvancedCheckRenderType(), "Advanced.CheckRenderType");
+
+ //// Advanced > Render > Features
+ view_listener_t::addMenu(new LLAdvancedToggleFeature(), "Advanced.ToggleFeature");
+ view_listener_t::addMenu(new LLAdvancedCheckFeature(), "Advanced.CheckFeature");
+ // Advanced > Render > Info Displays
+ view_listener_t::addMenu(new LLAdvancedToggleInfoDisplay(), "Advanced.ToggleInfoDisplay");
+ view_listener_t::addMenu(new LLAdvancedCheckInfoDisplay(), "Advanced.CheckInfoDisplay");
+ view_listener_t::addMenu(new LLAdvancedSelectedTextureInfo(), "Advanced.SelectedTextureInfo");
+ view_listener_t::addMenu(new LLAdvancedToggleWireframe(), "Advanced.ToggleWireframe");
+ view_listener_t::addMenu(new LLAdvancedCheckWireframe(), "Advanced.CheckWireframe");
+ view_listener_t::addMenu(new LLAdvancedToggleDisableTextures(), "Advanced.ToggleDisableTextures");
+ view_listener_t::addMenu(new LLAdvancedCheckDisableTextures(), "Advanced.CheckDisableTextures");
+ view_listener_t::addMenu(new LLAdvancedEnableObjectObjectOcclusion(), "Advanced.EnableObjectObjectOcclusion");
+ view_listener_t::addMenu(new LLAdvancedToggleRandomizeFramerate(), "Advanced.ToggleRandomizeFramerate");
+ view_listener_t::addMenu(new LLAdvancedCheckRandomizeFramerate(), "Advanced.CheckRandomizeFramerate");
+ view_listener_t::addMenu(new LLAdvancedTogglePeriodicSlowFrame(), "Advanced.TogglePeriodicSlowFrame");
+ view_listener_t::addMenu(new LLAdvancedCheckPeriodicSlowFrame(), "Advanced.CheckPeriodicSlowFrame");
+ view_listener_t::addMenu(new LLAdvancedVectorizePerfTest(), "Advanced.VectorizePerfTest");
+ view_listener_t::addMenu(new LLAdvancedToggleFrameTest(), "Advanced.ToggleFrameTest");
+ view_listener_t::addMenu(new LLAdvancedCheckFrameTest(), "Advanced.CheckFrameTest");
+ view_listener_t::addMenu(new LLAdvancedHandleAttchedLightParticles(), "Advanced.HandleAttchedLightParticles");
+
+
+ #ifdef TOGGLE_HACKED_GODLIKE_VIEWER
+ view_listener_t::addMenu(new LLAdvancedHandleToggleHackedGodmode(), "Advanced.HandleToggleHackedGodmode");
+ view_listener_t::addMenu(new LLAdvancedCheckToggleHackedGodmode(), "Advanced.CheckToggleHackedGodmode");
+ view_listener_t::addMenu(new LLAdvancedEnableToggleHackedGodmode(), "Advanced.EnableToggleHackedGodmode");
+ #endif
+
+ // Advanced > World
+ view_listener_t::addMenu(new LLAdvancedDumpScriptedCamera(), "Advanced.DumpScriptedCamera");
+ view_listener_t::addMenu(new LLAdvancedDumpRegionObjectCache(), "Advanced.DumpRegionObjectCache");
+
+ // Advanced > UI
+ view_listener_t::addMenu(new LLAdvancedWebBrowserTest(), "Advanced.WebBrowserTest");
+ view_listener_t::addMenu(new LLAdvancedBuyCurrencyTest(), "Advanced.BuyCurrencyTest");
+ view_listener_t::addMenu(new LLAdvancedToggleEditableUI(), "Advanced.ToggleEditableUI");
+ view_listener_t::addMenu(new LLAdvancedDumpSelectMgr(), "Advanced.DumpSelectMgr");
+ view_listener_t::addMenu(new LLAdvancedDumpInventory(), "Advanced.DumpInventory");
+ view_listener_t::addMenu(new LLAdvancedDumpFocusHolder(), "Advanced.DumpFocusHolder");
+ view_listener_t::addMenu(new LLAdvancedPrintSelectedObjectInfo(), "Advanced.PrintSelectedObjectInfo");
+ view_listener_t::addMenu(new LLAdvancedPrintAgentInfo(), "Advanced.PrintAgentInfo");
+ view_listener_t::addMenu(new LLAdvancedPrintTextureMemoryStats(), "Advanced.PrintTextureMemoryStats");
+ view_listener_t::addMenu(new LLAdvancedToggleDebugClicks(), "Advanced.ToggleDebugClicks");
+ view_listener_t::addMenu(new LLAdvancedCheckDebugClicks(), "Advanced.CheckDebugClicks");
+ view_listener_t::addMenu(new LLAdvancedCheckDebugViews(), "Advanced.CheckDebugViews");
+ view_listener_t::addMenu(new LLAdvancedToggleDebugViews(), "Advanced.ToggleDebugViews");
+ view_listener_t::addMenu(new LLAdvancedToggleXUINameTooltips(), "Advanced.ToggleXUINameTooltips");
+ view_listener_t::addMenu(new LLAdvancedCheckXUINameTooltips(), "Advanced.CheckXUINameTooltips");
+ view_listener_t::addMenu(new LLAdvancedToggleDebugMouseEvents(), "Advanced.ToggleDebugMouseEvents");
+ view_listener_t::addMenu(new LLAdvancedCheckDebugMouseEvents(), "Advanced.CheckDebugMouseEvents");
+ view_listener_t::addMenu(new LLAdvancedToggleDebugKeys(), "Advanced.ToggleDebugKeys");
+ view_listener_t::addMenu(new LLAdvancedCheckDebugKeys(), "Advanced.CheckDebugKeys");
+ view_listener_t::addMenu(new LLAdvancedToggleDebugWindowProc(), "Advanced.ToggleDebugWindowProc");
+ view_listener_t::addMenu(new LLAdvancedCheckDebugWindowProc(), "Advanced.CheckDebugWindowProc");
+
+
+ // Advanced > XUI
+ commit.add("Advanced.ReloadColorSettings", boost::bind(&LLUIColorTable::loadFromSettings, LLUIColorTable::getInstance()));
+ view_listener_t::addMenu(new LLAdvancedLoadUIFromXML(), "Advanced.LoadUIFromXML");
+ view_listener_t::addMenu(new LLAdvancedSaveUIToXML(), "Advanced.SaveUIToXML");
+ view_listener_t::addMenu(new LLAdvancedToggleXUINames(), "Advanced.ToggleXUINames");
+ view_listener_t::addMenu(new LLAdvancedCheckXUINames(), "Advanced.CheckXUINames");
+ view_listener_t::addMenu(new LLAdvancedSendTestIms(), "Advanced.SendTestIMs");
+ view_listener_t::addMenu(new LLAdvancedAvatarInspector(), "Advanced.AvatarInspector");
+
+ // Advanced > Character > Grab Baked Texture
+ view_listener_t::addMenu(new LLAdvancedGrabBakedTexture(), "Advanced.GrabBakedTexture");
+ view_listener_t::addMenu(new LLAdvancedEnableGrabBakedTexture(), "Advanced.EnableGrabBakedTexture");
+
+ // Advanced > Character > Character Tests
+ view_listener_t::addMenu(new LLAdvancedAppearanceToXML(), "Advanced.AppearanceToXML");
+ view_listener_t::addMenu(new LLAdvancedToggleCharacterGeometry(), "Advanced.ToggleCharacterGeometry");
+
+ view_listener_t::addMenu(new LLAdvancedTestMale(), "Advanced.TestMale");
+ view_listener_t::addMenu(new LLAdvancedTestFemale(), "Advanced.TestFemale");
+ view_listener_t::addMenu(new LLAdvancedTogglePG(), "Advanced.TogglePG");
+
+ // Advanced > Character (toplevel)
+ view_listener_t::addMenu(new LLAdvancedToggleAllowTapTapHoldRun(), "Advanced.ToggleAllowTapTapHoldRun");
+ view_listener_t::addMenu(new LLAdvancedCheckAllowTapTapHoldRun(), "Advanced.CheckAllowTapTapHoldRun");
+ view_listener_t::addMenu(new LLAdvancedForceParamsToDefault(), "Advanced.ForceParamsToDefault");
+ view_listener_t::addMenu(new LLAdvancedReloadVertexShader(), "Advanced.ReloadVertexShader");
+ view_listener_t::addMenu(new LLAdvancedToggleAnimationInfo(), "Advanced.ToggleAnimationInfo");
+ view_listener_t::addMenu(new LLAdvancedCheckAnimationInfo(), "Advanced.CheckAnimationInfo");
+ view_listener_t::addMenu(new LLAdvancedToggleShowLookAt(), "Advanced.ToggleShowLookAt");
+ view_listener_t::addMenu(new LLAdvancedCheckShowLookAt(), "Advanced.CheckShowLookAt");
+ view_listener_t::addMenu(new LLAdvancedToggleShowPointAt(), "Advanced.ToggleShowPointAt");
+ view_listener_t::addMenu(new LLAdvancedCheckShowPointAt(), "Advanced.CheckShowPointAt");
+ view_listener_t::addMenu(new LLAdvancedToggleDebugJointUpdates(), "Advanced.ToggleDebugJointUpdates");
+ view_listener_t::addMenu(new LLAdvancedCheckDebugJointUpdates(), "Advanced.CheckDebugJointUpdates");
+ view_listener_t::addMenu(new LLAdvancedToggleDisableLOD(), "Advanced.ToggleDisableLOD");
+ view_listener_t::addMenu(new LLAdvancedCheckDisableLOD(), "Advanced.CheckDisableLOD");
+ view_listener_t::addMenu(new LLAdvancedToggleDebugCharacterVis(), "Advanced.ToggleDebugCharacterVis");
+ view_listener_t::addMenu(new LLAdvancedCheckDebugCharacterVis(), "Advanced.CheckDebugCharacterVis");
+ view_listener_t::addMenu(new LLAdvancedDumpAttachments(), "Advanced.DumpAttachments");
+ view_listener_t::addMenu(new LLAdvancedRebakeTextures(), "Advanced.RebakeTextures");
+ #ifndef LL_RELEASE_FOR_DOWNLOAD
+ view_listener_t::addMenu(new LLAdvancedDebugAvatarTextures(), "Advanced.DebugAvatarTextures");
+ view_listener_t::addMenu(new LLAdvancedDumpAvatarLocalTextures(), "Advanced.DumpAvatarLocalTextures");
+ #endif
+ // Advanced > Network
+ view_listener_t::addMenu(new LLAdvancedEnableMessageLog(), "Advanced.EnableMessageLog");
+ view_listener_t::addMenu(new LLAdvancedDisableMessageLog(), "Advanced.DisableMessageLog");
+ view_listener_t::addMenu(new LLAdvancedDropPacket(), "Advanced.DropPacket");
+
+ // Advanced > Recorder
+ view_listener_t::addMenu(new LLAdvancedAgentPilot(), "Advanced.AgentPilot");
+ view_listener_t::addMenu(new LLAdvancedToggleAgentPilotLoop(), "Advanced.ToggleAgentPilotLoop");
+ view_listener_t::addMenu(new LLAdvancedCheckAgentPilotLoop(), "Advanced.CheckAgentPilotLoop");
+
+ // Advanced > Debugging
+ view_listener_t::addMenu(new LLAdvancedForceErrorBreakpoint(), "Advanced.ForceErrorBreakpoint");
+ view_listener_t::addMenu(new LLAdvancedForceErrorLlerror(), "Advanced.ForceErrorLlerror");
+ view_listener_t::addMenu(new LLAdvancedForceErrorBadMemoryAccess(), "Advanced.ForceErrorBadMemoryAccess");
+ view_listener_t::addMenu(new LLAdvancedForceErrorInfiniteLoop(), "Advanced.ForceErrorInfiniteLoop");
+ view_listener_t::addMenu(new LLAdvancedForceErrorSoftwareException(), "Advanced.ForceErrorSoftwareException");
+ view_listener_t::addMenu(new LLAdvancedForceErrorDriverCrash(), "Advanced.ForceErrorDriverCrash");
+ view_listener_t::addMenu(new LLAdvancedForceErrorDriverCrash(), "Advanced.ForceErrorDisconnectViewer");
+
+ // Advanced (toplevel)
+ view_listener_t::addMenu(new LLAdvancedToggleShowObjectUpdates(), "Advanced.ToggleShowObjectUpdates");
+ view_listener_t::addMenu(new LLAdvancedCheckShowObjectUpdates(), "Advanced.CheckShowObjectUpdates");
+ view_listener_t::addMenu(new LLAdvancedCompressImage(), "Advanced.CompressImage");
+ view_listener_t::addMenu(new LLAdvancedShowDebugSettings(), "Advanced.ShowDebugSettings");
+ view_listener_t::addMenu(new LLAdvancedToggleViewAdminOptions(), "Advanced.ToggleViewAdminOptions");
+ view_listener_t::addMenu(new LLAdvancedCheckViewAdminOptions(), "Advanced.CheckViewAdminOptions");
+ view_listener_t::addMenu(new LLAdvancedRequestAdminStatus(), "Advanced.RequestAdminStatus");
+ view_listener_t::addMenu(new LLAdvancedLeaveAdminStatus(), "Advanced.LeaveAdminStatus");
+
+
+ // Admin >Object
+ view_listener_t::addMenu(new LLAdminForceTakeCopy(), "Admin.ForceTakeCopy");
+ view_listener_t::addMenu(new LLAdminHandleObjectOwnerSelf(), "Admin.HandleObjectOwnerSelf");
+ view_listener_t::addMenu(new LLAdminHandleObjectOwnerPermissive(), "Admin.HandleObjectOwnerPermissive");
+ view_listener_t::addMenu(new LLAdminHandleForceDelete(), "Admin.HandleForceDelete");
+ view_listener_t::addMenu(new LLAdminHandleObjectLock(), "Admin.HandleObjectLock");
+ view_listener_t::addMenu(new LLAdminHandleObjectAssetIDs(), "Admin.HandleObjectAssetIDs");
+
+ // Admin >Parcel
+ view_listener_t::addMenu(new LLAdminHandleForceParcelOwnerToMe(), "Admin.HandleForceParcelOwnerToMe");
+ view_listener_t::addMenu(new LLAdminHandleForceParcelToContent(), "Admin.HandleForceParcelToContent");
+ view_listener_t::addMenu(new LLAdminHandleClaimPublicLand(), "Admin.HandleClaimPublicLand");
+
+ // Admin >Region
+ view_listener_t::addMenu(new LLAdminHandleRegionDumpTempAssetData(), "Admin.HandleRegionDumpTempAssetData");
+ // Admin top level
+ view_listener_t::addMenu(new LLAdminOnSaveState(), "Admin.OnSaveState");
+
// Self pie menu
- addMenu(new LLSelfStandUp(), "Self.StandUp");
- addMenu(new LLSelfRemoveAllAttachments(), "Self.RemoveAllAttachments");
+ view_listener_t::addMenu(new LLSelfStandUp(), "Self.StandUp");
+ view_listener_t::addMenu(new LLSelfRemoveAllAttachments(), "Self.RemoveAllAttachments");
- addMenu(new LLSelfEnableStandUp(), "Self.EnableStandUp");
- addMenu(new LLSelfEnableRemoveAllAttachments(), "Self.EnableRemoveAllAttachments");
+ view_listener_t::addMenu(new LLSelfEnableStandUp(), "Self.EnableStandUp");
+ view_listener_t::addMenu(new LLSelfEnableRemoveAllAttachments(), "Self.EnableRemoveAllAttachments");
+
+ // we don't use boost::bind directly to delay side tray construction
+ view_listener_t::addMenu(new LLSelfFriends(), "Self.Friends");
+ view_listener_t::addMenu(new LLSelfGroups(), "Self.Groups");
// Avatar pie menu
- addMenu(new LLObjectMute(), "Avatar.Mute");
- addMenu(new LLAvatarAddFriend(), "Avatar.AddFriend");
- addMenu(new LLAvatarFreeze(), "Avatar.Freeze");
- addMenu(new LLAvatarDebug(), "Avatar.Debug");
- addMenu(new LLAvatarVisibleDebug(), "Avatar.VisibleDebug");
- addMenu(new LLAvatarEnableDebug(), "Avatar.EnableDebug");
- addMenu(new LLAvatarInviteToGroup(), "Avatar.InviteToGroup");
- addMenu(new LLAvatarGiveCard(), "Avatar.GiveCard");
- addMenu(new LLAvatarEject(), "Avatar.Eject");
- addMenu(new LLAvatarSendIM(), "Avatar.SendIM");
- addMenu(new LLAvatarReportAbuse(), "Avatar.ReportAbuse");
+ view_listener_t::addMenu(new LLObjectMute(), "Avatar.Mute");
+ view_listener_t::addMenu(new LLAvatarAddFriend(), "Avatar.AddFriend");
+ view_listener_t::addMenu(new LLAvatarAddContact(), "Avatar.AddContact");
+ view_listener_t::addMenu(new LLAvatarFreeze(), "Avatar.Freeze");
+ view_listener_t::addMenu(new LLAvatarDebug(), "Avatar.Debug");
+ view_listener_t::addMenu(new LLAvatarVisibleDebug(), "Avatar.VisibleDebug");
+ view_listener_t::addMenu(new LLAvatarEnableDebug(), "Avatar.EnableDebug");
+ view_listener_t::addMenu(new LLAvatarInviteToGroup(), "Avatar.InviteToGroup");
+ view_listener_t::addMenu(new LLAvatarGiveCard(), "Avatar.GiveCard");
+ view_listener_t::addMenu(new LLAvatarEject(), "Avatar.Eject");
+ view_listener_t::addMenu(new LLAvatarSendIM(), "Avatar.SendIM");
+ view_listener_t::addMenu(new LLAvatarReportAbuse(), "Avatar.ReportAbuse");
- addMenu(new LLObjectEnableMute(), "Avatar.EnableMute");
- addMenu(new LLAvatarEnableAddFriend(), "Avatar.EnableAddFriend");
- addMenu(new LLAvatarEnableFreezeEject(), "Avatar.EnableFreezeEject");
+ view_listener_t::addMenu(new LLObjectEnableMute(), "Avatar.EnableMute");
+ view_listener_t::addMenu(new LLAvatarEnableAddFriend(), "Avatar.EnableAddFriend");
+ view_listener_t::addMenu(new LLAvatarEnableFreezeEject(), "Avatar.EnableFreezeEject");
// Object pie menu
- addMenu(new LLObjectOpen(), "Object.Open");
- addMenu(new LLObjectBuild(), "Object.Build");
- addMenu(new LLObjectTouch(), "Object.Touch");
- addMenu(new LLObjectSitOrStand(), "Object.SitOrStand");
- addMenu(new LLObjectDelete(), "Object.Delete");
- addMenu(new LLObjectAttachToAvatar(), "Object.AttachToAvatar");
- addMenu(new LLObjectReturn(), "Object.Return");
- addMenu(new LLObjectReportAbuse(), "Object.ReportAbuse");
- addMenu(new LLObjectMute(), "Object.Mute");
- addMenu(new LLObjectBuy(), "Object.Buy");
- addMenu(new LLObjectEdit(), "Object.Edit");
- addMenu(new LLObjectInspect(), "Object.Inspect");
-
- addMenu(new LLObjectEnableOpen(), "Object.EnableOpen");
- addMenu(new LLObjectEnableTouch(), "Object.EnableTouch");
- addMenu(new LLObjectEnableSitOrStand(), "Object.EnableSitOrStand");
- addMenu(new LLObjectEnableDelete(), "Object.EnableDelete");
- addMenu(new LLObjectEnableWear(), "Object.EnableWear");
- addMenu(new LLObjectEnableReturn(), "Object.EnableReturn");
- addMenu(new LLObjectEnableReportAbuse(), "Object.EnableReportAbuse");
- addMenu(new LLObjectEnableMute(), "Object.EnableMute");
- addMenu(new LLObjectEnableBuy(), "Object.EnableBuy");
-
- /*addMenu(new LLObjectVisibleTouch(), "Object.VisibleTouch");
- addMenu(new LLObjectVisibleCustomTouch(), "Object.VisibleCustomTouch");
- addMenu(new LLObjectVisibleStandUp(), "Object.VisibleStandUp");
- addMenu(new LLObjectVisibleSitHere(), "Object.VisibleSitHere");
- addMenu(new LLObjectVisibleCustomSit(), "Object.VisibleCustomSit");*/
+ view_listener_t::addMenu(new LLObjectBuild(), "Object.Build");
+ view_listener_t::addMenu(new LLObjectTouch(), "Object.Touch");
+ view_listener_t::addMenu(new LLObjectSitOrStand(), "Object.SitOrStand");
+ view_listener_t::addMenu(new LLObjectDelete(), "Object.Delete");
+ view_listener_t::addMenu(new LLObjectAttachToAvatar(), "Object.AttachToAvatar");
+ view_listener_t::addMenu(new LLObjectReturn(), "Object.Return");
+ view_listener_t::addMenu(new LLObjectReportAbuse(), "Object.ReportAbuse");
+ view_listener_t::addMenu(new LLObjectMute(), "Object.Mute");
+ view_listener_t::addMenu(new LLObjectBuy(), "Object.Buy");
+ view_listener_t::addMenu(new LLObjectEdit(), "Object.Edit");
+
+ view_listener_t::addMenu(new LLObjectEnableOpen(), "Object.EnableOpen");
+ view_listener_t::addMenu(new LLObjectEnableTouch(), "Object.EnableTouch");
+ view_listener_t::addMenu(new LLObjectEnableSitOrStand(), "Object.EnableSitOrStand");
+ view_listener_t::addMenu(new LLObjectEnableDelete(), "Object.EnableDelete");
+ view_listener_t::addMenu(new LLObjectEnableWear(), "Object.EnableWear");
+ view_listener_t::addMenu(new LLObjectEnableReturn(), "Object.EnableReturn");
+ view_listener_t::addMenu(new LLObjectEnableReportAbuse(), "Object.EnableReportAbuse");
+ view_listener_t::addMenu(new LLObjectEnableMute(), "Object.EnableMute");
+ view_listener_t::addMenu(new LLObjectEnableBuy(), "Object.EnableBuy");
+
+ /*view_listener_t::addMenu(new LLObjectVisibleTouch(), "Object.VisibleTouch");
+ view_listener_t::addMenu(new LLObjectVisibleCustomTouch(), "Object.VisibleCustomTouch");
+ view_listener_t::addMenu(new LLObjectVisibleStandUp(), "Object.VisibleStandUp");
+ view_listener_t::addMenu(new LLObjectVisibleSitHere(), "Object.VisibleSitHere");
+ view_listener_t::addMenu(new LLObjectVisibleCustomSit(), "Object.VisibleCustomSit");*/
// Attachment pie menu
- addMenu(new LLAttachmentDrop(), "Attachment.Drop");
- addMenu(new LLAttachmentDetach(), "Attachment.Detach");
-
- addMenu(new LLAttachmentEnableDrop(), "Attachment.EnableDrop");
- addMenu(new LLAttachmentEnableDetach(), "Attachment.EnableDetach");
+ enable.add("Attachment.Label", boost::bind(&onEnableAttachmentLabel, _1, _2));
+ view_listener_t::addMenu(new LLAttachmentDrop(), "Attachment.Drop");
+ view_listener_t::addMenu(new LLAttachmentDetachFromPoint(), "Attachment.DetachFromPoint");
+ view_listener_t::addMenu(new LLAttachmentDetach(), "Attachment.Detach");
+ view_listener_t::addMenu(new LLAttachmentPointFilled(), "Attachment.PointFilled");
+ view_listener_t::addMenu(new LLAttachmentEnableDrop(), "Attachment.EnableDrop");
+ view_listener_t::addMenu(new LLAttachmentEnableDetach(), "Attachment.EnableDetach");
// Land pie menu
- addMenu(new LLLandBuild(), "Land.Build");
- addMenu(new LLLandSit(), "Land.Sit");
- addMenu(new LLLandBuyPass(), "Land.BuyPass");
- addMenu(new LLLandEdit(), "Land.Edit");
+ view_listener_t::addMenu(new LLLandBuild(), "Land.Build");
+ view_listener_t::addMenu(new LLLandSit(), "Land.Sit");
+ view_listener_t::addMenu(new LLLandBuyPass(), "Land.BuyPass");
+ view_listener_t::addMenu(new LLLandEdit(), "Land.Edit");
- addMenu(new LLLandEnableBuyPass(), "Land.EnableBuyPass");
+ view_listener_t::addMenu(new LLLandEnableBuyPass(), "Land.EnableBuyPass");
// Generic actions
- addMenu(new LLShowFloater(), "ShowFloater");
- addMenu(new LLPromptShowURL(), "PromptShowURL");
- addMenu(new LLShowAgentProfile(), "ShowAgentProfile");
- addMenu(new LLShowAgentGroups(), "ShowAgentGroups");
- addMenu(new LLToggleControl(), "ToggleControl");
-
- addMenu(new LLGoToObject(), "GoToObject");
- addMenu(new LLPayObject(), "PayObject");
-
- addMenu(new LLEnablePayObject(), "EnablePayObject");
- addMenu(new LLEnableEdit(), "EnableEdit");
-
- addMenu(new LLFloaterVisible(), "FloaterVisible");
- addMenu(new LLSomethingSelected(), "SomethingSelected");
- addMenu(new LLSomethingSelectedNoHUD(), "SomethingSelectedNoHUD");
- addMenu(new LLEditableSelected(), "EditableSelected");
- addMenu(new LLEditableSelectedMono(), "EditableSelectedMono");
+ view_listener_t::addMenu(new LLShowFloater(), "ShowFloater");
+ view_listener_t::addMenu(new LLPromptShowURL(), "PromptShowURL");
+ view_listener_t::addMenu(new LLShowAgentProfile(), "ShowAgentProfile");
+ view_listener_t::addMenu(new LLToggleControl(), "ToggleControl");
+ view_listener_t::addMenu(new LLCheckControl(), "CheckControl");
+ view_listener_t::addMenu(new LLGoToObject(), "GoToObject");
+ view_listener_t::addMenu(new LLPayObject(), "PayObject");
+
+ view_listener_t::addMenu(new LLEnablePayObject(), "EnablePayObject");
+ view_listener_t::addMenu(new LLEnableEdit(), "EnableEdit");
+
+ view_listener_t::addMenu(new LLFloaterVisible(), "FloaterVisible");
+ view_listener_t::addMenu(new LLSomethingSelected(), "SomethingSelected");
+ view_listener_t::addMenu(new LLSomethingSelectedNoHUD(), "SomethingSelectedNoHUD");
+ view_listener_t::addMenu(new LLEditableSelected(), "EditableSelected");
+ view_listener_t::addMenu(new LLEditableSelectedMono(), "EditableSelectedMono");
+
}
diff --git a/indra/newview/llviewermenu.h b/indra/newview/llviewermenu.h
index e9fedf37d8..cf482266d6 100644
--- a/indra/newview/llviewermenu.h
+++ b/indra/newview/llviewermenu.h
@@ -34,6 +34,7 @@
#define LL_LLVIEWERMENU_H
#include "llmenugl.h"
+#include "llsafehandle.h"
//newview includes
#include "llfilepicker.h"
@@ -44,11 +45,11 @@ class LLParcelSelection;
class LLObjectSelection;
-void pre_init_menus();
void init_menus();
void cleanup_menus();
void show_debug_menus(); // checks for if menus should be shown first.
+void toggle_debug_menus(void*);
void show_context_menu( S32 x, S32 y, MASK mask );
void show_build_mode_context_menu(S32 x, S32 y, MASK mask);
BOOL enable_save_into_inventory(void*);
@@ -75,37 +76,30 @@ BOOL enable_deselect(void*);
BOOL enable_undo(void*);
BOOL enable_redo(void*);
-// returns TRUE if we have a friend relationship with agent_id
-BOOL is_agent_friend(const LLUUID& agent_id);
BOOL is_agent_mappable(const LLUUID& agent_id);
-void menu_toggle_control( void* user_data );
void confirm_replace_attachment(S32 option, void* user_data);
-void handle_detach_from_avatar(void* user_data);
-void attach_label(std::string& label, void* user_data);
-void detach_label(std::string& label, void* user_data);
-BOOL object_selected_and_point_valid(void* user_data);
-BOOL object_attached(void* user_data);
+void handle_detach_from_avatar(const LLSD& user_data);
+void attach_label(std::string& label, const LLSD&);
+void detach_label(std::string& label, const LLSD&);
+BOOL object_selected_and_point_valid(const LLSD&);
void handle_detach(void*);
BOOL enable_god_full(void* user_data);
BOOL enable_god_liaison(void* user_data);
BOOL enable_god_customer_service(void* user_data);
BOOL enable_god_basic(void* user_data);
-void handle_show_newest_map(void*);
void set_underclothes_menu_options();
void exchange_callingcard(const LLUUID& dest_id);
void handle_gestures(void*);
void handle_sit_down(void*);
-bool toggle_build_mode();
void handle_object_build(void*);
void handle_save_snapshot(void *);
void handle_toggle_flycam();
bool handle_sit_or_stand();
bool handle_give_money_dialog();
-bool handle_object_open();
bool handle_go_to();
// Export to XML or Collada
@@ -119,8 +113,6 @@ class LLPermissions;
class LLViewerMenuHolderGL : public LLMenuHolderGL
{
public:
- LLViewerMenuHolderGL();
-
virtual BOOL hideMenus();
void setParcelSelection(LLSafeHandle<LLParcelSelection> selection);
@@ -142,30 +134,31 @@ extern LLViewerMenuHolderGL* gMenuHolder;
extern LLMenuBarGL* gLoginMenuBarView;
// Pie menus
-extern LLPieMenu *gPieSelf;
-extern LLPieMenu *gPieAvatar;
-extern LLPieMenu *gPieObject;
-extern LLPieMenu *gPieAttachment;
-extern LLPieMenu *gPieLand;
-extern LLPieMenu* gPieRate;
+extern LLContextMenu *gPieSelf;
+extern LLContextMenu *gPieAvatar;
+extern LLContextMenu *gPieObject;
+extern LLContextMenu *gPieAttachment;
+
+extern LLContextMenu *gPieLand;
+extern LLContextMenu *gPieRate;
// Pie menus
-extern LLPieMenu *gPieSelfSimple;
-extern LLPieMenu *gPieAvatarSimple;
-extern LLPieMenu *gPieObjectSimple;
-extern LLPieMenu *gPieAttachmentSimple;
-extern LLPieMenu *gPieLandSimple;
+extern LLContextMenu *gPieSelfSimple;
+extern LLContextMenu *gPieAvatarSimple;
+extern LLContextMenu *gPieObjectSimple;
+extern LLContextMenu *gPieAttachmentSimple;
+extern LLContextMenu *gPieLandSimple;
// Needed to build menus when attachment site list available
extern LLMenuGL* gAttachSubMenu;
extern LLMenuGL* gDetachSubMenu;
extern LLMenuGL* gTakeOffClothes;
-extern LLPieMenu* gAttachScreenPieMenu;
-extern LLPieMenu* gDetachScreenPieMenu;
-extern LLPieMenu* gAttachPieMenu;
-extern LLPieMenu* gDetachPieMenu;
-extern LLPieMenu* gAttachBodyPartPieMenus[8];
-extern LLPieMenu* gDetachBodyPartPieMenus[8];
+extern LLContextMenu* gAttachScreenPieMenu;
+extern LLContextMenu* gDetachScreenPieMenu;
+extern LLContextMenu* gAttachPieMenu;
+extern LLContextMenu* gDetachPieMenu;
+extern LLContextMenu* gAttachBodyPartPieMenus[8];
+extern LLContextMenu* gDetachBodyPartPieMenus[8];
extern LLMenuItemCallGL* gAFKMenu;
extern LLMenuItemCallGL* gBusyMenu;
diff --git a/indra/newview/llviewermenufile.cpp b/indra/newview/llviewermenufile.cpp
index d1f50212db..1cfeec5627 100644
--- a/indra/newview/llviewermenufile.cpp
+++ b/indra/newview/llviewermenufile.cpp
@@ -37,62 +37,54 @@
// project includes
#include "llagent.h"
#include "llfilepicker.h"
-#include "llfloateranimpreview.h"
+#include "llfloaterreg.h"
#include "llfloaterbuycurrency.h"
-#include "llfloaterimagepreview.h"
-#include "llfloaternamedesc.h"
#include "llfloatersnapshot.h"
#include "llinventorymodel.h" // gInventory
#include "llresourcedata.h"
#include "llfloaterperms.h"
#include "llstatusbar.h"
#include "llviewercontrol.h" // gSavedSettings
-#include "llviewerimagelist.h"
+#include "llviewertexturelist.h"
#include "lluictrlfactory.h"
+#include "llviewerinventory.h"
#include "llviewermenu.h" // gMenuHolder
#include "llviewerregion.h"
#include "llviewerstats.h"
#include "llviewerwindow.h"
#include "llappviewer.h"
#include "lluploaddialog.h"
+#include "lltrans.h"
// linden libraries
#include "llassetuploadresponders.h"
#include "lleconomy.h"
#include "llhttpclient.h"
-#include "llmemberlistener.h"
#include "llsdserialize.h"
#include "llstring.h"
#include "lltransactiontypes.h"
#include "lluuid.h"
-#include "vorbisencode.h"
+#include "llvorbisencode.h"
// system libraries
#include <boost/tokenizer.hpp>
-using namespace LLOldEvents;
-
-typedef LLMemberListener<LLView> view_listener_t;
-
-
class LLFileEnableSaveAs : public view_listener_t
{
- bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
+ bool handleEvent(const LLSD& userdata)
{
bool new_value = gFloaterView->getFrontmost() && gFloaterView->getFrontmost()->canSaveAs();
- gMenuHolder->findControl(userdata["control"].asString())->setValue(new_value);
- return true;
+ return new_value;
}
};
class LLFileEnableUpload : public view_listener_t
{
- bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
+ bool handleEvent(const LLSD& userdata)
{
bool new_value = gStatusBar && LLGlobalEconomy::Singleton::getInstance() && (gStatusBar->getBalance() >= LLGlobalEconomy::Singleton::getInstance()->getPriceUpload());
- gMenuHolder->findControl(userdata["control"].asString())->setValue(new_value);
- return true;
+ return new_value;
}
};
@@ -255,13 +247,12 @@ const std::string upload_pick(void* data)
class LLFileUploadImage : public view_listener_t
{
- bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
+ bool handleEvent(const LLSD& userdata)
{
std::string filename = upload_pick((void *)LLFilePicker::FFLOAD_IMAGE);
if (!filename.empty())
{
- LLFloaterImagePreview* floaterp = new LLFloaterImagePreview(filename);
- LLUICtrlFactory::getInstance()->buildFloater(floaterp, "floater_image_preview.xml");
+ LLFloaterReg::showInstance("upload_image", LLSD(filename));
}
return TRUE;
}
@@ -269,14 +260,12 @@ class LLFileUploadImage : public view_listener_t
class LLFileUploadSound : public view_listener_t
{
- bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
+ bool handleEvent(const LLSD& userdata)
{
std::string filename = upload_pick((void*)LLFilePicker::FFLOAD_WAV);
if (!filename.empty())
{
- LLFloaterNameDesc* floaterp = new LLFloaterNameDesc(filename);
- LLUICtrlFactory::getInstance()->buildFloater(floaterp, "floater_sound_preview.xml");
- floaterp->childSetLabelArg("ok_btn", "[AMOUNT]", llformat("%d", LLGlobalEconomy::Singleton::getInstance()->getPriceUpload() ));
+ LLFloaterReg::showInstance("upload_sound", LLSD(filename));
}
return true;
}
@@ -284,13 +273,12 @@ class LLFileUploadSound : public view_listener_t
class LLFileUploadAnim : public view_listener_t
{
- bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
+ bool handleEvent(const LLSD& userdata)
{
const std::string filename = upload_pick((void*)LLFilePicker::FFLOAD_ANIM);
if (!filename.empty())
{
- LLFloaterAnimPreview* floaterp = new LLFloaterAnimPreview(filename);
- LLUICtrlFactory::getInstance()->buildFloater(floaterp, "floater_animation_preview.xml");
+ LLFloaterReg::showInstance("upload_anim", LLSD(filename));
}
return true;
}
@@ -298,7 +286,7 @@ class LLFileUploadAnim : public view_listener_t
class LLFileUploadBulk : public view_listener_t
{
- bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
+ bool handleEvent(const LLSD& userdata)
{
if( gAgent.cameraMouselook() )
{
@@ -360,19 +348,16 @@ void upload_error(const std::string& error_message, const std::string& label, co
class LLFileEnableCloseWindow : public view_listener_t
{
- bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
+ bool handleEvent(const LLSD& userdata)
{
bool new_value = NULL != LLFloater::getClosableFloaterFromFocus();
-
- // horrendously opaque, this code
- gMenuHolder->findControl(userdata["control"].asString())->setValue(new_value);
- return true;
+ return new_value;
}
};
class LLFileCloseWindow : public view_listener_t
{
- bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
+ bool handleEvent(const LLSD& userdata)
{
LLFloater::closeFocusedFloater();
@@ -382,17 +367,16 @@ class LLFileCloseWindow : public view_listener_t
class LLFileEnableCloseAllWindows : public view_listener_t
{
- bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
+ bool handleEvent(const LLSD& userdata)
{
bool open_children = gFloaterView->allChildrenClosed();
- gMenuHolder->findControl(userdata["control"].asString())->setValue(!open_children);
- return true;
+ return !open_children;
}
};
class LLFileCloseAllWindows : public view_listener_t
{
- bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
+ bool handleEvent(const LLSD& userdata)
{
bool app_quitting = false;
gFloaterView->closeAllChildren(app_quitting);
@@ -403,7 +387,7 @@ class LLFileCloseAllWindows : public view_listener_t
class LLFileSaveTexture : public view_listener_t
{
- bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
+ bool handleEvent(const LLSD& userdata)
{
LLFloater* top = gFloaterView->getFrontmost();
if (top)
@@ -414,18 +398,9 @@ class LLFileSaveTexture : public view_listener_t
}
};
-class LLFileTakeSnapshot : public view_listener_t
-{
- bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
- {
- LLFloaterSnapshot::show(NULL);
- return true;
- }
-};
-
class LLFileTakeSnapshotToDisk : public view_listener_t
{
- bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
+ bool handleEvent(const LLSD& userdata)
{
LLPointer<LLImageRaw> raw = new LLImageRaw;
@@ -477,23 +452,13 @@ class LLFileTakeSnapshotToDisk : public view_listener_t
class LLFileQuit : public view_listener_t
{
- bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
+ bool handleEvent(const LLSD& userdata)
{
LLAppViewer::instance()->userQuit();
return true;
}
};
-void handle_upload(void* data)
-{
- const std::string filename = upload_pick(data);
- if (!filename.empty())
- {
- LLFloaterNameDesc* floaterp = new LLFloaterNameDesc(filename);
- LLUICtrlFactory::getInstance()->buildFloater(floaterp, "floater_name_description.xml");
- floaterp->childSetLabelArg("ok_btn", "[AMOUNT]", llformat("%d", LLGlobalEconomy::Singleton::getInstance()->getPriceUpload() ));
- }
-}
void handle_compress_image(void*)
{
@@ -510,7 +475,7 @@ void handle_compress_image(void*)
BOOL success;
- success = LLViewerImageList::createUploadFile(infile, outfile, IMG_CODEC_TGA);
+ success = LLViewerTextureList::createUploadFile(infile, outfile, IMG_CODEC_TGA);
if (success)
{
@@ -566,7 +531,7 @@ void upload_new_resource(const std::string& src_filename, std::string name,
else if( exten == "bmp")
{
asset_type = LLAssetType::AT_TEXTURE;
- if (!LLViewerImageList::createUploadFile(src_filename,
+ if (!LLViewerTextureList::createUploadFile(src_filename,
filename,
IMG_CODEC_BMP ))
{
@@ -581,7 +546,7 @@ void upload_new_resource(const std::string& src_filename, std::string name,
else if( exten == "tga")
{
asset_type = LLAssetType::AT_TEXTURE;
- if (!LLViewerImageList::createUploadFile(src_filename,
+ if (!LLViewerTextureList::createUploadFile(src_filename,
filename,
IMG_CODEC_TGA ))
{
@@ -596,7 +561,7 @@ void upload_new_resource(const std::string& src_filename, std::string name,
else if( exten == "jpg" || exten == "jpeg")
{
asset_type = LLAssetType::AT_TEXTURE;
- if (!LLViewerImageList::createUploadFile(src_filename,
+ if (!LLViewerTextureList::createUploadFile(src_filename,
filename,
IMG_CODEC_JPEG ))
{
@@ -611,7 +576,7 @@ void upload_new_resource(const std::string& src_filename, std::string name,
else if( exten == "png")
{
asset_type = LLAssetType::AT_TEXTURE;
- if (!LLViewerImageList::createUploadFile(src_filename,
+ if (!LLViewerTextureList::createUploadFile(src_filename,
filename,
IMG_CODEC_PNG ))
{
@@ -777,8 +742,7 @@ void upload_new_resource(const std::string& src_filename, std::string name,
else
{
// Unknown extension
- // *TODO: Translate?
- error_message = llformat("Unknown file extension .%s\nExpected .wav, .tga, .bmp, .jpg, .jpeg, or .bvh", exten.c_str());
+ error_message = llformat(LLTrans::getString("UnknownFileExtension").c_str(), exten.c_str());
error = TRUE;;
}
@@ -858,9 +822,9 @@ void upload_done_callback(const LLUUID& uuid, void* user_data, S32 result, LLExt
if(!(can_afford_transaction(expected_upload_cost)))
{
LLFloaterBuyCurrency::buyCurrency(
- llformat("Uploading %s costs",
- data->mAssetInfo.getName().c_str()), // *TODO: Translate
- expected_upload_cost);
+ llformat(LLTrans::getString("UploadingCosts").c_str(),
+ data->mAssetInfo.getName().c_str()),
+ expected_upload_cost);
is_balance_sufficient = FALSE;
}
else if(region)
@@ -1075,22 +1039,20 @@ void upload_new_resource(const LLTransactionID &tid, LLAssetType::EType asset_ty
}
}
-
void init_menu_file()
{
- (new LLFileUploadImage())->registerListener(gMenuHolder, "File.UploadImage");
- (new LLFileUploadSound())->registerListener(gMenuHolder, "File.UploadSound");
- (new LLFileUploadAnim())->registerListener(gMenuHolder, "File.UploadAnim");
- (new LLFileUploadBulk())->registerListener(gMenuHolder, "File.UploadBulk");
- (new LLFileCloseWindow())->registerListener(gMenuHolder, "File.CloseWindow");
- (new LLFileCloseAllWindows())->registerListener(gMenuHolder, "File.CloseAllWindows");
- (new LLFileEnableCloseWindow())->registerListener(gMenuHolder, "File.EnableCloseWindow");
- (new LLFileEnableCloseAllWindows())->registerListener(gMenuHolder, "File.EnableCloseAllWindows");
- (new LLFileSaveTexture())->registerListener(gMenuHolder, "File.SaveTexture");
- (new LLFileTakeSnapshot())->registerListener(gMenuHolder, "File.TakeSnapshot");
- (new LLFileTakeSnapshotToDisk())->registerListener(gMenuHolder, "File.TakeSnapshotToDisk");
- (new LLFileQuit())->registerListener(gMenuHolder, "File.Quit");
-
- (new LLFileEnableUpload())->registerListener(gMenuHolder, "File.EnableUpload");
- (new LLFileEnableSaveAs())->registerListener(gMenuHolder, "File.EnableSaveAs");
+ view_listener_t::addCommit(new LLFileUploadImage(), "File.UploadImage");
+ view_listener_t::addCommit(new LLFileUploadSound(), "File.UploadSound");
+ view_listener_t::addCommit(new LLFileUploadAnim(), "File.UploadAnim");
+ view_listener_t::addCommit(new LLFileUploadBulk(), "File.UploadBulk");
+ view_listener_t::addCommit(new LLFileCloseWindow(), "File.CloseWindow");
+ view_listener_t::addCommit(new LLFileCloseAllWindows(), "File.CloseAllWindows");
+ view_listener_t::addEnable(new LLFileEnableCloseWindow(), "File.EnableCloseWindow");
+ view_listener_t::addEnable(new LLFileEnableCloseAllWindows(), "File.EnableCloseAllWindows");
+ view_listener_t::addCommit(new LLFileSaveTexture(), "File.SaveTexture");
+ view_listener_t::addCommit(new LLFileTakeSnapshotToDisk(), "File.TakeSnapshotToDisk");
+ view_listener_t::addCommit(new LLFileQuit(), "File.Quit");
+
+ view_listener_t::addEnable(new LLFileEnableUpload(), "File.EnableUpload");
+ view_listener_t::addEnable(new LLFileEnableSaveAs(), "File.EnableSaveAs");
}
diff --git a/indra/newview/llviewermessage.cpp b/indra/newview/llviewermessage.cpp
index 7664d7ee07..28e20d92d0 100644
--- a/indra/newview/llviewermessage.cpp
+++ b/indra/newview/llviewermessage.cpp
@@ -37,7 +37,7 @@
#include <deque>
-#include "audioengine.h"
+#include "llaudioengine.h"
#include "indra_constants.h"
#include "lscript_byteformat.h"
#include "mean_collision_data.h"
@@ -48,6 +48,7 @@
#include "lldbstrings.h"
#include "lleconomy.h"
#include "llfilepicker.h"
+#include "llfloaterreg.h"
#include "llfocusmgr.h"
#include "llfollowcamparams.h"
#include "llinstantmessage.h"
@@ -77,7 +78,6 @@
#include "llfloaterbuycurrency.h"
#include "llfloaterbuyland.h"
#include "llfloaterchat.h"
-#include "llfloatergroupinfo.h"
#include "llfloaterimagepreview.h"
#include "llfloaterland.h"
#include "llfloaterregioninfo.h"
@@ -93,13 +93,15 @@
#include "llhudmanager.h"
#include "llimpanel.h"
#include "llinventorymodel.h"
-#include "llinventoryview.h"
+#include "llfloaterinventory.h"
#include "llmenugl.h"
+#include "llmoveview.h"
#include "llmutelist.h"
#include "llnotifications.h"
#include "llnotify.h"
#include "llpanelgrouplandmoney.h"
#include "llselectmgr.h"
+#include "llsidetray.h"
#include "llstartup.h"
#include "llsky.h"
#include "llstatenums.h"
@@ -125,7 +127,7 @@
#include "llviewerthrottle.h"
#include "llviewerwindow.h"
#include "llvlmanager.h"
-#include "llvoavatar.h"
+#include "llvoavatarself.h"
#include "llvotextbubble.h"
#include "llweb.h"
#include "llworld.h"
@@ -134,13 +136,19 @@
#include "llfloaterworldmap.h"
#include "llviewerdisplay.h"
#include "llkeythrottle.h"
+#include "llgroupactions.h"
+#include "llagentui.h"
#include <boost/tokenizer.hpp>
+#include <boost/algorithm/string/split.hpp>
#if LL_WINDOWS // For Windows specific error handler
#include "llwindebug.h" // For the invalid message handler
#endif
+//#include "llnearbychathistory.h"
+#include "llnotificationmanager.h"
+
//
// Constants
//
@@ -160,7 +168,7 @@ void open_offer(const std::vector<LLUUID>& items, const std::string& from_name);
bool check_offer_throttle(const std::string& from_name, bool check_only);
void callbackCacheEstateOwnerName(const LLUUID& id,
const std::string& first, const std::string& last,
- BOOL is_group, void*);
+ BOOL is_group);
//inventory offer throttle globals
LLFrameTimer gThrottleTimer;
@@ -204,6 +212,10 @@ bool friendship_offer_callback(const LLSD& notification, const LLSD& response)
LLUUID fid;
LLMessageSystem* msg = gMessageSystem;
const LLSD& payload = notification["payload"];
+
+ // add friend to recent people list
+ LLRecentPeople::instance().add(payload["from_id"]);
+
switch(option)
{
case 0:
@@ -630,7 +642,7 @@ bool join_group_response(const LLSD& notification, const LLSD& response)
if (option == 2 && !group_id.isNull())
{
- LLFloaterGroupInfo::showFromUUID(group_id);
+ LLGroupActions::show(group_id);
LLSD args;
args["MESSAGE"] = message;
LLNotifications::instance().add("JoinGroup", args, notification["payload"]);
@@ -867,13 +879,14 @@ void open_offer(const std::vector<LLUUID>& items, const std::string& from_name)
LLInventoryItem* item;
for(; it != end; ++it)
{
- item = gInventory.getItem(*it);
+ const LLUUID& id = *it;
+ item = gInventory.getItem(id);
if(!item)
{
- LL_WARNS("Messaging") << "Unable to show inventory item: " << *it << LL_ENDL;
+ LL_WARNS("Messaging") << "Unable to show inventory item: " << id << LL_ENDL;
continue;
}
- if(gInventory.isObjectDescendentOf(*it, trash_id))
+ if(gInventory.isObjectDescendentOf(id, trash_id))
{
continue;
}
@@ -882,40 +895,55 @@ void open_offer(const std::vector<LLUUID>& items, const std::string& from_name)
//if we are throttled, don't display them
if (check_offer_throttle(from_name, false))
{
- // I'm not sure this is a good idea.
- bool show_keep_discard = item->getPermissions().getCreator() != gAgent.getID();
- //bool show_keep_discard = true;
+ // If we opened this ourselves, focus it
+ BOOL take_focus = from_name.empty() ? TAKE_FOCUS_YES : TAKE_FOCUS_NO;
switch(asset_type)
{
- case LLAssetType::AT_NOTECARD:
- open_notecard((LLViewerInventoryItem*)item, std::string("Note: ") + item->getName(), LLUUID::null, show_keep_discard, LLUUID::null, FALSE);
+ case LLAssetType::AT_NOTECARD:
+ LLFloaterReg::showInstance("preview_notecard", LLSD(id), take_focus);
break;
- case LLAssetType::AT_LANDMARK:
- open_landmark((LLViewerInventoryItem*)item, std::string("Landmark: ") + item->getName(), show_keep_discard, LLUUID::null, FALSE);
+ case LLAssetType::AT_LANDMARK:
+ {
+ LLInventoryCategory* parent_folder = gInventory.getCategory(item->getParentUUID());
+ LLSD args;
+ args["LANDMARK_NAME"] = item->getName();
+ args["FOLDER_NAME"] = std::string(parent_folder ? parent_folder->getName() : "unnkown");
+ LLNotifications::instance().add("LandmarkCreated", args);
+
+ // Open new landmark for editing in Places panel.
+ LLSD key;
+ key["type"] = "landmark";
+ key["id"] = item->getUUID();
+ LLSideTray::getInstance()->showPanel("panel_places", key);
+ }
break;
- case LLAssetType::AT_TEXTURE:
- open_texture(*it, std::string("Texture: ") + item->getName(), show_keep_discard, LLUUID::null, FALSE);
+ case LLAssetType::AT_TEXTURE:
+ LLFloaterReg::showInstance("preview_texture", LLSD(id), take_focus);
break;
- default:
+ default:
break;
}
}
//highlight item, if it's not in the trash or lost+found
// Don't auto-open the inventory floater
- LLInventoryView* view = LLInventoryView::getActiveInventory();
- if(!view)
- {
- return;
- }
-
+ LLFloaterInventory* view = NULL;
if(gSavedSettings.getBOOL("ShowInInventory") &&
asset_type != LLAssetType::AT_CALLINGCARD &&
item->getInventoryType() != LLInventoryType::IT_ATTACHMENT &&
!from_name.empty())
{
- LLInventoryView::showAgentInventory(TRUE);
+ view = LLFloaterInventory::showAgentInventory();
+ }
+ else
+ {
+ view = LLFloaterInventory::getActiveInventory();
+ }
+ if(!view)
+ {
+ return;
}
+
//Trash Check
LLUUID trash_id;
trash_id = gInventory.findCategoryUUIDForType(LLAssetType::AT_TRASH);
@@ -941,17 +969,19 @@ void open_offer(const std::vector<LLUUID>& items, const std::string& from_name)
LL_DEBUGS("Messaging") << "Highlighting" << item->getUUID() << LL_ENDL;
//highlight item
- LLUICtrl* focus_ctrl = gFocusMgr.getKeyboardFocus();
- view->getPanel()->setSelection(item->getUUID(), TAKE_FOCUS_NO);
- gFocusMgr.setKeyboardFocus(focus_ctrl);
+ if (view->getPanel())
+ {
+ LLFocusableElement* focus_ctrl = gFocusMgr.getKeyboardFocus();
+ view->getPanel()->setSelection(item->getUUID(), TAKE_FOCUS_NO);
+ gFocusMgr.setKeyboardFocus(focus_ctrl);
+ }
}
}
void inventory_offer_mute_callback(const LLUUID& blocked_id,
const std::string& first_name,
const std::string& last_name,
- BOOL is_group,
- void* user_data)
+ BOOL is_group)
{
std::string from_name;
LLMute::EType type;
@@ -970,8 +1000,9 @@ void inventory_offer_mute_callback(const LLUUID& blocked_id,
LLMute mute(blocked_id, from_name, type);
if (LLMuteList::getInstance()->add(mute))
{
- LLFloaterMute::showInstance();
- LLFloaterMute::getInstance()->selectMute(blocked_id);
+ LLFloaterReg::showInstance("mute");
+ LLFloaterMute* mute_instance = LLFloaterReg::getTypedInstance<LLFloaterMute>("mute");
+ if(mute_instance) mute_instance->selectMute(blocked_id);
}
// purge the message queue of any previously queued inventory offers from the same source.
@@ -1040,7 +1071,7 @@ bool LLOfferInfo::inventory_offer_callback(const LLSD& notification, const LLSD&
// * we can't build two messages at once.
if (2 == button)
{
- gCacheName->getNameFromUUID(mFromID, mFromGroup, inventory_offer_mute_callback, this);
+ gCacheName->get(mFromID, mFromGroup, &inventory_offer_mute_callback);
}
LLMessageSystem* msg = gMessageSystem;
@@ -1055,7 +1086,7 @@ bool LLOfferInfo::inventory_offer_callback(const LLSD& notification, const LLSD&
msg->addUUIDFast(_PREHASH_ID, mTransactionID);
msg->addU32Fast(_PREHASH_Timestamp, NO_TIMESTAMP); // no timestamp necessary
std::string name;
- gAgent.buildFullname(name);
+ LLAgentUI::buildFullname(name);
msg->addStringFast(_PREHASH_FromAgentName, name);
msg->addStringFast(_PREHASH_Message, "");
msg->addU32Fast(_PREHASH_ParentEstateID, 0);
@@ -1070,7 +1101,6 @@ bool LLOfferInfo::inventory_offer_callback(const LLSD& notification, const LLSD&
itemp = (LLViewerInventoryItem*)gInventory.getItem(mObjectID);
}
- // *TODO:translate
std::string from_string; // Used in the pop-up.
std::string chatHistory_string; // Used in chat history.
if (mFromObject == TRUE)
@@ -1080,13 +1110,18 @@ bool LLOfferInfo::inventory_offer_callback(const LLSD& notification, const LLSD&
std::string group_name;
if (gCacheName->getGroupName(mFromID, group_name))
{
- from_string = std::string("An object named '") + mFromName + "' owned by the group '" + group_name + "'";
- chatHistory_string = mFromName + " owned by the group '" + group_name + "'";
+ from_string = LLTrans::getString("InvOfferAnObjectNamed") + " "+"'"
+ + mFromName + LLTrans::getString("'") +" " + LLTrans::getString("InvOfferOwnedByGroup")
+ + " "+ "'" + group_name + "'";
+
+ chatHistory_string = mFromName + " " + LLTrans::getString("InvOfferOwnedByGroup")
+ + " " + group_name + "'";
}
else
{
- from_string = std::string("An object named '") + mFromName + "' owned by an unknown group";
- chatHistory_string = mFromName + " owned by an unknown group";
+ from_string = LLTrans::getString("InvOfferAnObjectNamed") + " "+"'"
+ + mFromName +"'"+ " " + LLTrans::getString("InvOfferOwnedByUnknownGroup");
+ chatHistory_string = mFromName + " " + LLTrans::getString("InvOfferOwnedByUnknownGroup");
}
}
else
@@ -1094,13 +1129,15 @@ bool LLOfferInfo::inventory_offer_callback(const LLSD& notification, const LLSD&
std::string first_name, last_name;
if (gCacheName->getName(mFromID, first_name, last_name))
{
- from_string = std::string("An object named '") + mFromName + "' owned by " + first_name + " " + last_name;
- chatHistory_string = mFromName + " owned by " + first_name + " " + last_name;
+ from_string = LLTrans::getString("InvOfferAnObjectNamed") + " "+ LLTrans::getString("'") + mFromName
+ + LLTrans::getString("'")+" " + LLTrans::getString("InvOfferOwnedBy") + first_name + " " + last_name;
+ chatHistory_string = mFromName + " " + LLTrans::getString("InvOfferOwnedBy") + " " + first_name + " " + last_name;
}
else
{
- from_string = std::string("An object named '") + mFromName + "' owned by an unknown user";
- chatHistory_string = mFromName + " owned by an unknown user";
+ from_string = LLTrans::getString("InvOfferAnObjectNamed") + " "+LLTrans::getString("'")
+ + mFromName + LLTrans::getString("'")+" " + LLTrans::getString("InvOfferOwnedByUnknownUser");
+ chatHistory_string = mFromName + " " + LLTrans::getString("InvOfferOwnedByUnknownUser");
}
}
}
@@ -1128,7 +1165,7 @@ bool LLOfferInfo::inventory_offer_callback(const LLSD& notification, const LLSD&
//don't spam them if they are getting flooded
if (check_offer_throttle(mFromName, true))
{
- log_message = chatHistory_string + " gave you " + mDesc + ".";
+ log_message = chatHistory_string + " " + LLTrans::getString("InvOfferGaveYou") + " " + mDesc + LLTrans::getString(".");
chat.mText = log_message;
LLFloaterChat::addChatHistory(chat);
}
@@ -1191,7 +1228,7 @@ bool LLOfferInfo::inventory_offer_callback(const LLSD& notification, const LLSD&
// send the message
msg->sendReliable(mHost);
- log_message = "You decline " + mDesc + " from " + mFromName + ".";
+ log_message = LLTrans::getString("InvOfferYouDecline") + " " + mDesc + " " + LLTrans::getString("InvOfferFrom") + " " + mFromName +".";
chat.mText = log_message;
if( LLMuteList::getInstance()->isMuted(mFromID ) && ! LLMuteList::getInstance()->isLinden(mFromName) ) // muting for SL-42269
{
@@ -1227,15 +1264,17 @@ bool LLOfferInfo::inventory_offer_callback(const LLSD& notification, const LLSD&
break;
}
+ if(IM_INVENTORY_OFFERED == mIM)
+ {
+ // add buddy to recent people list
+ LLRecentPeople::instance().add(mFromID);
+ }
+
if(opener)
{
gInventory.addObserver(opener);
}
- // Allow these to stack up, but once you deal with one, reset the
- // position.
- gFloaterView->resetStartingFloaterPosition();
-
delete this;
return false;
}
@@ -1329,7 +1368,7 @@ void inventory_offer_handler(LLOfferInfo* info, BOOL from_task)
args["NAME"] = info->mFromName;
LLNotification::Params p("ObjectGiveItem");
- p.substitutions(args).payload(payload).functor(boost::bind(&LLOfferInfo::inventory_offer_callback, info, _1, _2));
+ p.substitutions(args).payload(payload).functor.function(boost::bind(&LLOfferInfo::inventory_offer_callback, info, _1, _2));
if (from_task)
{
@@ -1415,7 +1454,7 @@ void process_improved_im(LLMessageSystem *msg, void **user_data)
LLChat chat;
std::string buffer;
- // *TODO:translate - need to fix the full name to first/last (maybe)
+ // *TODO: Translate - need to fix the full name to first/last (maybe)
msg->getUUIDFast(_PREHASH_AgentData, _PREHASH_AgentID, from_id);
msg->getBOOLFast(_PREHASH_MessageBlock, _PREHASH_FromGroup, from_group);
msg->getUUIDFast(_PREHASH_MessageBlock, _PREHASH_ToAgentID, to_id);
@@ -1437,6 +1476,8 @@ void process_improved_im(LLMessageSystem *msg, void **user_data)
BOOL is_muted = LLMuteList::getInstance()->isMuted(from_id, name, LLMute::flagTextChat);
BOOL is_linden = LLMuteList::getInstance()->isLinden(name);
BOOL is_owned_by_me = FALSE;
+ BOOL is_friend = (LLAvatarTracker::instance().getBuddyInfo(from_id) == NULL) ? false : true;
+ BOOL accept_im_from_only_friend = gSavedSettings.getBOOL("VoiceCallsFriendsOnly");
chat.mMuted = is_muted && !is_linden;
chat.mFromID = from_id;
@@ -1466,7 +1507,7 @@ void process_improved_im(LLMessageSystem *msg, void **user_data)
case IM_CONSOLE_AND_CHAT_HISTORY:
// These are used for system messages, hence don't need the name,
// as it is always "Second Life".
- // *TODO:translate
+ // *TODO: Translate
args["MESSAGE"] = message;
// Note: don't put the message in the IM history, even though was sent
@@ -1492,7 +1533,7 @@ void process_improved_im(LLMessageSystem *msg, void **user_data)
// if there is not a panel for this conversation (i.e. it is a new IM conversation
// initiated by the other party) then...
std::string my_name;
- gAgent.buildFullname(my_name);
+ LLAgentUI::buildFullname(my_name);
std::string response = gSavedPerAccountSettings.getString("BusyModeResponse2");
pack_instant_message(
gMessageSystem,
@@ -1510,7 +1551,7 @@ void process_improved_im(LLMessageSystem *msg, void **user_data)
// now store incoming IM in chat history
- buffer = separator_string + message.substr(message_offset);
+ buffer = message.substr(message_offset);
LL_INFOS("Messaging") << "process_improved_im: session_id( " << session_id << " ), from_id( " << from_id << " )" << LL_ENDL;
@@ -1560,11 +1601,16 @@ void process_improved_im(LLMessageSystem *msg, void **user_data)
{
saved = llformat("(Saved %s) ", formatted_time(timestamp).c_str());
}
- buffer = separator_string + saved + message.substr(message_offset);
+ buffer = saved + message.substr(message_offset);
LL_INFOS("Messaging") << "process_improved_im: session_id( " << session_id << " ), from_id( " << from_id << " )" << LL_ENDL;
- if (!is_muted || is_linden)
+ bool mute_im = is_muted;
+ if(accept_im_from_only_friend&&!is_friend)
+ {
+ mute_im = true;
+ }
+ if (!mute_im || is_linden)
{
gIMMgr->addMessage(
session_id,
@@ -1611,7 +1657,7 @@ void process_improved_im(LLMessageSystem *msg, void **user_data)
case IM_MESSAGEBOX:
{
// This is a block, modeless dialog.
- //*TODO:translate
+ //*TODO: Translate
args["MESSAGE"] = message;
LLNotifications::instance().add("SystemMessage", args);
}
@@ -1698,13 +1744,14 @@ void process_improved_im(LLMessageSystem *msg, void **user_data)
LLSD args;
args["SUBJECT"] = subj;
args["MESSAGE"] = mes;
- LLNotifications::instance().add(LLNotification::Params("GroupNotice").substitutions(args).payload(payload).timestamp(timestamp));
+ LLNotifications::instance().add(LLNotification::Params("GroupNotice").substitutions(args).payload(payload).time_stamp(timestamp));
}
// Also send down the old path for now.
if (IM_GROUP_NOTICE_REQUESTED == dialog)
{
- LLFloaterGroupInfo::showNotice(subj,mes,group_id,has_inventory,item_name,info);
+
+ LLPanelGroup::showNotice(subj,mes,group_id,has_inventory,item_name,info);
}
}
break;
@@ -1755,7 +1802,7 @@ void process_improved_im(LLMessageSystem *msg, void **user_data)
// Someone has offered us some inventory.
{
LLOfferInfo* info = new LLOfferInfo;
-
+ bool mute_im = false;
if (IM_INVENTORY_OFFERED == dialog)
{
struct offer_agent_bucket_t
@@ -1772,6 +1819,11 @@ void process_improved_im(LLMessageSystem *msg, void **user_data)
bucketp = (struct offer_agent_bucket_t*) &binary_bucket[0];
info->mType = (LLAssetType::EType) bucketp->asset_type;
info->mObjectID = bucketp->object_id;
+
+ if(accept_im_from_only_friend&&!is_friend)
+ {
+ mute_im = true;
+ }
}
else
{
@@ -1802,7 +1854,7 @@ void process_improved_im(LLMessageSystem *msg, void **user_data)
info->mDesc = message;
info->mHost = msg->getSender();
//if (((is_busy && !is_owned_by_me) || is_muted))
- if ( is_muted )
+ if ( is_muted || mute_im)
{
// Same as closing window
info->forceResponse(IOR_DECLINE);
@@ -1859,7 +1911,7 @@ void process_improved_im(LLMessageSystem *msg, void **user_data)
{
saved = llformat("(Saved %s) ", formatted_time(timestamp).c_str());
}
- buffer = separator_string + saved + message.substr(message_offset);
+ buffer = saved + message.substr(message_offset);
BOOL is_this_agent = FALSE;
if(from_id == gAgentID)
{
@@ -1969,7 +2021,7 @@ void process_improved_im(LLMessageSystem *msg, void **user_data)
else
{
LLSD args;
- // *TODO:translate -> [FIRST] [LAST] (maybe)
+ // *TODO: Translate -> [FIRST] [LAST] (maybe)
args["NAME"] = name;
args["MESSAGE"] = message;
LLSD payload;
@@ -2086,7 +2138,7 @@ void busy_message (LLMessageSystem* msg, LLUUID from_id)
if (gAgent.getBusy())
{
std::string my_name;
- gAgent.buildFullname(my_name);
+ LLAgentUI::buildFullname(my_name);
std::string response = gSavedPerAccountSettings.getString("BusyModeResponse2");
pack_instant_message(
gMessageSystem,
@@ -2352,15 +2404,15 @@ void process_chat_from_simulator(LLMessageSystem *msg, void **user_data)
switch(chat.mChatType)
{
case CHAT_TYPE_WHISPER:
- verb = " " + LLTrans::getString("whisper") + " ";
+ verb = "(" + LLTrans::getString("whisper") + ")";
break;
case CHAT_TYPE_DEBUG_MSG:
case CHAT_TYPE_OWNER:
case CHAT_TYPE_NORMAL:
- verb = ": ";
+ verb = "";
break;
case CHAT_TYPE_SHOUT:
- verb = " " + LLTrans::getString("shout") + " ";
+ verb = "(" + LLTrans::getString("shout") + ")";
break;
case CHAT_TYPE_START:
case CHAT_TYPE_STOP:
@@ -2368,12 +2420,12 @@ void process_chat_from_simulator(LLMessageSystem *msg, void **user_data)
break;
default:
LL_WARNS("Messaging") << "Unknown type " << chat.mChatType << " in chat!" << LL_ENDL;
- verb = " say, ";
+ verb = "";
break;
}
- chat.mText = from_name;
+ chat.mText = "";
chat.mText += verb;
chat.mText += mesg;
}
@@ -2396,17 +2448,24 @@ void process_chat_from_simulator(LLMessageSystem *msg, void **user_data)
// T * * * F Yes Yes
chat.mMuted = is_muted && !is_linden;
-
-
+
if (!visible_in_chat_bubble
&& (is_linden || !is_busy || is_owned_by_me))
{
// show on screen and add to history
+ LLNotificationsUI::LLNotificationManager::instance().onChat(
+ chat, LLNotificationsUI::NT_NEARBYCHAT);
+
+ // adding temporarily so that communications window chat bar
+ // works until the new chat window is ready
+ chat.mText = from_name + ": " + chat.mText;
LLFloaterChat::addChat(chat, FALSE, FALSE);
}
else
{
- // just add to chat history
+ LLNotificationsUI::LLNotificationManager::instance().onChat(
+ chat, LLNotificationsUI::NT_NEARBYCHAT);
+ // adding temporarily
LLFloaterChat::addChatHistory(chat);
}
}
@@ -2430,7 +2489,7 @@ void process_teleport_start(LLMessageSystem *msg, void**)
}
else
{
- gViewerWindow->setProgressCancelButtonVisible(TRUE, std::string("Cancel")); // *TODO: Translate
+ gViewerWindow->setProgressCancelButtonVisible(TRUE, LLTrans::getString("Cancel"));
}
// Freeze the UI and show progress bar
@@ -2465,7 +2524,7 @@ void process_teleport_progress(LLMessageSystem* msg, void**)
}
else
{
- gViewerWindow->setProgressCancelButtonVisible(TRUE, std::string("Cancel")); //TODO: Translate
+ gViewerWindow->setProgressCancelButtonVisible(TRUE, LLTrans::getString("Cancel"));
}
std::string buffer;
msg->getString("Info", "Message", buffer);
@@ -2880,12 +2939,45 @@ void process_agent_movement_complete(LLMessageSystem* msg, void**)
{
LLSD payload;
payload["message"] = version_channel;
- LLNotifications::instance().add("ServerVersionChanged", LLSD(), payload);
+ LLNotifications::instance().add("ServerVersionChanged", LLSD(), payload, server_version_changed_callback);
}
gLastVersionChannel = version_channel;
}
+bool server_version_changed_callback(const LLSD& notification, const LLSD& response)
+{
+ if(notification["payload"]["message"].asString() =="")
+ return false;
+ std::string url ="http://wiki.secondlife.com/wiki/Release_Notes/";
+ //parse the msg string
+ std::string server_version = notification["payload"]["message"].asString();
+ std::vector<std::string> s_vect;
+ boost::algorithm::split(s_vect, server_version, isspace);
+ for(U32 i = 0; i < s_vect.size(); i++)
+ {
+ if (i != (s_vect.size() - 1))
+ {
+ if(i != (s_vect.size() - 2))
+ {
+ url += s_vect[i] + "_";
+ }
+ else
+ {
+ url += s_vect[i] + "/";
+ }
+ }
+ else
+ {
+ url += s_vect[i].substr(0,4);
+ }
+ }
+
+ LLWeb::loadURL(url);
+ return false;
+}
+
+
void process_crossed_region(LLMessageSystem* msg, void**)
{
LLUUID agent_id;
@@ -3217,11 +3309,12 @@ void process_terse_object_update_improved(LLMessageSystem *mesgsys, void **user_
gObjectList.processCompressedObjectUpdate(mesgsys, user_data, OUT_TERSE_IMPROVED);
}
+static LLFastTimer::DeclareTimer FTM_PROCESS_OBJECTS("Process Objects");
void process_kill_object(LLMessageSystem *mesgsys, void **user_data)
{
- LLFastTimer t(LLFastTimer::FTM_PROCESS_OBJECTS);
+ LLFastTimer t(FTM_PROCESS_OBJECTS);
LLUUID id;
U32 local_id;
@@ -3782,13 +3875,13 @@ void process_avatar_sit_response(LLMessageSystem *mesgsys, void **user_data)
gAgent.setSitCamera(sitObjectID, camera_eye, camera_at);
}
- gAgent.mForceMouselook = force_mouselook;
+ gAgent.setForceMouselook(force_mouselook);
LLViewerObject* object = gObjectList.findObject(sitObjectID);
if (object)
{
LLVector3 sit_spot = object->getPositionAgent() + (sitPosition * object->getRotation());
- if (!use_autopilot || (avatar && avatar->mIsSitting && avatar->getRoot() == object->getRoot()))
+ if (!use_autopilot || (avatar && avatar->isSitting() && avatar->getRoot() == object->getRoot()))
{
//we're already sitting on this object, so don't autopilot
}
@@ -4094,7 +4187,7 @@ void process_money_balance_reply( LLMessageSystem* msg, void** )
{
// Make the user confirm the transaction, since they might
// have missed something during an event.
- // *TODO:translate
+ // *TODO: Translate
LLSD args;
args["MESSAGE"] = desc;
LLNotifications::instance().add("SystemMessage", args);
@@ -4170,7 +4263,7 @@ bool handle_special_notification(std::string notificationID, LLSD& llsdBlock)
bool attempt_standard_notification(LLMessageSystem* msgsystem)
{
// if we have additional alert data
- if (msgsystem->getNumberOfBlocksFast(_PREHASH_AlertInfo) > 0)
+ if (msgsystem->has(_PREHASH_AlertInfo) && msgsystem->getNumberOfBlocksFast(_PREHASH_AlertInfo) > 0)
{
// notification was specified using the new mechanism, so we can just handle it here
std::string notificationID;
@@ -4316,23 +4409,23 @@ void process_alert_core(const std::string& message, BOOL modal)
}
else
{
- // *TODO:translate
- args["MESSAGE"] = text;
+ std::string new_msg =LLNotifications::instance().getGlobalString(text);
+ args["MESSAGE"] = new_msg;
LLNotifications::instance().add("SystemMessage", args);
}
}
else if (modal)
{
- // *TODO:translate
LLSD args;
- args["ERROR_MESSAGE"] = message;
+ std::string new_msg =LLNotifications::instance().getGlobalString(message);
+ args["ERROR_MESSAGE"] = new_msg;
LLNotifications::instance().add("ErrorMessage", args);
}
else
{
- // *TODO:translate
LLSD args;
- args["MESSAGE"] = message;
+ std::string new_msg =LLNotifications::instance().getGlobalString(message);
+ args["MESSAGE"] = new_msg;
LLNotifications::instance().add("SystemMessageTip", args);
}
}
@@ -4346,11 +4439,11 @@ void handle_show_mean_events(void *)
{
return;
}
-
- LLFloaterBump::show(NULL);
+ LLFloaterReg::showInstance("bumps");
+ //LLFloaterBump::showInstance();
}
-void mean_name_callback(const LLUUID &id, const std::string& first, const std::string& last, BOOL always_false, void* data)
+void mean_name_callback(const LLUUID &id, const std::string& first, const std::string& last, BOOL always_false)
{
if (gNoRender)
{
@@ -4428,7 +4521,7 @@ void process_mean_collision_alert_message(LLMessageSystem *msgsystem, void **use
LLMeanCollisionData *mcd = new LLMeanCollisionData(gAgentID, perp, time, type, mag);
gMeanCollisionList.push_front(mcd);
const BOOL is_group = FALSE;
- gCacheName->getNameFromUUID(perp, is_group, mean_name_callback);
+ gCacheName->get(perp, is_group, &mean_name_callback);
}
}
}
@@ -4460,9 +4553,6 @@ void process_economy_data(LLMessageSystem *msg, void** /*user_data*/)
LL_INFOS_ONCE("Messaging") << "EconomyData message arrived; upload cost is L$" << upload_cost << LL_ENDL;
- LLFloaterImagePreview::setUploadAmount(upload_cost);
- LLFloaterAnimPreview::setUploadAmount(upload_cost);
-
gMenuHolder->childSetLabelArg("Upload Image", "[COST]", llformat("%d", upload_cost));
gMenuHolder->childSetLabelArg("Upload Sound", "[COST]", llformat("%d", upload_cost));
gMenuHolder->childSetLabelArg("Upload Animation", "[COST]", llformat("%d", upload_cost));
@@ -4480,7 +4570,7 @@ void notify_cautioned_script_question(const LLSD& notification, const LLSD& resp
// located in [REGIONNAME] at [REGIONPOS],
// has been <granted|denied> permission to: [PERMISSIONS]."
- LLUIString notice(LLFloaterChat::getInstance()->getString(granted ? "ScriptQuestionCautionChatGranted" : "ScriptQuestionCautionChatDenied"));
+ LLUIString notice(LLTrans::getString(granted ? "ScriptQuestionCautionChatGranted" : "ScriptQuestionCautionChatDenied"));
// always include the object name and owner name
notice.setArg("[OBJECTNAME]", notification["payload"]["object_name"].asString());
@@ -4534,7 +4624,7 @@ void notify_cautioned_script_question(const LLSD& notification, const LLSD& resp
perms.append(", ");
}
- perms.append(LLFloaterChat::getInstance()->getString(SCRIPT_QUESTIONS[i]));
+ perms.append(LLTrans::getString(SCRIPT_QUESTIONS[i]));
}
}
@@ -4628,7 +4718,7 @@ static LLNotificationFunctorRegistration script_question_cb_reg_2("ScriptQuestio
void process_script_question(LLMessageSystem *msg, void **user_data)
{
- // *TODO:translate owner name -> [FIRST] [LAST]
+ // *TODO: Translate owner name -> [FIRST] [LAST]
LLHost sender = msg->getSender();
@@ -4652,7 +4742,7 @@ void process_script_question(LLMessageSystem *msg, void **user_data)
// so we'll reuse the same namespace for both throttle types.
std::string throttle_name = owner_name;
std::string self_name;
- gAgent.getName( self_name );
+ LLAgentUI::buildName( self_name );
if( owner_name == self_name )
{
throttle_name = taskid.getString();
@@ -4696,7 +4786,7 @@ void process_script_question(LLMessageSystem *msg, void **user_data)
if (questions & LSCRIPTRunTimePermissionBits[i])
{
count++;
- script_question += " " + LLFloaterChat::getInstance()->getString(SCRIPT_QUESTIONS[i]) + "\n";
+ script_question += " " + LLTrans::getString(SCRIPT_QUESTIONS[i]) + "\n";
// check whether permission question should cause special caution dialog
caution |= (SCRIPT_QUESTION_IS_CAUTION[i]);
@@ -4744,15 +4834,15 @@ void container_inventory_arrived(LLViewerObject* object,
gAgent.changeCameraToDefault();
}
- LLInventoryView* view = LLInventoryView::getActiveInventory();
+ LLFloaterInventory* view = LLFloaterInventory::getActiveInventory();
if (inventory->size() > 2)
{
// create a new inventory category to put this in
LLUUID cat_id;
- cat_id = gInventory.createNewCategory(gAgent.getInventoryRootID(),
+ cat_id = gInventory.createNewCategory(gInventory.getRootFolderID(),
LLAssetType::AT_NONE,
- std::string("Acquired Items")); //TODO: Translate
+ LLTrans::getString("AcquiredItems"));
InventoryObjectList::const_iterator it = inventory->begin();
InventoryObjectList::const_iterator end = inventory->end();
@@ -4846,10 +4936,18 @@ void container_inventory_arrived(LLViewerObject* object,
// method to format the time.
std::string formatted_time(const time_t& the_time)
{
- char buffer[30]; /* Flawfinder: ignore */
- LLStringUtil::copy(buffer, ctime(&the_time), 30);
- buffer[24] = '\0';
- return std::string(buffer);
+ std::string dateStr = "["+LLTrans::getString("LTimeWeek")+"] ["
+ +LLTrans::getString("LTimeMonth")+"] ["
+ +LLTrans::getString("LTimeDay")+"] ["
+ +LLTrans::getString("LTimeHour")+"]:["
+ +LLTrans::getString("LTimeMin")+"]:["
+ +LLTrans::getString("LTimeSec")+"] ["
+ +LLTrans::getString("LTimeYear")+"]";
+
+ LLSD substitution;
+ substitution["datetime"] = (S32) the_time;
+ LLStringUtil::format (dateStr, substitution);
+ return dateStr;
}
@@ -4860,7 +4958,7 @@ void process_teleport_failed(LLMessageSystem *msg, void**)
LLSD args;
// if we have additional alert data
- if (msg->getNumberOfBlocksFast(_PREHASH_AlertInfo) > 0)
+ if (msg->has(_PREHASH_AlertInfo) && msg->getSizeFast(_PREHASH_AlertInfo, _PREHASH_Message) > 0)
{
// Get the message ID
msg->getStringFast(_PREHASH_AlertInfo, _PREHASH_Message, reason);
@@ -4917,6 +5015,9 @@ void process_teleport_failed(LLMessageSystem *msg, void**)
LLNotifications::instance().add("CouldNotTeleportReason", args);
+ // Let the interested parties know that teleport failed.
+ LLViewerParcelMgr::getInstance()->onTeleportFailed();
+
if( gAgent.getTeleportState() != LLAgent::TELEPORT_NONE )
{
gAgent.setTeleportState( LLAgent::TELEPORT_NONE );
@@ -4966,6 +5067,11 @@ void process_teleport_local(LLMessageSystem *msg,void**)
gAgent.updateCamera();
send_agent_update(TRUE, TRUE);
+
+ // Let the interested parties know we've teleported.
+ // Vadim *HACK: Agent position seems to get reset (to render position?)
+ // on each frame, so we have to pass the new position manually.
+ LLViewerParcelMgr::getInstance()->onTeleportFinished(true, gAgent.getPosGlobalFromAgent(pos));
}
void send_simple_im(const LLUUID& to_id,
@@ -4974,7 +5080,7 @@ void send_simple_im(const LLUUID& to_id,
const LLUUID& id)
{
std::string my_name;
- gAgent.buildFullname(my_name);
+ LLAgentUI::buildFullname(my_name);
send_improved_im(to_id,
my_name,
message,
@@ -4995,7 +5101,7 @@ void send_group_notice(const LLUUID& group_id,
// This will mean converting the item to a binary bucket,
// and the subject/message into a single field.
std::string my_name;
- gAgent.buildFullname(my_name);
+ LLAgentUI::buildFullname(my_name);
// Combine subject + message into a single string.
std::ostringstream subject_and_message;
@@ -5073,13 +5179,13 @@ void handle_lure(const LLUUID& invitee)
}
// Prompt for a message to the invited user.
-void handle_lure(LLDynamicArray<LLUUID>& ids)
+void handle_lure(const std::vector<LLUUID>& ids)
{
LLSD edit_args;
edit_args["REGION"] = gAgent.getRegion()->getName();
LLSD payload;
- for (LLDynamicArray<LLUUID>::iterator it = ids.begin();
+ for (LLDynamicArray<LLUUID>::const_iterator it = ids.begin();
it != ids.end();
++it)
{
@@ -5298,7 +5404,7 @@ static LLNotificationFunctorRegistration callback_load_url_reg("LoadWebPage", ca
// We've got the name of the person who owns the object hurling the url.
// Display confirmation dialog.
-void callback_load_url_name(const LLUUID& id, const std::string& first, const std::string& last, BOOL is_group, void* data)
+void callback_load_url_name(const LLUUID& id, const std::string& first, const std::string& last, BOOL is_group)
{
std::vector<LLSD>::iterator it;
for (it = gLoadUrlList.begin(); it != gLoadUrlList.end(); )
@@ -5311,7 +5417,7 @@ void callback_load_url_name(const LLUUID& id, const std::string& first, const st
std::string owner_name;
if (is_group)
{
- owner_name = first + " (group)";
+ owner_name = first + LLTrans::getString("Group");
}
else
{
@@ -5375,7 +5481,7 @@ void process_load_url(LLMessageSystem* msg, void**)
// Add to list of pending name lookups
gLoadUrlList.push_back(payload);
- gCacheName->getNameFromUUID(owner_id, owner_is_group, callback_load_url_name);
+ gCacheName->get(owner_id, owner_is_group, &callback_load_url_name);
}
@@ -5431,12 +5537,17 @@ void process_script_teleport_request(LLMessageSystem* msg, void**)
msg->getVector3("Data", "SimPosition", pos);
msg->getVector3("Data", "LookAt", look_at);
- gFloaterWorldMap->trackURL(sim_name, (S32)pos.mV[VX], (S32)pos.mV[VY], (S32)pos.mV[VZ]);
- LLFloaterWorldMap::show(NULL, TRUE);
-
+ LLFloaterWorldMap* instance = LLFloaterWorldMap::getInstance();
+ if(instance)
+ {
+ instance->trackURL(
+ sim_name, (S32)pos.mV[VX], (S32)pos.mV[VY], (S32)pos.mV[VZ]);
+ LLFloaterReg::showInstance("world_map", "center");
+ }
+
// remove above two lines and replace with below line
// to re-enable parcel browser for llMapDestination()
- // LLURLDispatcher::dispatch(LLURLDispatcher::buildSLURL(sim_name, (S32)pos.mV[VX], (S32)pos.mV[VY], (S32)pos.mV[VZ]), FALSE);
+ // LLURLDispatcher::dispatch(LLSLURL::buildSLURL(sim_name, (S32)pos.mV[VX], (S32)pos.mV[VY], (S32)pos.mV[VZ]), FALSE);
}
@@ -5458,18 +5569,28 @@ void process_covenant_reply(LLMessageSystem* msg, void**)
std::string last_modified;
if (covenant_timestamp == 0)
{
- last_modified = LLTrans::getString("covenant_never_modified");
+ last_modified = LLTrans::getString("covenant_last_modified")+LLTrans::getString("never_text");
}
else
{
- last_modified = LLTrans::getString("covenant_modified") + " " + formatted_time((time_t)covenant_timestamp);
+ last_modified = LLTrans::getString("covenant_last_modified")+"["
+ +LLTrans::getString("LTimeWeek")+"] ["
+ +LLTrans::getString("LTimeMonth")+"] ["
+ +LLTrans::getString("LTimeDay")+"] ["
+ +LLTrans::getString("LTimeHour")+"]:["
+ +LLTrans::getString("LTimeMin")+"]:["
+ +LLTrans::getString("LTimeSec")+"] ["
+ +LLTrans::getString("LTimeYear")+"]";
+ LLSD substitution;
+ substitution["datetime"] = (S32) covenant_timestamp;
+ LLStringUtil::format (last_modified, substitution);
}
LLPanelEstateCovenant::updateLastModified(last_modified);
LLPanelLandCovenant::updateLastModified(last_modified);
LLFloaterBuyLand::updateLastModified(last_modified);
- // Estates can't be owned by groups
+ gCacheName->get(estate_owner_id, false, &callbackCacheEstateOwnerName);
BOOL is_group = FALSE;
gCacheName->getNameFromUUID(estate_owner_id, is_group, callbackCacheEstateOwnerName);
@@ -5493,11 +5614,11 @@ void process_covenant_reply(LLMessageSystem* msg, void**)
if (estate_owner_id.isNull())
{
// mainland
- covenant_text = "There is no Covenant provided for this Estate.";
+ covenant_text = LLTrans::getString("RegionNoCovenant");
}
else
{
- covenant_text = "There is no Covenant provided for this Estate. The land on this estate is being sold by the Estate owner, not Linden Lab. Please contact the Estate Owner for sales details.";
+ covenant_text = LLTrans::getString("RegionNoCovenantOtherOwner");
}
LLPanelEstateCovenant::updateCovenantText(covenant_text, covenant_id);
LLPanelLandCovenant::updateCovenantText(covenant_text);
@@ -5507,13 +5628,13 @@ void process_covenant_reply(LLMessageSystem* msg, void**)
void callbackCacheEstateOwnerName(const LLUUID& id,
const std::string& first, const std::string& last,
- BOOL is_group, void*)
+ BOOL is_group)
{
std::string name;
if (id.isNull())
{
- name = "(none)";
+ name = LLTrans::getString("none_text");
}
else
{
@@ -5544,10 +5665,10 @@ void onCovenantLoadComplete(LLVFS *vfs,
if( (file_length > 19) && !strncmp( &buffer[0], "Linden text version", 19 ) )
{
- LLViewerTextEditor* editor =
- new LLViewerTextEditor(std::string("temp"),
- LLRect(0,0,0,0),
- file_length+1);
+ LLViewerTextEditor::Params params;
+ params.name("temp");
+ params.max_text_length(file_length+1);
+ LLViewerTextEditor * editor = LLUICtrlFactory::create<LLViewerTextEditor> (params);
if( !editor->importBuffer( &buffer[0], file_length+1 ) )
{
LL_WARNS("Messaging") << "Problem importing estate covenant." << LL_ENDL;
@@ -5622,6 +5743,6 @@ void invalid_message_callback(LLMessageSystem* msg,
void LLOfferInfo::forceResponse(InventoryOfferResponse response)
{
LLNotification::Params params("UserGiveItem");
- params.functor(boost::bind(&LLOfferInfo::inventory_offer_callback, this, _1, _2));
+ params.functor.function(boost::bind(&LLOfferInfo::inventory_offer_callback, this, _1, _2));
LLNotifications::instance().forceResponse(params, response);
}
diff --git a/indra/newview/llviewermessage.h b/indra/newview/llviewermessage.h
index e7a4303a8e..c15e5df675 100644
--- a/indra/newview/llviewermessage.h
+++ b/indra/newview/llviewermessage.h
@@ -34,6 +34,7 @@
#define LL_LLVIEWERMESSAGE_H
#include "llinstantmessage.h"
+#include "llpointer.h"
#include "lltransactiontypes.h"
#include "lluuid.h"
#include "stdenums.h"
@@ -42,10 +43,11 @@
// Forward declarations
//
class LLColor4;
-class LLViewerObject;
class LLInventoryObject;
class LLInventoryItem;
+class LLMeanCollisionData;
class LLMessageSystem;
+class LLViewerObject;
class LLViewerRegion;
//
@@ -130,6 +132,7 @@ void container_inventory_arrived(LLViewerObject* object,
// agent movement
void send_complete_agent_movement(const LLHost& sim_host);
void process_agent_movement_complete(LLMessageSystem* msg, void**);
+bool server_version_changed_callback(const LLSD& notification, const LLSD& response);
void process_crossed_region(LLMessageSystem* msg, void**);
void process_teleport_start(LLMessageSystem* msg, void**);
void process_teleport_progress(LLMessageSystem* msg, void**);
@@ -151,7 +154,7 @@ void send_group_notice(const LLUUID& group_id,
const LLInventoryItem* item);
void handle_lure(const LLUUID& invitee);
-void handle_lure(LLDynamicArray<LLUUID>& ids);
+void handle_lure(const std::vector<LLUUID>& ids);
// always from gAgent and
// routes through the gAgent's current simulator
diff --git a/indra/newview/llviewernetwork.cpp b/indra/newview/llviewernetwork.cpp
index 8719557cbc..918b15ef09 100644
--- a/indra/newview/llviewernetwork.cpp
+++ b/indra/newview/llviewernetwork.cpp
@@ -218,7 +218,7 @@ void LLViewerLogin::setGridChoice(const std::string& grid_name)
void LLViewerLogin::resetURIs()
{
// Clear URIs when picking a new server
- gSavedSettings.setValue("CmdLineLoginURI", LLSD::emptyArray());
+ gSavedSettings.setLLSD("CmdLineLoginURI", LLSD::emptyArray());
gSavedSettings.setString("CmdLineHelperURI", "");
}
diff --git a/indra/newview/llviewerobject.cpp b/indra/newview/llviewerobject.cpp
index 6591cd3b19..1594a68f36 100644
--- a/indra/newview/llviewerobject.cpp
+++ b/indra/newview/llviewerobject.cpp
@@ -34,7 +34,7 @@
#include "llviewerobject.h"
-#include "audioengine.h"
+#include "llaudioengine.h"
#include "imageids.h"
#include "indra_constants.h"
#include "llmath.h"
@@ -42,6 +42,7 @@
#include "llviewercontrol.h"
#include "lldatapacker.h"
#include "llfasttimer.h"
+#include "llfloaterreg.h"
#include "llfontgl.h"
#include "llframetimer.h"
#include "llinventory.h"
@@ -70,7 +71,7 @@
#include "llrendersphere.h"
#include "lltooldraganddrop.h"
#include "llviewercamera.h"
-#include "llviewerimagelist.h"
+#include "llviewertexturelist.h"
#include "llviewerinventory.h"
#include "llviewerobjectlist.h"
#include "llviewerparceloverlay.h"
@@ -79,6 +80,7 @@
#include "llviewertextureanim.h"
#include "llviewerwindow.h" // For getSpinAxis
#include "llvoavatar.h"
+#include "llvoavatarself.h"
#include "llvoclouds.h"
#include "llvograss.h"
#include "llvoground.h"
@@ -97,6 +99,7 @@
#include "llviewernetwork.h"
#include "llvowlsky.h"
#include "llmanip.h"
+#include "lltrans.h"
//#define DEBUG_UPDATE_TYPE
@@ -112,18 +115,31 @@ S32 LLViewerObject::sAxisArrowLength(50);
BOOL LLViewerObject::sPulseEnabled(FALSE);
BOOL LLViewerObject::sUseSharedDrawables(FALSE); // TRUE
+static LLFastTimer::DeclareTimer FTM_CREATE_OBJECT("Create Object");
+
// static
LLViewerObject *LLViewerObject::createObject(const LLUUID &id, const LLPCode pcode, LLViewerRegion *regionp)
{
LLViewerObject *res = NULL;
- LLFastTimer t1(LLFastTimer::FTM_CREATE_OBJECT);
+ LLFastTimer t1(FTM_CREATE_OBJECT);
switch (pcode)
{
case LL_PCODE_VOLUME:
res = new LLVOVolume(id, pcode, regionp); break;
case LL_PCODE_LEGACY_AVATAR:
- res = new LLVOAvatar(id, pcode, regionp); break;
+ {
+ if (id == gAgentID)
+ {
+ res = new LLVOAvatarSelf(id, pcode, regionp);
+ }
+ else
+ {
+ res = new LLVOAvatar(id, pcode, regionp);
+ }
+ static_cast<LLVOAvatar*>(res)->initInstance();
+ break;
+ }
case LL_PCODE_LEGACY_GRASS:
res = new LLVOGrass(id, pcode, regionp); break;
case LL_PCODE_LEGACY_PART_SYS:
@@ -499,15 +515,24 @@ BOOL LLViewerObject::isOverGroupOwnedLand() const
&& mRegionp->getParcelOverlay()->isOwnedGroup(getPositionRegion());
}
-void LLViewerObject::setParent(LLViewerObject* parent)
+BOOL LLViewerObject::setParent(LLViewerObject* parent)
{
- LLPrimitive::setParent(parent);
+ if(mParent != parent)
+ {
+ LLViewerObject* old_parent = (LLViewerObject*)mParent ;
+ BOOL ret = LLPrimitive::setParent(parent);
+ if(ret && old_parent && parent)
+ {
+ old_parent->removeChild(this) ;
+ }
+ return ret ;
+ }
+
+ return FALSE ;
}
void LLViewerObject::addChild(LLViewerObject *childp)
{
- BOOL result = TRUE;
-
for (child_list_t::iterator i = mChildList.begin(); i != mChildList.end(); ++i)
{
if (*i == childp)
@@ -522,18 +547,9 @@ void LLViewerObject::addChild(LLViewerObject *childp)
childp->mbCanSelect = mbCanSelect;
}
- childp->setParent(this);
- mChildList.push_back(childp);
-
- if (!result)
+ if(childp->setParent(this))
{
- llwarns << "Failed to attach child " << childp->getID() << " to object " << getID() << llendl;
- removeChild(childp);
- if (mJointInfo)
- {
- delete mJointInfo;
- mJointInfo = NULL;
- }
+ mChildList.push_back(childp);
}
}
@@ -549,7 +565,11 @@ void LLViewerObject::removeChild(LLViewerObject *childp)
}
mChildList.erase(i);
- childp->setParent(NULL);
+
+ if(childp->getParent() == this)
+ {
+ childp->setParent(NULL);
+ }
break;
}
}
@@ -631,11 +651,14 @@ BOOL LLViewerObject::setDrawableParent(LLDrawable* parentp)
return FALSE;
}
+ BOOL ret = mDrawable->mXform.setParent(parentp ? &parentp->mXform : NULL);
+ if(!ret)
+ {
+ return FALSE ;
+ }
LLDrawable* old_parent = mDrawable->mParent;
-
mDrawable->mParent = parentp;
-
- BOOL ret = mDrawable->mXform.setParent(parentp ? &parentp->mXform : NULL);
+
gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_VOLUME, TRUE);
if( old_parent != parentp &&
old_parent || (parentp && parentp->isActive()))
@@ -2461,7 +2484,7 @@ void LLViewerObject::processTaskInv(LLMessageSystem* msg, void** user_data)
LLPointer<LLInventoryObject> obj;
obj = new LLInventoryObject(object->mID, LLUUID::null,
LLAssetType::AT_CATEGORY,
- std::string("Contents"));
+ LLTrans::getString("ViewerObjectContents").c_str());
object->mInventory->push_front(obj);
object->doInventoryCallback();
delete ft;
@@ -2528,6 +2551,7 @@ void LLViewerObject::loadTaskInvFile(const std::string& filename)
{
LLPointer<LLInventoryObject> inv = new LLInventoryObject;
inv->importLegacyStream(ifs);
+ inv->rename(LLTrans::getString("ViewerObjectContents").c_str());
mInventory->push_front(inv);
}
else
@@ -2574,7 +2598,7 @@ void LLViewerObject::doInventoryCallback()
void LLViewerObject::removeInventory(const LLUUID& item_id)
{
// close any associated floater properties
- LLFloaterProperties::closeByID(item_id, mID);
+ LLFloaterReg::hideInstance("properties", item_id);
LLMessageSystem* msg = gMessageSystem;
msg->newMessageFast(_PREHASH_RemoveTaskInventory);
@@ -2587,11 +2611,6 @@ void LLViewerObject::removeInventory(const LLUUID& item_id)
msg->sendReliable(mRegionp->getHost());
deleteInventoryItem(item_id);
++mInventorySerialNum;
-
- // The viewer object should not refresh UI since this is a utility
- // function. The UI functionality that called this method should
- // refresh the views if necessary.
- //gBuildView->refresh();
}
void LLViewerObject::updateInventory(
@@ -2903,14 +2922,14 @@ void LLViewerObject::boostTexturePriority(BOOL boost_children /* = TRUE */)
S32 tex_count = getNumTEs();
for (i = 0; i < tex_count; i++)
{
- getTEImage(i)->setBoostLevel(LLViewerImage::BOOST_SELECTED);
+ getTEImage(i)->setBoostLevel(LLViewerTexture::BOOST_SELECTED);
}
if (isSculpted())
{
LLSculptParams *sculpt_params = (LLSculptParams *)getParameterEntry(LLNetworkData::PARAMS_SCULPT);
LLUUID sculpt_id = sculpt_params->getSculptTexture();
- gImageList.getImage(sculpt_id)->setBoostLevel(LLViewerImage::BOOST_SELECTED);
+ LLViewerTextureManager::getFetchedTexture(sculpt_id, TRUE, FALSE, LLViewerTexture::LOD_TEXTURE)->setBoostLevel(LLViewerTexture::BOOST_SELECTED);
}
if (boost_children)
@@ -3538,8 +3557,8 @@ void LLViewerObject::setNumTEs(const U8 num_tes)
{
if (num_tes)
{
- LLPointer<LLViewerImage> *new_images;
- new_images = new LLPointer<LLViewerImage>[num_tes];
+ LLPointer<LLViewerTexture> *new_images;
+ new_images = new LLPointer<LLViewerTexture>[num_tes];
for (i = 0; i < num_tes; i++)
{
if (i < getNumTEs())
@@ -3673,11 +3692,11 @@ void LLViewerObject::setTE(const U8 te, const LLTextureEntry &texture_entry)
// if (mDrawable.notNull() && mDrawable->isVisible())
// {
const LLUUID& image_id = getTE(te)->getID();
- mTEImages[te] = gImageList.getImage(image_id);
+ mTEImages[te] = LLViewerTextureManager::getFetchedTexture(image_id, TRUE, FALSE, LLViewerTexture::LOD_TEXTURE);
// }
}
-void LLViewerObject::setTEImage(const U8 te, LLViewerImage *imagep)
+void LLViewerObject::setTEImage(const U8 te, LLViewerTexture *imagep)
{
if (mTEImages[te] != imagep)
{
@@ -3699,7 +3718,7 @@ S32 LLViewerObject::setTETextureCore(const U8 te, const LLUUID& uuid, LLHost hos
uuid == LLUUID::null)
{
retval = LLPrimitive::setTETexture(te, uuid);
- mTEImages[te] = gImageList.getImageFromHost(uuid, host);
+ mTEImages[te] = LLViewerTextureManager::getFetchedTexture(uuid, TRUE, FALSE, LLViewerTexture::LOD_TEXTURE, 0, 0, host);
setChanged(TEXTURE);
if (mDrawable.notNull())
{
@@ -3710,6 +3729,18 @@ S32 LLViewerObject::setTETextureCore(const U8 te, const LLUUID& uuid, LLHost hos
}
+void LLViewerObject::changeTEImage(const LLViewerTexture* old_image, LLViewerTexture* new_image)
+{
+ U32 end = getNumTEs() ;
+ for (U32 face = 0 ; face < end ; face++)
+ {
+ if(old_image == mTEImages[face])
+ {
+ mTEImages[face] = new_image ;
+ }
+ }
+}
+
S32 LLViewerObject::setTETexture(const U8 te, const LLUUID& uuid)
{
// Invalid host == get from the agent's sim
@@ -3954,20 +3985,20 @@ S32 LLViewerObject::setTERotation(const U8 te, const F32 r)
}
-LLViewerImage *LLViewerObject::getTEImage(const U8 face) const
+LLViewerTexture *LLViewerObject::getTEImage(const U8 face) const
{
// llassert(mTEImages);
if (face < getNumTEs())
{
- LLViewerImage* image = mTEImages[face];
+ LLViewerTexture* image = mTEImages[face];
if (image)
{
return image;
}
else
{
- return (LLViewerImage*)((LLImageGL*)LLViewerImage::sDefaultImagep);
+ return (LLViewerTexture*)(LLViewerFetchedTexture::sDefaultImagep);
}
}
@@ -4088,7 +4119,7 @@ void LLViewerObject::setDebugText(const std::string &utf8text)
updateText();
}
-void LLViewerObject::setIcon(LLViewerImage* icon_image)
+void LLViewerObject::setIcon(LLViewerTexture* icon_image)
{
if (!mIcon)
{
@@ -4178,14 +4209,14 @@ void LLViewerObject::setParticleSource(const LLPartSysData& particle_parameters,
if (mPartSourcep->getImage()->getID() != mPartSourcep->mPartSysData.mPartImageID)
{
- LLViewerImage* image;
+ LLViewerTexture* image;
if (mPartSourcep->mPartSysData.mPartImageID == LLUUID::null)
{
- image = gImageList.getImageFromFile("pixiesmall.tga");
+ image = LLViewerTextureManager::getFetchedTextureFromFile("pixiesmall.tga");
}
else
{
- image = gImageList.getImage(mPartSourcep->mPartSysData.mPartImageID);
+ image = LLViewerTextureManager::getFetchedTexture(mPartSourcep->mPartSysData.mPartImageID);
}
mPartSourcep->setImage(image);
}
@@ -4227,14 +4258,14 @@ void LLViewerObject::unpackParticleSource(const S32 block_num, const LLUUID& own
{
if (mPartSourcep->getImage()->getID() != mPartSourcep->mPartSysData.mPartImageID)
{
- LLViewerImage* image;
+ LLViewerTexture* image;
if (mPartSourcep->mPartSysData.mPartImageID == LLUUID::null)
{
- image = gImageList.getImageFromFile("pixiesmall.j2c");
+ image = LLViewerTextureManager::getFetchedTextureFromFile("pixiesmall.j2c");
}
else
{
- image = gImageList.getImage(mPartSourcep->mPartSysData.mPartImageID);
+ image = LLViewerTextureManager::getFetchedTexture(mPartSourcep->mPartSysData.mPartImageID);
}
mPartSourcep->setImage(image);
}
@@ -4274,14 +4305,14 @@ void LLViewerObject::unpackParticleSource(LLDataPacker &dp, const LLUUID& owner_
{
if (mPartSourcep->getImage()->getID() != mPartSourcep->mPartSysData.mPartImageID)
{
- LLViewerImage* image;
+ LLViewerTexture* image;
if (mPartSourcep->mPartSysData.mPartImageID == LLUUID::null)
{
- image = gImageList.getImageFromFile("pixiesmall.j2c");
+ image = LLViewerTextureManager::getFetchedTextureFromFile("pixiesmall.j2c");
}
else
{
- image = gImageList.getImage(mPartSourcep->mPartSysData.mPartImageID);
+ image = LLViewerTextureManager::getFetchedTexture(mPartSourcep->mPartSysData.mPartImageID);
}
mPartSourcep->setImage(image);
}
diff --git a/indra/newview/llviewerobject.h b/indra/newview/llviewerobject.h
index db69399383..cda2c5114f 100644
--- a/indra/newview/llviewerobject.h
+++ b/indra/newview/llviewerobject.h
@@ -40,7 +40,7 @@
#include "llhudtext.h"
#include "llhudicon.h"
#include "llinventory.h"
-#include "llmemory.h"
+#include "llrefcount.h"
#include "llmemtype.h"
#include "llprimitive.h"
#include "lluuid.h"
@@ -64,10 +64,11 @@ class LLWorld;
class LLNameValue;
class LLNetMap;
class LLMessageSystem;
+class LLPartSysData;
class LLPrimitive;
class LLPipeline;
class LLTextureEntry;
-class LLViewerImage;
+class LLViewerTexture;
class LLViewerInventoryItem;
class LLViewerObject;
class LLViewerPartSourceScript;
@@ -236,7 +237,7 @@ public:
BOOL isProbablyModifiable() const;
*/
- virtual void setParent(LLViewerObject* parent);
+ virtual BOOL setParent(LLViewerObject* parent);
virtual void addChild(LLViewerObject *childp);
virtual void removeChild(LLViewerObject *childp);
const_child_list_t& getChildren() const { return mChildList; }
@@ -311,8 +312,9 @@ public:
/*virtual*/ S32 setTEMediaFlags(const U8 te, const U8 media_flags );
/*virtual*/ S32 setTEGlow(const U8 te, const F32 glow);
/*virtual*/ BOOL setMaterial(const U8 material);
- virtual void setTEImage(const U8 te, LLViewerImage *imagep); // Not derived from LLPrimitive
- LLViewerImage *getTEImage(const U8 te) const;
+ virtual void setTEImage(const U8 te, LLViewerTexture *imagep); // Not derived from LLPrimitive
+ void changeTEImage(const LLViewerTexture* old_image, LLViewerTexture* new_image) ;
+ LLViewerTexture *getTEImage(const U8 te) const;
void fitFaceTexture(const U8 face);
void sendTEUpdate() const; // Sends packed representation of all texture entry information
@@ -353,7 +355,7 @@ public:
void setCanSelect(BOOL canSelect);
void setDebugText(const std::string &utf8text);
- void setIcon(LLViewerImage* icon_image);
+ void setIcon(LLViewerTexture* icon_image);
void clearIcon();
void markForUpdate(BOOL priority);
@@ -526,7 +528,7 @@ public:
// Last total CRC received from sim, used for caching
U32 mTotalCRC;
- LLPointer<LLViewerImage> *mTEImages;
+ LLPointer<LLViewerTexture> *mTEImages;
// Selection, picking and rendering variables
U32 mGLName; // GL "name" used by selection code
diff --git a/indra/newview/llviewerobjectlist.cpp b/indra/newview/llviewerobjectlist.cpp
index e0741e7233..a8232e9a9d 100644
--- a/indra/newview/llviewerobjectlist.cpp
+++ b/indra/newview/llviewerobjectlist.cpp
@@ -38,6 +38,7 @@
#include "timing.h"
#include "llfasttimer.h"
#include "llrender.h"
+#include "llwindow.h" // decBusyCount()
#include "llviewercontrol.h"
#include "llface.h"
@@ -60,11 +61,12 @@
#include "llresmgr.h"
#include "llviewerregion.h"
#include "llviewerstats.h"
+#include "llvoavatarself.h"
#include "lltoolmgr.h"
#include "lltoolpie.h"
#include "llkeyboard.h"
#include "u64.h"
-#include "llviewerimagelist.h"
+#include "llviewertexturelist.h"
#include "lldatapacker.h"
#ifdef LL_STANDALONE
#include <zlib.h>
@@ -210,6 +212,7 @@ void LLViewerObjectList::processUpdateCore(LLViewerObject* objectp,
LLDataPacker* dpp,
BOOL just_created)
{
+ LLMemType mt(LLMemType::MTYPE_OBJECT_PROCESS_UPDATE_CORE);
LLMessageSystem* msg = gMessageSystem;
// ignore returned flags
@@ -251,16 +254,19 @@ void LLViewerObjectList::processUpdateCore(LLViewerObject* objectp,
objectp->mCreateSelected = false;
gViewerWindow->getWindow()->decBusyCount();
- gViewerWindow->getWindow()->setCursor( UI_CURSOR_ARROW );
+ gViewerWindow->setCursor( UI_CURSOR_ARROW );
}
}
+static LLFastTimer::DeclareTimer FTM_PROCESS_OBJECTS("Process Objects");
+
void LLViewerObjectList::processObjectUpdate(LLMessageSystem *mesgsys,
void **user_data,
const EObjectUpdateType update_type,
bool cached, bool compressed)
{
- LLFastTimer t(LLFastTimer::FTM_PROCESS_OBJECTS);
+ LLMemType mt(LLMemType::MTYPE_OBJECT_PROCESS_UPDATE);
+ LLFastTimer t(FTM_PROCESS_OBJECTS);
LLVector3d camera_global = gAgent.getCameraPositionGlobal();
LLViewerObject *objectp;
@@ -554,7 +560,7 @@ void LLViewerObjectList::updateApparentAngles(LLAgent &agent)
{
num_updates = mObjects.count() - mCurLazyUpdateIndex;
max_value = mObjects.count();
- gImageList.setUpdateStats(TRUE);
+ gTextureList.setUpdateStats(TRUE);
}
else
{
@@ -768,10 +774,10 @@ void LLViewerObjectList::update(LLAgent &agent, LLWorld &world)
}
*/
- mNumObjectsStat.addValue(mObjects.count());
- mNumActiveObjectsStat.addValue(num_active_objects);
- mNumSizeCulledStat.addValue(mNumSizeCulled);
- mNumVisCulledStat.addValue(mNumVisCulled);
+ LLViewerStats::getInstance()->mNumObjectsStat.addValue(mObjects.count());
+ LLViewerStats::getInstance()->mNumActiveObjectsStat.addValue(num_active_objects);
+ LLViewerStats::getInstance()->mNumSizeCulledStat.addValue(mNumSizeCulled);
+ LLViewerStats::getInstance()->mNumVisCulledStat.addValue(mNumVisCulled);
}
void LLViewerObjectList::clearDebugText()
@@ -1016,16 +1022,16 @@ void LLViewerObjectList::shiftObjects(const LLVector3 &offset)
void LLViewerObjectList::renderObjectsForMap(LLNetMap &netmap)
{
- LLColor4 above_water_color = gColors.getColor( "NetMapOtherOwnAboveWater" );
- LLColor4 below_water_color = gColors.getColor( "NetMapOtherOwnBelowWater" );
+ LLColor4 above_water_color = LLUIColorTable::instance().getColor( "NetMapOtherOwnAboveWater" );
+ LLColor4 below_water_color = LLUIColorTable::instance().getColor( "NetMapOtherOwnBelowWater" );
LLColor4 you_own_above_water_color =
- gColors.getColor( "NetMapYouOwnAboveWater" );
+ LLUIColorTable::instance().getColor( "NetMapYouOwnAboveWater" );
LLColor4 you_own_below_water_color =
- gColors.getColor( "NetMapYouOwnBelowWater" );
+ LLUIColorTable::instance().getColor( "NetMapYouOwnBelowWater" );
LLColor4 group_own_above_water_color =
- gColors.getColor( "NetMapGroupOwnAboveWater" );
+ LLUIColorTable::instance().getColor( "NetMapGroupOwnAboveWater" );
LLColor4 group_own_below_water_color =
- gColors.getColor( "NetMapGroupOwnBelowWater" );
+ LLUIColorTable::instance().getColor( "NetMapGroupOwnBelowWater" );
for (S32 i = 0; i < mMapObjects.count(); i++)
@@ -1300,12 +1306,13 @@ LLViewerObject *LLViewerObjectList::createObjectViewer(const LLPCode pcode, LLVi
}
+static LLFastTimer::DeclareTimer FTM_CREATE_OBJECT("Create Object");
LLViewerObject *LLViewerObjectList::createObject(const LLPCode pcode, LLViewerRegion *regionp,
const LLUUID &uuid, const U32 local_id, const LLHost &sender)
{
LLMemType mt(LLMemType::MTYPE_OBJECT);
- LLFastTimer t(LLFastTimer::FTM_CREATE_OBJECT);
+ LLFastTimer t(FTM_CREATE_OBJECT);
LLUUID fullid;
if (uuid == LLUUID::null)
diff --git a/indra/newview/llviewerobjectlist.h b/indra/newview/llviewerobjectlist.h
index ba31f70c3d..ace5c5038e 100644
--- a/indra/newview/llviewerobjectlist.h
+++ b/indra/newview/llviewerobjectlist.h
@@ -39,11 +39,13 @@
// common includes
#include "llstat.h"
#include "lldarrayptr.h"
+#include "llmap.h" // *TODO: switch to std::map
#include "llstring.h"
// project includes
#include "llviewerobject.h"
+class LLCamera;
class LLNetMap;
class LLDebugBeacon;
@@ -150,19 +152,8 @@ public:
U32 mCurBin; // Current bin we're working on...
- //////////////////////
- //
- // Statistics data
- //
- //
- LLStat mNumObjectsStat;
- LLStat mNumActiveObjectsStat;
- LLStat mNumNewObjectsStat;
- LLStat mNumSizeCulledStat;
- LLStat mNumVisCulledStat;
-
+ // Statistics data (see also LLViewerStats)
S32 mNumNewObjects;
-
S32 mNumSizeCulled;
S32 mNumVisCulled;
diff --git a/indra/newview/llviewerparcelmedia.cpp b/indra/newview/llviewerparcelmedia.cpp
index b98f418d49..cb233085e5 100644
--- a/indra/newview/llviewerparcelmedia.cpp
+++ b/indra/newview/llviewerparcelmedia.cpp
@@ -41,47 +41,22 @@
#include "llviewerparcelmgr.h"
#include "lluuid.h"
#include "message.h"
+#include "llviewermediafocus.h"
#include "llviewerparcelmediaautoplay.h"
#include "llviewerwindow.h"
#include "llfirstuse.h"
+#include "llpluginclassmedia.h"
// Static Variables
S32 LLViewerParcelMedia::sMediaParcelLocalID = 0;
LLUUID LLViewerParcelMedia::sMediaRegionID;
+viewer_media_t LLViewerParcelMedia::sMediaImpl;
+
// Local functions
bool callback_play_media(const LLSD& notification, const LLSD& response, LLParcel* parcel);
-// Move this to its own file.
-// helper class that tries to download a URL from a web site and calls a method
-// on the Panel Land Media and to discover the MIME type
-class LLMimeDiscoveryResponder : public LLHTTPClient::Responder
-{
-public:
- LLMimeDiscoveryResponder( )
- {}
-
-
-
- virtual void completedHeader(U32 status, const std::string& reason, const LLSD& content)
- {
- std::string media_type = content["content-type"].asString();
- std::string::size_type idx1 = media_type.find_first_of(";");
- std::string mime_type = media_type.substr(0, idx1);
- completeAny(status, mime_type);
- }
-
- virtual void error( U32 status, const std::string& reason )
- {
- completeAny(status, "none/none");
- }
-
- void completeAny(U32 status, const std::string& mime_type)
- {
- LLViewerMedia::setMimeType(mime_type);
- }
-};
// static
void LLViewerParcelMedia::initClass()
@@ -92,6 +67,13 @@ void LLViewerParcelMedia::initClass()
LLViewerParcelMediaAutoPlay::initClass();
}
+//static
+void LLViewerParcelMedia::cleanupClass()
+{
+ // This needs to be destroyed before global destructor time.
+ sMediaImpl = NULL;
+}
+
//////////////////////////////////////////////////////////////////////////////////////////
// static
void LLViewerParcelMedia::update(LLParcel* parcel)
@@ -105,6 +87,7 @@ void LLViewerParcelMedia::update(LLParcel* parcel)
{
sMediaRegionID = LLUUID() ;
stop() ;
+ LL_DEBUGS("Media") << "no agent region, bailing out." << LL_ENDL;
return ;
}
@@ -115,64 +98,54 @@ void LLViewerParcelMedia::update(LLParcel* parcel)
LLUUID regionid = gAgent.getRegion()->getRegionID();
if (parcelid != sMediaParcelLocalID || regionid != sMediaRegionID)
{
+ LL_DEBUGS("Media") << "New parcel, parcel id = " << parcelid << ", region id = " << regionid << LL_ENDL;
sMediaParcelLocalID = parcelid;
sMediaRegionID = regionid;
new_parcel = true;
}
std::string mediaUrl = std::string ( parcel->getMediaURL () );
+ std::string mediaCurrentUrl = std::string( parcel->getMediaCurrentURL());
+
+ // First use warning
+ if( ! mediaUrl.empty() && gWarningSettings.getBOOL("FirstStreamingVideo") )
+ {
+ LLNotifications::instance().add("ParcelCanPlayMedia", LLSD(), LLSD(),
+ boost::bind(callback_play_media, _1, _2, parcel));
+ return;
+
+ }
+
+ // if we have a current (link sharing) url, use it instead
+ if (mediaCurrentUrl != "" && parcel->getMediaType() == "text/html")
+ {
+ mediaUrl = mediaCurrentUrl;
+ }
+
LLStringUtil::trim(mediaUrl);
+
+ // If no parcel media is playing, nothing left to do
+ if(sMediaImpl.isNull())
- // has something changed?
- if ( ( LLViewerMedia::getMediaURL() != mediaUrl )
- || ( LLViewerMedia::getMediaTextureID() != parcel->getMediaID () ) )
{
- bool video_was_playing = FALSE;
- bool same_media_id = LLViewerMedia::getMediaTextureID() == parcel->getMediaID ();
+ return;
+ }
- if (LLViewerMedia::isMediaPlaying())
+ // Media is playing...has something changed?
+ else if (( sMediaImpl->getMediaURL() != mediaUrl )
+ || ( sMediaImpl->getMediaTextureID() != parcel->getMediaID() )
+ || ( sMediaImpl->getMimeType() != parcel->getMediaType() ))
+ {
+ // Only play if the media types are the same.
+ if(sMediaImpl->getMimeType() == parcel->getMediaType())
{
- video_was_playing = TRUE;
+ play(parcel);
}
- if ( !mediaUrl.empty() && same_media_id && ! new_parcel)
- {
- // Someone has "changed the channel", changing the URL of a video
- // you were already watching. Automatically play provided the texture ID is the same
- if (video_was_playing)
- {
- // Poke the mime type in before calling play.
- // This is necessary because in this instance we are not waiting
- // for the results of a header curl. In order to change the channel
- // a mime type MUST be provided.
- LLViewerMedia::setMimeType(parcel->getMediaType());
- play(parcel);
- }
- }
else
{
stop();
}
-
- // Discover the MIME type
- // Disabled for the time being. Get the mime type from the parcel.
- if(gSavedSettings.getBOOL("AutoMimeDiscovery"))
- {
- LLHTTPClient::getHeaderOnly( mediaUrl, new LLMimeDiscoveryResponder());
- }
- else
- {
- LLViewerMedia::setMimeType(parcel->getMediaType());
- }
-
- // First use warning
- if( gSavedSettings.getWarning("FirstStreamingVideo") )
- {
- LLNotifications::instance().add("ParcelCanPlayMedia", LLSD(), LLSD(),
- boost::bind(callback_play_media, _1, _2, parcel));
-
- }
-
}
}
else
@@ -183,15 +156,15 @@ void LLViewerParcelMedia::update(LLParcel* parcel)
/*
else
{
- // no audio player, do a first use dialog if their is media here
+ // no audio player, do a first use dialog if there is media here
if (parcel)
{
std::string mediaUrl = std::string ( parcel->getMediaURL () );
if (!mediaUrl.empty ())
{
- if (gSavedSettings.getWarning("QuickTimeInstalled"))
+ if (gWarningSettings.getBOOL("QuickTimeInstalled"))
{
- gSavedSettings.setWarning("QuickTimeInstalled", FALSE);
+ gWarningSettings.setBOOL("QuickTimeInstalled", FALSE);
LLNotifications::instance().add("NoQuickTime" );
};
@@ -208,19 +181,57 @@ void LLViewerParcelMedia::play(LLParcel* parcel)
if (!parcel) return;
- if (!gSavedSettings.getBOOL("AudioStreamingVideo"))
+ if (!gSavedSettings.getBOOL("AudioSteamingMedia") || !gSavedSettings.getBOOL("AudioStreamingVideo"))
return;
std::string media_url = parcel->getMediaURL();
+ std::string media_current_url = parcel->getMediaCurrentURL();
std::string mime_type = parcel->getMediaType();
LLUUID placeholder_texture_id = parcel->getMediaID();
U8 media_auto_scale = parcel->getMediaAutoScale();
U8 media_loop = parcel->getMediaLoop();
S32 media_width = parcel->getMediaWidth();
S32 media_height = parcel->getMediaHeight();
- LLViewerMedia::play(media_url, mime_type, placeholder_texture_id,
- media_width, media_height, media_auto_scale,
- media_loop);
+
+ if(sMediaImpl)
+ {
+ // If the url and mime type are the same, call play again
+ if(sMediaImpl->getMediaURL() == media_url
+ && sMediaImpl->getMimeType() == mime_type
+ && sMediaImpl->getMediaTextureID() == placeholder_texture_id)
+ {
+ LL_DEBUGS("Media") << "playing with existing url " << media_url << LL_ENDL;
+
+ sMediaImpl->play();
+ }
+ // Else if the texture id's are the same, navigate and rediscover type
+ // MBW -- This causes other state from the previous parcel (texture size, autoscale, and looping) to get re-used incorrectly.
+ // It's also not really necessary -- just creating a new instance is fine.
+// else if(sMediaImpl->getMediaTextureID() == placeholder_texture_id)
+// {
+// sMediaImpl->navigateTo(media_url, mime_type, true);
+// }
+ else
+ {
+ // Since the texture id is different, we need to generate a new impl
+ LL_DEBUGS("Media") << "new media impl with mime type " << mime_type << ", url " << media_url << LL_ENDL;
+
+ // Delete the old one first so they don't fight over the texture.
+ sMediaImpl->stop();
+
+ sMediaImpl = LLViewerMedia::newMediaImpl(media_url, placeholder_texture_id,
+ media_width, media_height, media_auto_scale,
+ media_loop);
+ }
+ }
+ else
+ {
+ // There is no media impl, make a new one
+ sMediaImpl = LLViewerMedia::newMediaImpl(media_url, placeholder_texture_id,
+ media_width, media_height, media_auto_scale,
+ media_loop);
+ }
+
LLFirstUse::useMedia();
LLViewerParcelMediaAutoPlay::playStarted();
@@ -229,20 +240,38 @@ void LLViewerParcelMedia::play(LLParcel* parcel)
// static
void LLViewerParcelMedia::stop()
{
+ if(sMediaImpl.isNull())
+ {
+ return;
+ }
+
+ // We need to remove the media HUD if it is up.
+ LLViewerMediaFocus::getInstance()->clearFocus();
- LLViewerMedia::stop();
+ // This will kill the media instance.
+ sMediaImpl->stop();
+ sMediaImpl = NULL;
}
// static
void LLViewerParcelMedia::pause()
{
- LLViewerMedia::pause();
+ if(sMediaImpl.isNull())
+ {
+ return;
+ }
+ sMediaImpl->pause();
}
// static
void LLViewerParcelMedia::start()
{
- LLViewerMedia::start();
+ if(sMediaImpl.isNull())
+ {
+ return;
+ }
+ sMediaImpl->start();
+
LLFirstUse::useMedia();
LLViewerParcelMediaAutoPlay::playStarted();
@@ -251,16 +280,41 @@ void LLViewerParcelMedia::start()
// static
void LLViewerParcelMedia::seek(F32 time)
{
- LLViewerMedia::seek(time);
+ if(sMediaImpl.isNull())
+ {
+ return;
+ }
+ sMediaImpl->seek(time);
}
-
// static
-LLMediaBase::EStatus LLViewerParcelMedia::getStatus()
+void LLViewerParcelMedia::focus(bool focus)
{
- return LLViewerMedia::getStatus();
+ sMediaImpl->focus(focus);
}
+// static
+LLPluginClassMediaOwner::EMediaStatus LLViewerParcelMedia::getStatus()
+{
+ LLPluginClassMediaOwner::EMediaStatus result = LLPluginClassMediaOwner::MEDIA_NONE;
+
+ if(sMediaImpl.notNull() && sMediaImpl->hasMedia())
+ {
+ result = sMediaImpl->getMediaPlugin()->getStatus();
+ }
+
+ return result;
+}
+
+// static
+std::string LLViewerParcelMedia::getMimeType()
+{
+ return sMediaImpl.notNull() ? sMediaImpl->getMimeType() : "none/none";
+}
+viewer_media_t LLViewerParcelMedia::getParcelMedia()
+{
+ return sMediaImpl;
+}
//////////////////////////////////////////////////////////////////////////////////////////
// static
void LLViewerParcelMedia::processParcelMediaCommandMessage( LLMessageSystem *msg, void ** )
@@ -298,7 +352,7 @@ void LLViewerParcelMedia::processParcelMediaCommandMessage( LLMessageSystem *msg
if(( command == PARCEL_MEDIA_COMMAND_PLAY ) ||
( command == PARCEL_MEDIA_COMMAND_LOOP ))
{
- if (LLViewerMedia::isMediaPaused())
+ if (getStatus() == LLViewerMediaImpl::MEDIA_PAUSED)
{
start();
}
@@ -318,7 +372,7 @@ void LLViewerParcelMedia::processParcelMediaCommandMessage( LLMessageSystem *msg
if (flags & (1<<PARCEL_MEDIA_COMMAND_TIME))
{
- if(! LLViewerMedia::hasMedia())
+ if(sMediaImpl.isNull())
{
LLParcel *parcel = LLViewerParcelMgr::getInstance()->getAgentParcel();
play(parcel);
@@ -382,6 +436,107 @@ void LLViewerParcelMedia::processParcelMediaUpdate( LLMessageSystem *msg, void *
}
}
}
+// Static
+/////////////////////////////////////////////////////////////////////////////////////////
+void LLViewerParcelMedia::sendMediaNavigateMessage(const std::string& url)
+{
+ std::string region_url = gAgent.getRegion()->getCapability("ParcelNavigateMedia");
+ if (!region_url.empty())
+ {
+ // send navigate event to sim for link sharing
+ LLSD body;
+ body["agent-id"] = gAgent.getID();
+ body["local-id"] = LLViewerParcelMgr::getInstance()->getAgentParcel()->getLocalID();
+ body["url"] = url;
+ LLHTTPClient::post(region_url, body, new LLHTTPClient::Responder);
+ }
+ else
+ {
+ llwarns << "can't get ParcelNavigateMedia capability" << llendl;
+ }
+
+}
+
+/////////////////////////////////////////////////////////////////////////////////////////
+// inherited from LLViewerMediaObserver
+// virtual
+void LLViewerParcelMedia::handleMediaEvent(LLPluginClassMedia* self, EMediaEvent event)
+{
+ switch(event)
+ {
+ case MEDIA_EVENT_CONTENT_UPDATED:
+ {
+ // LL_DEBUGS("Media") << "Media event: MEDIA_EVENT_CONTENT_UPDATED " << LL_ENDL;
+ };
+ break;
+
+ case MEDIA_EVENT_TIME_DURATION_UPDATED:
+ {
+ // LL_DEBUGS("Media") << "Media event: MEDIA_EVENT_TIME_DURATION_UPDATED, time is " << self->getCurrentTime() << " of " << self->getDuration() << LL_ENDL;
+ };
+ break;
+
+ case MEDIA_EVENT_SIZE_CHANGED:
+ {
+ LL_DEBUGS("Media") << "Media event: MEDIA_EVENT_SIZE_CHANGED " << LL_ENDL;
+ };
+ break;
+
+ case MEDIA_EVENT_CURSOR_CHANGED:
+ {
+ LL_DEBUGS("Media") << "Media event: MEDIA_EVENT_CURSOR_CHANGED, new cursor is " << self->getCursorName() << LL_ENDL;
+ };
+ break;
+
+ case MEDIA_EVENT_NAVIGATE_BEGIN:
+ {
+ LL_DEBUGS("Media") << "Media event: MEDIA_EVENT_NAVIGATE_BEGIN " << LL_ENDL;
+ };
+ break;
+
+ case MEDIA_EVENT_NAVIGATE_COMPLETE:
+ {
+ LL_DEBUGS("Media") << "Media event: MEDIA_EVENT_NAVIGATE_COMPLETE, result string is: " << self->getNavigateResultString() << LL_ENDL;
+ };
+ break;
+
+ case MEDIA_EVENT_PROGRESS_UPDATED:
+ {
+ LL_DEBUGS("Media") << "Media event: MEDIA_EVENT_PROGRESS_UPDATED, loading at " << self->getProgressPercent() << "%" << LL_ENDL;
+ };
+ break;
+
+ case MEDIA_EVENT_STATUS_TEXT_CHANGED:
+ {
+ LL_DEBUGS("Media") << "Media event: MEDIA_EVENT_STATUS_TEXT_CHANGED, new status text is: " << self->getStatusText() << LL_ENDL;
+ };
+ break;
+
+ case MEDIA_EVENT_LOCATION_CHANGED:
+ {
+ LL_DEBUGS("Media") << "Media event: MEDIA_EVENT_LOCATION_CHANGED, new uri is: " << self->getLocation() << LL_ENDL;
+ };
+ break;
+
+ case MEDIA_EVENT_CLICK_LINK_HREF:
+ {
+ LL_DEBUGS("Media") << "Media event: MEDIA_EVENT_CLICK_LINK_HREF, target is \"" << self->getClickTarget() << "\", uri is " << self->getClickURL() << LL_ENDL;
+ };
+ break;
+
+ case MEDIA_EVENT_CLICK_LINK_NOFOLLOW:
+ {
+ LL_DEBUGS("Media") << "Media event: MEDIA_EVENT_CLICK_LINK_NOFOLLOW, uri is " << self->getClickURL() << LL_ENDL;
+ };
+ break;
+
+ case MEDIA_EVENT_PLUGIN_FAILED:
+ {
+ LL_DEBUGS("Media") << "Media event: MEDIA_EVENT_PLUGIN_FAILED" << LL_ENDL;
+ };
+ break;
+ };
+}
bool callback_play_media(const LLSD& notification, const LLSD& response, LLParcel* parcel)
{
@@ -389,13 +544,31 @@ bool callback_play_media(const LLSD& notification, const LLSD& response, LLParce
if (option == 0)
{
gSavedSettings.setBOOL("AudioStreamingVideo", TRUE);
+ if(!gSavedSettings.getBOOL("AudioSteamingMedia"))
+ gSavedSettings.setBOOL("AudioSteamingMedia", TRUE);
LLViewerParcelMedia::play(parcel);
}
else
{
gSavedSettings.setBOOL("AudioStreamingVideo", FALSE);
}
- gSavedSettings.setWarning("FirstStreamingVideo", FALSE);
+ gWarningSettings.setBOOL("FirstStreamingVideo", FALSE);
return false;
}
+// TODO: observer
+/*
+void LLViewerParcelMediaNavigationObserver::onNavigateComplete( const EventType& event_in )
+{
+ std::string url = event_in.getStringValue();
+
+ if (mCurrentURL != url && ! mFromMessage)
+ {
+ LLViewerParcelMedia::sendMediaNavigateMessage(url);
+ }
+
+ mCurrentURL = url;
+ mFromMessage = false;
+
+}
+*/
diff --git a/indra/newview/llviewerparcelmedia.h b/indra/newview/llviewerparcelmedia.h
index 18988704d8..3f7f898356 100644
--- a/indra/newview/llviewerparcelmedia.h
+++ b/indra/newview/llviewerparcelmedia.h
@@ -33,18 +33,22 @@
#ifndef LLVIEWERPARCELMEDIA_H
#define LLVIEWERPARCELMEDIA_H
-#include "llmediabase.h"
+#include "llviewermedia.h"
class LLMessageSystem;
class LLParcel;
+class LLViewerParcelMediaNavigationObserver;
+
// This class understands land parcels, network traffic, LSL media
// transport commands, and talks to the LLViewerMedia class to actually
// do playback. It allows us to remove code from LLViewerParcelMgr.
-class LLViewerParcelMedia
+class LLViewerParcelMedia : public LLViewerMediaObserver
{
+ LOG_CLASS(LLViewerParcelMedia);
public:
static void initClass();
+ static void cleanupClass();
static void update(LLParcel* parcel);
// called when the agent's parcel has a new URL, or the agent has
@@ -60,17 +64,38 @@ class LLViewerParcelMedia
static void start();
// restart after pause - no need for all the setup
+ static void focus(bool focus);
+
static void seek(F32 time);
// jump to timecode time
- static LLMediaBase::EStatus getStatus();
+ static LLPluginClassMediaOwner::EMediaStatus getStatus();
+ static std::string getMimeType();
+ static viewer_media_t getParcelMedia();
static void processParcelMediaCommandMessage( LLMessageSystem *msg, void ** );
static void processParcelMediaUpdate( LLMessageSystem *msg, void ** );
+ static void sendMediaNavigateMessage(const std::string& url);
+
+ // inherited from LLViewerMediaObserver
+ virtual void handleMediaEvent(LLPluginClassMedia* self, EMediaEvent event);
public:
static S32 sMediaParcelLocalID;
static LLUUID sMediaRegionID;
+ // HACK: this will change with Media on a Prim
+ static viewer_media_t sMediaImpl;
+};
+
+
+class LLViewerParcelMediaNavigationObserver
+{
+public:
+ std::string mCurrentURL;
+ bool mFromMessage;
+
+ // void onNavigateComplete( const EventType& event_in );
+
};
#endif
diff --git a/indra/newview/llviewerparcelmediaautoplay.cpp b/indra/newview/llviewerparcelmediaautoplay.cpp
index dbb9c32008..1b79b47905 100644
--- a/indra/newview/llviewerparcelmediaautoplay.cpp
+++ b/indra/newview/llviewerparcelmediaautoplay.cpp
@@ -39,7 +39,7 @@
#include "llviewerparcelmgr.h"
#include "lluuid.h"
#include "message.h"
-#include "llviewerimagelist.h" // for texture stats
+#include "llviewertexturelist.h" // for texture stats
#include "llagent.h"
const F32 AUTOPLAY_TIME = 5; // how many seconds before we autoplay
@@ -109,17 +109,17 @@ BOOL LLViewerParcelMediaAutoPlay::tick()
if ((!mPlayed) && // if we've never played
(mTimeInParcel > AUTOPLAY_TIME) && // and if we've been here for so many seconds
(this_media_url.size() != 0) && // and if the parcel has media
- (!LLViewerMedia::isMediaPlaying())) // and if the media is not already playing
+ (LLViewerParcelMedia::sMediaImpl.isNull())) // and if the media is not already playing
{
if (this_media_texture_id.notNull()) // and if the media texture is good
{
- LLViewerImage *image = gImageList.getImage(this_media_texture_id, FALSE);
+ LLViewerMediaTexture *image = LLViewerTextureManager::getMediaTexture(this_media_texture_id, FALSE) ;
F32 image_size = 0;
if (image)
{
- image_size = image->mMaxVirtualSize;
+ image_size = image->getMaxVirtualSize() ;
}
if (gAgent.getVelocity().magVec() < AUTOPLAY_SPEED) // and if the agent is stopped (slow enough)
diff --git a/indra/newview/llviewerparcelmediaautoplay.h b/indra/newview/llviewerparcelmediaautoplay.h
index cc2e70b1b9..16279e7f1f 100644
--- a/indra/newview/llviewerparcelmediaautoplay.h
+++ b/indra/newview/llviewerparcelmediaautoplay.h
@@ -33,7 +33,6 @@
#ifndef LLVIEWERPARCELMEDIAAUTOPLAY_H
#define LLVIEWERPARCELMEDIAAUTOPLAY_H
-#include "llmediabase.h"
#include "lltimer.h"
// timer to automatically play media
diff --git a/indra/newview/llviewerparcelmgr.cpp b/indra/newview/llviewerparcelmgr.cpp
index 193dfaae96..ca3061e083 100644
--- a/indra/newview/llviewerparcelmgr.cpp
+++ b/indra/newview/llviewerparcelmgr.cpp
@@ -35,7 +35,7 @@
#include "llviewerparcelmgr.h"
// Library includes
-#include "audioengine.h"
+#include "llaudioengine.h"
#include "indra_constants.h"
#include "llcachename.h"
#include "llgl.h"
@@ -45,7 +45,6 @@
// Viewer includes
#include "llagent.h"
-#include "llfloatergroupinfo.h"
#include "llviewerwindow.h"
#include "llviewercontrol.h"
#include "llfirstuse.h"
@@ -60,8 +59,8 @@
#include "llsdutil.h"
#include "llstatusbar.h"
#include "llui.h"
-#include "llviewerimage.h"
-#include "llviewerimagelist.h"
+#include "llviewertexture.h"
+#include "llviewertexturelist.h"
#include "llviewermenu.h"
#include "llviewerparcelmedia.h"
#include "llviewerparceloverlay.h"
@@ -80,8 +79,8 @@ U8* LLViewerParcelMgr::sPackedOverlay = NULL;
LLUUID gCurrentMovieID = LLUUID::null;
-LLPointer<LLViewerImage> sBlockedImage;
-LLPointer<LLViewerImage> sPassImage;
+LLPointer<LLViewerTexture> sBlockedImage;
+LLPointer<LLViewerTexture> sPassImage;
// Local functions
void optionally_start_music(const std::string& music_url);
@@ -143,8 +142,11 @@ LLViewerParcelMgr::LLViewerParcelMgr()
mCollisionSegments = new U8[(mParcelsPerEdge+1)*(mParcelsPerEdge+1)];
resetSegments(mCollisionSegments);
- mBlockedImage = gImageList.getImageFromFile("noentrylines.j2c");
- mPassImage = gImageList.getImageFromFile("noentrypasslines.j2c");
+ // JC: Resolved a merge conflict here, eliminated
+ // mBlockedImage->setAddressMode(LLTexUnit::TAM_WRAP);
+ // because it is done in llviewertexturelist.cpp
+ mBlockedImage = LLViewerTextureManager::getFetchedTextureFromFile("world/NoEntryLines.png");
+ mPassImage = LLViewerTextureManager::getFetchedTextureFromFile("world/NoEntryPassLines.png");
S32 overlay_size = mParcelsPerEdge * mParcelsPerEdge / PARCEL_OVERLAY_CHUNKS;
sPackedOverlay = new U8[overlay_size];
@@ -155,6 +157,8 @@ LLViewerParcelMgr::LLViewerParcelMgr()
{
mAgentParcelOverlay[i] = 0;
}
+
+ mTeleportInProgress = TRUE; // the initial parcel update is treated like teleport
}
@@ -646,7 +650,7 @@ LLParcel *LLViewerParcelMgr::getAgentParcel() const
}
// Return whether the agent can build on the land they are on
-BOOL LLViewerParcelMgr::agentCanBuild() const
+bool LLViewerParcelMgr::agentCanBuild() const
{
if (mAgentParcel)
{
@@ -760,13 +764,17 @@ BOOL LLViewerParcelMgr::canHearSound(const LLVector3d &pos_global) const
BOOL LLViewerParcelMgr::inAgentParcel(const LLVector3d &pos_global) const
{
LLViewerRegion* region = LLWorld::getInstance()->getRegionFromPosGlobal(pos_global);
- if (region != gAgent.getRegion())
+ LLViewerRegion* agent_region = gAgent.getRegion();
+ if (!region || !agent_region)
+ return FALSE;
+
+ if (region != agent_region)
{
// Can't be in the agent parcel if you're not in the same region.
return FALSE;
}
- LLVector3 pos_region = gAgent.getRegion()->getPosRegionFromGlobal(pos_global);
+ LLVector3 pos_region = agent_region->getPosRegionFromGlobal(pos_global);
S32 row = S32(pos_region.mV[VY] / PARCEL_GRID_STEP_METERS);
S32 column = S32(pos_region.mV[VX] / PARCEL_GRID_STEP_METERS);
@@ -938,7 +946,7 @@ void LLViewerParcelMgr::sendParcelGodForceOwner(const LLUUID& owner_id)
payload["parcel_local_id"] = mCurrentParcel->getLocalID();
payload["region_host"] = region->getHost().getIPandPort();
LLNotification::Params params("ForceOwnerAuctionWarning");
- params.payload(payload).functor(callback_god_force_owner);
+ params.payload(payload).functor.function(callback_god_force_owner);
if(mCurrentParcel->getAuctionID())
{
@@ -1513,6 +1521,17 @@ void LLViewerParcelMgr::processParcelProperties(LLMessageSystem *msg, void **use
LLViewerParcelMgr::getInstance()->writeAgentParcelFromBitmap(bitmap);
delete[] bitmap;
+
+ // Let interesting parties know about agent parcel change.
+ LLViewerParcelMgr* instance = LLViewerParcelMgr::getInstance();
+
+ instance->mAgentParcelChangedSignal();
+
+ if (instance->mTeleportInProgress)
+ {
+ instance->mTeleportInProgress = FALSE;
+ instance->mTeleportFinishedSignal(gAgent.getPositionGlobal());
+ }
}
}
@@ -1584,6 +1603,9 @@ void LLViewerParcelMgr::processParcelProperties(LLMessageSystem *msg, void **use
// Request access list information for this land
LLViewerParcelMgr::getInstance()->sendParcelAccessListRequest(AL_ACCESS | AL_BAN);
+ // Request the media url filter list for this land
+ LLViewerParcelMgr::getInstance()->requestParcelMediaURLFilter();
+
// Request dwell for this land, if it's not public land.
LLViewerParcelMgr::getInstance()->mSelectedDwell = 0.f;
if (0 != local_id)
@@ -1697,7 +1719,7 @@ void LLViewerParcelMgr::processParcelProperties(LLMessageSystem *msg, void **use
void optionally_start_music(const std::string& music_url)
{
- if (gSavedSettings.getBOOL("AudioStreamingMusic"))
+ if (gSavedSettings.getBOOL("AudioStreamingMusic") && gSavedSettings.getBOOL("AudioSteamingMedia"))
{
// Make the user click the start button on the overlay bar. JC
// llinfos << "Starting parcel music " << music_url << llendl;
@@ -1907,6 +1929,66 @@ void LLViewerParcelMgr::sendParcelAccessListUpdate(U32 which)
}
}
+class LLParcelMediaURLFilterResponder : public LLHTTPClient::Responder
+{
+ virtual void result(const LLSD& content)
+ {
+ LLViewerParcelMgr::getInstance()->receiveParcelMediaURLFilter(content);
+ }
+};
+
+void LLViewerParcelMgr::requestParcelMediaURLFilter()
+{
+ if (!mSelected)
+ {
+ return;
+ }
+
+ LLViewerRegion* region = LLWorld::getInstance()->getRegionFromPosGlobal( mWestSouth );
+ if (!region)
+ {
+ return;
+ }
+
+ LLParcel* parcel = mCurrentParcel;
+ if (!parcel)
+ {
+ llwarns << "no parcel" << llendl;
+ return;
+ }
+
+ LLSD body;
+ body["local-id"] = parcel->getLocalID();
+ body["list"] = parcel->getMediaURLFilterList();
+
+ std::string url = region->getCapability("ParcelMediaURLFilterList");
+ if (!url.empty())
+ {
+ LLHTTPClient::post(url, body, new LLParcelMediaURLFilterResponder);
+ }
+ else
+ {
+ llwarns << "can't get ParcelMediaURLFilterList cap" << llendl;
+ }
+}
+
+
+void LLViewerParcelMgr::receiveParcelMediaURLFilter(const LLSD &content)
+{
+ if (content.has("list"))
+ {
+ LLParcel* parcel = LLViewerParcelMgr::getInstance()->mCurrentParcel;
+ if (!parcel) return;
+
+ if (content["local-id"].asInteger() == parcel->getLocalID())
+ {
+ parcel->setMediaURLFilterList(content["list"]);
+
+ LLViewerParcelMgr::getInstance()->notifyObservers();
+ }
+ }
+}
+
void LLViewerParcelMgr::deedLandToGroup()
{
@@ -2369,12 +2451,60 @@ void LLViewerParcelMgr::cleanupGlobals()
LLParcelSelection::sNullSelection = NULL;
}
-LLViewerImage* LLViewerParcelMgr::getBlockedImage() const
+LLViewerTexture* LLViewerParcelMgr::getBlockedImage() const
{
return sBlockedImage;
}
-LLViewerImage* LLViewerParcelMgr::getPassImage() const
+LLViewerTexture* LLViewerParcelMgr::getPassImage() const
{
return sPassImage;
}
+
+boost::signals2::connection LLViewerParcelMgr::addAgentParcelChangedCallback(parcel_changed_callback_t cb)
+{
+ return mAgentParcelChangedSignal.connect(cb);
+}
+/*
+ * Set finish teleport callback. You can use it to observe all teleport events.
+ * NOTE:
+ * After local( in one region) teleports we
+ * cannot rely on gAgent.getPositionGlobal(),
+ * so the new position gets passed explicitly.
+ * Use args of this callback to get global position of avatar after teleport event.
+ */
+boost::signals2::connection LLViewerParcelMgr::setTeleportFinishedCallback(teleport_finished_callback_t cb)
+{
+ return mTeleportFinishedSignal.connect(cb);
+}
+
+boost::signals2::connection LLViewerParcelMgr::setTeleportFailedCallback(parcel_changed_callback_t cb)
+{
+ return mTeleportFailedSignal.connect(cb);
+}
+
+/* Ok, we're notified that teleport has been finished.
+ * We should now propagate the notification via mTeleportFinishedSignal
+ * to all interested parties.
+ */
+void LLViewerParcelMgr::onTeleportFinished(bool local, const LLVector3d& new_pos)
+{
+ if (local)
+ {
+ // Local teleport. We already have the agent parcel data.
+ // Emit the signal immediately.
+ getInstance()->mTeleportFinishedSignal(new_pos);
+ }
+ else
+ {
+ // Non-local teleport.
+ // The agent parcel data has not been updated yet.
+ // Let's wait for the update and then emit the signal.
+ mTeleportInProgress = TRUE;
+ }
+}
+
+void LLViewerParcelMgr::onTeleportFailed()
+{
+ mTeleportFailedSignal();
+}
diff --git a/indra/newview/llviewerparcelmgr.h b/indra/newview/llviewerparcelmgr.h
index 9f762a186c..7373366cd7 100644
--- a/indra/newview/llviewerparcelmgr.h
+++ b/indra/newview/llviewerparcelmgr.h
@@ -36,14 +36,17 @@
#include "v3dmath.h"
#include "lldarray.h"
#include "llframetimer.h"
-#include "llmemory.h"
+#include "llsingleton.h"
#include "llparcelselection.h"
#include "llui.h"
+#include <boost/function.hpp>
+#include <boost/signals2.hpp>
+
class LLUUID;
class LLMessageSystem;
class LLParcel;
-class LLViewerImage;
+class LLViewerTexture;
class LLViewerRegion;
// Constants for sendLandOwner
@@ -79,6 +82,11 @@ class LLViewerParcelMgr : public LLSingleton<LLViewerParcelMgr>
{
public:
+ typedef boost::function<void (const LLVector3d&)> teleport_finished_callback_t;
+ typedef boost::signals2::signal<void (const LLVector3d&)> teleport_finished_signal_t;
+ typedef boost::function<void()> parcel_changed_callback_t;
+ typedef boost::signals2::signal<void()> parcel_changed_signal_t;
+
LLViewerParcelMgr();
~LLViewerParcelMgr();
@@ -163,7 +171,7 @@ public:
BOOL agentCanTakeDamage() const;
BOOL agentCanFly() const;
F32 agentDrawDistance() const;
- BOOL agentCanBuild() const;
+ bool agentCanBuild() const;
F32 getHoverParcelWidth() const
{ return F32(mHoverEastNorth.mdV[VX] - mHoverWestSouth.mdV[VX]); }
@@ -198,6 +206,11 @@ public:
// Takes an Access List flag, like AL_ACCESS or AL_BAN
void sendParcelAccessListRequest(U32 flags);
+ // asks for the parcel's media url filter list
+ void requestParcelMediaURLFilter();
+ // receive the response
+ void receiveParcelMediaURLFilter(const LLSD &content);
+
// Dwell is not part of the usual parcel update information because the
// simulator doesn't actually know the per-parcel dwell. Ack! We have
// to get it out of the database.
@@ -256,6 +269,12 @@ public:
// the agent is banned or not in the allowed group
BOOL isCollisionBanned();
+ boost::signals2::connection addAgentParcelChangedCallback(parcel_changed_callback_t cb);
+ boost::signals2::connection setTeleportFinishedCallback(teleport_finished_callback_t cb);
+ boost::signals2::connection setTeleportFailedCallback(parcel_changed_callback_t cb);
+ void onTeleportFinished(bool local, const LLVector3d& new_pos);
+ void onTeleportFailed();
+
static BOOL isParcelOwnedByAgent(const LLParcel* parcelp, U64 group_proxy_power);
static BOOL isParcelModifiableByAgent(const LLParcel* parcelp, U64 group_proxy_power);
@@ -279,8 +298,8 @@ private:
static bool callbackJoinLand(const LLSD& notification, const LLSD& response);
//void finishClaim(BOOL user_to_user_sale, U32 join);
- LLViewerImage* getBlockedImage() const;
- LLViewerImage* getPassImage() const;
+ LLViewerTexture* getBlockedImage() const;
+ LLViewerTexture* getPassImage() const;
private:
BOOL mSelected;
@@ -303,6 +322,11 @@ private:
LLDynamicArray<LLParcelObserver*> mObservers;
+ BOOL mTeleportInProgress;
+ teleport_finished_signal_t mTeleportFinishedSignal;
+ parcel_changed_signal_t mTeleportFailedSignal;
+ parcel_changed_signal_t mAgentParcelChangedSignal;
+
// Array of pieces of parcel edges to potentially draw
// Has (parcels_per_edge + 1) * (parcels_per_edge + 1) elements so
// we can represent edges of the grid.
@@ -324,8 +348,8 @@ private:
BOOL mRenderSelection;
S32 mCollisionBanned;
LLFrameTimer mCollisionTimer;
- LLImageGL* mBlockedImage;
- LLImageGL* mPassImage;
+ LLViewerTexture* mBlockedImage;
+ LLViewerTexture* mPassImage;
// Media
S32 mMediaParcelId;
diff --git a/indra/newview/llviewerparceloverlay.cpp b/indra/newview/llviewerparceloverlay.cpp
index 866c2a91eb..1a91240abb 100644
--- a/indra/newview/llviewerparceloverlay.cpp
+++ b/indra/newview/llviewerparceloverlay.cpp
@@ -36,19 +36,20 @@
// indra includes
#include "llparcel.h"
+#include "llfloaterreg.h"
#include "llgl.h"
#include "llrender.h"
#include "v4color.h"
#include "v2math.h"
// newview includes
-#include "llviewerimage.h"
+#include "llviewertexture.h"
#include "llviewercontrol.h"
#include "llsurface.h"
#include "llviewerregion.h"
#include "llagent.h"
#include "llviewercamera.h"
-#include "llviewerimagelist.h"
+#include "llviewertexturelist.h"
#include "llselectmgr.h"
#include "llfloatertools.h"
#include "llglheaders.h"
@@ -68,10 +69,9 @@ LLViewerParcelOverlay::LLViewerParcelOverlay(LLViewerRegion* region, F32 region_
{
// Create a texture to hold color information.
// 4 components
- // Use mipmaps = FALSE, clamped, NEAREST filter, for sharp edges
- mTexture = new LLImageGL(FALSE);
+ // Use mipmaps = FALSE, clamped, NEAREST filter, for sharp edges
mImageRaw = new LLImageRaw(mParcelGridsPerEdge, mParcelGridsPerEdge, OVERLAY_IMG_COMPONENTS);
- mTexture->createGLTexture(0, mImageRaw);
+ mTexture = LLViewerTextureManager::getLocalTexture(mImageRaw.get(), FALSE);
gGL.getTexUnit(0)->activate();
gGL.getTexUnit(0)->bind(mTexture);
mTexture->setAddressMode(LLTexUnit::TAM_CLAMP);
@@ -205,13 +205,12 @@ void LLViewerParcelOverlay::updateOverlayTexture()
{
return;
}
- // Can do this because gColors are actually stored as LLColor4U
- const LLColor4U avail = gColors.getColor4U("PropertyColorAvail");
- const LLColor4U owned = gColors.getColor4U("PropertyColorOther");
- const LLColor4U group = gColors.getColor4U("PropertyColorGroup");
- const LLColor4U self = gColors.getColor4U("PropertyColorSelf");
- const LLColor4U for_sale = gColors.getColor4U("PropertyColorForSale");
- const LLColor4U auction = gColors.getColor4U("PropertyColorAuction");
+ const LLColor4U avail = LLUIColorTable::instance().getColor("PropertyColorAvail").get();
+ const LLColor4U owned = LLUIColorTable::instance().getColor("PropertyColorOther").get();
+ const LLColor4U group = LLUIColorTable::instance().getColor("PropertyColorGroup").get();
+ const LLColor4U self = LLUIColorTable::instance().getColor("PropertyColorSelf").get();
+ const LLColor4U for_sale = LLUIColorTable::instance().getColor("PropertyColorForSale").get();
+ const LLColor4U auction = LLUIColorTable::instance().getColor("PropertyColorAuction").get();
// Create the base texture.
U8 *raw = mImageRaw->getData();
@@ -224,7 +223,7 @@ void LLViewerParcelOverlay::updateOverlayTexture()
{
U8 ownership = mOwnership[i];
- U8 r,g,b,a;
+ F32 r,g,b,a;
// Color stored in low three bits
switch( ownership & 0x7 )
@@ -273,10 +272,10 @@ void LLViewerParcelOverlay::updateOverlayTexture()
break;
}
- raw[pixel_index + 0] = r;
- raw[pixel_index + 1] = g;
- raw[pixel_index + 2] = b;
- raw[pixel_index + 3] = a;
+ raw[pixel_index + 0] = (U8)r;
+ raw[pixel_index + 1] = (U8)g;
+ raw[pixel_index + 2] = (U8)b;
+ raw[pixel_index + 3] = (U8)a;
pixel_index += OVERLAY_IMG_COMPONENTS;
}
@@ -314,12 +313,11 @@ void LLViewerParcelOverlay::updatePropertyLines()
S32 row, col;
- // Can do this because gColors are actually stored as LLColor4U
- const LLColor4U self_coloru = gColors.getColor4U("PropertyColorSelf");
- const LLColor4U other_coloru = gColors.getColor4U("PropertyColorOther");
- const LLColor4U group_coloru = gColors.getColor4U("PropertyColorGroup");
- const LLColor4U for_sale_coloru = gColors.getColor4U("PropertyColorForSale");
- const LLColor4U auction_coloru = gColors.getColor4U("PropertyColorAuction");
+ const LLColor4U self_coloru = LLUIColorTable::instance().getColor("PropertyColorSelf").get();
+ const LLColor4U other_coloru = LLUIColorTable::instance().getColor("PropertyColorOther").get();
+ const LLColor4U group_coloru = LLUIColorTable::instance().getColor("PropertyColorGroup").get();
+ const LLColor4U for_sale_coloru = LLUIColorTable::instance().getColor("PropertyColorForSale").get();
+ const LLColor4U auction_coloru = LLUIColorTable::instance().getColor("PropertyColorAuction").get();
// Build into dynamic arrays, then copy into static arrays.
LLDynamicArray<LLVector3, 256> new_vertex_array;
@@ -713,6 +711,7 @@ void LLViewerParcelOverlay::setDirty()
void LLViewerParcelOverlay::idleUpdate(bool force_update)
{
+ LLMemType mt_iup(LLMemType::MTYPE_IDLE_UPDATE_PARCEL_OVERLAY);
if (gGLManager.mIsDisabled)
{
return;
@@ -841,8 +840,8 @@ S32 LLViewerParcelOverlay::renderPropertyLines ()
drawn += vertex_per_edge;
gGL.end();
-
- if (LLSelectMgr::sRenderHiddenSelections && gFloaterTools && gFloaterTools->getVisible())
+
+ if (LLSelectMgr::sRenderHiddenSelections && LLFloaterReg::instanceVisible("build"))
{
LLGLDepthTest depth(GL_TRUE, GL_FALSE, GL_GREATER);
diff --git a/indra/newview/llviewerparceloverlay.h b/indra/newview/llviewerparceloverlay.h
index 9bed1dde34..e673b811ed 100644
--- a/indra/newview/llviewerparceloverlay.h
+++ b/indra/newview/llviewerparceloverlay.h
@@ -39,7 +39,7 @@
#include "lldarray.h"
#include "llframetimer.h"
#include "lluuid.h"
-#include "llviewerimage.h"
+#include "llviewertexture.h"
class LLViewerRegion;
class LLVector3;
@@ -53,7 +53,7 @@ public:
~LLViewerParcelOverlay();
// ACCESS
- LLImageGL* getTexture() const { return mTexture; }
+ LLViewerTexture* getTexture() const { return mTexture; }
BOOL isOwned(const LLVector3& pos) const;
BOOL isOwnedSelf(const LLVector3& pos) const;
@@ -99,7 +99,7 @@ private:
S32 mParcelGridsPerEdge;
- LLPointer<LLImageGL> mTexture;
+ LLPointer<LLViewerTexture> mTexture;
LLPointer<LLImageRaw> mImageRaw;
// Size: mParcelGridsPerEdge * mParcelGridsPerEdge
diff --git a/indra/newview/llviewerpartsim.cpp b/indra/newview/llviewerpartsim.cpp
index b74f9e9f2c..cfb8340462 100644
--- a/indra/newview/llviewerpartsim.cpp
+++ b/indra/newview/llviewerpartsim.cpp
@@ -98,7 +98,7 @@ LLViewerPart::~LLViewerPart()
--LLViewerPartSim::sParticleCount2 ;
}
-void LLViewerPart::init(LLPointer<LLViewerPartSource> sourcep, LLViewerImage *imagep, LLVPCallback cb)
+void LLViewerPart::init(LLPointer<LLViewerPartSource> sourcep, LLViewerTexture *imagep, LLVPCallback cb)
{
LLMemType mt(LLMemType::MTYPE_PARTICLES);
mPartID = LLViewerPart::sNextPartID;
@@ -631,6 +631,8 @@ void LLViewerPartSim::shift(const LLVector3 &offset)
}
}
+static LLFastTimer::DeclareTimer FTM_SIMULATE_PARTICLES("Simulate Particles");
+
void LLViewerPartSim::updateSimulation()
{
LLMemType mt(LLMemType::MTYPE_PARTICLES);
@@ -644,7 +646,7 @@ void LLViewerPartSim::updateSimulation()
return;
}
- LLFastTimer ftm(LLFastTimer::FTM_SIMULATE_PARTICLES);
+ LLFastTimer ftm(FTM_SIMULATE_PARTICLES);
// Start at a random particle system so the same
// particle system doesn't always get first pick at the
diff --git a/indra/newview/llviewerpartsim.h b/indra/newview/llviewerpartsim.h
index 21bc37f891..8f1f72518a 100644
--- a/indra/newview/llviewerpartsim.h
+++ b/indra/newview/llviewerpartsim.h
@@ -35,14 +35,14 @@
#include "lldarrayptr.h"
#include "llframetimer.h"
-#include "llmemory.h"
+#include "llpointer.h"
#include "llpartdata.h"
#include "llviewerpartsource.h"
-class LLViewerImage;
+class LLViewerTexture;
class LLViewerPart;
class LLViewerRegion;
-class LLViewerImage;
+class LLViewerTexture;
class LLVOPartGroup;
typedef void (*LLVPCallback)(LLViewerPart &part, const F32 dt);
@@ -60,7 +60,7 @@ public:
public:
LLViewerPart();
- void init(LLPointer<LLViewerPartSource> sourcep, LLViewerImage *imagep, LLVPCallback cb);
+ void init(LLPointer<LLViewerPartSource> sourcep, LLViewerTexture *imagep, LLVPCallback cb);
U32 mPartID; // Particle ID used primarily for moving between groups
@@ -72,7 +72,7 @@ public:
// Current particle state (possibly used for rendering)
- LLPointer<LLViewerImage> mImagep;
+ LLPointer<LLViewerTexture> mImagep;
LLVector3 mPosAgent;
LLVector3 mVelocity;
LLVector3 mAccel;
diff --git a/indra/newview/llviewerpartsource.cpp b/indra/newview/llviewerpartsource.cpp
index 38c75a84d1..a8cbcd86c6 100644
--- a/indra/newview/llviewerpartsource.cpp
+++ b/indra/newview/llviewerpartsource.cpp
@@ -39,7 +39,7 @@
#include "llagent.h"
#include "lldrawable.h"
#include "llviewercamera.h"
-#include "llviewerimagelist.h"
+#include "llviewertexturelist.h"
#include "llviewerobject.h"
#include "llviewerobjectlist.h"
#include "llvoavatar.h"
@@ -78,7 +78,7 @@ void LLViewerPartSource::update(const F32 dt)
LLUUID LLViewerPartSource::getImageUUID() const
{
- LLViewerImage* imagep = mImagep;
+ LLViewerTexture* imagep = mImagep;
if(imagep)
{
return imagep->getID();
@@ -100,8 +100,8 @@ LLViewerPartSourceScript::LLViewerPartSourceScript(LLViewerObject *source_objp)
llassert(source_objp);
mSourceObjectp = source_objp;
mPosAgent = mSourceObjectp->getPositionAgent();
- mImagep = gImageList.getImageFromFile("pixiesmall.j2c");
- gGL.getTexUnit(0)->bind(mImagep.get());
+ mImagep = LLViewerTextureManager::getFetchedTextureFromFile("pixiesmall.j2c");
+ gGL.getTexUnit(0)->bind(mImagep);
mImagep->setAddressMode(LLTexUnit::TAM_CLAMP);
}
@@ -491,7 +491,7 @@ LLPointer<LLViewerPartSourceScript> LLViewerPartSourceScript::createPSS(LLViewer
}
-void LLViewerPartSourceScript::setImage(LLViewerImage *imagep)
+void LLViewerPartSourceScript::setImage(LLViewerTexture *imagep)
{
LLMemType mt(LLMemType::MTYPE_PARTICLES);
mImagep = imagep;
@@ -551,7 +551,7 @@ void LLViewerPartSourceSpiral::update(const F32 dt)
LLMemType mt(LLMemType::MTYPE_PARTICLES);
if (!mImagep)
{
- mImagep = gImageList.getImageFromFile("pixiesmall.j2c");
+ mImagep = LLViewerTextureManager::getFetchedTextureFromFile("pixiesmall.j2c");
}
const F32 RATE = 0.025f;
@@ -720,7 +720,7 @@ void LLViewerPartSourceBeam::update(const F32 dt)
if (!mImagep)
{
- mImagep = gImageList.getImageFromFile("pixiesmall.j2c");
+ mImagep = LLViewerTextureManager::getFetchedTextureFromFile("pixiesmall.j2c");
}
LLViewerPart* part = new LLViewerPart();
@@ -806,7 +806,7 @@ void LLViewerPartSourceChat::update(const F32 dt)
LLMemType mt(LLMemType::MTYPE_PARTICLES);
if (!mImagep)
{
- mImagep = gImageList.getImageFromFile("pixiesmall.j2c");
+ mImagep = LLViewerTextureManager::getFetchedTextureFromFile("pixiesmall.j2c");
}
diff --git a/indra/newview/llviewerpartsource.h b/indra/newview/llviewerpartsource.h
index 4258b9170f..540e30eb19 100644
--- a/indra/newview/llviewerpartsource.h
+++ b/indra/newview/llviewerpartsource.h
@@ -33,8 +33,9 @@
#ifndef LL_LLVIEWERPARTSOURCE_H
#define LL_LLVIEWERPARTSOURCE_H
-#include "llmemory.h"
+#include "llrefcount.h"
#include "llpartdata.h"
+#include "llpointer.h"
#include "llquaternion.h"
#include "v3math.h"
@@ -44,7 +45,7 @@
//
//
-class LLViewerImage;
+class LLViewerTexture;
class LLViewerObject;
class LLViewerPart;
@@ -89,7 +90,7 @@ protected:
F32 mLastUpdateTime;
F32 mLastPartTime;
LLUUID mOwnerUUID;
- LLPointer<LLViewerImage> mImagep;
+ LLPointer<LLViewerTexture> mImagep;
// Particle information
U32 mPartFlags; // Flags for the particle
@@ -122,8 +123,8 @@ public:
static LLPointer<LLViewerPartSourceScript> unpackPSS(LLViewerObject *source_objp, LLPointer<LLViewerPartSourceScript> pssp, LLDataPacker &dp);
static LLPointer<LLViewerPartSourceScript> createPSS(LLViewerObject *source_objp, const LLPartSysData& particle_parameters);
- LLViewerImage *getImage() const { return mImagep; }
- void setImage(LLViewerImage *imagep);
+ LLViewerTexture *getImage() const { return mImagep; }
+ void setImage(LLViewerTexture *imagep);
LLPartSysData mPartSysData;
void setTargetObject(LLViewerObject *objp);
diff --git a/indra/newview/llviewerprecompiledheaders.h b/indra/newview/llviewerprecompiledheaders.h
index 49319b13b1..8bf7364714 100644
--- a/indra/newview/llviewerprecompiledheaders.h
+++ b/indra/newview/llviewerprecompiledheaders.h
@@ -69,31 +69,37 @@
// Library headers from llcommon project:
#include "bitpack.h"
+#include "lldeleteutils.h"
#include "imageids.h"
#include "indra_constants.h"
//#include "linden_common.h"
//#include "llpreprocessor.h"
+#include "llallocator.h"
#include "llapp.h"
#include "llapr.h"
#include "llcriticaldamp.h"
-#include "lldarray.h"
-#include "lldarrayptr.h"
+//#include "lldarray.h"
+//#include "lldarrayptr.h"
#include "lldefs.h"
#include "lldepthstack.h"
-#include "lldqueueptr.h"
+//#include "lldqueueptr.h"
#include "llendianswizzle.h"
#include "llerror.h"
#include "llfasttimer.h"
-#include "llfixedbuffer.h"
#include "llframetimer.h"
#include "llhash.h"
#include "lllocalidhashmap.h"
#include "llmap.h"
-#include "llmemory.h"
+//#include "llmemory.h"
#include "llnametable.h"
+#include "llpointer.h"
#include "llpriqueuemap.h"
#include "llprocessor.h"
+#include "llrefcount.h"
+#include "llsafehandle.h"
//#include "llsecondlifeurls.h"
+#include "llsd.h"
+#include "llsingleton.h"
#include "llstack.h"
#include "llstat.h"
#include "llstl.h"
@@ -114,20 +120,13 @@
#include "u64.h"
// Library includes from llimage
-//#include "kdc_flow_control.h"
-//#include "kde_flow_control.h"
-//#include "kdu_image.h"
-//#include "kdu_image_local.h"
//#include "llblockdata.h"
-//#include "llblockdecoder.h"
-//#include "llblockencoder.h"
#include "llimage.h"
#include "llimagebmp.h"
#include "llimagepng.h"
#include "llimagej2c.h"
#include "llimagejpeg.h"
#include "llimagetga.h"
-//#include "llkdumem.h"
#include "llmapimagetype.h"
// Library includes from llmath project
@@ -220,9 +219,6 @@
#include "llvolumemgr.h"
#include "material_codes.h"
-// Library includes from llxml
-#include "llxmlnode.h"
-
// Library includes from llvfs
#include "llassettype.h"
#include "lldir.h"
@@ -232,4 +228,8 @@
#include "llvfile.h"
#include "llvfs.h"
+// Library includes from llui
+// In skinning-7, llui.h dependencies are changing too often.
+//#include "llui.h"
+
#endif
diff --git a/indra/newview/llviewerregion.cpp b/indra/newview/llviewerregion.cpp
index d4ee7a7e50..2c68a106c3 100644
--- a/indra/newview/llviewerregion.cpp
+++ b/indra/newview/llviewerregion.cpp
@@ -35,6 +35,7 @@
#include "llviewerregion.h"
#include "indra_constants.h"
+#include "llfloaterreg.h"
#include "llmath.h"
#include "llhttpclient.h"
#include "llregionflags.h"
@@ -638,6 +639,7 @@ void LLViewerRegion::dirtyHeights()
BOOL LLViewerRegion::idleUpdate(F32 max_update_time)
{
+ LLMemType mt_ivr(LLMemType::MTYPE_IDLE_UPDATE_VIEWER_REGION);
// did_update returns TRUE if we did at least one significant update
BOOL did_update = mLandp->idleUpdate(max_update_time);
@@ -779,11 +781,6 @@ void LLViewerRegion::calculateCameraDistance()
mCameraDistanceSquared = (F32)(gAgent.getCameraPositionGlobal() - getCenterGlobal()).magVecSquared();
}
-U32 LLViewerRegion::getNetDetailsForLCD()
-{
- return mPingDelay;
-}
-
std::ostream& operator<<(std::ostream &s, const LLViewerRegion &region)
{
s << "{ ";
@@ -1439,6 +1436,8 @@ void LLViewerRegion::setSeedCapability(const std::string& url)
capabilityNames.append("MapLayerGod");
capabilityNames.append("NewFileAgentInventory");
capabilityNames.append("ParcelPropertiesUpdate");
+ capabilityNames.append("ParcelMediaURLFilterList");
+ capabilityNames.append("ParcelNavigateMedia");
capabilityNames.append("ParcelVoiceInfoRequest");
capabilityNames.append("ProductInfoRequest");
capabilityNames.append("ProvisionVoiceAccountRequest");
diff --git a/indra/newview/llviewerregion.h b/indra/newview/llviewerregion.h
index 4d345c811a..49d0900f2a 100644
--- a/indra/newview/llviewerregion.h
+++ b/indra/newview/llviewerregion.h
@@ -51,6 +51,7 @@
#include "llweb.h"
#include "llcapabilityprovider.h"
#include "llcapabilitylistener.h"
+#include "m4math.h" // LLMatrix4
// Surface id's
#define LAND 1
@@ -288,9 +289,6 @@ public:
/// implements LLCapabilityProvider
virtual std::string getDescription() const;
- // used by LCD to get details for debug screen
- U32 getNetDetailsForLCD();
-
LLSpatialPartition* getSpatialPartition(U32 type);
public:
struct CompareDistance
diff --git a/indra/newview/llviewerstats.cpp b/indra/newview/llviewerstats.cpp
index 5f83cddf5b..994fbd8475 100644
--- a/indra/newview/llviewerstats.cpp
+++ b/indra/newview/llviewerstats.cpp
@@ -36,6 +36,8 @@
#include "llviewerthrottle.h"
#include "message.h"
+#include "llfloaterreg.h"
+#include "llmemory.h"
#include "lltimer.h"
#include "llappviewer.h"
@@ -43,8 +45,9 @@
#include "pipeline.h"
#include "lltexturefetch.h"
#include "llviewerobjectlist.h"
-#include "llviewerimagelist.h"
+#include "llviewertexturelist.h"
#include "lltexlayer.h"
+#include "lltexlayerparams.h"
#include "llsurface.h"
#include "llvlmanager.h"
#include "llagent.h"
@@ -55,14 +58,11 @@
#include "llfasttimerview.h"
#include "llviewerregion.h"
#include "llvoavatar.h"
-#include "llfloaterhtml.h"
+#include "llvoavatarself.h"
#include "llviewerwindow.h" // *TODO: remove, only used for width/height
#include "llworld.h"
#include "llfeaturemanager.h"
#include "llviewernetwork.h"
-#if LL_LCD_COMPILE
-#include "lllcd.h"
-#endif
class StatAttributes
@@ -199,16 +199,76 @@ const StatAttributes STAT_INFO[LLViewerStats::ST_COUNT] =
// ST_TEX_BAKES
StatAttributes("Texture Bakes", FALSE, FALSE),
// ST_TEX_REBAKES
- StatAttributes("Texture Rebakes", FALSE, FALSE),
-
- // ST_LOGITECH_KEYBOARD
- StatAttributes("Logitech LCD", FALSE, FALSE)
+ StatAttributes("Texture Rebakes", FALSE, FALSE)
};
-LLViewerStats::LLViewerStats()
- : mPacketsLostPercentStat(64),
- mLastTimeDiff(0.0)
+LLViewerStats::LLViewerStats() :
+ mKBitStat("kbitstat"),
+ mLayersKBitStat("layerskbitstat"),
+ mObjectKBitStat("objectkbitstat"),
+ mAssetKBitStat("assetkbitstat"),
+ mTextureKBitStat("texturekbitstat"),
+ mVFSPendingOperations("vfspendingoperations"),
+ mObjectsDrawnStat("objectsdrawnstat"),
+ mObjectsCulledStat("objectsculledstat"),
+ mObjectsTestedStat("objectstestedstat"),
+ mObjectsComparedStat("objectscomparedstat"),
+ mObjectsOccludedStat("objectsoccludedstat"),
+ mFPSStat("fpsstat"),
+ mPacketsInStat("packetsinstat"),
+ mPacketsLostStat("packetsloststat"),
+ mPacketsOutStat("packetsoutstat"),
+ mPacketsLostPercentStat("packetslostpercentstat", 64),
+ mTexturePacketsStat("texturepacketsstat"),
+ mActualInKBitStat("actualinkbitstat"),
+ mActualOutKBitStat("actualoutkbitstat"),
+ mTrianglesDrawnStat("trianglesdrawnstat"),
+ mSimTimeDilation("simtimedilation"),
+ mSimFPS("simfps"),
+ mSimPhysicsFPS("simphysicsfps"),
+ mSimAgentUPS("simagentups"),
+ mSimScriptEPS("simscripteps"),
+ mSimFrameMsec("simframemsec"),
+ mSimNetMsec("simnetmsec"),
+ mSimSimOtherMsec("simsimothermsec"),
+ mSimSimPhysicsMsec("simsimphysicsmsec"),
+ mSimSimPhysicsStepMsec("simsimphysicsstepmsec"),
+ mSimSimPhysicsShapeUpdateMsec("simsimphysicsshapeupdatemsec"),
+ mSimSimPhysicsOtherMsec("simsimphysicsothermsec"),
+ mSimAgentMsec("simagentmsec"),
+ mSimImagesMsec("simimagesmsec"),
+ mSimScriptMsec("simscriptmsec"),
+ mSimSpareMsec("simsparemsec"),
+ mSimSleepMsec("simsleepmsec"),
+ mSimPumpIOMsec("simpumpiomsec"),
+ mSimMainAgents("simmainagents"),
+ mSimChildAgents("simchildagents"),
+ mSimObjects("simobjects"),
+ mSimActiveObjects("simactiveobjects"),
+ mSimActiveScripts("simactivescripts"),
+ mSimInPPS("siminpps"),
+ mSimOutPPS("simoutpps"),
+ mSimPendingDownloads("simpendingdownloads"),
+ mSimPendingUploads("simpendinguploads"),
+ mSimPendingLocalUploads("simpendinglocaluploads"),
+ mSimTotalUnackedBytes("simtotalunackedbytes"),
+ mPhysicsPinnedTasks("physicspinnedtasks"),
+ mPhysicsLODTasks("physicslodtasks"),
+ mPhysicsMemoryAllocated("physicsmemoryallocated"),
+ mSimPingStat("simpingstat"),
+ mNumImagesStat("numimagesstat", 32, TRUE),
+ mNumRawImagesStat("numrawimagesstat", 32, TRUE),
+ mGLTexMemStat("gltexmemstat", 32, TRUE),
+ mGLBoundMemStat("glboundmemstat", 32, TRUE),
+ mRawMemStat("rawmemstat", 32, TRUE),
+ mFormattedMemStat("formattedmemstat", 32, TRUE),
+ mNumObjectsStat("numobjectsstat"),
+ mNumActiveObjectsStat("numactiveobjectsstat"),
+ mNumNewObjectsStat("numnewobjectsstat"),
+ mNumSizeCulledStat("numsizeculledstat"),
+ mNumVisCulledStat("numvisculledstat"),
+ mLastTimeDiff(0.0)
{
for (S32 i = 0; i < ST_COUNT; i++)
{
@@ -353,7 +413,6 @@ void reset_statistics()
{
if (LLSurface::sTextureUpdateTime)
{
- LLSurface::sTexelsUpdatedPerSecStat.addValue(0.001f*(LLSurface::sTexelsUpdated / LLSurface::sTextureUpdateTime));
LLSurface::sTexelsUpdated = 0;
LLSurface::sTextureUpdateTime = 0.f;
}
@@ -364,7 +423,7 @@ void output_statistics(void*)
{
llinfos << "Number of orphans: " << gObjectList.getOrphanCount() << llendl;
llinfos << "Number of dead objects: " << gObjectList.mNumDeadObjects << llendl;
- llinfos << "Num images: " << gImageList.getNumImages() << llendl;
+ llinfos << "Num images: " << gTextureList.getNumImages() << llendl;
llinfos << "Texture usage: " << LLImageGL::sGlobalTextureMemoryInBytes << llendl;
llinfos << "Texture working set: " << LLImageGL::sBoundTextureMemoryInBytes << llendl;
llinfos << "Raw usage: " << LLImageRaw::sGlobalRawMemory << llendl;
@@ -449,10 +508,10 @@ void output_statistics(void*)
llinfos << "--------------------------------" << llendl;
llinfos << "Avatar Memory (partly overlaps with above stats):" << llendl;
- gTexStaticImageList.dumpByteCount();
- LLVOAvatar::dumpScratchTextureByteCount();
+ LLTexLayerStaticImageList::getInstance()->dumpByteCount();
+ LLVOAvatarSelf::dumpScratchTextureByteCount();
LLTexLayerSetBuffer::dumpTotalByteCount();
- LLVOAvatar::dumpTotalLocalTextureByteCount();
+ LLVOAvatarSelf::dumpTotalLocalTextureByteCount();
LLTexLayerParamAlpha::dumpCacheByteCount();
LLVOAvatar::dumpBakedStatus();
@@ -507,7 +566,7 @@ void update_statistics(U32 frame_count)
{
gTotalWorldBytes += gVLManager.getTotalBytes();
gTotalObjectBytes += gObjectBits / 8;
- gTotalTextureBytes += LLViewerImageList::sTextureBits / 8;
+ gTotalTextureBytes += gTextureList.mTextureBits / 8;
// make sure we have a valid time delta for this frame
if (gFrameIntervalSeconds > 0.f)
@@ -520,7 +579,7 @@ void update_statistics(U32 frame_count)
{
LLViewerStats::getInstance()->incStat(LLViewerStats::ST_AVATAR_EDIT_SECONDS, gFrameIntervalSeconds);
}
- else if (gFloaterTools && gFloaterTools->getVisible())
+ else if (LLFloaterReg::instanceVisible("build"))
{
LLViewerStats::getInstance()->incStat(LLViewerStats::ST_TOOLBOX_SECONDS, gFrameIntervalSeconds);
}
@@ -534,14 +593,14 @@ void update_statistics(U32 frame_count)
LLViewerStats::getInstance()->setStat(LLViewerStats::ST_SHADER_AVATAR, (F64)gSavedSettings.getBOOL("VertexShaderLevelAvatar"));
LLViewerStats::getInstance()->setStat(LLViewerStats::ST_SHADER_ENVIRONMENT, (F64)gSavedSettings.getBOOL("VertexShaderLevelEnvironment"));
#endif
- LLViewerStats::getInstance()->setStat(LLViewerStats::ST_FRAME_SECS, gDebugView->mFastTimerView->getTime(LLFastTimer::FTM_FRAME));
- F64 idle_secs = gDebugView->mFastTimerView->getTime(LLFastTimer::FTM_IDLE);
- F64 network_secs = gDebugView->mFastTimerView->getTime(LLFastTimer::FTM_NETWORK);
+ LLViewerStats::getInstance()->setStat(LLViewerStats::ST_FRAME_SECS, gDebugView->mFastTimerView->getTime("Frame"));
+ F64 idle_secs = gDebugView->mFastTimerView->getTime("Idle");
+ F64 network_secs = gDebugView->mFastTimerView->getTime("Network");
LLViewerStats::getInstance()->setStat(LLViewerStats::ST_UPDATE_SECS, idle_secs - network_secs);
LLViewerStats::getInstance()->setStat(LLViewerStats::ST_NETWORK_SECS, network_secs);
- LLViewerStats::getInstance()->setStat(LLViewerStats::ST_IMAGE_SECS, gDebugView->mFastTimerView->getTime(LLFastTimer::FTM_IMAGE_UPDATE));
- LLViewerStats::getInstance()->setStat(LLViewerStats::ST_REBUILD_SECS, gDebugView->mFastTimerView->getTime(LLFastTimer::FTM_STATESORT ));
- LLViewerStats::getInstance()->setStat(LLViewerStats::ST_RENDER_SECS, gDebugView->mFastTimerView->getTime(LLFastTimer::FTM_RENDER_GEOMETRY));
+ LLViewerStats::getInstance()->setStat(LLViewerStats::ST_IMAGE_SECS, gDebugView->mFastTimerView->getTime("Update Images"));
+ LLViewerStats::getInstance()->setStat(LLViewerStats::ST_REBUILD_SECS, gDebugView->mFastTimerView->getTime("Sort Draw State"));
+ LLViewerStats::getInstance()->setStat(LLViewerStats::ST_RENDER_SECS, gDebugView->mFastTimerView->getTime("Geometry"));
LLCircuitData *cdp = gMessageSystem->mCircuitInfo.findCircuit(gAgent.getRegion()->getHost());
if (cdp)
@@ -559,7 +618,7 @@ void update_statistics(U32 frame_count)
F32 layer_bits = (F32)(gVLManager.getLandBits() + gVLManager.getWindBits() + gVLManager.getCloudBits());
LLViewerStats::getInstance()->mLayersKBitStat.addValue(layer_bits/1024.f);
LLViewerStats::getInstance()->mObjectKBitStat.addValue(gObjectBits/1024.f);
- LLViewerStats::getInstance()->mTextureKBitStat.addValue(LLViewerImageList::sTextureBits/1024.f);
+ LLViewerStats::getInstance()->mTextureKBitStat.addValue(gTextureList.mTextureBits/1024.f);
LLViewerStats::getInstance()->mVFSPendingOperations.addValue(LLVFile::getVFSThread()->getPending());
LLViewerStats::getInstance()->mAssetKBitStat.addValue(gTransferManager.getTransferBitsIn(LLTCT_ASSET)/1024.f);
gTransferManager.resetTransferBitsIn(LLTCT_ASSET);
@@ -573,7 +632,7 @@ void update_statistics(U32 frame_count)
gDebugTimers[0].unpause();
}
- LLViewerStats::getInstance()->mTexturePacketsStat.addValue(LLViewerImageList::sTexturePackets);
+ LLViewerStats::getInstance()->mTexturePacketsStat.addValue(gTextureList.mTexturePackets);
{
static F32 visible_avatar_frames = 0.f;
@@ -594,15 +653,9 @@ void update_statistics(U32 frame_count)
gObjectBits = 0;
// gDecodedBits = 0;
- LLViewerImageList::sTextureBits = 0;
- LLViewerImageList::sTexturePackets = 0;
+ gTextureList.mTextureBits = 0;
+ gTextureList.mTexturePackets = 0;
-#if LL_LCD_COMPILE
- bool LCDenabled = gLcdScreen->Enabled();
- LLViewerStats::getInstance()->setStat(LLViewerStats::ST_LOGITECH_LCD, LCDenabled);
-#else
- LLViewerStats::getInstance()->setStat(LLViewerStats::ST_LOGITECH_LCD, false);
-#endif
}
class ViewerStatsResponder : public LLHTTPClient::Responder
@@ -692,7 +745,7 @@ void send_stats()
agent["ping"] = gAvgSimPing;
agent["meters_traveled"] = gAgent.getDistanceTraveled();
agent["regions_visited"] = gAgent.getRegionsVisited();
- agent["mem_use"] = getCurrentRSS() / 1024.0;
+ agent["mem_use"] = LLMemory::getCurrentRSS() / 1024.0;
LLSD &system = body["system"];
diff --git a/indra/newview/llviewerstats.h b/indra/newview/llviewerstats.h
index d3fd4f2466..ba89fbf02a 100644
--- a/indra/newview/llviewerstats.h
+++ b/indra/newview/llviewerstats.h
@@ -57,6 +57,7 @@ public:
LLStat mTexturePacketsStat;
LLStat mActualInKBitStat; // From the packet ring (when faking a bad connection)
LLStat mActualOutKBitStat; // From the packet ring (when faking a bad connection)
+ LLStat mTrianglesDrawnStat;
// Simulator stats
LLStat mSimTimeDilation;
@@ -98,15 +99,22 @@ public:
LLStat mPhysicsPinnedTasks;
LLStat mPhysicsLODTasks;
LLStat mPhysicsMemoryAllocated;
- /*
- LLStat mSimCPUUsageStat;
- LLStat mSimMemTotalStat;
- LLStat mSimMemRSSStat;
- */
-
LLStat mSimPingStat;
+ LLStat mNumImagesStat;
+ LLStat mNumRawImagesStat;
+ LLStat mGLTexMemStat;
+ LLStat mGLBoundMemStat;
+ LLStat mRawMemStat;
+ LLStat mFormattedMemStat;
+
+ LLStat mNumObjectsStat;
+ LLStat mNumActiveObjectsStat;
+ LLStat mNumNewObjectsStat;
+ LLStat mNumSizeCulledStat;
+ LLStat mNumVisCulledStat;
+
void resetStats();
public:
// If you change this, please also add a corresponding text label
@@ -171,9 +179,8 @@ public:
ST_WINDOW_HEIGHT = 55,
ST_TEX_BAKES = 56,
ST_TEX_REBAKES = 57,
- ST_LOGITECH_LCD = 58,
- ST_COUNT = 59
+ ST_COUNT = 58
};
diff --git a/indra/newview/llviewertexteditor.cpp b/indra/newview/llviewertexteditor.cpp
index d64700b523..de01e79803 100644
--- a/indra/newview/llviewertexteditor.cpp
+++ b/indra/newview/llviewertexteditor.cpp
@@ -32,37 +32,41 @@
#include "llviewerprecompiledheaders.h"
+#include "llfloaterreg.h"
#include "llfocusmgr.h"
-#include "audioengine.h"
+#include "llaudioengine.h"
#include "llagent.h"
#include "llinventory.h"
+#include "llinventorybridge.h"
#include "llinventorymodel.h"
-#include "llinventoryview.h"
-#include "llinventorybridge.h" // for landmark prefix string
#include "llviewertexteditor.h"
#include "llfloaterchat.h"
#include "llfloaterworldmap.h"
#include "llnotify.h"
+#include "llpanelplaces.h"
#include "llpreview.h"
#include "llpreviewtexture.h"
#include "llpreviewnotecard.h"
-#include "llpreviewlandmark.h"
#include "llscrollbar.h"
+#include "llsidetray.h"
#include "lltooldraganddrop.h"
+#include "lltrans.h"
#include "llviewercontrol.h"
-#include "llviewerimagelist.h"
+#include "llviewertexturelist.h"
#include "llviewerwindow.h"
#include "llviewerinventory.h"
#include "lluictrlfactory.h"
#include "llnotecard.h"
#include "llmemorystream.h"
#include "llmenugl.h"
+#include "llscrollcontainer.h"
+#include "llavataractions.h"
#include "llappviewer.h" // for gPacificDaylightTime
-static LLRegisterWidget<LLViewerTextEditor> r("text_editor");
+static LLDefaultChildRegistry::Register<LLViewerTextEditor> r("text_editor");
///----------------------------------------------------------------------------
/// Class LLEmbeddedNotecardOpener
@@ -96,36 +100,113 @@ public:
}
else
{
- // See if we can bring an existing preview to the front
- if(!LLPreview::show(item->getUUID(), true))
+ if(!gSavedSettings.getBOOL("ShowNewInventory"))
{
- if(!gSavedSettings.getBOOL("ShowNewInventory"))
- {
- // There isn't one, so make a new preview
- S32 left, top;
- gFloaterView->getNewFloaterPosition(&left, &top);
- LLRect rect = gSavedSettings.getRect("NotecardEditorRect");
- rect.translate(left - rect.mLeft, top - rect.mTop);
- LLPreviewNotecard* preview;
- preview = new LLPreviewNotecard("preview notecard",
- rect,
- std::string("Embedded Note: ") + item->getName(),
- item->getUUID(),
- LLUUID::null,
- item->getAssetUUID(),
- true,
- (LLViewerInventoryItem*)item);
- preview->setSourceID(LLUUID::null);
- preview->setFocus(TRUE);
-
- // Force to be entirely onscreen.
- gFloaterView->adjustToFitScreen(preview, FALSE);
- }
+ LLFloaterReg::showInstance("preview_notecard", LLSD(item->getUUID()), TAKE_FOCUS_YES);
}
}
}
};
+//
+// class LLEmbeddedItemSegment
+//
+
+const S32 EMBEDDED_ITEM_LABEL_PADDING = 2;
+
+class LLEmbeddedItemSegment : public LLTextSegment
+{
+public:
+ LLEmbeddedItemSegment(S32 pos, LLUIImagePtr image, LLPointer<LLInventoryItem> inv_item, LLTextEditor& editor)
+ : LLTextSegment(pos, pos + 1),
+ mImage(image),
+ mLabel(utf8str_to_wstring(inv_item->getName())),
+ mItem(inv_item),
+ mEditor(editor),
+ mHasMouseHover(false)
+ {
+
+ mStyle = new LLStyle(LLStyle::Params().font(LLFontGL::getFontSansSerif()));
+ mToolTip = inv_item->getName() + '\n' + inv_item->getDescription();
+ }
+
+ /*virtual*/ S32 getWidth(S32 first_char, S32 num_chars) const
+ {
+ if (num_chars == 0)
+ {
+ return 0;
+ }
+ else
+ {
+ return EMBEDDED_ITEM_LABEL_PADDING + mImage->getWidth() + mStyle->getFont()->getWidth(mLabel.c_str());
+ }
+
+ }
+ //virtual S32 getOffset(S32 segment_local_x_coord, S32 start_offset, S32 num_chars, bool round) const;
+ //virtual void updateLayout(const class LLTextEditor& editor);
+
+ /*virtual*/ S32 getNumChars(S32 num_pixels, S32 segment_offset, S32 line_offset, S32 max_chars) const
+ {
+ return 1;
+ }
+ /*virtual*/ F32 draw(S32 start, S32 end, S32 selection_start, S32 selection_end, const LLRect& draw_rect)
+ {
+ LLRect image_rect = draw_rect;
+ image_rect.mRight = image_rect.mLeft + mImage->getWidth();
+ image_rect.mTop = image_rect.mBottom + mImage->getHeight();
+ mImage->draw(image_rect);
+
+ LLColor4 color;
+ if (mEditor.getReadOnly())
+ {
+ color = LLUIColorTable::instance().getColor("TextEmbeddedItemReadOnlyColor");
+ }
+ else
+ {
+ color = LLUIColorTable::instance().getColor("TextEmbeddedItemColor");
+ }
+
+ F32 right_x;
+ mStyle->getFont()->render(mLabel, 0, image_rect.mRight + EMBEDDED_ITEM_LABEL_PADDING, draw_rect.mBottom, color, LLFontGL::LEFT, LLFontGL::BOTTOM, mHasMouseHover ? LLFontGL::UNDERLINE : 0, LLFontGL::NO_SHADOW, mLabel.length(), S32_MAX, &right_x);
+ return right_x;
+ }
+
+ /*virtual*/ S32 getMaxHeight() const
+ {
+ return llmax(mImage->getHeight(), llceil(mStyle->getFont()->getLineHeight()));
+ }
+ /*virtual*/ bool canEdit() const { return false; }
+ //virtual void unlinkFromDocument(class LLTextEditor* editor);
+ //virtual void linkToDocument(class LLTextEditor* editor);
+
+ virtual void setHasMouseHover(bool hover)
+ {
+ mHasMouseHover = hover;
+ }
+ //virtual const LLColor4& getColor() const;
+ //virtual void setColor(const LLColor4 &color);
+ //virtual void setStyle(const LLStyleSP &style);
+ virtual BOOL getToolTip( std::string& msg ) const
+ {
+ msg = mToolTip;
+ return TRUE;
+ }
+
+ /*virtual*/ const LLStyleSP getStyle() const { return mStyle; }
+
+private:
+ LLUIImagePtr mImage;
+ LLWString mLabel;
+ LLStyleSP mStyle;
+ std::string mToolTip;
+ LLPointer<LLInventoryItem> mItem;
+ LLTextEditor& mEditor;
+ bool mHasMouseHover;
+
+};
+
+
+
////////////////////////////////////////////////////////////
// LLEmbeddedItems
//
@@ -148,13 +229,11 @@ public:
// return true if there are no embedded items.
bool empty();
- void bindEmbeddedChars(const LLFontGL* font) const;
- void unbindEmbeddedChars(const LLFontGL* font) const;
-
BOOL insertEmbeddedItem(LLInventoryItem* item, llwchar* value, bool is_new);
BOOL removeEmbeddedItem( llwchar ext_char );
BOOL hasEmbeddedItem(llwchar ext_char); // returns TRUE if /this/ editor has an entry for this item
+ LLUIImagePtr getItemImage(llwchar ext_char) const;
void getEmbeddedItemList( std::vector<LLPointer<LLInventoryItem> >& items );
void addItems(const std::vector<LLPointer<LLInventoryItem> >& items);
@@ -369,88 +448,77 @@ BOOL LLEmbeddedItems::hasEmbeddedItem(llwchar ext_char)
return FALSE;
}
-void LLEmbeddedItems::bindEmbeddedChars( const LLFontGL* font ) const
-{
- if( sEntries.empty() )
- {
- return;
- }
- for (std::set<llwchar>::const_iterator iter1 = mEmbeddedUsedChars.begin(); iter1 != mEmbeddedUsedChars.end(); ++iter1)
+LLUIImagePtr LLEmbeddedItems::getItemImage(llwchar ext_char) const
+{
+ LLInventoryItem* item = getEmbeddedItem(ext_char);
+ if (item)
{
- llwchar wch = *iter1;
- item_map_t::iterator iter2 = sEntries.find(wch);
- if (iter2 == sEntries.end())
- {
- continue;
- }
- LLInventoryItem* item = iter2->second.mItem;
- if (!item)
- {
- continue;
- }
- const char* img_name;
+ const char* img_name = "";
switch( item->getType() )
{
- case LLAssetType::AT_TEXTURE:
- if(item->getInventoryType() == LLInventoryType::IT_SNAPSHOT)
- {
- img_name = "inv_item_snapshot.tga";
- }
- else
- {
- img_name = "inv_item_texture.tga";
- }
+ case LLAssetType::AT_TEXTURE:
+ if(item->getInventoryType() == LLInventoryType::IT_SNAPSHOT)
+ {
+ img_name = "inv_item_snapshot.tga";
+ }
+ else
+ {
+ img_name = "inv_item_texture.tga";
+ }
- break;
- case LLAssetType::AT_SOUND: img_name = "inv_item_sound.tga"; break;
- case LLAssetType::AT_LANDMARK:
- if (item->getFlags() & LLInventoryItem::II_FLAGS_LANDMARK_VISITED)
- {
- img_name = "inv_item_landmark_visited.tga";
- }
- else
- {
- img_name = "inv_item_landmark.tga";
- }
- break;
- case LLAssetType::AT_CLOTHING: img_name = "inv_item_clothing.tga"; break;
- case LLAssetType::AT_OBJECT:
- if (item->getFlags() & LLInventoryItem::II_FLAGS_OBJECT_HAS_MULTIPLE_ITEMS)
- {
- img_name = "inv_item_object_multi.tga";
- }
- else
+ break;
+ case LLAssetType::AT_SOUND: img_name = "inv_item_sound.tga"; break;
+ case LLAssetType::AT_LANDMARK:
+ if (item->getFlags() & LLInventoryItem::II_FLAGS_LANDMARK_VISITED)
+ {
+ img_name = "inv_item_landmark_visited.tga";
+ }
+ else
+ {
+ img_name = "inv_item_landmark.tga";
+ }
+ break;
+ case LLAssetType::AT_CALLINGCARD:
{
- img_name = "inv_item_object.tga";
+ BOOL online;
+ online = LLAvatarTracker::instance().isBuddyOnline(item->getCreatorUUID());
+ if (online)
+ {
+ img_name = "inv_item_callingcard_online.tga"; break;
+ }
+ else
+ {
+ img_name = "inv_item_callingcard_offline.tga"; break;
+ }
+ break;
}
- break;
- case LLAssetType::AT_NOTECARD: img_name = "inv_item_notecard.tga"; break;
- case LLAssetType::AT_LSL_TEXT: img_name = "inv_item_script.tga"; break;
- case LLAssetType::AT_BODYPART: img_name = "inv_item_skin.tga"; break;
- case LLAssetType::AT_ANIMATION: img_name = "inv_item_animation.tga";break;
- case LLAssetType::AT_GESTURE: img_name = "inv_item_gesture.tga"; break;
- default: llassert(0); continue;
+ case LLAssetType::AT_CLOTHING: img_name = "inv_item_clothing.tga"; break;
+ case LLAssetType::AT_OBJECT:
+ if (item->getFlags() & LLInventoryItem::II_FLAGS_OBJECT_HAS_MULTIPLE_ITEMS)
+ {
+ img_name = "inv_item_object_multi.tga";
+ }
+ else
+ {
+ img_name = "inv_item_object.tga";
+ }
+ break;
+ case LLAssetType::AT_NOTECARD: img_name = "inv_item_notecard.tga"; break;
+ case LLAssetType::AT_LSL_TEXT: img_name = "inv_item_script.tga"; break;
+ case LLAssetType::AT_BODYPART: img_name = "inv_item_skin.tga"; break;
+ case LLAssetType::AT_ANIMATION: img_name = "inv_item_animation.tga";break;
+ case LLAssetType::AT_GESTURE: img_name = "inv_item_gesture.tga"; break;
+ //TODO need img_name
+ case LLAssetType::AT_FAVORITE: img_name = "inv_item_landmark.tga"; break;
+ default: llassert(0);
}
- LLUIImagePtr image = LLUI::getUIImage(img_name);
-
- font->addEmbeddedChar( wch, image->getImage(), item->getName() );
+ return LLUI::getUIImage(img_name);
}
+ return LLUIImagePtr();
}
-void LLEmbeddedItems::unbindEmbeddedChars( const LLFontGL* font ) const
-{
- if( sEntries.empty() )
- {
- return;
- }
-
- for (std::set<llwchar>::const_iterator iter1 = mEmbeddedUsedChars.begin(); iter1 != mEmbeddedUsedChars.end(); ++iter1)
- {
- font->removeEmbeddedChar(*iter1);
- }
-}
void LLEmbeddedItems::addItems(const std::vector<LLPointer<LLInventoryItem> >& items)
{
@@ -561,33 +629,15 @@ struct LLNotecardCopyInfo
//
// Member functions
//
-
-LLViewerTextEditor::LLViewerTextEditor(const std::string& name,
- const LLRect& rect,
- S32 max_length,
- const std::string& default_text,
- const LLFontGL* font,
- BOOL allow_embedded_items)
- : LLTextEditor(name, rect, max_length, default_text, font, allow_embedded_items),
- mDragItemChar(0),
- mDragItemSaved(FALSE),
- mInventoryCallback(new LLEmbeddedNotecardOpener)
+LLViewerTextEditor::LLViewerTextEditor(const LLViewerTextEditor::Params& p)
+: LLTextEditor(p),
+ mDragItemChar(0),
+ mDragItemSaved(FALSE),
+ mInventoryCallback(new LLEmbeddedNotecardOpener)
{
+ mParseHTML = p.allow_html;
mEmbeddedItemList = new LLEmbeddedItems(this);
mInventoryCallback->setEditor(this);
-
- // *TODO: Add right click menus for SLURLs
- // Build the right click menu
- // make the popup menu available
-
- //LLMenuGL* menu = LLUICtrlFactory::getInstance()->buildMenu("menu_slurl.xml", this);
- //if (!menu)
- //{
- // menu = new LLMenuGL(LLStringUtil::null);
- //}
- //menu->setBackgroundColor(gColors.getColor("MenuPopupBgColor"));
- //// menu->setVisible(FALSE);
- //mPopupMenuHandle = menu->getHandle();
}
LLViewerTextEditor::~LLViewerTextEditor()
@@ -633,30 +683,16 @@ BOOL LLViewerTextEditor::handleToolTip(S32 x, S32 y, std::string& msg, LLRect* s
}
const LLTextSegment* cur_segment = getSegmentAtLocalPos( x, y );
- if( cur_segment )
+ if( cur_segment && cur_segment->getToolTip( msg ) )
{
- BOOL has_tool_tip = FALSE;
- if( cur_segment->getStyle()->getIsEmbeddedItem() )
- {
- LLWString wtip;
- has_tool_tip = getEmbeddedItemToolTipAtPos(cur_segment->getStart(), wtip);
- msg = wstring_to_utf8str(wtip);
- }
- else
- {
- has_tool_tip = cur_segment->getToolTip( msg );
- }
- if( has_tool_tip )
- {
- // Just use a slop area around the cursor
- // Convert rect local to screen coordinates
- S32 SLOP = 8;
- localPointToScreen(
- x - SLOP, y - SLOP,
- &(sticky_rect_screen->mLeft), &(sticky_rect_screen->mBottom) );
- sticky_rect_screen->mRight = sticky_rect_screen->mLeft + 2 * SLOP;
- sticky_rect_screen->mTop = sticky_rect_screen->mBottom + 2 * SLOP;
- }
+ // Just use a slop area around the cursor
+ // Convert rect local to screen coordinates
+ S32 SLOP = 8;
+ localPointToScreen(
+ x - SLOP, y - SLOP,
+ &(sticky_rect_screen->mLeft), &(sticky_rect_screen->mBottom) );
+ sticky_rect_screen->mRight = sticky_rect_screen->mLeft + 2 * SLOP;
+ sticky_rect_screen->mTop = sticky_rect_screen->mBottom + 2 * SLOP;
}
return TRUE;
}
@@ -668,21 +704,8 @@ BOOL LLViewerTextEditor::handleMouseDown(S32 x, S32 y, MASK mask)
// Let scrollbar have first dibs
handled = LLView::childrenHandleMouseDown(x, y, mask) != NULL;
- // enable I Agree checkbox if the user scrolled through entire text
- BOOL was_scrolled_to_bottom = (mScrollbar->getDocPos() == mScrollbar->getDocPosMax());
- if (mOnScrollEndCallback && was_scrolled_to_bottom)
+ if( !handled)
{
- mOnScrollEndCallback(mOnScrollEndData);
- }
-
- if( !handled && mTakesNonScrollClicks)
- {
- if (!(mask & MASK_SHIFT))
- {
- deselect();
- }
-
- BOOL start_select = TRUE;
if( allowsEmbeddedItems() )
{
setCursorAtLocalPos( x, y, FALSE );
@@ -705,191 +728,55 @@ BOOL LLViewerTextEditor::handleMouseDown(S32 x, S32 y, MASK mask)
localPointToScreen(x, y, &screen_x, &screen_y );
LLToolDragAndDrop::getInstance()->setDragStart( screen_x, screen_y );
- start_select = FALSE;
- }
- else
- {
- mDragItem = NULL;
- }
- }
-
- if( start_select )
- {
- // If we're not scrolling (handled by child), then we're selecting
- if (mask & MASK_SHIFT)
- {
- S32 old_cursor_pos = mCursorPos;
- setCursorAtLocalPos( x, y, TRUE );
-
- if (hasSelection())
+ if (hasTabStop())
{
- /* Mac-like behavior - extend selection towards the cursor
- if (mCursorPos < mSelectionStart
- && mCursorPos < mSelectionEnd)
- {
- // ...left of selection
- mSelectionStart = llmax(mSelectionStart, mSelectionEnd);
- mSelectionEnd = mCursorPos;
- }
- else if (mCursorPos > mSelectionStart
- && mCursorPos > mSelectionEnd)
- {
- // ...right of selection
- mSelectionStart = llmin(mSelectionStart, mSelectionEnd);
- mSelectionEnd = mCursorPos;
- }
- else
- {
- mSelectionEnd = mCursorPos;
- }
- */
- // Windows behavior
- mSelectionEnd = mCursorPos;
- }
- else
- {
- mSelectionStart = old_cursor_pos;
- mSelectionEnd = mCursorPos;
+ setFocus( TRUE );
}
- // assume we're starting a drag select
- mIsSelecting = TRUE;
+ handled = TRUE;
}
else
{
- setCursorAtLocalPos( x, y, TRUE );
- startSelection();
+ mDragItem = NULL;
}
- gFocusMgr.setMouseCapture( this );
}
- handled = TRUE;
- }
-
- if (hasTabStop())
- {
- setFocus(TRUE);
- handled = TRUE;
+ if (!handled)
+ {
+ handled = LLTextEditor::handleMouseDown(x, y, mask);
+ }
}
- // Delay cursor flashing
- resetKeystrokeTimer();
-
return handled;
}
BOOL LLViewerTextEditor::handleHover(S32 x, S32 y, MASK mask)
{
- BOOL handled = FALSE;
+ BOOL handled = LLTextEditor::handleHover(x, y, mask);
- if (!mDragItem)
- {
- // leave hover segment active during drag and drop
- mHoverSegment = NULL;
- }
- if(hasMouseCapture() )
+ if(hasMouseCapture() && mDragItem)
{
- if( mIsSelecting )
- {
- if (x != mLastSelectionX || y != mLastSelectionY)
- {
- mLastSelectionX = x;
- mLastSelectionY = y;
- }
+ S32 screen_x;
+ S32 screen_y;
+ localPointToScreen(x, y, &screen_x, &screen_y );
- if( y > getTextRect().mTop )
- {
- mScrollbar->setDocPos( mScrollbar->getDocPos() - 1 );
- }
- else
- if( y < getTextRect().mBottom )
- {
- mScrollbar->setDocPos( mScrollbar->getDocPos() + 1 );
- }
+ mScroller->autoScroll(x, y);
- setCursorAtLocalPos( x, y, TRUE );
- mSelectionEnd = mCursorPos;
-
- updateScrollFromCursor();
- getWindow()->setCursor(UI_CURSOR_IBEAM);
- }
- else if( mDragItem )
+ if( LLToolDragAndDrop::getInstance()->isOverThreshold( screen_x, screen_y ) )
{
- S32 screen_x;
- S32 screen_y;
- localPointToScreen(x, y, &screen_x, &screen_y );
- if( LLToolDragAndDrop::getInstance()->isOverThreshold( screen_x, screen_y ) )
- {
- LLToolDragAndDrop::getInstance()->beginDrag(
- LLAssetType::lookupDragAndDropType( mDragItem->getType() ),
- mDragItem->getUUID(),
- LLToolDragAndDrop::SOURCE_NOTECARD,
- getSourceID(), mObjectID);
+ LLToolDragAndDrop::getInstance()->beginDrag(
+ LLAssetType::lookupDragAndDropType( mDragItem->getType() ),
+ mDragItem->getUUID(),
+ LLToolDragAndDrop::SOURCE_NOTECARD,
+ mPreviewID, mObjectID);
- return LLToolDragAndDrop::getInstance()->handleHover( x, y, mask );
- }
- getWindow()->setCursor(UI_CURSOR_HAND);
+ return LLToolDragAndDrop::getInstance()->handleHover( x, y, mask );
}
-
- lldebugst(LLERR_USER_INPUT) << "hover handled by " << getName() << " (active)" << llendl;
+ getWindow()->setCursor(UI_CURSOR_HAND);
handled = TRUE;
}
- if( !handled )
- {
- // Pass to children
- handled = LLView::childrenHandleHover(x, y, mask) != NULL;
- }
-
- if( handled )
- {
- // Delay cursor flashing
- resetKeystrokeTimer();
- }
-
- // Opaque
- if( !handled && mTakesNonScrollClicks)
- {
- // Check to see if we're over an HTML-style link
- if( !mSegments.empty() )
- {
- const LLTextSegment* cur_segment = getSegmentAtLocalPos( x, y );
- if( cur_segment )
- {
- if(cur_segment->getStyle()->isLink())
- {
- lldebugst(LLERR_USER_INPUT) << "hover handled by " << getName() << " (over link, inactive)" << llendl;
- getWindow()->setCursor(UI_CURSOR_HAND);
- handled = TRUE;
- }
- else
- if(cur_segment->getStyle()->getIsEmbeddedItem())
- {
- lldebugst(LLERR_USER_INPUT) << "hover handled by " << getName() << " (over embedded item, inactive)" << llendl;
- getWindow()->setCursor(UI_CURSOR_HAND);
- //getWindow()->setCursor(UI_CURSOR_ARROW);
- handled = TRUE;
- }
- mHoverSegment = cur_segment;
- }
- }
-
- if( !handled )
- {
- lldebugst(LLERR_USER_INPUT) << "hover handled by " << getName() << " (inactive)" << llendl;
- if (!mScrollbar->getVisible() || x < getRect().getWidth() - SCROLLBAR_SIZE)
- {
- getWindow()->setCursor(UI_CURSOR_IBEAM);
- }
- else
- {
- getWindow()->setCursor(UI_CURSOR_ARROW);
- }
- handled = TRUE;
- }
- }
-
return handled;
}
@@ -922,13 +809,6 @@ BOOL LLViewerTextEditor::handleMouseUp(S32 x, S32 y, MASK mask)
handled = LLTextEditor::handleMouseUp(x,y,mask);
- // Used to enable I Agree checkbox if the user scrolled through entire text
- BOOL was_scrolled_to_bottom = (mScrollbar->getDocPos() == mScrollbar->getDocPosMax());
- if (mOnScrollEndCallback && was_scrolled_to_bottom)
- {
- mOnScrollEndCallback(mOnScrollEndData);
- }
-
return handled;
}
@@ -968,24 +848,6 @@ BOOL LLViewerTextEditor::handleRightMouseDown(S32 x, S32 y, MASK mask)
return handled;
}
-BOOL LLViewerTextEditor::handleMiddleMouseDown(S32 x, S32 y, MASK mask)
-{
- BOOL handled = FALSE;
- handled = childrenHandleMiddleMouseDown(x, y, mask) != NULL;
- if (!handled)
- {
- handled = LLTextEditor::handleMiddleMouseDown(x, y, mask);
- }
- return handled;
-}
-
-BOOL LLViewerTextEditor::handleMiddleMouseUp(S32 x, S32 y, MASK mask)
-{
- BOOL handled = childrenHandleMiddleMouseUp(x, y, mask) != NULL;
-
- return handled;
-}
-
BOOL LLViewerTextEditor::handleDoubleClick(S32 x, S32 y, MASK mask)
{
BOOL handled = FALSE;
@@ -993,14 +855,15 @@ BOOL LLViewerTextEditor::handleDoubleClick(S32 x, S32 y, MASK mask)
// let scrollbar have first dibs
handled = LLView::childrenHandleDoubleClick(x, y, mask) != NULL;
- if( !handled && mTakesNonScrollClicks)
+ if( !handled)
{
if( allowsEmbeddedItems() )
{
- const LLTextSegment* cur_segment = getSegmentAtLocalPos( x, y );
- if( cur_segment && cur_segment->getStyle()->getIsEmbeddedItem() )
+ S32 doc_index = getDocIndexFromLocalCoord(x, y, FALSE);
+ llwchar doc_char = getWText()[doc_index];
+ if (mEmbeddedItemList->hasEmbeddedItem(doc_char))
{
- if( openEmbeddedItemAtPos( cur_segment->getStart() ) )
+ if( openEmbeddedItemAtPos( doc_index ))
{
deselect();
setFocus( FALSE );
@@ -1008,54 +871,12 @@ BOOL LLViewerTextEditor::handleDoubleClick(S32 x, S32 y, MASK mask)
}
}
}
-
- setCursorAtLocalPos( x, y, FALSE );
- deselect();
-
- const LLWString &text = getWText();
-
- if( isPartOfWord( text[mCursorPos] ) )
- {
- // Select word the cursor is over
- while ((mCursorPos > 0) && isPartOfWord(text[mCursorPos-1]))
- {
- mCursorPos--;
- }
- startSelection();
-
- while ((mCursorPos < (S32)text.length()) && isPartOfWord( text[mCursorPos] ) )
- {
- mCursorPos++;
- }
-
- mSelectionEnd = mCursorPos;
- }
- else if ((mCursorPos < (S32)text.length()) && !iswspace( text[mCursorPos]) )
- {
- // Select the character the cursor is over
- startSelection();
- mCursorPos++;
- mSelectionEnd = mCursorPos;
- }
-
- // We don't want handleMouseUp() to "finish" the selection (and thereby
- // set mSelectionEnd to where the mouse is), so we finish the selection here.
- mIsSelecting = FALSE;
-
- // delay cursor flashing
- resetKeystrokeTimer();
-
- // take selection to 'primary' clipboard
- updatePrimary();
-
- handled = TRUE;
+ handled = LLTextEditor::handleDoubleClick(x, y, mask);
}
return handled;
}
-// Allow calling cards to be dropped onto text fields. Append the name and
-// a carriage return.
// virtual
BOOL LLViewerTextEditor::handleDragAndDrop(S32 x, S32 y, MASK mask,
BOOL drop, EDragAndDropType cargo_type, void *cargo_data,
@@ -1072,95 +893,78 @@ BOOL LLViewerTextEditor::handleDragAndDrop(S32 x, S32 y, MASK mask,
return FALSE;
}
- if (mTakesNonScrollClicks)
+ if (getEnabled() && acceptsTextInput())
{
- if (getEnabled() && acceptsTextInput())
+ switch( cargo_type )
{
- switch( cargo_type )
+ case DAD_CALLINGCARD:
+ case DAD_TEXTURE:
+ case DAD_SOUND:
+ case DAD_LANDMARK:
+ case DAD_SCRIPT:
+ case DAD_CLOTHING:
+ case DAD_OBJECT:
+ case DAD_NOTECARD:
+ case DAD_BODYPART:
+ case DAD_ANIMATION:
+ case DAD_GESTURE:
{
- case DAD_CALLINGCARD:
- if(acceptsCallingCardNames())
- {
- if (drop)
- {
- LLInventoryItem *item = (LLInventoryItem *)cargo_data;
- std::string name = item->getName();
- appendText(name, true, true);
- }
- *accept = ACCEPT_YES_COPY_SINGLE;
- }
- else
- {
- *accept = ACCEPT_NO;
- }
- break;
-
- case DAD_TEXTURE:
- case DAD_SOUND:
- case DAD_LANDMARK:
- case DAD_SCRIPT:
- case DAD_CLOTHING:
- case DAD_OBJECT:
- case DAD_NOTECARD:
- case DAD_BODYPART:
- case DAD_ANIMATION:
- case DAD_GESTURE:
+ LLInventoryItem *item = (LLInventoryItem *)cargo_data;
+ if( item && allowsEmbeddedItems() )
{
- LLInventoryItem *item = (LLInventoryItem *)cargo_data;
- if( item && allowsEmbeddedItems() )
+ U32 mask_next = item->getPermissions().getMaskNextOwner();
+ if((mask_next & PERM_ITEM_UNRESTRICTED) == PERM_ITEM_UNRESTRICTED)
{
- U32 mask_next = item->getPermissions().getMaskNextOwner();
- if((mask_next & PERM_ITEM_UNRESTRICTED) == PERM_ITEM_UNRESTRICTED)
+ if( drop )
{
- if( drop )
+ deselect();
+ S32 old_cursor = mCursorPos;
+ setCursorAtLocalPos( x, y, TRUE );
+ S32 insert_pos = mCursorPos;
+ setCursorPos(old_cursor);
+ BOOL inserted = insertEmbeddedItem( insert_pos, item );
+ if( inserted && (old_cursor > mCursorPos) )
{
- deselect();
- S32 old_cursor = mCursorPos;
- setCursorAtLocalPos( x, y, TRUE );
- S32 insert_pos = mCursorPos;
- setCursorPos(old_cursor);
- BOOL inserted = insertEmbeddedItem( insert_pos, item );
- if( inserted && (old_cursor > mCursorPos) )
- {
- setCursorPos(mCursorPos + 1);
- }
-
- updateLineStartList();
- }
- *accept = ACCEPT_YES_COPY_MULTI;
- }
- else
- {
- *accept = ACCEPT_NO;
- if (tooltip_msg.empty())
- {
- tooltip_msg.assign("Only items with unrestricted\n"
- "'next owner' permissions \n"
- "can be attached to notecards.");
+ setCursorPos(mCursorPos + 1);
}
+
+ needsReflow();
+
}
+ *accept = ACCEPT_YES_COPY_MULTI;
}
else
{
*accept = ACCEPT_NO;
+ if (tooltip_msg.empty())
+ {
+ // *TODO: Translate
+ tooltip_msg.assign("Only items with unrestricted\n"
+ "'next owner' permissions \n"
+ "can be attached to notecards.");
+ }
}
- break;
}
-
- default:
- *accept = ACCEPT_NO;
+ else
+ {
+ *accept = ACCEPT_NO;
+ }
break;
}
- }
- else
- {
- // Not enabled
+
+ default:
*accept = ACCEPT_NO;
+ break;
}
-
- handled = TRUE;
- lldebugst(LLERR_USER_INPUT) << "dragAndDrop handled by LLViewerTextEditor " << getName() << llendl;
}
+ else
+ {
+ // Not enabled
+ *accept = ACCEPT_NO;
+ }
+
+ handled = TRUE;
+ lldebugst(LLERR_USER_INPUT) << "dragAndDrop handled by LLViewerTextEditor " << getName() << llendl;
return handled;
}
@@ -1246,18 +1050,16 @@ std::string LLViewerTextEditor::appendTime(bool prepend_newline)
{
time_t utc_time;
utc_time = time_corrected();
+ std::string timeStr ="[["+ LLTrans::getString("TimeHour")+"]:["
+ +LLTrans::getString("TimeMin")+"]] ";
- // There's only one internal tm buffer.
- struct tm* timep;
+ LLSD substitution;
- // Convert to Pacific, based on server's opinion of whether
- // it's daylight savings time there.
- timep = utc_to_pacific_time(utc_time, gPacificDaylightTime);
+ substitution["datetime"] = (S32) utc_time;
+ LLStringUtil::format (timeStr, substitution);
+ appendColoredText(timeStr, false, prepend_newline, LLColor4::grey);
- std::string text = llformat("[%d:%02d] ", timep->tm_hour, timep->tm_min);
- appendColoredText(text, false, prepend_newline, LLColor4::grey);
-
- return text;
+ return timeStr;
}
//----------------------------------------------------------------------------
@@ -1282,33 +1084,33 @@ llwchar LLViewerTextEditor::pasteEmbeddedItem(llwchar ext_char)
return LL_UNKNOWN_CHAR; // item not found or list full
}
-void LLViewerTextEditor::bindEmbeddedChars(const LLFontGL* font) const
+void LLViewerTextEditor::onValueChange(S32 start, S32 end)
{
- mEmbeddedItemList->bindEmbeddedChars( font );
+ updateSegments();
+ findEmbeddedItemSegments(start, end);
}
-void LLViewerTextEditor::unbindEmbeddedChars(const LLFontGL* font) const
+void LLViewerTextEditor::findEmbeddedItemSegments(S32 start, S32 end)
{
- mEmbeddedItemList->unbindEmbeddedChars( font );
-}
+ LLWString text = getWText();
-BOOL LLViewerTextEditor::getEmbeddedItemToolTipAtPos(S32 pos, LLWString &msg) const
-{
- if (pos < getLength())
+ LLColor4 text_color = ( mReadOnly ? mReadOnlyFgColor.get() : mFgColor.get() );
+
+ // Start with i just after the first embedded item
+ for(S32 idx = start; idx < end; idx++ )
{
- LLInventoryItem* item = LLEmbeddedItems::getEmbeddedItem(getWChar(pos));
- if( item )
+ llwchar embedded_char = text[idx];
+ if( embedded_char >= FIRST_EMBEDDED_CHAR
+ && embedded_char <= LAST_EMBEDDED_CHAR
+ && mEmbeddedItemList->hasEmbeddedItem(embedded_char) )
{
- msg = utf8str_to_wstring(item->getName());
- msg += '\n';
- msg += utf8str_to_wstring(item->getDescription());
- return TRUE;
+ LLInventoryItem* itemp = mEmbeddedItemList->getEmbeddedItem(embedded_char);
+ LLUIImagePtr image = mEmbeddedItemList->getItemImage(embedded_char);
+ insertSegment(new LLEmbeddedItemSegment(idx, image, itemp, *this));
}
}
- return FALSE;
}
-
BOOL LLViewerTextEditor::openEmbeddedItemAtPos(S32 pos)
{
if( pos < getLength())
@@ -1337,32 +1139,36 @@ BOOL LLViewerTextEditor::openEmbeddedItem(LLInventoryItem* item, llwchar wc)
switch( item->getType() )
{
- case LLAssetType::AT_TEXTURE:
- openEmbeddedTexture( item, wc );
- return TRUE;
+ case LLAssetType::AT_TEXTURE:
+ openEmbeddedTexture( item, wc );
+ return TRUE;
- case LLAssetType::AT_SOUND:
- openEmbeddedSound( item, wc );
- return TRUE;
+ case LLAssetType::AT_SOUND:
+ openEmbeddedSound( item, wc );
+ return TRUE;
- case LLAssetType::AT_NOTECARD:
- openEmbeddedNotecard( item, wc );
- return TRUE;
+ case LLAssetType::AT_NOTECARD:
+ openEmbeddedNotecard( item, wc );
+ return TRUE;
- case LLAssetType::AT_LANDMARK:
- openEmbeddedLandmark( item, wc );
- return TRUE;
+ case LLAssetType::AT_LANDMARK:
+ openEmbeddedLandmark( item, wc );
+ return TRUE;
- case LLAssetType::AT_LSL_TEXT:
- case LLAssetType::AT_CLOTHING:
- case LLAssetType::AT_OBJECT:
- case LLAssetType::AT_BODYPART:
- case LLAssetType::AT_ANIMATION:
- case LLAssetType::AT_GESTURE:
- showCopyToInvDialog( item, wc );
- return TRUE;
- default:
- return FALSE;
+ case LLAssetType::AT_CALLINGCARD:
+ openEmbeddedCallingcard( item, wc );
+ return TRUE;
+
+ case LLAssetType::AT_LSL_TEXT:
+ case LLAssetType::AT_CLOTHING:
+ case LLAssetType::AT_OBJECT:
+ case LLAssetType::AT_BODYPART:
+ case LLAssetType::AT_ANIMATION:
+ case LLAssetType::AT_GESTURE:
+ showCopyToInvDialog( item, wc );
+ return TRUE;
+ default:
+ return FALSE;
}
}
@@ -1370,29 +1176,16 @@ BOOL LLViewerTextEditor::openEmbeddedItem(LLInventoryItem* item, llwchar wc)
void LLViewerTextEditor::openEmbeddedTexture( LLInventoryItem* item, llwchar wc )
{
- // See if we can bring an existing preview to the front
// *NOTE: Just for embedded Texture , we should use getAssetUUID(),
// not getUUID(), because LLPreviewTexture pass in AssetUUID into
// LLPreview constructor ItemUUID parameter.
-
- if( !LLPreview::show( item->getAssetUUID() ) )
+ if (!item)
+ return;
+ LLPreviewTexture* preview = LLFloaterReg::showTypedInstance<LLPreviewTexture>("preview_texture", LLSD(item->getAssetUUID()), TAKE_FOCUS_YES);
+ if (preview)
{
- // There isn't one, so make a new preview
- if(item)
- {
- S32 left, top;
- gFloaterView->getNewFloaterPosition(&left, &top);
- LLRect rect = gSavedSettings.getRect("PreviewTextureRect");
- rect.translate( left - rect.mLeft, top - rect.mTop );
-
- LLPreviewTexture* preview = new LLPreviewTexture("preview texture",
- rect,
- item->getName(),
- item->getAssetUUID(),
- TRUE);
- preview->setAuxItem( item );
- preview->setNotecardInfo(mNotecardInventoryID, mObjectID);
- }
+ preview->setAuxItem( item );
+ preview->setNotecardInfo(mNotecardInventoryID, mObjectID);
}
}
@@ -1411,9 +1204,18 @@ void LLViewerTextEditor::openEmbeddedSound( LLInventoryItem* item, llwchar wc )
void LLViewerTextEditor::openEmbeddedLandmark( LLInventoryItem* item, llwchar wc )
{
- std::string title =
- std::string(" ") + LLLandmarkBridge::prefix() + item->getName();
- open_landmark((LLViewerInventoryItem*)item, title, FALSE, item->getUUID(), TRUE);
+ if (!item)
+ return;
+
+ LLSD key;
+ key["type"] = "landmark";
+ key["id"] = item->getUUID();
+
+ LLPanelPlaces *panel = dynamic_cast<LLPanelPlaces*>(LLSideTray::getInstance()->showPanel("panel_places", key));
+ if (panel)
+ {
+ panel->setItem(item);
+ }
}
void LLViewerTextEditor::openEmbeddedNotecard( LLInventoryItem* item, llwchar wc )
@@ -1421,6 +1223,14 @@ void LLViewerTextEditor::openEmbeddedNotecard( LLInventoryItem* item, llwchar wc
copyInventory(item, gInventoryCallbacks.registerCB(mInventoryCallback));
}
+void LLViewerTextEditor::openEmbeddedCallingcard( LLInventoryItem* item, llwchar wc )
+{
+ if(item && !item->getCreatorUUID().isNull())
+ {
+ LLAvatarActions::showProfile(item->getCreatorUUID());
+ }
+}
+
void LLViewerTextEditor::showUnsavedAlertDialog( LLInventoryItem* item )
{
LLSD payload;
@@ -1435,9 +1245,11 @@ bool LLViewerTextEditor::onNotecardDialog(const LLSD& notification, const LLSD&
S32 option = LLNotification::getSelectedOption(notification, response);
if( option == 0 )
{
- // itemptr is deleted by LLPreview::save
- LLPointer<LLInventoryItem>* itemptr = new LLPointer<LLInventoryItem>(gInventory.getItem(notification["payload"]["item_id"].asUUID()));
- LLPreview::save( notification["payload"]["notecard_id"].asUUID() , itemptr);
+ LLPreviewNotecard* preview = LLFloaterReg::findTypedInstance<LLPreviewNotecard>("preview_notecard", notification["payload"]["notecard_id"]);;
+ if (preview)
+ {
+ preview->saveItem();
+ }
}
return false;
}
@@ -1541,61 +1353,3 @@ BOOL LLViewerTextEditor::exportBuffer( std::string& buffer )
return TRUE;
}
-LLView* LLViewerTextEditor::fromXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFactory *factory)
-{
- std::string name("text_editor");
- node->getAttributeString("name", name);
-
- LLRect rect;
- createRect(node, rect, parent, LLRect());
-
- U32 max_text_length = 255;
- node->getAttributeU32("max_length", max_text_length);
-
- BOOL allow_embedded_items = FALSE;
- node->getAttributeBOOL("embedded_items", allow_embedded_items);
-
- LLFontGL* font = LLView::selectFont(node);
-
- // std::string text = node->getValue();
- std::string text = node->getTextContents().substr(0, max_text_length - 1);
-
- if (text.size() > max_text_length)
- {
- // Erase everything from max_text_length on.
- text.erase(max_text_length);
- }
-
- LLViewerTextEditor* text_editor = new LLViewerTextEditor(name,
- rect,
- max_text_length,
- LLStringUtil::null,
- font,
- allow_embedded_items);
-
- BOOL ignore_tabs = text_editor->tabsToNextField();
- node->getAttributeBOOL("ignore_tab", ignore_tabs);
- text_editor->setTabsToNextField(ignore_tabs);
-
- text_editor->setTextEditorParameters(node);
-
- BOOL hide_scrollbar = FALSE;
- node->getAttributeBOOL("hide_scrollbar",hide_scrollbar);
- text_editor->setHideScrollbarForShortDocs(hide_scrollbar);
-
- BOOL hide_border = !text_editor->isBorderVisible();
- node->getAttributeBOOL("hide_border", hide_border);
- text_editor->setBorderVisible(!hide_border);
-
- BOOL parse_html = text_editor->mParseHTML;
- node->getAttributeBOOL("allow_html", parse_html);
- text_editor->setParseHTML(parse_html);
- text_editor->setParseHighlights(TRUE);
-
- text_editor->initFromXML(node, parent);
-
- // add text after all parameters have been set
- text_editor->appendStyledText(text, FALSE, FALSE);
-
- return text_editor;
-}
diff --git a/indra/newview/llviewertexteditor.h b/indra/newview/llviewertexteditor.h
index f29caee602..9567bfbc48 100644
--- a/indra/newview/llviewertexteditor.h
+++ b/indra/newview/llviewertexteditor.h
@@ -41,26 +41,30 @@
//
class LLViewerTextEditor : public LLTextEditor
{
-
public:
- LLViewerTextEditor(const std::string& name,
- const LLRect& rect,
- S32 max_length,
- const std::string& default_text = std::string(),
- const LLFontGL* glfont = NULL,
- BOOL allow_embedded_items = FALSE);
+ struct Params : public LLInitParam::Block<Params, LLTextEditor::Params>
+ {
+ Optional<bool> allow_html;
+
+ Params()
+ : allow_html("allow_html", false)
+ {
+ name = "text_editor";
+ }
+ };
+
+protected:
+ LLViewerTextEditor(const Params&);
+ friend class LLUICtrlFactory;
+public:
virtual ~LLViewerTextEditor();
virtual void makePristine();
- static LLView* fromXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFactory *factory);
-
// mousehandler overrides
virtual BOOL handleMouseDown(S32 x, S32 y, MASK mask);
virtual BOOL handleMouseUp(S32 x, S32 y, MASK mask);
- virtual BOOL handleMiddleMouseDown(S32 x, S32 y, MASK mask);
- virtual BOOL handleMiddleMouseUp(S32 x, S32 y, MASK mask);
virtual BOOL handleRightMouseDown(S32 x, S32 y, MASK mask);
virtual BOOL handleHover(S32 x, S32 y, MASK mask);
virtual BOOL handleDoubleClick(S32 x, S32 y, MASK mask );
@@ -74,10 +78,13 @@ public:
virtual BOOL importBuffer(const char* buffer, S32 length);
virtual bool importStream(std::istream& str);
virtual BOOL exportBuffer(std::string& buffer);
- void setNotecardInfo(const LLUUID& notecard_item_id, const LLUUID& object_id)
+ virtual void onValueChange(S32 start, S32 end);
+
+ void setNotecardInfo(const LLUUID& notecard_item_id, const LLUUID& object_id, const LLUUID& preview_id)
{
mNotecardInventoryID = notecard_item_id;
mObjectID = object_id;
+ mPreviewID = preview_id;
}
void setASCIIEmbeddedText(const std::string& instr);
@@ -99,11 +106,9 @@ public:
private:
// Embedded object operations
+ void findEmbeddedItemSegments(S32 start, S32 end);
virtual llwchar pasteEmbeddedItem(llwchar ext_char);
- virtual void bindEmbeddedChars(const LLFontGL* font) const;
- virtual void unbindEmbeddedChars(const LLFontGL* font) const;
- BOOL getEmbeddedItemToolTipAtPos(S32 pos, LLWString &wmsg) const;
BOOL openEmbeddedItemAtPos( S32 pos );
BOOL openEmbeddedItem(LLInventoryItem* item, llwchar wc);
@@ -113,6 +118,7 @@ private:
void openEmbeddedSound( LLInventoryItem* item, llwchar wc );
void openEmbeddedLandmark( LLInventoryItem* item, llwchar wc );
void openEmbeddedNotecard( LLInventoryItem* item, llwchar wc);
+ void openEmbeddedCallingcard( LLInventoryItem* item, llwchar wc);
void showCopyToInvDialog( LLInventoryItem* item, llwchar wc );
void showUnsavedAlertDialog( LLInventoryItem* item );
@@ -120,12 +126,14 @@ private:
static bool onNotecardDialog(const LLSD& notification, const LLSD& response );
LLPointer<LLInventoryItem> mDragItem;
+ LLTextSegment* mDragSegment;
llwchar mDragItemChar;
BOOL mDragItemSaved;
class LLEmbeddedItems* mEmbeddedItemList;
LLUUID mObjectID;
LLUUID mNotecardInventoryID;
+ LLUUID mPreviewID;
LLPointer<class LLEmbeddedNotecardOpener> mInventoryCallback;
diff --git a/indra/newview/llviewertexture.cpp b/indra/newview/llviewertexture.cpp
new file mode 100644
index 0000000000..6ea1522b47
--- /dev/null
+++ b/indra/newview/llviewertexture.cpp
@@ -0,0 +1,2386 @@
+/**
+ * @file llviewertexture.cpp
+ * @brief Object which handles a received image (and associated texture(s))
+ *
+ * $LicenseInfo:firstyear=2000&license=viewergpl$
+ *
+ * Copyright (c) 2000-2009, Linden Research, Inc.
+ *
+ * Second Life Viewer Source Code
+ * The source code in this file ("Source Code") is provided by Linden Lab
+ * to you under the terms of the GNU General Public License, version 2.0
+ * ("GPL"), unless you have obtained a separate licensing agreement
+ * ("Other License"), formally executed by you and Linden Lab. Terms of
+ * the GPL can be found in doc/GPL-license.txt in this distribution, or
+ * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
+ *
+ * There are special exceptions to the terms and conditions of the GPL as
+ * it is applied to this Source Code. View the full text of the exception
+ * in the file doc/FLOSS-exception.txt in this software distribution, or
+ * online at
+ * http://secondlifegrid.net/programs/open_source/licensing/flossexception
+ *
+ * By copying, modifying or distributing this software, you acknowledge
+ * that you have read and understood your obligations described above,
+ * and agree to abide by those obligations.
+ *
+ * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+ * COMPLETENESS OR PERFORMANCE.
+ * $/LicenseInfo$
+ */
+
+#include "llviewerprecompiledheaders.h"
+
+#include "llviewertexture.h"
+
+// Library includes
+#include "imageids.h"
+#include "llmath.h"
+#include "llerror.h"
+#include "llgl.h"
+#include "llglheaders.h"
+#include "llhost.h"
+#include "llimage.h"
+#include "llimagebmp.h"
+#include "llimagej2c.h"
+#include "llimagetga.h"
+#include "llmemtype.h"
+#include "llstl.h"
+#include "llvfile.h"
+#include "llvfs.h"
+#include "message.h"
+#include "lltimer.h"
+
+// viewer includes
+#include "llimagegl.h"
+#include "lldrawpool.h"
+#include "lltexturefetch.h"
+#include "llviewertexturelist.h"
+#include "llviewercontrol.h"
+#include "pipeline.h"
+#include "llappviewer.h"
+///////////////////////////////////////////////////////////////////////////////
+
+// statics
+LLPointer<LLViewerTexture> LLViewerTexture::sNullImagep = NULL;
+LLPointer<LLViewerFetchedTexture> LLViewerFetchedTexture::sMissingAssetImagep = NULL;
+LLPointer<LLViewerFetchedTexture> LLViewerFetchedTexture::sWhiteImagep = NULL;
+LLPointer<LLViewerFetchedTexture> LLViewerFetchedTexture::sDefaultImagep = NULL;
+LLPointer<LLViewerFetchedTexture> LLViewerFetchedTexture::sSmokeImagep = NULL;
+LLViewerMediaTexture::media_map_t LLViewerMediaTexture::sMediaMap ;
+LLTexturePipelineTester* LLViewerTextureManager::sTesterp = NULL ;
+
+S32 LLViewerTexture::sImageCount = 0;
+S32 LLViewerTexture::sRawCount = 0;
+S32 LLViewerTexture::sAuxCount = 0;
+LLTimer LLViewerTexture::sEvaluationTimer;
+F32 LLViewerTexture::sDesiredDiscardBias = 0.f;
+F32 LLViewerTexture::sDesiredDiscardScale = 1.1f;
+S32 LLViewerTexture::sBoundTextureMemoryInBytes = 0;
+S32 LLViewerTexture::sTotalTextureMemoryInBytes = 0;
+S32 LLViewerTexture::sMaxBoundTextureMemInMegaBytes = 0;
+S32 LLViewerTexture::sMaxTotalTextureMemInMegaBytes = 0;
+S32 LLViewerTexture::sMaxDesiredTextureMemInBytes = 0 ;
+BOOL LLViewerTexture::sDontLoadVolumeTextures = FALSE;
+
+const F32 desired_discard_bias_min = -2.0f; // -max number of levels to improve image quality by
+const F32 desired_discard_bias_max = 1.5f; // max number of levels to reduce image quality by
+
+//----------------------------------------------------------------------------------------------
+//namespace: LLViewerTextureAccess
+//----------------------------------------------------------------------------------------------
+LLViewerMediaTexture* LLViewerTextureManager::createMediaTexture(const LLUUID &media_id, BOOL usemipmaps, LLImageGL* gl_image)
+{
+ return new LLViewerMediaTexture(media_id, usemipmaps, gl_image) ;
+}
+
+LLViewerTexture* LLViewerTextureManager::findTexture(const LLUUID& id)
+{
+ LLViewerTexture* tex ;
+ //search fetched texture list
+ tex = gTextureList.findImage(id) ;
+
+ //search media texture list
+ if(!tex)
+ {
+ tex = LLViewerTextureManager::findMediaTexture(id) ;
+ }
+ return tex ;
+}
+
+LLViewerMediaTexture* LLViewerTextureManager::findMediaTexture(const LLUUID &media_id)
+{
+ LLViewerMediaTexture::media_map_t::iterator iter = LLViewerMediaTexture::sMediaMap.find(media_id);
+ if(iter == LLViewerMediaTexture::sMediaMap.end())
+ return NULL;
+
+ ((LLViewerMediaTexture*)(iter->second))->getLastReferencedTimer()->reset() ;
+ return iter->second;
+}
+
+LLViewerMediaTexture* LLViewerTextureManager::getMediaTexture(const LLUUID& id, BOOL usemipmaps, LLImageGL* gl_image)
+{
+ LLViewerMediaTexture* tex = LLViewerTextureManager::findMediaTexture(id) ;
+ if(!tex)
+ {
+ tex = LLViewerTextureManager::createMediaTexture(id, usemipmaps, gl_image) ;
+ }
+
+ LLViewerTexture* old_tex = tex->getOldTexture() ;
+ if(!old_tex)
+ {
+ //if there is a fetched texture with the same id, replace it by this media texture
+ old_tex = gTextureList.findImage(id) ;
+ if(old_tex)
+ {
+ tex->setOldTexture(old_tex) ;
+ }
+ }
+
+ if (gSavedSettings.getBOOL("ParcelMediaAutoPlayEnable") && gSavedSettings.getBOOL("AudioStreamingVideo"))
+ {
+ if(!tex->isPlaying())
+ {
+ if(old_tex)
+ {
+ old_tex->switchToTexture(tex) ;
+ }
+ tex->setPlaying(TRUE) ;
+ }
+ }
+ tex->getLastReferencedTimer()->reset() ;
+
+ return tex ;
+}
+
+LLViewerFetchedTexture* LLViewerTextureManager::staticCastToFetchedTexture(LLViewerTexture* tex, BOOL report_error)
+{
+ if(!tex)
+ {
+ return NULL ;
+ }
+
+ S8 type = tex->getType() ;
+ if(type == LLViewerTexture::FETCHED_TEXTURE || type == LLViewerTexture::LOD_TEXTURE)
+ {
+ return static_cast<LLViewerFetchedTexture*>(tex) ;
+ }
+
+ if(report_error)
+ {
+ llerrs << "not a fetched texture type: " << type << llendl ;
+ }
+
+ return NULL ;
+}
+
+LLPointer<LLViewerTexture> LLViewerTextureManager::getLocalTexture(BOOL usemipmaps, BOOL generate_gl_tex)
+{
+ LLPointer<LLViewerTexture> tex = new LLViewerTexture(usemipmaps) ;
+ if(generate_gl_tex)
+ {
+ tex->generateGLTexture() ;
+ }
+ return tex ;
+}
+LLPointer<LLViewerTexture> LLViewerTextureManager::getLocalTexture(const LLUUID& id, BOOL usemipmaps, BOOL generate_gl_tex)
+{
+ LLPointer<LLViewerTexture> tex = new LLViewerTexture(id, usemipmaps) ;
+ if(generate_gl_tex)
+ {
+ tex->generateGLTexture() ;
+ }
+ return tex ;
+}
+LLPointer<LLViewerTexture> LLViewerTextureManager::getLocalTexture(const LLImageRaw* raw, BOOL usemipmaps)
+{
+ LLPointer<LLViewerTexture> tex = new LLViewerTexture(raw, usemipmaps) ;
+ return tex ;
+}
+LLPointer<LLViewerTexture> LLViewerTextureManager::getLocalTexture(const U32 width, const U32 height, const U8 components, BOOL usemipmaps, BOOL generate_gl_tex)
+{
+ LLPointer<LLViewerTexture> tex = new LLViewerTexture(width, height, components, usemipmaps) ;
+ if(generate_gl_tex)
+ {
+ tex->generateGLTexture() ;
+ }
+ return tex ;
+}
+
+LLViewerFetchedTexture* LLViewerTextureManager::getFetchedTexture(
+ const LLUUID &image_id,
+ BOOL usemipmaps,
+ BOOL level_immediate,
+ S8 texture_type,
+ LLGLint internal_format,
+ LLGLenum primary_format,
+ LLHost request_from_host)
+{
+ return gTextureList.getImage(image_id, usemipmaps, level_immediate, texture_type, internal_format, primary_format, request_from_host) ;
+}
+
+LLViewerFetchedTexture* LLViewerTextureManager::getFetchedTextureFromFile(
+ const std::string& filename,
+ BOOL usemipmaps,
+ BOOL level_immediate,
+ S8 texture_type,
+ LLGLint internal_format,
+ LLGLenum primary_format,
+ const LLUUID& force_id)
+{
+ return gTextureList.getImageFromFile(filename, usemipmaps, level_immediate, texture_type, internal_format, primary_format, force_id) ;
+}
+
+LLViewerFetchedTexture* LLViewerTextureManager::getFetchedTextureFromHost(const LLUUID& image_id, LLHost host)
+{
+ return gTextureList.getImageFromHost(image_id, host) ;
+}
+
+void LLViewerTextureManager::init()
+{
+ LLPointer<LLImageRaw> raw = new LLImageRaw(1,1,3);
+ raw->clear(0x77, 0x77, 0x77, 0xFF);
+ LLViewerTexture::sNullImagep = LLViewerTextureManager::getLocalTexture(raw.get(), TRUE) ;
+
+#if 1
+ LLPointer<LLViewerFetchedTexture> imagep = new LLViewerFetchedTexture(IMG_DEFAULT, TRUE);
+ LLViewerFetchedTexture::sDefaultImagep = imagep;
+
+ const S32 dim = 128;
+ LLPointer<LLImageRaw> image_raw = new LLImageRaw(dim,dim,3);
+ U8* data = image_raw->getData();
+ for (S32 i = 0; i<dim; i++)
+ {
+ for (S32 j = 0; j<dim; j++)
+ {
+#if 0
+ const S32 border = 2;
+ if (i<border || j<border || i>=(dim-border) || j>=(dim-border))
+ {
+ *data++ = 0xff;
+ *data++ = 0xff;
+ *data++ = 0xff;
+ }
+ else
+#endif
+ {
+ *data++ = 0x7f;
+ *data++ = 0x7f;
+ *data++ = 0x7f;
+ }
+ }
+ }
+ imagep->createGLTexture(0, image_raw);
+ image_raw = NULL;
+ gTextureList.addImage(imagep);
+ LLViewerFetchedTexture::sDefaultImagep->dontDiscard();
+#else
+ LLViewerFetchedTexture::sDefaultImagep = LLViewerTextureManager::getFetchedTexture(IMG_DEFAULT, TRUE, TRUE);
+#endif
+
+ LLViewerFetchedTexture::sSmokeImagep = LLViewerTextureManager::getFetchedTexture(IMG_SMOKE, TRUE, TRUE);
+ LLViewerFetchedTexture::sSmokeImagep->setNoDelete() ;
+
+ LLViewerTexture::initClass() ;
+
+ if(LLFastTimer::sMetricLog)
+ {
+ LLViewerTextureManager::sTesterp = new LLTexturePipelineTester() ;
+ }
+}
+
+void LLViewerTextureManager::cleanup()
+{
+ stop_glerror();
+
+ LLImageGL::sDefaultGLTexture = NULL ;
+ LLViewerTexture::sNullImagep = NULL;
+ LLViewerFetchedTexture::sDefaultImagep = NULL;
+ LLViewerFetchedTexture::sSmokeImagep = NULL;
+ LLViewerFetchedTexture::sMissingAssetImagep = NULL;
+ LLViewerFetchedTexture::sWhiteImagep = NULL;
+
+ LLViewerMediaTexture::sMediaMap.clear() ;
+}
+
+//----------------------------------------------------------------------------------------------
+//----------------------------------------------------------------------------------------------
+//start of LLViewerTexture
+//----------------------------------------------------------------------------------------------
+// static
+void LLViewerTexture::initClass()
+{
+ LLImageGL::sDefaultGLTexture = LLViewerFetchedTexture::sDefaultImagep->getGLTexture() ;
+}
+
+// static
+void LLViewerTexture::cleanupClass()
+{
+}
+
+// tuning params
+const F32 discard_bias_delta = .05f;
+const F32 discard_delta_time = 0.5f;
+const S32 min_non_tex_system_mem = (128<<20); // 128 MB
+// non-const (used externally
+F32 texmem_lower_bound_scale = 0.85f;
+F32 texmem_middle_bound_scale = 0.925f;
+
+//static
+void LLViewerTexture::updateClass(const F32 velocity, const F32 angular_velocity)
+{
+ if(LLViewerTextureManager::sTesterp)
+ {
+ LLViewerTextureManager::sTesterp->update() ;
+ }
+ LLViewerMediaTexture::updateClass() ;
+
+ sBoundTextureMemoryInBytes = LLImageGL::sBoundTextureMemoryInBytes;//in bytes
+ sTotalTextureMemoryInBytes = LLImageGL::sGlobalTextureMemoryInBytes;//in bytes
+ sMaxBoundTextureMemInMegaBytes = gTextureList.getMaxResidentTexMem();//in MB
+ sMaxTotalTextureMemInMegaBytes = gTextureList.getMaxTotalTextureMem() ;//in MB
+ sMaxDesiredTextureMemInBytes = MEGA_BYTES_TO_BYTES(sMaxTotalTextureMemInMegaBytes) ; //in Bytes, by default and when total used texture memory is small.
+
+ if (BYTES_TO_MEGA_BYTES(sBoundTextureMemoryInBytes) >= sMaxBoundTextureMemInMegaBytes ||
+ BYTES_TO_MEGA_BYTES(sTotalTextureMemoryInBytes) >= sMaxTotalTextureMemInMegaBytes)
+ {
+ //when texture memory overflows, lower down the threashold to release the textures more aggressively.
+ sMaxDesiredTextureMemInBytes = llmin((S32)(sMaxDesiredTextureMemInBytes * 0.75f) , MEGA_BYTES_TO_BYTES(MAX_VIDEO_RAM_IN_MEGA_BYTES)) ;//512 MB
+
+ // If we are using more texture memory than we should,
+ // scale up the desired discard level
+ if (sEvaluationTimer.getElapsedTimeF32() > discard_delta_time)
+ {
+ sDesiredDiscardBias += discard_bias_delta;
+ sEvaluationTimer.reset();
+ }
+ }
+ else if (sDesiredDiscardBias > 0.0f &&
+ BYTES_TO_MEGA_BYTES(sBoundTextureMemoryInBytes) < sMaxBoundTextureMemInMegaBytes * texmem_lower_bound_scale &&
+ BYTES_TO_MEGA_BYTES(sTotalTextureMemoryInBytes) < sMaxTotalTextureMemInMegaBytes * texmem_lower_bound_scale)
+ {
+ // If we are using less texture memory than we should,
+ // scale down the desired discard level
+ if (sEvaluationTimer.getElapsedTimeF32() > discard_delta_time)
+ {
+ sDesiredDiscardBias -= discard_bias_delta;
+ sEvaluationTimer.reset();
+ }
+ }
+ sDesiredDiscardBias = llclamp(sDesiredDiscardBias, desired_discard_bias_min, desired_discard_bias_max);
+}
+
+//end of static functions
+//-------------------------------------------------------------------------------------------
+const U32 LLViewerTexture::sCurrentFileVersion = 1;
+
+LLViewerTexture::LLViewerTexture(BOOL usemipmaps)
+{
+ init(true);
+ mUseMipMaps = usemipmaps ;
+
+ mID.generate();
+ sImageCount++;
+}
+
+LLViewerTexture::LLViewerTexture(const LLUUID& id, BOOL usemipmaps)
+ : mID(id)
+{
+ init(true);
+ mUseMipMaps = usemipmaps ;
+
+ sImageCount++;
+}
+
+LLViewerTexture::LLViewerTexture(const U32 width, const U32 height, const U8 components, BOOL usemipmaps)
+{
+ init(true);
+
+ mFullWidth = width ;
+ mFullHeight = height ;
+ mUseMipMaps = usemipmaps ;
+ mComponents = components ;
+
+ mID.generate();
+ sImageCount++;
+}
+
+LLViewerTexture::LLViewerTexture(const LLImageRaw* raw, BOOL usemipmaps)
+{
+ init(true);
+ mUseMipMaps = usemipmaps ;
+ mGLTexturep = new LLImageGL(raw, usemipmaps) ;
+
+ // Create an empty image of the specified size and width
+ mID.generate();
+ sImageCount++;
+}
+
+LLViewerTexture::~LLViewerTexture()
+{
+ sImageCount--;
+}
+
+void LLViewerTexture::init(bool firstinit)
+{
+ mBoostLevel = LLViewerTexture::BOOST_NONE;
+
+ mFullWidth = 0;
+ mFullHeight = 0;
+ mUseMipMaps = FALSE ;
+ mComponents = 0 ;
+
+ mTextureState = NO_DELETE ;
+ mDontDiscard = FALSE;
+ mMaxVirtualSize = 0.f;
+}
+
+//virtual
+S8 LLViewerTexture::getType() const
+{
+ return LLViewerTexture::LOCAL_TEXTURE ;
+}
+
+void LLViewerTexture::cleanup()
+{
+ mFaceList.clear() ;
+
+ if(mGLTexturep)
+ {
+ mGLTexturep->cleanup();
+ }
+}
+
+// virtual
+void LLViewerTexture::dump()
+{
+ if(mGLTexturep)
+ {
+ mGLTexturep->dump();
+ }
+
+ llinfos << "LLViewerTexture"
+ << " mID " << mID
+ << llendl;
+}
+
+void LLViewerTexture::setBoostLevel(S32 level)
+{
+ if(mBoostLevel != level)
+ {
+ mBoostLevel = level ;
+ if(mBoostLevel != LLViewerTexture::BOOST_NONE)
+ {
+ setNoDelete() ;
+ }
+ }
+}
+
+
+bool LLViewerTexture::bindDefaultImage(S32 stage) const
+{
+ if (stage < 0) return false;
+
+ bool res = true;
+ if (LLViewerFetchedTexture::sDefaultImagep.notNull() && (this != LLViewerFetchedTexture::sDefaultImagep.get()))
+ {
+ // use default if we've got it
+ res = gGL.getTexUnit(stage)->bind(LLViewerFetchedTexture::sDefaultImagep);
+ }
+ if (!res && LLViewerTexture::sNullImagep.notNull() && (this != LLViewerTexture::sNullImagep))
+ {
+ res = gGL.getTexUnit(stage)->bind(LLViewerTexture::sNullImagep) ;
+ }
+ if (!res)
+ {
+ llwarns << "LLViewerTexture::bindDefaultImage failed." << llendl;
+ }
+ stop_glerror();
+ if(LLViewerTextureManager::sTesterp)
+ {
+ LLViewerTextureManager::sTesterp->updateGrayTextureBinding() ;
+ }
+ return res;
+}
+
+//virtual
+BOOL LLViewerTexture::isMissingAsset()const
+{
+ return FALSE;
+}
+
+//virtual
+void LLViewerTexture::forceImmediateUpdate()
+{
+}
+
+void LLViewerTexture::addTextureStats(F32 virtual_size) const
+{
+ if (virtual_size > mMaxVirtualSize)
+ {
+ mMaxVirtualSize = virtual_size;
+ }
+}
+
+void LLViewerTexture::resetTextureStats(BOOL zero)
+{
+ if (zero)
+ {
+ mMaxVirtualSize = 0.0f;
+ }
+ else
+ {
+ mMaxVirtualSize -= mMaxVirtualSize * .10f; // decay by 5%/update
+ }
+}
+
+void LLViewerTexture::addFace(LLFace* facep)
+{
+ mFaceList.push_back(facep) ;
+}
+void LLViewerTexture::removeFace(LLFace* facep)
+{
+ mFaceList.remove(facep) ;
+}
+
+void LLViewerTexture::switchToTexture(LLViewerTexture* new_texture)
+{
+ if(this == new_texture)
+ {
+ return ;
+ }
+
+ new_texture->addTextureStats(getMaxVirtualSize()) ;
+
+ for(ll_face_list_t::iterator iter = mFaceList.begin(); iter != mFaceList.end(); )
+ {
+ LLFace* facep = *iter++ ;
+ facep->setTexture(new_texture) ;
+ facep->getViewerObject()->changeTEImage(this, new_texture) ;
+ gPipeline.markTextured(facep->getDrawable());
+ }
+}
+
+void LLViewerTexture::forceActive()
+{
+ mTextureState = ACTIVE ;
+}
+
+void LLViewerTexture::setActive()
+{
+ if(mTextureState != NO_DELETE)
+ {
+ mTextureState = ACTIVE ;
+ }
+}
+
+//set the texture to stay in memory
+void LLViewerTexture::setNoDelete()
+{
+ mTextureState = NO_DELETE ;
+}
+
+void LLViewerTexture::generateGLTexture()
+{
+ if(mGLTexturep.isNull())
+ {
+ mGLTexturep = new LLImageGL(mFullWidth, mFullHeight, mComponents, mUseMipMaps) ;
+ }
+}
+
+LLImageGL* LLViewerTexture::getGLTexture() const
+{
+ llassert_always(mGLTexturep.notNull()) ;
+
+ return mGLTexturep ;
+}
+
+BOOL LLViewerTexture::createGLTexture()
+{
+ if(mGLTexturep.isNull())
+ {
+ generateGLTexture() ;
+ }
+
+ return mGLTexturep->createGLTexture() ;
+}
+
+BOOL LLViewerTexture::createGLTexture(S32 discard_level, const LLImageRaw* imageraw, S32 usename)
+{
+ llassert_always(mGLTexturep.notNull()) ;
+
+ return mGLTexturep->createGLTexture(discard_level, imageraw, usename) ;
+}
+
+void LLViewerTexture::setExplicitFormat(LLGLint internal_format, LLGLenum primary_format, LLGLenum type_format, BOOL swap_bytes)
+{
+ llassert_always(mGLTexturep.notNull()) ;
+
+ mGLTexturep->setExplicitFormat(internal_format, primary_format, type_format, swap_bytes) ;
+}
+void LLViewerTexture::setAddressMode(LLTexUnit::eTextureAddressMode mode)
+{
+ llassert_always(mGLTexturep.notNull()) ;
+ mGLTexturep->setAddressMode(mode) ;
+}
+void LLViewerTexture::setFilteringOption(LLTexUnit::eTextureFilterOptions option)
+{
+ llassert_always(mGLTexturep.notNull()) ;
+ mGLTexturep->setFilteringOption(option) ;
+}
+
+//virtual
+S32 LLViewerTexture::getWidth(S32 discard_level) const
+{
+ llassert_always(mGLTexturep.notNull()) ;
+ return mGLTexturep->getWidth(discard_level) ;
+}
+
+//virtual
+S32 LLViewerTexture::getHeight(S32 discard_level) const
+{
+ llassert_always(mGLTexturep.notNull()) ;
+ return mGLTexturep->getHeight(discard_level) ;
+}
+
+S32 LLViewerTexture::getMaxDiscardLevel() const
+{
+ llassert_always(mGLTexturep.notNull()) ;
+ return mGLTexturep->getMaxDiscardLevel() ;
+}
+S32 LLViewerTexture::getDiscardLevel() const
+{
+ llassert_always(mGLTexturep.notNull()) ;
+ return mGLTexturep->getDiscardLevel() ;
+}
+S8 LLViewerTexture::getComponents() const
+{
+ llassert_always(mGLTexturep.notNull()) ;
+
+ return mGLTexturep->getComponents() ;
+}
+
+LLGLuint LLViewerTexture::getTexName() const
+{
+ llassert_always(mGLTexturep.notNull()) ;
+
+ return mGLTexturep->getTexName() ;
+}
+
+BOOL LLViewerTexture::hasValidGLTexture() const
+{
+ if(mGLTexturep.notNull())
+ {
+ return mGLTexturep->getHasGLTexture() ;
+ }
+ return FALSE ;
+}
+
+BOOL LLViewerTexture::hasGLTexture() const
+{
+ return mGLTexturep.notNull() ;
+}
+
+BOOL LLViewerTexture::getBoundRecently() const
+{
+ if(mGLTexturep.notNull())
+ {
+ return mGLTexturep->getBoundRecently() ;
+ }
+ return FALSE ;
+}
+
+LLTexUnit::eTextureType LLViewerTexture::getTarget(void) const
+{
+ llassert_always(mGLTexturep.notNull()) ;
+ return mGLTexturep->getTarget() ;
+}
+
+BOOL LLViewerTexture::setSubImage(const LLImageRaw* imageraw, S32 x_pos, S32 y_pos, S32 width, S32 height)
+{
+ llassert_always(mGLTexturep.notNull()) ;
+
+ return mGLTexturep->setSubImage(imageraw, x_pos, y_pos, width, height) ;
+}
+
+BOOL LLViewerTexture::setSubImage(const U8* datap, S32 data_width, S32 data_height, S32 x_pos, S32 y_pos, S32 width, S32 height)
+{
+ llassert_always(mGLTexturep.notNull()) ;
+
+ return mGLTexturep->setSubImage(datap, data_width, data_height, x_pos, y_pos, width, height) ;
+}
+
+void LLViewerTexture::setGLTextureCreated (bool initialized)
+{
+ llassert_always(mGLTexturep.notNull()) ;
+
+ mGLTexturep->setGLTextureCreated (initialized) ;
+}
+
+LLTexUnit::eTextureAddressMode LLViewerTexture::getAddressMode(void) const
+{
+ llassert_always(mGLTexturep.notNull()) ;
+
+ return mGLTexturep->getAddressMode() ;
+}
+
+S32 LLViewerTexture::getTextureMemory() const
+{
+ llassert_always(mGLTexturep.notNull()) ;
+
+ return mGLTexturep->mTextureMemory ;
+}
+
+LLGLenum LLViewerTexture::getPrimaryFormat() const
+{
+ llassert_always(mGLTexturep.notNull()) ;
+
+ return mGLTexturep->getPrimaryFormat() ;
+}
+
+BOOL LLViewerTexture::getIsAlphaMask() const
+{
+ llassert_always(mGLTexturep.notNull()) ;
+
+ return mGLTexturep->getIsAlphaMask() ;
+}
+
+BOOL LLViewerTexture::getMask(const LLVector2 &tc)
+{
+ llassert_always(mGLTexturep.notNull()) ;
+
+ return mGLTexturep->getMask(tc) ;
+}
+
+F32 LLViewerTexture::getTimePassedSinceLastBound()
+{
+ llassert_always(mGLTexturep.notNull()) ;
+
+ return mGLTexturep->getTimePassedSinceLastBound() ;
+}
+BOOL LLViewerTexture::getMissed() const
+{
+ llassert_always(mGLTexturep.notNull()) ;
+
+ return mGLTexturep->getMissed() ;
+}
+
+BOOL LLViewerTexture::isValidForSculpt(S32 discard_level, S32 image_width, S32 image_height, S32 ncomponents)
+{
+ llassert_always(mGLTexturep.notNull()) ;
+
+ return mGLTexturep->isValidForSculpt(discard_level, image_width, image_height, ncomponents) ;
+}
+
+BOOL LLViewerTexture::readBackRaw(S32 discard_level, LLImageRaw* imageraw, bool compressed_ok) const
+{
+ llassert_always(mGLTexturep.notNull()) ;
+
+ return mGLTexturep->readBackRaw(discard_level, imageraw, compressed_ok) ;
+}
+
+void LLViewerTexture::destroyGLTexture()
+{
+ if(mGLTexturep.notNull() && mGLTexturep->getHasGLTexture())
+ {
+ mGLTexturep->destroyGLTexture() ;
+ mTextureState = DELETED ;
+ }
+}
+
+//virtual
+void LLViewerTexture::updateBindStatsForTester()
+{
+ if(LLViewerTextureManager::sTesterp)
+ {
+ LLViewerTextureManager::sTesterp->updateTextureBindingStats(this) ;
+ }
+}
+//----------------------------------------------------------------------------------------------
+//end of LLViewerTexture
+//----------------------------------------------------------------------------------------------
+
+//----------------------------------------------------------------------------------------------
+//start of LLViewerFetchedTexture
+//----------------------------------------------------------------------------------------------
+
+//static
+F32 LLViewerFetchedTexture::maxDecodePriority()
+{
+ return 2000000.f;
+}
+
+LLViewerFetchedTexture::LLViewerFetchedTexture(const LLUUID& id, BOOL usemipmaps)
+ : LLViewerTexture(id, usemipmaps)
+{
+ init(TRUE) ;
+ generateGLTexture() ;
+}
+
+LLViewerFetchedTexture::LLViewerFetchedTexture(const LLImageRaw* raw, BOOL usemipmaps)
+ : LLViewerTexture(raw, usemipmaps)
+{
+ init(TRUE) ;
+}
+
+LLViewerFetchedTexture::LLViewerFetchedTexture(const std::string& full_path, const LLUUID& id, BOOL usemipmaps)
+ : LLViewerTexture(id, usemipmaps),
+ mLocalFileName(full_path)
+{
+ init(TRUE) ;
+ generateGLTexture() ;
+}
+
+void LLViewerFetchedTexture::init(bool firstinit)
+{
+ mOrigWidth = 0;
+ mOrigHeight = 0;
+ mNeedsAux = FALSE;
+ mRequestedDiscardLevel = -1;
+ mRequestedDownloadPriority = 0.f;
+ mFullyLoaded = FALSE;
+ mDesiredDiscardLevel = MAX_DISCARD_LEVEL + 1;
+ mMinDesiredDiscardLevel = MAX_DISCARD_LEVEL + 1;
+
+ mDecodingAux = FALSE;
+
+ mKnownDrawWidth = 0;
+ mKnownDrawHeight = 0;
+
+ if (firstinit)
+ {
+ mDecodePriority = 0.f;
+ mInImageList = 0;
+ }
+
+ // Only set mIsMissingAsset true when we know for certain that the database
+ // does not contain this image.
+ mIsMissingAsset = FALSE;
+
+ mNeedsCreateTexture = FALSE;
+
+ mIsRawImageValid = FALSE;
+ mRawDiscardLevel = INVALID_DISCARD_LEVEL;
+ mMinDiscardLevel = 0;
+
+ mHasFetcher = FALSE;
+ mIsFetching = FALSE;
+ mFetchState = 0;
+ mFetchPriority = 0;
+ mDownloadProgress = 0.f;
+ mFetchDeltaTime = 999999.f;
+ mDecodeFrame = 0;
+ mVisibleFrame = 0;
+ mForSculpt = FALSE ;
+ mIsFetched = FALSE ;
+}
+
+LLViewerFetchedTexture::~LLViewerFetchedTexture()
+{
+ //*NOTE getTextureFetch can return NULL when Viewer is shutting down.
+ // This is due to LLWearableList is singleton and is destroyed after
+ // LLAppViewer::cleanup() was called. (see ticket EXT-177)
+ if (mHasFetcher && LLAppViewer::getTextureFetch())
+ {
+ LLAppViewer::getTextureFetch()->deleteRequest(getID(), true);
+ }
+ cleanup();
+}
+
+//virtual
+S8 LLViewerFetchedTexture::getType() const
+{
+ return LLViewerTexture::FETCHED_TEXTURE ;
+}
+
+void LLViewerFetchedTexture::cleanup()
+{
+ for(callback_list_t::iterator iter = mLoadedCallbackList.begin();
+ iter != mLoadedCallbackList.end(); )
+ {
+ LLLoadedCallbackEntry *entryp = *iter++;
+ // We never finished loading the image. Indicate failure.
+ // Note: this allows mLoadedCallbackUserData to be cleaned up.
+ entryp->mCallback( FALSE, this, NULL, NULL, 0, TRUE, entryp->mUserData );
+ delete entryp;
+ }
+ mLoadedCallbackList.clear();
+ mNeedsAux = FALSE;
+
+ // Clean up image data
+ destroyRawImage();
+}
+
+void LLViewerFetchedTexture::setForSculpt()
+{
+ mForSculpt = TRUE ;
+}
+
+BOOL LLViewerFetchedTexture::isDeleted()
+{
+ return mTextureState == DELETED ;
+}
+
+BOOL LLViewerFetchedTexture::isInactive()
+{
+ return mTextureState == INACTIVE ;
+}
+
+BOOL LLViewerFetchedTexture::isDeletionCandidate()
+{
+ return mTextureState == DELETION_CANDIDATE ;
+}
+
+void LLViewerFetchedTexture::setDeletionCandidate()
+{
+ if(mGLTexturep.notNull() && mGLTexturep->getTexName() && (mTextureState == INACTIVE))
+ {
+ mTextureState = DELETION_CANDIDATE ;
+ }
+}
+
+//set the texture inactive
+void LLViewerFetchedTexture::setInactive()
+{
+ if(mTextureState == ACTIVE && mGLTexturep.notNull() && mGLTexturep->getTexName() && !mGLTexturep->getBoundRecently())
+ {
+ mTextureState = INACTIVE ;
+ }
+}
+
+// virtual
+void LLViewerFetchedTexture::dump()
+{
+ LLViewerTexture::dump();
+
+ llinfos << "LLViewerFetchedTexture"
+ << " mIsMissingAsset " << (S32)mIsMissingAsset
+ << " mFullWidth " << mFullWidth
+ << " mFullHeight " << mFullHeight
+ << " mOrigWidth" << mOrigWidth
+ << " mOrigHeight" << mOrigHeight
+ << llendl;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+// ONLY called from LLViewerFetchedTextureList
+void LLViewerFetchedTexture::destroyTexture()
+{
+ if(LLImageGL::sGlobalTextureMemoryInBytes < sMaxDesiredTextureMemInBytes)//not ready to release unused memory.
+ {
+ return ;
+ }
+ if (mNeedsCreateTexture)//return if in the process of generating a new texture.
+ {
+ return ;
+ }
+
+ destroyGLTexture() ;
+ mFullyLoaded = FALSE ;
+}
+
+// ONLY called from LLViewerTextureList
+BOOL LLViewerFetchedTexture::createTexture(S32 usename/*= 0*/)
+{
+ if (!mNeedsCreateTexture)
+ {
+ destroyRawImage();
+ return FALSE;
+ }
+ mNeedsCreateTexture = FALSE;
+ if (mRawImage.isNull())
+ {
+ llerrs << "LLViewerTexture trying to create texture with no Raw Image" << llendl;
+ }
+// llinfos << llformat("IMAGE Creating (%d) [%d x %d] Bytes: %d ",
+// mRawDiscardLevel,
+// mRawImage->getWidth(), mRawImage->getHeight(),mRawImage->getDataSize())
+// << mID.getString() << llendl;
+ BOOL res = TRUE;
+ if (!gNoRender)
+ {
+ // store original size only for locally-sourced images
+ if (!mLocalFileName.empty())
+ {
+ mOrigWidth = mRawImage->getWidth();
+ mOrigHeight = mRawImage->getHeight();
+
+ // leave black border, do not scale image content
+ mRawImage->expandToPowerOfTwo(MAX_IMAGE_SIZE, FALSE);
+
+ mFullWidth = mRawImage->getWidth();
+ mFullHeight = mRawImage->getHeight();
+ }
+ else
+ {
+ mOrigWidth = mFullWidth;
+ mOrigHeight = mFullHeight;
+ }
+
+ bool size_okay = true;
+
+ U32 raw_width = mRawImage->getWidth() << mRawDiscardLevel;
+ U32 raw_height = mRawImage->getHeight() << mRawDiscardLevel;
+ if( raw_width > MAX_IMAGE_SIZE || raw_height > MAX_IMAGE_SIZE )
+ {
+ llinfos << "Width or height is greater than " << MAX_IMAGE_SIZE << ": (" << raw_width << "," << raw_height << ")" << llendl;
+ size_okay = false;
+ }
+
+ if (!LLImageGL::checkSize(mRawImage->getWidth(), mRawImage->getHeight()))
+ {
+ // A non power-of-two image was uploaded (through a non standard client)
+ llinfos << "Non power of two width or height: (" << mRawImage->getWidth() << "," << mRawImage->getHeight() << ")" << llendl;
+ size_okay = false;
+ }
+
+ if( !size_okay )
+ {
+ // An inappropriately-sized image was uploaded (through a non standard client)
+ // We treat these images as missing assets which causes them to
+ // be renderd as 'missing image' and to stop requesting data
+ setIsMissingAsset();
+ destroyRawImage();
+ return FALSE;
+ }
+
+ res = mGLTexturep->createGLTexture(mRawDiscardLevel, mRawImage, usename);
+ setActive() ;
+ }
+
+ //
+ // Iterate through the list of image loading callbacks to see
+ // what sort of data they need.
+ //
+ // *TODO: Fix image callback code
+ BOOL imageraw_callbacks = FALSE;
+ for(callback_list_t::iterator iter = mLoadedCallbackList.begin();
+ iter != mLoadedCallbackList.end(); )
+ {
+ LLLoadedCallbackEntry *entryp = *iter++;
+ if (entryp->mNeedsImageRaw)
+ {
+ imageraw_callbacks = TRUE;
+ break;
+ }
+ }
+
+ if (!imageraw_callbacks)
+ {
+ mNeedsAux = FALSE;
+ destroyRawImage();
+ }
+ return res;
+}
+
+// Call with 0,0 to turn this feature off.
+void LLViewerFetchedTexture::setKnownDrawSize(S32 width, S32 height)
+{
+ mKnownDrawWidth = width;
+ mKnownDrawHeight = height;
+ addTextureStats((F32)(width * height));
+}
+
+//virtual
+void LLViewerFetchedTexture::processTextureStats()
+{
+ if(mFullyLoaded)//already loaded
+ {
+ return ;
+ }
+
+ if(!mFullWidth || !mFullHeight)
+ {
+ mDesiredDiscardLevel = getMaxDiscardLevel() ;
+ }
+ else
+ {
+ mDesiredDiscardLevel = 0;
+ if (mFullWidth > MAX_IMAGE_SIZE_DEFAULT || mFullHeight > MAX_IMAGE_SIZE_DEFAULT)
+ {
+ mDesiredDiscardLevel = 1; // MAX_IMAGE_SIZE_DEFAULT = 1024 and max size ever is 2048
+ }
+
+ if(getDiscardLevel() >= 0 && (getDiscardLevel() <= mDesiredDiscardLevel))
+ {
+ mFullyLoaded = TRUE ;
+ }
+ }
+}
+
+//texture does not have any data, so we don't know the size of the image, treat it like 32 * 32.
+F32 LLViewerFetchedTexture::calcDecodePriorityForUnknownTexture(F32 pixel_priority)
+{
+ static const F64 log_2 = log(2.0);
+
+ F32 desired = (F32)(log(32.0/pixel_priority) / log_2);
+ S32 ddiscard = MAX_DISCARD_LEVEL - (S32)desired + 1;
+ ddiscard = llclamp(ddiscard, 1, 9);
+
+ return ddiscard*100000.f;
+}
+
+F32 LLViewerFetchedTexture::calcDecodePriority()
+{
+#ifndef LL_RELEASE_FOR_DOWNLOAD
+ if (mID == LLAppViewer::getTextureFetch()->mDebugID)
+ {
+ LLAppViewer::getTextureFetch()->mDebugCount++; // for setting breakpoints
+ }
+#endif
+
+ if(mFullyLoaded)//already loaded for static texture
+ {
+ return -4.0f ; //alreay fetched
+ }
+
+ if (mNeedsCreateTexture)
+ {
+ return mDecodePriority; // no change while waiting to create
+ }
+
+ F32 priority;
+ S32 cur_discard = getDiscardLevel();
+ bool have_all_data = (cur_discard >= 0 && (cur_discard <= mDesiredDiscardLevel));
+ F32 pixel_priority = fsqrtf(mMaxVirtualSize);
+ const S32 MIN_NOT_VISIBLE_FRAMES = 30; // NOTE: this function is not called every frame
+ mDecodeFrame++;
+ if (pixel_priority > 0.f)
+ {
+ mVisibleFrame = mDecodeFrame;
+ }
+
+ if (mIsMissingAsset)
+ {
+ priority = 0.0f;
+ }
+ else if (mDesiredDiscardLevel > getMaxDiscardLevel())
+ {
+ // Don't decode anything we don't need
+ priority = -1.0f;
+ }
+ else if (mBoostLevel == LLViewerTexture::BOOST_UI && !have_all_data)
+ {
+ priority = 1.f;
+ }
+ else if (pixel_priority <= 0.f && !have_all_data)
+ {
+ // Not on screen but we might want some data
+ if (mBoostLevel > BOOST_HIGH)
+ {
+ // Always want high boosted images
+ priority = 1.f;
+ }
+ else if (mVisibleFrame == 0 || (mDecodeFrame - mVisibleFrame > MIN_NOT_VISIBLE_FRAMES))
+ {
+ // Don't decode anything that isn't visible unless it's important
+ priority = -2.0f;
+ }
+ else
+ {
+ // Leave the priority as-is
+ return mDecodePriority;
+ }
+ }
+ else if (cur_discard < 0)
+ {
+ priority = calcDecodePriorityForUnknownTexture(pixel_priority) ;
+ }
+ else if ((mMinDiscardLevel > 0) && (cur_discard <= mMinDiscardLevel))
+ {
+ // larger mips are corrupted
+ priority = -3.0f;
+ }
+ else if (cur_discard <= mDesiredDiscardLevel)
+ {
+ priority = -4.0f;
+ }
+ else
+ {
+ // priority range = 100000-400000
+ S32 ddiscard = cur_discard - mDesiredDiscardLevel;
+ if (getDontDiscard())
+ {
+ ddiscard+=2;
+ }
+ else if (mGLTexturep.notNull() && !mGLTexturep->getBoundRecently() && mBoostLevel == 0)
+ {
+ ddiscard-=2;
+ }
+ ddiscard = llclamp(ddiscard, 0, 4);
+ priority = ddiscard*100000.f;
+ }
+ if (priority > 0.0f)
+ {
+ pixel_priority = llclamp(pixel_priority, 0.0f, priority-1.f); // priority range = 100000-900000
+ if ( mBoostLevel > BOOST_HIGH)
+ {
+ priority = 1000000.f + pixel_priority + 1000.f * mBoostLevel;
+ }
+ else
+ {
+ priority += 0.f + pixel_priority + 1000.f * mBoostLevel;
+ }
+ }
+ return priority;
+}
+//============================================================================
+
+void LLViewerFetchedTexture::setDecodePriority(F32 priority)
+{
+ llassert(!mInImageList);
+ mDecodePriority = priority;
+}
+
+bool LLViewerFetchedTexture::updateFetch()
+{
+ mFetchState = 0;
+ mFetchPriority = 0;
+ mFetchDeltaTime = 999999.f;
+ mRequestDeltaTime = 999999.f;
+
+#ifndef LL_RELEASE_FOR_DOWNLOAD
+ if (mID == LLAppViewer::getTextureFetch()->mDebugID)
+ {
+ LLAppViewer::getTextureFetch()->mDebugCount++; // for setting breakpoints
+ }
+#endif
+
+ if (mNeedsCreateTexture)
+ {
+ // We may be fetching still (e.g. waiting on write)
+ // but don't check until we've processed the raw data we have
+ return false;
+ }
+ if (mIsMissingAsset)
+ {
+ llassert_always(!mHasFetcher);
+ return false; // skip
+ }
+ if (!mLoadedCallbackList.empty() && mRawImage.notNull())
+ {
+ return false; // process any raw image data in callbacks before replacing
+ }
+
+ S32 current_discard = getDiscardLevel() ;
+ S32 desired_discard = getDesiredDiscardLevel();
+ F32 decode_priority = getDecodePriority();
+ decode_priority = llmax(decode_priority, 0.0f);
+
+ if (mIsFetching)
+ {
+ // Sets mRawDiscardLevel, mRawImage, mAuxRawImage
+ S32 fetch_discard = current_discard;
+ if (mRawImage.notNull()) sRawCount--;
+ if (mAuxRawImage.notNull()) sAuxCount--;
+ bool finished = LLAppViewer::getTextureFetch()->getRequestFinished(getID(), fetch_discard, mRawImage, mAuxRawImage);
+ if (mRawImage.notNull()) sRawCount++;
+ if (mAuxRawImage.notNull()) sAuxCount++;
+ if (finished)
+ {
+ mIsFetching = FALSE;
+ }
+ else
+ {
+ mFetchState = LLAppViewer::getTextureFetch()->getFetchState(mID, mDownloadProgress, mRequestedDownloadPriority,
+ mFetchPriority, mFetchDeltaTime, mRequestDeltaTime);
+ }
+
+ // We may have data ready regardless of whether or not we are finished (e.g. waiting on write)
+ if (mRawImage.notNull())
+ {
+ if(LLViewerTextureManager::sTesterp)
+ {
+ mIsFetched = TRUE ;
+ LLViewerTextureManager::sTesterp->updateTextureLoadingStats(this, mRawImage, LLAppViewer::getTextureFetch()->isFromLocalCache(mID)) ;
+ }
+ mRawDiscardLevel = fetch_discard;
+ if ((mRawImage->getDataSize() > 0 && mRawDiscardLevel >= 0) &&
+ (current_discard < 0 || mRawDiscardLevel < current_discard))
+ {
+ if (getComponents() != mRawImage->getComponents())
+ {
+ // We've changed the number of components, so we need to move any
+ // objects using this pool to a different pool.
+ mComponents = mRawImage->getComponents();
+ mGLTexturep->setComponents(mComponents) ;
+
+ gTextureList.dirtyImage(this);
+ }
+ mIsRawImageValid = TRUE;
+ gTextureList.mCreateTextureList.insert(this);
+ mNeedsCreateTexture = TRUE;
+ mFullWidth = mRawImage->getWidth() << mRawDiscardLevel;
+ mFullHeight = mRawImage->getHeight() << mRawDiscardLevel;
+ }
+ else
+ {
+ // Data is ready but we don't need it
+ // (received it already while fetcher was writing to disk)
+ destroyRawImage();
+ return false; // done
+ }
+ }
+
+ if (!mIsFetching)
+ {
+ if ((decode_priority > 0) && (mRawDiscardLevel < 0 || mRawDiscardLevel == INVALID_DISCARD_LEVEL))
+ {
+ // We finished but received no data
+ if (current_discard < 0)
+ {
+ setIsMissingAsset();
+ desired_discard = -1;
+ }
+ else
+ {
+ llwarns << mID << ": Setting min discard to " << current_discard << llendl;
+ mMinDiscardLevel = current_discard;
+ desired_discard = current_discard;
+ }
+ destroyRawImage();
+ }
+ else if (mRawImage.isNull())
+ {
+ // We have data, but our fetch failed to return raw data
+ // *TODO: FIgure out why this is happening and fix it
+ destroyRawImage();
+ }
+ }
+ else
+ {
+ LLAppViewer::getTextureFetch()->updateRequestPriority(mID, decode_priority);
+ }
+ }
+
+ bool make_request = true;
+
+ if (decode_priority <= 0)
+ {
+ make_request = false;
+ }
+ else if (mNeedsCreateTexture || mIsMissingAsset)
+ {
+ make_request = false;
+ }
+ else if (current_discard >= 0 && current_discard <= mMinDiscardLevel)
+ {
+ make_request = false;
+ }
+ else
+ {
+ if (mIsFetching)
+ {
+ if (mRequestedDiscardLevel <= desired_discard)
+ {
+ make_request = false;
+ }
+ }
+ else
+ {
+ if (current_discard >= 0 && current_discard <= desired_discard)
+ {
+ make_request = false;
+ }
+ }
+ }
+
+ if (make_request)
+ {
+ S32 w=0, h=0, c=0;
+ if (current_discard >= 0)
+ {
+ w = mGLTexturep->getWidth(0);
+ h = mGLTexturep->getHeight(0);
+ c = mComponents;
+ }
+ if (!mDontDiscard)
+ {
+ if (mBoostLevel == 0)
+ {
+ desired_discard = llmax(desired_discard, current_discard-1);
+ }
+ else
+ {
+ desired_discard = llmax(desired_discard, current_discard-2);
+ }
+ }
+
+ // bypass texturefetch directly by pulling from LLTextureCache
+ bool fetch_request_created = false;
+ if (mLocalFileName.empty())
+ {
+ fetch_request_created = LLAppViewer::getTextureFetch()->createRequest(getID(), getTargetHost(), decode_priority,
+ w, h, c, desired_discard,
+ needsAux());
+ }
+ else
+ {
+ fetch_request_created = LLAppViewer::getTextureFetch()->createRequest(mLocalFileName, getID(),getTargetHost(), decode_priority,
+ w, h, c, desired_discard,
+ needsAux());
+ }
+
+ if (fetch_request_created)
+ {
+ mHasFetcher = TRUE;
+ mIsFetching = TRUE;
+ mRequestedDiscardLevel = desired_discard;
+ mFetchState = LLAppViewer::getTextureFetch()->getFetchState(mID, mDownloadProgress, mRequestedDownloadPriority,
+ mFetchPriority, mFetchDeltaTime, mRequestDeltaTime);
+ }
+
+ // if createRequest() failed, we're finishing up a request for this UUID,
+ // wait for it to complete
+ }
+ else if (mHasFetcher && !mIsFetching)
+ {
+ // Only delete requests that haven't receeived any network data for a while
+ const F32 FETCH_IDLE_TIME = 5.f;
+ if (mLastPacketTimer.getElapsedTimeF32() > FETCH_IDLE_TIME)
+ {
+// llinfos << "Deleting request: " << getID() << " Discard: " << current_discard << " <= min:" << mMinDiscardLevel << " or priority == 0: " << decode_priority << llendl;
+ LLAppViewer::getTextureFetch()->deleteRequest(getID(), true);
+ mHasFetcher = FALSE;
+ }
+ }
+
+ llassert_always(mRawImage.notNull() || (!mNeedsCreateTexture && !mIsRawImageValid));
+
+ return mIsFetching ? true : false;
+}
+
+void LLViewerFetchedTexture::setIsMissingAsset()
+{
+ llwarns << mLocalFileName << " " << mID << ": Marking image as missing" << llendl;
+ if (mHasFetcher)
+ {
+ LLAppViewer::getTextureFetch()->deleteRequest(getID(), true);
+ mHasFetcher = FALSE;
+ mIsFetching = FALSE;
+ mFetchState = 0;
+ mFetchPriority = 0;
+ }
+ mIsMissingAsset = TRUE;
+}
+
+void LLViewerFetchedTexture::setLoadedCallback( loaded_callback_func loaded_callback,
+ S32 discard_level, BOOL keep_imageraw, BOOL needs_aux, void* userdata)
+{
+ //
+ // Don't do ANYTHING here, just add it to the global callback list
+ //
+ if (mLoadedCallbackList.empty())
+ {
+ // Put in list to call this->doLoadedCallbacks() periodically
+ gTextureList.mCallbackList.insert(this);
+ }
+ LLLoadedCallbackEntry* entryp = new LLLoadedCallbackEntry(loaded_callback, discard_level, keep_imageraw, userdata);
+ mLoadedCallbackList.push_back(entryp);
+ mNeedsAux |= needs_aux;
+ if (mNeedsAux && mAuxRawImage.isNull() && getDiscardLevel() >= 0)
+ {
+ // We need aux data, but we've already loaded the image, and it didn't have any
+ llwarns << "No aux data available for callback for image:" << getID() << llendl;
+ }
+}
+
+bool LLViewerFetchedTexture::doLoadedCallbacks()
+{
+ if (mNeedsCreateTexture)
+ {
+ return false;
+ }
+
+ bool res = false;
+
+ if (isMissingAsset())
+ {
+ for(callback_list_t::iterator iter = mLoadedCallbackList.begin();
+ iter != mLoadedCallbackList.end(); )
+ {
+ LLLoadedCallbackEntry *entryp = *iter++;
+ // We never finished loading the image. Indicate failure.
+ // Note: this allows mLoadedCallbackUserData to be cleaned up.
+ entryp->mCallback(FALSE, this, NULL, NULL, 0, TRUE, entryp->mUserData);
+ delete entryp;
+ }
+ mLoadedCallbackList.clear();
+
+ // Remove ourself from the global list of textures with callbacks
+ gTextureList.mCallbackList.erase(this);
+ }
+
+ S32 gl_discard = getDiscardLevel();
+
+ // If we don't have a legit GL image, set it to be lower than the worst discard level
+ if (gl_discard == -1)
+ {
+ gl_discard = MAX_DISCARD_LEVEL + 1;
+ }
+
+ //
+ // Determine the quality levels of textures that we can provide to callbacks
+ // and whether we need to do decompression/readback to get it
+ //
+ S32 current_raw_discard = MAX_DISCARD_LEVEL + 1; // We can always do a readback to get a raw discard
+ S32 best_raw_discard = gl_discard; // Current GL quality level
+ S32 current_aux_discard = MAX_DISCARD_LEVEL + 1;
+ S32 best_aux_discard = MAX_DISCARD_LEVEL + 1;
+
+ if (mIsRawImageValid)
+ {
+ // If we have an existing raw image, we have a baseline for the raw and auxiliary quality levels.
+ best_raw_discard = llmin(best_raw_discard, mRawDiscardLevel);
+ best_aux_discard = llmin(best_aux_discard, mRawDiscardLevel); // We always decode the aux when we decode the base raw
+ current_aux_discard = llmin(current_aux_discard, best_aux_discard);
+ }
+ else
+ {
+ // We have no data at all, we need to get it
+ // Do this by forcing the best aux discard to be 0.
+ best_aux_discard = 0;
+ }
+
+
+ //
+ // See if any of the callbacks would actually run using the data that we can provide,
+ // and also determine if we need to perform any readbacks or decodes.
+ //
+ bool run_gl_callbacks = false;
+ bool run_raw_callbacks = false;
+ bool need_readback = false;
+
+ for(callback_list_t::iterator iter = mLoadedCallbackList.begin();
+ iter != mLoadedCallbackList.end(); )
+ {
+ LLLoadedCallbackEntry *entryp = *iter++;
+ if (entryp->mNeedsImageRaw)
+ {
+ if (mNeedsAux)
+ {
+ //
+ // Need raw and auxiliary channels
+ //
+ if (entryp->mLastUsedDiscard > current_aux_discard)
+ {
+ // We have useful data, run the callbacks
+ run_raw_callbacks = true;
+ }
+ }
+ else
+ {
+ if (entryp->mLastUsedDiscard > current_raw_discard)
+ {
+ // We have useful data, just run the callbacks
+ run_raw_callbacks = true;
+ }
+ else if (entryp->mLastUsedDiscard > best_raw_discard)
+ {
+ // We can readback data, and then run the callbacks
+ need_readback = true;
+ run_raw_callbacks = true;
+ }
+ }
+ }
+ else
+ {
+ // Needs just GL
+ if (entryp->mLastUsedDiscard > gl_discard)
+ {
+ // We have enough data, run this callback requiring GL data
+ run_gl_callbacks = true;
+ }
+ }
+ }
+
+ //
+ // Do a readback if required, OR start off a texture decode
+ //
+ if (need_readback && (getMaxDiscardLevel() > gl_discard))
+ {
+ // Do a readback to get the GL data into the raw image
+ // We have GL data.
+
+ destroyRawImage();
+ readBackRawImage(gl_discard);
+ llassert_always(mRawImage.notNull());
+ llassert_always(!mNeedsAux || mAuxRawImage.notNull());
+ }
+
+ //
+ // Run raw/auxiliary data callbacks
+ //
+ if (run_raw_callbacks && mIsRawImageValid && (mRawDiscardLevel <= getMaxDiscardLevel()))
+ {
+ // Do callbacks which require raw image data.
+ //llinfos << "doLoadedCallbacks raw for " << getID() << llendl;
+
+ // Call each party interested in the raw data.
+ for(callback_list_t::iterator iter = mLoadedCallbackList.begin();
+ iter != mLoadedCallbackList.end(); )
+ {
+ callback_list_t::iterator curiter = iter++;
+ LLLoadedCallbackEntry *entryp = *curiter;
+ if (entryp->mNeedsImageRaw && (entryp->mLastUsedDiscard > mRawDiscardLevel))
+ {
+ // If we've loaded all the data there is to load or we've loaded enough
+ // to satisfy the interested party, then this is the last time that
+ // we're going to call them.
+
+ llassert_always(mRawImage.notNull());
+ if(mNeedsAux && mAuxRawImage.isNull())
+ {
+ llwarns << "Raw Image with no Aux Data for callback" << llendl;
+ }
+ BOOL final = mRawDiscardLevel <= entryp->mDesiredDiscard ? TRUE : FALSE;
+ //llinfos << "Running callback for " << getID() << llendl;
+ //llinfos << mRawImage->getWidth() << "x" << mRawImage->getHeight() << llendl;
+ if (final)
+ {
+ //llinfos << "Final!" << llendl;
+ }
+ entryp->mLastUsedDiscard = mRawDiscardLevel;
+ entryp->mCallback(TRUE, this, mRawImage, mAuxRawImage, mRawDiscardLevel, final, entryp->mUserData);
+ if (final)
+ {
+ iter = mLoadedCallbackList.erase(curiter);
+ delete entryp;
+ }
+ res = true;
+ }
+ }
+ }
+
+ //
+ // Run GL callbacks
+ //
+ if (run_gl_callbacks && (gl_discard <= getMaxDiscardLevel()))
+ {
+ //llinfos << "doLoadedCallbacks GL for " << getID() << llendl;
+
+ // Call the callbacks interested in GL data.
+ for(callback_list_t::iterator iter = mLoadedCallbackList.begin();
+ iter != mLoadedCallbackList.end(); )
+ {
+ callback_list_t::iterator curiter = iter++;
+ LLLoadedCallbackEntry *entryp = *curiter;
+ if (!entryp->mNeedsImageRaw && (entryp->mLastUsedDiscard > gl_discard))
+ {
+ BOOL final = gl_discard <= entryp->mDesiredDiscard ? TRUE : FALSE;
+ entryp->mLastUsedDiscard = gl_discard;
+ entryp->mCallback(TRUE, this, NULL, NULL, gl_discard, final, entryp->mUserData);
+ if (final)
+ {
+ iter = mLoadedCallbackList.erase(curiter);
+ delete entryp;
+ }
+ res = true;
+ }
+ }
+ }
+
+ //
+ // If we have no callbacks, take us off of the image callback list.
+ //
+ if (mLoadedCallbackList.empty())
+ {
+ gTextureList.mCallbackList.erase(this);
+ }
+
+ // Done with any raw image data at this point (will be re-created if we still have callbacks)
+ destroyRawImage();
+
+ return res;
+}
+
+//virtual
+void LLViewerFetchedTexture::forceImmediateUpdate()
+{
+ //only immediately update a deleted texture which is now being re-used.
+ if(!isDeleted())
+ {
+ return ;
+ }
+ //if already called forceImmediateUpdate()
+ if(mInImageList && mDecodePriority == LLViewerFetchedTexture::maxDecodePriority())
+ {
+ return ;
+ }
+
+ gTextureList.forceImmediateUpdate(this) ;
+ return ;
+}
+
+// Was in LLImageGL
+LLImageRaw* LLViewerFetchedTexture::readBackRawImage(S8 discard_level)
+{
+ llassert_always(mGLTexturep.notNull()) ;
+ llassert_always(discard_level >= 0);
+ llassert_always(mComponents > 0);
+ if (mRawImage.notNull())
+ {
+ llerrs << "called with existing mRawImage" << llendl;
+ mRawImage = NULL;
+ }
+ mRawImage = new LLImageRaw(mGLTexturep->getWidth(discard_level), mGLTexturep->getHeight(discard_level), mComponents);
+ sRawCount++;
+ mRawDiscardLevel = discard_level;
+ mGLTexturep->readBackRaw(mRawDiscardLevel, mRawImage, false);
+ mIsRawImageValid = TRUE;
+
+ return mRawImage;
+}
+
+void LLViewerFetchedTexture::destroyRawImage()
+{
+ if (mRawImage.notNull()) sRawCount--;
+ if (mAuxRawImage.notNull()) sAuxCount--;
+ mRawImage = NULL;
+ mAuxRawImage = NULL;
+ mIsRawImageValid = FALSE;
+ mRawDiscardLevel = INVALID_DISCARD_LEVEL;
+}
+//----------------------------------------------------------------------------------------------
+//end of LLViewerFetchedTexture
+//----------------------------------------------------------------------------------------------
+
+//----------------------------------------------------------------------------------------------
+//start of LLViewerLODTexture
+//----------------------------------------------------------------------------------------------
+LLViewerLODTexture::LLViewerLODTexture(const LLUUID& id, BOOL usemipmaps)
+ : LLViewerFetchedTexture(id, usemipmaps)
+{
+ init(TRUE) ;
+}
+
+LLViewerLODTexture::LLViewerLODTexture(const std::string& full_path, const LLUUID& id, BOOL usemipmaps)
+ : LLViewerFetchedTexture(full_path, id, usemipmaps)
+{
+ init(TRUE) ;
+}
+
+void LLViewerLODTexture::init(bool firstinit)
+{
+ mTexelsPerImage = 64.f*64.f;
+ mDiscardVirtualSize = 0.f;
+ mCalculatedDiscardLevel = -1.f;
+}
+
+//virtual
+S8 LLViewerLODTexture::getType() const
+{
+ return LLViewerTexture::LOD_TEXTURE ;
+}
+
+// This is gauranteed to get called periodically for every texture
+//virtual
+void LLViewerLODTexture::processTextureStats()
+{
+ // Generate the request priority and render priority
+ if (mDontDiscard || !mUseMipMaps)
+ {
+ mDesiredDiscardLevel = 0;
+ if (mFullWidth > MAX_IMAGE_SIZE_DEFAULT || mFullHeight > MAX_IMAGE_SIZE_DEFAULT)
+ mDesiredDiscardLevel = 1; // MAX_IMAGE_SIZE_DEFAULT = 1024 and max size ever is 2048
+ }
+ else if (mBoostLevel < LLViewerTexture::BOOST_HIGH && mMaxVirtualSize <= 10.f)
+ {
+ // If the image has not been significantly visible in a while, we don't want it
+ mDesiredDiscardLevel = llmin(mMinDesiredDiscardLevel, (S8)(MAX_DISCARD_LEVEL + 1));
+ }
+ else if (!mFullWidth || !mFullHeight)
+ {
+ mDesiredDiscardLevel = getMaxDiscardLevel() ;
+ }
+ else
+ {
+ //static const F64 log_2 = log(2.0);
+ static const F64 log_4 = log(4.0);
+
+ S32 fullwidth = llmin(mFullWidth,(S32)MAX_IMAGE_SIZE_DEFAULT);
+ S32 fullheight = llmin(mFullHeight,(S32)MAX_IMAGE_SIZE_DEFAULT);
+ mTexelsPerImage = (F32)fullwidth * fullheight;
+
+ F32 discard_level = 0.f;
+
+ // If we know the output width and height, we can force the discard
+ // level to the correct value, and thus not decode more texture
+ // data than we need to.
+ /*if (mBoostLevel == LLViewerTexture::BOOST_UI ||
+ mBoostLevel == LLViewerTexture::BOOST_PREVIEW ||
+ mBoostLevel == LLViewerTexture::BOOST_AVATAR_SELF) // JAMESDEBUG what about AVATAR_BAKED_SELF?
+ {
+ discard_level = 0; // full res
+ }
+ else*/ if (mKnownDrawWidth && mKnownDrawHeight)
+ {
+ S32 draw_texels = mKnownDrawWidth * mKnownDrawHeight;
+
+ // Use log_4 because we're in square-pixel space, so an image
+ // with twice the width and twice the height will have mTexelsPerImage
+ // 4 * draw_size
+ discard_level = (F32)(log(mTexelsPerImage/draw_texels) / log_4);
+ }
+ else
+ {
+ if ((mCalculatedDiscardLevel >= 0.f) &&
+ (llabs(mMaxVirtualSize - mDiscardVirtualSize) < mMaxVirtualSize*.20f))
+ {
+ // < 20% change in virtual size = no change in desired discard
+ discard_level = mCalculatedDiscardLevel;
+ }
+ else
+ {
+ // Calculate the required scale factor of the image using pixels per texel
+ discard_level = (F32)(log(mTexelsPerImage/mMaxVirtualSize) / log_4);
+ mDiscardVirtualSize = mMaxVirtualSize;
+ mCalculatedDiscardLevel = discard_level;
+ }
+ }
+ if (mBoostLevel < LLViewerTexture::BOOST_HIGH)
+ {
+ static const F32 discard_bias = -.5f; // Must be < 1 or highest discard will never load!
+ discard_level += discard_bias;
+ discard_level += sDesiredDiscardBias;
+ discard_level *= sDesiredDiscardScale; // scale
+ }
+ discard_level = floorf(discard_level);
+// discard_level -= (gTextureList.mVideoMemorySetting>>1); // more video ram = higher detail
+
+ F32 min_discard = 0.f;
+ if (mFullWidth > MAX_IMAGE_SIZE_DEFAULT || mFullHeight > MAX_IMAGE_SIZE_DEFAULT)
+ min_discard = 1.f; // MAX_IMAGE_SIZE_DEFAULT = 1024 and max size ever is 2048
+
+ discard_level = llclamp(discard_level, min_discard, (F32)MAX_DISCARD_LEVEL);
+
+ // Can't go higher than the max discard level
+ mDesiredDiscardLevel = llmin(getMaxDiscardLevel() + 1, (S32)discard_level);
+ // Clamp to min desired discard
+ mDesiredDiscardLevel = llmin(mMinDesiredDiscardLevel, mDesiredDiscardLevel);
+
+ //
+ // At this point we've calculated the quality level that we want,
+ // if possible. Now we check to see if we have it, and take the
+ // proper action if we don't.
+ //
+
+ BOOL increase_discard = FALSE;
+ S32 current_discard = getDiscardLevel();
+ if ((sDesiredDiscardBias > 0.0f) &&
+ (current_discard >= 0 && mDesiredDiscardLevel >= current_discard))
+ {
+ if ( BYTES_TO_MEGA_BYTES(sBoundTextureMemoryInBytes) > sMaxBoundTextureMemInMegaBytes * texmem_middle_bound_scale)
+ {
+ // Limit the amount of GL memory bound each frame
+ if (mDesiredDiscardLevel > current_discard)
+ {
+ increase_discard = TRUE;
+ }
+ }
+ if ( BYTES_TO_MEGA_BYTES(sTotalTextureMemoryInBytes) > sMaxTotalTextureMemInMegaBytes*texmem_middle_bound_scale)
+ {
+ // Only allow GL to have 2x the video card memory
+ if (!mGLTexturep->getBoundRecently())
+ {
+ increase_discard = TRUE;
+ }
+ }
+ if (increase_discard)
+ {
+ // llinfos << "DISCARDED: " << mID << " Discard: " << current_discard << llendl;
+ sBoundTextureMemoryInBytes -= mGLTexturep->mTextureMemory;
+ sTotalTextureMemoryInBytes -= mGLTexturep->mTextureMemory;
+ // Increase the discard level (reduce the texture res)
+ S32 new_discard = current_discard+1;
+ mGLTexturep->setDiscardLevel(new_discard);
+ sBoundTextureMemoryInBytes += mGLTexturep->mTextureMemory;
+ sTotalTextureMemoryInBytes += mGLTexturep->mTextureMemory;
+ if(LLViewerTextureManager::sTesterp)
+ {
+ LLViewerTextureManager::sTesterp->setStablizingTime() ;
+ }
+ }
+ }
+ }
+}
+
+//----------------------------------------------------------------------------------------------
+//end of LLViewerLODTexture
+//----------------------------------------------------------------------------------------------
+
+//----------------------------------------------------------------------------------------------
+//start of LLViewerMediaTexture
+//----------------------------------------------------------------------------------------------
+//static
+void LLViewerMediaTexture::updateClass()
+{
+ static const F32 MAX_INACTIVE_TIME = 30.f ;
+
+ for(media_map_t::iterator iter = sMediaMap.begin() ; iter != sMediaMap.end(); )
+ {
+ LLViewerMediaTexture* mediap = iter->second;
+ ++iter ;
+
+ if(mediap->getNumRefs() == 1 && mediap->getLastReferencedTimer()->getElapsedTimeF32() > MAX_INACTIVE_TIME) //one by sMediaMap
+ {
+ sMediaMap.erase(mediap->getID()) ;
+ }
+ }
+}
+
+LLViewerMediaTexture::LLViewerMediaTexture(const LLUUID& id, BOOL usemipmaps, LLImageGL* gl_image)
+ : LLViewerTexture(id, usemipmaps)
+{
+ sMediaMap.insert(std::make_pair(id, this));
+
+ mGLTexturep = gl_image ;
+ if(mGLTexturep.isNull())
+ {
+ generateGLTexture() ;
+ }
+ mGLTexturep->setNeedsAlphaAndPickMask(FALSE) ;
+
+ mIsPlaying = FALSE ;
+}
+
+void LLViewerMediaTexture::reinit(BOOL usemipmaps /* = TRUE */)
+{
+ mGLTexturep = NULL ;
+ init(false);
+ mUseMipMaps = usemipmaps ;
+ mIsPlaying = FALSE ;
+ getLastReferencedTimer()->reset() ;
+
+ generateGLTexture() ;
+ mGLTexturep->setNeedsAlphaAndPickMask(FALSE) ;
+}
+
+void LLViewerMediaTexture::setUseMipMaps(BOOL mipmap)
+{
+ mUseMipMaps = mipmap;
+
+ if(mGLTexturep.notNull())
+ {
+ mGLTexturep->setUseMipMaps(mipmap) ;
+ }
+}
+
+//virtual
+S8 LLViewerMediaTexture::getType() const
+{
+ return LLViewerTexture::MEDIA_TEXTURE ;
+}
+
+void LLViewerMediaTexture::setOldTexture(LLViewerTexture* tex)
+{
+ mOldTexturep = tex ;
+}
+
+LLViewerTexture* LLViewerMediaTexture::getOldTexture() const
+{
+ return mOldTexturep ;
+}
+//----------------------------------------------------------------------------------------------
+//end of LLViewerMediaTexture
+//----------------------------------------------------------------------------------------------
+
+//----------------------------------------------------------------------------------------------
+//start of LLTexturePipelineTester
+//----------------------------------------------------------------------------------------------
+LLTexturePipelineTester::LLTexturePipelineTester() :
+ LLMetricPerformanceTester("TextureTester", FALSE)
+{
+ addMetricString("TotalBytesLoaded") ;
+ addMetricString("TotalBytesLoadedFromCache") ;
+ addMetricString("TotalBytesLoadedForLargeImage") ;
+ addMetricString("TotalBytesLoadedForSculpties") ;
+ addMetricString("StartFetchingTime") ;
+ addMetricString("TotalGrayTime") ;
+ addMetricString("TotalStablizingTime") ;
+ addMetricString("StartTimeLoadingSculpties") ;
+ addMetricString("EndTimeLoadingSculpties") ;
+
+ addMetricString("Time") ;
+ addMetricString("TotalBytesBound") ;
+ addMetricString("TotalBytesBoundForLargeImage") ;
+ addMetricString("PercentageBytesBound") ;
+
+ mTotalBytesLoaded = 0 ;
+ mTotalBytesLoadedFromCache = 0 ;
+ mTotalBytesLoadedForLargeImage = 0 ;
+ mTotalBytesLoadedForSculpties = 0 ;
+
+ reset() ;
+}
+
+LLTexturePipelineTester::~LLTexturePipelineTester()
+{
+ LLViewerTextureManager::sTesterp = NULL ;
+}
+
+void LLTexturePipelineTester::update()
+{
+ mLastTotalBytesUsed = mTotalBytesUsed ;
+ mLastTotalBytesUsedForLargeImage = mTotalBytesUsedForLargeImage ;
+ mTotalBytesUsed = 0 ;
+ mTotalBytesUsedForLargeImage = 0 ;
+
+ if(LLAppViewer::getTextureFetch()->getNumRequests() > 0) //fetching list is not empty
+ {
+ if(mPause)
+ {
+ //start a new fetching session
+ reset() ;
+ mStartFetchingTime = LLImageGL::sLastFrameTime ;
+ mPause = FALSE ;
+ }
+
+ //update total gray time
+ if(mUsingDefaultTexture)
+ {
+ mUsingDefaultTexture = FALSE ;
+ mTotalGrayTime = LLImageGL::sLastFrameTime - mStartFetchingTime ;
+ }
+
+ //update the stablizing timer.
+ updateStablizingTime() ;
+
+ outputTestResults() ;
+ }
+ else if(!mPause)
+ {
+ //stop the current fetching session
+ mPause = TRUE ;
+ outputTestResults() ;
+ reset() ;
+ }
+}
+
+void LLTexturePipelineTester::reset()
+{
+ mPause = TRUE ;
+
+ mUsingDefaultTexture = FALSE ;
+ mStartStablizingTime = 0.0f ;
+ mEndStablizingTime = 0.0f ;
+
+ mTotalBytesUsed = 0 ;
+ mTotalBytesUsedForLargeImage = 0 ;
+ mLastTotalBytesUsed = 0 ;
+ mLastTotalBytesUsedForLargeImage = 0 ;
+
+ mStartFetchingTime = 0.0f ;
+
+ mTotalGrayTime = 0.0f ;
+ mTotalStablizingTime = 0.0f ;
+
+ mStartTimeLoadingSculpties = 1.0f ;
+ mEndTimeLoadingSculpties = 0.0f ;
+}
+
+//virtual
+void LLTexturePipelineTester::outputTestRecord(LLSD *sd)
+{
+ (*sd)[mCurLabel]["TotalBytesLoaded"] = (LLSD::Integer)mTotalBytesLoaded ;
+ (*sd)[mCurLabel]["TotalBytesLoadedFromCache"] = (LLSD::Integer)mTotalBytesLoadedFromCache ;
+ (*sd)[mCurLabel]["TotalBytesLoadedForLargeImage"] = (LLSD::Integer)mTotalBytesLoadedForLargeImage ;
+ (*sd)[mCurLabel]["TotalBytesLoadedForSculpties"] = (LLSD::Integer)mTotalBytesLoadedForSculpties ;
+
+ (*sd)[mCurLabel]["StartFetchingTime"] = (LLSD::Real)mStartFetchingTime ;
+ (*sd)[mCurLabel]["TotalGrayTime"] = (LLSD::Real)mTotalGrayTime ;
+ (*sd)[mCurLabel]["TotalStablizingTime"] = (LLSD::Real)mTotalStablizingTime ;
+
+ (*sd)[mCurLabel]["StartTimeLoadingSculpties"] = (LLSD::Real)mStartTimeLoadingSculpties ;
+ (*sd)[mCurLabel]["EndTimeLoadingSculpties"] = (LLSD::Real)mEndTimeLoadingSculpties ;
+
+ (*sd)[mCurLabel]["Time"] = LLImageGL::sLastFrameTime ;
+ (*sd)[mCurLabel]["TotalBytesBound"] = (LLSD::Integer)mLastTotalBytesUsed ;
+ (*sd)[mCurLabel]["TotalBytesBoundForLargeImage"] = (LLSD::Integer)mLastTotalBytesUsedForLargeImage ;
+ (*sd)[mCurLabel]["PercentageBytesBound"] = (LLSD::Real)(100.f * mLastTotalBytesUsed / mTotalBytesLoaded) ;
+}
+
+void LLTexturePipelineTester::updateTextureBindingStats(const LLViewerTexture* imagep)
+{
+ U32 mem_size = (U32)imagep->getTextureMemory() ;
+ mTotalBytesUsed += mem_size ;
+
+ if(MIN_LARGE_IMAGE_AREA <= (U32)(mem_size / (U32)imagep->getComponents()))
+ {
+ mTotalBytesUsedForLargeImage += mem_size ;
+ }
+}
+
+void LLTexturePipelineTester::updateTextureLoadingStats(const LLViewerFetchedTexture* imagep, const LLImageRaw* raw_imagep, BOOL from_cache)
+{
+ U32 data_size = (U32)raw_imagep->getDataSize() ;
+ mTotalBytesLoaded += data_size ;
+
+ if(from_cache)
+ {
+ mTotalBytesLoadedFromCache += data_size ;
+ }
+
+ if(MIN_LARGE_IMAGE_AREA <= (U32)(data_size / (U32)raw_imagep->getComponents()))
+ {
+ mTotalBytesLoadedForLargeImage += data_size ;
+ }
+
+ if(imagep->isForSculpt())
+ {
+ mTotalBytesLoadedForSculpties += data_size ;
+
+ if(mStartTimeLoadingSculpties > mEndTimeLoadingSculpties)
+ {
+ mStartTimeLoadingSculpties = LLImageGL::sLastFrameTime ;
+ }
+ mEndTimeLoadingSculpties = LLImageGL::sLastFrameTime ;
+ }
+}
+
+void LLTexturePipelineTester::updateGrayTextureBinding()
+{
+ mUsingDefaultTexture = TRUE ;
+}
+
+void LLTexturePipelineTester::setStablizingTime()
+{
+ if(mStartStablizingTime <= mStartFetchingTime)
+ {
+ mStartStablizingTime = LLImageGL::sLastFrameTime ;
+ }
+ mEndStablizingTime = LLImageGL::sLastFrameTime ;
+}
+
+void LLTexturePipelineTester::updateStablizingTime()
+{
+ if(mStartStablizingTime > mStartFetchingTime)
+ {
+ F32 t = mEndStablizingTime - mStartStablizingTime ;
+
+ if(t > 0.0001f && (t - mTotalStablizingTime) < 0.0001f)
+ {
+ //already stablized
+ mTotalStablizingTime = LLImageGL::sLastFrameTime - mStartStablizingTime ;
+
+ //cancel the timer
+ mStartStablizingTime = 0.f ;
+ mEndStablizingTime = 0.f ;
+ }
+ else
+ {
+ mTotalStablizingTime = t ;
+ }
+ }
+ mTotalStablizingTime = 0.f ;
+}
+
+//virtual
+void LLTexturePipelineTester::compareTestSessions(std::ofstream* os)
+{
+ LLTexturePipelineTester::LLTextureTestSession* base_sessionp = dynamic_cast<LLTexturePipelineTester::LLTextureTestSession*>(mBaseSessionp) ;
+ LLTexturePipelineTester::LLTextureTestSession* current_sessionp = dynamic_cast<LLTexturePipelineTester::LLTextureTestSession*>(mCurrentSessionp) ;
+ if(!base_sessionp || !current_sessionp)
+ {
+ llerrs << "type of test session does not match!" << llendl ;
+ }
+
+ //compare and output the comparison
+ *os << llformat("%s\n", mName.c_str()) ;
+ *os << llformat("AggregateResults\n") ;
+
+ compareTestResults(os, "TotalFetchingTime", base_sessionp->mTotalFetchingTime, current_sessionp->mTotalFetchingTime) ;
+ compareTestResults(os, "TotalGrayTime", base_sessionp->mTotalGrayTime, current_sessionp->mTotalGrayTime) ;
+ compareTestResults(os, "TotalStablizingTime", base_sessionp->mTotalStablizingTime, current_sessionp->mTotalStablizingTime);
+ compareTestResults(os, "StartTimeLoadingSculpties", base_sessionp->mStartTimeLoadingSculpties, current_sessionp->mStartTimeLoadingSculpties) ;
+ compareTestResults(os, "TotalTimeLoadingSculpties", base_sessionp->mTotalTimeLoadingSculpties, current_sessionp->mTotalTimeLoadingSculpties) ;
+
+ compareTestResults(os, "TotalBytesLoaded", base_sessionp->mTotalBytesLoaded, current_sessionp->mTotalBytesLoaded) ;
+ compareTestResults(os, "TotalBytesLoadedFromCache", base_sessionp->mTotalBytesLoadedFromCache, current_sessionp->mTotalBytesLoadedFromCache) ;
+ compareTestResults(os, "TotalBytesLoadedForLargeImage", base_sessionp->mTotalBytesLoadedForLargeImage, current_sessionp->mTotalBytesLoadedForLargeImage) ;
+ compareTestResults(os, "TotalBytesLoadedForSculpties", base_sessionp->mTotalBytesLoadedForSculpties, current_sessionp->mTotalBytesLoadedForSculpties) ;
+
+ *os << llformat("InstantResults\n") ;
+ S32 size = llmin(base_sessionp->mInstantPerformanceListCounter, current_sessionp->mInstantPerformanceListCounter) ;
+ for(S32 i = 0 ; i < size ; i++)
+ {
+ *os << llformat("Time(B-T)-%.4f-%.4f\n", base_sessionp->mInstantPerformanceList[i].mTime, current_sessionp->mInstantPerformanceList[i].mTime) ;
+
+ compareTestResults(os, "AverageBytesUsedPerSecond", base_sessionp->mInstantPerformanceList[i].mAverageBytesUsedPerSecond,
+ current_sessionp->mInstantPerformanceList[i].mAverageBytesUsedPerSecond) ;
+
+ compareTestResults(os, "AverageBytesUsedForLargeImagePerSecond", base_sessionp->mInstantPerformanceList[i].mAverageBytesUsedForLargeImagePerSecond,
+ current_sessionp->mInstantPerformanceList[i].mAverageBytesUsedForLargeImagePerSecond) ;
+
+ compareTestResults(os, "AveragePercentageBytesUsedPerSecond", base_sessionp->mInstantPerformanceList[i].mAveragePercentageBytesUsedPerSecond,
+ current_sessionp->mInstantPerformanceList[i].mAveragePercentageBytesUsedPerSecond) ;
+ }
+
+ if(size < base_sessionp->mInstantPerformanceListCounter)
+ {
+ for(S32 i = size ; i < base_sessionp->mInstantPerformanceListCounter ; i++)
+ {
+ *os << llformat("Time(B-T)-%.4f- \n", base_sessionp->mInstantPerformanceList[i].mTime) ;
+
+ *os << llformat(", AverageBytesUsedPerSecond, %d, N/A \n", base_sessionp->mInstantPerformanceList[i].mAverageBytesUsedPerSecond) ;
+ *os << llformat(", AverageBytesUsedForLargeImagePerSecond, %d, N/A \n", base_sessionp->mInstantPerformanceList[i].mAverageBytesUsedForLargeImagePerSecond) ;
+ *os << llformat(", AveragePercentageBytesUsedPerSecond, %.4f, N/A \n", base_sessionp->mInstantPerformanceList[i].mAveragePercentageBytesUsedPerSecond) ;
+ }
+ }
+ else if(size < current_sessionp->mInstantPerformanceListCounter)
+ {
+ for(S32 i = size ; i < current_sessionp->mInstantPerformanceListCounter ; i++)
+ {
+ *os << llformat("Time(B-T)- -%.4f\n", current_sessionp->mInstantPerformanceList[i].mTime) ;
+
+ *os << llformat(", AverageBytesUsedPerSecond, N/A, %d\n", current_sessionp->mInstantPerformanceList[i].mAverageBytesUsedPerSecond) ;
+ *os << llformat(", AverageBytesUsedForLargeImagePerSecond, N/A, %d\n", current_sessionp->mInstantPerformanceList[i].mAverageBytesUsedForLargeImagePerSecond) ;
+ *os << llformat(", AveragePercentageBytesUsedPerSecond, N/A, %.4f\n", current_sessionp->mInstantPerformanceList[i].mAveragePercentageBytesUsedPerSecond) ;
+ }
+ }
+}
+
+//virtual
+LLMetricPerformanceTester::LLTestSession* LLTexturePipelineTester::loadTestSession(LLSD* log)
+{
+ LLTexturePipelineTester::LLTextureTestSession* sessionp = new LLTexturePipelineTester::LLTextureTestSession() ;
+ if(!sessionp)
+ {
+ return NULL ;
+ }
+
+ F32 total_fetching_time = 0.f ;
+ F32 total_gray_time = 0.f ;
+ F32 total_stablizing_time = 0.f ;
+ F32 total_loading_sculpties_time = 0.f ;
+
+ F32 start_fetching_time = -1.f ;
+ F32 start_fetching_sculpties_time = 0.f ;
+
+ F32 last_time = 0.0f ;
+ S32 frame_count = 0 ;
+
+ sessionp->mInstantPerformanceListCounter = 0 ;
+ sessionp->mInstantPerformanceList.resize(128) ;
+ sessionp->mInstantPerformanceList[sessionp->mInstantPerformanceListCounter].mAverageBytesUsedPerSecond = 0 ;
+ sessionp->mInstantPerformanceList[sessionp->mInstantPerformanceListCounter].mAverageBytesUsedForLargeImagePerSecond = 0 ;
+ sessionp->mInstantPerformanceList[sessionp->mInstantPerformanceListCounter].mAveragePercentageBytesUsedPerSecond = 0.f ;
+ sessionp->mInstantPerformanceList[sessionp->mInstantPerformanceListCounter].mTime = 0.f ;
+
+ //load a session
+ BOOL in_log = (*log).has(mCurLabel) ;
+ while(in_log)
+ {
+ LLSD::String label = mCurLabel ;
+ incLabel() ;
+ in_log = (*log).has(mCurLabel) ;
+
+ if(sessionp->mInstantPerformanceListCounter >= (S32)sessionp->mInstantPerformanceList.size())
+ {
+ sessionp->mInstantPerformanceList.resize(sessionp->mInstantPerformanceListCounter + 128) ;
+ }
+
+ //time
+ F32 start_time = (*log)[label]["StartFetchingTime"].asReal() ;
+ F32 cur_time = (*log)[label]["Time"].asReal() ;
+ if(start_time - start_fetching_time > 0.0001f) //fetching has paused for a while
+ {
+ sessionp->mTotalFetchingTime += total_fetching_time ;
+ sessionp->mTotalGrayTime += total_gray_time ;
+ sessionp->mTotalStablizingTime += total_stablizing_time ;
+
+ sessionp->mStartTimeLoadingSculpties = start_fetching_sculpties_time ;
+ sessionp->mTotalTimeLoadingSculpties += total_loading_sculpties_time ;
+
+ start_fetching_time = start_time ;
+ total_fetching_time = 0.0f ;
+ total_gray_time = 0.f ;
+ total_stablizing_time = 0.f ;
+ total_loading_sculpties_time = 0.f ;
+ }
+ else
+ {
+ total_fetching_time = cur_time - start_time ;
+ total_gray_time = (*log)[label]["TotalGrayTime"].asReal() ;
+ total_stablizing_time = (*log)[label]["TotalStablizingTime"].asReal() ;
+
+ total_loading_sculpties_time = (*log)[label]["EndTimeLoadingSculpties"].asReal() - (*log)[label]["StartTimeLoadingSculpties"].asReal() ;
+ if(start_fetching_sculpties_time < 0.f && total_loading_sculpties_time > 0.f)
+ {
+ start_fetching_sculpties_time = (*log)[label]["StartTimeLoadingSculpties"].asReal() ;
+ }
+ }
+
+ //total loaded bytes
+ sessionp->mTotalBytesLoaded = (*log)[label]["TotalBytesLoaded"].asInteger() ;
+ sessionp->mTotalBytesLoadedFromCache = (*log)[label]["TotalBytesLoadedFromCache"].asInteger() ;
+ sessionp->mTotalBytesLoadedForLargeImage = (*log)[label]["TotalBytesLoadedForLargeImage"].asInteger() ;
+ sessionp->mTotalBytesLoadedForSculpties = (*log)[label]["TotalBytesLoadedForSculpties"].asInteger() ;
+
+ //instant metrics
+ sessionp->mInstantPerformanceList[sessionp->mInstantPerformanceListCounter].mAverageBytesUsedPerSecond +=
+ (*log)[label]["TotalBytesBound"].asInteger() ;
+ sessionp->mInstantPerformanceList[sessionp->mInstantPerformanceListCounter].mAverageBytesUsedForLargeImagePerSecond +=
+ (*log)[label]["TotalBytesBoundForLargeImage"].asInteger() ;
+ sessionp->mInstantPerformanceList[sessionp->mInstantPerformanceListCounter].mAveragePercentageBytesUsedPerSecond +=
+ (*log)[label]["PercentageBytesBound"].asReal() ;
+ frame_count++ ;
+ if(cur_time - last_time >= 1.0f)
+ {
+ sessionp->mInstantPerformanceList[sessionp->mInstantPerformanceListCounter].mAverageBytesUsedPerSecond /= frame_count ;
+ sessionp->mInstantPerformanceList[sessionp->mInstantPerformanceListCounter].mAverageBytesUsedForLargeImagePerSecond /= frame_count ;
+ sessionp->mInstantPerformanceList[sessionp->mInstantPerformanceListCounter].mAveragePercentageBytesUsedPerSecond /= frame_count ;
+ sessionp->mInstantPerformanceList[sessionp->mInstantPerformanceListCounter].mTime = last_time ;
+
+ frame_count = 0 ;
+ last_time = cur_time ;
+ sessionp->mInstantPerformanceListCounter++ ;
+ sessionp->mInstantPerformanceList[sessionp->mInstantPerformanceListCounter].mAverageBytesUsedPerSecond = 0 ;
+ sessionp->mInstantPerformanceList[sessionp->mInstantPerformanceListCounter].mAverageBytesUsedForLargeImagePerSecond = 0 ;
+ sessionp->mInstantPerformanceList[sessionp->mInstantPerformanceListCounter].mAveragePercentageBytesUsedPerSecond = 0.f ;
+ sessionp->mInstantPerformanceList[sessionp->mInstantPerformanceListCounter].mTime = 0.f ;
+ }
+ }
+
+ sessionp->mTotalFetchingTime += total_fetching_time ;
+ sessionp->mTotalGrayTime += total_gray_time ;
+ sessionp->mTotalStablizingTime += total_stablizing_time ;
+
+ if(sessionp->mStartTimeLoadingSculpties < 0.f)
+ {
+ sessionp->mStartTimeLoadingSculpties = start_fetching_sculpties_time ;
+ }
+ sessionp->mTotalTimeLoadingSculpties += total_loading_sculpties_time ;
+
+ return sessionp;
+}
+
+LLTexturePipelineTester::LLTextureTestSession::LLTextureTestSession()
+{
+ reset() ;
+}
+LLTexturePipelineTester::LLTextureTestSession::~LLTextureTestSession()
+{
+}
+void LLTexturePipelineTester::LLTextureTestSession::reset()
+{
+ mTotalFetchingTime = 0.0f ;
+
+ mTotalGrayTime = 0.0f ;
+ mTotalStablizingTime = 0.0f ;
+
+ mStartTimeLoadingSculpties = 0.0f ;
+ mTotalTimeLoadingSculpties = 0.0f ;
+
+ mTotalBytesLoaded = 0 ;
+ mTotalBytesLoadedFromCache = 0 ;
+ mTotalBytesLoadedForLargeImage = 0 ;
+ mTotalBytesLoadedForSculpties = 0 ;
+
+ mInstantPerformanceListCounter = 0 ;
+}
+//----------------------------------------------------------------------------------------------
+//end of LLTexturePipelineTester
+//----------------------------------------------------------------------------------------------
+
diff --git a/indra/newview/llviewertexture.h b/indra/newview/llviewertexture.h
new file mode 100644
index 0000000000..142c212435
--- /dev/null
+++ b/indra/newview/llviewertexture.h
@@ -0,0 +1,672 @@
+/**
+ * @file llviewertexture.h
+ * @brief Object for managing images and their textures
+ *
+ * $LicenseInfo:firstyear=2000&license=viewergpl$
+ *
+ * Copyright (c) 2000-2009, Linden Research, Inc.
+ *
+ * Second Life Viewer Source Code
+ * The source code in this file ("Source Code") is provided by Linden Lab
+ * to you under the terms of the GNU General Public License, version 2.0
+ * ("GPL"), unless you have obtained a separate licensing agreement
+ * ("Other License"), formally executed by you and Linden Lab. Terms of
+ * the GPL can be found in doc/GPL-license.txt in this distribution, or
+ * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
+ *
+ * There are special exceptions to the terms and conditions of the GPL as
+ * it is applied to this Source Code. View the full text of the exception
+ * in the file doc/FLOSS-exception.txt in this software distribution, or
+ * online at
+ * http://secondlifegrid.net/programs/open_source/licensing/flossexception
+ *
+ * By copying, modifying or distributing this software, you acknowledge
+ * that you have read and understood your obligations described above,
+ * and agree to abide by those obligations.
+ *
+ * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+ * COMPLETENESS OR PERFORMANCE.
+ * $/LicenseInfo$
+ */
+
+#ifndef LL_LLVIEWERTEXTURE_H
+#define LL_LLVIEWERTEXTURE_H
+
+#include "lltexture.h"
+#include "lltimer.h"
+#include "llframetimer.h"
+#include "llhost.h"
+#include "llgltypes.h"
+#include "llrender.h"
+#include "llmetricperformancetester.h"
+
+#include <map>
+#include <list>
+
+#define MIN_VIDEO_RAM_IN_MEGA_BYTES 32
+#define MAX_VIDEO_RAM_IN_MEGA_BYTES 512 // 512MB max for performance reasons.
+
+class LLFace;
+class LLImageGL ;
+class LLViewerTexture;
+class LLViewerFetchedTexture ;
+class LLViewerMediaTexture ;
+class LLTexturePipelineTester ;
+
+typedef void (*loaded_callback_func)( BOOL success, LLViewerFetchedTexture *src_vi, LLImageRaw* src, LLImageRaw* src_aux, S32 discard_level, BOOL final, void* userdata );
+
+class LLVFile;
+class LLMessageSystem;
+
+class LLLoadedCallbackEntry
+{
+public:
+ LLLoadedCallbackEntry(loaded_callback_func cb,
+ S32 discard_level,
+ BOOL need_imageraw, // Needs image raw for the callback
+ void* userdata )
+ : mCallback(cb),
+ mLastUsedDiscard(MAX_DISCARD_LEVEL+1),
+ mDesiredDiscard(discard_level),
+ mNeedsImageRaw(need_imageraw),
+ mUserData(userdata)
+ {
+ }
+
+ loaded_callback_func mCallback;
+ S32 mLastUsedDiscard;
+ S32 mDesiredDiscard;
+ BOOL mNeedsImageRaw;
+ void* mUserData;
+};
+
+class LLTextureBar;
+
+class LLViewerTexture : public LLTexture
+{
+public:
+ enum
+ {
+ MAX_IMAGE_SIZE_DEFAULT = 1024,
+ INVALID_DISCARD_LEVEL = 0x7fff
+ };
+ enum
+ {
+ LOCAL_TEXTURE,
+ MEDIA_TEXTURE,
+ DYNAMIC_TEXTURE,
+ FETCHED_TEXTURE,
+ LOD_TEXTURE,
+ INVALID_TEXTURE_TYPE
+ };
+
+ enum EBoostLevel
+ {
+ BOOST_NONE = 0,
+ BOOST_AVATAR_BAKED = 1,
+ BOOST_AVATAR = 2,
+ BOOST_CLOUDS = 3,
+ BOOST_SCULPTED = 4,
+
+ BOOST_HIGH = 10,
+ BOOST_TERRAIN = 11, // has to be high priority for minimap / low detail
+ BOOST_SELECTED = 12,
+ BOOST_HUD = 13,
+ BOOST_AVATAR_BAKED_SELF = 14,
+ BOOST_UI = 15,
+ BOOST_PREVIEW = 16,
+ BOOST_MAP = 17,
+ BOOST_MAP_LAYER = 18,
+ BOOST_AVATAR_SELF = 19, // needed for baking avatar
+ BOOST_MAX_LEVEL
+ };
+
+protected:
+ virtual ~LLViewerTexture();
+ LOG_CLASS(LLViewerTexture);
+
+public:
+ static void initClass();
+ static void cleanupClass();
+ static void updateClass(const F32 velocity, const F32 angular_velocity) ;
+
+ LLViewerTexture(BOOL usemipmaps = TRUE);
+ LLViewerTexture(const LLUUID& id, BOOL usemipmaps) ;
+ LLViewerTexture(const LLImageRaw* raw, BOOL usemipmaps) ;
+ LLViewerTexture(const U32 width, const U32 height, const U8 components, BOOL usemipmaps) ;
+
+ virtual S8 getType() const;
+ virtual BOOL isMissingAsset()const ;
+ virtual void dump(); // debug info to llinfos
+
+ /*virtual*/ bool bindDefaultImage(const S32 stage = 0) const ;
+ /*virtual*/ void forceImmediateUpdate() ;
+
+ const LLUUID& getID() const { return mID; }
+
+ void setBoostLevel(S32 level);
+ S32 getBoostLevel() { return mBoostLevel; }
+
+ //maxVirtualSize of the texture
+ void addTextureStats(F32 virtual_size) const ;
+ void resetTextureStats(BOOL zero = FALSE);
+ F32 getMaxVirtualSize()const {return mMaxVirtualSize ;}
+
+ LLFrameTimer* getLastReferencedTimer() {return &mLastReferencedTimer ;}
+
+ S32 getFullWidth() const { return mFullWidth; }
+ S32 getFullHeight() const { return mFullHeight; }
+
+ void addFace(LLFace* facep) ;
+ void removeFace(LLFace* facep) ;
+
+ void generateGLTexture() ;
+ void destroyGLTexture() ;
+
+ //---------------------------------------------------------------------------------------------
+ //functions to access LLImageGL
+ //---------------------------------------------------------------------------------------------
+ /*virtual*/S32 getWidth(S32 discard_level = -1) const;
+ /*virtual*/S32 getHeight(S32 discard_level = -1) const;
+
+ BOOL hasGLTexture() const ;
+ BOOL hasValidGLTexture() const ;
+ LLGLuint getTexName() const ;
+ BOOL createGLTexture() ;
+ BOOL createGLTexture(S32 discard_level, const LLImageRaw* imageraw, S32 usename = 0);
+
+ void setFilteringOption(LLTexUnit::eTextureFilterOptions option);
+ void setExplicitFormat(LLGLint internal_format, LLGLenum primary_format, LLGLenum type_format = 0, BOOL swap_bytes = FALSE);
+ void setAddressMode(LLTexUnit::eTextureAddressMode mode);
+ BOOL setSubImage(const LLImageRaw* imageraw, S32 x_pos, S32 y_pos, S32 width, S32 height);
+ BOOL setSubImage(const U8* datap, S32 data_width, S32 data_height, S32 x_pos, S32 y_pos, S32 width, S32 height);
+ void setGLTextureCreated (bool initialized);
+
+ LLTexUnit::eTextureAddressMode getAddressMode(void) const ;
+ S32 getMaxDiscardLevel() const;
+ S32 getDiscardLevel() const;
+ S8 getComponents() const ;
+ BOOL getBoundRecently() const;
+ S32 getTextureMemory() const ;
+ LLGLenum getPrimaryFormat() const;
+ BOOL getIsAlphaMask() const ;
+ LLTexUnit::eTextureType getTarget(void) const ;
+ BOOL getMask(const LLVector2 &tc);
+ F32 getTimePassedSinceLastBound();
+ BOOL getMissed() const ;
+ BOOL isValidForSculpt(S32 discard_level, S32 image_width, S32 image_height, S32 ncomponents) ;
+ BOOL readBackRaw(S32 discard_level, LLImageRaw* imageraw, bool compressed_ok) const;
+ //---------------------------------------------------------------------------------------------
+ //end of functions to access LLImageGL
+ //---------------------------------------------------------------------------------------------
+
+ void switchToTexture(LLViewerTexture* new_texture) ; //make all faces pointing to this texture to point to new_texture.
+
+ //-----------------
+ /*virtual*/ void setActive() ;
+ void forceActive() ;
+ void setNoDelete() ;
+ void dontDiscard() { mDontDiscard = 1; mTextureState = NO_DELETE; }
+ BOOL getDontDiscard() const { return mDontDiscard; }
+ //-----------------
+
+ /*virtual*/ void updateBindStatsForTester() ;
+protected:
+ void cleanup() ;
+ void init(bool firstinit) ;
+
+private:
+ //note: do not make this function public.
+ /*virtual*/ LLImageGL* getGLTexture() const ;
+
+protected:
+ LLUUID mID;
+ S32 mBoostLevel; // enum describing priority level
+ S32 mFullWidth;
+ S32 mFullHeight;
+ BOOL mUseMipMaps ;
+ S8 mComponents;
+ mutable F32 mMaxVirtualSize; // The largest virtual size of the image, in pixels - how much data to we need?
+
+ LLFrameTimer mLastReferencedTimer;
+
+ typedef std::list<LLFace*> ll_face_list_t ;
+ ll_face_list_t mFaceList ; //reverse pointer pointing to the faces using this image as texture
+
+ //GL texture
+ LLPointer<LLImageGL> mGLTexturep ;
+ S8 mDontDiscard; // Keep full res version of this image (for UI, etc)
+
+protected:
+ typedef enum
+ {
+ DELETED = 0, //removed from memory
+ DELETION_CANDIDATE, //ready to be removed from memory
+ INACTIVE, //not be used for the last certain period (i.e., 30 seconds).
+ ACTIVE, //just being used, can become inactive if not being used for a certain time (10 seconds).
+ NO_DELETE = 99 //stay in memory, can not be removed.
+ } LLGLTexureState;
+ LLGLTexureState mTextureState ;
+
+public:
+ static const U32 sCurrentFileVersion;
+ static S32 sImageCount;
+ static S32 sRawCount;
+ static S32 sAuxCount;
+ static LLTimer sEvaluationTimer;
+ static F32 sDesiredDiscardBias;
+ static F32 sDesiredDiscardScale;
+ static S32 sBoundTextureMemoryInBytes;
+ static S32 sTotalTextureMemoryInBytes;
+ static S32 sMaxBoundTextureMemInMegaBytes;
+ static S32 sMaxTotalTextureMemInMegaBytes;
+ static S32 sMaxDesiredTextureMemInBytes ;
+ static BOOL sDontLoadVolumeTextures;
+
+ static LLPointer<LLViewerTexture> sNullImagep; // Null texture for non-textured objects.
+};
+
+
+//
+//textures are managed in gTextureList.
+//raw image data is fetched from remote or local cache
+//but the raw image this texture pointing to is fixed.
+//
+class LLViewerFetchedTexture : public LLViewerTexture
+{
+ friend class LLTextureBar; // debug info only
+ friend class LLTextureView; // debug info only
+
+protected:
+ /*virtual*/ ~LLViewerFetchedTexture();
+public:
+ LLViewerFetchedTexture(const LLUUID& id, BOOL usemipmaps = TRUE);
+ LLViewerFetchedTexture(const LLImageRaw* raw, BOOL usemipmaps);
+ LLViewerFetchedTexture(const std::string& full_path, const LLUUID& id, BOOL usemipmaps = TRUE);
+
+public:
+ static F32 maxDecodePriority();
+
+ struct Compare
+ {
+ // lhs < rhs
+ bool operator()(const LLPointer<LLViewerFetchedTexture> &lhs, const LLPointer<LLViewerFetchedTexture> &rhs) const
+ {
+ const LLViewerFetchedTexture* lhsp = (const LLViewerFetchedTexture*)lhs;
+ const LLViewerFetchedTexture* rhsp = (const LLViewerFetchedTexture*)rhs;
+ // greater priority is "less"
+ const F32 lpriority = lhsp->getDecodePriority();
+ const F32 rpriority = rhsp->getDecodePriority();
+ if (lpriority > rpriority) // higher priority
+ return true;
+ if (lpriority < rpriority)
+ return false;
+ return lhsp < rhsp;
+ }
+ };
+
+public:
+ /*virtual*/ S8 getType() const ;
+ /*virtual*/ void forceImmediateUpdate() ;
+ /*virtual*/ void dump() ;
+
+ // Set callbacks to get called when the image gets updated with higher
+ // resolution versions.
+ void setLoadedCallback(loaded_callback_func cb,
+ S32 discard_level, BOOL keep_imageraw, BOOL needs_aux,
+ void* userdata);
+ bool hasCallbacks() { return mLoadedCallbackList.empty() ? false : true; }
+ bool doLoadedCallbacks();
+
+ // ONLY call from LLViewerTextureList
+ BOOL createTexture(S32 usename = 0);
+ void destroyTexture() ;
+
+ virtual void processTextureStats() ;
+ F32 calcDecodePriority() ;
+
+ BOOL needsAux() const { return mNeedsAux; }
+
+ // Host we think might have this image, used for baked av textures.
+ void setTargetHost(LLHost host) { mTargetHost = host; }
+ LLHost getTargetHost() const { return mTargetHost; }
+
+ // Set the decode priority for this image...
+ // DON'T CALL THIS UNLESS YOU KNOW WHAT YOU'RE DOING, it can mess up
+ // the priority list, and cause horrible things to happen.
+ void setDecodePriority(F32 priority = -1.0f);
+ F32 getDecodePriority() const { return mDecodePriority; };
+
+ // setDesiredDiscardLevel is only used by LLViewerTextureList
+ void setDesiredDiscardLevel(S32 discard) { mDesiredDiscardLevel = discard; }
+ S32 getDesiredDiscardLevel() { return mDesiredDiscardLevel; }
+ void setMinDiscardLevel(S32 discard) { mMinDesiredDiscardLevel = llmin(mMinDesiredDiscardLevel,(S8)discard); }
+
+ bool updateFetch();
+
+ // Override the computation of discard levels if we know the exact output
+ // size of the image. Used for UI textures to not decode, even if we have
+ // more data.
+ void setKnownDrawSize(S32 width, S32 height);
+
+ void setIsMissingAsset();
+ /*virtual*/ BOOL isMissingAsset() const { return mIsMissingAsset; }
+
+ // returns dimensions of original image for local files (before power of two scaling)
+ // and returns 0 for all asset system images
+ S32 getOriginalWidth() { return mOrigWidth; }
+ S32 getOriginalHeight() { return mOrigHeight; }
+
+ BOOL isInImageList() const {return mInImageList ;}
+ void setInImageList(BOOL flag) {mInImageList = flag ;}
+
+ const std::string& getLocalFileName() const {return mLocalFileName ;}
+ LLFrameTimer* getLastPacketTimer() {return &mLastPacketTimer;}
+
+ U32 getFetchPriority() const { return mFetchPriority ;}
+ F32 getDownloadProgress() const {return mDownloadProgress ;}
+
+ LLImageRaw* readBackRawImage(S8 discard_level) ;
+ void destroyRawImage();
+
+ //---------------
+ BOOL isDeleted() ;
+ BOOL isInactive() ;
+ BOOL isDeletionCandidate();
+ void setDeletionCandidate() ;
+ void setInactive() ;
+ BOOL getUseDiscard() const { return mUseMipMaps && !mDontDiscard; }
+ //---------------
+
+ void setForSculpt();
+ BOOL isForSculpt() const {return mForSculpt;}
+
+private:
+ void init(bool firstinit) ;
+ void cleanup() ;
+
+ F32 calcDecodePriorityForUnknownTexture(F32 pixel_priority) ;
+
+private:
+ BOOL mFullyLoaded;
+
+protected:
+ S32 mOrigWidth;
+ S32 mOrigHeight;
+
+ // Override the computation of discard levels if we know the exact output size of the image.
+ // Used for UI textures to not decode, even if we have more data.
+ S32 mKnownDrawWidth;
+ S32 mKnownDrawHeight;
+
+ std::string mLocalFileName;
+
+ S8 mDesiredDiscardLevel; // The discard level we'd LIKE to have - if we have it and there's space
+ S8 mMinDesiredDiscardLevel; // The minimum discard level we'd like to have
+ S32 mMinDiscardLevel;
+
+ S32 mRequestedDiscardLevel;
+ F32 mRequestedDownloadPriority;
+ S32 mFetchState;
+ U32 mFetchPriority;
+ F32 mDownloadProgress;
+ F32 mFetchDeltaTime;
+ F32 mRequestDeltaTime;
+ S32 mDecodeFrame;
+ S32 mVisibleFrame; // decode frame where image was last visible
+
+ S8 mNeedsAux; // We need to decode the auxiliary channels
+ S8 mDecodingAux; // Are we decoding high components
+ S8 mIsRawImageValid;
+ S8 mHasFetcher; // We've made a fecth request
+ S8 mIsFetching; // Fetch request is active
+
+ mutable S8 mIsMissingAsset; // True if we know that there is no image asset with this image id in the database.
+
+ F32 mDecodePriority; // The priority for decoding this image.
+ typedef std::list<LLLoadedCallbackEntry*> callback_list_t;
+ callback_list_t mLoadedCallbackList;
+
+ LLPointer<LLImageRaw> mRawImage;
+ S32 mRawDiscardLevel;
+
+ // Used ONLY for cloth meshes right now. Make SURE you know what you're
+ // doing if you use it for anything else! - djs
+ LLPointer<LLImageRaw> mAuxRawImage;
+
+ LLHost mTargetHost; // if LLHost::invalid, just request from agent's simulator
+
+ // Timers
+ LLFrameTimer mLastPacketTimer; // Time since last packet.
+
+ BOOL mInImageList; // TRUE if image is in list (in which case don't reset priority!)
+ BOOL mNeedsCreateTexture;
+
+ BOOL mForSculpt ; //a flag if the texture is used as sculpt data.
+ BOOL mIsFetched ; //is loaded from remote or from cache, not generated locally.
+
+public:
+ static LLPointer<LLViewerFetchedTexture> sMissingAssetImagep; // Texture to show for an image asset that is not in the database
+ static LLPointer<LLViewerFetchedTexture> sWhiteImagep; // Texture to show NOTHING (whiteness)
+ static LLPointer<LLViewerFetchedTexture> sDefaultImagep; // "Default" texture for error cases, the only case of fetched texture which is generated in local.
+ static LLPointer<LLViewerFetchedTexture> sSmokeImagep; // Old "Default" translucent texture
+};
+
+//
+//the image data is fetched from remote or from local cache
+//the resolution of the texture is adjustable: depends on the view-dependent parameters.
+//
+class LLViewerLODTexture : public LLViewerFetchedTexture
+{
+protected:
+ /*virtual*/ ~LLViewerLODTexture(){}
+
+public:
+ LLViewerLODTexture(const LLUUID& id, BOOL usemipmaps = TRUE);
+ LLViewerLODTexture(const std::string& full_path, const LLUUID& id, BOOL usemipmaps = TRUE);
+
+ /*virtual*/ S8 getType() const;
+ // Process image stats to determine priority/quality requirements.
+ /*virtual*/ void processTextureStats();
+
+private:
+ void init(bool firstinit) ;
+
+private:
+
+ F32 mTexelsPerImage; // Texels per image.
+ F32 mDiscardVirtualSize; // Virtual size used to calculate desired discard
+ F32 mCalculatedDiscardLevel; // Last calculated discard level
+};
+
+//
+//the image data is fetched from the media pipeline periodically
+//the resolution of the texture is also adjusted by the media pipeline
+//
+class LLViewerMediaTexture : public LLViewerTexture
+{
+protected:
+ /*virtual*/ ~LLViewerMediaTexture() {}
+
+public:
+ LLViewerMediaTexture(const LLUUID& id, BOOL usemipmaps = TRUE, LLImageGL* gl_image = NULL) ;
+
+ /*virtual*/ S8 getType() const;
+
+ void reinit(BOOL usemipmaps = TRUE);
+
+ BOOL getUseMipMaps() {return mUseMipMaps ; }
+ void setUseMipMaps(BOOL mipmap) ;
+
+ void setOldTexture(LLViewerTexture* tex) ;
+ LLViewerTexture* getOldTexture() const ;
+
+ void setPlaying(BOOL playing) {mIsPlaying = playing ;}
+ BOOL isPlaying() const {return mIsPlaying;}
+
+private:
+ LLPointer<LLViewerTexture> mOldTexturep ; //the texture this media texture replaces.
+ BOOL mIsPlaying ;
+
+public:
+ static void updateClass() ;
+
+public:
+ typedef std::map< LLUUID, LLPointer<LLViewerMediaTexture> > media_map_t ;
+ static media_map_t sMediaMap ;
+};
+
+//just an interface class, do not create instance from this class.
+class LLViewerTextureManager
+{
+private:
+ //make the constructor private to preclude creating instances from this class.
+ LLViewerTextureManager(){}
+
+public:
+ //texture pipeline tester
+ static LLTexturePipelineTester* sTesterp ;
+
+ //returns NULL if tex is not a LLViewerFetchedTexture nor derived from LLViewerFetchedTexture.
+ static LLViewerFetchedTexture* staticCastToFetchedTexture(LLViewerTexture* tex, BOOL report_error = FALSE) ;
+
+ //
+ //"find-texture" just check if the texture exists, if yes, return it, otherwise return null.
+ //
+ static LLViewerTexture* findTexture(const LLUUID& id) ;
+ static LLViewerMediaTexture* findMediaTexture(const LLUUID& id) ;
+
+ static LLViewerMediaTexture* createMediaTexture(const LLUUID& id, BOOL usemipmaps = TRUE, LLImageGL* gl_image = NULL) ;
+
+ //
+ //"get-texture" will create a new texture if the texture does not exist.
+ //
+ static LLViewerMediaTexture* getMediaTexture(const LLUUID& id, BOOL usemipmaps = TRUE, LLImageGL* gl_image = NULL) ;
+
+ static LLPointer<LLViewerTexture> getLocalTexture(BOOL usemipmaps = TRUE, BOOL generate_gl_tex = TRUE);
+ static LLPointer<LLViewerTexture> getLocalTexture(const LLUUID& id, BOOL usemipmaps, BOOL generate_gl_tex = TRUE) ;
+ static LLPointer<LLViewerTexture> getLocalTexture(const LLImageRaw* raw, BOOL usemipmaps) ;
+ static LLPointer<LLViewerTexture> getLocalTexture(const U32 width, const U32 height, const U8 components, BOOL usemipmaps, BOOL generate_gl_tex = TRUE) ;
+
+ static LLViewerFetchedTexture* getFetchedTexture(const LLUUID &image_id,
+ BOOL usemipmap = TRUE,
+ BOOL level_immediate = FALSE, // Get the requested level immediately upon creation.
+ S8 texture_type = LLViewerTexture::FETCHED_TEXTURE,
+ LLGLint internal_format = 0,
+ LLGLenum primary_format = 0,
+ LLHost request_from_host = LLHost()
+ );
+
+ static LLViewerFetchedTexture* getFetchedTextureFromFile(const std::string& filename,
+ BOOL usemipmap = TRUE,
+ BOOL level_immediate = FALSE, // Get the requested level immediately upon creation.
+ S8 texture_type = LLViewerTexture::FETCHED_TEXTURE,
+ LLGLint internal_format = 0,
+ LLGLenum primary_format = 0,
+ const LLUUID& force_id = LLUUID::null
+ );
+
+ static LLViewerFetchedTexture* getFetchedTextureFromHost(const LLUUID& image_id, LLHost host) ;
+
+ static void init() ;
+ static void cleanup() ;
+};
+//
+//this class is used for test/debug only
+//it tracks the activities of the texture pipeline
+//records them, and outputs them to log files
+//
+class LLTexturePipelineTester : public LLMetricPerformanceTester
+{
+ enum
+ {
+ MIN_LARGE_IMAGE_AREA = 262144 //512 * 512
+ };
+public:
+ LLTexturePipelineTester() ;
+ ~LLTexturePipelineTester() ;
+
+ void update();
+ void updateTextureBindingStats(const LLViewerTexture* imagep) ;
+ void updateTextureLoadingStats(const LLViewerFetchedTexture* imagep, const LLImageRaw* raw_imagep, BOOL from_cache) ;
+ void updateGrayTextureBinding() ;
+ void setStablizingTime() ;
+
+ /*virtual*/ void analyzePerformance(std::ofstream* os, LLSD* base, LLSD* current) ;
+
+private:
+ void reset() ;
+ void updateStablizingTime() ;
+
+ /*virtual*/ void outputTestRecord(LLSD* sd) ;
+
+private:
+ BOOL mPause ;
+private:
+ BOOL mUsingDefaultTexture; //if set, some textures are still gray.
+
+ U32 mTotalBytesUsed ; //total bytes of textures bound/used for the current frame.
+ U32 mTotalBytesUsedForLargeImage ; //total bytes of textures bound/used for the current frame for images larger than 256 * 256.
+ U32 mLastTotalBytesUsed ; //total bytes of textures bound/used for the previous frame.
+ U32 mLastTotalBytesUsedForLargeImage ; //total bytes of textures bound/used for the previous frame for images larger than 256 * 256.
+
+ //
+ //data size
+ //
+ U32 mTotalBytesLoaded ; //total bytes fetched by texture pipeline
+ U32 mTotalBytesLoadedFromCache ; //total bytes fetched by texture pipeline from local cache
+ U32 mTotalBytesLoadedForLargeImage ; //total bytes fetched by texture pipeline for images larger than 256 * 256.
+ U32 mTotalBytesLoadedForSculpties ; //total bytes fetched by texture pipeline for sculpties
+
+ //
+ //time
+ //NOTE: the error tolerances of the following timers is one frame time.
+ //
+ F32 mStartFetchingTime ;
+ F32 mTotalGrayTime ; //total loading time when no gray textures.
+ F32 mTotalStablizingTime ; //total stablizing time when texture memory overflows
+ F32 mStartTimeLoadingSculpties ; //the start moment of loading sculpty images.
+ F32 mEndTimeLoadingSculpties ; //the end moment of loading sculpty images.
+ F32 mStartStablizingTime ;
+ F32 mEndStablizingTime ;
+
+private:
+ //
+ //The following members are used for performance analyzing
+ //
+ class LLTextureTestSession : public LLTestSession
+ {
+ public:
+ LLTextureTestSession() ;
+ /*virtual*/ ~LLTextureTestSession() ;
+
+ void reset() ;
+
+ F32 mTotalFetchingTime ;
+ F32 mTotalGrayTime ;
+ F32 mTotalStablizingTime ;
+ F32 mStartTimeLoadingSculpties ;
+ F32 mTotalTimeLoadingSculpties ;
+
+ S32 mTotalBytesLoaded ;
+ S32 mTotalBytesLoadedFromCache ;
+ S32 mTotalBytesLoadedForLargeImage ;
+ S32 mTotalBytesLoadedForSculpties ;
+
+ typedef struct _texture_instant_preformance_t
+ {
+ S32 mAverageBytesUsedPerSecond ;
+ S32 mAverageBytesUsedForLargeImagePerSecond ;
+ F32 mAveragePercentageBytesUsedPerSecond ;
+ F32 mTime ;
+ }texture_instant_preformance_t ;
+ std::vector<texture_instant_preformance_t> mInstantPerformanceList ;
+ S32 mInstantPerformanceListCounter ;
+ };
+
+ /*virtual*/ LLMetricPerformanceTester::LLTestSession* loadTestSession(LLSD* log) ;
+ /*virtual*/ void compareTestSessions(std::ofstream* os) ;
+};
+
+#endif
diff --git a/indra/newview/llviewertexturelist.cpp b/indra/newview/llviewertexturelist.cpp
new file mode 100644
index 0000000000..dac2331ca3
--- /dev/null
+++ b/indra/newview/llviewertexturelist.cpp
@@ -0,0 +1,1513 @@
+/**
+ * @file llviewertexturelist.cpp
+ * @brief Object for managing the list of images within a region
+ *
+ * $LicenseInfo:firstyear=2000&license=viewergpl$
+ *
+ * Copyright (c) 2000-2009, Linden Research, Inc.
+ *
+ * Second Life Viewer Source Code
+ * The source code in this file ("Source Code") is provided by Linden Lab
+ * to you under the terms of the GNU General Public License, version 2.0
+ * ("GPL"), unless you have obtained a separate licensing agreement
+ * ("Other License"), formally executed by you and Linden Lab. Terms of
+ * the GPL can be found in doc/GPL-license.txt in this distribution, or
+ * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
+ *
+ * There are special exceptions to the terms and conditions of the GPL as
+ * it is applied to this Source Code. View the full text of the exception
+ * in the file doc/FLOSS-exception.txt in this software distribution, or
+ * online at
+ * http://secondlifegrid.net/programs/open_source/licensing/flossexception
+ *
+ * By copying, modifying or distributing this software, you acknowledge
+ * that you have read and understood your obligations described above,
+ * and agree to abide by those obligations.
+ *
+ * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+ * COMPLETENESS OR PERFORMANCE.
+ * $/LicenseInfo$
+ */
+
+#include "llviewerprecompiledheaders.h"
+
+#include <sys/stat.h>
+
+#include "llviewertexturelist.h"
+
+#include "imageids.h"
+#include "llgl.h" // fot gathering stats from GL
+#include "llimagegl.h"
+#include "llimagebmp.h"
+#include "llimagej2c.h"
+#include "llimagetga.h"
+#include "llimagejpeg.h"
+#include "llimagepng.h"
+
+#include "llsdserialize.h"
+#include "llsys.h"
+#include "llvfs.h"
+#include "llvfile.h"
+#include "llvfsthread.h"
+#include "llxmltree.h"
+#include "message.h"
+
+#include "lltexturecache.h"
+#include "lltexturefetch.h"
+#include "llviewercontrol.h"
+#include "llviewertexture.h"
+#include "llviewermedia.h"
+#include "llviewerregion.h"
+#include "llviewerstats.h"
+#include "pipeline.h"
+#include "llappviewer.h"
+#include "llxuiparser.h"
+
+////////////////////////////////////////////////////////////////////////////
+
+void (*LLViewerTextureList::sUUIDCallback)(void **, const LLUUID&) = NULL;
+
+const S32 IMAGES_PER_REQUEST = 42;
+const S32 IMAGES_MIN_UPDATES = 4; // Always update the highest N images each frame
+const S32 IMAGES_MAX_PACKET_UPDATES = 1; // Only send N packets of IMAGES_PER_REQUEST in a frame
+const F32 RESEND_IMAGE_REQUEST_TIME = 15.f; // seconds
+
+LLViewerTextureList gTextureList;
+static LLFastTimer::DeclareTimer FTM_PROCESS_IMAGES("Process Images");
+
+///////////////////////////////////////////////////////////////////////////////
+
+LLViewerTextureList::LLViewerTextureList()
+ : mForceResetTextureStats(FALSE),
+ mUpdateStats(FALSE),
+ mMaxResidentTexMemInMegaBytes(0),
+ mMaxTotalTextureMemInMegaBytes(0)
+{
+}
+
+void LLViewerTextureList::init()
+{
+ mNumImages = 0;
+ mMaxResidentTexMemInMegaBytes = 0;
+ mMaxTotalTextureMemInMegaBytes = 0 ;
+ if (gNoRender)
+ {
+ // Don't initialize GL stuff if we're not rendering.
+ return;
+ }
+
+ mUpdateStats = TRUE;
+
+ // Update how much texture RAM we're allowed to use.
+ updateMaxResidentTexMem(0); // 0 = use current
+
+ doPreloadImages();
+}
+
+
+void LLViewerTextureList::doPreloadImages()
+{
+ LL_DEBUGS("ViewerImages") << "Preloading images..." << LL_ENDL;
+
+ // Set the "missing asset" image
+ LLViewerFetchedTexture::sMissingAssetImagep = LLViewerTextureManager::getFetchedTextureFromFile("missing_asset.tga", MIPMAP_NO, IMMEDIATE_YES);
+
+ // Set the "white" image
+ LLViewerFetchedTexture::sWhiteImagep = LLViewerTextureManager::getFetchedTextureFromFile("white.tga", MIPMAP_NO, IMMEDIATE_YES);
+
+ LLUIImageList* image_list = LLUIImageList::getInstance();
+
+ image_list->initFromFile();
+
+ // turn off clamping and bilinear filtering for uv picking images
+ //LLViewerFetchedTexture* uv_test = preloadUIImage("uv_test1.tga", LLUUID::null, FALSE);
+ //uv_test->setClamp(FALSE, FALSE);
+ //uv_test->setMipFilterNearest(TRUE, TRUE);
+ //uv_test = preloadUIImage("uv_test2.tga", LLUUID::null, FALSE);
+ //uv_test->setClamp(FALSE, FALSE);
+ //uv_test->setMipFilterNearest(TRUE, TRUE);
+
+ // prefetch specific UUIDs
+ LLViewerTextureManager::getFetchedTexture(IMG_SHOT, TRUE);
+ LLViewerTextureManager::getFetchedTexture(IMG_SMOKE_POOF, TRUE);
+ LLViewerFetchedTexture* image = LLViewerTextureManager::getFetchedTextureFromFile("silhouette.j2c", MIPMAP_YES, IMMEDIATE_YES);
+ if (image)
+ {
+ image->setAddressMode(LLTexUnit::TAM_WRAP);
+ mImagePreloads.insert(image);
+ }
+ image = LLViewerTextureManager::getFetchedTextureFromFile("world/NoEntryLines.png", MIPMAP_YES, IMMEDIATE_YES);
+ if (image)
+ {
+ image->setAddressMode(LLTexUnit::TAM_WRAP);
+ mImagePreloads.insert(image);
+ }
+ image = LLViewerTextureManager::getFetchedTextureFromFile("world/NoEntryPassLines.png", MIPMAP_YES, IMMEDIATE_YES);
+ if (image)
+ {
+ image->setAddressMode(LLTexUnit::TAM_WRAP);
+ mImagePreloads.insert(image);
+ }
+ image = LLViewerTextureManager::getFetchedTexture(DEFAULT_WATER_NORMAL, MIPMAP_YES, IMMEDIATE_YES);
+ if (image)
+ {
+ image->setAddressMode(LLTexUnit::TAM_WRAP);
+ mImagePreloads.insert(image);
+ }
+ image = LLViewerTextureManager::getFetchedTextureFromFile("transparent.j2c", MIPMAP_YES, IMMEDIATE_YES, LLViewerTexture::FETCHED_TEXTURE,
+ 0,0,LLUUID("8dcd4a48-2d37-4909-9f78-f7a9eb4ef903"));
+ if (image)
+ {
+ image->setAddressMode(LLTexUnit::TAM_WRAP);
+ mImagePreloads.insert(image);
+ }
+
+}
+
+static std::string get_texture_list_name()
+{
+ return std::string("texture_list_") + gSavedSettings.getString("LoginLocation") + ".xml";
+}
+
+void LLViewerTextureList::doPrefetchImages()
+{
+ if (LLAppViewer::instance()->getPurgeCache())
+ {
+ // cache was purged, no point
+ return;
+ }
+
+ // Pre-fetch textures from last logout
+ LLSD imagelist;
+ std::string filename = gDirUtilp->getExpandedFilename(LL_PATH_PER_SL_ACCOUNT, get_texture_list_name());
+ llifstream file;
+ file.open(filename);
+ if (file.is_open())
+ {
+ LLSDSerialize::fromXML(imagelist, file);
+ }
+ for (LLSD::array_iterator iter = imagelist.beginArray();
+ iter != imagelist.endArray(); ++iter)
+ {
+ LLSD imagesd = *iter;
+ LLUUID uuid = imagesd["uuid"];
+ S32 pixel_area = imagesd["area"];
+ S32 texture_type = imagesd["type"];
+
+ if(LLViewerTexture::FETCHED_TEXTURE == texture_type || LLViewerTexture::LOD_TEXTURE == texture_type)
+ {
+ LLViewerFetchedTexture* image = LLViewerTextureManager::getFetchedTexture(uuid, MIPMAP_TRUE, FALSE, texture_type);
+ if (image)
+ {
+ image->addTextureStats((F32)pixel_area);
+ }
+ }
+ }
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+LLViewerTextureList::~LLViewerTextureList()
+{
+}
+
+void LLViewerTextureList::shutdown()
+{
+ // clear out preloads
+ mImagePreloads.clear();
+
+ // Write out list of currently loaded textures for precaching on startup
+ typedef std::set<std::pair<S32,LLViewerFetchedTexture*> > image_area_list_t;
+ image_area_list_t image_area_list;
+ for (image_priority_list_t::iterator iter = mImageList.begin();
+ iter != mImageList.end(); ++iter)
+ {
+ LLViewerFetchedTexture* image = *iter;
+ if (!image->hasGLTexture() ||
+ !image->getUseDiscard() ||
+ image->needsAux() ||
+ image->getTargetHost() != LLHost::invalid)
+ {
+ continue; // avoid UI, baked, and other special images
+ }
+ S32 desired = image->getDesiredDiscardLevel();
+ if (desired >= 0 && desired < MAX_DISCARD_LEVEL)
+ {
+ S32 pixel_area = image->getWidth(desired) * image->getHeight(desired);
+ image_area_list.insert(std::make_pair(pixel_area, image));
+ }
+ }
+
+ LLSD imagelist;
+ const S32 max_count = 1000;
+ S32 count = 0;
+ S32 image_type ;
+ for (image_area_list_t::reverse_iterator riter = image_area_list.rbegin();
+ riter != image_area_list.rend(); ++riter)
+ {
+ LLViewerFetchedTexture* image = riter->second;
+ image_type = (S32)image->getType() ;
+ imagelist[count]["area"] = riter->first;
+ imagelist[count]["uuid"] = image->getID();
+ imagelist[count]["type"] = image_type;
+ if (++count >= max_count)
+ break;
+ }
+
+ if (count > 0 && !gDirUtilp->getExpandedFilename(LL_PATH_PER_SL_ACCOUNT, "").empty())
+ {
+ std::string filename = gDirUtilp->getExpandedFilename(LL_PATH_PER_SL_ACCOUNT, get_texture_list_name());
+ llofstream file;
+ file.open(filename);
+ LLSDSerialize::toPrettyXML(imagelist, file);
+ }
+
+ //
+ // Clean up "loaded" callbacks.
+ //
+ mCallbackList.clear();
+
+ // Flush all of the references
+ mLoadingStreamList.clear();
+ mCreateTextureList.clear();
+
+ mUUIDMap.clear();
+
+ mImageList.clear();
+}
+
+void LLViewerTextureList::dump()
+{
+ llinfos << "LLViewerTextureList::dump()" << llendl;
+ for (image_priority_list_t::iterator it = mImageList.begin(); it != mImageList.end(); ++it)
+ {
+ LLViewerFetchedTexture* image = *it;
+
+ llinfos << "priority " << image->getDecodePriority()
+ << " boost " << image->getBoostLevel()
+ << " size " << image->getWidth() << "x" << image->getHeight()
+ << " discard " << image->getDiscardLevel()
+ << " desired " << image->getDesiredDiscardLevel()
+ << " http://asset.siva.lindenlab.com/" << image->getID() << ".texture"
+ << llendl;
+ }
+}
+
+void LLViewerTextureList::destroyGL(BOOL save_state)
+{
+ LLImageGL::destroyGL(save_state);
+}
+
+void LLViewerTextureList::restoreGL()
+{
+ LLImageGL::restoreGL();
+}
+
+/* Vertical tab container button image IDs
+ Seem to not decode when running app in debug.
+
+ const LLUUID BAD_IMG_ONE("1097dcb3-aef9-8152-f471-431d840ea89e");
+ const LLUUID BAD_IMG_TWO("bea77041-5835-1661-f298-47e2d32b7a70");
+ */
+
+///////////////////////////////////////////////////////////////////////////////
+
+LLViewerFetchedTexture* LLViewerTextureList::getImageFromFile(const std::string& filename,
+ BOOL usemipmaps,
+ BOOL level_immediate,
+ S8 texture_type,
+ LLGLint internal_format,
+ LLGLenum primary_format,
+ const LLUUID& force_id)
+{
+ if (gNoRender)
+ {
+ // Never mind that this ignores image_set_id;
+ // getImage() will handle that later.
+ return LLViewerTextureManager::getFetchedTexture(IMG_DEFAULT, TRUE, TRUE);
+ }
+
+ std::string full_path = gDirUtilp->findSkinnedFilename("textures", filename);
+ if (full_path.empty())
+ {
+ llwarns << "Failed to find local image file: " << filename << llendl;
+ return LLViewerTextureManager::getFetchedTexture(IMG_DEFAULT, TRUE, TRUE);
+ }
+
+ // generate UUID based on hash of filename
+ LLUUID new_id;
+ if (force_id.notNull())
+ {
+ new_id = force_id;
+ }
+ else
+ {
+ new_id.generate(full_path);
+ }
+
+ LLPointer<LLViewerFetchedTexture> imagep = findImage(new_id);
+
+ if (imagep.isNull())
+ {
+ switch(texture_type)
+ {
+ case LLViewerTexture::FETCHED_TEXTURE:
+ imagep = new LLViewerFetchedTexture(full_path, new_id, usemipmaps);
+ break ;
+ case LLViewerTexture::LOD_TEXTURE:
+ imagep = new LLViewerLODTexture(full_path, new_id, usemipmaps);
+ break ;
+ default:
+ llerrs << "Invalid texture type " << texture_type << llendl ;
+ }
+
+ if (internal_format && primary_format)
+ {
+ imagep->setExplicitFormat(internal_format, primary_format);
+ }
+
+ addImage(imagep);
+
+ if (level_immediate)
+ {
+ imagep->dontDiscard();
+ imagep->setBoostLevel(LLViewerFetchedTexture::BOOST_UI);
+ }
+ }
+
+ imagep->setGLTextureCreated(true);
+
+ return imagep;
+}
+
+
+LLViewerFetchedTexture* LLViewerTextureList::getImage(const LLUUID &image_id,
+ BOOL usemipmaps,
+ BOOL level_immediate,
+ S8 texture_type,
+ LLGLint internal_format,
+ LLGLenum primary_format,
+ LLHost request_from_host)
+{
+ // Return the image with ID image_id
+ // If the image is not found, creates new image and
+ // enqueues a request for transmission
+
+ if ((&image_id == NULL) || image_id.isNull())
+ {
+ return (LLViewerTextureManager::getFetchedTexture(IMG_DEFAULT, TRUE, TRUE));
+ }
+
+ LLPointer<LLViewerFetchedTexture> imagep = findImage(image_id);
+
+ if (imagep.isNull())
+ {
+ imagep = createImage(image_id, usemipmaps, level_immediate, texture_type, internal_format, primary_format, request_from_host) ;
+ }
+
+ imagep->setGLTextureCreated(true);
+
+ return imagep;
+}
+
+//when this function is called, there is no such texture in the gTextureList with image_id.
+LLViewerFetchedTexture* LLViewerTextureList::createImage(const LLUUID &image_id,
+ BOOL usemipmaps,
+ BOOL level_immediate,
+ S8 texture_type,
+ LLGLint internal_format,
+ LLGLenum primary_format,
+ LLHost request_from_host)
+{
+ LLPointer<LLViewerFetchedTexture> imagep ;
+ switch(texture_type)
+ {
+ case LLViewerTexture::FETCHED_TEXTURE:
+ imagep = new LLViewerFetchedTexture(image_id, usemipmaps);
+ break ;
+ case LLViewerTexture::LOD_TEXTURE:
+ imagep = new LLViewerLODTexture(image_id, usemipmaps);
+ break ;
+ default:
+ llerrs << "Invalid texture type " << texture_type << llendl ;
+ }
+
+ // Might want to request from host other than where the agent is. JC
+ imagep->setTargetHost(request_from_host);
+
+ if (internal_format && primary_format)
+ {
+ imagep->setExplicitFormat(internal_format, primary_format);
+ }
+
+ addImage(imagep);
+
+ if (level_immediate)
+ {
+ imagep->dontDiscard();
+ imagep->setBoostLevel(LLViewerFetchedTexture::BOOST_UI);
+ }
+ else
+ {
+ //by default, the texure can not be removed from memory even if it is not used.
+ //here turn this off
+ //if this texture should be set to NO_DELETE, either pass level_immediate == TRUE here, or call setNoDelete() afterwards.
+ imagep->forceActive() ;
+ }
+
+ return imagep ;
+}
+
+LLViewerFetchedTexture *LLViewerTextureList::findImage(const LLUUID &image_id)
+{
+ uuid_map_t::iterator iter = mUUIDMap.find(image_id);
+ if(iter == mUUIDMap.end())
+ return NULL;
+ return iter->second;
+}
+
+void LLViewerTextureList::addImageToList(LLViewerFetchedTexture *image)
+{
+ llassert(image);
+ if (image->isInImageList())
+ {
+ llerrs << "LLViewerTextureList::addImageToList - Image already in list" << llendl;
+ }
+ llverify((mImageList.insert(image)).second == true);
+ image->setInImageList(TRUE) ;
+}
+
+void LLViewerTextureList::removeImageFromList(LLViewerFetchedTexture *image)
+{
+ llassert(image);
+ if (!image->isInImageList())
+ {
+ llinfos << "RefCount: " << image->getNumRefs() << llendl ;
+ uuid_map_t::iterator iter = mUUIDMap.find(image->getID());
+ if(iter == mUUIDMap.end() || iter->second != image)
+ {
+ llinfos << "Image is not in mUUIDMap!" << llendl ;
+ }
+ llerrs << "LLViewerTextureList::removeImageFromList - Image not in list" << llendl;
+ }
+ llverify(mImageList.erase(image) == 1);
+ image->setInImageList(FALSE) ;
+}
+
+void LLViewerTextureList::addImage(LLViewerFetchedTexture *new_image)
+{
+ if (!new_image)
+ {
+ llwarning("No image to add to image list", 0);
+ return;
+ }
+ LLUUID image_id = new_image->getID();
+
+ LLViewerFetchedTexture *image = findImage(image_id);
+ if (image)
+ {
+ llwarns << "Image with ID " << image_id << " already in list" << llendl;
+ }
+ mNumImages++;
+
+ addImageToList(new_image);
+ mUUIDMap[image_id] = new_image;
+}
+
+
+void LLViewerTextureList::deleteImage(LLViewerFetchedTexture *image)
+{
+ if( image)
+ {
+ if (image->hasCallbacks())
+ {
+ mCallbackList.erase(image);
+ }
+
+ llverify(mUUIDMap.erase(image->getID()) == 1);
+ mNumImages--;
+ removeImageFromList(image);
+ }
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+
+////////////////////////////////////////////////////////////////////////////
+
+void LLViewerTextureList::dirtyImage(LLViewerFetchedTexture *image)
+{
+ mDirtyTextureList.insert(image);
+}
+
+////////////////////////////////////////////////////////////////////////////
+static LLFastTimer::DeclareTimer FTM_IMAGE_MARK_DIRTY("Dirty Images");
+
+void LLViewerTextureList::updateImages(F32 max_time)
+{
+ LLViewerStats::getInstance()->mNumImagesStat.addValue(mNumImages);
+ LLViewerStats::getInstance()->mNumRawImagesStat.addValue(LLImageRaw::sRawImageCount);
+ LLViewerStats::getInstance()->mGLTexMemStat.addValue((F32)BYTES_TO_MEGA_BYTES(LLImageGL::sGlobalTextureMemoryInBytes));
+ LLViewerStats::getInstance()->mGLBoundMemStat.addValue((F32)BYTES_TO_MEGA_BYTES(LLImageGL::sBoundTextureMemoryInBytes));
+ LLViewerStats::getInstance()->mRawMemStat.addValue((F32)BYTES_TO_MEGA_BYTES(LLImageRaw::sGlobalRawMemory));
+ LLViewerStats::getInstance()->mFormattedMemStat.addValue((F32)BYTES_TO_MEGA_BYTES(LLImageFormatted::sGlobalFormattedMemory));
+
+ updateImagesDecodePriorities();
+ max_time -= updateImagesFetchTextures(max_time);
+ max_time = llmin(llmax(max_time, 0.001f*10.f*gFrameIntervalSeconds), 0.001f);
+ max_time -= updateImagesCreateTextures(max_time);
+ max_time = llmin(llmax(max_time, 0.001f*10.f*gFrameIntervalSeconds), 0.001f);
+ if (!mDirtyTextureList.empty())
+ {
+ LLFastTimer t(FTM_IMAGE_MARK_DIRTY);
+ gPipeline.dirtyPoolObjectTextures(mDirtyTextureList);
+ mDirtyTextureList.clear();
+ }
+ bool didone = false;
+ for (image_list_t::iterator iter = mCallbackList.begin();
+ iter != mCallbackList.end(); )
+ {
+ //trigger loaded callbacks on local textures immediately
+ LLViewerFetchedTexture* image = *iter++;
+ if (!image->getLocalFileName().empty())
+ {
+ // Do stuff to handle callbacks, update priorities, etc.
+ didone = image->doLoadedCallbacks();
+ }
+ else if (!didone)
+ {
+ // Do stuff to handle callbacks, update priorities, etc.
+ didone = image->doLoadedCallbacks();
+ }
+ }
+ if (!gNoRender && !gGLManager.mIsDisabled)
+ {
+ LLViewerMedia::updateMedia();
+ }
+ updateImagesUpdateStats();
+}
+
+void LLViewerTextureList::updateImagesDecodePriorities()
+{
+ // Update the decode priority for N images each frame
+ {
+ const size_t max_update_count = llmin((S32) (1024*gFrameIntervalSeconds) + 1, 32); //target 1024 textures per second
+ S32 update_counter = llmin(max_update_count, mUUIDMap.size()/10);
+ uuid_map_t::iterator iter = mUUIDMap.upper_bound(mLastUpdateUUID);
+ while(update_counter > 0 && !mUUIDMap.empty())
+ {
+ if (iter == mUUIDMap.end())
+ {
+ iter = mUUIDMap.begin();
+ }
+ mLastUpdateUUID = iter->first;
+ LLPointer<LLViewerFetchedTexture> imagep = iter->second;
+ ++iter; // safe to incrament now
+
+ //
+ // Flush formatted images using a lazy flush
+ //
+ const F32 LAZY_FLUSH_TIMEOUT = 30.f; // stop decoding
+ const F32 MAX_INACTIVE_TIME = 50.f; // actually delete
+ S32 min_refs = 3; // 1 for mImageList, 1 for mUUIDMap, 1 for local reference
+ if (imagep->hasCallbacks())
+ {
+ min_refs++; // Add an extra reference if we're on the loaded callback list
+ }
+ S32 num_refs = imagep->getNumRefs();
+ if (num_refs == min_refs)
+ {
+ if (imagep->getLastReferencedTimer()->getElapsedTimeF32() > LAZY_FLUSH_TIMEOUT)
+ {
+ // Remove the unused image from the image list
+ deleteImage(imagep);
+ imagep = NULL; // should destroy the image
+ }
+ continue;
+ }
+ else
+ {
+ if(imagep->isDeleted())
+ {
+ continue ;
+ }
+ else if(imagep->isDeletionCandidate())
+ {
+ imagep->destroyTexture() ;
+ continue ;
+ }
+ else if(imagep->isInactive())
+ {
+ if (imagep->getLastReferencedTimer()->getElapsedTimeF32() > MAX_INACTIVE_TIME)
+ {
+ imagep->setDeletionCandidate() ;
+ }
+ continue ;
+ }
+ else
+ {
+ imagep->getLastReferencedTimer()->reset();
+
+ //reset texture state.
+ imagep->setInactive() ;
+ }
+ }
+
+ imagep->processTextureStats();
+ F32 old_priority = imagep->getDecodePriority();
+ F32 old_priority_test = llmax(old_priority, 0.0f);
+ F32 decode_priority = imagep->calcDecodePriority();
+ F32 decode_priority_test = llmax(decode_priority, 0.0f);
+ // Ignore < 20% difference
+ if ((decode_priority_test < old_priority_test * .8f) ||
+ (decode_priority_test > old_priority_test * 1.25f))
+ {
+ removeImageFromList(imagep);
+ imagep->setDecodePriority(decode_priority);
+ addImageToList(imagep);
+ }
+ update_counter--;
+ }
+ }
+}
+
+/*
+ static U8 get_image_type(LLViewerFetchedTexture* imagep, LLHost target_host)
+ {
+ // Having a target host implies this is a baked image. I don't
+ // believe that boost level has been set at this point. JC
+ U8 type_from_host = (target_host.isOk()
+ ? LLImageBase::TYPE_AVATAR_BAKE
+ : LLImageBase::TYPE_NORMAL);
+ S32 boost_level = imagep->getBoostLevel();
+ U8 type_from_boost = ( (boost_level == LLViewerFetchedTexture::BOOST_AVATAR_BAKED
+ || boost_level == LLViewerFetchedTexture::BOOST_AVATAR_BAKED_SELF)
+ ? LLImageBase::TYPE_AVATAR_BAKE
+ : LLImageBase::TYPE_NORMAL);
+ if (type_from_host == LLImageBase::TYPE_NORMAL
+ && type_from_boost == LLImageBase::TYPE_AVATAR_BAKE)
+ {
+ llwarns << "TAT: get_image_type() type_from_host doesn't match type_from_boost"
+ << " host " << target_host
+ << " boost " << imagep->getBoostLevel()
+ << " imageid " << imagep->getID()
+ << llendl;
+ imagep->dump();
+ }
+ return type_from_host;
+ }
+ */
+static LLFastTimer::DeclareTimer FTM_IMAGE_CREATE("Create Images");
+
+F32 LLViewerTextureList::updateImagesCreateTextures(F32 max_time)
+{
+ if (gNoRender || gGLManager.mIsDisabled) return 0.0f;
+
+ //
+ // Create GL textures for all textures that need them (images which have been
+ // decoded, but haven't been pushed into GL).
+ //
+ LLFastTimer t(FTM_IMAGE_CREATE);
+
+ LLTimer create_timer;
+ image_list_t::iterator enditer = mCreateTextureList.begin();
+ for (image_list_t::iterator iter = mCreateTextureList.begin();
+ iter != mCreateTextureList.end();)
+ {
+ image_list_t::iterator curiter = iter++;
+ enditer = iter;
+ LLViewerFetchedTexture *imagep = *curiter;
+ imagep->createTexture();
+ if (create_timer.getElapsedTimeF32() > max_time)
+ {
+ break;
+ }
+ }
+ mCreateTextureList.erase(mCreateTextureList.begin(), enditer);
+ return create_timer.getElapsedTimeF32();
+}
+
+void LLViewerTextureList::forceImmediateUpdate(LLViewerFetchedTexture* imagep)
+{
+ if(!imagep)
+ {
+ return ;
+ }
+ if(imagep->isInImageList())
+ {
+ removeImageFromList(imagep);
+ }
+
+ imagep->processTextureStats();
+ F32 decode_priority = LLViewerFetchedTexture::maxDecodePriority() ;
+ imagep->setDecodePriority(decode_priority);
+ mImageList.insert(imagep);
+ imagep->setInImageList(TRUE) ;
+
+ return ;
+}
+
+F32 LLViewerTextureList::updateImagesFetchTextures(F32 max_time)
+{
+ LLTimer image_op_timer;
+
+ // Update the decode priority for N images each frame
+ // Make a list with 32 high priority entries + 256 cycled entries
+ const size_t max_priority_count = llmin((S32) (256*10.f*gFrameIntervalSeconds)+1, 32);
+ const size_t max_update_count = llmin((S32) (1024*10.f*gFrameIntervalSeconds)+1, 256);
+
+ // 32 high priority entries
+ std::set<LLViewerFetchedTexture*> entries;
+ size_t update_counter = llmin(max_priority_count, mImageList.size());
+ image_priority_list_t::iterator iter1 = mImageList.begin();
+ while(update_counter > 0)
+ {
+ // added extra granularity and verbosity for crash logging during 1.19.1 RC. -Brad
+ if(iter1 == mImageList.end())
+ {
+ llerrs << "DEV-12002: update_counter not calculated correctly!" << llendl;
+ return 0.f;
+ }
+
+ LLPointer<LLViewerFetchedTexture> const & ptr = *iter1;
+
+ LLViewerFetchedTexture * img = ptr.get();
+
+ // added extra granularity and verbosity for crash logging during 1.19.1 RC. -Brad
+ if(img == NULL)
+ {
+ llwarns << "DEV-12002: image is NULL!" << llendl;
+ }
+
+ entries.insert(img);
+
+ ++iter1;
+ update_counter--;
+ }
+
+ // 256 cycled entries
+ update_counter = llmin(max_update_count, mUUIDMap.size());
+ uuid_map_t::iterator iter2 = mUUIDMap.upper_bound(mLastFetchUUID);
+ while(update_counter > 0)
+ {
+ if (iter2 == mUUIDMap.end())
+ {
+ iter2 = mUUIDMap.begin();
+ }
+ mLastFetchUUID = iter2->first;
+ entries.insert(iter2->second);
+ ++iter2;
+ update_counter--;
+ }
+
+ S32 min_count = max_priority_count + max_update_count/4;
+ for (std::set<LLViewerFetchedTexture*>::iterator iter3 = entries.begin();
+ iter3 != entries.end(); )
+ {
+ LLPointer<LLViewerFetchedTexture> imagep = *iter3++;
+
+ imagep->updateFetch();
+ if (min_count <= 0 && image_op_timer.getElapsedTimeF32() > max_time)
+ {
+ break;
+ }
+ min_count--;
+ }
+ return image_op_timer.getElapsedTimeF32();
+}
+
+void LLViewerTextureList::updateImagesUpdateStats()
+{
+ if (mUpdateStats)
+ {
+ for (image_priority_list_t::iterator iter = mImageList.begin();
+ iter != mImageList.end(); )
+ {
+ LLViewerFetchedTexture* imagep = *iter++;
+ imagep->resetTextureStats(mForceResetTextureStats);
+ }
+ mUpdateStats = FALSE;
+ mForceResetTextureStats = FALSE;
+ }
+}
+
+void LLViewerTextureList::decodeAllImages(F32 max_time)
+{
+ LLTimer timer;
+ if(gNoRender) return;
+
+ // Update texture stats and priorities
+ std::vector<LLPointer<LLViewerFetchedTexture> > image_list;
+ for (image_priority_list_t::iterator iter = mImageList.begin();
+ iter != mImageList.end(); )
+ {
+ LLViewerFetchedTexture* imagep = *iter++;
+ image_list.push_back(imagep);
+ imagep->setInImageList(FALSE) ;
+ }
+ mImageList.clear();
+ for (std::vector<LLPointer<LLViewerFetchedTexture> >::iterator iter = image_list.begin();
+ iter != image_list.end(); ++iter)
+ {
+ LLViewerFetchedTexture* imagep = *iter;
+ imagep->processTextureStats();
+ F32 decode_priority = imagep->calcDecodePriority();
+ imagep->setDecodePriority(decode_priority);
+ mImageList.insert(imagep);
+ imagep->setInImageList(TRUE) ;
+ }
+ image_list.clear();
+
+ // Update fetch (decode)
+ for (image_priority_list_t::iterator iter = mImageList.begin();
+ iter != mImageList.end(); )
+ {
+ LLViewerFetchedTexture* imagep = *iter++;
+ imagep->updateFetch();
+ }
+ // Run threads
+ S32 fetch_pending = 0;
+ while (1)
+ {
+ LLAppViewer::instance()->getTextureCache()->update(1); // unpauses the texture cache thread
+ LLAppViewer::instance()->getImageDecodeThread()->update(1); // unpauses the image thread
+ fetch_pending = LLAppViewer::instance()->getTextureFetch()->update(1); // unpauses the texture fetch thread
+ if (fetch_pending == 0 || timer.getElapsedTimeF32() > max_time)
+ {
+ break;
+ }
+ }
+ // Update fetch again
+ for (image_priority_list_t::iterator iter = mImageList.begin();
+ iter != mImageList.end(); )
+ {
+ LLViewerFetchedTexture* imagep = *iter++;
+ imagep->updateFetch();
+ }
+ max_time -= timer.getElapsedTimeF32();
+ max_time = llmax(max_time, .001f);
+ F32 create_time = updateImagesCreateTextures(max_time);
+
+ LL_DEBUGS("ViewerImages") << "decodeAllImages() took " << timer.getElapsedTimeF32() << " seconds. "
+ << " fetch_pending " << fetch_pending
+ << " create_time " << create_time
+ << LL_ENDL;
+}
+
+
+BOOL LLViewerTextureList::createUploadFile(const std::string& filename,
+ const std::string& out_filename,
+ const U8 codec)
+{
+ // First, load the image.
+ LLPointer<LLImageRaw> raw_image = new LLImageRaw;
+
+ switch (codec)
+ {
+ case IMG_CODEC_BMP:
+ {
+ LLPointer<LLImageBMP> bmp_image = new LLImageBMP;
+
+ if (!bmp_image->load(filename))
+ {
+ return FALSE;
+ }
+
+ if (!bmp_image->decode(raw_image, 0.0f))
+ {
+ return FALSE;
+ }
+ }
+ break;
+ case IMG_CODEC_TGA:
+ {
+ LLPointer<LLImageTGA> tga_image = new LLImageTGA;
+
+ if (!tga_image->load(filename))
+ {
+ return FALSE;
+ }
+
+ if (!tga_image->decode(raw_image))
+ {
+ return FALSE;
+ }
+
+ if( (tga_image->getComponents() != 3) &&
+ (tga_image->getComponents() != 4) )
+ {
+ tga_image->setLastError( "Image files with less than 3 or more than 4 components are not supported." );
+ return FALSE;
+ }
+ }
+ break;
+ case IMG_CODEC_JPEG:
+ {
+ LLPointer<LLImageJPEG> jpeg_image = new LLImageJPEG;
+
+ if (!jpeg_image->load(filename))
+ {
+ return FALSE;
+ }
+
+ if (!jpeg_image->decode(raw_image, 0.0f))
+ {
+ return FALSE;
+ }
+ }
+ break;
+ case IMG_CODEC_PNG:
+ {
+ LLPointer<LLImagePNG> png_image = new LLImagePNG;
+
+ if (!png_image->load(filename))
+ {
+ return FALSE;
+ }
+
+ if (!png_image->decode(raw_image, 0.0f))
+ {
+ return FALSE;
+ }
+ }
+ break;
+ default:
+ return FALSE;
+ }
+
+ LLPointer<LLImageJ2C> compressedImage = convertToUploadFile(raw_image);
+
+ if( !compressedImage->save(out_filename) )
+ {
+ llinfos << "Couldn't create output file " << out_filename << llendl;
+ return FALSE;
+ }
+
+ // test to see if the encode and save worked.
+ LLPointer<LLImageJ2C> integrity_test = new LLImageJ2C;
+ if( !integrity_test->loadAndValidate( out_filename ) )
+ {
+ llinfos << "Image: " << out_filename << " is corrupt." << llendl;
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+// note: modifies the argument raw_image!!!!
+LLPointer<LLImageJ2C> LLViewerTextureList::convertToUploadFile(LLPointer<LLImageRaw> raw_image)
+{
+ raw_image->biasedScaleToPowerOfTwo(LLViewerFetchedTexture::MAX_IMAGE_SIZE_DEFAULT);
+ LLPointer<LLImageJ2C> compressedImage = new LLImageJ2C();
+ compressedImage->setRate(0.f);
+
+ if (gSavedSettings.getBOOL("LosslessJ2CUpload") &&
+ (raw_image->getWidth() * raw_image->getHeight() <= LL_IMAGE_REZ_LOSSLESS_CUTOFF * LL_IMAGE_REZ_LOSSLESS_CUTOFF))
+ compressedImage->setReversible(TRUE);
+
+ compressedImage->encode(raw_image, 0.0f);
+
+ return compressedImage;
+}
+
+// Returns min setting for TextureMemory (in MB)
+S32 LLViewerTextureList::getMinVideoRamSetting()
+{
+ S32 system_ram = (S32)BYTES_TO_MEGA_BYTES(gSysMemory.getPhysicalMemoryClamped());
+ //min texture mem sets to 64M if total physical mem is more than 1.5GB
+ return (system_ram > 1500) ? 64 : MIN_VIDEO_RAM_IN_MEGA_BYTES ;
+}
+
+//static
+// Returns max setting for TextureMemory (in MB)
+S32 LLViewerTextureList::getMaxVideoRamSetting(bool get_recommended)
+{
+ S32 max_texmem;
+ if (gGLManager.mVRAM != 0)
+ {
+ // Treat any card with < 32 MB (shudder) as having 32 MB
+ // - it's going to be swapping constantly regardless
+ S32 max_vram = gGLManager.mVRAM;
+ max_vram = llmax(max_vram, getMinVideoRamSetting());
+ max_texmem = max_vram;
+ if (!get_recommended)
+ max_texmem *= 2;
+ }
+ else
+ {
+ if (get_recommended)
+ max_texmem = 128;
+ else
+ max_texmem = 512;
+ llwarns << "VRAM amount not detected, defaulting to " << max_texmem << " MB" << llendl;
+ }
+
+ S32 system_ram = (S32)BYTES_TO_MEGA_BYTES(gSysMemory.getPhysicalMemoryClamped()); // In MB
+ //llinfos << "*** DETECTED " << system_ram << " MB of system memory." << llendl;
+ if (get_recommended)
+ max_texmem = llmin(max_texmem, (S32)(system_ram/2));
+ else
+ max_texmem = llmin(max_texmem, (S32)(system_ram));
+
+ max_texmem = llclamp(max_texmem, getMinVideoRamSetting(), MAX_VIDEO_RAM_IN_MEGA_BYTES);
+
+ return max_texmem;
+}
+
+const S32 VIDEO_CARD_FRAMEBUFFER_MEM = 12; // MB
+const S32 MIN_MEM_FOR_NON_TEXTURE = 512 ; //MB
+void LLViewerTextureList::updateMaxResidentTexMem(S32 mem)
+{
+ // Initialize the image pipeline VRAM settings
+ S32 cur_mem = gSavedSettings.getS32("TextureMemory");
+ F32 mem_multiplier = gSavedSettings.getF32("RenderTextureMemoryMultiple");
+ S32 default_mem = getMaxVideoRamSetting(true); // recommended default
+ if (mem == 0)
+ {
+ mem = cur_mem > 0 ? cur_mem : default_mem;
+ }
+ else if (mem < 0)
+ {
+ mem = default_mem;
+ }
+
+ // limit the texture memory to a multiple of the default if we've found some cards to behave poorly otherwise
+ mem = llmin(mem, (S32) (mem_multiplier * (F32) default_mem));
+
+ mem = llclamp(mem, getMinVideoRamSetting(), getMaxVideoRamSetting());
+ if (mem != cur_mem)
+ {
+ gSavedSettings.setS32("TextureMemory", mem);
+ return; //listener will re-enter this function
+ }
+
+ // TODO: set available resident texture mem based on use by other subsystems
+ // currently max(12MB, VRAM/4) assumed...
+
+ S32 vb_mem = mem;
+ S32 fb_mem = llmax(VIDEO_CARD_FRAMEBUFFER_MEM, vb_mem/4);
+ mMaxResidentTexMemInMegaBytes = (vb_mem - fb_mem) ; //in MB
+
+ mMaxTotalTextureMemInMegaBytes = mMaxResidentTexMemInMegaBytes * 2;
+ if (mMaxResidentTexMemInMegaBytes > 640)
+ {
+ mMaxTotalTextureMemInMegaBytes -= (mMaxResidentTexMemInMegaBytes >> 2);
+ }
+
+ //system mem
+ S32 system_ram = (S32)BYTES_TO_MEGA_BYTES(gSysMemory.getPhysicalMemoryClamped()); // In MB
+
+ //minimum memory reserved for non-texture use.
+ //if system_raw >= 1GB, reserve at least 512MB for non-texture use;
+ //otherwise reserve half of the system_ram for non-texture use.
+ S32 min_non_texture_mem = llmin(system_ram / 2, MIN_MEM_FOR_NON_TEXTURE) ;
+
+ if (mMaxTotalTextureMemInMegaBytes > system_ram - min_non_texture_mem)
+ {
+ mMaxTotalTextureMemInMegaBytes = system_ram - min_non_texture_mem ;
+ }
+
+ llinfos << "Total Video Memory set to: " << vb_mem << " MB" << llendl;
+ llinfos << "Available Texture Memory set to: " << (vb_mem - fb_mem) << " MB" << llendl;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+// static
+void LLViewerTextureList::receiveImageHeader(LLMessageSystem *msg, void **user_data)
+{
+ LLFastTimer t(FTM_PROCESS_IMAGES);
+
+ // Receive image header, copy into image object and decompresses
+ // if this is a one-packet image.
+
+ LLUUID id;
+
+ char ip_string[256];
+ u32_to_ip_string(msg->getSenderIP(),ip_string);
+
+ if (msg->getReceiveCompressedSize())
+ {
+ gTextureList.mTextureBits += msg->getReceiveCompressedSize() * 8;
+ }
+ else
+ {
+ gTextureList.mTextureBits += msg->getReceiveSize() * 8;
+ }
+ gTextureList.mTexturePackets++;
+
+ U8 codec;
+ U16 packets;
+ U32 totalbytes;
+ msg->getUUIDFast(_PREHASH_ImageID, _PREHASH_ID, id);
+ msg->getU8Fast(_PREHASH_ImageID, _PREHASH_Codec, codec);
+ msg->getU16Fast(_PREHASH_ImageID, _PREHASH_Packets, packets);
+ msg->getU32Fast(_PREHASH_ImageID, _PREHASH_Size, totalbytes);
+
+ S32 data_size = msg->getSizeFast(_PREHASH_ImageData, _PREHASH_Data);
+ if (!data_size)
+ {
+ return;
+ }
+ if (data_size < 0)
+ {
+ // msg->getSizeFast() is probably trying to tell us there
+ // was an error.
+ llerrs << "image header chunk size was negative: "
+ << data_size << llendl;
+ return;
+ }
+
+ // this buffer gets saved off in the packet list
+ U8 *data = new U8[data_size];
+ msg->getBinaryDataFast(_PREHASH_ImageData, _PREHASH_Data, data, data_size);
+
+ LLViewerFetchedTexture *image = LLViewerTextureManager::getFetchedTexture(id, TRUE, FALSE, LLViewerTexture::LOD_TEXTURE);
+ if (!image)
+ {
+ delete [] data;
+ return;
+ }
+ image->getLastPacketTimer()->reset();
+ bool res = LLAppViewer::getTextureFetch()->receiveImageHeader(msg->getSender(), id, codec, packets, totalbytes, data_size, data);
+ if (!res)
+ {
+ delete[] data;
+ }
+}
+
+// static
+void LLViewerTextureList::receiveImagePacket(LLMessageSystem *msg, void **user_data)
+{
+ LLMemType mt1(LLMemType::MTYPE_APPFMTIMAGE);
+ LLFastTimer t(FTM_PROCESS_IMAGES);
+
+ // Receives image packet, copy into image object,
+ // checks if all packets received, decompresses if so.
+
+ LLUUID id;
+ U16 packet_num;
+
+ char ip_string[256];
+ u32_to_ip_string(msg->getSenderIP(),ip_string);
+
+ if (msg->getReceiveCompressedSize())
+ {
+ gTextureList.mTextureBits += msg->getReceiveCompressedSize() * 8;
+ }
+ else
+ {
+ gTextureList.mTextureBits += msg->getReceiveSize() * 8;
+ }
+ gTextureList.mTexturePackets++;
+
+ //llprintline("Start decode, image header...");
+ msg->getUUIDFast(_PREHASH_ImageID, _PREHASH_ID, id);
+ msg->getU16Fast(_PREHASH_ImageID, _PREHASH_Packet, packet_num);
+ S32 data_size = msg->getSizeFast(_PREHASH_ImageData, _PREHASH_Data);
+
+ if (!data_size)
+ {
+ return;
+ }
+ if (data_size < 0)
+ {
+ // msg->getSizeFast() is probably trying to tell us there
+ // was an error.
+ llerrs << "image data chunk size was negative: "
+ << data_size << llendl;
+ return;
+ }
+ if (data_size > MTUBYTES)
+ {
+ llerrs << "image data chunk too large: " << data_size << " bytes" << llendl;
+ return;
+ }
+ U8 *data = new U8[data_size];
+ msg->getBinaryDataFast(_PREHASH_ImageData, _PREHASH_Data, data, data_size);
+
+ LLViewerFetchedTexture *image = LLViewerTextureManager::getFetchedTexture(id, TRUE, FALSE, LLViewerTexture::LOD_TEXTURE);
+ if (!image)
+ {
+ delete [] data;
+ return;
+ }
+ image->getLastPacketTimer()->reset();
+ bool res = LLAppViewer::getTextureFetch()->receiveImagePacket(msg->getSender(), id, packet_num, data_size, data);
+ if (!res)
+ {
+ delete[] data;
+ }
+}
+
+
+// We've been that the asset server does not contain the requested image id.
+// static
+void LLViewerTextureList::processImageNotInDatabase(LLMessageSystem *msg,void **user_data)
+{
+ LLFastTimer t(FTM_PROCESS_IMAGES);
+ LLUUID image_id;
+ msg->getUUIDFast(_PREHASH_ImageID, _PREHASH_ID, image_id);
+
+ LLViewerFetchedTexture* image = gTextureList.findImage( image_id );
+ if( image )
+ {
+ image->setIsMissingAsset();
+ }
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+//static
+const U32 SIXTEEN_MEG = 0x1000000;
+S32 LLViewerTextureList::calcMaxTextureRAM()
+{
+ // Decide the maximum amount of RAM we should allow the user to allocate to texture cache
+ LLMemoryInfo memory_info;
+ U32 available_memory = memory_info.getPhysicalMemoryClamped();
+
+ clamp_rescale((F32)available_memory,
+ (F32)(SIXTEEN_MEG * 16),
+ (F32)U32_MAX,
+ (F32)(SIXTEEN_MEG * 4),
+ (F32)(U32_MAX >> 1));
+ return available_memory;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+// explicitly cleanup resources, as this is a singleton class with process
+// lifetime so ability to perform std::map operations in destructor is not
+// guaranteed.
+void LLUIImageList::cleanUp()
+{
+ mUIImages.clear();
+ mUITextureList.clear() ;
+}
+
+LLUIImagePtr LLUIImageList::getUIImageByID(const LLUUID& image_id)
+{
+ // use id as image name
+ std::string image_name = image_id.asString();
+
+ // look for existing image
+ uuid_ui_image_map_t::iterator found_it = mUIImages.find(image_name);
+ if (found_it != mUIImages.end())
+ {
+ return found_it->second;
+ }
+
+ return loadUIImageByID(image_id);
+}
+
+LLUIImagePtr LLUIImageList::getUIImage(const std::string& image_name)
+{
+ // look for existing image
+ uuid_ui_image_map_t::iterator found_it = mUIImages.find(image_name);
+ if (found_it != mUIImages.end())
+ {
+ return found_it->second;
+ }
+
+ return loadUIImageByName(image_name, image_name);
+}
+
+LLUIImagePtr LLUIImageList::loadUIImageByName(const std::string& name, const std::string& filename, BOOL use_mips, const LLRect& scale_rect)
+{
+ LLViewerFetchedTexture* imagep = LLViewerTextureManager::getFetchedTextureFromFile(filename, MIPMAP_NO, IMMEDIATE_YES);
+ return loadUIImage(imagep, name, use_mips, scale_rect);
+}
+
+LLUIImagePtr LLUIImageList::loadUIImageByID(const LLUUID& id, BOOL use_mips, const LLRect& scale_rect)
+{
+ LLViewerFetchedTexture* imagep = LLViewerTextureManager::getFetchedTexture(id, MIPMAP_NO, IMMEDIATE_YES);
+ return loadUIImage(imagep, id.asString(), use_mips, scale_rect);
+}
+
+LLUIImagePtr LLUIImageList::loadUIImage(LLViewerFetchedTexture* imagep, const std::string& name, BOOL use_mips, const LLRect& scale_rect)
+{
+ if (!imagep) return NULL;
+
+ imagep->setAddressMode(LLTexUnit::TAM_CLAMP);
+
+ //all UI images are non-deletable
+ imagep->setNoDelete() ;
+
+ LLUIImagePtr new_imagep = new LLUIImage(name, imagep);
+ mUIImages.insert(std::make_pair(name, new_imagep));
+ mUITextureList.push_back(imagep) ;
+
+ LLUIImageLoadData* datap = new LLUIImageLoadData;
+ datap->mImageName = name;
+ datap->mImageScaleRegion = scale_rect;
+
+ imagep->setLoadedCallback(onUIImageLoaded, 0, FALSE, FALSE, datap);
+
+ return new_imagep;
+}
+
+LLUIImagePtr LLUIImageList::preloadUIImage(const std::string& name, const std::string& filename, BOOL use_mips, const LLRect& scale_rect)
+{
+ // look for existing image
+ uuid_ui_image_map_t::iterator found_it = mUIImages.find(name);
+ if (found_it != mUIImages.end())
+ {
+ // image already loaded!
+ llerrs << "UI Image " << name << " already loaded." << llendl;
+ }
+
+ return loadUIImageByName(name, filename, use_mips, scale_rect);
+}
+
+//static
+void LLUIImageList::onUIImageLoaded( BOOL success, LLViewerFetchedTexture *src_vi, LLImageRaw* src, LLImageRaw* src_aux, S32 discard_level, BOOL final, void* user_data )
+{
+ if(!success || !user_data)
+ {
+ return;
+ }
+
+ LLUIImageLoadData* image_datap = (LLUIImageLoadData*)user_data;
+ std::string ui_image_name = image_datap->mImageName;
+ LLRect scale_rect = image_datap->mImageScaleRegion;
+ if (final)
+ {
+ delete image_datap;
+ }
+
+ LLUIImageList* instance = getInstance();
+
+ uuid_ui_image_map_t::iterator found_it = instance->mUIImages.find(ui_image_name);
+ if (found_it != instance->mUIImages.end())
+ {
+ LLUIImagePtr imagep = found_it->second;
+
+ // for images grabbed from local files, apply clipping rectangle to restore original dimensions
+ // from power-of-2 gl image
+ if (success && imagep.notNull() && src_vi && !src_vi->getLocalFileName().empty())
+ {
+ F32 clip_x = (F32)src_vi->getOriginalWidth() / (F32)src_vi->getFullWidth();
+ F32 clip_y = (F32)src_vi->getOriginalHeight() / (F32)src_vi->getFullHeight();
+ imagep->setClipRegion(LLRectf(0.f, clip_y, clip_x, 0.f));
+ if (scale_rect != LLRect::null)
+ {
+ imagep->setScaleRegion(
+ LLRectf(llclamp((F32)scale_rect.mLeft / (F32)imagep->getWidth(), 0.f, 1.f),
+ llclamp((F32)scale_rect.mTop / (F32)imagep->getHeight(), 0.f, 1.f),
+ llclamp((F32)scale_rect.mRight / (F32)imagep->getWidth(), 0.f, 1.f),
+ llclamp((F32)scale_rect.mBottom / (F32)imagep->getHeight(), 0.f, 1.f)));
+ }
+ }
+ }
+}
+
+struct UIImageDeclaration : public LLInitParam::Block<UIImageDeclaration>
+{
+ Mandatory<std::string> name;
+ Optional<std::string> file_name;
+ Optional<bool> preload;
+ Optional<LLRect> scale_rect;
+ Optional<bool> use_mips;
+
+ UIImageDeclaration()
+ : name("name"),
+ file_name("file_name"),
+ preload("preload", false),
+ scale_rect("scale"),
+ use_mips("use_mips", false)
+ {}
+};
+
+struct UIImageDeclarations : public LLInitParam::Block<UIImageDeclarations>
+{
+ Mandatory<S32> version;
+ Multiple<UIImageDeclaration> textures;
+
+ UIImageDeclarations()
+ : version("version"),
+ textures("texture")
+ {}
+};
+
+bool LLUIImageList::initFromFile()
+{
+ // construct path to canonical textures.xml in default skin dir
+ std::string base_file_path = gDirUtilp->getExpandedFilename(LL_PATH_SKINS, "default", "textures", "textures.xml");
+
+ LLXMLNodePtr root;
+
+ if (!LLXMLNode::parseFile(base_file_path, root, NULL))
+ {
+ llwarns << "Unable to parse UI image list file " << base_file_path << llendl;
+ return false;
+ }
+
+ std::vector<std::string> paths;
+ // path to current selected skin
+ paths.push_back(gDirUtilp->getSkinDir()
+ + gDirUtilp->getDirDelimiter()
+ + "textures"
+ + gDirUtilp->getDirDelimiter()
+ + "textures.xml");
+ // path to user overrides on current skin
+ paths.push_back(gDirUtilp->getUserSkinDir()
+ + gDirUtilp->getDirDelimiter()
+ + "textures"
+ + gDirUtilp->getDirDelimiter()
+ + "textures.xml");
+
+ // apply skinned xml files incrementally
+ for(std::vector<std::string>::iterator path_it = paths.begin();
+ path_it != paths.end();
+ ++path_it)
+ {
+ // don't reapply base file to itself
+ if (!path_it->empty() && (*path_it) != base_file_path)
+ {
+ LLXMLNodePtr update_root;
+ if (LLXMLNode::parseFile(*path_it, update_root, NULL))
+ {
+ LLXMLNode::updateNode(root, update_root);
+ }
+ }
+ }
+
+ UIImageDeclarations images;
+ LLXUIParser::instance().readXUI(root, images);
+
+ if (!images.validateBlock()) return false;
+
+ enum e_decode_pass
+ {
+ PASS_DECODE_NOW,
+ PASS_DECODE_LATER,
+ NUM_PASSES
+ };
+
+ for (S32 cur_pass = PASS_DECODE_NOW; cur_pass < NUM_PASSES; cur_pass++)
+ {
+ for (LLInitParam::ParamIterator<UIImageDeclaration>::const_iterator image_it = images.textures().begin();
+ image_it != images.textures().end();
+ ++image_it)
+ {
+ std::string file_name = image_it->file_name.isProvided() ? image_it->file_name() : image_it->name();
+
+ // load high priority textures on first pass (to kick off decode)
+ enum e_decode_pass decode_pass = image_it->preload ? PASS_DECODE_NOW : PASS_DECODE_LATER;
+ if (decode_pass != cur_pass)
+ {
+ continue;
+ }
+ preloadUIImage(image_it->name, file_name, image_it->use_mips, image_it->scale_rect);
+ }
+
+ if (cur_pass == PASS_DECODE_NOW && !gSavedSettings.getBOOL("NoPreload"))
+ {
+ gTextureList.decodeAllImages(10.f); // decode preloaded images
+ }
+ }
+ return true;
+}
+
+
diff --git a/indra/newview/llviewertexturelist.h b/indra/newview/llviewertexturelist.h
new file mode 100644
index 0000000000..11d1dd855f
--- /dev/null
+++ b/indra/newview/llviewertexturelist.h
@@ -0,0 +1,243 @@
+/**
+ * @file llviewertexturelist.h
+ * @brief Object for managing the list of images within a region
+ *
+ * $LicenseInfo:firstyear=2000&license=viewergpl$
+ *
+ * Copyright (c) 2000-2009, Linden Research, Inc.
+ *
+ * Second Life Viewer Source Code
+ * The source code in this file ("Source Code") is provided by Linden Lab
+ * to you under the terms of the GNU General Public License, version 2.0
+ * ("GPL"), unless you have obtained a separate licensing agreement
+ * ("Other License"), formally executed by you and Linden Lab. Terms of
+ * the GPL can be found in doc/GPL-license.txt in this distribution, or
+ * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
+ *
+ * There are special exceptions to the terms and conditions of the GPL as
+ * it is applied to this Source Code. View the full text of the exception
+ * in the file doc/FLOSS-exception.txt in this software distribution, or
+ * online at
+ * http://secondlifegrid.net/programs/open_source/licensing/flossexception
+ *
+ * By copying, modifying or distributing this software, you acknowledge
+ * that you have read and understood your obligations described above,
+ * and agree to abide by those obligations.
+ *
+ * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+ * COMPLETENESS OR PERFORMANCE.
+ * $/LicenseInfo$
+ */
+
+#ifndef LL_LLVIEWERTEXTURELIST_H
+#define LL_LLVIEWERTEXTURELIST_H
+
+#include "lluuid.h"
+//#include "message.h"
+#include "llgl.h"
+#include "llstat.h"
+#include "llviewertexture.h"
+#include "llui.h"
+#include <list>
+#include <set>
+
+const U32 LL_IMAGE_REZ_LOSSLESS_CUTOFF = 128;
+
+const BOOL MIPMAP_YES = TRUE;
+const BOOL MIPMAP_NO = FALSE;
+
+const BOOL GL_TEXTURE_YES = TRUE;
+const BOOL GL_TEXTURE_NO = FALSE;
+
+const BOOL IMMEDIATE_YES = TRUE;
+const BOOL IMMEDIATE_NO = FALSE;
+
+class LLImageJ2C;
+class LLMessageSystem;
+class LLTextureView;
+
+typedef void (*LLImageCallback)(BOOL success,
+ LLViewerFetchedTexture *src_vi,
+ LLImageRaw* src,
+ LLImageRaw* src_aux,
+ S32 discard_level,
+ BOOL final,
+ void* userdata);
+
+class LLViewerTextureList
+{
+ LOG_CLASS(LLViewerTextureList);
+
+ friend class LLTextureView;
+ friend class LLViewerTextureManager;
+
+public:
+ static BOOL createUploadFile(const std::string& filename, const std::string& out_filename, const U8 codec);
+ static LLPointer<LLImageJ2C> convertToUploadFile(LLPointer<LLImageRaw> raw_image);
+ static void processImageNotInDatabase( LLMessageSystem *msg, void **user_data );
+ static S32 calcMaxTextureRAM();
+ static void receiveImageHeader(LLMessageSystem *msg, void **user_data);
+ static void receiveImagePacket(LLMessageSystem *msg, void **user_data);
+
+public:
+ LLViewerTextureList();
+ ~LLViewerTextureList();
+
+ void init();
+ void shutdown();
+ void dump();
+ void destroyGL(BOOL save_state = TRUE);
+ void restoreGL();
+
+ LLViewerFetchedTexture *findImage(const LLUUID &image_id);
+
+ void dirtyImage(LLViewerFetchedTexture *image);
+
+ // Using image stats, determine what images are necessary, and perform image updates.
+ void updateImages(F32 max_time);
+ void forceImmediateUpdate(LLViewerFetchedTexture* imagep) ;
+
+ // Decode and create textures for all images currently in list.
+ void decodeAllImages(F32 max_decode_time);
+
+ void handleIRCallback(void **data, const S32 number);
+
+ void setUpdateStats(BOOL b) { mUpdateStats = b; }
+
+ S32 getMaxResidentTexMem() const { return mMaxResidentTexMemInMegaBytes; }
+ S32 getMaxTotalTextureMem() const { return mMaxTotalTextureMemInMegaBytes;}
+ S32 getNumImages() { return mImageList.size(); }
+
+ void updateMaxResidentTexMem(S32 mem);
+
+ void doPreloadImages();
+ void doPrefetchImages();
+
+ static S32 getMinVideoRamSetting();
+ static S32 getMaxVideoRamSetting(bool get_recommended = false);
+
+private:
+ void updateImagesDecodePriorities();
+ F32 updateImagesCreateTextures(F32 max_time);
+ F32 updateImagesFetchTextures(F32 max_time);
+ void updateImagesUpdateStats();
+
+ void addImage(LLViewerFetchedTexture *image);
+ void deleteImage(LLViewerFetchedTexture *image);
+
+ void addImageToList(LLViewerFetchedTexture *image);
+ void removeImageFromList(LLViewerFetchedTexture *image);
+
+ LLViewerFetchedTexture * getImage(const LLUUID &image_id,
+ BOOL usemipmap = TRUE,
+ BOOL level_immediate = FALSE, // Get the requested level immediately upon creation.
+ S8 texture_type = LLViewerTexture::FETCHED_TEXTURE,
+ LLGLint internal_format = 0,
+ LLGLenum primary_format = 0,
+ LLHost request_from_host = LLHost()
+ );
+
+ LLViewerFetchedTexture * getImageFromFile(const std::string& filename,
+ BOOL usemipmap = TRUE,
+ BOOL level_immediate = FALSE, // Get the requested level immediately upon creation.
+ S8 texture_type = LLViewerTexture::FETCHED_TEXTURE,
+ LLGLint internal_format = 0,
+ LLGLenum primary_format = 0,
+ const LLUUID& force_id = LLUUID::null
+ );
+
+ LLViewerFetchedTexture* createImage(const LLUUID &image_id,
+ BOOL usemipmap = TRUE,
+ BOOL level_immediate = FALSE, // Get the requested level immediately upon creation.
+ S8 texture_type = LLViewerTexture::FETCHED_TEXTURE,
+ LLGLint internal_format = 0,
+ LLGLenum primary_format = 0,
+ LLHost request_from_host = LLHost()
+ );
+
+ // Request image from a specific host, used for baked avatar textures.
+ // Implemented in header in case someone changes default params above. JC
+ LLViewerFetchedTexture* getImageFromHost(const LLUUID& image_id, LLHost host)
+ { return getImage(image_id, TRUE, FALSE, LLViewerTexture::LOD_TEXTURE, 0, 0, host); }
+
+public:
+ typedef std::set<LLPointer<LLViewerFetchedTexture> > image_list_t;
+ image_list_t mLoadingStreamList;
+ image_list_t mCreateTextureList;
+ image_list_t mCallbackList;
+
+ // Note: just raw pointers because they are never referenced, just compared against
+ std::set<LLViewerFetchedTexture*> mDirtyTextureList;
+
+ BOOL mForceResetTextureStats;
+
+private:
+ typedef std::map< LLUUID, LLPointer<LLViewerFetchedTexture> > uuid_map_t;
+ uuid_map_t mUUIDMap;
+ LLUUID mLastUpdateUUID;
+ LLUUID mLastFetchUUID;
+
+ typedef std::set<LLPointer<LLViewerFetchedTexture>, LLViewerFetchedTexture::Compare> image_priority_list_t;
+ image_priority_list_t mImageList;
+
+ // simply holds on to LLViewerFetchedTexture references to stop them from being purged too soon
+ std::set<LLPointer<LLViewerFetchedTexture> > mImagePreloads;
+
+ BOOL mUpdateStats;
+ S32 mMaxResidentTexMemInMegaBytes;
+ S32 mMaxTotalTextureMemInMegaBytes;
+ LLFrameTimer mForceDecodeTimer;
+
+public:
+ U32 mTextureBits;
+ U32 mTexturePackets;
+
+private:
+ S32 mNumImages;
+ static void (*sUUIDCallback)(void**, const LLUUID &);
+};
+
+class LLUIImageList : public LLImageProviderInterface, public LLSingleton<LLUIImageList>
+{
+public:
+ // LLImageProviderInterface
+ LLUIImagePtr getUIImageByID(const LLUUID& id);
+ LLUIImagePtr getUIImage(const std::string& name);
+ void cleanUp();
+
+ bool initFromFile();
+
+ LLUIImagePtr preloadUIImage(const std::string& name, const std::string& filename, BOOL use_mips, const LLRect& scale_rect);
+
+ static void onUIImageLoaded( BOOL success, LLViewerFetchedTexture *src_vi, LLImageRaw* src, LLImageRaw* src_aux, S32 discard_level, BOOL final, void* userdata );
+private:
+ LLUIImagePtr loadUIImageByName(const std::string& name, const std::string& filename, BOOL use_mips = FALSE, const LLRect& scale_rect = LLRect::null);
+ LLUIImagePtr loadUIImageByID(const LLUUID& id, BOOL use_mips = FALSE, const LLRect& scale_rect = LLRect::null);
+
+ LLUIImagePtr loadUIImage(LLViewerFetchedTexture* imagep, const std::string& name, BOOL use_mips = FALSE, const LLRect& scale_rect = LLRect::null);
+
+
+ struct LLUIImageLoadData
+ {
+ std::string mImageName;
+ LLRect mImageScaleRegion;
+ };
+
+ typedef std::map< std::string, LLPointer<LLUIImage> > uuid_ui_image_map_t;
+ uuid_ui_image_map_t mUIImages;
+
+ //
+ //keep a copy of UI textures to prevent them to be deleted.
+ //mGLTexturep of each UI texture equals to some LLUIImage.mImage.
+ std::list< LLPointer<LLViewerFetchedTexture> > mUITextureList ;
+};
+
+const BOOL GLTEXTURE_TRUE = TRUE;
+const BOOL GLTEXTURE_FALSE = FALSE;
+const BOOL MIPMAP_TRUE = TRUE;
+const BOOL MIPMAP_FALSE = FALSE;
+
+extern LLViewerTextureList gTextureList;
+
+#endif
diff --git a/indra/newview/llviewervisualparam.cpp b/indra/newview/llviewervisualparam.cpp
index 8c7700eb65..7d717ed6dc 100644
--- a/indra/newview/llviewervisualparam.cpp
+++ b/indra/newview/llviewervisualparam.cpp
@@ -76,7 +76,7 @@ BOOL LLViewerVisualParamInfo::parseXml(LLXmlTreeNode *node)
static LLStdStringHandle wearable_string = LLXmlTree::addAttributeString("wearable");
if( node->getFastAttributeString( wearable_string, wearable) )
{
- mWearableType = LLWearable::typeNameToType( wearable );
+ mWearableType = LLWearableDictionary::typeNameToType( wearable );
}
static LLStdStringHandle edit_group_string = LLXmlTree::addAttributeString("edit_group");
@@ -119,12 +119,6 @@ LLViewerVisualParam::LLViewerVisualParam()
{
}
-/*
-//=============================================================================
-// These virtual functions should always be overridden,
-// but are included here for use as templates
-//=============================================================================
-
//-----------------------------------------------------------------------------
// setInfo()
//-----------------------------------------------------------------------------
@@ -140,6 +134,12 @@ BOOL LLViewerVisualParam::setInfo(LLViewerVisualParamInfo *info)
return TRUE;
}
+/*
+//=============================================================================
+// These virtual functions should always be overridden,
+// but are included here for use as templates
+//=============================================================================
+
//-----------------------------------------------------------------------------
// parseData()
//-----------------------------------------------------------------------------
diff --git a/indra/newview/llviewervisualparam.h b/indra/newview/llviewervisualparam.h
index 48d28cebf3..77a95db564 100644
--- a/indra/newview/llviewervisualparam.h
+++ b/indra/newview/llviewervisualparam.h
@@ -90,7 +90,7 @@ public:
virtual const LLVector3* getNextDistortion(U32 *index, LLPolyMesh **mesh) = 0;
// interface methods
- F32 getDisplayOrder() { return getInfo()->mEditGroupDisplayOrder; }
+ F32 getDisplayOrder() const { return getInfo()->mEditGroupDisplayOrder; }
S32 getWearableType() const { return getInfo()->mWearableType; }
const std::string& getEditGroup() const { return getInfo()->mEditGroup; }
diff --git a/indra/newview/llviewerwindow.cpp b/indra/newview/llviewerwindow.cpp
index cbda0e8a64..461f7fc1c7 100644
--- a/indra/newview/llviewerwindow.cpp
+++ b/indra/newview/llviewerwindow.cpp
@@ -36,9 +36,12 @@
#include <stdio.h>
#include <iostream>
#include <fstream>
+#include <algorithm>
+#include "llfloaterreg.h"
#include "llpanellogin.h"
#include "llviewerkeyboard.h"
+#include "llviewermenu.h"
#include "llviewerwindow.h"
#include "llviewquery.h"
@@ -48,15 +51,15 @@
#include "llvoiceclient.h" // for push-to-talk button handling
-
//
// TODO: Many of these includes are unnecessary. Remove them.
//
// linden library includes
-#include "audioengine.h" // mute on minimize
+#include "llaudioengine.h" // mute on minimize
#include "indra_constants.h"
#include "llassetstorage.h"
+#include "llerrorcontrol.h"
#include "llfontgl.h"
#include "llmousehandler.h"
#include "llrect.h"
@@ -76,7 +79,6 @@
#include "llagent.h"
#include "llalertdialog.h"
#include "llbox.h"
-#include "llchatbar.h"
#include "llconsole.h"
#include "llviewercontrol.h"
#include "llcylinder.h"
@@ -91,23 +93,22 @@
#include "llfeaturemanager.h"
#include "llfilepicker.h"
#include "llfloater.h"
-#include "llfloateractivespeakers.h"
#include "llfloaterbuildoptions.h"
#include "llfloaterbuyland.h"
#include "llfloatercamera.h"
#include "llfloaterchat.h"
#include "llfloaterchatterbox.h"
#include "llfloatercustomize.h"
-#include "llfloatereditui.h" // HACK JAMESDEBUG for ui editor
#include "llfloaterland.h"
#include "llfloaterinspect.h"
+#include "llfloatermap.h"
#include "llfloaternamedesc.h"
#include "llfloaterpreference.h"
#include "llfloatersnapshot.h"
#include "llfloatertools.h"
#include "llfloaterworldmap.h"
#include "llfocusmgr.h"
-#include "llframestatview.h"
+#include "llfontfreetype.h"
#include "llgesturemgr.h"
#include "llglheaders.h"
#include "llhoverview.h"
@@ -115,20 +116,21 @@
#include "llhudview.h"
#include "llimagebmp.h"
#include "llimagej2c.h"
-#include "llinventoryview.h"
#include "llkeyboard.h"
#include "lllineeditor.h"
#include "llmenugl.h"
#include "llmodaldialog.h"
#include "llmorphview.h"
#include "llmoveview.h"
+#include "llnavigationbar.h"
#include "llnotify.h"
#include "lloverlaybar.h"
#include "llpreviewtexture.h"
#include "llprogressview.h"
#include "llresmgr.h"
-#include "llrootview.h"
+#include "llsidetray.h"
#include "llselectmgr.h"
+#include "llrootview.h"
#include "llrendersphere.h"
#include "llstartup.h"
#include "llstatusbar.h"
@@ -151,18 +153,19 @@
#include "lltoolmgr.h"
#include "lltoolmorph.h"
#include "lltoolpie.h"
-#include "lltoolplacer.h"
#include "lltoolselectland.h"
-#include "lltoolview.h"
+#include "lltrans.h"
#include "lluictrlfactory.h"
#include "lluploaddialog.h"
#include "llurldispatcher.h" // SLURL from other app instance
#include "llvieweraudio.h"
#include "llviewercamera.h"
#include "llviewergesture.h"
-#include "llviewerimagelist.h"
+#include "llviewertexturelist.h"
#include "llviewerinventory.h"
#include "llviewerkeyboard.h"
+#include "llviewermedia.h"
+#include "llviewermediafocus.h"
#include "llviewermenu.h"
#include "llviewermessage.h"
#include "llviewerobjectlist.h"
@@ -170,7 +173,7 @@
#include "llviewerregion.h"
#include "llviewershadermgr.h"
#include "llviewerstats.h"
-#include "llvoavatar.h"
+#include "llvoavatarself.h"
#include "llvovolume.h"
#include "llworld.h"
#include "llworldmapview.h"
@@ -182,10 +185,16 @@
#include "llviewerjoystick.h"
#include "llviewernetwork.h"
#include "llpostprocess.h"
+#include "llbottomtray.h"
+#include "llnearbychatbar.h"
+#include "llagentui.h"
+
+#include "llnotificationmanager.h"
-#include "llfloatertest.h" // HACK!
#include "llfloaternotificationsconsole.h"
+#include "llnearbychat.h"
+
#if LL_WINDOWS
#include <tchar.h> // For Unicode conversion methods
#endif
@@ -194,7 +203,6 @@
// Globals
//
void render_ui(F32 zoom_factor = 1.f, int subfield = 0);
-LLBottomPanel* gBottomPanel = NULL;
extern BOOL gDebugClicks;
extern BOOL gDisplaySwapBuffers;
@@ -203,7 +211,6 @@ extern BOOL gResizeScreenTexture;
extern S32 gJamesInt;
LLViewerWindow *gViewerWindow = NULL;
-LLVelocityBar *gVelocityBar = NULL;
BOOL gDebugSelect = FALSE;
@@ -247,9 +254,27 @@ std::string LLViewerWindow::sSnapshotDir;
std::string LLViewerWindow::sMovieBaseName;
-extern void toggle_debug_menus(void*);
-
+class RecordToChatConsole : public LLError::Recorder, public LLSingleton<RecordToChatConsole>
+{
+public:
+ virtual void recordMessage(LLError::ELevel level,
+ const std::string& message)
+ {
+ // only log warnings to chat console
+ if (level == LLError::LEVEL_WARN)
+ {
+ LLFloaterChat* chat_floater = LLFloaterReg::findTypedInstance<LLFloaterChat>("chat");
+ if (chat_floater && gSavedSettings.getBOOL("WarningsAsChat"))
+ {
+ LLChat chat;
+ chat.mText = message;
+ chat.mSourceType = CHAT_SOURCE_SYSTEM;
+ chat_floater->addChat(chat, FALSE, FALSE);
+ }
+ }
+ }
+};
////////////////////////////////////////////////////////////////////////////
//
@@ -513,7 +538,7 @@ public:
ypos += y_inc;
}
// only display these messages if we are actually rendering beacons at this moment
- if (LLPipeline::getRenderBeacons(NULL) && gSavedSettings.getBOOL("BeaconAlwaysOn"))
+ if (LLPipeline::getRenderBeacons(NULL) && LLFloaterReg::instanceVisible("beacons"))
{
if (LLPipeline::getRenderParticleBeacons(NULL))
{
@@ -557,7 +582,7 @@ public:
const Line& line = *iter;
LLFontGL::getFontMonospace()->renderUTF8(line.text, 0, (F32)line.x, (F32)line.y, mTextColor,
LLFontGL::LEFT, LLFontGL::TOP,
- LLFontGL::NORMAL, S32_MAX, S32_MAX, NULL, FALSE);
+ LLFontGL::NORMAL, LLFontGL::NO_SHADOW, S32_MAX, S32_MAX, NULL, FALSE);
}
mLineList.clear();
}
@@ -580,11 +605,11 @@ bool LLViewerWindow::shouldShowToolTipFor(LLMouseHandler *mh)
{
LLMouseHandler::EShowToolTip showlevel = mh->getShowToolTip();
- return (
- showlevel == LLMouseHandler::SHOW_ALWAYS ||
- (showlevel == LLMouseHandler::SHOW_IF_NOT_BLOCKED &&
- !mToolTipBlocked)
- );
+ bool tool_tip_allowed = (showlevel == LLMouseHandler::SHOW_ALWAYS
+ || (showlevel == LLMouseHandler::SHOW_IF_NOT_BLOCKED
+ && !mToolTipBlocked));
+
+ return tool_tip_allowed;
}
return false;
}
@@ -912,8 +937,6 @@ void LLViewerWindow::handleFocus(LLWindow *window)
gAgent.onAppFocusGained();
LLToolMgr::getInstance()->onAppFocusGained();
- gShowTextEditCursor = TRUE;
-
// See if we're coming in with modifier keys held down
if (gKeyboard)
{
@@ -943,11 +966,6 @@ void LLViewerWindow::handleFocusLost(LLWindow *window)
showCursor();
getWindow()->setMouseClipping(FALSE);
- // JC - Leave keyboard focus, so if you're popping in and out editing
- // a script, you don't have to click in the editor again and again.
- // gFocusMgr.setKeyboardFocus( NULL );
- gShowTextEditCursor = FALSE;
-
// If losing focus while keys are down, reset them.
if (gKeyboard)
{
@@ -1089,7 +1107,7 @@ BOOL LLViewerWindow::handlePaint(LLWindow *window, S32 x, S32 y, S32 width, S
FillRect(hdc, &wnd_rect, CreateSolidBrush(RGB(255, 255, 255)));
std::string name_str;
- gAgent.getName(name_str);
+ LLAgentUI::buildName(name_str);
std::string temp_str;
temp_str = llformat( "%s FPS %3.1f Phy FPS %2.1f Time Dil %1.3f", /* Flawfinder: ignore */
@@ -1138,7 +1156,7 @@ void LLViewerWindow::handleDataCopy(LLWindow *window, S32 data_type, void *data)
case SLURL_MESSAGE_TYPE:
// received URL
std::string url = (const char*)data;
- LLWebBrowserCtrl* web = NULL;
+ LLMediaCtrl* web = NULL;
const bool trusted_browser = false;
if (LLURLDispatcher::dispatch(url, web, trusted_browser))
{
@@ -1186,6 +1204,27 @@ void LLViewerWindow::handlePauseWatchdog(LLWindow *window)
LLAppViewer::instance()->pauseMainloopTimeout();
}
+//virtual
+std::string LLViewerWindow::translateString(const char* tag)
+{
+ return LLTrans::getString( std::string(tag) );
+}
+
+//virtual
+std::string LLViewerWindow::translateString(const char* tag,
+ const std::map<std::string, std::string>& args)
+{
+ // LLTrans uses a special subclass of std::string for format maps,
+ // but we must use std::map<> in these callbacks, otherwise we create
+ // a dependency between LLWindow and LLFormatMapString. So copy the data.
+ LLStringUtil::format_map_t args_copy;
+ std::map<std::string,std::string>::const_iterator it = args.begin();
+ for ( ; it != args.end(); ++it)
+ {
+ args_copy[it->first] = it->second;
+ }
+ return LLTrans::getString( std::string(tag), args_copy);
+}
//
// Classes
@@ -1196,11 +1235,13 @@ LLViewerWindow::LLViewerWindow(
S32 width, S32 height,
BOOL fullscreen, BOOL ignore_pixel_depth)
:
+ mWindow(NULL),
mActive(TRUE),
mWantFullscreen(fullscreen),
mShowFullscreenProgress(FALSE),
mWindowRect(0, height, width, 0),
mVirtualWindowRect(0, height, width, 0),
+ mWorldViewRect(0, height, width, 0),
mLeftMouseDown(FALSE),
mMiddleMouseDown(FALSE),
mRightMouseDown(FALSE),
@@ -1224,6 +1265,8 @@ LLViewerWindow::LLViewerWindow(
LLNotifications::instance().getChannel("VW_alerts")->connectChanged(&LLViewerWindow::onAlert);
LLNotifications::instance().getChannel("VW_alertmodal")->connectChanged(&LLViewerWindow::onAlert);
+ LLNotifications::instance().setIgnoreAllNotifications(gSavedSettings.getBOOL("IgnoreAllNotifications"));
+ llinfos << "NOTE: ALL NOTIFICATIONS THAT OCCUR WILL GET ADDED TO IGNORE LIST FOR LATER RUNS." << llendl;
// Default to application directory.
LLViewerWindow::sSnapshotBaseName = "Snapshot";
@@ -1231,7 +1274,7 @@ LLViewerWindow::LLViewerWindow(
resetSnapshotLoc();
// create window
- mWindow = LLWindowManager::createWindow(
+ mWindow = LLWindowManager::createWindow(this,
title, name, x, y, width, height, 0,
fullscreen,
gNoRender,
@@ -1306,26 +1349,31 @@ LLViewerWindow::LLViewerWindow(
mInitAlert = "DisplaySettingsNoShaders";
LLFeatureManager::getInstance()->setGraphicsLevel(0, false);
gSavedSettings.setU32("RenderQualityPerformance", 0);
-
}
- // set callbacks
- mWindow->setCallbacks(this);
-
// Init the image list. Must happen after GL is initialized and before the images that
// LLViewerWindow needs are requested.
- gImageList.init();
- LLViewerImage::initClass();
+ gTextureList.init();
+ LLViewerTextureManager::init() ;
gBumpImageList.init();
-
+
+ // Init font system, but don't actually load the fonts yet
+ // because our window isn't onscreen and they take several
+ // seconds to parse.
+ LLFontGL::initClass( gSavedSettings.getF32("FontScreenDPI"),
+ mDisplayScale.mV[VX],
+ mDisplayScale.mV[VY],
+ gDirUtilp->getAppRODataDir(),
+ LLUI::getXUIPaths());
+
// Create container for all sub-views
- mRootView = new LLRootView("root", mVirtualWindowRect, FALSE);
-
- if (!gNoRender)
- {
- // Init default fonts
- initFonts();
- }
+ LLView::Params rvp;
+ rvp.name("root");
+ rvp.rect(mVirtualWindowRect);
+ rvp.mouse_opaque(false);
+ rvp.follows.flags(FOLLOWS_NONE);
+ mRootView = LLUICtrlFactory::create<LLRootView>(rvp);
+ LLUI::setRootView(mRootView);
// Make avatar head look forward at start
mCurrentMousePoint.mX = getWindowWidth() / 2;
@@ -1381,8 +1429,6 @@ void LLViewerWindow::initBase()
LLRect full_window(0, height, width, 0);
- adjustRectanglesForFirstUse(full_window);
-
////////////////////
//
// Set the gamma
@@ -1402,41 +1448,57 @@ void LLViewerWindow::initBase()
// Constrain floaters to inside the menu and status bar regions.
LLRect floater_view_rect = full_window;
- // make space for menu bar if we have one
+ // make space for menu bar
floater_view_rect.mTop -= MENU_BAR_HEIGHT;
- // TODO: Eliminate magic constants - please used named constants if changing this
- floater_view_rect.mBottom += STATUS_BAR_HEIGHT + 12 + 16 + 2;
-
- // Check for non-first startup
- S32 floater_view_bottom = gSavedSettings.getS32("FloaterViewBottom");
- if (floater_view_bottom >= 0)
- {
- floater_view_rect.mBottom = floater_view_bottom;
- }
- gFloaterView = new LLFloaterView("Floater View", floater_view_rect );
- gFloaterView->setVisible(TRUE);
-
- gSnapshotFloaterView = new LLSnapshotFloaterView("Snapshot Floater View", full_window);
+ LLFloaterView::Params fvparams;
+ fvparams.name("Floater View");
+ fvparams.rect(floater_view_rect);
+ fvparams.mouse_opaque(false);
+ fvparams.follows.flags(FOLLOWS_ALL);
+ fvparams.tab_stop(false);
+ gFloaterView = LLUICtrlFactory::create<LLFloaterView> (fvparams);
+
+ LLSnapshotFloaterView::Params snapParams;
+ snapParams.name("Snapshot Floater View");
+ snapParams.rect(full_window);
+ snapParams.enabled(false);
+ gSnapshotFloaterView = LLUICtrlFactory::create<LLSnapshotFloaterView> (snapParams);
+
// Snapshot floater must start invisible otherwise it eats all
// the tooltips. JC
gSnapshotFloaterView->setVisible(FALSE);
// Console
llassert( !gConsole );
- gConsole = new LLConsole(
- "console",
- gSavedSettings.getS32("ConsoleBufferSize"),
- getChatConsoleRect(),
- gSavedSettings.getS32("ChatFontSize"),
- gSavedSettings.getF32("ChatPersistTime") );
- gConsole->setFollows(FOLLOWS_LEFT | FOLLOWS_RIGHT | FOLLOWS_BOTTOM);
+ LLConsole::Params cp;
+ cp.name("console");
+ cp.max_lines(gSavedSettings.getS32("ConsoleBufferSize"));
+ cp.rect(getChatConsoleRect());
+ cp.persist_time(gSavedSettings.getF32("ChatPersistTime"));
+ cp.font_size_index(gSavedSettings.getS32("ChatFontSize"));
+ cp.follows.flags(FOLLOWS_LEFT | FOLLOWS_RIGHT | FOLLOWS_BOTTOM);
+ gConsole = LLUICtrlFactory::create<LLConsole>(cp);
mRootView->addChild(gConsole);
+ // optionally forward warnings to chat console/chat floater
+ // for qa runs and dev builds
+#if !LL_RELEASE_FOR_DOWNLOAD
+ LLError::addRecorder(RecordToChatConsole::getInstance());
+#else
+ if(gSavedSettings.getBOOL("QAMode"))
+ {
+ LLError::addRecorder(RecordToChatConsole::getInstance());
+ }
+#endif
+
// Debug view over the console
- gDebugView = new LLDebugView("gDebugView", full_window);
- gDebugView->setFollowsAll();
- gDebugView->setVisible(TRUE);
+ LLDebugView::Params debug_p;
+ debug_p.name("DebugView");
+ debug_p.rect(full_window);
+ debug_p.follows.flags(FOLLOWS_ALL);
+ debug_p.visible(true);
+ gDebugView = LLUICtrlFactory::create<LLDebugView>(debug_p);
mRootView->addChild(gDebugView);
// Add floater view at the end so it will be on top, and give it tab priority over others
@@ -1444,303 +1506,204 @@ void LLViewerWindow::initBase()
mRootView->addChild(gSnapshotFloaterView);
// notify above floaters!
- LLRect notify_rect = full_window;
- //notify_rect.mTop -= 24;
- notify_rect.mBottom += STATUS_BAR_HEIGHT;
- gNotifyBoxView = new LLNotifyBoxView("notify_container", notify_rect, FALSE, FOLLOWS_ALL);
+ LLRect notify_rect = floater_view_rect;
+ LLNotifyBoxView::Params p;
+ p.name("notify_container");
+ p.rect(notify_rect);
+ p.mouse_opaque(false);
+ p.follows.flags(FOLLOWS_ALL);
+ gNotifyBoxView = LLUICtrlFactory::create<LLNotifyBoxView> (p);
mRootView->addChild(gNotifyBoxView, -2);
// Tooltips go above floaters
- mToolTip = new LLTextBox( std::string("tool tip"), LLRect(0, 1, 1, 0 ) );
- mToolTip->setHPad( 4 );
- mToolTip->setVPad( 2 );
- mToolTip->setColor( gColors.getColor( "ToolTipTextColor" ) );
- mToolTip->setBorderColor( gColors.getColor( "ToolTipBorderColor" ) );
- mToolTip->setBorderVisible( FALSE );
- mToolTip->setBackgroundColor( gColors.getColor( "ToolTipBgColor" ) );
- mToolTip->setBackgroundVisible( TRUE );
- mToolTip->setFontStyle(LLFontGL::NORMAL);
- mToolTip->setBorderDropshadowVisible( TRUE );
- mToolTip->setVisible( FALSE );
+ LLTextBox::Params params;
+ params.text("tool tip");
+ params.name(params.text);
+ params.rect(LLRect (0, 1, 1, 0));
+ params.h_pad(4);
+ params.v_pad(2);
+ params.text_color(LLUIColorTable::instance().getColor( "ToolTipTextColor" ));
+ params.border_color(LLUIColorTable::instance().getColor( "ToolTipBorderColor" ));
+ params.border_visible(false);
+ params.background_color(LLUIColorTable::instance().getColor( "ToolTipBgColor" ));
+ params.bg_visible(true);
+ params.font.style("NORMAL");
+ params.border_drop_shadow_visible(true);
+ params.visible(false);
+ mToolTip = LLUICtrlFactory::create<LLTextBox> (params);
// Add the progress bar view (startup view), which overrides everything
- mProgressView = new LLProgressView(std::string("ProgressView"), full_window);
+ mProgressView = new LLProgressView(full_window);
mRootView->addChild(mProgressView);
setShowProgress(FALSE);
setProgressCancelButtonVisible(FALSE);
}
-
-void adjust_rect_top_left(const std::string& control, const LLRect& window)
+void LLViewerWindow::initWorldUI()
{
- LLRect r = gSavedSettings.getRect(control);
- if (r.mLeft == 0 && r.mBottom == 0)
- {
- r.setLeftTopAndSize(0, window.getHeight(), r.getWidth(), r.getHeight());
- gSavedSettings.setRect(control, r);
- }
-}
+ S32 height = mRootView->getRect().getHeight();
+ S32 width = mRootView->getRect().getWidth();
+ LLRect full_window(0, height, width, 0);
-void adjust_rect_top_center(const std::string& control, const LLRect& window)
-{
- LLRect r = gSavedSettings.getRect(control);
- if (r.mLeft == 0 && r.mBottom == 0)
- {
- r.setLeftTopAndSize( window.getWidth()/2 - r.getWidth()/2,
- window.getHeight(),
- r.getWidth(),
- r.getHeight() );
- gSavedSettings.setRect(control, r);
- }
-}
+ gIMMgr = LLIMMgr::getInstance();
-void adjust_rect_top_right(const std::string& control, const LLRect& window)
-{
- LLRect r = gSavedSettings.getRect(control);
- if (r.mLeft == 0 && r.mBottom == 0)
- {
- r.setLeftTopAndSize(window.getWidth() - r.getWidth(),
- window.getHeight(),
- r.getWidth(),
- r.getHeight());
- gSavedSettings.setRect(control, r);
- }
-}
+ // side tray
+ getRootView()->addChild(LLSideTray::getInstance());
-// *TODO: Adjust based on XUI XML
-const S32 TOOLBAR_HEIGHT = 64;
+ getRootView()->sendChildToFront(gFloaterView);
+ getRootView()->sendChildToFront(gSnapshotFloaterView);
-void adjust_rect_bottom_left(const std::string& control, const LLRect& window)
-{
- LLRect r = gSavedSettings.getRect(control);
- if (r.mLeft == 0 && r.mBottom == 0)
- {
- r.setOriginAndSize(0, TOOLBAR_HEIGHT, r.getWidth(), r.getHeight());
- gSavedSettings.setRect(control, r);
- }
-}
+ // new bottom panel
+ LLRect rc = LLBottomTray::getInstance()->getRect();
+ rc.mLeft = 0;
+ rc.mRight = mRootView->getRect().getWidth();
+ LLBottomTray::getInstance()->reshape(rc.getWidth(),rc.getHeight(),FALSE);
+ LLBottomTray::getInstance()->setRect(rc);
-void adjust_rect_bottom_center(const std::string& control, const LLRect& window)
-{
- LLRect r = gSavedSettings.getRect(control);
- if (r.mLeft == 0 && r.mBottom == 0)
- {
- r.setOriginAndSize(
- window.getWidth()/2 - r.getWidth()/2,
- TOOLBAR_HEIGHT,
- r.getWidth(),
- r.getHeight());
- gSavedSettings.setRect(control, r);
- }
-}
+ // View for hover information
+ LLHoverView::Params hvp;
+ hvp.name("gHoverview");
+ hvp.rect(full_window);
+ gHoverView = LLUICtrlFactory::create<LLHoverView>(hvp);
+ mRootView->addChild(gHoverView);
-void adjust_rect_centered_partial_zoom(const std::string& control,
- const LLRect& window)
-{
- LLRect rect = gSavedSettings.getRect(control);
- // Only adjust on first use
- if (rect.mLeft == 0 && rect.mBottom == 0)
+ // Pre initialize instance communicate instance;
+ // currently needs to happen before initializing chat or IM
+ LLFloaterReg::getInstance("communicate");
+
+ if ( gSavedPerAccountSettings.getBOOL("LogShowHistory") )
{
- S32 width = window.getWidth();
- S32 height = window.getHeight();
- rect.set(0, height-STATUS_BAR_HEIGHT, width, TOOL_BAR_HEIGHT);
- // Make floater fill 80% of window, leaving 20% padding on
- // the sides.
- const F32 ZOOM_FRACTION = 0.8f;
- S32 dx = (S32)(width * (1.f - ZOOM_FRACTION));
- S32 dy = (S32)(height * (1.f - ZOOM_FRACTION));
- rect.stretch(-dx/2, -dy/2);
- gSavedSettings.setRect(control, rect);
+ LLFloaterChat::loadHistory();
}
-}
-
-
-// Many rectangles can't be placed until we know the screen size.
-// These rectangles have their bottom-left corner as 0,0
-void LLViewerWindow::adjustRectanglesForFirstUse(const LLRect& window)
-{
- LLRect r;
- // *NOTE: The width and height of these floaters must be
- // identical in settings.xml and their relevant floater.xml
- // files, otherwise the window construction will get
- // confused. JC
- adjust_rect_bottom_center("FloaterMoveRect2", window);
+ LLRect morph_view_rect = full_window;
+ morph_view_rect.stretch( -STATUS_BAR_HEIGHT );
+ morph_view_rect.mTop = full_window.mTop - 32;
+ LLMorphView::Params mvp;
+ mvp.name("MorphView");
+ mvp.rect(morph_view_rect);
+ mvp.visible(false);
+ gMorphView = LLUICtrlFactory::create<LLMorphView>(mvp);
+ mRootView->addChild(gMorphView);
- adjust_rect_top_center("FloaterCameraRect3", window);
+ // Make space for nav bar.
+ LLRect floater_view_rect = gFloaterView->getRect();
+ LLRect notify_view_rect = gNotifyBoxView->getRect();
+ floater_view_rect.mTop -= NAVIGATION_BAR_HEIGHT;
+ floater_view_rect.mBottom += LLBottomTray::getInstance()->getRect().getHeight();
+ notify_view_rect.mTop -= NAVIGATION_BAR_HEIGHT;
+ notify_view_rect.mBottom += LLBottomTray::getInstance()->getRect().getHeight();
+ gFloaterView->setRect(floater_view_rect);
+ gNotifyBoxView->setRect(notify_view_rect);
- adjust_rect_top_left("FloaterCustomizeAppearanceRect", window);
+ // *Note: this is where gFloaterMute used to be initialized.
- adjust_rect_top_left("FloaterLandRect5", window);
-
- adjust_rect_top_left("FloaterFindRect2", window);
-
- adjust_rect_top_left("FloaterGestureRect2", window);
-
- adjust_rect_top_right("FloaterMiniMapRect", window);
+ LLWorldMapView::initClass();
- adjust_rect_top_right("FloaterLagMeter", window);
-
- adjust_rect_top_left("FloaterBuildOptionsRect", window);
-
- adjust_rect_bottom_left("FloaterActiveSpeakersRect", window);
-
- adjust_rect_bottom_left("FloaterBumpRect", window);
-
- adjust_rect_bottom_left("FloaterRegionInfo", window);
-
- adjust_rect_bottom_left("FloaterEnvRect", window);
-
- adjust_rect_bottom_left("FloaterAdvancedSkyRect", window);
-
- adjust_rect_bottom_left("FloaterAdvancedWaterRect", window);
-
- adjust_rect_bottom_left("FloaterDayCycleRect", window);
-
- adjust_rect_top_right("FloaterStatisticsRect", window);
-
-
- // bottom-right
- r = gSavedSettings.getRect("FloaterInventoryRect");
- if (r.mLeft == 0 && r.mBottom == 0)
+ // Force gFloaterWorldMap to initialize
+ LLFloaterReg::getInstance("world_map");
+
+ // Force gFloaterTools to initialize
+ LLFloaterReg::getInstance("build");
+ LLFloaterReg::hideInstance("build");
+
+ // Status bar
+ S32 menu_bar_height = gMenuBarView->getRect().getHeight();
+ LLRect root_rect = getRootView()->getRect();
+ LLRect status_rect(0, root_rect.getHeight(), root_rect.getWidth(), root_rect.getHeight() - menu_bar_height);
+ gStatusBar = new LLStatusBar(status_rect);
+ gStatusBar->setFollows(FOLLOWS_LEFT | FOLLOWS_RIGHT | FOLLOWS_TOP);
+
+ gStatusBar->reshape(root_rect.getWidth(), gStatusBar->getRect().getHeight(), TRUE);
+ gStatusBar->translate(0, root_rect.getHeight() - gStatusBar->getRect().getHeight());
+ // sync bg color with menu bar
+ gStatusBar->setBackgroundColor( gMenuBarView->getBackgroundColor().get() );
+
+ // Navigation bar
+
+ LLNavigationBar* navbar = LLNavigationBar::getInstance();
+ navbar->reshape(root_rect.getWidth(), navbar->getRect().getHeight(), TRUE); // *TODO: redundant?
+ navbar->translate(0, root_rect.getHeight() - menu_bar_height - navbar->getRect().getHeight()); // FIXME
+ navbar->setBackgroundColor(gMenuBarView->getBackgroundColor().get());
+
+ if (!gSavedSettings.getBOOL("ShowNavbarNavigationPanel"))
{
- r.setOriginAndSize(
- window.getWidth() - r.getWidth(),
- 0,
- r.getWidth(),
- r.getHeight());
- gSavedSettings.setRect("FloaterInventoryRect", r);
+ navbar->showNavigationPanel(FALSE);
}
-
-// adjust_rect_top_left("FloaterHUDRect2", window);
- // slightly off center to be left of the avatar.
- r = gSavedSettings.getRect("FloaterHUDRect2");
- if (r.mLeft == 0 && r.mBottom == 0)
+ if (!gSavedSettings.getBOOL("ShowNavbarFavoritesPanel"))
{
- r.setOriginAndSize(
- window.getWidth()/4 - r.getWidth()/2,
- 2*window.getHeight()/3 - r.getHeight()/2,
- r.getWidth(),
- r.getHeight());
- gSavedSettings.setRect("FloaterHUDRect2", r);
+ navbar->showFavoritesPanel(FALSE);
}
-}
-//Rectangles need to be adjusted after the window is constructed
-//in order for proper centering to take place
-void LLViewerWindow::adjustControlRectanglesForFirstUse(const LLRect& window)
-{
- adjust_rect_bottom_center("FloaterMoveRect2", window);
- adjust_rect_top_center("FloaterCameraRect3", window);
-}
+ getRootView()->addChild(gStatusBar);
+ getRootView()->addChild(navbar);
-void LLViewerWindow::initWorldUI()
-{
- pre_init_menus();
- S32 height = mRootView->getRect().getHeight();
- S32 width = mRootView->getRect().getWidth();
- LLRect full_window(0, height, width, 0);
+ //sidetray
+ //then notify area
+ //then menu
+ //getRootView()->sendChildToFront(LLSideTray::getInstance());
- if ( gBottomPanel == NULL ) // Don't re-enter if objects are alreay created
- {
- // panel containing chatbar, toolbar, and overlay, over floaters
- gBottomPanel = new LLBottomPanel(mRootView->getRect());
- mRootView->addChild(gBottomPanel);
+ getRootView()->sendChildToFront(gNotifyBoxView);
+ // menu holder appears on top to get first pass at all mouse events
+ getRootView()->sendChildToFront(gMenuHolder);
- // View for hover information
- gHoverView = new LLHoverView(std::string("gHoverView"), full_window);
- gHoverView->setVisible(TRUE);
- mRootView->addChild(gHoverView);
-
- gIMMgr = LLIMMgr::getInstance();
+ //Channel Manager
+ LLNotificationsUI::LLChannelManager* channel_manager = LLNotificationsUI::LLChannelManager::getInstance();
+ getRootView()->addChild(channel_manager);
+ //Notification Manager
+ LLNotificationsUI::LLNotificationManager* notify_manager = LLNotificationsUI::LLNotificationManager::getInstance();
+ getRootView()->addChild(notify_manager);
- if ( gSavedPerAccountSettings.getBOOL("LogShowHistory") )
+ if ( gHUDView == NULL )
+ {
+ LLRect hud_rect = full_window;
+ hud_rect.mBottom += 50;
+ if (gMenuBarView)
{
- LLFloaterChat::getInstance(LLSD())->loadHistory();
+ hud_rect.mTop -= gMenuBarView->getRect().getHeight();
}
-
- LLRect morph_view_rect = full_window;
- morph_view_rect.stretch( -STATUS_BAR_HEIGHT );
- morph_view_rect.mTop = full_window.mTop - 32;
- gMorphView = new LLMorphView(std::string("gMorphView"), morph_view_rect );
- mRootView->addChild(gMorphView);
- gMorphView->setVisible(FALSE);
-
- // *Note: this is where gFloaterMute used to be initialized.
-
- LLWorldMapView::initClass();
-
- adjust_rect_centered_partial_zoom("FloaterWorldMapRect2", full_window);
-
- gFloaterWorldMap = new LLFloaterWorldMap();
- gFloaterWorldMap->setVisible(FALSE);
-
- //
- // Tools for building
- //
-
- // Toolbox floater
- init_menus();
-
- gFloaterTools = new LLFloaterTools();
- gFloaterTools->setVisible(FALSE);
-
- // Status bar
- S32 menu_bar_height = gMenuBarView->getRect().getHeight();
- LLRect root_rect = getRootView()->getRect();
- LLRect status_rect(0, root_rect.getHeight(), root_rect.getWidth(), root_rect.getHeight() - menu_bar_height);
- gStatusBar = new LLStatusBar(std::string("status"), status_rect);
- gStatusBar->setFollows(FOLLOWS_LEFT | FOLLOWS_RIGHT | FOLLOWS_TOP);
-
- gStatusBar->reshape(root_rect.getWidth(), gStatusBar->getRect().getHeight(), TRUE);
- gStatusBar->translate(0, root_rect.getHeight() - gStatusBar->getRect().getHeight());
- // sync bg color with menu bar
- gStatusBar->setBackgroundColor( gMenuBarView->getBackgroundColor() );
-
- LLFloaterChatterBox::createInstance(LLSD());
-
- getRootView()->addChild(gStatusBar);
-
- // menu holder appears on top to get first pass at all mouse events
- getRootView()->sendChildToFront(gMenuHolder);
+ gHUDView = new LLHUDView(hud_rect);
+ // put behind everything else in the UI
+ getRootView()->addChildInBack(gHUDView);
}
}
// Destroy the UI
void LLViewerWindow::shutdownViews()
{
+ // clean up warning logger
+ LLError::removeRecorder(RecordToChatConsole::getInstance());
+
delete mDebugText;
mDebugText = NULL;
- gSavedSettings.setS32("FloaterViewBottom", gFloaterView->getRect().mBottom);
-
// Cleanup global views
if (gMorphView)
{
gMorphView->setVisible(FALSE);
}
+ // Delete Tool Tip
+ delete mToolTip;
+ mToolTip = NULL;
+
// Delete all child views.
delete mRootView;
mRootView = NULL;
// Automatically deleted as children of mRootView. Fix the globals.
- gFloaterTools = NULL;
gStatusBar = NULL;
gIMMgr = NULL;
gHoverView = NULL;
- gFloaterView = NULL;
- gMorphView = NULL;
+ gFloaterView = NULL;
+ gMorphView = NULL;
gHUDView = NULL;
gNotifyBoxView = NULL;
-
- delete mToolTip;
- mToolTip = NULL;
}
void LLViewerWindow::shutdownGL()
@@ -1755,7 +1718,7 @@ void LLViewerWindow::shutdownGL()
gSky.cleanup();
stop_glerror();
- gImageList.shutdown();
+ gTextureList.shutdown();
stop_glerror();
gBumpImageList.shutdown();
@@ -1767,7 +1730,7 @@ void LLViewerWindow::shutdownGL()
gPipeline.cleanup();
stop_glerror();
- LLViewerImage::cleanupClass();
+ LLViewerTextureManager::cleanup() ;
llinfos << "Cleaning up select manager" << llendl;
LLSelectMgr::getInstance()->cleanup();
@@ -1829,8 +1792,8 @@ void LLViewerWindow::sendShapeToSim()
msg->addU32Fast(_PREHASH_CircuitCode, gMessageSystem->mOurCircuitCode);
msg->nextBlockFast(_PREHASH_HeightWidthBlock);
msg->addU32Fast(_PREHASH_GenCounter, 0);
- U16 height16 = (U16) mWindowRect.getHeight();
- U16 width16 = (U16) mWindowRect.getWidth();
+ U16 height16 = (U16) mWorldViewRect.getHeight();
+ U16 width16 = (U16) mWorldViewRect.getWidth();
msg->addU16Fast(_PREHASH_Height, height16);
msg->addU16Fast(_PREHASH_Width, width16);
gAgent.sendReliableMessage();
@@ -1851,25 +1814,18 @@ void LLViewerWindow::reshape(S32 width, S32 height)
return;
}
- glViewport(0, 0, width, height );
+ // update our window rectangle
+ mWindowRect.mRight = mWindowRect.mLeft + width;
+ mWindowRect.mTop = mWindowRect.mBottom + height;
+
+ //glViewport(0, 0, width, height );
if (height > 0)
{
- LLViewerCamera::getInstance()->setViewHeightInPixels( height );
- if (mWindow->getFullscreen())
- {
- // force to 4:3 aspect for odd resolutions
- LLViewerCamera::getInstance()->setAspect( getDisplayAspectRatio() );
- }
- else
- {
- LLViewerCamera::getInstance()->setAspect( width / (F32) height);
- }
+ LLViewerCamera::getInstance()->setViewHeightInPixels( mWorldViewRect.getHeight() );
+ LLViewerCamera::getInstance()->setAspect( getWorldViewAspectRatio() );
}
- // update our window rectangle
- mWindowRect.mRight = mWindowRect.mLeft + width;
- mWindowRect.mTop = mWindowRect.mBottom + height;
calcDisplayScale();
BOOL display_scale_changed = mDisplayScale != LLUI::sGLScaleFactor;
@@ -1879,7 +1835,7 @@ void LLViewerWindow::reshape(S32 width, S32 height)
mVirtualWindowRect.mRight = mVirtualWindowRect.mLeft + llround((F32)width / mDisplayScale.mV[VX]);
mVirtualWindowRect.mTop = mVirtualWindowRect.mBottom + llround((F32)height / mDisplayScale.mV[VY]);
- setupViewport();
+ setup2DViewport();
// Inform lower views of the change
// round up when converting coordinates to make sure there are no gaps at edge of window
@@ -1897,7 +1853,7 @@ void LLViewerWindow::reshape(S32 width, S32 height)
// store the mode the user wants (even if not there yet)
- gSavedSettings.setBOOL("FullScreen", mWantFullscreen);
+ gSavedSettings.setBOOL("WindowFullScreen", mWantFullscreen);
// store new settings for the mode we are in, regardless
if (!mWindow->getFullscreen())
@@ -1917,7 +1873,6 @@ void LLViewerWindow::reshape(S32 width, S32 height)
LLViewerStats::getInstance()->setStat(LLViewerStats::ST_WINDOW_WIDTH, (F64)width);
LLViewerStats::getInstance()->setStat(LLViewerStats::ST_WINDOW_HEIGHT, (F64)height);
- gResizeScreenTexture = TRUE;
}
}
@@ -1925,10 +1880,10 @@ void LLViewerWindow::reshape(S32 width, S32 height)
// Hide normal UI when a logon fails
void LLViewerWindow::setNormalControlsVisible( BOOL visible )
{
- if ( gBottomPanel )
+ if(LLBottomTray::instanceExists())
{
- gBottomPanel->setVisible( visible );
- gBottomPanel->setEnabled( visible );
+ LLBottomTray::getInstance()->setVisible(visible);
+ LLBottomTray::getInstance()->setEnabled(visible);
}
if ( gMenuBarView )
@@ -1946,6 +1901,12 @@ void LLViewerWindow::setNormalControlsVisible( BOOL visible )
gStatusBar->setVisible( visible );
gStatusBar->setEnabled( visible );
}
+
+ LLNavigationBar* navbarp = LLUI::getRootView()->findChild<LLNavigationBar>("navigation_bar");
+ if (navbarp)
+ {
+ navbarp->setVisible( visible );
+ }
}
void LLViewerWindow::setMenuBackgroundColor(bool god_mode, bool dev_grid)
@@ -1955,19 +1916,19 @@ void LLViewerWindow::setMenuBackgroundColor(bool god_mode, bool dev_grid)
if(god_mode && LLViewerLogin::getInstance()->isInProductionGrid())
{
- new_bg_color = gColors.getColor( "MenuBarGodBgColor" );
+ new_bg_color = LLUIColorTable::instance().getColor( "MenuBarGodBgColor" );
}
else if(god_mode && !LLViewerLogin::getInstance()->isInProductionGrid())
{
- new_bg_color = gColors.getColor( "MenuNonProductionGodBgColor" );
+ new_bg_color = LLUIColorTable::instance().getColor( "MenuNonProductionGodBgColor" );
}
else if(!god_mode && !LLViewerLogin::getInstance()->isInProductionGrid())
{
- new_bg_color = gColors.getColor( "MenuNonProductionBgColor" );
+ new_bg_color = LLUIColorTable::instance().getColor( "MenuNonProductionBgColor" );
}
else
{
- new_bg_color = gColors.getColor( "MenuBarBgColor" );
+ new_bg_color = LLUIColorTable::instance().getColor( "MenuBarBgColor" );
}
if(gMenuBarView)
@@ -1978,6 +1939,7 @@ void LLViewerWindow::setMenuBackgroundColor(bool god_mode, bool dev_grid)
if(gStatusBar)
{
gStatusBar->setBackgroundColor( new_bg_color );
+ gStatusBar->getChild<LLTextBox>("HealthText")->setBackgroundColor(new_bg_color);
}
}
@@ -2021,7 +1983,7 @@ void LLViewerWindow::draw()
glLoadIdentity();
microsecondsToTimecodeString(gFrameTime,text);
- const LLFontGL* font = LLResMgr::getInstance()->getRes( LLFONT_SANSSERIF );
+ const LLFontGL* font = LLFontGL::getFontSansSerif();
font->renderUTF8(text, 0,
llround((getWindowWidth()/2)-100.f),
llround((getWindowHeight()-60.f)),
@@ -2067,6 +2029,11 @@ void LLViewerWindow::draw()
// No translation needed, this view is glued to 0,0
mRootView->draw();
+ if (mToolTip->getVisible() && LLView::sDebugRects)
+ {
+ gl_rect_2d(mToolTipStickyRect, LLColor4::white, false);
+ }
+
// Draw optional on-top-of-everyone view
LLUICtrl* top_ctrl = gFocusMgr.getTopCtrl();
if (top_ctrl && top_ctrl->getVisible())
@@ -2126,6 +2093,9 @@ void LLViewerWindow::draw()
#if LL_DEBUG
LLView::sIsDrawing = FALSE;
#endif
+
+ // UI post-draw Updates
+ gNotifyBoxView->updateNotifyBoxView();
}
// Takes a single keydown event, usually when UI is visible
@@ -2140,18 +2110,18 @@ BOOL LLViewerWindow::handleKey(KEY key, MASK mask)
if (key < 0x80)
{
// Not a special key, so likely (we hope) to generate a character. Let it fall through to character handler first.
- return gFocusMgr.childHasKeyboardFocus(mRootView);
+ return (gFocusMgr.getKeyboardFocus() != NULL);
}
}
- // HACK look for UI editing keys
- if (LLView::sEditingUI)
- {
- if (LLFloaterEditUI::processKeystroke(key, mask))
- {
- return TRUE;
- }
- }
+ //// HACK look for UI editing keys
+ //if (LLView::sEditingUI)
+ //{
+ // if (LLFloaterEditUI::processKeystroke(key, mask))
+ // {
+ // return TRUE;
+ // }
+ //}
// Hide tooltips on keypress
mToolTipBlocked = TRUE; // block until next time mouse is moved
@@ -2193,7 +2163,8 @@ BOOL LLViewerWindow::handleKey(KEY key, MASK mask)
&& (MASK_CONTROL & mask)
&& ('5' == key))
{
- LLFloaterNotificationConsole::showInstance();
+ //LLFloaterNotificationConsole::showInstance();
+ LLFloaterReg::showInstance("notifications_console");
return TRUE;
}
@@ -2222,13 +2193,14 @@ BOOL LLViewerWindow::handleKey(KEY key, MASK mask)
}
// Traverses up the hierarchy
- LLUICtrl* keyboard_focus = gFocusMgr.getKeyboardFocus();
+ LLFocusableElement* keyboard_focus = gFocusMgr.getKeyboardFocus();
if( keyboard_focus )
{
+ LLLineEditor* chat_editor = LLBottomTray::instanceExists() ? LLBottomTray::getInstance()->getNearbyChatBar()->getChatBox() : NULL;
// arrow keys move avatar while chatting hack
- if (gChatBar && gChatBar->inputEditorHasFocus())
+ if (chat_editor && chat_editor->hasFocus())
{
- if (gChatBar->getCurrentChat().empty() || gSavedSettings.getBOOL("ArrowKeysMoveAvatar"))
+ if (chat_editor->getText().empty() || gSavedSettings.getBOOL("ArrowKeysMoveAvatar"))
{
switch(key)
{
@@ -2269,7 +2241,7 @@ BOOL LLViewerWindow::handleKey(KEY key, MASK mask)
}
// Try for a new-format gesture
- if (gGestureManager.triggerGesture(key, mask))
+ if (LLGestureManager::instance().triggerGesture(key, mask))
{
return TRUE;
}
@@ -2356,7 +2328,7 @@ BOOL LLViewerWindow::handleUnicodeChar(llwchar uni_char, MASK mask)
}
// Traverses up the hierarchy
- LLView* keyboard_focus = gFocusMgr.getKeyboardFocus();
+ LLFocusableElement* keyboard_focus = gFocusMgr.getKeyboardFocus();
if( keyboard_focus )
{
if (keyboard_focus->handleUnicodeChar(uni_char, FALSE))
@@ -2434,8 +2406,8 @@ void LLViewerWindow::handleScrollWheel(S32 clicks)
void LLViewerWindow::moveCursorToCenter()
{
- S32 x = mVirtualWindowRect.getWidth() / 2;
- S32 y = mVirtualWindowRect.getHeight() / 2;
+ S32 x = mWorldViewRect.getWidth() / 2;
+ S32 y = mWorldViewRect.getHeight() / 2;
//on a forced move, all deltas get zeroed out to prevent jumping
mCurrentMousePoint.set(x,y);
@@ -2445,6 +2417,30 @@ void LLViewerWindow::moveCursorToCenter()
LLUI::setCursorPositionScreen(x, y);
}
+void LLViewerWindow::updateBottomTrayRect()
+{
+ if(LLBottomTray::instanceExists() && LLSideTray::instanceCreated())
+ {
+ S32 side_tray_width = 0;
+ if(LLSideTray::getInstance()->getVisible())
+ {
+ side_tray_width = LLSideTray::getInstance()->getTrayWidth();
+ }
+
+ LLBottomTray* bottom_tray = LLBottomTray::getInstance();
+ S32 right = llround((F32)mWindowRect.mRight / mDisplayScale.mV[VX]) - side_tray_width;
+
+ LLRect rc = bottom_tray->getRect();
+ if (right != rc.mRight)
+ {
+ rc.mRight = right;
+ bottom_tray->reshape(rc.getWidth(), rc.getHeight(), FALSE);
+ bottom_tray->setRect(rc);
+ mOnBottomTrayWidthChanged();
+ }
+ }
+}
+
//////////////////////////////////////////////////////////////////////
//
// Hover handlers
@@ -2452,103 +2448,141 @@ void LLViewerWindow::moveCursorToCenter()
// Update UI based on stored mouse position from mouse-move
// event processing.
-BOOL LLViewerWindow::handlePerFrameHover()
+void LLViewerWindow::updateUI()
{
static std::string last_handle_msg;
+ updateWorldViewRect();
+
+ //updateBottomTrayRect();
+
LLView::sMouseHandlerMessage.clear();
S32 x = mCurrentMousePoint.mX;
S32 y = mCurrentMousePoint.mY;
MASK mask = gKeyboard->currentMask(TRUE);
- //RN: fix for asynchronous notification of mouse leaving window not working
- LLCoordWindow mouse_pos;
- mWindow->getCursorPosition(&mouse_pos);
- if (mouse_pos.mX < 0 ||
- mouse_pos.mY < 0 ||
- mouse_pos.mX > mWindowRect.getWidth() ||
- mouse_pos.mY > mWindowRect.getHeight())
- {
- mMouseInWindow = FALSE;
- }
- else
+ if (gNoRender)
{
- mMouseInWindow = TRUE;
+ return;
}
+ updateMouseDelta();
+ updateKeyboardFocus();
- S32 dx = lltrunc((F32) (mCurrentMousePoint.mX - mLastMousePoint.mX) * LLUI::sGLScaleFactor.mV[VX]);
- S32 dy = lltrunc((F32) (mCurrentMousePoint.mY - mLastMousePoint.mY) * LLUI::sGLScaleFactor.mV[VY]);
+ BOOL handled = FALSE;
- LLVector2 mouse_vel;
+ BOOL handled_by_top_ctrl = FALSE;
+ LLUICtrl* top_ctrl = gFocusMgr.getTopCtrl();
+ LLMouseHandler* mouse_captor = gFocusMgr.getMouseCapture();
- if (gSavedSettings.getBOOL("MouseSmooth"))
- {
- static F32 fdx = 0.f;
- static F32 fdy = 0.f;
+ //build set of views containing mouse cursor by traversing UI hierarchy and testing
+ //screen rect against mouse cursor
+ view_handle_set_t mouse_hover_set;
- F32 amount = 16.f;
- fdx = fdx + ((F32) dx - fdx) * llmin(gFrameIntervalSeconds*amount,1.f);
- fdy = fdy + ((F32) dy - fdy) * llmin(gFrameIntervalSeconds*amount,1.f);
-
- mCurrentMouseDelta.set(llround(fdx), llround(fdy));
- mouse_vel.setVec(fdx,fdy);
- }
- else
+ // start at current mouse captor (if is a view) or UI root
+ LLView* root_view = NULL;
+ root_view = dynamic_cast<LLView*>(mouse_captor);
+ if (!root_view)
{
- mCurrentMouseDelta.set(dx, dy);
- mouse_vel.setVec((F32) dx, (F32) dy);
+ root_view = mRootView;
}
-
- mMouseVelocityStat.addValue(mouse_vel.magVec());
- if (gNoRender)
+ // aggregate visible views that contain mouse cursor in display order
+
+ // while the top_ctrl contains the mouse cursor, only it and its descendants will receive onMouseEnter events
+ if (top_ctrl && top_ctrl->calcScreenBoundingRect().pointInRect(x, y))
{
- return TRUE;
+ // iterator over contents of top_ctrl, and throw into mouse_hover_set
+ for (LLView::tree_iterator_t it = top_ctrl->beginTree();
+ it != top_ctrl->endTree();
+ ++it)
+ {
+ LLView* viewp = *it;
+ if (viewp->getVisible()
+ && viewp->calcScreenBoundingRect().pointInRect(x, y))
+ {
+ // we have a view that contains the mouse, add it to the set
+ mouse_hover_set.insert(viewp->getHandle());
+ }
+ else
+ {
+ // skip this view and all of its children
+ it.skipDescendants();
+ }
+ }
}
-
- // clean up current focus
- LLUICtrl* cur_focus = gFocusMgr.getKeyboardFocus();
- if (cur_focus)
+ else
{
- if (!cur_focus->isInVisibleChain() || !cur_focus->isInEnabledChain())
+ // walk UI tree in depth-first order
+ LLView::tree_iterator_t end_it;
+ for (LLView::tree_iterator_t it = root_view->beginTree();
+ it != end_it;
+ ++it)
{
- gFocusMgr.releaseFocusIfNeeded(cur_focus);
-
- LLUICtrl* parent = cur_focus->getParentUICtrl();
- const LLUICtrl* focus_root = cur_focus->findRootMostFocusRoot();
- while(parent)
+ LLView* viewp = *it;
+ // calculating the screen rect involves traversing the parent, so this is less than optimal
+ if (viewp->getVisible()
+ && viewp->calcScreenBoundingRect().pointInRect(x, y))
{
- if (parent->isCtrl() &&
- (parent->hasTabStop() || parent == focus_root) &&
- !parent->getIsChrome() &&
- parent->isInVisibleChain() &&
- parent->isInEnabledChain())
+
+ // if this view is mouse opaque, nothing behind it should be in mouse_hover_set
+ if (viewp->getMouseOpaque())
{
- if (!parent->focusFirstItem())
- {
- parent->setFocus(TRUE);
- }
- break;
+ // constrain further iteration to children of this widget
+ it = viewp->beginTree();
}
- parent = parent->getParentUICtrl();
+
+ // we have a view that contains the mouse, add it to the set
+ mouse_hover_set.insert(viewp->getHandle());
+ }
+ else
+ {
+ // skip this view and all of its children
+ it.skipDescendants();
}
}
- else if (cur_focus->isFocusRoot())
+ }
+
+ typedef std::vector<LLHandle<LLView> > view_handle_list_t;
+
+ // call onMouseEnter() on all views which contain the mouse cursor but did not before
+ view_handle_list_t mouse_enter_views;
+ std::set_difference(mouse_hover_set.begin(), mouse_hover_set.end(),
+ mMouseHoverViews.begin(), mMouseHoverViews.end(),
+ std::back_inserter(mouse_enter_views));
+ for (view_handle_list_t::iterator it = mouse_enter_views.begin();
+ it != mouse_enter_views.end();
+ ++it)
+ {
+ LLView* viewp = it->get();
+ if (viewp)
{
- // focus roots keep trying to delegate focus to their first valid descendant
- // this assumes that focus roots are not valid focus holders on their own
- cur_focus->focusFirstItem();
+ LLRect view_screen_rect = viewp->calcScreenRect();
+ viewp->onMouseEnter(x - view_screen_rect.mLeft, y - view_screen_rect.mBottom, mask);
}
}
- BOOL handled = FALSE;
+ // call onMouseLeave() on all views which no longer contain the mouse cursor
+ view_handle_list_t mouse_leave_views;
+ std::set_difference(mMouseHoverViews.begin(), mMouseHoverViews.end(),
+ mouse_hover_set.begin(), mouse_hover_set.end(),
+ std::back_inserter(mouse_leave_views));
+ for (view_handle_list_t::iterator it = mouse_leave_views.begin();
+ it != mouse_leave_views.end();
+ ++it)
+ {
+ LLView* viewp = it->get();
+ if (viewp)
+ {
+ LLRect view_screen_rect = viewp->calcScreenRect();
+ viewp->onMouseLeave(x - view_screen_rect.mLeft, y - view_screen_rect.mBottom, mask);
+ }
+ }
- BOOL handled_by_top_ctrl = FALSE;
- LLUICtrl* top_ctrl = gFocusMgr.getTopCtrl();
+ // store resulting hover set for next frame
+ swap(mMouseHoverViews, mouse_hover_set);
- LLMouseHandler* mouse_captor = gFocusMgr.getMouseCapture();
if( mouse_captor )
{
// Pass hover events to object capturing mouse events.
@@ -2638,168 +2672,298 @@ BOOL LLViewerWindow::handlePerFrameHover()
// Show a new tool tip (or update one that is alrady shown)
BOOL tool_tip_handled = FALSE;
std::string tool_tip_msg;
- F32 tooltip_delay = gSavedSettings.getF32( "ToolTipDelay" );
- //HACK: hack for tool-based tooltips which need to pop up more quickly
- //Also for show xui names as tooltips debug mode
- if ((mouse_captor && !mouse_captor->isView()) || LLUI::sShowXUINames)
- {
- tooltip_delay = gSavedSettings.getF32( "DragAndDropToolTipDelay" );
- }
- if( handled &&
- gMouseIdleTimer.getElapsedTimeF32() > tooltip_delay &&
- !mWindow->isCursorHidden() )
+ if( handled
+ && !mWindow->isCursorHidden()
+ && mToolTip)
{
LLRect screen_sticky_rect;
- LLMouseHandler *mh;
+ LLMouseHandler *tooltip_source = NULL;
S32 local_x, local_y;
if (mouse_captor)
{
mouse_captor->screenPointToLocal(x, y, &local_x, &local_y);
- mh = mouse_captor;
+ tooltip_source = mouse_captor;
}
else if (handled_by_top_ctrl)
{
top_ctrl->screenPointToLocal(x, y, &local_x, &local_y);
- mh = top_ctrl;
+ tooltip_source = top_ctrl;
}
else
{
local_x = x; local_y = y;
- mh = mRootView;
+ tooltip_source = mRootView;
+ }
+
+ F32 tooltip_delay = gSavedSettings.getF32( "ToolTipDelay" );
+ //HACK: hack for tool-based tooltips which need to pop up more quickly
+ //Also for show xui names as tooltips debug mode
+ if ((gFocusMgr.getMouseCapture()
+ && !gFocusMgr.getMouseCapture()->isView())
+ || LLUI::sShowXUINames)
+ {
+ tooltip_delay = gSavedSettings.getF32( "DragAndDropToolTipDelay" );
}
+
BOOL tooltip_vis = FALSE;
- if (shouldShowToolTipFor(mh))
+ if (shouldShowToolTipFor(tooltip_source))
{
- tool_tip_handled = mh->handleToolTip(local_x, local_y, tool_tip_msg, &screen_sticky_rect );
+ tool_tip_handled = tooltip_source->handleToolTip(local_x, local_y, tool_tip_msg, &screen_sticky_rect );
+ // if we actually got a tooltip back...
if( tool_tip_handled && !tool_tip_msg.empty() )
{
- mToolTipStickyRect = screen_sticky_rect;
- mToolTip->setWrappedText( tool_tip_msg, 200 );
- mToolTip->reshapeToFitText();
- mToolTip->setOrigin( x, y );
- LLRect virtual_window_rect(0, getWindowHeight(), getWindowWidth(), 0);
- mToolTip->translateIntoRect( virtual_window_rect, FALSE );
- tooltip_vis = TRUE;
+ if (mToolTip->getVisible() // already showing a tooltip
+ || gMouseIdleTimer.getElapsedTimeF32() > tooltip_delay) // mouse has been still long enough to show the tooltip
+ {
+ // if tooltip has changed or mouse has moved outside of "sticky" rectangle...
+ if (mLastToolTipMessage != tool_tip_msg
+ || !mToolTipStickyRect.pointInRect(x, y))
+ {
+ //...update "sticky" rect and tooltip position
+ mToolTipStickyRect = screen_sticky_rect;
+ mToolTip->setOrigin( x, y );
+ }
+
+ // remember this tooltip so we know when it changes
+ mLastToolTipMessage = tool_tip_msg;
+ mToolTip->setWrappedText( tool_tip_msg, 200 );
+ mToolTip->reshapeToFitText();
+ LLRect virtual_window_rect(0, getWindowHeight(), getWindowWidth(), 0);
+ mToolTip->translateIntoRect( virtual_window_rect, FALSE );
+ tooltip_vis = TRUE;
+ }
}
}
- if (mToolTip)
+ // HACK: assuming tooltip background is in ToolTipBGColor, perform fade out
+ LLColor4 bg_color = LLUIColorTable::instance().getColor( "ToolTipBgColor" );
+ if (tooltip_vis)
{
- mToolTip->setVisible( tooltip_vis );
+ mToolTipFadeTimer.stop();
+ mToolTip->setBackgroundColor(bg_color);
}
+ else
+ {
+ if (!mToolTipFadeTimer.getStarted())
+ {
+ mToolTipFadeTimer.start();
+ }
+ F32 tool_tip_fade_time = gSavedSettings.getF32("ToolTipFadeTime");
+ bg_color.mV[VALPHA] = clamp_rescale(mToolTipFadeTimer.getElapsedTimeF32(), 0.f, tool_tip_fade_time, bg_color.mV[VALPHA], 0.f);
+ mToolTip->setBackgroundColor(bg_color);
+ }
+
+ // above interpolation of bg_color alpha is guaranteed to reach 0.f exactly
+ mToolTip->setVisible( bg_color.mV[VALPHA] != 0.f );
}
- if (tool && tool != gToolNull && tool != LLToolCompInspect::getInstance() && tool != LLToolDragAndDrop::getInstance() && !gSavedSettings.getBOOL("FreezeTime"))
+ updateLayout();
+
+ mLastMousePoint = mCurrentMousePoint;
+
+ // cleanup unused selections when no modal dialogs are open
+ if (LLModalDialog::activeCount() == 0)
+ {
+ LLViewerParcelMgr::getInstance()->deselectUnused();
+ }
+
+ if (LLModalDialog::activeCount() == 0)
+ {
+ LLSelectMgr::getInstance()->deselectUnused();
+ }
+
+ updatePicking(x, y, mask);
+}
+
+void LLViewerWindow::updatePicking(S32 x, S32 y, MASK mask)
+{
+ // per frame picking - for tooltips and changing cursor over interactive objects
+ static S32 previous_x = -1;
+ static S32 previous_y = -1;
+ static BOOL mouse_moved_since_pick = FALSE;
+
+ if (gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_RAYCAST))
+ {
+ gDebugRaycastFaceHit = -1;
+ gDebugRaycastObject = cursorIntersect(-1, -1, 512.f, NULL, -1, FALSE,
+ &gDebugRaycastFaceHit,
+ &gDebugRaycastIntersection,
+ &gDebugRaycastTexCoord,
+ &gDebugRaycastNormal,
+ &gDebugRaycastBinormal);
+ }
+
+
+ if ((previous_x != x) || (previous_y != y))
+ mouse_moved_since_pick = TRUE;
+
+ BOOL do_pick = FALSE;
+
+ F32 picks_moving = gSavedSettings.getF32("PicksPerSecondMouseMoving");
+ if ((mouse_moved_since_pick) && (picks_moving > 0.0) && (mPickTimer.getElapsedTimeF32() > 1.0f / picks_moving))
+ {
+ do_pick = TRUE;
+ }
+
+ F32 picks_stationary = gSavedSettings.getF32("PicksPerSecondMouseStationary");
+ if ((!mouse_moved_since_pick) && (picks_stationary > 0.0) && (mPickTimer.getElapsedTimeF32() > 1.0f / picks_stationary))
+ {
+ do_pick = TRUE;
+ }
+
+ if (getCursorHidden())
+ {
+ do_pick = FALSE;
+ }
+
+ if(LLViewerMediaFocus::getInstance()->getFocus())
+ {
+ // When in-world media is in focus, pick every frame so that browser mouse-overs, dragging scrollbars, etc. work properly.
+ do_pick = TRUE;
+ }
+
+ if (do_pick)
+ {
+ mouse_moved_since_pick = FALSE;
+ mPickTimer.reset();
+ pickAsync(getCurrentMouseX(), getCurrentMouseY(), mask, hoverPickCallback, TRUE);
+ }
+
+ previous_x = x;
+ previous_y = y;
+}
+
+void LLViewerWindow::updateLayout()
+{
+ LLTool* tool = LLToolMgr::getInstance()->getCurrentTool();
+ if (gFloaterTools != NULL
+ && tool != NULL
+ && tool != gToolNull
+ && tool != LLToolCompInspect::getInstance()
+ && tool != LLToolDragAndDrop::getInstance()
+ && !gSavedSettings.getBOOL("FreezeTime"))
{
LLMouseHandler *captor = gFocusMgr.getMouseCapture();
// With the null, inspect, or drag and drop tool, don't muck
// with visibility.
- if (gFloaterTools->isMinimized() ||
- (tool != LLToolPie::getInstance() // not default tool
- && tool != LLToolCompGun::getInstance() // not coming out of mouselook
- && !mSuppressToolbox // not override in third person
- && LLToolMgr::getInstance()->getCurrentToolset() != gFaceEditToolset // not special mode
- && LLToolMgr::getInstance()->getCurrentToolset() != gMouselookToolset
- && (!captor || captor->isView())) // not dragging
- )
+ if (gFloaterTools->isMinimized()
+ || (tool != LLToolPie::getInstance() // not default tool
+ && tool != LLToolCompGun::getInstance() // not coming out of mouselook
+ && !mSuppressToolbox // not override in third person
+ && LLToolMgr::getInstance()->getCurrentToolset() != gFaceEditToolset // not special mode
+ && LLToolMgr::getInstance()->getCurrentToolset() != gMouselookToolset
+ && (!captor || captor->isView()))) // not dragging
{
// Force floater tools to be visible (unless minimized)
if (!gFloaterTools->getVisible())
{
- gFloaterTools->open(); /* Flawfinder: ignore */
+ gFloaterTools->openFloater();
}
// Update the location of the blue box tool popup
LLCoordGL select_center_screen;
- gFloaterTools->updatePopup( select_center_screen, mask );
+ gFloaterTools->updatePopup( select_center_screen, gKeyboard->currentMask(TRUE) );
}
else
{
gFloaterTools->setVisible(FALSE);
}
- // In the future we may wish to hide the tools menu unless you
- // are building. JC
- //gMenuBarView->setItemVisible("Tools", gFloaterTools->getVisible());
- //gMenuBarView->arrange();
+ gMenuBarView->setItemVisible("BuildTools", gFloaterTools->getVisible());
}
- if (gToolBar)
+
+ // Always update console
+ if(gConsole)
{
- gToolBar->refresh();
+ LLRect console_rect = getChatConsoleRect();
+ gConsole->reshape(console_rect.getWidth(), console_rect.getHeight());
+ gConsole->setRect(console_rect);
}
+}
- if (gChatBar)
+void LLViewerWindow::updateMouseDelta()
+{
+ S32 dx = lltrunc((F32) (mCurrentMousePoint.mX - mLastMousePoint.mX) * LLUI::sGLScaleFactor.mV[VX]);
+ S32 dy = lltrunc((F32) (mCurrentMousePoint.mY - mLastMousePoint.mY) * LLUI::sGLScaleFactor.mV[VY]);
+
+ //RN: fix for asynchronous notification of mouse leaving window not working
+ LLCoordWindow mouse_pos;
+ mWindow->getCursorPosition(&mouse_pos);
+ if (mouse_pos.mX < 0 ||
+ mouse_pos.mY < 0 ||
+ mouse_pos.mX > mWindowRect.getWidth() ||
+ mouse_pos.mY > mWindowRect.getHeight())
{
- gChatBar->refresh();
+ mMouseInWindow = FALSE;
}
-
- if (gOverlayBar)
+ else
{
- gOverlayBar->refresh();
+ mMouseInWindow = TRUE;
}
- // Update rectangles for the various toolbars
- if (gOverlayBar && gNotifyBoxView && gConsole && gToolBar)
+ LLVector2 mouse_vel;
+
+ if (gSavedSettings.getBOOL("MouseSmooth"))
{
- LLRect bar_rect(-1, STATUS_BAR_HEIGHT, getWindowWidth()+1, -1);
+ static F32 fdx = 0.f;
+ static F32 fdy = 0.f;
- LLRect notify_box_rect = gNotifyBoxView->getRect();
- notify_box_rect.mBottom = bar_rect.mBottom;
- gNotifyBoxView->reshape(notify_box_rect.getWidth(), notify_box_rect.getHeight());
- gNotifyBoxView->setRect(notify_box_rect);
+ F32 amount = 16.f;
+ fdx = fdx + ((F32) dx - fdx) * llmin(gFrameIntervalSeconds*amount,1.f);
+ fdy = fdy + ((F32) dy - fdy) * llmin(gFrameIntervalSeconds*amount,1.f);
- // make sure floaters snap to visible rect by adjusting floater view rect
- LLRect floater_rect = gFloaterView->getRect();
- if (floater_rect.mBottom != bar_rect.mBottom+1)
- {
- floater_rect.mBottom = bar_rect.mBottom+1;
- // Don't bounce the floaters up and down.
- gFloaterView->reshapeFloater(floater_rect.getWidth(), floater_rect.getHeight(),
- TRUE, ADJUST_VERTICAL_NO);
- gFloaterView->setRect(floater_rect);
- }
+ mCurrentMouseDelta.set(llround(fdx), llround(fdy));
+ mouse_vel.setVec(fdx,fdy);
+ }
+ else
+ {
+ mCurrentMouseDelta.set(dx, dy);
+ mouse_vel.setVec((F32) dx, (F32) dy);
+ }
+
+ mMouseVelocityStat.addValue(mouse_vel.magVec());
+}
- // snap floaters to top of chat bar/button strip
- LLView* chatbar_and_buttons = gOverlayBar->getChild<LLView>("chatbar_and_buttons", TRUE);
- // find top of chatbar and state buttons, if either are visible
- if (chatbar_and_buttons && !chatbar_and_buttons->getLocalBoundingRect().isNull())
- {
- // convert top/left corner of chatbar/buttons container to gFloaterView-relative coordinates
- S32 top, left;
- chatbar_and_buttons->localPointToOtherView(
- chatbar_and_buttons->getLocalBoundingRect().mLeft,
- chatbar_and_buttons->getLocalBoundingRect().mTop,
- &left,
- &top,
- gFloaterView);
- gFloaterView->setSnapOffsetBottom(top);
- }
- else if (gToolBar->getVisible())
+void LLViewerWindow::updateKeyboardFocus()
+{
+ // clean up current focus
+ LLUICtrl* cur_focus = dynamic_cast<LLUICtrl*>(gFocusMgr.getKeyboardFocus());
+ if (cur_focus)
+ {
+ if (!cur_focus->isInVisibleChain() || !cur_focus->isInEnabledChain())
{
- S32 top, left;
- gToolBar->localPointToOtherView(
- gToolBar->getLocalBoundingRect().mLeft,
- gToolBar->getLocalBoundingRect().mTop,
- &left,
- &top,
- gFloaterView);
- gFloaterView->setSnapOffsetBottom(top);
+ // don't release focus, just reassign so that if being given
+ // to a sibling won't call onFocusLost on all the ancestors
+ // gFocusMgr.releaseFocusIfNeeded(cur_focus);
+
+ LLUICtrl* parent = cur_focus->getParentUICtrl();
+ const LLUICtrl* focus_root = cur_focus->findRootMostFocusRoot();
+ while(parent)
+ {
+ if (parent->isCtrl() &&
+ (parent->hasTabStop() || parent == focus_root) &&
+ !parent->getIsChrome() &&
+ parent->isInVisibleChain() &&
+ parent->isInEnabledChain())
+ {
+ if (!parent->focusFirstItem())
+ {
+ parent->setFocus(TRUE);
+ }
+ break;
+ }
+ parent = parent->getParentUICtrl();
+ }
}
- else
+ else if (cur_focus->isFocusRoot())
{
- gFloaterView->setSnapOffsetBottom(0);
+ // focus roots keep trying to delegate focus to their first valid descendant
+ // this assumes that focus roots are not valid focus holders on their own
+ cur_focus->focusFirstItem();
}
-
- // Always update console
- LLRect console_rect = getChatConsoleRect();
- console_rect.mBottom = gHUDView->getRect().mBottom + getChatConsoleBottomPad();
- gConsole->reshape(console_rect.getWidth(), console_rect.getHeight());
- gConsole->setRect(console_rect);
}
- mLastMousePoint = mCurrentMousePoint;
-
// last ditch force of edit menu to selection manager
if (LLEditMenuHandler::gEditMenuHandler == NULL && LLSelectMgr::getInstance()->getSelection()->getObjectCount())
{
@@ -2832,78 +2996,47 @@ BOOL LLViewerWindow::handlePerFrameHover()
gFloaterView->syncFloaterTabOrder();
}
- if (gSavedSettings.getBOOL("ChatBarStealsFocus")
- && gChatBar
- && gFocusMgr.getKeyboardFocus() == NULL
- && gChatBar->isInVisibleChain())
- {
- gChatBar->startChat(NULL);
- }
-
- // cleanup unused selections when no modal dialogs are open
- if (LLModalDialog::activeCount() == 0)
- {
- LLViewerParcelMgr::getInstance()->deselectUnused();
- }
-
- if (LLModalDialog::activeCount() == 0)
- {
- LLSelectMgr::getInstance()->deselectUnused();
- }
-
- if (gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_RAYCAST))
- {
- gDebugRaycastFaceHit = -1;
- gDebugRaycastObject = cursorIntersect(-1, -1, 512.f, NULL, -1, FALSE,
- &gDebugRaycastFaceHit,
- &gDebugRaycastIntersection,
- &gDebugRaycastTexCoord,
- &gDebugRaycastNormal,
- &gDebugRaycastBinormal);
- }
-
-
- // per frame picking - for tooltips and changing cursor over interactive objects
- static S32 previous_x = -1;
- static S32 previous_y = -1;
- static BOOL mouse_moved_since_pick = FALSE;
+ if(LLSideTray::instanceCreated())//just getInstance will create sidetray. we don't want this
+ LLSideTray::getInstance()->highlightFocused();
+}
- if ((previous_x != x) || (previous_y != y))
- mouse_moved_since_pick = TRUE;
+void LLViewerWindow::updateWorldViewRect(bool use_full_window)
+{
+ if (!LLSideTray::instanceCreated()) return;
- BOOL do_pick = FALSE;
+ // start off using whole window to render world
+ LLRect new_world_rect = mWindowRect;
- F32 picks_moving = gSavedSettings.getF32("PicksPerSecondMouseMoving");
- if ((mouse_moved_since_pick) && (picks_moving > 0.0) && (mPickTimer.getElapsedTimeF32() > 1.0f / picks_moving))
+ if (use_full_window == false)
{
- do_pick = TRUE;
- }
-
- F32 picks_stationary = gSavedSettings.getF32("PicksPerSecondMouseStationary");
- if ((!mouse_moved_since_pick) && (picks_stationary > 0.0) && (mPickTimer.getElapsedTimeF32() > 1.0f / picks_stationary))
- {
- do_pick = TRUE;
- }
+ // pull in right side of world view based on sidetray
+ LLSideTray* sidetray = LLSideTray::getInstance();
+ if (sidetray->getVisible())
+ {
+ new_world_rect.mRight -= llround((F32)sidetray->getTrayWidth() * mDisplayScale.mV[VX]);
+ }
- if (getCursorHidden())
- {
- do_pick = FALSE;
+ // push top of world view below nav bar
+ if (LLNavigationBar::getInstance()->getVisible())
+ {
+ LLNavigationBar* barp = LLNavigationBar::getInstance();
+ LLRect nav_bar_rect;
+ if(barp->localRectToOtherView(barp->getLocalRect(), &nav_bar_rect, mRootView))
+ {
+ new_world_rect.mTop = llround((F32)LLNavigationBar::getInstance()->getRect().mBottom * mDisplayScale.mV[VY]);
+ }
+ }
}
- if (do_pick)
+ if (mWorldViewRect != new_world_rect)
{
- mouse_moved_since_pick = FALSE;
- mPickTimer.reset();
- pickAsync(getCurrentMouseX(), getCurrentMouseY(), mask, hoverPickCallback, TRUE);
+ mWorldViewRect = new_world_rect;
+ gResizeScreenTexture = TRUE;
+ LLViewerCamera::getInstance()->setViewHeightInPixels( mWorldViewRect.getHeight() );
+ LLViewerCamera::getInstance()->setAspect( getWorldViewAspectRatio() );
}
-
- previous_x = x;
- previous_y = y;
-
- return handled;
}
-
/* static */
void LLViewerWindow::hoverPickCallback(const LLPickInfo& pick_info)
{
@@ -3164,7 +3297,7 @@ void LLViewerWindow::pickAsync(S32 x, S32 y_from_bot, MASK mask, void (*callback
}
// push back pick info object
- BOOL in_build_mode = gFloaterTools && gFloaterTools->getVisible();
+ BOOL in_build_mode = LLFloaterReg::instanceVisible("build");
if (in_build_mode || LLDrawPoolAlpha::sShowDebugAlpha)
{
// build mode allows interaction with all transparent objects
@@ -3179,10 +3312,10 @@ void LLViewerWindow::pickAsync(S32 x, S32 y_from_bot, MASK mask, void (*callback
{
mPickScreenRegion.setCenterAndSize(x, y_from_bot, PICK_DIAMETER, PICK_DIAMETER);
- if (mPickScreenRegion.mLeft < 0) mPickScreenRegion.translate(-mPickScreenRegion.mLeft, 0);
- if (mPickScreenRegion.mBottom < 0) mPickScreenRegion.translate(0, -mPickScreenRegion.mBottom);
- if (mPickScreenRegion.mRight > mWindowRect.getWidth() ) mPickScreenRegion.translate(mWindowRect.getWidth() - mPickScreenRegion.mRight, 0);
- if (mPickScreenRegion.mTop > mWindowRect.getHeight() ) mPickScreenRegion.translate(0, mWindowRect.getHeight() - mPickScreenRegion.mTop);
+ if (mPickScreenRegion.mLeft < mWorldViewRect.mLeft) mPickScreenRegion.translate(mWorldViewRect.mLeft - mPickScreenRegion.mLeft, 0);
+ if (mPickScreenRegion.mBottom < mWorldViewRect.mBottom) mPickScreenRegion.translate(0, mWorldViewRect.mBottom - mPickScreenRegion.mBottom);
+ if (mPickScreenRegion.mRight > mWorldViewRect.mRight ) mPickScreenRegion.translate(mWorldViewRect.mRight - mPickScreenRegion.mRight, 0);
+ if (mPickScreenRegion.mTop > mWorldViewRect.mTop ) mPickScreenRegion.translate(0, mWorldViewRect.mTop - mPickScreenRegion.mTop);
}
// set frame buffer region for picking results
@@ -3207,80 +3340,9 @@ void LLViewerWindow::schedulePick(LLPickInfo& pick_info)
return;
}
- llassert_always(pick_info.mScreenRegion.notNull());
+ llassert_always(pick_info.mScreenRegion.notEmpty());
mPicks.push_back(pick_info);
- /*S32 scaled_x = llround((F32)pick_info.mMousePt.mX * mDisplayScale.mV[VX]);
- S32 scaled_y = llround((F32)pick_info.mMousePt.mY * mDisplayScale.mV[VY]);
-
- // Default to not hitting anything
- LLCamera pick_camera;
- pick_camera.setOrigin(LLViewerCamera::getInstance()->getOrigin());
- pick_camera.setOriginAndLookAt(LLViewerCamera::getInstance()->getOrigin(),
- LLViewerCamera::getInstance()->getUpAxis(),
- LLViewerCamera::getInstance()->getOrigin() + mouseDirectionGlobal(pick_info.mMousePt.mX, pick_info.mMousePt.mY));
- pick_camera.setView(0.5f*DEG_TO_RAD);
- pick_camera.setNear(LLViewerCamera::getInstance()->getNear());
- pick_camera.setFar(LLViewerCamera::getInstance()->getFar());
- pick_camera.setAspect(1.f);
-
- // save our drawing state
- // *TODO: should we be saving using the new method here using
- // glh_get_current_projection/glh_set_current_projection? -brad
- glMatrixMode(GL_MODELVIEW);
- glPushMatrix();
- glLoadIdentity();
-
- glMatrixMode(GL_PROJECTION);
- glPushMatrix();
- glLoadIdentity();
-
- // clear work area
- {
- LLGLState scissor_state(GL_SCISSOR_TEST);
- scissor_state.enable();
- glScissor(pick_info.mScreenRegion.mLeft, pick_info.mScreenRegion.mBottom, pick_info.mScreenRegion.getWidth(), pick_info.mScreenRegion.getHeight());
- glClearColor(0.f, 0.f, 0.f, 0.f);
- glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
- //glClear(GL_COLOR_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
- }
-
- // build perspective transform and picking viewport
- // Perform pick on a PICK_DIAMETER x PICK_DIAMETER pixel region around cursor point.
- // Don't limit the select distance for this pick.
- LLViewerCamera::getInstance()->setPerspective(FOR_SELECTION, scaled_x - PICK_HALF_WIDTH, scaled_y - PICK_HALF_WIDTH, PICK_DIAMETER, PICK_DIAMETER, FALSE);
-
- // render for object picking
-
- // make viewport big enough to handle antialiased frame buffers
- gGLViewport[0] = pick_info.mScreenRegion.mLeft;
- gGLViewport[1] = pick_info.mScreenRegion.mBottom;
- gGLViewport[2] = pick_info.mScreenRegion.getWidth();
- gGLViewport[3] = pick_info.mScreenRegion.getHeight();
-
- glViewport(gGLViewport[0], gGLViewport[1], gGLViewport[2], gGLViewport[3]);
- LLViewerCamera::updateFrustumPlanes(pick_camera);
- stop_glerror();
-
- // Draw the objects so the user can select them.
- // The starting ID is 1, since land is zero.
- LLRect pick_region;
- pick_region.setOriginAndSize(pick_info.mMousePt.mX - PICK_HALF_WIDTH,
- pick_info.mMousePt.mY - PICK_HALF_WIDTH, PICK_DIAMETER, PICK_DIAMETER);
- gObjectList.renderObjectsForSelect(pick_camera, pick_region, FALSE, pick_info.mPickTransparent);
-
- stop_glerror();
-
- // restore drawing state
- glMatrixMode(GL_PROJECTION);
- glPopMatrix();
- glMatrixMode(GL_MODELVIEW);
- glPopMatrix();
-
- setup3DRender();
- setup2DRender();
- setupViewport();*/
-
// delay further event processing until we receive results of pick
mWindow->delayInputProcessing();
}
@@ -3449,16 +3511,16 @@ LLVector3 LLViewerWindow::mouseDirectionGlobal(const S32 x, const S32 y) const
// find vertical field of view
F32 fov = LLViewerCamera::getInstance()->getView();
- // find screen resolution
- S32 height = getWindowHeight();
- S32 width = getWindowWidth();
+ // find world view center in scaled ui coordinates
+ F32 center_x = (F32)getWorldViewRect().getCenterX() / mDisplayScale.mV[VX];
+ F32 center_y = (F32)getWorldViewRect().getCenterY() / mDisplayScale.mV[VY];
// calculate pixel distance to screen
- F32 distance = (height / 2.f) / (tan(fov / 2.f));
+ F32 distance = ((F32)getWorldViewHeight() / (mDisplayScale.mV[VY] * 2.f)) / (tan(fov / 2.f));
// calculate click point relative to middle of screen
- F32 click_x = x - width / 2.f;
- F32 click_y = y - height / 2.f;
+ F32 click_x = x - center_x;
+ F32 click_y = y - center_y;
// compute mouse vector
LLVector3 mouse_vector = distance * LLViewerCamera::getInstance()->getAtAxis()
@@ -3473,12 +3535,15 @@ LLVector3 LLViewerWindow::mouseDirectionGlobal(const S32 x, const S32 y) const
LLVector3 LLViewerWindow::mousePointHUD(const S32 x, const S32 y) const
{
// find screen resolution
- S32 height = getWindowHeight();
- S32 width = getWindowWidth();
+ S32 height = llround((F32)getWorldViewHeight() / mDisplayScale.mV[VY]);
+
+ // find world view center
+ F32 center_x = (F32)getWorldViewRect().getCenterX() / mDisplayScale.mV[VX];
+ F32 center_y = (F32)getWorldViewRect().getCenterY() / mDisplayScale.mV[VY];
// remap with uniform scale (1/height) so that top is -0.5, bottom is +0.5
- F32 hud_x = -((F32)x - (F32)width/2.f) / height;
- F32 hud_y = ((F32)y - (F32)height/2.f) / height;
+ F32 hud_x = -((F32)x - center_x) / height;
+ F32 hud_y = ((F32)y - center_y) / height;
return LLVector3(0.f, hud_x/gAgent.mHUDCurZoom, hud_y/gAgent.mHUDCurZoom);
}
@@ -3492,12 +3557,16 @@ LLVector3 LLViewerWindow::mouseDirectionCamera(const S32 x, const S32 y) const
F32 fov_width = fov_height * LLViewerCamera::getInstance()->getAspect();
// find screen resolution
- S32 height = getWindowHeight();
- S32 width = getWindowWidth();
+ S32 height = llround((F32)getWorldViewHeight() / mDisplayScale.mV[VY]);
+ S32 width = llround((F32)getWorldViewWidth() / mDisplayScale.mV[VX]);
+
+ // find world view center
+ F32 center_x = (F32)getWorldViewRect().getCenterX() / mDisplayScale.mV[VX];
+ F32 center_y = (F32)getWorldViewRect().getCenterY() / mDisplayScale.mV[VY];
// calculate click point relative to middle of screen
- F32 click_x = (((F32)x / (F32)width) - 0.5f) * fov_width * -1.f;
- F32 click_y = (((F32)y / (F32)height) - 0.5f) * fov_height;
+ F32 click_x = (((F32)x - center_x) / (F32)width) * fov_width * -1.f;
+ F32 click_y = (((F32)y - center_y) / (F32)height) * fov_height;
// compute mouse vector
LLVector3 mouse_vector = LLVector3(0.f, 0.f, -1.f);
@@ -3841,7 +3910,6 @@ BOOL LLViewerWindow::thumbnailSnapshot(LLImageRaw *raw, S32 preview_width, S32 p
glClearColor(0.f, 0.f, 0.f, 0.f);
glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
setup3DRender();
- setupViewport();
LLFontGL::setFontDisplay(FALSE) ;
LLHUDText::setDisplayText(FALSE) ;
@@ -3902,7 +3970,6 @@ BOOL LLViewerWindow::thumbnailSnapshot(LLImageRaw *raw, S32 preview_width, S32 p
mDisplayScale.setVec(display_scale) ;
mWindowRect = window_rect;
setup3DRender();
- setupViewport();
gDisplaySwapBuffers = FALSE;
gDepthDirty = TRUE;
@@ -3946,6 +4013,9 @@ BOOL LLViewerWindow::rawSnapshot(LLImageRaw *raw, S32 image_width, S32 image_hei
// PRE SNAPSHOT
gDisplaySwapBuffers = FALSE;
+ // if not showing ui, use full window to render world view
+ updateWorldViewRect(!show_ui);
+
glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
setCursor(UI_CURSOR_WAIT);
@@ -4070,7 +4140,6 @@ BOOL LLViewerWindow::rawSnapshot(LLImageRaw *raw, S32 image_width, S32 image_hei
LLViewerCamera::getInstance()->setZoomParameters(scale_factor, subimage_x+(subimage_y*llceil(scale_factor)));
setup3DRender();
- setupViewport();
gObjectList.renderPickList(gViewerWindow->getVirtualWindowRect(), FALSE, FALSE);
}
else
@@ -4214,33 +4283,21 @@ void LLViewerWindow::destroyWindow()
void LLViewerWindow::drawMouselookInstructions()
{
- // Draw instructions for mouselook ("Press ESC to leave Mouselook" in a box at the top of the screen.)
- const std::string instructions = "Press ESC to leave Mouselook.";
- const LLFontGL* font = LLResMgr::getInstance()->getRes( LLFONT_SANSSERIF );
-
- const S32 INSTRUCTIONS_PAD = 5;
- LLRect instructions_rect;
- instructions_rect.setLeftTopAndSize(
- INSTRUCTIONS_PAD,
- getWindowHeight() - INSTRUCTIONS_PAD,
- font->getWidth( instructions ) + 2 * INSTRUCTIONS_PAD,
- llround(font->getLineHeight() + 2 * INSTRUCTIONS_PAD));
-
- {
- gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
- gGL.color4f( 0.9f, 0.9f, 0.9f, 1.0f );
- gl_rect_2d( instructions_rect );
- }
+ // Draw instructions for mouselook ("Press ESC to return to World View" partially transparent at the bottom of the screen.)
+ const std::string instructions = LLTrans::getString("LeaveMouselook");
+ const LLFontGL* font = LLFontGL::getFont(LLFontDescriptor("SansSerif", "Huge", LLFontGL::BOLD));
+ //to be on top of Bottom bar when it is opened
+ const S32 INSTRUCTIONS_PAD = 50;
+
font->renderUTF8(
instructions, 0,
- instructions_rect.mLeft + INSTRUCTIONS_PAD,
- instructions_rect.mTop - INSTRUCTIONS_PAD,
- LLColor4( 0.0f, 0.0f, 0.0f, 1.f ),
- LLFontGL::LEFT, LLFontGL::TOP);
+ mWorldViewRect.getCenterX(),
+ mWorldViewRect.mBottom + INSTRUCTIONS_PAD,
+ LLColor4( 0.0f, 0.0f, 0.0f, 0.6f ),
+ LLFontGL::HCENTER, LLFontGL::TOP);
}
-
S32 LLViewerWindow::getWindowHeight() const
{
return mVirtualWindowRect.getHeight();
@@ -4251,6 +4308,46 @@ S32 LLViewerWindow::getWindowWidth() const
return mVirtualWindowRect.getWidth();
}
+void* LLViewerWindow::getPlatformWindow() const
+{
+ return mWindow->getPlatformWindow();
+}
+
+void* LLViewerWindow::getMediaWindow() const
+{
+ return mWindow->getMediaWindow();
+}
+
+void LLViewerWindow::focusClient() const
+{
+ return mWindow->focusClient();
+}
+
+LLRootView* LLViewerWindow::getRootView() const
+{
+ return mRootView;
+}
+
+LLRect LLViewerWindow::getVirtualWorldViewRect() const
+{
+ LLRect world_view_rect = mWorldViewRect;
+ world_view_rect.mLeft = llround((F32)world_view_rect.mLeft / mDisplayScale.mV[VX]);
+ world_view_rect.mRight = llround((F32)world_view_rect.mRight / mDisplayScale.mV[VX]);
+ world_view_rect.mBottom = llround((F32)world_view_rect.mBottom / mDisplayScale.mV[VY]);
+ world_view_rect.mTop = llround((F32)world_view_rect.mTop / mDisplayScale.mV[VY]);
+ return world_view_rect;
+}
+
+S32 LLViewerWindow::getWorldViewHeight() const
+{
+ return mWorldViewRect.getHeight();
+}
+
+S32 LLViewerWindow::getWorldViewWidth() const
+{
+ return mWorldViewRect.getWidth();
+}
+
S32 LLViewerWindow::getWindowDisplayHeight() const
{
return mWindowRect.getHeight();
@@ -4261,27 +4358,48 @@ S32 LLViewerWindow::getWindowDisplayWidth() const
return mWindowRect.getWidth();
}
-void LLViewerWindow::setupViewport(S32 x_offset, S32 y_offset)
+void LLViewerWindow::setup2DRender()
+{
+ // setup ortho camera
+ gl_state_for_2d(mWindowRect.getWidth(), mWindowRect.getHeight());
+ setup2DViewport();
+}
+
+void LLViewerWindow::setup2DViewport(S32 x_offset, S32 y_offset)
{
- gGLViewport[0] = x_offset;
- gGLViewport[1] = y_offset;
+ gGLViewport[0] = mWindowRect.mLeft + x_offset;
+ gGLViewport[1] = mWindowRect.mBottom + y_offset;
gGLViewport[2] = mWindowRect.getWidth();
gGLViewport[3] = mWindowRect.getHeight();
glViewport(gGLViewport[0], gGLViewport[1], gGLViewport[2], gGLViewport[3]);
}
+
void LLViewerWindow::setup3DRender()
{
- LLViewerCamera::getInstance()->setPerspective(NOT_FOR_SELECTION, 0, 0, mWindowRect.getWidth(), mWindowRect.getHeight(), FALSE, LLViewerCamera::getInstance()->getNear(), MAX_FAR_CLIP*2.f);
+ // setup perspective camera
+ LLViewerCamera::getInstance()->setPerspective(NOT_FOR_SELECTION, mWorldViewRect.mLeft, mWorldViewRect.mBottom, mWorldViewRect.getWidth(), mWorldViewRect.getHeight(), FALSE, LLViewerCamera::getInstance()->getNear(), MAX_FAR_CLIP*2.f);
+ setup3DViewport();
}
-void LLViewerWindow::setup2DRender()
+void LLViewerWindow::setup3DViewport(S32 x_offset, S32 y_offset)
{
- gl_state_for_2d(mWindowRect.getWidth(), mWindowRect.getHeight());
+ if (LLRenderTarget::getCurrentBoundTarget() != NULL)
+ {
+ // don't use translation component of mWorldViewRect, as we are already in a properly sized render target
+ gGLViewport[0] = x_offset;
+ gGLViewport[1] = y_offset;
+ }
+ else
+ {
+ gGLViewport[0] = mWorldViewRect.mLeft + x_offset;
+ gGLViewport[1] = mWorldViewRect.mBottom + y_offset;
+ }
+ gGLViewport[2] = mWorldViewRect.getWidth();
+ gGLViewport[3] = mWorldViewRect.getHeight();
+ glViewport(gGLViewport[0], gGLViewport[1], gGLViewport[2], gGLViewport[3]);
}
-
-
void LLViewerWindow::setShowProgress(const BOOL show)
{
if (mProgressView)
@@ -4295,7 +4413,6 @@ BOOL LLViewerWindow::getShowProgress() const
return (mProgressView && mProgressView->getVisible());
}
-
void LLViewerWindow::moveProgressViewToFront()
{
if( mProgressView && mRootView )
@@ -4356,7 +4473,7 @@ void LLViewerWindow::stopGL(BOOL save_state)
//Note: --bao
//if not necessary, do not change the order of the function calls in this function.
//if change something, make sure it will not break anything.
- //especially be careful to put anything behind gImageList.destroyGL(save_state);
+ //especially be careful to put anything behind gTextureList.destroyGL(save_state);
if (!gGLManager.mIsDisabled)
{
llinfos << "Shutting down GL..." << llendl;
@@ -4381,7 +4498,7 @@ void LLViewerWindow::stopGL(BOOL save_state)
LLVOAvatar::destroyGL();
stop_glerror();
- LLDynamicTexture::destroyGL();
+ LLViewerDynamicTexture::destroyGL();
stop_glerror();
if (gPipeline.isInit())
@@ -4399,9 +4516,9 @@ void LLViewerWindow::stopGL(BOOL save_state)
gPostProcess->invalidate();
}
- gImageList.destroyGL(save_state);
+ gTextureList.destroyGL(save_state);
stop_glerror();
-
+
gGLManager.mIsDisabled = TRUE;
stop_glerror();
@@ -4414,7 +4531,7 @@ void LLViewerWindow::restoreGL(const std::string& progress_message)
//Note: --bao
//if not necessary, do not change the order of the function calls in this function.
//if change something, make sure it will not break anything.
- //especially, be careful to put something before gImageList.restoreGL();
+ //especially, be careful to put something before gTextureList.restoreGL();
if (gGLManager.mIsDisabled)
{
llinfos << "Restoring GL..." << llendl;
@@ -4422,8 +4539,9 @@ void LLViewerWindow::restoreGL(const std::string& progress_message)
initGLDefaults();
LLGLState::restoreGL();
- gImageList.restoreGL();
-
+
+ gTextureList.restoreGL();
+
// for future support of non-square pixels, and fonts that are properly stretched
//LLFontGL::destroyDefaultFonts();
initFonts();
@@ -4434,7 +4552,7 @@ void LLViewerWindow::restoreGL(const std::string& progress_message)
LLManipTranslate::restoreGL();
gBumpImageList.restoreGL();
- LLDynamicTexture::restoreGL();
+ LLViewerDynamicTexture::restoreGL();
LLVOAvatar::restoreGL();
gResizeScreenTexture = TRUE;
@@ -4463,12 +4581,16 @@ void LLViewerWindow::restoreGL(const std::string& progress_message)
void LLViewerWindow::initFonts(F32 zoom_factor)
{
LLFontGL::destroyAllGL();
- LLFontGL::initDefaultFonts( gSavedSettings.getF32("FontScreenDPI"),
+ // Initialize with possibly different zoom factor
+ LLFontGL::initClass( gSavedSettings.getF32("FontScreenDPI"),
mDisplayScale.mV[VX] * zoom_factor,
mDisplayScale.mV[VY] * zoom_factor,
gDirUtilp->getAppRODataDir(),
- LLUICtrlFactory::getXUIPaths());
+ LLUI::getXUIPaths());
+ // Force font reloads, which can be very slow
+ LLFontGL::loadDefaultFonts();
}
+
void LLViewerWindow::toggleFullscreen(BOOL show_progress)
{
if (mWindow)
@@ -4501,6 +4623,11 @@ void LLViewerWindow::getTargetWindow(BOOL& fullscreen, S32& width, S32& height)
}
}
+void LLViewerWindow::requestResolutionUpdate()
+{
+ mResDirty = true;
+}
+
void LLViewerWindow::requestResolutionUpdate(bool fullscreen_checked)
{
mResDirty = true;
@@ -4534,7 +4661,7 @@ BOOL LLViewerWindow::checkSettings()
// force aspect ratio
if (mIsFullscreenChecked)
{
- LLViewerCamera::getInstance()->setAspect( getDisplayAspectRatio() );
+ LLViewerCamera::getInstance()->setAspect( getWorldViewAspectRatio() );
}
mResDirty = false;
@@ -4605,9 +4732,9 @@ BOOL LLViewerWindow::changeDisplaySettings(BOOL fullscreen, LLCoordScreen size,
BOOL was_maximized = gSavedSettings.getBOOL("WindowMaximized");
mWantFullscreen = fullscreen;
mShowFullscreenProgress = show_progress_bar;
- gSavedSettings.setBOOL("FullScreen", mWantFullscreen);
+ gSavedSettings.setBOOL("WindowFullScreen", mWantFullscreen);
- gResizeScreenTexture = TRUE;
+ //gResizeScreenTexture = TRUE;
BOOL old_fullscreen = mWindow->getFullscreen();
if (!old_fullscreen && fullscreen && !LLStartUp::canGoFullscreen())
@@ -4635,12 +4762,12 @@ BOOL LLViewerWindow::changeDisplaySettings(BOOL fullscreen, LLCoordScreen size,
}
// Close floaters that don't handle settings change
- LLFloaterSnapshot::hide(0);
+ LLFloaterReg::hideInstance("snapshot");
BOOL result_first_try = FALSE;
BOOL result_second_try = FALSE;
- LLUICtrl* keyboard_focus = gFocusMgr.getKeyboardFocus();
+ LLFocusableElement* keyboard_focus = gFocusMgr.getKeyboardFocus();
send_agent_pause();
llinfos << "Stopping GL during changeDisplaySettings" << llendl;
stopGL();
@@ -4753,6 +4880,21 @@ F32 LLViewerWindow::getDisplayAspectRatio() const
}
+F32 LLViewerWindow::getWorldViewAspectRatio() const
+{
+ F32 world_aspect = (F32)mWorldViewRect.getWidth() / (F32)mWorldViewRect.getHeight();
+ //F32 window_aspect = (F32)mWindowRect.getWidth() / (F32)mWindowRect.getHeight();
+ if (mWindow->getFullscreen())
+ {
+ return world_aspect * mWindow->getPixelAspectRatio();
+ }
+ else
+ {
+ llinfos << "World aspect ratio: " << world_aspect << llendl;
+ return world_aspect;
+ }
+}
+
void LLViewerWindow::drawPickBuffer() const
{
mHoverPick.drawPickBuffer();
@@ -4798,8 +4940,9 @@ void LLViewerWindow::calcDisplayScale()
S32 LLViewerWindow::getChatConsoleBottomPad()
{
S32 offset = 0;
- if( gToolBar && gToolBar->getVisible() )
- offset += TOOL_BAR_HEIGHT;
+
+ if(LLBottomTray::instanceExists())
+ offset += LLBottomTray::getInstance()->getRect().getHeight();
return offset;
}
@@ -4818,7 +4961,9 @@ LLRect LLViewerWindow::getChatConsoleRect()
console_rect.mLeft += CONSOLE_PADDING_LEFT;
- if (gSavedSettings.getBOOL("ChatFullWidth"))
+ static const BOOL CHAT_FULL_WIDTH = gSavedSettings.getBOOL("ChatFullWidth");
+
+ if (CHAT_FULL_WIDTH)
{
console_rect.mRight -= CONSOLE_PADDING_RIGHT;
}
@@ -4857,63 +5002,6 @@ bool LLViewerWindow::onAlert(const LLSD& notify)
}
////////////////////////////////////////////////////////////////////////////
-
-LLBottomPanel::LLBottomPanel(const LLRect &rect) :
- LLPanel(LLStringUtil::null, rect, FALSE),
- mIndicator(NULL)
-{
- // bottom panel is focus root, so Tab moves through the toolbar and button bar, and overlay
- setFocusRoot(TRUE);
- // flag this panel as chrome so buttons don't grab keyboard focus
- setIsChrome(TRUE);
-
- mFactoryMap["toolbar"] = LLCallbackMap(createToolBar, NULL);
- mFactoryMap["overlay"] = LLCallbackMap(createOverlayBar, NULL);
- mFactoryMap["hud"] = LLCallbackMap(createHUD, NULL);
- LLUICtrlFactory::getInstance()->buildPanel(this, "panel_bars.xml", &getFactoryMap());
-
- setOrigin(rect.mLeft, rect.mBottom);
- reshape(rect.getWidth(), rect.getHeight());
-}
-
-void LLBottomPanel::setFocusIndicator(LLView * indicator)
-{
- mIndicator = indicator;
-}
-
-void LLBottomPanel::draw()
-{
- if(mIndicator)
- {
- BOOL hasFocus = gFocusMgr.childHasKeyboardFocus(this);
- mIndicator->setVisible(hasFocus);
- mIndicator->setEnabled(hasFocus);
- }
- LLPanel::draw();
-}
-
-void* LLBottomPanel::createHUD(void* data)
-{
- delete gHUDView;
- gHUDView = new LLHUDView();
- return gHUDView;
-}
-
-
-void* LLBottomPanel::createOverlayBar(void* data)
-{
- delete gOverlayBar;
- gOverlayBar = new LLOverlayBar();
- return gOverlayBar;
-}
-
-void* LLBottomPanel::createToolBar(void* data)
-{
- delete gToolBar;
- gToolBar = new LLToolBar();
- return gToolBar;
-}
-
//
// LLPickInfo
//
@@ -4957,10 +5045,6 @@ LLPickInfo::LLPickInfo(const LLCoordGL& mouse_pos,
{
}
-LLPickInfo::~LLPickInfo()
-{
-}
-
void LLPickInfo::fetchResults()
{
@@ -4979,59 +5063,14 @@ void LLPickInfo::fetchResults()
NULL, -1, mPickTransparent, &face_hit,
&intersection, &uv, &normal, &binormal);
- // read back colors and depth values from buffer
- //glReadPixels(mScreenRegion.mLeft, mScreenRegion.mBottom, mScreenRegion.getWidth(), mScreenRegion.getHeight(), GL_RGBA, GL_UNSIGNED_BYTE, mPickBuffer);
- //glReadPixels(mScreenRegion.mLeft, mScreenRegion.mBottom, mScreenRegion.getWidth(), mScreenRegion.getHeight(), GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, mPickDepthBuffer );
-
- // find pick region that is fully onscreen
- LLCoordGL scaled_pick_point;;
- scaled_pick_point.mX = llclamp(llround((F32)mMousePt.mX * gViewerWindow->getDisplayScale().mV[VX]), PICK_HALF_WIDTH, gViewerWindow->getWindowDisplayWidth() - PICK_HALF_WIDTH);
- scaled_pick_point.mY = llclamp(llround((F32)mMousePt.mY * gViewerWindow->getDisplayScale().mV[VY]), PICK_HALF_WIDTH, gViewerWindow->getWindowDisplayHeight() - PICK_HALF_WIDTH);
- //S32 pixel_index = PICK_HALF_WIDTH * PICK_DIAMETER + PICK_HALF_WIDTH;
- //S32 pick_id = (U32)mPickBuffer[(pixel_index * 4) + 0] << 16 | (U32)mPickBuffer[(pixel_index * 4) + 1] << 8 | (U32)mPickBuffer[(pixel_index * 4) + 2];
- //F32 depth = mPickDepthBuffer[pixel_index];
-
- //S32 x_offset = mMousePt.mX - llround((F32)scaled_pick_point.mX / gViewerWindow->getDisplayScale().mV[VX]);
- //S32 y_offset = mMousePt.mY - llround((F32)scaled_pick_point.mY / gViewerWindow->getDisplayScale().mV[VY]);
-
mPickPt = mMousePt;
- // we hit nothing, scan surrounding pixels for something useful
- /*if (!pick_id)
- {
- S32 closest_distance = 10000;
- //S32 closest_pick_name = 0;
- for (S32 col = 0; col < PICK_DIAMETER; col++)
- {
- for (S32 row = 0; row < PICK_DIAMETER; row++)
- {
- S32 distance_squared = (llabs(col - x_offset - PICK_HALF_WIDTH) * llabs(col - x_offset - PICK_HALF_WIDTH)) + (llabs(row - y_offset - PICK_HALF_WIDTH) * llabs(row - y_offset - PICK_HALF_WIDTH));
- pixel_index = row * PICK_DIAMETER + col;
- S32 test_name = (U32)mPickBuffer[(pixel_index * 4) + 0] << 16 | (U32)mPickBuffer[(pixel_index * 4) + 1] << 8 | (U32)mPickBuffer[(pixel_index * 4) + 2];
- if (test_name && distance_squared < closest_distance)
- {
- closest_distance = distance_squared;
- pick_id = test_name;
- depth = mPickDepthBuffer[pixel_index];
- mPickPt.mX = mMousePt.mX + (col - PICK_HALF_WIDTH);
- mPickPt.mY = mMousePt.mY + (row - PICK_HALF_WIDTH);
- }
- }
- }
- }*/
-
-
U32 te_offset = face_hit > -1 ? face_hit : 0;
- //pick_id &= 0x000fffff;
//unproject relative clicked coordinate from window coordinate using GL
LLViewerObject* objectp = hit_object;
- //if (pick_id == (S32)GL_NAME_PARCEL_WALL)
- //{
- // mPickType = PICK_PARCEL_WALL;
- //}
if (hit_icon &&
(!objectp ||
icon_dist < (LLViewerCamera::getInstance()->getOrigin()-intersection).magVec()))
@@ -5075,20 +5114,6 @@ void LLPickInfo::fetchResults()
mObjectID = objectp->mID;
mObjectFace = (te_offset == NO_FACE) ? -1 : (S32)te_offset;
- /*glh::matrix4f newModel((F32*)LLViewerCamera::getInstance()->getModelview().mMatrix);
-
- for(U32 i = 0; i < 16; ++i)
- {
- modelview[i] = newModel.m[i];
- projection[i] = LLViewerCamera::getInstance()->getProjection().mMatrix[i/4][i%4];
- }
- glGetIntegerv( GL_VIEWPORT, viewport );
-
- winX = ((F32)mPickPt.mX) * gViewerWindow->getDisplayScale().mV[VX];
- winY = ((F32)mPickPt.mY) * gViewerWindow->getDisplayScale().mV[VY];
-
- gluUnProject( winX, winY, depth, modelview, projection, viewport, &posX, &posY, &posZ);*/
-
mPosGlobal = gAgent.getPosGlobalFromAgent(intersection);
if (mWantSurfaceInfo)
@@ -5114,15 +5139,11 @@ void LLPickInfo::updateXYCoords()
if (mObjectFace > -1)
{
const LLTextureEntry* tep = getObject()->getTE(mObjectFace);
- LLPointer<LLViewerImage> imagep = gImageList.getImage(tep->getID());
+ LLPointer<LLViewerTexture> imagep = LLViewerTextureManager::getFetchedTexture(tep->getID());
if(mUVCoords.mV[VX] >= 0.f && mUVCoords.mV[VY] >= 0.f && imagep.notNull())
{
- LLCoordGL coords;
-
- coords.mX = llround(mUVCoords.mV[VX] * (F32)imagep->getWidth());
- coords.mY = llround(mUVCoords.mV[VY] * (F32)imagep->getHeight());
-
- gViewerWindow->getWindow()->convertCoords(coords, &mXYCoords);
+ mXYCoords.mX = llround(mUVCoords.mV[VX] * (F32)imagep->getWidth());
+ mXYCoords.mY = llround((1.f - mUVCoords.mV[VY]) * (F32)imagep->getHeight());
}
}
}
diff --git a/indra/newview/llviewerwindow.h b/indra/newview/llviewerwindow.h
index 509a7c4884..7afb77bed8 100644
--- a/indra/newview/llviewerwindow.h
+++ b/indra/newview/llviewerwindow.h
@@ -44,12 +44,13 @@
#include "v3dmath.h"
#include "v2math.h"
-#include "llwindow.h"
+#include "llwindowcallbacks.h"
#include "lltimer.h"
#include "llstat.h"
-#include "llalertdialog.h"
#include "llnotifications.h"
#include "llmousehandler.h"
+#include "llcursortypes.h"
+#include "llhandle.h"
class LLView;
class LLViewerObject;
@@ -60,6 +61,8 @@ class LLVelocityBar;
class LLTextBox;
class LLImageRaw;
class LLHUDIcon;
+class LLWindow;
+class LLRootView;
#define PICK_HALF_WIDTH 5
#define PICK_DIAMETER (2 * PICK_HALF_WIDTH + 1)
@@ -74,7 +77,6 @@ public:
BOOL pick_transparent,
BOOL pick_surface_info,
void (*pick_callback)(const LLPickInfo& pick_info));
- ~LLPickInfo();
void fetchResults();
LLPointer<LLViewerObject> getObject() const;
@@ -181,15 +183,28 @@ public:
/*virtual*/ void handlePingWatchdog(LLWindow *window, const char * msg);
/*virtual*/ void handlePauseWatchdog(LLWindow *window);
/*virtual*/ void handleResumeWatchdog(LLWindow *window);
-
+ /*virtual*/ std::string translateString(const char* tag);
+ /*virtual*/ std::string translateString(const char* tag,
+ const std::map<std::string, std::string>& args);
+
+ // signal on bottom tray width changed
+ typedef boost::function<void (void)> bottom_tray_callback_t;
+ typedef boost::signals2::signal<void (void)> bottom_tray_signal_t;
+ bottom_tray_signal_t mOnBottomTrayWidthChanged;
+ boost::signals2::connection setOnBottomTrayWidthChanged(bottom_tray_callback_t cb) { return mOnBottomTrayWidthChanged.connect(cb); }
//
// ACCESSORS
//
- LLView* getRootView() const { return mRootView; }
+ LLRootView* getRootView() const;
// Window in raw pixels as seen on screen.
const LLRect& getWindowRect() const { return mWindowRect; };
+ // portion of window that shows 3d world
+ const LLRect& getWorldViewRect() const { return mWorldViewRect; };
+ LLRect getVirtualWorldViewRect() const;
+ S32 getWorldViewHeight() const;
+ S32 getWorldViewWidth() const;
S32 getWindowDisplayHeight() const;
S32 getWindowDisplayWidth() const;
@@ -200,9 +215,9 @@ public:
S32 getWindowWidth() const;
LLWindow* getWindow() const { return mWindow; }
- void* getPlatformWindow() const { return mWindow->getPlatformWindow(); }
- void* getMediaWindow() const { return mWindow->getMediaWindow(); }
- void focusClient() const { return mWindow->focusClient(); };
+ void* getPlatformWindow() const;
+ void* getMediaWindow() const;
+ void focusClient() const;
LLCoordGL getLastMouse() const { return mLastMousePoint; }
S32 getLastMouseX() const { return mLastMousePoint.mX; }
@@ -221,7 +236,8 @@ public:
const LLPickInfo& getLastPick() const { return mLastPick; }
const LLPickInfo& getHoverPick() const { return mHoverPick; }
- void setupViewport(S32 x_offset = 0, S32 y_offset = 0);
+ void setup2DViewport(S32 x_offset = 0, S32 y_offset = 0);
+ void setup3DViewport(S32 x_offset = 0, S32 y_offset = 0);
void setup3DRender();
void setup2DRender();
@@ -261,7 +277,14 @@ public:
void updateObjectUnderCursor();
- BOOL handlePerFrameHover(); // Once per frame, update UI based on mouse position
+ void updateUI(); // Once per frame, update UI based on mouse position, calls following update* functions
+ void updateLayout();
+ void updateMouseDelta();
+ void updateKeyboardFocus();
+ void updatePicking(S32 x, S32 y, MASK mask);
+
+ void updateWorldViewRect(bool use_full_window=false);
+ void updateBottomTrayRect();
BOOL handleKey(KEY key, MASK mask);
void handleScrollWheel (S32 clicks);
@@ -349,11 +372,13 @@ public:
// handle shutting down GL and bringing it back up
void requestResolutionUpdate(bool fullscreen_checked);
+ void requestResolutionUpdate(); // doesn't affect fullscreen
BOOL checkSettings();
void restartDisplay(BOOL show_progress_bar);
BOOL changeDisplaySettings(BOOL fullscreen, LLCoordScreen size, BOOL disable_vsync, BOOL show_progress_bar);
BOOL getIgnoreDestroyWindow() { return mIgnoreActivate; }
F32 getDisplayAspectRatio() const;
+ F32 getWorldViewAspectRatio() const;
const LLVector2& getDisplayScale() const { return mDisplayScale; }
void calcDisplayScale();
@@ -382,7 +407,8 @@ protected:
BOOL mShowFullscreenProgress;
LLRect mWindowRect;
LLRect mVirtualWindowRect;
- LLView* mRootView; // a view of size mWindowRect, containing all child views
+ LLRect mWorldViewRect; // specifies area of screen where we render the 3D world
+ LLRootView* mRootView; // a view of size mWindowRect, containing all child views
LLVector2 mDisplayScale;
LLCoordGL mCurrentMousePoint; // last mouse position in GL coords
@@ -395,12 +421,16 @@ protected:
LLProgressView *mProgressView;
+ LLFrameTimer mToolTipFadeTimer;
LLTextBox* mToolTip;
+ std::string mLastToolTipMessage;
BOOL mToolTipBlocked; // True after a key press or a mouse button event. False once the mouse moves again.
LLRect mToolTipStickyRect; // Once a tool tip is shown, it will stay visible until the mouse leaves this rect.
BOOL mMouseInWindow; // True if the mouse is over our window or if we have captured the mouse.
BOOL mFocusCycleMode;
+ typedef std::set<LLHandle<LLView> > view_handle_set_t;
+ view_handle_set_t mMouseHoverViews;
// Variables used for tool override switching based on modifier keys. JC
MASK mLastMask; // used to detect changes in modifier mask
@@ -435,36 +465,16 @@ protected:
static std::string sMovieBaseName;
};
-class LLBottomPanel : public LLPanel
-{
-public:
- LLBottomPanel(const LLRect& rect);
- void setFocusIndicator(LLView * indicator);
- LLView * getFocusIndicator() { return mIndicator; }
- /*virtual*/ void draw();
-
- static void* createHUD(void* data);
- static void* createOverlayBar(void* data);
- static void* createToolBar(void* data);
-
-protected:
- LLView * mIndicator;
-};
-extern LLBottomPanel * gBottomPanel;
-
void toggle_flying(void*);
void toggle_first_person();
void toggle_build(void*);
void reset_viewer_state_on_sim(void);
void update_saved_window_size(const std::string& control,S32 delta_width, S32 delta_height);
-
-
//
// Globals
//
-extern LLVelocityBar* gVelocityBar;
extern LLViewerWindow* gViewerWindow;
extern LLFrameTimer gMouseIdleTimer; // how long has it been since the mouse last moved?
diff --git a/indra/newview/llvlcomposition.cpp b/indra/newview/llvlcomposition.cpp
index e52fec7909..f26ba6f46e 100644
--- a/indra/newview/llvlcomposition.cpp
+++ b/indra/newview/llvlcomposition.cpp
@@ -39,8 +39,8 @@
#include "v3math.h"
#include "llsurface.h"
#include "lltextureview.h"
-#include "llviewerimage.h"
-#include "llviewerimagelist.h"
+#include "llviewertexture.h"
+#include "llviewertexturelist.h"
#include "llviewerregion.h"
#include "noise.h"
#include "llregionhandle.h" // for from_region_handle
@@ -106,7 +106,7 @@ void LLVLComposition::setDetailTextureID(S32 corner, const LLUUID& id)
{
return;
}
- mDetailTextures[corner] = gImageList.getImage(id);
+ mDetailTextures[corner] = LLViewerTextureManager::getFetchedTexture(id);
mDetailTextures[corner]->setNoDelete() ;
mRawImages[corner] = NULL;
}
@@ -229,7 +229,7 @@ BOOL LLVLComposition::generateComposition()
{
if (mDetailTextures[i]->getDiscardLevel() < 0)
{
- mDetailTextures[i]->setBoostLevel(LLViewerImage::BOOST_TERRAIN); // in case we are at low detail
+ mDetailTextures[i]->setBoostLevel(LLViewerTexture::BOOST_TERRAIN); // in case we are at low detail
mDetailTextures[i]->addTextureStats(BASE_SIZE*BASE_SIZE);
return FALSE;
}
@@ -237,8 +237,8 @@ BOOL LLVLComposition::generateComposition()
(mDetailTextures[i]->getWidth() < BASE_SIZE ||
mDetailTextures[i]->getHeight() < BASE_SIZE)))
{
- S32 width = mDetailTextures[i]->getWidth(0);
- S32 height = mDetailTextures[i]->getHeight(0);
+ S32 width = mDetailTextures[i]->getFullWidth();
+ S32 height = mDetailTextures[i]->getFullHeight();
S32 min_dim = llmin(width, height);
S32 ddiscard = 0;
while (min_dim > BASE_SIZE && ddiscard < MAX_DISCARD_LEVEL)
@@ -246,7 +246,7 @@ BOOL LLVLComposition::generateComposition()
ddiscard++;
min_dim /= 2;
}
- mDetailTextures[i]->setBoostLevel(LLViewerImage::BOOST_TERRAIN); // in case we are at low detail
+ mDetailTextures[i]->setBoostLevel(LLViewerTexture::BOOST_TERRAIN); // in case we are at low detail
mDetailTextures[i]->setMinDiscardLevel(ddiscard);
return FALSE;
}
@@ -280,7 +280,7 @@ BOOL LLVLComposition::generateTexture(const F32 x, const F32 y,
{
// Read back a raw image for this discard level, if it exists
mRawImages[i] = new LLImageRaw;
- S32 min_dim = llmin(mDetailTextures[i]->getWidth(0), mDetailTextures[i]->getHeight(0));
+ S32 min_dim = llmin(mDetailTextures[i]->getFullWidth(), mDetailTextures[i]->getFullHeight());
S32 ddiscard = 0;
while (min_dim > BASE_SIZE && ddiscard < MAX_DISCARD_LEVEL)
{
@@ -336,7 +336,7 @@ BOOL LLVLComposition::generateTexture(const F32 x, const F32 y,
//
//
- LLViewerImage *texturep;
+ LLViewerTexture *texturep;
U32 tex_width, tex_height, tex_comps;
U32 tex_stride;
F32 tex_x_scalef, tex_y_scalef;
@@ -455,7 +455,7 @@ BOOL LLVLComposition::generateTexture(const F32 x, const F32 y,
for (S32 i = 0; i < 4; i++)
{
// Un-boost detatil textures (will get re-boosted if rendering in high detail)
- mDetailTextures[i]->setBoostLevel(LLViewerImage::BOOST_NONE);
+ mDetailTextures[i]->setBoostLevel(LLViewerTexture::BOOST_NONE);
mDetailTextures[i]->setMinDiscardLevel(MAX_DISCARD_LEVEL + 1);
}
@@ -467,7 +467,7 @@ LLUUID LLVLComposition::getDetailTextureID(S32 corner)
return mDetailTextures[corner]->getID();
}
-LLViewerImage* LLVLComposition::getDetailTexture(S32 corner)
+LLViewerFetchedTexture* LLVLComposition::getDetailTexture(S32 corner)
{
return mDetailTextures[corner];
}
diff --git a/indra/newview/llvlcomposition.h b/indra/newview/llvlcomposition.h
index 6d5db3c050..d1b3dc4495 100644
--- a/indra/newview/llvlcomposition.h
+++ b/indra/newview/llvlcomposition.h
@@ -34,7 +34,7 @@
#define LL_LLVLCOMPOSITION_H
#include "llviewerlayer.h"
-#include "llviewerimage.h"
+#include "llviewertexture.h"
class LLSurface;
@@ -62,7 +62,7 @@ public:
CORNER_COUNT = 4
};
LLUUID getDetailTextureID(S32 corner);
- LLViewerImage* getDetailTexture(S32 corner);
+ LLViewerFetchedTexture* getDetailTexture(S32 corner);
F32 getStartHeight(S32 corner);
F32 getHeightRange(S32 corner);
@@ -79,7 +79,7 @@ protected:
LLSurface *mSurfacep;
BOOL mTexturesLoaded;
- LLPointer<LLViewerImage> mDetailTextures[CORNER_COUNT];
+ LLPointer<LLViewerFetchedTexture> mDetailTextures[CORNER_COUNT];
LLPointer<LLImageRaw> mRawImages[CORNER_COUNT];
F32 mStartHeight[CORNER_COUNT];
diff --git a/indra/newview/llvlmanager.cpp b/indra/newview/llvlmanager.cpp
index 177093c4d1..07ef262668 100644
--- a/indra/newview/llvlmanager.cpp
+++ b/indra/newview/llvlmanager.cpp
@@ -40,7 +40,6 @@
#include "patch_dct.h"
#include "llviewerregion.h"
#include "llframetimer.h"
-#include "llagent.h"
#include "llsurface.h"
LLVLManager gVLManager;
diff --git a/indra/newview/llvoavatar.cpp b/indra/newview/llvoavatar.cpp
index 983a580fea..018cce4b49 100644
--- a/indra/newview/llvoavatar.cpp
+++ b/indra/newview/llvoavatar.cpp
@@ -1,5 +1,5 @@
/**
- * @file llvoavatar.cpp
+ * @File llvoavatar.cpp
* @brief Implementation of LLVOAvatar class which is a derivation fo LLViewerObject
*
* $LicenseInfo:firstyear=2001&license=viewergpl$
@@ -37,10 +37,12 @@
#include <stdio.h>
#include <ctype.h>
-#include "audioengine.h"
+#include "llaudioengine.h"
#include "noise.h"
#include "llagent.h" // Get state values from here
+#include "llagentwearables.h"
+#include "llanimationstates.h"
#include "llviewercontrol.h"
#include "lldrawpoolavatar.h"
#include "lldriverparam.h"
@@ -50,11 +52,11 @@
#include "llheadrotmotion.h"
#include "llhudeffecttrail.h"
#include "llhudmanager.h"
-#include "llinventoryview.h"
#include "llkeyframefallmotion.h"
#include "llkeyframestandmotion.h"
#include "llkeyframewalkmotion.h"
#include "llmutelist.h"
+#include "llmoveview.h"
#include "llnotify.h"
#include "llquantize.h"
#include "llregionhandle.h"
@@ -63,21 +65,22 @@
#include "llsprite.h"
#include "lltargetingmotion.h"
#include "lltexlayer.h"
-#include "lltoolgrab.h" // for needsRenderBeam
-#include "lltoolmgr.h" // for needsRenderBeam
#include "lltoolmorph.h"
#include "llviewercamera.h"
-#include "llviewerimagelist.h"
+#include "llviewertexturelist.h"
#include "llviewermenu.h"
#include "llviewerobjectlist.h"
#include "llviewerparcelmgr.h"
#include "llviewerstats.h"
+#include "llvoavatarself.h"
#include "llvovolume.h"
#include "llworld.h"
#include "pipeline.h"
#include "llviewershadermgr.h"
#include "llsky.h"
#include "llanimstatelabels.h"
+#include "lltrans.h"
+
#include "llgesturemgr.h" //needed to trigger the voice gesticulations
#include "llvoiceclient.h"
#include "llvoicevisualizer.h" // Ventrella
@@ -136,8 +139,7 @@ const S32 MIN_REQUIRED_PIXEL_AREA_PELVIS_FIX = 40;
const S32 TEX_IMAGE_SIZE_SELF = 512;
const S32 TEX_IMAGE_AREA_SELF = TEX_IMAGE_SIZE_SELF * TEX_IMAGE_SIZE_SELF;
-const S32 TEX_IMAGE_SIZE_OTHER = TEX_IMAGE_SIZE_SELF / 4; // The size of local textures for other (!mIsSelf) avatars
-const S32 TEX_IMAGE_AREA_OTHER = TEX_IMAGE_SIZE_OTHER * TEX_IMAGE_SIZE_OTHER;
+const S32 TEX_IMAGE_SIZE_OTHER = 512 / 4; // The size of local textures for other (!isSelf()) avatars
const F32 HEAD_MOVEMENT_AVG_TIME = 0.9f;
@@ -168,32 +170,27 @@ const LLColor4 DUMMY_COLOR = LLColor4(0.5,0.5,0.5,1.0);
enum ERenderName
{
RENDER_NAME_NEVER,
- RENDER_NAME_FADE,
- RENDER_NAME_ALWAYS
+ RENDER_NAME_ALWAYS,
+ RENDER_NAME_FADE
};
//-----------------------------------------------------------------------------
// Callback data
//-----------------------------------------------------------------------------
-struct LLAvatarTexData
-{
- LLAvatarTexData( const LLUUID& id, ETextureIndex index )
- : mAvatarID(id), mIndex(index) {}
- LLUUID mAvatarID;
- ETextureIndex mIndex;
-};
struct LLTextureMaskData
{
- LLTextureMaskData( const LLUUID& id )
- : mAvatarID(id), mLastDiscardLevel(S32_MAX) {}
+ LLTextureMaskData( const LLUUID& id ) :
+ mAvatarID(id),
+ mLastDiscardLevel(S32_MAX)
+ {}
LLUUID mAvatarID;
S32 mLastDiscardLevel;
};
/*********************************************************************************
** **
- ** Begin LLVOAvatar Support classes
+ ** Begin private LLVOAvatar Support classes
**
**/
@@ -249,85 +246,6 @@ private:
bone_info_list_t mBoneInfoList;
};
-
-//------------------------------------------------------------------------
-// LLVOAvatarXmlInfo
-// One instance (in LLVOAvatar) with common data parsed from the XML files
-//------------------------------------------------------------------------
-class LLVOAvatarXmlInfo
-{
- friend class LLVOAvatar;
-public:
- LLVOAvatarXmlInfo();
- ~LLVOAvatarXmlInfo();
-
-private:
- BOOL parseXmlSkeletonNode(LLXmlTreeNode* root);
- BOOL parseXmlMeshNodes(LLXmlTreeNode* root);
- BOOL parseXmlColorNodes(LLXmlTreeNode* root);
- BOOL parseXmlLayerNodes(LLXmlTreeNode* root);
- BOOL parseXmlDriverNodes(LLXmlTreeNode* root);
-
- struct LLVOAvatarMeshInfo
- {
- typedef std::pair<LLPolyMorphTargetInfo*,BOOL> morph_info_pair_t;
- typedef std::vector<morph_info_pair_t> morph_info_list_t;
-
- LLVOAvatarMeshInfo() : mLOD(0), mMinPixelArea(.1f) {}
- ~LLVOAvatarMeshInfo()
- {
- morph_info_list_t::iterator iter;
- for (iter = mPolyMorphTargetInfoList.begin(); iter != mPolyMorphTargetInfoList.end(); iter++)
- {
- delete iter->first;
- }
- mPolyMorphTargetInfoList.clear();
- }
-
- std::string mType;
- S32 mLOD;
- std::string mMeshFileName;
- std::string mReferenceMeshName;
- F32 mMinPixelArea;
- morph_info_list_t mPolyMorphTargetInfoList;
- };
- typedef std::vector<LLVOAvatarMeshInfo*> mesh_info_list_t;
- mesh_info_list_t mMeshInfoList;
-
- typedef std::vector<LLPolySkeletalDistortionInfo*> skeletal_distortion_info_list_t;
- skeletal_distortion_info_list_t mSkeletalDistortionInfoList;
-
- struct LLVOAvatarAttachmentInfo
- {
- LLVOAvatarAttachmentInfo()
- : mGroup(-1), mAttachmentID(-1), mPieMenuSlice(-1), mVisibleFirstPerson(FALSE),
- mIsHUDAttachment(FALSE), mHasPosition(FALSE), mHasRotation(FALSE) {}
- std::string mName;
- std::string mJointName;
- LLVector3 mPosition;
- LLVector3 mRotationEuler;
- S32 mGroup;
- S32 mAttachmentID;
- S32 mPieMenuSlice;
- BOOL mVisibleFirstPerson;
- BOOL mIsHUDAttachment;
- BOOL mHasPosition;
- BOOL mHasRotation;
- };
- typedef std::vector<LLVOAvatarAttachmentInfo*> attachment_info_list_t;
- attachment_info_list_t mAttachmentInfoList;
-
- LLTexGlobalColorInfo *mTexSkinColorInfo;
- LLTexGlobalColorInfo *mTexHairColorInfo;
- LLTexGlobalColorInfo *mTexEyeColorInfo;
-
- typedef std::vector<LLTexLayerSetInfo*> layer_info_list_t;
- layer_info_list_t mLayerInfoList;
-
- typedef std::vector<LLDriverParamInfo*> driver_info_list_t;
- driver_info_list_t mDriverInfoList;
-};
-
//-----------------------------------------------------------------------------
// class LLBodyNoiseMotion
//-----------------------------------------------------------------------------
@@ -492,7 +410,7 @@ public:
virtual LLMotionInitStatus onInitialize(LLCharacter *character)
{
mCharacter = character;
- bool success = true;
+ BOOL success = true;
if ( !mChestState->setJoint( character->getJoint( "mChest" ) ) ) { success = false; }
@@ -651,15 +569,11 @@ private:
//-----------------------------------------------------------------------------
LLXmlTree LLVOAvatar::sXMLTree;
LLXmlTree LLVOAvatar::sSkeletonXMLTree;
-BOOL LLVOAvatar::sDebugAvatarRotation = FALSE;
LLVOAvatarSkeletonInfo* LLVOAvatar::sAvatarSkeletonInfo = NULL;
-LLVOAvatarXmlInfo* LLVOAvatar::sAvatarXmlInfo = NULL;
+LLVOAvatar::LLVOAvatarXmlInfo* LLVOAvatar::sAvatarXmlInfo = NULL;
LLVOAvatarDictionary *LLVOAvatar::sAvatarDictionary = NULL;
S32 LLVOAvatar::sFreezeCounter = 0;
S32 LLVOAvatar::sMaxVisible = 50;
-LLMap< LLGLenum, LLGLuint*> LLVOAvatar::sScratchTexNames;
-LLMap< LLGLenum, F32*> LLVOAvatar::sScratchTexLastBindTime;
-S32 LLVOAvatar::sScratchTexBytes = 0;
F32 LLVOAvatar::sRenderDistance = 256.f;
S32 LLVOAvatar::sNumVisibleAvatars = 0;
S32 LLVOAvatar::sNumLODChangesThisFrame = 0;
@@ -730,8 +644,6 @@ LLVOAvatar::LLVOAvatar(const LLUUID& id,
mNameMute(FALSE),
mRenderGroupTitles(sRenderGroupTitles),
mNameAppearance(FALSE),
- mLastRegionHandle(0),
- mRegionCrossingCount(0),
mFirstTEMessageReceived( FALSE ),
mFirstAppearanceMessageReceived( FALSE ),
mCulled( FALSE ),
@@ -742,36 +654,29 @@ LLVOAvatar::LLVOAvatar(const LLUUID& id,
mNeedsSkin(FALSE),
mUpdatePeriod(1),
mFullyLoadedInitialized(FALSE),
- mHasBakedHair( FALSE )
+ mSupportsAlphaLayers(FALSE)
{
LLMemType mt(LLMemType::MTYPE_AVATAR);
//VTResume(); // VTune
// mVoiceVisualizer is created by the hud effects manager and uses the HUD Effects pipeline
- const bool needsSendToSim = false; // currently, this HUD effect doesn't need to pack and unpack data to do its job
+ const BOOL needsSendToSim = false; // currently, this HUD effect doesn't need to pack and unpack data to do its job
mVoiceVisualizer = ( LLVoiceVisualizer *)LLHUDManager::getInstance()->createViewerEffect( LLHUDObject::LL_HUD_EFFECT_VOICE_VISUALIZER, needsSendToSim );
lldebugs << "LLVOAvatar Constructor (0x" << this << ") id:" << mID << llendl;
mPelvisp = NULL;
- for( S32 i=0; i<TEX_NUM_INDICES; i++ )
- {
- if (isIndexLocalTexture((ETextureIndex)i))
- {
- mLocalTextureData[(ETextureIndex)i] = LocalTextureData();
- }
- }
-
- mBakedTextureData.resize(BAKED_NUM_INDICES);
- for (U32 i = 0; i < mBakedTextureData.size(); i++ )
+ mBakedTextureDatas.resize(BAKED_NUM_INDICES);
+ for (U32 i = 0; i < mBakedTextureDatas.size(); i++ )
{
- mBakedTextureData[i].mLastTextureIndex = IMG_DEFAULT_AVATAR;
- mBakedTextureData[i].mTexLayerSet = NULL;
- mBakedTextureData[i].mIsLoaded = false;
- mBakedTextureData[i].mIsUsed = false;
- mBakedTextureData[i].mMaskTexName = 0;
- mBakedTextureData[i].mTextureIndex = getTextureIndex((EBakedTextureIndex)i);
+ mBakedTextureDatas[i].mLastTextureIndex = IMG_DEFAULT_AVATAR;
+ mBakedTextureDatas[i].mTexLayerSet = NULL;
+ mBakedTextureDatas[i].mIsLoaded = false;
+ mBakedTextureDatas[i].mIsUsed = false;
+ mBakedTextureDatas[i].mMaskTexName = 0;
+ mBakedTextureDatas[i].mTextureIndex = LLVOAvatarDictionary::bakedToLocalTextureIndex((EBakedTextureIndex)i);
+ mBakedTextureDatas[i].mMorphMasksValid = FALSE;
}
mDirtyMesh = TRUE; // Dirty geometry, need to regenerate.
@@ -783,7 +688,6 @@ LLVOAvatar::LLVOAvatar(const LLUUID& id,
mNumJoints = 0;
mSkeleton = NULL;
- mScreenp = NULL;
mNumCollisionVolumes = 0;
mCollisionVolumes = NULL;
@@ -792,17 +696,6 @@ LLVOAvatar::LLVOAvatar(const LLUUID& id,
mSpeed = 0.f;
setAnimationData("Speed", &mSpeed);
- if (id == gAgentID)
- {
- mIsSelf = TRUE;
- gAgent.setAvatarObject(this);
- lldebugs << "Marking avatar as self " << id << llendl;
- }
- else
- {
- mIsSelf = FALSE;
- }
-
mNeedsImpostorUpdate = TRUE;
mNeedsAnimUpdate = TRUE;
@@ -824,8 +717,8 @@ LLVOAvatar::LLVOAvatar(const LLUUID& id,
mRippleTimeLast = 0.f;
- mShadowImagep = gImageList.getImageFromFile("foot_shadow.j2c");
- gGL.getTexUnit(0)->bind(mShadowImagep.get());
+ mShadowImagep = LLViewerTextureManager::getFetchedTextureFromFile("foot_shadow.j2c");
+ gGL.getTexUnit(0)->bind(mShadowImagep);
mShadowImagep->setAddressMode(LLTexUnit::TAM_CLAMP);
mInAir = FALSE;
@@ -837,146 +730,8 @@ LLVOAvatar::LLVOAvatar(const LLUUID& id,
mOohMorph = NULL;
mAahMorph = NULL;
- //-------------------------------------------------------------------------
- // initialize joint, mesh and shape members
- //-------------------------------------------------------------------------
- mRoot.setName( "mRoot" );
-
- for (LLVOAvatarDictionary::mesh_map_t::const_iterator iter = LLVOAvatarDictionary::getInstance()->getMeshes().begin();
- iter != LLVOAvatarDictionary::getInstance()->getMeshes().end();
- iter++)
- {
- const EMeshIndex mesh_index = iter->first;
- const LLVOAvatarDictionary::MeshDictionaryEntry *mesh_dict = iter->second;
-
- LLViewerJoint* joint = new LLViewerJoint();
- joint->setName(mesh_dict->mName);
- joint->setMeshID(mesh_index);
- mMeshLOD.push_back(joint);
-
- /* mHairLOD.setName("mHairLOD");
- mHairMesh0.setName("mHairMesh0");
- mHairMesh0.setMeshID(MESH_ID_HAIR);
- mHairMesh1.setName("mHairMesh1"); */
- for (U32 lod = 0; lod < mesh_dict->mLOD; lod++)
- {
- LLViewerJointMesh* mesh = new LLViewerJointMesh();
- std::string mesh_name = "m" + mesh_dict->mName + boost::lexical_cast<std::string>(lod);
- // We pre-pended an m - need to capitalize first character for camelCase
- mesh_name[1] = toupper(mesh_name[1]);
- mesh->setName(mesh_name);
- mesh->setMeshID(mesh_index);
- mesh->setPickName(mesh_dict->mPickName);
- switch((int)mesh_index)
- {
- case MESH_ID_HAIR:
- mesh->setIsTransparent(TRUE);
- break;
- case MESH_ID_SKIRT:
- mesh->setIsTransparent(TRUE);
- break;
- case MESH_ID_EYEBALL_LEFT:
- case MESH_ID_EYEBALL_RIGHT:
- mesh->setSpecular( LLColor4( 1.0f, 1.0f, 1.0f, 1.0f ), 1.f );
- break;
- }
-
- joint->mMeshParts.push_back(mesh);
- }
- }
-
- //-------------------------------------------------------------------------
- // associate baked textures with meshes
- //-------------------------------------------------------------------------
- for (LLVOAvatarDictionary::mesh_map_t::const_iterator iter = LLVOAvatarDictionary::getInstance()->getMeshes().begin();
- iter != LLVOAvatarDictionary::getInstance()->getMeshes().end();
- iter++)
- {
- const EMeshIndex mesh_index = iter->first;
- const LLVOAvatarDictionary::MeshDictionaryEntry *mesh_dict = iter->second;
- const EBakedTextureIndex baked_texture_index = mesh_dict->mBakedID;
-
- // Skip it if there's no associated baked texture.
- if (baked_texture_index == BAKED_NUM_INDICES) continue;
-
- for (std::vector<LLViewerJointMesh* >::iterator iter = mMeshLOD[mesh_index]->mMeshParts.begin();
- iter != mMeshLOD[mesh_index]->mMeshParts.end(); iter++)
- {
- LLViewerJointMesh* mesh = (LLViewerJointMesh*) *iter;
- mBakedTextureData[(int)baked_texture_index].mMeshes.push_back(mesh);
- }
- }
-
-
- //-------------------------------------------------------------------------
- // register motions
- //-------------------------------------------------------------------------
- if (LLCharacter::sInstances.size() == 1)
- {
- LLKeyframeMotion::setVFS(gStaticVFS);
- registerMotion( ANIM_AGENT_BUSY, LLNullMotion::create );
- registerMotion( ANIM_AGENT_CROUCH, LLKeyframeStandMotion::create );
- registerMotion( ANIM_AGENT_CROUCHWALK, LLKeyframeWalkMotion::create );
- registerMotion( ANIM_AGENT_EXPRESS_AFRAID, LLEmote::create );
- registerMotion( ANIM_AGENT_EXPRESS_ANGER, LLEmote::create );
- registerMotion( ANIM_AGENT_EXPRESS_BORED, LLEmote::create );
- registerMotion( ANIM_AGENT_EXPRESS_CRY, LLEmote::create );
- registerMotion( ANIM_AGENT_EXPRESS_DISDAIN, LLEmote::create );
- registerMotion( ANIM_AGENT_EXPRESS_EMBARRASSED, LLEmote::create );
- registerMotion( ANIM_AGENT_EXPRESS_FROWN, LLEmote::create );
- registerMotion( ANIM_AGENT_EXPRESS_KISS, LLEmote::create );
- registerMotion( ANIM_AGENT_EXPRESS_LAUGH, LLEmote::create );
- registerMotion( ANIM_AGENT_EXPRESS_OPEN_MOUTH, LLEmote::create );
- registerMotion( ANIM_AGENT_EXPRESS_REPULSED, LLEmote::create );
- registerMotion( ANIM_AGENT_EXPRESS_SAD, LLEmote::create );
- registerMotion( ANIM_AGENT_EXPRESS_SHRUG, LLEmote::create );
- registerMotion( ANIM_AGENT_EXPRESS_SMILE, LLEmote::create );
- registerMotion( ANIM_AGENT_EXPRESS_SURPRISE, LLEmote::create );
- registerMotion( ANIM_AGENT_EXPRESS_TONGUE_OUT, LLEmote::create );
- registerMotion( ANIM_AGENT_EXPRESS_TOOTHSMILE, LLEmote::create );
- registerMotion( ANIM_AGENT_EXPRESS_WINK, LLEmote::create );
- registerMotion( ANIM_AGENT_EXPRESS_WORRY, LLEmote::create );
- registerMotion( ANIM_AGENT_RUN, LLKeyframeWalkMotion::create );
- registerMotion( ANIM_AGENT_STAND, LLKeyframeStandMotion::create );
- registerMotion( ANIM_AGENT_STAND_1, LLKeyframeStandMotion::create );
- registerMotion( ANIM_AGENT_STAND_2, LLKeyframeStandMotion::create );
- registerMotion( ANIM_AGENT_STAND_3, LLKeyframeStandMotion::create );
- registerMotion( ANIM_AGENT_STAND_4, LLKeyframeStandMotion::create );
- registerMotion( ANIM_AGENT_STANDUP, LLKeyframeFallMotion::create );
- registerMotion( ANIM_AGENT_TURNLEFT, LLKeyframeWalkMotion::create );
- registerMotion( ANIM_AGENT_TURNRIGHT, LLKeyframeWalkMotion::create );
- registerMotion( ANIM_AGENT_WALK, LLKeyframeWalkMotion::create );
-
- // motions without a start/stop bit
- registerMotion( ANIM_AGENT_BODY_NOISE, LLBodyNoiseMotion::create );
- registerMotion( ANIM_AGENT_BREATHE_ROT, LLBreatheMotionRot::create );
- registerMotion( ANIM_AGENT_EDITING, LLEditingMotion::create );
- registerMotion( ANIM_AGENT_EYE, LLEyeMotion::create );
- registerMotion( ANIM_AGENT_FEMALE_WALK, LLKeyframeWalkMotion::create );
- registerMotion( ANIM_AGENT_FLY_ADJUST, LLFlyAdjustMotion::create );
- registerMotion( ANIM_AGENT_HAND_MOTION, LLHandMotion::create );
- registerMotion( ANIM_AGENT_HEAD_ROT, LLHeadRotMotion::create );
- registerMotion( ANIM_AGENT_PELVIS_FIX, LLPelvisFixMotion::create );
- registerMotion( ANIM_AGENT_SIT_FEMALE, LLKeyframeMotion::create );
- registerMotion( ANIM_AGENT_TARGET, LLTargetingMotion::create );
- registerMotion( ANIM_AGENT_WALK_ADJUST, LLWalkAdjustMotion::create );
-
- }
-
- if (gNoRender)
- {
- return;
- }
- buildCharacter();
-
- // preload specific motions here
- createMotion( ANIM_AGENT_CUSTOMIZE);
- createMotion( ANIM_AGENT_CUSTOMIZE_DONE);
-
- //VTPause(); // VTune
-
- mVoiceVisualizer->setVoiceEnabled( gVoiceClient->getVoiceEnabled( mID ) );
mCurrentGesticulationLevel = 0;
+
}
//------------------------------------------------------------------------
@@ -986,46 +741,43 @@ LLVOAvatar::~LLVOAvatar()
{
lldebugs << "LLVOAvatar Destructor (0x" << this << ") id:" << mID << llendl;
- if (mIsSelf)
+ if (isSelf())
{
gAgent.setAvatarObject(NULL);
}
mRoot.removeAllChildren();
- delete [] mSkeleton;
- mSkeleton = NULL;
-
- delete mScreenp;
- mScreenp = NULL;
-
- delete [] mCollisionVolumes;
- mCollisionVolumes = NULL;
-
+ deleteAndClearArray(mSkeleton);
+ deleteAndClearArray(mCollisionVolumes);
mNumJoints = 0;
- for (U32 i = 0; i < mBakedTextureData.size(); i++)
+ for (U32 i = 0; i < mBakedTextureDatas.size(); i++)
{
- delete mBakedTextureData[i].mTexLayerSet;
- mBakedTextureData[i].mTexLayerSet = NULL;
+ deleteAndClear(mBakedTextureDatas[i].mTexLayerSet);
+ mBakedTextureDatas[i].mMeshes.clear();
+
+ for (morph_list_t::iterator iter2 = mBakedTextureDatas[i].mMaskedMorphs.begin();
+ iter2 != mBakedTextureDatas[i].mMaskedMorphs.end(); iter2++)
+ {
+ LLMaskedMorph* masked_morph = (*iter2);
+ delete masked_morph;
+ }
}
std::for_each(mAttachmentPoints.begin(), mAttachmentPoints.end(), DeletePairedPointer());
mAttachmentPoints.clear();
- delete mTexSkinColor;
- mTexSkinColor = NULL;
- delete mTexHairColor;
- mTexHairColor = NULL;
- delete mTexEyeColor;
- mTexEyeColor = NULL;
+ deleteAndClear(mTexSkinColor);
+ deleteAndClear(mTexHairColor);
+ deleteAndClear(mTexEyeColor);
std::for_each(mMeshes.begin(), mMeshes.end(), DeletePairedPointer());
mMeshes.clear();
for (std::vector<LLViewerJoint*>::iterator jointIter = mMeshLOD.begin();
- jointIter != mMeshLOD.end(); jointIter++)
+ jointIter != mMeshLOD.end(); jointIter++)
{
LLViewerJoint* joint = (LLViewerJoint *) *jointIter;
std::for_each(joint->mMeshParts.begin(), joint->mMeshParts.end(), DeletePointer());
@@ -1036,9 +788,6 @@ LLVOAvatar::~LLVOAvatar()
mDead = TRUE;
- // Clean up class data
- LLVOAvatar::cullAvatarsByPixelArea();
-
mAnimationSources.clear();
lldebugs << "LLVOAvatar Destructor end" << llendl;
@@ -1052,10 +801,7 @@ void LLVOAvatar::markDead()
mNameText = NULL;
sNumVisibleChatBubbles--;
}
-
mVoiceVisualizer->markDead();
-
- mBeam = NULL;
LLViewerObject::markDead();
}
@@ -1065,9 +811,9 @@ BOOL LLVOAvatar::isFullyBaked()
if (mIsDummy) return TRUE;
if (getNumTEs() == 0) return FALSE;
- for (U32 i = 0; i < mBakedTextureData.size(); i++)
+ for (U32 i = 0; i < mBakedTextureDatas.size(); i++)
{
- if (!isTextureDefined(mBakedTextureData[i].mTextureIndex)
+ if (!isTextureDefined(mBakedTextureDatas[i].mTextureIndex)
&& ( (i != BAKED_SKIRT) || isWearingWearableType(WT_SKIRT) ) )
{
return FALSE;
@@ -1078,19 +824,21 @@ BOOL LLVOAvatar::isFullyBaked()
void LLVOAvatar::deleteLayerSetCaches(bool clearAll)
{
- for (U32 i = 0; i < mBakedTextureData.size(); i++)
+ for (U32 i = 0; i < mBakedTextureDatas.size(); i++)
{
- if (mBakedTextureData[i].mTexLayerSet)
+ if (mBakedTextureDatas[i].mTexLayerSet)
{
- if ((i != BAKED_HAIR || mIsSelf) && !clearAll) // Backwards compatibility - can be removed after hair baking is mandatory on the grid
+ // ! BACKWARDS COMPATIBILITY !
+ // Can be removed after hair baking is mandatory on the grid
+ if ((i != BAKED_HAIR || isSelf()) && !clearAll)
{
- mBakedTextureData[i].mTexLayerSet->deleteCaches();
+ mBakedTextureDatas[i].mTexLayerSet->deleteCaches();
}
}
- if (mBakedTextureData[i].mMaskTexName)
+ if (mBakedTextureDatas[i].mMaskTexName)
{
- glDeleteTextures(1, (GLuint*)&(mBakedTextureData[i].mMaskTexName));
- mBakedTextureData[i].mMaskTexName = 0 ;
+ glDeleteTextures(1, (GLuint*)&(mBakedTextureDatas[i].mMaskTexName));
+ mBakedTextureDatas[i].mMaskTexName = 0 ;
}
}
}
@@ -1101,20 +849,14 @@ BOOL LLVOAvatar::areAllNearbyInstancesBaked(S32& grey_avatars)
BOOL res = TRUE;
grey_avatars = 0;
for (std::vector<LLCharacter*>::iterator iter = LLCharacter::sInstances.begin();
- iter != LLCharacter::sInstances.end(); ++iter)
+ iter != LLCharacter::sInstances.end(); ++iter)
{
LLVOAvatar* inst = (LLVOAvatar*) *iter;
if( inst->isDead() )
{
continue;
}
-// else
-// if( inst->getPixelArea() < MIN_PIXEL_AREA_FOR_COMPOSITE )
-// {
-// return res; // Assumes sInstances is sorted by pixel area.
-// }
- else
- if( !inst->isFullyBaked() )
+ else if( !inst->isFullyBaked() )
{
res = FALSE;
if (inst->mHasGrey)
@@ -1126,19 +868,13 @@ BOOL LLVOAvatar::areAllNearbyInstancesBaked(S32& grey_avatars)
return res;
}
-// static
-void LLVOAvatar::dumpScratchTextureByteCount()
-{
- llinfos << "Scratch Texture GL: " << (sScratchTexBytes/1024) << "KB" << llendl;
-}
-
// static
void LLVOAvatar::dumpBakedStatus()
{
LLVector3d camera_pos_global = gAgent.getCameraPositionGlobal();
for (std::vector<LLCharacter*>::iterator iter = LLCharacter::sInstances.begin();
- iter != LLCharacter::sInstances.end(); ++iter)
+ iter != LLCharacter::sInstances.end(); ++iter)
{
LLVOAvatar* inst = (LLVOAvatar*) *iter;
llinfos << "Avatar ";
@@ -1190,18 +926,17 @@ void LLVOAvatar::dumpBakedStatus()
{
llcont << " Unbaked (";
- for (LLVOAvatarDictionary::baked_map_t::const_iterator iter = LLVOAvatarDictionary::getInstance()->getBakedTextures().begin();
+ for (LLVOAvatarDictionary::BakedTextures::const_iterator iter = LLVOAvatarDictionary::getInstance()->getBakedTextures().begin();
iter != LLVOAvatarDictionary::getInstance()->getBakedTextures().end();
iter++)
{
- const LLVOAvatarDictionary::BakedDictionaryEntry *baked_dict = iter->second;
+ const LLVOAvatarDictionary::BakedEntry *baked_dict = iter->second;
const ETextureIndex index = baked_dict->mTextureIndex;
if (!inst->isTextureDefined(index))
{
llcont << " " << LLVOAvatarDictionary::getInstance()->getTexture(index)->mName;
}
}
-
llcont << " ) " << inst->getUnbakedPixelAreaRank();
if( inst->isCulled() )
{
@@ -1215,17 +950,15 @@ void LLVOAvatar::dumpBakedStatus()
//static
void LLVOAvatar::restoreGL()
{
- for (std::vector<LLCharacter*>::iterator iter = LLCharacter::sInstances.begin();
- iter != LLCharacter::sInstances.end(); ++iter)
+ LLVOAvatar* self = gAgent.getAvatarObject();
+ if (!self)
+ return;
+ self->setCompositeUpdatesEnabled(TRUE);
+ for (U32 i = 0; i < self->mBakedTextureDatas.size(); i++)
{
- LLVOAvatar* inst = (LLVOAvatar*) *iter;
- inst->setCompositeUpdatesEnabled( TRUE );
- for (U32 i = 0; i < inst->mBakedTextureData.size(); i++)
- {
- inst->invalidateComposite( inst->mBakedTextureData[i].mTexLayerSet, FALSE );
- }
- inst->updateMeshTextures();
+ self->invalidateComposite(self->mBakedTextureDatas[i].mTexLayerSet, FALSE);
}
+ self->updateMeshTextures();
}
//static
@@ -1240,7 +973,7 @@ void LLVOAvatar::destroyGL()
void LLVOAvatar::resetImpostors()
{
for (std::vector<LLCharacter*>::iterator iter = LLCharacter::sInstances.begin();
- iter != LLCharacter::sInstances.end(); ++iter)
+ iter != LLCharacter::sInstances.end(); ++iter)
{
LLVOAvatar* avatar = (LLVOAvatar*) *iter;
avatar->mImpostor.release();
@@ -1254,33 +987,15 @@ void LLVOAvatar::deleteCachedImages(bool clearAll)
{
lldebugs << "Deleting layer set caches" << llendl;
for (std::vector<LLCharacter*>::iterator iter = LLCharacter::sInstances.begin();
- iter != LLCharacter::sInstances.end(); ++iter)
+ iter != LLCharacter::sInstances.end(); ++iter)
{
LLVOAvatar* inst = (LLVOAvatar*) *iter;
inst->deleteLayerSetCaches(clearAll);
}
LLTexLayerSet::sHasCaches = FALSE;
}
-
- for( LLGLuint* namep = sScratchTexNames.getFirstData();
- namep;
- namep = sScratchTexNames.getNextData() )
- {
- LLImageGL::deleteTextures(1, (U32 *)namep );
- stop_glerror();
- }
-
- if( sScratchTexBytes )
- {
- lldebugs << "Clearing Scratch Textures " << (sScratchTexBytes/1024) << "KB" << llendl;
-
- sScratchTexNames.deleteAllData();
- LLVOAvatar::sScratchTexLastBindTime.deleteAllData();
- LLImageGL::sGlobalTextureMemoryInBytes -= sScratchTexBytes;
- sScratchTexBytes = 0;
- }
-
- gTexStaticImageList.deleteCachedImages();
+ LLVOAvatarSelf::deleteScratchTextures();
+ LLTexLayerStaticImageList::getInstance()->deleteCachedImages();
}
@@ -1382,20 +1097,168 @@ void LLVOAvatar::initClass()
{
llerrs << "Error parsing skeleton node in avatar XML file: " << skeleton_path << llendl;
}
-
+ if (!sAvatarXmlInfo->parseXmlMorphNodes(root))
+ {
+ llerrs << "Error parsing skeleton node in avatar XML file: " << skeleton_path << llendl;
+ }
}
void LLVOAvatar::cleanupClass()
{
- delete sAvatarXmlInfo;
- sAvatarXmlInfo = NULL;
- delete sAvatarSkeletonInfo;
- sAvatarSkeletonInfo = NULL;
+ deleteAndClear(sAvatarXmlInfo);
sSkeletonXMLTree.cleanup();
sXMLTree.cleanup();
}
+void LLVOAvatar::initInstance(void)
+{
+ //-------------------------------------------------------------------------
+ // initialize joint, mesh and shape members
+ //-------------------------------------------------------------------------
+ mRoot.setName( "mRoot" );
+
+ for (LLVOAvatarDictionary::Meshes::const_iterator iter = LLVOAvatarDictionary::getInstance()->getMeshes().begin();
+ iter != LLVOAvatarDictionary::getInstance()->getMeshes().end();
+ iter++)
+ {
+ const EMeshIndex mesh_index = iter->first;
+ const LLVOAvatarDictionary::MeshEntry *mesh_dict = iter->second;
+ LLViewerJoint* joint = new LLViewerJoint();
+ joint->setName(mesh_dict->mName);
+ joint->setMeshID(mesh_index);
+ mMeshLOD.push_back(joint);
+
+ /* mHairLOD.setName("mHairLOD");
+ mHairMesh0.setName("mHairMesh0");
+ mHairMesh0.setMeshID(MESH_ID_HAIR);
+ mHairMesh1.setName("mHairMesh1"); */
+ for (U32 lod = 0; lod < mesh_dict->mLOD; lod++)
+ {
+ LLViewerJointMesh* mesh = new LLViewerJointMesh();
+ std::string mesh_name = "m" + mesh_dict->mName + boost::lexical_cast<std::string>(lod);
+ // We pre-pended an m - need to capitalize first character for camelCase
+ mesh_name[1] = toupper(mesh_name[1]);
+ mesh->setName(mesh_name);
+ mesh->setMeshID(mesh_index);
+ mesh->setPickName(mesh_dict->mPickName);
+ mesh->setIsTransparent(FALSE);
+ switch((int)mesh_index)
+ {
+ case MESH_ID_HAIR:
+ mesh->setIsTransparent(TRUE);
+ break;
+ case MESH_ID_SKIRT:
+ mesh->setIsTransparent(TRUE);
+ break;
+ case MESH_ID_EYEBALL_LEFT:
+ case MESH_ID_EYEBALL_RIGHT:
+ mesh->setSpecular( LLColor4( 1.0f, 1.0f, 1.0f, 1.0f ), 1.f );
+ break;
+ }
+
+ joint->mMeshParts.push_back(mesh);
+ }
+ }
+
+ //-------------------------------------------------------------------------
+ // associate baked textures with meshes
+ //-------------------------------------------------------------------------
+ for (LLVOAvatarDictionary::Meshes::const_iterator iter = LLVOAvatarDictionary::getInstance()->getMeshes().begin();
+ iter != LLVOAvatarDictionary::getInstance()->getMeshes().end();
+ iter++)
+ {
+ const EMeshIndex mesh_index = iter->first;
+ const LLVOAvatarDictionary::MeshEntry *mesh_dict = iter->second;
+ const EBakedTextureIndex baked_texture_index = mesh_dict->mBakedID;
+ // Skip it if there's no associated baked texture.
+ if (baked_texture_index == BAKED_NUM_INDICES) continue;
+
+ for (std::vector<LLViewerJointMesh* >::iterator iter = mMeshLOD[mesh_index]->mMeshParts.begin();
+ iter != mMeshLOD[mesh_index]->mMeshParts.end(); iter++)
+ {
+ LLViewerJointMesh* mesh = (LLViewerJointMesh*) *iter;
+ mBakedTextureDatas[(int)baked_texture_index].mMeshes.push_back(mesh);
+ }
+ }
+
+
+ //-------------------------------------------------------------------------
+ // register motions
+ //-------------------------------------------------------------------------
+ if (LLCharacter::sInstances.size() == 1)
+ {
+ LLKeyframeMotion::setVFS(gStaticVFS);
+ registerMotion( ANIM_AGENT_BUSY, LLNullMotion::create );
+ registerMotion( ANIM_AGENT_CROUCH, LLKeyframeStandMotion::create );
+ registerMotion( ANIM_AGENT_CROUCHWALK, LLKeyframeWalkMotion::create );
+ registerMotion( ANIM_AGENT_EXPRESS_AFRAID, LLEmote::create );
+ registerMotion( ANIM_AGENT_EXPRESS_ANGER, LLEmote::create );
+ registerMotion( ANIM_AGENT_EXPRESS_BORED, LLEmote::create );
+ registerMotion( ANIM_AGENT_EXPRESS_CRY, LLEmote::create );
+ registerMotion( ANIM_AGENT_EXPRESS_DISDAIN, LLEmote::create );
+ registerMotion( ANIM_AGENT_EXPRESS_EMBARRASSED, LLEmote::create );
+ registerMotion( ANIM_AGENT_EXPRESS_FROWN, LLEmote::create );
+ registerMotion( ANIM_AGENT_EXPRESS_KISS, LLEmote::create );
+ registerMotion( ANIM_AGENT_EXPRESS_LAUGH, LLEmote::create );
+ registerMotion( ANIM_AGENT_EXPRESS_OPEN_MOUTH, LLEmote::create );
+ registerMotion( ANIM_AGENT_EXPRESS_REPULSED, LLEmote::create );
+ registerMotion( ANIM_AGENT_EXPRESS_SAD, LLEmote::create );
+ registerMotion( ANIM_AGENT_EXPRESS_SHRUG, LLEmote::create );
+ registerMotion( ANIM_AGENT_EXPRESS_SMILE, LLEmote::create );
+ registerMotion( ANIM_AGENT_EXPRESS_SURPRISE, LLEmote::create );
+ registerMotion( ANIM_AGENT_EXPRESS_TONGUE_OUT, LLEmote::create );
+ registerMotion( ANIM_AGENT_EXPRESS_TOOTHSMILE, LLEmote::create );
+ registerMotion( ANIM_AGENT_EXPRESS_WINK, LLEmote::create );
+ registerMotion( ANIM_AGENT_EXPRESS_WORRY, LLEmote::create );
+ registerMotion( ANIM_AGENT_RUN, LLKeyframeWalkMotion::create );
+ registerMotion( ANIM_AGENT_STAND, LLKeyframeStandMotion::create );
+ registerMotion( ANIM_AGENT_STAND_1, LLKeyframeStandMotion::create );
+ registerMotion( ANIM_AGENT_STAND_2, LLKeyframeStandMotion::create );
+ registerMotion( ANIM_AGENT_STAND_3, LLKeyframeStandMotion::create );
+ registerMotion( ANIM_AGENT_STAND_4, LLKeyframeStandMotion::create );
+ registerMotion( ANIM_AGENT_STANDUP, LLKeyframeFallMotion::create );
+ registerMotion( ANIM_AGENT_TURNLEFT, LLKeyframeWalkMotion::create );
+ registerMotion( ANIM_AGENT_TURNRIGHT, LLKeyframeWalkMotion::create );
+ registerMotion( ANIM_AGENT_WALK, LLKeyframeWalkMotion::create );
+
+ // motions without a start/stop bit
+ registerMotion( ANIM_AGENT_BODY_NOISE, LLBodyNoiseMotion::create );
+ registerMotion( ANIM_AGENT_BREATHE_ROT, LLBreatheMotionRot::create );
+ registerMotion( ANIM_AGENT_EDITING, LLEditingMotion::create );
+ registerMotion( ANIM_AGENT_EYE, LLEyeMotion::create );
+ registerMotion( ANIM_AGENT_FEMALE_WALK, LLKeyframeWalkMotion::create );
+ registerMotion( ANIM_AGENT_FLY_ADJUST, LLFlyAdjustMotion::create );
+ registerMotion( ANIM_AGENT_HAND_MOTION, LLHandMotion::create );
+ registerMotion( ANIM_AGENT_HEAD_ROT, LLHeadRotMotion::create );
+ registerMotion( ANIM_AGENT_PELVIS_FIX, LLPelvisFixMotion::create );
+ registerMotion( ANIM_AGENT_SIT_FEMALE, LLKeyframeMotion::create );
+ registerMotion( ANIM_AGENT_TARGET, LLTargetingMotion::create );
+ registerMotion( ANIM_AGENT_WALK_ADJUST, LLWalkAdjustMotion::create );
+
+ }
+
+ if (gNoRender)
+ {
+ return;
+ }
+
+ buildCharacter();
+
+ if (gNoRender)
+ {
+ return;
+ }
+
+ // preload specific motions here
+ createMotion( ANIM_AGENT_CUSTOMIZE);
+ createMotion( ANIM_AGENT_CUSTOMIZE_DONE);
+
+ //VTPause(); // VTune
+
+ mVoiceVisualizer->setVoiceEnabled( gVoiceClient->getVoiceEnabled( mID ) );
+}
+
const LLVector3 LLVOAvatar::getRenderPosition() const
{
if (mDrawable.isNull() || mDrawable->getGeneration() < 0)
@@ -1461,7 +1324,7 @@ void LLVOAvatar::getSpatialExtents(LLVector3& newMin, LLVector3& newMax)
for (S32 joint_num = 0; joint_num < mesh->mJointRenderData.count(); joint_num++)
{
update_min_max(newMin, newMax,
- mesh->mJointRenderData[joint_num]->mWorldMatrix->getTranslation());
+ mesh->mJointRenderData[joint_num]->mWorldMatrix->getTranslation());
}
}
@@ -1469,8 +1332,8 @@ void LLVOAvatar::getSpatialExtents(LLVector3& newMin, LLVector3& newMax)
//stretch bounding box by attachments
for (attachment_map_t::iterator iter = mAttachmentPoints.begin();
- iter != mAttachmentPoints.end();
- ++iter)
+ iter != mAttachmentPoints.end();
+ ++iter)
{
LLViewerJointAttachment* attachment = iter->second;
@@ -1535,11 +1398,9 @@ BOOL LLVOAvatar::lineSegmentIntersect(const LLVector3& start, const LLVector3& e
LLVector3* intersection,
LLVector2* tex_coord,
LLVector3* normal,
- LLVector3* bi_normal
- )
+ LLVector3* bi_normal)
{
-
- if (mIsSelf && !gAgent.needsRenderAvatar() || !LLPipeline::sPickAvatar)
+ if (isSelf() && !gAgent.needsRenderAvatar() || !LLPipeline::sPickAvatar)
{
return FALSE;
}
@@ -1668,7 +1529,6 @@ BOOL LLVOAvatar::setupBone(const LLVOAvatarBoneInfo* info, LLViewerJoint* parent
return FALSE;
}
joint = (LLViewerJoint*)(&mCollisionVolumes[volume_num]);
-
joint->setName( info->mName );
}
@@ -1679,10 +1539,8 @@ BOOL LLVOAvatar::setupBone(const LLVOAvatarBoneInfo* info, LLViewerJoint* parent
}
joint->setPosition(info->mPos);
-
joint->setRotation(mayaQ(info->mRot.mV[VX], info->mRot.mV[VY],
info->mRot.mV[VZ], LLQuaternion::XYZ));
-
joint->setScale(info->mScale);
@@ -1751,18 +1609,6 @@ BOOL LLVOAvatar::buildSkeleton(const LLVOAvatarSkeletonInfo *info)
}
}
- // add special-purpose "screen" joint
- if (mIsSelf)
- {
- mScreenp = new LLViewerJoint("mScreen", NULL);
- // for now, put screen at origin, as it is only used during special
- // HUD rendering mode
- F32 aspect = LLViewerCamera::getInstance()->getAspect();
- LLVector3 scale(1.f, aspect, 1.f);
- mScreenp->setScale(scale);
- mScreenp->setWorldPosition(LLVector3::zero);
- }
-
return TRUE;
}
@@ -1811,11 +1657,11 @@ void LLVOAvatar::buildCharacter()
// clear mesh data
//-------------------------------------------------------------------------
for (std::vector<LLViewerJoint*>::iterator jointIter = mMeshLOD.begin();
- jointIter != mMeshLOD.end(); jointIter++)
+ jointIter != mMeshLOD.end(); jointIter++)
{
LLViewerJoint* joint = (LLViewerJoint*) *jointIter;
for (std::vector<LLViewerJointMesh*>::iterator meshIter = joint->mMeshParts.begin();
- meshIter != joint->mMeshParts.end(); meshIter++)
+ meshIter != joint->mMeshParts.end(); meshIter++)
{
LLViewerJointMesh * mesh = (LLViewerJointMesh *) *meshIter;
mesh->setMesh(NULL);
@@ -1839,9 +1685,9 @@ void LLVOAvatar::buildCharacter()
// gPrintMessagesThisFrame = TRUE;
lldebugs << "Avatar load took " << timer.getElapsedTimeF32() << " seconds." << llendl;
- if ( ! status )
+ if (!status)
{
- if ( mIsSelf )
+ if (isSelf())
{
llerrs << "Unable to load user's avatar" << llendl;
}
@@ -1878,23 +1724,23 @@ void LLVOAvatar::buildCharacter()
// Make sure "well known" pointers exist
//-------------------------------------------------------------------------
if (!(mPelvisp &&
- mTorsop &&
- mChestp &&
- mNeckp &&
- mHeadp &&
- mSkullp &&
- mHipLeftp &&
- mHipRightp &&
- mKneeLeftp &&
- mKneeRightp &&
- mAnkleLeftp &&
- mAnkleRightp &&
- mFootLeftp &&
- mFootRightp &&
- mWristLeftp &&
- mWristRightp &&
- mEyeLeftp &&
- mEyeRightp))
+ mTorsop &&
+ mChestp &&
+ mNeckp &&
+ mHeadp &&
+ mSkullp &&
+ mHipLeftp &&
+ mHipRightp &&
+ mKneeLeftp &&
+ mKneeRightp &&
+ mAnkleLeftp &&
+ mAnkleRightp &&
+ mFootLeftp &&
+ mFootRightp &&
+ mWristLeftp &&
+ mWristRightp &&
+ mEyeLeftp &&
+ mEyeRightp))
{
llerrs << "Failed to create avatar." << llendl;
return;
@@ -1940,197 +1786,6 @@ void LLVOAvatar::buildCharacter()
mIsBuilt = TRUE;
stop_glerror();
- //-------------------------------------------------------------------------
- // build the attach and detach menus
- //-------------------------------------------------------------------------
- if (mIsSelf)
- {
- // *TODO: Translate
- gAttachBodyPartPieMenus[0] = NULL;
- gAttachBodyPartPieMenus[1] = new LLPieMenu(std::string("Right Arm >"));
- gAttachBodyPartPieMenus[2] = new LLPieMenu(std::string("Head >"));
- gAttachBodyPartPieMenus[3] = new LLPieMenu(std::string("Left Arm >"));
- gAttachBodyPartPieMenus[4] = NULL;
- gAttachBodyPartPieMenus[5] = new LLPieMenu(std::string("Left Leg >"));
- gAttachBodyPartPieMenus[6] = new LLPieMenu(std::string("Torso >"));
- gAttachBodyPartPieMenus[7] = new LLPieMenu(std::string("Right Leg >"));
-
- gDetachBodyPartPieMenus[0] = NULL;
- gDetachBodyPartPieMenus[1] = new LLPieMenu(std::string("Right Arm >"));
- gDetachBodyPartPieMenus[2] = new LLPieMenu(std::string("Head >"));
- gDetachBodyPartPieMenus[3] = new LLPieMenu(std::string("Left Arm >"));
- gDetachBodyPartPieMenus[4] = NULL;
- gDetachBodyPartPieMenus[5] = new LLPieMenu(std::string("Left Leg >"));
- gDetachBodyPartPieMenus[6] = new LLPieMenu(std::string("Torso >"));
- gDetachBodyPartPieMenus[7] = new LLPieMenu(std::string("Right Leg >"));
-
- for (S32 i = 0; i < 8; i++)
- {
- if (gAttachBodyPartPieMenus[i])
- {
- gAttachPieMenu->appendPieMenu( gAttachBodyPartPieMenus[i] );
- }
- else
- {
- BOOL attachment_found = FALSE;
- for (attachment_map_t::iterator iter = mAttachmentPoints.begin();
- iter != mAttachmentPoints.end(); )
- {
- attachment_map_t::iterator curiter = iter++;
- LLViewerJointAttachment* attachment = curiter->second;
- if (attachment->getGroup() == i)
- {
- LLMenuItemCallGL* item;
- item = new LLMenuItemCallGL(attachment->getName(),
- NULL,
- object_selected_and_point_valid);
- item->addListener(gMenuHolder->getListenerByName("Object.AttachToAvatar"), "on_click", curiter->first);
-
- gAttachPieMenu->append(item);
-
- attachment_found = TRUE;
- break;
-
- }
- }
-
- if (!attachment_found)
- {
- gAttachPieMenu->appendSeparator();
- }
- }
-
- if (gDetachBodyPartPieMenus[i])
- {
- gDetachPieMenu->appendPieMenu( gDetachBodyPartPieMenus[i] );
- }
- else
- {
- BOOL attachment_found = FALSE;
- for (attachment_map_t::iterator iter = mAttachmentPoints.begin();
- iter != mAttachmentPoints.end(); )
- {
- attachment_map_t::iterator curiter = iter++;
- LLViewerJointAttachment* attachment = curiter->second;
- if (attachment->getGroup() == i)
- {
- gDetachPieMenu->append(new LLMenuItemCallGL(attachment->getName(),
- &handle_detach_from_avatar, object_attached, attachment));
-
- attachment_found = TRUE;
- break;
- }
- }
-
- if (!attachment_found)
- {
- gDetachPieMenu->appendSeparator();
- }
- }
- }
-
- // add screen attachments
- for (attachment_map_t::iterator iter = mAttachmentPoints.begin();
- iter != mAttachmentPoints.end(); )
- {
- attachment_map_t::iterator curiter = iter++;
- LLViewerJointAttachment* attachment = curiter->second;
- if (attachment->getGroup() == 8)
- {
- LLMenuItemCallGL* item;
- item = new LLMenuItemCallGL(attachment->getName(),
- NULL,
- object_selected_and_point_valid);
- item->addListener(gMenuHolder->getListenerByName("Object.AttachToAvatar"), "on_click", curiter->first);
- gAttachScreenPieMenu->append(item);
- gDetachScreenPieMenu->append(new LLMenuItemCallGL(attachment->getName(),
- &handle_detach_from_avatar, object_attached, attachment));
- }
- }
-
- for (S32 pass = 0; pass < 2; pass++)
- {
- for (attachment_map_t::iterator iter = mAttachmentPoints.begin();
- iter != mAttachmentPoints.end(); )
- {
- attachment_map_t::iterator curiter = iter++;
- LLViewerJointAttachment* attachment = curiter->second;
- if (attachment->getIsHUDAttachment() != (pass == 1))
- {
- continue;
- }
- LLMenuItemCallGL* item = new LLMenuItemCallGL(attachment->getName(),
- NULL, &object_selected_and_point_valid,
- &attach_label, attachment);
- item->addListener(gMenuHolder->getListenerByName("Object.AttachToAvatar"), "on_click", curiter->first);
- gAttachSubMenu->append(item);
-
- gDetachSubMenu->append(new LLMenuItemCallGL(attachment->getName(),
- &handle_detach_from_avatar, object_attached, &detach_label, attachment));
-
- }
- if (pass == 0)
- {
- // put separator between non-hud and hud attachments
- gAttachSubMenu->appendSeparator();
- gDetachSubMenu->appendSeparator();
- }
- }
-
- for (S32 group = 0; group < 8; group++)
- {
- // skip over groups that don't have sub menus
- if (!gAttachBodyPartPieMenus[group] || !gDetachBodyPartPieMenus[group])
- {
- continue;
- }
-
- std::multimap<S32, S32> attachment_pie_menu_map;
-
- // gather up all attachment points assigned to this group, and throw into map sorted by pie slice number
- for (attachment_map_t::iterator iter = mAttachmentPoints.begin();
- iter != mAttachmentPoints.end(); )
- {
- attachment_map_t::iterator curiter = iter++;
- LLViewerJointAttachment* attachment = curiter->second;
- if(attachment->getGroup() == group)
- {
- // use multimap to provide a partial order off of the pie slice key
- S32 pie_index = attachment->getPieSlice();
- attachment_pie_menu_map.insert(std::make_pair(pie_index, curiter->first));
- }
- }
-
- // add in requested order to pie menu, inserting separators as necessary
- S32 cur_pie_slice = 0;
- for (std::multimap<S32, S32>::iterator attach_it = attachment_pie_menu_map.begin();
- attach_it != attachment_pie_menu_map.end(); ++attach_it)
- {
- S32 requested_pie_slice = attach_it->first;
- S32 attach_index = attach_it->second;
- while (cur_pie_slice < requested_pie_slice)
- {
- gAttachBodyPartPieMenus[group]->appendSeparator();
- gDetachBodyPartPieMenus[group]->appendSeparator();
- cur_pie_slice++;
- }
-
- LLViewerJointAttachment* attachment = get_if_there(mAttachmentPoints, attach_index, (LLViewerJointAttachment*)NULL);
- if (attachment)
- {
- LLMenuItemCallGL* item = new LLMenuItemCallGL(attachment->getName(),
- NULL, object_selected_and_point_valid);
- gAttachBodyPartPieMenus[group]->append(item);
- item->addListener(gMenuHolder->getListenerByName("Object.AttachToAvatar"), "on_click", attach_index);
- gDetachBodyPartPieMenus[group]->append(new LLMenuItemCallGL(attachment->getName(),
- &handle_detach_from_avatar,
- object_attached, attachment));
- cur_pie_slice++;
- }
- }
- }
- }
-
mMeshValid = TRUE;
}
@@ -2151,7 +1806,7 @@ void LLVOAvatar::releaseMeshData()
// cleanup mesh data
for (std::vector<LLViewerJoint*>::iterator iter = mMeshLOD.begin();
- iter != mMeshLOD.end(); iter++)
+ iter != mMeshLOD.end(); iter++)
{
LLViewerJoint* joint = (LLViewerJoint*) *iter;
joint->setValid(FALSE, TRUE);
@@ -2185,29 +1840,24 @@ void LLVOAvatar::releaseMeshData()
//-----------------------------------------------------------------------------
// restoreMeshData()
//-----------------------------------------------------------------------------
+// virtual
void LLVOAvatar::restoreMeshData()
{
+ llassert(!isSelf());
LLMemType mt(LLMemType::MTYPE_AVATAR);
//llinfos << "Restoring" << llendl;
mMeshValid = TRUE;
updateJointLODs();
- if (mIsSelf)
- {
- updateAttachmentVisibility(gAgent.getCameraMode());
- }
- else
+ for (attachment_map_t::iterator iter = mAttachmentPoints.begin();
+ iter != mAttachmentPoints.end(); )
{
- for (attachment_map_t::iterator iter = mAttachmentPoints.begin();
- iter != mAttachmentPoints.end(); )
+ attachment_map_t::iterator curiter = iter++;
+ LLViewerJointAttachment* attachment = curiter->second;
+ if (!attachment->getIsHUDAttachment())
{
- attachment_map_t::iterator curiter = iter++;
- LLViewerJointAttachment* attachment = curiter->second;
- if (!attachment->getIsHUDAttachment())
- {
- attachment->setAttachmentVisibility(TRUE);
- }
+ attachment->setAttachmentVisibility(TRUE);
}
}
@@ -2393,9 +2043,9 @@ void LLVOAvatar::computeBodySize()
// LLVOAvatar::processUpdateMessage()
//------------------------------------------------------------------------
U32 LLVOAvatar::processUpdateMessage(LLMessageSystem *mesgsys,
- void **user_data,
- U32 block_num, const EObjectUpdateType update_type,
- LLDataPacker *dp)
+ void **user_data,
+ U32 block_num, const EObjectUpdateType update_type,
+ LLDataPacker *dp)
{
LLMemType mt(LLMemType::MTYPE_AVATAR);
@@ -2434,8 +2084,8 @@ S32 LLVOAvatar::setTETexture(const U8 te, const LLUUID& uuid)
}
}
-
-// setTEImage
+static LLFastTimer::DeclareTimer FTM_AVATAR_UPDATE("Update Avatar");
+static LLFastTimer::DeclareTimer FTM_JOINT_UPDATE("Update Joints");
//------------------------------------------------------------------------
// idleUpdate()
@@ -2443,7 +2093,7 @@ S32 LLVOAvatar::setTETexture(const U8 te, const LLUUID& uuid)
BOOL LLVOAvatar::idleUpdate(LLAgent &agent, LLWorld &world, const F64 &time)
{
LLMemType mt(LLMemType::MTYPE_AVATAR);
- LLFastTimer t(LLFastTimer::FTM_AVATAR_UPDATE);
+ LLFastTimer t(FTM_AVATAR_UPDATE);
if (isDead())
{
@@ -2462,7 +2112,7 @@ BOOL LLVOAvatar::idleUpdate(LLAgent &agent, LLWorld &world, const F64 &time)
// force asynchronous drawable update
if(mDrawable.notNull() && !gNoRender)
{
- LLFastTimer t(LLFastTimer::FTM_JOINT_UPDATE);
+ LLFastTimer t(FTM_JOINT_UPDATE);
if (mIsSitting && getParent())
{
@@ -2491,7 +2141,7 @@ BOOL LLVOAvatar::idleUpdate(LLAgent &agent, LLWorld &world, const F64 &time)
// set alpha flag depending on state
//--------------------------------------------------------------------
- if (mIsSelf)
+ if (isSelf())
{
LLViewerObject::idleUpdate(agent, world, time);
@@ -2515,8 +2165,8 @@ BOOL LLVOAvatar::idleUpdate(LLAgent &agent, LLWorld &world, const F64 &time)
// animate the character
// store off last frame's root position to be consistent with camera position
LLVector3 root_pos_last = mRoot.getWorldPosition();
- bool detailed_update = updateCharacter(agent);
- bool voice_enabled = gVoiceClient->getVoiceEnabled( mID ) && gVoiceClient->inProximalChannel();
+ BOOL detailed_update = updateCharacter(agent);
+ BOOL voice_enabled = gVoiceClient->getVoiceEnabled( mID ) && gVoiceClient->inProximalChannel();
if (gNoRender)
{
@@ -2539,13 +2189,13 @@ BOOL LLVOAvatar::idleUpdate(LLAgent &agent, LLWorld &world, const F64 &time)
void LLVOAvatar::idleUpdateVoiceVisualizer(bool voice_enabled)
{
// disable voice visualizer when in mouselook
- mVoiceVisualizer->setVoiceEnabled( voice_enabled && !(mIsSelf && gAgent.cameraMouselook()) );
+ mVoiceVisualizer->setVoiceEnabled( voice_enabled && !(isSelf() && gAgent.cameraMouselook()) );
if ( voice_enabled )
{
//----------------------------------------------------------------
// Only do gesture triggering for your own avatar, and only when you're in a proximal channel.
//----------------------------------------------------------------
- if( mIsSelf )
+ if( isSelf() )
{
//----------------------------------------------------------------------------------------
// The following takes the voice signal and uses that to trigger gesticulations.
@@ -2567,11 +2217,11 @@ void LLVOAvatar::idleUpdateVoiceVisualizer(bool voice_enabled)
else { llinfos << "oops - CurrentGesticulationLevel can be only 0, 1, or 2" << llendl; }
// this is the call that Karl S. created for triggering gestures from within the code.
- gGestureManager.triggerAndReviseString( gestureString );
+ LLGestureManager::instance().triggerAndReviseString( gestureString );
}
}
- } //if( mIsSelf )
+ } //if( isSelf() )
//-----------------------------------------------------------------------------------------------------------------
// If the avatar is speaking, then the voice amplitude signal is passed to the voice visualizer.
@@ -2580,9 +2230,9 @@ void LLVOAvatar::idleUpdateVoiceVisualizer(bool voice_enabled)
// Notice the calls to "gAwayTimer.reset()". This resets the timer that determines how long the avatar has been
// "away", so that the avatar doesn't lapse into away-mode (and slump over) while the user is still talking.
//-----------------------------------------------------------------------------------------------------------------
- if ( gVoiceClient->getIsSpeaking( mID ) )
+ if (gVoiceClient->getIsSpeaking( mID ))
{
- if ( ! mVoiceVisualizer->getCurrentlySpeaking() )
+ if (!mVoiceVisualizer->getCurrentlySpeaking())
{
mVoiceVisualizer->setStartSpeaking();
@@ -2591,7 +2241,7 @@ void LLVOAvatar::idleUpdateVoiceVisualizer(bool voice_enabled)
mVoiceVisualizer->setSpeakingAmplitude( gVoiceClient->getCurrentPower( mID ) );
- if( mIsSelf )
+ if( isSelf() )
{
gAgent.clearAFK();
}
@@ -2624,6 +2274,8 @@ void LLVOAvatar::idleUpdateVoiceVisualizer(bool voice_enabled)
}//if ( voiceEnabled )
}
+static LLFastTimer::DeclareTimer FTM_ATTACHMENT_UPDATE("Update Attachments");
+
void LLVOAvatar::idleUpdateMisc(bool detailed_update)
{
if (LLVOAvatar::sJointDebug)
@@ -2645,7 +2297,7 @@ void LLVOAvatar::idleUpdateMisc(bool detailed_update)
// update attachments positions
if (detailed_update || !sUseImpostors)
{
- LLFastTimer t(LLFastTimer::FTM_ATTACHMENT_UPDATE);
+ LLFastTimer t(FTM_ATTACHMENT_UPDATE);
for (attachment_map_t::iterator iter = mAttachmentPoints.begin();
iter != mAttachmentPoints.end(); )
{
@@ -2654,8 +2306,8 @@ void LLVOAvatar::idleUpdateMisc(bool detailed_update)
LLViewerObject *attached_object = attachment->getObject();
BOOL visibleAttachment = visible || (attached_object &&
- !(attached_object->mDrawable->getSpatialBridge() &&
- attached_object->mDrawable->getSpatialBridge()->getRadius() < 2.0));
+ !(attached_object->mDrawable->getSpatialBridge() &&
+ attached_object->mDrawable->getSpatialBridge()->getRadius() < 2.0));
if (visibleAttachment && attached_object && !attached_object->isDead() && attachment->getValid())
{
@@ -2751,7 +2403,7 @@ void LLVOAvatar::idleUpdateAppearanceAnimation()
}
}
updateVisualParams();
- if (mIsSelf)
+ if (isSelf())
{
gAgent.sendAgentSetAppearance();
}
@@ -2852,7 +2504,7 @@ void LLVOAvatar::idleUpdateLoadingEffect()
particle_parameters.mPartData.mStartColor = LLColor4(1, 1, 1, 0.5f);
particle_parameters.mPartData.mEndColor = LLColor4(1, 1, 1, 0.0f);
particle_parameters.mPartData.mStartScale.mV[VX] = 0.8f;
- LLViewerImage* cloud = gImageList.getImageFromFile("cloud-particle.j2c");
+ LLViewerTexture* cloud = LLViewerTextureManager::getFetchedTextureFromFile("cloud-particle.j2c");
particle_parameters.mPartImageID = cloud->getID();
particle_parameters.mMaxAge = 0.f;
particle_parameters.mPattern = LLPartSysData::LL_PART_SRC_PATTERN_ANGLE_CONE;
@@ -2947,16 +2599,17 @@ void LLVOAvatar::idleUpdateNameTag(const LLVector3& root_pos_last)
BOOL visible_avatar = isVisible() || mNeedsAnimUpdate;
BOOL visible_chat = gSavedSettings.getBOOL("UseChatBubbles") && (mChats.size() || mTyping);
BOOL render_name = visible_chat ||
- (visible_avatar &&
- ((sRenderName == RENDER_NAME_ALWAYS) ||
- (sRenderName == RENDER_NAME_FADE && time_visible < NAME_SHOW_TIME)));
+ (visible_avatar &&
+ ((sRenderName == RENDER_NAME_ALWAYS) ||
+ (sRenderName == RENDER_NAME_FADE && time_visible < NAME_SHOW_TIME)));
// If it's your own avatar, don't draw in mouselook, and don't
// draw if we're specifically hiding our own name.
- if (mIsSelf)
+ if (isSelf())
{
render_name = render_name
- && !gAgent.cameraMouselook()
- && (visible_chat || !gSavedSettings.getBOOL("RenderNameHideSelf"));
+ && !gAgent.cameraMouselook()
+ && (visible_chat || (gSavedSettings.getBOOL("RenderNameShowSelf")
+ && gSavedSettings.getS32("AvatarNameTagMode") ));
}
if ( render_name )
@@ -3013,7 +2666,7 @@ void LLVOAvatar::idleUpdateNameTag(const LLVector3& root_pos_last)
new_name = TRUE;
}
- LLColor4 avatar_name_color = gColors.getColor( "AvatarNameColor" );
+ LLColor4 avatar_name_color = LLUIColorTable::instance().getColor( "AvatarNameColor" );
avatar_name_color.setAlpha(alpha);
mNameText->setColor(avatar_name_color);
@@ -3056,7 +2709,7 @@ void LLVOAvatar::idleUpdateNameTag(const LLVector3& root_pos_last)
BOOL is_busy = mSignaledAnimations.find(ANIM_AGENT_BUSY) != mSignaledAnimations.end();
BOOL is_appearance = mSignaledAnimations.find(ANIM_AGENT_CUSTOMIZE) != mSignaledAnimations.end();
BOOL is_muted;
- if (mIsSelf)
+ if (isSelf())
{
is_muted = FALSE;
}
@@ -3101,7 +2754,7 @@ void LLVOAvatar::idleUpdateNameTag(const LLVector3& root_pos_last)
line += " (";
if (is_away)
{
- line += "Away";
+ line += LLTrans::getString("AvatarAway");
need_comma = TRUE;
}
if (is_busy)
@@ -3110,7 +2763,7 @@ void LLVOAvatar::idleUpdateNameTag(const LLVector3& root_pos_last)
{
line += ", ";
}
- line += "Busy";
+ line += LLTrans::getString("AvatarBusy");
need_comma = TRUE;
}
if (is_muted)
@@ -3119,7 +2772,7 @@ void LLVOAvatar::idleUpdateNameTag(const LLVector3& root_pos_last)
{
line += ", ";
}
- line += "Muted";
+ line += LLTrans::getString("AvatarMuted");
need_comma = TRUE;
}
line += ")";
@@ -3127,7 +2780,7 @@ void LLVOAvatar::idleUpdateNameTag(const LLVector3& root_pos_last)
if (is_appearance)
{
line += "\n";
- line += "(Editing Appearance)";
+ line += LLTrans::getString("AvatarEditingAppearance");
}
mNameAway = is_away;
mNameBusy = is_busy;
@@ -3155,7 +2808,7 @@ void LLVOAvatar::idleUpdateNameTag(const LLVector3& root_pos_last)
std::deque<LLChat>::iterator chat_iter = mChats.begin();
mNameText->clearString();
- LLColor4 new_chat = gColors.getColor( "AvatarNameColor" );
+ LLColor4 new_chat = LLUIColorTable::instance().getColor( "AvatarNameColor" );
LLColor4 normal_chat = lerp(new_chat, LLColor4(0.8f, 0.8f, 0.8f, 1.f), 0.7f);
LLColor4 old_chat = lerp(normal_chat, LLColor4(0.6f, 0.6f, 0.6f, 1.f), 0.7f);
if (mTyping && mChats.size() >= MAX_BUBBLE_CHAT_UTTERANCES)
@@ -3169,15 +2822,15 @@ void LLVOAvatar::idleUpdateNameTag(const LLVector3& root_pos_last)
LLFontGL::StyleFlags style;
switch(chat_iter->mChatType)
{
- case CHAT_TYPE_WHISPER:
- style = LLFontGL::ITALIC;
- break;
- case CHAT_TYPE_SHOUT:
- style = LLFontGL::BOLD;
- break;
- default:
- style = LLFontGL::NORMAL;
- break;
+ case CHAT_TYPE_WHISPER:
+ style = LLFontGL::ITALIC;
+ break;
+ case CHAT_TYPE_SHOUT:
+ style = LLFontGL::BOLD;
+ break;
+ default:
+ style = LLFontGL::NORMAL;
+ break;
}
if (chat_fade_amt < 1.f)
{
@@ -3202,15 +2855,15 @@ void LLVOAvatar::idleUpdateNameTag(const LLVector3& root_pos_last)
S32 dot_count = (llfloor(mTypingTimer.getElapsedTimeF32() * 3.f) + 2) % 3 + 1;
switch(dot_count)
{
- case 1:
- mNameText->addLine(".", new_chat);
- break;
- case 2:
- mNameText->addLine("..", new_chat);
- break;
- case 3:
- mNameText->addLine("...", new_chat);
- break;
+ case 1:
+ mNameText->addLine(".", new_chat);
+ break;
+ case 2:
+ mNameText->addLine("..", new_chat);
+ break;
+ case 3:
+ mNameText->addLine("...", new_chat);
+ break;
}
}
@@ -3244,75 +2897,12 @@ void LLVOAvatar::idleUpdateNameTag(const LLVector3& root_pos_last)
}
}
+//--------------------------------------------------------------------
+// draw tractor beam when editing objects
+//--------------------------------------------------------------------
+// virtual
void LLVOAvatar::idleUpdateTractorBeam()
{
- //--------------------------------------------------------------------
- // draw tractor beam when editing objects
- //--------------------------------------------------------------------
- if (!mIsSelf)
- {
- return;
- }
-
- // This is only done for yourself (maybe it should be in the agent?)
- if (!needsRenderBeam() || !mIsBuilt)
- {
- mBeam = NULL;
- }
- else if (!mBeam || mBeam->isDead())
- {
- // VEFFECT: Tractor Beam
- mBeam = (LLHUDEffectSpiral *)LLHUDManager::getInstance()->createViewerEffect(LLHUDObject::LL_HUD_EFFECT_BEAM);
- mBeam->setColor(LLColor4U(gAgent.getEffectColor()));
- mBeam->setSourceObject(this);
- mBeamTimer.reset();
- }
-
- if (!mBeam.isNull())
- {
- LLObjectSelectionHandle selection = LLSelectMgr::getInstance()->getSelection();
-
- if (gAgent.mPointAt.notNull())
- {
- // get point from pointat effect
- mBeam->setPositionGlobal(gAgent.mPointAt->getPointAtPosGlobal());
- mBeam->triggerLocal();
- }
- else if (selection->getFirstRootObject() &&
- selection->getSelectType() != SELECT_TYPE_HUD)
- {
- LLViewerObject* objectp = selection->getFirstRootObject();
- mBeam->setTargetObject(objectp);
- }
- else
- {
- mBeam->setTargetObject(NULL);
- LLTool *tool = LLToolMgr::getInstance()->getCurrentTool();
- if (tool->isEditing())
- {
- if (tool->getEditingObject())
- {
- mBeam->setTargetObject(tool->getEditingObject());
- }
- else
- {
- mBeam->setPositionGlobal(tool->getEditingPointGlobal());
- }
- }
- else
- {
- const LLPickInfo& pick = gViewerWindow->getLastPick();
- mBeam->setPositionGlobal(pick.mPosGlobal);
- }
-
- }
- if (mBeamTimer.getElapsedTimeF32() > 0.25f)
- {
- mBeam->setColor(LLColor4U(gAgent.getEffectColor()));
- mBeam->setNeedsSendToSim(TRUE);
- mBeamTimer.reset();
- }
- }
}
void LLVOAvatar::idleUpdateBelowWater()
@@ -3344,16 +2934,6 @@ void LLVOAvatar::slamPosition()
BOOL LLVOAvatar::updateCharacter(LLAgent &agent)
{
LLMemType mt(LLMemType::MTYPE_AVATAR);
- // update screen joint size
-
- if (mScreenp)
- {
- F32 aspect = LLViewerCamera::getInstance()->getAspect();
- LLVector3 scale(1.f, aspect, 1.f);
- mScreenp->setScale(scale);
- mScreenp->updateWorldMatrixChildren();
- resetHUDAttachments();
- }
// clear debug text
mDebugText.clear();
@@ -3386,7 +2966,7 @@ BOOL LLVOAvatar::updateCharacter(LLAgent &agent)
if (gNoRender)
{
// Hack if we're running drones...
- if (mIsSelf)
+ if (isSelf())
{
gAgent.setPositionAgent(getPositionAgent());
}
@@ -3415,7 +2995,7 @@ BOOL LLVOAvatar::updateCharacter(LLAgent &agent)
// the rest should only be done occasionally for far away avatars
//--------------------------------------------------------------------
- if (visible && !mIsSelf && !mIsDummy && sUseImpostors && !mNeedsAnimUpdate && !sFreezeCounter)
+ if (visible && !isSelf() && !mIsDummy && sUseImpostors && !mNeedsAnimUpdate && !sFreezeCounter)
{
F32 impostor_area = 256.f*512.f*(8.125f - LLVOAvatar::sLODFactor*8.f);
if (LLMuteList::getInstance()->isMuted(getID()))
@@ -3457,7 +3037,7 @@ BOOL LLVOAvatar::updateCharacter(LLAgent &agent)
}
// change animation time quanta based on avatar render load
- if (!mIsSelf && !mIsDummy)
+ if (!isSelf() && !mIsDummy)
{
F32 time_quantum = clamp_rescale((F32)sInstances.size(), 10.f, 35.f, 0.f, 0.25f);
F32 pixel_area_scale = clamp_rescale(mPixelArea, 100, 5000, 1.f, 0.f);
@@ -3526,7 +3106,7 @@ BOOL LLVOAvatar::updateCharacter(LLAgent &agent)
LLVector3d root_pos;
LLVector3d ground_under_pelvis;
- if (mIsSelf)
+ if (isSelf())
{
gAgent.setPositionAgent(getRenderPosition());
}
@@ -3535,8 +3115,8 @@ BOOL LLVOAvatar::updateCharacter(LLAgent &agent)
resolveHeightGlobal(root_pos, ground_under_pelvis, normal);
F32 foot_to_ground = (F32) (root_pos.mdV[VZ] - mPelvisToFoot - ground_under_pelvis.mdV[VZ]);
- BOOL in_air = ( (!LLWorld::getInstance()->getRegionFromPosGlobal(ground_under_pelvis)) ||
- foot_to_ground > FOOT_GROUND_COLLISION_TOLERANCE);
+ BOOL in_air = ((!LLWorld::getInstance()->getRegionFromPosGlobal(ground_under_pelvis)) ||
+ foot_to_ground > FOOT_GROUND_COLLISION_TOLERANCE);
if (in_air && !mInAir)
{
@@ -3571,7 +3151,7 @@ BOOL LLVOAvatar::updateCharacter(LLAgent &agent)
// more than 90 from the view, if necessary, flip the velocity vector.
LLVector3 primDir;
- if (mIsSelf)
+ if (isSelf())
{
primDir = agent.getAtAxis() - projected_vec(agent.getAtAxis(), agent.getReferenceUpVector());
primDir.normalize();
@@ -3591,7 +3171,7 @@ BOOL LLVOAvatar::updateCharacter(LLAgent &agent)
}
}
LLVector3 fwdDir = lerp(primDir, velDir, clamp_rescale(speed, 0.5f, 2.0f, 0.0f, 1.0f));
- if (mIsSelf && gAgent.cameraMouselook())
+ if (isSelf() && gAgent.cameraMouselook())
{
// make sure fwdDir stays in same general direction as primdir
if (gAgent.getFlying())
@@ -3619,18 +3199,10 @@ BOOL LLVOAvatar::updateCharacter(LLAgent &agent)
F32 root_roll, root_pitch, root_yaw;
root_rotation.getEulerAngles(&root_roll, &root_pitch, &root_yaw);
- if (sDebugAvatarRotation)
- {
- llinfos << "root_roll " << RAD_TO_DEG * root_roll
- << " root_pitch " << RAD_TO_DEG * root_pitch
- << " root_yaw " << RAD_TO_DEG * root_yaw
- << llendl;
- }
-
// When moving very slow, the pelvis is allowed to deviate from the
// forward direction to allow it to hold it's position while the torso
// and head turn. Once in motion, it must conform however.
- BOOL self_in_mouselook = mIsSelf && gAgent.cameraMouselook();
+ BOOL self_in_mouselook = isSelf() && gAgent.cameraMouselook();
LLVector3 pelvisDir( mRoot.getWorldMatrix().getFwdRow4().mV );
F32 pelvis_rot_threshold = clamp_rescale(speed, 0.1f, 1.0f, PELVIS_ROT_THRESHOLD_SLOW, PELVIS_ROT_THRESHOLD_FAST);
@@ -3647,7 +3219,7 @@ BOOL LLVOAvatar::updateCharacter(LLAgent &agent)
// from the forward direction, but if roll or pitch are off even
// a little bit we need to correct the rotation.
if(root_roll < 1.f * DEG_TO_RAD
- && root_pitch < 5.f * DEG_TO_RAD)
+ && root_pitch < 5.f * DEG_TO_RAD)
{
// smaller correction vector means pelvis follows prim direction more closely
if (!mTurning && angle > pelvis_rot_threshold*0.75f)
@@ -3681,7 +3253,7 @@ BOOL LLVOAvatar::updateCharacter(LLAgent &agent)
fwdDir = leftDir % upDir;
LLQuaternion wQv( fwdDir, leftDir, upDir );
- if (mIsSelf && mTurning)
+ if (isSelf() && mTurning)
{
if ((fwdDir % pelvisDir) * upDir > 0.f)
{
@@ -3890,9 +3462,9 @@ void LLVOAvatar::updateVisibility()
visible = FALSE;
}
- if( mIsSelf )
+ if(isSelf())
{
- if( !gAgent.areWearablesLoaded())
+ if (!gAgentWearables.areWearablesLoaded())
{
visible = FALSE;
}
@@ -3997,27 +3569,6 @@ void LLVOAvatar::updateVisibility()
mVisible = visible;
}
-//------------------------------------------------------------------------
-// needsRenderBeam()
-//------------------------------------------------------------------------
-BOOL LLVOAvatar::needsRenderBeam()
-{
- if (gNoRender)
- {
- return FALSE;
- }
- LLTool *tool = LLToolMgr::getInstance()->getCurrentTool();
-
- BOOL is_touching_or_grabbing = (tool == LLToolGrab::getInstance() && LLToolGrab::getInstance()->isEditing());
- if (LLToolGrab::getInstance()->getEditingObject() &&
- LLToolGrab::getInstance()->getEditingObject()->isAttachment())
- {
- // don't render selection beam on hud objects
- is_touching_or_grabbing = FALSE;
- }
- return is_touching_or_grabbing || (mState & AGENT_STATE_EDITING && LLSelectMgr::getInstance()->shouldShowSelection());
-}
-
//-----------------------------------------------------------------------------
// renderSkinned()
//-----------------------------------------------------------------------------
@@ -4051,7 +3602,7 @@ U32 LLVOAvatar::renderSkinned(EAvatarRenderPass pass)
mMeshLOD[MESH_ID_SKIRT]->updateJointGeometry();
}
- if (!mIsSelf || gAgent.needsRenderHead() || LLPipeline::sShadowRender)
+ if (!isSelf() || gAgent.needsRenderHead() || LLPipeline::sShadowRender)
{
mMeshLOD[MESH_ID_EYELASH]->updateJointGeometry();
mMeshLOD[MESH_ID_HEAD]->updateJointGeometry();
@@ -4101,7 +3652,7 @@ U32 LLVOAvatar::renderSkinned(EAvatarRenderPass pass)
return num_indices;
}
- if (mIsSelf && !gAgent.needsRenderAvatar())
+ if (isSelf() && !gAgent.needsRenderAvatar())
{
return num_indices;
}
@@ -4151,17 +3702,10 @@ U32 LLVOAvatar::renderSkinned(EAvatarRenderPass pass)
if (pass == AVATAR_RENDER_PASS_SINGLE)
{
- const bool should_alpha_mask = mHasBakedHair && isTextureDefined(TEX_HEAD_BAKED) && isTextureDefined(TEX_UPPER_BAKED)
- && isTextureDefined(TEX_LOWER_BAKED)
- && mBakedTextureData[BAKED_HEAD].mIsLoaded
- && mBakedTextureData[BAKED_UPPER].mIsLoaded && mBakedTextureData[BAKED_LOWER].mIsLoaded
- && mBakedTextureData[BAKED_HEAD].mIsUsed
- && mBakedTextureData[BAKED_UPPER].mIsUsed && mBakedTextureData[BAKED_LOWER].mIsUsed
- && !LLDrawPoolAlpha::sShowDebugAlpha // Don't alpha mask if "Highlight Transparent" checked
- && !(isSelf() && gAgent.cameraCustomizeAvatar()); // don't alpha mask if in customize mode
+ const bool should_alpha_mask = mSupportsAlphaLayers && !LLDrawPoolAlpha::sShowDebugAlpha; // Don't alpha mask if "Highlight Transparent" checked
LLGLState test(GL_ALPHA_TEST, should_alpha_mask);
-
+
if (should_alpha_mask)
{
gGL.setAlphaRejectSettings(LLRender::CF_GREATER, 0.5f);
@@ -4170,7 +3714,7 @@ U32 LLVOAvatar::renderSkinned(EAvatarRenderPass pass)
BOOL first_pass = TRUE;
if (!LLDrawPoolAvatar::sSkipOpaque)
{
- if (!mIsSelf || gAgent.needsRenderHead() || LLPipeline::sShadowRender)
+ if (!isSelf() || gAgent.needsRenderHead() || LLPipeline::sShadowRender)
{
if (isTextureVisible(TEX_HEAD_BAKED) || mIsDummy)
{
@@ -4221,7 +3765,7 @@ U32 LLVOAvatar::renderTransparent(BOOL first_pass)
gGL.setAlphaRejectSettings(LLRender::CF_DEFAULT);
}
- if (!mIsSelf || gAgent.needsRenderHead() || LLPipeline::sShadowRender)
+ if (!isSelf() || gAgent.needsRenderHead() || LLPipeline::sShadowRender)
{
if (LLPipeline::sImpostorRender)
{
@@ -4235,7 +3779,7 @@ U32 LLVOAvatar::renderTransparent(BOOL first_pass)
}
// Can't test for baked hair being defined, since that won't always be the case (not all viewers send baked hair)
// TODO: 1.25 will be able to switch this logic back to calling isTextureVisible();
- if (getTEImage(TEX_HAIR_BAKED)->getID() != IMG_INVISIBLE || LLDrawPoolAlpha::sShowDebugAlpha)
+ if (getImage(TEX_HAIR_BAKED)->getID() != IMG_INVISIBLE || LLDrawPoolAlpha::sShowDebugAlpha)
{
num_indices += mMeshLOD[MESH_ID_HAIR]->render(mAdjustedPixelArea, first_pass, mIsDummy);
first_pass = FALSE;
@@ -4261,7 +3805,7 @@ U32 LLVOAvatar::renderRigid()
return 0;
}
- if (mIsSelf && (!gAgent.needsRenderAvatar() || !gAgent.needsRenderHead()))
+ if (isSelf() && (!gAgent.needsRenderAvatar() || !gAgent.needsRenderHead()))
{
return 0;
}
@@ -4274,10 +3818,7 @@ U32 LLVOAvatar::renderRigid()
if (isTextureVisible(TEX_EYES_BAKED) || mIsDummy)
{
// If the meshes need to be drawn, enable alpha masking but not blending
- bool should_alpha_mask = mHasBakedHair
- && mBakedTextureData[BAKED_EYES].mIsLoaded
- && mBakedTextureData[BAKED_EYES].mIsUsed
- && !(isSelf() && gAgent.cameraCustomizeAvatar());
+ bool should_alpha_mask = mSupportsAlphaLayers && !LLDrawPoolAlpha::sShowDebugAlpha;
LLGLState test(GL_ALPHA_TEST, should_alpha_mask);
@@ -4304,7 +3845,7 @@ U32 LLVOAvatar::renderFootShadows()
return 0;
}
- if (mIsSelf && (!gAgent.needsRenderAvatar() || !gAgent.needsRenderHead()))
+ if (isSelf() && (!gAgent.needsRenderAvatar() || !gAgent.needsRenderHead()))
{
return 0;
}
@@ -4316,7 +3857,7 @@ U32 LLVOAvatar::renderFootShadows()
// Don't render foot shadows if your lower body is completely invisible.
// (non-humanoid avatars rule!)
- if (! isTextureVisible(TEX_LOWER_BAKED))
+ if (!isTextureVisible(TEX_LOWER_BAKED))
{
return 0;
}
@@ -4334,7 +3875,7 @@ U32 LLVOAvatar::renderFootShadows()
LLGLDepthTest test(GL_TRUE, GL_FALSE);
//render foot shadows
LLGLEnable blend(GL_BLEND);
- gGL.getTexUnit(0)->bind(mShadowImagep.get());
+ gGL.getTexUnit(0)->bind(mShadowImagep);
glColor4fv(mShadow0Facep->getRenderColor().mV);
mShadow0Facep->renderIndexed(foot_mask);
glColor4fv(mShadow1Facep->getRenderColor().mV);
@@ -4391,7 +3932,7 @@ void LLVOAvatar::updateTextures(LLAgent &agent)
return;
}
- if( mIsSelf )
+ if( isSelf() )
{
render_avatar = TRUE;
}
@@ -4400,66 +3941,32 @@ void LLVOAvatar::updateTextures(LLAgent &agent)
render_avatar = isVisible() && !mCulled;
}
- std::vector<bool> layer_baked;
- for (U32 i = 0; i < mBakedTextureData.size(); i++)
+ std::vector<BOOL> layer_baked;
+ for (U32 i = 0; i < mBakedTextureDatas.size(); i++)
{
- layer_baked.push_back(isTextureDefined(mBakedTextureData[i].mTextureIndex));
+ layer_baked.push_back(isTextureDefined(mBakedTextureDatas[i].mTextureIndex));
// bind the texture so that they'll be decoded slightly
// inefficient, we can short-circuit this if we have to
- if( render_avatar && !gGLManager.mIsDisabled )
+ if (render_avatar && !gGLManager.mIsDisabled)
{
- if (layer_baked[i] && !mBakedTextureData[i].mIsLoaded)
+ if (layer_baked[i] && !mBakedTextureDatas[i].mIsLoaded)
{
- gGL.getTexUnit(0)->bind(getTEImage( mBakedTextureData[i].mTextureIndex ));
+ gGL.getTexUnit(0)->bind(getImage( mBakedTextureDatas[i].mTextureIndex ));
}
}
}
- /*
- // JAMESDEBUG
- if (mIsSelf)
- {
- S32 null_count = 0;
- S32 default_count = 0;
- for (U32 i = 0; i < getNumTEs(); i++)
- {
- const LLTextureEntry* te = getTE(i);
- if (te)
- {
- if (te->getID() == LLUUID::null)
- {
- null_count++;
- }
- else if (te->getID() == IMG_DEFAULT_AVATAR)
- {
- default_count++;
- }
- }
- }
- llinfos << "JAMESDEBUG my avatar TE null " << null_count << " default " << default_count << llendl;
- }
- */
-
mMaxPixelArea = 0.f;
mMinPixelArea = 99999999.f;
mHasGrey = FALSE; // debug
for (U32 index = 0; index < getNumTEs(); index++)
{
- LLViewerImage *imagep = getTEImage(index);
+ LLViewerFetchedTexture *imagep = LLViewerTextureManager::staticCastToFetchedTexture(getImage(index), TRUE);
if (imagep)
{
- // Debugging code - maybe non-self avatars are downloading textures?
- //llinfos << "avatar self " << mIsSelf << " tex " << i
- // << " decode " << imagep->getDecodePriority()
- // << " boost " << boost_avatar
- // << " size " << imagep->getWidth() << "x" << imagep->getHeight()
- // << " discard " << imagep->getDiscardLevel()
- // << " desired " << imagep->getDesiredDiscardLevel()
- // << llendl;
-
const LLTextureEntry *te = getTE(index);
- F32 texel_area_ratio = fabs(te->mScaleS * te->mScaleT);
- S32 boost_level = mIsSelf ? LLViewerImage::BOOST_AVATAR_BAKED_SELF : LLViewerImage::BOOST_AVATAR_BAKED;
+ const F32 texel_area_ratio = fabs(te->mScaleS * te->mScaleT);
+ const S32 boost_level = getAvatarBakedBoostLevel();
// Spam if this is a baked texture, not set to default image, without valid host info
if (isIndexBakedTexture((ETextureIndex)index)
@@ -4467,15 +3974,15 @@ void LLVOAvatar::updateTextures(LLAgent &agent)
&& !imagep->getTargetHost().isOk())
{
LL_WARNS_ONCE("Texture") << "LLVOAvatar::updateTextures No host for texture "
- << imagep->getID() << " for avatar "
- << (mIsSelf ? "<myself>" : getID().asString())
- << " on host " << getRegion()->getHost() << llendl;
+ << imagep->getID() << " for avatar "
+ << (isSelf() ? "<myself>" : getID().asString())
+ << " on host " << getRegion()->getHost() << llendl;
}
/* switch(index)
case TEX_HEAD_BODYPAINT:
addLocalTextureStats( LOCTEX_HEAD_BODYPAINT, imagep, texel_area_ratio, render_avatar, head_baked ); */
- const LLVOAvatarDictionary::TextureDictionaryEntry *texture_dict = LLVOAvatarDictionary::getInstance()->getTexture((ETextureIndex)index);
+ const LLVOAvatarDictionary::TextureEntry *texture_dict = LLVOAvatarDictionary::getInstance()->getTexture((ETextureIndex)index);
if (texture_dict->mIsUsedByBakedTexture)
{
const EBakedTextureIndex baked_index = texture_dict->mBakedTextureIndex;
@@ -4506,42 +4013,15 @@ void LLVOAvatar::updateTextures(LLAgent &agent)
}
-void LLVOAvatar::addLocalTextureStats( ETextureIndex idx, LLViewerImage* imagep,
- F32 texel_area_ratio, BOOL render_avatar, BOOL covered_by_baked )
+void LLVOAvatar::addLocalTextureStats( ETextureIndex idx, LLViewerFetchedTexture* imagep,
+ F32 texel_area_ratio, BOOL render_avatar, BOOL covered_by_baked, U32 index )
{
- if (!isIndexLocalTexture(idx)) return;
-
- if (!covered_by_baked && render_avatar) // render_avatar is always true if mIsSelf
- {
- if (getLocalTextureID(idx) != IMG_DEFAULT_AVATAR)
- {
- F32 desired_pixels;
- if( mIsSelf )
- {
- desired_pixels = llmin(mPixelArea, (F32)TEX_IMAGE_AREA_SELF );
- imagep->setBoostLevel(LLViewerImage::BOOST_AVATAR_SELF);
- }
- else
- {
- desired_pixels = llmin(mPixelArea, (F32)TEX_IMAGE_AREA_OTHER );
- imagep->setBoostLevel(LLViewerImage::BOOST_AVATAR);
- }
- imagep->addTextureStats( desired_pixels / texel_area_ratio );
- if (imagep->getDiscardLevel() < 0)
- {
- mHasGrey = TRUE; // for statistics gathering
- }
- }
- else
- {
- // texture asset is missing
- mHasGrey = TRUE; // for statistics gathering
- }
- }
+ // No local texture stats for non-self avatars
+ return;
}
-void LLVOAvatar::addBakedTextureStats( LLViewerImage* imagep, F32 pixel_area, F32 texel_area_ratio, S32 boost_level)
+void LLVOAvatar::addBakedTextureStats( LLViewerFetchedTexture* imagep, F32 pixel_area, F32 texel_area_ratio, S32 boost_level)
{
mMaxPixelArea = llmax(pixel_area, mMaxPixelArea);
mMinPixelArea = llmin(pixel_area, mMinPixelArea);
@@ -4549,6 +4029,29 @@ void LLVOAvatar::addBakedTextureStats( LLViewerImage* imagep, F32 pixel_area, F3
imagep->setBoostLevel(boost_level);
}
+//virtual
+void LLVOAvatar::setImage(const U8 te, LLViewerTexture *imagep)
+{
+ setTEImage(te, imagep);
+}
+
+//virtual
+LLViewerTexture* LLVOAvatar::getImage(const U8 te) const
+{
+ return getTEImage(te);
+}
+//virtual
+const LLTextureEntry* LLVOAvatar::getTexEntry(const U8 te_num) const
+{
+ return getTE(te_num);
+}
+
+//virtual
+void LLVOAvatar::setTexEntry(const U8 index, const LLTextureEntry &te)
+{
+ setTE(index, te);
+}
+
//-----------------------------------------------------------------------------
// resolveHeight()
//-----------------------------------------------------------------------------
@@ -4690,7 +4193,7 @@ void LLVOAvatar::processAnimationStateChanges()
}
// clear source information for animations which have been stopped
- if (mIsSelf)
+ if (isSelf())
{
AnimSourceIterator source_it = mAnimationSources.begin();
@@ -4732,7 +4235,7 @@ BOOL LLVOAvatar::processSingleAnimationStateChange( const LLUUID& anim_id, BOOL
{
// RN: uncomment this to play on typing sound at fixed volume once sound engine is fixed
// to support both spatialized and non-spatialized instances of the same sound
- //if (mIsSelf)
+ //if (isSelf())
//{
// gAudiop->triggerSound(LLUUID(gSavedSettings.getString("UISndTyping")), 1.0f, LLAudioEngine::AUDIO_TYPE_UI);
//}
@@ -4746,7 +4249,7 @@ BOOL LLVOAvatar::processSingleAnimationStateChange( const LLUUID& anim_id, BOOL
}
else if (anim_id == ANIM_AGENT_SIT_GROUND_CONSTRAINED)
{
- mIsSitting = TRUE;
+ sitDown(TRUE);
}
@@ -4763,7 +4266,7 @@ BOOL LLVOAvatar::processSingleAnimationStateChange( const LLUUID& anim_id, BOOL
{
if (anim_id == ANIM_AGENT_SIT_GROUND_CONSTRAINED)
{
- mIsSitting = FALSE;
+ sitDown(FALSE);
}
stopMotion(anim_id);
result = TRUE;
@@ -4775,7 +4278,7 @@ BOOL LLVOAvatar::processSingleAnimationStateChange( const LLUUID& anim_id, BOOL
//-----------------------------------------------------------------------------
// isAnyAnimationSignaled()
//-----------------------------------------------------------------------------
-BOOL LLVOAvatar::isAnyAnimationSignaled(const LLUUID *anim_array, const S32 num_anims)
+BOOL LLVOAvatar::isAnyAnimationSignaled(const LLUUID *anim_array, const S32 num_anims) const
{
for (S32 i = 0; i < num_anims; i++)
{
@@ -4818,7 +4321,7 @@ BOOL LLVOAvatar::startMotion(const LLUUID& id, F32 time_offset)
}
}
- if (mIsSelf && id == ANIM_AGENT_AWAY)
+ if (isSelf() && id == ANIM_AGENT_AWAY)
{
gAgent.setAFK();
}
@@ -4831,7 +4334,7 @@ BOOL LLVOAvatar::startMotion(const LLUUID& id, F32 time_offset)
//-----------------------------------------------------------------------------
BOOL LLVOAvatar::stopMotion(const LLUUID& id, BOOL stop_immediate)
{
- if (mIsSelf)
+ if (isSelf())
{
gAgent.onAnimStop(id);
}
@@ -4851,25 +4354,9 @@ BOOL LLVOAvatar::stopMotion(const LLUUID& id, BOOL stop_immediate)
//-----------------------------------------------------------------------------
// stopMotionFromSource()
//-----------------------------------------------------------------------------
+// virtual
void LLVOAvatar::stopMotionFromSource(const LLUUID& source_id)
{
- if (!mIsSelf)
- {
- return;
- }
- AnimSourceIterator motion_it;
-
- for(motion_it = mAnimationSources.find(source_id); motion_it != mAnimationSources.end();)
- {
- gAgent.sendAnimationRequest( motion_it->second, ANIM_REQUEST_STOP );
- mAnimationSources.erase(motion_it++);
- }
-
- LLViewerObject* object = gObjectList.findObject(source_id);
- if (object)
- {
- object->mFlags &= ~FLAGS_ANIM_SOURCE;
- }
}
//-----------------------------------------------------------------------------
@@ -4917,7 +4404,7 @@ S32 LLVOAvatar::getCollisionVolumeID(std::string &name)
//-----------------------------------------------------------------------------
// addDebugText()
//-----------------------------------------------------------------------------
- void LLVOAvatar::addDebugText(const std::string& text)
+void LLVOAvatar::addDebugText(const std::string& text)
{
mDebugText.append(1, '\n');
mDebugText.append(text);
@@ -4937,15 +4424,7 @@ const LLUUID& LLVOAvatar::getID()
// RN: avatar joints are multi-rooted to include screen-based attachments
LLJoint *LLVOAvatar::getJoint( const std::string &name )
{
- LLJoint* jointp = NULL;
- if (mScreenp)
- {
- jointp = mScreenp->findJoint(name);
- }
- if (!jointp)
- {
- jointp = mRoot.findJoint(name);
- }
+ LLJoint* jointp = mRoot.findJoint(name);
return jointp;
}
@@ -5075,8 +4554,7 @@ LLVector3 LLVOAvatar::getPosAgentFromGlobal(const LLVector3d &position)
//-----------------------------------------------------------------------------
BOOL LLVOAvatar::allocateCharacterJoints( U32 num )
{
- delete [] mSkeleton;
- mSkeleton = NULL;
+ deleteAndClearArray(mSkeleton);
mNumJoints = 0;
mSkeleton = new LLViewerJoint[num];
@@ -5100,8 +4578,7 @@ BOOL LLVOAvatar::allocateCharacterJoints( U32 num )
//-----------------------------------------------------------------------------
BOOL LLVOAvatar::allocateCollisionVolumes( U32 num )
{
- delete [] mCollisionVolumes;
- mCollisionVolumes = NULL;
+ deleteAndClearArray(mCollisionVolumes);
mNumCollisionVolumes = 0;
mCollisionVolumes = new LLViewerJointCollisionVolume[num];
@@ -5131,22 +4608,20 @@ LLJoint *LLVOAvatar::getCharacterJoint( U32 num )
//-----------------------------------------------------------------------------
// requestStopMotion()
//-----------------------------------------------------------------------------
+// virtual
void LLVOAvatar::requestStopMotion( LLMotion* motion )
{
// Only agent avatars should handle the stop motion notifications.
- if ( mIsSelf )
- {
- // Notify agent that motion has stopped
- gAgent.requestStopMotion( motion );
- }
}
//-----------------------------------------------------------------------------
// loadAvatar()
//-----------------------------------------------------------------------------
+static LLFastTimer::DeclareTimer FTM_LOAD_AVATAR("Load Avatar");
+
BOOL LLVOAvatar::loadAvatar()
{
-// LLFastTimer t(LLFastTimer::FTM_LOAD_AVATAR);
+// LLFastTimer t(FTM_LOAD_AVATAR);
// avatar_skeleton.xml
if( !buildSkeleton(sAvatarSkeletonInfo) )
@@ -5217,62 +4692,55 @@ BOOL LLVOAvatar::loadAvatar()
if (sAvatarXmlInfo->mLayerInfoList.empty())
{
llwarns << "avatar file: missing <layer_set> node" << llendl;
+ return FALSE;
}
- else
+
+ if (sAvatarXmlInfo->mMorphMaskInfoList.empty())
{
- LLVOAvatarXmlInfo::layer_info_list_t::iterator iter;
- for (iter = sAvatarXmlInfo->mLayerInfoList.begin();
- iter != sAvatarXmlInfo->mLayerInfoList.end(); iter++)
+ llwarns << "avatar file: missing <morph_masks> node" << llendl;
+ return FALSE;
+ }
+
+ // avatar_lad.xml : <morph_masks>
+ for (LLVOAvatarXmlInfo::morph_info_list_t::iterator iter = sAvatarXmlInfo->mMorphMaskInfoList.begin();
+ iter != sAvatarXmlInfo->mMorphMaskInfoList.end();
+ iter++)
+ {
+ LLVOAvatarXmlInfo::LLVOAvatarMorphInfo *info = *iter;
+
+ EBakedTextureIndex baked = LLVOAvatarDictionary::findBakedByRegionName(info->mRegion);
+ if (baked != BAKED_NUM_INDICES)
{
- LLTexLayerSetInfo *info = *iter;
- LLTexLayerSet* layer_set = new LLTexLayerSet( this );
- if (!layer_set->setInfo(info))
- {
- stop_glerror();
- delete layer_set;
- llwarns << "avatar file: layer_set->parseData() failed" << llendl;
- return FALSE;
- }
- bool found_baked_entry = false;
- for (LLVOAvatarDictionary::baked_map_t::const_iterator baked_iter = LLVOAvatarDictionary::getInstance()->getBakedTextures().begin();
- baked_iter != LLVOAvatarDictionary::getInstance()->getBakedTextures().end();
- baked_iter++)
- {
- const LLVOAvatarDictionary::BakedDictionaryEntry *baked_dict = baked_iter->second;
- if (layer_set->isBodyRegion(baked_dict->mName))
- {
- mBakedTextureData[baked_iter->first].mTexLayerSet = layer_set;
- found_baked_entry = true;
- break;
- }
- }
- if (!found_baked_entry)
+ LLPolyMorphTarget *morph_param;
+ const std::string *name = &info->mName;
+ morph_param = (LLPolyMorphTarget *)(getVisualParam(name->c_str()));
+ if (morph_param)
{
- llwarns << "<layer_set> has invalid body_region attribute" << llendl;
- delete layer_set;
- return FALSE;
+ BOOL invert = info->mInvert;
+ addMaskedMorph(baked, morph_param, invert, info->mLayer);
}
}
+
}
+
+ loadLayersets();
// avatar_lad.xml : <driver_parameters>
+ for (LLVOAvatarXmlInfo::driver_info_list_t::iterator iter = sAvatarXmlInfo->mDriverInfoList.begin();
+ iter != sAvatarXmlInfo->mDriverInfoList.end();
+ iter++)
{
- LLVOAvatarXmlInfo::driver_info_list_t::iterator iter;
- for (iter = sAvatarXmlInfo->mDriverInfoList.begin();
- iter != sAvatarXmlInfo->mDriverInfoList.end(); iter++)
+ LLDriverParamInfo *info = *iter;
+ LLDriverParam* driver_param = new LLDriverParam( this );
+ if (driver_param->setInfo(info))
{
- LLDriverParamInfo *info = *iter;
- LLDriverParam* driver_param = new LLDriverParam( this );
- if (driver_param->setInfo(info))
- {
- addVisualParam( driver_param );
- }
- else
- {
- delete driver_param;
- llwarns << "avatar file: driver_param->parseData() failed" << llendl;
- return FALSE;
- }
+ addVisualParam( driver_param );
+ }
+ else
+ {
+ delete driver_param;
+ llwarns << "avatar file: driver_param->parseData() failed" << llendl;
+ return FALSE;
}
}
@@ -5287,7 +4755,7 @@ BOOL LLVOAvatar::loadSkeletonNode ()
mRoot.addChild( &mSkeleton[0] );
for (std::vector<LLViewerJoint *>::iterator iter = mMeshLOD.begin();
- iter != mMeshLOD.end(); iter++)
+ iter != mMeshLOD.end(); iter++)
{
LLViewerJoint *joint = (LLViewerJoint *) *iter;
joint->mUpdateXform = FALSE;
@@ -5438,12 +4906,12 @@ BOOL LLVOAvatar::loadMeshNodes()
switch(lod)
case 0:
mesh = &mHairMesh0; */
- for (LLVOAvatarDictionary::mesh_map_t::const_iterator mesh_iter = LLVOAvatarDictionary::getInstance()->getMeshes().begin();
+ for (LLVOAvatarDictionary::Meshes::const_iterator mesh_iter = LLVOAvatarDictionary::getInstance()->getMeshes().begin();
mesh_iter != LLVOAvatarDictionary::getInstance()->getMeshes().end();
mesh_iter++)
{
const EMeshIndex mesh_index = mesh_iter->first;
- const LLVOAvatarDictionary::MeshDictionaryEntry *mesh_dict = mesh_iter->second;
+ const LLVOAvatarDictionary::MeshEntry *mesh_dict = mesh_iter->second;
if (type.compare(mesh_dict->mName) == 0)
{
mesh_id = mesh_index;
@@ -5539,6 +5007,23 @@ BOOL LLVOAvatar::loadMeshNodes()
}
//-----------------------------------------------------------------------------
+// loadLayerSets()
+//-----------------------------------------------------------------------------
+BOOL LLVOAvatar::loadLayersets()
+{
+ BOOL success = TRUE;
+ for (LLVOAvatarXmlInfo::layer_info_list_t::const_iterator layerset_iter = sAvatarXmlInfo->mLayerInfoList.begin();
+ layerset_iter != sAvatarXmlInfo->mLayerInfoList.end();
+ layerset_iter++)
+ {
+ // Construct a layerset for each one specified in avatar_lad.xml and initialize it as such.
+ LLTexLayerSetInfo *layerset_info = *layerset_iter;
+ layerset_info->createVisualParams(this);
+ }
+ return success;
+}
+
+//-----------------------------------------------------------------------------
// updateVisualParams()
//-----------------------------------------------------------------------------
void LLVOAvatar::updateVisualParams()
@@ -5602,9 +5087,9 @@ void LLVOAvatar::setPixelAreaAndAngle(LLAgent &agent)
}
// We always want to look good to ourselves
- if( mIsSelf )
+ if( isSelf() )
{
- mPixelArea = llmax( mPixelArea, F32(TEX_IMAGE_SIZE_SELF / 16) );
+ mPixelArea = llmax( mPixelArea, F32(getTexImageSize() / 16) );
}
}
@@ -5620,7 +5105,7 @@ BOOL LLVOAvatar::updateJointLODs()
F32 area_scale = 0.16f;
{
- if (mIsSelf)
+ if (isSelf())
{
if(gAgent.cameraCustomizeAvatar() || gAgent.cameraMouselook())
{
@@ -5689,9 +5174,10 @@ LLDrawable *LLVOAvatar::createDrawable(LLPipeline *pipeline)
//-----------------------------------------------------------------------------
// updateGeometry()
//-----------------------------------------------------------------------------
+static LLFastTimer::DeclareTimer FTM_UPDATE_AVATAR("Update Avatar");
BOOL LLVOAvatar::updateGeometry(LLDrawable *drawable)
{
- LLFastTimer ftm(LLFastTimer::FTM_UPDATE_AVATAR);
+ LLFastTimer ftm(FTM_UPDATE_AVATAR);
if (!(gPipeline.hasRenderType(LLPipeline::RENDER_TYPE_AVATAR)))
{
return TRUE;
@@ -5736,7 +5222,7 @@ void LLVOAvatar::updateShadowFaces()
sprite.setSize(0.4f + cos_elev * 0.8f, 0.3f);
LLVector3 sun_vec = gSky.mVOSkyp ? gSky.mVOSkyp->getToSun() : LLVector3(0.f, 0.f, 0.f);
- if (mShadowImagep->getHasGLTexture())
+ if (mShadowImagep->hasValidGLTexture())
{
LLVector3 normal;
LLVector3d shadow_pos;
@@ -5749,7 +5235,7 @@ void LLVOAvatar::updateShadowFaces()
// this only does a ray straight down from the foot, as our client-side ray-tracing is very limited now
// but we make an explicit ray trace call in expectation of future improvements
resolveRayCollisionAgent(gAgent.getPosGlobalFromAgent(joint_world_pos),
- gAgent.getPosGlobalFromAgent(gSky.getSunDirection() + joint_world_pos), shadow_pos, normal);
+ gAgent.getPosGlobalFromAgent(gSky.getSunDirection() + joint_world_pos), shadow_pos, normal);
shadow_pos_agent = gAgent.getPosAgentFromGlobal(shadow_pos);
foot_height = joint_world_pos.mV[VZ] - shadow_pos_agent.mV[VZ];
@@ -5758,7 +5244,7 @@ void LLVOAvatar::updateShadowFaces()
// Render sprite
sprite.setNormal(normal);
- if (mIsSelf && gAgent.getCameraMode() == CAMERA_MODE_MOUSELOOK)
+ if (isSelf() && gAgent.getCameraMode() == CAMERA_MODE_MOUSELOOK)
{
sprite.setColor(0.f, 0.f, 0.f, 0.f);
}
@@ -5782,7 +5268,7 @@ void LLVOAvatar::updateShadowFaces()
// this only does a ray straight down from the foot, as our client-side ray-tracing is very limited now
// but we make an explicit ray trace call in expectation of future improvements
resolveRayCollisionAgent(gAgent.getPosGlobalFromAgent(joint_world_pos),
- gAgent.getPosGlobalFromAgent(gSky.getSunDirection() + joint_world_pos), shadow_pos, normal);
+ gAgent.getPosGlobalFromAgent(gSky.getSunDirection() + joint_world_pos), shadow_pos, normal);
shadow_pos_agent = gAgent.getPosAgentFromGlobal(shadow_pos);
foot_height = joint_world_pos.mV[VZ] - shadow_pos_agent.mV[VZ];
@@ -5791,7 +5277,7 @@ void LLVOAvatar::updateShadowFaces()
// Render sprite
sprite.setNormal(normal);
- if (mIsSelf && gAgent.getCameraMode() == CAMERA_MODE_MOUSELOOK)
+ if (isSelf() && gAgent.getCameraMode() == CAMERA_MODE_MOUSELOOK)
{
sprite.setColor(0.f, 0.f, 0.f, 0.f);
}
@@ -5816,9 +5302,9 @@ void LLVOAvatar::updateShadowFaces()
//-----------------------------------------------------------------------------
void LLVOAvatar::updateSexDependentLayerSets( BOOL set_by_user )
{
- invalidateComposite( mBakedTextureData[BAKED_HEAD].mTexLayerSet, set_by_user );
- invalidateComposite( mBakedTextureData[BAKED_UPPER].mTexLayerSet, set_by_user );
- invalidateComposite( mBakedTextureData[BAKED_LOWER].mTexLayerSet, set_by_user );
+ invalidateComposite( mBakedTextureDatas[BAKED_HEAD].mTexLayerSet, set_by_user );
+ invalidateComposite( mBakedTextureDatas[BAKED_UPPER].mTexLayerSet, set_by_user );
+ invalidateComposite( mBakedTextureDatas[BAKED_LOWER].mTexLayerSet, set_by_user );
updateMeshTextures();
}
@@ -5838,33 +5324,13 @@ void LLVOAvatar::hideSkirt()
mMeshLOD[MESH_ID_SKIRT]->setVisible(FALSE, TRUE);
}
-
-//-----------------------------------------------------------------------------
-// requestLayerSetUpdate()
-//-----------------------------------------------------------------------------
-void LLVOAvatar::requestLayerSetUpdate(ETextureIndex index )
-{
- /* switch(index)
- case LOCTEX_UPPER_BODYPAINT:
- case LOCTEX_UPPER_SHIRT:
- if( mUpperBodyLayerSet )
- mUpperBodyLayerSet->requestUpdate(); */
- const LLVOAvatarDictionary::TextureDictionaryEntry *texture_dict = LLVOAvatarDictionary::getInstance()->getTexture(index);
- if (!texture_dict->mIsLocalTexture || !texture_dict->mIsUsedByBakedTexture)
- return;
- const EBakedTextureIndex baked_index = texture_dict->mBakedTextureIndex;
- if (mBakedTextureData[baked_index].mTexLayerSet)
- {
- mBakedTextureData[baked_index].mTexLayerSet->requestUpdate();
- }
-}
-
-void LLVOAvatar::setParent(LLViewerObject* parent)
+BOOL LLVOAvatar::setParent(LLViewerObject* parent)
{
+ BOOL ret ;
if (parent == NULL)
{
getOffObject();
- LLViewerObject::setParent(parent);
+ ret = LLViewerObject::setParent(parent);
if (isSelf())
{
gAgent.resetCamera();
@@ -5872,9 +5338,13 @@ void LLVOAvatar::setParent(LLViewerObject* parent)
}
else
{
- LLViewerObject::setParent(parent);
- sitOnObject(parent);
+ ret = LLViewerObject::setParent(parent);
+ if(ret)
+ {
+ sitOnObject(parent);
+ }
}
+ return ret ;
}
void LLVOAvatar::addChild(LLViewerObject *childp)
@@ -5913,13 +5383,13 @@ LLViewerJointAttachment* LLVOAvatar::getTargetAttachmentPoint(LLViewerObject* vi
//-----------------------------------------------------------------------------
// attachObject()
//-----------------------------------------------------------------------------
-BOOL LLVOAvatar::attachObject(LLViewerObject *viewer_object)
+LLViewerJointAttachment *LLVOAvatar::attachObject(LLViewerObject *viewer_object)
{
LLViewerJointAttachment* attachment = getTargetAttachmentPoint(viewer_object);
if (!attachment || !attachment->addObject(viewer_object))
{
- return FALSE;
+ return 0;
}
if (viewer_object->isSelected())
@@ -5928,16 +5398,7 @@ BOOL LLVOAvatar::attachObject(LLViewerObject *viewer_object)
LLSelectMgr::getInstance()->updatePointAt();
}
- if (mIsSelf)
- {
- updateAttachmentVisibility(gAgent.getCameraMode());
-
- // Then make sure the inventory is in sync with the avatar.
- gInventory.addChangedMask( LLInventoryObserver::LABEL, attachment->getItemID() );
- gInventory.notifyObservers();
- }
-
- return TRUE;
+ return attachment;
}
//-----------------------------------------------------------------------------
@@ -5995,7 +5456,7 @@ BOOL LLVOAvatar::detachObject(LLViewerObject *viewer_object)
{
LLUUID item_id = attachment->getItemID();
attachment->removeObject(viewer_object);
- if (mIsSelf)
+ if (isSelf())
{
// the simulator should automatically handle
// permission revocation
@@ -6017,7 +5478,7 @@ BOOL LLVOAvatar::detachObject(LLViewerObject *viewer_object)
}
lldebugs << "Detaching object " << viewer_object->mID << " from " << attachment->getName() << llendl;
- if (mIsSelf)
+ if (isSelf())
{
// Then make sure the inventory is in sync with the avatar.
gInventory.addChangedMask(LLInventoryObserver::LABEL, item_id);
@@ -6027,15 +5488,45 @@ BOOL LLVOAvatar::detachObject(LLViewerObject *viewer_object)
}
}
-
return FALSE;
}
//-----------------------------------------------------------------------------
+// sitDown()
+//-----------------------------------------------------------------------------
+void LLVOAvatar::sitDown(BOOL bSitting)
+{
+ mIsSitting = bSitting;
+ if (isSelf())
+ {
+ // Update Movement Controls according to own Sitting mode
+ LLFloaterMove::setSittingMode(bSitting);
+ }
+}
+
+//-----------------------------------------------------------------------------
// sitOnObject()
//-----------------------------------------------------------------------------
void LLVOAvatar::sitOnObject(LLViewerObject *sit_object)
{
+ if (isSelf())
+ {
+ // Might be first sit
+ LLFirstUse::useSit();
+
+ gAgent.setFlying(FALSE);
+ gAgent.setThirdPersonHeadOffset(LLVector3::zero);
+ //interpolate to new camera position
+ gAgent.startCameraAnimation();
+ // make sure we are not trying to autopilot
+ gAgent.stopAutoPilot();
+ gAgent.setupSitCamera();
+ if (gAgent.getForceMouselook())
+ {
+ gAgent.changeCameraToMouselook();
+ }
+ }
+
if (mDrawable.isNull())
{
return;
@@ -6050,27 +5541,13 @@ void LLVOAvatar::sitOnObject(LLViewerObject *sit_object)
mDrawable->mXform.setRotation(mDrawable->getWorldRotation() * inv_obj_rot);
gPipeline.markMoved(mDrawable, TRUE);
- mIsSitting = TRUE;
+ sitDown(TRUE);
mRoot.getXform()->setParent(&sit_object->mDrawable->mXform); // LLVOAvatar::sitOnObject
mRoot.setPosition(getPosition());
mRoot.updateWorldMatrixChildren();
stopMotion(ANIM_AGENT_BODY_NOISE);
- if (mIsSelf)
- {
- // Might be first sit
- LLFirstUse::useSit();
-
- gAgent.setFlying(FALSE);
- gAgent.setThirdPersonHeadOffset(LLVector3::zero);
- //interpolate to new camera position
- gAgent.startCameraAnimation();
- // make sure we are not trying to autopilot
- gAgent.stopAutoPilot();
- gAgent.setupSitCamera();
- if (gAgent.mForceMouselook) gAgent.changeCameraToMouselook();
- }
}
//-----------------------------------------------------------------------------
@@ -6111,7 +5588,8 @@ void LLVOAvatar::getOffObject()
gPipeline.markMoved(mDrawable, TRUE);
- mIsSitting = FALSE;
+ sitDown(FALSE);
+
mRoot.getXform()->setParent(NULL); // LLVOAvatar::getOffObject
mRoot.setPosition(cur_position_world);
mRoot.setRotation(cur_rotation_world);
@@ -6119,7 +5597,7 @@ void LLVOAvatar::getOffObject()
startMotion(ANIM_AGENT_BODY_NOISE);
- if (mIsSelf)
+ if (isSelf())
{
LLQuaternion av_rot = gAgent.getFrameAgent().getQuaternion();
LLQuaternion obj_rot = sit_object ? sit_object->getRenderRotation() : LLQuaternion::DEFAULT;
@@ -6160,146 +5638,24 @@ LLVOAvatar* LLVOAvatar::findAvatarFromAttachment( LLViewerObject* obj )
return NULL;
}
-//-----------------------------------------------------------------------------
-// isWearingAttachment()
-//-----------------------------------------------------------------------------
-BOOL LLVOAvatar::isWearingAttachment( const LLUUID& inv_item_id )
-{
- for (attachment_map_t::iterator iter = mAttachmentPoints.begin();
- iter != mAttachmentPoints.end(); )
- {
- attachment_map_t::iterator curiter = iter++;
- LLViewerJointAttachment* attachment = curiter->second;
- if( attachment->getItemID() == inv_item_id )
- {
- return TRUE;
- }
- }
- return FALSE;
-}
-
-//-----------------------------------------------------------------------------
-// getWornAttachment()
-//-----------------------------------------------------------------------------
-LLViewerObject* LLVOAvatar::getWornAttachment( const LLUUID& inv_item_id )
-{
- for (attachment_map_t::iterator iter = mAttachmentPoints.begin();
- iter != mAttachmentPoints.end(); )
- {
- attachment_map_t::iterator curiter = iter++;
- LLViewerJointAttachment* attachment = curiter->second;
- if( attachment->getItemID() == inv_item_id )
- {
- return attachment->getObject();
- }
- }
- return NULL;
-}
-
-const std::string LLVOAvatar::getAttachedPointName(const LLUUID& inv_item_id)
-{
- for (attachment_map_t::iterator iter = mAttachmentPoints.begin();
- iter != mAttachmentPoints.end(); )
- {
- attachment_map_t::iterator curiter = iter++;
- LLViewerJointAttachment* attachment = curiter->second;
- if( attachment->getItemID() == inv_item_id )
- {
- return attachment->getName();
- }
- }
-
- return LLStringUtil::null;
-}
-
-
-//-----------------------------------------------------------------------------
-// static
-// onLocalTextureLoaded()
-//-----------------------------------------------------------------------------
-
-void LLVOAvatar::onLocalTextureLoaded( BOOL success, LLViewerImage *src_vi, LLImageRaw* src_raw, LLImageRaw* aux_src, S32 discard_level, BOOL final, void* userdata )
-{
- //llinfos << "onLocalTextureLoaded: " << src_vi->getID() << llendl;
-
- const LLUUID& src_id = src_vi->getID();
- LLAvatarTexData *data = (LLAvatarTexData *)userdata;
- if (success)
- {
- LLVOAvatar *self = (LLVOAvatar *)gObjectList.findObject(data->mAvatarID);
- if (self)
- {
- ETextureIndex index = data->mIndex;
- if (!self->isIndexLocalTexture(index)) return;
- LocalTextureData &local_tex_data = self->mLocalTextureData[index];
- if(!local_tex_data.mIsBakedReady &&
- local_tex_data.mImage.notNull() &&
- (local_tex_data.mImage->getID() == src_id) &&
- discard_level < local_tex_data.mDiscard)
- {
- local_tex_data.mDiscard = discard_level;
- if ( self->isSelf() && !gAgent.cameraCustomizeAvatar() )
- {
- self->requestLayerSetUpdate( index );
- }
- else if( self->isSelf() && gAgent.cameraCustomizeAvatar() )
- {
- LLVisualParamHint::requestHintUpdates();
- }
- self->updateMeshTextures();
- }
- }
- }
- else if (final)
- {
- LLVOAvatar *self = (LLVOAvatar *)gObjectList.findObject(data->mAvatarID);
- if (self)
- {
- ETextureIndex index = data->mIndex;
- if (!self->isIndexLocalTexture(index)) return;
- LocalTextureData &local_tex_data = self->mLocalTextureData[index];
- // Failed: asset is missing
- if(!local_tex_data.mIsBakedReady &&
- local_tex_data.mImage.notNull() &&
- local_tex_data.mImage->getID() == src_id)
- {
- local_tex_data.mDiscard = 0;
- self->requestLayerSetUpdate( index );
- self->updateMeshTextures();
- }
- }
- }
-
- if( final || !success )
- {
- delete data;
- }
-}
-
-void LLVOAvatar::updateComposites()
+// warning: order(N) not order(1)
+S32 LLVOAvatar::getAttachmentCount()
{
- for (U32 i = 0; i < mBakedTextureData.size(); i++)
- {
- if ( mBakedTextureData[i].mTexLayerSet
- && ((i != BAKED_SKIRT) || isWearingWearableType( WT_SKIRT )) )
- {
- mBakedTextureData[i].mTexLayerSet->updateComposite();
- }
- }
+ S32 count = mAttachmentPoints.size();
+ return count;
}
-LLColor4 LLVOAvatar::getGlobalColor( const std::string& color_name )
+LLColor4 LLVOAvatar::getGlobalColor( const std::string& color_name ) const
{
- if( color_name=="skin_color" && mTexSkinColor )
+ if (color_name=="skin_color" && mTexSkinColor)
{
return mTexSkinColor->getColor();
}
- else
- if( color_name=="hair_color" && mTexHairColor )
+ else if(color_name=="hair_color" && mTexHairColor)
{
return mTexHairColor->getColor();
}
- if( color_name=="eye_color" && mTexEyeColor )
+ if(color_name=="eye_color" && mTexEyeColor)
{
return mTexEyeColor->getColor();
}
@@ -6310,282 +5666,64 @@ LLColor4 LLVOAvatar::getGlobalColor( const std::string& color_name )
}
}
-
+// virtual
void LLVOAvatar::invalidateComposite( LLTexLayerSet* layerset, BOOL set_by_user )
{
- if( !layerset || !layerset->getUpdatesEnabled() )
- {
- return;
- }
-
- /* Debug spam. JC
- const char* layer_name = "";
- if (layerset == mHeadLayerSet)
- {
- layer_name = "head";
- }
- else if (layerset == mUpperBodyLayerSet)
- {
- layer_name = "upperbody";
- }
- else if (layerset == mLowerBodyLayerSet)
- {
- layer_name = "lowerbody";
- }
- else if (layerset == mEyesLayerSet)
- {
- layer_name = "eyes";
- }
- else if (layerset == mHairLayerSet)
- {
- layer_name = "hair";
- }
- else if (layerset == mSkirtLayerSet)
- {
- layer_name = "skirt";
- }
- else
- {
- layer_name = "unknown";
- }
- llinfos << "LLVOAvatar::invalidComposite() " << layer_name << llendl;
- */
-
- layerset->requestUpdate();
-
- if( set_by_user )
- {
- llassert( mIsSelf );
-
- ETextureIndex baked_te = getBakedTE( layerset );
- setTEImage( baked_te, gImageList.getImage(IMG_DEFAULT_AVATAR) );
- layerset->requestUpload();
- }
}
void LLVOAvatar::invalidateAll()
{
- for (U32 i = 0; i < mBakedTextureData.size(); i++)
- {
- invalidateComposite(mBakedTextureData[i].mTexLayerSet, TRUE);
- }
- updateMeshTextures();
}
-void LLVOAvatar::onGlobalColorChanged( LLTexGlobalColor* global_color, BOOL set_by_user )
+// virtual
+void LLVOAvatar::setCompositeUpdatesEnabled( BOOL b )
{
- if( global_color == mTexSkinColor )
+}
+
+void LLVOAvatar::onGlobalColorChanged(const LLTexGlobalColor* global_color, BOOL set_by_user )
+{
+ if (global_color == mTexSkinColor)
{
-// llinfos << "invalidateComposite cause: onGlobalColorChanged( skin color )" << llendl;
- invalidateComposite( mBakedTextureData[BAKED_HEAD].mTexLayerSet, set_by_user );
- invalidateComposite( mBakedTextureData[BAKED_UPPER].mTexLayerSet, set_by_user );
- invalidateComposite( mBakedTextureData[BAKED_LOWER].mTexLayerSet, set_by_user );
+ invalidateComposite( mBakedTextureDatas[BAKED_HEAD].mTexLayerSet, set_by_user );
+ invalidateComposite( mBakedTextureDatas[BAKED_UPPER].mTexLayerSet, set_by_user );
+ invalidateComposite( mBakedTextureDatas[BAKED_LOWER].mTexLayerSet, set_by_user );
}
- else
- if( global_color == mTexHairColor )
+ else if (global_color == mTexHairColor)
{
-// llinfos << "invalidateComposite cause: onGlobalColorChanged( hair color )" << llendl;
- invalidateComposite( mBakedTextureData[BAKED_HEAD].mTexLayerSet, set_by_user );
- invalidateComposite( mBakedTextureData[BAKED_HAIR].mTexLayerSet, set_by_user );
+ invalidateComposite( mBakedTextureDatas[BAKED_HEAD].mTexLayerSet, set_by_user );
+ invalidateComposite( mBakedTextureDatas[BAKED_HAIR].mTexLayerSet, set_by_user );
// ! BACKWARDS COMPATIBILITY !
// Fix for dealing with avatars from viewers that don't bake hair.
- if (!isTextureDefined(mBakedTextureData[BAKED_HAIR].mTextureIndex))
+ if (!isTextureDefined(mBakedTextureDatas[BAKED_HAIR].mTextureIndex))
{
LLColor4 color = mTexHairColor->getColor();
- for (U32 i = 0; i < mBakedTextureData[BAKED_HAIR].mMeshes.size(); i++)
+ for (U32 i = 0; i < mBakedTextureDatas[BAKED_HAIR].mMeshes.size(); i++)
{
- mBakedTextureData[BAKED_HAIR].mMeshes[i]->setColor( color.mV[VX], color.mV[VY], color.mV[VZ], color.mV[VW] );
+ mBakedTextureDatas[BAKED_HAIR].mMeshes[i]->setColor( color.mV[VX], color.mV[VY], color.mV[VZ], color.mV[VW] );
}
}
- }
- else
- if( global_color == mTexEyeColor )
+ }
+ else if (global_color == mTexEyeColor)
{
// llinfos << "invalidateComposite cause: onGlobalColorChanged( eyecolor )" << llendl;
- invalidateComposite( mBakedTextureData[BAKED_EYES].mTexLayerSet, set_by_user );
+ invalidateComposite( mBakedTextureDatas[BAKED_EYES].mTexLayerSet, set_by_user );
}
updateMeshTextures();
}
-void LLVOAvatar::forceBakeAllTextures(bool slam_for_debug)
-{
- llinfos << "TAT: forced full rebake. " << llendl;
-
- for (U32 i = 0; i < mBakedTextureData.size(); i++)
- {
- ETextureIndex baked_index = mBakedTextureData[i].mTextureIndex;
- LLTexLayerSet* layer_set = getLayerSet(baked_index);
- if (layer_set)
- {
- if (slam_for_debug)
- {
- layer_set->setUpdatesEnabled(TRUE);
- layer_set->cancelUpload();
- }
-
- BOOL set_by_user = TRUE;
- invalidateComposite(layer_set, set_by_user);
- LLViewerStats::getInstance()->incStat(LLViewerStats::ST_TEX_REBAKES);
- }
- else
- {
- llwarns << "TAT: NO LAYER SET FOR " << (S32)baked_index << llendl;
- }
- }
-
- // Don't know if this is needed
- updateMeshTextures();
-}
-
-
-// static
-void LLVOAvatar::processRebakeAvatarTextures(LLMessageSystem* msg, void**)
-{
- LLUUID texture_id;
- msg->getUUID("TextureData", "TextureID", texture_id);
-
- LLVOAvatar* self = gAgent.getAvatarObject();
- if (!self) return;
-
- // If this is a texture corresponding to one of our baked entries,
- // just rebake that layer set.
- BOOL found = FALSE;
-
- /* ETextureIndex baked_texture_indices[BAKED_NUM_INDICES] =
- TEX_HEAD_BAKED,
- TEX_UPPER_BAKED, */
- for (LLVOAvatarDictionary::texture_map_t::const_iterator iter = LLVOAvatarDictionary::getInstance()->getTextures().begin();
- iter != LLVOAvatarDictionary::getInstance()->getTextures().end();
- iter++)
- {
- const ETextureIndex index = iter->first;
- const LLVOAvatarDictionary::TextureDictionaryEntry *text_dict = iter->second;
- if (text_dict->mIsBakedTexture)
- {
- if (texture_id == self->getTEImage(index)->getID())
- {
- LLTexLayerSet* layer_set = self->getLayerSet(index);
- if (layer_set)
- {
- llinfos << "TAT: rebake - matched entry " << (S32)index << llendl;
- // Apparently set_by_user == force upload
- BOOL set_by_user = TRUE;
- self->invalidateComposite(layer_set, set_by_user);
- found = TRUE;
- LLViewerStats::getInstance()->incStat(LLViewerStats::ST_TEX_REBAKES);
- }
- }
- }
- }
-
- // If texture not found, rebake all entries.
- if (!found)
- {
- self->forceBakeAllTextures();
- }
- else
- {
- // Not sure if this is necessary, but forceBakeAllTextures() does it.
- self->updateMeshTextures();
- }
-}
-
-
-BOOL LLVOAvatar::getLocalTextureRaw(ETextureIndex index, LLImageRaw* image_raw)
-{
- if (!isIndexLocalTexture(index)) return FALSE;
-
- BOOL success = FALSE;
-
- if (getLocalTextureID(index) == IMG_DEFAULT_AVATAR)
- {
- success = TRUE;
- }
- else
- {
- LocalTextureData &local_tex_data = mLocalTextureData[index];
- if(local_tex_data.mImage->readBackRaw(-1, image_raw, false))
- {
- success = TRUE;
- }
- else
- {
- // No data loaded yet
- setLocalTexture( (ETextureIndex)index, getTEImage( index ), FALSE );
- }
- }
- return success;
-}
-
-BOOL LLVOAvatar::getLocalTextureGL(ETextureIndex index, LLImageGL** image_gl_pp)
-{
- if (!isIndexLocalTexture(index)) return FALSE;
-
- BOOL success = FALSE;
- *image_gl_pp = NULL;
-
- if (getLocalTextureID(index) == IMG_DEFAULT_AVATAR)
- {
- success = TRUE;
- }
- else
- {
- LocalTextureData &local_tex_data = mLocalTextureData[index];
- *image_gl_pp = local_tex_data.mImage;
- success = TRUE;
- }
-
- if( !success )
- {
-// llinfos << "getLocalTextureGL(" << index << ") had no data" << llendl;
- }
- return success;
-}
-
-const LLUUID& LLVOAvatar::getLocalTextureID(ETextureIndex index)
-{
- if (!isIndexLocalTexture(index)) return IMG_DEFAULT_AVATAR;
-
- if (mLocalTextureData[index].mImage.notNull())
- {
- return mLocalTextureData[index].mImage->getID();
- }
- else
- {
- return IMG_DEFAULT_AVATAR;
- }
-}
-
-// static
-void LLVOAvatar::dumpTotalLocalTextureByteCount()
-{
- S32 total_gl_bytes = 0;
- for (std::vector<LLCharacter*>::iterator iter = LLCharacter::sInstances.begin();
- iter != LLCharacter::sInstances.end(); ++iter)
- {
- LLVOAvatar* cur = (LLVOAvatar*) *iter;
- S32 gl_bytes = 0;
- cur->getLocalTextureByteCount(&gl_bytes );
- total_gl_bytes += gl_bytes;
- }
- llinfos << "Total Avatar LocTex GL:" << (total_gl_bytes/1024) << "KB" << llendl;
-}
-
-BOOL LLVOAvatar::isVisible()
+BOOL LLVOAvatar::isVisible() const
{
return mDrawable.notNull()
&& (mDrawable->isVisible() || mIsDummy);
}
-
// call periodically to keep isFullyLoaded up to date.
// returns true if the value has changed.
BOOL LLVOAvatar::updateIsFullyLoaded()
{
// a "heuristic" to determine if we have enough avatar data to render
// (to avoid rendering a "Ruth" - DEV-3168)
-
BOOL loading = FALSE;
// do we have a shape?
@@ -6594,48 +5732,18 @@ BOOL LLVOAvatar::updateIsFullyLoaded()
loading = TRUE;
}
- //
- if (mIsSelf)
- {
- if (!isTextureDefined(TEX_HAIR))
- {
- loading = TRUE;
- }
- }
- else if (!isTextureDefined(TEX_LOWER_BAKED) || !isTextureDefined(TEX_UPPER_BAKED) || !isTextureDefined(TEX_HEAD_BAKED))
+ if (!isTextureDefined(TEX_LOWER_BAKED) ||
+ !isTextureDefined(TEX_UPPER_BAKED) ||
+ !isTextureDefined(TEX_HEAD_BAKED))
{
loading = TRUE;
}
- // special case to keep nudity off orientation island -
- // this is fragilely dependent on the compositing system,
- // which gets available textures in the following order:
- //
- // 1) use the baked texture
- // 2) use the layerset
- // 3) use the previously baked texture
- //
- // on orientation island case (3) can show naked skin.
- // so we test for that here:
- //
- // if we were previously unloaded, and we don't have enough
- // texture info for our shirt/pants, stay unloaded:
- if (!mPreviousFullyLoaded)
- {
- if ((!isLocalTextureDataAvailable(mBakedTextureData[BAKED_LOWER].mTexLayerSet)) &&
- (!isTextureDefined(TEX_LOWER_BAKED)))
- {
- loading = TRUE;
- }
-
- if ((!isLocalTextureDataAvailable(mBakedTextureData[BAKED_UPPER].mTexLayerSet)) &&
- (!isTextureDefined(TEX_UPPER_BAKED)))
- {
- loading = TRUE;
- }
- }
+ return processFullyLoadedChange(loading);
+}
-
+BOOL LLVOAvatar::processFullyLoadedChange(bool loading)
+{
// we wait a little bit before giving the all clear,
// to let textures settle down
const F32 PAUSE = 1.f;
@@ -6659,8 +5767,7 @@ BOOL LLVOAvatar::updateIsFullyLoaded()
return changed;
}
-
-BOOL LLVOAvatar::isFullyLoaded()
+BOOL LLVOAvatar::isFullyLoaded() const
{
if (gSavedSettings.getBOOL("RenderUnloadedAvatar"))
return TRUE;
@@ -6672,177 +5779,11 @@ BOOL LLVOAvatar::isFullyLoaded()
//-----------------------------------------------------------------------------
// findMotion()
//-----------------------------------------------------------------------------
-LLMotion* LLVOAvatar::findMotion(const LLUUID& id)
+LLMotion* LLVOAvatar::findMotion(const LLUUID& id) const
{
return mMotionController.findMotion(id);
}
-// Counts the memory footprint of local textures.
-void LLVOAvatar::getLocalTextureByteCount( S32* gl_bytes )
-{
- *gl_bytes = 0;
- for( S32 i = 0; i < TEX_NUM_INDICES; i++ )
- {
- if (!isIndexLocalTexture((ETextureIndex)i)) continue;
- LLViewerImage* image_gl = mLocalTextureData[(ETextureIndex)i].mImage;
- if( image_gl )
- {
- S32 bytes = (S32)image_gl->getWidth() * image_gl->getHeight() * image_gl->getComponents();
-
- if( image_gl->getHasGLTexture() )
- {
- *gl_bytes += bytes;
- }
- }
- }
-}
-
-
-BOOL LLVOAvatar::bindScratchTexture( LLGLenum format )
-{
- U32 texture_bytes = 0;
- GLuint gl_name = getScratchTexName( format, &texture_bytes );
- if( gl_name )
- {
- gGL.getTexUnit(0)->bindManual(LLTexUnit::TT_TEXTURE, gl_name);
- stop_glerror();
-
- F32* last_bind_time = LLVOAvatar::sScratchTexLastBindTime.getIfThere( format );
- if( last_bind_time )
- {
- if( *last_bind_time != LLImageGL::sLastFrameTime )
- {
- *last_bind_time = LLImageGL::sLastFrameTime;
- LLImageGL::updateBoundTexMem(texture_bytes);
- }
- }
- else
- {
- LLImageGL::updateBoundTexMem(texture_bytes);
- LLVOAvatar::sScratchTexLastBindTime.addData( format, new F32(LLImageGL::sLastFrameTime) );
- }
-
-
- return TRUE;
- }
- else
- {
- return FALSE;
- }
-}
-
-
-LLGLuint LLVOAvatar::getScratchTexName( LLGLenum format, U32* texture_bytes )
-{
- S32 components;
- GLenum internal_format;
- switch( format )
- {
- case GL_LUMINANCE: components = 1; internal_format = GL_LUMINANCE8; break;
- case GL_ALPHA: components = 1; internal_format = GL_ALPHA8; break;
- case GL_COLOR_INDEX: components = 1; internal_format = GL_COLOR_INDEX8_EXT; break;
- case GL_LUMINANCE_ALPHA: components = 2; internal_format = GL_LUMINANCE8_ALPHA8; break;
- case GL_RGB: components = 3; internal_format = GL_RGB8; break;
- case GL_RGBA: components = 4; internal_format = GL_RGBA8; break;
- default: llassert(0); components = 4; internal_format = GL_RGBA8; break;
- }
-
- *texture_bytes = components * SCRATCH_TEX_WIDTH * SCRATCH_TEX_HEIGHT;
-
- if( LLVOAvatar::sScratchTexNames.checkData( format ) )
- {
- return *( LLVOAvatar::sScratchTexNames.getData( format ) );
- }
- else
- {
-
- LLGLSUIDefault gls_ui;
-
- U32 name = 0;
- LLImageGL::generateTextures(1, &name );
- stop_glerror();
-
- gGL.getTexUnit(0)->bindManual(LLTexUnit::TT_TEXTURE, name);
- stop_glerror();
-
- LLImageGL::setManualImage(
- GL_TEXTURE_2D, 0, internal_format,
- SCRATCH_TEX_WIDTH, SCRATCH_TEX_HEIGHT,
- format, GL_UNSIGNED_BYTE, NULL );
- stop_glerror();
-
- gGL.getTexUnit(0)->setTextureFilteringOption(LLTexUnit::TFO_BILINEAR);
- gGL.getTexUnit(0)->setTextureAddressMode(LLTexUnit::TAM_CLAMP);
- stop_glerror();
-
- gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
- stop_glerror();
-
- LLVOAvatar::sScratchTexNames.addData( format, new LLGLuint( name ) );
-
- LLVOAvatar::sScratchTexBytes += *texture_bytes;
- LLImageGL::sGlobalTextureMemoryInBytes += *texture_bytes;
- return name;
- }
-}
-
-
-
-//-----------------------------------------------------------------------------
-// setLocalTextureTE()
-//-----------------------------------------------------------------------------
-void LLVOAvatar::setLocTexTE( U8 te, LLViewerImage* image, BOOL set_by_user )
-{
- if( !mIsSelf )
- {
- llassert( 0 );
- return;
- }
-
- if( te >= TEX_NUM_INDICES )
- {
- llassert(0);
- return;
- }
-
- if( getTEImage( te )->getID() == image->getID() )
- {
- return;
- }
-
- if (isIndexBakedTexture((ETextureIndex)te))
- {
- llassert(0);
- return;
- }
-
- LLTexLayerSet* layer_set = getLayerSet((ETextureIndex)te);
- if (layer_set)
- {
- invalidateComposite(layer_set, set_by_user);
- }
-
- setTEImage( te, image );
- updateMeshTextures();
-
- if( gAgent.cameraCustomizeAvatar() )
- {
- LLVisualParamHint::requestHintUpdates();
- }
-}
-
-void LLVOAvatar::setupComposites()
-{
- for (U32 i = 0; i < mBakedTextureData.size(); i++)
- {
- bool layer_baked = isTextureDefined(mBakedTextureData[i].mTextureIndex);
- if (mBakedTextureData[i].mTexLayerSet)
- {
- mBakedTextureData[i].mTexLayerSet->setUpdatesEnabled( !layer_baked );
- }
- }
-}
-
//-----------------------------------------------------------------------------
// updateMeshTextures()
// Uses the current TE values to set the meshes' and layersets' textures.
@@ -6855,25 +5796,25 @@ void LLVOAvatar::updateMeshTextures()
// if user has never specified a texture, assign the default
for (U32 i=0; i < getNumTEs(); i++)
{
- const LLViewerImage* te_image = getTEImage(i);
+ const LLViewerTexture* te_image = getImage(i);
if(!te_image || te_image->getID().isNull() || (te_image->getID() == IMG_DEFAULT))
{
- setTEImage(i, gImageList.getImage(i == TEX_HAIR ? IMG_DEFAULT : IMG_DEFAULT_AVATAR)); // IMG_DEFAULT_AVATAR = a special texture that's never rendered.
+ setImage(i, LLViewerTextureManager::getFetchedTexture(i == TEX_HAIR ? IMG_DEFAULT : IMG_DEFAULT_AVATAR)); // IMG_DEFAULT_AVATAR = a special texture that's never rendered.
}
}
- const BOOL self_customizing = mIsSelf && gAgent.cameraCustomizeAvatar(); // During face edit mode, we don't use baked textures
- const BOOL other_culled = !mIsSelf && mCulled;
+ const BOOL self_customizing = isSelf() && gAgent.cameraCustomizeAvatar(); // During face edit mode, we don't use baked textures
+ const BOOL other_culled = !isSelf() && mCulled;
- std::vector<bool> is_layer_baked;
- is_layer_baked.resize(mBakedTextureData.size(), false);
+ std::vector<BOOL> is_layer_baked;
+ is_layer_baked.resize(mBakedTextureDatas.size(), false);
- std::vector<bool> use_lkg_baked_layer; // lkg = "last known good"
- use_lkg_baked_layer.resize(mBakedTextureData.size(), false);
+ std::vector<BOOL> use_lkg_baked_layer; // lkg = "last known good"
+ use_lkg_baked_layer.resize(mBakedTextureDatas.size(), false);
- for (U32 i=0; i < mBakedTextureData.size(); i++)
+ for (U32 i=0; i < mBakedTextureDatas.size(); i++)
{
- is_layer_baked[i] = isTextureDefined(mBakedTextureData[i].mTextureIndex);
+ is_layer_baked[i] = isTextureDefined(mBakedTextureDatas[i].mTextureIndex);
if (!other_culled)
{
@@ -6881,21 +5822,21 @@ void LLVOAvatar::updateMeshTextures()
// use the last-known good baked texture until it finish the first
// render of the new layerset.
use_lkg_baked_layer[i] = (!is_layer_baked[i]
- && (mBakedTextureData[i].mLastTextureIndex != IMG_DEFAULT_AVATAR)
- && mBakedTextureData[i].mTexLayerSet
- && !mBakedTextureData[i].mTexLayerSet->getComposite()->isInitialized());
+ && (mBakedTextureDatas[i].mLastTextureIndex != IMG_DEFAULT_AVATAR)
+ && mBakedTextureDatas[i].mTexLayerSet
+ && !mBakedTextureDatas[i].mTexLayerSet->getComposite()->isInitialized());
if (use_lkg_baked_layer[i])
{
- mBakedTextureData[i].mTexLayerSet->setUpdatesEnabled(TRUE);
+ mBakedTextureDatas[i].mTexLayerSet->setUpdatesEnabled(TRUE);
}
}
else
{
use_lkg_baked_layer[i] = (!is_layer_baked[i]
- && mBakedTextureData[i].mLastTextureIndex != IMG_DEFAULT_AVATAR);
- if (mBakedTextureData[i].mTexLayerSet)
+ && mBakedTextureDatas[i].mLastTextureIndex != IMG_DEFAULT_AVATAR);
+ if (mBakedTextureDatas[i].mTexLayerSet)
{
- mBakedTextureData[i].mTexLayerSet->destroyComposite();
+ mBakedTextureDatas[i].mTexLayerSet->destroyComposite();
}
}
@@ -6908,28 +5849,28 @@ void LLVOAvatar::updateMeshTextures()
llwarns << "updateMeshTextures: invalid host for object: " << getID() << llendl;
}
- for (U32 i=0; i < mBakedTextureData.size(); i++)
+ for (U32 i=0; i < mBakedTextureDatas.size(); i++)
{
if (use_lkg_baked_layer[i] && !self_customizing )
{
- LLViewerImage* baked_img = gImageList.getImageFromHost( mBakedTextureData[i].mLastTextureIndex, target_host );
- mBakedTextureData[i].mIsUsed = TRUE;
- for (U32 k=0; k < mBakedTextureData[i].mMeshes.size(); k++)
+ LLViewerFetchedTexture* baked_img = LLViewerTextureManager::getFetchedTextureFromHost( mBakedTextureDatas[i].mLastTextureIndex, target_host );
+ mBakedTextureDatas[i].mIsUsed = TRUE;
+ for (U32 k=0; k < mBakedTextureDatas[i].mMeshes.size(); k++)
{
- mBakedTextureData[i].mMeshes[k]->setTexture( baked_img );
+ mBakedTextureDatas[i].mMeshes[k]->setTexture( baked_img );
}
}
else if (!self_customizing && is_layer_baked[i])
{
- LLViewerImage* baked_img = getTEImage( mBakedTextureData[i].mTextureIndex );
- if( baked_img->getID() == mBakedTextureData[i].mLastTextureIndex )
+ LLViewerFetchedTexture* baked_img = LLViewerTextureManager::staticCastToFetchedTexture(getImage( mBakedTextureDatas[i].mTextureIndex ), TRUE) ;
+ if( baked_img->getID() == mBakedTextureDatas[i].mLastTextureIndex )
{
// Even though the file may not be finished loading, we'll consider it loaded and use it (rather than doing compositing).
useBakedTexture( baked_img->getID() );
}
else
{
- mBakedTextureData[i].mIsLoaded = FALSE;
+ mBakedTextureDatas[i].mIsLoaded = FALSE;
if ( (i == BAKED_HEAD) || (i == BAKED_UPPER) || (i == BAKED_LOWER) )
{
baked_img->setLoadedCallback(onBakedTextureMasksLoaded, MORPH_MASK_REQUESTED_DISCARD, TRUE, TRUE, new LLTextureMaskData( mID ));
@@ -6937,133 +5878,63 @@ void LLVOAvatar::updateMeshTextures()
baked_img->setLoadedCallback(onBakedTextureLoaded, SWITCH_TO_BAKED_DISCARD, FALSE, FALSE, new LLUUID( mID ) );
}
}
- else if (mBakedTextureData[i].mTexLayerSet
+ else if (mBakedTextureDatas[i].mTexLayerSet
&& !other_culled
- && (i != BAKED_HAIR || is_layer_baked[i] || mIsSelf)) // ! BACKWARDS COMPATIBILITY ! workaround for old viewers.
+ && (i != BAKED_HAIR || is_layer_baked[i] || isSelf())) // ! BACKWARDS COMPATIBILITY ! workaround for old viewers.
{
- mBakedTextureData[i].mTexLayerSet->createComposite();
- mBakedTextureData[i].mTexLayerSet->setUpdatesEnabled( TRUE );
- mBakedTextureData[i].mIsUsed = FALSE;
- for (U32 k=0; k < mBakedTextureData[i].mMeshes.size(); k++)
+ mBakedTextureDatas[i].mTexLayerSet->createComposite();
+ mBakedTextureDatas[i].mTexLayerSet->setUpdatesEnabled( TRUE );
+ mBakedTextureDatas[i].mIsUsed = FALSE;
+ for (U32 k=0; k < mBakedTextureDatas[i].mMeshes.size(); k++)
{
- mBakedTextureData[i].mMeshes[k]->setLayerSet( mBakedTextureData[i].mTexLayerSet );
+ mBakedTextureDatas[i].mMeshes[k]->setLayerSet( mBakedTextureDatas[i].mTexLayerSet );
}
}
}
// ! BACKWARDS COMPATIBILITY !
// Workaround for viewing avatars from old viewers that haven't baked hair textures.
- // if (!isTextureDefined(mBakedTextureData[BAKED_HAIR].mTextureIndex))
if (!is_layer_baked[BAKED_HAIR] || self_customizing)
{
const LLColor4 color = mTexHairColor ? mTexHairColor->getColor() : LLColor4(1,1,1,1);
- LLViewerImage* hair_img = getTEImage( TEX_HAIR );
- for (U32 i = 0; i < mBakedTextureData[BAKED_HAIR].mMeshes.size(); i++)
+ LLViewerTexture* hair_img = getImage( TEX_HAIR );
+ for (U32 i = 0; i < mBakedTextureDatas[BAKED_HAIR].mMeshes.size(); i++)
{
- mBakedTextureData[BAKED_HAIR].mMeshes[i]->setColor( color.mV[VX], color.mV[VY], color.mV[VZ], color.mV[VW] );
- mBakedTextureData[BAKED_HAIR].mMeshes[i]->setTexture( hair_img );
+ mBakedTextureDatas[BAKED_HAIR].mMeshes[i]->setColor( color.mV[VX], color.mV[VY], color.mV[VZ], color.mV[VW] );
+ mBakedTextureDatas[BAKED_HAIR].mMeshes[i]->setTexture( hair_img );
}
- mHasBakedHair = FALSE;
}
- else
- {
- mHasBakedHair = TRUE;
- }
- /* // Head
- BOOL head_baked_ready = (is_layer_baked[BAKED_HEAD] && mBakedTextureData[BAKED_HEAD].mIsLoaded) || other_culled;
- setLocalTexture( TEX_HEAD_BODYPAINT, getTEImage( TEX_HEAD_BODYPAINT ), head_baked_ready ); */
- for (LLVOAvatarDictionary::baked_map_t::const_iterator baked_iter = LLVOAvatarDictionary::getInstance()->getBakedTextures().begin();
+ // Turn on alpha masking correctly for yourself and other avatars on 1.23+
+ mSupportsAlphaLayers = isSelf() || is_layer_baked[BAKED_HAIR];
+
+ for (LLVOAvatarDictionary::BakedTextures::const_iterator baked_iter = LLVOAvatarDictionary::getInstance()->getBakedTextures().begin();
baked_iter != LLVOAvatarDictionary::getInstance()->getBakedTextures().end();
baked_iter++)
{
const EBakedTextureIndex baked_index = baked_iter->first;
- const LLVOAvatarDictionary::BakedDictionaryEntry *baked_dict = baked_iter->second;
+ const LLVOAvatarDictionary::BakedEntry *baked_dict = baked_iter->second;
for (texture_vec_t::const_iterator local_tex_iter = baked_dict->mLocalTextures.begin();
local_tex_iter != baked_dict->mLocalTextures.end();
local_tex_iter++)
{
const ETextureIndex texture_index = *local_tex_iter;
- const BOOL is_baked_ready = (is_layer_baked[baked_index] && mBakedTextureData[baked_index].mIsLoaded) || other_culled;
- setLocalTexture(texture_index, getTEImage(texture_index), is_baked_ready );
+ const BOOL is_baked_ready = (is_layer_baked[baked_index] && mBakedTextureDatas[baked_index].mIsLoaded) || other_culled;
+ setLocalTexture(texture_index, getImage(texture_index), is_baked_ready );
}
}
removeMissingBakedTextures();
}
+// virtual
//-----------------------------------------------------------------------------
// setLocalTexture()
//-----------------------------------------------------------------------------
-void LLVOAvatar::setLocalTexture( ETextureIndex index, LLViewerImage* tex, BOOL baked_version_ready )
-{
- if (!isIndexLocalTexture(index)) return;
-
- S32 desired_discard = mIsSelf ? 0 : 2;
- LocalTextureData &local_tex_data = mLocalTextureData[index];
- if (!baked_version_ready)
- {
- if (tex != local_tex_data.mImage || local_tex_data.mIsBakedReady)
- {
- local_tex_data.mDiscard = MAX_DISCARD_LEVEL+1;
- }
- if (tex->getID() != IMG_DEFAULT_AVATAR)
- {
- if (local_tex_data.mDiscard > desired_discard)
- {
- S32 tex_discard = tex->getDiscardLevel();
- if (tex_discard >= 0 && tex_discard <= desired_discard)
- {
- local_tex_data.mDiscard = tex_discard;
- if( mIsSelf && !gAgent.cameraCustomizeAvatar() )
- {
- requestLayerSetUpdate( index );
- }
- else if( mIsSelf && gAgent.cameraCustomizeAvatar() )
- {
- LLVisualParamHint::requestHintUpdates();
- }
- }
- else
- {
- tex->setLoadedCallback( onLocalTextureLoaded, desired_discard, TRUE, FALSE, new LLAvatarTexData(getID(), index) );
- }
- }
- tex->setMinDiscardLevel(desired_discard);
- }
- }
- local_tex_data.mIsBakedReady = baked_version_ready;
- local_tex_data.mImage = tex;
-}
-
-//-----------------------------------------------------------------------------
-// requestLayerSetUploads()
-//-----------------------------------------------------------------------------
-void LLVOAvatar::requestLayerSetUploads()
-{
- for (U32 i = 0; i < mBakedTextureData.size(); i++)
- {
- bool layer_baked = isTextureDefined(mBakedTextureData[i].mTextureIndex);
- if ( !layer_baked && mBakedTextureData[i].mTexLayerSet )
- {
- mBakedTextureData[i].mTexLayerSet->requestUpload();
- }
- }
-}
-
-
-//-----------------------------------------------------------------------------
-// setCompositeUpdatesEnabled()
-//-----------------------------------------------------------------------------
-void LLVOAvatar::setCompositeUpdatesEnabled( BOOL b )
+void LLVOAvatar::setLocalTexture( ETextureIndex type, LLViewerTexture* in_tex, BOOL baked_version_ready, U32 index )
{
- for (U32 i = 0; i < mBakedTextureData.size(); i++)
- {
- if (mBakedTextureData[i].mTexLayerSet )
- {
- mBakedTextureData[i].mTexLayerSet->setUpdatesEnabled( b );
- }
- }
+ // invalid for anyone but self
+ llassert(0);
}
void LLVOAvatar::addChat(const LLChat& chat)
@@ -7095,184 +5966,85 @@ void LLVOAvatar::clearChat()
mChats.clear();
}
-S32 LLVOAvatar::getLocalDiscardLevel( ETextureIndex index )
+// adds a morph mask to the appropriate baked texture structure
+void LLVOAvatar::addMaskedMorph(EBakedTextureIndex index, LLPolyMorphTarget* morph_target, BOOL invert, std::string layer)
{
- if (!isIndexLocalTexture(index)) return FALSE;
-
- LocalTextureData &local_tex_data = mLocalTextureData[index];
- if (index >= 0
- && getLocalTextureID(index) != IMG_DEFAULT_AVATAR
- && !local_tex_data.mImage->isMissingAsset())
+ if (index < BAKED_NUM_INDICES)
{
- return local_tex_data.mImage->getDiscardLevel();
- }
- else
- {
- // We don't care about this (no image associated with the layer) treat as fully loaded.
- return 0;
+ LLMaskedMorph *morph = new LLMaskedMorph(morph_target, invert, layer);
+ mBakedTextureDatas[index].mMaskedMorphs.push_front(morph);
}
}
-//-----------------------------------------------------------------------------
-// isLocalTextureDataFinal()
-// Returns true if the highest quality discard level exists for every texture
-// in the layerset.
-//-----------------------------------------------------------------------------
-BOOL LLVOAvatar::isLocalTextureDataFinal( LLTexLayerSet* layerset )
+// invalidates morph masks for a given layer. Don't pass a parameter to invalidate all morph masks.
+void LLVOAvatar::invalidateMorphMasks(LLVOAvatarDefines::EBakedTextureIndex index)
{
- for (U32 i = 0; i < mBakedTextureData.size(); i++)
- {
- if (layerset == mBakedTextureData[i].mTexLayerSet)
- {
- const LLVOAvatarDictionary::BakedDictionaryEntry *baked_dict = LLVOAvatarDictionary::getInstance()->getBakedTexture((EBakedTextureIndex)i);
- for (texture_vec_t::const_iterator local_tex_iter = baked_dict->mLocalTextures.begin();
- local_tex_iter != baked_dict->mLocalTextures.end();
- local_tex_iter++)
- {
- if (getLocalDiscardLevel(*local_tex_iter) != 0)
- {
- return FALSE;
- }
- }
- return TRUE;
- }
- }
-
- llassert(0);
- return FALSE;
+ setMorphMasksValid(FALSE, index);
}
-//-----------------------------------------------------------------------------
-// isLocalTextureDataAvailable()
-// Returns true if at least the lowest quality discard level exists for every texture
-// in the layerset.
-//-----------------------------------------------------------------------------
-BOOL LLVOAvatar::isLocalTextureDataAvailable( LLTexLayerSet* layerset )
+// updates morph masks to be a value for a given layer. Don't pass an argument to set value for all morph masks
+void LLVOAvatar::setMorphMasksValid(BOOL new_status, LLVOAvatarDefines::EBakedTextureIndex index)
{
- /* if( layerset == mBakedTextureData[BAKED_HEAD].mTexLayerSet )
- return getLocalDiscardLevel( TEX_HEAD_BODYPAINT ) >= 0; */
- for (LLVOAvatarDictionary::baked_map_t::const_iterator baked_iter = LLVOAvatarDictionary::getInstance()->getBakedTextures().begin();
- baked_iter != LLVOAvatarDictionary::getInstance()->getBakedTextures().end();
- baked_iter++)
+ if (index == BAKED_NUM_INDICES)
{
- const EBakedTextureIndex baked_index = baked_iter->first;
- if (layerset == mBakedTextureData[baked_index].mTexLayerSet)
+ for (U8 tex = 0; tex < (U8)BAKED_NUM_INDICES; tex++)
{
- bool ret = true;
- const LLVOAvatarDictionary::BakedDictionaryEntry *baked_dict = baked_iter->second;
- for (texture_vec_t::const_iterator local_tex_iter = baked_dict->mLocalTextures.begin();
- local_tex_iter != baked_dict->mLocalTextures.end();
- local_tex_iter++)
- {
- ret &= (getLocalDiscardLevel(*local_tex_iter) >= 0);
- }
- return ret;
+ mBakedTextureDatas[tex].mMorphMasksValid = new_status;
}
- }
- llassert(0);
- return FALSE;
-}
-
-
-//-----------------------------------------------------------------------------
-// getBakedTE()
-// Used by the LayerSet. (Layer sets don't in general know what textures depend on them.)
-//-----------------------------------------------------------------------------
-ETextureIndex LLVOAvatar::getBakedTE( LLTexLayerSet* layerset )
-{
- for (U32 i = 0; i < mBakedTextureData.size(); i++)
+ }
+ else if (index < BAKED_NUM_INDICES)
{
- if (layerset == mBakedTextureData[i].mTexLayerSet )
- {
- return mBakedTextureData[i].mTextureIndex;
- }
+ mBakedTextureDatas[index].mMorphMasksValid = new_status;
}
-
- llassert(0);
- return TEX_HEAD_BAKED;
}
-//-----------------------------------------------------------------------------
-// setNewBakedTexture()
-// A new baked texture has been successfully uploaded and we can start using it now.
-//-----------------------------------------------------------------------------
-void LLVOAvatar::setNewBakedTexture( ETextureIndex te, const LLUUID& uuid )
+// returns TRUE if morph masks are present and not valid for a given baked texture, FALSE otherwise
+BOOL LLVOAvatar::morphMaskNeedsUpdate(LLVOAvatarDefines::EBakedTextureIndex index)
{
- // Baked textures live on other sims.
- LLHost target_host = getObjectHost();
- setTEImage( te, gImageList.getImageFromHost( uuid, target_host ) );
- updateMeshTextures();
- dirtyMesh();
-
-
- LLVOAvatar::cullAvatarsByPixelArea();
-
- /* switch(te)
- case TEX_HEAD_BAKED:
- llinfos << "New baked texture: HEAD" << llendl; */
- const LLVOAvatarDictionary::TextureDictionaryEntry *text_dict = LLVOAvatarDictionary::getInstance()->getTexture(te);
- if (text_dict->mIsBakedTexture)
+ if (index >= BAKED_NUM_INDICES)
{
- llinfos << "New baked texture: " << text_dict->mName << " UUID: " << uuid <<llendl;
- mBakedTextureData[text_dict->mBakedTextureIndex].mTexLayerSet->requestUpdate();
- }
- else
- {
- llwarns << "New baked texture: unknown te " << te << llendl;
+ return FALSE;
}
-
- // dumpAvatarTEs( "setNewBakedTexture() send" );
- // RN: throttle uploads
- if (!hasPendingBakedUploads())
+
+ if (!mBakedTextureDatas[index].mMaskedMorphs.empty() && !mBakedTextureDatas[index].mMorphMasksValid)
{
- gAgent.sendAgentSetAppearance();
+ return TRUE;
}
+
+ return FALSE;
}
-bool LLVOAvatar::hasPendingBakedUploads()
+void LLVOAvatar::applyMorphMask(U8* tex_data, S32 width, S32 height, S32 num_components, LLVOAvatarDefines::EBakedTextureIndex index)
{
- for (U32 i = 0; i < mBakedTextureData.size(); i++)
+ if (index >= BAKED_NUM_INDICES)
{
- bool upload_pending = (mBakedTextureData[i].mTexLayerSet && mBakedTextureData[i].mTexLayerSet->getComposite()->uploadPending());
- if (upload_pending)
- {
- return true;
- }
+ llwarns << "invalid baked texture index passed to applyMorphMask" << llendl;
+ return;
}
- return false;
-}
-
-//-----------------------------------------------------------------------------
-// setCachedBakedTexture()
-// A baked texture id was received from a cache query, make it active
-//-----------------------------------------------------------------------------
-void LLVOAvatar::setCachedBakedTexture( ETextureIndex te, const LLUUID& uuid )
-{
- setTETexture( te, uuid );
- /* switch(te)
- case TEX_HEAD_BAKED:
- if( mHeadLayerSet )
- mHeadLayerSet->cancelUpload(); */
- for (U32 i = 0; i < mBakedTextureData.size(); i++)
+ for (morph_list_t::const_iterator iter = mBakedTextureDatas[index].mMaskedMorphs.begin();
+ iter != mBakedTextureDatas[index].mMaskedMorphs.end(); iter++)
{
- if ( mBakedTextureData[i].mTextureIndex == te && mBakedTextureData[i].mTexLayerSet)
- {
- mBakedTextureData[i].mTexLayerSet->cancelUpload();
- }
+ const LLMaskedMorph* maskedMorph = (*iter);
+ maskedMorph->mMorphTarget->applyMask(tex_data, width, height, num_components, maskedMorph->mInvert);
}
}
+
//-----------------------------------------------------------------------------
-// releaseUnneccesaryTextures()
+// releaseComponentTextures()
// release any component texture UUIDs for which we have a baked texture
+// ! BACKWARDS COMPATIBILITY !
+// This is only called for non-self avatars, it can be taken out once component
+// textures aren't communicated by non-self avatars.
//-----------------------------------------------------------------------------
-void LLVOAvatar::releaseUnnecessaryTextures()
+void LLVOAvatar::releaseComponentTextures()
{
- // Backwards Compat: detect if the baked hair texture actually wasn't sent, and if so set to default
- if (isTextureDefined(TEX_HAIR_BAKED) && getTEImage(TEX_HAIR_BAKED)->getID() == getTEImage(TEX_SKIRT_BAKED)->getID())
+ // ! BACKWARDS COMPATIBILITY !
+ // Detect if the baked hair texture actually wasn't sent, and if so set to default
+ if (isTextureDefined(TEX_HAIR_BAKED) && getImage(TEX_HAIR_BAKED)->getID() == getImage(TEX_SKIRT_BAKED)->getID())
{
- if (getTEImage(TEX_HAIR_BAKED)->getID() != IMG_INVISIBLE)
+ if (getImage(TEX_HAIR_BAKED)->getID() != IMG_INVISIBLE)
{
// Regression case of messaging system. Expected 21 textures, received 20. last texture is not valid so set to default
setTETexture(TEX_HAIR_BAKED, IMG_DEFAULT_AVATAR);
@@ -7281,7 +6053,7 @@ void LLVOAvatar::releaseUnnecessaryTextures()
for (U8 baked_index = 0; baked_index < BAKED_NUM_INDICES; baked_index++)
{
- const LLVOAvatarDictionary::BakedDictionaryEntry * bakedDicEntry = LLVOAvatarDictionary::getInstance()->getBakedTexture((EBakedTextureIndex)baked_index);
+ const LLVOAvatarDictionary::BakedEntry * bakedDicEntry = LLVOAvatarDictionary::getInstance()->getBakedTexture((EBakedTextureIndex)baked_index);
// skip if this is a skirt and av is not wearing one, or if we don't have a baked texture UUID
if (!isTextureDefined(bakedDicEntry->mTextureIndex)
&& ( (baked_index != BAKED_SKIRT) || isWearingWearableType(WT_SKIRT) ))
@@ -7297,111 +6069,68 @@ void LLVOAvatar::releaseUnnecessaryTextures()
}
}
-//-----------------------------------------------------------------------------
-// static
-// onCustomizeStart()
-//-----------------------------------------------------------------------------
-void LLVOAvatar::onCustomizeStart()
-{
- // We're no longer doing any baking or invalidating on entering
- // appearance editing mode. Leaving function in place in case
- // further changes require us to do something at this point - Nyx
-}
-
-//-----------------------------------------------------------------------------
-// static
-// onCustomizeEnd()
-//-----------------------------------------------------------------------------
-void LLVOAvatar::onCustomizeEnd()
-{
- LLVOAvatar *avatarp = gAgent.getAvatarObject();
- if (avatarp)
- {
- avatarp->invalidateAll();
- avatarp->requestLayerSetUploads();
- }
-}
-
-void LLVOAvatar::onChangeSelfInvisible(BOOL newvalue)
-{
- LLVOAvatar *avatarp = gAgent.getAvatarObject();
- if (avatarp)
- {
- if (newvalue)
- {
- // we have just requested to set the avatar's baked textures to invisible
- avatarp->setInvisible(TRUE);
- }
- else
- {
- avatarp->setInvisible(FALSE);
- }
- }
-}
-
-
BOOL LLVOAvatar::teToColorParams( ETextureIndex te, const char* param_name[3] )
{
switch( te )
{
- case TEX_UPPER_SHIRT:
- param_name[0] = "shirt_red";
- param_name[1] = "shirt_green";
- param_name[2] = "shirt_blue";
- break;
-
- case TEX_LOWER_PANTS:
- param_name[0] = "pants_red";
- param_name[1] = "pants_green";
- param_name[2] = "pants_blue";
- break;
-
- case TEX_LOWER_SHOES:
- param_name[0] = "shoes_red";
- param_name[1] = "shoes_green";
- param_name[2] = "shoes_blue";
- break;
-
- case TEX_LOWER_SOCKS:
- param_name[0] = "socks_red";
- param_name[1] = "socks_green";
- param_name[2] = "socks_blue";
- break;
-
- case TEX_UPPER_JACKET:
- case TEX_LOWER_JACKET:
- param_name[0] = "jacket_red";
- param_name[1] = "jacket_green";
- param_name[2] = "jacket_blue";
- break;
-
- case TEX_UPPER_GLOVES:
- param_name[0] = "gloves_red";
- param_name[1] = "gloves_green";
- param_name[2] = "gloves_blue";
- break;
-
- case TEX_UPPER_UNDERSHIRT:
- param_name[0] = "undershirt_red";
- param_name[1] = "undershirt_green";
- param_name[2] = "undershirt_blue";
- break;
+ case TEX_UPPER_SHIRT:
+ param_name[0] = "shirt_red";
+ param_name[1] = "shirt_green";
+ param_name[2] = "shirt_blue";
+ break;
+
+ case TEX_LOWER_PANTS:
+ param_name[0] = "pants_red";
+ param_name[1] = "pants_green";
+ param_name[2] = "pants_blue";
+ break;
+
+ case TEX_LOWER_SHOES:
+ param_name[0] = "shoes_red";
+ param_name[1] = "shoes_green";
+ param_name[2] = "shoes_blue";
+ break;
+
+ case TEX_LOWER_SOCKS:
+ param_name[0] = "socks_red";
+ param_name[1] = "socks_green";
+ param_name[2] = "socks_blue";
+ break;
+
+ case TEX_UPPER_JACKET:
+ case TEX_LOWER_JACKET:
+ param_name[0] = "jacket_red";
+ param_name[1] = "jacket_green";
+ param_name[2] = "jacket_blue";
+ break;
+
+ case TEX_UPPER_GLOVES:
+ param_name[0] = "gloves_red";
+ param_name[1] = "gloves_green";
+ param_name[2] = "gloves_blue";
+ break;
+
+ case TEX_UPPER_UNDERSHIRT:
+ param_name[0] = "undershirt_red";
+ param_name[1] = "undershirt_green";
+ param_name[2] = "undershirt_blue";
+ break;
- case TEX_LOWER_UNDERPANTS:
- param_name[0] = "underpants_red";
- param_name[1] = "underpants_green";
- param_name[2] = "underpants_blue";
- break;
-
- case TEX_SKIRT:
- param_name[0] = "skirt_red";
- param_name[1] = "skirt_green";
- param_name[2] = "skirt_blue";
- break;
-
- default:
- llassert(0);
- return FALSE;
+ case TEX_LOWER_UNDERPANTS:
+ param_name[0] = "underpants_red";
+ param_name[1] = "underpants_green";
+ param_name[2] = "underpants_blue";
+ break;
+
+ case TEX_SKIRT:
+ param_name[0] = "skirt_red";
+ param_name[1] = "skirt_green";
+ param_name[2] = "skirt_blue";
+ break;
+
+ default:
+ llassert(0);
+ return FALSE;
}
return TRUE;
@@ -7431,140 +6160,53 @@ LLColor4 LLVOAvatar::getClothesColor( ETextureIndex te )
return color;
}
-
-
+// static
+LLColor4 LLVOAvatar::getDummyColor()
+{
+ return DUMMY_COLOR;
+}
void LLVOAvatar::dumpAvatarTEs( const std::string& context )
{
/* const char* te_name[] = {
"TEX_HEAD_BODYPAINT ",
"TEX_UPPER_SHIRT ", */
- llinfos << (mIsSelf ? "Self: " : "Other: ") << context << llendl;
- for (LLVOAvatarDictionary::texture_map_t::const_iterator iter = LLVOAvatarDictionary::getInstance()->getTextures().begin();
+ llinfos << (isSelf() ? "Self: " : "Other: ") << context << llendl;
+ for (LLVOAvatarDictionary::Textures::const_iterator iter = LLVOAvatarDictionary::getInstance()->getTextures().begin();
iter != LLVOAvatarDictionary::getInstance()->getTextures().end();
iter++)
{
- const LLVOAvatarDictionary::TextureDictionaryEntry *text_dict = iter->second;
- const LLViewerImage* te_image = getTEImage(iter->first);
+ const LLVOAvatarDictionary::TextureEntry *texture_dict = iter->second;
+ const LLViewerTexture* te_image = getImage(iter->first);
if( !te_image )
{
- llinfos << " " << text_dict->mName << ": null ptr" << llendl;
+ llinfos << " " << texture_dict->mName << ": null ptr" << llendl;
}
else if( te_image->getID().isNull() )
{
- llinfos << " " << text_dict->mName << ": null UUID" << llendl;
+ llinfos << " " << texture_dict->mName << ": null UUID" << llendl;
}
else if( te_image->getID() == IMG_DEFAULT )
{
- llinfos << " " << text_dict->mName << ": IMG_DEFAULT" << llendl;
+ llinfos << " " << texture_dict->mName << ": IMG_DEFAULT" << llendl;
}
else if( te_image->getID() == IMG_DEFAULT_AVATAR )
{
- llinfos << " " << text_dict->mName << ": IMG_DEFAULT_AVATAR" << llendl;
- }
- else
- {
- llinfos << " " << text_dict->mName << ": " << te_image->getID() << llendl;
- }
- }
-}
-
-//-----------------------------------------------------------------------------
-// updateAttachmentVisibility()
-//-----------------------------------------------------------------------------
-void LLVOAvatar::updateAttachmentVisibility(U32 camera_mode)
-{
- for (attachment_map_t::iterator iter = mAttachmentPoints.begin();
- iter != mAttachmentPoints.end(); )
- {
- attachment_map_t::iterator curiter = iter++;
- LLViewerJointAttachment* attachment = curiter->second;
- if (attachment->getIsHUDAttachment())
- {
- attachment->setAttachmentVisibility(TRUE);
+ llinfos << " " << texture_dict->mName << ": IMG_DEFAULT_AVATAR" << llendl;
}
else
{
- switch (camera_mode)
- {
- case CAMERA_MODE_MOUSELOOK:
- if (LLVOAvatar::sVisibleInFirstPerson && attachment->getVisibleInFirstPerson())
- {
- attachment->setAttachmentVisibility(TRUE);
- }
- else
- {
- attachment->setAttachmentVisibility(FALSE);
- }
- break;
- default:
- attachment->setAttachmentVisibility(TRUE);
- break;
- }
- }
- }
-}
-
-// Given a texture entry, determine which wearable type owns it.
-// static
-LLUUID LLVOAvatar::getDefaultTEImageID(ETextureIndex index )
-{
- /* switch( index )
- case TEX_UPPER_SHIRT: return LLUUID( gSavedSettings.getString("UIImgDefaultShirtUUID") ); */
- const LLVOAvatarDictionary::TextureDictionaryEntry *text_dict = LLVOAvatarDictionary::getInstance()->getTexture(index);
- const std::string &default_image_name = text_dict->mDefaultImageName;
- if (default_image_name == "")
- {
- return IMG_DEFAULT_AVATAR;
- }
- else
- {
- return LLUUID(gSavedSettings.getString(default_image_name));
- }
-}
-
-
-void LLVOAvatar::setInvisible(BOOL newvalue)
-{
- if (newvalue)
- {
- setCompositeUpdatesEnabled(FALSE);
- for (U32 i = 0; i < mBakedTextureData.size(); i++ )
- {
- setNewBakedTexture(mBakedTextureData[i].mTextureIndex, IMG_INVISIBLE);
+ llinfos << " " << texture_dict->mName << ": " << te_image->getID() << llendl;
}
- gAgent.sendAgentSetAppearance();
}
- else
- {
- setCompositeUpdatesEnabled(TRUE);
- invalidateAll();
- requestLayerSetUploads();
- gAgent.sendAgentSetAppearance();
- }
-}
-
-LLColor4 LLVOAvatar::getDummyColor()
-{
- return DUMMY_COLOR;
-}
-
-// Given a texture entry, determine which wearable type owns it.
-// static
-EWearableType LLVOAvatar::getTEWearableType(ETextureIndex index )
-{
- /* switch(index)
- case TEX_UPPER_SHIRT:
- return WT_SHIRT; */
- return LLVOAvatarDictionary::getInstance()->getTexture(index)->mWearableType;
}
// Unlike most wearable functions, this works for both self and other.
-BOOL LLVOAvatar::isWearingWearableType( EWearableType type )
+BOOL LLVOAvatar::isWearingWearableType(EWearableType type) const
{
if (mIsDummy) return TRUE;
- switch( type )
+ switch(type)
{
case WT_SHAPE:
case WT_SKIN:
@@ -7578,16 +6220,16 @@ BOOL LLVOAvatar::isWearingWearableType( EWearableType type )
/* switch(type)
case WT_SHIRT:
indicator_te = TEX_UPPER_SHIRT; */
- for (LLVOAvatarDictionary::texture_map_t::const_iterator tex_iter = LLVOAvatarDictionary::getInstance()->getTextures().begin();
+ for (LLVOAvatarDictionary::Textures::const_iterator tex_iter = LLVOAvatarDictionary::getInstance()->getTextures().begin();
tex_iter != LLVOAvatarDictionary::getInstance()->getTextures().end();
tex_iter++)
{
const LLVOAvatarDefines::ETextureIndex index = tex_iter->first;
- const LLVOAvatarDictionary::TextureDictionaryEntry *text_dict = tex_iter->second;
- if (text_dict->mWearableType == type)
+ const LLVOAvatarDictionary::TextureEntry *texture_dict = tex_iter->second;
+ if (texture_dict->mWearableType == type)
{
// If you're checking your own clothing, check the component texture
- if (mIsSelf)
+ if (isSelf())
{
if (isTextureDefined(index))
{
@@ -7604,23 +6246,10 @@ BOOL LLVOAvatar::isWearingWearableType( EWearableType type )
// NOTE: this is a poor substitute if you actually want to know about individual pieces of clothing
// this works for detecting a skirt (most important), but is ineffective at any piece of clothing that
// gets baked into a texture that always exists (upper or lower).
- const std::string name = text_dict->mName;
- for (LLVOAvatarDictionary::baked_map_t::const_iterator iter = LLVOAvatarDictionary::getInstance()->getBakedTextures().begin();
- iter != LLVOAvatarDictionary::getInstance()->getBakedTextures().end();
- iter++)
+ if (texture_dict->mIsUsedByBakedTexture)
{
- const LLVOAvatarDictionary::BakedDictionaryEntry *baked_dict = iter->second;
- if (baked_dict->mName == name)
- {
- if (isTextureDefined(baked_dict->mTextureIndex))
- {
- return TRUE;
- }
- else
- {
- return FALSE;
- }
- }
+ const EBakedTextureIndex baked_index = texture_dict->mBakedTextureIndex;
+ return isTextureDefined(LLVOAvatarDictionary::getInstance()->getBakedTexture(baked_index)->mTextureIndex);
}
return FALSE;
}
@@ -7629,41 +6258,6 @@ BOOL LLVOAvatar::isWearingWearableType( EWearableType type )
}
//-----------------------------------------------------------------------------
-// updatedWearable( EWearableType type )
-// forces an update to any baked textures relevant to type.
-// Should be called only on saving the wearable
-//-----------------------------------------------------------------------------
-void LLVOAvatar::wearableUpdated( EWearableType type )
-{
- for (LLVOAvatarDictionary::wearable_map_t::const_iterator wearable_iter = LLVOAvatarDictionary::getInstance()->getWearables().begin();
- wearable_iter != LLVOAvatarDictionary::getInstance()->getWearables().end();
- wearable_iter++)
- {
- const LLVOAvatarDictionary::WearableDictionaryEntry *wearable_dict = wearable_iter->second;
- const LLVOAvatarDefines::EBakedTextureIndex index = wearable_iter->first;
- if (wearable_dict)
- {
- for (LLVOAvatarDefines::wearables_vec_t::const_iterator type_iter = wearable_dict->mWearablesVec.begin();
- type_iter != wearable_dict->mWearablesVec.end();
- type_iter++)
- {
- const EWearableType comp_type = *type_iter;
- if (comp_type == type)
- {
- if (mBakedTextureData[index].mTexLayerSet)
- {
- mBakedTextureData[index].mTexLayerSet->requestUpdate();
- mBakedTextureData[index].mTexLayerSet->requestUpload();
- }
- break;
- }
- }
- }
- }
-}
-
-
-//-----------------------------------------------------------------------------
// clampAttachmentPositions()
//-----------------------------------------------------------------------------
void LLVOAvatar::clampAttachmentPositions()
@@ -7741,16 +6335,16 @@ void LLVOAvatar::onFirstTEMessageReceived()
{
mFirstTEMessageReceived = TRUE;
- for (U32 i = 0; i < mBakedTextureData.size(); i++)
+ for (U32 i = 0; i < mBakedTextureDatas.size(); i++)
{
- bool layer_baked = isTextureDefined(mBakedTextureData[i].mTextureIndex);
+ const BOOL layer_baked = isTextureDefined(mBakedTextureDatas[i].mTextureIndex);
// Use any baked textures that we have even if they haven't downloaded yet.
// (That is, don't do a transition from unbaked to baked.)
if (layer_baked)
{
- LLViewerImage* image = getTEImage( mBakedTextureData[i].mTextureIndex );
- mBakedTextureData[i].mLastTextureIndex = image->getID();
+ LLViewerFetchedTexture* image = LLViewerTextureManager::staticCastToFetchedTexture(getImage( mBakedTextureDatas[i].mTextureIndex ), TRUE) ;
+ mBakedTextureDatas[i].mLastTextureIndex = image->getID();
// If we have more than one texture for the other baked layers, we'll want to call this for them too.
if ( (i == BAKED_HEAD) || (i == BAKED_UPPER) || (i == BAKED_LOWER) )
{
@@ -7782,7 +6376,7 @@ void LLVOAvatar::processAvatarAppearance( LLMessageSystem* mesgsys )
mFirstAppearanceMessageReceived = TRUE;
- if( mIsSelf )
+ if( isSelf() )
{
llwarns << "Received AvatarAppearance for self" << llendl;
if( mFirstTEMessageReceived )
@@ -7799,31 +6393,24 @@ void LLVOAvatar::processAvatarAppearance( LLMessageSystem* mesgsys )
ESex old_sex = getSex();
-// llinfos << "ady LLVOAvatar::processAvatarAppearance()" << llendl;
+// llinfos << "LLVOAvatar::processAvatarAppearance()" << llendl;
// dumpAvatarTEs( "PRE processAvatarAppearance()" );
unpackTEMessage(mesgsys, _PREHASH_ObjectData);
// dumpAvatarTEs( "POST processAvatarAppearance()" );
// prevent the overwriting of valid baked textures with invalid baked textures
- for (U8 baked_index = 0; baked_index < mBakedTextureData.size(); baked_index++)
+ for (U8 baked_index = 0; baked_index < mBakedTextureDatas.size(); baked_index++)
{
- if (!isTextureDefined(mBakedTextureData[baked_index].mTextureIndex)
- && mBakedTextureData[baked_index].mLastTextureIndex != IMG_DEFAULT
+ if (!isTextureDefined(mBakedTextureDatas[baked_index].mTextureIndex)
+ && mBakedTextureDatas[baked_index].mLastTextureIndex != IMG_DEFAULT
&& baked_index != BAKED_SKIRT)
{
- setTEImage(mBakedTextureData[baked_index].mTextureIndex, gImageList.getImage(mBakedTextureData[baked_index].mLastTextureIndex));
+ setTEImage(mBakedTextureDatas[baked_index].mTextureIndex,
+ LLViewerTextureManager::getFetchedTexture(mBakedTextureDatas[baked_index].mLastTextureIndex, TRUE, FALSE, LLViewerTexture::LOD_TEXTURE));
}
}
- //llinfos << "Received AvatarAppearance: " << (mIsSelf ? "(self): " : "(other): ") << std::endl <<
- // (isTextureDefined(TEX_HEAD_BAKED) ? "HEAD " : "head " ) << (getTEImage(TEX_HEAD_BAKED)->getID()) << std::endl <<
- // (isTextureDefined(TEX_UPPER_BAKED) ? "UPPER " : "upper " ) << (getTEImage(TEX_UPPER_BAKED)->getID()) << std::endl <<
- // (isTextureDefined(TEX_LOWER_BAKED) ? "LOWER " : "lower " ) << (getTEImage(TEX_LOWER_BAKED)->getID()) << std::endl <<
- // (isTextureDefined(TEX_SKIRT_BAKED) ? "SKIRT " : "skirt " ) << (getTEImage(TEX_SKIRT_BAKED)->getID()) << std::endl <<
- // (isTextureDefined(TEX_HAIR_BAKED) ? "HAIR" : "hair " ) << (getTEImage(TEX_HAIR_BAKED)->getID()) << std::endl <<
- // (isTextureDefined(TEX_EYES_BAKED) ? "EYES" : "eyes" ) << (getTEImage(TEX_EYES_BAKED)->getID()) << llendl ;
-
if( !mFirstTEMessageReceived )
{
onFirstTEMessageReceived();
@@ -7831,9 +6418,11 @@ void LLVOAvatar::processAvatarAppearance( LLMessageSystem* mesgsys )
setCompositeUpdatesEnabled( FALSE );
- if (!mIsSelf)
+ // ! BACKWARDS COMPATIBILITY !
+ // Non-self avatars will no longer have component textures
+ if (!isSelf())
{
- releaseUnnecessaryTextures();
+ releaseComponentTextures();
}
updateMeshTextures(); // enables updates for laysets without baked textures.
@@ -7954,7 +6543,7 @@ void LLVOAvatar::getAnimNames( LLDynamicArray<std::string>* names )
names->put( "enter_away_from_keyboard_state" );
}
-void LLVOAvatar::onBakedTextureMasksLoaded( BOOL success, LLViewerImage *src_vi, LLImageRaw* src, LLImageRaw* aux_src, S32 discard_level, BOOL final, void* userdata )
+void LLVOAvatar::onBakedTextureMasksLoaded( BOOL success, LLViewerFetchedTexture *src_vi, LLImageRaw* src, LLImageRaw* aux_src, S32 discard_level, BOOL final, void* userdata )
{
if (!userdata) return;
@@ -7993,39 +6582,32 @@ void LLVOAvatar::onBakedTextureMasksLoaded( BOOL success, LLViewerImage *src_vi,
gGL.getTexUnit(0)->setTextureFilteringOption(LLTexUnit::TFO_BILINEAR);
/* if( id == head_baked->getID() )
- if (self->mBakedTextureData[BAKED_HEAD].mTexLayerSet)
+ if (self->mBakedTextureDatas[BAKED_HEAD].mTexLayerSet)
//llinfos << "onBakedTextureMasksLoaded for head " << id << " discard = " << discard_level << llendl;
- self->mBakedTextureData[BAKED_HEAD].mTexLayerSet->applyMorphMask(aux_src->getData(), aux_src->getWidth(), aux_src->getHeight(), 1);
+ self->mBakedTextureDatas[BAKED_HEAD].mTexLayerSet->applyMorphMask(aux_src->getData(), aux_src->getWidth(), aux_src->getHeight(), 1);
maskData->mLastDiscardLevel = discard_level; */
- bool found_texture_id = false;
- for (LLVOAvatarDictionary::texture_map_t::const_iterator iter = LLVOAvatarDictionary::getInstance()->getTextures().begin();
+ BOOL found_texture_id = false;
+ for (LLVOAvatarDictionary::Textures::const_iterator iter = LLVOAvatarDictionary::getInstance()->getTextures().begin();
iter != LLVOAvatarDictionary::getInstance()->getTextures().end();
iter++)
{
- const LLVOAvatarDictionary::TextureDictionaryEntry *text_dict = iter->second;
- if (text_dict->mIsUsedByBakedTexture)
+ const LLVOAvatarDictionary::TextureEntry *texture_dict = iter->second;
+ if (texture_dict->mIsUsedByBakedTexture)
{
const ETextureIndex texture_index = iter->first;
- const LLViewerImage *baked_img = self->getTEImage(texture_index);
+ const LLViewerTexture *baked_img = self->getImage(texture_index);
if (id == baked_img->getID())
{
- const EBakedTextureIndex baked_index = text_dict->mBakedTextureIndex;
- if (self->mBakedTextureData[baked_index].mTexLayerSet)
+ const EBakedTextureIndex baked_index = texture_dict->mBakedTextureIndex;
+ self->applyMorphMask(aux_src->getData(), aux_src->getWidth(), aux_src->getHeight(), 1, baked_index);
+ maskData->mLastDiscardLevel = discard_level;
+ if (self->mBakedTextureDatas[baked_index].mMaskTexName)
{
- //llinfos << "onBakedTextureMasksLoaded for " << text_dict->mName << " " << id << " discard = " << discard_level << llendl;
- self->mBakedTextureData[baked_index].mTexLayerSet->applyMorphMask(aux_src->getData(), aux_src->getWidth(), aux_src->getHeight(), 1);
- maskData->mLastDiscardLevel = discard_level;
- if (self->mBakedTextureData[baked_index].mMaskTexName)
- {
- LLImageGL::deleteTextures(1, &(self->mBakedTextureData[baked_index].mMaskTexName));
- }
- self->mBakedTextureData[baked_index].mMaskTexName = gl_name;
- }
- else
- {
- llwarns << "onBakedTextureMasksLoaded: no LayerSet for " << text_dict->mName << "." << llendl;
+ LLImageGL::deleteTextures(1, &(self->mBakedTextureDatas[baked_index].mMaskTexName));
}
+
+ self->mBakedTextureDatas[baked_index].mMaskTexName = gl_name;
found_texture_id = true;
break;
}
@@ -8052,7 +6634,7 @@ void LLVOAvatar::onBakedTextureMasksLoaded( BOOL success, LLViewerImage *src_vi,
}
// static
-void LLVOAvatar::onInitialBakedTextureLoaded( BOOL success, LLViewerImage *src_vi, LLImageRaw* src, LLImageRaw* aux_src, S32 discard_level, BOOL final, void* userdata )
+void LLVOAvatar::onInitialBakedTextureLoaded( BOOL success, LLViewerFetchedTexture *src_vi, LLImageRaw* src, LLImageRaw* aux_src, S32 discard_level, BOOL final, void* userdata )
{
LLUUID *avatar_idp = (LLUUID *)userdata;
LLVOAvatar *selfp = (LLVOAvatar *)gObjectList.findObject(*avatar_idp);
@@ -8067,7 +6649,7 @@ void LLVOAvatar::onInitialBakedTextureLoaded( BOOL success, LLViewerImage *src_v
}
}
-void LLVOAvatar::onBakedTextureLoaded(BOOL success, LLViewerImage *src_vi, LLImageRaw* src, LLImageRaw* aux_src, S32 discard_level, BOOL final, void* userdata)
+void LLVOAvatar::onBakedTextureLoaded(BOOL success, LLViewerFetchedTexture *src_vi, LLImageRaw* src, LLImageRaw* aux_src, S32 discard_level, BOOL final, void* userdata)
{
//llinfos << "onBakedTextureLoaded: " << src_vi->getID() << llendl;
@@ -8100,28 +6682,28 @@ void LLVOAvatar::useBakedTexture( const LLUUID& id )
mLastHeadBakedID = id;
mHeadMesh0.setTexture( head_baked );
mHeadMesh1.setTexture( head_baked ); */
- for (U32 i = 0; i < mBakedTextureData.size(); i++)
+ for (U32 i = 0; i < mBakedTextureDatas.size(); i++)
{
- LLViewerImage* image_baked = getTEImage( mBakedTextureData[i].mTextureIndex );
+ LLViewerTexture* image_baked = getImage( mBakedTextureDatas[i].mTextureIndex );
if (id == image_baked->getID())
{
- mBakedTextureData[i].mIsLoaded = true;
- mBakedTextureData[i].mIsUsed = true;
- mBakedTextureData[i].mLastTextureIndex = id;
- for (U32 k = 0; k < mBakedTextureData[i].mMeshes.size(); k++)
+ mBakedTextureDatas[i].mIsLoaded = true;
+ mBakedTextureDatas[i].mLastTextureIndex = id;
+ mBakedTextureDatas[i].mIsUsed = true;
+ for (U32 k = 0; k < mBakedTextureDatas[i].mMeshes.size(); k++)
{
- mBakedTextureData[i].mMeshes[k]->setTexture( image_baked );
+ mBakedTextureDatas[i].mMeshes[k]->setTexture( image_baked );
}
- if (mBakedTextureData[i].mTexLayerSet)
+ if (mBakedTextureDatas[i].mTexLayerSet)
{
- mBakedTextureData[i].mTexLayerSet->destroyComposite();
+ mBakedTextureDatas[i].mTexLayerSet->destroyComposite();
}
- const LLVOAvatarDictionary::BakedDictionaryEntry *baked_dict = LLVOAvatarDictionary::getInstance()->getBakedTexture((EBakedTextureIndex)i);
+ const LLVOAvatarDictionary::BakedEntry *baked_dict = LLVOAvatarDictionary::getInstance()->getBakedTexture((EBakedTextureIndex)i);
for (texture_vec_t::const_iterator local_tex_iter = baked_dict->mLocalTextures.begin();
local_tex_iter != baked_dict->mLocalTextures.end();
local_tex_iter++)
{
- setLocalTexture(*local_tex_iter, getTEImage(*local_tex_iter), TRUE);
+ setLocalTexture(*local_tex_iter, getImage(*local_tex_iter), TRUE);
}
// ! BACKWARDS COMPATIBILITY !
@@ -8129,9 +6711,9 @@ void LLVOAvatar::useBakedTexture( const LLUUID& id )
// This is paired with similar code in updateMeshTextures that sets hair mesh color.
if (i == BAKED_HAIR)
{
- for (U32 i = 0; i < mBakedTextureData[BAKED_HAIR].mMeshes.size(); i++)
+ for (U32 i = 0; i < mBakedTextureDatas[BAKED_HAIR].mMeshes.size(); i++)
{
- mBakedTextureData[BAKED_HAIR].mMeshes[i]->setColor( 1.f, 1.f, 1.f, 1.f );
+ mBakedTextureDatas[BAKED_HAIR].mMeshes[i]->setColor( 1.f, 1.f, 1.f, 1.f );
}
}
}
@@ -8147,7 +6729,7 @@ void LLVOAvatar::dumpArchetypeXML( void* )
LLAPRFile outfile ;
outfile.open(gDirUtilp->getExpandedFilename(LL_PATH_CHARACTER,"new archetype.xml"), LL_APR_WB );
apr_file_t* file = outfile.getFileHandle() ;
- if( !file )
+ if (!file)
{
return;
}
@@ -8157,27 +6739,27 @@ void LLVOAvatar::dumpArchetypeXML( void* )
apr_file_printf( file, "\n\t<archetype name=\"???\">\n" );
// only body parts, not clothing.
- for( S32 type = WT_SHAPE; type <= WT_EYES; type++ )
+ for (S32 type = WT_SHAPE; type <= WT_EYES; type++)
{
- const std::string& wearable_name = LLWearable::typeToTypeName( (EWearableType) type );
+ const std::string& wearable_name = LLWearableDictionary::getTypeName((EWearableType)type);
apr_file_printf( file, "\n\t\t<!-- wearable: %s -->\n", wearable_name.c_str() );
- for( LLVisualParam* param = avatar->getFirstVisualParam(); param; param = avatar->getNextVisualParam() )
+ for (LLVisualParam* param = avatar->getFirstVisualParam(); param; param = avatar->getNextVisualParam())
{
LLViewerVisualParam* viewer_param = (LLViewerVisualParam*)param;
if( (viewer_param->getWearableType() == type) &&
(viewer_param->getGroup() == VISUAL_PARAM_GROUP_TWEAKABLE) )
{
- apr_file_printf( file, "\t\t<param id=\"%d\" name=\"%s\" value=\"%.3f\"/>\n",
- viewer_param->getID(), viewer_param->getName().c_str(), viewer_param->getWeight() );
+ apr_file_printf(file, "\t\t<param id=\"%d\" name=\"%s\" value=\"%.3f\"/>\n",
+ viewer_param->getID(), viewer_param->getName().c_str(), viewer_param->getWeight());
}
}
- for(U8 te = 0; te < TEX_NUM_INDICES; te++)
+ for (U8 te = 0; te < TEX_NUM_INDICES; te++)
{
- if( LLVOAvatar::getTEWearableType((ETextureIndex)te) == type )
+ if (LLVOAvatarDictionary::getTEWearableType((ETextureIndex)te) == type)
{
- LLViewerImage* te_image = avatar->getTEImage((ETextureIndex)te);
+ LLViewerTexture* te_image = avatar->getImage((ETextureIndex)te);
if( te_image )
{
std::string uuid_str;
@@ -8192,18 +6774,13 @@ void LLVOAvatar::dumpArchetypeXML( void* )
}
-U32 LLVOAvatar::getVisibilityRank()
-{
- return mVisibilityRank;
-}
-
void LLVOAvatar::setVisibilityRank(U32 rank)
{
if (mDrawable.isNull() || mDrawable->isDead())
- { //do nothing
+ {
+ // do nothing
return;
}
-
mVisibilityRank = rank;
}
@@ -8212,15 +6789,14 @@ S32 LLVOAvatar::getUnbakedPixelAreaRank()
{
S32 rank = 1;
for (std::vector<LLCharacter*>::iterator iter = LLCharacter::sInstances.begin();
- iter != LLCharacter::sInstances.end(); ++iter)
+ iter != LLCharacter::sInstances.end(); ++iter)
{
LLVOAvatar* inst = (LLVOAvatar*) *iter;
- if( inst == this )
+ if (inst == this)
{
return rank;
}
- else
- if( !inst->isDead() && !inst->isFullyBaked() )
+ else if (!inst->isDead() && !inst->isFullyBaked())
{
rank++;
}
@@ -8232,7 +6808,7 @@ S32 LLVOAvatar::getUnbakedPixelAreaRank()
struct CompareScreenAreaGreater
{
- bool operator()(const LLCharacter* const& lhs, const LLCharacter* const& rhs)
+ BOOL operator()(const LLCharacter* const& lhs, const LLCharacter* const& rhs)
{
return lhs->getPixelArea() > rhs->getPixelArea();
}
@@ -8246,7 +6822,7 @@ void LLVOAvatar::cullAvatarsByPixelArea()
// Update the avatars that have changed status
U32 rank = 0;
for (std::vector<LLCharacter*>::iterator iter = LLCharacter::sInstances.begin();
- iter != LLCharacter::sInstances.end(); ++iter)
+ iter != LLCharacter::sInstances.end(); ++iter)
{
LLVOAvatar* inst = (LLVOAvatar*) *iter;
BOOL culled;
@@ -8277,7 +6853,7 @@ void LLVOAvatar::cullAvatarsByPixelArea()
}
S32 grey_avatars = 0;
- if ( LLVOAvatar::areAllNearbyInstancesBaked(grey_avatars) )
+ if (LLVOAvatar::areAllNearbyInstancesBaked(grey_avatars))
{
LLVOAvatar::deleteCachedImages(false);
}
@@ -8299,144 +6875,6 @@ void LLVOAvatar::cullAvatarsByPixelArea()
}
}
-const LLUUID& LLVOAvatar::grabLocalTexture(ETextureIndex index)
-{
- if (canGrabLocalTexture(index))
- {
- return getTEImage( index )->getID();
- }
- return LLUUID::null;
-}
-
-BOOL LLVOAvatar::canGrabLocalTexture(ETextureIndex index)
-{
- // Check if the texture hasn't been baked yet.
- if (!isTextureDefined(index))
- {
- lldebugs << "getTEImage( " << (U32) index << " )->getID() == IMG_DEFAULT_AVATAR" << llendl;
- return FALSE;
- }
-
- if (gAgent.isGodlike() && !gAgent.getAdminOverride())
- return TRUE;
-
- // Check permissions of textures that show up in the
- // baked texture. We don't want people copying people's
- // work via baked textures.
- /* switch(index)
- case TEX_EYES_BAKED:
- textures.push_back(TEX_EYES_IRIS); */
- const LLVOAvatarDictionary::TextureDictionaryEntry *text_dict = LLVOAvatarDictionary::getInstance()->getTexture(index);
- if (!text_dict->mIsUsedByBakedTexture) return FALSE;
-
- const EBakedTextureIndex baked_index = text_dict->mBakedTextureIndex;
- const LLVOAvatarDictionary::BakedDictionaryEntry *baked_dict = LLVOAvatarDictionary::getInstance()->getBakedTexture(baked_index);
- for (texture_vec_t::const_iterator iter = baked_dict->mLocalTextures.begin();
- iter != baked_dict->mLocalTextures.end();
- iter++)
- {
- const ETextureIndex t_index = (*iter);
- lldebugs << "Checking index " << (U32) t_index << llendl;
- const LLUUID& texture_id = getTEImage( t_index )->getID();
- if (texture_id != IMG_DEFAULT_AVATAR)
- {
- // Search inventory for this texture.
- LLViewerInventoryCategory::cat_array_t cats;
- LLViewerInventoryItem::item_array_t items;
- LLAssetIDMatches asset_id_matches(texture_id);
- gInventory.collectDescendentsIf(LLUUID::null,
- cats,
- items,
- LLInventoryModel::INCLUDE_TRASH,
- asset_id_matches);
-
- BOOL can_grab = FALSE;
- lldebugs << "item count for asset " << texture_id << ": " << items.count() << llendl;
- if (items.count())
- {
- // search for full permissions version
- for (S32 i = 0; i < items.count(); i++)
- {
- LLInventoryItem* itemp = items[i];
- LLPermissions item_permissions = itemp->getPermissions();
- if ( item_permissions.allowOperationBy(
- PERM_MODIFY, gAgent.getID(), gAgent.getGroupID()) &&
- item_permissions.allowOperationBy(
- PERM_COPY, gAgent.getID(), gAgent.getGroupID()) &&
- item_permissions.allowOperationBy(
- PERM_TRANSFER, gAgent.getID(), gAgent.getGroupID()) )
- {
- can_grab = TRUE;
- break;
- }
- }
- }
- if (!can_grab) return FALSE;
- }
- }
-
- return TRUE;
-}
-
-void LLVOAvatar::dumpLocalTextures()
-{
- llinfos << "Local Textures:" << llendl;
-
- /* ETextureIndex baked_equiv[] = {
- TEX_UPPER_BAKED,
- if (isTextureDefined(baked_equiv[i])) */
- for (LLVOAvatarDictionary::texture_map_t::const_iterator iter = LLVOAvatarDictionary::getInstance()->getTextures().begin();
- iter != LLVOAvatarDictionary::getInstance()->getTextures().end();
- iter++)
- {
- const LLVOAvatarDictionary::TextureDictionaryEntry *text_dict = iter->second;
- if (!text_dict->mIsLocalTexture || !text_dict->mIsUsedByBakedTexture)
- continue;
-
- const EBakedTextureIndex baked_index = text_dict->mBakedTextureIndex;
- const ETextureIndex baked_equiv = LLVOAvatarDictionary::getInstance()->getBakedTexture(baked_index)->mTextureIndex;
-
- const std::string &name = text_dict->mName;
- const LocalTextureData &local_tex_data = mLocalTextureData[iter->first];
- if (isTextureDefined(baked_equiv))
- {
-#if LL_RELEASE_FOR_DOWNLOAD
- // End users don't get to trivially see avatar texture IDs, makes textures
- // easier to steal. JC
- llinfos << "LocTex " << name << ": Baked " << llendl;
-#else
- llinfos << "LocTex " << name << ": Baked " << getTEImage( baked_equiv )->getID() << llendl;
-#endif
- }
- else if (local_tex_data.mImage.notNull())
- {
- if( local_tex_data.mImage->getID() == IMG_DEFAULT_AVATAR )
- {
- llinfos << "LocTex " << name << ": None" << llendl;
- }
- else
- {
- const LLViewerImage* image = local_tex_data.mImage;
-
- llinfos << "LocTex " << name << ": "
- << "Discard " << image->getDiscardLevel() << ", "
- << "(" << image->getWidth() << ", " << image->getHeight() << ") "
-#if !LL_RELEASE_FOR_DOWNLOAD
- // End users don't get to trivially see avatar texture IDs,
- // makes textures easier to steal
- << image->getID() << " "
-#endif
- << "Priority: " << image->getDecodePriority()
- << llendl;
- }
- }
- else
- {
- llinfos << "LocTex " << name << ": No LLViewerImage" << llendl;
- }
- }
-}
-
void LLVOAvatar::startAppearanceAnimation(BOOL set_by_user, BOOL play_sound)
{
if(!mAppearanceAnimating)
@@ -8448,53 +6886,31 @@ void LLVOAvatar::startAppearanceAnimation(BOOL set_by_user, BOOL play_sound)
}
}
-
+// virtual
void LLVOAvatar::removeMissingBakedTextures()
{
- if (!mIsSelf) return;
-
- BOOL removed = FALSE;
- for (U32 i = 0; i < mBakedTextureData.size(); i++)
- {
- const S32 te = mBakedTextureData[i].mTextureIndex;
- if (getTEImage(te)->isMissingAsset())
- {
- setTEImage(te, gImageList.getImage(IMG_DEFAULT_AVATAR));
- removed = TRUE;
- }
- }
-
- if (removed)
- {
- for(U32 i = 0; i < mBakedTextureData.size(); i++)
- {
- invalidateComposite(mBakedTextureData[i].mTexLayerSet, FALSE);
- }
- updateMeshTextures();
- requestLayerSetUploads();
- }
}
-
//-----------------------------------------------------------------------------
// LLVOAvatarXmlInfo
//-----------------------------------------------------------------------------
-LLVOAvatarXmlInfo::LLVOAvatarXmlInfo()
+LLVOAvatar::LLVOAvatarXmlInfo::LLVOAvatarXmlInfo()
: mTexSkinColorInfo(0), mTexHairColorInfo(0), mTexEyeColorInfo(0)
{
}
-LLVOAvatarXmlInfo::~LLVOAvatarXmlInfo()
+LLVOAvatar::LLVOAvatarXmlInfo::~LLVOAvatarXmlInfo()
{
std::for_each(mMeshInfoList.begin(), mMeshInfoList.end(), DeletePointer());
std::for_each(mSkeletalDistortionInfoList.begin(), mSkeletalDistortionInfoList.end(), DeletePointer());
std::for_each(mAttachmentInfoList.begin(), mAttachmentInfoList.end(), DeletePointer());
- delete mTexSkinColorInfo;
- delete mTexHairColorInfo;
- delete mTexEyeColorInfo;
+ deleteAndClear(mTexSkinColorInfo);
+ deleteAndClear(mTexHairColorInfo);
+ deleteAndClear(mTexEyeColorInfo);
std::for_each(mLayerInfoList.begin(), mLayerInfoList.end(), DeletePointer());
- std::for_each(mDriverInfoList.begin(), mDriverInfoList.end(), DeletePointer());
+ std::for_each(mDriverInfoList.begin(), mDriverInfoList.end(), DeletePointer());
+ std::for_each(mMorphMaskInfoList.begin(), mMorphMaskInfoList.end(), DeletePointer());
}
//-----------------------------------------------------------------------------
@@ -8606,7 +7022,7 @@ BOOL LLVOAvatarSkeletonInfo::parseXml(LLXmlTreeNode* node)
//-----------------------------------------------------------------------------
// parseXmlSkeletonNode(): parses <skeleton> nodes from XML tree
//-----------------------------------------------------------------------------
-BOOL LLVOAvatarXmlInfo::parseXmlSkeletonNode(LLXmlTreeNode* root)
+BOOL LLVOAvatar::LLVOAvatarXmlInfo::parseXmlSkeletonNode(LLXmlTreeNode* root)
{
LLXmlTreeNode* node = root->getChildByName( "skeleton" );
if( !node )
@@ -8712,7 +7128,7 @@ BOOL LLVOAvatarXmlInfo::parseXmlSkeletonNode(LLXmlTreeNode* root)
//-----------------------------------------------------------------------------
// parseXmlMeshNodes(): parses <mesh> nodes from XML tree
//-----------------------------------------------------------------------------
-BOOL LLVOAvatarXmlInfo::parseXmlMeshNodes(LLXmlTreeNode* root)
+BOOL LLVOAvatar::LLVOAvatarXmlInfo::parseXmlMeshNodes(LLXmlTreeNode* root)
{
for (LLXmlTreeNode* node = root->getChildByName( "mesh" );
node;
@@ -8802,7 +7218,7 @@ BOOL LLVOAvatarXmlInfo::parseXmlMeshNodes(LLXmlTreeNode* root)
//-----------------------------------------------------------------------------
// parseXmlColorNodes(): parses <global_color> nodes from XML tree
//-----------------------------------------------------------------------------
-BOOL LLVOAvatarXmlInfo::parseXmlColorNodes(LLXmlTreeNode* root)
+BOOL LLVOAvatar::LLVOAvatarXmlInfo::parseXmlColorNodes(LLXmlTreeNode* root)
{
for (LLXmlTreeNode* color_node = root->getChildByName( "global_color" );
color_node;
@@ -8822,7 +7238,7 @@ BOOL LLVOAvatarXmlInfo::parseXmlColorNodes(LLXmlTreeNode* root)
mTexSkinColorInfo = new LLTexGlobalColorInfo;
if( !mTexSkinColorInfo->parseXml( color_node ) )
{
- delete mTexSkinColorInfo; mTexSkinColorInfo = 0;
+ deleteAndClear(mTexSkinColorInfo);
llwarns << "avatar file: mTexSkinColor->parseXml() failed" << llendl;
return FALSE;
}
@@ -8837,7 +7253,7 @@ BOOL LLVOAvatarXmlInfo::parseXmlColorNodes(LLXmlTreeNode* root)
mTexHairColorInfo = new LLTexGlobalColorInfo;
if( !mTexHairColorInfo->parseXml( color_node ) )
{
- delete mTexHairColorInfo; mTexHairColorInfo = 0;
+ deleteAndClear(mTexHairColorInfo);
llwarns << "avatar file: mTexHairColor->parseXml() failed" << llendl;
return FALSE;
}
@@ -8864,7 +7280,7 @@ BOOL LLVOAvatarXmlInfo::parseXmlColorNodes(LLXmlTreeNode* root)
//-----------------------------------------------------------------------------
// parseXmlLayerNodes(): parses <layer_set> nodes from XML tree
//-----------------------------------------------------------------------------
-BOOL LLVOAvatarXmlInfo::parseXmlLayerNodes(LLXmlTreeNode* root)
+BOOL LLVOAvatar::LLVOAvatarXmlInfo::parseXmlLayerNodes(LLXmlTreeNode* root)
{
for (LLXmlTreeNode* layer_node = root->getChildByName( "layer_set" );
layer_node;
@@ -8888,7 +7304,7 @@ BOOL LLVOAvatarXmlInfo::parseXmlLayerNodes(LLXmlTreeNode* root)
//-----------------------------------------------------------------------------
// parseXmlDriverNodes(): parses <driver_parameters> nodes from XML tree
//-----------------------------------------------------------------------------
-BOOL LLVOAvatarXmlInfo::parseXmlDriverNodes(LLXmlTreeNode* root)
+BOOL LLVOAvatar::LLVOAvatarXmlInfo::parseXmlDriverNodes(LLXmlTreeNode* root)
{
LLXmlTreeNode* driver = root->getChildByName( "driver_parameters" );
if( driver )
@@ -8916,36 +7332,60 @@ BOOL LLVOAvatarXmlInfo::parseXmlDriverNodes(LLXmlTreeNode* root)
return TRUE;
}
-// warning: order(N) not order(1)
-S32 LLVOAvatar::getAttachmentCount()
+//-----------------------------------------------------------------------------
+// parseXmlDriverNodes(): parses <driver_parameters> nodes from XML tree
+//-----------------------------------------------------------------------------
+BOOL LLVOAvatar::LLVOAvatarXmlInfo::parseXmlMorphNodes(LLXmlTreeNode* root)
{
- S32 count = mAttachmentPoints.size();
- return count;
-}
+ LLXmlTreeNode* masks = root->getChildByName( "morph_masks" );
+ if( !masks )
+ {
+ return FALSE;
+ }
-//virtual
-void LLVOAvatar::updateRegion(LLViewerRegion *regionp)
-{
- if (mIsSelf)
+ for (LLXmlTreeNode* grand_child = masks->getChildByName( "mask" );
+ grand_child;
+ grand_child = masks->getNextNamedChild())
{
- if (regionp->getHandle() != mLastRegionHandle)
+ LLVOAvatarMorphInfo* info = new LLVOAvatarMorphInfo();
+
+ static LLStdStringHandle name_string = LLXmlTree::addAttributeString("morph_name");
+ if (!grand_child->getFastAttributeString(name_string, info->mName))
{
- if (mLastRegionHandle != 0)
- {
- ++mRegionCrossingCount;
- F64 delta = (F64)mRegionCrossingTimer.getElapsedTimeF32();
- F64 avg = (mRegionCrossingCount == 1) ? 0 : LLViewerStats::getInstance()->getStat(LLViewerStats::ST_CROSSING_AVG);
- F64 delta_avg = (delta + avg*(mRegionCrossingCount-1)) / mRegionCrossingCount;
- LLViewerStats::getInstance()->setStat(LLViewerStats::ST_CROSSING_AVG, delta_avg);
+ llwarns << "No name supplied for morph mask." << llendl;
+ delete info;
+ continue;
+ }
- F64 max = (mRegionCrossingCount == 1) ? 0 : LLViewerStats::getInstance()->getStat(LLViewerStats::ST_CROSSING_MAX);
- max = llmax(delta, max);
- LLViewerStats::getInstance()->setStat(LLViewerStats::ST_CROSSING_MAX, max);
- }
- mLastRegionHandle = regionp->getHandle();
+ static LLStdStringHandle region_string = LLXmlTree::addAttributeString("body_region");
+ if (!grand_child->getFastAttributeString(region_string, info->mRegion))
+ {
+ llwarns << "No region supplied for morph mask." << llendl;
+ delete info;
+ continue;
+ }
+
+ static LLStdStringHandle layer_string = LLXmlTree::addAttributeString("layer");
+ if (!grand_child->getFastAttributeString(layer_string, info->mLayer))
+ {
+ llwarns << "No layer supplied for morph mask." << llendl;
+ delete info;
+ continue;
}
- mRegionCrossingTimer.reset();
+
+ // optional parameter. don't throw a warning if not present.
+ static LLStdStringHandle invert_string = LLXmlTree::addAttributeString("invert");
+ grand_child->getFastAttributeBOOL(invert_string, info->mInvert);
+
+ mMorphMaskInfoList.push_back(info);
}
+
+ return TRUE;
+}
+
+//virtual
+void LLVOAvatar::updateRegion(LLViewerRegion *regionp)
+{
}
std::string LLVOAvatar::getFullname() const
@@ -8964,21 +7404,6 @@ std::string LLVOAvatar::getFullname() const
return name;
}
-LLTexLayerSet* LLVOAvatar::getLayerSet(ETextureIndex index) const
-{
- /* switch(index)
- case TEX_HEAD_BAKED:
- case TEX_HEAD_BODYPAINT:
- return mHeadLayerSet; */
- const LLVOAvatarDictionary::TextureDictionaryEntry *text_dict = LLVOAvatarDictionary::getInstance()->getTexture(index);
- if (text_dict->mIsUsedByBakedTexture)
- {
- const EBakedTextureIndex baked_index = text_dict->mBakedTextureIndex;
- return mBakedTextureData[baked_index].mTexLayerSet;
- }
- return NULL;
-}
-
LLHost LLVOAvatar::getObjectHost() const
{
LLViewerRegion* region = getRegion();
@@ -9017,7 +7442,7 @@ BOOL LLVOAvatar::updateLOD()
if (facep->mVertexBuffer.isNull() ||
LLVertexBuffer::sEnableVBOs &&
((facep->mVertexBuffer->getUsage() == GL_STATIC_DRAW ? TRUE : FALSE) !=
- (facep->getPool()->getVertexShaderLevel() > 0 ? TRUE : FALSE)))
+ (facep->getPool()->getVertexShaderLevel() > 0 ? TRUE : FALSE)))
{
mDirtyMesh = TRUE;
}
@@ -9036,7 +7461,8 @@ BOOL LLVOAvatar::updateLOD()
}
U32 LLVOAvatar::getPartitionType() const
-{ //avatars merely exist as drawables in the bridge partition
+{
+ // Avatars merely exist as drawables in the bridge partition
return LLViewerRegion::PARTITION_BRIDGE;
}
@@ -9044,10 +7470,9 @@ U32 LLVOAvatar::getPartitionType() const
void LLVOAvatar::updateImpostors()
{
for (std::vector<LLCharacter*>::iterator iter = LLCharacter::sInstances.begin();
- iter != LLCharacter::sInstances.end(); ++iter)
+ iter != LLCharacter::sInstances.end(); ++iter)
{
LLVOAvatar* avatar = (LLVOAvatar*) *iter;
-
if (!avatar->isDead() && avatar->needsImpostorUpdate() && avatar->isVisible() && avatar->isImpostor())
{
gPipeline.generateImpostor(avatar);
@@ -9111,10 +7536,9 @@ void LLVOAvatar::idleUpdateRenderCost()
std::set<LLUUID> textures;
- attachment_map_t::const_iterator iter;
- for (iter = mAttachmentPoints.begin();
- iter != mAttachmentPoints.end();
- ++iter)
+ for (attachment_map_t::const_iterator iter = mAttachmentPoints.begin();
+ iter != mAttachmentPoints.end();
+ ++iter)
{
LLViewerJointAttachment* attachment = iter->second;
LLViewerObject* object = attachment->getObject();
@@ -9159,15 +7583,15 @@ const std::string LLVOAvatar::getBakedStatusForPrintout() const
{
std::string line;
- for (LLVOAvatarDictionary::texture_map_t::const_iterator iter = LLVOAvatarDictionary::getInstance()->getTextures().begin();
+ for (LLVOAvatarDictionary::Textures::const_iterator iter = LLVOAvatarDictionary::getInstance()->getTextures().begin();
iter != LLVOAvatarDictionary::getInstance()->getTextures().end();
iter++)
{
const ETextureIndex index = iter->first;
- const LLVOAvatarDictionary::TextureDictionaryEntry *text_dict = iter->second;
- if (text_dict->mIsBakedTexture)
+ const LLVOAvatarDictionary::TextureEntry *texture_dict = iter->second;
+ if (texture_dict->mIsBakedTexture)
{
- line += text_dict->mName;
+ line += texture_dict->mName;
if (isTextureDefined(index))
{
line += "_baked";
@@ -9224,7 +7648,7 @@ U32 calc_shame(LLVOVolume* volume, std::set<LLUUID> &textures)
{
LLFace* face = drawablep->getFace(i);
const LLTextureEntry* te = face->getTextureEntry();
- LLViewerImage* img = face->getTexture();
+ LLViewerTexture* img = face->getTexture();
textures.insert(img->getID());
@@ -9283,6 +7707,12 @@ U32 calc_shame(LLVOVolume* volume, std::set<LLUUID> &textures)
return shame;
}
+//virtual
+S32 LLVOAvatar::getTexImageSize() const
+{
+ return TEX_IMAGE_SIZE_OTHER;
+}
+
//-----------------------------------------------------------------------------
// Utility functions
//-----------------------------------------------------------------------------
@@ -9291,3 +7721,16 @@ F32 calc_bouncy_animation(F32 x)
{
return -(cosf(x * F_PI * 2.5f - F_PI_BY_TWO))*(0.4f + x * -0.1f) + x * 1.3f;
}
+
+//virtual
+BOOL LLVOAvatar::isTextureDefined(LLVOAvatarDefines::ETextureIndex te, U32 index ) const
+{
+ if (isIndexLocalTexture(te))
+ {
+ return FALSE;
+ }
+
+ return (getImage(te)->getID() != IMG_DEFAULT_AVATAR &&
+ getImage(te)->getID() != IMG_DEFAULT);
+}
+
diff --git a/indra/newview/llvoavatar.h b/indra/newview/llvoavatar.h
index f8b2c068ff..4dc70511ce 100644
--- a/indra/newview/llvoavatar.h
+++ b/indra/newview/llvoavatar.h
@@ -39,6 +39,7 @@
#include <string>
#include <vector>
+#include "imageids.h" // IMG_INVISIBLE
#include "llchat.h"
#include "lldrawpoolalpha.h"
#include "llviewerobject.h"
@@ -46,8 +47,10 @@
#include "llviewerjointmesh.h"
#include "llviewerjointattachment.h"
#include "llrendertarget.h"
-#include "llwearable.h"
#include "llvoavatardefines.h"
+#include "lltexglobalcolor.h"
+#include "lldriverparam.h"
+#include "material_codes.h" // LL_MCODE_END
extern const LLUUID ANIM_AGENT_BODY_NOISE;
extern const LLUUID ANIM_AGENT_BREATHE_ROT;
@@ -65,10 +68,8 @@ class LLVoiceVisualizer;
class LLHUDText;
class LLHUDEffectSpiral;
class LLTexGlobalColor;
-
class LLVOAvatarBoneInfo;
class LLVOAvatarSkeletonInfo;
-class LLVOAvatarXmlInfo;
//------------------------------------------------------------------------
// LLVOAvatar
@@ -77,414 +78,516 @@ class LLVOAvatar :
public LLViewerObject,
public LLCharacter
{
+public:
+ friend class LLVOAvatarSelf;
protected:
- virtual ~LLVOAvatar();
+ struct LLVOAvatarXmlInfo;
+ struct LLMaskedMorph;
+
+/********************************************************************************
+ ** **
+ ** INITIALIZATION
+ **/
public:
LLVOAvatar(const LLUUID &id, const LLPCode pcode, LLViewerRegion *regionp);
- /*virtual*/ void markDead();
- void startDefaultMotions();
-
- static void updateImpostors();
+ virtual void markDead();
+ static void initClass(); // Initialize data that's only init'd once per class.
+ static void cleanupClass(); // Cleanup data that's only init'd once per class.
+ virtual void initInstance(); // Called after construction to initialize the class.
+protected:
+ virtual ~LLVOAvatar();
+ BOOL loadSkeletonNode();
+ BOOL loadMeshNodes();
+ virtual BOOL loadLayersets();
- //--------------------------------------------------------------------
- // LLViewerObject interface
- //--------------------------------------------------------------------
-public:
- static void initClass(); // Initialize data that's only init'd once per class.
- static void cleanupClass(); // Cleanup data that's only init'd once per class.
- static BOOL parseSkeletonFile(const std::string& filename);
- virtual U32 processUpdateMessage(LLMessageSystem *mesgsys,
- void **user_data,
- U32 block_num,
- const EObjectUpdateType update_type,
- LLDataPacker *dp);
- /*virtual*/ BOOL idleUpdate(LLAgent &agent, LLWorld &world, const F64 &time);
- void idleUpdateVoiceVisualizer(bool voice_enabled);
- void idleUpdateMisc(bool detailed_update);
- void idleUpdateAppearanceAnimation();
- void idleUpdateLipSync(bool voice_enabled);
- void idleUpdateLoadingEffect();
- void idleUpdateWindEffect();
- void idleUpdateNameTag(const LLVector3& root_pos_last);
- void idleUpdateRenderCost();
- void idleUpdateTractorBeam();
- void idleUpdateBelowWater();
-
-public:
- virtual BOOL updateLOD();
- /*virtual*/ BOOL isActive() const; // Whether this object needs to do an idleUpdate.
-
- // Graphical stuff for objects - maybe broken out into render class later?
- U32 renderFootShadows();
- U32 renderImpostor(LLColor4U color = LLColor4U(255,255,255,255));
- U32 renderRigid();
- U32 renderSkinned(EAvatarRenderPass pass);
- U32 renderTransparent(BOOL first_pass);
- void renderCollisionVolumes();
-
- /*virtual*/ BOOL lineSegmentIntersect(const LLVector3& start, const LLVector3& end,
- S32 face = -1, // which face to check, -1 = ALL_SIDES
- BOOL pick_transparent = FALSE,
- S32* face_hit = NULL, // which face was hit
- LLVector3* intersection = NULL, // return the intersection point
- LLVector2* tex_coord = NULL, // return the texture coordinates of the intersection point
- LLVector3* normal = NULL, // return the surface normal at the intersection point
- LLVector3* bi_normal = NULL // return the surface bi-normal at the intersection point
- );
-
- /*virtual*/ void updateTextures(LLAgent &agent);
- // If setting a baked texture, need to request it from a non-local sim.
- /*virtual*/ S32 setTETexture(const U8 te, const LLUUID& uuid);
- /*virtual*/ void onShift(const LLVector3& shift_vector);
- virtual U32 getPartitionType() const;
-
- void updateVisibility();
- void updateAttachmentVisibility(U32 camera_mode);
- void clampAttachmentPositions();
- S32 getAttachmentCount(); // Warning: order(N) not order(1)
+/** Initialization
+ ** **
+ *******************************************************************************/
- // HUD functions
- BOOL hasHUDAttachment() const;
- LLBBox getHUDBBox() const;
- void rebuildHUD();
+/********************************************************************************
+ ** **
+ ** INHERITED
+ **/
- /*virtual*/ LLDrawable* createDrawable(LLPipeline *pipeline);
- /*virtual*/ BOOL updateGeometry(LLDrawable *drawable);
+ //--------------------------------------------------------------------
+ // LLViewerObject interface and related
+ //--------------------------------------------------------------------
+public:
+ virtual U32 processUpdateMessage(LLMessageSystem *mesgsys,
+ void **user_data,
+ U32 block_num,
+ const EObjectUpdateType update_type,
+ LLDataPacker *dp);
+ virtual BOOL idleUpdate(LLAgent &agent, LLWorld &world, const F64 &time);
+ virtual BOOL updateLOD();
+ BOOL updateJointLODs();
+ virtual BOOL isActive() const; // Whether this object needs to do an idleUpdate.
+ virtual void updateTextures(LLAgent &agent);
+ virtual S32 setTETexture(const U8 te, const LLUUID& uuid); // If setting a baked texture, need to request it from a non-local sim.
+ virtual void onShift(const LLVector3& shift_vector);
+ virtual U32 getPartitionType() const;
+ virtual const LLVector3 getRenderPosition() const;
+ virtual void updateDrawable(BOOL force_damped);
+ virtual LLDrawable* createDrawable(LLPipeline *pipeline);
+ virtual BOOL updateGeometry(LLDrawable *drawable);
+ virtual void setPixelAreaAndAngle(LLAgent &agent);
+ virtual void updateRegion(LLViewerRegion *regionp);
+ virtual void updateSpatialExtents(LLVector3& newMin, LLVector3 &newMax);
+ virtual void getSpatialExtents(LLVector3& newMin, LLVector3& newMax);
+ virtual BOOL lineSegmentIntersect(const LLVector3& start, const LLVector3& end,
+ S32 face = -1, // which face to check, -1 = ALL_SIDES
+ BOOL pick_transparent = FALSE,
+ S32* face_hit = NULL, // which face was hit
+ LLVector3* intersection = NULL, // return the intersection point
+ LLVector2* tex_coord = NULL, // return the texture coordinates of the intersection point
+ LLVector3* normal = NULL, // return the surface normal at the intersection point
+ LLVector3* bi_normal = NULL); // return the surface bi-normal at the intersection point
- /*virtual*/ void setPixelAreaAndAngle(LLAgent &agent);
- BOOL updateJointLODs();
+ //--------------------------------------------------------------------
+ // LLCharacter interface and related
+ //--------------------------------------------------------------------
+public:
+ virtual LLVector3 getCharacterPosition();
+ virtual LLQuaternion getCharacterRotation();
+ virtual LLVector3 getCharacterVelocity();
+ virtual LLVector3 getCharacterAngularVelocity();
+ virtual LLJoint* getCharacterJoint(U32 num);
+ virtual BOOL allocateCharacterJoints(U32 num);
+
+ virtual BOOL startMotion(const LLUUID& id, F32 time_offset = 0.f);
+ virtual BOOL stopMotion(const LLUUID& id, BOOL stop_immediate = FALSE);
+ virtual void stopMotionFromSource(const LLUUID& source_id);
+ virtual void requestStopMotion(LLMotion* motion);
+ LLMotion* findMotion(const LLUUID& id) const;
+ void startDefaultMotions();
+
+ virtual LLJoint* getJoint(const std::string &name);
+ virtual LLJoint* getRootJoint() { return &mRoot; }
+
+ virtual const char* getAnimationPrefix() { return "avatar"; }
+ virtual const LLUUID& getID();
+ virtual LLVector3 getVolumePos(S32 joint_index, LLVector3& volume_offset);
+ virtual LLJoint* findCollisionVolume(U32 volume_id);
+ virtual S32 getCollisionVolumeID(std::string &name);
+ virtual void addDebugText(const std::string& text);
+ virtual F32 getTimeDilation();
+ virtual void getGround(const LLVector3 &inPos, LLVector3 &outPos, LLVector3 &outNorm);
+ virtual F32 getPixelArea() const;
+ virtual LLPolyMesh* getHeadMesh();
+ virtual LLPolyMesh* getUpperBodyMesh();
+ virtual LLVector3d getPosGlobalFromAgent(const LLVector3 &position);
+ virtual LLVector3 getPosAgentFromGlobal(const LLVector3d &position);
+ virtual void updateVisualParams();
+
+
+/** Inherited
+ ** **
+ *******************************************************************************/
+
+/********************************************************************************
+ ** **
+ ** STATE
+ **/
- virtual void updateRegion(LLViewerRegion *regionp);
+public:
+ virtual bool isSelf() const { return false; } // True if this avatar is for this viewer's agent
+ bool isBuilt() const { return mIsBuilt; }
- virtual const LLVector3 getRenderPosition() const;
- virtual void updateDrawable(BOOL force_damped);
- void updateSpatialExtents(LLVector3& newMin, LLVector3 &newMax);
- void getSpatialExtents(LLVector3& newMin, LLVector3& newMax);
- BOOL isImpostor() const;
- BOOL needsImpostorUpdate() const;
- const LLVector3& getImpostorOffset() const;
- const LLVector2& getImpostorDim() const;
- void getImpostorValues(LLVector3* extents, LLVector3& angle, F32& distance) const;
- void cacheImpostorValues();
- void setImpostorDim(const LLVector2& dim);
-
- //--------------------------------------------------------------------
- // LLCharacter interface
- //--------------------------------------------------------------------
-public:
- virtual const char *getAnimationPrefix() { return "avatar"; }
- virtual LLJoint *getRootJoint() { return &mRoot; }
- virtual LLVector3 getCharacterPosition();
- virtual LLQuaternion getCharacterRotation();
- virtual LLVector3 getCharacterVelocity();
- virtual LLVector3 getCharacterAngularVelocity();
- virtual F32 getTimeDilation();
- virtual void getGround(const LLVector3 &inPos, LLVector3 &outPos, LLVector3 &outNorm);
- virtual BOOL allocateCharacterJoints( U32 num );
- virtual LLJoint *getCharacterJoint( U32 num );
- virtual void requestStopMotion( LLMotion* motion );
- virtual F32 getPixelArea() const;
- virtual LLPolyMesh* getHeadMesh();
- virtual LLPolyMesh* getUpperBodyMesh();
- virtual LLVector3d getPosGlobalFromAgent(const LLVector3 &position);
- virtual LLVector3 getPosAgentFromGlobal(const LLVector3d &position);
- virtual void updateVisualParams();
- virtual BOOL startMotion(const LLUUID& id, F32 time_offset = 0.f);
- virtual BOOL stopMotion(const LLUUID& id, BOOL stop_immediate = FALSE);
- virtual void stopMotionFromSource(const LLUUID& source_id);
- virtual LLVector3 getVolumePos(S32 joint_index, LLVector3& volume_offset);
- virtual LLJoint* findCollisionVolume(U32 volume_id);
- virtual S32 getCollisionVolumeID(std::string &name);
- virtual void addDebugText(const std::string& text);
- virtual const LLUUID& getID();
- virtual LLJoint *getJoint( const std::string &name );
-
- //--------------------------------------------------------------------
- // Other public functions
- //--------------------------------------------------------------------
-public:
- static void onCustomizeStart();
- static void onCustomizeEnd();
-
-public:
- static void dumpTotalLocalTextureByteCount();
-protected:
- void getLocalTextureByteCount( S32* gl_byte_count );
+private:
+ BOOL mSupportsAlphaLayers; // For backwards compatibility, TRUE for 1.23+ clients
+ //--------------------------------------------------------------------
+ // Updates
+ //--------------------------------------------------------------------
public:
- LLMotion* findMotion(const LLUUID& id);
-
- BOOL isVisible();
- BOOL isSelf() const { return mIsSelf; }
- BOOL isCulled() const { return mCulled; }
+ virtual BOOL updateCharacter(LLAgent &agent);
+ void idleUpdateVoiceVisualizer(bool voice_enabled);
+ void idleUpdateMisc(bool detailed_update);
+ void idleUpdateAppearanceAnimation();
+ void idleUpdateLipSync(bool voice_enabled);
+ void idleUpdateLoadingEffect();
+ void idleUpdateWindEffect();
+ void idleUpdateNameTag(const LLVector3& root_pos_last);
+ void idleUpdateRenderCost();
+ void idleUpdateTractorBeam();
+ void idleUpdateBelowWater();
+ //--------------------------------------------------------------------
+ // Static preferences (controlled by user settings/menus)
+ //--------------------------------------------------------------------
public:
- static void cullAvatarsByPixelArea();
- void setVisibilityRank(U32 rank);
- U32 getVisibilityRank(); // unused
-protected:
- S32 getUnbakedPixelAreaRank();
+ static S32 sRenderName;
+ static BOOL sRenderGroupTitles;
+ static S32 sMaxVisible;
+ static F32 sRenderDistance; //distance at which avatars will render (affected by control "RenderAvatarMaxVisible")
+ static BOOL sShowAnimationDebug; // show animation debug info
+ static BOOL sUseImpostors; //use impostors for far away avatars
+ static BOOL sShowFootPlane; // show foot collision plane reported by server
+ static BOOL sShowCollisionVolumes; // show skeletal collision volumes
+ static BOOL sVisibleInFirstPerson;
+ static S32 sNumLODChangesThisFrame;
+ static S32 sNumVisibleChatBubbles;
+ static BOOL sDebugInvisible;
+ static BOOL sShowAttachmentPoints;
+ static F32 sLODFactor; // user-settable LOD factor
+ static BOOL sJointDebug; // output total number of joints being touched for each avatar
+ static BOOL sDebugAvatarRotation;
+ //--------------------------------------------------------------------
+ // Region state
+ //--------------------------------------------------------------------
public:
- void dumpLocalTextures();
- const LLUUID& grabLocalTexture(LLVOAvatarDefines::ETextureIndex index);
- BOOL canGrabLocalTexture(LLVOAvatarDefines::ETextureIndex index);
- BOOL isTextureDefined(U8 te) const;
- BOOL isTextureVisible(U8 te) const;
- void startAppearanceAnimation(BOOL set_by_user, BOOL play_sound);
-
- void setCompositeUpdatesEnabled(BOOL b);
-
- void addChat(const LLChat& chat);
- void clearChat();
- void startTyping() { mTyping = TRUE; mTypingTimer.reset(); }
- void stopTyping() { mTyping = FALSE; }
+ LLHost getObjectHost() const;
- // Returns "FirstName LastName"
- std::string getFullname() const;
+ //--------------------------------------------------------------------
+ // Loading state
+ //--------------------------------------------------------------------
+public:
+ BOOL isFullyLoaded() const;
+ virtual BOOL updateIsFullyLoaded();
+ BOOL processFullyLoadedChange(bool loading);
+private:
+ BOOL mFullyLoaded;
+ BOOL mPreviousFullyLoaded;
+ BOOL mFullyLoadedInitialized;
+ S32 mFullyLoadedFrameCounter;
+ LLFrameTimer mFullyLoadedTimer;
- BOOL updateCharacter(LLAgent &agent);
- void updateHeadOffset();
+/** State
+ ** **
+ *******************************************************************************/
- F32 getPelvisToFoot() const { return mPelvisToFoot; }
+/********************************************************************************
+ ** **
+ ** SKELETON
+ **/
public:
- BOOL isAnyAnimationSignaled(const LLUUID *anim_array, const S32 num_anims);
- void processAnimationStateChanges();
+ void updateHeadOffset();
+ F32 getPelvisToFoot() const { return mPelvisToFoot; }
+ LLVector3 mHeadOffset; // current head position
+ LLViewerJoint mRoot;
protected:
- BOOL processSingleAnimationStateChange(const LLUUID &anim_id, BOOL start);
- void resetAnimations();
-
-public:
- void resolveHeightGlobal(const LLVector3d &inPos, LLVector3d &outPos, LLVector3 &outNorm);
- void resolveHeightAgent(const LLVector3 &inPos, LLVector3 &outPos, LLVector3 &outNorm);
- void resolveRayCollisionAgent(const LLVector3d start_pt, const LLVector3d end_pt, LLVector3d &out_pos, LLVector3 &out_norm);
+ static BOOL parseSkeletonFile(const std::string& filename);
+ void buildCharacter();
+ BOOL loadAvatar();
+ BOOL setupBone(const LLVOAvatarBoneInfo* info, LLViewerJoint* parent, S32 &current_volume_num, S32 &current_joint_num);
+ BOOL buildSkeleton(const LLVOAvatarSkeletonInfo *info);
+private:
+ BOOL mIsBuilt; // state of deferred character building
+ S32 mNumJoints;
+ LLViewerJoint* mSkeleton;
- void slamPosition(); // Slam position to transmitted position (for teleport);
+ //--------------------------------------------------------------------
+ // Pelvis height adjustment members.
+ //--------------------------------------------------------------------
+public:
+ LLVector3 mBodySize;
+ S32 mLastSkeletonSerialNum;
+private:
+ F32 mPelvisToFoot;
- // morph targets and such
- void processAvatarAppearance( LLMessageSystem* mesgsys );
- void onFirstTEMessageReceived();
- void updateSexDependentLayerSets( BOOL set_by_user );
- void dirtyMesh(); // Dirty the avatar mesh
- void hideSkirt();
+ //--------------------------------------------------------------------
+ // Cached pointers to well known joints
+ //--------------------------------------------------------------------
+public:
+ LLViewerJoint* mPelvisp;
+ LLViewerJoint* mTorsop;
+ LLViewerJoint* mChestp;
+ LLViewerJoint* mNeckp;
+ LLViewerJoint* mHeadp;
+ LLViewerJoint* mSkullp;
+ LLViewerJoint* mEyeLeftp;
+ LLViewerJoint* mEyeRightp;
+ LLViewerJoint* mHipLeftp;
+ LLViewerJoint* mHipRightp;
+ LLViewerJoint* mKneeLeftp;
+ LLViewerJoint* mKneeRightp;
+ LLViewerJoint* mAnkleLeftp;
+ LLViewerJoint* mAnkleRightp;
+ LLViewerJoint* mFootLeftp;
+ LLViewerJoint* mFootRightp;
+ LLViewerJoint* mWristLeftp;
+ LLViewerJoint* mWristRightp;
- virtual void setParent(LLViewerObject* parent);
- virtual void addChild(LLViewerObject *childp);
- virtual void removeChild(LLViewerObject *childp);
+ //--------------------------------------------------------------------
+ // XML parse tree
+ //--------------------------------------------------------------------
+private:
+ static LLXmlTree sXMLTree; // avatar config file
+ static LLXmlTree sSkeletonXMLTree; // avatar skeleton file
- LLViewerJointAttachment* getTargetAttachmentPoint(LLViewerObject* viewer_object);
- BOOL attachObject(LLViewerObject *viewer_object);
- BOOL detachObject(LLViewerObject *viewer_object);
- void lazyAttach();
-
- void sitOnObject(LLViewerObject *sit_object);
- void getOffObject();
-
- BOOL isWearingAttachment( const LLUUID& inv_item_id );
- LLViewerObject* getWornAttachment( const LLUUID& inv_item_id );
- const std::string getAttachedPointName(const LLUUID& inv_item_id);
-
- static LLVOAvatar* findAvatarFromAttachment( LLViewerObject* obj );
-
- void updateMeshTextures();
-
- //--------------------------------------------------------------------
- // texture compositing (used only by the LLTexLayer series of classes)
- //--------------------------------------------------------------------
-public:
- LLColor4 getGlobalColor( const std::string& color_name );
- BOOL isLocalTextureDataAvailable( LLTexLayerSet* layerset );
- BOOL isLocalTextureDataFinal( LLTexLayerSet* layerset );
- LLVOAvatarDefines::ETextureIndex getBakedTE( LLTexLayerSet* layerset );
- void updateComposites();
- void onGlobalColorChanged( LLTexGlobalColor* global_color, BOOL set_by_user );
- BOOL getLocalTextureRaw( LLVOAvatarDefines::ETextureIndex index, LLImageRaw* image_raw_pp );
- BOOL getLocalTextureGL( LLVOAvatarDefines::ETextureIndex index, LLImageGL** image_gl_pp );
- const LLUUID& getLocalTextureID( LLVOAvatarDefines::ETextureIndex index );
- LLGLuint getScratchTexName( LLGLenum format, U32* texture_bytes );
- BOOL bindScratchTexture( LLGLenum format );
- void invalidateComposite( LLTexLayerSet* layerset, BOOL set_by_user );
- void invalidateAll();
- void forceBakeAllTextures(bool slam_for_debug = false);
- static void processRebakeAvatarTextures(LLMessageSystem* msg, void**);
- void setNewBakedTexture( LLVOAvatarDefines::ETextureIndex i, const LLUUID& uuid );
- void setCachedBakedTexture( LLVOAvatarDefines::ETextureIndex i, const LLUUID& uuid );
- void releaseUnnecessaryTextures();
- void requestLayerSetUploads();
- bool hasPendingBakedUploads();
- static void onLocalTextureLoaded( BOOL succcess, LLViewerImage *src_vi, LLImageRaw* src, LLImageRaw* aux_src, S32 discard_level, BOOL final, void* userdata );
- static void dumpArchetypeXML( void* );
- static void dumpScratchTextureByteCount();
- static void dumpBakedStatus();
- static void deleteCachedImages(bool clearAll=true);
- static void destroyGL();
- static void restoreGL();
- static void resetImpostors();
- static enum EWearableType getTEWearableType(LLVOAvatarDefines::ETextureIndex te );
- static LLUUID getDefaultTEImageID(LLVOAvatarDefines::ETextureIndex te );
- static void onChangeSelfInvisible(BOOL newvalue);
- void setInvisible(BOOL newvalue);
- static LLColor4 getDummyColor();
+/** Skeleton
+ ** **
+ *******************************************************************************/
+/********************************************************************************
+ ** **
+ ** RENDERING
+ **/
+public:
+ U32 renderFootShadows();
+ U32 renderImpostor(LLColor4U color = LLColor4U(255,255,255,255));
+ U32 renderRigid();
+ U32 renderSkinned(EAvatarRenderPass pass);
+ U32 renderTransparent(BOOL first_pass);
+ void renderCollisionVolumes();
+ static void deleteCachedImages(bool clearAll=true);
+ static void destroyGL();
+ static void restoreGL();
+ BOOL mIsDummy; // for special views
+ S32 mSpecialRenderMode; // special lighting
+private:
+ BOOL mNeedsSkin; // avatar has been animated and verts have not been updated
+ S32 mUpdatePeriod;
+ S32 mNumInitFaces; //number of faces generated when creating the avatar drawable, does not inculde splitted faces due to long vertex buffer.
//--------------------------------------------------------------------
- // Clothing colors (conventience functions to access visual parameters
+ // Morph masks
//--------------------------------------------------------------------
public:
- void setClothesColor( LLVOAvatarDefines::ETextureIndex te, const LLColor4& new_color, BOOL set_by_user );
- LLColor4 getClothesColor( LLVOAvatarDefines::ETextureIndex te );
- BOOL teToColorParams( LLVOAvatarDefines::ETextureIndex te, const char* param_name[3] );
-
- BOOL isWearingWearableType( EWearableType type );
- void wearableUpdated( EWearableType type );
+ void invalidateMorphMasks(LLVOAvatarDefines::EBakedTextureIndex index = LLVOAvatarDefines::BAKED_NUM_INDICES);
+ BOOL morphMaskNeedsUpdate(LLVOAvatarDefines::EBakedTextureIndex index = LLVOAvatarDefines::BAKED_NUM_INDICES);
+ void addMaskedMorph(LLVOAvatarDefines::EBakedTextureIndex index, LLPolyMorphTarget* morph_target, BOOL invert, std::string layer);
+ void setMorphMasksValid(BOOL new_status, LLVOAvatarDefines::EBakedTextureIndex index = LLVOAvatarDefines::BAKED_NUM_INDICES);
+ void applyMorphMask(U8* tex_data, S32 width, S32 height, S32 num_components, LLVOAvatarDefines::EBakedTextureIndex index = LLVOAvatarDefines::BAKED_NUM_INDICES);
//--------------------------------------------------------------------
- // texture compositing
+ // Visibility
//--------------------------------------------------------------------
-public:
- void setLocTexTE( U8 te, LLViewerImage* image, BOOL set_by_user );
- void setupComposites();
-
+protected:
+ void updateVisibility();
+private:
+ U32 mVisibilityRank;
+ BOOL mVisible;
+
//--------------------------------------------------------------------
- // Handling partially loaded avatars (Ruth)
+ // Shadowing
//--------------------------------------------------------------------
public:
- BOOL isFullyLoaded();
- BOOL updateIsFullyLoaded();
+ void updateShadowFaces();
+ LLDrawable* mShadow;
private:
- BOOL mFullyLoaded;
- BOOL mPreviousFullyLoaded;
- BOOL mFullyLoadedInitialized;
- S32 mFullyLoadedFrameCounter;
- LLFrameTimer mFullyLoadedTimer;
+ LLFace* mShadow0Facep;
+ LLFace* mShadow1Facep;
+ LLPointer<LLViewerTexture> mShadowImagep;
//--------------------------------------------------------------------
- // Collision Volumes
+ // Impostors
//--------------------------------------------------------------------
public:
- S32 mNumCollisionVolumes;
- LLViewerJointCollisionVolume* mCollisionVolumes;
+ BOOL isImpostor() const;
+ BOOL needsImpostorUpdate() const;
+ const LLVector3& getImpostorOffset() const;
+ const LLVector2& getImpostorDim() const;
+ void getImpostorValues(LLVector3* extents, LLVector3& angle, F32& distance) const;
+ void cacheImpostorValues();
+ void setImpostorDim(const LLVector2& dim);
+ static void resetImpostors();
+ static void updateImpostors();
+ LLRenderTarget mImpostor;
+ BOOL mNeedsImpostorUpdate;
+private:
+ LLVector3 mImpostorOffset;
+ LLVector2 mImpostorDim;
+ BOOL mNeedsAnimUpdate;
+ LLVector3 mImpostorExtents[2];
+ LLVector3 mImpostorAngle;
+ F32 mImpostorDistance;
+ F32 mImpostorPixelArea;
+ LLVector3 mLastAnimExtents[2];
//--------------------------------------------------------------------
- // cached pointers to well known joints
+ // Wind rippling in clothes
//--------------------------------------------------------------------
public:
- LLViewerJoint* mPelvisp;
- LLViewerJoint* mTorsop;
- LLViewerJoint* mChestp;
- LLViewerJoint* mNeckp;
- LLViewerJoint* mHeadp;
- LLViewerJoint* mSkullp;
- LLViewerJoint* mEyeLeftp;
- LLViewerJoint* mEyeRightp;
- LLViewerJoint* mHipLeftp;
- LLViewerJoint* mHipRightp;
- LLViewerJoint* mKneeLeftp;
- LLViewerJoint* mKneeRightp;
- LLViewerJoint* mAnkleLeftp;
- LLViewerJoint* mAnkleRightp;
- LLViewerJoint* mFootLeftp;
- LLViewerJoint* mFootRightp;
- LLViewerJoint* mWristLeftp;
- LLViewerJoint* mWristRightp;
+ LLVector4 mWindVec;
+ F32 mRipplePhase;
+ BOOL mBelowWater;
+private:
+ F32 mWindFreq;
+ LLFrameTimer mRippleTimer;
+ F32 mRippleTimeLast;
+ LLVector3 mRippleAccel;
+ LLVector3 mLastVel;
//--------------------------------------------------------------------
- // impostor state
+ // Culling
//--------------------------------------------------------------------
public:
- LLRenderTarget mImpostor;
- BOOL mNeedsImpostorUpdate;
+ static void cullAvatarsByPixelArea();
+ BOOL isCulled() const { return mCulled; }
private:
- LLVector3 mImpostorOffset;
- LLVector2 mImpostorDim;
- BOOL mNeedsAnimUpdate;
- LLVector3 mImpostorExtents[2];
- LLVector3 mImpostorAngle;
- F32 mImpostorDistance;
- F32 mImpostorPixelArea;
- LLVector3 mLastAnimExtents[2];
+ BOOL mCulled;
//--------------------------------------------------------------------
- // Misc Render State
+ // Freeze counter
//--------------------------------------------------------------------
public:
- BOOL mIsDummy; // For special views
- S32 mSpecialRenderMode; // Special lighting
+ static void updateFreezeCounter(S32 counter = 0);
+private:
+ static S32 sFreezeCounter;
//--------------------------------------------------------------------
- // animation state data
+ // Constants
//--------------------------------------------------------------------
public:
- typedef std::map<LLUUID, S32>::iterator AnimIterator;
+ virtual LLViewerTexture::EBoostLevel getAvatarBoostLevel() const { return LLViewerTexture::BOOST_AVATAR; }
+ virtual LLViewerTexture::EBoostLevel getAvatarBakedBoostLevel() const { return LLViewerTexture::BOOST_AVATAR_BAKED; }
+ virtual S32 getTexImageSize() const;
+ virtual S32 getTexImageArea() const { return getTexImageSize()*getTexImageSize(); }
- std::map<LLUUID, S32> mSignaledAnimations; // requested state of Animation name/value
- std::map<LLUUID, S32> mPlayingAnimations; // current state of Animation name/value
+/** Rendering
+ ** **
+ *******************************************************************************/
- typedef std::multimap<LLUUID, LLUUID> AnimationSourceMap;
- typedef AnimationSourceMap::iterator AnimSourceIterator;
- AnimationSourceMap mAnimationSources; // object ids that triggered anim ids
+/********************************************************************************
+ ** **
+ ** TEXTURES
+ **/
//--------------------------------------------------------------------
- // Shadowing
+ // Loading status
//--------------------------------------------------------------------
public:
- void updateShadowFaces();
- LLDrawable* mShadow;
-private:
- LLFace* mShadow0Facep;
- LLFace* mShadow1Facep;
- LLPointer<LLViewerImage> mShadowImagep;
+ virtual BOOL isTextureDefined(LLVOAvatarDefines::ETextureIndex type, U32 index = 0) const;
+ BOOL isTextureVisible(LLVOAvatarDefines::ETextureIndex index) const;
+protected:
+ BOOL isFullyBaked();
+ static BOOL areAllNearbyInstancesBaked(S32& grey_avatars);
//--------------------------------------------------------------------
- // Keeps track of foot step state for generating sounds
+ // Baked textures
//--------------------------------------------------------------------
public:
- void setFootPlane(const LLVector4 &plane) { mFootPlane = plane; }
- LLVector4 mFootPlane;
+ void releaseComponentTextures(); // ! BACKWARDS COMPATIBILITY !
+protected:
+ static void onBakedTextureMasksLoaded(BOOL success, LLViewerFetchedTexture *src_vi, LLImageRaw* src, LLImageRaw* aux_src, S32 discard_level, BOOL final, void* userdata);
+ static void onInitialBakedTextureLoaded(BOOL success, LLViewerFetchedTexture *src_vi, LLImageRaw* src, LLImageRaw* aux_src, S32 discard_level, BOOL final, void* userdata);
+ static void onBakedTextureLoaded(BOOL success, LLViewerFetchedTexture *src_vi, LLImageRaw* src, LLImageRaw* aux_src, S32 discard_level, BOOL final, void* userdata);
+ virtual void removeMissingBakedTextures();
+ void useBakedTexture(const LLUUID& id);
+
+ typedef std::deque<LLMaskedMorph *> morph_list_t;
+ struct BakedTextureData
+ {
+ LLUUID mLastTextureIndex;
+ LLTexLayerSet* mTexLayerSet; // Only exists for self
+ bool mIsLoaded;
+ bool mIsUsed;
+ LLVOAvatarDefines::ETextureIndex mTextureIndex;
+ U32 mMaskTexName;
+ // Stores pointers to the joint meshes that this baked texture deals with
+ std::vector< LLViewerJointMesh * > mMeshes; // std::vector<LLViewerJointMesh> mJoints[i]->mMeshParts
+ morph_list_t mMaskedMorphs;
+ BOOL mMorphMasksValid;
+ };
+ typedef std::vector<BakedTextureData> bakedtexturedata_vec_t;
+ bakedtexturedata_vec_t mBakedTextureDatas;
+
+ //--------------------------------------------------------------------
+ // Local Textures
+ //--------------------------------------------------------------------
+protected:
+ virtual void setLocalTexture(LLVOAvatarDefines::ETextureIndex type, LLViewerTexture* tex, BOOL baked_version_exits, U32 index = 0);
+ virtual void addLocalTextureStats(LLVOAvatarDefines::ETextureIndex type, LLViewerFetchedTexture* imagep, F32 texel_area_ratio, BOOL rendered, BOOL covered_by_baked, U32 index = 0);
+
+ //--------------------------------------------------------------------
+ // Texture accessors
+ //--------------------------------------------------------------------
private:
- BOOL mWasOnGroundLeft;
- BOOL mWasOnGroundRight;
+ virtual void setImage(const U8 te, LLViewerTexture *imagep);
+ virtual LLViewerTexture* getImage(const U8 te) const;
+
+ virtual const LLTextureEntry* getTexEntry(const U8 te_num) const;
+ virtual void setTexEntry(const U8 index, const LLTextureEntry &te);
+
//--------------------------------------------------------------------
- // Pelvis height adjustment members.
+ // Layers
+ //--------------------------------------------------------------------
+protected:
+ void deleteLayerSetCaches(bool clearAll = true);
+ void addBakedTextureStats(LLViewerFetchedTexture* imagep, F32 pixel_area, F32 texel_area_ratio, S32 boost_level);
+
+ //--------------------------------------------------------------------
+ // Composites
//--------------------------------------------------------------------
public:
- LLVector3 mBodySize;
- S32 mLastSkeletonSerialNum;
-private:
- F32 mPelvisToFoot;
+ virtual void invalidateComposite(LLTexLayerSet* layerset, BOOL set_by_user);
+ virtual void invalidateAll();
+ virtual void setCompositeUpdatesEnabled(BOOL b);
//--------------------------------------------------------------------
- // Display the name, then optionally fade it out
+ // Static texture/mesh/baked dictionary
//--------------------------------------------------------------------
public:
- LLFrameTimer mChatTimer;
- LLPointer<LLHUDText> mNameText;
+ static BOOL isIndexLocalTexture(LLVOAvatarDefines::ETextureIndex i);
+ static BOOL isIndexBakedTexture(LLVOAvatarDefines::ETextureIndex i);
private:
- LLFrameTimer mTimeVisible;
- std::deque<LLChat> mChats;
- BOOL mTyping;
- LLFrameTimer mTypingTimer;
+ static const LLVOAvatarDefines::LLVOAvatarDictionary *getDictionary() { return sAvatarDictionary; }
+ static LLVOAvatarDefines::LLVOAvatarDictionary* sAvatarDictionary;
+ static LLVOAvatarSkeletonInfo* sAvatarSkeletonInfo;
+ static LLVOAvatarXmlInfo* sAvatarXmlInfo;
//--------------------------------------------------------------------
- // wind rippling in clothes
+ // Messaging
//--------------------------------------------------------------------
public:
- LLVector4 mWindVec;
- F32 mRipplePhase;
- BOOL mBelowWater;
+ void onFirstTEMessageReceived();
+private:
+ BOOL mFirstTEMessageReceived;
+ BOOL mFirstAppearanceMessageReceived;
+
+/** Textures
+ ** **
+ *******************************************************************************/
+
+/********************************************************************************
+ ** **
+ ** MESHES
+ **/
+
+public:
+ void updateMeshTextures();
+ void updateSexDependentLayerSets(BOOL set_by_user);
+ void dirtyMesh(); // Dirty the avatar mesh
+ void updateMeshData();
+protected:
+ void releaseMeshData();
+ /*virtual*/ void restoreMeshData();
private:
- F32 mWindFreq;
- LLFrameTimer mRippleTimer;
- F32 mRippleTimeLast;
- LLVector3 mRippleAccel;
- LLVector3 mLastVel;
+ BOOL mDirtyMesh;
+
+ typedef std::multimap<std::string, LLPolyMesh*> polymesh_map_t;
+ polymesh_map_t mMeshes;
+ std::vector<LLViewerJoint *> mMeshLOD;
//--------------------------------------------------------------------
- // appearance morphing
+ // Destroy invisible mesh
+ //--------------------------------------------------------------------
+protected:
+ BOOL mMeshValid;
+ LLFrameTimer mMeshInvisibleTime;
+
+/** Meshes
+ ** **
+ *******************************************************************************/
+
+/********************************************************************************
+ ** **
+ ** APPEARANCE
+ **/
+
+public:
+ void processAvatarAppearance(LLMessageSystem* mesgsys);
+ void hideSkirt();
+ void startAppearanceAnimation(BOOL set_by_user, BOOL play_sound);
+
+ //--------------------------------------------------------------------
+ // Appearance morphing
//--------------------------------------------------------------------
public:
BOOL mAppearanceAnimating;
@@ -494,269 +597,426 @@ private:
F32 mLastAppearanceBlendTime;
//--------------------------------------------------------------------
- // Attachments
+ // Clothing colors (convenience functions to access visual parameters)
//--------------------------------------------------------------------
public:
- // map of attachment points, by ID
- typedef std::map<S32, LLViewerJointAttachment*> attachment_map_t;
- attachment_map_t mAttachmentPoints;
- std::vector<LLPointer<LLViewerObject> > mPendingAttachment;
+ void setClothesColor(LLVOAvatarDefines::ETextureIndex te, const LLColor4& new_color, BOOL set_by_user);
+ LLColor4 getClothesColor(LLVOAvatarDefines::ETextureIndex te);
+ BOOL teToColorParams(LLVOAvatarDefines::ETextureIndex te, const char* param_name[3]);
//--------------------------------------------------------------------
- // static preferences that are controlled by user settings/menus
+ // Global colors
//--------------------------------------------------------------------
public:
- static S32 sRenderName;
- static BOOL sRenderGroupTitles;
- static S32 sMaxVisible;
- static F32 sRenderDistance; //distance at which avatars will render (affected by control "RenderAvatarMaxVisible")
- static BOOL sShowAnimationDebug; // show animation debug info
- static BOOL sUseImpostors; //use impostors for far away avatars
- static BOOL sShowFootPlane; // show foot collision plane reported by server
- static BOOL sVisibleInFirstPerson;
- static S32 sNumLODChangesThisFrame;
- static S32 sNumVisibleChatBubbles;
- static BOOL sDebugInvisible;
- static BOOL sShowAttachmentPoints;
- static F32 sLODFactor; // user-settable LOD factor
- static BOOL sJointDebug; // output total number of joints being touched for each avatar
- static BOOL sDebugAvatarRotation;
+ LLColor4 getGlobalColor(const std::string& color_name ) const;
+ void onGlobalColorChanged(const LLTexGlobalColor* global_color, BOOL set_by_user);
+private:
+ LLTexGlobalColor* mTexSkinColor;
+ LLTexGlobalColor* mTexHairColor;
+ LLTexGlobalColor* mTexEyeColor;
+
+ //--------------------------------------------------------------------
+ // Visibility
+ //--------------------------------------------------------------------
+public:
+ BOOL isVisible() const;
+ void setVisibilityRank(U32 rank);
+ U32 getVisibilityRank() const { return mVisibilityRank; } // unused
+ static S32 sNumVisibleAvatars; // Number of instances of this class
+ static LLColor4 getDummyColor();
+/** Appearance
+ ** **
+ *******************************************************************************/
+
+/********************************************************************************
+ ** **
+ ** WEARABLES
+ **/
- static S32 sNumVisibleAvatars; // Number of instances of this class
+public:
+ BOOL isWearingWearableType(EWearableType type ) const;
//--------------------------------------------------------------------
- // Miscellaneous public variables.
+ // Attachments
//--------------------------------------------------------------------
public:
- BOOL mInAir;
- LLFrameTimer mTimeInAir;
- LLVector3 mHeadOffset; // current head position
- LLViewerJoint mRoot; // avatar skeleton
- BOOL mIsSitting; // sitting state
+ void clampAttachmentPositions();
+ virtual LLViewerJointAttachment* attachObject(LLViewerObject *viewer_object);
+ BOOL detachObject(LLViewerObject *viewer_object);
+ static LLVOAvatar* findAvatarFromAttachment(LLViewerObject* obj);
+protected:
+ LLViewerJointAttachment* getTargetAttachmentPoint(LLViewerObject* viewer_object);
+ void lazyAttach();
//--------------------------------------------------------------------
- // Private member variables.
+ // Map of attachment points, by ID
+ //--------------------------------------------------------------------
+public:
+ S32 getAttachmentCount(); // Warning: order(N) not order(1) // currently used only by -self
+ typedef std::map<S32, LLViewerJointAttachment*> attachment_map_t;
+ attachment_map_t mAttachmentPoints;
+ std::vector<LLPointer<LLViewerObject> > mPendingAttachment;
+
+ //--------------------------------------------------------------------
+ // HUD functions
+ //--------------------------------------------------------------------
+public:
+ BOOL hasHUDAttachment() const;
+ LLBBox getHUDBBox() const;
+ void rebuildHUD();
+ void resetHUDAttachments();
+
+/** Wearables
+ ** **
+ *******************************************************************************/
+
+/********************************************************************************
+ ** **
+ ** ACTIONS
+ **/
+
//--------------------------------------------------------------------
+ // Animations
+ //--------------------------------------------------------------------
+public:
+ BOOL isAnyAnimationSignaled(const LLUUID *anim_array, const S32 num_anims) const;
+ void processAnimationStateChanges();
+protected:
+ BOOL processSingleAnimationStateChange(const LLUUID &anim_id, BOOL start);
+ void resetAnimations();
private:
- BOOL mIsSelf; // True if this avatar is for this viewer's agent
+ LLTimer mAnimTimer;
+ F32 mTimeLast;
- LLViewerJoint *mScreenp; // special purpose joint for HUD attachments
- BOOL mIsBuilt; // state of deferred character building
- F32 mSpeedAccum; // measures speed (for diagnostics mostly).
+ //--------------------------------------------------------------------
+ // Animation state data
+ //--------------------------------------------------------------------
+public:
+ typedef std::map<LLUUID, S32>::iterator AnimIterator;
+ std::map<LLUUID, S32> mSignaledAnimations; // requested state of Animation name/value
+ std::map<LLUUID, S32> mPlayingAnimations; // current state of Animation name/value
-
- // LLFrameTimer mUpdateLODTimer; // controls frequency of LOD change calculations
- BOOL mDirtyMesh;
- BOOL mTurning; // controls hysteresis on avatar rotation
- F32 mSpeed; // misc. animation repeated state
+ typedef std::multimap<LLUUID, LLUUID> AnimationSourceMap;
+ typedef AnimationSourceMap::iterator AnimSourceIterator;
+ AnimationSourceMap mAnimationSources; // object ids that triggered anim ids
- // Keep track of the material being stepped on
- BOOL mStepOnLand;
- U8 mStepMaterial;
- LLVector3 mStepObjectVelocity;
+ //--------------------------------------------------------------------
+ // Chat
+ //--------------------------------------------------------------------
+public:
+ void addChat(const LLChat& chat);
+ void clearChat();
+ void startTyping() { mTyping = TRUE; mTypingTimer.reset(); }
+ void stopTyping() { mTyping = FALSE; }
+private:
+ BOOL mVisibleChat;
- // Destroy mesh data after being invisible for a while
- BOOL mMeshValid;
- BOOL mVisible;
- LLFrameTimer mMeshInvisibleTime;
+ //--------------------------------------------------------------------
+ // Lip synch morphs
+ //--------------------------------------------------------------------
+private:
+ bool mLipSyncActive; // we're morphing for lip sync
+ LLVisualParam* mOohMorph; // cached pointers morphs for lip sync
+ LLVisualParam* mAahMorph; // cached pointers morphs for lip sync
- // Lip synch morph stuff
- bool mLipSyncActive; // we're morphing for lip sync
- LLVisualParam* mOohMorph; // cached pointers morphs for lip sync
- LLVisualParam* mAahMorph; // cached pointers morphs for lip sync
+ //--------------------------------------------------------------------
+ // Flight
+ //--------------------------------------------------------------------
+public:
+ BOOL mInAir;
+ LLFrameTimer mTimeInAir;
- // Skeleton for skinned avatar
- S32 mNumJoints;
- LLViewerJoint* mSkeleton;
+/** Actions
+ ** **
+ *******************************************************************************/
- // Scratch textures used for compositing
- static LLMap< LLGLenum, LLGLuint*> sScratchTexNames;
- static LLMap< LLGLenum, F32*> sScratchTexLastBindTime;
- static S32 sScratchTexBytes;
+/********************************************************************************
+ ** **
+ ** PHYSICS
+ **/
- // Global table of sound ids per material, and the ground
- const static LLUUID sStepSounds[LL_MCODE_END];
- const static LLUUID sStepSoundOnLand;
+private:
+ F32 mSpeedAccum; // measures speed (for diagnostics mostly).
+ BOOL mTurning; // controls hysteresis on avatar rotation
+ F32 mSpeed; // misc. animation repeated state
- // Xml parse tree of avatar config file
- static LLXmlTree sXMLTree;
- // Xml parse tree of avatar skeleton file
- static LLXmlTree sSkeletonXMLTree;
+ //--------------------------------------------------------------------
+ // Collision volumes
+ //--------------------------------------------------------------------
+public:
+ S32 mNumCollisionVolumes;
+ LLViewerJointCollisionVolume* mCollisionVolumes;
+protected:
+ BOOL allocateCollisionVolumes(U32 num);
- // Voice Visualizer is responsible for detecting the user's voice signal, and when the
- // user speaks, it puts a voice symbol over the avatar's head, and triggering gesticulations
- LLVoiceVisualizer* mVoiceVisualizer;
- int mCurrentGesticulationLevel;
-
- // Animation timer
- LLTimer mAnimTimer;
- F32 mTimeLast;
-
- LLPointer<LLHUDEffectSpiral> mBeam;
- LLFrameTimer mBeamTimer;
-
- F32 mAdjustedPixelArea;
-
- LLWString mNameString;
- std::string mTitle;
- BOOL mNameAway;
- BOOL mNameBusy;
- BOOL mNameMute;
- BOOL mNameAppearance;
- BOOL mVisibleChat;
- BOOL mRenderGroupTitles;
-
- std::string mDebugText;
- U64 mLastRegionHandle;
- LLFrameTimer mRegionCrossingTimer;
- S32 mRegionCrossingCount;
-
//--------------------------------------------------------------------
- // local textures for compositing.
+ // Dimensions
//--------------------------------------------------------------------
-private:
- LLUUID mSavedTE[ LLVOAvatarDefines::TEX_NUM_INDICES ];
- BOOL mFirstTEMessageReceived;
- BOOL mFirstAppearanceMessageReceived;
- BOOL mHasBakedHair;
-
- BOOL mCulled;
- U32 mVisibilityRank;
- F32 mMinPixelArea; // debug
- F32 mMaxPixelArea; // debug
- BOOL mHasGrey; // debug
-
+public:
+ void resolveHeightGlobal(const LLVector3d &inPos, LLVector3d &outPos, LLVector3 &outNorm);
+ void resolveHeightAgent(const LLVector3 &inPos, LLVector3 &outPos, LLVector3 &outNorm);
+ void resolveRayCollisionAgent(const LLVector3d start_pt, const LLVector3d end_pt, LLVector3d &out_pos, LLVector3 &out_norm);
+ void slamPosition(); // Slam position to transmitted position (for teleport);
+protected:
+ void computeBodySize();
+
//--------------------------------------------------------------------
- // Global Colors
+ // Material being stepped on
//--------------------------------------------------------------------
private:
- LLTexGlobalColor* mTexSkinColor;
- LLTexGlobalColor* mTexHairColor;
- LLTexGlobalColor* mTexEyeColor;
+ BOOL mStepOnLand;
+ U8 mStepMaterial;
+ LLVector3 mStepObjectVelocity;
- BOOL mNeedsSkin; //if TRUE, avatar has been animated and verts have not been updated
- S32 mUpdatePeriod;
+/** Physics
+ ** **
+ *******************************************************************************/
+
+/********************************************************************************
+ ** **
+ ** HIERARCHY
+ **/
+
+public:
+ virtual BOOL setParent(LLViewerObject* parent);
+ virtual void addChild(LLViewerObject *childp);
+ virtual void removeChild(LLViewerObject *childp);
//--------------------------------------------------------------------
- // Internal functions
+ // Sitting
//--------------------------------------------------------------------
+public:
+ void sitDown(BOOL bSitting);
+ BOOL isSitting(){return mIsSitting;}
+ void sitOnObject(LLViewerObject *sit_object);
+ void getOffObject();
+
+private:
+ // set this property only with LLVOAvatar::sitDown method
+ BOOL mIsSitting;
+
+/** Hierarchy
+ ** **
+ *******************************************************************************/
+
+/********************************************************************************
+ ** **
+ ** NAME
+ **/
+
+public:
+ std::string getFullname() const; // Returns "FirstName LastName"
protected:
- void buildCharacter();
- void releaseMeshData();
- void restoreMeshData();
- void updateMeshData();
- void computeBodySize();
- const LLUUID& getStepSound() const;
- BOOL needsRenderBeam();
+ static void getAnimLabels(LLDynamicArray<std::string>* labels);
+ static void getAnimNames(LLDynamicArray<std::string>* names);
+private:
+ LLWString mNameString;
+ std::string mTitle;
+ BOOL mNameAway;
+ BOOL mNameBusy;
+ BOOL mNameMute;
+ BOOL mNameAppearance;
+ BOOL mRenderGroupTitles;
- BOOL allocateCollisionVolumes( U32 num );
- void resetHUDAttachments();
- static void getAnimLabels( LLDynamicArray<std::string>* labels );
- static void getAnimNames( LLDynamicArray<std::string>* names );
+ //--------------------------------------------------------------------
+ // Display the name (then optionally fade it out)
+ //--------------------------------------------------------------------
+public:
+ LLFrameTimer mChatTimer;
+ LLPointer<LLHUDText> mNameText;
+private:
+ LLFrameTimer mTimeVisible;
+ std::deque<LLChat> mChats;
+ BOOL mTyping;
+ LLFrameTimer mTypingTimer;
+
+/** Name
+ ** **
+ *******************************************************************************/
+
+/********************************************************************************
+ ** **
+ ** SOUNDS
+ **/
//--------------------------------------------------------------------
- // Textures and Layers
+ // Voice visualizer
+ //--------------------------------------------------------------------
+public:
+ // Responsible for detecting the user's voice signal (and when the
+ // user speaks, it puts a voice symbol over the avatar's head) and gesticulations
+ LLVoiceVisualizer* mVoiceVisualizer;
+ int mCurrentGesticulationLevel;
+
+ //--------------------------------------------------------------------
+ // Step sound
//--------------------------------------------------------------------
protected:
- BOOL loadSkeletonNode();
- BOOL loadMeshNodes();
- BOOL isFullyBaked();
- void deleteLayerSetCaches(bool clearAll = true);
- static BOOL areAllNearbyInstancesBaked(S32& grey_avatars);
- static void onBakedTextureMasksLoaded(BOOL success, LLViewerImage *src_vi, LLImageRaw* src, LLImageRaw* aux_src, S32 discard_level, BOOL final, void* userdata);
- void setLocalTexture(LLVOAvatarDefines::ETextureIndex i, LLViewerImage* tex, BOOL baked_version_exits);
- void requestLayerSetUpdate(LLVOAvatarDefines::ETextureIndex i);
- void addLocalTextureStats(LLVOAvatarDefines::ETextureIndex i, LLViewerImage* imagep, F32 texel_area_ratio, BOOL rendered, BOOL covered_by_baked);
- void addBakedTextureStats( LLViewerImage* imagep, F32 pixel_area, F32 texel_area_ratio, S32 boost_level);
- static void onInitialBakedTextureLoaded( BOOL success, LLViewerImage *src_vi, LLImageRaw* src, LLImageRaw* aux_src, S32 discard_level, BOOL final, void* userdata );
- static void onBakedTextureLoaded(BOOL success, LLViewerImage *src_vi, LLImageRaw* src, LLImageRaw* aux_src, S32 discard_level, BOOL final, void* userdata);
- void useBakedTexture(const LLUUID& id);
- void dumpAvatarTEs(const std::string& context);
- void removeMissingBakedTextures();
- LLTexLayerSet* getLayerSet(LLVOAvatarDefines::ETextureIndex index) const;
- LLHost getObjectHost() const;
- S32 getLocalDiscardLevel(LLVOAvatarDefines::ETextureIndex index);
+ const LLUUID& getStepSound() const;
+private:
+ // Global table of sound ids per material, and the ground
+ const static LLUUID sStepSounds[LL_MCODE_END];
+ const static LLUUID sStepSoundOnLand;
+
+ //--------------------------------------------------------------------
+ // Foot step state (for generating sounds)
+ //--------------------------------------------------------------------
public:
- static void updateFreezeCounter(S32 counter = 0 );
+ void setFootPlane(const LLVector4 &plane) { mFootPlane = plane; }
+ LLVector4 mFootPlane;
private:
- static S32 sFreezeCounter;
+ BOOL mWasOnGroundLeft;
+ BOOL mWasOnGroundRight;
+
+/** Sounds
+ ** **
+ *******************************************************************************/
+
+/********************************************************************************
+ ** **
+ ** DIAGNOSTICS
+ **/
- //-----------------------------------------------------------------------------------------------
- // Avatar skeleton setup.
- //-----------------------------------------------------------------------------------------------
-private:
- BOOL loadAvatar();
- BOOL setupBone(const LLVOAvatarBoneInfo* info, LLViewerJoint* parent, S32 &current_volume_num, S32 &current_joint_num);
- BOOL buildSkeleton(const LLVOAvatarSkeletonInfo *info);
-
- //-----------------------------------------------------------------------------------------------
- // Per-avatar information about texture data.
- // To-do: Move this to private implementation class
- //-----------------------------------------------------------------------------------------------
+public:
+ static void dumpArchetypeXML(void*);
+ static void dumpBakedStatus();
+ const std::string getBakedStatusForPrintout() const;
+ void dumpAvatarTEs(const std::string& context);
+
+ static F32 sUnbakedTime; // Total seconds with >=1 unbaked avatars
+ static F32 sUnbakedUpdateTime; // Last time stats were updated (to prevent multiple updates per frame)
+ static F32 sGreyTime; // Total seconds with >=1 grey avatars
+ static F32 sGreyUpdateTime; // Last time stats were updated (to prevent multiple updates per frame)
+protected:
+ S32 getUnbakedPixelAreaRank();
+ BOOL mHasGrey;
private:
- struct BakedTextureData
+ F32 mMinPixelArea;
+ F32 mMaxPixelArea;
+ F32 mAdjustedPixelArea;
+ std::string mDebugText;
+
+/** Diagnostics
+ ** **
+ *******************************************************************************/
+
+/********************************************************************************
+ ** **
+ ** SUPPORT CLASSES
+ **/
+
+protected: // Shared with LLVOAvatarSelf
+
+ struct LLVOAvatarXmlInfo
{
- LLUUID mLastTextureIndex;
- LLTexLayerSet* mTexLayerSet;
- bool mIsLoaded;
- bool mIsUsed;
- LLVOAvatarDefines::ETextureIndex mTextureIndex;
- U32 mMaskTexName;
- // Stores pointers to the joint meshes that this baked texture deals with
- std::vector< LLViewerJointMesh * > mMeshes; // std::vector<LLViewerJointMesh> mJoints[i]->mMeshParts
+ LLVOAvatarXmlInfo();
+ ~LLVOAvatarXmlInfo();
+
+ BOOL parseXmlSkeletonNode(LLXmlTreeNode* root);
+ BOOL parseXmlMeshNodes(LLXmlTreeNode* root);
+ BOOL parseXmlColorNodes(LLXmlTreeNode* root);
+ BOOL parseXmlLayerNodes(LLXmlTreeNode* root);
+ BOOL parseXmlDriverNodes(LLXmlTreeNode* root);
+ BOOL parseXmlMorphNodes(LLXmlTreeNode* root);
+
+ struct LLVOAvatarMeshInfo
+ {
+ typedef std::pair<LLPolyMorphTargetInfo*,BOOL> morph_info_pair_t;
+ typedef std::vector<morph_info_pair_t> morph_info_list_t;
+
+ LLVOAvatarMeshInfo() : mLOD(0), mMinPixelArea(.1f) {}
+ ~LLVOAvatarMeshInfo()
+ {
+ morph_info_list_t::iterator iter;
+ for (iter = mPolyMorphTargetInfoList.begin(); iter != mPolyMorphTargetInfoList.end(); iter++)
+ {
+ delete iter->first;
+ }
+ mPolyMorphTargetInfoList.clear();
+ }
+
+ std::string mType;
+ S32 mLOD;
+ std::string mMeshFileName;
+ std::string mReferenceMeshName;
+ F32 mMinPixelArea;
+ morph_info_list_t mPolyMorphTargetInfoList;
+ };
+ typedef std::vector<LLVOAvatarMeshInfo*> mesh_info_list_t;
+ mesh_info_list_t mMeshInfoList;
+
+ typedef std::vector<LLPolySkeletalDistortionInfo*> skeletal_distortion_info_list_t;
+ skeletal_distortion_info_list_t mSkeletalDistortionInfoList;
+
+ struct LLVOAvatarAttachmentInfo
+ {
+ LLVOAvatarAttachmentInfo()
+ : mGroup(-1), mAttachmentID(-1), mPieMenuSlice(-1), mVisibleFirstPerson(FALSE),
+ mIsHUDAttachment(FALSE), mHasPosition(FALSE), mHasRotation(FALSE) {}
+ std::string mName;
+ std::string mJointName;
+ LLVector3 mPosition;
+ LLVector3 mRotationEuler;
+ S32 mGroup;
+ S32 mAttachmentID;
+ S32 mPieMenuSlice;
+ BOOL mVisibleFirstPerson;
+ BOOL mIsHUDAttachment;
+ BOOL mHasPosition;
+ BOOL mHasRotation;
+ };
+ typedef std::vector<LLVOAvatarAttachmentInfo*> attachment_info_list_t;
+ attachment_info_list_t mAttachmentInfoList;
+
+ LLTexGlobalColorInfo *mTexSkinColorInfo;
+ LLTexGlobalColorInfo *mTexHairColorInfo;
+ LLTexGlobalColorInfo *mTexEyeColorInfo;
+
+ typedef std::vector<LLTexLayerSetInfo*> layer_info_list_t;
+ layer_info_list_t mLayerInfoList;
+
+ typedef std::vector<LLDriverParamInfo*> driver_info_list_t;
+ driver_info_list_t mDriverInfoList;
+
+ struct LLVOAvatarMorphInfo
+ {
+ LLVOAvatarMorphInfo()
+ : mInvert(FALSE) {}
+ std::string mName;
+ std::string mRegion;
+ std::string mLayer;
+ BOOL mInvert;
+ };
+
+ typedef std::vector<LLVOAvatarMorphInfo*> morph_info_list_t;
+ morph_info_list_t mMorphMaskInfoList;
};
- typedef std::vector<BakedTextureData> bakedtexturedata_vec_t;
- bakedtexturedata_vec_t mBakedTextureData;
- struct LocalTextureData
+ struct LLMaskedMorph
{
- LocalTextureData() : mIsBakedReady(FALSE), mDiscard(MAX_DISCARD_LEVEL+1), mImage(NULL)
- {}
- LLPointer<LLViewerImage> mImage;
- BOOL mIsBakedReady;
- S32 mDiscard;
+ LLMaskedMorph(LLPolyMorphTarget *morph_target, BOOL invert, std::string layer) :
+ mMorphTarget(morph_target),
+ mInvert(invert),
+ mLayer(layer)
+ {
+ morph_target->addPendingMorphMask();
+ }
+
+ LLPolyMorphTarget *mMorphTarget;
+ BOOL mInvert;
+ std::string mLayer;
};
- typedef std::map<LLVOAvatarDefines::ETextureIndex, LocalTextureData> localtexture_map_t;
- localtexture_map_t mLocalTextureData;
- typedef std::multimap<std::string, LLPolyMesh*> polymesh_map_t;
- polymesh_map_t mMeshes;
- std::vector<LLViewerJoint *> mMeshLOD;
- S32 mNumInitFaces ; //number of faces generated when creating the avatar drawable, does not inculde splitted faces due to long vertex buffer.
+/** Support classes
+ ** **
+ *******************************************************************************/
- //-----------------------------------------------------------------------------------------------
- // Static texture/mesh/baked dictionary for avatars
- //-----------------------------------------------------------------------------------------------
-public:
- static BOOL isIndexLocalTexture(LLVOAvatarDefines::ETextureIndex i);
- static BOOL isIndexBakedTexture(LLVOAvatarDefines::ETextureIndex i);
-private:
- static const LLVOAvatarDefines::LLVOAvatarDictionary *getDictionary() { return sAvatarDictionary; }
- static LLVOAvatarDefines::LLVOAvatarDictionary *sAvatarDictionary;
- static LLVOAvatarSkeletonInfo* sAvatarSkeletonInfo;
- static LLVOAvatarXmlInfo* sAvatarXmlInfo;
+}; // LLVOAvatar
- //-----------------------------------------------------------------------------------------------
- // Diagnostics
- //-----------------------------------------------------------------------------------------------
-public:
- static F32 sUnbakedTime; // Total seconds with >=1 unbaked avatars
- static F32 sUnbakedUpdateTime; // Last time stats were updated (to prevent multiple updates per frame)
- static F32 sGreyTime; // Total seconds with >=1 grey avatars
- static F32 sGreyUpdateTime; // Last time stats were updated (to prevent multiple updates per frame)
-
- const std::string getBakedStatusForPrintout() const;
-};
-
-//-----------------------------------------------------------------------------------------------
+//------------------------------------------------------------------------
// Inlines
-//-----------------------------------------------------------------------------------------------
-inline BOOL LLVOAvatar::isTextureDefined(U8 te) const
-{
- return (getTEImage(te)->getID() != IMG_DEFAULT_AVATAR && getTEImage(te)->getID() != IMG_DEFAULT);
-}
-
-inline BOOL LLVOAvatar::isTextureVisible(U8 te) const
+//------------------------------------------------------------------------
+inline BOOL LLVOAvatar::isTextureVisible(LLVOAvatarDefines::ETextureIndex te) const
{
return ((isTextureDefined(te) || isSelf())
&& (getTEImage(te)->getID() != IMG_INVISIBLE
diff --git a/indra/newview/llvoavatardefines.cpp b/indra/newview/llvoavatardefines.cpp
index 19ad90a8e2..978a61972f 100644
--- a/indra/newview/llvoavatardefines.cpp
+++ b/indra/newview/llvoavatardefines.cpp
@@ -4,7 +4,7 @@
*
* $LicenseInfo:firstyear=2001&license=viewergpl$
*
- * Copyright (c) 2001-2007, Linden Research, Inc.
+ * Copyright (c) 2001-2009, Linden Research, Inc.
*
* Second Life Viewer Source Code
* The source code in this file ("Source Code") is provided by Linden Lab
@@ -12,12 +12,13 @@
* ("GPL"), unless you have obtained a separate licensing agreement
* ("Other License"), formally executed by you and Linden Lab. Terms of
* the GPL can be found in doc/GPL-license.txt in this distribution, or
- * online at http://secondlife.com/developers/opensource/gplv2
+ * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
*
* There are special exceptions to the terms and conditions of the GPL as
* it is applied to this Source Code. View the full text of the exception
* in the file doc/FLOSS-exception.txt in this software distribution, or
- * online at http://secondlife.com/developers/opensource/flossexception
+ * online at
+ * http://secondlifegrid.net/programs/open_source/licensing/flossexception
*
* By copying, modifying or distributing this software, you acknowledge
* that you have read and understood your obligations described above,
@@ -31,6 +32,7 @@
#include "llviewerprecompiledheaders.h"
#include "llvoavatardefines.h"
+#include "llviewercontrol.h" // gSavedSettings
const S32 LLVOAvatarDefines::SCRATCH_TEX_WIDTH = 512;
const S32 LLVOAvatarDefines::SCRATCH_TEX_HEIGHT = 512;
@@ -41,56 +43,87 @@ using namespace LLVOAvatarDefines;
/*********************************************************************************
* Edit this function to add/remove/change textures and mesh definitions for avatars.
*/
-void LLVOAvatarDictionary::initData()
+
+LLVOAvatarDictionary::Textures::Textures()
{
- // Textures
- mTextureMap[TEX_HEAD_BODYPAINT] = new TextureDictionaryEntry("head bodypaint", TRUE, BAKED_NUM_INDICES, "", WT_SKIN);
- mTextureMap[TEX_UPPER_SHIRT] = new TextureDictionaryEntry("shirt", TRUE, BAKED_NUM_INDICES, "UIImgDefaultShirtUUID", WT_SHIRT);
- mTextureMap[TEX_LOWER_PANTS] = new TextureDictionaryEntry("pants", TRUE, BAKED_NUM_INDICES, "UIImgDefaultPantsUUID", WT_PANTS);
- mTextureMap[TEX_EYES_IRIS] = new TextureDictionaryEntry("iris", TRUE, BAKED_NUM_INDICES, "UIImgDefaultEyesUUID", WT_EYES);
- mTextureMap[TEX_HAIR] = new TextureDictionaryEntry("hair", TRUE, BAKED_NUM_INDICES, "UIImgDefaultHairUUID", WT_HAIR);
- mTextureMap[TEX_UPPER_BODYPAINT] = new TextureDictionaryEntry("upper bodypaint", TRUE, BAKED_NUM_INDICES, "", WT_SKIN);
- mTextureMap[TEX_LOWER_BODYPAINT] = new TextureDictionaryEntry("lower bodypaint", TRUE, BAKED_NUM_INDICES, "", WT_SKIN);
- mTextureMap[TEX_LOWER_SHOES] = new TextureDictionaryEntry("shoes", TRUE, BAKED_NUM_INDICES, "UIImgDefaultShoesUUID", WT_SHOES);
- mTextureMap[TEX_LOWER_SOCKS] = new TextureDictionaryEntry("socks", TRUE, BAKED_NUM_INDICES, "UIImgDefaultSocksUUID", WT_SOCKS);
- mTextureMap[TEX_UPPER_JACKET] = new TextureDictionaryEntry("upper jacket", TRUE, BAKED_NUM_INDICES, "UIImgDefaultJacketUUID", WT_JACKET);
- mTextureMap[TEX_LOWER_JACKET] = new TextureDictionaryEntry("lower jacket", TRUE, BAKED_NUM_INDICES, "UIImgDefaultJacketUUID", WT_JACKET);
- mTextureMap[TEX_UPPER_GLOVES] = new TextureDictionaryEntry("gloves", TRUE, BAKED_NUM_INDICES, "UIImgDefaultGlovesUUID", WT_GLOVES);
- mTextureMap[TEX_UPPER_UNDERSHIRT] = new TextureDictionaryEntry("undershirt", TRUE, BAKED_NUM_INDICES, "UIImgDefaultUnderwearUUID", WT_UNDERSHIRT);
- mTextureMap[TEX_LOWER_UNDERPANTS] = new TextureDictionaryEntry("underpants", TRUE, BAKED_NUM_INDICES, "UIImgDefaultUnderwearUUID", WT_UNDERPANTS);
- mTextureMap[TEX_SKIRT] = new TextureDictionaryEntry("skirt", TRUE, BAKED_NUM_INDICES, "UIImgDefaultSkirtUUID", WT_SKIRT);
- mTextureMap[TEX_HEAD_BAKED] = new TextureDictionaryEntry("head-baked", FALSE, BAKED_HEAD);
- mTextureMap[TEX_UPPER_BAKED] = new TextureDictionaryEntry("upper-baked", FALSE, BAKED_UPPER);
- mTextureMap[TEX_LOWER_BAKED] = new TextureDictionaryEntry("lower-baked", FALSE, BAKED_LOWER);
- mTextureMap[TEX_EYES_BAKED] = new TextureDictionaryEntry("eyes-baked", FALSE, BAKED_EYES);
- mTextureMap[TEX_HAIR_BAKED] = new TextureDictionaryEntry("hair-baked", FALSE, BAKED_HAIR);
- mTextureMap[TEX_SKIRT_BAKED] = new TextureDictionaryEntry("skirt-baked", FALSE, BAKED_SKIRT);
+ addEntry(TEX_HEAD_BODYPAINT, new TextureEntry("head_bodypaint", TRUE, BAKED_NUM_INDICES, "", WT_SKIN));
+ addEntry(TEX_UPPER_SHIRT, new TextureEntry("upper_shirt", TRUE, BAKED_NUM_INDICES, "UIImgDefaultShirtUUID", WT_SHIRT));
+ addEntry(TEX_LOWER_PANTS, new TextureEntry("lower_pants", TRUE, BAKED_NUM_INDICES, "UIImgDefaultPantsUUID", WT_PANTS));
+ addEntry(TEX_EYES_IRIS, new TextureEntry("eyes_iris", TRUE, BAKED_NUM_INDICES, "UIImgDefaultEyesUUID", WT_EYES));
+ addEntry(TEX_HAIR, new TextureEntry("hair_grain", TRUE, BAKED_NUM_INDICES, "UIImgDefaultHairUUID", WT_HAIR));
+ addEntry(TEX_UPPER_BODYPAINT, new TextureEntry("upper_bodypaint", TRUE, BAKED_NUM_INDICES, "", WT_SKIN));
+ addEntry(TEX_LOWER_BODYPAINT, new TextureEntry("lower_bodypaint", TRUE, BAKED_NUM_INDICES, "", WT_SKIN));
+ addEntry(TEX_LOWER_SHOES, new TextureEntry("lower_shoes", TRUE, BAKED_NUM_INDICES, "UIImgDefaultShoesUUID", WT_SHOES));
+ addEntry(TEX_LOWER_SOCKS, new TextureEntry("lower_socks", TRUE, BAKED_NUM_INDICES, "UIImgDefaultSocksUUID", WT_SOCKS));
+ addEntry(TEX_UPPER_JACKET, new TextureEntry("upper_jacket", TRUE, BAKED_NUM_INDICES, "UIImgDefaultJacketUUID", WT_JACKET));
+ addEntry(TEX_LOWER_JACKET, new TextureEntry("lower_jacket", TRUE, BAKED_NUM_INDICES, "UIImgDefaultJacketUUID", WT_JACKET));
+ addEntry(TEX_UPPER_GLOVES, new TextureEntry("upper_gloves", TRUE, BAKED_NUM_INDICES, "UIImgDefaultGlovesUUID", WT_GLOVES));
+ addEntry(TEX_UPPER_UNDERSHIRT, new TextureEntry("upper_undershirt", TRUE, BAKED_NUM_INDICES, "UIImgDefaultUnderwearUUID", WT_UNDERSHIRT));
+ addEntry(TEX_LOWER_UNDERPANTS, new TextureEntry("lower_underpants", TRUE, BAKED_NUM_INDICES, "UIImgDefaultUnderwearUUID", WT_UNDERPANTS));
+ addEntry(TEX_SKIRT, new TextureEntry("skirt", TRUE, BAKED_NUM_INDICES, "UIImgDefaultSkirtUUID", WT_SKIRT));
+ addEntry(TEX_LOWER_ALPHA, new TextureEntry("lower_alpha", TRUE, BAKED_NUM_INDICES, "UIImgDefaultAlphaUUID", WT_ALPHA));
+ addEntry(TEX_UPPER_ALPHA, new TextureEntry("upper_alpha", TRUE, BAKED_NUM_INDICES, "UIImgDefaultAlphaUUID", WT_ALPHA));
+ addEntry(TEX_HEAD_ALPHA, new TextureEntry("head_alpha", TRUE, BAKED_NUM_INDICES, "UIImgDefaultAlphaUUID", WT_ALPHA));
+ addEntry(TEX_EYES_ALPHA, new TextureEntry("eyes_alpha", TRUE, BAKED_NUM_INDICES, "UIImgDefaultAlphaUUID", WT_ALPHA));
+ addEntry(TEX_HAIR_ALPHA, new TextureEntry("hair_alpha", TRUE, BAKED_NUM_INDICES, "UIImgDefaultAlphaUUID", WT_ALPHA));
+ addEntry(TEX_HEAD_TATTOO, new TextureEntry("head_tattoo", TRUE, BAKED_NUM_INDICES, "UIImgDefaultTattooUUID", WT_TATTOO));
+ addEntry(TEX_UPPER_TATTOO, new TextureEntry("upper_tattoo", TRUE, BAKED_NUM_INDICES, "UIImgDefaultTattooUUID", WT_TATTOO));
+ addEntry(TEX_LOWER_TATTOO, new TextureEntry("lower_tattoo", TRUE, BAKED_NUM_INDICES, "UIImgDefaultTattooUUID", WT_TATTOO));
+ addEntry(TEX_HEAD_BAKED, new TextureEntry("head-baked", FALSE, BAKED_HEAD));
+ addEntry(TEX_UPPER_BAKED, new TextureEntry("upper-baked", FALSE, BAKED_UPPER));
+ addEntry(TEX_LOWER_BAKED, new TextureEntry("lower-baked", FALSE, BAKED_LOWER));
+ addEntry(TEX_EYES_BAKED, new TextureEntry("eyes-baked", FALSE, BAKED_EYES));
+ addEntry(TEX_HAIR_BAKED, new TextureEntry("hair-baked", FALSE, BAKED_HAIR));
+ addEntry(TEX_SKIRT_BAKED, new TextureEntry("skirt-baked", FALSE, BAKED_SKIRT));
+}
+LLVOAvatarDictionary::BakedTextures::BakedTextures()
+{
// Baked textures
- mBakedTextureMap[BAKED_HEAD] = new BakedDictionaryEntry(TEX_HEAD_BAKED, "head", 1, TEX_HEAD_BODYPAINT);
- mBakedTextureMap[BAKED_UPPER] = new BakedDictionaryEntry(TEX_UPPER_BAKED, "upper_body", 5, TEX_UPPER_SHIRT,TEX_UPPER_BODYPAINT,TEX_UPPER_JACKET,TEX_UPPER_GLOVES,TEX_UPPER_UNDERSHIRT);
- mBakedTextureMap[BAKED_LOWER] = new BakedDictionaryEntry(TEX_LOWER_BAKED, "lower_body", 6, TEX_LOWER_PANTS,TEX_LOWER_BODYPAINT,TEX_LOWER_SHOES,TEX_LOWER_SOCKS,TEX_LOWER_JACKET,TEX_LOWER_UNDERPANTS);
- mBakedTextureMap[BAKED_EYES] = new BakedDictionaryEntry(TEX_EYES_BAKED, "eyes", 1, TEX_EYES_IRIS);
- mBakedTextureMap[BAKED_SKIRT] = new BakedDictionaryEntry(TEX_SKIRT_BAKED, "skirt", 1, TEX_SKIRT);
- mBakedTextureMap[BAKED_HAIR] = new BakedDictionaryEntry(TEX_HAIR_BAKED, "hair", 1, TEX_HAIR);
-
+ addEntry(BAKED_HEAD, new BakedEntry(TEX_HEAD_BAKED,
+ "head", "18ded8d6-bcfc-e415-8539-944c0f5ea7a6",
+ 3, TEX_HEAD_BODYPAINT, TEX_HEAD_TATTOO, TEX_HEAD_ALPHA,
+ 5, WT_SHAPE, WT_SKIN, WT_HAIR, WT_TATTOO, WT_ALPHA));
+
+ addEntry(BAKED_UPPER, new BakedEntry(TEX_UPPER_BAKED,
+ "upper_body", "338c29e3-3024-4dbb-998d-7c04cf4fa88f",
+ 7, TEX_UPPER_SHIRT,TEX_UPPER_BODYPAINT, TEX_UPPER_JACKET,
+ TEX_UPPER_GLOVES, TEX_UPPER_UNDERSHIRT, TEX_UPPER_TATTOO, TEX_UPPER_ALPHA,
+ 8, WT_SHAPE, WT_SKIN, WT_SHIRT, WT_JACKET, WT_GLOVES, WT_UNDERSHIRT, WT_TATTOO, WT_ALPHA));
+
+ addEntry(BAKED_LOWER, new BakedEntry(TEX_LOWER_BAKED,
+ "lower_body", "91b4a2c7-1b1a-ba16-9a16-1f8f8dcc1c3f",
+ 8, TEX_LOWER_PANTS,TEX_LOWER_BODYPAINT,TEX_LOWER_SHOES, TEX_LOWER_SOCKS,
+ TEX_LOWER_JACKET, TEX_LOWER_UNDERPANTS, TEX_LOWER_TATTOO, TEX_LOWER_ALPHA,
+ 9, WT_SHAPE, WT_SKIN, WT_PANTS, WT_SHOES, WT_SOCKS, WT_JACKET, WT_UNDERPANTS, WT_TATTOO, WT_ALPHA));
+
+ addEntry(BAKED_EYES, new BakedEntry(TEX_EYES_BAKED,
+ "eyes", "b2cf28af-b840-1071-3c6a-78085d8128b5",
+ 2, TEX_EYES_IRIS, TEX_EYES_ALPHA,
+ 2, WT_EYES, WT_ALPHA));
+
+ addEntry(BAKED_SKIRT, new BakedEntry(TEX_SKIRT_BAKED,
+ "skirt", "ea800387-ea1a-14e0-56cb-24f2022f969a",
+ 1, TEX_SKIRT,
+ 1, WT_SKIRT));
+
+ addEntry(BAKED_HAIR, new BakedEntry(TEX_HAIR_BAKED,
+ "hair", "0af1ef7c-ad24-11dd-8790-001f5bf833e8",
+ 2, TEX_HAIR, TEX_HAIR_ALPHA,
+ 2, WT_HAIR, WT_ALPHA));
+}
+
+LLVOAvatarDictionary::Meshes::Meshes()
+{
// Meshes
- mMeshMap[MESH_ID_HAIR] = new MeshDictionaryEntry(BAKED_HAIR, "hairMesh", 6, LLViewerJoint::PN_4);
- mMeshMap[MESH_ID_HEAD] = new MeshDictionaryEntry(BAKED_HEAD, "headMesh", 5, LLViewerJoint::PN_5);
- mMeshMap[MESH_ID_EYELASH] = new MeshDictionaryEntry(BAKED_HEAD, "eyelashMesh", 1, LLViewerJoint::PN_0); // no baked mesh associated currently
- mMeshMap[MESH_ID_UPPER_BODY] = new MeshDictionaryEntry(BAKED_UPPER, "upperBodyMesh", 5, LLViewerJoint::PN_1);
- mMeshMap[MESH_ID_LOWER_BODY] = new MeshDictionaryEntry(BAKED_LOWER, "lowerBodyMesh", 5, LLViewerJoint::PN_2);
- mMeshMap[MESH_ID_EYEBALL_LEFT] = new MeshDictionaryEntry(BAKED_EYES, "eyeBallLeftMesh", 2, LLViewerJoint::PN_3);
- mMeshMap[MESH_ID_EYEBALL_RIGHT] = new MeshDictionaryEntry(BAKED_EYES, "eyeBallRightMesh", 2, LLViewerJoint::PN_3);
- mMeshMap[MESH_ID_SKIRT] = new MeshDictionaryEntry(BAKED_SKIRT, "skirtMesh", 5, LLViewerJoint::PN_5);
-
- // Wearables
- mWearableMap[BAKED_HEAD] = new WearableDictionaryEntry("18ded8d6-bcfc-e415-8539-944c0f5ea7a6", 3, WT_SHAPE, WT_SKIN, WT_HAIR);
- mWearableMap[BAKED_UPPER] = new WearableDictionaryEntry("338c29e3-3024-4dbb-998d-7c04cf4fa88f", 6, WT_SHAPE, WT_SKIN, WT_SHIRT, WT_JACKET, WT_GLOVES, WT_UNDERSHIRT);
- mWearableMap[BAKED_LOWER] = new WearableDictionaryEntry("91b4a2c7-1b1a-ba16-9a16-1f8f8dcc1c3f", 7, WT_SHAPE, WT_SKIN, WT_PANTS, WT_SHOES, WT_SOCKS, WT_JACKET, WT_UNDERPANTS);
- mWearableMap[BAKED_EYES] = new WearableDictionaryEntry("b2cf28af-b840-1071-3c6a-78085d8128b5", 1, WT_EYES);
- mWearableMap[BAKED_SKIRT] = new WearableDictionaryEntry("ea800387-ea1a-14e0-56cb-24f2022f969a", 1, WT_SKIRT);
- mWearableMap[BAKED_HAIR] = new WearableDictionaryEntry("0af1ef7c-ad24-11dd-8790-001f5bf833e8", 1, WT_HAIR);
+ addEntry(MESH_ID_HAIR, new MeshEntry(BAKED_HAIR, "hairMesh", 6, LLViewerJoint::PN_4));
+ addEntry(MESH_ID_HEAD, new MeshEntry(BAKED_HEAD, "headMesh", 5, LLViewerJoint::PN_5));
+ addEntry(MESH_ID_EYELASH, new MeshEntry(BAKED_HEAD, "eyelashMesh", 1, LLViewerJoint::PN_0)); // no baked mesh associated currently
+ addEntry(MESH_ID_UPPER_BODY, new MeshEntry(BAKED_UPPER, "upperBodyMesh", 5, LLViewerJoint::PN_1));
+ addEntry(MESH_ID_LOWER_BODY, new MeshEntry(BAKED_LOWER, "lowerBodyMesh", 5, LLViewerJoint::PN_2));
+ addEntry(MESH_ID_EYEBALL_LEFT, new MeshEntry(BAKED_EYES, "eyeBallLeftMesh", 2, LLViewerJoint::PN_3));
+ addEntry(MESH_ID_EYEBALL_RIGHT, new MeshEntry(BAKED_EYES, "eyeBallRightMesh", 2, LLViewerJoint::PN_3));
+ addEntry(MESH_ID_SKIRT, new MeshEntry(BAKED_SKIRT, "skirtMesh", 5, LLViewerJoint::PN_5));
}
/*
@@ -99,18 +132,22 @@ void LLVOAvatarDictionary::initData()
LLVOAvatarDictionary::LLVOAvatarDictionary()
{
- initData();
createAssociations();
}
+//virtual
+LLVOAvatarDictionary::~LLVOAvatarDictionary()
+{
+}
+
// Baked textures are composites of textures; for each such composited texture,
// map it to the baked texture.
void LLVOAvatarDictionary::createAssociations()
{
- for (baked_map_t::const_iterator iter = mBakedTextureMap.begin(); iter != mBakedTextureMap.end(); iter++)
+ for (BakedTextures::const_iterator iter = mBakedTextures.begin(); iter != mBakedTextures.end(); iter++)
{
const EBakedTextureIndex baked_index = (iter->first);
- const BakedDictionaryEntry *dict = (iter->second);
+ const BakedEntry *dict = (iter->second);
// For each texture that this baked texture index affects, associate those textures
// with this baked texture index.
@@ -119,19 +156,19 @@ void LLVOAvatarDictionary::createAssociations()
local_texture_iter++)
{
const ETextureIndex local_texture_index = (ETextureIndex) *local_texture_iter;
- mTextureMap[local_texture_index]->mIsUsedByBakedTexture = true;
- mTextureMap[local_texture_index]->mBakedTextureIndex = baked_index;
+ mTextures[local_texture_index]->mIsUsedByBakedTexture = true;
+ mTextures[local_texture_index]->mBakedTextureIndex = baked_index;
}
}
}
-LLVOAvatarDictionary::TextureDictionaryEntry::TextureDictionaryEntry(const std::string &name,
- bool is_local_texture,
- EBakedTextureIndex baked_texture_index,
- const std::string &default_image_name,
- EWearableType wearable_type) :
- mName(name),
+LLVOAvatarDictionary::TextureEntry::TextureEntry(const std::string &name,
+ bool is_local_texture,
+ EBakedTextureIndex baked_texture_index,
+ const std::string &default_image_name,
+ EWearableType wearable_type) :
+ LLDictionaryEntry(name),
mIsLocalTexture(is_local_texture),
mIsBakedTexture(!is_local_texture),
mIsUsedByBakedTexture(baked_texture_index != BAKED_NUM_INDICES),
@@ -141,87 +178,93 @@ LLVOAvatarDictionary::TextureDictionaryEntry::TextureDictionaryEntry(const std::
{
}
-LLVOAvatarDictionary::MeshDictionaryEntry::MeshDictionaryEntry(EBakedTextureIndex baked_index,
- const std::string &name,
- U8 level,
- LLViewerJoint::PickName pick) :
+LLVOAvatarDictionary::MeshEntry::MeshEntry(EBakedTextureIndex baked_index,
+ const std::string &name,
+ U8 level,
+ LLViewerJoint::PickName pick) :
+ LLDictionaryEntry(name),
mBakedID(baked_index),
- mName(name),
mLOD(level),
mPickName(pick)
{
}
-LLVOAvatarDictionary::BakedDictionaryEntry::BakedDictionaryEntry(ETextureIndex tex_index,
- const std::string &name,
- U32 num_local_textures, ... ) :
- mName(name),
+LLVOAvatarDictionary::BakedEntry::BakedEntry(ETextureIndex tex_index,
+ const std::string &name,
+ const std::string &hash_name,
+ U32 num_local_textures,
+ ... ) :
+ LLDictionaryEntry(name),
+ mWearablesHashID(LLUUID(hash_name)),
mTextureIndex(tex_index)
-
{
va_list argp;
+
va_start(argp, num_local_textures);
+
+ // Read in local textures
for (U8 i=0; i < num_local_textures; i++)
{
ETextureIndex t = (ETextureIndex)va_arg(argp,int);
mLocalTextures.push_back(t);
}
-}
-LLVOAvatarDictionary::WearableDictionaryEntry::WearableDictionaryEntry(const std::string &hash_name,
- U32 num_wearables, ... ) :
- mHashID(LLUUID(hash_name))
-{
- va_list argp;
- va_start(argp, num_wearables);
+ // Read in number of wearables
+ const U32 num_wearables = (U32)va_arg(argp,int);
+ // Read in wearables
for (U8 i=0; i < num_wearables; i++)
{
EWearableType t = (EWearableType)va_arg(argp,int);
- mWearablesVec.push_back(t);
+ mWearables.push_back(t);
}
}
-//virtual
-LLVOAvatarDictionary::~LLVOAvatarDictionary()
+// static
+ETextureIndex LLVOAvatarDictionary::bakedToLocalTextureIndex(EBakedTextureIndex index)
{
- for (mesh_map_t::iterator iter = mMeshMap.begin(); iter != mMeshMap.end(); iter++)
- delete (iter->second);
- for (baked_map_t::iterator iter = mBakedTextureMap.begin(); iter != mBakedTextureMap.end(); iter++)
- delete (iter->second);
- for (texture_map_t::iterator iter = mTextureMap.begin(); iter != mTextureMap.end(); iter++)
- delete (iter->second);
-}
-
-const LLVOAvatarDictionary::MeshDictionaryEntry *LLVOAvatarDictionary::getMesh(EMeshIndex index) const
-{
- mesh_map_t::const_iterator mesh_iter = mMeshMap.find(index);
- if (mesh_iter == mMeshMap.end()) return NULL;
- return mesh_iter->second;
+ return LLVOAvatarDictionary::getInstance()->getBakedTexture(index)->mTextureIndex;
}
-const LLVOAvatarDictionary::BakedDictionaryEntry *LLVOAvatarDictionary::getBakedTexture(EBakedTextureIndex index) const
+//static
+EBakedTextureIndex LLVOAvatarDictionary::findBakedByRegionName(std::string name)
{
- baked_map_t::const_iterator baked_iter = mBakedTextureMap.find(index);
- if (baked_iter == mBakedTextureMap.end()) return NULL;
- return baked_iter->second;
+ U8 index = 0;
+ while (index < BAKED_NUM_INDICES)
+ {
+ const BakedEntry *be = LLVOAvatarDictionary::getInstance()->getBakedTexture((EBakedTextureIndex) index);
+ if (be && be->mName.compare(name) == 0)
+ {
+ // baked texture found
+ return (EBakedTextureIndex) index;
+ }
+ index++;
+ }
+ // baked texture could not be found
+ return BAKED_NUM_INDICES;
}
-const LLVOAvatarDictionary::TextureDictionaryEntry *LLVOAvatarDictionary::getTexture(ETextureIndex index) const
+//static
+const LLUUID LLVOAvatarDictionary::getDefaultTextureImageID(ETextureIndex index)
{
- texture_map_t::const_iterator texture_iter = mTextureMap.find(index);
- if (texture_iter == mTextureMap.end()) return NULL;
- return texture_iter->second;
+ /* switch( index )
+ case TEX_UPPER_SHIRT: return LLUUID( gSavedSettings.getString("UIImgDefaultShirtUUID") ); */
+ const TextureEntry *texture_dict = getInstance()->getTexture(index);
+ const std::string &default_image_name = texture_dict->mDefaultImageName;
+ if (default_image_name == "")
+ {
+ return IMG_DEFAULT_AVATAR;
+ }
+ else
+ {
+ return LLUUID(gSavedSettings.getString(default_image_name));
+ }
}
-const LLVOAvatarDictionary::WearableDictionaryEntry *LLVOAvatarDictionary::getWearable(EBakedTextureIndex index) const
+// static
+EWearableType LLVOAvatarDictionary::getTEWearableType(ETextureIndex index )
{
- wearable_map_t::const_iterator wearable_iter = mWearableMap.find(index);
- if (wearable_iter == mWearableMap.end()) return NULL;
- return wearable_iter->second;
+ /* switch(index)
+ case TEX_UPPER_SHIRT:
+ return WT_SHIRT; */
+ return getInstance()->getTexture(index)->mWearableType;
}
-
-
-ETextureIndex LLVOAvatarDefines::getTextureIndex(EBakedTextureIndex index)
-{
- return LLVOAvatarDictionary::getInstance()->getBakedTexture(index)->mTextureIndex;
-}
diff --git a/indra/newview/llvoavatardefines.h b/indra/newview/llvoavatardefines.h
index bc1a1f1c1f..cf3d318159 100644
--- a/indra/newview/llvoavatardefines.h
+++ b/indra/newview/llvoavatardefines.h
@@ -5,7 +5,7 @@
*
* $LicenseInfo:firstyear=2001&license=viewergpl$
*
- * Copyright (c) 2001-2007, Linden Research, Inc.
+ * Copyright (c) 2001-2009, Linden Research, Inc.
*
* Second Life Viewer Source Code
* The source code in this file ("Source Code") is provided by Linden Lab
@@ -13,12 +13,13 @@
* ("GPL"), unless you have obtained a separate licensing agreement
* ("Other License"), formally executed by you and Linden Lab. Terms of
* the GPL can be found in doc/GPL-license.txt in this distribution, or
- * online at http://secondlife.com/developers/opensource/gplv2
+ * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
*
* There are special exceptions to the terms and conditions of the GPL as
* it is applied to this Source Code. View the full text of the exception
* in the file doc/FLOSS-exception.txt in this software distribution, or
- * online at http://secondlife.com/developers/opensource/flossexception
+ * online at
+ * http://secondlifegrid.net/programs/open_source/licensing/flossexception
*
* By copying, modifying or distributing this software, you acknowledge
* that you have read and understood your obligations described above,
@@ -36,6 +37,7 @@
#include <vector>
#include "llwearable.h"
#include "llviewerjoint.h"
+#include "lldictionary.h"
namespace LLVOAvatarDefines
{
@@ -45,7 +47,7 @@ extern const S32 SCRATCH_TEX_HEIGHT;
extern const S32 IMPOSTOR_PERIOD;
//--------------------------------------------------------------------
-// texture entry assignment
+// Enums
//--------------------------------------------------------------------
enum ETextureIndex
{
@@ -57,9 +59,9 @@ enum ETextureIndex
TEX_UPPER_BODYPAINT,
TEX_LOWER_BODYPAINT,
TEX_LOWER_SHOES,
- TEX_HEAD_BAKED, // Pre-composited
- TEX_UPPER_BAKED, // Pre-composited
- TEX_LOWER_BAKED, // Pre-composited
+ TEX_HEAD_BAKED, // Pre-composited
+ TEX_UPPER_BAKED, // Pre-composited
+ TEX_LOWER_BAKED, // Pre-composited
TEX_EYES_BAKED, // Pre-composited
TEX_LOWER_SOCKS,
TEX_UPPER_JACKET,
@@ -68,14 +70,19 @@ enum ETextureIndex
TEX_UPPER_UNDERSHIRT,
TEX_LOWER_UNDERPANTS,
TEX_SKIRT,
- TEX_SKIRT_BAKED, // Pre-composited
+ TEX_SKIRT_BAKED, // Pre-composited
TEX_HAIR_BAKED, // Pre-composited
+ TEX_LOWER_ALPHA,
+ TEX_UPPER_ALPHA,
+ TEX_HEAD_ALPHA,
+ TEX_EYES_ALPHA,
+ TEX_HAIR_ALPHA,
+ TEX_HEAD_TATTOO,
+ TEX_UPPER_TATTOO,
+ TEX_LOWER_TATTOO,
TEX_NUM_INDICES
-}; // "Note: if TEX_NUM_ENTRIES changes, update AGENT_TEXTURES in llagentinfo.h, mTextureIndexBaked, and BAKED_TEXTURE_COUNT"
-// Seraph - Above comment about order is probably obsolete.
+};
-typedef std::vector<ETextureIndex> texture_vec_t;
-
enum EBakedTextureIndex
{
BAKED_HEAD = 0,
@@ -86,7 +93,6 @@ enum EBakedTextureIndex
BAKED_HAIR,
BAKED_NUM_INDICES
};
-typedef std::vector<EBakedTextureIndex> bakedtexture_vec_t;
// Reference IDs for each mesh. Used as indices for vector of joints
enum EMeshIndex
@@ -101,19 +107,15 @@ enum EMeshIndex
MESH_ID_SKIRT,
MESH_ID_NUM_INDICES
};
-typedef std::vector<EMeshIndex> mesh_vec_t;
+//--------------------------------------------------------------------
+// Vector Types
+//--------------------------------------------------------------------
+typedef std::vector<ETextureIndex> texture_vec_t;
+typedef std::vector<EBakedTextureIndex> bakedtexture_vec_t;
+typedef std::vector<EMeshIndex> mesh_vec_t;
typedef std::vector<EWearableType> wearables_vec_t;
-//--------------------------------------------------------------------------------
-// Convenience Functions
-//--------------------------------------------------------------------------------
-
-// Convert from baked texture to associated texture; e.g. BAKED_HEAD -> TEX_HEAD_BAKED
-ETextureIndex getTextureIndex(EBakedTextureIndex t);
-
-
-
//------------------------------------------------------------------------
// LLVOAvatarDictionary
//
@@ -124,86 +126,109 @@ ETextureIndex getTextureIndex(EBakedTextureIndex t);
//------------------------------------------------------------------------
class LLVOAvatarDictionary : public LLSingleton<LLVOAvatarDictionary>
{
+ //--------------------------------------------------------------------
+ // Constructors and Destructors
+ //--------------------------------------------------------------------
public:
LLVOAvatarDictionary();
virtual ~LLVOAvatarDictionary();
+private:
+ void createAssociations();
- struct TextureDictionaryEntry
+ //--------------------------------------------------------------------
+ // Local and baked textures
+ //--------------------------------------------------------------------
+public:
+ struct TextureEntry : public LLDictionaryEntry
{
- TextureDictionaryEntry(const std::string &name,
- bool is_local_texture,
- EBakedTextureIndex baked_texture_index = BAKED_NUM_INDICES,
- const std::string &default_image_name = "",
- EWearableType wearable_type = WT_INVALID);
- const std::string mName;
- const std::string mDefaultImageName;
+ TextureEntry(const std::string &name, // this must match the xml name used by LLTexLayerInfo::parseXml
+ bool is_local_texture,
+ EBakedTextureIndex baked_texture_index = BAKED_NUM_INDICES,
+ const std::string& default_image_name = "",
+ EWearableType wearable_type = WT_INVALID);
+ const std::string mDefaultImageName;
const EWearableType mWearableType;
// It's either a local texture xor baked
- BOOL mIsLocalTexture;
- BOOL mIsBakedTexture;
+ BOOL mIsLocalTexture;
+ BOOL mIsBakedTexture;
// If it's a local texture, it may be used by a baked texture
- BOOL mIsUsedByBakedTexture;
- EBakedTextureIndex mBakedTextureIndex;
+ BOOL mIsUsedByBakedTexture;
+ EBakedTextureIndex mBakedTextureIndex;
};
+
+ struct Textures : public LLDictionary<ETextureIndex, TextureEntry>
+ {
+ Textures();
+ } mTextures;
+ const TextureEntry* getTexture(ETextureIndex index) const { return mTextures.lookup(index); }
+ const Textures& getTextures() const { return mTextures; }
- struct MeshDictionaryEntry
+ //--------------------------------------------------------------------
+ // Meshes
+ //--------------------------------------------------------------------
+public:
+ struct MeshEntry : public LLDictionaryEntry
{
- MeshDictionaryEntry(EBakedTextureIndex baked_index,
- const std::string &name,
- U8 level,
- LLViewerJoint::PickName pick);
- const std::string mName; // names of mesh types as they are used in avatar_lad.xml
+ MeshEntry(EBakedTextureIndex baked_index,
+ const std::string &name, // names of mesh types as they are used in avatar_lad.xml
+ U8 level,
+ LLViewerJoint::PickName pick);
// Levels of Detail for each mesh. Must match levels of detail present in avatar_lad.xml
// Otherwise meshes will be unable to be found, or levels of detail will be ignored
- const U8 mLOD;
- const EBakedTextureIndex mBakedID;
- const LLViewerJoint::PickName mPickName;
+ const U8 mLOD;
+ const EBakedTextureIndex mBakedID;
+ const LLViewerJoint::PickName mPickName;
};
- struct BakedDictionaryEntry
+ struct Meshes : public LLDictionary<EMeshIndex, MeshEntry>
{
- BakedDictionaryEntry(ETextureIndex tex_index,
- const std::string &name,
- U32 num_local_textures, ... );
- const ETextureIndex mTextureIndex;
- const std::string mName;
- texture_vec_t mLocalTextures;
- };
-
- struct WearableDictionaryEntry
+ Meshes();
+ } mMeshes;
+ const MeshEntry* getMesh(EMeshIndex index) const { return mMeshes.lookup(index); }
+ const Meshes& getMeshes() const { return mMeshes; }
+
+ //--------------------------------------------------------------------
+ // Baked Textures
+ //--------------------------------------------------------------------
+public:
+ struct BakedEntry : public LLDictionaryEntry
{
- WearableDictionaryEntry(const std::string &hash_name,
- U32 num_wearables, ... );
- const LLUUID mHashID;
- wearables_vec_t mWearablesVec;
+ BakedEntry(ETextureIndex tex_index,
+ const std::string &name, // unused, but necessary for templating.
+ const std::string &hash_name,
+ U32 num_local_textures, ... ); // # local textures, local texture list, # wearables, wearable list
+ // Local Textures
+ const ETextureIndex mTextureIndex;
+ texture_vec_t mLocalTextures;
+ // Wearables
+ const LLUUID mWearablesHashID;
+ wearables_vec_t mWearables;
};
- typedef std::map<EBakedTextureIndex, BakedDictionaryEntry*> baked_map_t;
- typedef std::map<ETextureIndex, TextureDictionaryEntry*> texture_map_t;
- typedef std::map<EMeshIndex, MeshDictionaryEntry*> mesh_map_t;
- typedef std::map<EBakedTextureIndex, WearableDictionaryEntry*> wearable_map_t;
+ struct BakedTextures: public LLDictionary<EBakedTextureIndex, BakedEntry>
+ {
+ BakedTextures();
+ } mBakedTextures;
+ const BakedEntry* getBakedTexture(EBakedTextureIndex index) const { return mBakedTextures.lookup(index); }
+ const BakedTextures& getBakedTextures() const { return mBakedTextures; }
+
+ //--------------------------------------------------------------------
+ // Convenience Functions
+ //--------------------------------------------------------------------
+public:
+ // Convert from baked texture to associated texture; e.g. BAKED_HEAD -> TEX_HEAD_BAKED
+ static ETextureIndex bakedToLocalTextureIndex(EBakedTextureIndex t);
- const MeshDictionaryEntry *getMesh(EMeshIndex index) const;
- const BakedDictionaryEntry *getBakedTexture(EBakedTextureIndex index) const;
- const TextureDictionaryEntry *getTexture(ETextureIndex index) const;
- const WearableDictionaryEntry *getWearable(EBakedTextureIndex index) const;
+ // find a baked texture index based on its name
+ static EBakedTextureIndex findBakedByRegionName(std::string name);
- const texture_map_t &getTextures() const { return mTextureMap; }
- const baked_map_t &getBakedTextures() const { return mBakedTextureMap; }
- const mesh_map_t &getMeshes() const { return mMeshMap; }
- const wearable_map_t &getWearables() const { return mWearableMap; }
-
-private:
- void initData();
- void createAssociations();
+ static const LLUUID getDefaultTextureImageID(ETextureIndex index);
- texture_map_t mTextureMap;
- baked_map_t mBakedTextureMap;
- mesh_map_t mMeshMap;
- wearable_map_t mWearableMap;
+ // Given a texture entry, determine which wearable type owns it.
+ static EWearableType getTEWearableType(ETextureIndex index);
}; // End LLVOAvatarDictionary
} // End namespace LLVOAvatarDefines
-#endif
+#endif //LL_VO_AVATARDEFINES_H
diff --git a/indra/newview/llvoavatarself.cpp b/indra/newview/llvoavatarself.cpp
new file mode 100644
index 0000000000..a7b5b60842
--- /dev/null
+++ b/indra/newview/llvoavatarself.cpp
@@ -0,0 +1,2044 @@
+/**
+ * @file llvoavatar.cpp
+ * @brief Implementation of LLVOAvatar class which is a derivation fo LLViewerObject
+ *
+ * $LicenseInfo:firstyear=2001&license=viewergpl$
+ *
+ * Copyright (c) 2001-2009, Linden Research, Inc.
+ *
+ * Second Life Viewer Source Code
+ * The source code in this file ("Source Code") is provided by Linden Lab
+ * to you under the terms of the GNU General Public License, version 2.0
+ * ("GPL"), unless you have obtained a separate licensing agreement
+ * ("Other License"), formally executed by you and Linden Lab. Terms of
+ * the GPL can be found in doc/GPL-license.txt in this distribution, or
+ * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
+ *
+ * There are special exceptions to the terms and conditions of the GPL as
+ * it is applied to this Source Code. View the full text of the exception
+ * in the file doc/FLOSS-exception.txt in this software distribution, or
+ * online at
+ * http://secondlifegrid.net/programs/open_source/licensing/flossexception
+ *
+ * By copying, modifying or distributing this software, you acknowledge
+ * that you have read and understood your obligations described above,
+ * and agree to abide by those obligations.
+ *
+ * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+ * COMPLETENESS OR PERFORMANCE.
+ * $/LicenseInfo$
+ */
+
+#include "llviewerprecompiledheaders.h"
+
+#include "llvoavatarself.h"
+#include "llvoavatar.h"
+
+#include <stdio.h>
+#include <ctype.h>
+
+#include "llaudioengine.h"
+#include "noise.h"
+
+// TODO: Seraph - Remove unnecessary headers. These are copied from llvoavatar.h.
+#include "llagent.h" // Get state values from here
+#include "llagentwearables.h"
+#include "llviewercontrol.h"
+#include "lldrawpoolavatar.h"
+#include "lldriverparam.h"
+#include "lleditingmotion.h"
+#include "llemote.h"
+#include "llface.h"
+#include "llfirstuse.h"
+#include "llheadrotmotion.h"
+#include "llhudeffecttrail.h"
+#include "llhudmanager.h"
+#include "llkeyframefallmotion.h"
+#include "llkeyframestandmotion.h"
+#include "llkeyframewalkmotion.h"
+#include "llmutelist.h"
+#include "llselectmgr.h"
+#include "llsprite.h"
+#include "lltargetingmotion.h"
+#include "lltexlayer.h"
+#include "lltexglobalcolor.h"
+#include "lltoolgrab.h" // for needsRenderBeam
+#include "lltoolmgr.h" // for needsRenderBeam
+#include "lltoolmorph.h"
+#include "lltrans.h"
+#include "llviewercamera.h"
+#include "llviewertexturelist.h"
+#include "llviewermenu.h"
+#include "llviewerobjectlist.h"
+#include "llviewerparcelmgr.h"
+#include "llviewerstats.h"
+#include "llvovolume.h"
+#include "llworld.h"
+#include "pipeline.h"
+#include "llviewershadermgr.h"
+#include "llsky.h"
+#include "llanimstatelabels.h"
+#include "llgesturemgr.h" //needed to trigger the voice gesticulations
+#include "llvoiceclient.h"
+#include "llvoicevisualizer.h" // Ventrella
+
+#include "boost/lexical_cast.hpp"
+
+using namespace LLVOAvatarDefines;
+
+/*********************************************************************************
+ ** **
+ ** Begin private LLVOAvatarSelf Support classes
+ **
+ **/
+
+struct LocalTextureData
+{
+ LocalTextureData() :
+ mIsBakedReady(FALSE),
+ mDiscard(MAX_DISCARD_LEVEL+1),
+ mImage(NULL),
+ mWearableID(IMG_DEFAULT_AVATAR),
+ mTexEntry(NULL)
+ {}
+ LLPointer<LLViewerFetchedTexture> mImage;
+ BOOL mIsBakedReady;
+ S32 mDiscard;
+ LLUUID mWearableID; // UUID of the wearable that this texture belongs to, not of the image itself
+ LLTextureEntry *mTexEntry;
+};
+
+//-----------------------------------------------------------------------------
+// Callback data
+//-----------------------------------------------------------------------------
+struct LLAvatarTexData
+{
+ LLAvatarTexData(const LLUUID& id, ETextureIndex index) :
+ mAvatarID(id),
+ mIndex(index)
+ {}
+ LLUUID mAvatarID;
+ ETextureIndex mIndex;
+};
+
+/**
+ **
+ ** End LLVOAvatarSelf Support classes
+ ** **
+ *********************************************************************************/
+
+
+//-----------------------------------------------------------------------------
+// Static Data
+//-----------------------------------------------------------------------------
+S32 LLVOAvatarSelf::sScratchTexBytes = 0;
+LLMap< LLGLenum, LLGLuint*> LLVOAvatarSelf::sScratchTexNames;
+LLMap< LLGLenum, F32*> LLVOAvatarSelf::sScratchTexLastBindTime;
+
+
+/*********************************************************************************
+ ** **
+ ** Begin LLVOAvatarSelf Constructor routines
+ **
+ **/
+
+LLVOAvatarSelf::LLVOAvatarSelf(const LLUUID& id,
+ const LLPCode pcode,
+ LLViewerRegion* regionp) :
+ LLVOAvatar(id, pcode, regionp),
+ mScreenp(NULL),
+ mLastRegionHandle(0),
+ mRegionCrossingCount(0)
+{
+ gAgent.setAvatarObject(this);
+ gAgentWearables.setAvatarObject(this);
+
+ lldebugs << "Marking avatar as self " << id << llendl;
+}
+
+void LLVOAvatarSelf::initInstance()
+{
+ BOOL status = TRUE;
+ // creates hud joint(mScreen) among other things
+ status &= loadAvatarSelf();
+
+ // adds attachment points to mScreen among other things
+ LLVOAvatar::initInstance();
+
+ status &= buildMenus();
+ if (!status)
+ {
+ llerrs << "Unable to load user's avatar" << llendl;
+ return;
+ }
+}
+
+// virtual
+void LLVOAvatarSelf::markDead()
+{
+ mBeam = NULL;
+ LLVOAvatar::markDead();
+}
+
+BOOL LLVOAvatarSelf::loadAvatarSelf()
+{
+ BOOL success = TRUE;
+ // avatar_skeleton.xml
+ if (!buildSkeletonSelf(sAvatarSkeletonInfo))
+ {
+ llwarns << "avatar file: buildSkeleton() failed" << llendl;
+ return FALSE;
+ }
+ // TODO: make loadLayersets() called only by self.
+ //success &= loadLayersets();
+
+ return success;
+}
+
+BOOL LLVOAvatarSelf::buildSkeletonSelf(const LLVOAvatarSkeletonInfo *info)
+{
+ LLMemType mt(LLMemType::MTYPE_AVATAR);
+
+ // add special-purpose "screen" joint
+ mScreenp = new LLViewerJoint("mScreen", NULL);
+ // for now, put screen at origin, as it is only used during special
+ // HUD rendering mode
+ F32 aspect = LLViewerCamera::getInstance()->getAspect();
+ LLVector3 scale(1.f, aspect, 1.f);
+ mScreenp->setScale(scale);
+ mScreenp->setWorldPosition(LLVector3::zero);
+ return TRUE;
+}
+
+BOOL LLVOAvatarSelf::buildMenus()
+{
+ //-------------------------------------------------------------------------
+ // build the attach and detach menus
+ //-------------------------------------------------------------------------
+ gAttachBodyPartPieMenus[0] = NULL;
+
+ LLContextMenu::Params params;
+ params.label(LLTrans::getString("BodyPartsRightArm") + " >");
+ params.name(params.label);
+ params.visible(false);
+ gAttachBodyPartPieMenus[1] = LLUICtrlFactory::create<LLContextMenu> (params);
+
+ params.label(LLTrans::getString("BodyPartsHead") + " >");
+ params.name(params.label);
+ gAttachBodyPartPieMenus[2] = LLUICtrlFactory::create<LLContextMenu> (params);
+
+ params.label(LLTrans::getString("BodyPartsLeftArm") + " >");
+ params.name(params.label);
+ gAttachBodyPartPieMenus[3] = LLUICtrlFactory::create<LLContextMenu> (params);
+
+ gAttachBodyPartPieMenus[4] = NULL;
+
+ params.label(LLTrans::getString("BodyPartsLeftLeg") + " >");
+ params.name(params.label);
+ gAttachBodyPartPieMenus[5] = LLUICtrlFactory::create<LLContextMenu> (params);
+
+ params.label(LLTrans::getString("BodyPartsTorso") + " >");
+ params.name(params.label);
+ gAttachBodyPartPieMenus[6] = LLUICtrlFactory::create<LLContextMenu> (params);
+
+ params.label(LLTrans::getString("BodyPartsRightLeg") + " >");
+ params.name(params.label);
+ gAttachBodyPartPieMenus[7] = LLUICtrlFactory::create<LLContextMenu> (params);
+
+ gDetachBodyPartPieMenus[0] = NULL;
+
+ params.label(LLTrans::getString("BodyPartsRightArm") + " >");
+ params.name(params.label);
+ gDetachBodyPartPieMenus[1] = LLUICtrlFactory::create<LLContextMenu> (params);
+
+ params.label(LLTrans::getString("BodyPartsHead") + " >");
+ params.name(params.label);
+ gDetachBodyPartPieMenus[2] = LLUICtrlFactory::create<LLContextMenu> (params);
+
+ params.label(LLTrans::getString("BodyPartsLeftArm") + " >");
+ params.name(params.label);
+ gDetachBodyPartPieMenus[3] = LLUICtrlFactory::create<LLContextMenu> (params);
+
+ gDetachBodyPartPieMenus[4] = NULL;
+
+ params.label(LLTrans::getString("BodyPartsLeftLeg") + " >");
+ params.name(params.label);
+ gDetachBodyPartPieMenus[5] = LLUICtrlFactory::create<LLContextMenu> (params);
+
+ params.label(LLTrans::getString("BodyPartsTorso") + " >");
+ params.name(params.label);
+ gDetachBodyPartPieMenus[6] = LLUICtrlFactory::create<LLContextMenu> (params);
+
+ params.label(LLTrans::getString("BodyPartsRightLeg") + " >");
+ params.name(params.label);
+ gDetachBodyPartPieMenus[7] = LLUICtrlFactory::create<LLContextMenu> (params);
+
+ for (S32 i = 0; i < 8; i++)
+ {
+ if (gAttachBodyPartPieMenus[i])
+ {
+ gAttachPieMenu->appendContextSubMenu( gAttachBodyPartPieMenus[i] );
+ }
+ else
+ {
+ BOOL attachment_found = FALSE;
+ for (attachment_map_t::iterator iter = mAttachmentPoints.begin();
+ iter != mAttachmentPoints.end(); )
+ {
+ attachment_map_t::iterator curiter = iter++;
+ LLViewerJointAttachment* attachment = curiter->second;
+ if (attachment->getGroup() == i)
+ {
+ LLMenuItemCallGL::Params item_params;
+
+ std::string sub_piemenu_name = attachment->getName();
+ if (LLTrans::getString(sub_piemenu_name) != "")
+ {
+ item_params.label = LLTrans::getString(sub_piemenu_name);
+ }
+ else
+ {
+ item_params.label = sub_piemenu_name;
+ }
+ item_params.name =(item_params.label );
+ item_params.on_click.function_name = "Object.AttachToAvatar";
+ item_params.on_click.parameter = curiter->first;
+ item_params.on_enable.function_name = "Object.EnableWear";
+ item_params.on_enable.parameter = curiter->first;
+ LLMenuItemCallGL* item = LLUICtrlFactory::create<LLMenuItemCallGL>(item_params);
+
+ gAttachPieMenu->addChild(item);
+
+ attachment_found = TRUE;
+ break;
+
+ }
+ }
+
+ if (!attachment_found)
+ {
+ gAttachPieMenu->addSeparator();
+ }
+ }
+
+ if (gDetachBodyPartPieMenus[i])
+ {
+ gDetachPieMenu->appendContextSubMenu( gDetachBodyPartPieMenus[i] );
+ }
+ else
+ {
+ BOOL attachment_found = FALSE;
+ for (attachment_map_t::iterator iter = mAttachmentPoints.begin();
+ iter != mAttachmentPoints.end(); )
+ {
+ attachment_map_t::iterator curiter = iter++;
+ LLViewerJointAttachment* attachment = curiter->second;
+ if (attachment->getGroup() == i)
+ {
+ LLMenuItemCallGL::Params item_params;
+ std::string sub_piemenu_name = attachment->getName();
+ if (LLTrans::getString(sub_piemenu_name) != "")
+ {
+ item_params.label = LLTrans::getString(sub_piemenu_name);
+ }
+ else
+ {
+ item_params.label = sub_piemenu_name;
+ }
+ item_params.name =(item_params.label );
+ item_params.on_click.function_name = "Attachment.Detach";
+ item_params.on_click.parameter = curiter->first;
+ item_params.on_enable.function_name = "Attachment.EnableDetach";
+ item_params.on_enable.parameter = curiter->first;
+ LLMenuItemCallGL* item = LLUICtrlFactory::create<LLMenuItemCallGL>(item_params);
+
+ gDetachPieMenu->addChild(item);
+
+ attachment_found = TRUE;
+ break;
+ }
+ }
+
+ if (!attachment_found)
+ {
+ gDetachPieMenu->addSeparator();
+ }
+ }
+ }
+
+ // add screen attachments
+ for (attachment_map_t::iterator iter = mAttachmentPoints.begin();
+ iter != mAttachmentPoints.end(); )
+ {
+ attachment_map_t::iterator curiter = iter++;
+ LLViewerJointAttachment* attachment = curiter->second;
+ if (attachment->getGroup() == 8)
+ {
+ LLMenuItemCallGL::Params item_params;
+ std::string sub_piemenu_name = attachment->getName();
+ if (LLTrans::getString(sub_piemenu_name) != "")
+ {
+ item_params.label = LLTrans::getString(sub_piemenu_name);
+ }
+ else
+ {
+ item_params.label = sub_piemenu_name;
+ }
+ item_params.name =(item_params.label );
+ item_params.on_click.function_name = "Object.AttachToAvatar";
+ item_params.on_click.parameter = curiter->first;
+ item_params.on_enable.function_name = "Object.EnableWear";
+ item_params.on_enable.parameter = curiter->first;
+ LLMenuItemCallGL* item = LLUICtrlFactory::create<LLMenuItemCallGL>(item_params);
+ gAttachScreenPieMenu->addChild(item);
+
+ item_params.on_click.function_name = "Attachment.DetachFromPoint";
+ item_params.on_click.parameter = curiter->first;
+ item_params.on_enable.function_name = "Attachment.PointFilled";
+ item_params.on_enable.parameter = curiter->first;
+ item = LLUICtrlFactory::create<LLMenuItemCallGL>(item_params);
+ gDetachScreenPieMenu->addChild(item);
+ }
+ }
+
+ for (S32 pass = 0; pass < 2; pass++)
+ {
+ // *TODO: Skinning - gAttachSubMenu is an awful, awful hack
+ if (!gAttachSubMenu)
+ {
+ break;
+ }
+ for (attachment_map_t::iterator iter = mAttachmentPoints.begin();
+ iter != mAttachmentPoints.end(); )
+ {
+ attachment_map_t::iterator curiter = iter++;
+ LLViewerJointAttachment* attachment = curiter->second;
+ if (attachment->getIsHUDAttachment() != (pass == 1))
+ {
+ continue;
+ }
+ LLMenuItemCallGL::Params item_params;
+ std::string sub_piemenu_name = attachment->getName();
+ if (LLTrans::getString(sub_piemenu_name) != "")
+ {
+ item_params.label = LLTrans::getString(sub_piemenu_name);
+ }
+ else
+ {
+ item_params.label = sub_piemenu_name;
+ }
+ item_params.name =(item_params.label );
+ item_params.on_click.function_name = "Object.AttachToAvatar";
+ item_params.on_click.parameter = curiter->first;
+ item_params.on_enable.function_name = "Object.EnableWear";
+ item_params.on_enable.parameter = curiter->first;
+ //* TODO: Skinning:
+ //LLSD params;
+ //params["index"] = curiter->first;
+ //params["label"] = attachment->getName();
+ //item->addEventHandler("on_enable", LLMenuItemCallGL::MenuCallback().function_name("Attachment.Label").parameter(params));
+
+ LLMenuItemCallGL* item = LLUICtrlFactory::create<LLMenuItemCallGL>(item_params);
+ gAttachSubMenu->addChild(item);
+
+ item_params.on_click.function_name = "Attachment.DetachFromPoint";
+ item_params.on_click.parameter = curiter->first;
+ item_params.on_enable.function_name = "Attachment.PointFilled";
+ item_params.on_enable.parameter = curiter->first;
+ //* TODO: Skinning: item->addEventHandler("on_enable", LLMenuItemCallGL::MenuCallback().function_name("Attachment.Label").parameter(params));
+
+ item = LLUICtrlFactory::create<LLMenuItemCallGL>(item_params);
+ gDetachSubMenu->addChild(item);
+ }
+ if (pass == 0)
+ {
+ // put separator between non-hud and hud attachments
+ gAttachSubMenu->addSeparator();
+ gDetachSubMenu->addSeparator();
+ }
+ }
+
+ for (S32 group = 0; group < 8; group++)
+ {
+ // skip over groups that don't have sub menus
+ if (!gAttachBodyPartPieMenus[group] || !gDetachBodyPartPieMenus[group])
+ {
+ continue;
+ }
+
+ std::multimap<S32, S32> attachment_pie_menu_map;
+
+ // gather up all attachment points assigned to this group, and throw into map sorted by pie slice number
+ for (attachment_map_t::iterator iter = mAttachmentPoints.begin();
+ iter != mAttachmentPoints.end(); )
+ {
+ attachment_map_t::iterator curiter = iter++;
+ LLViewerJointAttachment* attachment = curiter->second;
+ if(attachment->getGroup() == group)
+ {
+ // use multimap to provide a partial order off of the pie slice key
+ S32 pie_index = attachment->getPieSlice();
+ attachment_pie_menu_map.insert(std::make_pair(pie_index, curiter->first));
+ }
+ }
+
+ // add in requested order to pie menu, inserting separators as necessary
+ S32 cur_pie_slice = 0;
+ for (std::multimap<S32, S32>::iterator attach_it = attachment_pie_menu_map.begin();
+ attach_it != attachment_pie_menu_map.end(); ++attach_it)
+ {
+ S32 requested_pie_slice = attach_it->first;
+ S32 attach_index = attach_it->second;
+ while (cur_pie_slice < requested_pie_slice)
+ {
+ gAttachBodyPartPieMenus[group]->addSeparator();
+ gDetachBodyPartPieMenus[group]->addSeparator();
+ cur_pie_slice++;
+ }
+
+ LLViewerJointAttachment* attachment = get_if_there(mAttachmentPoints, attach_index, (LLViewerJointAttachment*)NULL);
+ if (attachment)
+ {
+ LLMenuItemCallGL::Params item_params;
+ item_params.name = attachment->getName();
+ item_params.label = attachment->getName();
+ item_params.on_click.function_name = "Object.AttachToAvatar";
+ item_params.on_click.parameter = attach_index;
+ item_params.on_enable.function_name = "Object.EnableWear";
+ item_params.on_enable.parameter = attach_index;
+
+ LLMenuItemCallGL* item = LLUICtrlFactory::create<LLMenuItemCallGL>(item_params);
+ gAttachBodyPartPieMenus[group]->addChild(item);
+
+ item_params.on_click.function_name = "Attachment.DetachFromPoint";
+ item_params.on_click.parameter = attach_index;
+ item_params.on_enable.function_name = "Attachment.PointFilled";
+ item_params.on_enable.parameter = attach_index;
+ item = LLUICtrlFactory::create<LLMenuItemCallGL>(item_params);
+ gDetachBodyPartPieMenus[group]->addChild(item);
+ cur_pie_slice++;
+ }
+ }
+ }
+ return TRUE;
+}
+
+LLVOAvatarSelf::~LLVOAvatarSelf()
+{
+ gAgent.setAvatarObject(NULL);
+ gAgentWearables.setAvatarObject(NULL);
+ delete mScreenp;
+ mScreenp = NULL;
+}
+
+/**
+ **
+ ** End LLVOAvatarSelf Constructor routines
+ ** **
+ *********************************************************************************/
+
+//virtual
+BOOL LLVOAvatarSelf::loadLayersets()
+{
+ BOOL success = TRUE;
+ for (LLVOAvatarXmlInfo::layer_info_list_t::const_iterator iter = sAvatarXmlInfo->mLayerInfoList.begin();
+ iter != sAvatarXmlInfo->mLayerInfoList.end();
+ iter++)
+ {
+ // Construct a layerset for each one specified in avatar_lad.xml and initialize it as such.
+ const LLTexLayerSetInfo *info = *iter;
+ LLTexLayerSet* layer_set = new LLTexLayerSet( this );
+
+ if (!layer_set->setInfo(info))
+ {
+ stop_glerror();
+ delete layer_set;
+ llwarns << "avatar file: layer_set->parseData() failed" << llendl;
+ return FALSE;
+ }
+
+ // scan baked textures and associate the layerset with the appropriate one
+ EBakedTextureIndex baked_index = BAKED_NUM_INDICES;
+ for (LLVOAvatarDictionary::BakedTextures::const_iterator baked_iter = LLVOAvatarDictionary::getInstance()->getBakedTextures().begin();
+ baked_iter != LLVOAvatarDictionary::getInstance()->getBakedTextures().end();
+ baked_iter++)
+ {
+ const LLVOAvatarDictionary::BakedEntry *baked_dict = baked_iter->second;
+ if (layer_set->isBodyRegion(baked_dict->mName))
+ {
+ baked_index = baked_iter->first;
+ // ensure both structures are aware of each other
+ mBakedTextureDatas[baked_index].mTexLayerSet = layer_set;
+ layer_set->setBakedTexIndex(baked_index);
+ break;
+ }
+ }
+ // if no baked texture was found, warn and cleanup
+ if (baked_index == BAKED_NUM_INDICES)
+ {
+ llwarns << "<layer_set> has invalid body_region attribute" << llendl;
+ delete layer_set;
+ return FALSE;
+ }
+
+ // scan morph masks and let any affected layers know they have an associated morph
+ for (LLVOAvatar::morph_list_t::const_iterator morph_iter = mBakedTextureDatas[baked_index].mMaskedMorphs.begin();
+ morph_iter != mBakedTextureDatas[baked_index].mMaskedMorphs.end();
+ morph_iter++)
+ {
+ LLMaskedMorph *morph = *morph_iter;
+ LLTexLayer * layer = layer_set->findLayerByName(morph->mLayer);
+ if (layer)
+ {
+ layer->setHasMorph(TRUE);
+ }
+ else
+ {
+ llwarns << "Could not find layer named " << morph->mLayer << " to set morph flag" << llendl;
+ success = FALSE;
+ }
+ }
+ }
+ return success;
+}
+// virtual
+BOOL LLVOAvatarSelf::updateCharacter(LLAgent &agent)
+{
+ LLMemType mt(LLMemType::MTYPE_AVATAR);
+
+ // update screen joint size
+ if (mScreenp)
+ {
+ F32 aspect = LLViewerCamera::getInstance()->getAspect();
+ LLVector3 scale(1.f, aspect, 1.f);
+ mScreenp->setScale(scale);
+ mScreenp->updateWorldMatrixChildren();
+ resetHUDAttachments();
+ }
+ return LLVOAvatar::updateCharacter(agent);
+}
+
+// virtual
+LLJoint *LLVOAvatarSelf::getJoint(const std::string &name)
+{
+ if (mScreenp)
+ {
+ LLJoint* jointp = mScreenp->findJoint(name);
+ if (jointp) return jointp;
+ }
+ return LLVOAvatar::getJoint(name);
+}
+
+// virtual
+void LLVOAvatarSelf::requestStopMotion(LLMotion* motion)
+{
+ // Only agent avatars should handle the stop motion notifications.
+
+ // Notify agent that motion has stopped
+ gAgent.requestStopMotion(motion);
+}
+
+// virtual
+void LLVOAvatarSelf::stopMotionFromSource(const LLUUID& source_id)
+{
+ for (AnimSourceIterator motion_it = mAnimationSources.find(source_id); motion_it != mAnimationSources.end(); )
+ {
+ gAgent.sendAnimationRequest(motion_it->second, ANIM_REQUEST_STOP);
+ mAnimationSources.erase(motion_it++);
+ }
+
+ LLViewerObject* object = gObjectList.findObject(source_id);
+ if (object)
+ {
+ object->mFlags &= ~FLAGS_ANIM_SOURCE;
+ }
+}
+
+// virtual
+void LLVOAvatarSelf::setLocalTextureTE(U8 te, LLViewerTexture* image, BOOL set_by_user, U32 index)
+{
+ if (te >= TEX_NUM_INDICES)
+ {
+ llassert(0);
+ return;
+ }
+
+ if (getTEImage(te)->getID() == image->getID())
+ {
+ return;
+ }
+
+ if (isIndexBakedTexture((ETextureIndex)te))
+ {
+ llassert(0);
+ return;
+ }
+
+ LLTexLayerSet* layer_set = getLayerSet((ETextureIndex)te);
+ if (layer_set)
+ {
+ invalidateComposite(layer_set, set_by_user);
+ }
+
+ setTEImage(te, image);
+ updateMeshTextures();
+
+ if (gAgent.cameraCustomizeAvatar())
+ {
+ LLVisualParamHint::requestHintUpdates();
+ }
+}
+
+//virtual
+void LLVOAvatarSelf::removeMissingBakedTextures()
+{
+ BOOL removed = FALSE;
+ for (U32 i = 0; i < mBakedTextureDatas.size(); i++)
+ {
+ const S32 te = mBakedTextureDatas[i].mTextureIndex;
+ LLViewerTexture* tex = getTEImage(te) ;
+ if (!tex || tex->isMissingAsset())
+ {
+ setTEImage(te, LLViewerTextureManager::getFetchedTexture(IMG_DEFAULT_AVATAR));
+ removed = TRUE;
+ }
+ }
+
+ if (removed)
+ {
+ for (U32 i = 0; i < mBakedTextureDatas.size(); i++)
+ {
+ invalidateComposite(mBakedTextureDatas[i].mTexLayerSet, FALSE);
+ }
+ updateMeshTextures();
+ requestLayerSetUploads();
+ }
+}
+
+//virtual
+void LLVOAvatarSelf::updateRegion(LLViewerRegion *regionp)
+{
+ if (regionp->getHandle() != mLastRegionHandle)
+ {
+ if (mLastRegionHandle != 0)
+ {
+ ++mRegionCrossingCount;
+ F64 delta = (F64)mRegionCrossingTimer.getElapsedTimeF32();
+ F64 avg = (mRegionCrossingCount == 1) ? 0 : LLViewerStats::getInstance()->getStat(LLViewerStats::ST_CROSSING_AVG);
+ F64 delta_avg = (delta + avg*(mRegionCrossingCount-1)) / mRegionCrossingCount;
+ LLViewerStats::getInstance()->setStat(LLViewerStats::ST_CROSSING_AVG, delta_avg);
+
+ F64 max = (mRegionCrossingCount == 1) ? 0 : LLViewerStats::getInstance()->getStat(LLViewerStats::ST_CROSSING_MAX);
+ max = llmax(delta, max);
+ LLViewerStats::getInstance()->setStat(LLViewerStats::ST_CROSSING_MAX, max);
+ }
+ mLastRegionHandle = regionp->getHandle();
+ }
+ mRegionCrossingTimer.reset();
+}
+
+//--------------------------------------------------------------------
+// draw tractor beam when editing objects
+//--------------------------------------------------------------------
+//virtual
+void LLVOAvatarSelf::idleUpdateTractorBeam()
+{
+ // This is only done for yourself (maybe it should be in the agent?)
+ if (!needsRenderBeam() || !mIsBuilt)
+ {
+ mBeam = NULL;
+ }
+ else if (!mBeam || mBeam->isDead())
+ {
+ // VEFFECT: Tractor Beam
+ mBeam = (LLHUDEffectSpiral *)LLHUDManager::getInstance()->createViewerEffect(LLHUDObject::LL_HUD_EFFECT_BEAM);
+ mBeam->setColor(LLColor4U(gAgent.getEffectColor()));
+ mBeam->setSourceObject(this);
+ mBeamTimer.reset();
+ }
+
+ if (!mBeam.isNull())
+ {
+ LLObjectSelectionHandle selection = LLSelectMgr::getInstance()->getSelection();
+
+ if (gAgent.mPointAt.notNull())
+ {
+ // get point from pointat effect
+ mBeam->setPositionGlobal(gAgent.mPointAt->getPointAtPosGlobal());
+ mBeam->triggerLocal();
+ }
+ else if (selection->getFirstRootObject() &&
+ selection->getSelectType() != SELECT_TYPE_HUD)
+ {
+ LLViewerObject* objectp = selection->getFirstRootObject();
+ mBeam->setTargetObject(objectp);
+ }
+ else
+ {
+ mBeam->setTargetObject(NULL);
+ LLTool *tool = LLToolMgr::getInstance()->getCurrentTool();
+ if (tool->isEditing())
+ {
+ if (tool->getEditingObject())
+ {
+ mBeam->setTargetObject(tool->getEditingObject());
+ }
+ else
+ {
+ mBeam->setPositionGlobal(tool->getEditingPointGlobal());
+ }
+ }
+ else
+ {
+ const LLPickInfo& pick = gViewerWindow->getLastPick();
+ mBeam->setPositionGlobal(pick.mPosGlobal);
+ }
+
+ }
+ if (mBeamTimer.getElapsedTimeF32() > 0.25f)
+ {
+ mBeam->setColor(LLColor4U(gAgent.getEffectColor()));
+ mBeam->setNeedsSendToSim(TRUE);
+ mBeamTimer.reset();
+ }
+ }
+}
+
+//-----------------------------------------------------------------------------
+// restoreMeshData()
+//-----------------------------------------------------------------------------
+// virtual
+void LLVOAvatarSelf::restoreMeshData()
+{
+ LLMemType mt(LLMemType::MTYPE_AVATAR);
+
+ //llinfos << "Restoring" << llendl;
+ mMeshValid = TRUE;
+ updateJointLODs();
+ updateAttachmentVisibility(gAgent.getCameraMode());
+
+ // force mesh update as LOD might not have changed to trigger this
+ gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_GEOMETRY, TRUE);
+}
+
+
+
+//-----------------------------------------------------------------------------
+// updateAttachmentVisibility()
+//-----------------------------------------------------------------------------
+void LLVOAvatarSelf::updateAttachmentVisibility(U32 camera_mode)
+{
+ for (attachment_map_t::iterator iter = mAttachmentPoints.begin();
+ iter != mAttachmentPoints.end(); )
+ {
+ attachment_map_t::iterator curiter = iter++;
+ LLViewerJointAttachment* attachment = curiter->second;
+ if (attachment->getIsHUDAttachment())
+ {
+ attachment->setAttachmentVisibility(TRUE);
+ }
+ else
+ {
+ switch (camera_mode)
+ {
+ case CAMERA_MODE_MOUSELOOK:
+ if (LLVOAvatar::sVisibleInFirstPerson && attachment->getVisibleInFirstPerson())
+ {
+ attachment->setAttachmentVisibility(TRUE);
+ }
+ else
+ {
+ attachment->setAttachmentVisibility(FALSE);
+ }
+ break;
+ default:
+ attachment->setAttachmentVisibility(TRUE);
+ break;
+ }
+ }
+ }
+}
+
+//-----------------------------------------------------------------------------
+// updatedWearable( EWearableType type )
+// forces an update to any baked textures relevant to type.
+// Should be called only on saving the wearable
+//-----------------------------------------------------------------------------
+void LLVOAvatarSelf::wearableUpdated( EWearableType type )
+{
+ for (LLVOAvatarDictionary::BakedTextures::const_iterator baked_iter = LLVOAvatarDictionary::getInstance()->getBakedTextures().begin();
+ baked_iter != LLVOAvatarDictionary::getInstance()->getBakedTextures().end();
+ baked_iter++)
+ {
+ const LLVOAvatarDictionary::BakedEntry *baked_dict = baked_iter->second;
+ const LLVOAvatarDefines::EBakedTextureIndex index = baked_iter->first;
+ if (baked_dict)
+ {
+ for (LLVOAvatarDefines::wearables_vec_t::const_iterator type_iter = baked_dict->mWearables.begin();
+ type_iter != baked_dict->mWearables.end();
+ type_iter++)
+ {
+ const EWearableType comp_type = *type_iter;
+ if (comp_type == type)
+ {
+ if (mBakedTextureDatas[index].mTexLayerSet)
+ {
+ mBakedTextureDatas[index].mTexLayerSet->requestUpdate();
+ mBakedTextureDatas[index].mTexLayerSet->requestUpload();
+ }
+ break;
+ }
+ }
+ }
+ }
+}
+
+//-----------------------------------------------------------------------------
+// isWearingAttachment()
+//-----------------------------------------------------------------------------
+// Warning: include_linked_items = TRUE makes this operation expensive.
+BOOL LLVOAvatarSelf::isWearingAttachment( const LLUUID& inv_item_id , BOOL include_linked_items ) const
+{
+ for (attachment_map_t::const_iterator iter = mAttachmentPoints.begin();
+ iter != mAttachmentPoints.end(); )
+ {
+ attachment_map_t::const_iterator curiter = iter++;
+ const LLViewerJointAttachment* attachment = curiter->second;
+ if( attachment->getItemID() == inv_item_id )
+ {
+ return TRUE;
+ }
+ }
+
+ if (include_linked_items)
+ {
+ LLInventoryModel::item_array_t item_array;
+ gInventory.collectLinkedItems(inv_item_id, item_array);
+ for (LLInventoryModel::item_array_t::const_iterator iter = item_array.begin();
+ iter != item_array.end();
+ iter++)
+ {
+ const LLViewerInventoryItem *linked_item = (*iter);
+ const LLUUID &item_id = linked_item->getUUID();
+ for (attachment_map_t::const_iterator iter = mAttachmentPoints.begin();
+ iter != mAttachmentPoints.end(); )
+ {
+ attachment_map_t::const_iterator curiter = iter++;
+ const LLViewerJointAttachment* attachment = curiter->second;
+ if( attachment->getItemID() == item_id )
+ {
+ return TRUE;
+ }
+ }
+ }
+ }
+
+ return FALSE;
+}
+
+//-----------------------------------------------------------------------------
+// getWornAttachment()
+//-----------------------------------------------------------------------------
+LLViewerObject* LLVOAvatarSelf::getWornAttachment( const LLUUID& inv_item_id ) const
+{
+ for (attachment_map_t::const_iterator iter = mAttachmentPoints.begin();
+ iter != mAttachmentPoints.end(); )
+ {
+ attachment_map_t::const_iterator curiter = iter++;
+ const LLViewerJointAttachment* attachment = curiter->second;
+ if( attachment->getItemID() == inv_item_id )
+ {
+ return attachment->getObject();
+ }
+ }
+ return NULL;
+}
+
+const std::string LLVOAvatarSelf::getAttachedPointName(const LLUUID& inv_item_id) const
+{
+ for (attachment_map_t::const_iterator iter = mAttachmentPoints.begin();
+ iter != mAttachmentPoints.end(); )
+ {
+ attachment_map_t::const_iterator curiter = iter++;
+ const LLViewerJointAttachment* attachment = curiter->second;
+ if( attachment->getItemID() == inv_item_id )
+ {
+ return attachment->getName();
+ }
+ }
+
+ return LLStringUtil::null;
+}
+
+//virtual
+LLViewerJointAttachment *LLVOAvatarSelf::attachObject(LLViewerObject *viewer_object)
+{
+ LLViewerJointAttachment *attachment = LLVOAvatar::attachObject(viewer_object);
+ if (!attachment)
+ {
+ return 0;
+ }
+
+ updateAttachmentVisibility(gAgent.getCameraMode());
+
+ // Then make sure the inventory is in sync with the avatar.
+ gInventory.addChangedMask(LLInventoryObserver::LABEL, attachment->getItemID());
+ gInventory.notifyObservers();
+
+ return attachment;
+}
+
+void LLVOAvatarSelf::getAllAttachmentsArray(LLDynamicArray<S32>& attachments)
+{
+ for (LLVOAvatar::attachment_map_t::const_iterator iter = mAttachmentPoints.begin();
+ iter != mAttachmentPoints.end(); ++iter)
+ {
+ LLViewerJointAttachment* attachment = iter->second;
+ if ( attachment && (attachment->getNumObjects() > 0))
+ {
+ attachments.push_back(iter->first);
+ }
+ }
+}
+
+U32 LLVOAvatarSelf::getNumWearables(LLVOAvatarDefines::ETextureIndex i) const
+{
+ EWearableType type = LLVOAvatarDictionary::getInstance()->getTEWearableType(i);
+ return gAgentWearables.getWearableCount(type);
+}
+
+// virtual
+void LLVOAvatarSelf::localTextureLoaded(BOOL success, LLViewerFetchedTexture *src_vi, LLImageRaw* src_raw, LLImageRaw* aux_src, S32 discard_level, BOOL final, void* userdata)
+{
+ //llinfos << "onLocalTextureLoaded: " << src_vi->getID() << llendl;
+
+ const LLUUID& src_id = src_vi->getID();
+ LLAvatarTexData *data = (LLAvatarTexData *)userdata;
+ ETextureIndex index = data->mIndex;
+ if (!isIndexLocalTexture(index)) return;
+ LLLocalTextureObject *local_tex_obj = getLocalTextureObject(index, 0);
+
+ // fix for EXT-268. Preventing using of NULL pointer
+ if(NULL == local_tex_obj)
+ {
+ LL_WARNS("TAG") << "There is no Local Texture Object with index: " << index
+ << ", final: " << final
+ << LL_ENDL;
+ return;
+ }
+ if (success)
+ {
+ if (!local_tex_obj->getBakedReady() &&
+ local_tex_obj->getImage() != NULL &&
+ (local_tex_obj->getID() == src_id) &&
+ discard_level < local_tex_obj->getDiscard())
+ {
+ local_tex_obj->setDiscard(discard_level);
+ if (!gAgent.cameraCustomizeAvatar())
+ {
+ requestLayerSetUpdate(index);
+ }
+ else if (gAgent.cameraCustomizeAvatar())
+ {
+ LLVisualParamHint::requestHintUpdates();
+ }
+ updateMeshTextures();
+ }
+ }
+ else if (final)
+ {
+ // Failed: asset is missing
+ if (!local_tex_obj->getBakedReady() &&
+ local_tex_obj->getImage() != NULL &&
+ local_tex_obj->getImage()->getID() == src_id)
+ {
+ local_tex_obj->setDiscard(0);
+ requestLayerSetUpdate(index);
+ updateMeshTextures();
+ }
+ }
+}
+
+// virtual
+/* //unused
+BOOL LLVOAvatarSelf::getLocalTextureRaw(ETextureIndex index, LLImageRaw* image_raw) const
+{
+ if (!isIndexLocalTexture(index)) return FALSE;
+ if (getLocalTextureID(index) == IMG_DEFAULT_AVATAR) return TRUE;
+
+ const LocalTextureData *local_tex_data = getLocalTextureData(index)[0];
+ if (local_tex_data->mImage->readBackRaw(-1, image_raw, false))
+ {
+
+ return TRUE;
+ }
+
+ // No data loaded yet
+ setLocalTexture((ETextureIndex)index, getTEImage(index), FALSE); // <-- non-const, move this elsewhere
+ return FALSE;
+}
+*/
+
+// virtual
+BOOL LLVOAvatarSelf::getLocalTextureGL(ETextureIndex type, LLViewerTexture** tex_pp, U32 index) const
+{
+ *tex_pp = NULL;
+
+ if (!isIndexLocalTexture(type)) return FALSE;
+ if (getLocalTextureID(type, index) == IMG_DEFAULT_AVATAR) return TRUE;
+
+ const LLLocalTextureObject *local_tex_obj = getLocalTextureObject(type, index);
+ if (!local_tex_obj)
+ {
+ return FALSE;
+ }
+ *tex_pp = local_tex_obj->getImage();
+ return TRUE;
+}
+
+const LLUUID& LLVOAvatarSelf::getLocalTextureID(ETextureIndex type, U32 index) const
+{
+ if (!isIndexLocalTexture(type)) return IMG_DEFAULT_AVATAR;
+
+ const LLLocalTextureObject *local_tex_obj = getLocalTextureObject(type, index);
+ if (local_tex_obj && local_tex_obj->getImage() != NULL)
+ {
+ return local_tex_obj->getImage()->getID();
+ }
+ return IMG_DEFAULT_AVATAR;
+}
+
+//-----------------------------------------------------------------------------
+// isLocalTextureDataAvailable()
+// Returns true if at least the lowest quality discard level exists for every texture
+// in the layerset.
+//-----------------------------------------------------------------------------
+BOOL LLVOAvatarSelf::isLocalTextureDataAvailable(const LLTexLayerSet* layerset) const
+{
+ /* if (layerset == mBakedTextureDatas[BAKED_HEAD].mTexLayerSet)
+ return getLocalDiscardLevel(TEX_HEAD_BODYPAINT) >= 0; */
+ for (LLVOAvatarDictionary::BakedTextures::const_iterator baked_iter = LLVOAvatarDictionary::getInstance()->getBakedTextures().begin();
+ baked_iter != LLVOAvatarDictionary::getInstance()->getBakedTextures().end();
+ baked_iter++)
+ {
+ const EBakedTextureIndex baked_index = baked_iter->first;
+ if (layerset == mBakedTextureDatas[baked_index].mTexLayerSet)
+ {
+ BOOL ret = true;
+ const LLVOAvatarDictionary::BakedEntry *baked_dict = baked_iter->second;
+ for (texture_vec_t::const_iterator local_tex_iter = baked_dict->mLocalTextures.begin();
+ local_tex_iter != baked_dict->mLocalTextures.end();
+ local_tex_iter++)
+ {
+ const ETextureIndex tex_index = *local_tex_iter;
+ ret &= (getLocalDiscardLevel(tex_index) >= 0);
+ }
+ return ret;
+ }
+ }
+ llassert(0);
+ return FALSE;
+}
+
+//-----------------------------------------------------------------------------
+// virtual
+// isLocalTextureDataFinal()
+// Returns true if the highest quality discard level exists for every texture
+// in the layerset.
+//-----------------------------------------------------------------------------
+BOOL LLVOAvatarSelf::isLocalTextureDataFinal(const LLTexLayerSet* layerset) const
+{
+ for (U32 i = 0; i < mBakedTextureDatas.size(); i++)
+ {
+ if (layerset == mBakedTextureDatas[i].mTexLayerSet)
+ {
+ const LLVOAvatarDictionary::BakedEntry *baked_dict = LLVOAvatarDictionary::getInstance()->getBakedTexture((EBakedTextureIndex)i);
+ for (texture_vec_t::const_iterator local_tex_iter = baked_dict->mLocalTextures.begin();
+ local_tex_iter != baked_dict->mLocalTextures.end();
+ local_tex_iter++)
+ {
+ if (getLocalDiscardLevel(*local_tex_iter) != 0)
+ {
+ return FALSE;
+ }
+ }
+ return TRUE;
+ }
+ }
+ llassert(0);
+ return FALSE;
+}
+
+BOOL LLVOAvatarSelf::isTextureDefined(LLVOAvatarDefines::ETextureIndex type, U32 index) const
+{
+ LLUUID id;
+ if (isIndexLocalTexture(type))
+ {
+ id = getLocalTextureID(type, index);
+ }
+ else
+ {
+ id = getTEImage(type)->getID();
+ }
+
+ return (id != IMG_DEFAULT_AVATAR &&
+ id != IMG_DEFAULT);
+}
+
+//-----------------------------------------------------------------------------
+// virtual
+// requestLayerSetUploads()
+//-----------------------------------------------------------------------------
+void LLVOAvatarSelf::requestLayerSetUploads()
+{
+ for (U32 i = 0; i < mBakedTextureDatas.size(); i++)
+ {
+ BOOL layer_baked = isTextureDefined(mBakedTextureDatas[i].mTextureIndex);
+ if (!layer_baked && mBakedTextureDatas[i].mTexLayerSet)
+ {
+ mBakedTextureDatas[i].mTexLayerSet->requestUpload();
+ }
+ }
+}
+
+bool LLVOAvatarSelf::areTexturesCurrent() const
+{
+ return !hasPendingBakedUploads() && gAgentWearables.areWearablesLoaded();
+}
+
+// virtual
+bool LLVOAvatarSelf::hasPendingBakedUploads() const
+{
+ for (U32 i = 0; i < mBakedTextureDatas.size(); i++)
+ {
+ BOOL upload_pending = (mBakedTextureDatas[i].mTexLayerSet && mBakedTextureDatas[i].mTexLayerSet->getComposite()->uploadPending());
+ if (upload_pending)
+ {
+ return true;
+ }
+ }
+ return false;
+}
+
+void LLVOAvatarSelf::invalidateComposite( LLTexLayerSet* layerset, BOOL set_by_user )
+{
+ if( !layerset || !layerset->getUpdatesEnabled() )
+ {
+ return;
+ }
+ // llinfos << "LLVOAvatar::invalidComposite() " << layerset->getBodyRegion() << llendl;
+
+ invalidateMorphMasks(layerset->getBakedTexIndex());
+ layerset->requestUpdate();
+
+ if( set_by_user )
+ {
+ llassert(isSelf());
+
+ ETextureIndex baked_te = getBakedTE( layerset );
+ setTEImage( baked_te, LLViewerTextureManager::getFetchedTexture(IMG_DEFAULT_AVATAR) );
+ layerset->requestUpload();
+ }
+}
+
+void LLVOAvatarSelf::invalidateAll()
+{
+ for (U32 i = 0; i < mBakedTextureDatas.size(); i++)
+ {
+ invalidateComposite(mBakedTextureDatas[i].mTexLayerSet, TRUE);
+ }
+ updateMeshTextures();
+}
+
+//-----------------------------------------------------------------------------
+// setCompositeUpdatesEnabled()
+//-----------------------------------------------------------------------------
+void LLVOAvatarSelf::setCompositeUpdatesEnabled( BOOL b )
+{
+ for (U32 i = 0; i < mBakedTextureDatas.size(); i++)
+ {
+ if (mBakedTextureDatas[i].mTexLayerSet )
+ {
+ mBakedTextureDatas[i].mTexLayerSet->setUpdatesEnabled( b );
+ }
+ }
+}
+
+void LLVOAvatarSelf::setupComposites()
+{
+ for (U32 i = 0; i < mBakedTextureDatas.size(); i++)
+ {
+ BOOL layer_baked = isTextureDefined(mBakedTextureDatas[i].mTextureIndex);
+ if (mBakedTextureDatas[i].mTexLayerSet)
+ {
+ mBakedTextureDatas[i].mTexLayerSet->setUpdatesEnabled(!layer_baked);
+ }
+ }
+}
+
+void LLVOAvatarSelf::updateComposites()
+{
+ for (U32 i = 0; i < mBakedTextureDatas.size(); i++)
+ {
+ if (mBakedTextureDatas[i].mTexLayerSet
+ && ((i != BAKED_SKIRT) || isWearingWearableType(WT_SKIRT)))
+ {
+ mBakedTextureDatas[i].mTexLayerSet->updateComposite();
+ }
+ }
+}
+
+// virtual
+S32 LLVOAvatarSelf::getLocalDiscardLevel(ETextureIndex type, U32 index) const
+{
+ if (!isIndexLocalTexture(type)) return FALSE;
+
+ const LLLocalTextureObject *local_tex_obj = getLocalTextureObject(type, index);
+ if (local_tex_obj)
+ {
+ if (type >= 0
+ && getLocalTextureID(type,index) != IMG_DEFAULT_AVATAR
+ && !local_tex_obj->getImage()->isMissingAsset())
+ {
+ return local_tex_obj->getImage()->getDiscardLevel();
+ }
+ else
+ {
+ // We don't care about this (no image associated with the layer) treat as fully loaded.
+ return 0;
+ }
+ }
+ return 0;
+}
+
+// virtual
+// Counts the memory footprint of local textures.
+void LLVOAvatarSelf::getLocalTextureByteCount(S32* gl_bytes) const
+{
+ *gl_bytes = 0;
+ for (S32 type = 0; type < TEX_NUM_INDICES; type++)
+ {
+ if (!isIndexLocalTexture((ETextureIndex)type)) continue;
+ U32 max_tex = getNumWearables((ETextureIndex) type);
+ for (U32 num = 0; num < max_tex; num++)
+ {
+ const LLLocalTextureObject *local_tex_obj = getLocalTextureObject((ETextureIndex) type, num);
+ if (local_tex_obj)
+ {
+ const LLViewerFetchedTexture* image_gl = local_tex_obj->getImage();
+ if (image_gl)
+ {
+ S32 bytes = (S32)image_gl->getWidth() * image_gl->getHeight() * image_gl->getComponents();
+
+ if (image_gl->hasValidGLTexture())
+ {
+ *gl_bytes += bytes;
+ }
+ }
+ }
+ }
+ }
+}
+
+// virtual
+void LLVOAvatarSelf::setLocalTexture(ETextureIndex type, LLViewerTexture* src_tex, BOOL baked_version_ready, U32 index)
+{
+ if (!isIndexLocalTexture(type)) return;
+
+ LLViewerFetchedTexture* tex = LLViewerTextureManager::staticCastToFetchedTexture(src_tex, TRUE) ;
+ if(!tex)
+ {
+ return ;
+ }
+
+ S32 desired_discard = isSelf() ? 0 : 2;
+ LLLocalTextureObject *local_tex_obj = getLocalTextureObject(type,index);
+ if (!local_tex_obj)
+ {
+ if (type >= TEX_NUM_INDICES)
+ {
+ llerrs << "Tried to set local texture with invalid type: (" << (U32) type << ", " << index << ")" << llendl;
+ return;
+ }
+ EWearableType wearable_type = LLVOAvatarDictionary::getInstance()->getTEWearableType(type);
+ if (!gAgentWearables.getWearable(wearable_type,0))
+ {
+ // no wearable is loaded, cannot set the texture.
+ return;
+ }
+ gAgentWearables.addLocalTextureObject(wearable_type,type,index);
+ local_tex_obj = getLocalTextureObject(type,index);
+ if (!local_tex_obj)
+ {
+ llerrs << "Unable to create LocalTextureObject for wearable type & index: (" << (U32) wearable_type << ", " << index << ")" << llendl;
+ return;
+ }
+ }
+ if (!baked_version_ready)
+ {
+ if (tex != local_tex_obj->getImage() || local_tex_obj->getBakedReady())
+ {
+ local_tex_obj->setDiscard(MAX_DISCARD_LEVEL+1);
+ }
+ if (tex->getID() != IMG_DEFAULT_AVATAR)
+ {
+ if (local_tex_obj->getDiscard() > desired_discard)
+ {
+ S32 tex_discard = tex->getDiscardLevel();
+ if (tex_discard >= 0 && tex_discard <= desired_discard)
+ {
+ local_tex_obj->setDiscard(tex_discard);
+ if (isSelf() && !gAgent.cameraCustomizeAvatar())
+ {
+ requestLayerSetUpdate(type);
+ }
+ else if (isSelf() && gAgent.cameraCustomizeAvatar())
+ {
+ LLVisualParamHint::requestHintUpdates();
+ }
+ }
+ else
+ {
+ tex->setLoadedCallback(onLocalTextureLoaded, desired_discard, TRUE, FALSE, new LLAvatarTexData(getID(), type));
+ }
+ }
+ tex->setMinDiscardLevel(desired_discard);
+ }
+ }
+ local_tex_obj->setBakedReady( baked_version_ready );
+ local_tex_obj->setImage(tex);
+}
+
+// virtual
+void LLVOAvatarSelf::dumpLocalTextures() const
+{
+ llinfos << "Local Textures:" << llendl;
+
+ /* ETextureIndex baked_equiv[] = {
+ TEX_UPPER_BAKED,
+ if (isTextureDefined(baked_equiv[i])) */
+ for (LLVOAvatarDictionary::Textures::const_iterator iter = LLVOAvatarDictionary::getInstance()->getTextures().begin();
+ iter != LLVOAvatarDictionary::getInstance()->getTextures().end();
+ iter++)
+ {
+ const LLVOAvatarDictionary::TextureEntry *texture_dict = iter->second;
+ if (!texture_dict->mIsLocalTexture || !texture_dict->mIsUsedByBakedTexture)
+ continue;
+
+ const EBakedTextureIndex baked_index = texture_dict->mBakedTextureIndex;
+ const ETextureIndex baked_equiv = LLVOAvatarDictionary::getInstance()->getBakedTexture(baked_index)->mTextureIndex;
+
+ const std::string &name = texture_dict->mName;
+ const LLLocalTextureObject *local_tex_obj = getLocalTextureObject(iter->first, 0);
+ if (isTextureDefined(baked_equiv))
+ {
+#if LL_RELEASE_FOR_DOWNLOAD
+ // End users don't get to trivially see avatar texture IDs, makes textures
+ // easier to steal. JC
+ llinfos << "LocTex " << name << ": Baked " << llendl;
+#else
+ llinfos << "LocTex " << name << ": Baked " << getTEImage(baked_equiv)->getID() << llendl;
+#endif
+ }
+ else if (local_tex_obj->getImage() != NULL)
+ {
+ if (local_tex_obj->getImage()->getID() == IMG_DEFAULT_AVATAR)
+ {
+ llinfos << "LocTex " << name << ": None" << llendl;
+ }
+ else
+ {
+ const LLViewerFetchedTexture* image = local_tex_obj->getImage();
+
+ llinfos << "LocTex " << name << ": "
+ << "Discard " << image->getDiscardLevel() << ", "
+ << "(" << image->getWidth() << ", " << image->getHeight() << ") "
+#if !LL_RELEASE_FOR_DOWNLOAD
+ // End users don't get to trivially see avatar texture IDs,
+ // makes textures easier to steal
+ << image->getID() << " "
+#endif
+ << "Priority: " << image->getDecodePriority()
+ << llendl;
+ }
+ }
+ else
+ {
+ llinfos << "LocTex " << name << ": No LLViewerTexture" << llendl;
+ }
+ }
+}
+
+//-----------------------------------------------------------------------------
+// static
+// onLocalTextureLoaded()
+//-----------------------------------------------------------------------------
+
+void LLVOAvatarSelf::onLocalTextureLoaded(BOOL success, LLViewerFetchedTexture *src_vi, LLImageRaw* src_raw, LLImageRaw* aux_src, S32 discard_level, BOOL final, void* userdata)
+{
+ LLAvatarTexData *data = (LLAvatarTexData *)userdata;
+ LLVOAvatarSelf *self = (LLVOAvatarSelf *)gObjectList.findObject(data->mAvatarID);
+ if (self)
+ {
+ // We should only be handling local textures for ourself
+ self->localTextureLoaded(success, src_vi, src_raw, aux_src, discard_level, final, userdata);
+ }
+ // ensure data is cleaned up
+ if (final || !success)
+ {
+ delete data;
+ }
+}
+
+// static
+void LLVOAvatarSelf::dumpTotalLocalTextureByteCount()
+{
+ S32 gl_bytes = 0;
+ gAgent.getAvatarObject()->getLocalTextureByteCount(&gl_bytes);
+ llinfos << "Total Avatar LocTex GL:" << (gl_bytes/1024) << "KB" << llendl;
+}
+
+BOOL LLVOAvatarSelf::updateIsFullyLoaded()
+{
+ BOOL loading = FALSE;
+
+ // do we have a shape?
+ if (visualParamWeightsAreDefault())
+ {
+ loading = TRUE;
+ }
+
+ if (!isTextureDefined(TEX_HAIR))
+ {
+ loading = TRUE;
+ }
+
+ if (!mPreviousFullyLoaded)
+ {
+ if (!isLocalTextureDataAvailable(mBakedTextureDatas[BAKED_LOWER].mTexLayerSet) &&
+ (!isTextureDefined(TEX_LOWER_BAKED)))
+ {
+ loading = TRUE;
+ }
+
+ if (!isLocalTextureDataAvailable(mBakedTextureDatas[BAKED_UPPER].mTexLayerSet) &&
+ (!isTextureDefined(TEX_UPPER_BAKED)))
+ {
+ loading = TRUE;
+ }
+
+ for (U32 i = 0; i < mBakedTextureDatas.size(); i++)
+ {
+ if (i == BAKED_SKIRT && !isWearingWearableType(WT_SKIRT))
+ continue;
+
+ BakedTextureData& texture_data = mBakedTextureDatas[i];
+ if (!isTextureDefined(texture_data.mTextureIndex))
+ continue;
+
+ // Check for the case that texture is defined but not sufficiently loaded to display anything.
+ LLViewerTexture* baked_img = getImage( texture_data.mTextureIndex );
+ if (!baked_img || !baked_img->hasValidGLTexture())
+ {
+ loading = TRUE;
+ }
+
+ }
+
+ }
+ return processFullyLoadedChange(loading);
+}
+
+const LLUUID& LLVOAvatarSelf::grabLocalTexture(ETextureIndex type, U32 index) const
+{
+ if (canGrabLocalTexture(type, index))
+ {
+ return getTEImage( type )->getID();
+ }
+ return LLUUID::null;
+}
+
+BOOL LLVOAvatarSelf::canGrabLocalTexture(ETextureIndex type, U32 index) const
+{
+ // Check if the texture hasn't been baked yet.
+ if (!isTextureDefined(type))
+ {
+ lldebugs << "getTEImage( " << (U32) type << " )->getID() == IMG_DEFAULT_AVATAR" << llendl;
+ return FALSE;
+ }
+
+ if (gAgent.isGodlike())
+ return TRUE;
+
+ // Check permissions of textures that show up in the
+ // baked texture. We don't want people copying people's
+ // work via baked textures.
+ /* switch(type)
+ case TEX_EYES_BAKED:
+ textures.push_back(TEX_EYES_IRIS); */
+ const LLVOAvatarDictionary::TextureEntry *texture_dict = LLVOAvatarDictionary::getInstance()->getTexture(type);
+ if (!texture_dict->mIsUsedByBakedTexture) return FALSE;
+
+ const EBakedTextureIndex baked_index = texture_dict->mBakedTextureIndex;
+ const LLVOAvatarDictionary::BakedEntry *baked_dict = LLVOAvatarDictionary::getInstance()->getBakedTexture(baked_index);
+ for (texture_vec_t::const_iterator iter = baked_dict->mLocalTextures.begin();
+ iter != baked_dict->mLocalTextures.end();
+ iter++)
+ {
+ const ETextureIndex t_index = (*iter);
+ lldebugs << "Checking index " << (U32) t_index << llendl;
+ const LLUUID& texture_id = getTEImage( t_index )->getID();
+ if (texture_id != IMG_DEFAULT_AVATAR)
+ {
+ // Search inventory for this texture.
+ LLViewerInventoryCategory::cat_array_t cats;
+ LLViewerInventoryItem::item_array_t items;
+ LLAssetIDMatches asset_id_matches(texture_id);
+ gInventory.collectDescendentsIf(LLUUID::null,
+ cats,
+ items,
+ LLInventoryModel::INCLUDE_TRASH,
+ asset_id_matches);
+
+ BOOL can_grab = FALSE;
+ lldebugs << "item count for asset " << texture_id << ": " << items.count() << llendl;
+ if (items.count())
+ {
+ // search for full permissions version
+ for (S32 i = 0; i < items.count(); i++)
+ {
+ LLInventoryItem* itemp = items[i];
+ LLPermissions item_permissions = itemp->getPermissions();
+ if ( item_permissions.allowOperationBy(
+ PERM_MODIFY, gAgent.getID(), gAgent.getGroupID()) &&
+ item_permissions.allowOperationBy(
+ PERM_COPY, gAgent.getID(), gAgent.getGroupID()) &&
+ item_permissions.allowOperationBy(
+ PERM_TRANSFER, gAgent.getID(), gAgent.getGroupID()) )
+ {
+ can_grab = TRUE;
+ break;
+ }
+ }
+ }
+ if (!can_grab) return FALSE;
+ }
+ }
+
+ return TRUE;
+}
+
+void LLVOAvatarSelf::addLocalTextureStats( ETextureIndex type, LLViewerFetchedTexture* imagep,
+ F32 texel_area_ratio, BOOL render_avatar, BOOL covered_by_baked, U32 index )
+{
+ if (!isIndexLocalTexture(type)) return;
+
+ if (!covered_by_baked)
+ {
+ if (getLocalTextureID(type, index) != IMG_DEFAULT_AVATAR)
+ {
+ F32 desired_pixels;
+ desired_pixels = llmin(mPixelArea, (F32)getTexImageArea());
+ imagep->setBoostLevel(getAvatarBoostLevel());
+ imagep->addTextureStats( desired_pixels / texel_area_ratio );
+ if (imagep->getDiscardLevel() < 0)
+ {
+ mHasGrey = TRUE; // for statistics gathering
+ }
+ }
+ else
+ {
+ // texture asset is missing
+ mHasGrey = TRUE; // for statistics gathering
+ }
+ }
+}
+
+LLLocalTextureObject* LLVOAvatarSelf::getLocalTextureObject(LLVOAvatarDefines::ETextureIndex i, U32 wearable_index) const
+{
+ EWearableType type = LLVOAvatarDictionary::getInstance()->getTEWearableType(i);
+ LLWearable* wearable = gAgentWearables.getWearable(type, wearable_index);
+ if (wearable)
+ {
+ return wearable->getLocalTextureObject(i);
+ }
+
+ return NULL;
+}
+
+//-----------------------------------------------------------------------------
+// getBakedTE()
+// Used by the LayerSet. (Layer sets don't in general know what textures depend on them.)
+//-----------------------------------------------------------------------------
+ETextureIndex LLVOAvatarSelf::getBakedTE( const LLTexLayerSet* layerset ) const
+{
+ for (U32 i = 0; i < mBakedTextureDatas.size(); i++)
+ {
+ if (layerset == mBakedTextureDatas[i].mTexLayerSet )
+ {
+ return mBakedTextureDatas[i].mTextureIndex;
+ }
+ }
+ llassert(0);
+ return TEX_HEAD_BAKED;
+}
+
+
+//-----------------------------------------------------------------------------
+// setNewBakedTexture()
+// A new baked texture has been successfully uploaded and we can start using it now.
+//-----------------------------------------------------------------------------
+void LLVOAvatarSelf::setNewBakedTexture( ETextureIndex te, const LLUUID& uuid )
+{
+ // Baked textures live on other sims.
+ LLHost target_host = getObjectHost();
+ setTEImage( te, LLViewerTextureManager::getFetchedTextureFromHost( uuid, target_host ) );
+ updateMeshTextures();
+ dirtyMesh();
+
+ LLVOAvatar::cullAvatarsByPixelArea();
+
+ /* switch(te)
+ case TEX_HEAD_BAKED:
+ llinfos << "New baked texture: HEAD" << llendl; */
+ const LLVOAvatarDictionary::TextureEntry *texture_dict = LLVOAvatarDictionary::getInstance()->getTexture(te);
+ if (texture_dict->mIsBakedTexture)
+ {
+ llinfos << "New baked texture: " << texture_dict->mName << " UUID: " << uuid <<llendl;
+ }
+ else
+ {
+ llwarns << "New baked texture: unknown te " << te << llendl;
+ }
+
+ // dumpAvatarTEs( "setNewBakedTexture() send" );
+ // RN: throttle uploads
+ if (!hasPendingBakedUploads())
+ {
+ gAgent.sendAgentSetAppearance();
+ }
+}
+
+//-----------------------------------------------------------------------------
+// setCachedBakedTexture()
+// A baked texture id was received from a cache query, make it active
+//-----------------------------------------------------------------------------
+void LLVOAvatarSelf::setCachedBakedTexture( ETextureIndex te, const LLUUID& uuid )
+{
+ setTETexture( te, uuid );
+
+ /* switch(te)
+ case TEX_HEAD_BAKED:
+ if( mHeadLayerSet )
+ mHeadLayerSet->cancelUpload(); */
+ for (U32 i = 0; i < mBakedTextureDatas.size(); i++)
+ {
+ if ( mBakedTextureDatas[i].mTextureIndex == te && mBakedTextureDatas[i].mTexLayerSet)
+ {
+ mBakedTextureDatas[i].mTexLayerSet->cancelUpload();
+ }
+ }
+}
+
+// static
+void LLVOAvatarSelf::processRebakeAvatarTextures(LLMessageSystem* msg, void**)
+{
+ LLUUID texture_id;
+ msg->getUUID("TextureData", "TextureID", texture_id);
+
+ LLVOAvatarSelf* self = gAgent.getAvatarObject();
+ if (!self) return;
+
+ // If this is a texture corresponding to one of our baked entries,
+ // just rebake that layer set.
+ BOOL found = FALSE;
+
+ /* ETextureIndex baked_texture_indices[BAKED_NUM_INDICES] =
+ TEX_HEAD_BAKED,
+ TEX_UPPER_BAKED, */
+ for (LLVOAvatarDictionary::Textures::const_iterator iter = LLVOAvatarDictionary::getInstance()->getTextures().begin();
+ iter != LLVOAvatarDictionary::getInstance()->getTextures().end();
+ iter++)
+ {
+ const ETextureIndex index = iter->first;
+ const LLVOAvatarDictionary::TextureEntry *texture_dict = iter->second;
+ if (texture_dict->mIsBakedTexture)
+ {
+ if (texture_id == self->getTEImage(index)->getID())
+ {
+ LLTexLayerSet* layer_set = self->getLayerSet(index);
+ if (layer_set)
+ {
+ llinfos << "TAT: rebake - matched entry " << (S32)index << llendl;
+ // Apparently set_by_user == force upload
+ BOOL set_by_user = TRUE;
+ self->invalidateComposite(layer_set, set_by_user);
+ found = TRUE;
+ LLViewerStats::getInstance()->incStat(LLViewerStats::ST_TEX_REBAKES);
+ }
+ }
+ }
+ }
+
+ // If texture not found, rebake all entries.
+ if (!found)
+ {
+ self->forceBakeAllTextures();
+ }
+ else
+ {
+ // Not sure if this is necessary, but forceBakeAllTextures() does it.
+ self->updateMeshTextures();
+ }
+}
+
+void LLVOAvatarSelf::forceBakeAllTextures(bool slam_for_debug)
+{
+ llinfos << "TAT: forced full rebake. " << llendl;
+
+ for (U32 i = 0; i < mBakedTextureDatas.size(); i++)
+ {
+ ETextureIndex baked_index = mBakedTextureDatas[i].mTextureIndex;
+ LLTexLayerSet* layer_set = getLayerSet(baked_index);
+ if (layer_set)
+ {
+ if (slam_for_debug)
+ {
+ layer_set->setUpdatesEnabled(TRUE);
+ layer_set->cancelUpload();
+ }
+
+ BOOL set_by_user = TRUE;
+ invalidateComposite(layer_set, set_by_user);
+ LLViewerStats::getInstance()->incStat(LLViewerStats::ST_TEX_REBAKES);
+ }
+ else
+ {
+ llwarns << "TAT: NO LAYER SET FOR " << (S32)baked_index << llendl;
+ }
+ }
+
+ // Don't know if this is needed
+ updateMeshTextures();
+}
+
+//-----------------------------------------------------------------------------
+// requestLayerSetUpdate()
+//-----------------------------------------------------------------------------
+void LLVOAvatarSelf::requestLayerSetUpdate(ETextureIndex index )
+{
+ /* switch(index)
+ case LOCTEX_UPPER_BODYPAINT:
+ case LOCTEX_UPPER_SHIRT:
+ if( mUpperBodyLayerSet )
+ mUpperBodyLayerSet->requestUpdate(); */
+ const LLVOAvatarDictionary::TextureEntry *texture_dict = LLVOAvatarDictionary::getInstance()->getTexture(index);
+ if (!texture_dict->mIsLocalTexture || !texture_dict->mIsUsedByBakedTexture)
+ return;
+ const EBakedTextureIndex baked_index = texture_dict->mBakedTextureIndex;
+ if (mBakedTextureDatas[baked_index].mTexLayerSet)
+ {
+ mBakedTextureDatas[baked_index].mTexLayerSet->requestUpdate();
+ }
+}
+
+LLTexLayerSet* LLVOAvatarSelf::getLayerSet(ETextureIndex index) const
+{
+ /* switch(index)
+ case TEX_HEAD_BAKED:
+ case TEX_HEAD_BODYPAINT:
+ return mHeadLayerSet; */
+ const LLVOAvatarDictionary::TextureEntry *texture_dict = LLVOAvatarDictionary::getInstance()->getTexture(index);
+ if (texture_dict->mIsUsedByBakedTexture)
+ {
+ const EBakedTextureIndex baked_index = texture_dict->mBakedTextureIndex;
+ return mBakedTextureDatas[baked_index].mTexLayerSet;
+ }
+ return NULL;
+}
+
+// static
+void LLVOAvatarSelf::onCustomizeStart()
+{
+ // We're no longer doing any baking or invalidating on entering
+ // appearance editing mode. Leaving function in place in case
+ // further changes require us to do something at this point - Nyx
+}
+
+// static
+void LLVOAvatarSelf::onCustomizeEnd()
+{
+ LLVOAvatarSelf *avatarp = gAgent.getAvatarObject();
+ if (avatarp)
+ {
+ avatarp->invalidateAll();
+ avatarp->requestLayerSetUploads();
+ }
+}
+
+// static
+void LLVOAvatarSelf::onChangeSelfInvisible(BOOL newvalue)
+{
+ LLVOAvatarSelf *avatarp = gAgent.getAvatarObject();
+ if (avatarp)
+ {
+ if (newvalue)
+ {
+ // we have just requested to set the avatar's baked textures to invisible
+ avatarp->setInvisible(TRUE);
+ }
+ else
+ {
+ avatarp->setInvisible(FALSE);
+ }
+ }
+}
+
+void LLVOAvatarSelf::setInvisible(BOOL newvalue)
+{
+ if (newvalue)
+ {
+ setCompositeUpdatesEnabled(FALSE);
+ for (U32 i = 0; i < mBakedTextureDatas.size(); i++ )
+ {
+ setNewBakedTexture(mBakedTextureDatas[i].mTextureIndex, IMG_INVISIBLE);
+ }
+ gAgent.sendAgentSetAppearance();
+ }
+ else
+ {
+ setCompositeUpdatesEnabled(TRUE);
+ invalidateAll();
+ requestLayerSetUploads();
+ gAgent.sendAgentSetAppearance();
+ }
+}
+
+//------------------------------------------------------------------------
+// needsRenderBeam()
+//------------------------------------------------------------------------
+BOOL LLVOAvatarSelf::needsRenderBeam()
+{
+ if (gNoRender)
+ {
+ return FALSE;
+ }
+ LLTool *tool = LLToolMgr::getInstance()->getCurrentTool();
+
+ BOOL is_touching_or_grabbing = (tool == LLToolGrab::getInstance() && LLToolGrab::getInstance()->isEditing());
+ if (LLToolGrab::getInstance()->getEditingObject() &&
+ LLToolGrab::getInstance()->getEditingObject()->isAttachment())
+ {
+ // don't render selection beam on hud objects
+ is_touching_or_grabbing = FALSE;
+ }
+ return is_touching_or_grabbing || (mState & AGENT_STATE_EDITING && LLSelectMgr::getInstance()->shouldShowSelection());
+}
+
+// static
+void LLVOAvatarSelf::deleteScratchTextures()
+{
+ for( LLGLuint* namep = sScratchTexNames.getFirstData();
+ namep;
+ namep = sScratchTexNames.getNextData() )
+ {
+ LLImageGL::deleteTextures(1, (U32 *)namep );
+ stop_glerror();
+ }
+
+ if( sScratchTexBytes )
+ {
+ lldebugs << "Clearing Scratch Textures " << (sScratchTexBytes/1024) << "KB" << llendl;
+
+ sScratchTexNames.deleteAllData();
+ sScratchTexLastBindTime.deleteAllData();
+ LLImageGL::sGlobalTextureMemoryInBytes -= sScratchTexBytes;
+ sScratchTexBytes = 0;
+ }
+}
+
+BOOL LLVOAvatarSelf::bindScratchTexture( LLGLenum format )
+{
+ U32 texture_bytes = 0;
+ GLuint gl_name = getScratchTexName( format, &texture_bytes );
+ if( gl_name )
+ {
+ gGL.getTexUnit(0)->bindManual(LLTexUnit::TT_TEXTURE, gl_name);
+ stop_glerror();
+
+ F32* last_bind_time = sScratchTexLastBindTime.getIfThere( format );
+ if( last_bind_time )
+ {
+ if( *last_bind_time != LLImageGL::sLastFrameTime )
+ {
+ *last_bind_time = LLImageGL::sLastFrameTime;
+ LLImageGL::updateBoundTexMem(texture_bytes);
+ }
+ }
+ else
+ {
+ LLImageGL::updateBoundTexMem(texture_bytes);
+ sScratchTexLastBindTime.addData( format, new F32(LLImageGL::sLastFrameTime) );
+ }
+ return TRUE;
+ }
+ return FALSE;
+}
+
+LLGLuint LLVOAvatarSelf::getScratchTexName( LLGLenum format, U32* texture_bytes )
+{
+ S32 components;
+ GLenum internal_format;
+ switch( format )
+ {
+ case GL_LUMINANCE: components = 1; internal_format = GL_LUMINANCE8; break;
+ case GL_ALPHA: components = 1; internal_format = GL_ALPHA8; break;
+ case GL_COLOR_INDEX: components = 1; internal_format = GL_COLOR_INDEX8_EXT; break;
+ case GL_LUMINANCE_ALPHA: components = 2; internal_format = GL_LUMINANCE8_ALPHA8; break;
+ case GL_RGB: components = 3; internal_format = GL_RGB8; break;
+ case GL_RGBA: components = 4; internal_format = GL_RGBA8; break;
+ default: llassert(0); components = 4; internal_format = GL_RGBA8; break;
+ }
+
+ *texture_bytes = components * SCRATCH_TEX_WIDTH * SCRATCH_TEX_HEIGHT;
+
+ if( sScratchTexNames.checkData( format ) )
+ {
+ return *( sScratchTexNames.getData( format ) );
+ }
+
+ LLGLSUIDefault gls_ui;
+
+ U32 name = 0;
+ LLImageGL::generateTextures(1, &name );
+ stop_glerror();
+
+ gGL.getTexUnit(0)->bindManual(LLTexUnit::TT_TEXTURE, name);
+ stop_glerror();
+
+ LLImageGL::setManualImage(
+ GL_TEXTURE_2D, 0, internal_format,
+ SCRATCH_TEX_WIDTH, SCRATCH_TEX_HEIGHT,
+ format, GL_UNSIGNED_BYTE, NULL );
+ stop_glerror();
+
+ gGL.getTexUnit(0)->setTextureFilteringOption(LLTexUnit::TFO_BILINEAR);
+ gGL.getTexUnit(0)->setTextureAddressMode(LLTexUnit::TAM_CLAMP);
+ stop_glerror();
+
+ gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
+ stop_glerror();
+
+ sScratchTexNames.addData( format, new LLGLuint( name ) );
+
+ sScratchTexBytes += *texture_bytes;
+ LLImageGL::sGlobalTextureMemoryInBytes += *texture_bytes;
+ return name;
+}
+
+// static
+void LLVOAvatarSelf::dumpScratchTextureByteCount()
+{
+ llinfos << "Scratch Texture GL: " << (sScratchTexBytes/1024) << "KB" << llendl;
+}
diff --git a/indra/newview/llvoavatarself.h b/indra/newview/llvoavatarself.h
new file mode 100644
index 0000000000..17744cce1b
--- /dev/null
+++ b/indra/newview/llvoavatarself.h
@@ -0,0 +1,314 @@
+/**
+ * @file llvoavatarself.h
+ * @brief Declaration of LLVOAvatar class which is a derivation fo
+ * LLViewerObject
+ *
+ * $LicenseInfo:firstyear=2001&license=viewergpl$
+ *
+ * Copyright (c) 2001-2009, Linden Research, Inc.
+ *
+ * Second Life Viewer Source Code
+ * The source code in this file ("Source Code") is provided by Linden Lab
+ * to you under the terms of the GNU General Public License, version 2.0
+ * ("GPL"), unless you have obtained a separate licensing agreement
+ * ("Other License"), formally executed by you and Linden Lab. Terms of
+ * the GPL can be found in doc/GPL-license.txt in this distribution, or
+ * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
+ *
+ * There are special exceptions to the terms and conditions of the GPL as
+ * it is applied to this Source Code. View the full text of the exception
+ * in the file doc/FLOSS-exception.txt in this software distribution, or
+ * online at
+ * http://secondlifegrid.net/programs/open_source/licensing/flossexception
+ *
+ * By copying, modifying or distributing this software, you acknowledge
+ * that you have read and understood your obligations described above,
+ * and agree to abide by those obligations.
+ *
+ * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+ * COMPLETENESS OR PERFORMANCE.
+ * $/LicenseInfo$
+ */
+
+#ifndef LL_LLVOAVATARSELF_H
+#define LL_LLVOAVATARSELF_H
+
+#include "llviewertexture.h"
+#include "llvoavatar.h"
+
+struct LocalTextureData;
+
+//------------------------------------------------------------------------
+// LLVOAvatarSelf
+//------------------------------------------------------------------------
+class LLVOAvatarSelf :
+ public LLVOAvatar
+{
+
+/********************************************************************************
+ ** **
+ ** INITIALIZATION
+ **/
+
+public:
+ LLVOAvatarSelf(const LLUUID &id, const LLPCode pcode, LLViewerRegion *regionp);
+ virtual ~LLVOAvatarSelf();
+ virtual void markDead();
+ virtual void initInstance(); // Called after construction to initialize the class.
+protected:
+ BOOL loadAvatarSelf();
+ BOOL buildSkeletonSelf(const LLVOAvatarSkeletonInfo *info);
+ BOOL buildMenus();
+ /*virtual*/ BOOL loadLayersets();
+
+/** Initialization
+ ** **
+ *******************************************************************************/
+
+/********************************************************************************
+ ** **
+ ** INHERITED
+ **/
+
+ //--------------------------------------------------------------------
+ // LLViewerObject interface and related
+ //--------------------------------------------------------------------
+public:
+ /*virtual*/ void updateRegion(LLViewerRegion *regionp);
+
+ //--------------------------------------------------------------------
+ // LLCharacter interface and related
+ //--------------------------------------------------------------------
+public:
+ /*virtual*/ void stopMotionFromSource(const LLUUID& source_id);
+ /*virtual*/ void requestStopMotion(LLMotion* motion);
+ /*virtual*/ LLJoint* getJoint(const std::string &name);
+
+/** Initialization
+ ** **
+ *******************************************************************************/
+
+/********************************************************************************
+ ** **
+ ** STATE
+ **/
+
+public:
+ /*virtual*/ bool isSelf() const { return true; }
+
+ //--------------------------------------------------------------------
+ // Updates
+ //--------------------------------------------------------------------
+public:
+ /*virtual*/ BOOL updateCharacter(LLAgent &agent);
+ /*virtual*/ void idleUpdateTractorBeam();
+
+ //--------------------------------------------------------------------
+ // Loading state
+ //--------------------------------------------------------------------
+public:
+ /*virtual*/ BOOL updateIsFullyLoaded();
+private:
+ BOOL mIsBaked; // are the stored baked textures up to date?
+
+ //--------------------------------------------------------------------
+ // Region state
+ //--------------------------------------------------------------------
+private:
+ U64 mLastRegionHandle;
+ LLFrameTimer mRegionCrossingTimer;
+ S32 mRegionCrossingCount;
+
+/** State
+ ** **
+ *******************************************************************************/
+
+/********************************************************************************
+ ** **
+ ** RENDERING
+ **/
+
+ //--------------------------------------------------------------------
+ // Render beam
+ //--------------------------------------------------------------------
+protected:
+ BOOL needsRenderBeam();
+private:
+ LLPointer<LLHUDEffectSpiral> mBeam;
+ LLFrameTimer mBeamTimer;
+
+ //--------------------------------------------------------------------
+ // LLVOAvatar Constants
+ //--------------------------------------------------------------------
+public:
+ /*virtual*/ LLViewerTexture::EBoostLevel getAvatarBoostLevel() const { return LLViewerTexture::BOOST_AVATAR_SELF; }
+ /*virtual*/ LLViewerTexture::EBoostLevel getAvatarBakedBoostLevel() const { return LLViewerTexture::BOOST_AVATAR_BAKED_SELF; }
+ /*virtual*/ S32 getTexImageSize() const { return LLVOAvatar::getTexImageSize()*4; }
+
+/** Rendering
+ ** **
+ *******************************************************************************/
+
+/********************************************************************************
+ ** **
+ ** TEXTURES
+ **/
+
+ //--------------------------------------------------------------------
+ // Loading status
+ //--------------------------------------------------------------------
+public:
+ /*virtual*/ bool hasPendingBakedUploads() const;
+ S32 getLocalDiscardLevel(LLVOAvatarDefines::ETextureIndex type, U32 index = 0) const;
+ bool areTexturesCurrent() const;
+ BOOL isLocalTextureDataAvailable(const LLTexLayerSet* layerset) const;
+ BOOL isLocalTextureDataFinal(const LLTexLayerSet* layerset) const;
+ /*virtual*/ BOOL isTextureDefined(LLVOAvatarDefines::ETextureIndex type, U32 index = 0) const;
+
+ //--------------------------------------------------------------------
+ // Local Textures
+ //--------------------------------------------------------------------
+public:
+ BOOL getLocalTextureGL(LLVOAvatarDefines::ETextureIndex type, LLViewerTexture** image_gl_pp, U32 index = 0) const;
+ const LLUUID& getLocalTextureID(LLVOAvatarDefines::ETextureIndex type, U32 index = 0) const;
+ void setLocalTextureTE(U8 te, LLViewerTexture* image, BOOL set_by_user, U32 index = 0);
+ const LLUUID& grabLocalTexture(LLVOAvatarDefines::ETextureIndex type, U32 index = 0) const;
+ BOOL canGrabLocalTexture(LLVOAvatarDefines::ETextureIndex type, U32 index = 0) const;
+protected:
+ /*virtual*/ void setLocalTexture(LLVOAvatarDefines::ETextureIndex type, LLViewerTexture* tex, BOOL baked_version_exits, U32 index = 0);
+ void localTextureLoaded(BOOL succcess, LLViewerFetchedTexture *src_vi, LLImageRaw* src, LLImageRaw* aux_src, S32 discard_level, BOOL final, void* userdata);
+ void getLocalTextureByteCount(S32* gl_byte_count) const;
+ /*virtual*/ void addLocalTextureStats(LLVOAvatarDefines::ETextureIndex i, LLViewerFetchedTexture* imagep, F32 texel_area_ratio, BOOL rendered, BOOL covered_by_baked, U32 index = 0);
+ LLLocalTextureObject* getLocalTextureObject(LLVOAvatarDefines::ETextureIndex i, U32 index = 0) const;
+
+private:
+ static void onLocalTextureLoaded(BOOL succcess, LLViewerFetchedTexture *src_vi, LLImageRaw* src, LLImageRaw* aux_src, S32 discard_level, BOOL final, void* userdata);
+
+ //--------------------------------------------------------------------
+ // Baked textures
+ //--------------------------------------------------------------------
+public:
+ LLVOAvatarDefines::ETextureIndex getBakedTE(const LLTexLayerSet* layerset ) const;
+ void setNewBakedTexture(LLVOAvatarDefines::ETextureIndex i, const LLUUID& uuid);
+ void setCachedBakedTexture(LLVOAvatarDefines::ETextureIndex i, const LLUUID& uuid);
+ void forceBakeAllTextures(bool slam_for_debug = false);
+ static void processRebakeAvatarTextures(LLMessageSystem* msg, void**);
+protected:
+ /*virtual*/ void removeMissingBakedTextures();
+
+ //--------------------------------------------------------------------
+ // Layers
+ //--------------------------------------------------------------------
+public:
+ void requestLayerSetUploads();
+ void requestLayerSetUpdate(LLVOAvatarDefines::ETextureIndex i);
+protected:
+ LLTexLayerSet* getLayerSet(LLVOAvatarDefines::ETextureIndex index) const;
+
+ //--------------------------------------------------------------------
+ // Composites
+ //--------------------------------------------------------------------
+public:
+ /* virtual */ void invalidateComposite(LLTexLayerSet* layerset, BOOL set_by_user);
+ /* virtual */ void invalidateAll();
+ /* virtual */ void setCompositeUpdatesEnabled(BOOL b); // only works for self
+ void setupComposites();
+ void updateComposites();
+
+ //--------------------------------------------------------------------
+ // Scratch textures (used for compositing)
+ //--------------------------------------------------------------------
+public:
+ BOOL bindScratchTexture(LLGLenum format);
+ static void deleteScratchTextures();
+protected:
+ LLGLuint getScratchTexName(LLGLenum format, U32* texture_bytes);
+private:
+ static S32 sScratchTexBytes;
+ static LLMap< LLGLenum, LLGLuint*> sScratchTexNames;
+ static LLMap< LLGLenum, F32*> sScratchTexLastBindTime;
+
+/** Textures
+ ** **
+ *******************************************************************************/
+
+/********************************************************************************
+ ** **
+ ** MESHES
+ **/
+protected:
+ /*virtual*/ void restoreMeshData();
+
+/** Meshes
+ ** **
+ *******************************************************************************/
+
+/********************************************************************************
+ ** **
+ ** WEARABLES
+ **/
+
+public:
+ void wearableUpdated(EWearableType type);
+
+ //--------------------------------------------------------------------
+ // Attachments
+ //--------------------------------------------------------------------
+public:
+ void updateAttachmentVisibility(U32 camera_mode);
+ BOOL isWearingAttachment(const LLUUID& inv_item_id, BOOL include_linked_items = FALSE) const;
+ LLViewerObject* getWornAttachment(const LLUUID& inv_item_id ) const;
+ const std::string getAttachedPointName(const LLUUID& inv_item_id) const;
+ /*virtual*/ LLViewerJointAttachment *attachObject(LLViewerObject *viewer_object);
+ void getAllAttachmentsArray(LLDynamicArray<S32>& attachments);
+
+ //--------------------------------------------------------------------
+ // HUDs
+ //--------------------------------------------------------------------
+private:
+ U32 getNumWearables(LLVOAvatarDefines::ETextureIndex i) const;
+
+ LLViewerJoint* mScreenp; // special purpose joint for HUD attachments
+
+/** Attachments
+ ** **
+ *******************************************************************************/
+
+/********************************************************************************
+ ** **
+ ** APPEARANCE
+ **/
+
+public:
+ static void onCustomizeStart();
+ static void onCustomizeEnd();
+
+ //--------------------------------------------------------------------
+ // Visibility
+ //--------------------------------------------------------------------
+public:
+ static void onChangeSelfInvisible(BOOL newvalue);
+ void setInvisible(BOOL newvalue);
+
+/** Appearance
+ ** **
+ *******************************************************************************/
+
+/********************************************************************************
+ ** **
+ ** DIAGNOSTICS
+ **/
+
+public:
+ static void dumpTotalLocalTextureByteCount();
+ void dumpLocalTextures() const;
+ static void dumpScratchTextureByteCount();
+
+/** Diagnostics
+ ** **
+ *******************************************************************************/
+
+};
+
+#endif // LL_VO_AVATARSELF_H
diff --git a/indra/newview/llvoclouds.cpp b/indra/newview/llvoclouds.cpp
index 9095ee43c8..130e1fd749 100644
--- a/indra/newview/llvoclouds.cpp
+++ b/indra/newview/llvoclouds.cpp
@@ -44,7 +44,7 @@
#include "llprimitive.h"
#include "llsky.h"
#include "llviewercamera.h"
-#include "llviewerimagelist.h"
+#include "llviewertexturelist.h"
#include "llviewerobjectlist.h"
#include "llviewerregion.h"
#include "llvosky.h"
@@ -61,8 +61,8 @@ LLVOClouds::LLVOClouds(const LLUUID &id, const LLPCode pcode, LLViewerRegion *re
mCloudGroupp = NULL;
mbCanSelect = FALSE;
setNumTEs(1);
- LLViewerImage* image = gImageList.getImage(gCloudTextureID);
- image->setBoostLevel(LLViewerImage::BOOST_CLOUDS);
+ LLViewerTexture* image = LLViewerTextureManager::getFetchedTexture(gCloudTextureID);
+ image->setBoostLevel(LLViewerTexture::BOOST_CLOUDS);
setTEImage(0, image);
}
@@ -115,9 +115,11 @@ LLDrawable* LLVOClouds::createDrawable(LLPipeline *pipeline)
return mDrawable;
}
+static LLFastTimer::DeclareTimer FTM_UPDATE_CLOUDS("Update Clouds");
+
BOOL LLVOClouds::updateGeometry(LLDrawable *drawable)
{
- LLFastTimer ftm(LLFastTimer::FTM_UPDATE_CLOUDS);
+ LLFastTimer ftm(FTM_UPDATE_CLOUDS);
if (!(gPipeline.hasRenderType(LLPipeline::RENDER_TYPE_CLOUDS)))
{
return TRUE;
diff --git a/indra/newview/llvoclouds.h b/indra/newview/llvoclouds.h
index f70ea5b9e7..95e6b96e4e 100644
--- a/indra/newview/llvoclouds.h
+++ b/indra/newview/llvoclouds.h
@@ -37,7 +37,7 @@
#include "lltable.h"
#include "v4coloru.h"
-class LLViewerImage;
+class LLViewerTexture;
class LLViewerCloudGroup;
class LLCloudGroup;
diff --git a/indra/newview/llvograss.cpp b/indra/newview/llvograss.cpp
index fe4a2fdc76..a2793accea 100644
--- a/indra/newview/llvograss.cpp
+++ b/indra/newview/llvograss.cpp
@@ -46,7 +46,7 @@
#include "llsurfacepatch.h"
#include "llvosky.h"
#include "llviewercamera.h"
-#include "llviewerimagelist.h"
+#include "llviewertexturelist.h"
#include "llviewerregion.h"
#include "pipeline.h"
#include "llspatialpartition.h"
@@ -106,7 +106,7 @@ void LLVOGrass::updateSpecies()
SpeciesMap::const_iterator it = sSpeciesTable.begin();
mSpecies = (*it).first;
}
- setTEImage(0, gImageList.getImage(sSpeciesTable[mSpecies]->mTextureID));
+ setTEImage(0, LLViewerTextureManager::getFetchedTexture(sSpeciesTable[mSpecies]->mTextureID, TRUE, FALSE, LLViewerTexture::LOD_TEXTURE));
}
@@ -165,16 +165,6 @@ void LLVOGrass::initClass()
grass_def->getFastAttributeUUID(texture_id_string, id);
newGrass->mTextureID = id;
- if (newGrass->mTextureID.isNull())
- {
- std::string textureName;
-
- static LLStdStringHandle texture_name_string = LLXmlTree::addAttributeString("texture_name");
- success &= grass_def->getFastAttributeString(texture_name_string, textureName);
- LLViewerImage* grass_image = gImageList.getImageFromFile(textureName);
- newGrass->mTextureID = grass_image->getID();
- }
-
static LLStdStringHandle blade_sizex_string = LLXmlTree::addAttributeString("blade_size_x");
success &= grass_def->getFastAttributeF32(blade_sizex_string, F32_val);
newGrass->mBladeSizeX = F32_val;
@@ -392,9 +382,11 @@ LLDrawable* LLVOGrass::createDrawable(LLPipeline *pipeline)
return mDrawable;
}
+static LLFastTimer::DeclareTimer FTM_UPDATE_GRASS("Update Grass");
+
BOOL LLVOGrass::updateGeometry(LLDrawable *drawable)
{
- LLFastTimer ftm(LLFastTimer::FTM_UPDATE_GRASS);
+ LLFastTimer ftm(FTM_UPDATE_GRASS);
dirtySpatialGroup();
plantBlades();
return TRUE;
diff --git a/indra/newview/llvograss.h b/indra/newview/llvograss.h
index 11b79d519c..124400d356 100644
--- a/indra/newview/llvograss.h
+++ b/indra/newview/llvograss.h
@@ -38,7 +38,7 @@
#include <map>
class LLSurfacePatch;
-class LLViewerImage;
+class LLViewerTexture;
class LLVOGrass : public LLAlphaObject
diff --git a/indra/newview/llvoground.cpp b/indra/newview/llvoground.cpp
index fe19e18151..ac2484ddfd 100644
--- a/indra/newview/llvoground.cpp
+++ b/indra/newview/llvoground.cpp
@@ -37,7 +37,6 @@
#include "llviewercontrol.h"
-#include "llagent.h"
#include "lldrawable.h"
#include "llface.h"
#include "llsky.h"
diff --git a/indra/newview/llvoground.h b/indra/newview/llvoground.h
index f485bd0aa4..af3fcd65d4 100644
--- a/indra/newview/llvoground.h
+++ b/indra/newview/llvoground.h
@@ -36,7 +36,7 @@
#include "stdtypes.h"
#include "v3color.h"
#include "v4coloru.h"
-#include "llviewerimage.h"
+#include "llviewertexture.h"
#include "llviewerobject.h"
class LLVOGround : public LLStaticViewerObject
diff --git a/indra/newview/llvoiceclient.cpp b/indra/newview/llvoiceclient.cpp
index 232885b3f6..182850f326 100644
--- a/indra/newview/llvoiceclient.cpp
+++ b/indra/newview/llvoiceclient.cpp
@@ -62,10 +62,14 @@
#include "llfirstuse.h"
#include "llviewerwindow.h"
#include "llviewercamera.h"
+#include "llvoavatarself.h"
#include "llfloaterfriends.h" //VIVOX, inorder to refresh communicate panel
#include "llfloaterchat.h" // for LLFloaterChat::addChat()
+// for Talk Button's state updating
+#include "llnearbychatbar.h"
+
// for base64 decoding
#include "apr_base64.h"
@@ -1103,58 +1107,61 @@ static void killGateway()
///////////////////////////////////////////////////////////////////////////////////////////////
-LLVoiceClient::LLVoiceClient()
-{
- gVoiceClient = this;
- mWriteInProgress = false;
- mAreaVoiceDisabled = false;
- mPTT = true;
- mUserPTTState = false;
- mMuteMic = false;
- mSessionTerminateRequested = false;
- mRelogRequested = false;
- mCommandCookie = 0;
- mCurrentParcelLocalID = 0;
- mLoginRetryCount = 0;
-
- mSpeakerVolume = 0;
- mMicVolume = 0;
-
- mAudioSession = NULL;
- mAudioSessionChanged = false;
-
- // Initial dirty state
- mSpatialCoordsDirty = false;
- mPTTDirty = true;
- mFriendsListDirty = true;
- mSpeakerVolumeDirty = true;
- mMicVolumeDirty = true;
- mBuddyListMapPopulated = false;
- mBlockRulesListReceived = false;
- mAutoAcceptRulesListReceived = false;
- mCaptureDeviceDirty = false;
- mRenderDeviceDirty = false;
-
- // Use default values for everything then call updateSettings() after preferences are loaded
- mVoiceEnabled = false;
- mUsePTT = true;
- mPTTIsToggle = false;
- mEarLocation = 0;
- mLipSyncEnabled = false;
+LLVoiceClient::LLVoiceClient() :
+ mState(stateDisabled),
+ mSessionTerminateRequested(false),
+ mRelogRequested(false),
+ mConnected(false),
+ mPump(NULL),
+
+ mTuningMode(false),
+ mTuningEnergy(0.0f),
+ mTuningMicVolume(0),
+ mTuningMicVolumeDirty(true),
+ mTuningSpeakerVolume(0),
+ mTuningSpeakerVolumeDirty(true),
+ mTuningExitState(stateDisabled),
+
+ mAreaVoiceDisabled(false),
+ mAudioSession(NULL),
+ mAudioSessionChanged(false),
+ mNextAudioSession(NULL),
+
+ mCurrentParcelLocalID(0),
+ mNumberOfAliases(0),
+ mCommandCookie(0),
+ mLoginRetryCount(0),
+
+ mBuddyListMapPopulated(false),
+ mBlockRulesListReceived(false),
+ mAutoAcceptRulesListReceived(false),
+ mCaptureDeviceDirty(false),
+ mRenderDeviceDirty(false),
+ mSpatialCoordsDirty(false),
+
+ mPTTDirty(true),
+ mPTT(true),
+ mUsePTT(true),
+ mPTTIsMiddleMouse(false),
+ mPTTKey(0),
+ mPTTIsToggle(false),
+ mUserPTTState(false),
+ mMuteMic(false),
+ mFriendsListDirty(true),
+
+ mEarLocation(0),
+ mSpeakerVolumeDirty(true),
+ mSpeakerMuteDirty(true),
+ mSpeakerVolume(0),
+ mMicVolume(0),
+ mMicVolumeDirty(true),
- mTuningMode = false;
- mTuningEnergy = 0.0f;
- mTuningMicVolume = 0;
- mTuningMicVolumeDirty = true;
- mTuningSpeakerVolume = 0;
- mTuningSpeakerVolumeDirty = true;
-
- // gMuteListp isn't set up at this point, so we defer this until later.
-// gMuteListp->addObserver(&mutelist_listener);
+ mVoiceEnabled(false),
+ mWriteInProgress(false),
- // stash the pump for later use
- // This now happens when init() is called instead.
- mPump = NULL;
+ mLipSyncEnabled(false)
+{
+ gVoiceClient = this;
#if LL_DARWIN || LL_LINUX || LL_SOLARIS
// HACK: THIS DOES NOT BELONG HERE
@@ -1503,6 +1510,7 @@ std::string LLVoiceClientStatusObserver::status2string(LLVoiceClientStatusObserv
CASE(STATUS_JOINED);
CASE(STATUS_LEFT_CHANNEL);
CASE(STATUS_VOICE_DISABLED);
+ CASE(STATUS_VOICE_ENABLED);
CASE(BEGIN_ERROR_STATUS);
CASE(ERROR_CHANNEL_FULL);
CASE(ERROR_CHANNEL_LOCKED);
@@ -4547,7 +4555,7 @@ void LLVoiceClient::messageEvent(
if(messageHeader.find("text/html") != std::string::npos)
{
- std::string rawMessage;
+ std::string message;
{
const std::string startMarker = "<body";
@@ -4559,7 +4567,7 @@ void LLVoiceClient::messageEvent(
std::string::size_type end;
// Default to displaying the raw string, so the message gets through.
- rawMessage = messageBody;
+ message = messageBody;
// Find the actual message text within the XML fragment
start = messageBody.find(startMarker);
@@ -4573,7 +4581,7 @@ void LLVoiceClient::messageEvent(
if(end != std::string::npos)
end -= start;
- rawMessage.assign(messageBody, start, end);
+ message.assign(messageBody, start, end);
}
else
{
@@ -4589,24 +4597,24 @@ void LLVoiceClient::messageEvent(
if(end != std::string::npos)
end -= start;
- rawMessage.assign(messageBody, start, end);
+ message.assign(messageBody, start, end);
}
}
}
-// LL_DEBUGS("Voice") << " raw message = \n" << rawMessage << LL_ENDL;
+// LL_DEBUGS("Voice") << " raw message = \n" << message << LL_ENDL;
// strip formatting tags
{
std::string::size_type start;
std::string::size_type end;
- while((start = rawMessage.find('<')) != std::string::npos)
+ while((start = message.find('<')) != std::string::npos)
{
- if((end = rawMessage.find('>', start + 1)) != std::string::npos)
+ if((end = message.find('>', start + 1)) != std::string::npos)
{
// Strip out the tag
- rawMessage.erase(start, (end + 1) - start);
+ message.erase(start, (end + 1) - start);
}
else
{
@@ -4622,31 +4630,31 @@ void LLVoiceClient::messageEvent(
// The text may contain text encoded with &lt;, &gt;, and &amp;
mark = 0;
- while((mark = rawMessage.find("&lt;", mark)) != std::string::npos)
+ while((mark = message.find("&lt;", mark)) != std::string::npos)
{
- rawMessage.replace(mark, 4, "<");
+ message.replace(mark, 4, "<");
mark += 1;
}
mark = 0;
- while((mark = rawMessage.find("&gt;", mark)) != std::string::npos)
+ while((mark = message.find("&gt;", mark)) != std::string::npos)
{
- rawMessage.replace(mark, 4, ">");
+ message.replace(mark, 4, ">");
mark += 1;
}
mark = 0;
- while((mark = rawMessage.find("&amp;", mark)) != std::string::npos)
+ while((mark = message.find("&amp;", mark)) != std::string::npos)
{
- rawMessage.replace(mark, 5, "&");
+ message.replace(mark, 5, "&");
mark += 1;
}
}
// strip leading/trailing whitespace (since we always seem to get a couple newlines)
- LLStringUtil::trim(rawMessage);
+ LLStringUtil::trim(message);
-// LL_DEBUGS("Voice") << " stripped message = \n" << rawMessage << LL_ENDL;
+// LL_DEBUGS("Voice") << " stripped message = \n" << message << LL_ENDL;
sessionState *session = findSession(sessionHandle);
if(session)
@@ -4670,14 +4678,12 @@ void LLVoiceClient::messageEvent(
quiet_chat = true;
// TODO: Question: Return busy mode response here? Or maybe when session is started instead?
}
-
- std::string fullMessage = std::string(": ") + rawMessage;
-
+
LL_DEBUGS("Voice") << "adding message, name " << session->mName << " session " << session->mIMSessionID << ", target " << session->mCallerID << LL_ENDL;
gIMMgr->addMessage(session->mIMSessionID,
session->mCallerID,
session->mName.c_str(),
- fullMessage.c_str(),
+ message.c_str(),
LLStringUtil::null, // default arg
IM_NOTHING_SPECIAL, // default arg
0, // default arg
@@ -4685,7 +4691,7 @@ void LLVoiceClient::messageEvent(
LLVector3::zero, // default arg
true); // prepend name and make it a link to the user's profile
- chat.mText = std::string("IM: ") + session->mName + std::string(": ") + rawMessage;
+ chat.mText = std::string("IM: ") + session->mName + std::string(": ") + message;
// If the chat should come in quietly (i.e. we're in busy mode), pretend it's from a local agent.
LLFloaterChat::addChat( chat, TRUE, quiet_chat );
}
@@ -5773,9 +5779,15 @@ void LLVoiceClient::setMuteMic(bool muted)
mMuteMic = muted;
}
+bool LLVoiceClient::getMuteMic() const
+{
+ return mMuteMic;
+}
+
void LLVoiceClient::setUserPTTState(bool ptt)
{
mUserPTTState = ptt;
+ if (LLNearbyChatBar::instanceExists()) LLNearbyChatBar::getInstance()->setPTTState(ptt);
}
bool LLVoiceClient::getUserPTTState()
@@ -5786,6 +5798,7 @@ bool LLVoiceClient::getUserPTTState()
void LLVoiceClient::toggleUserPTTState(void)
{
mUserPTTState = !mUserPTTState;
+ if (LLNearbyChatBar::instanceExists()) LLNearbyChatBar::getInstance()->setPTTState(mUserPTTState);
}
void LLVoiceClient::setVoiceEnabled(bool enabled)
@@ -5793,15 +5806,21 @@ void LLVoiceClient::setVoiceEnabled(bool enabled)
if (enabled != mVoiceEnabled)
{
mVoiceEnabled = enabled;
+ LLVoiceClientStatusObserver::EStatusType status;
+
if (enabled)
{
LLVoiceChannel::getCurrentVoiceChannel()->activate();
+ status = LLVoiceClientStatusObserver::STATUS_VOICE_ENABLED;
}
else
{
// Turning voice off looses your current channel -- this makes sure the UI isn't out of sync when you re-enable it.
LLVoiceChannel::getCurrentVoiceChannel()->deactivate();
+ status = LLVoiceClientStatusObserver::STATUS_VOICE_DISABLED;
}
+
+ notifyStatusObservers(status);
}
}
@@ -6901,12 +6920,12 @@ void LLVoiceClient::notifyFriendObservers()
void LLVoiceClient::lookupName(const LLUUID &id)
{
- BOOL is_group = FALSE;
+ gCacheName->get(id, FALSE, &LLVoiceClient::onAvatarNameLookup);
gCacheName->getNameFromUUID(id, is_group, onAvatarNameLookup);
}
//static
-void LLVoiceClient::onAvatarNameLookup(const LLUUID& id, const std::string& first, const std::string& last, BOOL is_group, void* user_data)
+void LLVoiceClient::onAvatarNameLookup(const LLUUID& id, const std::string& first, const std::string& last, BOOL is_group)
{
if(gVoiceClient)
{
diff --git a/indra/newview/llvoiceclient.h b/indra/newview/llvoiceclient.h
index cfc336b27d..fe99e787da 100644
--- a/indra/newview/llvoiceclient.h
+++ b/indra/newview/llvoiceclient.h
@@ -43,6 +43,7 @@ class LLVivoxProtocolParser;
#include "llframetimer.h"
#include "llviewerregion.h"
#include "llcallingcard.h" // for LLFriendObserver
+#include "m3math.h" // LLMatrix3
class LLVoiceClientParticipantObserver
{
@@ -64,6 +65,11 @@ public:
STATUS_JOINED,
STATUS_LEFT_CHANNEL,
STATUS_VOICE_DISABLED,
+
+ // Adding STATUS_VOICE_ENABLED as pair status for STATUS_VOICE_DISABLED
+ // See LLVoiceClient::setVoiceEnabled()
+ STATUS_VOICE_ENABLED,
+
BEGIN_ERROR_STATUS,
ERROR_CHANNEL_FULL,
ERROR_CHANNEL_LOCKED,
@@ -178,6 +184,7 @@ static void updatePosition(void);
void setMuteMic(bool muted); // Use this to mute the local mic (for when the client is minimized, etc), ignoring user PTT state.
+ bool getMuteMic() const;
void setUserPTTState(bool ptt);
bool getUserPTTState();
void toggleUserPTTState(void);
@@ -461,7 +468,7 @@ static void updatePosition(void);
void removeObserver(LLFriendObserver* observer);
void lookupName(const LLUUID &id);
- static void onAvatarNameLookup(const LLUUID& id, const std::string& first, const std::string& last, BOOL is_group, void* user_data);
+ static void onAvatarNameLookup(const LLUUID& id, const std::string& first, const std::string& last, BOOL is_group);
void avatarNameResolved(const LLUUID &id, const std::string &name);
typedef std::vector<std::string> deviceList;
@@ -727,7 +734,6 @@ static std::string nameFromsipURI(const std::string &uri);
bool mVoiceEnabled;
bool mWriteInProgress;
std::string mWriteString;
- size_t mWriteOffset;
LLTimer mUpdateTimer;
diff --git a/indra/newview/llvoicevisualizer.cpp b/indra/newview/llvoicevisualizer.cpp
index 5606398aaf..9bafc03a6d 100644
--- a/indra/newview/llvoicevisualizer.cpp
+++ b/indra/newview/llvoicevisualizer.cpp
@@ -42,9 +42,8 @@
#include "llvoicevisualizer.h"
#include "llviewercamera.h"
#include "llviewerobject.h"
-#include "llimagegl.h"
-#include "llviewerimage.h"
-#include "llviewerimagelist.h"
+#include "llviewertexture.h"
+#include "llviewertexturelist.h"
#include "llvoiceclient.h"
#include "llrender.h"
@@ -131,19 +130,19 @@ LLVoiceVisualizer::LLVoiceVisualizer( const U8 type )
const char* sound_level_img[] =
{
- "041ee5a0-cb6a-9ac5-6e49-41e9320507d5.j2c",
- "29de489d-0491-fb00-7dab-f9e686d31e83.j2c",
- "29de489d-0491-fb00-7dab-f9e686d31e83.j2c",
- "29de489d-0491-fb00-7dab-f9e686d31e83.j2c",
- "29de489d-0491-fb00-7dab-f9e686d31e83.j2c",
- "29de489d-0491-fb00-7dab-f9e686d31e83.j2c",
- "29de489d-0491-fb00-7dab-f9e686d31e83.j2c"
+ "voice_meter_dot.j2c",
+ "voice_meter_rings.j2c",
+ "voice_meter_rings.j2c",
+ "voice_meter_rings.j2c",
+ "voice_meter_rings.j2c",
+ "voice_meter_rings.j2c",
+ "voice_meter_rings.j2c"
};
for (int i=0; i<NUM_VOICE_SYMBOL_WAVES; i++)
{
mSoundSymbol.mWaveFadeOutStartTime [i] = mCurrentTime;
- mSoundSymbol.mTexture [i] = gImageList.getImageFromFile(sound_level_img[i], FALSE, TRUE);
+ mSoundSymbol.mTexture [i] = LLViewerTextureManager::getFetchedTextureFromFile(sound_level_img[i], FALSE, TRUE);
mSoundSymbol.mWaveActive [i] = false;
mSoundSymbol.mWaveOpacity [i] = 1.0f;
mSoundSymbol.mWaveExpansion [i] = 1.0f;
@@ -157,12 +156,12 @@ LLVoiceVisualizer::LLVoiceVisualizer( const U8 type )
setPreferences();
// Set up our listener to get updates on all prefs values we care about.
- gSavedSettings.getControl("LipSyncEnabled")->getSignal()->connect(boost::bind(&handleVoiceVisualizerPrefsChanged, _1));
- gSavedSettings.getControl("LipSyncOohAahRate")->getSignal()->connect(boost::bind(&handleVoiceVisualizerPrefsChanged, _1));
- gSavedSettings.getControl("LipSyncOoh")->getSignal()->connect(boost::bind(&handleVoiceVisualizerPrefsChanged, _1));
- gSavedSettings.getControl("LipSyncAah")->getSignal()->connect(boost::bind(&handleVoiceVisualizerPrefsChanged, _1));
- gSavedSettings.getControl("LipSyncOohPowerTransfer")->getSignal()->connect(boost::bind(&handleVoiceVisualizerPrefsChanged, _1));
- gSavedSettings.getControl("LipSyncAahPowerTransfer")->getSignal()->connect(boost::bind(&handleVoiceVisualizerPrefsChanged, _1));
+ gSavedSettings.getControl("LipSyncEnabled")->getSignal()->connect(boost::bind(&handleVoiceVisualizerPrefsChanged, _2));
+ gSavedSettings.getControl("LipSyncOohAahRate")->getSignal()->connect(boost::bind(&handleVoiceVisualizerPrefsChanged, _2));
+ gSavedSettings.getControl("LipSyncOoh")->getSignal()->connect(boost::bind(&handleVoiceVisualizerPrefsChanged, _2));
+ gSavedSettings.getControl("LipSyncAah")->getSignal()->connect(boost::bind(&handleVoiceVisualizerPrefsChanged, _2));
+ gSavedSettings.getControl("LipSyncOohPowerTransfer")->getSignal()->connect(boost::bind(&handleVoiceVisualizerPrefsChanged, _2));
+ gSavedSettings.getControl("LipSyncAahPowerTransfer")->getSignal()->connect(boost::bind(&handleVoiceVisualizerPrefsChanged, _2));
sPrefsInitialized = true;
}
diff --git a/indra/newview/llvoicevisualizer.h b/indra/newview/llvoicevisualizer.h
index 0cbf24b786..1887849300 100644
--- a/indra/newview/llvoicevisualizer.h
+++ b/indra/newview/llvoicevisualizer.h
@@ -121,7 +121,7 @@ class LLVoiceVisualizer : public LLHUDEffect
bool mWaveActive [ NUM_VOICE_SYMBOL_WAVES ];
F64 mWaveFadeOutStartTime [ NUM_VOICE_SYMBOL_WAVES ];
F32 mWaveOpacity [ NUM_VOICE_SYMBOL_WAVES ];
- LLPointer<LLImageGL> mTexture [ NUM_VOICE_SYMBOL_WAVES ];
+ LLPointer<LLViewerFetchedTexture> mTexture [ NUM_VOICE_SYMBOL_WAVES ];
bool mActive;
LLVector3 mPosition;
};
diff --git a/indra/newview/llvopartgroup.cpp b/indra/newview/llvopartgroup.cpp
index 29036f4947..38c9ce28c4 100644
--- a/indra/newview/llvopartgroup.cpp
+++ b/indra/newview/llvopartgroup.cpp
@@ -139,9 +139,10 @@ LLVector3 LLVOPartGroup::getCameraPosition() const
return gAgent.getCameraPositionAgent();
}
+static LLFastTimer::DeclareTimer FTM_UPDATE_PARTICLES("Update Particles");
BOOL LLVOPartGroup::updateGeometry(LLDrawable *drawable)
{
- LLFastTimer ftm(LLFastTimer::FTM_UPDATE_PARTICLES);
+ LLFastTimer ftm(FTM_UPDATE_PARTICLES);
dirtySpatialGroup();
@@ -416,12 +417,15 @@ void LLParticlePartition::addGeometryCount(LLSpatialGroup* group, U32& vertex_co
}
}
+static LLFastTimer::DeclareTimer FTM_REBUILD_GRASS_VB("Grass VB");
+static LLFastTimer::DeclareTimer FTM_REBUILD_PARTICLE_VB("Particle VB");
+
void LLParticlePartition::getGeometry(LLSpatialGroup* group)
{
LLMemType mt(LLMemType::MTYPE_SPACE_PARTITION);
LLFastTimer ftm(mDrawableType == LLPipeline::RENDER_TYPE_GRASS ?
- LLFastTimer::FTM_REBUILD_GRASS_VB :
- LLFastTimer::FTM_REBUILD_PARTICLE_VB);
+ FTM_REBUILD_GRASS_VB :
+ FTM_REBUILD_PARTICLE_VB);
std::sort(mFaceList.begin(), mFaceList.end(), LLFace::CompareDistanceGreater());
diff --git a/indra/newview/llvosky.cpp b/indra/newview/llvosky.cpp
index d4df141477..ae5992099d 100644
--- a/indra/newview/llvosky.cpp
+++ b/indra/newview/llvosky.cpp
@@ -49,7 +49,7 @@
#include "llglheaders.h"
#include "llsky.h"
#include "llviewercamera.h"
-#include "llviewerimagelist.h"
+#include "llviewertexturelist.h"
#include "llviewerobjectlist.h"
#include "llviewerregion.h"
#include "llworld.h"
@@ -212,8 +212,8 @@ void LLSkyTex::init()
for (S32 i = 0; i < 2; ++i)
{
- mImageGL[i] = new LLImageGL(FALSE);
- mImageGL[i]->setAddressMode(LLTexUnit::TAM_CLAMP);
+ mTexture[i] = LLViewerTextureManager::getLocalTexture(FALSE);
+ mTexture[i]->setAddressMode(LLTexUnit::TAM_CLAMP);
mImageRaw[i] = new LLImageRaw(sResolution, sResolution, sComponents);
initEmpty(i);
@@ -222,16 +222,16 @@ void LLSkyTex::init()
void LLSkyTex::cleanupGL()
{
- mImageGL[0] = NULL;
- mImageGL[1] = NULL;
+ mTexture[0] = NULL;
+ mTexture[1] = NULL;
}
void LLSkyTex::restoreGL()
{
for (S32 i = 0; i < 2; i++)
{
- mImageGL[i] = new LLImageGL(FALSE);
- mImageGL[i]->setAddressMode(LLTexUnit::TAM_CLAMP);
+ mTexture[i] = LLViewerTextureManager::getLocalTexture(FALSE);
+ mTexture[i]->setAddressMode(LLTexUnit::TAM_CLAMP);
}
}
@@ -289,13 +289,13 @@ void LLSkyTex::create(const F32 brightness)
void LLSkyTex::createGLImage(S32 which)
{
- mImageGL[which]->createGLTexture(0, mImageRaw[which]);
- mImageGL[which]->setAddressMode(LLTexUnit::TAM_CLAMP);
+ mTexture[which]->createGLTexture(0, mImageRaw[which]);
+ mTexture[which]->setAddressMode(LLTexUnit::TAM_CLAMP);
}
void LLSkyTex::bindTexture(BOOL curr)
{
- gGL.getTexUnit(0)->bind(mImageGL[getWhich(curr)]);
+ gGL.getTexUnit(0)->bind(mTexture[getWhich(curr)]);
}
/***************************************
@@ -376,11 +376,11 @@ LLVOSky::LLVOSky(const LLUUID &id, const LLPCode pcode, LLViewerRegion *regionp)
mSun.setIntensity(SUN_INTENSITY);
mMoon.setIntensity(0.1f * SUN_INTENSITY);
- mSunTexturep = gImageList.getImage(gSunTextureID, TRUE, TRUE);
+ mSunTexturep = LLViewerTextureManager::getFetchedTexture(gSunTextureID, TRUE, TRUE);
mSunTexturep->setAddressMode(LLTexUnit::TAM_CLAMP);
- mMoonTexturep = gImageList.getImage(gMoonTextureID, TRUE, TRUE);
+ mMoonTexturep = LLViewerTextureManager::getFetchedTexture(gMoonTextureID, TRUE, TRUE);
mMoonTexturep->setAddressMode(LLTexUnit::TAM_CLAMP);
- mBloomTexturep = gImageList.getImage(IMG_BLOOM1);
+ mBloomTexturep = LLViewerTextureManager::getFetchedTexture(IMG_BLOOM1);
mBloomTexturep->setNoDelete() ;
mBloomTexturep->setAddressMode(LLTexUnit::TAM_CLAMP);
@@ -390,7 +390,7 @@ LLVOSky::LLVOSky(const LLUUID &id, const LLPCode pcode, LLViewerRegion *regionp)
LLVOSky::~LLVOSky()
{
- // Don't delete images - it'll get deleted by gImageList on shutdown
+ // Don't delete images - it'll get deleted by gTextureList on shutdown
// This needs to be done for each texture
mCubeMap = NULL;
@@ -472,11 +472,11 @@ void LLVOSky::restoreGL()
{
mSkyTex[i].restoreGL();
}
- mSunTexturep = gImageList.getImage(gSunTextureID, TRUE, TRUE);
+ mSunTexturep = LLViewerTextureManager::getFetchedTexture(gSunTextureID, TRUE, TRUE);
mSunTexturep->setAddressMode(LLTexUnit::TAM_CLAMP);
- mMoonTexturep = gImageList.getImage(gMoonTextureID, TRUE, TRUE);
+ mMoonTexturep = LLViewerTextureManager::getFetchedTexture(gMoonTextureID, TRUE, TRUE);
mMoonTexturep->setAddressMode(LLTexUnit::TAM_CLAMP);
- mBloomTexturep = gImageList.getImage(IMG_BLOOM1);
+ mBloomTexturep = LLViewerTextureManager::getFetchedTexture(IMG_BLOOM1);
mBloomTexturep->setNoDelete() ;
mBloomTexturep->setAddressMode(LLTexUnit::TAM_CLAMP);
@@ -1231,6 +1231,8 @@ void LLVOSky::createDummyVertexBuffer()
}
}
+static LLFastTimer::DeclareTimer FTM_RENDER_FAKE_VBO_UPDATE("Fake VBO Update");
+
void LLVOSky::updateDummyVertexBuffer()
{
if(!LLVertexBuffer::sEnableVBOs)
@@ -1242,7 +1244,7 @@ void LLVOSky::updateDummyVertexBuffer()
return ;
}
- LLFastTimer t(LLFastTimer::FTM_RENDER_FAKE_VBO_UPDATE) ;
+ LLFastTimer t(FTM_RENDER_FAKE_VBO_UPDATE) ;
if(!mFace[FACE_DUMMY] || mFace[FACE_DUMMY]->mVertexBuffer.isNull())
createDummyVertexBuffer() ;
@@ -1255,10 +1257,11 @@ void LLVOSky::updateDummyVertexBuffer()
//----------------------------------
//end of fake vertex buffer updating
//----------------------------------
+static LLFastTimer::DeclareTimer FTM_GEO_SKY("Sky Geometry");
BOOL LLVOSky::updateGeometry(LLDrawable *drawable)
{
- LLFastTimer ftm(LLFastTimer::FTM_GEO_SKY);
+ LLFastTimer ftm(FTM_GEO_SKY);
if (mFace[FACE_REFLECTION] == NULL)
{
LLDrawPoolWater *poolp = (LLDrawPoolWater*) gPipeline.getPool(LLDrawPool::POOL_WATER);
diff --git a/indra/newview/llvosky.h b/indra/newview/llvosky.h
index 5e23065153..466cdfdcd0 100644
--- a/indra/newview/llvosky.h
+++ b/indra/newview/llvosky.h
@@ -36,7 +36,7 @@
#include "stdtypes.h"
#include "v3color.h"
#include "v4coloru.h"
-#include "llviewerimage.h"
+#include "llviewertexture.h"
#include "llviewerobject.h"
#include "llframetimer.h"
@@ -122,7 +122,7 @@ class LLSkyTex
private:
static S32 sResolution;
static S32 sComponents;
- LLPointer<LLImageGL> mImageGL[2];
+ LLPointer<LLViewerTexture> mTexture[2];
LLPointer<LLImageRaw> mImageRaw[2];
LLColor4 *mSkyData;
LLVector3 *mSkyDirs; // Cache of sky direction vectors
@@ -567,9 +567,9 @@ public:
BOOL isReflFace(const LLFace* face) const { return face == mFace[FACE_REFLECTION]; }
LLFace* getReflFace() const { return mFace[FACE_REFLECTION]; }
- LLViewerImage* getSunTex() const { return mSunTexturep; }
- LLViewerImage* getMoonTex() const { return mMoonTexturep; }
- LLViewerImage* getBloomTex() const { return mBloomTexturep; }
+ LLViewerTexture* getSunTex() const { return mSunTexturep; }
+ LLViewerTexture* getMoonTex() const { return mMoonTexturep; }
+ LLViewerTexture* getBloomTex() const { return mBloomTexturep; }
void forceSkyUpdate(void) { mForceUpdate = TRUE; }
public:
@@ -579,9 +579,9 @@ public:
protected:
~LLVOSky();
- LLPointer<LLViewerImage> mSunTexturep;
- LLPointer<LLViewerImage> mMoonTexturep;
- LLPointer<LLViewerImage> mBloomTexturep;
+ LLPointer<LLViewerFetchedTexture> mSunTexturep;
+ LLPointer<LLViewerFetchedTexture> mMoonTexturep;
+ LLPointer<LLViewerFetchedTexture> mBloomTexturep;
static S32 sResolution;
static S32 sTileResX;
diff --git a/indra/newview/llvosurfacepatch.cpp b/indra/newview/llvosurfacepatch.cpp
index 4980b50de4..157d719fcc 100644
--- a/indra/newview/llvosurfacepatch.cpp
+++ b/indra/newview/llvosurfacepatch.cpp
@@ -176,10 +176,11 @@ LLDrawable *LLVOSurfacePatch::createDrawable(LLPipeline *pipeline)
return mDrawable;
}
+static LLFastTimer::DeclareTimer FTM_UPDATE_TERRAIN("Update Terrain");
BOOL LLVOSurfacePatch::updateGeometry(LLDrawable *drawable)
{
- LLFastTimer ftm(LLFastTimer::FTM_UPDATE_TERRAIN);
+ LLFastTimer ftm(FTM_UPDATE_TERRAIN);
dirtySpatialGroup();
@@ -1028,9 +1029,10 @@ LLVertexBuffer* LLTerrainPartition::createVertexBuffer(U32 type_mask, U32 usage)
return new LLVertexBufferTerrain();
}
+static LLFastTimer::DeclareTimer FTM_REBUILD_TERRAIN_VB("Terrain VB");
void LLTerrainPartition::getGeometry(LLSpatialGroup* group)
{
- LLFastTimer ftm(LLFastTimer::FTM_REBUILD_TERRAIN_VB);
+ LLFastTimer ftm(FTM_REBUILD_TERRAIN_VB);
LLVertexBuffer* buffer = group->mVertexBuffer;
diff --git a/indra/newview/llvotextbubble.cpp b/indra/newview/llvotextbubble.cpp
index de69aac037..f5094c025e 100644
--- a/indra/newview/llvotextbubble.cpp
+++ b/indra/newview/llvotextbubble.cpp
@@ -39,11 +39,10 @@
#include "llprimitive.h"
#include "llrendersphere.h"
-#include "llagent.h"
#include "llbox.h"
#include "lldrawable.h"
#include "llface.h"
-#include "llviewerimagelist.h"
+#include "llviewertexturelist.h"
#include "llvolume.h"
#include "pipeline.h"
#include "llviewerregion.h"
@@ -125,7 +124,7 @@ void LLVOTextBubble::updateTextures(LLAgent &agent)
const LLTextureEntry *te = getTE(i);
F32 texel_area_ratio = fabs(te->mScaleS * te->mScaleT);
texel_area_ratio = llclamp(texel_area_ratio, .125f, 16.f);
- LLViewerImage *imagep = getTEImage(i);
+ LLViewerTexture *imagep = getTEImage(i);
if (imagep)
{
imagep->addTextureStats(mPixelArea / texel_area_ratio);
@@ -142,9 +141,9 @@ LLDrawable *LLVOTextBubble::createDrawable(LLPipeline *pipeline)
for (U32 i = 0; i < getNumTEs(); i++)
{
- LLViewerImage *imagep;
+ LLViewerTexture *imagep;
const LLTextureEntry *texture_entry = getTE(i);
- imagep = gImageList.getImage(texture_entry->getID());
+ imagep = LLViewerTextureManager::getFetchedTexture(texture_entry->getID());
mDrawable->addFace((LLFacePool*) NULL, imagep);
}
@@ -194,7 +193,7 @@ BOOL LLVOTextBubble::updateGeometry(LLDrawable *drawable)
{
LLFace *face = drawable->getFace(i);
face->setTEOffset(i);
- face->setTexture(LLViewerImage::sSmokeImagep);
+ face->setTexture(LLViewerFetchedTexture::sSmokeImagep);
face->setState(LLFace::FULLBRIGHT);
}
diff --git a/indra/newview/llvotree.cpp b/indra/newview/llvotree.cpp
index 3fd5054fd1..86d9f31d07 100644
--- a/indra/newview/llvotree.cpp
+++ b/indra/newview/llvotree.cpp
@@ -48,14 +48,14 @@
#include "lldrawable.h"
#include "llface.h"
#include "llviewercamera.h"
-#include "llviewerimagelist.h"
+#include "llviewertexturelist.h"
#include "llviewerobjectlist.h"
#include "llviewerregion.h"
#include "llworld.h"
#include "noise.h"
#include "pipeline.h"
#include "llspatialpartition.h"
-#include "llviewerwindow.h"
+#include "llnotifications.h"
extern LLPipeline gPipeline;
@@ -311,10 +311,10 @@ U32 LLVOTree::processUpdateMessage(LLMessageSystem *mesgsys,
//
// Load Species-Specific data
//
- mTreeImagep = gImageList.getImage(sSpeciesTable[mSpecies]->mTextureID);
+ mTreeImagep = LLViewerTextureManager::getFetchedTexture(sSpeciesTable[mSpecies]->mTextureID, TRUE, FALSE, LLViewerTexture::LOD_TEXTURE);
if (mTreeImagep)
{
- gGL.getTexUnit(0)->bind(mTreeImagep.get());
+ gGL.getTexUnit(0)->bind(mTreeImagep);
}
mBranchLength = sSpeciesTable[mSpecies]->mBranchLength;
mTrunkLength = sSpeciesTable[mSpecies]->mTrunkLength;
@@ -504,9 +504,11 @@ LLDrawable* LLVOTree::createDrawable(LLPipeline *pipeline)
const S32 LEAF_INDICES = 24;
const S32 LEAF_VERTICES = 16;
+static LLFastTimer::DeclareTimer FTM_UPDATE_TREE("Update Tree");
+
BOOL LLVOTree::updateGeometry(LLDrawable *drawable)
{
- LLFastTimer ftm(LLFastTimer::FTM_UPDATE_TREE);
+ LLFastTimer ftm(FTM_UPDATE_TREE);
if (mReferenceBuffer.isNull() || mDrawable->getFace(0)->mVertexBuffer.isNull())
{
diff --git a/indra/newview/llvotree.h b/indra/newview/llvotree.h
index 42a6d54f62..13817fa111 100644
--- a/indra/newview/llvotree.h
+++ b/indra/newview/llvotree.h
@@ -39,7 +39,7 @@
class LLFace;
class LLDrawPool;
-
+class LLViewerFetchedTexture;
class LLVOTree : public LLViewerObject
{
@@ -160,7 +160,7 @@ protected:
LLVector3 mWind;
LLPointer<LLVertexBuffer> mReferenceBuffer; //reference geometry for generating tree mesh
- LLPointer<LLViewerImage> mTreeImagep; // Pointer to proper tree image
+ LLPointer<LLViewerFetchedTexture> mTreeImagep; // Pointer to proper tree image
U8 mSpecies; // Species of tree
F32 mBranchLength; // Scale (length) of tree branches
@@ -184,7 +184,7 @@ protected:
// complete rebuild when not animating
LLVector3 mLastPosition;
LLQuaternion mLastRotation;
-
+
U32 mFrameCount;
typedef std::map<U32, TreeSpeciesData*> SpeciesMap;
diff --git a/indra/newview/llvotreenew.h b/indra/newview/llvotreenew.h
index 02f6d3a056..3fec5855ef 100644
--- a/indra/newview/llvotreenew.h
+++ b/indra/newview/llvotreenew.h
@@ -41,7 +41,7 @@
#include "llstrider.h"
#include "v2math.h"
#include "v3math.h"
-#include "llviewerimage.h"
+#include "llviewertexture.h"
class LLFace;
class LLDrawPool;
@@ -187,7 +187,7 @@ public:
//LLTreeParams mParams;
U8 mSpecies;
- LLPointer<LLViewerImage> mTreeImagep;
+ LLPointer<LLViewerTexture> mTreeImagep;
LLMatrix4 mTrunkFlareFrames[MAX_FLARE];
F32 mSegSplitsError[3];
U32 mRandOffset[MAX_LEVELS];
diff --git a/indra/newview/llvovolume.cpp b/indra/newview/llvovolume.cpp
index dd68733d98..940accdd06 100644
--- a/indra/newview/llvovolume.cpp
+++ b/indra/newview/llvovolume.cpp
@@ -47,7 +47,7 @@
#include "material_codes.h"
#include "message.h"
#include "object_flags.h"
-#include "llagent.h"
+#include "llagentconstants.h"
#include "lldrawable.h"
#include "lldrawpoolbump.h"
#include "llface.h"
@@ -59,7 +59,7 @@
#include "llsky.h"
#include "llviewercamera.h"
-#include "llviewerimagelist.h"
+#include "llviewertexturelist.h"
#include "llviewerregion.h"
#include "llviewertextureanim.h"
#include "llworld.h"
@@ -72,13 +72,16 @@ const F32 FORCE_CULL_AREA = 8.f;
const S32 MAX_SCULPT_REZ = 128;
BOOL gAnimateTextures = TRUE;
-extern BOOL gHideSelectedObjects;
+//extern BOOL gHideSelectedObjects;
F32 LLVOVolume::sLODFactor = 1.f;
F32 LLVOVolume::sLODSlopDistanceFactor = 0.5f; //Changing this to zero, effectively disables the LOD transition slop
F32 LLVOVolume::sDistanceFactor = 1.0f;
S32 LLVOVolume::sNumLODChanges = 0;
+static LLFastTimer::DeclareTimer FTM_GEN_TRIANGLES("Generate Triangles");
+static LLFastTimer::DeclareTimer FTM_GEN_VOLUME("Generate Volumes");
+
LLVOVolume::LLVOVolume(const LLUUID &id, const LLPCode pcode, LLViewerRegion *regionp)
: LLViewerObject(id, pcode, regionp),
mVolumeImpl(NULL)
@@ -427,7 +430,7 @@ void LLVOVolume::updateTextures()
return;
}
- if (LLViewerImage::sDontLoadVolumeTextures || mDrawable.isNull()) // || !mDrawable->isVisible())
+ if (LLViewerTexture::sDontLoadVolumeTextures || mDrawable.isNull()) // || !mDrawable->isVisible())
{
return;
}
@@ -443,7 +446,7 @@ void LLVOVolume::updateTextures()
{
LLFace* face = mDrawable->getFace(i);
const LLTextureEntry *te = face->getTextureEntry();
- LLViewerImage *imagep = face->getTexture();
+ LLViewerTexture *imagep = face->getTexture();
if (!imagep || !te ||
face->mExtents[0] == face->mExtents[1])
{
@@ -456,7 +459,7 @@ void LLVOVolume::updateTextures()
{
F32 area = (F32) LLViewerCamera::getInstance()->getScreenPixelArea();
vsize = area;
- imagep->setBoostLevel(LLViewerImage::BOOST_HUD);
+ imagep->setBoostLevel(LLViewerTexture::BOOST_HUD);
face->setPixelArea(area); // treat as full screen
}
else
@@ -486,10 +489,14 @@ void LLVOVolume::updateTextures()
}
else if (gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_TEXTURE_PRIORITY))
{
- F32 pri = imagep->getDecodePriority();
- pri = llmax(pri, 0.0f);
- if (pri < min_vsize) min_vsize = pri;
- if (pri > max_vsize) max_vsize = pri;
+ LLViewerFetchedTexture* img = LLViewerTextureManager::staticCastToFetchedTexture(imagep) ;
+ if(img)
+ {
+ F32 pri = img->getDecodePriority();
+ pri = llmax(pri, 0.0f);
+ if (pri < min_vsize) min_vsize = pri;
+ if (pri > max_vsize) max_vsize = pri;
+ }
}
else if (gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_FACE_AREA))
{
@@ -503,7 +510,7 @@ void LLVOVolume::updateTextures()
{
LLSculptParams *sculpt_params = (LLSculptParams *)getParameterEntry(LLNetworkData::PARAMS_SCULPT);
LLUUID id = sculpt_params->getSculptTexture();
- mSculptTexture = gImageList.getImage(id);
+ mSculptTexture = LLViewerTextureManager::getFetchedTexture(id, TRUE, FALSE, LLViewerTexture::LOD_TEXTURE);
if (mSculptTexture.notNull())
{
S32 lod = llmin(mLOD, 3);
@@ -511,7 +518,8 @@ void LLVOVolume::updateTextures()
F32 tex_size = lodf * MAX_SCULPT_REZ;
mSculptTexture->addTextureStats(2.f * tex_size * tex_size);
mSculptTexture->setBoostLevel(llmax((S32)mSculptTexture->getBoostLevel(),
- (S32)LLViewerImage::BOOST_SCULPTED));
+ (S32)LLViewerTexture::BOOST_SCULPTED));
+ mSculptTexture->setForSculpt() ;
}
S32 texture_discard = mSculptTexture->getDiscardLevel(); //try to match the texture
@@ -624,7 +632,7 @@ void LLVOVolume::setScale(const LLVector3 &scale, BOOL damped)
LLFace* LLVOVolume::addFace(S32 f)
{
const LLTextureEntry* te = getTE(f);
- LLViewerImage* imagep = getTEImage(f);
+ LLViewerTexture* imagep = getTEImage(f);
return mDrawable->addFace(te, imagep);
}
@@ -700,7 +708,7 @@ BOOL LLVOVolume::setVolume(const LLVolumeParams &volume_params, const S32 detail
if (isSculpted())
{
- mSculptTexture = gImageList.getImage(volume_params.getSculptID());
+ mSculptTexture = LLViewerTextureManager::getFetchedTexture(volume_params.getSculptID(), TRUE, FALSE, LLViewerTexture::LOD_TEXTURE);
if (mSculptTexture.notNull())
{
sculpt();
@@ -781,6 +789,11 @@ void LLVOVolume::sculpt()
sculpt_width = 0;
sculpt_height = 0;
sculpt_data = NULL ;
+
+ if(LLViewerTextureManager::sTesterp)
+ {
+ LLViewerTextureManager::sTesterp->updateGrayTextureBinding();
+ }
}
else
{
@@ -789,6 +802,11 @@ void LLVOVolume::sculpt()
<< " < " << sculpt_height << " x " << sculpt_width << " x " <<sculpt_components << llendl;
sculpt_data = raw_image->getData();
+
+ if(LLViewerTextureManager::sTesterp)
+ {
+ mSculptTexture->updateBindStatsForTester() ;
+ }
}
getVolume()->sculpt(sculpt_width, sculpt_height, sculpt_components, sculpt_data, discard_level);
}
@@ -923,17 +941,20 @@ void LLVOVolume::updateFaceFlags()
}
}
-void LLVOVolume::setParent(LLViewerObject* parent)
+BOOL LLVOVolume::setParent(LLViewerObject* parent)
{
+ BOOL ret = FALSE ;
if (parent != getParent())
{
- LLViewerObject::setParent(parent);
- if (mDrawable)
+ ret = LLViewerObject::setParent(parent);
+ if (ret && mDrawable)
{
gPipeline.markMoved(mDrawable);
gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_VOLUME, TRUE);
}
}
+
+ return ret ;
}
// NOTE: regenFaces() MUST be followed by genTriangles()!
@@ -1112,15 +1133,18 @@ void LLVOVolume::updateRelativeXform()
}
}
+static LLFastTimer::DeclareTimer FTM_GEN_FLEX("Generate Flexies");
+static LLFastTimer::DeclareTimer FTM_UPDATE_PRIMITIVES("Update Primitives");
+
BOOL LLVOVolume::updateGeometry(LLDrawable *drawable)
{
- LLFastTimer t(LLFastTimer::FTM_UPDATE_PRIMITIVES);
+ LLFastTimer t(FTM_UPDATE_PRIMITIVES);
if (mVolumeImpl != NULL)
{
BOOL res;
{
- LLFastTimer t(LLFastTimer::FTM_GEN_FLEX);
+ LLFastTimer t(FTM_GEN_FLEX);
res = mVolumeImpl->doUpdateGeometry(drawable);
}
updateFaceFlags();
@@ -1144,14 +1168,14 @@ BOOL LLVOVolume::updateGeometry(LLDrawable *drawable)
if (mVolumeChanged)
{
- LLFastTimer ftm(LLFastTimer::FTM_GEN_VOLUME);
+ LLFastTimer ftm(FTM_GEN_VOLUME);
LLVolumeParams volume_params = getVolume()->getParams();
setVolume(volume_params, 0);
drawable->setState(LLDrawable::REBUILD_VOLUME);
}
{
- LLFastTimer t(LLFastTimer::FTM_GEN_TRIANGLES);
+ LLFastTimer t(FTM_GEN_TRIANGLES);
regenFaces();
genBBoxes(FALSE);
}
@@ -1168,7 +1192,7 @@ BOOL LLVOVolume::updateGeometry(LLDrawable *drawable)
old_volumep = NULL ;
{
- LLFastTimer ftm(LLFastTimer::FTM_GEN_VOLUME);
+ LLFastTimer ftm(FTM_GEN_VOLUME);
LLVolumeParams volume_params = getVolume()->getParams();
setVolume(volume_params, 0);
}
@@ -1186,7 +1210,7 @@ BOOL LLVOVolume::updateGeometry(LLDrawable *drawable)
drawable->setState(LLDrawable::REBUILD_VOLUME); // for face->genVolumeTriangles()
{
- LLFastTimer t(LLFastTimer::FTM_GEN_TRIANGLES);
+ LLFastTimer t(FTM_GEN_TRIANGLES);
if (new_num_faces != old_num_faces)
{
regenFaces();
@@ -1200,7 +1224,7 @@ BOOL LLVOVolume::updateGeometry(LLDrawable *drawable)
{
compiled = TRUE;
// All it did was move or we changed the texture coordinate offset
- LLFastTimer t(LLFastTimer::FTM_GEN_TRIANGLES);
+ LLFastTimer t(FTM_GEN_TRIANGLES);
genBBoxes(FALSE);
}
@@ -1243,7 +1267,7 @@ BOOL LLVOVolume::isRootEdit() const
return TRUE;
}
-void LLVOVolume::setTEImage(const U8 te, LLViewerImage *imagep)
+void LLVOVolume::setTEImage(const U8 te, LLViewerTexture *imagep)
{
BOOL changed = (mTEImages[te] != imagep);
LLViewerObject::setTEImage(te, imagep);
@@ -1735,7 +1759,7 @@ void LLVOVolume::generateSilhouette(LLSelectNode* nodep, const LLVector3& view_p
trans_mat.translate(getRegion()->getOriginAgent());
}
- volume->generateSilhouetteVertices(nodep->mSilhouetteVertices, nodep->mSilhouetteNormals, nodep->mSilhouetteSegments, view_vector, trans_mat, mRelativeXformInvTrans);
+ volume->generateSilhouetteVertices(nodep->mSilhouetteVertices, nodep->mSilhouetteNormals, nodep->mSilhouetteSegments, view_vector, trans_mat, mRelativeXformInvTrans, nodep->getTESelectMask());
nodep->mSilhouetteExists = TRUE;
}
@@ -1977,10 +2001,9 @@ BOOL LLVOVolume::lineSegmentIntersect(const LLVector3& start, const LLVector3& e
LLVector3* intersection,LLVector2* tex_coord, LLVector3* normal, LLVector3* bi_normal)
{
- if (!mbCanSelect ||
- (gHideSelectedObjects && isSelected()) ||
- mDrawable->isDead() ||
- !gPipeline.hasRenderType(mDrawable->getRenderType()))
+ if (!mbCanSelect
+ || mDrawable->isDead()
+ || !gPipeline.hasRenderType(mDrawable->getRenderType()))
{
return FALSE;
}
@@ -2043,7 +2066,7 @@ BOOL LLVOVolume::lineSegmentIntersect(const LLVector3& start, const LLVector3& e
{
LLFace* face = mDrawable->getFace(face_hit);
- if (pick_transparent || !face->getTexture() || face->getTexture()->getMask(face->surfaceToTexture(tc, p, n)))
+ if (pick_transparent || !face->getTexture() || !face->getTexture()->hasGLTexture() || face->getTexture()->getMask(face->surfaceToTexture(tc, p, n)))
{
v_end = p;
if (face_hitp != NULL)
@@ -2120,7 +2143,7 @@ void LLVolumeGeometryManager::registerFace(LLSpatialGroup* group, LLFace* facep,
{
LLMemType mt(LLMemType::MTYPE_SPACE_PARTITION);
- if (facep->getViewerObject()->isSelected() && gHideSelectedObjects)
+ if (facep->getViewerObject()->isSelected() && LLSelectMgr::getInstance()->mHideSelectedObjects)
{
return;
}
@@ -2154,7 +2177,7 @@ void LLVolumeGeometryManager::registerFace(LLSpatialGroup* group, LLFace* facep,
U8 bump = (type == LLRenderPass::PASS_BUMP ? facep->getTextureEntry()->getBumpmap() : 0);
- LLViewerImage* tex = facep->getTexture();
+ LLViewerTexture* tex = facep->getTexture();
U8 glow = 0;
@@ -2218,6 +2241,9 @@ void LLVolumeGeometryManager::getGeometry(LLSpatialGroup* group)
}
+static LLFastTimer::DeclareTimer FTM_REBUILD_VOLUME_VB("Volume");
+static LLFastTimer::DeclareTimer FTM_REBUILD_VBO("VBO Rebuilt");
+
void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group)
{
if (LLPipeline::sSkipUpdate)
@@ -2236,8 +2262,8 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group)
{
if (group->isState(LLSpatialGroup::MESH_DIRTY) && !LLPipeline::sDelayVBUpdate)
{
- LLFastTimer ftm(LLFastTimer::FTM_REBUILD_VBO);
- LLFastTimer ftm2(LLFastTimer::FTM_REBUILD_VOLUME_VB);
+ LLFastTimer ftm(FTM_REBUILD_VBO);
+ LLFastTimer ftm2(FTM_REBUILD_VOLUME_VB);
rebuildMesh(group);
}
@@ -2245,9 +2271,9 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group)
}
group->mBuilt = 1.f;
- LLFastTimer ftm(LLFastTimer::FTM_REBUILD_VBO);
+ LLFastTimer ftm(FTM_REBUILD_VBO);
- LLFastTimer ftm2(LLFastTimer::FTM_REBUILD_VOLUME_VB);
+ LLFastTimer ftm2(FTM_REBUILD_VOLUME_VB);
group->clearDrawMap();
@@ -2305,7 +2331,7 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group)
if (facep->hasGeometry() && facep->mPixelArea > FORCE_CULL_AREA)
{
const LLTextureEntry* te = facep->getTextureEntry();
- LLViewerImage* tex = facep->getTexture();
+ LLViewerTexture* tex = facep->getTexture();
if (facep->isState(LLFace::TEXTURE_ANIM))
{
@@ -2553,7 +2579,7 @@ void LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, std::
LLSpatialGroup::buffer_map_t buffer_map;
- LLViewerImage* last_tex = NULL;
+ LLViewerTexture* last_tex = NULL;
S32 buffer_index = 0;
if (distance_sort)
@@ -2565,7 +2591,7 @@ void LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, std::
{
//pull off next face
LLFace* facep = *face_iter;
- LLViewerImage* tex = facep->getTexture();
+ LLViewerTexture* tex = facep->getTexture();
if (distance_sort)
{
diff --git a/indra/newview/llvovolume.h b/indra/newview/llvovolume.h
index 9b4e715194..d343d4db74 100644
--- a/indra/newview/llvovolume.h
+++ b/indra/newview/llvovolume.h
@@ -34,9 +34,11 @@
#define LL_LLVOVOLUME_H
#include "llviewerobject.h"
-#include "llviewerimage.h"
+#include "llviewertexture.h"
#include "llframetimer.h"
#include "llapr.h"
+#include "m3math.h" // LLMatrix3
+#include "m4math.h" // LLMatrix4
#include <map>
class LLViewerTextureAnim;
@@ -105,7 +107,7 @@ public:
/*virtual*/ BOOL isHUDAttachment() const;
void generateSilhouette(LLSelectNode* nodep, const LLVector3& view_point);
- /*virtual*/ void setParent(LLViewerObject* parent);
+ /*virtual*/ BOOL setParent(LLViewerObject* parent);
S32 getLOD() const { return mLOD; }
const LLVector3 getPivotPositionAgent() const;
const LLMatrix4& getRelativeXform() const { return mRelativeXform; }
@@ -151,7 +153,7 @@ public:
/*virtual*/ void setScale(const LLVector3 &scale, BOOL damped);
- /*virtual*/ void setTEImage(const U8 te, LLViewerImage *imagep);
+ /*virtual*/ void setTEImage(const U8 te, LLViewerTexture *imagep);
/*virtual*/ S32 setTETexture(const U8 te, const LLUUID &uuid);
/*virtual*/ S32 setTEColor(const U8 te, const LLColor3 &color);
/*virtual*/ S32 setTEColor(const U8 te, const LLColor4 &color);
@@ -235,7 +237,7 @@ private:
BOOL mVolumeChanged;
F32 mVObjRadius;
LLVolumeInterface *mVolumeImpl;
- LLPointer<LLViewerImage> mSculptTexture;
+ LLPointer<LLViewerFetchedTexture> mSculptTexture;
// statics
public:
diff --git a/indra/newview/llvowater.cpp b/indra/newview/llvowater.cpp
index d23c746b75..e2357957ab 100644
--- a/indra/newview/llvowater.cpp
+++ b/indra/newview/llvowater.cpp
@@ -37,7 +37,6 @@
#include "imageids.h"
#include "llviewercontrol.h"
-#include "llagent.h"
#include "lldrawable.h"
#include "lldrawpoolwater.h"
#include "llface.h"
@@ -45,7 +44,7 @@
#include "llsurface.h"
#include "llvosky.h"
#include "llviewercamera.h"
-#include "llviewerimagelist.h"
+#include "llviewertexturelist.h"
#include "llviewerregion.h"
#include "llworld.h"
#include "pipeline.h"
@@ -139,9 +138,11 @@ LLDrawable *LLVOWater::createDrawable(LLPipeline *pipeline)
return mDrawable;
}
+static LLFastTimer::DeclareTimer FTM_UPDATE_WATER("Update Water");
+
BOOL LLVOWater::updateGeometry(LLDrawable *drawable)
{
- LLFastTimer ftm(LLFastTimer::FTM_UPDATE_WATER);
+ LLFastTimer ftm(FTM_UPDATE_WATER);
LLFace *face;
if (drawable->getNumFaces() < 1)
diff --git a/indra/newview/llvowater.h b/indra/newview/llvowater.h
index cdda48f6f2..28a5633c58 100644
--- a/indra/newview/llvowater.h
+++ b/indra/newview/llvowater.h
@@ -34,7 +34,7 @@
#define LL_VOWATER_H
#include "llviewerobject.h"
-#include "llviewerimage.h"
+#include "llviewertexture.h"
#include "v2math.h"
const U32 N_RES = 16; //32 // number of subdivisions of wave tile
diff --git a/indra/newview/llvowlsky.cpp b/indra/newview/llvowlsky.cpp
index abd25e6598..8621e5e1d9 100644
--- a/indra/newview/llvowlsky.cpp
+++ b/indra/newview/llvowlsky.cpp
@@ -307,9 +307,11 @@ void LLVOWLSky::restoreGL()
gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_ALL, TRUE);
}
+static LLFastTimer::DeclareTimer FTM_GEO_SKY("Sky Geometry");
+
BOOL LLVOWLSky::updateGeometry(LLDrawable * drawable)
{
- LLFastTimer ftm(LLFastTimer::FTM_GEO_SKY);
+ LLFastTimer ftm(FTM_GEO_SKY);
LLStrider<LLVector3> vertices;
LLStrider<LLVector2> texCoords;
LLStrider<U16> indices;
diff --git a/indra/newview/llwatchdog.h b/indra/newview/llwatchdog.h
index ed7d5bdcfb..79398c434a 100644
--- a/indra/newview/llwatchdog.h
+++ b/indra/newview/llwatchdog.h
@@ -64,9 +64,10 @@ public:
/* virtual */ bool isAlive() const;
/* virtual */ void reset();
- /* virtual */ void start(const std::string& state);
+ /* virtual */ void start() { start(""); }
/* virtual */ void stop();
+ void start(const std::string& state);
void setTimeout(F32 d);
void ping(const std::string& state);
const std::string& getState() {return mPingState; }
diff --git a/indra/newview/llwaterparammanager.cpp b/indra/newview/llwaterparammanager.cpp
index 50e407739b..3661be500b 100644
--- a/indra/newview/llwaterparammanager.cpp
+++ b/indra/newview/llwaterparammanager.cpp
@@ -39,6 +39,7 @@
#include "pipeline.h"
#include "llsky.h"
+#include "llfloaterreg.h"
#include "llsliderctrl.h"
#include "llspinctrl.h"
#include "llcheckboxctrl.h"
@@ -262,17 +263,20 @@ void LLWaterParamManager::updateShaderUniforms(LLGLSLShader * shader)
}
}
+static LLFastTimer::DeclareTimer FTM_UPDATE_WLPARAM("Update Windlight Params");
+
void LLWaterParamManager::update(LLViewerCamera * cam)
{
- LLFastTimer ftm(LLFastTimer::FTM_UPDATE_WLPARAM);
+ LLFastTimer ftm(FTM_UPDATE_WLPARAM);
// update the shaders and the menu
propagateParameters();
// sync menus if they exist
- if(LLFloaterWater::isOpen())
+ LLFloaterWater* waterfloater = LLFloaterReg::findTypedInstance<LLFloaterWater>("env_water");
+ if(waterfloater)
{
- LLFloaterWater::instance()->syncMenu();
+ waterfloater->syncMenu();
}
stop_glerror();
diff --git a/indra/newview/llwaterparamset.cpp b/indra/newview/llwaterparamset.cpp
index a26ccedfb2..3e97f9dbef 100644
--- a/indra/newview/llwaterparamset.cpp
+++ b/indra/newview/llwaterparamset.cpp
@@ -39,7 +39,7 @@
#include "llwaterparammanager.h"
#include "lluictrlfactory.h"
#include "llsliderctrl.h"
-#include "llviewerimagelist.h"
+#include "llviewertexturelist.h"
#include "llviewercontrol.h"
#include "lluuid.h"
diff --git a/indra/newview/llwearable.cpp b/indra/newview/llwearable.cpp
index f705531723..0d3dd10a01 100644
--- a/indra/newview/llwearable.cpp
+++ b/indra/newview/llwearable.cpp
@@ -32,92 +32,27 @@
#include "llviewerprecompiledheaders.h"
-#include "imageids.h"
-#include "llassetstorage.h"
-#include "lldbstrings.h"
-#include "lldir.h"
-#include "llquantize.h"
-
#include "llagent.h"
-#include "llassetuploadresponders.h"
-#include "llviewerwindow.h"
+#include "llagentwearables.h"
#include "llfloatercustomize.h"
+#include "llviewertexturelist.h"
#include "llinventorymodel.h"
-#include "llviewerimagelist.h"
-#include "llviewerinventory.h"
#include "llviewerregion.h"
#include "llvoavatar.h"
+#include "llvoavatarself.h"
+#include "llvoavatardefines.h"
#include "llwearable.h"
+#include "lldictionary.h"
+#include "lltrans.h"
using namespace LLVOAvatarDefines;
// static
S32 LLWearable::sCurrentDefinitionVersion = 1;
-// static
-const std::string LLWearable::sTypeName[ WT_COUNT+1 ] =
-{
- "shape",
- "skin",
- "hair",
- "eyes",
- "shirt",
- "pants",
- "shoes",
- "socks",
- "jacket",
- "gloves",
- "undershirt",
- "underpants",
- "skirt",
- "invalid"
-};
-
-// static
-const std::string LLWearable::sTypeLabel[ WT_COUNT+1 ] =
-{
- "Shape",
- "Skin",
- "Hair",
- "Eyes",
- "Shirt",
- "Pants",
- "Shoes",
- "Socks",
- "Jacket",
- "Gloves",
- "Undershirt",
- "Underpants",
- "Skirt",
- "invalid"
-};
-
-
-// static
-LLAssetType::EType LLWearable::typeToAssetType(EWearableType wearable_type)
-{
- switch( wearable_type )
- {
- case WT_SHAPE:
- case WT_SKIN:
- case WT_HAIR:
- case WT_EYES:
- return LLAssetType::AT_BODYPART;
- case WT_SHIRT:
- case WT_PANTS:
- case WT_SHOES:
- case WT_SOCKS:
- case WT_JACKET:
- case WT_GLOVES:
- case WT_UNDERSHIRT:
- case WT_UNDERPANTS:
- case WT_SKIRT:
- return LLAssetType::AT_CLOTHING;
- default:
- return LLAssetType::AT_NONE;
- }
-}
-
+// Private local functions
+static std::string terse_F32_to_string(F32 f);
+static std::string asset_id_to_filename(const LLUUID &asset_id);
LLWearable::LLWearable(const LLTransactionID& transaction_id) :
mDefinitionVersion(LLWearable::sCurrentDefinitionVersion),
@@ -139,56 +74,22 @@ LLWearable::~LLWearable()
{
}
-
-// static
-EWearableType LLWearable::typeNameToType( const std::string& type_name )
+const std::string& LLWearable::getTypeLabel() const
{
- for( S32 i = 0; i < WT_COUNT; i++ )
- {
- if( type_name == LLWearable::sTypeName[ i ] )
- {
- return (EWearableType)i;
- }
- }
- return WT_INVALID;
+ return LLWearableDictionary::getTypeLabel(mType);
}
-
-std::string terse_F32_to_string( F32 f )
+const std::string& LLWearable::getTypeName() const
{
- std::string r = llformat( "%.2f", f );
-
- // "1.20" -> "1.2"
- // "24.00" -> "24."
- S32 len = r.length();
- while( len > 0 && '0' == r[len - 1] )
- {
- r.erase(len-1, 1);
- len--;
- }
-
- if( '.' == r[len - 1] )
- {
- // "24." -> "24"
- r.erase(len-1, 1);
- }
- else
- if( ('-' == r[0]) && ('0' == r[1]) )
- {
- // "-0.59" -> "-.59"
- r.erase(1, 1);
- }
- else
- if( '0' == r[0] )
- {
- // "0.59" -> ".59"
- r.erase(0, 1);
- }
+ return LLWearableDictionary::getTypeName(mType);
+}
- return r;
+LLAssetType::EType LLWearable::getAssetType() const
+{
+ return LLWearableDictionary::getAssetType(mType);
}
-BOOL LLWearable::exportFile( LLFILE* file )
+BOOL LLWearable::exportFile(LLFILE* file) const
{
// header and version
if( fprintf( file, "LLWearable version %d\n", mDefinitionVersion ) < 0 )
@@ -234,7 +135,7 @@ BOOL LLWearable::exportFile( LLFILE* file )
return FALSE;
}
- for (param_map_t::iterator iter = mVisualParamMap.begin();
+ for (param_map_t::const_iterator iter = mVisualParamMap.begin();
iter != mVisualParamMap.end(); ++iter)
{
S32 param_id = iter->first;
@@ -252,22 +153,18 @@ BOOL LLWearable::exportFile( LLFILE* file )
return FALSE;
}
- for (te_map_t::iterator iter = mTEMap.begin();
- iter != mTEMap.end(); ++iter)
+ for (te_map_t::const_iterator iter = mTEMap.begin(); iter != mTEMap.end(); ++iter)
{
S32 te = iter->first;
- LLUUID& image_id = iter->second;
+ const LLUUID& image_id = iter->second.getID();
if( fprintf( file, "%d %s\n", te, image_id.asString().c_str()) < 0 )
{
return FALSE;
}
}
-
return TRUE;
}
-
-
BOOL LLWearable::importFile( LLFILE* file )
{
// *NOTE: changing the type or size of this buffer will require
@@ -453,7 +350,8 @@ BOOL LLWearable::importFile( LLFILE* file )
return FALSE;
}
- mTEMap[te] = LLUUID(text_buffer );
+ //TODO: check old values
+ mTEMap[te] = LLLocalTextureObject(NULL, NULL, NULL, LLUUID(text_buffer));
}
return TRUE;
@@ -463,7 +361,7 @@ BOOL LLWearable::importFile( LLFILE* file )
// Avatar parameter and texture definitions can change over time.
// This function returns true if parameters or textures have been added or removed
// since this wearable was created.
-BOOL LLWearable::isOldVersion()
+BOOL LLWearable::isOldVersion() const
{
LLVOAvatar* avatar = gAgent.getAvatarObject();
llassert( avatar );
@@ -506,7 +404,7 @@ BOOL LLWearable::isOldVersion()
S32 te_count = 0;
for( S32 te = 0; te < TEX_NUM_INDICES; te++ )
{
- if( LLVOAvatar::getTEWearableType((ETextureIndex) te ) == mType )
+ if (LLVOAvatarDictionary::getTEWearableType((ETextureIndex) te) == mType)
{
te_count++;
if( !is_in_map(mTEMap, te ) )
@@ -530,7 +428,7 @@ BOOL LLWearable::isOldVersion()
// * If parameters or textures have been ADDED since the wearable was created,
// they are taken to have default values, so we consider the wearable clean
// only if those values are the same as the defaults.
-BOOL LLWearable::isDirty()
+BOOL LLWearable::isDirty() const
{
LLVOAvatar* avatar = gAgent.getAvatarObject();
llassert( avatar );
@@ -560,18 +458,23 @@ BOOL LLWearable::isDirty()
for( S32 te = 0; te < TEX_NUM_INDICES; te++ )
{
- if( LLVOAvatar::getTEWearableType((ETextureIndex) te ) == mType )
+ if (LLVOAvatarDictionary::getTEWearableType((ETextureIndex) te) == mType)
{
- LLViewerImage* avatar_image = avatar->getTEImage( te );
+ LLViewerTexture* avatar_image = avatar->getTEImage( te );
if( !avatar_image )
{
llassert( 0 );
continue;
}
- const LLUUID& image_id = get_if_there(mTEMap, te, LLVOAvatar::getDefaultTEImageID((ETextureIndex) te ) );
- if( avatar_image->getID() != image_id )
+
+ te_map_t::const_iterator iter = mTEMap.find(te);
+ if(iter != mTEMap.end())
{
- return TRUE;
+ const LLUUID& image_id = iter->second.getID();
+ if (avatar_image->getID() != image_id)
+ {
+ return TRUE;
+ }
}
}
}
@@ -612,9 +515,9 @@ void LLWearable::setTexturesToDefaults()
mTEMap.clear();
for( S32 te = 0; te < TEX_NUM_INDICES; te++ )
{
- if( LLVOAvatar::getTEWearableType((ETextureIndex) te ) == mType )
+ if (LLVOAvatarDictionary::getTEWearableType((ETextureIndex) te) == mType)
{
- mTEMap[te] = LLVOAvatar::getDefaultTEImageID((ETextureIndex) te );
+ mTEMap[te] = LLLocalTextureObject(NULL, NULL, NULL, LLVOAvatarDictionary::getDefaultTextureImageID((ETextureIndex) te));
}
}
}
@@ -622,7 +525,7 @@ void LLWearable::setTexturesToDefaults()
// Updates the user's avatar's appearance
void LLWearable::writeToAvatar( BOOL set_by_user )
{
- LLVOAvatar* avatar = gAgent.getAvatarObject();
+ LLVOAvatarSelf* avatar = gAgent.getAvatarObject();
llassert( avatar );
if( !avatar )
{
@@ -659,11 +562,20 @@ void LLWearable::writeToAvatar( BOOL set_by_user )
// Pull texture entries
for( S32 te = 0; te < TEX_NUM_INDICES; te++ )
{
- if( LLVOAvatar::getTEWearableType((ETextureIndex) te ) == mType )
+ if (LLVOAvatarDictionary::getTEWearableType((ETextureIndex) te) == mType)
{
- const LLUUID& image_id = get_if_there(mTEMap, te, LLVOAvatar::getDefaultTEImageID((ETextureIndex) te ) );
- LLViewerImage* image = gImageList.getImage( image_id );
- avatar->setLocTexTE( te, image, set_by_user );
+ te_map_t::const_iterator iter = mTEMap.find(te);
+ LLUUID image_id;
+ if(iter != mTEMap.end())
+ {
+ image_id = iter->second.getID();
+ }
+ else
+ {
+ image_id = LLVOAvatarDictionary::getDefaultTextureImageID((ETextureIndex) te);
+ }
+ LLViewerTexture* image = LLViewerTextureManager::getFetchedTexture( image_id, TRUE, FALSE, LLViewerTexture::LOD_TEXTURE );
+ avatar->setLocalTextureTE(te, image, set_by_user);
}
}
@@ -672,7 +584,8 @@ void LLWearable::writeToAvatar( BOOL set_by_user )
if( gFloaterCustomize )
{
LLViewerInventoryItem* item;
- item = (LLViewerInventoryItem*)gInventory.getItem(gAgent.getWearableItem(mType));
+ // MULTI_WEARABLE:
+ item = (LLViewerInventoryItem*)gInventory.getItem(gAgentWearables.getWearableItemID(mType,0));
U32 perm_mask = PERM_NONE;
BOOL is_complete = FALSE;
if(item)
@@ -685,7 +598,7 @@ void LLWearable::writeToAvatar( BOOL set_by_user )
}
}
gFloaterCustomize->setWearable(mType, this, perm_mask, is_complete);
- LLFloaterCustomize::setCurrentWearableType( mType );
+ gFloaterCustomize->setCurrentWearableType( mType );
}
ESex new_sex = avatar->getSex();
@@ -706,7 +619,7 @@ void LLWearable::writeToAvatar( BOOL set_by_user )
// static
void LLWearable::removeFromAvatar( EWearableType type, BOOL set_by_user )
{
- LLVOAvatar* avatar = gAgent.getAvatarObject();
+ LLVOAvatarSelf* avatar = gAgent.getAvatarObject();
llassert( avatar );
if( !avatar )
{
@@ -733,12 +646,12 @@ void LLWearable::removeFromAvatar( EWearableType type, BOOL set_by_user )
}
// Pull textures
- LLViewerImage* image = gImageList.getImage( IMG_DEFAULT_AVATAR );
+ LLViewerTexture* image = LLViewerTextureManager::getFetchedTexture( IMG_DEFAULT_AVATAR );
for( S32 te = 0; te < TEX_NUM_INDICES; te++ )
{
- if( LLVOAvatar::getTEWearableType((ETextureIndex) te ) == type )
+ if (LLVOAvatarDictionary::getTEWearableType((ETextureIndex) te) == type)
{
- avatar->setLocTexTE( te, image, set_by_user );
+ avatar->setLocalTextureTE(te, image, set_by_user);
}
}
@@ -782,12 +695,12 @@ void LLWearable::readFromAvatar()
mTEMap.clear();
for( S32 te = 0; te < TEX_NUM_INDICES; te++ )
{
- if( LLVOAvatar::getTEWearableType((ETextureIndex) te ) == mType )
+ if (LLVOAvatarDictionary::getTEWearableType((ETextureIndex) te) == mType)
{
- LLViewerImage* image = avatar->getTEImage( te );
+ LLViewerTexture* image = avatar->getTEImage( te );
if( image )
{
- mTEMap[te] = image->getID();
+ mTEMap[te] = LLLocalTextureObject(NULL, NULL, NULL, image->getID());
}
}
}
@@ -800,7 +713,7 @@ void LLWearable::readFromAvatar()
// Does not copy mAssetID.
// Definition version is current: removes obsolete enties and creates default values for new ones.
-void LLWearable::copyDataFrom( LLWearable* src )
+void LLWearable::copyDataFrom(const LLWearable* src)
{
LLVOAvatar* avatar = gAgent.getAvatarObject();
llassert( avatar );
@@ -833,28 +746,67 @@ void LLWearable::copyDataFrom( LLWearable* src )
// Deep copy of mTEMap (copies only those tes that are current, filling in defaults where needed)
for( S32 te = 0; te < TEX_NUM_INDICES; te++ )
{
- if( LLVOAvatar::getTEWearableType((ETextureIndex) te ) == mType )
+ if (LLVOAvatarDictionary::getTEWearableType((ETextureIndex) te) == mType)
{
- const LLUUID& image_id = get_if_there(src->mTEMap, te, LLVOAvatar::getDefaultTEImageID((ETextureIndex) te ) );
- mTEMap[te] = image_id;
+ te_map_t::const_iterator iter = mTEMap.find(te);
+ LLUUID image_id;
+ if(iter != mTEMap.end())
+ {
+ image_id = iter->second.getID();
+ }
+ else
+ {
+ image_id = LLVOAvatarDictionary::getDefaultTextureImageID((ETextureIndex) te);
+ }
+ mTEMap[te] = LLLocalTextureObject(NULL, NULL, NULL, image_id);
}
}
}
+void LLWearable::setItemID(const LLUUID& item_id)
+{
+ mItemID = item_id;
+}
+
+const LLUUID& LLWearable::getItemID() const
+{
+ return mItemID;
+}
+
+LLLocalTextureObject* LLWearable::getLocalTextureObject(S32 index) const
+{
+ te_map_t::const_iterator iter = mTEMap.find(index);
+ if( iter != mTEMap.end() )
+ {
+ return (LLLocalTextureObject*) &iter->second;
+ }
+ return NULL;
+}
+
+void LLWearable::setLocalTextureObject(S32 index, LLLocalTextureObject *lto)
+{
+ if( lto )
+ {
+ LLLocalTextureObject obj(*lto);
+ mTEMap[index] = obj;
+ }
+ else
+ {
+ mTEMap.erase(index);
+ }
+}
+
struct LLWearableSaveData
{
EWearableType mType;
};
-void LLWearable::saveNewAsset()
+void LLWearable::saveNewAsset() const
{
// llinfos << "LLWearable::saveNewAsset() type: " << getTypeName() << llendl;
//llinfos << *this << llendl;
- std::string new_asset_id_string;
- mAssetID.toString(new_asset_id_string);
- std::string filename;
- filename = gDirUtilp->getExpandedFilename(LL_PATH_CACHE,new_asset_id_string) + ".wbl";
+ const std::string filename = asset_id_to_filename(mAssetID);
LLFILE* fp = LLFile::fopen(filename, "wb"); /* Flawfinder: ignore */
BOOL successful_save = FALSE;
if(fp && exportFile(fp))
@@ -909,7 +861,7 @@ void LLWearable::saveNewAsset()
void LLWearable::onSaveNewAssetComplete(const LLUUID& new_asset_id, void* userdata, S32 status, LLExtStat ext_status) // StoreAssetData callback (fixed)
{
LLWearableSaveData* data = (LLWearableSaveData*)userdata;
- const std::string& type_name = LLWearable::typeToTypeName(data->mType);
+ const std::string& type_name = LLWearableDictionary::getTypeName(data->mType);
if(0 == status)
{
// Success
@@ -925,28 +877,16 @@ void LLWearable::onSaveNewAssetComplete(const LLUUID& new_asset_id, void* userda
}
// Delete temp file
- std::string new_asset_id_string;
- new_asset_id.toString(new_asset_id_string);
- std::string src_filename;
- src_filename = gDirUtilp->getExpandedFilename(LL_PATH_CACHE,new_asset_id_string) + ".wbl";
+ const std::string src_filename = asset_id_to_filename(new_asset_id);
LLFile::remove(src_filename);
// delete the context data
delete data;
}
-BOOL LLWearable::isMatchedToInventoryItem( LLViewerInventoryItem* item )
-{
- return
- ( mName == item->getName() ) &&
- ( mDescription == item->getDescription() ) &&
- ( mPermissions == item->getPermissions() ) &&
- ( mSaleInfo == item->getSaleInfo() );
-}
-
std::ostream& operator<<(std::ostream &s, const LLWearable &w)
{
- s << "wearable " << LLWearable::typeToTypeName( w.mType ) << "\n";
+ s << "wearable " << LLWearableDictionary::getTypeName(w.mType) << "\n";
s << " Name: " << w.mName << "\n";
s << " Desc: " << w.mDescription << "\n";
//w.mPermissions
@@ -966,10 +906,47 @@ std::ostream& operator<<(std::ostream &s, const LLWearable &w)
iter != w.mTEMap.end(); ++iter)
{
S32 te = iter->first;
- const LLUUID& image_id = iter->second;
+ const LLUUID& image_id = iter->second.getID();
s << " " << te << " " << image_id << "\n";
}
return s;
}
+std::string terse_F32_to_string(F32 f)
+{
+ std::string r = llformat("%.2f", f);
+ S32 len = r.length();
+
+ // "1.20" -> "1.2"
+ // "24.00" -> "24."
+ while (len > 0 && ('0' == r[len - 1]))
+ {
+ r.erase(len-1, 1);
+ len--;
+ }
+ if ('.' == r[len - 1])
+ {
+ // "24." -> "24"
+ r.erase(len-1, 1);
+ }
+ else if (('-' == r[0]) && ('0' == r[1]))
+ {
+ // "-0.59" -> "-.59"
+ r.erase(1, 1);
+ }
+ else if ('0' == r[0])
+ {
+ // "0.59" -> ".59"
+ r.erase(0, 1);
+ }
+ return r;
+}
+
+std::string asset_id_to_filename(const LLUUID &asset_id)
+{
+ std::string asset_id_string;
+ asset_id.toString(asset_id_string);
+ std::string filename = gDirUtilp->getExpandedFilename(LL_PATH_CACHE,asset_id_string) + ".wbl";
+ return filename;
+}
diff --git a/indra/newview/llwearable.h b/indra/newview/llwearable.h
index 683a8fa928..5f0b235c7f 100644
--- a/indra/newview/llwearable.h
+++ b/indra/newview/llwearable.h
@@ -19,7 +19,7 @@
* in the file doc/FLOSS-exception.txt in this software distribution, or
* online at
* http://secondlifegrid.net/programs/open_source/licensing/flossexception
- *
+ *
* By copying, modifying or distributing this software, you acknowledge
* that you have read and understood your obligations described above,
* and agree to abide by those obligations.
@@ -38,92 +38,75 @@
#include "llpermissions.h"
#include "llsaleinfo.h"
#include "llassetstorage.h"
+#include "llwearabledictionary.h"
+#include "llfile.h"
+#include "lllocaltextureobject.h"
class LLViewerInventoryItem;
-enum EWearableType // If you change this, update LLWearable::getTypeName(), getTypeLabel(), and LLVOAvatar::getTEWearableType()
-{
- WT_SHAPE = 0,
- WT_SKIN = 1,
- WT_HAIR = 2,
- WT_EYES = 3,
- WT_SHIRT = 4,
- WT_PANTS = 5,
- WT_SHOES = 6,
- WT_SOCKS = 7,
- WT_JACKET = 8,
- WT_GLOVES = 9,
- WT_UNDERSHIRT = 10,
- WT_UNDERPANTS = 11,
- WT_SKIRT = 12,
- WT_COUNT = 13,
- WT_INVALID = 255
-};
-
class LLWearable
{
friend class LLWearableList;
+
+ //--------------------------------------------------------------------
+ // Constructors and destructors
+ //--------------------------------------------------------------------
+private:
+ // Private constructors used by LLWearableList
+ LLWearable(const LLTransactionID& transactionID);
+ LLWearable(const LLAssetID& assetID);
public:
- ~LLWearable();
+ virtual ~LLWearable();
- const LLAssetID& getID() const { return mAssetID; }
+ //--------------------------------------------------------------------
+ // Accessors
+ //--------------------------------------------------------------------
+public:
+ const LLAssetID& getAssetID() const { return mAssetID; }
const LLTransactionID& getTransactionID() const { return mTransactionID; }
+ EWearableType getType() const { return mType; }
+ void setType(EWearableType type) { mType = type; }
+ const std::string& getName() const { return mName; }
+ void setName(const std::string& name) { mName = name; }
+ const std::string& getDescription() const { return mDescription; }
+ void setDescription(const std::string& desc) { mDescription = desc; }
+ const LLPermissions& getPermissions() const { return mPermissions; }
+ void setPermissions(const LLPermissions& p) { mPermissions = p; }
+ const LLSaleInfo& getSaleInfo() const { return mSaleInfo; }
+ void setSaleInfo(const LLSaleInfo& info) { mSaleInfo = info; }
+ const std::string& getTypeLabel() const;
+ const std::string& getTypeName() const;
+ LLAssetType::EType getAssetType() const;
- BOOL isDirty();
- BOOL isOldVersion();
+public:
+ BOOL isDirty() const;
+ BOOL isOldVersion() const;
void writeToAvatar( BOOL set_by_user );
void readFromAvatar();
void removeFromAvatar( BOOL set_by_user ) { LLWearable::removeFromAvatar( mType, set_by_user ); }
static void removeFromAvatar( EWearableType type, BOOL set_by_user );
- BOOL exportFile(LLFILE* file);
+ BOOL exportFile(LLFILE* file) const;
BOOL importFile(LLFILE* file);
-
- EWearableType getType() const { return mType; }
- void setType( EWearableType type ) { mType = type; }
-
- void setName( const std::string& name ) { mName = name; }
- const std::string& getName() const { return mName; }
-
- void setDescription( const std::string& desc ) { mDescription = desc; }
- const std::string& getDescription() const { return mDescription; }
-
- void setPermissions( const LLPermissions& p ) { mPermissions = p; }
- const LLPermissions& getPermissions() const { return mPermissions; }
-
- void setSaleInfo( const LLSaleInfo& info ) { mSaleInfo = info; }
- const LLSaleInfo& getSaleInfo() const { return mSaleInfo; }
-
- const std::string& getTypeLabel() const { return LLWearable::sTypeLabel[ mType ]; }
- const std::string& getTypeName() const { return LLWearable::sTypeName[ mType ]; }
-
+
void setParamsToDefaults();
void setTexturesToDefaults();
- LLAssetType::EType getAssetType() const { return LLWearable::typeToAssetType( mType ); }
-
- static EWearableType typeNameToType( const std::string& type_name );
- static const std::string& typeToTypeName( EWearableType type ) { return LLWearable::sTypeName[llmin(type,WT_COUNT)]; }
- static const std::string& typeToTypeLabel( EWearableType type ) { return LLWearable::sTypeLabel[llmin(type,WT_COUNT)]; }
- static LLAssetType::EType typeToAssetType( EWearableType wearable_type );
-
- void saveNewAsset();
+ void saveNewAsset() const;
static void onSaveNewAssetComplete( const LLUUID& asset_uuid, void* user_data, S32 status, LLExtStat ext_status );
- BOOL isMatchedToInventoryItem( LLViewerInventoryItem* item );
-
- void copyDataFrom( LLWearable* src );
+ void copyDataFrom(const LLWearable* src);
static void setCurrentDefinitionVersion( S32 version ) { LLWearable::sCurrentDefinitionVersion = version; }
friend std::ostream& operator<<(std::ostream &s, const LLWearable &w);
+ void setItemID(const LLUUID& item_id);
+ const LLUUID& getItemID() const;
+ LLLocalTextureObject* getLocalTextureObject(S32 index) const;
+ void setLocalTextureObject(S32 index, LLLocalTextureObject *lto);
private:
- // Private constructor used by LLWearableList
- LLWearable(const LLTransactionID& transactionID);
- LLWearable(const LLAssetID& assetID);
-
static S32 sCurrentDefinitionVersion; // Depends on the current state of the avatar_lad.xml.
S32 mDefinitionVersion; // Depends on the state of the avatar_lad.xml when this asset was created.
std::string mName;
@@ -136,11 +119,9 @@ private:
typedef std::map<S32, F32> param_map_t;
param_map_t mVisualParamMap; // maps visual param id to weight
- typedef std::map<S32, LLUUID> te_map_t;
- te_map_t mTEMap; // maps TE to Image ID
-
- static const std::string sTypeName[ WT_COUNT+1 ];
- static const std::string sTypeLabel[ WT_COUNT+1 ];
+ typedef std::map<S32, LLLocalTextureObject> te_map_t;
+ te_map_t mTEMap; // maps TE to LocalTextureObject
+ LLUUID mItemID; // ID of the inventory item in the agent's inventory
};
#endif // LL_LLWEARABLE_H
diff --git a/indra/newview/llwearablelist.cpp b/indra/newview/llwearablelist.cpp
index 512c03fa4d..1275312676 100644
--- a/indra/newview/llwearablelist.cpp
+++ b/indra/newview/llwearablelist.cpp
@@ -39,22 +39,18 @@
#include "llagent.h"
#include "llvoavatar.h"
#include "llviewerinventory.h"
-//#include "llfloaterchat.h"
#include "llviewerstats.h"
#include "llnotify.h"
+#include "llinventorymodel.h"
+#include "lltrans.h"
-// Globals
-LLWearableList gWearableList; // Globally constructed; be careful that there's no dependency with gAgent.
-
-
+// Callback struct
struct LLWearableArrivedData
{
- LLWearableArrivedData(
- LLAssetType::EType asset_type,
+ LLWearableArrivedData(LLAssetType::EType asset_type,
const std::string& wearable_name,
void(*asset_arrived_callback)(LLWearable*, void* userdata),
- void* userdata )
- :
+ void* userdata) :
mAssetType( asset_type ),
mCallback( asset_arrived_callback ),
mUserdata( userdata ),
@@ -69,8 +65,6 @@ struct LLWearableArrivedData
S32 mRetries;
};
-
-
////////////////////////////////////////////////////////////////////////////
// LLWearableList
@@ -80,8 +74,21 @@ LLWearableList::~LLWearableList()
mList.clear();
}
-void LLWearableList::getAsset( const LLAssetID& assetID, const std::string& wearable_name, LLAssetType::EType asset_type, void(*asset_arrived_callback)(LLWearable*, void* userdata), void* userdata )
+void LLWearableList::getAsset(const LLAssetID& _assetID, const std::string& wearable_name, LLAssetType::EType asset_type, void(*asset_arrived_callback)(LLWearable*, void* userdata), void* userdata)
{
+ LLAssetID assetID = _assetID;
+
+ // A bit of a hack since wearables database doesn't contain asset types...
+ // Perform indirection in case this assetID is in fact a link. This only works
+ // because of the assumption that all assetIDs and itemIDs are unique (i.e.
+ // no assetID is also used as an itemID elsewhere); therefore if the assetID
+ // exists as an itemID in the user's inventory, then this must be a link.
+ const LLInventoryItem *linked_item = gInventory.getItem(_assetID);
+ if (linked_item)
+ {
+ assetID = linked_item->getAssetUUID();
+ asset_type = linked_item->getType();
+ }
llassert( (asset_type == LLAssetType::AT_CLOTHING) || (asset_type == LLAssetType::AT_BODYPART) );
LLWearable* instance = get_if_there(mList, assetID, (LLWearable*)NULL );
if( instance )
@@ -90,8 +97,7 @@ void LLWearableList::getAsset( const LLAssetID& assetID, const std::string& wear
}
else
{
- gAssetStorage->getAssetData(
- assetID,
+ gAssetStorage->getAssetData(assetID,
asset_type,
LLWearableList::processGetAssetReply,
(void*)new LLWearableArrivedData( asset_type, wearable_name, asset_arrived_callback, userdata ),
@@ -110,8 +116,7 @@ void LLWearableList::processGetAssetReply( const char* filename, const LLAssetID
{
LL_WARNS("Wearable") << "Bad Wearable Asset: missing file." << LL_ENDL;
}
- else
- if( status >= 0 )
+ else if (status >= 0)
{
// read the file
LLFILE* fp = LLFile::fopen(std::string(filename), "rb"); /*Flawfinder: ignore*/
@@ -180,15 +185,14 @@ void LLWearableList::processGetAssetReply( const char* filename, const LLAssetID
if (wearable) // success
{
- gWearableList.mList[ uuid ] = wearable;
+ LLWearableList::instance().mList[ uuid ] = wearable;
LL_DEBUGS("Wearable") << "processGetAssetReply()" << LL_ENDL;
LL_DEBUGS("Wearable") << wearable << LL_ENDL;
}
else
{
LLSD args;
- // *TODO:translate
- args["TYPE"] = LLAssetType::lookupHumanReadable(data->mAssetType);
+ args["TYPE"] =LLTrans::getString(LLAssetType::lookupHumanReadable(data->mAssetType));
if (isNewWearable)
{
LLNotifications::instance().add("InvalidWearable");
@@ -214,42 +218,13 @@ void LLWearableList::processGetAssetReply( const char* filename, const LLAssetID
}
-// Creates a new wearable just like the old_wearable but with data copied over from item
-LLWearable* LLWearableList::createWearableMatchedToInventoryItem( LLWearable* old_wearable, LLViewerInventoryItem* item )
-{
- lldebugs << "LLWearableList::createWearableMatchedToInventoryItem()" << llendl;
-
- LLTransactionID tid;
- LLAssetID new_asset_id;
- new_asset_id = tid.makeAssetID(gAgent.getSecureSessionID());
-
- LLWearable* wearable = new LLWearable( tid );
- wearable->copyDataFrom( old_wearable );
-
- wearable->setName( item->getName() );
- wearable->setDescription( item->getDescription() );
- wearable->setPermissions( item->getPermissions() );
- wearable->setSaleInfo( item->getSaleInfo() );
-
- mList[ new_asset_id ] = wearable;
-
- // Send to the dataserver
- wearable->saveNewAsset();
-
- return wearable;
-}
-
-LLWearable* LLWearableList::createCopyFromAvatar( LLWearable* old_wearable, const std::string& new_name )
+LLWearable* LLWearableList::createCopyFromAvatar(const LLWearable* old_wearable, const std::string& new_name)
{
lldebugs << "LLWearableList::createCopyFromAvatar()" << llendl;
- LLTransactionID tid;
- LLAssetID new_asset_id;
- tid.generate();
- new_asset_id = tid.makeAssetID(gAgent.getSecureSessionID());
-
- LLWearable* wearable = new LLWearable( tid );
+ LLWearable *wearable = generateNewWearable();
wearable->copyDataFrom( old_wearable );
+
LLPermissions perm(old_wearable->getPermissions());
perm.setOwnerAndGroup(LLUUID::null, gAgent.getID(), LLUUID::null, true);
wearable->setPermissions(perm);
@@ -257,8 +232,6 @@ LLWearable* LLWearableList::createCopyFromAvatar( LLWearable* old_wearable, cons
if (!new_name.empty()) wearable->setName(new_name);
- mList[ new_asset_id ] = wearable;
-
// Send to the dataserver
wearable->saveNewAsset();
@@ -266,21 +239,16 @@ LLWearable* LLWearableList::createCopyFromAvatar( LLWearable* old_wearable, cons
}
-LLWearable* LLWearableList::createCopy( LLWearable* old_wearable )
+LLWearable* LLWearableList::createCopy(const LLWearable* old_wearable)
{
lldebugs << "LLWearableList::createCopy()" << llendl;
- LLTransactionID tid;
- LLAssetID new_asset_id;
- tid.generate();
- new_asset_id = tid.makeAssetID(gAgent.getSecureSessionID());
+ LLWearable *wearable = generateNewWearable();
+ wearable->copyDataFrom(old_wearable);
- LLWearable* wearable = new LLWearable( tid );
- wearable->copyDataFrom( old_wearable );
LLPermissions perm(old_wearable->getPermissions());
perm.setOwnerAndGroup(LLUUID::null, gAgent.getID(), LLUUID::null, true);
wearable->setPermissions(perm);
- mList[ new_asset_id ] = wearable;
// Send to the dataserver
wearable->saveNewAsset();
@@ -292,12 +260,7 @@ LLWearable* LLWearableList::createNewWearable( EWearableType type )
{
lldebugs << "LLWearableList::createNewWearable()" << llendl;
- LLTransactionID tid;
- LLAssetID new_asset_id;
- tid.generate();
- new_asset_id = tid.makeAssetID(gAgent.getSecureSessionID());
-
- LLWearable* wearable = new LLWearable( tid );
+ LLWearable *wearable = generateNewWearable();
wearable->setType( type );
std::string name = "New ";
@@ -314,10 +277,19 @@ LLWearable* LLWearableList::createNewWearable( EWearableType type )
wearable->setParamsToDefaults();
wearable->setTexturesToDefaults();
- mList[ new_asset_id ] = wearable;
-
// Send to the dataserver
wearable->saveNewAsset();
return wearable;
}
+
+LLWearable *LLWearableList::generateNewWearable()
+{
+ LLTransactionID tid;
+ tid.generate();
+ LLAssetID new_asset_id = tid.makeAssetID(gAgent.getSecureSessionID());
+
+ LLWearable* wearable = new LLWearable(tid);
+ mList[new_asset_id] = wearable;
+ return wearable;
+}
diff --git a/indra/newview/llwearablelist.h b/indra/newview/llwearablelist.h
index cda0cb11f9..f844c0f443 100644
--- a/indra/newview/llwearablelist.h
+++ b/indra/newview/llwearablelist.h
@@ -33,37 +33,37 @@
#ifndef LL_LLWEARABLELIST_H
#define LL_LLWEARABLELIST_H
+#include "llmemory.h"
#include "llwearable.h"
#include "lluuid.h"
#include "llassetstorage.h"
-class LLWearableList
+// Globally constructed; be careful that there's no dependency with gAgent.
+class LLWearableList : public LLSingleton<LLWearableList>
{
public:
LLWearableList() {}
~LLWearableList();
- S32 getLength() { return mList.size(); }
+ S32 getLength() const { return mList.size(); }
- void getAsset(
- const LLAssetID& assetID,
- const std::string& wearable_name,
- LLAssetType::EType asset_type,
- void(*asset_arrived_callback)(LLWearable*, void* userdata),
- void* userdata );
+ void getAsset(const LLAssetID& assetID,
+ const std::string& wearable_name,
+ LLAssetType::EType asset_type,
+ void(*asset_arrived_callback)(LLWearable*, void* userdata),
+ void* userdata);
- LLWearable* createWearableMatchedToInventoryItem( LLWearable* old_wearable, LLViewerInventoryItem* item );
- LLWearable* createCopyFromAvatar( LLWearable* old_wearable, const std::string& new_name = std::string() );
- LLWearable* createCopy( LLWearable* old_wearable );
- LLWearable* createNewWearable( EWearableType type );
+ LLWearable* createCopyFromAvatar(const LLWearable* old_wearable, const std::string& new_name = std::string());
+ LLWearable* createCopy(const LLWearable* old_wearable);
+ LLWearable* createNewWearable(EWearableType type);
// Callback
static void processGetAssetReply(const char* filename, const LLAssetID& assetID, void* user_data, S32 status, LLExtStat ext_status);
protected:
- std::map< LLUUID, LLWearable* > mList;
+ LLWearable* generateNewWearable(); // used for the create... functions
+private:
+ std::map<LLUUID, LLWearable*> mList;
};
-extern LLWearableList gWearableList;
-
#endif // LL_LLWEARABLELIST_H
diff --git a/indra/newview/llweb.cpp b/indra/newview/llweb.cpp
index a5691d8a1c..300a5db7c3 100644
--- a/indra/newview/llweb.cpp
+++ b/indra/newview/llweb.cpp
@@ -35,10 +35,31 @@
#include "llweb.h"
-#include "llviewerwindow.h"
+// Library includes
+#include "llwindow.h" // spawnWebBrowser()
+#include "llviewerwindow.h"
#include "llviewercontrol.h"
-#include "llfloaterhtmlhelp.h"
+#include "llfloatermediabrowser.h"
+#include "llfloaterreg.h"
+#include "llalertdialog.h"
+
+class URLLoader : public LLAlertDialog::URLLoader
+{
+ virtual void load(const std::string& url , bool force_open_externally)
+ {
+ if (force_open_externally)
+ {
+ LLWeb::loadURLExternal(url);
+ }
+ else
+ {
+ LLWeb::loadURL(url);
+ }
+ }
+};
+static URLLoader sAlertURLLoader;
+
// static
void LLWeb::initClass()
@@ -55,7 +76,7 @@ void LLWeb::loadURL(const std::string& url)
}
else
{
- LLFloaterMediaBrowser::showInstance(url);
+ LLFloaterReg::showInstance("media_browser",url);
}
}
@@ -93,12 +114,3 @@ std::string LLWeb::escapeURL(const std::string& url)
}
return escaped_url;
}
-
-// virtual
-void LLWeb::URLLoader::load(const std::string& url)
-{
- loadURL(url);
-}
-
-// static
-LLWeb::URLLoader LLWeb::sAlertURLLoader;
diff --git a/indra/newview/llweb.h b/indra/newview/llweb.h
index 278821bac5..71cc236621 100644
--- a/indra/newview/llweb.h
+++ b/indra/newview/llweb.h
@@ -35,7 +35,6 @@
#define LL_LLWEB_H
#include <string>
-#include "llalertdialog.h"
class LLWeb
{
@@ -54,12 +53,6 @@ public:
// Returns escaped (eg, " " to "%20") url
static std::string escapeURL(const std::string& url);
- class URLLoader : public LLAlertDialog::URLLoader
- {
- virtual void load(const std::string& url);
- };
-
- static URLLoader sAlertURLLoader;
};
#endif
diff --git a/indra/newview/llwind.cpp b/indra/newview/llwind.cpp
index ae98bead98..cbee4ddae1 100644
--- a/indra/newview/llwind.cpp
+++ b/indra/newview/llwind.cpp
@@ -49,7 +49,6 @@
// viewer
#include "noise.h"
#include "v4color.h"
-#include "llagent.h"
#include "llworld.h"
diff --git a/indra/newview/llwldaycycle.cpp b/indra/newview/llwldaycycle.cpp
index 1d17c6047f..10a9703d1a 100644
--- a/indra/newview/llwldaycycle.cpp
+++ b/indra/newview/llwldaycycle.cpp
@@ -35,8 +35,7 @@
#include "llwldaycycle.h"
#include "llsdserialize.h"
#include "llwlparammanager.h"
-
-#include "llviewerwindow.h"
+#include "llnotifications.h"
#include <map>
diff --git a/indra/newview/llwldaycycle.h b/indra/newview/llwldaycycle.h
index f045a6d1b0..eed6a78c18 100644
--- a/indra/newview/llwldaycycle.h
+++ b/indra/newview/llwldaycycle.h
@@ -35,8 +35,6 @@
class LLWLDayCycle;
-#include "llfloater.h"
-
#include <vector>
#include <map>
#include <string>
diff --git a/indra/newview/llwlparammanager.cpp b/indra/newview/llwlparammanager.cpp
index b8a2bf0bd2..7d9d0a6191 100644
--- a/indra/newview/llwlparammanager.cpp
+++ b/indra/newview/llwlparammanager.cpp
@@ -37,6 +37,7 @@
#include "pipeline.h"
#include "llsky.h"
+#include "llfloaterreg.h"
#include "llsliderctrl.h"
#include "llspinctrl.h"
#include "llcheckboxctrl.h"
@@ -51,7 +52,6 @@
#include "llviewercontrol.h"
#include "llviewerwindow.h"
#include "lldrawpoolwater.h"
-#include "llagent.h"
#include "llviewerregion.h"
#include "llwlparamset.h"
@@ -63,6 +63,7 @@
#include "curl/curl.h"
LLWLParamManager * LLWLParamManager::sInstance = NULL;
+static LLFastTimer::DeclareTimer FTM_UPDATE_WLPARAM("Update Windlight Params");
LLWLParamManager::LLWLParamManager() :
@@ -291,7 +292,7 @@ void LLWLParamManager::updateShaderUniforms(LLGLSLShader * shader)
void LLWLParamManager::propagateParameters(void)
{
- LLFastTimer ftm(LLFastTimer::FTM_UPDATE_WLPARAM);
+ LLFastTimer ftm(FTM_UPDATE_WLPARAM);
LLVector4 sunDir;
LLVector4 moonDir;
@@ -362,7 +363,7 @@ void LLWLParamManager::propagateParameters(void)
void LLWLParamManager::update(LLViewerCamera * cam)
{
- LLFastTimer ftm(LLFastTimer::FTM_UPDATE_WLPARAM);
+ LLFastTimer ftm(FTM_UPDATE_WLPARAM);
// update clouds, sun, and general
mCurParams.updateCloudScrolling();
@@ -377,17 +378,20 @@ void LLWLParamManager::update(LLViewerCamera * cam)
propagateParameters();
// sync menus if they exist
- if(LLFloaterWindLight::isOpen())
+ LLFloaterWindLight* wlfloater = LLFloaterReg::findTypedInstance<LLFloaterWindLight>("env_windlight");
+ if (wlfloater)
{
- LLFloaterWindLight::instance()->syncMenu();
+ wlfloater->syncMenu();
}
- if(LLFloaterDayCycle::isOpen())
+ LLFloaterDayCycle* dlfloater = LLFloaterReg::findTypedInstance<LLFloaterDayCycle>("env_day_cycle");
+ if (dlfloater)
{
- LLFloaterDayCycle::instance()->syncMenu();
+ dlfloater->syncMenu();
}
- if(LLFloaterEnvSettings::isOpen())
+ LLFloaterEnvSettings* envfloater = LLFloaterReg::findTypedInstance<LLFloaterEnvSettings>("env_settings");
+ if (envfloater)
{
- LLFloaterEnvSettings::instance()->syncMenu();
+ envfloater->syncMenu();
}
F32 camYaw = cam->getYaw();
diff --git a/indra/newview/llworld.cpp b/indra/newview/llworld.cpp
index 3fdef29540..5c6fc2cf21 100644
--- a/indra/newview/llworld.cpp
+++ b/indra/newview/llworld.cpp
@@ -46,8 +46,8 @@
#include "llregionhandle.h"
#include "llsurface.h"
#include "llviewercamera.h"
-#include "llviewerimage.h"
-#include "llviewerimagelist.h"
+#include "llviewertexture.h"
+#include "llviewertexturelist.h"
#include "llviewernetwork.h"
#include "llviewerobjectlist.h"
#include "llviewerparceloverlay.h"
@@ -109,8 +109,8 @@ LLWorld::LLWorld() :
*(default_texture++) = MAX_WATER_COLOR.mV[2];
*(default_texture++) = MAX_WATER_COLOR.mV[3];
- mDefaultWaterTexturep = new LLViewerImage(raw, FALSE);
- gGL.getTexUnit(0)->bind(mDefaultWaterTexturep.get());
+ mDefaultWaterTexturep = LLViewerTextureManager::getLocalTexture(raw.get(), FALSE);
+ gGL.getTexUnit(0)->bind(mDefaultWaterTexturep);
mDefaultWaterTexturep->setAddressMode(LLTexUnit::TAM_CLAMP);
}
@@ -632,6 +632,7 @@ void LLWorld::updateVisibilities()
void LLWorld::updateRegions(F32 max_update_time)
{
+ LLMemType mt_ur(LLMemType::MTYPE_IDLE_UPDATE_REGIONS);
LLTimer update_timer;
BOOL did_one = FALSE;
@@ -961,7 +962,7 @@ void LLWorld::shiftRegions(const LLVector3& offset)
LLViewerPartSim::getInstance()->shift(offset);
}
-LLViewerImage* LLWorld::getDefaultWaterTexture()
+LLViewerTexture* LLWorld::getDefaultWaterTexture()
{
return mDefaultWaterTexturep;
}
diff --git a/indra/newview/llworld.h b/indra/newview/llworld.h
index ce83cbd97c..48025c700b 100644
--- a/indra/newview/llworld.h
+++ b/indra/newview/llworld.h
@@ -42,10 +42,10 @@
#include "llmath.h"
#include "v3math.h"
-#include "llmemory.h"
+#include "llsingleton.h"
#include "llstring.h"
#include "llviewerpartsim.h"
-#include "llviewerimage.h"
+#include "llviewertexture.h"
#include "llvowater.h"
class LLViewerRegion;
@@ -141,7 +141,7 @@ public:
F32 getLandFarClip() const;
void setLandFarClip(const F32 far_clip);
- LLViewerImage *getDefaultWaterTexture();
+ LLViewerTexture *getDefaultWaterTexture();
void updateWaterObjects();
void shiftRegions(const LLVector3& offset);
@@ -192,7 +192,7 @@ private:
std::list<LLVOWater*> mHoleWaterObjects;
LLPointer<LLVOWater> mEdgeWaterObjects[8];
- LLPointer<LLViewerImage> mDefaultWaterTexturep;
+ LLPointer<LLViewerTexture> mDefaultWaterTexturep;
};
diff --git a/indra/newview/llworldmap.cpp b/indra/newview/llworldmap.cpp
index 572f31f566..700971dcc4 100644
--- a/indra/newview/llworldmap.cpp
+++ b/indra/newview/llworldmap.cpp
@@ -43,9 +43,10 @@
#include "llviewercontrol.h"
#include "llfloaterworldmap.h"
#include "lltracker.h"
-#include "llviewerimagelist.h"
+#include "llviewertexturelist.h"
#include "llviewerregion.h"
#include "llregionflags.h"
+#include "lltrans.h"
const F32 REQUEST_ITEMS_TIMER = 10.f * 60.f; // 10 minutes
@@ -518,9 +519,9 @@ void LLWorldMap::processMapLayerReply(LLMessageSystem* msg, void**)
LLWorldMapLayer new_layer;
new_layer.LayerDefined = TRUE;
msg->getUUIDFast(_PREHASH_LayerData, _PREHASH_ImageID, new_layer.LayerImageID, block);
- new_layer.LayerImage = gImageList.getImage(new_layer.LayerImageID, MIPMAP_TRUE, FALSE);
+ new_layer.LayerImage = LLViewerTextureManager::getFetchedTexture(new_layer.LayerImageID, MIPMAP_TRUE, FALSE, LLViewerTexture::LOD_TEXTURE);
- gGL.getTexUnit(0)->bind(new_layer.LayerImage.get());
+ gGL.getTexUnit(0)->bind(new_layer.LayerImage);
new_layer.LayerImage->setAddressMode(LLTexUnit::TAM_CLAMP);
U32 left, right, top, bottom;
@@ -633,15 +634,15 @@ void LLWorldMap::processMapBlockReply(LLMessageSystem* msg, void**)
siminfo->mMapImageID[agent_flags] = image_id;
#ifdef IMMEDIATE_IMAGE_LOAD
- siminfo->mCurrentImage = gImageList.getImage(siminfo->mMapImageID[LLWorldMap::getInstance()->mCurrentMap], MIPMAP_TRUE, FALSE);
- gGL.getTexUnit(0)->bind(siminfo->mCurrentImage.get());
+ siminfo->mCurrentImage = LLViewerTextureManager::getFetchedTexture(siminfo->mMapImageID[LLWorldMap::getInstance()->mCurrentMap], MIPMAP_TRUE, FALSE, LLViewerTexture::LOD_TEXTURE);
+ gGL.getTexUnit(0)->bind(siminfo->mCurrentImage);
siminfo->mCurrentImage->setAddressMode(LLTexUnit::TAM_CLAMP);
#endif
if (siminfo->mMapImageID[2].notNull())
{
#ifdef IMMEDIATE_IMAGE_LOAD
- siminfo->mOverlayImage = gImageList.getImage(siminfo->mMapImageID[2], MIPMAP_TRUE, FALSE);
+ siminfo->mOverlayImage = LLViewerTextureManager::getFetchedTexture(siminfo->mMapImageID[2], MIPMAP_TRUE, FALSE, LLViewerTexture::LOD_TEXTURE);
#endif
}
else
@@ -757,18 +758,13 @@ void LLWorldMap::processMapItemReply(LLMessageSystem* msg, void**)
case MAP_ITEM_MATURE_EVENT:
case MAP_ITEM_ADULT_EVENT:
{
- struct tm* timep;
- // Convert to Pacific, based on server's opinion of whether
- // it's daylight savings time there.
- timep = utc_to_pacific_time(extra, gPacificDaylightTime);
-
- S32 display_hour = timep->tm_hour % 12;
- if (display_hour == 0) display_hour = 12;
-
- new_item.mToolTip = llformat( "%d:%02d %s",
- display_hour,
- timep->tm_min,
- (timep->tm_hour < 12 ? "AM" : "PM") );
+ std::string timeStr = "["+ LLTrans::getString ("TimeHour")+"]:["
+ +LLTrans::getString ("TimeMin")+"] ["
+ +LLTrans::getString ("TimeAMPM")+"]";
+ LLSD substitution;
+ substitution["datetime"] = (S32) extra;
+ LLStringUtil::format (timeStr, substitution);
+ new_item.mToolTip = timeStr;
// HACK: store Z in extra2
new_item.mPosGlobal.mdV[VZ] = (F64)extra2;
@@ -866,10 +862,10 @@ void LLWorldMap::dump()
if (info->mCurrentImage)
{
llinfos << "image discard " << (S32)info->mCurrentImage->getDiscardLevel()
- << " fullwidth " << info->mCurrentImage->getWidth(0)
- << " fullheight " << info->mCurrentImage->getHeight(0)
- << " maxvirt " << info->mCurrentImage->mMaxVirtualSize
- << " maxdisc " << (S32)info->mCurrentImage->getMaxDiscardLevel()
+ << " fullwidth " << info->mCurrentImage->getFullWidth()
+ << " fullheight " << info->mCurrentImage->getFullHeight()
+ << " maxvirt " << info->mCurrentImage->getMaxVirtualSize()
+ //<< " maxdisc " << (S32)info->mCurrentImage->getMaxDiscardLevel()
<< llendl;
}
}
diff --git a/indra/newview/llworldmap.h b/indra/newview/llworldmap.h
index bb3c97cfd9..9daee38752 100644
--- a/indra/newview/llworldmap.h
+++ b/indra/newview/llworldmap.h
@@ -36,14 +36,16 @@
#include <map>
#include <string>
#include <vector>
+#include <boost/function.hpp>
#include "v3math.h"
#include "v3dmath.h"
#include "llframetimer.h"
#include "llmapimagetype.h"
#include "lluuid.h"
-#include "llmemory.h"
-#include "llviewerimage.h"
+#include "llpointer.h"
+#include "llsingleton.h"
+#include "llviewertexture.h"
#include "lleventinfo.h"
#include "v3color.h"
@@ -94,8 +96,8 @@ public:
LLUUID mMapImageID[MAP_SIM_IMAGE_TYPES];
// Hold a reference to the currently displayed image.
- LLPointer<LLViewerImage> mCurrentImage;
- LLPointer<LLViewerImage> mOverlayImage;
+ LLPointer<LLViewerFetchedTexture> mCurrentImage;
+ LLPointer<LLViewerFetchedTexture> mOverlayImage;
};
#define MAP_BLOCK_RES 256
@@ -103,7 +105,7 @@ public:
struct LLWorldMapLayer
{
BOOL LayerDefined;
- LLPointer<LLViewerImage> LayerImage;
+ LLPointer<LLViewerFetchedTexture> LayerImage;
LLUUID LayerImageID;
LLRect LayerExtents;
@@ -114,7 +116,8 @@ struct LLWorldMapLayer
class LLWorldMap : public LLSingleton<LLWorldMap>
{
public:
- typedef void(*url_callback_t)(U64 region_handle, const std::string& url, const LLUUID& snapshot_id, bool teleport);
+ typedef boost::function<void(U64 region_handle, const std::string& url, const LLUUID& snapshot_id, bool teleport)>
+ url_callback_t;
LLWorldMap();
~LLWorldMap();
diff --git a/indra/newview/llworldmapview.cpp b/indra/newview/llworldmapview.cpp
index 2e18b710a7..67bc205f62 100644
--- a/indra/newview/llworldmapview.cpp
+++ b/indra/newview/llworldmapview.cpp
@@ -39,11 +39,11 @@
#include "llmath.h" // clampf()
#include "llregionhandle.h"
#include "lleventflags.h"
+#include "llfloaterreg.h"
#include "llrender.h"
#include "llagent.h"
#include "llcallingcard.h"
-#include "llcolorscheme.h"
#include "llviewercontrol.h"
#include "llcylinder.h"
#include "llfloaterdirectory.h"
@@ -54,8 +54,8 @@
#include "lltextureview.h"
#include "lltracker.h"
#include "llviewercamera.h"
-#include "llviewerimage.h"
-#include "llviewerimagelist.h"
+#include "llviewertexture.h"
+#include "llviewertexturelist.h"
#include "llviewermenu.h"
#include "llviewerparceloverlay.h"
#include "llviewerregion.h"
@@ -164,8 +164,8 @@ void LLWorldMapView::cleanupClass()
sForSaleAdultImage = NULL;
}
-LLWorldMapView::LLWorldMapView(const std::string& name, const LLRect& rect )
-: LLPanel(name, rect, BORDER_NO),
+LLWorldMapView::LLWorldMapView()
+: LLPanel(),
mBackgroundColor( LLColor4( 4.f/255.f, 4.f/255.f, 75.f/255.f, 1.f ) ),
mItemPicked(FALSE),
mPanning( FALSE ),
@@ -177,47 +177,38 @@ LLWorldMapView::LLWorldMapView(const std::string& name, const LLRect& rect )
{
sPixelsPerMeter = gMapScale / REGION_WIDTH_METERS;
clearLastClick();
+}
- const S32 DIR_WIDTH = 10;
- const S32 DIR_HEIGHT = 10;
- LLRect major_dir_rect( 0, DIR_HEIGHT, DIR_WIDTH, 0 );
- LLColor4 minor_color( 1.f, 1.f, 1.f, .7f );
-
- mTextBoxNorth = new LLTextBox( std::string("N"), major_dir_rect );
- mTextBoxNorth->setColor( minor_color );
- addChild( mTextBoxNorth );
-
- mTextBoxEast = new LLTextBox( std::string("E"), major_dir_rect );
- mTextBoxEast->setColor( minor_color );
- addChild( mTextBoxEast );
-
- major_dir_rect.mRight += 1 ;
- mTextBoxWest = new LLTextBox( std::string("W"), major_dir_rect );
- mTextBoxWest->setColor( minor_color );
- addChild( mTextBoxWest );
- major_dir_rect.mRight -= 1 ;
-
- mTextBoxSouth = new LLTextBox( std::string("S"), major_dir_rect );
- mTextBoxSouth->setColor( minor_color );
- addChild( mTextBoxSouth );
-
- LLRect minor_dir_rect( 0, DIR_HEIGHT, DIR_WIDTH * 2, 0 );
-
- mTextBoxSouthEast = new LLTextBox( std::string("SE"), minor_dir_rect );
- mTextBoxSouthEast->setColor( minor_color );
- addChild( mTextBoxSouthEast );
+BOOL LLWorldMapView::postBuild()
+{
+ mTextBoxNorth = getChild<LLTextBox> ("floater_map_north");
+ mTextBoxEast = getChild<LLTextBox> ("floater_map_east");
+ mTextBoxWest = getChild<LLTextBox> ("floater_map_west");
+ mTextBoxSouth = getChild<LLTextBox> ("floater_map_south");
+ mTextBoxSouthEast = getChild<LLTextBox> ("floater_map_southeast");
+ mTextBoxNorthEast = getChild<LLTextBox> ("floater_map_northeast");
+ mTextBoxSouthWest = getChild<LLTextBox> ("floater_map_southwest");
+ mTextBoxNorthWest = getChild<LLTextBox> ("floater_map_northwest");
- mTextBoxNorthEast = new LLTextBox( std::string("NE"), minor_dir_rect );
- mTextBoxNorthEast->setColor( minor_color );
- addChild( mTextBoxNorthEast );
+ mTextBoxNorth->setText(getString("world_map_north"));
+ mTextBoxEast->setText(getString ("world_map_east"));
+ mTextBoxWest->setText(getString("world_map_west"));
+ mTextBoxSouth->setText(getString ("world_map_south"));
+ mTextBoxSouthEast ->setText(getString ("world_map_southeast"));
+ mTextBoxNorthEast ->setText(getString ("world_map_northeast"));
+ mTextBoxSouthWest->setText(getString ("world_map_southwest"));
+ mTextBoxNorthWest ->setText(getString("world_map_northwest"));
- mTextBoxSouthWest = new LLTextBox( std::string("SW"), minor_dir_rect );
- mTextBoxSouthWest->setColor( minor_color );
- addChild( mTextBoxSouthWest );
+ mTextBoxNorth->reshapeToFitText();
+ mTextBoxEast->reshapeToFitText();
+ mTextBoxWest->reshapeToFitText();
+ mTextBoxSouth->reshapeToFitText();
+ mTextBoxSouthEast ->reshapeToFitText();
+ mTextBoxNorthEast ->reshapeToFitText();
+ mTextBoxSouthWest->reshapeToFitText();
+ mTextBoxNorthWest ->reshapeToFitText();
- mTextBoxNorthWest = new LLTextBox( std::string("NW"), minor_dir_rect );
- mTextBoxNorthWest->setColor( minor_color );
- addChild( mTextBoxNorthWest );
+ return true;
}
@@ -293,6 +284,8 @@ BOOL is_agent_in_region(LLViewerRegion* region, LLSimInfo* info)
void LLWorldMapView::draw()
{
+ static LLUIColor map_track_color = LLUIColorTable::instance().getColor("MapTrackColor", LLColor4::white);
+
LLTextureView::clearDebugImages();
F64 current_time = LLTimer::getElapsedSeconds();
@@ -339,7 +332,7 @@ void LLWorldMapView::draw()
continue;
}
LLWorldMapLayer *layer = &LLWorldMap::getInstance()->mMapLayers[LLWorldMap::getInstance()->mCurrentMap][layer_idx];
- LLViewerImage *current_image = layer->LayerImage;
+ LLViewerFetchedTexture *current_image = layer->LayerImage;
if (current_image->isMissingAsset())
{
@@ -374,10 +367,10 @@ void LLWorldMapView::draw()
continue;
}
- current_image->setBoostLevel(LLViewerImage::BOOST_MAP_LAYER);
+ current_image->setBoostLevel(LLViewerTexture::BOOST_MAP_LAYER);
current_image->setKnownDrawSize(llround(pix_width * LLUI::sGLScaleFactor.mV[VX]), llround(pix_height * LLUI::sGLScaleFactor.mV[VY]));
- if (!current_image->getHasGLTexture())
+ if (!current_image->hasValidGLTexture())
{
continue; // better to draw nothing than the default image
}
@@ -441,8 +434,8 @@ void LLWorldMapView::draw()
U64 handle = (*it).first;
LLSimInfo* info = (*it).second;
- LLViewerImage* simimage = info->mCurrentImage;
- LLViewerImage* overlayimage = info->mOverlayImage;
+ LLViewerFetchedTexture* simimage = info->mCurrentImage;
+ LLViewerFetchedTexture* overlayimage = info->mOverlayImage;
if (gMapScale < SIM_MAP_SCALE)
{
@@ -479,7 +472,7 @@ void LLWorldMapView::draw()
bool sim_visible =
(gMapScale >= map_scale_cutoff) &&
(simimage != NULL) &&
- (simimage->getHasGLTexture());
+ (simimage->hasValidGLTexture());
if (sim_visible)
{
@@ -517,7 +510,7 @@ void LLWorldMapView::draw()
(textures_requested_this_tick < MAX_REQUEST_PER_TICK)))
{
textures_requested_this_tick++;
- info->mCurrentImage = gImageList.getImage(info->mMapImageID[LLWorldMap::getInstance()->mCurrentMap], MIPMAP_TRUE, FALSE);
+ info->mCurrentImage = LLViewerTextureManager::getFetchedTexture(info->mMapImageID[LLWorldMap::getInstance()->mCurrentMap], MIPMAP_TRUE, FALSE, LLViewerTexture::LOD_TEXTURE);
info->mCurrentImage->setAddressMode(LLTexUnit::TAM_CLAMP);
simimage = info->mCurrentImage;
gGL.getTexUnit(0)->bind(simimage);
@@ -530,7 +523,7 @@ void LLWorldMapView::draw()
(textures_requested_this_tick < MAX_REQUEST_PER_TICK)))
{
textures_requested_this_tick++;
- info->mOverlayImage = gImageList.getImage(info->mMapImageID[2], MIPMAP_TRUE, FALSE);
+ info->mOverlayImage = LLViewerTextureManager::getFetchedTexture(info->mMapImageID[2], MIPMAP_TRUE, FALSE, LLViewerTexture::LOD_TEXTURE);
info->mOverlayImage->setAddressMode(LLTexUnit::TAM_CLAMP);
overlayimage = info->mOverlayImage;
gGL.getTexUnit(0)->bind(overlayimage);
@@ -553,13 +546,13 @@ void LLWorldMapView::draw()
S32 draw_size = llround(gMapScale);
if (simimage != NULL)
{
- simimage->setBoostLevel(LLViewerImage::BOOST_MAP);
+ simimage->setBoostLevel(LLViewerTexture::BOOST_MAP);
simimage->setKnownDrawSize(llround(draw_size * LLUI::sGLScaleFactor.mV[VX]), llround(draw_size * LLUI::sGLScaleFactor.mV[VY]));
}
if (overlayimage != NULL)
{
- overlayimage->setBoostLevel(LLViewerImage::BOOST_MAP);
+ overlayimage->setBoostLevel(LLViewerTexture::BOOST_MAP);
overlayimage->setKnownDrawSize(llround(draw_size * LLUI::sGLScaleFactor.mV[VX]), llround(draw_size * LLUI::sGLScaleFactor.mV[VY]));
}
@@ -588,7 +581,7 @@ void LLWorldMapView::draw()
gGL.vertex3f(right, top, 0.f);
gGL.end();
- if (gSavedSettings.getBOOL("MapShowLandForSale") && overlayimage && overlayimage->getHasGLTexture())
+ if (gSavedSettings.getBOOL("MapShowLandForSale") && overlayimage && overlayimage->hasValidGLTexture())
{
gGL.getTexUnit(0)->bind(overlayimage);
gGL.color4f(1.f, 1.f, 1.f, alpha);
@@ -698,6 +691,7 @@ void LLWorldMapView::draw()
LLColor4::white,
LLFontGL::LEFT,
LLFontGL::BASELINE,
+ LLFontGL::NORMAL,
LLFontGL::DROP_SHADOW);
// If map texture is still loading,
@@ -713,6 +707,7 @@ void LLWorldMapView::draw()
LLColor4::white,
LLFontGL::LEFT,
LLFontGL::BASELINE,
+ LLFontGL::NORMAL,
LLFontGL::DROP_SHADOW);
}
}
@@ -801,7 +796,7 @@ void LLWorldMapView::draw()
LLTracker::ETrackingStatus tracking_status = LLTracker::getTrackingStatus();
if ( LLTracker::TRACKING_AVATAR == tracking_status )
{
- drawTracking( LLAvatarTracker::instance().getGlobalPos(), gTrackColor, TRUE, LLTracker::getLabel(), "" );
+ drawTracking( LLAvatarTracker::instance().getGlobalPos(), map_track_color, TRUE, LLTracker::getLabel(), "" );
}
else if ( LLTracker::TRACKING_LANDMARK == tracking_status
|| LLTracker::TRACKING_LOCATION == tracking_status )
@@ -811,7 +806,7 @@ void LLWorldMapView::draw()
LLVector3d pos_global = LLTracker::getTrackedPositionGlobal();
if (!pos_global.isExactlyZero())
{
- drawTracking( pos_global, gTrackColor, TRUE, LLTracker::getLabel(), LLTracker::getToolTip() );
+ drawTracking( pos_global, map_track_color, TRUE, LLTracker::getLabel(), LLTracker::getToolTip() );
}
}
else if (LLWorldMap::getInstance()->mIsTrackingUnknownLocation)
@@ -820,14 +815,14 @@ void LLWorldMapView::draw()
{
// We know this location to be invalid
LLColor4 loading_color(0.0, 0.5, 1.0, 1.0);
- drawTracking( LLWorldMap::getInstance()->mUnknownLocation, loading_color, TRUE, "Invalid Location", "");
+ drawTracking( LLWorldMap::getInstance()->mUnknownLocation, loading_color, TRUE, getString("InvalidLocation"), "");
}
else
{
double value = fmod(current_time, 2);
value = 0.5 + 0.5*cos(value * 3.14159f);
LLColor4 loading_color(0.0, F32(value/2), F32(value), 1.0);
- drawTracking( LLWorldMap::getInstance()->mUnknownLocation, loading_color, TRUE, "Loading...", "");
+ drawTracking( LLWorldMap::getInstance()->mUnknownLocation, loading_color, TRUE, getString("Loading"), "");
}
}
// #endif used to be here
@@ -913,10 +908,10 @@ void LLWorldMapView::drawImageStack(const LLVector3d& global_pos, LLUIImagePtr i
void LLWorldMapView::drawAgents()
{
- F32 agents_scale = (gMapScale * 0.9f) / 256.f;
+ static LLUIColor map_avatar_color = LLUIColorTable::instance().getColor("MapAvatarColor", LLColor4::white);
+ static LLUIColor map_avatar_friend_color = LLUIColorTable::instance().getColor("MapAvatarFriendColor", LLColor4::white);
- LLColor4 avatar_color = gColors.getColor( "MapAvatar" );
- // LLColor4 friend_color = gColors.getColor( "MapFriend" );
+ F32 agents_scale = (gMapScale * 0.9f) / 256.f;
for (handle_list_t::iterator iter = mVisibleRegions.begin(); iter != mVisibleRegions.end(); ++iter)
{
@@ -939,8 +934,8 @@ void LLWorldMapView::drawAgents()
S32 agent_count = info.mExtra;
sim_agent_count += info.mExtra;
// Here's how we'd choose the color if info.mID were available but it's not being sent:
- //LLColor4 color = (agent_count == 1 && is_agent_friend(info.mID)) ? friend_color : avatar_color;
- drawImageStack(info.mPosGlobal, sAvatarSmallImage, agent_count, 3.f, avatar_color);
+ //LLColor4 color = (agent_count == 1 && is_agent_friend(info.mID)) ? map_avatar_friend_color : map_avatar_color;
+ drawImageStack(info.mPosGlobal, sAvatarSmallImage, agent_count, 3.f, map_avatar_color);
}
LLWorldMap::getInstance()->mNumAgents[handle] = sim_agent_count; // override mNumAgents for this sim
}
@@ -955,7 +950,7 @@ void LLWorldMapView::drawAgents()
region_center[VY] += REGION_WIDTH_METERS / 2;
// Reduce the stack size as you zoom out - always display at lease one agent where there is one or more
S32 agent_count = (S32)(((num_agents-1) * agents_scale + (num_agents-1) * 0.1f)+.1f) + 1;
- drawImageStack(region_center, sAvatarSmallImage, agent_count, 3.f, avatar_color);
+ drawImageStack(region_center, sAvatarSmallImage, agent_count, 3.f, map_avatar_color);
}
}
}
@@ -1142,7 +1137,7 @@ void LLWorldMapView::drawTracking(const LLVector3d& pos_global, const LLColor4&
text_x,
text_y,
LLColor4::white, LLFontGL::HCENTER,
- LLFontGL::BASELINE, LLFontGL::DROP_SHADOW);
+ LLFontGL::BASELINE, LLFontGL::NORMAL, LLFontGL::DROP_SHADOW);
if (tooltip != "")
{
@@ -1153,7 +1148,7 @@ void LLWorldMapView::drawTracking(const LLVector3d& pos_global, const LLColor4&
text_x,
text_y,
LLColor4::white, LLFontGL::HCENTER,
- LLFontGL::BASELINE, LLFontGL::DROP_SHADOW);
+ LLFontGL::BASELINE, LLFontGL::NORMAL, LLFontGL::DROP_SHADOW);
}
}
}
@@ -1233,12 +1228,11 @@ BOOL LLWorldMapView::handleToolTip( S32 x, S32 y, std::string& msg, LLRect* stic
msg += region_flags;
}
- S32 SLOP = 4;
- localPointToScreen(
- x - SLOP, y - SLOP,
- &(sticky_rect_screen->mLeft), &(sticky_rect_screen->mBottom) );
- sticky_rect_screen->mRight = sticky_rect_screen->mLeft + 2 * SLOP;
- sticky_rect_screen->mTop = sticky_rect_screen->mBottom + 2 * SLOP;
+ const S32 SLOP = 9;
+ S32 screen_x, screen_y;
+
+ localPointToScreen(x, y, &screen_x, &screen_y);
+ sticky_rect_screen->setCenterAndSize(screen_x, screen_y, SLOP, SLOP);
}
return TRUE;
}
@@ -1338,6 +1332,7 @@ void LLWorldMapView::drawIconName(F32 x_pixels,
color,
LLFontGL::HCENTER,
LLFontGL::TOP,
+ LLFontGL::NORMAL,
LLFontGL::DROP_SHADOW);
text_y -= llround(LLFontGL::getFontSansSerif()->getLineHeight());
@@ -1349,6 +1344,7 @@ void LLWorldMapView::drawIconName(F32 x_pixels,
color,
LLFontGL::HCENTER,
LLFontGL::TOP,
+ LLFontGL::NORMAL,
LLFontGL::DROP_SHADOW);
}
@@ -1886,27 +1882,27 @@ BOOL LLWorldMapView::handleDoubleClick( S32 x, S32 y, MASK mask )
case MAP_ITEM_MATURE_EVENT:
case MAP_ITEM_ADULT_EVENT:
{
- gFloaterWorldMap->close();
+ LLFloaterReg::hideInstance("world_map");
// This is an ungainly hack
std::string uuid_str;
S32 event_id;
id.toString(uuid_str);
uuid_str = uuid_str.substr(28);
sscanf(uuid_str.c_str(), "%X", &event_id);
- LLFloaterDirectory::showEvents(event_id);
+ LLFloaterReg::showInstance("search", LLSD().insert("panel", "event").insert("id", event_id));
break;
}
case MAP_ITEM_LAND_FOR_SALE:
case MAP_ITEM_LAND_FOR_SALE_ADULT:
{
- gFloaterWorldMap->close();
- LLFloaterDirectory::showLandForSale(id);
+ LLFloaterReg::hideInstance("world_map");
+ LLFloaterReg::showInstance("search", LLSD().insert("panel", "land").insert("id", id));
break;
}
case MAP_ITEM_CLASSIFIED:
{
- gFloaterWorldMap->close();
- LLFloaterDirectory::showClassified(id);
+ LLFloaterReg::hideInstance("world_map");
+ LLFloaterReg::showInstance("search", LLSD().insert("panel", "classified").insert("id", id));
break;
}
default:
diff --git a/indra/newview/llworldmapview.h b/indra/newview/llworldmapview.h
index 1717b76beb..41c9772694 100644
--- a/indra/newview/llworldmapview.h
+++ b/indra/newview/llworldmapview.h
@@ -39,7 +39,7 @@
#include "v3math.h"
#include "v3dmath.h"
#include "v4color.h"
-#include "llviewerimage.h"
+#include "llviewertexture.h"
#include "llmapimagetype.h"
#include "llworldmap.h"
@@ -50,7 +50,7 @@ const S32 DEFAULT_TRACKING_ARROW_SIZE = 16;
class LLColor4;
class LLColor4U;
class LLCoordGL;
-class LLViewerImage;
+class LLViewerTexture;
class LLTextBox;
@@ -60,9 +60,11 @@ public:
static void initClass();
static void cleanupClass();
- LLWorldMapView(const std::string& name, const LLRect& rect );
+ LLWorldMapView();
virtual ~LLWorldMapView();
-
+
+ virtual BOOL postBuild();
+
virtual void reshape(S32 width, S32 height, BOOL called_from_parent = TRUE );
virtual void setVisible(BOOL visible);
diff --git a/indra/newview/macview_Prefix.h b/indra/newview/macview_Prefix.h
index 8cbabb5103..0fcdf2da4f 100644
--- a/indra/newview/macview_Prefix.h
+++ b/indra/newview/macview_Prefix.h
@@ -63,20 +63,17 @@
#include "lldrawable.h"
#include "llfirstuse.h"
#include "llfloater.h"
-#include "llfloateravatarinfo.h"
#include "llfloaterbuildoptions.h"
#include "llfloaterchat.h"
#include "llfloatercustomize.h"
#include "llfloaterdirectory.h"
#include "llfloatergroups.h"
-#include "llfloatermap.h"
#include "llfloaterworldmap.h"
#include "llfloatermute.h"
#include "llconversation.h"
#include "llfloatertools.h"
#include "llhudeffectlookat.h"
#include "llhudmanager.h"
-#include "llinventoryview.h"
#include "lljoystickbutton.h"
#include "llmenugl.h"
#include "llmorphview.h"
@@ -92,7 +89,6 @@
#include "lltoolgrab.h"
#include "lltoolmgr.h"
#include "lltoolpie.h"
-#include "lltoolview.h"
#include "llui.h" // for make_ui_sound
#include "llviewercamera.h"
#include "llviewermenu.h"
diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp
index ebf2f91aa2..b0c3e8d711 100644
--- a/indra/newview/pipeline.cpp
+++ b/indra/newview/pipeline.cpp
@@ -35,15 +35,15 @@
#include "pipeline.h"
// library includes
-#include "audioengine.h" // For MAX_BUFFERS for debugging.
+#include "llaudioengine.h" // For MAX_BUFFERS for debugging.
#include "imageids.h"
#include "llerror.h"
#include "llviewercontrol.h"
#include "llfasttimer.h"
#include "llfontgl.h"
-#include "llmemory.h"
#include "llmemtype.h"
#include "llnamevalue.h"
+#include "llpointer.h"
#include "llprimitive.h"
#include "llvolume.h"
#include "material_codes.h"
@@ -52,6 +52,7 @@
#include "llui.h"
#include "llglheaders.h"
#include "llrender.h"
+#include "llwindow.h" // swapBuffers()
// newview includes
#include "llagent.h"
@@ -65,7 +66,7 @@
#include "llface.h"
#include "llfeaturemanager.h"
#include "llfloatertelehub.h"
-#include "llframestats.h"
+#include "llfloaterreg.h"
#include "llgldbg.h"
#include "llhudmanager.h"
#include "lllightconstants.h"
@@ -76,13 +77,13 @@
#include "lltool.h"
#include "lltoolmgr.h"
#include "llviewercamera.h"
-#include "llviewerimagelist.h"
+#include "llviewertexturelist.h"
#include "llviewerobject.h"
#include "llviewerobjectlist.h"
#include "llviewerparcelmgr.h"
#include "llviewerregion.h" // for audio debugging.
#include "llviewerwindow.h" // For getSpinAxis
-#include "llvoavatar.h"
+#include "llvoavatarself.h"
#include "llvoground.h"
#include "llvosky.h"
#include "llvotree.h"
@@ -93,8 +94,8 @@
#include "llvopartgroup.h"
#include "llworld.h"
#include "llcubemap.h"
-#include "lldebugmessagebox.h"
#include "llviewershadermgr.h"
+#include "llviewerstats.h"
#include "llviewerjoystick.h"
#include "llviewerdisplay.h"
#include "llwlparammanager.h"
@@ -121,8 +122,7 @@ const U32 REFLECTION_MAP_RES = 128;
const S32 MAX_OCCLUDER_COUNT = 2;
extern S32 gBoxFrame;
-extern BOOL gRenderLightGlows;
-extern BOOL gHideSelectedObjects;
+//extern BOOL gHideSelectedObjects;
extern BOOL gDisplaySwapBuffers;
extern BOOL gDebugGL;
@@ -138,6 +138,33 @@ BOOL gDebugPipeline = FALSE;
LLPipeline gPipeline;
const LLMatrix4* gGLLastMatrix = NULL;
+LLFastTimer::DeclareTimer FTM_RENDER_GEOMETRY("Geometry");
+LLFastTimer::DeclareTimer FTM_RENDER_GRASS("Grass");
+LLFastTimer::DeclareTimer FTM_RENDER_INVISIBLE("Invisible");
+LLFastTimer::DeclareTimer FTM_RENDER_OCCLUSION("Occlusion");
+LLFastTimer::DeclareTimer FTM_RENDER_SHINY("Shiny");
+LLFastTimer::DeclareTimer FTM_RENDER_SIMPLE("Simple");
+LLFastTimer::DeclareTimer FTM_RENDER_TERRAIN("Terrain");
+LLFastTimer::DeclareTimer FTM_RENDER_TREES("Trees");
+LLFastTimer::DeclareTimer FTM_RENDER_UI("UI");
+LLFastTimer::DeclareTimer FTM_RENDER_WATER("Water");
+LLFastTimer::DeclareTimer FTM_RENDER_WL_SKY("Windlight Sky");
+LLFastTimer::DeclareTimer FTM_RENDER_ALPHA("Alpha Objects");
+LLFastTimer::DeclareTimer FTM_RENDER_CHARACTERS("Avatars");
+LLFastTimer::DeclareTimer FTM_RENDER_BUMP("Bump");
+LLFastTimer::DeclareTimer FTM_RENDER_FULLBRIGHT("Fullbright");
+LLFastTimer::DeclareTimer FTM_RENDER_GLOW("Glow");
+LLFastTimer::DeclareTimer FTM_GEO_UPDATE("Geo Update");
+LLFastTimer::DeclareTimer FTM_POOLRENDER("RenderPool");
+LLFastTimer::DeclareTimer FTM_POOLS("Pools");
+LLFastTimer::DeclareTimer FTM_RENDER_BLOOM_FBO("First FBO");
+LLFastTimer::DeclareTimer FTM_STATESORT("Sort Draw State");
+LLFastTimer::DeclareTimer FTM_PIPELINE("Pipeline");
+LLFastTimer::DeclareTimer FTM_CLIENT_COPY("Client Copy");
+
+static LLFastTimer::DeclareTimer FTM_STATESORT_DRAWABLE("Sort Drawables");
+static LLFastTimer::DeclareTimer FTM_STATESORT_POSTSORT("Post Sort");
+
//----------------------------------------
std::string gPoolNames[] =
{
@@ -317,7 +344,7 @@ LLPipeline::LLPipeline() :
void LLPipeline::init()
{
- LLMemType mt(LLMemType::MTYPE_PIPELINE);
+ LLMemType mt(LLMemType::MTYPE_PIPELINE_INIT);
sDynamicLOD = gSavedSettings.getBOOL("RenderDynamicLOD");
sRenderBump = gSavedSettings.getBOOL("RenderObjectBump");
@@ -337,7 +364,7 @@ void LLPipeline::init()
getPool(LLDrawPool::POOL_BUMP);
getPool(LLDrawPool::POOL_GLOW);
- mTrianglesDrawnStat.reset();
+ LLViewerStats::getInstance()->mTrianglesDrawnStat.reset();
resetFrameStats();
mRenderTypeMask = 0xffffffff; // All render types start on
@@ -466,8 +493,8 @@ void LLPipeline::resizeScreenTexture()
{
if (gPipeline.canUseVertexShaders() && assertInitialized())
{
- GLuint resX = gViewerWindow->getWindowDisplayWidth();
- GLuint resY = gViewerWindow->getWindowDisplayHeight();
+ GLuint resX = gViewerWindow->getWorldViewWidth();
+ GLuint resY = gViewerWindow->getWorldViewHeight();
U32 res_mod = gSavedSettings.getU32("RenderResolutionDivisor");
if (res_mod > 1 && res_mod < resX && res_mod < resY)
@@ -577,6 +604,7 @@ void LLPipeline::releaseGLBuffers()
void LLPipeline::createGLBuffers()
{
+ LLMemType mt_cb(LLMemType::MTYPE_PIPELINE_CREATE_BUFFERS);
assertInitialized();
updateRenderDeferred();
@@ -592,6 +620,9 @@ void LLPipeline::createGLBuffers()
stop_glerror();
+ GLuint resX = gViewerWindow->getWorldViewWidth();
+ GLuint resY = gViewerWindow->getWorldViewHeight();
+
if (LLPipeline::sRenderGlow)
{ //screen space glow buffers
const U32 glow_res = llmax(1,
@@ -601,13 +632,10 @@ void LLPipeline::createGLBuffers()
{
mGlow[i].allocate(512,glow_res,GL_RGBA,FALSE,FALSE);
}
- }
- GLuint resX = gViewerWindow->getWindowDisplayWidth();
- GLuint resY = gViewerWindow->getWindowDisplayHeight();
+ allocateScreenBuffer(resX,resY);
+ }
- allocateScreenBuffer(resX,resY);
-
if (sRenderDeferred)
{
mSunShadow[0].allocate(1024,1024, 0, TRUE, FALSE);
@@ -639,6 +667,7 @@ void LLPipeline::createGLBuffers()
void LLPipeline::restoreGL()
{
+ LLMemType mt_cb(LLMemType::MTYPE_PIPELINE_RESTORE_GL);
assertInitialized();
if (mVertexShadersEnabled)
@@ -693,6 +722,7 @@ BOOL LLPipeline::canUseWindLightShadersOnObjects() const
void LLPipeline::unloadShaders()
{
+ LLMemType mt_us(LLMemType::MTYPE_PIPELINE_UNLOAD_SHADERS);
LLViewerShaderMgr::instance()->unloadShaders();
mVertexShadersLoaded = 0;
@@ -724,6 +754,7 @@ S32 LLPipeline::getMaxLightingDetail() const
S32 LLPipeline::setLightingDetail(S32 level)
{
+ LLMemType mt_ld(LLMemType::MTYPE_PIPELINE_LIGHTING_DETAIL);
assertInitialized();
if (level < 0)
@@ -748,9 +779,9 @@ S32 LLPipeline::setLightingDetail(S32 level)
class LLOctreeDirtyTexture : public LLOctreeTraveler<LLDrawable>
{
public:
- const std::set<LLViewerImage*>& mTextures;
+ const std::set<LLViewerFetchedTexture*>& mTextures;
- LLOctreeDirtyTexture(const std::set<LLViewerImage*>& textures) : mTextures(textures) { }
+ LLOctreeDirtyTexture(const std::set<LLViewerFetchedTexture*>& textures) : mTextures(textures) { }
virtual void visit(const LLOctreeNode<LLDrawable>* node)
{
@@ -763,7 +794,8 @@ public:
for (LLSpatialGroup::drawmap_elem_t::iterator j = i->second.begin(); j != i->second.end(); ++j)
{
LLDrawInfo* params = *j;
- if (mTextures.find(params->mTexture) != mTextures.end())
+ LLViewerFetchedTexture* tex = LLViewerTextureManager::staticCastToFetchedTexture(params->mTexture);
+ if (tex && mTextures.find(tex) != mTextures.end())
{
group->setState(LLSpatialGroup::GEOM_DIRTY);
}
@@ -780,7 +812,7 @@ public:
};
// Called when a texture changes # of channels (causes faces to move to alpha pool)
-void LLPipeline::dirtyPoolObjectTextures(const std::set<LLViewerImage*>& textures)
+void LLPipeline::dirtyPoolObjectTextures(const std::set<LLViewerFetchedTexture*>& textures)
{
assertInitialized();
@@ -812,7 +844,7 @@ void LLPipeline::dirtyPoolObjectTextures(const std::set<LLViewerImage*>& texture
}
}
-LLDrawPool *LLPipeline::findPool(const U32 type, LLViewerImage *tex0)
+LLDrawPool *LLPipeline::findPool(const U32 type, LLViewerTexture *tex0)
{
assertInitialized();
@@ -884,7 +916,7 @@ LLDrawPool *LLPipeline::findPool(const U32 type, LLViewerImage *tex0)
}
-LLDrawPool *LLPipeline::getPool(const U32 type, LLViewerImage *tex0)
+LLDrawPool *LLPipeline::getPool(const U32 type, LLViewerTexture *tex0)
{
LLMemType mt(LLMemType::MTYPE_PIPELINE);
LLDrawPool *poolp = findPool(type, tex0);
@@ -901,7 +933,7 @@ LLDrawPool *LLPipeline::getPool(const U32 type, LLViewerImage *tex0)
// static
-LLDrawPool* LLPipeline::getPoolFromTE(const LLTextureEntry* te, LLViewerImage* imagep)
+LLDrawPool* LLPipeline::getPoolFromTE(const LLTextureEntry* te, LLViewerTexture* imagep)
{
LLMemType mt(LLMemType::MTYPE_PIPELINE);
U32 type = getPoolTypeFromTE(te, imagep);
@@ -909,9 +941,9 @@ LLDrawPool* LLPipeline::getPoolFromTE(const LLTextureEntry* te, LLViewerImage* i
}
//static
-U32 LLPipeline::getPoolTypeFromTE(const LLTextureEntry* te, LLViewerImage* imagep)
+U32 LLPipeline::getPoolTypeFromTE(const LLTextureEntry* te, LLViewerTexture* imagep)
{
- LLMemType mt(LLMemType::MTYPE_PIPELINE);
+ LLMemType mt_gpt(LLMemType::MTYPE_PIPELINE_GET_POOL_TYPE);
if (!te || !imagep)
{
@@ -921,7 +953,7 @@ U32 LLPipeline::getPoolTypeFromTE(const LLTextureEntry* te, LLViewerImage* image
bool alpha = te->getColor().mV[3] < 0.999f;
if (imagep)
{
- alpha = alpha || (imagep->getComponents() == 4 && ! imagep->mIsMediaTexture) || (imagep->getComponents() == 2);
+ alpha = alpha || (imagep->getComponents() == 4 && imagep->getType() != LLViewerTexture::MEDIA_TEXTURE) || (imagep->getComponents() == 2);
}
if (alpha)
@@ -941,7 +973,7 @@ U32 LLPipeline::getPoolTypeFromTE(const LLTextureEntry* te, LLViewerImage* image
void LLPipeline::addPool(LLDrawPool *new_poolp)
{
- LLMemType mt(LLMemType::MTYPE_PIPELINE);
+ LLMemType mt_a(LLMemType::MTYPE_PIPELINE_ADD_POOL);
assertInitialized();
mPools.insert(new_poolp);
addToQuickLookup( new_poolp );
@@ -949,7 +981,7 @@ void LLPipeline::addPool(LLDrawPool *new_poolp)
void LLPipeline::allocDrawable(LLViewerObject *vobj)
{
- LLMemType mt(LLMemType::MTYPE_DRAWABLE);
+ LLMemType mt_ad(LLMemType::MTYPE_PIPELINE_ALLOCATE_DRAWABLE);
LLDrawable *drawable = new LLDrawable();
vobj->mDrawable = drawable;
@@ -968,7 +1000,7 @@ void LLPipeline::allocDrawable(LLViewerObject *vobj)
void LLPipeline::unlinkDrawable(LLDrawable *drawable)
{
- LLFastTimer t(LLFastTimer::FTM_PIPELINE);
+ LLFastTimer t(FTM_PIPELINE);
assertInitialized();
@@ -1010,6 +1042,7 @@ void LLPipeline::unlinkDrawable(LLDrawable *drawable)
U32 LLPipeline::addObject(LLViewerObject *vobj)
{
+ LLMemType mt_ao(LLMemType::MTYPE_PIPELINE_ADD_OBJECT);
if (gNoRender)
{
return 0;
@@ -1029,8 +1062,8 @@ U32 LLPipeline::addObject(LLViewerObject *vobj)
void LLPipeline::createObjects(F32 max_dtime)
{
- LLFastTimer ftm(LLFastTimer::FTM_GEO_UPDATE);
- LLMemType mt(LLMemType::MTYPE_DRAWABLE);
+ LLFastTimer ftm(FTM_GEO_UPDATE);
+ LLMemType mt(LLMemType::MTYPE_PIPELINE_CREATE_OBJECTS);
LLTimer update_timer;
@@ -1093,7 +1126,7 @@ void LLPipeline::resetFrameStats()
{
assertInitialized();
- mTrianglesDrawnStat.addValue(mTrianglesDrawn/1000.f);
+ LLViewerStats::getInstance()->mTrianglesDrawnStat.addValue(mTrianglesDrawn/1000.f);
if (mBatchCount > 0)
{
@@ -1195,10 +1228,13 @@ void LLPipeline::updateMovedList(LLDrawable::drawable_vector_t& moved_list)
}
}
+static LLFastTimer::DeclareTimer FTM_OCTREE_BALANCE("Balance Octree");
+static LLFastTimer::DeclareTimer FTM_UPDATE_MOVE("Update Move");
+
void LLPipeline::updateMove()
{
- LLFastTimer t(LLFastTimer::FTM_UPDATE_MOVE);
- LLMemType mt(LLMemType::MTYPE_PIPELINE);
+ LLFastTimer t(FTM_UPDATE_MOVE);
+ LLMemType mt_um(LLMemType::MTYPE_PIPELINE_UPDATE_MOVE);
if (gSavedSettings.getBOOL("FreezeTime"))
{
@@ -1243,7 +1279,7 @@ void LLPipeline::updateMove()
//balance octrees
{
- LLFastTimer ot(LLFastTimer::FTM_OCTREE_BALANCE);
+ LLFastTimer ot(FTM_OCTREE_BALANCE);
for (LLWorld::region_list_t::const_iterator iter = LLWorld::getInstance()->getRegionList().begin();
iter != LLWorld::getInstance()->getRegionList().end(); ++iter)
@@ -1348,11 +1384,12 @@ BOOL LLPipeline::getVisibleExtents(LLCamera& camera, LLVector3& min, LLVector3&
return res;
}
+static LLFastTimer::DeclareTimer FTM_CULL("Object Culling");
void LLPipeline::updateCull(LLCamera& camera, LLCullResult& result, S32 water_clip)
{
- LLFastTimer t(LLFastTimer::FTM_CULL);
- LLMemType mt(LLMemType::MTYPE_PIPELINE);
+ LLFastTimer t(FTM_CULL);
+ LLMemType mt_uc(LLMemType::MTYPE_PIPELINE_UPDATE_CULL);
grabReferences(result);
@@ -1563,10 +1600,10 @@ BOOL LLPipeline::updateDrawableGeom(LLDrawable* drawablep, BOOL priority)
void LLPipeline::updateGeom(F32 max_dtime)
{
LLTimer update_timer;
- LLMemType mt(LLMemType::MTYPE_PIPELINE);
+ LLMemType mt(LLMemType::MTYPE_PIPELINE_UPDATE_GEOM);
LLPointer<LLDrawable> drawablep;
- LLFastTimer t(LLFastTimer::FTM_GEO_UPDATE);
+ LLFastTimer t(FTM_GEO_UPDATE);
assertInitialized();
@@ -1666,7 +1703,7 @@ void LLPipeline::updateGeom(F32 max_dtime)
void LLPipeline::markVisible(LLDrawable *drawablep, LLCamera& camera)
{
- LLMemType mt(LLMemType::MTYPE_PIPELINE);
+ LLMemType mt(LLMemType::MTYPE_PIPELINE_MARK_VISIBLE);
if(!drawablep || drawablep->isDead())
{
return;
@@ -1686,7 +1723,7 @@ void LLPipeline::markVisible(LLDrawable *drawablep, LLCamera& camera)
void LLPipeline::markMoved(LLDrawable *drawablep, BOOL damped_motion)
{
- LLMemType mt(LLMemType::MTYPE_PIPELINE);
+ LLMemType mt_mm(LLMemType::MTYPE_PIPELINE_MARK_MOVED);
if (!drawablep)
{
@@ -1732,7 +1769,7 @@ void LLPipeline::markMoved(LLDrawable *drawablep, BOOL damped_motion)
void LLPipeline::markShift(LLDrawable *drawablep)
{
- LLMemType mt(LLMemType::MTYPE_PIPELINE);
+ LLMemType mt(LLMemType::MTYPE_PIPELINE_MARK_SHIFT);
if (!drawablep || drawablep->isDead())
{
@@ -1755,7 +1792,7 @@ void LLPipeline::markShift(LLDrawable *drawablep)
void LLPipeline::shiftObjects(const LLVector3 &offset)
{
- LLMemType mt(LLMemType::MTYPE_PIPELINE);
+ LLMemType mt(LLMemType::MTYPE_PIPELINE_SHIFT_OBJECTS);
assertInitialized();
@@ -1795,7 +1832,7 @@ void LLPipeline::shiftObjects(const LLVector3 &offset)
void LLPipeline::markTextured(LLDrawable *drawablep)
{
- LLMemType mt(LLMemType::MTYPE_PIPELINE);
+ LLMemType mt(LLMemType::MTYPE_PIPELINE_MARK_TEXTURED);
if (drawablep && !drawablep->isDead() && assertInitialized())
{
@@ -1805,7 +1842,7 @@ void LLPipeline::markTextured(LLDrawable *drawablep)
void LLPipeline::markRebuild(LLDrawable *drawablep, LLDrawable::EDrawableFlags flag, BOOL priority)
{
- LLMemType mt(LLMemType::MTYPE_PIPELINE);
+ LLMemType mt(LLMemType::MTYPE_PIPELINE_MARK_REBUILD);
if (drawablep && !drawablep->isDead() && assertInitialized())
{
@@ -1834,6 +1871,8 @@ void LLPipeline::markRebuild(LLDrawable *drawablep, LLDrawable::EDrawableFlags f
}
}
+static LLFastTimer::DeclareTimer FTM_RESET_DRAWORDER("Reset Draw Order");
+
void LLPipeline::stateSort(LLCamera& camera, LLCullResult &result)
{
const U32 face_mask = (1 << LLPipeline::RENDER_TYPE_AVATAR) |
@@ -1846,12 +1885,12 @@ void LLPipeline::stateSort(LLCamera& camera, LLCullResult &result)
if (mRenderTypeMask & face_mask)
{
//clear faces from face pools
- LLFastTimer t(LLFastTimer::FTM_RESET_DRAWORDER);
+ LLFastTimer t(FTM_RESET_DRAWORDER);
gPipeline.resetDrawOrders();
}
- LLFastTimer ftm(LLFastTimer::FTM_STATESORT);
- LLMemType mt(LLMemType::MTYPE_PIPELINE);
+ LLFastTimer ftm(FTM_STATESORT);
+ LLMemType mt(LLMemType::MTYPE_PIPELINE_STATE_SORT);
//LLVertexBuffer::unbind();
@@ -1906,7 +1945,7 @@ void LLPipeline::stateSort(LLCamera& camera, LLCullResult &result)
}
{
- LLFastTimer ftm(LLFastTimer::FTM_STATESORT_DRAWABLE);
+ LLFastTimer ftm(FTM_STATESORT_DRAWABLE);
for (LLCullResult::drawable_list_t::iterator iter = sCull->beginVisibleList();
iter != sCull->endVisibleList(); ++iter)
{
@@ -1919,7 +1958,7 @@ void LLPipeline::stateSort(LLCamera& camera, LLCullResult &result)
}
{
- LLFastTimer ftm(LLFastTimer::FTM_CLIENT_COPY);
+ LLFastTimer ftm(FTM_CLIENT_COPY);
LLVertexBuffer::clientCopy();
}
@@ -1928,7 +1967,7 @@ void LLPipeline::stateSort(LLCamera& camera, LLCullResult &result)
void LLPipeline::stateSort(LLSpatialGroup* group, LLCamera& camera)
{
- LLMemType mt(LLMemType::MTYPE_PIPELINE);
+ LLMemType mt(LLMemType::MTYPE_PIPELINE_STATE_SORT);
if (!sSkipUpdate && group->changeLOD())
{
for (LLSpatialGroup::element_iter i = group->getData().begin(); i != group->getData().end(); ++i)
@@ -1942,7 +1981,7 @@ void LLPipeline::stateSort(LLSpatialGroup* group, LLCamera& camera)
void LLPipeline::stateSort(LLSpatialBridge* bridge, LLCamera& camera)
{
- LLMemType mt(LLMemType::MTYPE_PIPELINE);
+ LLMemType mt(LLMemType::MTYPE_PIPELINE_STATE_SORT);
if (!sSkipUpdate && bridge->getSpatialGroup()->changeLOD())
{
bool force_update = false;
@@ -1952,7 +1991,7 @@ void LLPipeline::stateSort(LLSpatialBridge* bridge, LLCamera& camera)
void LLPipeline::stateSort(LLDrawable* drawablep, LLCamera& camera)
{
- LLMemType mt(LLMemType::MTYPE_PIPELINE);
+ LLMemType mt(LLMemType::MTYPE_PIPELINE_STATE_SORT);
if (!drawablep
|| drawablep->isDead()
@@ -1961,7 +2000,7 @@ void LLPipeline::stateSort(LLDrawable* drawablep, LLCamera& camera)
return;
}
- if (gHideSelectedObjects)
+ if (LLSelectMgr::getInstance()->mHideSelectedObjects)
{
if (drawablep->getVObj().notNull() &&
drawablep->getVObj()->isSelected())
@@ -2181,8 +2220,8 @@ void renderSoundHighlights(LLDrawable* drawablep)
void LLPipeline::postSort(LLCamera& camera)
{
- LLMemType mt(LLMemType::MTYPE_PIPELINE);
- LLFastTimer ftm(LLFastTimer::FTM_STATESORT_POSTSORT);
+ LLMemType mt(LLMemType::MTYPE_PIPELINE_POST_SORT);
+ LLFastTimer ftm(FTM_STATESORT_POSTSORT);
assertInitialized();
@@ -2294,7 +2333,7 @@ void LLPipeline::postSort(LLCamera& camera)
}
// only render if the flag is set. The flag is only set if we are in edit mode or the toggle is set in the menus
- if (gSavedSettings.getBOOL("BeaconAlwaysOn") && !sShadowRender)
+ if (LLFloaterReg::instanceVisible("beacons") && !sShadowRender)
{
if (sRenderScriptedTouchBeacons)
{
@@ -2375,7 +2414,8 @@ void LLPipeline::postSort(LLCamera& camera)
void render_hud_elements()
{
- LLFastTimer t(LLFastTimer::FTM_RENDER_UI);
+ LLMemType mt_rhe(LLMemType::MTYPE_PIPELINE_RENDER_HUD_ELS);
+ LLFastTimer t(FTM_RENDER_UI);
gPipeline.disableLights();
LLGLDisable fog(GL_FOG);
@@ -2419,7 +2459,7 @@ void render_hud_elements()
void LLPipeline::renderHighlights()
{
- LLMemType mt(LLMemType::MTYPE_PIPELINE);
+ LLMemType mt(LLMemType::MTYPE_PIPELINE_RENDER_HL);
assertInitialized();
@@ -2441,7 +2481,7 @@ void LLPipeline::renderHighlights()
// Make sure the selection image gets downloaded and decoded
if (!mFaceSelectImagep)
{
- mFaceSelectImagep = gImageList.getImage(IMG_FACE_SELECT);
+ mFaceSelectImagep = LLViewerTextureManager::getFetchedTexture(IMG_FACE_SELECT);
}
mFaceSelectImagep->addTextureStats((F32)MAX_IMAGE_AREA);
@@ -2471,7 +2511,7 @@ void LLPipeline::renderHighlights()
for (S32 i = 0; i < count; i++)
{
LLFace* facep = mHighlightFaces[i];
- facep->renderSelected(LLViewerImage::sNullImagep, color);
+ facep->renderSelected(LLViewerTexture::sNullImagep, color);
}
}
@@ -2487,8 +2527,8 @@ void LLPipeline::renderHighlights()
void LLPipeline::renderGeom(LLCamera& camera, BOOL forceVBOUpdate)
{
- LLMemType mt(LLMemType::MTYPE_PIPELINE);
- LLFastTimer t(LLFastTimer::FTM_RENDER_GEOMETRY);
+ LLMemType mt(LLMemType::MTYPE_PIPELINE_RENDER_GEOM);
+ LLFastTimer t(FTM_RENDER_GEOMETRY);
assertInitialized();
@@ -2512,7 +2552,6 @@ void LLPipeline::renderGeom(LLCamera& camera, BOOL forceVBOUpdate)
//
stop_glerror();
- gFrameStats.start(LLFrameStats::RENDER_SYNC);
LLVertexBuffer::unbind();
@@ -2538,7 +2577,6 @@ void LLPipeline::renderGeom(LLCamera& camera, BOOL forceVBOUpdate)
if(forceVBOUpdate)
gSky.mVOSkyp->updateDummyVertexBuffer() ;
- gFrameStats.start(LLFrameStats::RENDER_GEOM);
// Initialize lots of GL state to "safe" values
glMatrixMode(GL_TEXTURE);
@@ -2562,8 +2600,8 @@ void LLPipeline::renderGeom(LLCamera& camera, BOOL forceVBOUpdate)
sUnderWaterRender = FALSE;
}
- gGL.getTexUnit(0)->bind(LLViewerImage::sDefaultImagep);
- LLViewerImage::sDefaultImagep->setAddressMode(LLTexUnit::TAM_WRAP);
+ gGL.getTexUnit(0)->bind(LLViewerFetchedTexture::sDefaultImagep);
+ LLViewerFetchedTexture::sDefaultImagep->setAddressMode(LLTexUnit::TAM_WRAP);
//////////////////////////////////////////////
//
@@ -2589,7 +2627,7 @@ void LLPipeline::renderGeom(LLCamera& camera, BOOL forceVBOUpdate)
}
else
{
- LLFastTimer t(LLFastTimer::FTM_POOLS);
+ LLFastTimer t(FTM_POOLS);
// HACK: don't calculate local lights if we're rendering the HUD!
// Removing this check will cause bad flickering when there are
@@ -2621,7 +2659,7 @@ void LLPipeline::renderGeom(LLCamera& camera, BOOL forceVBOUpdate)
pool_set_t::iterator iter2 = iter1;
if (hasRenderType(poolp->getType()) && poolp->getNumPasses() > 0)
{
- LLFastTimer t(LLFastTimer::FTM_POOLRENDER);
+ LLFastTimer t(FTM_POOLRENDER);
gGLLastMatrix = NULL;
glLoadMatrixd(gGLModelView);
@@ -2648,6 +2686,10 @@ void LLPipeline::renderGeom(LLCamera& camera, BOOL forceVBOUpdate)
glGetIntegerv(GL_MODELVIEW_STACK_DEPTH, &depth);
if (depth > 3)
{
+ if (gDebugSession)
+ {
+ ll_fail("GL matrix stack corrupted.");
+ }
llerrs << "GL matrix stack corrupted!" << llendl;
}
std::string msg = llformat("%s pass %d", gPoolNames[cur_type].c_str(), i);
@@ -2749,9 +2791,11 @@ void LLPipeline::renderGeom(LLCamera& camera, BOOL forceVBOUpdate)
void LLPipeline::renderGeomDeferred(LLCamera& camera)
{
LLAppViewer::instance()->pingMainloopTimeout("Pipeline:RenderGeomDeferred");
- LLFastTimer t(LLFastTimer::FTM_RENDER_GEOMETRY);
- LLFastTimer t2(LLFastTimer::FTM_POOLS);
+ LLMemType mt_rgd(LLMemType::MTYPE_PIPELINE_RENDER_GEOM_DEFFERRED);
+ LLFastTimer t(FTM_RENDER_GEOMETRY);
+
+ LLFastTimer t2(FTM_POOLS);
LLGLEnable cull(GL_CULL_FACE);
@@ -2793,7 +2837,7 @@ void LLPipeline::renderGeomDeferred(LLCamera& camera)
pool_set_t::iterator iter2 = iter1;
if (hasRenderType(poolp->getType()) && poolp->getNumDeferredPasses() > 0)
{
- LLFastTimer t(LLFastTimer::FTM_POOLRENDER);
+ LLFastTimer t(FTM_POOLRENDER);
gGLLastMatrix = NULL;
glLoadMatrixd(gGLModelView);
@@ -2850,7 +2894,8 @@ void LLPipeline::renderGeomDeferred(LLCamera& camera)
void LLPipeline::renderGeomPostDeferred(LLCamera& camera)
{
- LLFastTimer t(LLFastTimer::FTM_POOLS);
+ LLMemType mt_rgpd(LLMemType::MTYPE_PIPELINE_RENDER_GEOM_POST_DEF);
+ LLFastTimer t(FTM_POOLS);
U32 cur_type = 0;
LLGLEnable cull(GL_CULL_FACE);
@@ -2883,7 +2928,7 @@ void LLPipeline::renderGeomPostDeferred(LLCamera& camera)
pool_set_t::iterator iter2 = iter1;
if (hasRenderType(poolp->getType()) && poolp->getNumPostDeferredPasses() > 0)
{
- LLFastTimer t(LLFastTimer::FTM_POOLRENDER);
+ LLFastTimer t(FTM_POOLRENDER);
gGLLastMatrix = NULL;
glLoadMatrixd(gGLModelView);
@@ -2961,6 +3006,7 @@ void LLPipeline::renderGeomPostDeferred(LLCamera& camera)
void LLPipeline::renderGeomShadow(LLCamera& camera)
{
+ LLMemType mt_rgs(LLMemType::MTYPE_PIPELINE_RENDER_GEOM_SHADOW);
U32 cur_type = 0;
LLGLEnable cull(GL_CULL_FACE);
@@ -3222,7 +3268,7 @@ void LLPipeline::renderForSelect(std::set<LLViewerObject*>& objects, BOOL render
stateSort((*iter)->mDrawable, *LLViewerCamera::getInstance());
}
- LLMemType mt(LLMemType::MTYPE_PIPELINE);
+ LLMemType mt(LLMemType::MTYPE_PIPELINE_RENDER_SELECT);
@@ -3297,7 +3343,7 @@ void LLPipeline::renderForSelect(std::set<LLViewerObject*>& objects, BOOL render
LLDrawable* drawable = vobj->mDrawable;
if (vobj->isDead() ||
vobj->isHUDAttachment() ||
- (gHideSelectedObjects && vobj->isSelected()) ||
+ (LLSelectMgr::getInstance()->mHideSelectedObjects && vobj->isSelected()) ||
drawable->isDead() ||
!hasRenderType(drawable->getRenderType()))
{
@@ -3387,7 +3433,7 @@ void LLPipeline::renderForSelect(std::set<LLViewerObject*>& objects, BOOL render
void LLPipeline::rebuildPools()
{
- LLMemType mt(LLMemType::MTYPE_PIPELINE);
+ LLMemType mt(LLMemType::MTYPE_PIPELINE_REBUILD_POOLS);
assertInitialized();
@@ -3427,7 +3473,7 @@ void LLPipeline::rebuildPools()
void LLPipeline::addToQuickLookup( LLDrawPool* new_poolp )
{
- LLMemType mt(LLMemType::MTYPE_PIPELINE);
+ LLMemType mt(LLMemType::MTYPE_PIPELINE_QUICK_LOOKUP);
assertInitialized();
@@ -4098,18 +4144,21 @@ void LLPipeline::setupHWLights(LLDrawPool* pool)
void LLPipeline::enableLights(U32 mask)
{
assertInitialized();
+
if (mLightingDetail == 0)
{
mask &= 0xf003; // sun and backlight only (and fullbright bit)
}
if (mLightMask != mask)
{
+ stop_glerror();
if (!mLightMask)
{
glEnable(GL_LIGHTING);
}
if (mask)
{
+ stop_glerror();
for (S32 i=0; i<8; i++)
{
if (mask & (1<<i))
@@ -4123,14 +4172,17 @@ void LLPipeline::enableLights(U32 mask)
glLightfv(GL_LIGHT0 + i, GL_DIFFUSE, LLColor4::black.mV);
}
}
+ stop_glerror();
}
else
{
glDisable(GL_LIGHTING);
}
+ stop_glerror();
mLightMask = mask;
LLColor4 ambient = gSky.getTotalAmbientColor();
glLightModelfv(GL_LIGHT_MODEL_AMBIENT,ambient.mV);
+ stop_glerror();
}
}
@@ -4873,6 +4925,7 @@ void LLPipeline::resetVertexBuffers()
void LLPipeline::renderObjects(U32 type, U32 mask, BOOL texture)
{
+ LLMemType mt_ro(LLMemType::MTYPE_PIPELINE_RENDER_OBJECTS);
assertInitialized();
glLoadMatrixd(gGLModelView);
gGLLastMatrix = NULL;
@@ -4959,8 +5012,10 @@ void LLPipeline::bindScreenToTexture()
}
+static LLFastTimer::DeclareTimer FTM_RENDER_BLOOM("Bloom");
void LLPipeline::renderBloom(BOOL for_snapshot, F32 zoom_factor, int subfield)
{
+ LLMemType mt_ru(LLMemType::MTYPE_PIPELINE_RENDER_BLOOM);
if (!(gPipeline.canUseVertexShaders() &&
sRenderGlow))
{
@@ -4981,8 +5036,8 @@ void LLPipeline::renderBloom(BOOL for_snapshot, F32 zoom_factor, int subfield)
U32 res_mod = gSavedSettings.getU32("RenderResolutionDivisor");
LLVector2 tc1(0,0);
- LLVector2 tc2((F32) gViewerWindow->getWindowDisplayWidth()*2,
- (F32) gViewerWindow->getWindowDisplayHeight()*2);
+ LLVector2 tc2((F32) gViewerWindow->getWorldViewWidth()*2,
+ (F32) gViewerWindow->getWorldViewHeight()*2);
if (res_mod > 1)
{
@@ -4991,7 +5046,7 @@ void LLPipeline::renderBloom(BOOL for_snapshot, F32 zoom_factor, int subfield)
gGL.setColorMask(true, true);
- LLFastTimer ftm(LLFastTimer::FTM_RENDER_BLOOM);
+ LLFastTimer ftm(FTM_RENDER_BLOOM);
gGL.color4f(1,1,1,1);
LLGLDepthTest depth(GL_FALSE);
LLGLDisable blend(GL_BLEND);
@@ -5066,7 +5121,7 @@ void LLPipeline::renderBloom(BOOL for_snapshot, F32 zoom_factor, int subfield)
{
{
- LLFastTimer ftm(LLFastTimer::FTM_RENDER_BLOOM_FBO);
+ LLFastTimer ftm(FTM_RENDER_BLOOM_FBO);
mGlow[2].bindTarget();
mGlow[2].clear();
}
@@ -5138,7 +5193,7 @@ void LLPipeline::renderBloom(BOOL for_snapshot, F32 zoom_factor, int subfield)
{
gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
{
- LLFastTimer ftm(LLFastTimer::FTM_RENDER_BLOOM_FBO);
+ LLFastTimer ftm(FTM_RENDER_BLOOM_FBO);
mGlow[i%2].bindTarget();
mGlow[i%2].clear();
}
@@ -5180,11 +5235,15 @@ void LLPipeline::renderBloom(BOOL for_snapshot, F32 zoom_factor, int subfield)
if (LLRenderTarget::sUseFBO)
{
- LLFastTimer ftm(LLFastTimer::FTM_RENDER_BLOOM_FBO);
+ LLFastTimer ftm(FTM_RENDER_BLOOM_FBO);
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
}
- gViewerWindow->setupViewport();
+ gGLViewport[0] = gViewerWindow->getWorldViewRect().mLeft;
+ gGLViewport[1] = gViewerWindow->getWorldViewRect().mBottom;
+ gGLViewport[2] = gViewerWindow->getWorldViewRect().getWidth();
+ gGLViewport[3] = gViewerWindow->getWorldViewRect().getHeight();
+ glViewport(gGLViewport[0], gGLViewport[1], gGLViewport[2], gGLViewport[3]);
gGL.flush();
@@ -5193,8 +5252,8 @@ void LLPipeline::renderBloom(BOOL for_snapshot, F32 zoom_factor, int subfield)
- tc2.setVec((F32) gViewerWindow->getWindowDisplayWidth(),
- (F32) gViewerWindow->getWindowDisplayHeight());
+ tc2.setVec((F32) gViewerWindow->getWorldViewWidth(),
+ (F32) gViewerWindow->getWorldViewHeight());
if (res_mod > 1)
{
@@ -5787,15 +5846,15 @@ void LLPipeline::generateWaterReflection(LLCamera& camera_in)
{
if (LLPipeline::sWaterReflections && assertInitialized() && LLDrawPoolWater::sNeedsReflectionUpdate)
{
- LLVOAvatar* agent = gAgent.getAvatarObject();
+ LLVOAvatarSelf* avatar = gAgent.getAvatarObject();
if (gAgent.getCameraAnimating() || gAgent.getCameraMode() != CAMERA_MODE_MOUSELOOK)
{
- agent = NULL;
+ avatar = NULL;
}
- if (agent)
+ if (avatar)
{
- agent->updateAttachmentVisibility(CAMERA_MODE_THIRD_PERSON);
+ avatar->updateAttachmentVisibility(CAMERA_MODE_THIRD_PERSON);
}
LLVertexBuffer::unbind();
@@ -5985,7 +6044,7 @@ void LLPipeline::generateWaterReflection(LLCamera& camera_in)
}
glClearColor(0.f, 0.f, 0.f, 0.f);
- gViewerWindow->setupViewport();
+ gViewerWindow->setup3DViewport();
mRenderTypeMask = type_mask;
LLDrawPoolWater::sNeedsReflectionUpdate = FALSE;
LLDrawPoolWater::sNeedsDistortionUpdate = FALSE;
@@ -5996,9 +6055,9 @@ void LLPipeline::generateWaterReflection(LLCamera& camera_in)
LLGLState::checkTextureChannels();
LLGLState::checkClientArrays();
- if (agent)
+ if (avatar)
{
- agent->updateAttachmentVisibility(gAgent.getCameraMode());
+ avatar->updateAttachmentVisibility(gAgent.getCameraMode());
}
}
}
@@ -6070,6 +6129,10 @@ glh::matrix4f scale_translate_to_fit(const LLVector3 min, const LLVector3 max)
return ret;
}
+static LLFastTimer::DeclareTimer FTM_SHADOW_RENDER("Render Shadows");
+static LLFastTimer::DeclareTimer FTM_SHADOW_ALPHA("Alpha Shadow");
+static LLFastTimer::DeclareTimer FTM_SHADOW_SIMPLE("Simple Shadow");
+
void LLPipeline::generateSunShadow(LLCamera& camera)
{
@@ -6318,7 +6381,7 @@ void LLPipeline::generateSunShadow(LLCamera& camera)
mShadowCamera[j+4] = shadow_cam;
}
- LLFastTimer t(LLFastTimer::FTM_SHADOW_RENDER);
+ LLFastTimer t(FTM_SHADOW_RENDER);
stop_glerror();
@@ -6356,7 +6419,7 @@ void LLPipeline::generateSunShadow(LLCamera& camera)
gDeferredShadowProgram.bind();
{
- LLFastTimer ftm(LLFastTimer::FTM_SHADOW_SIMPLE);
+ LLFastTimer ftm(FTM_SHADOW_SIMPLE);
LLGLDisable test(GL_ALPHA_TEST);
gGL.getTexUnit(0)->disable();
for (U32 i = 0; i < sizeof(types)/sizeof(U32); ++i)
@@ -6367,7 +6430,7 @@ void LLPipeline::generateSunShadow(LLCamera& camera)
}
{
- LLFastTimer ftm(LLFastTimer::FTM_SHADOW_ALPHA);
+ LLFastTimer ftm(FTM_SHADOW_ALPHA);
LLGLEnable test(GL_ALPHA_TEST);
gGL.setAlphaRejectSettings(LLRender::CF_GREATER, 0.6f);
renderObjects(LLRenderPass::PASS_ALPHA_SHADOW, LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_TEXCOORD0 | LLVertexBuffer::MAP_COLOR, TRUE);
@@ -6430,6 +6493,7 @@ void LLPipeline::renderGroups(LLRenderPass* pass, U32 type, U32 mask, BOOL textu
void LLPipeline::generateImpostor(LLVOAvatar* avatar)
{
+ LLMemType mt_gi(LLMemType::MTYPE_PIPELINE_GENERATE_IMPOSTOR);
LLGLState::checkStates();
LLGLState::checkTextureChannels();
LLGLState::checkClientArrays();
@@ -6670,3 +6734,4 @@ LLCullResult::sg_list_t::iterator LLPipeline::endAlphaGroups()
return sCull->endAlphaGroups();
}
+
diff --git a/indra/newview/pipeline.h b/indra/newview/pipeline.h
index 1a32b30831..8f6867aa01 100644
--- a/indra/newview/pipeline.h
+++ b/indra/newview/pipeline.h
@@ -33,20 +33,20 @@
#ifndef LL_PIPELINE_H
#define LL_PIPELINE_H
+#include "llcamera.h"
#include "llerror.h"
#include "lldarrayptr.h"
#include "lldqueueptr.h"
-#include "llstat.h"
#include "lldrawpool.h"
#include "llspatialpartition.h"
#include "m4math.h"
-#include "llmemory.h"
+#include "llpointer.h"
#include "lldrawpool.h"
#include "llgl.h"
#include "lldrawable.h"
#include "llrendertarget.h"
-class LLViewerImage;
+class LLViewerTexture;
class LLEdge;
class LLFace;
class LLViewerObject;
@@ -78,6 +78,27 @@ glh::matrix4f gl_ortho(GLfloat left, GLfloat right, GLfloat bottom, GLfloat top,
glh::matrix4f gl_perspective(GLfloat fovy, GLfloat aspect, GLfloat zNear, GLfloat zFar);
glh::matrix4f gl_lookat(LLVector3 eye, LLVector3 center, LLVector3 up);
+extern LLFastTimer::DeclareTimer FTM_RENDER_GEOMETRY;
+extern LLFastTimer::DeclareTimer FTM_RENDER_GRASS;
+extern LLFastTimer::DeclareTimer FTM_RENDER_INVISIBLE;
+extern LLFastTimer::DeclareTimer FTM_RENDER_OCCLUSION;
+extern LLFastTimer::DeclareTimer FTM_RENDER_SHINY;
+extern LLFastTimer::DeclareTimer FTM_RENDER_SIMPLE;
+extern LLFastTimer::DeclareTimer FTM_RENDER_TERRAIN;
+extern LLFastTimer::DeclareTimer FTM_RENDER_TREES;
+extern LLFastTimer::DeclareTimer FTM_RENDER_UI;
+extern LLFastTimer::DeclareTimer FTM_RENDER_WATER;
+extern LLFastTimer::DeclareTimer FTM_RENDER_WL_SKY;
+extern LLFastTimer::DeclareTimer FTM_RENDER_ALPHA;
+extern LLFastTimer::DeclareTimer FTM_RENDER_CHARACTERS;
+extern LLFastTimer::DeclareTimer FTM_RENDER_BUMP;
+extern LLFastTimer::DeclareTimer FTM_RENDER_FULLBRIGHT;
+extern LLFastTimer::DeclareTimer FTM_RENDER_GLOW;
+extern LLFastTimer::DeclareTimer FTM_STATESORT;
+extern LLFastTimer::DeclareTimer FTM_PIPELINE;
+extern LLFastTimer::DeclareTimer FTM_CLIENT_COPY;
+
+
class LLPipeline
{
public:
@@ -104,15 +125,15 @@ public:
/// @brief Get a draw pool from pool type (POOL_SIMPLE, POOL_MEDIA) and texture.
/// @return Draw pool, or NULL if not found.
- LLDrawPool *findPool(const U32 pool_type, LLViewerImage *tex0 = NULL);
+ LLDrawPool *findPool(const U32 pool_type, LLViewerTexture *tex0 = NULL);
/// @brief Get a draw pool for faces of the appropriate type and texture. Create if necessary.
/// @return Always returns a draw pool.
- LLDrawPool *getPool(const U32 pool_type, LLViewerImage *tex0 = NULL);
+ LLDrawPool *getPool(const U32 pool_type, LLViewerTexture *tex0 = NULL);
/// @brief Figures out draw pool type from texture entry. Creates pool if necessary.
- static LLDrawPool* getPoolFromTE(const LLTextureEntry* te, LLViewerImage* te_image);
- static U32 getPoolTypeFromTE(const LLTextureEntry* te, LLViewerImage* imagep);
+ static LLDrawPool* getPoolFromTE(const LLTextureEntry* te, LLViewerTexture* te_image);
+ static U32 getPoolTypeFromTE(const LLTextureEntry* te, LLViewerTexture* imagep);
void addPool(LLDrawPool *poolp); // Only to be used by LLDrawPool classes for splitting pools!
void removePool( LLDrawPool* poolp );
@@ -150,7 +171,7 @@ public:
);
// Something about these textures has changed. Dirty them.
- void dirtyPoolObjectTextures(const std::set<LLViewerImage*>& textures);
+ void dirtyPoolObjectTextures(const std::set<LLViewerFetchedTexture*>& textures);
void resetDrawOrders();
@@ -383,7 +404,6 @@ public:
S32 mMeanBatchSize;
S32 mTrianglesDrawn;
S32 mNumVisibleNodes;
- LLStat mTrianglesDrawnStat;
S32 mVerticesRelit;
S32 mLightingChanges;
@@ -562,9 +582,9 @@ public:
protected:
std::vector<LLFace*> mSelectedFaces;
- LLPointer<LLViewerImage> mFaceSelectImagep;
- LLPointer<LLViewerImage> mBloomImagep;
- LLPointer<LLViewerImage> mBloomImage2p;
+ LLPointer<LLViewerFetchedTexture> mFaceSelectImagep;
+ LLPointer<LLViewerTexture> mBloomImagep;
+ LLPointer<LLViewerTexture> mBloomImage2p;
U32 mLightMask;
U32 mLightMovingMask;
diff --git a/indra/newview/res/bitmap2.bmp b/indra/newview/res/bitmap2.bmp
new file mode 100644
index 0000000000..770b07558c
--- /dev/null
+++ b/indra/newview/res/bitmap2.bmp
Binary files differ
diff --git a/indra/newview/res/install_icon.BMP b/indra/newview/res/install_icon.BMP
new file mode 100644
index 0000000000..09df573870
--- /dev/null
+++ b/indra/newview/res/install_icon.BMP
Binary files differ
diff --git a/indra/newview/res/loginbackground.bmp b/indra/newview/res/loginbackground.bmp
new file mode 100644
index 0000000000..288a0b0398
--- /dev/null
+++ b/indra/newview/res/loginbackground.bmp
Binary files differ
diff --git a/indra/newview/res/uninstall_icon.BMP b/indra/newview/res/uninstall_icon.BMP
new file mode 100644
index 0000000000..562b56676a
--- /dev/null
+++ b/indra/newview/res/uninstall_icon.BMP
Binary files differ
diff --git a/indra/newview/res/viewerRes.rc b/indra/newview/res/viewerRes.rc
index 352d5cab55..9a0938b879 100644
--- a/indra/newview/res/viewerRes.rc
+++ b/indra/newview/res/viewerRes.rc
@@ -138,8 +138,8 @@ TOOLMEDIAOPEN CURSOR "toolmediaopen.cur"
//
VS_VERSION_INFO VERSIONINFO
- FILEVERSION 1,24,4,0
- PRODUCTVERSION 1,24,4,0
+ FILEVERSION 2,0,0,0
+ PRODUCTVERSION 2,0,0,0
FILEFLAGSMASK 0x3fL
#ifdef _DEBUG
FILEFLAGS 0x1L
@@ -156,12 +156,12 @@ BEGIN
BEGIN
VALUE "CompanyName", "Linden Lab"
VALUE "FileDescription", "Second Life"
- VALUE "FileVersion", "1.24.4.0"
+ VALUE "FileVersion", "2.0.0.0"
VALUE "InternalName", "Second Life"
- VALUE "LegalCopyright", "Copyright © 2001-2008, Linden Research, Inc."
+ VALUE "LegalCopyright", "Copyright � 2001-2008, Linden Research, Inc."
VALUE "OriginalFilename", "SecondLife.exe"
VALUE "ProductName", "Second Life"
- VALUE "ProductVersion", "1.24.4.0"
+ VALUE "ProductVersion", "2.0.0.0"
END
END
BLOCK "VarFileInfo"
diff --git a/indra/newview/skins/default/colors.xml b/indra/newview/skins/default/colors.xml
index cf9466fad3..c739d4d455 100644
--- a/indra/newview/skins/default/colors.xml
+++ b/indra/newview/skins/default/colors.xml
@@ -1,3 +1,674 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<settings version = "101">
-</settings>
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<colors>
+
+ <!-- Named Colors -->
+
+ <color
+ name="EmphasisColor"
+ value="0.38 0.694 0.573 1" />
+ <color
+ name="EmphasisColor_13"
+ value="0.38 0.694 0.573 0.13" />
+ <color
+ name="EmphasisColor_35"
+ value="0.38 0.694 0.573 0.35" />
+ <color
+ name="White"
+ value="1 1 1 1" />
+ <color
+ name="White_05"
+ value="1 1 1 0.05" />
+ <color
+ name="White_10"
+ value="1 1 1 0.1" />
+ <color
+ name="White_25"
+ value="1 1 1 0.25" />
+ <color
+ name="White_50"
+ value="1 1 1 0.5" />
+ <color
+ name="LtGray"
+ value="0.75 0.75 0.75 1" />
+ <color
+ name="LtGray_50"
+ value="0.75 0.75 0.75 0.50" />
+ <color
+ name="DkGray"
+ value="0.125 0.125 0.125 1" />
+ <color
+ name="DkGray_66"
+ value="0.125 0.125 0.125 .66" />
+ <color
+ name="DkGray2"
+ value="0.169 0.169 0.169 1" />
+ <color
+ name="Black"
+ value="0 0 0 1" />
+ <color
+ name="Black_10"
+ value="0 0 0 0.1" />
+ <color
+ name="Black_25"
+ value="0 0 0 0.25" />
+ <color
+ name="Black_50"
+ value="0 0 0 0.5" />
+ <color
+ name="Red"
+ value="1 0 0 1" />
+ <color
+ name="Green"
+ value="0 1 0 1" />
+ <color
+ name="Blue"
+ value="0 0 1 1" />
+ <color
+ name="Unused?"
+ value="1 0 1 1" />
+ <color
+ name="Transparent"
+ value="0 0 0 0" />
+
+
+
+ <!-- UI Definitions -->
+
+ <color
+ name="AgentChatColor"
+ reference="LtGray" />
+ <color
+ name="AlertBoxColor"
+ value="0.24 0.24 0.24 1" />
+ <color
+ name="AlertCautionBoxColor"
+ value="1 0.82 0.46 1" />
+ <color
+ name="AlertCautionTextColor"
+ reference="Black" />
+ <color
+ name="AlertTextColor"
+ value="0.58 0.66 0.84 1" />
+ <color
+ name="AvatarNameColor"
+ value="0.98 0.69 0.36 1" />
+ <color
+ name="BackgroundChatColor"
+ reference="DkGray_66" />
+ <color
+ name="ButtonBorderColor"
+ reference="Unused?" />
+ <color
+ name="ButtonCautionImageColor"
+ reference="Unused?" />
+ <color
+ name="ButtonColor"
+ reference="Unused?" />
+ <color
+ name="ButtonFlashBgColor"
+ reference="Unused?" />
+ <color
+ name="ButtonImageColor"
+ reference="White" />
+ <color
+ name="ButtonLabelColor"
+ reference="LtGray" />
+ <color
+ name="ButtonLabelDisabledColor"
+ reference="LtGray_50" />
+ <color
+ name="ButtonLabelSelectedColor"
+ reference="White" />
+ <color
+ name="ButtonLabelSelectedDisabledColor"
+ reference="White_50" />
+ <color
+ name="ButtonSelectedBgColor"
+ reference="Unused?" />
+ <color
+ name="ButtonSelectedColor"
+ reference="Unused?" />
+ <color
+ name="ButtonUnselectedBgColor"
+ reference="Unused?" />
+ <color
+ name="ButtonUnselectedFgColor"
+ reference="Unused?" />
+ <color
+ name="ChatHistoryBgColor"
+ reference="Transparent" />
+ <color
+ name="ChatHistoryTextColor"
+ reference="LtGray" />
+ <color
+ name="ColorDropShadow"
+ reference="Black_50" />
+ <color
+ name="ColorPaletteEntry01"
+ value="0 0 0 1" />
+ <color
+ name="ColorPaletteEntry02"
+ value="0.5 0.5 0.5 1" />
+ <color
+ name="ColorPaletteEntry03"
+ value="0.3344 0.5456 0.5159 1" />
+ <color
+ name="ColorPaletteEntry04"
+ value="0.5 0.5 0 1" />
+ <color
+ name="ColorPaletteEntry05"
+ value="0 0.5 0 1" />
+ <color
+ name="ColorPaletteEntry06"
+ value="0 0.5 0.5 1" />
+ <color
+ name="ColorPaletteEntry07"
+ value="0 0 0.5 1" />
+ <color
+ name="ColorPaletteEntry08"
+ value="0.5 0 0.5 1" />
+ <color
+ name="ColorPaletteEntry09"
+ value="0.5 0.5 0 1" />
+ <color
+ name="ColorPaletteEntry10"
+ value="0 0.25 0.25 1" />
+ <color
+ name="ColorPaletteEntry11"
+ value="0 0.5 1 1" />
+ <color
+ name="ColorPaletteEntry12"
+ value="0 0.25 0.5 1" />
+ <color
+ name="ColorPaletteEntry13"
+ value="0.5 0 1 1" />
+ <color
+ name="ColorPaletteEntry14"
+ value="0.5 0.25 0 1" />
+ <color
+ name="ColorPaletteEntry15"
+ value="1 1 1 1" />
+ <color
+ name="ColorPaletteEntry16"
+ value="1 1 1 1" />
+ <color
+ name="ColorPaletteEntry17"
+ value="1 1 1 1" />
+ <color
+ name="ColorPaletteEntry18"
+ value="0.75 0.75 0.75 1" />
+ <color
+ name="ColorPaletteEntry19"
+ value="1 0 0 1" />
+ <color
+ name="ColorPaletteEntry20"
+ reference="Unused?" />
+ <color
+ name="ColorPaletteEntry21"
+ value="0 1 0 1" />
+ <color
+ name="ColorPaletteEntry22"
+ value="0 1 1 1" />
+ <color
+ name="ColorPaletteEntry23"
+ value="0 0 1 1" />
+ <color
+ name="ColorPaletteEntry24"
+ value="1 0 1 1" />
+ <color
+ name="ColorPaletteEntry25"
+ value="1 1 0.5 1" />
+ <color
+ name="ColorPaletteEntry26"
+ value="0 1 0.5 1" />
+ <color
+ name="ColorPaletteEntry27"
+ value="0.5 1 1 1" />
+ <color
+ name="ColorPaletteEntry28"
+ value="0.5 0.5 1 1" />
+ <color
+ name="ColorPaletteEntry29"
+ value="1 0 0.5 1" />
+ <color
+ name="ColorPaletteEntry30"
+ value="1 0.5 0 1" />
+ <color
+ name="ColorPaletteEntry31"
+ value="1 1 1 1" />
+ <color
+ name="ColorPaletteEntry32"
+ value="1 1 1 1" />
+ <color
+ name="ConsoleBackground"
+ reference="Black" />
+ <color
+ name="ContextSilhouetteColor"
+ value="0.94 0.61 0 1" />
+ <color
+ name="DefaultHighlightDark"
+ reference="White_10" />
+ <color
+ name="DefaultHighlightLight"
+ reference="White_25" />
+ <color
+ name="DefaultShadowDark"
+ reference="Black_50" />
+ <color
+ name="DefaultShadowLight"
+ reference="Black_50" />
+ <color
+ name="EffectColor"
+ reference="White" />
+ <color
+ name="FilterBackgroundColor"
+ reference="DkGray" />
+ <color
+ name="FilterTextColor"
+ value="1 0.78 0.27 1" />
+ <color
+ name="FloaterButtonImageColor"
+ reference="LtGray" />
+ <color
+ name="FloaterDefaultBackgroundColor"
+ reference="DkGray_66" />
+ <color
+ name="FloaterFocusBackgroundColor"
+ reference="DkGray2" />
+ <color
+ name="FloaterFocusBorderColor"
+ reference="Black_50" />
+ <color
+ name="FloaterUnfocusBorderColor"
+ reference="Black_50" />
+ <color
+ name="FocusColor"
+ reference="EmphasisColor" />
+ <color
+ name="FolderViewLoadingMessageTextColor"
+ value="0.3344 0.5456 0.5159 1" />
+ <color
+ name="GridFocusPointColor"
+ reference="White_50" />
+ <color
+ name="GridlineBGColor"
+ value="0.92 0.92 1 0.78" />
+ <color
+ name="GridlineColor"
+ value="1 0 0 1" />
+ <color
+ name="GridlineShadowColor"
+ value="0 0 0 0.31" />
+ <color
+ name="GroupNotifyBoxColor"
+ value="0.3344 0.5456 0.5159 1" />
+ <color
+ name="GroupNotifyTextColor"
+ reference="White"/>
+ <color
+ name="GroupNotifyDimmedTextColor"
+ reference="DkGray"/>
+ <color
+ name="GroupOverTierColor"
+ value="0.43 0.06 0.06 1" />
+ <color
+ name="HTMLLinkColor"
+ reference="EmphasisColor" />
+ <color
+ name="HealthTextColor"
+ reference="White" />
+ <color
+ name="HelpBgColor"
+ reference="Unused?" />
+ <color
+ name="HelpFgColor"
+ reference="Unused?" />
+ <color
+ name="HelpScrollHighlightColor"
+ reference="Unused?" />
+ <color
+ name="HelpScrollShadowColor"
+ reference="Unused?" />
+ <color
+ name="HelpScrollThumbColor"
+ reference="Unused?" />
+ <color
+ name="HelpScrollTrackColor"
+ reference="Unused?" />
+ <color
+ name="HighlightChildColor"
+ reference="Unused?" />
+ <color
+ name="HighlightInspectColor"
+ value="1 0.5 0 1" />
+ <color
+ name="HighlightParentColor"
+ value="0.67 0.83 0.96 1" />
+ <color
+ name="IMChatColor"
+ reference="LtGray" />
+ <color
+ name="IMHistoryBgColor"
+ reference="Unused?" />
+ <color
+ name="IMHistoryTextColor"
+ reference="Unused?" />
+ <color
+ name="IconDisabledColor"
+ reference="White_50" />
+ <color
+ name="IconEnabledColor"
+ reference="White" />
+ <color
+ name="InventoryBackgroundColor"
+ reference="Unused?" />
+ <color
+ name="InventoryItemSuffixColor"
+ reference="White_25" />
+ <color
+ name="InventorySearchStatusColor"
+ reference="Black" />
+ <color
+ name="LabelDisabledColor"
+ reference="White_50" />
+ <color
+ name="LabelSelectedColor"
+ reference="White" />
+ <color
+ name="LabelSelectedDisabledColor"
+ reference="White_50" />
+ <color
+ name="LabelTextColor"
+ reference="LtGray" />
+ <color
+ name="LoginProgressBarBgColor"
+ reference="Unused?" />
+ <color
+ name="LoginProgressBarFgColor"
+ reference="Unused?" />
+ <color
+ name="LoginProgressBoxBorderColor"
+ value="0 0.12 0.24 0" />
+ <color
+ name="LoginProgressBoxCenterColor"
+ value="0 0 0 0.78" />
+ <color
+ name="LoginProgressBoxShadowColor"
+ value="0 0 0 0.78" />
+ <color
+ name="LoginProgressBoxTextColor"
+ reference="White" />
+ <color
+ name="MapAvatarColor"
+ reference="White" />
+ <color
+ name="MapAvatarFriendColor"
+ reference="Unused?" />
+ <color
+ name="MapAvatarSelfColor"
+ value="0.53125 0 0.498047 1" />
+ <color
+ name="MapFrustumColor"
+ reference="White_10" />
+ <color
+ name="MapFrustumRotatingColor"
+ value="1 1 1 0.2" />
+ <color
+ name="MapTrackColor"
+ reference="Red" />
+ <color
+ name="MapTrackDisabledColor"
+ value="0.5 0 0 1" />
+ <color
+ name="MenuBarBgColor"
+ reference="DkGray" />
+ <color
+ name="MenuBarGodBgColor"
+ reference="DkGray2" />
+ <color
+ name="MenuDefaultBgColor"
+ reference="DkGray2" />
+ <color
+ name="MenuItemDisabledColor"
+ reference="LtGray_50" />
+ <color
+ name="MenuItemEnabledColor"
+ reference="LtGray" />
+ <color
+ name="MenuItemHighlightBgColor"
+ reference="EmphasisColor_35" />
+ <color
+ name="MenuItemHighlightFgColor"
+ reference="White" />
+ <color
+ name="MenuNonProductionBgColor"
+ reference="Black" />
+ <color
+ name="MenuNonProductionGodBgColor"
+ value="0 0.5 0 1" />
+ <color
+ name="MenuPopupBgColor"
+ reference="DkGray_66" />
+ <color
+ name="MultiSliderDisabledThumbColor"
+ reference="Unused?" />
+ <color
+ name="MultiSliderThumbCenterColor"
+ reference="Unused?" />
+ <color
+ name="MultiSliderThumbCenterSelectedColor"
+ reference="Unused?" />
+ <color
+ name="MultiSliderThumbOutlineColor"
+ reference="Unused?" />
+ <color
+ name="MultiSliderTrackColor"
+ reference="Unused?" />
+ <color
+ name="MultiSliderTriangleColor"
+ reference="Unused?" />
+ <color
+ name="NetMapBackgroundColor"
+ value="0 0 0 0.3" />
+ <color
+ name="NetMapGroupOwnAboveWater"
+ value="1 0 1 1" />
+ <color
+ name="NetMapGroupOwnBelowWater"
+ value="0.78 0 0.78 1" />
+ <color
+ name="NetMapOtherOwnAboveWater"
+ value="0.24 0.24 0.24 1" />
+ <color
+ name="NetMapOtherOwnBelowWater"
+ value="0.12 0.12 0.12 1" />
+ <color
+ name="NetMapYouOwnAboveWater"
+ value="0 1 1 1" />
+ <color
+ name="NetMapYouOwnBelowWater"
+ value="0 0.78 0.78 1" />
+ <color
+ name="NotifyBoxColor"
+ value="0.27 0.67 1 1" />
+ <color
+ name="NotifyCautionBoxColor"
+ value="1 0.82 0.46 1" />
+ <color
+ name="NotifyCautionWarnColor"
+ reference="White" />
+ <color
+ name="NotifyTextColor"
+ reference="White" />
+ <color
+ name="ObjectChatColor"
+ reference="LtGray" />
+ <color
+ name="OverdrivenColor"
+ value="1 0 0 1" />
+ <color
+ name="PanelDefaultBackgroundColor"
+ reference="DkGray" />
+ <color
+ name="PanelDefaultHighlightLight"
+ reference="White_50" />
+ <color
+ name="PanelFocusBackgroundColor"
+ reference="DkGray2" />
+ <color
+ name="ParcelHoverColor"
+ reference="White" />
+ <color
+ name="PieMenuBgColor"
+ value="0.24 0.24 0.24 0.59" />
+ <color
+ name="PieMenuLineColor"
+ value="0 0 0 0.5" />
+ <color
+ name="PieMenuSelectedColor"
+ value="0.72 0.72 0.74 0.3" />
+ <color
+ name="PropertyColorAuction"
+ value="0.5 0 1 0.4" />
+ <color
+ name="PropertyColorAvail"
+ reference="Transparent" />
+ <color
+ name="PropertyColorForSale"
+ value="1 0.5 0 0.4" />
+ <color
+ name="PropertyColorGroup"
+ value="0 0.72 0.72 0.4" />
+ <color
+ name="PropertyColorOther"
+ value="1 0 0 0.4" />
+ <color
+ name="PropertyColorSelf"
+ value="0 1 0 0.4" />
+ <color
+ name="ScriptBgReadOnlyColor"
+ value="0.39 0.39 0.39 1" />
+ <color
+ name="ScriptErrorColor"
+ value="0.82 0.27 0.27 1" />
+ <color
+ name="ScrollBGStripeColor"
+ reference="Transparent" />
+ <color
+ name="ScrollBgReadOnlyColor"
+ reference="Transparent" />
+ <color
+ name="ScrollBgWriteableColor"
+ reference="White_05" />
+ <color
+ name="ScrollDisabledColor"
+ reference="Unused?" />
+ <color
+ name="ScrollHighlightedColor"
+ reference="Unused?" />
+ <color
+ name="ScrollHoveredColor"
+ reference="EmphasisColor_13" />
+ <color
+ name="ScrollSelectedBGColor"
+ reference="EmphasisColor_35" />
+ <color
+ name="ScrollSelectedFGColor"
+ reference="White" />
+ <color
+ name="ScrollUnselectedColor"
+ reference="LtGray" />
+ <color
+ name="ScrollbarThumbColor"
+ reference="White" />
+ <color
+ name="ScrollbarTrackColor"
+ reference="Black" />
+ <color
+ name="SilhouetteChildColor"
+ value="0.13 0.42 0.77 1" />
+ <color
+ name="SilhouetteParentColor"
+ reference="Unused?" />
+ <color
+ name="SliderDisabledThumbColor"
+ reference="White_50" />
+ <color
+ name="SliderThumbCenterColor"
+ reference="White" />
+ <color
+ name="SliderThumbOutlineColor"
+ reference="White" />
+ <color
+ name="SliderTrackColor"
+ reference="Unused?" />
+ <color
+ name="SpeakingColor"
+ value="0 1 0 1" />
+ <color
+ name="SystemChatColor"
+ reference="White" />
+ <color
+ name="TextBgFocusColor"
+ reference="White" />
+ <color
+ name="TextBgReadOnlyColor"
+ reference="White_05" />
+ <color
+ name="TextBgWriteableColor"
+ reference="LtGray" />
+ <color
+ name="TextCursorColor"
+ reference="Black" />
+ <color
+ name="TextDefaultColor"
+ value="0 0 0 .33" />
+ <color
+ name="TextEmbeddedItemColor"
+ value="0 0 0.5 1" />
+ <color
+ name="TextEmbeddedItemReadOnlyColor"
+ reference="Unused?" />
+ <color
+ name="TextFgColor"
+ value="0.102 0.102 0.102 1" />
+ <color
+ name="TextFgReadOnlyColor"
+ reference="LtGray" />
+ <color
+ name="TextFgTentativeColor"
+ value="0 0 0 .33" />
+ <color
+ name="TimeTextColor"
+ reference="LtGray" />
+ <color
+ name="TitleBarFocusColor"
+ reference="White_10" />
+ <color
+ name="ToolTipBgColor"
+ value="0 0 0 .75" />
+ <color
+ name="ToolTipBorderColor"
+ value="0 0 0 .75" />
+ <color
+ name="ToolTipTextColor"
+ reference="LtGray" />
+ <color
+ name="UserChatColor"
+ reference="LtGray" />
+ <color
+ name="llOwnerSayChatColor"
+ reference="LtGray" />
+
+ <!-- New Colors -->
+ <color
+ name="OutputMonitorMutedColor"
+ reference="DkGray2" />
+ <color
+ name="SysWellItemUnselected"
+ value="0 0 0 0" />
+ <color
+ name="SysWellItemSelected"
+ value="0.3 0.3 0.3 1.0" />
+
+</colors>
diff --git a/indra/newview/skins/default/textures/bottomtray/DownArrow.png b/indra/newview/skins/default/textures/bottomtray/DownArrow.png
new file mode 100644
index 0000000000..82f58b22b9
--- /dev/null
+++ b/indra/newview/skins/default/textures/bottomtray/DownArrow.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/bottomtray/Unread_IM.png b/indra/newview/skins/default/textures/bottomtray/Unread_IM.png
new file mode 100644
index 0000000000..a355917fca
--- /dev/null
+++ b/indra/newview/skins/default/textures/bottomtray/Unread_IM.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/bottomtray/VoicePTT_Lvl1.png b/indra/newview/skins/default/textures/bottomtray/VoicePTT_Lvl1.png
new file mode 100644
index 0000000000..cd18ae310d
--- /dev/null
+++ b/indra/newview/skins/default/textures/bottomtray/VoicePTT_Lvl1.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/bottomtray/VoicePTT_Lvl2.png b/indra/newview/skins/default/textures/bottomtray/VoicePTT_Lvl2.png
new file mode 100644
index 0000000000..b0ed6ee8eb
--- /dev/null
+++ b/indra/newview/skins/default/textures/bottomtray/VoicePTT_Lvl2.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/bottomtray/VoicePTT_Lvl3.png b/indra/newview/skins/default/textures/bottomtray/VoicePTT_Lvl3.png
new file mode 100644
index 0000000000..14ec77b99a
--- /dev/null
+++ b/indra/newview/skins/default/textures/bottomtray/VoicePTT_Lvl3.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/bottomtray/VoicePTT_Off.png b/indra/newview/skins/default/textures/bottomtray/VoicePTT_Off.png
new file mode 100644
index 0000000000..48be51e9af
--- /dev/null
+++ b/indra/newview/skins/default/textures/bottomtray/VoicePTT_Off.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/bottomtray/VoicePTT_On.png b/indra/newview/skins/default/textures/bottomtray/VoicePTT_On.png
new file mode 100644
index 0000000000..be4881b64c
--- /dev/null
+++ b/indra/newview/skins/default/textures/bottomtray/VoicePTT_On.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/containers/Accordion_ArrowClosed_Off.png b/indra/newview/skins/default/textures/containers/Accordion_ArrowClosed_Off.png
new file mode 100644
index 0000000000..19c842b816
--- /dev/null
+++ b/indra/newview/skins/default/textures/containers/Accordion_ArrowClosed_Off.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/containers/Accordion_ArrowClosed_Over.png b/indra/newview/skins/default/textures/containers/Accordion_ArrowClosed_Over.png
new file mode 100644
index 0000000000..e47f913db1
--- /dev/null
+++ b/indra/newview/skins/default/textures/containers/Accordion_ArrowClosed_Over.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/containers/Accordion_ArrowClosed_Press.png b/indra/newview/skins/default/textures/containers/Accordion_ArrowClosed_Press.png
new file mode 100644
index 0000000000..b9879dcc8a
--- /dev/null
+++ b/indra/newview/skins/default/textures/containers/Accordion_ArrowClosed_Press.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/containers/Accordion_ArrowOpened_Off.png b/indra/newview/skins/default/textures/containers/Accordion_ArrowOpened_Off.png
new file mode 100644
index 0000000000..d506cda5c9
--- /dev/null
+++ b/indra/newview/skins/default/textures/containers/Accordion_ArrowOpened_Off.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/containers/Accordion_ArrowOpened_Over.png b/indra/newview/skins/default/textures/containers/Accordion_ArrowOpened_Over.png
new file mode 100644
index 0000000000..e2c67de9c0
--- /dev/null
+++ b/indra/newview/skins/default/textures/containers/Accordion_ArrowOpened_Over.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/containers/Accordion_ArrowOpened_Press.png b/indra/newview/skins/default/textures/containers/Accordion_ArrowOpened_Press.png
new file mode 100644
index 0000000000..08f7493a02
--- /dev/null
+++ b/indra/newview/skins/default/textures/containers/Accordion_ArrowOpened_Press.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/containers/Accordion_Off.png b/indra/newview/skins/default/textures/containers/Accordion_Off.png
new file mode 100644
index 0000000000..414f4509c6
--- /dev/null
+++ b/indra/newview/skins/default/textures/containers/Accordion_Off.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/containers/Accordion_Over.png b/indra/newview/skins/default/textures/containers/Accordion_Over.png
new file mode 100644
index 0000000000..5416d73310
--- /dev/null
+++ b/indra/newview/skins/default/textures/containers/Accordion_Over.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/containers/Accordion_Press.png b/indra/newview/skins/default/textures/containers/Accordion_Press.png
new file mode 100644
index 0000000000..1578e0dfc5
--- /dev/null
+++ b/indra/newview/skins/default/textures/containers/Accordion_Press.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/containers/Container.png b/indra/newview/skins/default/textures/containers/Container.png
new file mode 100644
index 0000000000..511eb94386
--- /dev/null
+++ b/indra/newview/skins/default/textures/containers/Container.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/containers/TabTop_Left_Off.png b/indra/newview/skins/default/textures/containers/TabTop_Left_Off.png
new file mode 100644
index 0000000000..1951413f8d
--- /dev/null
+++ b/indra/newview/skins/default/textures/containers/TabTop_Left_Off.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/containers/TabTop_Left_Over.png b/indra/newview/skins/default/textures/containers/TabTop_Left_Over.png
new file mode 100644
index 0000000000..295cd89a57
--- /dev/null
+++ b/indra/newview/skins/default/textures/containers/TabTop_Left_Over.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/containers/TabTop_Left_Selected.png b/indra/newview/skins/default/textures/containers/TabTop_Left_Selected.png
new file mode 100644
index 0000000000..8364716e02
--- /dev/null
+++ b/indra/newview/skins/default/textures/containers/TabTop_Left_Selected.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/containers/TabTop_Middle_Off.png b/indra/newview/skins/default/textures/containers/TabTop_Middle_Off.png
new file mode 100644
index 0000000000..21f1c2d8a8
--- /dev/null
+++ b/indra/newview/skins/default/textures/containers/TabTop_Middle_Off.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/containers/TabTop_Middle_Over.png b/indra/newview/skins/default/textures/containers/TabTop_Middle_Over.png
new file mode 100644
index 0000000000..0758cbcf0d
--- /dev/null
+++ b/indra/newview/skins/default/textures/containers/TabTop_Middle_Over.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/containers/TabTop_Middle_Selected.png b/indra/newview/skins/default/textures/containers/TabTop_Middle_Selected.png
new file mode 100644
index 0000000000..3946917c7c
--- /dev/null
+++ b/indra/newview/skins/default/textures/containers/TabTop_Middle_Selected.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/containers/TabTop_Right_Off.png b/indra/newview/skins/default/textures/containers/TabTop_Right_Off.png
new file mode 100644
index 0000000000..eeef28e5a5
--- /dev/null
+++ b/indra/newview/skins/default/textures/containers/TabTop_Right_Off.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/containers/TabTop_Right_Over.png b/indra/newview/skins/default/textures/containers/TabTop_Right_Over.png
new file mode 100644
index 0000000000..c2cbc2b1e5
--- /dev/null
+++ b/indra/newview/skins/default/textures/containers/TabTop_Right_Over.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/containers/TabTop_Right_Selected.png b/indra/newview/skins/default/textures/containers/TabTop_Right_Selected.png
new file mode 100644
index 0000000000..b0f1f16398
--- /dev/null
+++ b/indra/newview/skins/default/textures/containers/TabTop_Right_Selected.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/containers/Toolbar_Left_Off.png b/indra/newview/skins/default/textures/containers/Toolbar_Left_Off.png
new file mode 100644
index 0000000000..41b5d24d87
--- /dev/null
+++ b/indra/newview/skins/default/textures/containers/Toolbar_Left_Off.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/containers/Toolbar_Left_Over.png b/indra/newview/skins/default/textures/containers/Toolbar_Left_Over.png
new file mode 100644
index 0000000000..083acc0156
--- /dev/null
+++ b/indra/newview/skins/default/textures/containers/Toolbar_Left_Over.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/containers/Toolbar_Left_Selected.png b/indra/newview/skins/default/textures/containers/Toolbar_Left_Selected.png
new file mode 100644
index 0000000000..ee4649a8f9
--- /dev/null
+++ b/indra/newview/skins/default/textures/containers/Toolbar_Left_Selected.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/containers/Toolbar_Middle_Off.png b/indra/newview/skins/default/textures/containers/Toolbar_Middle_Off.png
new file mode 100644
index 0000000000..55c02160e3
--- /dev/null
+++ b/indra/newview/skins/default/textures/containers/Toolbar_Middle_Off.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/containers/Toolbar_Middle_Over.png b/indra/newview/skins/default/textures/containers/Toolbar_Middle_Over.png
new file mode 100644
index 0000000000..2f6ea90196
--- /dev/null
+++ b/indra/newview/skins/default/textures/containers/Toolbar_Middle_Over.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/containers/Toolbar_Middle_Selected.png b/indra/newview/skins/default/textures/containers/Toolbar_Middle_Selected.png
new file mode 100644
index 0000000000..642113b135
--- /dev/null
+++ b/indra/newview/skins/default/textures/containers/Toolbar_Middle_Selected.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/containers/Toolbar_Right_Off.png b/indra/newview/skins/default/textures/containers/Toolbar_Right_Off.png
new file mode 100644
index 0000000000..01fd765c3d
--- /dev/null
+++ b/indra/newview/skins/default/textures/containers/Toolbar_Right_Off.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/containers/Toolbar_Right_Over.png b/indra/newview/skins/default/textures/containers/Toolbar_Right_Over.png
new file mode 100644
index 0000000000..74e00635f1
--- /dev/null
+++ b/indra/newview/skins/default/textures/containers/Toolbar_Right_Over.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/containers/Toolbar_Right_Selected.png b/indra/newview/skins/default/textures/containers/Toolbar_Right_Selected.png
new file mode 100644
index 0000000000..8a0d98a780
--- /dev/null
+++ b/indra/newview/skins/default/textures/containers/Toolbar_Right_Selected.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/icons/AddItem_Off.png b/indra/newview/skins/default/textures/icons/AddItem_Off.png
new file mode 100644
index 0000000000..52d4f9bc80
--- /dev/null
+++ b/indra/newview/skins/default/textures/icons/AddItem_Off.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/icons/AddItem_Over.png b/indra/newview/skins/default/textures/icons/AddItem_Over.png
new file mode 100644
index 0000000000..cad6e8d52f
--- /dev/null
+++ b/indra/newview/skins/default/textures/icons/AddItem_Over.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/icons/AddItem_Press.png b/indra/newview/skins/default/textures/icons/AddItem_Press.png
new file mode 100644
index 0000000000..acc898e5f4
--- /dev/null
+++ b/indra/newview/skins/default/textures/icons/AddItem_Press.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/icons/BackArrow_Off.png b/indra/newview/skins/default/textures/icons/BackArrow_Off.png
new file mode 100644
index 0000000000..ff32192856
--- /dev/null
+++ b/indra/newview/skins/default/textures/icons/BackArrow_Off.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/icons/BackArrow_Over.png b/indra/newview/skins/default/textures/icons/BackArrow_Over.png
new file mode 100644
index 0000000000..b36e03a8cf
--- /dev/null
+++ b/indra/newview/skins/default/textures/icons/BackArrow_Over.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/icons/ForwardArrow_Off.png b/indra/newview/skins/default/textures/icons/ForwardArrow_Off.png
new file mode 100644
index 0000000000..e9b72b0401
--- /dev/null
+++ b/indra/newview/skins/default/textures/icons/ForwardArrow_Off.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/icons/ForwardArrow_Press.png b/indra/newview/skins/default/textures/icons/ForwardArrow_Press.png
new file mode 100644
index 0000000000..c7b2c769ae
--- /dev/null
+++ b/indra/newview/skins/default/textures/icons/ForwardArrow_Press.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/icons/Info.png b/indra/newview/skins/default/textures/icons/Info.png
new file mode 100644
index 0000000000..e52560281b
--- /dev/null
+++ b/indra/newview/skins/default/textures/icons/Info.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/icons/OptionsMenu_Off.png b/indra/newview/skins/default/textures/icons/OptionsMenu_Off.png
new file mode 100644
index 0000000000..25b055bfc0
--- /dev/null
+++ b/indra/newview/skins/default/textures/icons/OptionsMenu_Off.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/icons/OptionsMenu_Over.png b/indra/newview/skins/default/textures/icons/OptionsMenu_Over.png
new file mode 100644
index 0000000000..fcabd4c6d3
--- /dev/null
+++ b/indra/newview/skins/default/textures/icons/OptionsMenu_Over.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/icons/OptionsMenu_Press.png b/indra/newview/skins/default/textures/icons/OptionsMenu_Press.png
new file mode 100644
index 0000000000..6e91dd7159
--- /dev/null
+++ b/indra/newview/skins/default/textures/icons/OptionsMenu_Press.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/icons/TrashItem_Off.png b/indra/newview/skins/default/textures/icons/TrashItem_Off.png
new file mode 100644
index 0000000000..bb64920ec4
--- /dev/null
+++ b/indra/newview/skins/default/textures/icons/TrashItem_Off.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/icons/TrashItem_Over.png b/indra/newview/skins/default/textures/icons/TrashItem_Over.png
new file mode 100644
index 0000000000..1a0eea6c67
--- /dev/null
+++ b/indra/newview/skins/default/textures/icons/TrashItem_Over.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/icons/TrashItem_Press.png b/indra/newview/skins/default/textures/icons/TrashItem_Press.png
new file mode 100644
index 0000000000..c62f833d86
--- /dev/null
+++ b/indra/newview/skins/default/textures/icons/TrashItem_Press.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/icons/VoicePTT_Lvl1.png b/indra/newview/skins/default/textures/icons/VoicePTT_Lvl1.png
new file mode 100644
index 0000000000..cd18ae310d
--- /dev/null
+++ b/indra/newview/skins/default/textures/icons/VoicePTT_Lvl1.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/icons/VoicePTT_Lvl2.png b/indra/newview/skins/default/textures/icons/VoicePTT_Lvl2.png
new file mode 100644
index 0000000000..b0ed6ee8eb
--- /dev/null
+++ b/indra/newview/skins/default/textures/icons/VoicePTT_Lvl2.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/icons/VoicePTT_Lvl3.png b/indra/newview/skins/default/textures/icons/VoicePTT_Lvl3.png
new file mode 100644
index 0000000000..14ec77b99a
--- /dev/null
+++ b/indra/newview/skins/default/textures/icons/VoicePTT_Lvl3.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/icons/VoicePTT_Off.png b/indra/newview/skins/default/textures/icons/VoicePTT_Off.png
new file mode 100644
index 0000000000..48be51e9af
--- /dev/null
+++ b/indra/newview/skins/default/textures/icons/VoicePTT_Off.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/icons/VoicePTT_On.png b/indra/newview/skins/default/textures/icons/VoicePTT_On.png
new file mode 100644
index 0000000000..be4881b64c
--- /dev/null
+++ b/indra/newview/skins/default/textures/icons/VoicePTT_On.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/image_edit_icon.tga b/indra/newview/skins/default/textures/image_edit_icon.tga
new file mode 100644
index 0000000000..8666f0bbe6
--- /dev/null
+++ b/indra/newview/skins/default/textures/image_edit_icon.tga
Binary files differ
diff --git a/indra/newview/skins/default/textures/jump_left_in.tga b/indra/newview/skins/default/textures/jump_left_in.tga
new file mode 100644
index 0000000000..e0656c901d
--- /dev/null
+++ b/indra/newview/skins/default/textures/jump_left_in.tga
Binary files differ
diff --git a/indra/newview/skins/default/textures/jump_left_out.tga b/indra/newview/skins/default/textures/jump_left_out.tga
new file mode 100644
index 0000000000..fb6dac0c3d
--- /dev/null
+++ b/indra/newview/skins/default/textures/jump_left_out.tga
Binary files differ
diff --git a/indra/newview/skins/default/textures/jump_right_in.tga b/indra/newview/skins/default/textures/jump_right_in.tga
new file mode 100644
index 0000000000..010c748c2a
--- /dev/null
+++ b/indra/newview/skins/default/textures/jump_right_in.tga
Binary files differ
diff --git a/indra/newview/skins/default/textures/jump_right_out.tga b/indra/newview/skins/default/textures/jump_right_out.tga
new file mode 100644
index 0000000000..33355262d4
--- /dev/null
+++ b/indra/newview/skins/default/textures/jump_right_out.tga
Binary files differ
diff --git a/indra/newview/skins/default/textures/menu_separator.png b/indra/newview/skins/default/textures/menu_separator.png
new file mode 100644
index 0000000000..89dcdcdff5
--- /dev/null
+++ b/indra/newview/skins/default/textures/menu_separator.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/navbar/Arrow_Left_Off.png b/indra/newview/skins/default/textures/navbar/Arrow_Left_Off.png
new file mode 100644
index 0000000000..19569501fe
--- /dev/null
+++ b/indra/newview/skins/default/textures/navbar/Arrow_Left_Off.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/navbar/Arrow_Left_Over.png b/indra/newview/skins/default/textures/navbar/Arrow_Left_Over.png
new file mode 100644
index 0000000000..a91b74819f
--- /dev/null
+++ b/indra/newview/skins/default/textures/navbar/Arrow_Left_Over.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/navbar/Arrow_Right_Off.png b/indra/newview/skins/default/textures/navbar/Arrow_Right_Off.png
new file mode 100644
index 0000000000..3648c42656
--- /dev/null
+++ b/indra/newview/skins/default/textures/navbar/Arrow_Right_Off.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/navbar/Arrow_Right_Over.png b/indra/newview/skins/default/textures/navbar/Arrow_Right_Over.png
new file mode 100644
index 0000000000..a2caf227a7
--- /dev/null
+++ b/indra/newview/skins/default/textures/navbar/Arrow_Right_Over.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/navbar/Favorite_Star_Active.png b/indra/newview/skins/default/textures/navbar/Favorite_Star_Active.png
new file mode 100644
index 0000000000..e27dbe2cad
--- /dev/null
+++ b/indra/newview/skins/default/textures/navbar/Favorite_Star_Active.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/navbar/Favorite_Star_Off.png b/indra/newview/skins/default/textures/navbar/Favorite_Star_Off.png
new file mode 100644
index 0000000000..82d044d817
--- /dev/null
+++ b/indra/newview/skins/default/textures/navbar/Favorite_Star_Off.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/navbar/Favorite_Star_Over.png b/indra/newview/skins/default/textures/navbar/Favorite_Star_Over.png
new file mode 100644
index 0000000000..7909d54f2b
--- /dev/null
+++ b/indra/newview/skins/default/textures/navbar/Favorite_Star_Over.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/navbar/Favorite_Star_Press.png b/indra/newview/skins/default/textures/navbar/Favorite_Star_Press.png
new file mode 100644
index 0000000000..6670667022
--- /dev/null
+++ b/indra/newview/skins/default/textures/navbar/Favorite_Star_Press.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/navbar/FileMenu_Divider.png b/indra/newview/skins/default/textures/navbar/FileMenu_Divider.png
new file mode 100644
index 0000000000..5ab4abc5b8
--- /dev/null
+++ b/indra/newview/skins/default/textures/navbar/FileMenu_Divider.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/navbar/Help_Over.png b/indra/newview/skins/default/textures/navbar/Help_Over.png
new file mode 100644
index 0000000000..b9bc0d0f87
--- /dev/null
+++ b/indra/newview/skins/default/textures/navbar/Help_Over.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/navbar/Help_Press.png b/indra/newview/skins/default/textures/navbar/Help_Press.png
new file mode 100644
index 0000000000..ed3695f9d5
--- /dev/null
+++ b/indra/newview/skins/default/textures/navbar/Help_Press.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/navbar/Home_Off.png b/indra/newview/skins/default/textures/navbar/Home_Off.png
new file mode 100644
index 0000000000..fe3bc63b77
--- /dev/null
+++ b/indra/newview/skins/default/textures/navbar/Home_Off.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/navbar/Home_Over.png b/indra/newview/skins/default/textures/navbar/Home_Over.png
new file mode 100644
index 0000000000..d9c6b3842e
--- /dev/null
+++ b/indra/newview/skins/default/textures/navbar/Home_Over.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/navbar/Info_Off.png b/indra/newview/skins/default/textures/navbar/Info_Off.png
new file mode 100644
index 0000000000..64722255a3
--- /dev/null
+++ b/indra/newview/skins/default/textures/navbar/Info_Off.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/navbar/Info_Over.png b/indra/newview/skins/default/textures/navbar/Info_Over.png
new file mode 100644
index 0000000000..84f1d03129
--- /dev/null
+++ b/indra/newview/skins/default/textures/navbar/Info_Over.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/navbar/Info_Press.png b/indra/newview/skins/default/textures/navbar/Info_Press.png
new file mode 100644
index 0000000000..169105829e
--- /dev/null
+++ b/indra/newview/skins/default/textures/navbar/Info_Press.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/navbar/NavBar_BG.png b/indra/newview/skins/default/textures/navbar/NavBar_BG.png
new file mode 100644
index 0000000000..1df61751a8
--- /dev/null
+++ b/indra/newview/skins/default/textures/navbar/NavBar_BG.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/navbar/Row_Selection.png b/indra/newview/skins/default/textures/navbar/Row_Selection.png
new file mode 100644
index 0000000000..fc4f0c07ef
--- /dev/null
+++ b/indra/newview/skins/default/textures/navbar/Row_Selection.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/navbar/Search.png b/indra/newview/skins/default/textures/navbar/Search.png
new file mode 100644
index 0000000000..c43519d5f1
--- /dev/null
+++ b/indra/newview/skins/default/textures/navbar/Search.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/quick_tips/avatar_free_mode.png b/indra/newview/skins/default/textures/quick_tips/avatar_free_mode.png
new file mode 100644
index 0000000000..be7c87efb6
--- /dev/null
+++ b/indra/newview/skins/default/textures/quick_tips/avatar_free_mode.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/quick_tips/camera_free_mode.png b/indra/newview/skins/default/textures/quick_tips/camera_free_mode.png
new file mode 100644
index 0000000000..9a3f3703b2
--- /dev/null
+++ b/indra/newview/skins/default/textures/quick_tips/camera_free_mode.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/quick_tips/camera_orbit_mode.png b/indra/newview/skins/default/textures/quick_tips/camera_orbit_mode.png
new file mode 100644
index 0000000000..dd72cc0162
--- /dev/null
+++ b/indra/newview/skins/default/textures/quick_tips/camera_orbit_mode.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/quick_tips/camera_pan_mode.png b/indra/newview/skins/default/textures/quick_tips/camera_pan_mode.png
new file mode 100644
index 0000000000..b537dcbe46
--- /dev/null
+++ b/indra/newview/skins/default/textures/quick_tips/camera_pan_mode.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/quick_tips/camera_preset_front_view.png b/indra/newview/skins/default/textures/quick_tips/camera_preset_front_view.png
new file mode 100644
index 0000000000..7674a75ac3
--- /dev/null
+++ b/indra/newview/skins/default/textures/quick_tips/camera_preset_front_view.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/quick_tips/camera_preset_group_view.png b/indra/newview/skins/default/textures/quick_tips/camera_preset_group_view.png
new file mode 100644
index 0000000000..9c9b923a5a
--- /dev/null
+++ b/indra/newview/skins/default/textures/quick_tips/camera_preset_group_view.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/quick_tips/camera_preset_rear_view.png b/indra/newview/skins/default/textures/quick_tips/camera_preset_rear_view.png
new file mode 100644
index 0000000000..15c3053491
--- /dev/null
+++ b/indra/newview/skins/default/textures/quick_tips/camera_preset_rear_view.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/quick_tips/move_fly_first.png b/indra/newview/skins/default/textures/quick_tips/move_fly_first.png
new file mode 100644
index 0000000000..b6e2ce60e4
--- /dev/null
+++ b/indra/newview/skins/default/textures/quick_tips/move_fly_first.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/quick_tips/move_fly_second.png b/indra/newview/skins/default/textures/quick_tips/move_fly_second.png
new file mode 100644
index 0000000000..84b63cc338
--- /dev/null
+++ b/indra/newview/skins/default/textures/quick_tips/move_fly_second.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/quick_tips/move_run_first.png b/indra/newview/skins/default/textures/quick_tips/move_run_first.png
new file mode 100644
index 0000000000..16093dc683
--- /dev/null
+++ b/indra/newview/skins/default/textures/quick_tips/move_run_first.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/quick_tips/move_run_second.png b/indra/newview/skins/default/textures/quick_tips/move_run_second.png
new file mode 100644
index 0000000000..19fa43ec32
--- /dev/null
+++ b/indra/newview/skins/default/textures/quick_tips/move_run_second.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/quick_tips/move_walk_first.png b/indra/newview/skins/default/textures/quick_tips/move_walk_first.png
new file mode 100644
index 0000000000..92d120d53e
--- /dev/null
+++ b/indra/newview/skins/default/textures/quick_tips/move_walk_first.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/quick_tips/move_walk_second.png b/indra/newview/skins/default/textures/quick_tips/move_walk_second.png
new file mode 100644
index 0000000000..f8e28722be
--- /dev/null
+++ b/indra/newview/skins/default/textures/quick_tips/move_walk_second.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/show_btn.tga b/indra/newview/skins/default/textures/show_btn.tga
new file mode 100644
index 0000000000..5f05f377e3
--- /dev/null
+++ b/indra/newview/skins/default/textures/show_btn.tga
Binary files differ
diff --git a/indra/newview/skins/default/textures/show_btn_selected.tga b/indra/newview/skins/default/textures/show_btn_selected.tga
new file mode 100644
index 0000000000..00a2f34a37
--- /dev/null
+++ b/indra/newview/skins/default/textures/show_btn_selected.tga
Binary files differ
diff --git a/indra/newview/skins/default/textures/taskpanel/TabIcon_Appearance_Off.png b/indra/newview/skins/default/textures/taskpanel/TabIcon_Appearance_Off.png
new file mode 100644
index 0000000000..2dc32a576b
--- /dev/null
+++ b/indra/newview/skins/default/textures/taskpanel/TabIcon_Appearance_Off.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/taskpanel/TabIcon_Appearance_Selected.png b/indra/newview/skins/default/textures/taskpanel/TabIcon_Appearance_Selected.png
new file mode 100644
index 0000000000..bea218a2fb
--- /dev/null
+++ b/indra/newview/skins/default/textures/taskpanel/TabIcon_Appearance_Selected.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/taskpanel/TabIcon_Close_Off.png b/indra/newview/skins/default/textures/taskpanel/TabIcon_Close_Off.png
new file mode 100644
index 0000000000..bc4e00c646
--- /dev/null
+++ b/indra/newview/skins/default/textures/taskpanel/TabIcon_Close_Off.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/taskpanel/TabIcon_Home_Off.png b/indra/newview/skins/default/textures/taskpanel/TabIcon_Home_Off.png
new file mode 100644
index 0000000000..1e7d7beafa
--- /dev/null
+++ b/indra/newview/skins/default/textures/taskpanel/TabIcon_Home_Off.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/taskpanel/TabIcon_Home_Selected.png b/indra/newview/skins/default/textures/taskpanel/TabIcon_Home_Selected.png
new file mode 100644
index 0000000000..a70d3abbbf
--- /dev/null
+++ b/indra/newview/skins/default/textures/taskpanel/TabIcon_Home_Selected.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/taskpanel/TabIcon_Me_Off.png b/indra/newview/skins/default/textures/taskpanel/TabIcon_Me_Off.png
new file mode 100644
index 0000000000..2d36f70361
--- /dev/null
+++ b/indra/newview/skins/default/textures/taskpanel/TabIcon_Me_Off.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/taskpanel/TabIcon_Me_Selected.png b/indra/newview/skins/default/textures/taskpanel/TabIcon_Me_Selected.png
new file mode 100644
index 0000000000..3c20459126
--- /dev/null
+++ b/indra/newview/skins/default/textures/taskpanel/TabIcon_Me_Selected.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/taskpanel/TabIcon_Open_Off.png b/indra/newview/skins/default/textures/taskpanel/TabIcon_Open_Off.png
new file mode 100644
index 0000000000..4556602f58
--- /dev/null
+++ b/indra/newview/skins/default/textures/taskpanel/TabIcon_Open_Off.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/taskpanel/TabIcon_People_Off.png b/indra/newview/skins/default/textures/taskpanel/TabIcon_People_Off.png
new file mode 100644
index 0000000000..c272372a39
--- /dev/null
+++ b/indra/newview/skins/default/textures/taskpanel/TabIcon_People_Off.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/taskpanel/TabIcon_People_Selected.png b/indra/newview/skins/default/textures/taskpanel/TabIcon_People_Selected.png
new file mode 100644
index 0000000000..3828752606
--- /dev/null
+++ b/indra/newview/skins/default/textures/taskpanel/TabIcon_People_Selected.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/taskpanel/TabIcon_Places_Off.png b/indra/newview/skins/default/textures/taskpanel/TabIcon_Places_Off.png
new file mode 100644
index 0000000000..d7ec33af55
--- /dev/null
+++ b/indra/newview/skins/default/textures/taskpanel/TabIcon_Places_Off.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/taskpanel/TabIcon_Places_Selected.png b/indra/newview/skins/default/textures/taskpanel/TabIcon_Places_Selected.png
new file mode 100644
index 0000000000..dd7e361ea9
--- /dev/null
+++ b/indra/newview/skins/default/textures/taskpanel/TabIcon_Places_Selected.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/taskpanel/TabIcon_Things_Off.png b/indra/newview/skins/default/textures/taskpanel/TabIcon_Things_Off.png
new file mode 100644
index 0000000000..e56eda9802
--- /dev/null
+++ b/indra/newview/skins/default/textures/taskpanel/TabIcon_Things_Off.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/taskpanel/TabIcon_Things_Selected.png b/indra/newview/skins/default/textures/taskpanel/TabIcon_Things_Selected.png
new file mode 100644
index 0000000000..d4ac451c8e
--- /dev/null
+++ b/indra/newview/skins/default/textures/taskpanel/TabIcon_Things_Selected.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/taskpanel/TaskPanel_Tab_Off.png b/indra/newview/skins/default/textures/taskpanel/TaskPanel_Tab_Off.png
new file mode 100644
index 0000000000..918be7555f
--- /dev/null
+++ b/indra/newview/skins/default/textures/taskpanel/TaskPanel_Tab_Off.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/taskpanel/TaskPanel_Tab_Selected.png b/indra/newview/skins/default/textures/taskpanel/TaskPanel_Tab_Selected.png
new file mode 100644
index 0000000000..b3316386b9
--- /dev/null
+++ b/indra/newview/skins/default/textures/taskpanel/TaskPanel_Tab_Selected.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/textures.xml b/indra/newview/skins/default/textures/textures.xml
index 34c9dea7e6..0bd5f114ed 100644
--- a/indra/newview/skins/default/textures/textures.xml
+++ b/indra/newview/skins/default/textures/textures.xml
@@ -1,74 +1,359 @@
<textures version="101">
+ <!-- Please add new files alphabetically to prevent merge conflicts. JC -->
+ <texture name="Accordion_ArrowClosed_Off" file_name="containers/Accordion_ArrowClosed_Off.png" preload="false" />
+ <texture name="Accordion_ArrowClosed_Press" file_name="containers/Accordion_ArrowClosed_Press.png" preload="false" />
+ <texture name="Accordion_ArrowOpened_Off" file_name="containers/Accordion_ArrowOpened_Off.png" preload="false" />
+ <texture name="Accordion_ArrowOpened_Press" file_name="containers/Accordion_ArrowOpened_Press.png" preload="false" />
+ <texture name="Accordion_Off" file_name="containers/Accordion_Off.png" preload="false" />
+ <texture name="Accordion_Press" file_name="containers/Accordion_Press.png" preload="false" />
- <texture name="icn_scrollbar_thumb.tga" preload="true" scale_top="7" scale_left="4" scale_bottom="8" scale_right="4" />
- <texture name="icn_scrollbar_bg.tga" preload="true" scale_top="7" scale_left="4" scale_bottom="8" scale_right="4" />
- <texture name="sm_rounded_corners_simple.tga" scale_left="4" scale_top="4" scale_bottom="4" scale_right="4"/>
- <texture name="icn_textfield_enabled.tga" scale_left="5" scale_top="5" scale_bottom="5" scale_right="5"/>
-
- <texture name="button_disabled_32x128.tga" preload="true" scale_left="16" scale_top="16" scale_right="112" scale_bottom="16" />
-
- <texture name="button_enabled_32x128.tga" preload="true" scale_left="16" scale_top="16" scale_right="112" scale_bottom="16" />
-
- <texture name="toolbar_btn_enabled.tga" scale_left="7" scale_top="32" scale_right="121" scale_bottom="0" />
+ <texture name="AddItem_Off" file_name="icons/AddItem_Off.png" preload="false" />
+ <texture name="AddItem_Press" file_name="icons/AddItem_Press.png" preload="false" />
- <texture name="toolbar_btn_disabled.tga" scale_left="7" scale_top="32" scale_right="121" scale_bottom="0" />
-
- <texture name="toolbar_btn_selected.tga" scale_left="7" scale_top="32" scale_right="121" scale_bottom="0" />
-
- <texture name="button_enabled_selected_32x128.tga" preload="true" scale_left="16" scale_top="16" scale_right="112" scale_bottom="16" />
-
- <texture name="checkbox_disabled_false.tga" preload="true"/>
- <texture name="checkbox_disabled_true.tga" preload="true"/>
- <texture name="checkbox_enabled_false.tga" preload="true"/>
- <texture name="checkbox_enabled_true.tga" preload="true"/>
-
- <texture name="close_in_blue.tga" preload="true"/>
-
- <texture name="minimize.tga" preload="true"/>
+ <texture name="Arrow_Left_Off" file_name="navbar/Arrow_Left_Off.png" preload="true"/>
+ <texture name="Arrow_Left_Press" file_name="navbar/Arrow_Left_Press.png" preload="true"/>
+ <texture name="Arrow_Right_Off" file_name="navbar/Arrow_Right_Off.png" preload="true"/>
+ <texture name="Arrow_Right_Press" file_name="navbar/Arrow_Right_Press.png" preload="true"/>
+
+ <texture name="Arrow_Up" file_name="widgets/Arrow_Up.png" preload="true" />
+ <texture name="Arrow_Down" file_name="widgets/Arrow_Down.png" preload="true" />
+
+ <texture name="BackArrow_Off" file_name="icons/BackArrow_Off.png" preload="false" />
+ <texture name="BackArrow_Press" file_name="icons/BackArrow_Press.png" preload="false" />
+
+ <texture name="BottomTray_BG" file_name="bottomtray/BottomTray_BG.png" preload="false" />
+
+ <texture name="Checkbox_Off_Disabled" file_name="widgets/Checkbox_Disabled.png" preload="true" />
+ <texture name="Checkbox_On_Disabled" file_name="widgets/Checkbox_On_Disabled.png" preload="true" />
+ <texture name="Checkbox_Off" file_name="widgets/Checkbox_Off.png" preload="true" />
+ <texture name="Checkbox_On" file_name="widgets/Checkbox_On.png" preload="true" />
+ <texture name="Checkbox_On_Press" file_name="widgets/Checkbox_On_Press.png" preload="true" />
+ <texture name="Checkbox_Press" file_name="widgets/Checkbox_Press.png" preload="true" />
+
+ <texture name="ComboButton_Disabled" file_name="widgets/ComboButton_Disabled.png" preload="true" scale.left="2" scale.top="19" scale.right="18" scale.bottom="2" />
+ <texture name="ComboButton_Over" file_name="widgets/ComboButton_Over.png" preload="true" scale.left="2" scale.top="19" scale.right="18" scale.bottom="2" />
+ <texture name="ComboButton_Press" file_name="widgets/ComboButton_Press.png" preload="true" scale.left="2" scale.top="19" scale.right="18" scale.bottom="2" />
+ <texture name="ComboButton_Selected" file_name="widgets/ComboButton_Selected.png" preload="true" scale.left="2" scale.top="19" scale.right="18" scale.bottom="2" />
+ <texture name="ComboButton_Off" file_name="widgets/ComboButton_Off.png" preload="true" scale.left="2" scale.top="19" scale.right="18" scale.bottom="2" />
+
+ <texture name="Container" file_name="containers/Container.png" preload="false" />
+
+ <texture name="DisclosureArrow_Closed_Off" file_name="widgets/DisclosureArrow_Closed_Off.png" preload="true" />
+ <texture name="DisclosureArrow_Closed_Press" file_name="widgets/DisclosureArrow_Closed_Press.png" preload="true" />
+ <texture name="DisclosureArrow_Opened_Off" file_name="widgets/DisclosureArrow_Opened_Off.png" preload="true" />
+ <texture name="DisclosureArrow_Opened_Press" file_name="widgets/DisclosureArrow_Opened_Press.png" preload="true" />
+
+ <texture name="DownArrow" file_name="bottomtray/DownArrow.png" preload="false" />
+
+ <texture name="DropDown_Disabled" file_name="widgets/DropDown_Disabled.png" preload="true" scale.left="2" scale.top="19" scale.right="18" scale.bottom="2" />
+ <texture name="DropDown_Over" file_name="widgets/DropDown_Over.png" preload="true" scale.left="2" scale.top="19" scale.right="18" scale.bottom="2" />
+ <texture name="DropDown_Press" file_name="widgets/DropDown_Press.png" preload="true" scale.left="2" scale.top="19" scale.right="18" scale.bottom="2" />
+ <texture name="DropDown_Selected" file_name="widgets/DropDown_Selected.png" preload="true" scale.left="2" scale.top="19" scale.right="18" scale.bottom="2" />
+ <texture name="DropDown_Off" file_name="widgets/DropDown_Off.png" preload="true" scale.left="2" scale.top="19" scale.right="18" scale.bottom="2" />
+
+ <texture name="Favorite_Star_Active" file_name="navbar/Favorite_Star_Active.png" preload="false" />
+ <texture name="Favorite_Star_Off" file_name="navbar/Favorite_Star_Off.png" preload="false" />
+ <texture name="Favorite_Star_Press" file_name="navbar/Favorite_Star_Press.png" preload="false" />
+ <texture name="Favorite_Star_Over" file_name="navbar/Favorite_Star_Over.png" preload="false"/>
+
+ <texture name="FileMenu_BarSelect" file_name="navbar/FileMenu_BarSelect.png" preload="false" />
+ <texture name="FileMenu_BG" file_name="navbar/FileMenu_BG.png" preload="false" />
+
+ <texture name="ForwardArrow_Off" file_name="icons/ForwardArrow_Off.png" preload="false" />
+ <texture name="ForwardArrow_Press" file_name="icons/ForwardArrow_Press.png" preload="false" />
+
+ <texture name="Help_Off" file_name="navbar/Help_Off.png" preload="false"/>
+ <texture name="Help_Press" file_name="navbar/Help_Press.png" preload="false"/>
+
+ <texture name="History_Arrow" file_name="navbar/History_Arrow.png" preload="true"/>
+
+ <texture name="Home_Off" file_name="navbar/Home_Off.png" preload="false"/>
+ <texture name="Home_Press" file_name="navbar/Home_Press.png" preload="false"/>
+
+ <texture name="Icon_Close_Background" file_name="windows/Icon_Close_Background.png" preload="true" />
+ <texture name="Icon_Close_Foreground" file_name="windows/Icon_Close_Foreground.png" preload="true" />
+ <texture name="Icon_Close_Press" file_name="windows/Icon_Close_Press.png" preload="true" />
+ <texture name="Icon_Close_Toast" file_name="windows/Icon_Close_Toast.png" preload="true" />
+
+ <texture name="Icon_Dock_Background" file_name="windows/Icon_Dock_Background.png" preload="true" />
+ <texture name="Icon_Dock_Foreground" file_name="windows/Icon_Dock_Foreground.png" preload="true" />
+ <texture name="Icon_Dock_Press" file_name="windows/Icon_Dock_Press.png" preload="true" />
+
+ <texture name="Icon_Gear_Background" file_name="windows/Icon_Gear_Background.png" preload="false"/>
+ <texture name="Icon_Gear_Foreground" file_name="windows/Icon_Gear_Foreground.png" preload="false"/>
+ <texture name="Icon_Gear_Press" file_name="windows/Icon_Gear_Press.png" preload="false"/>
+
+ <texture name="Icon_Undock_Background" file_name="windows/Icon_Undock_Background.png" preload="true" />
+ <texture name="Icon_Undock_Foreground" file_name="windows/Icon_Undock_Foreground.png" preload="true" />
+ <texture name="Icon_Undock_Press" file_name="windows/Icon_Undock_Press.png" preload="true" />
+
+ <texture name="Info" file_name="icons/Info.png" preload="false" />
+
+ <texture name="Info_Off" file_name="navbar/Info_Off.png" preload="false"/>
+ <texture name="Info_Press" file_name="navbar/Info_Press.png" preload="false"/>
+
+ <texture name="ListItem_Select" file_name="widgets/ListItem_Select.png" preload="true" />
+
+ <texture name="menu_separator" file_name="navbar/FileMenu_Divider.png" scale.left="4" scale.top="166" scale.right="0" scale.bottom="0" />
+
+ <texture name="NavBar_BG_NoFav" file_name="navbar/NavBar_BG_NoFav.png" preload="false" />
+ <texture name="NavBar_BG" file_name="navbar/NavBar_BG.png" preload="false" />
+
+ <texture name="NearbyVoice_Lvl1" file_name="bottomtray/NearbyVoice_Lvl1.png" preload="false" />
+ <texture name="NearbyVoice_Lvl2" file_name="bottomtray/NearbyVoice_Lvl2.png" preload="false" />
+ <texture name="NearbyVoice_Lvl3" file_name="bottomtray/NearbyVoice_Lvl3.png" preload="false" />
+ <texture name="NearbyVoice_On" file_name="bottomtray/NearbyVoice_On.png" preload="false" />
+
+ <texture name="OptionsMenu_Off" file_name="icons/OptionsMenu_Off.png" preload="false" />
+ <texture name="OptionsMenu_Press" file_name="icons/OptionsMenu_Press.png" preload="false" />
+
+ <texture name="ProgressBar" file_name="widgets/ProgressBar.png" preload="true" scale.left="4" scale.top="10" scale.right="48" scale.bottom="2" />
+ <texture name="ProgressTrack" file_name="widgets/ProgressTrack.png" preload="true" scale.left="4" scale.top="13" scale.right="148" scale.bottom="2" />
+
+ <texture name="PushButton_Off" file_name="widgets/PushButton_Off.png" preload="true" scale.left="4" scale.top="19" scale.right="28" scale.bottom="4" />
+ <texture name="PushButton_Press" file_name="widgets/PushButton_Press.png" preload="true" scale.left="4" scale.top="19" scale.right="28" scale.bottom="4" />
+ <texture name="PushButton_Disabled" file_name="widgets/PushButton_Disabled.png" preload="true" scale.left="4" scale.top="19" scale.right="28" scale.bottom="4" />
+ <texture name="PushButton_Selected" file_name="widgets/PushButton_Selected.png" preload="true" scale.left="4" scale.top="19" scale.right="28" scale.bottom="4" />
+ <texture name="PushButton_Selected_Press" file_name="widgets/PushButton_Selected_Press.png" preload="true" scale.left="4" scale.top="19" scale.right="28" scale.bottom="4" />
+ <texture name="PushButton_Selected_Disabled" file_name="widgets/PushButton_Selected_Disabled.png" preload="true" scale.left="4" scale.top="19" scale.right="28" scale.bottom="4" />
+
+ <texture name="RadioButton_Press" file_name="widgets/RadioButton_Press.png" preload="true" />
+ <texture name="RadioButton_On_Press" file_name="widgets/RadioButton_On_Press.png" preload="true" />
+ <texture name="RadioButton_Off" file_name="widgets/RadioButton_Off.png" preload="true" />
+ <texture name="RadioButton_On" file_name="widgets/RadioButton_On.png" preload="true" />
+ <texture name="RadioButton_Disabled" file_name="widgets/RadioButton_Disabled.png" preload="true" />
+ <texture name="RadioButton_On_Disabled" file_name="widgets/RadioButton_On_Disabled.png" preload="true" />
+
+ <texture name="Resize_Corner" file_name="windows/Resize_Corner.png" preload="true"/>
+
+ <texture name="Row_Selection" file_name="navbar/Row_Selection.png" preload="false" />
+
+ <texture name="ScrollArrow_Down" file_name="widgets/ScrollArrow_Down.png" preload="true" scale.left="2" scale.top="13" scale.right="13" scale.bottom="2" />
+ <texture name="ScrollArrow_Left" file_name="widgets/ScrollArrow_Left.png" preload="true" scale.left="2" scale.top="13" scale.right="13" scale.bottom="2" />
+ <texture name="ScrollArrow_Right" file_name="widgets/ScrollArrow_Right.png" preload="true" scale.left="2" scale.top="13" scale.right="13" scale.bottom="2" />
+ <texture name="ScrollArrow_Up" file_name="widgets/ScrollArrow_Up.png" preload="true" scale.left="2" scale.top="13" scale.right="13" scale.bottom="2" />
+
+ <texture name="ScrollThumb_Horiz" file_name="widgets/ScrollThumb_Horiz.png" preload="true" scale.left="4" scale.top="0" scale.bottom="0" scale.right="2" />
+ <texture name="ScrollThumb_Vert" file_name="widgets/ScrollThumb_Vert.png" preload="true" scale.left="4" scale.top="53" scale.bottom="10" scale.right="4" />
+ <texture name="ScrollTrack_Vert" file_name="widgets/ScrollTrack_Vert.png" preload="true" scale.left="2" scale.top="40" scale.bottom="13" scale.right="0" />
+ <texture name="ScrollTrack_Horiz" file_name="widgets/ScrollTrack_Horiz.png" preload="true" scale.left="4" scale.top="0" scale.bottom="0" scale.right="2" />
+
+ <texture name="Search" file_name="navbar/Search.png" preload="false"/>
+
+ <texture name="SegmentedBtn_Left_Off" file_name="widgets/SegmentedBtn_Left_Off.png" preload="true" scale.left="4" scale.top="19" scale.right="22" scale.bottom="4" />
+ <texture name="SegmentedBtn_Left_Press" file_name="widgets/SegmentedBtn_Left_Press.png" preload="true" scale.left="4" scale.top="19" scale.right="22" scale.bottom="4" />
+ <texture name="SegmentedBtn_Left_Disabled" file_name="widgets/SegmentedBtn_Left_Disabled.png" preload="true" scale.left="4" scale.top="19" scale.right="22" scale.bottom="4" />
+ <texture name="SegmentedBtn_Left_Selected" file_name="widgets/SegmentedBtn_Left_Selected.png" preload="true" scale.left="4" scale.top="19" scale.right="22" scale.bottom="4" />
+ <texture name="SegmentedBtn_Left_Selected_Press" file_name="widgets/SegmentedBtn_Left_Selected_Press.png" preload="true" scale.left="4" scale.top="19" scale.right="22" scale.bottom="4" />
+ <texture name="SegmentedBtn_Left_Selected_Disabled" file_name="widgets/SegmentedBtn_Left_Selected_Disabled.png" preload="true" scale.left="4" scale.top="19" scale.right="22" scale.bottom="4" />
+
+ <texture name="SegmentedBtn_Middle_Off" file_name="widgets/SegmentedBtn_Middle_Off.png" preload="true" scale.left="4" scale.top="19" scale.right="22" scale.bottom="4" />
+ <texture name="SegmentedBtn_Middle_Press" file_name="widgets/SegmentedBtn_Middle_Press.png" preload="true" scale.left="4" scale.top="19" scale.right="22" scale.bottom="4" />
+ <texture name="SegmentedBtn_Middle_Disabled" file_name="widgets/SegmentedBtn_Middle_Disabled.png" preload="true" scale.left="4" scale.top="19" scale.right="22" scale.bottom="4" />
+ <texture name="SegmentedBtn_Middle_Selected" file_name="widgets/SegmentedBtn_Middle_Selected.png" preload="true" scale.left="4" scale.top="19" scale.right="22" scale.bottom="4" />
+ <texture name="SegmentedBtn_Middle_Selected_Press" file_name="widgets/SegmentedBtn_Middle_Selected_Press.png" preload="true" scale.left="4" scale.top="19" scale.right="22" scale.bottom="4" />
+ <texture name="SegmentedBtn_Middle_Selected_Disabled" file_name="widgets/SegmentedBtn_Middle_Selected_Disabled.png" preload="true" scale.left="4" scale.top="19" scale.right="22" scale.bottom="4" />
+
+ <texture name="SegmentedBtn_Right_Off" file_name="widgets/SegmentedBtn_Right_Off.png" preload="true" scale.left="4" scale.top="19" scale.right="22" scale.bottom="4" />
+ <texture name="SegmentedBtn_Right_Press" file_name="widgets/SegmentedBtn_Right_Press.png" preload="true" scale.left="4" scale.top="19" scale.right="22" scale.bottom="4" />
+ <texture name="SegmentedBtn_Right_Disabled" file_name="widgets/SegmentedBtn_Right_Disabled.png" preload="true" scale.left="4" scale.top="19" scale.right="22" scale.bottom="4" />
+ <texture name="SegmentedBtn_Right_Selected" file_name="widgets/SegmentedBtn_Right_Selected.png" preload="true" scale.left="4" scale.top="19" scale.right="22" scale.bottom="4" />
+ <texture name="SegmentedBtn_Right_Selected_Press" file_name="widgets/SegmentedBtn_Right_Selected_Press.png" preload="true" scale.left="4" scale.top="19" scale.right="22" scale.bottom="4" />
+ <texture name="SegmentedBtn_Right_Selected_Disabled" file_name="widgets/SegmentedBtn_Right_Selected_Disabled.png" preload="true" scale.left="4" scale.top="19" scale.right="22" scale.bottom="4" />
+
+ <texture name="SliderTrack_Horiz" file_name="widgets/SliderTrack_Horiz.png" scale.left="4" scale.top="4" scale.right="100" scale.bottom="2" />
+ <texture name="SliderTrack_Vert" file_name="widgets/SliderTrack_Vert.png" scale.left="2" scale.top="100" scale.right="4" scale.bottom="4" />
+ <texture name="SliderThumb_Off" file_name="widgets/SliderThumb_Off.png" />
+ <texture name="SliderThumb_Disabled" file_name="widgets/SliderThumb_Disabled.png" />
+ <texture name="SliderThumb_Press" file_name="widgets/SliderThumb_Press.png" />
+
+ <texture name="Stepper_Down_Disabled" file_name="widgets/Stepper_Down_Disabled.png" preload="true"/>
+ <texture name="Stepper_Down_Off" file_name="widgets/Stepper_Down_Off.png" preload="true"/>
+ <texture name="Stepper_Down_Press" file_name="widgets/Stepper_Down_Press.png" preload="true"/>
+ <texture name="Stepper_Up_Disabled" file_name="widgets/Stepper_Up_Disabled.png" preload="true"/>
+ <texture name="Stepper_Up_Off" file_name="widgets/Stepper_Up_Off.png" preload="true"/>
+ <texture name="Stepper_Up_Press" file_name="widgets/Stepper_Up_Press.png" preload="true"/>
+
+ <texture name="TabIcon_Appearance_Off" file_name="taskpanel/TabIcon_Appearance_Off.png" preload="false" />
+ <texture name="TabIcon_Appearance_Over" file_name="taskpanel/TabIcon_Appearance_Over.png" preload="false"/>
+ <texture name="TabIcon_Appearance_Selected" file_name="taskpanel/TabIcon_Appearance_Selected.png" preload="false" />
+ <texture name="TabIcon_Close_Off" file_name="taskpanel/TabIcon_Close_Off.png" preload="false" />
+ <texture name="TabIcon_Close_Over" file_name="taskpanel/TabIcon_Close_Over.png" preload="false"/>
+ <texture name="TabIcon_Home_Off" file_name="taskpanel/TabIcon_Home_Off.png" preload="false" />
+ <texture name="TabIcon_Home_Over" file_name="taskpanel/TabIcon_Home_Over.png" preload="false"/>
+ <texture name="TabIcon_Home_Selected" file_name="taskpanel/TabIcon_Home_Selected.png" preload="false" />
+ <texture name="TabIcon_Me_Off" file_name="taskpanel/TabIcon_Me_Off.png" preload="false" />
+ <texture name="TabIcon_Me_Over" file_name="taskpanel/TabIcon_Me_Over.png" preload="false"/>
+ <texture name="TabIcon_Me_Selected" file_name="taskpanel/TabIcon_Me_Selected.png" preload="false" />
+ <texture name="TabIcon_Open_Off" file_name="taskpanel/TabIcon_Open_Off.png" preload="false" />
+ <texture name="TabIcon_Open_Over" file_name="taskpanel/TabIcon_Open_Over.png" preload="false"/>
+ <texture name="TabIcon_People_Off" file_name="taskpanel/TabIcon_People_Off.png" preload="false" />
+ <texture name="TabIcon_People_Over" file_name="taskpanel/TabIcon_People_Over.png" preload="false"/>
+ <texture name="TabIcon_People_Selected" file_name="taskpanel/TabIcon_People_Selected.png" preload="false" />
+ <texture name="TabIcon_Places_Over" file_name="taskpanel/TabIcon_Places_Over.png" preload="false"/>
+ <texture name="TabIcon_Places_Off" file_name="taskpanel/TabIcon_Places_Off.png" preload="false" />
+ <texture name="TabIcon_Places_Selected" file_name="taskpanel/TabIcon_Places_Selected.png" preload="false" />
+ <texture name="TabIcon_Things_Off" file_name="taskpanel/TabIcon_Things_Off.png" preload="false" />
+ <texture name="TabIcon_Things_Selected" file_name="taskpanel/TabIcon_Things_Selected.png" preload="false" />
+ <texture name="TabIcon_Things_Over" file_name="taskpanel/TabIcon_Things_Over.png" preload="false"/>
+
+ <texture name="TabTop_Divider" file_name="containers/TabTop_Divider.png" preload="false" />
+ <texture name="TabTop_Left_Press" file_name="containers/TabTop_Left_Press.png" preload="false" />
+ <texture name="TabTop_Middle_Press" file_name="containers/TabTop_Middle_Press.png" preload="false" />
+ <texture name="TabTop_Right_Off" file_name="containers/TabTop_Right_Off.png" preload="false" />
+ <texture name="TabTop_Right_Press" file_name="containers/TabTop_Right_Press.png" preload="false" />
+ <texture name="TabTop_Right_Selected" file_name="containers/TabTop_Right_Selected.png" preload="false" />
+ <texture name="TabTop_Middle_Off" file_name="containers/TabTop_Middle_Off.png" preload="false" scale.left="8" scale.top="8" scale.right="120" scale.bottom="9" />
+ <texture name="TabTop_Middle_Selected" file_name="containers/TabTop_Middle_Selected.png" preload="false" scale.left="8" scale.top="8" scale.right="96" scale.bottom="9" />
+ <texture name="TabTop_Left_Off" file_name="containers/TabTop_Left_Off.png" preload="false" scale.left="8" scale.top="8" scale.right="120" scale.bottom="9"/>
+ <texture name="TabTop_Left_Selected" file_name="containers/TabTop_Left_Selected.png" preload="false" scale.left="8" scale.top="8" scale.right="96" scale.bottom="9"/>
+
+ <texture name="TaskPanel_Tab_Off" file_name="taskpanel/TaskPanel_Tab_Off.png" preload="false" scale.left="4" scale.top="29" scale.right="36" scale.bottom="4" />
+ <texture name="TaskPanel_Tab_Selected" file_name="taskpanel/TaskPanel_Tab_Selected.png" preload="false" scale.left="5" scale.top="30" scale.right="36" scale.bottom="5" />
+ <texture name="TaskPanel_BG" file_name="taskpanel/TaskPanel_BG.png" preload="false" scale.left="4" scale.top="146" scale.right="146" scale.bottom="4" />
+ <texture name="TaskPanel_Tab_Unselected" file_name="taskpanel/TaskPanel_Tab_Over.png" preload="false" scale.left="5" scale.top="30" scale.right="36" scale.bottom="5" />
+
+ <texture name="TextField_Search_Disabled" file_name="widgets/TextField_Search_Disabled.png" preload="true" scale.left="4" scale.top="18" scale.right="252" scale.bottom="4" />
+ <texture name="TextField_Off" file_name="widgets/TextField_Off.png" preload="true" scale.left="4" scale.top="18" scale.right="252" scale.bottom="4" />
+ <texture name="TextField_Search_Active" file_name="widgets/TextField_Search_Active.png" preload="true" scale.left="4" scale.top="18" scale.right="252" scale.bottom="4" />
+ <texture name="TextField_Search_Off" file_name="widgets/TextField_Search_Off.png" preload="true" scale.left="4" scale.top="18" scale.right="252" scale.bottom="4" />
+ <texture name="TextField_Disabled" file_name="widgets/TextField_Disabled.png" preload="true" scale.left="4" scale.top="18" scale.right="252" scale.bottom="4" />
+ <texture name="TextField_Active" file_name="widgets/TextField_Active.png" preload="true" scale.left="4" scale.top="18" scale.right="252" scale.bottom="4" />
+
+ <texture name="Toast_CloseBtn" file_name="windows/Toast_CloseBtn.png" preload="true" />
+ <texture name="Toast" file_name="windows/Toast.png" preload="true" />
+
+ <texture name="Toolbar_Divider" file_name="containers/Toolbar_Divider.png" preload="false" />
+ <texture name="Toolbar_Left_Off" file_name="containers/Toolbar_Left_Off.png" preload="false" />
+ <texture name="Toolbar_Left_Press" file_name="containers/Toolbar_Left_Press.png" preload="false" />
+ <texture name="Toolbar_Left_Selected" file_name="containers/Toolbar_Left_Selected.png" preload="false" />
+ <texture name="Toolbar_Middle_Off" file_name="containers/Toolbar_Middle_Off.png" preload="false" />
+ <texture name="Toolbar_Middle_Press" file_name="containers/Toolbar_Middle_Press.png" preload="false" />
+ <texture name="Toolbar_Middle_Selected" file_name="containers/Toolbar_Middle_Selected.png" preload="false" />
+ <texture name="Toolbar_Right_Off" file_name="containers/Toolbar_Right_Off.png" preload="false" />
+ <texture name="Toolbar_Right_Press" file_name="containers/Toolbar_Right_Press.png" preload="false" />
+ <texture name="Toolbar_Right_Selected" file_name="containers/Toolbar_Right_Selected.png" preload="false" />
+
+ <texture name="TrashItem_Off" file_name="icons/TrashItem_Off.png" preload="false" />
+ <texture name="TrashItem_Press" file_name="icons/TrashItem_Press.png" preload="false" />
+
+ <texture name="Unread_IM" file_name="bottomtray/Unread_IM.png" preload="false" />
+ <texture name="Unread_Msg" file_name="bottomtray/Unread_Msg.png" preload="false" />
+
+ <texture name="VoicePTT_Lvl1" file_name="bottomtray/VoicePTT_Lvl1.png" preload="false" />
+ <texture name="VoicePTT_Lvl2" file_name="bottomtray/VoicePTT_Lvl2.png" preload="false" />
+ <texture name="VoicePTT_Lvl3" file_name="bottomtray/VoicePTT_Lvl3.png" preload="false" />
+ <texture name="VoicePTT_Off" file_name="bottomtray/VoicePTT_Off.png" preload="false" />
+ <texture name="VoicePTT_On" file_name="bottomtray/VoicePTT_On.png" preload="false" />
+
+ <texture name="Widget_DownArrow" file_name="icons/Widget_DownArrow.png" preload="true" />
+
+ <texture name="Window_Background" file_name="windows/Window_Background.png" preload="true" />
+ <texture name="Window_Foreground" file_name="windows/Window_Foreground.png" preload="true" />
+
+
+
+
+
+ <!--There are still references to this old textfield art in the code somewhere -erica-->
+
+ <texture name="btn_chatbar.tga" scale.left="20" scale.top="24" scale.right="44" scale.bottom="0"/>
+ <texture name="btn_chatbar_selected.tga" scale.left="20" scale.top="24" scale.right="44" scale.bottom="0"/>
+
+ <texture name="cam_rotate_out.tga" preload="false"/>
+ <texture name="cam_rotate_in.tga" preload="false"/>
+ <texture name="cam_zoom_out.tga" preload="false"/>
+ <texture name="cam_zoom_plus_in.tga" preload="false"/>
+ <texture name="cam_zoom_minus_in.tga" preload="false"/>
+
+ <texture name="close_inactive_blue.tga"/>
+ <texture name="closebox.tga"/>
+ <texture name="icn_clear_lineeditor.tga" />
+
+ <texture name="icn_chatbar.tga"/>
+ <texture name="icn_media-pause.tga"/>
+ <texture name="icn_media-play.tga"/>
+ <texture name="icn_music-play.tga"/>
+ <texture name="icn_music-pause.tga"/>
+ <texture name="icn_media_web.tga" preload="true"/>
+ <texture name="icn_media_movie.tga" preload="true"/>
+
+ <texture name="icn_speaker-muted_dark.tga"/>
+ <texture name="icn_speaker_dark.tga"/>
+
+ <texture name="icn_voice-localchat.tga"/>
+ <texture name="icn_voice-groupfocus.tga"/>
+ <texture name="icn_voice-pvtfocus.tga"/>
+
+ <texture name="jump_left_out.tga"/>
+ <texture name="jump_left_in.tga"/>
+ <texture name="jump_right_out.tga"/>
+ <texture name="jump_right_in.tga"/>
+
+ <texture name="move_forward_out.tga" preload="false"/>
+ <texture name="move_forward_in.tga" preload="false"/>
+ <texture name="move_left_out.tga" preload="false"/>
+ <texture name="move_left_in.tga" preload="false"/>
+ <texture name="move_turn_left_out.tga" preload="false"/>
+ <texture name="move_turn_left_in.tga" preload="false"/>
+ <texture name="move_turn_right_out.tga" preload="false"/>
+ <texture name="move_turn_right_in.tga" preload="false"/>
+ <texture name="move_right_out.tga" preload="false"/>
+ <texture name="move_right_in.tga" preload="false"/>
+ <texture name="move_up_in.tga" preload="false"/>
+ <texture name="move_up_out.tga" preload="false"/>
+ <texture name="move_down_in.tga" preload="false"/>
+ <texture name="move_down_out.tga" preload="false"/>
+
+ <texture name="tool_grab.tga"/>
+ <texture name="tool_grab_active.tga"/>
+
+ <texture name="tool_face.tga"/>
+ <texture name="tool_face_active.tga"/>
+
+ <texture name="tool_create.tga"/>
+ <texture name="tool_create_active.tga"/>
+
+ <texture name="up_arrow.tga" file_name="up_arrow.png"/>
+ <texture name="down_arrow.tga" file_name="down_arrow.png"/>
+
+ <texture name="restore_inactive.tga"/>
+ <texture name="restore.tga"/>
+ <texture name="restore_pressed.tga"/>
+
+ <texture name="tearoffbox.tga"/>
+ <texture name="tearoff_pressed.tga"/>
+
+ <texture name="icn_label_music.tga"/>
+ <texture name="icn_label_media.tga"/>
+ <texture name="arrow_down.tga"/>
+ <texture name="cloud-particle.j2c" use_mips="true"/>
+
+ <texture name="skin_thumbnail_default.png" preload="false" />
+
+ <texture name="icn_textfield_enabled.tga" scale.left="5" scale.top="5" scale.bottom="5" scale.right="5"/>
+ <texture name="icn_rounded-text-field.tga" scale.left="14" scale.bottom="16" scale.top="16" scale.right="114"/>
+
+ <texture name="toolbar_btn_enabled.tga" scale.left="7" scale.top="32" scale.right="121" scale.bottom="0" />
+ <texture name="toolbar_btn_disabled.tga" scale.left="7" scale.top="32" scale.right="121" scale.bottom="0" />
+ <texture name="toolbar_btn_selected.tga" scale.left="7" scale.top="32" scale.right="121" scale.bottom="0" />
+
+ <texture name="minimize_inactive.tga" preload="true"/>
+ <texture name="minimize.tga" preload="true" />
<texture name="minimize_pressed.tga" preload="true"/>
-
- <texture name="radio_active_false.tga" preload="true"/>
- <texture name="radio_active_true.tga" preload="true"/>
- <texture name="radio_inactive_false.tga" preload="true"/>
- <texture name="radio_inactive_true.tga" preload="true"/>
-
- <texture name="combobox_arrow.tga" preload="true"/>
-
- <texture name="resize_handle_bottom_right_blue.tga" preload="true"/>
-
- <texture name="rounded_square.tga" file_name="rounded_square.j2c" preload="true" scale_left="16" scale_top="16" scale_right="112" scale_bottom="16"/>
-
- <texture name="rounded_square_soft.tga" file_name="rounded_square_soft.j2c" preload="true" scale_left="16" scale_top="16" scale_right="112" scale_bottom="16"/>
-
- <texture name="toolbar_tab.tga" preload="true" scale_left="6" scale_top="42" scale_right="104" scale_bottom="8"/>
- <texture name="toolbar_bg.tga" preload="true" scale_left="6" scale_top="42" scale_right="96" scale_bottom="16"/>
-
- <texture name="progressbar_fill.tga" preload="true" scale_left="10" scale_top="7" scale_right="65" scale_bottom="7"/>
- <texture name="progressbar_track.tga" preload="true" scale_left="10" scale_top="7" scale_right="80" scale_bottom="7"/>
-
- <texture name="scrollbutton_down_in_blue.tga" preload="true"/>
- <texture name="scrollbutton_down_out_blue.tga" preload="true"/>
- <texture name="scrollbutton_left_in_blue.tga" preload="true"/>
- <texture name="scrollbutton_left_out_blue.tga" preload="true"/>
- <texture name="scrollbutton_right_in_blue.tga" preload="true"/>
- <texture name="scrollbutton_right_out_blue.tga" preload="true"/>
- <texture name="scrollbutton_up_in_blue.tga" preload="true"/>
- <texture name="scrollbutton_up_out_blue.tga" preload="true"/>
- <texture name="spin_down_in_blue.tga" preload="true"/>
- <texture name="spin_down_out_blue.tga" preload="true"/>
- <texture name="spin_up_in_blue.tga" preload="true"/>
- <texture name="spin_up_out_blue.tga" preload="true"/>
-
- <texture name="square_btn_32x128.tga" preload="true" scale_left="8" scale_top="10" scale_right="120" scale_bottom="10"/>
- <texture name="square_btn_selected_32x128.tga" preload="true" scale_left="2" scale_top="10" scale_right="126" scale_bottom="10"/>
-
- <texture name="tab_bottom_blue.tga" preload="true" scale_left="8" scale_top="8" scale_right="120" scale_bottom="9"/>
- <texture name="tab_bottom_selected_blue.tga" preload="true" scale_left="8" scale_top="8" scale_right="96" scale_bottom="9"/>
- <texture name="tab_left.tga" preload="true" scale_left="8" scale_top="8" scale_right="120" scale_bottom="9"/>
- <texture name="tab_left_selected.tga" preload="true" scale_left="8" scale_top="8" scale_right="96" scale_bottom="9"/>
- <texture name="tab_top_blue.tga" preload="true" scale_left="8" scale_top="8" scale_right="120" scale_bottom="9"/>
- <texture name="tab_top_selected_blue.tga" preload="true" scale_left="8" scale_top="8" scale_right="96" scale_bottom="9"/>
-
+
+ <texture name="sm_rounded_corners_simple.tga" scale.left="4" scale.top="4" scale.bottom="4" scale.right="4"/>
+
+ <texture name="rounded_square.tga" file_name="rounded_square.j2c" preload="true" scale.left="16" scale.top="16" scale.right="112" scale.bottom="16" />
+
+ <texture name="rounded_square_soft.tga" file_name="rounded_square_soft.j2c" preload="true" scale.left="16" scale.top="16" scale.right="112" scale.bottom="16"/>
+
+ <texture name="toolbar_tab.tga" preload="true" scale.left="6" scale.top="42" scale.right="104" scale.bottom="8"/>
+ <texture name="toolbar_bg.tga" preload="true" scale.left="6" scale.top="42" scale.right="96" scale.bottom="16"/>
+
+ <texture name="tab_top_blue.tga" preload="false" scale.left="8" scale.top="8" scale.right="120" scale.bottom="9"/>
+ <texture name="tab_top_selected_blue.tga" preload="false" scale.left="8" scale.top="8" scale.right="96" scale.bottom="9"/>
+
<texture name="startup_logo.j2c" preload="true"/>
<texture name="color_swatch_alpha.tga" preload="true"/>
@@ -96,6 +381,7 @@
<texture name="icon_groupnoticeinventory.tga"/>
<texture name="icon_lock.tga"/>
<texture name="icon_place.tga"/>
+ <texture name="icon_place_for_sale.tga"/>
<texture name="icon_popular.tga"/>
<texture name="icon_top_pick.tga"/>
@@ -103,18 +389,21 @@
<texture name="inv_folder_bodypart.tga"/>
<texture name="inv_folder_callingcard.tga"/>
<texture name="inv_folder_clothing.tga"/>
+ <texture name="inv_folder_current_outfit.tga"/>
<texture name="inv_folder_gesture.tga"/>
<texture name="inv_folder_landmark.tga"/>
<texture name="inv_folder_lostandfound.tga"/>
+ <texture name="inv_folder_my_outfits.tga"/>
<texture name="inv_folder_notecard.tga"/>
<texture name="inv_folder_object.tga"/>
+ <texture name="inv_folder_outfit.tga"/>
<texture name="inv_folder_plain_closed.tga"/>
<texture name="inv_folder_script.tga"/>
<texture name="inv_folder_snapshot.tga"/>
<texture name="inv_folder_sound.tga"/>
<texture name="inv_folder_texture.tga"/>
<texture name="inv_folder_trash.tga"/>
-
+
<texture name="inv_item_animation.tga"/>
<texture name="inv_item_skin.tga"/>
<texture name="inv_item_callingcard_offline.tga"/>
@@ -126,6 +415,8 @@
<texture name="inv_item_jacket.tga"/>
<texture name="inv_item_landmark.tga"/>
<texture name="inv_item_landmark_visited.tga"/>
+ <texture name="inv_item_linkitem.tga"/>
+ <texture name="inv_item_linkfolder.tga"/>
<texture name="inv_item_notecard.tga"/>
<texture name="inv_item_object.tga"/>
<texture name="inv_item_object_multi.tga"/>
@@ -141,13 +432,13 @@
<texture name="inv_item_texture.tga"/>
<texture name="inv_item_underpants.tga"/>
<texture name="inv_item_undershirt.tga"/>
-
+
<texture name="lag_status_critical.tga"/>
<texture name="lag_status_good.tga"/>
<texture name="lag_status_warning.tga"/>
-
+
<texture name="legend.tga"/>
-
+
<texture name="map_avatar_16.tga"/>
<texture name="map_avatar_8.tga"/>
<texture name="map_avatar_you_8.tga"/>
@@ -157,17 +448,17 @@
<texture name="map_infohub.tga"/>
<texture name="map_telehub.tga"/>
<texture name="map_track_16.tga"/>
-
+
<texture name="media_icon.tga" file_name="icn_label_media.tga" />
<texture name="music_icon.tga" file_name="icn_label_music.tga" />
- <texture name="noentrylines.j2c" use_mips="true"/>
- <texture name="noentrypasslines.j2c" use_mips="true"/>
-
+ <texture name="NoEntryLines" file_name="world/NoEntryLines.png" use_mips="true" preload="false" />
+ <texture name="NoEntryPassLines" file_name="world/NoEntryPassLines.png" use_mips="true" preload="false" />
+
<texture name="notify_tip_icon.tga"/>
<texture name="notify_caution_icon.tga"/>
<texture name="notify_next.png" preload="true"/>
<texture name="notify_box_icon.tga"/>
-
+
<texture name="object_cone.tga"/>
<texture name="object_cone_active.tga"/>
<texture name="object_cube.tga"/>
@@ -198,11 +489,11 @@
<texture name="object_tree_active.tga"/>
<texture name="object_tube.tga"/>
<texture name="object_tube_active.tga"/>
-
+
<texture name="pixiesmall.j2c" use_mips="true"/>
<texture name="script_error.j2c" use_mips="true"/>
<texture name="silhouette.j2c" use_mips="true"/>
-
+
<texture name="status_no_build.tga"/>
<texture name="status_voice.tga"/>
<texture name="status_buy_currency.tga"/>
@@ -213,7 +504,7 @@
<texture name="status_health.tga"/>
<texture name="status_no_push.tga"/>
<texture name="status_no_scripts.tga"/>
-
+
<texture name="tool_dozer.tga"/>
<texture name="tool_dozer_active.tga"/>
<texture name="tool_zoom.tga"/>
@@ -225,7 +516,7 @@
<texture name="icn_active-speakers-typing1.tga"/>
<texture name="icn_active-speakers-typing2.tga"/>
<texture name="icn_active-speakers-typing3.tga"/>
-
+
<texture name="icn_voice_ptt-off.tga"/>
<texture name="icn_voice_ptt-on.tga"/>
<texture name="icn_voice_ptt-on-lvl1.tga"/>
@@ -233,144 +524,30 @@
<texture name="icn_voice_ptt-on-lvl3.tga"/>
<texture name="icn_voice-call-end.tga"/>
<texture name="icn_voice-call-start.tga"/>
-
- <texture name="mute_icon.tga"/>
-
- <texture name="icn_slide-groove_dark.tga" scale_left="2" scale_top="5" scale_right="29" scale_bottom="4"/>
- <texture name="icn_slide-highlight.tga" scale_left="2" scale_top="5" scale_right="29" scale_bottom="4"/>
- <texture name="icn_slide-thumb_dark.tga" scale_left="2" scale_top="5" scale_right="29" scale_bottom="4"/>
-
- <texture name="icn_speaker-muted_dark.tga"/>
- <texture name="icn_speaker_dark.tga"/>
- <texture name="icn_voice-localchat.tga"/>
- <texture name="icn_voice-groupfocus.tga"/>
- <texture name="icn_voice-pvtfocus.tga"/>
-
- <texture name="icn_media-pause.tga"/>
- <texture name="icn_media-play.tga"/>
- <texture name="icn_music-play.tga"/>
- <texture name="icn_music-pause.tga"/>
- <texture name="icn_media_web.tga" preload="true"/>
- <texture name="icn_media_movie.tga" preload="true"/>
-
- <texture name="icn_chatbar.tga"/>
- <texture name="btn_chatbar.tga" scale_left="20" scale_top="24" scale_right="44" scale_bottom="0"/>
- <texture name="btn_chatbar_selected.tga" scale_left="20" scale_top="24" scale_right="44" scale_bottom="0"/>
-
- <texture name="icn_rounded-text-field.tga"/>
+ <texture name="mute_icon.tga"/>
- <texture name="flyout_btn_right_selected.tga" scale_left="0" scale_top="30" scale_right="32" scale_bottom="0"/>
-
- <texture name="flyout_btn_right.tga" scale_left="0" scale_top="30" scale_right="32" scale_bottom="0"/>
-
- <texture name="flyout_btn_right_disabled.tga" scale_left="0" scale_top="30" scale_right="32" scale_bottom="0"/>
-
- <texture name="flyout_btn_left_selected.tga" scale_left="16" scale_top="15" scale_right="112" scale_bottom="15"/>
-
- <texture name="flyout_btn_left.tga" scale_left="16" scale_top="15" scale_right="112" scale_bottom="15"/>
-
- <texture name="flyout_btn_left_disabled.tga" scale_left="16" scale_top="15" scale_right="112" scale_bottom="15"/>
-
- <texture name="UIImgResizeBottomRightUUID" file_name="resize_handle_bottom_right_blue.tga"/>
-
- <texture name="UIImgBtnForwardOutUUID" file_name="move_forward_out.tga" preload="true"/>
- <texture name="UIImgBtnForwardInUUID" file_name="move_forward_in.tga" preload="true"/>
- <texture name="UIImgBtnSlideLeftOutUUID" file_name="move_left_out.tga" preload="true"/>
- <texture name="UIImgBtnSlideLeftInUUID" file_name="move_left_in.tga" preload="true"/>
- <texture name="UIImgBtnLeftOutUUID" file_name="move_turn_left_out.tga" preload="true"/>
- <texture name="UIImgBtnLeftInUUID" file_name="move_turn_left_in.tga" preload="true"/>
- <texture name="UIImgBtnRightOutUUID" file_name="move_turn_right_out.tga" preload="true"/>
- <texture name="UIImgBtnRightInUUID" file_name="move_turn_right_in.tga" preload="true"/>
- <texture name="UIImgBtnSlideRightOutUUID" file_name="move_right_out.tga" preload="true"/>
- <texture name="UIImgBtnSlideRightInUUID" file_name="move_right_in.tga" preload="true"/>
- <texture name="UIImgBtnMoveUpInUUID" file_name="move_up_in.tga" preload="true"/>
- <texture name="UIImgBtnMoveUpOutUUID" file_name="move_up_out.tga" preload="true"/>
- <texture name="UIImgBtnMoveDownInUUID" file_name="move_down_in.tga" preload="true"/>
- <texture name="UIImgBtnMoveDownOutUUID" file_name="move_down_out.tga" preload="true"/>
-
- <texture name="cam_rotate_out.tga" preload="true"/>
- <texture name="cam_rotate_in.tga" preload="true"/>
- <texture name="cam_zoom_out.tga" preload="true"/>
- <texture name="cam_zoom_plus_in.tga" preload="true"/>
- <texture name="cam_zoom_minus_in.tga" preload="true"/>
-
- <texture name="UIImgBtnScrollUpOutUUID" file_name="scrollbutton_up_out_blue.tga"/>
- <texture name="UIImgBtnScrollUpInUUID" file_name="scrollbutton_up_in_blue.tga"/>
- <texture name="UIImgBtnScrollDownOutUUID" file_name="scrollbutton_down_out_blue.tga"/>
- <texture name="UIImgBtnScrollDownInUUID" file_name="scrollbutton_down_in_blue.tga"/>
- <texture name="UIImgBtnScrollLeftOutUUID" file_name="scrollbutton_left_out_blue.tga"/>
- <texture name="UIImgBtnScrollLeftInUUID" file_name="scrollbutton_left_in_blue.tga"/>
- <texture name="UIImgBtnScrollRightOutUUID" file_name="scrollbutton_right_out_blue.tga"/>
- <texture name="UIImgBtnScrollRightInUUID" file_name="scrollbutton_right_in_blue.tga"/>
-
- <texture name="UIImgBtnJumpLeftOutUUID" file_name="3c18c87e-5f50-14e2-e744-f44734aa365f.tga"/>
- <texture name="UIImgBtnJumpLeftInUUID" file_name="9cad3e6d-2d6d-107d-f8ab-5ba272b5bfe1.tga"/>
- <texture name="UIImgBtnJumpRightOutUUID" file_name="ff9a71eb-7414-4cf8-866e-a701deb7c3cf.tga"/>
- <texture name="UIImgBtnJumpRightInUUID" file_name="7dabc040-ec13-2309-ddf7-4f161f6de2f4.tga"/>
-
- <texture name="UIImgBtnSpinUpOutUUID" file_name="spin_up_out_blue.tga"/>
- <texture name="UIImgBtnSpinUpInUUID" file_name="spin_up_in_blue.tga"/>
- <texture name="UIImgBtnSpinDownOutUUID" file_name="spin_down_out_blue.tga"/>
- <texture name="UIImgBtnSpinDownInUUID" file_name="spin_down_in_blue.tga"/>
-
- <texture name="UIImgRadioActiveUUID" file_name="radio_active_false.tga"/>
- <texture name="UIImgRadioActiveSelectedUUID" file_name="radio_active_true.tga"/>
- <texture name="UIImgRadioInactiveUUID" file_name="radio_inactive_false.tga"/>
- <texture name="UIImgRadioInactiveSelectedUUID" file_name="radio_inactive_true.tga"/>
-
- <texture name="UIImgCheckboxActiveUUID" file_name="checkbox_enabled_false.tga"/>
- <texture name="UIImgCheckboxActiveSelectedUUID" file_name="checkbox_enabled_true.tga"/>
- <texture name="UIImgCheckboxInactiveUUID" file_name="checkbox_disabled_false.tga"/>
- <texture name="UIImgCheckboxInactiveSelectedUUID" file_name="checkbox_disabled_true.tga"/>
-
- <texture name="UIImgBtnTabTopOutUUID" file_name="tab_top_blue.tga"/>
- <texture name="UIImgBtnTabTopInUUID" file_name="tab_top_selected_blue.tga"/>
- <texture name="UIImgBtnTabBottomOutUUID" file_name="tab_bottom_blue.tga"/>
- <texture name="UIImgBtnTabBottomInUUID" file_name="tab_bottom_selected_blue.tga"/>
-
- <texture name="UIImgGrabUUID" file_name="c63f124c-6340-4fbf-b59e-0869a44adb64.tga"/>
- <texture name="UIImgGrabSelectedUUID" file_name="c1e21504-f136-451d-b8e9-929037812f1d.tga"/>
-
- <!--<texture name="UIImgScaleUUID" file_name="88a90fef-b448-4883-9344-ecf378a60433.tga"/>-->
-
- <texture name="UIImgFaceUUID" file_name="ce15fd63-b0b6-463c-a37d-ea6393208b3e.tga"/>
- <texture name="UIImgFaceSelectedUUID" file_name="b4870163-6208-42a9-9801-93133bf9a6cd.tga"/>
-
- <texture name="UIImgCreateUUID" file_name="7a0b1bdb-b5d9-4df5-bac2-ba230da93b5b.tga"/>
- <texture name="UIImgCreateSelectedUUID" file_name="0098b015-3daf-4cfe-a72f-915369ea97c2.tga"/>
-
- <texture name="UIImgBtnCloseInactiveUUID" file_name="close_inactive_blue.tga"/>
- <texture name="UIImgBtnCloseActiveUUID" file_name="closebox.tga"/>
- <texture name="UIImgBtnClosePressedUUID" file_name="close_in_blue.tga"/>
- <texture name="icn_clear_lineeditor.tga" />
+ <texture name="default_land_picture.j2c"/>
+ <texture name="default_profile_picture.j2c"/>
+ <texture name="locked_image.j2c"/>
- <texture name="up_arrow.tga" file_name="up_arrow.png"/>
- <texture name="down_arrow.tga" file_name="down_arrow.png"/>
+ <texture name="media_btn_back.png"/>
+ <texture name="media_btn_done.png"/>
+ <texture name="media_btn_forward.png"/>
+ <texture name="media_btn_home.png"/>
+ <texture name="media_btn_newwindow.png"/>
+ <texture name="media_btn_optimalzoom.png"/>
+ <texture name="media_btn_reload.png"/>
+ <texture name="media_btn_scrolldown.png"/>
+ <texture name="media_btn_scrollleft.png"/>
+ <texture name="media_btn_scrollright.png"/>
+ <texture name="media_btn_scrollup.png"/>
+ <texture name="media_btn_stoploading.png"/>
+ <texture name="media_panel_divider.png"/>
+ <texture name="media_floater_border_16.png" scale_top="12" scale_left="4" scale_bottom="4" scale_right="12"/>
- <texture name="UIImgBtnMinimizeInactiveUUID" file_name="minimize_inactive.tga"/>
- <texture name="UIImgBtnMinimizeActiveUUID" file_name="minimize.tga"/>
- <texture name="UIImgBtnMinimizePressedUUID" file_name="minimize_pressed.tga"/>
+ <texture name="media_panel_bg.png" preload="true" scale_left="9" scale_top="9" scale_right="9" scale_bottom="9" />
+ <texture name="media_panel_hoverrectangle.png" preload="true" scale_left="9" scale_top="9" scale_right="9" scale_bottom="9" />
- <texture name="UIImgBtnRestoreInactiveUUID" file_name="restore_inactive.tga"/>
- <texture name="UIImgBtnRestoreActiveUUID" file_name="restore.tga"/>
- <texture name="UIImgBtnRestorePressedUUID" file_name="restore_pressed.tga"/>
-
- <texture name="UIImgBtnTearOffInactiveUUID" file_name="tearoffbox.tga"/>
- <texture name="UIImgBtnTearOffActiveUUID" file_name="tearoffbox.tga"/>
- <texture name="UIImgBtnTearOffPressedUUID" file_name="tearoff_pressed.tga"/>
-
- <texture name="UIImgCrosshairsUUID" file_name="crosshairs.tga"/>
- <texture name="icn_label_music.tga"/>
- <texture name="icn_label_media.tga"/>
- <texture name="arrow_down.tga"/>
- <texture name="cloud-particle.j2c" use_mips="true"/>
-
- <texture name="skin_thumbnail_default.png" preload="true" />
- <texture name="skin_thumbnail_silver.png" preload="true" />
-
- <texture name="default_land_picture.j2c"/>
- <texture name="default_profile_picture.j2c"/>
- <texture name="locked_image.j2c"/>
</textures>
diff --git a/indra/newview/skins/default/textures/transparent.j2c b/indra/newview/skins/default/textures/transparent.j2c
new file mode 100644
index 0000000000..1068e940b9
--- /dev/null
+++ b/indra/newview/skins/default/textures/transparent.j2c
Binary files differ
diff --git a/indra/newview/skins/default/textures/voice_meter_dot.j2c b/indra/newview/skins/default/textures/voice_meter_dot.j2c
new file mode 100644
index 0000000000..e536c3338a
--- /dev/null
+++ b/indra/newview/skins/default/textures/voice_meter_dot.j2c
Binary files differ
diff --git a/indra/newview/skins/default/textures/voice_meter_rings.j2c b/indra/newview/skins/default/textures/voice_meter_rings.j2c
new file mode 100644
index 0000000000..17e7c6c6a1
--- /dev/null
+++ b/indra/newview/skins/default/textures/voice_meter_rings.j2c
Binary files differ
diff --git a/indra/newview/skins/default/textures/widgets/Arrow_Down.png b/indra/newview/skins/default/textures/widgets/Arrow_Down.png
new file mode 100644
index 0000000000..e10f6472eb
--- /dev/null
+++ b/indra/newview/skins/default/textures/widgets/Arrow_Down.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/widgets/Arrow_Up.png b/indra/newview/skins/default/textures/widgets/Arrow_Up.png
new file mode 100644
index 0000000000..48df69d82e
--- /dev/null
+++ b/indra/newview/skins/default/textures/widgets/Arrow_Up.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/widgets/Checkbox_Disabled.png b/indra/newview/skins/default/textures/widgets/Checkbox_Disabled.png
new file mode 100644
index 0000000000..c1ee210099
--- /dev/null
+++ b/indra/newview/skins/default/textures/widgets/Checkbox_Disabled.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/widgets/Checkbox_Off.png b/indra/newview/skins/default/textures/widgets/Checkbox_Off.png
new file mode 100644
index 0000000000..2525405f37
--- /dev/null
+++ b/indra/newview/skins/default/textures/widgets/Checkbox_Off.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/widgets/Checkbox_On.png b/indra/newview/skins/default/textures/widgets/Checkbox_On.png
new file mode 100644
index 0000000000..2d9dba1592
--- /dev/null
+++ b/indra/newview/skins/default/textures/widgets/Checkbox_On.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/widgets/Checkbox_On_Disabled.png b/indra/newview/skins/default/textures/widgets/Checkbox_On_Disabled.png
new file mode 100644
index 0000000000..beaa7bcbf6
--- /dev/null
+++ b/indra/newview/skins/default/textures/widgets/Checkbox_On_Disabled.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/widgets/Checkbox_On_Over.png b/indra/newview/skins/default/textures/widgets/Checkbox_On_Over.png
new file mode 100644
index 0000000000..bc504d130e
--- /dev/null
+++ b/indra/newview/skins/default/textures/widgets/Checkbox_On_Over.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/widgets/Checkbox_On_Press.png b/indra/newview/skins/default/textures/widgets/Checkbox_On_Press.png
new file mode 100644
index 0000000000..5bced95a89
--- /dev/null
+++ b/indra/newview/skins/default/textures/widgets/Checkbox_On_Press.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/widgets/Checkbox_Over.png b/indra/newview/skins/default/textures/widgets/Checkbox_Over.png
new file mode 100644
index 0000000000..5a7162addf
--- /dev/null
+++ b/indra/newview/skins/default/textures/widgets/Checkbox_Over.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/widgets/Checkbox_Press.png b/indra/newview/skins/default/textures/widgets/Checkbox_Press.png
new file mode 100644
index 0000000000..44be193678
--- /dev/null
+++ b/indra/newview/skins/default/textures/widgets/Checkbox_Press.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/widgets/ComboButton_Disabled.png b/indra/newview/skins/default/textures/widgets/ComboButton_Disabled.png
new file mode 100644
index 0000000000..d0fff1b3c3
--- /dev/null
+++ b/indra/newview/skins/default/textures/widgets/ComboButton_Disabled.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/widgets/ComboButton_Off.png b/indra/newview/skins/default/textures/widgets/ComboButton_Off.png
new file mode 100644
index 0000000000..80402458b7
--- /dev/null
+++ b/indra/newview/skins/default/textures/widgets/ComboButton_Off.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/widgets/ComboButton_On.png b/indra/newview/skins/default/textures/widgets/ComboButton_On.png
new file mode 100644
index 0000000000..b42cc7542e
--- /dev/null
+++ b/indra/newview/skins/default/textures/widgets/ComboButton_On.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/widgets/ComboButton_Selected.png b/indra/newview/skins/default/textures/widgets/ComboButton_Selected.png
new file mode 100644
index 0000000000..bbc0657487
--- /dev/null
+++ b/indra/newview/skins/default/textures/widgets/ComboButton_Selected.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/widgets/DisclosureArrow_Closed_Over.png b/indra/newview/skins/default/textures/widgets/DisclosureArrow_Closed_Over.png
new file mode 100644
index 0000000000..45bcb0464e
--- /dev/null
+++ b/indra/newview/skins/default/textures/widgets/DisclosureArrow_Closed_Over.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/widgets/DisclosureArrow_Opened_Off.png b/indra/newview/skins/default/textures/widgets/DisclosureArrow_Opened_Off.png
new file mode 100644
index 0000000000..75057938d2
--- /dev/null
+++ b/indra/newview/skins/default/textures/widgets/DisclosureArrow_Opened_Off.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/widgets/DisclosureArrow_Opened_Over.png b/indra/newview/skins/default/textures/widgets/DisclosureArrow_Opened_Over.png
new file mode 100644
index 0000000000..dabbd85b34
--- /dev/null
+++ b/indra/newview/skins/default/textures/widgets/DisclosureArrow_Opened_Over.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/widgets/DropDown_Disabled.png b/indra/newview/skins/default/textures/widgets/DropDown_Disabled.png
new file mode 100644
index 0000000000..b295752ea9
--- /dev/null
+++ b/indra/newview/skins/default/textures/widgets/DropDown_Disabled.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/widgets/DropDown_Off.png b/indra/newview/skins/default/textures/widgets/DropDown_Off.png
new file mode 100644
index 0000000000..4764ed4ee2
--- /dev/null
+++ b/indra/newview/skins/default/textures/widgets/DropDown_Off.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/widgets/DropDown_On.png b/indra/newview/skins/default/textures/widgets/DropDown_On.png
new file mode 100644
index 0000000000..10262d3979
--- /dev/null
+++ b/indra/newview/skins/default/textures/widgets/DropDown_On.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/widgets/DropDown_Press.png b/indra/newview/skins/default/textures/widgets/DropDown_Press.png
new file mode 100644
index 0000000000..16cb25cc77
--- /dev/null
+++ b/indra/newview/skins/default/textures/widgets/DropDown_Press.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/widgets/ListItem_Over.png b/indra/newview/skins/default/textures/widgets/ListItem_Over.png
new file mode 100644
index 0000000000..4b2b9ab3e5
--- /dev/null
+++ b/indra/newview/skins/default/textures/widgets/ListItem_Over.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/widgets/ListItem_Select.png b/indra/newview/skins/default/textures/widgets/ListItem_Select.png
new file mode 100644
index 0000000000..317c672441
--- /dev/null
+++ b/indra/newview/skins/default/textures/widgets/ListItem_Select.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/widgets/ProgressBar.png b/indra/newview/skins/default/textures/widgets/ProgressBar.png
new file mode 100644
index 0000000000..edf11ac1f5
--- /dev/null
+++ b/indra/newview/skins/default/textures/widgets/ProgressBar.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/widgets/ProgressTrack.png b/indra/newview/skins/default/textures/widgets/ProgressTrack.png
new file mode 100644
index 0000000000..bb6d9f4144
--- /dev/null
+++ b/indra/newview/skins/default/textures/widgets/ProgressTrack.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/widgets/PushButton_Disabled.png b/indra/newview/skins/default/textures/widgets/PushButton_Disabled.png
new file mode 100644
index 0000000000..04e91bdaab
--- /dev/null
+++ b/indra/newview/skins/default/textures/widgets/PushButton_Disabled.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/widgets/PushButton_Off.png b/indra/newview/skins/default/textures/widgets/PushButton_Off.png
new file mode 100644
index 0000000000..1ee0329e66
--- /dev/null
+++ b/indra/newview/skins/default/textures/widgets/PushButton_Off.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/widgets/PushButton_On.png b/indra/newview/skins/default/textures/widgets/PushButton_On.png
new file mode 100644
index 0000000000..661d1c5611
--- /dev/null
+++ b/indra/newview/skins/default/textures/widgets/PushButton_On.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/widgets/PushButton_On_Over.png b/indra/newview/skins/default/textures/widgets/PushButton_On_Over.png
new file mode 100644
index 0000000000..064a4c4f7f
--- /dev/null
+++ b/indra/newview/skins/default/textures/widgets/PushButton_On_Over.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/widgets/PushButton_On_Selected.png b/indra/newview/skins/default/textures/widgets/PushButton_On_Selected.png
new file mode 100644
index 0000000000..48e8aa2eab
--- /dev/null
+++ b/indra/newview/skins/default/textures/widgets/PushButton_On_Selected.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/widgets/PushButton_Over.png b/indra/newview/skins/default/textures/widgets/PushButton_Over.png
new file mode 100644
index 0000000000..c227f07513
--- /dev/null
+++ b/indra/newview/skins/default/textures/widgets/PushButton_Over.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/widgets/PushButton_Press.png b/indra/newview/skins/default/textures/widgets/PushButton_Press.png
new file mode 100644
index 0000000000..0a4a3a6ad9
--- /dev/null
+++ b/indra/newview/skins/default/textures/widgets/PushButton_Press.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/widgets/PushButton_Selected.png b/indra/newview/skins/default/textures/widgets/PushButton_Selected.png
new file mode 100644
index 0000000000..0a4a3a6ad9
--- /dev/null
+++ b/indra/newview/skins/default/textures/widgets/PushButton_Selected.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/widgets/PushButton_Selected_Disabled.png b/indra/newview/skins/default/textures/widgets/PushButton_Selected_Disabled.png
new file mode 100644
index 0000000000..661d1c5611
--- /dev/null
+++ b/indra/newview/skins/default/textures/widgets/PushButton_Selected_Disabled.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/widgets/PushButton_Selected_Over.png b/indra/newview/skins/default/textures/widgets/PushButton_Selected_Over.png
new file mode 100644
index 0000000000..064a4c4f7f
--- /dev/null
+++ b/indra/newview/skins/default/textures/widgets/PushButton_Selected_Over.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/widgets/PushButton_Selected_Press.png b/indra/newview/skins/default/textures/widgets/PushButton_Selected_Press.png
new file mode 100644
index 0000000000..48e8aa2eab
--- /dev/null
+++ b/indra/newview/skins/default/textures/widgets/PushButton_Selected_Press.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/widgets/RadioButton_Disabled.png b/indra/newview/skins/default/textures/widgets/RadioButton_Disabled.png
new file mode 100644
index 0000000000..a1052684b9
--- /dev/null
+++ b/indra/newview/skins/default/textures/widgets/RadioButton_Disabled.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/widgets/RadioButton_Off.png b/indra/newview/skins/default/textures/widgets/RadioButton_Off.png
new file mode 100644
index 0000000000..c58e0305ef
--- /dev/null
+++ b/indra/newview/skins/default/textures/widgets/RadioButton_Off.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/widgets/RadioButton_On.png b/indra/newview/skins/default/textures/widgets/RadioButton_On.png
new file mode 100644
index 0000000000..c09a2197c7
--- /dev/null
+++ b/indra/newview/skins/default/textures/widgets/RadioButton_On.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/widgets/RadioButton_On_Disabled.png b/indra/newview/skins/default/textures/widgets/RadioButton_On_Disabled.png
new file mode 100644
index 0000000000..d7d444fd0c
--- /dev/null
+++ b/indra/newview/skins/default/textures/widgets/RadioButton_On_Disabled.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/widgets/RadioButton_On_Over.png b/indra/newview/skins/default/textures/widgets/RadioButton_On_Over.png
new file mode 100644
index 0000000000..3e7d803a28
--- /dev/null
+++ b/indra/newview/skins/default/textures/widgets/RadioButton_On_Over.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/widgets/RadioButton_On_Press.png b/indra/newview/skins/default/textures/widgets/RadioButton_On_Press.png
new file mode 100644
index 0000000000..a707e8ceb8
--- /dev/null
+++ b/indra/newview/skins/default/textures/widgets/RadioButton_On_Press.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/widgets/RadioButton_Over.png b/indra/newview/skins/default/textures/widgets/RadioButton_Over.png
new file mode 100644
index 0000000000..a5c8cbe293
--- /dev/null
+++ b/indra/newview/skins/default/textures/widgets/RadioButton_Over.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/widgets/RadioButton_Press.png b/indra/newview/skins/default/textures/widgets/RadioButton_Press.png
new file mode 100644
index 0000000000..33eaa14030
--- /dev/null
+++ b/indra/newview/skins/default/textures/widgets/RadioButton_Press.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/widgets/ScrollArrow_Down.png b/indra/newview/skins/default/textures/widgets/ScrollArrow_Down.png
new file mode 100644
index 0000000000..186822da43
--- /dev/null
+++ b/indra/newview/skins/default/textures/widgets/ScrollArrow_Down.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/widgets/ScrollArrow_Down_Over.png b/indra/newview/skins/default/textures/widgets/ScrollArrow_Down_Over.png
new file mode 100644
index 0000000000..605d159eaa
--- /dev/null
+++ b/indra/newview/skins/default/textures/widgets/ScrollArrow_Down_Over.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/widgets/ScrollArrow_Left.png b/indra/newview/skins/default/textures/widgets/ScrollArrow_Left.png
new file mode 100644
index 0000000000..42f999a451
--- /dev/null
+++ b/indra/newview/skins/default/textures/widgets/ScrollArrow_Left.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/widgets/ScrollArrow_Left_Over.png b/indra/newview/skins/default/textures/widgets/ScrollArrow_Left_Over.png
new file mode 100644
index 0000000000..c79547dffd
--- /dev/null
+++ b/indra/newview/skins/default/textures/widgets/ScrollArrow_Left_Over.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/widgets/ScrollArrow_Right.png b/indra/newview/skins/default/textures/widgets/ScrollArrow_Right.png
new file mode 100644
index 0000000000..176ffcdbb9
--- /dev/null
+++ b/indra/newview/skins/default/textures/widgets/ScrollArrow_Right.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/widgets/ScrollArrow_Right_Over.png b/indra/newview/skins/default/textures/widgets/ScrollArrow_Right_Over.png
new file mode 100644
index 0000000000..e353542ad9
--- /dev/null
+++ b/indra/newview/skins/default/textures/widgets/ScrollArrow_Right_Over.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/widgets/ScrollArrow_Up.png b/indra/newview/skins/default/textures/widgets/ScrollArrow_Up.png
new file mode 100644
index 0000000000..4d245eb57a
--- /dev/null
+++ b/indra/newview/skins/default/textures/widgets/ScrollArrow_Up.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/widgets/ScrollArrow_Up_Over.png b/indra/newview/skins/default/textures/widgets/ScrollArrow_Up_Over.png
new file mode 100644
index 0000000000..dd2fceb716
--- /dev/null
+++ b/indra/newview/skins/default/textures/widgets/ScrollArrow_Up_Over.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/widgets/ScrollThumb_Horiz.png b/indra/newview/skins/default/textures/widgets/ScrollThumb_Horiz.png
new file mode 100644
index 0000000000..8a085aa966
--- /dev/null
+++ b/indra/newview/skins/default/textures/widgets/ScrollThumb_Horiz.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/widgets/ScrollThumb_Horiz_Over.png b/indra/newview/skins/default/textures/widgets/ScrollThumb_Horiz_Over.png
new file mode 100644
index 0000000000..cf78ea3924
--- /dev/null
+++ b/indra/newview/skins/default/textures/widgets/ScrollThumb_Horiz_Over.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/widgets/ScrollThumb_Vert.png b/indra/newview/skins/default/textures/widgets/ScrollThumb_Vert.png
new file mode 100644
index 0000000000..fc7fd93e7a
--- /dev/null
+++ b/indra/newview/skins/default/textures/widgets/ScrollThumb_Vert.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/widgets/ScrollThumb_Vert_Over.png b/indra/newview/skins/default/textures/widgets/ScrollThumb_Vert_Over.png
new file mode 100644
index 0000000000..53587197da
--- /dev/null
+++ b/indra/newview/skins/default/textures/widgets/ScrollThumb_Vert_Over.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/widgets/ScrollTrack_Horiz.png b/indra/newview/skins/default/textures/widgets/ScrollTrack_Horiz.png
new file mode 100644
index 0000000000..4f31c48c02
--- /dev/null
+++ b/indra/newview/skins/default/textures/widgets/ScrollTrack_Horiz.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/widgets/ScrollTrack_Vert.png b/indra/newview/skins/default/textures/widgets/ScrollTrack_Vert.png
new file mode 100644
index 0000000000..f89ee3f68f
--- /dev/null
+++ b/indra/newview/skins/default/textures/widgets/ScrollTrack_Vert.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/widgets/SegmentedBtn_Left_Disabled.png b/indra/newview/skins/default/textures/widgets/SegmentedBtn_Left_Disabled.png
new file mode 100644
index 0000000000..3b39c51a77
--- /dev/null
+++ b/indra/newview/skins/default/textures/widgets/SegmentedBtn_Left_Disabled.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/widgets/SegmentedBtn_Left_Off.png b/indra/newview/skins/default/textures/widgets/SegmentedBtn_Left_Off.png
new file mode 100644
index 0000000000..57ed79d733
--- /dev/null
+++ b/indra/newview/skins/default/textures/widgets/SegmentedBtn_Left_Off.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/widgets/SegmentedBtn_Left_On.png b/indra/newview/skins/default/textures/widgets/SegmentedBtn_Left_On.png
new file mode 100644
index 0000000000..7afb9c99c3
--- /dev/null
+++ b/indra/newview/skins/default/textures/widgets/SegmentedBtn_Left_On.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/widgets/SegmentedBtn_Left_On_Disabled.png b/indra/newview/skins/default/textures/widgets/SegmentedBtn_Left_On_Disabled.png
new file mode 100644
index 0000000000..77c4224539
--- /dev/null
+++ b/indra/newview/skins/default/textures/widgets/SegmentedBtn_Left_On_Disabled.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/widgets/SegmentedBtn_Left_On_Over.png b/indra/newview/skins/default/textures/widgets/SegmentedBtn_Left_On_Over.png
new file mode 100644
index 0000000000..8b93dd551e
--- /dev/null
+++ b/indra/newview/skins/default/textures/widgets/SegmentedBtn_Left_On_Over.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/widgets/SegmentedBtn_Left_On_Selected.png b/indra/newview/skins/default/textures/widgets/SegmentedBtn_Left_On_Selected.png
new file mode 100644
index 0000000000..3f207cbea2
--- /dev/null
+++ b/indra/newview/skins/default/textures/widgets/SegmentedBtn_Left_On_Selected.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/widgets/SegmentedBtn_Left_Over.png b/indra/newview/skins/default/textures/widgets/SegmentedBtn_Left_Over.png
new file mode 100644
index 0000000000..5b8878e0cb
--- /dev/null
+++ b/indra/newview/skins/default/textures/widgets/SegmentedBtn_Left_Over.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/widgets/SegmentedBtn_Left_Press.png b/indra/newview/skins/default/textures/widgets/SegmentedBtn_Left_Press.png
new file mode 100644
index 0000000000..379953216b
--- /dev/null
+++ b/indra/newview/skins/default/textures/widgets/SegmentedBtn_Left_Press.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/widgets/SegmentedBtn_Left_Selected.png b/indra/newview/skins/default/textures/widgets/SegmentedBtn_Left_Selected.png
new file mode 100644
index 0000000000..379953216b
--- /dev/null
+++ b/indra/newview/skins/default/textures/widgets/SegmentedBtn_Left_Selected.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/widgets/SegmentedBtn_Left_Selected_Disabled.png b/indra/newview/skins/default/textures/widgets/SegmentedBtn_Left_Selected_Disabled.png
new file mode 100644
index 0000000000..77c4224539
--- /dev/null
+++ b/indra/newview/skins/default/textures/widgets/SegmentedBtn_Left_Selected_Disabled.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/widgets/SegmentedBtn_Left_Selected_Over.png b/indra/newview/skins/default/textures/widgets/SegmentedBtn_Left_Selected_Over.png
new file mode 100644
index 0000000000..8b93dd551e
--- /dev/null
+++ b/indra/newview/skins/default/textures/widgets/SegmentedBtn_Left_Selected_Over.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/widgets/SegmentedBtn_Left_Selected_Press.png b/indra/newview/skins/default/textures/widgets/SegmentedBtn_Left_Selected_Press.png
new file mode 100644
index 0000000000..3f207cbea2
--- /dev/null
+++ b/indra/newview/skins/default/textures/widgets/SegmentedBtn_Left_Selected_Press.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/widgets/SegmentedBtn_Middle_Disabled.png b/indra/newview/skins/default/textures/widgets/SegmentedBtn_Middle_Disabled.png
new file mode 100644
index 0000000000..deb87c8489
--- /dev/null
+++ b/indra/newview/skins/default/textures/widgets/SegmentedBtn_Middle_Disabled.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/widgets/SegmentedBtn_Middle_On.png b/indra/newview/skins/default/textures/widgets/SegmentedBtn_Middle_On.png
new file mode 100644
index 0000000000..220df9db25
--- /dev/null
+++ b/indra/newview/skins/default/textures/widgets/SegmentedBtn_Middle_On.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/widgets/SegmentedBtn_Middle_On_Over.png b/indra/newview/skins/default/textures/widgets/SegmentedBtn_Middle_On_Over.png
new file mode 100644
index 0000000000..5bbcdcb0b4
--- /dev/null
+++ b/indra/newview/skins/default/textures/widgets/SegmentedBtn_Middle_On_Over.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/widgets/SegmentedBtn_Middle_On_Press.png b/indra/newview/skins/default/textures/widgets/SegmentedBtn_Middle_On_Press.png
new file mode 100644
index 0000000000..dde367f05e
--- /dev/null
+++ b/indra/newview/skins/default/textures/widgets/SegmentedBtn_Middle_On_Press.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/widgets/SegmentedBtn_Middle_Over.png b/indra/newview/skins/default/textures/widgets/SegmentedBtn_Middle_Over.png
new file mode 100644
index 0000000000..d4f30b9adb
--- /dev/null
+++ b/indra/newview/skins/default/textures/widgets/SegmentedBtn_Middle_Over.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/widgets/SegmentedBtn_Middle_Selected.png b/indra/newview/skins/default/textures/widgets/SegmentedBtn_Middle_Selected.png
new file mode 100644
index 0000000000..ca7027da91
--- /dev/null
+++ b/indra/newview/skins/default/textures/widgets/SegmentedBtn_Middle_Selected.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/widgets/SegmentedBtn_Middle_Selected_Disabled.png b/indra/newview/skins/default/textures/widgets/SegmentedBtn_Middle_Selected_Disabled.png
new file mode 100644
index 0000000000..220df9db25
--- /dev/null
+++ b/indra/newview/skins/default/textures/widgets/SegmentedBtn_Middle_Selected_Disabled.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/widgets/SegmentedBtn_Middle_Selected_Over.png b/indra/newview/skins/default/textures/widgets/SegmentedBtn_Middle_Selected_Over.png
new file mode 100644
index 0000000000..5bbcdcb0b4
--- /dev/null
+++ b/indra/newview/skins/default/textures/widgets/SegmentedBtn_Middle_Selected_Over.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/widgets/SegmentedBtn_Middle_Selected_Press.png b/indra/newview/skins/default/textures/widgets/SegmentedBtn_Middle_Selected_Press.png
new file mode 100644
index 0000000000..dde367f05e
--- /dev/null
+++ b/indra/newview/skins/default/textures/widgets/SegmentedBtn_Middle_Selected_Press.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/widgets/SegmentedBtn_Right_Disabled.png b/indra/newview/skins/default/textures/widgets/SegmentedBtn_Right_Disabled.png
new file mode 100644
index 0000000000..8e6b9c8c6f
--- /dev/null
+++ b/indra/newview/skins/default/textures/widgets/SegmentedBtn_Right_Disabled.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/widgets/SegmentedBtn_Right_Off.png b/indra/newview/skins/default/textures/widgets/SegmentedBtn_Right_Off.png
new file mode 100644
index 0000000000..b1521199ff
--- /dev/null
+++ b/indra/newview/skins/default/textures/widgets/SegmentedBtn_Right_Off.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/widgets/SegmentedBtn_Right_On.png b/indra/newview/skins/default/textures/widgets/SegmentedBtn_Right_On.png
new file mode 100644
index 0000000000..467c43fc90
--- /dev/null
+++ b/indra/newview/skins/default/textures/widgets/SegmentedBtn_Right_On.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/widgets/SegmentedBtn_Right_On_Over.png b/indra/newview/skins/default/textures/widgets/SegmentedBtn_Right_On_Over.png
new file mode 100644
index 0000000000..2049736897
--- /dev/null
+++ b/indra/newview/skins/default/textures/widgets/SegmentedBtn_Right_On_Over.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/widgets/SegmentedBtn_Right_On_Selected.png b/indra/newview/skins/default/textures/widgets/SegmentedBtn_Right_On_Selected.png
new file mode 100644
index 0000000000..1574f48b28
--- /dev/null
+++ b/indra/newview/skins/default/textures/widgets/SegmentedBtn_Right_On_Selected.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/widgets/SegmentedBtn_Right_Over.png b/indra/newview/skins/default/textures/widgets/SegmentedBtn_Right_Over.png
new file mode 100644
index 0000000000..2717e7d7b0
--- /dev/null
+++ b/indra/newview/skins/default/textures/widgets/SegmentedBtn_Right_Over.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/widgets/SegmentedBtn_Right_Press.png b/indra/newview/skins/default/textures/widgets/SegmentedBtn_Right_Press.png
new file mode 100644
index 0000000000..3883518033
--- /dev/null
+++ b/indra/newview/skins/default/textures/widgets/SegmentedBtn_Right_Press.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/widgets/SegmentedBtn_Right_Selected.png b/indra/newview/skins/default/textures/widgets/SegmentedBtn_Right_Selected.png
new file mode 100644
index 0000000000..3883518033
--- /dev/null
+++ b/indra/newview/skins/default/textures/widgets/SegmentedBtn_Right_Selected.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/widgets/SegmentedBtn_Right_Selected_Disabled.png b/indra/newview/skins/default/textures/widgets/SegmentedBtn_Right_Selected_Disabled.png
new file mode 100644
index 0000000000..ab31f6ded7
--- /dev/null
+++ b/indra/newview/skins/default/textures/widgets/SegmentedBtn_Right_Selected_Disabled.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/widgets/SegmentedBtn_Right_Selected_Over.png b/indra/newview/skins/default/textures/widgets/SegmentedBtn_Right_Selected_Over.png
new file mode 100644
index 0000000000..2049736897
--- /dev/null
+++ b/indra/newview/skins/default/textures/widgets/SegmentedBtn_Right_Selected_Over.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/widgets/SegmentedBtn_Right_Selected_Press.png b/indra/newview/skins/default/textures/widgets/SegmentedBtn_Right_Selected_Press.png
new file mode 100644
index 0000000000..1574f48b28
--- /dev/null
+++ b/indra/newview/skins/default/textures/widgets/SegmentedBtn_Right_Selected_Press.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/widgets/SliderThumb_Disabled.png b/indra/newview/skins/default/textures/widgets/SliderThumb_Disabled.png
new file mode 100644
index 0000000000..b627232012
--- /dev/null
+++ b/indra/newview/skins/default/textures/widgets/SliderThumb_Disabled.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/widgets/SliderThumb_Off.png b/indra/newview/skins/default/textures/widgets/SliderThumb_Off.png
new file mode 100644
index 0000000000..b627232012
--- /dev/null
+++ b/indra/newview/skins/default/textures/widgets/SliderThumb_Off.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/widgets/SliderThumb_Over.png b/indra/newview/skins/default/textures/widgets/SliderThumb_Over.png
new file mode 100644
index 0000000000..b6f900d3bd
--- /dev/null
+++ b/indra/newview/skins/default/textures/widgets/SliderThumb_Over.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/widgets/SliderThumb_Press.png b/indra/newview/skins/default/textures/widgets/SliderThumb_Press.png
new file mode 100644
index 0000000000..7081f9cfe0
--- /dev/null
+++ b/indra/newview/skins/default/textures/widgets/SliderThumb_Press.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/widgets/SliderTrack_Horiz.png b/indra/newview/skins/default/textures/widgets/SliderTrack_Horiz.png
new file mode 100644
index 0000000000..232006ee5a
--- /dev/null
+++ b/indra/newview/skins/default/textures/widgets/SliderTrack_Horiz.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/widgets/SliderTrack_Vert.png b/indra/newview/skins/default/textures/widgets/SliderTrack_Vert.png
new file mode 100644
index 0000000000..cd002b3973
--- /dev/null
+++ b/indra/newview/skins/default/textures/widgets/SliderTrack_Vert.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/widgets/Stepper_Down_Off.png b/indra/newview/skins/default/textures/widgets/Stepper_Down_Off.png
new file mode 100644
index 0000000000..cf0d8ee2c1
--- /dev/null
+++ b/indra/newview/skins/default/textures/widgets/Stepper_Down_Off.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/widgets/Stepper_Down_Over.png b/indra/newview/skins/default/textures/widgets/Stepper_Down_Over.png
new file mode 100644
index 0000000000..01e0a2d9f1
--- /dev/null
+++ b/indra/newview/skins/default/textures/widgets/Stepper_Down_Over.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/widgets/Stepper_Down_Press.png b/indra/newview/skins/default/textures/widgets/Stepper_Down_Press.png
new file mode 100644
index 0000000000..fe3a7beafd
--- /dev/null
+++ b/indra/newview/skins/default/textures/widgets/Stepper_Down_Press.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/widgets/Stepper_Up_Off.png b/indra/newview/skins/default/textures/widgets/Stepper_Up_Off.png
new file mode 100644
index 0000000000..133589b8a6
--- /dev/null
+++ b/indra/newview/skins/default/textures/widgets/Stepper_Up_Off.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/widgets/Stepper_Up_Over.png b/indra/newview/skins/default/textures/widgets/Stepper_Up_Over.png
new file mode 100644
index 0000000000..2ce84ea5be
--- /dev/null
+++ b/indra/newview/skins/default/textures/widgets/Stepper_Up_Over.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/widgets/Stepper_Up_Press.png b/indra/newview/skins/default/textures/widgets/Stepper_Up_Press.png
new file mode 100644
index 0000000000..e83babc519
--- /dev/null
+++ b/indra/newview/skins/default/textures/widgets/Stepper_Up_Press.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/widgets/TextField_Active.png b/indra/newview/skins/default/textures/widgets/TextField_Active.png
new file mode 100644
index 0000000000..ca6daab4e0
--- /dev/null
+++ b/indra/newview/skins/default/textures/widgets/TextField_Active.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/widgets/TextField_Disabled.png b/indra/newview/skins/default/textures/widgets/TextField_Disabled.png
new file mode 100644
index 0000000000..3d205a3f2e
--- /dev/null
+++ b/indra/newview/skins/default/textures/widgets/TextField_Disabled.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/widgets/TextField_Off.png b/indra/newview/skins/default/textures/widgets/TextField_Off.png
new file mode 100644
index 0000000000..911d907acc
--- /dev/null
+++ b/indra/newview/skins/default/textures/widgets/TextField_Off.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/widgets/TextField_Search_Active.png b/indra/newview/skins/default/textures/widgets/TextField_Search_Active.png
new file mode 100644
index 0000000000..fa79cb6260
--- /dev/null
+++ b/indra/newview/skins/default/textures/widgets/TextField_Search_Active.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/widgets/TextField_Search_Disabled.png b/indra/newview/skins/default/textures/widgets/TextField_Search_Disabled.png
new file mode 100644
index 0000000000..8b504af101
--- /dev/null
+++ b/indra/newview/skins/default/textures/widgets/TextField_Search_Disabled.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/widgets/TextField_Search_Off.png b/indra/newview/skins/default/textures/widgets/TextField_Search_Off.png
new file mode 100644
index 0000000000..862b13d219
--- /dev/null
+++ b/indra/newview/skins/default/textures/widgets/TextField_Search_Off.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/windows/Flyout.png b/indra/newview/skins/default/textures/windows/Flyout.png
new file mode 100644
index 0000000000..5596b194c9
--- /dev/null
+++ b/indra/newview/skins/default/textures/windows/Flyout.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/windows/Flyout_Pointer.png b/indra/newview/skins/default/textures/windows/Flyout_Pointer.png
new file mode 100644
index 0000000000..69fc08ceaa
--- /dev/null
+++ b/indra/newview/skins/default/textures/windows/Flyout_Pointer.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/windows/Icon_Close_Foreground.png b/indra/newview/skins/default/textures/windows/Icon_Close_Foreground.png
new file mode 100644
index 0000000000..5dd0852a72
--- /dev/null
+++ b/indra/newview/skins/default/textures/windows/Icon_Close_Foreground.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/windows/Icon_Close_Press.png b/indra/newview/skins/default/textures/windows/Icon_Close_Press.png
new file mode 100644
index 0000000000..ea547fca6f
--- /dev/null
+++ b/indra/newview/skins/default/textures/windows/Icon_Close_Press.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/windows/Icon_Close_Toast.png b/indra/newview/skins/default/textures/windows/Icon_Close_Toast.png
new file mode 100644
index 0000000000..ecf01c617a
--- /dev/null
+++ b/indra/newview/skins/default/textures/windows/Icon_Close_Toast.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/windows/Icon_Dock_Foreground.png b/indra/newview/skins/default/textures/windows/Icon_Dock_Foreground.png
new file mode 100644
index 0000000000..4207ba68e5
--- /dev/null
+++ b/indra/newview/skins/default/textures/windows/Icon_Dock_Foreground.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/windows/Icon_Dock_Press.png b/indra/newview/skins/default/textures/windows/Icon_Dock_Press.png
new file mode 100644
index 0000000000..2d09475783
--- /dev/null
+++ b/indra/newview/skins/default/textures/windows/Icon_Dock_Press.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/windows/Icon_Gear_Background.png b/indra/newview/skins/default/textures/windows/Icon_Gear_Background.png
new file mode 100644
index 0000000000..db74b93afd
--- /dev/null
+++ b/indra/newview/skins/default/textures/windows/Icon_Gear_Background.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/windows/Icon_Gear_Foreground.png b/indra/newview/skins/default/textures/windows/Icon_Gear_Foreground.png
new file mode 100644
index 0000000000..1032e45f7e
--- /dev/null
+++ b/indra/newview/skins/default/textures/windows/Icon_Gear_Foreground.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/windows/Icon_Gear_Over.png b/indra/newview/skins/default/textures/windows/Icon_Gear_Over.png
new file mode 100644
index 0000000000..01dbde102b
--- /dev/null
+++ b/indra/newview/skins/default/textures/windows/Icon_Gear_Over.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/windows/Icon_Gear_Press.png b/indra/newview/skins/default/textures/windows/Icon_Gear_Press.png
new file mode 100644
index 0000000000..6614bdd165
--- /dev/null
+++ b/indra/newview/skins/default/textures/windows/Icon_Gear_Press.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/windows/Icon_Undock_Foreground.png b/indra/newview/skins/default/textures/windows/Icon_Undock_Foreground.png
new file mode 100644
index 0000000000..9a71d16a3f
--- /dev/null
+++ b/indra/newview/skins/default/textures/windows/Icon_Undock_Foreground.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/windows/Icon_Undock_Press.png b/indra/newview/skins/default/textures/windows/Icon_Undock_Press.png
new file mode 100644
index 0000000000..3ab8c3666a
--- /dev/null
+++ b/indra/newview/skins/default/textures/windows/Icon_Undock_Press.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/windows/Resize_Corner.png b/indra/newview/skins/default/textures/windows/Resize_Corner.png
new file mode 100644
index 0000000000..16ed63e428
--- /dev/null
+++ b/indra/newview/skins/default/textures/windows/Resize_Corner.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/windows/Toast_CloseBtn.png b/indra/newview/skins/default/textures/windows/Toast_CloseBtn.png
new file mode 100644
index 0000000000..78b137cdaf
--- /dev/null
+++ b/indra/newview/skins/default/textures/windows/Toast_CloseBtn.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/windows/Toast_Over.png b/indra/newview/skins/default/textures/windows/Toast_Over.png
new file mode 100644
index 0000000000..807e8e553c
--- /dev/null
+++ b/indra/newview/skins/default/textures/windows/Toast_Over.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/windows/Window_Background.png b/indra/newview/skins/default/textures/windows/Window_Background.png
new file mode 100644
index 0000000000..e9f15e76b9
--- /dev/null
+++ b/indra/newview/skins/default/textures/windows/Window_Background.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/windows/Window_Foreground.png b/indra/newview/skins/default/textures/windows/Window_Foreground.png
new file mode 100644
index 0000000000..e76e9f3c79
--- /dev/null
+++ b/indra/newview/skins/default/textures/windows/Window_Foreground.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/world/NoEntryLines.png b/indra/newview/skins/default/textures/world/NoEntryLines.png
new file mode 100644
index 0000000000..18e270bde5
--- /dev/null
+++ b/indra/newview/skins/default/textures/world/NoEntryLines.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/world/NoEntryPassLines.png b/indra/newview/skins/default/textures/world/NoEntryPassLines.png
new file mode 100644
index 0000000000..e4b8fc6ae2
--- /dev/null
+++ b/indra/newview/skins/default/textures/world/NoEntryPassLines.png
Binary files differ
diff --git a/indra/newview/skins/default/xui/da/floater_about.xml b/indra/newview/skins/default/xui/da/floater_about.xml
index 9f3a61d0c5..6b52da04d0 100644
--- a/indra/newview/skins/default/xui/da/floater_about.xml
+++ b/indra/newview/skins/default/xui/da/floater_about.xml
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
-<floater name="floater_about" title="Om Second Life">
+<floater name="floater_about" title="Om [APP_NAME]">
<text_editor name="credits_editor">
Second Life er gjort muligt for dig af Philip, Tessa, Andrew, Cory, James, Ben, Char, Charlie, Colin, Dan, Daniel, Doug, Eric, Hamlet, Haney, Eve, Hunter, Ian, Jeff, Jennifer, Jim, John, Lee, Mark, Peter, Phoenix, Richard, Robin, Xenon, Steve, Tanya, Eddie, Avi, Frank, Bruce, Aaron, Alice, Bob, Debra, Eileen, Helen, Janet, Louie, Leviathania, Stefan, Ray, Kevin, Tom, Mikeb, MikeT, Burgess, Elena, Tracy, Bill, Todd, Ryan, Zach, Sarah, Nova, Tim, Stephanie, Michael, Evan, Nicolas, Catherine, Rachelle, Dave, Holly, Bub, Kelly, Magellan, Ramzi, Don, Sabin, Jill, Rheya, Jeska, Torley, Kona, Callum, Charity, Ventrella, Jack, Vektor, Iris, Chris, Nicole, Mick, Reuben, Blue, Babbage, Yedwab, Deana, Lauren, Brent, Pathfinder, Chadrick, Altruima, Jesse, Teeny, Monroe, Icculus, David, Tess, Lizzie, Patsy, Isaac, Lawrence, Cyn, Bo, Gia, Annette, Marius, Tbone, Jonathan, Karen, Ginsu, Satoko, Yuko, Makiko, Thomas, Harry, Seth, Alexei, Brian, Guy, Runitai, Ethan, Data, Cornelius, Kenny, Swiss, Zero, Natria, Wendy, Stephen, Teeple, Thumper, Lucy, Dee, Mia, Liana, Warren, Branka, Aura, beez, Milo, Hermia, Red, Thrax, Joe, Sally, Magenta, Mogura, Paul, Jose, Rejean, Henrik, Lexie, Amber, Logan, Xan, Nora, Morpheus, Donovan, Leyla, MichaelFrancis, Beast, Cube, Bucky, Joshua, Stryfe, Harmony, Teresa, Claudia, Walker, Glenn, Fritz, Fordak, June, Cleopetra, Jean, Ivy, Betsy, Roosevelt, Spike, Ken, Which, Tofu, Chiyo, Rob, Zee, dustin, George, Del, Matthew, Cat, Jacqui, Lightfoot, Adrian, Viola, Alfred, Noel, Irfan, Sunil, Yool, Rika, Jane, Xtreme, Frontier, a2, Neo, Siobhan, Yoz, Justin, Elle, Qarl, Benjamin, Isabel, Gulliver, Everett, Christopher, Izzy, Stephany, Garry, Sejong, Sean, Tobin, Iridium, Meta, Anthony, Jeremy, JP, Jake, Maurice, Madhavi, Leopard, Kyle, Joon, Kari, Bert, Belinda, Jon, Kristi, Bridie, Pramod, KJ, Socrates, Maria, Ivan, Aric, Yamasaki, Adreanne, Jay, MitchK, Ceren, Coco, Durl, Jenny, Periapse, Kartic, Storrs, Lotte, Sandy, Rohn, Colossus, Zen, BigPapi, Brad, Pastrami, Kurz, Mani, Neuro, Jaime, MJ, Rowan, Sgt, Elvis, Gecko, Samuel, Sardonyx, Leo, Bryan, Niko, Soft, Poppy, Rachel, Aki, Angelo, Banzai, Alexa, Sue, CeeLo, Bender, CG, Gillian, Pelle, Nick, Echo, Zara, Christine, Shamiran, Emma, Blake, Keiko, Plexus, Joppa, Sidewinder, Erica, Ashlei, Twilight, Kristen, Brett, Q, Enus, Simon, Bevis, Kraft, Kip, Chandler, Ron, LauraP, Ram, KyleJM, Scouse, Prospero, Melissa, Marty, Nat, Hamilton, Kend, Lordan, Jimmy, Kosmo, Seraph, Green, Ekim, Wiggo, JT, Rome, Doris, Miz, Benoc, Whump, Trinity, Patch, Kate, TJ, Bao, Joohwan, Christy, Sofia, Matias, Cogsworth, Johan, Oreh, Cheah, Angela, Brandy, Mango, Lan, Aleks, Gloria, Heidy, Mitchell, Space, Colton, Bambers, Einstein, Maggie, Malbers, Rose, Winnie, Stella, Milton, Rothman, Niall, Marin, Allison, Katie, Dawn, Katt, Dusty, Kalpana, Judy, Andrea, Ambroff, Infinity, Gail, Rico, Raymond, Yi, William, Christa, M, Teagan, Scout, Molly, Dante, Corr, Dynamike, Usi, Kaylee, Vidtuts, Lil, Danica, Sascha, Kelv, Jacob, Nya, Rodney, Brandon, Elsie, Blondin, Grant, Katrin, Nyx, Gabriel, Locklainn, Claire, Devin, Minerva, Monty, Austin, Bradford, Si, Keira, H, Caitlin, Dita, Makai, Jenn, Ann, Meredith, Clare, Joy, Praveen, Cody, Edmund, Ruthe, Sirena, Gayathri, Spider, FJ, Davidoff, Tian, Jennie, Louise, Oskar, Landon, Noelle, Jarv, Ingrid, Al, Sommer, Doc, Aria, Huin, Gray, Lili, Vir, DJ, Yang, T, Simone, Maestro, Scott, Charlene, Quixote, Amanda, Susan, Zed, Anne, Enkidu, Esbee, Joroan, Katelin, Roxie, Tay, Scarlet, Kevin, Johnny, Wolfgang, Andren, Bob, Howard, Merov, Rand, Ray, Michon, Newell, Galen, Dessie, Les, Michon, Jenelle, Geo, Siz, Shapiro, Pete, Calyle, Selene, Allen, Phoebe, Goldin, Kimmora, Dakota, Slaton, Lindquist, Zoey, Hari, Othello, Rohit, Sheldon, Petra, Viale, Gordon, Kaye, Pink, Ferny, Emerson, Davy, Bri, Chan, Juan, Robert, Terrence, Nathan, Carl and many others.
diff --git a/indra/newview/skins/default/xui/da/floater_about_land.xml b/indra/newview/skins/default/xui/da/floater_about_land.xml
index df7d5fe8ff..15ebffa302 100644
--- a/indra/newview/skins/default/xui/da/floater_about_land.xml
+++ b/indra/newview/skins/default/xui/da/floater_about_land.xml
@@ -340,42 +340,18 @@ Kun større parceller kan vises i søgning.
</combo_item>
</combo_box>
<combo_box name="land category">
- <combo_item name="AnyCategory">
- Alle kategorier
- </combo_item>
- <combo_item name="LindenLocation">
- Linden Location
- </combo_item>
- <combo_item name="Arts&amp;Culture">
- Kunst &amp; kultur
- </combo_item>
- <combo_item name="Business">
- Business
- </combo_item>
- <combo_item name="Educational">
- Uddannelse
- </combo_item>
- <combo_item name="Gaming">
- Spil
- </combo_item>
- <combo_item name="Hangout">
- Afslapning
- </combo_item>
- <combo_item name="NewcomerFriendly">
- Nybegynder venligt
- </combo_item>
- <combo_item name="Parks&amp;Nature">
- Parker &amp; natur
- </combo_item>
- <combo_item name="Residential">
- Beboelse
- </combo_item>
- <combo_item name="Shopping">
- Indkøb
- </combo_item>
- <combo_item name="Other">
- Andet
- </combo_item>
+ <combo_box.item name="AnyCategory" label="Alle kategorier" />
+ <combo_box.item name="LindenLocation" label="Linden Location" />
+ <combo_box.item name="Arts&amp;Culture" label="Kunst &amp; kultur" />
+ <combo_box.item name="Business" label="Business" />
+ <combo_box.item name="Educational" label="Uddannelse" />
+ <combo_box.item name="Gaming" label="Spil" />
+ <combo_box.item name="Hangout" label="Afslapning" />
+ <combo_box.item name="NewcomerFriendly" label="Nybegynder venligt" />
+ <combo_box.item name="Parks&amp;Nature" label="Parker &amp; natur" />
+ <combo_box.item name="Residential" label="Beboelse" />
+ <combo_box.item name="Shopping" label="Indkøb" />
+ <combo_box.item name="Other" label="Andet" />
</combo_box>
<button label="?" label_selected="?" name="?"/>
<check_box label="Mature indhold" name="MatureCheck" tool_tip=""/>
@@ -407,15 +383,9 @@ Kun større parceller kan vises i søgning.
Teleport valg:
</text>
<combo_box name="landing type" tool_tip="Vælg hvordan du vil håndtere teleporteringer til dit land.">
- <combo_item length="1" name="Blocked" type="string">
- Blokeret
- </combo_item>
- <combo_item length="1" name="LandingPoint" type="string">
- Landingspunkt
- </combo_item>
- <combo_item length="1" name="Anywhere" type="string">
- Hvor som helst
- </combo_item>
+ <combo_box.item length="1" name="Blocked" type="string" label="Blokeret" />
+ <combo_box.item length="1" name="LandingPoint" type="string" label="Landingspunkt" />
+ <combo_box.item length="1" name="Anywhere" type="string" label="Hvor som helst" />
</combo_box>
<string name="push_restrict_text">
Skub forbudt
@@ -471,9 +441,11 @@ web-siden, efter du klikker på play knappen.)
<text length="1" name="Voice settings:" type="string">
Stemme:
</text>
- <check_box label="Aktiver stemme chat" name="parcel_enable_voice_channel"/>
- <check_box label="Aktiver stemme chat (muliggjort via estate opsætning)" name="parcel_enable_voice_channel_is_estate_disabled"/>
- <check_box label="Begræns stemme chat til denne parcel" name="parcel_enable_voice_channel_parcel"/>
+ <radio_group name="parcel_voice_channel">
+ <radio_item type="string" length="1" name="Estate" label="Brug Estate kanalen" />
+ <radio_item type="string" length="1" name="Private" label="Brug en privat kanal" />
+ <radio_item type="string" length="1" name="Disabled" label="Slå stemme chat fra på denne parcel" />
+ </radio_group>
</panel>
<panel label="Adgang" name="land_access_panel">
<text length="1" name="Limit access to this parcel to:" type="string">
@@ -491,12 +463,8 @@ web-siden, efter du klikker på play knappen.)
<check_box label="Tillad adgang til gruppen: [GROUP]" name="GroupCheck" tool_tip="Vælg gruppe under fanen &apos;generelt&apos;."/>
<check_box label="Sælg adgang til:" name="PassCheck" tool_tip="Tillader midlertidig adgang til denne parcel"/>
<combo_box name="pass_combo">
- <combo_item name="Anyone">
- Alle
- </combo_item>
- <combo_item name="Group">
- Gruppe
- </combo_item>
+ <combo_box.item name="Anyone" label="Alle" />
+ <combo_box.item name="Group" label="Gruppe" />
</combo_box>
<spinner label="Pris i L$:" name="PriceSpin"/>
<spinner label="Timers adgang:" name="HoursSpin"/>
diff --git a/indra/newview/skins/default/xui/da/floater_animation_preview.xml b/indra/newview/skins/default/xui/da/floater_animation_preview.xml
index 92508e36de..8cb0eee601 100644
--- a/indra/newview/skins/default/xui/da/floater_animation_preview.xml
+++ b/indra/newview/skins/default/xui/da/floater_animation_preview.xml
@@ -17,129 +17,55 @@
</text>
<combo_box label="" name="hand_pose_combo"
tool_tip="Kontrollerer hvad hænderne går i løbet af animationen." width="140">
- <combo_item name="Spread">
- Spredt
- </combo_item>
- <combo_item name="Relaxed">
- Afslappet
- </combo_item>
- <combo_item name="PointBoth">
- Peg begge
- </combo_item>
- <combo_item name="Fist">
- Knytnæver
- </combo_item>
- <combo_item name="RelaxedLeft">
- Afslappet venstre
- </combo_item>
- <combo_item name="PointLeft">
- Peg venstre
- </combo_item>
- <combo_item name="FistLeft">
- Knytnæve venstre
- </combo_item>
- <combo_item name="RelaxedRight">
- Afslappet højre
- </combo_item>
- <combo_item name="PointRight">
- Peg højre
- </combo_item>
- <combo_item name="FistRight">
- Knytnæve højre
- </combo_item>
- <combo_item name="SaluteRight">
- Honnør højre
- </combo_item>
- <combo_item name="Typing">
- Skriver
- </combo_item>
- <combo_item name="PeaceRight">
- Fredstegn højre
- </combo_item>
+ <combo_box.item name="Spread" label="Spredt" />
+ <combo_box.item name="Relaxed" label="Afslappet" />
+ <combo_box.item name="PointBoth" label="Peg begge" />
+ <combo_box.item name="Fist" label="Knytnæver" />
+ <combo_box.item name="RelaxedLeft" label="Afslappet venstre" />
+ <combo_box.item name="PointLeft" label="Peg venstre" />
+ <combo_box.item name="FistLeft" label="Knytnæve venstre" />
+ <combo_box.item name="RelaxedRight" label="Afslappet højre" />
+ <combo_box.item name="PointRight" label="Peg højre" />
+ <combo_box.item name="FistRight" label="Knytnæve højre" />
+ <combo_box.item name="SaluteRight" label="Honnør højre" />
+ <combo_box.item name="Typing" label="Skriver" />
+ <combo_box.item name="PeaceRight" label="Fredstegn højre" />
</combo_box>
<text name="emote_label">
Ansigtsudtryk
</text>
<combo_box label="" name="emote_combo"
tool_tip="Angiver hvad ansigtet gør under animationen" width="140">
- <combo_item name="[None]">
- [Intet]
- </combo_item>
- <combo_item name="Aaaaah">
- Aaaaah
- </combo_item>
- <combo_item name="Afraid">
- Bange
- </combo_item>
- <combo_item name="Angry">
- Vred
- </combo_item>
- <combo_item name="BigSmile">
- Stort smil
- </combo_item>
- <combo_item name="Bored">
- Keder sig
- </combo_item>
- <combo_item name="Cry">
- Græder
- </combo_item>
- <combo_item name="Disdain">
- Forarget
- </combo_item>
- <combo_item name="Embarrassed">
- Flov
- </combo_item>
- <combo_item name="Frown">
- Skuler
- </combo_item>
- <combo_item name="Kiss">
- Kysser
- </combo_item>
- <combo_item name="Laugh">
- Griner
- </combo_item>
- <combo_item name="Plllppt">
- Plllppt
- </combo_item>
- <combo_item name="Repulsed">
- Frastødt
- </combo_item>
- <combo_item name="Sad">
- Ked af det
- </combo_item>
- <combo_item name="Shrug">
- Skuldertræk
- </combo_item>
- <combo_item name="Smile">
- Smiler
- </combo_item>
- <combo_item name="Surprise">
- Overrasket
- </combo_item>
- <combo_item name="Wink">
- Blinker
- </combo_item>
- <combo_item name="Worry">
- Bekymret
- </combo_item>
+ <combo_box.item name="[None]" label="Intet]" />
+ <combo_box.item name="Aaaaah" label="Aaaaah" />
+ <combo_box.item name="Afraid" label="Bange" />
+ <combo_box.item name="Angry" label="Vred" />
+ <combo_box.item name="BigSmile" label="Stort smil" />
+ <combo_box.item name="Bored" label="Keder sig" />
+ <combo_box.item name="Cry" label="Græder" />
+ <combo_box.item name="Disdain" label="Forarget" />
+ <combo_box.item name="Embarrassed" label="Flov" />
+ <combo_box.item name="Frown" label="Skuler" />
+ <combo_box.item name="Kiss" label="Kysser" />
+ <combo_box.item name="Laugh" label="Griner" />
+ <combo_box.item name="Plllppt" label="Plllppt" />
+ <combo_box.item name="Repulsed" label="Frastødt" />
+ <combo_box.item name="Sad" label="Ked af det" />
+ <combo_box.item name="Shrug" label="Skuldertræk" />
+ <combo_box.item name="Smile" label="Smiler" />
+ <combo_box.item name="Surprise" label="Overrasket" />
+ <combo_box.item name="Wink" label="Blinker" />
+ <combo_box.item name="Worry" label="Bekymret" />
</combo_box>
<text name="preview_label">
Vis mens
</text>
<combo_box label="" name="preview_base_anim"
tool_tip="Se hvordan animation ser ud i forskellige typiske avatar-situationer." width="140">
- <combo_item name="Standing">
- Står
- </combo_item>
- <combo_item name="Walking">
- GÃ¥r
- </combo_item>
- <combo_item name="Sitting">
- Sidder
- </combo_item>
- <combo_item name="Flying">
- Flyver
- </combo_item>
+ <combo_box.item name="Standing" label="Står" />
+ <combo_box.item name="Walking" label="GÃ¥r" />
+ <combo_box.item name="Sitting" label="Sidder" />
+ <combo_box.item name="Flying" label="Flyver" />
</combo_box>
<spinner label="start (sec)" name="ease_in_time"
tool_tip="Tid i sekunder animationen bruger på at komme i gang." />
diff --git a/indra/newview/skins/default/xui/da/floater_buy_land.xml b/indra/newview/skins/default/xui/da/floater_buy_land.xml
index 81f66a3276..1d42ffb45a 100644
--- a/indra/newview/skins/default/xui/da/floater_buy_land.xml
+++ b/indra/newview/skins/default/xui/da/floater_buy_land.xml
@@ -75,15 +75,9 @@ sælges med objekter
Kun premium medlemmer kan eje land.
</text>
<combo_box name="account_level">
- <combo_item name="US$9.95/month,billedmonthly">
- US$9.95/md, månedlig afregning
- </combo_item>
- <combo_item name="US$7.50/month,billedquarterly">
- US$7.50/md, kvartalsvis afregning
- </combo_item>
- <combo_item name="US$6.00/month,billedannually">
- US$6.00/md, årlig afregning
- </combo_item>
+ <combo_box.item name="US$9.95/month,billedmonthly" label="US$9.95/md, månedlig afregning" />
+ <combo_box.item name="US$7.50/month,billedquarterly" label="US$7.50/md, kvartalsvis afregning" />
+ <combo_box.item name="US$6.00/month,billedannually" label="US$6.00/md, årlig afregning" />
</combo_box>
<text name="land_use_action">
Forøg dine månedlige arealanvendelse gebyrer til US $ 40/måned.
diff --git a/indra/newview/skins/default/xui/da/floater_customize.xml b/indra/newview/skins/default/xui/da/floater_customize.xml
index 3fceddc040..aa6b8cb043 100644
--- a/indra/newview/skins/default/xui/da/floater_customize.xml
+++ b/indra/newview/skins/default/xui/da/floater_customize.xml
@@ -14,12 +14,8 @@
<button label="Overkrop" label_selected="Overkrop" name="Torso"/>
<button label="Ben" label_selected="Ben" name="Legs"/>
<radio_group name="sex radio">
- <radio_item length="1" name="radio" type="string">
- Kvinde
- </radio_item>
- <radio_item length="1" name="radio2" type="string">
- Mand
- </radio_item>
+ <radio_item type="string" length="1" name="radio" label="Kvinde" />
+ <radio_item type="string" length="1" name="radio2" label="Mand" />
</radio_group>
<text length="1" name="title" type="string">
[DESC]
diff --git a/indra/newview/skins/default/xui/da/floater_hardware_settings.xml b/indra/newview/skins/default/xui/da/floater_hardware_settings.xml
index 2f462f7a0c..488660853f 100644
--- a/indra/newview/skins/default/xui/da/floater_hardware_settings.xml
+++ b/indra/newview/skins/default/xui/da/floater_hardware_settings.xml
@@ -8,21 +8,11 @@
Antialiasing:
</text>
<combo_box label="Antialiasing" name="fsaa" width="100">
- <combo_item name="FSAADisabled">
- Slået fra
- </combo_item>
- <combo_item name="2x">
- 2x
- </combo_item>
- <combo_item name="4x">
- 4x
- </combo_item>
- <combo_item name="8x">
- 8x
- </combo_item>
- <combo_item name="16x">
- 16x
- </combo_item>
+ <combo_box.item name="FSAADisabled" label="Slået fra"/>
+ <combo_box.item name="2x" label="2x"/>
+ <combo_box.item name="4x" label="4x"/>
+ <combo_box.item name="8x" label="8x"/>
+ <combo_box.item name="16x" label="16x"/>
</combo_box>
<spinner label="Gamma:" name="gamma" />
<text type="string" length="1" name="(brightness, lower is brighter)">
diff --git a/indra/newview/skins/default/xui/da/floater_image_preview.xml b/indra/newview/skins/default/xui/da/floater_image_preview.xml
index c7ce3d00b6..345c9aa6d1 100644
--- a/indra/newview/skins/default/xui/da/floater_image_preview.xml
+++ b/indra/newview/skins/default/xui/da/floater_image_preview.xml
@@ -10,36 +10,16 @@
Se billede som:
</text>
<combo_box label="Tøj type" name="clothing_type_combo">
- <combo_item name="Image">
- Billede
- </combo_item>
- <combo_item name="Hair">
- HÃ¥r
- </combo_item>
- <combo_item name="FemaleHead">
- Kvinde - hoved
- </combo_item>
- <combo_item name="FemaleUpperBody">
- Kvinde - overkrop
- </combo_item>
- <combo_item name="FemaleLowerBody">
- Kvinde - underkrop
- </combo_item>
- <combo_item name="MaleHead">
- Mand - hoved
- </combo_item>
- <combo_item name="MaleUpperBody">
- Mand - overkrop
- </combo_item>
- <combo_item name="MaleLowerBody">
- Mand - underkrop
- </combo_item>
- <combo_item name="Skirt">
- Nederdel
- </combo_item>
- <combo_item name="SculptedPrim">
- Sculpted prim
- </combo_item>
+ <combo_box.item name="Image" label="Billede"/>
+ <combo_box.item name="Hair" label="HÃ¥r"/>
+ <combo_box.item name="FemaleHead" label="Kvinde - hoved"/>
+ <combo_box.item name="FemaleUpperBody" label="Kvinde - overkrop"/>
+ <combo_box.item name="FemaleLowerBody" label="Kvinde - underkrop"/>
+ <combo_box.item name="MaleHead" label="Mand - hoved"/>
+ <combo_box.item name="MaleUpperBody" label="Mand - overkrop"/>
+ <combo_box.item name="MaleLowerBody" label="Mand - underkrop"/>
+ <combo_box.item name="Skirt" label="Nederdel"/>
+ <combo_box.item name="SculptedPrim" label="Sculpted prim"/>
</combo_box>
<text name="bad_image_text">
Kunne ikke læse billede.
diff --git a/indra/newview/skins/default/xui/da/floater_inventory_item_properties.xml b/indra/newview/skins/default/xui/da/floater_inventory_item_properties.xml
index 96039c8444..9f28440fb0 100644
--- a/indra/newview/skins/default/xui/da/floater_inventory_item_properties.xml
+++ b/indra/newview/skins/default/xui/da/floater_inventory_item_properties.xml
@@ -60,12 +60,8 @@
</text>
<check_box label="Til salg" name="CheckPurchase" />
<radio_group name="RadioSaleType">
- <radio_item name="radio">
- Original
- </radio_item>
- <radio_item name="radio2">
- Kopi
- </radio_item>
+ <radio_item name="radio" label="Original" />
+ <radio_item name="radio2" label="Kopi" />
</radio_group>
<text name="TextPrice">
Pris: L$
diff --git a/indra/newview/skins/default/xui/da/floater_postcard.xml b/indra/newview/skins/default/xui/da/floater_postcard.xml
index 6b02f43633..24d45062ae 100644
--- a/indra/newview/skins/default/xui/da/floater_postcard.xml
+++ b/indra/newview/skins/default/xui/da/floater_postcard.xml
@@ -25,7 +25,7 @@
<button label="Annullér" name="cancel_btn" />
<button label="Send" name="send_btn" />
<string name="default_subject">
- Postkort fra Second Life.
+ Postkort fra [SECOND_LIFE]
</string>
<string name="default_message">
Tjek det her ud!
diff --git a/indra/newview/skins/default/xui/da/floater_preview_gesture.xml b/indra/newview/skins/default/xui/da/floater_preview_gesture.xml
index 5a45f7750c..0053cb852f 100644
--- a/indra/newview/skins/default/xui/da/floater_preview_gesture.xml
+++ b/indra/newview/skins/default/xui/da/floater_preview_gesture.xml
@@ -45,12 +45,8 @@ Vent
medmindre du tilføjer vente trin.
</text>
<radio_group name="animation_trigger_type">
- <radio_item name="start">
- Start
- </radio_item>
- <radio_item name="stop">
- Stop
- </radio_item>
+ <radio_item name="start" label="Start" />
+ <radio_item name="stop" label="Stop" />
</radio_group>
<check_box label="Indtil animation er færdig" name="wait_anim_check"/>
<check_box label="tid i sekunder" name="wait_time_check"/>
diff --git a/indra/newview/skins/default/xui/da/floater_report_abuse.xml b/indra/newview/skins/default/xui/da/floater_report_abuse.xml
index 471222e08d..804051e62c 100644
--- a/indra/newview/skins/default/xui/da/floater_report_abuse.xml
+++ b/indra/newview/skins/default/xui/da/floater_report_abuse.xml
@@ -37,123 +37,51 @@
Hendrerit Vulputate
</text>
<combo_box name="category_combo" tool_tip="Kategori -- Vælg en kategori der passer bedst på denne rapport">
- <combo_item name="Select_category">
- Vælg kategori
- </combo_item>
- <combo_item name="Age__Age_play">
- Alder &gt; Falsk alder
- </combo_item>
- <combo_item name="Age__Adult_resident_on_Teen_Second_Life">
- Alder &gt; Voksen beboer på Teen Second Life
- </combo_item>
+ <combo_box.item name="Select_category" label="Vælg kategori"/>
+ <combo_box.item name="Age__Age_play" label="Alder &gt; Falsk alder"/>
+ <combo_box.item name="Age__Adult_resident_on_Teen_Second_Life" label="Alder &gt; Voksen beboer på Teen Second Life"/>
<combo_item name="Age__Underage_resident_outside_of_Teen_Second_Life">
Alder &gt; Mindreårig beboer udenfor Teen Second Life
</combo_item>
- <combo_item name="Assault__Combat_sandbox___unsafe_area">
- Overfald &gt; Kamp sandkasse / Usikkert område
- </combo_item>
- <combo_item name="Assault__Safe_area">
- Overfald &gt; Sikkert område
- </combo_item>
- <combo_item name="Assault__Weapons_testing_sandbox">
- Overfald &gt; Sandkasse til våbentest
- </combo_item>
- <combo_item name="Commerce__Failure_to_deliver_product_or_service">
- Handel &gt; Vare eller ydelse ikke leveret
- </combo_item>
- <combo_item name="Disclosure__Real_world_information">
- Offentliggørelse &gt; Om oplysninger i den virkelige verden
- </combo_item>
- <combo_item name="Disclosure__Remotely_monitoring chat">
- Offentliggørelse &gt; Fjernaflytning af chat
- </combo_item>
- <combo_item name="Disclosure__Second_Life_information_chat_IMs">
- Offentliggørelse &gt; Information/chat/IM fra Second Life
- </combo_item>
- <combo_item name="Disturbing_the_peace__Unfair_use_of_region_resources">
- Forstyrrelse af fred &gt; Unfair brug af region ressourcer
- </combo_item>
- <combo_item name="Disturbing_the_peace__Excessive_scripted_objects">
- Forstyrrelse af fred &gt; Overdreven brug af objekter med script
- </combo_item>
- <combo_item name="Disturbing_the_peace__Object_littering">
- Forstyrrelse af fred &gt; Object affald
- </combo_item>
- <combo_item name="Disturbing_the_peace__Repetitive_spam">
- Forstyrring af fred &gt; Gentagen spam
- </combo_item>
- <combo_item name="Disturbing_the_peace__Unwanted_advert_spam">
- Forstyrrelse af fred &gt; Uønsket reklame spam
- </combo_item>
- <combo_item name="Fraud__L$">
- Bedrageri &gt; L$
- </combo_item>
- <combo_item name="Fraud__Land">
- Bedrageri &gt; Land
- </combo_item>
- <combo_item name="Fraud__Pyramid_scheme_or_chain_letter">
- Bedrageri &gt; Pyramide spil eller kædebreve
- </combo_item>
- <combo_item name="Fraud__US$">
- Bedrageri &gt; US$
- </combo_item>
- <combo_item name="Harassment__Advert_farms___visual_spam">
- Chikane &gt; reklame farm / billedeligt spam
- </combo_item>
- <combo_item name="Harassment__Defaming_individuals_or_groups">
- Chikane &gt; Injurier/bagvask enkeltpersoner eller grupper
- </combo_item>
- <combo_item name="Harassment__Impeding_movement">
- Chikane &gt; Hindre bevægelse
- </combo_item>
- <combo_item name="Harassment__Sexual_harassment">
- Chikane &gt; Sex chikane
- </combo_item>
- <combo_item name="Harassment__Solicting_inciting_others_to_violate_ToS">
- Chikane &gt; Opfordrer/kræver at andre overtræder licensbetingelser
- </combo_item>
- <combo_item name="Harassment__Verbal_abuse">
- Chikane &gt; Verbalt chikane
- </combo_item>
- <combo_item name="Indecency__Broadly_offensive_content_or_conduct">
- Uanstændighed &gt; Meget stødende indhold eller adfærd
- </combo_item>
- <combo_item name="Indecency__Inappropriate_avatar_name">
- Uanstændighed &gt; Upassende avatar navn
- </combo_item>
+ <combo_box.item name="Assault__Combat_sandbox___unsafe_area" label="Overfald &gt; Kamp sandkasse / Usikkert område"/>
+ <combo_box.item name="Assault__Safe_area" label="Overfald &gt; Sikkert område"/>
+ <combo_box.item name="Assault__Weapons_testing_sandbox" label="Overfald &gt; Sandkasse til våbentest"/>
+ <combo_box.item name="Commerce__Failure_to_deliver_product_or_service" label="Handel &gt; Vare eller ydelse ikke leveret"/>
+ <combo_box.item name="Disclosure__Real_world_information" label="Offentliggørelse &gt; Om oplysninger i den virkelige verden"/>
+ <combo_box.item name="Disclosure__Remotely_monitoring chat" label="Offentliggørelse &gt; Fjernaflytning af chat"/>
+ <combo_box.item name="Disclosure__Second_Life_information_chat_IMs" label="Offentliggørelse &gt; Information/chat/IM fra Second Life"/>
+ <combo_box.item name="Disturbing_the_peace__Unfair_use_of_region_resources" label="Forstyrrelse af fred &gt; Unfair brug af region ressourcer"/>
+ <combo_box.item name="Disturbing_the_peace__Excessive_scripted_objects" label="Forstyrrelse af fred &gt; Overdreven brug af objekter med script"/>
+ <combo_box.item name="Disturbing_the_peace__Object_littering" label="Forstyrrelse af fred &gt; Object affald"/>
+ <combo_box.item name="Disturbing_the_peace__Repetitive_spam" label="Forstyrring af fred &gt; Gentagen spam"/>
+ <combo_box.item name="Disturbing_the_peace__Unwanted_advert_spam" label="Forstyrrelse af fred &gt; Uønsket reklame spam"/>
+ <combo_box.item name="Fraud__L$" label="Bedrageri &gt; L$"/>
+ <combo_box.item name="Fraud__Land" label="Bedrageri &gt; Land"/>
+ <combo_box.item name="Fraud__Pyramid_scheme_or_chain_letter" label="Bedrageri &gt; Pyramide spil eller kædebreve"/>
+ <combo_box.item name="Fraud__US$" label="Bedrageri &gt; US$"/>
+ <combo_box.item name="Harassment__Advert_farms___visual_spam" label="Chikane &gt; reklame farm / billedeligt spam"/>
+ <combo_box.item name="Harassment__Defaming_individuals_or_groups" label="Chikane &gt; Injurier/bagvask enkeltpersoner eller grupper"/>
+ <combo_box.item name="Harassment__Impeding_movement" label="Chikane &gt; Hindre bevægelse"/>
+ <combo_box.item name="Harassment__Sexual_harassment" label="Chikane &gt; Sex chikane"/>
+ <combo_box.item name="Harassment__Solicting_inciting_others_to_violate_ToS" label="Chikane &gt; Opfordrer/kræver at andre overtræder licensbetingelser"/>
+ <combo_box.item name="Harassment__Verbal_abuse" label="Chikane &gt; Verbalt chikane"/>
+ <combo_box.item name="Indecency__Broadly_offensive_content_or_conduct" label="Uanstændighed &gt; Meget stødende indhold eller adfærd"/>
+ <combo_box.item name="Indecency__Inappropriate_avatar_name" label="Uanstændighed &gt; Upassende avatar navn"/>
<combo_item name="Indecency__Mature_content_in_PG_region">
Usømmelighed &gt; Upassende inhold eller opførsel i en &apos;PG&apos; region
</combo_item>
<combo_item name="Indecency__Inappropriate_content_in_Mature_region">
Usømmelighed &gt; Upassende inhold eller opførsel i en &apos;Mature&apos; region
</combo_item>
- <combo_item name="Intellectual_property_infringement_Content_Removal">
- Krænkelse af intellektuelle ejendomsrettigheder &gt; Indholds fjernelse
- </combo_item>
- <combo_item name="Intellectual_property_infringement_CopyBot_or_Permissions_Exploit">
- Krænkelse af intellektuelle ejendomsrettigheder &gt; CopyBot eller omgåelse af rettighedsbeskyttelse
- </combo_item>
- <combo_item name="Intolerance">
- Intolerance
- </combo_item>
- <combo_item name="Land__Abuse_of_sandbox_resources">
- Land &gt; Misbrug af sandkasse resourcer
- </combo_item>
- <combo_item name="Land__Encroachment__Objects_textures">
- Land &gt; Overgreb &gt; Objekter/teksturer
- </combo_item>
- <combo_item name="Land__Encroachment__Particles">
- Land &gt; Overgreb &gt; Partikler
- </combo_item>
- <combo_item name="Land__Encroachment__Trees_plants">
- Land &gt; Overgreb &gt; Træer/planter
- </combo_item>
- <combo_item name="Wagering_gambling">
- Væddemål/gambling
- </combo_item>
- <combo_item name="Other">
- Andet
- </combo_item>
+ <combo_box.item name="Intellectual_property_infringement_Content_Removal" label="Krænkelse af intellektuelle ejendomsrettigheder &gt; Indholds fjernelse"/>
+ <combo_box.item name="Intellectual_property_infringement_CopyBot_or_Permissions_Exploit" label="Krænkelse af intellektuelle ejendomsrettigheder &gt; CopyBot eller omgåelse af rettighedsbeskyttelse"/>
+ <combo_box.item name="Intolerance" label="Intolerance"/>
+ <combo_box.item name="Land__Abuse_of_sandbox_resources" label="Land &gt; Misbrug af sandkasse resourcer"/>
+ <combo_box.item name="Land__Encroachment__Objects_textures" label="Land &gt; Overgreb &gt; Objekter/teksturer"/>
+ <combo_box.item name="Land__Encroachment__Particles" label="Land &gt; Overgreb &gt; Partikler"/>
+ <combo_box.item name="Land__Encroachment__Trees_plants" label="Land &gt; Overgreb &gt; Træer/planter"/>
+ <combo_box.item name="Wagering_gambling" label="Væddemål/gambling"/>
+ <combo_box.item name="Other" label="Andet"/>
</combo_box>
<text name="abuser_name_title">
Udøvers navn:
diff --git a/indra/newview/skins/default/xui/da/floater_sell_land.xml b/indra/newview/skins/default/xui/da/floater_sell_land.xml
index dbf9433872..fc88b3d49a 100644
--- a/indra/newview/skins/default/xui/da/floater_sell_land.xml
+++ b/indra/newview/skins/default/xui/da/floater_sell_land.xml
@@ -34,15 +34,9 @@
Vælg om du vil sælge til hvem som helst eller en specifik køber.
</text>
<combo_box name="sell_to">
- <combo_item name="--selectone--">
- -- Vælg --
- </combo_item>
- <combo_item name="Anyone">
- Alle
- </combo_item>
- <combo_item name="Specificuser:">
- Specifik bruger:
- </combo_item>
+ <combo_box.item name="--selectone--" label="Vælg --" />
+ <combo_box.item name="Anyone" label="Alle" />
+ <combo_box.item name="Specificuser:" label="Specifik bruger:" />
</combo_box>
<button label="Vælg..." name="sell_to_select_agent" />
<text name="sell_objects_label">
@@ -52,12 +46,8 @@
Dine objekter der kan videregives sælges med jorden.
</text>
<radio_group name="sell_objects">
- <radio_item name="no">
- Nej, behold ejerskab til objekterne
- </radio_item>
- <radio_item name="yes">
- Ja, sælg objekter med jorden
- </radio_item>
+ <radio_item name="no" label="Nej, behold ejerskab til objekterne" />
+ <radio_item name="yes" label="Ja, sælg objekter med jorden" />
</radio_group>
<button label="Vis objekter" name="show_objects" />
<text name="nag_message_label">
diff --git a/indra/newview/skins/default/xui/da/floater_settings_debug.xml b/indra/newview/skins/default/xui/da/floater_settings_debug.xml
index f9cb4d0186..60f99deae2 100644
--- a/indra/newview/skins/default/xui/da/floater_settings_debug.xml
+++ b/indra/newview/skins/default/xui/da/floater_settings_debug.xml
@@ -1,12 +1,8 @@
<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
<floater name="settings_debug" title="Tekniske indstillinger">
<combo_box name="boolean_combo">
- <combo_item name="TRUE">
- TRUE (Valgt)
- </combo_item>
- <combo_item name="FALSE">
- FALSE (Fravalgt)
- </combo_item>
+ <combo_box.item name="TRUE" label="TRUE (Valgt)" />
+ <combo_box.item name="FALSE" label="FALSE (Fravalgt)" />
</combo_box>
<color_swatch label="Farve" name="color_swatch" />
<spinner label="x" name="val_spinner_1" />
diff --git a/indra/newview/skins/default/xui/da/floater_snapshot.xml b/indra/newview/skins/default/xui/da/floater_snapshot.xml
index 5b51d5f500..ed715bdb39 100644
--- a/indra/newview/skins/default/xui/da/floater_snapshot.xml
+++ b/indra/newview/skins/default/xui/da/floater_snapshot.xml
@@ -4,15 +4,9 @@
Hvor skal foto hen?
</text>
<radio_group label="Snapshot type" name="snapshot_type_radio">
- <radio_item name="postcard">
- Send via e-mail
- </radio_item>
- <radio_item name="texture">
- Gem i din beholdning (L$[AMOUNT])
- </radio_item>
- <radio_item name="local">
- Gem på din computer
- </radio_item>
+ <radio_item name="postcard" label="Send via e-mail" />
+ <radio_item name="texture" label="Gem i din beholdning (L$[AMOUNT])" />
+ <radio_item name="local" label="Gem på din computer" />
</radio_group>
<text name="file_size_label">
Fil størrelse: [SIZE] KB
@@ -38,75 +32,33 @@
Format
</text>
<combo_box label="Opløsning" name="postcard_size_combo">
- <combo_item name="CurrentWindow">
- Aktuelle vindue
- </combo_item>
- <combo_item name="640x480">
- 640x480
- </combo_item>
- <combo_item name="800x600">
- 800x600
- </combo_item>
- <combo_item name="1024x768">
- 1024x768
- </combo_item>
- <combo_item name="Custom">
- Manuel
- </combo_item>
+ <combo_box.item name="CurrentWindow" label="Aktuelle vindue"/>
+ <combo_box.item name="640x480" label="640x480"/>
+ <combo_box.item name="800x600" label="800x600"/>
+ <combo_box.item name="1024x768" label="1024x768"/>
+ <combo_box.item name="Custom" label="Manuel"/>
</combo_box>
<combo_box label="Opløsning" name="texture_size_combo">
- <combo_item name="CurrentWindow">
- Aktuelle vindue
- </combo_item>
- <combo_item name="Small(128x128)">
- Lille (128x128)
- </combo_item>
- <combo_item name="Medium(256x256)">
- Medium (256x256)
- </combo_item>
- <combo_item name="Large(512x512)">
- Stor (512x512)
- </combo_item>
- <combo_item name="Custom">
- Manuel
- </combo_item>
+ <combo_box.item name="CurrentWindow" label="Aktuelle vindue"/>
+ <combo_box.item name="Small(128x128)" label="Lille (128x128)"/>
+ <combo_box.item name="Medium(256x256)" label="Medium (256x256)"/>
+ <combo_box.item name="Large(512x512)" label="Stor (512x512)"/>
+ <combo_box.item name="Custom" label="Manuel"/>
</combo_box>
<combo_box label="Opløsning" name="local_size_combo">
- <combo_item name="CurrentWindow">
- Aktuelle vindue
- </combo_item>
- <combo_item name="320x240">
- 320x240
- </combo_item>
- <combo_item name="640x480">
- 640x480
- </combo_item>
- <combo_item name="800x600">
- 800x600
- </combo_item>
- <combo_item name="1024x768">
- 1024x768
- </combo_item>
- <combo_item name="1280x1024">
- 1280x1024
- </combo_item>
- <combo_item name="1600x1200">
- 1600x1200
- </combo_item>
- <combo_item name="Custom">
- Manuelt
- </combo_item>
+ <combo_box.item name="CurrentWindow" label="Aktuelle vindue"/>
+ <combo_box.item name="320x240" label="320x240"/>
+ <combo_box.item name="640x480" label="640x480"/>
+ <combo_box.item name="800x600" label="800x600"/>
+ <combo_box.item name="1024x768" label="1024x768"/>
+ <combo_box.item name="1280x1024" label="1280x1024"/>
+ <combo_box.item name="1600x1200" label="1600x1200"/>
+ <combo_box.item name="Custom" label="Manuelt"/>
</combo_box>
<combo_box label="Fil-format" name="local_format_combo" width="76">
- <combo_item name="PNG">
- PNG
- </combo_item>
- <combo_item name="JPEG">
- JPEG
- </combo_item>
- <combo_item name="BMP">
- BMP
- </combo_item>
+ <combo_box.item name="PNG" label="PNG"/>
+ <combo_box.item name="JPEG" label="JPEG"/>
+ <combo_box.item name="BMP" label="BMP"/>
</combo_box>
<spinner label="Bredde" name="snapshot_width" label_width="41" width="101"/>
<spinner label="Højde" name="snapshot_height" label_width="32" width="92" left="117"/>
@@ -116,15 +68,9 @@
Benyt:
</text>
<combo_box label="Billedlag" name="layer_types">
- <combo_item name="Colors">
- Farver
- </combo_item>
- <combo_item name="Depth">
- Dybde
- </combo_item>
- <combo_item name="ObjectMattes">
- Materinger
- </combo_item>
+ <combo_box.item name="Colors" label="Farver"/>
+ <combo_box.item name="Depth" label="Dybde"/>
+ <combo_box.item name="ObjectMattes" label="Materinger"/>
</combo_box>
<check_box label="Vis brugerflade på foto" name="ui_check"/>
<check_box label="Vis HUD objekter på foto" name="hud_check"/>
diff --git a/indra/newview/skins/default/xui/da/floater_tools.xml b/indra/newview/skins/default/xui/da/floater_tools.xml
index 0cd5f682fa..ccb8c67b68 100644
--- a/indra/newview/skins/default/xui/da/floater_tools.xml
+++ b/indra/newview/skins/default/xui/da/floater_tools.xml
@@ -20,15 +20,9 @@
Lineal:
</text>
<combo_box name="combobox grid mode">
- <combo_item name="World">
- Verden
- </combo_item>
- <combo_item name="Local">
- Lokal
- </combo_item>
- <combo_item name="Reference">
- Reference
- </combo_item>
+ <combo_box.item name="World" label="Verden"/>
+ <combo_box.item name="Local" label="Lokal"/>
+ <combo_box.item name="Reference" label="Reference"/>
</combo_box>
<check_box label="Stræk begge sider" name="checkbox uniform"/>
<check_box label="Stræk teksturer" name="checkbox stretch textures"/>
@@ -37,35 +31,39 @@
<text name="text status">
Træk for at flytte, shift+træk for at kopiere
</text>
- <button label="" label_selected="" name="ToolCube" tool_tip="Terning"/>
- <button label="" label_selected="" name="ToolPrism" tool_tip="Prisme"/>
- <button label="" label_selected="" name="ToolPyramid" tool_tip="Pyramide"/>
- <button label="" label_selected="" name="ToolTetrahedron" tool_tip="Tetraed"/>
- <button label="" label_selected="" name="ToolCylinder" tool_tip="Cylinder"/>
- <button label="" label_selected="" name="ToolHemiCylinder" tool_tip="Hemicylinder"/>
- <button label="" label_selected="" name="ToolCone" tool_tip="Kegle"/>
- <button label="" label_selected="" name="ToolHemiCone" tool_tip="Hemikegle"/>
- <button label="" label_selected="" name="ToolSphere" tool_tip="Sfære"/>
- <button label="" label_selected="" name="ToolHemiSphere" tool_tip="Hemisfære"/>
- <button label="" label_selected="" name="ToolTorus" tool_tip="Kuglering"/>
- <button label="" label_selected="" name="ToolTube" tool_tip="Rør"/>
- <button label="" label_selected="" name="ToolRing" tool_tip="Ring"/>
- <button label="" label_selected="" name="ToolTree" tool_tip="Træ"/>
- <button label="" label_selected="" name="ToolGrass" tool_tip="Græs"/>
- <check_box label="Hold værktøjet valgt" name="checkbox sticky"/>
- <check_box label="Kopiér valgte" name="checkbox copy selection"/>
- <check_box label="Centreret kopi" name="checkbox copy centers"/>
- <check_box label="Rotér" name="checkbox copy rotates"/>
- <check_box label="Vælg land" name="radio select land"/>
- <check_box label="Udflad" name="radio flatten"/>
- <check_box label="Hæv" name="radio raise"/>
- <check_box label="Sænk" name="radio lower"/>
- <check_box label="Udjævn" name="radio smooth"/>
- <check_box label="Gør ujævn" name="radio noise"/>
- <check_box label="Tilbagefør" name="radio revert"/>
- <button label="Gem" label_selected="Gem" name="button apply to selection" tool_tip="Redigér valgt land"/>
- <text name="Bulldozer:">
- Bulldozer:
+ <button label="" label_selected="" name="ToolCube" tool_tip="Terning" />
+ <button label="" label_selected="" name="ToolPrism" tool_tip="Prisme" />
+ <button label="" label_selected="" name="ToolPyramid" tool_tip="Pyramide" />
+ <button label="" label_selected="" name="ToolTetrahedron" tool_tip="Tetraed" />
+ <button label="" label_selected="" name="ToolCylinder" tool_tip="Cylinder" />
+ <button label="" label_selected="" name="ToolHemiCylinder" tool_tip="Hemicylinder" />
+ <button label="" label_selected="" name="ToolCone" tool_tip="Kegle" />
+ <button label="" label_selected="" name="ToolHemiCone" tool_tip="Hemikegle" />
+ <button label="" label_selected="" name="ToolSphere" tool_tip="Sfære" />
+ <button label="" label_selected="" name="ToolHemiSphere" tool_tip="Hemisfære" />
+ <button label="" label_selected="" name="ToolTorus" tool_tip="Kuglering" />
+ <button label="" label_selected="" name="ToolTube" tool_tip="Rør" />
+ <button label="" label_selected="" name="ToolRing" tool_tip="Ring" />
+ <button label="" label_selected="" name="ToolTree" tool_tip="Træ" />
+ <button label="" label_selected="" name="ToolGrass" tool_tip="Græs" />
+ <check_box label="Hold værktøjet valgt" name="checkbox sticky" />
+ <check_box label="Kopiér valgte" name="checkbox copy selection" />
+ <check_box label="Centreret kopi" name="checkbox copy centers" />
+ <check_box label="Rotér" name="checkbox copy rotates" />
+ <check_box label="Vælg" name="radio select land" />
+ <check_box label="Udflad" name="radio flatten" />
+ <check_box label="Hæv" name="radio raise" />
+ <check_box label="Sænk" name="radio lower" />
+ <check_box label="Udjævn" name="radio smooth" />
+ <check_box label="Gør ujævnt" name="radio noise" />
+ <check_box label="Tilbagefør" name="radio revert" />
+ <combo_box name="combobox brush size">
+ <combo_box.item name="Small" label="Lille"/>
+ <combo_box.item name ="Medium" label="Mellem"/>
+ <combo_box.item name="Large" label="Stor"/>
+ </combo_box>
+ <text type="string" length="1" name="Strength:">
+ Styrke:
</text>
<text name="Dozer Size:">
Størrelse
@@ -130,15 +128,9 @@
Pris: L$
</text>
<radio_group name="sale type">
- <radio_item name="Original">
- Original
- </radio_item>
- <radio_item name="Copy">
- Kopi
- </radio_item>
- <radio_item name="Contents">
- Indhold
- </radio_item>
+ <radio_item name="Original" label="Original" />
+ <radio_item name="Copy" label="Kopi" />
+ <radio_item name="Contents" label="Indhold" />
</radio_group>
<text name="Next owner can:">
Næste ejer kan:
@@ -150,27 +142,13 @@
NÃ¥r der venstreklikkes:
</text>
<combo_box name="clickaction">
- <combo_item name="Touch/grab(default)">
- Rør/tag (standard)
- </combo_item>
- <combo_item name="Sitonobject">
- Sid på objekt
- </combo_item>
- <combo_item name="Buyobject">
- Køb objekt
- </combo_item>
- <combo_item name="Payobject">
- Betal objekt
- </combo_item>
- <combo_item name="Open">
- Ã…ben
- </combo_item>
- <combo_item name="Play">
- Afspil medie på parcel
- </combo_item>
- <combo_item name="Opemmedia">
- Åben media på parcel
- </combo_item>
+ <combo_box.item name="Touch/grab(default)" label="Rør/tag (standard)"/>
+ <combo_box.item name="Sitonobject" label="Sid på objekt"/>
+ <combo_box.item name="Buyobject" label="Køb objekt"/>
+ <combo_box.item name="Payobject" label="Betal objekt"/>
+ <combo_box.item name="Open" label="Ã…ben"/>
+ <combo_box.item name="Play" label="Afspil medie på parcel"/>
+ <combo_box.item name="Opemmedia" label="Åben media på parcel"/>
</combo_box>
<text name="B:">
B:
@@ -254,56 +232,26 @@
Materiale
</text>
<combo_box name="material">
- <combo_item name="Stone">
- Sten
- </combo_item>
- <combo_item name="Metal">
- Metal
- </combo_item>
- <combo_item name="Glass">
- Glas
- </combo_item>
- <combo_item name="Wood">
- Træ
- </combo_item>
- <combo_item name="Flesh">
- Kød
- </combo_item>
- <combo_item name="Plastic">
- Plastik
- </combo_item>
- <combo_item name="Rubber">
- Gummi
- </combo_item>
+ <combo_box.item name="Stone" label="Sten"/>
+ <combo_box.item name="Metal" label="Metal"/>
+ <combo_box.item name="Glass" label="Glas"/>
+ <combo_box.item name="Wood" label="Træ"/>
+ <combo_box.item name="Flesh" label="Kød"/>
+ <combo_box.item name="Plastic" label="Plastik"/>
+ <combo_box.item name="Rubber" label="Gummi"/>
</combo_box>
<text name="label basetype">
Byggegeometrisk figur
</text>
<combo_box name="comboBaseType">
- <combo_item name="Box">
- Terning
- </combo_item>
- <combo_item name="Cylinder">
- Cylinder
- </combo_item>
- <combo_item name="Prism">
- Prisme
- </combo_item>
- <combo_item name="Sphere">
- Spfære
- </combo_item>
- <combo_item name="Torus">
- Kuglering
- </combo_item>
- <combo_item name="Tube">
- Rør
- </combo_item>
- <combo_item name="Ring">
- Ring
- </combo_item>
- <combo_item name="Sculpted">
- Sculpted
- </combo_item>
+ <combo_box.item name="Box" label="Terning"/>
+ <combo_box.item name="Cylinder" label="Cylinder"/>
+ <combo_box.item name="Prism" label="Prisme"/>
+ <combo_box.item name="Sphere" label="Spfære"/>
+ <combo_box.item name="Torus" label="Kuglering"/>
+ <combo_box.item name="Tube" label="Rør"/>
+ <combo_box.item name="Ring" label="Ring"/>
+ <combo_box.item name="Sculpted" label="Sculpted"/>
</combo_box>
<text name="text cut">
Snit begynd og slut
@@ -320,18 +268,10 @@
Form på hul
</text>
<combo_box name="hole">
- <combo_item name="Default">
- Standard
- </combo_item>
- <combo_item name="Circle">
- Cirkel
- </combo_item>
- <combo_item name="Square">
- Firkant
- </combo_item>
- <combo_item name="Triangle">
- Trekant
- </combo_item>
+ <combo_box.item name="Default" label="Standard"/>
+ <combo_box.item name="Circle" label="Cirkel"/>
+ <combo_box.item name="Square" label="Firkant"/>
+ <combo_box.item name="Triangle" label="Trekant"/>
</combo_box>
<text name="text twist">
Vrid begynd og slut
@@ -380,21 +320,11 @@
Sting type
</text>
<combo_box name="sculpt type control">
- <combo_item name="None">
- (ingen)
- </combo_item>
- <combo_item name="Sphere">
- Sfære
- </combo_item>
- <combo_item name="Torus">
- Kuglering
- </combo_item>
- <combo_item name="Plane">
- Plan
- </combo_item>
- <combo_item name="Cylinder">
- Cylinder
- </combo_item>
+ <combo_box.item name="None" label="ingen)"/>
+ <combo_box.item name="Sphere" label="Sfære"/>
+ <combo_box.item name="Torus" label="Kuglering"/>
+ <combo_box.item name="Plane" label="Plan"/>
+ <combo_box.item name="Cylinder" label="Cylinder"/>
</combo_box>
</panel>
<panel label="Features" name="Features">
@@ -438,88 +368,40 @@
Afbildning
</text>
<combo_box name="combobox texgen">
- <combo_item name="Default">
- Standard
- </combo_item>
- <combo_item name="Planar">
- Plan
- </combo_item>
+ <combo_box.item name="Default" label="Standard"/>
+ <combo_box.item name="Planar" label="Plan"/>
</combo_box>
<text name="label shininess">
Blankhed
</text>
<combo_box name="combobox shininess">
- <combo_item name="None">
- Ingen
- </combo_item>
- <combo_item name="Low">
- Lav
- </combo_item>
- <combo_item name="Medium">
- Mellem
- </combo_item>
- <combo_item name="High">
- Høj
- </combo_item>
+ <combo_box.item name="None" label="Ingen"/>
+ <combo_box.item name="Low" label="Lav"/>
+ <combo_box.item name="Medium" label="Mellem"/>
+ <combo_box.item name="High" label="Høj"/>
</combo_box>
<text name="label bumpiness">
Struktur
</text>
<combo_box name="combobox bumpiness">
- <combo_item name="None">
- Ingen
- </combo_item>
- <combo_item name="Brightness">
- Lysintensitet
- </combo_item>
- <combo_item name="Darkness">
- Mørke
- </combo_item>
- <combo_item name="woodgrain">
- træårer
- </combo_item>
- <combo_item name="bark">
- bark
- </combo_item>
- <combo_item name="bricks">
- mursten
- </combo_item>
- <combo_item name="checker">
- tern
- </combo_item>
- <combo_item name="concrete">
- beton
- </combo_item>
- <combo_item name="crustytile">
- rustik flise
- </combo_item>
- <combo_item name="cutstone">
- Skåret sten
- </combo_item>
- <combo_item name="discs">
- plader
- </combo_item>
- <combo_item name="gravel">
- grus
- </combo_item>
- <combo_item name="petridish">
- petriskål
- </combo_item>
- <combo_item name="siding">
- udvendig beklædning
- </combo_item>
- <combo_item name="stonetile">
- stenflise
- </combo_item>
- <combo_item name="stucco">
- puds
- </combo_item>
- <combo_item name="suction">
- rør
- </combo_item>
- <combo_item name="weave">
- væv
- </combo_item>
+ <combo_box.item name="None" label="Ingen"/>
+ <combo_box.item name="Brightness" label="Lysintensitet"/>
+ <combo_box.item name="Darkness" label="Mørke"/>
+ <combo_box.item name="woodgrain" label="træårer"/>
+ <combo_box.item name="bark" label="bark"/>
+ <combo_box.item name="bricks" label="mursten"/>
+ <combo_box.item name="checker" label="tern"/>
+ <combo_box.item name="concrete" label="beton"/>
+ <combo_box.item name="crustytile" label="rustik flise"/>
+ <combo_box.item name="cutstone" label="Skåret sten"/>
+ <combo_box.item name="discs" label="plader"/>
+ <combo_box.item name="gravel" label="grus"/>
+ <combo_box.item name="petridish" label="petriskål"/>
+ <combo_box.item name="siding" label="udvendig beklædning"/>
+ <combo_box.item name="stonetile" label="stenflise"/>
+ <combo_box.item name="stucco" label="puds"/>
+ <combo_box.item name="suction" label="rør"/>
+ <combo_box.item name="weave" label="væv"/>
</combo_box>
<text name="tex scale">
Gentagelser pr. overflade
diff --git a/indra/newview/skins/default/xui/da/floater_tos.xml b/indra/newview/skins/default/xui/da/floater_tos.xml
index 91a45afd18..9a348ca7bf 100644
--- a/indra/newview/skins/default/xui/da/floater_tos.xml
+++ b/indra/newview/skins/default/xui/da/floater_tos.xml
@@ -4,7 +4,7 @@
<button label="Annullér" label_selected="Annullér" name="Cancel" />
<check_box label="Jeg accepterer vilkårene for brug af tjenesten" name="agree_chk" />
<text name="tos_heading">
- Læs venligst de almindelige bestemmelser og vilkår igennem, for at fortsætte til Second Life
+ Læs venligst de almindelige bestemmelser og vilkår igennem, for at fortsætte til [SECOND_LIFE]
skal du acceptere vilkårene.
</text>
<text_editor name="tos_text">
diff --git a/indra/newview/skins/default/xui/da/floater_world_map.xml b/indra/newview/skins/default/xui/da/floater_world_map.xml
index 7b951b0b52..53c53dd707 100644
--- a/indra/newview/skins/default/xui/da/floater_world_map.xml
+++ b/indra/newview/skins/default/xui/da/floater_world_map.xml
@@ -28,14 +28,10 @@
<check_box label="Mature" name="event_mature_chk"/>
<check_box label="Adult" name="event_adult_chk"/>
<combo_box label="Venner online" name="friend combo" tool_tip="Ven der skal vises på kortet">
- <combo_item name="none_selected">
- Venner online
- </combo_item>
+ <combo_box.item name="none_selected" label="Venner online" />
</combo_box>
<combo_box label="Landemærker" name="landmark combo" tool_tip="Landemærke der skal vises på kortet">
- <combo_item name="none_selected">
- Landemærker
- </combo_item>
+ <combo_box.item name="none_selected" label="Landemærker" />
</combo_box>
<line_editor label="Søg på region navn" name="location" tool_tip="Skriv navnet på en region"/>
<button label="Søg" name="DoSearch" tool_tip="Søg efter en region"/>
@@ -56,6 +52,6 @@
<button label="Vis destination" label_selected="Vis destination" name="Show Destination" tool_tip="Centrér kortet på valgte lokation"/>
<button label="Slet" label_selected="Slet" name="Clear" tool_tip="Stop søg"/>
<button label="Vis min position" label_selected="Vis min position" name="Show My Location" tool_tip="Centrer kortet på din avatars lokation"/>
- <button label="Kopiér SLURL til udklipsholder" name="copy_slurl" tool_tip="Kopierer den nuværende lokation som et SLURL, så det kan bruges på nettet."/>
+ <button label="Kopiér SLurl til udklipsholder" name="copy_slurl" tool_tip="Kopierer den nuværende lokation som et SLurl, så det kan bruges på nettet."/>
<slider label="Zoom" name="zoom slider"/>
</floater>
diff --git a/indra/newview/skins/default/xui/da/language_settings.xml b/indra/newview/skins/default/xui/da/language_settings.xml
new file mode 100644
index 0000000000..71418d446a
--- /dev/null
+++ b/indra/newview/skins/default/xui/da/language_settings.xml
@@ -0,0 +1,55 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<!-- This file contains strings that used to be hardcoded in the source.-->
+<strings>
+
+ <!-- Locale Information -->
+ <string name="MicrosoftLocale">english</string>
+ <string name="DarwinLocale">C</string>
+ <string name="LinuxLocale">C</string>
+
+ <!--
+ datetimeToCodes["wkday"] = "%a"; // Thu
+ datetimeToCodes["weekday"] = "%A"; // Thursday
+ datetimeToCodes["year4"] = "%Y"; // 2009
+ datetimeToCodes["year"] = "%Y"; // 2009
+ datetimeToCodes["year2"] = "%y"; // 09
+ datetimeToCodes["mth"] = "%b"; // Aug
+ datetimeToCodes["month"] = "%B"; // August
+ datetimeToCodes["mthnum"] = "%m"; // 08
+ datetimeToCodes["day"] = "%d"; // 31
+ datetimeToCodes["hour24"] = "%H"; // 14
+ datetimeToCodes["hour"] = "%H"; // 14
+ datetimeToCodes["hour12"] = "%I"; // 02
+ datetimeToCodes["min"] = "%M"; // 59
+ datetimeToCodes["ampm"] = "%p"; // AM
+ datetimeToCodes["second"] = "%S"; // 59
+ datetimeToCodes["timezone"] = "%Z"; // PST
+ -->
+
+ <string name="TimeHour">hour,datetime,slt</string>
+ <string name="TimeMin">min,datetime,slt</string>
+ <string name="TimeYear">year,datetime,slt</string>
+ <string name="TimeDay">day,datetime,slt</string>
+ <string name="TimeMonth">mthnum,datetime,slt</string>
+ <string name="TimeWeek">wkday,datetime,slt</string>
+ <string name="TimeAMPM">ampm,datetime,slt</string>
+ <string name="TimeHour12">hour12,datetime,slt</string>
+
+ <string name="LTimeMthNum">mthnum,datetime,local</string>
+ <string name="LTimeWeek">wkday,datetime,local</string>
+ <string name="LTimeMonth">mth,datetime,local</string>
+ <string name="LTimeDay">day,datetime,local</string>
+ <string name="LTimeSec">second,datetime,local</string>
+ <string name="LTimeHour">hour,datetime,local</string>
+ <string name="LTimeMin">min,datetime,local</string>
+ <string name="LTimeYear">year,datetime,local</string>
+
+ <string name="UTCTimeWeek">weekday,datetime,utc</string>
+ <string name="UTCTimeDay">day,datetime,utc</string>
+ <string name="UTCTimeMth">mth,datetime,utc</string>
+ <string name="UTCTimeYr">year,datetime,utc</string>
+ <string name="UTCTimeHr">hour,datetime,utc</string>
+ <string name="UTCTimeMin">min,datetime,utc</string>
+ <string name="UTCTimeSec">second,datetime,utc</string>
+ <string name="UTCTimeTimezone">timezone,datetime,utc</string>
+</strings>
diff --git a/indra/newview/skins/default/xui/da/menu_login.xml b/indra/newview/skins/default/xui/da/menu_login.xml
index 26276ff3eb..9d9dcd4b2e 100644
--- a/indra/newview/skins/default/xui/da/menu_login.xml
+++ b/indra/newview/skins/default/xui/da/menu_login.xml
@@ -7,7 +7,7 @@
<menu_item_call label="Indstillinger..." name="Preferences..." />
</menu>
<menu label="Hjælp" name="Help">
- <menu_item_call label="Second Life hjælp" name="Second Life Help" />
- <menu_item_call label="Om Second Life..." name="About Second Life..." />
+ <menu_item_call label="[SECOND_LIFE] hjælp" name="Second Life Help" />
+ <menu_item_call label="Om [APP_NAME]..." name="About Second Life..." />
</menu>
</menu_bar>
diff --git a/indra/newview/skins/default/xui/da/menu_viewer.xml b/indra/newview/skins/default/xui/da/menu_viewer.xml
index 8bc99f27bf..6a75e27381 100644
--- a/indra/newview/skins/default/xui/da/menu_viewer.xml
+++ b/indra/newview/skins/default/xui/da/menu_viewer.xml
@@ -181,7 +181,7 @@
<menu_item_call label="Sæt scripts til &apos; Not running&apos; i valgte objekter" name="Set Scripts to Not Running in Selection"/>
</menu>
<menu label="Hjælp" name="Help">
- <menu_item_call label="Second Life Hjælp" name="Second Life Help"/>
+ <menu_item_call label="[SECOND_LIFE] Hjælp" name="Second Life Help"/>
<menu_item_call label="Tutorial" name="Tutorial"/>
<menu_item_separator label="-----------" name="separator"/>
<menu_item_call label="Officiel Linden Blog..." name="Official Linden Blog..."/>
@@ -193,8 +193,8 @@
<menu_item_call label="Lag meter" name="Lag Meter"/>
<menu_item_separator label="-----------" name="separator7"/>
<menu label="Fejlrapport" name="Bug Reporting">
- <menu_item_call label="Second Life sagsstyring..." name="Public Issue Tracker..."/>
- <menu_item_call label="Hjælp til Second Life sagsstyring..." name="Publc Issue Tracker Help..."/>
+ <menu_item_call label="[SECOND_LIFE] sagsstyring..." name="Public Issue Tracker..."/>
+ <menu_item_call label="Hjælp til [SECOND_LIFE] sagsstyring..." name="Publc Issue Tracker Help..."/>
<menu_item_separator label="-----------" name="separator7"/>
<menu_item_call label="Om fejlrapportering..." name="Bug Reporing 101..."/>
<menu_item_call label="Anmeld sikkerhedshændelser..." name="Security Issues..."/>
@@ -202,6 +202,6 @@
<menu_item_separator label="-----------" name="separator9"/>
<menu_item_call label="Anmeld fejl..." name="Report Bug..."/>
</menu>
- <menu_item_call label="Om Second Life..." name="About Second Life..."/>
+ <menu_item_call label="Om [APP_NAME]..." name="About Second Life..."/>
</menu>
</menu_bar>
diff --git a/indra/newview/skins/default/xui/da/notifications.xml b/indra/newview/skins/default/xui/da/notifications.xml
index 4963e8862d..d3e2ab83f2 100644
--- a/indra/newview/skins/default/xui/da/notifications.xml
+++ b/indra/newview/skins/default/xui/da/notifications.xml
@@ -6,6 +6,9 @@
<global name="alwayschoose">
Vælg altid dette
</global>
+ <global name="implicitclosebutton">
+ Luk
+ </global>
<template name="okbutton">
<form>
<button
@@ -71,7 +74,7 @@
</form>
</template>
<notification functor="GenericAcknowledge" label="Ukendt advarsels-besked" name="MissingAlert">
- Din version af Second Life kan ikke vise den advarselsbesked den modtog.
+ Din version af [APP_NAME] kan ikke vise den advarselsbesked den modtog.
Fejl detaljer: Advarslen &apos;[_NAME]&apos; blev ikke fundet i notifications.xml.
<usetemplate name="okbutton" yestext="OK"/>
@@ -94,7 +97,7 @@ Fejl detaljer: Advarslen &apos;[_NAME]&apos; blev ikke fundet i notifications.xm
<usetemplate name="okcancelbuttons" notext="Annullér" yestext="Ja"/>
</notification>
<notification name="BadInstallation">
- Der opstod en fejl ved opdatering af Second Life. Hent venligst den nyeste version fra secondlife.com.
+ Der opstod en fejl ved opdatering af [APP_NAME]. Hent venligst den nyeste version fra secondlife.com.
<usetemplate
name="okbutton"
yestext="OK"/>
@@ -250,7 +253,7 @@ Du har brug for en konto for at logge ind i [SECOND_LIFE]. Vil du oprette en nu?
<usetemplate name="okcancelbuttons" notext="Annullér" yestext="OK"/>
</notification>
<notification name="ChangeSkin">
- Det nye udseende vil vises efter du har genstartet [SECOND_LIFE].
+ Det nye udseende vil vises efter du har genstartet [APP_NAME].
</notification>
<notification name="UnsupportedHardware"/>
<notification name="UnknownGPU">
@@ -328,7 +331,7 @@ Grå = Offentligt ejet
<notification name="YouHaveBeenLoggedOut">
Du er blevet logget ud af [SECOND_LIFE]:
[MESSAGE]
-Du kan stadig se eksiterende PB&apos;er og chat ved at klikke&apos;Se PB &amp; Chat&apos;. Ellers, klik &apos;Afslut&apos; for at afslutte [SECOND_LIFE] nu.
+Du kan stadig se eksiterende PB&apos;er og chat ved at klikke&apos;Se PB &amp; Chat&apos;. Ellers, klik &apos;Afslut&apos; for at afslutte [APP_NAME] nu.
<usetemplate name="okcancelbuttons" notext="Afslut" yestext="Se PB &amp; Chat"/>
</notification>
<notification label="Tilføj ven" name="AddFriend">
@@ -372,7 +375,7 @@ Tilbyd venskab til [NAME]?
<notification name="RegionEntryAccessBlocked">
Du har ikke adgang til denne region på grund af din valgte indholdsrating. Dette kan skyldes manglende validering af din alder.
-Undersøg venligst om du har installeret den nyeste Second Life klient, og gå til &apos;Knowledge Base&apos; for yderligere detaljer om adgang til områder med denne indholdsrating.
+Undersøg venligst om du har installeret den nyeste [APP_NAME] klient, og gå til &apos;Knowledge Base&apos; for yderligere detaljer om adgang til områder med denne indholdsrating.
<usetemplate
name="okbutton"
yestext="OK"/>
@@ -410,7 +413,7 @@ Du kan vælge &apos;Indstillinger&apos; for at hæve din indholdsrating nu og de
<notification name="LandClaimAccessBlocked">
Du kan ikke kræve dette land på grund af din nuværende indholdsrating indstillinge . Dette kan skyldes manglende validering af din alder.
-Undersøg om du har den nyeste Second Life klient og gå venligst til &apos;Knowledge Base&apos; for yderligere detaljer om adgang til områder med denne indholdsrating.
+Undersøg om du har den nyeste [APP_NAME] klient og gå venligst til &apos;Knowledge Base&apos; for yderligere detaljer om adgang til områder med denne indholdsrating.
<usetemplate
name="okbutton"
yestext="OK"/>
@@ -444,7 +447,7 @@ Du kan vælge &apos;Indstillinger&apos; for at hæve din indholdsrating nu og de
<notification name="LandBuyAccessBlocked">
Du kan ikke købe dette land på grund af din nuværende indholdsrating indstillinge . Dette kan skyldes manglende validering af din alder.
-Undersøg om du har den nyeste Second Life klient og gå venligst til &apos;Knowledge Base&apos; for yderligere detaljer om adgang til områder med denne indholdsrating.
+Undersøg om du har den nyeste [APP_NAME] klient og gå venligst til &apos;Knowledge Base&apos; for yderligere detaljer om adgang til områder med denne indholdsrating.
<usetemplate
name="okbutton"
yestext="OK"/>
@@ -515,9 +518,9 @@ http://secondlife.com/support/incidentreport.php
Du ser ud til at være ved at rapportere noget vedr. krænkelse af intellektuelle ejendomsrettigheder. Sørg for, at du rapporterer dette korrekt:
-(1) Misbrugs processen. Du kan indsende en misbrugs rapport, hvis du mener, at en Beboer udnytter Second Life&apos;s rettigheds system, for eksempel ved hjælp af en CopyBot eller lignende kopierings værktøjer, at de krænker intellektuelle ejendomsrettigheder. Det team vil undersøge og spørgsmål passende disciplinære sanktioner for adfærd, der overtræder Second Life EF-standarderne eller Servicevilkår. Men det team vil ikke håndtere og vil ikke reagere på anmodninger om at fjerne indhold fra Second Life&apos;s verden.
+(1) Misbrugs processen. Du kan indsende en misbrugs rapport, hvis du mener, at en Beboer udnytter [SECOND_LIFE]&apos;s rettigheds system, for eksempel ved hjælp af en CopyBot eller lignende kopierings værktøjer, at de krænker intellektuelle ejendomsrettigheder. Det team vil undersøge og spørgsmål passende disciplinære sanktioner for adfærd, der overtræder [SECOND_LIFE] EF-standarderne eller Servicevilkår. Men det team vil ikke håndtere og vil ikke reagere på anmodninger om at fjerne indhold fra [SECOND_LIFE]&apos;s verden.
-(2) DMCA eller Indholds fjernelses processen. For at anmode om fjernelse af indhold fra Second Life, skal du sende en gyldig anmeldelse af overtrædelsen som beskrevet i vores DMCA-politik på http://secondlife.com/corporate/dmca.php.
+(2) DMCA eller Indholds fjernelses processen. For at anmode om fjernelse af indhold fra [SECOND_LIFE], skal du sende en gyldig anmeldelse af overtrædelsen som beskrevet i vores DMCA-politik på http://secondlife.com/corporate/dmca.php.
Hvis du stadig ønsker at fortsætte med misbrugs processen, luk da venligst dette vindue og færdiggør indsendelsen af din rapport. Du kan være nødt til at vælge den særlige kategori »CopyBot eller Tilladelses Ydnyttelse.
@@ -789,7 +792,7 @@ Ingen scripts vil køre på nær dem, som tilhører ejeren af landet.
Du kan kun gøre krav på offentlig land i den region, du befinder dig i.
</notification>
<notification name="RegionTPAccessBlocked">
- Du har ikke adgang til denne region på grund af din valgte indholdsrating. Dette kan skyldes manglende validering af din alder eller at du ikke benytter den nyeste Second Life klient.
+ Du har ikke adgang til denne region på grund af din valgte indholdsrating. Dette kan skyldes manglende validering af din alder eller at du ikke benytter den nyeste [APP_NAME] klient.
Gå venligst til &apos;Knowledge Base&apos; for yderligere detaljer om adgang til områder med denne indholdsrating.
</notification>
@@ -856,13 +859,13 @@ Prøv igen om lidt.
Kunne ikke skabe fast forbindelse.
</notification>
<notification name="InternalUsherError">
- Der opstod en intern fejl ved teleportering til din teleport destination.. Der kan være generelle problemer med Second Life lige nu.
+ Der opstod en intern fejl ved teleportering til din teleport destination.. Der kan være generelle problemer med [SECOND_LIFE] lige nu.
</notification>
<notification name="NoGoodTPDestination">
Kunne ikke finde et egnet teleport sted i denne region.
</notification>
<notification name="InternalErrorRegionResolver">
- Der opstod en intern fejl ved beregning af globale koordinater for din teleport forespørgsel. Der kan være generelle problemer med Second Life lige nu.
+ Der opstod en intern fejl ved beregning af globale koordinater for din teleport forespørgsel. Der kan være generelle problemer med [SECOND_LIFE] lige nu.
</notification>
<notification name="NoValidLanding">
Kunne ikke finde et gyldigt landingspunkt.
@@ -972,7 +975,7 @@ Fra genstand: [OBJECTNAME], ejer: [NAME]?
Det lykkedes ikke at finde [TYPE] med navnet [DESC] i databasen.
</notification>
<notification name="InvalidWearable">
- Den genstand du prøver at tage på benytter funktioner som din klient ikke kan forstå. Opdatér din version af Second Life for at tage genstanden på.
+ Den genstand du prøver at tage på benytter funktioner som din klient ikke kan forstå. Opdatér din version af [APP_NAME] for at tage genstanden på.
</notification>
<notification name="ScriptQuestion">
&apos;[OBJECTNAME]&apos;, en genstand, ejet af &apos;[NAME]&apos;, vil gerne:
@@ -1075,8 +1078,8 @@ Fleksible genstande er ikke fysiske og man kan gå igennem dem, indtil fleksibel
</notification>
<notification name="FirstDebugMenus">
Du har sat avanceret menu til.
-Denne menu indeholder funktioner brugbare for udviklere, der udbedrer fejl i Second Life.
-For at vise denne menu, skal man i Windows trykke Ctrl-Alt-D. PÃ¥ Mac tryk Cmd-Opt-Shift-D.
+Denne menu indeholder funktioner brugbare for udviklere, der udbedrer fejl i [SECOND_LIFE].
+For at vise denne menu, skal man i Windows trykke Ctrl-Alt-D. PÃ¥ Mac tryk &#8984;-Opt-Shift-D.
</notification>
<notification name="FirstSculptedPrim">
Du retter en sculpted prim.
diff --git a/indra/newview/skins/default/xui/da/panel_login.xml b/indra/newview/skins/default/xui/da/panel_login.xml
index 48d58ae8f7..6f02778264 100644
--- a/indra/newview/skins/default/xui/da/panel_login.xml
+++ b/indra/newview/skins/default/xui/da/panel_login.xml
@@ -19,15 +19,9 @@
Start lokation:
</text>
<combo_box name="start_location_combo">
- <combo_item name="MyHome">
- Hjem
- </combo_item>
- <combo_item name="MyLastLocation">
- Min sidste lokation
- </combo_item>
- <combo_item name="Typeregionname">
- &lt;Skriv navn på region&gt;
- </combo_item>
+ <combo_box.item name="MyHome" label="Hjem" />
+ <combo_box.item name="MyLastLocation" label="Min sidste lokation" />
+ <combo_box.item name="Typeregionname" label="lt;Skriv navn på region&gt;" />
</combo_box>
<check_box label="Husk password" name="remember_check" />
<button label="Log ind" label_selected="Log ind" name="connect_btn" />
diff --git a/indra/newview/skins/default/xui/da/panel_preferences_chat.xml b/indra/newview/skins/default/xui/da/panel_preferences_chat.xml
index 254cd6ddb9..e57b151511 100644
--- a/indra/newview/skins/default/xui/da/panel_preferences_chat.xml
+++ b/indra/newview/skins/default/xui/da/panel_preferences_chat.xml
@@ -4,15 +4,9 @@
Chat skriftstørrelse:
</text>
<radio_group name="chat_font_size">
- <radio_item type="string" length="1" name="radio">
- Lille
- </radio_item>
- <radio_item type="string" length="1" name="radio2">
- Mellem
- </radio_item>
- <radio_item type="string" length="1" name="radio3">
- Stor
- </radio_item>
+ <radio_item type="string" length="1" name="radio" label="Lille" />
+ <radio_item type="string" length="1" name="radio2" label="Mellem" />
+ <radio_item type="string" length="1" name="radio3" label="Stor" />
</radio_group>
<text type="string" length="1" name="text_box2">
Chat farve:
diff --git a/indra/newview/skins/default/xui/da/panel_preferences_general.xml b/indra/newview/skins/default/xui/da/panel_preferences_general.xml
index bb8bea6580..df27d05643 100644
--- a/indra/newview/skins/default/xui/da/panel_preferences_general.xml
+++ b/indra/newview/skins/default/xui/da/panel_preferences_general.xml
@@ -1,24 +1,14 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<panel label="Generelt" name="general_panel">
<radio_group name="default_start_location">
- <radio_item name="MyHome" tool_tip="Log ind til min hjemme lokation som standard.">
- Mit hjem
- </radio_item>
- <radio_item name="MyLastLocation" tool_tip="Log ind til min sidste lokation som standard.">
- Min sidste lokation
- </radio_item>
+ <radio_item name="MyHome" tool_tip="Log ind til min hjemme lokation som standard." label="Mit hjem" />
+ <radio_item name="MyLastLocation" tool_tip="Log ind til min sidste lokation som standard." label="Min sidste lokation" />
</radio_group>
<check_box label="Vis start lokation på login billedet" name="show_location_checkbox"/>
<combo_box name="fade_out_combobox">
- <combo_item name="Never">
- Aldrig
- </combo_item>
- <combo_item name="Show Temporarily">
- Vis midlertidigt
- </combo_item>
- <combo_item name="Always">
- Altid
- </combo_item>
+ <combo_box.item name="Never" label="Aldrig"/>
+ <combo_box.item name="Show Temporarily" label="Vis midlertidigt"/>
+ <combo_box.item name="Always" label="Altid"/>
</combo_box>
<check_box label="Små avatar navne" name="small_avatar_names_checkbox"/>
<check_box label="Skjul mit navn på min skærm" name="show_my_name_checkbox"/>
@@ -79,68 +69,23 @@
&lt;Skriv regions navn&gt;
</string>
<combo_box name="crash_behavior_combobox">
- <combo_item length="1" name="Askbeforesending" type="string">
- Bed om bekræftigelse
- </combo_item>
- <combo_item length="1" name="Alwayssend" type="string">
- Send altid
- </combo_item>
- <combo_item length="1" name="Neversend" type="string">
- Send aldrig
- </combo_item>
+ <combo_box.item type="string" length="1" name="Askbeforesending" label="Bed om bekræftigelse"/>
+ <combo_box.item type="string" length="1" name="Alwayssend" label="Send altid"/>
+ <combo_box.item type="string" length="1" name="Neversend" label="Send aldrig"/>
</combo_box>
<combo_box name="language_combobox">
- <combo_item length="1" name="System Default Language" type="string">
- System standard
- </combo_item>
- <combo_item length="1" name="English" type="string">
- English (Engelsk)
- </combo_item>
- <combo_item length="1" name="Danish" type="string">
- Dansk - Beta
- </combo_item>
- <combo_item length="1" name="Deutsch(German)" type="string">
- Deutsch (Tysk) - Beta
- </combo_item>
- <combo_item length="1" name="Spanish" type="string">
- Español (Spansk) - Beta
- </combo_item>
- <combo_item length="1" name="French" type="string">
- Français (Fransk) - Beta
- </combo_item>
- <combo_item name="Italian">
- Italiano (Italiensk) - Beta
- </combo_item>
- <combo_item length="1" name="Hungarian" type="string">
- Magyar (Ungarsk) - Beta
- </combo_item>
- <combo_item name="Dutch">
- Nederlands (Hollandsk) - Beta
- </combo_item>
- <combo_item length="1" name="Polish" type="string">
- Polski (Polsk) - Beta
- </combo_item>
- <combo_item length="1" name="Portugese" type="string">
- Portugués (Portugisisk) - Beta
- </combo_item>
- <combo_item name="Russian">
- РуÑÑкий (Russisk) - Beta
- </combo_item>
- <combo_item name="Turkish">
- Türkçe (Tyrkisk) - Beta
- </combo_item>
- <combo_item name="Ukrainian">
- УкраїнÑька (Ukrainsk) - Beta
- </combo_item>
- <combo_item length="1" name="Chinese" type="string">
- 中文 (简体) (Kinesisk) - Beta
- </combo_item>
- <combo_item length="1" name="(Japanese)" type="string">
- 日本語 (Japansk) - Beta
- </combo_item>
- <combo_item length="1" name="(Korean)" type="string">
- 한국어 (Koreansk) - Beta
- </combo_item>
+ <combo_box.item type="string" length="1" name="System Default Language" label="System standard"/>
+ <combo_box.item type="string" length="1" name="English" label="English (Engelsk)"/>
+ <combo_box.item type="string" length="1" name="Danish" label="Dansk - Beta"/>
+ <combo_box.item type="string" length="1" name="Deutsch(German)" label="Deutsch (Tysk) - Beta"/>
+ <combo_box.item type="string" length="1" name="Spanish" label="Español (Spansk) - Beta"/>
+ <combo_box.item type="string" length="1" name="French" label="Français (Fransk) - Beta"/>
+ <combo_box.item type="string" length="1" name="Hungarian" label="Magyar (Ungarsk) - Beta"/>
+ <combo_box.item type="string" length="1" name="Polish" label="Polski (Polsk) - Beta"/>
+ <combo_box.item type="string" length="1" name="Portugese" label="Portugués (Portugisisk) - Beta"/>
+ <combo_box.item type="string" length="1" name="Chinese" label="中文 (简体) (Kinesisk) - Beta"/>
+ <combo_box.item type="string" length="1" name="(Japanese)" label="日本語 (Japansk) - Beta"/>
+ <combo_box.item type="string" length="1" name="(Korean)" label="한국어 (Koreansk) - Beta"/>
</combo_box>
<check_box label="Del sprog med objekter" name="language_is_public" tool_tip="Dette lader objekter i verden vide hvad dit foretrukne sprog er."/>
</panel>
diff --git a/indra/newview/skins/default/xui/da/panel_preferences_graphics1.xml b/indra/newview/skins/default/xui/da/panel_preferences_graphics1.xml
index 5ebab1778f..86c506a0fd 100644
--- a/indra/newview/skins/default/xui/da/panel_preferences_graphics1.xml
+++ b/indra/newview/skins/default/xui/da/panel_preferences_graphics1.xml
@@ -9,21 +9,11 @@
Opløsning:
</text>
<combo_box name="windowsize combo">
- <combo_item type="string" length="1" name="640x480">
- 640x480
- </combo_item>
- <combo_item type="string" length="1" name="800x600">
- 800x600
- </combo_item>
- <combo_item type="string" length="1" name="720x480">
- 720x480 (NTSC)
- </combo_item>
- <combo_item type="string" length="1" name="768x576">
- 768x576 (PAL)
- </combo_item>
- <combo_item type="string" length="1" name="1024x768">
- 1024x768
- </combo_item>
+ <combo_box.item type="string" length="1" name="640x480" label="640x480" />
+ <combo_box.item type="string" length="1" name="800x600" label="800x600" />
+ <combo_box.item type="string" length="1" name="720x480" label="720x480 (NTSC)" />
+ <combo_box.item type="string" length="1" name="768x576" label="768x576 (PAL)" />
+ <combo_box.item type="string" length="1" name="1024x768" label="1024x768" />
</combo_box>
<text type="string" length="1" name="DisplayResLabel">
Skærm opløsning:
@@ -32,18 +22,10 @@
Format:
</text>
<combo_box name="aspect_ratio" tool_tip="bredde/ højde">
- <combo_item type="string" length="1" name="4:3(StandardCRT)">
- 4:3 (Standard CRT)
- </combo_item>
- <combo_item type="string" length="1" name="5:4(1280x1024LCD)">
- 5:4 (1280x1024 LCD)
- </combo_item>
- <combo_item type="string" length="1" name="8:5(Widescreen)">
- 8:5 (Widescreen)
- </combo_item>
- <combo_item type="string" length="1" name="16:9(Widescreen)">
- 16:9 (Widescreen)
- </combo_item>
+ <combo_box.item type="string" length="1" name="4:3(StandardCRT)" label="4:3 (Standard CRT)" />
+ <combo_box.item type="string" length="1" name="5:4(1280x1024LCD)" label="5:4 (1280x1024 LCD)" />
+ <combo_box.item type="string" length="1" name="8:5(Widescreen)" label="8:5 (Widescreen)" />
+ <combo_box.item type="string" length="1" name="16:9(Widescreen)" label="16:9 (Widescreen)" />
</combo_box>
<check_box label="Auto-detect format" name="aspect_auto_detect" />
<text type="string" length="1" name="HigherText">
@@ -87,18 +69,10 @@
Spejlnings detaljer:
</text>
<radio_group name="ReflectionDetailRadio">
- <radio_item type="string" length="1" name="0">
- Terræn og træer
- </radio_item>
- <radio_item type="string" length="1" name="1">
- Alle statiske objekter
- </radio_item>
- <radio_item type="string" length="1" name="2">
- Alle avatarer og objekter
- </radio_item>
- <radio_item type="string" length="1" name="3">
- Alt
- </radio_item>
+ <radio_item type="string" length="1" name="0" label="Terræn og træer" />
+ <radio_item type="string" length="1" name="1" label="Alle statiske objekter" />
+ <radio_item type="string" length="1" name="2" label="Alle avatarer og objekter" />
+ <radio_item type="string" length="1" name="3" label="Alt" />
</radio_group>
<text type="string" length="1" name="AvatarRenderingText">
Avatar gengivelse
@@ -149,23 +123,15 @@
Lys detaljer:
</text>
<radio_group name="LightingDetailRadio">
- <radio_item type="string" length="1" name="SunMoon">
- Kun sol og måne
- </radio_item>
- <radio_item type="string" length="1" name="LocalLights">
- Lys i nærheden
- </radio_item>
+ <radio_item type="string" length="1" name="SunMoon" label="Kun sol og måne" />
+ <radio_item type="string" length="1" name="LocalLights" label="Lys i nærheden" />
</radio_group>
<text type="string" length="1" name="TerrainDetailText">
Terræn detaljer:
</text>
<radio_group name="TerrainDetailRadio">
- <radio_item type="string" length="1" name="0">
- Lav
- </radio_item>
- <radio_item type="string" length="1" name="2">
- Høj
- </radio_item>
+ <radio_item type="string" length="1" name="0" label="Lav" />
+ <radio_item type="string" length="1" name="2" label="Høj" />
</radio_group>
<button label="Anbefalede indstillinger" name="Defaults" />
<button label="Hardware valg" label_selected="Hardware Options"
diff --git a/indra/newview/skins/default/xui/da/panel_status_bar.xml b/indra/newview/skins/default/xui/da/panel_status_bar.xml
index 7bc66b1101..c286960334 100644
--- a/indra/newview/skins/default/xui/da/panel_status_bar.xml
+++ b/indra/newview/skins/default/xui/da/panel_status_bar.xml
@@ -8,7 +8,7 @@
Henter...
</text>
<button label="" label_selected="" name="buycurrency" tool_tip="Køb valuta" />
- <text type="string" length="12" name="TimeText" tool_tip="Nuværende Second Life tid">
+ <text type="string" length="12" name="TimeText" tool_tip="Nuværende [SECOND_LIFE] tid">
12:00
</text>
<string name="StatBarDaysOfWeek">
@@ -33,8 +33,8 @@
tool_tip="Stemme chat ikke tilgængelig" />
<button label="" label_selected="" name="buyland" tool_tip="Køb denne parcel" />
<button label="" name="menubar_search_bevel_bg" />
- <line_editor label="Søg" name="search_editor" tool_tip="Søg Second Life" />
- <button label="" label_selected="" name="search_btn" tool_tip="Søg Second Life" />
+ <line_editor label="Søg" name="search_editor" tool_tip="Søg [SECOND_LIFE]" />
+ <button label="" label_selected="" name="search_btn" tool_tip="Søg [SECOND_LIFE]" />
<string name="packet_loss_tooltip">
Packet Loss
</string>
diff --git a/indra/newview/skins/default/xui/da/strings.xml b/indra/newview/skins/default/xui/da/strings.xml
index 79ebbc3324..c039e2e1c5 100644
--- a/indra/newview/skins/default/xui/da/strings.xml
+++ b/indra/newview/skins/default/xui/da/strings.xml
@@ -182,7 +182,7 @@
Forbindelsen mistet
</string>
<string name="AssetErrorPriceMismatch">
- Second Life klient og server er uenige om prisen
+ [APP_NAME] klient og server er uenige om prisen
</string>
<string name="AssetErrorUnknownStatus">
Ukendt status
diff --git a/indra/newview/skins/default/xui/de/floater_about.xml b/indra/newview/skins/default/xui/de/floater_about.xml
index 28785c6786..340b90d802 100644
--- a/indra/newview/skins/default/xui/de/floater_about.xml
+++ b/indra/newview/skins/default/xui/de/floater_about.xml
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
-<floater name="floater_about" title="Ãœber Second Life">
+<floater name="floater_about" title="Ãœber [APP_NAME]">
<text_editor name="credits_editor">
Second Life wird Ihnen präsentiert von Philip, Tessa, Andrew, Cory, James, Ben, Char, Charlie, Colin, Dan, Daniel, Doug, Eric, Hamlet, Haney, Eve, Hunter, Ian, Jeff, Jennifer, Jim, John, Lee, Mark, Peter, Phoenix, Richard, Robin, Xenon, Steve, Tanya, Eddie, Avi, Frank, Bruce, Aaron, Alice, Bob, Debra, Eileen, Helen, Janet, Louie, Leviathania, Stefan, Ray, Kevin, Tom, Mikeb, MikeT, Burgess, Elena, Tracy, Bill, Todd, Ryan, Zach, Sarah, Nova, Tim, Stephanie, Michael, Evan, Nicolas, Catherine, Rachelle, Dave, Holly, Bub, Kelly, Magellan, Ramzi, Don, Sabin, Jill, Rheya, Jeska, Torley, Kona, Callum, Charity, Ventrella, Jack, Vektor, Iris, Chris, Nicole, Mick, Reuben, Blue, Babbage, Yedwab, Deana, Lauren, Brent, Pathfinder, Chadrick, Altruima, Jesse, Teeny, Monroe, Icculus, David, Tess, Lizzie, Patsy, Isaac, Lawrence, Cyn, Bo, Gia, Annette, Marius, Tbone, Jonathan, Karen, Ginsu, Satoko, Yuko, Makiko, Thomas, Harry, Seth, Alexei, Brian, Guy, Runitai, Ethan, Data, Cornelius, Kenny, Swiss, Zero, Natria, Wendy, Stephen, Teeple, Thumper, Lucy, Dee, Mia, Liana, Warren, Branka, Aura, beez, Milo, Hermia, Red, Thrax, Joe, Sally, Magenta, Mogura, Paul, Jose, Rejean, Henrik, Lexie, Amber, Logan, Xan, Nora, Morpheus, Donovan, Leyla, MichaelFrancis, Beast, Cube, Bucky, Joshua, Stryfe, Harmony, Teresa, Claudia, Walker, Glenn, Fritz, Fordak, June, Cleopetra, Jean, Ivy, Betsy, Roosevelt, Spike, Ken, Which, Tofu, Chiyo, Rob, Zee, dustin, George, Del, Matthew, Cat, Jacqui, Lightfoot, Adrian, Viola, Alfred, Noel, Irfan, Sunil, Yool, Rika, Jane, Xtreme, Frontier, a2, Neo, Siobhan, Yoz, Justin, Elle, Qarl, Benjamin, Isabel, Gulliver, Everett, Christopher, Izzy, Stephany, Garry, Sejong, Sean, Tobin, Iridium, Meta, Anthony, Jeremy, JP, Jake, Maurice, Madhavi, Leopard, Kyle, Joon, Kari, Bert, Belinda, Jon, Kristi, Bridie, Pramod, KJ, Socrates, Maria, Ivan, Aric, Yamasaki, Adreanne, Jay, MitchK, Ceren, Coco, Durl, Jenny, Periapse, Kartic, Storrs, Lotte, Sandy, Rohn, Colossus, Zen, BigPapi, Brad, Pastrami, Kurz, Mani, Neuro, Jaime, MJ, Rowan, Sgt, Elvis, Gecko, Samuel, Sardonyx, Leo, Bryan, Niko, Soft, Poppy, Rachel, Aki, Angelo, Banzai, Alexa, Sue, CeeLo, Bender, CG, Gillian, Pelle, Nick, Echo, Zara, Christine, Shamiran, Emma, Blake, Keiko, Plexus, Joppa, Sidewinder, Erica, Ashlei, Twilight, Kristen, Brett, Q, Enus, Simon, Bevis, Kraft, Kip, Chandler, Ron, LauraP, Ram, KyleJM, Scouse, Prospero, Melissa, Marty, Nat, Hamilton, Kend, Lordan, Jimmy, Kosmo, Seraph, Green, Ekim, Wiggo, JT, Rome, Doris, Miz, Benoc, Whump, Trinity, Patch, Kate, TJ, Bao, Joohwan, Christy, Sofia, Matias, Cogsworth, Johan, Oreh, Cheah, Angela, Brandy, Mango, Lan, Aleks, Gloria, Heidy, Mitchell, Space, Colton, Bambers, Einstein, Maggie, Malbers, Rose, Winnie, Stella, Milton, Rothman, Niall, Marin, Allison, Katie, Dawn, Katt, Dusty, Kalpana, Judy, Andrea, Ambroff, Infinity, Gail, Rico, Raymond, Yi, William, Christa, M, Teagan, Scout, Molly, Dante, Corr, Dynamike, Usi, Kaylee, Vidtuts, Lil, Danica, Sascha, Kelv, Jacob, Nya, Rodney, Brandon, Elsie, Blondin, Grant, Katrin, Nyx, Gabriel, Locklainn, Claire, Devin, Minerva, Monty, Austin, Bradford, Si, Keira, H, Caitlin, Dita, Makai, Jenn, Ann, Meredith, Clare, Joy, Praveen, Cody, Edmund, Ruthe, Sirena, Gayathri, Spider, FJ, Davidoff, Tian, Jennie, Louise, Oskar, Landon, Noelle, Jarv, Ingrid, Al, Sommer, Doc, Aria, Huin, Gray, Lili, Vir, DJ, Yang, T, Simone, Maestro, Scott, Charlene, Quixote, Amanda, Susan, Zed, Anne, Enkidu, Esbee, Joroan, Katelin, Roxie, Tay, Scarlet, Kevin, Johnny, Wolfgang, Andren, Bob, Howard, Merov, Rand, Ray, Michon, Newell, Galen, Dessie, Les, Michon, Jenelle, Geo, Siz, Shapiro, Pete, Calyle, Selene, Allen, Phoebe, Goldin, Kimmora, Dakota, Slaton, Lindquist, Zoey, Hari, Othello, Rohit, Sheldon, Petra, Viale, Gordon, Kaye, Pink, Ferny, Emerson, Davy, Bri, Chan, Juan, Robert, Terrence, Nathan, Carl und vielen anderen.
diff --git a/indra/newview/skins/default/xui/de/floater_animation_preview.xml b/indra/newview/skins/default/xui/de/floater_animation_preview.xml
index 299b6a7f7e..fbd03ab3d7 100644
--- a/indra/newview/skins/default/xui/de/floater_animation_preview.xml
+++ b/indra/newview/skins/default/xui/de/floater_animation_preview.xml
@@ -15,127 +15,53 @@
Handhaltung
</text>
<combo_box label="" name="hand_pose_combo" tool_tip="Steuert während der Animation die Bewegung der Hände.">
- <combo_item name="Spread">
- Dehnen
- </combo_item>
- <combo_item name="Relaxed">
- Entspannt
- </combo_item>
- <combo_item name="PointBoth">
- Beide zeigen
- </combo_item>
- <combo_item name="Fist">
- Faust
- </combo_item>
- <combo_item name="RelaxedLeft">
- Links entspannt
- </combo_item>
- <combo_item name="PointLeft">
- Nach links zeigen
- </combo_item>
- <combo_item name="FistLeft">
- Linke Faust
- </combo_item>
- <combo_item name="RelaxedRight">
- Rechts entspannt
- </combo_item>
- <combo_item name="PointRight">
- Nach rechts zeigen
- </combo_item>
- <combo_item name="FistRight">
- Rechte Faust
- </combo_item>
- <combo_item name="SaluteRight">
- Rechts salutieren
- </combo_item>
- <combo_item name="Typing">
- Tippt
- </combo_item>
- <combo_item name="PeaceRight">
- Friedensrecht
- </combo_item>
+ <combo_box.item name="Spread" label="Dehnen" />
+ <combo_box.item name="Relaxed" label="Entspannt" />
+ <combo_box.item name="PointBoth" label="Beide zeigen" />
+ <combo_box.item name="Fist" label="Faust" />
+ <combo_box.item name="RelaxedLeft" label="Links entspannt" />
+ <combo_box.item name="PointLeft" label="Nach links zeigen" />
+ <combo_box.item name="FistLeft" label="Linke Faust" />
+ <combo_box.item name="RelaxedRight" label="Rechts entspannt" />
+ <combo_box.item name="PointRight" label="Nach rechts zeigen" />
+ <combo_box.item name="FistRight" label="Rechte Faust" />
+ <combo_box.item name="SaluteRight" label="Rechts salutieren" />
+ <combo_box.item name="Typing" label="Tippt" />
+ <combo_box.item name="PeaceRight" label="Friedensrecht" />
</combo_box>
<text name="emote_label">
Ausdruck
</text>
<combo_box label="" name="emote_combo" tool_tip="Steuert Gesichtsregungen während der Animation.">
- <combo_item name="[None]">
- [Keine]
- </combo_item>
- <combo_item name="Aaaaah">
- Aaaaah
- </combo_item>
- <combo_item name="Afraid">
- Ängstlich
- </combo_item>
- <combo_item name="Angry">
- Verärgert
- </combo_item>
- <combo_item name="BigSmile">
- Grinst
- </combo_item>
- <combo_item name="Bored">
- Gelangweilt
- </combo_item>
- <combo_item name="Cry">
- Weinen
- </combo_item>
- <combo_item name="Disdain">
- Verachten
- </combo_item>
- <combo_item name="Embarrassed">
- Verlegen
- </combo_item>
- <combo_item name="Frown">
- Stirnrunzeln
- </combo_item>
- <combo_item name="Kiss">
- Küssen
- </combo_item>
- <combo_item name="Laugh">
- Lachen
- </combo_item>
- <combo_item name="Plllppt">
- Bäääh
- </combo_item>
- <combo_item name="Repulsed">
- Zurückgestoßen
- </combo_item>
- <combo_item name="Sad">
- Traurig
- </combo_item>
- <combo_item name="Shrug">
- Schulterzucken
- </combo_item>
- <combo_item name="Smile">
- Lächeln
- </combo_item>
- <combo_item name="Surprise">
- Ãœberraschung
- </combo_item>
- <combo_item name="Wink">
- Zwinkern
- </combo_item>
- <combo_item name="Worry">
- Sorgenvoll
- </combo_item>
+ <combo_box.item name="[None]" label="Keine]" />
+ <combo_box.item name="Aaaaah" label="Aaaaah" />
+ <combo_box.item name="Afraid" label="Ängstlich" />
+ <combo_box.item name="Angry" label="Verärgert" />
+ <combo_box.item name="BigSmile" label="Grinst" />
+ <combo_box.item name="Bored" label="Gelangweilt" />
+ <combo_box.item name="Cry" label="Weinen" />
+ <combo_box.item name="Disdain" label="Verachten" />
+ <combo_box.item name="Embarrassed" label="Verlegen" />
+ <combo_box.item name="Frown" label="Stirnrunzeln" />
+ <combo_box.item name="Kiss" label="Küssen" />
+ <combo_box.item name="Laugh" label="Lachen" />
+ <combo_box.item name="Plllppt" label="Bäääh" />
+ <combo_box.item name="Repulsed" label="Zurückgestoßen" />
+ <combo_box.item name="Sad" label="Traurig" />
+ <combo_box.item name="Shrug" label="Schulterzucken" />
+ <combo_box.item name="Smile" label="Lächeln" />
+ <combo_box.item name="Surprise" label="Ãœberraschung" />
+ <combo_box.item name="Wink" label="Zwinkern" />
+ <combo_box.item name="Worry" label="Sorgenvoll" />
</combo_box>
<text name="preview_label" width="97">
Vorschau während:
</text>
<combo_box label="" left_delta="107" name="preview_base_anim" tool_tip="Hiermit können Sie das Verhalten Ihres Avatars testen, während Ihr Avatar normale Bewegungen ausführt.">
- <combo_item name="Standing">
- Stehend
- </combo_item>
- <combo_item name="Walking">
- Geht
- </combo_item>
- <combo_item name="Sitting">
- Sitzt
- </combo_item>
- <combo_item name="Flying">
- Fliegend
- </combo_item>
+ <combo_box.item name="Standing" label="Stehend" />
+ <combo_box.item name="Walking" label="Geht" />
+ <combo_box.item name="Sitting" label="Sitzt" />
+ <combo_box.item name="Flying" label="Fliegend" />
</combo_box>
<spinner label="Eingang glätten (s)" label_width="105" name="ease_in_time" tool_tip="Einblendungsgeschwindigkeit von Animationen (in Sekunden)." width="175"/>
<spinner bottom_delta="-20" label="Ausgang glätten (s)" label_width="105" left="10" name="ease_out_time" tool_tip="Ausblendungsgeschwindigkeit von Animationen (in Sekunden)." width="175"/>
diff --git a/indra/newview/skins/default/xui/de/floater_buy_land.xml b/indra/newview/skins/default/xui/de/floater_buy_land.xml
index 44ae6b0c15..e0abf8fae9 100644
--- a/indra/newview/skins/default/xui/de/floater_buy_land.xml
+++ b/indra/newview/skins/default/xui/de/floater_buy_land.xml
@@ -75,15 +75,9 @@ Objekte im Verkauf eingeschlossen
Landbesitz ist Premium-Mitgliedern vorbehalten.
</text>
<combo_box name="account_level">
- <combo_item name="US$9.95/month,billedmonthly">
- 9,95 US$/Monat, monatliche Abrechnung
- </combo_item>
- <combo_item name="US$7.50/month,billedquarterly">
- 7,50 US$/Monat, vierteljährliche Abrechnung
- </combo_item>
- <combo_item name="US$6.00/month,billedannually">
- 6,00 US$/Monat, jährliche Abrechnung
- </combo_item>
+ <combo_box.item name="US$9.95/month,billedmonthly" label="9,95 US$/Monat, monatliche Abrechnung" />
+ <combo_box.item name="US$7.50/month,billedquarterly" label="7,50 US$/Monat, vierteljährliche Abrechnung" />
+ <combo_box.item name="US$6.00/month,billedannually" label="6,00 US$/Monat, jährliche Abrechnung" />
</combo_box>
<text name="land_use_action">
Erhöhen Sie Ihre monatlichen Landnutzungsgebühren auf 40 US$/month.
diff --git a/indra/newview/skins/default/xui/de/floater_god_tools.xml b/indra/newview/skins/default/xui/de/floater_god_tools.xml
index dcb6982588..39c064b265 100644
--- a/indra/newview/skins/default/xui/de/floater_god_tools.xml
+++ b/indra/newview/skins/default/xui/de/floater_god_tools.xml
@@ -115,29 +115,17 @@
Ziel:
</text>
<combo_box name="destination">
- <combo_item name="Selection">
- Auswahl
- </combo_item>
- <combo_item name="AgentRegion">
- Avatar-Region
- </combo_item>
+ <combo_box.item name="Selection" label="Auswahl" />
+ <combo_box.item name="AgentRegion" label="Avatar-Region" />
</combo_box>
<text name="Request:">
Anfrage:
</text>
<combo_box name="request">
- <combo_item name="colliders&lt;steps&gt;">
- Kollisionsobjekte &lt;Schritte&gt;
- </combo_item>
- <combo_item name="scripts&lt;count&gt;,&lt;optionalpattern&gt;">
- Skripts &lt;Zähler&gt;,&lt;Optionales Muster&gt;
- </combo_item>
- <combo_item name="objects&lt;pattern&gt;">
- Objekte &lt;Muster&gt;
- </combo_item>
- <combo_item name="rez&lt;asset_id&gt;">
- &lt;asset_id&gt; erstellen
- </combo_item>
+ <combo_box.item name="colliders&lt;steps&gt;" label="Kollisionsobjekte &lt;Schritte&gt;" />
+ <combo_box.item name="scripts&lt;count&gt;,&lt;optionalpattern&gt;" label="Skripts &lt;Zähler&gt;,&lt;Optionales Muster&gt;" />
+ <combo_box.item name="objects&lt;pattern&gt;" label="Objekte &lt;Muster&gt;" />
+ <combo_box.item name="rez&lt;asset_id&gt;" label="lt;asset_id&gt; erstellen" />
</combo_box>
<text name="Parameter:">
Parameter:
diff --git a/indra/newview/skins/default/xui/de/floater_hardware_settings.xml b/indra/newview/skins/default/xui/de/floater_hardware_settings.xml
index a90e726392..4051776b0d 100644
--- a/indra/newview/skins/default/xui/de/floater_hardware_settings.xml
+++ b/indra/newview/skins/default/xui/de/floater_hardware_settings.xml
@@ -8,21 +8,11 @@
Antialiasing:
</text>
<combo_box label="Antialiasing" name="fsaa">
- <combo_item name="FSAADisabled">
- Deaktiviert
- </combo_item>
- <combo_item name="2x">
- 2x
- </combo_item>
- <combo_item name="4x">
- 4x
- </combo_item>
- <combo_item name="8x">
- 8x
- </combo_item>
- <combo_item name="16x">
- 16x
- </combo_item>
+ <combo_box.item name="FSAADisabled" label="Deaktiviert" />
+ <combo_box.item name="2x" label="2x" />
+ <combo_box.item name="4x" label="4x" />
+ <combo_box.item name="8x" label="8x" />
+ <combo_box.item name="16x" label="16x" />
</combo_box>
<spinner label="Gamma:" name="gamma" />
<text name="(brightness, lower is brighter)">
diff --git a/indra/newview/skins/default/xui/de/floater_image_preview.xml b/indra/newview/skins/default/xui/de/floater_image_preview.xml
index 145e0bbc33..724da83495 100644
--- a/indra/newview/skins/default/xui/de/floater_image_preview.xml
+++ b/indra/newview/skins/default/xui/de/floater_image_preview.xml
@@ -10,36 +10,16 @@
Bildvorschau als:
</text>
<combo_box label="Kleidungstyp" name="clothing_type_combo">
- <combo_item name="Image">
- Bild
- </combo_item>
- <combo_item name="Hair">
- Haar
- </combo_item>
- <combo_item name="FemaleHead">
- Kopf (Frau)
- </combo_item>
- <combo_item name="FemaleUpperBody">
- Oberkörper (Frau)
- </combo_item>
- <combo_item name="FemaleLowerBody">
- Unterkörper (Frau)
- </combo_item>
- <combo_item name="MaleHead">
- Kopf (Mann)
- </combo_item>
- <combo_item name="MaleUpperBody">
- Oberkörper (Mann)
- </combo_item>
- <combo_item name="MaleLowerBody">
- Unterkörper (Mann)
- </combo_item>
- <combo_item name="Skirt">
- Rock
- </combo_item>
- <combo_item name="SculptedPrim">
- Geformtes Primitiv
- </combo_item>
+ <combo_box.item name="Image" label="Bild" />
+ <combo_box.item name="Hair" label="Haar" />
+ <combo_box.item name="FemaleHead" label="Kopf (Frau)" />
+ <combo_box.item name="FemaleUpperBody" label="Oberkörper (Frau)" />
+ <combo_box.item name="FemaleLowerBody" label="Unterkörper (Frau)" />
+ <combo_box.item name="MaleHead" label="Kopf (Mann)" />
+ <combo_box.item name="MaleUpperBody" label="Oberkörper (Mann)" />
+ <combo_box.item name="MaleLowerBody" label="Unterkörper (Mann)" />
+ <combo_box.item name="Skirt" label="Rock" />
+ <combo_box.item name="SculptedPrim" label="Geformtes Primitiv" />
</combo_box>
<text name="bad_image_text">
Bild kann nicht gelesen werden.
diff --git a/indra/newview/skins/default/xui/de/floater_inventory_item_properties.xml b/indra/newview/skins/default/xui/de/floater_inventory_item_properties.xml
index 0028f1da13..3e79a31abd 100644
--- a/indra/newview/skins/default/xui/de/floater_inventory_item_properties.xml
+++ b/indra/newview/skins/default/xui/de/floater_inventory_item_properties.xml
@@ -60,12 +60,8 @@
</text>
<check_box label="Zum Verkauf" name="CheckPurchase" />
<radio_group name="RadioSaleType" left_delta="85" width="245" >
- <radio_item name="radio">
- Original
- </radio_item>
- <radio_item name="radio2">
- Kopieren
- </radio_item>
+ <radio_item name="radio" label="Original" />
+ <radio_item name="radio2" label="Kopieren" />
</radio_group>
<text name="TextPrice">
Preis: L$
diff --git a/indra/newview/skins/default/xui/de/floater_postcard.xml b/indra/newview/skins/default/xui/de/floater_postcard.xml
index 639a8ffdd1..2755704660 100644
--- a/indra/newview/skins/default/xui/de/floater_postcard.xml
+++ b/indra/newview/skins/default/xui/de/floater_postcard.xml
@@ -33,7 +33,7 @@
<button label="Abbrechen" name="cancel_btn" />
<button label="Senden" name="send_btn" />
<text name="default_subject">
- Postkarte aus Second Life.
+ Postkarte aus [SECOND_LIFE]
</text>
<text name="default_message">
Sehen Sie hier!
diff --git a/indra/newview/skins/default/xui/de/floater_preview_gesture.xml b/indra/newview/skins/default/xui/de/floater_preview_gesture.xml
index 327d0b70f1..d72dceec90 100644
--- a/indra/newview/skins/default/xui/de/floater_preview_gesture.xml
+++ b/indra/newview/skins/default/xui/de/floater_preview_gesture.xml
@@ -46,12 +46,8 @@ Zeit, außer Sie fügen Warteschritte
ein.
</text>
<radio_group name="animation_trigger_type">
- <radio_item name="start">
- Start
- </radio_item>
- <radio_item name="stop">
- Stopp
- </radio_item>
+ <radio_item name="start" label="Start" />
+ <radio_item name="stop" label="Stopp" />
</radio_group>
<check_box label="bis alle Animationen beendet sind" name="wait_anim_check"/>
<check_box label="Zeit in Sekunden" name="wait_time_check"/>
diff --git a/indra/newview/skins/default/xui/de/floater_report_abuse.xml b/indra/newview/skins/default/xui/de/floater_report_abuse.xml
index 6a7246d1e6..af7145003a 100644
--- a/indra/newview/skins/default/xui/de/floater_report_abuse.xml
+++ b/indra/newview/skins/default/xui/de/floater_report_abuse.xml
@@ -38,123 +38,51 @@ dann auf das Objekt:
Hendrerit Vulputate
</text>
<combo_box name="category_combo" tool_tip="Kategorie -- wählen Sie die Kategorie aus, die am besten auf diesen Bericht zutrifft">
- <combo_item name="Select_category">
- Kategorie auswählen
- </combo_item>
- <combo_item name="Age__Age_play">
- Alter&gt; Age-Play
- </combo_item>
- <combo_item name="Age__Adult_resident_on_Teen_Second_Life">
- Alter&gt; Erwachsener Einwohner in Teen Second Life
- </combo_item>
+ <combo_box.item name="Select_category" label="Kategorie auswählen"/>
+ <combo_box.item name="Age__Age_play" label="Alter&gt; Age-Play"/>
+ <combo_box.item name="Age__Adult_resident_on_Teen_Second_Life" label="Alter&gt; Erwachsener Einwohner in Teen Second Life"/>
<combo_item name="Age__Underage_resident_outside_of_Teen_Second_Life">
Alter &gt; Minderjähriger Einwohner außerhalb Teen Second Life
</combo_item>
- <combo_item name="Assault__Combat_sandbox___unsafe_area">
- Angriff&gt; Kampf-Sandbox / unsichere Region
- </combo_item>
- <combo_item name="Assault__Safe_area">
- Angriff&gt; Sichere Region
- </combo_item>
- <combo_item name="Assault__Weapons_testing_sandbox">
- Angriff &gt; Sandbox für Waffentest
- </combo_item>
- <combo_item name="Commerce__Failure_to_deliver_product_or_service">
- Handel &gt; Produkt nicht geliefert oder Dienstleistung nicht erbracht
- </combo_item>
- <combo_item name="Disclosure__Real_world_information">
- Offenlegung &gt; Informationen aus realer Welt
- </combo_item>
- <combo_item name="Disclosure__Remotely_monitoring chat">
- Offenlegung &gt; Abhören eines Chats aus der Ferne
- </combo_item>
- <combo_item name="Disclosure__Second_Life_information_chat_IMs">
- Offenlegung &gt; Second Life-Informationen/Chat/IMs
- </combo_item>
- <combo_item name="Disturbing_the_peace__Unfair_use_of_region_resources">
- Ruhestörung &gt; Unfaire Nutzung von Regionsressourcen
- </combo_item>
- <combo_item name="Disturbing_the_peace__Excessive_scripted_objects">
- Ruhestörung &gt; Exzessive Nutzung geskripteter Objekte
- </combo_item>
- <combo_item name="Disturbing_the_peace__Object_littering">
- Ruhestörung &gt; Wildes Erzeugen von Objekten
- </combo_item>
- <combo_item name="Disturbing_the_peace__Repetitive_spam">
- Ruhestörung &gt; Ständige Spam-Wiederholung
- </combo_item>
- <combo_item name="Disturbing_the_peace__Unwanted_advert_spam">
- Ruhestörung &gt; Unerwünschte Spam-Werbung
- </combo_item>
- <combo_item name="Fraud__L$">
- Betrug &gt; L$
- </combo_item>
- <combo_item name="Fraud__Land">
- Betrug&gt; Land
- </combo_item>
- <combo_item name="Fraud__Pyramid_scheme_or_chain_letter">
- Betrug &gt; Schneeballsystem oder Kettenbrief
- </combo_item>
- <combo_item name="Fraud__US$">
- Betrug &gt; US$
- </combo_item>
- <combo_item name="Harassment__Advert_farms___visual_spam">
- Belästigung &gt; Werbefarmen / visueller Spam
- </combo_item>
- <combo_item name="Harassment__Defaming_individuals_or_groups">
- Belästigung &gt; Diffamieren von Einzelpersonen/Gruppen
- </combo_item>
- <combo_item name="Harassment__Impeding_movement">
- Belästigung &gt; Bewegungseinschränkung
- </combo_item>
- <combo_item name="Harassment__Sexual_harassment">
- Belästigung &gt; Sexuelle Belästigung
- </combo_item>
- <combo_item name="Harassment__Solicting_inciting_others_to_violate_ToS">
- Belästigung &gt; Anstiften Dritter zur Missachtung der Nutzungsbedingungen
- </combo_item>
- <combo_item name="Harassment__Verbal_abuse">
- Belästigung &gt; Beschimpfung
- </combo_item>
- <combo_item name="Indecency__Broadly_offensive_content_or_conduct">
- Unanständigkeit &gt; Anstößige Inhalte oder Handlungen in der Öffentlichkeit
- </combo_item>
- <combo_item name="Indecency__Inappropriate_avatar_name">
- Unanständigkeit &gt; Anstößiger Avatarname
- </combo_item>
+ <combo_box.item name="Assault__Combat_sandbox___unsafe_area" label="Angriff&gt; Kampf-Sandbox / unsichere Region"/>
+ <combo_box.item name="Assault__Safe_area" label="Angriff&gt; Sichere Region"/>
+ <combo_box.item name="Assault__Weapons_testing_sandbox" label="Angriff &gt; Sandbox für Waffentest"/>
+ <combo_box.item name="Commerce__Failure_to_deliver_product_or_service" label="Handel &gt; Produkt nicht geliefert oder Dienstleistung nicht erbracht"/>
+ <combo_box.item name="Disclosure__Real_world_information" label="Offenlegung &gt; Informationen aus realer Welt"/>
+ <combo_box.item name="Disclosure__Remotely_monitoring chat" label="Offenlegung &gt; Abhören eines Chats aus der Ferne"/>
+ <combo_box.item name="Disclosure__Second_Life_information_chat_IMs" label="Offenlegung &gt; Second Life-Informationen/Chat/IMs"/>
+ <combo_box.item name="Disturbing_the_peace__Unfair_use_of_region_resources" label="Ruhestörung &gt; Unfaire Nutzung von Regionsressourcen"/>
+ <combo_box.item name="Disturbing_the_peace__Excessive_scripted_objects" label="Ruhestörung &gt; Exzessive Nutzung geskripteter Objekte"/>
+ <combo_box.item name="Disturbing_the_peace__Object_littering" label="Ruhestörung &gt; Wildes Erzeugen von Objekten"/>
+ <combo_box.item name="Disturbing_the_peace__Repetitive_spam" label="Ruhestörung &gt; Ständige Spam-Wiederholung"/>
+ <combo_box.item name="Disturbing_the_peace__Unwanted_advert_spam" label="Ruhestörung &gt; Unerwünschte Spam-Werbung"/>
+ <combo_box.item name="Fraud__L$" label="Betrug &gt; L$"/>
+ <combo_box.item name="Fraud__Land" label="Betrug&gt; Land"/>
+ <combo_box.item name="Fraud__Pyramid_scheme_or_chain_letter" label="Betrug &gt; Schneeballsystem oder Kettenbrief"/>
+ <combo_box.item name="Fraud__US$" label="Betrug &gt; US$"/>
+ <combo_box.item name="Harassment__Advert_farms___visual_spam" label="Belästigung &gt; Werbefarmen / visueller Spam"/>
+ <combo_box.item name="Harassment__Defaming_individuals_or_groups" label="Belästigung &gt; Diffamieren von Einzelpersonen/Gruppen"/>
+ <combo_box.item name="Harassment__Impeding_movement" label="Belästigung &gt; Bewegungseinschränkung"/>
+ <combo_box.item name="Harassment__Sexual_harassment" label="Belästigung &gt; Sexuelle Belästigung"/>
+ <combo_box.item name="Harassment__Solicting_inciting_others_to_violate_ToS" label="Belästigung &gt; Anstiften Dritter zur Missachtung der Nutzungsbedingungen"/>
+ <combo_box.item name="Harassment__Verbal_abuse" label="Belästigung &gt; Beschimpfung"/>
+ <combo_box.item name="Indecency__Broadly_offensive_content_or_conduct" label="Unanständigkeit &gt; Anstößige Inhalte oder Handlungen in der Öffentlichkeit"/>
+ <combo_box.item name="Indecency__Inappropriate_avatar_name" label="Unanständigkeit &gt; Anstößiger Avatarname"/>
<combo_item name="Indecency__Mature_content_in_PG_region">
Unanständigkeit &gt; Unangemessener Inhalt oder unangemessenes Verhalten in PG-Region
</combo_item>
<combo_item name="Indecency__Inappropriate_content_in_Mature_region">
Unanständigkeit &gt; Unangemessener Inhalt oder unangemessenes Verhalten in Mature-Region
</combo_item>
- <combo_item name="Intellectual_property_infringement_Content_Removal">
- Urheberrechtsverletzung &gt; Entfernen von Inhalten
- </combo_item>
- <combo_item name="Intellectual_property_infringement_CopyBot_or_Permissions_Exploit">
- Urheberrechtsverletzung &gt; CopyBot oder Berechtigungs-Exploit
- </combo_item>
- <combo_item name="Intolerance">
- Intoleranz
- </combo_item>
- <combo_item name="Land__Abuse_of_sandbox_resources">
- Land &gt; Missbrauch der Sandbox-Ressourcen
- </combo_item>
- <combo_item name="Land__Encroachment__Objects_textures">
- Land &gt; Unbefugte Nutzung &gt; Objekte/Texturen
- </combo_item>
- <combo_item name="Land__Encroachment__Particles">
- Land &gt; Unbefugte Nutzung &gt; Partikel
- </combo_item>
- <combo_item name="Land__Encroachment__Trees_plants">
- Land &gt; Unbefugte Nutzung &gt; Bäume/Pflanzen
- </combo_item>
- <combo_item name="Wagering_gambling">
- Wetten/Glücksspiel
- </combo_item>
- <combo_item name="Other">
- Sonstige
- </combo_item>
+ <combo_box.item name="Intellectual_property_infringement_Content_Removal" label="Urheberrechtsverletzung &gt; Entfernen von Inhalten"/>
+ <combo_box.item name="Intellectual_property_infringement_CopyBot_or_Permissions_Exploit" label="Urheberrechtsverletzung &gt; CopyBot oder Berechtigungs-Exploit"/>
+ <combo_box.item name="Intolerance" label="Intoleranz"/>
+ <combo_box.item name="Land__Abuse_of_sandbox_resources" label="Land &gt; Missbrauch der Sandbox-Ressourcen"/>
+ <combo_box.item name="Land__Encroachment__Objects_textures" label="Land &gt; Unbefugte Nutzung &gt; Objekte/Texturen"/>
+ <combo_box.item name="Land__Encroachment__Particles" label="Land &gt; Unbefugte Nutzung &gt; Partikel"/>
+ <combo_box.item name="Land__Encroachment__Trees_plants" label="Land &gt; Unbefugte Nutzung &gt; Bäume/Pflanzen"/>
+ <combo_box.item name="Wagering_gambling" label="Wetten/Glücksspiel"/>
+ <combo_box.item name="Other" label="Sonstige"/>
</combo_box>
<text name="abuser_name_title">
Name des Beschuldigten:
diff --git a/indra/newview/skins/default/xui/de/floater_sell_land.xml b/indra/newview/skins/default/xui/de/floater_sell_land.xml
index d4ec0fa729..c34252d8a7 100644
--- a/indra/newview/skins/default/xui/de/floater_sell_land.xml
+++ b/indra/newview/skins/default/xui/de/floater_sell_land.xml
@@ -38,15 +38,9 @@ dieser Parzelle:
beschränkt ist.
</text>
<combo_box height="16" left="72" name="sell_to" bottom_delta="-32" width="140">
- <combo_item name="--selectone--">
- -- select one --
- </combo_item>
- <combo_item name="Anyone">
- Jeder
- </combo_item>
- <combo_item name="Specificuser:">
- Bestimmter Benutzer:
- </combo_item>
+ <combo_box.item name="--selectone--" label="select one --" />
+ <combo_box.item name="Anyone" label="Jeder" />
+ <combo_box.item name="Specificuser:" label="Bestimmter Benutzer:" />
</combo_box>
<button label="Auswählen..." name="sell_to_select_agent" />
<text name="sell_objects_label">
@@ -57,12 +51,8 @@ beschränkt ist.
wechseln den Eigentümer.
</text>
<radio_group bottom_delta="-58" name="sell_objects">
- <radio_item name="no">
- Nein, Objekte behalten
- </radio_item>
- <radio_item name="yes">
- Ja, Objekte mit Land verkaufen
- </radio_item>
+ <radio_item name="no" label="Nein, Objekte behalten" />
+ <radio_item name="yes" label="Ja, Objekte mit Land verkaufen" />
</radio_group>
<button label="Objekte anzeigen" name="show_objects" width="116"/>
<text name="nag_message_label">
diff --git a/indra/newview/skins/default/xui/de/floater_settings_debug.xml b/indra/newview/skins/default/xui/de/floater_settings_debug.xml
index d64b9dccf9..034cfca017 100644
--- a/indra/newview/skins/default/xui/de/floater_settings_debug.xml
+++ b/indra/newview/skins/default/xui/de/floater_settings_debug.xml
@@ -1,12 +1,8 @@
<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
<floater name="settings_debug" title="Debug-Einstellungen">
<combo_box name="boolean_combo">
- <combo_item name="TRUE">
- WAHR
- </combo_item>
- <combo_item name="FALSE">
- FALSCH
- </combo_item>
+ <combo_box.item name="TRUE" label="WAHR" />
+ <combo_box.item name="FALSE" label="FALSCH" />
</combo_box>
<color_swatch label="Farbe" name="color_swatch" />
<spinner label="x" name="val_spinner_1" />
diff --git a/indra/newview/skins/default/xui/de/floater_sound_preview.xml b/indra/newview/skins/default/xui/de/floater_sound_preview.xml
index 552b4b0f27..1e5ac179b5 100644
--- a/indra/newview/skins/default/xui/de/floater_sound_preview.xml
+++ b/indra/newview/skins/default/xui/de/floater_sound_preview.xml
@@ -12,17 +12,9 @@
Bitrate (kbit/s):
</text>
<radio_group name="bitrate">
- <radio_item name="32">
- 32
- </radio_item>
- <radio_item name="64">
- 64
- </radio_item>
- <radio_item name="96">
- 96
- </radio_item>
- <radio_item name="128">
- 128
- </radio_item>
+ <radio_item name="32" label="32" />
+ <radio_item name="64" label="64" />
+ <radio_item name="96" label="96" />
+ <radio_item name="128" label="128" />
</radio_group>
</floater>
diff --git a/indra/newview/skins/default/xui/de/floater_tools.xml b/indra/newview/skins/default/xui/de/floater_tools.xml
index 44ebde6b3c..8084d2427e 100644
--- a/indra/newview/skins/default/xui/de/floater_tools.xml
+++ b/indra/newview/skins/default/xui/de/floater_tools.xml
@@ -79,6 +79,634 @@
<text name="prim_count">
Primitive: [COUNT]
</text>
+ <tab_container name="Object Info Tabs">
+ <panel label="Allgemein" name="General">
+ <text name="Name:">
+ Name:
+ </text>
+ <text name="Description:">
+ Beschreibung:
+ </text>
+ <text name="Creator:">
+ Ersteller:
+ </text>
+ <text name="Creator Name">
+ Thrax Linden
+ </text>
+ <button label="Profil..." label_selected="Profil..." name="button creator profile"/>
+ <text name="Owner:">
+ Eigentümer:
+ </text>
+ <text name="Owner Name">
+ Thrax Linden
+ </text>
+ <button label="Profil..." label_selected="Profil..." name="button owner profile"/>
+ <text name="Group:">
+ Gruppe:
+ </text>
+ <text name="Group Name Proxy">
+ Die Lindens
+ </text>
+ <button label="Festlegen..." label_selected="Festlegen..." name="button set group"/>
+ <text name="Permissions:">
+ Berechtigungen:
+ </text>
+ <text name="perm_modify">
+ Sie können dieses Objekt ändern.
+ </text>
+ <check_box label="Mit Gruppe teilen" name="checkbox share with group" tool_tip="Allen Mitgliedern der zugeordneten Gruppe die Erlaubnis erteilen, Ihre Berechtigungen für dieses Objekt zu teilen und zu verwenden. Sie müssen Übereignen, um Rollenbeschränkungen zu aktivieren."/>
+ <string name="text deed continued">
+ Ãœbertragung...
+ </string>
+ <string name="text deed">
+ Ãœbertragung
+ </string>
+ <button label="Übertragung..." label_selected="Übertragung..." name="button deed" tool_tip="In der Gruppe gemeinsam verwendete Objekte können von einem Gruppenfunktionär übertragen werden."/>
+ <check_box label="Verschieben durch beliebige Personen zulassen" name="checkbox allow everyone move"/>
+ <check_box label="Kopieren durch beliebige Personen zulassen" name="checkbox allow everyone copy"/>
+ <check_box label="In Suche anzeigen" name="search_check" tool_tip="Dieses Objekt in Suchergebnissen anzeigen"/>
+ <check_box label="Zu verkaufen" name="checkbox for sale"/>
+ <text name="Cost">
+ Preis:L$
+ </text>
+ <radio_group name="sale type">
+ <radio_item name="Original">
+ Original
+ </radio_item>
+ <radio_item name="Copy">
+ Kopieren
+ </radio_item>
+ <radio_item name="Contents">
+ Inhalt
+ </radio_item>
+ </radio_group>
+ <text name="Next owner can:">
+ Nächster Eigentümer kann:
+ </text>
+ <check_box label="Ändern" name="checkbox next owner can modify"/>
+ <check_box label="Kopieren" name="checkbox next owner can copy"/>
+ <check_box label="Wiederverkaufen" name="checkbox next owner can transfer"/>
+ <text name="label click action">
+ Bei Linksklicken:
+ </text>
+ <combo_box name="clickaction">
+ <combo_item name="Touch/grab(default)">
+ Berühren/Greifen (Standard)
+ </combo_item>
+ <combo_item name="Sitonobject">
+ Auf Objekt sitzen
+ </combo_item>
+ <combo_item name="Buyobject">
+ Objekt kaufen
+ </combo_item>
+ <combo_item name="Payobject">
+ Objekt bezahlen
+ </combo_item>
+ <combo_item name="Open">
+ Öffnen
+ </combo_item>
+ <combo_item name="Play">
+ Parzellenmedien wiedergeben
+ </combo_item>
+ <combo_item name="Opemmedia">
+ Parzellenmedien öffnen
+ </combo_item>
+ </combo_box>
+ <text name="B:">
+ B:
+ </text>
+ <text name="O:">
+ O;
+ </text>
+ <text name="G:">
+ G:
+ </text>
+ <text name="E:">
+ E:
+ </text>
+ <text name="N:">
+ N:
+ </text>
+ <text name="F:">
+ F:
+ </text>
+ <string name="text modify info 1">
+ Sie können dieses Objekt ändern.
+ </string>
+ <string name="text modify info 2">
+ Sie können diese Objekte ändern.
+ </string>
+ <string name="text modify info 3">
+ Sie können dieses Objekt nicht ändern.
+ </string>
+ <string name="text modify info 4">
+ Sie können diese Objekte nicht ändern.
+ </string>
+ <string name="text modify warning">
+ Gesamtes Objekt muss gewählt werden, um Berechtigungen festzulegen.
+ </string>
+ <string name="Cost Default">
+ Preis:L$
+ </string>
+ <string name="Cost Total">
+ Summe:L$
+ </string>
+ <string name="Cost Per Unit">
+ Stückpreis:L$
+ </string>
+ <string name="Cost Mixed">
+ Mischpreis
+ </string>
+ <string name="Sale Mixed">
+ Mischverkauf
+ </string>
+ </panel>
+ <panel label="Objekt" name="Object">
+ <text name="select_single">
+ Wählen Sie nur ein Primitivum aus, um Parameter zu bearbeiten.
+ </text>
+ <text name="edit_object">
+ Objektparameter bearbeiten:
+ </text>
+ <check_box label="Gesperrt" name="checkbox locked" tool_tip="Verhindert, dass Objekt verschoben oder gelöscht wird. Oft beim Bauen nützlich, um unbeabsichtigte Bearbeitungen zu vermeiden."/>
+ <check_box label="Physisch" name="Physical Checkbox Ctrl" tool_tip="Gestattet, das Objekt geschoben und von Schwerkraft beeinflusst wird"/>
+ <check_box label="Temporär" name="Temporary Checkbox Ctrl" tool_tip="Verursacht, dass Objekt 1 Minute nach Erstellung gelöscht wird."/>
+ <check_box label="Phantom" name="Phantom Checkbox Ctrl" tool_tip="Verursacht, dass Objekt nicht mit anderen Objekten oder Avataren kollidiert"/>
+ <text name="label position">
+ Position (Meter)
+ </text>
+ <spinner label="X" name="Pos X"/>
+ <spinner label="Y" name="Pos Y"/>
+ <spinner label="Z" name="Pos Z"/>
+ <text name="label size">
+ Größe (Meter)
+ </text>
+ <spinner label="X" name="Scale X"/>
+ <spinner label="Y" name="Scale Y"/>
+ <spinner label="Z" name="Scale Z"/>
+ <text name="label rotation">
+ Rotation (Grad)
+ </text>
+ <spinner label="X" name="Rot X"/>
+ <spinner label="Y" name="Rot Y"/>
+ <spinner label="Z" name="Rot Z"/>
+ <text name="label material">
+ Material
+ </text>
+ <combo_box name="material">
+ <combo_item name="Stone">
+ Stein
+ </combo_item>
+ <combo_item name="Metal">
+ Metall
+ </combo_item>
+ <combo_item name="Glass">
+ Glas
+ </combo_item>
+ <combo_item name="Wood">
+ Holz
+ </combo_item>
+ <combo_item name="Flesh">
+ Fleisch
+ </combo_item>
+ <combo_item name="Plastic">
+ Kunststoff
+ </combo_item>
+ <combo_item name="Rubber">
+ Gummi
+ </combo_item>
+ </combo_box>
+ <text name="label basetype">
+ Bausteintyp
+ </text>
+ <combo_box name="comboBaseType">
+ <combo_item name="Box">
+ Quader
+ </combo_item>
+ <combo_item name="Cylinder">
+ Zylinder
+ </combo_item>
+ <combo_item name="Prism">
+ Prisma
+ </combo_item>
+ <combo_item name="Sphere">
+ Kugel
+ </combo_item>
+ <combo_item name="Torus">
+ Torus
+ </combo_item>
+ <combo_item name="Tube">
+ Rohr
+ </combo_item>
+ <combo_item name="Ring">
+ Ring
+ </combo_item>
+ <combo_item name="Sculpted">
+ Geformt
+ </combo_item>
+ </combo_box>
+ <text name="text cut">
+ Pfadschnitt Beginn und Ende
+ </text>
+ <spinner label="B" name="cut begin"/>
+ <spinner label="E" name="cut end"/>
+ <text name="text hollow">
+ Hohl
+ </text>
+ <text name="text skew">
+ Versatz
+ </text>
+ <spinner name="Scale 1"/>
+ <spinner name="Skew"/>
+ <text name="Hollow Shape">
+ Hohlform
+ </text>
+ <combo_box name="hole">
+ <combo_item name="Default">
+ Standard
+ </combo_item>
+ <combo_item name="Circle">
+ Kreis
+ </combo_item>
+ <combo_item name="Square">
+ Quadrat
+ </combo_item>
+ <combo_item name="Triangle">
+ Dreieck
+ </combo_item>
+ </combo_box>
+ <text name="text twist">
+ Torsion
+ </text>
+ <spinner label="B" name="Twist Begin"/>
+ <spinner label="E" name="Twist End"/>
+ <text name="scale_taper">
+ Verjüngung
+ </text>
+ <text name="scale_hole">
+ Lochgröße
+ </text>
+ <spinner label="X" name="Taper Scale X"/>
+ <spinner label="Y" name="Taper Scale Y"/>
+ <text name="text topshear">
+ Verscherung
+ </text>
+ <spinner label="X" name="Shear X"/>
+ <spinner label="Y" name="Shear Y"/>
+ <text name="advanced_cut">
+ Profilschnitt-Beginn und Ende
+ </text>
+ <text name="advanced_dimple">
+ Vertiefung-Beginn und Ende
+ </text>
+ <text name="advanced_slice">
+ Anfang/Ende abschneiden
+ </text>
+ <spinner label="B" name="Path Limit Begin"/>
+ <spinner label="E" name="Path Limit End"/>
+ <text name="text taper2">
+ Verjüngung
+ </text>
+ <spinner label="X" name="Taper X"/>
+ <spinner label="Y" name="Taper Y"/>
+ <text name="text radius delta">
+ Radius
+ </text>
+ <text name="text revolutions">
+ Umdrehungen
+ </text>
+ <spinner name="Radius Offset"/>
+ <texture_picker label="Textur für gestaltetes
+Primitiv" name="sculpt texture control" tool_tip="Klicken Sie hier, um ein Bild auszuwählen"/>
+ <check_box label="Spiegeln" name="sculpt mirror control" tool_tip="Geformtes Primitiv entlang der X-Achse spiegeln."/>
+ <check_box label="Wenden" name="sculpt invert control" tool_tip="Dreht die Normalen des geformten Primitivs von innen nach außen."/>
+ <text name="label sculpt type">
+ Naht
+ </text>
+ <combo_box name="sculpt type control">
+ <combo_item name="None">
+ (keiner)
+ </combo_item>
+ <combo_item name="Sphere">
+ Kugel
+ </combo_item>
+ <combo_item name="Torus">
+ Torus
+ </combo_item>
+ <combo_item name="Plane">
+ Fläche
+ </combo_item>
+ <combo_item name="Cylinder">
+ Zylinder
+ </combo_item>
+ </combo_box>
+ </panel>
+ <panel label="Eigenschaften" name="Features">
+ <text name="select_single">
+ Wählen Sie nur einen einzelnen Baustein aus, um Eigenschaften zu bearbeiten.
+ </text>
+ <text name="edit_object">
+ Objekteigenschaften bearbeiten:
+ </text>
+ <check_box label="Flexibler Weg" name="Flexible1D Checkbox Ctrl" tool_tip="Gestattet, dass Objekt um die Z-Achse gebogen wird. (nur Client-Seite)"/>
+ <spinner label="Weichheit" name="FlexNumSections"/>
+ <spinner label="Schwerkraft" name="FlexGravity"/>
+ <spinner label="Ziehen" name="FlexFriction"/>
+ <spinner label="Wind" name="FlexWind"/>
+ <spinner label="Spannung" name="FlexTension"/>
+ <spinner label="Erzwingen X" name="FlexForceX"/>
+ <spinner label="Erzwingen Y" name="FlexForceY"/>
+ <spinner label="Erzwingen Z" name="FlexForceZ"/>
+ <check_box label="Licht" name="Light Checkbox Ctrl" tool_tip="Verursacht, dass Objekt Licht emittiert"/>
+ <text name="label color">
+ Farbe
+ </text>
+ <color_swatch label="" name="colorswatch" tool_tip="Klicken, um Farbauswahl zu öffnen"/>
+ <spinner label="Intensität" name="Light Intensity"/>
+ <spinner label="Radius" name="Light Radius"/>
+ <spinner label="Abnehmend" name="Light Falloff"/>
+ </panel>
+ <panel label="Textur" name="Texture">
+ <texture_picker label="Textur" name="texture control" tool_tip="Klicken, um ein Bild zu wählen"/>
+ <color_swatch label="Farbe" name="colorswatch" tool_tip="Klicken, um Farbauswahl zu öffnen"/>
+ <text name="color trans">
+ Transparenz %
+ </text>
+ <text name="glow label">
+ Leuchten
+ </text>
+ <check_box label="Ganz hell" name="checkbox fullbright"/>
+ <text name="tex gen">
+ Zuordnung
+ </text>
+ <combo_box name="combobox texgen">
+ <combo_item name="Default">
+ Standard
+ </combo_item>
+ <combo_item name="Planar">
+ Eben
+ </combo_item>
+ </combo_box>
+ <text name="label shininess">
+ Glanz
+ </text>
+ <combo_box name="combobox shininess">
+ <combo_item name="None">
+ Kein
+ </combo_item>
+ <combo_item name="Low">
+ Niedrig
+ </combo_item>
+ <combo_item name="Medium">
+ Mittel
+ </combo_item>
+ <combo_item name="High">
+ Hoch
+ </combo_item>
+ </combo_box>
+ <text name="label bumpiness">
+ Holprigkeit
+ </text>
+ <combo_box name="combobox bumpiness">
+ <combo_item name="None">
+ Keine
+ </combo_item>
+ <combo_item name="Brightness">
+ Helligkeit
+ </combo_item>
+ <combo_item name="Darkness">
+ Dunkelheit
+ </combo_item>
+ <combo_item name="woodgrain">
+ Holzmaserung
+ </combo_item>
+ <combo_item name="bark">
+ Rinde
+ </combo_item>
+ <combo_item name="bricks">
+ Ziegel
+ </combo_item>
+ <combo_item name="checker">
+ Karo
+ </combo_item>
+ <combo_item name="concrete">
+ Beton
+ </combo_item>
+ <combo_item name="crustytile">
+ verkrustete Fliesen
+ </combo_item>
+ <combo_item name="cutstone">
+ Steinplatten
+ </combo_item>
+ <combo_item name="discs">
+ Scheiben
+ </combo_item>
+ <combo_item name="gravel">
+ Kies
+ </combo_item>
+ <combo_item name="petridish">
+ Petrischale
+ </combo_item>
+ <combo_item name="siding">
+ Verkleidung
+ </combo_item>
+ <combo_item name="stonetile">
+ Steinfliesen
+ </combo_item>
+ <combo_item name="stucco">
+ Stuck
+ </combo_item>
+ <combo_item name="suction">
+ Saugen
+ </combo_item>
+ <combo_item name="weave">
+ gewoben
+ </combo_item>
+ </combo_box>
+ <text name="tex scale">
+ Wiederholungen
+ </text>
+ <spinner label="Horizontal (U)" name="TexScaleU"/>
+ <check_box label="Umkehren" name="checkbox flip s"/>
+ <spinner label="Vertikal (V)" name="TexScaleV"/>
+ <check_box label="Umkehren" name="checkbox flip t"/>
+ <text name="tex rotate">
+ Rotation (Grad)
+ </text>
+ <string name="string repeats per meter">
+ Kacheln pro Meter
+ </string>
+ <string name="string repeats per face">
+ Wiederholungen pro Fläche
+ </string>
+ <text name="rpt">
+ Kacheln pro Meter
+ </text>
+ <button label="Ãœbernehmen" label_selected="Ãœbernehmen" name="button apply"/>
+ <text name="tex offset">
+ Versatz
+ </text>
+ <spinner label="Horizontal (U)" name="TexOffsetU"/>
+ <spinner label="Vertikal (V)" name="TexOffsetV"/>
+ <text name="textbox autofix">
+ Medientextur ausrichten
+(zuerst laden)
+ </text>
+ <button label="Ausrichten" label_selected="Ausrichten" name="button align"/>
+ </panel>
+ <panel label="Inhalt" name="Contents">
+ <button label="Neues Skript" label_selected="Neues Skript..." name="button new script"/>
+ <button label="Berechtigungen..." name="button permissions"/>
+ </panel>
+ </tab_container>
+ <panel name="land info panel">
+ <text name="label_parcel_info">
+ Parzelleninformation
+ </text>
+ <text name="label_area_price">
+ Preis: L$ [PRICE] für [AREA] m2.
+ </text>
+ <text name="label_area">
+ Fläche: [AREA] m2
+ </text>
+ <button label="Info zu Land..." label_selected="Info zu Land..." name="button about land"/>
+ <check_box label="Eigentümer anzeigen" name="checkbox show owners" tool_tip="Parzellen nach Eigentümer farbig kennzeichnen"/>
+ <button label="?" label_selected="?" name="button show owners help"/>
+ <text name="label_parcel_modify">
+ Parzelle ändern
+ </text>
+ <button label="Unterteilen..." label_selected="Unterteilen..." name="button subdivide land"/>
+ <button label="Zusammenlegen" label_selected="Zusammenlegen" name="button join land"/>
+ <text name="label_parcel_trans">
+ Land-Transaktionen
+ </text>
+ <button label="Land kaufen..." label_selected="Land kaufen..." name="button buy land"/>
+ <button label="Land aufgeben..." label_selected="Land aufgeben..." name="button abandon land"/>
+ </panel>
+ <string name="status_rotate">
+ An den farbigen Bändern ziehen, um das Objekt zu drehen
+ </string>
+ <string name="status_scale">
+ Klicken und ziehen, um die ausgewählte Seite zu dehnen
+ </string>
+ <string name="status_move">
+ Maus verschiebt, Umschalt-Taste und Maus kopiert
+ </string>
+ <string name="status_modifyland">
+ Klicken und halten, um das Land zu bearbeiten
+ </string>
+ <string name="status_camera">
+ Klicken und ziehen, um die Ansicht zu ändern
+ </string>
+ <string name="status_grab">
+ Ziehen, um Objekte zu verschieben, Strg zum Heben, Strg-Umschalt zum Drehen
+ </string>
+ <string name="status_place">
+ Inworld klicken, um zu bauen.
+ </string>
+ <string name="status_selectland">
+ Klicken und ziehen, um Land auszuwählen
+ </string>
+ <string name="grid_screen_text">
+ Bildschirm
+ </string>
+ <string name="grid_local_text">
+ Lokal
+ </string>
+ <string name="grid_world_text">
+ Welt
+ </string>
+ <string name="grid_reference_text">
+ Referenz
+ </string>
+ <string name="grid_attachment_text">
+ Anhang
+ </string>
+</floater>
+
+<!-- original file
+
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<floater name="toolbox floater" title="" short_title="Bauen">
+ <button label="" label_selected="" name="button focus" tool_tip="Fokus"/>
+ <button label="" label_selected="" name="button move" tool_tip="Verschieben"/>
+ <button label="" label_selected="" name="button edit" tool_tip="Bearbeiten"/>
+ <button label="" label_selected="" name="button create" tool_tip="Erstellen"/>
+ <button label="" label_selected="" name="button land" tool_tip="Land"/>
+ <check_box label="Zoom" name="radio zoom"/>
+ <check_box label="Orbit (Strg)" name="radio orbit"/>
+ <check_box label="Schwenken (Strg-Umschalt)" name="radio pan"/>
+ <check_box label="Verschieben" name="radio move"/>
+ <check_box label="Heben (Strg)" name="radio lift"/>
+ <check_box label="Rotieren (Strg-Umschalt)" name="radio spin"/>
+ <check_box label="Position" name="radio position"/>
+ <check_box label="Drehen (Strg)" name="radio rotate"/>
+ <check_box label="Dehnen (Strg-Umschalt)" name="radio stretch"/>
+ <check_box label="Textur auswählen" name="radio select face"/>
+ <check_box label="Verknüpfte Teile bearbeiten" name="checkbox edit linked parts"/>
+ <text name="text ruler mode">
+ Lineal:
+ </text>
+ <combo_box name="combobox grid mode">
+ <combo_item name="World">
+ Welt
+ </combo_item>
+ <combo_item name="Local">
+ Lokal
+ </combo_item>
+ <combo_item name="Reference">
+ Referenz
+ </combo_item>
+ </combo_box>
+ <check_box label="Beide Seiten dehnen" name="checkbox uniform"/>
+ <check_box label="Texturen dehnen" name="checkbox stretch textures"/>
+ <check_box label="Raster verwenden" name="checkbox snap to grid"/>
+ <button label="Optionen..." label_selected="Optionen..." name="Options..."/>
+ <text name="text status">
+ Zum Verschieben ziehen, zum Kopieren Umschalttaste-Ziehen
+ </text>
+ <button label="" label_selected="" name="ToolCube" tool_tip="Würfel"/>
+ <button label="" label_selected="" name="ToolPrism" tool_tip="Prisma"/>
+ <button label="" label_selected="" name="ToolPyramid" tool_tip="Pyramide"/>
+ <button label="" label_selected="" name="ToolTetrahedron" tool_tip="Tetraeder"/>
+ <button label="" label_selected="" name="ToolCylinder" tool_tip="Zylinder"/>
+ <button label="" label_selected="" name="ToolHemiCylinder" tool_tip="Halbzylinder"/>
+ <button label="" label_selected="" name="ToolCone" tool_tip="Kegel"/>
+ <button label="" label_selected="" name="ToolHemiCone" tool_tip="Halbkegel"/>
+ <button label="" label_selected="" name="ToolSphere" tool_tip="Kugel"/>
+ <button label="" label_selected="" name="ToolHemiSphere" tool_tip="Halbkugel"/>
+ <button label="" label_selected="" name="ToolTorus" tool_tip="Torus"/>
+ <button label="" label_selected="" name="ToolTube" tool_tip="Rohr"/>
+ <button label="" label_selected="" name="ToolRing" tool_tip="Ring"/>
+ <button label="" label_selected="" name="ToolTree" tool_tip="Baum"/>
+ <button label="" label_selected="" name="ToolGrass" tool_tip="Gras"/>
+ <check_box label="Auswahl behalten" name="checkbox sticky"/>
+ <check_box label="Auswahl kopieren" name="checkbox copy selection"/>
+ <check_box label="Zentrieren" name="checkbox copy centers"/>
+ <check_box label="Drehen" name="checkbox copy rotates"/>
+ <check_box label="Land auswählen" name="radio select land"/>
+ <check_box label="Einebnen" name="radio flatten"/>
+ <check_box label="Anheben" name="radio raise"/>
+ <check_box label="Absenken" name="radio lower"/>
+ <check_box label="Glätten" name="radio smooth"/>
+ <check_box label="Aufrauen" name="radio noise"/>
+ <check_box label="Zurücksetzen" name="radio revert"/>
+ <button label="Übernehmen" label_selected="Übernehmen" name="button apply to selection" tool_tip="Ausgewähltes Land ändern"/>
+ <text name="Bulldozer:">
+ Planierraupe:
+ </text>
+ <text name="Dozer Size:">
+ Größe
+ </text>
+ <text name="Strength:">
+ Stärke
+ </text>
+ <text name="obj_count">
+ Ausgewählte Objekte: [COUNT]
+ </text>
+ <text name="prim_count">
+ Primitive: [COUNT]
+ </text>
<tab_container name="Object Info Tabs" tab_max_width="150" tab_min_width="30">
<panel label="Allgemein" name="General">
<text name="Name:">
@@ -623,3 +1251,5 @@ Primitiv" name="sculpt texture control" tool_tip="Klicken Sie hier, um ein Bild
Anhang
</string>
</floater>
+
+-->
diff --git a/indra/newview/skins/default/xui/de/floater_tos.xml b/indra/newview/skins/default/xui/de/floater_tos.xml
index 42f48fad4d..e2ad5ef2f6 100644
--- a/indra/newview/skins/default/xui/de/floater_tos.xml
+++ b/indra/newview/skins/default/xui/de/floater_tos.xml
@@ -3,12 +3,8 @@
<button label="Weiter" label_selected="Weiter" name="Continue" />
<button label="Abbrechen" label_selected="Abbrechen" name="Cancel" />
<radio_group name="tos_agreement">
- <radio_item name="radio_disagree">
- Ich stimme den Nutzungsbedingungen nicht zu
- </radio_item>
- <radio_item name="radio_agree">
- Ich stimme den Nutzungsbedingungen zu
- </radio_item>
+ <radio_item name="radio_disagree" label="Ich stimme den Nutzungsbedingungen nicht zu" />
+ <radio_item name="radio_agree" label="Ich stimme den Nutzungsbedingungen zu" />
</radio_group>
<text name="tos_title">
Nutzungsvereinbarung
@@ -16,7 +12,7 @@
<check_box label="Ich stimme den Nutzungsbedingungen zu" name="agree_chk" />
<text name="tos_heading">
Lesen Sie die folgenden Nutzungsbedingungen sorgfältig durch. Sie müssen dieser Vereinbarung
-zustimmen, um Second Life benutzen zu können.
+zustimmen, um [SECOND_LIFE] benutzen zu können.
</text>
<text_editor name="tos_text">
TOS_TEXT
diff --git a/indra/newview/skins/default/xui/de/floater_world_map.xml b/indra/newview/skins/default/xui/de/floater_world_map.xml
index d28b55e8a8..fecaf3eaff 100644
--- a/indra/newview/skins/default/xui/de/floater_world_map.xml
+++ b/indra/newview/skins/default/xui/de/floater_world_map.xml
@@ -28,14 +28,10 @@
<check_box label="Mature" name="event_mature_chk"/>
<check_box label="Adult" name="event_adult_chk"/>
<combo_box label="Online-Freunde" name="friend combo" tool_tip="Freund, der auf Karte angezeigt werden soll">
- <combo_item name="none_selected">
- Online-Freunde
- </combo_item>
+ <combo_box.item name="none_selected" label="Online-Freunde" />
</combo_box>
<combo_box label="Landmarken" name="landmark combo" tool_tip="Landmarke, die auf Karte angezeigt werden soll">
- <combo_item name="none_selected">
- Landmarken
- </combo_item>
+ <combo_box.item name="none_selected" label="Landmarken" />
</combo_box>
<line_editor label="Nach Regionsname suchen" name="location" tool_tip="Geben Sie den Namen einer Region ein"/>
<button label="Suchen" name="DoSearch" tool_tip="Nach einer Region suchen"/>
@@ -56,6 +52,6 @@
<button label="Gesuchte Position" label_selected="Ziel anzeigen" name="Show Destination" tool_tip="Karte auf ausgewählte Position zentrieren"/>
<button label="Löschen" label_selected="Löschen" name="Clear" tool_tip="Verfolgung abschalten"/>
<button label="Meine Position" label_selected="Wo bin ich?" name="Show My Location" tool_tip="Karte auf Position Ihres Avatars zentrieren"/>
- <button font="SansSerifSmall" label="SLURL in die Zwischenablage kopieren" name="copy_slurl" tool_tip="Kopiert die aktuelle Position als SLURL zur Verwendung im Web."/>
+ <button font="SansSerifSmall" label="SLurl in die Zwischenablage kopieren" name="copy_slurl" tool_tip="Kopiert die aktuelle Position als SLurl zur Verwendung im Web."/>
<slider label="Zoom" name="zoom slider"/>
</floater>
diff --git a/indra/newview/skins/default/xui/de/language_settings.xml b/indra/newview/skins/default/xui/de/language_settings.xml
new file mode 100644
index 0000000000..71418d446a
--- /dev/null
+++ b/indra/newview/skins/default/xui/de/language_settings.xml
@@ -0,0 +1,55 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<!-- This file contains strings that used to be hardcoded in the source.-->
+<strings>
+
+ <!-- Locale Information -->
+ <string name="MicrosoftLocale">english</string>
+ <string name="DarwinLocale">C</string>
+ <string name="LinuxLocale">C</string>
+
+ <!--
+ datetimeToCodes["wkday"] = "%a"; // Thu
+ datetimeToCodes["weekday"] = "%A"; // Thursday
+ datetimeToCodes["year4"] = "%Y"; // 2009
+ datetimeToCodes["year"] = "%Y"; // 2009
+ datetimeToCodes["year2"] = "%y"; // 09
+ datetimeToCodes["mth"] = "%b"; // Aug
+ datetimeToCodes["month"] = "%B"; // August
+ datetimeToCodes["mthnum"] = "%m"; // 08
+ datetimeToCodes["day"] = "%d"; // 31
+ datetimeToCodes["hour24"] = "%H"; // 14
+ datetimeToCodes["hour"] = "%H"; // 14
+ datetimeToCodes["hour12"] = "%I"; // 02
+ datetimeToCodes["min"] = "%M"; // 59
+ datetimeToCodes["ampm"] = "%p"; // AM
+ datetimeToCodes["second"] = "%S"; // 59
+ datetimeToCodes["timezone"] = "%Z"; // PST
+ -->
+
+ <string name="TimeHour">hour,datetime,slt</string>
+ <string name="TimeMin">min,datetime,slt</string>
+ <string name="TimeYear">year,datetime,slt</string>
+ <string name="TimeDay">day,datetime,slt</string>
+ <string name="TimeMonth">mthnum,datetime,slt</string>
+ <string name="TimeWeek">wkday,datetime,slt</string>
+ <string name="TimeAMPM">ampm,datetime,slt</string>
+ <string name="TimeHour12">hour12,datetime,slt</string>
+
+ <string name="LTimeMthNum">mthnum,datetime,local</string>
+ <string name="LTimeWeek">wkday,datetime,local</string>
+ <string name="LTimeMonth">mth,datetime,local</string>
+ <string name="LTimeDay">day,datetime,local</string>
+ <string name="LTimeSec">second,datetime,local</string>
+ <string name="LTimeHour">hour,datetime,local</string>
+ <string name="LTimeMin">min,datetime,local</string>
+ <string name="LTimeYear">year,datetime,local</string>
+
+ <string name="UTCTimeWeek">weekday,datetime,utc</string>
+ <string name="UTCTimeDay">day,datetime,utc</string>
+ <string name="UTCTimeMth">mth,datetime,utc</string>
+ <string name="UTCTimeYr">year,datetime,utc</string>
+ <string name="UTCTimeHr">hour,datetime,utc</string>
+ <string name="UTCTimeMin">min,datetime,utc</string>
+ <string name="UTCTimeSec">second,datetime,utc</string>
+ <string name="UTCTimeTimezone">timezone,datetime,utc</string>
+</strings>
diff --git a/indra/newview/skins/default/xui/de/menu_login.xml b/indra/newview/skins/default/xui/de/menu_login.xml
index 29330d894a..887d8d1b84 100644
--- a/indra/newview/skins/default/xui/de/menu_login.xml
+++ b/indra/newview/skins/default/xui/de/menu_login.xml
@@ -7,7 +7,7 @@
<menu_item_call label="Einstellungen..." name="Preferences..." />
</menu>
<menu label="Hilfe" name="Help">
- <menu_item_call label="Hilfe zu Second Life" name="Second Life Help" />
- <menu_item_call label="Ãœber Second Life..." name="About Second Life..." />
+ <menu_item_call label="Hilfe zu [SECOND_LIFE]" name="Second Life Help" />
+ <menu_item_call label="Ãœber [APP_NAME]..." name="About Second Life..." />
</menu>
</menu_bar>
diff --git a/indra/newview/skins/default/xui/de/menu_viewer.xml b/indra/newview/skins/default/xui/de/menu_viewer.xml
index e1fb1caffd..62cd982875 100644
--- a/indra/newview/skins/default/xui/de/menu_viewer.xml
+++ b/indra/newview/skins/default/xui/de/menu_viewer.xml
@@ -185,7 +185,7 @@
<menu_item_call label="Skripte in Auswahl so einstellen, dass sie nicht ausgeführt werden" name="Set Scripts to Not Running in Selection"/>
</menu>
<menu label="Hilfe" name="Help">
- <menu_item_call label="Hilfe zu Second Life" name="Second Life Help"/>
+ <menu_item_call label="Hilfe zu [SECOND_LIFE]" name="Second Life Help"/>
<menu_item_call label="Tutorial" name="Tutorial"/>
<menu_item_separator label="-----------" name="separator"/>
<menu_item_call label="Offizielles Linden-Blog..." name="Official Linden Blog..."/>
@@ -214,6 +214,6 @@
<menu_item_separator label="-----------" name="separator9"/>
<menu_item_call label="Fehler melden..." name="Report Bug..."/>
</menu>
- <menu_item_call label="Ãœber Second Life..." name="About Second Life..."/>
+ <menu_item_call label="Ãœber [APP_NAME]..." name="About Second Life..."/>
</menu>
</menu_bar>
diff --git a/indra/newview/skins/default/xui/de/notifications.xml b/indra/newview/skins/default/xui/de/notifications.xml
index ae25e1ec85..a746d2c08f 100644
--- a/indra/newview/skins/default/xui/de/notifications.xml
+++ b/indra/newview/skins/default/xui/de/notifications.xml
@@ -6,6 +6,9 @@
<global name="alwayschoose">
Diese Option immer auswählen
</global>
+ <global name="implicitclosebutton">
+ Schließen
+ </global>
<template name="okbutton">
<form>
<button
@@ -71,7 +74,7 @@
</form>
</template>
<notification functor="GenericAcknowledge" label="Unbekannter Warnhinweis" name="MissingAlert">
- Ihre Version von Second Life kann den gerade empfangenen Warnhinweis nicht anzeigen.
+ Ihre Version von [APP_NAME] kann den gerade empfangenen Warnhinweis nicht anzeigen.
Fehlerdetails: Der Warnhinweis „[_NAME]“ wurde in notifications.xml nicht gefunden.
<usetemplate name="okbutton" yestext="OK"/>
@@ -94,7 +97,7 @@ Fehlerdetails: Der Warnhinweis „[_NAME]“ wurde in notifications.xml nicht ge
<usetemplate name="okcancelbuttons" notext="Abbrechen" yestext="Ja"/>
</notification>
<notification name="BadInstallation">
- Beim Aktualisieren von Second Life ist ein Fehler aufgetreten. Bitte laden Sie die aktuellste Version von secondlife.com herunter.
+ Beim Aktualisieren von [APP_NAME] ist ein Fehler aufgetreten. Bitte laden Sie die aktuellste Version von secondlife.com herunter.
<usetemplate name="okbutton" yestext="OK"/>
</notification>
<notification name="LoginFailedNoNetwork">
@@ -132,12 +135,12 @@ Wählen Sie ein einzelnes Objekt aus und versuchen Sie es erneut.
<usetemplate canceltext="Abbrechen" name="yesnocancelbuttons" notext="Nicht speichern" yestext="Alles speichern"/>
</notification>
<notification name="GrantModifyRights">
- Die Gewährung von Änderungsrechten an andere Einwohner ermöglicht es diesen, JEDES BELIEBIGE Objekt zu ändern oder an sich zu nehmen, das Sie in der Second Life-Welt besitzen. Seien Sie SEHR vorsichtig beim Erteilen dieser Erlaubnis.
+ Die Gewährung von Änderungsrechten an andere Einwohner ermöglicht es diesen, JEDES BELIEBIGE Objekt zu ändern oder an sich zu nehmen, das Sie in der [SECOND_LIFE]-Welt besitzen. Seien Sie SEHR vorsichtig beim Erteilen dieser Erlaubnis.
Möchten Sie [FIRST_NAME] [LAST_NAME] Änderungsrechte gewähren?
<usetemplate name="okcancelbuttons" notext="Nein" yestext="Ja"/>
</notification>
<notification name="GrantModifyRightsMultiple">
- Die Gewährung von Änderungsrechten an andere Einwohner ermöglicht es diesen, JEDES BELIEBIGE Objekt zu ändern, das Sie in der Second Life-Welt besitzen. Seien Sie SEHR vorsichtig beim Erteilen dieser Erlaubnis.
+ Die Gewährung von Änderungsrechten an andere Einwohner ermöglicht es diesen, JEDES BELIEBIGE Objekt zu ändern, das Sie in der [SECOND_LIFE]-Welt besitzen. Seien Sie SEHR vorsichtig beim Erteilen dieser Erlaubnis.
Möchten Sie den ausgewählten Einwohnern Änderungsrechte gewähren?
<usetemplate name="okcancelbuttons" notext="Nein" yestext="Ja"/>
</notification>
@@ -226,7 +229,7 @@ Dieses Kontrollkästchen zeigt Folgendes an:
<notification name="ClickPartnerHelpAvatar">
Auf der [SECOND_LIFE] Website können Sie anderen Einwohnern eine Partnerschaft vorschlagen und bestehende Partnerschaften lösen.
-Die Second Life Website für weitere Informationen über Partnerschaften öffnen?
+Die [SECOND_LIFE] Website für weitere Informationen über Partnerschaften öffnen?
<usetemplate name="okcancelbuttons" notext="Abbrechen" yestext="Gehe zu Seite"/>
</notification>
<notification name="ClickUploadHelpPermissions">
@@ -265,7 +268,7 @@ Der Verkaufspreis beträgt [SALE_PRICE] L$ und wird automatisch für den Verkauf
<usetemplate name="okcancelbuttons" notext="Abbrechen" yestext="OK"/>
</notification>
<notification name="ConfirmLandSaleToAnyoneChange">
- ACHTUNG: Wenn Sie auf „An jeden verkaufen“ klicken, kann jeder in Second Life Ihr Land kaufen, auch Einwohner in anderen Regionen.
+ ACHTUNG: Wenn Sie auf „An jeden verkaufen“ klicken, kann jeder in [SECOND_LIFE] Ihr Land kaufen, auch Einwohner in anderen Regionen.
Die ausgewählten [LAND_SIZE] qm Land werden zum Verkauf freigegeben.
Der Verkaufspreis beträgt [SALE_PRICE] L$ und wird automatisch für den Verkauf an [NAME] autorisiert.
@@ -409,17 +412,17 @@ Gebühren werden nicht rückerstattet.
<usetemplate name="okcancelbuttons" notext="Abbrechen" yestext="OK"/>
</notification>
<notification name="CacheWillClear">
- Der Cache wird nach einem Neustart von [SECOND_LIFE] geleert.
+ Der Cache wird nach einem Neustart von [APP_NAME] geleert.
</notification>
<notification name="CacheWillBeMoved">
- Der Cache wird nach einem Neustart von [SECOND_LIFE] verschoben.
+ Der Cache wird nach einem Neustart von [APP_NAME] verschoben.
Hinweis: Der Cache wird dabei gelöscht/geleert.
</notification>
<notification name="ChangeConnectionPort">
- Die Port-Einstellungen werden nach einem Neustart von [SECOND_LIFE] wirksam.
+ Die Port-Einstellungen werden nach einem Neustart von [APP_NAME] wirksam.
</notification>
<notification name="ChangeSkin">
- Die neue Benutzeroberfläche wird nach einem Neustart von [SECOND_LIFE] angewendet.
+ Die neue Benutzeroberfläche wird nach einem Neustart von [APP_NAME] angewendet.
</notification>
<notification name="GoToAuctionPage">
Zur [SECOND_LIFE]-Webseite, um Auktionen anzuzeigen oder ein Gebot abzugeben?
@@ -478,7 +481,7 @@ Das Objekt ist möglicherweise außer Reichweite oder wurde gelöscht.
Datei [[FILE]] kann nicht geschrieben werden
</notification>
<notification name="UnsupportedHardware">
- Achtung: Ihr System erfüllt nicht die Mindestanforderungen von Second Life. Dies kann eine schlechte Darstellungsleistung in Second Life zur Folge haben. Für nicht unterstützte Systemkonfigurationen bieten wir keinen technischen Support.
+ Achtung: Ihr System erfüllt nicht die Mindestanforderungen von [APP_NAME]. Dies kann eine schlechte Darstellungsleistung in [APP_NAME] zur Folge haben. Für nicht unterstützte Systemkonfigurationen bieten wir keinen technischen Support.
MINSPECS
Die Seite [_URL] für weitere Informationen öffnen?
@@ -490,14 +493,14 @@ Die Seite [_URL] für weitere Informationen öffnen?
<notification name="UnknownGPU">
Ihr System verwendet eine uns zurzeit unbekannte Grafikkarte.
Dies ist häufig der Fall bei neuer Hardware, die wir noch nicht testen konnten.
-Second Life funktioniert aller Voraussicht nach normal, möglicherweise müssen Sie aber die Grafikeinstellungen anpassen.
+[APP_NAME] funktioniert aller Voraussicht nach normal, möglicherweise müssen Sie aber die Grafikeinstellungen anpassen.
(Bearbeiten &gt; Einstellungen &gt; Grafik).
<form name="form">
<ignore name="ignore" text="Bei Entdeckung einer unbekannten Grafikkarte"/>
</form>
</notification>
<notification name="DisplaySettingsNoShaders">
- [SECOND_LIFE] ist bei der Initialisierung der Grafiktreiber abgestürzt.
+ [APP_NAME] ist bei der Initialisierung der Grafiktreiber abgestürzt.
Die Grafikqualität wird auf eine niedrige Stufe zurückgesetzt, um einige typische Treiberfehler zu vermeiden.
Einige Grafikfunktionen werden ausgeschaltet.
Wir empfehlen die Aktualisierung Ihrer Grafikkartentreiber.
@@ -780,8 +783,7 @@ Keine Parzelle ausgewählt.
Kann die Region nicht finden, in der sich dieses Land befindet.
</notification>
<notification name="CannotCloseFloaterBuyLand">
- Das Fenster „Land kaufen“ kann erst geschlossen werden,
-nachdem Second Life den Transaktionspreis geschätzt hat.
+ Das Fenster „Land kaufen“ kann erst geschlossen werden, nachdem [APP_NAME] den Transaktionspreis geschätzt hat.
</notification>
<notification name="CannotDeedLandNothingSelected">
Land kann nicht übertragen werden:
@@ -953,7 +955,7 @@ Tritt dieses Problem wiederholt auf, klicken Sie auf das Pulldown-Menü „Hilfe
<notification name="YouHaveBeenLoggedOut">
Sie wurden von [SECOND_LIFE] abgemeldet:
[MESSAGE]
-Klicken Sie auf „IM &amp; Chat anzeigen“, um vorhandene Nachrichten und Chat weiterhin anzuzeigen. Klicken Sie andernfalls auf „Beenden“, um [SECOND_LIFE] sofort zu beenden.
+Klicken Sie auf „IM &amp; Chat anzeigen“, um vorhandene Nachrichten und Chat weiterhin anzuzeigen. Klicken Sie andernfalls auf „Beenden“, um [APP_NAME] sofort zu beenden.
<usetemplate name="okcancelbuttons" notext="Beenden" yestext="IM &amp; Chat anzeigen"/>
</notification>
<notification name="OnlyOfficerCanBuyLand">
@@ -1124,14 +1126,14 @@ Sie können [SECOND_LIFE] normal verwenden. Andere Benutzer können Sie korrekt
</form>
</notification>
<notification name="FirstRun">
- Die Installation von [SECOND_LIFE] ist abgeschlossen.
+ Die Installation von [APP_NAME] ist abgeschlossen.
Wenn Sie [SECOND_LIFE] das erste Mal verwenden, müssen Sie ein Konto anlegen, bevor Sie sich anmelden können.
Möchten Sie auf www.secondlife.com ein Konto erstellen?
<usetemplate name="okcancelbuttons" notext="Weiter" yestext="Neues Konto..."/>
</notification>
<notification name="LoginPacketNeverReceived">
- Die Verbindung kann nicht hergestellt werden. Möglicherweise besteht ein Problem mit Ihrer Internetverbindung oder den Second Life-Servern.
+ Die Verbindung kann nicht hergestellt werden. Möglicherweise besteht ein Problem mit Ihrer Internetverbindung oder den [SECOND_LIFE]-Servern.
Überprüfen Sie Ihre Internetverbindung und versuchen Sie es dann erneut, oder klicken Sie auf „Hilfe“, um zu unserer Supportseite zu gelangen, oder klicken Sie auf „Teleportieren“, um nach Hause zu teleportieren.
<form name="form">
@@ -1234,33 +1236,33 @@ Geben Sie das Objekt zum Verkauf frei und versuchen Sie es erneut.
[DOWNLOAD_PATH].
</notification>
<notification name="DownloadWindowsMandatory">
- Eine neue Version von [SECOND_LIFE] ist verfügbar.
+ Eine neue Version von [APP_NAME] ist verfügbar.
[MESSAGE]
-Sie müssen das Update herunterladen, um [SECOND_LIFE] weiter verwenden zu können.
+Sie müssen das Update herunterladen, um [APP_NAME] weiter verwenden zu können.
<usetemplate name="okcancelbuttons" notext="Beenden" yestext="Herunterladen"/>
</notification>
<notification name="DownloadWindows">
- Eine aktualisierte Version von [SECOND_LIFE] ist verfügbar.
+ Eine aktualisierte Version von [APP_NAME] ist verfügbar.
[MESSAGE]
Dieses Update ist nicht erforderlich, für bessere Leistung und Stabilität sollte es jedoch installiert werden.
<usetemplate name="okcancelbuttons" notext="Weiter" yestext="Herunterladen"/>
</notification>
<notification name="DownloadWindowsReleaseForDownload">
- Eine aktualisierte Version von [SECOND_LIFE] ist verfügbar.
+ Eine aktualisierte Version von [APP_NAME] ist verfügbar.
[MESSAGE]
Dieses Update ist nicht erforderlich, für bessere Leistung und Stabilität sollte es jedoch installiert werden.
<usetemplate name="okcancelbuttons" notext="Weiter" yestext="Herunterladen"/>
</notification>
<notification name="DownloadMacMandatory">
- Eine neue Version von [SECOND_LIFE] ist verfügbar.
+ Eine neue Version von [APP_NAME] ist verfügbar.
[MESSAGE]
-Sie müssen das Update herunterladen, um [SECOND_LIFE] weiter verwenden zu können.
+Sie müssen das Update herunterladen, um [APP_NAME] weiter verwenden zu können.
In Ihren Anwendungsordner herunterladen?
<usetemplate name="okcancelbuttons" notext="Beenden" yestext="Herunterladen"/>
</notification>
<notification name="DownloadMac">
- Eine aktualisierte Version von [SECOND_LIFE] ist verfügbar.
+ Eine aktualisierte Version von [APP_NAME] ist verfügbar.
[MESSAGE]
Dieses Update ist nicht erforderlich, für bessere Leistung und Stabilität sollte es jedoch installiert werden.
@@ -1268,7 +1270,7 @@ In Ihren Anwendungsordner herunterladen?
<usetemplate name="okcancelbuttons" notext="Weiter" yestext="Herunterladen"/>
</notification>
<notification name="DownloadMacReleaseForDownload">
- Eine aktualisierte Version von [SECOND_LIFE] ist verfügbar.
+ Eine aktualisierte Version von [APP_NAME] ist verfügbar.
[MESSAGE]
Dieses Update ist nicht erforderlich, für bessere Leistung und Stabilität sollte es jedoch installiert werden.
@@ -1828,7 +1830,7 @@ Wenn dieses Feld leer ist, werden Missbrauchsmeldungen nur an Linden Lab gesende
Standard: deaktiviert
</notification>
<notification label="Falsche Voice-Version" name="VoiceVersionMismatch">
- Diese Version von Second ist mit dem Voice-Chat-Feature in dieser Region nicht kompatibel. Damit Voice-Chat funktioniert, müssen Sie Second Life aktualisieren.
+ Diese Version von [APP_NAME] mit dem Voice-Chat-Feature in dieser Region nicht kompatibel. Damit Voice-Chat funktioniert, müssen Sie [APP_NAME] aktualisieren.
</notification>
<notification label="Grunstücksvertrag" name="HelpEstateCovenant">
Ein Grundstücksvertrag ermöglicht es Ihnen, Grundstücksparzellen zu verkaufen. Ohne Vertrag können Sie kein Land verkaufen. Wenn Sie keine Regeln festlegen oder Käufern vor dem Kauf keine anderen Informationen über das Land bereitstellen möchten, können Sie die Vertrags-Notizkarte auch leer lassen.
@@ -1943,16 +1945,16 @@ Inventarobjekt(e) verschieben?
Sie haben keine Berechtigung zum Kopieren von Elementen in diesem Objekt.
</notification>
<notification name="WebLaunchAccountHistory">
- Zur Second Life-Website, um Ihre Kontostatistik anzuzeigen?
+ Zur [SECOND_LIFE]-Website, um Ihre Kontostatistik anzuzeigen?
<usetemplate ignoretext="Beim Laden der Kontostatistik-Website" name="okcancelignore" notext="Abbrechen" yestext="Gehe zu Seite"/>
</notification>
<notification name="ClickOpenF1Help">
- Die Support-Website von Second Life öffnen?
- <usetemplate ignoretext="Bei Besuch der Second Life Support-Website." name="okcancelignore" notext="Abbrechen" yestext="Los"/>
+ Die Support-Website von [SECOND_LIFE] öffnen?
+ <usetemplate ignoretext="Bei Besuch der [SECOND_LIFE] Support-Website." name="okcancelignore" notext="Abbrechen" yestext="Los"/>
</notification>
<notification name="ConfirmQuit">
Wirklich beenden?
- <usetemplate ignoretext="Beim Beenden von Second Life." name="okcancelignore" notext="Weiter" yestext="Beenden"/>
+ <usetemplate ignoretext="Beim Beenden von [APP_NAME]." name="okcancelignore" notext="Weiter" yestext="Beenden"/>
</notification>
<notification name="HelpReportAbuseEmailLL">
Verwenden Sie dieses Tool, um Verletzungen der Servicebedingungen und Community-Standards zu melden. Siehe:
@@ -1970,7 +1972,7 @@ http://secondlife.com/support/incidentreport.php
Als besonderen Service für Einwohner und Besucher übernimmt der Eigentümer dieser Region die Bearbeitung aller anfallenden Meldungen. Von diesem Standort aus eingereichte Meldungen werden nicht von Linden Lab bearbeitet. Der Eigentümer der Region bearbeitet Meldungen auf Grundlage der Richtlinien, die im für diese Region geltenden Grundstücksvertrag festgelegt sind.
(Den Vertrag können Sie unter „Welt“ &gt; „Land-Info“ einsehen.)
-
-Das Resultat, das sich aus dieser Meldung ergibt, betrifft nur diese Region; der Einwohnerzugang zu anderen Bereichen von Second Life ist davon nicht betroffen. Nur Linden Lab kann den Zugang zu Second Life beschränken.
+Das Resultat, das sich aus dieser Meldung ergibt, betrifft nur diese Region; der Einwohnerzugang zu anderen Bereichen von [SECOND_LIFE] ist davon nicht betroffen. Nur Linden Lab kann den Zugang zu [SECOND_LIFE] beschränken.
</notification>
<notification name="HelpReportBug">
Verwenden Sie dieses Tool *nur*, um technische Features zu melden, die nicht wie beschrieben oder erwartet funktionieren. Bitte machen Sie so viele Angaben wie möglich. Sie können auf die automatische Antwort-E-Mail antworten, um Ihre Meldung noch zu ergänzen.
@@ -2018,9 +2020,9 @@ Eine möglichst genaue Beschreibung mit Schritten zur Reproduktion des Fehlers h
Sie melden eine Urheberrechtsverletzung. Sind Sie wirklich sicher, dass Sie eine Verletzung des Urheberrechts melden möchten?
-1. Missbrauch melden. Wenn Sie der Meinung sind, ein Einwohner nutzt das Berechtigungssystem von Second Life auf unerlaubte Weise zu seinem Vorteil aus, indem er zum Beispiel einen CopyBot oder ähnliche Kopiertools verwendet und damit eine Urheberrechtsverletzung begeht, können Sie diesen Missbrauch melden. Das Missbrauchsteam untersucht etwaige Verstöße gegen die Second Life Community Standards oder die Nutzungsbedingungen und verhängt entsprechende Strafen. Das Missbrauchsteam ist jedoch nicht dafür zuständig, Inhalte aus der Second Life-Welt zu entfernen und reagiert auch nicht auf entsprechende Anfragen.
+1. Missbrauch melden. Wenn Sie der Meinung sind, ein Einwohner nutzt das Berechtigungssystem von [SECOND_LIFE] auf unerlaubte Weise zu seinem Vorteil aus, indem er zum Beispiel einen CopyBot oder ähnliche Kopiertools verwendet und damit eine Urheberrechtsverletzung begeht, können Sie diesen Missbrauch melden. Das Missbrauchsteam untersucht etwaige Verstöße gegen die [SECOND_LIFE] Community Standards oder die Nutzungsbedingungen und verhängt entsprechende Strafen. Das Missbrauchsteam ist jedoch nicht dafür zuständig, Inhalte aus der [SECOND_LIFE]-Welt zu entfernen und reagiert auch nicht auf entsprechende Anfragen.
-2. Der DMCA oder das Entfernen von Inhalten. Sie können das Entfernen von Inhalten aus Second Life beantragen. Dazu MÜSSEN Sie eine Urheberrechtsverletzung gemäß den in unserer DMCA-Richtlinie unter http://secondlife.com/corporate/dmca.php dargelegten Anweisungen einreichen.
+2. Der DMCA oder das Entfernen von Inhalten. Sie können das Entfernen von Inhalten aus [SECOND_LIFE] beantragen. Dazu MÜSSEN Sie eine Urheberrechtsverletzung gemäß den in unserer DMCA-Richtlinie unter http://secondlife.com/corporate/dmca.php dargelegten Anweisungen einreichen.
Wenn Sie mit der Missbrauchmeldung jetzt fortfahren möchten, schließen Sie bitte dieses Fenster und senden Sie Ihren Bericht ein. Möglicherweise müssen Sie Kategorie „CopyBot oder Berechtigungs-Exploit“ auswählen.
@@ -2072,12 +2074,12 @@ Möchten Sie den Bechäftigt-Modus verlassen, bevor Sie diese Transaktion abschl
<usetemplate ignoretext="Beim Leeren von Inventar und Fundstückeordner-" name="okcancelignore" notext="Nein" yestext="Ja"/>
</notification>
<notification name="CopySLURL">
- Die folgende SLURL wurde in die Zwischenablage kopiert:
+ Die folgende SLurl wurde in die Zwischenablage kopiert:
[SLURL]
Veröffentlichen Sie sie auf einer Website, um anderen den Zugang zu diesem Ort zu erleichtern, oder testen Sie sie, indem Sie sie in die Adressleiste Ihres Browsers kopieren.
<form name="form">
- <ignore name="ignore" text="Beim Kopieren einer SLURL in die Zwischenablage"/>
+ <ignore name="ignore" text="Beim Kopieren einer SLurl in die Zwischenablage"/>
</form>
</notification>
<notification name="GraphicsPreferencesHelp">
@@ -2143,7 +2145,7 @@ Klicken Sie auf „Himmel (erweitert)“, um einen Editor mit erweiterten Einste
Klicken Sie auf „Wasser (erweitert)“, um einen Editor mit erweiterten Einstellungen für die Wasserdarstellung anzuzeigen.
</notification>
<notification name="HelpDayCycle">
- Im Tageszyklus-Editor steuern Sie den Tag-/Nachtzyklus am Second Life Himmel. Dabei handelt es sich um den Zyklus, der mit dem Tageszeit-Regler im Umwelt-Basiseditor gesteuert wird.
+ Im Tageszyklus-Editor steuern Sie den Tag-/Nachtzyklus am [SECOND_LIFE] Himmel. Dabei handelt es sich um den Zyklus, der mit dem Tageszeit-Regler im Umwelt-Basiseditor gesteuert wird.
Der Tageszyklus-Editor verwendet sogenannte Keyframes zur Steuerung des Tag-/Nachtablaufs. Dabei handelt es sich um „Schlüsselbilder“ (die grauen Kreise auf der Zeitskala), für die bestimmte Himmelseinstellungen definiert wurden. Bei voranschreitender Tageszeit interpoliert WindLight den Übergang zwischen diesen Keyframes und erzeugt eine entsprechende Himmelsanimation.
@@ -2222,7 +2224,7 @@ Entspricht dem Azimut.
Steuert die Bewegungsgeschwindigkeit der Wolken in Y-Richtung.
</notification>
<notification name="HelpClassicClouds">
- Aktivieren Sie dieses Kontrollkästchen, um die Darstellung der klassischen Second Life Wolken zusätzlich zu den WindLight-Wolken zu erzwingen.
+ Aktivieren Sie dieses Kontrollkästchen, um die Darstellung der klassischen [SECOND_LIFE] Wolken zusätzlich zu den WindLight-Wolken zu erzwingen.
</notification>
<notification name="HelpWaterFogColor">
Steuert die Farbe der Wassertrübung
@@ -2320,7 +2322,7 @@ Entspricht dem Azimut.
</notification>
<notification name="NotAgeVerified">
Um Zugang zu dieser Parzelle zu erhalten, müssen Sie sich einer Altersprüfung unterziehen.
-Möchten Sie auf der Second Life Website eine Altersüberprüfung durchführen?
+Möchten Sie auf der [SECOND_LIFE] Website eine Altersüberprüfung durchführen?
[_URL]
<url name="url" option="0">
@@ -2330,7 +2332,7 @@ Möchten Sie auf der Second Life Website eine Altersüberprüfung durchführen?
</notification>
<notification name="Cannot enter parcel: no payment info on file">
Um Zugang zu dieser Parzelle zu erhalten, müssen Sie Zahlungsinformationen hinterlegt haben.
-Möchten Sie die Second Life Website öffnen, um diese Angaben zu hinterlegen?
+Möchten Sie die [SECOND_LIFE] Website öffnen, um diese Angaben zu hinterlegen?
[_URL]
<url name="url" option="0">
@@ -2775,7 +2777,7 @@ Von Objekt: [OBJECTNAME], Eigentümer: [NAME]?
[TYPE] namens [DESC] nicht in Datenbank.
</notification>
<notification name="InvalidWearable">
- Dieser Artikel verwendet eine Funktion, die Ihr Viewer nicht unterstützt. Bitte aktualisieren Sie Ihre Version von Second Life, um diesen Artikel anziehen zu können.
+ Dieser Artikel verwendet eine Funktion, die Ihr Viewer nicht unterstützt. Bitte aktualisieren Sie Ihre Version von [APP_NAME], um diesen Artikel anziehen zu können.
</notification>
<notification name="ScriptQuestion">
Das Objekt „[OBJECTNAME]“, Eigentum von „[NAME]“, möchte:
@@ -2880,7 +2882,7 @@ Ein flexibles Objekt ist ein Phantom und nicht physisch, bis die Option „Flexi
</notification>
<notification name="FirstDebugMenus">
Sie haben das Advanced-Menü aktiviert.
-Dieses Menü enthält nützliche Funktionen zum Debuggen von Second Life.
+Dieses Menü enthält nützliche Funktionen zum Debuggen von [SECOND_LIFE].
Drücken Sie in Windows Strg-Alt-D (Mac: Befehl-Opt-Umschalt-D) zum Ein- und Ausschalten dieses Menüs.
</notification>
<notification name="FirstSculptedPrim">
@@ -2989,7 +2991,7 @@ Klicken Sie auf „Akzeptieren“, um dem Chat beizutreten, oder auf „Ablehnen
- Ihre CPU-Geschwindigkeit entspricht nicht den Mindestanforderungen.
</global>
<global name="UnsupportedGLRequirements">
- Ihr Computer entspricht nicht den Hardwareanforderungen von Second Life. Second Life setzt eine OpenGL-Grafikkarte mit Multitextur-Unterstützung voraus. Falls Ihre Grafikkarte diese Funktion unterstützt, installieren Sie die neuesten Treiber sowie die aktuellen Service Packs und Patches für Ihr Betriebssystem.
+ Ihr Computer entspricht nicht den Hardwareanforderungen von [APP_NAME]. [APP_NAME] setzt eine OpenGL-Grafikkarte mit Multitextur-Unterstützung voraus. Falls Ihre Grafikkarte diese Funktion unterstützt, installieren Sie die neuesten Treiber sowie die aktuellen Service Packs und Patches für Ihr Betriebssystem.
Sollte das Problem fortbestehen, finden Sie weitere Hilfestellung unter: http://www.secondlife.com/support
</global>
diff --git a/indra/newview/skins/default/xui/de/panel_group_general.xml b/indra/newview/skins/default/xui/de/panel_group_general.xml
index ce19248755..2ce40e5787 100644
--- a/indra/newview/skins/default/xui/de/panel_group_general.xml
+++ b/indra/newview/skins/default/xui/de/panel_group_general.xml
@@ -47,6 +47,89 @@ Bewegen Sie die Maus über die Optionen, um weitere Informationen anzuzeigen.
<panel name="preferences_container">
<check_box label="In Suche anzeigen" name="show_in_group_list" tool_tip="Diese Gruppe in Suchergebnissen anzeigen."/>
<check_box label="Registrierung offen" name="open_enrollement" tool_tip="Festlegen, ob der Gruppenbeitritt ohne Einladung zulässig ist."/>
+ <check_box label="Beitrittsgebühr: L$" name="check_enrollment_fee" tool_tip="Festlegen, ob Neumitglieder eine Beitrittsgebühr zahlen müssen."/>
+ <spinner name="spin_enrollment_fee" tool_tip="Wenn „Beitrittsgebühr“ aktiviert ist, müssen neue Mitglieder diesen Betrag zahlen."/>
+ <combo_box name="group_mature_check" tool_tip="Festlegen, ob die Informationen Ihrer Gruppe „Mature“ sind.">
+ <combo_item name="select_mature">
+ - Mature wählen -
+ </combo_item>
+ <combo_item name="mature">
+ Mature-Inhalt
+ </combo_item>
+ <combo_item name="pg">
+ PG-Inhalt
+ </combo_item>
+ </combo_box>
+ <panel name="title_container">
+ <text name="active_title_label">
+ Mein aktiver Titel
+ </text>
+ <combo_box name="active_title" tool_tip="Legt fest, was im Namensschild Ihres Avatars angezeigt wird, wenn diese Gruppe aktiviert ist."/>
+ </panel>
+ <check_box label="Gruppenmitteilungen erhalten" name="receive_notices" tool_tip="Festlegen, ob Sie von dieser Gruppe Mitteilungen erhalten können. Deaktivieren Sie diese Option, wenn Sie von der Gruppe Spam erhalten."/>
+ <check_box label="Gruppe im Profil anzeigen" name="list_groups_in_profile" tool_tip="Steuert, ob diese Gruppe in Ihrem Profil angezeigt wird"/>
+ </panel>
+ <string name="incomplete_member_data_str">
+ Mitgliedsdaten werden abgerufen
+ </string>
+ <string name="confirm_group_create_str">
+ Die Gründung dieser Gruppe kostet 100 L$.
+Sind Sie wirklich, WIRKLICH sicher, dass Sie 100 L$ für die Gründung dieser Gruppe ausgeben möchten?
+Falls in den nächsten 48 Stunden niemand sonst dieser Gruppe beitritt, wird sie aufgelöst und der Name der Gruppe wird nicht mehr verfügbar sein.
+ </string>
+</panel>
+
+<!-- original file
+
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel label="Allgemein" name="general_tab">
+ <string name="help_text">
+ Die Registerkarte „Allgemein“ enthält Informationen über
+diese Gruppe, eine Liste der Eigentümer und sichtbaren Mitglieder,
+allgemeine Gruppeneinstellungen und Mitgliederoptionen.
+
+Bewegen Sie die Maus über die Optionen, um weitere Informationen anzuzeigen.
+ </string>
+ <string name="group_info_unchanged">
+ Die allgemeine Gruppeninfo wurde geändert.
+ </string>
+ <button label="?" label_selected="?" name="help_button"/>
+ <line_editor label="Neuen Gruppennamen hier eingeben" name="group_name_editor"/>
+ <text name="group_name">
+ Neuen Gruppennamen hier eingeben
+ </text>
+ <text name="prepend_founded_by">
+ Gegründet von
+ </text>
+ <text left_delta="79" name="founder_name">
+ (wartet)
+ </text>
+ <text name="group_charter_label">
+ Gruppencharta
+ </text>
+ <texture_picker label="Gruppeninsignien" name="insignia" tool_tip="Klicken Sie hier, um ein Bild auszuwählen"/>
+ <text_editor name="charter">
+ Gruppencharta
+ </text_editor>
+ <button label="Beitreten (0 L$)" label_selected="Beitreten (0 L$)" name="join_button"/>
+ <button label="Detailansicht" label_selected="Detailansicht" name="info_button"/>
+ <text name="text_owners_and_visible_members">
+ Eigentümer und sichtbare Mitglieder
+ </text>
+ <text name="text_owners_are_shown_in_bold">
+ (Eigentümer werden fettgedruckt angezeigt)
+ </text>
+ <name_list name="visible_members">
+ <column label="Mitgliedsname" name="name" relwidth="0.40"/>
+ <column label="Titel" name="title" relwidth="0.25"/>
+ <column label="Letzte Anmeldung" name="online" relwidth="0.35"/>
+ </name_list>
+ <text name="text_group_preferences">
+ Gruppeneinstellungen
+ </text>
+ <panel name="preferences_container">
+ <check_box label="In Suche anzeigen" name="show_in_group_list" tool_tip="Diese Gruppe in Suchergebnissen anzeigen."/>
+ <check_box label="Registrierung offen" name="open_enrollement" tool_tip="Festlegen, ob der Gruppenbeitritt ohne Einladung zulässig ist."/>
<check_box label="Beitrittsgebühr: L$" name="check_enrollment_fee" tool_tip="Festlegen, ob Neumitglieder eine Beitrittsgebühr zahlen müssen." width="125"/>
<spinner name="spin_enrollment_fee" tool_tip="Wenn „Beitrittsgebühr“ aktiviert ist, müssen neue Mitglieder diesen Betrag zahlen."/>
<combo_box name="group_mature_check" tool_tip="Festlegen, ob die Informationen Ihrer Gruppe „Mature“ sind.">
@@ -78,3 +161,5 @@ Sind Sie wirklich, WIRKLICH sicher, dass Sie 100 L$ für die Gründung dieser Gr
Falls in den nächsten 48 Stunden niemand sonst dieser Gruppe beitritt, wird sie aufgelöst und der Name der Gruppe wird nicht mehr verfügbar sein.
</string>
</panel>
+
+-->
diff --git a/indra/newview/skins/default/xui/de/panel_group_land_money.xml b/indra/newview/skins/default/xui/de/panel_group_land_money.xml
index c038d97822..e2e30b7479 100644
--- a/indra/newview/skins/default/xui/de/panel_group_land_money.xml
+++ b/indra/newview/skins/default/xui/de/panel_group_land_money.xml
@@ -52,6 +52,90 @@
qm (max. [AMOUNT])
</text>
<text name="group_over_limit_text">
+ Die Gruppenmitglieder müssen mehr Landnutzungsrechte spenden, damit das verwendete Land gehalten werden kann.
+ </text>
+ <text name="group_money_heading">
+ Gruppen-L$
+ </text>
+ <tab_container name="group_money_tab_container">
+ <panel label="Planung" name="group_money_planning_tab">
+ <text_editor name="group_money_planning_text">
+ Wird berechnet...
+ </text_editor>
+ </panel>
+ <panel label="Details" name="group_money_details_tab">
+ <text_editor name="group_money_details_text">
+ Wird berechnet...
+ </text_editor>
+ <button label="&lt; Früher" label_selected="&lt; Früher" name="earlier_details_button" tool_tip="Zurück in der Zeit"/>
+ <button label="Später &gt;" label_selected="Später &gt;" name="later_details_button" tool_tip="Weiter in der Zeit"/>
+ </panel>
+ <panel label="Verkäufe" name="group_money_sales_tab">
+ <text_editor name="group_money_sales_text">
+ Wird berechnet...
+ </text_editor>
+ <button label="&lt; Früher" label_selected="&lt; Früher" name="earlier_sales_button" tool_tip="Zurück in der Zeit"/>
+ <button label="Später &gt;" label_selected="Später &gt;" name="later_sales_button" tool_tip="Weiter in der Zeit"/>
+ </panel>
+ </tab_container>
+</panel>
+
+<!--
+
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel label="Land und L$" name="land_money_tab">
+ <string name="help_text">
+ Parzellen in Gruppenbesitz werden zusammen mit Beitragsdetails angezeigt. Ein Warnhinweis wird angezeigt, solange der Wert für das insgesamt verwendete Land gleich oder weniger ist als der Gesamtbeitrag. Die Registerkarten „Planung“, „Details“ und „Verkäufe“ enthalten Informationen über die Gruppenfinanzen.
+ </string>
+ <button label="?" name="help_button"/>
+ <string name="cant_view_group_land_text">
+ Sie sind nicht berechtigt, Landeigentum der Gruppe anzuzeigen.
+ </string>
+ <string name="cant_view_group_accounting_text">
+ Sie sind nicht berechtigt, die Finanzinformationen der Gruppe anzuzeigen.
+ </string>
+ <string name="loading_txt">
+ Wird geladen...
+ </string>
+ <text name="group_land_heading">
+ Land in Gruppenbesitz
+ </text>
+ <scroll_list name="group_parcel_list">
+ <column label="Parzellenname" name="name"/>
+ <column label="Region" name="location"/>
+ <column label="Typ" name="type"/>
+ <column label="Gebiet" name="area"/>
+ <column label="" name="hidden"/>
+ </scroll_list>
+ <button label="Auf Karte" label_selected="Auf Karte" name="map_button"/>
+ <text name="total_contributed_land_label">
+ Gesamtbeitrag:
+ </text>
+ <text name="total_contributed_land_value">
+ [AREA] qm
+ </text>
+ <text name="total_land_in_use_label">
+ Insgesamt verwendetes Land:
+ </text>
+ <text name="total_land_in_use_value">
+ [AREA] qm
+ </text>
+ <text name="land_available_label">
+ Land verfügbar:
+ </text>
+ <text name="land_available_value">
+ [AREA] qm
+ </text>
+ <text name="your_contribution_label">
+ Ihr Beitrag:
+ </text>
+ <string name="land_contrib_error">
+ Ihr Landbeitrag kann nicht festgelegt werden.
+ </string>
+ <text name="your_contribution_max_value">
+ qm (max. [AMOUNT])
+ </text>
+ <text name="group_over_limit_text">
Die Gruppenmitglieder müssen mehr Landnutzungsrechte spenden, damit
das verwendete Land gehalten werden kann.
</text>
@@ -80,3 +164,5 @@ das verwendete Land gehalten werden kann.
</panel>
</tab_container>
</panel>
+
+-->
diff --git a/indra/newview/skins/default/xui/de/panel_group_notices.xml b/indra/newview/skins/default/xui/de/panel_group_notices.xml
index 12dcbb1321..8d4afd356e 100644
--- a/indra/newview/skins/default/xui/de/panel_group_notices.xml
+++ b/indra/newview/skins/default/xui/de/panel_group_notices.xml
@@ -16,6 +16,81 @@ gesendet. Mitteilungen können unter
Gruppenmitteilungsarchiv
</text>
<text name="lbl2">
+ Mitteilungen werden 14 Tage lang aufbewahrt. Klicken Sie auf eine Mitteilung, um sie anzuzeigen. Klicken Sie „Aktualisieren“, um neue Mitteilungen zu suchen. Eine Mitteilungsliste speichert maximal 200 Mitteilungen pro Gruppe täglich.
+ </text>
+ <scroll_list name="notice_list">
+ <column label="" name="icon" />
+ <column label="Thema" name="subject" />
+ <column label="Von" name="from" />
+ <column label="Datum" name="date" />
+ </scroll_list>
+ <text name="notice_list_none_found">
+ Nicht gefunden.
+ </text>
+ <button label="Neue Mitteilung" label_selected="Neue Mitteilung"
+ name="create_new_notice" />
+ <button label="Aktualisieren" label_selected="Liste aktualisieren"
+ name="refresh_notices" />
+ <panel label="Neue Mitteilung" name="panel_create_new_notice">
+ <text name="lbl">
+ Mitteilung schreiben
+ </text>
+ <text name="lbl2">
+ Geben Sie einen Betreff für die Mitteilung ein. Sie können der Mitteilung ein Objekt anfügen, indem Sie es aus dem Inventar in dieses Feld ziehen. Angehängte Objekte müssen kopier-und transferierbar sein. Ordner können nicht gesendet werden.
+ </text>
+ <text name="lbl3">
+ Betreff:
+ </text>
+ <text name="lbl4">
+ Nachricht:
+ </text>
+ <text name="lbl5">
+ Anhängen:
+ </text>
+ <button label="Anhang entfernen" label_selected="Anhang entfernen"
+ name="remove_attachment" />
+ <button label="Mitteilung senden" label_selected="Mitteilung senden" name="send_notice" />
+ <panel name="drop_target"
+ tool_tip="Drag an inventory item onto the message box to send it with the notice. You must have permission to copy and transfer the object to send it with the notice." />
+ </panel>
+ <panel label="Ältere Notiz anzeigen" name="panel_view_past_notice">
+ <text name="lbl">
+ Archivierte Mitteilung
+ </text>
+ <text name="lbl2">
+ Klicken Sie zum Senden einer Mitteilung auf „Neue Mitteilung“.
+ </text>
+ <text name="lbl3">
+ Betreff:
+ </text>
+ <text name="lbl4">
+ Nachricht:
+ </text>
+ <button label="Anlage öffnen" label_selected="Anlage öffnen" name="open_attachment" />
+ </panel>
+</panel>
+
+
+<!-- original file
+
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<panel label="Mitteilungen" name="notices_tab">
+ <text name="help_text">
+ Mitteilungen sind eine schnelle Möglichkeit,
+Mitglieder auf dem Laufenden zu halten und
+Objekte im Anhang zu versenden. Mitteilungen werden
+nur an Mitglieder mit einer entsprechenden Rolle
+gesendet. Mitteilungen können unter
+„Allgemein“ ausgeschaltet werden.
+ </text>
+ <text name="no_notices_text">
+ Keine älteren Mitteilungen.
+ </text>
+ <button label="?" label_selected="?" name="help_button" />
+ <text name="lbl">
+ Gruppenmitteilungsarchiv
+ </text>
+ <text name="lbl2">
Mitteilungen werden 14 Tage lang aufbewahrt. Klicken Sie auf eine Mitteilung,
um sie anzuzeigen. Klicken Sie „Aktualisieren“, um neue Mitteilungen zu suchen.
Eine Mitteilungsliste speichert maximal 200 Mitteilungen pro Gruppe täglich.
@@ -74,3 +149,8 @@ und transferierbar sein. Ordner können nicht gesendet werden.
<button label="Anlage öffnen" label_selected="Anlage öffnen" name="open_attachment" />
</panel>
</panel>
+
+-->
+
+
+
diff --git a/indra/newview/skins/default/xui/de/panel_group_roles.xml b/indra/newview/skins/default/xui/de/panel_group_roles.xml
index d4589f83e4..d7f47de46f 100644
--- a/indra/newview/skins/default/xui/de/panel_group_roles.xml
+++ b/indra/newview/skins/default/xui/de/panel_group_roles.xml
@@ -12,8 +12,165 @@
Mitglieder und Rollen
</text>
<text name="static2">
- Gruppenmitgliedern werden Rollen mit Fähigkeiten zugewiesen. Diese
-Einstellungen können zur flexibleren Organisation angepasst werden.
+ Gruppenmitgliedern werden Rollen mit Fähigkeiten zugewiesen. Diese Einstellungen können zur flexibleren Organisation angepasst werden.
+ </text>
+ </panel>
+ <panel name="roles_header">
+ <text name="static">
+ Rollen
+ </text>
+ <text name="role_properties_modifiable">
+ Wählen Sie eine Rolle. Sie können ihren Namen, ihre Beschreibung und den Mitgliedstitel ändern.
+ </text>
+ <text name="role_properties_not_modifiable">
+ Rolle anklicken um Mitglieder und Fähigkeiten anzuzeigen.
+ </text>
+ <text name="role_actions_modifiable">
+ Sie können der Rolle auch Fähigkeiten zuweisen.
+ </text>
+ <text name="role_actions_not_modifiable">
+ Sie können zugewiesene Fähigkeiten anzeigen, aber nicht bearbeiten.
+ </text>
+ </panel>
+ <panel name="actions_header">
+ <text name="static">
+ Fähigkeiten
+ </text>
+ <text name="static2">
+ Sie können Fähigkeiten-Beschreibungen anzeigen und welche Rollen bzw. Mitglieder diese Fähigkeit haben.
+ </text>
+ </panel>
+ <tab_container name="roles_tab_container">
+ <panel label="Mitglieder" name="members_sub_tab" tool_tip="Mitglieder">
+ <button label="Suchen" name="search_button"/>
+ <button label="Alle anzeigen" name="show_all_button"/>
+ <name_list name="member_list">
+ <column label="Mitgliedsname" name="name"/>
+ <column label="Ãœbertragene Landanteile" name="donated"/>
+ <column label="Letzte Anmeldung" name="online"/>
+ </name_list>
+ <button label="Neues Mitglied einladen..." name="member_invite"/>
+ <button label="Aus Gruppe werfen" name="member_eject"/>
+ <string name="help_text">
+ Sie können Mitgliedern Rollen zuweisen und entziehen.
+Drücken Sie die Strg-Taste und klicken Sie auf Namen,
+um mehrere Mitglieder auszuwählen.
+ </string>
+ </panel>
+ <panel label="Rollen" name="roles_sub_tab">
+ <button label="Suchen" name="search_button"/>
+ <button label="Alle anzeigen" name="show_all_button"/>
+ <scroll_list name="role_list">
+ <column label="Rolle" name="name"/>
+ <column label="Titel" name="title"/>
+ <column label="Mitglieder" name="members"/>
+ </scroll_list>
+ <button label="Neue Rolle erstellen..." name="role_create"/>
+ <button label="Rolle löschen" name="role_delete"/>
+ <string name="help_text">
+ Rollen haben einen Titel und umfassen bestimmte
+Fähigkeiten. Mitglieder können mehrere
+Rollen innehaben. Eine Gruppe kann bis zu 10 Rollen
+definieren, darunter „Jeder“ und „Eigentümer“.
+ </string>
+ <string name="cant_delete_role">
+ Die Rollen „Jeder“ und „Eigentümer“ können nicht gelöscht werden.
+ </string>
+ </panel>
+ <panel label="Fähigkeiten" name="actions_sub_tab">
+ <button label="Suchen" name="search_button"/>
+ <button label="Alle anzeigen" name="show_all_button"/>
+ <scroll_list name="action_list" tool_tip="Select an Ability to view more details.">
+ <column label="" name="icon"/>
+ <column label="" name="action"/>
+ </scroll_list>
+ <string name="help_text">
+ Fähigkeiten verleihen Mitgliedern in Rollen bestimmte
+Rechte in einer Gruppe. Es gibt viele verschiedene Fähigkeiten.
+ </string>
+ </panel>
+ </tab_container>
+ <panel name="members_footer">
+ <text name="static">
+ Rollen
+ </text>
+ <text name="static2">
+ Zulässige Fähigkeiten
+ </text>
+ <scroll_list name="member_assigned_roles">
+ <column label="" name="checkbox"/>
+ <column label="" name="role"/>
+ </scroll_list>
+ <scroll_list name="member_allowed_actions" tool_tip="Um detaillierte Informationen zu erlaubten Fähigkeiten anzuzeigen, siehe Reiter Fähigkeiten.">
+ <column label="" name="icon"/>
+ <column label="" name="action"/>
+ </scroll_list>
+ </panel>
+ <panel name="roles_footer">
+ <text name="static">
+ Name
+ </text>
+ <text name="static2">
+ Beschreibung
+ </text>
+ <line_editor name="role_name">
+ Angestellte
+ </line_editor>
+ <text name="static3">
+ Titel
+ </text>
+ <line_editor name="role_title">
+ (wartet)
+ </line_editor>
+ <text_editor name="role_description">
+ (wartet)
+ </text_editor>
+ <text name="static4">
+ Mitglieder in Rolle
+ </text>
+ <text name="static5" tool_tip="Eine Liste der Fähigkeiten der aktuell ausgewählten Rolle.">
+ Zulässige Fähigkeiten
+ </text>
+ <check_box label="Mitglieder sind sichtbar" name="role_visible_in_list" tool_tip="Festlegen, ob Mitglieder in dieser Rolle auf der Registerkarte „Allgemein“ für Personen außerhalb der Gruppe sichtbar sind."/>
+ <scroll_list name="role_allowed_actions" tool_tip="Um detaillierte Informationen zu erlaubten Fähigkeiten anzuzeigen, siehe Reiter Fähigkeiten.">
+ <column label="" name="icon"/>
+ <column label="" name="checkbox"/>
+ <column label="" name="action"/>
+ </scroll_list>
+ </panel>
+ <panel name="actions_footer">
+ <text name="static">
+ Beschreibung
+ </text>
+ <text_editor name="action_description">
+ Diese Fähigkeit heißt „Mitglieder aus dieser Gruppe werfen“. Eigentümer können nur von anderen Eigentümern hinausgeworfen werden.
+ </text_editor>
+ <text name="static2">
+ Rollen mit Fähigkeit
+ </text>
+ <text name="static3">
+ Mitglieder mit Fähigkeit
+ </text>
+ </panel>
+</panel>
+
+<!-- original file
+
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel label="Mitglieder und Rollen" name="roles_tab">
+ <string name="default_needs_apply_text">
+ Das Unterregister enthält nicht übernommene Änderungen.
+ </string>
+ <string name="want_apply_text">
+ Diese Änderungen übernehmen?
+ </string>
+ <button label="?" name="help_button"/>
+ <panel name="members_header">
+ <text name="static">
+ Mitglieder und Rollen
+ </text>
+ <text name="static2">
+ Gruppenmitgliedern werden Rollen mit Fähigkeiten zugewiesen. Diese Einstellungen können zur flexibleren Organisation angepasst werden.
</text>
</panel>
<panel name="roles_header">
@@ -155,3 +312,5 @@ Rechte in einer Gruppe. Es gibt viele verschiedene Fähigkeiten.
</text>
</panel>
</panel>
+
+-->
diff --git a/indra/newview/skins/default/xui/de/panel_login.xml b/indra/newview/skins/default/xui/de/panel_login.xml
index 6846b1536c..3f459050b1 100644
--- a/indra/newview/skins/default/xui/de/panel_login.xml
+++ b/indra/newview/skins/default/xui/de/panel_login.xml
@@ -13,15 +13,9 @@
Startposition:
</text>
<combo_box name="start_location_combo">
- <combo_item name="MyHome">
- Mein Heimatort
- </combo_item>
- <combo_item name="MyLastLocation">
- Mein letzter Standort
- </combo_item>
- <combo_item name="Typeregionname">
- &lt;Region eingeben&gt;
- </combo_item>
+ <combo_box.item name="MyHome" label="Mein Heimatort" />
+ <combo_box.item name="MyLastLocation" label="Mein letzter Standort" />
+ <combo_box.item name="Typeregionname" label="lt;Region eingeben&gt;" />
</combo_box>
<check_box label="Kennwort merken" name="remember_check"/>
<text name="full_screen_text">
diff --git a/indra/newview/skins/default/xui/de/panel_preferences_chat.xml b/indra/newview/skins/default/xui/de/panel_preferences_chat.xml
index feeb528721..9de8922954 100644
--- a/indra/newview/skins/default/xui/de/panel_preferences_chat.xml
+++ b/indra/newview/skins/default/xui/de/panel_preferences_chat.xml
@@ -4,15 +4,9 @@
Chat-Schriftgröße:
</text>
<radio_group name="chat_font_size">
- <radio_item length="1" name="radio" type="string">
- Klein
- </radio_item>
- <radio_item length="1" name="radio2" type="string">
- Mittel
- </radio_item>
- <radio_item length="1" name="radio3" type="string">
- Groß
- </radio_item>
+ <radio_item length="1" name="radio" type="string" label="Klein" />
+ <radio_item length="1" name="radio2" type="string" label="Mittel" />
+ <radio_item length="1" name="radio3" type="string" label="Groß" />
</radio_group>
<text length="1" name="text_box2" type="string">
Chat-Farbe:
diff --git a/indra/newview/skins/default/xui/de/panel_preferences_graphics1.xml b/indra/newview/skins/default/xui/de/panel_preferences_graphics1.xml
index bc40ec0da1..dd77d57f87 100644
--- a/indra/newview/skins/default/xui/de/panel_preferences_graphics1.xml
+++ b/indra/newview/skins/default/xui/de/panel_preferences_graphics1.xml
@@ -21,21 +21,11 @@
Fenstergröße:
</text>
<combo_box left="115" name="windowsize combo">
- <combo_item name="640x480">
- 640x480
- </combo_item>
- <combo_item name="800x600">
- 800x600
- </combo_item>
- <combo_item name="720x480">
- 720x480 (NTSC)
- </combo_item>
- <combo_item name="768x576">
- 768x576 (PAL)
- </combo_item>
- <combo_item name="1024x768">
- 1024x768
- </combo_item>
+ <combo_box.item name="640x480" label="640x480" />
+ <combo_box.item name="800x600" label="800x600" />
+ <combo_box.item name="720x480" label="720x480 (NTSC)" />
+ <combo_box.item name="768x576" label="768x576 (PAL)" />
+ <combo_box.item name="1024x768" label="1024x768" />
</combo_box>
<text name="DisplayResLabel" width="100">
Anzeigeauflösung:
@@ -45,18 +35,10 @@
Aspektverhältnis:
</text>
<combo_box left="115" name="aspect_ratio" tool_tip="Breite/Höhe">
- <combo_item type="string" length="1" name="4:3(StandardCRT)">
- 4:3 (Standard-CRT)
- </combo_item>
- <combo_item type="string" length="1" name="5:4(1280x1024LCD)">
- 5:4 (1280x1024 LCD)
- </combo_item>
- <combo_item name="8:5(Widescreen)">
- 8:5 (Widescreen)
- </combo_item>
- <combo_item type="string" length="1" name="16:9(Widescreen)">
- 16:9 (Widescreen)
- </combo_item>
+ <combo_box.item type="string" length="1" name="4:3(StandardCRT)" label="4:3 (Standard-CRT)" />
+ <combo_box.item type="string" length="1" name="5:4(1280x1024LCD)" label="5:4 (1280x1024 LCD)" />
+ <combo_box.item name="8:5(Widescreen)" label="8:5 (Widescreen)" />
+ <combo_box.item type="string" length="1" name="16:9(Widescreen)" label="16:9 (Widescreen)" />
</combo_box>
<check_box label="Verhältnis automatisch erkennen" left="275" name="aspect_auto_detect" />
<text type="string" length="1" name="UI Size:">
@@ -111,18 +93,10 @@
Spiegelung:
</text>
<radio_group name="ReflectionDetailRadio">
- <radio_item name="0">
- Terrain und Bäume
- </radio_item>
- <radio_item name="1">
- Alle statischen Objekte
- </radio_item>
- <radio_item name="2">
- Alle Avatare und Objekte
- </radio_item>
- <radio_item name="3">
- Alles
- </radio_item>
+ <radio_item name="0" label="Terrain und Bäume" />
+ <radio_item name="1" label="Alle statischen Objekte" />
+ <radio_item name="2" label="Alle Avatare und Objekte" />
+ <radio_item name="3" label="Alles" />
</radio_group>
<text name="AvatarRenderingText">
Avatar-Darstellung:
@@ -173,23 +147,15 @@
Beleuchtungsdetails:
</text>
<radio_group name="LightingDetailRadio">
- <radio_item name="SunMoon">
- Nur Sonne und Mond
- </radio_item>
- <radio_item name="LocalLights">
- Lokale Lichtquellen
- </radio_item>
+ <radio_item name="SunMoon" label="Nur Sonne und Mond" />
+ <radio_item name="LocalLights" label="Lokale Lichtquellen" />
</radio_group>
<text name="TerrainDetailText">
Terraindetails:
</text>
<radio_group name="TerrainDetailRadio">
- <radio_item name="0">
- Niedrig
- </radio_item>
- <radio_item name="2">
- Hoch
- </radio_item>
+ <radio_item name="0" label="Niedrig" />
+ <radio_item name="2" label="Hoch" />
</radio_group>
<button label="Empfohlene Einstellungen" name="Defaults" />
<button label="Hardware-Optionen" label_selected="Hardware-Optionen"
diff --git a/indra/newview/skins/default/xui/de/panel_status_bar.xml b/indra/newview/skins/default/xui/de/panel_status_bar.xml
index adfe38797d..bfc77876d6 100644
--- a/indra/newview/skins/default/xui/de/panel_status_bar.xml
+++ b/indra/newview/skins/default/xui/de/panel_status_bar.xml
@@ -37,6 +37,6 @@
<text name="bandwidth_tooltip">
Bandbreite
</text>
- <line_editor label="Suchen" name="search_editor" tool_tip="Second Life durchsuchen"/>
- <button name="search_btn" tool_tip="Second Life durchsuchen"/>
+ <line_editor label="Suchen" name="search_editor" tool_tip="[SECOND_LIFE] durchsuchen"/>
+ <button name="search_btn" tool_tip="[SECOND_LIFE] durchsuchen"/>
</panel>
diff --git a/indra/newview/skins/default/xui/en/accordion_drag.xml b/indra/newview/skins/default/xui/en/accordion_drag.xml
new file mode 100644
index 0000000000..94839a7593
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/accordion_drag.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel border_thickness="2" visible ="true" name="splitter_drag"
+ width="100"
+ height="5"
+ left="50"
+ top="50"
+ follows="left|bottom|right" background_visible="true" label="splitter_drag" title="">
+</panel>
diff --git a/indra/newview/skins/default/xui/en/accordion_parent.xml b/indra/newview/skins/default/xui/en/accordion_parent.xml
new file mode 100644
index 0000000000..914a6eddb9
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/accordion_parent.xml
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+ <panel border_thickness="2" name="splitter_parent"
+ background_visible="true"
+ label="splitter_parent"
+ title=""
+ >
+ </panel>
diff --git a/indra/newview/skins/default/xui/en/favorites_bar_button.xml b/indra/newview/skins/default/xui/en/favorites_bar_button.xml
new file mode 100644
index 0000000000..e2f81168fa
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/favorites_bar_button.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<!-- *NOTE: mantipov: top & height should be synchronized with <favorites_bar> in the panel_navigation_bar.xml-->
+<!-- All buttons in the Favorites bar will be created from this one -->
+<button
+ follows="left|bottom"
+ halign="center"
+ height="23"
+ image_disabled="transparent.j2c"
+ image_disabled_selected="PushButton_Selected"
+ image_selected="PushButton_Selected"
+ image_unselected="PushButton_Off"
+ hover_glow_amount="0.15"
+ layout="topleft"
+ left="2"
+ name="favorites_bar_btn"
+ tab_stop="false"
+ top="2"
+ use_ellipses="true"
+ width="120" />
diff --git a/indra/newview/skins/default/xui/en/floater_aaa.xml b/indra/newview/skins/default/xui/en/floater_aaa.xml
new file mode 100644
index 0000000000..bf8988ca45
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/floater_aaa.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<floater
+ height="440"
+ layout="topleft"
+ name="floater_aaa"
+ save_rect="true"
+ can_resize="true"
+ title="About [APP_NAME]"
+ width="470">
+ <text_editor
+ follows="left|top|right|bottom"
+ height="400"
+ layout="topleft"
+ left="6"
+ max_length="65536"
+ name="credits_editor"
+ top="25"
+ width="458"
+ word_wrap="true">
+This is line 4
+ </text_editor>
+</floater>
diff --git a/indra/newview/skins/default/xui/en/floater_about.xml b/indra/newview/skins/default/xui/en/floater_about.xml
new file mode 100644
index 0000000000..73d789ce89
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/floater_about.xml
@@ -0,0 +1,121 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<floater
+ height="440"
+ layout="topleft"
+ name="floater_about"
+ save_rect="true"
+ title="About [APP_NAME]"
+ width="470">
+ <floater.string
+ name="you_are_at">
+ You are at [POSITION]
+ </floater.string>
+ <floater.string
+ name="in_region">
+ in [REGION] located at
+ </floater.string>
+ <floater.string
+ name="CPU">
+ CPU:
+ </floater.string>
+ <floater.string
+ name="Memory">
+ Memory: [MEM] MB
+ </floater.string>
+ <floater.string
+ name="OSVersion">
+ OS Version:
+ </floater.string>
+ <floater.string
+ name="GraphicsCardVendor">
+ Graphics Card Vendor:
+ </floater.string>
+ <floater.string
+ name="GraphicsCard">
+ Graphics Card:
+ </floater.string>
+ <floater.string
+ name="OpenGLVersion">
+ OpenGL Version:
+ </floater.string>
+ <floater.string
+ name="LibCurlVersion">
+ libcurl Version:
+ </floater.string>
+ <floater.string
+ name="J2CDecoderVersion">
+ J2C Decoder Version:
+ </floater.string>
+ <floater.string
+ name="AudioDriverVersion">
+ Audio Driver Version:
+ </floater.string>
+ <floater.string
+ name="none">
+ (none)
+ </floater.string>
+ <floater.string
+ name="LLMozLibVersion">
+ LLMozLib Version:
+ </floater.string>
+ <floater.string
+ name="LLQtWebkitVersion">
+ Qt Webkit Version: 4.5.2
+ </floater.string>
+ <floater.string
+ name="PacketsLost">
+ Packets Lost: [LOST]/[IN] ([PCT]%)
+ </floater.string>
+ <text_editor
+ type="string"
+ length="1"
+ follows="left|top|right|bottom"
+ height="168"
+ layout="topleft"
+ left="6"
+ max_length="65536"
+ name="credits_editor"
+ top="266"
+ width="458"
+ word_wrap="true">
+ Second Life is brought to you by Philip, Tessa, Andrew, Cory, James, Ben, Char, Charlie, Colin, Dan, Daniel, Doug, Eric, Hamlet, Haney, Eve, Hunter, Ian, Jeff, Jennifer, Jim, John, Lee, Mark, Peter, Phoenix, Richard, Robin, Xenon, Steve, Tanya, Eddie, Avi, Frank, Bruce, Aaron, Alice, Bob, Debra, Eileen, Helen, Janet, Louie, Leviathania, Stefan, Ray, Kevin, Tom, Mikeb, MikeT, Burgess, Elena, Tracy, Bill, Todd, Ryan, Zach, Sarah, Nova, Tim, Stephanie, Michael, Evan, Nicolas, Catherine, Rachelle, Dave, Holly, Bub, Kelly, Magellan, Ramzi, Don, Sabin, Jill, Rheya, Jeska, Torley, Kona, Callum, Charity, Ventrella, Jack, Vektor, Iris, Chris, Nicole, Mick, Reuben, Blue, Babbage, Yedwab, Deana, Lauren, Brent, Pathfinder, Chadrick, Altruima, Jesse, Teeny, Monroe, Icculus, David, Tess, Lizzie, Patsy, Isaac, Lawrence, Cyn, Bo, Gia, Annette, Marius, Tbone, Jonathan, Karen, Ginsu, Satoko, Yuko, Makiko, Thomas, Harry, Seth, Alexei, Brian, Guy, Runitai, Ethan, Data, Cornelius, Kenny, Swiss, Zero, Natria, Wendy, Stephen, Teeple, Thumper, Lucy, Dee, Mia, Liana, Warren, Branka, Aura, beez, Milo, Hermia, Red, Thrax, Joe, Sally, Magenta, Mogura, Paul, Jose, Rejean, Henrik, Lexie, Amber, Logan, Xan, Nora, Morpheus, Donovan, Leyla, MichaelFrancis, Beast, Cube, Bucky, Joshua, Stryfe, Harmony, Teresa, Claudia, Walker, Glenn, Fritz, Fordak, June, Cleopetra, Jean, Ivy, Betsy, Roosevelt, Spike, Ken, Which, Tofu, Chiyo, Rob, Zee, dustin, George, Del, Matthew, Cat, Jacqui, Lightfoot, Adrian, Viola, Alfred, Noel, Irfan, Sunil, Yool, Rika, Jane, Xtreme, Frontier, a2, Neo, Siobhan, Yoz, Justin, Elle, Qarl, Benjamin, Isabel, Gulliver, Everett, Christopher, Izzy, Stephany, Garry, Sejong, Sean, Tobin, Iridium, Meta, Anthony, Jeremy, JP, Jake, Maurice, Madhavi, Leopard, Kyle, Joon, Kari, Bert, Belinda, Jon, Kristi, Bridie, Pramod, KJ, Socrates, Maria, Ivan, Aric, Yamasaki, Adreanne, Jay, MitchK, Ceren, Coco, Durl, Jenny, Periapse, Kartic, Storrs, Lotte, Sandy, Rohn, Colossus, Zen, BigPapi, Brad, Pastrami, Kurz, Mani, Neuro, Jaime, MJ, Rowan, Sgt, Elvis, Gecko, Samuel, Sardonyx, Leo, Bryan, Niko, Soft, Poppy, Rachel, Aki, Angelo, Banzai, Alexa, Sue, CeeLo, Bender, CG, Gillian, Pelle, Nick, Echo, Zara, Christine, Shamiran, Emma, Blake, Keiko, Plexus, Joppa, Sidewinder, Erica, Ashlei, Twilight, Kristen, Brett, Q, Enus, Simon, Bevis, Kraft, Kip, Chandler, Ron, LauraP, Ram, KyleJM, Scouse, Prospero, Melissa, Marty, Nat, Hamilton, Kend, Lordan, Jimmy, Kosmo, Seraph, Green, Ekim, Wiggo, JT, Rome, Doris, Miz, Benoc, Whump, Trinity, Patch, Kate, TJ, Bao, Joohwan, Christy, Sofia, Matias, Cogsworth, Johan, Oreh, Cheah, Angela, Brandy, Mango, Lan, Aleks, Gloria, Heidy, Mitchell, Space, Colton, Bambers, Einstein, Maggie, Malbers, Rose, Winnie, Stella, Milton, Rothman, Niall, Marin, Allison, Katie, Dawn, Katt, Dusty, Kalpana, Judy, Andrea, Ambroff, Infinity, Gail, Rico, Raymond, Yi, William, Christa, M, Teagan, Scout, Molly, Dante, Corr, Dynamike, Usi, Kaylee, Vidtuts, Lil, Danica, Sascha, Kelv, Jacob, Nya, Rodney, Brandon, Elsie, Blondin, Grant, Katrin, Nyx, Gabriel, Locklainn, Claire, Devin, Minerva, Monty, Austin, Bradford, Si, Keira, H, Caitlin, Dita, Makai, Jenn, Ann, Meredith, Clare, Joy, Praveen, Cody, Edmund, Ruthe, Sirena, Gayathri, Spider, FJ, Davidoff, Tian, Jennie, Louise, Oskar, Landon, Noelle, Jarv, Ingrid, Al, Sommer, Doc, Aria, Huin, Gray, Lili, Vir, DJ, Yang, T, Simone, Maestro, Scott, Charlene, Quixote, Amanda, Susan, Zed, Anne, Enkidu, Esbee, Joroan, Katelin, Roxie, Tay, Scarlet, Kevin, Johnny, Wolfgang, Andren, Bob, Howard, Merov, Rand, Ray, Michon, Newell, Galen, Dessie, Les and many others.
+
+ Thank you to the following residents for helping to ensure that this is the best version yet: (in progress)
+
+ 3Dconnexion SDK Copyright (C) 1992-2007 3Dconnexion
+ APR Copyright (C) 2000-2004 The Apache Software Foundation
+ cURL Copyright (C) 1996-2002, Daniel Stenberg, (daniel@haxx.se)
+ DBus/dbus-glib Copyright (C) 2002, 2003 CodeFactory AB / Copyright (C) 2003, 2004 Red Hat, Inc.
+ expat Copyright (C) 1998, 1999, 2000 Thai Open Source Software Center Ltd.
+ FreeType Copyright (C) 1996-2002, The FreeType Project (www.freetype.org).
+ GL Copyright (C) 1999-2004 Brian Paul.
+ Havok.com(TM) Copyright (C) 1999-2001, Telekinesys Research Limited.
+ jpeg2000 Copyright (C) 2001, David Taubman, The University of New South Wales (UNSW)
+ jpeglib Copyright (C) 1991-1998, Thomas G. Lane.
+ ogg/vorbis Copyright (C) 2001, Xiphophorus
+ OpenSSL Copyright (C) 1998-2002 The OpenSSL Project.
+ SDL Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002 Sam Lantinga
+ SSLeay Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ xmlrpc-epi Copyright (C) 2000 Epinions, Inc.
+ zlib Copyright (C) 1995-2002 Jean-loup Gailly and Mark Adler.
+ google-perftools Copyright (c) 2005, Google Inc.
+
+ All rights reserved. See licenses.txt for details.
+
+ Voice chat Audio coding: Polycom(R) Siren14(TM) (ITU-T Rec. G.722.1 Annex C)
+
+
+ Oh, Parabuild, why hast thou forsaken me?
+ </text_editor>
+ <text_editor
+ follows="left|top|right|bottom"
+ font="SansSerif"
+ height="238"
+ layout="topleft"
+ left_delta="0"
+ max_length="65536"
+ name="support_editor"
+ top_delta="-244"
+ width="458"
+ word_wrap="true" />
+</floater>
diff --git a/indra/newview/skins/default/xui/en/floater_about_land.xml b/indra/newview/skins/default/xui/en/floater_about_land.xml
new file mode 100644
index 0000000000..63abb63bdf
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/floater_about_land.xml
@@ -0,0 +1,2196 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<floater
+ can_tear_off="false"
+ height="420"
+ layout="topleft"
+ name="floaterland"
+ save_rect="true"
+ title="About Land"
+ width="460">
+ <floater.string
+ name="Minutes">
+ [MINUTES] minutes
+ </floater.string>
+ <floater.string
+ name="Minute">
+ minute
+ </floater.string>
+ <floater.string
+ name="Seconds">
+ [SECONDS] seconds
+ </floater.string>
+ <floater.string
+ name="Remaining">
+ remaining
+ </floater.string>
+ <tab_container
+ follows="left|top|right|bottom"
+ height="400"
+ layout="topleft"
+ left="1"
+ name="landtab"
+ tab_position="top"
+ top="20"
+ width="459">
+ <panel
+ border="true"
+ follows="left|top|right|bottom"
+ height="380"
+ label="General"
+ layout="topleft"
+ left="1"
+ name="land_general_panel"
+ top="-31"
+ width="458">
+ <panel.string
+ name="new users only">
+ New users only
+ </panel.string>
+ <panel.string
+ name="anyone">
+ Anyone
+ </panel.string>
+ <panel.string
+ name="area_text">
+ Area
+ </panel.string>
+ <panel.string
+ name="area_size_text">
+ [AREA] m²
+ </panel.string>
+ <panel.string
+ name="auction_id_text">
+ Auction ID: [ID]
+ </panel.string>
+ <panel.string
+ name="need_tier_to_modify">
+ You must approve your purchase to modify this land.
+ </panel.string>
+ <panel.string
+ name="group_owned_text">
+ (Group Owned)
+ </panel.string>
+ <panel.string
+ name="profile_text">
+ Profile...
+ </panel.string>
+ <panel.string
+ name="info_text">
+ Info...
+ </panel.string>
+ <panel.string
+ name="public_text">
+ (public)
+ </panel.string>
+ <panel.string
+ name="none_text">
+ (none)
+ </panel.string>
+ <panel.string
+ name="sale_pending_text">
+ (Sale Pending)
+ </panel.string>
+ <panel.string
+ name="no_selection_text">
+ No parcel selected.
+Go to World menu &gt; About Land or select another parcel to show its details.
+ </panel.string>
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="16"
+ layout="topleft"
+ left="4"
+ name="Name:"
+ top="4"
+ width="92">
+ Name:
+ </text>
+ <line_editor
+ border_style="line"
+ border_thickness="1"
+ follows="left|top|right"
+ height="16"
+ layout="topleft"
+ left_pad="2"
+ max_length="63"
+ name="Name"
+ top_delta="0"
+ width="350" />
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="16"
+ layout="topleft"
+ left="4"
+ name="Description:"
+ top="24"
+ width="100">
+ Description:
+ </text>
+ <text_editor
+ bevel_style="in"
+ border_style="line"
+ border_thickness="1"
+ follows="left|top|right"
+ height="52"
+ layout="topleft"
+ left_delta="92"
+ name="Description"
+ top_delta="0"
+ width="350"
+ word_wrap="true" />
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="16"
+ layout="topleft"
+ left="4"
+ name="LandType"
+ top="84"
+ width="92">
+ Type:
+ </text>
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="16"
+ layout="topleft"
+ left_delta="92"
+ name="LandTypeText"
+ top_delta="0"
+ width="250">
+ Mainland / Homestead
+ </text>
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="16"
+ layout="topleft"
+ left="4"
+ name="ContentRating"
+ top="104"
+ width="92">
+ Rating:
+ </text>
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="16"
+ layout="topleft"
+ left_delta="92"
+ name="ContentRatingText"
+ top_delta="0"
+ width="250">
+ Adult
+ </text>
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="16"
+ layout="topleft"
+ left="4"
+ name="Owner:"
+ top="124"
+ width="92">
+ Owner:
+ </text>
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="16"
+ layout="topleft"
+ left_delta="92"
+ name="OwnerText"
+ top_delta="0"
+ width="250">
+ Leyla Linden
+ </text>
+ <button
+ follows="left|top"
+ font="SansSerifSmall"
+ height="16"
+ label="Profile..."
+ label_selected="Profile..."
+ layout="topleft"
+ left_pad="4"
+ name="Profile..."
+ top_delta="0"
+ width="90" />
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="16"
+ layout="topleft"
+ left="4"
+ name="Group:"
+ top="144"
+ width="92">
+ Group:
+ </text>
+ <text
+ enabled="false"
+ follows="left|top"
+ height="16"
+ layout="topleft"
+ left_delta="92"
+ name="GroupText"
+ top_delta="2"
+ width="250" />
+ <button
+ follows="left|top"
+ font="SansSerifSmall"
+ height="16"
+ label="Set..."
+ label_selected="Set..."
+ layout="topleft"
+ left_pad="4"
+ name="Set..."
+ top_delta="-2"
+ width="90" />
+ <check_box
+ enabled="false"
+ height="16"
+ label="Allow Deed to Group"
+ layout="topleft"
+ left="96"
+ name="check deed"
+ tool_tip="A group officer can deed this land to the group, so it will be supported by the group&apos;s land allocation."
+ top="164"
+ width="116" />
+ <button
+ enabled="false"
+ follows="left|top"
+ font="SansSerifSmall"
+ height="16"
+ label="Deed..."
+ label_selected="Deed..."
+ layout="topleft"
+ left_pad="138"
+ name="Deed..."
+ tool_tip="You may only deed land if you are an officer in the selected group."
+ top_delta="0"
+ width="90" />
+ <check_box
+ enabled="false"
+ height="16"
+ label="Owner Makes Contribution With Deed"
+ layout="topleft"
+ left="96"
+ name="check contrib"
+ tool_tip="When the land is deeded to the group, the former owner contributes enough land allocation to support it."
+ top="184"
+ width="199" />
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="16"
+ layout="topleft"
+ left="4"
+ name="For Sale:"
+ top="204"
+ width="92">
+ For Sale:
+ </text>
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="16"
+ layout="topleft"
+ left_delta="92"
+ name="Not for sale."
+ top_delta="0"
+ width="186">
+ Not for sale.
+ </text>
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="16"
+ layout="topleft"
+ left_delta="0"
+ name="For Sale: Price L$[PRICE]."
+ top_delta="0"
+ width="226">
+ Price: L$[PRICE] (L$[PRICE_PER_SQM]/m²).
+ </text>
+ <text
+ enabled="false"
+ follows="left|top"
+ height="16"
+ layout="topleft"
+ left_delta="0"
+ name="SalePending"
+ top_pad="4"
+ width="344" />
+ <button
+ follows="left|top"
+ height="20"
+ label="Sell Land..."
+ label_selected="Sell Land..."
+ layout="topleft"
+ left_delta="199"
+ name="Sell Land..."
+ top_delta="0"
+ width="145" />
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="16"
+ layout="topleft"
+ left_delta="-199"
+ name="For sale to"
+ top_delta="0"
+ width="186">
+ For sale to: [BUYER]
+ </text>
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="16"
+ layout="topleft"
+ left_delta="0"
+ name="Sell with landowners objects in parcel."
+ top_pad="4"
+ width="186">
+ Objects included in sale.
+ </text>
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="16"
+ layout="topleft"
+ left_delta="0"
+ name="Selling with no objects in parcel."
+ top_delta="0"
+ width="186">
+ Objects not included in sale.
+ </text>
+ <button
+ follows="left|top"
+ height="20"
+ label="Cancel Land Sale"
+ label_selected="Cancel Land Sale"
+ layout="topleft"
+ left="295"
+ name="Cancel Land Sale"
+ top="228"
+ width="145" />
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="16"
+ layout="topleft"
+ left="4"
+ name="Claimed:"
+ top="268"
+ width="92">
+ Claimed:
+ </text>
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="16"
+ layout="topleft"
+ left_delta="92"
+ name="DateClaimText"
+ top_delta="0"
+ width="186">
+ Tue Aug 15 13:47:25 2006
+ </text>
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="16"
+ layout="topleft"
+ left="4"
+ name="PriceLabel"
+ top="288"
+ width="92">
+ Area:
+ </text>
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="16"
+ layout="topleft"
+ left_delta="92"
+ name="PriceText"
+ top_delta="0"
+ width="186">
+ 4048 m²
+ </text>
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="16"
+ layout="topleft"
+ left="4"
+ name="Traffic:"
+ top="308"
+ width="92">
+ Traffic:
+ </text>
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="16"
+ layout="topleft"
+ left_delta="92"
+ name="DwellText"
+ top_delta="0"
+ width="186">
+ 0
+ </text>
+ <button
+ enabled="false"
+ follows="left|top"
+ height="20"
+ label="Buy Land..."
+ label_selected="Buy Land..."
+ layout="topleft"
+ left="155"
+ name="Buy Land..."
+ top="328"
+ width="100" />
+ <button
+ enabled="false"
+ follows="left|top"
+ height="20"
+ label="Buy For Group..."
+ label_selected="Buy For Group..."
+ layout="topleft"
+ left="260"
+ name="Buy For Group..."
+ top="352"
+ width="180" />
+ <button
+ enabled="false"
+ follows="left|top"
+ height="20"
+ label="Buy Pass..."
+ label_selected="Buy Pass..."
+ layout="topleft"
+ left_delta="-105"
+ name="Buy Pass..."
+ tool_tip="A pass gives you temporary access to this land."
+ top_delta="0"
+ width="100" />
+ <button
+ follows="left|top"
+ height="20"
+ label="Abandon Land..."
+ label_selected="Abandon Land..."
+ layout="topleft"
+ left="260"
+ name="Abandon Land..."
+ top="328"
+ width="180" />
+ <button
+ follows="left|top"
+ height="20"
+ label="Reclaim Land..."
+ label_selected="Reclaim Land..."
+ layout="topleft"
+ left_delta="0"
+ name="Reclaim Land..."
+ top_delta="-48"
+ width="180" />
+ <button
+ enabled="false"
+ follows="left|top"
+ height="20"
+ label="Linden Sale..."
+ label_selected="Linden Sale..."
+ layout="topleft"
+ left_delta="0"
+ name="Linden Sale..."
+ tool_tip="Land must be owned, set content, and not already for auction."
+ top_pad="4"
+ width="180" />
+ </panel>
+ <panel
+ border="true"
+ follows="left|top|right|bottom"
+ height="380"
+ label="Covenant"
+ layout="topleft"
+ left_delta="-1"
+ name="land_covenant_panel"
+ top_delta="-47"
+ width="458">
+ <panel.string
+ name="can_resell">
+ Purchased land in this region may be resold.
+ </panel.string>
+ <panel.string
+ name="can_not_resell">
+ Purchased land in this region may not be resold.
+ </panel.string>
+ <panel.string
+ name="can_change">
+ Purchased land in this region may be joined or subdivided.
+ </panel.string>
+ <panel.string
+ name="can_not_change">
+ Purchased land in this region may not be joined or subdivided.
+ </panel.string>
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ font="SansSerif"
+ height="20"
+ layout="topleft"
+ left="5"
+ mouse_opaque="false"
+ name="estate_section_lbl"
+ top="0"
+ width="100">
+ Estate:
+ </text>
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="20"
+ layout="topleft"
+ left="10"
+ mouse_opaque="false"
+ name="estate_name_lbl"
+ top="20"
+ width="100">
+ Name:
+ </text>
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="20"
+ layout="topleft"
+ left_pad="10"
+ mouse_opaque="false"
+ name="estate_name_text"
+ top_delta="0"
+ width="150">
+ mainland
+ </text>
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="20"
+ layout="topleft"
+ left="10"
+ mouse_opaque="false"
+ name="estate_owner_lbl"
+ top="40"
+ width="100">
+ Owner:
+ </text>
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="20"
+ layout="topleft"
+ left_pad="10"
+ mouse_opaque="false"
+ name="estate_owner_text"
+ top_delta="0"
+ width="150">
+ (none)
+ </text>
+ <text_editor
+ type="string"
+ length="1"
+ enabled="false"
+ follows="left|top|right|bottom"
+ handle_edit_keys_directly="true"
+ height="115"
+ layout="topleft"
+ left_delta="0"
+ max_length="65535"
+ name="covenant_editor"
+ top_delta="20"
+ width="330"
+ word_wrap="true">
+ There is no Covenant provided for this Estate.
+ </text_editor>
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="20"
+ layout="topleft"
+ left_delta="0"
+ mouse_opaque="false"
+ name="covenant_timestamp_text"
+ top_pad="55"
+ width="250">
+ Last Modified Wed Dec 31 16:00:00 1969
+ </text>
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ font="SansSerif"
+ height="20"
+ layout="topleft"
+ left="5"
+ mouse_opaque="false"
+ name="region_section_lbl"
+ top="250"
+ width="100">
+ Region:
+ </text>
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="20"
+ layout="topleft"
+ left="10"
+ mouse_opaque="false"
+ name="region_name_lbl"
+ top="270"
+ width="100">
+ Name:
+ </text>
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="20"
+ layout="topleft"
+ left_pad="10"
+ mouse_opaque="false"
+ name="region_name_text"
+ top_delta="0"
+ width="150">
+ leyla
+ </text>
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="20"
+ layout="topleft"
+ left="10"
+ mouse_opaque="false"
+ name="region_landtype_lbl"
+ top="290"
+ width="100">
+ Type:
+ </text>
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="20"
+ layout="topleft"
+ left_pad="10"
+ mouse_opaque="false"
+ name="region_landtype_text"
+ top_delta="0"
+ width="150">
+ Mainland / Homestead
+ </text>
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="20"
+ layout="topleft"
+ left="10"
+ mouse_opaque="false"
+ name="region_maturity_lbl"
+ top="310"
+ width="100">
+ Rating:
+ </text>
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="20"
+ layout="topleft"
+ left_pad="10"
+ mouse_opaque="false"
+ name="region_maturity_text"
+ top_delta="0"
+ width="150">
+ Adult
+ </text>
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="20"
+ layout="topleft"
+ left="10"
+ mouse_opaque="false"
+ name="resellable_lbl"
+ top="330"
+ width="100">
+ Resale:
+ </text>
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="20"
+ layout="topleft"
+ left_pad="10"
+ mouse_opaque="false"
+ name="resellable_clause"
+ top_delta="0"
+ width="330">
+ Land in this region may not be resold.
+ </text>
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="20"
+ layout="topleft"
+ left="10"
+ mouse_opaque="false"
+ name="changeable_lbl"
+ top="350"
+ width="100">
+ Subdivide:
+ </text>
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="30"
+ layout="topleft"
+ left_pad="10"
+ mouse_opaque="false"
+ name="changeable_clause"
+ top_delta="0"
+ width="330">
+ Land in this region may not be joined/subdivided.
+ </text>
+ </panel>
+ <panel
+ border="true"
+ follows="left|top|right|bottom"
+ height="380"
+ label="Objects"
+ layout="topleft"
+ left_delta="0"
+ name="land_objects_panel"
+ top_delta="-47"
+ width="458">
+ <panel.string
+ name="objects_available_text">
+ [COUNT] out of [MAX] ([AVAILABLE] available)
+ </panel.string>
+ <panel.string
+ name="objects_deleted_text">
+ [COUNT] out of [MAX] ([DELETED] will be deleted)
+ </panel.string>
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="16"
+ layout="topleft"
+ left="4"
+ name="parcel_object_bonus"
+ top="4"
+ visible="false"
+ width="364">
+ Region Object Bonus Factor: [BONUS]
+ </text>
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="16"
+ layout="topleft"
+ left_delta="0"
+ name="Simulator primitive usage:"
+ top_pad="4"
+ width="364">
+ Simulator primitive usage:
+ </text>
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="16"
+ layout="topleft"
+ left_delta="152"
+ name="objects_available"
+ top_delta="0"
+ width="212">
+ [COUNT] out of [MAX] ([AVAILABLE] available)
+ </text>
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="16"
+ layout="topleft"
+ left="4"
+ name="Primitives parcel supports:"
+ top="44"
+ width="152">
+ Primitives parcel supports:
+ </text>
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="16"
+ layout="topleft"
+ left_delta="152"
+ name="object_contrib_text"
+ top_delta="0"
+ width="212">
+ [COUNT]
+ </text>
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="16"
+ layout="topleft"
+ left="4"
+ name="Primitives on parcel:"
+ top="64"
+ width="152">
+ Primitives on parcel:
+ </text>
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="16"
+ layout="topleft"
+ left_delta="152"
+ name="total_objects_text"
+ top_delta="0"
+ width="48">
+ [COUNT]
+ </text>
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="16"
+ layout="topleft"
+ left="28"
+ name="Owned by parcel owner:"
+ top="84"
+ width="128">
+ Owned by parcel owner:
+ </text>
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="16"
+ layout="topleft"
+ left_delta="128"
+ name="owner_objects_text"
+ top_delta="0"
+ width="48">
+ [COUNT]
+ </text>
+ <button
+ bottom="100"
+ enabled="false"
+ follows="left|top"
+ font="SansSerifSmall"
+ height="16"
+ label="Show"
+ label_selected="Show"
+ layout="topleft"
+ name="ShowOwner"
+ right="-190"
+ width="60" />
+ <button
+ bottom="100"
+ enabled="false"
+ follows="left|top"
+ font="SansSerifSmall"
+ height="16"
+ label="Return..."
+ label_selected="Return..."
+ layout="topleft"
+ name="ReturnOwner..."
+ right="-60"
+ tool_tip="Return objects to their owners."
+ width="119" />
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="16"
+ layout="topleft"
+ left="28"
+ name="Set to group:"
+ top="104"
+ width="128">
+ Set to group:
+ </text>
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="16"
+ layout="topleft"
+ left_delta="128"
+ name="group_objects_text"
+ top_delta="0"
+ width="48">
+ [COUNT]
+ </text>
+ <button
+ bottom="120"
+ enabled="false"
+ follows="left|top"
+ font="SansSerifSmall"
+ height="16"
+ label="Show"
+ label_selected="Show"
+ layout="topleft"
+ name="ShowGroup"
+ right="-190"
+ width="60" />
+ <button
+ bottom="120"
+ enabled="false"
+ follows="left|top"
+ font="SansSerifSmall"
+ height="16"
+ label="Return..."
+ label_selected="Return..."
+ layout="topleft"
+ name="ReturnGroup..."
+ right="-60"
+ tool_tip="Return objects to their owners."
+ width="119" />
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="16"
+ layout="topleft"
+ left="28"
+ name="Owned by others:"
+ top="124"
+ width="128">
+ Owned by others:
+ </text>
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="16"
+ layout="topleft"
+ left_delta="128"
+ name="other_objects_text"
+ top_delta="0"
+ width="48">
+ [COUNT]
+ </text>
+ <button
+ bottom="140"
+ enabled="false"
+ follows="left|top"
+ font="SansSerifSmall"
+ height="16"
+ label="Show"
+ label_selected="Show"
+ layout="topleft"
+ name="ShowOther"
+ right="-190"
+ width="60" />
+ <button
+ bottom="140"
+ enabled="false"
+ follows="left|top"
+ font="SansSerifSmall"
+ height="16"
+ label="Return..."
+ label_selected="Return..."
+ layout="topleft"
+ name="ReturnOther..."
+ right="-60"
+ tool_tip="Return objects to their owners."
+ width="119" />
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="16"
+ layout="topleft"
+ left="28"
+ name="Selected / sat upon:"
+ top="144"
+ width="128">
+ Selected / sat upon:
+ </text>
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="16"
+ layout="topleft"
+ left_delta="128"
+ name="selected_objects_text"
+ top_delta="0"
+ width="48">
+ [COUNT]
+ </text>
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="16"
+ layout="topleft"
+ left="4"
+ name="Autoreturn"
+ top="164"
+ width="294">
+ Autoreturn other residents&apos; objects (minutes, 0 for off):
+ </text>
+ <line_editor
+ border_style="line"
+ border_thickness="1"
+ bottom="180"
+ follows="left|top"
+ height="16"
+ layout="topleft"
+ max_length="6"
+ name="clean other time"
+ right="-100"
+ width="56" />
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="16"
+ layout="topleft"
+ left="4"
+ name="Object Owners:"
+ top="184"
+ width="104">
+ Object Owners:
+ </text>
+ <button
+ follows="left|top"
+ font="SansSerifSmall"
+ height="16"
+ label="Refresh List"
+ label_selected="Refresh List"
+ layout="topleft"
+ left_delta="104"
+ name="Refresh List"
+ top_delta="0"
+ width="106" />
+ <button
+ enabled="false"
+ follows="left|top"
+ font="SansSerifSmall"
+ height="16"
+ label="Return objects..."
+ label_selected="Return objects..."
+ layout="topleft"
+ left_pad="6"
+ name="Return objects..."
+ top_delta="0"
+ width="164" />
+ <name_list
+ column_padding="0"
+ draw_heading="true"
+ follows="left|top|right|bottom"
+ height="165"
+ layout="topleft"
+ left="4"
+ name="owner list"
+ name_column="name"
+ top="210"
+ width="450">
+ <name_list.columns
+ label="Type"
+ name="type"
+ sort_column="online_status"
+ width="24" />
+ <name_list.columns
+ name="online_status"
+ width="-1" />
+ <name_list.columns
+ dynamic_width="true"
+ label="Name"
+ name="name" />
+ <name_list.columns
+ label="Count"
+ name="count"
+ width="70" />
+ <name_list.columns
+ label="Most Recent"
+ name="mostrecent"
+ width="160" />
+ </name_list>
+ </panel>
+ <panel
+ border="true"
+ follows="left|top|right|bottom"
+ height="333"
+ label="Options"
+ layout="topleft"
+ left_delta="0"
+ name="land_options_panel"
+ top_delta="31"
+ width="458">
+ <panel.string
+ name="search_enabled_tooltip">
+ Let people see this parcel in search results
+ </panel.string>
+ <panel.string
+ name="search_disabled_small_tooltip">
+ This option is disabled because this parcel&apos;s area is 128 m² or smaller.
+Only large parcels can be listed in search.
+ </panel.string>
+ <panel.string
+ name="search_disabled_permissions_tooltip">
+ This option is disabled because you cannot modify this parcel&apos;s options.
+ </panel.string>
+ <panel.string
+ name="mature_check_mature">
+ Mature Content
+ </panel.string>
+ <panel.string
+ name="mature_check_adult">
+ Adult Content
+ </panel.string>
+ <panel.string
+ name="mature_check_mature_tooltip">
+ Your parcel information or content is considered mature.
+ </panel.string>
+ <panel.string
+ name="mature_check_adult_tooltip">
+ Your parcel information or content is considered adult.
+ </panel.string>
+ <panel.string
+ name="landing_point_none">
+ (none)
+ </panel.string>
+ <panel.string
+ name="push_restrict_text">
+ No Pushing
+ </panel.string>
+ <panel.string
+ name="push_restrict_region_text">
+ No Pushing (Region Override)
+ </panel.string>
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="16"
+ layout="topleft"
+ left="4"
+ name="allow_label"
+ top="4"
+ width="278">
+ Allow other residents to:
+ </text>
+ <check_box
+ height="16"
+ label="Edit Terrain"
+ layout="topleft"
+ left="14"
+ name="edit land check"
+ tool_tip="If checked, anyone can terraform your land. It is best to leave this unchecked, as you can always edit your own land."
+ top="24"
+ width="268" />
+ <check_box
+ height="16"
+ label="Fly"
+ layout="topleft"
+ left_delta="0"
+ name="check fly"
+ tool_tip="If checked, Residents can fly on your land. If unchecked, they can only fly into and over your land."
+ top_pad="4"
+ width="268" />
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="16"
+ layout="topleft"
+ left="178"
+ name="allow_label2"
+ top="24"
+ width="104">
+ Create Objects:
+ </text>
+ <check_box
+ height="16"
+ label="All Residents"
+ layout="topleft"
+ left_delta="92"
+ name="edit objects check"
+ top_delta="0"
+ width="104" />
+ <check_box
+ height="16"
+ label="Group"
+ layout="topleft"
+ left_delta="100"
+ name="edit group objects check"
+ top_delta="0"
+ width="70" />
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="16"
+ layout="topleft"
+ left="178"
+ name="allow_label3"
+ top="44"
+ width="124">
+ Object Entry:
+ </text>
+ <check_box
+ height="16"
+ label="All Residents"
+ layout="topleft"
+ left_delta="92"
+ name="all object entry check"
+ top_delta="0"
+ width="120" />
+ <check_box
+ height="16"
+ label="Group"
+ layout="topleft"
+ left_delta="100"
+ name="group object entry check"
+ top_delta="0"
+ width="70" />
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="16"
+ layout="topleft"
+ left="178"
+ name="allow_label4"
+ top="64"
+ width="124">
+ Run Scripts:
+ </text>
+ <check_box
+ height="16"
+ label="All Residents"
+ layout="topleft"
+ left_delta="92"
+ name="check other scripts"
+ top_delta="0"
+ width="120" />
+ <check_box
+ height="16"
+ label="Group"
+ layout="topleft"
+ left_delta="100"
+ name="check group scripts"
+ top_delta="0"
+ width="70" />
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="16"
+ layout="topleft"
+ left="4"
+ name="land_options_label"
+ top="84"
+ width="278">
+ Land Options:
+ </text>
+ <check_box
+ height="16"
+ label="Safe (no damage)"
+ layout="topleft"
+ left="14"
+ name="check safe"
+ tool_tip="If checked, sets the land to Safe, disabling damage combat. If cleared, damage combat is enabled."
+ top="104"
+ width="268" />
+ <check_box
+ height="16"
+ label="No Pushing"
+ layout="topleft"
+ left_delta="164"
+ name="PushRestrictCheck"
+ tool_tip="Prevents scripts from pushing. Checking this option may be useful for preventing disruptive behavior on your land."
+ top_delta="0"
+ width="119" />
+ <check_box
+ height="16"
+ label="Show Place in Search (L$30/week) under"
+ layout="topleft"
+ left="14"
+ name="ShowDirectoryCheck"
+ tool_tip="Let people see this parcel in search results"
+ top="124"
+ width="268" />
+ <combo_box
+ enabled="false"
+ height="18"
+ layout="topleft"
+ left_delta="241"
+ name="land category with adult"
+ top_delta="-2"
+ visible="false"
+ width="130">
+ <combo_box.item
+ label="Any Category"
+ name="item0"
+ value="any" />
+ <combo_box.item
+ label="Linden Location"
+ name="item1"
+ value="linden" />
+ <combo_box.item
+ label="Adult"
+ name="item2"
+ value="adult" />
+ <combo_box.item
+ label="Arts &amp; Culture"
+ name="item3"
+ value="arts" />
+ <combo_box.item
+ label="Business"
+ name="item4"
+ value="store" />
+ <combo_box.item
+ label="Educational"
+ name="item5"
+ value="educational" />
+ <combo_box.item
+ label="Gaming"
+ name="item6"
+ value="game" />
+ <combo_box.item
+ label="Hangout"
+ name="item7"
+ value="gather" />
+ <combo_box.item
+ label="Newcomer Friendly"
+ name="item8"
+ value="newcomer" />
+ <combo_box.item
+ label="Parks &amp; Nature"
+ name="item9"
+ value="park" />
+ <combo_box.item
+ label="Residential"
+ name="item10"
+ value="home" />
+ <combo_box.item
+ label="Shopping"
+ name="item11"
+ value="shopping" />
+ <combo_box.item
+ label="Other"
+ name="item12"
+ value="other" />
+ </combo_box>
+ <combo_box
+ enabled="false"
+ height="18"
+ layout="topleft"
+ left_delta="0"
+ name="land category"
+ top_delta="0"
+ visible="false"
+ width="130">
+ <combo_box.item
+ label="Any Category"
+ name="item0"
+ value="any" />
+ <combo_box.item
+ label="Linden Location"
+ name="item1"
+ value="linden" />
+ <combo_box.item
+ label="Arts &amp; Culture"
+ name="item3"
+ value="arts" />
+ <combo_box.item
+ label="Business"
+ name="item4"
+ value="store" />
+ <combo_box.item
+ label="Educational"
+ name="item5"
+ value="educational" />
+ <combo_box.item
+ label="Gaming"
+ name="item6"
+ value="game" />
+ <combo_box.item
+ label="Hangout"
+ name="item7"
+ value="gather" />
+ <combo_box.item
+ label="Newcomer Friendly"
+ name="item8"
+ value="newcomer" />
+ <combo_box.item
+ label="Parks &amp; Nature"
+ name="item9"
+ value="park" />
+ <combo_box.item
+ label="Residential"
+ name="item10"
+ value="home" />
+ <combo_box.item
+ label="Shopping"
+ name="item11"
+ value="shopping" />
+ <combo_box.item
+ label="Other"
+ name="item12"
+ value="other" />
+ </combo_box>
+ <button
+ follows="left|top"
+ height="18"
+ label="?"
+ label_selected="?"
+ layout="topleft"
+ left_pad="15"
+ name="?"
+ top_delta="0"
+ width="18" />
+ <check_box
+ height="16"
+ label="Mature Content"
+ layout="topleft"
+ left="14"
+ name="MatureCheck"
+ tool_tip=" "
+ top="144"
+ width="107" />
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="16"
+ layout="topleft"
+ left="4"
+ name="Snapshot:"
+ top="164"
+ width="278">
+ Snapshot:
+ </text>
+ <texture_picker
+ follows="left|top"
+ height="135"
+ layout="topleft"
+ left_delta="72"
+ name="snapshot_ctrl"
+ tool_tip="Click to choose a picture"
+ top_delta="0"
+ width="180" />
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="16"
+ layout="topleft"
+ left="4"
+ name="landing_point"
+ top="287"
+ width="278">
+ Landing Point: [LANDING]
+ </text>
+ <button
+ follows="left|top"
+ font="SansSerifSmall"
+ height="16"
+ label="Set"
+ label_selected="Set"
+ layout="topleft"
+ left_delta="232"
+ name="Set"
+ tool_tip="Sets the landing point where visitors arrive. Sets to your avatar&apos;s location inside this parcel."
+ top_delta="0"
+ width="50" />
+ <button
+ follows="left|top"
+ font="SansSerifSmall"
+ height="16"
+ label="Clear"
+ label_selected="Clear"
+ layout="topleft"
+ left_pad="5"
+ name="Clear"
+ tool_tip="Clear the landing point."
+ top_delta="0"
+ width="50" />
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="16"
+ layout="topleft"
+ left="4"
+ name="Teleport Routing: "
+ top="307"
+ width="278">
+ Teleport Routing:
+ </text>
+ <combo_box
+ height="18"
+ layout="topleft"
+ left_delta="116"
+ name="landing type"
+ tool_tip="Teleport Routing -- select how to handle teleports onto your land."
+ top_delta="0"
+ width="120">
+ <combo_box.item
+ enabled="true"
+ label="Blocked"
+ name="Blocked"
+ value="Blocked" />
+ <combo_box.item
+ enabled="true"
+ label="Landing Point"
+ name="LandingPoint"
+ value="Landing Point" />
+ <combo_box.item
+ enabled="true"
+ label="Anywhere"
+ name="Anywhere"
+ value="Anywhere" />
+ </combo_box>
+ </panel>
+ <panel
+ border="true"
+ follows="left|top|right|bottom"
+ height="363"
+ label="Media"
+ layout="topleft"
+ left_delta="0"
+ name="land_media_panel"
+ top_delta="1"
+ width="458">
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="16"
+ layout="topleft"
+ left="10"
+ name="with media:"
+ top="9"
+ width="65">
+ Type:
+ </text>
+ <combo_box
+ height="18"
+ layout="topleft"
+ left_pad="5"
+ name="media type"
+ tool_tip="Specify if the URL is a movie, web page, or other media"
+ top_delta="-2"
+ width="120" />
+ <text
+ follows="left|top"
+ height="16"
+ layout="topleft"
+ left_pad="10"
+ name="mime_type"
+ top_delta="2"
+ width="200" />
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="16"
+ layout="topleft"
+ left="10"
+ name="at URL:"
+ top="29"
+ width="65">
+ Home URL:
+ </text>
+ <line_editor
+ bottom_delta="0"
+ follows="left|top"
+ height="16"
+ layout="topleft"
+ left="80"
+ max_length="255"
+ name="media_url"
+ right="-80"
+ select_on_focus="true"
+ text_readonly_color="0.576471 0.662745 0.835294 1" />
+ <button
+ follows="left|top"
+ font="SansSerifSmall"
+ height="16"
+ label="Set..."
+ label_selected="Set..."
+ layout="topleft"
+ left_pad="8"
+ name="set_media_url"
+ top_delta="0"
+ width="60" />
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="16"
+ layout="topleft"
+ left="10"
+ name="at URL:"
+ top="49"
+ width="65">
+ Current URL:
+ </text>
+ <text
+ follows="left|top"
+ height="16"
+ layout="topleft"
+ left_pad="5"
+ name="current_url"
+ top_delta="0"
+ width="300" />
+ <button
+ follows="left|top"
+ font="SansSerifSmall"
+ height="16"
+ label="Reset..."
+ label_selected="Reset..."
+ layout="topleft"
+ left_pad="6"
+ name="reset_media_url"
+ top_delta="0"
+ width="60" />
+ <check_box
+ height="16"
+ label="Hide URL"
+ layout="topleft"
+ left="100"
+ name="hide_media_url"
+ tool_tip="Checking this option will hide the media url to any non-authorized viewers of this parcel information. Note this is not available for HTML types."
+ top="89"
+ width="200" />
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="16"
+ layout="topleft"
+ left="10"
+ name="Description:"
+ top="49"
+ width="364">
+ Description:
+ </text>
+ <line_editor
+ border_style="line"
+ border_thickness="1"
+ bottom_delta="0"
+ follows="left|top"
+ height="16"
+ layout="topleft"
+ left="80"
+ max_length="255"
+ name="url_description"
+ right="-80"
+ select_on_focus="true"
+ tool_tip="Text displayed next to play/load button" />
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="16"
+ layout="topleft"
+ left="10"
+ name="Media texture:"
+ top="69"
+ width="364">
+ Replace
+Texture:
+ </text>
+ <texture_picker
+ allow_no_texture="true"
+ default_image_name="Default"
+ follows="left|top"
+ height="80"
+ layout="topleft"
+ left_delta="70"
+ name="media texture"
+ tool_tip="Click to choose a picture"
+ top_delta="0"
+ width="64" />
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="16"
+ layout="topleft"
+ left_delta="75"
+ name="replace_texture_help"
+ top="85"
+ width="270">
+ Objects using this texture will show the movie or
+ web page after you click the play arrow.
+
+ Select the thumbnail to choose a different texture.
+ </text>
+ <check_box
+ height="16"
+ label="Auto scale"
+ layout="topleft"
+ left_delta="70"
+ name="media_auto_scale"
+ tool_tip="Checking this option will scale the content for this parcel automatically. It may be slightly slower and lower quality visually but no other texture scaling or alignment will be required."
+ top_delta="0"
+ width="200" />
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="16"
+ layout="topleft"
+ left="85"
+ name="media_size"
+ tool_tip="Size to render Web media, leave 0 for default."
+ top="185"
+ width="85">
+ Size:
+ </text>
+ <spinner
+ decimal_digits="0"
+ enabled="false"
+ follows="left|top"
+ halign="right"
+ height="16"
+ increment="1"
+ initial_value="0"
+ layout="topleft"
+ left_delta="65"
+ max_val="1024"
+ name="media_size_width"
+ tool_tip="Size to render Web media, leave 0 for default."
+ top_delta="0"
+ width="64" />
+ <spinner
+ decimal_digits="0"
+ enabled="false"
+ follows="left|top"
+ halign="right"
+ height="16"
+ increment="1"
+ initial_value="0"
+ layout="topleft"
+ left_pad="16"
+ max_val="1024"
+ name="media_size_height"
+ tool_tip="Size to render Web media, leave 0 for default."
+ top_delta="0"
+ width="64" />
+ <text
+ type="string"
+ length="1"
+ bottom_delta="0"
+ follows="left|top"
+ height="16"
+ layout="topleft"
+ left_delta="70"
+ name="pixels"
+ right="-10">
+ pixels
+ </text>
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="16"
+ layout="topleft"
+ left="10"
+ name="Options:"
+ top="237"
+ width="292">
+ Options:
+ </text>
+ <check_box
+ height="16"
+ label="Loop"
+ layout="topleft"
+ left_delta="70"
+ name="media_loop"
+ tool_tip="Play media in a loop. When the media has finished playing, it will restart from the beginning."
+ top_delta="0"
+ width="200" />
+ </panel>
+ <panel
+ border="true"
+ follows="left|top|right|bottom"
+ height="363"
+ label="Audio"
+ layout="topleft"
+ left_delta="0"
+ name="land_audio_panel"
+ top_delta="1"
+ width="458">
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="16"
+ layout="topleft"
+ left="10"
+ name="MusicURL:"
+ top="225"
+ width="364">
+ Music URL:
+ </text>
+ <line_editor
+ border_style="line"
+ border_thickness="1"
+ bottom_delta="0"
+ follows="left|top"
+ height="16"
+ layout="topleft"
+ left="80"
+ max_length="255"
+ name="music_url"
+ right="-15"
+ select_on_focus="true" />
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="16"
+ layout="topleft"
+ left="10"
+ name="Sound:"
+ top="265"
+ width="364">
+ Sound:
+ </text>
+ <check_box
+ height="16"
+ label="Restrict gesture and object sounds to this parcel"
+ layout="topleft"
+ left_delta="70"
+ name="check sound local"
+ top_delta="0"
+ width="292" />
+ <button
+ follows="left|top"
+ height="18"
+ label="?"
+ label_selected="?"
+ layout="topleft"
+ left_delta="292"
+ name="?"
+ top_delta="-2"
+ width="18" />
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="16"
+ layout="topleft"
+ left="10"
+ mouse_opaque="false"
+ name="Voice settings:"
+ top="305"
+ width="364">
+ Voice:
+ </text>
+ <check_box
+ height="54"
+ label="Enable Voice"
+ layout="topleft"
+ left="80"
+ name="parcel_enable_voice_channel"
+ top="267"
+ width="463" />
+ <check_box
+ enabled="false"
+ height="54"
+ label="Enable Voice (established by the Estate)"
+ layout="topleft"
+ left_delta="0"
+ name="parcel_enable_voice_channel_is_estate_disabled"
+ top_delta="0"
+ width="463" />
+ <check_box
+ height="54"
+ label="Restrict Voice to this parcel"
+ layout="topleft"
+ left="100"
+ name="parcel_enable_voice_channel_parcel"
+ top="287"
+ width="443" />
+ </panel>
+ <panel
+ border="true"
+ follows="left|top|right|bottom"
+ height="333"
+ label="Access"
+ layout="topleft"
+ left_delta="0"
+ name="land_access_panel"
+ top_delta="31"
+ width="458">
+ <panel.string
+ name="estate_override">
+ One or more of these options is set at the estate level
+ </panel.string>
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ font="SansSerif"
+ height="20"
+ layout="topleft"
+ left="8"
+ name="Limit access to this parcel to:"
+ top="4"
+ width="278">
+ Access To This Parcel
+ </text>
+ <check_box
+ follows="top|left"
+ height="16"
+ label="Allow Public Access"
+ layout="topleft"
+ left_delta="0"
+ name="public_access"
+ top_pad="5"
+ width="278" />
+ <text
+ type="string"
+ length="1"
+ follows="top|left"
+ height="16"
+ layout="topleft"
+ left_delta="20"
+ name="Only Allow"
+ top="49"
+ width="278">
+ Block Access By:
+ </text>
+ <check_box
+ follows="top|left"
+ height="16"
+ label="Residents who have not given payment info to Linden Lab"
+ layout="topleft"
+ left_delta="0"
+ name="limit_payment"
+ tool_tip="Ban unidentified residents."
+ top_pad="4"
+ width="278" />
+ <check_box
+ follows="top|left"
+ height="16"
+ label="Residents who are not age verified adults"
+ layout="topleft"
+ left_delta="0"
+ name="limit_age_verified"
+ tool_tip="Ban residents who have not verified their age. See the [SUPPORT_SITE] for more information."
+ top_pad="4"
+ width="278" />
+ <check_box
+ height="16"
+ label="Allow Group Access: [GROUP]"
+ layout="topleft"
+ left="8"
+ name="GroupCheck"
+ tool_tip="Set group in the General tab."
+ top="109"
+ width="278" />
+ <check_box
+ enabled="false"
+ height="16"
+ label="Sell passes to:"
+ layout="topleft"
+ left_delta="0"
+ name="PassCheck"
+ tool_tip="Allows temporary access to this parcel"
+ top_pad="4"
+ width="120" />
+ <combo_box
+ height="16"
+ layout="topleft"
+ left_pad="22"
+ name="pass_combo"
+ top_delta="0"
+ width="100">
+ <combo_box.item
+ label="Anyone"
+ name="Anyone"
+ value="anyone" />
+ <combo_box.item
+ label="Group"
+ name="Group"
+ value="group" />
+ </combo_box>
+ <spinner
+ enabled="false"
+ follows="left|top"
+ height="16"
+ increment="1"
+ initial_value="10"
+ label="Price in L$:"
+ label_width="120"
+ layout="topleft"
+ left="28"
+ max_val="500"
+ min_val="1"
+ name="PriceSpin"
+ top="149"
+ width="180" />
+ <spinner
+ enabled="false"
+ follows="left|top"
+ height="16"
+ increment="0.25"
+ initial_value="1"
+ label="Hours of access:"
+ label_width="120"
+ layout="topleft"
+ left_delta="0"
+ max_val="24"
+ min_val="0.01"
+ name="HoursSpin"
+ top_pad="4"
+ width="180" />
+ <text
+ type="string"
+ length="1"
+ follows="left|right|top"
+ height="16"
+ label="Always Allow"
+ layout="topleft"
+ left="20"
+ name="AllowedText"
+ top="204"
+ width="195">
+ Allowed Residents
+ </text>
+ <name_list
+ column_padding="0"
+ follows="top|bottom"
+ heading_height="14"
+ height="80"
+ layout="topleft"
+ left_delta="0"
+ multi_select="true"
+ name="AccessList"
+ tool_tip="([LISTED] listed, [MAX] max)"
+ top_pad="4"
+ width="195" />
+ <button
+ follows="bottom"
+ font="SansSerifSmall"
+ height="16"
+ label="Add..."
+ label_selected="Add..."
+ layout="topleft"
+ left_delta="5"
+ name="add_allowed"
+ top="308"
+ width="80" />
+ <button
+ follows="bottom"
+ font="SansSerifSmall"
+ height="16"
+ label="Remove"
+ label_selected="Remove"
+ layout="topleft"
+ left_pad="20"
+ name="remove_allowed"
+ top_delta="0"
+ width="80" />
+ <text
+ type="string"
+ length="1"
+ follows="left|right|top"
+ height="16"
+ label="Ban"
+ layout="topleft"
+ left="240"
+ name="BanCheck"
+ top="204"
+ width="195">
+ Banned Residents
+ </text>
+ <name_list
+ column_padding="0"
+ follows="top|bottom"
+ heading_height="14"
+ height="80"
+ layout="topleft"
+ left_delta="0"
+ multi_select="true"
+ name="BannedList"
+ tool_tip="([LISTED] listed, [MAX] max)"
+ top_pad="4"
+ width="195" />
+ <button
+ follows="bottom"
+ font="SansSerifSmall"
+ height="16"
+ label="Add..."
+ label_selected="Add..."
+ layout="topleft"
+ left_delta="5"
+ name="add_banned"
+ top="308"
+ width="80" />
+ <button
+ enabled="false"
+ follows="bottom"
+ font="SansSerifSmall"
+ height="16"
+ label="Remove"
+ label_selected="Remove"
+ layout="topleft"
+ left_pad="20"
+ name="remove_banned"
+ top_delta="0"
+ width="80" />
+ </panel>
+ </tab_container>
+</floater>
diff --git a/indra/newview/skins/default/xui/en/floater_activeim.xml b/indra/newview/skins/default/xui/en/floater_activeim.xml
new file mode 100644
index 0000000000..38c6d44fdf
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/floater_activeim.xml
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<floater
+ name="floater_activeim"
+ title="ACTIVE IM"
+ top="26"
+ left="0"
+ height="22"
+ width="350"
+ follows="right|bottom"
+ background_visible="true"
+ can_close="true"
+ can_dock="true"
+ can_minimize="false"
+ visible="true"
+ bg_alpha_color="0 0 0 0">
+ <scroll_container
+ follows="top|bottom"
+ layout="topleft"
+ top="20"
+ left="1"
+ width="349"
+ height="2"
+ name="panel_list_container">
+ <scrolling_panel_list
+ follows="left|right"
+ layout="topleft"
+ name="chiclet_row_panel_list"
+ width="335"/>
+ </scroll_container>
+</floater> \ No newline at end of file
diff --git a/indra/newview/skins/default/xui/en/floater_animation_preview.xml b/indra/newview/skins/default/xui/en/floater_animation_preview.xml
new file mode 100644
index 0000000000..846dda802d
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/floater_animation_preview.xml
@@ -0,0 +1,512 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<floater
+ can_minimize="false"
+ height="556"
+ layout="topleft"
+ name="Animation Preview"
+ width="280">
+ <floater.string
+ name="failed_to_initialize">
+ Failed to initialize motion
+ </floater.string>
+ <floater.string
+ name="anim_too_long">
+ Animation file is [LENGTH] seconds in length.
+
+Maximum animation length is [MAX_LENGTH] seconds.
+ </floater.string>
+ <floater.string
+ name="failed_file_read">
+ Unable to read animation file.
+
+[STATUS]
+ </floater.string>
+ <floater.string
+ name="E_ST_OK">
+ Ok
+ </floater.string>
+ <floater.string
+ name="E_ST_EOF">
+ Premature end of file.
+ </floater.string>
+ <floater.string
+ name="E_ST_NO_CONSTRAINT">
+ Cannot read constraint definition.
+ </floater.string>
+ <floater.string
+ name="E_ST_NO_FILE">
+ Cannot open BVH file.
+ </floater.string>
+ <floater.string
+ name="E_ST_NO_HIER">
+ Invalid HIERARCHY header.
+ </floater.string>
+ <floater.string
+ name="E_ST_NO_JOINT">
+ Cannot find ROOT or JOINT.
+ </floater.string>
+ <floater.string
+ name="E_ST_NO_NAME">
+ Cannot get JOINT name.
+ </floater.string>
+ <floater.string
+ name="E_ST_NO_OFFSET">
+ Cannot find OFFSET.
+ </floater.string>
+ <floater.string
+ name="E_ST_NO_CHANNELS">
+ Cannot find CHANNELS.
+ </floater.string>
+ <floater.string
+ name="E_ST_NO_ROTATION">
+ Cannot get rotation order.
+ </floater.string>
+ <floater.string
+ name="E_ST_NO_AXIS">
+ Cannot get rotation axis.
+ </floater.string>
+ <floater.string
+ name="E_ST_NO_MOTION">
+ Cannot find MOTION.
+ </floater.string>
+ <floater.string
+ name="E_ST_NO_FRAMES">
+ Cannot get number of frames.
+ </floater.string>
+ <floater.string
+ name="E_ST_NO_FRAME_TIME">
+ Cannot get frame time.
+ </floater.string>
+ <floater.string
+ name="E_ST_NO_POS">
+ Cannot get position values.
+ </floater.string>
+ <floater.string
+ name="E_ST_NO_ROT">
+ Cannot get rotation values.
+ </floater.string>
+ <floater.string
+ name="E_ST_NO_XLT_FILE">
+ Cannot open translation file.
+ </floater.string>
+ <floater.string
+ name="E_ST_NO_XLT_HEADER">
+ Cannot read translation header.
+ </floater.string>
+ <floater.string
+ name="E_ST_NO_XLT_NAME">
+ Cannot read translation names.
+ </floater.string>
+ <floater.string
+ name="E_ST_NO_XLT_IGNORE">
+ Cannot read translation ignore value.
+ </floater.string>
+ <floater.string
+ name="E_ST_NO_XLT_RELATIVE">
+ Cannot read translation relative value.
+ </floater.string>
+ <floater.string
+ name="E_ST_NO_XLT_OUTNAME">
+ Cannot read translation outname value.
+ </floater.string>
+ <floater.string
+ name="E_ST_NO_XLT_MATRIX">
+ Cannot read translation matrix.
+ </floater.string>
+ <floater.string
+ name="E_ST_NO_XLT_MERGECHILD">
+ Cannot get mergechild name.
+ </floater.string>
+ <floater.string
+ name="E_ST_NO_XLT_MERGEPARENT">
+ Cannot get mergeparent name.
+ </floater.string>
+ <floater.string
+ name="E_ST_NO_XLT_PRIORITY">
+ Cannot get priority value.
+ </floater.string>
+ <floater.string
+ name="E_ST_NO_XLT_LOOP">
+ Cannot get loop value.
+ </floater.string>
+ <floater.string
+ name="E_ST_NO_XLT_EASEIN">
+ Cannot get easeIn values.
+ </floater.string>
+ <floater.string
+ name="E_ST_NO_XLT_EASEOUT">
+ Cannot get easeOut values.
+ </floater.string>
+ <floater.string
+ name="E_ST_NO_XLT_HAND">
+ Cannot get hand morph value.
+ </floater.string>
+ <floater.string
+ name="E_ST_NO_XLT_EMOTE">
+ Cannot read emote name.
+ </floater.string>
+ <text
+ type="string"
+ length="1"
+ bottom="42"
+ follows="top|left"
+ height="15"
+ layout="topleft"
+ left="10"
+ name="name_label">
+ Name:
+ </text>
+ <line_editor
+ bottom_delta="2"
+ follows="top|left|right"
+ height="19"
+ layout="topleft"
+ left="85"
+ name="name_form"
+ right="-10" />
+ <text
+ type="string"
+ length="1"
+ bottom_delta="22"
+ follows="top|left"
+ height="15"
+ layout="topleft"
+ left="10"
+ name="description_label">
+ Description:
+ </text>
+ <line_editor
+ bottom_delta="2"
+ follows="top|left|right"
+ height="19"
+ layout="topleft"
+ left="85"
+ name="description_form"
+ right="-10" />
+ <spinner
+ decimal_digits="0"
+ follows="left|top"
+ height="18"
+ increment="1"
+ initial_value="0"
+ label="Priority"
+ label_width="50"
+ layout="topleft"
+ left="10"
+ max_val="4"
+ name="priority"
+ tool_tip="Controls which other animations can be overridden by this animation."
+ width="90" />
+ <check_box
+ bottom_delta="23"
+ height="18"
+ label="Loop"
+ layout="topleft"
+ left="10"
+ name="loop_check"
+ tool_tip="Makes this animation loop." />
+ <spinner
+ follows="left|top"
+ height="18"
+ increment="1"
+ initial_value="0"
+ label="In(%)"
+ label_width="30"
+ layout="topleft"
+ left_delta="70"
+ max_val="100"
+ name="loop_in_point"
+ tool_tip="Sets point in animation that looping returns to."
+ top_delta="2"
+ width="90" />
+ <spinner
+ bottom_delta="0"
+ follows="left|top"
+ height="18"
+ increment="1"
+ initial_value="0"
+ label="Out(%)"
+ layout="topleft"
+ left="185"
+ max_val="100"
+ name="loop_out_point"
+ tool_tip="Sets point in animation that ends a loop." />
+ <text
+ type="string"
+ length="1"
+ bottom_delta="20"
+ follows="top|left"
+ height="15"
+ layout="topleft"
+ left="10"
+ name="hand_label">
+ Hand Pose
+ </text>
+ <combo_box
+ height="18"
+ layout="topleft"
+ left_delta="76"
+ name="hand_pose_combo"
+ tool_tip="Controls what hands do during animation."
+ top_delta="-1"
+ width="104">
+ <combo_box.item
+ label="Spread"
+ name="Spread"
+ value="" />
+ <combo_box.item
+ label="Relaxed"
+ name="Relaxed"
+ value="Hands_Relaxed" />
+ <combo_box.item
+ label="Point Both"
+ name="PointBoth"
+ value="Hands_Point" />
+ <combo_box.item
+ label="Fist"
+ name="Fist"
+ value="Hands_Fist" />
+ <combo_box.item
+ label="Relaxed Left"
+ name="RelaxedLeft"
+ value="Hands_Relaxed_L" />
+ <combo_box.item
+ label="Point Left"
+ name="PointLeft"
+ value="Hands_Point_L" />
+ <combo_box.item
+ label="Fist Left"
+ name="FistLeft"
+ value="Hands_Fist_L" />
+ <combo_box.item
+ label="Relaxed Right"
+ name="RelaxedRight"
+ value="Hands_Relaxed_R" />
+ <combo_box.item
+ label="Point Right"
+ name="PointRight"
+ value="Hands_Point_R" />
+ <combo_box.item
+ label="Fist Right"
+ name="FistRight"
+ value="Hands_Fist_R" />
+ <combo_box.item
+ label="Salute Right"
+ name="SaluteRight"
+ value="Hands_Salute_R" />
+ <combo_box.item
+ label="Typing"
+ name="Typing"
+ value="Hands_Typing" />
+ <combo_box.item
+ label="Peace Right"
+ name="PeaceRight"
+ value="Hands_Peace_R" />
+ </combo_box>
+ <text
+ type="string"
+ length="1"
+ bottom_delta="22"
+ follows="top|left"
+ height="15"
+ layout="topleft"
+ left="10"
+ name="emote_label">
+ Expression
+ </text>
+ <combo_box
+ height="18"
+ layout="topleft"
+ left_delta="76"
+ name="emote_combo"
+ tool_tip="Controls what face does during animation."
+ top_delta="-1"
+ width="104">
+ <combo_box.item
+ label="(None)"
+ name="[None]" />
+ <combo_box.item
+ label="Aaaaah"
+ name="Aaaaah" />
+ <combo_box.item
+ label="Afraid"
+ name="Afraid" />
+ <combo_box.item
+ label="Angry"
+ name="Angry" />
+ <combo_box.item
+ label="Big Smile"
+ name="BigSmile" />
+ <combo_box.item
+ label="Bored"
+ name="Bored" />
+ <combo_box.item
+ label="Cry"
+ name="Cry" />
+ <combo_box.item
+ label="Disdain"
+ name="Disdain" />
+ <combo_box.item
+ label="Embarrassed"
+ name="Embarrassed" />
+ <combo_box.item
+ label="Frown"
+ name="Frown" />
+ <combo_box.item
+ label="Kiss"
+ name="Kiss" />
+ <combo_box.item
+ label="Laugh"
+ name="Laugh" />
+ <combo_box.item
+ label="Plllppt"
+ name="Plllppt" />
+ <combo_box.item
+ label="Repulsed"
+ name="Repulsed" />
+ <combo_box.item
+ label="Sad"
+ name="Sad" />
+ <combo_box.item
+ label="Shrug"
+ name="Shrug" />
+ <combo_box.item
+ label="Smile"
+ name="Smile" />
+ <combo_box.item
+ label="Surprise"
+ name="Surprise" />
+ <combo_box.item
+ label="Wink"
+ name="Wink" />
+ <combo_box.item
+ label="Worry"
+ name="Worry" />
+ </combo_box>
+ <text
+ type="string"
+ length="1"
+ follows="top|left"
+ height="15"
+ layout="topleft"
+ left="10"
+ name="preview_label"
+ top="167"
+ width="70">
+ Preview while
+ </text>
+ <combo_box
+ height="18"
+ layout="topleft"
+ left_pad="6"
+ name="preview_base_anim"
+ tool_tip="Use this to test your animation behavior while your avatar performs common actions."
+ top_delta="-1"
+ width="104">
+ <combo_box.item
+ label="Standing"
+ name="Standing" />
+ <combo_box.item
+ label="Walking"
+ name="Walking" />
+ <combo_box.item
+ label="Sitting"
+ name="Sitting" />
+ <combo_box.item
+ label="Flying"
+ name="Flying" />
+ </combo_box>
+ <spinner
+ follows="left|top"
+ height="18"
+ increment="0.01"
+ initial_value="0"
+ label="Ease In (sec)"
+ label_width="75"
+ layout="topleft"
+ left="10"
+ max_val="10"
+ name="ease_in_time"
+ tool_tip="Amount of time (in seconds) over which animations blends in."
+ top="191"
+ width="125" />
+ <spinner
+ follows="left|top"
+ height="18"
+ increment="0.01"
+ initial_value="0"
+ label="Ease Out (sec)"
+ label_width="80"
+ layout="topleft"
+ left_pad="10"
+ max_val="10"
+ name="ease_out_time"
+ tool_tip="Amount of time (in seconds) over which animations blends out."
+ top_delta="0"
+ width="130" />
+ <button
+ follows="top|right"
+ height="28"
+ image_selected="button_anim_play_selected.tga"
+ image_unselected="button_anim_play.tga"
+ layout="topleft"
+ left="10"
+ name="play_btn"
+ picture_style="true"
+ tool_tip="Play/pause your animation."
+ top="223"
+ width="28" />
+ <button
+ follows="top|right"
+ height="28"
+ image_selected="button_anim_stop_selected.tga"
+ image_unselected="button_anim_stop.tga"
+ layout="topleft"
+ left_pad="4"
+ name="stop_btn"
+ picture_style="true"
+ tool_tip="Stop animation playback"
+ top_delta="0"
+ width="28" />
+ <slider
+ bottom_delta="0"
+ follows="top|right"
+ height="20"
+ increment="0.0001"
+ initial_value="0"
+ layout="topleft"
+ left="80"
+ name="playback_slider"
+ right="275"
+ show_text="false" />
+ <text
+ type="string"
+ length="1"
+ bottom="306"
+ follows="top|left"
+ layout="topleft"
+ left="10"
+ name="bad_animation_text">
+ Unable to read animation file.
+
+We recommend BVH files exported from Poser 4.
+ </text>
+ <button
+ bottom="546"
+ follows="bottom|right"
+ height="20"
+ label="Cancel"
+ layout="topleft"
+ name="cancel_btn"
+ right="265"
+ width="123" />
+ <button
+ follows="bottom|left"
+ height="20"
+ label="Upload (L$[AMOUNT])"
+ layout="topleft"
+ left_delta="-129"
+ name="ok_btn"
+ top_delta="0"
+ width="123" />
+</floater>
diff --git a/indra/newview/skins/default/xui/en/floater_auction.xml b/indra/newview/skins/default/xui/en/floater_auction.xml
new file mode 100644
index 0000000000..32d3f4fd7e
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/floater_auction.xml
@@ -0,0 +1,68 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<floater
+ can_resize="true"
+ height="368"
+ layout="topleft"
+ min_height="368"
+ min_width="420"
+ name="floater_auction"
+ title="Start Linden Land Sale"
+ width="420">
+ <floater.string
+ name="already for sale">
+ You cannot auction parcels which are already for sale.
+ </floater.string>
+ <icon
+ bottom="280"
+ follows="left|right|top|bottom"
+ layout="topleft"
+ left="4"
+ name="snapshot_icon"
+ right="-4"
+ top="24" />
+ <text
+ follows="left|right|bottom"
+ height="16"
+ layout="topleft"
+ left_delta="0"
+ name="parcel_text"
+ top_pad="12"
+ width="400" />
+ <check_box
+ control_name="AuctionShowFence"
+ follows="left|bottom"
+ height="16"
+ initial_value="true"
+ label="Include yellow selection fence"
+ layout="topleft"
+ left_delta="0"
+ name="fence_check"
+ top_pad="12"
+ width="199" />
+ <button
+ follows="left|bottom"
+ height="20"
+ label="Snapshot"
+ label_selected="Snapshot"
+ layout="topleft"
+ left_delta="0"
+ name="snapshot_btn"
+ top_pad="4"
+ width="96">
+ <button.commit_callback
+ function="ClickSnapshot" />
+ </button>
+ <button
+ follows="left|bottom"
+ height="20"
+ label="OK"
+ label_selected="OK"
+ layout="topleft"
+ left_pad="4"
+ name="ok_btn"
+ top_delta="0"
+ width="48">
+ <button.commit_callback
+ function="ClickOK" />
+ </button>
+</floater>
diff --git a/indra/newview/skins/default/xui/en/floater_avatar_picker.xml b/indra/newview/skins/default/xui/en/floater_avatar_picker.xml
new file mode 100644
index 0000000000..b0472eb7e2
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/floater_avatar_picker.xml
@@ -0,0 +1,208 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<floater
+ can_resize="true"
+ height="350"
+ layout="topleft"
+ min_height="200"
+ min_width="265"
+ name="avatarpicker"
+ title="Choose Resident"
+ width="265">
+ <floater.string
+ name="not_found">
+ &apos;[TEXT]&apos; not found
+ </floater.string>
+ <floater.string
+ name="no_one_near">
+ No-one near
+ </floater.string>
+ <floater.string
+ name="no_results">
+ No results
+ </floater.string>
+ <floater.string
+ name="searching">
+ Searching...
+ </floater.string>
+ <tab_container
+ follows="left|right|top|bottom"
+ height="300"
+ layout="topleft"
+ left="4"
+ name="ResidentChooserTabs"
+ tab_position="top"
+ tab_width="65"
+ top="20"
+ width="255">
+ <panel
+ border="true"
+ height="150"
+ label="Search"
+ layout="topleft"
+ left="6"
+ name="SearchPanel"
+ top="150"
+ width="134">
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="16"
+ layout="topleft"
+ left="10"
+ name="InstructSearchResidentName"
+ top="8"
+ width="220">
+ Type part of the resident&apos;s name:
+ </text>
+ <line_editor
+ border_style="line"
+ border_thickness="1"
+ follows="left|top|right"
+ height="16"
+ layout="topleft"
+ left_delta="0"
+ name="Edit"
+ top_pad="4"
+ width="50" />
+ <button
+ follows="top|right"
+ height="20"
+ label="Find"
+ label_selected="Find"
+ layout="topleft"
+ left_pad="5"
+ name="Find"
+ top_delta="-1"
+ width="62" />
+ <scroll_list
+ follows="left|top|right|bottom"
+ height="90"
+ layout="topleft"
+ left="10"
+ name="SearchResults"
+ top="52"
+ width="115" />
+ </panel>
+ <panel
+ border="true"
+ height="150"
+ label="Calling Cards"
+ layout="topleft"
+ left_delta="-1"
+ name="CallingCardsPanel"
+ top_delta="134"
+ width="135">
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="16"
+ layout="topleft"
+ left="10"
+ name="InstructSelectCallingCard"
+ top="8"
+ width="220">
+ Select a calling card:
+ </text>
+ <inventory_panel
+ allow_multi_select="false"
+ border="true"
+ follows="left|top|right|bottom"
+ height="110"
+ layout="topleft"
+ left_delta="0"
+ name="InventoryPanel"
+ top_pad="7"
+ width="115" />
+ </panel>
+ <panel
+ border="true"
+ height="240"
+ label="Near Me"
+ layout="topleft"
+ left="6"
+ name="NearMePanel"
+ top="60"
+ width="135">
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="16"
+ layout="topleft"
+ left="10"
+ name="InstructSelectResident"
+ top="8"
+ width="220">
+ Select nearby resident:
+ </text>
+ <button
+ follows="top|right"
+ height="20"
+ label="Refresh List"
+ label_selected="Refresh List"
+ layout="topleft"
+ left_delta="25"
+ name="Refresh"
+ top_delta="-1"
+ width="90" />
+ <slider
+ control_name="NearMeRange"
+ decimal_digits="0"
+ follows="left|top"
+ height="15"
+ increment="1"
+ initial_value="20"
+ label="Range"
+ layout="topleft"
+ left="10"
+ max_val="130"
+ min_val="5"
+ name="near_me_range"
+ top="32"
+ width="175" />
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="15"
+ layout="topleft"
+ left_delta="175"
+ name="meters"
+ top_delta="0"
+ width="40">
+ Meters
+ </text>
+ <scroll_list
+ follows="left|top|right|bottom"
+ height="175"
+ layout="topleft"
+ left="10"
+ name="NearMe"
+ sort_column="0"
+ top="57"
+ width="115" />
+ </panel>
+ </tab_container>
+ <button
+ follows="left|bottom"
+ height="20"
+ label="Select"
+ label_selected="Select"
+ layout="topleft"
+ left="10"
+ name="Select"
+ top="324"
+ width="95" />
+ <button
+ follows="right|bottom"
+ height="20"
+ label="Cancel"
+ label_selected="Cancel"
+ layout="topleft"
+ right="-10"
+ name="Cancel"
+ top_delta="0"
+ width="95" />
+</floater>
diff --git a/indra/newview/skins/default/xui/en/floater_avatar_textures.xml b/indra/newview/skins/default/xui/en/floater_avatar_textures.xml
new file mode 100644
index 0000000000..9e2c8a44d1
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/floater_avatar_textures.xml
@@ -0,0 +1,211 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<floater
+ height="950"
+ layout="topleft"
+ name="avatar_texture_debug"
+ title="Avatar Textures"
+ width="960">
+ <floater.string
+ name="InvalidAvatar">
+ INVALID AVATAR
+ </floater.string>
+ <text
+ type="string"
+ length="1"
+ height="16"
+ layout="topleft"
+ left="10"
+ name="label"
+ top="24"
+ width="80">
+ Baked Textures
+ </text>
+ <text
+ type="string"
+ length="1"
+ height="16"
+ layout="topleft"
+ left_pad="60"
+ name="composite_label"
+ top_delta="0"
+ width="120">
+ Composite Textures
+ </text>
+ <button
+ height="20"
+ label="Dump IDs to Console"
+ label_selected="Dump"
+ layout="topleft"
+ left_pad="530"
+ name="Dump"
+ top_delta="1"
+ width="150" />
+ <texture_picker
+ height="143"
+ label="Hair"
+ layout="topleft"
+ left="10"
+ name="hair-baked"
+ top="47"
+ width="128" />
+ <texture_picker
+ height="143"
+ label="Hair"
+ layout="topleft"
+ left_pad="7"
+ name="hair"
+ top_delta="0"
+ width="128" />
+ <texture_picker
+ height="143"
+ label="Head"
+ layout="topleft"
+ left="10"
+ name="head-baked"
+ top="197"
+ width="128" />
+ <texture_picker
+ height="143"
+ label="Makeup"
+ layout="topleft"
+ left_pad="7"
+ name="head bodypaint"
+ top_delta="0"
+ width="128" />
+ <texture_picker
+ height="143"
+ label="Eyes"
+ layout="topleft"
+ left="10"
+ name="eyes-baked"
+ top="347"
+ width="128" />
+ <texture_picker
+ height="143"
+ label="Eye"
+ layout="topleft"
+ left_pad="7"
+ name="iris"
+ top_delta="0"
+ width="128" />
+ <texture_picker
+ height="143"
+ label="Upper Body"
+ layout="topleft"
+ left="10"
+ name="upper-baked"
+ top="497"
+ width="128" />
+ <texture_picker
+ height="143"
+ label="Upper Body Tattoo"
+ layout="topleft"
+ left_pad="7"
+ name="upper bodypaint"
+ top_delta="0"
+ width="128" />
+ <texture_picker
+ height="143"
+ label="Undershirt"
+ layout="topleft"
+ left_pad="7"
+ name="undershirt"
+ top_delta="0"
+ width="128" />
+ <texture_picker
+ height="143"
+ label="Gloves"
+ layout="topleft"
+ left_pad="7"
+ name="gloves"
+ top_delta="0"
+ width="128" />
+ <texture_picker
+ height="143"
+ label="Shirt"
+ layout="topleft"
+ left_pad="7"
+ name="shirt"
+ top_delta="0"
+ width="128" />
+ <texture_picker
+ height="143"
+ label="Upper Jacket"
+ layout="topleft"
+ left_pad="7"
+ name="upper jacket"
+ top_delta="0"
+ width="128" />
+ <texture_picker
+ height="143"
+ label="Lower Body"
+ layout="topleft"
+ left="10"
+ name="lower-baked"
+ top="647"
+ width="128" />
+ <texture_picker
+ height="143"
+ label="Lower Body Tattoo"
+ layout="topleft"
+ left_pad="7"
+ name="lower bodypaint"
+ top_delta="0"
+ width="128" />
+ <texture_picker
+ height="143"
+ label="Underpants"
+ layout="topleft"
+ left_pad="7"
+ name="underpants"
+ top_delta="0"
+ width="128" />
+ <texture_picker
+ height="143"
+ label="Socks"
+ layout="topleft"
+ left_pad="7"
+ name="socks"
+ top_delta="0"
+ width="128" />
+ <texture_picker
+ height="143"
+ label="Shoes"
+ layout="topleft"
+ left_pad="7"
+ name="shoes"
+ top_delta="0"
+ width="128" />
+ <texture_picker
+ height="143"
+ label="Pants"
+ layout="topleft"
+ left_pad="7"
+ name="pants"
+ top_delta="0"
+ width="128" />
+ <texture_picker
+ height="143"
+ label="Jacket"
+ layout="topleft"
+ left_pad="7"
+ name="lower jacket"
+ top_delta="0"
+ width="128" />
+ <texture_picker
+ height="143"
+ label="Skirt"
+ layout="topleft"
+ left="10"
+ name="skirt-baked"
+ top="797"
+ width="128" />
+ <texture_picker
+ height="143"
+ label="Skirt"
+ layout="topleft"
+ left_pad="7"
+ name="skirt"
+ top_delta="0"
+ width="128" />
+</floater>
diff --git a/indra/newview/skins/default/xui/en/floater_beacons.xml b/indra/newview/skins/default/xui/en/floater_beacons.xml
new file mode 100644
index 0000000000..ea41289769
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/floater_beacons.xml
@@ -0,0 +1,108 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<floater
+ height="225"
+ layout="topleft"
+ name="beacons"
+ save_rect="true"
+ save_visibility="true"
+ single_instance="true"
+ title="Beacons"
+ width="250">
+ <panel
+ follows="left|top|right|bottom"
+ height="200"
+ layout="topleft"
+ left="10"
+ name="beacons_panel"
+ top="15"
+ width="230">
+ <check_box
+ bottom_delta="33"
+ control_name="scripttouchbeacon"
+ label="Scripted Objects with Touch Only"
+ layout="topleft"
+ name="touch_only" >
+ <check_box.commit_callback
+ function="Beacons.UICheck" />
+ </check_box>
+ <check_box
+ bottom_delta="20"
+ control_name="scriptsbeacon"
+ label="Scripted Objects"
+ layout="topleft"
+ name="scripted">
+ <check_box.commit_callback
+ function="Beacons.UICheck" />
+ </check_box>
+ <check_box
+ bottom_delta="20"
+ control_name="physicalbeacon"
+ label="Physical Objects"
+ layout="topleft"
+ name="physical" >
+ <check_box.commit_callback
+ function="Beacons.UICheck" />
+ </check_box>
+ <check_box
+ bottom_delta="20"
+ control_name="soundsbeacon"
+ label="Sound Sources"
+ layout="topleft"
+ name="sounds" >
+ <check_box.commit_callback
+ function="Beacons.UICheck" />
+ </check_box>
+ <check_box
+ bottom_delta="20"
+ control_name="particlesbeacon"
+ label="Particle Sources"
+ layout="topleft"
+ name="particles" >
+ <check_box.commit_callback
+ function="Beacons.UICheck" />
+ </check_box>
+ <check_box
+ bottom_delta="20"
+ control_name="renderhighlights"
+ label="Render Highlights"
+ layout="topleft"
+ name="highlights" >
+ <check_box.commit_callback
+ function="Beacons.UICheck" />
+ </check_box>
+ <check_box
+ bottom_delta="20"
+ control_name="renderbeacons"
+ label="Render Beacons"
+ layout="topleft"
+ name="beacons" >
+ <check_box.commit_callback
+ function="Beacons.UICheck" />
+ </check_box>
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="12"
+ layout="topleft"
+ left="5"
+ name="beacon_width_label"
+ top="171"
+ width="128">
+ Beacon Width:
+ </text>
+ <slider
+ control_name="DebugBeaconLineWidth"
+ decimal_digits="0"
+ height="16"
+ increment="1"
+ initial_value="1"
+ layout="topleft"
+ left="30"
+ max_val="16"
+ min_val="1"
+ name="beacon_width"
+ top="187"
+ width="185" />
+ </panel>
+</floater>
diff --git a/indra/newview/skins/default/xui/en/floater_build_options.xml b/indra/newview/skins/default/xui/en/floater_build_options.xml
new file mode 100644
index 0000000000..af5c006779
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/floater_build_options.xml
@@ -0,0 +1,71 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<floater
+ follows="right"
+ height="151"
+ layout="topleft"
+ name="build options floater"
+ save_rect="true"
+ title="Grid Options"
+ width="272">
+ <spinner
+ control_name="GridResolution"
+ follows="left|top"
+ height="16"
+ initial_value="1"
+ label="Grid Unit (meters)"
+ label_width="110"
+ layout="topleft"
+ left="14"
+ max_val="5"
+ min_val="0.01"
+ name="GridResolution"
+ top="37"
+ width="170" />
+ <spinner
+ control_name="GridDrawSize"
+ decimal_digits="1"
+ follows="left|top"
+ height="16"
+ increment="0.5"
+ initial_value="5"
+ label="Grid Extents (meters)"
+ label_width="110"
+ layout="topleft"
+ left_delta="0"
+ max_val="50"
+ min_val="1"
+ name="GridDrawSize"
+ top_pad="5"
+ width="170" />
+ <check_box
+ control_name="GridSubUnit"
+ height="16"
+ label="Enable Sub-Unit Snapping"
+ layout="topleft"
+ left_delta="0"
+ name="GridSubUnit"
+ top_pad="5"
+ width="200" />
+ <check_box
+ control_name="GridCrossSections"
+ height="16"
+ label="Show Cross Sections"
+ layout="topleft"
+ left_delta="0"
+ name="GridCrossSection"
+ top_pad="5"
+ width="200" />
+ <slider
+ control_name="GridOpacity"
+ follows="left"
+ height="16"
+ increment="0.05"
+ initial_value="0.7"
+ label="Grid Opacity"
+ layout="topleft"
+ left_delta="0"
+ name="GridOpacity"
+ show_text="false"
+ top_pad="5"
+ width="200" />
+</floater>
diff --git a/indra/newview/skins/default/xui/en/floater_bulk_perms.xml b/indra/newview/skins/default/xui/en/floater_bulk_perms.xml
new file mode 100644
index 0000000000..0414ab5fa6
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/floater_bulk_perms.xml
@@ -0,0 +1,334 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<floater
+ can_tear_off="false"
+ height="360"
+ layout="topleft"
+ name="floaterbulkperms"
+ title="Bulk change content permissions"
+ width="280">
+ <floater.string
+ name="nothing_to_modify_text">
+ Selection contains no editable contents.
+ </floater.string>
+ <floater.string
+ name="status_text">
+ Setting permissions on [NAME]
+ </floater.string>
+ <floater.string
+ name="start_text">
+ Starting permission change requests...
+ </floater.string>
+ <floater.string
+ name="done_text">
+ Finished permission change requests.
+ </floater.string>
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ font="SansSerif"
+ height="10"
+ layout="topleft"
+ left="10"
+ name="applyto"
+ top="30"
+ width="206">
+ Content Types
+ </text>
+ <icon
+ height="16"
+ image_name="inv_item_animation.tga"
+ layout="topleft"
+ left_delta="2"
+ mouse_opaque="true"
+ name="icon_animation"
+ top_pad="14"
+ width="16" />
+ <check_box
+ control_name="BulkChangeIncludeAnimations"
+ height="16"
+ label="Animation"
+ layout="topleft"
+ left_pad="2"
+ name="check_animation"
+ top_delta="0"
+ width="126" />
+ <icon
+ height="16"
+ image_name="inv_folder_bodypart.tga"
+ layout="topleft"
+ left="12"
+ mouse_opaque="true"
+ name="icon_bodypart"
+ top="74"
+ width="16" />
+ <check_box
+ control_name="BulkChangeIncludeBodyParts"
+ height="16"
+ label="Body Parts"
+ layout="topleft"
+ left_pad="2"
+ name="check_bodypart"
+ top_delta="0"
+ width="126" />
+ <icon
+ height="16"
+ image_name="inv_item_shirt.tga"
+ layout="topleft"
+ left="12"
+ mouse_opaque="true"
+ name="icon_clothing"
+ top="94"
+ width="16" />
+ <check_box
+ control_name="BulkChangeIncludeClothing"
+ height="16"
+ label="Clothing"
+ layout="topleft"
+ left_pad="2"
+ name="check_clothing"
+ top_delta="0"
+ width="126" />
+ <icon
+ height="16"
+ image_name="inv_item_gesture.tga"
+ layout="topleft"
+ left="12"
+ mouse_opaque="true"
+ name="icon_gesture"
+ top="114"
+ width="16" />
+ <check_box
+ control_name="BulkChangeIncludeGestures"
+ height="16"
+ label="Gestures"
+ layout="topleft"
+ left_pad="2"
+ name="check_gesture"
+ top_delta="0"
+ width="126" />
+ <icon
+ height="16"
+ image_name="inv_item_notecard.tga"
+ layout="topleft"
+ left="12"
+ mouse_opaque="true"
+ name="icon_notecard"
+ top="134"
+ width="16" />
+ <check_box
+ control_name="BulkChangeIncludeNotecards"
+ height="16"
+ label="Notecards"
+ layout="topleft"
+ left_pad="2"
+ name="check_notecard"
+ top_delta="0"
+ width="126" />
+ <icon
+ height="16"
+ image_name="inv_item_object.tga"
+ layout="topleft"
+ left="12"
+ mouse_opaque="true"
+ name="icon_object"
+ top="154"
+ width="16" />
+ <check_box
+ control_name="BulkChangeIncludeObjects"
+ height="16"
+ label="Objects"
+ layout="topleft"
+ left_pad="2"
+ name="check_object"
+ top_delta="0"
+ width="126" />
+ <icon
+ height="16"
+ image_name="inv_item_script.tga"
+ layout="topleft"
+ left="12"
+ mouse_opaque="true"
+ name="icon_script"
+ top="174"
+ width="16" />
+ <check_box
+ control_name="BulkChangeIncludeScripts"
+ height="16"
+ label="Scripts"
+ layout="topleft"
+ left_pad="2"
+ name="check_script"
+ top_delta="0"
+ width="126" />
+ <icon
+ height="16"
+ image_name="inv_item_sound.tga"
+ layout="topleft"
+ left="12"
+ mouse_opaque="true"
+ name="icon_sound"
+ top="194"
+ width="16" />
+ <check_box
+ control_name="BulkChangeIncludeSounds"
+ height="16"
+ label="Sounds"
+ layout="topleft"
+ left_pad="2"
+ name="check_sound"
+ top_delta="0"
+ width="126" />
+ <icon
+ height="16"
+ image_name="inv_item_texture.tga"
+ layout="topleft"
+ left="12"
+ mouse_opaque="true"
+ name="icon_texture"
+ top="214"
+ width="16" />
+ <check_box
+ control_name="BulkChangeIncludeTextures"
+ height="16"
+ label="Textures"
+ layout="topleft"
+ left_pad="2"
+ name="check_texture"
+ top_delta="0"
+ width="126" />
+ <button
+ follows="left|top"
+ height="20"
+ label="Check All"
+ label_selected="All"
+ layout="topleft"
+ left="8"
+ name="check_all"
+ top="257"
+ width="100">
+ <button.commit_callback
+ function="BulkPermission.CheckAll" />
+ </button>
+ <button
+ follows="left|top"
+ height="20"
+ label="Uncheck All"
+ label_selected="None"
+ layout="topleft"
+ left_delta="0"
+ name="check_none"
+ top_pad="4"
+ width="100" >
+ <button.commit_callback
+ function="BulkPermission.UncheckAll"/>
+ </button>
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ font="SansSerif"
+ height="10"
+ layout="topleft"
+ left="140"
+ name="newperms"
+ top="30"
+ width="206">
+ New Permissions
+ </text>
+ <check_box
+ control_name="BulkChangeShareWithGroup"
+ height="16"
+ label="Share with group"
+ layout="topleft"
+ left="140"
+ name="share_with_group"
+ top="54"
+ width="106" />
+ <check_box
+ control_name="BulkChangeEveryoneCopy"
+ height="16"
+ label="Allow anyone to copy"
+ layout="topleft"
+ left_delta="0"
+ name="everyone_copy"
+ top_pad="16"
+ width="130" />
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="10"
+ layout="topleft"
+ left_delta="0"
+ name="NextOwnerLabel"
+ top_pad="16"
+ width="88">
+ Next owner can:
+ </text>
+ <check_box
+ control_name="BulkChangeNextOwnerModify"
+ height="16"
+ label="Modify"
+ layout="topleft"
+ left_delta="0"
+ name="next_owner_modify"
+ top_pad="14"
+ width="78" />
+ <check_box
+ control_name="BulkChangeNextOwnerCopy"
+ height="16"
+ label="Copy"
+ layout="topleft"
+ left_delta="78"
+ name="next_owner_copy"
+ top_delta="0"
+ width="88">
+ <check_box.commit_callback
+ function="BulkPermission.CommitCopy"/>
+ </check_box>
+ <check_box
+ control_name="BulkChangeNextOwnerTransfer"
+ enabled_control="BulkChangeNextOwnerCopy"
+ height="16"
+ initial_value="true"
+ label="Resell/Give away"
+ layout="topleft"
+ left="145"
+ name="next_owner_transfer"
+ top_delta="20"
+ width="106" />
+ <scroll_list
+ enabled="false"
+ follows="left|top|right|bottom"
+ height="130"
+ layout="topleft"
+ left="120"
+ name="queue output"
+ top="185"
+ width="150" />
+ <button
+ follows="left|top"
+ height="20"
+ label="Apply"
+ layout="topleft"
+ left="65"
+ name="apply"
+ top_pad="10"
+ width="100">
+ <button.commit_callback
+ function="BulkPermission.Apply"/>
+ </button>
+ <button
+ follows="left|top"
+ height="20"
+ label="Close"
+ layout="topleft"
+ left_pad="5"
+ name="close"
+ top_delta="0"
+ width="100" >
+ <button.commit_callback
+ function="BulkPermission.Close"/>
+ </button>
+</floater>
diff --git a/indra/newview/skins/default/xui/en/floater_bumps.xml b/indra/newview/skins/default/xui/en/floater_bumps.xml
new file mode 100644
index 0000000000..4fb2fe24cc
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/floater_bumps.xml
@@ -0,0 +1,47 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<floater
+ height="180"
+ layout="topleft"
+ name="floater_bumps"
+ save_rect="true"
+ title="Bumps, Pushes &amp; Hits"
+ width="400">
+ <floater.string
+ name="none_detected">
+ None detected
+ </floater.string>
+ <floater.string
+ name="bump">
+ [TIME] [FIRST] [LAST] bumped you
+ </floater.string>
+ <floater.string
+ name="llpushobject">
+ [TIME] [FIRST] [LAST] pushed you with a script
+ </floater.string>
+ <floater.string
+ name="selected_object_collide">
+ [TIME] [FIRST] [LAST] hit you with an object
+ </floater.string>
+ <floater.string
+ name="scripted_object_collide">
+ [TIME] [FIRST] [LAST] hit you with a scripted object
+ </floater.string>
+ <floater.string
+ name="physical_object_collide">
+ [TIME] [FIRST] [LAST] hit you with a physical object
+ </floater.string>
+ <floater.string
+ name="timeStr">
+ [[hour,datetime,slt]:[min,datetime,slt]]
+ </floater.string>
+ <scroll_list
+ draw_border="false"
+ follows="left|top|right|bottom"
+ height="152"
+ layout="topleft"
+ left="6"
+ multi_select="true"
+ name="bump_list"
+ top="20"
+ width="388" />
+</floater>
diff --git a/indra/newview/skins/default/xui/en/floater_buy_contents.xml b/indra/newview/skins/default/xui/en/floater_buy_contents.xml
new file mode 100644
index 0000000000..0930043659
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/floater_buy_contents.xml
@@ -0,0 +1,94 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<floater
+ can_resize="true"
+ height="300"
+ layout="topleft"
+ min_height="150"
+ min_width="200"
+ name="floater_buy_contents"
+ save_rect="true"
+ title="Buy Contents"
+ width="280">
+ <floater.string
+ name="no_copy_text">
+ (no copy)
+ </floater.string>
+ <floater.string
+ name="no_modify_text">
+ (no modify)
+ </floater.string>
+ <floater.string
+ name="no_transfer_text">
+ (no transfer)
+ </floater.string>
+ <text
+ type="string"
+ length="1"
+ follows="left|top|right"
+ font="SansSerif"
+ height="16"
+ layout="topleft"
+ left="15"
+ name="contains_text"
+ top="24"
+ width="281">
+ [NAME] contains:
+ </text>
+ <scroll_list
+ follows="left|top|right|bottom"
+ height="148"
+ layout="topleft"
+ left_delta="0"
+ name="item_list"
+ top_pad="4"
+ width="250">
+ <scroll_list.columns
+ name="icon"
+ width="16" />
+ <scroll_list.columns
+ name="text"
+ relative_width="1" />
+ </scroll_list>
+ <text
+ type="string"
+ length="1"
+ follows="left|right|bottom"
+ font="SansSerif"
+ height="24"
+ layout="topleft"
+ left_delta="0"
+ name="buy_text"
+ top_pad="4"
+ width="281">
+ Buy for L$[AMOUNT] from [NAME]?
+ </text>
+ <check_box
+ follows="left|bottom"
+ height="20"
+ label="Wear clothing now"
+ layout="topleft"
+ left_delta="0"
+ name="wear_check"
+ top="224"
+ width="135" />
+ <button
+ follows="right|bottom"
+ height="20"
+ label="Buy"
+ label_selected="Buy"
+ layout="topleft"
+ left_delta="0"
+ name="buy_btn"
+ top_pad="10"
+ width="125" />
+ <button
+ follows="right|bottom"
+ height="20"
+ label="Cancel"
+ label_selected="Cancel"
+ layout="topleft"
+ left_pad="5"
+ name="cancel_btn"
+ top_delta="0"
+ width="125" />
+</floater>
diff --git a/indra/newview/skins/default/xui/en/floater_buy_currency.xml b/indra/newview/skins/default/xui/en/floater_buy_currency.xml
new file mode 100644
index 0000000000..e2bdc756a9
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/floater_buy_currency.xml
@@ -0,0 +1,295 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<floater
+ can_minimize="false"
+ height="270"
+ layout="topleft"
+ name="buy currency"
+ single_instance="true"
+ title="Buy Currency"
+ width="350">
+ <floater.string
+ name="buy_currency">
+ Buy L$ [LINDENS] for approx. US$ [USD]
+ </floater.string>
+ <text
+ type="string"
+ length="1"
+ bottom_delta="48"
+ follows="top|left"
+ font="SansSerifHuge"
+ height="24"
+ layout="topleft"
+ left="16"
+ name="info_buying"
+ right="-20">
+ Buying Currency:
+ </text>
+ <text
+ type="string"
+ length="1"
+ bottom_delta="0"
+ follows="top|left"
+ font="SansSerifHuge"
+ height="24"
+ layout="topleft"
+ left="16"
+ name="info_cannot_buy"
+ right="-20">
+ Cannot buy now:
+ </text>
+ <text
+ type="string"
+ length="1"
+ bottom_delta="0"
+ follows="top|left"
+ font="SansSerifHuge"
+ height="24"
+ layout="topleft"
+ left="16"
+ name="info_need_more"
+ right="-20">
+ You need more currency:
+ </text>
+ <icon
+ follows="top|left"
+ height="64"
+ image_name="badge_note.j2c"
+ layout="topleft"
+ left="0"
+ name="step_error"
+ top="48"
+ width="64" />
+ <text
+ type="string"
+ length="1"
+ bottom_delta="96"
+ follows="top|left"
+ height="140"
+ layout="topleft"
+ left="72"
+ name="error_message"
+ right="-20">
+ Something ain&apos;t right.
+ </text>
+ <button
+ follows="bottom|left"
+ height="20"
+ label="Go to website"
+ layout="topleft"
+ left_delta="0"
+ name="error_web"
+ top_delta="124"
+ width="120" />
+ <icon
+ follows="top|left"
+ height="64"
+ image_name="badge_note.j2c"
+ layout="topleft"
+ left="0"
+ name="step_1"
+ top="48"
+ width="64" />
+ <text
+ type="string"
+ length="1"
+ bottom_delta="-38"
+ follows="top|left"
+ height="16"
+ layout="topleft"
+ left="72"
+ name="contacting"
+ right="-20">
+ Contacting LindeX...
+ </text>
+ <text
+ type="string"
+ length="1"
+ bottom_delta="0"
+ follows="top|left"
+ height="16"
+ layout="topleft"
+ left="72"
+ name="buy_action_unknown"
+ right="-20">
+ Buy L$ on the LindeX currency exchange
+ </text>
+ <text
+ type="string"
+ length="1"
+ bottom_delta="0"
+ follows="top|left"
+ height="16"
+ layout="topleft"
+ left="72"
+ name="buy_action"
+ right="-20">
+ [NAME] L$ [PRICE]
+ </text>
+ <text
+ type="string"
+ length="1"
+ follows="top|left"
+ height="16"
+ layout="topleft"
+ left_delta="0"
+ name="currency_action"
+ top_pad="4"
+ width="40">
+ Buy L$
+ </text>
+ <line_editor
+ type="string"
+ length="1"
+ follows="top|right"
+ height="16"
+ layout="topleft"
+ left_pad="5"
+ name="currency_amt"
+ top_delta="0"
+ width="80">
+ 1234
+ </line_editor>
+ <text
+ type="string"
+ length="1"
+ follows="top|right"
+ height="16"
+ layout="topleft"
+ left_pad="5"
+ name="currency_est"
+ top_delta="0"
+ width="180">
+ for approx. US$ [USD,number,2]
+ </text>
+ <text
+ type="string"
+ length="1"
+ follows="top|right"
+ height="16"
+ layout="topleft"
+ left_delta="5"
+ name="getting_data"
+ top_delta="0"
+ width="180">
+ Getting data...
+ </text>
+ <text
+ type="string"
+ length="1"
+ follows="top|left"
+ height="16"
+ layout="topleft"
+ left="80"
+ name="balance_label"
+ top="110"
+ width="240">
+ You currently have
+ </text>
+ <text
+ type="string"
+ length="1"
+ follows="top|left"
+ halign="right"
+ height="16"
+ layout="topleft"
+ left_delta="0"
+ name="balance_amount"
+ top_delta="0"
+ width="240">
+ L$ [AMT]
+ </text>
+ <text
+ type="string"
+ length="1"
+ follows="top|left"
+ height="16"
+ layout="topleft"
+ left_delta="0"
+ name="buying_label"
+ top_pad="4"
+ width="240">
+ You are buying
+ </text>
+ <text
+ type="string"
+ length="1"
+ follows="top|left"
+ halign="right"
+ height="16"
+ layout="topleft"
+ left_delta="0"
+ name="buying_amount"
+ top_delta="0"
+ width="240">
+ L$ [AMT]
+ </text>
+ <text
+ type="string"
+ length="1"
+ follows="top|left"
+ height="16"
+ layout="topleft"
+ left_delta="0"
+ name="total_label"
+ top_pad="4"
+ width="240">
+ Your balance will be
+ </text>
+ <text
+ type="string"
+ length="1"
+ follows="top|left"
+ halign="right"
+ height="16"
+ layout="topleft"
+ left_delta="0"
+ name="total_amount"
+ top_delta="0"
+ width="240">
+ L$ [AMT]
+ </text>
+ <text
+ type="string"
+ length="1"
+ bottom_delta="48"
+ follows="top|left"
+ height="32"
+ layout="topleft"
+ left="72"
+ name="purchase_warning_repurchase"
+ right="-20">
+ Confirming this purchase only buys the currency.
+You&apos;ll need to try the operation again.
+ </text>
+ <text
+ type="string"
+ length="1"
+ bottom_delta="0"
+ follows="top|left"
+ height="32"
+ layout="topleft"
+ left="72"
+ name="purchase_warning_notenough"
+ right="-20">
+ You aren&apos;t buying enough currency
+Increase the amount to buy.
+ </text>
+ <button
+ follows="bottom|right"
+ height="20"
+ label="Cancel"
+ layout="topleft"
+ left="237"
+ name="cancel_btn"
+ top="234"
+ width="90" />
+ <button
+ follows="bottom|left"
+ height="20"
+ label="Purchase"
+ layout="topleft"
+ left_delta="-96"
+ name="buy_btn"
+ top_delta="0"
+ width="90" />
+</floater>
diff --git a/indra/newview/skins/default/xui/en/floater_buy_land.xml b/indra/newview/skins/default/xui/en/floater_buy_land.xml
new file mode 100644
index 0000000000..5e0e423128
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/floater_buy_land.xml
@@ -0,0 +1,707 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<floater
+ can_minimize="false"
+ height="484"
+ layout="topleft"
+ name="buy land"
+ single_instance="true"
+ title="Buy Land"
+ width="740">
+ <floater.string
+ name="can_resell">
+ May be resold.
+ </floater.string>
+ <floater.string
+ name="can_not_resell">
+ May not be resold.
+ </floater.string>
+ <floater.string
+ name="can_change">
+ May be joined or subdivided.
+ </floater.string>
+ <floater.string
+ name="can_not_change">
+ May not be joined or subdivided.
+ </floater.string>
+ <floater.string
+ name="cant_buy_for_group">
+ You do not have permission to buy land for your active group.
+ </floater.string>
+ <floater.string
+ name="no_land_selected">
+ No land selected.
+ </floater.string>
+ <floater.string
+ name="multiple_parcels_selected">
+ Multiple different parcels selected.
+Try selecting a smaller area.
+ </floater.string>
+ <floater.string
+ name="no_permission">
+ You do not have permission to buy land for your active group.
+ </floater.string>
+ <floater.string
+ name="parcel_not_for_sale">
+ The selected parcel is not for sale.
+ </floater.string>
+ <floater.string
+ name="group_already_owns">
+ The group already owns the parcel.
+ </floater.string>
+ <floater.string
+ name="you_already_own">
+ You already own the parcel.
+ </floater.string>
+ <floater.string
+ name="set_to_sell_to_other">
+ The selected parcel is set to sell to another party.
+ </floater.string>
+ <floater.string
+ name="no_public_land">
+ The selected area has no public land.
+ </floater.string>
+ <floater.string
+ name="not_owned_by_you">
+ Land owned by another user is selected.
+Try selecting a smaller area.
+ </floater.string>
+ <floater.string
+ name="processing">
+ Processing your purchase...
+
+(This may take a minute or two.)
+ </floater.string>
+ <floater.string
+ name="fetching_error">
+ There has been an error while fetching land buying information.
+ </floater.string>
+ <floater.string
+ name="buying_will">
+ Buying this land will:
+ </floater.string>
+ <floater.string
+ name="buying_for_group">
+ Buying land for group will:
+ </floater.string>
+ <floater.string
+ name="cannot_buy_now">
+ Cannot buy now:
+ </floater.string>
+ <floater.string
+ name="not_for_sale">
+ Not for sale:
+ </floater.string>
+ <floater.string
+ name="none_needed">
+ none needed
+ </floater.string>
+ <floater.string
+ name="must_upgrade">
+ Your account must be upgraded to own land.
+ </floater.string>
+ <floater.string
+ name="cant_own_land">
+ Your account can own land.
+ </floater.string>
+ <floater.string
+ name="land_holdings">
+ You hold [BUYER] m² of land.
+ </floater.string>
+ <floater.string
+ name="pay_to_for_land">
+ Pay L$ [AMOUNT] to [SELLER] for this land
+ </floater.string>
+ <floater.string
+ name="buy_for_US">
+ Buy L$ [AMOUNT] for approx. US$ [AMOUNT2],
+ </floater.string>
+ <floater.string
+ name="parcel_meters">
+ This parcel is [AMOUNT] m²
+ </floater.string>
+ <floater.string
+ name="premium_land">
+ This land is premium, and will charge as [AMOUNT] m².
+ </floater.string>
+ <floater.string
+ name="discounted_land">
+ This land is discounted, and will charge as [AMOUNT] m².
+ </floater.string>
+ <floater.string
+ name="meters_supports_object">
+ [AMOUNT] m²
+supports [AMOUNT2] objects
+ </floater.string>
+ <floater.string
+ name="sold_with_objects">
+ sold with objects
+ </floater.string>
+ <floater.string
+ name="sold_without_objects">
+ objects not included
+ </floater.string>
+ <floater.string
+ name="info_price_string">
+ L$ [PRICE]
+(L$ [PRICE_PER_SQM]/m²)
+[SOLD_WITH_OBJECTS]
+ </floater.string>
+ <floater.string
+ name="insufficient_land_credits">
+ The group [GROUP] will need sufficient contributed land use credits to cover this parcel before the purchase will complete.
+ </floater.string>
+ <floater.string
+ name="have_enough_lindens">
+ You have L$ [AMOUNT], which is enough to buy this land.
+ </floater.string>
+ <floater.string
+ name="not_enough_lindens">
+ You have only L$ [AMOUNT], and need L$ [AMOUNT2] more.
+ </floater.string>
+ <floater.string
+ name="balance_left">
+ After the purchase, you will have L$ [AMOUNT] left.
+ </floater.string>
+ <floater.string
+ name="balance_needed">
+ You need to buy at least L$ [AMOUNT] to afford this land.
+ </floater.string>
+ <floater.string
+ name="no_parcel_selected">
+ (no parcel selected)
+ </floater.string>
+ <floater.string
+ name="buy_currency">
+ Buy L$ [LINDENS] for approx. US$ [USD]
+ </floater.string>
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="14"
+ layout="topleft"
+ left="440"
+ name="region_name_label"
+ right="550"
+ top="21"
+ width="60"
+ word_wrap="true">
+ Region:
+ </text>
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="14"
+ layout="topleft"
+ left_delta="110"
+ name="region_name_text"
+ top_delta="0"
+ width="175">
+ (unknown)
+ </text>
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="14"
+ layout="topleft"
+ left="440"
+ name="region_type_label"
+ right="550"
+ width="60"
+ word_wrap="true">
+ Type:
+ </text>
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="14"
+ layout="topleft"
+ left_delta="110"
+ name="region_type_text"
+ top_delta="0"
+ width="175">
+ (unknown)
+ </text>
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="14"
+ layout="topleft"
+ left="440"
+ name="estate_name_label"
+ right="550"
+ width="60"
+ word_wrap="true">
+ Estate:
+ </text>
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="14"
+ layout="topleft"
+ left_delta="110"
+ name="estate_name_text"
+ top_delta="0"
+ width="175">
+ (unknown)
+ </text>
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="20"
+ layout="topleft"
+ left="440"
+ name="estate_owner_label"
+ right="550"
+ width="100"
+ word_wrap="true">
+ Estate Owner:
+ </text>
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="20"
+ layout="topleft"
+ left_delta="110"
+ name="estate_owner_text"
+ top_delta="0"
+ width="175">
+ (unknown)
+ </text>
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ font="SansSerif"
+ height="16"
+ layout="topleft"
+ left="440"
+ name="resellable_changeable_label"
+ right="725"
+ width="260"
+ word_wrap="true">
+ Purchased land in this region:
+ </text>
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="16"
+ layout="topleft"
+ left="470"
+ name="resellable_clause"
+ right="725"
+ width="260"
+ word_wrap="true">
+ May or may not be resold.
+ </text>
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="16"
+ layout="topleft"
+ left="470"
+ name="changeable_clause"
+ right="725"
+ width="260"
+ word_wrap="true">
+ May or may not be joined or subdivided.
+ </text>
+ <text
+ type="string"
+ length="1"
+ height="16"
+ layout="topleft"
+ left="440"
+ name="covenant_text"
+ right="725"
+ width="260">
+ You must agree to the Estate Covenant:
+ </text>
+ <text
+ follows="left|top"
+ height="12"
+ layout="topleft"
+ left="500"
+ name="covenant_timestamp_text"
+ right="725"
+ top="175"
+ width="275"
+ word_wrap="true" />
+ <text_editor
+ type="string"
+ length="1"
+ enabled="false"
+ follows="top|right"
+ handle_edit_keys_directly="false"
+ height="237"
+ layout="topleft"
+ left="444"
+ max_length="65535"
+ name="covenant_editor"
+ right="725"
+ top="192"
+ width="271"
+ word_wrap="true">
+ Loading...
+ </text_editor>
+ <check_box
+ height="20"
+ label="I Agree to the Covenant Defined Above."
+ layout="topleft"
+ left="440"
+ name="agree_covenant"
+ right="725"
+ width="275" />
+ <texture_picker
+ enabled="false"
+ follows="top|left"
+ height="135"
+ layout="topleft"
+ left="16"
+ name="info_image"
+ top="28"
+ width="180" />
+ <text
+ type="string"
+ length="1"
+ bottom_delta="-119"
+ follows="top|left"
+ height="16"
+ layout="topleft"
+ left="204"
+ name="info_parcel_label"
+ top="30"
+ width="48">
+ Parcel:
+ </text>
+ <text
+ type="string"
+ length="1"
+ follows="top|left"
+ font="SansSerif"
+ height="16"
+ layout="topleft"
+ left_delta="16"
+ name="info_parcel"
+ top_pad="1"
+ width="180">
+ Scotopteryx 138,204
+ </text>
+ <text
+ type="string"
+ length="1"
+ follows="top|left"
+ height="16"
+ layout="topleft"
+ left="204"
+ name="info_size_label"
+ top_pad="1"
+ width="48">
+ Size:
+ </text>
+ <text
+ type="string"
+ length="1"
+ follows="top|left"
+ font="SansSerif"
+ height="32"
+ layout="topleft"
+ left_delta="16"
+ name="info_size"
+ top_pad="1"
+ width="180">
+ 1024 m²
+ </text>
+ <text
+ type="string"
+ length="1"
+ follows="top|left"
+ height="16"
+ layout="topleft"
+ left="204"
+ name="info_price_label"
+ top_pad="1"
+ width="48">
+ Price:
+ </text>
+ <text
+ type="string"
+ length="1"
+ follows="top|left"
+ font="SansSerif"
+ height="16"
+ layout="topleft"
+ left_delta="16"
+ name="info_price"
+ top_pad="1"
+ width="180">
+ L$ 1500
+(L$ 1.1/m²)
+sold with objects
+ </text>
+ <text
+ type="string"
+ length="1"
+ follows="top|left"
+ font="SansSerifHuge"
+ height="24"
+ layout="topleft"
+ left="16"
+ name="info_action"
+ top="166"
+ width="350">
+ Buying this land will:
+ </text>
+ <locate
+ height="6"
+ layout="topleft" />
+ <icon
+ follows="top|left"
+ height="64"
+ image_name="badge_note.j2c"
+ layout="topleft"
+ left="0"
+ name="step_error"
+ width="64" />
+ <text
+ type="string"
+ length="1"
+ follows="top|left"
+ height="160"
+ layout="topleft"
+ left="72"
+ name="error_message"
+ right="435"
+ top="208"
+ width="215">
+ Something ain&apos;t right.
+ </text>
+ <button
+ follows="bottom|left"
+ height="20"
+ label="Go to website"
+ layout="topleft"
+ left_delta="0"
+ name="error_web"
+ top_delta="154"
+ width="120" />
+ <locate
+ height="-200"
+ layout="topleft" />
+ <icon
+ follows="top|left"
+ height="64"
+ image_name="badge_ok.j2c"
+ layout="topleft"
+ left="0"
+ name="step_1"
+ width="64" />
+ <text
+ type="string"
+ length="1"
+ follows="top|left"
+ font="SansSerifBig"
+ height="16"
+ layout="topleft"
+ left="72"
+ name="account_action"
+ right="438"
+ top="200"
+ width="218">
+ Upgrade you to premium membership.
+ </text>
+ <text
+ type="string"
+ length="1"
+ follows="top|left"
+ height="16"
+ layout="topleft"
+ left="72"
+ name="account_reason"
+ right="400"
+ width="180">
+ Only premimum members may own land.
+ </text>
+ <combo_box
+ follows="top|left"
+ height="16"
+ layout="topleft"
+ left="80"
+ name="account_level"
+ width="336">
+ <combo_box.item
+ label="US$9.95/month, billed monthly"
+ name="US$9.95/month,billedmonthly" />
+ <combo_box.item
+ label="US$7.50/month, billed quarterly"
+ name="US$7.50/month,billedquarterly" />
+ <combo_box.item
+ label="US$6.00/month, billed annually"
+ name="US$6.00/month,billedannually" />
+ </combo_box>
+ <locate
+ height="10"
+ layout="topleft" />
+ <icon
+ follows="top|left"
+ height="64"
+ image_name="badge_note.j2c"
+ layout="topleft"
+ left="0"
+ name="step_2"
+ width="64" />
+ <text
+ type="string"
+ length="1"
+ follows="top|left"
+ font="SansSerifBig"
+ height="16"
+ layout="topleft"
+ left="72"
+ name="land_use_action"
+ right="438"
+ top="284"
+ width="218">
+ Increase your monthly land use fees to US$ 40/month.
+ </text>
+ <text
+ type="string"
+ length="1"
+ follows="top|left"
+ height="32"
+ layout="topleft"
+ left="72"
+ name="land_use_reason"
+ right="435"
+ width="215">
+ You hold 1309 m² of land.
+ This parcel is 512 m² of land.
+ </text>
+ <locate
+ height="10"
+ layout="topleft" />
+ <icon
+ follows="top|left"
+ height="64"
+ image_name="badge_note.j2c"
+ layout="topleft"
+ left="0"
+ name="step_3"
+ width="64" />
+ <text
+ type="string"
+ length="1"
+ bottom_delta="-38"
+ follows="top|left"
+ font="SansSerifBig"
+ height="16"
+ layout="topleft"
+ left="72"
+ name="purchase_action"
+ right="438">
+ Pay Joe Resident L$ 4000 for the land
+ </text>
+ <text
+ type="string"
+ length="1"
+ follows="top|left"
+ height="16"
+ layout="topleft"
+ left="72"
+ name="currency_reason"
+ right="400">
+ You have L$ 2,100.
+ </text>
+ <text
+ type="string"
+ length="1"
+ follows="top|left"
+ height="16"
+ layout="topleft"
+ left_delta="0"
+ name="currency_action"
+ top_pad="9"
+ width="90">
+ Buy additional L$
+ </text>
+ <locate
+ height="0"
+ layout="topleft"
+ width="8" />
+ <line_editor
+ type="string"
+ length="1"
+ follows="top|right"
+ height="16"
+ layout="topleft"
+ left="170"
+ name="currency_amt"
+ top="408"
+ width="80">
+ 1000
+ </line_editor>
+ <locate
+ height="0"
+ layout="topleft"
+ width="8" />
+ <text
+ type="string"
+ length="1"
+ follows="top|right"
+ height="16"
+ layout="topleft"
+ left="260"
+ name="currency_est"
+ top="409"
+ width="178">
+ for approx. US$ [AMOUNT2]
+ </text>
+ <text
+ type="string"
+ length="1"
+ follows="top|left"
+ height="16"
+ layout="topleft"
+ left="72"
+ name="currency_balance"
+ right="400">
+ You have L$ 2,100.
+ </text>
+ <check_box
+ follows="bottom|left"
+ height="20"
+ label="Remove [AMOUNT] m² of contribution from group."
+ layout="topleft"
+ left_delta="3"
+ name="remove_contribution"
+ top_delta="14"
+ visible="false"
+ width="275" />
+ <button
+ follows="bottom|left"
+ height="20"
+ label="Purchase"
+ layout="topleft"
+ left="70"
+ name="buy_btn"
+ top="448"
+ width="100" />
+ <button
+ follows="bottom|right"
+ height="20"
+ label="Cancel"
+ layout="topleft"
+ left="-90"
+ name="cancel_btn"
+ top="454"
+ width="80" />
+</floater>
diff --git a/indra/newview/skins/default/xui/en/floater_buy_object.xml b/indra/newview/skins/default/xui/en/floater_buy_object.xml
new file mode 100644
index 0000000000..505411b964
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/floater_buy_object.xml
@@ -0,0 +1,109 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<floater
+ can_resize="true"
+ height="250"
+ layout="topleft"
+ min_height="175"
+ min_width="154"
+ name="contents"
+ save_rect="true"
+ single_instance="true"
+ title="Buy Copy of Object"
+ width="280">
+ <floater.string
+ name="title_buy_text">
+ Buy
+ </floater.string>
+ <floater.string
+ name="title_buy_copy_text">
+ Buy a copy of
+ </floater.string>
+ <floater.string
+ name="no_copy_text">
+ (no copy)
+ </floater.string>
+ <floater.string
+ name="no_modify_text">
+ (no modify)
+ </floater.string>
+ <floater.string
+ name="no_transfer_text">
+ (no transfer)
+ </floater.string>
+ <scroll_list
+ follows="left|top|right"
+ height="36"
+ layout="topleft"
+ left="15"
+ name="object_list"
+ top="24"
+ width="250">
+ <scroll_list.columns
+ name="icon"
+ width="16" />
+ <scroll_list.columns
+ name="text"
+ width="234" />
+ </scroll_list>
+ <text
+ type="string"
+ length="1"
+ follows="left|top|right"
+ font="SansSerif"
+ height="16"
+ layout="topleft"
+ left_delta="0"
+ name="contents_text"
+ top_pad="4"
+ width="250">
+ and its contents:
+ </text>
+ <scroll_list
+ follows="left|top|right|bottom"
+ height="108"
+ layout="topleft"
+ left_delta="0"
+ name="item_list"
+ top_pad="4"
+ width="250">
+ <scroll_list.columns
+ name="icon"
+ width="16" />
+ <scroll_list.columns
+ name="text"
+ width="234" />
+ </scroll_list>
+ <text
+ type="string"
+ length="1"
+ follows="left|right|bottom"
+ font="SansSerif"
+ height="24"
+ layout="topleft"
+ left_delta="0"
+ name="buy_text"
+ top_pad="4"
+ width="281">
+ Buy for L$[AMOUNT] from [NAME]?
+ </text>
+ <button
+ follows="right|bottom"
+ height="20"
+ label="Buy"
+ label_selected="Buy"
+ layout="topleft"
+ left="10"
+ name="buy_btn"
+ top_pad="5"
+ width="125" />
+ <button
+ follows="right|bottom"
+ height="20"
+ label="Cancel"
+ label_selected="Cancel"
+ layout="topleft"
+ left_pad="5"
+ name="cancel_btn"
+ top_delta="0"
+ width="125" />
+</floater>
diff --git a/indra/newview/skins/default/xui/en/floater_camera.xml b/indra/newview/skins/default/xui/en/floater_camera.xml
new file mode 100644
index 0000000000..1501f39b67
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/floater_camera.xml
@@ -0,0 +1,142 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<floater
+ can_minimize="false"
+ can_close="false"
+ center_horiz="true"
+ follows="top"
+ height="95"
+ layout="topleft"
+ name="camera_floater"
+ save_rect="true"
+ save_visibility="true"
+ width="105">
+ <floater.string
+ name="rotate_tooltip">
+ Rotate Camera Around Focus
+ </floater.string>
+ <floater.string
+ name="zoom_tooltip">
+ Zoom Camera Towards Focus
+ </floater.string>
+ <floater.string
+ name="move_tooltip">
+ Move Camera Up and Down, Left and Right
+ </floater.string>
+ <panel
+ border="true"
+ height="64"
+ layout="topleft"
+ left="0"
+ top="0"
+ name="controls"
+ width="105">
+ <joystick_rotate
+ follows="top|left"
+ height="64"
+ image_selected="cam_rotate_in.tga"
+ image_unselected="cam_rotate_out.tga"
+ layout="topleft"
+ left="2"
+ name="cam_rotate_stick"
+ picture_style="true"
+ quadrant="left"
+ scale_image="false"
+ sound_flags="3"
+ tool_tip="Orbit Camera Around Focus"
+ top="0"
+ width="64" />
+ <joystick_track
+ follows="top|left"
+ height="64"
+ image_selected="cam_tracking_in.tga"
+ image_unselected="cam_tracking_out.tga"
+ layout="topleft"
+ left="2"
+ name="cam_track_stick"
+ picture_style="true"
+ quadrant="left"
+ scale_image="false"
+ sound_flags="3"
+ tool_tip="Move Camera Up and Down, Left and Right"
+ top="0"
+ visible="false"
+ width="64" />
+ <joystick_zoom
+ follows="top|left"
+ height="64"
+ image_unselected="cam_zoom_out.tga"
+ layout="topleft"
+ left_delta="74"
+ minus_image="cam_zoom_minus_in.tga"
+ name="zoom"
+ picture_style="true"
+ plus_image="cam_zoom_plus_in.tga"
+ quadrant="left"
+ scale_image="false"
+ sound_flags="3"
+ tool_tip="Zoom Camera Towards Focus"
+ top_delta="0"
+ width="16" />
+ </panel>
+ <panel
+ border="true"
+ height="30"
+ layout="topleft"
+ left="0"
+ top_pad="1"
+ name="buttons"
+ width="105">
+ <button
+ height="25"
+ label=""
+ layout="topleft"
+ left="0"
+ is_toggle="true"
+ image_selected="btn_orbit_selected.png"
+ image_unselected="btn_orbit_unselected.png"
+ name="orbit_btn"
+ tab_stop="false"
+ tool_tip="Orbit Camera"
+ value="true"
+ width="25">
+ </button>
+ <button
+ height="25"
+ label=""
+ layout="topleft"
+ left_pad="1"
+ is_toggle="true"
+ image_selected="btn_pan_selected.png"
+ image_unselected="btn_pan_unselected.png"
+ name="pan_btn"
+ tab_stop="false"
+ tool_tip="Pan Camera"
+ width="25">
+ </button>
+ <button
+ height="25"
+ label=""
+ layout="topleft"
+ left_pad="1"
+ is_toggle="true"
+ image_selected="btn_freecamera_selected.png"
+ image_unselected="btn_freecamera_unselected.png"
+ name="freecamera_btn"
+ tab_stop="false"
+ tool_tip="View Object"
+ width="25">
+ </button>
+ <button
+ height="25"
+ label=""
+ layout="topleft"
+ left_pad="2"
+ image_selected="btn_firstperson_selected.png"
+ image_unselected="btn_firstperson_unselected.png"
+ name="avatarview_btn"
+ tab_stop="false"
+ tool_tip="See as Avatar"
+ width="25">
+ </button>
+ </panel>
+</floater>
diff --git a/indra/newview/skins/default/xui/en/floater_choose_group.xml b/indra/newview/skins/default/xui/en/floater_choose_group.xml
new file mode 100644
index 0000000000..428afcff52
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/floater_choose_group.xml
@@ -0,0 +1,49 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<floater
+ height="258"
+ layout="topleft"
+ name="groups"
+ title="Groups"
+ width="280">
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="16"
+ layout="topleft"
+ left="12"
+ name="groupdesc"
+ top="24"
+ width="248">
+ Choose a group:
+ </text>
+ <scroll_list
+ height="160"
+ layout="topleft"
+ left_delta="0"
+ name="group list"
+ top_pad="8"
+ width="248">
+ <scroll_list.columns
+ name="name"
+ width="248" />
+ </scroll_list>
+ <button
+ height="20"
+ label="OK"
+ label_selected="OK"
+ layout="topleft"
+ left_delta="0"
+ name="OK"
+ top_pad="8"
+ width="80" />
+ <button
+ height="20"
+ label="Cancel"
+ label_selected="Cancel"
+ layout="topleft"
+ left_pad="8"
+ name="Cancel"
+ top_delta="0"
+ width="80" />
+</floater>
diff --git a/indra/newview/skins/default/xui/en/floater_color_picker.xml b/indra/newview/skins/default/xui/en/floater_color_picker.xml
new file mode 100644
index 0000000000..cda2020fca
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/floater_color_picker.xml
@@ -0,0 +1,225 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<floater
+ can_minimize="false"
+ follows="left|top"
+ height="380"
+ layout="topleft"
+ name="ColorPicker"
+ title="Color Picker"
+ width="440">
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ font="SansSerif"
+ height="10"
+ layout="topleft"
+ left="12"
+ mouse_opaque="false"
+ name="r_val_text"
+ top="35"
+ width="413">
+ Red:
+ </text>
+ <spinner
+ decimal_digits="0"
+ follows="left"
+ height="16"
+ increment="1"
+ initial_value="128"
+ layout="topleft"
+ left_delta="63"
+ max_val="255"
+ name="rspin"
+ top_delta="0"
+ width="50" />
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ font="SansSerif"
+ height="10"
+ layout="topleft"
+ left="12"
+ mouse_opaque="false"
+ name="g_val_text"
+ top="56"
+ width="413">
+ Green:
+ </text>
+ <spinner
+ decimal_digits="0"
+ follows="left"
+ height="16"
+ increment="1"
+ initial_value="128"
+ layout="topleft"
+ left_delta="63"
+ max_val="255"
+ name="gspin"
+ top_delta="0"
+ width="50" />
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ font="SansSerif"
+ height="10"
+ layout="topleft"
+ left="12"
+ mouse_opaque="false"
+ name="b_val_text"
+ top="77"
+ width="413">
+ Blue:
+ </text>
+ <spinner
+ decimal_digits="0"
+ follows="left"
+ height="16"
+ increment="1"
+ initial_value="128"
+ layout="topleft"
+ left_delta="63"
+ max_val="255"
+ name="bspin"
+ top_delta="0"
+ width="50" />
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ font="SansSerif"
+ height="10"
+ layout="topleft"
+ left="12"
+ mouse_opaque="false"
+ name="h_val_text"
+ top="108"
+ width="413">
+ Hue:
+ </text>
+ <spinner
+ decimal_digits="0"
+ follows="left"
+ height="16"
+ increment="1"
+ initial_value="180"
+ layout="topleft"
+ left_delta="63"
+ max_val="360"
+ name="hspin"
+ top_delta="0"
+ width="50" />
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ font="SansSerif"
+ height="10"
+ layout="topleft"
+ left="12"
+ mouse_opaque="false"
+ name="s_val_text"
+ top="129"
+ width="413">
+ Sat:
+ </text>
+ <spinner
+ decimal_digits="0"
+ follows="left"
+ height="16"
+ increment="1"
+ initial_value="50"
+ layout="topleft"
+ left_delta="63"
+ max_val="100"
+ name="sspin"
+ top_delta="0"
+ width="50" />
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ font="SansSerif"
+ height="10"
+ layout="topleft"
+ left="12"
+ mouse_opaque="false"
+ name="l_val_text"
+ top="150"
+ width="413">
+ Lum:
+ </text>
+ <spinner
+ decimal_digits="0"
+ follows="left"
+ height="16"
+ increment="1"
+ initial_value="50"
+ layout="topleft"
+ left_delta="63"
+ max_val="100"
+ name="lspin"
+ top_delta="0"
+ width="50" />
+ <check_box
+ follows="left|bottom"
+ height="20"
+ label="Apply Now"
+ layout="topleft"
+ left="12"
+ name="apply_immediate"
+ top_pad="185"
+ width="100" />
+ <button
+ follows="left|top"
+ height="32"
+ layout="topleft"
+ left_pad="30"
+ name="color_pipette"
+ picture_style="true"
+ width="32" />
+ <button
+ follows="right|bottom"
+ height="20"
+ label="Ok"
+ label_selected="Select"
+ layout="topleft"
+ left_pad="50"
+ name="select_btn"
+ width="100" />
+ <button
+ follows="right|bottom"
+ height="20"
+ label="Cancel"
+ label_selected="Cancel"
+ layout="topleft"
+ left_pad="5"
+ name="cancel_btn"
+ width="100" />
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="16"
+ layout="topleft"
+ left="12"
+ name="Current color:"
+ top="172"
+ width="110">
+ Current color:
+ </text>
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="16"
+ layout="topleft"
+ left="12"
+ name="(Drag below to save.)"
+ top_pad="66"
+ width="130">
+ (Drag below to save)
+ </text>
+</floater>
diff --git a/indra/newview/skins/default/xui/en/floater_critical.xml b/indra/newview/skins/default/xui/en/floater_critical.xml
new file mode 100644
index 0000000000..5475a1cf6a
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/floater_critical.xml
@@ -0,0 +1,57 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<floater
+ can_close="false"
+ can_minimize="false"
+ height="500"
+ layout="topleft"
+ name="modal container"
+ width="600">
+ <button
+ height="20"
+ label="Continue"
+ label_selected="Continue"
+ layout="topleft"
+ left="484"
+ name="Continue"
+ top="465"
+ width="100" />
+ <button
+ height="20"
+ label="Cancel"
+ label_selected="Cancel"
+ layout="topleft"
+ left_delta="-468"
+ name="Cancel"
+ top_delta="0"
+ width="100" />
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ font="SansSerif"
+ height="20"
+ layout="topleft"
+ left_delta="4"
+ name="tos_heading"
+ top_delta="-450"
+ width="552">
+ Please read the following message carefully.
+ </text>
+ <text_editor
+ type="string"
+ length="1"
+ bg_readonly_color="1 1 1 1"
+ bottom="455"
+ follows="left|top"
+ font="SansSerif"
+ layout="topleft"
+ left="20"
+ max_length="65536"
+ name="tos_text"
+ right="-20"
+ text_readonly_color="0 0 0 1"
+ top="45"
+ word_wrap="true">
+ TOS_TEXT
+ </text_editor>
+</floater>
diff --git a/indra/newview/skins/default/xui/en/floater_customize.xml b/indra/newview/skins/default/xui/en/floater_customize.xml
new file mode 100644
index 0000000000..824df082d8
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/floater_customize.xml
@@ -0,0 +1,3564 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<floater
+ can_minimize="false"
+ follows="left|top"
+ height="540"
+ layout="topleft"
+ left_delta="-3"
+ name="floater customize"
+ save_rect="true"
+ title="Appearance"
+ top_delta="-185"
+ width="494">
+ <tab_container
+ height="483"
+ layout="topleft"
+ left="0"
+ name="customize tab container"
+ tab_min_width="96"
+ tab_position="left"
+ top="24"
+ width="492">
+ <placeholder
+ label="Body Parts"
+ layout="topleft"
+ name="body_parts_placeholder" />
+ <panel
+ border="true"
+ follows="left|top|right|bottom"
+ height="481"
+ label="Shape"
+ layout="topleft"
+ left_delta="0"
+ name="Shape"
+ top_delta="0"
+ width="389">
+ <icon
+ follows="top|right"
+ height="16"
+ image_name="icon_lock.tga"
+ layout="topleft"
+ left="333"
+ mouse_opaque="true"
+ name="square"
+ top="5"
+ width="16" />
+ <icon
+ height="16"
+ layout="topleft"
+ left_delta="-325"
+ mouse_opaque="true"
+ top_delta="3"
+ width="16" />
+ <button
+ follows="right|bottom"
+ height="20"
+ label="Revert"
+ label_selected="Revert"
+ layout="topleft"
+ left="299"
+ name="Revert"
+ top="458"
+ width="82" />
+ <button
+ follows="left|top"
+ font="SansSerifSmall"
+ height="16"
+ label="Body"
+ label_selected="Body"
+ layout="topleft"
+ left="8"
+ name="Body"
+ top="65"
+ width="82" />
+ <button
+ follows="left|top"
+ font="SansSerifSmall"
+ height="16"
+ label="Head"
+ label_selected="Head"
+ layout="topleft"
+ left_delta="0"
+ name="Head"
+ top_pad="16"
+ width="82" />
+ <button
+ follows="left|top"
+ font="SansSerifSmall"
+ height="16"
+ label="Eyes"
+ label_selected="Eyes"
+ layout="topleft"
+ left_delta="0"
+ name="Eyes"
+ top_pad="16"
+ width="82" />
+ <button
+ follows="left|top"
+ font="SansSerifSmall"
+ height="16"
+ label="Ears"
+ label_selected="Ears"
+ layout="topleft"
+ left_delta="0"
+ name="Ears"
+ top_pad="16"
+ width="82" />
+ <button
+ follows="left|top"
+ font="SansSerifSmall"
+ height="16"
+ label="Nose"
+ label_selected="Nose"
+ layout="topleft"
+ left_delta="0"
+ name="Nose"
+ top_pad="16"
+ width="82" />
+ <button
+ follows="left|top"
+ font="SansSerifSmall"
+ height="16"
+ label="Mouth"
+ label_selected="Mouth"
+ layout="topleft"
+ left_delta="0"
+ name="Mouth"
+ top_pad="16"
+ width="82" />
+ <button
+ follows="left|top"
+ font="SansSerifSmall"
+ height="16"
+ label="Chin"
+ label_selected="Chin"
+ layout="topleft"
+ left_delta="0"
+ name="Chin"
+ top_pad="16"
+ width="82" />
+ <button
+ follows="left|top"
+ font="SansSerifSmall"
+ height="16"
+ label="Torso"
+ label_selected="Torso"
+ layout="topleft"
+ left_delta="0"
+ name="Torso"
+ top_pad="16"
+ width="82" />
+ <button
+ follows="left|top"
+ font="SansSerifSmall"
+ height="16"
+ label="Legs"
+ label_selected="Legs"
+ layout="topleft"
+ left_delta="0"
+ name="Legs"
+ top_pad="16"
+ width="82" />
+ <radio_group
+ control_name="AvatarSex"
+ height="34"
+ layout="topleft"
+ left_delta="0"
+ name="sex radio"
+ top_pad="16"
+ width="82">
+ <radio_item
+ height="16"
+ label="Female"
+ layout="topleft"
+ left="1"
+ name="radio"
+ top="1"
+ width="82" />
+ <radio_item
+ height="16"
+ label="Male"
+ layout="topleft"
+ left_delta="0"
+ name="radio2"
+ top_delta="16"
+ width="82" />
+ </radio_group>
+ <text
+ type="string"
+ length="1"
+ follows="left|top|right"
+ font="SansSerif"
+ height="16"
+ layout="topleft"
+ left="26"
+ name="title"
+ top="8"
+ width="355">
+ [DESC]
+ </text>
+ <text
+ type="string"
+ length="1"
+ follows="left|top|right"
+ font="SansSerif"
+ height="16"
+ layout="topleft"
+ left_delta="0"
+ name="title_no_modify"
+ top_delta="0"
+ width="355">
+ [DESC]: cannot modify
+ </text>
+ <text
+ type="string"
+ length="1"
+ follows="left|top|right"
+ font="SansSerif"
+ height="16"
+ layout="topleft"
+ left_delta="0"
+ name="title_loading"
+ top_delta="0"
+ width="355">
+ [DESC]: loading...
+ </text>
+ <text
+ type="string"
+ length="1"
+ follows="left|top|right"
+ font="SansSerif"
+ height="16"
+ layout="topleft"
+ left_delta="0"
+ name="title_not_worn"
+ top_delta="0"
+ width="355">
+ [DESC]: not worn
+ </text>
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="14"
+ layout="topleft"
+ left="8"
+ name="path"
+ top="24"
+ width="373">
+ Located in [PATH]
+ </text>
+ <text
+ type="string"
+ length="1"
+ follows="left|top|right"
+ height="28"
+ layout="topleft"
+ left_delta="0"
+ name="not worn instructions"
+ top_pad="8"
+ width="373">
+ Put on a new shape by dragging one from your inventory
+to your avatar. Alternately, you create a new one from
+scratch and wear it.
+ </text>
+ <text
+ type="string"
+ length="1"
+ follows="left|top|right"
+ height="28"
+ layout="topleft"
+ left_delta="0"
+ name="no modify instructions"
+ top_delta="0"
+ width="373">
+ You do not have permission to modify this wearable.
+ </text>
+ <text
+ type="string"
+ length="1"
+ bottom="486"
+ follows="left|top|right"
+ font="SansSerif"
+ halign="right"
+ height="28"
+ layout="topleft"
+ name="Item Action Label"
+ right="117"
+ width="100">
+ Shape:
+ </text>
+ <button
+ follows="left|top"
+ height="24"
+ label="Create New Shape"
+ label_selected="Create New Shape"
+ layout="topleft"
+ left="8"
+ name="Create New"
+ top="104"
+ width="120" />
+ <button
+ follows="right|bottom"
+ height="20"
+ label="Save"
+ label_selected="Save"
+ layout="topleft"
+ left="123"
+ name="Save"
+ top="458"
+ width="82" />
+ <button
+ follows="right|bottom"
+ height="20"
+ label="Save As..."
+ label_selected="Save As..."
+ layout="topleft"
+ left_pad="6"
+ name="Save As"
+ top_delta="0"
+ width="82" />
+ </panel>
+ <panel
+ border="true"
+ follows="left|top|right|bottom"
+ height="481"
+ label="Skin"
+ layout="topleft"
+ left_delta="0"
+ name="Skin"
+ top_delta="0"
+ width="389">
+ <icon
+ follows="top|right"
+ height="16"
+ image_name="icon_lock.tga"
+ layout="topleft"
+ left="333"
+ mouse_opaque="true"
+ name="square"
+ top="5"
+ width="16" />
+ <icon
+ height="16"
+ layout="topleft"
+ left_delta="-325"
+ mouse_opaque="true"
+ top_delta="3"
+ width="16" />
+ <button
+ follows="left|top"
+ font="SansSerifSmall"
+ height="16"
+ label="Skin Color"
+ label_selected="Skin Color"
+ layout="topleft"
+ left_delta="0"
+ name="Skin Color"
+ top_pad="41"
+ width="82" />
+ <button
+ follows="left|top"
+ font="SansSerifSmall"
+ height="16"
+ label="Face Detail"
+ label_selected="Face Detail"
+ layout="topleft"
+ left_delta="0"
+ name="Face Detail"
+ top_pad="16"
+ width="82" />
+ <button
+ follows="left|top"
+ font="SansSerifSmall"
+ height="16"
+ label="Makeup"
+ label_selected="Makeup"
+ layout="topleft"
+ left_delta="0"
+ name="Makeup"
+ top_pad="16"
+ width="82" />
+ <button
+ follows="left|top"
+ font="SansSerifSmall"
+ height="16"
+ label="Body Detail"
+ label_selected="Body Detail"
+ layout="topleft"
+ left_delta="0"
+ name="Body Detail"
+ top_pad="16"
+ width="82" />
+ <text
+ type="string"
+ length="1"
+ follows="left|top|right"
+ font="SansSerif"
+ height="16"
+ layout="topleft"
+ left="26"
+ name="title"
+ top="8"
+ width="355">
+ [DESC]
+ </text>
+ <text
+ type="string"
+ length="1"
+ follows="left|top|right"
+ font="SansSerif"
+ height="16"
+ layout="topleft"
+ left_delta="0"
+ name="title_no_modify"
+ top_delta="0"
+ width="355">
+ [DESC]: cannot modify
+ </text>
+ <text
+ type="string"
+ length="1"
+ follows="left|top|right"
+ font="SansSerif"
+ height="16"
+ layout="topleft"
+ left_delta="0"
+ name="title_loading"
+ top_delta="0"
+ width="355">
+ [DESC]: loading...
+ </text>
+ <text
+ type="string"
+ length="1"
+ follows="left|top|right"
+ font="SansSerif"
+ height="16"
+ layout="topleft"
+ left_delta="0"
+ name="title_not_worn"
+ top_delta="0"
+ width="355">
+ [DESC]: not worn
+ </text>
+ <text
+ type="string"
+ length="1"
+ follows="left|top|right"
+ height="14"
+ layout="topleft"
+ left="8"
+ name="path"
+ top="24"
+ width="373">
+ Located in [PATH]
+ </text>
+ <text
+ type="string"
+ length="1"
+ follows="left|top|right"
+ height="28"
+ layout="topleft"
+ left_delta="0"
+ name="not worn instructions"
+ top_pad="8"
+ width="373">
+ Put on a new skin by dragging one from your inventory
+to your avatar. Alternately, you create a new one from
+scratch and wear it.
+ </text>
+ <text
+ type="string"
+ length="1"
+ follows="left|top|right"
+ height="28"
+ layout="topleft"
+ left_delta="0"
+ name="no modify instructions"
+ top_delta="0"
+ width="373">
+ You do not have permission to modify this wearable.
+ </text>
+ <text
+ type="string"
+ length="1"
+ bottom="486"
+ follows="left|top|right"
+ font="SansSerif"
+ halign="right"
+ height="28"
+ layout="topleft"
+ name="Item Action Label"
+ right="117"
+ width="100">
+ Skin:
+ </text>
+ <texture_picker
+ allow_no_texture="true"
+ can_apply_immediately="true"
+ default_image_name="Default"
+ follows="left|top"
+ height="80"
+ label="Head Tattoos"
+ layout="topleft"
+ left="8"
+ name="Head Tattoos"
+ tool_tip="Click to choose a picture"
+ top="193"
+ width="74" />
+ <texture_picker
+ allow_no_texture="true"
+ can_apply_immediately="true"
+ default_image_name="Default"
+ follows="left|top"
+ height="80"
+ label="Upper Tattoos"
+ layout="topleft"
+ left_delta="0"
+ name="Upper Tattoos"
+ tool_tip="Click to choose a picture"
+ top_delta="80"
+ width="74" />
+ <texture_picker
+ allow_no_texture="true"
+ can_apply_immediately="true"
+ default_image_name="Default"
+ follows="left|top"
+ height="80"
+ label="Lower Tattoos"
+ layout="topleft"
+ left_delta="0"
+ name="Lower Tattoos"
+ tool_tip="Click to choose a picture"
+ top_delta="80"
+ width="74" />
+ <button
+ follows="left|top"
+ height="24"
+ label="Create New Skin"
+ label_selected="Create New Skin"
+ layout="topleft"
+ left_delta="0"
+ name="Create New"
+ top_delta="-249"
+ width="120" />
+ <button
+ follows="right|bottom"
+ height="20"
+ label="Save"
+ label_selected="Save"
+ layout="topleft"
+ left="123"
+ name="Save"
+ top="458"
+ width="82" />
+ <button
+ follows="right|bottom"
+ height="20"
+ label="Save As..."
+ label_selected="Save As..."
+ layout="topleft"
+ left_pad="6"
+ name="Save As"
+ top_delta="0"
+ width="82" />
+ <button
+ follows="right|bottom"
+ height="20"
+ label="Revert"
+ label_selected="Revert"
+ layout="topleft"
+ left_pad="6"
+ name="Revert"
+ top_delta="0"
+ width="82" />
+ </panel>
+ <panel
+ border="true"
+ follows="left|top|right|bottom"
+ height="481"
+ label="Hair"
+ layout="topleft"
+ left_delta="0"
+ name="Hair"
+ top_delta="0"
+ width="389">
+ <icon
+ follows="top|right"
+ height="16"
+ image_name="icon_lock.tga"
+ layout="topleft"
+ left="333"
+ mouse_opaque="true"
+ name="square"
+ top="5"
+ width="16" />
+ <icon
+ height="16"
+ layout="topleft"
+ left_delta="-325"
+ mouse_opaque="true"
+ top_delta="3"
+ width="16" />
+ <button
+ follows="left|top"
+ font="SansSerifSmall"
+ height="16"
+ label="Color"
+ label_selected="Color"
+ layout="topleft"
+ left_delta="0"
+ name="Color"
+ top_pad="41"
+ width="82" />
+ <button
+ follows="left|top"
+ font="SansSerifSmall"
+ height="16"
+ label="Style"
+ label_selected="Style"
+ layout="topleft"
+ left_delta="0"
+ name="Style"
+ top_pad="16"
+ width="82" />
+ <button
+ follows="left|top"
+ font="SansSerifSmall"
+ height="16"
+ label="Eyebrows"
+ label_selected="Eyebrows"
+ layout="topleft"
+ left_delta="0"
+ name="Eyebrows"
+ top_pad="16"
+ width="82" />
+ <button
+ follows="left|top"
+ font="SansSerifSmall"
+ height="16"
+ label="Facial"
+ label_selected="Facial"
+ layout="topleft"
+ left_delta="0"
+ name="Facial"
+ top_pad="16"
+ width="82" />
+ <text
+ type="string"
+ length="1"
+ follows="left|top|right"
+ font="SansSerif"
+ height="16"
+ layout="topleft"
+ left="26"
+ name="title"
+ top="8"
+ width="355">
+ [DESC]
+ </text>
+ <text
+ type="string"
+ length="1"
+ follows="left|top|right"
+ font="SansSerif"
+ height="16"
+ layout="topleft"
+ left_delta="0"
+ name="title_no_modify"
+ top_delta="0"
+ width="355">
+ [DESC]: cannot modify
+ </text>
+ <text
+ type="string"
+ length="1"
+ follows="left|top|right"
+ font="SansSerif"
+ height="16"
+ layout="topleft"
+ left_delta="0"
+ name="title_loading"
+ top_delta="0"
+ width="355">
+ [DESC]: loading...
+ </text>
+ <text
+ type="string"
+ length="1"
+ follows="left|top|right"
+ font="SansSerif"
+ height="16"
+ layout="topleft"
+ left_delta="0"
+ name="title_not_worn"
+ top_delta="0"
+ width="355">
+ [DESC]: not worn
+ </text>
+ <text
+ type="string"
+ length="1"
+ follows="left|top|right"
+ height="14"
+ layout="topleft"
+ left="8"
+ name="path"
+ top="24"
+ width="373">
+ Located in [PATH]
+ </text>
+ <text
+ type="string"
+ length="1"
+ follows="left|top|right"
+ height="28"
+ layout="topleft"
+ left_delta="0"
+ name="not worn instructions"
+ top_pad="8"
+ width="373">
+ Put on a new hair by dragging one from your inventory
+to your avatar. Alternately, you create a new one from
+scratch and wear it.
+ </text>
+ <text
+ type="string"
+ length="1"
+ follows="left|top|right"
+ height="28"
+ layout="topleft"
+ left_delta="0"
+ name="no modify instructions"
+ top_delta="0"
+ width="373">
+ You do not have permission to modify this wearable.
+ </text>
+ <text
+ type="string"
+ length="1"
+ bottom="486"
+ follows="left|top|right"
+ font="SansSerif"
+ halign="right"
+ height="28"
+ layout="topleft"
+ name="Item Action Label"
+ right="117"
+ width="100">
+ Hair:
+ </text>
+ <texture_picker
+ can_apply_immediately="true"
+ default_image_name="Default"
+ follows="left|top"
+ height="80"
+ label="Texture"
+ layout="topleft"
+ left="8"
+ name="Texture"
+ tool_tip="Click to choose a picture"
+ top="193"
+ width="64" />
+ <button
+ follows="left|top"
+ height="24"
+ label="Create New Hair"
+ label_selected="Create New Hair"
+ layout="topleft"
+ left_delta="0"
+ name="Create New"
+ top_delta="-89"
+ width="120" />
+ <button
+ follows="right|bottom"
+ height="20"
+ label="Save"
+ label_selected="Save"
+ layout="topleft"
+ left="123"
+ name="Save"
+ top="458"
+ width="82" />
+ <button
+ follows="right|bottom"
+ height="20"
+ label="Save As..."
+ label_selected="Save As..."
+ layout="topleft"
+ left_pad="6"
+ name="Save As"
+ top_delta="0"
+ width="82" />
+ <button
+ follows="right|bottom"
+ height="20"
+ label="Revert"
+ label_selected="Revert"
+ layout="topleft"
+ left_pad="6"
+ name="Revert"
+ top_delta="0"
+ width="82" />
+ </panel>
+ <panel
+ border="true"
+ follows="left|top|right|bottom"
+ height="481"
+ label="Eyes"
+ layout="topleft"
+ left_delta="0"
+ name="Eyes"
+ top_delta="0"
+ width="389">
+ <icon
+ follows="top|right"
+ height="16"
+ image_name="icon_lock.tga"
+ layout="topleft"
+ left="333"
+ mouse_opaque="true"
+ name="square"
+ top="5"
+ width="16" />
+ <icon
+ height="16"
+ layout="topleft"
+ left_delta="-325"
+ mouse_opaque="true"
+ top_delta="3"
+ width="16" />
+ <text
+ type="string"
+ length="1"
+ follows="left|top|right"
+ font="SansSerif"
+ height="16"
+ layout="topleft"
+ left_pad="2"
+ name="title"
+ top_delta="0"
+ width="355">
+ [DESC]
+ </text>
+ <text
+ type="string"
+ length="1"
+ follows="left|top|right"
+ font="SansSerif"
+ height="16"
+ layout="topleft"
+ left_delta="0"
+ name="title_no_modify"
+ top_delta="0"
+ width="355">
+ [DESC]: cannot modify
+ </text>
+ <text
+ type="string"
+ length="1"
+ follows="left|top|right"
+ font="SansSerif"
+ height="16"
+ layout="topleft"
+ left_delta="0"
+ name="title_loading"
+ top_delta="0"
+ width="355">
+ [DESC]: loading...
+ </text>
+ <text
+ type="string"
+ length="1"
+ follows="left|top|right"
+ font="SansSerif"
+ height="16"
+ layout="topleft"
+ left_delta="0"
+ name="title_not_worn"
+ top_delta="0"
+ width="355">
+ [DESC]: not worn
+ </text>
+ <text
+ type="string"
+ length="1"
+ follows="left|top|right"
+ height="14"
+ layout="topleft"
+ left="8"
+ name="path"
+ top="24"
+ width="373">
+ Located in [PATH]
+ </text>
+ <text
+ type="string"
+ length="1"
+ follows="left|top|right"
+ height="28"
+ layout="topleft"
+ left_delta="0"
+ name="not worn instructions"
+ top_pad="8"
+ width="373">
+ Put on a new eyes by dragging one from your inventory
+to your avatar. Alternately, you create a new one from
+scratch and wear it.
+ </text>
+ <text
+ type="string"
+ length="1"
+ follows="left|top|right"
+ height="28"
+ layout="topleft"
+ left_delta="0"
+ name="no modify instructions"
+ top_delta="0"
+ width="373">
+ You do not have permission to modify this wearable.
+ </text>
+ <text
+ type="string"
+ length="1"
+ bottom="486"
+ follows="left|top|right"
+ font="SansSerif"
+ halign="right"
+ height="28"
+ layout="topleft"
+ name="Item Action Label"
+ right="117"
+ width="100">
+ Eyes:
+ </text>
+ <texture_picker
+ can_apply_immediately="true"
+ default_image_name="Default"
+ follows="left|top"
+ height="80"
+ label="Iris"
+ layout="topleft"
+ left="8"
+ name="Iris"
+ tool_tip="Click to choose a picture"
+ top="65"
+ width="64" />
+ <button
+ follows="left|top"
+ height="24"
+ label="Create New Eyes"
+ label_selected="Create New Eyes"
+ layout="topleft"
+ left_delta="0"
+ name="Create New"
+ top_delta="39"
+ width="120" />
+ <button
+ follows="right|bottom"
+ height="20"
+ label="Save"
+ label_selected="Save"
+ layout="topleft"
+ left="123"
+ name="Save"
+ top="458"
+ width="82" />
+ <button
+ follows="right|bottom"
+ height="20"
+ label="Save As..."
+ label_selected="Save As..."
+ layout="topleft"
+ left_pad="6"
+ name="Save As"
+ top_delta="0"
+ width="82" />
+ <button
+ follows="right|bottom"
+ height="20"
+ label="Revert"
+ label_selected="Revert"
+ layout="topleft"
+ left_pad="6"
+ name="Revert"
+ top_delta="0"
+ width="82" />
+ </panel>
+ <placeholder
+ label="Clothes"
+ layout="topleft"
+ name="clothes_placeholder" />
+ <panel
+ border="true"
+ follows="left|top|right|bottom"
+ height="481"
+ label="Shirt"
+ layout="topleft"
+ left_delta="0"
+ name="Shirt"
+ top_delta="0"
+ width="389">
+ <icon
+ follows="top|right"
+ height="16"
+ image_name="icon_lock.tga"
+ layout="topleft"
+ left="333"
+ mouse_opaque="true"
+ name="square"
+ top="5"
+ width="16" />
+ <icon
+ height="16"
+ layout="topleft"
+ left_delta="-325"
+ mouse_opaque="true"
+ top_delta="3"
+ width="16" />
+ <texture_picker
+ can_apply_immediately="true"
+ default_image_name="Default"
+ follows="left|top"
+ height="80"
+ label="Fabric"
+ layout="topleft"
+ left_delta="0"
+ name="Fabric"
+ tool_tip="Click to choose a picture"
+ top_pad="41"
+ width="64" />
+ <color_swatch
+ border_color="0.45098 0.517647 0.607843 1"
+ can_apply_immediately="true"
+ follows="left|top"
+ height="80"
+ label="Color/Tint"
+ layout="topleft"
+ left_delta="0"
+ name="Color/Tint"
+ tool_tip="Click to open Color Picker"
+ top_delta="80"
+ width="64" />
+ <button
+ follows="left|top"
+ height="24"
+ label="Create New Shirt"
+ label_selected="Create New Shirt"
+ layout="topleft"
+ left_delta="0"
+ name="Create New"
+ top_delta="-41"
+ width="120" />
+ <button
+ follows="left|top"
+ height="20"
+ label="Take Off"
+ label_selected="Take Off"
+ layout="topleft"
+ left_delta="0"
+ name="Take Off"
+ top_pad="102"
+ width="82" />
+ <button
+ follows="right|bottom"
+ height="20"
+ label="Save"
+ label_selected="Save"
+ layout="topleft"
+ left="123"
+ name="Save"
+ top="458"
+ width="82" />
+ <button
+ follows="right|bottom"
+ height="20"
+ label="Save As..."
+ label_selected="Save As..."
+ layout="topleft"
+ left_pad="6"
+ name="Save As"
+ top_delta="0"
+ width="82" />
+ <button
+ follows="right|bottom"
+ height="20"
+ label="Revert"
+ label_selected="Revert"
+ layout="topleft"
+ left_pad="6"
+ name="Revert"
+ top_delta="0"
+ width="82" />
+ <text
+ type="string"
+ length="1"
+ follows="left|top|right"
+ font="SansSerif"
+ height="16"
+ layout="topleft"
+ left="26"
+ name="title"
+ top="8"
+ width="355">
+ [DESC]
+ </text>
+ <text
+ type="string"
+ length="1"
+ follows="left|top|right"
+ font="SansSerif"
+ height="16"
+ layout="topleft"
+ left_delta="0"
+ name="title_no_modify"
+ top_delta="0"
+ width="355">
+ [DESC]: cannot modify
+ </text>
+ <text
+ type="string"
+ length="1"
+ follows="left|top|right"
+ font="SansSerif"
+ height="16"
+ layout="topleft"
+ left_delta="0"
+ name="title_loading"
+ top_delta="0"
+ width="355">
+ [DESC]: loading...
+ </text>
+ <text
+ type="string"
+ length="1"
+ follows="left|top|right"
+ font="SansSerif"
+ height="16"
+ layout="topleft"
+ left_delta="0"
+ name="title_not_worn"
+ top_delta="0"
+ width="355">
+ [DESC]: not worn
+ </text>
+ <text
+ type="string"
+ length="1"
+ follows="left|top|right"
+ height="14"
+ layout="topleft"
+ left="8"
+ name="path"
+ top="24"
+ width="373">
+ Located in [PATH]
+ </text>
+ <spinner
+ decimal_digits="0"
+ follows="left|top|right"
+ height="16"
+ increment="1"
+ initial_value="0"
+ label="Item"
+ label_width="30"
+ layout="topleft"
+ left_delta="2"
+ max_val="5"
+ name="index"
+ text_enabled_color="110, 15, 15, 255"
+ top_pad="6"
+ width="87" />
+ <text
+ type="string"
+ length="1"
+ follows="left|top|right"
+ height="28"
+ layout="topleft"
+ left_delta="0"
+ name="not worn instructions"
+ top_pad="8"
+ width="373">
+ Put on a new shirt by dragging one from your inventory
+to your avatar. Alternately, you create a new one from
+scratch and wear it.
+ </text>
+ <text
+ type="string"
+ length="1"
+ follows="left|top|right"
+ height="28"
+ layout="topleft"
+ left_delta="0"
+ name="no modify instructions"
+ top_delta="0"
+ width="373">
+ You do not have permission to modify this wearable.
+ </text>
+ <text
+ type="string"
+ length="1"
+ bottom="486"
+ follows="left|top|right"
+ font="SansSerif"
+ halign="right"
+ height="28"
+ layout="topleft"
+ name="Item Action Label"
+ right="117"
+ width="100">
+ Shirt:
+ </text>
+ </panel>
+ <panel
+ border="true"
+ follows="left|top|right|bottom"
+ height="481"
+ label="Pants"
+ layout="topleft"
+ left_delta="0"
+ name="Pants"
+ top_delta="0"
+ width="389">
+ <icon
+ follows="top|right"
+ height="16"
+ image_name="icon_lock.tga"
+ layout="topleft"
+ left="333"
+ mouse_opaque="true"
+ name="square"
+ top="5"
+ width="16" />
+ <icon
+ height="16"
+ layout="topleft"
+ left_delta="-325"
+ mouse_opaque="true"
+ top_delta="3"
+ width="16" />
+ <texture_picker
+ can_apply_immediately="true"
+ default_image_name="Default"
+ follows="left|top"
+ height="80"
+ label="Fabric"
+ layout="topleft"
+ left_delta="0"
+ name="Fabric"
+ tool_tip="Click to choose a picture"
+ top_pad="41"
+ width="64" />
+ <color_swatch
+ border_color="0.45098 0.517647 0.607843 1"
+ can_apply_immediately="true"
+ follows="left|top"
+ height="80"
+ label="Color/Tint"
+ layout="topleft"
+ left_delta="0"
+ name="Color/Tint"
+ tool_tip="Click to open Color Picker"
+ top_delta="80"
+ width="64" />
+ <button
+ follows="left|top"
+ height="24"
+ label="Create New Pants"
+ label_selected="Create New Pants"
+ layout="topleft"
+ left_delta="0"
+ name="Create New"
+ top_delta="-41"
+ width="120" />
+ <button
+ follows="left|top"
+ height="20"
+ label="Take Off"
+ label_selected="Take Off"
+ layout="topleft"
+ left_delta="0"
+ name="Take Off"
+ top_pad="102"
+ width="82" />
+ <button
+ follows="right|bottom"
+ height="20"
+ label="Save"
+ label_selected="Save"
+ layout="topleft"
+ left="123"
+ name="Save"
+ top="458"
+ width="82" />
+ <button
+ follows="right|bottom"
+ height="20"
+ label="Save As..."
+ label_selected="Save As..."
+ layout="topleft"
+ left_pad="6"
+ name="Save As"
+ top_delta="0"
+ width="82" />
+ <button
+ follows="right|bottom"
+ height="20"
+ label="Revert"
+ label_selected="Revert"
+ layout="topleft"
+ left_pad="6"
+ name="Revert"
+ top_delta="0"
+ width="82" />
+ <text
+ type="string"
+ length="1"
+ follows="left|top|right"
+ font="SansSerif"
+ height="16"
+ layout="topleft"
+ left="26"
+ name="title"
+ top="8"
+ width="355">
+ [DESC]
+ </text>
+ <text
+ type="string"
+ length="1"
+ follows="left|top|right"
+ font="SansSerif"
+ height="16"
+ layout="topleft"
+ left_delta="0"
+ name="title_no_modify"
+ top_delta="0"
+ width="355">
+ [DESC]: cannot modify
+ </text>
+ <text
+ type="string"
+ length="1"
+ follows="left|top|right"
+ font="SansSerif"
+ height="16"
+ layout="topleft"
+ left_delta="0"
+ name="title_loading"
+ top_delta="0"
+ width="355">
+ [DESC]: loading...
+ </text>
+ <text
+ type="string"
+ length="1"
+ follows="left|top|right"
+ font="SansSerif"
+ height="16"
+ layout="topleft"
+ left_delta="0"
+ name="title_not_worn"
+ top_delta="0"
+ width="355">
+ [DESC]: not worn
+ </text>
+ <text
+ type="string"
+ length="1"
+ follows="left|top|right"
+ height="14"
+ layout="topleft"
+ left="8"
+ name="path"
+ top="24"
+ width="373">
+ Located in [PATH]
+ </text>
+ <spinner
+ decimal_digits="0"
+ follows="left|top|right"
+ height="16"
+ increment="1"
+ initial_value="0"
+ label="Item"
+ label_width="30"
+ layout="topleft"
+ left_delta="2"
+ max_val="5"
+ name="index"
+ text_enabled_color="110, 15, 15, 255"
+ top_pad="6"
+ width="87" />
+ <text
+ type="string"
+ length="1"
+ follows="left|top|right"
+ height="28"
+ layout="topleft"
+ left_delta="0"
+ name="not worn instructions"
+ top_pad="8"
+ width="373">
+ Put on a new pants by dragging one from your inventory
+to your avatar. Alternately, you create a new one from
+scratch and wear it.
+ </text>
+ <text
+ type="string"
+ length="1"
+ follows="left|top|right"
+ height="28"
+ layout="topleft"
+ left_delta="0"
+ name="no modify instructions"
+ top_delta="0"
+ width="373">
+ You do not have permission to modify this wearable.
+ </text>
+ <text
+ type="string"
+ length="1"
+ bottom="486"
+ follows="left|top|right"
+ font="SansSerif"
+ halign="right"
+ height="28"
+ layout="topleft"
+ name="Item Action Label"
+ right="117"
+ width="100">
+ Pants:
+ </text>
+ </panel>
+ <panel
+ border="true"
+ follows="left|top|right|bottom"
+ height="481"
+ label="Shoes"
+ layout="topleft"
+ left_delta="0"
+ name="Shoes"
+ top_delta="0"
+ width="389">
+ <icon
+ follows="top|right"
+ height="16"
+ image_name="icon_lock.tga"
+ layout="topleft"
+ left="333"
+ mouse_opaque="true"
+ name="square"
+ top="5"
+ width="16" />
+ <icon
+ height="16"
+ layout="topleft"
+ left_delta="-325"
+ mouse_opaque="true"
+ top_delta="3"
+ width="16" />
+ <text
+ type="string"
+ length="1"
+ follows="left|top|right"
+ font="SansSerif"
+ height="16"
+ layout="topleft"
+ left_pad="2"
+ name="title"
+ top_delta="0"
+ width="355">
+ [DESC]
+ </text>
+ <text
+ type="string"
+ length="1"
+ follows="left|top|right"
+ font="SansSerif"
+ height="16"
+ layout="topleft"
+ left_delta="0"
+ name="title_no_modify"
+ top_delta="0"
+ width="355">
+ [DESC]: cannot modify
+ </text>
+ <text
+ type="string"
+ length="1"
+ follows="left|top|right"
+ font="SansSerif"
+ height="16"
+ layout="topleft"
+ left_delta="0"
+ name="title_loading"
+ top_delta="0"
+ width="355">
+ [DESC]: loading...
+ </text>
+ <text
+ type="string"
+ length="1"
+ follows="left|top|right"
+ font="SansSerif"
+ height="16"
+ layout="topleft"
+ left_delta="0"
+ name="title_not_worn"
+ top_delta="0"
+ width="355">
+ [DESC]: not worn
+ </text>
+ <text
+ type="string"
+ length="1"
+ follows="left|top|right"
+ height="14"
+ layout="topleft"
+ left="8"
+ name="path"
+ top="24"
+ width="373">
+ Located in [PATH]
+ </text>
+ <spinner
+ decimal_digits="0"
+ follows="left|top|right"
+ height="16"
+ increment="1"
+ initial_value="0"
+ label="Item"
+ label_width="30"
+ layout="topleft"
+ left_delta="2"
+ max_val="5"
+ name="index"
+ text_enabled_color="110, 15, 15, 255"
+ top_pad="6"
+ width="87" />
+ <text
+ type="string"
+ length="1"
+ follows="left|top|right"
+ height="28"
+ layout="topleft"
+ left_delta="0"
+ name="not worn instructions"
+ top_pad="8"
+ width="373">
+ Put on a new shoes by dragging one from your inventory
+to your avatar. Alternately, you create a new one from
+scratch and wear it.
+ </text>
+ <text
+ type="string"
+ length="1"
+ follows="left|top|right"
+ height="28"
+ layout="topleft"
+ left_delta="0"
+ name="no modify instructions"
+ top_delta="0"
+ width="373">
+ You do not have permission to modify this wearable.
+ </text>
+ <text
+ type="string"
+ length="1"
+ bottom="486"
+ follows="left|top|right"
+ font="SansSerif"
+ halign="right"
+ height="28"
+ layout="topleft"
+ name="Item Action Label"
+ right="117"
+ width="100">
+ Shoes:
+ </text>
+ <texture_picker
+ can_apply_immediately="true"
+ default_image_name="Default"
+ follows="left|top"
+ height="80"
+ label="Fabric"
+ layout="topleft"
+ left="8"
+ name="Fabric"
+ tool_tip="Click to choose a picture"
+ top="65"
+ width="64" />
+ <color_swatch
+ border_color="0.45098 0.517647 0.607843 1"
+ can_apply_immediately="true"
+ follows="left|top"
+ height="80"
+ label="Color/Tint"
+ layout="topleft"
+ left_delta="0"
+ name="Color/Tint"
+ tool_tip="Click to open Color Picker"
+ top_delta="80"
+ width="64" />
+ <button
+ follows="left|top"
+ height="24"
+ label="Create New Shoes"
+ label_selected="Create New Shoes"
+ layout="topleft"
+ left_delta="0"
+ name="Create New"
+ top_delta="-41"
+ width="120" />
+ <button
+ follows="left|top"
+ height="20"
+ label="Take Off"
+ label_selected="Take Off"
+ layout="topleft"
+ left_delta="0"
+ name="Take Off"
+ top_pad="102"
+ width="82" />
+ <button
+ follows="right|bottom"
+ height="20"
+ label="Save"
+ label_selected="Save"
+ layout="topleft"
+ left="123"
+ name="Save"
+ top="458"
+ width="82" />
+ <button
+ follows="right|bottom"
+ height="20"
+ label="Save As..."
+ label_selected="Save As..."
+ layout="topleft"
+ left_pad="6"
+ name="Save As"
+ top_delta="0"
+ width="82" />
+ <button
+ follows="right|bottom"
+ height="20"
+ label="Revert"
+ label_selected="Revert"
+ layout="topleft"
+ left_pad="6"
+ name="Revert"
+ top_delta="0"
+ width="82" />
+ </panel>
+ <panel
+ border="true"
+ follows="left|top|right|bottom"
+ height="481"
+ label="Socks"
+ layout="topleft"
+ left_delta="0"
+ name="Socks"
+ top_delta="0"
+ width="389">
+ <icon
+ follows="top|right"
+ height="16"
+ image_name="icon_lock.tga"
+ layout="topleft"
+ left="333"
+ mouse_opaque="true"
+ name="square"
+ top="5"
+ width="16" />
+ <icon
+ height="16"
+ layout="topleft"
+ left_delta="-325"
+ mouse_opaque="true"
+ top_delta="3"
+ width="16" />
+ <text
+ type="string"
+ length="1"
+ follows="left|top|right"
+ font="SansSerif"
+ height="16"
+ layout="topleft"
+ left_pad="2"
+ name="title"
+ top_delta="0"
+ width="355">
+ [DESC]
+ </text>
+ <text
+ type="string"
+ length="1"
+ follows="left|top|right"
+ font="SansSerif"
+ height="16"
+ layout="topleft"
+ left_delta="0"
+ name="title_no_modify"
+ top_delta="0"
+ width="355">
+ [DESC]: cannot modify
+ </text>
+ <text
+ type="string"
+ length="1"
+ follows="left|top|right"
+ font="SansSerif"
+ height="16"
+ layout="topleft"
+ left_delta="0"
+ name="title_loading"
+ top_delta="0"
+ width="355">
+ [DESC]: loading...
+ </text>
+ <text
+ type="string"
+ length="1"
+ follows="left|top|right"
+ font="SansSerif"
+ height="16"
+ layout="topleft"
+ left_delta="0"
+ name="title_not_worn"
+ top_delta="0"
+ width="355">
+ [DESC]: not worn
+ </text>
+ <text
+ type="string"
+ length="1"
+ follows="left|top|right"
+ height="14"
+ layout="topleft"
+ left="8"
+ name="path"
+ top="24"
+ width="373">
+ Located in [PATH]
+ </text>
+ <spinner
+ decimal_digits="0"
+ follows="left|top|right"
+ height="16"
+ increment="1"
+ initial_value="0"
+ label="Item"
+ label_width="30"
+ layout="topleft"
+ left_delta="2"
+ max_val="5"
+ name="index"
+ text_enabled_color="110, 15, 15, 255"
+ top_pad="6"
+ width="87" />
+ <text
+ type="string"
+ length="1"
+ follows="left|top|right"
+ height="28"
+ layout="topleft"
+ left_delta="0"
+ name="not worn instructions"
+ top_pad="8"
+ width="373">
+ Put on a new socks by dragging one from your inventory
+to your avatar. Alternately, you create a new one from
+scratch and wear it.
+ </text>
+ <text
+ type="string"
+ length="1"
+ follows="left|top|right"
+ height="28"
+ layout="topleft"
+ left_delta="0"
+ name="no modify instructions"
+ top_delta="0"
+ width="373">
+ You do not have permission to modify this wearable.
+ </text>
+ <text
+ type="string"
+ length="1"
+ bottom="486"
+ follows="left|top|right"
+ font="SansSerif"
+ halign="right"
+ height="28"
+ layout="topleft"
+ name="Item Action Label"
+ right="117"
+ width="100">
+ Socks:
+ </text>
+ <texture_picker
+ can_apply_immediately="true"
+ default_image_name="Default"
+ follows="left|top"
+ height="80"
+ label="Fabric"
+ layout="topleft"
+ left="8"
+ name="Fabric"
+ tool_tip="Click to choose a picture"
+ top="65"
+ width="64" />
+ <color_swatch
+ border_color="0.45098 0.517647 0.607843 1"
+ can_apply_immediately="true"
+ follows="left|top"
+ height="80"
+ label="Color/Tint"
+ layout="topleft"
+ left_delta="0"
+ name="Color/Tint"
+ tool_tip="Click to open Color Picker"
+ top_delta="80"
+ width="64" />
+ <button
+ follows="left|top"
+ height="24"
+ label="Create New Socks"
+ label_selected="Create New Socks"
+ layout="topleft"
+ left_delta="0"
+ name="Create New"
+ top_delta="-41"
+ width="120" />
+ <button
+ follows="left|top"
+ height="20"
+ label="Take Off"
+ label_selected="Take Off"
+ layout="topleft"
+ left_delta="0"
+ name="Take Off"
+ top_pad="102"
+ width="82" />
+ <button
+ follows="right|bottom"
+ height="20"
+ label="Save"
+ label_selected="Save"
+ layout="topleft"
+ left="123"
+ name="Save"
+ top="458"
+ width="82" />
+ <button
+ follows="right|bottom"
+ height="20"
+ label="Save As..."
+ label_selected="Save As..."
+ layout="topleft"
+ left_pad="6"
+ name="Save As"
+ top_delta="0"
+ width="82" />
+ <button
+ follows="right|bottom"
+ height="20"
+ label="Revert"
+ label_selected="Revert"
+ layout="topleft"
+ left_pad="6"
+ name="Revert"
+ top_delta="0"
+ width="82" />
+ </panel>
+ <panel
+ border="true"
+ follows="left|top|right|bottom"
+ height="481"
+ label="Jacket"
+ layout="topleft"
+ left_delta="0"
+ name="Jacket"
+ top_delta="0"
+ width="389">
+ <icon
+ follows="top|right"
+ height="16"
+ image_name="icon_lock.tga"
+ layout="topleft"
+ left="333"
+ mouse_opaque="true"
+ name="square"
+ top="5"
+ width="16" />
+ <icon
+ height="16"
+ layout="topleft"
+ left_delta="-325"
+ mouse_opaque="true"
+ top_delta="3"
+ width="16" />
+ <text
+ type="string"
+ length="1"
+ follows="left|top|right"
+ font="SansSerif"
+ height="16"
+ layout="topleft"
+ left_pad="2"
+ name="title"
+ top_delta="0"
+ width="355">
+ [DESC]
+ </text>
+ <text
+ type="string"
+ length="1"
+ follows="left|top|right"
+ font="SansSerif"
+ height="16"
+ layout="topleft"
+ left_delta="0"
+ name="title_no_modify"
+ top_delta="0"
+ width="355">
+ [DESC]: cannot modify
+ </text>
+ <text
+ type="string"
+ length="1"
+ follows="left|top|right"
+ font="SansSerif"
+ height="16"
+ layout="topleft"
+ left_delta="0"
+ name="title_loading"
+ top_delta="0"
+ width="355">
+ [DESC]: loading...
+ </text>
+ <text
+ type="string"
+ length="1"
+ follows="left|top|right"
+ font="SansSerif"
+ height="16"
+ layout="topleft"
+ left_delta="0"
+ name="title_not_worn"
+ top_delta="0"
+ width="355">
+ [DESC]: not worn
+ </text>
+ <text
+ type="string"
+ length="1"
+ follows="left|top|right"
+ height="14"
+ layout="topleft"
+ left="8"
+ name="path"
+ top="24"
+ width="373">
+ Located in [PATH]
+ </text>
+ <spinner
+ decimal_digits="0"
+ follows="left|top|right"
+ height="16"
+ increment="1"
+ initial_value="0"
+ label="Item"
+ label_width="30"
+ layout="topleft"
+ left_delta="2"
+ max_val="5"
+ name="index"
+ text_enabled_color="110, 15, 15, 255"
+ top_pad="6"
+ width="87" />
+ <text
+ type="string"
+ length="1"
+ follows="left|top|right"
+ height="28"
+ layout="topleft"
+ left_delta="0"
+ name="not worn instructions"
+ top_pad="8"
+ width="373">
+ Put on a new jacket by dragging one from your inventory
+to your avatar. Alternately, you create a new one from
+scratch and wear it.
+ </text>
+ <text
+ type="string"
+ length="1"
+ follows="left|top|right"
+ height="28"
+ layout="topleft"
+ left_delta="0"
+ name="no modify instructions"
+ top_delta="0"
+ width="373">
+ You do not have permission to modify this wearable.
+ </text>
+ <text
+ type="string"
+ length="1"
+ bottom="486"
+ follows="left|top|right"
+ font="SansSerif"
+ halign="right"
+ height="28"
+ layout="topleft"
+ name="Item Action Label"
+ right="117"
+ width="100">
+ Jacket:
+ </text>
+ <texture_picker
+ can_apply_immediately="true"
+ default_image_name="Default"
+ follows="left|top"
+ height="80"
+ label="Upper Fabric"
+ layout="topleft"
+ left="8"
+ name="Upper Fabric"
+ tool_tip="Click to choose a picture"
+ top="65"
+ width="64" />
+ <texture_picker
+ can_apply_immediately="true"
+ default_image_name="Default"
+ follows="left|top"
+ height="80"
+ label="Lower Fabric"
+ layout="topleft"
+ left_delta="0"
+ name="Lower Fabric"
+ tool_tip="Click to choose a picture"
+ top_delta="80"
+ width="64" />
+ <color_swatch
+ border_color="0.45098 0.517647 0.607843 1"
+ can_apply_immediately="true"
+ follows="left|top"
+ height="80"
+ label="Color/Tint"
+ layout="topleft"
+ left_delta="0"
+ name="Color/Tint"
+ tool_tip="Click to open Color Picker"
+ top_delta="80"
+ width="64" />
+ <button
+ follows="left|top"
+ height="24"
+ label="Create New Jacket"
+ label_selected="Create New Jacket"
+ layout="topleft"
+ left_delta="0"
+ name="Create New"
+ top_delta="-121"
+ width="140" />
+ <button
+ follows="left|top"
+ height="20"
+ label="Take Off"
+ label_selected="Take Off"
+ layout="topleft"
+ left_delta="0"
+ name="Take Off"
+ top_pad="182"
+ width="82" />
+ <button
+ follows="right|bottom"
+ height="20"
+ label="Save"
+ label_selected="Save"
+ layout="topleft"
+ left="123"
+ name="Save"
+ top="458"
+ width="82" />
+ <button
+ follows="right|bottom"
+ height="20"
+ label="Save As..."
+ label_selected="Save As..."
+ layout="topleft"
+ left_pad="6"
+ name="Save As"
+ top_delta="0"
+ width="82" />
+ <button
+ follows="right|bottom"
+ height="20"
+ label="Revert"
+ label_selected="Revert"
+ layout="topleft"
+ left_pad="6"
+ name="Revert"
+ top_delta="0"
+ width="82" />
+ </panel>
+ <panel
+ border="true"
+ follows="left|top|right|bottom"
+ height="481"
+ label="Gloves"
+ layout="topleft"
+ left_delta="0"
+ name="Gloves"
+ top_delta="0"
+ width="389">
+ <icon
+ follows="top|right"
+ height="16"
+ image_name="icon_lock.tga"
+ layout="topleft"
+ left="333"
+ mouse_opaque="true"
+ name="square"
+ top="5"
+ width="16" />
+ <icon
+ height="16"
+ layout="topleft"
+ left_delta="-325"
+ mouse_opaque="true"
+ top_delta="3"
+ width="16" />
+ <text
+ type="string"
+ length="1"
+ follows="left|top|right"
+ font="SansSerif"
+ height="16"
+ layout="topleft"
+ left_pad="2"
+ name="title"
+ top_delta="0"
+ width="355">
+ [DESC]
+ </text>
+ <text
+ type="string"
+ length="1"
+ follows="left|top|right"
+ font="SansSerif"
+ height="16"
+ layout="topleft"
+ left_delta="0"
+ name="title_no_modify"
+ top_delta="0"
+ width="355">
+ [DESC]: cannot modify
+ </text>
+ <text
+ type="string"
+ length="1"
+ follows="left|top|right"
+ font="SansSerif"
+ height="16"
+ layout="topleft"
+ left_delta="0"
+ name="title_loading"
+ top_delta="0"
+ width="355">
+ [DESC]: loading...
+ </text>
+ <text
+ type="string"
+ length="1"
+ follows="left|top|right"
+ font="SansSerif"
+ height="16"
+ layout="topleft"
+ left_delta="0"
+ name="title_not_worn"
+ top_delta="0"
+ width="355">
+ [DESC]: not worn
+ </text>
+ <text
+ type="string"
+ length="1"
+ follows="left|top|right"
+ height="14"
+ layout="topleft"
+ left="8"
+ name="path"
+ top="24"
+ width="373">
+ Located in [PATH]
+ </text>
+ <spinner
+ decimal_digits="0"
+ follows="left|top|right"
+ height="16"
+ increment="1"
+ initial_value="0"
+ label="Item"
+ label_width="30"
+ layout="topleft"
+ left_delta="2"
+ max_val="5"
+ name="index"
+ text_enabled_color="110, 15, 15, 255"
+ top_pad="6"
+ width="87" />
+ <text
+ type="string"
+ length="1"
+ follows="left|top|right"
+ height="28"
+ layout="topleft"
+ left_delta="0"
+ name="not worn instructions"
+ top_pad="8"
+ width="373">
+ Put on a new gloves by dragging one from your inventory
+to your avatar. Alternately, you create a new one from
+scratch and wear it.
+ </text>
+ <text
+ type="string"
+ length="1"
+ follows="left|top|right"
+ height="28"
+ layout="topleft"
+ left_delta="0"
+ name="no modify instructions"
+ top_delta="0"
+ width="373">
+ You do not have permission to modify this wearable.
+ </text>
+ <text
+ type="string"
+ length="1"
+ bottom="486"
+ follows="left|top|right"
+ font="SansSerif"
+ halign="right"
+ height="28"
+ layout="topleft"
+ name="Item Action Label"
+ right="117"
+ width="100">
+ Gloves:
+ </text>
+ <texture_picker
+ can_apply_immediately="true"
+ default_image_name="Default"
+ follows="left|top"
+ height="80"
+ label="Fabric"
+ layout="topleft"
+ left="8"
+ name="Fabric"
+ tool_tip="Click to choose a picture"
+ top="65"
+ width="64" />
+ <color_swatch
+ border_color="0.45098 0.517647 0.607843 1"
+ can_apply_immediately="true"
+ follows="left|top"
+ height="80"
+ label="Color/Tint"
+ layout="topleft"
+ left_delta="0"
+ name="Color/Tint"
+ tool_tip="Click to open Color Picker"
+ top_delta="80"
+ width="64" />
+ <button
+ follows="left|top"
+ height="24"
+ label="Create New Gloves"
+ label_selected="Create New Gloves"
+ layout="topleft"
+ left_delta="0"
+ name="Create New"
+ top_delta="-41"
+ width="130" />
+ <button
+ follows="left|top"
+ height="20"
+ label="Take Off"
+ label_selected="Take Off"
+ layout="topleft"
+ left_delta="0"
+ name="Take Off"
+ top_pad="102"
+ width="82" />
+ <button
+ follows="right|bottom"
+ height="20"
+ label="Save"
+ label_selected="Save"
+ layout="topleft"
+ left="123"
+ name="Save"
+ top="458"
+ width="82" />
+ <button
+ follows="right|bottom"
+ height="20"
+ label="Save As..."
+ label_selected="Save As..."
+ layout="topleft"
+ left_pad="6"
+ name="Save As"
+ top_delta="0"
+ width="82" />
+ <button
+ follows="right|bottom"
+ height="20"
+ label="Revert"
+ label_selected="Revert"
+ layout="topleft"
+ left_pad="6"
+ name="Revert"
+ top_delta="0"
+ width="82" />
+ </panel>
+ <panel
+ border="true"
+ follows="left|top|right|bottom"
+ height="481"
+ label="Undershirt"
+ layout="topleft"
+ left_delta="0"
+ name="Undershirt"
+ top_delta="0"
+ width="389">
+ <icon
+ follows="top|right"
+ height="16"
+ image_name="icon_lock.tga"
+ layout="topleft"
+ left="333"
+ mouse_opaque="true"
+ name="square"
+ top="5"
+ width="16" />
+ <icon
+ height="16"
+ layout="topleft"
+ left_delta="-325"
+ mouse_opaque="true"
+ top_delta="3"
+ width="16" />
+ <text
+ type="string"
+ length="1"
+ follows="left|top|right"
+ font="SansSerif"
+ height="16"
+ layout="topleft"
+ left_pad="2"
+ name="title"
+ top_delta="0"
+ width="355">
+ [DESC]
+ </text>
+ <text
+ type="string"
+ length="1"
+ follows="left|top|right"
+ font="SansSerif"
+ height="16"
+ layout="topleft"
+ left_delta="0"
+ name="title_no_modify"
+ top_delta="0"
+ width="355">
+ [DESC]: cannot modify
+ </text>
+ <text
+ type="string"
+ length="1"
+ follows="left|top|right"
+ font="SansSerif"
+ height="16"
+ layout="topleft"
+ left_delta="0"
+ name="title_loading"
+ top_delta="0"
+ width="355">
+ [DESC]: loading...
+ </text>
+ <text
+ type="string"
+ length="1"
+ follows="left|top|right"
+ font="SansSerif"
+ height="16"
+ layout="topleft"
+ left_delta="0"
+ name="title_not_worn"
+ top_delta="0"
+ width="355">
+ [DESC]: not worn
+ </text>
+ <text
+ type="string"
+ length="1"
+ follows="left|top|right"
+ height="14"
+ layout="topleft"
+ left="8"
+ name="path"
+ top="24"
+ width="373">
+ Located in [PATH]
+ </text>
+ <spinner
+ decimal_digits="0"
+ follows="left|top|right"
+ height="16"
+ increment="1"
+ initial_value="0"
+ label="Item"
+ label_width="30"
+ layout="topleft"
+ left_delta="2"
+ max_val="5"
+ name="index"
+ text_enabled_color="110, 15, 15, 255"
+ top_pad="6"
+ width="87" />
+ <text
+ type="string"
+ length="1"
+ follows="left|top|right"
+ height="28"
+ layout="topleft"
+ left_delta="0"
+ name="not worn instructions"
+ top_pad="8"
+ width="373">
+ Put on a new undershirt by dragging one from your inventory
+to your avatar. Alternately, you create a new one from
+scratch and wear it.
+ </text>
+ <text
+ type="string"
+ length="1"
+ follows="left|top|right"
+ height="28"
+ layout="topleft"
+ left_delta="0"
+ name="no modify instructions"
+ top_delta="0"
+ width="373">
+ You do not have permission to modify this wearable.
+ </text>
+ <text
+ type="string"
+ length="1"
+ bottom="486"
+ follows="left|top|right"
+ font="SansSerif"
+ halign="right"
+ height="28"
+ layout="topleft"
+ name="Item Action Label"
+ right="117"
+ width="100">
+ Undershirt:
+ </text>
+ <texture_picker
+ can_apply_immediately="true"
+ default_image_name="Default"
+ follows="left|top"
+ height="80"
+ label="Fabric"
+ layout="topleft"
+ left="8"
+ name="Fabric"
+ tool_tip="Click to choose a picture"
+ top="65"
+ width="64" />
+ <color_swatch
+ border_color="0.45098 0.517647 0.607843 1"
+ can_apply_immediately="true"
+ follows="left|top"
+ height="80"
+ label="Color/Tint"
+ layout="topleft"
+ left_delta="0"
+ name="Color/Tint"
+ tool_tip="Click to open Color Picker"
+ top_delta="80"
+ width="64" />
+ <button
+ follows="left|top"
+ height="24"
+ label="Create New Undershirt"
+ label_selected="Create New Undershirt"
+ layout="topleft"
+ left_delta="0"
+ name="Create New"
+ top_delta="-41"
+ width="160" />
+ <button
+ follows="left|top"
+ height="20"
+ label="Take Off"
+ label_selected="Take Off"
+ layout="topleft"
+ left_delta="0"
+ name="Take Off"
+ top_pad="102"
+ width="82" />
+ <button
+ follows="right|bottom"
+ height="20"
+ label="Save"
+ label_selected="Save"
+ layout="topleft"
+ left="123"
+ name="Save"
+ top="458"
+ width="82" />
+ <button
+ follows="right|bottom"
+ height="20"
+ label="Save As..."
+ label_selected="Save As..."
+ layout="topleft"
+ left_pad="6"
+ name="Save As"
+ top_delta="0"
+ width="82" />
+ <button
+ follows="right|bottom"
+ height="20"
+ label="Revert"
+ label_selected="Revert"
+ layout="topleft"
+ left_pad="6"
+ name="Revert"
+ top_delta="0"
+ width="82" />
+ </panel>
+ <panel
+ border="true"
+ follows="left|top|right|bottom"
+ height="481"
+ label="Underpants"
+ layout="topleft"
+ left_delta="0"
+ name="Underpants"
+ top_delta="0"
+ width="389">
+ <icon
+ follows="top|right"
+ height="16"
+ image_name="icon_lock.tga"
+ layout="topleft"
+ left="333"
+ mouse_opaque="true"
+ name="square"
+ top="5"
+ width="16" />
+ <icon
+ height="16"
+ layout="topleft"
+ left_delta="-325"
+ mouse_opaque="true"
+ top_delta="3"
+ width="16" />
+ <text
+ type="string"
+ length="1"
+ follows="left|top|right"
+ font="SansSerif"
+ height="16"
+ layout="topleft"
+ left_pad="2"
+ name="title"
+ top_delta="0"
+ width="355">
+ [DESC]
+ </text>
+ <text
+ type="string"
+ length="1"
+ follows="left|top|right"
+ font="SansSerif"
+ height="16"
+ layout="topleft"
+ left_delta="0"
+ name="title_no_modify"
+ top_delta="0"
+ width="355">
+ [DESC]: cannot modify
+ </text>
+ <text
+ type="string"
+ length="1"
+ follows="left|top|right"
+ font="SansSerif"
+ height="16"
+ layout="topleft"
+ left_delta="0"
+ name="title_loading"
+ top_delta="0"
+ width="355">
+ [DESC]: loading...
+ </text>
+ <text
+ type="string"
+ length="1"
+ follows="left|top|right"
+ font="SansSerif"
+ height="16"
+ layout="topleft"
+ left_delta="0"
+ name="title_not_worn"
+ top_delta="0"
+ width="355">
+ [DESC]: not worn
+ </text>
+ <text
+ type="string"
+ length="1"
+ follows="left|top|right"
+ height="14"
+ layout="topleft"
+ left="8"
+ name="path"
+ top="24"
+ width="373">
+ Located in [PATH]
+ </text>
+ <spinner
+ decimal_digits="0"
+ follows="left|top|right"
+ height="16"
+ increment="1"
+ initial_value="0"
+ label="Item"
+ label_width="30"
+ layout="topleft"
+ left_delta="2"
+ max_val="5"
+ name="index"
+ text_enabled_color="110, 15, 15, 255"
+ top_pad="6"
+ width="87" />
+ <text
+ type="string"
+ length="1"
+ follows="left|top|right"
+ height="28"
+ layout="topleft"
+ left_delta="0"
+ name="not worn instructions"
+ top_pad="8"
+ width="373">
+ Put on a new underpants by dragging one from your inventory
+to your avatar. Alternately, you create a new one from
+scratch and wear it.
+ </text>
+ <text
+ type="string"
+ length="1"
+ follows="left|top|right"
+ height="28"
+ layout="topleft"
+ left_delta="0"
+ name="no modify instructions"
+ top_delta="0"
+ width="373">
+ You do not have permission to modify this wearable.
+ </text>
+ <text
+ type="string"
+ length="1"
+ bottom="486"
+ follows="left|top|right"
+ font="SansSerif"
+ halign="right"
+ height="28"
+ layout="topleft"
+ name="Item Action Label"
+ right="117"
+ width="100">
+ Underpants:
+ </text>
+ <texture_picker
+ can_apply_immediately="true"
+ default_image_name="Default"
+ follows="left|top"
+ height="80"
+ label="Fabric"
+ layout="topleft"
+ left="8"
+ name="Fabric"
+ tool_tip="Click to choose a picture"
+ top="65"
+ width="64" />
+ <color_swatch
+ border_color="0.45098 0.517647 0.607843 1"
+ can_apply_immediately="true"
+ follows="left|top"
+ height="80"
+ label="Color/Tint"
+ layout="topleft"
+ left_delta="0"
+ name="Color/Tint"
+ tool_tip="Click to open Color Picker"
+ top_delta="80"
+ width="64" />
+ <button
+ follows="left|top"
+ height="24"
+ label="Create New Underpants"
+ label_selected="Create New Underpants"
+ layout="topleft"
+ left_delta="0"
+ name="Create New"
+ top_delta="-41"
+ width="160" />
+ <button
+ follows="left|top"
+ height="20"
+ label="Take Off"
+ label_selected="Take Off"
+ layout="topleft"
+ left_delta="0"
+ name="Take Off"
+ top_pad="102"
+ width="82" />
+ <button
+ follows="right|bottom"
+ height="20"
+ label="Save"
+ label_selected="Save"
+ layout="topleft"
+ left="123"
+ name="Save"
+ top="458"
+ width="82" />
+ <button
+ follows="right|bottom"
+ height="20"
+ label="Save As..."
+ label_selected="Save As..."
+ layout="topleft"
+ left_pad="6"
+ name="Save As"
+ top_delta="0"
+ width="82" />
+ <button
+ follows="right|bottom"
+ height="20"
+ label="Revert"
+ label_selected="Revert"
+ layout="topleft"
+ left_pad="6"
+ name="Revert"
+ top_delta="0"
+ width="82" />
+ </panel>
+ <panel
+ border="true"
+ follows="left|top|right|bottom"
+ height="481"
+ label="Skirt"
+ layout="topleft"
+ left_delta="0"
+ name="Skirt"
+ top_delta="0"
+ width="389">
+ <icon
+ follows="top|right"
+ height="16"
+ image_name="icon_lock.tga"
+ layout="topleft"
+ left="333"
+ mouse_opaque="true"
+ name="square"
+ top="5"
+ width="16" />
+ <icon
+ height="16"
+ layout="topleft"
+ left_delta="-325"
+ mouse_opaque="true"
+ top_delta="3"
+ width="16" />
+ <text
+ type="string"
+ length="1"
+ follows="left|top|right"
+ font="SansSerif"
+ height="16"
+ layout="topleft"
+ left_pad="2"
+ name="title"
+ top_delta="0"
+ width="355">
+ [DESC]
+ </text>
+ <text
+ type="string"
+ length="1"
+ follows="left|top|right"
+ font="SansSerif"
+ height="16"
+ layout="topleft"
+ left_delta="0"
+ name="title_no_modify"
+ top_delta="0"
+ width="355">
+ [DESC]: cannot modify
+ </text>
+ <text
+ type="string"
+ length="1"
+ follows="left|top|right"
+ font="SansSerif"
+ height="16"
+ layout="topleft"
+ left_delta="0"
+ name="title_loading"
+ top_delta="0"
+ width="355">
+ [DESC]: loading...
+ </text>
+ <text
+ type="string"
+ length="1"
+ follows="left|top|right"
+ font="SansSerif"
+ height="16"
+ layout="topleft"
+ left_delta="0"
+ name="title_not_worn"
+ top_delta="0"
+ width="355">
+ [DESC]: not worn
+ </text>
+ <text
+ type="string"
+ length="1"
+ follows="left|top|right"
+ height="14"
+ layout="topleft"
+ left="8"
+ name="path"
+ top="24"
+ width="373">
+ Located in [PATH]
+ </text>
+ <spinner
+ decimal_digits="0"
+ follows="left|top|right"
+ height="16"
+ increment="1"
+ initial_value="0"
+ label="Item"
+ label_width="30"
+ layout="topleft"
+ left_delta="2"
+ max_val="5"
+ name="index"
+ text_enabled_color="110, 15, 15, 255"
+ top_pad="6"
+ width="87" />
+ <text
+ type="string"
+ length="1"
+ follows="left|top|right"
+ height="28"
+ layout="topleft"
+ left_delta="0"
+ name="not worn instructions"
+ top_pad="8"
+ width="373">
+ Put on a new skirt by dragging one from your inventory
+to your avatar. Alternately, you create a new one from
+scratch and wear it.
+ </text>
+ <text
+ type="string"
+ length="1"
+ follows="left|top|right"
+ height="28"
+ layout="topleft"
+ left_delta="0"
+ name="no modify instructions"
+ top_delta="0"
+ width="373">
+ You do not have permission to modify this wearable.
+ </text>
+ <text
+ type="string"
+ length="1"
+ bottom="486"
+ follows="left|top|right"
+ font="SansSerif"
+ halign="right"
+ height="28"
+ layout="topleft"
+ name="Item Action Label"
+ right="117"
+ width="100">
+ Skirt:
+ </text>
+ <texture_picker
+ can_apply_immediately="true"
+ default_image_name="Default"
+ follows="left|top"
+ height="80"
+ label="Fabric"
+ layout="topleft"
+ left="8"
+ name="Fabric"
+ tool_tip="Click to choose a picture"
+ top="65"
+ width="64" />
+ <color_swatch
+ border_color="0.45098 0.517647 0.607843 1"
+ can_apply_immediately="true"
+ follows="left|top"
+ height="80"
+ label="Color/Tint"
+ layout="topleft"
+ left_delta="0"
+ name="Color/Tint"
+ tool_tip="Click to open Color Picker"
+ top_delta="80"
+ width="64" />
+ <button
+ follows="left|top"
+ height="24"
+ label="Create New Skirt"
+ label_selected="Create New Skirt"
+ layout="topleft"
+ left_delta="0"
+ name="Create New"
+ top_delta="-41"
+ width="120" />
+ <button
+ follows="left|top"
+ height="20"
+ label="Take Off"
+ label_selected="Take Off"
+ layout="topleft"
+ left_delta="0"
+ name="Take Off"
+ top_pad="102"
+ width="82" />
+ <button
+ follows="right|bottom"
+ height="20"
+ label="Save"
+ label_selected="Save"
+ layout="topleft"
+ left="123"
+ name="Save"
+ top="458"
+ width="82" />
+ <button
+ follows="right|bottom"
+ height="20"
+ label="Save As..."
+ label_selected="Save As..."
+ layout="topleft"
+ left_pad="6"
+ name="Save As"
+ top_delta="0"
+ width="82" />
+ <button
+ follows="right|bottom"
+ height="20"
+ label="Revert"
+ label_selected="Revert"
+ layout="topleft"
+ left_pad="6"
+ name="Revert"
+ top_delta="0"
+ width="82" />
+ </panel>
+ <panel
+ border="true"
+ follows="left|top|right|bottom"
+ height="481"
+ label="Alpha"
+ layout="topleft"
+ left_delta="0"
+ name="Alpha"
+ top_delta="0"
+ width="389">
+ <icon
+ follows="top|right"
+ height="16"
+ image_name="icon_lock.tga"
+ layout="topleft"
+ left="333"
+ mouse_opaque="true"
+ name="square"
+ top="5"
+ width="16" />
+ <icon
+ height="16"
+ layout="topleft"
+ left_delta="-325"
+ mouse_opaque="true"
+ top_delta="3"
+ width="16" />
+ <text
+ type="string"
+ length="1"
+ follows="left|top|right"
+ font="SansSerif"
+ height="16"
+ layout="topleft"
+ left_pad="2"
+ name="title"
+ top_delta="0"
+ width="355">
+ [DESC]
+ </text>
+ <text
+ type="string"
+ length="1"
+ follows="left|top|right"
+ font="SansSerif"
+ height="16"
+ layout="topleft"
+ left_delta="0"
+ name="title_no_modify"
+ top_delta="0"
+ width="355">
+ [DESC]: cannot modify
+ </text>
+ <text
+ type="string"
+ length="1"
+ follows="left|top|right"
+ font="SansSerif"
+ height="16"
+ layout="topleft"
+ left_delta="0"
+ name="title_loading"
+ top_delta="0"
+ width="355">
+ [DESC]: loading...
+ </text>
+ <text
+ type="string"
+ length="1"
+ follows="left|top|right"
+ font="SansSerif"
+ height="16"
+ layout="topleft"
+ left_delta="0"
+ name="title_not_worn"
+ top_delta="0"
+ width="355">
+ [DESC]: not worn
+ </text>
+ <text
+ type="string"
+ length="1"
+ follows="left|top|right"
+ height="14"
+ layout="topleft"
+ left="8"
+ name="path"
+ top="24"
+ width="373">
+ Located in [PATH]
+ </text>
+ <spinner
+ decimal_digits="0"
+ follows="left|top|right"
+ height="16"
+ increment="1"
+ initial_value="0"
+ label="Item"
+ label_width="30"
+ layout="topleft"
+ left_delta="2"
+ max_val="5"
+ name="index"
+ text_enabled_color="110, 15, 15, 255"
+ top_pad="6"
+ width="87" />
+ <text
+ type="string"
+ length="1"
+ follows="left|top|right"
+ height="28"
+ layout="topleft"
+ left_delta="-2"
+ name="not worn instructions"
+ top_delta="2"
+ width="373">
+ Put on a new alpha mask by dragging one from your inventory
+to your avatar. Alternately, you create a new one from
+scratch and wear it.
+ </text>
+ <text
+ type="string"
+ length="1"
+ follows="left|top|right"
+ height="28"
+ layout="topleft"
+ left_delta="0"
+ name="no modify instructions"
+ top_delta="0"
+ width="373">
+ You do not have permission to modify this wearable.
+ </text>
+ <text
+ type="string"
+ length="1"
+ bottom="486"
+ follows="left|top|right"
+ font="SansSerif"
+ halign="right"
+ height="28"
+ layout="topleft"
+ name="Item Action Label"
+ right="119"
+ width="100">
+ Alpha:
+ </text>
+ <texture_picker
+ can_apply_immediately="true"
+ default_image_name="Default"
+ follows="left|top"
+ height="80"
+ label="Lower Alpha"
+ layout="topleft"
+ left="8"
+ name="Lower Alpha"
+ tool_tip="Click to choose a picture"
+ top="65"
+ width="64" />
+ <check_box
+ control_name="LowerAlphaTextureInvisible"
+ follows="left"
+ height="16"
+ layout="topleft"
+ left_pad="6"
+ name="lower alpha texture invisible"
+ top_delta="4"
+ width="16" />
+ <texture_picker
+ can_apply_immediately="true"
+ default_image_name="Default"
+ follows="left|top"
+ height="80"
+ label="Upper Alpha"
+ layout="topleft"
+ left="8"
+ name="Upper Alpha"
+ tool_tip="Click to choose a picture"
+ top="145"
+ width="64" />
+ <check_box
+ control_name="UpperAlphaTextureInvisible"
+ follows="left"
+ height="16"
+ layout="topleft"
+ left_pad="6"
+ name="upper alpha texture invisible"
+ top_delta="4"
+ width="16" />
+ <texture_picker
+ can_apply_immediately="true"
+ default_image_name="Default"
+ follows="left|top"
+ height="80"
+ label="Head Alpha"
+ layout="topleft"
+ left="8"
+ name="Head Alpha"
+ tool_tip="Click to choose a picture"
+ top="225"
+ width="64" />
+ <check_box
+ control_name="HeadAlphaTextureInvisible"
+ follows="left"
+ height="16"
+ layout="topleft"
+ left_pad="6"
+ name="head alpha texture invisible"
+ top_delta="4"
+ width="16" />
+ <texture_picker
+ can_apply_immediately="true"
+ default_image_name="Default"
+ follows="left|top"
+ height="80"
+ label="Eye Alpha"
+ layout="topleft"
+ left="8"
+ name="Eye Alpha"
+ tool_tip="Click to choose a picture"
+ top="305"
+ width="64" />
+ <check_box
+ control_name="Eye AlphaTextureInvisible"
+ follows="left"
+ height="16"
+ layout="topleft"
+ left_pad="6"
+ name="eye alpha texture invisible"
+ top_delta="4"
+ width="16" />
+ <texture_picker
+ can_apply_immediately="true"
+ default_image_name="Default"
+ follows="left|top"
+ height="80"
+ label="Hair Alpha"
+ layout="topleft"
+ left="8"
+ name="Hair Alpha"
+ tool_tip="Click to choose a picture"
+ top="385"
+ width="64" />
+ <check_box
+ control_name="HairAlphaTextureInvisible"
+ follows="left"
+ height="16"
+ layout="topleft"
+ left_pad="6"
+ name="hair alpha texture invisible"
+ top_delta="4"
+ width="16" />
+ <button
+ follows="left|top"
+ height="24"
+ label="Create New Alpha"
+ label_selected="Create New Alpha"
+ layout="topleft"
+ left="8"
+ name="Create New"
+ top="104"
+ width="120" />
+ <button
+ follows="left|top"
+ height="20"
+ label="Take Off"
+ label_selected="Take Off"
+ layout="topleft"
+ left_delta="-4"
+ name="Take Off"
+ top_pad="332"
+ width="82" />
+ <button
+ follows="right|bottom"
+ height="20"
+ label="Save"
+ label_selected="Save"
+ layout="topleft"
+ left_pad="37"
+ name="Save"
+ top_delta="-2"
+ width="82" />
+ <button
+ follows="right|bottom"
+ height="20"
+ label="Save As..."
+ label_selected="Save As..."
+ layout="topleft"
+ left_pad="6"
+ name="Save As"
+ top_delta="0"
+ width="82" />
+ <button
+ follows="right|bottom"
+ height="20"
+ label="Revert"
+ label_selected="Revert"
+ layout="topleft"
+ left_pad="6"
+ name="Revert"
+ top_delta="0"
+ width="82" />
+ </panel>
+ <panel
+ border="true"
+ follows="left|top|right|bottom"
+ height="481"
+ label="Tattoo"
+ layout="topleft"
+ left_delta="0"
+ name="Tattoo"
+ top_delta="0"
+ width="389">
+ <icon
+ follows="top|right"
+ height="16"
+ image_name="icon_lock.tga"
+ layout="topleft"
+ left="333"
+ mouse_opaque="true"
+ name="square"
+ top="5"
+ width="16" />
+ <icon
+ height="16"
+ layout="topleft"
+ left_delta="-325"
+ mouse_opaque="true"
+ top_delta="3"
+ width="16" />
+ <text
+ type="string"
+ length="1"
+ follows="left|top|right"
+ font="SansSerif"
+ height="16"
+ layout="topleft"
+ left_pad="2"
+ name="title"
+ top_delta="0"
+ width="355">
+ [DESC]
+ </text>
+ <text
+ type="string"
+ length="1"
+ follows="left|top|right"
+ font="SansSerif"
+ height="16"
+ layout="topleft"
+ left_delta="0"
+ name="title_no_modify"
+ top_delta="0"
+ width="355">
+ [DESC]: cannot modify
+ </text>
+ <text
+ type="string"
+ length="1"
+ follows="left|top|right"
+ font="SansSerif"
+ height="16"
+ layout="topleft"
+ left_delta="0"
+ name="title_loading"
+ top_delta="0"
+ width="355">
+ [DESC]: loading...
+ </text>
+ <text
+ type="string"
+ length="1"
+ follows="left|top|right"
+ font="SansSerif"
+ height="16"
+ layout="topleft"
+ left_delta="0"
+ name="title_not_worn"
+ top_delta="0"
+ width="355">
+ [DESC]: not worn
+ </text>
+ <text
+ type="string"
+ length="1"
+ follows="left|top|right"
+ height="14"
+ layout="topleft"
+ left="8"
+ name="path"
+ top="24"
+ width="373">
+ Located in [PATH]
+ </text>
+ <spinner
+ decimal_digits="0"
+ follows="left|top|right"
+ height="16"
+ increment="1"
+ initial_value="0"
+ label="Item"
+ label_width="30"
+ layout="topleft"
+ left_delta="2"
+ max_val="5"
+ name="index"
+ text_enabled_color="110, 15, 15, 255"
+ top_pad="6"
+ width="87" />
+ <text
+ type="string"
+ length="1"
+ follows="left|top|right"
+ height="28"
+ layout="topleft"
+ left_delta="-2"
+ name="not worn instructions"
+ top_delta="2"
+ width="373">
+ Put on a new tattoo by dragging one from your inventory
+to your avatar. Alternately, you create a new one from
+scratch and wear it.
+ </text>
+ <text
+ type="string"
+ length="1"
+ follows="left|top|right"
+ height="28"
+ layout="topleft"
+ left_delta="0"
+ name="no modify instructions"
+ top_delta="0"
+ width="373">
+ You do not have permission to modify this wearable.
+ </text>
+ <text
+ type="string"
+ length="1"
+ bottom="486"
+ follows="left|top|right"
+ font="SansSerif"
+ halign="right"
+ height="28"
+ layout="topleft"
+ name="Item Action Label"
+ right="119"
+ width="100">
+ Tattoo:
+ </text>
+ <texture_picker
+ can_apply_immediately="true"
+ default_image_name="Default"
+ follows="left|top"
+ height="80"
+ label="Head Tattoo"
+ layout="topleft"
+ left="8"
+ name="Head Tattoo"
+ tool_tip="Click to choose a picture"
+ top="65"
+ width="64" />
+ <texture_picker
+ can_apply_immediately="true"
+ default_image_name="Default"
+ follows="left|top"
+ height="80"
+ label="Upper Tattoo"
+ layout="topleft"
+ left_delta="0"
+ name="Upper Tattoo"
+ tool_tip="Click to choose a picture"
+ top_delta="80"
+ width="64" />
+ <texture_picker
+ can_apply_immediately="true"
+ default_image_name="Default"
+ follows="left|top"
+ height="80"
+ label="Lower Tattoo"
+ layout="topleft"
+ left_delta="0"
+ name="Lower Tattoo"
+ tool_tip="Click to choose a picture"
+ top_delta="80"
+ width="64" />
+ <button
+ follows="left|top"
+ height="24"
+ label="Create New Tattoo"
+ label_selected="Create New Tattoo"
+ layout="topleft"
+ left_delta="0"
+ name="Create New"
+ top_delta="-121"
+ width="120" />
+ <button
+ follows="left|top"
+ height="20"
+ label="Take Off"
+ label_selected="Take Off"
+ layout="topleft"
+ left_delta="-4"
+ name="Take Off"
+ top_pad="332"
+ width="82" />
+ <button
+ follows="right|bottom"
+ height="20"
+ label="Save"
+ label_selected="Save"
+ layout="topleft"
+ left_pad="37"
+ name="Save"
+ top_delta="-2"
+ width="82" />
+ <button
+ follows="right|bottom"
+ height="20"
+ label="Save As..."
+ label_selected="Save As..."
+ layout="topleft"
+ left_pad="6"
+ name="Save As"
+ top_delta="0"
+ width="82" />
+ <button
+ follows="right|bottom"
+ height="20"
+ label="Revert"
+ label_selected="Revert"
+ layout="topleft"
+ left_pad="6"
+ name="Revert"
+ top_delta="0"
+ width="82" />
+ </panel>
+ </tab_container>
+ <scroll_container
+ follows="left|top|right|bottom"
+ height="382"
+ layout="topleft"
+ left="197"
+ mouse_opaque="false"
+ name="panel_container"
+ top="94"
+ width="292">
+ <scrolling_panel_list
+ follows="left|bottom"
+ layout="topleft"
+ name="panel_list" />
+ </scroll_container>
+ <button
+ bottom="536"
+ follows="right|bottom"
+ height="20"
+ label="Cancel"
+ label_selected="Cancel"
+ layout="topleft"
+ name="Cancel"
+ right="-10"
+ width="100" />
+ <button
+ bottom="536"
+ follows="right|bottom"
+ height="20"
+ label="OK"
+ label_selected="OK"
+ layout="topleft"
+ name="Ok"
+ right="-116"
+ width="100" />
+</floater>
diff --git a/indra/newview/skins/default/xui/en/floater_day_cycle_options.xml b/indra/newview/skins/default/xui/en/floater_day_cycle_options.xml
new file mode 100644
index 0000000000..9ca7172f81
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/floater_day_cycle_options.xml
@@ -0,0 +1,613 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<floater
+ height="275"
+ layout="topleft"
+ name="Day Cycle Floater"
+ save_rect="true"
+ title="Day Cycle Editor"
+ width="646">
+ <tab_container
+ follows="left|top"
+ height="255"
+ layout="topleft"
+ left="0"
+ name="Day Cycle Tabs"
+ tab_position="top"
+ top="20"
+ width="644">
+ <panel
+ border="true"
+ follows="left|top|right|bottom"
+ height="255"
+ label="Day Cycle"
+ layout="topleft"
+ left="1"
+ mouse_opaque="false"
+ name="Day Cycle"
+ top="0"
+ width="642">
+ <button
+ follows="left|top"
+ font="SansSerifSmall"
+ height="15"
+ label="?"
+ layout="topleft"
+ left="612"
+ name="WLDayCycleHelp"
+ top="3"
+ width="18" />
+ <multi_slider
+ can_edit_text="true"
+ control_name="WLTimeSlider"
+ decimal_digits="0"
+ draw_track="false"
+ follows="bottom"
+ height="10"
+ increment="0.0833333"
+ initial_value="0"
+ layout="topleft"
+ left="20"
+ max_sliders="20"
+ max_val="24"
+ name="WLTimeSlider"
+ show_text="false"
+ top="25"
+ use_triangle="true"
+ width="525" />
+ <multi_slider
+ can_edit_text="true"
+ control_name="WLDayCycleKeys"
+ decimal_digits="0"
+ follows="bottom"
+ height="10"
+ increment="0.0833333"
+ initial_value="0"
+ layout="topleft"
+ left_delta="0"
+ max_sliders="20"
+ max_val="24"
+ name="WLDayCycleKeys"
+ show_text="false"
+ top_pad="15"
+ width="525" />
+ <text
+ type="string"
+ length="1"
+ bg_visible="true"
+ border_visible="true"
+ control_name="WL12am"
+ follows="left|top|right"
+ height="6"
+ layout="topleft"
+ left="8"
+ name="WL12am"
+ top="74"
+ width="55">
+ 12am
+ </text>
+ <text
+ type="string"
+ length="1"
+ bg_visible="true"
+ border_visible="true"
+ control_name="WL3am"
+ follows="left|top|right"
+ height="6"
+ layout="topleft"
+ left_pad="10"
+ name="WL3am"
+ top_delta="0"
+ width="55">
+ 3am
+ </text>
+ <text
+ type="string"
+ length="1"
+ bg_visible="true"
+ border_visible="true"
+ control_name="WL6am"
+ follows="left|top|right"
+ height="6"
+ layout="topleft"
+ left_pad="10"
+ name="WL6am"
+ top_delta="0"
+ width="55">
+ 6am
+ </text>
+ <text
+ type="string"
+ length="1"
+ bg_visible="true"
+ border_visible="true"
+ control_name="WL9am"
+ follows="left|top|right"
+ height="6"
+ layout="topleft"
+ left_pad="10"
+ name="WL9amHash"
+ top_delta="0"
+ width="55">
+ 9am
+ </text>
+ <text
+ type="string"
+ length="1"
+ bg_visible="true"
+ border_visible="true"
+ control_name="WL12pm"
+ follows="left|top|right"
+ height="6"
+ layout="topleft"
+ left_pad="10"
+ name="WL12pmHash"
+ top_delta="0"
+ width="55">
+ 12pm
+ </text>
+ <text
+ type="string"
+ length="1"
+ bg_visible="true"
+ border_visible="true"
+ control_name="WL3pm"
+ follows="left|top|right"
+ height="6"
+ layout="topleft"
+ left_pad="10"
+ name="WL3pm"
+ top_delta="0"
+ width="55">
+ 3pm
+ </text>
+ <text
+ type="string"
+ length="1"
+ bg_visible="true"
+ border_visible="true"
+ control_name="WL6pm"
+ follows="left|top|right"
+ height="6"
+ layout="topleft"
+ left_pad="10"
+ name="WL6pm"
+ top_delta="0"
+ width="55">
+ 6pm
+ </text>
+ <text
+ type="string"
+ length="1"
+ bg_visible="true"
+ border_visible="true"
+ control_name="WL9pm"
+ follows="left|top|right"
+ height="6"
+ layout="topleft"
+ left_pad="10"
+ name="WL9pm"
+ top_delta="0"
+ width="55">
+ 9pm
+ </text>
+ <text
+ type="string"
+ length="1"
+ bg_visible="true"
+ border_visible="true"
+ control_name="WL12am2"
+ follows="left|top|right"
+ height="6"
+ layout="topleft"
+ left_pad="10"
+ name="WL12am2"
+ top_delta="0"
+ width="55">
+ 12am
+ </text>
+ <text
+ type="string"
+ length="1"
+ bg_visible="true"
+ border_visible="true"
+ control_name="WL12amHash"
+ follows="left|top|right"
+ font="SansSerif"
+ height="14"
+ layout="topleft"
+ left="20"
+ name="WL12amHash"
+ top="54"
+ width="4">
+ |
+ </text>
+ <text
+ type="string"
+ length="1"
+ bg_visible="true"
+ border_visible="true"
+ control_name="WL3amHash"
+ follows="left|top|right"
+ font="SansSerif"
+ height="11"
+ layout="topleft"
+ left_pad="61"
+ name="WL3amHash"
+ top_delta="3"
+ width="4">
+ I
+ </text>
+ <text
+ type="string"
+ length="1"
+ bg_visible="true"
+ border_visible="true"
+ control_name="WL6amHash"
+ follows="left|top|right"
+ font="SansSerif"
+ height="14"
+ layout="topleft"
+ left_pad="61"
+ name="WL6amHash"
+ top_delta="-3"
+ width="4">
+ |
+ </text>
+ <text
+ type="string"
+ length="1"
+ bg_visible="true"
+ border_visible="true"
+ control_name="WL9amHash"
+ follows="left|top|right"
+ font="SansSerif"
+ height="11"
+ layout="topleft"
+ left_pad="61"
+ name="WL9amHash2"
+ top_delta="3"
+ width="4">
+ I
+ </text>
+ <text
+ type="string"
+ length="1"
+ bg_visible="true"
+ border_visible="true"
+ control_name="WL12pmHash"
+ follows="left|top|right"
+ font="SansSerif"
+ height="14"
+ layout="topleft"
+ left_pad="61"
+ name="WL12pmHash2"
+ top_delta="-3"
+ width="4">
+ |
+ </text>
+ <text
+ type="string"
+ length="1"
+ bg_visible="true"
+ border_visible="true"
+ control_name="WL3pmHash"
+ follows="left|top|right"
+ font="SansSerif"
+ height="11"
+ layout="topleft"
+ left_pad="61"
+ name="WL3pmHash"
+ top_delta="3"
+ width="4">
+ I
+ </text>
+ <text
+ type="string"
+ length="1"
+ bg_visible="true"
+ border_visible="true"
+ control_name="WL6pmHash"
+ follows="left|top|right"
+ font="SansSerif"
+ height="14"
+ layout="topleft"
+ left_pad="61"
+ name="WL6pmHash"
+ top_delta="-3"
+ width="4">
+ |
+ </text>
+ <text
+ type="string"
+ length="1"
+ bg_visible="true"
+ border_visible="true"
+ control_name="WL9pmHash"
+ follows="left|top|right"
+ font="SansSerif"
+ height="11"
+ layout="topleft"
+ left_pad="61"
+ name="WL9pmHash"
+ top_delta="3"
+ width="4">
+ I
+ </text>
+ <text
+ type="string"
+ length="1"
+ bg_visible="true"
+ border_visible="true"
+ control_name="WL12amHash2"
+ follows="left|top|right"
+ font="SansSerif"
+ height="14"
+ layout="topleft"
+ left_pad="61"
+ name="WL12amHash2"
+ top_delta="-3"
+ width="4">
+ |
+ </text>
+ <button
+ height="20"
+ label="Add Key"
+ label_selected="Add Key"
+ layout="topleft"
+ left="550"
+ name="WLAddKey"
+ top="20"
+ width="80" />
+ <button
+ height="20"
+ label="Delete Key"
+ label_selected="Delete Key"
+ layout="topleft"
+ left_delta="0"
+ name="WLDeleteKey"
+ top_pad="5"
+ width="80" />
+ <text
+ type="string"
+ length="1"
+ bg_visible="true"
+ border_visible="true"
+ control_name="DayCycleText"
+ follows="left|top|right"
+ font="SansSerif"
+ height="16"
+ layout="topleft"
+ left="20"
+ name="WLCurKeyFrameText"
+ top="104"
+ width="150">
+ Key Frame Settings:
+ </text>
+ <text
+ type="string"
+ length="1"
+ bg_visible="true"
+ border_visible="true"
+ control_name="DayCycleText"
+ follows="left|top|right"
+ font="SansSerif"
+ height="16"
+ layout="topleft"
+ left="30"
+ name="WLCurKeyTimeText"
+ top="124"
+ width="100">
+ Key Time:
+ </text>
+ <spinner
+ control_name="WLCurKeyHour"
+ decimal_digits="0"
+ follows="left|top"
+ height="16"
+ increment="1"
+ initial_value="0"
+ label="Hour"
+ label_width="30"
+ layout="topleft"
+ left_delta="0"
+ max_val="100"
+ name="WLCurKeyHour"
+ top_pad="4"
+ width="70" />
+ <spinner
+ control_name="WLCurKeyMin"
+ decimal_digits="0"
+ follows="left|top"
+ height="16"
+ increment="5"
+ initial_value="0"
+ label="Min"
+ label_width="20"
+ layout="topleft"
+ left_pad="5"
+ max_val="55"
+ name="WLCurKeyMin"
+ top_delta="0"
+ width="60" />
+ <text
+ type="string"
+ length="1"
+ bg_visible="true"
+ border_visible="true"
+ control_name="WLCurKeyTimeText"
+ follows="left|top|right"
+ font="SansSerif"
+ height="16"
+ layout="topleft"
+ left="30"
+ name="WLCurKeyTimeText2"
+ top="169"
+ width="120">
+ Key Preset:
+ </text>
+ <combo_box
+ height="18"
+ label="Preset"
+ layout="topleft"
+ left_delta="0"
+ name="WLKeyPresets"
+ top_pad="7"
+ width="155" />
+ <view_border
+ bevel_style="none"
+ follows="top|left"
+ height="115"
+ layout="topleft"
+ left="12"
+ top="101"
+ width="190" />
+ <text
+ type="string"
+ length="1"
+ bg_visible="true"
+ border_visible="true"
+ control_name="DayCycleText"
+ follows="left|top|right"
+ font="SansSerif"
+ height="16"
+ layout="topleft"
+ left="220"
+ name="DayCycleText"
+ top="114"
+ width="120">
+ Snap:
+ </text>
+ <combo_box
+ enabled="false"
+ height="18"
+ label="5 min"
+ layout="topleft"
+ left_delta="0"
+ name="WLSnapOptions"
+ top_pad="7"
+ width="70" />
+ <text
+ type="string"
+ length="1"
+ bg_visible="true"
+ border_visible="true"
+ control_name="DayCycleText"
+ follows="left|top|right"
+ font="SansSerif"
+ height="16"
+ layout="topleft"
+ left_delta="0"
+ name="DayCycleText2"
+ top_pad="9"
+ width="120">
+ Length of Cycle:
+ </text>
+ <spinner
+ control_name="WLLengthOfDayHour"
+ decimal_digits="0"
+ follows="left|top"
+ height="16"
+ increment="1"
+ initial_value="0"
+ label="Hour"
+ label_width="30"
+ layout="topleft"
+ left_delta="0"
+ max_val="100"
+ name="WLLengthOfDayHour"
+ top_pad="4"
+ width="70" />
+ <spinner
+ control_name="WLLengthOfDayMin"
+ decimal_digits="0"
+ follows="left|top"
+ height="16"
+ increment="1"
+ initial_value="0"
+ label="Min"
+ label_width="20"
+ layout="topleft"
+ left_pad="5"
+ max_val="59"
+ name="WLLengthOfDayMin"
+ top_delta="0"
+ width="60" />
+ <spinner
+ control_name="WLLengthOfDaySec"
+ decimal_digits="0"
+ follows="left|top"
+ height="16"
+ increment="1"
+ initial_value="24"
+ label="Sec"
+ label_width="20"
+ layout="topleft"
+ left_pad="5"
+ max_val="59"
+ name="WLLengthOfDaySec"
+ top_delta="0"
+ width="60" />
+ <text
+ type="string"
+ length="1"
+ bg_visible="true"
+ border_visible="true"
+ control_name="DayCycleText"
+ follows="left|top|right"
+ font="SansSerif"
+ height="16"
+ layout="topleft"
+ left="310"
+ name="DayCycleText3"
+ top="114"
+ width="120">
+ Preview:
+ </text>
+ <button
+ height="20"
+ label="Play"
+ label_selected="Play"
+ layout="topleft"
+ left_delta="0"
+ name="WLAnimSky"
+ top_pad="5"
+ width="50" />
+ <button
+ height="20"
+ label="Stop!"
+ label_selected="Stop"
+ layout="topleft"
+ left_pad="5"
+ name="WLStopAnimSky"
+ top_delta="0"
+ width="50" />
+ <button
+ height="20"
+ label="Use Estate Time"
+ label_selected="Go to Estate Time"
+ layout="topleft"
+ left_pad="5"
+ name="WLUseLindenTime"
+ top_delta="0"
+ width="140" />
+ <button
+ height="20"
+ label="Save Test Day"
+ label_selected="Save Test Day"
+ layout="topleft"
+ left="480"
+ name="WLSaveDayCycle"
+ top="175"
+ width="150" />
+ <button
+ height="20"
+ label="Load Test Day"
+ label_selected="Load Test Day"
+ layout="topleft"
+ left_delta="0"
+ name="WLLoadDayCycle"
+ top_pad="5"
+ width="150" />
+ </panel>
+ </tab_container>
+</floater>
diff --git a/indra/newview/skins/default/xui/en/floater_device_settings.xml b/indra/newview/skins/default/xui/en/floater_device_settings.xml
new file mode 100644
index 0000000000..fa0cce3795
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/floater_device_settings.xml
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<floater
+ height="260"
+ layout="topleft"
+ name="floater_device_settings"
+ title="Voice Chat Device Settings"
+ width="405">
+ <panel
+ bottom="260"
+ filename="panel_audio_device.xml"
+ layout="topleft"
+ left="2"
+ name="device_settings"
+ right="-5"
+ top="20" />
+</floater>
diff --git a/indra/newview/skins/default/xui/en/floater_env_settings.xml b/indra/newview/skins/default/xui/en/floater_env_settings.xml
new file mode 100644
index 0000000000..5aa7809208
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/floater_env_settings.xml
@@ -0,0 +1,165 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<floater
+ height="150"
+ layout="topleft"
+ name="Environment Editor Floater"
+ save_rect="true"
+ title="Environment Editor"
+ width="600">
+ <floater.string
+ name="timeStr">
+ [hour12,datetime,utc]:[min,datetime,utc] [ampm,datetime,utc]
+ </floater.string>
+ <text
+ type="string"
+ length="1"
+ follows="left|top|right"
+ font="SansSerif"
+ height="16"
+ layout="topleft"
+ left="10"
+ name="EnvTimeText"
+ top="32"
+ width="140">
+ Time of Day
+ </text>
+ <text
+ type="string"
+ length="1"
+ follows="left|top|right"
+ height="16"
+ layout="topleft"
+ left="15"
+ name="EnvTimeText2"
+ top="62"
+ width="140">
+ 12:00 PM
+ </text>
+ <icon
+ height="25"
+ image_name="icon_diurnal.tga"
+ layout="topleft"
+ left="85"
+ name="EnvDayCycle"
+ top="30"
+ width="200" />
+ <slider
+ control_name="EnvTimeSlider"
+ decimal_digits="2"
+ follows="left"
+ height="10"
+ increment="0.0069444"
+ initial_value="0.7"
+ layout="topleft"
+ left_delta="0"
+ max_val="0.99"
+ name="EnvTimeSlider"
+ show_text="false"
+ top_pad="10"
+ width="200" />
+ <text
+ type="string"
+ length="1"
+ follows="left|top|right"
+ font="SansSerif"
+ height="16"
+ layout="topleft"
+ left="10"
+ name="EnvCloudText"
+ top="86"
+ width="140">
+ Cloud Cover
+ </text>
+ <slider
+ control_name="EnvCloudSlider"
+ decimal_digits="2"
+ follows="left"
+ height="10"
+ increment="0.01"
+ initial_value="0.7"
+ layout="topleft"
+ left_delta="75"
+ name="EnvCloudSlider"
+ top_delta="4"
+ width="210" />
+ <text
+ type="string"
+ length="1"
+ follows="left|top|right"
+ font="SansSerif"
+ height="16"
+ layout="topleft"
+ left="310"
+ name="EnvWaterColorText"
+ top="39"
+ width="140">
+ Water Color
+ </text>
+ <color_swatch
+ border_color="0.45098 0.517647 0.607843 1"
+ can_apply_immediately="true"
+ color="0.5 0.5 0.5 1"
+ follows="left|top"
+ height="50"
+ layout="topleft"
+ left="390"
+ name="EnvWaterColor"
+ tool_tip="Click to open Color Picker"
+ top="30"
+ width="40" />
+ <text
+ type="string"
+ length="1"
+ follows="left|top|right"
+ font="SansSerif"
+ height="16"
+ layout="topleft"
+ left="310"
+ name="EnvWaterFogText"
+ top="86"
+ width="140">
+ Water Fog
+ </text>
+ <slider
+ control_name="EnvWaterFogSlider"
+ decimal_digits="2"
+ follows="left"
+ height="10"
+ initial_value="0"
+ layout="topleft"
+ left_delta="75"
+ max_val="10"
+ name="EnvWaterFogSlider"
+ top_delta="4"
+ width="210" />
+ <button
+ follows="left|top"
+ font="SansSerifSmall"
+ height="20"
+ label="Use Estate Time"
+ layout="topleft"
+ left="8"
+ name="EnvUseEstateTimeButton"
+ top="120"
+ width="137" />
+ <button
+ follows="left|top"
+ font="SansSerifSmall"
+ height="20"
+ label="Advanced Sky"
+ layout="topleft"
+ left_pad="9"
+ name="EnvAdvancedSkyButton"
+ top_delta="0"
+ width="137" />
+ <button
+ follows="left|top"
+ font="SansSerifSmall"
+ height="20"
+ label="Advanced Water"
+ layout="topleft"
+ left_pad="9"
+ name="EnvAdvancedWaterButton"
+ top_delta="0"
+ width="137" />
+</floater>
diff --git a/indra/newview/skins/default/xui/en/floater_first_time_tip.xml b/indra/newview/skins/default/xui/en/floater_first_time_tip.xml
new file mode 100644
index 0000000000..c16373ba3c
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/floater_first_time_tip.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<floater
+ can_close="true"
+ can_minimize="false"
+ height="250"
+ layout="topleft"
+ name="set_name_in_the_cladd"
+ save_rect="true"
+ width="300">
+ <check_box
+ height="20"
+ follows="left|bottom|right"
+ label="Turn off Quick Tips"
+ layout="topleft"
+ left="5"
+ name="DontShowFirstTimeTip_checkbox"
+ text_enabled_color="white"
+ top="225"
+ width="200" />
+</floater>
diff --git a/indra/newview/skins/default/xui/en/floater_font_test.xml b/indra/newview/skins/default/xui/en/floater_font_test.xml
new file mode 100644
index 0000000000..8babbaa273
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/floater_font_test.xml
@@ -0,0 +1,336 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<floater
+ can_resize="true"
+ height="800"
+ layout="topleft"
+ min_height="175"
+ min_width="154"
+ name="contents"
+ title="Font Test"
+ width="500">
+ <text
+ type="string"
+ length="1"
+ bottom_delta="40"
+ follows="left|top|right"
+ height="16"
+ layout="topleft"
+ left="16">
+ SansSerifSmall
+ </text>
+ <text
+ type="string"
+ length="1"
+ bottom_delta="20"
+ follows="left|top|right"
+ font="SansSerifMedium"
+ height="16"
+ layout="topleft"
+ left="16">
+ SansSerifMedium
+ </text>
+ <text
+ type="string"
+ length="1"
+ bottom_delta="20"
+ follows="left|top|right"
+ font="SansSerif"
+ height="16"
+ layout="topleft"
+ left="16">
+ SansSerif, no size or style (should be same as medium)
+ </text>
+ <text
+ type="string"
+ length="1"
+ bottom_delta="20"
+ follows="left|top|right"
+ font="SansSerifLarge"
+ height="16"
+ layout="topleft"
+ left="16">
+ SansSerifLarge
+ </text>
+ <text
+ type="string"
+ length="1"
+ bottom_delta="36"
+ follows="left|top|right"
+ font="SansSerifHuge"
+ height="32"
+ layout="topleft"
+ left="16">
+ SansSerifHuge
+ </text>
+ <text
+ type="string"
+ length="1"
+ bottom_delta="40"
+ follows="left|top|right"
+ font="Monospace"
+ height="16"
+ layout="topleft"
+ left="16">
+ Monospace
+ </text>
+ <text
+ type="string"
+ length="1"
+ bottom_delta="20"
+ follows="left|top|right"
+ font="Monospace"
+ font.size="Large"
+ height="16"
+ layout="topleft"
+ left="16">
+ Monospace size=Large
+ </text>
+ <text
+ type="string"
+ length="1"
+ bottom_delta="20"
+ follows="left|top|right"
+ font="SansSerifLarge"
+ font.style="BOLD"
+ height="16"
+ layout="topleft"
+ left="16">
+ SansSerifLarge style=BOLD
+ </text>
+ <text
+ type="string"
+ length="1"
+ bottom_delta="20"
+ follows="left|top|right"
+ font="SansSerifBold"
+ height="16"
+ layout="topleft"
+ left="16">
+ SansSerifBold
+ </text>
+ <text
+ type="string"
+ length="1"
+ bottom_delta="20"
+ follows="left|top|right"
+ font="SansSerif"
+ font.style="BOLD"
+ height="16"
+ layout="topleft"
+ left="16">
+ SansSerif style=BOLD (should be same as SansSerifBold)
+ </text>
+ <text
+ type="string"
+ length="1"
+ bottom_delta="20"
+ follows="left|top|right"
+ font="SansSerif"
+ font.style="ITALIC"
+ height="16"
+ layout="topleft"
+ left="16">
+ SansSerif style=ITALIC
+ </text>
+ <text
+ type="string"
+ length="1"
+ bottom_delta="20"
+ follows="left|top|right"
+ font="SansSerif"
+ font.style="BOLD|ITALIC"
+ height="16"
+ layout="topleft"
+ left="16">
+ SansSerif style=BOLD|ITALIC
+ </text>
+ <text
+ type="string"
+ length="1"
+ bottom_delta="20"
+ follows="left|top|right"
+ font="SansSerif"
+ font.style="BOLD|ITALIC"
+ height="16"
+ layout="topleft"
+ left="16">
+ SansSerif style=BOLD|ITALIC shadow=soft
+ </text>
+ <text
+ type="string"
+ length="1"
+ bottom_delta="20"
+ follows="left|top|right"
+ font="SansSerif"
+ font.style="UNDERLINE"
+ height="16"
+ layout="topleft"
+ left="16">
+ SansSerif style=UNDERLINE
+ </text>
+ <text
+ type="string"
+ length="1"
+ bottom_delta="20"
+ follows="left|top|right"
+ font="SansSerif"
+ font_shadow="hard"
+ height="16"
+ layout="topleft"
+ left="16">
+ SansSerif style=hard
+ </text>
+ <text
+ type="string"
+ length="1"
+ bottom_delta="20"
+ follows="left|top|right"
+ font="SansSerif"
+ height="16"
+ layout="topleft"
+ left="16">
+ SansSerif shadow=soft
+ </text>
+ <text
+ type="string"
+ length="1"
+ bottom_delta="20"
+ follows="left|top|right"
+ font="DejaVu"
+ height="16"
+ layout="topleft"
+ left="16">
+ DejaVu
+ </text>
+ <text
+ type="string"
+ length="1"
+ bottom_delta="20"
+ follows="left|top|right"
+ font="DejaVu"
+ font.style="BOLD"
+ height="16"
+ layout="topleft"
+ left="16">
+ DejaVu style=BOLD
+ </text>
+ <text
+ type="string"
+ length="1"
+ bottom_delta="20"
+ follows="left|top|right"
+ font="DejaVu"
+ font.style="ITALIC"
+ height="16"
+ layout="topleft"
+ left="16">
+ DejaVu style=ITALIC
+ </text>
+ <text
+ type="string"
+ length="1"
+ bottom_delta="20"
+ follows="left|top|right"
+ font="DejaVu"
+ font.style="BOLD|ITALIC"
+ height="16"
+ layout="topleft"
+ left="16">
+ DejaVu style=BOLD|ITALIC
+ </text>
+ <text
+ type="string"
+ length="1"
+ bottom_delta="20"
+ follows="left|top|right"
+ font="DejaVu"
+ font.size="Large"
+ font.style="BOLD|ITALIC"
+ height="16"
+ layout="topleft"
+ left="16">
+ DejaVu size=Large style=BOLD|ITALIC
+ </text>
+ <text
+ type="string"
+ length="1"
+ bottom_delta="20"
+ follows="left|top|right"
+ font="Helvetica"
+ height="16"
+ layout="topleft"
+ left="16">
+ Helvetica
+ </text>
+ <text
+ type="string"
+ length="1"
+ bottom_delta="20"
+ follows="left|top|right"
+ font="Helvetica"
+ font.style="BOLD"
+ height="16"
+ layout="topleft"
+ left="16">
+ Helvetica style=BOLD
+ </text>
+ <text
+ type="string"
+ length="1"
+ bottom_delta="20"
+ follows="left|top|right"
+ font="Helvetica"
+ font.style="ITALIC"
+ height="16"
+ layout="topleft"
+ left="16">
+ Helvetica style=ITALIC
+ </text>
+ <text
+ type="string"
+ length="1"
+ bottom_delta="20"
+ follows="left|top|right"
+ font="Helvetica"
+ font.style="BOLD|ITALIC"
+ height="16"
+ layout="topleft"
+ left="16">
+ Helvetica style=BOLD|ITALIC
+ </text>
+ <text
+ type="string"
+ length="1"
+ bottom_delta="20"
+ follows="left|top|right"
+ font="Helvetica"
+ font.size="Large"
+ font.style="BOLD|ITALIC"
+ height="16"
+ layout="topleft"
+ left="16">
+ Helvetica size=Large style=BOLD|ITALIC
+ </text>
+ <text
+ type="string"
+ length="1"
+ bottom_delta="20"
+ follows="left|top|right"
+ font="OverrideTest"
+ height="16"
+ layout="topleft"
+ left="16"
+ name="linea">
+ OverrideTest, should be times, from default/xui/en
+ </text>
+ <text
+ type="string"
+ length="1"
+ bottom_delta="20"
+ follows="left|top|right"
+ height="16"
+ layout="topleft"
+ left="16">
+ BogusFontName
+ </text>
+</floater>
diff --git a/indra/newview/skins/default/xui/en/floater_gesture.xml b/indra/newview/skins/default/xui/en/floater_gesture.xml
new file mode 100644
index 0000000000..f042385fb4
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/floater_gesture.xml
@@ -0,0 +1,92 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<floater
+ can_resize="true"
+ height="465"
+ layout="topleft"
+ min_height="200"
+ min_width="280"
+ name="gestures"
+ title="Active Gestures"
+ width="280">
+ <floater.string
+ name="loading">
+ Loading...
+ </floater.string>
+ <floater.string
+ name="playing">
+ (Playing)
+ </floater.string>
+ <text
+ type="string"
+ length="1"
+ bottom="30"
+ follows="top|left"
+ layout="topleft"
+ left="15"
+ name="help_label">
+ Double-click a gesture to play.
+ </text>
+ <scroll_list
+ bottom_delta="390"
+ draw_heading="true"
+ follows="top|left|bottom|right"
+ height="380"
+ layout="topleft"
+ left="15"
+ name="gesture_list"
+ right="-15">
+ <scroll_list.columns
+ label="Name"
+ name="name"
+ width="90" />
+ <scroll_list.columns
+ label="Trigger"
+ name="trigger"
+ width="80" />
+ <scroll_list.columns
+ label=""
+ name="key"
+ width="-1" />
+ <scroll_list.columns
+ label="Key"
+ name="shortcut"
+ width="50" />
+ </scroll_list>
+ <button
+ follows="bottom|right"
+ height="20"
+ label="New"
+ layout="topleft"
+ left_delta="0"
+ name="new_gesture_btn"
+ top_pad="10"
+ width="83" />
+ <button
+ follows="bottom|right"
+ height="20"
+ label="Edit"
+ layout="topleft"
+ left_pad="6"
+ name="edit_btn"
+ top_delta="0"
+ width="83" />
+ <button
+ follows="bottom|right"
+ height="20"
+ label="Play"
+ layout="topleft"
+ left_pad="6"
+ name="play_btn"
+ top_delta="0"
+ width="83" />
+ <button
+ follows="bottom|right"
+ height="20"
+ label="Stop"
+ layout="topleft"
+ left_delta="0"
+ name="stop_btn"
+ top_delta="0"
+ width="83" />
+</floater>
+
diff --git a/indra/newview/skins/default/xui/en/floater_god_tools.xml b/indra/newview/skins/default/xui/en/floater_god_tools.xml
new file mode 100644
index 0000000000..e3bea2e2d6
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/floater_god_tools.xml
@@ -0,0 +1,798 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<floater
+ height="384"
+ layout="topleft"
+ name="godtools floater"
+ title="God Tools"
+ width="400">
+ <tab_container
+ follows="left|top"
+ height="364"
+ layout="topleft"
+ left="0"
+ name="GodTools Tabs"
+ tab_position="top"
+ top="20"
+ width="400">
+ <panel
+ border="true"
+ follows="left|top|right|bottom"
+ height="347"
+ label="Grid"
+ layout="topleft"
+ left="1"
+ mouse_opaque="false"
+ name="grid"
+ top="16"
+ width="398">
+ <button
+ follows="left|top"
+ height="20"
+ label="Kick all users"
+ label_selected="Kick all users"
+ layout="topleft"
+ left="10"
+ name="Kick all users"
+ top="30"
+ width="120">
+ <button.commit_callback
+ function="GridTools.KickAll" />
+ </button>
+ <button
+ follows="left|top"
+ height="20"
+ label="Flush This Region&apos;s Map Visibility Caches"
+ label_selected="Flush This Region&apos;s Map Visibility Caches"
+ layout="topleft"
+ left="10"
+ name="Flush This Region&apos;s Map Visibility Caches"
+ top_pad="30"
+ width="350">
+ <button.commit_callback
+ function="GridTools.FlushMapVisibilityCaches" />
+ </button>
+ </panel>
+ <panel
+ border="true"
+ follows="left|top|right|bottom"
+ height="347"
+ label="Region"
+ layout="topleft"
+ left_delta="0"
+ mouse_opaque="false"
+ name="region"
+ top_delta="0"
+ width="398">
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="10"
+ layout="topleft"
+ left="10"
+ name="Sim Name:"
+ top="12"
+ width="80">
+ Sim Name:
+ </text>
+ <line_editor
+ border_style="line"
+ border_thickness="1"
+ follows="left|top|right"
+ height="20"
+ layout="topleft"
+ left_pad="0"
+ max_length="63"
+ name="region name"
+ top_delta="0"
+ width="250">
+ <line_editor.commit_callback
+ function="RegionTools.ChangeAnything" />
+ </line_editor>
+ <check_box
+ height="16"
+ label="Prelude"
+ layout="topleft"
+ left="10"
+ name="check prelude"
+ tool_tip="Set this to make the region a prelude."
+ top_pad="10"
+ width="180">
+ <check_box.commit_callback
+ function="RegionTools.ChangePrelude" />
+ </check_box>
+ <check_box
+ height="16"
+ label="Fixed Sun"
+ layout="topleft"
+ left_delta="0"
+ name="check fixed sun"
+ tool_tip="Fix the sun position (like in Region/Estate &gt; Terrain."
+ top_pad="4"
+ width="180">
+ <check_box.commit_callback
+ function="RegionTools.ChangeAnything" />
+ </check_box>
+ <check_box
+ height="16"
+ label="Reset Home On Teleport"
+ layout="topleft"
+ left_delta="0"
+ name="check reset home"
+ tool_tip="When resident teleports out, reset their home to the destination position."
+ top_pad="4"
+ width="180">
+ <check_box.commit_callback
+ function="RegionTools.ChangeAnything" />
+ </check_box>
+ <check_box
+ height="16"
+ label="Visible"
+ layout="topleft"
+ left_delta="0"
+ name="check visible"
+ tool_tip="Set this to make the region visible to non-gods."
+ top_pad="4"
+ width="180">
+ <check_box.commit_callback
+ function="RegionTools.ChangeAnything" />
+ </check_box>
+ <check_box
+ height="16"
+ label="Damage"
+ layout="topleft"
+ left_delta="0"
+ name="check damage"
+ tool_tip="Set this to enable damage in this region."
+ top_pad="4"
+ width="180">
+ <check_box.commit_callback
+ function="RegionTools.ChangeAnything" />
+ </check_box>
+ <check_box
+ height="16"
+ label="Block Traffic Tracking"
+ layout="topleft"
+ left_delta="0"
+ name="block dwell"
+ tool_tip="Set this to make the region not compute traffic."
+ top_pad="4"
+ width="180">
+ <check_box.commit_callback
+ function="RegionTools.ChangeAnything" />
+ </check_box>
+ <check_box
+ height="16"
+ label="Block Terraform"
+ layout="topleft"
+ left_delta="0"
+ name="block terraform"
+ tool_tip="Set this to disallow people terraforming their land"
+ top_pad="4"
+ width="180">
+ <check_box.commit_callback
+ function="RegionTools.ChangeAnything" />
+ </check_box>
+ <check_box
+ height="16"
+ label="Sandbox"
+ layout="topleft"
+ left_delta="0"
+ name="is sandbox"
+ tool_tip="Toggle whether this is a sandbox region."
+ top_pad="4"
+ width="180">
+ <check_box.commit_callback
+ function="RegionTools.ChangeAnything" />
+ </check_box>
+ <button
+ follows="top|right"
+ font="SansSerifSmall"
+ height="22"
+ label="Bake Terrain"
+ label_selected="Bake Terrain"
+ layout="topleft"
+ left="12"
+ name="Bake Terrain"
+ tool_tip="Save the current terrain as default."
+ top_pad="32"
+ width="110">
+ <button.commit_callback
+ function="RegionTools.BakeTerrain" />
+ </button>
+ <button
+ follows="top|right"
+ font="SansSerifSmall"
+ height="22"
+ label="Revert Terrain"
+ label_selected="Revert Terrain"
+ layout="topleft"
+ name="Revert Terrain"
+ tool_tip="Replace the current terrain with default."
+ top_pad="10"
+ width="110">
+ <button.commit_callback
+ function="RegionTools.RevertTerrain" />
+ </button>
+ <button
+ follows="top|right"
+ font="SansSerifSmall"
+ height="22"
+ label="Swap Terrain"
+ label_selected="Swap Terrain"
+ layout="topleft"
+ name="Swap Terrain"
+ tool_tip="Swap current terrain with default."
+ top_pad="10"
+ width="110">
+ <button.commit_callback
+ function="RegionTools.SwapTerrain" />
+ </button>
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ font="SansSerif"
+ height="16"
+ layout="topleft"
+ left="200"
+ name="estate id"
+ top="40"
+ width="190">
+ Estate ID:
+ </text>
+ <line_editor
+ border_style="line"
+ border_thickness="1"
+ follows="top|right"
+ height="16"
+ layout="topleft"
+ left_delta="108"
+ max_length="10"
+ name="estate"
+ top_delta="0"
+ width="50" />
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ font="SansSerif"
+ height="16"
+ layout="topleft"
+ left="200"
+ name="parent id"
+ top_pad="4"
+ width="190">
+ Parent ID:
+ </text>
+ <line_editor
+ border_style="line"
+ border_thickness="1"
+ follows="top|right"
+ height="16"
+ layout="topleft"
+ left_delta="108"
+ max_length="10"
+ name="parentestate"
+ tool_tip="This is the parent estate for this region"
+ top_delta="0"
+ width="50">
+ <line_editor.commit_callback
+ function="RegionTools.ChangeAnything" />
+ </line_editor>
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="16"
+ layout="topleft"
+ left="200"
+ name="Grid Pos: "
+ top_pad="4"
+ width="190">
+ Grid Pos:
+ </text>
+ <line_editor
+ border_style="line"
+ border_thickness="1"
+ follows="top|right"
+ height="16"
+ layout="topleft"
+ left_delta="88"
+ max_length="10"
+ name="gridposx"
+ tool_tip="This is the grid x position for this region"
+ top_delta="0"
+ width="50">
+ <line_editor.commit_callback
+ function="RegionTools.ChangeAnything" />
+ </line_editor>
+ <line_editor
+ border_style="line"
+ border_thickness="1"
+ follows="top|right"
+ height="16"
+ layout="topleft"
+ left_pad="10"
+ max_length="10"
+ name="gridposy"
+ tool_tip="This is the grid y position for this region"
+ top_delta="0"
+ width="40">
+ <line_editor.commit_callback
+ function="RegionTools.ChangeAnything" />
+ </line_editor>
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="16"
+ layout="topleft"
+ left="200"
+ name="Redirect to Grid: "
+ top_pad="4"
+ width="88">
+ Redirect to Grid:
+ </text>
+ <line_editor
+ border_style="line"
+ border_thickness="1"
+ follows="top|right"
+ height="16"
+ layout="topleft"
+ left_pad="0"
+ max_length="10"
+ name="redirectx"
+ width="50">
+ <line_editor.commit_callback
+ function="RegionTools.ChangeAnything" />
+ </line_editor>
+ <line_editor
+ border_style="line"
+ border_thickness="1"
+ follows="top|right"
+ height="16"
+ layout="topleft"
+ left_pad="10"
+ max_length="10"
+ name="redirecty"
+ top_delta="0"
+ width="40">
+ <line_editor.commit_callback
+ function="RegionTools.ChangeAnything" />
+ </line_editor>
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ font="SansSerif"
+ height="16"
+ layout="topleft"
+ left="200"
+ name="billable factor text"
+ top_pad="10"
+ width="110">
+ Billable Factor:
+ </text>
+ <spinner
+ follows="top|right"
+ height="16"
+ initial_value="1"
+ layout="topleft"
+ max_val="4"
+ name="billable factor"
+ left_pad="0"
+ width="80">
+ <spinner.commit_callback
+ function="RegionTools.ChangeAnything" />
+ </spinner>
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ font="SansSerif"
+ height="16"
+ layout="topleft"
+ left="200"
+ name="land cost text"
+ top_pad="10"
+ width="110">
+ L$ per m²:
+ </text>
+ <spinner
+ follows="top|right"
+ height="16"
+ increment="1"
+ initial_value="1"
+ layout="topleft"
+ left_pad="0"
+ max_val="100"
+ name="land cost"
+ width="80">
+ <spinner.commit_callback
+ function="RegionTools.ChangeAnything" />
+ </spinner>
+
+ <button
+ follows="top|right"
+ font="SansSerifSmall"
+ height="22"
+ label="Refresh"
+ label_selected="Refresh"
+ layout="topleft"
+ left="278"
+ name="Refresh"
+ tool_tip="Click here to refresh the above information."
+ top_pad="10"
+ width="110">
+ <button.commit_callback
+ function="RegionTools.Refresh" />
+ </button>
+ <button
+ follows="top|right"
+ font="SansSerifSmall"
+ height="22"
+ label="Apply"
+ label_selected="Apply"
+ layout="topleft"
+ left="278"
+ name="Apply"
+ tool_tip="Click here to apply any changes from above."
+ top="317"
+ width="110">
+ <button.commit_callback
+ function="RegionTools.ApplyChanges" />
+ </button>
+ <button
+ follows="top|right"
+ font="SansSerifSmall"
+ height="22"
+ label="Select Region"
+ label_selected="Select Region"
+ layout="topleft"
+ left="130"
+ name="Select Region"
+ tool_tip="Select the whole region with the land tool."
+ top="238"
+ width="110">
+ <button.commit_callback
+ function="RegionTools.SelectRegion" />
+ </button>
+ <button
+ follows="top|right"
+ font="SansSerifSmall"
+ height="22"
+ label="Autosave now"
+ label_selected="Autosave now"
+ layout="topleft"
+ left_delta="0"
+ name="Autosave now"
+ tool_tip="Save gzipped state to autosave directory."
+ top_pad="10"
+ width="110">
+ <button.commit_callback
+ function="RegionTools.SaveState" />
+ </button>
+ </panel>
+ <panel
+ border="true"
+ follows="left|top|right|bottom"
+ height="347"
+ label="Objects"
+ layout="topleft"
+ left_delta="0"
+ mouse_opaque="false"
+ name="objects"
+ top_delta="0"
+ width="398">
+ <panel.string
+ name="no_target">
+ (no target)
+ </panel.string>
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="10"
+ layout="topleft"
+ left="10"
+ name="Sim Name:"
+ top="10"
+ width="80">
+ Sim Name:
+ </text>
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="10"
+ layout="topleft"
+ left_pad="10"
+ name="region name"
+ top_delta="0"
+ width="320">
+ Welsh
+ </text>
+ <check_box
+ height="16"
+ label="Disable Scripts"
+ layout="topleft"
+ left="10"
+ name="disable scripts"
+ tool_tip="Set this to disable all scripts in this region"
+ top="30"
+ width="110">
+ <check_box.commit_callback
+ function="ObjectTools.ChangeAnything" />
+ </check_box>
+ <check_box
+ height="16"
+ label="Disable Collisions"
+ layout="topleft"
+ left_pad="10"
+ name="disable collisions"
+ tool_tip="Set this to disable non-agent collisions in this region"
+ top_delta="0"
+ width="121">
+ <check_box.commit_callback
+ function="ObjectTools.ChangeAnything" />
+ </check_box>
+ <check_box
+ height="16"
+ label="Disable Physics"
+ layout="topleft"
+ left_delta="120"
+ name="disable physics"
+ tool_tip="Set this to disable all physics in this region"
+ top_delta="0"
+ width="130">
+ <check_box.commit_callback
+ function="ObjectTools.ChangeAnything" />
+ </check_box>
+ <button
+ follows="top|right"
+ font="SansSerifSmall"
+ height="22"
+ label="Apply"
+ label_selected="Apply"
+ layout="topleft"
+ left="278"
+ name="Apply"
+ tool_tip="Click here to apply any changes from above."
+ top="54"
+ width="110">
+ <button.commit_callback
+ function="ObjectTools.ApplyChanges" />
+ </button>
+ <button
+ follows="top|right"
+ font="SansSerifSmall"
+ height="22"
+ label="Set Target"
+ label_selected="Set Target"
+ layout="topleft"
+ left="8"
+ name="Set Target"
+ tool_tip="Set the target avatar for object deletion."
+ top="78"
+ width="110">
+ <button.commit_callback
+ function="ObjectTools.Set" />
+ </button>
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="10"
+ layout="topleft"
+ left_pad="12"
+ name="target_avatar_name"
+ top_delta="0"
+ width="260">
+ (no target)
+ </text>
+ <button
+ follows="top|right"
+ font="SansSerifSmall"
+ height="22"
+ label="Delete Target&apos;s Scripted Objects On Others Land"
+ label_selected="Delete Target&apos;s Scripted Objects On Others Land"
+ layout="topleft"
+ left="8"
+ name="Delete Target&apos;s Scripted Objects On Others Land"
+ tool_tip="Delete all scripted objects owned by the target on land not owned by the target. (no copy) objects will be returned."
+ top="126"
+ width="380">
+ <button.commit_callback
+ function="ObjectTools.DeletePublicOwnedBy" />
+ </button>
+ <button
+ follows="top|right"
+ font="SansSerifSmall"
+ height="22"
+ label="Delete Target&apos;s Scripted Objects On *Any* Land"
+ label_selected="Delete Target&apos;s Scripted Objects On *Any* Land"
+ layout="topleft"
+ left_delta="0"
+ name="Delete Target&apos;s Scripted Objects On *Any* Land"
+ tool_tip="Delete all scripted objects owned by the target in this region. (no copy) objects will be returned."
+ top_pad="28"
+ width="380">
+ <button.commit_callback
+ function="ObjectTools.DeleteAllScriptedOwnedBy" />
+ </button>
+ <button
+ follows="top|right"
+ font="SansSerifSmall"
+ height="22"
+ label="Delete *ALL* Of Target&apos;s Objects"
+ label_selected="Delete *ALL* Of Target&apos;s Objects"
+ layout="topleft"
+ left_delta="0"
+ name="Delete *ALL* Of Target&apos;s Objects"
+ tool_tip="Delete all objects owned by the target in this region. (no copy) objects will be returned."
+ top_pad="28"
+ width="380">
+ <button.commit_callback
+ function="ObjectTools.DeleteAllOwnedBy" />
+ </button>
+ <button
+ follows="top|right"
+ font="SansSerifSmall"
+ height="20"
+ label="Get Top Colliders"
+ label_selected="Get Top Colliders"
+ layout="topleft"
+ left="12"
+ name="Get Top Colliders"
+ tool_tip="Gets list of objects experiencing the most narrowphase callbacks."
+ top_pad="20"
+ width="130">
+ <button.commit_callback
+ function="ObjectTools.GetTopColliders" />
+ </button>
+ <button
+ follows="top|right"
+ font="SansSerifSmall"
+ height="20"
+ label="Get Top Scripts"
+ label_selected="Get Top Scripts"
+ layout="topleft"
+ left_delta="0"
+ name="Get Top Scripts"
+ tool_tip="Gets list of objects spending the most time running scripts."
+ top_pad="5"
+ width="130">
+ <button.commit_callback
+ function="ObjectTools.GetTopScripts" />
+ </button>
+ <button
+ follows="top|right"
+ font="SansSerifSmall"
+ height="20"
+ label="Scripts digest"
+ label_selected="Scripts digest"
+ layout="topleft"
+ left_delta="0"
+ name="Scripts digest"
+ tool_tip="Gets a list of all scripts and number of occurences of each."
+ top_pad="5"
+ width="130" >
+ <button.commit_callback
+ function="ObjectTools.GetScriptDigest" />
+ </button>
+ </panel>
+ <panel
+ border="true"
+ follows="left|top|right|bottom"
+ height="347"
+ label="Request"
+ layout="topleft"
+ left_delta="0"
+ name="request"
+ top_delta="0"
+ width="398">
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="22"
+ layout="topleft"
+ left="10"
+ name="Destination:"
+ top="12"
+ width="80">
+ Destination:
+ </text>
+ <combo_box
+ height="22"
+ layout="topleft"
+ left_pad="10"
+ name="destination"
+ top_delta="0"
+ width="290">
+ <combo_box.item
+ label="Selection"
+ name="item1"
+ value="Selection" />
+ <combo_box.item
+ label="Agent Region"
+ name="item2"
+ value="Agent Region" />
+ </combo_box>
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="22"
+ layout="topleft"
+ left="10"
+ name="Request:"
+ top_pad="10"
+ width="80">
+ Request:
+ </text>
+ <combo_box
+ allow_text_entry="true"
+ height="22"
+ layout="topleft"
+ left_pad="10"
+ name="request"
+ top_delta="0"
+ width="290">
+ <combo_box.item
+ label="colliders &lt;steps&gt;"
+ name="item1"
+ value="colliders &lt;steps&gt;" />
+ <combo_box.item
+ label="scripts &lt;count&gt;,&lt;optional pattern&gt;"
+ name="item2"
+ value="scripts &lt;count&gt;,&lt;optional pattern&gt;" />
+ <combo_box.item
+ label="objects &lt;pattern&gt;"
+ name="item3"
+ value="objects &lt;pattern&gt;" />
+ <combo_box.item
+ label="rez &lt;asset_id&gt;"
+ name="item4"
+ value="rez &lt;asset_id&gt;" />
+ </combo_box>
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="10"
+ layout="topleft"
+ left="10"
+ name="Parameter:"
+ top_pad="10"
+ width="80">
+ Parameter:
+ </text>
+ <line_editor
+ border_style="line"
+ border_thickness="1"
+ follows="left|top"
+ height="22"
+ layout="topleft"
+ left_pad="10"
+ max_length="63"
+ name="parameter"
+ top_delta="0"
+ width="290" />
+ <button
+ follows="left|top"
+ height="20"
+ label="Make Request"
+ label_selected="Make Request"
+ layout="topleft"
+ left="10"
+ name="Make Request"
+ top_pad="10"
+ width="140">
+ <button.commit_callback
+ function="GodTools.Request" />
+ </button>
+ </panel>
+ </tab_container>
+</floater>
diff --git a/indra/newview/skins/default/xui/en/floater_hardware_settings.xml b/indra/newview/skins/default/xui/en/floater_hardware_settings.xml
new file mode 100644
index 0000000000..b7733c6388
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/floater_hardware_settings.xml
@@ -0,0 +1,162 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<floater
+ height="224"
+ layout="topleft"
+ name="Hardware Settings Floater"
+ title="Hardware Settings"
+ width="500">
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="12"
+ layout="topleft"
+ left="10"
+ name="Filtering:"
+ top="20"
+ width="128">
+ Filtering:
+ </text>
+ <check_box
+ control_name="RenderAnisotropic"
+ height="16"
+ label="Anisotropic Filtering (slower when enabled)"
+ layout="topleft"
+ left_pad="10"
+ name="ani"
+ top_delta="0"
+ width="256" />
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="12"
+ layout="topleft"
+ left="10"
+ name="Antialiasing:"
+ top_pad="7"
+ width="128">
+ Antialiasing:
+ </text>
+ <combo_box
+ control_name="RenderFSAASamples"
+ height="22"
+ initial_value="false"
+ label="Antialiasing"
+ layout="topleft"
+ left_pad="10"
+ name="fsaa"
+ top_delta="0"
+ width="130">
+ <combo_box.item
+ label="Disabled"
+ name="FSAADisabled"
+ value="0" />
+ <combo_box.item
+ label="2x"
+ name="2x"
+ value="2" />
+ <combo_box.item
+ label="4x"
+ name="4x"
+ value="4" />
+ <combo_box.item
+ label="8x"
+ name="8x"
+ value="8" />
+ <combo_box.item
+ label="16x"
+ name="16x"
+ value="16" />
+ </combo_box>
+ <spinner
+ control_name="RenderGamma"
+ decimal_digits="2"
+ follows="left|top"
+ height="16"
+ increment="0.01"
+ initial_value="1"
+ label="Gamma:"
+ label_width="138"
+ layout="topleft"
+ left="10"
+ max_val="2"
+ name="gamma"
+ top_pad="7"
+ width="202" />
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="12"
+ layout="topleft"
+ left_pad="10"
+ name="(brightness, lower is brighter)"
+ top_delta="2"
+ width="315">
+ (brightness, lower = brighter, 0 = default)
+ </text>
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="16"
+ layout="topleft"
+ left="10"
+ name="Enable VBO:"
+ top_pad="10"
+ width="128">
+ Enable VBO:
+ </text>
+ <check_box
+ control_name="RenderVBOEnable"
+ height="16"
+ initial_value="true"
+ label="Enable OpenGL Vertex Buffer Objects"
+ layout="topleft"
+ left_pad="10"
+ name="vbo"
+ tool_tip="Enabling this on modern hardware gives a performance gain. However, older hardware often has poor implementations of VBOs and you may get crashes when this is enabled."
+ width="315" />
+ <slider
+ control_name="TextureMemory"
+ decimal_digits="0"
+ follows="left|top"
+ height="20"
+ increment="16"
+ initial_value="32"
+ label="Texture Memory (MB):"
+ label_width="135"
+ layout="topleft"
+ left="10"
+ max_val="4096"
+ name="GrapicsCardTextureMemory"
+ tool_tip="Amount of memory to allocate for textures. Defaults to Video Card Memory. Reducing this may improve performance but may also make textures blurry."
+ top_pad="10"
+ width="300" />
+ <spinner
+ control_name="RenderFogRatio"
+ decimal_digits="1"
+ follows="left|top"
+ height="22"
+ initial_value="4"
+ label="Fog Distance Ratio:"
+ label_width="138"
+ layout="topleft"
+ left_delta="0"
+ max_val="10"
+ min_val="0.5"
+ name="fog"
+ top_pad="7"
+ width="202" />
+ <button
+ follows="right|bottom"
+ height="22"
+ label="OK"
+ label_selected="OK"
+ layout="topleft"
+ left="-102"
+ name="OK"
+ top="192"
+ width="90" />
+</floater>
diff --git a/indra/newview/skins/default/xui/en/floater_hud.xml b/indra/newview/skins/default/xui/en/floater_hud.xml
new file mode 100644
index 0000000000..73804f90a5
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/floater_hud.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<floater
+ can_minimize="false"
+ height="292"
+ layout="topleft"
+ name="floater_hud"
+ save_rect="true"
+ save_visibility="true"
+ title="Tutorial"
+ width="362">
+ <web_browser
+ border_visible="false"
+ caret_color="1 1 1 1"
+ follows="top|left|bottom|right"
+ height="265"
+ layout="topleft"
+ left="1"
+ name="floater_hud_browser"
+ start_url="data:text/html,%3Chtml%3E%3Chead%3E%3C/head%3E%3Cbody bgcolor=%22#000000%22 text=%22ffffff%22%3E%3Ch1%3E%3Ctt%3E%0D%0A%0D%0ALoading...%3C/tt%3E%3C/h1%3E%3C/body%3E%3C/html%3E"
+ top="26"
+ width="360" />
+</floater>
diff --git a/indra/newview/skins/default/xui/en/floater_im.xml b/indra/newview/skins/default/xui/en/floater_im.xml
new file mode 100644
index 0000000000..e8b8fee678
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/floater_im.xml
@@ -0,0 +1,78 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<multi_floater
+ can_resize="true"
+ follows="left|bottom"
+ height="422"
+ layout="topleft"
+ min_height="130"
+ min_width="350"
+ name="im_floater"
+ save_rect="true"
+ title="Instant Message"
+ width="419">
+ <multi_floater.string
+ name="only_user_message">
+ You are the only user in this session.
+ </multi_floater.string>
+ <multi_floater.string
+ name="offline_message">
+ [FIRST] [LAST] is offline.
+ </multi_floater.string>
+ <multi_floater.string
+ name="invite_message">
+ Click the [BUTTON NAME] button to accept/connect to this voice chat.
+ </multi_floater.string>
+ <multi_floater.string
+ name="muted_message">
+ You have blocked this resident. Sending a message will automatically unblock them.
+ </multi_floater.string>
+ <multi_floater.string
+ name="generic_request_error">
+ Error making request, please try again later.
+ </multi_floater.string>
+ <multi_floater.string
+ name="insufficient_perms_error">
+ You do not have sufficient permissions.
+ </multi_floater.string>
+ <multi_floater.string
+ name="session_does_not_exist_error">
+ The session no longer exists
+ </multi_floater.string>
+ <multi_floater.string
+ name="no_ability_error">
+ You do not have that ability.
+ </multi_floater.string>
+ <multi_floater.string
+ name="not_a_mod_error">
+ You are not a session moderator.
+ </multi_floater.string>
+ <multi_floater.string
+ name="muted_error">
+ A group moderator disabled your text chat.
+ </multi_floater.string>
+ <multi_floater.string
+ name="add_session_event">
+ Unable to add users to chat session with [RECIPIENT].
+ </multi_floater.string>
+ <multi_floater.string
+ name="message_session_event">
+ Unable to send your message to the chat session with [RECIPIENT].
+ </multi_floater.string>
+ <multi_floater.string
+ name="removed_from_group">
+ You have been removed from the group.
+ </multi_floater.string>
+ <multi_floater.string
+ name="close_on_no_ability">
+ You no longer have the ability to be in the chat session.
+ </multi_floater.string>
+ <tab_container
+ follows="left|top|right|bottom"
+ height="406"
+ layout="topleft"
+ left="1"
+ name="Preview Tabs"
+ tab_position="bottom"
+ top="16"
+ width="417" />
+</multi_floater>
diff --git a/indra/newview/skins/default/xui/en/floater_im_session.xml b/indra/newview/skins/default/xui/en/floater_im_session.xml
new file mode 100644
index 0000000000..ae9e658688
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/floater_im_session.xml
@@ -0,0 +1,66 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<floater
+ background_visible="true"
+ follows="left|top|right|bottom"
+ height="250"
+ layout="topleft"
+ left="0"
+ name="panel_im"
+ top="0"
+ can_dock="true"
+ can_minimize="false"
+ visible="true"
+ width="315">
+ <layout_stack follows="left|top|right|bottom"
+ height="235"
+ width="315"
+ layout="topleft"
+ orientation="horizontal"
+ name="im_panels"
+ top="16"
+ left="2">
+ <layout_panel
+ name="panel_im_control_panel"
+ layout="topleft"
+ top_delta="-3"
+ min_width="96"
+ width="96"
+ height="225"
+ label="IM Control Panel"
+ user_resize="false" />
+ <layout_panel height="235"
+ width="200"
+ left_delta="96"
+ top="0"
+ user_resize="false">
+ <button height="12"
+ top="8"
+ label="&lt;&lt;"
+ layout="topleft"
+ width="35"
+ name="slide_left_btn" />
+ <button height="12"
+ top="8"
+ label="&gt;&gt;"
+ layout="topleft"
+ width="35"
+ name="slide_right_btn" />
+ <text_editor
+ enabled="false"
+ type="string"
+ length="1"
+ follows="left|top|right"
+ font="SansSerif"
+ height="185"
+ layout="topleft"
+ max_length="2147483647"
+ name="im_text"
+ track_bottom="true"
+ width="195"
+ word_wrap="true">
+ </text_editor>
+ <line_editor name="chat_editor" height="20" layout="topleft" width="190">
+ </line_editor>
+ </layout_panel>
+ </layout_stack>
+</floater>
diff --git a/indra/newview/skins/default/xui/en/floater_image_preview.xml b/indra/newview/skins/default/xui/en/floater_image_preview.xml
new file mode 100644
index 0000000000..6fface12a3
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/floater_image_preview.xml
@@ -0,0 +1,135 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<floater
+ can_minimize="false"
+ height="440"
+ layout="topleft"
+ name="Image Preview"
+ width="300">
+ <text
+ type="string"
+ length="1"
+ bottom_delta="40"
+ follows="top|left"
+ height="15"
+ layout="topleft"
+ left="10"
+ name="name_label">
+ Name:
+ </text>
+ <line_editor
+ follows="top|left|right"
+ height="19"
+ layout="topleft"
+ left_delta="0"
+ name="name_form"
+ top_pad="5"
+ width="280" />
+ <text
+ type="string"
+ length="1"
+ bottom_delta="20"
+ follows="top|left"
+ height="15"
+ layout="topleft"
+ name="description_label">
+ Description:
+ </text>
+ <line_editor
+ follows="top|left|right"
+ height="19"
+ layout="topleft"
+ left_delta="0"
+ name="description_form"
+ top_pad="5"
+ width="280" />
+ <text
+ type="string"
+ length="1"
+ bottom_delta="20"
+ follows="top|left"
+ height="15"
+ layout="topleft"
+ name="preview_label">
+ Preview image as:
+ </text>
+ <combo_box
+ height="18"
+ label="Clothing Type"
+ layout="topleft"
+ left_delta="110"
+ name="clothing_type_combo"
+ top_delta="3"
+ width="160">
+ <combo_box.item
+ label="Image"
+ name="Image" />
+ <combo_box.item
+ label="Hair"
+ name="Hair" />
+ <combo_box.item
+ label="Female Head"
+ name="FemaleHead" />
+ <combo_box.item
+ label="Female Upper Body"
+ name="FemaleUpperBody" />
+ <combo_box.item
+ label="Female Lower Body"
+ name="FemaleLowerBody" />
+ <combo_box.item
+ label="Male Head"
+ name="MaleHead" />
+ <combo_box.item
+ label="Male Upper Body"
+ name="MaleUpperBody" />
+ <combo_box.item
+ label="Male Lower Body"
+ name="MaleLowerBody" />
+ <combo_box.item
+ label="Skirt"
+ name="Skirt" />
+ <combo_box.item
+ label="Sculpted Prim"
+ name="SculptedPrim" />
+ </combo_box>
+ <text
+ type="string"
+ length="1"
+ bottom="190"
+ follows="top|left"
+ layout="topleft"
+ left="10"
+ name="bad_image_text">
+ Unable to read image.
+
+Try saving image as 24 bit Targa (.tga).
+ </text>
+ <check_box
+ control_name="LosslessJ2CUpload"
+ enabled="false"
+ follows="bottom|left"
+ height="16"
+ label="Use lossless compression"
+ layout="topleft"
+ left_delta="2"
+ name="lossless_check"
+ top_pad="197"
+ width="280" />
+ <button
+ follows="bottom|right"
+ height="20"
+ label="Cancel"
+ layout="topleft"
+ left="165"
+ name="cancel_btn"
+ top="410"
+ width="125" />
+ <button
+ follows="bottom|left"
+ height="20"
+ label="Upload (L$[AMOUNT])"
+ layout="topleft"
+ left_delta="-150"
+ name="ok_btn"
+ top_delta="0"
+ width="125" />
+</floater>
diff --git a/indra/newview/skins/default/xui/en/floater_incoming_call.xml b/indra/newview/skins/default/xui/en/floater_incoming_call.xml
new file mode 100644
index 0000000000..2e7f5e6c42
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/floater_incoming_call.xml
@@ -0,0 +1,71 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<floater
+ can_close="false"
+ can_minimize="false"
+ can_tear_off="false"
+ height="200"
+ layout="topleft"
+ name="incoming call"
+ title="Unknown Person is calling"
+ width="240">
+ <floater.string
+ name="anonymous">
+ anonymous
+ </floater.string>
+ <floater.string
+ name="VoiceInviteP2P">
+ is calling.
+ </floater.string>
+ <floater.string
+ name="VoiceInviteAdHoc">
+ has joined a Voice Chat call with a conference chat.
+ </floater.string>
+ <avatar_icon
+ enabled="false"
+ follows="left|top"
+ height="36"
+ image_name="icon_avatar_online.tga"
+ layout="topleft"
+ left_delta="19"
+ top="35"
+ width="36" />
+ <text_editor
+ font="SansSerif"
+ height="64"
+ hide_border="true"
+ hide_scrollbar="true"
+ layout="topleft"
+ left="77"
+ max_length="2147483647"
+ name="caller name"
+ read_only="true"
+ top="21"
+ width="163"
+ word_wrap="true" />
+ <button
+ height="24"
+ label="Accept"
+ label_selected="Accept"
+ layout="topleft"
+ left="70"
+ name="Accept"
+ top="92"
+ width="100" />
+ <button
+ height="24"
+ label="Reject"
+ label_selected="Reject"
+ layout="topleft"
+ left_delta="0"
+ name="Reject"
+ top_pad="12"
+ width="100" />
+ <button
+ height="24"
+ label="Start IM"
+ layout="topleft"
+ left_delta="0"
+ name="Start IM"
+ top_pad="12"
+ width="100" />
+</floater>
diff --git a/indra/newview/skins/default/xui/en/floater_inspect.xml b/indra/newview/skins/default/xui/en/floater_inspect.xml
new file mode 100644
index 0000000000..b43cdca0d1
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/floater_inspect.xml
@@ -0,0 +1,72 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<floater
+ can_resize="true"
+ height="300"
+ layout="topleft"
+ min_height="300"
+ min_width="400"
+ name="inspect"
+ save_rect="true"
+ title="Inspect Objects"
+ width="400">
+ <floater.string
+ name="timeStamp">
+ [wkday,datetime,local] [mth,datetime,local] [day,datetime,local] [hour,datetime,local]:[min,datetime,local]:[second,datetime,local] [year,datetime,local]
+ </floater.string>
+ <scroll_list
+ bottom="270"
+ column_padding="0"
+ draw_heading="true"
+ follows="top|right|left|bottom"
+ layout="topleft"
+ left="10"
+ name="object_list"
+ right="-10"
+ tool_tip="Select an object from this list to highlight it in-world"
+ top="20">
+ <scroll_list.columns
+ dynamic_width="true"
+ label="Object Name"
+ name="object_name" />
+ <scroll_list.columns
+ dynamic_width="true"
+ label="Owner Name"
+ name="owner_name" />
+ <scroll_list.columns
+ dynamic_width="true"
+ label="Creator Name"
+ name="creator_name" />
+ <scroll_list.columns
+ label="Creation Date"
+ name="creation_date"
+ width="150" />
+ <scroll_list.commit_callback
+ function="Inspect.SelectObject" />
+ </scroll_list>
+ <button
+ follows="left|bottom"
+ height="20"
+ label="See Owner Profile..."
+ layout="topleft"
+ left_delta="0"
+ name="button owner"
+ tool_tip="See profile of the highlighted object&apos;s owner"
+ top_pad="5"
+ width="150">
+ <button.commit_callback
+ function="Inspect.OwnerProfilet" />
+ </button>
+ <button
+ follows="left|bottom"
+ height="20"
+ label="See Creator Profile..."
+ layout="topleft"
+ left_pad="10"
+ name="button creator"
+ tool_tip="See profile of the highlighted object&apos;s original creator"
+ top_delta="0"
+ width="150">
+ <button.commit_callback
+ function="Inspect.CreatorProfile" />
+ </button>
+</floater>
diff --git a/indra/newview/skins/default/xui/en/floater_inventory.xml b/indra/newview/skins/default/xui/en/floater_inventory.xml
new file mode 100644
index 0000000000..37c6cbf391
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/floater_inventory.xml
@@ -0,0 +1,424 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<floater
+ auto_tile="true"
+ can_resize="true"
+ height="563"
+ layout="topleft"
+ min_height="150"
+ min_width="240"
+ name="Inventory"
+ save_rect="true"
+ save_visibility="true"
+ single_instance="true"
+ title="Inventory"
+ width="467">
+ <floater.string
+ name="Title">
+ Inventory
+ </floater.string>
+ <floater.string
+ name="Items">
+ Items...
+ </floater.string>
+ <floater.string
+ name="Fetched">
+ Fetched
+ </floater.string>
+ <filter_editor
+ follows="left|top|right"
+ height="16"
+ label="Type here to search"
+ layout="topleft"
+ left="6"
+ name="inventory search editor"
+ top="34"
+ width="455" />
+ <tab_container
+ follows="left|top|right|bottom"
+ height="508"
+ layout="topleft"
+ left_delta="-4"
+ name="inventory filter tabs"
+ tab_position="top"
+ top_pad="4"
+ width="463">
+ <inventory_panel
+ follows="left|top|right|bottom"
+ height="491"
+ label="All Items"
+ layout="topleft"
+ left="1"
+ name="All Items"
+ top="16"
+ width="461" />
+ <inventory_panel
+ follows="left|top|right|bottom"
+ height="491"
+ label="Recent Items"
+ layout="topleft"
+ left_delta="0"
+ name="Recent Items"
+ top_delta="0"
+ width="461" />
+ </tab_container>
+ <menu_bar
+ bg_visible="false"
+ follows="left|top|right"
+ height="18"
+ layout="topleft"
+ left_delta="0"
+ mouse_opaque="false"
+ name="Inventory Menu"
+ top_delta="-38"
+ width="461">
+ <menu
+ height="101"
+ label="File"
+ layout="topleft"
+ left="0"
+ mouse_opaque="false"
+ name="File"
+ tear_off="true"
+ top="-117"
+ width="128">
+ <menu_item_call
+ label="Open"
+ layout="topleft"
+ name="Open">
+ <menu_item_call.on_click
+ function="Inventory.DoToSelected"
+ parameter="open" />
+ </menu_item_call>
+ <menu
+ create_jump_keys="true"
+ label="Upload"
+ layout="topleft"
+ name="upload"
+ tear_off="true">
+ <menu_item_call
+ label="Image (L$[COST])..."
+ layout="topleft"
+ name="Upload Image"
+ shortcut="control|U">
+ <menu_item_call.on_click
+ function="File.UploadImage"
+ parameter="" />
+ <menu_item_call.on_enable
+ function="File.EnableUpload" />
+ </menu_item_call>
+ <menu_item_call
+ label="Sound (L$[COST])..."
+ layout="topleft"
+ name="Upload Sound">
+ <menu_item_call.on_click
+ function="File.UploadSound"
+ parameter="" />
+ <menu_item_call.on_enable
+ function="File.EnableUpload" />
+ </menu_item_call>
+ <menu_item_call
+ label="Animation (L$[COST])..."
+ layout="topleft"
+ name="Upload Animation">
+ <menu_item_call.on_click
+ function="File.UploadAnim"
+ parameter="" />
+ <menu_item_call.on_enable
+ function="File.EnableUpload" />
+ </menu_item_call>
+ <menu_item_call
+ label="Bulk (L$[COST] per file)..."
+ layout="topleft"
+ name="Bulk Upload">
+ <menu_item_call.on_click
+ function="File.UploadBulk"
+ parameter="" />
+ </menu_item_call>
+ <menu_item_separator
+ layout="topleft" />
+ </menu>
+ <menu_item_separator
+ layout="topleft" />
+ <menu_item_call
+ label="New Window"
+ layout="topleft"
+ name="New Window">
+ <menu_item_call.on_click
+ function="Inventory.NewWindow" />
+ </menu_item_call>
+ <menu_item_separator
+ layout="topleft"
+ name="separator2" />
+ <menu_item_call
+ label="Show Filters"
+ layout="topleft"
+ name="Show Filters">
+ <menu_item_call.on_click
+ function="Inventory.ShowFilters" />
+ </menu_item_call>
+ <menu_item_call
+ label="Reset Filters"
+ layout="topleft"
+ name="Reset Current">
+ <menu_item_call.on_click
+ function="Inventory.ResetFilter" />
+ </menu_item_call>
+ <menu_item_call
+ label="Close All Folders"
+ layout="topleft"
+ name="Close All Folders">
+ <menu_item_call.on_click
+ function="Inventory.CloseAllFolders" />
+ </menu_item_call>
+ <menu_item_separator
+ layout="topleft"
+ name="separator3" />
+ <menu_item_call
+ label="Empty Trash"
+ layout="topleft"
+ name="Empty Trash">
+ <menu_item_call.on_click
+ function="Inventory.EmptyTrash" />
+ </menu_item_call>
+ <menu_item_call
+ label="Empty Lost And Found"
+ layout="topleft"
+ name="Empty Lost And Found">
+ <menu_item_call.on_click
+ function="Inventory.EmptyLostAndFound" />
+ </menu_item_call>
+ </menu>
+ <menu
+ height="121"
+ label="Create"
+ layout="topleft"
+ left="0"
+ mouse_opaque="false"
+ name="Create"
+ tear_off="true"
+ top="-201"
+ width="121">
+ <menu_item_call
+ label="New Folder"
+ layout="topleft"
+ name="New Folder">
+ <menu_item_call.on_click
+ function="Inventory.DoCreate"
+ parameter="category" />
+ </menu_item_call>
+ <menu_item_call
+ label="New Script"
+ layout="topleft"
+ name="New Script">
+ <menu_item_call.on_click
+ function="Inventory.DoCreate"
+ parameter="lsl" />
+ </menu_item_call>
+ <menu_item_call
+ label="New Note"
+ layout="topleft"
+ name="New Note">
+ <menu_item_call.on_click
+ function="Inventory.DoCreate"
+ parameter="notecard" />
+ </menu_item_call>
+ <menu_item_call
+ label="New Gesture"
+ layout="topleft"
+ name="New Gesture">
+ <menu_item_call.on_click
+ function="Inventory.DoCreate"
+ parameter="gesture" />
+ </menu_item_call>
+ <menu
+ height="175"
+ label="New Clothes"
+ layout="topleft"
+ left_delta="0"
+ mouse_opaque="false"
+ name="New Clothes"
+ top_pad="514"
+ width="125">
+ <menu_item_call
+ label="New Shirt"
+ layout="topleft"
+ name="New Shirt">
+ <menu_item_call.on_click
+ function="Inventory.DoCreate"
+ parameter="shirt" />
+ </menu_item_call>
+ <menu_item_call
+ label="New Pants"
+ layout="topleft"
+ name="New Pants">
+ <menu_item_call.on_click
+ function="Inventory.DoCreate"
+ parameter="pants" />
+ </menu_item_call>
+ <menu_item_call
+ label="New Shoes"
+ layout="topleft"
+ name="New Shoes">
+ <menu_item_call.on_click
+ function="Inventory.DoCreate"
+ parameter="shoes" />
+ </menu_item_call>
+ <menu_item_call
+ label="New Socks"
+ layout="topleft"
+ name="New Socks">
+ <menu_item_call.on_click
+ function="Inventory.DoCreate"
+ parameter="socks" />
+ </menu_item_call>
+ <menu_item_call
+ label="New Jacket"
+ layout="topleft"
+ name="New Jacket">
+ <menu_item_call.on_click
+ function="Inventory.DoCreate"
+ parameter="jacket" />
+ </menu_item_call>
+ <menu_item_call
+ label="New Skirt"
+ layout="topleft"
+ name="New Skirt">
+ <menu_item_call.on_click
+ function="Inventory.DoCreate"
+ parameter="skirt" />
+ </menu_item_call>
+ <menu_item_call
+ label="New Gloves"
+ layout="topleft"
+ name="New Gloves">
+ <menu_item_call.on_click
+ function="Inventory.DoCreate"
+ parameter="gloves" />
+ </menu_item_call>
+ <menu_item_call
+ label="New Undershirt"
+ layout="topleft"
+ name="New Undershirt">
+ <menu_item_call.on_click
+ function="Inventory.DoCreate"
+ parameter="undershirt" />
+ </menu_item_call>
+ <menu_item_call
+ label="New Underpants"
+ layout="topleft"
+ name="New Underpants">
+ <menu_item_call.on_click
+ function="Inventory.DoCreate"
+ parameter="underpants" />
+ </menu_item_call>
+ <menu_item_call
+ label="New Alpha"
+ layout="topleft"
+ name="New Alpha">
+ <menu_item_call.on_click
+ function="Inventory.DoCreate"
+ parameter="alpha" />
+ </menu_item_call>
+ <menu_item_call
+ label="New Tattoo"
+ layout="topleft"
+ name="New Tattoo">
+ <menu_item_call.on_click
+ function="Inventory.DoCreate"
+ parameter="tattoo" />
+ </menu_item_call>
+ </menu>
+ <menu
+ height="85"
+ label="New Body Parts"
+ layout="topleft"
+ left_delta="0"
+ mouse_opaque="false"
+ name="New Body Parts"
+ top_pad="514"
+ width="118">
+ <menu_item_call
+ label="New Shape"
+ layout="topleft"
+ name="New Shape">
+ <menu_item_call.on_click
+ function="Inventory.DoCreate"
+ parameter="shape" />
+ </menu_item_call>
+ <menu_item_call
+ label="New Skin"
+ layout="topleft"
+ name="New Skin">
+ <menu_item_call.on_click
+ function="Inventory.DoCreate"
+ parameter="skin" />
+ </menu_item_call>
+ <menu_item_call
+ label="New Hair"
+ layout="topleft"
+ name="New Hair">
+ <menu_item_call.on_click
+ function="Inventory.DoCreate"
+ parameter="hair" />
+ </menu_item_call>
+ <menu_item_call
+ label="New Eyes"
+ layout="topleft"
+ name="New Eyes">
+ <menu_item_call.on_click
+ function="Inventory.DoCreate"
+ parameter="eyes" />
+ </menu_item_call>
+ </menu>
+ </menu>
+ <menu
+ height="49"
+ label="Sort"
+ layout="topleft"
+ left="0"
+ mouse_opaque="false"
+ name="Sort"
+ tear_off="true"
+ top="-113"
+ width="118">
+ <menu_item_check
+ control_name="Inventory.SortByName"
+ label="By Name"
+ layout="topleft"
+ name="By Name">
+ <menu_item_check.on_click
+ function="Inventory.SetSortBy"
+ parameter="name" />
+ </menu_item_check>
+ <menu_item_check
+ control_name="Inventory.SortByDate"
+ label="By Date"
+ layout="topleft"
+ name="By Date">
+ <menu_item_check.on_click
+ function="Inventory.SetSortBy"
+ parameter="date" />
+ </menu_item_check>
+ <menu_item_separator
+ layout="topleft" />
+ <menu_item_check
+ control_name="Inventory.FoldersAlwaysByName"
+ label="Folders Always By Name"
+ layout="topleft"
+ name="Folders Always By Name">
+ <menu_item_check.on_click
+ function="Inventory.SetSortBy"
+ parameter="foldersalwaysbyname" />
+ </menu_item_check>
+ <menu_item_check
+ control_name="Inventory.SystemFoldersToTop"
+ label="System Folders To Top"
+ layout="topleft"
+ name="System Folders To Top">
+ <menu_item_check.on_click
+ function="Inventory.SetSortBy"
+ parameter="systemfolderstotop" />
+ </menu_item_check>
+ </menu>
+ </menu_bar>
+</floater>
diff --git a/indra/newview/skins/default/xui/en/floater_inventory_item_properties.xml b/indra/newview/skins/default/xui/en/floater_inventory_item_properties.xml
new file mode 100644
index 0000000000..467168ebd8
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/floater_inventory_item_properties.xml
@@ -0,0 +1,455 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<floater
+ auto_tile="true"
+ height="340"
+ layout="topleft"
+ name="item properties"
+ save_rect="true"
+ title="Inventory Item Properties"
+ width="350">
+ <floater.string
+ name="unknown">
+ (unknown)
+ </floater.string>
+ <floater.string
+ name="public">
+ (public)
+ </floater.string>
+ <floater.string
+ name="you_can">
+ You can:
+ </floater.string>
+ <floater.string
+ name="owner_can">
+ Owner can:
+ </floater.string>
+ <floater.string
+ name="acquiredDate">
+ [wkday,datetime,local] [mth,datetime,local] [day,datetime,local] [hour,datetime,local]:[min,datetime,local]:[second,datetime,local] [year,datetime,local]
+ </floater.string>
+ <icon
+ follows="top|right"
+ height="16"
+ image_name="icon_lock.tga"
+ layout="topleft"
+ left="294"
+ mouse_opaque="true"
+ name="IconLocked"
+ top="5"
+ width="16" />
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="10"
+ layout="topleft"
+ left="10"
+ name="LabelItemNameTitle"
+ top="25"
+ width="78">
+ Name:
+ </text>
+ <line_editor
+ border_style="line"
+ border_thickness="1"
+ follows="left|top|right"
+ height="16"
+ layout="topleft"
+ left_delta="78"
+ max_length="63"
+ name="LabelItemName"
+ top_delta="0"
+ width="252" />
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="10"
+ layout="topleft"
+ left="10"
+ name="LabelItemDescTitle"
+ top="45"
+ width="78">
+ Description:
+ </text>
+ <line_editor
+ border_style="line"
+ border_thickness="1"
+ follows="left|top|right"
+ height="16"
+ layout="topleft"
+ left_delta="78"
+ max_length="127"
+ name="LabelItemDesc"
+ top_delta="0"
+ width="252" />
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="16"
+ layout="topleft"
+ left="10"
+ name="LabelCreatorTitle"
+ top="65"
+ width="78">
+ Creator:
+ </text>
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="16"
+ layout="topleft"
+ left_delta="78"
+ name="LabelCreatorName"
+ top_delta="0"
+ width="200">
+ Nicole Linden
+ </text>
+ <button
+ follows="top|right"
+ font="SansSerifSmall"
+ height="16"
+ label="Profile..."
+ layout="topleft"
+ left_delta="174"
+ name="BtnCreator"
+ top_delta="0"
+ width="78" />
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="16"
+ layout="topleft"
+ left="10"
+ name="LabelOwnerTitle"
+ top="85"
+ width="78">
+ Owner:
+ </text>
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="16"
+ layout="topleft"
+ left_delta="78"
+ name="LabelOwnerName"
+ top_delta="0"
+ width="200">
+ Thrax Linden
+ </text>
+ <button
+ follows="top|right"
+ font="SansSerifSmall"
+ height="16"
+ label="Profile..."
+ layout="topleft"
+ left_delta="174"
+ name="BtnOwner"
+ top_delta="0"
+ width="78" />
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="16"
+ layout="topleft"
+ left="10"
+ name="LabelAcquiredTitle"
+ top="105"
+ width="78">
+ Acquired:
+ </text>
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="16"
+ layout="topleft"
+ left_delta="78"
+ name="LabelAcquiredDate"
+ top_delta="0"
+ width="252">
+ Wed May 24 12:50:46 2006
+ </text>
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="10"
+ layout="topleft"
+ left="10"
+ name="OwnerLabel"
+ top="125"
+ width="78">
+ You:
+ </text>
+ <check_box
+ height="16"
+ label="Edit"
+ layout="topleft"
+ left_pad="5"
+ name="CheckOwnerModify"
+ top_delta="0"
+ width="78" />
+ <check_box
+ height="16"
+ label="Copy"
+ layout="topleft"
+ left_delta="0"
+ name="CheckOwnerCopy"
+ top_pad="5"
+ width="88" />
+ <check_box
+ height="16"
+ label="Resell"
+ layout="topleft"
+ left_delta="0"
+ name="CheckOwnerTransfer"
+ top_pad="5"
+ width="106" />
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="10"
+ layout="topleft"
+ left="10"
+ name="AnyoneLabel"
+ top_pad="5"
+ width="78">
+ Anyone:
+ </text>
+ <check_box
+ height="16"
+ label="Copy"
+ layout="topleft"
+ left_pad="5"
+ name="CheckEveryoneCopy"
+ top_delta="0"
+ width="130" />
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="10"
+ layout="topleft"
+ left="10"
+ name="GroupLabel"
+ top_pad="5"
+ width="78">
+ Group:
+ </text>
+ <check_box
+ height="16"
+ label="Share"
+ layout="topleft"
+ left_pad="5"
+ name="CheckShareWithGroup"
+ top_delta="5"
+ width="106" />
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="10"
+ layout="topleft"
+ left="10"
+ name="NextOwnerLabel"
+ top_pad="5"
+ width="78">
+ Next owner:
+ </text>
+ <check_box
+ height="16"
+ label="Edit"
+ layout="topleft"
+ left_pad="5"
+ name="CheckNextOwnerModify"
+ top_delta="0"
+ width="78" />
+ <check_box
+ height="16"
+ label="Copy"
+ layout="topleft"
+ left_delta="0"
+ name="CheckNextOwnerCopy"
+ top_pad="5"
+ width="88" />
+ <check_box
+ height="16"
+ label="Resell"
+ layout="topleft"
+ left_delta="0"
+ name="CheckNextOwnerTransfer"
+ top_pad="5"
+ width="106" />
+ <check_box
+ height="16"
+ label="For Sale"
+ layout="topleft"
+ left="10"
+ name="CheckPurchase"
+ top_pad="5"
+ width="78" />
+ <combo_box
+ height="19"
+ left_pad="5"
+ layout="topleft"
+ follows="left|top"
+ name="combobox sale copy"
+ width="90">
+ <combo_box.item
+ label="Copy"
+ name="Copy"
+ value="Copy" />
+ <combo_box.item
+ label="Original"
+ name="Original"
+ value="Original" />
+ </combo_box>
+ <spinner
+ follows="left|top"
+ decimal_digits="0"
+ increment="1"
+ control_name="Edit Cost"
+ name="Edit Cost"
+ label="Price: L$"
+ label_width="60"
+ left="10"
+ width="180"
+ min_val="1"
+ height="19"
+ max_val="999999999"
+ top_pad="5"/>
+
+ <!--line_editor
+ border_style="line"
+ border_thickness="1"
+ follows="left|top|right"
+ height="16"
+ layout="topleft"
+ left_pad="5"
+ max_length="25"
+ name="EditPrice"
+ top_delta="0"
+ width="242" /-->
+
+ <!--text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="10"
+ layout="topleft"
+ left="10"
+ name="BaseMaskDebug"
+ top="155"
+ width="330">
+ B:
+ </text>
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="10"
+ layout="topleft"
+ left_delta="60"
+ name="OwnerMaskDebug"
+ top_delta="0"
+ width="270">
+ O:
+ </text>
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="10"
+ layout="topleft"
+ left_delta="60"
+ name="GroupMaskDebug"
+ top_delta="0"
+ width="210">
+ G:
+ </text>
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="10"
+ layout="topleft"
+ left_delta="60"
+ name="EveryoneMaskDebug"
+ top_delta="0"
+ width="150">
+ E:
+ </text>
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="10"
+ layout="topleft"
+ left_delta="60"
+ name="NextMaskDebug"
+ top_delta="0"
+ width="90">
+ N:
+ </text-->
+ <!--text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="10"
+ layout="topleft"
+ left="10"
+ name="SaleLabel"
+ top_pad="5"
+ width="330">
+ Mark Item:
+ </text-->
+
+
+ <!--radio_group
+ draw_border="false"
+ follows="left|top|right"
+ height="16"
+ layout="topleft"
+ left_delta="78"
+ name="RadioSaleType"
+ top_delta="0"
+ width="252">
+ <radio_item
+ height="16"
+ label="Original"
+ layout="topleft"
+ left="0"
+ name="radio"
+ top="0"
+ width="70" />
+ <radio_item
+ height="16"
+ label="Copy"
+ layout="topleft"
+ left_delta="60"
+ name="radio2"
+ top_delta="0"
+ width="70" />
+ </radio_group-->
+
+ <!--text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="16"
+ layout="topleft"
+ left="10"
+ name="TextPrice"
+ top_pad="5"
+ width="78">
+ Price: L$
+ </text-->
+
+</floater>
diff --git a/indra/newview/skins/default/xui/en/floater_inventory_view_finder.xml b/indra/newview/skins/default/xui/en/floater_inventory_view_finder.xml
new file mode 100644
index 0000000000..f07a146471
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/floater_inventory_view_finder.xml
@@ -0,0 +1,281 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<floater
+ can_minimize="false"
+ height="408"
+ layout="topleft"
+ name="Inventory Finder"
+ title="inventory_recent_items"
+ width="280">
+ <icon
+ height="16"
+ image_name="inv_item_animation.tga"
+ layout="topleft"
+ left="8"
+ mouse_opaque="true"
+ name="icon_animation"
+ top="22"
+ width="16" />
+ <check_box
+ height="16"
+ label="Animation"
+ layout="topleft"
+ left_pad="2"
+ name="check_animation"
+ top_delta="0"
+ width="126" />
+ <icon
+ height="16"
+ image_name="inv_item_callingcard_online.tga"
+ layout="topleft"
+ left="8"
+ mouse_opaque="true"
+ name="icon_calling_card"
+ top="42"
+ width="16" />
+ <check_box
+ height="16"
+ label="Calling Cards"
+ layout="topleft"
+ left_pad="2"
+ name="check_calling_card"
+ top_delta="0"
+ width="126" />
+ <icon
+ height="16"
+ image_name="inv_item_shirt.tga"
+ layout="topleft"
+ left="8"
+ mouse_opaque="true"
+ name="icon_clothing"
+ top="62"
+ width="16" />
+ <check_box
+ height="16"
+ label="Clothing"
+ layout="topleft"
+ left_pad="2"
+ name="check_clothing"
+ top_delta="0"
+ width="126" />
+ <icon
+ height="16"
+ image_name="inv_item_gesture.tga"
+ layout="topleft"
+ left="8"
+ mouse_opaque="true"
+ name="icon_gesture"
+ top="82"
+ width="16" />
+ <check_box
+ height="16"
+ label="Gestures"
+ layout="topleft"
+ left_pad="2"
+ name="check_gesture"
+ top_delta="0"
+ width="126" />
+ <icon
+ height="16"
+ image_name="inv_item_landmark_visited.tga"
+ layout="topleft"
+ left="8"
+ mouse_opaque="true"
+ name="icon_landmark"
+ top="102"
+ width="16" />
+ <check_box
+ height="16"
+ label="Landmarks"
+ layout="topleft"
+ left_pad="2"
+ name="check_landmark"
+ top_delta="0"
+ width="126" />
+ <icon
+ height="16"
+ image_name="inv_item_notecard.tga"
+ layout="topleft"
+ left="8"
+ mouse_opaque="true"
+ name="icon_notecard"
+ top="122"
+ width="16" />
+ <check_box
+ height="16"
+ label="Notecards"
+ layout="topleft"
+ left_pad="2"
+ name="check_notecard"
+ top_delta="0"
+ width="126" />
+ <icon
+ height="16"
+ image_name="inv_item_object.tga"
+ layout="topleft"
+ left="8"
+ mouse_opaque="true"
+ name="icon_object"
+ top="142"
+ width="16" />
+ <check_box
+ height="16"
+ label="Objects"
+ layout="topleft"
+ left_pad="2"
+ name="check_object"
+ top_delta="0"
+ width="126" />
+ <icon
+ height="16"
+ image_name="inv_item_script.tga"
+ layout="topleft"
+ left="8"
+ mouse_opaque="true"
+ name="icon_script"
+ top="162"
+ width="16" />
+ <check_box
+ height="16"
+ label="Scripts"
+ layout="topleft"
+ left_pad="2"
+ name="check_script"
+ top_delta="0"
+ width="126" />
+ <icon
+ height="16"
+ image_name="inv_item_sound.tga"
+ layout="topleft"
+ left="8"
+ mouse_opaque="true"
+ name="icon_sound"
+ top="182"
+ width="16" />
+ <check_box
+ height="16"
+ label="Sounds"
+ layout="topleft"
+ left_pad="2"
+ name="check_sound"
+ top_delta="0"
+ width="126" />
+ <icon
+ height="16"
+ image_name="inv_item_texture.tga"
+ layout="topleft"
+ left="8"
+ mouse_opaque="true"
+ name="icon_texture"
+ top="202"
+ width="16" />
+ <check_box
+ height="16"
+ label="Textures"
+ layout="topleft"
+ left_pad="2"
+ name="check_texture"
+ top_delta="0"
+ width="126" />
+ <icon
+ height="16"
+ image_name="inv_item_snapshot.tga"
+ layout="topleft"
+ left="8"
+ mouse_opaque="true"
+ name="icon_snapshot"
+ top="222"
+ width="16" />
+ <check_box
+ height="16"
+ label="Snapshots"
+ layout="topleft"
+ left_pad="2"
+ name="check_snapshot"
+ top_delta="0"
+ width="126" />
+ <button
+ follows="left|top"
+ height="20"
+ label="All"
+ label_selected="All"
+ layout="topleft"
+ left="8"
+ name="All"
+ top="242"
+ width="100" />
+ <button
+ follows="left|top"
+ height="20"
+ label="None"
+ label_selected="None"
+ layout="topleft"
+ left_delta="0"
+ name="None"
+ top_pad="4"
+ width="100" />
+ <check_box
+ height="16"
+ label="Always show folders"
+ layout="topleft"
+ left_delta="0"
+ name="check_show_empty"
+ top_pad="4"
+ width="144" />
+ <check_box
+ height="16"
+ label="Since Logoff"
+ layout="topleft"
+ left_delta="0"
+ name="check_since_logoff"
+ top_pad="4"
+ width="144" />
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ halign="center"
+ height="12"
+ layout="topleft"
+ left_delta="0"
+ name="- OR -"
+ top_delta="16"
+ width="144">
+ - OR -
+ </text>
+ <spinner
+ follows="left|top"
+ height="16"
+ increment="1"
+ initial_value="0"
+ label="Hours Ago"
+ label_width="64"
+ layout="topleft"
+ left_delta="0"
+ max_val="240000"
+ name="spin_hours_ago"
+ top_pad="4"
+ width="144" />
+ <spinner
+ follows="left|top"
+ height="16"
+ increment="1"
+ initial_value="0"
+ label="Days Ago"
+ label_width="64"
+ layout="topleft"
+ left_delta="0"
+ max_val="10000"
+ name="spin_days_ago"
+ top_pad="4"
+ width="144" />
+ <button
+ follows="top|right"
+ height="20"
+ label="Close"
+ label_selected="Close"
+ layout="topleft"
+ name="Close"
+ right="-6"
+ top="382"
+ width="76" />
+</floater>
diff --git a/indra/newview/skins/default/xui/en/floater_joystick.xml b/indra/newview/skins/default/xui/en/floater_joystick.xml
new file mode 100644
index 0000000000..b9c1b08c68
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/floater_joystick.xml
@@ -0,0 +1,862 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<floater
+ height="500"
+ layout="topleft"
+ name="Joystick"
+ title="Joystick Configuration"
+ width="550">
+ <floater.string
+ name="NoDevice">
+ no device detected
+ </floater.string>
+ <check_box
+ bottom="38"
+ control_name="JoystickEnabled"
+ halign="left"
+ label="Enable Joystick:"
+ layout="topleft"
+ left="14"
+ name="enable_joystick"
+ width="60" />
+ <text
+ bottom="32"
+ layout="topleft"
+ left="120"
+ name="joystick_type"
+ width="380" />
+ <spinner
+ bottom="48"
+ control_name="JoystickAxis1"
+ decimal_digits="0"
+ increment="1"
+ label="X Axis Mapping"
+ label_width="100"
+ layout="topleft"
+ left="20"
+ max_val="5"
+ min_val="-1"
+ name="JoystickAxis1"
+ width="140" />
+ <spinner
+ bottom="48"
+ control_name="JoystickAxis2"
+ decimal_digits="0"
+ increment="1"
+ label="Y Axis Mapping"
+ label_width="100"
+ layout="topleft"
+ left="190"
+ max_val="5"
+ min_val="-1"
+ name="JoystickAxis2"
+ width="140" />
+ <spinner
+ bottom="48"
+ control_name="JoystickAxis0"
+ decimal_digits="0"
+ increment="1"
+ label="Z Axis Mapping"
+ label_width="100"
+ layout="topleft"
+ left="360"
+ max_val="5"
+ min_val="-1"
+ name="JoystickAxis0"
+ width="140" />
+ <spinner
+ bottom="68"
+ control_name="JoystickAxis4"
+ decimal_digits="0"
+ increment="1"
+ label="Pitch Mapping"
+ label_width="100"
+ layout="topleft"
+ left="20"
+ max_val="5"
+ min_val="-1"
+ name="JoystickAxis4"
+ width="140" />
+ <spinner
+ bottom="68"
+ control_name="JoystickAxis5"
+ decimal_digits="0"
+ increment="1"
+ label="Yaw Mapping"
+ label_width="100"
+ layout="topleft"
+ left="190"
+ max_val="5"
+ min_val="-1"
+ name="JoystickAxis5"
+ width="140" />
+ <spinner
+ bottom="68"
+ control_name="JoystickAxis3"
+ decimal_digits="0"
+ increment="1"
+ label="Roll Mapping"
+ label_width="100"
+ layout="topleft"
+ left="360"
+ max_val="5"
+ min_val="-1"
+ name="JoystickAxis3"
+ width="140" />
+ <spinner
+ bottom="88"
+ control_name="JoystickAxis6"
+ decimal_digits="0"
+ increment="1"
+ label="Zoom Mapping"
+ label_width="100"
+ layout="topleft"
+ left="20"
+ max_val="5"
+ min_val="-1"
+ name="JoystickAxis6"
+ width="140" />
+ <check_box
+ bottom_delta="18"
+ control_name="ZoomDirect"
+ label="Direct Zoom"
+ layout="topleft"
+ left="185"
+ name="ZoomDirect"
+ width="60" />
+ <check_box
+ bottom_delta="0"
+ control_name="Cursor3D"
+ label="3D Cursor"
+ layout="topleft"
+ left="310"
+ name="Cursor3D"
+ width="60" />
+ <check_box
+ bottom_delta="0"
+ control_name="AutoLeveling"
+ label="Auto Level"
+ layout="topleft"
+ left="420"
+ name="AutoLeveling"
+ width="60" />
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ halign="right"
+ height="10"
+ layout="topleft"
+ left="12"
+ mouse_opaque="false"
+ name="Control Modes:"
+ top="110"
+ width="102">
+ Control Modes:
+ </text>
+ <check_box
+ bottom="127"
+ control_name="JoystickAvatarEnabled"
+ halign="center"
+ label="Avatar"
+ layout="topleft"
+ left="125"
+ name="JoystickAvatarEnabled"
+ width="60" />
+ <check_box
+ bottom="127"
+ control_name="JoystickBuildEnabled"
+ halign="center"
+ label="Build"
+ layout="topleft"
+ left="194"
+ name="JoystickBuildEnabled"
+ width="60" />
+ <check_box
+ bottom="127"
+ control_name="JoystickFlycamEnabled"
+ halign="center"
+ label="Flycam"
+ layout="topleft"
+ left="262"
+ name="JoystickFlycamEnabled"
+ width="60" />
+ <stat_view
+ height="250"
+ label="Joystick Monitor"
+ layout="topleft"
+ left="340"
+ name="axis_view"
+ show_label="true"
+ top="142"
+ width="200">
+ <stat_bar
+ bar_max="2"
+ bar_min="-2"
+ height="0"
+ label="Axis 0"
+ label_spacing="1"
+ layout="topleft"
+ left="0"
+ name="axis0"
+ tick_spacing="0.5"
+ top="20"
+ width="0" />
+ <stat_bar
+ bar_max="2"
+ bar_min="-2"
+ label="Axis 1"
+ label_spacing="1"
+ layout="topleft"
+ name="axis1"
+ tick_spacing="0.5" />
+ <stat_bar
+ bar_max="2"
+ bar_min="-2"
+ label="Axis 2"
+ label_spacing="1"
+ layout="topleft"
+ name="axis2"
+ tick_spacing="0.5" />
+ <stat_bar
+ bar_max="2"
+ bar_min="-2"
+ label="Axis 3"
+ label_spacing="1"
+ layout="topleft"
+ name="axis3"
+ tick_spacing="0.5" />
+ <stat_bar
+ bar_max="2"
+ bar_min="-2"
+ label="Axis 4"
+ label_spacing="1"
+ layout="topleft"
+ name="axis4"
+ tick_spacing="0.5" />
+ <stat_bar
+ bar_max="2"
+ bar_min="-2"
+ label="Axis 5"
+ label_spacing="1"
+ layout="topleft"
+ name="axis5"
+ tick_spacing="0.5" />
+ </stat_view>
+ <text
+ type="string"
+ length="1"
+ bottom="144"
+ halign="right"
+ layout="topleft"
+ left="20"
+ name="XScale"
+ width="94">
+ X Scale
+ </text>
+ <spinner
+ bottom="144"
+ control_name="AvatarAxisScale1"
+ decimal_digits="2"
+ label_width="0"
+ layout="topleft"
+ left="125"
+ max_val="50"
+ min_val="-50"
+ name="AvatarAxisScale1"
+ width="56" />
+ <spinner
+ bottom="144"
+ control_name="BuildAxisScale1"
+ decimal_digits="2"
+ label_width="0"
+ layout="topleft"
+ left="195"
+ max_val="1024"
+ min_val="-1024"
+ name="BuildAxisScale1"
+ width="56" />
+ <spinner
+ bottom="144"
+ control_name="FlycamAxisScale1"
+ decimal_digits="2"
+ label_width="0"
+ layout="topleft"
+ left="265"
+ max_val="1024"
+ min_val="-1024"
+ name="FlycamAxisScale1"
+ width="56" />
+ <text
+ type="string"
+ length="1"
+ bottom="164"
+ halign="right"
+ layout="topleft"
+ left="20"
+ name="YScale"
+ width="94">
+ Y Scale
+ </text>
+ <spinner
+ bottom="164"
+ control_name="AvatarAxisScale2"
+ decimal_digits="2"
+ label_width="0"
+ layout="topleft"
+ left="125"
+ max_val="50"
+ min_val="-50"
+ name="AvatarAxisScale2"
+ width="56" />
+ <spinner
+ bottom="164"
+ control_name="BuildAxisScale2"
+ decimal_digits="2"
+ label_width="0"
+ layout="topleft"
+ left="195"
+ max_val="1024"
+ min_val="-1024"
+ name="BuildAxisScale2"
+ width="56" />
+ <spinner
+ bottom="164"
+ control_name="FlycamAxisScale2"
+ decimal_digits="2"
+ label_width="0"
+ layout="topleft"
+ left="265"
+ max_val="1024"
+ min_val="-1024"
+ name="FlycamAxisScale2"
+ width="56" />
+ <text
+ type="string"
+ length="1"
+ bottom="184"
+ halign="right"
+ layout="topleft"
+ left="20"
+ name="ZScale"
+ width="94">
+ Z Scale
+ </text>
+ <spinner
+ bottom="184"
+ control_name="AvatarAxisScale0"
+ decimal_digits="2"
+ label_width="0"
+ layout="topleft"
+ left="125"
+ max_val="50"
+ min_val="-50"
+ name="AvatarAxisScale0"
+ width="56" />
+ <spinner
+ bottom="184"
+ control_name="BuildAxisScale0"
+ decimal_digits="2"
+ label_width="0"
+ layout="topleft"
+ left="195"
+ max_val="1024"
+ min_val="-1024"
+ name="BuildAxisScale0"
+ width="56" />
+ <spinner
+ bottom="184"
+ control_name="FlycamAxisScale0"
+ decimal_digits="2"
+ label_width="0"
+ layout="topleft"
+ left="265"
+ max_val="1024"
+ min_val="-1024"
+ name="FlycamAxisScale0"
+ width="56" />
+ <text
+ type="string"
+ length="1"
+ bottom="204"
+ halign="right"
+ layout="topleft"
+ left="20"
+ name="PitchScale"
+ width="94">
+ Pitch Scale
+ </text>
+ <spinner
+ bottom="204"
+ control_name="AvatarAxisScale4"
+ decimal_digits="2"
+ label_width="0"
+ layout="topleft"
+ left="125"
+ max_val="1024"
+ min_val="-1024"
+ name="AvatarAxisScale4"
+ width="56" />
+ <spinner
+ bottom="204"
+ control_name="BuildAxisScale4"
+ decimal_digits="2"
+ label_width="0"
+ layout="topleft"
+ left="195"
+ max_val="1024"
+ min_val="-1024"
+ name="BuildAxisScale4"
+ width="56" />
+ <spinner
+ bottom="204"
+ control_name="FlycamAxisScale4"
+ decimal_digits="2"
+ label_width="0"
+ layout="topleft"
+ left="265"
+ max_val="1024"
+ min_val="-1024"
+ name="FlycamAxisScale4"
+ width="56" />
+ <text
+ type="string"
+ length="1"
+ bottom="224"
+ halign="right"
+ layout="topleft"
+ left="20"
+ name="YawScale"
+ width="94">
+ Yaw Scale
+ </text>
+ <spinner
+ bottom="224"
+ control_name="AvatarAxisScale5"
+ decimal_digits="2"
+ label_width="0"
+ layout="topleft"
+ left="125"
+ max_val="1024"
+ min_val="-1024"
+ name="AvatarAxisScale5"
+ width="56" />
+ <spinner
+ bottom="224"
+ control_name="BuildAxisScale5"
+ decimal_digits="2"
+ label_width="0"
+ layout="topleft"
+ left="195"
+ max_val="1024"
+ min_val="-1024"
+ name="BuildAxisScale5"
+ width="56" />
+ <spinner
+ bottom="224"
+ control_name="FlycamAxisScale5"
+ decimal_digits="2"
+ label_width="0"
+ layout="topleft"
+ left="265"
+ max_val="1024"
+ min_val="-1024"
+ name="FlycamAxisScale5"
+ width="56" />
+ <text
+ type="string"
+ length="1"
+ bottom="244"
+ halign="right"
+ layout="topleft"
+ left="20"
+ name="RollScale"
+ width="94">
+ Roll Scale
+ </text>
+ <spinner
+ bottom="244"
+ control_name="BuildAxisScale3"
+ decimal_digits="2"
+ label_width="0"
+ layout="topleft"
+ left="195"
+ max_val="1024"
+ min_val="-1024"
+ name="BuildAxisScale3"
+ width="56" />
+ <spinner
+ bottom="244"
+ control_name="FlycamAxisScale3"
+ decimal_digits="2"
+ label_width="0"
+ layout="topleft"
+ left="265"
+ max_val="1024"
+ min_val="-1024"
+ name="FlycamAxisScale3"
+ width="56" />
+ <text
+ type="string"
+ length="1"
+ bottom="274"
+ halign="right"
+ layout="topleft"
+ left="20"
+ name="XDeadZone"
+ width="94">
+ X Dead Zone
+ </text>
+ <spinner
+ bottom="274"
+ control_name="AvatarAxisDeadZone1"
+ decimal_digits="2"
+ increment="0.01"
+ label_width="0"
+ layout="topleft"
+ left="125"
+ name="AvatarAxisDeadZone1"
+ width="56" />
+ <spinner
+ bottom="274"
+ control_name="BuildAxisDeadZone1"
+ decimal_digits="2"
+ increment="0.01"
+ label_width="0"
+ layout="topleft"
+ left="195"
+ name="BuildAxisDeadZone1"
+ width="56" />
+ <spinner
+ bottom="274"
+ control_name="FlycamAxisDeadZone1"
+ decimal_digits="2"
+ increment="0.01"
+ label_width="0"
+ layout="topleft"
+ left="265"
+ name="FlycamAxisDeadZone1"
+ width="56" />
+ <text
+ type="string"
+ length="1"
+ bottom="294"
+ halign="right"
+ layout="topleft"
+ left="20"
+ name="YDeadZone"
+ width="94">
+ Y Dead Zone
+ </text>
+ <spinner
+ bottom="294"
+ control_name="AvatarAxisDeadZone2"
+ decimal_digits="2"
+ increment="0.01"
+ label_width="0"
+ layout="topleft"
+ left="125"
+ name="AvatarAxisDeadZone2"
+ width="56" />
+ <spinner
+ bottom="294"
+ control_name="BuildAxisDeadZone2"
+ decimal_digits="2"
+ increment="0.01"
+ label_width="0"
+ layout="topleft"
+ left="195"
+ name="BuildAxisDeadZone2"
+ width="56" />
+ <spinner
+ bottom="294"
+ control_name="FlycamAxisDeadZone2"
+ decimal_digits="2"
+ increment="0.01"
+ label_width="0"
+ layout="topleft"
+ left="265"
+ name="FlycamAxisDeadZone2"
+ width="56" />
+ <text
+ type="string"
+ length="1"
+ bottom="314"
+ halign="right"
+ layout="topleft"
+ left="20"
+ name="ZDeadZone"
+ width="94">
+ Z Dead Zone
+ </text>
+ <spinner
+ bottom="314"
+ control_name="AvatarAxisDeadZone0"
+ decimal_digits="2"
+ increment="0.01"
+ label_width="0"
+ layout="topleft"
+ left="125"
+ name="AvatarAxisDeadZone0"
+ width="56" />
+ <spinner
+ bottom="314"
+ control_name="BuildAxisDeadZone0"
+ decimal_digits="2"
+ increment="0.01"
+ label_width="0"
+ layout="topleft"
+ left="195"
+ name="BuildAxisDeadZone0"
+ width="56" />
+ <spinner
+ bottom="314"
+ control_name="FlycamAxisDeadZone0"
+ decimal_digits="2"
+ increment="0.01"
+ label_width="0"
+ layout="topleft"
+ left="265"
+ name="FlycamAxisDeadZone0"
+ width="56" />
+ <text
+ type="string"
+ length="1"
+ bottom="334"
+ halign="right"
+ layout="topleft"
+ left="20"
+ name="PitchDeadZone"
+ width="94">
+ Pitch Dead Zone
+ </text>
+ <spinner
+ bottom="334"
+ control_name="AvatarAxisDeadZone4"
+ decimal_digits="2"
+ increment="0.01"
+ label_width="0"
+ layout="topleft"
+ left="125"
+ name="AvatarAxisDeadZone4"
+ width="56" />
+ <spinner
+ bottom="334"
+ control_name="BuildAxisDeadZone4"
+ decimal_digits="2"
+ increment="0.01"
+ label_width="0"
+ layout="topleft"
+ left="195"
+ name="BuildAxisDeadZone4"
+ width="56" />
+ <spinner
+ bottom="334"
+ control_name="FlycamAxisDeadZone4"
+ decimal_digits="2"
+ increment="0.01"
+ label_width="0"
+ layout="topleft"
+ left="265"
+ name="FlycamAxisDeadZone4"
+ width="56" />
+ <text
+ type="string"
+ length="1"
+ bottom="354"
+ halign="right"
+ layout="topleft"
+ left="20"
+ name="YawDeadZone"
+ width="94">
+ Yaw Dead Zone
+ </text>
+ <spinner
+ bottom="354"
+ control_name="AvatarAxisDeadZone5"
+ decimal_digits="2"
+ increment="0.01"
+ label_width="0"
+ layout="topleft"
+ left="125"
+ name="AvatarAxisDeadZone5"
+ width="56" />
+ <spinner
+ bottom="354"
+ control_name="BuildAxisDeadZone5"
+ decimal_digits="2"
+ increment="0.01"
+ label_width="0"
+ layout="topleft"
+ left="195"
+ name="BuildAxisDeadZone5"
+ width="56" />
+ <spinner
+ bottom="354"
+ control_name="FlycamAxisDeadZone5"
+ decimal_digits="2"
+ increment="0.01"
+ label_width="0"
+ layout="topleft"
+ left="265"
+ name="FlycamAxisDeadZone5"
+ width="56" />
+ <text
+ type="string"
+ length="1"
+ bottom="374"
+ halign="right"
+ layout="topleft"
+ left="20"
+ name="RollDeadZone"
+ width="94">
+ Roll Dead Zone
+ </text>
+ <spinner
+ bottom="374"
+ control_name="BuildAxisDeadZone3"
+ decimal_digits="2"
+ increment="0.01"
+ label_width="0"
+ layout="topleft"
+ left="195"
+ name="BuildAxisDeadZone3"
+ width="56" />
+ <spinner
+ bottom="374"
+ control_name="FlycamAxisDeadZone3"
+ decimal_digits="2"
+ increment="0.01"
+ label_width="0"
+ layout="topleft"
+ left="265"
+ name="FlycamAxisDeadZone3"
+ width="56" />
+ <text
+ type="string"
+ length="1"
+ bottom="402"
+ halign="right"
+ layout="topleft"
+ left="20"
+ name="Feathering"
+ width="94">
+ Feathering
+ </text>
+ <slider
+ control_name="AvatarFeathering"
+ decimal_digits="0"
+ follows="left|top"
+ height="16"
+ increment="1"
+ initial_value="0.7"
+ layout="topleft"
+ left="116"
+ max_val="32"
+ min_val="1"
+ name="AvatarFeathering"
+ show_text="false"
+ top="402"
+ width="73" />
+ <slider
+ control_name="BuildFeathering"
+ decimal_digits="0"
+ follows="left|top"
+ height="16"
+ increment="1"
+ initial_value="0.7"
+ layout="topleft"
+ left_delta="70"
+ max_val="32"
+ min_val="1"
+ name="BuildFeathering"
+ show_text="false"
+ top_delta="0"
+ width="73" />
+ <slider
+ control_name="FlycamFeathering"
+ decimal_digits="0"
+ follows="left|top"
+ height="16"
+ increment="1"
+ initial_value="0.7"
+ layout="topleft"
+ left_delta="70"
+ max_val="32"
+ min_val="1"
+ name="FlycamFeathering"
+ show_text="false"
+ top_delta="0"
+ width="73" />
+ <text
+ type="string"
+ length="1"
+ bottom="430"
+ halign="right"
+ layout="topleft"
+ left="20"
+ name="ZoomScale2"
+ width="94">
+ Zoom Scale
+ </text>
+ <spinner
+ bottom="430"
+ control_name="FlycamAxisScale6"
+ decimal_digits="2"
+ label_width="0"
+ layout="topleft"
+ left="265"
+ max_val="1024"
+ min_val="-1024"
+ name="FlycamAxisScale6"
+ width="56" />
+ <text
+ type="string"
+ length="1"
+ bottom="450"
+ halign="right"
+ layout="topleft"
+ left="20"
+ name="ZoomDeadZone"
+ width="94">
+ Zoom Dead Zone
+ </text>
+ <spinner
+ bottom="450"
+ control_name="FlycamAxisDeadZone6"
+ decimal_digits="2"
+ increment="0.01"
+ label_width="0"
+ layout="topleft"
+ left="265"
+ name="FlycamAxisDeadZone6"
+ width="56" />
+ <button
+ follows="left|top"
+ height="22"
+ label="SpaceNavigator Defaults"
+ layout="topleft"
+ left="340"
+ name="SpaceNavigatorDefaults"
+ top="429"
+ width="184" />
+ <button
+ follows="right|bottom"
+ height="20"
+ label="OK"
+ label_selected="OK"
+ layout="topleft"
+ left_delta="0"
+ name="ok_btn"
+ top_pad="9"
+ width="90" />
+ <button
+ follows="right|bottom"
+ height="20"
+ label="Cancel"
+ label_selected="Cancel"
+ layout="topleft"
+ left_pad="4"
+ name="cancel_btn"
+ top_delta="0"
+ width="90" />
+</floater>
diff --git a/indra/newview/skins/default/xui/en/floater_lagmeter.xml b/indra/newview/skins/default/xui/en/floater_lagmeter.xml
new file mode 100644
index 0000000000..a326cd006f
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/floater_lagmeter.xml
@@ -0,0 +1,346 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<floater
+ height="150"
+ layout="topleft"
+ name="floater_lagmeter"
+ save_rect="true"
+ title="Lag Meter"
+ width="350">
+ <floater.string
+ name="max_title_msg">
+ Lag Meter
+ </floater.string>
+ <floater.string
+ name="max_width_px">
+ 360
+ </floater.string>
+ <floater.string
+ name="min_title_msg">
+ Lag
+ </floater.string>
+ <floater.string
+ name="min_width_px">
+ 90
+ </floater.string>
+ <floater.string
+ name="client_text_msg">
+ Client
+ </floater.string>
+ <floater.string
+ name="client_frame_rate_critical_fps">
+ 10
+ </floater.string>
+ <floater.string
+ name="client_frame_rate_warning_fps">
+ 15
+ </floater.string>
+ <floater.string
+ name="client_frame_time_window_bg_msg">
+ Normal, window in background
+ </floater.string>
+ <floater.string
+ name="client_frame_time_critical_msg">
+ Client frame rate below [CLIENT_FRAME_RATE_CRITICAL]
+ </floater.string>
+ <floater.string
+ name="client_frame_time_warning_msg">
+ Client frame rate between [CLIENT_FRAME_RATE_CRITICAL] and [CLIENT_FRAME_RATE_WARNING]
+ </floater.string>
+ <floater.string
+ name="client_frame_time_normal_msg">
+ Normal
+ </floater.string>
+ <floater.string
+ name="client_draw_distance_cause_msg">
+ Possible cause: Draw distance set too high
+ </floater.string>
+ <floater.string
+ name="client_texture_loading_cause_msg">
+ Possible cause: Images loading
+ </floater.string>
+ <floater.string
+ name="client_texture_memory_cause_msg">
+ Possible cause: Too many images in memory
+ </floater.string>
+ <floater.string
+ name="client_complex_objects_cause_msg">
+ Possible cause: Too many complex objects in scene
+ </floater.string>
+ <floater.string
+ name="network_text_msg">
+ Network
+ </floater.string>
+ <floater.string
+ name="network_packet_loss_critical_pct">
+ 10
+ </floater.string>
+ <floater.string
+ name="network_packet_loss_warning_pct">
+ 5
+ </floater.string>
+ <floater.string
+ name="network_packet_loss_critical_msg">
+ Connection is dropping over [NETWORK_PACKET_LOSS_CRITICAL]% of packets
+ </floater.string>
+ <floater.string
+ name="network_packet_loss_warning_msg">
+ Connection is dropping [NETWORK_PACKET_LOSS_WARNING]%-[NETWORK_PACKET_LOSS_CRITICAL]% of packets
+ </floater.string>
+ <floater.string
+ name="network_performance_normal_msg">
+ Normal
+ </floater.string>
+ <floater.string
+ name="network_ping_critical_ms">
+ 600
+ </floater.string>
+ <floater.string
+ name="network_ping_warning_ms">
+ 300
+ </floater.string>
+ <floater.string
+ name="network_ping_critical_msg">
+ Connection ping time is over [NETWORK_PING_CRITICAL] ms
+ </floater.string>
+ <floater.string
+ name="network_ping_warning_msg">
+ Connection ping time is [NETWORK_PING_WARNING]-[NETWORK_PING_CRITICAL] ms
+ </floater.string>
+ <floater.string
+ name="network_packet_loss_cause_msg">
+ Possible bad connection or &apos;Bandwidth&apos; pref too high.
+ </floater.string>
+ <floater.string
+ name="network_ping_cause_msg">
+ Possible bad connection or file-sharing app.
+ </floater.string>
+ <floater.string
+ name="server_text_msg">
+ Server
+ </floater.string>
+ <floater.string
+ name="server_frame_rate_critical_fps">
+ 20
+ </floater.string>
+ <floater.string
+ name="server_frame_rate_warning_fps">
+ 30
+ </floater.string>
+ <floater.string
+ name="server_single_process_max_time_ms">
+ 20
+ </floater.string>
+ <floater.string
+ name="server_frame_time_critical_msg">
+ Simulator framerate below [SERVER_FRAME_RATE_CRITICAL]
+ </floater.string>
+ <floater.string
+ name="server_frame_time_warning_msg">
+ Simulator framerate between [SERVER_FRAME_RATE_CRITICAL] and [SERVER_FRAME_RATE_WARNING]
+ </floater.string>
+ <floater.string
+ name="server_frame_time_normal_msg">
+ Normal
+ </floater.string>
+ <floater.string
+ name="server_physics_cause_msg">
+ Possible Cause: Too many physical objects
+ </floater.string>
+ <floater.string
+ name="server_scripts_cause_msg">
+ Possible Cause: Too many scripted objects
+ </floater.string>
+ <floater.string
+ name="server_net_cause_msg">
+ Possible Cause: Too much network traffic
+ </floater.string>
+ <floater.string
+ name="server_agent_cause_msg">
+ Possible Cause: Too many moving people in region
+ </floater.string>
+ <floater.string
+ name="server_images_cause_msg">
+ Possible Cause: Too many image calculations
+ </floater.string>
+ <floater.string
+ name="server_generic_cause_msg">
+ Possible Cause: Simulator load too heavy
+ </floater.string>
+ <floater.string
+ name="smaller_label">
+ &gt;&gt;
+ </floater.string>
+ <floater.string
+ name="bigger_label">
+ &lt;&lt;
+ </floater.string>
+ <button
+ follows="top|left"
+ height="16"
+ image_selected="lag_status_good.tga"
+ image_unselected="lag_status_good.tga"
+ layout="topleft"
+ left="8"
+ name="client_lagmeter"
+ picture_style="true"
+ tab_stop="false"
+ tool_tip="Client lag status"
+ top="24"
+ width="16" />
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ font="SansSerif"
+ height="16"
+ layout="topleft"
+ left_pad="3"
+ name="client"
+ top_delta="0"
+ width="128">
+ Client:
+ </text>
+ <text
+ visiblity_control="LagMeterShrunk"
+ type="string"
+ length="1"
+ bottom="40"
+ follows="left|top"
+ font="SansSerif"
+ height="16"
+ layout="topleft"
+ left="110"
+ name="client_text"
+ right="-10">
+ Normal
+ </text>
+ <text
+ visiblity_control="LagMeterShrunk"
+ bottom="56"
+ follows="left|top"
+ height="16"
+ layout="topleft"
+ left="40"
+ name="client_lag_cause"
+ right="-32" />
+ <button
+ follows="top|left"
+ height="16"
+ image_selected="lag_status_good.tga"
+ image_unselected="lag_status_good.tga"
+ layout="topleft"
+ left="8"
+ name="network_lagmeter"
+ picture_style="true"
+ tab_stop="false"
+ tool_tip="Network lag status"
+ top="64"
+ width="16" />
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ font="SansSerif"
+ height="16"
+ layout="topleft"
+ left_pad="3"
+ name="network"
+ top_delta="0"
+ width="128">
+ Network:
+ </text>
+ <text
+ visiblity_control="LagMeterShrunk"
+ type="string"
+ length="1"
+ bottom="80"
+ follows="left|top"
+ font="SansSerif"
+ height="16"
+ layout="topleft"
+ left="110"
+ name="network_text"
+ right="-10">
+ Normal
+ </text>
+ <text
+ visiblity_control="LagMeterShrunk"
+ bottom="96"
+ follows="left|top"
+ height="16"
+ layout="topleft"
+ left="40"
+ name="network_lag_cause"
+ right="-32" />
+ <button
+ follows="top|left"
+ height="16"
+ image_selected="lag_status_good.tga"
+ image_unselected="lag_status_good.tga"
+ layout="topleft"
+ left="8"
+ name="server_lagmeter"
+ picture_style="true"
+ tab_stop="false"
+ tool_tip="Server lag status"
+ top="104"
+ width="16" />
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ font="SansSerif"
+ height="16"
+ layout="topleft"
+ left_pad="3"
+ name="server"
+ top_delta="0"
+ width="60">
+ Server:
+ </text>
+ <text
+ make_visible_control="LagMeterShrunk"
+ type="string"
+ length="1"
+ bottom="120"
+ follows="left|top"
+ font="SansSerif"
+ height="16"
+ layout="topleft"
+ left="85"
+ name="server_text"
+ right="-10">
+ Normal
+ </text>
+ <text
+ make_visible_control="LagMeterShrunk"
+ bottom="136"
+ follows="left|top"
+ height="16"
+ layout="topleft"
+ left="40"
+ name="server_lag_cause"
+ right="-32" />
+ <button
+ bottom="145"
+ follows="left|top"
+ height="18"
+ help_url="https://support.secondlife.com/ics/support/default.asp?deptID=4417&amp;task=knowledge&amp;questionID=4851"
+ label="?"
+ layout="topleft"
+ name="server_help"
+ right="-10"
+ width="18" />
+ <button
+ follows="left|top"
+ height="20"
+ label="&gt;&gt;"
+ layout="topleft"
+ left_delta="-317"
+ name="minimize"
+ top_delta="-2"
+ width="25">
+ <button.commit_callback
+ function="LagMeter.ClickShrink" />
+ </button>
+</floater>
diff --git a/indra/newview/skins/default/xui/en/floater_land_holdings.xml b/indra/newview/skins/default/xui/en/floater_land_holdings.xml
new file mode 100644
index 0000000000..60677ca0df
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/floater_land_holdings.xml
@@ -0,0 +1,168 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<floater
+ height="400"
+ layout="topleft"
+ name="land holdings floater"
+ title="My Land"
+ width="280">
+ <floater.string
+ name="area_string">
+ [AREA] m²
+ </floater.string>
+ <scroll_list
+ draw_heading="true"
+ height="170"
+ layout="topleft"
+ left="8"
+ name="parcel list"
+ top="24"
+ width="270">
+ <scroll_list.columns
+ label="Parcel"
+ name="name"
+ width="69" />
+ <scroll_list.columns
+ label="Region"
+ name="location"
+ width="74" />
+ <scroll_list.columns
+ label="Type"
+ name="type"
+ width="55" />
+ <scroll_list.columns
+ label="Area"
+ name="area"
+ width="10" />
+ <scroll_list.columns
+ label=""
+ name="hidden"
+ width="-1" />
+ </scroll_list>
+ <button
+ height="20"
+ font="SansSerifSmall"
+ label="Teleport"
+ label_selected="Teleport"
+ layout="topleft"
+ left_delta="4"
+ name="Teleport"
+ tool_tip="Teleport to the center of this land."
+ top_pad="4"
+ width="100" />
+ <button
+ height="20"
+ font="SansSerifSmall"
+ label="Map"
+ label_selected="Map"
+ layout="topleft"
+ left_pad="4"
+ name="Show on Map"
+ tool_tip="Show this land on the world map."
+ top_delta="0"
+ width="100" />
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="16"
+ layout="topleft"
+ left="12"
+ name="contrib_label"
+ top="222"
+ width="480">
+ Contributions to your groups:
+ </text>
+ <scroll_list
+ draw_heading="true"
+ height="75"
+ layout="topleft"
+ left_delta="-4"
+ name="grant list"
+ top_pad="4"
+ width="270">
+ <scroll_list.columns
+ label="Group"
+ name="group"
+ width="125" />
+ <scroll_list.columns
+ label="Area"
+ name="area"
+ width="125" />
+ </scroll_list>
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="16"
+ layout="topleft"
+ left_delta="4"
+ name="allowed_label"
+ top_pad="4"
+ width="150">
+ Allowed land holdings at
+current payment plan:
+ </text>
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="16"
+ layout="topleft"
+ left_pad="5"
+ name="allowed_text"
+ top_delta="10"
+ width="132">
+ [AREA] m²
+ </text>
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="16"
+ layout="topleft"
+ left="12"
+ name="current_label"
+ top_pad="5"
+ width="150">
+ Current land holdings:
+ </text>
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="16"
+ layout="topleft"
+ left_pad="5"
+ name="current_text"
+ top_delta="0"
+ width="132">
+ [AREA] m²
+ </text>
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ font="SansSerifBold"
+ height="16"
+ layout="topleft"
+ left="12"
+ name="available_label"
+ top_pad="5"
+ width="150">
+ Available for land
+purchases:
+ </text>
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ font="SansSerifBold"
+ height="16"
+ layout="topleft"
+ left_pad="5"
+ name="available_text"
+ top_delta="5"
+ width="140">
+ [AREA] m²
+ </text>
+</floater> \ No newline at end of file
diff --git a/indra/newview/skins/default/xui/en/floater_live_lsleditor.xml b/indra/newview/skins/default/xui/en/floater_live_lsleditor.xml
new file mode 100644
index 0000000000..6d6c6c6644
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/floater_live_lsleditor.xml
@@ -0,0 +1,71 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<floater
+ bevel_style="none"
+ border_style="line"
+ can_resize="true"
+ follows="left|top"
+ height="550"
+ layout="topleft"
+ min_height="271"
+ min_width="290"
+ name="script ed float"
+ save_rect="true"
+ title="Script: New Script"
+ width="500">
+ <floater.string
+ name="not_allowed">
+ You can not view or edit this script, since it has been set as &quot;no copy&quot;. You need full permissions to view or edit a script inside an object.
+ </floater.string>
+ <floater.string
+ name="script_running">
+ Running
+ </floater.string>
+ <floater.string
+ name="Title">
+ Script: [NAME]
+ </floater.string>
+ <button
+ follows="right|bottom"
+ height="20"
+ label="Reset"
+ label_selected="Reset"
+ layout="topleft"
+ left="362"
+ name="Reset"
+ top="525"
+ width="128" />
+ <check_box
+ enabled="false"
+ follows="left|bottom"
+ font="SansSerif"
+ height="18"
+ initial_value="true"
+ label="Running"
+ layout="topleft"
+ left_delta="-350"
+ name="running"
+ top_delta="2"
+ width="100" />
+ <check_box
+ enabled="false"
+ follows="left|bottom"
+ font="SansSerif"
+ height="18"
+ initial_value="true"
+ label="Mono"
+ layout="topleft"
+ left_delta="70"
+ name="mono"
+ top_delta="0"
+ width="100" />
+ <panel
+ bevel_style="none"
+ border_style="line"
+ follows="left|top|right|bottom"
+ height="506"
+ layout="topleft"
+ left="1"
+ name="script ed panel"
+ top="18"
+ width="497" />
+</floater>
diff --git a/indra/newview/skins/default/xui/en/floater_lsl_guide.xml b/indra/newview/skins/default/xui/en/floater_lsl_guide.xml
new file mode 100644
index 0000000000..ce6b0efd03
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/floater_lsl_guide.xml
@@ -0,0 +1,62 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<floater
+ can_resize="true"
+ follows="left|top"
+ height="400"
+ layout="topleft"
+ min_height="271"
+ min_width="350"
+ name="script ed float"
+ save_rect="true"
+ title="LSL Wiki"
+ width="370">
+ <check_box
+ follows="top|left"
+ font="SansSerif"
+ halign="center"
+ height="20"
+ label="Follow cursor"
+ layout="topleft"
+ left="10"
+ name="lock_check"
+ top="25"
+ width="60" />
+ <combo_box
+ allow_text_entry="true"
+ follows="top|left|right"
+ font="SansSerif"
+ halign="center"
+ height="20"
+ label="Lock"
+ layout="topleft"
+ left_pad="40"
+ name="history_combo"
+ top_delta="0"
+ width="90" />
+ <button
+ follows="top|right"
+ height="20"
+ label="Back"
+ layout="topleft"
+ left_pad="5"
+ name="back_btn"
+ top_delta="0"
+ width="70" />
+ <button
+ follows="top|right"
+ height="20"
+ label="Forward"
+ layout="topleft"
+ left_pad="5"
+ name="fwd_btn"
+ top_delta="0"
+ width="70" />
+ <web_browser
+ bottom="390"
+ follows="left|right|top|bottom"
+ layout="topleft"
+ left="10"
+ name="lsl_guide_html"
+ right="-10"
+ top="50" />
+</floater>
diff --git a/indra/newview/skins/default/xui/en/floater_map.xml b/indra/newview/skins/default/xui/en/floater_map.xml
new file mode 100644
index 0000000000..ed3b00250b
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/floater_map.xml
@@ -0,0 +1,172 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<floater
+ can_resize="true"
+ follows="top|right"
+ height="225"
+ layout="topleft"
+ min_height="60"
+ min_width="174"
+ name="Map"
+ save_rect="true"
+ save_visibility="true"
+ single_instance="true"
+ width="200">
+ <floater.string
+ name="mini_map_north">
+ N
+ </floater.string>
+ <floater.string
+ name="mini_map_east">
+ E
+ </floater.string>
+ <floater.string
+ name="mini_map_west">
+ W
+ </floater.string>
+ <floater.string
+ name="mini_map_south">
+ S
+ </floater.string>
+ <floater.string
+ name="mini_map_southeast">
+ SE
+ </floater.string>
+ <floater.string
+ name="mini_map_northeast">
+ NE
+ </floater.string>
+ <floater.string
+ name="mini_map_southwest">
+ SW
+ </floater.string>
+ <floater.string
+ name="mini_map_northwest">
+ NW
+ </floater.string>
+ <floater.string
+ name="ToolTipMsg">
+ [AGENT][REGION](Double-click to open Map)
+ </floater.string>
+ <net_map
+ bg_color="NetMapBackgroundColor"
+ bottom="225"
+ follows="top|left|bottom|right"
+ layout="topleft"
+ left="0"
+ mouse_opaque="false"
+ name="Net Map"
+ right="198"
+ top="2" />
+ <text
+ type="string"
+ length="1"
+ bottom="225"
+ label="N"
+ layout="topleft"
+ left="0"
+ name="floater_map_north"
+ right="10"
+ text="N"
+ text_color="1 1 1 0.7"
+ top="215">
+ N
+ </text>
+ <text
+ type="string"
+ length="1"
+ bottom="225"
+ label="E"
+ layout="topleft"
+ left="0"
+ name="floater_map_east"
+ right="10"
+ text="E"
+ text_color="1 1 1 0.7"
+ top="215">
+ E
+ </text>
+ <text
+ type="string"
+ length="1"
+ bottom="225"
+ label="W"
+ layout="topleft"
+ left="0"
+ name="floater_map_west"
+ right="11"
+ text="W"
+ text_color="1 1 1 0.7"
+ top="215">
+ W
+ </text>
+ <text
+ type="string"
+ length="1"
+ bottom="225"
+ label="S"
+ layout="topleft"
+ left="0"
+ name="floater_map_south"
+ right="10"
+ text="S"
+ text_color="1 1 1 0.7"
+ top="215">
+ S
+ </text>
+ <text
+ type="string"
+ length="1"
+ bottom="225"
+ label="SE"
+ layout="topleft"
+ left="0"
+ name="floater_map_southeast"
+ right="20"
+ text="SE"
+ text_color="1 1 1 0.7"
+ top="215">
+ SE
+ </text>
+ <text
+ type="string"
+ length="1"
+ bottom="225"
+ label="NE"
+ layout="topleft"
+ left="0"
+ name="floater_map_northeast"
+ right="20"
+ text="NE"
+ text_color="1 1 1 0.7"
+ top="215">
+ NE
+ </text>
+ <text
+ type="string"
+ length="1"
+ bottom="225"
+ label="SW"
+ layout="topleft"
+ left="0"
+ name="floater_map_southwest"
+ right="20"
+ text="SW"
+ text_color="1 1 1 0.7"
+ top="215">
+ SW
+ </text>
+ <text
+ type="string"
+ length="1"
+ bottom="225"
+ label="NW"
+ layout="topleft"
+ left="0"
+ name="floater_map_northwest"
+ right="20"
+ text="NW"
+ text_color="1 1 1 0.7"
+ top="215">
+ NW
+ </text>
+</floater>
diff --git a/indra/newview/skins/default/xui/en/floater_media_browser.xml b/indra/newview/skins/default/xui/en/floater_media_browser.xml
new file mode 100644
index 0000000000..afc72a78a9
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/floater_media_browser.xml
@@ -0,0 +1,235 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<floater
+ can_resize="true"
+ height="440"
+ layout="topleft"
+ min_height="140"
+ min_width="467"
+ name="floater_about"
+ save_rect="true"
+ title="Media Browser"
+ width="820">
+ <floater.string
+ name="home_page_url">
+ http://www.secondlife.com
+ </floater.string>
+ <floater.string
+ name="support_page_url">
+ http://support.secondlife.com
+ </floater.string>
+ <layout_stack
+ bottom="440"
+ follows="left|right|top|bottom"
+ layout="topleft"
+ left="10"
+ name="stack1"
+ top="20"
+ width="800">
+ <layout_panel
+ auto_resize="false"
+ height="20"
+ layout="topleft"
+ left="0"
+ name="nav_controls"
+ top="400"
+ user_resize="false"
+ width="800">
+ <button
+ follows="left|top"
+ height="20"
+ label="Back"
+ layout="topleft"
+ left="0"
+ name="back"
+ top="0"
+ width="55">
+ <button.commit_callback
+ function="MediaBrowser.Back" />
+ </button>
+ <button
+ follows="left|top"
+ height="20"
+ label="Forward"
+ layout="topleft"
+ left_pad="3"
+ name="forward"
+ top_delta="0"
+ width="68">
+ <button.commit_callback
+ function="MediaBrowser.Forward" />
+ </button>
+ <button
+ enabled="false"
+ follows="left|top"
+ height="20"
+ label="Reload"
+ layout="topleft"
+ left_pad="2"
+ name="reload"
+ top_delta="0"
+ width="70">
+ <button.commit_callback
+ function="MediaBrowser.Refresh" />
+ </button>
+ <combo_box
+ allow_text_entry="true"
+ follows="left|top|right"
+ height="20"
+ layout="topleft"
+ left_pad="5"
+ max_chars="255"
+ name="address"
+ top_delta="0"
+ width="540">
+ <combo_box.commit_callback
+ function="MediaBrowser.EnterAddress" />
+ </combo_box>
+ <button
+ enabled="false"
+ follows="right|top"
+ height="20"
+ label="Go"
+ layout="topleft"
+ left_pad="5"
+ name="go"
+ top_delta="0"
+ width="55">
+ <button.commit_callback
+ function="MediaBrowser.Go" />
+ </button>
+ </layout_panel>
+ <layout_panel
+ auto_resize="false"
+ height="20"
+ layout="topleft"
+ left_delta="0"
+ name="time_controls"
+ top_delta="0"
+ user_resize="false"
+ width="800">
+ <button
+ follows="left|top"
+ height="20"
+ label="rewind"
+ layout="topleft"
+ left="0"
+ name="rewind"
+ top="0"
+ width="55" />
+ <button
+ follows="left|top"
+ height="20"
+ image_selected="button_anim_play_selected.tga"
+ image_unselected="button_anim_play.tga"
+ layout="topleft"
+ left_delta="55"
+ name="play"
+ picture_style="true"
+ top_delta="0"
+ width="55" />
+ <button
+ follows="left|top"
+ height="20"
+ image_selected="button_anim_pause_selected.tga"
+ image_unselected="button_anim_pause.tga"
+ layout="topleft"
+ left_delta="0"
+ name="pause"
+ picture_style="true"
+ top_delta="0"
+ width="55" />
+ <button
+ follows="left|top"
+ height="20"
+ label="stop"
+ layout="topleft"
+ left_pad="10"
+ name="stop"
+ top_delta="0"
+ width="55" />
+ <button
+ follows="left|top"
+ height="20"
+ label="forward"
+ layout="topleft"
+ left_pad="20"
+ name="seek"
+ top_delta="0"
+ width="55" />
+ </layout_panel>
+ <layout_panel
+ auto_resize="false"
+ height="20"
+ layout="topleft"
+ left_delta="0"
+ name="parcel_owner_controls"
+ top_delta="0"
+ user_resize="false"
+ width="540">
+ <button
+ enabled="false"
+ follows="left|top"
+ height="20"
+ label="Send Current URL to Parcel"
+ layout="topleft"
+ left="0"
+ name="assign"
+ top="0"
+ width="200">
+ <button.commit_callback
+ function="MediaBrowser.Assign" />
+ </button>
+ </layout_panel>
+ <layout_panel
+ height="20"
+ layout="topleft"
+ left_delta="0"
+ name="external_controls"
+ top_delta="0"
+ user_resize="false"
+ width="540">
+ <web_browser
+ bottom="-10"
+ follows="left|right|top|bottom"
+ layout="topleft"
+ left="0"
+ name="browser"
+ top="0"
+ width="540" />
+ <button
+ follows="bottom|left"
+ height="20"
+ label="Open in My Web Browser"
+ layout="topleft"
+ left_delta="0"
+ name="open_browser"
+ top_pad="5"
+ width="185">
+ <button.commit_callback
+ function="MediaBrowser.OpenWebBrowser" />
+ </button>
+ <check_box
+ control_name="UseExternalBrowser"
+ follows="bottom|left"
+ height="20"
+ label="Always open in my web browser"
+ layout="topleft"
+ left_pad="5"
+ name="open_always"
+ top_delta="0"
+ width="200" />
+ <button
+ follows="bottom|right"
+ height="20"
+ label="Close"
+ layout="topleft"
+ left_pad="80"
+ name="close"
+ top_delta="0"
+ width="70">
+ <button.commit_callback
+ function="MediaBrowser.Close" />
+ </button>
+ </layout_panel>
+ </layout_stack>
+</floater>
diff --git a/indra/newview/skins/default/xui/en/floater_mem_leaking.xml b/indra/newview/skins/default/xui/en/floater_mem_leaking.xml
new file mode 100644
index 0000000000..da698f276b
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/floater_mem_leaking.xml
@@ -0,0 +1,128 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<floater
+ can_minimize="false"
+ follows="left|top"
+ height="175"
+ layout="topleft"
+ name="MemLeak"
+ title="Memory Leaking Simulation"
+ width="350">
+ <spinner
+ decimal_digits="0"
+ follows="left|top"
+ height="20"
+ increment="256"
+ initial_value="512"
+ label="Leaking Speed (bytes per frame):"
+ label_width="220"
+ layout="topleft"
+ left="10"
+ max_val="4.29497e+009"
+ name="leak_speed"
+ top="30"
+ width="330">
+ <spinner.commit_callback
+ function="MemLeak.ChangeLeakingSpeed" />
+ </spinner>
+ <spinner
+ decimal_digits="0"
+ follows="left|top"
+ height="20"
+ increment="4"
+ initial_value="512"
+ label="Max Leaked Memory (MB):"
+ label_width="220"
+ layout="topleft"
+ left_delta="0"
+ max_val="4096"
+ name="max_leak"
+ top_pad="5"
+ width="330">
+ <spinner.commit_callback
+ function="MemLeak.ChangeMaxMemLeaking" />
+ </spinner>
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="25"
+ layout="topleft"
+ left_delta="0"
+ name="total_leaked_label"
+ top_delta="20"
+ width="300">
+ Current leaked memory: [SIZE] KB
+ </text>
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="25"
+ layout="topleft"
+ left_delta="0"
+ name="note_label_1"
+ top_delta="25"
+ width="330">
+ [NOTE1]
+ </text>
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="25"
+ layout="topleft"
+ left_delta="0"
+ name="note_label_2"
+ top_delta="25"
+ width="330">
+ [NOTE2]
+ </text>
+ <button
+ follows="left|top"
+ height="20"
+ label="Start"
+ layout="topleft"
+ left_delta="0"
+ name="start_btn"
+ top_delta="20"
+ width="70">
+ <button.commit_callback
+ function="MemLeak.Start" />
+ </button>
+ <button
+ follows="left|top"
+ height="20"
+ label="Stop"
+ layout="topleft"
+ left_pad="7"
+ name="stop_btn"
+ top_delta="0"
+ width="70">
+ <button.commit_callback
+ function="MemLeak.Stop" />
+ </button>
+ <button
+ follows="left|top"
+ height="20"
+ label="Release"
+ layout="topleft"
+ left_pad="7"
+ name="release_btn"
+ top_delta="0"
+ width="70">
+ <button.commit_callback
+ function="MemLeak.Release" />
+ </button>
+ <button
+ follows="left|top"
+ height="20"
+ label="Close"
+ layout="topleft"
+ left_pad="36"
+ name="close_btn"
+ top_delta="0"
+ width="70">
+ <button.commit_callback
+ function="MemLeak.Close" />
+ </button>
+</floater>
diff --git a/indra/newview/skins/default/xui/en/floater_moveview.xml b/indra/newview/skins/default/xui/en/floater_moveview.xml
new file mode 100644
index 0000000000..17d12c89b7
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/floater_moveview.xml
@@ -0,0 +1,184 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<floater
+ can_close="false"
+ can_minimize="false"
+ center_horiz="true"
+ follows="bottom"
+ height="95"
+ layout="topleft"
+ name="move_floater"
+ save_rect="true"
+ save_visibility="true"
+ width="115">
+ <string
+ name="walk_forward_tooltip">
+ Walk Forward (press Up Arrow or W)
+ </string>
+ <string
+ name="walk_back_tooltip">
+ Walk Backwards (press Down Arrow or S)
+ </string>
+ <string
+ name="run_forward_tooltip">
+ Run Forward (press Up Arrow or W)
+ </string>
+ <string
+ name="run_back_tooltip">
+ Run Backwards (press Down Arrow or S)
+ </string>
+ <string
+ name="fly_forward_tooltip">
+ Fly Forward (press Up Arrow or W)
+ </string>
+ <string
+ name="fly_back_tooltip">
+ Fly Backwards (press Down Arrow or S)
+ </string>
+ <panel
+ border="true"
+ height="70"
+ follows="left|top"
+ layout="topleft"
+ left="0"
+ name="panel_actions"
+ top="0"
+ width="115">
+ <button
+ follows="left|bottom"
+ height="25"
+ image_selected="move_turn_left_in.tga"
+ image_unselected="move_turn_left_out.tga"
+ layout="topleft"
+ left="10"
+ name="turn left btn"
+ picture_style="true"
+ scale_image="false"
+ tool_tip="Turn Left (press Left Arrow or A)"
+ top="35"
+ width="25" />
+ <button
+ follows="left|bottom"
+ height="25"
+ image_selected="move_turn_right_in.tga"
+ image_unselected="move_turn_right_out.tga"
+ layout="topleft"
+ left_pad="45"
+ name="turn right btn"
+ picture_style="true"
+ scale_image="false"
+ tool_tip="Turn Right (press Right Arrow or D)"
+ top_delta="0"
+ width="25" />
+ <button
+ follows="left|bottom"
+ height="25"
+ image_selected="move_up_in.tga"
+ image_unselected="move_up_out.tga"
+ layout="topleft"
+ left="10"
+ name="move up btn"
+ picture_style="true"
+ scale_image="false"
+ tool_tip="Fly Up, Press &quot;E&quot;"
+ top="4"
+ width="25" />
+ <button
+ follows="left|bottom"
+ height="25"
+ image_selected="move_down_in.tga"
+ image_unselected="move_down_out.tga"
+ layout="topleft"
+ left_pad="45"
+ name="move down btn"
+ picture_style="true"
+ scale_image="false"
+ tool_tip="Fly Down, Press &quot;C&quot;"
+ top_delta="0"
+ width="25" />
+ <joystick_turn
+ follows="left|bottom"
+ height="25"
+ image_selected="move_forward_in.tga"
+ image_unselected="move_forward_out.tga"
+ layout="topleft"
+ left="47"
+ name="forward btn"
+ picture_style="true"
+ quadrant="up"
+ scale_image="false"
+ tool_tip="Walk Forward (press Up Arrow or W)"
+ top_delta="10"
+ width="21" />
+ <joystick_turn
+ follows="left|bottom"
+ height="25"
+ image_selected="move_backward_in.tga"
+ image_unselected="move_backward_out.tga"
+ layout="topleft"
+ left_delta="0"
+ name="backward btn"
+ picture_style="true"
+ quadrant="down"
+ scale_image="false"
+ tool_tip="Walk Backward (press Down Arrow or S)"
+ top_delta="30"
+ width="21" />
+ </panel>
+<!-- Width and height of this panel should be synchronized with panel_stand_stop_flying.xml -->
+ <panel
+ border="true"
+ height="25"
+ layout="topleft"
+ left="0"
+ name="panel_modes"
+ top_pad="1"
+ width="115">
+ <button
+ follows="left|bottom"
+ height="20"
+ label="Walk"
+ layout="topleft"
+ name="mode_walk_btn"
+ pad_left="0"
+ pad_right="0"
+ tool_tip="Walking Mode"
+ top="2"
+ width="43" />
+ <button
+ follows="left|bottom"
+ font="SansSerifSmall"
+ height="20"
+ label="Run"
+ layout="topleft"
+ left_pad="0"
+ name="mode_run_btn"
+ pad_left="0"
+ pad_right="0"
+ tool_tip="Running Mode"
+ top="2"
+ width="37" />
+ <button
+ follows="left|bottom"
+ height="20"
+ label="Fly"
+ layout="topleft"
+ left_pad="0"
+ name="mode_fly_btn"
+ pad_left="0"
+ pad_right="0"
+ tool_tip="Flying Mode"
+ top="2"
+ width="35" />
+ <button
+ visible="false"
+ follows="left|bottom"
+ height="20"
+ label="Stop Flying"
+ layout="topleft"
+ left="0"
+ name="stop_fly_btn"
+ tool_tip="Stop Flying"
+ top="2"
+ width="115" />
+ </panel>
+</floater>
diff --git a/indra/newview/skins/default/xui/en/floater_mute_object.xml b/indra/newview/skins/default/xui/en/floater_mute_object.xml
new file mode 100644
index 0000000000..6b6b2c80ba
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/floater_mute_object.xml
@@ -0,0 +1,55 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<floater
+ can_minimize="false"
+ height="140"
+ layout="topleft"
+ name="mute by name"
+ title="Block object by name"
+ width="375">
+ <text
+ type="string"
+ length="1"
+ bottom_delta="50"
+ follows="top|left"
+ font="SansSerif"
+ height="16"
+ layout="topleft"
+ left="20"
+ left_delta="25"
+ name="message"
+ right="380">
+ Block by name only affects object chat and IM, not sounds.
+You must type the object&apos;s name exactly.
+ </text>
+ <line_editor
+ type="string"
+ length="1"
+ follows="top|right"
+ font="SansSerif"
+ height="18"
+ layout="topleft"
+ left_delta="0"
+ name="object_name"
+ top_pad="22"
+ width="320">
+ Object name
+ </line_editor>
+ <button
+ follows="bottom|left"
+ height="20"
+ label="Ok"
+ layout="topleft"
+ left="108"
+ name="OK"
+ top="100"
+ width="75" />
+ <button
+ follows="bottom|right"
+ height="20"
+ label="Cancel"
+ layout="topleft"
+ left_pad="7"
+ name="Cancel"
+ top_delta="0"
+ width="75" />
+</floater>
diff --git a/indra/newview/skins/default/xui/en/floater_my_friends.xml b/indra/newview/skins/default/xui/en/floater_my_friends.xml
new file mode 100644
index 0000000000..65665c7036
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/floater_my_friends.xml
@@ -0,0 +1,41 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<floater
+ can_close="false"
+ can_resize="true"
+ height="390"
+ layout="topleft"
+ min_height="240"
+ min_width="365"
+ name="floater_my_friends"
+ save_rect="true"
+ single_instance="true"
+ title="Contacts"
+ width="395">
+ <tab_container
+ follows="all"
+ height="364"
+ layout="topleft"
+ left="4"
+ name="friends_and_groups"
+ tab_position="top"
+ tab_width="80"
+ top="20"
+ width="383">
+ <panel
+ bottom="364"
+ filename="panel_friends.xml"
+ label="Friends"
+ layout="topleft"
+ left="0"
+ name="friends_panel"
+ width="370" />
+ <panel
+ bottom="364"
+ filename="panel_groups.xml"
+ label="Groups"
+ layout="topleft"
+ left="0"
+ name="groups_panel"
+ width="370" />
+ </tab_container>
+</floater>
diff --git a/indra/newview/skins/default/xui/en/floater_nearby_chat.xml b/indra/newview/skins/default/xui/en/floater_nearby_chat.xml
new file mode 100644
index 0000000000..674bfa42da
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/floater_nearby_chat.xml
@@ -0,0 +1,49 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<floater
+ background_opaque="false"
+ background_visible="true"
+ bevel_style="in"
+ bg_alpha_color="0.3 0.3 0.3 1.0"
+ height="300"
+ layout="topleft"
+ name="nearby_chat"
+ save_rect="true"
+ title="Nearby Chat"
+ single_instance="true"
+ width="320">
+ <panel top="20" width="320" height="30" background_visible="true" background_opaque="false" bg_alpha_color="0.0 0.0 0.0 1.0" name="chat_caption">
+ <text
+ width="140" left="25" height="20" follows="left|right|top"
+ font="SansSerifBigBold" text_color="white" word_wrap="true"
+ mouse_opaque="true" name="sender_name" >NEARBY CHAT </text>
+ <icon top="5" left="250"
+ width="20" height="20" follows="top|right"
+ color="1 1 1 1" enabled="true" image_name="icn_voice-groupfocus.tga"
+ mouse_opaque="true" name="nearby_speakers_btn"/>
+ <icon top="5" left="275"
+ width="20" height="20" follows="top|right"
+ color="1 1 1 1" enabled="true" image_name="inv_item_landmark_visited.tga"
+ mouse_opaque="true" name="tearoff_btn"/>
+ <icon top="5" left="300"
+ width="15" height="15" follows="top|right"
+ color="1 1 1 1" enabled="true" image_name="closebox.tga"
+ name="close_btn"/>
+ </panel>
+ <text_editor
+ bg_readonly_color="ChatHistoryBgColor"
+ bg_writeable_color="ChatHistoryBgColor"
+ follows="left|top|right|bottom"
+ font="SansSerif"
+ layout="topleft"
+ height="320"
+ max_length="2147483647"
+ name="Chat History Editor"
+ read_only="true"
+ text_color="ChatHistoryTextColor"
+ text_readonly_color="ChatHistoryTextColor"
+ bottom="0"
+ track_bottom="true"
+ width="250"
+ word_wrap="true" />
+
+</floater>
diff --git a/indra/newview/skins/default/xui/en/floater_notification.xml b/indra/newview/skins/default/xui/en/floater_notification.xml
new file mode 100644
index 0000000000..cd88ec2f3f
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/floater_notification.xml
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<floater
+ can_resize="true"
+ height="200"
+ layout="topleft"
+ min_height="50"
+ name="notification"
+ title="Notifications Console"
+ width="200">
+ <text_editor
+ type="string"
+ length="1"
+ enabled="false"
+ follows="left|top|right|bottom"
+ font="SansSerif"
+ height="140"
+ ignore_tab="false"
+ layout="topleft"
+ left="4"
+ max_length="65536"
+ name="payload"
+ top="25"
+ width="192"
+ word_wrap="true">
+ Loading...
+ </text_editor>
+ <combo_box
+ follows="left|bottom"
+ height="20"
+ label="Response"
+ layout="topleft"
+ left="10"
+ name="response"
+ top="171"
+ width="100" />
+</floater>
diff --git a/indra/newview/skins/default/xui/en/floater_notifications_console.xml b/indra/newview/skins/default/xui/en/floater_notifications_console.xml
new file mode 100644
index 0000000000..34bda53ef1
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/floater_notifications_console.xml
@@ -0,0 +1,40 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<floater
+ can_resize="true"
+ height="500"
+ layout="topleft"
+ min_height="50"
+ name="notifications_console"
+ single_instance="true"
+ title="Notifications Console"
+ width="500">
+ <combo_box
+ follows="left|right|top"
+ height="18"
+ label="Select notification type"
+ layout="topleft"
+ left="2"
+ name="notification_types"
+ top="22"
+ width="440" />
+ <button
+ follows="right|top"
+ height="18"
+ label="Add"
+ layout="topleft"
+ left_pad="3"
+ name="add_notification"
+ top_delta="0"
+ width="50" >
+ <button.commit_callback
+ function="ClickAdd" />
+ </button>
+ <layout_stack
+ bottom="495"
+ follows="left|right|top|bottom"
+ layout="topleft"
+ left="5"
+ name="notification_channels"
+ right="-5"
+ top="42" />
+</floater>
diff --git a/indra/newview/skins/default/xui/en/floater_openobject.xml b/indra/newview/skins/default/xui/en/floater_openobject.xml
new file mode 100644
index 0000000000..e0ac2c1d51
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/floater_openobject.xml
@@ -0,0 +1,63 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<floater
+ can_resize="true"
+ default_tab_group="1"
+ height="350"
+ layout="topleft"
+ min_height="160"
+ min_width="270"
+ name="objectcontents"
+ save_rect="true"
+ title="Object Contents"
+ width="300">
+ <panel_inventory
+ follows="left|top|right|bottom"
+ height="276"
+ layout="topleft"
+ left="8"
+ name="object_contents"
+ top="44"
+ width="284" />
+ <text
+ type="string"
+ length="1"
+ follows="left|top|right"
+ font="SansSerif"
+ height="16"
+ layout="topleft"
+ left_delta="0"
+ name="object_name"
+ top_delta="-20"
+ width="284">
+ [DESC]:
+ </text>
+ <button
+ follows="bottom|left"
+ font="SansSerifSmall"
+ height="20"
+ label="Copy To Inventory"
+ label_selected="Copy To Inventory"
+ layout="topleft"
+ left_delta="2"
+ name="copy_to_inventory_button"
+ tab_group="1"
+ top_pad="285"
+ width="120">
+ <button.commit_callback
+ function="OpenObject.MoveToInventory" />
+ </button>
+ <button
+ follows="bottom|left"
+ font="SansSerifSmall"
+ height="20"
+ label="Copy And Wear"
+ label_selected="Copy And Wear"
+ layout="topleft"
+ left_pad="10"
+ name="copy_and_wear_button"
+ top_delta="0"
+ width="120">
+ <button.commit_callback
+ function="OpenObject.MoveAndWear" />
+ </button>
+</floater>
diff --git a/indra/newview/skins/default/xui/en/floater_pay.xml b/indra/newview/skins/default/xui/en/floater_pay.xml
new file mode 100644
index 0000000000..96195c9ba1
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/floater_pay.xml
@@ -0,0 +1,129 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<floater
+ can_minimize="false"
+ height="140"
+ layout="topleft"
+ name="Give Money"
+ save_rect="true"
+ width="300">
+ <button
+ height="20"
+ label="L$1"
+ label_selected="L$1"
+ layout="topleft"
+ left="108"
+ name="fastpay 1"
+ top="54"
+ width="80" />
+ <button
+ height="20"
+ label="L$5"
+ label_selected="L$5"
+ layout="topleft"
+ left_pad="15"
+ name="fastpay 5"
+ top_delta="0"
+ width="80" />
+ <button
+ height="20"
+ label="L$10"
+ label_selected="L$10"
+ layout="topleft"
+ left="108"
+ name="fastpay 10"
+ top="78"
+ width="80" />
+ <button
+ height="20"
+ label="L$20"
+ label_selected="L$20"
+ layout="topleft"
+ left_pad="15"
+ name="fastpay 20"
+ top_delta="0"
+ width="80" />
+ <button
+ enabled="false"
+ height="20"
+ label="Pay"
+ label_selected="Pay"
+ layout="topleft"
+ left="120"
+ name="pay btn"
+ top="112"
+ width="80" />
+ <button
+ height="20"
+ label="Cancel"
+ label_selected="Cancel"
+ layout="topleft"
+ left_pad="3"
+ name="cancel btn"
+ top_delta="0"
+ width="80" />
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ font="SansSerif"
+ height="18"
+ layout="topleft"
+ left="12"
+ name="payee_label"
+ top="7"
+ width="75">
+ Pay resident:
+ </text>
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ font="SansSerif"
+ height="18"
+ layout="topleft"
+ left_delta="73"
+ name="payee_name"
+ top_delta="0"
+ width="210">
+ [FIRST] [LAST]
+ </text>
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ font="SansSerif"
+ halign="right"
+ height="18"
+ layout="topleft"
+ left="5"
+ name="fastpay text"
+ top="54"
+ width="95">
+ Fast Pay:
+ </text>
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ font="SansSerif"
+ height="18"
+ layout="topleft"
+ left="12"
+ name="amount text"
+ top="112"
+ width="75">
+ Amount:
+ </text>
+ <line_editor
+ border_style="line"
+ border_thickness="1"
+ follows="left|top|right"
+ font="SansSerif"
+ height="18"
+ layout="topleft"
+ left_delta="46"
+ max_length="9"
+ name="amount"
+ top_delta="0"
+ width="57" />
+</floater>
diff --git a/indra/newview/skins/default/xui/en/floater_pay_object.xml b/indra/newview/skins/default/xui/en/floater_pay_object.xml
new file mode 100644
index 0000000000..bb91f709a3
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/floater_pay_object.xml
@@ -0,0 +1,174 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<floater
+ can_minimize="false"
+ height="140"
+ layout="topleft"
+ name="Give Money"
+ save_rect="true"
+ width="300">
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ font="SansSerif"
+ halign="right"
+ height="18"
+ layout="topleft"
+ left="5"
+ name="payee_group"
+ top="7"
+ width="75">
+ Pay group:
+ </text>
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ font="SansSerif"
+ halign="right"
+ height="18"
+ layout="topleft"
+ left_delta="0"
+ name="payee_resident"
+ top_delta="0"
+ width="75">
+ Pay resident:
+ </text>
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ font="SansSerif"
+ height="18"
+ layout="topleft"
+ left_pad="5"
+ name="payee_name"
+ top_delta="0"
+ width="210">
+ [FIRST] [LAST]
+ </text>
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ font="SansSerif"
+ halign="right"
+ height="18"
+ layout="topleft"
+ left="5"
+ name="object_name_label"
+ top="32"
+ width="75">
+ Via object:
+ </text>
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ font="SansSerif"
+ height="18"
+ layout="topleft"
+ left_pad="5"
+ name="object_name_text"
+ top_delta="0"
+ width="210">
+ ...
+ </text>
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ font="SansSerif"
+ halign="right"
+ height="18"
+ layout="topleft"
+ left="5"
+ name="fastpay text"
+ top="54"
+ width="75">
+ Fast Pay:
+ </text>
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ font="SansSerif"
+ halign="right"
+ height="18"
+ layout="topleft"
+ left_delta="0"
+ name="amount text"
+ top_pad="40"
+ width="75">
+ Amount:
+ </text>
+ <button
+ height="20"
+ label="L$1"
+ label_selected="L$1"
+ layout="topleft"
+ left="85"
+ name="fastpay 1"
+ top="54"
+ width="80" />
+ <button
+ height="20"
+ label="L$5"
+ label_selected="L$5"
+ layout="topleft"
+ left_pad="5"
+ name="fastpay 5"
+ top_delta="0"
+ width="80" />
+ <button
+ height="20"
+ label="L$10"
+ label_selected="L$10"
+ layout="topleft"
+ left="85"
+ name="fastpay 10"
+ top="78"
+ width="80" />
+ <button
+ height="20"
+ label="L$20"
+ label_selected="L$20"
+ layout="topleft"
+ left_pad="5"
+ name="fastpay 20"
+ top_delta="0"
+ width="80" />
+ <button
+ enabled="false"
+ follows="right|bottom"
+ height="20"
+ label="Pay"
+ label_selected="Pay"
+ layout="topleft"
+ left="140"
+ name="pay btn"
+ top="112"
+ width="70" />
+ <button
+ follows="right|bottom"
+ height="20"
+ label="Cancel"
+ label_selected="Cancel"
+ layout="topleft"
+ left_pad="5"
+ name="cancel btn"
+ top_delta="0"
+ width="70" />
+ <line_editor
+ border_style="line"
+ border_thickness="1"
+ follows="left|top|right"
+ font="SansSerif"
+ height="18"
+ layout="topleft"
+ left_delta="-130"
+ max_length="9"
+ name="amount"
+ top_delta="0"
+ width="50" />
+</floater>
diff --git a/indra/newview/skins/default/xui/en/floater_perm_prefs.xml b/indra/newview/skins/default/xui/en/floater_perm_prefs.xml
new file mode 100644
index 0000000000..e4cb97035c
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/floater_perm_prefs.xml
@@ -0,0 +1,120 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<floater
+ height="180"
+ layout="topleft"
+ name="perm prefs"
+ save_rect="true"
+ title="Default Upload Permissions"
+ width="315">
+ <panel
+ follows="left|top|right|bottom"
+ height="120"
+ label="Permissions"
+ layout="topleft"
+ left="10"
+ name="permissions"
+ top="20"
+ width="315">
+ <button
+ follows="left"
+ height="18"
+ label="?"
+ label_selected="?"
+ layout="topleft"
+ left="260"
+ name="help"
+ top="7"
+ width="22">
+ <button.commit_callback
+ function="Notification.Show"
+ parameter="ClickUploadHelpPermissions" />
+ </button>
+ <check_box
+ control_name="ShareWithGroup"
+ height="16"
+ label="Share with group"
+ layout="topleft"
+ left_delta="-250"
+ name="share_with_group"
+ top_delta="2"
+ width="106" />
+ <check_box
+ control_name="EveryoneCopy"
+ height="16"
+ label="Allow anyone to copy"
+ layout="topleft"
+ left_delta="0"
+ name="everyone_copy"
+ top_pad="16"
+ width="130" />
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="10"
+ layout="topleft"
+ left_delta="0"
+ name="NextOwnerLabel"
+ top_pad="16"
+ width="88">
+ Next owner can:
+ </text>
+ <check_box
+ control_name="NextOwnerModify"
+ height="16"
+ label="Modify"
+ layout="topleft"
+ left_delta="0"
+ name="next_owner_modify"
+ top_pad="14"
+ width="78" />
+ <check_box
+ control_name="NextOwnerCopy"
+ height="16"
+ label="Copy"
+ layout="topleft"
+ left_delta="78"
+ name="next_owner_copy"
+ top_delta="0"
+ width="88" >
+ <check_box.commit_callback
+ function="Perms.Copy" />
+ </check_box>
+ <check_box
+ enabled_control="NextOwnerCopy"
+ control_name="NextOwnerTransfer"
+ enabled="false"
+ height="16"
+ initial_value="true"
+ label="Resell/Give away"
+ layout="topleft"
+ left_delta="88"
+ name="next_owner_transfer"
+ top_delta="0"
+ width="106" />
+ </panel>
+ <button
+ height="20"
+ label="OK"
+ label_selected="OK"
+ layout="topleft"
+ left="90"
+ name="ok"
+ top="150"
+ width="100">
+ <button.commit_callback
+ function="Perms.OK" />
+ </button>
+ <button
+ height="20"
+ label="Cancel"
+ label_selected="Cancel"
+ layout="topleft"
+ left_pad="5"
+ name="cancel"
+ top_delta="0"
+ width="100">
+ <button.commit_callback
+ function="Perms.Cancel" />
+ </button>
+</floater>
diff --git a/indra/newview/skins/default/xui/en/floater_post_process.xml b/indra/newview/skins/default/xui/en/floater_post_process.xml
new file mode 100644
index 0000000000..5a36ed5fd6
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/floater_post_process.xml
@@ -0,0 +1,420 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<floater
+ height="400"
+ layout="topleft"
+ name="Post-Process Floater"
+ title="Post-Process Settings"
+ width="400">
+ <tab_container
+ follows="left|top"
+ height="400"
+ layout="topleft"
+ left="0"
+ name="Post-Process Tabs"
+ tab_position="top"
+ top="0"
+ width="400">
+ <panel
+ border="true"
+ follows="left|top|right|bottom"
+ height="400"
+ label="Color Filter"
+ layout="topleft"
+ left="1"
+ mouse_opaque="false"
+ name="wmiColorFilterPanel"
+ top="0"
+ width="398">
+ <check_box
+ control_name="wmiColorFilterToggle"
+ height="16"
+ label="Enable"
+ layout="topleft"
+ left="14"
+ name="wmiColorFilterToggle"
+ top="4"
+ width="200" />
+ <text
+ type="string"
+ length="1"
+ follows="left|top|right"
+ font="SansSerif"
+ height="16"
+ layout="topleft"
+ left_delta="-4"
+ name="wmiColorFilterBrightnessText"
+ top_pad="4"
+ width="355">
+ Brightness
+ </text>
+ <slider
+ control_name="wmiColorFilterBrightness"
+ decimal_digits="2"
+ follows="left"
+ height="10"
+ increment="0.01"
+ initial_value="1.0"
+ layout="topleft"
+ left_delta="4"
+ max_val="4"
+ name="wmiColorFilterBrightness"
+ top_pad="20"
+ width="200" />
+ <text
+ type="string"
+ length="1"
+ follows="left|top|right"
+ font="SansSerif"
+ height="16"
+ layout="topleft"
+ left_delta="-4"
+ name="wmiColorFilterSaturationText"
+ top_pad="4"
+ width="355">
+ Saturation
+ </text>
+ <slider
+ control_name="wmiColorFilterSaturation"
+ decimal_digits="2"
+ follows="left"
+ height="10"
+ increment="0.01"
+ initial_value="1.0"
+ layout="topleft"
+ left_delta="4"
+ max_val="2"
+ min_val="-1"
+ name="wmiColorFilterSaturation"
+ top_pad="20"
+ width="200" />
+ <text
+ type="string"
+ length="1"
+ follows="left|top|right"
+ font="SansSerif"
+ height="16"
+ layout="topleft"
+ left_delta="-4"
+ name="wmiColorFilterContrastText"
+ top_pad="4"
+ width="355">
+ Contrast
+ </text>
+ <slider
+ control_name="wmiColorFilterContrast"
+ decimal_digits="2"
+ follows="left"
+ height="10"
+ increment="0.01"
+ initial_value="1.0"
+ layout="topleft"
+ left_delta="4"
+ max_val="4"
+ name="wmiColorFilterContrast"
+ top_pad="20"
+ width="200" />
+ <text
+ type="string"
+ length="1"
+ follows="left|top|right"
+ font="SansSerif"
+ height="16"
+ layout="topleft"
+ left_delta="-4"
+ name="wmiColorFilterBaseText"
+ top_pad="4"
+ width="355">
+ Contrast Base Color
+ </text>
+ <slider
+ control_name="wmiColorFilterBaseR"
+ follows="left"
+ height="10"
+ increment="0.01"
+ initial_value="1.0"
+ label="R"
+ layout="topleft"
+ left_delta="4"
+ name="wmiColorFilterBaseR"
+ top_pad="20"
+ width="200" />
+ <slider
+ control_name="wmiColorFilterBaseG"
+ follows="left"
+ height="10"
+ increment="0.01"
+ initial_value="1.0"
+ label="G"
+ layout="topleft"
+ left_delta="0"
+ name="wmiColorFilterBaseG"
+ top_pad="10"
+ width="200" />
+ <slider
+ control_name="wmiColorFilterBaseB"
+ follows="left"
+ height="10"
+ increment="0.01"
+ initial_value="1.0"
+ label="B"
+ layout="topleft"
+ left_delta="0"
+ name="wmiColorFilterBaseB"
+ top_pad="10"
+ width="200" />
+ <slider
+ control_name="wmiColorFilterBaseI"
+ follows="left"
+ height="10"
+ increment="0.01"
+ initial_value="0.5"
+ label="I"
+ layout="topleft"
+ left_delta="0"
+ name="wmiColorFilterBaseI"
+ top_pad="10"
+ width="200" />
+ </panel>
+ <panel
+ border="true"
+ follows="left|top|right|bottom"
+ height="400"
+ label="Night Vision"
+ layout="topleft"
+ left_delta="0"
+ mouse_opaque="false"
+ name="wmiNightVisionPanel"
+ top_delta="-236"
+ width="398">
+ <check_box
+ control_name="wmiNightVisionToggle"
+ height="16"
+ label="Enable"
+ layout="topleft"
+ left="14"
+ name="wmiNightVisionToggle"
+ top="4"
+ width="200" />
+ <text
+ type="string"
+ length="1"
+ follows="left|top|right"
+ font="SansSerif"
+ height="16"
+ layout="topleft"
+ left_delta="-4"
+ name="wmiNightVisionBrightMultText"
+ top_pad="5"
+ width="355">
+ Light Amplification Multiple
+ </text>
+ <slider
+ control_name="wmiNightVisionBrightMult"
+ follows="left"
+ height="10"
+ increment="0.01"
+ initial_value="3.0"
+ layout="topleft"
+ left_delta="4"
+ max_val="10"
+ min_val="1"
+ name="wmiNightVisionBrightMult"
+ top_pad="20"
+ width="200" />
+ <text
+ type="string"
+ length="1"
+ follows="left|top|right"
+ font="SansSerif"
+ height="16"
+ layout="topleft"
+ left_delta="-4"
+ name="wmiNightVisionNoiseSizeText"
+ top_pad="4"
+ width="355">
+ Noise Size
+ </text>
+ <slider
+ control_name="wmiNightVisionNoiseSize"
+ follows="left"
+ height="10"
+ initial_value="1"
+ layout="topleft"
+ left_delta="4"
+ max_val="100"
+ min_val="1"
+ name="wmiNightVisionNoiseSize"
+ top_pad="20"
+ width="200" />
+ <text
+ type="string"
+ length="1"
+ follows="left|top|right"
+ font="SansSerif"
+ height="16"
+ layout="topleft"
+ left_delta="-4"
+ name="wmiNightVisionNoiseStrengthText"
+ top_pad="4"
+ width="355">
+ Noise Strength
+ </text>
+ <slider
+ control_name="wmiNightVisionNoiseStrength"
+ follows="left"
+ height="10"
+ increment="0.01"
+ initial_value="0.3"
+ layout="topleft"
+ left_delta="4"
+ name="wmiNightVisionNoiseStrength"
+ top_pad="20"
+ width="200" />
+ </panel>
+ <panel
+ border="true"
+ follows="left|top|right|bottom"
+ height="400"
+ label="Bloom"
+ layout="topleft"
+ left_delta="0"
+ name="wmiBloomPanel"
+ top_delta="-236"
+ width="398">
+ <check_box
+ control_name="wmiBloomToggle"
+ height="16"
+ label="Enable"
+ layout="topleft"
+ left="14"
+ name="wmiBloomToggle"
+ top="4"
+ width="200" />
+ <text
+ type="string"
+ length="1"
+ follows="left|top|right"
+ font="SansSerif"
+ height="16"
+ layout="topleft"
+ left_delta="-4"
+ name="wmiBloomExtractText"
+ top_pad="5"
+ width="355">
+ Luminosity Extraction
+ </text>
+ <slider
+ control_name="wmiBloomExtract"
+ follows="left"
+ height="10"
+ increment="0.01"
+ initial_value="0.9"
+ layout="topleft"
+ left_delta="4"
+ name="wmiBloomExtract"
+ top_pad="20"
+ width="200" />
+ <text
+ type="string"
+ length="1"
+ follows="left|top|right"
+ font="SansSerif"
+ height="16"
+ layout="topleft"
+ left_delta="-4"
+ name="wmiBloomSizeText"
+ top_pad="4"
+ width="355">
+ Bloom Size
+ </text>
+ <slider
+ control_name="wmiBloomSize"
+ follows="left"
+ height="10"
+ increment="0.01"
+ initial_value="3.0"
+ layout="topleft"
+ left_delta="4"
+ max_val="20"
+ name="wmiBloomSize"
+ top_pad="20"
+ width="200" />
+ <text
+ type="string"
+ length="1"
+ follows="left|top|right"
+ font="SansSerif"
+ height="16"
+ layout="topleft"
+ left_delta="-4"
+ name="wmiBloomStrengthText"
+ top_pad="4"
+ width="355">
+ Bloom Strength
+ </text>
+ <slider
+ control_name="wmiBloomStrength"
+ follows="left"
+ height="10"
+ increment="0.01"
+ initial_value="1.2"
+ layout="topleft"
+ left_delta="4"
+ max_val="10"
+ name="wmiBloomStrength"
+ top_pad="20"
+ width="200" />
+ </panel>
+ <panel
+ border="true"
+ follows="left|top|right|bottom"
+ height="400"
+ label="Extras"
+ layout="topleft"
+ left_delta="0"
+ mouse_opaque="false"
+ name="Extras"
+ top_delta="-236"
+ width="398">
+ <button
+ height="20"
+ label="LoadEffect"
+ label_selected="LoadEffect"
+ layout="topleft"
+ left="15"
+ name="PPLoadEffect"
+ top="13"
+ width="100" />
+ <button
+ height="20"
+ label="SaveEffect"
+ label_selected="SaveEffect"
+ layout="topleft"
+ left_delta="0"
+ name="PPSaveEffect"
+ top_pad="7"
+ width="100" />
+ <combo_box
+ height="18"
+ layout="topleft"
+ left_delta="120"
+ name="PPEffectsCombo"
+ top="15"
+ width="150" />
+ <line_editor
+ border_style="line"
+ border_thickness="1"
+ follows="left|right|bottom"
+ font="SansSerif"
+ height="20"
+ label="Effect Name"
+ layout="topleft"
+ left_delta="0"
+ max_length="40"
+ name="PPEffectNameEditor"
+ tab_group="1"
+ top_pad="22"
+ width="150" />
+ </panel>
+ </tab_container>
+</floater>
diff --git a/indra/newview/skins/default/xui/en/floater_postcard.xml b/indra/newview/skins/default/xui/en/floater_postcard.xml
new file mode 100644
index 0000000000..8657663057
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/floater_postcard.xml
@@ -0,0 +1,157 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<floater
+ auto_tile="true"
+ can_minimize="false"
+ can_resize="true"
+ height="380"
+ layout="topleft"
+ min_height="380"
+ min_width="450"
+ name="Postcard"
+ title="Email Snapshot"
+ width="450">
+ <floater.string
+ name="default_subject">
+ Postcard from [SECOND_LIFE].
+ </floater.string>
+ <floater.string
+ name="default_message">
+ Check this out!
+ </floater.string>
+ <floater.string
+ name="upload_message">
+ Sending...
+ </floater.string>
+ <text
+ type="string"
+ length="1"
+ bottom="35"
+ follows="top|left"
+ font="SansSerif"
+ layout="topleft"
+ left="12"
+ name="to_label">
+ Recipient&apos;s Email:
+ </text>
+ <line_editor
+ follows="left|top"
+ height="20"
+ layout="topleft"
+ left_delta="108"
+ name="to_form"
+ top_delta="-4"
+ width="150" />
+ <text
+ type="string"
+ length="1"
+ bottom_delta="23"
+ follows="top|left"
+ font="SansSerif"
+ layout="topleft"
+ left="12"
+ name="from_label">
+ Your Email:
+ </text>
+ <line_editor
+ follows="left|top"
+ height="20"
+ layout="topleft"
+ left_delta="108"
+ name="from_form"
+ top_delta="-4"
+ width="150" />
+ <text
+ type="string"
+ length="1"
+ bottom_delta="23"
+ follows="top|left"
+ font="SansSerif"
+ layout="topleft"
+ left="12"
+ name="name_label">
+ Your Name:
+ </text>
+ <line_editor
+ follows="left|top"
+ height="20"
+ layout="topleft"
+ left_delta="108"
+ max_length="100"
+ name="name_form"
+ top_delta="-4"
+ width="150" />
+ <text
+ type="string"
+ length="1"
+ bottom_delta="23"
+ follows="top|left"
+ font="SansSerif"
+ layout="topleft"
+ left="12"
+ name="subject_label">
+ Subject:
+ </text>
+ <line_editor
+ follows="left|top"
+ height="20"
+ label="Type your subject here."
+ layout="topleft"
+ left_delta="108"
+ max_length="100"
+ name="subject_form"
+ top_delta="-4"
+ width="150" />
+ <text
+ type="string"
+ length="1"
+ bottom_delta="23"
+ follows="top|left"
+ font="SansSerif"
+ layout="topleft"
+ left="12"
+ name="msg_label">
+ Message:
+ </text>
+ <text_editor
+ type="string"
+ length="1"
+ follows="left|top|right|bottom"
+ height="140"
+ layout="topleft"
+ left_delta="0"
+ max_length="700"
+ name="msg_form"
+ word_wrap="true"
+ top_pad="10"
+ width="420">
+ Type your message here.
+ </text_editor>
+ <text
+ type="string"
+ length="1"
+ bottom_delta="37"
+ follows="left|bottom"
+ layout="topleft"
+ left="12"
+ name="fine_print">
+ If your recipient joins SL, you&apos;ll get a referral bonus.
+ </text>
+ <button
+ follows="right|bottom"
+ height="20"
+ label="Cancel"
+ layout="topleft"
+ name="cancel_btn"
+ right="-10"
+ top="350"
+ width="100" />
+ <button
+ follows="right|bottom"
+ height="20"
+ label="Send"
+ layout="topleft"
+ left_delta="-106"
+ name="send_btn"
+ top_delta="0"
+ width="100" />
+</floater>
diff --git a/indra/newview/skins/default/xui/en/floater_preferences.xml b/indra/newview/skins/default/xui/en/floater_preferences.xml
new file mode 100644
index 0000000000..bacec627e1
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/floater_preferences.xml
@@ -0,0 +1,105 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<floater
+ center_horiz="true"
+ center_vert="true"
+ default_tab_group="1"
+ height="460"
+ layout="topleft"
+ name="Preferences"
+ single_instance="true"
+ title="Preferences"
+ width="620">
+ <button
+ follows="right|bottom"
+ height="20"
+ label="OK"
+ label_selected="OK"
+ layout="topleft"
+ left="427"
+ name="OK"
+ top="435"
+ width="90">
+ <button.commit_callback
+ function="Pref.OK" />
+ </button>
+ <button
+ follows="right|bottom"
+ height="20"
+ label="Cancel"
+ label_selected="Cancel"
+ layout="topleft"
+ left_pad="3"
+ name="Cancel"
+ top_delta="0"
+ width="90" >
+ <button.commit_callback
+ function="Pref.Cancel" />
+ </button>
+ <tab_container
+ follows="left|top|right|bottom"
+ height="410"
+ layout="topleft"
+ left="0"
+ name="pref core"
+ tab_group="1"
+ tab_position="left"
+ tab_width="115"
+ top="21"
+ width="620">
+ <panel
+ class="panel_preference"
+ filename="panel_preferences_general.xml"
+ label="General"
+ layout="topleft"
+ name="general" />
+ <panel
+ class="panel_preference"
+ filename="panel_preferences_graphics1.xml"
+ label="Graphics"
+ layout="topleft"
+ name="display" />
+ <panel
+ class="panel_preference"
+ filename="panel_preferences_im.xml"
+ label="Privacy"
+ layout="topleft"
+ name="im" />
+ <panel
+ class="panel_preference"
+ filename="panel_preferences_audio.xml"
+ label="Sound"
+ layout="topleft"
+ name="audio" />
+ <panel
+ class="panel_preference"
+ filename="panel_preferences_chat.xml"
+ label="Chat"
+ layout="topleft"
+ name="chat" />
+ <panel
+ class="panel_preference"
+ filename="panel_preferences_popups.xml"
+ label="Alerts"
+ layout="topleft"
+ name="msgs" />
+ <panel
+ class="panel_preference"
+ filename="panel_preferences_input.xml"
+ label="Setup"
+ layout="topleft"
+ name="input" />
+ <panel
+ class="panel_preference"
+ filename="panel_preferences_advanced.xml"
+ label="Advanced"
+ layout="topleft"
+ name="advanced1" />
+ <panel
+ class="panel_preference"
+ filename="panel_preferences_advanced2.xml"
+ label="Move or Kill"
+ layout="topleft"
+ name="advanced2" />
+ </tab_container>
+
+</floater>
diff --git a/indra/newview/skins/default/xui/en/floater_preview_animation.xml b/indra/newview/skins/default/xui/en/floater_preview_animation.xml
new file mode 100644
index 0000000000..e9342b772f
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/floater_preview_animation.xml
@@ -0,0 +1,59 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<floater
+ auto_tile="true"
+ height="85"
+ layout="topleft"
+ name="preview_anim"
+ width="280">
+ <floater.string
+ name="Title">
+ Animation: [NAME]
+ </floater.string>
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ font="SansSerif"
+ height="19"
+ layout="topleft"
+ left="10"
+ name="desc txt"
+ top="25"
+ width="80">
+ Description:
+ </text>
+ <line_editor
+ border_style="line"
+ border_thickness="1"
+ follows="left|top|right"
+ font="SansSerifSmall"
+ height="19"
+ layout="topleft"
+ left_delta="95"
+ max_length="127"
+ name="desc"
+ top="19"
+ width="170" />
+ <button
+ height="20"
+ font="SansSerifSmall"
+ label="Play in World"
+ label_selected="Stop"
+ layout="topleft"
+ left="10"
+ name="Anim play btn"
+ tool_tip="Play this animation so that others can see it."
+ top="47"
+ width="125" />
+ <button
+ height="20"
+ font="SansSerifSmall"
+ label="Play Locally"
+ label_selected="Stop"
+ layout="topleft"
+ left_pad="5"
+ name="Anim audition btn"
+ tool_tip="Play this animation so that only you can see it."
+ top_delta="0"
+ width="125" />
+</floater>
diff --git a/indra/newview/skins/default/xui/en/floater_preview_classified.xml b/indra/newview/skins/default/xui/en/floater_preview_classified.xml
new file mode 100644
index 0000000000..6fac2823e8
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/floater_preview_classified.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<floater
+ auto_tile="true"
+ height="510"
+ layout="topleft"
+ name="classified_preview"
+ save_rect="true"
+ title="Classified Information"
+ width="440">
+ <floater.string
+ name="Title">
+ Classified: [NAME]
+ </floater.string>
+ <panel
+ follows="bottom|left"
+ height="470"
+ layout="topleft"
+ left="0"
+ name="classified_details_panel"
+ top="20"
+ width="440" />
+</floater>
diff --git a/indra/newview/skins/default/xui/en/floater_preview_event.xml b/indra/newview/skins/default/xui/en/floater_preview_event.xml
new file mode 100644
index 0000000000..58dd43075d
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/floater_preview_event.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<floater
+ auto_tile="true"
+ height="510"
+ layout="topleft"
+ name="event_preview"
+ save_rect="true"
+ title="Event Information"
+ width="440">
+ <floater.string
+ name="Title">
+ Event: [NAME]
+ </floater.string>
+ <panel
+ follows="bottom|left"
+ height="470"
+ layout="topleft"
+ left="0"
+ name="event_details_panel"
+ top="20"
+ width="440" />
+</floater>
diff --git a/indra/newview/skins/default/xui/en/floater_preview_gesture.xml b/indra/newview/skins/default/xui/en/floater_preview_gesture.xml
new file mode 100644
index 0000000000..90711e3acc
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/floater_preview_gesture.xml
@@ -0,0 +1,171 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<floater
+ auto_tile="true"
+ height="700"
+ layout="topleft"
+ name="gesture_preview"
+ width="280">
+ <floater.string
+ name="step_anim">
+ Animation to play:
+ </floater.string>
+ <floater.string
+ name="step_sound">
+ Sound to play:
+ </floater.string>
+ <floater.string
+ name="step_chat">
+ Chat to say:
+ </floater.string>
+ <floater.string
+ name="step_wait">
+ Wait:
+ </floater.string>
+ <floater.string
+ name="stop_txt">
+ Stop
+ </floater.string>
+ <floater.string
+ name="preview_txt">
+ Preview
+ </floater.string>
+ <floater.string
+ name="none_text">
+ -- None --
+ </floater.string>
+ <floater.string
+ name="Title">
+ Gesture: [NAME]
+ </floater.string>
+ <text
+ type="string"
+ length="1"
+ follows="top|left"
+ font="SansSerifSmall"
+ height="10"
+ layout="topleft"
+ left="10"
+ name="Name"
+ top="25"
+ width="100">
+ Name (not working yet):
+ </text>
+ <line_editor
+ follows="left|top"
+ height="20"
+ layout="topleft"
+ left_delta="84"
+ name="desc"
+ top_delta="-4"
+ width="180" />
+ <text
+ type="string"
+ length="1"
+ follows="top|left"
+ font="SansSerifSmall"
+ height="10"
+ layout="topleft"
+ left="10"
+ name="desc_label"
+ top_pad="10"
+ width="100">
+ Description:
+ </text>
+ <line_editor
+ follows="left|top"
+ height="40"
+ layout="topleft"
+ left_delta="84"
+ name="desc"
+ top_delta="-4"
+ width="180" />
+
+ <accordion
+ layout="topleft"
+ left="2"
+ width="276"
+ top="95"
+ height="580"
+ follows="all"
+ name="group_accordion">
+ <accordion_tab
+ min_height="75"
+ title="Shortcuts"
+ name="snapshot_destination_tab"
+ an_resize="false">
+ <panel
+ class="floater_snapshot_destination"
+ filename="floater_preview_gesture_shortcut.xml"
+ name="snapshot_destination_tab"/>
+ </accordion_tab>
+ <accordion_tab
+ min_height="400"
+ title="Steps"
+ name="snapshot_file_settings_tab"
+ can_resize="false">
+ <panel
+ class="floater_snapshot_file_settings"
+ filename="floater_preview_gesture_steps.xml"
+ name="snapshot_file_settings_tab"/>
+ </accordion_tab>
+ <accordion_tab
+ min_height="100"
+ title="Info"
+ name="snapshot_capture_tab"
+ can_resize="false">
+ <panel
+ class="floater_snapshot_capture"
+ filename="floater_snapshot_Info.xml"
+ name="snapshot_capture_tab"/>
+ </accordion_tab>
+ <accordion_tab
+ min_height="100"
+ title="Permissions"
+ name="snapshot_capture_tab"
+ can_resize="false">
+ <panel
+ class="floater_snapshot_capture"
+ filename="floater_snapshot_Permissions.xml"
+ name="snapshot_capture_tab"/>
+ </accordion_tab>
+ </accordion>
+ <!--check_box
+ follows="top|left"
+ height="20"
+ label="Active"
+ layout="topleft"
+ left="20"
+ name="active_check"
+ tool_tip="Active gestures can be triggered by chatting their trigger phrases or pressing their hot keys. Gestures usually become inactive when there is a key binding conflict."
+ top="365"
+ width="100" /-->
+
+ <button
+ follows="bottom|left"
+ height="20"
+ label="Preview"
+ layout="topleft"
+ left="20"
+ name="preview_btn"
+ top_pad="-80"
+ width="80" />
+ <button
+ follows="top|left"
+ height="20"
+ label="Save"
+ layout="topleft"
+ left_pad="5"
+ name="save_btn"
+ top_delta="0"
+ width="80" />
+ <button
+ follows="top|left"
+ height="20"
+ label="Cancel (not working)"
+ layout="topleft"
+ left_pad="5"
+ name="save_btn"
+ top_delta="0"
+ width="80" />
+
+</floater> \ No newline at end of file
diff --git a/indra/newview/skins/default/xui/en/floater_preview_gesture_info.xml b/indra/newview/skins/default/xui/en/floater_preview_gesture_info.xml
new file mode 100644
index 0000000000..b4a7e8fefd
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/floater_preview_gesture_info.xml
@@ -0,0 +1,173 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<floater
+ can_minimize="false"
+ follows="left|top"
+ height="155"
+ layout="topleft"
+ name="Gesture"
+ save_rect="true"
+ title="Gesture Shortcut"
+ width="260">
+ <scroll_list
+ follows="top|left"
+ height="110"
+ layout="topleft"
+ left="10"
+ name="step_list"
+ top_pad="10"
+ width="260" />
+ <button
+ follows="top|left"
+ height="20"
+ font="SansSerifSmall"
+ label="Add"
+ layout="topleft"
+ left_pad="-100"
+ name="add_btn"
+ top_pad="5"
+ width="100" />
+ <scroll_list
+ follows="top|left"
+ height="110"
+ layout="topleft"
+ left="10"
+ name="library_list"
+ top_pad="10"
+ width="260">
+ <scroll_list.rows
+ value="Animation" />
+ <scroll_list.rows
+ value="Sound" />
+ <scroll_list.rows
+ value="Chat" />
+ <scroll_list.rows
+ value="Wait" />
+ </scroll_list>
+ <button
+ follows="top|left"
+ height="20"
+ label="Preview"
+ layout="topleft"
+ left="20"
+ name="preview_btn"
+ top_pad="50"
+ width="80" />
+ <button
+ follows="top|left"
+ height="20"
+ label="Save"
+ layout="topleft"
+ left_pad="5"
+ name="save_btn"
+ top_delta="0"
+ width="80" />
+ <button
+ follows="top|left"
+ height="20"
+ label="Cancel (not working)"
+ layout="topleft"
+ left_pad="5"
+ name="save_btn"
+ top_delta="0"
+ width="80" />
+ <text
+ type="string"
+ length="1"
+ follows="top|left"
+ font="SansSerifSmall"
+ height="60"
+ layout="topleft"
+ left="10"
+ name="help_label"
+ top_pad="10"
+ width="200">
+ All steps happen simultaneously,
+unless you add wait steps.
+ </text>
+ <text
+ follows="top|left"
+ height="60"
+ layout="topleft"
+ left="10"
+ name="options_text"
+ top_pad="10"
+ width="205" />
+ <combo_box
+ follows="top|left"
+ height="20"
+ layout="topleft"
+ left_delta="10"
+ name="animation_list"
+ top_pad="10"
+ width="100" />
+ <combo_box
+ follows="top|left"
+ height="20"
+ layout="topleft"
+ left_delta="0"
+ name="sound_list"
+ top_delta="0"
+ width="100" />
+ <line_editor
+ follows="top|left"
+ height="20"
+ layout="topleft"
+ left_delta="0"
+ max_length="127"
+ name="chat_editor"
+ top_delta="0"
+ width="100" />
+ <radio_group
+ draw_border="false"
+ follows="top|left"
+ height="40"
+ layout="topleft"
+ left_pad="8"
+ name="animation_trigger_type"
+ top="445"
+ width="80">
+ <radio_item
+ height="16"
+ label="Start"
+ layout="topleft"
+ left="3"
+ name="start"
+ top="-11"
+ width="80" />
+ <radio_item
+ height="16"
+ label="Stop"
+ layout="topleft"
+ left_delta="0"
+ name="stop"
+ top_pad="10"
+ width="80" />
+ </radio_group>
+ <check_box
+ follows="top|left"
+ height="20"
+ label="until animations are done"
+ layout="topleft"
+ left="16"
+ name="wait_anim_check"
+ top="430"
+ width="100" />
+ <check_box
+ follows="top|left"
+ height="20"
+ label="time in seconds"
+ layout="topleft"
+ left_delta="0"
+ name="wait_time_check"
+ top_delta="20"
+ width="100" />
+ <line_editor
+ follows="top|left"
+ height="20"
+ layout="topleft"
+ left_pad="5"
+ max_length="15"
+ name="wait_time_editor"
+ top_delta="0"
+ width="50" />
+</floater> \ No newline at end of file
diff --git a/indra/newview/skins/default/xui/en/floater_preview_gesture_shortcut.xml b/indra/newview/skins/default/xui/en/floater_preview_gesture_shortcut.xml
new file mode 100644
index 0000000000..75fb24d640
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/floater_preview_gesture_shortcut.xml
@@ -0,0 +1,86 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<floater
+ can_minimize="false"
+ follows="left|top"
+ height="80"
+ layout="topleft"
+ name="Gesture"
+ save_rect="true"
+ title="Gesture Shortcut"
+ width="260">
+ <text
+ type="string"
+ length="1"
+ follows="top|left"
+ font="SansSerifSmall"
+ height="10"
+ layout="topleft"
+ left="10"
+ name="trigger_label"
+ top_pad="10"
+ width="100">
+ Chat:
+ </text>
+ <line_editor
+ follows="left|top"
+ height="20"
+ layout="topleft"
+ left_pad="5"
+ max_length="31"
+ name="trigger_editor"
+ top_delta="-4"
+ width="135" />
+ <text
+ type="string"
+ length="1"
+ follows="top|left"
+ font="SansSerifSmall"
+ height="10"
+ layout="topleft"
+ left="10"
+ name="key_label"
+ top_pad="10"
+ width="100">
+ Keyboard:
+ </text>
+ <combo_box
+ height="20"
+ label="None"
+ layout="topleft"
+ left_pad="5"
+ name="modifier_combo"
+ top_delta="-4"
+ width="50" />
+ <combo_box
+ height="20"
+ label="None"
+ layout="topleft"
+ left_pad="5"
+ name="key_combo"
+ top_delta="0"
+ width="45" />
+ <text
+ type="string"
+ length="1"
+ follows="top|left"
+ font="SansSerifSmall"
+ height="10"
+ layout="topleft"
+ left="10"
+ name="replace_text"
+ tool_tip="Replace the trigger word(s) with these words. For example, trigger &apos;hello&apos; replace with &apos;howdy&apos; will turn the chat &apos;I wanted to say hello&apos; into &apos;I wanted to say howdy&apos; as well as playing the gesture!"
+ top_pad="10"
+ width="100">
+ Replace:
+ </text>
+ <line_editor
+ follows="left|top"
+ height="20"
+ layout="topleft"
+ left_pad="5"
+ max_length="31"
+ name="replace_editor"
+ tool_tip="Replace the trigger word(s) with these words. For example, trigger &apos;hello&apos; replace with &apos;howdy&apos; will turn the chat &apos;I wanted to say hello&apos; into &apos;I wanted to say howdy&apos; as well as playing the gesture"
+ top_delta="-4"
+ width="135" />
+</floater> \ No newline at end of file
diff --git a/indra/newview/skins/default/xui/en/floater_preview_gesture_steps.xml b/indra/newview/skins/default/xui/en/floater_preview_gesture_steps.xml
new file mode 100644
index 0000000000..f0e88b9dd4
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/floater_preview_gesture_steps.xml
@@ -0,0 +1,148 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<floater
+ can_minimize="false"
+ follows="left|top"
+ height="155"
+ layout="topleft"
+ name="Gesture"
+ save_rect="true"
+ title="Gesture Shortcut"
+ width="260">
+ <scroll_list
+ follows="top|left"
+ height="110"
+ layout="topleft"
+ left="10"
+ name="step_list"
+ top_pad="10"
+ width="260" />
+ <button
+ follows="top|left"
+ height="20"
+ font="SansSerifSmall"
+ label="Add"
+ layout="topleft"
+ left_pad="-100"
+ name="add_btn"
+ top_pad="5"
+ width="100" />
+
+ <!--For pop out floater-->
+ <!--scroll_list
+ follows="top|left"
+ height="110"
+ layout="topleft"
+ left="10"
+ name="library_list"
+ top_pad="10"
+ width="260">
+ <scroll_list.rows
+ value="Animation" />
+ <scroll_list.rows
+ value="Sound" />
+ <scroll_list.rows
+ value="Chat" />
+ <scroll_list.rows
+ value="Wait" />
+ </scroll_list>
+ <text
+ type="string"
+ length="1"
+ follows="top|left"
+ font="SansSerifSmall"
+ height="60"
+ layout="topleft"
+ left="10"
+ name="help_label"
+ top_pad="10"
+ width="200">
+ All steps happen simultaneously,
+unless you add wait steps.
+ </text>
+ <text
+ follows="top|left"
+ height="60"
+ layout="topleft"
+ left="10"
+ name="options_text"
+ top_pad="10"
+ width="205" />
+ <combo_box
+ follows="top|left"
+ height="20"
+ layout="topleft"
+ left_delta="10"
+ name="animation_list"
+ top_pad="10"
+ width="100" />
+ <combo_box
+ follows="top|left"
+ height="20"
+ layout="topleft"
+ left_delta="0"
+ name="sound_list"
+ top_delta="0"
+ width="100" />
+ <line_editor
+ follows="top|left"
+ height="20"
+ layout="topleft"
+ left_delta="0"
+ max_length="127"
+ name="chat_editor"
+ top_delta="0"
+ width="100" />
+ <radio_group
+ draw_border="false"
+ follows="top|left"
+ height="40"
+ layout="topleft"
+ left_pad="8"
+ name="animation_trigger_type"
+ top="445"
+ width="80">
+ <radio_item
+ height="16"
+ label="Start"
+ layout="topleft"
+ left="3"
+ name="start"
+ top="-11"
+ width="80" />
+ <radio_item
+ height="16"
+ label="Stop"
+ layout="topleft"
+ left_delta="0"
+ name="stop"
+ top_pad="10"
+ width="80" />
+ </radio_group>
+ <check_box
+ follows="top|left"
+ height="20"
+ label="until animations are done"
+ layout="topleft"
+ left="16"
+ name="wait_anim_check"
+ top="430"
+ width="100" />
+ <check_box
+ follows="top|left"
+ height="20"
+ label="time in seconds"
+ layout="topleft"
+ left_delta="0"
+ name="wait_time_check"
+ top_delta="20"
+ width="100" />
+ <line_editor
+ follows="top|left"
+ height="20"
+ layout="topleft"
+ left_pad="5"
+ max_length="15"
+ name="wait_time_editor"
+ top_delta="0"
+ width="50" /-->
+</floater> \ No newline at end of file
diff --git a/indra/newview/skins/default/xui/en/floater_preview_notecard.xml b/indra/newview/skins/default/xui/en/floater_preview_notecard.xml
new file mode 100644
index 0000000000..a767b40b03
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/floater_preview_notecard.xml
@@ -0,0 +1,93 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<floater
+ auto_tile="true"
+ can_resize="true"
+ default_tab_group="1"
+ follows="left|top"
+ height="361"
+ layout="topleft"
+ min_height="243"
+ min_width="234"
+ name="preview notecard"
+ title="Note:"
+ width="400">
+ <floater.string
+ name="no_object">
+ Unable to find object containing this note.
+ </floater.string>
+ <floater.string
+ name="not_allowed">
+ You do not have permission to view this note.
+ </floater.string>
+ <floater.string
+ name="Title">
+ Notecard: [NAME]
+ </floater.string>
+ <floater.string
+ name="Save">
+ Save
+ </floater.string>
+ <icon
+ follows="top|right"
+ height="16"
+ image_name="icon_lock.tga"
+ layout="topleft"
+ left="340"
+ mouse_opaque="true"
+ name="lock"
+ top="1"
+ width="16" />
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ font="SansSerif"
+ height="19"
+ layout="topleft"
+ left="10"
+ name="desc txt"
+ top="22"
+ width="90">
+ Description:
+ </text>
+ <line_editor
+ border_style="line"
+ border_thickness="1"
+ follows="left|top|right"
+ font="SansSerif"
+ height="22"
+ layout="topleft"
+ left_pad="0"
+ max_length="127"
+ name="desc"
+ width="296" />
+ <text_editor
+ type="string"
+ length="1"
+ embedded_items="true"
+ follows="left|top|right|bottom"
+ font="SansSerif"
+ height="281"
+ ignore_tab="false"
+ layout="topleft"
+ left="4"
+ max_length="65536"
+ name="Notecard Editor"
+ handle_edit_keys_directly="true"
+ tab_group="1"
+ top="46"
+ width="392"
+ word_wrap="true">
+ Loading...
+ </text_editor>
+ <button
+ follows="left|bottom"
+ height="22"
+ label="Save"
+ label_selected="Discard"
+ layout="topleft"
+ left="288"
+ name="Save"
+ top="332"
+ width="100" />
+</floater>
diff --git a/indra/newview/skins/default/xui/en/floater_preview_sound.xml b/indra/newview/skins/default/xui/en/floater_preview_sound.xml
new file mode 100644
index 0000000000..e341dd7b97
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/floater_preview_sound.xml
@@ -0,0 +1,61 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<floater
+ auto_tile="true"
+ height="85"
+ layout="topleft"
+ name="preview_sound"
+ width="280">
+ <floater.string
+ name="Title">
+ Sound: [NAME]
+ </floater.string>
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ font="SansSerif"
+ height="19"
+ layout="topleft"
+ left="10"
+ top="22"
+ name="desc txt"
+ width="90">
+ Description:
+ </text>
+ <line_editor
+ border_style="line"
+ border_thickness="1"
+ follows="left|top|right"
+ font="SansSerif"
+ height="19"
+ layout="topleft"
+ left_pad="0"
+ max_length="127"
+ name="desc"
+ width="170" />
+ <button
+ follows="left|top"
+ height="22"
+ label="Play in World"
+ label_selected="Play in World"
+ layout="topleft"
+ name="Sound play btn"
+ sound_flags="0"
+ top="55"
+ left="10"
+ tool_tip="Play this sound so that others can hear it."
+ width="125" />
+ <button
+ follows="left|top"
+ height="22"
+ font="SansSerifSmall"
+ label="Play Locally"
+ label_selected="Play Locally"
+ layout="topleft"
+ name="Sound audition btn"
+ sound_flags="0"
+ tool_tip="Play this sound so that only you can hear it."
+ left_pad="10"
+ width="125" />
+
+</floater>
diff --git a/indra/newview/skins/default/xui/en/floater_preview_texture.xml b/indra/newview/skins/default/xui/en/floater_preview_texture.xml
new file mode 100644
index 0000000000..7bac6fdb32
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/floater_preview_texture.xml
@@ -0,0 +1,74 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<floater
+ auto_tile="true"
+ can_resize="true"
+ follows="left|bottom"
+ height="331"
+ layout="topleft"
+ min_height="120"
+ min_width="300"
+ name="preview_texture"
+ width="300">
+ <floater.string
+ name="Title">
+ Texture: [NAME]
+ </floater.string>
+ <floater.string
+ name="Copy">
+ Copy To Inventory
+ </floater.string>
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ font="SansSerif"
+ height="19"
+ layout="topleft"
+ left="10"
+ name="desc txt"
+ top="21"
+ width="90">
+ Description:
+ </text>
+ <line_editor
+ border_style="line"
+ border_thickness="1"
+ follows="left|top|right"
+ font="SansSerif"
+ height="19"
+ layout="topleft"
+ left_pad="0"
+ max_length="127"
+ name="desc"
+ width="190" />
+ <button
+ follows="left|bottom"
+ height="22"
+ label="Delete"
+ layout="topleft"
+ left="80"
+ name="Discard"
+ top="302"
+ width="100" />
+ <button
+ follows="left|bottom"
+ height="22"
+ label="Save"
+ layout="topleft"
+ left_pad="5"
+ name="Keep"
+ top_delta="0"
+ width="100" />
+ <text
+ type="string"
+ length="1"
+ follows="left|bottom"
+ height="16"
+ layout="topleft"
+ left="13"
+ name="dimensions"
+ top="287"
+ width="303">
+ [WIDTH]px x [HEIGHT]px
+ </text>
+</floater>
diff --git a/indra/newview/skins/default/xui/en/floater_region_info.xml b/indra/newview/skins/default/xui/en/floater_region_info.xml
new file mode 100644
index 0000000000..a890de3e28
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/floater_region_info.xml
@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<floater
+ height="512"
+ layout="topleft"
+ name="regioninfo"
+ save_rect="true"
+ title="Region/Estate"
+ width="280">
+ <tab_container
+ bottom="512"
+ follows="left|right|top|bottom"
+ layout="topleft"
+ left="1"
+ name="region_panels"
+ right="-1"
+ tab_position="top"
+ top="20" />
+</floater>
diff --git a/indra/newview/skins/default/xui/en/floater_report_abuse.xml b/indra/newview/skins/default/xui/en/floater_report_abuse.xml
new file mode 100644
index 0000000000..fcbc27a5f9
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/floater_report_abuse.xml
@@ -0,0 +1,493 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<floater
+ height="590"
+ layout="topleft"
+ name="floater_report_abuse"
+ title="Report Abuse"
+ width="390">
+ <floater.string
+ name="Screenshot">
+ Screenshot
+ </floater.string>
+ <texture_picker
+ allow_no_texture="true"
+ default_image_name="None"
+ follows="left|top"
+ height="114"
+ layout="topleft"
+ left="238"
+ name="screenshot"
+ top="36"
+ width="134" />
+ <check_box
+ height="16"
+ label="Include screenshot"
+ layout="topleft"
+ left="13"
+ name="screen_check"
+ top="134"
+ width="116" />
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="16"
+ layout="topleft"
+ left_delta="3"
+ name="reporter_title"
+ top_delta="-102"
+ width="50">
+ Reporter:
+ </text>
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="16"
+ layout="topleft"
+ left_pad="12"
+ name="reporter_field"
+ top_delta="0"
+ width="150">
+ Loremipsum Dolorsitamut
+ </text>
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="16"
+ layout="topleft"
+ left="16"
+ name="sim_title"
+ top="48"
+ width="60">
+ Region:
+ </text>
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="16"
+ layout="topleft"
+ left_pad="2"
+ name="sim_field"
+ top_delta="0"
+ width="120">
+ Region Name
+ </text>
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="16"
+ layout="topleft"
+ left="16"
+ name="pos_title"
+ top="64"
+ width="50">
+ Position:
+ </text>
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="16"
+ layout="topleft"
+ left_pad="12"
+ name="pos_field"
+ top_delta="0"
+ width="120">
+ {128.1, 128.1, 15.4}
+ </text>
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="16"
+ layout="topleft"
+ left="16"
+ name="select_object_label"
+ top="82"
+ width="220">
+ Click the button then the object:
+ </text>
+ <button
+ height="32"
+ layout="topleft"
+ left_delta="0"
+ name="pick_btn"
+ picture_style="true"
+ tool_tip="Object Picker - Identify an object as the subject of this report"
+ top_delta="14"
+ width="32" />
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="16"
+ layout="topleft"
+ left_pad="5"
+ name="object_name_label"
+ top_delta="0"
+ width="60">
+ Name:
+ </text>
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="16"
+ layout="topleft"
+ left_pad="6"
+ name="object_name"
+ top_delta="0"
+ width="109">
+ Consetetur Sadipscing
+ </text>
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="16"
+ layout="topleft"
+ left="53"
+ name="owner_name_label"
+ top="112"
+ width="60">
+ Owner:
+ </text>
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="16"
+ layout="topleft"
+ left_pad="6"
+ name="owner_name"
+ top_delta="0"
+ width="109">
+ Hendrerit Vulputate
+ </text>
+ <combo_box
+ height="20"
+ layout="topleft"
+ left="16"
+ name="category_combo"
+ tool_tip="Category -- select the category that best describes this report"
+ top="156"
+ width="356">
+ <combo_box.item
+ label="Select category"
+ name="Select_category"
+ value="0" />
+ <combo_box.item
+ label="Age &gt; Age play"
+ name="Age__Age_play"
+ value="31" />
+ <combo_box.item
+ label="Age &gt; Adult resident on Teen Second Life"
+ name="Age__Adult_resident_on_Teen_Second_Life"
+ value="32" />
+ <combo_box.item
+ label="Age &gt; Underage resident outside of Teen Second Life"
+ name="Age__Underage_resident_outside_of_Teen_Second_Life"
+ value="33" />
+ <combo_box.item
+ label="Assault &gt; Combat sandbox / unsafe area"
+ name="Assault__Combat_sandbox___unsafe_area"
+ value="34" />
+ <combo_box.item
+ label="Assault &gt; Safe area"
+ name="Assault__Safe_area"
+ value="35" />
+ <combo_box.item
+ label="Assault &gt; Weapons testing sandbox"
+ name="Assault__Weapons_testing_sandbox"
+ value="36" />
+ <combo_box.item
+ label="Commerce &gt; Failure to deliver product or service"
+ name="Commerce__Failure_to_deliver_product_or_service"
+ value="38" />
+ <combo_box.item
+ label="Disclosure &gt; Real world information"
+ name="Disclosure__Real_world_information"
+ value="39" />
+ <combo_box.item
+ label="Disclosure &gt; Remotely monitoring chat"
+ name="Disclosure__Remotely_monitoring chat"
+ value="40" />
+ <combo_box.item
+ label="Disclosure &gt; Second Life information/chat/IMs"
+ name="Disclosure__Second_Life_information_chat_IMs"
+ value="41" />
+ <combo_box.item
+ label="Disturbing the peace &gt; Unfair use of region resources"
+ name="Disturbing_the_peace__Unfair_use_of_region_resources"
+ value="42" />
+ <combo_box.item
+ label="Disturbing the peace &gt; Excessive scripted objects"
+ name="Disturbing_the_peace__Excessive_scripted_objects"
+ value="43" />
+ <combo_box.item
+ label="Disturbing the peace &gt; Object littering"
+ name="Disturbing_the_peace__Object_littering"
+ value="44" />
+ <combo_box.item
+ label="Disturbing the peace &gt; Repetitive spam"
+ name="Disturbing_the_peace__Repetitive_spam"
+ value="45" />
+ <combo_box.item
+ label="Disturbing the peace &gt; Unwanted advert spam"
+ name="Disturbing_the_peace__Unwanted_advert_spam"
+ value="46" />
+ <combo_box.item
+ label="Fraud &gt; L$"
+ name="Fraud__L$"
+ value="47" />
+ <combo_box.item
+ label="Fraud &gt; Land"
+ name="Fraud__Land"
+ value="48" />
+ <combo_box.item
+ label="Fraud &gt; Pyramid scheme or chain letter"
+ name="Fraud__Pyramid_scheme_or_chain_letter"
+ value="49" />
+ <combo_box.item
+ label="Fraud &gt; US$"
+ name="Fraud__US$"
+ value="50" />
+ <combo_box.item
+ label="Harassment &gt; Advert farms / visual spam"
+ name="Harassment__Advert_farms___visual_spam"
+ value="51" />
+ <combo_box.item
+ label="Harassment &gt; Defaming individuals or groups"
+ name="Harassment__Defaming_individuals_or_groups"
+ value="52" />
+ <combo_box.item
+ label="Harassment &gt; Impeding movement"
+ name="Harassment__Impeding_movement"
+ value="53" />
+ <combo_box.item
+ label="Harassment &gt; Sexual harassment"
+ name="Harassment__Sexual_harassment"
+ value="54" />
+ <combo_box.item
+ label="Harassment &gt; Solicting/inciting others to violate ToS"
+ name="Harassment__Solicting_inciting_others_to_violate_ToS"
+ value="55" />
+ <combo_box.item
+ label="Harassment &gt; Verbal abuse"
+ name="Harassment__Verbal_abuse"
+ value="56" />
+ <combo_box.item
+ label="Indecency &gt; Broadly offensive content or conduct"
+ name="Indecency__Broadly_offensive_content_or_conduct"
+ value="57" />
+ <combo_box.item
+ label="Indecency &gt; Inappropriate avatar name"
+ name="Indecency__Inappropriate_avatar_name"
+ value="59" />
+ <combo_box.item
+ label="Indecency &gt; Inappropriate content or conduct in a PG region"
+ name="Indecency__Mature_content_in_PG_region"
+ value="60" />
+ <combo_box.item
+ label="Indecency &gt; Inappropriate content or conduct in a Mature region"
+ name="Indecency__Inappropriate_content_in_Mature_region"
+ value="69" />
+ <combo_box.item
+ label="Intellectual property infringement &gt; Content Removal"
+ name="Intellectual_property_infringement_Content_Removal"
+ value="66" />
+ <combo_box.item
+ label="Intellectual property infringement &gt; CopyBot or Permissions Exploit"
+ name="Intellectual_property_infringement_CopyBot_or_Permissions_Exploit"
+ value="37" />
+ <combo_box.item
+ label="Intolerance"
+ name="Intolerance"
+ value="61" />
+ <combo_box.item
+ label="Land &gt; Abuse of sandbox resources"
+ name="Land__Abuse_of_sandbox_resources"
+ value="62" />
+ <combo_box.item
+ label="Land &gt; Encroachment &gt; Objects/textures"
+ name="Land__Encroachment__Objects_textures"
+ value="63" />
+ <combo_box.item
+ label="Land &gt; Encroachment &gt; Particles"
+ name="Land__Encroachment__Particles"
+ value="64" />
+ <combo_box.item
+ label="Land &gt; Encroachment &gt; Trees/plants"
+ name="Land__Encroachment__Trees_plants"
+ value="65" />
+ <combo_box.item
+ label="Wagering/gambling"
+ name="Wagering_gambling"
+ value="67" />
+ <combo_box.item
+ label="Other"
+ name="Other"
+ value="68" />
+ </combo_box>
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="16"
+ layout="topleft"
+ left_delta="0"
+ name="abuser_name_title"
+ top_pad="10"
+ width="180">
+ Abuser name:
+ </text>
+ <line_editor
+ border_style="line"
+ border_thickness="1"
+ follows="left|top"
+ height="16"
+ layout="topleft"
+ left_delta="0"
+ max_length="32"
+ name="abuser_name_edit"
+ top_pad="2"
+ width="180" />
+ <button
+ height="20"
+ label="Choose Resident"
+ layout="topleft"
+ left_pad="10"
+ name="select_abuser"
+ tool_tip="Select the name of the abuser from a list"
+ top_delta="-2"
+ width="160" />
+ <check_box
+ height="16"
+ label="Don&apos;t know abuser&apos;s name"
+ layout="topleft"
+ left="13"
+ name="omit_abuser_name"
+ tool_tip="Check this if you are unable to provide the abuser&apos;s name"
+ top="224"
+ visible="false"
+ width="116" />
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="16"
+ layout="topleft"
+ left_delta="3"
+ name="abuser_name_title2"
+ top_pad="8"
+ width="180">
+ Location of Abuse:
+ </text>
+ <line_editor
+ border_style="line"
+ border_thickness="1"
+ follows="left|top"
+ height="16"
+ layout="topleft"
+ left_delta="0"
+ max_length="256"
+ name="abuse_location_edit"
+ top_pad="2"
+ width="356" />
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="16"
+ layout="topleft"
+ left_delta="0"
+ name="sum_title"
+ top_pad="8"
+ width="180">
+ Summary:
+ </text>
+ <line_editor
+ border_style="line"
+ border_thickness="1"
+ follows="left|top"
+ height="16"
+ layout="topleft"
+ left_delta="0"
+ max_length="64"
+ name="summary_edit"
+ top_pad="2"
+ width="356" />
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="16"
+ layout="topleft"
+ left_delta="0"
+ name="dscr_title"
+ top_pad="8"
+ width="180">
+ Details:
+ </text>
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="48"
+ layout="topleft"
+ left_delta="54"
+ name="bug_aviso"
+ top_delta="0"
+ width="308">
+ Please be specific about the date, location, nature of
+abuse, relevant chat/IM text, and select the object
+if possible.
+ </text>
+ <text_editor
+ follows="left|top"
+ height="146"
+ layout="topleft"
+ left="16"
+ max_length="800"
+ mouse_opaque="false"
+ name="details_edit"
+ top="386"
+ width="356"
+ word_wrap="true" />
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="16"
+ layout="topleft"
+ left_delta="0"
+ name="incomplete_title"
+ top_pad="8"
+ width="342">
+ Note: Incomplete reports will not be investigated.
+ </text>
+ <button
+ bottom="580"
+ follows="right|bottom"
+ height="20"
+ label="Cancel"
+ label_selected="Cancel"
+ layout="topleft"
+ name="cancel_btn"
+ right="373"
+ width="150" />
+ <button
+ bottom="580"
+ follows="right|bottom"
+ height="20"
+ label="Report Abuse"
+ label_selected="Report Abuse"
+ layout="topleft"
+ name="send_btn"
+ right="217"
+ width="150" />
+</floater>
diff --git a/indra/newview/skins/default/xui/en/floater_script_debug.xml b/indra/newview/skins/default/xui/en/floater_script_debug.xml
new file mode 100644
index 0000000000..2ae0afa168
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/floater_script_debug.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<multi_floater
+ can_resize="true"
+ height="233"
+ layout="topleft"
+ name="script debug floater"
+ save_rect="true"
+ title="Script Warning/Error"
+ width="450">
+ <tab_container
+ follows="left|top|right|bottom"
+ height="217"
+ layout="topleft"
+ left="1"
+ name="Preview Tabs"
+ tab_position="bottom"
+ top="16"
+ width="448" />
+</multi_floater>
diff --git a/indra/newview/skins/default/xui/en/floater_script_debug_panel.xml b/indra/newview/skins/default/xui/en/floater_script_debug_panel.xml
new file mode 100644
index 0000000000..2dd7a1e777
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/floater_script_debug_panel.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<floater
+ can_resize="true"
+ follows="left|top|right|bottom"
+ height="200"
+ layout="topleft"
+ name="script"
+ short_title="[All scripts]"
+ title="[All scripts]"
+ width="440">
+ <text_editor
+ bottom="197"
+ follows="left|top|right|bottom"
+ height="176"
+ layout="topleft"
+ max_length="10000"
+ name="Chat History Editor"
+ width="420"
+ word_wrap="true" />
+</floater>
diff --git a/indra/newview/skins/default/xui/en/floater_script_preview.xml b/indra/newview/skins/default/xui/en/floater_script_preview.xml
new file mode 100644
index 0000000000..cb3ff92363
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/floater_script_preview.xml
@@ -0,0 +1,62 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<floater
+ auto_tile="true"
+ can_resize="true"
+ height="550"
+ layout="topleft"
+ left_delta="343"
+ min_height="271"
+ min_width="290"
+ name="preview lsl text"
+ save_rect="true"
+ title="Script: Rotation Script"
+ top_delta="0"
+ width="500">
+ <floater.string
+ name="Title">
+ Script: [NAME]
+ </floater.string>
+ <panel
+ follows="left|top|right|bottom"
+ height="508"
+ layout="topleft"
+ left="0"
+ name="script panel"
+ top="42"
+ width="497" />
+ <icon
+ follows="top|right"
+ height="16"
+ image_name="icon_lock.tga"
+ layout="topleft"
+ left="444"
+ mouse_opaque="true"
+ name="lock"
+ top="3"
+ width="16" />
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ font="SansSerif"
+ height="19"
+ layout="topleft"
+ left="13"
+ name="desc txt"
+ top="19"
+ width="80">
+ Description:
+ </text>
+ <line_editor
+ border_style="line"
+ border_thickness="1"
+ follows="left|top|right"
+ font="SansSerif"
+ height="19"
+ layout="topleft"
+ left_delta="80"
+ max_length="127"
+ name="desc"
+ top_delta="0"
+ width="394" />
+</floater>
diff --git a/indra/newview/skins/default/xui/en/floater_script_queue.xml b/indra/newview/skins/default/xui/en/floater_script_queue.xml
new file mode 100644
index 0000000000..ad91e8156b
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/floater_script_queue.xml
@@ -0,0 +1,49 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<floater
+ auto_tile="true"
+ can_resize="true"
+ height="400"
+ layout="topleft"
+ name="queue"
+ save_rect="true"
+ title="Reset Progress"
+ width="300">
+ <floater.string
+ name="Starting">
+ Starting [START] of [COUNT] items.
+ </floater.string>
+ <floater.string
+ name="Done">
+ Done.
+ </floater.string>
+ <floater.string
+ name="Resetting">
+ Resetting
+ </floater.string>
+ <floater.string
+ name="Running">
+ Running
+ </floater.string>
+ <floater.string
+ name="NotRunning">
+ Not running
+ </floater.string>
+ <button
+ follows="right|bottom"
+ height="24"
+ label="Close"
+ label_selected="Close"
+ layout="topleft"
+ left="220"
+ name="close"
+ top="368"
+ width="64" />
+ <scroll_list
+ follows="left|top|right|bottom"
+ height="344"
+ layout="topleft"
+ left="4"
+ name="queue output"
+ top="20"
+ width="292" />
+</floater>
diff --git a/indra/newview/skins/default/xui/en/floater_script_search.xml b/indra/newview/skins/default/xui/en/floater_script_search.xml
new file mode 100644
index 0000000000..bb0c60e75b
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/floater_script_search.xml
@@ -0,0 +1,90 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<floater
+ default_tab_group="1"
+ height="120"
+ layout="topleft"
+ name="script search"
+ title="Script Search"
+ width="300">
+ <check_box
+ control_name="LSLFindCaseInsensitivity"
+ height="16"
+ label="Case Insensitive"
+ layout="topleft"
+ left="55"
+ name="case_text"
+ top="61"
+ width="240" />
+ <button
+ height="24"
+ label="Search"
+ label_selected="Search"
+ layout="topleft"
+ left="10"
+ name="search_btn"
+ top="84"
+ width="90" />
+ <button
+ height="24"
+ label="Replace"
+ label_selected="Replace"
+ layout="topleft"
+ left_pad="5"
+ name="replace_btn"
+ top_delta="0"
+ width="90" />
+ <button
+ height="24"
+ label="Replace All"
+ label_selected="Replace All"
+ layout="topleft"
+ left_pad="5"
+ name="replace_all_btn"
+ top_delta="0"
+ width="90" />
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="16"
+ layout="topleft"
+ left="5"
+ name="txt"
+ top="21"
+ width="45">
+ Search
+ </text>
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="16"
+ layout="topleft"
+ left_delta="0"
+ name="txt2"
+ top_pad="5"
+ width="45">
+ Replace
+ </text>
+ <line_editor
+ border_style="line"
+ border_thickness="1"
+ follows="left|top"
+ height="16"
+ layout="topleft"
+ left="55"
+ name="search_text"
+ tab_group="1"
+ top="21"
+ width="240" />
+ <line_editor
+ border_style="line"
+ border_thickness="1"
+ follows="left|top"
+ height="16"
+ layout="topleft"
+ left_delta="0"
+ name="replace_text"
+ top_pad="5"
+ width="240" />
+</floater>
diff --git a/indra/newview/skins/default/xui/en/floater_select_key.xml b/indra/newview/skins/default/xui/en/floater_select_key.xml
new file mode 100644
index 0000000000..b89af0ef3e
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/floater_select_key.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<floater
+ border="true"
+ can_close="false"
+ can_minimize="false"
+ height="100"
+ layout="topleft"
+ name="modal container"
+ width="240">
+ <button
+ height="20"
+ label="Cancel"
+ label_selected="Cancel"
+ layout="topleft"
+ left="138"
+ name="Cancel"
+ top="70"
+ width="82" />
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ font="SansSerif"
+ height="16"
+ layout="topleft"
+ left="20"
+ name="Save item as:"
+ top="10"
+ width="200">
+ Press a key to select
+ </text>
+</floater>
diff --git a/indra/newview/skins/default/xui/en/floater_sell_land.xml b/indra/newview/skins/default/xui/en/floater_sell_land.xml
new file mode 100644
index 0000000000..cf26b7ab47
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/floater_sell_land.xml
@@ -0,0 +1,326 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<floater
+ can_minimize="false"
+ height="600"
+ layout="topleft"
+ name="sell land"
+ single_instance="true"
+ title="Sell Land"
+ width="280">
+ <texture_picker
+ enabled="false"
+ follows="top|left"
+ height="135"
+ layout="topleft"
+ left="50"
+ name="info_image"
+ right="230"
+ top="20"
+ width="180" />
+ <text
+ type="string"
+ length="1"
+ top="145"
+ follows="top|left"
+ layout="topleft"
+ left="16"
+ name="info_parcel_label"
+ width="48">
+ Parcel:
+ </text>
+ <text
+ type="string"
+ length="1"
+ bottom_delta="5"
+ follows="top|left"
+ font="SansSerif"
+ height="16"
+ layout="topleft"
+ left="56"
+ name="info_parcel"
+ right="-20">
+ PARCEL NAME
+ </text>
+ <text
+ type="string"
+ length="1"
+ follows="top|left"
+ layout="topleft"
+ left="16"
+ name="info_size_label"
+ width="48">
+ Size:
+ </text>
+ <text
+ type="string"
+ length="1"
+ bottom_delta="21"
+ follows="top|left"
+ font="SansSerif"
+ height="32"
+ layout="topleft"
+ left="56"
+ name="info_size"
+ right="-20">
+ [AREA] m²
+ </text>
+ <text
+ type="string"
+ length="1"
+ follows="top|left"
+ font="SansSerifBig"
+ height="24"
+ layout="topleft"
+ left="16"
+ name="info_action"
+ text_color="white"
+ top="190"
+ width="200">
+ To sell this parcel:
+ </text>
+ <icon
+ follows="top|left"
+ height="64"
+ image_name="badge_note.j2c"
+ layout="topleft"
+ left="0"
+ name="step_price"
+ top="211"
+ width="64" />
+ <text
+ type="string"
+ length="1"
+ bottom_delta="-38"
+ follows="top|left"
+ font="SansSerif"
+ height="16"
+ layout="topleft"
+ left="72"
+ name="price_label"
+ right="-20">
+ Set a price:
+ </text>
+ <text
+ type="string"
+ length="1"
+ follows="top|left"
+ height="16"
+ layout="topleft"
+ left="72"
+ name="price_text"
+ right="-20">
+ Choose an appropriate price.
+ </text>
+ <text
+ type="string"
+ length="1"
+ height="16"
+ layout="topleft"
+ left="72"
+ name="price_ld"
+ width="20">
+ L$
+ </text>
+ <line_editor
+ type="string"
+ length="1"
+ follows="top|left"
+ height="16"
+ layout="topleft"
+ left_delta="20"
+ name="price"
+ top_delta="0"
+ width="100">
+ 0
+ </line_editor>
+ <text
+ type="string"
+ length="1"
+ height="16"
+ layout="topleft"
+ left="72"
+ name="price_per_m"
+ top_delta="25"
+ width="200">
+ (L$[PER_METER] per m²)
+ </text>
+ <icon
+ follows="top|left"
+ height="64"
+ image_name="badge_note.j2c"
+ layout="topleft"
+ left="0"
+ name="step_sell_to"
+ width="64" />
+ <text
+ type="string"
+ length="1"
+ bottom_delta="-38"
+ follows="top|left"
+ font="SansSerif"
+ height="16"
+ layout="topleft"
+ left="72"
+ name="sell_to_label"
+ right="-20">
+ Sell the land to:
+ </text>
+ <text
+ type="string"
+ length="1"
+ follows="top|left"
+ height="16"
+ layout="topleft"
+ left="72"
+ name="sell_to_text"
+ right="-20">
+ Choose whether to sell to anyone
+or a particular buyer.
+ </text>
+ <combo_box
+ follows="top|right"
+ height="16"
+ layout="topleft"
+ left_delta="0"
+ name="sell_to"
+ top_delta="32"
+ width="130">
+ <combo_box.item
+ enabled="false"
+ label="-- select one --"
+ name="--selectone--"
+ value="select" />
+ <combo_box.item
+ label="Anyone"
+ name="Anyone"
+ value="anyone" />
+ <combo_box.item
+ label="Specific user:"
+ name="Specificuser:"
+ value="user" />
+ </combo_box>
+ <line_editor
+ enabled="false"
+ follows="top|right"
+ height="16"
+ layout="topleft"
+ left_delta="0"
+ name="sell_to_agent"
+ top_pad="4"
+ width="130" />
+ <button
+ height="16"
+ font="SansSerifSmall"
+ label="Select"
+ layout="topleft"
+ left_pad="5"
+ name="sell_to_select_agent"
+ top_delta="0"
+ width="60" />
+ <icon
+ follows="top|left"
+ height="64"
+ image_name="badge_note.j2c"
+ layout="topleft"
+ left="0"
+ name="step_sell_objects"
+ width="64" />
+ <text
+ type="string"
+ length="1"
+ bottom_delta="-38"
+ follows="top|left"
+ font="SansSerif"
+ height="16"
+ layout="topleft"
+ left="72"
+ name="sell_objects_label"
+ right="-20">
+ Sell the objects with the land?
+ </text>
+ <text
+ type="string"
+ length="1"
+ font="SansSerifSmall"
+ bottom_delta="20"
+ follows="top|left"
+ height="16"
+ layout="topleft"
+ left="72"
+ name="sell_objects_text">
+ Land owner&apos;s transferable objects
+on parcel will change ownership.
+ </text>
+ <radio_group
+ top_pad="15"
+ follows="top|right"
+ height="40"
+ layout="topleft"
+ left="72"
+ name="sell_objects"
+ right="420">
+ <radio_item
+ bottom="40"
+ height="0"
+ layout="topleft"
+ left="10"
+ name="none"
+ visible="false" />
+ <radio_item
+ bottom="20"
+ height="16"
+ label="No, keep ownership of objects"
+ layout="topleft"
+ left="10"
+ name="no" />
+ <radio_item
+ bottom="40"
+ height="16"
+ label="Yes, sell objects with land"
+ layout="topleft"
+ left="10"
+ name="yes" />
+ </radio_group>
+ <button
+ height="16"
+ font="SansSerifSmall"
+ label="Show Objects"
+ layout="topleft"
+ name="show_objects"
+ left="100"
+ top_pad="10"
+ width="110" />
+ <text
+ type="string"
+ length="1"
+ bottom_delta="30"
+ follows="top|left"
+ font="SansSerifBig"
+ height="16"
+ layout="topleft"
+ left="16"
+ name="nag_message_label"
+ right="-20">
+ REMEMBER: All sales are final.
+ </text>
+ <button
+ follows="bottom|left"
+ height="20"
+ font="SansSerifSmall"
+ label="Set Land For Sale"
+ layout="topleft"
+ left_delta="0"
+ name="sell_btn"
+ top_pad="10"
+ width="130" />
+ <button
+ follows="bottom|right"
+ height="20"
+ font="SansSerifSmall"
+ label="Cancel"
+ layout="topleft"
+ left_pad="30"
+ name="cancel_btn"
+ top_delta="0"
+ width="90" />
+</floater>
diff --git a/indra/newview/skins/default/xui/en/floater_settings_debug.xml b/indra/newview/skins/default/xui/en/floater_settings_debug.xml
new file mode 100644
index 0000000000..4d4dc084bf
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/floater_settings_debug.xml
@@ -0,0 +1,137 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<floater
+ can_minimize="false"
+ height="215"
+ layout="topleft"
+ name="settings_debug"
+ title="Debug Settings"
+ width="350">
+ <combo_box
+ allow_text_entry="true"
+ follows="top|left"
+ height="22"
+ layout="topleft"
+ left="15"
+ max_chars="255"
+ name="settings_combo"
+ top="30"
+ width="320">
+ <combo_box.commit_callback
+ function="SettingSelect" />
+ </combo_box>
+ <text_editor
+ enabled="false"
+ height="60"
+ hide_scrollbar="true"
+ layout="topleft"
+ left_delta="0"
+ name="comment_text"
+ top_pad="10"
+ width="320"
+ word_wrap="true" />
+ <combo_box
+ follows="top|left"
+ height="20"
+ layout="topleft"
+ left_delta="0"
+ name="boolean_combo"
+ top_pad="10"
+ visible="false"
+ width="100">
+ <combo_box.item
+ label="TRUE"
+ name="TRUE"
+ value="true" />
+ <combo_box.item
+ label="FALSE"
+ name="FALSE"
+ value="" />
+ <combo_box.commit_callback
+ function="CommitSettings" />
+ </combo_box>
+ <line_editor
+ height="20"
+ layout="topleft"
+ left_delta="0"
+ name="val_text"
+ top_delta="0"
+ visible="false"
+ width="300" >
+ <line_editor.commit_callback
+ function="CommitSettings" />
+ </line_editor>
+ <color_swatch
+ bottom="185"
+ can_apply_immediately="true"
+ height="55"
+ name="val_color_swatch"
+ label="Color"
+ layout="topleft"
+ width="37" >
+ <color_swatch.commit_callback
+ function="CommitSettings" />
+ </color_swatch>
+ <spinner
+ height="20"
+ label="x"
+ layout="topleft"
+ left_delta="0"
+ max_val="1e+007"
+ name="val_spinner_1"
+ top_delta="10"
+ visible="false"
+ width="120" >
+ <spinner.commit_callback
+ function="CommitSettings" />
+ </spinner>
+ <spinner
+ height="20"
+ label="x"
+ layout="topleft"
+ left_pad="15"
+ max_val="1e+007"
+ name="val_spinner_2"
+ top_delta="0"
+ visible="false"
+ width="120">
+ <spinner.commit_callback
+ function="CommitSettings" />
+ </spinner>
+ <spinner
+ height="20"
+ label="x"
+ layout="topleft"
+ left="15"
+ max_val="1e+007"
+ name="val_spinner_3"
+ top="160"
+ visible="false"
+ width="120">
+ <spinner.commit_callback
+ function="CommitSettings" />
+ </spinner>
+ <spinner
+ height="20"
+ label="x"
+ layout="topleft"
+ left_pad="15"
+ max_val="1e+007"
+ name="val_spinner_4"
+ top_delta="0"
+ visible="false"
+ width="120" >
+ <spinner.commit_callback
+ function="CommitSettings" />
+ </spinner>
+ <button
+ height="22"
+ label="Reset to default"
+ layout="topleft"
+ left="15"
+ name="default_btn"
+ top="186"
+ width="150" >
+ <button.commit_callback
+ function="ClickDefault" />
+ </button>
+</floater>
diff --git a/indra/newview/skins/default/xui/en/floater_snapshot.xml b/indra/newview/skins/default/xui/en/floater_snapshot.xml
new file mode 100644
index 0000000000..1d2978adb8
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/floater_snapshot.xml
@@ -0,0 +1,394 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<floater
+ can_minimize="false"
+ follows="left|top"
+ height="526"
+ layout="topleft"
+ name="Snapshot"
+ save_rect="true"
+ title="Snapshot Preview"
+ width="215">
+ <floater.string
+ name="unknown">
+ unknown
+ </floater.string>
+ <text
+ type="string"
+ length="1"
+ follows="top|left"
+ height="15"
+ layout="topleft"
+ left="10"
+ name="type_label"
+ top="25"
+ width="195">
+ Snapshot destination
+ </text>
+ <radio_group
+ height="60"
+ label="Snapshot type"
+ layout="topleft"
+ left_delta="0"
+ name="snapshot_type_radio"
+ top_pad="5"
+ width="195">
+ <radio_item
+ bottom="19"
+ height="16"
+ label="Send via email"
+ layout="topleft"
+ name="postcard" />
+ <radio_item
+ bottom="38"
+ height="16"
+ label="Save to your inventory (L$[AMOUNT])"
+ layout="topleft"
+ name="texture" />
+ <radio_item
+ bottom="57"
+ height="16"
+ label="Save to your hard drive"
+ layout="topleft"
+ name="local" />
+ </radio_group>
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="25"
+ layout="topleft"
+ left_delta="0"
+ name="file_size_label"
+ top_pad="106"
+ width="195">
+ File size: [SIZE] KB
+ </text>
+ <button
+ follows="left|top"
+ height="20"
+ label="Refresh Snapshot"
+ layout="topleft"
+ left_delta="0"
+ name="new_snapshot_btn"
+ top_delta="15"
+ width="195" />
+ <button
+ follows="left|top"
+ height="20"
+ label="Send"
+ layout="topleft"
+ left_delta="0"
+ name="send_btn"
+ top_pad="2"
+ width="105" />
+ <button
+ follows="left|top"
+ height="20"
+ label="Save (L$[AMOUNT])"
+ layout="topleft"
+ left_delta="0"
+ name="upload_btn"
+ top_delta="0"
+ width="105" />
+ <flyout_button
+ follows="left|top"
+ height="20"
+ label="Save"
+ layout="topleft"
+ left_delta="0"
+ name="save_btn"
+ tool_tip="Save image to a file"
+ top_delta="0"
+ width="105">
+ <flyout_button.item
+ label="Save"
+ value="save" />
+ <flyout_button.item
+ label="Save As..."
+ value="save as" />
+ </flyout_button>
+ <button
+ follows="left|top"
+ height="20"
+ label="Cancel"
+ layout="topleft"
+ left_pad="5"
+ name="discard_btn"
+ top_delta="0"
+ width="85" />
+ <button
+ follows="left|top"
+ font="SansSerifSmall"
+ height="20"
+ label="More &gt;&gt;"
+ layout="topleft"
+ left="10"
+ name="more_btn"
+ tool_tip="Advanced Options"
+ top="270"
+ width="80" />
+ <button
+ follows="left|top"
+ font="SansSerifSmall"
+ height="20"
+ label="&lt;&lt; Less"
+ layout="topleft"
+ left_delta="0"
+ name="less_btn"
+ tool_tip="Advanced Options"
+ top_delta="0"
+ width="80" />
+ <text
+ type="string"
+ length="1"
+ follows="top|left"
+ height="15"
+ layout="topleft"
+ left_delta="0"
+ name="type_label2"
+ top_pad="5"
+ width="115">
+ Size
+ </text>
+ <text
+ type="string"
+ length="1"
+ follows="top|left"
+ height="15"
+ layout="topleft"
+ left_pad="5"
+ name="format_label"
+ top_delta="0"
+ width="70">
+ Format
+ </text>
+ <combo_box
+ height="20"
+ label="Resolution"
+ layout="topleft"
+ left="10"
+ name="postcard_size_combo"
+ top="312"
+ width="115">
+ <combo_box.item
+ label="Current Window"
+ name="CurrentWindow"
+ value="[i0,i0]" />
+ <combo_box.item
+ label="640x480"
+ name="640x480"
+ value="[i640,i480]" />
+ <combo_box.item
+ label="800x600"
+ name="800x600"
+ value="[i800,i600]" />
+ <combo_box.item
+ label="1024x768"
+ name="1024x768"
+ value="[i1024,i768]" />
+ <combo_box.item
+ label="Custom"
+ name="Custom"
+ value="[i-1,i-1]" />
+ </combo_box>
+ <combo_box
+ height="20"
+ label="Resolution"
+ layout="topleft"
+ left_delta="0"
+ name="texture_size_combo"
+ top_delta="0"
+ width="115">
+ <combo_box.item
+ label="Current Window"
+ name="CurrentWindow"
+ value="[i0,i0]" />
+ <combo_box.item
+ label="Small (128x128)"
+ name="Small(128x128)"
+ value="[i128,i128]" />
+ <combo_box.item
+ label="Medium (256x256)"
+ name="Medium(256x256)"
+ value="[i256,i256]" />
+ <combo_box.item
+ label="Large (512x512)"
+ name="Large(512x512)"
+ value="[i512,i512]" />
+ <combo_box.item
+ label="Custom"
+ name="Custom"
+ value="[i-1,i-1]" />
+ </combo_box>
+ <combo_box
+ height="20"
+ label="Resolution"
+ layout="topleft"
+ left_delta="0"
+ name="local_size_combo"
+ top_delta="0"
+ width="115">
+ <combo_box.item
+ label="Current Window"
+ name="CurrentWindow"
+ value="[i0,i0]" />
+ <combo_box.item
+ label="320x240"
+ name="320x240"
+ value="[i320,i240]" />
+ <combo_box.item
+ label="640x480"
+ name="640x480"
+ value="[i640,i480]" />
+ <combo_box.item
+ label="800x600"
+ name="800x600"
+ value="[i800,i600]" />
+ <combo_box.item
+ label="1024x768"
+ name="1024x768"
+ value="[i1024,i768]" />
+ <combo_box.item
+ label="1280x1024"
+ name="1280x1024"
+ value="[i1280,i1024]" />
+ <combo_box.item
+ label="1600x1200"
+ name="1600x1200"
+ value="[i1600,i1200]" />
+ <combo_box.item
+ label="Custom"
+ name="Custom"
+ value="[i-1,i-1]" />
+ </combo_box>
+ <combo_box
+ height="20"
+ label="Format"
+ layout="topleft"
+ left_pad="5"
+ name="local_format_combo"
+ top_delta="0"
+ width="70">
+ <combo_box.item
+ label="PNG"
+ name="PNG" />
+ <combo_box.item
+ label="JPEG"
+ name="JPEG" />
+ <combo_box.item
+ label="BMP"
+ name="BMP" />
+ </combo_box>
+ <spinner
+ allow_text_entry="false"
+ decimal_digits="0"
+ follows="left|top"
+ height="20"
+ increment="32"
+ label="Width"
+ label_width="30"
+ layout="topleft"
+ left="10"
+ max_val="6016"
+ min_val="32"
+ name="snapshot_width"
+ top="337"
+ width="95" />
+ <spinner
+ allow_text_entry="false"
+ decimal_digits="0"
+ follows="left|top"
+ height="20"
+ increment="32"
+ label="Height"
+ label_width="35"
+ layout="topleft"
+ left_pad="5"
+ max_val="6016"
+ min_val="32"
+ name="snapshot_height"
+ top_delta="0"
+ width="95" />
+ <check_box
+ bottom_delta="20"
+ label="Constrain Proportions"
+ layout="topleft"
+ left="10"
+ name="keep_aspect_check" />
+ <slider
+ decimal_digits="0"
+ follows="left|top"
+ height="15"
+ increment="1"
+ initial_value="75"
+ label="Image Quality"
+ layout="topleft"
+ left_delta="0"
+ max_val="100"
+ name="image_quality_slider"
+ top_pad="5"
+ width="210" />
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="20"
+ layout="topleft"
+ left_delta="0"
+ name="layer_type_label"
+ top_pad="8"
+ width="50">
+ Capture:
+ </text>
+ <combo_box
+ height="20"
+ label="Image Layers"
+ layout="topleft"
+ left_delta="50"
+ name="layer_types"
+ top_delta="-3"
+ width="145">
+ <combo_box.item
+ label="Colors"
+ name="Colors"
+ value="colors" />
+ <combo_box.item
+ label="Depth"
+ name="Depth"
+ value="depth" />
+ <combo_box.item
+ label="Object Mattes"
+ name="ObjectMattes"
+ value="objects" />
+ </combo_box>
+ <check_box
+ bottom_delta="20"
+ label="Show interface in snapshot"
+ layout="topleft"
+ left="10"
+ name="ui_check" />
+ <check_box
+ bottom_delta="20"
+ label="Show HUD objects in snapshot"
+ layout="topleft"
+ left="10"
+ name="hud_check" />
+ <check_box
+ bottom_delta="20"
+ label="Keep open after saving"
+ layout="topleft"
+ left="10"
+ name="keep_open_check" />
+ <check_box
+ bottom_delta="20"
+ label="Freeze frame (fullscreen preview)"
+ layout="topleft"
+ left="10"
+ name="freeze_frame_check" />
+ <check_box
+ bottom_delta="20"
+ label="Auto-refresh"
+ layout="topleft"
+ left="10"
+ name="auto_snapshot_check" />
+</floater>
diff --git a/indra/newview/skins/default/xui/en/floater_sound_preview.xml b/indra/newview/skins/default/xui/en/floater_sound_preview.xml
new file mode 100644
index 0000000000..78540c0b98
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/floater_sound_preview.xml
@@ -0,0 +1,74 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<floater
+ height="190"
+ layout="topleft"
+ name="Sound Preview"
+ title="sound.wav"
+ width="300">
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="15"
+ layout="topleft"
+ left="10"
+ mouse_opaque="false"
+ name="name_label"
+ top="20"
+ width="275">
+ Name:
+ </text>
+ <line_editor
+ border_style="line"
+ border_thickness="1"
+ follows="left|top|right"
+ height="19"
+ layout="topleft"
+ left_delta="0"
+ max_length="63"
+ name="name_form"
+ top_pad="0"
+ width="280" />
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="15"
+ layout="topleft"
+ left_delta="0"
+ mouse_opaque="false"
+ name="description_label"
+ top_pad="10"
+ width="270">
+ Description:
+ </text>
+ <line_editor
+ border_style="line"
+ border_thickness="1"
+ follows="left|top|right"
+ height="19"
+ layout="topleft"
+ left_delta="0"
+ max_length="127"
+ name="description_form"
+ top_pad="0"
+ width="280" />
+ <button
+ follows="left|bottom"
+ height="22"
+ label="Upload (L$[AMOUNT])"
+ layout="topleft"
+ left="45"
+ name="ok_btn"
+ top_pad="60"
+ width="150" />
+ <button
+ follows="right|bottom"
+ height="22"
+ label="Cancel"
+ label_selected="Cancel"
+ layout="topleft"
+ name="cancel_btn"
+ left_pad="5"
+ width="90" />
+</floater>
diff --git a/indra/newview/skins/default/xui/en/floater_statistics.xml b/indra/newview/skins/default/xui/en/floater_statistics.xml
new file mode 100644
index 0000000000..1661fbffb0
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/floater_statistics.xml
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<floater
+ can_resize="true"
+ follows="right|top"
+ height="392"
+ layout="topleft"
+ mouse_opaque="false"
+ name="stats floater"
+ title="Statistics"
+ width="250" />
diff --git a/indra/newview/skins/default/xui/en/floater_stats.xml b/indra/newview/skins/default/xui/en/floater_stats.xml
new file mode 100644
index 0000000000..4d7da97f79
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/floater_stats.xml
@@ -0,0 +1,692 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<floater
+ can_resize="true"
+ follows="top|right"
+ height="400"
+ layout="topleft"
+ name="Statistics"
+ save_rect="true"
+ save_visibility="true"
+ title="Statistics"
+ width="250">
+ <scroll_container
+ follows="top|left|bottom|right"
+ height="380"
+ layout="topleft"
+ left="0"
+ name="statistics_scroll"
+ reserve_scroll_corner="true"
+ top="20"
+ width="250">
+ <container_view
+ follows="top|left|bottom|right"
+ height="378"
+ layout="topleft"
+ left="2"
+ name="statistics_view"
+ top="20"
+ width="230" >
+ <stat_view
+ name="basic"
+ label="Basic"
+ show_label="true"
+ setting="OpenDebugStatBasic">
+ <stat_bar
+ name="fps"
+ label="FPS"
+ unit_label="fps"
+ stat="fpsstat"
+ bar_min="0"
+ bar_max="45"
+ tick_spacing="7.5"
+ label_spacing="15.0"
+ precision="1"
+ show_bar="true"
+ show_history="true">
+ </stat_bar>
+ <stat_bar
+ name="bandwidth"
+ label="Bandwidth"
+ unit_label="kbps"
+ stat="kbitstat"
+ bar_min="0"
+ bar_max="900"
+ tick_spacing="100"
+ label_spacing="300"
+ show_bar="true"
+ show_history="false">
+ </stat_bar>
+ <stat_bar
+ name="packet_loss"
+ label="Packet Loss"
+ unit_label=" %"
+ stat="packetslostpercentstat"
+ bar_min="0"
+ bar_max="5"
+ tick_spacing="1"
+ label_spacing="1"
+ precision="1"
+ show_per_sec="false"
+ show_bar="false"
+ show_mean="true">
+ </stat_bar>
+ <stat_bar
+ name="ping"
+ label="Ping Sim"
+ unit_label="msec"
+ stat="simpingstat"
+ bar_min="0"
+ bar_max="1000"
+ tick_spacing="100"
+ label_spacing="200"
+ show_bar="false"
+ show_per_sec="false"
+ show_mean="false">
+ </stat_bar>
+ </stat_view>
+ <stat_view
+ name="advanced"
+ label="Advanced"
+ show_label="true"
+ setting="OpenDebugStatAdvanced">
+ <stat_view
+ name="render"
+ label="Render"
+ show_label="true"
+ setting="OpenDebugStatRender">
+ <stat_bar
+ name="ktrisframe"
+ label="KTris Drawn"
+ unit_label="/fr"
+ stat="trianglesdrawnstat"
+ bar_min="0"
+ bar_max="500"
+ tick_spacing="100"
+ label_spacing="500"
+ precision="1"
+ show_per_sec="false">
+ </stat_bar>
+ <stat_bar
+ name="ktrissec"
+ label="KTris Drawn"
+ unit_label="/sec"
+ stat="trianglesdrawnstat"
+ bar_min="0"
+ bar_max="3000"
+ tick_spacing="250"
+ label_spacing="1000"
+ precision="1">
+ </stat_bar>
+ <stat_bar
+ name="objs"
+ label="Total Objects"
+ unit_label=""
+ stat="numobjectsstat"
+ bar_min="0"
+ bar_max="3000"
+ tick_spacing="250"
+ label_spacing="1000"
+ precision="1"
+ show_per_sec="false"
+ show_bar="false">
+ </stat_bar>
+ <stat_bar
+ name="newobjs"
+ label="New Objects"
+ unit_label="/sec"
+ stat="numnewobjectsstat"
+ bar_min="0"
+ bar_max="1000"
+ tick_spacing="100"
+ label_spacing="500"
+ show_per_sec="true"
+ show_bar="false">
+ </stat_bar>
+ </stat_view>
+ <stat_view
+ name="texture"
+ label="Texture"
+ show_label="true">
+ <stat_bar
+ name="numimagesstat"
+ label="Count"
+ stat="numimagesstat"
+ bar_min="0.f"
+ bar_max="8000.f"
+ tick_spacing="2000.f"
+ label_spacing="4000.f"
+ show_per_sec="false"
+ show_bar="false">
+ </stat_bar>
+
+ <stat_bar
+ name="numrawimagesstat"
+ label="Raw Count"
+ stat="numrawimagesstat"
+ bar_min="0.f"
+ bar_max="8000.f"
+ tick_spacing="2000.f"
+ label_spacing="4000.f"
+ show_per_sec="false"
+ show_bar="false">
+ </stat_bar>
+
+ <stat_bar
+ name="gltexmemstat"
+ label="GL Mem"
+ stat="gltexmemstat"
+ bar_min="0.f"
+ bar_max="400.f"
+ tick_spacing="100.f"
+ label_spacing="200.f"
+ precision="1"
+ show_per_sec="false" >
+ </stat_bar>
+
+ <stat_bar
+ name="formattedmemstat"
+ label="Formatted Mem"
+ stat="formattedmemstat"
+ bar_min="0.f"
+ bar_max="400.f"
+ tick_spacing="100.f"
+ label_spacing="200.f"
+ precision="1"
+ show_per_sec="false" >
+ </stat_bar>
+
+ <stat_bar
+ name="rawmemstat"
+ label="Raw Mem"
+ stat="rawmemstat"
+ bar_min="0.f"
+ bar_max="400.f"
+ tick_spacing="100.f"
+ label_spacing="200.f"
+ precision="1"
+ show_per_sec="false" >
+ </stat_bar>
+
+ <stat_bar
+ name="glboundmemstat"
+ label="Bound Mem"
+ stat="glboundmemstat"
+ bar_min="0.f"
+ bar_max="400.f"
+ tick_spacing="100.f"
+ label_spacing="200.f"
+ precision="1"
+ show_per_sec="false" >
+ </stat_bar>
+ </stat_view>
+
+ <stat_view
+ name="network"
+ label="Network"
+ show_label="true"
+ setting="OpenDebugStatNet">
+ <stat_bar
+ name="packetsinstat"
+ label="Packets In"
+ stat="packetsinstat"
+ unit_label="/sec"
+ show_bar="false">
+ </stat_bar>
+
+ <stat_bar
+ name="packetsoutstat"
+ label="Packets Out"
+ stat="packetsoutstat"
+ unit_label="/sec"
+ show_bar="false" >
+ </stat_bar>
+
+ <stat_bar
+ name="objectkbitstat"
+ label="Objects"
+ stat="objectkbitstat"
+ unit_label="kbps"
+ show_bar="false" >
+ </stat_bar>
+
+ <stat_bar
+ name="texturekbitstat"
+ label="Texture"
+ stat="texturekbitstat"
+ unit_label="kbps"
+ show_bar="false" >
+ </stat_bar>
+
+ <stat_bar
+ name="assetkbitstat"
+ label="Asset"
+ stat="assetkbitstat"
+ unit_label="kbps"
+ show_bar="false" >
+ </stat_bar>
+
+ <stat_bar
+ name="layerskbitstat"
+ label="Layers"
+ stat="layerskbitstat"
+ unit_label="kbps"
+ show_bar="false" >
+ </stat_bar>
+
+ <stat_bar
+ name="actualinkbitstat"
+ label="Actual In"
+ stat="actualinkbitstat"
+ unit_label="kbps"
+ bar_min="0.f"
+ bar_max="1024.f"
+ tick_spacing="128.f"
+ label_spacing="256.f"
+ show_bar="true"
+ show_history="false" >
+ </stat_bar>
+
+ <stat_bar
+ name="actualoutkbitstat"
+ label="Actual Out"
+ stat="actualoutkbitstat"
+ unit_label="kbps"
+ bar_min="0.f"
+ bar_max="512.f"
+ tick_spacing="128.f"
+ label_spacing="256.f"
+ show_bar="true"
+ show_history="false">
+ </stat_bar>
+
+ <stat_bar
+ name="vfspendingoperations"
+ label="VFS Pending Ops"
+ stat="vfspendingoperations"
+ unit_label=" "
+ show_per_sec="false"
+ show_bar="false" >
+ </stat_bar>
+ </stat_view>
+ </stat_view>
+
+ <stat_view
+ name="sim"
+ label="Simulator"
+ show_label="true"
+ setting="OpenDebugStatSim">
+ <stat_bar
+ name="simtimedilation"
+ label="Time Dilation"
+ stat="simtimedilation"
+ precision="2"
+ bar_min="0.f"
+ bar_max="1.f"
+ tick_spacing="0.25f"
+ label_spacing="0.5f"
+ show_per_sec="false"
+ show_bar="false"
+ show_mean="false" >
+ </stat_bar>
+
+ <stat_bar
+ name="simfps"
+ label="Sim FPS"
+ stat="simfps"
+ bar_min="0.f"
+ bar_max="200.f"
+ tick_spacing="20.f"
+ label_spacing="100.f"
+ show_per_sec="false"
+ show_bar="false"
+ show_mean="false" >
+ </stat_bar>
+
+ <stat_bar
+ name="simphysicsfps"
+ label="Physics FPS"
+ stat="simphysicsfps"
+ precision="1"
+ bar_min="0.f"
+ bar_max="66.f"
+ tick_spacing="33.f"
+ label_spacing="33.f"
+ show_per_sec="false"
+ show_bar="false"
+ show_mean="false" >
+ </stat_bar>
+
+ <stat_view
+ name="physicsdetail"
+ label="Physics Details"
+ show_label="true"
+ display_children="false">
+ <stat_bar
+ name="physicspinnedtasks"
+ label="Pinned Objects"
+ stat="physicspinnedtasks"
+ precision="0"
+ bar_min="0.f"
+ bar_max="500.f"
+ tick_spacing="10.f"
+ label_spacing="40.f"
+ show_per_sec="false"
+ show_bar="false"
+ show_mean="false" >
+ </stat_bar>
+
+ <stat_bar
+ name="physicslodtasks"
+ label="Low LOD Objects"
+ stat="physicslodtasks"
+ precision="0"
+ bar_min="0.f"
+ bar_max="500.f"
+ tick_spacing="10.f"
+ label_spacing="40.f"
+ show_per_sec="false"
+ show_bar="false"
+ show_mean="false" >
+ </stat_bar>
+
+ <stat_bar
+ name="physicsmemoryallocated"
+ label="Memory Allocated"
+ stat="physicsmemoryallocated"
+ unit_label="MB"
+ precision="0"
+ bar_min="0.f"
+ bar_max="1024.f"
+ tick_spacing="128.f"
+ label_spacing="256.f"
+ show_per_sec="false"
+ show_bar="false"
+ show_mean="false" >
+ </stat_bar>
+
+ <stat_bar
+ name="simagentups"
+ label="Agent Updates/Sec"
+ stat="simagentups"
+ precision="1"
+ bar_min="0.f"
+ bar_max="100.f"
+ tick_spacing="25.f"
+ label_spacing="50.f"
+ show_per_sec="false"
+ show_bar="false"
+ show_mean="false" >
+ </stat_bar>
+
+ <stat_bar
+ name="simmainagents"
+ label="Main Agents"
+ stat="simmainagents"
+ precision="0"
+ bar_min="0.f"
+ bar_max="80.f"
+ tick_spacing="10.f"
+ label_spacing="40.f"
+ show_per_sec="false"
+ show_bar="false"
+ show_mean="false" >
+ </stat_bar>
+
+ <stat_bar
+ name="simchildagents"
+ label="Child Agents"
+ stat="simchildagents"
+ precision="0"
+ bar_min="0.f"
+ bar_max="40.f"
+ tick_spacing="5.f"
+ label_spacing="10.f"
+ show_per_sec="false"
+ show_bar="false"
+ show_mean="false" >
+ </stat_bar>
+
+ <stat_bar
+ name="simobjects"
+ label="Objects"
+ stat="simobjects"
+ precision="0"
+ bar_min="0.f"
+ bar_max="30000.f"
+ tick_spacing="5000.f"
+ label_spacing="10000.f"
+ show_per_sec="false"
+ show_bar="false"
+ show_mean="false" >
+ </stat_bar>
+
+ <stat_bar
+ name="simactiveobjects"
+ label="Active Objects"
+ stat="simactiveobjects"
+ precision="0"
+ bar_min="0.f"
+ bar_max="800.f"
+ tick_spacing="100.f"
+ label_spacing="200.f"
+ show_per_sec="false"
+ show_bar="false"
+ show_mean="false" >
+ </stat_bar>
+
+ <stat_bar
+ name="simactivescripts"
+ label="Active Scripts"
+ stat="simactivescripts"
+ precision="0"
+ bar_min="0.f"
+ bar_max="800.f"
+ tick_spacing="100.f"
+ label_spacing="200.f"
+ show_per_sec="false"
+ show_bar="false"
+ show_mean="false" >
+ </stat_bar>
+
+ <stat_bar
+ name="simscripteps"
+ label="Script Events"
+ stat="simscripteps"
+ unit_label="eps"
+ precision="0"
+ bar_min="0.f"
+ bar_max="20000.f"
+ tick_spacing="2500.f"
+ label_spacing="5000.f"
+ show_per_sec="false"
+ show_bar="false"
+ show_mean="false" >
+ </stat_bar>
+
+ <stat_bar
+ name="siminpps"
+ label="Packets In"
+ stat="siminpps"
+ unit_label="pps"
+ precision="0"
+ bar_min="0.f"
+ bar_max="2000.f"
+ tick_spacing="250.f"
+ label_spacing="1000.f"
+ show_per_sec="false"
+ show_bar="false"
+ show_mean="false" >
+ </stat_bar>
+
+ <stat_bar
+ name="simoutpps"
+ label="Packets Out"
+ stat="simoutpps"
+ unit_label="pps"
+ precision="0"
+ bar_min="0.f"
+ bar_max="2000.f"
+ tick_spacing="250.f"
+ label_spacing="1000.f"
+ show_per_sec="false"
+ show_bar="false"
+ show_mean="false" >
+ </stat_bar>
+
+ <stat_bar
+ name="simpendingdownloads"
+ label="Pending Downloads"
+ stat="simpendingdownloads"
+ precision="0"
+ bar_min="0.f"
+ bar_max="800.f"
+ tick_spacing="100.f"
+ label_spacing="200.f"
+ show_per_sec="false"
+ show_bar="false"
+ show_mean="false" >
+ </stat_bar>
+
+ <stat_bar
+ name="simpendinguploads"
+ label="Pending Uploads"
+ stat="simpendinguploads"
+ precision="0"
+ bar_min="0.f"
+ bar_max="100.f"
+ tick_spacing="25.f"
+ label_spacing="50.f"
+ show_per_sec="false"
+ show_bar="false"
+ show_mean="false" >
+ </stat_bar>
+
+ <stat_bar
+ name="simtotalunackedbytes"
+ label="Total Unacked Bytes"
+ stat="simtotalunackedbytes"
+ unit_label="kb"
+ precision="0"
+ bar_min="0.f"
+ bar_max="100000.f"
+ tick_spacing="25000.f"
+ label_spacing="50000.f"
+ show_per_sec="false"
+ show_bar="false"
+ show_mean="false" >
+ </stat_bar>
+ </stat_view>
+
+ <stat_view
+ name="simperf"
+ label="Time (ms)"
+ show_label="true">
+ <stat_bar
+ name="simframemsec"
+ label="Total Frame Time"
+ stat="simframemsec"
+ unit_label="ms"
+ precision="1"
+ bar_min="0.f"
+ bar_max="40.f"
+ tick_spacing="10.f"
+ label_spacing="20.f"
+ show_per_sec="false"
+ show_bar="false"
+ show_mean="false" >
+ </stat_bar>
+
+ <stat_bar
+ name="simnetmsec"
+ label="Net Time"
+ stat="simnetmsec"
+ unit_label="ms"
+ precision="1"
+ bar_min="0.f"
+ bar_max="40.f"
+ tick_spacing="10.f"
+ label_spacing="20.f"
+ show_per_sec="false"
+ show_bar="false"
+ show_mean="false" >
+ </stat_bar>
+
+ <stat_bar
+ name="simsimphysicsmsec"
+ label="Physics Time"
+ stat="simsimphysicsmsec"
+ unit_label="ms"
+ precision="1"
+ bar_min="0.f"
+ bar_max="40.f"
+ tick_spacing="10.f"
+ label_spacing="20.f"
+ show_per_sec="false"
+ show_bar="false"
+ show_mean="false" >
+ </stat_bar>
+
+ <stat_bar
+ name="simsimothermsec"
+ label="Simulation Time"
+ stat="simsimothermsec"
+ unit_label="ms"
+ precision="1"
+ bar_min="0.f"
+ bar_max="40.f"
+ tick_spacing="10.f"
+ label_spacing="20.f"
+ show_per_sec="false"
+ show_bar="false"
+ show_mean="false" >
+ </stat_bar>
+
+ <stat_bar
+ name="simagentmsec"
+ label="Agent Time"
+ stat="simagentmsec"
+ unit_label="ms"
+ precision="1"
+ bar_min="0.f"
+ bar_max="40.f"
+ tick_spacing="10.f"
+ label_spacing="20.f"
+ show_per_sec="false"
+ show_bar="false"
+ show_mean="false" >
+ </stat_bar>
+
+ <stat_bar
+ name="simimagesmsec"
+ label="Images Time"
+ stat="simimagesmsec"
+ unit_label="ms"
+ precision="1"
+ bar_min="0.f"
+ bar_max="40.f"
+ tick_spacing="10.f"
+ label_spacing="20.f"
+ show_per_sec="false"
+ show_bar="false"
+ show_mean="false" >
+ </stat_bar>
+
+ <stat_bar
+ name="simscriptmsec"
+ label="Script Time"
+ stat="simscriptmsec"
+ unit_label="ms"
+ precision="1"
+ bar_min="0.f"
+ bar_max="40.f"
+ tick_spacing="10.f"
+ label_spacing="20.f"
+ show_per_sec="false"
+ show_bar="false"
+ show_mean="false" >
+ </stat_bar>
+ </stat_view>
+ </stat_view>
+ </container_view>
+ </scroll_container>
+</floater>
diff --git a/indra/newview/skins/default/xui/en/floater_sys_well.xml b/indra/newview/skins/default/xui/en/floater_sys_well.xml
new file mode 100644
index 0000000000..46c8960fbd
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/floater_sys_well.xml
@@ -0,0 +1,40 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<floater
+ background_opaque="false"
+ background_visible="true"
+ bevel_style="in"
+ bg_alpha_color="0.0 0.0 0.0 0.0"
+ height="30"
+ left="0"
+ top="0"
+ follows="right|bottom"
+ layout="topleft"
+ name="notification_chiclet"
+ save_rect="true"
+ title="NOTIFICATIONS"
+ width="320"
+ min_width="320"
+ can_minimize="false"
+ can_tear_off="false"
+ can_resize="false"
+ can_drag_on_left="false"
+ can_close="false"
+ can_dock="true"
+>
+ <scroll_container
+ follows="top|bottom"
+ layout="topleft"
+ name="notification_list_container"
+ left="0"
+ top="18"
+ width="320"
+ height="12">
+ <scrolling_panel_list
+ layout="topleft"
+ name="notification_list"
+ left="1"
+ top="0"
+ height="10"
+ width="318" />
+ </scroll_container>
+</floater>
diff --git a/indra/newview/skins/default/xui/en/floater_telehub.xml b/indra/newview/skins/default/xui/en/floater_telehub.xml
new file mode 100644
index 0000000000..ef9aef7f6f
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/floater_telehub.xml
@@ -0,0 +1,132 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<floater
+ height="250"
+ layout="topleft"
+ name="telehub"
+ title="Telehub"
+ width="280">
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="16"
+ layout="topleft"
+ left="10"
+ name="status_text_connected"
+ top="24"
+ width="200">
+ Telehub connected to object [OBJECT]
+ </text>
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="16"
+ layout="topleft"
+ left_delta="0"
+ name="status_text_not_connected"
+ top_delta="0"
+ width="200">
+ No telehub connected.
+ </text>
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="20"
+ layout="topleft"
+ left_delta="0"
+ name="help_text_connected"
+ top_delta="16"
+ width="260">
+ To remove, click Disconnect.
+ </text>
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="20"
+ layout="topleft"
+ left_delta="0"
+ name="help_text_not_connected"
+ top_delta="0"
+ width="260">
+ Select object and click Connect Telehub.
+ </text>
+ <button
+ follows="top|left"
+ font="SansSerifSmall"
+ height="20"
+ label="Connect Telehub"
+ layout="topleft"
+ left_delta="0"
+ name="connect_btn"
+ top_delta="20"
+ width="110" />
+ <button
+ follows="top|left"
+ font="SansSerifSmall"
+ height="20"
+ label="Disconnect"
+ layout="topleft"
+ left_pad="10"
+ name="disconnect_btn"
+ top_delta="0"
+ width="110" />
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="16"
+ layout="topleft"
+ left="10"
+ name="spawn_points_text"
+ top="84"
+ width="200">
+ Spawn Points (positions, not objects):
+ </text>
+ <scroll_list
+ follows="left|top"
+ font="SansSerifSmall"
+ height="60"
+ layout="topleft"
+ left_delta="0"
+ name="spawn_points_list"
+ top_delta="16"
+ width="230" />
+ <button
+ follows="top|left"
+ font="SansSerifSmall"
+ height="20"
+ label="Add Spawn"
+ layout="topleft"
+ left_delta="0"
+ name="add_spawn_point_btn"
+ top_pad="5"
+ width="110" />
+ <button
+ follows="top|left"
+ font="SansSerifSmall"
+ height="20"
+ label="Remove Spawn"
+ layout="topleft"
+ left_pad="10"
+ name="remove_spawn_point_btn"
+ top_delta="0"
+ width="110" />
+ <text
+ type="string"
+ length="1"
+ follows="top|left"
+ height="80"
+ layout="topleft"
+ left="10"
+ name="spawn_point_help"
+ top="190"
+ width="260">
+ Select object and click Add to specify position.
+You may then move or delete the object.
+Positions are relative to the telehub center.
+Select item in list to show position in world.
+ </text>
+</floater>
diff --git a/indra/newview/skins/default/xui/en/floater_test_button.xml b/indra/newview/skins/default/xui/en/floater_test_button.xml
new file mode 100644
index 0000000000..0681eedbab
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/floater_test_button.xml
@@ -0,0 +1,111 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<floater
+ can_resize="true"
+ height="500"
+ layout="topleft"
+ name="floater_test_button"
+ width="500">
+ <button
+ height="20"
+ label="Generic Button"
+ layout="topleft"
+ left="10"
+ name="generic_button"
+ top="20"
+ width="150" />
+ <button
+ bottom_delta="30"
+ height="20"
+ label="Bottom delta"
+ layout="topleft"
+ name="bottom_delta_button" />
+ <button
+ bottom_delta="30"
+ font="SansSerifSmall"
+ height="20"
+ label="SansSerifSmall"
+ layout="topleft"
+ name="sans_serif_small_button" />
+ <button
+ auto_resize="true"
+ bottom_delta="30"
+ height="20"
+ label="Auto Resize"
+ layout="topleft"
+ name="auto_resize_button" />
+ <button
+ bottom_delta="30"
+ height="20"
+ is_toggle="true"
+ label="Click Change Label"
+ label_selected="New Label"
+ layout="topleft"
+ name="label_selected_button" />
+ <button
+ bottom_delta="30"
+ height="20"
+ label="No Label Shadow"
+ label_shadow="false"
+ layout="topleft"
+ name="label_shadow_button" />
+ <button
+ bottom_delta="30"
+ height="20"
+ label="Red Label"
+ label_color="red"
+ layout="topleft"
+ name="label_color_button" />
+ <button
+ bottom_delta="30"
+ height="20"
+ is_toggle="true"
+ label="Red Label Selected"
+ label_color_selected="red"
+ label_selected="Red Label Selected"
+ layout="topleft"
+ name="label_color_selected_button" />
+ <button
+ bottom_delta="30"
+ enabled="false"
+ height="20"
+ label="Red Label Disabled"
+ label_color_disabled="red"
+ label_selected="Red Label Selected"
+ layout="topleft"
+ name="label_color_disabled_button" />
+ <button
+ bottom_delta="30"
+ height="20"
+ highlight_color="red"
+ label="Red Highlight"
+ layout="topleft"
+ name="highlight_color_button" />
+ <button
+ bottom_delta="30"
+ height="20"
+ hover_glow_amount="0"
+ label="No Hover Glow"
+ layout="topleft"
+ name="hover_glow_amount_button" />
+ <button
+ height="30"
+ image_selected="object_cube_active.tga"
+ image_unselected="object_cube.tga"
+ layout="topleft"
+ left="200"
+ name="image_button"
+ picture_style="true"
+ top="20"
+ width="30" />
+ <button
+ height="30"
+ image_color="red"
+ image_selected="object_cube_active.tga"
+ image_unselected="object_cube.tga"
+ layout="topleft"
+ left_delta="0"
+ name="image_color_button"
+ picture_style="true"
+ top_pad="10"
+ width="30" />
+</floater>
diff --git a/indra/newview/skins/default/xui/en/floater_test_checkbox.xml b/indra/newview/skins/default/xui/en/floater_test_checkbox.xml
new file mode 100644
index 0000000000..021474d7ab
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/floater_test_checkbox.xml
@@ -0,0 +1,72 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<floater
+ can_resize="true"
+ height="400"
+ layout="topleft"
+ name="floater_test_checkbox"
+ width="400">
+ <check_box
+ control_name="ShowStartLocation"
+ height="16"
+ initial_value="true"
+ label="Show Start Location on Login Screen"
+ layout="topleft"
+ left="10"
+ name="show_location_checkbox"
+ top="28"
+ width="256" />
+ <check_box
+ height="16"
+ label="Minimal Checkbox"
+ layout="topleft"
+ left_delta="0"
+ name="minimal_checkbox"
+ top_pad="14"
+ width="150" />
+ <check_box
+ enabled="false"
+ height="16"
+ label="Disabled Checkbox"
+ layout="topleft"
+ left_delta="0"
+ name="disabled_checkbox"
+ top_pad="14"
+ width="150" />
+ <check_box
+ height="16"
+ label="Text Enabled Red"
+ layout="topleft"
+ left_delta="0"
+ name="text_enabled_color_checkbox"
+ text_enabled_color="red"
+ top_pad="14"
+ width="150" />
+ <check_box
+ enabled="false"
+ height="16"
+ label="Text Disabled Red"
+ layout="topleft"
+ left_delta="0"
+ name="text_disabled_color_checkbox"
+ text_disabled_color="red"
+ top_pad="14"
+ width="150" />
+ <check_box
+ height="16"
+ initial_value="true"
+ label="Initial Value Checked"
+ layout="topleft"
+ left_delta="0"
+ name="initial_value_checkbox"
+ top_pad="14"
+ width="150" />
+ <check_box
+ font="Monospace"
+ height="16"
+ label="Font Monospace"
+ layout="topleft"
+ left_delta="0"
+ name="font_checkbox"
+ top_pad="14"
+ width="150" />
+</floater>
diff --git a/indra/newview/skins/default/xui/en/floater_test_combobox.xml b/indra/newview/skins/default/xui/en/floater_test_combobox.xml
new file mode 100644
index 0000000000..06422d6a26
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/floater_test_combobox.xml
@@ -0,0 +1,155 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<floater
+ can_resize="true"
+ height="400"
+ layout="topleft"
+ name="floater_test_combobox"
+ width="400">
+ <text
+ type="string"
+ length="1"
+ height="16"
+ layout="topleft"
+ left="10"
+ top="24"
+ width="200">
+ Real world usage (login location):
+ </text>
+ <combo_box
+ allow_text_entry="true"
+ control_name="LoginLocation"
+ follows="left|bottom"
+ height="18"
+ layout="topleft"
+ left_delta="0"
+ max_chars="128"
+ name="start_location_combo"
+ top_pad="2"
+ width="155">
+ <combo_box.item
+ label="My Last Location"
+ name="MyLastLocation"
+ value="last" />
+ <combo_box.item
+ label="My Home"
+ name="MyHome"
+ value="home" />
+ <combo_box.item
+ label="&lt;Type region name&gt;"
+ name="Typeregionname"
+ value="" />
+ </combo_box>
+ <text
+ type="string"
+ length="1"
+ height="16"
+ layout="topleft"
+ left_delta="0"
+ top_pad="24"
+ width="200">
+ Minimal combobox:
+ </text>
+ <combo_box
+ height="18"
+ layout="topleft"
+ left_delta="0"
+ name="minimal_combo"
+ top_pad="2"
+ width="150">
+ <combo_box.item
+ label="First Item"
+ name="item1"
+ value="first" />
+ <combo_box.item
+ label="Second Item"
+ name="item2"
+ value="second" />
+ </combo_box>
+ <text
+ type="string"
+ length="1"
+ height="16"
+ layout="topleft"
+ left_delta="0"
+ top_pad="24"
+ width="200">
+ Allow text input:
+ </text>
+ <combo_box
+ allow_text_entry="true"
+ height="18"
+ layout="topleft"
+ left_delta="0"
+ name="text_entry_combo"
+ top_pad="2"
+ width="150">
+ <combo_box.item
+ label="First Item"
+ name="item1"
+ value="first" />
+ <combo_box.item
+ label="Second Item"
+ name="item2"
+ value="second" />
+ </combo_box>
+ <text
+ type="string"
+ length="1"
+ height="16"
+ layout="topleft"
+ left_delta="0"
+ top_pad="24"
+ width="200">
+ Allow text input, default to second item:
+ </text>
+ <combo_box
+ allow_text_entry="true"
+ height="18"
+ initial_value="second"
+ layout="topleft"
+ left_delta="0"
+ name="text_entry_combo2"
+ top_pad="2"
+ width="150">
+ <combo_box.item
+ label="First Item"
+ name="item1"
+ value="first" />
+ <combo_box.item
+ label="Second Item"
+ name="item2"
+ value="second" />
+ </combo_box>
+ <text
+ type="string"
+ length="1"
+ height="16"
+ layout="topleft"
+ left_delta="0"
+ top_pad="24"
+ width="200">
+ Two character max input:
+ </text>
+ <combo_box
+ allow_text_entry="true"
+ height="16"
+ layout="topleft"
+ left_delta="0"
+ max_chars="2"
+ name="state_combo"
+ top_pad="4"
+ width="150">
+ <combo_box.item
+ label="CA"
+ name="item1"
+ value="ca" />
+ <combo_box.item
+ label="NY"
+ name="item2"
+ value="ny" />
+ <combo_box.item
+ label="TX"
+ name="item3"
+ value="tx" />
+ </combo_box>
+</floater>
diff --git a/indra/newview/skins/default/xui/en/floater_test_layout.xml b/indra/newview/skins/default/xui/en/floater_test_layout.xml
new file mode 100644
index 0000000000..344ad8447e
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/floater_test_layout.xml
@@ -0,0 +1,88 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<floater
+ can_resize="true"
+ height="500"
+ layout="topleft"
+ name="floater_test_layout"
+ width="500">
+ <text
+ type="string"
+ length="1"
+ height="16"
+ layout="topleft"
+ left="10"
+ top="84"
+ width="200">
+ bottom 400 left 10
+ </text>
+ <text
+ type="string"
+ length="1"
+ height="16"
+ layout="topleft"
+ left_delta="0"
+ top_pad="4"
+ width="200">
+ Bottom delta -20
+ </text>
+ <text
+ type="string"
+ length="1"
+ height="16"
+ layout="topleft"
+ left_delta="0"
+ top_pad="64"
+ width="200">
+ bottom 300 left 10, should delta_bottom
+ </text>
+ <text
+ type="string"
+ length="1"
+ height="16"
+ layout="topleft"
+ left_pad="40"
+ top_delta="0"
+ width="200">
+ bottom 300 left 250, should delta_left
+ </text>
+ <text
+ type="string"
+ length="1"
+ height="16"
+ layout="topleft"
+ left="10"
+ top="204"
+ width="200">
+ bottom 280 left 10, should absolute position
+ </text>
+ <text
+ type="string"
+ length="1"
+ height="16"
+ layout="topleft"
+ left_pad="40"
+ top_delta="-2"
+ width="200">
+ bottom 282 left 250, should delta_left and delta_bottom
+ </text>
+ <text
+ type="string"
+ length="1"
+ height="16"
+ layout="topleft"
+ left="10"
+ top="234"
+ width="200">
+ bottom 250 left 10, should absolute position
+ </text>
+ <text
+ type="string"
+ length="1"
+ height="16"
+ layout="topleft"
+ left="250"
+ top="244"
+ width="200">
+ bottom 240 left 250, should absolute position
+ </text>
+</floater>
diff --git a/indra/newview/skins/default/xui/en/floater_test_line_editor.xml b/indra/newview/skins/default/xui/en/floater_test_line_editor.xml
new file mode 100644
index 0000000000..a17e3ea949
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/floater_test_line_editor.xml
@@ -0,0 +1,64 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<floater
+ can_resize="true"
+ height="400"
+ layout="topleft"
+ name="floater_test_line_editor"
+ width="400">
+ <line_editor
+ height="20"
+ layout="topleft"
+ left="10"
+ name="enabled_line_editor"
+ top="40"
+ tool_tip="enabled line editor"
+ width="200">
+ Enabled line editor
+ </line_editor>
+ <line_editor
+ enabled="false"
+ height="20"
+ layout="topleft"
+ left_delta="0"
+ name="disabled_line_editor"
+ top_pad="10"
+ tool_tip="disabled line editor"
+ width="200">
+ Disabled line editor
+ </line_editor>
+ <line_editor
+ height="20"
+ layout="topleft"
+ left_delta="0"
+ name="enabled_colored_line_editor"
+ text_color="1 0 0 1"
+ top_pad="10"
+ tool_tip="enabled colored line editor"
+ width="200">
+ Enabled red-text line editor
+ </line_editor>
+ <line_editor
+ enabled="false"
+ height="20"
+ layout="topleft"
+ left_delta="0"
+ name="disabled_colored_line_editor"
+ text_readonly_color="1 0 0 1"
+ top_pad="10"
+ tool_tip="disabled colored line editor"
+ width="200">
+ Disabled red-text line editor
+ </line_editor>
+ <!-- "search_editor" is a specialized line_editor that shows read-only
+ help text until the user clicks in the widget. -->
+ <search_editor
+ follows="left|top|right"
+ height="20"
+ label="Type here to search"
+ layout="topleft"
+ left_delta="0"
+ name="search editor"
+ tool_tip="search editor"
+ top_pad="10"
+ width="200" />
+</floater>
diff --git a/indra/newview/skins/default/xui/en/floater_test_list_view.xml b/indra/newview/skins/default/xui/en/floater_test_list_view.xml
new file mode 100644
index 0000000000..b637699228
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/floater_test_list_view.xml
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<floater
+ can_resize="true"
+ height="400"
+ layout="topleft"
+ name="floater_test_list_view"
+ width="400">
+ <list_view
+ height="300"
+ left="10"
+ name="test_list_view"
+ top="28"
+ width="300" />
+ <button
+ name="test_1_btn"
+ label="Test 1"
+ top="350"
+ left="10"
+ height="20"
+ width="80"
+ commit_callback.function="TestListView.Test1" />
+ <button
+ name="test_2_btn"
+ label="Test 2"
+ top_delta="0"
+ left_pad="10"
+ height="20"
+ width="80"
+ commit_callback.function="TestListView.Test2" />
+
+</floater>
diff --git a/indra/newview/skins/default/xui/en/floater_test_navigation_bar.xml b/indra/newview/skins/default/xui/en/floater_test_navigation_bar.xml
new file mode 100644
index 0000000000..21956c2eac
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/floater_test_navigation_bar.xml
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<floater
+ can_resize="true"
+ height="200"
+ layout="topleft"
+ name="floater_test_navigation_bar"
+ width="900">
+ <panel
+ name="navigation_bar"
+ filename="panel_navigation_bar.xml"
+ left="10"
+ right="-10"
+ top="30"
+ height="100"
+ border="true"
+ />
+</floater>
diff --git a/indra/newview/skins/default/xui/en/floater_test_radiogroup.xml b/indra/newview/skins/default/xui/en/floater_test_radiogroup.xml
new file mode 100644
index 0000000000..ef3e1f598d
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/floater_test_radiogroup.xml
@@ -0,0 +1,81 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<floater
+ can_resize="true"
+ height="400"
+ layout="topleft"
+ name="floater_test_radiogroup"
+ width="400">
+ <radio_group
+ height="54"
+ layout="topleft"
+ left="10"
+ name="parcel_voice_channel"
+ top="46"
+ width="219">
+ <radio_item
+ height="16"
+ label="Use the Estate spatial channel"
+ layout="topleft"
+ left="3"
+ name="Estate"
+ top="3"
+ width="463" />
+ <radio_item
+ height="16"
+ label="Use a private spatial channel"
+ layout="topleft"
+ left_delta="0"
+ name="Private"
+ top_delta="16"
+ width="463" />
+ <radio_item
+ height="16"
+ label="Disable spatial audio on this parcel"
+ layout="topleft"
+ left_delta="0"
+ name="Disabled"
+ top_delta="16"
+ width="463" />
+ </radio_group>
+ <radio_group
+ height="50"
+ layout="topleft"
+ left_delta="0"
+ name="simple_radio_group"
+ top_pad="50"
+ width="150">
+ <radio_item
+ bottom="20"
+ height="16"
+ label="Label in label attribute"
+ layout="topleft"
+ name="label_radio_item" />
+ <radio_item
+ bottom_delta="20"
+ height="16"
+ label="Label in text contents"
+ layout="topleft"
+ name="contents_radio_item" />
+ </radio_group>
+ <radio_group
+ draw_border="false"
+ height="50"
+ layout="topleft"
+ left_delta="0"
+ name="no_border_radio_group"
+ top_pad="50"
+ width="150">
+ <radio_item
+ bottom="20"
+ height="16"
+ label="No Border Foo"
+ layout="topleft"
+ name="foo_radio_item" />
+ <radio_item
+ bottom_delta="20"
+ height="16"
+ label="No Border Bar"
+ layout="topleft"
+ name="bar_item" />
+ </radio_group>
+</floater>
diff --git a/indra/newview/skins/default/xui/en/floater_test_slider.xml b/indra/newview/skins/default/xui/en/floater_test_slider.xml
new file mode 100644
index 0000000000..b1d468e265
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/floater_test_slider.xml
@@ -0,0 +1,77 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<floater
+ can_resize="true"
+ height="400"
+ layout="topleft"
+ name="floater_test_slider"
+ width="450">
+ <slider
+ height="20"
+ label="Generic Slider"
+ layout="topleft"
+ left="10"
+ name="generic_slider"
+ top="40"
+ width="250" />
+ <slider
+ height="20"
+ label="Callback Slider"
+ layout="topleft"
+ left_delta="0"
+ name="callback_slider"
+ top_pad="20"
+ width="400">
+ <slider.mouse_up_callback
+ function="Test.TestCallback"
+ parameter="test" />
+ </slider>
+ <slider
+ height="20"
+ increment="1"
+ initial_value="2.0"
+ label="Value Slider"
+ layout="topleft"
+ left_delta="0"
+ max_val="5"
+ min_val="1"
+ name="value_slider"
+ top_pad="20"
+ width="250" />
+ <slider
+ height="20"
+ label="Mini Slider 1"
+ layout="topleft"
+ left_delta="0"
+ name="mini_slider_1"
+ top_pad="20"
+ width="200" />
+ <slider
+ height="20"
+ label="Mini Slider 2"
+ layout="topleft"
+ left_pad="20"
+ name="mini_slider_2"
+ top_delta="0"
+ width="200" />
+ <slider_bar
+ bottom="320"
+ height="20"
+ increment="1"
+ initial_value="2.0"
+ label="Slider Bar"
+ layout="topleft"
+ max_val="5"
+ min_val="1"
+ name="slider_bar"
+ width="300" />
+ <slider
+ bottom="360"
+ decimal_digits="1"
+ height="20"
+ label="Red Slider"
+ label_width="100"
+ layout="topleft"
+ name="red_slider"
+ text_color="red"
+ text_width="40" />
+</floater>
diff --git a/indra/newview/skins/default/xui/en/floater_test_spinner.xml b/indra/newview/skins/default/xui/en/floater_test_spinner.xml
new file mode 100644
index 0000000000..da88d825e4
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/floater_test_spinner.xml
@@ -0,0 +1,93 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<floater
+ can_resize="true"
+ height="400"
+ layout="topleft"
+ name="floater_test_spinner"
+ width="450">
+ <spinner
+ height="20"
+ label="Generic Spinner"
+ layout="topleft"
+ left="10"
+ name="generic_spinner"
+ top="40"
+ width="350" />
+ <spinner
+ height="20"
+ label="Callback Spinner"
+ label_width="80"
+ layout="topleft"
+ left_delta="0"
+ name="callback_spinner"
+ top_pad="20"
+ width="400" />
+ <spinner
+ height="20"
+ label="Colorful Spinner"
+ layout="topleft"
+ left_delta="0"
+ name="colorful_spinner"
+ top_pad="20"
+ width="250" />
+ <spinner
+ height="20"
+ increment="1"
+ initial_value="2.0"
+ label="Value Spinner"
+ layout="topleft"
+ left_delta="0"
+ max_val="5"
+ min_val="1"
+ name="value_spinner"
+ top_pad="20"
+ width="250" />
+ <spinner
+ height="20"
+ label="Mini Spinner 1"
+ layout="topleft"
+ left_delta="0"
+ name="mini_spinner_1"
+ top_pad="20"
+ width="200" />
+ <spinner
+ height="20"
+ label="Mini Spinner 2"
+ layout="topleft"
+ left_pad="20"
+ name="mini_spinner_2"
+ top_delta="0"
+ width="200" />
+ <spinner
+ control_name="RenderFogRatio"
+ decimal_digits="1"
+ height="20"
+ label="Control Spinner"
+ layout="topleft"
+ left="10"
+ max_val="20"
+ min_val="10"
+ name="control_spinner"
+ top="260"
+ width="250" />
+ <spinner
+ follows="left"
+ height="20"
+ label="Follows Left"
+ label_width="85"
+ layout="topleft"
+ left_delta="0"
+ name="follows_left"
+ top_pad="20"
+ width="250" />
+ <spinner
+ follows="right"
+ height="20"
+ label="Follows Right"
+ label_width="85"
+ layout="topleft"
+ left_delta="0"
+ name="follows_right"
+ top_pad="20"
+ width="250" />
+</floater>
diff --git a/indra/newview/skins/default/xui/en/floater_test_textbox.xml b/indra/newview/skins/default/xui/en/floater_test_textbox.xml
new file mode 100644
index 0000000000..b4f3fc1e78
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/floater_test_textbox.xml
@@ -0,0 +1,129 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<floater
+ can_resize="true"
+ height="400"
+ layout="topleft"
+ name="floater_test_textbox"
+ width="400">
+ <text
+ type="string"
+ length="1"
+ height="10"
+ layout="topleft"
+ left="10"
+ top="30"
+ width="300">
+ Bottom and left specified
+ </text>
+ <text
+ type="string"
+ length="1"
+ height="10"
+ layout="topleft"
+ left_delta="200"
+ top_delta="0"
+ width="300">
+ Bottom delta left delta
+ </text>
+ <text
+ type="string"
+ length="1"
+ height="10"
+ layout="topleft"
+ left="10"
+ top="50"
+ width="300">
+ Bottom delta -20
+ </text>
+ <text
+ type="string"
+ length="1"
+ height="10"
+ layout="topleft"
+ left_delta="0"
+ top_pad="30"
+ width="300">
+ First line of multiple lines
+ Second line of multiple lines
+ </text>
+ <text
+ type="string"
+ length="1"
+ font="SansSerif"
+ height="10"
+ layout="topleft"
+ left_delta="0"
+ top_pad="30"
+ width="300">
+ font SansSerif
+ </text>
+ <text
+ type="string"
+ length="1"
+ follows="bottom|right"
+ height="10"
+ layout="topleft"
+ left_delta="0"
+ top_pad="10"
+ width="300">
+ follows bottom right
+ </text>
+ <text
+ type="string"
+ length="1"
+ font="SansSerifSmall"
+ font.style="BOLD"
+ height="10"
+ layout="topleft"
+ left_delta="0"
+ top_pad="10"
+ width="300">
+ font style BOLD
+ </text>
+ <text
+ type="string"
+ length="1"
+ font="SansSerifSmall"
+ font.style="BOLD|UNDERLINE"
+ height="10"
+ layout="topleft"
+ left_delta="0"
+ top_pad="10"
+ width="300">
+ font style BOLD UNDERLINE
+ </text>
+ <text
+ type="string"
+ length="1"
+ height="10"
+ layout="topleft"
+ left_delta="0"
+ top_pad="10"
+ width="300">
+ font style UNDERLINE
+ </text>
+ <text
+ type="string"
+ length="1"
+ height="10"
+ layout="topleft"
+ left_delta="0"
+ top_pad="10"
+ width="300">
+ Escaped greater than &gt;
+ </text>
+ <text
+ type="string"
+ length="1"
+ bottom="390"
+ label="N"
+ layout="topleft"
+ left="10"
+ name="floater_map_north"
+ right="30"
+ text="N"
+ text_color="1 1 1 0.7"
+ top="370">
+ N
+ </text>
+</floater>
diff --git a/indra/newview/skins/default/xui/en/floater_test_widgets.xml b/indra/newview/skins/default/xui/en/floater_test_widgets.xml
new file mode 100644
index 0000000000..d773e1f2b8
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/floater_test_widgets.xml
@@ -0,0 +1,345 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<!-- Sample "floater" window with examples of common widgets.
+
+ Notes:
+ XML UI (XUI) files use spaces for indentation, not tabs.
+ All position values are in pixels.
+ For now, each widget must contain attribute layout="topleft".
+ 0,0 is the top-left corner of the floater.
+ Each widget must have a unique name attribute.
+ If a widget is aligned with the one before it, use relative positioning:
+ top_pad
+ top_delta
+ left_pad
+ left_delta
+ Otherwise specify location with left and top attributes.
+-->
+<floater
+ can_dock="true"
+ can_resize="true"
+ title="Test Floater"
+ height="500"
+ layout="topleft"
+ name="floater_test_widgets"
+ width="850">
+
+ <!-- Strings are used by C++ code for localization. They are not visible
+ unless the C++ code uses them to fill in another widget. -->
+ <floater.string
+ name="sample_string"
+ value="Sample String" />
+ <floater.string
+ name="other_string"
+ value="Other String" />
+
+ <!-- Floaters can contain drop-down menus.
+ The menu_bar widget contains the inividual menus.
+ The width is automatically computed to fit the labels. -->
+ <menu_bar
+ height="18"
+ layout="topleft"
+ tool_tip="menu"
+ left="2"
+ name="test_menu_bar"
+ top="16">
+ <menu
+ height="16"
+ label="Menu"
+ layout="topleft"
+ tear_off="true"
+ left="0"
+ name="Menu"
+ top="-32"
+ width="128">
+ <!-- menu_item_call will trigger a function call in the C++ code -->
+ <menu_item_call
+ label="Menu Item 1"
+ layout="topleft"
+ name="test_menu_item_1" />
+ <!-- menu_item_separator is a horizontal line used to separate sections
+ of a menu. In general, menus should be divided into chunks of
+ no more than 7 items separated by menu_item_separators. -->
+ <menu_item_separator/>
+ <menu_item_call
+ label="Menu Item 2"
+ layout="topleft"
+ name="test_menu_item_2" />
+ </menu>
+ </menu_bar>
+
+ <!-- "text" is one or more read-only lines of text.
+ It can be made clickable but this requires C++ code
+ support. URLs are not automatically underlined. -->
+ <text
+ bottom="55"
+ layout="topleft"
+ left="10">
+ For widget list see https://wiki.lindenlab.com/wiki/Viewer:UI/Widgets
+ </text>
+
+ <!-- First column -->
+
+ <button
+ height="20"
+ label="Button"
+ layout="topleft"
+ left_delta="0"
+ name="test_button"
+ tool_tip="button"
+ top="80"
+ width="100" />
+ <!-- "flyout_button" is a button that can spawn a menu -->
+ <flyout_button
+ follows="right|bottom"
+ height="20"
+ label="Flyout"
+ layout="topleft"
+ left_delta="0"
+ name="fly_btn"
+ top_pad="15"
+ tool_tip="flyout button"
+ width="100">
+ <flyout_button.item
+ label="Item 1"
+ value="shout" />
+ <flyout_button.item
+ label="Item 2"
+ value="say" />
+ <flyout_button.item
+ label="Item 3"
+ value="whisper" />
+ </flyout_button>
+ <check_box
+ bottom_delta="35"
+ label="Checkbox"
+ layout="topleft"
+ tool_tip="checkbox"
+ name="test_checkbox" />
+ <!-- "combo_box" is a pop-menu of items. Optionally the box itself can
+ contain a general purpose line input editor, allowing the user to
+ provide input that is not a list item. -->
+ <combo_box
+ bottom_delta="35"
+ height="16"
+ width="150"
+ label="Combobox"
+ layout="topleft"
+ tool_tip="combo box"
+ name="test_combo_box">
+ <combo_box.item
+ name="item1"
+ label="Combobox Item 1" />
+ <combo_box.item
+ name="item2"
+ label="Combobox Item 2" />
+ </combo_box>
+ <!-- "icon" is a read-only image. The image_name must match an entry
+ in textures.xml. We support TGA and PNG for UI images. -->
+ <icon
+ height="16"
+ image_name="icon_avatar_online.tga"
+ layout="topleft"
+ left_delta="0"
+ tool_tip="icon"
+ name="test_icon"
+ top_pad="40"
+ width="16" />
+ <!-- "line_editor" allows a single line of editable text input.
+ The contents of this XML node are used as the initial value for
+ the text. -->
+ <line_editor
+ height="20"
+ layout="topleft"
+ left_delta="0"
+ name="test_line_editor"
+ top_pad="20"
+ tool_tip="line editor"
+ width="200">
+ Line Editor Sample Text
+ </line_editor>
+ <!-- "filter_editor" is a specialized line_editor that shows read-only
+ help text until the user clicks in the widget. -->
+ <filter_editor
+ follows="left|top|right"
+ height="20"
+ label="Type here to search"
+ layout="topleft"
+ left_delta="0"
+ name="search editor"
+ tool_tip="search editor"
+ top_pad="30"
+ width="200" />
+ <!-- "progress_bar" percent completed gets set in C++ code -->
+ <progress_bar
+ height="16"
+ layout="topleft"
+ left_delta="0"
+ name="test_progress_bar"
+ top_pad="30"
+ tool_tip="progress bar"
+ width="200" />
+ <!-- "stat_view" is a container for statistics graphs. It is only used
+ for debugging/diagnostic displays. -->
+ <stat_view
+ height="250"
+ label="Statistics View"
+ layout="topleft"
+ left_delta="0"
+ name="axis_view"
+ show_label="true"
+ top_pad="30"
+ tool_tip="stat view"
+ width="200">
+ <stat_bar
+ width="100"
+ bar_max="100"
+ bottom_delta="30"
+ label="Test Stat"
+ layout="topleft"
+ stat="stat"
+ bar_min="20"
+ name="test_stat_bar" />
+ </stat_view>
+
+ <!-- New column -->
+
+ <!-- "radio_group" is a set of mutually exclusive choices, like the buttons
+ on a car radio that allow a single radio station to be chosen. -->
+ <radio_group
+ height="40"
+ layout="topleft"
+ left_pad="90"
+ name="size_radio_group"
+ tool_tip="radio group"
+ top="80"
+ width="200">
+ <radio_item
+ bottom="20"
+ label="Radio 1"
+ layout="topleft"
+ name="small_radio_item" />
+ <radio_item
+ label="Radio 2"
+ layout="topleft"
+ name="large_radio_item" />
+ </radio_group>
+ <!-- "scroll_list" is a scrolling list of columnar data. -->
+ <scroll_list
+ bottom_delta="100"
+ height="80"
+ draw_heading="true"
+ tool_tip="scroll list"
+ layout="topleft">
+ <scroll_list.columns
+ dynamic_width="true"
+ name="first_column"
+ label="Column A"/>
+ <scroll_list.columns
+ dynamic_width="true"
+ name="second_column"
+ label="Column B"/>
+ </scroll_list>
+ <!-- "slider" is a horizontal input widget for numerical data. -->
+ <slider
+ bottom_delta="45"
+ layout="topleft"
+ min_val="0"
+ max_val="100"
+ initial_value="20"
+ label="Slider"
+ name="test_slider"
+ tool_tip="slider"
+ width="200" />
+ <!-- "spinner" is a numerical input widget with an up and down arrow to
+ change the value. -->
+ <spinner
+ bottom_delta="35"
+ label="Spinner"
+ layout="topleft"
+ name="test_spinner"
+ tool_tip="spinner"/>
+ <text
+ bottom_delta="50"
+ font.style = "UNDERLINE"
+ layout="topleft"
+ name="test_text"
+ tool_tip="text">
+ Text (underlined)
+ </text>
+ <!-- "text_editor" is a multi-line text input widget, similar to
+ textarea in HTML. -->
+ <text_editor
+ height="80"
+ layout="topleft"
+ left_delta="0"
+ name="test_text_editor"
+ tool_tip="text editor"
+ top_pad="25"
+ width="200">
+ Text Editor
+ </text_editor>
+
+ <!-- And a third column -->
+
+ <!-- "tab_container" is a holder for multiple panels of UI widgets.
+ Tabs can appear at the top, bottom, or left of the container. -->
+ <tab_container
+ follows="all"
+ height="400"
+ layout="topleft"
+ left="575"
+ name="group_tab_container"
+ tab_position="top"
+ tool_tip="tab container"
+ top="80"
+ width="250">
+ <!-- "panel" is a container for widgets. It is automatically resized to
+ fit the parent tab_container. -->
+ <panel
+ border="true"
+ label="Tab 1 - Color"
+ layout="topleft"
+ name="panel2">
+ <!-- "color_swatch" displays a color and spawns a color picker when
+ clicked. -->
+ <color_swatch
+ border_color="1 0 0 1"
+ can_apply_immediately="true"
+ color="0.3 0.6 0.9 1"
+ follows="left|top"
+ height="90"
+ border="true"
+ layout="topleft"
+ left="10"
+ label="Color Swatch 1"
+ name="swatch1"
+ tool_tip="Color Swatch: Click to open Color Picker"
+ top="10"
+ width="80" />
+ <color_swatch
+ border_color="0.45098 0.517647 0.607843 1"
+ can_apply_immediately="true"
+ color="1 0 1 1"
+ follows="left|top"
+ height="90"
+ label="Color Swatch 2"
+ layout="topleft"
+ left_pad="10"
+ name="swatch2"
+ tool_tip="Color Swatch: Click to open Color Picker"
+ top_delta="0"
+ width="80" />
+ </panel>
+ <!-- panels can also refer to other floaters or panels -->
+ <panel
+ border="true"
+ filename="floater_test_checkbox.xml"
+ height="225"
+ label="Tab 2 - Checkbox"
+ layout="topleft"
+ left_delta="0"
+ name="tab2"
+ top_delta="159"
+ width="250" />
+ </tab_container>
+</floater>
diff --git a/indra/newview/skins/default/xui/en/floater_texture_ctrl.xml b/indra/newview/skins/default/xui/en/floater_texture_ctrl.xml
new file mode 100644
index 0000000000..dc048eb352
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/floater_texture_ctrl.xml
@@ -0,0 +1,149 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<floater
+ can_minimize="false"
+ can_resize="true"
+ height="290"
+ layout="topleft"
+ min_height="290"
+ min_width="410"
+ name="texture picker"
+ title="Pick: Texture"
+ width="410">
+ <floater.string
+ name="choose_picture">
+ Click to choose a picture
+ </floater.string>
+ <floater.string
+ name="pick title">
+ Pick:
+ </floater.string>
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ halign="center"
+ height="14"
+ layout="topleft"
+ left="4"
+ name="Multiple"
+ top="96"
+ width="163">
+ Multiple
+ </text>
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="14"
+ layout="topleft"
+ left_delta="0"
+ name="unknown"
+ top_pad="80"
+ width="163">
+ Dimensions: [DIMENSIONS]
+ </text>
+ <button
+ enabled="false"
+ follows="left|bottom"
+ font="SansSerifSmall"
+ height="20"
+ label="Default"
+ label_selected="Default"
+ layout="topleft"
+ left_delta="0"
+ name="Default"
+ top_pad="4"
+ width="64" />
+ <button
+ enabled="false"
+ follows="left|bottom"
+ font="SansSerifSmall"
+ height="20"
+ label="None"
+ label_selected="None"
+ layout="topleft"
+ left_pad="4"
+ name="None"
+ top_delta="0"
+ width="64" />
+ <button
+ follows="left|bottom"
+ font="SansSerifSmall"
+ height="20"
+ label="Blank"
+ label_selected="Blank"
+ layout="topleft"
+ left="4"
+ name="Blank"
+ top="232"
+ width="64" />
+ <check_box
+ height="24"
+ initial_value="true"
+ label="Show Folders"
+ layout="topleft"
+ left="175"
+ name="show_folders_check"
+ top="20"
+ width="201" />
+ <filter_editor
+ follows="left|top|right"
+ height="16"
+ label="Type here to search"
+ layout="topleft"
+ left_delta="0"
+ name="inventory search editor"
+ top_delta="0"
+ width="231" />
+ <inventory_panel
+ allow_multi_select="false"
+ border="true"
+ follows="left|top|right|bottom"
+ height="216"
+ layout="topleft"
+ left_delta="0"
+ name="inventory panel"
+ top_pad="4"
+ width="231" />
+ <check_box
+ follows="left|bottom"
+ height="20"
+ initial_value="true"
+ label="Apply Immediately"
+ layout="topleft"
+ left="4"
+ name="apply_immediate_check"
+ top="262"
+ width="150" />
+ <button
+ follows="left|bottom"
+ height="32"
+ image_selected="eye_button_active.tga"
+ image_unselected="eye_button_inactive.tga"
+ layout="topleft"
+ left="139"
+ name="Pipette"
+ picture_style="true"
+ top="250"
+ width="32" />
+ <button
+ follows="right|bottom"
+ height="20"
+ label="Cancel"
+ label_selected="Cancel"
+ layout="topleft"
+ left="186"
+ name="Cancel"
+ top="262"
+ width="100" />
+ <button
+ follows="right|bottom"
+ height="20"
+ label="Select"
+ label_selected="Select"
+ layout="topleft"
+ left_pad="4"
+ name="Select"
+ top_delta="0"
+ width="100" />
+</floater>
diff --git a/indra/newview/skins/default/xui/en/floater_tools.xml b/indra/newview/skins/default/xui/en/floater_tools.xml
new file mode 100644
index 0000000000..51e4d15e5d
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/floater_tools.xml
@@ -0,0 +1,2902 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<floater
+ follows="left|top|right"
+ height="615"
+ layout="topleft"
+ name="toolbox floater"
+ save_rect="true"
+ short_title="Build Tools"
+ single_instance="true"
+ sound_flags="0"
+ width="280">
+ <floater.string
+ name="status_rotate">
+ Drag colored bands to rotate object
+ </floater.string>
+ <floater.string
+ name="status_scale">
+ Click and drag to stretch selected side
+ </floater.string>
+ <floater.string
+ name="status_move">
+ Drag to move, shift-drag to copy
+ </floater.string>
+ <floater.string
+ name="status_modifyland">
+ Click and hold to modify land
+ </floater.string>
+ <floater.string
+ name="status_camera">
+ Click and drag to change view
+ </floater.string>
+ <floater.string
+ name="status_grab">
+ Drag to move, Ctrl to lift, Ctrl-Shift to rotate
+ </floater.string>
+ <floater.string
+ name="status_place">
+ Click inworld to build
+ </floater.string>
+ <floater.string
+ name="status_selectland">
+ Click and drag to select land
+ </floater.string>
+ <floater.string
+ name="grid_screen_text">
+ Screen
+ </floater.string>
+ <floater.string
+ name="grid_local_text">
+ Local
+ </floater.string>
+ <floater.string
+ name="grid_world_text">
+ World
+ </floater.string>
+ <floater.string
+ name="grid_reference_text">
+ Reference
+ </floater.string>
+ <floater.string
+ name="grid_attachment_text">
+ Attachment
+ </floater.string>
+ <button
+ follows="left|top"
+ height="32"
+ image_disabled="tool_zoom.tga"
+ image_disabled_selected="tool_zoom_active.tga"
+ image_selected="tool_zoom_active.tga"
+ image_unselected="tool_zoom.tga"
+ layout="topleft"
+ left="10"
+ name="button focus"
+ picture_style="true"
+ tool_tip="Focus"
+ width="32" />
+ <button
+ follows="left|top"
+ height="32"
+ image_disabled="tool_grab.tga"
+ image_disabled_selected="tool_grab_active.tga"
+ image_selected="tool_grab_active.tga"
+ image_unselected="tool_grab.tga"
+ layout="topleft"
+ left_pad="8"
+ name="button move"
+ picture_style="true"
+ tool_tip="Move"
+ width="32" />
+ <button
+ follows="left|top"
+ height="32"
+ image_disabled="tool_face.tga"
+ image_disabled_selected="tool_face_active.tga"
+ image_selected="tool_face_active.tga"
+ image_unselected="tool_face.tga"
+ layout="topleft"
+ left_pad="8"
+ name="button edit"
+ picture_style="true"
+ tool_tip="Edit"
+ width="32" />
+ <button
+ follows="left|top"
+ height="32"
+ image_disabled="tool_create.tga"
+ image_disabled_selected="tool_create_active.tga"
+ image_selected="tool_create_active.tga"
+ image_unselected="tool_create.tga"
+ layout="topleft"
+ left_pad="8"
+ name="button create"
+ picture_style="true"
+ tool_tip="Create"
+ width="32" />
+ <button
+ follows="left|top"
+ height="32"
+ image_disabled="tool_dozer.tga"
+ image_disabled_selected="tool_dozer_active.tga"
+ image_selected="tool_dozer_active.tga"
+ image_unselected="tool_dozer.tga"
+ layout="topleft"
+ left_pad="8"
+ name="button land"
+ picture_style="true"
+ tool_tip="Land"
+ width="32" />
+ <text
+ type="string"
+ text_color="LabelSelectedDisabledColor"
+ length="1"
+ follows="left|top"
+ layout="topleft"
+ left="8"
+ name="text status"
+ top_pad="3"
+ width="280">
+ Drag to move, shift-drag to copy
+ </text>
+ <radio_group
+ layout="topleft"
+ left="10"
+ height="70"
+ top="54"
+ name="focus_radio_group">
+ <radio_item
+ top_pad="6"
+ label="Zoom"
+ layout="topleft"
+ name="radio zoom" />
+ <radio_item
+ top_pad="6"
+ label="Orbit (Ctrl)"
+ layout="topleft"
+ name="radio orbit" />
+ <radio_item
+ top_pad="6"
+ label="Pan (Ctrl-Shift)"
+ layout="topleft"
+ name="radio pan" />
+ </radio_group>
+ <slider_bar
+ follows="left|top"
+ height="14"
+ increment="0.01"
+ initial_value="0.125"
+ layout="topleft"
+ max_val="0.5"
+ top_delta="-2"
+ left_delta="100"
+ name="slider zoom"
+ width="134" />
+ <radio_group
+ left="10"
+ height="70"
+ top="54"
+ layout="topleft"
+ name="move_radio_group">
+ <radio_item
+ top_pad="6"
+ label="Move"
+ layout="topleft"
+ name="radio move" />
+ <radio_item
+ top_pad="6"
+ label="Lift (Ctrl)"
+ layout="topleft"
+ name="radio lift" />
+ <radio_item
+ top_pad="6"
+ label="Spin (Ctrl-Shift)"
+ layout="topleft"
+ name="radio spin" />
+ </radio_group>
+ <radio_group
+ follows="left|top"
+ left="10"
+ top="54"
+ height="70"
+ layout="topleft"
+ name="edit_radio_group">
+ <radio_item
+ label="Move"
+ layout="topleft"
+ name="radio position" />
+ <radio_item
+ top_pad="6"
+ label="Rotate (Ctrl)"
+ layout="topleft"
+ name="radio rotate" />
+ <radio_item
+ top_pad="6"
+ label="Stretch (Ctrl-Shift)"
+ layout="topleft"
+ name="radio stretch" />
+ <radio_item
+ top_pad="6"
+ label="Select Texture"
+ layout="topleft"
+ name="radio select face" />
+ </radio_group>
+ <check_box
+ left="10"
+ follows="left|top"
+ control_name="EditLinkedParts"
+ label="Edit linked prims"
+ layout="topleft"
+ name="checkbox edit linked parts" />
+ <text
+ left="10"
+ type="string"
+ length="1"
+ follows="left|top"
+ layout="topleft"
+ name="text ruler mode">
+ Ruler:
+ </text>
+ <combo_box
+ height="19"
+ left="30"
+ layout="topleft"
+ follows="left|top"
+ name="combobox grid mode"
+ width="90">
+ <combo_box.item
+ label="World"
+ name="World"
+ value="World" />
+ <combo_box.item
+ label="Local"
+ name="Local"
+ value="Local" />
+ <combo_box.item
+ label="Reference"
+ name="Reference"
+ value="Reference" />
+ </combo_box>
+ <check_box
+ control_name="ScaleUniform"
+ height="19"
+ label="Stretch Both Sides"
+ layout="topleft"
+ left="143"
+ name="checkbox uniform"
+ top="54"
+ width="134" />
+ <check_box
+ control_name="ScaleStretchTextures"
+ height="19"
+ initial_value="true"
+ label="Stretch Textures"
+ layout="topleft"
+ name="checkbox stretch textures"
+ top_pad="1"
+ width="134" />
+ <check_box
+ control_name="SnapEnabled"
+ height="19"
+ initial_value="true"
+ label="Use Grid"
+ layout="topleft"
+ name="checkbox snap to grid"
+ top_pad="1"
+ width="134" />
+ <button
+ follows="left|top"
+ font="SansSerifSmall"
+ height="19"
+ left_delta="40"
+ top_delta="20"
+ label="Options..."
+ label_selected="Options..."
+ layout="topleft"
+ name="Options..."
+ width="78" />
+ <button
+ follows="left|top"
+ height="24"
+ image_disabled="object_cube.tga"
+ image_disabled_selected="object_cube_active.tga"
+ image_selected="object_cube_active.tga"
+ image_unselected="object_cube.tga"
+ layout="topleft"
+ left="4"
+ name="ToolCube"
+ picture_style="true"
+ tool_tip="Cube"
+ top="51"
+ width="24" />
+ <button
+ follows="left|top"
+ height="24"
+ image_disabled="object_prism.tga"
+ image_disabled_selected="object_prism_active.tga"
+ image_selected="object_prism_active.tga"
+ image_unselected="object_prism.tga"
+ layout="topleft"
+ left_delta="23"
+ name="ToolPrism"
+ picture_style="true"
+ tool_tip="Prism"
+ top_delta="0"
+ width="24" />
+ <button
+ follows="left|top"
+ height="24"
+ image_disabled="object_pyramid.tga"
+ image_disabled_selected="object_pyramid_active.tga"
+ image_selected="object_pyramid_active.tga"
+ image_unselected="object_pyramid.tga"
+ layout="topleft"
+ left_delta="23"
+ name="ToolPyramid"
+ picture_style="true"
+ tool_tip="Pyramid"
+ top_delta="0"
+ width="24" />
+ <button
+ follows="left|top"
+ height="24"
+ image_disabled="object_tetrahedron.tga"
+ image_disabled_selected="object_tetrahedron_active.tga"
+ image_selected="object_tetrahedron_active.tga"
+ image_unselected="object_tetrahedron.tga"
+ layout="topleft"
+ left_delta="23"
+ name="ToolTetrahedron"
+ picture_style="true"
+ tool_tip="Tetrahedron"
+ top_delta="0"
+ width="24" />
+ <button
+ follows="left|top"
+ height="24"
+ image_disabled="object_cylinder.tga"
+ image_disabled_selected="object_cylinder_active.tga"
+ image_selected="object_cylinder_active.tga"
+ image_unselected="object_cylinder.tga"
+ layout="topleft"
+ left_delta="23"
+ name="ToolCylinder"
+ picture_style="true"
+ tool_tip="Cylinder"
+ top_delta="0"
+ width="24" />
+ <button
+ follows="left|top"
+ height="24"
+ image_disabled="object_hemi_cylinder.tga"
+ image_disabled_selected="object_hemi_cylinder_active.tga"
+ image_selected="object_hemi_cylinder_active.tga"
+ image_unselected="object_hemi_cylinder.tga"
+ layout="topleft"
+ left_delta="23"
+ name="ToolHemiCylinder"
+ picture_style="true"
+ tool_tip="Hemicylinder"
+ top_delta="0"
+ width="24" />
+ <button
+ follows="left|top"
+ height="24"
+ image_disabled="object_cone.tga"
+ image_disabled_selected="object_cone_active.tga"
+ image_selected="object_cone_active.tga"
+ image_unselected="object_cone.tga"
+ layout="topleft"
+ left_delta="23"
+ name="ToolCone"
+ picture_style="true"
+ tool_tip="Cone"
+ top_delta="0"
+ width="24" />
+ <button
+ follows="left|top"
+ height="24"
+ image_disabled="object_hemi_cone.tga"
+ image_disabled_selected="object_hemi_cone_active.tga"
+ image_selected="object_hemi_cone_active.tga"
+ image_unselected="object_hemi_cone.tga"
+ layout="topleft"
+ left_delta="23"
+ name="ToolHemiCone"
+ picture_style="true"
+ tool_tip="Hemicone"
+ top_delta="0"
+ width="24" />
+ <button
+ follows="left|top"
+ height="24"
+ image_disabled="object_sphere.tga"
+ image_disabled_selected="object_sphere_active.tga"
+ image_selected="object_sphere_active.tga"
+ image_unselected="object_sphere.tga"
+ layout="topleft"
+ left_delta="23"
+ name="ToolSphere"
+ picture_style="true"
+ tool_tip="Sphere"
+ top_delta="0"
+ width="24" />
+ <button
+ follows="left|top"
+ height="24"
+ image_disabled="object_hemi_sphere.tga"
+ image_disabled_selected="object_hemi_sphere_active.tga"
+ image_selected="object_hemi_sphere_active.tga"
+ image_unselected="object_hemi_sphere.tga"
+ layout="topleft"
+ left_delta="23"
+ name="ToolHemiSphere"
+ picture_style="true"
+ tool_tip="Hemisphere"
+ top_delta="0"
+ width="24" />
+ <button
+ follows="left|top"
+ height="24"
+ image_disabled="object_torus.tga"
+ image_disabled_selected="object_torus_active.tga"
+ image_selected="object_torus_active.tga"
+ image_unselected="object_torus.tga"
+ layout="topleft"
+ left="4"
+ name="ToolTorus"
+ picture_style="true"
+ tool_tip="Torus"
+ top="74"
+ width="24" />
+ <button
+ follows="left|top"
+ height="24"
+ image_disabled="object_tube.tga"
+ image_disabled_selected="object_tube_active.tga"
+ image_selected="object_tube_active.tga"
+ image_unselected="object_tube.tga"
+ layout="topleft"
+ left_delta="23"
+ name="ToolTube"
+ picture_style="true"
+ tool_tip="Tube"
+ top_delta="0"
+ width="24" />
+ <button
+ follows="left|top"
+ height="24"
+ image_disabled="object_ring.tga"
+ image_disabled_selected="object_ring_active.tga"
+ image_selected="object_ring_active.tga"
+ image_unselected="object_ring.tga"
+ layout="topleft"
+ left_delta="23"
+ name="ToolRing"
+ picture_style="true"
+ tool_tip="Ring"
+ top_delta="0"
+ width="24" />
+ <button
+ follows="left|top"
+ height="24"
+ image_disabled="object_tree.tga"
+ image_disabled_selected="object_tree_active.tga"
+ image_selected="object_tree_active.tga"
+ image_unselected="object_tree.tga"
+ layout="topleft"
+ left_delta="23"
+ name="ToolTree"
+ picture_style="true"
+ tool_tip="Tree"
+ top_delta="0"
+ width="24" />
+ <button
+ follows="left|top"
+ height="24"
+ image_disabled="object_grass.tga"
+ image_disabled_selected="object_grass_active.tga"
+ image_selected="object_grass_active.tga"
+ image_unselected="object_grass.tga"
+ layout="topleft"
+ left_delta="23"
+ name="ToolGrass"
+ picture_style="true"
+ tool_tip="Grass"
+ top_delta="0"
+ width="24" />
+ <check_box
+ control_name="CreateToolKeepSelected"
+ height="19"
+ label="Keep Tool selected"
+ layout="topleft"
+ left="4"
+ name="checkbox sticky"
+ top="101"
+ width="128" />
+ <check_box
+ control_name="CreateToolCopySelection"
+ height="19"
+ label="Copy selection"
+ layout="topleft"
+ left_delta="0"
+ name="checkbox copy selection"
+ top_delta="15"
+ width="134" />
+ <check_box
+ control_name="CreateToolCopyCenters"
+ height="19"
+ initial_value="true"
+ label="Center Copy"
+ layout="topleft"
+ left_delta="18"
+ name="checkbox copy centers"
+ top="132"
+ width="134" />
+ <check_box
+ control_name="CreateToolCopyRotates"
+ height="19"
+ label="Rotate Copy"
+ layout="topleft"
+ left_delta="0"
+ name="checkbox copy rotates"
+ top_delta="16"
+ width="134" />
+ <radio_group
+ height="105"
+ layout="topleft"
+ left="4"
+ name="land_radio_group"
+ top="54"
+ width="114">
+ <radio_item
+ height="19"
+ label="Select Land"
+ layout="topleft"
+ left="0"
+ name="radio select land"
+ top="-1"
+ width="114" />
+ <radio_item
+ height="19"
+ label="Flatten"
+ layout="topleft"
+ left_delta="0"
+ name="radio flatten"
+ top_delta="15"
+ width="114" />
+ <radio_item
+ height="19"
+ label="Raise"
+ layout="topleft"
+ left_delta="0"
+ name="radio raise"
+ top_delta="15"
+ width="114" />
+ <radio_item
+ height="19"
+ label="Lower"
+ layout="topleft"
+ left_delta="0"
+ name="radio lower"
+ top_delta="15"
+ width="114" />
+ <radio_item
+ height="19"
+ label="Smooth"
+ layout="topleft"
+ left_delta="0"
+ name="radio smooth"
+ top_delta="15"
+ width="114" />
+ <radio_item
+ height="19"
+ label="Roughen"
+ layout="topleft"
+ left_delta="0"
+ name="radio noise"
+ top_delta="15"
+ width="114" />
+ <radio_item
+ height="19"
+ label="Revert"
+ layout="topleft"
+ left_delta="0"
+ name="radio revert"
+ top_delta="15"
+ width="114" />
+ </radio_group>
+
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="12"
+ layout="topleft"
+ left="125"
+ name="Bulldozer:"
+ top="57"
+ width="100">
+ Bulldozer:
+ </text>
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="12"
+ layout="topleft"
+ name="Dozer Size:"
+ left="135"
+ top_pad="5"
+ width="50">
+ Size
+ </text>
+ <slider_bar
+ follows="left|top"
+ height="19"
+ initial_value="2.0"
+ layout="topleft"
+ max_val="11"
+ min_val="1"
+ left_pad="0"
+ name="slider brush size"
+ top_delta="-3"
+ width="80" />
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="12"
+ layout="topleft"
+ name="Strength:"
+ left="135"
+ top_pad="5"
+ width="50">
+ Strength
+ </text>
+ <slider_bar
+ follows="left|top"
+ height="19"
+ left_pad="0"
+ initial_value="0.00"
+ layout="topleft"
+ max_val="2"
+ min_val="-1"
+ name="slider force"
+ top_delta="-3"
+ width="80" />
+ <button
+ follows="left|top"
+ font="SansSerifSmall"
+ height="19"
+ label="Apply"
+ label_selected="Apply"
+ top_pad="5"
+ layout="topleft"
+ left="135"
+ name="button apply to selection"
+ tool_tip="Modify Selected Land"
+ width="78" />
+ <text
+ type="string"
+ text_color="LabelSelectedDisabledColor"
+ length="1"
+ top_pad="7"
+ height="12"
+ follows="left|top"
+ halign="right"
+ layout="topleft"
+ left="115"
+ name="obj_count"
+ width="143">
+ Objects: [COUNT]
+ </text>
+ <text
+ type="string"
+ text_color="LabelSelectedDisabledColor"
+ length="1"
+ follows="left|top"
+ halign="right"
+ layout="topleft"
+ name="prim_count"
+ width="143">
+ Prims: [COUNT]
+ </text>
+ <tab_container
+ follows="left|top"
+ height="400"
+ layout="topleft"
+ left="0"
+ name="Object Info Tabs"
+ tab_max_width="55"
+ tab_min_width="40"
+ tab_position="top"
+ top="180"
+ width="280">
+ <panel
+ border="false"
+ follows="left|top|right|bottom"
+ label="General"
+ layout="topleft"
+ mouse_opaque="false"
+ name="General"
+ top="16">
+ <panel.string
+ name="text deed continued">
+ Deed...
+ </panel.string>
+ <panel.string
+ name="text deed">
+ Deed
+ </panel.string>
+ <panel.string
+ name="text modify info 1">
+ You can modify this object
+ </panel.string>
+ <panel.string
+ name="text modify info 2">
+ You can modify these objects
+ </panel.string>
+ <panel.string
+ name="text modify info 3">
+ You can't modify this object
+ </panel.string>
+ <panel.string
+ name="text modify info 4">
+ You can't modify these objects
+ </panel.string>
+ <panel.string
+ name="text modify warning">
+ This object has linked parts
+ </panel.string>
+ <panel.string
+ name="Cost Default">
+ Price: L$
+ </panel.string>
+ <panel.string
+ name="Cost Total">
+ Total Price: L$
+ </panel.string>
+ <panel.string
+ name="Cost Per Unit">
+ Price Per: L$
+ </panel.string>
+ <panel.string
+ name="Cost Mixed">
+ Mixed Price
+ </panel.string>
+ <panel.string
+ name="Sale Mixed">
+ Mixed Sale
+ </panel.string>
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="10"
+ layout="topleft"
+ left="10"
+ name="Name:"
+ top_pad="8"
+ width="90">
+ Name:
+ </text>
+ <line_editor
+ follows="left|top|right"
+ height="19"
+ layout="topleft"
+ left_pad="0"
+ max_length="63"
+ name="Object Name"
+ select_on_focus="true"
+ top_delta="0"
+ width="172" />
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="10"
+ layout="topleft"
+ left="10"
+ name="Description:"
+ top_pad="3"
+ width="90">
+ Description:
+ </text>
+ <line_editor
+ follows="left|top|right"
+ height="19"
+ layout="topleft"
+ left_pad="0"
+ max_length="127"
+ name="Object Description"
+ select_on_focus="true"
+ top_delta="0"
+ width="172" />
+
+ <text
+ type="string"
+ left="10"
+ length="1"
+ follows="left|top"
+ height="19"
+ layout="topleft"
+ name="Creator:"
+ width="90">
+ Creator:
+ </text>
+<!-- TODO: add person inspector to creator name -->
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ left_pad="0"
+ height="19"
+ layout="topleft"
+ name="Creator Name"
+ width="150">
+ Thrax Linden
+ </text>
+<!--TODO: Kill this-->
+<!-- <button
+ follows="top|right"
+ font="SansSerifSmall"
+ height="19"
+ label="Profile..."
+ label_selected="Profile..."
+ layout="topleft"
+ left_pad="6"
+ name="button creator profile"
+ tool_tip="View creator profile"
+ width="78" />-->
+ <text
+ type="string"
+ length="1"
+ left="10"
+ follows="left|top"
+ height="19"
+ layout="topleft"
+ name="Owner:"
+ width="90">
+ Owner:
+ </text>
+<!--TODO: add person inspector to creator name-->
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="19"
+ layout="topleft"
+ name="Owner Name"
+ left_pad="0"
+ width="150">
+ Thrax Linden
+ </text>
+<!--TODO: Kill this-->
+<!--<button
+ follows="top|right"
+ font="SansSerifSmall"
+ height="19"
+ label="Profile..."
+ label_selected="Profile..."
+ layout="topleft"
+ left_pad="6"
+ name="button owner profile"
+ tool_tip="View owner profile"
+ width="78" />-->
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ layout="topleft"
+ left="10"
+ height="19"
+ name="Group:"
+ width="90">
+ Group:
+ </text>
+ <name_box
+ follows="left|top|right"
+ height="19"
+ initial_value="Loading..."
+ layout="topleft"
+ left_pad="0"
+ name="Group Name Proxy"
+ width="170" />
+ <button
+ follows="top|right"
+ font="SansSerifSmall"
+ height="19"
+ label="Deed..."
+ label_selected="Deed..."
+ layout="topleft"
+ name="button deed"
+ top_pad="0"
+ left="102"
+ tool_tip="Deeding gives this item away with Next Owner permissions. Group shared objects can be deeded by a group officer."
+ width="80" />
+ <button
+ follows="left|top"
+ font="SansSerifSmall"
+ height="19"
+ label="Set..."
+ label_selected="Set..."
+ layout="topleft"
+ left_pad="7"
+ name="button set group"
+ tool_tip="Choose a group to share this object's permissions"
+ width="80" />
+ <check_box
+ height="19"
+ follows="left|top"
+ label="Share"
+ layout="topleft"
+ name="checkbox share with group"
+ tool_tip="Allow all members of the set group to share your modify permissions for this object. You must Deed to enable role restrictions."
+ left="100"
+ width="93" />
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="19"
+ layout="topleft"
+ top_pad="7"
+ left="10"
+ name="label click action"
+ width="90">
+ Click to:
+ </text>
+ <combo_box
+ follows="left|top"
+ height="22"
+ layout="topleft"
+ name="clickaction"
+ width="170"
+ left_pad="0">
+ <combo_box.item
+ label="Touch (default)"
+ name="Touch/grab(default)"
+ value="Touch/grab (default)" />
+ <combo_box.item
+ label="Sit on object"
+ name="Sitonobject"
+ value="Sit on object" />
+ <combo_box.item
+ label="Buy object"
+ name="Buyobject"
+ value="Buy object" />
+ <combo_box.item
+ label="Pay object"
+ name="Payobject"
+ value="Pay object" />
+ <combo_box.item
+ label="Open"
+ name="Open"
+ value="Open" />
+<!--TODO: Kill this-->
+<!-- <combo_box.item
+ label="Play parcel media"
+ name="Play"
+ value="Play" />
+ <combo_box.item
+ label="Open parcel media"
+ name="Opemmedia"
+ value="Open Media" />-->
+ </combo_box>
+ <check_box
+ height="20"
+ label="For Sale:"
+ layout="topleft"
+ name="checkbox for sale"
+ left="10"
+ width="90" />
+<!-- NEW SALE TYPE COMBO BOX -->
+ <combo_box
+ left_pad="0"
+ layout="topleft"
+ follows="left|top"
+ allow_text_entry="false"
+ height="22"
+ width="170"
+ max_chars="20"
+ mouse_opaque="true"
+ name="sale type"
+ intial_value="2">
+ <combo_item
+ label="Copy"
+ value="2" />
+ <combo_item
+ label="Contents"
+ value="3" />
+ <combo_item
+ label="Original"
+ value="1" />
+ </combo_box>
+<!-- NEW PRICE SPINNER -->
+ <spinner
+ follows="left|top"
+ decimal_digits="0"
+ increment="1"
+ control_name="Edit Cost"
+ name="Edit Cost"
+ label="Price: L$"
+ label_width="60"
+ width="170"
+ min_val="1"
+ height="19"
+ max_val="999999999" />
+ <panel
+ border="false"
+ follows="left|top|right"
+ layout="topleft"
+ mouse_opaque="false"
+ background_visible="true"
+ bg_alpha_color="FloaterUnfocusBorderColor"
+ name="perms_build"
+ left="0"
+ height="140"
+ width="280">
+ <text
+ type="string"
+ length="1"
+ left="10"
+ top_pad="6"
+ height="19"
+ follows="left|top|right"
+ layout="topleft"
+ name="perm_modify"
+ width="180">
+ You can modify this object
+ </text>
+ <text
+ type="string"
+ text_color="LabelSelectedDisabledColor"
+ length="1"
+ top_pad="0"
+ follows="left|top"
+ layout="topleft"
+ left="17"
+ name="B:"
+ width="30">
+ B:
+ </text>
+ <text
+ type="string"
+ text_color="LabelSelectedDisabledColor"
+ length="1"
+ follows="left|top"
+ layout="topleft"
+ left_pad="0"
+ name="O:"
+ width="30">
+ O:
+ </text>
+ <text
+ type="string"
+ text_color="LabelSelectedDisabledColor"
+ length="1"
+ follows="left|top"
+ layout="topleft"
+ left_pad="0"
+ name="G:"
+ width="30">
+ G:
+ </text>
+ <text
+ type="string"
+ text_color="LabelSelectedDisabledColor"
+ length="1"
+ follows="left|top"
+ left_pad="0"
+ layout="topleft"
+ name="E:"
+ width="30">
+ E:
+ </text>
+ <text
+ type="string"
+ text_color="LabelSelectedDisabledColor"
+ length="1"
+ follows="left|top"
+ layout="topleft"
+ left_pad="0"
+ name="N:"
+ width="30">
+ N:
+ </text>
+ <text
+ type="string"
+ text_color="LabelSelectedDisabledColor"
+ length="1"
+ follows="left|top"
+ layout="topleft"
+ left_pad="0"
+ name="F:"
+ width="30">
+ F:
+ </text>
+ <check_box
+ left="15"
+ height="19"
+ label="Show in search"
+ layout="topleft"
+ name="search_check"
+ tool_tip="Let people see this object in search results"
+ />
+ <text
+ type="string"
+ follows="left|top"
+ name="Anyone can:"
+ width="250"
+ top_pad="7"
+ left="10">
+ Anyone:
+ </text>
+ <check_box
+ height="19"
+ label="Move"
+ layout="topleft"
+ name="checkbox allow everyone move"
+ left="15"
+ width="85" />
+ <check_box
+ height="19"
+ label="Copy"
+ layout="topleft"
+ left_pad="0"
+ name="checkbox allow everyone copy"
+ width="260" />
+ <text
+ type="string"
+ follows="left|top"
+ height="19"
+ name="Next owner can:"
+ width="270"
+ left="10">
+ Next owner:
+ </text>
+ <check_box
+ follows="left|top|right"
+ label="Modify"
+ layout="topleft"
+ left="15"
+ name="checkbox next owner can modify"
+ width="85" />
+ <check_box
+ follows="left|top|right"
+ height="19"
+ label="Copy"
+ layout="topleft"
+ left_pad="0"
+ name="checkbox next owner can copy"
+ width="90" />
+ <check_box
+ follows="left|top|right"
+ height="19"
+ label="Transfer"
+ layout="topleft"
+ name="checkbox next owner can transfer"
+ left_pad="0"
+ top_delta="0"
+ tool_tip="Next owner can give away or resell this object"
+ width="90" />
+ </panel>
+<!--TODO: KILL THIS-->
+<!--<text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="19"
+ layout="topleft"
+ left_pad="12"
+ name="Cost"
+ top_delta="0"
+ width="78">
+ Price: L$
+ </text>
+ <line_editor
+ follows="left|top|right"
+ height="19"
+ layout="topleft"
+ left_pad="0"
+ max_length="25"
+ name="Edit Cost"
+ top_delta="0"
+ width="75" />-->
+<!--TODO: KILL THIS-->
+<!--<radio_group
+ follows="left|top|right"
+ height="19"
+ left="15"
+ layout="topleft"
+ name="sale type"
+ width="218">
+ <radio_item
+ height="19"
+ label="Original"
+ layout="topleft"
+ left="0"
+ name="Original"
+ top="0"
+ width="70" />
+ <radio_item
+ height="19"
+ label="Copy"
+ layout="topleft"
+ left_delta="70"
+ name="Copy"
+ top_delta="0"
+ width="70" />
+ <radio_item
+ height="19"
+ label="Contents"
+ layout="topleft"
+ left_delta="70"
+ name="Contents"
+ top_delta="0"
+ width="76" />
+ </radio_group>-->
+ </panel>
+ <panel
+ border="false"
+ follows="left|top|right|bottom"
+ height="367"
+ label="Object"
+ layout="topleft"
+ left_delta="0"
+ mouse_opaque="false"
+ name="Object"
+ top_delta="0"
+ width="280">
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="10"
+ layout="topleft"
+ left="10"
+ name="select_single"
+ top="10"
+ width="252">
+ Select only one primitive to edit parameters.
+ </text>
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="10"
+ layout="topleft"
+ left_delta="0"
+ name="edit_object"
+ top_delta="0"
+ width="252">
+ Edit object parameters:
+ </text>
+ <check_box
+ height="19"
+ label="Locked"
+ layout="topleft"
+ left_delta="-2"
+ name="checkbox locked"
+ tool_tip="Prevents object from being moved or deleted. Frequently useful during building to avoid unintended edits."
+ top_pad="10"
+ width="123" />
+ <check_box
+ height="19"
+ label="Physical"
+ layout="topleft"
+ left_delta="0"
+ name="Physical Checkbox Ctrl"
+ tool_tip="Allows object to be pushed and affected by gravity"
+ top_pad="2"
+ width="123" />
+ <check_box
+ height="19"
+ label="Temporary"
+ layout="topleft"
+ left_delta="0"
+ name="Temporary Checkbox Ctrl"
+ tool_tip="Causes object to be deleted 1 minute after creation."
+ top_pad="2"
+ width="123" />
+ <check_box
+ height="19"
+ label="Phantom"
+ layout="topleft"
+ left_delta="0"
+ name="Phantom Checkbox Ctrl"
+ tool_tip="Causes object to not collide with other objects or avatars"
+ top_pad="2"
+ width="123" />
+
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="10"
+ layout="topleft"
+ left_delta="0"
+ name="label material"
+ top_pad="9"
+ width="121">
+ Material
+ </text>
+ <combo_box
+ height="19"
+ layout="topleft"
+ left_delta="0"
+ name="material"
+ top_pad="4"
+ width="95">
+ <combo_box.item
+ label="Stone"
+ name="Stone"
+ value="Stone" />
+ <combo_box.item
+ label="Metal"
+ name="Metal"
+ value="Metal" />
+ <combo_box.item
+ label="Glass"
+ name="Glass"
+ value="Glass" />
+ <combo_box.item
+ label="Wood"
+ name="Wood"
+ value="Wood" />
+ <combo_box.item
+ label="Flesh"
+ name="Flesh"
+ value="Flesh" />
+ <combo_box.item
+ label="Plastic"
+ name="Plastic"
+ value="Plastic" />
+ <combo_box.item
+ label="Rubber"
+ name="Rubber"
+ value="Rubber" />
+ </combo_box>
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="10"
+ layout="topleft"
+ left_delta="2"
+ name="label position"
+ top_pad="8"
+ width="121">
+ Position (meters)
+ </text>
+ <spinner
+ follows="left|top"
+ height="19"
+ increment="0.01"
+ initial_value="0"
+ label="X"
+ label_width="10"
+ layout="topleft"
+ left_delta="0"
+ max_val="512"
+ min_val="-256"
+ name="Pos X"
+ text_enabled_color="0.43 0.06 0.06 1"
+ top_pad="5"
+ width="87" />
+ <spinner
+ follows="left|top"
+ height="19"
+ increment="0.01"
+ initial_value="0"
+ label="Y"
+ label_width="10"
+ layout="topleft"
+ left_delta="0"
+ max_val="512"
+ min_val="-256"
+ name="Pos Y"
+ text_enabled_color="0 0.39 0.15 1"
+ top_pad="3"
+ width="87" />
+ <spinner
+ follows="left|top"
+ height="19"
+ increment="0.01"
+ initial_value="0"
+ label="Z"
+ label_width="10"
+ layout="topleft"
+ left_delta="0"
+ max_val="4096"
+ name="Pos Z"
+ text_enabled_color="0 0.26 0.51 1"
+ top_pad="3"
+ width="87" />
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="10"
+ layout="topleft"
+ left_delta="0"
+ name="label size"
+ top_pad="6"
+ width="121">
+ Size (meters)
+ </text>
+ <spinner
+ follows="left|top"
+ height="19"
+ increment="0.01"
+ initial_value="0"
+ label="X"
+ label_width="10"
+ layout="topleft"
+ left_delta="0"
+ max_val="10"
+ min_val="0.01"
+ name="Scale X"
+ text_enabled_color="1 1 1 1"
+ top_pad="5"
+ width="87" />
+ <spinner
+ follows="left|top"
+ height="19"
+ increment="0.01"
+ initial_value="0"
+ label="Y"
+ label_width="10"
+ layout="topleft"
+ left_delta="0"
+ max_val="10"
+ min_val="0.01"
+ name="Scale Y"
+ text_enabled_color="1 1 1 1"
+ top_pad="3"
+ width="87" />
+ <spinner
+ follows="left|top"
+ height="19"
+ increment="0.01"
+ initial_value="0"
+ label="Z"
+ label_width="10"
+ layout="topleft"
+ left_delta="0"
+ max_val="10"
+ min_val="0.01"
+ name="Scale Z"
+ text_enabled_color="1 1 1 1"
+ top_pad="3"
+ width="87" />
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="10"
+ layout="topleft"
+ left_delta="0"
+ name="label rotation"
+ top_pad="6"
+ width="121">
+ Rotation (degrees)
+ </text>
+ <spinner
+ decimal_digits="2"
+ follows="left|top"
+ height="19"
+ increment="1"
+ initial_value="0"
+ label="X"
+ label_width="10"
+ layout="topleft"
+ left_delta="0"
+ max_val="9999"
+ min_val="-9999"
+ name="Rot X"
+ text_enabled_color="1 1 1 1"
+ top_pad="5"
+ width="87" />
+ <spinner
+ decimal_digits="2"
+ follows="left|top"
+ height="19"
+ increment="1"
+ initial_value="0"
+ label="Y"
+ label_width="10"
+ layout="topleft"
+ left_delta="0"
+ max_val="9999"
+ min_val="-9999"
+ name="Rot Y"
+ text_enabled_color="1 1 1 1"
+ top_pad="3"
+ width="87" />
+ <spinner
+ decimal_digits="2"
+ follows="left|top"
+ height="19"
+ increment="1"
+ initial_value="0"
+ label="Z"
+ label_width="10"
+ layout="topleft"
+ left_delta="0"
+ max_val="9999"
+ min_val="-9999"
+ name="Rot Z"
+ text_enabled_color="1 1 1 1"
+ top_pad="3"
+ width="87" />
+
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="10"
+ layout="topleft"
+ left="125"
+ name="label basetype"
+ top="26"
+ width="150">
+ Building Block Type
+ </text>
+ <combo_box
+ height="19"
+ layout="topleft"
+ left_delta="0"
+ name="comboBaseType"
+ top_pad="4"
+ width="150">
+ <combo_box.item
+ label="Box"
+ name="Box"
+ value="Box" />
+ <combo_box.item
+ label="Cylinder"
+ name="Cylinder"
+ value="Cylinder" />
+ <combo_box.item
+ label="Prism"
+ name="Prism"
+ value="Prism" />
+ <combo_box.item
+ label="Sphere"
+ name="Sphere"
+ value="Sphere" />
+ <combo_box.item
+ label="Torus"
+ name="Torus"
+ value="Torus" />
+ <combo_box.item
+ label="Tube"
+ name="Tube"
+ value="Tube" />
+ <combo_box.item
+ label="Ring"
+ name="Ring"
+ value="Ring" />
+ <combo_box.item
+ label="Sculpted"
+ name="Sculpted"
+ value="Sculpted" />
+ </combo_box>
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="10"
+ layout="topleft"
+ left_delta="0"
+ name="text cut"
+ top_pad="6"
+ width="150">
+ Path Cut Begin and End
+ </text>
+ <spinner
+ follows="left|top"
+ height="19"
+ increment="0.025"
+ initial_value="0"
+ label="B"
+ label_width="10"
+ layout="topleft"
+ left_delta="0"
+ max_val="0.98"
+ name="cut begin"
+ top_pad="4"
+ width="68" />
+ <spinner
+ follows="left|top"
+ height="19"
+ increment="0.025"
+ initial_value="1"
+ label="E"
+ label_width="10"
+ layout="topleft"
+ left_pad="10"
+ min_val="0.02"
+ name="cut end"
+ top_delta="0"
+ width="68" />
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="10"
+ layout="topleft"
+ left="125"
+ name="text hollow"
+ top_pad="6"
+ width="68">
+ Hollow
+ </text>
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="10"
+ layout="topleft"
+ left_pad="10"
+ name="text skew"
+ top_delta="0"
+ width="63">
+ Skew
+ </text>
+ <spinner
+ decimal_digits="1"
+ follows="left|top"
+ height="19"
+ increment="5"
+ initial_value="0"
+ layout="topleft"
+ left="125"
+ max_val="95"
+ name="Scale 1"
+ top_pad="4"
+ width="68" />
+ <spinner
+ decimal_digits="2"
+ follows="left|top"
+ height="19"
+ increment="0.05"
+ initial_value="0"
+ layout="topleft"
+ left_pad="10"
+ max_val="0.95"
+ min_val="-0.95"
+ name="Skew"
+ top_delta="0"
+ width="68" />
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="10"
+ layout="topleft"
+ left="125"
+ name="Hollow Shape"
+ top_pad="6"
+ width="150">
+ Hollow Shape
+ </text>
+ <combo_box
+ height="19"
+ layout="topleft"
+ left_delta="0"
+ name="hole"
+ top_pad="4"
+ width="150">
+ <combo_box.item
+ label="Default"
+ name="Default"
+ value="Default" />
+ <combo_box.item
+ label="Circle"
+ name="Circle"
+ value="Circle" />
+ <combo_box.item
+ label="Square"
+ name="Square"
+ value="Square" />
+ <combo_box.item
+ label="Triangle"
+ name="Triangle"
+ value="Triangle" />
+ </combo_box>
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="10"
+ layout="topleft"
+ left_delta="0"
+ name="text twist"
+ top_pad="4"
+ width="150">
+ Twist Begin and End
+ </text>
+ <spinner
+ decimal_digits="0"
+ follows="left|top"
+ height="19"
+ increment="9"
+ initial_value="0"
+ label="B"
+ label_width="10"
+ layout="topleft"
+ left_delta="0"
+ max_val="180"
+ min_val="-180"
+ name="Twist Begin"
+ top_pad="4"
+ width="68" />
+ <spinner
+ decimal_digits="0"
+ follows="left|top"
+ height="19"
+ increment="9"
+ initial_value="0"
+ label="E"
+ label_width="10"
+ layout="topleft"
+ left_pad="10"
+ max_val="180"
+ min_val="-180"
+ name="Twist End"
+ top_delta="0"
+ width="68" />
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="10"
+ layout="topleft"
+ left="125"
+ name="scale_taper"
+ top_pad="6"
+ width="150">
+ Taper
+ </text>
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="10"
+ layout="topleft"
+ left_delta="0"
+ name="scale_hole"
+ top_delta="0"
+ width="150">
+ Hole Size
+ </text>
+ <spinner
+ decimal_digits="2"
+ follows="left|top"
+ height="19"
+ increment="0.05"
+ initial_value="0"
+ label="X"
+ label_width="10"
+ layout="topleft"
+ left_delta="0"
+ min_val="-1"
+ name="Taper Scale X"
+ top_pad="4"
+ width="68" />
+ <spinner
+ decimal_digits="2"
+ follows="left|top"
+ height="19"
+ increment="0.05"
+ initial_value="0"
+ label="Y"
+ label_width="10"
+ layout="topleft"
+ left_pad="10"
+ min_val="-1"
+ name="Taper Scale Y"
+ top_delta="0"
+ width="68" />
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="10"
+ layout="topleft"
+ left="125"
+ name="text topshear"
+ top_pad="6"
+ width="141">
+ Top Shear
+ </text>
+ <spinner
+ decimal_digits="2"
+ follows="left|top"
+ height="19"
+ increment="0.05"
+ initial_value="0"
+ label="X"
+ label_width="10"
+ layout="topleft"
+ left_delta="0"
+ max_val="0.5"
+ min_val="-0.5"
+ name="Shear X"
+ top_pad="4"
+ width="68" />
+ <spinner
+ decimal_digits="2"
+ follows="left|top"
+ height="19"
+ increment="0.05"
+ initial_value="0"
+ label="Y"
+ label_width="10"
+ layout="topleft"
+ left_pad="10"
+ max_val="0.5"
+ min_val="-0.5"
+ name="Shear Y"
+ top_delta="0"
+ width="68" />
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="10"
+ layout="topleft"
+ left="125"
+ name="advanced_cut"
+ top_pad="6"
+ width="150">
+ Profile Cut Begin and End
+ </text>
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="10"
+ layout="topleft"
+ left_delta="0"
+ name="advanced_dimple"
+ top_delta="0"
+ width="150">
+ Dimple Begin and End
+ </text>
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="10"
+ layout="topleft"
+ left_delta="0"
+ name="advanced_slice"
+ top_delta="0"
+ width="150">
+ Slice Begin and End
+ </text>
+ <spinner
+ follows="left|top"
+ height="19"
+ increment="0.025"
+ initial_value="0"
+ label="B"
+ label_width="10"
+ layout="topleft"
+ left_delta="0"
+ max_val="0.95"
+ name="Path Limit Begin"
+ top_pad="4"
+ width="68" />
+ <spinner
+ follows="left|top"
+ height="19"
+ increment="0.025"
+ initial_value="1"
+ label="E"
+ label_width="10"
+ layout="topleft"
+ left_pad="10"
+ min_val="0.05"
+ name="Path Limit End"
+ top_delta="0"
+ width="68" />
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="10"
+ layout="topleft"
+ left="125"
+ name="text taper2"
+ top_pad="6"
+ width="150">
+ Taper
+ </text>
+ <spinner
+ decimal_digits="2"
+ follows="left|top"
+ height="19"
+ increment="0.05"
+ initial_value="0"
+ label="X"
+ label_width="10"
+ layout="topleft"
+ left_delta="0"
+ min_val="-1"
+ name="Taper X"
+ top_pad="4"
+ width="68" />
+ <spinner
+ decimal_digits="2"
+ follows="left|top"
+ height="19"
+ increment="0.05"
+ initial_value="0"
+ label="Y"
+ label_width="10"
+ layout="topleft"
+ left_pad="10"
+ min_val="-1"
+ name="Taper Y"
+ top_delta="0"
+ width="68" />
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="10"
+ layout="topleft"
+ left="125"
+ name="text radius delta"
+ top_pad="6"
+ width="78">
+ Radius
+ </text>
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="10"
+ layout="topleft"
+ left_delta="78"
+ name="text revolutions"
+ top_delta="0"
+ width="68">
+ Revolutions
+ </text>
+ <spinner
+ follows="left|top"
+ height="19"
+ increment="0.05"
+ initial_value="0"
+ layout="topleft"
+ left="125"
+ min_val="-1"
+ name="Radius Offset"
+ top_pad="4"
+ width="68" />
+ <spinner
+ decimal_digits="2"
+ follows="left|top"
+ height="19"
+ initial_value="1"
+ layout="topleft"
+ left_pad="10"
+ max_val="4"
+ min_val="1"
+ name="Revolutions"
+ top_delta="0"
+ width="68" />
+ <texture_picker
+ can_apply_immediately="true"
+ default_image_name="Default"
+ follows="left|top"
+ height="141"
+ label="Sculpt Texture"
+ layout="topleft"
+ left="125"
+ name="sculpt texture control"
+ tool_tip="Click to choose a picture"
+ top="70"
+ visible="false"
+ width="145" />
+ <check_box
+ height="19"
+ label="Mirror"
+ layout="topleft"
+ left_delta="0"
+ name="sculpt mirror control"
+ tool_tip="Flips sculpted prim along the X axis."
+ top_pad="8"
+ visible="false"
+ width="130" />
+ <check_box
+ height="19"
+ label="Inside-out"
+ layout="topleft"
+ left_delta="0"
+ name="sculpt invert control"
+ tool_tip="Inverts the sculpted prims normals, making it appear inside-out."
+ top_pad="4"
+ visible="false"
+ width="121" />
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="10"
+ layout="topleft"
+ left_delta="0"
+ name="label sculpt type"
+ top_pad="10"
+ visible="false"
+ width="130">
+ Stitching type
+ </text>
+ <combo_box
+ height="19"
+ layout="topleft"
+ left_delta="0"
+ name="sculpt type control"
+ top_pad="4"
+ visible="false"
+ width="150">
+ <combo_box.item
+ label="(none)"
+ name="None"
+ value="None" />
+ <combo_box.item
+ label="Sphere"
+ name="Sphere"
+ value="Sphere" />
+ <combo_box.item
+ label="Torus"
+ name="Torus"
+ value="Torus" />
+ <combo_box.item
+ label="Plane"
+ name="Plane"
+ value="Plane" />
+ <combo_box.item
+ label="Cylinder"
+ name="Cylinder"
+ value="Cylinder" />
+ </combo_box>
+ </panel>
+
+ <panel
+ border="false"
+ follows="left|top|right|bottom"
+ height="367"
+ label="Features"
+ layout="topleft"
+ left_delta="0"
+ mouse_opaque="false"
+ name="Features"
+ top_delta="0"
+ width="280">
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="10"
+ layout="topleft"
+ left="10"
+ name="select_single"
+ top="10"
+ width="252">
+ Select only one primitive to edit features.
+ </text>
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="10"
+ layout="topleft"
+ left_delta="0"
+ name="edit_object"
+ top_delta="0"
+ width="252">
+ Edit object features:
+ </text>
+ <check_box
+ height="19"
+ label="Flexible Path"
+ layout="topleft"
+ left_delta="0"
+ name="Flexible1D Checkbox Ctrl"
+ tool_tip="Allows object to flex about the Z axis. (Client-side only)"
+ top_pad="10"
+ width="121" />
+ <spinner
+ follows="left|top"
+ height="19"
+ increment="1"
+ initial_value="2"
+ label="Softness"
+ label_width="65"
+ layout="topleft"
+ left_delta="0"
+ max_val="3"
+ name="FlexNumSections"
+ top_pad="10"
+ width="128" />
+ <spinner
+ follows="left|top"
+ height="19"
+ increment="0.5"
+ initial_value="0.3"
+ label="Gravity"
+ label_width="65"
+ layout="topleft"
+ left_delta="0"
+ max_val="10"
+ min_val="-10"
+ name="FlexGravity"
+ top_pad="4"
+ width="128" />
+ <spinner
+ follows="left|top"
+ height="19"
+ increment="0.5"
+ initial_value="2"
+ label="Drag"
+ label_width="65"
+ layout="topleft"
+ left_delta="0"
+ max_val="10"
+ name="FlexFriction"
+ top_pad="4"
+ width="128" />
+ <spinner
+ follows="left|top"
+ height="19"
+ increment="0.5"
+ initial_value="0"
+ label="Wind"
+ label_width="65"
+ layout="topleft"
+ left_delta="0"
+ max_val="10"
+ name="FlexWind"
+ top_pad="4"
+ width="128" />
+ <spinner
+ follows="left|top"
+ height="19"
+ increment="0.5"
+ initial_value="1"
+ label="Tension"
+ label_width="65"
+ layout="topleft"
+ left_delta="0"
+ max_val="10"
+ name="FlexTension"
+ top_pad="4"
+ width="128" />
+ <spinner
+ follows="left|top"
+ height="19"
+ increment="0.01"
+ initial_value="0"
+ label="Force X"
+ label_width="65"
+ layout="topleft"
+ left_delta="0"
+ max_val="10"
+ min_val="-10"
+ name="FlexForceX"
+ top_pad="4"
+ width="128" />
+ <spinner
+ follows="left|top"
+ height="19"
+ increment="0.01"
+ initial_value="0"
+ label="Force Y"
+ label_width="65"
+ layout="topleft"
+ left_delta="0"
+ max_val="10"
+ min_val="-10"
+ name="FlexForceY"
+ top_pad="4"
+ width="128" />
+ <spinner
+ follows="left|top"
+ height="19"
+ increment="0.01"
+ initial_value="0"
+ label="Force Z"
+ label_width="65"
+ layout="topleft"
+ left_delta="0"
+ max_val="10"
+ min_val="-10"
+ name="FlexForceZ"
+ top_pad="4"
+ width="128" />
+ <check_box
+ height="19"
+ label="Light"
+ layout="topleft"
+ left_delta="0"
+ name="Light Checkbox Ctrl"
+ tool_tip="Causes object to emit light"
+ top_pad="14"
+ width="121" />
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="10"
+ layout="topleft"
+ left_delta="0"
+ name="label color"
+ top_pad="15"
+ width="58">
+ Color
+ </text>
+ <color_swatch
+ border_color="0.45098 0.517647 0.607843 1"
+ can_apply_immediately="true"
+ color="0.5 0.5 0.5 1"
+ follows="left|top"
+ height="48"
+ layout="topleft"
+ left_delta="67"
+ name="colorswatch"
+ tool_tip="Click to open Color Picker"
+ top_delta="-10"
+ width="32" />
+ <spinner
+ follows="left|top"
+ height="19"
+ initial_value="0.5"
+ label="Intensity"
+ label_width="65"
+ layout="topleft"
+ left="10"
+ name="Light Intensity"
+ top_pad="4"
+ width="128" />
+ <spinner
+ follows="left|top"
+ height="19"
+ initial_value="5"
+ label="Radius"
+ label_width="65"
+ layout="topleft"
+ left_delta="0"
+ max_val="20"
+ name="Light Radius"
+ top_pad="0"
+ width="128" />
+ <spinner
+ follows="left|top"
+ height="19"
+ increment="0.25"
+ initial_value="1"
+ label="Falloff"
+ label_width="65"
+ layout="topleft"
+ left_delta="0"
+ max_val="2"
+ name="Light Falloff"
+ top_pad="0"
+ width="128" />
+ </panel>
+ <panel
+ border="false"
+ follows="left|top|right|bottom"
+ height="367"
+ label="Texture"
+ layout="topleft"
+ left_delta="0"
+ mouse_opaque="false"
+ name="Texture"
+ top_delta="0"
+ width="280">
+ <panel.string
+ name="string repeats per meter">
+ Repeats Per Meter
+ </panel.string>
+ <panel.string
+ name="string repeats per face">
+ Repeats Per Face
+ </panel.string>
+ <texture_picker
+ can_apply_immediately="true"
+ default_image_name="Default"
+ follows="left|top"
+ height="80"
+ label="Texture"
+ layout="topleft"
+ left="10"
+ name="texture control"
+ tool_tip="Click to choose a picture"
+ top="10"
+ width="64" />
+ <color_swatch
+ border_color="0.45098 0.517647 0.607843 1"
+ can_apply_immediately="true"
+ follows="left|top"
+ height="80"
+ label="Color"
+ layout="topleft"
+ left_pad="25"
+ name="colorswatch"
+ tool_tip="Click to open Color Picker"
+ top_delta="0"
+ width="64" />
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="10"
+ layout="topleft"
+ left_pad="20"
+ name="color trans"
+ top="10"
+ width="100">
+ Transparency %
+ </text>
+ <spinner
+ decimal_digits="0"
+ follows="left|top"
+ height="19"
+ increment="2"
+ initial_value="0"
+ layout="topleft"
+ left_delta="0"
+ max_val="90"
+ name="ColorTrans"
+ top_pad="4"
+ width="80" />
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="10"
+ layout="topleft"
+ left_delta="0"
+ name="glow label"
+ top_pad="4"
+ width="80">
+ Glow
+ </text>
+ <spinner
+ decimal_digits="2"
+ follows="left|top"
+ height="19"
+ initial_value="0"
+ layout="topleft"
+ left_delta="0"
+ name="glow"
+ top_pad="4"
+ width="80" />
+ <check_box
+ height="19"
+ label="Full Bright"
+ layout="topleft"
+ left_delta="0"
+ name="checkbox fullbright"
+ top_pad="7"
+ width="81" />
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="10"
+ layout="topleft"
+ left="10"
+ name="tex gen"
+ top_pad="10"
+ width="90">
+ Mapping
+ </text>
+ <combo_box
+ height="19"
+ layout="topleft"
+ left_delta="0"
+ name="combobox texgen"
+ top_pad="4"
+ width="80">
+ <combo_box.item
+ label="Default"
+ name="Default"
+ value="Default" />
+ <combo_box.item
+ label="Planar"
+ name="Planar"
+ value="Planar" />
+ </combo_box>
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="10"
+ layout="topleft"
+ left="100"
+ name="label shininess"
+ top_pad="-33"
+ width="70">
+ Shininess
+ </text>
+ <combo_box
+ height="19"
+ layout="topleft"
+ left_delta="0"
+ name="combobox shininess"
+ top_pad="4"
+ width="70">
+ <combo_box.item
+ label="None"
+ name="None"
+ value="None" />
+ <combo_box.item
+ label="Low"
+ name="Low"
+ value="Low" />
+ <combo_box.item
+ label="Medium"
+ name="Medium"
+ value="Medium" />
+ <combo_box.item
+ label="High"
+ name="High"
+ value="High" />
+ </combo_box>
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="10"
+ layout="topleft"
+ left="180"
+ name="label bumpiness"
+ top_pad="-33"
+ width="80">
+ Bumpiness
+ </text>
+ <combo_box
+ height="19"
+ layout="topleft"
+ left_delta="0"
+ name="combobox bumpiness"
+ top_pad="4"
+ width="80">
+ <combo_box.item
+ label="None"
+ name="None"
+ value="None" />
+ <combo_box.item
+ label="Brightness"
+ name="Brightness"
+ value="Brightness" />
+ <combo_box.item
+ label="Darkness"
+ name="Darkness"
+ value="Darkness" />
+ <combo_box.item
+ label="woodgrain"
+ name="woodgrain"
+ value="woodgrain" />
+ <combo_box.item
+ label="bark"
+ name="bark"
+ value="bark" />
+ <combo_box.item
+ label="bricks"
+ name="bricks"
+ value="bricks" />
+ <combo_box.item
+ label="checker"
+ name="checker"
+ value="checker" />
+ <combo_box.item
+ label="concrete"
+ name="concrete"
+ value="concrete" />
+ <combo_box.item
+ label="crustytile"
+ name="crustytile"
+ value="crustytile" />
+ <combo_box.item
+ label="cutstone"
+ name="cutstone"
+ value="cutstone" />
+ <combo_box.item
+ label="discs"
+ name="discs"
+ value="discs" />
+ <combo_box.item
+ label="gravel"
+ name="gravel"
+ value="gravel" />
+ <combo_box.item
+ label="petridish"
+ name="petridish"
+ value="petridish" />
+ <combo_box.item
+ label="siding"
+ name="siding"
+ value="siding" />
+ <combo_box.item
+ label="stonetile"
+ name="stonetile"
+ value="stonetile" />
+ <combo_box.item
+ label="stucco"
+ name="stucco"
+ value="stucco" />
+ <combo_box.item
+ label="suction"
+ name="suction"
+ value="suction" />
+ <combo_box.item
+ label="weave"
+ name="weave"
+ value="weave" />
+ </combo_box>
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="10"
+ layout="topleft"
+ left="10"
+ name="tex scale"
+ top_pad="15"
+ width="160">
+ Repeats per Face
+ </text>
+ <spinner
+ follows="left|top"
+ height="19"
+ initial_value="0"
+ label="Horizontal (U)"
+ label_width="90"
+ layout="topleft"
+ left="20"
+ max_val="100"
+ name="TexScaleU"
+ top_pad="10"
+ width="160" />
+ <check_box
+ height="19"
+ label="Flip"
+ layout="topleft"
+ left_pad="10"
+ name="checkbox flip s"
+ top_delta="1"
+ width="70" />
+ <spinner
+ follows="left|top"
+ height="19"
+ initial_value="0"
+ label="Vertical (V)"
+ label_width="90"
+ layout="topleft"
+ left="20"
+ max_val="100"
+ name="TexScaleV"
+ top_pad="0"
+ width="160" />
+ <check_box
+ height="19"
+ label="Flip"
+ layout="topleft"
+ left_pad="10"
+ name="checkbox flip t"
+ top_delta="1"
+ width="70" />
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="10"
+ layout="topleft"
+ left="10"
+ name="tex rotate"
+ top_pad="20"
+ width="102">
+ Rotation (degrees)
+ </text>
+ <spinner
+ decimal_digits="2"
+ follows="left|top"
+ height="19"
+ increment="1"
+ initial_value="0"
+ layout="topleft"
+ left_delta="102"
+ max_val="9999"
+ min_val="-9999"
+ name="TexRot"
+ top_delta="0"
+ width="68" />
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="10"
+ layout="topleft"
+ left="10"
+ name="rpt"
+ top_pad="0"
+ width="160">
+ Repeats Per Meter
+ </text>
+ <spinner
+ decimal_digits="1"
+ follows="left|top"
+ height="19"
+ initial_value="1"
+ layout="topleft"
+ left_delta="102"
+ max_val="10"
+ min_val="0.1"
+ name="rptctrl"
+ top_delta="0"
+ width="68" />
+ <button
+ follows="left|top"
+ font="SansSerifSmall"
+ height="19"
+ label="Apply"
+ label_selected="Apply"
+ layout="topleft"
+ left_pad="10"
+ name="button apply"
+ top_delta="-4"
+ width="75" />
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="10"
+ layout="topleft"
+ left="10"
+ name="tex offset"
+ top_pad="20"
+ width="160">
+ Offset
+ </text>
+ <spinner
+ follows="left|top"
+ height="19"
+ initial_value="0"
+ label="Horizontal (U)"
+ label_width="90"
+ layout="topleft"
+ left="20"
+ min_val="-1"
+ name="TexOffsetU"
+ top_pad="10"
+ width="160" />
+ <spinner
+ follows="left|top"
+ height="19"
+ initial_value="0"
+ label="Vertical (V)"
+ label_width="90"
+ layout="topleft"
+ left_delta="0"
+ min_val="-1"
+ name="TexOffsetV"
+ top_pad="2"
+ width="160" />
+<!--TODO: KILL THIS-->
+ <!-- <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="19"
+ layout="topleft"
+ left="10"
+ name="textbox autofix"
+ top="332"
+ width="160">
+ Align media texture
+(must load first)
+ </text>
+ <button
+ follows="left|top"
+ font="SansSerifSmall"
+ height="19"
+ label="Align"
+ label_selected="Align"
+ layout="topleft"
+ left="112"
+ name="button align"
+ top="340"
+ width="68" />-->
+ </panel>
+ <panel
+ border="false"
+ follows="left|top|right|bottom"
+ height="367"
+ label="Content"
+ layout="topleft"
+ left_delta="0"
+ mouse_opaque="false"
+ name="Contents"
+ top_delta="0"
+ width="280">
+ <button
+ follows="left|top"
+ height="19"
+ label="New Script"
+ label_selected="New Script..."
+ layout="topleft"
+ left="10"
+ name="button new script"
+ top="10"
+ width="100" />
+ <button
+ follows="left|top"
+ height="19"
+ label="Permissions..."
+ layout="topleft"
+ left_pad="10"
+ name="button permissions"
+ top_delta="0"
+ width="100" />
+ <panel_inventory
+ follows="left|top"
+ height="300"
+ layout="topleft"
+ left="10"
+ name="contents_inventory"
+ top="35"
+ width="260" />
+ </panel>
+ </tab_container>
+ <panel
+ follows="left|top"
+ height="384"
+ layout="topleft"
+ left_delta="0"
+ name="land info panel"
+ top_delta="0"
+ width="280">
+ <text
+ type="string"
+ length="1"
+ font="SansSerifBig"
+ follows="left|top"
+ height="19"
+ layout="topleft"
+ left="20"
+ name="label_parcel_info"
+ top="24"
+ width="150">
+ Parcel Information
+ </text>
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="19"
+ layout="topleft"
+ left="30"
+ name="label_area_price"
+ top="48"
+ width="150">
+ Price: L$[PRICE] for [AREA] m²
+ </text>
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="19"
+ layout="topleft"
+ left_delta="0"
+ name="label_area"
+ top_delta="0"
+ width="150">
+ Area: [AREA] m²
+ </text>
+ <button
+ follows="left|top"
+ height="19"
+ label="About Land..."
+ label_selected="About Land..."
+ layout="topleft"
+ left_delta="0"
+ name="button about land"
+ top_pad="4"
+ width="112" />
+ <check_box
+ control_name="ShowParcelOwners"
+ height="19"
+ label="Show owners"
+ layout="topleft"
+ left_delta="0"
+ name="checkbox show owners"
+ tool_tip="Colour parcels according to their ownership"
+ top_pad="8"
+ width="140" />
+ <button
+ follows="left|top"
+ height="19"
+ label="?"
+ label_selected="?"
+ layout="topleft"
+ left_pad="5"
+ name="button show owners help"
+ top_delta="-2"
+ width="18" />
+ <text
+ type="string"
+ length="1"
+ font="SansSerifBig"
+ follows="left|top"
+ height="19"
+ layout="topleft"
+ left="20"
+ name="label_parcel_modify"
+ top="152"
+ width="150">
+ Modify Parcel
+ </text>
+ <button
+ follows="left|top"
+ height="19"
+ label="Subdivide..."
+ label_selected="Subdivide..."
+ layout="topleft"
+ left="30"
+ name="button subdivide land"
+ top="172"
+ width="112" />
+ <button
+ follows="left|top"
+ height="19"
+ label="Join..."
+ label_selected="Join..."
+ layout="topleft"
+ left_delta="0"
+ name="button join land"
+ top_pad="4"
+ width="112" />
+ <text
+ type="string"
+ length="1"
+ font="SansSerifBig"
+ follows="left|top"
+ height="19"
+ layout="topleft"
+ left="20"
+ name="label_parcel_trans"
+ top="256"
+ width="150">
+ Land Transactions
+ </text>
+ <button
+ follows="left|top"
+ height="19"
+ label="Buy Land..."
+ label_selected="Buy Land..."
+ layout="topleft"
+ left="30"
+ name="button buy land"
+ top="276"
+ width="112" />
+ <button
+ follows="left|top"
+ height="19"
+ label="Abandon Land..."
+ label_selected="Abandon Land..."
+ layout="topleft"
+ left_delta="0"
+ name="button abandon land"
+ top_pad="4"
+ width="112" />
+ </panel>
+</floater>
diff --git a/indra/newview/skins/default/xui/en/floater_top_objects.xml b/indra/newview/skins/default/xui/en/floater_top_objects.xml
new file mode 100644
index 0000000000..ecd64d08e6
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/floater_top_objects.xml
@@ -0,0 +1,250 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<floater
+ can_resize="true"
+ height="350"
+ layout="topleft"
+ min_height="300"
+ min_width="450"
+ name="top_objects"
+ title="loading..."
+ width="550">
+ <floater.string
+ name="top_scripts_title">
+ Top Scripts
+ </floater.string>
+ <floater.string
+ name="top_scripts_text">
+ [COUNT] scripts taking a total of [TIME] ms
+ </floater.string>
+ <floater.string
+ name="scripts_score_label">
+ Time
+ </floater.string>
+ <floater.string
+ name="scripts_mono_time_label">
+ Mono Time
+ </floater.string>
+ <floater.string
+ name="top_colliders_title">
+ Top Colliders
+ </floater.string>
+ <floater.string
+ name="top_colliders_text">
+ Top [COUNT] objects experiencing many potential collisions
+ </floater.string>
+ <floater.string
+ name="colliders_score_label">
+ Score
+ </floater.string>
+ <floater.string
+ name="none_descriptor">
+ None found.
+ </floater.string>
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ font="SansSerif"
+ height="20"
+ layout="topleft"
+ left="10"
+ name="title_text"
+ top="30"
+ width="400">
+ Loading...
+ </text>
+ <scroll_list
+ draw_heading="true"
+ follows="left|top|bottom|right"
+ height="150"
+ layout="topleft"
+ left_delta="0"
+ multi_select="true"
+ name="objects_list"
+ top_delta="20"
+ width="530">
+ <scroll_list.columns
+ label="Score"
+ name="score"
+ width="55" />
+ <scroll_list.columns
+ label="Name"
+ name="name"
+ width="140" />
+ <scroll_list.columns
+ label="Owner"
+ name="owner"
+ width="105" />
+ <scroll_list.columns
+ label="Location"
+ name="location"
+ width="130" />
+ <scroll_list.columns
+ label="Time"
+ name="time"
+ width="100" />
+ <scroll_list.columns
+ label="Mono Time"
+ name="mono_time"
+ width="55" />
+ <scroll_list.commit_callback
+ function="TopObjects.CommitObjectsList" />
+ </scroll_list>
+ <text
+ type="string"
+ length="1"
+ follows="left|bottom"
+ height="20"
+ layout="topleft"
+ left_delta="0"
+ name="id_text"
+ top_pad="10"
+ width="100">
+ Object ID:
+ </text>
+ <line_editor
+ enabled="false"
+ follows="left|bottom|right"
+ height="20"
+ layout="topleft"
+ left_delta="70"
+ name="id_editor"
+ top_delta="-3"
+ width="350" />
+ <button
+ follows="bottom|right"
+ height="20"
+ label="Show Beacon"
+ layout="topleft"
+ left_pad="10"
+ name="show_beacon_btn"
+ top_delta="0"
+ width="100">
+ <button.commit_callback
+ function="TopObjects.ShowBeacon" />
+ </button>
+ <text
+ type="string"
+ length="1"
+ follows="left|bottom"
+ height="20"
+ layout="topleft"
+ left="10"
+ name="obj_name_text"
+ top="237"
+ width="100">
+ Object Name:
+ </text>
+ <line_editor
+ follows="left|bottom|right"
+ height="20"
+ layout="topleft"
+ left_delta="70"
+ name="object_name_editor"
+ top_delta="-3"
+ width="350" />
+ <button
+ follows="bottom|right"
+ height="20"
+ label="Filter"
+ layout="topleft"
+ left_pad="10"
+ name="filter_object_btn"
+ top_delta="0"
+ width="100">
+ <button.commit_callback
+ function="TopObjects.GetByObjectName" />
+ </button>
+ <text
+ type="string"
+ length="1"
+ follows="left|bottom"
+ height="20"
+ layout="topleft"
+ left="10"
+ name="owner_name_text"
+ top="264"
+ width="100">
+ Owner Name:
+ </text>
+ <line_editor
+ follows="left|bottom|right"
+ height="20"
+ layout="topleft"
+ left_delta="70"
+ name="owner_name_editor"
+ top_delta="-3"
+ width="350" />
+ <button
+ follows="bottom|right"
+ height="20"
+ label="Filter"
+ layout="topleft"
+ left_pad="10"
+ name="filter_owner_btn"
+ top_delta="0"
+ width="100">
+ <button.commit_callback
+ function="TopObjects.GetByOwnerName" />
+ </button>
+ <button
+ follows="bottom|left"
+ height="20"
+ label="Return Selected"
+ layout="topleft"
+ left="10"
+ name="return_selected_btn"
+ top="295"
+ width="130">
+ <button.commit_callback
+ function="TopObjects.ReturnSelected" />
+ </button>
+ <button
+ follows="bottom|left"
+ height="20"
+ label="Return All"
+ layout="topleft"
+ left_pad="10"
+ name="return_all_btn"
+ top_delta="0"
+ width="130">
+ <button.commit_callback
+ function="TopObjects.ReturnAll" />
+ </button>
+ <button
+ follows="bottom|left"
+ height="20"
+ label="Disable Selected"
+ layout="topleft"
+ left="10"
+ name="disable_selected_btn"
+ top="320"
+ width="130">
+ <button.commit_callback
+ function="TopObjects.DisableSelected" />
+ </button>
+ <button
+ follows="bottom|left"
+ height="20"
+ label="Disable All"
+ layout="topleft"
+ left_pad="10"
+ name="disable_all_btn"
+ top_delta="0"
+ width="130">
+ <button.commit_callback
+ function="TopObjects.DisableAll" />
+ </button>
+ <button
+ bottom="315"
+ follows="bottom|right"
+ height="20"
+ label="Refresh"
+ layout="topleft"
+ name="refresh_btn"
+ right="-10"
+ width="100">
+ <button.commit_callback
+ function="TopObjects.Refresh" />
+ </button>
+</floater>
diff --git a/indra/newview/skins/default/xui/en/floater_tos.xml b/indra/newview/skins/default/xui/en/floater_tos.xml
new file mode 100644
index 0000000000..54facbb659
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/floater_tos.xml
@@ -0,0 +1,80 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<floater
+ can_close="false"
+ can_minimize="false"
+ height="500"
+ layout="topleft"
+ name="modal container"
+ width="600">
+ <floater.string
+ name="real_url">
+ http://secondlife.com/app/tos/
+ </floater.string>
+ <button
+ enabled="false"
+ height="20"
+ label="Continue"
+ label_selected="Continue"
+ layout="topleft"
+ left="484"
+ name="Continue"
+ top="464"
+ width="100" />
+ <button
+ height="20"
+ label="Cancel"
+ label_selected="Cancel"
+ layout="topleft"
+ left_delta="-468"
+ name="Cancel"
+ top_delta="0"
+ width="100" />
+ <check_box
+ follows="top|right"
+ height="16"
+ label="I Agree to the Terms of Service"
+ layout="topleft"
+ left_delta="0"
+ name="agree_chk"
+ top_delta="-45"
+ width="55" />
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ font="SansSerif"
+ height="30"
+ layout="topleft"
+ left_delta="0"
+ name="tos_heading"
+ top_delta="-399"
+ width="552">
+ Please read the following Terms of Service carefully. To continue logging in to [SECOND_LIFE],
+you must accept the agreement.
+ </text>
+ <text_editor
+ type="string"
+ length="1"
+ follows="left|top"
+ font="SansSerif"
+ height="283"
+ layout="topleft"
+ left_delta="0"
+ max_length="65536"
+ name="tos_text"
+ top_pad="43"
+ width="568"
+ handle_edit_keys_directly="true"
+ word_wrap="true">
+ TOS_TEXT
+ </text_editor>
+ <web_browser
+ follows="left|top"
+ height="340"
+ layout="topleft"
+ left_delta="0"
+ name="tos_html"
+ start_url="data:text/html,%3Chtml%3E%3Chead%3E%3C/head%3E%3Cbody text=%22000000%22%3E%3Ch2%3E Loading %3Ca%20target%3D%22_external%22%20href%3D%22http%3A//secondlife.com/app/tos/%22%3ETerms%20of%20Service%3C/a%3E...%3C/h2%3E %3C/body%3E %3C/html%3E"
+ top_delta="-27"
+ width="568" />
+</floater>
diff --git a/indra/newview/skins/default/xui/en/floater_ui_preview.xml b/indra/newview/skins/default/xui/en/floater_ui_preview.xml
new file mode 100644
index 0000000000..bbb17dfb8f
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/floater_ui_preview.xml
@@ -0,0 +1,392 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<floater
+ can_resize="true"
+ height="640"
+ layout="topleft"
+ min_height="230"
+ min_width="650"
+ name="gui_preview_tool"
+ single_instance="true"
+ title="XUI Preview Tool"
+ width="750">
+ <panel
+ bottom="640"
+ follows="left|top|right|bottom"
+ layout="topleft"
+ left="0"
+ mouse_opaque="false"
+ name="main_panel"
+ right="650"
+ top="0">
+ <text
+ type="string"
+ length="1"
+ follows="top|left"
+ font="SansSerif"
+ height="30"
+ layout="topleft"
+ left="10"
+ name="select_language_label"
+ top="25"
+ width="130">
+ Primary Language:
+ </text>
+ <combo_box
+ follows="top|left"
+ height="20"
+ layout="topleft"
+ left_pad="5"
+ name="language_select_combo"
+ top_delta="0"
+ width="55">
+ <combo_box.item
+ label="en"
+ name="item1"
+ value="en" />
+ </combo_box>
+ <button
+ follows="left|top"
+ height="25"
+ label="Display Floater"
+ label_selected="Display Floater"
+ layout="topleft"
+ left_pad="10"
+ name="display_floater"
+ tool_tip="Display the XUI floater defined by the selected XML file"
+ top_delta="-2"
+ width="95" />
+ <button
+ enabled="false"
+ follows="left|top"
+ height="25"
+ label="Close Floater"
+ label_selected="Close Floater"
+ layout="topleft"
+ left_pad="10"
+ name="close_displayed_floater"
+ tool_tip="Closes the currently-displayed floater, if one exists"
+ top_delta="0"
+ width="85" />
+ <button
+ follows="left|top"
+ height="25"
+ label="Edit Floater..."
+ label_selected="Edit Floater..."
+ layout="topleft"
+ left_pad="10"
+ name="edit_floater"
+ tool_tip="Edit the XUI floater defined by the selected XML file (opens external editor). Opens en version if no localized version exists."
+ top_delta="0"
+ width="95" />
+ <button
+ follows="left|top"
+ height="25"
+ label="Save"
+ label_selected="Save"
+ layout="topleft"
+ left_pad="5"
+ name="save_floater"
+ tool_tip="Save the XUI floater defined by the selected XML file"
+ top_delta="0"
+ width="85" />
+ <button
+ follows="left|top"
+ height="25"
+ label="Save All"
+ label_selected="Save All"
+ layout="topleft"
+ left_pad="10"
+ name="save_all_floaters"
+ tool_tip="Save all XUI floaters defined by the selected language"
+ top_delta="0"
+ width="85" />
+ <button
+ enabled="false"
+ follows="right|top"
+ height="25"
+ is_toggle="true"
+ label="&gt; &gt;"
+ label_selected="&lt; &lt;"
+ layout="topleft"
+ left_pad="15"
+ name="toggle_overlap_panel"
+ tool_tip="Toggle highlighting and display panel for overlapping elements; right click an element to select it for this feature. The selected element is marked by a red rectangle."
+ top_delta="0"
+ width="30" />
+ <text
+ type="string"
+ length="1"
+ follows="top|left"
+ font="SansSerif"
+ height="30"
+ layout="topleft"
+ left="10"
+ name="select_language_label_2"
+ right="-50"
+ top="53"
+ width="105">
+ Secondary Language:
+ </text>
+ <combo_box
+ follows="top|left"
+ height="20"
+ layout="topleft"
+ left_delta="135"
+ name="language_select_combo_2"
+ top_delta="0"
+ width="55">
+ <combo_box.item
+ label="en"
+ name="item1"
+ value="en" />
+ </combo_box>
+ <button
+ follows="left|top"
+ height="25"
+ label="Display Floater"
+ label_selected="Display Floater"
+ layout="topleft"
+ left_pad="10"
+ name="display_floater_2"
+ tool_tip="Display the XUI floater defined by the selected XML file"
+ top_delta="-2"
+ width="95" />
+ <button
+ enabled="false"
+ follows="left|top"
+ height="25"
+ label="Close Floater"
+ label_selected="Close Floater"
+ layout="topleft"
+ left_pad="10"
+ name="close_displayed_floater_2"
+ tool_tip="Closes the currently-displayed floater, if one exists"
+ top_delta="0"
+ width="85" />
+ <button
+ follows="left|top"
+ height="25"
+ label="Export Schema"
+ layout="topleft"
+ left_pad="10"
+ name="export_schema"
+ top_delta="0"
+ width="120" />
+ <scroll_list
+ bottom="525"
+ column_padding="0"
+ draw_heading="true"
+ draw_stripes="false"
+ follows="left|top|bottom|right"
+ label="Name"
+ layout="topleft"
+ left="10"
+ name="name_list"
+ right="-10"
+ search_column="1"
+ top="80">
+ <scroll_list.columns
+ label="Title"
+ name="title_column"
+ width="150" />
+ <scroll_list.columns
+ label="File"
+ name="file_column"
+ width="150" />
+ <scroll_list.columns
+ dynamic_width="true"
+ label="Top-Level Node"
+ name="top_level_node_column" />
+ </scroll_list>
+ <panel
+ bevel_style="in"
+ bg_alpha_color="0 0 0 0"
+ bg_opaque_color="0 0 0 0.3"
+ border="true"
+ bottom_delta="65"
+ follows="left|right|bottom"
+ height="60"
+ layout="topleft"
+ left="10"
+ name="editor_panel"
+ right="-10">
+ <text
+ type="string"
+ length="1"
+ follows="left|bottom"
+ font="SansSerif"
+ height="30"
+ layout="topleft"
+ left="10"
+ left_delta="10"
+ name="editor_path_label"
+ top="10"
+ width="100">
+ Editor Path:
+ </text>
+ <line_editor
+ border_style="line"
+ border_thickness="1"
+ follows="left|bottom"
+ font="SansSerif"
+ handle_edit_keys_directly="true"
+ height="20"
+ layout="topleft"
+ left_delta="100"
+ max_length="300"
+ name="executable_path_field"
+ select_on_focus="true"
+ tool_tip="The full path to an editor (executable) to edit floater XML files (quotes not necessary)"
+ top_delta="-2"
+ width="315" />
+ <button
+ follows="left|bottom"
+ height="25"
+ label="Browse..."
+ label_selected="Browse..."
+ layout="topleft"
+ left_pad="5"
+ name="browse_for_executable"
+ tool_tip="Browse for an editor (executable) to edit floater XML files"
+ top_delta="-2"
+ width="75" />
+ <text
+ type="string"
+ length="1"
+ follows="left|bottom"
+ font="SansSerif"
+ height="30"
+ layout="topleft"
+ left="10"
+ left_delta="-420"
+ name="executable_args_label"
+ top="36"
+ width="100">
+ Editor Arguments:
+ </text>
+ <line_editor
+ border_style="line"
+ border_thickness="1"
+ follows="left|bottom"
+ font="SansSerif"
+ handle_edit_keys_directly="true"
+ height="20"
+ layout="topleft"
+ left_delta="100"
+ max_length="300"
+ name="executable_args_field"
+ select_on_focus="true"
+ tool_tip="Command-line arguments to the editor; use &apos;%FILE%&apos; to refer to the target file; &apos;YourProgram.exe FileName.xml&apos; will be run if this field is empty"
+ top_delta="-2"
+ width="315" />
+ </panel>
+ <panel
+ bevel_style="in"
+ bg_alpha_color="0 0 0 0"
+ bg_opaque_color="0 0 0 0.3"
+ border="true"
+ bottom_delta="40"
+ follows="left|right|bottom"
+ height="35"
+ layout="topleft"
+ left="10"
+ name="vlt_panel"
+ right="-10">
+ <text
+ type="string"
+ length="1"
+ follows="left|bottom"
+ font="SansSerif"
+ height="30"
+ layout="topleft"
+ left="10"
+ left_delta="10"
+ name="diff_file_label"
+ top="10"
+ width="200">
+ Delta File:
+ </text>
+ <line_editor
+ border_style="line"
+ border_thickness="1"
+ follows="left|bottom"
+ font="SansSerif"
+ handle_edit_keys_directly="true"
+ height="20"
+ layout="topleft"
+ left_delta="65"
+ max_length="300"
+ name="vlt_diff_path_field"
+ select_on_focus="true"
+ tool_tip="The full path to an XML D0 or D1 localization difference file generated by the Viewer Localization Toolkit"
+ top_delta="-2"
+ width="235" />
+ <button
+ follows="left|bottom"
+ height="25"
+ label="Browse..."
+ label_selected="Browse..."
+ layout="topleft"
+ left_pad="5"
+ name="browse_for_vlt_diffs"
+ tool_tip="Browse for a VLT-generated D0 or D1 difference file to highlight changed files and elements"
+ top_delta="-2"
+ width="75" />
+ <button
+ follows="left|bottom"
+ height="25"
+ is_toggle="true"
+ label="Highlight Diffs"
+ label_selected="Unhighlight Diffs"
+ layout="topleft"
+ left_pad="5"
+ name="toggle_vlt_diff_highlight"
+ tool_tip="Toggle highlighting of files and elements containing changed localization data"
+ top_delta="0"
+ width="110" />
+ </panel>
+ </panel>
+ <scroll_container
+ follows="top|right|bottom"
+ height="637"
+ layout="topleft"
+ left_delta="550"
+ name="overlap_scroll"
+ reserve_scroll_corner="true"
+ top_delta="2"
+ width="300">
+ <panel
+ background_opaque="true"
+ background_visible="true"
+ bevel_style="in"
+ bg_alpha_color="0 0 0 1"
+ bg_opaque_color="1 1 1 1"
+ border="true"
+ follows="top|right|bottom"
+ height="637"
+ label="Overlap Panel"
+ layout="topleft"
+ left_delta="0"
+ min_width="300"
+ name="overlap_panel"
+ tool_tip="This panel displays the currently-selected element and all of the elements that overlap it, separated by horizontal lines"
+ top="-607"
+ visible="false"
+ width="300" />
+ <text
+ type="string"
+ length="1"
+ follows="top|right"
+ font="SansSerif"
+ height="30"
+ layout="topleft"
+ left="10"
+ left_delta="10"
+ name="overlap_panel_label"
+ right="-50"
+ top="0"
+ width="150">
+ Overlapping Elements:
+ </text>
+ </scroll_container>
+</floater>
diff --git a/indra/newview/skins/default/xui/en/floater_url_entry.xml b/indra/newview/skins/default/xui/en/floater_url_entry.xml
new file mode 100644
index 0000000000..cf59d44d01
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/floater_url_entry.xml
@@ -0,0 +1,73 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<floater
+ can_minimize="false"
+ height="87"
+ layout="topleft"
+ name="url_entry"
+ width="280">
+ <text
+ type="string"
+ length="1"
+ bottom="20"
+ follows="top|left"
+ height="15"
+ layout="topleft"
+ left="10"
+ name="media_label"
+ top="20">
+ Media URL:
+ </text>
+ <combo_box
+ allow_text_entry="true"
+ follows="left|top|right"
+ height="19"
+ layout="topleft"
+ left_delta="70"
+ max_chars="255"
+ name="media_entry"
+ top_delta="-4"
+ width="190" />
+ <button
+ follows="top|left"
+ height="20"
+ font="SansSerifSmall"
+ label="OK"
+ layout="topleft"
+ left="10"
+ name="ok_btn"
+ top="50"
+ width="64" />
+ <button
+ follows="top|left"
+ height="20"
+ font="SansSerifSmall"
+ label="Cancel"
+ layout="topleft"
+ left_pad="5"
+ name="cancel_btn"
+ top_delta="0"
+ width="64" />
+ <button
+ follows="top|right"
+ height="20"
+ font="SansSerifSmall"
+ label="Clear"
+ layout="topleft"
+ left_pad="65"
+ name="clear_btn"
+ top_delta="0"
+ width="64" />
+ <text
+ type="string"
+ length="1"
+ font="SansSerifSmall"
+ bottom_delta="-2"
+ follows="bottom|left"
+ height="15"
+ layout="topleft"
+ left="152"
+ name="loading_label"
+ visible="true">
+ Loading...
+ </text>
+</floater>
diff --git a/indra/newview/skins/default/xui/en/floater_water.xml b/indra/newview/skins/default/xui/en/floater_water.xml
new file mode 100644
index 0000000000..07ebf734ea
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/floater_water.xml
@@ -0,0 +1,656 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<floater
+ height="240"
+ layout="topleft"
+ name="Water Floater"
+ save_rect="true"
+ title="Advanced Water Editor"
+ width="700">
+ <floater.string
+ name="WLDefaultWaterNames">
+ Default:Glassy:Pond:Murky:Second Plague:SNAKE!!!:Valdez
+ </floater.string>
+ <text
+ type="string"
+ length="1"
+ follows="left|top|right"
+ font="SansSerif"
+ height="16"
+ layout="topleft"
+ left="10"
+ name="KeyFramePresetsText"
+ top="34"
+ width="110">
+ Water Presets:
+ </text>
+ <combo_box
+ height="18"
+ layout="topleft"
+ left_delta="110"
+ name="WaterPresetsCombo"
+ top_delta="-2"
+ width="150" />
+ <button
+ height="20"
+ label="New"
+ label_selected="New"
+ layout="topleft"
+ left_pad="20"
+ name="WaterNewPreset"
+ top_delta="1"
+ width="70" />
+ <button
+ height="20"
+ label="Save"
+ label_selected="Save"
+ layout="topleft"
+ left_pad="10"
+ name="WaterSavePreset"
+ top_delta="0"
+ width="70" />
+ <button
+ height="20"
+ label="Delete"
+ label_selected="Delete"
+ layout="topleft"
+ left_pad="10"
+ name="WaterDeletePreset"
+ top_delta="0"
+ width="70" />
+ <tab_container
+ follows="left|top"
+ height="180"
+ layout="topleft"
+ left="0"
+ name="Water Tabs"
+ tab_position="top"
+ top="60"
+ width="700">
+ <panel
+ border="true"
+ follows="left|top|right|bottom"
+ height="180"
+ label="Settings"
+ layout="topleft"
+ left="1"
+ mouse_opaque="false"
+ name="Settings"
+ top="60"
+ width="698">
+ <text
+ type="string"
+ length="1"
+ follows="left|top|right"
+ font="SansSerif"
+ height="16"
+ layout="topleft"
+ left="10"
+ name="BHText"
+ top="4"
+ width="355">
+ Water Fog Color
+ </text>
+ <button
+ follows="left|top"
+ font="SansSerifSmall"
+ height="18"
+ label="?"
+ layout="topleft"
+ left_delta="150"
+ name="WaterFogColorHelp"
+ top_delta="-2"
+ width="18" />
+ <color_swatch
+ border_color="0.45098 0.517647 0.607843 1"
+ can_apply_immediately="true"
+ color="0.5 0.5 0.5 1"
+ follows="left|top"
+ height="50"
+ layout="topleft"
+ left="40"
+ name="WaterFogColor"
+ tool_tip="Click to open Color Picker"
+ top="30"
+ width="40" />
+ <text
+ type="string"
+ length="1"
+ follows="left|top|right"
+ font="SansSerif"
+ height="16"
+ layout="topleft"
+ left="10"
+ name="WaterFogDensText"
+ top="74"
+ width="355">
+ Fog Density Exponent
+ </text>
+ <button
+ follows="left|top"
+ font="SansSerifSmall"
+ height="18"
+ label="?"
+ layout="topleft"
+ left_delta="150"
+ name="WaterFogDensityHelp"
+ top_delta="-2"
+ width="18" />
+ <slider
+ control_name="WaterFogDensity"
+ decimal_digits="1"
+ follows="left"
+ height="10"
+ initial_value="16"
+ layout="topleft"
+ left="24"
+ max_val="10"
+ name="WaterFogDensity"
+ top="110"
+ width="200" />
+ <text
+ type="string"
+ length="1"
+ follows="left|top|right"
+ font="SansSerif"
+ height="16"
+ layout="topleft"
+ left_delta="-14"
+ name="WaterUnderWaterFogModText"
+ top_delta="4"
+ width="355">
+ Underwater Fog Modifier
+ </text>
+ <button
+ follows="left|top"
+ font="SansSerifSmall"
+ height="18"
+ label="?"
+ layout="topleft"
+ left_delta="150"
+ name="WaterUnderWaterFogModHelp"
+ top_delta="-2"
+ width="18" />
+ <slider
+ decimal_digits="2"
+ follows="left"
+ height="10"
+ increment="0.01"
+ initial_value="16"
+ layout="topleft"
+ left="24"
+ max_val="2"
+ name="WaterUnderWaterFogMod"
+ top="150"
+ width="200" />
+ <text
+ type="string"
+ length="1"
+ follows="left|top|right"
+ font="SansSerif"
+ height="16"
+ layout="topleft"
+ left="245"
+ name="BDensText"
+ top="4"
+ width="355">
+ Reflection Wavelet Scale
+ </text>
+ <button
+ follows="left|top"
+ font="SansSerifSmall"
+ height="18"
+ label="?"
+ layout="topleft"
+ left_delta="150"
+ name="WaterNormalScaleHelp"
+ top_delta="-2"
+ width="18" />
+ <text
+ type="string"
+ length="1"
+ follows="left|top|right"
+ halign="center"
+ height="16"
+ layout="topleft"
+ left="245"
+ name="BHText2"
+ top="21"
+ width="10">
+ 1
+ </text>
+ <text
+ type="string"
+ length="1"
+ follows="left|top|right"
+ halign="center"
+ height="16"
+ layout="topleft"
+ left_delta="0"
+ name="BHText3"
+ top_delta="11"
+ width="10">
+ 2
+ </text>
+ <text
+ type="string"
+ length="1"
+ follows="left|top|right"
+ halign="center"
+ height="16"
+ layout="topleft"
+ left_delta="0"
+ name="BHText4"
+ top_delta="11"
+ width="10">
+ 3
+ </text>
+ <slider
+ control_name="WaterNormalScaleX"
+ decimal_digits="1"
+ follows="left"
+ height="10"
+ initial_value="0.7"
+ layout="topleft"
+ left_pad="4"
+ max_val="10"
+ name="WaterNormalScaleX"
+ top_delta="-3"
+ width="200" />
+ <slider
+ control_name="WaterNormalScaleY"
+ decimal_digits="1"
+ follows="left"
+ height="10"
+ initial_value="0.7"
+ layout="topleft"
+ left_delta="0"
+ max_val="10"
+ name="WaterNormalScaleY"
+ top_pad="1"
+ width="200" />
+ <slider
+ control_name="WaterNormalScaleZ"
+ decimal_digits="1"
+ follows="left"
+ height="10"
+ initial_value="0.7"
+ layout="topleft"
+ left_delta="0"
+ max_val="10"
+ name="WaterNormalScaleZ"
+ top_pad="1"
+ width="200" />
+ <text
+ type="string"
+ length="1"
+ follows="left|top|right"
+ font="SansSerif"
+ height="16"
+ layout="topleft"
+ left_delta="-14"
+ name="HDText"
+ top_delta="2"
+ width="355">
+ Fresnel Scale
+ </text>
+ <button
+ follows="left|top"
+ font="SansSerifSmall"
+ height="18"
+ label="?"
+ layout="topleft"
+ left_delta="150"
+ name="WaterFresnelScaleHelp"
+ top_delta="-2"
+ width="18" />
+ <slider
+ control_name="WaterFresnelScale"
+ decimal_digits="2"
+ follows="left"
+ height="10"
+ increment="0.01"
+ initial_value="0.7"
+ layout="topleft"
+ left="259"
+ name="WaterFresnelScale"
+ top="100"
+ width="200" />
+ <text
+ type="string"
+ length="1"
+ follows="left|top|right"
+ font="SansSerif"
+ height="16"
+ layout="topleft"
+ left_delta="-14"
+ name="FresnelOffsetText"
+ top_delta="-1"
+ width="355">
+ Fresnel Offset
+ </text>
+ <button
+ follows="left|top"
+ font="SansSerifSmall"
+ height="18"
+ label="?"
+ layout="topleft"
+ left_delta="150"
+ name="WaterFresnelOffsetHelp"
+ top_delta="-2"
+ width="18" />
+ <slider
+ control_name="WaterFresnelOffset"
+ decimal_digits="2"
+ follows="left"
+ height="10"
+ increment="0.01"
+ initial_value="0.7"
+ layout="topleft"
+ left="259"
+ name="WaterFresnelOffset"
+ top="135"
+ width="200" />
+ <text
+ type="string"
+ length="1"
+ follows="left|top|right"
+ font="SansSerif"
+ height="16"
+ layout="topleft"
+ left="480"
+ name="DensMultText"
+ top="4"
+ width="355">
+ Refract Scale Above
+ </text>
+ <button
+ follows="left|top"
+ font="SansSerifSmall"
+ height="18"
+ label="?"
+ layout="topleft"
+ left_delta="150"
+ name="WaterScaleAboveHelp"
+ top_delta="-2"
+ width="18" />
+ <slider
+ control_name="WaterScaleAbove"
+ decimal_digits="2"
+ follows="left"
+ height="10"
+ increment="0.01"
+ initial_value="0.1"
+ layout="topleft"
+ left="494"
+ name="WaterScaleAbove"
+ top="40"
+ width="200" />
+ <text
+ type="string"
+ length="1"
+ follows="left|top|right"
+ font="SansSerif"
+ height="16"
+ layout="topleft"
+ left_delta="-14"
+ name="WaterScaleBelowText"
+ top_delta="-3"
+ width="355">
+ Refract Scale Below
+ </text>
+ <button
+ follows="left|top"
+ font="SansSerifSmall"
+ height="18"
+ label="?"
+ layout="topleft"
+ left_delta="150"
+ name="WaterScaleBelowHelp"
+ top_delta="-2"
+ width="18" />
+ <slider
+ control_name="WaterScaleBelow"
+ decimal_digits="2"
+ follows="left"
+ height="10"
+ increment="0.01"
+ initial_value="0"
+ layout="topleft"
+ left="494"
+ name="WaterScaleBelow"
+ top="73"
+ width="200" />
+ <text
+ type="string"
+ length="1"
+ follows="left|top|right"
+ font="SansSerif"
+ height="16"
+ layout="topleft"
+ left_delta="-14"
+ name="MaxAltText"
+ top_delta="-2"
+ width="355">
+ Blur Multiplier
+ </text>
+ <button
+ follows="left|top"
+ font="SansSerifSmall"
+ height="18"
+ label="?"
+ layout="topleft"
+ left_delta="150"
+ name="WaterBlurMultiplierHelp"
+ top_delta="-2"
+ width="18" />
+ <slider
+ control_name="WaterBlurMult"
+ follows="left"
+ height="10"
+ increment="0.001"
+ initial_value="0"
+ layout="topleft"
+ left="494"
+ max_val="0.16"
+ name="WaterBlurMult"
+ top="107"
+ width="200" />
+ </panel>
+ <panel
+ border="true"
+ follows="left|top|right|bottom"
+ height="180"
+ label="Image"
+ layout="topleft"
+ left_delta="0"
+ mouse_opaque="false"
+ name="Waves"
+ top_delta="44"
+ width="698">
+ <text
+ type="string"
+ length="1"
+ follows="left|top|right"
+ font="SansSerif"
+ height="16"
+ layout="topleft"
+ left="10"
+ name="BHText"
+ top="4"
+ width="355">
+ Big Wave Direction
+ </text>
+ <button
+ follows="left|top"
+ font="SansSerifSmall"
+ height="18"
+ label="?"
+ layout="topleft"
+ left_delta="145"
+ name="WaterWave1Help"
+ top_delta="-2"
+ width="18" />
+ <text
+ type="string"
+ length="1"
+ follows="left|top|right"
+ halign="center"
+ height="16"
+ layout="topleft"
+ left="10"
+ name="WaterWave1DirXText"
+ top="21"
+ width="10">
+ X
+ </text>
+ <text
+ type="string"
+ length="1"
+ follows="left|top|right"
+ halign="center"
+ height="16"
+ layout="topleft"
+ left_delta="0"
+ name="WaterWave1DirYText"
+ top_delta="11"
+ width="10">
+ Y
+ </text>
+ <slider
+ control_name="WaterWave1DirX"
+ decimal_digits="2"
+ follows="left"
+ height="10"
+ increment="0.01"
+ initial_value="0.7"
+ layout="topleft"
+ left="24"
+ max_val="4"
+ min_val="-4"
+ name="WaterWave1DirX"
+ top="40"
+ width="200" />
+ <slider
+ control_name="WaterWave1DirY"
+ decimal_digits="2"
+ follows="left"
+ height="10"
+ increment="0.01"
+ initial_value="0.7"
+ layout="topleft"
+ left_delta="0"
+ max_val="4"
+ min_val="-4"
+ name="WaterWave1DirY"
+ top_pad="1"
+ width="200" />
+ <text
+ type="string"
+ length="1"
+ follows="left|top|right"
+ font="SansSerif"
+ height="16"
+ layout="topleft"
+ left_delta="-14"
+ name="BHText2"
+ top_delta="3"
+ width="355">
+ Little Wave Direction
+ </text>
+ <button
+ follows="left|top"
+ font="SansSerifSmall"
+ height="18"
+ label="?"
+ layout="topleft"
+ left_delta="145"
+ name="WaterWave2Help"
+ top_delta="-2"
+ width="18" />
+ <text
+ type="string"
+ length="1"
+ follows="left|top|right"
+ halign="center"
+ height="16"
+ layout="topleft"
+ left="10"
+ name="WaterWave2DirXText"
+ top="71"
+ width="10">
+ X
+ </text>
+ <text
+ type="string"
+ length="1"
+ follows="left|top|right"
+ halign="center"
+ height="16"
+ layout="topleft"
+ left_delta="0"
+ name="WaterWave2DirYText"
+ top_delta="11"
+ width="10">
+ Y
+ </text>
+ <slider
+ control_name="WaterWave2DirX"
+ decimal_digits="2"
+ follows="left"
+ height="10"
+ increment="0.01"
+ initial_value="0.7"
+ layout="topleft"
+ left="24"
+ max_val="4"
+ min_val="-4"
+ name="WaterWave2DirX"
+ top="90"
+ width="200" />
+ <slider
+ control_name="WaterWave2DirY"
+ decimal_digits="2"
+ follows="left"
+ height="10"
+ increment="0.01"
+ initial_value="0.7"
+ layout="topleft"
+ left_delta="0"
+ max_val="4"
+ min_val="-4"
+ name="WaterWave2DirY"
+ top_pad="1"
+ width="200" />
+ <text
+ type="string"
+ length="1"
+ follows="left|top|right"
+ font="SansSerif"
+ height="16"
+ layout="topleft"
+ left="240"
+ name="BHText3"
+ top="4"
+ width="355">
+ Normal Map
+ </text>
+ <button
+ follows="left|top"
+ font="SansSerifSmall"
+ height="18"
+ label="?"
+ layout="topleft"
+ left_delta="125"
+ name="WaterNormalMapHelp"
+ top_delta="-2"
+ width="18" />
+ <texture_picker
+ height="143"
+ layout="topleft"
+ left="250"
+ name="WaterNormalMap"
+ top="22"
+ width="128" />
+ </panel>
+ </tab_container>
+</floater>
diff --git a/indra/newview/skins/default/xui/en/floater_wearable_save_as.xml b/indra/newview/skins/default/xui/en/floater_wearable_save_as.xml
new file mode 100644
index 0000000000..ee67989d33
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/floater_wearable_save_as.xml
@@ -0,0 +1,58 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<floater
+ border="true"
+ can_close="false"
+ can_minimize="false"
+ height="100"
+ layout="topleft"
+ name="modal container"
+ width="240">
+ <button
+ height="20"
+ label="Save"
+ label_selected="Save"
+ layout="topleft"
+ left="20"
+ name="Save"
+ top="70"
+ width="82" />
+ <button
+ height="20"
+ label="Cancel"
+ label_selected="Cancel"
+ layout="topleft"
+ left_pad="36"
+ name="Cancel"
+ top_delta="0"
+ width="82" />
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ font="SansSerif"
+ height="16"
+ layout="topleft"
+ left="20"
+ name="Save item as:"
+ top="10"
+ width="200">
+ Save item as:
+ </text>
+ <line_editor
+ type="string"
+ length="1"
+ border_style="line"
+ border_thickness="1"
+ follows="left|top"
+ font="SansSerif"
+ handle_edit_keys_directly="true"
+ height="20"
+ layout="topleft"
+ left_delta="0"
+ max_length="63"
+ name="name ed"
+ top_pad="4"
+ width="200">
+ New [DESC]
+ </line_editor>
+</floater>
diff --git a/indra/newview/skins/default/xui/en/floater_windlight_options.xml b/indra/newview/skins/default/xui/en/floater_windlight_options.xml
new file mode 100644
index 0000000000..5257cc687e
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/floater_windlight_options.xml
@@ -0,0 +1,1487 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<floater
+ height="220"
+ layout="topleft"
+ name="WindLight floater"
+ save_rect="true"
+ title="Advanced Sky Editor"
+ width="700">
+ <floater.string
+ name="WLDefaultSkyNames">
+ A-12AM:A-12PM:A-3AM:A-3PM:A-4.30PM:A-6AM:A-6PM:A-9AM:A-9PM:Barcelona:Blizzard:Blue Midday:Coastal Afternoon:Coastal Sunset:Default:Desert Sunset:Fine Day:Fluffy Big Clouds:Foggy:Funky Funky:Funky Funky Funky:Gelatto:Ghost:Incongruent Truths:Midday 1:Midday 2:Midday 3:Midday 4:Night:Pirate:Purple:Sailor&apos;s Delight:Sheer Sensuality
+ </floater.string>
+ <text
+ type="string"
+ length="1"
+ follows="left|top|right"
+ font="SansSerif"
+ height="16"
+ layout="topleft"
+ left="10"
+ name="KeyFramePresetsText"
+ top="34"
+ width="110">
+ Sky Presets:
+ </text>
+ <combo_box
+ height="18"
+ layout="topleft"
+ left_delta="110"
+ name="WLPresetsCombo"
+ top_delta="-2"
+ width="150" />
+ <button
+ height="20"
+ label="New"
+ label_selected="New"
+ layout="topleft"
+ left_pad="20"
+ name="WLNewPreset"
+ top_delta="1"
+ width="70" />
+ <button
+ height="20"
+ label="Save"
+ label_selected="Save"
+ layout="topleft"
+ left_pad="10"
+ name="WLSavePreset"
+ top_delta="0"
+ width="70" />
+ <button
+ height="20"
+ label="Delete"
+ label_selected="Delete"
+ layout="topleft"
+ left_pad="10"
+ name="WLDeletePreset"
+ top_delta="0"
+ width="70" />
+ <button
+ height="20"
+ label="Day Cycle Editor"
+ label_selected="Day Cycle Editor"
+ layout="topleft"
+ left_pad="50"
+ name="WLDayCycleMenuButton"
+ top_delta="0"
+ width="120" />
+ <tab_container
+ follows="left|top"
+ height="160"
+ layout="topleft"
+ left="0"
+ name="WindLight Tabs"
+ tab_position="top"
+ top="60"
+ width="700">
+ <panel
+ border="true"
+ follows="left|top|right|bottom"
+ height="160"
+ label="Atmosphere"
+ layout="topleft"
+ left="1"
+ mouse_opaque="false"
+ name="Atmosphere"
+ top="60"
+ width="698">
+ <text
+ type="string"
+ length="1"
+ follows="left|top|right"
+ font="SansSerif"
+ height="16"
+ layout="topleft"
+ left="10"
+ name="BHText"
+ top="4"
+ width="355">
+ Blue Horizon
+ </text>
+ <button
+ follows="left|top"
+ font="SansSerifSmall"
+ height="18"
+ label="?"
+ layout="topleft"
+ left_delta="150"
+ name="WLBlueHorizonHelp"
+ top_delta="-2"
+ width="18" />
+ <text
+ type="string"
+ length="1"
+ follows="left|top|right"
+ halign="center"
+ height="16"
+ layout="topleft"
+ left="10"
+ name="BHText2"
+ top="21"
+ width="10">
+ R
+ </text>
+ <text
+ type="string"
+ length="1"
+ follows="left|top|right"
+ halign="center"
+ height="16"
+ layout="topleft"
+ left_delta="0"
+ name="BHText3"
+ top_delta="11"
+ width="10">
+ G
+ </text>
+ <text
+ type="string"
+ length="1"
+ follows="left|top|right"
+ halign="center"
+ height="16"
+ layout="topleft"
+ left_delta="0"
+ name="BHText4"
+ top_delta="11"
+ width="10">
+ B
+ </text>
+ <text
+ type="string"
+ length="1"
+ follows="left|top|right"
+ halign="center"
+ height="16"
+ layout="topleft"
+ left_delta="0"
+ name="BHText5"
+ top_delta="11"
+ width="10">
+ I
+ </text>
+ <slider
+ control_name="WLBlueHorizonR"
+ decimal_digits="2"
+ follows="left"
+ height="10"
+ increment="0.01"
+ initial_value="0.7"
+ layout="topleft"
+ left="24"
+ name="WLBlueHorizonR"
+ top="40"
+ width="200" />
+ <slider
+ control_name="WLBlueHorizonG"
+ decimal_digits="2"
+ follows="left"
+ height="10"
+ increment="0.01"
+ initial_value="0.7"
+ layout="topleft"
+ left_delta="0"
+ name="WLBlueHorizonG"
+ top_pad="1"
+ width="200" />
+ <slider
+ control_name="WLBlueHorizonB"
+ decimal_digits="2"
+ follows="left"
+ height="10"
+ increment="0.01"
+ initial_value="0.7"
+ layout="topleft"
+ left_delta="0"
+ name="WLBlueHorizonB"
+ top_pad="1"
+ width="200" />
+ <slider
+ control_name="WLBlueHorizonI"
+ decimal_digits="2"
+ follows="left"
+ height="10"
+ increment="0.01"
+ initial_value="1.0"
+ layout="topleft"
+ left_delta="0"
+ name="WLBlueHorizonI"
+ top_pad="1"
+ width="200" />
+ <text
+ type="string"
+ length="1"
+ follows="left|top|right"
+ font="SansSerif"
+ height="16"
+ layout="topleft"
+ left_delta="-14"
+ name="BDensText"
+ top_delta="-2"
+ width="355">
+ Haze Horizon
+ </text>
+ <button
+ follows="left|top"
+ font="SansSerifSmall"
+ height="18"
+ label="?"
+ layout="topleft"
+ left_delta="150"
+ name="WLHazeHorizonHelp"
+ top_delta="-2"
+ width="18" />
+ <slider
+ control_name="WLHazeHorizon"
+ decimal_digits="2"
+ follows="left"
+ height="10"
+ increment="0.01"
+ initial_value="0.25"
+ layout="topleft"
+ left="24"
+ name="WLHazeHorizon"
+ top="107"
+ width="200" />
+ <text
+ type="string"
+ length="1"
+ follows="left|top|right"
+ font="SansSerif"
+ height="16"
+ layout="topleft"
+ left="245"
+ name="BDensText2"
+ top="4"
+ width="355">
+ Blue Density
+ </text>
+ <button
+ follows="left|top"
+ font="SansSerifSmall"
+ height="18"
+ label="?"
+ layout="topleft"
+ left_delta="150"
+ name="WLBlueDensityHelp"
+ top_delta="-2"
+ width="18" />
+ <text
+ type="string"
+ length="1"
+ follows="left|top|right"
+ halign="center"
+ height="16"
+ layout="topleft"
+ left="245"
+ name="BHText6"
+ top="21"
+ width="10">
+ R
+ </text>
+ <text
+ type="string"
+ length="1"
+ follows="left|top|right"
+ halign="center"
+ height="16"
+ layout="topleft"
+ left_delta="0"
+ name="BHText7"
+ top_delta="11"
+ width="10">
+ G
+ </text>
+ <text
+ type="string"
+ length="1"
+ follows="left|top|right"
+ halign="center"
+ height="16"
+ layout="topleft"
+ left_delta="0"
+ name="BHText8"
+ top_delta="11"
+ width="10">
+ B
+ </text>
+ <text
+ type="string"
+ length="1"
+ follows="left|top|right"
+ halign="center"
+ height="16"
+ layout="topleft"
+ left_delta="0"
+ name="BHText9"
+ top_delta="11"
+ width="10">
+ I
+ </text>
+ <slider
+ control_name="WLBlueDensityR"
+ decimal_digits="2"
+ follows="left"
+ height="10"
+ increment="0.01"
+ initial_value="0.7"
+ layout="topleft"
+ left="259"
+ name="WLBlueDensityR"
+ top="40"
+ width="200" />
+ <slider
+ control_name="WLBlueDensityG"
+ decimal_digits="2"
+ follows="left"
+ height="10"
+ increment="0.01"
+ initial_value="0.7"
+ layout="topleft"
+ left_delta="0"
+ name="WLBlueDensityG"
+ top_pad="1"
+ width="200" />
+ <slider
+ control_name="WLBlueDensityB"
+ decimal_digits="2"
+ follows="left"
+ height="10"
+ increment="0.01"
+ initial_value="0.7"
+ layout="topleft"
+ left_delta="0"
+ name="WLBlueDensityB"
+ top_pad="1"
+ width="200" />
+ <slider
+ control_name="WLBlueDensityI"
+ decimal_digits="2"
+ follows="left"
+ height="10"
+ increment="0.01"
+ initial_value="1"
+ layout="topleft"
+ left_delta="0"
+ name="WLBlueDensityI"
+ top_pad="1"
+ width="200" />
+ <text
+ type="string"
+ length="1"
+ follows="left|top|right"
+ font="SansSerif"
+ height="16"
+ layout="topleft"
+ left_delta="-14"
+ name="HDText"
+ top_delta="-2"
+ width="355">
+ Haze Density
+ </text>
+ <button
+ follows="left|top"
+ font="SansSerifSmall"
+ height="18"
+ label="?"
+ layout="topleft"
+ left_delta="150"
+ name="WLHazeDensityHelp"
+ top_delta="-2"
+ width="18" />
+ <slider
+ control_name="WLHazeDensity"
+ decimal_digits="2"
+ follows="left"
+ height="10"
+ increment="0.01"
+ initial_value="0.7"
+ layout="topleft"
+ left="259"
+ max_val="4"
+ name="WLHazeDensity"
+ top="107"
+ width="200" />
+ <text
+ type="string"
+ length="1"
+ follows="left|top|right"
+ font="SansSerif"
+ height="16"
+ layout="topleft"
+ left="480"
+ name="DensMultText"
+ top="4"
+ width="355">
+ Density Multiplier
+ </text>
+ <button
+ follows="left|top"
+ font="SansSerifSmall"
+ height="18"
+ label="?"
+ layout="topleft"
+ left_delta="150"
+ name="WLDensityMultHelp"
+ top_delta="-2"
+ width="18" />
+ <slider
+ control_name="WLDensityMult"
+ decimal_digits="2"
+ follows="left"
+ height="10"
+ increment="0.01"
+ initial_value="0.1"
+ layout="topleft"
+ left="494"
+ max_val="0.9"
+ name="WLDensityMult"
+ top="40"
+ width="200" />
+ <text
+ type="string"
+ length="1"
+ follows="left|top|right"
+ font="SansSerif"
+ height="16"
+ layout="topleft"
+ left_delta="-14"
+ name="WLDistanceMultText"
+ top_delta="-3"
+ width="355">
+ Distance Multiplier
+ </text>
+ <button
+ follows="left|top"
+ font="SansSerifSmall"
+ height="18"
+ label="?"
+ layout="topleft"
+ left_delta="150"
+ name="WLDistanceMultHelp"
+ top_delta="-2"
+ width="18" />
+ <slider
+ control_name="WLDistancMult"
+ decimal_digits="1"
+ follows="left"
+ height="10"
+ initial_value="1.0"
+ layout="topleft"
+ left="494"
+ max_val="100"
+ name="WLDistanceMult"
+ top="73"
+ width="207" />
+ <text
+ type="string"
+ length="1"
+ follows="left|top|right"
+ font="SansSerif"
+ height="16"
+ layout="topleft"
+ left_delta="-14"
+ name="MaxAltText"
+ top_delta="-2"
+ width="355">
+ Max Altitude
+ </text>
+ <button
+ follows="left|top"
+ font="SansSerifSmall"
+ height="18"
+ label="?"
+ layout="topleft"
+ left_delta="150"
+ name="WLMaxAltitudeHelp"
+ top_delta="-2"
+ width="18" />
+ <slider
+ control_name="WLMaxAltitude"
+ decimal_digits="0"
+ follows="left"
+ height="10"
+ increment="1"
+ initial_value="500"
+ layout="topleft"
+ left="494"
+ max_val="4000"
+ name="WLMaxAltitude"
+ top="107"
+ width="205" />
+ </panel>
+ <panel
+ border="true"
+ follows="left|top|right|bottom"
+ height="160"
+ label="Lighting"
+ layout="topleft"
+ left_delta="0"
+ name="Lighting"
+ top_delta="4"
+ width="698">
+ <text
+ type="string"
+ length="1"
+ follows="left|top|right"
+ font="SansSerif"
+ height="16"
+ layout="topleft"
+ left="10"
+ name="SLCText"
+ top="4"
+ width="355">
+ Sun/Moon Color
+ </text>
+ <button
+ follows="left|top"
+ font="SansSerifSmall"
+ height="18"
+ label="?"
+ layout="topleft"
+ left_delta="150"
+ name="WLSunlightColorHelp"
+ top_delta="-2"
+ width="18" />
+ <text
+ type="string"
+ length="1"
+ follows="left|top|right"
+ halign="center"
+ height="16"
+ layout="topleft"
+ left="10"
+ name="BHText"
+ top="21"
+ width="10">
+ R
+ </text>
+ <text
+ type="string"
+ length="1"
+ follows="left|top|right"
+ halign="center"
+ height="16"
+ layout="topleft"
+ left_delta="0"
+ name="BHText2"
+ top_delta="11"
+ width="10">
+ G
+ </text>
+ <text
+ type="string"
+ length="1"
+ follows="left|top|right"
+ halign="center"
+ height="16"
+ layout="topleft"
+ left_delta="0"
+ name="BHText3"
+ top_delta="11"
+ width="10">
+ B
+ </text>
+ <text
+ type="string"
+ length="1"
+ follows="left|top|right"
+ halign="center"
+ height="16"
+ layout="topleft"
+ left_delta="0"
+ name="BHText4"
+ top_delta="11"
+ width="10">
+ I
+ </text>
+ <slider
+ control_name="WLSunlightR"
+ decimal_digits="2"
+ follows="left"
+ height="10"
+ increment="0.01"
+ initial_value="0.7"
+ layout="topleft"
+ left="24"
+ name="WLSunlightR"
+ top="40"
+ width="200" />
+ <slider
+ control_name="WLSunlightG"
+ decimal_digits="2"
+ follows="left"
+ height="10"
+ increment="0.01"
+ initial_value="0.7"
+ layout="topleft"
+ left_delta="0"
+ name="WLSunlightG"
+ top_pad="1"
+ width="200" />
+ <slider
+ control_name="WLSunlightB"
+ decimal_digits="2"
+ follows="left"
+ height="10"
+ increment="0.01"
+ initial_value="0.7"
+ layout="topleft"
+ left_delta="0"
+ name="WLSunlightB"
+ top_pad="1"
+ width="200" />
+ <slider
+ control_name="WLSunlightI"
+ decimal_digits="2"
+ follows="left"
+ height="10"
+ increment="0.01"
+ initial_value="1.0"
+ layout="topleft"
+ left_delta="0"
+ name="WLSunlightI"
+ top_pad="1"
+ width="200" />
+ <text
+ type="string"
+ length="1"
+ follows="left|top|right"
+ font="SansSerif"
+ height="16"
+ layout="topleft"
+ left_delta="-14"
+ name="TODText"
+ top_delta="-2"
+ width="355">
+ Sun/Moon Position
+ </text>
+ <button
+ follows="left|top"
+ font="SansSerifSmall"
+ height="18"
+ label="?"
+ layout="topleft"
+ left_delta="150"
+ name="WLTimeOfDayHelp"
+ top_delta="-2"
+ width="18" />
+ <icon
+ height="20"
+ image_name="icon_diurnal.tga"
+ layout="topleft"
+ left="30"
+ name="SkyDayCycle"
+ top="97"
+ width="148" />
+ <slider
+ control_name="WLSunAngle"
+ follows="left"
+ height="10"
+ increment="0.001"
+ initial_value="0.7"
+ layout="topleft"
+ left="24"
+ name="WLSunAngle"
+ top="137"
+ width="204" />
+ <text
+ type="string"
+ length="1"
+ follows="left|top|right"
+ font="SansSerif"
+ height="16"
+ layout="topleft"
+ left="245"
+ name="WLAmbientText"
+ top="4"
+ width="355">
+ Ambient
+ </text>
+ <button
+ follows="left|top"
+ font="SansSerifSmall"
+ height="18"
+ label="?"
+ layout="topleft"
+ left_delta="150"
+ name="WLAmbientHelp"
+ top_delta="-2"
+ width="18" />
+ <text
+ type="string"
+ length="1"
+ follows="left|top|right"
+ halign="center"
+ height="16"
+ layout="topleft"
+ left="245"
+ name="BHText5"
+ top="21"
+ width="10">
+ R
+ </text>
+ <text
+ type="string"
+ length="1"
+ follows="left|top|right"
+ halign="center"
+ height="16"
+ layout="topleft"
+ left_delta="0"
+ name="BHText6"
+ top_delta="11"
+ width="10">
+ G
+ </text>
+ <text
+ type="string"
+ length="1"
+ follows="left|top|right"
+ halign="center"
+ height="16"
+ layout="topleft"
+ left_delta="0"
+ name="BHText7"
+ top_delta="11"
+ width="10">
+ B
+ </text>
+ <text
+ type="string"
+ length="1"
+ follows="left|top|right"
+ halign="center"
+ height="16"
+ layout="topleft"
+ left_delta="0"
+ name="BHText8"
+ top_delta="11"
+ width="10">
+ I
+ </text>
+ <slider
+ control_name="WLAmbientR"
+ decimal_digits="2"
+ follows="left"
+ height="10"
+ increment="0.01"
+ initial_value="0.7"
+ layout="topleft"
+ left="259"
+ name="WLAmbientR"
+ top="40"
+ width="200" />
+ <slider
+ control_name="WLAmbientG"
+ decimal_digits="2"
+ follows="left"
+ height="10"
+ increment="0.01"
+ initial_value="0.7"
+ layout="topleft"
+ left_delta="0"
+ name="WLAmbientG"
+ top_pad="1"
+ width="200" />
+ <slider
+ control_name="WLAmbientB"
+ decimal_digits="2"
+ follows="left"
+ height="10"
+ increment="0.01"
+ initial_value="0.7"
+ layout="topleft"
+ left_delta="0"
+ name="WLAmbientB"
+ top_pad="1"
+ width="200" />
+ <slider
+ control_name="WLAmbientI"
+ decimal_digits="2"
+ follows="left"
+ height="10"
+ increment="0.01"
+ initial_value="1"
+ layout="topleft"
+ left_delta="0"
+ name="WLAmbientI"
+ top_pad="1"
+ width="200" />
+ <text
+ type="string"
+ length="1"
+ follows="left|top|right"
+ font="SansSerif"
+ height="16"
+ layout="topleft"
+ left_delta="-14"
+ name="WLEastAngleText"
+ top_delta="-2"
+ width="355">
+ East Angle
+ </text>
+ <button
+ follows="left|top"
+ font="SansSerifSmall"
+ height="18"
+ label="?"
+ layout="topleft"
+ left_delta="150"
+ name="WLEastAngleHelp"
+ top_delta="-2"
+ width="18" />
+ <slider
+ control_name="WLEastAngle"
+ decimal_digits="2"
+ follows="left"
+ height="10"
+ increment="0.01"
+ initial_value="0.0"
+ layout="topleft"
+ left="259"
+ name="WLEastAngle"
+ top="107"
+ width="200" />
+ <text
+ type="string"
+ length="1"
+ follows="left|top|right"
+ font="SansSerif"
+ height="16"
+ layout="topleft"
+ left="480"
+ name="SunGlowText"
+ top="4"
+ width="355">
+ Sun Glow
+ </text>
+ <button
+ follows="left|top"
+ font="SansSerifSmall"
+ height="18"
+ label="?"
+ layout="topleft"
+ left_delta="150"
+ name="WLSunGlowHelp"
+ top_delta="-2"
+ width="18" />
+ <slider
+ control_name="WLGlowB"
+ decimal_digits="2"
+ follows="left"
+ height="10"
+ increment="0.01"
+ initial_value="0.1"
+ label="Focus "
+ layout="topleft"
+ left="494"
+ max_val="0.5"
+ name="WLGlowB"
+ top="40"
+ width="200" />
+ <slider
+ control_name="WLGlowR"
+ decimal_digits="2"
+ follows="left"
+ height="10"
+ increment="0.01"
+ initial_value="0.25"
+ label="Size "
+ layout="topleft"
+ left_delta="0"
+ max_val="1.99"
+ min_val="1"
+ name="WLGlowR"
+ top_pad="1"
+ width="200" />
+ <text
+ type="string"
+ length="1"
+ follows="left|top|right"
+ font="SansSerif"
+ height="16"
+ layout="topleft"
+ left_delta="-14"
+ name="SceneGammaText"
+ top_delta="0"
+ width="200">
+ Scene Gamma
+ </text>
+ <button
+ follows="left|top"
+ font="SansSerifSmall"
+ height="18"
+ label="?"
+ layout="topleft"
+ left_delta="150"
+ name="WLSceneGammaHelp"
+ top_delta="-2"
+ width="18" />
+ <slider
+ control_name="WLGamma"
+ decimal_digits="2"
+ follows="bottom"
+ height="10"
+ increment="0.01"
+ initial_value="2.0"
+ layout="topleft"
+ left="494"
+ max_val="10"
+ name="WLGamma"
+ top="87"
+ width="207" />
+ <text
+ type="string"
+ length="1"
+ follows="left|top|right"
+ font="SansSerif"
+ height="16"
+ layout="topleft"
+ left_delta="-14"
+ name="WLStarText"
+ top_delta="-1"
+ width="355">
+ Star Brightness
+ </text>
+ <button
+ follows="left|top"
+ font="SansSerifSmall"
+ height="18"
+ label="?"
+ layout="topleft"
+ left_delta="150"
+ name="WLStarBrightnessHelp"
+ top_delta="-2"
+ width="18" />
+ <slider
+ control_name="WLStarAlpha"
+ decimal_digits="2"
+ follows="bottom"
+ height="10"
+ increment="0.01"
+ initial_value="0"
+ layout="topleft"
+ left="494"
+ max_val="2"
+ name="WLStarAlpha"
+ top="122"
+ width="200" />
+ </panel>
+ <panel
+ border="true"
+ follows="left|top|right|bottom"
+ height="160"
+ label="Clouds"
+ layout="topleft"
+ left_delta="0"
+ mouse_opaque="false"
+ name="Clouds"
+ top_delta="4"
+ width="698">
+ <text
+ type="string"
+ length="1"
+ follows="left|top|right"
+ font="SansSerif"
+ height="16"
+ layout="topleft"
+ left="10"
+ name="WLCloudColorText"
+ top="4"
+ width="355">
+ Cloud Color
+ </text>
+ <button
+ follows="left|top"
+ font="SansSerifSmall"
+ height="18"
+ label="?"
+ layout="topleft"
+ left_delta="150"
+ name="WLCloudColorHelp"
+ top_delta="-2"
+ width="18" />
+ <text
+ type="string"
+ length="1"
+ follows="left|top|right"
+ halign="center"
+ height="16"
+ layout="topleft"
+ left="10"
+ name="BHText"
+ top="21"
+ width="10">
+ R
+ </text>
+ <text
+ type="string"
+ length="1"
+ follows="left|top|right"
+ halign="center"
+ height="16"
+ layout="topleft"
+ left_delta="0"
+ name="BHText2"
+ top_delta="11"
+ width="10">
+ G
+ </text>
+ <text
+ type="string"
+ length="1"
+ follows="left|top|right"
+ halign="center"
+ height="16"
+ layout="topleft"
+ left_delta="0"
+ name="BHText3"
+ top_delta="11"
+ width="10">
+ B
+ </text>
+ <text
+ type="string"
+ length="1"
+ follows="left|top|right"
+ halign="center"
+ height="16"
+ layout="topleft"
+ left_delta="0"
+ name="BHText4"
+ top_delta="11"
+ width="10">
+ I
+ </text>
+ <slider
+ control_name="WLCloudColorR"
+ decimal_digits="2"
+ follows="left"
+ height="10"
+ increment="0.01"
+ initial_value="0.7"
+ layout="topleft"
+ left="24"
+ name="WLCloudColorR"
+ top="40"
+ width="200" />
+ <slider
+ control_name="WLCloudColorG"
+ decimal_digits="2"
+ follows="left"
+ height="10"
+ increment="0.01"
+ initial_value="0.7"
+ layout="topleft"
+ left_delta="0"
+ name="WLCloudColorG"
+ top_pad="1"
+ width="200" />
+ <slider
+ control_name="WLCloudColorB"
+ decimal_digits="2"
+ follows="left"
+ height="10"
+ increment="0.01"
+ initial_value="0.7"
+ layout="topleft"
+ left_delta="0"
+ name="WLCloudColorB"
+ top_pad="1"
+ width="200" />
+ <slider
+ control_name="WLCloudColorI"
+ decimal_digits="2"
+ follows="left"
+ height="10"
+ increment="0.01"
+ initial_value="1.0"
+ layout="topleft"
+ left_delta="0"
+ name="WLCloudColorI"
+ top_pad="1"
+ width="200" />
+ <text
+ type="string"
+ length="1"
+ follows="left|top|right"
+ font="SansSerif"
+ height="16"
+ layout="topleft"
+ left_delta="-14"
+ name="WLCloudColorText2"
+ top_delta="-2"
+ width="355">
+ Cloud XY/Density
+ </text>
+ <button
+ follows="left|top"
+ font="SansSerifSmall"
+ height="18"
+ label="?"
+ layout="topleft"
+ left_delta="150"
+ name="WLCloudDensityHelp"
+ top_delta="-2"
+ width="18" />
+ <text
+ type="string"
+ length="1"
+ follows="left|top|right"
+ halign="center"
+ height="16"
+ layout="topleft"
+ left="10"
+ name="BHText5"
+ top="87"
+ width="10">
+ X
+ </text>
+ <text
+ type="string"
+ length="1"
+ follows="left|top|right"
+ halign="center"
+ height="16"
+ layout="topleft"
+ left_delta="0"
+ name="BHText6"
+ top_delta="11"
+ width="10">
+ Y
+ </text>
+ <text
+ type="string"
+ length="1"
+ follows="left|top|right"
+ halign="center"
+ height="16"
+ layout="topleft"
+ left_delta="0"
+ name="BHText7"
+ top_delta="11"
+ width="10">
+ D
+ </text>
+ <slider
+ control_name="WLCloudX"
+ decimal_digits="2"
+ follows="left"
+ height="10"
+ increment="0.01"
+ initial_value="0.5"
+ layout="topleft"
+ left_pad="4"
+ name="WLCloudX"
+ top_delta="-2"
+ width="200" />
+ <slider
+ control_name="WLCloudY"
+ decimal_digits="2"
+ follows="left"
+ height="10"
+ increment="0.01"
+ initial_value="0.5"
+ layout="topleft"
+ left_delta="0"
+ name="WLCloudY"
+ top_pad="1"
+ width="200" />
+ <slider
+ control_name="WLCloudDensity"
+ decimal_digits="2"
+ follows="left"
+ height="10"
+ increment="0.01"
+ initial_value="1.0"
+ layout="topleft"
+ left_delta="0"
+ name="WLCloudDensity"
+ top_pad="1"
+ width="200" />
+ <text
+ type="string"
+ length="1"
+ follows="left|top|right"
+ font="SansSerif"
+ height="16"
+ layout="topleft"
+ left="245"
+ name="WLCloudCoverageText"
+ top="4"
+ width="355">
+ Cloud Coverage
+ </text>
+ <button
+ follows="left|top"
+ font="SansSerifSmall"
+ height="18"
+ label="?"
+ layout="topleft"
+ left_delta="150"
+ name="WLCloudCoverageHelp"
+ top_delta="-2"
+ width="18" />
+ <slider
+ control_name="WLCloudCoverage"
+ decimal_digits="2"
+ follows="left"
+ height="10"
+ increment="0.01"
+ initial_value="0.5"
+ layout="topleft"
+ left="259"
+ name="WLCloudCoverage"
+ top="40"
+ width="200" />
+ <text
+ type="string"
+ length="1"
+ follows="left|top|right"
+ font="SansSerif"
+ height="16"
+ layout="topleft"
+ left_delta="-14"
+ name="WLCloudScaleText"
+ top_delta="-1"
+ width="355">
+ Cloud Scale
+ </text>
+ <button
+ follows="left|top"
+ font="SansSerifSmall"
+ height="18"
+ label="?"
+ layout="topleft"
+ left_delta="150"
+ name="WLCloudScaleHelp"
+ top_delta="-2"
+ width="18" />
+ <slider
+ control_name="WLCloudScale"
+ decimal_digits="2"
+ follows="left"
+ height="10"
+ increment="0.01"
+ initial_value="1.0"
+ layout="topleft"
+ left="259"
+ min_val="0.01"
+ name="WLCloudScale"
+ top="75"
+ width="200" />
+ <text
+ type="string"
+ length="1"
+ follows="left|top|right"
+ font="SansSerif"
+ height="16"
+ layout="topleft"
+ left_delta="-14"
+ name="WLCloudDetailText"
+ top_delta="-4"
+ width="355">
+ Cloud Detail (XY/Density)
+ </text>
+ <button
+ follows="left|top"
+ font="SansSerifSmall"
+ height="18"
+ label="?"
+ layout="topleft"
+ left_delta="150"
+ name="WLCloudDetailHelp"
+ top_delta="-2"
+ width="18" />
+ <text
+ type="string"
+ length="1"
+ follows="left|top|right"
+ halign="center"
+ height="16"
+ layout="topleft"
+ left="245"
+ name="BHText8"
+ top="87"
+ width="10">
+ X
+ </text>
+ <text
+ type="string"
+ length="1"
+ follows="left|top|right"
+ halign="center"
+ height="16"
+ layout="topleft"
+ left_delta="0"
+ name="BHText9"
+ top_delta="11"
+ width="10">
+ Y
+ </text>
+ <text
+ type="string"
+ length="1"
+ follows="left|top|right"
+ halign="center"
+ height="16"
+ layout="topleft"
+ left_delta="0"
+ name="BHText10"
+ top_delta="11"
+ width="10">
+ D
+ </text>
+ <slider
+ control_name="WLCloudDetailX"
+ decimal_digits="2"
+ follows="left"
+ height="10"
+ increment="0.01"
+ initial_value="0.5"
+ layout="topleft"
+ left_pad="4"
+ name="WLCloudDetailX"
+ top_delta="-2"
+ width="200" />
+ <slider
+ control_name="WLCloudDetailY"
+ decimal_digits="2"
+ follows="left"
+ height="10"
+ increment="0.01"
+ initial_value="0.5"
+ layout="topleft"
+ left_delta="0"
+ name="WLCloudDetailY"
+ top_pad="1"
+ width="200" />
+ <slider
+ control_name="WLCloudDetailDensity"
+ decimal_digits="2"
+ follows="left"
+ height="10"
+ increment="0.01"
+ initial_value="1.0"
+ layout="topleft"
+ left_delta="0"
+ name="WLCloudDetailDensity"
+ top_pad="1"
+ width="200" />
+ <text
+ type="string"
+ length="1"
+ follows="left|top|right"
+ font="SansSerif"
+ height="16"
+ layout="topleft"
+ left="480"
+ name="WLCloudScrollXText"
+ top="4"
+ width="355">
+ Cloud Scroll X
+ </text>
+ <button
+ follows="left|top"
+ font="SansSerifSmall"
+ height="18"
+ label="?"
+ layout="topleft"
+ left_delta="125"
+ name="WLCloudScrollXHelp"
+ top_delta="-2"
+ width="18" />
+ <check_box
+ control_name="WLCloudLockX"
+ follows="left"
+ height="16"
+ label="Lock"
+ layout="topleft"
+ left="625"
+ name="WLCloudLockX"
+ width="200" />
+ <slider
+ control_name="WLCloudScrollX"
+ decimal_digits="2"
+ follows="left"
+ height="10"
+ increment="0.01"
+ initial_value="0.5"
+ layout="topleft"
+ left="494"
+ max_val="10"
+ min_val="-10"
+ name="WLCloudScrollX"
+ top="45"
+ width="200" />
+ <text
+ type="string"
+ length="1"
+ follows="left|top|right"
+ font="SansSerif"
+ height="16"
+ layout="topleft"
+ left_delta="-14"
+ name="WLCloudScrollYText"
+ top_delta="-1"
+ width="355">
+ Cloud Scroll Y
+ </text>
+ <button
+ follows="left|top"
+ font="SansSerifSmall"
+ height="18"
+ label="?"
+ layout="topleft"
+ left_delta="125"
+ name="WLCloudScrollYHelp"
+ top_delta="-2"
+ width="18" />
+ <check_box
+ control_name="WLCloudLockY"
+ follows="left"
+ height="16"
+ label="Lock"
+ layout="topleft"
+ left="625"
+ name="WLCloudLockY"
+ width="200" />
+ <slider
+ control_name="WLCloudScrollY"
+ decimal_digits="2"
+ follows="left"
+ height="10"
+ increment="0.01"
+ initial_value="0.5"
+ layout="topleft"
+ left="494"
+ max_val="10"
+ min_val="-10"
+ name="WLCloudScrollY"
+ top="85"
+ width="200" />
+ <check_box
+ control_name="DrawClassicClouds"
+ follows="left"
+ height="16"
+ label="Draw Classic Clouds"
+ layout="topleft"
+ left="480"
+ name="DrawClassicClouds"
+ top="104"
+ width="200" />
+ <button
+ follows="left|top"
+ font="SansSerifSmall"
+ height="18"
+ label="?"
+ layout="topleft"
+ left="608"
+ name="WLClassicCloudsHelp"
+ top="84"
+ width="18" />
+ </panel>
+ </tab_container>
+</floater>
diff --git a/indra/newview/skins/default/xui/en/floater_world_map.xml b/indra/newview/skins/default/xui/en/floater_world_map.xml
new file mode 100644
index 0000000000..e46588dd71
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/floater_world_map.xml
@@ -0,0 +1,576 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<floater
+ can_resize="true"
+ center_horiz="true"
+ center_vert="true"
+ height="600"
+ layout="topleft"
+ min_height="520"
+ min_width="520"
+ name="worldmap"
+ save_rect="true"
+ save_visibility="true"
+ single_instance="true"
+ title="World Map"
+ width="800">
+ <tab_container
+ follows="left|top|right|bottom"
+ height="565"
+ layout="topleft"
+ left="15"
+ name="maptab"
+ tab_position="top"
+ top="25"
+ width="542">
+ <panel
+ filename="panel_world_map.xml"
+ follows="left|top|right|bottom"
+ height="550"
+ label="Objects"
+ layout="topleft"
+ left="1"
+ name="objects_mapview"
+ top="19"
+ width="540" />
+ <panel
+ filename="panel_world_map.xml"
+ follows="left|top|right|bottom"
+ height="550"
+ label="Terrain"
+ layout="topleft"
+ left_delta="0"
+ name="terrain_mapview"
+ top_delta="3"
+ width="540" />
+ </tab_container>
+ <icon
+ follows="top|right"
+ height="16"
+ image_name="map_avatar_16.tga"
+ layout="topleft"
+ left="-230"
+ mouse_opaque="true"
+ name="self"
+ top="34"
+ width="16" />
+ <text
+ type="string"
+ length="1"
+ follows="top|right"
+ height="16"
+ layout="topleft"
+ left_pad="4"
+ name="you_label"
+ top_delta="0"
+ width="145">
+ You
+ </text>
+ <icon
+ follows="top|right"
+ height="16"
+ image_name="map_home.tga"
+ layout="topleft"
+ left_delta="50"
+ mouse_opaque="true"
+ name="home"
+ top_delta="0"
+ width="16" />
+ <text
+ type="string"
+ length="1"
+ follows="top|right"
+ height="16"
+ layout="topleft"
+ left_pad="4"
+ name="home_label"
+ top_delta="0"
+ width="145">
+ Home
+ </text>
+ <icon
+ color="0.5 0.25 1 1"
+ follows="top|right"
+ height="16"
+ image_name="legend.tga"
+ layout="topleft"
+ left="-230"
+ mouse_opaque="true"
+ name="square2"
+ top="54"
+ width="16" />
+ <text
+ type="string"
+ length="1"
+ follows="top|right"
+ height="16"
+ layout="topleft"
+ left_pad="4"
+ name="auction_label"
+ top_delta="0"
+ width="145">
+ Auction
+ </text>
+ <icon
+ color="1 1 0.25 1"
+ follows="top|right"
+ height="16"
+ image_name="legend.tga"
+ layout="topleft"
+ left_delta="50"
+ mouse_opaque="true"
+ name="square"
+ top_delta="0"
+ width="16" />
+ <text
+ type="string"
+ length="1"
+ follows="top|right"
+ height="16"
+ layout="topleft"
+ left_pad="4"
+ name="land_for_sale_label"
+ top_delta="0"
+ width="145">
+ Land For Sale
+ </text>
+ <button
+ follows="top|right"
+ font="SansSerifSmall"
+ height="16"
+ label="Go Home"
+ label_selected="Go Home"
+ layout="topleft"
+ left="-90"
+ name="Go Home"
+ tool_tip="Teleport to your home"
+ top="34"
+ width="88" >
+ <button.commit_callback
+ function="WMap.GoHome" />
+ </button>
+ <icon
+ color="0 1 0 1"
+ follows="top|right"
+ height="8"
+ image_name="map_avatar_8.tga"
+ layout="topleft"
+ left="-226"
+ mouse_opaque="true"
+ name="person"
+ top="84"
+ width="8" />
+ <check_box
+ control_name="MapShowPeople"
+ follows="top|right"
+ height="16"
+ label="Resident"
+ layout="topleft"
+ left_pad="8"
+ name="people_chk"
+ top_delta="-4"
+ width="110" />
+ <icon
+ follows="top|right"
+ height="16"
+ image_name="map_infohub.tga"
+ layout="topleft"
+ left="-230"
+ mouse_opaque="true"
+ name="infohub"
+ top="100"
+ width="16" />
+ <check_box
+ control_name="MapShowInfohubs"
+ follows="top|right"
+ height="16"
+ label="Infohub"
+ layout="topleft"
+ left_pad="4"
+ name="infohub_chk"
+ top_delta="0"
+ width="110" />
+ <icon
+ follows="top|right"
+ height="16"
+ image_name="map_telehub.tga"
+ layout="topleft"
+ left="-230"
+ mouse_opaque="true"
+ name="telehub"
+ top="120"
+ width="16" />
+ <check_box
+ control_name="MapShowTelehubs"
+ follows="top|right"
+ height="16"
+ label="Telehub"
+ layout="topleft"
+ left_pad="4"
+ name="telehubchk"
+ top_delta="0"
+ width="110" />
+ <icon
+ follows="top|right"
+ height="16"
+ image_name="icon_for_sale.tga"
+ layout="topleft"
+ left="-230"
+ mouse_opaque="true"
+ name="landforsale"
+ top="140"
+ width="16" />
+ <check_box
+ control_name="MapShowLandForSale"
+ follows="top|right"
+ height="16"
+ label="Land for Sale"
+ layout="topleft"
+ left_pad="4"
+ name="land_for_sale_chk"
+ top_delta="0"
+ width="110" />
+ <text
+ type="string"
+ length="1"
+ follows="top|right"
+ height="16"
+ layout="topleft"
+ left="-104"
+ name="events_label"
+ top="80"
+ width="145">
+ Events:
+ </text>
+ <icon
+ follows="top|right"
+ height="16"
+ image_name="map_event.tga"
+ layout="topleft"
+ left="-92"
+ mouse_opaque="true"
+ name="event"
+ top="100"
+ width="16" />
+ <check_box
+ control_name="MapShowEvents"
+ follows="top|right"
+ height="16"
+ label="PG"
+ layout="topleft"
+ left_pad="4"
+ name="event_chk"
+ top_delta="0"
+ width="55" />
+ <icon
+ follows="top|right"
+ height="16"
+ image_name="map_event_mature.tga"
+ layout="topleft"
+ left="-92"
+ mouse_opaque="true"
+ name="events_mature_icon"
+ top="120"
+ width="16" />
+ <check_box
+ control_name="ShowMatureEvents"
+ follows="top|right"
+ height="16"
+ initial_value="true"
+ label="Mature"
+ layout="topleft"
+ left_pad="4"
+ name="event_mature_chk"
+ top_delta="0"
+ width="55" />
+ <icon
+ follows="top|right"
+ height="16"
+ image_name="map_event_adult.tga"
+ layout="topleft"
+ left="-92"
+ mouse_opaque="true"
+ name="events_adult_icon"
+ top="140"
+ width="16" />
+ <check_box
+ control_name="ShowAdultEvents"
+ follows="top|right"
+ height="16"
+ label="Adult"
+ layout="topleft"
+ left_pad="4"
+ name="event_adult_chk"
+ top_delta="0"
+ width="55" />
+ <icon
+ color="0.5 0 0 1"
+ follows="top|right"
+ height="16"
+ image_name="map_track_16.tga"
+ layout="topleft"
+ left="-230"
+ mouse_opaque="true"
+ name="avatar_icon"
+ top="164"
+ width="16" />
+ <combo_box
+ allow_text_entry="true"
+ follows="top|right"
+ height="20"
+ label="Online Friends"
+ layout="topleft"
+ left_pad="4"
+ max_chars="60"
+ name="friend combo"
+ tool_tip="Friend to Show on Map"
+ top_delta="-4"
+ width="202">
+ <combo_box.item
+ label="Online Friends"
+ name="item1"
+ value="None" />
+ <combo_box.commit_callback
+ function="WMap.AvatarCombo"/>
+ </combo_box>
+ <icon
+ color="0.5 0 0 1"
+ follows="top|right"
+ height="16"
+ image_name="map_track_16.tga"
+ layout="topleft"
+ left="-230"
+ mouse_opaque="true"
+ name="landmark_icon"
+ top="189"
+ width="16" />
+ <combo_box
+ allow_text_entry="true"
+ follows="top|right"
+ height="20"
+ label="Landmarks"
+ layout="topleft"
+ left_pad="4"
+ max_chars="64"
+ name="landmark combo"
+ tool_tip="Landmark to Show on Map"
+ top_delta="-4"
+ width="202">
+ <combo_box.item
+ label="Landmarks"
+ name="item1"
+ value="None" />
+ </combo_box>
+ <icon
+ color="0.5 0 0 1"
+ follows="top|right"
+ height="16"
+ image_name="map_track_16.tga"
+ layout="topleft"
+ left="-230"
+ mouse_opaque="true"
+ name="location_icon"
+ top="214"
+ width="16" />
+ <line_editor
+ follows="top|right"
+ height="20"
+ label="Search by Region Name"
+ layout="topleft"
+ left_pad="4"
+ name="location"
+ select_on_focus="true"
+ tool_tip="Type the name of a region"
+ top_delta="-4"
+ width="140" />
+ <button
+ follows="top|right"
+ height="20"
+ label="Search"
+ layout="topleft"
+ left_pad="5"
+ name="DoSearch"
+ tool_tip="Search for region"
+ top_delta="0"
+ width="60">
+ <button.commit_callback
+ function="WMap.Location" />
+ </button>
+ <text
+ type="string"
+ length="1"
+ follows="top|right"
+ font="SansSerif"
+ height="16"
+ layout="topleft"
+ left="-230"
+ name="search_label"
+ top="234"
+ width="222">
+ Search Results:
+ </text>
+ <scroll_list
+ draw_stripes="false"
+ follows="top|right|bottom"
+ height="200"
+ layout="topleft"
+ left_delta="0"
+ name="search_results"
+ top_pad="10"
+ width="222">
+ <scroll_list.columns
+ label=""
+ name="icon"
+ width="16" />
+ <scroll_list.columns
+ label=""
+ name="sim_name"
+ width="206" />
+ <scroll_list.commit_callback
+ function="WMap.SearchResult" />
+ </scroll_list>
+ <text
+ type="string"
+ length="1"
+ follows="bottom|right"
+ font="SansSerif"
+ height="16"
+ layout="topleft"
+ left_delta="0"
+ name="location_label"
+ top_pad="4"
+ width="98">
+ Location:
+ </text>
+ <spinner
+ decimal_digits="0"
+ follows="bottom|right"
+ height="16"
+ increment="1"
+ initial_value="128"
+ layout="topleft"
+ left_delta="70"
+ max_val="255"
+ name="spin x"
+ tool_tip="X coordinate of location to show on map"
+ top_delta="0"
+ width="48">
+ <spinner.commit_callback
+ function="WMap.CommitLocation" />
+ </spinner>
+ <spinner
+ decimal_digits="0"
+ follows="bottom|right"
+ height="16"
+ increment="1"
+ initial_value="128"
+ layout="topleft"
+ left_pad="2"
+ max_val="255"
+ name="spin y"
+ tool_tip="Y coordinate of location to show on map"
+ top_delta="0"
+ width="48" >
+ <spinner.commit_callback
+ function="WMap.CommitLocation" />
+ </spinner>
+ <spinner
+ decimal_digits="0"
+ follows="bottom|right"
+ height="16"
+ increment="1"
+ initial_value="0"
+ layout="topleft"
+ left_pad="2"
+ max_val="4096"
+ name="spin z"
+ tool_tip="Z coordinate of location to show on map"
+ top_delta="0"
+ width="48">
+ <spinner.commit_callback
+ function="WMap.CommitLocation" />
+ </spinner>
+ <button
+ follows="right|bottom"
+ height="20"
+ label="Teleport"
+ label_selected="Teleport"
+ layout="topleft"
+ left="-230"
+ name="Teleport"
+ tool_tip="Teleport to selected location"
+ top="494"
+ width="90">
+ <button.commit_callback
+ function="WMap.Teleport" />
+ </button>
+ <button
+ follows="right|bottom"
+ height="20"
+ label="Show Destination"
+ label_selected="Show Destination"
+ layout="topleft"
+ left_pad="10"
+ name="Show Destination"
+ tool_tip="Center map on selected location"
+ top_delta="0"
+ width="125">
+ <button.commit_callback
+ function="WMap.ShowTarget" />
+ </button>
+ <button
+ follows="right|bottom"
+ height="20"
+ label="Clear"
+ label_selected="Clear"
+ layout="topleft"
+ left="-230"
+ name="Clear"
+ tool_tip="Stop tracking"
+ top="518"
+ width="90">
+ <button.commit_callback
+ function="WMap.Clear" />
+ </button>
+ <button
+ follows="right|bottom"
+ height="20"
+ label="Show My Location"
+ label_selected="Show My Location"
+ layout="topleft"
+ left_pad="10"
+ name="Show My Location"
+ tool_tip="Center map on your avatar&apos;s location"
+ top_delta="0"
+ width="125" >
+ <button.commit_callback
+ function="WMap.ShowAgent" />
+ </button>
+ <button
+ enabled="false"
+ follows="bottom|right"
+ height="20"
+ label="Copy SLurl to clipboard"
+ layout="topleft"
+ left="-230"
+ name="copy_slurl"
+ tool_tip="Copies current location as SLurl to be used on the web."
+ top="542"
+ width="222">
+ <button.commit_callback
+ function="WMap.CopySLURL" />
+ </button>
+ <slider
+ follows="right|bottom"
+ height="16"
+ increment="0.2"
+ initial_value="48.5029"
+ label="Zoom"
+ layout="topleft"
+ left_delta="0"
+ max_val="0"
+ min_val="-8"
+ name="zoom slider"
+ show_text="false"
+ top_pad="8"
+ width="222" />
+</floater>
diff --git a/indra/newview/skins/default/xui/en/fonts.xml b/indra/newview/skins/default/xui/en/fonts.xml
new file mode 100644
index 0000000000..ced8ba83f7
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/fonts.xml
@@ -0,0 +1,120 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<fonts>
+
+ <font name="default" comment="default font files (global fallbacks)">
+ <file>DejaVuSansCondensed.ttf</file>
+ <os name="Windows">
+ <file>MSGOTHIC.TTC</file>
+ <file>gulim.ttc</file>
+ <file>simhei.ttf</file>
+ <file>ArialUni.ttf</file>
+ </os>
+ <os name="Mac">
+ <file>ヒラギノ角ゴ Pro W3.otf</file>
+ <file>ヒラギノ角ゴ ProN W3.otf</file>
+ <file>AppleGothic.dfont</file>
+ <file>AppleGothic.ttf</file>
+ <file>åŽæ–‡ç»†é»‘.ttf</file>
+ </os>
+ </font>
+
+ <font name="SansSerif" comment="Name of san-serif font (Truetype file name)">
+ <file>Helvetica.dfont</file>
+ <os name="Windows">
+ <file>arial.ttf</file>
+ </os>
+ <os name="Mac">
+ <file>Helvetica.dfont</file>
+ </os>
+ </font>
+
+ <font name="SansSerifBold"
+ comment="Name of bold sans-serif font"
+ font_style="Bold">
+ <file>Helvetica.dfont</file>
+ <os name="Windows">
+ <file>arialbd.ttf</file>
+ </os>
+ <os name="Mac">
+ <file>Helvetica.dfont</file>
+ </os>
+ </font>
+
+ <font name="Monospace"
+ comment="Name of monospace font">
+ <file>DejaVuSansMono.ttf</file>
+ </font>
+
+ <font name="DejaVu"
+ comment="Name of DejaVu font">
+ <file>DejaVuSans.ttf</file>
+ </font>
+
+ <font name="DejaVu"
+ comment="Name of DejaVu font (bold)"
+ font_style="BOLD">
+ <file>DejaVuSansBold.ttf</file>
+ </font>
+
+ <font name="DejaVu"
+ comment="Name of DejaVu font (italic)"
+ font_style="ITALIC">
+ <file>DejaVuSansOblique.ttf</file>
+ </font>
+
+ <font name="DejaVu"
+ comment="Name of DejaVu font (bold italic)"
+ font_style="BOLD|ITALIC">
+ <file>DejaVuSansBoldOblique.ttf</file>
+ </font>
+
+ <font name="Helvetica"
+ comment="Name of Helvetica font">
+ <file>arial.ttf</file>
+ </font>
+
+ <font name="Helvetica"
+ comment="Name of Helvetica font (bold)"
+ font_style="BOLD">
+ <file>arialbd.ttf</file>
+ </font>
+
+ <font name="Helvetica"
+ comment="Name of Helvetica font (italic)"
+ font_style="ITALIC">
+ <file>ariali.ttf</file>
+ </font>
+
+ <font name="Helvetica"
+ comment="Name of Helvetica font (bold italic)"
+ font_style="BOLD|ITALIC">
+ <file>arialbi.ttf</file>
+ </font>
+
+ <font name="OverrideTest"
+ comment="Name of font to test overriding">
+ <file>times.ttf</file>
+ </font>
+
+ <font_size name="Monospace"
+ comment="Size for monospaced font (points, or 1/72 of an inch)"
+ size="9.0"
+ />
+ <font_size name="Huge"
+ comment="Size of huge font (points, or 1/72 of an inch)"
+ size="16.0"
+ />
+ <font_size name="Large"
+ comment="Size of large font (points, or 1/72 of an inch)"
+ size="12.0"
+ />
+ <font_size name="Medium"
+ comment="Size of medium font (points, or 1/72 of an inch)"
+ size="10.0"
+ />
+ <font_size name="Small"
+ comment="Size of small font (points, or 1/72 of an inch)"
+ size="9"
+ />
+</fonts>
+
diff --git a/indra/newview/skins/default/xui/en/inspect_avatar.xml b/indra/newview/skins/default/xui/en/inspect_avatar.xml
new file mode 100644
index 0000000000..cee789d435
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/inspect_avatar.xml
@@ -0,0 +1,84 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<!-- All our XML is utf-8 encoded. -->
+
+<!-- No title to avoid window chrome -->
+<floater
+ background_opaque="false"
+ background_visible="true"
+ bevel_style="in"
+ bg_alpha_color="black"
+ can_minimize="false"
+ name="inspect_avatar"
+ title=""
+ visible="true"
+ width="300"
+ height="200"
+ left="0"
+ top="200"
+ >
+ <text
+ top="180" left="10" width="220" height="70" follows="left|top|right|bottom"
+ use_ellipses="true" word_wrap="true"
+ font="SansSerifHugeBold" text_color="white"
+ mouse_opaque="true" name="user_name" >
+ Codex Linden
+ </text>
+ <text
+ top="155" left="10" width="150" height="20" follows="left|top|right|bottom"
+ font="SansSerifBig" font.style="UNDERLINE"
+ text_color="white"
+ mouse_opaque="true"
+ name="active_group" >
+ The Guild
+ </text>
+ <text
+ top="110" left="10" width="290" height="50" follows="left|top|right|bottom"
+ font="SansSerifSmall" text_color="white" word_wrap="true"
+ mouse_opaque="true" name="user_detail" >
+3 year-old account, Payment info on file
+Languages: English, Spanish; +5 Sexterity Vest
+ </text>
+ <avatar_icon
+ top="185" left="230" width="60" height="60" follows="left|top|right|bottom"
+ color="1 1 1 1" enabled="true" mouse_opaque="true" name="avatar_icon"
+ />
+ <slider
+ bottom="35" left="45" width="250" height="30" follows="top|left"
+ name="volume_slider"
+ tool_tip="Voice Volume"
+ increment="0.05" initial_value="0.75" max_val="1" min_val="0"
+ show_text="false"
+ />
+ <button
+ bottom="40" left="10" width="32" height="16" follows="left|top|right|bottom"
+ name="mute_btn"
+ label=""
+ image_unselected="icn_speaker_dark.tga"
+ image_disabled="icn_speaker_dark.tga"
+ image_selected="icn_speaker-muted_dark.tga"
+ image_hover_selected="icn_speaker-muted_dark.tga"
+ image_disabled_selected="icn_speaker-muted_dark.tga"
+ halign="center"
+ toggle="true"
+ />
+ <button
+ bottom="10" left="10" width="110" height="20" follows="top|left"
+ name="add_friend_btn"
+ label="Add Friend"
+ font="SansSerif"
+ />
+ <button
+ bottom="10" left="120" width="110" height="20" follows="top|left"
+ name="view_profile_btn"
+ label="View Profile"
+ font="SansSerif"
+ />
+ <button
+ bottom="10" left="230" width="60" height="20" follows="top|left"
+ name="gear_btn"
+ label=""
+ image_overlay="gear.tga"
+ image_overlay_alignment="center"
+ scale_image="true"
+ />
+</floater>
diff --git a/indra/newview/skins/default/xui/en/language_settings.xml b/indra/newview/skins/default/xui/en/language_settings.xml
new file mode 100644
index 0000000000..71418d446a
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/language_settings.xml
@@ -0,0 +1,55 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<!-- This file contains strings that used to be hardcoded in the source.-->
+<strings>
+
+ <!-- Locale Information -->
+ <string name="MicrosoftLocale">english</string>
+ <string name="DarwinLocale">C</string>
+ <string name="LinuxLocale">C</string>
+
+ <!--
+ datetimeToCodes["wkday"] = "%a"; // Thu
+ datetimeToCodes["weekday"] = "%A"; // Thursday
+ datetimeToCodes["year4"] = "%Y"; // 2009
+ datetimeToCodes["year"] = "%Y"; // 2009
+ datetimeToCodes["year2"] = "%y"; // 09
+ datetimeToCodes["mth"] = "%b"; // Aug
+ datetimeToCodes["month"] = "%B"; // August
+ datetimeToCodes["mthnum"] = "%m"; // 08
+ datetimeToCodes["day"] = "%d"; // 31
+ datetimeToCodes["hour24"] = "%H"; // 14
+ datetimeToCodes["hour"] = "%H"; // 14
+ datetimeToCodes["hour12"] = "%I"; // 02
+ datetimeToCodes["min"] = "%M"; // 59
+ datetimeToCodes["ampm"] = "%p"; // AM
+ datetimeToCodes["second"] = "%S"; // 59
+ datetimeToCodes["timezone"] = "%Z"; // PST
+ -->
+
+ <string name="TimeHour">hour,datetime,slt</string>
+ <string name="TimeMin">min,datetime,slt</string>
+ <string name="TimeYear">year,datetime,slt</string>
+ <string name="TimeDay">day,datetime,slt</string>
+ <string name="TimeMonth">mthnum,datetime,slt</string>
+ <string name="TimeWeek">wkday,datetime,slt</string>
+ <string name="TimeAMPM">ampm,datetime,slt</string>
+ <string name="TimeHour12">hour12,datetime,slt</string>
+
+ <string name="LTimeMthNum">mthnum,datetime,local</string>
+ <string name="LTimeWeek">wkday,datetime,local</string>
+ <string name="LTimeMonth">mth,datetime,local</string>
+ <string name="LTimeDay">day,datetime,local</string>
+ <string name="LTimeSec">second,datetime,local</string>
+ <string name="LTimeHour">hour,datetime,local</string>
+ <string name="LTimeMin">min,datetime,local</string>
+ <string name="LTimeYear">year,datetime,local</string>
+
+ <string name="UTCTimeWeek">weekday,datetime,utc</string>
+ <string name="UTCTimeDay">day,datetime,utc</string>
+ <string name="UTCTimeMth">mth,datetime,utc</string>
+ <string name="UTCTimeYr">year,datetime,utc</string>
+ <string name="UTCTimeHr">hour,datetime,utc</string>
+ <string name="UTCTimeMin">min,datetime,utc</string>
+ <string name="UTCTimeSec">second,datetime,utc</string>
+ <string name="UTCTimeTimezone">timezone,datetime,utc</string>
+</strings>
diff --git a/indra/newview/skins/default/xui/en/menu_avatar_icon.xml b/indra/newview/skins/default/xui/en/menu_avatar_icon.xml
new file mode 100644
index 0000000000..df510d68eb
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/menu_avatar_icon.xml
@@ -0,0 +1,43 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<menu
+ height="101"
+ layout="topleft"
+ left="100"
+ mouse_opaque="false"
+ name="Avatar Icon Menu"
+ top="724"
+ visible="false"
+ width="128">
+ <menu_item_call
+ label="Show Profile..."
+ layout="topleft"
+ name="Show Profile">
+ <menu_item_call.on_click
+ function="AvatarIcon.Action"
+ parameter="profile" />
+ </menu_item_call>
+ <menu_item_call
+ label="Send IM..."
+ layout="topleft"
+ name="Send IM">
+ <menu_item_call.on_click
+ function="AvatarIcon.Action"
+ parameter="im" />
+ </menu_item_call>
+ <menu_item_call
+ label="Add Friend..."
+ layout="topleft"
+ name="Add Friend">
+ <menu_item_call.on_click
+ function="AvatarIcon.Action"
+ parameter="add" />
+ </menu_item_call>
+ <menu_item_call
+ label="Remove Friend..."
+ layout="topleft"
+ name="Remove Friend">
+ <menu_item_call.on_click
+ function="AvatarIcon.Action"
+ parameter="remove" />
+ </menu_item_call>
+</menu>
diff --git a/indra/newview/skins/default/xui/en/menu_favorites.xml b/indra/newview/skins/default/xui/en/menu_favorites.xml
new file mode 100644
index 0000000000..951cf63c76
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/menu_favorites.xml
@@ -0,0 +1,71 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<menu
+ bottom="825"
+ layout="topleft"
+ name="Popup"
+ visible="false">
+ <menu_item_call
+ label="Teleport"
+ layout="topleft"
+ name="Teleport To Landmark">
+ <menu_item_call.on_click
+ function="Favorites.DoToSelected"
+ parameter="open" />
+ </menu_item_call>
+ <menu_item_call
+ label="View/Edit Landmark"
+ layout="topleft"
+ name="Landmark Open">
+ <menu_item_call.on_click
+ function="Favorites.DoToSelected"
+ parameter="about" />
+ </menu_item_call>
+ <menu_item_call
+ label="Copy SLurl"
+ layout="topleft"
+ name="Copy slurl">
+ <menu_item_call.on_click
+ function="Favorites.DoToSelected"
+ parameter="copy_slurl" />
+ </menu_item_call>
+ <menu_item_call
+ label="Show On Map"
+ layout="topleft"
+ name="Show On Map">
+ <menu_item_call.on_click
+ function="Favorites.DoToSelected"
+ parameter="show_on_map" />
+ </menu_item_call>
+
+ <menu_item_separator
+ layout="topleft" />
+
+ <menu_item_call
+ label="Copy"
+ layout="topleft"
+ name="Landmark Copy">
+ <menu_item_call.on_click
+ function="Favorites.DoToSelected"
+ parameter="copy" />
+ </menu_item_call>
+ <menu_item_call
+ label="Paste"
+ layout="topleft"
+ name="Landmark Paste">
+ <menu_item_call.on_click
+ function="Favorites.DoToSelected"
+ parameter="paste" />
+ </menu_item_call>
+
+ <menu_item_separator
+ layout="topleft" />
+
+ <menu_item_call
+ label="Delete"
+ layout="topleft"
+ name="Delete">
+ <menu_item_call.on_click
+ function="Favorites.DoToSelected"
+ parameter="delete" />
+ </menu_item_call>
+</menu>
diff --git a/indra/newview/skins/default/xui/en/menu_group_plus.xml b/indra/newview/skins/default/xui/en/menu_group_plus.xml
new file mode 100644
index 0000000000..2029b19c1c
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/menu_group_plus.xml
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<menu name="menu_group_plus"
+ left="0" bottom="0" visible="false"
+ mouse_opaque="false" opaque="true" color="MenuDefaultBgColor" drop_shadow="true">
+ <menu_item_call name="item_join" label="Join Group...">
+ <menu_item_call.on_click function="People.Group.Plus.Action" userdata="join_group" />
+ </menu_item_call>
+ <menu_item_call name="item_new" label="New Group...">
+ <menu_item_call.on_click function="People.Group.Plus.Action" userdata="new_group" />
+ </menu_item_call>
+</menu>
diff --git a/indra/newview/skins/default/xui/en/menu_hide_navbar.xml b/indra/newview/skins/default/xui/en/menu_hide_navbar.xml
new file mode 100644
index 0000000000..1ad10abbeb
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/menu_hide_navbar.xml
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<menu
+ height="201"
+ layout="topleft"
+ left="100"
+ mouse_opaque="false"
+ name="hide_navbar_menu"
+ top="624"
+ visible="false"
+ width="128">
+ <menu_item_check
+ label="Show Navigation Bar"
+ layout="topleft"
+ name="Show Navigation Bar">
+ <menu_item_check.on_click
+ function="HideNavbarMenu.Action"
+ parameter="show_navbar_navigation_panel" />
+ <menu_item_check.on_check
+ function="HideNavbarMenu.EnableMenuItem"
+ parameter="show_navbar_navigation_panel" />
+ </menu_item_check>
+ <menu_item_check
+ label="Show Favorites Bar"
+ layout="topleft"
+ name="Show Favorites Bar">
+ <menu_item_check.on_click
+ function="HideNavbarMenu.Action"
+ parameter="show_navbar_favorites_panel" />
+ <menu_item_check.on_check
+ function="HideNavbarMenu.EnableMenuItem"
+ parameter="show_navbar_favorites_panel" />
+ </menu_item_check>
+</menu>
diff --git a/indra/newview/skins/default/xui/en/menu_imchiclet_group.xml b/indra/newview/skins/default/xui/en/menu_imchiclet_group.xml
new file mode 100644
index 0000000000..542e319792
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/menu_imchiclet_group.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<menu
+ height="101"
+ layout="topleft"
+ left="100"
+ mouse_opaque="false"
+ name="IMChiclet Group Menu"
+ top="724"
+ visible="false"
+ width="128">
+ <menu_item_call
+ label="Chat..."
+ layout="topleft"
+ name="Chat">
+ <menu_item_call.on_click
+ function="IMChicletMenu.Action"
+ parameter="group chat" />
+ </menu_item_call>
+ <menu_item_call
+ label="Info..."
+ layout="topleft"
+ name="Show Profile">
+ <menu_item_call.on_click
+ function="IMChicletMenu.Action"
+ parameter="info" />
+ </menu_item_call>
+</menu>
diff --git a/indra/newview/skins/default/xui/en/menu_imchiclet_p2p.xml b/indra/newview/skins/default/xui/en/menu_imchiclet_p2p.xml
new file mode 100644
index 0000000000..c205868429
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/menu_imchiclet_p2p.xml
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<menu
+ height="101"
+ layout="topleft"
+ left="100"
+ mouse_opaque="false"
+ name="IMChiclet P2P Menu"
+ top="724"
+ visible="false"
+ width="128">
+ <menu_item_call
+ label="Show Profile..."
+ layout="topleft"
+ name="Show Profile">
+ <menu_item_call.on_click
+ function="IMChicletMenu.Action"
+ parameter="profile" />
+ </menu_item_call>
+ <menu_item_call
+ label="Send IM..."
+ layout="topleft"
+ name="Send IM">
+ <menu_item_call.on_click
+ function="IMChicletMenu.Action"
+ parameter="im" />
+ </menu_item_call>
+ <menu_item_call
+ label="Add Friend..."
+ layout="topleft"
+ name="Add Friend">
+ <menu_item_call.on_click
+ function="IMChicletMenu.Action"
+ parameter="add" />
+ </menu_item_call>
+</menu>
diff --git a/indra/newview/skins/default/xui/en/menu_inventory.xml b/indra/newview/skins/default/xui/en/menu_inventory.xml
new file mode 100644
index 0000000000..7762a7f667
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/menu_inventory.xml
@@ -0,0 +1,619 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<menu
+ bottom="825"
+ layout="topleft"
+ name="Popup"
+ visible="false">
+ <menu_item_call
+ label="Buy"
+ layout="topleft"
+ name="Task Buy">
+ <menu_item_call.on_click
+ function="Inventory.DoToSelected"
+ parameter="task_buy" />
+ </menu_item_call>
+ <menu_item_call
+ label="Open"
+ layout="topleft"
+ name="Task Open">
+ <menu_item_call.on_click
+ function="Inventory.DoToSelected"
+ parameter="task_open" />
+ </menu_item_call>
+ <menu_item_call
+ label="Play"
+ layout="topleft"
+ name="Task Play">
+ <menu_item_call.on_click
+ function="Inventory.DoToSelected"
+ parameter="task_play" />
+ </menu_item_call>
+ <menu_item_call
+ label="Properties"
+ layout="topleft"
+ name="Task Properties">
+ <menu_item_call.on_click
+ function="Inventory.DoToSelected"
+ parameter="task_properties" />
+ </menu_item_call>
+ <menu_item_call
+ label="Rename"
+ layout="topleft"
+ name="Task Rename">
+ <menu_item_call.on_click
+ function="Inventory.DoToSelected"
+ parameter="rename" />
+ </menu_item_call>
+ <menu_item_call
+ label="Delete"
+ layout="topleft"
+ name="Task Remove">
+ <menu_item_call.on_click
+ function="Inventory.DoToSelected"
+ parameter="delete" />
+ </menu_item_call>
+ <menu_item_call
+ label="Empty Trash"
+ layout="topleft"
+ name="Empty Trash">
+ <menu_item_call.on_click
+ function="Inventory.EmptyTrash"
+ parameter="rename" />
+ </menu_item_call>
+ <menu_item_call
+ label="Empty Lost And Found"
+ layout="topleft"
+ name="Empty Lost And Found">
+ <menu_item_call.on_click
+ function="Inventory.EmptyLostAndFound"
+ parameter="rename" />
+ </menu_item_call>
+ <menu_item_call
+ label="New Folder"
+ layout="topleft"
+ name="New Folder">
+ <menu_item_call.on_click
+ function="Inventory.DoCreate"
+ parameter="category" />
+ </menu_item_call>
+ <menu_item_call
+ label="New Script"
+ layout="topleft"
+ name="New Script">
+ <menu_item_call.on_click
+ function="Inventory.DoCreate"
+ parameter="lsl" />
+ </menu_item_call>
+ <menu_item_call
+ label="New Note"
+ layout="topleft"
+ name="New Note">
+ <menu_item_call.on_click
+ function="Inventory.DoCreate"
+ parameter="notecard" />
+ </menu_item_call>
+ <menu_item_call
+ label="New Gesture"
+ layout="topleft"
+ name="New Gesture">
+ <menu_item_call.on_click
+ function="Inventory.DoCreate"
+ parameter="gesture" />
+ </menu_item_call>
+ <menu
+ label="New Clothes"
+ layout="topleft"
+ name="New Clothes">
+ <menu_item_call
+ label="New Shirt"
+ layout="topleft"
+ name="New Shirt">
+ <menu_item_call.on_click
+ function="Inventory.DoCreate"
+ parameter="shirt" />
+ </menu_item_call>
+ <menu_item_call
+ label="New Pants"
+ layout="topleft"
+ name="New Pants">
+ <menu_item_call.on_click
+ function="Inventory.DoCreate"
+ parameter="pants" />
+ </menu_item_call>
+ <menu_item_call
+ label="New Shoes"
+ layout="topleft"
+ name="New Shoes">
+ <menu_item_call.on_click
+ function="Inventory.DoCreate"
+ parameter="shoes" />
+ </menu_item_call>
+ <menu_item_call
+ label="New Socks"
+ layout="topleft"
+ name="New Socks">
+ <menu_item_call.on_click
+ function="Inventory.DoCreate"
+ parameter="socks" />
+ </menu_item_call>
+ <menu_item_call
+ label="New Jacket"
+ layout="topleft"
+ name="New Jacket">
+ <menu_item_call.on_click
+ function="Inventory.DoCreate"
+ parameter="jacket" />
+ </menu_item_call>
+ <menu_item_call
+ label="New Skirt"
+ layout="topleft"
+ name="New Skirt">
+ <menu_item_call.on_click
+ function="Inventory.DoCreate"
+ parameter="skirt" />
+ </menu_item_call>
+ <menu_item_call
+ label="New Gloves"
+ layout="topleft"
+ name="New Gloves">
+ <menu_item_call.on_click
+ function="Inventory.DoCreate"
+ parameter="gloves" />
+ </menu_item_call>
+ <menu_item_call
+ label="New Undershirt"
+ layout="topleft"
+ name="New Undershirt">
+ <menu_item_call.on_click
+ function="Inventory.DoCreate"
+ parameter="undershirt" />
+ </menu_item_call>
+ <menu_item_call
+ label="New Underpants"
+ layout="topleft"
+ name="New Underpants">
+ <menu_item_call.on_click
+ function="Inventory.DoCreate"
+ parameter="underpants" />
+ </menu_item_call>
+ <menu_item_call
+ label="New Alpha Mask"
+ layout="topleft"
+ name="New Alpha Mask">
+ <menu_item_call.on_click
+ function="Inventory.DoCreate"
+ parameter="alpha" />
+ </menu_item_call>
+ <menu_item_call
+ label="New Tattoo"
+ layout="topleft"
+ name="New Tattoo">
+ <menu_item_call.on_click
+ function="Inventory.DoCreate"
+ parameter="tattoo" />
+ </menu_item_call>
+ </menu>
+ <menu
+ label="New Body Parts"
+ layout="topleft"
+ name="New Body Parts">
+ <menu_item_call
+ label="New Shape"
+ layout="topleft"
+ name="New Shape">
+ <menu_item_call.on_click
+ function="Inventory.DoCreate"
+ parameter="shape" />
+ </menu_item_call>
+ <menu_item_call
+ label="New Skin"
+ layout="topleft"
+ name="New Skin">
+ <menu_item_call.on_click
+ function="Inventory.DoCreate"
+ parameter="skin" />
+ </menu_item_call>
+ <menu_item_call
+ label="New Hair"
+ layout="topleft"
+ name="New Hair">
+ <menu_item_call.on_click
+ function="Inventory.DoCreate"
+ parameter="hair" />
+ </menu_item_call>
+ <menu_item_call
+ label="New Eyes"
+ layout="topleft"
+ name="New Eyes">
+ <menu_item_call.on_click
+ function="Inventory.DoCreate"
+ parameter="eyes" />
+ </menu_item_call>
+ </menu>
+ <menu
+ label="Change Type"
+ layout="topleft"
+ name="Change Type">
+ <menu_item_call
+ label="Default"
+ layout="topleft"
+ name="Default">
+ <menu_item_call.on_click
+ function="Inventory.DoToSelected"
+ parameter="change_folder_type_default" />
+ </menu_item_call>
+ <menu_item_call
+ label="Gloves"
+ layout="topleft"
+ name="Gloves">
+ <menu_item_call.on_click
+ function="Inventory.DoToSelected"
+ parameter="change_folder_type_gloves" />
+ </menu_item_call>
+ <menu_item_call
+ label="Jacket"
+ layout="topleft"
+ name="Jacket">
+ <menu_item_call.on_click
+ function="Inventory.DoToSelected"
+ parameter="change_folder_type_jacket" />
+ </menu_item_call>
+ <menu_item_call
+ label="Pants"
+ layout="topleft"
+ name="Pants">
+ <menu_item_call.on_click
+ function="Inventory.DoToSelected"
+ parameter="change_folder_type_pants" />
+ </menu_item_call>
+ <menu_item_call
+ label="Shape"
+ layout="topleft"
+ name="Shape">
+ <menu_item_call.on_click
+ function="Inventory.DoToSelected"
+ parameter="change_folder_type_shape" />
+ </menu_item_call>
+ <menu_item_call
+ label="Shoes"
+ layout="topleft"
+ name="Shoes">
+ <menu_item_call.on_click
+ function="Inventory.DoToSelected"
+ parameter="change_folder_type_shoes" />
+ </menu_item_call>
+ <menu_item_call
+ label="Shirt"
+ layout="topleft"
+ name="Shirt">
+ <menu_item_call.on_click
+ function="Inventory.DoToSelected"
+ parameter="change_folder_type_shirt" />
+ </menu_item_call>
+ <menu_item_call
+ label="Skirt"
+ layout="topleft"
+ name="Skirt">
+ <menu_item_call.on_click
+ function="Inventory.DoToSelected"
+ parameter="change_folder_type_skirt" />
+ </menu_item_call>
+ <menu_item_call
+ label="Underpants"
+ layout="topleft"
+ name="Underpants">
+ <menu_item_call.on_click
+ function="Inventory.DoToSelected"
+ parameter="change_folder_type_underpants" />
+ </menu_item_call>
+ <menu_item_call
+ label="Undershirt"
+ layout="topleft"
+ name="Undershirt">
+ <menu_item_call.on_click
+ function="Inventory.DoToSelected"
+ parameter="change_folder_type_undershirt" />
+ </menu_item_call>
+ </menu>
+ <menu_item_call
+ label="Teleport"
+ layout="topleft"
+ name="Landmark Open">
+ <menu_item_call.on_click
+ function="Inventory.DoToSelected"
+ parameter="open" />
+ </menu_item_call>
+ <menu_item_call
+ label="Open"
+ layout="topleft"
+ name="Animation Open">
+ <menu_item_call.on_click
+ function="Inventory.DoToSelected"
+ parameter="open" />
+ </menu_item_call>
+ <menu_item_call
+ label="Open"
+ layout="topleft"
+ name="Sound Open">
+ <menu_item_call.on_click
+ function="Inventory.DoToSelected"
+ parameter="open" />
+ </menu_item_call>
+ <menu_item_call
+ label="Purge Item"
+ layout="topleft"
+ name="Purge Item">
+ <menu_item_call.on_click
+ function="Inventory.DoToSelected"
+ parameter="purge" />
+ </menu_item_call>
+ <menu_item_call
+ label="Restore Item"
+ layout="topleft"
+ name="Restore Item">
+ <menu_item_call.on_click
+ function="Inventory.DoToSelected"
+ parameter="restore" />
+ </menu_item_call>
+ <menu_item_call
+ label="Goto Link"
+ layout="topleft"
+ name="Goto Link">
+ <menu_item_call.on_click
+ function="Inventory.DoToSelected"
+ parameter="goto" />
+ </menu_item_call>
+ <menu_item_call
+ label="Open"
+ layout="topleft"
+ name="Open">
+ <menu_item_call.on_click
+ function="Inventory.DoToSelected"
+ parameter="open" />
+ </menu_item_call>
+ <menu_item_call
+ label="Properties"
+ layout="topleft"
+ name="Properties">
+ <menu_item_call.on_click
+ function="Inventory.DoToSelected"
+ parameter="properties" />
+ </menu_item_call>
+ <menu_item_call
+ label="Rename"
+ layout="topleft"
+ name="Rename">
+ <menu_item_call.on_click
+ function="Inventory.DoToSelected"
+ parameter="rename" />
+ </menu_item_call>
+ <menu_item_call
+ label="Copy Asset UUID"
+ layout="topleft"
+ name="Copy Asset UUID">
+ <menu_item_call.on_click
+ function="Inventory.DoToSelected"
+ parameter="copy_uuid" />
+ </menu_item_call>
+ <menu_item_separator
+ layout="topleft" />
+ <menu_item_call
+ label="Copy"
+ layout="topleft"
+ name="Copy">
+ <menu_item_call.on_click
+ function="Inventory.DoToSelected"
+ parameter="copy" />
+ </menu_item_call>
+ <menu_item_call
+ label="Paste"
+ layout="topleft"
+ name="Paste">
+ <menu_item_call.on_click
+ function="Inventory.DoToSelected"
+ parameter="paste" />
+ </menu_item_call>
+ <menu_item_call
+ label="Paste As Link"
+ layout="topleft"
+ name="Paste As Link">
+ <menu_item_call.on_click
+ function="Inventory.DoToSelected"
+ parameter="paste_link" />
+ </menu_item_call>
+ <menu_item_separator
+ layout="topleft" />
+ <menu_item_call
+ label="Delete"
+ layout="topleft"
+ name="Delete">
+ <menu_item_call.on_click
+ function="Inventory.DoToSelected"
+ parameter="delete" />
+ </menu_item_call>
+ <menu_item_separator
+ layout="topleft" />
+ <menu_item_call
+ label="Take Off Items"
+ layout="topleft"
+ name="Take Off Items">
+ <menu_item_call.on_click
+ function="Inventory.DoToSelected"
+ parameter="removefromoutfit" />
+ </menu_item_call>
+ <menu_item_call
+ label="Add To Outfit"
+ layout="topleft"
+ name="Add To Outfit">
+ <menu_item_call.on_click
+ function="Inventory.DoToSelected"
+ parameter="addtooutfit" />
+ </menu_item_call>
+ <menu_item_call
+ label="Replace Outfit"
+ layout="topleft"
+ name="Replace Outfit">
+ <menu_item_call.on_click
+ function="Inventory.DoToSelected"
+ parameter="replaceoutfit" />
+ </menu_item_call>
+ <menu_item_separator
+ layout="topleft" />
+ <menu_item_call
+ label="Start Conference Chat"
+ layout="topleft"
+ name="Conference Chat Folder">
+ <menu_item_call.on_click
+ function="Inventory.BeginIMSession"
+ parameter="everyone" />
+ </menu_item_call>
+ <menu_item_separator
+ layout="topleft" />
+ <menu_item_call
+ label="Play"
+ layout="topleft"
+ name="Sound Play">
+ <menu_item_call.on_click
+ function="Inventory.DoToSelected"
+ parameter="open" />
+ </menu_item_call>
+ <menu_item_separator
+ layout="topleft" />
+ <menu_item_call
+ label="About Landmark"
+ layout="topleft"
+ name="Teleport To Landmark">
+ <menu_item_call.on_click
+ function="Inventory.DoToSelected"
+ parameter="about" />
+ </menu_item_call>
+ <menu_item_separator
+ layout="topleft" />
+ <menu_item_call
+ label="Play in World"
+ layout="topleft"
+ name="Animation Play">
+ <menu_item_call.on_click
+ function="Inventory.DoToSelected"
+ parameter="playworld" />
+ </menu_item_call>
+ <menu_item_call
+ label="Play Locally"
+ layout="topleft"
+ name="Animation Audition">
+ <menu_item_call.on_click
+ function="Inventory.DoToSelected"
+ parameter="playlocal" />
+ </menu_item_call>
+ <menu_item_separator
+ layout="topleft" />
+ <menu_item_call
+ label="Send Instant Message"
+ layout="topleft"
+ name="Send Instant Message">
+ <menu_item_call.on_click
+ function="Inventory.DoToSelected"
+ parameter="begin_im" />
+ </menu_item_call>
+ <menu_item_call
+ label="Offer Teleport..."
+ layout="topleft"
+ name="Offer Teleport...">
+ <menu_item_call.on_click
+ function="Inventory.DoToSelected"
+ parameter="lure" />
+ </menu_item_call>
+ <menu_item_call
+ label="Start Conference Chat"
+ layout="topleft"
+ name="Conference Chat">
+ <menu_item_call.on_click
+ function="Inventory.BeginIMSession"
+ parameter="selected" />
+ </menu_item_call>
+ <menu_item_separator
+ layout="topleft" />
+ <menu_item_call
+ label="Activate"
+ layout="topleft"
+ name="Activate">
+ <menu_item_call.on_click
+ function="Inventory.DoToSelected"
+ parameter="activate" />
+ </menu_item_call>
+ <menu_item_call
+ label="Deactivate"
+ layout="topleft"
+ name="Deactivate">
+ <menu_item_call.on_click
+ function="Inventory.DoToSelected"
+ parameter="deactivate" />
+ </menu_item_call>
+ <menu_item_separator
+ layout="topleft" />
+ <menu_item_call
+ label="Detach From Yourself"
+ layout="topleft"
+ name="Detach From Yourself">
+ <menu_item_call.on_click
+ function="Inventory.DoToSelected"
+ parameter="detach" />
+ </menu_item_call>
+ <!-- COMMENTED OUT for DEV-32347 -->
+ <!--
+ <menu_item_call
+ label="Restore to Last Position"
+ layout="topleft"
+ name="Restore to Last Position">
+ <menu_item_call.on_click
+ function="Inventory.DoToSelected"
+ parameter="restoreToWorld" />
+ </menu_item_call>
+ -->
+ <menu_item_call
+ label="Wear"
+ layout="topleft"
+ name="Object Wear">
+ <menu_item_call.on_click
+ function="Inventory.DoToSelected"
+ parameter="attach" />
+ </menu_item_call>
+ <menu
+ label="Attach To"
+ layout="topleft"
+ name="Attach To" />
+ <menu
+ label="Attach To HUD"
+ layout="topleft"
+ name="Attach To HUD" />
+ <menu_item_call
+ label="Edit"
+ layout="topleft"
+ name="Wearable Edit">
+ <menu_item_call.on_click
+ function="Inventory.DoToSelected"
+ parameter="edit" />
+ </menu_item_call>
+ <menu_item_call
+ label="Wear"
+ layout="topleft"
+ name="Wearable Wear">
+ <menu_item_call.on_click
+ function="Inventory.DoToSelected"
+ parameter="wear" />
+ </menu_item_call>
+ <menu_item_call
+ label="Take Off"
+ layout="topleft"
+ name="Take Off">
+ <menu_item_call.on_click
+ function="Inventory.DoToSelected"
+ parameter="take_off" />
+ </menu_item_call>
+ <menu_item_call
+ label="--no options--"
+ layout="topleft"
+ name="--no options--" />
+ <menu_item_separator
+ layout="topleft" />
+</menu>
diff --git a/indra/newview/skins/default/xui/en/menu_landmark.xml b/indra/newview/skins/default/xui/en/menu_landmark.xml
new file mode 100644
index 0000000000..64fec3ab40
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/menu_landmark.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<toggleable_menu
+ height="201"
+ layout="topleft"
+ mouse_opaque="false"
+ name="landmark_overflow_menu"
+ width="128">
+ <menu_item_call
+ label="Copy SLurl"
+ layout="topleft"
+ name="copy">
+ <menu_item_call.on_click
+ function="Places.OverflowMenu.Action"
+ parameter="copy" />
+ </menu_item_call>
+ <menu_item_call
+ label="Delete"
+ layout="topleft"
+ name="delete">
+ <menu_item_call.on_click
+ function="Places.OverflowMenu.Action"
+ parameter="delete" />
+ </menu_item_call>
+ <menu_item_call
+ label="Create Pick"
+ layout="topleft"
+ name="pick">
+ <menu_item_call.on_click
+ function="Places.OverflowMenu.Action"
+ parameter="pick" />
+ </menu_item_call>
+</toggleable_menu>
diff --git a/indra/newview/skins/default/xui/en/menu_login.xml b/indra/newview/skins/default/xui/en/menu_login.xml
new file mode 100644
index 0000000000..1e911c2664
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/menu_login.xml
@@ -0,0 +1,129 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<menu_bar
+ follows="left|top|right"
+ height="18"
+ layout="topleft"
+ left_delta="0"
+ name="Login Menu"
+ top_delta="0"
+ width="802">
+ <menu
+ create_jump_keys="true"
+ label="File"
+ layout="topleft"
+ name="File">
+ <menu_item_call
+ label="Quit"
+ layout="topleft"
+ name="Quit"
+ shortcut="control|Q">
+ <menu_item_call.on_click
+ function="File.Quit" />
+ </menu_item_call>
+ </menu>
+ <menu
+ create_jump_keys="true"
+ label="Edit"
+ layout="topleft"
+ name="Edit"
+ width="153">
+ <menu_item_call
+ label="Preferences..."
+ layout="topleft"
+ name="Preferences..."
+ shortcut="control|P">
+ <menu_item_call.on_click
+ function="ShowFloater"
+ parameter="preferences" />
+ </menu_item_call>
+ </menu>
+ <menu
+ create_jump_keys="true"
+ label="Help"
+ layout="topleft"
+ name="Help">
+ <menu_item_call
+ label="[SECOND_LIFE] Help"
+ layout="topleft"
+ name="Second Life Help"
+ shortcut="F1">
+ <menu_item_call.on_click
+ function="ShowFloater"
+ parameter="help f1" />
+ </menu_item_call>
+ <menu_item_call
+ label="About [APP_NAME]"
+ layout="topleft"
+ name="About Second Life">
+ <menu_item_call.on_click
+ function="ShowFloater"
+ parameter="sl_about" />
+ </menu_item_call>
+ </menu>
+ <menu
+ create_jump_keys="true"
+ label="Debug"
+ layout="topleft"
+ name="Debug">
+ <menu_item_call
+ label="Debug Settings"
+ layout="topleft"
+ name="Debug Settings">
+ <menu_item_call.on_click
+ function="Advanced.ShowDebugSettings"
+ parameter="all" />
+ </menu_item_call>
+ <menu_item_call
+ label="UI/Color Settings"
+ layout="topleft"
+ name="UI/Color Settings">
+ <menu_item_call.on_click
+ function="Advanced.ShowDebugSettings"
+ parameter="skin" />
+ </menu_item_call>
+ <menu_item_separator />
+ <menu_item_call
+ label="UI Preview Tool"
+ layout="topleft"
+ name="UI Preview Tool"
+ shortcut="control|T">
+ <menu_item_call.on_click
+ function="ShowFloater"
+ parameter="ui_preview" />
+ </menu_item_call>
+ <menu_item_separator />
+ <menu_item_call
+ label="Widget Test"
+ layout="topleft"
+ name="Widget Test"
+ shortcut="control|shift|T">
+ <menu_item_call.on_click
+ function="ShowFloater"
+ parameter="test_widgets" />
+ </menu_item_call>
+ <menu_item_call
+ label="Avatar Inspector"
+ name="Avatar Inspector"
+ shortcut="control|shift|I">
+ <menu_item_call.on_click
+ function="ShowFloater"
+ parameter="inspect_avatar" />
+ </menu_item_call>
+ <menu_item_call
+ label="Show TOS"
+ layout="topleft"
+ name="TOS">
+ <menu_item_call.on_click
+ function="ShowFloater"
+ parameter="message_tos" />
+ </menu_item_call>
+ <menu_item_call
+ label="Show Critical Message"
+ layout="topleft"
+ name="TOS">
+ <menu_item_call.on_click
+ function="ShowFloater"
+ parameter="message_critical" />
+ </menu_item_call>
+ </menu>
+</menu_bar>
diff --git a/indra/newview/skins/default/xui/en/menu_mini_map.xml b/indra/newview/skins/default/xui/en/menu_mini_map.xml
new file mode 100644
index 0000000000..5cbbd71bfe
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/menu_mini_map.xml
@@ -0,0 +1,57 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<menu
+ height="101"
+ layout="topleft"
+ left="100"
+ mouse_opaque="false"
+ name="Popup"
+ top="724"
+ visible="false"
+ width="128">
+ <menu_item_call
+ label="Zoom Close"
+ layout="topleft"
+ name="Zoom Close">
+ <menu_item_call.on_click
+ function="Minimap.Zoom"
+ parameter="close" />
+ </menu_item_call>
+ <menu_item_call
+ label="Zoom Medium"
+ layout="topleft"
+ name="Zoom Medium">
+ <menu_item_call.on_click
+ function="Minimap.Zoom"
+ parameter="medium" />
+ </menu_item_call>
+ <menu_item_call
+ label="Zoom Far"
+ layout="topleft"
+ name="Zoom Far">
+ <menu_item_call.on_click
+ function="Minimap.Zoom"
+ parameter="far" />
+ </menu_item_call>
+ <menu_item_separator
+ layout="topleft"
+ name="Tracking Separator" />
+ <menu_item_call
+ label="Stop Tracking"
+ layout="topleft"
+ name="Stop Tracking">
+ <menu_item_call.on_click
+ function="Minimap.Tracker"
+ parameter="task_properties" />
+ </menu_item_call>
+ <menu_item_separator
+ layout="topleft"
+ name="Tracking Separator" />
+ <menu_item_call
+ label="World Map"
+ layout="topleft"
+ name="World Map">
+ <menu_item_call.on_click
+ function="ShowFloater"
+ parameter="world_map" />
+ </menu_item_call>
+</menu>
diff --git a/indra/newview/skins/default/xui/en/menu_navbar.xml b/indra/newview/skins/default/xui/en/menu_navbar.xml
new file mode 100644
index 0000000000..89469fb013
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/menu_navbar.xml
@@ -0,0 +1,90 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<menu
+ height="201"
+ layout="topleft"
+ left="100"
+ mouse_opaque="false"
+ name="Navbar Menu"
+ top="624"
+ visible="false"
+ width="128">
+ <menu_item_check
+ label="Show Coordinates"
+ layout="topleft"
+ name="Show Coordinates">
+ <menu_item_check.on_click
+ function="Navbar.Action"
+ parameter="show_coordinates" />
+ <menu_item_check.on_check
+ function="Navbar.EnableMenuItem"
+ parameter="show_coordinates" />
+ </menu_item_check>
+ <!-- Label of 'Landmark' item is changing in runtime,
+ see AddLandmarkNavBarMenu/EditLandmarkNavBarMenu in strings.xml -->
+ <menu_item_call
+ label="Landmark"
+ layout="topleft"
+ name="Landmark">
+ <menu_item_call.on_click
+ function="Navbar.Action"
+ parameter="landmark" />
+ </menu_item_call>
+ <menu_item_separator
+ layout="topleft"
+ name="Separator" />
+ <menu_item_call
+ label="Cut"
+ layout="topleft"
+ name="Cut">
+ <menu_item_call.on_click
+ function="Navbar.Action"
+ parameter="cut" />
+ <menu_item_call.on_enable
+ function="Navbar.EnableMenuItem"
+ parameter="can_cut" />
+ </menu_item_call>
+ <menu_item_call
+ label="Copy"
+ layout="topleft"
+ name="Copy">
+ <menu_item_call.on_click
+ function="Navbar.Action"
+ parameter="copy" />
+ <menu_item_call.on_enable
+ function="Navbar.EnableMenuItem"
+ parameter="can_copy" />
+ </menu_item_call>
+ <menu_item_call
+ label="Paste"
+ layout="topleft"
+ name="Paste">
+ <menu_item_call.on_click
+ function="Navbar.Action"
+ parameter="paste" />
+ <menu_item_call.on_enable
+ function="Navbar.EnableMenuItem"
+ parameter="can_paste" />
+ </menu_item_call>
+ <menu_item_call
+ label="Delete"
+ layout="topleft"
+ name="Delete">
+ <menu_item_call.on_click
+ function="Navbar.Action"
+ parameter="delete" />
+ <menu_item_call.on_enable
+ function="Navbar.EnableMenuItem"
+ parameter="can_delete" />
+ </menu_item_call>
+ <menu_item_call
+ label="Select All"
+ layout="topleft"
+ name="Select All">
+ <menu_item_call.on_click
+ function="Navbar.Action"
+ parameter="select_all" />
+ <menu_item_call.on_enable
+ function="Navbar.EnableMenuItem"
+ parameter="can_select_all" />
+ </menu_item_call>
+</menu>
diff --git a/indra/newview/skins/default/xui/en/menu_nearby_chat.xml b/indra/newview/skins/default/xui/en/menu_nearby_chat.xml
new file mode 100644
index 0000000000..ff89e20ea5
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/menu_nearby_chat.xml
@@ -0,0 +1,39 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<menu bottom="100" color="MenuDefaultBgColor" drop_shadow="true" height="101" left="100"
+ mouse_opaque="false" name="NearBy Chat Menu" opaque="true" width="128" visible="false">
+ <menu_item_call bottom_delta="-18" height="18" label="Show Nearby People..." left="0" mouse_opaque="true"
+ name="nearby_people" width="128">
+ <menu_item_call.on_click function="NearbyChat.Action" userdata="nearby_people" />
+ </menu_item_call>
+
+ <menu_item_separator />
+ <menu_item_check bottom_delta="-18" height="18" label="Show Blocked Text" left="0" mouse_opaque="true"
+ name="muted_text" width="128">
+ <menu_item_check.on_click function="NearbyChat.Action" userdata="muted_text" />
+ <menu_item_check.on_check function="NearbyChat.Check" userdata="muted_text"/>
+ </menu_item_check>
+
+ <menu_item_separator />
+
+ <menu_item_check bottom_delta="-18" height="18" label="Show Buddy Icons" left="0" mouse_opaque="true"
+ name="show_buddy_icons" width="128">
+ <menu_item_check.on_click function="NearbyChat.Action" userdata="show_buddy_icons" />
+ <menu_item_check.on_check function="NearbyChat.Check" userdata="show_buddy_icons"/>
+ </menu_item_check>
+ <menu_item_check bottom_delta="-18" height="18" label="Show Names" left="0" mouse_opaque="true"
+ name="show_names" width="128">
+ <menu_item_check.on_click function="NearbyChat.Action" userdata="show_names" />
+ <menu_item_check.on_check function="NearbyChat.Check" userdata="show_names"/>
+ </menu_item_check>
+ <menu_item_check bottom_delta="-18" height="18" label="Show Icons and Names" left="0" mouse_opaque="true"
+ name="show_icons_and_names" width="128">
+ <menu_item_check.on_click function="NearbyChat.Action" userdata="show_icons_and_names" />
+ <menu_item_check.on_check function="NearbyChat.Check" userdata="show_icons_and_names"/>
+ </menu_item_check>
+
+ <menu_item_separator />
+ <menu_item_call bottom_delta="-18" height="18" label="Font Size" left="0" mouse_opaque="true"
+ name="font_size" width="128">
+ <menu_item_call.on_click function="NearbyChat.Action" userdata="font_size" />
+ </menu_item_call>
+</menu>
diff --git a/indra/newview/skins/default/xui/en/menu_people_friends_view_sort.xml b/indra/newview/skins/default/xui/en/menu_people_friends_view_sort.xml
new file mode 100644
index 0000000000..bb5a4e51f7
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/menu_people_friends_view_sort.xml
@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<menu name="menu_group_plus"
+ left="0" bottom="0" visible="false"
+ mouse_opaque="false" opaque="true" color="MenuDefaultBgColor" drop_shadow="true">
+ <menu_item_call name="sort_name" label="Sort by Name">
+ <menu_item_call.on_click function="People.Friends.ViewSort.Action" userdata="sort_name" />
+ </menu_item_call>
+ <menu_item_call name="sort_status" label="Sort by Status">
+ <menu_item_call.on_click function="People.Friends.ViewSort.Action" userdata="sort_status" />
+ </menu_item_call>
+ <menu_item_separator layout="topleft" />
+ <menu_item_call name="view_icons" label="View People Icons">
+ <menu_item_call.on_click function="People.Friends.ViewSort.Action" userdata="view_icons" />
+ </menu_item_call>
+ <menu_item_call name="organize_offline" label="Organize Offline Friends">
+ <menu_item_call.on_click function="People.Friends.ViewSort.Action" userdata="organize_offline" />
+ </menu_item_call>
+</menu>
diff --git a/indra/newview/skins/default/xui/en/menu_people_nearby_view_sort.xml b/indra/newview/skins/default/xui/en/menu_people_nearby_view_sort.xml
new file mode 100644
index 0000000000..8c2c5e8c9e
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/menu_people_nearby_view_sort.xml
@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<menu name="menu_group_plus"
+ left="0" bottom="0" visible="false"
+ mouse_opaque="false" opaque="true" color="MenuDefaultBgColor" drop_shadow="true">
+ <menu_item_call name="sort_recent" label="Sort by Recent Speakers">
+ <menu_item_call.on_click function="People.Nearby.ViewSort.Action" userdata="sort_recent" />
+ </menu_item_call>
+ <menu_item_call name="sort_name" label="Sort by Name">
+ <menu_item_call.on_click function="People.Nearby.ViewSort.Action" userdata="sort_name" />
+ </menu_item_call>
+ <menu_item_call name="sort_distance" label="Sort by Distance">
+ <menu_item_call.on_click function="People.Nearby.ViewSort.Action" userdata="sort_distance" />
+ </menu_item_call>
+ <menu_item_separator layout="topleft" />
+ <menu_item_call name="view_icons" label="View People Icons">
+ <menu_item_call.on_click function="People.Nearby.ViewSort.Action" userdata="view_icons" />
+ </menu_item_call>
+</menu>
diff --git a/indra/newview/skins/default/xui/en/menu_people_recent_view_sort.xml b/indra/newview/skins/default/xui/en/menu_people_recent_view_sort.xml
new file mode 100644
index 0000000000..00cf443cc6
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/menu_people_recent_view_sort.xml
@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<menu name="menu_group_plus"
+ left="0" bottom="0" visible="false"
+ mouse_opaque="false" opaque="true" color="MenuDefaultBgColor" drop_shadow="true">
+ <menu_item_call name="sort_most" label="Sort by Most Speakers">
+ <menu_item_call.on_click function="People.Recent.ViewSort.Action" userdata="sort_most" />
+ </menu_item_call>
+ <menu_item_call name="sort_name" label="Sort by Name">
+ <menu_item_call.on_click function="People.Recent.ViewSort.Action" userdata="sort_name" />
+ </menu_item_call>
+ <menu_item_separator layout="topleft" />
+ <menu_item_call name="view_icons" label="View People Icons">
+ <menu_item_call.on_click function="People.Recent.ViewSort.Action" userdata="view_icons" />
+ </menu_item_call>
+</menu>
diff --git a/indra/newview/skins/default/xui/en/menu_picks.xml b/indra/newview/skins/default/xui/en/menu_picks.xml
new file mode 100644
index 0000000000..7e07a97016
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/menu_picks.xml
@@ -0,0 +1,46 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<context_menu
+ layout="topleft"
+ name="Picks">
+ <menu_item_call
+ label="Info"
+ layout="topleft"
+ name="pick_info">
+ <menu_item_call.on_click
+ function="Pick.Info" />
+ </menu_item_call>
+ <menu_item_call
+ label="Edit"
+ layout="topleft"
+ name="pick_edit"
+ visible="false">
+ <menu_item_call.on_click
+ function="Pick.Edit" />
+ </menu_item_call>
+ <menu_item_call
+ label="Teleport"
+ layout="topleft"
+ name="pick_teleport">
+ <menu_item_call.on_click
+ function="Pick.Teleport" />
+ </menu_item_call>
+ <menu_item_call
+ label="Map"
+ layout="topleft"
+ name="pick_map">
+ <menu_item_call.on_click
+ function="Pick.Map" />
+ </menu_item_call>
+ <menu_item_separator
+ layout="topleft"
+ name="pick_separator"
+ visible="false" />
+ <menu_item_call
+ label="Delete"
+ layout="topleft"
+ name="pick_delete"
+ visible="false">
+ <menu_item_call.on_click
+ function="Pick.Delete" />
+ </menu_item_call>
+</context_menu>
diff --git a/indra/newview/skins/default/xui/en/menu_place.xml b/indra/newview/skins/default/xui/en/menu_place.xml
new file mode 100644
index 0000000000..01f62985ca
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/menu_place.xml
@@ -0,0 +1,46 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<toggleable_menu
+ height="201"
+ layout="topleft"
+ mouse_opaque="false"
+ name="place_overflow_menu"
+ width="128">
+ <menu_item_call
+ label="Make a Landmark"
+ layout="topleft"
+ name="landmark">
+ <menu_item_call.on_click
+ function="Places.OverflowMenu.Action"
+ parameter="landmark" />
+ </menu_item_call>
+ <menu_item_call
+ label="Create Pick"
+ layout="topleft"
+ name="pick">
+ <menu_item_call.on_click
+ function="Places.OverflowMenu.Action"
+ parameter="pick" />
+ </menu_item_call>
+ <menu_item_separator
+ layout="topleft"/>
+ <menu_item_call
+ enabled="false"
+ label="Buy Pass"
+ layout="topleft"
+ name="pass">
+ <menu_item_call.on_click
+ function="Places.OverflowMenu.Action"
+ parameter="pass" />
+ </menu_item_call>
+ <menu_item_separator
+ layout="topleft"/>
+ <menu_item_call
+ enabled="false"
+ label="Edit"
+ layout="topleft"
+ name="edit">
+ <menu_item_call.on_click
+ function="Places.OverflowMenu.Action"
+ parameter="edit" />
+ </menu_item_call>
+</toggleable_menu>
diff --git a/indra/newview/skins/default/xui/en/menu_slurl.xml b/indra/newview/skins/default/xui/en/menu_slurl.xml
new file mode 100644
index 0000000000..ee37d49946
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/menu_slurl.xml
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<menu
+ height="101"
+ layout="topleft"
+ left="100"
+ mouse_opaque="false"
+ name="Popup"
+ top="724"
+ width="128">
+ <menu_item_separator
+ layout="topleft"
+ name="Landmark Separator" />
+ <menu_item_call
+ label="About URL"
+ layout="topleft"
+ name="about_url">
+ <menu_item_call.on_click
+ function="Inventory.DoToSelected"
+ parameter="about" />
+ </menu_item_call>
+ <menu_item_call
+ label="Teleport to URL"
+ layout="topleft"
+ name="teleport_to_url">
+ <menu_item_call.on_click
+ function="Inventory.DoToSelected"
+ parameter="about" />
+ </menu_item_call>
+ <menu_item_call
+ label="Map"
+ layout="topleft"
+ name="show_on_map">
+ <menu_item_call.on_click
+ function="Inventory.DoToSelected"
+ parameter="about" />
+ </menu_item_call>
+</menu>
diff --git a/indra/newview/skins/default/xui/en/menu_viewer.xml b/indra/newview/skins/default/xui/en/menu_viewer.xml
new file mode 100644
index 0000000000..352ec79385
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/menu_viewer.xml
@@ -0,0 +1,3390 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<menu_bar
+ bg_visible="false"
+ follows="left|top|right"
+ layout="topleft"
+ name="Main Menu">
+ <menu
+ label="Me"
+ layout="topleft"
+ name="Me"
+ tear_off="true">
+ <menu_item_call
+ label="Preferences"
+ layout="topleft"
+ name="Preferences"
+ shortcut="control|P">
+ <menu_item_call.on_click
+ function="Floater.Show"
+ parameter="preferences" />
+ </menu_item_call>
+ <menu_item_separator
+ layout="topleft" />
+ <menu
+ label="My Account"
+ layout="topleft"
+ name="My Account"
+ tear_off="true">
+ <menu_item_call
+ label="Account History"
+ layout="topleft"
+ name="Account History">
+ <menu_item_call.on_click
+ function="PromptShowURL"
+ name="AccountHistory_url"
+ parameter="WebLaunchAccountHistory,http://secondlife.com/account/transactions.php" />
+ </menu_item_call>
+ <menu_item_call
+ label="Manage My Account"
+ layout="topleft"
+ name="Manage My Account">
+ <menu_item_call.on_click
+ function="PromptShowURL"
+ name="ManageMyAccount_url"
+ parameter="WebLaunchJoinNow,http://secondlife.com/account/" />
+ </menu_item_call>
+ <menu_item_separator
+ layout="topleft" />
+ <menu_item_call
+ label="My Land"
+ layout="topleft"
+ name="My Land">
+ <menu_item_call.on_click
+ function="ShowFloater"
+ parameter="land_holdings" />
+ </menu_item_call>
+ <menu_item_call
+ label="Buy Land"
+ layout="topleft"
+ name="Buy Land">
+ <menu_item_call.on_click
+ function="ShowFloater"
+ parameter="buy land" />
+ <menu_item_call.on_enable
+ function="World.EnableBuyLand" />
+ </menu_item_call>
+ </menu>
+ <menu_item_call
+ label="Buy L$"
+ layout="topleft"
+ name="Buy and Sell L$">
+ <menu_item_call.on_click
+ function="ShowFloater"
+ parameter="buy currency" />
+ </menu_item_call>
+ <menu_item_separator
+ layout="topleft" />
+ <menu_item_call
+ label="My Profile"
+ layout="topleft"
+ name="Profile">
+ <menu_item_call.on_click
+ function="ShowAgentProfile"
+ parameter="agent" />
+ </menu_item_call>
+ <menu_item_call
+ label="My Appearance"
+ layout="topleft"
+ name="Appearance">
+ <menu_item_call.on_click
+ function="ShowFloater"
+ parameter="appearance" />
+ <menu_item_call.on_enable
+ function="Edit.EnableCustomizeAvatar" />
+ </menu_item_call>
+ <menu_item_check
+ label="My Things"
+ layout="topleft"
+ name="Inventory"
+ shortcut="control|I">
+ <menu_item_check.on_check
+ function="Floater.Visible"
+ parameter="inventory" />
+ <menu_item_check.on_click
+ function="Floater.Toggle"
+ parameter="inventory" />
+ </menu_item_check>
+ <menu_item_call
+ label="My Gestures"
+ layout="topleft"
+ name="Gestures"
+ shortcut="control|G">
+ <menu_item_call.on_click
+ function="ShowFloater"
+ parameter="gestures" />
+ </menu_item_call>
+ <menu_item_separator
+ layout="topleft" />
+ <menu
+ label="Status"
+ layout="topleft"
+ name="Status"
+ tear_off="true">
+ <menu_item_call
+ label="Set Away"
+ layout="topleft"
+ name="Set Away">
+ <menu_item_call.on_click
+ function="World.SetAway" />
+ </menu_item_call>
+ <menu_item_call
+ label="Set Busy"
+ layout="topleft"
+ name="Set Busy">
+ <menu_item_call.on_click
+ function="World.SetBusy" />
+ </menu_item_call>
+ </menu>
+ <menu_item_separator
+ layout="topleft" />
+ <menu_item_call
+ label="Quit [APP_NAME]"
+ layout="topleft"
+ name="Quit"
+ shortcut="control|Q">
+ <menu_item_call.on_click
+ function="File.Quit" />
+ </menu_item_call>
+ </menu>
+ <menu
+ label="Communicate"
+ layout="topleft"
+ name="Communicate"
+ tear_off="true">
+ <menu_item_check
+ label="My Friends"
+ layout="topleft"
+ name="My Friends"
+ shortcut="control|shift|F">
+ <menu_item_check.on_check
+ function="Floater.Visible"
+ parameter="contacts.friends" />
+ <menu_item_check.on_click
+ function="Floater.Toggle"
+ parameter="contacts.friends" />
+ </menu_item_check>
+ <menu_item_call
+ label="My Groups"
+ layout="topleft"
+ name="My Groups">
+ <menu_item_call.on_click
+ function="Floater.Show"
+ parameter="contacts.groups" />
+ </menu_item_call>
+ <menu_item_separator
+ layout="topleft" />
+ <!--menu_item_call
+ label="Chat"
+ layout="topleft"
+ name="Chat">
+ <menu_item_call.on_click
+ function="World.Chat" />
+ </menu_item_call-->
+ <menu_item_check
+ label="Local Chat"
+ layout="topleft"
+ name="Nearby Chat"
+ shortcut="control|H">
+ <menu_item_check.on_check
+ function="Floater.Visible"
+ parameter="nearby_chat" />
+ <menu_item_check.on_click
+ function="Floater.Toggle"
+ parameter="nearby_chat" />
+ </menu_item_check>
+ <menu_item_check
+ label="Nearby Speakers"
+ layout="topleft"
+ name="Active Speakers"
+ shortcut="control|shift|A">
+ <menu_item_check.on_check
+ function="Floater.Visible"
+ parameter="active_speakers" />
+ <menu_item_check.on_click
+ function="Floater.Toggle"
+ parameter="active_speakers" />
+ </menu_item_check>
+ <!--menu_item_check
+ label="Block List"
+ layout="topleft"
+ name="Mute List">
+ <menu_item_check.on_check
+ function="Floater.Visible"
+ parameter="mute" />
+ <menu_item_check.on_click
+ function="Floater.Toggle"
+ parameter="mute" />
+ </menu_item_check-->
+ <menu_item_separator
+ layout="topleft" />
+ <menu_item_check
+ label="(Legacy) Communicate"
+ layout="topleft"
+ name="Instant Message"
+ shortcut="control|T">
+ <menu_item_check.on_check
+ function="Floater.Visible"
+ parameter="communicate" />
+ <menu_item_check.on_click
+ function="Floater.Toggle"
+ parameter="communicate" />
+ </menu_item_check>
+ <menu_item_call
+ label="(Temp) Media Remote Ctrl"
+ layout="topleft"
+ name="Preferences"
+ shortcut="control|alt|M">
+ <menu_item_call.on_click
+ function="Floater.Toggle"
+ parameter="media_remote_ctrl" />
+ </menu_item_call>
+ </menu>
+ <menu
+ label="World"
+ layout="topleft"
+ name="World"
+ tear_off="true">
+ <menu_item_check
+ label="Camera Controls"
+ layout="topleft"
+ name="Camera Controls">
+ <menu_item_check.on_check
+ function="Floater.Visible"
+ parameter="camera" />
+ <menu_item_check.on_click
+ function="Floater.Toggle"
+ parameter="camera" />
+ </menu_item_check>
+ <menu_item_check
+ label="Movement Controls"
+ layout="topleft"
+ name="Movement Controls">
+ <menu_item_check.on_check
+ function="Floater.Visible"
+ parameter="moveview" />
+ <menu_item_check.on_click
+ function="Floater.Toggle"
+ parameter="moveview" />
+ </menu_item_check>
+ <menu_item_separator
+ layout="topleft" />
+ <menu_item_call
+ label="Place Information"
+ layout="topleft"
+ name="About Land">
+ <menu_item_call.on_click
+ function="Floater.Show"
+ parameter="about_land" />
+ </menu_item_call>
+ <menu_item_call
+ label="Region/Estate"
+ layout="topleft"
+ name="Region/Estate">
+ <menu_item_call.on_click
+ function="Floater.Show"
+ parameter="region_info" />
+ </menu_item_call>
+ <menu_item_separator
+ layout="topleft" />
+ <menu
+ label="Landmarks"
+ layout="topleft"
+ name="Landmarks"
+ tear_off="true">
+ <menu_item_call
+ label="Create Landmark Here"
+ layout="topleft"
+ name="Create Landmark Here">
+ <menu_item_call.on_click
+ function="World.CreateLandmark" />
+ <menu_item_call.on_enable
+ function="World.EnableCreateLandmark" />
+ </menu_item_call>
+ <menu_item_call
+ label="Set Home to Here"
+ layout="topleft"
+ name="Set Home to Here">
+ <menu_item_call.on_click
+ function="World.SetHomeLocation" />
+ <menu_item_call.on_enable
+ function="World.EnableSetHomeLocation" />
+ </menu_item_call>
+ <menu_item_call
+ label="Teleport Home"
+ layout="topleft"
+ name="Teleport Home"
+ shortcut="control|shift|H">
+ <menu_item_call.on_click
+ function="World.TeleportHome" />
+ <menu_item_call.on_enable
+ function="World.EnableTeleportHome" />
+ </menu_item_call>
+ </menu>
+ <menu_item_check
+ label="Search"
+ layout="topleft"
+ name="Search"
+ shortcut="control|F">
+ <menu_item_check.on_check
+ function="Floater.Visible"
+ parameter="search" />
+ <menu_item_check.on_click
+ function="Floater.Toggle"
+ parameter="search" />
+ </menu_item_check>
+ <menu_item_check
+ label="World Map"
+ layout="topleft"
+ name="World Map"
+ shortcut="control|M">
+ <menu_item_check.on_check
+ function="Floater.Visible"
+ parameter="world_map" />
+ <menu_item_check.on_click
+ function="Floater.Toggle"
+ parameter="world_map" />
+ </menu_item_check>
+ <menu_item_check
+ label="Mini-Map"
+ layout="topleft"
+ name="Mini-Map"
+ shortcut="control|shift|M">
+ <menu_item_check.on_check
+ function="Floater.Visible"
+ parameter="mini_map" />
+ <menu_item_check.on_click
+ function="Floater.Toggle"
+ parameter="mini_map" />
+ </menu_item_check>
+ <menu_item_separator
+ layout="topleft" />
+ <menu_item_call
+ label="Take Snapshot"
+ layout="topleft"
+ name="Take Snapshot"
+ shortcut="control|shift|S">
+ <menu_item_call.on_click
+ function="Floater.Show"
+ parameter="snapshot" />
+ </menu_item_call>
+ <menu_item_separator
+ layout="topleft" />
+ <menu
+ create_jump_keys="true"
+ label="Sun Settings"
+ layout="topleft"
+ name="Environment Settings"
+ tear_off="true">
+ <menu_item_call
+ label="Sunrise"
+ layout="topleft"
+ name="Sunrise">
+ <menu_item_call.on_click
+ function="World.EnvSettings"
+ parameter="sunrise" />
+ </menu_item_call>
+ <menu_item_call
+ label="Midday"
+ layout="topleft"
+ name="Noon"
+ shortcut="control|shift|Y">
+ <menu_item_call.on_click
+ function="World.EnvSettings"
+ parameter="noon" />
+ </menu_item_call>
+ <menu_item_call
+ label="Sunset"
+ layout="topleft"
+ name="Sunset"
+ shortcut="control|shift|N">
+ <menu_item_call.on_click
+ function="World.EnvSettings"
+ parameter="sunset" />
+ </menu_item_call>
+ <menu_item_call
+ label="Midnight"
+ layout="topleft"
+ name="Midnight">
+ <menu_item_call.on_click
+ function="World.EnvSettings"
+ parameter="midnight" />
+ </menu_item_call>
+ <menu_item_call
+ label="Use region settings"
+ layout="topleft"
+ name="Revert to Region Default">
+ <menu_item_call.on_click
+ function="World.EnvSettings"
+ parameter="default" />
+ </menu_item_call>
+ <menu_item_separator
+ layout="topleft" />
+ <menu_item_call
+ label="Environment Editor"
+ layout="topleft"
+ name="Environment Editor">
+ <menu_item_call.on_click
+ function="World.EnvSettings"
+ parameter="editor" />
+ </menu_item_call>
+ </menu>
+ <menu_item_separator
+ layout="topleft" />
+ <menu_item_check
+ label="Build"
+ layout="topleft"
+ name="Build"
+ shortcut="B">
+ <menu_item_check.on_check
+ function="Build.Active" />
+ <menu_item_check.on_click
+ function="Build.Toggle" />
+ <menu_item_check.on_enable
+ function="Build.Enabled" />
+ </menu_item_check>
+ </menu>
+ <menu
+ label="Help"
+ layout="topleft"
+ name="Help"
+ tear_off="true">
+ <menu_item_call
+ label="[SECOND_LIFE] Help"
+ layout="topleft"
+ name="Second Life Help"
+ shortcut="F1">
+ <menu_item_call.on_click
+ function="ShowFloater"
+ parameter="help f1" />
+ </menu_item_call>
+ <menu_item_call
+ label="Tutorial"
+ layout="topleft"
+ name="Tutorial">
+ <menu_item_call.on_click
+ function="Floater.Show"
+ parameter="hud" />
+ </menu_item_call>
+ <menu_item_check
+ label="Show Quick Tips"
+ layout="topleft"
+ name="Show Quick Tips">
+ <menu_item_check.on_check
+ function="Help.CheckShowFirstTimeTip" />
+ <menu_item_check.on_click
+ function="Help.ShowQuickTips" />
+ </menu_item_check>
+ <menu_item_separator
+ layout="topleft" />
+ <menu_item_call
+ label="Report Bug..."
+ layout="topleft"
+ name="ReportBug">
+ <menu_item_call.on_click
+ function="PromptShowURL"
+ name="ReportBug_url"
+ parameter="hud,http://help.secondlife.com/en/bugreport/" />
+ </menu_item_call>
+ <menu_item_call
+ label="Report Abuse..."
+ layout="topleft"
+ name="Report Abuse">
+ <menu_item_call.on_click
+ function="ShowFloater"
+ parameter="complaint reporter" />
+ </menu_item_call>
+ <menu_item_separator
+ layout="topleft" />
+ <menu_item_call
+ label="About [APP_NAME]"
+ layout="topleft"
+ name="About Second Life">
+ <menu_item_call.on_click
+ function="Floater.Show"
+ parameter="sl_about" />
+ </menu_item_call>
+ </menu>
+ <menu
+ create_jump_keys="true"
+ label="Tools"
+ layout="topleft"
+ name="BuildTools"
+ tear_off="true"
+ visible="false">
+ <menu
+ create_jump_keys="true"
+ label="Edit"
+ layout="topleft"
+ name="Edit"
+ tear_off="true">
+ <menu_item_call
+ label="Undo"
+ layout="topleft"
+ name="Undo"
+ shortcut="control|Z">
+ <menu_item_call.on_click
+ function="Edit.Undo" />
+ <menu_item_call.on_enable
+ function="Edit.EnableUndo" />
+ </menu_item_call>
+ <menu_item_call
+ label="Redo"
+ layout="topleft"
+ name="Redo"
+ shortcut="control|Y">
+ <menu_item_call.on_click
+ function="Edit.Redo" />
+ <menu_item_call.on_enable
+ function="Edit.EnableRedo" />
+ </menu_item_call>
+ <menu_item_separator
+ layout="topleft" />
+ <menu_item_call
+ label="Cut"
+ layout="topleft"
+ name="Cut"
+ shortcut="control|X">
+ <menu_item_call.on_click
+ function="Edit.Cut" />
+ <menu_item_call.on_enable
+ function="Edit.EnableCut" />
+ </menu_item_call>
+ <menu_item_call
+ label="Copy"
+ layout="topleft"
+ name="Copy"
+ shortcut="control|C">
+ <menu_item_call.on_click
+ function="Edit.Copy" />
+ <menu_item_call.on_enable
+ function="Edit.EnableCopy" />
+ </menu_item_call>
+ <menu_item_call
+ label="Paste"
+ layout="topleft"
+ name="Paste"
+ shortcut="control|V">
+ <menu_item_call.on_click
+ function="Edit.Paste" />
+ <menu_item_call.on_enable
+ function="Edit.EnablePaste" />
+ </menu_item_call>
+ <menu_item_call
+ label="Delete"
+ layout="topleft"
+ name="Delete"
+ shortcut="Del">
+ <menu_item_call.on_click
+ function="Edit.Delete" />
+ <menu_item_call.on_enable
+ function="Edit.EnableDelete" />
+ </menu_item_call>
+ <menu_item_call
+ label="Duplicate"
+ layout="topleft"
+ name="Duplicate"
+ shortcut="control|D">
+ <menu_item_call.on_click
+ function="Edit.Duplicate" />
+ <menu_item_call.on_enable
+ function="Edit.EnableDuplicate" />
+ </menu_item_call>
+ <menu_item_separator
+ layout="topleft" />
+ <menu_item_call
+ label="Select All"
+ layout="topleft"
+ name="Select All"
+ shortcut="control|A">
+ <menu_item_call.on_click
+ function="Edit.SelectAll" />
+ <menu_item_call.on_enable
+ function="Edit.EnableSelectAll" />
+ </menu_item_call>
+ <menu_item_call
+ label="Deselect"
+ layout="topleft"
+ name="Deselect"
+ shortcut="control|E">
+ <menu_item_call.on_click
+ function="Edit.Deselect" />
+ <menu_item_call.on_enable
+ function="Edit.EnableDeselect" />
+ </menu_item_call>
+ </menu>
+ <menu
+ create_jump_keys="true"
+ label="Options"
+ layout="topleft"
+ name="Options"
+ tear_off="true">
+ <menu_item_check
+ label="Edit Linked Parts"
+ layout="topleft"
+ name="Edit Linked Parts">
+ <menu_item_check.on_check
+ control="EditLinkedParts" />
+ <menu_item_check.on_click
+ function="Tools.EditLinkedParts"
+ parameter="EditLinkedParts" />
+ <menu_item_check.on_enable
+ function="Tools.EnableToolNotPie" />
+ </menu_item_check>
+ <menu_item_call
+ label="Set Default Permissions"
+ layout="topleft"
+ name="perm prefs">
+ <menu_item_call.on_click
+ function="Floater.Toggle"
+ parameter="perm_prefs" />
+ </menu_item_call>
+ <menu_item_call
+ label="Show Script Warning/Error Window"
+ layout="topleft"
+ name="Show Script Warning/Error Window">
+ <menu_item_call.on_click
+ function="ShowFloater"
+ parameter="script errors" />
+ </menu_item_call>
+ <menu_item_separator
+ layout="topleft" />
+ <menu
+ create_jump_keys="true"
+ label="Selection"
+ layout="topleft"
+ name="Selection"
+ tear_off="true">
+ <menu_item_check
+ label="Select Only My Objects"
+ layout="topleft"
+ name="Select Only My Objects">
+ <menu_item_check.on_check
+ control="SelectOwnedOnly" />
+ <menu_item_check.on_click
+ function="Tools.SelectOnlyMyObjects"
+ parameter="agents" />
+ </menu_item_check>
+ <menu_item_check
+ label="Select Only Movable Objects"
+ layout="topleft"
+ name="Select Only Movable Objects">
+ <menu_item_check.on_check
+ control="SelectMovableOnly" />
+ <menu_item_check.on_click
+ function="Tools.SelectOnlyMovableObjects"
+ parameter="movable" />
+ </menu_item_check>
+ <menu_item_check
+ label="Select By Surrounding"
+ layout="topleft"
+ name="Select By Surrounding">
+ <menu_item_check.on_check
+ control="RectangleSelectInclusive" />
+ <menu_item_check.on_click
+ function="Tools.SelectBySurrounding" />
+ </menu_item_check>
+ </menu>
+ <menu
+ create_jump_keys="true"
+ label="Show"
+ layout="topleft"
+ name="Show"
+ tear_off="true">
+ <menu_item_check
+ label="Show Hidden Selection"
+ layout="topleft"
+ name="Show Hidden Selection">
+ <menu_item_check.on_check
+ control="RenderHiddenSelections" />
+ <menu_item_check.on_click
+ function="Tools.ShowHiddenSelection" />
+ </menu_item_check>
+ <menu_item_check
+ label="Show Light Radius for Selection"
+ layout="topleft"
+ name="Show Light Radius for Selection">
+ <menu_item_check.on_check
+ control="RenderLightRadius" />
+ <menu_item_check.on_click
+ function="Tools.ShowSelectionLightRadius" />
+ </menu_item_check>
+ <menu_item_check
+ label="Show Selection Beam"
+ layout="topleft"
+ name="Show Selection Beam">
+ <menu_item_check.on_check
+ control="ShowSelectionBeam" />
+ <menu_item_check.on_click
+ function="ToggleControl"
+ parameter="ShowSelectionBeam" />
+ </menu_item_check>
+ </menu>
+ <menu
+ create_jump_keys="true"
+ label="Grid"
+ layout="topleft"
+ name="Grid"
+ tear_off="true">
+ <menu_item_check
+ label="Snap to Grid"
+ layout="topleft"
+ name="Snap to Grid"
+ shortcut="G">
+ <menu_item_check.on_check
+ control="SnapEnabled" />
+ <menu_item_check.on_click
+ function="ToggleControl"
+ parameter="SnapEnabled" />
+ <menu_item_check.on_enable
+ function="Tools.EnableToolNotPie" />
+ </menu_item_check>
+ <menu_item_call
+ label="Snap Object XY to Grid"
+ layout="topleft"
+ name="Snap Object XY to Grid"
+ shortcut="shift|X">
+ <menu_item_call.on_click
+ function="Tools.SnapObjectXY" />
+ <menu_item_call.on_enable
+ function="Tools.EnableToolNotPie" />
+ </menu_item_call>
+ <menu_item_call
+ label="Use Selection for Grid"
+ layout="topleft"
+ name="Use Selection for Grid"
+ shortcut="shift|G">
+ <menu_item_call.on_click
+ function="Tools.UseSelectionForGrid" />
+ <menu_item_call.on_enable
+ function="SomethingSelected" />
+ </menu_item_call>
+ <menu_item_call
+ label="Grid Options"
+ layout="topleft"
+ name="Grid Options"
+ shortcut="control|shift|B">
+ <menu_item_call.on_click
+ function="Floater.Show"
+ parameter="build_options" />
+ <menu_item_call.on_enable
+ function="Tools.EnableToolNotPie" />
+ </menu_item_call>
+ </menu>
+ <menu
+ create_jump_keys="true"
+ label="Beacons"
+ layout="topleft"
+ name="Beacons"
+ tear_off="true">
+ <menu_item_check
+ label="Beacons"
+ layout="topleft"
+ name="beacons"
+ shortcut="control|alt|shift|N">
+ <menu_item_check.on_check
+ function="Floater.Visible"
+ parameter="beacons" />
+ <menu_item_check.on_click
+ function="Floater.Toggle"
+ parameter="beacons" />
+ </menu_item_check>
+ <menu_item_check
+ label="Cheesy Beacon"
+ layout="topleft"
+ name="Cheesy Beacon">
+ <menu_item_check.on_check
+ function="CheckControl"
+ parameter="CheesyBeacon" />
+ <menu_item_check.on_click
+ function="ToggleControl"
+ parameter="CheesyBeacon" />
+ </menu_item_check>
+ </menu>
+ <menu
+ create_jump_keys="true"
+ label="Land"
+ layout="topleft"
+ name="Land"
+ tear_off="true">
+ <menu_item_check
+ label="Property Lines"
+ layout="topleft"
+ name="Property Lines"
+ shortcut="control|alt|shift|P">
+ <menu_item_check.on_check
+ control="ShowPropertyLines" />
+ <menu_item_check.on_click
+ function="ToggleControl"
+ parameter="ShowPropertyLines" />
+ </menu_item_check>
+ <menu_item_check
+ label="Land Owners"
+ layout="topleft"
+ name="Land Owners">
+ <menu_item_check.on_check
+ control="ShowParcelOwners" />
+ <menu_item_check.on_click
+ function="ToggleControl"
+ parameter="ShowParcelOwners" />
+ </menu_item_check>
+ <menu_item_check
+ label="Ban Lines"
+ layout="topleft"
+ name="Ban Lines">
+ <menu_item_check.on_check
+ control="ShowBanLines" />
+ <menu_item_check.on_click
+ function="ToggleControl"
+ parameter="ShowBanLines" />
+ </menu_item_check>
+ </menu>
+ </menu>
+ <menu
+ create_jump_keys="true"
+ label="Actions"
+ layout="topleft"
+ name="Actions"
+ tear_off="true">
+ <menu_item_call
+ label="Link"
+ layout="topleft"
+ name="Link"
+ shortcut="control|L">
+ <menu_item_call.on_click
+ function="Tools.Link" />
+ <menu_item_call.on_enable
+ function="Tools.EnableLink" />
+ </menu_item_call>
+ <menu_item_call
+ label="Unlink"
+ layout="topleft"
+ name="Unlink"
+ shortcut="control|shift|L">
+ <menu_item_call.on_click
+ function="Tools.Unlink" />
+ <menu_item_call.on_enable
+ function="Tools.EnableUnlink" />
+ </menu_item_call>
+ <menu_item_separator
+ layout="topleft" />
+ <menu_item_call
+ label="Focus on Selection"
+ layout="topleft"
+ name="Focus on Selection"
+ shortcut="H">
+ <menu_item_call.on_click
+ function="Tools.LookAtSelection"
+ parameter="focus" />
+ <menu_item_call.on_enable
+ function="Tools.SomethingSelectedNoHUD" />
+ </menu_item_call>
+ <menu_item_call
+ label="Zoom to Selection"
+ layout="topleft"
+ name="Zoom to Selection"
+ shortcut="shift|H">
+ <menu_item_call.on_click
+ function="Tools.LookAtSelection"
+ parameter="zoom" />
+ <menu_item_call.on_enable
+ function="Tools.SomethingSelectedNoHUD" />
+ </menu_item_call>
+ <menu_item_separator
+ layout="topleft" />
+ <menu_item_call
+ label="Buy Object"
+ layout="topleft"
+ name="Menu Object Take"
+ visible="false">
+ <menu_item_call.on_click
+ function="Tools.BuyOrTake" />
+ <menu_item_call.on_enable
+ function="Tools.EnableBuyOrTake"
+ name="EnableBuyOrTake"
+ parameter="Buy,Take" />
+ </menu_item_call>
+ <menu_item_call
+ label="Take Copy"
+ layout="topleft"
+ name="Take Copy">
+ <menu_item_call.on_click
+ function="Tools.TakeCopy" />
+ <menu_item_call.on_enable
+ function="Tools.EnableTakeCopy" />
+ </menu_item_call>
+ <menu_item_call
+ label="Save Object Back to My Inventory"
+ layout="topleft"
+ name="Save Object Back to My Inventory">
+ <menu_item_call.on_click
+ function="Tools.SaveToInventory" />
+ <menu_item_call.on_enable
+ function="Tools.EnableSaveToInventory" />
+ </menu_item_call>
+ <menu_item_call
+ label="Save Object Back to Object Contents"
+ layout="topleft"
+ name="Save Object Back to Object Contents">
+ <menu_item_call.on_click
+ function="Tools.SaveToObjectInventory" />
+ <menu_item_call.on_enable
+ function="Tools.EnableSaveToObjectInventory" />
+ </menu_item_call>
+ <menu_item_separator
+ layout="topleft" />
+ <menu
+ create_jump_keys="true"
+ label="Recompile Scripts in Selection"
+ layout="topleft"
+ name="Recompile Scripts in Selection"
+ tear_off="true">
+ <menu_item_call
+ label="Mono"
+ layout="topleft"
+ name="Mono">
+ <menu_item_call.on_click
+ function="Tools.SelectedScriptAction"
+ parameter="compile mono" />
+ <menu_item_call.on_enable
+ function="EditableSelectedMono" />
+ </menu_item_call>
+ <menu_item_call
+ label="LSL"
+ layout="topleft"
+ name="LSL">
+ <menu_item_call.on_click
+ function="Tools.SelectedScriptAction"
+ parameter="compile lsl" />
+ <menu_item_call.on_enable
+ function="EditableSelected" />
+ </menu_item_call>
+ </menu>
+ <menu_item_call
+ label="Reset Scripts in Selection"
+ layout="topleft"
+ name="Reset Scripts in Selection">
+ <menu_item_call.on_click
+ function="Tools.SelectedScriptAction"
+ parameter="reset" />
+ <menu_item_call.on_enable
+ function="EditableSelected" />
+ </menu_item_call>
+ <menu_item_call
+ label="Set Scripts to Running in Selection"
+ layout="topleft"
+ name="Set Scripts to Running in Selection">
+ <menu_item_call.on_click
+ function="Tools.SelectedScriptAction"
+ parameter="start" />
+ <menu_item_call.on_enable
+ function="EditableSelected" />
+ </menu_item_call>
+ <menu_item_call
+ label="Set Scripts to Not Running in Selection"
+ layout="topleft"
+ name="Set Scripts to Not Running in Selection">
+ <menu_item_call.on_click
+ function="Tools.SelectedScriptAction"
+ parameter="stop" />
+ <menu_item_call.on_enable
+ function="EditableSelected" />
+ </menu_item_call>
+ </menu>
+ </menu>
+ <menu
+ label="Advanced"
+ layout="topleft"
+ name="Advanced"
+ tear_off="true"
+ visible="false">
+ <menu
+ label="Shortcuts"
+ layout="topleft"
+ name="Shortcuts"
+ tear_off="true"
+ visible="false">
+ <menu_item_call
+ enabled="false"
+ label="Release Keys"
+ layout="topleft"
+ name="Release Keys">
+ <menu_item_call.on_click
+ function="Tools.ReleaseKeys"
+ parameter="" />
+ <menu_item_call.on_enable
+ function="Tools.EnableReleaseKeys"
+ parameter="" />
+ </menu_item_call>
+ <menu_item_call
+ label="Set UI Size to Default"
+ layout="topleft"
+ name="Set UI Size to Default">
+ <menu_item_call.on_click
+ function="View.DefaultUISize" />
+ </menu_item_call>
+ <menu_item_separator
+ layout="topleft" />
+ <menu_item_check
+ label="Always Run"
+ layout="topleft"
+ name="Always Run"
+ shortcut="control|R">
+ <menu_item_check.on_check
+ function="World.CheckAlwaysRun" />
+ <menu_item_check.on_click
+ function="World.AlwaysRun" />
+ </menu_item_check>
+ <menu_item_check
+ control_name="FlyBtnState"
+ label="Fly"
+ layout="topleft"
+ name="Fly"
+ shortcut="Home">
+ <menu_item_check.on_click
+ function="Agent.toggleFlying" />
+ <menu_item_check.on_enable
+ function="Agent.enableFlying" />
+ </menu_item_check>
+ <menu_item_separator
+ layout="topleft" />
+ <menu_item_call
+ label="Close Window"
+ layout="topleft"
+ name="Close Window"
+ shortcut="control|W">
+ <menu_item_call.on_click
+ function="File.CloseWindow" />
+ <menu_item_call.on_enable
+ function="File.EnableCloseWindow" />
+ </menu_item_call>
+ <menu_item_call
+ label="Close All Windows"
+ layout="topleft"
+ name="Close All Windows"
+ shortcut="control|shift|W">
+ <menu_item_call.on_click
+ function="File.CloseAllWindows" />
+ <menu_item_call.on_enable
+ function="File.EnableCloseAllWindows" />
+ </menu_item_call>
+ <menu_item_separator
+ layout="topleft" />
+ <menu_item_call
+ label="Snapshot to Disk"
+ layout="topleft"
+ name="Snapshot to Disk"
+ shortcut="control|`"
+ use_mac_ctrl="true">
+ <menu_item_call.on_click
+ function="File.TakeSnapshotToDisk" />
+ </menu_item_call>
+ <menu_item_separator
+ layout="topleft" />
+ <menu_item_call
+ label="Mouselook"
+ layout="topleft"
+ name="Mouselook"
+ shortcut="M">
+ <menu_item_call.on_click
+ function="View.Mouselook" />
+ <menu_item_call.on_enable
+ function="View.EnableMouselook" />
+ </menu_item_call>
+ <menu_item_check
+ label="Joystick Flycam"
+ layout="topleft"
+ name="Joystick Flycam"
+ shortcut="alt|shift|F">
+ <menu_item_check.on_check
+ function="View.CheckJoystickFlycam" />
+ <menu_item_check.on_click
+ function="View.JoystickFlycam" />
+ <menu_item_check.on_enable
+ function="View.EnableJoystickFlycam" />
+ </menu_item_check>
+ <menu_item_call
+ label="Reset View"
+ layout="topleft"
+ name="Reset View"
+ shortcut="Esc">
+ <menu_item_call.on_click
+ function="View.ResetView" />
+ </menu_item_call>
+ <menu_item_call
+ label="Look at Last Chatter"
+ layout="topleft"
+ name="Look at Last Chatter"
+ shortcut="control|\">
+ <menu_item_call.on_click
+ function="View.LookAtLastChatter" />
+ <menu_item_call.on_enable
+ function="View.EnableLastChatter" />
+ </menu_item_call>
+ <menu_item_separator
+ layout="topleft" />
+ <menu
+ create_jump_keys="true"
+ label="Select Tool"
+ layout="topleft"
+ name="Select Tool"
+ tear_off="true">
+ <menu_item_call
+ label="Focus"
+ layout="topleft"
+ name="Focus"
+ shortcut="control|1">
+ <menu_item_call.on_click
+ function="Tools.SelectTool"
+ parameter="focus" />
+ </menu_item_call>
+ <menu_item_call
+ label="Move"
+ layout="topleft"
+ name="Move"
+ shortcut="control|2">
+ <menu_item_call.on_click
+ function="Tools.SelectTool"
+ parameter="move" />
+ </menu_item_call>
+ <menu_item_call
+ label="Edit"
+ layout="topleft"
+ name="Edit"
+ shortcut="control|3">
+ <menu_item_call.on_click
+ function="Tools.SelectTool"
+ parameter="edit" />
+ </menu_item_call>
+ <menu_item_call
+ label="Create"
+ layout="topleft"
+ name="Create"
+ shortcut="control|4">
+ <menu_item_call.on_click
+ function="Tools.SelectTool"
+ parameter="create" />
+ </menu_item_call>
+ <menu_item_call
+ label="Land"
+ layout="topleft"
+ name="Land"
+ shortcut="control|5">
+ <menu_item_call.on_click
+ function="Tools.SelectTool"
+ parameter="land" />
+ </menu_item_call>
+ </menu>
+ <menu_item_separator
+ layout="topleft" />
+ <menu_item_call
+ label="Zoom In"
+ layout="topleft"
+ name="Zoom In"
+ shortcut="control|0">
+ <menu_item_call.on_click
+ function="View.ZoomIn" />
+ </menu_item_call>
+ <menu_item_call
+ label="Zoom Default"
+ layout="topleft"
+ name="Zoom Default"
+ shortcut="control|9">
+ <menu_item_call.on_click
+ function="View.ZoomDefault" />
+ </menu_item_call>
+ <menu_item_call
+ label="Zoom Out"
+ layout="topleft"
+ name="Zoom Out"
+ shortcut="control|8">
+ <menu_item_call.on_click
+ function="View.ZoomOut" />
+ </menu_item_call>
+ <menu_item_separator
+ layout="topleft" />
+ <menu_item_call
+ label="Toggle Fullscreen"
+ layout="topleft"
+ name="Toggle Fullscreen"
+ shortcut="alt|Enter">
+ <menu_item_call.on_click
+ function="View.Fullscreen" />
+ </menu_item_call>
+ </menu>
+ <menu_item_check
+ label="Go Away/AFK When Idle"
+ layout="topleft"
+ name="Go Away/AFK When Idle">
+ <menu_item_check.on_check
+ function="CheckControl"
+ parameter="AllowIdleAFK" />
+ <menu_item_check.on_click
+ function="ToggleControl"
+ parameter="AllowIdleAFK" />
+ </menu_item_check>
+ <menu_item_call
+ label="Stop Animating My Avatar"
+ layout="topleft"
+ name="Stop Animating My Avatar">
+ <menu_item_call.on_click
+ function="Tools.StopAllAnimations" />
+ </menu_item_call>
+ <menu_item_call
+ label="Rebake Texture"
+ layout="topleft"
+ name="Rebake Texture"
+ shortcut="control|alt|R">
+ <menu_item_call.on_click
+ function="Advanced.RebakeTextures" />
+ </menu_item_call>
+ <menu_item_check
+ label="Limit Select Distance"
+ layout="topleft"
+ name="Limit Select Distance">
+ <menu_item_check.on_check
+ function="CheckControl"
+ parameter="LimitSelectDistance" />
+ <menu_item_check.on_click
+ function="ToggleControl"
+ parameter="LimitSelectDistance" />
+ </menu_item_check>
+ <menu_item_check
+ label="Disable Camera Constraints"
+ layout="topleft"
+ name="Disable Camera Distance">
+ <menu_item_check.on_check
+ function="CheckControl"
+ parameter="DisableCameraConstraints" />
+ <menu_item_check.on_click
+ function="ToggleControl"
+ parameter="DisableCameraConstraints" />
+ </menu_item_check>
+ <menu_item_separator
+ layout="topleft" />
+ <menu_item_check
+ label="High-res Snapshot"
+ layout="topleft"
+ name="HighResSnapshot">
+ <menu_item_check.on_check
+ function="CheckControl"
+ parameter="HighResSnapshot" />
+ <menu_item_check.on_click
+ function="ToggleControl"
+ parameter="HighResSnapshot" />
+ </menu_item_check>
+ <menu_item_check
+ label="Quiet Snapshots to Disk"
+ layout="topleft"
+ name="QuietSnapshotsToDisk">
+ <menu_item_check.on_check
+ function="CheckControl"
+ parameter="QuietSnapshotsToDisk" />
+ <menu_item_check.on_click
+ function="ToggleControl"
+ parameter="QuietSnapshotsToDisk" />
+ </menu_item_check>
+ <menu_item_check
+ label="Compress Snapshots to Disk"
+ layout="topleft"
+ name="CompressSnapshotsToDisk">
+ <menu_item_check.on_check
+ function="CheckControl"
+ parameter="CompressSnapshotsToDisk" />
+ <menu_item_check.on_click
+ function="ToggleControl"
+ parameter="CompressSnapshotsToDisk" />
+ </menu_item_check>
+ <menu_item_call
+ label="Save Texture As..."
+ layout="topleft"
+ name="Save Texture As">
+ <menu_item_call.on_click
+ function="File.SaveTexture" />
+ <menu_item_call.on_enable
+ function="File.EnableSaveAs" />
+ </menu_item_call>
+ <menu_item_separator
+ layout="topleft" />
+ <menu
+ create_jump_keys="true"
+ label="Performance Tools"
+ layout="topleft"
+ name="Performance Tools"
+ tear_off="true">
+ <menu_item_call
+ label="Lag Meter"
+ layout="topleft"
+ name="Lag Meter">
+ <menu_item_call.on_click
+ function="Floater.Show"
+ parameter="lagmeter" />
+ </menu_item_call>
+ <menu_item_check
+ label="Statistics Bar"
+ layout="topleft"
+ name="Statistics Bar"
+ shortcut="control|shift|1">
+ <menu_item_check.on_check
+ function="Floater.Visible"
+ parameter="stats" />
+ <menu_item_check.on_click
+ function="Floater.Toggle"
+ parameter="stats" />
+ </menu_item_check>
+ </menu>
+ <menu
+ create_jump_keys="true"
+ label="Highlighting and Visibility"
+ layout="topleft"
+ name="Highlighting and Visibility"
+ tear_off="true">
+ <menu_item_check
+ label="Highlight Transparent"
+ layout="topleft"
+ name="Highlight Transparent"
+ shortcut="control|alt|T">
+ <menu_item_check.on_check
+ function="View.CheckHighlightTransparent" />
+ <menu_item_check.on_click
+ function="View.HighlightTransparent" />
+ </menu_item_check>
+ <menu_item_check
+ label="Hide Particles"
+ layout="topleft"
+ name="Hide Particles"
+ shortcut="control|alt|shift|=">
+ <menu_item_check.on_check
+ function="View.CheckRenderType"
+ parameter="hideparticles" />
+ <menu_item_check.on_click
+ function="View.ToggleRenderType"
+ parameter="hideparticles" />
+ </menu_item_check>
+ <menu_item_check
+ label="Show HUD Attachments"
+ layout="topleft"
+ name="Show HUD Attachments"
+ shortcut="alt|shift|H">
+ <menu_item_check.on_check
+ function="View.CheckHUDAttachments" />
+ <menu_item_check.on_click
+ function="View.ShowHUDAttachments" />
+ </menu_item_check>
+ <menu_item_check
+ label="Hide Selected"
+ layout="topleft"
+ name="Hide Selected">
+ <menu_item_check.on_check
+ function="CheckControl"
+ parameter="HideSelectedObjects" />
+ <menu_item_check.on_click
+ function="ToggleControl"
+ parameter="HideSelectedObjects" />
+ </menu_item_check>
+ <menu_item_check
+ label="Show Mouselook Crosshairs"
+ layout="topleft"
+ name="ShowCrosshairs">
+ <menu_item_check.on_check
+ function="CheckControl"
+ parameter="ShowCrosshairs" />
+ <menu_item_check.on_click
+ function="ToggleControl"
+ parameter="ShowCrosshairs" />
+ </menu_item_check>
+ </menu>
+ <menu
+ create_jump_keys="true"
+ label="Hover Tips"
+ layout="topleft"
+ name="Hover Tips"
+ tear_off="true">
+ <menu_item_check
+ label="Show Tips"
+ layout="topleft"
+ name="Show Tips"
+ shortcut="control|shift|T">
+ <menu_item_check.on_check
+ function="View.CheckShowHoverTips" />
+ <menu_item_check.on_click
+ function="View.ShowHoverTips" />
+ </menu_item_check>
+ <menu_item_separator
+ layout="topleft" />
+ <menu_item_check
+ label="Land Tips"
+ layout="topleft"
+ name="Land Tips">
+ <menu_item_check.on_check
+ control="ShowLandHoverTip" />
+ <menu_item_check.on_click
+ function="ToggleControl"
+ parameter="ShowLandHoverTip" />
+ <menu_item_check.on_enable
+ function="View.CheckShowHoverTips" />
+ </menu_item_check>
+ <menu_item_check
+ label="Tips On All Objects"
+ layout="topleft"
+ name="Tips On All Objects">
+ <menu_item_check.on_check
+ control="ShowAllObjectHoverTip" />
+ <menu_item_check.on_click
+ function="ToggleControl"
+ parameter="ShowAllObjectHoverTip" />
+ <menu_item_check.on_enable
+ function="View.CheckShowHoverTips" />
+ </menu_item_check>
+ </menu>
+ <menu_item_separator
+ layout="topleft" />
+ <menu_item_check
+ label="Run Multiple Threads"
+ layout="topleft"
+ name="Run Multiple Threads">
+ <menu_item_check.on_check
+ function="CheckControl"
+ parameter="RunMultipleThreads" />
+ <menu_item_check.on_click
+ function="ToggleControl"
+ parameter="RunMultipleThreads" />
+ </menu_item_check>
+ <menu_item_separator
+ layout="topleft" />
+ <menu
+ create_jump_keys="true"
+ label="Rendering Types"
+ layout="topleft"
+ name="Rendering Types"
+ tear_off="true">
+ <menu_item_check
+ label="Simple"
+ layout="topleft"
+ name="Simple"
+ shortcut="control|alt|shift|1">
+ <menu_item_check.on_check
+ function="Advanced.CheckRenderType"
+ parameter="simple" />
+ <menu_item_check.on_click
+ function="Advanced.ToggleRenderType"
+ parameter="simple" />
+ </menu_item_check>
+ <menu_item_check
+ label="Alpha"
+ layout="topleft"
+ name="Alpha"
+ shortcut="control|alt|shift|2">
+ <menu_item_check.on_check
+ function="Advanced.CheckRenderType"
+ parameter="alpha" />
+ <menu_item_check.on_click
+ function="Advanced.ToggleRenderType"
+ parameter="alpha" />
+ </menu_item_check>
+ <menu_item_check
+ label="Tree"
+ layout="topleft"
+ name="Tree"
+ shortcut="control|alt|shift|3">
+ <menu_item_check.on_check
+ function="Advanced.CheckRenderType"
+ parameter="tree" />
+ <menu_item_check.on_click
+ function="Advanced.ToggleRenderType"
+ parameter="tree" />
+ </menu_item_check>
+ <menu_item_check
+ label="Character"
+ layout="topleft"
+ name="Character"
+ shortcut="control|alt|shift|4">
+ <menu_item_check.on_check
+ function="Advanced.CheckRenderType"
+ parameter="character" />
+ <menu_item_check.on_click
+ function="Advanced.ToggleRenderType"
+ parameter="character" />
+ </menu_item_check>
+ <menu_item_check
+ label="SurfacePath"
+ layout="topleft"
+ name="SurfacePath"
+ shortcut="control|alt|shift|5">
+ <menu_item_check.on_check
+ function="Advanced.CheckRenderType"
+ parameter="surfacePath" />
+ <menu_item_check.on_click
+ function="Advanced.ToggleRenderType"
+ parameter="surfacePath" />
+ </menu_item_check>
+ <menu_item_check
+ label="Sky"
+ layout="topleft"
+ name="Sky"
+ shortcut="control|alt|shift|6">
+ <menu_item_check.on_check
+ function="Advanced.CheckRenderType"
+ parameter="sky" />
+ <menu_item_check.on_click
+ function="Advanced.ToggleRenderType"
+ parameter="sky" />
+ </menu_item_check>
+ <menu_item_check
+ label="Water"
+ layout="topleft"
+ name="Water"
+ shortcut="control|alt|shift|7">
+ <menu_item_check.on_check
+ function="Advanced.CheckRenderType"
+ parameter="water" />
+ <menu_item_check.on_click
+ function="Advanced.ToggleRenderType"
+ parameter="water" />
+ </menu_item_check>
+ <menu_item_check
+ label="Ground"
+ layout="topleft"
+ name="Ground"
+ shortcut="control|alt|shift|8">
+ <menu_item_check.on_check
+ function="Advanced.CheckRenderType"
+ parameter="ground" />
+ <menu_item_check.on_click
+ function="Advanced.ToggleRenderType"
+ parameter="ground" />
+ </menu_item_check>
+ <menu_item_check
+ label="Volume"
+ layout="topleft"
+ name="Volume"
+ shortcut="control|alt|shift|9">
+ <menu_item_check.on_check
+ function="Advanced.CheckRenderType"
+ parameter="volume" />
+ <menu_item_check.on_click
+ function="Advanced.ToggleRenderType"
+ parameter="volume" />
+ </menu_item_check>
+ <menu_item_check
+ label="Grass"
+ layout="topleft"
+ name="Grass"
+ shortcut="control|alt|shift|0">
+ <menu_item_check.on_check
+ function="Advanced.CheckRenderType"
+ parameter="grass" />
+ <menu_item_check.on_click
+ function="Advanced.ToggleRenderType"
+ parameter="grass" />
+ </menu_item_check>
+ <menu_item_check
+ label="Clouds"
+ layout="topleft"
+ name="Clouds"
+ shortcut="control|alt|shift|-">
+ <menu_item_check.on_check
+ function="Advanced.CheckRenderType"
+ parameter="clouds" />
+ <menu_item_check.on_click
+ function="Advanced.ToggleRenderType"
+ parameter="clouds" />
+ </menu_item_check>
+ <menu_item_check
+ label="Particles"
+ layout="topleft"
+ name="Particles"
+ shortcut="control|alt|shift|=">
+ <menu_item_check.on_check
+ function="Advanced.CheckRenderType"
+ parameter="particles" />
+ <menu_item_check.on_click
+ function="Advanced.ToggleRenderType"
+ parameter="particles" />
+ </menu_item_check>
+ <menu_item_check
+ label="Bump"
+ layout="topleft"
+ name="Bump"
+ shortcut="control|alt|shift|\">
+ <menu_item_check.on_check
+ function="Advanced.CheckRenderType"
+ parameter="bump" />
+ <menu_item_check.on_click
+ function="Advanced.ToggleRenderType"
+ parameter="bump" />
+ </menu_item_check>
+ </menu>
+ <menu
+ create_jump_keys="true"
+ label="Rendering Features"
+ layout="topleft"
+ name="Rendering Features"
+ tear_off="true">
+ <menu_item_check
+ label="UI"
+ layout="topleft"
+ name="UI"
+ shortcut="control|alt|F1">
+ <menu_item_check.on_check
+ function="Advanced.CheckFeature"
+ parameter="ui" />
+ <menu_item_check.on_click
+ function="Advanced.ToggleFeature"
+ parameter="ui" />
+ </menu_item_check>
+ <menu_item_check
+ label="Selected"
+ layout="topleft"
+ name="Selected"
+ shortcut="control|alt|F2">
+ <menu_item_check.on_check
+ function="Advanced.CheckFeature"
+ parameter="selected" />
+ <menu_item_check.on_click
+ function="Advanced.ToggleFeature"
+ parameter="selected" />
+ </menu_item_check>
+ <menu_item_check
+ label="Highlighted"
+ layout="topleft"
+ name="Highlighted"
+ shortcut="control|alt|F3">
+ <menu_item_check.on_check
+ function="Advanced.CheckFeature"
+ parameter="highlighted" />
+ <menu_item_check.on_click
+ function="Advanced.ToggleFeature"
+ parameter="highlighted" />
+ </menu_item_check>
+ <menu_item_check
+ label="Dynamic Textures"
+ layout="topleft"
+ name="Dynamic Textures"
+ shortcut="control|alt|F4">
+ <menu_item_check.on_check
+ function="Advanced.CheckFeature"
+ parameter="dynamic textures" />
+ <menu_item_check.on_click
+ function="Advanced.ToggleFeature"
+ parameter="dynamic textures" />
+ </menu_item_check>
+ <menu_item_check
+ label="Foot Shadows"
+ layout="topleft"
+ name="Foot Shadows"
+ shortcut="control|alt|F5">
+ <menu_item_check.on_check
+ function="Advanced.CheckFeature"
+ parameter="foot shadows" />
+ <menu_item_check.on_click
+ function="Advanced.ToggleFeature"
+ parameter="foot shadows" />
+ </menu_item_check>
+ <menu_item_check
+ label="Fog"
+ layout="topleft"
+ name="Fog"
+ shortcut="control|alt|F6">
+ <menu_item_check.on_check
+ function="Advanced.CheckFeature"
+ parameter="fog" />
+ <menu_item_check.on_click
+ function="Advanced.ToggleFeature"
+ parameter="fog" />
+ </menu_item_check>
+ <menu_item_check
+ label="Test FRInfo"
+ layout="topleft"
+ name="Test FRInfo"
+ shortcut="control|alt|F8">
+ <menu_item_check.on_check
+ function="Advanced.CheckFeature"
+ parameter="fr info" />
+ <menu_item_check.on_click
+ function="Advanced.ToggleFeature"
+ parameter="fr info" />
+ </menu_item_check>
+ <menu_item_check
+ label="Flexible Objects"
+ layout="topleft"
+ name="Flexible Objects"
+ shortcut="control|alt|F9">
+ <menu_item_check.on_check
+ function="Advanced.CheckFeature"
+ parameter="flexible" />
+ <menu_item_check.on_click
+ function="Advanced.ToggleFeature"
+ parameter="flexible" />
+ </menu_item_check>
+ </menu>
+ <menu_item_separator
+ layout="topleft" />
+ <menu
+ create_jump_keys="true"
+ label="Recorder"
+ layout="topleft"
+ name="Recorder"
+ tear_off="true">
+ <menu_item_call
+ label="Start Playback"
+ layout="topleft"
+ name="Start Playback">
+ <menu_item_call.on_click
+ function="Advanced.AgentPilot"
+ parameter="start playback" />
+ </menu_item_call>
+ <menu_item_call
+ label="Stop Playback"
+ layout="topleft"
+ name="Stop Playback">
+ <menu_item_call.on_click
+ function="Advanced.AgentPilot"
+ parameter="stop playback" />
+ </menu_item_call>
+ <menu_item_check
+ label="Loop Playback"
+ layout="topleft"
+ name="Loop Playback">
+ <menu_item_check.on_check
+ function="Advanced.CheckAgentPilotLoop"
+ parameter="loopPlayback" />
+ <menu_item_check.on_click
+ function="Advanced.ToggleAgentPilotLoop" />
+ </menu_item_check>
+ <menu_item_call
+ label="Start Record"
+ layout="topleft"
+ name="Start Record">
+ <menu_item_call.on_click
+ function="Advanced.AgentPilot"
+ parameter="start record" />
+ </menu_item_call>
+ <menu_item_call
+ label="Stop Record"
+ layout="topleft"
+ name="Stop Record">
+ <menu_item_call.on_click
+ function="Advanced.AgentPilot"
+ parameter="stop record" />
+ </menu_item_call>
+ </menu>
+ <menu_item_call
+ label="Dump Scripted Camera"
+ layout="topleft"
+ name="Dump Scripted Camera">
+ <menu_item_call.on_click
+ function="Advanced.DumpScriptedCamera" />
+ </menu_item_call>
+ <menu_item_separator
+ layout="topleft" />
+ <menu_item_call
+ label="Clear Group Cache"
+ layout="topleft"
+ name="ClearGroupCache">
+ <menu_item_call.on_click
+ function="Advanced.ClearGroupCache"
+ parameter="ClearGroupCache" />
+ </menu_item_call>
+ <menu_item_check
+ label="Enable Lip Sync(Beta)"
+ layout="topleft"
+ name="Enable Lip Sync(Beta)">
+ <menu_item_check.on_check
+ function="CheckControl"
+ parameter="LipSyncEnabled" />
+ <menu_item_check.on_click
+ function="ToggleControl"
+ parameter="LipSyncEnabled" />
+ </menu_item_check>
+ <menu_item_check
+ label="Tap-Tap-Hold to Run"
+ layout="topleft"
+ name="Tap-Tap-Hold to Run">
+ <menu_item_check.on_check
+ function="Advanced.CheckAllowTapTapHoldRun"
+ parameter="TapTapHoldRun" />
+ <menu_item_check.on_click
+ function="Advanced.ToggleAllowTapTapHoldRun" />
+ </menu_item_check>
+ <menu_item_check
+ label="Mouse Smoothing"
+ layout="topleft"
+ name="Mouse Smoothing">
+ <menu_item_check.on_check
+ function="CheckControl"
+ parameter="MouseSmooth" />
+ <menu_item_check.on_click
+ function="ToggleControl"
+ parameter="MouseSmooth" />
+ </menu_item_check>
+ <menu_item_separator
+ layout="topleft" />
+ <menu_item_call
+ label="Debug Settings"
+ layout="topleft"
+ name="Debug Settings">
+ <menu_item_call.on_click
+ function="Advanced.ShowDebugSettings"
+ parameter="all" />
+ </menu_item_call>
+ <menu_item_check
+ label="Debug (QA) Mode"
+ layout="topleft"
+ name="Debug Mode"
+ shortcut="control|alt|Q">
+ <menu_item_check.on_check
+ function="CheckControl"
+ parameter="QAMode" />
+ <menu_item_check.on_click
+ function="ToggleControl"
+ parameter="QAMode" />
+ </menu_item_check>
+ </menu>
+ <menu
+ create_jump_keys="true"
+ label="Debug"
+ layout="topleft"
+ name="Debug"
+ tear_off="true"
+ visible="false">
+ <menu
+ create_jump_keys="true"
+ label="Consoles"
+ layout="topleft"
+ name="Consoles"
+ tear_off="true">
+ <menu_item_check
+ label="Texture Console"
+ layout="topleft"
+ name="Texture Console"
+ shortcut="control|shift|3">
+ <menu_item_check.on_check
+ function="Advanced.CheckConsole"
+ parameter="texture" />
+ <menu_item_check.on_click
+ function="Advanced.ToggleConsole"
+ parameter="texture" />
+ </menu_item_check>
+ <menu_item_check
+ label="Debug Console"
+ layout="topleft"
+ name="Debug Console"
+ shortcut="control|shift|4">
+ <menu_item_check.on_check
+ function="Advanced.CheckConsole"
+ parameter="debug" />
+ <menu_item_check.on_click
+ function="Advanced.ToggleConsole"
+ parameter="debug" />
+ </menu_item_check>
+ <menu_item_check
+ label="Fast Timers"
+ layout="topleft"
+ name="Fast Timers"
+ shortcut="control|shift|9">
+ <menu_item_check.on_check
+ function="Advanced.CheckConsole"
+ parameter="fast timers" />
+ <menu_item_check.on_click
+ function="Advanced.ToggleConsole"
+ parameter="fast timers" />
+ </menu_item_check>
+ <menu_item_check
+ label="Memory"
+ layout="topleft"
+ name="Memory"
+ shortcut="control|shift|0">
+ <menu_item_check.on_check
+ function="Advanced.CheckConsole"
+ parameter="memory view" />
+ <menu_item_check.on_click
+ function="Advanced.ToggleConsole"
+ parameter="memory view" />
+ </menu_item_check>
+ <menu_item_check
+ label="Notifications Console"
+ layout="topleft"
+ name="Notifications"
+ shortcut="control|shift|5">
+ <menu_item_check.on_check
+ function="Advanced.CheckConsole"
+ parameter="notifications" />
+ <menu_item_check.on_click
+ function="Floater.Show"
+ parameter="notifications_console" />
+ </menu_item_check>
+ <menu_item_separator
+ layout="topleft" />
+ <menu_item_call
+ label="Region Info to Debug Console"
+ layout="topleft"
+ name="Region Info to Debug Console">
+ <menu_item_call.on_click
+ function="Advanced.DumpInfoToConsole"
+ parameter="region" />
+ </menu_item_call>
+ <menu_item_call
+ label="Group Info to Debug Console"
+ layout="topleft"
+ name="Group Info to Debug Console">
+ <menu_item_call.on_click
+ function="Advanced.DumpInfoToConsole"
+ parameter="group" />
+ </menu_item_call>
+ <menu_item_call
+ label="Capabilities Info to Debug Console"
+ layout="topleft"
+ name="Capabilities Info to Debug Console">
+ <menu_item_call.on_click
+ function="Advanced.DumpInfoToConsole"
+ parameter="capabilities" />
+ </menu_item_call>
+ </menu>
+ <menu
+ create_jump_keys="true"
+ label="Debugging"
+ layout="topleft"
+ name="Force Errors"
+ tear_off="true">
+ <menu_item_call
+ label="Force Breakpoint"
+ layout="topleft"
+ name="Force Breakpoint"
+ shortcut="control|alt|shift|B">
+ <menu_item_call.on_click
+ function="Advanced.ForceErrorBreakpoint" />
+ </menu_item_call>
+ <menu_item_call
+ label="Force LLError And Crash"
+ layout="topleft"
+ name="Force LLError And Crash">
+ <menu_item_call.on_click
+ function="Advanced.ForceErrorLlerror" />
+ </menu_item_call>
+ <menu_item_call
+ label="Force Bad Memory Access"
+ layout="topleft"
+ name="Force Bad Memory Access">
+ <menu_item_call.on_click
+ function="Advanced.ForceErrorBadMemoryAccess" />
+ </menu_item_call>
+ <menu_item_call
+ label="Force Infinite Loop"
+ layout="topleft"
+ name="Force Infinite Loop">
+ <menu_item_call.on_click
+ function="Advanced.ForceErrorInfiniteLoop" />
+ </menu_item_call>
+ <menu_item_call
+ label="Force Driver Crash"
+ layout="topleft"
+ name="Force Driver Carsh">
+ <menu_item_call.on_click
+ function="Advanced.ForceErrorDriverCrash" />
+ </menu_item_call>
+ <menu_item_call
+ label="Force Software Exception"
+ layout="topleft"
+ name="Force Software Exception">
+ <menu_item_call.on_click
+ function="Advanced.ForceErrorSoftwareException" />
+ </menu_item_call>
+ <menu_item_call
+ label="Force Disconnect Viewer"
+ layout="topleft"
+ name="Force Disconnect Viewer">
+ <menu_item_call.on_click
+ function="Advanced.ForceErrorDisconnectViewer" />
+ </menu_item_call>
+ </menu>
+ <menu_item_separator
+ layout="topleft" />
+ <menu_item_check
+ label="Output Debug Minidump"
+ layout="topleft"
+ name="Output Debug Minidump">
+ <menu_item_check.on_check
+ function="CheckControl"
+ parameter="SaveMinidump" />
+ <menu_item_check.on_click
+ function="ToggleControl"
+ parameter="SaveMinidump" />
+ </menu_item_check>
+ <menu_item_call
+ label="Memory Leaking Simulation"
+ layout="topleft"
+ name="Memory Leaking Simulation">
+ <menu_item_call.on_click
+ function="Floater.Show"
+ parameter="mem_leaking" />
+ </menu_item_call>
+ <menu_item_call
+ label="Bumps, Pushes &amp; Hits..."
+ layout="topleft"
+ name="Bumps, Pushes &amp;amp; Hits">
+ <menu_item_call.on_click
+ function="Floater.Show"
+ parameter="bumps" />
+ </menu_item_call>
+ <menu_item_separator
+ layout="topleft" />
+ <menu
+ create_jump_keys="true"
+ label="Render Tests"
+ layout="topleft"
+ name="Render Tests"
+ tear_off="true">
+ <menu_item_check
+ label="Camera Offset"
+ layout="topleft"
+ name="Camera Offset">
+ <menu_item_check.on_check
+ function="CheckControl"
+ parameter="CameraOffset" />
+ <menu_item_check.on_click
+ function="ToggleControl"
+ parameter="CameraOffset" />
+ </menu_item_check>
+ <menu_item_check
+ label="Randomize Framerate"
+ layout="topleft"
+ name="Randomize Framerate">
+ <menu_item_check.on_check
+ function="Advanced.CheckRandomizeFramerate"
+ parameter="Randomize Framerate" />
+ <menu_item_check.on_click
+ function="Advanced.ToggleRandomizeFramerate" />
+ </menu_item_check>
+ <menu_item_check
+ label="Periodic Slow Frame"
+ layout="topleft"
+ name="Periodic Slow Frame">
+ <menu_item_check.on_check
+ function="Advanced.CheckPeriodicSlowFrame"
+ parameter="points" />
+ <menu_item_check.on_click
+ function="Advanced.TogglePeriodicSlowFrame"
+ parameter="points" />
+ </menu_item_check>
+ <menu_item_check
+ label="Frame Test"
+ layout="topleft"
+ name="Frame Test">
+ <menu_item_check.on_check
+ function="Advanced.CheckFrameTest"
+ parameter="Frame Test" />
+ <menu_item_check.on_click
+ function="Advanced.ToggleFrameTest" />
+ </menu_item_check>
+ </menu>
+ <menu_item_separator
+ layout="topleft" />
+ <menu
+ create_jump_keys="true"
+ label="Display Info"
+ layout="topleft"
+ name="Display Info"
+ tear_off="true">
+ <menu_item_check
+ label="Show Time"
+ layout="topleft"
+ name="Show Time">
+ <menu_item_check.on_check
+ function="CheckControl"
+ parameter="DebugShowTime" />
+ <menu_item_check.on_click
+ function="ToggleControl"
+ parameter="DebugShowTime" />
+ </menu_item_check>
+ <menu_item_check
+ label="Show Render Info"
+ layout="topleft"
+ name="Show Render Info">
+ <menu_item_check.on_check
+ function="CheckControl"
+ parameter="DebugShowRenderInfo" />
+ <menu_item_check.on_click
+ function="ToggleControl"
+ parameter="DebugShowRenderInfo" />
+ </menu_item_check>
+ <menu_item_check
+ label="Show Matrices"
+ layout="topleft"
+ name="Show Matrices">
+ <menu_item_check.on_check
+ function="CheckControl"
+ parameter="DebugShowRenderMatrices" />
+ <menu_item_check.on_click
+ function="ToggleControl"
+ parameter="DebugShowRenderMatrices" />
+ </menu_item_check>
+ <menu_item_check
+ label="Show Color Under Cursor"
+ layout="topleft"
+ name="Show Color Under Cursor">
+ <menu_item_check.on_check
+ function="CheckControl"
+ parameter="DebugShowColor" />
+ <menu_item_check.on_click
+ function="ToggleControl"
+ parameter="DebugShowColor" />
+ </menu_item_check>
+ </menu>
+ <menu_item_separator
+ layout="topleft" />
+ <menu
+ create_jump_keys="true"
+ label="Network"
+ layout="topleft"
+ name="Network"
+ tear_off="true">
+ <menu_item_call
+ label="Enable Message Log"
+ layout="topleft"
+ name="Enable Message Log">
+ <menu_item_call.on_click
+ function="Advanced.EnableMessageLog" />
+ </menu_item_call>
+ <menu_item_call
+ label="Disable Message Log"
+ layout="topleft"
+ name="Disable Message Log">
+ <menu_item_call.on_click
+ function="Advanced.DisableMessageLog" />
+ </menu_item_call>
+ <menu_item_check
+ label="Velocity Interpolate Objects"
+ layout="topleft"
+ name="Velocity Interpolate Objects">
+ <menu_item_check.on_check
+ function="CheckControl"
+ parameter="VelocityInterpolate" />
+ <menu_item_check.on_click
+ function="ToggleControl"
+ parameter="VelocityInterpolate" />
+ </menu_item_check>
+ <menu_item_check
+ label="Ping Interpolate Object Positions"
+ layout="topleft"
+ name="Ping Interpolate Object Positions">
+ <menu_item_check.on_check
+ function="CheckControl"
+ parameter="PingInterpolate" />
+ <menu_item_check.on_click
+ function="ToggleControl"
+ parameter="PingInterpolate" />
+ </menu_item_check>
+ <menu_item_call
+ label="Drop a Packet"
+ layout="topleft"
+ name="Drop a Packet"
+ shortcut="control|alt|L">
+ <menu_item_call.on_click
+ function="Advanced.DropPacket" />
+ </menu_item_call>
+ <menu_item_check
+ label="Show Updates"
+ layout="topleft"
+ name="Show Updates"
+ shortcut="control|alt|shift|U">
+ <menu_item_check.on_check
+ function="Advanced.CheckShowObjectUpdates"
+ parameter="ObjectUpdates" />
+ <menu_item_check.on_click
+ function="Advanced.ToggleShowObjectUpdates" />
+ </menu_item_check>
+ </menu>
+ <menu_item_separator
+ layout="topleft" />
+ <menu_item_check
+ label="View Admin Options"
+ layout="topleft"
+ name="View Admin Options"
+ shortcut="control|alt|V">
+ <menu_item_check.on_check
+ function="Advanced.CheckViewAdminOptions"
+ parameter="ViewAdminOptions" />
+ <menu_item_check.on_click
+ function="Advanced.ToggleViewAdminOptions" />
+ </menu_item_check>
+ <menu_item_call
+ label="Request Admin Status"
+ layout="topleft"
+ name="Request Admin Options"
+ shortcut="control|alt|G">
+ <menu_item_call.on_click
+ function="Advanced.RequestAdminStatus" />
+ </menu_item_call>
+ <menu_item_call
+ label="Leave Admin Status"
+ layout="topleft"
+ name="Leave Admin Options"
+ shortcut="control|alt|shift|G">
+ <menu_item_call.on_click
+ function="Advanced.LeaveAdminStatus" />
+ </menu_item_call>
+ </menu>
+ <menu
+ create_jump_keys="true"
+ label="Develop"
+ layout="topleft"
+ name="Develop"
+ tear_off="true"
+ visible="false">
+ <menu
+ create_jump_keys="true"
+ label="HUD Info"
+ layout="topleft"
+ name="HUD Info"
+ tear_off="true">
+ <menu_item_check
+ label="Camera"
+ layout="topleft"
+ name="Camera">
+ <menu_item_check.on_check
+ function="Advanced.CheckHUDInfo"
+ parameter="camera" />
+ <menu_item_check.on_click
+ function="Advanced.ToggleHUDInfo"
+ parameter="camera" />
+ </menu_item_check>
+ <menu_item_check
+ label="Wind"
+ layout="topleft"
+ name="Wind">
+ <menu_item_check.on_check
+ function="Advanced.CheckHUDInfo"
+ parameter="wind" />
+ <menu_item_check.on_click
+ function="Advanced.ToggleHUDInfo"
+ parameter="wind" />
+ </menu_item_check>
+ <menu_item_check
+ label="FOV"
+ layout="topleft"
+ name="FOV">
+ <menu_item_check.on_check
+ function="Advanced.CheckHUDInfo"
+ parameter="fov" />
+ <menu_item_check.on_click
+ function="Advanced.ToggleHUDInfo"
+ parameter="fov" />
+ </menu_item_check>
+ </menu>
+ <menu
+ create_jump_keys="true"
+ label="Rendering"
+ layout="topleft"
+ name="Rendering"
+ tear_off="true">
+ <menu_item_check
+ label="Axes"
+ layout="topleft"
+ name="Axes">
+ <menu_item_check.on_check
+ function="CheckControl"
+ parameter="ShowAxes" />
+ <menu_item_check.on_click
+ function="ToggleControl"
+ parameter="ShowAxes" />
+ </menu_item_check>
+ <menu_item_check
+ label="Tangent Basis"
+ layout="topleft"
+ name="Tangent Basis">
+ <menu_item_check.on_check
+ function="CheckControl"
+ parameter="ShowTangentBasis" />
+ <menu_item_check.on_click
+ function="ToggleControl"
+ parameter="ShowTangentBasis" />
+ </menu_item_check>
+ <menu_item_call
+ label="Selected Texture Info Basis"
+ layout="topleft"
+ name="Selected Texture Info Basis"
+ shortcut="control|alt|shift|T">
+ <menu_item_call.on_click
+ function="Advanced.SelectedTextureInfo" />
+ </menu_item_call>
+ <menu_item_check
+ label="Wireframe"
+ layout="topleft"
+ name="Wireframe"
+ shortcut="control|shift|R">
+ <menu_item_check.on_check
+ function="Advanced.CheckWireframe"
+ parameter="Wireframe" />
+ <menu_item_check.on_click
+ function="Advanced.ToggleWireframe" />
+ </menu_item_check>
+ <menu_item_check
+ label="Object-Object Occlusion"
+ layout="topleft"
+ name="Object-Object Occlusion"
+ shortcut="control|shift|O">
+ <menu_item_check.on_check
+ function="CheckControl"
+ parameter="UseOcclusion" />
+ <menu_item_check.on_click
+ function="ToggleControl"
+ parameter="UseOcclusion" />
+ <menu_item_check.on_enable
+ function="Advanced.EnableObjectObjectOcclusion" />
+ </menu_item_check>
+ <menu_item_check
+ label="Debug GL"
+ layout="topleft"
+ name="Debug GL">
+ <menu_item_check.on_check
+ function="CheckControl"
+ parameter="RenderDebugGL" />
+ <menu_item_check.on_click
+ function="ToggleControl"
+ parameter="RenderDebugGL" />
+ </menu_item_check>
+ <menu_item_check
+ label="Debug Pipeline"
+ layout="topleft"
+ name="Debug Pipeline">
+ <menu_item_check.on_check
+ function="CheckControl"
+ parameter="RenderDebugGL" />
+ <menu_item_check.on_click
+ function="ToggleControl"
+ parameter="RenderDebugGL" />
+ </menu_item_check>
+ <menu_item_check
+ label="Fast Alpha"
+ layout="topleft"
+ name="Fast Alpha">
+ <menu_item_check.on_check
+ function="CheckControl"
+ parameter="RenderDebugGL" />
+ <menu_item_check.on_click
+ function="ToggleControl"
+ parameter="RenderDebugGL" />
+ </menu_item_check>
+ <menu_item_check
+ label="Animation Textures"
+ layout="topleft"
+ name="Animation Textures">
+ <menu_item_check.on_check
+ function="CheckControl"
+ parameter="RenderDebugGL" />
+ <menu_item_check.on_click
+ function="ToggleControl"
+ parameter="RenderDebugGL" />
+ </menu_item_check>
+ <menu_item_check
+ label="Disable Textures"
+ layout="topleft"
+ name="Disable Textures">
+ <menu_item_check.on_check
+ function="Advanced.CheckDisableTextures"
+ parameter="DisableTextures" />
+ <menu_item_check.on_click
+ function="Advanced.ToggleDisableTextures" />
+ </menu_item_check>
+ <menu_item_check
+ label="Render Attached Lights"
+ layout="topleft"
+ name="Render Attached Lights">
+ <menu_item_check.on_check
+ function="CheckControl"
+ parameter="RenderAttachedLights" />
+ <menu_item_check.on_click
+ function="Advanced.HandleAttchedLightParticles"
+ parameter="RenderAttachedLights" />
+ </menu_item_check>
+ <menu_item_check
+ label="Render Attached Particles"
+ layout="topleft"
+ name="Render Attached Particles">
+ <menu_item_check.on_check
+ function="CheckControl"
+ parameter="RenderAttachedParticles" />
+ <menu_item_check.on_click
+ function="Advanced.HandleAttchedLightParticles"
+ parameter="RenderAttachedParticles" />
+ </menu_item_check>
+ </menu>
+ <menu
+ create_jump_keys="true"
+ label="World"
+ layout="topleft"
+ name="World"
+ tear_off="true">
+ <menu_item_check
+ label="Sim Sun Override"
+ layout="topleft"
+ name="Sim Sun Override">
+ <menu_item_check.on_check
+ function="CheckControl"
+ parameter="SkyOverrideSimSunPosition" />
+ <menu_item_check.on_click
+ function="ToggleControl"
+ parameter="SkyOverrideSimSunPosition" />
+ </menu_item_check>
+ <menu_item_check
+ label="Cheesy Beacon"
+ layout="topleft"
+ name="Cheesy Beacon">
+ <menu_item_check.on_check
+ function="CheckControl"
+ parameter="CheesyBeacon" />
+ <menu_item_check.on_click
+ function="ToggleControl"
+ parameter="CheesyBeacon" />
+ </menu_item_check>
+ <menu_item_check
+ label="Fixed Weather"
+ layout="topleft"
+ name="Fixed Weather">
+ <menu_item_check.on_check
+ function="CheckControl"
+ parameter="FixedWeather" />
+ <menu_item_check.on_click
+ function="ToggleControl"
+ parameter="FixedWeather" />
+ </menu_item_check>
+ <menu_item_call
+ label="Dump Region Object Cache"
+ layout="topleft"
+ name="Dump Region Object Cache">
+ <menu_item_call.on_click
+ function="Advanced.DumpRegionObjectCache" />
+ </menu_item_call>
+ </menu>
+ <menu
+ create_jump_keys="true"
+ label="UI"
+ layout="topleft"
+ name="UI"
+ tear_off="true">
+ <menu_item_check
+ label="New Bottom Bar"
+ layout="topleft"
+ name="New Bottom Bar">
+ <menu_item_check.on_check
+ function="CheckControl"
+ parameter="BottomPanelNew" />
+ <menu_item_check.on_click
+ function="ToggleControl"
+ parameter="BottomPanelNew" />
+ </menu_item_check>
+ <menu_item_call
+ label="Web Browser Test"
+ layout="topleft"
+ name="Web Browser Test">
+ <menu_item_call.on_click
+ function="Advanced.WebBrowserTest" />
+ </menu_item_call>
+ <menu_item_call
+ label="Simple Web Browser Test"
+ layout="topleft"
+ name="Simple Web Browser Test">
+ <menu_item_call.on_click
+ function="Floater.Show"
+ parameter="html_simple.http://www.secondlife.com" />
+ </menu_item_call>
+ <menu_item_call
+ label="UI/Color Settings"
+ layout="topleft"
+ name="UI/Color Settings">
+ <menu_item_call.on_click
+ function="Advanced.ShowDebugSettings"
+ parameter="skin" />
+ </menu_item_call>
+ <menu_item_check
+ label="Editable UI"
+ layout="topleft"
+ name="Editable UI">
+ <menu_item_check.on_check
+ function="Advanced.CheckEditableUI" />
+ <menu_item_check.on_click
+ function="Advanced.ToggleEditableUI" />
+ </menu_item_check>
+ <menu_item_call
+ label="Dump SelectMgr"
+ layout="topleft"
+ name="Dump SelectMgr">
+ <menu_item_call.on_click
+ function="Advanced.DumpSelectMgr" />
+ </menu_item_call>
+ <menu_item_call
+ label="Dump Inventory"
+ layout="topleft"
+ name="Dump Inventory">
+ <menu_item_call.on_click
+ function="Advanced.DumpInventory" />
+ </menu_item_call>
+ <menu_item_call
+ label="Dump Focus Holder"
+ layout="topleft"
+ name="Dump Focus Holder"
+ shortcut="control|alt|F">
+ <menu_item_call.on_click
+ function="Advanced.DumpFocusHolder" />
+ </menu_item_call>
+ <menu_item_call
+ label="Print Selected Object Info"
+ layout="topleft"
+ name="Print Selected Object Info"
+ shortcut="control|shift|P">
+ <menu_item_call.on_click
+ function="Advanced.PrintSelectedObjectInfo" />
+ </menu_item_call>
+ <menu_item_call
+ label="Print Agent Info"
+ layout="topleft"
+ name="Print Agent Info"
+ shortcut="shift|P">
+ <menu_item_call.on_click
+ function="Advanced.PrintAgentInfo" />
+ </menu_item_call>
+ <menu_item_call
+ label="Memory Stats"
+ layout="topleft"
+ name="Memory Stats"
+ shortcut="control|alt|shift|M">
+ <menu_item_call.on_click
+ function="Advanced.PrintTextureMemoryStats" />
+ </menu_item_call>
+ <menu_item_check
+ label="Double-ClickAuto-Pilot"
+ layout="topleft"
+ name="Double-ClickAuto-Pilot">
+ <menu_item_check.on_check
+ function="CheckControl"
+ parameter="DoubleClickAutoPilot" />
+ <menu_item_check.on_click
+ function="ToggleControl"
+ parameter="DoubleClickAutoPilot" />
+ </menu_item_check>
+ <menu_item_separator
+ layout="topleft" />
+ <menu_item_check
+ label="Debug SelectMgr"
+ layout="topleft"
+ name="Debug SelectMgr">
+ <menu_item_check.on_check
+ function="CheckControl"
+ parameter="DebugSelectMgr" />
+ <menu_item_check.on_click
+ function="ToggleControl"
+ parameter="DebugSelectMgr" />
+ </menu_item_check>
+ <menu_item_check
+ label="Debug Clicks"
+ layout="topleft"
+ name="Debug Clicks">
+ <menu_item_check.on_check
+ function="Advanced.CheckDebugClicks"
+ parameter="DebugClicks" />
+ <menu_item_check.on_click
+ function="Advanced.ToggleDebugClicks"
+ parameter="DebugClicks" />
+ </menu_item_check>
+ <menu_item_check
+ label="Debug Views"
+ layout="topleft"
+ name="Debug Views">
+ <menu_item_check.on_check
+ function="Advanced.CheckDebugViews" />
+ <menu_item_check.on_click
+ function="Advanced.ToggleDebugViews" />
+ </menu_item_check>
+ <menu_item_check
+ label="Debug Name Tooltips"
+ layout="topleft"
+ name="Debug Name Tooltips">
+ <menu_item_check.on_check
+ function="Advanced.CheckXUINameTooltips"
+ parameter="XUINameTooltips" />
+ <menu_item_check.on_click
+ function="Advanced.ToggleXUINameTooltips" />
+ </menu_item_check>
+ <menu_item_check
+ label="Debug Mouse Events"
+ layout="topleft"
+ name="Debug Mouse Events">
+ <menu_item_check.on_check
+ function="Advanced.CheckDebugMouseEvents"
+ parameter="MouseEvents" />
+ <menu_item_check.on_click
+ function="Advanced.ToggleDebugMouseEvents" />
+ </menu_item_check>
+ <menu_item_check
+ label="Debug Keys"
+ layout="topleft"
+ name="Debug Keys">
+ <menu_item_check.on_check
+ function="Advanced.CheckDebugKeys"
+ parameter="DebugKeys" />
+ <menu_item_check.on_click
+ function="Advanced.ToggleDebugKeys" />
+ </menu_item_check>
+ <menu_item_check
+ label="Debug WindowProc"
+ layout="topleft"
+ name="Debug WindowProc">
+ <menu_item_check.on_check
+ function="Advanced.CheckDebugWindowProc"
+ parameter="DebugWindowProc" />
+ <menu_item_check.on_click
+ function="Advanced.ToggleDebugWindowProc"
+ parameter="DebugWindowProc" />
+ </menu_item_check>
+ </menu>
+ <menu
+ create_jump_keys="true"
+ label="XUI"
+ name="XUI"
+ tear_off="true">
+ <menu_item_call
+ label="Reload Color Settings"
+ layout="topleft"
+ name="Reload Color Settings">
+ <menu_item_call.on_click
+ function="Advanced.ReloadColorSettings" />
+ </menu_item_call>
+ <menu_item_call
+ label="Show Font Test"
+ layout="topleft"
+ name="Show Font Test">
+ <menu_item_call.on_click
+ function="Floater.Show"
+ parameter="font_test" />
+ </menu_item_call>
+ <menu_item_call
+ label="Load from XML..."
+ layout="topleft"
+ name="Load from XML">
+ <menu_item_call.on_click
+ function="Advanced.LoadUIFromXML" />
+ </menu_item_call>
+ <menu_item_call
+ label="Save to XML..."
+ layout="topleft"
+ name="Save to XML">
+ <menu_item_call.on_click
+ function="Advanced.SaveUIToXML" />
+ </menu_item_call>
+ <menu_item_check
+ label="Show XUI Names"
+ layout="topleft"
+ name="Show XUI Names">
+ <menu_item_check.on_check
+ function="Advanced.CheckXUINames"
+ parameter="showUIname" />
+ <menu_item_check.on_click
+ function="Advanced.ToggleXUINames" />
+ </menu_item_check>
+ <menu_item_call
+ label="Send Test IMs"
+ layout="topleft"
+ name="Send Test IMs">
+ <menu_item_call.on_click
+ function="Advanced.SendTestIMs" />
+ </menu_item_call>
+ <!-- *HACK: Hard code James Tester's UUID -->
+ <menu_item_call
+ label="Avatar Inspector"
+ name="Avatar Inspector"
+ shortcut="control|shift|I">
+ <menu_item_call.on_click
+ function="Advanced.AvatarInspector"
+ parameter="22df1dcb-810a-4975-aab9-0159958fe155" />
+ </menu_item_call>
+ </menu>
+ <menu
+ create_jump_keys="true"
+ label="Character"
+ layout="topleft"
+ name="Character"
+ tear_off="true">
+ <menu
+ create_jump_keys="true"
+ label="Grab Baked Texture"
+ layout="topleft"
+ name="Grab Baked Texture"
+ tear_off="true">
+ <menu_item_call
+ label="Iris"
+ layout="topleft"
+ name="Iris">
+ <menu_item_call.on_click
+ function="Advanced.GrabBakedTexture"
+ parameter="iris" />
+ <menu_item_call.on_enable
+ function="Advanced.EnableGrabBakedTexture" />
+ </menu_item_call>
+ <menu_item_call
+ label="Head"
+ layout="topleft"
+ name="Head">
+ <menu_item_call.on_click
+ function="Advanced.GrabBakedTexture"
+ parameter="head" />
+ <menu_item_call.on_enable
+ function="Advanced.EnableGrabBakedTexture" />
+ </menu_item_call>
+ <menu_item_call
+ label="Upper Body"
+ layout="topleft"
+ name="Upper Body">
+ <menu_item_call.on_click
+ function="Advanced.GrabBakedTexture"
+ parameter="upper" />
+ <menu_item_call.on_enable
+ function="Advanced.EnableGrabBakedTexture" />
+ </menu_item_call>
+ <menu_item_call
+ label="Lower Body"
+ layout="topleft"
+ name="Lower Body">
+ <menu_item_call.on_click
+ function="Advanced.GrabBakedTexture"
+ parameter="lower" />
+ <menu_item_call.on_enable
+ function="Advanced.EnableGrabBakedTexture" />
+ </menu_item_call>
+ <menu_item_call
+ label="Skirt"
+ layout="topleft"
+ name="Skirt">
+ <menu_item_call.on_click
+ function="Advanced.GrabBakedTexture"
+ parameter="skirt" />
+ <menu_item_call.on_enable
+ function="Advanced.EnableGrabBakedTexture" />
+ </menu_item_call>
+ <menu_item_call
+ label="Skirt"
+ layout="topleft"
+ name="Hair">
+ <menu_item_call.on_click
+ function="Advanced.GrabBakedTexture"
+ parameter="hair" />
+ <menu_item_call.on_enable
+ function="Advanced.EnableGrabBakedTexture" />
+ </menu_item_call>
+ </menu>
+ <menu
+ create_jump_keys="true"
+ label="Character Tests"
+ layout="topleft"
+ name="Character Tests"
+ tear_off="true">
+ <menu_item_call
+ label="Appearance To XML"
+ layout="topleft"
+ name="Appearance To XML">
+ <menu_item_call.on_click
+ function="Advanced.AppearanceToXML" />
+ </menu_item_call>
+ <menu_item_call
+ label="Toggle Character Geometry"
+ layout="topleft"
+ name="Toggle Character Geometry">
+ <menu_item_call.on_click
+ function="Advanced.ToggleCharacterGeometry" />
+ <menu_item_call.on_enable
+ function="EnableGodCustomerService" />
+ </menu_item_call>
+ <menu_item_call
+ label="Test Male"
+ layout="topleft"
+ name="Test Male">
+ <menu_item_call.on_click
+ function="Advanced.TestMale" />
+ </menu_item_call>
+ <menu_item_call
+ label="Test Female"
+ layout="topleft"
+ name="Test Female">
+ <menu_item_call.on_click
+ function="Advanced.TestFemale" />
+ </menu_item_call>
+ <menu_item_call
+ label="Toggle PG"
+ layout="topleft"
+ name="Toggle PG">
+ <menu_item_call.on_click
+ function="Advanced.TogglePG" />
+ </menu_item_call>
+ <menu_item_check
+ label="Allow Select Avatar"
+ layout="topleft"
+ name="Allow Select Avatar">
+ <menu_item_check.on_check
+ function="CheckControl"
+ parameter="AllowSelectAvatar" />
+ <menu_item_check.on_click
+ function="ToggleControl"
+ parameter="AllowSelectAvatar" />
+ </menu_item_check>
+ </menu>
+ <menu_item_call
+ label="Force Params to Default"
+ layout="topleft"
+ name="Force Params to Default">
+ <menu_item_call.on_click
+ function="Advanced.ForceParamsToDefault" />
+ </menu_item_call>
+ <menu_item_check
+ label="Animation Info"
+ layout="topleft"
+ name="Animation Info">
+ <menu_item_check.on_check
+ function="Advanced.CheckAnimationInfo"
+ parameter="AnimationInfo" />
+ <menu_item_check.on_click
+ function="Advanced.ToggleAnimationInfo"
+ parameter="" />
+ </menu_item_check>
+ <menu_item_check
+ label="Slow Motion Animations"
+ layout="topleft"
+ name="Slow Motion Animations">
+ <menu_item_check.on_check
+ function="CheckControl"
+ parameter="SlowMotionAnimation" />
+ <menu_item_check.on_click
+ function="ToggleControl"
+ parameter="SlowMotionAnimation" />
+ </menu_item_check>
+ <menu_item_check
+ label="Show Look At"
+ layout="topleft"
+ name="Show Look At">
+ <menu_item_check.on_check
+ function="Advanced.CheckShowLookAt"
+ parameter="ShowLookAt" />
+ <menu_item_check.on_click
+ function="Advanced.ToggleShowLookAt" />
+ </menu_item_check>
+ <menu_item_check
+ label="Show Point At"
+ layout="topleft"
+ name="Show Point At">
+ <menu_item_check.on_check
+ function="Advanced.CheckShowPointAt"
+ parameter="ShowPointAt" />
+ <menu_item_check.on_click
+ function="Advanced.ToggleShowPointAt" />
+ </menu_item_check>
+ <menu_item_check
+ label="Debug Joint Updates"
+ layout="topleft"
+ name="Debug Joint Updates">
+ <menu_item_check.on_check
+ function="Advanced.CheckDebugJointUpdates"
+ parameter="DebugJointUpdates" />
+ <menu_item_check.on_click
+ function="Advanced.ToggleDebugJointUpdates" />
+ </menu_item_check>
+ <menu_item_check
+ label="Disable LOD"
+ layout="topleft"
+ name="Disable LOD">
+ <menu_item_check.on_check
+ function="Advanced.CheckDisableLOD"
+ parameter="DisableLOD" />
+ <menu_item_check.on_click
+ function="Advanced.ToggleDisableLOD" />
+ </menu_item_check>
+ <menu_item_check
+ label="Debug Character Vis"
+ layout="topleft"
+ name="Debug Character Vis">
+ <menu_item_check.on_check
+ function="Advanced.CheckDebugCharacterVis"
+ parameter="DebugCharacterVis" />
+ <menu_item_check.on_click
+ function="Advanced.ToggleDebugCharacterVis" />
+ </menu_item_check>
+ <menu_item_check
+ label="Show Collision Skeleton"
+ layout="topleft"
+ name="Show Collision Skeleton">
+ <menu_item_check.on_check
+ function="Advanced.CheckInfoDisplay"
+ parameter="collision skeleton" />
+ <menu_item_check.on_click
+ function="Advanced.ToggleInfoDisplay"
+ parameter="collision skeleton" />
+ </menu_item_check>
+ <menu_item_check
+ label="Display Agent Target"
+ layout="topleft"
+ name="Display Agent Target">
+ <menu_item_check.on_check
+ function="Advanced.CheckInfoDisplay"
+ parameter="agent target" />
+ <menu_item_check.on_click
+ function="Advanced.ToggleInfoDisplay"
+ parameter="agent target" />
+ </menu_item_check>
+<!-- Appears not to exist anymore
+ <menu_item_check
+ label="Debug Rotation"
+ layout="topleft"
+ name="Debug Rotation">
+ <menu_item_check.on_check
+ function="CheckControl"
+ parameter="DebugAvatarRotation" />
+ <menu_item_check.on_click
+ function="ToggleControl"
+ parameter="DebugAvatarRotation" />
+ </menu_item_check> -->
+-->
+ <menu_item_call
+ label="Dump Attachments"
+ layout="topleft"
+ name="Dump Attachments">
+ <menu_item_call.on_click
+ function="Advanced.DumpAttachments" />
+ </menu_item_call>
+ <menu_item_call
+ label="Debug Avatar Textures"
+ layout="topleft"
+ name="Debug Avatar Textures"
+ shortcut="control|alt|shift|A">
+ <menu_item_call.on_click
+ function="Advanced.DebugAvatarTextures" />
+ </menu_item_call>
+ <menu_item_call
+ label="Dump Local Textures"
+ layout="topleft"
+ name="Dump Local Textures"
+ shortcut="alt|shift|M">
+ <menu_item_call.on_click
+ function="Advanced.DumpAvatarLocalTextures" />
+ </menu_item_call>
+ </menu>
+ <menu_item_separator
+ layout="topleft" />
+ <menu_item_check
+ label="Debug Permissions"
+ layout="topleft"
+ name="DebugPermissions">
+ <menu_item_check.on_check
+ function="CheckControl"
+ parameter="DebugPermissions" />
+ <menu_item_check.on_click
+ function="ToggleControl"
+ parameter="DebugPermissions" />
+ </menu_item_check>
+ <menu_item_call
+ label="Compress Images"
+ layout="topleft"
+ name="Compress Images">
+ <menu_item_call.on_click
+ function="Advanced.CompressImage" />
+ </menu_item_call>
+ <menu_item_check
+ label="Console Window"
+ layout="topleft"
+ name="Console Window">
+ <menu_item_check.on_check
+ function="CheckControl"
+ parameter="ShowConsoleWindow" />
+ <menu_item_check.on_click
+ function="ToggleControl"
+ parameter="ShowConsoleWindow" />
+ </menu_item_check>
+ </menu>
+ <menu
+ create_jump_keys="true"
+ label="Admin"
+ layout="topleft"
+ name="Admin"
+ tear_off="true"
+ visible="false">
+ <menu
+ create_jump_keys="true"
+ label="Object"
+ layout="topleft"
+ tear_off="true">
+ <menu_item_call
+ label="Take Copy"
+ layout="topleft"
+ name="Take Copy"
+ shortcut="control|alt|shift|O">
+ <menu_item_call.on_click
+ function="Admin.ForceTakeCopy" />
+ <menu_item_call.on_enable
+ function="EnableGodCustomerService" />
+ </menu_item_call>
+ <menu_item_call
+ label="Force Owner To Me"
+ layout="topleft"
+ name="Force Owner To Me">
+ <menu_item_call.on_click
+ function="Admin.HandleObjectOwnerSelf" />
+ <menu_item_call.on_enable
+ function="EnableGodCustomerService" />
+ </menu_item_call>
+ <menu_item_call
+ label="Force Owner Permissive"
+ layout="topleft"
+ name="Force Owner Permissive">
+ <menu_item_call.on_click
+ function="Admin.HandleObjectOwnerPermissive" />
+ <menu_item_call.on_enable
+ function="EnableGodCustomerService" />
+ </menu_item_call>
+ <menu_item_call
+ label="Delete"
+ layout="topleft"
+ name="Delete"
+ shortcut="control|alt|shift|Del">
+ <menu_item_call.on_click
+ function="Admin.HandleForceDelete" />
+ <menu_item_call.on_enable
+ function="EnableGodCustomerService" />
+ </menu_item_call>
+ <menu_item_call
+ label="Lock"
+ layout="topleft"
+ name="Lock"
+ shortcut="control|alt|shift|L">
+ <menu_item_call.on_click
+ function="Admin.HandleObjectLock" />
+ <menu_item_call.on_enable
+ function="EnableGodCustomerService" />
+ </menu_item_call>
+ <menu_item_call
+ label="Get Assets IDs"
+ layout="topleft"
+ name="Get Assets IDs"
+ shortcut="control|alt|shift|I">
+ <menu_item_call.on_click
+ function="Admin.HandleObjectAssetIDs" />
+ <menu_item_call.on_enable
+ function="EnableGodCustomerService" />
+ </menu_item_call>
+ </menu>
+ <menu
+ create_jump_keys="true"
+ label="Parcel"
+ layout="topleft"
+ name="Parcel"
+ tear_off="true">
+ <menu_item_call
+ label="Owner To Me"
+ layout="topleft"
+ name="Owner To Me">
+ <menu_item_call.on_click
+ function="Admin.HandleForceParcelOwnerToMe" />
+ <menu_item_call.on_enable
+ function="EnableGodCustomerService" />
+ </menu_item_call>
+ <menu_item_call
+ label="Set to Linden Content"
+ layout="topleft"
+ name="Set to Linden Content"
+ shortcut="control|alt|shift|C">
+ <menu_item_call.on_click
+ function="Admin.HandleForceParcelToContent" />
+ <menu_item_call.on_enable
+ function="EnableGodCustomerService" />
+ </menu_item_call>
+ <menu_item_call
+ label="Claim Public Land"
+ layout="topleft"
+ name="Claim Public Land">
+ <menu_item_call.on_click
+ function="Admin.HandleClaimPublicLand" />
+ <menu_item_call.on_enable
+ function="EnableGodCustomerService" />
+ </menu_item_call>
+ </menu>
+ <menu
+ create_jump_keys="true"
+ label="Region"
+ layout="topleft"
+ name="Region"
+ tear_off="true">
+ <menu_item_call
+ label="Dump Temp Asset Data"
+ layout="topleft"
+ name="Dump Temp Asset Data">
+ <menu_item_call.on_click
+ function="Admin.HandleRegionDumpTempAssetData" />
+ <menu_item_call.on_enable
+ function="EnableGodCustomerService" />
+ </menu_item_call>
+ <menu_item_call
+ label="Save Region State"
+ layout="topleft"
+ name="Save Region State">
+ <menu_item_call.on_click
+ function="Admin.OnSaveState" />
+ <menu_item_call.on_enable
+ function="EnableGodCustomerService" />
+ </menu_item_call>
+ </menu>
+ <menu_item_call
+ label="God Tools"
+ layout="topleft"
+ name="God Tools">
+ <menu_item_call.on_click
+ function="Floater.Show"
+ parameter="god_tools" />
+ <menu_item_call.on_enable
+ function="EnableGodCustomerService" />
+ </menu_item_call>
+ </menu>
+ <menu
+ create_jump_keys="true"
+ label="Admin"
+ layout="topleft"
+ name="Deprecated"
+ tear_off="true"
+ visible="false">
+ <menu
+ create_jump_keys="true"
+ label="Attach Object"
+ layout="topleft"
+ mouse_opaque="false"
+ name="Attach Object"
+ tear_off="true" />
+ <menu
+ create_jump_keys="true"
+ label="Detach Object"
+ layout="topleft"
+ mouse_opaque="false"
+ name="Detach Object"
+ tear_off="true" />
+ <menu
+ create_jump_keys="true"
+ label="Take Off Clothing"
+ layout="topleft"
+ mouse_opaque="false"
+ name="Take Off Clothing"
+ tear_off="true">
+ <menu_item_call
+ label="Shirt"
+ layout="topleft"
+ name="Shirt">
+ <menu_item_call.on_click
+ function="Edit.TakeOff"
+ parameter="shirt" />
+ <menu_item_call.on_enable
+ function="Edit.EnableTakeOff"
+ parameter="shirt" />
+ </menu_item_call>
+ <menu_item_call
+ label="Pants"
+ layout="topleft"
+ name="Pants">
+ <menu_item_call.on_click
+ function="Edit.TakeOff"
+ parameter="pants" />
+ <menu_item_call.on_enable
+ function="Edit.EnableTakeOff"
+ parameter="pants" />
+ </menu_item_call>
+ <menu_item_call
+ label="Shoes"
+ layout="topleft"
+ name="Shoes">
+ <menu_item_call.on_click
+ function="Edit.TakeOff"
+ parameter="shoes" />
+ <menu_item_call.on_enable
+ function="Edit.EnableTakeOff"
+ parameter="shoes" />
+ </menu_item_call>
+ <menu_item_call
+ label="Socks"
+ layout="topleft"
+ name="Socks">
+ <menu_item_call.on_click
+ function="Edit.TakeOff"
+ parameter="socks" />
+ <menu_item_call.on_enable
+ function="Edit.EnableTakeOff"
+ parameter="socks" />
+ </menu_item_call>
+ <menu_item_call
+ label="Jacket"
+ layout="topleft"
+ name="Jacket">
+ <menu_item_call.on_click
+ function="Edit.TakeOff"
+ parameter="jacket" />
+ <menu_item_call.on_enable
+ function="Edit.EnableTakeOff"
+ parameter="jacket" />
+ </menu_item_call>
+ <menu_item_call
+ label="Gloves"
+ layout="topleft"
+ name="Gloves">
+ <menu_item_call.on_click
+ function="Edit.TakeOff"
+ parameter="gloves" />
+ <menu_item_call.on_enable
+ function="Edit.EnableTakeOff"
+ parameter="gloves" />
+ </menu_item_call>
+ <menu_item_call
+ label="Undershirt"
+ layout="topleft"
+ name="Menu Undershirt">
+ <menu_item_call.on_click
+ function="Edit.TakeOff"
+ parameter="undershirt" />
+ <menu_item_call.on_enable
+ function="Edit.EnableTakeOff"
+ parameter="undershirt" />
+ </menu_item_call>
+ <menu_item_call
+ label="Underpants"
+ layout="topleft"
+ name="Menu Underpants">
+ <menu_item_call.on_click
+ function="Edit.TakeOff"
+ parameter="underpants" />
+ <menu_item_call.on_enable
+ function="Edit.EnableTakeOff"
+ parameter="underpants" />
+ </menu_item_call>
+ <menu_item_call
+ label="Skirt"
+ layout="topleft"
+ name="Skirt">
+ <menu_item_call.on_click
+ function="Edit.TakeOff"
+ parameter="skirt" />
+ <menu_item_call.on_enable
+ function="Edit.EnableTakeOff"
+ parameter="skirt" />
+ </menu_item_call>
+ <menu_item_call
+ label="Alpha"
+ layout="topleft"
+ name="Alpha">
+ <menu_item_call.on_click
+ function="Edit.TakeOff"
+ parameter="alpha" />
+ <menu_item_call.on_enable
+ function="Edit.EnableTakeOff"
+ parameter="alpha" />
+ </menu_item_call>
+ <menu_item_call
+ label="Tattoo"
+ layout="topleft"
+ name="Tattoo">
+ <menu_item_call.on_click
+ function="Edit.TakeOff"
+ parameter="tattoo" />
+ <menu_item_call.on_enable
+ function="Edit.EnableTakeOff"
+ parameter="tattoo" />
+ </menu_item_call>
+ <menu_item_call
+ label="All Clothes"
+ layout="topleft"
+ name="All Clothes">
+ <menu_item_call.on_click
+ function="Edit.TakeOff"
+ parameter="all" />
+ </menu_item_call>
+ </menu>
+ <menu_item_check
+ label="Show Toolbar"
+ layout="topleft"
+ name="Show Toolbar">
+ <menu_item_check.on_check
+ function="FloaterVisible"
+ parameter="toolbar" />
+ <menu_item_check.on_click
+ function="ShowFloater"
+ parameter="toolbar" />
+ </menu_item_check>
+ <menu
+ create_jump_keys="true"
+ label="Help"
+ layout="topleft"
+ name="Help"
+ tear_off="true">
+ <menu_item_call
+ label="Official Linden Blog"
+ layout="topleft"
+ name="Official Linden Blog">
+ <menu_item_call.on_click
+ function="PromptShowURL"
+ name="OfficialLindenBlog_url"
+ parameter="WebLaunchSupportWiki,http://blog.secondlife.com/" />
+ </menu_item_call>
+ <menu_item_call
+ label="Scripting Portal"
+ layout="topleft"
+ name="Scripting Portal">
+ <menu_item_call.on_click
+ function="PromptShowURL"
+ name="ScriptingPortal_url"
+ parameter="WebLaunchLSLWiki,http://wiki.secondlife.com/wiki/LSL_Portal" />
+ </menu_item_call>
+ <menu
+ create_jump_keys="true"
+ label="Bug Reporting"
+ layout="topleft"
+ name="Bug Reporting"
+ tear_off="true">
+ <menu_item_call
+ label="Public Issue Tracker"
+ layout="topleft"
+ name="Public Issue Tracker">
+ <menu_item_call.on_click
+ function="PromptShowURL"
+ name="PublicIssueTracker_url"
+ parameter="WebLaunchPublicIssue,http://jira.secondlife.com" />
+ </menu_item_call>
+ <menu_item_call
+ label="Public Issue Tracker Help"
+ layout="topleft"
+ name="Publc Issue Tracker Help">
+ <menu_item_call.on_click
+ function="PromptShowURL"
+ name="PublicIssueTrackerHelp_url"
+ parameter="WebLaunchPublicIssueHelp,http://wiki.secondlife.com/wiki/Issue_tracker" />
+ </menu_item_call>
+ <menu_item_separator
+ layout="topleft" />
+ <menu_item_call
+ label="Bug Reporting 101"
+ layout="topleft"
+ name="Bug Reporing 101">
+ <menu_item_call.on_click
+ function="PromptShowURL"
+ name="BugReporting101_url"
+ parameter="WebLaunchBugReport101,http://wiki.secondlife.com/wiki/Bug_Reporting_101" />
+ </menu_item_call>
+ <menu_item_call
+ label="Security Issues"
+ layout="topleft"
+ name="Security Issues">
+ <menu_item_call.on_click
+ function="PromptShowURL"
+ name="SecurityIssues_url"
+ parameter="WebLaunchSecurityIssues,http://wiki.secondlife.com/wiki/Security_issues" />
+ </menu_item_call>
+ <menu_item_call
+ label="QA Wiki"
+ layout="topleft"
+ name="QA Wiki">
+ <menu_item_call.on_click
+ function="PromptShowURL"
+ name="QAWiki_url"
+ parameter="WebLaunchQAWiki,http://wiki.secondlife.com/wiki/QA_Portal" />
+ </menu_item_call>
+ </menu>
+ </menu>
+ </menu>
+</menu_bar>
diff --git a/indra/newview/skins/default/xui/en/mime_types.xml b/indra/newview/skins/default/xui/en/mime_types.xml
new file mode 100644
index 0000000000..2de9449ea6
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/mime_types.xml
@@ -0,0 +1,442 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<mimetypes name="default">
+ <defaultlabel>
+ (Unknown)
+ </defaultlabel>
+ <defaultwidget>
+ none
+ </defaultwidget>
+ <defaultimpl>
+ media_plugin_webkit
+ </defaultimpl>
+ <widgetset name="web">
+ <label name="web_label">
+ Web Content
+ </label>
+ <icon>
+ icn_media_web.tga
+ </icon>
+ <default_type>
+ text/html
+ </default_type>
+ <tooltip name="web_tooltip">
+ This location has Web content
+ </tooltip>
+ <playtip name="web_playtip">
+ Show Web content
+ </playtip>
+ <allow_resize>
+ true
+ </allow_resize>
+ <allow_looping>
+ false
+ </allow_looping>
+ </widgetset>
+ <widgetset name="movie">
+ <label name="movie_label">
+ Movie
+ </label>
+ <default_type>
+ video/*
+ </default_type>
+ <icon>
+ icn_media_movie.tga
+ </icon>
+ <tooltip name="movie_tooltip">
+ There is a movie to play here
+ </tooltip>
+ <playtip name="movie_playtip">
+ Play movie
+ </playtip>
+ <allow_resize>
+ false
+ </allow_resize>
+ <allow_looping>
+ true
+ </allow_looping>
+ </widgetset>
+ <widgetset name="image">
+ <label name="image_label">
+ Image
+ </label>
+ <icon>
+ icn_media_web.tga
+ </icon>
+ <default_type>
+ image/*
+ </default_type>
+ <tooltip name="image_tooltip">
+ There is an image at this location
+ </tooltip>
+ <playtip name="image_playtip">
+ View this location&apos;s image
+ </playtip>
+ <allow_resize>
+ false
+ </allow_resize>
+ <allow_looping>
+ false
+ </allow_looping>
+ </widgetset>
+ <widgetset name="audio">
+ <label name="audio_label">
+ Audio
+ </label>
+ <icon>
+ icn_media_web.tga
+ </icon>
+ <default_type>
+ audio/*
+ </default_type>
+ <tooltip name="audio_tooltip">
+ There is audio at this location
+ </tooltip>
+ <playtip name="audio_playtip">
+ Play this location&apos;s audio
+ </playtip>
+ <allow_resize>
+ false
+ </allow_resize>
+ <allow_looping>
+ true
+ </allow_looping>
+ </widgetset>
+ <scheme name="rtsp">
+ <label name="rtsp_label">
+ Real Time Streaming
+ </label>
+ <widgettype>
+ movie
+ </widgettype>
+ <impl>
+ media_plugin_quicktime
+ </impl>
+ </scheme>
+ <mimetype name="blank">
+ <label name="blank_label">
+ - None -
+ </label>
+ <widgettype>
+ none
+ </widgettype>
+ <impl>
+ media_plugin_quicktime
+ </impl>
+ </mimetype>
+ <mimetype name="none/none">
+ <label name="none/none_label">
+ - None -
+ </label>
+ <widgettype>
+ none
+ </widgettype>
+ </mimetype>
+ <mimetype name="audio/*">
+ <label name="audio2_label">
+ Audio
+ </label>
+ <widgettype>
+ audio
+ </widgettype>
+ </mimetype>
+ <mimetype name="video/*">
+ <label name="video2_label">
+ Video
+ </label>
+ <widgettype>
+ movie
+ </widgettype>
+ </mimetype>
+ <mimetype name="image/*">
+ <label name="image2_label">
+ Image
+ </label>
+ <widgettype>
+ image
+ </widgettype>
+ </mimetype>
+ <mimetype menu="1" name="video/vnd.secondlife.qt.legacy">
+ <label name="vnd.secondlife.qt.legacy_label">
+ Movie (QuickTime)
+ </label>
+ <widgettype>
+ movie
+ </widgettype>
+ <impl>
+ media_plugin_quicktime
+ </impl>
+ </mimetype>
+ <mimetype name="application/javascript">
+ <label name="application/javascript_label">
+ Javascript
+ </label>
+ <widgettype>
+ web
+ </widgettype>
+ </mimetype>
+ <mimetype name="application/ogg">
+ <label name="application/ogg_label">
+ Ogg Audio/Video
+ </label>
+ <widgettype>
+ audio
+ </widgettype>
+ </mimetype>
+ <mimetype name="application/pdf">
+ <label name="application/pdf_label">
+ PDF Document
+ </label>
+ <widgettype>
+ image
+ </widgettype>
+ </mimetype>
+ <mimetype name="application/postscript">
+ <label name="application/postscript_label">
+ Postscript Document
+ </label>
+ <widgettype>
+ image
+ </widgettype>
+ </mimetype>
+ <mimetype name="application/rtf">
+ <label name="application/rtf_label">
+ Rich Text (RTF)
+ </label>
+ <widgettype>
+ image
+ </widgettype>
+ </mimetype>
+ <mimetype name="application/smil">
+ <label name="application/smil_label">
+ Synchronized Multimedia Integration Language (SMIL)
+ </label>
+ <widgettype>
+ movie
+ </widgettype>
+ </mimetype>
+ <mimetype name="application/xhtml+xml">
+ <label name="application/xhtml+xml_label">
+ Web Page (XHTML)
+ </label>
+ <widgettype>
+ web
+ </widgettype>
+ </mimetype>
+ <mimetype name="application/x-director">
+ <label name="application/x-director_label">
+ Macromedia Director
+ </label>
+ <widgettype>
+ image
+ </widgettype>
+ </mimetype>
+ <mimetype name="audio/mid">
+ <label name="audio/mid_label">
+ Audio (MIDI)
+ </label>
+ <widgettype>
+ audio
+ </widgettype>
+ <impl>
+ media_plugin_quicktime
+ </impl>
+ </mimetype>
+ <mimetype name="audio/mpeg">
+ <label name="audio/mpeg_label">
+ Audio (MP3)
+ </label>
+ <widgettype>
+ audio
+ </widgettype>
+ <impl>
+ media_plugin_quicktime
+ </impl>
+ </mimetype>
+ <mimetype name="audio/x-aiff">
+ <label name="audio/x-aiff_label">
+ Audio (AIFF)
+ </label>
+ <widgettype>
+ audio
+ </widgettype>
+ <impl>
+ media_plugin_quicktime
+ </impl>
+ </mimetype>
+ <mimetype name="audio/x-wav">
+ <label name="audio/x-wav_label">
+ Audio (WAV)
+ </label>
+ <widgettype>
+ audio
+ </widgettype>
+ <impl>
+ media_plugin_quicktime
+ </impl>
+ </mimetype>
+ <mimetype menu="1" name="image/bmp">
+ <label name="image/bmp_label">
+ Image (BMP)
+ </label>
+ <widgettype>
+ image
+ </widgettype>
+ <impl>
+ media_plugin_webkit
+ </impl>
+ </mimetype>
+ <mimetype menu="1" name="image/gif">
+ <label name="image/gif_label">
+ Image (GIF)
+ </label>
+ <widgettype>
+ image
+ </widgettype>
+ <impl>
+ media_plugin_webkit
+ </impl>
+ </mimetype>
+ <mimetype menu="1" name="image/jpeg">
+ <label name="image/jpeg_label">
+ Image (JPEG)
+ </label>
+ <widgettype>
+ image
+ </widgettype>
+ <impl>
+ media_plugin_webkit
+ </impl>
+ </mimetype>
+ <mimetype menu="1" name="image/png">
+ <label name="image/png_label">
+ Image (PNG)
+ </label>
+ <widgettype>
+ image
+ </widgettype>
+ <impl>
+ media_plugin_webkit
+ </impl>
+ </mimetype>
+ <mimetype name="image/svg+xml">
+ <label name="image/svg+xml_label">
+ Image (SVG)
+ </label>
+ <widgettype>
+ image
+ </widgettype>
+ <impl>
+ media_plugin_webkit
+ </impl>
+ </mimetype>
+ <mimetype menu="1" name="image/tiff">
+ <label name="image/tiff_label">
+ Image (TIFF)
+ </label>
+ <widgettype>
+ image
+ </widgettype>
+ <impl>
+ media_plugin_webkit
+ </impl>
+ </mimetype>
+ <mimetype menu="1" name="text/html">
+ <label name="text/html_label">
+ Web Page
+ </label>
+ <widgettype>
+ web
+ </widgettype>
+ <impl>
+ media_plugin_webkit
+ </impl>
+ </mimetype>
+ <mimetype menu="1" name="text/plain">
+ <label name="text/plain_label">
+ Text
+ </label>
+ <widgettype>
+ text
+ </widgettype>
+ <impl>
+ media_plugin_webkit
+ </impl>
+ </mimetype>
+ <mimetype name="text/xml">
+ <label name="text/xml_label">
+ XML
+ </label>
+ <widgettype>
+ text
+ </widgettype>
+ <impl>
+ media_plugin_webkit
+ </impl>
+ </mimetype>
+ <mimetype menu="1" name="video/mpeg">
+ <label name="video/mpeg_label">
+ Movie (MPEG)
+ </label>
+ <widgettype>
+ movie
+ </widgettype>
+ <impl>
+ media_plugin_quicktime
+ </impl>
+ </mimetype>
+ <mimetype name="video/mp4">
+ <label name="video/mp4_label">
+ Movie (MP4)
+ </label>
+ <widgettype>
+ movie
+ </widgettype>
+ <impl>
+ media_plugin_quicktime
+ </impl>
+ </mimetype>
+ <mimetype menu="1" name="video/quicktime">
+ <label name="video/quicktime_label">
+ Movie (QuickTime)
+ </label>
+ <widgettype>
+ movie
+ </widgettype>
+ <impl>
+ media_plugin_quicktime
+ </impl>
+ </mimetype>
+ <mimetype name="video/x-ms-asf">
+ <label name="video/x-ms-asf_label">
+ Movie (Windows Media ASF)
+ </label>
+ <widgettype>
+ movie
+ </widgettype>
+ <impl>
+ media_plugin_quicktime
+ </impl>
+ </mimetype>
+ <mimetype name="video/x-ms-wmv">
+ <label name="video/x-ms-wmv_label">
+ Movie (Windows Media WMV)
+ </label>
+ <widgettype>
+ movie
+ </widgettype>
+ <impl>
+ media_plugin_quicktime
+ </impl>
+ </mimetype>
+ <mimetype menu="1" name="video/x-msvideo">
+ <label name="video/x-msvideo_label">
+ Movie (AVI)
+ </label>
+ <widgettype>
+ movie
+ </widgettype>
+ <impl>
+ media_plugin_quicktime
+ </impl>
+ </mimetype>
+</mimetypes>
diff --git a/indra/newview/skins/default/xui/en/notifications.xml b/indra/newview/skins/default/xui/en/notifications.xml
new file mode 100644
index 0000000000..98c9ec868a
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/notifications.xml
@@ -0,0 +1,6571 @@
+<?xml version="1.0" ?><notifications>
+
+ <global name="skipnexttime">
+
+ Don&apos;t show me this again
+ </global>
+
+ <global name="alwayschoose">
+
+ Always choose this option
+ </global>
+
+ <global name="implicitclosebutton">
+ Close
+ </global>
+
+ <template name="okbutton">
+ <form>
+ <button
+ default="true"
+ index="0"
+ name="OK"
+ text="$yestext"/>
+ </form>
+ </template>
+
+ <template name="okignore">
+ <form>
+ <button
+ default="true"
+ index="0"
+ name="OK"
+ text="$yestext"/>
+ <ignore text="$ignoretext"/>
+ </form>
+ </template>
+
+ <template name="okcancelbuttons">
+ <form>
+ <button
+ default="true"
+ index="0"
+ name="OK"
+ text="$yestext"/>
+ <button
+ index="1"
+ name="Cancel"
+ text="$notext"/>
+ </form>
+ </template>
+
+ <template name="okcancelignore">
+ <form>
+ <button
+ default="true"
+ index="0"
+ name="OK"
+ text="$yestext"/>
+ <button
+ index="1"
+ name="Cancel"
+ text="$notext"/>
+ <ignore text="$ignoretext"/>
+ </form>
+ </template>
+
+ <template name="okhelpbuttons">
+ <form>
+ <button
+ default="true"
+ index="0"
+ name="OK"
+ text="$yestext"/>
+ <button
+ index="1"
+ name="Help"
+ text="$helptext"/>
+ </form>
+ </template>
+
+ <template name="yesnocancelbuttons">
+ <form>
+ <button
+ default="true"
+ index="0"
+ name="Yes"
+ text="$yestext"/>
+ <button
+ index="1"
+ name="No"
+ text="$notext"/>
+ <button
+ index="2"
+ name="Cancel"
+ text="$canceltext"/>
+ </form>
+ </template>
+
+ <notification
+ functor="GenericAcknowledge"
+ icon="alertmodal.tga"
+ name="MissingAlert"
+ label="Unknown Alert Message"
+ type="alertmodal">
+Your version of [APP_NAME] does not know how to display the alert it just received. Please verify that you have the latest Viewer installed.
+
+Error details: The alert called &apos;[_NAME]&apos; was not found in notifications.xml.
+ <usetemplate
+ name="okbutton"
+ yestext="OK"/>
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="FloaterNotFound"
+ type="alertmodal">
+Floater error: Could not find the following controls:
+
+[CONTROLS]
+ <usetemplate
+ name="okbutton"
+ yestext="OK"/>
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="TutorialNotFound"
+ type="alertmodal">
+No tutorial is currently available.
+ <usetemplate
+ name="okbutton"
+ yestext="OK"/>
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="GenericAlert"
+ type="alertmodal">
+[MESSAGE]
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="GenericAlertYesCancel"
+ type="alertmodal">
+[MESSAGE]
+ <usetemplate
+ name="okcancelbuttons"
+ notext="Cancel"
+ yestext="Yes"/>
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="BadInstallation"
+ type="alertmodal">
+ An error occurred while updating [APP_NAME]. Please download the latest version of the Viewer. http://get.secondlife.com
+ <usetemplate
+ name="okbutton"
+ yestext="Ok"/>
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="LoginFailedNoNetwork"
+ type="alertmodal">
+Could not connect to the [SECOND_LIFE_GRID].
+&apos;[DIAGNOSTIC]&apos;
+Make sure your Internet connection is working properly.
+ <usetemplate
+ name="okbutton"
+ yestext="Ok"/>
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="MessageTemplateNotFound"
+ type="alertmodal">
+Message Template [PATH] not found.
+ <usetemplate
+ name="okbutton"
+ yestext="Ok"/>
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="WearableSave"
+ type="alertmodal">
+Save changes to current clothing/body part?
+ <usetemplate
+ canceltext="Cancel"
+ name="yesnocancelbuttons"
+ notext="Don&apos;t Save"
+ yestext="Save"/>
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="CompileQueueSaveText"
+ type="alertmodal">
+There was a problem uploading the text for a script due to the following reason: [REASON]. Please try again later.
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="CompileQueueSaveBytecode"
+ type="alertmodal">
+There was a problem uploading the compiled script due to the following reason: [REASON]. Please try again later.
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="WriteAnimationFail"
+ type="alertmodal">
+There was a problem writing animation data. Please try again later.
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="UploadAuctionSnapshotFail"
+ type="alertmodal">
+There was a problem uploading the auction snapshot due to the following reason: [REASON]
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="UnableToViewContentsMoreThanOne"
+ type="alertmodal">
+Unable to view the contents of more than one item at a time.
+Please select only one object and try again.
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="SaveClothingBodyChanges"
+ type="alertmodal">
+Save all changes to clothing/body parts?
+ <usetemplate
+ canceltext="Cancel"
+ name="yesnocancelbuttons"
+ notext="Don&apos;t Save"
+ yestext="Save All"/>
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="GrantModifyRights"
+ type="alertmodal">
+Granting modify rights to another resident allows them to change, delete or take ANY objects you may have in-world. Be VERY careful when handing out this permission.
+Do you want to grant modify rights for [FIRST_NAME] [LAST_NAME]?
+ <usetemplate
+ name="okcancelbuttons"
+ notext="No"
+ yestext="Yes"/>
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="GrantModifyRightsMultiple"
+ type="alertmodal">
+Granting modify rights to another resident allows them to change ANY objects you may have in-world. Be VERY careful when handing out this permission.
+Do you want to grant modify rights for the selected Residents?
+ <usetemplate
+ name="okcancelbuttons"
+ notext="No"
+ yestext="Yes"/>
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="RevokeModifyRights"
+ type="alertmodal">
+Do you want to revoke modify rights for [FIRST_NAME] [LAST_NAME]?
+ <usetemplate
+ name="okcancelbuttons"
+ notext="No"
+ yestext="Yes"/>
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="RevokeModifyRightsMultiple"
+ type="alertmodal">
+Do you want to revoke modify rights for the selected Residents?
+ <usetemplate
+ name="okcancelbuttons"
+ notext="No"
+ yestext="Yes"/>
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="UnableToCreateGroup"
+ type="alertmodal">
+Unable to create group.
+[MESSAGE]
+ <usetemplate
+ name="okbutton"
+ yestext="OK"/>
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="PanelGroupApply"
+ type="alertmodal">
+[NEEDS_APPLY_MESSAGE]
+[WANT_APPLY_MESSAGE]
+ <usetemplate
+ canceltext="Cancel"
+ name="yesnocancelbuttons"
+ notext="Ignore Changes"
+ yestext="Apply Changes"/>
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="MustSpecifyGroupNoticeSubject"
+ type="alertmodal">
+You must specify a subject to send a group notice.
+ <usetemplate
+ name="okbutton"
+ yestext="OK"/>
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="AddGroupOwnerWarning"
+ type="alertmodal">
+You are about to add group members to the role of [ROLE_NAME].
+Members cannot be removed from that role.
+The members must resign from the role themselves.
+Are you sure you want to continue?
+ <usetemplate
+ ignoretext="Confirm before I add a new group Owner"
+ name="okcancelignore"
+ notext="No"
+ yestext="Yes"/>
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="AssignDangerousActionWarning"
+ type="alertmodal">
+You are about to add the Ability &apos;[ACTION_NAME]&apos; to the Role &apos;[ROLE_NAME]&apos;.
+
+ *WARNING*
+ Any Member in a Role with this Ability can assign themselves -- and any other member -- to Roles that have more powers than they currently have, potentially elevating themselves to near-Owner power. Be sure you know what you&apos;re doing before assigning this Ability.
+
+Add this Ability to &apos;[ROLE_NAME]&apos;?
+ <usetemplate
+ name="okcancelbuttons"
+ notext="No"
+ yestext="Yes"/>
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="AssignDangerousAbilityWarning"
+ type="alertmodal">
+You are about to add the Ability &apos;[ACTION_NAME]&apos; to the Role &apos;[ROLE_NAME]&apos;.
+
+ *WARNING*
+ Any Member in a Role with this Ability can assign themselves -- and any other member -- all Abilities, elevating themselves to near-Owner power.
+
+Add this Ability to &apos;[ROLE_NAME]&apos;?
+ <usetemplate
+ name="okcancelbuttons"
+ notext="No"
+ yestext="Yes"/>
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="ClickPublishHelpLand"
+ type="alertmodal">
+Selecting the &quot;Publish in Search&quot;
+Checking this box will show:
+- this parcel in search results
+- this parcel&apos;s public objects
+- this parcel in web search
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="ClickSoundHelpLand"
+ type="alertmodal">Media and Music can only be experienced within the parcel. Sound and Voice options can be restricted to the parcel or will be heard by residents outside the parcel depending on their maturity Rating. Go to Knowledge Base to learn more about how to set these options?
+ <url option="0" name="url">
+ https://support.secondlife.com/ics/support/default.asp?deptID=4417&amp;task=knowledge&amp;questionID=5046
+ </url>
+ <usetemplate
+ name="okcancelbuttons"
+ yestext="Go to Knowledge Base"
+ notext="Close" />
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="ClickSearchHelpAll"
+ type="alertmodal">
+Search results are organized based on the tab you are in, your maturity Rating, the category chosen, and other factors. For more details, please see the Knowledge Base.
+ <url option="0" name="url">
+ https://support.secondlife.com/ics/support/default.asp?deptID=4417&amp;task=knowledge&amp;questionID=4722
+ </url>
+ <usetemplate
+ name="okcancelbuttons"
+ yestext="Go to Knowledge Base"
+ notext="Close" />
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="ClickPublishHelpLandDisabled"
+ type="alertmodal">
+You can&apos;t make this parcel show in search because it is located in a region that forbids this.
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="ClickPublishHelpAvatar"
+ type="alertmodal">
+Selecting &quot;Show in Search&quot; will show:
+- my profile in search results
+- a link to my profile in public group pages
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="ClickPartnerHelpAvatar"
+ type="alertmodal">
+You can propose to another Resident or dissolve an existing partnership through the [SECOND_LIFE] website.
+
+Go to the [SECOND_LIFE] web site for more information on partnering?
+ <usetemplate
+ name="okcancelbuttons"
+ notext="Cancel"
+ yestext="Go to Page"/>
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="ClickUploadHelpPermissions"
+ type="alertmodal">
+Your default permissions may not work in older regions.
+ </notification>
+
+<notification
+ icon="alertmodal.tga"
+ name="ClickUnimplemented"
+ type="alertmodal">
+This feature is yet to be implemented.
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="ClickWebProfileHelpAvatar"
+ type="alertmodal">
+If this Resident has set a web profile URL then you can:
+ * Click &apos;Load&apos; to see the page in this Web tab.
+ * Click Load &gt; &apos;In external browser&apos; to view the page in your default web browser.
+ * Click Load &gt; &apos;Home URL&apos; to return to this Resident&apos;s web profile if you&apos;ve navigated away.
+
+When viewing your own profile, you can enter any URL as your web profile and click OK to set it.
+Other residents can visit the URL you set when they look at your profile.
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="JoinGroupCanAfford"
+ type="alertmodal">
+Joining this group costs L$[COST].
+Do you wish to proceed?
+ <usetemplate
+ name="okcancelbuttons"
+ notext="Cancel"
+ yestext="Join"/>
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="JoinGroupCannotAfford"
+ type="alertmodal">
+Joining this group costs L$[COST].
+You do not have enough L$ to join this group.
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="LandBuyPass"
+ type="alertmodal">
+For L$[COST] you can enter this land (&apos;[PARCEL_NAME]&apos;) for [TIME] hours. Buy a pass?
+ <usetemplate
+ name="okcancelbuttons"
+ notext="Cancel"
+ yestext="OK"/>
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="SalePriceRestriction"
+ type="alertmodal">
+Sale price must be set to more than L$0 if selling to anyone.
+Please select an individual to sell to if selling for L$0.
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="ConfirmLandSaleChange"
+ priority="high"
+ type="alertmodal">
+The selected [LAND_SIZE] m² land is being set for sale.
+Your selling price will be L$[SALE_PRICE] and will be authorized for sale to [NAME].
+ <usetemplate
+ name="okcancelbuttons"
+ notext="Cancel"
+ yestext="OK"/>
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="ConfirmLandSaleToAnyoneChange"
+ type="alertmodal">
+ATTENTION: Clicking &apos;sell to anyone&apos; makes your land available to the entire [SECOND_LIFE] community, even those not in this region.
+
+The selected [LAND_SIZE] m² land is being set for sale.
+Your selling price will be L$[SALE_PRICE] and will be authorized for sale to [NAME].
+ <usetemplate
+ name="okcancelbuttons"
+ notext="Cancel"
+ yestext="OK"/>
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="ReturnObjectsDeededToGroup"
+ type="alertmodal">
+Are you sure you want to return all objects shared with the group &apos;[NAME]&apos; on this parcel of land back to their previous owner&apos;s inventory?
+
+*WARNING* This will delete the non-transferable objects deeded to the group!
+
+Objects: [N]
+ <usetemplate
+ name="okcancelbuttons"
+ notext="Cancel"
+ yestext="OK"/>
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="ReturnObjectsOwnedByUser"
+ type="alertmodal">
+Are you sure you want to return all objects owned by the Resident &apos;[NAME]&apos; on this parcel of land back to their inventory?
+
+Objects: [N]
+ <usetemplate
+ name="okcancelbuttons"
+ notext="Cancel"
+ yestext="OK"/>
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="ReturnObjectsOwnedBySelf"
+ type="alertmodal">
+Are you sure you want to return all objects owned by you on this parcel of land back to your inventory?
+
+Objects: [N]
+ <usetemplate
+ name="okcancelbuttons"
+ notext="Cancel"
+ yestext="OK"/>
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="ReturnObjectsNotOwnedBySelf"
+ type="alertmodal">
+Are you sure you want to return all objects NOT owned by you on this parcel of land back to their owner&apos;s inventory?
+Transferable objects deeded to a group will be returned to their previous owners.
+
+*WARNING* This will delete the non-transferable objects deeded to the group!
+
+Objects: [N]
+ <usetemplate
+ name="okcancelbuttons"
+ notext="Cancel"
+ yestext="OK"/>
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="ReturnObjectsNotOwnedByUser"
+ type="alertmodal">
+Are you sure you want to return all objects NOT owned by [NAME] on this parcel of land back to their owner&apos;s inventory?
+Transferable objects deeded to a group will be returned to their previous owners.
+
+*WARNING* This will delete the non-transferable objects deeded to the group!
+
+Objects: [N]
+ <usetemplate
+ name="okcancelbuttons"
+ notext="Cancel"
+ yestext="OK"/>
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="ReturnAllTopObjects"
+ type="alertmodal">
+Are you sure you want to return all listed objects back to their owner&apos;s inventory?
+ <usetemplate
+ name="okcancelbuttons"
+ notext="Cancel"
+ yestext="OK"/>
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="DisableAllTopObjects"
+ type="alertmodal">
+Are you sure you want to disable all objects in this region?
+ <usetemplate
+ name="okcancelbuttons"
+ notext="Cancel"
+ yestext="OK"/>
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="ReturnObjectsNotOwnedByGroup"
+ type="alertmodal">
+Return the objects on this parcel of land that are NOT shared with the group [NAME] back to their owners?
+
+Objects: [N]
+ <usetemplate
+ name="okcancelbuttons"
+ notext="Cancel"
+ yestext="OK"/>
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="UnableToDisableOutsideScripts"
+ type="alertmodal">
+Can not disable scripts.
+This entire region is damage enabled.
+Scripts must be allowed to run for weapons to work.
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="MustBeInParcel"
+ type="alertmodal">
+You must be standing inside the land parcel to set its Landing Point.
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="PromptRecipientEmail"
+ type="alertmodal">
+Please enter a valid email address for the recipient(s).
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="PromptSelfEmail"
+ type="alertmodal">
+Please enter your email address.
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="PromptMissingSubjMsg"
+ type="alertmodal">
+Email snapshot with the default subject or message?
+ <usetemplate
+ name="okcancelbuttons"
+ notext="Cancel"
+ yestext="OK"/>
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="ErrorProcessingSnapshot"
+ type="alertmodal">
+Error processing snapshot data
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="ErrorEncodingSnapshot"
+ type="alertmodal">
+Error encoding snapshot.
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="ErrorUploadingPostcard"
+ type="alertmodal">
+There was a problem sending a snapshot due to the following reason: [REASON]
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="ErrorUploadingReportScreenshot"
+ type="alertmodal">
+There was a problem uploading a report screenshot due to the following reason: [REASON]
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="MustAgreeToLogIn"
+ type="alertmodal">
+You must agree to the Terms of Service to continue logging into [SECOND_LIFE].
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="CouldNotPutOnOutfit"
+ type="alertmodal">
+Could not put on outfit.
+The outfit folder contains no clothing, body parts, or attachments.
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="CannotWearTrash"
+ type="alertmodal">
+You can not wear clothes or body parts that are in the trash
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="CannotWearInfoNotComplete"
+ type="alertmodal">
+You can not wear that item because it has not yet loaded. Please try again in a minute.
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="MustHaveAccountToLogIn"
+ type="alertmodal">
+Oops! Something was left blank.
+You need to enter both the First and Last name of your avatar.
+
+You need an account to enter [SECOND_LIFE]. Would you like to create one now?
+ <url
+ option="0"
+ name="url"
+ openexternally = "1">
+
+ http://secondlife.com/registration/
+ </url>
+ <usetemplate
+ name="okcancelbuttons"
+ notext="Try again"
+ yestext="Create a new account"/>
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="AddClassified"
+ type="alertmodal">
+Classified ads appear in the &apos;Classified&apos; section of the Search directory and on www.secondlife.com for one week.
+Fill out your ad, then click &apos;Publish...&apos; to add it to the directory.
+You&apos;ll be asked for a price to pay when clicking Publish.
+Paying more makes your ad appear higher in the list, and also appear higher when people search for keywords.
+ <usetemplate
+ ignoretext="How to create a new Classified ad"
+ name="okcancelignore"
+ notext="Cancel"
+ yestext="OK"/>
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="DeleteClassified"
+ type="alertmodal">
+Delete classified &apos;[NAME]&apos;?
+There is no reimbursement for fees paid.
+ <usetemplate
+ name="okcancelbuttons"
+ notext="Cancel"
+ yestext="OK"/>
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="ClassifiedSave"
+ type="alertmodal">
+Save changes to classified [NAME]?
+ <usetemplate
+ canceltext="Cancel"
+ name="yesnocancelbuttons"
+ notext="Don&apos;t Save"
+ yestext="Save"/>
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="DeleteAvatarPick"
+ type="alertmodal">
+Delete pick [PICK]?
+ <usetemplate
+ name="okcancelbuttons"
+ notext="Cancel"
+ yestext="OK"/>
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="PromptGoToEventsPage"
+ type="alertmodal">
+Go to the [SECOND_LIFE] events web page?
+ <url option="0" name="url">
+
+ http://secondlife.com/events/
+ </url>
+ <usetemplate
+ name="okcancelbuttons"
+ notext="Cancel"
+ yestext="OK"/>
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="SelectProposalToView"
+ type="alertmodal">
+Please select a proposal to view.
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="SelectHistoryItemToView"
+ type="alertmodal">
+Please select a history item to view.
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="ResetShowNextTimeDialogs"
+ type="alertmodal">
+Would you like to re-enable all these popups, which you previously indicated &apos;Don&apos;t show me again&apos;?
+ <usetemplate
+ name="okcancelbuttons"
+ notext="Cancel"
+ yestext="OK"/>
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="SkipShowNextTimeDialogs"
+ type="alertmodal">
+Would you like to disable all popups which can be skipped?
+ <usetemplate
+ name="okcancelbuttons"
+ notext="Cancel"
+ yestext="OK"/>
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="CacheWillClear"
+ type="alertmodal">
+Cache will be cleared after you restart [APP_NAME].
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="CacheWillBeMoved"
+ type="alertmodal">
+Cache will be moved after you restart [APP_NAME].
+Note: This will clear the cache.
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="ChangeConnectionPort"
+ type="alertmodal">
+Port settings take effect after you restart [APP_NAME].
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="ChangeSkin"
+ type="alertmodal">
+The new skin will appear after you restart [APP_NAME].
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="GoToAuctionPage"
+ type="alertmodal">
+Go to the [SECOND_LIFE] web page to see auction details or make a bid?
+ <url option="0" name="url">
+
+ http://secondlife.com/auctions/auction-detail.php?id=[AUCTION_ID]
+ </url>
+ <usetemplate
+ name="okcancelbuttons"
+ notext="Cancel"
+ yestext="OK"/>
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="SaveChanges"
+ type="alertmodal">
+Save Changes?
+ <usetemplate
+ canceltext="Cancel"
+ name="yesnocancelbuttons"
+ notext="Don&apos;t Save"
+ yestext="Save"/>
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="GestureSaveFailedTooManySteps"
+ type="alertmodal">
+Gesture save failed.
+This gesture has too many steps.
+Try removing some steps, then save again.
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="GestureSaveFailedTryAgain"
+ type="alertmodal">
+Gesture save failed. Please try again in a minute.
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="GestureSaveFailedObjectNotFound"
+ type="alertmodal">
+Could not save gesture because the object or the associated object inventory could not be found.
+The object may be out of range or may have been deleted.
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="GestureSaveFailedReason"
+ type="alertmodal">
+There was a problem saving a gesture due to the following reason: [REASON]. Please try resaving the gesture later.
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="SaveNotecardFailObjectNotFound"
+ type="alertmodal">
+Could not save notecard because the object or the associated object inventory could not be found.
+The object may be out of range or may have been deleted.
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="SaveNotecardFailReason"
+ type="alertmodal">
+There was a problem saving a notecard due to the following reason: [REASON]. Please try re-saving the notecard later.
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="ScriptCannotUndo"
+ type="alertmodal">
+Could not undo all changes in your version of the script.
+Would you like to load the server&apos;s last saved version?
+(**Warning** This operation cannot be undone.)
+ <usetemplate
+ name="okcancelbuttons"
+ notext="Cancel"
+ yestext="OK"/>
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="SaveScriptFailReason"
+ type="alertmodal">
+There was a problem saving a script due to the following reason: [REASON]. Please try re-saving the script later.
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="SaveScriptFailObjectNotFound"
+ type="alertmodal">
+Could not save the script because the object it is in could not be found.
+The object may be out of range or may have been deleted.
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="SaveBytecodeFailReason"
+ type="alertmodal">
+There was a problem saving a compiled script due to the following reason: [REASON]. Please try re-saving the script later.
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="CouldNotStartStopScript"
+ type="alertmodal">
+Could not start or stop the script because the object it is on could not be found.
+The object may be out of range or may have been deleted.
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="CannotDownloadFile"
+ type="alertmodal">
+Unable to download file
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="CannotWriteFile"
+ type="alertmodal">
+Unable to write file [[FILE]]
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="UnsupportedHardware"
+ type="alertmodal">
+Warning: Your system does not meet [APP_NAME]&apos;s minimum system requirements. If you continue using [APP_NAME], you may experience poor performance. Unfortunately, the [SUPPORT_SITE] cannot provide technical support for unsupported system configurations.
+
+MINSPECS
+Do you wish to visit [_URL] for more information?
+ <url option="0" name="url">
+
+ http://www.secondlife.com/corporate/sysreqs.php
+ </url>
+ <usetemplate
+ ignoretext="My computer hardware is not supported"
+ name="okcancelignore"
+ notext="No"
+ yestext="Yes"/>
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="UnknownGPU"
+ type="alertmodal">
+Your system contains a graphics card that is unknown to [APP_NAME] at this time.
+This is often the case with new hardware that hasn&apos;t been tested yet with [APP_NAME]. [APP_NAME] will most likely run properly, but you may need to adjust your graphics settings to something more appropriate.
+(Me &gt; Preferences &gt; Graphics).
+ <form name="form">
+ <ignore name="ignore"
+ text="My graphics card could not be identified"/>
+ </form>
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="DisplaySettingsNoShaders"
+ type="alertmodal">
+[APP_NAME] crashed while initializing graphics drivers.
+Graphics Quality will be set to Low to avoid some common driver errors. This will disable some graphics features.
+We recommend updating your graphics card drivers.
+Graphics Quality can be raised in Preferences &gt; Graphics.
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="RegionNoTerraforming"
+ type="alertmodal">
+The region [REGION] does not allow terraforming.
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="CannotCopyWarning"
+ type="alertmodal">
+You do not have permission to copy this item and will lose it from your inventory if you give it away. Do you really want to offer this item?
+ <usetemplate
+ name="okcancelbuttons"
+ notext="No"
+ yestext="Yes"/>
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="CannotGiveItem"
+ type="alertmodal">
+Unable to give inventory item.
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="TransactionCancelled"
+ type="alertmodal">
+Transaction cancelled.
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="TooManyItems"
+ type="alertmodal">
+Cannot give more than 42 items in a single inventory transfer.
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="NoItems"
+ type="alertmodal">
+You do not have permission to transfer the selected items.
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="CannotCopyCountItems"
+ type="alertmodal">
+You do not have permission to copy [COUNT] of the selected items. You will lose these items from your inventory.
+Do you really want to give these items?
+ <usetemplate
+ name="okcancelbuttons"
+ notext="No"
+ yestext="Yes"/>
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="CannotGiveCategory"
+ type="alertmodal">
+You do not have permission to transfer the selected folder.
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="FreezeAvatar"
+ type="alertmodal">
+Freeze this avatar?
+He or she will temporarily be unable to move, chat, or interact with the world.
+ <usetemplate
+ canceltext="Cancel"
+ name="yesnocancelbuttons"
+ notext="Unfreeze"
+ yestext="Freeze"/>
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="FreezeAvatarFullname"
+ type="alertmodal">
+Freeze [AVATAR_NAME]?
+He or she will temporarily be unable to move, chat, or interact with the world.
+ <usetemplate
+ canceltext="Cancel"
+ name="yesnocancelbuttons"
+ notext="Unfreeze"
+ yestext="Freeze"/>
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="EjectAvatarFullname"
+ type="alertmodal">
+Eject [AVATAR_NAME] from your land?
+ <usetemplate
+ canceltext="Cancel"
+ name="yesnocancelbuttons"
+ notext="Eject and Ban"
+ yestext="Eject"/>
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="EjectAvatarNoBan"
+ type="alertmodal">
+Eject this avatar from your land?
+ <usetemplate
+ name="okcancelbuttons"
+ notext="Cancel"
+ yestext="Eject"/>
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="EjectAvatarFullnameNoBan"
+ type="alertmodal">
+Eject [AVATAR_NAME] from your land?
+ <usetemplate
+ name="okcancelbuttons"
+ notext="Cancel"
+ yestext="Eject"/>
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="AcquireErrorTooManyObjects"
+ type="alertmodal">
+ACQUIRE ERROR: Too many objects selected.
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="AcquireErrorObjectSpan"
+ type="alertmodal">
+ACQUIRE ERROR: Objects span more than one region.
+Please move all objects to be acquired onto the same region.
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="PromptGoToCurrencyPage"
+ type="alertmodal">
+[EXTRA]
+
+Go to [_URL] for information on purchasing currency?
+ <url option="0" name="url">
+
+ http://secondlife.com/app/currency/
+ </url>
+ <usetemplate
+ name="okcancelbuttons"
+ notext="Cancel"
+ yestext="OK"/>
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="UnableToLinkObjects"
+ type="alertmodal">
+Unable to link these [COUNT] objects.
+You can link a maximum of [MAX] objects.
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="CannotLinkIncompleteSet"
+ type="alertmodal">
+You can only link complete sets of objects, and must select more than one object.
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="CannotLinkModify"
+ type="alertmodal">
+Unable to link because you don&apos;t have modify permission on all the objects.
+
+Please make sure none are locked, and that you own all of them.
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="CannotLinkDifferentOwners"
+ type="alertmodal">
+Unable to link because not all of the objects have the same owner.
+
+Please make sure you own all of the selected objects.
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="NoFileExtension"
+ type="alertmodal">
+No file extension for the file: &apos;[FILE]&apos;
+
+Please make sure the file has a correct file extension.
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="InvalidFileExtension"
+ type="alertmodal">
+Invalid file extension [EXTENSION]
+Expected [VALIDS]
+ <usetemplate
+ name="okbutton"
+ yestext="OK"/>
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="CannotUploadSoundFile"
+ type="alertmodal">
+Couldn&apos;t open uploaded sound file for reading:
+[FILE]
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="SoundFileNotRIFF"
+ type="alertmodal">
+File does not appear to be a RIFF WAVE file:
+[FILE]
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="SoundFileNotPCM"
+ type="alertmodal">
+File does not appear to be a PCM WAVE audio file:
+[FILE]
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="SoundFileInvalidChannelCount"
+ type="alertmodal">
+File has invalid number of channels (must be mono or stereo):
+[FILE]
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="SoundFileInvalidSampleRate"
+ type="alertmodal">
+File does not appear to be a supported sample rate (must be 44.1k):
+[FILE]
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="SoundFileInvalidWordSize"
+ type="alertmodal">
+File does not appear to be a supported word size (must be 8 or 16 bit):
+[FILE]
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="SoundFileInvalidHeader"
+ type="alertmodal">
+Could not find &apos;data&apos; chunk in WAV header:
+[FILE]
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="SoundFileInvalidTooLong"
+ type="alertmodal">
+Audio file is too long (10 second maximum):
+[FILE]
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="ProblemWithFile"
+ type="alertmodal">
+Problem with file [FILE]:
+
+[ERROR]
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="CannotOpenTemporarySoundFile"
+ type="alertmodal">
+Couldn&apos;t open temporary compressed sound file for writing: [FILE]
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="UnknownVorbisEncodeFailure"
+ type="alertmodal">
+Unknown Vorbis encode failure on: [FILE]
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="CannotEncodeFile"
+ type="alertmodal">
+Unable to encode file: [FILE]
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="CorruptResourceFile"
+ type="alertmodal">
+Corrupt resource file: [FILE]
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="UnknownResourceFileVersion"
+ type="alertmodal">
+Unknown Linden resource file version in file: [FILE]
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="UnableToCreateOutputFile"
+ type="alertmodal">
+Unable to create output file: [FILE]
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="DoNotSupportBulkAnimationUpload"
+ type="alertmodal">
+[APP_NAME] does not currently support bulk upload of animation files.
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="CannotUploadReason"
+ type="alertmodal">
+Unable to upload [FILE] due to the following reason: [REASON]
+Please try again later.
+ </notification>
+
+ <notification
+ icon="notifytip.tga"
+ name="LandmarkCreated"
+ type="notifytip">
+You have added "[LANDMARK_NAME]" to your [FOLDER_NAME] folder.
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="CannotCreateLandmarkNotOwner"
+ type="alertmodal">
+You cannot create a landmark here because the owner of the land doesn&apos;t allow it.
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="CannotRecompileSelectObjectsNoScripts"
+ type="alertmodal">
+Not able to perform &apos;recompilation&apos;.
+Select an object with a script.
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="CannotRecompileSelectObjectsNoPermission"
+ type="alertmodal">
+Not able to perform &apos;recompilation&apos;.
+
+Select objects with scripts that you have permission to modify.
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="CannotResetSelectObjectsNoScripts"
+ type="alertmodal">
+Not able to perform &apos;reset&apos;.
+
+Select objects with scripts.
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="CannotResetSelectObjectsNoPermission"
+ type="alertmodal">
+Not able to perform &apos;reset&apos;.
+
+Select objects with scripts that you have permission to modify.
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="CannotSetRunningSelectObjectsNoScripts"
+ type="alertmodal">
+Not able to set any scripts to &apos;running&apos;.
+
+Select objects with scripts.
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="CannotSetRunningNotSelectObjectsNoScripts"
+ type="alertmodal">
+Unable to set any scripts to &apos;not running&apos;.
+
+Select objects with scripts.
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="NoFrontmostFloater"
+ type="alertmodal">
+No frontmost floater to save.
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="SeachFilteredOnShortWords"
+ type="alertmodal">
+Your search query was modified and the words that were too short were removed.
+
+Searched for: [FINALQUERY]
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="SeachFilteredOnShortWordsEmpty"
+ type="alertmodal">
+Your search terms were too short so no search was performed.
+ </notification>
+
+ <!-- Generic Teleport failure modes - strings will be inserted from
+ teleport_strings.xml if available. -->
+ <notification
+ icon="alertmodal.tga"
+ name="CouldNotTeleportReason"
+ type="alertmodal">
+Could not teleport.
+[REASON]
+ </notification>
+
+ <!-- Teleport failure modes not delivered via the generic mechanism
+ above (for example, delivered as an AlertMessage on
+ region-crossing :( ) - these paths should really be merged
+ in the future. -->
+ <notification
+ icon="alertmodal.tga"
+ name="invalid_tport"
+ type="alertmodal">
+Problem encountered processing your teleport request. You may need to log back in before you can teleport.
+If you continue to get this message, please check the [SUPPORT_SITE].
+ </notification>
+ <notification
+ icon="alertmodal.tga"
+ name="invalid_region_handoff"
+ type="alertmodal">
+Problem encountered processing your region crossing. You may need to log back in before you can cross regions.
+If you continue to get this message, please check the [SUPPORT_SITE].
+ </notification>
+ <notification
+ icon="alertmodal.tga"
+ name="blocked_tport"
+ type="alertmodal">
+Sorry, teleport is currently blocked. Try again in a moment. If you still cannot teleport, please log out and log back in to resolve the problem.
+ </notification>
+ <notification
+ icon="alertmodal.tga"
+ name="nolandmark_tport"
+ type="alertmodal">
+Sorry, but system was unable to locate landmark destination.
+ </notification>
+ <notification
+ icon="alertmodal.tga"
+ name="timeout_tport"
+ type="alertmodal">
+Sorry, but system was unable to complete the teleport connection. Try again in a moment.
+ </notification>
+ <notification
+ icon="alertmodal.tga"
+ name="noaccess_tport"
+ type="alertmodal">
+Sorry, you do not have access to that teleport destination.
+ </notification>
+ <notification
+ icon="alertmodal.tga"
+ name="missing_attach_tport"
+ type="alertmodal">
+Your attachments have not arrived yet. Try waiting for a few more seconds or log out and back in again before attempting to teleport.
+ </notification>
+ <notification
+ icon="alertmodal.tga"
+ name="too_many_uploads_tport"
+ type="alertmodal">
+The asset queue in this region is currently clogged so your teleport request will not be able to succeed in a timely manner. Please try again in a few minutes or go to a less busy area.
+ </notification>
+ <notification
+ icon="alertmodal.tga"
+ name="expired_tport"
+ type="alertmodal">
+Sorry, but the system was unable to complete your teleport request in a timely fashion. Please try again in a few minutes.
+ </notification>
+ <notification
+ icon="alertmodal.tga"
+ name="expired_region_handoff"
+ type="alertmodal">
+Sorry, but the system was unable to complete your region crossing in a timely fashion. Please try again in a few minutes.
+ </notification>
+ <notification
+ icon="alertmodal.tga"
+ name="no_host"
+ type="alertmodal">
+Unable to find teleport destination. The destination may be temporarily unavailable or no longer exists. Please try again in a few minutes.
+ </notification>
+ <notification
+ icon="alertmodal.tga"
+ name="no_inventory_host"
+ type="alertmodal">
+The inventory system is currently unavailable.
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="CannotSetLandOwnerNothingSelected"
+ type="alertmodal">
+Unable to set land owner:
+No parcel selected.
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="CannotSetLandOwnerMultipleRegions"
+ type="alertmodal">
+Unable to force land ownership because selection spans multiple regions. Please select a smaller area and try again.
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="ForceOwnerAuctionWarning"
+ type="alertmodal">
+This parcel is up for auction. Forcing ownership will cancel the auction and potentially make some residents unhappy if bidding has begun. Force ownership?
+ <usetemplate
+ name="okcancelbuttons"
+ notext="Cancel"
+ yestext="OK"/>
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="CannotContentifyNothingSelected"
+ type="alertmodal">
+Unable to contentify:
+No parcel selected.
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="CannotContentifyNoRegion"
+ type="alertmodal">
+Unable to contentify:
+No region selected.
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="CannotReleaseLandNothingSelected"
+ type="alertmodal">
+Unable to abandon land:
+No parcel selected.
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="CannotReleaseLandNoRegion"
+ type="alertmodal">
+Unable to abandon land:
+Cannot find region.
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="CannotBuyLandNothingSelected"
+ type="alertmodal">
+Unable to buy land:
+No parcel selected.
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="CannotBuyLandNoRegion"
+ type="alertmodal">
+Unable to buy land:
+Cannot find the region this land is in.
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="CannotCloseFloaterBuyLand"
+ type="alertmodal">
+You cannot close the Buy Land window until [APP_NAME] estimates the price of this transaction.
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="CannotDeedLandNothingSelected"
+ type="alertmodal">
+Unable to deed land:
+No parcel selected.
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="CannotDeedLandNoGroup"
+ type="alertmodal">
+Unable to deed land:
+No Group selected.
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="CannotDeedLandNoRegion"
+ type="alertmodal">
+Unable to deed land:
+Cannot find the region this land is in.
+Please use Help &gt; Report Bug to report this.
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="CannotDeedLandMultipleSelected"
+ type="alertmodal">
+Unable to deed land:
+Multiple parcels selected.
+
+Try selecting a single parcel.
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="ParcelCanPlayMedia"
+ type="alertmodal">
+This location can play streaming media.
+Streaming media requires a fast Internet connection.
+
+Play streaming media when available?
+(You can change this option later under Preferences &gt; Audio &amp; Video.)
+ <usetemplate
+ name="okcancelbuttons"
+ notext="Disable"
+ yestext="Play Media"/>
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="CannotDeedLandWaitingForServer"
+ type="alertmodal">
+Unable to deed land:
+Waiting for server to report ownership.
+
+Please try again.
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="CannotDeedLandNoTransfer"
+ type="alertmodal">
+Unable to deed land:
+The region [REGION] does not allow transfer of land.
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="CannotReleaseLandWatingForServer"
+ type="alertmodal">
+Unable to abandon land:
+Waiting for server to update parcel information.
+
+Try again in a few seconds.
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="CannotReleaseLandSelected"
+ type="alertmodal">
+Unable to abandon land:
+You do not own all the parcels selected.
+
+Please select a single parcel.
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="CannotReleaseLandDontOwn"
+ type="alertmodal">
+Unable to abandon land:
+You don&apos;t have permission to release this parcel.
+Parcels you own appear in green.
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="CannotReleaseLandRegionNotFound"
+ type="alertmodal">
+Unable to abandon land:
+Cannot find the region this land is in.
+
+Please use Help &gt; Report Bug to report this.
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="CannotReleaseLandNoTransfer"
+ type="alertmodal">
+Unable to abandon land:
+The region [REGION] does not allow transfer of land.
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="CannotReleaseLandPartialSelection"
+ type="alertmodal">
+Unable to abandon land:
+You must select an entire parcel to release it.
+
+Select an entire parcel, or divide your parcel first.
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="ReleaseLandWarning"
+ type="alertmodal">
+You are about to release [AREA] m² of land.
+Releasing this parcel will remove it from your land holdings, but will not grant any L$.
+
+Release this land?
+ <usetemplate
+ name="okcancelbuttons"
+ notext="Cancel"
+ yestext="OK"/>
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="CannotDivideLandNothingSelected"
+ type="alertmodal">
+Unable to divide land:
+
+No parcels selected.
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="CannotDivideLandPartialSelection"
+ type="alertmodal">
+Unable to divide land:
+
+You have an entire parcel selected.
+Try selecting a part of the parcel.
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="LandDivideWarning"
+ type="alertmodal">
+Dividing this land will split this parcel into two and each parcel can have its own settings. Some settings will be reset to defaults after the operation.
+
+Divide land?
+ <usetemplate
+ name="okcancelbuttons"
+ notext="Cancel"
+ yestext="OK"/>
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="CannotDivideLandNoRegion"
+ type="alertmodal">
+Unable to divide land:
+Cannot find the region this land is in.
+
+Please use Help &gt; Report Bug to report this.
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="CannotJoinLandNoRegion"
+ type="alertmodal">
+Unable to join land:
+Cannot find the region this land is in.
+
+Please use Help &gt; Report Bug to report this.
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="CannotJoinLandNothingSelected"
+ type="alertmodal">
+Unable to join land:
+No parcels selected.
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="CannotJoinLandEntireParcelSelected"
+ type="alertmodal">
+Unable to join land:
+You only have one parcel selected.
+
+Select land across both parcels.
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="CannotJoinLandSelection"
+ type="alertmodal">
+Unable to join land:
+You must select more than one parcel.
+
+Select land across both parcels.
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="JoinLandWarning"
+ type="alertmodal">
+Joining this land will create one large parcel out of all parcels intersecting the selected rectangle.
+You will need to reset the name and options of the new parcel.
+
+Join land?
+ <usetemplate
+ name="okcancelbuttons"
+ notext="Cancel"
+ yestext="OK"/>
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="ShowOwnersHelp"
+ type="alertmodal">
+Show owners:
+Color parcels to show the owner type.
+
+Green = Your land
+Aqua = Your Group&apos;s land
+Red = Owned by others
+Yellow = For sale
+Purple = For auction
+Grey = Public
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="ConfirmNotecardSave"
+ type="alertmodal">
+This notecard needs to be saved before the item can be copied or viewed. Save notecard?
+ <usetemplate
+ name="okcancelbuttons"
+ notext="Cancel"
+ yestext="OK"/>
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="ConfirmItemCopy"
+ type="alertmodal">
+Copy this item to your inventory?
+ <usetemplate
+ name="okcancelbuttons"
+ notext="Cancel"
+ yestext="Copy"/>
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="ResolutionSwitchFail"
+ type="alertmodal">
+Failed to switch resolution to [RESX] by [RESY]
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="ErrorUndefinedGrasses"
+ type="alertmodal">
+Error: Undefined grasses: [SPECIES]
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="ErrorUndefinedTrees"
+ type="alertmodal">
+Error: Undefined trees: [SPECIES]
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="CannotSaveWearableOutOfSpace"
+ type="alertmodal">
+Unable to save &apos;[NAME]&apos; to wearable file. You will need to free up some space on your computer and save the wearable again.
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="CannotSaveToAssetStore"
+ type="alertmodal">
+Unable to save [NAME] to central asset store.
+This is usually a temporary failure. Please customize and save the wearable again in a few minutes.
+
+If this problem persists, please click on Help &gt; Report Bug and provide details about your network setup.
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="YouHaveBeenLoggedOut"
+ type="alertmodal">
+You have been logged out of [SECOND_LIFE]:
+ [MESSAGE]
+You can still look at existing IM and chat by clicking &apos;View IM &amp; Chat&apos;. Otherwise, click &apos;Quit&apos; to exit [APP_NAME] immediately.
+ <usetemplate
+ name="okcancelbuttons"
+ notext="Quit"
+ yestext="View IM &amp; Chat"/>
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="OnlyOfficerCanBuyLand"
+ type="alertmodal">
+Unable to buy land for the group:
+You do not have permission to buy land for your active group.
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ label="Add Friend"
+ name="AddFriend"
+ type="alertmodal">
+Friends can give permissions to track each other on the map and receive online status updates.
+
+Offer friendship to [NAME]?
+ <usetemplate
+ name="okcancelbuttons"
+ notext="Cancel"
+ yestext="OK"/>
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ label="Add Friend"
+ name="AddFriendWithMessage"
+ type="alertmodal">
+Friends can give permissions to track each other on the map and receive online status updates.
+
+Offer friendship to [NAME]?
+ <form name="form">
+ <input name="message" type="text">
+Would you be my friend?
+ </input>
+ <button
+ default="true"
+ index="0"
+ name="Offer"
+ text="OK"/>
+ <button
+ index="1"
+ name="Cancel"
+ text="Cancel"/>
+ </form>
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="RemoveFromFriends"
+ type="alertmodal">
+Do you want to remove [FIRST_NAME] [LAST_NAME] from your Friends List?
+ <usetemplate
+ name="okcancelbuttons"
+ notext="Cancel"
+ yestext="OK"/>
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="RemoveMultipleFromFriends"
+ type="alertmodal">
+Do you want to remove multiple friends from your Friends list?
+ <usetemplate
+ name="okcancelbuttons"
+ notext="Cancel"
+ yestext="OK"/>
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="GodDeleteAllScriptedPublicObjectsByUser"
+ type="alertmodal">
+Are you sure you want to delete all scripted objects owned by
+** [AVATAR_NAME] **
+on all others land in this sim?
+ <usetemplate
+ name="okcancelbuttons"
+ notext="Cancel"
+ yestext="OK"/>
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="GodDeleteAllScriptedObjectsByUser"
+ type="alertmodal">
+Are you sure you want to DELETE ALL scripted objects owned by
+** [AVATAR_NAME] **
+on ALL LAND in this sim?
+ <usetemplate
+ name="okcancelbuttons"
+ notext="Cancel"
+ yestext="OK"/>
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="GodDeleteAllObjectsByUser"
+ type="alertmodal">
+Are you sure you want to DELETE ALL objects (scripted or not) owned by
+** [AVATAR_NAME] **
+on ALL LAND in this sim?
+ <usetemplate
+ name="okcancelbuttons"
+ notext="Cancel"
+ yestext="OK"/>
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="BlankClassifiedName"
+ type="alertmodal">
+You must specify a name for your classified.
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="MinClassifiedPrice"
+ type="alertmodal">
+Price to pay for listing must be at least L$[MIN_PRICE].
+
+Please enter a higher price.
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="ConfirmObjectDeleteLock"
+ type="alertmodal">
+At least one of the items you have selected is locked.
+
+Are you sure you want to delete these items?
+ <usetemplate
+ name="okcancelbuttons"
+ notext="Cancel"
+ yestext="OK"/>
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="ConfirmObjectDeleteNoCopy"
+ type="alertmodal">
+At least one of the items you have selected is not copyable.
+
+Are you sure you want to delete these items?
+ <usetemplate
+ name="okcancelbuttons"
+ notext="Cancel"
+ yestext="OK"/>
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="ConfirmObjectDeleteNoOwn"
+ type="alertmodal">
+You do not own least one of the items you have selected.
+
+Are you sure you want to delete these items?
+ <usetemplate
+ name="okcancelbuttons"
+ notext="Cancel"
+ yestext="OK"/>
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="ConfirmObjectDeleteLockNoCopy"
+ type="alertmodal">
+At least one object is locked.
+At least one object is not copyable.
+
+Are you sure you want to delete these items?
+ <usetemplate
+ name="okcancelbuttons"
+ notext="Cancel"
+ yestext="OK"/>
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="ConfirmObjectDeleteLockNoOwn"
+ type="alertmodal">
+At least one object is locked.
+You do not own least one object.
+
+Are you sure you want to delete these items?
+ <usetemplate
+ name="okcancelbuttons"
+ notext="Cancel"
+ yestext="OK"/>
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="ConfirmObjectDeleteNoCopyNoOwn"
+ type="alertmodal">
+At least one object is not copyable.
+You do not own least one object.
+
+Are you sure you want to delete these items?
+ <usetemplate
+ name="okcancelbuttons"
+ notext="Cancel"
+ yestext="OK"/>
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="ConfirmObjectDeleteLockNoCopyNoOwn"
+ type="alertmodal">
+At least one object is locked.
+At least one object is not copyable.
+You do not own least one object.
+
+Are you sure you want to delete these items?
+ <usetemplate
+ name="okcancelbuttons"
+ notext="cancel"
+ yestext="OK"/>
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="ConfirmObjectTakeLock"
+ type="alertmodal">
+At least one object is locked.
+
+Are you sure you want to take these items?
+ <usetemplate
+ name="okcancelbuttons"
+ notext="Cancel"
+ yestext="OK"/>
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="ConfirmObjectTakeNoOwn"
+ type="alertmodal">
+You do not own all of the objects you are taking.
+If you continue, next owner permissions will be applied and possibly restrict your ability to modify or copy them.
+
+Are you sure you want to take these items?
+ <usetemplate
+ name="okcancelbuttons"
+ notext="Cancel"
+ yestext="OK"/>
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="ConfirmObjectTakeLockNoOwn"
+ type="alertmodal">
+At least one object is locked.
+You do not own all of the objects you are taking.
+If you continue, next owner permissions will be applied and possibly restrict your ability to modify or copy them.
+However, you can take the current selection.
+
+Are you sure you want to take these items?
+ <usetemplate
+ name="okcancelbuttons"
+ notext="Cancel"
+ yestext="OK"/>
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="CantBuyLandAcrossMultipleRegions"
+ type="alertmodal">
+Unable to buy land because selection spans multiple regions.
+
+Please select a smaller area and try again.
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="DeedLandToGroup"
+ type="alertmodal">
+By deeding this parcel, the group will be required to have and maintain sufficient land use credits.
+The purchase price of the land is not refunded to the owner. If a deeded parcel is sold, the sale price will be divided evenly among group members.
+
+Deed this [AREA] m² of land to the group &apos;[GROUP_NAME]&apos;?
+ <usetemplate
+ name="okcancelbuttons"
+ notext="Cancel"
+ yestext="OK"/>
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="DeedLandToGroupWithContribution"
+ type="alertmodal">
+By deeding this parcel, the group will be required to have and maintain sufficient land use credits.
+The deed will include a simultaneous land contribution to the group from &apos;[FIRST_NAME] [LAST_NAME]&apos;.
+The purchase price of the land is not refunded to the owner. If a deeded parcel is sold, the sale price will be divided evenly among group members.
+
+Deed this [AREA] m² of land to the group &apos;[GROUP_NAME]&apos;?
+ <usetemplate
+ name="okcancelbuttons"
+ notext="Cancel"
+ yestext="OK"/>
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="DisplaySetToSafe"
+ type="alertmodal">
+Display settings have been set to safe levels because you have specified the -safe option.
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="DisplaySetToRecommended"
+ type="alertmodal">
+Display settings have been set to recommended levels based on your system configuration.
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="ErrorMessage"
+ type="alertmodal">
+[ERROR_MESSAGE]
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="AvatarMovedDesired"
+ type="alertmodal">
+Your desired location is not currently available.
+You have been moved into a nearby region.
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="AvatarMovedLast"
+ type="alertmodal">
+Your last location is not currently available.
+You have been moved into a nearby region.
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="AvatarMovedHome"
+ type="alertmodal">
+Your home location is not currently available.
+You have been moved into a nearby region.
+You may want to set a new home location.
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="ClothingLoading"
+ type="alertmodal">
+Your clothing is still downloading.
+You can use [SECOND_LIFE] normally and other people will see you correctly.
+ <form name="form">
+ <ignore name="ignore"
+ text="Clothing is taking a long time to download"/>
+ </form>
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="FirstRun"
+ type="alertmodal">
+
+[APP_NAME] installation is complete.
+
+If this is your first time using [SECOND_LIFE], you will need to create an account before you can log in.
+Return to www.secondlife.com to create a new account?
+ <usetemplate
+ name="okcancelbuttons"
+ notext="Continue"
+ yestext="New Account..."/>
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="LoginPacketNeverReceived"
+ type="alertmodal">
+We&apos;re having trouble connecting. There may be a problem with your Internet connection or the [SECOND_LIFE_GRID].
+
+You can either check your Internet connection and try again in a few minutes, click Help to view the [SUPPORT_SITE], or click Teleport to attempt to teleport home.
+ <url option="1" name="url">
+
+ http://secondlife.com/support/
+ </url>
+ <form name="form">
+ <button
+ default="true"
+ index="0"
+ name="OK"
+ text="OK"/>
+ <button
+ index="1"
+ name="Help"
+ text="Help"/>
+ <button
+ index="2"
+ name="Teleport"
+ text="Teleport"/>
+ </form>
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="WelcomeChooseSex"
+ type="alertmodal">
+Your character will appear in a moment.
+
+Use arrow keys to walk.
+Press the F1 key at any time for help or to learn more about [SECOND_LIFE].
+Please choose the male or female avatar. You can change your mind later.
+ <usetemplate
+ name="okcancelbuttons"
+ notext="Female"
+ yestext="Male"/>
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="NotEnoughCurrency"
+ type="alertmodal">
+[NAME] L$ [PRICE] You don&apos;t have enough L$ to do that.
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="GrantedModifyRights"
+ type="alertmodal">
+[FIRST_NAME] [LAST_NAME] has given you permission to edit their objects.
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="RevokedModifyRights"
+ type="alertmodal">
+Your privilege to modify [FIRST_NAME] [LAST_NAME]&apos;s objects has been revoked
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="FlushMapVisibilityCaches"
+ type="alertmodal">
+This will flush the map caches on this region.
+This is really only useful for debugging.
+(In production, wait 5 minutes, then everyone&apos;s map will update after they relog.)
+ <usetemplate
+ name="okcancelbuttons"
+ notext="Cancel"
+ yestext="OK"/>
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="BuyOneObjectOnly"
+ type="alertmodal">
+Unable to buy more than one object at a time. Please select only one object and try again.
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="OnlyCopyContentsOfSingleItem"
+ type="alertmodal">
+Unable to copy the contents of more than one item at a time.
+Please select only one object and try again.
+ <usetemplate
+ name="okcancelbuttons"
+ notext="Cancel"
+ yestext="OK"/>
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="KickUsersFromRegion"
+ type="alertmodal">
+Teleport all Residents in this region home?
+ <usetemplate
+ name="okcancelbuttons"
+ notext="Cancel"
+ yestext="OK"/>
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="EstateObjectReturn"
+ type="alertmodal">
+Are you sure you want to return objects owned by [USER_NAME]?
+ <usetemplate
+ name="okcancelbuttons"
+ notext="Cancel"
+ yestext="OK"/>
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="InvalidTerrainBitDepth"
+ type="alertmodal">
+Couldn&apos;t set region textures:
+Terrain texture [TEXTURE_NUM] has an invalid bit depth of [TEXTURE_BIT_DEPTH].
+
+Replace texture [TEXTURE_NUM] with a 24-bit 512x512 or smaller image then click &quot;Apply&quot; again.
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="InvalidTerrainSize"
+ type="alertmodal">
+Couldn&apos;t set region textures:
+Terrain texture [TEXTURE_NUM] is too large at [TEXTURE_SIZE_X]x[TEXTURE_SIZE_Y].
+
+Replace texture [TEXTURE_NUM] with a 24-bit 512x512 or smaller image then click &quot;Apply&quot; again.
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="RawUploadStarted"
+ type="alertmodal">
+Upload started. It may take up to two minutes, depending on your connection speed.
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="ConfirmBakeTerrain"
+ type="alertmodal">
+Do you really want to bake the current terrain, make it the center for terrain raise/lower limits and the default for the &apos;Revert&apos; tool?
+ <usetemplate
+ name="okcancelbuttons"
+ notext="Cancel"
+ yestext="OK"/>
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="MaxAllowedAgentOnRegion"
+ type="alertmodal">
+You can only have [MAX_AGENTS] Allowed Residents.
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="MaxBannedAgentsOnRegion"
+ type="alertmodal">
+You can only have [MAX_BANNED] Banned Residents.
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="MaxAgentOnRegionBatch"
+ type="alertmodal">
+Failure while attempting to add [NUM_ADDED] agents:
+Exceeds the [MAX_AGENTS] [LIST_TYPE] limit by [NUM_EXCESS].
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="MaxAllowedGroupsOnRegion"
+ type="alertmodal">
+You can only have [MAX_GROUPS] Allowed Groups.
+ <usetemplate
+ name="okcancelbuttons"
+ notext="Cancel"
+ yestext="Bake"/>
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="MaxManagersOnRegion"
+ type="alertmodal">
+You can only have [MAX_MANAGER] Estate Managers.
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="OwnerCanNotBeDenied"
+ type="alertmodal">
+Can&apos;t add estate owner to estate &apos;Banned Resident&apos; list.
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="CanNotChangeAppearanceUntilLoaded"
+ type="alertmodal">
+Can&apos;t change appearance until clothing and shape are loaded.
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="ClassifiedMustBeAlphanumeric"
+ type="alertmodal">
+The name of your classified must start with a letter from A to Z or a number. No punctuation is allowed.
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="CantSetBuyObject"
+ type="alertmodal">
+Can&apos;t set Buy Object, because the object is not for sale.
+Please set the object for sale and try again.
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="FinishedRawDownload"
+ type="alertmodal">
+Finished download of raw terrain file to:
+[DOWNLOAD_PATH].
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="DownloadWindowsMandatory"
+ type="alertmodal">
+A new version of [APP_NAME] is available.
+[MESSAGE]
+You must download this update to use [APP_NAME].
+ <usetemplate
+ name="okcancelbuttons"
+ notext="Quit"
+ yestext="Download"/>
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="DownloadWindows"
+ type="alertmodal">
+An updated version of [APP_NAME] is available.
+[MESSAGE]
+This update is not required, but we suggest you install it to improve performance and stability.
+ <usetemplate
+ name="okcancelbuttons"
+ notext="Continue"
+ yestext="Download"/>
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="DownloadWindowsReleaseForDownload"
+ type="alertmodal">
+An updated version of [APP_NAME] is available.
+[MESSAGE]
+This update is not required, but we suggest you install it to improve performance and stability.
+ <usetemplate
+ name="okcancelbuttons"
+ notext="Continue"
+ yestext="Download"/>
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="DownloadLinuxMandatory"
+ type="alertmodal">
+A new version of [APP_NAME] is available.
+[MESSAGE]
+You must download this update to use [APP_NAME].
+ <usetemplate
+ name="okcancelbuttons"
+ notext="Quit"
+ yestext="Download"/>
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="DownloadLinux"
+ type="alertmodal">
+An updated version of [APP_NAME] is available.
+[MESSAGE]
+This update is not required, but we suggest you install it to improve performance and stability.
+ <usetemplate
+ name="okcancelbuttons"
+ notext="Continue"
+ yestext="Download"/>
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="DownloadLinuxReleaseForDownload"
+ type="alertmodal">
+An updated version of [APP_NAME] is available.
+[MESSAGE]
+This update is not required, but we suggest you install it to improve performance and stability.
+ <usetemplate
+ name="okcancelbuttons"
+ notext="Continue"
+ yestext="Download"/>
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="DownloadMacMandatory"
+ type="alertmodal">
+A new version of [APP_NAME] is available.
+[MESSAGE]
+You must download this update to use [APP_NAME].
+
+Download to your Applications folder?
+ <usetemplate
+ name="okcancelbuttons"
+ notext="Quit"
+ yestext="Download"/>
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="DownloadMac"
+ type="alertmodal">
+An updated version of [APP_NAME] is available.
+[MESSAGE]
+This update is not required, but we suggest you install it to improve performance and stability.
+
+Download to your Applications folder?
+ <usetemplate
+ name="okcancelbuttons"
+ notext="Continue"
+ yestext="Download"/>
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="DownloadMacReleaseForDownload"
+ type="alertmodal">
+An updated version of [APP_NAME] is available.
+[MESSAGE]
+This update is not required, but we suggest you install it to improve performance and stability.
+
+Download to your Applications folder?
+ <usetemplate
+ name="okcancelbuttons"
+ notext="Continue"
+ yestext="Download"/>
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="DeedObjectToGroup"
+ type="alertmodal">
+Deeding this object will cause the group to:
+* Receive L$ paid into the object
+ <usetemplate
+ ignoretext="Confirm before I deed an object to a group"
+ name="okcancelignore"
+ notext="Cancel"
+ yestext="Deed"/>
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="WebLaunchExternalTarget"
+ type="alertmodal">
+Do you want to open your Web browser to view this content?
+ <usetemplate
+ ignoretext="Launch my browser to view a web page"
+ name="okcancelignore"
+ notext="Cancel"
+ yestext="OK"/>
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="WebLaunchJoinNow"
+ type="alertmodal">
+Go to secondlife.com to manage your account?
+ <usetemplate
+ ignoretext="Launch my browser to manage my account"
+ name="okcancelignore"
+ notext="Cancel"
+ yestext="OK"/>
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="WebLaunchBugReport101"
+ type="alertmodal">
+Visit the [SECOND_LIFE] Wiki and learn how to report bugs correctly.
+ <usetemplate
+ ignoretext="Launch my browser to learn how to report a Bug"
+ name="okcancelignore"
+ notext="Cancel"
+ yestext="OK"/>
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="WebLaunchSecurityIssues"
+ type="alertmodal">
+Visit the [SECOND_LIFE] Wiki for details of how to report a security issue.
+ <usetemplate
+ ignoretext="Launch my browser to learn how to report a Security Issue"
+ name="okcancelignore"
+ notext="Cancel"
+ yestext="OK"/>
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="WebLaunchQAWiki"
+ type="alertmodal">
+Visit the [SECOND_LIFE] QA Wiki.
+ <usetemplate
+ ignoretext="Launch my browser to view the QA Wiki"
+ name="okcancelignore"
+ notext="Cancel"
+ yestext="OK"/>
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="WebLaunchPublicIssue"
+ type="alertmodal">
+Visit the [SECOND_LIFE] Public Issue Tracker, where you can report bugs and other issues.
+ <usetemplate
+ ignoretext="Launch my browser to use the Public Issue Tracker"
+ name="okcancelignore"
+ notext="Cancel"
+ yestext="Go to page"/>
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="WebLaunchPublicIssueHelp"
+ type="alertmodal">
+Visit the [SECOND_LIFE] Wiki for info on how to use the Public Issue Tracker.
+ <usetemplate
+ ignoretext="Launch my browser to view instructions for the Public Issue Tracker"
+ name="okcancelignore"
+ notext="Cancel"
+ yestext="Go to page"/>
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="WebLaunchSupportWiki"
+ type="alertmodal">
+Go to the Official Linden Blog, for the latest news and information.
+ <usetemplate
+ ignoretext="Launch my browser to view the blog"
+ name="okcancelignore"
+ notext="Cancel"
+ yestext="OK"/>
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="WebLaunchLSLGuide"
+ type="alertmodal">
+Do you want to open the Scripting Guide for help with scripting?
+ <usetemplate
+ ignoretext="Launch my browser to view the Scripting Guide"
+ name="okcancelignore"
+ notext="Cancel"
+ yestext="OK"/>
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="WebLaunchLSLWiki"
+ type="alertmodal">
+Do you want to visit the LSL Portal for help with scripting?
+ <usetemplate
+ ignoretext="Launch my browser to view the LSL Portal"
+ name="okcancelignore"
+ notext="Cancel"
+ yestext="Go to page"/>
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="ReturnToOwner"
+ type="alertmodal">
+Are you sure you want to return the selected objects to their owners? Transferable deeded objects will be returned to their previous owners.
+
+*WARNING* No-transfer deeded objects will be deleted!
+ <usetemplate
+ ignoretext="Confirm before I return objects to their owners"
+ name="okcancelignore"
+ notext="Cancel"
+ yestext="OK"/>
+ </notification>
+
+ <notification
+ icon="alert.tga"
+ name="GroupLeaveConfirmMember"
+ type="alert">
+You are currently a member of the group [GROUP].
+Leave Group?
+ <usetemplate
+ name="okcancelbuttons"
+ notext="Cancel"
+ yestext="OK"/>
+ </notification>
+
+ <notification
+ icon="alert.tga"
+ name="ConfirmKick"
+ type="alert">
+Do you REALLY want to kick all users off the grid?
+ <usetemplate
+ name="okcancelbuttons"
+ notext="Cancel"
+ yestext="Kick All Users"/>
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="MuteLinden"
+ type="alertmodal">
+Sorry, you cannot block a Linden.
+ <usetemplate
+ name="okbutton"
+ yestext="OK"/>
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="CannotStartAuctionAlreadyForSale"
+ type="alertmodal">
+You cannot start an auction on a parcel which is already set for sale. Disable the land sale if you are sure you want to start an auction.
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ label="Block object by name failed"
+ name="MuteByNameFailed"
+ type="alertmodal">
+You already have blocked this name.
+ <usetemplate
+ name="okbutton"
+ yestext="OK"/>
+ </notification>
+
+ <notification
+ icon="alert.tga"
+ name="RemoveItemWarn"
+ type="alert">
+Though permitted, deleting contents may damage the object. Do you want to delete that item?
+ <usetemplate
+ name="okcancelbuttons"
+ notext="Cancel"
+ yestext="OK"/>
+ </notification>
+
+ <notification
+ icon="alert.tga"
+ name="CantOfferCallingCard"
+ type="alert">
+Cannot offer a calling card at this time. Please try again in a moment.
+ <usetemplate
+ name="okbutton"
+ yestext="OK"/>
+ </notification>
+
+ <notification
+ icon="alert.tga"
+ name="CantOfferFriendship"
+ type="alert">
+Cannot offer friendship at this time. Please try again in a moment.
+ <usetemplate
+ name="okbutton"
+ yestext="OK"/>
+ </notification>
+
+ <notification
+ icon="alert.tga"
+ name="BusyModeSet"
+ type="alert">
+Busy mode is set.
+Chat and instant messages will be hidden. Instant messages will get your Busy mode response. All teleportation offers will be declined. All inventory offers will go to your Trash.
+ <usetemplate
+ ignoretext="I change my status to Busy mode"
+ name="okignore"
+ yestext="OK"/>
+ </notification>
+
+ <notification
+ icon="alert.tga"
+ name="JoinedTooManyGroupsMember"
+ type="alert">
+You have reached your maximum number of groups. Please leave another group before joining this one, or decline the offer.
+[NAME] has invited you to join a group as a member.
+[INVITE]
+ <usetemplate
+ name="okcancelbuttons"
+ notext="Decline"
+ yestext="Join"/>
+ </notification>
+
+ <notification
+ icon="alert.tga"
+ name="KickUser"
+ type="alert">
+Kick this user with what message?
+ <form name="form">
+ <input name="message" type="text">
+An administrator has logged you off.
+ </input>
+ <button
+ default="true"
+ index="0"
+ name="OK"
+ text="OK"/>
+ <button
+ index="1"
+ name="Cancel"
+ text="Cancel"/>
+ </form>
+ </notification>
+
+ <notification
+ icon="alert.tga"
+ name="KickAllUsers"
+ type="alert">
+Kick everyone currently on the grid with what message?
+ <form name="form">
+ <input name="message" type="text">
+An administrator has logged you off.
+ </input>
+ <button
+ default="true"
+ index="0"
+ name="OK"
+ text="OK"/>
+ <button
+ index="1"
+ name="Cancel"
+ text="Cancel"/>
+ </form>
+ </notification>
+
+ <notification
+ icon="alert.tga"
+ name="FreezeUser"
+ type="alert">
+Freeze this user with what message?
+ <form name="form">
+ <input name="message" type="text">
+You have been frozen. You cannot move or chat. An administrator will contact you via instant message (IM).
+ </input>
+ <button
+ default="true"
+ index="0"
+ name="OK"
+ text="OK"/>
+ <button
+ index="1"
+ name="Cancel"
+ text="Cancel"/>
+ </form>
+ </notification>
+
+ <notification
+ icon="alert.tga"
+ name="UnFreezeUser"
+ type="alert">
+Unfreeze this user with what message?
+ <form name="form">
+ <input name="message" type="text">
+You are no longer frozen.
+ </input>
+ <button
+ default="true"
+ index="0"
+ name="OK"
+ text="OK"/>
+ <button
+ index="1"
+ name="Cancel"
+ text="Cancel"/>
+ </form>
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="OfferTeleport"
+ type="alertmodal">
+Offer a teleport to your location with the following message?
+ <form name="form">
+ <input name="message" type="text">
+Join me in [REGION]
+ </input>
+ <button
+ default="true"
+ index="0"
+ name="OK"
+ text="OK"/>
+ <button
+ index="1"
+ name="Cancel"
+ text="Cancel"/>
+ </form>
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="OfferTeleportFromGod"
+ type="alertmodal">
+God summon user to your location?
+ <form name="form">
+ <input name="message" type="text">
+Join me in [REGION]
+ </input>
+ <button
+ default="true"
+ index="0"
+ name="OK"
+ text="OK"/>
+ <button
+ index="1"
+ name="Cancel"
+ text="Cancel"/>
+ </form>
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="TeleportFromLandmark"
+ type="alertmodal">
+Are you sure you want to teleport?
+ <usetemplate
+ ignoretext="Confirm that I want to teleport to a landmark"
+ name="okcancelignore"
+ notext="Cancel"
+ yestext="Teleport"/>
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="TeleportToPick"
+ type="alertmodal">
+Teleport to [PICK]?
+ <usetemplate
+ ignoretext="Confirm that I want to teleport to a location in Picks"
+ name="okcancelignore"
+ notext="Cancel"
+ yestext="Teleport"/>
+ </notification>
+
+ <notification
+ icon="alert.tga"
+ label="Message everyone in your Estate"
+ name="MessageEstate"
+ type="alert">
+Type a short announcement which will be sent to everyone currently in your estate.
+ <form name="form">
+ <input name="message" type="text"/>
+ <button
+ default="true"
+ index="0"
+ name="OK"
+ text="OK"/>
+ <button
+ index="1"
+ name="Cancel"
+ text="Cancel"/>
+ </form>
+ </notification>
+
+ <notification
+ icon="alert.tga"
+ label="Change Linden Estate"
+ name="ChangeLindenEstate"
+ type="alert">
+You are about to change a Linden owned estate (mainland, teen grid, orientation, etc.).
+
+This is EXTREMELY DANGEROUS because it can fundamentally affect the user experience. On the mainland, it will change thousands of regions and make the spaceserver hiccup.
+
+Proceed?
+ <usetemplate
+ name="okcancelbuttons"
+ notext="Cancel"
+ yestext="OK"/>
+ </notification>
+
+ <notification
+ icon="alert.tga"
+ label="Change Linden Estate Access"
+ name="ChangeLindenAccess"
+ type="alert">
+You are about to change the access list for a Linden owned estate (mainland, teen grid, orientation, etc.).
+
+This is DANGEROUS and should only be done to invoke the hack allowing objects/L$ to be transfered in/out of a grid.
+It will change thousands of regions and make the spaceserver hiccup.
+ <usetemplate
+ name="okcancelbuttons"
+ notext="Cancel"
+ yestext="OK"/>
+ </notification>
+
+ <notification
+ icon="alert.tga"
+ label="Select estate"
+ name="EstateAllowedAgentAdd"
+ type="alert">
+Add to allowed list for this estate only or for [ALL_ESTATES]?
+ <usetemplate
+ canceltext="Cancel"
+ name="yesnocancelbuttons"
+ notext="All Estates"
+ yestext="This Estate"/>
+ </notification>
+
+ <notification
+ icon="alert.tga"
+ label="Select estate"
+ name="EstateAllowedAgentRemove"
+ type="alert">
+Remove from allowed list for this estate only or for [ALL_ESTATES]?
+ <usetemplate
+ canceltext="Cancel"
+ name="yesnocancelbuttons"
+ notext="All Estates"
+ yestext="This Estate"/>
+ </notification>
+
+ <notification
+ icon="alert.tga"
+ label="Select estate"
+ name="EstateAllowedGroupAdd"
+ type="alert">
+Add to group allowed list for this estate only or for [ALL_ESTATES]?
+ <usetemplate
+ canceltext="Cancel"
+ name="yesnocancelbuttons"
+ notext="All Estates"
+ yestext="This Estate"/>
+ </notification>
+
+ <notification
+ icon="alert.tga"
+ label="Select estate"
+ name="EstateAllowedGroupRemove"
+ type="alert">
+Remove from group allowed list for this estate only or [ALL_ESTATES]?
+ <usetemplate
+ canceltext="Cancel"
+ name="yesnocancelbuttons"
+ notext="All Estates"
+ yestext="This Estate"/>
+ </notification>
+
+ <notification
+ icon="alert.tga"
+ label="Select estate"
+ name="EstateBannedAgentAdd"
+ type="alert">
+Deny access for this estate only or for [ALL_ESTATES]?
+ <usetemplate
+ canceltext="Cancel"
+ name="yesnocancelbuttons"
+ notext="All Estates"
+ yestext="This Estate"/>
+ </notification>
+
+ <notification
+ icon="alert.tga"
+ label="Select estate"
+ name="EstateBannedAgentRemove"
+ type="alert">
+Remove this Resident from the ban list for access for this estate only or for [ALL_ESTATES]?
+ <usetemplate
+ canceltext="Cancel"
+ name="yesnocancelbuttons"
+ notext="All Estates"
+ yestext="This Estate"/>
+ </notification>
+
+ <notification
+ icon="alert.tga"
+ label="Select estate"
+ name="EstateManagerAdd"
+ type="alert">
+Add estate manager for this estate only or for [ALL_ESTATES]?
+ <usetemplate
+ canceltext="Cancel"
+ name="yesnocancelbuttons"
+ notext="All Estates"
+ yestext="This Estate"/>
+ </notification>
+
+ <notification
+ icon="alert.tga"
+ label="Select estate"
+ name="EstateManagerRemove"
+ type="alert">
+Remove estate manager for this estate only or for [ALL_ESTATES]?
+ <usetemplate
+ canceltext="Cancel"
+ name="yesnocancelbuttons"
+ notext="All Estates"
+ yestext="This Estate"/>
+ </notification>
+
+ <notification
+ icon="alert.tga"
+ label="Confirm Kick"
+ name="EstateKickUser"
+ type="alert">
+Kick [EVIL_USER] from this estate?
+ <usetemplate
+ name="okcancelbuttons"
+ notext="Cancel"
+ yestext="OK"/>
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="EstateChangeCovenant"
+ type="alertmodal">
+Are you sure you want to change the Estate Covenant?
+ <usetemplate
+ name="okcancelbuttons"
+ notext="Cancel"
+ yestext="OK"/>
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="RegionEntryAccessBlocked"
+ type="alertmodal">
+You are not allowed in that Region due to your maturity Rating. This may be a result of a lack of information validating your age.
+
+Please verify you have the latest Viewer installed, and go to the Knowledge Base for details on accessing areas with this maturity rating.
+ <usetemplate
+ name="okbutton"
+ yestext="OK"/>
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="RegionEntryAccessBlocked_KB"
+ type="alertmodal">
+You are not allowed in that region due to your maturity Rating.
+
+Go to the Knowledge Base for more information about maturity Ratings?
+ <url option="0" name="url">
+ https://support.secondlife.com/ics/support/default.asp?deptID=4417&amp;task=knowledge&amp;questionID=6010
+ </url>
+ <usetemplate
+ name="okcancelignore"
+ yestext="Go to Knowledge Base"
+ notext="Close"
+ ignoretext="I can&apos;t enter this Region, due to restrictions of the maturity Rating"/>
+ </notification>
+
+ <notification
+ icon="notifytip.tga"
+ name="RegionEntryAccessBlocked_Notify"
+ type="notifytip">
+You are not allowed in that region due to your maturity Rating.
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="RegionEntryAccessBlocked_Change"
+ type="alertmodal">
+You are not allowed in that Region due to your maturity Rating preference.
+
+You can click &apos;Change Preference&apos; to raise your maturity Rating preference now and allow you to enter. You will be able to search and access [REGIONMATURITY] content from now on. If you later want to change this setting back, go to Me &gt; Preferences &gt; General.
+ <form name="form">
+ <button
+ index="0"
+ name="OK"
+ text="Change Preference"/>
+ <button
+ default="true"
+ index="1"
+ name="Cancel"
+ text="Close"/>
+ <ignore name="ignore" text="My chosen Rating preference prevents me from entering a Region"/>
+ </form>
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="LandClaimAccessBlocked"
+ type="alertmodal">
+You cannot claim this land due to your maturity Rating. This may be a result of a lack of information validating your age.
+
+Please verify you have the latest Viewer installed, and go to the Knowledge Base for details on accessing areas with this maturity rating.
+ <usetemplate
+ name="okbutton"
+ yestext="OK"/>
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="LandClaimAccessBlocked_KB"
+ type="alertmodal">
+You cannot claim this land due to your maturity Rating.
+
+Go to the Knowledge Base for more information about maturity Ratings?
+ <url option="0" name="url">
+ https://support.secondlife.com/ics/support/default.asp?deptID=4417&amp;task=knowledge&amp;questionID=6010
+ </url>
+ <usetemplate
+ name="okcancelignore"
+ yestext="Go to Knowledge Base"
+ notext="Close"
+ ignoretext="I can&apos;t claim this Land, due to restrictions of the maturity Rating"/>
+ </notification>
+
+ <notification
+ icon="notifytip.tga"
+ name="LandClaimAccessBlocked_Notify"
+ type="notifytip">
+You cannot claim this land due to your maturity Rating.
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="LandClaimAccessBlocked_Change"
+ type="alertmodal">
+You cannot claim this land due to your maturity Rating preference.
+
+You can click &apos;Change Preference&apos; to raise your maturity Rating preference now and allow you to enter. You will be able to search and access [REGIONMATURITY] content from now on. If you later want to change this setting back, go to Me &gt; Preferences &gt; General.
+ <usetemplate
+ name="okcancelignore"
+ yestext="Change Preference"
+ notext="Close"
+ ignoretext="My chosen Rating preference prevents me from claiming Land"/>
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="LandBuyAccessBlocked"
+ type="alertmodal">
+You cannot buy this land due to your maturity Rating. This may be a result of a lack of information validating your age.
+
+Please verify you have the latest Viewer installed, and go to the Knowledge Base for details on accessing areas with this maturity rating.
+ <usetemplate
+ name="okbutton"
+ yestext="OK"/>
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="LandBuyAccessBlocked_KB"
+ type="alertmodal">
+You cannot buy this land due to your maturity Rating.
+
+Go to the Knowledge Base for more information about maturity Ratings?
+ <url option="0" name="url">
+ https://support.secondlife.com/ics/support/default.asp?deptID=4417&amp;task=knowledge&amp;questionID=6010
+ </url>
+ <usetemplate
+ name="okcancelignore"
+ yestext="Go to Knowledge Base"
+ notext="Close"
+ ignoretext="I can&apos;t buy this Land, due to restrictions of the maturity Rating"/>
+ </notification>
+
+ <notification
+ icon="notifytip.tga"
+ name="LandBuyAccessBlocked_Notify"
+ type="notifytip">
+You cannot buy this land due to your maturity Rating.
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="LandBuyAccessBlocked_Change"
+ type="alertmodal">
+You cannot buy this land due to your maturity Rating preference.
+
+You can click &apos;Change Preference&apos; to raise your maturity Rating preference now and allow you to enter. You will be able to search and access [REGIONMATURITY] content from now on. If you later want to change this setting back, go to Me &gt; Preferences &gt; General.
+ <usetemplate
+ name="okcancelignore"
+ yestext="Change Preference"
+ notext="Close"
+ ignoretext="My chosen Rating preference prevents me from buying Land"/>
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="TooManyPrimsSelected"
+ type="alertmodal">
+ "There are too many prims selected. Please select [MAX_PRIM_COUNT] or fewer prims and try again"
+ <usetemplate
+ name="okbutton"
+ yestext="OK"/>
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="ProblemImportingEstateCovenant"
+ type="alertmodal">
+Problem importing estate covenant.
+ <usetemplate
+ name="okbutton"
+ yestext="OK"/>
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="ProblemAddingEstateManager"
+ type="alertmodal">
+Problems adding a new estate manager. One or more estates may have a full manager list.
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="ProblemAddingEstateGeneric"
+ type="alertmodal">
+Problems adding to this estate list. One or more estates may have a full list.
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="UnableToLoadNotecardAsset"
+ type="alertmodal">
+Unable to load notecard&apos;s asset at this time.
+ <usetemplate
+ name="okbutton"
+ yestext="OK"/>
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="NotAllowedToViewNotecard"
+ type="alertmodal">
+Insufficient permissions to view notecard associated with asset ID requested.
+ <usetemplate
+ name="okbutton"
+ yestext="OK"/>
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="MissingNotecardAssetID"
+ type="alertmodal">
+Asset ID for notecard is missing from database.
+ <usetemplate
+ name="okbutton"
+ yestext="OK"/>
+ </notification>
+
+ <notification
+ icon="alert.tga"
+ name="PublishClassified"
+ type="alert">
+Remember: Classified ad fees are non-refundable.
+
+Publish this classified now for L$[AMOUNT]?
+ <usetemplate
+ name="okcancelbuttons"
+ notext="Cancel"
+ yestext="OK"/>
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="SetClassifiedMature"
+ type="alertmodal">
+Does this classified contain Mature content?
+ <usetemplate
+ canceltext="Cancel"
+ name="yesnocancelbuttons"
+ notext="No"
+ yestext="Yes"/>
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="SetGroupMature"
+ type="alertmodal">
+Does this group contain Mature content?
+ <usetemplate
+ canceltext="Cancel"
+ name="yesnocancelbuttons"
+ notext="No"
+ yestext="Yes"/>
+ </notification>
+
+ <notification
+ icon="alert.tga"
+ label="Confirm restart"
+ name="ConfirmRestart"
+ type="alert">
+Do you really want to restart this region in 2 minutes?
+ <usetemplate
+ name="okcancelbuttons"
+ notext="Cancel"
+ yestext="OK"/>
+ </notification>
+
+ <notification
+ icon="alert.tga"
+ label="Message everyone in this region"
+ name="MessageRegion"
+ type="alert">
+Type a short announcement which will be sent to everyone in this region.
+ <form name="form">
+ <input name="message" type="text"/>
+ <button
+ default="true"
+ index="0"
+ name="OK"
+ text="OK"/>
+ <button
+ index="1"
+ name="Cancel"
+ text="Cancel"/>
+ </form>
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ label="Block Terraform"
+ name="HelpRegionBlockTerraform"
+ type="alertmodal">
+If this box is checked, land owners will not be able to terraform their land regardless of the per-parcel &apos;Edit Terrain&apos; setting.
+
+Default: off
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ label="Block Fly"
+ name="HelpRegionBlockFly"
+ type="alertmodal">
+If this box is checked, people will not be able to fly in this region regardless of the per-parcel &apos;Fly&apos; setting.
+
+Default: off
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ label="Bulk Change Content Permissions"
+ name="HelpBulkPermission"
+ type="alertmodal">
+The Bulk Permissions tool helps you to quickly change the permissions on multiple items in the contents of the selected object(s). However, please note that you are only setting permissions on the items in the Contents of the selected objects -- not permissions on the container object(s) themselves.
+
+Also note, the permissions are not applied to the nested contents of any of the contained items. Your request only operates on items exactly one level deep.
+
+You can selectively choose which types of items to modify by using the checklist under &apos;Content Types&apos; here. Snapshots are included when you select Textures.
+
+* This tool will only succeed at changing permissions on items you are allowed to change.
+* You cannot grant any Next owner permissions which you do not already have.
+* The Next owner permissions are merely requests. If any item cannot take all of the new permissions, none of its permissions will change.
+
+When you are ready to change the permissions in bulk, click &apos;Apply&apos; and wait for the results to display.
+
+If you close the Bulk Permissions window while permissions are being changed, it will halt the operation.
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ label="Allow Damage"
+ name="HelpRegionAllowDamage"
+ type="alertmodal">
+If this box is checked, the health system across all parcels regardless of individual parcel settings. If this box is left unchecked, individual parcel owners will still be able to activate the health system on their parcels.
+
+Default: off
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ label="Agent Limit"
+ name="HelpRegionAgentLimit"
+ type="alertmodal">
+Sets the maximum number of avatars allowed in this region.
+Performance may vary depending on the number avatars present.
+
+Default: 40
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ label="Object Bonus"
+ name="HelpRegionObjectBonus"
+ type="alertmodal">
+The Object Bonus is a multiplier for primitives allowed on any given parcel. The range allowed is 1 to 10. Set at &apos;1&apos;, each 512m² parcel is allowed 117 objects. Set at &apos;2&apos;, each 512m² parcel is allowed 234, or twice as many, and so on. The max number of objects allowed per region remains 15,000 no matter what the Object Bonus is. Once set, be aware that lowering the Object Bonus may cause objects to be returned or deleted.
+
+Default: 1.0
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ label="Maturity"
+ name="HelpRegionMaturity"
+ type="alertmodal">
+Sets the maturity Rating of the Region, as shown in the menu bar at the top of any Resident&apos;s viewer, and in tooltips on the World Map when the cursor hovers over this Region. This setting also affects access to this Region and search results. Other Residents may only enter Regions or view search results with the same maturity Ratings they have chosen in their preferences.
+
+It may take some time for this change to be reflected on the map.
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ label="Restrict Pushing"
+ name="HelpRegionRestrictPushObject"
+ type="alertmodal">
+This checkbox sets the full region to restricted push permissions.
+When enabled, Residents may only be pushed by themselves or by the parcel&apos;s owner.
+(Push refers to the llPushObject() LSL function.)
+
+Default: Off
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ label="Parcel Join/Subdivide"
+ name="HelpParcelChanges"
+ type="alertmodal">
+This checkbox sets whether or not parcels not owned by the estate owner can be joined or subdivided.
+If this option is unchecked:
+ * Only estate owners or managers can join or subdivide parcels.
+ * They may only join or subdivide parcels belonging to the owner, or to a group where they have the appropriate group powers.
+If this option is checked:
+ * All parcel owners can join or subdivide the parcels they own.
+ * For group owned parcels, those with appropriate group powers may join or subdivide parcels.
+
+Default: Checked
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ label="Do Not Show In Search"
+ name="HelpRegionSearch"
+ type="alertmodal">
+Checking this box will block parcel owners from listing their parcels in search.
+
+Default: Off
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ label="Changed Region Maturity"
+ name="RegionMaturityChange"
+ type="alertmodal">
+The maturity rating for this region has been updated.
+It may take some time for the change to be reflected on the map.
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ label="Land Resale"
+ name="HelpRegionLandResell"
+ type="alertmodal">
+Estate owners and managers can sell any land owned by the estate owner.
+If this option is left unchecked, buyers cannot resell their land in this region.
+If this option is checked, buyers can resell their land in this region.
+
+Default: Disallow
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ label="Disable Scripts"
+ name="HelpRegionDisableScripts"
+ type="alertmodal">
+When sim performance is poor, a script may be to blame. Open the Statistics Bar (Ctrl-Shift-1). Look at the Simulator Physics FPS.
+If it is lower than 45, open the Time panel located at the bottom of the Stats Bar. If Script Time reads 25 ms or higher, click the Get Top Scripts button. You will be given the name and location of scripts that may be causing poor performance.
+
+Checking the Disable Scripts box and then pressing the Apply button will temporarily disable all scripts in this region. You may need to do this in order to travel to the location of a noted &apos;top script&apos;. Once you have arrived at the location, investigate the script to determine if it is causing the problem. You may want to contact the owner of the script or delete or return the object.
+Uncheck the Disable Script box and then Apply to reactivate the scripts in the region.
+
+Default: off
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ label="Disable Collisions"
+ name="HelpRegionDisableCollisions"
+ type="alertmodal">
+When sim performance is poor, physical objects may be to blame.
+Open the Statistics Bar (Ctrl-Shift-1). Look at the Simulator Physics FPS. If it is lower than 45, open the Time panel located at the bottom of the Stats Bar. If Sim Time (Physics) reads 20 ms or higher, click the Get Top Colliders button.
+You will be given the name and location of physical objects that may be causing poor performance.
+
+Checking the Disable Collisions box and then pressing the Apply button will temporarily disable object-object collisions. You may need to do this in order to travel to the location of a noted &apos;top collider&apos;. Once you have arrived at the location, investigate the object - is it constantly colliding with other objects? You may want to contact the owner of the object or delete or return the object.
+Uncheck the Disable Collisions box and then Apply to reactivate collisions in the region.
+
+Default: off
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ label="Disable Physics"
+ name="HelpRegionDisablePhysics"
+ type="alertmodal">
+Disable Physics is similar to Disable Collisions, except all physics simulation is disabled. This means that not only will objects stop colliding, but avatars will be unable to move.
+
+This should only be used when Disable Collisions does not give back enough performance to the region to investigate a physics problem or Top Collider.
+
+Be sure to re-enable physics when you are done, or avatars will continue to be unable to move.
+
+Default: off
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ label="Top Colliders"
+ name="HelpRegionTopColliders"
+ type="alertmodal">
+Show a list of objects experiencing the greatest number of potential object-object collisions. These objects can slow performance. Select Advanced &gt; Performance Tools &gt; Statistics Bar and look under Simulator &gt; Time &gt; Physics Time to see if more than 20 ms is being spent in physics.
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ label="Top Scripts"
+ name="HelpRegionTopScripts"
+ type="alertmodal">
+Show a list of objects spending the most time running LSL scripts. These objects can slow performance.
+Select Advanced &gt; Performance Tools &gt; Statistics Bar and look under Simulator &gt; Time &gt; Script Time to see if more than 25 ms is being spent in scripts.
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ label="Restart Region"
+ name="HelpRegionRestart"
+ type="alertmodal">
+Restart the server process running this region after a two minute warning. All Residents in the region will be disconnected. The region will save its data, and should come back up within 90 seconds.
+
+Restarting the region will not fix most performance problems, and should usually be used only when directed.
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ label="Water Height"
+ name="HelpRegionWaterHeight"
+ type="alertmodal">
+This is the height in meters where water appears. If this setting is anything other than 20 and you have water that is adjacent to the edge of world or &apos;void&apos; water, there will be a visible gap.
+
+Default: 20
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ label="Terrain Raise"
+ name="HelpRegionTerrainRaise"
+ type="alertmodal">
+This is the distance in meters that parcel owners can raise their terrain above the &apos;baked&apos; terrain default height.
+
+Default: 4
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ label="Terrain Lower"
+ name="HelpRegionTerrainLower"
+ type="alertmodal">
+This is the distance in meters that parcel owners can lower their terrain below the &apos;baked&apos; terrain default height.
+
+Default: -4
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ label="Upload RAW Terrain"
+ name="HelpRegionUploadRaw"
+ type="alertmodal">
+This button uploads a .RAW file to the region you are in.
+The file must have the correct dimensions (RGB, 256x256) and 13 channels. The best way to create a terrain file is to download the existing RAW file. A good first step is to modify the red channel (land height), and upload it.
+
+The upload can take up to 45 seconds. Note that uploading a terrain file *will not* move the objects that are on the land, only the terrain itself and the permissions associated with the parcels. This can result in objects going underground.
+
+For more information on editing region height fields, consult F1 Help.
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ label="Download RAW Terrain"
+ name="HelpRegionDownloadRaw"
+ type="alertmodal">
+This button downloads a file containing the height field data, parcel dimensions, parcel for sale status and some parcel permissions for this region. When opening the file in a program such as Photoshop you must specify the document&apos;s dimensions which are: RGB, 256x256 with 13 channels. This terrain file cannot be opened in any other way.
+
+For more information on editing region height fields, consult F1 help.
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ label="Use Estate Sun"
+ name="HelpRegionUseEstateSun"
+ type="alertmodal">
+This checkbox makes the sun position in this region the same as the sun position in the rest of the estate.
+
+Default: on
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ label="Fixed Sun"
+ name="HelpRegionFixedSun"
+ type="alertmodal">
+This checkbox sets the sun position to the position in the Phase slider and stops the sun from moving.
+
+Default: off
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ label="Bake Terrain"
+ name="HelpRegionBakeTerrain"
+ type="alertmodal">
+This button saves the current shape of the terrain as the new default for the region. Once baked, the land can revert to the saved shape whenever you or others use the Edit Terrain &apos;Revert&apos; option. The baked terrain is also the middle point for the terrain raise and lower limits.
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ label="Estate Managers"
+ name="HelpEstateEstateManager"
+ type="alertmodal">
+An estate manager is a Resident to whom you have delegated control of region and estate settings. An estate manager can change any setting in these panels, except for uploading, downloading, and baking terrain. In particular, they can allow or ban Residents from your estate.
+
+Estate managers can only be added or removed by the owner of the estate, not by each other. Please only choose Residents you trust as estate managers, as you will be ultimately responsible for their actions.
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ label="Use Global Time"
+ name="HelpEstateUseGlobalTime"
+ type="alertmodal">
+This checkbox makes the sun in your estate follow the same position as on the Linden-owned &apos;mainland&apos; estates.
+
+Default: on
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ label="Fixed Sun"
+ name="HelpEstateFixedSun"
+ type="alertmodal">
+This checkbox sets the sun position to the position in the Phase slider and stops the sun from moving.
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ label="Public Access"
+ name="HelpEstateExternallyVisible"
+ type="alertmodal">
+This checkbox sets whether Residents who are on other estates can enter this estate without being on an access list.
+
+Default: on
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ label="Allow Direct Teleport"
+ name="HelpEstateAllowDirectTeleport"
+ type="alertmodal">
+When checked, allows Residents to directly teleport to any point in your estate. When unchecked, Residents teleport to the nearest telehub.
+
+Default: off
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ label="Allow Access"
+ name="HelpEstateAllowResident"
+ type="alertmodal">
+Access to this estate will be limited to Residents listed here and any groups below. This setting is only available when Public Access is unchecked.
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ label="Allow Group Access"
+ name="HelpEstateAllowGroup"
+ type="alertmodal">
+Access to this estate will be limited to groups listed here and any Residents above. This setting is only available when Public Access is unchecked.
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ label="Abuse Email Address"
+ name="HelpEstateAbuseEmailAddress"
+ type="alertmodal">
+Setting this to a valid email address will cause abuse reports on this estate to be sent to that address.
+Setting it blank will cause abuse reports to be sent only to Linden Lab.
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ label="Deny Access"
+ name="HelpEstateBanResident"
+ type="alertmodal">
+Residents on this list are denied access to your estate, regardless of any other settings.
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ label="Allow Voice Chat"
+ name="HelpEstateVoiceChat"
+ type="alertmodal">
+Parcels in this estate are allowed to have their own voice channels in which residents may hear and talk with others nearby.
+
+Default: off
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ label="Voice Version Mismatch"
+ name="VoiceVersionMismatch"
+ type="alertmodal">
+This version of [APP_NAME] is not compatible with the Voice Chat feature in this region. In order for Voice Chat to function correctly you will need to update [APP_NAME].
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ label="Estate Covenant"
+ name="HelpEstateCovenant"
+ type="alertmodal">
+Setting an estate covenant enables you to sell parcels within that estate. If a covenant is not set, you cannot sell the land. The notecard for your covenant can be empty if you do not wish to apply any rules or advise buyers of anything in relation to the land before they buy it.
+
+A covenant can be used to communicate rules, guidelines, cultural information or simply your own expectations to the prospective buyer. This can include zoning, building regulations, payment options or any other information you feel it is important for the new owner to have seen and to have agreed to before they purchase.
+
+The buyer must agree to the covenant by ticking the check box before they will be able to finish the purchase. Estate covenants are always visible in the About Land dialog for any parcels that have one set.
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ label="Can&apos;t Buy Objects"
+ name="BuyObjectOneOwner"
+ type="alertmodal">
+Cannot buy objects from different owners at the same time.
+Please select only one object and try again.
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ label="Can&apos;t Buy Contents"
+ name="BuyContentsOneOnly"
+ type="alertmodal">
+Unable to buy the contents of more than one object at a time.
+Please select only one object and try again.
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ label="Can&apos;t Buy Contents"
+ name="BuyContentsOneOwner"
+ type="alertmodal">
+Cannot buy objects from different owners at the same time.
+Please select only one object and try again.
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="BuyOriginal"
+ type="alertmodal">
+Buy original object from [OWNER] for L$[PRICE]?
+You will become the owner of this object.
+You will be able to:
+ Modify: [MODIFYPERM]
+ Copy: [COPYPERM]
+ Resell or Give Away: [RESELLPERM]
+ <usetemplate
+ name="okcancelbuttons"
+ notext="Cancel"
+ yestext="OK"/>
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="BuyOriginalNoOwner"
+ type="alertmodal">
+Buy original object for L$[PRICE]?
+You will become the owner of this object.
+You will be able to:
+ Modify: [MODIFYPERM]
+ Copy: [COPYPERM]
+ Resell or Give Away: [RESELLPERM]
+ <usetemplate
+ name="okcancelbuttons"
+ notext="Cancel"
+ yestext="OK"/>
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="BuyCopy"
+ type="alertmodal">
+Buy a copy from [OWNER] for L$[PRICE]?
+The object will be copied to your inventory.
+You will be able to:
+ Modify: [MODIFYPERM]
+ Copy: [COPYPERM]
+ Resell or Give Away: [RESELLPERM]
+ <usetemplate
+ name="okcancelbuttons"
+ notext="Cancel"
+ yestext="OK"/>
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="BuyCopyNoOwner"
+ type="alertmodal">
+Buy a copy for L$[PRICE]?
+The object will be copied to your inventory.
+You will be able to:
+ Modify: [MODIFYPERM]
+ Copy: [COPYPERM]
+ Resell or Give Away: [RESELLPERM]
+ <usetemplate
+ name="okcancelbuttons"
+ notext="Cancel"
+ yestext="OK"/>
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="BuyContents"
+ type="alertmodal">
+Buy contents from [OWNER] for L$[PRICE]?
+They will be copied to your inventory.
+ <usetemplate
+ name="okcancelbuttons"
+ notext="Cancel"
+ yestext="OK"/>
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="BuyContentsNoOwner"
+ type="alertmodal">
+Buy contents for L$[PRICE]?
+They will be copied to your inventory.
+ <usetemplate
+ name="okcancelbuttons"
+ notext="Cancel"
+ yestext="OK"/>
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="ConfirmPurchase"
+ type="alertmodal">
+This transaction will:
+[ACTION]
+
+Are you sure you want to proceed with this purchase?
+ <usetemplate
+ name="okcancelbuttons"
+ notext="Cancel"
+ yestext="OK"/>
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="ConfirmPurchasePassword"
+ type="password">
+This transaction will:
+[ACTION]
+
+Are you sure you want to proceed with this purchase?
+Please re-enter your password and click OK.
+ <form name="form">
+ <input
+ name="message"
+ type="password"/>
+ <button
+ default="true"
+ index="0"
+ name="ConfirmPurchase"
+ text="OK"/>
+ <button
+ index="1"
+ name="Cancel"
+ text="Cancel"/>
+ </form>
+ </notification>
+
+ <notification
+ icon="alert.tga"
+ name="SetPickLocation"
+ type="alert">
+Note:
+You have updated the location of this pick but the other details will retain their original values.
+ <usetemplate
+ name="okbutton"
+ yestext="OK"/>
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="MoveInventoryFromObject"
+ type="alertmodal">
+You have selected &apos;no copy&apos; inventory items.
+These items will be moved to your inventory, not copied.
+
+Move the inventory item(s)?
+ <usetemplate
+ ignoretext="Warn me before I move &apos;no-copy&apos; items from an object"
+ name="okcancelignore"
+ notext="Cancel"
+ yestext="OK"/>
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="MoveInventoryFromScriptedObject"
+ type="alertmodal">
+You have selected &apos;no copy&apos; inventory items. These items will be moved to your inventory, not copied.
+Because this object is scripted, moving these items to your inventory may cause the script to malfunction.
+
+Move the inventory item(s)?
+ <usetemplate
+ ignoretext="Warn me before I move &apos;no-copy&apos; items which might break a scripted object"
+ name="okcancelignore"
+ notext="Cancel"
+ yestext="OK"/>
+ </notification>
+
+ <notification
+ icon="alert.tga"
+ name="ClickActionNotPayable"
+ type="alert">
+Warning: The &apos;Pay object&apos; click action has been set, but it will only work if a script is added with a money() event.
+ <form name="form">
+ <ignore name="ignore"
+ text="I set the action &apos;Pay object&apos; when building an object without a money() script"/>
+ </form>
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="OpenObjectCannotCopy"
+ type="alertmodal">
+There are no items in this object that you are allowed to copy.
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="WebLaunchAccountHistory"
+ type="alertmodal">
+Go to secondlife.com to see your account history?
+ <usetemplate
+ ignoretext="Launch my browser to see my account history"
+ name="okcancelignore"
+ notext="Cancel"
+ yestext="Go to page"/>
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="ClickOpenF1Help"
+ type="alertmodal">
+Do you want to visit [SECOND_LIFE] help?
+ <usetemplate
+ ignoretext="Launch my browser to view Help/Support"
+ name="okcancelignore"
+ notext="Cancel"
+ yestext="Go"/>
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="ConfirmQuit"
+ type="alertmodal">
+Are you sure you want to quit?
+ <usetemplate
+ ignoretext="Confirm before I quit"
+ name="okcancelignore"
+ notext="Don&apos;t Quit"
+ yestext="Quit"/>
+ <unique/>
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="HelpReportAbuseEmailLL"
+ type="alertmodal">
+Use this tool to report violations of the Terms of Service and Community Standards. See:
+
+http://secondlife.com/corporate/tos.php
+http://secondlife.com/corporate/cs.php
+
+All reported abuses of the Terms of Service and Community Standards are investigated and resolved. You can view the incident resolution on the Incident Report at:
+
+http://secondlife.com/support/incidentreport.php
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="HelpReportAbuseEmailEO"
+ type="alertmodal">
+IMPORTANT: This report will go to the owner of the region you are currently in and not to Linden Lab.
+
+As a service to residents and visitors, the owner of the region you are in has elected to receive and resolve all reports originating in this region. Linden Lab will not investigate reports you file from this location.
+
+The region owner will resolve reports based on the local rules of this region as outlined in the estate Covenant.
+(View covenants by going to the World menu and selecting About Land.)
+
+The resolution of this report applies only to this Region. Residents&apos; access to other areas of [SECOND_LIFE] will not be affected by the outcome of this report. Only Linden Lab can restrict access to the entirety of [SECOND_LIFE].
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="HelpReportBug"
+ type="alertmodal">
+Use this tool to *only* report technical features that do not perform as described or expected, please provide as much detail as possible.
+You may reply to the auto-response email to add more details to your report.
+
+All bug reports are investigated and assessed. No email response will be sent.
+
+If you are having a technical difficulty, please contact Support at:
+
+http://secondlife.com/community/support.php
+
+Note: Incomplete reports will not be investigated
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="HelpReportAbuseSelectCategory"
+ type="alertmodal">
+Please select a category for this abuse report.
+Selecting a category helps us file and process abuse reports.
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="HelpReportBugSelectCategory"
+ type="alertmodal">
+Please select a category for this bug.
+Selecting a category helps us file and process bug reports.
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="HelpReportAbuseAbuserNameEmpty"
+ type="alertmodal">
+Please enter the name of the abuser.
+Entering an accurate value helps us file and process abuse reports.
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="HelpReportAbuseAbuserLocationEmpty"
+ type="alertmodal">
+Please enter the location where the abuse took place.
+Entering an accurate value helps us file and process abuse reports.
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="HelpReportAbuseSummaryEmpty"
+ type="alertmodal">
+Please enter a summary of the abuse that took place.
+Entering an accurate summary helps us file and process abuse reports.
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="HelpReportBugSummaryEmpty"
+ type="alertmodal">
+Please enter a summary of the bug.
+Entering an accurate summary helps us file and process bug reports.
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="HelpReportAbuseDetailsEmpty"
+ type="alertmodal">
+Please enter a detailed description of the abuse that took place.
+Be as specific as you can, including names and the details of the incident you are reporting.
+Entering an accurate description helps us file and process abuse reports.
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="HelpReportBugDetailsEmpty"
+ type="alertmodal">
+Please enter a detailed description of the bug.
+Be as specific as you can, including steps to reproduce the bug if possible.
+Entering an accurate description helps us file and process bug reports.
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="HelpReportAbuseContainsCopyright"
+ type="alertmodal">
+Dear Resident,
+
+You appear to be reporting intellectual property infringement. Please make sure you are reporting it correctly:
+
+(1) The Abuse Process. You may submit an abuse report if you believe a Resident is exploiting the [SECOND_LIFE] permissions system, for example, by using CopyBot or similar copying tools, to infringe intellectual property rights. The Abuse Team investigates and issues appropriate disciplinary action for behavior that violates the [SECOND_LIFE] Community Standards or Terms of Service. However, the Abuse Team does not handle and will not respond to requests to remove content from the [SECOND_LIFE] world.
+
+(2) The DMCA or Content Removal Process. To request removal of content from [SECOND_LIFE], you MUST submit a valid notification of infringement as provided in our DMCA Policy at http://secondlife.com/corporate/dmca.php.
+
+If you still wish to continue with the abuse process, please close this window and finish submitting your report. You may need to select the specific category &apos;CopyBot or Permissions Exploit&apos;.
+
+Thank you,
+
+Linden Lab
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="FailedRequirementsCheck"
+ type="alertmodal">
+The following required components are missing from [FLOATER]:
+[COMPONENTS]
+ </notification>
+
+ <notification
+ icon="alert.tga"
+ label="Replace Existing Attachment"
+ name="ReplaceAttachment"
+ type="alert">
+There is already an object attached to this point on your body.
+Do you want to replace it with the selected object?
+ <form name="form">
+ <ignore name="ignore"
+ save_option="true"
+ text="Replace an existing attachment with the selected item"/>
+ <button
+ default="true"
+ ignore="Replace Automatically"
+ index="0"
+ name="Yes"
+ text="OK"/>
+ <button
+ ignore="Never Replace"
+ index="1"
+ name="No"
+ text="Cancel"/>
+ </form>
+ </notification>
+
+ <notification
+ icon="alert.tga"
+ label="Busy Mode Warning"
+ name="BusyModePay"
+ type="alert">
+You are in Busy Mode, which means you will not receive any items offered in exchange for this payment.
+
+Would you like to leave Busy Mode before completing this transaction?
+ <form name="form">
+ <ignore name="ignore"
+ save_option="true"
+ text="I am about to pay a person or object while I am in Busy mode"/>
+ <button
+ default="true"
+ ignore="Always leave Busy Mode"
+ index="0"
+ name="Yes"
+ text="OK"/>
+ <button
+ ignore="Never leave Busy Mode"
+ index="1"
+ name="No"
+ text="Cancel"/>
+ </form>
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="ConfirmEmptyTrash"
+ type="alertmodal">
+Are you sure you want to permanently delete the contents of your Trash?
+ <usetemplate
+ ignoretext="Confirm before I empty the inventory Trash folder"
+ name="okcancelignore"
+ notext="Cancel"
+ yestext="OK"/>
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="ConfirmClearBrowserCache"
+ type="alertmodal">
+Are you sure you want to delete your travel, web, and search history?
+ <usetemplate
+ name="okcancelbuttons"
+ notext="Cancel"
+ yestext="Yes"/>
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="ConfirmClearCookies"
+ type="alertmodal">
+Are you sure you want to clear your cookies?
+ <usetemplate
+ name="okcancelbuttons"
+ notext="Cancel"
+ yestext="Yes"/>
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="ConfirmClearMediaUrlList"
+ type="alertmodal">
+Are you sure you want to clear your list of saved URLs?
+ <usetemplate
+ name="okcancelbuttons"
+ notext="Cancel"
+ yestext="Yes"/>
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="ConfirmEmptyLostAndFound"
+ type="alertmodal">
+Are you sure you want to permanently delete the contents of your Lost And Found?
+ <usetemplate
+ ignoretext="Confirm before I empty the inventory Lost And Found folder"
+ name="okcancelignore"
+ notext="No"
+ yestext="Yes"/>
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="CopySLURL"
+ type="alertmodal">
+The following SLurl has been copied to your clipboard:
+ [SLURL]
+
+Link to this from a web page to give others easy access to this location, or try it out yourself by pasting it into the address bar of any web browser.
+ <form name="form">
+ <ignore name="ignore"
+ text="SLurl is copied to my clipboard"/>
+ </form>
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="GraphicsPreferencesHelp"
+ type="alertmodal">
+This panel controls window size and resolution and the quality of the client&apos;s graphics. The Preferences &gt; Graphics interface allows you to choose between four graphics levels: Low, Mid, High, and Ultra. You may also customize your graphics settings by checking the Custom checkbox and manipulating the following settings:
+
+Shaders: Enable or disable various types of pixel shaders.
+
+Reflection Detail: Sets the types of objects that water can reflect.
+
+Avatar Rendering: Sets options that affect how the client renders avatars.
+
+Draw Distance: Affects how far out from your viewpoint objects will be rendered in the scene.
+
+Max Particle Count: Sets the maximum number of particles you are able to see on your screen at once.
+
+Post Process Quality: Sets the resolution with which Glow is rendered.
+
+Mesh Detail: Sets the amount of detail or number of triangles used in rendering certain objects. A higher value takes longer to render, but makes these objects appear with more detail.
+
+Lighting Detail: Selects what types of lights you would like to render.
+
+Terrain Detail: Sets the amount of detail you would like to see for the terrain texture.
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="WLSavePresetAlert"
+ type="alertmodal">
+Do you wish to overwrite the saved preset?
+ <usetemplate
+ name="okcancelbuttons"
+ notext="No"
+ yestext="Yes"/>
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="WLDeletePresetAlert"
+ type="alertmodal">
+Do you wish to delete [SKY]?
+ <usetemplate
+ name="okcancelbuttons"
+ notext="No"
+ yestext="Yes"/>
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="WLNoEditDefault"
+ type="alertmodal">
+You cannot edit or delete a default preset.
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="WLMissingSky"
+ type="alertmodal">
+This day cycle file references a missing sky file: [SKY].
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="PPSaveEffectAlert"
+ type="alertmodal">
+PostProcess Effect exists. Do you still wish overwrite it?
+ <usetemplate
+ name="okcancelbuttons"
+ notext="No"
+ yestext="Yes"/>
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="HelpEditSky"
+ type="alertmodal">
+Edit the WindLight sliders to create and save a set of skies.
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="HelpEditDayCycle"
+ type="alertmodal">
+Set which skies to turn to throughout the day.
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="EnvSettingsHelpButton"
+ type="alertmodal">
+These settings adjust the way the environment looks locally on your computer. Your graphics card needs to support atmospheric shaders in order to have access to all of the settings.
+
+Adjust the &quot;Time of Day&quot; slider to change the day&apos;s phase locally on the viewer.
+
+Adjust the &quot;Cloud Cover&quot; slider to control how much the clouds cover the sky.
+
+Pick a color in the &quot;Water Color&quot; color picker to change the color of the water.
+
+Adjust the &quot;Water Fog&quot; slider to control how dense the fog is underwater.
+
+Click &quot;Use Estate Time&quot; to reset the time of day to the region&apos;s current time of day and remain linked to it.
+
+Click &quot;Advanced Sky&quot; to bring up an editor with more advanced settings for the sky.
+
+Click &quot;Advanced Water&quot; to bring up an editor with more advanced settings for the water.
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="HelpDayCycle"
+ type="alertmodal">
+The Day Cycle Editor gives you control over the sky during [SECOND_LIFE]&apos;s day/night cycle. This is the cycle that is used by the Basic Environment Editor&apos;s Time of Day slider.
+
+The Day Cycle Editor works by setting keyframes. These are nodes (represented by the gray blips on the time graph) that have Sky Presets associated with them. As the Time of Day progresses, the WindLight sky &quot;animates&quot; as it interpolates between these keyframes.
+
+The yellow arrow above the timeline represents your current view, based on Time of Day. Click and drag it to see how your day will animate. You may add or delete keyframes by pressing the Add Key and Delete Key buttons to the right of the timeline.
+
+You can set the time position of a keyframe by either dragging it along the timeline, or by setting its value manually in the Key Frame Settings frame. Within the Key Frame Settings frame, you&apos;ll be able to associate the keyframe with its respective WindLight preset.
+
+Length of Cycle dictates the overall duration of a &quot;day&quot;. Setting this to a low value (for instance, 2 min.) will mean your entire 24-hour timeline will animate in only two real minutes! Once you are satisfied with your timeline and keyframe cycle, use the Play and Stop buttons to preview the results. Remember- you can also move the yellow time-indicator arrow above the timeline to see the cycle animate interactively. Using the Use Estate Time button will synchronize your day length and time of day with the Estate&apos;s day cycle.
+
+Once you are pleased with your Day Cycle, you can save and load it with the Save Test Day and Load Test Day buttons. Note that, for now, we only allow one Day Cycle.
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="HelpBlueHorizon"
+ type="alertmodal">
+Use the Red/Green/Blue (RGB) sliders to adjust the color of the sky. You can use the Intensity (I) slider to move all three RGB sliders in unison.
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="HelpHazeHorizon"
+ type="alertmodal">
+Haze Horizon is one of the most useful parameters for adjusting overall light exposure in the scene. It is effective for simulating many exposure settings, such as white-outs from the sun and darker, closed-iris settings.
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="HelpBlueDensity"
+ type="alertmodal">
+Blue Density affects the overall color saturation of the sky and fog. If you move the Intensity (I) slider to the right, colors will become brighter and more vibrant. If you move it all the way to the left, the colors will become duller, eventually fading to black and white. If you want to fine-tune the sky&apos;s color balance, you can control individual elements of saturation by using the Red/Green/Blue (RGB) sliders.
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="HelpHazeDensity"
+ type="alertmodal">
+Haze Density controls the level of dull, gray haze in the atmosphere. It is effective for simulating scenes with high levels of smoke and man-made pollutants. It is also effective for simulating fog and mist.
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="HelpDensityMult"
+ type="alertmodal">
+The Density Multiplier can be used to affect the overall atmospheric density. At lower settings, it creates a feeling of &quot;thin air&quot;, and at higher settings, it creates a very heavy, smoggy effect.
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="HelpDistanceMult"
+ type="alertmodal">
+Adjusts WindLight&apos;s perceived distance. A value of zero effectively turns off WindLight&apos;s influence on terrain and objects. Values greater than 1 simulate greater distances for thicker atmospheric effects.
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="HelpMaxAltitude"
+ type="alertmodal">
+Max Altitude adjusts the altitude calculations WindLight performs when computing its atmospheric lighting. At later times of day, it is useful for adjusting how &quot;deep&quot; the sunset appears.
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="HelpSunlightColor"
+ type="alertmodal">
+Adjusts the color and intensity of the direct light in the scene.
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="HelpSunAmbient"
+ type="alertmodal">
+Adjusts the color and intensity of ambient atmospheric light in the scene.
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="HelpSunGlow"
+ type="alertmodal">
+The Size slider controls the size of the sun.
+The Focus slider controls how blurred the sun is over the sky.
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="HelpSceneGamma"
+ type="alertmodal">
+Adjust the screen&apos;s distribution of light and dark.
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="HelpStarBrightness"
+ type="alertmodal">
+Adjusts the brightness of the stars in the sky.
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="HelpTimeOfDay"
+ type="alertmodal">
+Controls the location of the sun in the sky.
+Similar to elevation.
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="HelpEastAngle"
+ type="alertmodal">
+Controls the location of the sun in the sky.
+Similar to azimuth.
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="HelpCloudColor"
+ type="alertmodal">
+Edits the color of the clouds. It is generally recommended to keep it whitish, but hey, have fun if you want.
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="HelpCloudDetail"
+ type="alertmodal">
+Controls the detail image layered on top of the main cloud image. X and Y control its position. D (Density) controls how puffy or fractured the clouds appear.
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="HelpCloudDensity"
+ type="alertmodal">
+Allows you to control the position of the clouds with the X and Y sliders and how dense they are with the the D slider.
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="HelpCloudCoverage"
+ type="alertmodal">
+Controls how much the clouds cover the sky.
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="HelpCloudScale"
+ type="alertmodal">
+Controls the scaling of the cloud image on the sky dome.
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="HelpCloudScrollX"
+ type="alertmodal">
+Controls the speed of the clouds as they move in the X direction.
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="HelpCloudScrollY"
+ type="alertmodal">
+Controls the speed of the clouds as they move in the Y direction.
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="HelpClassicClouds"
+ type="alertmodal">
+Check this box to enable rendering of [SECOND_LIFE]&apos;s older classic clouds in addition to WindLight&apos;s clouds.
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="HelpWaterFogColor"
+ type="alertmodal">
+Chooses the color of the underwater fog.
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="HelpWaterFogDensity"
+ type="alertmodal">
+Controls how dense the water fog is and how far you can see underwater.
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="HelpUnderWaterFogMod"
+ type="alertmodal">
+Modifies the effect of the Fog Density Exponent to control how far you can see when your avatar is underwater.
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="HelpWaterGlow"
+ type="alertmodal">
+Controls how much the surface of the water glows.
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="HelpWaterNormalScale"
+ type="alertmodal">
+Controls the scaling of the three wavelets that make up the water.
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="HelpWaterFresnelScale"
+ type="alertmodal">
+Controls how much light is reflected at different angles.
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="HelpWaterFresnelOffset"
+ type="alertmodal">
+Controls how much light intensity is reflected.
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="HelpWaterScaleAbove"
+ type="alertmodal">
+Controls how much light is refracted from looking above the surface of the water.
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="HelpWaterScaleBelow"
+ type="alertmodal">
+Controls how much light is refracted from looking from below the surface of the water.
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="HelpWaterBlurMultiplier"
+ type="alertmodal">
+Controls how waves and reflections are mixed.
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="HelpWaterNormalMap"
+ type="alertmodal">
+Controls what normal map is layered across the water to determine reflections/refractions.
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="HelpWaterWave1"
+ type="alertmodal">
+Controls where and how fast the large scaled version of the normal map moves in the X and Y direction.
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="HelpWaterWave2"
+ type="alertmodal">
+Controls where and how fast the the small scaled version of the normal map moves in the X and Y direction.
+ </notification>
+
+ <notification
+ icon="alert.tga"
+ name="NewSkyPreset"
+ type="alert">
+Give me a name for the new sky.
+ <form name="form">
+ <input name="message" type="text">
+New Preset
+ </input>
+ <button
+ default="true"
+ index="0"
+ name="OK"
+ text="OK"/>
+ <button
+ index="1"
+ name="Cancel"
+ text="Cancel"/>
+ </form>
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="ExistsSkyPresetAlert"
+ type="alertmodal">
+Preset already exists!
+ </notification>
+
+ <notification
+ icon="alert.tga"
+ name="NewWaterPreset"
+ type="alert">
+Give me a name for the new water preset.
+ <form name="form">
+ <input name="message" type="text">
+New Preset
+ </input>
+ <button
+ default="true"
+ index="0"
+ name="OK"
+ text="OK"/>
+ <button
+ index="1"
+ name="Cancel"
+ text="Cancel"/>
+ </form>
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="ExistsWaterPresetAlert"
+ type="alertmodal">
+Preset already exists!
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="WaterNoEditDefault"
+ type="alertmodal">
+You cannot edit or delete a default preset.
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="ChatterBoxSessionStartError"
+ type="alertmodal">
+Unable to start a new chat session with [RECIPIENT].
+[REASON]
+ <usetemplate
+ name="okbutton"
+ yestext="OK"/>
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="ChatterBoxSessionEventError"
+ type="alertmodal">
+[EVENT]
+[REASON]
+ <usetemplate
+ name="okbutton"
+ yestext="OK"/>
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="ForceCloseChatterBoxSession"
+ type="alertmodal">
+Your chat session with [NAME] must close.
+[REASON]
+ <usetemplate
+ name="okbutton"
+ yestext="OK"/>
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="Cannot_Purchase_an_Attachment"
+ type="alertmodal">
+You can&apos;t buy an object while it is attached.
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ label="About Requests for the Debit Permission"
+ name="DebitPermissionDetails"
+ type="alertmodal">
+Granting this request gives a script ongoing permission to take Linden dollars (L$) from your account. To revoke this permission, the object owner must delete the object or reset the scripts in the object.
+ <usetemplate
+ name="okbutton"
+ yestext="OK"/>
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="AutoWearNewClothing"
+ type="alertmodal">
+Would you like to automatically wear the clothing you are about to create?
+ <usetemplate
+ ignoretext="Wear the clothing I create while editing My Appearance"
+ name="okcancelignore"
+ notext="No"
+ yestext="Yes"/>
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="NotAgeVerified"
+ type="alertmodal">
+You must be age-verified to visit this area. Do you want to go to the [SECOND_LIFE] website and verify your age?
+
+[_URL]
+ <url option="0" name="url">
+
+ https://secondlife.com/account/verification.php
+ </url>
+ <usetemplate
+ ignoretext="I have not verified my age"
+ name="okcancelignore"
+ notext="No"
+ yestext="Yes"/>
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="Cannot enter parcel: no payment info on file"
+ type="alertmodal">
+You must have payment information on file to visit this area. Do you want to go to the [SECOND_LIFE] website and set this up?
+
+[_URL]
+ <url option="0" name="url">
+
+ https://secondlife.com/account/
+ </url>
+ <usetemplate
+ ignoretext="I lack payment information on file"
+ name="okcancelignore"
+ notext="No"
+ yestext="Yes"/>
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="MissingString"
+ type="alertmodal">
+How odd. The string [STRING_NAME] is missing from strings.xml
+ </notification>
+
+ <notification
+ icon="notifytip.tga"
+ name="SystemMessageTip"
+ type="notifytip">
+ [MESSAGE]
+ </notification>
+
+ <notification
+ icon="notifytip.tga"
+ name="Cancelled"
+ type="notifytip">
+ Cancelled
+ </notification>
+
+ <notification
+ icon="notifytip.tga"
+ name="CancelledSit"
+ type="notifytip">
+ Cancelled Sit
+ </notification>
+
+ <notification
+ icon="notifytip.tga"
+ name="CancelledAttach"
+ type="notifytip">
+ Cancelled Attach
+ </notification>
+
+ <notification
+ icon="notifytip.tga"
+ name="ReplacedMissingWearable"
+ type="notifytip">
+ Replaced missing clothing/body part with default.
+ </notification>
+
+ <notification
+ icon="groupnotify"
+ name="GroupNotice"
+ type="groupnotify">
+ Topic: [SUBJECT], Message: [MESSAGE]
+ </notification>
+
+ <notification
+ icon="notifytip.tga"
+ name="FriendOnline"
+ type="notifytip">
+ [FIRST] [LAST] is Online
+ </notification>
+
+ <notification
+ icon="notifytip.tga"
+ name="FriendOffline"
+ type="notifytip">
+ [FIRST] [LAST] is Offline
+ </notification>
+
+ <notification
+ icon="notifytip.tga"
+ name="AddSelfFriend"
+ type="notifytip">
+ Although you&apos;re very nice, you can&apos;t add yourself as a friend.
+ </notification>
+
+ <notification
+ icon="notifytip.tga"
+ name="UploadingAuctionSnapshot"
+ type="notifytip">
+ Uploading in-world and web site snapshots...
+ (Takes about 5 minutes.)
+ </notification>
+
+ <notification
+ icon="notify.tga"
+ name="UploadPayment"
+ type="notify">
+ You paid L$[AMOUNT] to upload.
+ </notification>
+
+ <notification
+ icon="notifytip.tga"
+ name="UploadWebSnapshotDone"
+ type="notifytip">
+ Web site snapshot upload done.
+ </notification>
+
+ <notification
+ icon="notifytip.tga"
+ name="UploadSnapshotDone"
+ type="notifytip">
+ In-world snapshot upload done
+ </notification>
+
+ <notification
+ icon="notifytip.tga"
+ name="TerrainDownloaded"
+ type="notifytip">
+ Terrain.raw downloaded
+ </notification>
+
+ <notification
+ icon="notifytip.tga"
+ name="GestureMissing"
+ type="notifytip">
+ Hmm. Gesture [NAME] is missing from the database.
+ </notification>
+
+ <notification
+ icon="notifytip.tga"
+ name="UnableToLoadGesture"
+ type="notifytip">
+ Unable to load gesture [NAME].
+ Please try again.
+ </notification>
+
+ <notification
+ icon="notifytip.tga"
+ name="LandmarkMissing"
+ type="notifytip">
+ Landmark is missing from database.
+ </notification>
+
+ <notification
+ icon="notifytip.tga"
+ name="UnableToLoadLandmark"
+ type="notifytip">
+ Unable to load landmark. Please try again.
+ </notification>
+
+ <notification
+ icon="notifytip.tga"
+ name="CapsKeyOn"
+ type="notifytip">
+ Your Caps Lock key is on.
+ This might affect your password.
+ </notification>
+
+ <notification
+ icon="notifytip.tga"
+ name="NotecardMissing"
+ type="notifytip">
+ Notecard is missing from database.
+ </notification>
+
+ <notification
+ icon="notifytip.tga"
+ name="NotecardNoPermissions"
+ type="notifytip">
+ You don&apos;t have permission to view this notecard.
+ </notification>
+
+ <notification
+ icon="notifytip.tga"
+ name="RezItemNoPermissions"
+ type="notifytip">
+ Insufficient permissions to rez object.
+ </notification>
+
+ <notification
+ icon="notifytip.tga"
+ name="UnableToLoadNotecard"
+ type="notifytip">
+ Unable to load notecard.
+ Please try again.
+ </notification>
+
+ <notification
+ icon="notifytip.tga"
+ name="ScriptMissing"
+ type="notifytip">
+ Script is missing from database.
+ </notification>
+
+ <notification
+ icon="notifytip.tga"
+ name="ScriptNoPermissions"
+ type="notifytip">
+ Insufficient permissions to view script.
+ </notification>
+
+ <notification
+ icon="notifytip.tga"
+ name="UnableToLoadScript"
+ type="notifytip">
+ Unable to load script. Please try again.
+ </notification>
+
+ <notification
+ icon="notifytip.tga"
+ name="IncompleteInventory"
+ type="notifytip">
+ The complete contents you are offering are not yet locally available. Please try offering those items again in a minute.
+ </notification>
+
+ <notification
+ icon="notifytip.tga"
+ name="CannotModifyProtectedCategories"
+ type="notifytip">
+ You cannot modify protected categories.
+ </notification>
+
+ <notification
+ icon="notifytip.tga"
+ name="CannotRemoveProtectedCategories"
+ type="notifytip">
+ You cannot remove protected categories.
+ </notification>
+
+ <notification
+ icon="notifytip.tga"
+ name="OfferedCard"
+ type="notifytip">
+ You have offered a calling card to [FIRST] [LAST]
+ </notification>
+
+ <notification
+ icon="notifytip.tga"
+ name="UnableToBuyWhileDownloading"
+ type="notifytip">
+ Unable to buy while downloading object data.
+ Please try again.
+ </notification>
+
+ <notification
+ icon="notifytip.tga"
+ name="UnableToLinkWhileDownloading"
+ type="notifytip">
+ Unable to link while downloading object data.
+ Please try again.
+ </notification>
+
+ <notification
+ icon="notifytip.tga"
+ name="CannotBuyObjectsFromDifferentOwners"
+ type="notifytip">
+ You can only buy objects from one owner at a time.
+ Please select a single object.
+ </notification>
+
+ <notification
+ icon="notifytip.tga"
+ name="ObjectNotForSale"
+ type="notifytip">
+ This object is not for sale.
+ </notification>
+
+ <notification
+ icon="notifytip.tga"
+ name="EnteringGodMode"
+ type="notifytip">
+ Entering god mode, level [LEVEL]
+ </notification>
+
+ <notification
+ icon="notifytip.tga"
+ name="LeavingGodMode"
+ type="notifytip">
+ Now leaving god mode, level [LEVEL]
+ </notification>
+
+ <notification
+ icon="notifytip.tga"
+ name="CopyFailed"
+ type="notifytip">
+ You don&apos;t have permission to copy this.
+ </notification>
+
+ <notification
+ icon="notifytip.tga"
+ name="InventoryAccepted"
+ type="notifytip">
+ [NAME] accepted your inventory offer.
+ </notification>
+
+ <notification
+ icon="notifytip.tga"
+ name="InventoryDeclined"
+ type="notifytip">
+ [NAME] declined your inventory offer.
+ </notification>
+
+ <notification
+ icon="notifytip.tga"
+ name="ObjectMessage"
+ type="notifytip">
+ [NAME]: [MESSAGE]
+ </notification>
+
+ <notification
+ icon="notifytip.tga"
+ name="CallingCardAccepted"
+ type="notifytip">
+ Your calling card was accepted.
+ </notification>
+
+ <notification
+ icon="notifytip.tga"
+ name="CallingCardDeclined"
+ type="notifytip">
+ Your calling card was declined.
+ </notification>
+
+ <notification
+ icon="notifytip.tga"
+ name="TeleportToLandmark"
+ type="notifytip">
+ Now that you have reached the mainland, you can teleport to locations like &apos;[NAME]&apos; by clicking on the Inventory button on the bottom right of your screen, and then select the Landmarks folder.
+ Double click on the landmark and click on Teleport to travel there.
+ </notification>
+
+ <notification
+ icon="notifytip.tga"
+ name="TeleportToPerson"
+ type="notifytip">
+ Now that you have reached the mainland, you can contact residents like &apos;[NAME]&apos; by clicking on the Inventory button on the bottom right of your screen, and then select the Calling Cards folder.
+ Double click on the card, click on Instant Message, and type a message.
+ </notification>
+
+ <notification
+ icon="notifytip.tga"
+ name="CantSelectLandFromMultipleRegions"
+ type="notifytip">
+ Can&apos;t select land across server boundaries.
+ Try selecting a smaller piece of land.
+ </notification>
+
+ <notification
+ icon="notifytip.tga"
+ name="SearchWordBanned"
+ type="notifytip">
+ Some terms in your search query were excluded due to content restrictions as clarified in the Community Standards.
+ </notification>
+
+ <notification
+ icon="notifytip.tga"
+ name="NoContentToSearch"
+ type="notifytip">
+ Please select at least one type of content to search (PG, Mature, or Adult).
+ </notification>
+
+ <notification
+ icon="notify.tga"
+ name="GroupVote"
+ type="notify">
+ [NAME] has proposed to vote on:
+ [MESSAGE]
+ <form name="form">
+ <button
+ index="0"
+ name="VoteNow"
+ text="Vote Now"/>
+ <button
+ index="1"
+ name="Later"
+ text="Later"/>
+ </form>
+ </notification>
+
+ <notification
+ icon="notify.tga"
+ name="SystemMessage"
+ type="notify">
+ [MESSAGE]
+ </notification>
+
+ <notification
+ icon="notify.tga"
+ name="EventNotification"
+ type="notify">
+ Event Notification:
+
+ [NAME]
+ [DATE]
+ <form name="form">
+ <button
+ index="0"
+ name="Teleport"
+ text="Teleport"/>
+ <button
+ index="1"
+ name="Description"
+ text="Description"/>
+ <button
+ index="2"
+ name="Cancel"
+ text="Cancel"/>
+ </form>
+ </notification>
+
+ <notification
+ icon="notify.tga"
+ name="TransferObjectsHighlighted"
+ type="notify">
+ All objects on this parcel that will transfer to the purchaser of this parcel are now highlighted.
+
+ * Trees and grasses that will transfer are not highlighted.
+ <form name="form">
+ <button
+ index="0"
+ name="Done"
+ text="Done"/>
+ </form>
+ </notification>
+
+ <notification
+ icon="notify.tga"
+ name="DeactivatedGesturesTrigger"
+ type="notify">
+ Deactivated gestures with same trigger:
+ [NAMES]
+ </notification>
+
+ <notification
+ icon="notify.tga"
+ name="NoQuickTime"
+ type="notify">
+ Apple&apos;s QuickTime software does not appear to be installed on your system.
+ If you want to view streaming media on parcels that support it you should go to the QuickTime site (http://www.apple.com/quicktime) and install the QuickTime Player.
+ </notification>
+ <notification
+ icon="notify.tga"
+ name="NoPlugin"
+ type="notify">
+ No Media Plugin was found to handle the "[MIME_TYPE]" mime type. Media of this type will be unavailable.
+ </notification>
+ <notification
+ icon="alertmodal.tga"
+ name="MediaPluginFailed"
+ type="alertmodal">
+ The following Media Plugin has failed:
+ [PLUGIN]
+
+Please re-install the plugin or contact the vendor if you continue to experience problems.
+ <form name="form">
+ <ignore name="ignore"
+ text="When a Media Plugin fails"/>
+ </form>
+ </notification>
+ <notification
+ icon="notify.tga"
+ name="OwnedObjectsReturned"
+ type="notify">
+ The objects you own on the selected parcel of land have been returned back to your inventory.
+ </notification>
+
+ <notification
+ icon="notify.tga"
+ name="OtherObjectsReturned"
+ type="notify">
+ The objects on the selected parcel of land that is owned by [FIRST] [LAST] have been returned to his or her inventory.
+ </notification>
+
+ <notification
+ icon="notify.tga"
+ name="OtherObjectsReturned2"
+ type="notify">
+ The objects on the selected parcel of land owned by the resident &apos;[NAME]&apos; have been returned to their owner.
+ </notification>
+
+ <notification
+ icon="notify.tga"
+ name="GroupObjectsReturned"
+ type="notify">
+ The objects on the selected parcel of land shared with the group [GROUPNAME] have been returned back to their owner&apos;s inventory.
+ Transferable deeded objects have been returned to their previous owners.
+ Non-transferable objects that are deeded to the group have been deleted.
+ </notification>
+
+ <notification
+ icon="notify.tga"
+ name="UnOwnedObjectsReturned"
+ type="notify">
+ The objects on the selected parcel that are NOT owned by you have been returned to their owners.
+ </notification>
+
+ <notification
+ icon="notify.tga"
+ name="NotSafe"
+ type="notify">
+ This land has damage enabled.
+ You can be hurt here. If you die, you will be teleported to your home location.
+ <unique/>
+ </notification>
+
+ <notification
+ icon="notify.tga"
+ name="NoFly"
+ type="notify">
+ This area has flying disabled.
+ You can&apos;t fly here.
+ <unique/>
+ </notification>
+
+ <notification
+ icon="notify.tga"
+ name="PushRestricted"
+ type="notify">
+ This area does not allow pushing. You can&apos;t push others here unless you own the land.
+ <unique/>
+ </notification>
+
+ <notification
+ icon="notify.tga"
+ name="NoVoice"
+ type="notify">
+ This area has voice chat disabled. You won&apos;t be able to hear anyone talking.
+ <unique/>
+ </notification>
+
+ <notification
+ icon="notify.tga"
+ name="NoBuild"
+ type="notify">
+ This area has building disabled. You can&apos;t build or rez objects here.
+ <unique/>
+ </notification>
+
+ <notification
+ icon="notify.tga"
+ name="ScriptsStopped"
+ type="notify">
+ An administrator has temporarily stopped scripts in this region.
+ </notification>
+
+ <notification
+ icon="notify.tga"
+ name="ScriptsNotRunning"
+ type="notify">
+ This region is not running any scripts.
+ </notification>
+
+ <notification
+ icon="notify.tga"
+ name="NoOutsideScripts"
+ type="notify">
+ This land has outside scripts disabled.
+
+ No scripts will work here except those belonging to the land owner.
+ </notification>
+
+ <notification
+ icon="notify.tga"
+ name="ClaimPublicLand"
+ type="notify">
+ You can only claim public land in the Region you&apos;re in.
+ </notification>
+
+ <notification
+ icon="notify.tga"
+ name="RegionTPAccessBlocked"
+ type="notify">
+ You aren&apos;t allowed in that Region due to your maturity Rating. You may need to validate your age and/or install the latest Viewer.
+
+ Please go to the Knowledge Base for details on accessing areas with this maturity Rating.
+ </notification>
+
+ <notification
+ icon="notify.tga"
+ name="URBannedFromRegion"
+ type="notify">
+ You are banned from the region.
+ </notification>
+
+ <notification
+ icon="notify.tga"
+ name="NoTeenGridAccess"
+ type="notify">
+ Your account cannot connect to this teen grid region.
+ </notification>
+
+ <notification
+ icon="notify.tga"
+ name="NoHelpIslandTP"
+ type="notify">
+ You cannot teleport back to Help Island.
+ Go to &apos;Help Island Public&apos; to repeat the tutorial.
+ </notification>
+
+ <notification
+ icon="notify.tga"
+ name="ImproperPaymentStatus"
+ type="notify">
+ You do not have proper payment status to enter this region.
+ </notification>
+
+ <notification
+ icon="notify.tga"
+ name="MustGetAgeRgion"
+ type="notify">
+ You must be age-verified to enter this region.
+ </notification>
+
+ <notification
+ icon="notify.tga"
+ name="MustGetAgeParcel"
+ type="notify">
+ You must be age-verified to enter this parcel.
+ </notification>
+
+ <notification
+ icon="notify.tga"
+ name="NoDestRegion"
+ type="notify">
+ No destination region found.
+ </notification>
+
+ <notification
+ icon="notify.tga"
+ name="NotAllowedInDest"
+ type="notify">
+ You are not allowed into the destination.
+ </notification>
+
+ <notification
+ icon="notify.tga"
+ name="RegionParcelBan"
+ type="notify">
+ Cannot region cross into banned parcel. Try another way.
+ </notification>
+
+ <notification
+ icon="notify.tga"
+ name="TelehubRedirect"
+ type="notify">
+ You have been redirected to a telehub.
+ </notification>
+
+ <notification
+ icon="notify.tga"
+ name="CouldntTPCloser"
+ type="notify">
+ Could not teleport closer to destination.
+ </notification>
+
+ <notification
+ icon="notify.tga"
+ name="TPCancelled"
+ type="notify">
+ Teleport cancelled.
+ </notification>
+
+ <notification
+ icon="notify.tga"
+ name="FullRegionTryAgain"
+ type="notify">
+ The region you are attempting to enter is currently full.
+ Please try again in a few moments.
+ </notification>
+
+ <notification
+ icon="notify.tga"
+ name="GeneralFailure"
+ type="notify">
+ General failure.
+ </notification>
+
+ <notification
+ icon="notify.tga"
+ name="RoutedWrongRegion"
+ type="notify">
+ Routed to wrong region. Please try again.
+ </notification>
+
+ <notification
+ icon="notify.tga"
+ name="NoValidAgentID"
+ type="notify">
+ No valid agent id.
+ </notification>
+
+ <notification
+ icon="notify.tga"
+ name="NoValidSession"
+ type="notify">
+ No valid session id.
+ </notification>
+
+ <notification
+ icon="notify.tga"
+ name="NoValidCircuit"
+ type="notify">
+ No valid circuit code.
+ </notification>
+
+ <notification
+ icon="notify.tga"
+ name="NoValidTimestamp"
+ type="notify">
+ No valid timestamp.
+ </notification>
+
+ <notification
+ icon="notify.tga"
+ name="NoPendingConnection"
+ type="notify">
+ Unable to create pending connection.
+ </notification>
+
+ <notification
+ icon="notify.tga"
+ name="InternalUsherError"
+ type="notify">
+ Internal error attempting to connect agent usher.
+ </notification>
+
+ <notification
+ icon="notify.tga"
+ name="NoGoodTPDestination"
+ type="notify">
+ Unable to find a good teleport destination in this region.
+ </notification>
+
+ <notification
+ icon="notify.tga"
+ name="InternalErrorRegionResolver"
+ type="notify">
+ Internal error attempting to activate region resolver.
+ </notification>
+
+ <notification
+ icon="notify.tga"
+ name="NoValidLanding"
+ type="notify">
+ A valid landing point could not be found.
+ </notification>
+
+ <notification
+ icon="notify.tga"
+ name="NoValidParcel"
+ type="notify">
+ No valid parcel could be found.
+ </notification>
+
+ <notification
+ icon="notify.tga"
+ name="ObjectGiveItem"
+ type="notify">
+ An object named [OBJECTFROMNAME] owned by [FIRST] [LAST] has given you a [OBJECTTYPE] named [OBJECTNAME].
+ <form name="form">
+ <button
+ index="0"
+ name="Keep"
+ text="Keep"/>
+ <button
+ index="1"
+ name="Discard"
+ text="Discard"/>
+ <button
+ index="2"
+ name="Mute"
+ text="Block"/>
+ </form>
+ </notification>
+
+ <notification
+ icon="notify.tga"
+ name="ObjectGiveItemUnknownUser"
+ type="notify">
+ An object named [OBJECTFROMNAME] owned by (an unknown Resident) has given you a [OBJECTTYPE] named [OBJECTNAME].
+ <form name="form">
+ <button
+ index="0"
+ name="Keep"
+ text="Keep"/>
+ <button
+ index="1"
+ name="Discard"
+ text="Discard"/>
+ <button
+ index="2"
+ name="Mute"
+ text="Block"/>
+ </form>
+ </notification>
+
+ <notification
+ icon="notify.tga"
+ name="UserGiveItem"
+ type="notify">
+ [NAME] has given you a [OBJECTTYPE] named &apos;[OBJECTNAME]&apos;.
+ <form name="form">
+ <button
+ index="0"
+ name="Keep"
+ text="Keep"/>
+ <button
+ index="1"
+ name="Discard"
+ text="Discard"/>
+ <button
+ index="2"
+ name="Mute"
+ text="Block"/>
+ </form>
+ </notification>
+
+ <notification
+ icon="notify.tga"
+ name="GodMessage"
+ type="notify">
+ [NAME]
+ [MESSAGE]
+ </notification>
+
+ <notification
+ icon="notify.tga"
+ name="JoinGroup"
+ type="notify">
+ [MESSAGE]
+ <form name="form">
+ <button
+ index="0"
+ name="Join"
+ text="Join"/>
+ <button
+ index="1"
+ name="Decline"
+ text="Decline"/>
+ <button
+ index="2"
+ name="Info"
+ text="Info"/>
+ </form>
+ </notification>
+
+ <notification
+ icon="notify.tga"
+ name="TeleportOffered"
+ type="notify">
+ [NAME] has offered to teleport you to their location:
+
+ [MESSAGE]
+ <form name="form">
+ <button
+ index="0"
+ name="Teleport"
+ text="Teleport"/>
+ <button
+ index="1"
+ name="Cancel"
+ text="Cancel"/>
+ </form>
+ </notification>
+
+ <notification
+ icon="notify.tga"
+ name="GotoURL"
+ type="notify">
+ [MESSAGE]
+ [URL]
+ <form name="form">
+ <button
+ index="0"
+ name="Later"
+ text="Later"/>
+ <button
+ index="1"
+ name="GoNow..."
+ text="Go Now..."/>
+ </form>
+ </notification>
+
+ <notification
+ icon="notify.tga"
+ name="OfferFriendship"
+ type="notify">
+ [NAME] is offering friendship.
+
+ [MESSAGE]
+
+ (By default, you will be able to see each other&apos;s online status.)
+ <form name="form">
+ <button
+ index="0"
+ name="Accept"
+ text="Accept"/>
+ <button
+ index="1"
+ name="Decline"
+ text="Decline"/>
+ </form>
+ </notification>
+
+ <notification
+ icon="notify.tga"
+ name="OfferFriendshipNoMessage"
+ type="notify">
+ [NAME] is offering friendship.
+
+ (By default, you will be able to see each other&apos;s online status.)
+ <form name="form">
+ <button
+ index="0"
+ name="Accept"
+ text="Accept"/>
+ <button
+ index="1"
+ name="Decline"
+ text="Decline"/>
+ </form>
+ </notification>
+
+ <notification
+ icon="notify.tga"
+ name="FriendshipAccepted"
+ type="notify">
+ [NAME] accepted your friendship offer.
+ </notification>
+
+ <notification
+ icon="notify.tga"
+ name="FriendshipDeclined"
+ type="notify">
+ [NAME] declined your friendship offer.
+ </notification>
+
+ <notification
+ icon="notify.tga"
+ name="OfferCallingCard"
+ type="notify">
+ [FIRST] [LAST] is offering their calling card.
+ This will add a bookmark in your inventory so you can quickly IM this resident.
+ <form name="form">
+ <button
+ index="0"
+ name="Accept"
+ text="Accept"/>
+ <button
+ index="1"
+ name="Decline"
+ text="Decline"/>
+ </form>
+ </notification>
+
+ <notification
+ icon="notify.tga"
+ name="RegionRestartMinutes"
+ priority="high"
+ sound="UISndAlert"
+ type="notify">
+ This region will restart in [MINUTES] minutes.
+ If you stay in this region you will be logged out.
+ </notification>
+
+ <notification
+ icon="notify.tga"
+ name="RegionRestartSeconds"
+ priority="high"
+ sound="UISndAlert"
+ type="notify">
+ This region will restart in [SECONDS] seconds.
+ If you stay in this region you will be logged out.
+ </notification>
+
+ <notification
+ icon="notify.tga"
+ name="LoadWebPage"
+ type="notify">
+ Load web page [URL]?
+
+ [MESSAGE]
+
+ From object: [OBJECTNAME], owner: [NAME]?
+ <form name="form">
+ <button
+ index="0"
+ name="Gotopage"
+ text="Go to page"/>
+ <button
+ index="1"
+ name="Cancel"
+ text="Cancel"/>
+ </form>
+ </notification>
+
+ <notification
+ icon="notify.tga"
+ name="FailedToFindWearableUnnamed"
+ type="notify">
+ Failed to find [TYPE] in database.
+ </notification>
+
+ <notification
+ icon="notify.tga"
+ name="FailedToFindWearable"
+ type="notify">
+ Failed to find [TYPE] named [DESC] in database.
+ </notification>
+
+ <notification
+ icon="notify.tga"
+ name="InvalidWearable"
+ type="notify">
+ The item you are trying to wear uses a feature that your Viewer can&apos;t read. Please upgrade your version of [APP_NAME] to wear this item.
+ </notification>
+
+ <notification
+ icon="notify.tga"
+ name="ScriptQuestion"
+ type="notify">
+ &apos;[OBJECTNAME]&apos;, an object owned by &apos;[NAME]&apos;, would like to:
+
+ [QUESTIONS]
+ Is this OK?
+ <form name="form">
+ <button
+ index="0"
+ name="Yes"
+ text="Yes"/>
+ <button
+ index="1"
+ name="No"
+ text="No"/>
+ <button
+ index="2"
+ name="Mute"
+ text="Block"/>
+ </form>
+ </notification>
+
+ <notification
+ icon="notify.tga"
+ name="ScriptQuestionCaution"
+ priority="high"
+ type="notify">
+ An object named &apos;[OBJECTNAME]&apos;, owned by &apos;[NAME]&apos; would like to:
+
+ [QUESTIONS]
+ If you do not trust this object and its creator, you should deny the request.
+
+ Grant this request?
+ <form name="form">
+ <button
+ index="0"
+ name="Grant"
+ text="Grant"/>
+ <button
+ default="true"
+ index="1"
+ name="Deny"
+ text="Deny"/>
+ <button
+ index="2"
+ name="Details"
+ text="Details..."/>
+ </form>
+ </notification>
+
+ <notification
+ icon="notify.tga"
+ name="ScriptDialog"
+ type="notify">
+ [FIRST] [LAST]&apos;s &apos;[TITLE]&apos;
+ [MESSAGE]
+ <form name="form">
+ <button
+ index="-1"
+ name="Ignore"
+ text="Ignore"/>
+ </form>
+ </notification>
+
+ <notification
+ icon="notify.tga"
+ name="ScriptDialogGroup"
+ type="notify">
+ [GROUPNAME]&apos;s &apos;[TITLE]&apos;
+ [MESSAGE]
+ <form name="form">
+ <button
+ index="-1"
+ name="Ignore"
+ text="Ignore"/>
+ </form>
+ </notification>
+
+ <notification
+ icon="notify.tga"
+ name="FirstBalanceIncrease"
+ type="notify">
+ You just received L$[AMOUNT].
+ Your L$ balance is shown in the upper-right.
+ </notification>
+
+ <notification
+ icon="notify.tga"
+ name="FirstBalanceDecrease"
+ type="notify">
+ You just paid L$[AMOUNT].
+ Your L$ balance is shown in the upper-right.
+ </notification>
+
+ <notification
+ icon="notify.tga"
+ name="FirstSit"
+ type="notify">
+ You are sitting.
+ Use your arrow keys (or AWSD) to look around.
+ Click the &apos;Stand Up&apos; button to stand.
+ </notification>
+
+ <notification
+ icon="notify.tga"
+ name="FirstMap"
+ type="notify">
+ Click and drag the map to look around.
+ Double-click to teleport.
+ Use the controls on the right to find things and display different backgrounds.
+ </notification>
+
+ <notification
+ icon="notify.tga"
+ name="FirstBuild"
+ type="notify">
+ You have opened the Build Tools. Every object you see around you was created using these tools.
+ </notification>
+
+<!--
+ <notification
+ icon="notify.tga"
+ name="FirstLeftClickNoHit"
+ type="notify">
+ Left-clicking interacts with special objects.
+ If the mouse pointer changes to a hand, you can interact with the object.
+ Right-click always shows a menu of things you can do.
+ </notification>
+-->
+ <notification
+ icon="notify.tga"
+ name="FirstTeleport"
+ type="notify">
+ You can only teleport to certain areas in this region. The arrow points to your specific destination. Click the arrow to dismiss it.
+ </notification>
+
+ <notification
+ icon="notify.tga"
+ name="FirstOverrideKeys"
+ type="notify">
+ Your movement keys are now being handled by an object.
+ Try the arrow keys or AWSD to see what they do.
+ Some objects (like guns) require you to go into mouselook to use them.
+ Press &apos;M&apos; to do this.
+ </notification>
+
+ <notification
+ icon="notify.tga"
+ name="FirstAppearance"
+ type="notify">
+ You are editing your Appearance.
+Use the arrow keys to look around.
+When you are done, press &apos;Save All&apos;.
+ </notification>
+
+ <notification
+ icon="notify.tga"
+ name="FirstInventory"
+ type="notify">
+ This is your Inventory, which contains items you own.
+
+ * To wear something, drag it onto yourself.
+ * To rez something inworld, drag it onto the ground.
+ * To read a notecard, double-click it.
+ </notification>
+
+ <notification
+ icon="notify.tga"
+ name="FirstSandbox"
+ type="notify">
+ This is a sandbox area, and is meant to help Residents learn how to build.
+
+ Things you build here will be deleted after you leave, so don&apos;t forget to right-click and choose &apos;Take&apos; to move your creation to your Inventory.
+ </notification>
+
+ <notification
+ icon="notify.tga"
+ name="FirstFlexible"
+ type="notify">
+ This object is flexible. Flexis must be phantom and not physical.
+ </notification>
+
+ <notification
+ icon="notify.tga"
+ name="FirstDebugMenus"
+ type="notify">
+ You opened the Advanced menu.
+
+ To toggle this menu,
+ Windows: Ctrl-Alt-D
+ Mac: &#8984;-Opt-D
+
+ </notification>
+
+ <notification
+ icon="notify.tga"
+ name="FirstSculptedPrim"
+ type="notify">
+ You are editing a Sculpted prim. Sculpties require a special texture to define their shape.
+ </notification>
+
+ <!--notification
+ icon="notify.tga"
+ name="FirstMedia"
+ type="notify">
+ You have begun playing media. Media can set to play automatically in the preferences window under Audio / Video. Note that this can be a security risk for media sites you do not trust.
+ </notification-->
+
+ <notification
+ icon="notifytip.tga"
+ name="MaxListSelectMessage"
+ type="notifytip">
+ You may only select up to [MAX_SELECT] items from this list.
+ </notification>
+
+ <notification
+ icon="notify.tga"
+ name="VoiceInviteP2P"
+ type="notify">
+[NAME] is inviting you to a Voice Chat call.
+Click Accept to join the call or Decline to decline the invitation. Click Block to block this caller.
+ <unique>
+ <context key="NAME"/>
+ </unique>
+ <form name="form">
+ <button
+ index="0"
+ name="Accept"
+ text="Accept"/>
+ <button
+ index="1"
+ name="Decline"
+ text="Decline"/>
+ <button
+ index="2"
+ name="Mute"
+ text="Block"/>
+ </form>
+ </notification>
+
+ <notification
+ icon="notify.tga"
+ name="AutoUnmuteByIM"
+ type="notify">
+[FIRST] [LAST] was sent an instant message and has been automatically unblocked.
+ </notification>
+
+ <notification
+ icon="notify.tga"
+ name="AutoUnmuteByMoney"
+ type="notify">
+[FIRST] [LAST] was given money and has been automatically unblocked.
+ </notification>
+
+ <notification
+ icon="notify.tga"
+ name="AutoUnmuteByInventory"
+ type="notify">
+[FIRST] [LAST] was offered inventory and has been automatically unblocked.
+ </notification>
+
+ <notification
+ icon="notify.tga"
+ name="VoiceInviteGroup"
+ type="notify">
+[NAME] has joined a Voice Chat call with the group [GROUP].
+Click Accept to join the call or Decline to decline the invitation. Click Block to block this caller.
+ <unique>
+ <context key="NAME"/>
+ <context key="GROUP"/>
+ </unique>
+ <form name="form">
+ <button
+ index="0"
+ name="Accept"
+ text="Accept"/>
+ <button
+ index="1"
+ name="Decline"
+ text="Decline"/>
+ <button
+ index="2"
+ name="Mute"
+ text="Block"/>
+ </form>
+ </notification>
+
+ <notification
+ icon="notify.tga"
+ name="VoiceInviteAdHoc"
+ type="notify">
+[NAME] has joined a voice chat call with a conference chat.
+Click Accept to join the call or Decline to decline the invitation. Click Block to block this caller.
+ <unique>
+ <context key="NAME"/>
+ </unique>
+ <form name="form">
+ <button
+ index="0"
+ name="Accept"
+ text="Accept"/>
+ <button
+ index="1"
+ name="Decline"
+ text="Decline"/>
+ <button
+ index="2"
+ name="Mute"
+ text="Block"/>
+ </form>
+ </notification>
+
+ <notification
+ icon="notify.tga"
+ name="InviteAdHoc"
+ type="notify">
+[NAME] is inviting you to a conference chat.
+Click Accept to join the chat or Decline to decline the invitation. Click Block to block this caller.
+ <unique>
+ <context key="NAME"/>
+ </unique>
+ <form name="form">
+ <button
+ index="0"
+ name="Accept"
+ text="Accept"/>
+ <button
+ index="1"
+ name="Decline"
+ text="Decline"/>
+ <button
+ index="2"
+ name="Mute"
+ text="Block"/>
+ </form>
+ </notification>
+
+ <notification
+ icon="notifytip.tga"
+ name="VoiceChannelFull"
+ type="notifytip">
+ The voice call you are trying to join, [VOICE_CHANNEL_NAME], has reached maximum capacity. Please try again later.
+ <unique>
+ <context key="VOICE_CHANNEL_NAME"/>
+ </unique>
+ </notification>
+
+ <notification
+ icon="notifytip.tga"
+ name="ProximalVoiceChannelFull"
+ type="notifytip">
+ We&apos;re sorry. This area has reached maximum capacity for voice conversations. Please try to use voice in another area.
+ <unique/>
+ </notification>
+
+ <notification
+ icon="notifytip.tga"
+ name="VoiceChannelDisconnected"
+ type="notifytip">
+ You have been disconnected from [VOICE_CHANNEL_NAME]. You will now be reconnected to spatial voice chat.
+ <unique>
+ <context key="VOICE_CHANNEL_NAME"/>
+ </unique>
+ </notification>
+
+ <notification
+ icon="notifytip.tga"
+ name="VoiceChannelDisconnectedP2P"
+ type="notifytip">
+ [VOICE_CHANNEL_NAME] has ended the call. You will now be reconnected to spatial voice chat.
+ <unique>
+ <context key="VOICE_CHANNEL_NAME"/>
+ </unique>
+ </notification>
+
+ <notification
+ icon="notifytip.tga"
+ name="P2PCallDeclined"
+ type="notifytip">
+ [VOICE_CHANNEL_NAME] has declined your call. You will now be reconnected to spatial voice chat.
+ <unique>
+ <context key="VOICE_CHANNEL_NAME"/>
+ </unique>
+ </notification>
+
+ <notification
+ icon="notifytip.tga"
+ name="P2PCallNoAnswer"
+ type="notifytip">
+ [VOICE_CHANNEL_NAME] is not available to take your call. You will now be reconnected to spatial voice chat.
+ <unique>
+ <context key="VOICE_CHANNEL_NAME"/>
+ </unique>
+ </notification>
+
+ <notification
+ icon="notifytip.tga"
+ name="VoiceChannelJoinFailed"
+ type="notifytip">
+ Failed to connect to [VOICE_CHANNEL_NAME], please try again later. You will now be reconnected to spatial voice chat.
+ <unique>
+ <context key="VOICE_CHANNEL_NAME"/>
+ </unique>
+ </notification>
+
+ <notification
+ duration="10"
+ icon="notifytip.tga"
+ name="VoiceLoginRetry"
+ type="notifytip">
+ We are creating a voice channel for you. This may take up to one minute.
+ <unique/>
+ </notification>
+
+ <notification
+ icon="notifytip.tga"
+ name="Cannot enter parcel: not a group member"
+ type="notifytip">
+ Only members of a certain group can visit this area.
+ </notification>
+
+ <notification
+ icon="notifytip.tga"
+ name="Cannot enter parcel: banned"
+ type="notifytip">
+ Cannot enter parcel, you have been banned.
+ </notification>
+
+ <notification
+ icon="notifytip.tga"
+ name="Cannot enter parcel: not on access list"
+ type="notifytip">
+ Cannot enter parcel, you are not on the access list.
+ </notification>
+
+ <notification
+ icon="notifytip.tga"
+ name="VoiceNotAllowed"
+ type="notifytip">
+ You do not have permission to connect to voice chat for [VOICE_CHANNEL_NAME].
+ <unique>
+ <context key="VOICE_CHANNEL_NAME"/>
+ </unique>
+ </notification>
+
+ <notification
+ icon="notifytip.tga"
+ name="VoiceCallGenericError"
+ type="notifytip">
+ An error has occurred while trying to connect to voice chat for [VOICE_CHANNEL_NAME]. Please try again later.
+ <unique>
+ <context key="VOICE_CHANNEL_NAME"/>
+ </unique>
+ </notification>
+
+ <notification
+ duration="10"
+ icon="notifytip.tga"
+ name="ServerVersionChanged"
+ priority="high"
+ type="notifytip">
+ You just entered a region using a different server version, which may affect performance. Click to see the release notes.
+ </notification>
+
+ <notification
+ icon="notifytip.tga"
+ name="UnableToOpenCommandURL"
+ priority="high"
+ type="notifytip">
+ The link you clicked cannot be opened from this web browser.
+ </notification>
+
+ <notification name="IMToast" type="notifytoast">
+ [MESSAGE]
+ <form name="form">
+ <button index="0" name="respondbutton" text="Respond"/>
+ </form>
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="CreateGroupCost"
+ type="alertmodal">
+ Creating this group will cost L$100.
+ Groups need more than one member, or they are deleted forever.
+ Please invite members within 48 hours.
+ <usetemplate
+ canceltext="Cancel"
+ name="okcancelbuttons"
+ notext="Cancel"
+ yestext="Create group for L$100"/>
+ </notification>
+
+ <notification icon="notifytip.tga"
+ name="AttachmentSaved" type="notifytip">
+ Attachment has been saved.
+ </notification>
+
+ <global name="UnsupportedCPU">
+- Your CPU speed does not meet the minimum requirements.
+ </global>
+
+ <global name="UnsupportedGLRequirements">
+You do not appear to have the proper hardware requirements for [APP_NAME]. [APP_NAME] requires an OpenGL graphics card that has multitexture support. If this is the case, you may want to make sure that you have the latest drivers for your graphics card, and service packs and patches for your operating system.
+
+If you continue to have problems, please visit the [SUPPORT_SITE].
+ </global>
+
+ <global name="UnsupportedCPUAmount">
+796
+ </global>
+
+ <global name="UnsupportedRAMAmount">
+510
+ </global>
+
+ <global name="UnsupportedGPU">
+- Your graphics card does not meet the minimum requirements.
+ </global>
+
+ <global name="UnsupportedRAM">
+- Your system memory does not meet the minimum requirements.
+ </global>
+
+ <global name="PermYes">
+Yes
+ </global>
+
+ <global name="PermNo">
+No
+ </global>
+<!-- this is alert string from server. the name needs to match entire the server string, and needs to be changed
+ whenever the server string changes -->
+ <global name="You can only set your 'Home Location' on your land or at a mainland Infohub.">
+If you own a piece of land, you can make it your home location.
+Otherwise, you can look at the Map and find places marked &quot;Infohub&quot;.
+ </global>
+
+</notifications>
+
diff --git a/indra/newview/skins/default/xui/en/panel_activeim_row.xml b/indra/newview/skins/default/xui/en/panel_activeim_row.xml
new file mode 100644
index 0000000000..8977f30a51
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/panel_activeim_row.xml
@@ -0,0 +1,47 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<panel
+ follows="bottom|right"
+ name="panel_activeim_row"
+ layout="topleft"
+ top="0"
+ left="0"
+ height="40"
+ width="332"
+ background_visible="true"
+ bevel_style="in"
+ bg_alpha_color="0 0 0 0">
+ <chiclet_im
+ name="chiclet"
+ layout="topleft"
+ top="4"
+ left="10"
+ height="26"
+ width="45">
+ </chiclet_im>
+ <text
+ type="string"
+ name="contact_name"
+ layout="topleft"
+ top="8"
+ left="70"
+ height="20"
+ width="230"
+ length="1"
+ follows="left|top|right|bottom"
+ font="SansSerifBigBold"
+ text_color="White">Contact Name</text>
+ <button
+ name="hide_btn"
+ layout="topleft"
+ top="10"
+ left="310"
+ height="20"
+ width="20"
+ label=""
+ image_unselected="toast_hide_btn.tga"
+ image_disabled="toast_hide_btn.tga"
+ image_selected="toast_hide_btn.tga"
+ image_hover_selected="toast_hide_btn.tga"
+ image_disabled_selected="toast_hide_btn.tga">
+ </button>
+</panel> \ No newline at end of file
diff --git a/indra/newview/skins/default/xui/en/panel_audio_device.xml b/indra/newview/skins/default/xui/en/panel_audio_device.xml
new file mode 100644
index 0000000000..5f495ef8ce
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/panel_audio_device.xml
@@ -0,0 +1,153 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<panel
+ height="240"
+ layout="topleft"
+ left="8"
+ name="device_settings"
+ top="240"
+ width="404">
+ <panel.string
+ name="default_text">
+ Default
+ </panel.string>
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="16"
+ layout="topleft"
+ left="6"
+ name="Audio Devices"
+ width="200">
+ Audio Devices
+ </text>
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="16"
+ layout="topleft"
+ left="20"
+ name="Input device (microphone):"
+ top="26"
+ width="200">
+ Input device (microphone):
+ </text>
+ <combo_box
+ height="18"
+ layout="topleft"
+ left_delta="0"
+ max_chars="128"
+ name="voice_input_device"
+ top_pad="2"
+ width="225" />
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="16"
+ layout="topleft"
+ left_delta="0"
+ name="Output device (speakers):"
+ top_pad="9"
+ width="200">
+ Output device (speakers):
+ </text>
+ <combo_box
+ height="18"
+ layout="topleft"
+ left_delta="0"
+ max_chars="128"
+ name="voice_output_device"
+ top_pad="2"
+ width="225" />
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="16"
+ layout="topleft"
+ left="6"
+ name="Input level:"
+ top="121"
+ width="200">
+ Input Level
+ </text>
+ <text_editor
+ type="string"
+ length="1"
+ top="135"
+ bg_readonly_color="0 0 0 0"
+ enabled="false"
+ height="60"
+ hide_border="true"
+ hide_scrollbar="true"
+ layout="topleft"
+ left_delta="10"
+ max_length="65535"
+ name="voice_intro_text1"
+ tab_stop="false"
+ width="380"
+ word_wrap="true">
+ Adjust the slider to control how loud you sound to other Residents. To test the input level, simply speak into your microphone.
+ </text_editor>
+ <slider_bar
+ follows="left|top"
+ height="17"
+ increment="0.05"
+ initial_value="1.0"
+ layout="topleft"
+ left_delta="5"
+ max_val="2"
+ name="mic_volume_slider"
+ tool_tip="Change the volume using this slider"
+ top="202"
+ width="90" />
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="20"
+ layout="topleft"
+ left_pad="5"
+ name="wait_text"
+ top_delta="1"
+ width="200">
+ Please wait
+ </text>
+ <locate
+ height="20"
+ layout="topleft"
+ left_delta="0"
+ name="bar0"
+ top_delta="5"
+ width="20" />
+ <locate
+ height="20"
+ layout="topleft"
+ left_pad="2"
+ name="bar1"
+ top_delta="0"
+ width="20" />
+ <locate
+ height="20"
+ layout="topleft"
+ left_pad="2"
+ name="bar2"
+ top_delta="0"
+ width="20" />
+ <locate
+ height="20"
+ layout="topleft"
+ left_pad="2"
+ name="bar3"
+ top_delta="0"
+ width="20" />
+ <locate
+ height="20"
+ layout="topleft"
+ left_pad="2"
+ name="bar4"
+ top_delta="0"
+ width="20" />
+</panel>
diff --git a/indra/newview/skins/default/xui/en/panel_avatar_list_item.xml b/indra/newview/skins/default/xui/en/panel_avatar_list_item.xml
new file mode 100644
index 0000000000..3de3365539
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/panel_avatar_list_item.xml
@@ -0,0 +1,65 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<!-- All our XML is utf-8 encoded. -->
+
+<panel
+ name="avatar_list_item"
+ title="avatar_list_item"
+ visible="true"
+ width="314"
+ height="30"
+ left="0"
+ top="100"
+ follows="bottom|right|left"
+ min_width="150"
+ max_height="30"
+
+ background_opaque="false"
+ background_visible="true"
+ bevel_style="in"
+ bg_alpha_color="0.3 0.3 0.3 1.0">
+
+ <avatar_icon
+ bottom="5" left="5" width="20" height="20" follows="top|left"
+ color="1 1 1 1" enabled="true" image_name="smile.png"
+ mouse_opaque="true" name="avatar_icon"
+ />
+
+ <text
+ bottom="4" left="35" width="160" height="20" follows="right|left"
+ font="SansSerifBigBold" text_color="white"
+ mouse_opaque="true" name="user_name" >
+ Boris Linden
+ </text>
+
+ <text
+ bottom="3" left="190" width="40" height="20" follows="right"
+ font="SansSerif" text_color="0.5 0.5 0.5 1.0"
+ mouse_opaque="true" name="user_status" >
+ Away
+ </text>
+
+ <icon
+ bottom="5" left="230" width="20" height="20" follows="right"
+ color="1 1 1 1" enabled="true" image_name="speaking_indicator.tga"
+ mouse_opaque="true" name="locator"
+ />
+
+ <button
+ bottom="5" left="260" width="20" height="20" follows="right"
+ name="info_btn" label=""
+ image_unselected="avatar_info_btn.tga" image_disabled="avatar_info_btn.tga"
+ image_selected="avatar_info_btn_active.tga" image_hover_selected="avatar_info_btn_active.tga"
+ image_disabled_selected="avatar_info_btn.tga" font="SansSerifBigBold"
+ />
+
+ <button
+ bottom="5" left="290" width="20" height="20" follows="right"
+ name="profile_btn" label=""
+ image_unselected="profile_chevron_btn.tga" image_disabled="profile_chevron_btn.tga"
+ image_selected="profile_chevron_btn_active.tga" image_hover_selected="profile_chevron_btn_active.tga"
+ image_disabled_selected="profile_chevron_btn.tga" font="SansSerifBigBold"
+ />
+
+
+
+</panel>
diff --git a/indra/newview/skins/default/xui/en/panel_avatar_tag.xml b/indra/newview/skins/default/xui/en/panel_avatar_tag.xml
new file mode 100644
index 0000000000..34b4736979
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/panel_avatar_tag.xml
@@ -0,0 +1,71 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<panel
+ name="avatar_tag_notification"
+ top="10"
+ width="250"
+ height="100"
+ background_opaque="false"
+ background_visible="true"
+ follows="left|top|bottom|right"
+ bg_alpha_color="0.3 0.3 0.3 1.0">
+ <panel
+ width="250"
+ height="30"
+ background_visible="true"
+ background_opaque="false"
+ follows="left|top|right"
+ bg_alpha_color="0.0 0.0 0.0 1.0"
+ name="msg_caption">
+ <avatar_icon
+ top="-7"
+ left="10"
+ width="20"
+ height="20"
+ follows="left|top"
+ color="1 1 1 1"
+ enabled="true"
+ name="avatar_tag_icon"/>
+ <text
+ width="160"
+ top="-10"
+ left="40"
+ height="20"
+ follows="left|right|top"
+ font="SansSerifBigBold"
+ text_color="white"
+ word_wrap="true"
+ mouse_opaque="true"
+ name="sender_tag_name" >
+ Angela Tester
+ </text>
+ <text
+ width="30"
+ top="-12"
+ left="210"
+ height="20"
+ follows="right|top"
+ text_color="white"
+ word_wrap="true"
+ mouse_opaque="true"
+ name="tag_time" >
+ 07:52
+ </text>
+ </panel>
+ <text_editor
+ top="65"
+ left="10"
+ right="-10"
+ can_resize="true"
+ height="100"
+ follows="left|top|bottom|right"
+ font="SansSerifSmall"
+ read_only="true"
+ bg_readonly_color="0 0 0 0"
+ hide_scrollbar="true"
+ word_wrap="true"
+ mouse_opaque="true"
+ name="msg_text" >
+ The quick brown fox jumps over the lazy dog.
+ </text_editor>
+</panel>
+
diff --git a/indra/newview/skins/default/xui/en/panel_bars.xml b/indra/newview/skins/default/xui/en/panel_bars.xml
new file mode 100644
index 0000000000..9c06329eaf
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/panel_bars.xml
@@ -0,0 +1,69 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<panel
+ follows="left|right|top|bottom"
+ height="768"
+ layout="topleft"
+ left="0"
+ mouse_opaque="false"
+ name="bottom_panel"
+ width="1024">
+ <panel
+ follows="left|right|top|bottom"
+ height="728"
+ layout="topleft"
+ left="0"
+ mouse_opaque="false"
+ name="status"
+ top="0"
+ width="1024" />
+ <layout_stack
+ border_size="0"
+ follows="left|right|bottom|top"
+ height="768"
+ layout="topleft"
+ left_delta="0"
+ mouse_opaque="false"
+ name="bar_stack"
+ top_delta="0"
+ use_bounding_rect="true"
+ width="1024">
+ <layout_panel
+ follows="left|right|top|bottom"
+ height="768"
+ layout="topleft"
+ left="0"
+ mouse_opaque="false"
+ name="spacer"
+ top="0"
+ user_resize="false"
+ width="1024" />
+ <layout_panel
+ auto_resize="false"
+ height="200"
+ layout="topleft"
+ min_height="200"
+ mouse_opaque="false"
+ name="overlay"
+ use_bounding_rect="true"
+ user_resize="false"
+ width="1024" />
+ <layout_panel
+ auto_resize="false"
+ filename="panel_toolbar.xml"
+ layout="topleft"
+ min_height="28"
+ name="toolbar"
+ use_bounding_rect="true"
+ user_resize="false"
+ width="1024" />
+ </layout_stack>
+ <panel
+ follows="left|right|top|bottom"
+ height="728"
+ layout="topleft"
+ left_delta="0"
+ mouse_opaque="false"
+ name="hud"
+ top_delta="-10"
+ width="1024" />
+</panel>
diff --git a/indra/newview/skins/default/xui/en/panel_bottomtray.xml b/indra/newview/skins/default/xui/en/panel_bottomtray.xml
new file mode 100644
index 0000000000..b6d0678cfb
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/panel_bottomtray.xml
@@ -0,0 +1,328 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<panel
+ background_visible="true"
+ bg_alpha_color="0.25 0.25 0.25 1"
+ bg_opaque_color="0.25 0.25 0.25 1"
+ follows="left|bottom|right"
+ height="28"
+ layout="topleft"
+ left="0"
+ name="bottom_tray"
+ top="28"
+ border_visible="true"
+ width="1000">
+ <layout_stack
+ border_size="0"
+ clip="false"
+ follows="left|right|bottom|top"
+ height="28"
+ layout="topleft"
+ left="0"
+ name="toolbar_stack"
+ orientation="horizontal"
+ top="0"
+ width="1000">
+ <icon
+ auto_resize="false"
+ color="0 0 0 0"
+ follows="left|right"
+ height="10"
+ image_name="spacer24.tga"
+ layout="topleft"
+ left="0"
+ top="0"
+ width="5"/>
+ <layout_panel
+ follows="left|right"
+ height="28"
+ layout="topleft"
+ left="5"
+ min_height="28"
+ width="500"
+ top="0"
+ min_width="305"
+ name="chat_bar"
+ user_resize="false"
+ filename="panel_nearby_chat_bar.xml"/>
+ <icon
+ auto_resize="false"
+ color="0 0 0 0"
+ follows="left|right"
+ height="10"
+ image_name="spacer24.tga"
+ layout="topleft"
+ left="0"
+ name="DUMMY"
+ top="0"
+ width="3"/>
+ <layout_panel
+ auto_resize="false"
+ follows="right"
+ height="28"
+ layout="topleft"
+ left="5"
+ min_height="28"
+ width="70"
+ top_delta="-10"
+ min_width="70"
+ name="movement_panel"
+ user_resize="false">
+ <button
+ follows="right"
+ height="20"
+ is_toggle="true"
+ label="Move"
+ layout="topleft"
+ name="movement_btn"
+ tab_stop="false"
+ tool_tip="Shows/Hide Movement controls"
+ top="6"
+ width="70">
+ <button.init_callback
+ function="Button.SetFloaterToggle"
+ parameter="moveview" />
+ </button>
+ </layout_panel>
+ <icon
+ auto_resize="false"
+ color="0 0 0 0"
+ follows="left|right"
+ height="10"
+ image_name="spacer24.tga"
+ layout="topleft"
+ left="0"
+ name="DUMMY"
+ top="0"
+ width="8"/>
+ <layout_panel
+ auto_resize="false"
+ follows="right"
+ height="28"
+ layout="topleft"
+ min_height="28"
+ min_width="150"
+ name="cam_panel"
+ top_delta="-10"
+ width="150">
+ <split_button
+ follows="right"
+ height="18"
+ name="presets"
+ top="6"
+ width="35">
+ <split_button.arrow_button
+ image_selected="camera_presets/camera_presets_arrow.png"
+ image_unselected="camera_presets/camera_presets_arrow.png"
+ image_disabled_selected="camera_presets/camera_presets_arrow.png"
+ image_disabled="camera_presets/camera_presets_arrow.png"
+ name="camera_presets"
+ tool_tip="Camera Presets"
+ />
+ <split_button.item
+ image_selected="camera_presets/camera_presets_rear_view.png"
+ image_unselected="camera_presets/camera_presets_rear_view.png"
+ name="rear_view"
+ tool_tip="Rear View"
+ />
+ <split_button.item
+ image_selected="camera_presets/camera_presets_34_view.png"
+ image_unselected="camera_presets/camera_presets_34_view.png"
+ name="group_view"
+ tool_tip="Group View"
+ />
+ <split_button.item
+ image_selected="camera_presets/camera_presets_fron_view.png"
+ image_unselected="camera_presets/camera_presets_fron_view.png"
+ name="front_view"
+ tool_tip="Front View"
+ />
+ </split_button>
+ <button
+ follows="right"
+ height="20"
+ is_toggle="true"
+ label="Camera"
+ layout="topleft"
+ left_pad="0"
+ tab_stop="false"
+ tool_tip="Shows/Hide Camera controls"
+ top="6"
+ name="camera_btn"
+ width="70">
+ <button.init_callback
+ function="Button.SetFloaterToggle"
+ parameter="camera" />
+ </button>
+ <split_button
+ arrow_position="right"
+ follows="right"
+ height="18"
+ left_pad="0"
+ name="snapshots"
+ top="6"
+ width="35">
+ <split_button.arrow_button
+ image_selected="camera_presets/camera_presets_arrow_right.png"
+ image_unselected="camera_presets/camera_presets_arrow_right.png"
+ image_disabled_selected="camera_presets/camera_presets_arrow_right.png"
+ image_disabled="camera_presets/camera_presets_arrow_right.png"
+ name="snapshot_settings"
+ tool_tip="Snapshot Settings" />
+ <split_button.item
+ image_selected="camera_presets/camera_presets_snapshot.png"
+ image_unselected="camera_presets/camera_presets_snapshot.png"
+ name="snapshot"
+ tool_tip="Take Snapshot" />
+ </split_button>
+ </layout_panel>
+ <icon
+ auto_resize="false"
+ color="0 0 0 0"
+ follows="left|right"
+ height="10"
+ image_name="spacer24.tga"
+ layout="topleft"
+ left="0"
+ name="DUMMY"
+ top="0"
+ width="5"/>
+ <layout_panel
+ follows="left|right"
+ height="28"
+ layout="topleft"
+ min_height="28"
+ top="0"
+ name="chiclet_list_panel"
+ width="150"
+ user_resize="false">
+ <chiclet_panel
+ follows="left|right"
+ height="25"
+ layout="topleft"
+ left="0"
+ name="chiclet_list"
+ top="1"
+ chiclet_padding="3"
+ scrolling_offset="40"
+ width="150" />
+ </layout_panel>
+ <icon
+ auto_resize="false"
+ color="0 0 0 0"
+ follows="left|right"
+ height="10"
+ image_name="spacer24.tga"
+ layout="topleft"
+ left="0"
+ top="0"
+ width="5"/>
+ <layout_panel
+ auto_resize="false"
+ follows="right"
+ height="28"
+ layout="topleft"
+ min_height="28"
+ name="im_well_panel"
+ width="40"
+ top="0"
+ min_width="40"
+ user_resize="false">
+ <chiclet_notification
+ follows="right"
+ height="25"
+ layout="topleft"
+ left="0"
+ name="im_well"
+ top="2"
+ width="40">
+ <button
+ image_selected="im_notifications.tga"
+ image_unselected="im_notifications.tga"/>
+ <unread_notifications
+ width="20"
+ height="20"
+ left="18"
+ top="23"/>
+<!--
+ <chiclet_notification.commit_callback
+ function="Notification.Show"
+ parameter="ClickUnimplemented" />
+ -->
+ </chiclet_notification>
+ </layout_panel>
+ <icon
+ auto_resize="false"
+ color="0 0 0 0"
+ follows="left|right"
+ height="10"
+ image_name="spacer24.tga"
+ layout="topleft"
+ left="0"
+ top="0"
+ width="10"/>
+ <view_border
+ auto_resize="false"
+ bevel_style="in"
+ follows="left|right"
+ height="28"
+ layout="topleft"
+ left="270"
+ name="well_separator"
+ top="0"
+ width="1" />
+ <icon
+ auto_resize="false"
+ color="0 0 0 0"
+ follows="left|right"
+ height="10"
+ image_name="spacer24.tga"
+ layout="topleft"
+ left="0"
+ top="0"
+ width="10"/>
+ <layout_panel
+ auto_resize="false"
+ follows="right"
+ height="28"
+ layout="topleft"
+ min_height="28"
+ top="0"
+ name="sys_well_panel"
+ width="48"
+ min_width="48"
+ user_resize="false">
+ <chiclet_notification
+ follows="right"
+ height="25"
+ layout="topleft"
+ left="0"
+ name="sys_well"
+ top="2"
+ width="48">
+ <button
+ image_selected="bottom_tray_sys_notifications.tga"
+ image_unselected="bottom_tray_sys_notifications.tga"/>
+ <unread_notifications
+ width="20"
+ height="20"
+ left="22"
+ top="23"/>
+<!--
+ <chiclet_notification.commit_callback
+ function="Notification.Show"
+ parameter="ClickUnimplemented" />
+ -->
+ </chiclet_notification>
+ </layout_panel>
+ <icon
+ auto_resize="false"
+ color="0 0 0 0"
+ follows="left|right"
+ height="10"
+ image_name="spacer24.tga"
+ layout="topleft"
+ left="0"
+ top="0"
+ width="5"/>
+ </layout_stack>
+</panel>
diff --git a/indra/newview/skins/default/xui/en/panel_chat_item.xml b/indra/newview/skins/default/xui/en/panel_chat_item.xml
new file mode 100644
index 0000000000..713c3a41a2
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/panel_chat_item.xml
@@ -0,0 +1,38 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<!-- All our XML is utf-8 encoded. -->
+
+<panel
+ name="instant_message"
+ width="300"
+ height="180"
+ background_opaque="false"
+ background_visible="true"
+ follows="left|top|right|bottom"
+ bg_alpha_color="0.3 0.3 0.3 1.0">
+ <panel width="250" height="30" background_visible="true" background_opaque="false" bg_alpha_color="0.0 0.0 0.0 1.0" name="msg_caption">
+ <avatar_icon
+ top="25" left="10" width="20" height="20" follows="left|top"
+ color="1 1 1 1" enabled="true" name="avatar_icon"
+ />
+ <text
+ width="130" top="25" left="40" height="20" follows="left|right|top"
+ font="SansSerifBigBold" text_color="white" word_wrap="true"
+ mouse_opaque="true" name="sender_name" >
+ Jerry Knight
+ </text>
+ <icon top="22" left="170" width="15" height="15" follows="top|right"
+ image_name="icn_voice-pvtfocus.tga" visible="false" name="msg_inspector"/>
+ <icon top="22" left="190" width="10" height="10" follows="top|right"
+ image_name="speaking_indicator.tga" name="msg_icon"/>
+ <text width="35" top="22" left="205" height="20" follows="right|top"
+ text_color="white" word_wrap="true" mouse_opaque="true" name="msg_time" >
+ 10:32
+ </text>
+ </panel>
+ <text_chat
+ top="-35" left="10" right="-10" height="120" follows="left|right|bottom"
+ font="SansSerifSmall" text_color="white" word_wrap="true"
+ mouse_opaque="true" name="msg_text" >
+ </text_chat>
+</panel>
+
diff --git a/indra/newview/skins/default/xui/en/panel_classified.xml b/indra/newview/skins/default/xui/en/panel_classified.xml
new file mode 100644
index 0000000000..fde795260e
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/panel_classified.xml
@@ -0,0 +1,138 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<panel
+ follows="bottom|left"
+ height="490"
+ label="Classified"
+ layout="topleft"
+ left="330"
+ name="Classified"
+ top="490"
+ width="450">
+ <panel.string
+ name="ad_placed_paid">
+ Ad placed: [DATE], Paid L$[AMT] for listing.
+ </panel.string>
+ <panel.string
+ name="update_txt">
+ Update
+ </panel.string>
+ <panel.string
+ name="publish_txt">
+ Publish...
+ </panel.string>
+ <panel.string
+ name="dateStr">
+ [mthnum,datetime,slt]/[day,datetime,slt]/[year,datetime,slt]
+ </panel.string>
+ <texture_picker
+ follows="left|top"
+ height="300"
+ layout="topleft"
+ left="20"
+ name="snapshot_ctrl"
+ top="15"
+ width="400" />
+ <line_editor
+ enabled="false"
+ follows="left|top"
+ font="SansSerif"
+ height="20"
+ layout="topleft"
+ left_delta="0"
+ name="given_name_editor"
+ tool_tip="Name must begin with a letter or number, not punctuation."
+ top_delta="288"
+ width="400" />
+ <text_editor
+ enabled="false"
+ follows="left|top"
+ height="90"
+ layout="topleft"
+ left="20"
+ max_length="1023"
+ name="desc_editor"
+ width="400"
+ word_wrap="true" />
+ <line_editor
+ enabled="false"
+ follows="left|top"
+ font="SansSerif"
+ height="20"
+ layout="topleft"
+ left="20"
+ name="location_editor"
+ tool_tip="Set the location for this classified to your current position."
+ width="400" />
+ <button
+ follows="left|top"
+ height="20"
+ label="Set"
+ layout="topleft"
+ left_delta="360"
+ name="set_location_btn"
+ top_delta="0"
+ width="60" />
+ <button
+ follows="left|top"
+ height="20"
+ label="Teleport"
+ layout="topleft"
+ left="20"
+ name="classified_teleport_btn"
+ top="449"
+ width="100" />
+ <button
+ follows="left|top"
+ height="20"
+ label="Map"
+ layout="topleft"
+ left_pad="5"
+ name="classified_map_btn"
+ top_delta="0"
+ width="100" />
+ <button
+ follows="left|top"
+ height="20"
+ label="Profile"
+ layout="topleft"
+ left_pad="5"
+ name="classified_profile_btn"
+ top_delta="0"
+ width="100" />
+ <combo_box
+ height="20"
+ layout="topleft"
+ left="30"
+ name="classified_mature_check"
+ top="48"
+ width="130">
+ <combo_box.item
+ label="- Select Mature -"
+ name="select_mature"
+ value="Select" />
+ <combo_box.item
+ label="Mature Content"
+ name="mature"
+ value="Mature" />
+ <combo_box.item
+ label="PG Content"
+ name="pg"
+ value="PG" />
+ </combo_box>
+ <combo_box
+ bottom="45"
+ height="18"
+ layout="topleft"
+ left="20"
+ name="classified_category_combo"
+ right="150" />
+ <button
+ follows="left|top"
+ height="20"
+ label="Update"
+ layout="topleft"
+ left="30"
+ name="classified_update_btn"
+ top="70"
+ width="70" />
+</panel>
diff --git a/indra/newview/skins/default/xui/en/panel_edit_pick.xml b/indra/newview/skins/default/xui/en/panel_edit_pick.xml
new file mode 100644
index 0000000000..291803fbc5
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/panel_edit_pick.xml
@@ -0,0 +1,194 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<panel
+ background_visible="true"
+ bevel_style="in"
+ height="420"
+ label="Edit Pick"
+ layout="topleft"
+ left="0"
+ name="panel_edit_pick"
+ top="0"
+ width="255">
+ <scroll_container
+ color="DkGray2"
+ follows="left|top|right|bottom"
+ height="300"
+ layout="topleft"
+ left="0"
+ name="profile_scroll"
+ reserve_scroll_corner="true"
+ opaque="true"
+ width="255">
+ <panel
+ name="scroll_content_panel"
+ follows="left|top|right"
+ layout="topleft"
+ top="0"
+ left="0"
+ width="240"
+ height="575">
+ <text
+ type="string"
+ length="1"
+ follows="top"
+ font="SansSerifHugeBold"
+ height="15"
+ layout="topleft"
+ left="10"
+ name="title"
+ text_color="white"
+ top="17"
+ width="250">
+ Edit Pick
+ </text>
+ <panel
+ background_visible="true"
+ bg_alpha_color="DkGray2"
+ width="280"
+ follows="left|right|top|bottom"
+ height="560"
+ layout="topleft"
+ left="10"
+ right="-10"
+ top_pad="5">
+ <panel
+ follows="left|top|right"
+ height="150"
+ layout="topleft"
+ left="10"
+ right="-10"
+ top="10">
+ <panel
+ follows="left|top|right"
+ height="150"
+ layout="topleft" >
+ <texture_picker
+ follows="left|top|right"
+ height="150"
+ layout="topleft"
+ name="pick_snapshot" />
+ </panel>
+ <icon
+ height="16"
+ image_name="image_edit_icon.tga"
+ layout="topleft"
+ name="edit_icon"
+ right="-25"
+ top="30"
+ visible="false"
+ width="16" />
+ </panel>
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="16"
+ layout="topleft"
+ left="10"
+ name="Name:"
+ text_color="white">
+ Name:
+ </text>
+ <line_editor
+ follows="left|top|right"
+ font="SansSerif"
+ height="20"
+ layout="topleft"
+ left="10"
+ max_length="63"
+ name="pick_name"
+ right="-10"
+ text_color="black"
+ width="255" />
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="30"
+ layout="topleft"
+ left="10"
+ name="description_label"
+ text_color="white"
+ v_pad="15"
+ valign="center">
+ Description:
+ </text>
+ <text_editor
+ follows="left|top|right"
+ height="100"
+ hide_scrollbar="true"
+ layout="topleft"
+ left="10"
+ max_length="1023"
+ name="pick_desc"
+ text_color="black"
+ right="-10"
+ word_wrap="true" />
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="20"
+ layout="topleft"
+ left="10"
+ name="location_label"
+ text_color="white"
+ v_pad="15"
+ valign="bottom">
+ Location:
+ </text>
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="50"
+ layout="topleft"
+ left="10"
+ name="pick_location"
+ right="-10"
+ text_color="white"
+ v_pad="10"
+ width="250"
+ valign="center"
+ word_wrap="true">
+ loading...
+ </text>
+ <button
+ follows="left|top"
+ height="20"
+ label="Set to Current Location"
+ layout="topleft"
+ left="10"
+ name="set_to_curr_location_btn"
+ width="200" />
+ </panel>
+ </panel>
+ </scroll_container>
+ <panel
+ follows="left|right|bottom"
+ height="25"
+ label="bottom_panel"
+ layout="topleft"
+ left="10"
+ name="bottom_panel"
+ top_pad="2">
+ <button
+ follows="bottom|left"
+ height="20"
+ label="Save [WHAT]"
+ layout="topleft"
+ name="save_changes_btn"
+ right="-120"
+ top="5"
+ width="130" />
+ <button
+ follows="bottom|left"
+ height="20"
+ label="Cancel"
+ layout="topleft"
+ name="cancel_btn"
+ right="-10"
+ top="5"
+ width="90" />
+ </panel>
+</panel>
diff --git a/indra/newview/skins/default/xui/en/panel_edit_profile.xml b/indra/newview/skins/default/xui/en/panel_edit_profile.xml
new file mode 100644
index 0000000000..c0366437db
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/panel_edit_profile.xml
@@ -0,0 +1,413 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<panel
+ class="edit_profile_panel"
+ background_visible="true"
+ bevel_style="in"
+ follows="left|top|right|bottom"
+ height="420"
+ label="Profile Edit"
+ layout="topleft"
+ left="10"
+ mouse_opaque="true"
+ name="edit_profile_panel"
+ top="10"
+ width="255">
+ <scroll_container
+ color="DkGray2"
+ follows="left|top|right|bottom"
+ height="300"
+ layout="topleft"
+ left="0"
+ name="profile_scroll"
+ reserve_scroll_corner="true"
+ opaque="true"
+ width="255">
+ <panel
+ name="scroll_content_panel"
+ follows="left|top|right"
+ layout="topleft"
+ top="0"
+ left="0"
+ width="240"
+ height="760">
+ <panel
+ background_visible="true"
+ bg_alpha_color="DkGray2"
+ follows="left|top|right|bottom"
+ height="620"
+ layout="topleft"
+ left="0"
+ name="data_panel"
+ top_pad="10"
+ width="260">
+ <panel
+ follows="left|top"
+ height="120"
+ layout="topleft"
+ left="10"
+ name="lifes_images_panel"
+ top_pad="10"
+ width="265">
+ <panel
+ height="137"
+ layout="topleft"
+ left="0"
+ name="second_life_image_panel"
+ top="0"
+ width="125">
+ <text
+ type="string"
+ length="1"
+ follows="left|top|right|bottom"
+ font="SansSerifSmall"
+ font.style="BOLD"
+ height="15"
+ layout="topleft"
+ left="0"
+ name="second_life_photo_title_text"
+ text_color="white"
+ top="0"
+ width="240">
+ [SECOND_LIFE]:
+ </text>
+ <texture_picker
+ allow_no_texture="true"
+ default_image_name="None"
+ follows="top|left"
+ height="117"
+ layout="topleft"
+ left="0"
+ name="2nd_life_pic"
+ top_pad="5"
+ width="102" />
+ </panel>
+ <icon
+ height="16"
+ image_name="image_edit_icon.tga"
+ layout="topleft"
+ left="75"
+ name="2nd_life_edit_icon"
+ tool_tip="Click to select an image"
+ top="35"
+ width="16" />
+ </panel>
+ <text_editor
+ type="string"
+ length="1"
+ follows="left|top|right"
+ font="SansSerifSmall"
+ height="125"
+ layout="topleft"
+ left="120"
+ top="30"
+ name="sl_description_edit"
+ width="115"
+ word_wrap="true">
+ </text_editor>
+ <panel
+ height="137"
+ layout="topleft"
+ left="10"
+ name="first_life_image_panel"
+ top_pad="20"
+ width="125">
+ <text
+ type="string"
+ length="1"
+ follows="left|top|right|bottom"
+ font="SansSerifSmall"
+ font.style="BOLD"
+ height="15"
+ layout="topleft"
+ left="0"
+ name="real_world_photo_title_text"
+ text_color="white"
+ top="0"
+ width="125">
+ Real World:
+ </text>
+ <texture_picker
+ allow_no_texture="true"
+ default_image_name="None"
+ follows="top|left"
+ height="117"
+ layout="topleft"
+ left="0"
+ name="real_world_pic"
+ top_pad="5"
+ width="102" />
+ </panel>
+ <icon
+ height="16"
+ image_name="image_edit_icon.tga"
+ layout="topleft"
+ left="85"
+ name="real_world_edit_icon"
+ tool_tip="Click to select an image"
+ top="210"
+ width="16" />
+ <text_editor
+ type="string"
+ length="1"
+ follows="left|top|right"
+ font="SansSerifSmall"
+ height="125"
+ layout="topleft"
+ left="120"
+ top="195"
+ name="fl_description_edit"
+ width="115"
+ word_wrap="true">
+ </text_editor>
+ <text
+ type="string"
+ follows="left|top"
+ font="SansSerifSmall"
+ font.style="BOLD"
+ height="15"
+ layout="topleft"
+ left="10"
+ name="online_me_status_text"
+ text_color="white"
+ top_pad="20"
+ width="255">
+ Status:
+ </text>
+ <combo_box
+ font="SansSerifSmall"
+ follows="left|top"
+ height="18"
+ layout="topleft"
+ left="10"
+ top_pad="5"
+ name="status_combo"
+ width="140">
+ <combo_box.item
+ label="Online"
+ name="online"
+ value="online" />
+ <combo_box.item
+ label="Away"
+ name="away"
+ value="away" />
+ <combo_box.item
+ label="Busy"
+ name="busy"
+ value="busy" />
+ </combo_box>
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ font="SansSerifSmall"
+ font.style="BOLD"
+ height="15"
+ layout="topleft"
+ left="10"
+ name="title_homepage_text"
+ text_color="white"
+ top_pad="20"
+ width="240">
+ Homepage:
+ </text>
+ <line_editor
+ follows="left|top|right"
+ font="SansSerifSmall"
+ height="20"
+ layout="topleft"
+ left="9"
+ name="homepage_edit"
+ width="220">
+ TODO
+ </line_editor>
+ <check_box
+ follows="left|top"
+ font="SansSerifSmall"
+ label="Show me in Search results"
+ layout="topleft"
+ left="10"
+ name="show_in_search_checkbox"
+ height="16"
+ text_enabled_color="white"
+ top_pad="20"
+ width="240"/>
+ <text
+ follows="left|top"
+ font="SansSerifSmall"
+ font.style="BOLD"
+ height="15"
+ layout="topleft"
+ left="10"
+ name="title_acc_status_text"
+ text_color="white"
+ top_pad="15"
+ value="Account Status:"
+ width="100" />
+ <link
+ type="string"
+ follows="left|top"
+ font="SansSerifSmall"
+ font.style="UNDERLINE"
+ height="15"
+ layout="topleft"
+ left_pad="10"
+ name="my_account_link"
+ top_delta="0"
+ value="Go to Dashboard"
+ width="100"/>
+ <text
+ follows="left|top|right"
+ height="15"
+ layout="topleft"
+ left="10"
+ name="acc_status_text"
+ top_pad="5"
+ value="Resident. No payment info on file."
+ width="255"
+ word_wrap="true" />
+ <text
+ follows="left|top"
+ font="SansSerifSmall"
+ font.style="BOLD"
+ height="15"
+ layout="topleft"
+ left="10"
+ name="title_partner_text"
+ text_color="white"
+ top_pad="15"
+ value="Partner:"
+ width="100" />
+ <link
+ follows="left|top"
+ height="15"
+ font.style="UNDERLINE"
+ layout="topleft"
+ left_pad="10"
+ name="partner_edit_link"
+ top_delta="0"
+ value="Edit"
+ width="100" />
+ <panel
+ follows="left|top|right"
+ height="15"
+ layout="topleft"
+ left="10"
+ name="partner_data_panel"
+ top_pad="10"
+ width="255">
+ <text
+ follows="left|top|right"
+ height="30"
+ layout="topleft"
+ left="0"
+ name="partner_text"
+ top="0"
+ value="[FIRST] [LAST]"
+ width="240"
+ word_wrap="true" />
+ </panel>
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ font="SansSerifSmall"
+ font.style="BOLD"
+ height="15"
+ layout="topleft"
+ left="10"
+ name="title_afk_text"
+ text_color="white"
+ top_pad="15"
+ width="240">
+ Away Timeout:
+ </text>
+ <spinner
+ control_name="AFKTimeout"
+ decimal_digits="0"
+ follows="left|top"
+ height="16"
+ increment="1"
+ initial_value="300"
+ label=""
+ label_width="0"
+ layout="topleft"
+ left="10"
+ max_val="600"
+ min_val="30"
+ name="afk_timeout_spinner"
+ top_pad="5"
+ width="50" />
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="10"
+ layout="topleft"
+ left_pad="10"
+ name="seconds_textbox"
+ top_delta="0"
+ width="128">
+ seconds
+ </text>
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="10"
+ layout="topleft"
+ font.style="BOLD"
+ left="12"
+ mouse_opaque="false"
+ name="text_box3"
+ top_pad="25"
+ width="240">
+ Busy Mode Response:
+ </text>
+ <text_editor
+ control_name="BusyModeResponse2"
+ commit_on_focus_lost = "true"
+ follows="left|top"
+ height="70"
+ layout="topleft"
+ left="12"
+ name="busy_response"
+ top_pad="10"
+ width="240"
+ word_wrap="true">
+ log_in_to_change
+ </text_editor>
+ </panel>
+ </panel>
+ </scroll_container>
+ <panel
+ follows="bottom|left"
+ height="30"
+ left="10"
+ name="profile_me_buttons_panel"
+ top_pad="10"
+ width="240">
+ <button
+ follows="bottom|left"
+ font="SansSerifSmallBold"
+ height="25"
+ label="Save Changes"
+ layout="topleft"
+ left="0"
+ name="save_btn"
+ top="0"
+ width="130" />
+ <button
+ follows="bottom|left"
+ font="SansSerifSmallBold"
+ height="25"
+ label="Cancel"
+ layout="topleft"
+ left_pad="5"
+ name="cancel_btn"
+ top_delta="0"
+ width="130" />
+ </panel>
+</panel>
+
+
+
diff --git a/indra/newview/skins/default/xui/en/panel_friends.xml b/indra/newview/skins/default/xui/en/panel_friends.xml
new file mode 100644
index 0000000000..3a35465df2
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/panel_friends.xml
@@ -0,0 +1,124 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<panel
+ border="true"
+ follows="all"
+ height="347"
+ layout="topleft"
+ name="friends"
+ width="100">
+ <panel.string
+ name="Multiple">
+ Multiple friends...
+ </panel.string>
+ <scroll_list
+ bottom="337"
+ column_padding="0"
+ draw_heading="true"
+ follows="left|top|bottom|right"
+ layout="topleft"
+ left="10"
+ multi_select="true"
+ name="friend_list"
+ right="-100"
+ search_column="1"
+ tool_tip="Hold shift or control while clicking to select multiple friends"
+ top="10">
+ <scroll_list.columns
+ image="ff_online_status_button.tga"
+ name="icon_online_status"
+ tool_tip="Online status"
+ width="20" />
+ <scroll_list.columns
+ dynamic_width="true"
+ label="Name"
+ name="friend_name"
+ tool_tip="Name" />
+ <scroll_list.columns
+ image="ff_visible_online_button.tga"
+ name="icon_visible_online"
+ tool_tip="Friend can see when you&apos;re online"
+ width="20" />
+ <scroll_list.columns
+ image="ff_visible_map_button.tga"
+ name="icon_visible_map"
+ tool_tip="Friend can locate you on the map"
+ width="20" />
+ <scroll_list.columns
+ image="ff_edit_mine_button.tga"
+ name="icon_edit_mine"
+ tool_tip="Friend can edit, delete or take objects"
+ width="20" />
+ <scroll_list.columns
+ image="ff_edit_theirs_button.tga"
+ name="icon_edit_theirs"
+ tool_tip="You can edit this friend&apos;s objects"
+ width="20" />
+ <scroll_list.columns
+ name="friend_last_update_generation"
+ width="0" />
+ </scroll_list>
+ <locate
+ bottom="7"
+ layout="topleft"
+ left="-90" />
+ <button
+ follows="top|right"
+ height="22"
+ label="IM/Call"
+ layout="topleft"
+ left_pad="10"
+ name="im_btn"
+ tool_tip="Open Instant Message session"
+ top_pad="3"
+ width="80" />
+ <button
+ follows="top|right"
+ height="22"
+ label="Profile"
+ layout="topleft"
+ left_delta="0"
+ name="profile_btn"
+ tool_tip="Show picture, groups, and other information"
+ top_pad="3"
+ width="80" />
+ <button
+ follows="top|right"
+ height="22"
+ label="Teleport..."
+ layout="topleft"
+ left_delta="0"
+ name="offer_teleport_btn"
+ tool_tip="Offer this friend a teleport to your current location"
+ top_pad="3"
+ width="80" />
+ <button
+ follows="top|right"
+ height="22"
+ label="Pay..."
+ layout="topleft"
+ left_delta="0"
+ name="pay_btn"
+ tool_tip="Give Linden dollars (L$) to this friend"
+ top_pad="3"
+ width="80" />
+ <button
+ follows="top|right"
+ height="22"
+ label="Remove..."
+ layout="topleft"
+ left_delta="0"
+ name="remove_btn"
+ tool_tip="Remove this person from your friends list"
+ top_pad="3"
+ width="80" />
+ <button
+ follows="top|right"
+ height="22"
+ label="Add..."
+ layout="topleft"
+ left_delta="0"
+ name="add_btn"
+ tool_tip="Offer friendship to a resident"
+ top_pad="13"
+ width="80" />
+</panel>
diff --git a/indra/newview/skins/default/xui/en/panel_group_control_panel.xml b/indra/newview/skins/default/xui/en/panel_group_control_panel.xml
new file mode 100644
index 0000000000..a9363df259
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/panel_group_control_panel.xml
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<panel name="panel_im_control_panel"
+ width="96"
+ height="215"
+ border="false">
+ <avatar_list
+ width="90"
+ column_padding="0"
+ draw_heading="true"
+ draw_stripes="false"
+ follows="left|top|bottom|right"
+ layout="topleft"
+ left="3"
+ name="speakers_list"
+ search_column="1"
+ sort_column="2"
+ top="10"
+ height="150" />
+
+ <button name="group_info_btn"
+ label="Group Info"
+ left_delta="3"
+ width="90"
+ height="20" />
+
+ <button name="call_btn"
+ label="Call"
+ width="90"
+ height="20" />
+
+</panel>
diff --git a/indra/newview/skins/default/xui/en/panel_group_general.xml b/indra/newview/skins/default/xui/en/panel_group_general.xml
new file mode 100644
index 0000000000..03e2d35b9f
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/panel_group_general.xml
@@ -0,0 +1,218 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<panel
+ border="true"
+ follows="all"
+ height="445"
+ label="General"
+ class="panel_group_general"
+ layout="topleft"
+ left="1"
+ name="general_tab"
+ top="500"
+ width="280">
+ <panel.string
+ name="help_text">
+ The General tab contains general information about
+this group, a list of Owners and visible Members,
+general Group Preferences and member options.
+
+Hover your mouse over the options for more help.
+ </panel.string>
+ <panel.string
+ name="group_info_unchanged">
+ General group information has changed.
+ </panel.string>
+ <panel.string
+ name="incomplete_member_data_str">
+ Retrieving member data
+ </panel.string>
+ <panel.string
+ name="group_join_btn">
+ Join (L$[AMOUNT])
+ </panel.string>
+ <!--<button
+ follows="left|top"
+ height="16"
+ label="?"
+ label_selected="?"
+ layout="topleft"
+ left="255"
+ name="help_button"
+ top="8"
+ width="20" /> -->
+ <text_editor
+ type="string"
+ follows="left|top"
+ left="5"
+ height="75"
+ hide_scrollbar="true"
+ layout="topleft"
+ max_length="511"
+ name="charter"
+ top="5"
+ width="260"
+ word_wrap="true">
+ Group Charter
+ </text_editor>
+ <text
+ follows="left|top"
+ type="string"
+ font="SansSerifBig"
+ tool_tip="Owners are shown in bold."
+ height="16"
+ layout="topleft"
+ left="5"
+ name="text_owners_and_visible_members"
+ top_pad="10"
+ width="270">
+ Members
+ </text>
+ <name_list
+ column_padding="0"
+ draw_heading="true"
+ follows="left|top"
+ heading_height="14"
+ height="80"
+ layout="topleft"
+ left_delta="0"
+ name="visible_members"
+ top_pad="0"
+ width="263">
+ <name_list.columns
+ label="Member Name"
+ name="name"
+ relative_width="0.6" />
+ <name_list.columns
+ label="Title"
+ name="title"
+ relative_width="0.4" />
+ </name_list>
+ <text
+ follows="left|top"
+ height="16"
+ type="string"
+ top_pad="10"
+ font="SansSerifBig"
+ layout="topleft"
+ name="text_group_preferences">
+ Group Preferences
+ </text>
+ <text
+ follows="left|top"
+ type="string"
+ height="16"
+ layout="topleft"
+ left_delta="0"
+ name="active_title_label"
+ top_pad="8"
+ width="240">
+ My Active Title
+ </text>
+ <combo_box
+ follows="left|top"
+ height="20"
+ layout="topleft"
+ left_delta="0"
+ name="active_title"
+ tool_tip="Sets the title that appears in your avatar&apos;s name tag when this group is active."
+ top_pad="0"
+ width="240" />
+ <check_box
+ height="16"
+ font="SansSerifSmall"
+ label="Receive notices"
+ layout="topleft"
+ left_delta="0"
+ name="receive_notices"
+ tool_tip="Sets whether you want to receive Notices from this group. Uncheck this box if this group is spamming you."
+ top_pad="5"
+ width="240" />
+ <check_box
+ height="16"
+ label="Show in my profile"
+ layout="topleft"
+ left_delta="0"
+ name="list_groups_in_profile"
+ tool_tip="Sets whether you want to show this group in your Profile"
+ top_pad="5"
+ width="240" />
+ <panel
+ background_visible="true"
+ bevel_style="in"
+ border="true"
+ bg_alpha_color="FloaterUnfocusBorderColor"
+ follows="left|top"
+ height="125"
+ layout="topleft"
+ left_delta="0"
+ name="preferences_container"
+ top_pad="10"
+ width="263">
+ <check_box
+ follows="right|top"
+ height="16"
+ label="Open enrollment"
+ layout="topleft"
+ left_delta="0"
+ name="open_enrollement"
+ tool_tip="Sets whether this group allows new members to join without being invited."
+ top_pad="5"
+ width="90" />
+ <check_box
+ height="16"
+ label="Enrollment fee:"
+ layout="topleft"
+ left_delta="0"
+ name="check_enrollment_fee"
+ tool_tip="Sets whether to require an enrollment fee to join the group."
+ top_pad="5"
+ width="90" />
+ <spinner
+ decimal_digits="0"
+ follows="left|top"
+ halign="left"
+ height="16"
+ increment="1"
+ label_width="20"
+ label="L$"
+ layout="topleft"
+ left="25"
+ max_val="99999"
+ top_pad="5"
+ name="spin_enrollment_fee"
+ tool_tip="New members must pay this fee to join the group when Enrollment Fee is checked."
+ top_delta="-2"
+ width="75" />
+ <check_box
+ height="16"
+ initial_value="true"
+ label="Show in search"
+ layout="topleft"
+ left="4"
+ name="show_in_group_list"
+ tool_tip="Let people see this group in search results."
+ top_pad="4"
+ width="90" />
+ <combo_box
+ height="20"
+ layout="topleft"
+ left_delta="0"
+ name="group_mature_check"
+ tool_tip="Sets whether your group information is considered mature."
+ top_pad="10"
+ width="240">
+ <combo_box.item
+ label="Select Mature -"
+ name="select_mature"
+ value="Select" />
+ <combo_box.item
+ label="Mature Content"
+ name="mature"
+ value="Mature" />
+ <combo_box.item
+ label="PG Content"
+ name="pg"
+ value="Not Mature" />
+ </combo_box>
+ </panel>
+</panel> \ No newline at end of file
diff --git a/indra/newview/skins/default/xui/en/panel_group_info_sidetray.xml b/indra/newview/skins/default/xui/en/panel_group_info_sidetray.xml
new file mode 100644
index 0000000000..2de41a9ee6
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/panel_group_info_sidetray.xml
@@ -0,0 +1,118 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+
+<panel
+ follows="left|top|right|bottom"
+ height="660"
+ label="Group Info"
+ layout="topleft"
+ name="panel_group_info"
+ border="false"
+ width="300">
+ <panel.string
+ name="default_needs_apply_text">
+ There are unapplied changes on the current tab.
+ </panel.string>
+ <panel.string
+ name="want_apply_text">
+ Do you want to apply these changes?
+ </panel.string>
+
+ <button
+ layout="topleft"
+ name="back"
+ right="-9"
+ top="0"
+ width="25"
+ height="25"
+ label=""
+ follows="top|left"
+ image_overlay="BackArrow_Off"
+ tab_stop="false" />
+ <text
+ layout="topleft"
+ top="0"
+ left="10"
+ width="250"
+ height="20"
+ font="SansSerifHugeBold"
+ text_color="white"
+ follows="top|left|right"
+ mouse_opaque="true"
+ name="group_name">(Loading...)</text>
+ <texture_picker
+ follows="left|top"
+ height="113"
+ label=""
+ layout="topleft"
+ left="10"
+ name="insignia"
+ tool_tip="Click to choose a picture"
+ top_pad="15"
+ width="100" />
+ <text
+ type="string"
+ follows="left|top"
+ height="16"
+ length="1"
+ layout="topleft"
+ left_pad="10"
+ name="prepend_founded_by"
+ top_delta="0"
+ width="140">
+ Founded by:
+ </text>
+ <name_box
+ follows="left|top"
+ height="16"
+ initial_value="(retrieving)"
+ layout="topleft"
+ left_delta="0"
+ name="founder_name"
+ top_pad="10"
+ width="140" />
+ <button
+ top="632"
+ height="20"
+ font="SansSerifSmall"
+ label="Apply"
+ label_selected="Apply"
+ name="btn_apply"
+ left="5"
+ width="65" />
+ <button
+ top="632"
+ left="75"
+ height="20"
+ font="SansSerifSmall"
+ label="Refresh"
+ label_selected="Refresh"
+ name="btn_refresh"
+ follows="top|left"
+ width="65" />
+ <button
+ top="632"
+ height="20"
+ font="SansSerifSmall"
+ label="Create"
+ label_selected="Create"
+ name="btn_create"
+ left="5"
+ visible="false"
+ width="65" />
+ <accordion layout="topleft" left="2" width="296" top="135" height="500" follows="all" name="group_accordion">
+ <accordion_tab min_height="445" title="Group General" name="group_general_tab">
+ <panel class="panel_group_general" filename="panel_group_general.xml" name="group_general_tab_panel"/>
+ </accordion_tab>
+ <accordion_tab min_height="380" title="Group Roles" name="group_roles_tab" expanded="False" can_resize="false">
+ <panel class="panel_group_roles" filename="panel_group_roles.xml" name="group_roles_tab_panel"/>
+ </accordion_tab>
+ <accordion_tab min_height="530" title="Group Notices" name="group_notices_tab" expanded="False" can_resize="false">
+ <panel class="panel_group_notices" filename="panel_group_notices.xml" name="group_notices_tab_panel"/>
+ </accordion_tab>
+ <accordion_tab min_height="270" title="Group Land Money" name="group_land_tab" expanded="False" can_resize="false">
+ <panel class="panel_group_land_money" filename="panel_group_land_money.xml" name="group_land_tab_panel"/>
+ </accordion_tab>
+ </accordion>
+
+
+</panel> \ No newline at end of file
diff --git a/indra/newview/skins/default/xui/en/panel_group_invite.xml b/indra/newview/skins/default/xui/en/panel_group_invite.xml
new file mode 100644
index 0000000000..68b30faa1c
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/panel_group_invite.xml
@@ -0,0 +1,106 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<panel
+ height="380"
+ label="Invite a Member"
+ layout="topleft"
+ left="0"
+ name="invite_panel"
+ top="380"
+ width="210">
+ <panel.string
+ name="confirm_invite_owner_str">
+ Are you sure you want to invite new owner(s)? This action is permanent!
+ </panel.string>
+ <panel.string
+ name="loading">
+ (loading...)
+ </panel.string>
+ <panel.string
+ name="already_in_group">
+ Some avatars are already in group and were not invited.
+ </panel.string>
+ <text
+ type="string"
+ length="1"
+ height="54"
+ layout="topleft"
+ left="7"
+ name="help_text"
+ top="24"
+ width="200">
+ You can select multiple residents to
+invite to your group. Click &apos;Open
+Resident Chooser&apos; to start.
+ </text>
+ <button
+ font="SansSerifSmall"
+ height="20"
+ label="Open Resident Chooser"
+ layout="topleft"
+ left_delta="-2"
+ name="add_button"
+ top_delta="44"
+ width="200" />
+ <name_list
+ allow_calling_card_drop="true"
+ column_padding="0"
+ height="174"
+ layout="topleft"
+ left_delta="0"
+ multi_select="true"
+ name="invitee_list"
+ tool_tip="Hold the Ctrl key and click resident names to multi-select."
+ top_pad="4"
+ width="200" />
+ <button
+ font="SansSerifSmall"
+ height="20"
+ label="Remove Selected from List"
+ layout="topleft"
+ left_delta="0"
+ name="remove_button"
+ tool_tip="Removes residents selected above from the invite list."
+ top_pad="4"
+ width="200" />
+ <text
+ type="string"
+ length="1"
+ height="16"
+ layout="topleft"
+ left_delta="4"
+ name="role_text"
+ top_pad="5"
+ width="200">
+ Choose what Role to assign them to:
+ </text>
+ <combo_box
+ height="16"
+ layout="topleft"
+ left_delta="0"
+ name="role_name"
+ tool_tip="Choose from the list of Roles you are allowed to assign members to."
+ top_delta="16"
+ width="196" />
+ <button
+ font="SansSerifSmall"
+ height="20"
+ label="Send Invitations"
+ layout="topleft"
+ left="4"
+ name="ok_button"
+ top="356"
+ width="130" />
+ <button
+ font="SansSerifSmall"
+ height="20"
+ label="Cancel"
+ layout="topleft"
+ left_pad="2"
+ name="cancel_button"
+ top_delta="0"
+ width="70" />
+ <string
+ name="GroupInvitation">
+ Group Invitation
+ </string>
+</panel>
diff --git a/indra/newview/skins/default/xui/en/panel_group_land_money.xml b/indra/newview/skins/default/xui/en/panel_group_land_money.xml
new file mode 100644
index 0000000000..069cf1d7bd
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/panel_group_land_money.xml
@@ -0,0 +1,372 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<panel
+ border="true"
+ follows="all"
+ height="410"
+ label="Land &amp; L$"
+ layout="topleft"
+ left="1"
+ name="land_money_tab"
+ top="490"
+ width="280">
+ <panel.string
+ name="help_text">
+ Parcels owned by the group are listed along with contribution details. A warning appears until the Total Land in Use is less than or equal to the Total Contribution. The Planning, Details, and Sales tabs provide information about the group&apos;s finances.
+ </panel.string>
+ <panel.string
+ name="cant_view_group_land_text">
+ You do not have permission to view group owned land.
+ </panel.string>
+ <panel.string
+ name="cant_view_group_accounting_text">
+ You do not have permission to view the group&apos;s accounting information.
+ </panel.string>
+ <panel.string
+ name="loading_txt">
+ Loading...
+ </panel.string>
+ <panel.string
+ name="land_contrib_error">
+ Unable to set your land contribution.
+ </panel.string>
+ <!--
+ <button
+ follows="left|top"
+ height="16"
+ label="?"
+ layout="topleft"
+ left="250"
+ name="help_button"
+ top="8"
+ width="20" />
+ -->
+ <!-- <text
+ type="string"
+ follows="left|top"
+ font="SansSerifBig"
+ height="16"
+ layout="topleft"
+ left="10"
+ name="group_land_heading"
+ top_pad="10"
+ width="260">
+ Group Owned Land
+ </text> -->
+ <scroll_list
+ draw_heading="true"
+ follows="top"
+ font="SansSerifSmall"
+ heading_height="14"
+ height="100"
+ layout="topleft"
+ left="5"
+ name="group_parcel_list"
+ top_pad="10"
+ width="265">
+ <scroll_list.columns
+ label="Parcel"
+ name="name"
+ width="67" />
+ <scroll_list.columns
+ label="Region"
+ name="location"
+ width="72" />
+ <scroll_list.columns
+ label="Type"
+ name="type"
+ width="60" />
+ <scroll_list.columns
+ label="Area"
+ name="area"
+ width="20" />
+ <scroll_list.columns
+ label=""
+ name="hidden"
+ width="-1" />
+ </scroll_list>
+ <button
+ follows="top"
+ height="20"
+ label="Map"
+ label_selected="Map"
+ layout="topleft"
+ left="150"
+ name="map_button"
+ top_pad="10"
+ width="125"
+ enabled="false" />
+ <text
+ type="string"
+ follows="left|top"
+ halign="right"
+ height="16"
+ layout="topleft"
+ left="5"
+ name="total_contributed_land_label"
+ top_pad="10"
+ width="130">
+ Total Contribution:
+ </text>
+ <text
+ type="string"
+ follows="left|top"
+ height="16"
+ layout="topleft"
+ left_pad="5"
+ name="total_contributed_land_value"
+ top_delta="0"
+ width="120">
+ [AREA] m²
+ </text>
+ <text
+ type="string"
+ follows="left|top"
+ halign="right"
+ height="16"
+ layout="topleft"
+ left="5"
+ name="total_land_in_use_label"
+ top_pad="0"
+ width="130">
+ Total Land In Use:
+ </text>
+ <text
+ type="string"
+ follows="left|top"
+ height="16"
+ layout="topleft"
+ left_pad="5"
+ name="total_land_in_use_value"
+ top_delta="0"
+ width="120">
+ [AREA] m²
+ </text>
+ <text
+ type="string"
+ follows="left|top"
+ halign="right"
+ height="16"
+ layout="topleft"
+ left="5"
+ name="land_available_label"
+ top_pad="0"
+ width="130">
+ Land Available:
+ </text>
+ <text
+ type="string"
+ follows="left|top"
+ height="16"
+ layout="topleft"
+ left_pad="5"
+ name="land_available_value"
+ top_delta="0"
+ width="120">
+ [AREA] m²
+ </text>
+ <text
+ type="string"
+ follows="left|top"
+ halign="right"
+ height="16"
+ layout="topleft"
+ left="5"
+ name="your_contribution_label"
+ top_pad="0"
+ width="130">
+ Your Contribution:
+ </text>
+ <line_editor
+ border_style="line"
+ border_thickness="1"
+ follows="left|top"
+ height="16"
+ layout="topleft"
+ left_pad="5"
+ max_length="10"
+ name="your_contribution_line_editor"
+ top_delta="-2"
+ width="95" />
+ <text
+ type="string"
+ follows="left|top"
+ height="16"
+ layout="topleft"
+ left_pad="5"
+ name="your_contribution_units"
+ top_delta="2">
+ ( m² )
+ </text>
+ <text
+ type="string"
+ follows="left|top"
+ halign="right"
+ height="16"
+ layout="topleft"
+ left="140"
+ name="your_contribution_max_value"
+ top_pad="0"
+ width="95">
+ ([AMOUNT] max)
+ </text>
+ <icon
+ height="16"
+ image_name="smicon_warn.tga"
+ layout="topleft"
+ left="9"
+ name="group_over_limit_icon"
+ top_pad="0"
+ visible="false"
+ width="16" />
+ <text
+ follows="left|top"
+ type="string"
+ word_wrap="true"
+ font="SansSerifSmall"
+ height="40"
+ layout="topleft"
+ left_pad="5"
+ name="group_over_limit_text"
+ text_color="GroupOverTierColor"
+ top_delta="0"
+ width="250">
+ Group members must contribute more land credits to support land in use.
+ </text>
+ <text
+ type="string"
+ follows="left|top"
+ font="SansSerifBig"
+ height="16"
+ layout="topleft"
+ left="10"
+ name="group_money_heading"
+ top_pad="0"
+ width="150">
+ Group L$
+ </text>
+ <tab_container
+ follows="all"
+ height="100"
+ layout="topleft"
+ left="10"
+ name="group_money_tab_container"
+ tab_position="top"
+ top_pad="10"
+ width="265">
+ <panel
+ border="true"
+ follows="left|top|right|bottom"
+ height="180"
+ label="Planning"
+ layout="topleft"
+ left="1"
+ name="group_money_planning_tab"
+ top="5"
+ width="265">
+ <text_editor
+ type="string"
+ bg_readonly_color="0.784314 0.819608 0.8 1"
+ follows="all"
+ font="Monospace"
+ height="172"
+ layout="topleft"
+ left="8"
+ max_length="4096"
+ name="group_money_planning_text"
+ top="5"
+ width="250">
+ Computing...
+ </text_editor>
+ </panel>
+ <panel
+ border="true"
+ follows="left|top|right|bottom"
+ height="180"
+ label="Details"
+ layout="topleft"
+ left_delta="0"
+ name="group_money_details_tab"
+ top_delta="0"
+ width="265">
+ <text_editor
+ type="string"
+ bg_readonly_color="0.784314 0.819608 0.8 1"
+ follows="all"
+ font="Monospace"
+ height="140"
+ layout="topleft"
+ left="8"
+ max_length="4096"
+ name="group_money_details_text"
+ top="7"
+ width="250">
+ Computing...
+ </text_editor>
+ <button
+ height="20"
+ label="&lt; Earlier"
+ label_selected="&lt; Earlier"
+ layout="topleft"
+ left="5"
+ name="earlier_details_button"
+ tool_tip="Go back in time"
+ top_pad="10"
+ width="125" />
+ <button
+ height="20"
+ label="Later &gt;"
+ label_selected="Later &gt;"
+ layout="topleft"
+ left_pad="5"
+ name="later_details_button"
+ tool_tip="Go forward in time"
+ top_delta="0"
+ width="125" />
+ </panel>
+ <panel
+ border="true"
+ follows="left|top|right|bottom"
+ height="180"
+ label="Sales"
+ layout="topleft"
+ left_delta="0"
+ name="group_money_sales_tab"
+ top_delta="-1"
+ width="265">
+ <text_editor
+ type="string"
+ bg_readonly_color="0.784314 0.819608 0.8 1"
+ follows="all"
+ font="Monospace"
+ height="140"
+ layout="topleft"
+ left="8"
+ max_length="4096"
+ name="group_money_sales_text"
+ top="7"
+ width="250">
+ Computing...
+ </text_editor>
+ <button
+ height="20"
+ label="&lt; Earlier"
+ label_selected="&lt; Earlier"
+ layout="topleft"
+ left="5"
+ name="earlier_sales_button"
+ tool_tip="Go back in time"
+ top_pad="10"
+ width="125" />
+ <button
+ height="20"
+ label="Later &gt;"
+ label_selected="Later &gt;"
+ layout="topleft"
+ left_pad="5"
+ name="later_sales_button"
+ tool_tip="Go forward in time"
+ top_delta="0"
+ width="125" />
+ </panel>
+ </tab_container>
+</panel>
diff --git a/indra/newview/skins/default/xui/en/panel_group_notices.xml b/indra/newview/skins/default/xui/en/panel_group_notices.xml
new file mode 100644
index 0000000000..ffc2f279bc
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/panel_group_notices.xml
@@ -0,0 +1,384 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<panel
+ border="true"
+ follows="all"
+ height="485"
+ label="Notices"
+ layout="topleft"
+ left="1"
+ name="notices_tab"
+ top="485"
+ width="280">
+ <panel.string
+ name="help_text">
+ Notices are a quick way to communicate across a
+group by broadcasting a message and delivering
+an optionally attached item. Notices only go to
+group members in Roles granted the ability to
+receive Notices. You can turn off Notices on
+the General tab.
+ </panel.string>
+ <panel.string
+ name="no_notices_text">
+ There are no past notices.
+ </panel.string>
+ <!-- <button
+ follows="left|top"
+ height="16"
+ label="?"
+ label_selected="?"
+ layout="topleft"
+ left="250"
+ name="help_button"
+ top="8"
+ width="20" /> -->
+ <!--<text
+ follows="left|top"
+ type="string"
+ font="SansSerifBig"
+ height="16"
+ layout="topleft"
+ left="10"
+ name="lbl"
+ top_pad="10"
+ width="269">
+ Group Notices Archive
+ </text> -->
+ <text
+ follows="left|top"
+ type="string"
+ word_wrap="true"
+ height="40"
+ layout="topleft"
+ left_delta="10"
+ name="lbl2"
+ top_pad="10"
+ width="270">
+ Notices are kept for 14 days. Notice lists are limited to 200 notices per group on a daily basis.
+ </text>
+ <scroll_list
+ follows="left|top"
+ column_padding="0"
+ draw_heading="true"
+ heading_height="14"
+ height="109"
+ layout="topleft"
+ left_delta="0"
+ name="notice_list"
+ top_pad="0"
+ width="265">
+ <scroll_list.columns
+ label=""
+ name="icon"
+ width="16" />
+ <scroll_list.columns
+ label="Subject"
+ name="subject"
+ width="100" />
+ <scroll_list.columns
+ label="From"
+ name="from"
+ width="83" />
+ <scroll_list.columns
+ label="Date"
+ name="date"
+ width="50" />
+ <scroll_list.columns
+ name="sort"
+ width="-1" />
+ </scroll_list>
+ <text
+ follows="left|top"
+ type="string"
+ layout="topleft"
+ name="notice_list_none_found"
+ visible="false">
+ None found.
+ </text>
+ <button
+ follows="left|top"
+ height="20"
+ font="SansSerifSmall"
+ label="New Notice"
+ label_selected="Create New Notice"
+ layout="topleft"
+ left_delta="0"
+ name="create_new_notice"
+ top_delta="4"
+ width="125" />
+ <button
+ follows="left|top"
+ height="20"
+ font="SansSerifSmall"
+ label="Refresh"
+ label_selected="Refresh List"
+ layout="topleft"
+ left_pad="12"
+ name="refresh_notices"
+ top_delta="0"
+ width="125" />
+ <panel
+ follows="left|top"
+ height="268"
+ label="Create New Notice"
+ layout="topleft"
+ left="0"
+ name="panel_create_new_notice"
+ top_pad="10"
+ width="265">
+ <text
+ follows="left|top"
+ type="string"
+ font="SansSerifBig"
+ height="16"
+ layout="topleft"
+ left="10"
+ mouse_opaque="false"
+ name="lbl"
+ top_pad="0"
+ width="265">
+ Create a Notice
+ </text>
+ <text
+ follows="left|top"
+ type="string"
+ word_wrap="true"
+ height="90"
+ layout="topleft"
+ left_delta="0"
+ name="lbl2"
+ top_pad="4"
+ width="195">
+ You can add a single item to a notice by dragging it from your inventory to this panel. Attached items must be copiable and transferrable, and you can&apos;t send a folder.
+ </text>
+ <text
+ follows="left|top"
+ type="string"
+ halign="left"
+ height="16"
+ layout="topleft"
+ left_delta="0"
+ name="lbl3"
+ top_pad="10"
+ width="60">
+ Subject:
+ </text>
+ <line_editor
+ border_style="line"
+ border_thickness="1"
+ height="16"
+ layout="topleft"
+ left_pad="3"
+ max_length="63"
+ name="create_subject"
+ top_delta="-1"
+ width="200" />
+ <text
+ follows="left|top"
+ type="string"
+ halign="left"
+ height="16"
+ layout="topleft"
+ left="10"
+ name="lbl4"
+ top_pad="10"
+ width="60">
+ Message:
+ </text>
+ <text_editor
+ height="75"
+ hide_scrollbar="true"
+ layout="topleft"
+ left_pad="3"
+ max_length="511"
+ name="create_message"
+ top_delta="0"
+ width="200"
+ word_wrap="true" />
+ <text
+ follows="left|top"
+ type="string"
+ halign="left"
+ height="16"
+ layout="topleft"
+ left="10"
+ name="lbl5"
+ top_pad="10"
+ width="60">
+ Attach:
+ </text>
+ <line_editor
+ enabled="false"
+ height="16"
+ layout="topleft"
+ left_pad="3"
+ max_length="63"
+ mouse_opaque="false"
+ name="create_inventory_name"
+ top_delta="0"
+ width="200" />
+ <icon
+ height="16"
+ layout="topleft"
+ left_delta="0"
+ name="create_inv_icon"
+ top_delta="0"
+ width="16" />
+ <button
+ follows="left|top"
+ height="20"
+ font="SansSerifSmall"
+ label="Remove Attachment"
+ label_selected="Remove Attachment"
+ layout="topleft"
+ left="10"
+ name="remove_attachment"
+ top_pad="10"
+ width="135" />
+ <button
+ follows="left|top"
+ height="20"
+ font="SansSerifSmall"
+ label="Send"
+ label_selected="Send Notice"
+ layout="topleft"
+ left_delta="138"
+ name="send_notice"
+ top_delta="0"
+ width="125" />
+ <panel
+ bevel_style="in"
+ border="true"
+ height="71"
+ layout="topleft"
+ left="200"
+ name="drop_target2"
+ top="20"
+ width="71" />
+ <icon
+ height="59"
+ image_name="icon_groupnoticeinventory.tga"
+ layout="topleft"
+ left_delta="6"
+ mouse_opaque="true"
+ name="drop_icon"
+ top="26"
+ width="59" />
+ <group_drop_target
+ height="466"
+ layout="topleft"
+ left="0"
+ name="drop_target"
+ tool_tip="Drag an inventory item onto the message box to send it with the notice. You must have permission to copy and transfer the object to send it with the notice."
+ top="-198"
+ width="280" />
+ </panel>
+ <panel
+ follows="left|top"
+ height="268"
+ label="View Past Notice"
+ layout="topleft"
+ left="0"
+ name="panel_view_past_notice"
+ top="197"
+ width="265">
+ <text
+ type="string"
+ font="SansSerifBig"
+ height="16"
+ layout="topleft"
+ left="10"
+ mouse_opaque="false"
+ name="lbl"
+ top_pad="0"
+ width="265">
+ Archived Notice
+ </text>
+ <text
+ type="string"
+ height="16"
+ word_wrap="true"
+ layout="topleft"
+ left_delta="0"
+ name="lbl2"
+ top_pad="4"
+ width="265">
+ To send a new notice, click the &apos;Create New Notice&apos; button above.
+ </text>
+ <text
+ type="string"
+ halign="left"
+ height="16"
+ layout="topleft"
+ left_delta="0"
+ name="lbl3"
+ top_pad="24"
+ visible="false"
+ width="60">
+ Subject:
+ </text>
+ <line_editor
+ border_style="line"
+ border_thickness="1"
+ enabled="false"
+ height="16"
+ layout="topleft"
+ left_pad="3"
+ max_length="63"
+ name="view_subject"
+ top_delta="-1"
+ visible="false"
+ width="200" />
+ <text
+ type="string"
+ halign="left"
+ height="16"
+ layout="topleft"
+ left="10"
+ name="lbl4"
+ top_pad="10"
+ visible="false"
+ width="60">
+ Message:
+ </text>
+ <text_editor
+ enabled="false"
+ height="150"
+ hide_scrollbar="true"
+ layout="topleft"
+ left="10"
+ max_length="511"
+ name="view_message"
+ top_delta="-35"
+ width="260"
+ word_wrap="true" />
+ <line_editor
+ enabled="false"
+ height="16"
+ layout="topleft"
+ left_delta="0"
+ max_length="63"
+ mouse_opaque="false"
+ name="view_inventory_name"
+ top_pad="10"
+ width="260" />
+ <icon
+ height="16"
+ layout="topleft"
+ left_delta="0"
+ name="view_inv_icon"
+ top_delta="0"
+ width="16" />
+ <button
+ follows="left|top"
+ height="20"
+ font="SansSerifSmall"
+ label="Open Attachment"
+ label_selected="Open Attachment"
+ layout="topleft"
+ left_delta="0"
+ name="open_attachment"
+ top_pad="10"
+ width="135" />
+ </panel>
+</panel> \ No newline at end of file
diff --git a/indra/newview/skins/default/xui/en/panel_group_notify.xml b/indra/newview/skins/default/xui/en/panel_group_notify.xml
new file mode 100644
index 0000000000..8ebf1b69a7
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/panel_group_notify.xml
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<panel background_visible="true" bevel_style="in" bg_alpha_color="0 0 0 0"
+ height="200" label="instant_message" layout="topleft" left="0"
+ name="panel_group_notify" top="0" width="350">
+ <panel background_visible="true" bevel_style="in" bg_alpha_color="black"
+ height="50" label="header" layout="topleft" left="0" name="header"
+ top="0" width="350">
+ <icon follows="left|top|right|bottom" height="40" width="40" layout="topleft"
+ top="5" left="5" mouse_opaque="true" name="group_icon"/>
+ <text type="string" length="1" follows="left|top|right|bottom"
+ font="SansSerifBigBold" height="20" layout="topleft" left="60" name="title"
+ text_color="GroupNotifyTextColor" top="20" width="275" use_ellipses="true">
+ Sender Name / Group Name
+ </text>
+ </panel>
+ <text_editor type="string" length="1" bg_readonly_color="0 0 0 0"
+ follows="left|top|right|bottom" height="70" hide_scrollbar="true"
+ hide_border="true" layout="topleft" top="55" left="25" name="message"
+ text_color="GroupNotifyTextColor" text_readonly_color="GroupNotifyTextColor" width="300" word_wrap="true">
+ Message
+ Body
+ </text_editor>
+ <icon follows="left|top|right|bottom" height="16" width="16"
+ layout="topleft" top="135" left="25" mouse_opaque="true" name="attachment_icon" />
+ <text font="SansSerif" font.style="UNDERLINE" font_shadow="hard"
+ type="string" length="1" follows="left|top|right|bottom" layout="topleft"
+ left="45" top="135" height="15" width="280" name="attachment"
+ text_color="GroupNotifyTextColor">
+ Attachment
+ </text>
+ <button label="OK" layout="topleft" top="170" left="140" height="20"
+ width="70" name="btn_ok" />
+</panel>
diff --git a/indra/newview/skins/default/xui/en/panel_group_roles.xml b/indra/newview/skins/default/xui/en/panel_group_roles.xml
new file mode 100644
index 0000000000..9ae165cbb9
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/panel_group_roles.xml
@@ -0,0 +1,797 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<panel
+ border="true"
+ height="490"
+ label="Members &amp; Roles"
+ layout="topleft"
+ left="1"
+ name="roles_tab"
+ top="490"
+ width="280">
+ <panel.string
+ name="default_needs_apply_text">
+ There are unapplied changes on the current sub-tab.
+ </panel.string>
+ <panel.string
+ name="want_apply_text">
+ Do you want to apply these changes?
+ </panel.string>
+ <panel.string
+ name="help_text" />
+ <!--
+ <button
+ follows="left|top"
+ height="16"
+ label="?"
+ layout="topleft"
+ left="250"
+ name="help_button"
+ top="8"
+ width="20" />
+ -->
+ <!--<panel
+ follows="left|top"
+ height="80"
+ layout="topleft"
+ left="10"
+ name="members_header"
+ top_pad="10"
+ width="270">
+ <text
+ type="string"
+ font="SansSerifBig"
+ height="16"
+ layout="topleft"
+ left="0"
+ name="static"
+ top="0"
+ width="270">
+ Members &amp; Roles
+ </text>
+ <text
+ type="string"
+ word_wrap="true"
+ height="40"
+ layout="topleft"
+ left_delta="0"
+ name="static2"
+ top_pad="4"
+ width="270">
+ Group Members are assigned Roles with Abilities. These settings can easily be customized, allowing for greater organization and flexibility.
+ </text>
+ </panel>
+ <panel
+ follows="left|top"
+ height="24"
+ layout="topleft"
+ left_delta="0"
+ name="roles_header"
+ top_delta="0"
+ visible="false"
+ width="270">
+ <text
+ type="string"
+ font="SansSerifBig"
+ height="16"
+ layout="topleft"
+ left="0"
+ name="static"
+ top="0"
+ width="270">
+ Roles
+ </text>
+ <text
+ type="string"
+ word_wrap="true"
+ height="40"
+ layout="topleft"
+ left_delta="0"
+ name="role_properties_modifiable"
+ top_pad="4"
+ visible="false"
+ width="270">
+ Select a Role below. You can modify its Name, Description and Member Title.
+ </text>
+ <text
+ type="string"
+ word_wrap="true"
+ height="40"
+ layout="topleft"
+ left_delta="0"
+ name="role_properties_not_modifiable"
+ top_delta="0"
+ width="270">
+ Select a Role below to see its properties, Members and allowed Abilities.
+ </text>
+ <text
+ type="string"
+ word_wrap="true"
+ height="16"
+ layout="topleft"
+ left_delta="0"
+ name="role_actions_modifiable"
+ top_delta="24"
+ visible="false"
+ width="270">
+ You can also assign Abilities to the Role.
+ </text>
+ <text
+ type="string"
+ word_wrap="true"
+ height="16"
+ layout="topleft"
+ left_delta="0"
+ name="role_actions_not_modifiable"
+ top_delta="0"
+ width="270">
+ You may view, but not modify, assigned Abilities.
+ </text>
+ </panel>
+ <panel
+ follows="left|top"
+ height="24"
+ layout="topleft"
+ left_delta="0"
+ name="actions_header"
+ top_delta="0"
+ visible="false"
+ width="270">
+ <text
+ type="string"
+ font="SansSerifBig"
+ height="16"
+ layout="topleft"
+ left="0"
+ name="static"
+ top="0"
+ width="270">
+ Abilities
+ </text>
+ <text
+ type="string"
+ word_wrap="true"
+ height="40"
+ layout="topleft"
+ left_delta="0"
+ name="static2"
+ top_pad="4"
+ width="270">
+ You can view an Ability&apos;s Description and which Roles and Members can execute the Ability.
+ </text>
+ </panel> -->
+ <tab_container
+ follows="left|top"
+ height="180"
+ layout="topleft"
+ left="5"
+ name="roles_tab_container"
+ tab_position="top"
+ top="10"
+ width="265">
+ <panel
+ border="true"
+ height="165"
+ label="Members"
+ layout="topleft"
+ left="1"
+ name="members_sub_tab"
+ tool_tip="Members"
+ top="17"
+ class="panel_group_members_subtab"
+ width="265">
+ <panel.string
+ name="help_text">
+ You can add or remove Roles assigned to Members.
+Select multiple Members by holding the Ctrl key and
+clicking on their names.
+ </panel.string>
+ <search_editor
+ layout="topleft"
+ top="10"
+ left="4"
+ width="255"
+ height="20"
+ follows="left|top|right"
+ max_length="250"
+ label="Filter People"
+ name="filter_input"
+ font="SansSerif"
+ background_image="TextField_Search_Off"
+ text_pad_left="10"
+ text_color="black">
+ <search_button label=""
+ top_pad="4"
+ left_pad="6"
+ />
+ </search_editor>
+ <!--<line_editor
+ border_style="line"
+ border_thickness="1"
+ follows="left|top"
+ height="16"
+ layout="topleft"
+ left="4"
+ max_length="63"
+ name="search_text"
+ top="10"
+ width="90" />
+ <button
+ font="SansSerifSmall"
+ height="20"
+ label="Search"
+ layout="topleft"
+ left_pad="5"
+ name="search_button"
+ top_delta="-2"
+ width="80" />
+ <button
+ enabled="false"
+ font="SansSerifSmall"
+ height="20"
+ label="Show All"
+ layout="topleft"
+ left_pad="0"
+ name="show_all_button"
+ top_delta="0"
+ width="80" /> -->
+ <name_list
+ column_padding="0"
+ draw_heading="true"
+ heading_height="14"
+ height="100"
+ follows="left|top"
+ layout="topleft"
+ left="4"
+ multi_select="true"
+ name="member_list"
+ top_pad="6"
+ width="255">
+ <name_list.columns
+ label="Member"
+ name="name"
+ width="90" />
+ <name_list.columns
+ label="Donations"
+ name="donated"
+ width="95" />
+ <name_list.columns
+ label="Online"
+ name="online"
+ width="80" />
+ </name_list>
+ <button
+ height="20"
+ font="SansSerifSmall"
+ label="Invite"
+ layout="topleft"
+ left_delta="0"
+ name="member_invite"
+ top_pad="6"
+ width="125" />
+ <button
+ height="20"
+ font="SansSerifSmall"
+ label="Eject"
+ layout="topleft"
+ left_pad="5"
+ name="member_eject"
+ top_delta="0"
+ width="125" />
+ <icon
+ height="16"
+ image_name="inv_folder_plain_closed.tga"
+ layout="topleft"
+ name="power_folder_icon"
+ visible="false"
+ width="16" />
+ </panel>
+ <panel
+ border="true"
+ height="164"
+ label="Roles"
+ layout="topleft"
+ left_delta="0"
+ name="roles_sub_tab"
+ class="panel_group_roles_subtab"
+ top="17"
+ width="265">
+ <panel.string
+ name="help_text">
+ Roles have a title and an allowed list of Abilities
+that Members can perform. Members can belong to
+one or more Roles. A group can have up to 10 Roles,
+including the Everyone and Owner Roles.
+ </panel.string>
+ <panel.string
+ name="cant_delete_role">
+ The &apos;Everyone&apos; and &apos;Owners&apos; Roles are special and cannot be deleted.
+ </panel.string>
+ <panel.string
+ name="power_folder_icon">
+ inv_folder_plain_closed.tga
+ </panel.string>
+ <panel.string
+ name="power_all_have_icon">
+ checkbox_enabled_true.tga
+ </panel.string>
+ <panel.string
+ name="power_partial_icon">
+ checkbox_enabled_false.tga
+ </panel.string>
+ <search_editor
+ layout="topleft"
+ top="10"
+ left="4"
+ width="255"
+ height="20"
+ follows="left|top|right"
+ max_length="250"
+ label="Filter Roles"
+ name="filter_input"
+ font="SansSerif"
+ background_image="TextField_Search_Off"
+ text_pad_left="10"
+ text_color="black">
+ <search_button label=""
+ top_pad="4"
+ left_pad="6"
+ />
+ </search_editor>
+ <!--<line_editor
+ border_style="line"
+ border_thickness="1"
+ follows="left|top"
+ height="16"
+ layout="topleft"
+ left="4"
+ max_length="63"
+ name="search_text"
+ top="10"
+ width="90" />
+ <button
+ font="SansSerifSmall"
+ height="20"
+ label="Search"
+ layout="topleft"
+ left_pad="5"
+ name="search_button"
+ top_delta="-2"
+ width="80" />
+ <button
+ enabled="false"
+ font="SansSerifSmall"
+ height="20"
+ label="Show All"
+ layout="topleft"
+ left_pad="0"
+ name="show_all_button"
+ top_delta="0"
+ width="80" /> -->
+ <scroll_list
+ column_padding="0"
+ draw_heading="true"
+ follows="left|top"
+ heading_height="14"
+ height="100"
+ layout="topleft"
+ left="4"
+ name="role_list"
+ top_pad="4"
+ width="255">
+ <scroll_list.columns
+ label="Role"
+ name="name"
+ width="80" />
+ <scroll_list.columns
+ label="Title"
+ name="title"
+ width="90" />
+ <scroll_list.columns
+ label="Members"
+ name="members"
+ width="95" />
+ </scroll_list>
+ <button
+ height="20"
+ font="SansSerifSmall"
+ label="Add Role"
+ layout="topleft"
+ left_delta="0"
+ name="role_create"
+ top_pad="6"
+ width="125" />
+ <button
+ height="20"
+ font="SansSerifSmall"
+ label="Delete Role"
+ layout="topleft"
+ left_pad="5"
+ name="role_delete"
+ top_delta="0"
+ width="125" />
+ </panel>
+ <panel
+ border="true"
+ height="164"
+ label="Abilities"
+ layout="topleft"
+ left_delta="0"
+ name="actions_sub_tab"
+ class="panel_group_actions_subtab"
+ top="17"
+ tool_tip="You can view an Ability&apos;s Description and which Roles and Members can execute the Ability."
+ width="265">
+ <panel.string
+ name="help_text">
+ Abilities allow Members in Roles to do specific
+things in this group. There&apos;s a broad variety of Abilities.
+ </panel.string>
+ <search_editor
+ layout="topleft"
+ top="10"
+ left="4"
+ width="255"
+ height="20"
+ follows="left|top|right"
+ max_length="250"
+ label="Filter Abilities"
+ name="filter_input"
+ font="SansSerif"
+ background_image="TextField_Search_Off"
+ text_pad_left="10"
+ text_color="black">
+ <search_button label=""
+ top_pad="4"
+ left_pad="6"
+ />
+ </search_editor>
+ <!--<line_editor
+ border_style="line"
+ border_thickness="1"
+ follows="left|top"
+ height="16"
+ layout="topleft"
+ left="4"
+ max_length="63"
+ name="search_text"
+ top="10"
+ width="90" />
+ <button
+ font="SansSerifSmall"
+ height="20"
+ label="Search"
+ layout="topleft"
+ left_pad="5"
+ name="search_button"
+ top_delta="-2"
+ width="80" />
+ <button
+ enabled="false"
+ font="SansSerifSmall"
+ height="20"
+ label="Show All"
+ layout="topleft"
+ left_pad="0"
+ name="show_all_button"
+ top_delta="0"
+ width="80" /> -->
+ <scroll_list
+ column_padding="0"
+ draw_stripes="false"
+ follows="left|top"
+ height="100"
+ layout="topleft"
+ left="6"
+ multi_select="true"
+ name="action_list"
+ search_column="1"
+ tool_tip="Select an Ability to view more details."
+ top_pad="6"
+ width="255">
+ <scroll_list.columns
+ label=""
+ name="icon"
+ width="18" />
+ <scroll_list.columns
+ label=""
+ name="action"
+ width="247" />
+ </scroll_list>
+ <icon
+ height="16"
+ image_name="inv_folder_plain_closed.tga"
+ layout="topleft"
+ name="power_folder_icon"
+ visible="false"
+ width="16" />
+ </panel>
+ </tab_container>
+ <panel
+ height="170"
+ layout="topleft"
+ follows="left|top"
+ left="10"
+ name="members_footer"
+ top_pad="10"
+ width="265">
+ <text
+ type="string"
+ font="SansSerif"
+ height="16"
+ layout="topleft"
+ follows="left|top"
+ left="0"
+ name="static"
+ top_pad="0"
+ width="100">
+ Assigned Roles
+ </text>
+ <text
+ type="string"
+ font="SansSerif"
+ height="16"
+ layout="topleft"
+ follows="left|top"
+ left_pad="35"
+ name="static2"
+ top_delta="0"
+ width="100">
+ Allowed Abilities
+ </text>
+ <scroll_list
+ draw_stripes="false"
+ follows="left|top"
+ height="150"
+ layout="topleft"
+ left="0"
+ name="member_assigned_roles"
+ top_pad="5"
+ width="130">
+ <scroll_list.columns
+ label=""
+ name="checkbox"
+ width="18" />
+ <scroll_list.columns
+ label=""
+ name="role"
+ width="107" />
+ </scroll_list>
+ <scroll_list
+ draw_stripes="false"
+ height="150"
+ layout="topleft"
+ follows="left|top"
+ left_pad="5"
+ name="member_allowed_actions"
+ tool_tip="For Details of each Allowed Ability see the Abilities tab."
+ top_delta="0"
+ width="130">
+ <scroll_list.columns
+ label=""
+ name="icon"
+ width="14" />
+ <scroll_list.columns
+ label=""
+ name="action"
+ width="126" />
+ </scroll_list>
+ </panel>
+ <panel
+ height="215"
+ layout="topleft"
+ left_delta="0"
+ name="roles_footer"
+ top_delta="0"
+ visible="false"
+ width="270">
+ <text
+ type="string"
+ font="SansSerif"
+ height="16"
+ layout="topleft"
+ left="0"
+ name="static"
+ top="0"
+ width="100">
+ Name
+ </text>
+ <text
+ type="string"
+ font="SansSerif"
+ height="16"
+ layout="topleft"
+ left_pad="35"
+ name="static2"
+ top_delta="0"
+ width="100">
+ Description
+ </text>
+ <line_editor
+ type="string"
+ border_style="line"
+ border_thickness="1"
+ follows="left|top"
+ height="20"
+ layout="topleft"
+ left="0"
+ max_length="20"
+ name="role_name"
+ top_pad="0"
+ width="130">
+ Employees
+ </line_editor>
+ <text
+ type="string"
+ font="SansSerif"
+ height="16"
+ layout="topleft"
+ left_delta="0"
+ name="static3"
+ top_pad="10"
+ width="100">
+ Title
+ </text>
+ <line_editor
+ type="string"
+ border_style="line"
+ border_thickness="1"
+ follows="left|top"
+ height="20"
+ layout="topleft"
+ left_delta="0"
+ max_length="20"
+ name="role_title"
+ top_pad="0"
+ width="130">
+ (waiting)
+ </line_editor>
+ <text_editor
+ type="string"
+ halign="left"
+ height="48"
+ hide_scrollbar="true"
+ layout="topleft"
+ left="135"
+ max_length="254"
+ name="role_description"
+ top="16"
+ width="130"
+ word_wrap="true">
+ (waiting)
+ </text_editor>
+ <text
+ type="string"
+ font="SansSerif"
+ height="16"
+ layout="topleft"
+ left="0"
+ name="static4"
+ top="85"
+ width="120">
+ Assigned Members
+ </text>
+ <text
+ type="string"
+ font="SansSerif"
+ height="16"
+ layout="topleft"
+ left_pad="15"
+ name="static5"
+ tool_tip="A list of Abilities the currently selected role can perform."
+ top_delta="0"
+ width="100">
+ Allowed Abilities
+ </text>
+ <name_list
+ draw_stripes="false"
+ height="150"
+ layout="topleft"
+ left="0"
+ name="role_assigned_members"
+ top_pad="0"
+ width="130" />
+ <check_box
+ height="16"
+ label="Members are visible"
+ layout="topleft"
+ left_delta="0"
+ name="role_visible_in_list"
+ tool_tip="Sets whether members of this role are visible in the General tab to people outside of the group."
+ top_pad="10"
+ width="130" />
+ <scroll_list
+ draw_stripes="false"
+ height="150"
+ layout="topleft"
+ left="135"
+ name="role_allowed_actions"
+ search_column="2"
+ tool_tip="For Details of each Allowed Ability see the Abilities tab."
+ top="101"
+ width="130">
+ <scroll_list.columns
+ label=""
+ name="icon"
+ width="2" />
+ <scroll_list.columns
+ label=""
+ name="checkbox"
+ width="16" />
+ <scroll_list.columns
+ label=""
+ name="action"
+ width="220" />
+ </scroll_list>
+ </panel>
+ <panel
+ height="215"
+ layout="topleft"
+ left_delta="0"
+ name="actions_footer"
+ top_delta="0"
+ visible="false"
+ width="265">
+ <text
+ type="string"
+ font="SansSerif"
+ height="16"
+ layout="topleft"
+ left="0"
+ name="static"
+ top="0"
+ width="200">
+ Description
+ </text>
+ <text_editor
+ type="string"
+ enabled="false"
+ halign="left"
+ height="48"
+ hide_scrollbar="true"
+ layout="topleft"
+ left_delta="0"
+ max_length="512"
+ name="action_description"
+ top_pad="0"
+ width="265"
+ word_wrap="true">
+ This Ability is &apos;Eject Members from this Group&apos;. Only an Owner can eject another Owner.
+ </text_editor>
+ <text
+ type="string"
+ font="SansSerif"
+ height="16"
+ layout="topleft"
+ left_delta="0"
+ name="static2"
+ top_pad="10"
+ width="125">
+ Roles with Ability
+ </text>
+ <text
+ type="string"
+ font="SansSerif"
+ height="16"
+ layout="topleft"
+ left_pad="10"
+ name="static3"
+ top_delta="0"
+ width="125">
+ Members with Ability
+ </text>
+ <scroll_list
+ height="150"
+ layout="topleft"
+ left="0"
+ name="action_roles"
+ top="90"
+ width="130" />
+ <name_list
+ height="150"
+ layout="topleft"
+ left_pad="5"
+ name="action_members"
+ top_delta="0"
+ width="130" />
+ </panel>
+</panel>
diff --git a/indra/newview/skins/default/xui/en/panel_groups.xml b/indra/newview/skins/default/xui/en/panel_groups.xml
new file mode 100644
index 0000000000..bba399481b
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/panel_groups.xml
@@ -0,0 +1,111 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<panel
+ border="true"
+ follows="all"
+ height="347"
+ layout="topleft"
+ left="280"
+ name="groups"
+ top="24"
+ width="350">
+ <scroll_list
+ bottom="302"
+ follows="left|top|right|bottom"
+ layout="topleft"
+ left="10"
+ name="group list"
+ top="10"
+ width="240">
+ <scroll_list.columns
+ label=""
+ name="name"
+ width="248" />
+ </scroll_list>
+ <text
+ type="string"
+ length="1"
+ follows="left|bottom"
+ height="16"
+ layout="topleft"
+ left_delta="2"
+ mouse_opaque="false"
+ name="groupdesc"
+ top_pad="7"
+ width="248">
+ Your currently active group is displayed in bold.
+ </text>
+ <text
+ type="string"
+ length="1"
+ follows="left|bottom"
+ height="16"
+ layout="topleft"
+ left_delta="0"
+ mouse_opaque="false"
+ name="groupcount"
+ top_pad="1"
+ width="248">
+ You belong to [COUNT] groups (of [MAX] maximum).
+ </text>
+ <locate
+ height="0"
+ layout="topleft"
+ left="-90"
+ top="7"
+ width="1" />
+ <button
+ follows="top|right"
+ height="22"
+ label="IM/Call"
+ layout="topleft"
+ left_delta="0"
+ name="IM"
+ tool_tip="Open Instant Message session"
+ top_pad="3"
+ width="80" />
+ <button
+ follows="top|right"
+ height="22"
+ label="Info"
+ layout="topleft"
+ left_delta="0"
+ name="Info"
+ top_pad="3"
+ width="80" />
+ <button
+ follows="top|right"
+ height="22"
+ label="Activate"
+ layout="topleft"
+ left_delta="0"
+ name="Activate"
+ top_pad="3"
+ width="80" />
+ <button
+ follows="top|right"
+ height="22"
+ label="Leave"
+ layout="topleft"
+ left_delta="0"
+ name="Leave"
+ top_pad="3"
+ width="80" />
+ <button
+ follows="top|right"
+ height="22"
+ label="Create..."
+ layout="topleft"
+ left_delta="0"
+ name="Create"
+ top_pad="13"
+ width="80" />
+ <button
+ follows="top|right"
+ height="22"
+ label="Search..."
+ layout="topleft"
+ left_delta="0"
+ name="Search..."
+ top_pad="3"
+ width="80" />
+</panel>
diff --git a/indra/newview/skins/default/xui/en/panel_hud.xml b/indra/newview/skins/default/xui/en/panel_hud.xml
new file mode 100644
index 0000000000..3e9614a9b7
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/panel_hud.xml
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<panel
+ follows="left|right|top|bottom"
+ height="728"
+ layout="topleft"
+ left="0"
+ mouse_opaque="false"
+ name="hud"
+ top="778"
+ width="1024" />
diff --git a/indra/newview/skins/default/xui/en/panel_im_control_panel.xml b/indra/newview/skins/default/xui/en/panel_im_control_panel.xml
new file mode 100644
index 0000000000..7dc94d1141
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/panel_im_control_panel.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<panel name="panel_im_control_panel"
+ width="96"
+ height="215"
+ border="false">
+
+ <avatar_icon name="avatar_icon"
+ width="96"
+ height="96" />
+
+ <button name="view_profile_btn"
+ label="View Profile"
+ left_delta="3"
+ width="90"
+ height="20" />
+
+ <button name="add_friend_btn"
+ label="Add Friend"
+ width="90"
+ height="20" />
+
+ <button name="call_btn"
+ label="Call"
+ width="90"
+ height="20" />
+
+ <button name="share_btn"
+ label="Share"
+ width="90"
+ height="20" />
+
+</panel>
diff --git a/indra/newview/skins/default/xui/en/panel_instant_message.xml b/indra/newview/skins/default/xui/en/panel_instant_message.xml
new file mode 100644
index 0000000000..169fde7b47
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/panel_instant_message.xml
@@ -0,0 +1,80 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<panel
+ background_visible="true"
+ bevel_style="in"
+ bg_alpha_color="0.3 0.3 0.3 0"
+ height="140"
+ label="im_panel"
+ layout="topleft"
+ left="0"
+ name="im_panel"
+ top="0"
+ width="350">
+ <panel
+ background_visible="true"
+ bevel_style="in"
+ bg_alpha_color="black"
+ follows="top"
+ height="30"
+ label="im_header"
+ layout="topleft"
+ left="5"
+ name="im_header"
+ top="5"
+ width="340">
+ <avatar_icon
+ follows="right"
+ height="20"
+ image_name="icon_avatar_online.tga"
+ layout="topleft"
+ left="5"
+ mouse_opaque="true"
+ name="avatar"
+ top="5"
+ width="20" />
+ <text
+ follows="left|right"
+ font="SansSerifBigBold"
+ height="20"
+ layout="topleft"
+ left_pad="10"
+ name="user_name"
+ text_color="white"
+ top="5"
+ value="Darth Vader"
+ width="250" />
+ <text
+ follows="right"
+ font="SansSerifBig"
+ height="20"
+ layout="topleft"
+ left_pad="10"
+ name="time_box"
+ text_color="white"
+ top="5"
+ value="23:30"
+ width="50" />
+ </panel>
+ <text
+ follows="left|bottom|right"
+ height="60"
+ layout="topleft"
+ left="10"
+ name="message"
+ text_color="white"
+ top="40"
+ use_ellipses="true"
+ value="MESSAGE"
+ width="330"
+ word_wrap="true" />
+ <button
+ follows="bottom"
+ font="SansSerifBigBold"
+ height="25"
+ label="reply"
+ layout="topleft"
+ left="120"
+ name="reply"
+ top="110"
+ width="110" />
+</panel>
diff --git a/indra/newview/skins/default/xui/en/panel_landmarks.xml b/indra/newview/skins/default/xui/en/panel_landmarks.xml
new file mode 100644
index 0000000000..9ee80a37d7
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/panel_landmarks.xml
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<panel
+ name="Landmarks"
+ bottom="0"
+ height="326"
+ left="0"
+ width="380"
+ border="true"
+ background_visible="true"
+ bg_alpha_color="DkGray2"
+ follows="left|top|right|bottom">
+ <inventory_panel
+ allow_multi_select="true"
+ border="true"
+ bottom="0"
+ follows="left|top|right|bottom"
+ height="326"
+ left="0"
+ mouse_opaque="true"
+ name="landmarks_list"
+ width="380"/>
+ <button
+ bottom="0"
+ halign="center"
+ height="16"
+ label=">"
+ enabled="false"
+ mouse_opaque="false"
+ name="selector"
+ width="20"
+ left="0"
+ follows="right|bottom"
+ tool_tip="View landmark properties"/>
+</panel>
diff --git a/indra/newview/skins/default/xui/en/panel_login.xml b/indra/newview/skins/default/xui/en/panel_login.xml
new file mode 100644
index 0000000000..794b69d7ed
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/panel_login.xml
@@ -0,0 +1,225 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<panel
+ follows="left|top|right|bottom"
+ height="600"
+ layout="topleft"
+ left="0"
+ name="panel_login"
+ top="600"
+ width="800">
+ <panel.string
+ name="create_account_url">
+ http://secondlife.com/registration/
+ </panel.string>
+ <panel.string
+ name="real_url">
+ http://secondlife.com/app/login/
+ </panel.string>
+ <panel.string
+ name="forgot_password_url">
+ http://secondlife.com/account/request.php
+ </panel.string>
+ <web_browser
+ border_visible="false"
+ bottom="600"
+ follows="top|left|bottom|right"
+ layout="topleft"
+ left="0"
+ name="login_html"
+ hide_loading="true"
+ right="-1"
+ start_url="data:text/html,%3Chtml%3E%3Chead%3E%3C/head%3E%3Cbody bgcolor=%22#000000%22 text=%22ffffff%22%3E%3Ch1%3E%3Ctt%3Eloading...%3C/tt%3E%3C/h1%3E %3C/body%3E %3C/html%3E"
+ top="1" />
+ <text
+ type="string"
+ length="1"
+ follows="left|bottom"
+ font="SansSerif"
+ height="16"
+ layout="topleft"
+ left="32"
+ name="first_name_text"
+ top="530"
+ width="120">
+ First Name:
+ </text>
+ <line_editor
+ border_style="line"
+ border_thickness="1"
+ follows="left|bottom"
+ font="SansSerif"
+ handle_edit_keys_directly="true"
+ height="20"
+ layout="topleft"
+ left_delta="0"
+ max_length="31"
+ name="first_name_edit"
+ select_on_focus="true"
+ top_pad="4"
+ width="120" />
+ <text
+ type="string"
+ length="1"
+ follows="left|bottom"
+ font="SansSerif"
+ height="16"
+ layout="topleft"
+ left="164"
+ name="last_name_text"
+ top="530"
+ width="120">
+ Last Name:
+ </text>
+ <line_editor
+ border_style="line"
+ border_thickness="1"
+ follows="left|bottom"
+ font="SansSerif"
+ handle_edit_keys_directly="true"
+ height="20"
+ layout="topleft"
+ left_delta="0"
+ max_length="31"
+ name="last_name_edit"
+ select_on_focus="true"
+ top_pad="4"
+ width="120" />
+ <text
+ type="string"
+ length="1"
+ follows="left|bottom"
+ font="SansSerif"
+ height="16"
+ layout="topleft"
+ left="296"
+ name="password_text"
+ top="530"
+ width="120">
+ Password:
+ </text>
+ <line_editor
+ border_style="line"
+ border_thickness="1"
+ follows="left|bottom"
+ font="SansSerif"
+ handle_edit_keys_directly="true"
+ height="20"
+ layout="topleft"
+ left_delta="0"
+ max_length="16"
+ name="password_edit"
+ select_on_focus="true"
+ top_pad="4"
+ width="120" />
+ <text
+ type="string"
+ length="1"
+ follows="left|bottom"
+ font="SansSerif"
+ height="16"
+ layout="topleft"
+ left="32"
+ name="start_location_text"
+ top="576"
+ width="95">
+ Start Location:
+ </text>
+ <combo_box
+ allow_text_entry="true"
+ control_name="LoginLocation"
+ follows="left|bottom"
+ height="18"
+ layout="topleft"
+ left_pad="2"
+ max_chars="128"
+ name="start_location_combo"
+ top_delta="-2"
+ width="155">
+ <combo_box.item
+ label="My Last Location"
+ name="MyLastLocation"
+ value="last" />
+ <combo_box.item
+ label="My Home"
+ name="MyHome"
+ value="home" />
+ <combo_box.item
+ label="&lt;Type region name&gt;"
+ name="Typeregionname"
+ value="" />
+ </combo_box>
+ <check_box
+ control_name="RememberPassword"
+ follows="left|bottom"
+ height="16"
+ label="Remember password"
+ layout="topleft"
+ left_pad="10"
+ name="remember_check"
+ top_delta="3"
+ width="138" />
+ <button
+ follows="left|bottom"
+ height="24"
+ label="Log In"
+ label_selected="Log In"
+ layout="topleft"
+ left="435"
+ name="connect_btn"
+ top="548"
+ width="120" />
+ <combo_box
+ allow_text_entry="true"
+ follows="left|bottom"
+ height="18"
+ layout="topleft"
+ left_pad="15"
+ name="server_combo"
+ top_delta="2"
+ width="120" />
+ <text
+ type="string"
+ length="1"
+ follows="right|bottom"
+ halign="right"
+ height="16"
+ hover="true"
+ hover_color="0.2 0.45 0.72 1"
+ layout="topleft"
+ left="-210"
+ name="create_new_account_text"
+ top="539"
+ width="200">
+ Sign up for account
+ </text>
+ <text
+ type="string"
+ length="1"
+ follows="right|bottom"
+ halign="right"
+ height="16"
+ hover="true"
+ hover_color="0.2 0.45 0.72 1"
+ layout="topleft"
+ left_delta="0"
+ name="forgot_password_text"
+ top_pad="4"
+ width="200">
+ Forgot your name or password?
+ </text>
+ <text
+ type="string"
+ length="1"
+ follows="right|bottom"
+ halign="right"
+ height="16"
+ hover="true"
+ hover_color="0.2 0.45 0.72 1"
+ layout="topleft"
+ left="-310"
+ name="channel_text"
+ top="579"
+ width="300">
+ [VERSION]
+ </text>
+</panel>
diff --git a/indra/newview/skins/default/xui/en/panel_navigation_bar.xml b/indra/newview/skins/default/xui/en/panel_navigation_bar.xml
new file mode 100644
index 0000000000..dee911a45d
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/panel_navigation_bar.xml
@@ -0,0 +1,138 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<panel
+ background_opaque="true"
+ background_visible="true"
+ bg_opaque_color="0.25 0.25 0.25 1"
+ follows="left|top|right"
+ height="60"
+ layout="topleft"
+ name="navigation_bar"
+ width="600">
+ <panel
+ background_visible="false"
+ follows="left|top|right"
+ height="60"
+ layout="topleft"
+ name="navigation_panel"
+ width="600">
+ <button
+ follows="left|top"
+ font="SansSerifSmall"
+ height="23"
+ image_disabled="PushButton_Disabled"
+ image_disabled_selected="PushButton_Disabled"
+ image_overlay="Arrow_Left_Off"
+ image_selected="PushButton_Selected"
+ image_unselected="PushButton_Off"
+ hover_glow_amount="0.15"
+ layout="topleft"
+ left="10"
+ name="back_btn"
+ picture_style="true"
+ tool_tip="Go back to previous location"
+ top="3"
+ width="31" />
+
+ <button
+ follows="left|top"
+ font="SansSerifSmall"
+ height="23"
+ image_disabled="PushButton_Disabled"
+ image_disabled_selected="PushButton_Disabled"
+ image_overlay="Arrow_Right_Off"
+ image_selected="PushButton_Selected"
+ image_unselected="PushButton_Off"
+ hover_glow_amount="0.15"
+ layout="topleft"
+ left_pad="0"
+ name="forward_btn"
+ picture_style="true"
+ tool_tip="Go forward one location"
+ top_delta="0"
+ width="31" />
+ <button
+ follows="left|top"
+ font="SansSerifSmall"
+ height="23"
+ image_disabled="PushButton_Disabled"
+ image_disabled_selected="PushButton_Disabled"
+ image_overlay="Home_Off"
+ image_selected="PushButton_Selected"
+ image_unselected="PushButton_Off"
+ hover_glow_amount="0.15"
+ layout="topleft"
+ left_pad="7"
+ name="home_btn"
+ picture_style="true"
+ tool_tip="Teleport to your home location"
+ top_delta="0"
+ width="32" />
+ <location_input
+ follows="left|right|top"
+ halign="right"
+ height="22"
+ label="Location"
+ layout="topleft"
+ left_pad="7"
+ max_chars="254"
+ mouse_opaque="false"
+ name="location_combo"
+ top_delta="0"
+ width="266">
+ <!-- *TODO: Delete. Let the location_input use the correct art sizes.
+ <location_input.add_landmark_button
+ height="18"
+ name="location_combo_add"
+ width="20" />
+ <location_input.info_button
+ height="18"
+ name="location_combo_info"
+ width="20" />
+ -->
+ </location_input>
+
+ <!-- <button -->
+ <!-- follows="right|top" -->
+ <!-- height="20" -->
+ <!-- image_disabled="TextField_Search_Off" -->
+ <!-- image_disabled_selected="TextField_Search_Off" -->
+ <!-- image_hover_selected="TextField_Search_Off" -->
+ <!-- image_hover_unselected="TextField_Search_Off" -->
+ <!-- image_selected="TextField_Search_Off" -->
+ <!-- image_unselected="TextField_Search_Off" -->
+ <!-- layout="topleft" -->
+ <!-- left_pad="5" -->
+ <!-- mouse_opaque="false" -->
+ <!-- name="search_bg" -->
+ <!-- picture_style="true" -->
+ <!-- top_delta="0" -->
+ <!-- width="168" /> -->
+
+ <search_editor
+ bevel_style="none"
+ border_style="line"
+ border.border_thickness="0"
+ commit_on_focus_lost="false"
+ follows="right|top"
+ halign="right"
+ height="22"
+ label="Search"
+ layout="topleft"
+ left_pad="7"
+ mouse_opaque="false"
+ name="search_input"
+ tool_tip="Search"
+ top_delta="0"
+ width="200" />
+ </panel>
+
+ <favorites_bar
+ follows="left|right|top"
+ height="25"
+ layout="topleft"
+ left="5"
+ name="favorite"
+ chevron_button_tool_tip="Show more of My Favorites"
+ top="32"
+ width="590" />
+</panel>
diff --git a/indra/newview/skins/default/xui/en/panel_nearby_chat.xml b/indra/newview/skins/default/xui/en/panel_nearby_chat.xml
new file mode 100644
index 0000000000..50a78e1c71
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/panel_nearby_chat.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<!-- All our XML is utf-8 encoded. -->
+
+<panel
+ name="nearby_chat" visible="true" width="250" height="480" background_opaque="false"
+ background_visible="true" bevel_style="in" follows="left|top" bg_alpha_color="0.3 0.3 0.3 1.0">
+ <panel bottom="380" width="250" height="30" background_visible="true" background_opaque="false" bg_alpha_color="0.0 0.0 0.0 1.0" name="chat_caption">
+ <text
+ width="140" left="25" height="20" follows="left|right|top"
+ font="SansSerifBigBold" text_color="white" word_wrap="true"
+ mouse_opaque="true" name="sender_name" >NEARBY CHAT </text>
+ <icon top="25" left="180"
+ width="20" height="20" follows="top|right"
+ color="1 1 1 1" enabled="true" image_name="icn_voice-groupfocus.tga"
+ mouse_opaque="true" name="nearby_speakers_btn"/>
+ <icon top="25" left="205"
+ width="20" height="20" follows="top|right"
+ color="1 1 1 1" enabled="true" image_name="inv_item_landmark_visited.tga"
+ mouse_opaque="true" name="tearoff_btn"/>
+ <icon top="22" left="230"
+ width="15" height="15" follows="top|right"
+ color="1 1 1 1" enabled="true" image_name="closebox.tga"
+ name="close_btn"/>
+ </panel>
+ <chat_history_view bottom="0" width="250" height="320" follows="left|right|top|bottom" name="chat_scroll" />
+</panel>
+
diff --git a/indra/newview/skins/default/xui/en/panel_nearby_chat_bar.xml b/indra/newview/skins/default/xui/en/panel_nearby_chat_bar.xml
new file mode 100644
index 0000000000..8b19f9a515
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/panel_nearby_chat_bar.xml
@@ -0,0 +1,51 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<panel
+ default_tab_group="1"
+ follows="left|bottom|right"
+ height="25"
+ layout="topleft"
+ left="0"
+ name="chat_bar"
+ top="24"
+ width="500">
+ <line_editor
+ border_style="line"
+ border_thickness="1"
+ follows="left|right"
+ height="20"
+ label="Click here to chat."
+ layout="topleft"
+ left_delta="7"
+ left="0"
+ name="chat_box"
+ tool_tip="Press Enter to say, Ctrl-Enter to shout."
+ top="3"
+ width="250" />
+ <button
+ follows="right"
+ width="45"
+ top="3"
+ layout="topleft"
+ left_pad="5"
+ label="Log"
+ height="20">
+ <button.commit_callback function="Floater.Toggle" parameter="nearby_chat"/>
+ </button>
+ <chiclet_talk
+ follows="right"
+ height="20"
+ layout="topleft"
+ left_pad="5"
+ name="talk"
+ top="3"
+ width="100" />
+ <gesture_combo_box
+ follows="right"
+ height="20"
+ label="Gestures"
+ layout="topleft"
+ name="Gesture"
+ left_pad="5"
+ top="3"
+ width="90" />
+</panel>
diff --git a/indra/newview/skins/default/xui/en/panel_notes.xml b/indra/newview/skins/default/xui/en/panel_notes.xml
new file mode 100644
index 0000000000..12badfccf0
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/panel_notes.xml
@@ -0,0 +1,144 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<panel
+ bevel_style="in"
+ follows="left|top|right|bottom"
+ height="420"
+ label="Notes &amp; Privacy"
+ layout="topleft"
+ left="0"
+ name="panel_notes"
+ top="0"
+ width="285">
+ <layout_stack
+ name="layout"
+ orientation="vertical"
+ follows="all"
+ layout="topleft"
+ left="0"
+ top="0"
+ height="420"
+ width="285"
+ border_size="0">
+ <panel
+ name="notes_stack"
+ follows="all"
+ layout="topleft"
+ top="0"
+ left="0"
+ height="390"
+ width="285">
+ <scroll_container
+ color="DkGray2"
+ follows="left|top|right|bottom"
+ height="390"
+ layout="topleft"
+ left="0"
+ name="profile_scroll"
+ opaque="true"
+ top="0"
+ width="285">
+ <panel
+ height="350"
+ layout="topleft"
+ name="profile_scroll_panel"
+ top="0"
+ left="0"
+ width="240">
+ <text
+ follows="left|top"
+ font="SansSerifBold"
+ height="16"
+ layout="topleft"
+ left="10"
+ name="status_message"
+ text_color="white"
+ top="0"
+ value="My private notes:"
+ width="230" />
+ <text_editor
+ follows="left|top"
+ height="200"
+ hide_scrollbar="true"
+ layout="topleft"
+ left="10"
+ max_length="1000"
+ name="notes_edit"
+ text_color="black"
+ top_pad="10"
+ width="235"
+ word_wrap="true" />
+ <text
+ follows="left|top"
+ font="SansSerifBold"
+ height="16"
+ layout="topleft"
+ left="10"
+ name="status_message2"
+ text_color="white"
+ top_pad="10"
+ value="Let this person:"
+ width="225" />
+ <check_box
+ enabled="false"
+ height="20"
+ label="See my online status"
+ layout="topleft"
+ left="20"
+ name="status_check"
+ top_pad="0"
+ width="230" />
+ <check_box
+ enabled="false"
+ height="20"
+ label="See me on the map"
+ layout="topleft"
+ left="20"
+ name="map_check"
+ top_pad="0"
+ width="230" />
+ <check_box
+ enabled="false"
+ height="20"
+ label="Edit, delete or take my objects"
+ layout="topleft"
+ left="20"
+ name="objects_check"
+ top_pad="0"
+ width="230" />
+ </panel>
+ </scroll_container>
+ </panel>
+ <panel
+ follows="bottom"
+ height="30"
+ layout="topleft"
+ left="10"
+ name="notes_buttons_panel"
+ top_pad="5"
+ width="280"
+ auto_resize="false">
+ <button
+ enabled="false"
+ follows="bottom|left"
+ font="SansSerifSmallBold"
+ height="25"
+ label="Teleport"
+ layout="topleft"
+ left="0"
+ name="teleport_btn"
+ top="0"
+ width="75" />
+ <button
+ enabled="false"
+ follows="bottom|left"
+ font="SansSerifSmallBold"
+ height="25"
+ label="Map"
+ layout="topleft"
+ name="show_on_map_btn"
+ top="0"
+ left_pad="5"
+ width="85" />
+ </panel>
+ </layout_stack>
+</panel>
diff --git a/indra/newview/skins/default/xui/en/panel_notifications_channel.xml b/indra/newview/skins/default/xui/en/panel_notifications_channel.xml
new file mode 100644
index 0000000000..c67ae41677
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/panel_notifications_channel.xml
@@ -0,0 +1,77 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<panel
+ height="100"
+ layout="topleft"
+ name="notifications_panel"
+ width="100">
+ <layout_stack
+ follows="left|right|top|bottom"
+ height="78"
+ layout="topleft"
+ left="0"
+ name="stack1"
+ orientation="horizontal"
+ top="20"
+ width="100">
+ <scroll_list
+ draw_heading="true"
+ follows="left|right|top|bottom"
+ height="78"
+ layout="topleft"
+ left="0"
+ name="notifications_list"
+ sort_ascending="false"
+ sort_column="2"
+ top="-78"
+ user_resize="true"
+ width="100">
+ <scroll_list.columns
+ label="Name"
+ name="name"
+ width="100" />
+ <scroll_list.columns
+ label="Content"
+ name="content"
+ width="150" />
+ <scroll_list.columns
+ label="Date"
+ name="date"
+ width="150" />
+ </scroll_list>
+ <scroll_list
+ draw_heading="true"
+ follows="left|right|top|bottom"
+ height="78"
+ layout="topleft"
+ left="0"
+ name="notification_rejects_list"
+ sort_ascending="false"
+ sort_column="2"
+ top="-78"
+ user_resize="true"
+ width="100">
+ <scroll_list.columns
+ label="Name"
+ name="name"
+ width="100" />
+ <scroll_list.columns
+ label="Content"
+ name="content"
+ width="150" />
+ <scroll_list.columns
+ label="Date"
+ name="date"
+ width="150" />
+ </scroll_list>
+ </layout_stack>
+ <button
+ follows="left|right|top"
+ height="20"
+ is_toggle="true"
+ layout="topleft"
+ left_delta="0"
+ name="header"
+ picture_style="true"
+ top_delta="-20"
+ width="100" />
+</panel>
diff --git a/indra/newview/skins/default/xui/en/panel_people.xml b/indra/newview/skins/default/xui/en/panel_people.xml
new file mode 100644
index 0000000000..22823ea98b
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/panel_people.xml
@@ -0,0 +1,524 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<panel
+ background_visible="true"
+ follows="all"
+ height="400"
+ label="People"
+ layout="topleft"
+ min_height="350"
+ min_width="240"
+ name="people_panel"
+ width="305">
+ <string
+ name="no_people"
+ value="No people" />
+ <string
+ name="no_one_near"
+ value="No-one near" />
+ <string
+ name="no_friends_online"
+ value="No friends online" />
+ <string
+ name="no_friends"
+ value="No friends" />
+ <string
+ name="no_groups"
+ value="No groups" />
+ <string
+ name="people_filter_label"
+ value="Filter People" />
+ <string
+ name="groups_filter_label"
+ value="Filter Groups" />
+ <filter_editor
+ background_image="TextField_Search_Off"
+ follows="left|top|right"
+ font="SansSerif"
+ height="23"
+ layout="topleft"
+ left="15"
+ max_length="270"
+ name="filter_input"
+ text_color="black"
+ text_pad_left="26"
+ top="3"
+ width="256" />
+ <button
+ follows="left|top|right"
+ height="13"
+ image_selected="Search"
+ image_unselected="Search"
+ layout="topleft"
+ left="20"
+ name="people_search"
+ picture_style="true"
+ scale_image="false"
+ top="8"
+ width="13" />
+ <tab_container
+ follows="left|top|right|bottom"
+ height="326"
+ layout="topleft"
+ left="9"
+ name="tabs"
+ tab_position="top"
+ top_pad="15"
+ width="285">
+ <panel
+ bevel_style="none"
+ follows="left|top|right|bottom"
+ height="390"
+ label="Nearby"
+ layout="topleft"
+ name="nearby_panel"
+ width="285">
+ <avatar_list
+ follows="left|top|right|bottom"
+ height="357"
+ layout="topleft"
+ left="0"
+ name="avatar_list"
+ top="2"
+ volume_column_width="20"
+ width="285" />
+ <panel
+ background_visible="true"
+ bevel_style="none"
+ bottom="390"
+ follows="left|right|bottom"
+ height="30"
+ label="bottom_panel"
+ layout="topleft"
+ left="0"
+ name="bottom_panel"
+ width="285">
+ <button
+ follows="bottom|left"
+ font="SansSerifBigBold"
+ height="18"
+ image_selected="OptionsMenu_Press"
+ image_unselected="OptionsMenu_Off"
+ layout="topleft"
+ left="20"
+ name="nearby_view_sort_btn"
+ picture_style="true"
+ tool_tip="Change sort and view of Residents list"
+ top="7"
+ width="18" />
+ </panel>
+ </panel>
+ <panel
+ background_visible="true"
+ bevel_style="none"
+ follows="left|top|right|bottom"
+ height="390"
+ label="Friends"
+ layout="topleft"
+ name="friends_panel"
+ width="285">
+ <accordion
+ follows="left|top|right|bottom"
+ height="357"
+ layout="topleft"
+ left="0"
+ name="friends_accordion"
+ top="2"
+ width="285">
+ <accordion_tab
+ can_resize="false"
+ layout="topleft"
+ min_height="100"
+ name="tab_online"
+ title="Online">
+ <panel
+ follows="all"
+ height="150"
+ layout="topleft"
+ left="0"
+ name="tab_online_panel"
+ top="100"
+ width="285">
+ <avatar_list
+ draw_heading="false"
+ follows="all"
+ height="145"
+ layout="topleft"
+ left="0"
+ name="avatars_online"
+ top="0"
+ width="285" />
+ </panel>
+ </accordion_tab>
+ <accordion_tab
+ can_resize="false"
+ layout="topleft"
+ min_height="100"
+ name="tab_all"
+ title="All">
+ <panel
+ follows="all"
+ height="260"
+ layout="topleft"
+ left="0"
+ name="tab_all_panel"
+ top="100"
+ width="285">
+ <avatar_list
+ draw_heading="false"
+ follows="all"
+ height="255"
+ layout="topleft"
+ left="0"
+ name="avatars_all"
+ top="0"
+ width="285" />
+ </panel>
+ </accordion_tab>
+ </accordion>
+ <panel
+ background_visible="true"
+ bevel_style="none"
+ bottom="390"
+ follows="left|right|bottom"
+ height="30"
+ label="bottom_panel"
+ layout="topleft"
+ left="0"
+ name="bottom_panel"
+ width="285">
+ <button
+ follows="bottom|left"
+ font="SansSerifBigBold"
+ height="18"
+ image_selected="OptionsMenu_Press"
+ image_unselected="OptionsMenu_Off"
+ layout="topleft"
+ left="20"
+ name="friends_viewsort_btn"
+ picture_style="true"
+ tool_tip="Change sort and view of Friends list"
+ top="7"
+ width="18" />
+ <button
+ follows="bottom|left"
+ font="SansSerifBigBold"
+ height="18"
+ image_selected="AddItem_Press"
+ image_unselected="AddItem_Off"
+ layout="topleft"
+ left_pad="5"
+ name="add_btn"
+ picture_style="true"
+ tool_tip="Offer friendship to a resident"
+ top_delta="0"
+ width="18" />
+ <button
+ follows="bottom|left"
+ font="SansSerifBigBold"
+ height="18"
+ image_selected="TrashItem_Press"
+ image_unselected="TrashItem_Off"
+ layout="topleft"
+ left_pad="180"
+ name="del_btn"
+ picture_style="true"
+ tool_tip="Remove selected person from your Friends list"
+ top_delta="0"
+ width="18" />
+ </panel>
+ </panel>
+ <panel
+ background_visible="true"
+ bevel_style="none"
+ follows="left|top|right|bottom"
+ height="390"
+ label="Groups"
+ layout="topleft"
+ name="groups_panel"
+ width="285">
+ <group_list
+ follows="left|top|right|bottom"
+ height="357"
+ layout="topleft"
+ left="0"
+ name="group_list"
+ top="2"
+ width="285" />
+ <panel
+ background_visible="true"
+ bevel_style="none"
+ bottom="390"
+ follows="left|right|bottom"
+ height="30"
+ label="bottom_panel"
+ layout="topleft"
+ left="0"
+ name="bottom_panel"
+ width="285">
+ <button
+ enabled="false"
+ follows="bottom|left"
+ font="SansSerifBigBold"
+ height="18"
+ image_selected="OptionsMenu_Press"
+ image_unselected="OptionsMenu_Off"
+ layout="topleft"
+ left="20"
+ name="gear_btn"
+ picture_style="true"
+ tool_tip="Change sort and view of Groups list"
+ top="7"
+ width="18" />
+ <button
+ follows="bottom|left"
+ font="SansSerifBigBold"
+ height="18"
+ image_selected="AddItem_Press"
+ image_unselected="AddItem_Off"
+ layout="topleft"
+ left_pad="5"
+ name="plus_btn"
+ picture_style="true"
+ tool_tip="Join group/Create new group"
+ top_delta="0"
+ width="18" />
+ <button
+ follows="bottom|left"
+ font="SansSerifBigBold"
+ height="10"
+ image_hover_selected="group_activate_btn.tga"
+ image_selected="group_activate_btn.tga"
+ image_unselected="group_activate_btn.tga"
+ layout="topleft"
+ left_pad="24"
+ name="activate_btn"
+ picture_style="true"
+ tool_tip="Activate selected group"
+ top_delta="5"
+ width="10" />
+ <button
+ follows="bottom|left"
+ font="SansSerifBigBold"
+ height="18"
+ image_selected="TrashItem_Press"
+ image_unselected="TrashItem_Off"
+ layout="topleft"
+ left_pad="146"
+ name="minus_btn"
+ picture_style="true"
+ tool_tip="Leave selected group"
+ top_delta="-5"
+ width="18" />
+ </panel>
+ </panel>
+ <panel
+ background_visible="true"
+ bevel_style="none"
+ follows="left|top|right|bottom"
+ height="390"
+ label="Recent"
+ layout="topleft"
+ name="recent_panel"
+ width="285">
+ <avatar_list
+ follows="left|top|right|bottom"
+ height="357"
+ layout="topleft"
+ left="0"
+ name="avatar_list"
+ top="2"
+ width="285" />
+ <panel
+ background_visible="true"
+ bevel_style="none"
+ bottom="390"
+ follows="left|right|bottom"
+ height="30"
+ label="bottom_panel"
+ layout="topleft"
+ left="0"
+ name="bottom_panel"
+ width="285">
+ <button
+ follows="bottom|left"
+ font="SansSerifBigBold"
+ height="18"
+ image_selected="OptionsMenu_Press"
+ image_unselected="OptionsMenu_Off"
+ layout="topleft"
+ left="20"
+ name="recent_viewsort_btn"
+ picture_style="true"
+ tool_tip="Change sort and view of Residents list"
+ top="7"
+ width="18" />
+ </panel>
+ </panel>
+ </tab_container>
+ <layout_stack
+ animate="false"
+ border_size="0"
+ follows="left|right|bottom"
+ height="27"
+ layout="topleft"
+ left="10"
+ name="button_bar"
+ orientation="horizontal"
+ width="295">
+ <layout_panel
+ default_tab_group="1"
+ follows="left|top|right"
+ height="25"
+ layout="topleft"
+ left="0"
+ name="view_profile_btn_panel"
+ top="-25"
+ width="65">
+ <button
+ follows="top|left|right"
+ font="SansSerifSmallBold"
+ height="25"
+ label="Profile"
+ layout="topleft"
+ name="view_profile_btn"
+ tool_tip="Show picture, groups, and other residents information"
+ width="65" />
+ </layout_panel>
+ <layout_panel
+ default_tab_group="1"
+ follows="left|top|right"
+ height="25"
+ layout="topleft"
+ left_delta="0"
+ min_width="85"
+ name="add_friend_btn_panel"
+ top_delta="0"
+ width="85">
+ <button
+ follows="top|left|right"
+ font="SansSerifSmallBold"
+ height="25"
+ label="Add Friend"
+ layout="topleft"
+ name="add_friend_btn"
+ tool_tip="Add selected resident to your Friends List"
+ width="85" />
+ </layout_panel>
+ <layout_panel
+ default_tab_group="1"
+ follows="left|top|right"
+ height="25"
+ layout="topleft"
+ min_width="80"
+ name="group_info_btn_panel"
+ width="80">
+ <button
+ follows="top|left|right"
+ font="SansSerifSmallBold"
+ height="25"
+ label="Group Profile"
+ layout="topleft"
+ name="group_info_btn"
+ tool_tip="Show group information"
+ width="80" />
+ </layout_panel>
+ <layout_panel
+ default_tab_group="1"
+ follows="left|top|right"
+ height="25"
+ layout="topleft"
+ min_width="45"
+ name="chat_btn_panel"
+ top_delta="0"
+ width="45">
+ <button
+ follows="top|left|right"
+ font="SansSerifSmallBold"
+ height="25"
+ label="Chat"
+ layout="topleft"
+ name="chat_btn"
+ tool_tip="Open chat session"
+ width="45" />
+ </layout_panel>
+ <layout_panel
+ default_tab_group="1"
+ follows="left|top|right"
+ height="25"
+ layout="topleft"
+ min_width="35"
+ name="im_btn_panel"
+ top_delta="0"
+ width="35">
+ <button
+ follows="top|left|right"
+ font="SansSerifSmallBold"
+ height="25"
+ label="IM"
+ layout="topleft"
+ name="im_btn"
+ tool_tip="Open instant message session"
+ width="35" />
+ </layout_panel>
+ <layout_panel
+ default_tab_group="1"
+ follows="left|top|right"
+ height="25"
+ layout="topleft"
+ min_width="40"
+ name="call_btn_panel"
+ top_delta="0"
+ visible="false"
+ width="40">
+ <button
+ enabled="false"
+ follows="top|left|right"
+ font="SansSerifSmallBold"
+ height="25"
+ label="Call"
+ layout="topleft"
+ name="call_btn"
+ width="40" />
+ </layout_panel>
+ <layout_panel
+ default_tab_group="1"
+ follows="left|top|right"
+ height="25"
+ layout="topleft"
+ min_width="65"
+ name="teleport_btn_panel"
+ top_delta="0"
+ width="65">
+ <button
+ follows="left|top|right"
+ font="SansSerifSmallBold"
+ height="25"
+ label="Teleport"
+ layout="topleft"
+ name="teleport_btn"
+ tool_tip="Offer teleport"
+ width="65" />
+ </layout_panel>
+ <layout_panel
+ default_tab_group="1"
+ enabled="false"
+ follows="left|top|right"
+ height="25"
+ layout="topleft"
+ min_width="50"
+ name="share_btn_panel"
+ top_delta="0"
+ visible="false"
+ width="50">
+ <button
+ enabled="false"
+ follows="top|left|right"
+ font="SansSerifSmallBold"
+ height="25"
+ label="Share"
+ layout="topleft"
+ name="share_btn"
+ width="50" />
+ </layout_panel>
+ </layout_stack>
+</panel>
diff --git a/indra/newview/skins/default/xui/en/panel_pick_info.xml b/indra/newview/skins/default/xui/en/panel_pick_info.xml
new file mode 100644
index 0000000000..80fa99c257
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/panel_pick_info.xml
@@ -0,0 +1,173 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<panel
+ bevel_style="in"
+ follows="left|top|right|bottom"
+ height="420"
+ layout="topleft"
+ left="0"
+ name="panel_pick_info"
+ top="0"
+ width="255">
+ <scroll_container
+ color="DkGray2"
+ follows="left|top|right|bottom"
+ height="300"
+ layout="topleft"
+ left="0"
+ name="profile_scroll"
+ reserve_scroll_corner="true"
+ opaque="true"
+ width="255">
+ <panel
+ name="scroll_content_panel"
+ follows="left|top|right"
+ layout="topleft"
+ top="0"
+ left="0"
+ width="240"
+ height="575">
+ <text
+ follows="top"
+ font="SansSerifHugeBold"
+ height="15"
+ layout="topleft"
+ left="10"
+ name="title"
+ text_color="white"
+ top="5"
+ value="Pick Info"
+ width="150" />
+ <button
+ follows="top|right"
+ height="20"
+ image_overlay="BackArrow_Off"
+ layout="topleft"
+ name="back_btn"
+ picture_style="true"
+ right="-20"
+ top="7"
+ width="20" />
+ <panel
+ background_visible="true"
+ bg_alpha_color="DkGray2"
+ follows="left|right|top|bottom"
+ height="550"
+ layout="topleft"
+ left="0"
+ min_height="300"
+ top="30"
+ width="255">
+ <texture_picker
+ enabled="false"
+ follows="left|top|right"
+ height="300"
+ layout="topleft"
+ left="10"
+ name="pick_snapshot"
+ top="10"
+ width="245" />
+ <text
+ follows="left|top"
+ font="SansSerifBigBold"
+ height="15"
+ layout="topleft"
+ left="10"
+ name="Name:"
+ text_color="white"
+ value="Name:" />
+ <text
+ follows="left|top|right"
+ height="15"
+ layout="topleft"
+ left="10"
+ name="pick_name"
+ right="-10"
+ text_color="white"
+ value="[name]"
+ word_wrap="true" />
+ <text
+ follows="left|top"
+ font="SansSerifBigBold"
+ height="15"
+ layout="topleft"
+ left="10"
+ name="description_label"
+ text_color="white"
+ top_pad="20"
+ valign="center"
+ value="Description:" />
+ <text
+ follows="left|top|right"
+ height="60"
+ layout="topleft"
+ left="10"
+ name="pick_desc"
+ right="-10"
+ text_color="white"
+ valign="center"
+ value="[description]"
+ width="255"
+ word_wrap="true" />
+ <text
+ follows="left|top"
+ font="SansSerifBigBold"
+ height="20"
+ layout="topleft"
+ left="10"
+ name="location_label"
+ text_color="white"
+ top_pad="20"
+ valign="bottom"
+ value="Location:" />
+ <text
+ follows="left|top"
+ height="30"
+ layout="topleft"
+ left="10"
+ name="pick_location"
+ text_color="white"
+ valign="center"
+ value="[loading...]" />
+ </panel>
+ </panel>
+ </scroll_container>
+ <panel
+ follows="left|right|bottom"
+ height="30"
+ layout="topleft"
+ top_pad="2"
+ left="8"
+ name="buttons"
+ right="-10">
+ <button
+ follows="bottom|left"
+ font="SansSerifSmallBold"
+ height="25"
+ label="Edit"
+ layout="topleft"
+ left="0"
+ name="edit_btn"
+ top="0"
+ width="50" />
+ <button
+ follows="bottom|left"
+ font="SansSerifSmallBold"
+ height="25"
+ label="Teleport"
+ layout="topleft"
+ left_pad="2"
+ name="teleport_btn"
+ top="0"
+ width="80" />
+ <button
+ follows="bottom|left"
+ font="SansSerifSmallBold"
+ height="25"
+ label="Map"
+ layout="topleft"
+ left_pad="2"
+ name="show_on_map_btn"
+ top="0"
+ width="100" />
+ </panel>
+</panel>
diff --git a/indra/newview/skins/default/xui/en/panel_pick_list_item.xml b/indra/newview/skins/default/xui/en/panel_pick_list_item.xml
new file mode 100644
index 0000000000..6f4110067b
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/panel_pick_list_item.xml
@@ -0,0 +1,57 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<panel
+ bevel_style="none"
+ follows="top|left|right"
+ height="120"
+ layout="topleft"
+ left="0"
+ name="picture_item"
+ top="0"
+ width="275">
+ <texture_picker
+ allow_no_texture="true"
+ default_image_name="None"
+ enabled="false"
+ follows="left|top"
+ height="120"
+ layout="topleft"
+ left="5"
+ mouse_opaque="false"
+ name="picture"
+ tab_stop="false"
+ top="5"
+ width="120" />
+ <text
+ follows="top|left|right"
+ height="16"
+ layout="topleft"
+ left="135"
+ name="picture_name"
+ text_color="white"
+ top="5"
+ use_ellipses="true"
+ width="120"
+ word_wrap="true" />
+ <text
+ follows="top|left|right"
+ height="75"
+ layout="topleft"
+ left="135"
+ name="picture_descr"
+ top_pad="10"
+ use_ellipses="true"
+ width="130"
+ word_wrap="true" />
+ <button
+ follows="top|right"
+ height="16"
+ image_selected="Info_Press"
+ image_unselected="Info_Off"
+ layout="topleft"
+ name="info_chevron"
+ picture_style="true"
+ right="262"
+ tab_stop="false"
+ top="3"
+ width="16" />
+</panel>
diff --git a/indra/newview/skins/default/xui/en/panel_picks.xml b/indra/newview/skins/default/xui/en/panel_picks.xml
new file mode 100644
index 0000000000..ff161cc2ab
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/panel_picks.xml
@@ -0,0 +1,112 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<panel
+ follows="left|top|right|bottom"
+ height="420"
+ label="Picks"
+ layout="topleft"
+ left="0"
+ name="panel_picks"
+ top="0"
+ width="285">
+ <layout_stack
+ name="layout"
+ orientation="vertical"
+ follows="all"
+ layout="topleft"
+ left="0"
+ top="0"
+ height="420"
+ width="284"
+ border_size="0">
+ <scroll_container
+ color="DkGray2"
+ follows="left|top|right|bottom"
+ height="350"
+ layout="topleft"
+ left="2"
+ name="profile_scroll"
+ opaque="true"
+ top="0"
+ width="284">
+ <panel
+ height="115"
+ layout="topleft"
+ left="0"
+ name="back_panel"
+ top="0"
+ width="284" />
+ </scroll_container>
+ <panel
+ background_visible="true"
+ bevel_style="none"
+ enabled="false"
+ auto_resize="false"
+ follows="bottom"
+ height="30"
+ label="bottom_panel"
+ layout="topleft"
+ name="edit_panel"
+ top_pad="5"
+ width="284">
+ <button
+ enabled="false"
+ follows="bottom|left"
+ font="SansSerifBigBold"
+ height="18"
+ image_selected="OptionsMenu_Press"
+ image_unselected="OptionsMenu_Off"
+ layout="topleft"
+ left="10"
+ name="gear_menu_btn"
+ picture_style="true"
+ top="5"
+ width="18" />
+ <button
+ follows="bottom|left"
+ font="SansSerifBigBold"
+ height="18"
+ image_disabled="AddItem_Off"
+ image_disabled_selected="AddItem_Press"
+ image_selected="AddItem_Press"
+ image_unselected="AddItem_Off"
+ layout="topleft"
+ left="35"
+ name="new_btn"
+ picture_style="true"
+ tool_tip="Create New Pick at Current Location"
+ top="5"
+ width="18" />
+ <button
+ follows="bottom|right"
+ font="SansSerifBigBold"
+ height="18"
+ image_disabled="TrashItem_Off"
+ image_disabled_selected="TrashItem_Press"
+ image_selected="TrashItem_Press"
+ image_unselected="TrashItem_Off"
+ layout="topleft"
+ name="trash_btn"
+ picture_style="true"
+ right="-10"
+ top="5"
+ width="18" />
+ </panel>
+ <panel
+ follows="bottom"
+ height="30"
+ auto_resize="false"
+ layout="topleft"
+ name="buttons_cucks"
+ width="284">
+ <button
+ enabled="false"
+ follows="bottom|left"
+ font="SansSerifSmallBold"
+ height="25"
+ label="Map"
+ layout="topleft"
+ name="show_on_map_btn"
+ width="85" />
+ </panel>
+ </layout_stack>
+</panel>
diff --git a/indra/newview/skins/default/xui/en/panel_places.xml b/indra/newview/skins/default/xui/en/panel_places.xml
new file mode 100644
index 0000000000..bff28718a7
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/panel_places.xml
@@ -0,0 +1,137 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<panel
+ background_visible="true"
+ follows="all"
+ height="400"
+ label="Places"
+ layout="topleft"
+ min_height="350"
+ min_width="240"
+ name="places panel"
+ width="305">
+ <string
+ name="landmarks_tab_title"
+ value="Landmarks" />
+ <string
+ name="teleport_history_tab_title"
+ value="Teleport History" />
+ <filter_editor
+ background_image="TextField_Search_Off"
+ follows="left|top|right"
+ font="SansSerif"
+ height="23"
+ label="Filter"
+ layout="topleft"
+ left="15"
+ name="Filter"
+ text_color="black"
+ text_pad_left="26"
+ top="3"
+ width="256" />
+ <button
+ follows="left|top|right"
+ height="13"
+ image_selected="Search"
+ image_unselected="Search"
+ layout="topleft"
+ left="20"
+ name="landmark_search"
+ picture_style="true"
+ scale_image="false"
+ top="8"
+ width="13" />
+ <tab_container
+ follows="all"
+ height="326"
+ layout="topleft"
+ left="9"
+ name="Places Tabs"
+ tab_position="top"
+ top="30"
+ width="285" />
+ <panel
+ class="panel_place_info"
+ filename="panel_place_info.xml"
+ follows="all"
+ height="326"
+ layout="topleft"
+ left="0"
+ name="panel_place_info"
+ top="30"
+ visible="false" />
+ <panel
+ height="25"
+ layout="topleft"
+ left="0"
+ name="button_panel"
+ top_pad="10"
+ width="305">
+ <button
+ follows="bottom|left"
+ font="SansSerifSmallBold"
+ height="25"
+ label="Teleport"
+ layout="topleft"
+ left="5"
+ name="teleport_btn"
+ top="0"
+ width="80" />
+ <button
+ follows="bottom|left"
+ font="SansSerifSmallBold"
+ height="25"
+ label="Map"
+ layout="topleft"
+ left_pad="5"
+ name="map_btn"
+ top="0"
+ width="80" />
+ <button
+ enabled="false"
+ follows="bottom|left"
+ font="SansSerifSmallBold"
+ height="25"
+ label="Share"
+ layout="topleft"
+ left_pad="5"
+ name="share_btn"
+ top="0"
+ width="60" />
+ <button
+ follows="bottom|right"
+ font="SansSerifSmallBold"
+ height="25"
+ label="â–¼"
+ layout="topleft"
+ left_pad="5"
+ name="overflow_btn"
+ top="0"
+ width="30" />
+ <button
+ follows="bottom|left"
+ font="SansSerifSmallBold"
+ height="25"
+ image_disabled="widgets/SegmentedBtn_Left_Disabled.png"
+ image_selected="widgets/SegmentedBtn_Left_Selected.png"
+ image_unselected="widgets/SegmentedBtn_Left_Off.png"
+ label="Create"
+ layout="topleft"
+ left="5"
+ name="create_landmark_btn"
+ top="0"
+ width="60" />
+ <button
+ follows="bottom|left"
+ font="SansSerifSmallBold"
+ height="25"
+ image_disabled="widgets/ComboButton_Disabled.png"
+ image_selected="widgets/ComboButton_Selected.png"
+ image_unselected="widgets/ComboButton_Off.png"
+ label="â–¼"
+ layout="topleft"
+ left_pad="0"
+ name="folder_menu_btn"
+ top="0"
+ width="20" />
+ </panel>
+</panel>
diff --git a/indra/newview/skins/default/xui/en/panel_preferences_advanced.xml b/indra/newview/skins/default/xui/en/panel_preferences_advanced.xml
new file mode 100644
index 0000000000..060d84b2e4
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/panel_preferences_advanced.xml
@@ -0,0 +1,217 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<panel
+ border="true"
+ background_visible="true"
+ follows="left|top|right|bottom"
+ height="408"
+ layout="topleft"
+ left="102"
+ name="advanced"
+ top="1"
+ width="517">
+ <panel.string
+ name="resolution_format">
+ [RES_X] x [RES_Y]
+ </panel.string>
+ <panel.string
+ name="aspect_ratio_text">
+ [NUM]:[DEN]
+ </panel.string>
+ <check_box
+ control_name="UseChatBubbles"
+ height="16"
+ label="Bubble Chat"
+ layout="topleft"
+ left="30"
+ top="20"
+ name="bubble_text_chat"
+ width="150" />
+
+ <slider
+ control_name="ChatBubbleOpacity"
+ height="16"
+ increment="0.05"
+ initial_value="1"
+ label="Opacity"
+ layout="topleft"
+ left="50"
+ top_pad="5"
+ label_width="50"
+ name="bubble_chat_opacity"
+ width="200" />
+
+ <!-- <check_box
+ control_name="UIAutoScale"
+ height="16"
+ label="Resolution independent scale"
+ layout="topleft"
+ left="30"
+ name="ui_auto_scale"
+ top_pad="10"
+ width="256" />-->
+ <!--
+ <combo_box
+ height="18"
+ layout="topleft"
+ left_pad="5"
+ name="fullscreen combo"
+ top_delta="-1"
+ width="150" /-->
+ <text
+ type="string"
+ length="1"
+ height="25"
+ layout="topleft"
+ left="30"
+ top_pad="20"
+ name="AspectRatioLabel1"
+ tool_tip="width / height"
+ label_width="50"
+ width="120">
+ Aspect Ratio
+ </text>
+ <combo_box
+ allow_text_entry="true"
+ height="25"
+ layout="topleft"
+ left_pad="0"
+ max_chars="100"
+ name="aspect_ratio"
+ tool_tip="width / height"
+ top_delta="0"
+ width="150">
+ <combo_box.item
+ enabled="true"
+ label=" 4:3 (Standard CRT)"
+ name="item1"
+ value="1.333333" />
+ <combo_box.item
+ enabled="true"
+ label=" 5:4 (1280x1024 LCD)"
+ name="item2"
+ value="1.25" />
+ <combo_box.item
+ enabled="true"
+ label=" 8:5 (Widescreen)"
+ name="item3"
+ value="1.6" />
+ <combo_box.item
+ enabled="true"
+ label=" 16:9 (Widescreen)"
+ name="item4"
+ value="1.7777777" />
+ </combo_box>
+ <check_box
+ control_name="FullScreenAutoDetectAspectRatio"
+ height="25"
+ label="Auto-detect"
+ layout="topleft"
+ left_pad="10"
+ name="aspect_auto_detect"
+ width="256">
+ <check_box.commit_callback
+ function="Pref.AutoDetectAspect" />
+ </check_box>
+
+ <text
+ type="string"
+ length="1"
+ height="10"
+ left="30"
+ text_color="EmphasisColor"
+ name="text_box1"
+ top_pad="30"
+ width="270">
+Camera:
+ </text>
+ <slider
+ can_edit_text="true"
+ control_name="CameraAngle"
+ decimal_digits="2"
+ top_pad="10"
+ follows="left|top"
+ height="16"
+ increment="0.025"
+ initial_value="1.57"
+ layout="topleft"
+ label_width="100"
+ label="View Angle"
+ left="30"
+ max_val="2.97"
+ min_val="0.17"
+ name="camera_fov"
+ show_text="false"
+ width="240" />
+
+ <slider
+ can_edit_text="true"
+ control_name="CameraOffsetScale"
+ decimal_digits="2"
+ follows="left|top"
+ height="16"
+ increment="0.025"
+ initial_value="1"
+ layout="topleft"
+ label="Distance"
+ left="30"
+ label_width="100"
+ max_val="3"
+ min_val="0.5"
+ name="camera_offset_scale"
+ show_text="false"
+ width="240" />
+ <text
+ type="string"
+ length="1"
+ height="10"
+ left="30"
+ name="text_box1"
+ width="270">
+Automatic positioning for:
+ </text>
+ <check_box
+ control_name="EditCameraMovement"
+ height="20"
+ label="Build/Edit"
+ layout="topleft"
+ left="50"
+ name="edit_camera_movement"
+ tool_tip="Use automatic camera positioning when entering and exiting edit mode"
+ width="280" />
+ <check_box
+ control_name="AppearanceCameraMovement"
+ height="16"
+ label="Appearance"
+ layout="topleft"
+ name="appearance_camera_movement"
+ tool_tip="Use automatic camera positioning while in edit mode"
+ width="242" />
+
+ <text
+ type="string"
+ length="1"
+ height="10"
+ left="30"
+ text_color="EmphasisColor"
+ name="text_box1"
+ top_pad="30"
+ width="270">
+My Avatar:
+ </text>
+ <check_box
+ control_name="FirstPersonAvatarVisible"
+ height="20"
+ label="Show me in Mouselook"
+ layout="topleft"
+ name="first_person_avatar_visible"
+ width="256" />
+ <check_box
+ control_name="ArrowKeysMoveAvatar"
+ height="20"
+ label="Arrow keys always move me"
+ layout="topleft"
+ left="30"
+ name="arrow_keys_move_avatar_check"
+ width="237" />
+</panel> \ No newline at end of file
diff --git a/indra/newview/skins/default/xui/en/panel_preferences_chat.xml b/indra/newview/skins/default/xui/en/panel_preferences_chat.xml
new file mode 100644
index 0000000000..f4696152f9
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/panel_preferences_chat.xml
@@ -0,0 +1,289 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<panel
+ border="true"
+ follows="left|top|right|bottom"
+ height="408"
+ label="Text Chat"
+ layout="topleft"
+ left="102"
+ name="chat"
+ top="1"
+ width="517">
+ <radio_group
+ height="30"
+ layout="topleft"
+ left="30"
+ control_name="ChatFontSize"
+ name="chat_font_size"
+ top="10"
+ width="331">
+ <radio_item
+ height="16"
+ label="Small"
+ layout="topleft"
+ left="0"
+ name="radio"
+ top="10"
+ width="125" />
+ <radio_item
+ height="16"
+ label="Medium"
+ layout="topleft"
+ left_pad="12"
+ name="radio2"
+ top_delta="0"
+ width="125" />
+ <radio_item
+ height="16"
+ label="Large"
+ layout="topleft"
+ left_pad="12"
+ name="radio3"
+ top_delta="0"
+ width="125" />
+ </radio_group>
+ <color_swatch
+ border_color="0.45098 0.517647 0.607843 1"
+ can_apply_immediately="true"
+ control_name="UserChatColor"
+ follows="left|top"
+ height="47"
+ layout="topleft"
+ left="30"
+ name="user"
+ top_pad="10"
+ width="44" />
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="10"
+ layout="topleft"
+ left_pad="5"
+ mouse_opaque="false"
+ name="text_box1"
+ top_delta="5"
+ width="95">
+ Me
+ </text>
+ <color_swatch
+ border_color="0.45098 0.517647 0.607843 1"
+ can_apply_immediately="true"
+ control_name="AgentChatColor"
+ follows="left|top"
+ height="47"
+ layout="topleft"
+ left="180"
+ name="agent"
+ top_pad="-17"
+ width="44" />
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="10"
+ layout="topleft"
+ left_pad="5"
+ mouse_opaque="false"
+ name="text_box2"
+ top_delta="5"
+ width="95">
+ Others
+ </text>
+ <color_swatch
+ border_color="0.45098 0.517647 0.607843 1"
+ can_apply_immediately="true"
+ color="0.6 0.6 1 1"
+ control_name="IMChatColor"
+ follows="left|top"
+ height="47"
+ label_width="60"
+ layout="topleft"
+ left="350"
+ name="im"
+ top_pad="-17"
+ width="44" />
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="10"
+ layout="topleft"
+ left_pad="5"
+ mouse_opaque="false"
+ name="text_box3"
+ top_delta="5"
+ width="95">
+ IM
+ </text>
+ <color_swatch
+ border_color="0.45098 0.517647 0.607843 1"
+ can_apply_immediately="true"
+ color="0.8 1 1 1"
+ control_name="SystemChatColor"
+ follows="left|top"
+ height="47"
+ label_width="44"
+ layout="topleft"
+ left="30"
+ name="system"
+ top_pad="40"
+ width="44" />
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="10"
+ layout="topleft"
+ left_pad="5"
+ mouse_opaque="false"
+ name="text_box4"
+ top_delta="5"
+ width="95">
+ System
+ </text>
+ <color_swatch
+ border_color="0.45098 0.517647 0.607843 1"
+ can_apply_immediately="true"
+ color="0.82 0.82 0.99 1"
+ control_name="ScriptErrorColor"
+ follows="left|top"
+ height="47"
+ layout="topleft"
+ left="180"
+ name="script_error"
+ top_pad="-17"
+ width="44" />
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="10"
+ layout="topleft"
+ left_pad="5"
+ mouse_opaque="false"
+ name="text_box5"
+ top_delta="5"
+ width="95">
+ Errors
+ </text>
+ <color_swatch
+ border_color="0.45098 0.517647 0.607843 1"
+ can_apply_immediately="true"
+ color="0.7 0.9 0.7 1"
+ control_name="ObjectChatColor"
+ follows="left|top"
+ height="47"
+ layout="topleft"
+ left="350"
+ name="objects"
+ top_pad="-17"
+ width="44" />
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="10"
+ layout="topleft"
+ left_pad="5"
+ mouse_opaque="false"
+ name="text_box6"
+ top_delta="5"
+ width="95">
+ Objects
+ </text>
+ <color_swatch
+ border_color="0.45098 0.517647 0.607843 1"
+ can_apply_immediately="true"
+ color="0.7 0.9 0.7 1"
+ control_name="llOwnerSayChatColor"
+ follows="left|top"
+ height="47"
+ layout="topleft"
+ left="30"
+ name="owner"
+ top_pad="40"
+ width="44" />
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="10"
+ layout="topleft"
+ left_pad="5"
+ mouse_opaque="false"
+ name="text_box7"
+ top_delta="5"
+ width="95">
+ Owner
+ </text>
+ <color_swatch
+ border_color="0.45098 0.517647 0.607843 1"
+ can_apply_immediately="true"
+ color="0 0 0 1"
+ control_name="BackgroundChatColor"
+ follows="left|top"
+ height="47"
+ layout="topleft"
+ left="180"
+ name="background"
+ top_pad="-17"
+ width="44" />
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="10"
+ layout="topleft"
+ left_pad="5"
+ mouse_opaque="false"
+ name="text_box8"
+ top_delta="5"
+ width="95">
+ Bubble
+ </text>
+ <color_swatch
+ border_color="0.45098 0.517647 0.607843 1"
+ can_apply_immediately="true"
+ color="0.6 0.6 1 1"
+ control_name="HTMLLinkColor"
+ follows="left|top"
+ height="47"
+ layout="topleft"
+ left="350"
+ name="links"
+ top_pad="-17"
+ width="44" />
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="10"
+ layout="topleft"
+ left_pad="5"
+ mouse_opaque="false"
+ name="text_box9"
+ top_delta="5"
+ width="95">
+ URLs
+ </text>
+ <check_box
+ control_name="PlayTypingAnim"
+ height="16"
+ initial_value="true"
+ label="Play typing animation when chatting"
+ layout="topleft"
+ left="30"
+ name="play_typing_animation"
+ top_pad="40"
+ width="400" />
+ <check_box
+ enabled="false"
+ height="16"
+ label="Email me IMs when I'm offline"
+ layout="topleft"
+ left_delta="0"
+ name="send_im_to_email"
+ top_pad="5"
+ width="400" />
+</panel>
diff --git a/indra/newview/skins/default/xui/en/panel_preferences_general.xml b/indra/newview/skins/default/xui/en/panel_preferences_general.xml
new file mode 100644
index 0000000000..95d8d2ce2a
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/panel_preferences_general.xml
@@ -0,0 +1,310 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<panel
+ border="true"
+ follows="left|top|right|bottom"
+ height="408"
+ label="General"
+ layout="topleft"
+ left="102"
+ name="general_panel"
+ top="1"
+ width="517">
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="10"
+ layout="topleft"
+ left="30"
+ name="language_textbox"
+ top="10"
+ width="400">
+ Language:
+ </text>
+ <combo_box
+ control_name="Language"
+ follows="left|bottom"
+ height="18"
+ layout="topleft"
+ left_delta="50"
+ max_chars="135"
+ name="language_combobox"
+ top_pad="10"
+ width="170">
+ <combo_box.item
+ enabled="true"
+ label="System Default"
+ name="System Default Language"
+ value="default" />
+ <combo_box.item
+ enabled="true"
+ label="English"
+ name="English"
+ value="en" />
+ <combo_box.item
+ enabled="true"
+ label="Dansk (Danish) - Beta"
+ name="Danish"
+ value="da" />
+ <combo_box.item
+ enabled="true"
+ label="Deutsch (German) - Beta"
+ name="Deutsch(German)"
+ value="de" />
+ <combo_box.item
+ enabled="true"
+ label="Español (Spanish) - Beta"
+ name="Spanish"
+ value="es" />
+ <combo_box.item
+ enabled="true"
+ label="Français (French) - Beta"
+ name="French"
+ value="fr" />
+ <combo_box.item
+ enabled="true"
+ label="Italiano (Italian) - Beta"
+ name="Italian"
+ value="it" />
+ <combo_box.item
+ enabled="true"
+ label="Magyar (Hungarian) - Beta"
+ name="Hungarian"
+ value="hu" />
+ <combo_box.item
+ enabled="true"
+ label="Nederlands (Dutch) - Beta"
+ name="Dutch"
+ value="nl" />
+ <combo_box.item
+ enabled="true"
+ label="Polski (Polish) - Beta"
+ name="Polish"
+ value="pl" />
+ <combo_box.item
+ enabled="true"
+ label="Portugués (Portuguese) - Beta"
+ name="Portugese"
+ value="pt" />
+ <combo_box.item
+ enabled="true"
+ label="РуÑÑкий (Russian) - Beta"
+ name="Russian"
+ value="ru" />
+ <combo_box.item
+ enabled="true"
+ label="Türkçe (Turkish) - Beta"
+ name="Turkish"
+ value="tr" />
+ <combo_box.item
+ enabled="true"
+ label="УкраїнÑька (Ukrainian) - Beta"
+ name="Ukrainian"
+ value="uk" />
+ <combo_box.item
+ enabled="true"
+ label="中文 (简体) (Chinese) - Beta"
+ name="Chinese"
+ value="zh" />
+ <combo_box.item
+ enabled="true"
+ label="日本語 (Japanese) - Beta"
+ name="(Japanese)"
+ value="ja" />
+ <combo_box.item
+ enabled="true"
+ label="한국어 (Korean) - Beta"
+ name="(Korean)"
+ value="ko" />
+ <combo_box.item
+ enabled="true"
+ label="Test Language"
+ name="TestLanguage"
+ value="test" />
+ </combo_box>
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="10"
+ layout="topleft"
+ left_delta="175"
+ name="language_textbox2"
+ top_delta="1"
+ width="400">
+ (Requires restart)
+ </text>
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="10"
+ layout="topleft"
+ left="30"
+ name="maturity_desired_prompt"
+ top_pad="10"
+ width="400">
+ I want to access content rated:
+ </text>
+ <combo_box
+ control_name="PreferredMaturity"
+ follows="left|bottom"
+ height="18"
+ layout="topleft"
+ left_delta="50"
+ name="maturity_desired_combobox"
+ top_pad="10"
+ width="170">
+ <combo_box.item
+ label="PG, Mature and Adult"
+ name="Desired_Adult"
+ value="42" />
+ <combo_box.item
+ label="PG and Mature"
+ name="Desired_Mature"
+ value="21" />
+ <combo_box.item
+ label="PG"
+ name="Desired_PG"
+ value="13" />
+ </combo_box>
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="10"
+ layout="topleft"
+ left="30"
+ name="start_location_textbox"
+ top_delta="20"
+ width="394">
+ Start Location:
+ </text>
+ <combo_box
+ control_name="LoginLocation"
+ follows="left|bottom"
+ height="18"
+ layout="topleft"
+ left_delta="50"
+ name="start_location_combo"
+ top_pad="10"
+ width="170">
+ <combo_box.item
+ label="My Last Location"
+ name="MyLastLocation"
+ value="last" />
+ <combo_box.item
+ label="My Home"
+ name="MyHome"
+ value="home" />
+ </combo_box>
+ <check_box
+ control_name="ShowStartLocation"
+ height="16"
+ initial_value="true"
+ label="Show on Login"
+ layout="topleft"
+ left_delta="175"
+ name="show_location_checkbox"
+ top_delta="1"
+ width="256" />
+
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="10"
+ layout="topleft"
+ left="30"
+ name="name_tags_textbox"
+ top_pad="10"
+ width="400">
+ Name tags:
+ </text>
+ <radio_group
+ control_name="AvatarNameTagMode"
+ height="30"
+ layout="topleft"
+ left_delta="50"
+ name="Name_Tag_Preference"
+ top_pad="10">
+ <radio_item
+ height="16"
+ label="Off"
+ layout="topleft"
+ left="0"
+ name="radio"
+ top_pad="0"
+ width="98" />
+ <radio_item
+ height="16"
+ label="On"
+ layout="topleft"
+ left_pad="12"
+ name="radio2"
+ top_delta="0"
+ width="98" />
+ <radio_item
+ height="16"
+ label="Show briefly"
+ layout="topleft"
+ left_pad="12"
+ name="radio3"
+ top_delta="0"
+ width="98" />
+ </radio_group>
+ <check_box
+ enabled_control="AvatarNameTagMode"
+ control_name="RenderNameShowSelf"
+ height="16"
+ label="Show my name"
+ layout="topleft"
+ left_delta="0"
+ name="show_my_name_checkbox"
+ top_pad="5"
+ width="300" />
+ <check_box
+ control_name="SmallAvatarNames"
+ height="16"
+ initial_value="true"
+ label="Small name tags"
+ layout="topleft"
+ left_delta="175"
+ name="small_avatar_names_checkbox"
+ top_delta="0"
+ width="200" />
+ <check_box
+ enabled_control="AvatarNameTagMode"
+ control_name="RenderShowGroupTitleAll"
+ height="16"
+ label="Show group titles"
+ layout="topleft"
+ left_delta="-175"
+ name="show_all_title_checkbox"
+ top_pad="5"
+ width="300" />
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="10"
+ layout="topleft"
+ left="30"
+ name="effects_color_textbox"
+ top_pad="10"
+ width="400">
+ My Effects:
+ </text>
+ <color_swatch
+ border_color="0.45098 0.517647 0.607843 1"
+ control_name="EffectColor"
+ follows="left|top"
+ height="48"
+ layout="topleft"
+ left_delta="50"
+ name="effect_color_swatch"
+ tool_tip="Click to open Color Picker"
+ top_pad="10"
+ width="32" />
+
+</panel>
diff --git a/indra/newview/skins/default/xui/en/panel_preferences_graphics1.xml b/indra/newview/skins/default/xui/en/panel_preferences_graphics1.xml
new file mode 100644
index 0000000000..ecfb0048a3
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/panel_preferences_graphics1.xml
@@ -0,0 +1,848 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<panel
+ border="true"
+ follows="left|top|right|bottom"
+ height="408"
+ label="Graphics"
+ layout="topleft"
+ left="102"
+ name="Display panel"
+ top="1"
+ width="517">
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="12"
+ layout="topleft"
+ left="30"
+ name="WindowSizeLabel"
+ top="10"
+ width="300">
+ Window size:
+ </text>
+ <check_box
+ control_name="WindowFullScreen"
+ height="16"
+ label="Use fullscreen"
+ layout="topleft"
+ left_delta="30"
+ name="windowed mode"
+ top_pad="4"
+ width="175">
+ </check_box>
+ <combo_box
+ visiblity_control="WindowFullScreen"
+ allow_text_entry="false"
+ enabled="true"
+ layout="topleft"
+ height="18"
+ left_delta="220"
+ max_chars="20"
+ mouse_opaque="true"
+ name="windowsize combo"
+ top_delta="-1"
+ width="150">
+ <combo_box.item
+ type="string"
+ length="1"
+ enabled="true"
+ name="640x480"
+ value="640 x 480">
+ 640x480
+ </combo_box.item>
+ <combo_box.item
+ type="string"
+ length="1"
+ enabled="true"
+ name="800x600"
+ value="800 x 600">
+ 800x600
+ </combo_box.item>
+ <combo_box.item
+ type="string"
+ length="1"
+ enabled="true"
+ name="720x480"
+ value="720 x 480">
+ 720x480 (NTSC)
+ </combo_box.item>
+ <combo_box.item
+ type="string"
+ length="1"
+ enabled="true"
+ name="768x576"
+ value="768 x 576">
+ 768x576 (PAL)
+ </combo_box.item>
+ <combo_box.item
+ type="string"
+ length="1"
+ enabled="true"
+ name="1024x768"
+ value="1024 x 768">
+ 1024x768
+ </combo_box.item>
+ <combo_box.commit_callback
+ function="Pref.setControlFalse"
+ parameter="FullScreenAutoDetectAspectRatio" />
+ </combo_box>
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="12"
+ layout="topleft"
+ left="30"
+ name="UI Size:"
+ top_pad="4"
+ width="300">
+ UI Size:
+ </text>
+ <slider
+ can_edit_text="true"
+ control_name="UIScaleFactor"
+ decimal_digits="2"
+ follows="left|top"
+ height="15"
+ increment="0.025"
+ initial_value="1"
+ layout="topleft"
+ left_delta="32"
+ max_val="1.4"
+ min_val="0.75"
+ name="ui_scale_slider"
+ top_pad="2"
+ width="180" />
+ <spinner
+ control_name="UIScaleFactor"
+ height="16"
+ increment="0.025"
+ initial_value="1"
+ layout="topleft"
+ left_pad="10"
+ max_val="1.4"
+ min_val="0.75"
+ name="ui_scale_slider"
+ top_delta="0"
+ width="58" />
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="12"
+ layout="topleft"
+ left="30"
+ name="QualitySpeed"
+ top_pad="4"
+ width="400">
+ Quality and speed:
+ </text>
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ halign="right"
+ height="12"
+ layout="topleft"
+ left="35"
+ name="FasterText"
+ top_pad="4"
+ width="80">
+ Faster
+ </text>
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="12"
+ layout="topleft"
+ left_delta="360"
+ name="BetterText"
+ top_delta="0"
+ width="100">
+ Better
+ </text>
+ <icon
+ color="0.12 0.12 0.12 1"
+ height="14"
+ image_name="rounded_square.tga"
+ layout="topleft"
+ left="128"
+ name="LowGraphicsDivet"
+ top_delta="-2"
+ width="2" />
+ <icon
+ color="0.12 0.12 0.12 1"
+ height="14"
+ image_name="rounded_square.tga"
+ layout="topleft"
+ left_pad="83"
+ name="MidGraphicsDivet"
+ top_delta="0"
+ width="2" />
+ <icon
+ color="0.12 0.12 0.12 1"
+ height="14"
+ image_name="rounded_square.tga"
+ layout="topleft"
+ left_pad="85"
+ name="HighGraphicsDivet"
+ top_delta="0"
+ width="2" />
+ <icon
+ color="0.12 0.12 0.12 1"
+ height="14"
+ image_name="rounded_square.tga"
+ layout="topleft"
+ left_pad="83"
+ name="UltraGraphicsDivet"
+ top_delta="0"
+ width="2" />
+ <slider
+ control_name="RenderQualityPerformance"
+ decimal_digits="0"
+ follows="left|top"
+ height="16"
+ increment="1"
+ initial_value="0"
+ layout="topleft"
+ left="120"
+ max_val="3"
+ name="QualityPerformanceSelection"
+ show_text="false"
+ top_delta="-2"
+ width="275">
+ <slider.commit_callback
+ function="Pref.QualityPerformance"/>
+ </slider>
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ halign="center"
+ height="12"
+ layout="topleft"
+ left="88"
+ name="ShadersPrefText"
+ top_delta="20"
+ width="80">
+ Low
+ </text>
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ halign="center"
+ height="12"
+ layout="topleft"
+ left_delta="87"
+ name="ShadersPrefText2"
+ top_delta="0"
+ width="80">
+ Mid
+ </text>
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ halign="center"
+ height="12"
+ layout="topleft"
+ left_delta="87"
+ name="ShadersPrefText3"
+ top_delta="0"
+ width="80">
+ High
+ </text>
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ halign="center"
+ height="12"
+ layout="topleft"
+ left_delta="85"
+ name="ShadersPrefText4"
+ top_delta="0"
+ width="80">
+ Ultra
+ </text>
+ <panel
+ visiblity_control="ShowAdvancedGraphicsSettings"
+ border="false"
+ follows="top|left"
+ height="260"
+ label="CustomGraphics"
+ layout="topleft"
+ left="5"
+ name="CustomGraphics Panel"
+ top="124"
+ width="485">
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="12"
+ layout="topleft"
+ left_delta="5"
+ name="ShadersText"
+ top="3"
+ width="128">
+ Shaders:
+ </text>
+ <check_box
+ control_name="RenderObjectBump"
+ height="16"
+ initial_value="true"
+ label="Bump Mapping and Shiny"
+ layout="topleft"
+ left_delta="0"
+ name="BumpShiny"
+ top_pad="7"
+ width="256" />
+ <check_box
+ control_name="VertexShaderEnable"
+ height="16"
+ initial_value="true"
+ label="Basic Shaders"
+ layout="topleft"
+ left_delta="0"
+ name="BasicShaders"
+ tool_tip="Disabling this option may prevent some graphics card drivers from crashing."
+ top_pad="1"
+ width="315">
+ <check_box.commit_callback
+ function="Pref.VertexShaderEnable" />
+ </check_box>
+ <check_box
+ control_name="WindLightUseAtmosShaders"
+ height="16"
+ initial_value="true"
+ label="Atmospheric Shaders"
+ layout="topleft"
+ left_delta="0"
+ name="WindLightUseAtmosShaders"
+ top_pad="1"
+ width="256">
+ <check_box.commit_callback
+ function="Pref.VertexShaderEnable" />
+ </check_box>
+ <check_box
+ control_name="RenderWaterReflections"
+ height="16"
+ initial_value="true"
+ label="Water Reflections"
+ layout="topleft"
+ left_delta="0"
+ name="Reflections"
+ top_pad="1"
+ width="256">
+ <check_box.commit_callback
+ function="Pref.VertexShaderEnable" />
+ </check_box>
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="12"
+ layout="topleft"
+ left_delta="0"
+ name="ReflectionDetailText"
+ top_pad="7"
+ width="128">
+ Reflection Detail:
+ </text>
+ <radio_group
+ control_name="RenderReflectionDetail"
+ draw_border="false"
+ height="70"
+ layout="topleft"
+ left_delta="-2"
+ name="ReflectionDetailRadio"
+ top_pad="3"
+ width="321">
+ <radio_item
+ height="16"
+ label="Terrain and Trees"
+ layout="topleft"
+ left="3"
+ name="0"
+ top="3"
+ width="315" />
+ <radio_item
+ height="16"
+ label="All Static Objects"
+ layout="topleft"
+ left_delta="0"
+ name="1"
+ top_delta="16"
+ width="315" />
+ <radio_item
+ height="16"
+ label="All Avatars and Objects"
+ layout="topleft"
+ left_delta="0"
+ name="2"
+ top_delta="16"
+ width="315" />
+ <radio_item
+ height="16"
+ label="Everything"
+ layout="topleft"
+ left_delta="0"
+ name="3"
+ top_delta="16"
+ width="315" />
+ </radio_group>
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="12"
+ layout="topleft"
+ left_delta="2"
+ name="AvatarRenderingText"
+ top_pad="5"
+ width="128">
+ Avatar Rendering:
+ </text>
+ <check_box
+ control_name="RenderUseImpostors"
+ height="16"
+ initial_value="true"
+ label="Avatar Impostors"
+ layout="topleft"
+ left_delta="0"
+ name="AvatarImpostors"
+ top_pad="7"
+ width="256" />
+ <check_box
+ control_name="RenderAvatarVP"
+ height="16"
+ initial_value="true"
+ label="Hardware Skinning"
+ layout="topleft"
+ left_delta="0"
+ name="AvatarVertexProgram"
+ top_pad="1"
+ width="256">
+ <check_box.commit_callback
+ function="Pref.VertexShaderEnable" />
+ </check_box>
+ <check_box
+ control_name="RenderAvatarCloth"
+ height="16"
+ initial_value="true"
+ label="Avatar Cloth"
+ layout="topleft"
+ left_delta="0"
+ name="AvatarCloth"
+ top_pad="1"
+ width="256" />
+
+ <slider
+ control_name="RenderFarClip"
+ decimal_digits="0"
+ follows="left|top"
+ height="16"
+ increment="8"
+ initial_value="160"
+ label="Draw Distance:"
+ label_width="140"
+ layout="topleft"
+ left="216"
+ max_val="512"
+ min_val="64"
+ name="DrawDistance"
+ top="3"
+ width="255">
+ <slider.commit_callback
+ function="Pref.UpdateMeterText" />
+ </slider>
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="12"
+ layout="topleft"
+ left_delta="250"
+ name="DrawDistanceMeterText2"
+ top_delta="1"
+ width="128">
+ m
+ </text>
+ <slider
+ control_name="RenderMaxPartCount"
+ decimal_digits="0"
+ follows="left|top"
+ height="16"
+ increment="256"
+ initial_value="4096"
+ label="Max. Particle Count:"
+ label_width="140"
+ layout="topleft"
+ left="216"
+ max_val="8192"
+ name="MaxParticleCount"
+ top_pad="6"
+ width="262" />
+ <slider
+ control_name="RenderGlowResolutionPow"
+ decimal_digits="0"
+ follows="left|top"
+ height="16"
+ increment="1"
+ initial_value="8"
+ label="Post Process Quality:"
+ label_width="140"
+ layout="topleft"
+ left_delta="0"
+ max_val="9"
+ min_val="8"
+ name="RenderPostProcess"
+ show_text="false"
+ top_pad="4"
+ width="223">
+ <slider.commit_callback
+ function="Pref.UpdateSliderText"
+ parameter="PostProcessText" />
+ </slider>
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="12"
+ layout="topleft"
+ left_delta="0"
+ name="MeshDetailText"
+ top_pad="5"
+ width="128">
+ Mesh Detail:
+ </text>
+ <slider
+ control_name="RenderVolumeLODFactor"
+ follows="left|top"
+ height="16"
+ increment="0.125"
+ initial_value="160"
+ label=" Objects:"
+ label_width="140"
+ layout="topleft"
+ left_delta="0"
+ max_val="2"
+ name="ObjectMeshDetail"
+ show_text="false"
+ top_pad="6"
+ width="223">
+ <slider.commit_callback
+ function="Pref.UpdateSliderText"
+ parameter="ObjectMeshDetailText" />
+ </slider>
+ <slider
+ control_name="RenderFlexTimeFactor"
+ follows="left|top"
+ height="16"
+ initial_value="160"
+ label=" Flexiprims:"
+ label_width="140"
+ layout="topleft"
+ left_delta="0"
+ name="FlexibleMeshDetail"
+ show_text="false"
+ top_pad="4"
+ width="223">
+ <slider.commit_callback
+ function="Pref.UpdateSliderText"
+ parameter="FlexibleMeshDetailText" />
+ </slider>
+ <slider
+ control_name="RenderTreeLODFactor"
+ follows="left|top"
+ height="16"
+ increment="0.125"
+ initial_value="160"
+ label=" Trees:"
+ label_width="140"
+ layout="topleft"
+ left_delta="0"
+ name="TreeMeshDetail"
+ show_text="false"
+ top_pad="4"
+ width="223">
+ <slider.commit_callback
+ function="Pref.UpdateSliderText"
+ parameter="TreeMeshDetailText" />
+ </slider>
+ <slider
+ control_name="RenderAvatarLODFactor"
+ follows="left|top"
+ height="16"
+ increment="0.125"
+ initial_value="160"
+ label=" Avatars:"
+ label_width="140"
+ layout="topleft"
+ left_delta="0"
+ name="AvatarMeshDetail"
+ show_text="false"
+ top_pad="4"
+ width="223">
+ <slider.commit_callback
+ function="Pref.UpdateSliderText"
+ parameter="AvatarMeshDetailText" />
+ </slider>
+ <slider
+ control_name="RenderTerrainLODFactor"
+ follows="left|top"
+ height="16"
+ increment="0.125"
+ initial_value="160"
+ label=" Terrain:"
+ label_width="140"
+ layout="topleft"
+ left_delta="0"
+ max_val="2"
+ min_val="1"
+ name="TerrainMeshDetail"
+ show_text="false"
+ top_pad="4"
+ width="223">
+ <slider.commit_callback
+ function="Pref.UpdateSliderText"
+ parameter="TerrainMeshDetailText" />
+ </slider>
+ <slider
+ control_name="WLSkyDetail"
+ enabled_control="WindLightUseAtmosShaders"
+ decimal_digits="0"
+ follows="left|top"
+ height="16"
+ increment="8"
+ initial_value="160"
+ label=" Sky:"
+ label_width="140"
+ layout="topleft"
+ left_delta="0"
+ max_val="128"
+ min_val="16"
+ name="SkyMeshDetail"
+ show_text="false"
+ top_pad="4"
+ width="223">
+ <slider.commit_callback
+ function="Pref.UpdateSliderText"
+ parameter="SkyMeshDetailText" />
+ </slider>
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="12"
+ layout="topleft"
+ left="444"
+ name="PostProcessText"
+ top="305"
+ width="128">
+ Low
+ </text>
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="12"
+ layout="topleft"
+ left_delta="0"
+ name="ObjectMeshDetailText"
+ top_pad="26"
+ width="128">
+ Low
+ </text>
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="12"
+ layout="topleft"
+ left_delta="0"
+ name="FlexibleMeshDetailText"
+ top_pad="8"
+ width="128">
+ Low
+ </text>
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="12"
+ layout="topleft"
+ left_delta="0"
+ name="TreeMeshDetailText"
+ top_pad="8"
+ width="128">
+ Low
+ </text>
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="12"
+ layout="topleft"
+ left_delta="0"
+ name="AvatarMeshDetailText"
+ top_pad="8"
+ width="128">
+ Low
+ </text>
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="12"
+ layout="topleft"
+ left_delta="0"
+ name="TerrainMeshDetailText"
+ top_pad="8"
+ width="128">
+ Low
+ </text>
+ <text
+ enabled_control="WindLightUseAtmosShaders"
+ type="string"
+ length="1"
+ follows="left|top"
+ height="12"
+ layout="topleft"
+ left_delta="0"
+ name="SkyMeshDetailText"
+ top_pad="8"
+ width="128">
+ Low
+ </text>
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="12"
+ layout="topleft"
+ left_delta="-230"
+ name="LightingDetailText"
+ top_pad="8"
+ width="128">
+ Lighting Detail:
+ </text>
+ <radio_group
+ control_name="RenderLightingDetail"
+ draw_border="false"
+ height="38"
+ layout="topleft"
+ left_delta="0"
+ name="LightingDetailRadio"
+ top_pad="5"
+ width="321">
+ <radio_item
+ height="16"
+ label="Sun and moon only"
+ layout="topleft"
+ left="3"
+ name="SunMoon"
+ top="3"
+ width="156" />
+ <radio_item
+ height="16"
+ label="Nearby local lights"
+ layout="topleft"
+ left_delta="0"
+ name="LocalLights"
+ top_delta="16"
+ width="156" />
+ </radio_group>
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="12"
+ layout="topleft"
+ left="360"
+ name="TerrainDetailText"
+ top="465"
+ width="128">
+ Terrain Detail:
+ </text>
+ <radio_group
+ control_name="RenderTerrainDetail"
+ draw_border="false"
+ height="38"
+ layout="topleft"
+ left_delta="0"
+ name="TerrainDetailRadio"
+ top_pad="5"
+ width="321">
+ <radio_item
+ height="16"
+ label="Low"
+ layout="topleft"
+ left="3"
+ name="0"
+ top="3"
+ width="315" />
+ <radio_item
+ height="16"
+ label="High"
+ layout="topleft"
+ left_delta="0"
+ name="2"
+ top_delta="16"
+ width="315" />
+ </radio_group>
+ </panel>
+ <button
+ follows="left|bottom"
+ height="20"
+ label="Apply"
+ label_selected="Apply"
+ layout="topleft"
+ left="10"
+ name="Apply"
+ top="383"
+ width="115">
+ <button.commit_callback
+ function="Pref.Apply" />
+ </button>
+ <button
+ follows="left|bottom"
+ height="20"
+ label="Reset"
+ layout="topleft"
+ left_pad="3"
+ name="Defaults"
+ top="383"
+ width="115">
+ <button.commit_callback
+ function="Pref.HardwareDefaults" />
+ </button>
+ <button
+ control_name="ShowAdvancedGraphicsSettings"
+ follows="right|bottom"
+ height="20"
+ is_toggle="true"
+ label="Advanced"
+ layout="topleft"
+ left_pad="35"
+ name="Advanced"
+ top_delta="0"
+ width="115" />
+ <button
+ follows="right|bottom"
+ height="20"
+ label="Hardware"
+ label_selected="Hardware"
+ layout="topleft"
+ left_pad="3"
+ name="GraphicsHardwareButton"
+ top_delta="0"
+ width="115">
+ <button.commit_callback
+ function="Pref.HardwareSettings" />
+ </button>
+</panel>
diff --git a/indra/newview/skins/default/xui/en/panel_profile.xml b/indra/newview/skins/default/xui/en/panel_profile.xml
new file mode 100644
index 0000000000..01602dc906
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/panel_profile.xml
@@ -0,0 +1,383 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<panel
+ bevel_style="out"
+ follows="left|top|right|bottom"
+ height="420"
+ label="Profile"
+ layout="topleft"
+ left="0"
+ name="panel_profile"
+ top="0"
+ width="255">
+ <string
+ name="CaptionTextAcctInfo">
+ [ACCTTYPE] [PAYMENTINFO] [AGEVERIFICATION]
+ </string>
+ <string
+ name="AcctTypeResident"
+ value="Resident" />
+ <string
+ name="AcctTypeTrial"
+ value="Trial" />
+ <string
+ name="AcctTypeCharterMember"
+ value="Charter Member" />
+ <string
+ name="AcctTypeEmployee"
+ value="Linden Lab Employee" />
+ <string
+ name="PaymentInfoUsed"
+ value="Payment Info Used" />
+ <string
+ name="PaymentInfoOnFile"
+ value="Payment Info On File" />
+ <string
+ name="NoPaymentInfoOnFile"
+ value="No Payment Info On File" />
+ <string
+ name="AgeVerified"
+ value="Age-verified" />
+ <string
+ name="NotAgeVerified"
+ value="Not Age-verified" />
+ <string
+ name="payment_update_link_url">
+ http://www.secondlife.com/account/billing.php?lang=en
+ </string>
+ <string
+ name="my_account_link_url"
+ value="http://secondlife.com/account" />
+ <string
+ name="partner_edit_link_url">
+ http://www.secondlife.com/account/partners.php?lang=en
+ </string>
+ <string
+ name="no_partner_text"
+ value="None" />
+ <scroll_container
+ color="DkGray2"
+ follows="left|top|right|bottom"
+ height="300"
+ layout="topleft"
+ left="0"
+ name="profile_scroll"
+ reserve_scroll_corner="true"
+ opaque="true"
+ width="255">
+ <panel
+ name="scroll_content_panel"
+ follows="left|top|right"
+ layout="topleft"
+ top="0"
+ left="0"
+ width="240"
+ height="780">
+ <panel
+ follows="left|top"
+ height="117"
+ layout="topleft"
+ left="10"
+ name="second_life_image_panel"
+ top="10"
+ width="260">
+ <texture_picker
+ allow_no_texture="true"
+ default_image_name="None"
+ enabled="false"
+ follows="top|left"
+ height="117"
+ layout="topleft"
+ left="0"
+ name="2nd_life_pic"
+ top="10"
+ width="102" />
+ <text
+ follows="left|top|right"
+ font="SansSerifSmall"
+ font.style="BOLD"
+ height="15"
+ layout="topleft"
+ left_pad="10"
+ name="title_sl_descr_text"
+ text_color="white"
+ top_delta="0"
+ value="[SECOND_LIFE]:"
+ width="130" />
+ <text
+ follows="left|top|right"
+ height="70"
+ layout="topleft"
+ name="sl_description_edit"
+ width="130"
+ word_wrap="true">
+ Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aenean viverra orci et justo sagittis aliquet. Nullam malesuada mauris sit amet ipsum. adipiscing elit. Aenean viverra orci et justo sagittis aliquet. Nullam malesuada mauris sit amet ipsum. adipiscing elit. Aenean viverra orci et justo sagittis aliquet. Nullam malesuada mauris sit amet ipsum.
+ </text>
+ </panel>
+ <panel
+ follows="left|top"
+ height="117"
+ layout="topleft"
+ top_pad="10"
+ left="10"
+ name="first_life_image_panel"
+ width="260">
+ <texture_picker
+ allow_no_texture="true"
+ default_image_name="None"
+ enabled="false"
+ follows="top|left"
+ height="117"
+ layout="topleft"
+ left="0"
+ name="real_world_pic"
+ width="102" />
+ <text
+ follows="left|top|right"
+ font="SansSerifSmall"
+ font.style="BOLD"
+ height="15"
+ layout="topleft"
+ left_pad="10"
+ name="title_rw_descr_text"
+ text_color="white"
+ top_delta="0"
+ value="Real World:"
+ width="130" />
+ <text
+ follows="left|top|right"
+ height="70"
+ layout="topleft"
+ name="fl_description_edit"
+ width="130"
+ word_wrap="true">
+ Lorem ipsum dolor sit amet, consectetur adlkjpiscing elit moose moose. Aenean viverra orci et justo sagittis aliquet. Nullam malesuada mauris sit amet. adipiscing elit. Aenean rigviverra orci et justo sagittis aliquet. Nullam malesuada mauris sit amet sorbet ipsum. adipiscing elit. Aenean viverra orci et justo sagittis aliquet. Nullam malesuada mauris sit amet ipsum.
+ </text>
+ </panel>
+ <text
+ type="string"
+ follows="left|top"
+ font="SansSerifSmall"
+ font.style="BOLD"
+ height="15"
+ layout="topleft"
+ left="10"
+ name="me_homepage_text"
+ text_color="white"
+ top_pad="10"
+ width="255">
+ Homepage:
+ </text>
+ <link
+ follows="left|top|right"
+ height="15"
+ layout="topleft"
+ font.style="UNDERLINE"
+ left="10"
+ name="homepage_edit"
+ top_pad="5"
+ value="http://librarianavengers.org"
+ width="225"
+ word_wrap="false" />
+ <text
+ follows="left|top"
+ font="SansSerifSmall"
+ font.style="BOLD"
+ height="15"
+ layout="topleft"
+ left="10"
+ name="title_member_text"
+ text_color="white"
+ top_pad="20"
+ value="Member Since:"
+ width="255" />
+ <text
+ follows="left|top|right"
+ height="15"
+ layout="topleft"
+ left="10"
+ name="register_date"
+ top_pad="5"
+ value="05/31/1976"
+ width="160"
+ word_wrap="true" />
+ <text
+ follows="left|top"
+ font="SansSerifSmall"
+ font.style="BOLD"
+ height="15"
+ layout="topleft"
+ left="10"
+ name="title_acc_status_text"
+ text_color="white"
+ top_pad="15"
+ value="Account Status:"
+ width="100" />
+ <link
+ type="string"
+ follows="left|top"
+ font="SansSerifSmall"
+ font.style="UNDERLINE"
+ height="15"
+ layout="topleft"
+ left_pad="10"
+ name="my_account_link"
+ top_delta="0"
+ value="Go to Dashboard"
+ width="100"/>
+ <text
+ follows="left|top|right"
+ height="15"
+ layout="topleft"
+ left="10"
+ name="acc_status_text"
+ top_pad="5"
+ value="Resident. No payment info on file."
+ width="255"
+ word_wrap="true" />
+ <text
+ follows="left|top"
+ font="SansSerifSmall"
+ font.style="BOLD"
+ height="15"
+ layout="topleft"
+ left="10"
+ name="title_partner_text"
+ text_color="white"
+ top_pad="15"
+ value="Partner:"
+ width="100" />
+ <link
+ follows="left|top"
+ height="15"
+ font.style="UNDERLINE"
+ layout="topleft"
+ left_pad="10"
+ name="partner_edit_link"
+ top_delta="0"
+ value="Edit"
+ width="100" />
+ <panel
+ follows="left|top|right"
+ height="15"
+ layout="topleft"
+ left="10"
+ name="partner_data_panel"
+ top_pad="10"
+ width="255">
+ <text
+ follows="left|top|right"
+ height="30"
+ layout="topleft"
+ left="0"
+ name="partner_text"
+ top="0"
+ value="[FIRST] [LAST]"
+ width="240"
+ word_wrap="true" />
+ </panel>
+ <text
+ follows="left|top"
+ font="SansSerifSmall"
+ font.style="BOLD"
+ height="15"
+ layout="topleft"
+ left="10"
+ name="title_groups_text"
+ text_color="white"
+ top_pad="15"
+ value="Groups:"
+ width="255" />
+ <text
+ follows="left|top|right|bottom"
+ height="160"
+ layout="topleft"
+ left="10"
+ name="sl_groups"
+ top_pad="5"
+ width="130"
+ word_wrap="true">
+ Lorem ipsum dolor sit amet, consectetur adlkjpiscing elit moose moose. Aenean viverra orci et justo sagittis aliquet. Nullam malesuada mauris sit amet. adipiscing elit. Aenean rigviverra orci et justo sagittis aliquet. Nullam malesuada mauris sit amet sorbet ipsum. adipiscing elit. Aenean viverra orci et justo sagittis aliquet. Nullam malesuada mauris sit amet ipsum.
+ </text>
+ </panel>
+ </scroll_container>
+ <panel
+ follows="bottom|left"
+ height="30"
+ layout="topleft"
+ left="10"
+ name="profile_buttons_panel"
+ top_pad="5"
+ width="280">
+ <button
+ follows="bottom|left"
+ font="SansSerifSmallBold"
+ height="25"
+ label="Add Friend"
+ layout="topleft"
+ left="0"
+ mouse_opaque="false"
+ name="add_friend"
+ top="0"
+ width="90" />
+ <button
+ follows="bottom|left"
+ font="SansSerifSmallBold"
+ height="25"
+ label="IM"
+ layout="topleft"
+ name="im"
+ top="0"
+ left_pad="0"
+ width="40" />
+ <button
+ enabled="false"
+ follows="bottom|left"
+ font="SansSerifSmallBold"
+ height="25"
+ label="Call"
+ layout="topleft"
+ name="call"
+ left_pad="0"
+ top="0"
+ width="50" />
+ <button
+ follows="bottom|left"
+ font="SansSerifSmallBold"
+ height="25"
+ label="Teleport"
+ layout="topleft"
+ name="teleport"
+ left_pad="0"
+ top="0"
+ width="75" />
+ </panel>
+ <panel
+ height="30"
+ layout="topleft"
+ left="10"
+ name="profile_me_buttons_panel"
+ top_pad="5"
+ visible="false"
+ width="280">
+ <button
+ follows="bottom|left"
+ font="SansSerifSmallBold"
+ height="25"
+ label="Edit Profile"
+ layout="topleft"
+ left="0"
+ name="edit_profile_btn"
+ top="0"
+ width="130" />
+ <button
+ follows="bottom|left"
+ font="SansSerifSmallBold"
+ height="25"
+ label="Edit Appearance"
+ layout="topleft"
+ left_pad="5"
+ name="edit_appearance_btn"
+ top="0"
+ width="130" />
+ </panel>
+</panel>
diff --git a/indra/newview/skins/default/xui/en/panel_profile_view.xml b/indra/newview/skins/default/xui/en/panel_profile_view.xml
new file mode 100644
index 0000000000..32223d542d
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/panel_profile_view.xml
@@ -0,0 +1,72 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<panel
+ background_visible="true"
+ follows="all"
+ height="660"
+ layout="topleft"
+ min_height="350"
+ min_width="240"
+ name="panel_target_profile"
+ width="305">
+ <text
+ follows="top|left|right"
+ font="SansSerifHugeBold"
+ height="20"
+ layout="topleft"
+ left="10"
+ name="user_name"
+ text_color="white"
+ top="0"
+ value="(Loading...)"
+ width="250" />
+ <text
+ follows="top|left"
+ height="16"
+ layout="topleft"
+ left="10"
+ name="status"
+ text_color="LtGray_50"
+ top_pad="5"
+ value="Online"
+ width="100" />
+ <button
+ follows="top|right"
+ height="25"
+ image_overlay="BackArrow_Off"
+ layout="topleft"
+ name="back"
+ picture_style="true"
+ right="-10"
+ tab_stop="false"
+ top="0"
+ width="25" />
+ <tab_container
+ follows="left|top|right|bottom"
+ height="660"
+ layout="topleft"
+ left="10"
+ name="tabs"
+ tab_min_width="75"
+ tab_position="top"
+ top_pad="15"
+ width="285">
+ <panel
+ class="panel_profile"
+ filename="panel_profile.xml"
+ label="Profile"
+ layout="topleft"
+ name="panel_profile" />
+ <panel
+ class="panel_picks"
+ filename="panel_picks.xml"
+ label="Picks"
+ layout="topleft"
+ name="panel_picks" />
+ <panel
+ class="panel_notes"
+ filename="panel_notes.xml"
+ label="Notes &amp; Privacy"
+ layout="topleft"
+ name="panel_notes" />
+ </tab_container>
+</panel>
diff --git a/indra/newview/skins/default/xui/en/panel_progress.xml b/indra/newview/skins/default/xui/en/panel_progress.xml
new file mode 100644
index 0000000000..4f23c4d26d
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/panel_progress.xml
@@ -0,0 +1,133 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<panel
+ follows="left|bottom|right|top"
+ height="768"
+ layout="topleft"
+ left="0"
+ name="login_progress_panel"
+ top="768"
+ width="1024">
+ <layout_stack
+ follows="left|right|top|bottom"
+ height="768"
+ layout="topleft"
+ left="0"
+ name="stack1"
+ orientation="horizontal"
+ top="0"
+ width="1024">
+ <layout_panel
+ layout="topleft"
+ min_width="10"
+ name="panel1"
+ user_resize="false"
+ width="150" />
+ <layout_panel
+ height="768"
+ layout="topleft"
+ min_width="640"
+ name="panel2"
+ user_resize="false"
+ width="640">
+ <layout_stack
+ follows="left|right|top|bottom"
+ height="768"
+ layout="topleft"
+ left="0"
+ name="stack2"
+ top="0"
+ width="640">
+ <layout_panel
+ height="200"
+ layout="topleft"
+ min_height="10"
+ name="panel3"
+ width="640" />
+ <layout_panel
+ auto_resize="false"
+ height="250"
+ layout="topleft"
+ min_height="250"
+ name="panel4"
+ width="640">
+ <icon
+ color="LoginProgressBoxCenterColor"
+ follows="left|right|bottom|top"
+ height="250"
+ image_name="rounded_square.tga"
+ layout="topleft"
+ left="0"
+ top="0"
+ width="640" />
+ <text
+ follows="left|right|top"
+ font="SansSerifHuge"
+ font_shadow="hard"
+ halign="left"
+ height="20"
+ layout="topleft"
+ left_delta="47"
+ name="title_text"
+ text_color="LoginProgressBoxTextColor"
+ top_delta="50"
+ width="593" />
+ <text
+ follows="left|right|top"
+ font="SansSerif"
+ font_shadow="hard"
+ halign="left"
+ height="20"
+ layout="topleft"
+ left_delta="0"
+ name="progress_text"
+ text_color="LoginProgressBoxTextColor"
+ top_pad="5"
+ width="593" />
+ <progress_bar
+ bottom="115"
+ color_bar="1 1 1 0.96"
+ follows="left|right|top"
+ height="16"
+ layout="topleft"
+ left="45"
+ name="login_progress_bar"
+ right="-45" />
+ <text
+ follows="left|right|top|bottom"
+ font="SansSerifLarge"
+ font_shadow="hard"
+ halign="left"
+ height="100"
+ layout="topleft"
+ left="30"
+ line_spacing="2"
+ name="message_text"
+ text_color="LoginProgressBoxTextColor"
+ top="145"
+ width="610" />
+ </layout_panel>
+ <layout_panel
+ height="200"
+ layout="topleft"
+ min_width="10"
+ name="panel5"
+ width="640" />
+ </layout_stack>
+ </layout_panel>
+ <layout_panel
+ layout="topleft"
+ min_width="10"
+ name="panel6"
+ user_resize="false"
+ width="150" />
+ </layout_stack>
+ <button
+ follows="right|bottom"
+ height="22"
+ layout="topleft"
+ left="-106"
+ name="cancel_btn"
+ picture_style="true"
+ top="700"
+ width="90" />
+</panel>
diff --git a/indra/newview/skins/default/xui/en/panel_region_covenant.xml b/indra/newview/skins/default/xui/en/panel_region_covenant.xml
new file mode 100644
index 0000000000..8445b933bf
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/panel_region_covenant.xml
@@ -0,0 +1,333 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<panel
+ border="true"
+ follows="top|left"
+ height="350"
+ label="Covenant"
+ layout="topleft"
+ left="0"
+ name="Covenant"
+ top="320"
+ width="280">
+ <panel.string
+ name="can_resell">
+ Purchased land in this region may be resold.
+ </panel.string>
+ <panel.string
+ name="can_not_resell">
+ Purchased land in this region may not be resold.
+ </panel.string>
+ <panel.string
+ name="can_change">
+ Purchased land in this region may be joined or subdivided.
+ </panel.string>
+ <panel.string
+ name="can_not_change">
+ Purchased land in this region may not be joined or subdivided.
+ </panel.string>
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ font="SansSerif"
+ height="20"
+ layout="topleft"
+ left="5"
+ mouse_opaque="false"
+ name="estate_section_lbl"
+ top="5"
+ width="100">
+ Estate
+ </text>
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="20"
+ layout="topleft"
+ left="10"
+ mouse_opaque="false"
+ name="estate_name_lbl"
+ top_pad="5"
+ width="75">
+ Name:
+ </text>
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="20"
+ layout="topleft"
+ left_pad="0"
+ mouse_opaque="false"
+ name="estate_name_text"
+ top_delta="0"
+ width="150">
+ mainland
+ </text>
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="20"
+ layout="topleft"
+ left="10"
+ mouse_opaque="false"
+ name="estate_owner_lbl"
+ top_pad="5"
+ width="75">
+ Owner:
+ </text>
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="20"
+ layout="topleft"
+ left_pad="0"
+ mouse_opaque="false"
+ name="estate_owner_text"
+ top_delta="0"
+ width="150">
+ (none)
+ </text>
+
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="20"
+ layout="topleft"
+ left="10"
+ mouse_opaque="false"
+ name="estate_cov_lbl"
+ top_pad="5"
+ width="75">
+ Covenant:
+ </text>
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="20"
+ layout="topleft"
+ left_pad="0"
+ mouse_opaque="false"
+ name="covenant_timestamp_text"
+ top_delta="0"
+ width="167">
+ Last Modified Wed Dec 31 16:00:00 1969
+ </text>
+ <button
+ follows="left|top"
+ font="SansSerifSmall"
+ height="18"
+ label="?"
+ layout="topleft"
+ left_pad="5"
+ name="covenant_help"
+ top_delta="-2"
+ width="18" />
+
+ <text_editor
+ type="string"
+ length="1"
+ enabled="false"
+ follows="left|top"
+ height="100"
+ layout="topleft"
+ left="80"
+ max_length="65535"
+ name="covenant_editor"
+ top_delta="30"
+ handle_edit_keys_directly="true"
+ width="193"
+ word_wrap="true">
+ There is no Covenant provided for this Estate.
+ </text_editor>
+ <button
+ follows="left|top"
+ font="SansSerifSmall"
+ height="18"
+ label="Reset"
+ layout="topleft"
+ left_delta="75"
+ name="reset_covenant"
+ top_pad="5"
+ width="90" />
+
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="20"
+ layout="topleft"
+ left="85"
+ name="covenant_help_text"
+ top_pad="10"
+ width="190">
+ Changes to the covenant will show
+on all parcels in the estate.
+ </text>
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="16"
+ layout="topleft"
+ left_delta="0"
+ name="covenant_instructions"
+ top_pad="15"
+ width="190">
+ Drag and drop a notecard to change
+the Covenant for this Estate.
+ </text>
+
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ font="SansSerif"
+ height="20"
+ layout="topleft"
+ left="5"
+ mouse_opaque="false"
+ name="region_section_lbl"
+ top_pad="10"
+ width="100">
+ Region
+ </text>
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="20"
+ layout="topleft"
+ left="10"
+ mouse_opaque="false"
+ name="region_name_lbl"
+ top_pad="5"
+ width="75">
+ Name:
+ </text>
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="20"
+ layout="topleft"
+ left_pad="0"
+ mouse_opaque="false"
+ name="region_name_text"
+ top_delta="0"
+ width="150">
+ leyla
+ </text>
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="20"
+ layout="topleft"
+ left="10"
+ mouse_opaque="false"
+ name="region_landtype_lbl"
+ top_pad="5"
+ width="75">
+ Type:
+ </text>
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="20"
+ layout="topleft"
+ left_pad="0"
+ mouse_opaque="false"
+ name="region_landtype_text"
+ top_delta="0"
+ width="150">
+ Mainland / Homestead
+ </text>
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="20"
+ layout="topleft"
+ left="10"
+ mouse_opaque="false"
+ name="region_maturity_lbl"
+ top_pad="5"
+ width="75">
+ Rating:
+ </text>
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="20"
+ layout="topleft"
+ left_pad="0"
+ mouse_opaque="false"
+ name="region_maturity_text"
+ top_delta="0"
+ width="150">
+ Adult
+ </text>
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="20"
+ layout="topleft"
+ left="10"
+ mouse_opaque="false"
+ name="resellable_lbl"
+ top_pad="5"
+ width="75">
+ Resale:
+ </text>
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="20"
+ layout="topleft"
+ left_pad="0"
+ mouse_opaque="false"
+ name="resellable_clause"
+ top_delta="0"
+ width="190">
+ Land in this region may not be
+resold.
+ </text>
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="20"
+ layout="topleft"
+ left="10"
+ mouse_opaque="false"
+ name="changeable_lbl"
+ top_pad="10"
+ width="75">
+ Subdivide:
+ </text>
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="30"
+ layout="topleft"
+ left_pad="0"
+ mouse_opaque="false"
+ name="changeable_clause"
+ top_delta="0"
+ width="190">
+ Land in this region may not be
+joined/subdivided.
+ </text>
+
+</panel>
diff --git a/indra/newview/skins/default/xui/en/panel_region_debug.xml b/indra/newview/skins/default/xui/en/panel_region_debug.xml
new file mode 100644
index 0000000000..6a43bf3c4b
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/panel_region_debug.xml
@@ -0,0 +1,279 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<panel
+ border="true"
+ follows="top|left"
+ height="320"
+ label="Debug"
+ layout="topleft"
+ left="0"
+ name="Debug"
+ top="320"
+ width="280">
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ font="SansSerif"
+ height="20"
+ layout="topleft"
+ left="10"
+ name="region_text_lbl"
+ top="10"
+ width="100">
+ Region:
+ </text>
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ font="SansSerif"
+ height="20"
+ layout="topleft"
+ left_delta="50"
+ name="region_text"
+ top_delta="0"
+ width="220">
+ unknown
+ </text>
+ <check_box
+ height="20"
+ label="Disable Scripts"
+ layout="topleft"
+ left="10"
+ name="disable_scripts_check"
+ tool_tip="Disable all scripts in this region"
+ top="30"
+ width="80" />
+ <button
+ follows="left|top"
+ font="SansSerifSmall"
+ height="18"
+ label="?"
+ layout="topleft"
+ left_pad="70"
+ name="disable_scripts_help"
+ top_delta="2"
+ width="18" />
+ <check_box
+ height="20"
+ label="Disable Collisions"
+ layout="topleft"
+ left="10"
+ name="disable_collisions_check"
+ tool_tip="Disable non-avatar collisions in this region"
+ top="50"
+ width="80" />
+ <button
+ follows="left|top"
+ font="SansSerifSmall"
+ height="18"
+ label="?"
+ layout="topleft"
+ left_pad="70"
+ name="disable_collisions_help"
+ top_delta="2"
+ width="18" />
+ <check_box
+ height="20"
+ label="Disable Physics"
+ layout="topleft"
+ left="10"
+ name="disable_physics_check"
+ tool_tip="Disable all physics in this region"
+ top="70"
+ width="80" />
+ <button
+ follows="left|top"
+ font="SansSerifSmall"
+ height="18"
+ label="?"
+ layout="topleft"
+ left_pad="70"
+ name="disable_physics_help"
+ top_delta="2"
+ width="18" />
+ <button
+ enabled="false"
+ follows="left|top"
+ height="20"
+ font="SansSerifSmall"
+ label="Apply"
+ layout="topleft"
+ left="60"
+ name="apply_btn"
+ top="100"
+ width="80" />
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="20"
+ layout="topleft"
+ left="10"
+ name="objret_text_lbl"
+ top="150"
+ width="90">
+ Object Return
+ </text>
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="20"
+ layout="topleft"
+ left="20"
+ name="resident_text_lbl"
+ top="175"
+ width="60">
+ Resident:
+ </text>
+ <line_editor
+ type="string"
+ length="1"
+ border_style="line"
+ border_thickness="1"
+ enabled="false"
+ follows="left|top"
+ height="20"
+ layout="topleft"
+ left_delta="60"
+ mouse_opaque="false"
+ name="target_avatar_name"
+ top_delta="-2"
+ width="115">
+ (none)
+ </line_editor>
+ <button
+ follows="left|top"
+ height="20"
+ font="SansSerifSmall"
+ label="Choose"
+ layout="topleft"
+ left_pad="5"
+ name="choose_avatar_btn"
+ top_delta="0"
+ width="70" />
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="20"
+ layout="topleft"
+ left="20"
+ name="options_text_lbl"
+ top="198"
+ width="60">
+ Options:
+ </text>
+ <check_box
+ height="20"
+ label="With scripts"
+ layout="topleft"
+ left_delta="60"
+ name="return_scripts"
+ tool_tip="Return only objects which have scripts."
+ top_delta="0"
+ width="80" />
+ <check_box
+ height="20"
+ label="On someone else&apos;s land"
+ layout="topleft"
+ left_delta="0"
+ name="return_other_land"
+ tool_tip="Return only objects which are on land belonging to someone else"
+ top_delta="20"
+ width="80" />
+ <check_box
+ height="20"
+ label="In every region of this estate"
+ layout="topleft"
+ left_delta="0"
+ name="return_estate_wide"
+ tool_tip="Return objects in all of the regions that make up this estate"
+ top_delta="20"
+ width="80" />
+ <button
+ follows="left|top"
+ height="20"
+ font="SansSerifSmall"
+ label="Return"
+ layout="topleft"
+ left="20"
+ name="return_btn"
+ top="263"
+ width="80" />
+ <button
+ follows="left|top"
+ height="20"
+ font="SansSerifSmall"
+ label="Get Top Colliders..."
+ layout="topleft"
+ left="10"
+ name="top_colliders_btn"
+ tool_tip="List of objects experiencing the most potential collisions"
+ top="313"
+ width="130" />
+ <button
+ follows="left|top"
+ font="SansSerifSmall"
+ height="18"
+ label="?"
+ layout="topleft"
+ left_pad="10"
+ name="top_colliders_help"
+ top_delta="2"
+ width="18" />
+ <button
+ follows="left|top"
+ height="20"
+ font="SansSerifSmall"
+ label="Get Top Scripts..."
+ layout="topleft"
+ left="10"
+ name="top_scripts_btn"
+ tool_tip="List of objects spending the most time running scripts"
+ top_pad="5"
+ width="130" />
+ <button
+ follows="left|top"
+ font="SansSerifSmall"
+ height="18"
+ label="?"
+ layout="topleft"
+ left_pad="10"
+ name="top_scripts_help"
+ top_delta="2"
+ width="18" />
+ <button
+ follows="left|top"
+ height="20"
+ font="SansSerifSmall"
+ label="Restart Region"
+ layout="topleft"
+ left="10"
+ name="restart_btn"
+ tool_tip="Give 2 minute countdown and restart region"
+ top_pad="5"
+ width="110" />
+ <button
+ follows="left|top"
+ font="SansSerifSmall"
+ height="18"
+ label="?"
+ layout="topleft"
+ left_pad="10"
+ name="restart_help"
+ top_delta="2"
+ width="18" />
+ <button
+ follows="left|top"
+ height="20"
+ font="SansSerifSmall"
+ label="Delay Restart"
+ layout="topleft"
+ left="10"
+ name="cancel_restart_btn"
+ tool_tip="Delay region restart by one hour"
+ top_pad="5"
+ width="110" />
+</panel>
diff --git a/indra/newview/skins/default/xui/en/panel_region_estate.xml b/indra/newview/skins/default/xui/en/panel_region_estate.xml
new file mode 100644
index 0000000000..c905e0e42c
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/panel_region_estate.xml
@@ -0,0 +1,531 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<panel
+ border="true"
+ follows="top|left"
+ height="512"
+ name="EstateWrapper"
+ label="Estate"
+ layout="topleft"
+ width="280">
+ <scroll_container
+ follows="top|left|right|bottom"
+ height="508"
+ name="container1"
+ layout="topleft"
+ width="280">
+ <panel
+ follows="top|left"
+ height="950"
+ label="Estate"
+ layout="topleft"
+ name="Estate"
+ width="258">
+ <panel.string
+ name="email_unsupported">
+ Feature unsupported
+ </panel.string>
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="32"
+ layout="topleft"
+ left="10"
+ name="estate_help_text"
+ top="14"
+ width="300">
+ Changes to settings on this tab will affect all
+ regions in the estate.
+ </text>
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ font="SansSerif"
+ height="20"
+ layout="topleft"
+ left_delta="0"
+ name="estate_text"
+ top_pad="2"
+ width="80">
+ Estate:
+ </text>
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ font="SansSerif"
+ height="20"
+ layout="topleft"
+ left_delta="0"
+ name="estate_name"
+ top_delta="16"
+ width="150">
+ (unknown)
+ </text>
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ font="SansSerif"
+ height="20"
+ layout="topleft"
+ left_delta="0"
+ name="owner_text"
+ top_pad="2"
+ width="80">
+ Owner:
+ </text>
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ font="SansSerif"
+ height="20"
+ layout="topleft"
+ left_delta="0"
+ name="estate_owner"
+ top_delta="16"
+ width="150">
+ (unknown)
+ </text>
+ <view_border
+ bevel_style="in"
+ follows="top|left"
+ height="290"
+ layout="topleft"
+ left_delta="-4"
+ top_pad="5"
+ width="250" />
+ <check_box
+ height="20"
+ label="Use Global Time"
+ layout="topleft"
+ left="12"
+ name="use_global_time_check"
+ top="132"
+ width="200" />
+ <button
+ follows="left|top"
+ font="SansSerifSmall"
+ height="18"
+ label="?"
+ layout="topleft"
+ left_pad="20"
+ name="use_global_time_help"
+ top_delta="2"
+ width="18" />
+ <check_box
+ height="20"
+ label="Fixed Sun"
+ layout="topleft"
+ left="12"
+ name="fixed_sun_check"
+ top="152"
+ width="100" />
+ <button
+ follows="left|top"
+ font="SansSerifSmall"
+ height="18"
+ label="?"
+ layout="topleft"
+ left_pad="120"
+ name="fixed_sun_help"
+ top_delta="2"
+ width="18" />
+ <icon
+ height="20"
+ image_name="icon_day_cycle.tga"
+ layout="topleft"
+ left="47"
+ name="daycycle"
+ top="177"
+ width="165" />
+ <slider
+ follows="left|top"
+ height="20"
+ increment="0.001"
+ label="Phase"
+ layout="topleft"
+ left="12"
+ max_val="30"
+ min_val="6"
+ name="sun_hour_slider"
+ show_text="false"
+ top="202"
+ width="200" />
+ <check_box
+ height="20"
+ label="Allow Public Access"
+ layout="topleft"
+ left_delta="0"
+ name="externally_visible_check"
+ top_pad="6"
+ width="200" />
+ <button
+ follows="left|top"
+ font="SansSerifSmall"
+ height="18"
+ label="?"
+ layout="topleft"
+ left_pad="20"
+ name="externally_visible_help"
+ top_delta="2"
+ width="18" />
+ <text
+ type="string"
+ length="1"
+ follows="top|left"
+ height="16"
+ layout="topleft"
+ left="32"
+ name="Only Allow"
+ top="250"
+ width="278">
+ Restrict Access To:
+ </text>
+ <check_box
+ follows="top|left"
+ height="16"
+ label="Residents with payment info on file"
+ layout="topleft"
+ left_delta="0"
+ name="limit_payment"
+ tool_tip="Ban unidentified residents."
+ top_pad="2"
+ width="278" />
+ <check_box
+ follows="top|left"
+ height="16"
+ label="Age-verified adults"
+ layout="topleft"
+ left_delta="0"
+ name="limit_age_verified"
+ tool_tip="Ban residents who have not verified their age. See the [SUPPORT_SITE] for more information."
+ top_pad="2"
+ width="278" />
+ <check_box
+ height="20"
+ label="Allow Voice Chat"
+ layout="topleft"
+ left="12"
+ name="voice_chat_check"
+ top="304"
+ width="200" />
+ <button
+ follows="left|top"
+ font="SansSerifSmall"
+ height="18"
+ label="?"
+ layout="topleft"
+ left_pad="20"
+ name="voice_chat_help"
+ top_delta="2"
+ width="18" />
+ <check_box
+ height="20"
+ label="Allow Direct Teleport"
+ layout="topleft"
+ left="12"
+ name="allow_direct_teleport"
+ top_pad="4"
+ width="80" />
+ <button
+ follows="left|top"
+ font="SansSerifSmall"
+ height="18"
+ label="?"
+ layout="topleft"
+ left_pad="140"
+ name="allow_direct_teleport_help"
+ top_delta="2"
+ width="18" />
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="20"
+ layout="topleft"
+ left="10"
+ name="abuse_email_text"
+ top_pad="5"
+ width="180">
+ Abuse email address:
+ </text>
+ <line_editor
+ follows="top|left"
+ height="19"
+ layout="topleft"
+ left="15"
+ name="abuse_email_address"
+ top_pad="5"
+ width="205" />
+ <button
+ follows="left|top"
+ font="SansSerifSmall"
+ height="18"
+ label="?"
+ layout="topleft"
+ left_pad="12"
+ name="abuse_email_address_help"
+ top_delta="0"
+ width="18" />
+ <button
+ enabled="false"
+ follows="left|top"
+ height="20"
+ label="Apply"
+ layout="topleft"
+ name="apply_btn"
+ right="250"
+ top_pad="4"
+ width="90" />
+ <button
+ follows="left|top"
+ height="20"
+ label="Send Message To Estate..."
+ layout="topleft"
+ left="8"
+ name="message_estate_btn"
+ top_pad="5"
+ width="250" />
+ <button
+ follows="left|top"
+ height="20"
+ label="Kick User from Estate..."
+ layout="topleft"
+ left="8"
+ name="kick_user_from_estate_btn"
+ top_pad="5"
+ width="250" />
+ <text
+ type="string"
+ length="1"
+ top="490"
+ follows="left|top"
+ height="20"
+ layout="topleft"
+ name="estate_manager_label"
+ left="8"
+ width="200">
+ Estate Managers:
+ </text>
+ <button
+ follows="left|top"
+ font="SansSerifSmall"
+ height="18"
+ label="?"
+ layout="topleft"
+ left_delta="232"
+ name="estate_manager_help"
+ top_delta="-1"
+ width="18" />
+ <view_border
+ bevel_style="none"
+ follows="top|left"
+ height="60"
+ layout="topleft"
+ left="8"
+ top_pad="5"
+ width="250" />
+ <name_list
+ follows="left|top"
+ height="60"
+ layout="topleft"
+ left_delta="0"
+ multi_select="true"
+ name="estate_manager_name_list"
+ top_delta="0"
+ width="250" />
+ <button
+ follows="left|top"
+ height="20"
+ label="Add..."
+ layout="topleft"
+ left="8"
+ name="add_estate_manager_btn"
+ top_pad="5"
+ width="90" />
+ <button
+ follows="left|top"
+ height="20"
+ label="Remove..."
+ layout="topleft"
+ name="remove_estate_manager_btn"
+ left_pad="70"
+ top_delta="0"
+ width="90" />
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="20"
+ layout="topleft"
+ left="8"
+ name="allow_resident_label"
+ top_pad="5"
+ width="200">
+ Allowed Residents:
+ </text>
+ <button
+ follows="left|top"
+ font="SansSerifSmall"
+ height="18"
+ label="?"
+ layout="topleft"
+ left_delta="232"
+ name="allow_resident_help"
+ top_delta="-1"
+ width="18" />
+ <view_border
+ bevel_style="none"
+ follows="top|left"
+ height="60"
+ layout="topleft"
+ left="8"
+ top_pad="5"
+ width="250" />
+ <name_list
+ follows="left|top"
+ height="60"
+ layout="topleft"
+ left_delta="0"
+ multi_select="true"
+ name="allowed_avatar_name_list"
+ top_delta="0"
+ width="250" />
+ <button
+ follows="left|top"
+ height="20"
+ label="Add..."
+ layout="topleft"
+ left="8"
+ name="add_allowed_avatar_btn"
+ top_pad="5"
+ width="90" />
+ <button
+ follows="left|top"
+ height="20"
+ label="Remove..."
+ layout="topleft"
+ name="remove_allowed_avatar_btn"
+ left_pad="70"
+ top_delta="0"
+ width="90" />
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="20"
+ layout="topleft"
+ left="8"
+ name="allow_group_label"
+ top_pad="5"
+ width="200">
+ Allowed Groups:
+ </text>
+ <button
+ follows="left|top"
+ font="SansSerifSmall"
+ height="18"
+ label="?"
+ layout="topleft"
+ left_delta="232"
+ name="allow_group_help"
+ top_delta="-1"
+ width="18" />
+ <view_border
+ bevel_style="none"
+ follows="top|left"
+ height="60"
+ layout="topleft"
+ left="8"
+ top_pad="5"
+ width="250" />
+ <name_list
+ follows="left|top"
+ height="60"
+ layout="topleft"
+ left_delta="0"
+ multi_select="true"
+ name="allowed_group_name_list"
+ top_delta="0"
+ width="250" />
+ <button
+ follows="left|top"
+ height="20"
+ label="Add..."
+ layout="topleft"
+ left="8"
+ name="add_allowed_group_btn"
+ top_pad="5"
+ width="90" />
+ <button
+ follows="left|top"
+ height="20"
+ label="Remove..."
+ layout="topleft"
+ name="remove_allowed_group_btn"
+ left_pad="70"
+ top_delta="0"
+ width="90" />
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="20"
+ layout="topleft"
+ left="8"
+ name="ban_resident_label"
+ top_pad="5"
+ width="200">
+ Banned Residents:
+ </text>
+ <button
+ follows="left|top"
+ font="SansSerifSmall"
+ height="18"
+ label="?"
+ layout="topleft"
+ left_delta="232"
+ name="ban_resident_help"
+ top_delta="-1"
+ width="18" />
+ <view_border
+ bevel_style="none"
+ follows="top|left"
+ height="60"
+ layout="topleft"
+ left="8"
+ top_pad="5"
+ width="250" />
+ <name_list
+ follows="left|top"
+ height="60"
+ layout="topleft"
+ left_delta="0"
+ multi_select="true"
+ name="banned_avatar_name_list"
+ top_delta="0"
+ width="250" />
+ <button
+ follows="left|top"
+ height="20"
+ label="Add..."
+ layout="topleft"
+ left="8"
+ name="add_banned_avatar_btn"
+ top_pad="5"
+ width="90" />
+ <button
+ follows="left|top"
+ height="20"
+ label="Remove..."
+ layout="topleft"
+ name="remove_banned_avatar_btn"
+ left_pad="70"
+ top_delta="0"
+ width="90" />
+ </panel>
+ </scroll_container>
+</panel>
diff --git a/indra/newview/skins/default/xui/en/panel_region_general.xml b/indra/newview/skins/default/xui/en/panel_region_general.xml
new file mode 100644
index 0000000000..b7a32213cf
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/panel_region_general.xml
@@ -0,0 +1,356 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<panel
+ border="true"
+ follows="top|left"
+ height="360"
+ label="Region"
+ layout="topleft"
+ left="0"
+ name="General"
+ top="360"
+ width="280">
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ font="SansSerif"
+ height="20"
+ layout="topleft"
+ left="10"
+ name="region_text_lbl"
+ top="10"
+ width="100">
+ Region:
+ </text>
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ font="SansSerif"
+ height="20"
+ layout="topleft"
+ left_delta="50"
+ name="region_text"
+ top_delta="0"
+ width="200">
+ unknown
+ </text>
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ font="SansSerif"
+ height="20"
+ layout="topleft"
+ left="10"
+ name="version_channel_text_lbl"
+ top="30"
+ width="100">
+ Version:
+ </text>
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ font="SansSerif"
+ height="20"
+ layout="topleft"
+ left_delta="50"
+ name="version_channel_text"
+ top_delta="0"
+ width="200">
+ unknown
+ </text>
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ font="SansSerif"
+ height="20"
+ layout="topleft"
+ left="10"
+ name="region_type_lbl"
+ top="50"
+ width="100">
+ Type:
+ </text>
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ font="SansSerif"
+ height="20"
+ layout="topleft"
+ left_delta="50"
+ name="region_type"
+ top_delta="0"
+ width="200">
+ unknown
+ </text>
+ <check_box
+ height="20"
+ label="Block Terraform"
+ layout="topleft"
+ left="10"
+ name="block_terraform_check"
+ top="70"
+ width="80" />
+ <button
+ follows="left|top"
+ font="SansSerifSmall"
+ height="18"
+ label="?"
+ layout="topleft"
+ left_pad="115"
+ name="terraform_help"
+ top_delta="2"
+ width="18" />
+ <check_box
+ height="20"
+ label="Block Fly"
+ layout="topleft"
+ left="10"
+ name="block_fly_check"
+ top="90"
+ width="80" />
+ <button
+ follows="left|top"
+ font="SansSerifSmall"
+ height="18"
+ label="?"
+ layout="topleft"
+ left_pad="115"
+ name="fly_help"
+ top_delta="2"
+ width="18" />
+ <check_box
+ height="20"
+ label="Allow Damage"
+ layout="topleft"
+ left="10"
+ name="allow_damage_check"
+ top="110"
+ width="80" />
+ <button
+ follows="left|top"
+ font="SansSerifSmall"
+ height="18"
+ label="?"
+ layout="topleft"
+ left_pad="115"
+ name="damage_help"
+ top_delta="2"
+ width="18" />
+ <check_box
+ height="20"
+ label="Restrict Pushing"
+ layout="topleft"
+ left="10"
+ name="restrict_pushobject"
+ top="130"
+ width="80" />
+ <button
+ follows="left|top"
+ font="SansSerifSmall"
+ height="18"
+ label="?"
+ layout="topleft"
+ left_pad="115"
+ name="restrict_pushobject_help"
+ top_delta="2"
+ width="18" />
+ <check_box
+ height="20"
+ label="Allow Land Resell"
+ layout="topleft"
+ left="10"
+ name="allow_land_resell_check"
+ top="160"
+ width="80" />
+ <button
+ follows="left|top"
+ font="SansSerifSmall"
+ height="18"
+ label="?"
+ layout="topleft"
+ left_pad="115"
+ name="land_resell_help"
+ top_delta="2"
+ width="18" />
+ <check_box
+ height="20"
+ label="Allow Land Join/Divide"
+ layout="topleft"
+ left="10"
+ name="allow_parcel_changes_check"
+ top="180"
+ width="80" />
+ <button
+ follows="left|top"
+ font="SansSerifSmall"
+ height="18"
+ label="?"
+ layout="topleft"
+ left_pad="115"
+ name="parcel_changes_help"
+ top_delta="2"
+ width="18" />
+ <check_box
+ height="20"
+ label="Block Land Show in Search"
+ layout="topleft"
+ left="10"
+ name="block_parcel_search_check"
+ tool_tip="Let people see this region and its parcels in search results"
+ top="200"
+ width="80" />
+ <button
+ follows="left|top"
+ font="SansSerifSmall"
+ height="18"
+ label="?"
+ layout="topleft"
+ left_pad="115"
+ name="parcel_search_help"
+ top_delta="2"
+ width="18" />
+ <spinner
+ follows="left|top"
+ height="20"
+ increment="1"
+ label="Agent Limit"
+ label_width="97"
+ layout="topleft"
+ left="10"
+ max_val="100"
+ min_val="1"
+ name="agent_limit_spin"
+ top="240"
+ width="170" />
+ <button
+ follows="left|top"
+ font="SansSerifSmall"
+ height="18"
+ label="?"
+ layout="topleft"
+ left_pad="25"
+ name="agent_limit_help"
+ top_delta="2"
+ width="18" />
+ <spinner
+ follows="left|top"
+ height="20"
+ increment="0.5"
+ label="Object Bonus"
+ label_width="97"
+ layout="topleft"
+ left="10"
+ max_val="10"
+ min_val="1"
+ name="object_bonus_spin"
+ top="260"
+ width="170" />
+ <button
+ follows="left|top"
+ font="SansSerifSmall"
+ height="18"
+ label="?"
+ layout="topleft"
+ left_pad="25"
+ name="object_bonus_help"
+ top_delta="2"
+ width="18" />
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="20"
+ label="Maturity"
+ layout="topleft"
+ left="10"
+ name="access_text"
+ top="290"
+ width="100">
+ Rating:
+ </text>
+ <combo_box
+ height="20"
+ label="Mature"
+ layout="topleft"
+ left_delta="100"
+ name="access_combo"
+ top_delta="0"
+ width="85">
+ <combo_box.item
+ label="Adult"
+ name="Adult"
+ value="42" />
+ <combo_box.item
+ label="Mature"
+ name="Mature"
+ value="21" />
+ <combo_box.item
+ label="PG"
+ name="PG"
+ value="13" />
+ </combo_box>
+ <button
+ follows="left|top"
+ font="SansSerifSmall"
+ height="18"
+ label="?"
+ layout="topleft"
+ left_pad="10"
+ name="access_help"
+ top_delta="2"
+ width="18" />
+ <button
+ enabled="false"
+ follows="left|top"
+ height="20"
+ label="Apply"
+ layout="topleft"
+ left="108"
+ name="apply_btn"
+ top="320"
+ width="100">
+ <button.commit_callback
+ function="RegionInfo.Cancel" />
+ </button>
+ <button
+ follows="left|top"
+ height="20"
+ label="Teleport Home One User..."
+ layout="topleft"
+ left="10"
+ name="kick_btn"
+ top_pad="10"
+ width="250" />
+ <button
+ follows="left|top"
+ height="20"
+ label="Teleport Home All Users..."
+ layout="topleft"
+ left_delta="0"
+ name="kick_all_btn"
+ top_pad="3"
+ width="250" />
+ <button
+ follows="left|top"
+ height="20"
+ label="Send Message To Region..."
+ layout="topleft"
+ left_delta="0"
+ name="im_btn"
+ top_pad="20"
+ width="200" />
+ <button
+ follows="left|top"
+ height="20"
+ label="Manage Telehub..."
+ layout="topleft"
+ left_delta="0"
+ name="manage_telehub_btn"
+ top_pad="20"
+ width="150" />
+</panel>
diff --git a/indra/newview/skins/default/xui/en/panel_region_terrain.xml b/indra/newview/skins/default/xui/en/panel_region_terrain.xml
new file mode 100644
index 0000000000..bdf74c5621
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/panel_region_terrain.xml
@@ -0,0 +1,239 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<panel
+ border="true"
+ follows="top|left"
+ height="340"
+ label="Terrain"
+ layout="topleft"
+ left="0"
+ name="Terrain"
+ top="320"
+ width="280">
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ font="SansSerif"
+ height="20"
+ layout="topleft"
+ left="10"
+ name="region_text_lbl"
+ top="10"
+ width="100">
+ Region:
+ </text>
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ font="SansSerif"
+ height="20"
+ layout="topleft"
+ left_delta="50"
+ name="region_text"
+ top_delta="0"
+ width="200">
+ unknown
+ </text>
+ <spinner
+ follows="left|top"
+ height="20"
+ label="Water Height"
+ label_width="120"
+ layout="topleft"
+ left="15"
+ max_val="100"
+ name="water_height_spin"
+ top="40"
+ width="180" />
+ <button
+ follows="left|top"
+ font="SansSerifSmall"
+ height="18"
+ label="?"
+ layout="topleft"
+ left_pad="5"
+ name="water_height_help"
+ top_delta="2"
+ width="18" />
+ <spinner
+ follows="left|top"
+ height="20"
+ increment="0.2"
+ label="Terrain Raise Limit"
+ label_width="120"
+ layout="topleft"
+ left="15"
+ max_val="100"
+ name="terrain_raise_spin"
+ top="60"
+ width="180" />
+ <button
+ follows="left|top"
+ font="SansSerifSmall"
+ height="18"
+ label="?"
+ layout="topleft"
+ left_pad="5"
+ name="terrain_raise_help"
+ top_delta="2"
+ width="18" />
+ <spinner
+ follows="left|top"
+ height="20"
+ increment="0.2"
+ label="Terrain Lower Limit"
+ label_width="120"
+ layout="topleft"
+ left="15"
+ max_val="0"
+ min_val="-100"
+ name="terrain_lower_spin"
+ top="80"
+ width="180" />
+ <button
+ follows="left|top"
+ font="SansSerifSmall"
+ height="18"
+ label="?"
+ layout="topleft"
+ left_pad="5"
+ name="terrain_lower_help"
+ top_delta="2"
+ width="18" />
+ <check_box
+ height="20"
+ label="Use Estate Sun"
+ layout="topleft"
+ left="15"
+ name="use_estate_sun_check"
+ top="105"
+ width="100" />
+ <button
+ follows="left|top"
+ font="SansSerifSmall"
+ height="18"
+ label="?"
+ layout="topleft"
+ left_pad="85"
+ name="use_estate_sun_help"
+ top_delta="2"
+ width="18" />
+ <check_box
+ height="20"
+ label="Fixed Sun"
+ layout="topleft"
+ left="15"
+ name="fixed_sun_check"
+ top_pad="0"
+ width="100" />
+ <button
+ follows="left|top"
+ font="SansSerifSmall"
+ height="18"
+ label="?"
+ layout="topleft"
+ left_pad="85"
+ name="fixed_sun_help"
+ top_delta="2"
+ width="18" />
+ <icon
+ height="20"
+ image_name="icon_day_cycle.tga"
+ layout="topleft"
+ left="50"
+ name="daycycle"
+ top_delta="25"
+ width="165" />
+ <slider
+ follows="left|top"
+ height="20"
+ increment="0.001"
+ label="Phase"
+ layout="topleft"
+ left="15"
+ max_val="30"
+ min_val="6"
+ name="sun_hour_slider"
+ show_text="false"
+ top_delta="30"
+ width="200" />
+ <button
+ enabled="false"
+ follows="left|top"
+ height="20"
+ label="Apply"
+ layout="topleft"
+ left="130"
+ name="apply_btn"
+ top_delta="30"
+ width="90" />
+ <view_border
+ bevel_style="none"
+ follows="top|left"
+ height="210"
+ layout="topleft"
+ left="8"
+ top="30"
+ width="240" />
+ <button
+ follows="left|top"
+ height="20"
+ label="Download RAW terrain..."
+ layout="topleft"
+ left_delta="2"
+ name="download_raw_btn"
+ tool_tip="Available only to estate owners, not managers"
+ top_pad="15"
+ width="170" />
+ <button
+ follows="left|top"
+ font="SansSerifSmall"
+ height="18"
+ label="?"
+ layout="topleft"
+ left_pad="10"
+ name="download_raw_help"
+ top_delta="2"
+ width="18" />
+ <button
+ follows="left|top"
+ height="20"
+ label="Upload RAW terrain..."
+ layout="topleft"
+ left="10"
+ name="upload_raw_btn"
+ tool_tip="Available only to estate owners, not managers"
+ top_pad="0"
+ width="170" />
+ <button
+ follows="left|top"
+ font="SansSerifSmall"
+ height="18"
+ label="?"
+ layout="topleft"
+ left_pad="10"
+ name="upload_raw_help"
+ top_delta="2"
+ width="18" />
+ <button
+ follows="left|top"
+ height="20"
+ label="Bake Terrain"
+ layout="topleft"
+ left="10"
+ name="bake_terrain_btn"
+ tool_tip="Set current terrain as mid-point for raise/lower limits"
+ top_pad="15"
+ width="100" />
+ <button
+ follows="left|top"
+ font="SansSerifSmall"
+ height="18"
+ label="?"
+ layout="topleft"
+ left_pad="10"
+ name="bake_terrain_help"
+ top_delta="2"
+ width="18" />
+</panel>
diff --git a/indra/newview/skins/default/xui/en/panel_region_texture.xml b/indra/newview/skins/default/xui/en/panel_region_texture.xml
new file mode 100644
index 0000000000..5285a53c59
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/panel_region_texture.xml
@@ -0,0 +1,347 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<panel
+ border="true"
+ follows="top|left"
+ height="512"
+ name="TextureWrapper"
+ label="Ground Textures"
+ layout="topleft"
+ width="280">
+ <scroll_container
+ follows="top|left|right|bottom"
+ height="508"
+ name="container1"
+ layout="topleft"
+ width="280">
+ <panel
+ follows="top|left"
+ height="575"
+ label="Ground Textures"
+ layout="topleft"
+ name="Textures"
+ width="258">
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ font="SansSerif"
+ height="20"
+ layout="topleft"
+ left="10"
+ name="region_text_lbl"
+ top="10"
+ width="100">
+ Region:
+ </text>
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ font="SansSerif"
+ height="20"
+ layout="topleft"
+ left_delta="50"
+ name="region_text"
+ top_delta="0"
+ width="200">
+ unknown
+ </text>
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="20"
+ layout="topleft"
+ left="10"
+ name="detail_texture_text"
+ top="36"
+ width="300">
+ Terrain Textures
+ (requires 512x512, 24 bit .tga files)
+ </text>
+ <texture_picker
+ follows="left|top"
+ height="100"
+ layout="topleft"
+ left_delta="0"
+ name="texture_detail_0"
+ top_delta="30"
+ width="100" />
+ <texture_picker
+ follows="left|top"
+ height="100"
+ layout="topleft"
+ left_pad="10"
+ name="texture_detail_1"
+ top_delta="0"
+ width="100" />
+ <texture_picker
+ follows="left|top"
+ height="100"
+ layout="topleft"
+ left="10"
+ name="texture_detail_2"
+ top_delta="105"
+ width="100" />
+ <texture_picker
+ follows="left|top"
+ height="100"
+ layout="topleft"
+ left_pad="10"
+ name="texture_detail_3"
+ top_delta="0"
+ width="100" />
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="20"
+ layout="topleft"
+ left="10"
+ name="height_text_lbl"
+ top="157"
+ width="65">
+ 1 (Low)
+ </text>
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="20"
+ layout="topleft"
+ left_pad="45"
+ name="height_text_lbl2"
+ top_delta="0"
+ width="100">
+ 2
+ </text>
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="20"
+ layout="topleft"
+ left="10"
+ name="height_text_lbl3"
+ top_delta="105"
+ width="100">
+ 3
+ </text>
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="20"
+ layout="topleft"
+ left_pad="10"
+ name="height_text_lbl4"
+ top_delta="0"
+ width="100">
+ 4 (High)
+ </text>
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="20"
+ layout="topleft"
+ left="10"
+ name="height_text_lbl5"
+ top_delta="25"
+ width="300">
+ Texture Elevation Ranges
+ </text>
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="20"
+ layout="topleft"
+ left="51"
+ name="height_text_lbl6"
+ top_delta="20"
+ width="100">
+ Southwest
+ </text>
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="20"
+ layout="topleft"
+ left_pad="10"
+ name="height_text_lbl7"
+ top_delta="0"
+ width="100">
+ Northwest
+ </text>
+ <spinner
+ follows="left|top"
+ height="20"
+ increment="0.5"
+ label="Low"
+ label_width="37"
+ layout="topleft"
+ left="10"
+ max_val="500"
+ min_val="-500"
+ name="height_start_spin_0"
+ top_delta="20"
+ width="100" />
+ <spinner
+ follows="left|top"
+ height="20"
+ increment="0.5"
+ label="Low"
+ label_width="37"
+ layout="topleft"
+ left_pad="10"
+ max_val="500"
+ min_val="-500"
+ name="height_start_spin_1"
+ top_delta="0"
+ width="100" />
+ <spinner
+ follows="left|top"
+ height="20"
+ increment="0.5"
+ label="High"
+ label_width="37"
+ layout="topleft"
+ left="10"
+ max_val="500"
+ min_val="-500"
+ name="height_range_spin_0"
+ top_delta="20"
+ width="100" />
+ <spinner
+ follows="left|top"
+ height="20"
+ increment="0.5"
+ label="High"
+ label_width="37"
+ layout="topleft"
+ left_pad="10"
+ max_val="500"
+ min_val="-500"
+ name="height_range_spin_1"
+ top_delta="0"
+ width="100" />
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="20"
+ layout="topleft"
+ left="51"
+ name="height_text_lbl8"
+ top_delta="30"
+ width="100">
+ Southeast
+ </text>
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="20"
+ layout="topleft"
+ left_pad="10"
+ name="height_text_lbl9"
+ top_delta="0"
+ width="100">
+ Northeast
+ </text>
+ <spinner
+ follows="left|top"
+ height="20"
+ increment="0.5"
+ label="Low"
+ label_width="37"
+ layout="topleft"
+ left="10"
+ max_val="500"
+ min_val="-500"
+ name="height_start_spin_2"
+ top_delta="20"
+ width="100" />
+ <spinner
+ follows="left|top"
+ height="20"
+ increment="0.5"
+ label="Low"
+ label_width="37"
+ layout="topleft"
+ left_pad="10"
+ max_val="500"
+ min_val="-500"
+ name="height_start_spin_3"
+ top_delta="0"
+ width="100" />
+ <spinner
+ follows="left|top"
+ height="20"
+ increment="0.5"
+ label="High"
+ label_width="37"
+ layout="topleft"
+ left="10"
+ max_val="500"
+ min_val="-500"
+ name="height_range_spin_2"
+ top_delta="20"
+ width="100" />
+ <spinner
+ follows="left|top"
+ height="20"
+ increment="0.5"
+ label="High"
+ label_width="37"
+ layout="topleft"
+ left_pad="10"
+ max_val="500"
+ min_val="-500"
+ name="height_range_spin_3"
+ top_delta="0"
+ width="100" />
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="20"
+ layout="topleft"
+ left="10"
+ name="height_text_lbl10"
+ top_delta="30"
+ width="270">
+ These values represent the blend range
+ for the textures above.
+ </text>
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="20"
+ layout="topleft"
+ left_delta="0"
+ name="height_text_lbl11"
+ top_delta="32"
+ width="270">
+ Measured in meters, the LOW value
+ is the MAXIMUM height of Texture #1,
+ and the HIGH value is the MINIMUM
+ height of Texture #4.
+ </text>
+
+ <button
+ enabled="false"
+ follows="left|bottom"
+ height="20"
+ label="Apply"
+ layout="topleft"
+ left="120"
+ name="apply_btn"
+ top_delta="60"
+ width="100" />
+ </panel>
+ </scroll_container>
+</panel>
diff --git a/indra/newview/skins/default/xui/en/panel_script_ed.xml b/indra/newview/skins/default/xui/en/panel_script_ed.xml
new file mode 100644
index 0000000000..5738879c5a
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/panel_script_ed.xml
@@ -0,0 +1,192 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<panel
+ bevel_style="none"
+ border_style="line"
+ bottom="550"
+ follows="left|top|right|bottom"
+ height="508"
+ layout="topleft"
+ left="0"
+ name="script panel"
+ width="500">
+ <panel.string
+ name="loading">
+ Loading...
+ </panel.string>
+ <panel.string
+ name="can_not_view">
+ You can not view or edit this script, since it has been set as &quot;no copy&quot;. You need full permissions to view or edit a script inside an object.
+ </panel.string>
+ <panel.string
+ name="public_objects_can_not_run">
+ Public Objects cannot run scripts
+ </panel.string>
+ <panel.string
+ name="script_running">
+ Running
+ </panel.string>
+ <panel.string
+ name="Title">
+ Script: [NAME]
+ </panel.string>
+ <text_editor
+ type="string"
+ length="1"
+ bevel_style="none"
+ border_style="line"
+ bottom="393"
+ follows="left|top|right|bottom"
+ font="Monospace"
+ height="376"
+ ignore_tab="false"
+ layout="topleft"
+ left="4"
+ max_length="65536"
+ name="Script Editor"
+ width="492"
+ show_line_numbers="true"
+ handle_edit_keys_directly="true"
+ word_wrap="true">
+ Loading...
+ </text_editor>
+ <button
+ bottom="499"
+ follows="right|bottom"
+ height="20"
+ label="Save"
+ label_selected="Save"
+ layout="topleft"
+ left="360"
+ name="Save_btn"
+ width="128" />
+ <scroll_list
+ bottom="457"
+ follows="left|right|bottom"
+ height="60"
+ layout="topleft"
+ left="4"
+ name="lsl errors"
+ width="492" />
+ <combo_box
+ bottom="499"
+ follows="left|bottom"
+ height="20"
+ label="Insert..."
+ layout="topleft"
+ left="12"
+ name="Insert..."
+ width="128" />
+ <text
+ bottom="473"
+ follows="left|bottom"
+ height="12"
+ layout="topleft"
+ left="12"
+ name="line_col"
+ width="128" />
+ <menu_bar
+ bg_visible="false"
+ bottom="18"
+ follows="left|top|right"
+ height="18"
+ layout="topleft"
+ left="8"
+ mouse_opaque="false"
+ name="script_menu"
+ width="476">
+ <menu
+ bottom="18"
+ height="62"
+ label="File"
+ layout="topleft"
+ left="0"
+ mouse_opaque="false"
+ name="File"
+ width="138">
+ <menu_item_call
+ label="Save"
+ layout="topleft"
+ name="Save" />
+ <menu_item_separator
+ layout="topleft" />
+ <menu_item_call
+ label="Revert All Changes"
+ layout="topleft"
+ name="Revert All Changes" />
+ </menu>
+ <menu
+ bottom="-647"
+ height="198"
+ label="Edit"
+ layout="topleft"
+ left="222"
+ mouse_opaque="false"
+ name="Edit"
+ width="139">
+ <menu_item_call
+ enabled="false"
+ label="Undo"
+ layout="topleft"
+ name="Undo" />
+ <menu_item_call
+ enabled="false"
+ label="Redo"
+ layout="topleft"
+ name="Redo" />
+ <menu_item_separator
+ layout="topleft" />
+ <menu_item_call
+ enabled="false"
+ label="Cut"
+ layout="topleft"
+ name="Cut" />
+ <menu_item_call
+ enabled="false"
+ label="Copy"
+ layout="topleft"
+ name="Copy" />
+ <menu_item_call
+ enabled="false"
+ label="Paste"
+ layout="topleft"
+ name="Paste" />
+ <menu_item_separator
+ layout="topleft"
+ name="separator2" />
+ <menu_item_call
+ label="Select All"
+ layout="topleft"
+ name="Select All" />
+ <menu_item_call
+ enabled="false"
+ label="Deselect"
+ layout="topleft"
+ name="Deselect" />
+ <menu_item_separator
+ layout="topleft"
+ name="separator3" />
+ <menu_item_call
+ label="Search / Replace..."
+ layout="topleft"
+ name="Search / Replace..." />
+ </menu>
+ <menu
+ bottom="18"
+ height="34"
+ label="Help"
+ layout="topleft"
+ left="0"
+ mouse_opaque="false"
+ name="Help"
+ width="112">
+ <menu_item_call
+ label="Help..."
+ layout="topleft"
+ name="Help..." />
+ <menu_item_call
+ label="LSL Wiki Help..."
+ layout="topleft"
+ name="LSL Wiki Help..." />
+ </menu>
+ </menu_bar>
+</panel>
diff --git a/indra/newview/skins/default/xui/en/panel_scrolling_param.xml b/indra/newview/skins/default/xui/en/panel_scrolling_param.xml
new file mode 100644
index 0000000000..21ecd01839
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/panel_scrolling_param.xml
@@ -0,0 +1,92 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<panel
+ height="152"
+ layout="topleft"
+ left="0"
+ name="LLScrollingPanelParam"
+ top="152"
+ width="270">
+ <text
+ follows="left|top"
+ height="16"
+ layout="topleft"
+ left="4"
+ name="min param text"
+ top="116"
+ width="128" />
+ <text
+ follows="left|top"
+ height="16"
+ layout="topleft"
+ left_pad="6"
+ name="max param text"
+ top_delta="0"
+ width="128" />
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="16"
+ layout="topleft"
+ left="8"
+ name="Loading..."
+ top="11"
+ width="128">
+ Loading...
+ </text>
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="16"
+ layout="topleft"
+ left_pad="6"
+ name="Loading...2"
+ top_delta="0"
+ width="128">
+ Loading...
+ </text>
+ <button
+ enabled="false"
+ height="132"
+ image_disabled="PushButton_Disabled"
+ image_disabled_selected="PushButton_Disabled_Selected"
+ image_selected="PushButton_Selected"
+ image_unselected="PushButton_Off"
+ layout="topleft"
+ left="2"
+ name="less"
+ picture_style="true"
+ tab_stop="false"
+ top="0"
+ width="132" />
+ <button
+ enabled="false"
+ height="132"
+ image_disabled="PushButton_Disabled"
+ image_disabled_selected="PushButton_Disabled_Selected"
+ image_selected="PushButton_Selected"
+ image_unselected="PushButton_Off"
+ layout="topleft"
+ left_pad="2"
+ name="more"
+ picture_style="true"
+ tab_stop="false"
+ top_delta="0"
+ width="132" />
+ <slider
+ can_edit_text="true"
+ decimal_digits="0"
+ enabled="false"
+ height="16"
+ increment="1"
+ initial_value="0"
+ label="[DESC]"
+ label_width="100"
+ layout="topleft"
+ left="6"
+ max_val="100"
+ name="param slider"
+ top="134"
+ width="258" />
+</panel>
diff --git a/indra/newview/skins/default/xui/en/panel_side_tray.xml b/indra/newview/skins/default/xui/en/panel_side_tray.xml
new file mode 100644
index 0000000000..e9eac2c9dc
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/panel_side_tray.xml
@@ -0,0 +1,118 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<side_tray
+ name="sidebar"
+ background_visible="false"
+ mouse_opaque="true"
+ width="305"
+ collapsed="true"
+>
+ <sidetray_tab
+ name="sidebar_home"
+ tab_title="Home"
+ description="Home."
+ image="icn_voice-groupfocus.tga"
+ mouse_opaque="false"
+ background_opaque="false"
+ background_visible="true"
+ >
+ <panel
+ name="panel_home"
+ filename="panel_sidetray_home_tab.xml"
+ label="home"
+ border="true"
+ font="SansSerifBold"
+ />
+ </sidetray_tab>
+
+ <sidetray_tab
+ name="sidebar_people"
+ tab_title="People"
+ description="Find your friends, contacts and people nearby."
+ image="TabIcon_People_Off"
+ mouse_opaque="false"
+ background_opaque="false"
+ background_visible="true"
+ >
+ <panel_container
+ name="panel_container"
+ >
+ <panel
+ class="panel_people"
+ name="panel_people"
+ filename="panel_people.xml"
+ border="true"
+ font="SansSerifBold"
+ />
+ <panel
+ class="panel_profile_view"
+ name="panel_profile_view"
+ filename="panel_profile_view.xml"
+ border="true"
+ font="SansSerifBold"
+ />
+ <panel
+ class="panel_group_info_sidetray"
+ name="panel_group_info_sidetray"
+ filename="panel_group_info_sidetray.xml"
+ label="Group Info"
+ border="true"
+ />
+
+ </panel_container>
+ </sidetray_tab>
+ <sidetray_tab
+ name="sidebar_places"
+ tab_title="Places"
+ label="Places"
+ description="Find places to go and places you've been."
+ image="TabIcon_Places_Off"
+ mouse_opaque="false"
+ background_visible="true"
+ >
+ <panel
+ class="panel_places"
+ name="panel_places"
+ filename="panel_places.xml"
+ label="Places"
+ border="true"
+ />
+ </sidetray_tab>
+
+ <sidetray_tab
+ name="sidebar_me"
+ tab_title="My Profile"
+ description="Change your profile, your look and quick links to your outfits."
+ image="TabIcon_Me_Off"
+ mouse_opaque="false"
+ background_visible="true"
+ >
+ <panel
+ class="panel_me_profile_view"
+ name="panel_me_profile"
+ filename="panel_me_profile.xml"
+ label="My Profile"
+ border="true"
+ font="SansSerifBold"
+ />
+ </sidetray_tab>
+
+ <sidetray_tab
+ name="sidebar_appearance"
+ tab_title="Appearance"
+ description="Change your looks and appearance."
+ image="TabIcon_Appearance_Off"
+ mouse_opaque="false"
+ background_opaque="false"
+ background_visible="true"
+ bg_opaque_color="0.5 0.5 0.5 1.0"
+ >
+ <panel
+ class="panel_appearance"
+ name="panel_appearance"
+ filename="panel_appearance.xml"
+ border="true"
+ />
+ </sidetray_tab>
+
+
+</side_tray>
diff --git a/indra/newview/skins/default/xui/en/panel_side_tray_tab_caption.xml b/indra/newview/skins/default/xui/en/panel_side_tray_tab_caption.xml
new file mode 100644
index 0000000000..a5c3be3349
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/panel_side_tray_tab_caption.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<panel
+ background_visible="true"
+ bottom="0"
+ follows="left|top|right"
+ height="30"
+ layout="topleft"
+ left="0"
+ name="sidetray_tab_panel">
+ <text
+ follows="left|top"
+ font="SansSerifHuge"
+ height="16"
+ layout="topleft"
+ left="10"
+ name="sidetray_tab_title"
+ text_color="white"
+ top="4"
+ value="Side Panel"
+ width="255" />
+</panel>
diff --git a/indra/newview/skins/default/xui/en/panel_sidetray_home_tab.xml b/indra/newview/skins/default/xui/en/panel_sidetray_home_tab.xml
new file mode 100644
index 0000000000..e87517e200
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/panel_sidetray_home_tab.xml
@@ -0,0 +1,203 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<panel
+ background_visible="true"
+ bevel_style="in"
+ follows="left|top|right|bottom"
+ height="420"
+ label="home_tab"
+ layout="topleft"
+ name="home_tab"
+ width="300">
+ <panel
+ background_visible="true"
+ bg_alpha_color="DkGray2"
+ class="panel_sidetray_home_info"
+ follows="left|top|right"
+ height="130"
+ layout="topleft"
+ left="10"
+ name="sidebar_people"
+ width="280">
+ <text
+ follows="left|right|top"
+ font="SansSerifBigBold"
+ height="30"
+ layout="topleft"
+ left="5"
+ mouse_opaque="false"
+ name="tab_name"
+ text_color="white"
+ top="10"
+ value="People"
+ width="200"
+ word_wrap="true" />
+ <icon
+ color="DkGray"
+ follows="top|right"
+ height="20"
+ layout="topleft"
+ name="tab_icon"
+ right="-10"
+ top="10"
+ image_name="TabIcon_Home_Selected"
+ width="20" />
+ <text
+ follows="left|right|bottom"
+ font="SansSerifBold"
+ height="120"
+ layout="topleft"
+ left="10"
+ mouse_opaque="false"
+ name="tab_description"
+ right="-10"
+ text_color="white"
+ top="40"
+ word_wrap="true">
+ Find your friends, contacts and people nearby.
+ </text>
+ </panel>
+ <panel
+ background_visible="true"
+ bg_alpha_color="DkGray2"
+ class="panel_sidetray_home_info"
+ follows="left|top|right"
+ height="130"
+ layout="topleft"
+ left="10"
+ name="sidebar_places"
+ width="280">
+ <text
+ follows="left|right|top"
+ font="SansSerifBigBold"
+ height="30"
+ layout="topleft"
+ left="5"
+ mouse_opaque="false"
+ name="tab_name"
+ text_color="white"
+ top="10"
+ value="Places"
+ width="200"
+ word_wrap="true" />
+ <icon
+ color="DkGray"
+ follows="top|right"
+ height="20"
+ layout="topleft"
+ name="tab_icon"
+ right="-10"
+ top="10"
+ width="20"
+ image_name="TabIcon_Places_Selected"/>
+ <text
+ follows="left|right|bottom|top"
+ font="SansSerifBold"
+ height="120"
+ layout="topleft"
+ left="10"
+ mouse_opaque="false"
+ name="tab_description"
+ right="-10"
+ text_color="white"
+ top="40"
+ word_wrap="true">
+ Find your friends, contacts and people nearby.
+ </text>
+ </panel>
+ <panel
+ background_visible="true"
+ bg_alpha_color="DkGray2"
+ class="panel_sidetray_home_info"
+ follows="left|top|right"
+ height="130"
+ layout="topleft"
+ left="10"
+ name="sidebar_me"
+ width="280">
+ <text
+ follows="left|right|top"
+ font="SansSerifBigBold"
+ height="30"
+ layout="topleft"
+ left="5"
+ mouse_opaque="false"
+ name="tab_name"
+ text_color="white"
+ top="10"
+ value="My Profile"
+ width="200"
+ word_wrap="true" />
+ <icon
+ color="DkGray"
+ follows="top|right"
+ height="20"
+ layout="topleft"
+ name="tab_icon"
+ right="-10"
+ top="10"
+ width="20"
+ image_name="TabIcon_Me_Selected"/>
+ <text
+ follows="left|right|bottom|top"
+ font="SansSerifBold"
+ height="120"
+ layout="topleft"
+ left="10"
+ mouse_opaque="false"
+ name="tab_description"
+ right="-10"
+ text_color="white"
+ top="40"
+ word_wrap="true">
+ Change your profile.
+ </text>
+ </panel>
+ <panel
+ background_visible="true"
+ bg_alpha_color="DkGray2"
+ class="panel_sidetray_home_info"
+ follows="left|top|right"
+ height="130"
+ layout="topleft"
+ left="10"
+ name="sidebar_appearance"
+ width="280">
+ <text
+ follows="left|right|top"
+ font="SansSerifBigBold"
+ height="30"
+ layout="topleft"
+ left="5"
+ mouse_opaque="false"
+ name="tab_name"
+ text_color="white"
+ top="10"
+ value="My Appearance"
+ width="200"
+ word_wrap="true" />
+ <icon
+ color="DkGray"
+ follows="top|right"
+ height="20"
+ layout="topleft"
+ name="tab_icon"
+ right="-10"
+ top="10"
+ width="20"
+ image_name="TabIcon_Things_Selected"/>
+ <text
+ follows="left|right|bottom|top"
+ font="SansSerifBold"
+ height="120"
+ layout="topleft"
+ left="10"
+ mouse_opaque="false"
+ name="tab_description"
+ right="-10"
+ text_color="white"
+ top="40"
+ word_wrap="true">
+ Change your apperance and looks.
+ </text>
+ </panel>
+</panel>
diff --git a/indra/newview/skins/default/xui/en/panel_stand_stop_flying.xml b/indra/newview/skins/default/xui/en/panel_stand_stop_flying.xml
new file mode 100644
index 0000000000..4d91a544c3
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/panel_stand_stop_flying.xml
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<!-- Width and height of this panel should be synchronized with "panel_modes" in the floater_moveview.xml-->
+<panel
+ height="25"
+ layout="topleft"
+ name="panel_stand_stop_flying"
+ mouse_opaque="false"
+ visible="false"
+ width="115">
+ <button
+ follows="left|bottom"
+ height="20"
+ label="Stand"
+ layout="topleft"
+ name="stand_btn"
+ tool_tip="Click here to stand up."
+ top="2"
+ visible="false"
+ width="115" />
+ <button
+ follows="left|bottom"
+ height="20"
+ label="Stop Flying"
+ layout="topleft"
+ name="stop_fly_btn"
+ tool_tip="Stop Flying"
+ top="2"
+ visible="false"
+ width="115" />
+</panel>
diff --git a/indra/newview/skins/default/xui/en/panel_status_bar.xml b/indra/newview/skins/default/xui/en/panel_status_bar.xml
new file mode 100644
index 0000000000..f597211ec9
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/panel_status_bar.xml
@@ -0,0 +1,210 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<panel
+ background_opaque="true"
+ background_visible="true"
+ bg_opaque_color="0.25 0.25 0.25 1"
+ follows="top|left|right"
+ height="18"
+ layout="topleft"
+ left="0"
+ mouse_opaque="false"
+ name="status"
+ top="18"
+ width="1000">
+ <panel.string
+ name="StatBarDaysOfWeek">
+ Sunday:Monday:Tuesday:Wednesday:Thursday:Friday:Saturday
+ </panel.string>
+ <panel.string
+ name="StatBarMonthsOfYear">
+ January:February:March:April:May:June:July:August:September:October:November:December
+ </panel.string>
+ <panel.string
+ name="packet_loss_tooltip">
+ Packet Loss
+ </panel.string>
+ <panel.string
+ name="bandwidth_tooltip">
+ Bandwidth
+ </panel.string>
+ <panel.string
+ name="time">
+ [hour12, datetime, slt]:[min, datetime, slt] [ampm, datetime, slt] [timezone,datetime, slt]
+ </panel.string>
+ <panel.string
+ name="timeTooltip">
+ [weekday, datetime, slt], [day, datetime, slt] [month, datetime, slt] [year, datetime, slt]
+ </panel.string>
+ <panel.string
+ name="buycurrencylabel">
+ L$ [AMT]
+ </panel.string>
+ <button
+ auto_resize="true"
+ follows="right|bottom"
+ font="SansSerifSmall"
+ height="16"
+ layout="topleft"
+ left="-150"
+ name="buycurrency"
+ picture_style="true"
+ tool_tip="Account Balance / Buy currency"
+ top="1"
+ width="60" />
+ <text
+ type="string"
+ length="1"
+ disabled_color="TimeTextColor"
+ follows="right|bottom"
+ halign="right"
+ height="20"
+ layout="topleft"
+ left_pad="5"
+ name="TimeText"
+ text_color="TimeTextColor"
+ tool_tip="Current Time (Pacific)"
+ top_delta="-1"
+ v_pad="2"
+ width="80">
+ 12:00 AM
+ </text>
+ <button
+ follows="right|bottom"
+ height="16"
+ image_selected="status_script_debug.tga"
+ image_unselected="status_script_debug.tga"
+ layout="topleft"
+ left_delta="-537"
+ name="scriptout"
+ picture_style="true"
+ scale_image="false"
+ tool_tip="Script Warnings and Errors"
+ top_delta="2"
+ visible="false"
+ width="16" />
+ <button
+ follows="right|bottom"
+ height="18"
+ image_selected="status_health.tga"
+ image_unselected="status_health.tga"
+ layout="topleft"
+ left_delta="16"
+ name="health"
+ picture_style="true"
+ scale_image="false"
+ tool_tip="Health"
+ top_delta="2"
+ visible="false"
+ width="24" />
+ <text
+ type="string"
+ length="1"
+ disabled_color="HealthTextColor"
+ follows="rsight|bottom"
+ font_shadow="hard"
+ height="18"
+ layout="topleft"
+ left_delta="24"
+ name="HealthText"
+ text_color="HealthTextColor"
+ tool_tip="Health"
+ top_delta="-4"
+ v_pad="2"
+ visible="false"
+ width="31">
+ 100%
+ </text>
+ <button
+ follows="right|bottom"
+ height="18"
+ image_selected="status_no_fly.tga"
+ image_unselected="status_no_fly.tga"
+ layout="topleft"
+ left_delta="31"
+ name="no_fly"
+ picture_style="true"
+ scale_image="false"
+ tool_tip="Flying not allowed"
+ top_delta="4"
+ visible="false"
+ width="24" />
+ <button
+ follows="right|bottom"
+ height="18"
+ image_selected="status_no_build.tga"
+ image_unselected="status_no_build.tga"
+ layout="topleft"
+ left_delta="24"
+ name="no_build"
+ picture_style="true"
+ scale_image="false"
+ tool_tip="Building/Rezzing not allowed"
+ top_delta="0"
+ visible="false"
+ width="24" />
+ <button
+ follows="right|bottom"
+ height="18"
+ image_selected="status_no_scripts.tga"
+ image_unselected="status_no_scripts.tga"
+ layout="topleft"
+ left_delta="24"
+ name="no_scripts"
+ picture_style="true"
+ scale_image="false"
+ tool_tip="Scripts not allowed"
+ top_delta="0"
+ visible="false"
+ width="24" />
+ <button
+ follows="right|bottom"
+ height="18"
+ image_selected="status_no_push.tga"
+ image_unselected="status_no_push.tga"
+ layout="topleft"
+ left_delta="24"
+ name="restrictpush"
+ picture_style="true"
+ scale_image="false"
+ tool_tip="No Pushing"
+ top_delta="0"
+ visible="false"
+ width="24" />
+ <button
+ follows="right|bottom"
+ height="18"
+ image_selected="status_no_voice.tga"
+ image_unselected="status_no_voice.tga"
+ layout="topleft"
+ left_delta="24"
+ name="status_no_voice"
+ picture_style="true"
+ scale_image="false"
+ tool_tip="Voice not available here"
+ top_delta="0"
+ visible="false"
+ width="24" />
+ <button
+ follows="right|bottom"
+ height="16"
+ image_selected="status_buy_land_pressed.tga"
+ image_unselected="status_buy_land.tga"
+ layout="topleft"
+ left_pad="7"
+ name="buyland"
+ picture_style="true"
+ tool_tip="Buy this parcel"
+ top_delta="-3"
+ visible="false"
+ width="16" />
+ <text
+ enabled="false"
+ follows="right|bottom"
+ halign="center"
+ height="12"
+ layout="topleft"
+ left_delta="-4"
+ name="stat_btn"
+ top_delta="3"
+ width="20" />
+</panel>
diff --git a/indra/newview/skins/default/xui/en/panel_sys_well_item.xml b/indra/newview/skins/default/xui/en/panel_sys_well_item.xml
new file mode 100644
index 0000000000..3ac15fe550
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/panel_sys_well_item.xml
@@ -0,0 +1,65 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<!-- All our XML is utf-8 encoded. -->
+
+<panel
+ name="sys_well_item"
+ title="sys_well_item"
+ visible="false"
+ top="0"
+ left="0"
+ width="318"
+ height="35"
+ layout="topleft"
+ follows="left|right"
+ background_opaque="false"
+ background_visible="true"
+ bg_alpha_color="0.0 0.0 0.0 0.0" >
+
+ <icon
+ top="8"
+ left="8"
+ width="20"
+ height="20"
+ layout="topleft"
+ follows="left"
+ name="icon"
+ label=""
+ mouse_opaque="false"
+ image_name="lag_status_warning.tga"
+ />
+
+ <text
+ top="2"
+ left_pad="8"
+ width="255"
+ height="28"
+ layout="topleft"
+ follows="right|left"
+ font="SansSerifBold"
+ text_color="white"
+ use_ellipses="true"
+ word_wrap="true"
+ mouse_opaque="false"
+ name="title" >
+ Select your streaming media preference. Select your streaming media preference.
+ </text>
+
+ <button
+ top="5"
+ left_pad="5"
+ width="15"
+ height="15"
+ layout="topleft"
+ follows="right"
+ name="close_btn"
+ mouse_opaque="true"
+ label=""
+ tab_stop="false"
+ image_unselected="toast_hide_btn.tga"
+ image_disabled="toast_hide_btn.tga"
+ image_selected="toast_hide_btn.tga"
+ image_hover_selected="toast_hide_btn.tga"
+ image_disabled_selected="toast_hide_btn.tga"
+ />
+
+</panel>
diff --git a/indra/newview/skins/default/xui/en/panel_teleport_history.xml b/indra/newview/skins/default/xui/en/panel_teleport_history.xml
new file mode 100644
index 0000000000..82d6945e0f
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/panel_teleport_history.xml
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<panel name="Teleport History" bottom="0" height="326" left="0" width="380"
+ border="true" follows="left|top|right|bottom">
+ <scroll_list bottom="0" column_padding="0" draw_heading="false"
+ draw_stripes="false" follows="left|top|bottom|right" left="0"
+ multi_select="false" name="history_items" search_column="1"
+ sort_column="1" height="326" width="380" >
+ <column name="landmark_icon" width="20" />
+ <column dynamic_width="true" label="Region" name="region" />
+ <column name="index" width="0" />
+ </scroll_list>
+</panel>
diff --git a/indra/newview/skins/default/xui/en/panel_toast.xml b/indra/newview/skins/default/xui/en/panel_toast.xml
new file mode 100644
index 0000000000..441caffa28
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/panel_toast.xml
@@ -0,0 +1,72 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<!-- All our XML is utf-8 encoded. -->
+
+<floater
+ name="toast"
+ title=""
+ visible="false"
+ layout="topleft"
+ width="350"
+ height="72"
+ left="100"
+ top="500"
+ follows="right|bottom"
+ background_opaque="true"
+ background_visible="true"
+ bevel_style="in"
+ can_minimize="false"
+ can_tear_off="false"
+ can_resize="false"
+ can_drag_on_left="false"
+ can_close="false"
+ can_dock="false"
+ bg_alpha_color="0.3 0.3 0.3 1.0">
+
+ <text
+ visible="false"
+ follows="left|top|right|bottom"
+ font="SansSerifBold"
+ height="40"
+ layout="topleft"
+ left="60"
+ name="toast_text"
+ word_wrap="true"
+ text_color="white"
+ top="20"
+ width="290">
+ Toast text;
+ </text>
+ <icon
+ top="20"
+ left="10"
+ width="32"
+ height="32"
+ follows="top|left"
+ layout="topleft"
+ visible="false"
+ color="1 1 1 1"
+ enabled="true"
+ image_name="notify_tip_icon.tga"
+ mouse_opaque="true"
+ name="icon"
+ />
+ <button
+ layout="topleft"
+ top="-5"
+ left="335"
+ width="20"
+ height="20"
+ follows="top|right"
+ visible="false"
+ enabled="true"
+ mouse_opaque="true"
+ name="hide_btn"
+ label=""
+ tab_stop="false"
+ image_unselected="toast_hide_btn.tga"
+ image_disabled="toast_hide_btn.tga"
+ image_selected="toast_hide_btn.tga"
+ image_hover_selected="toast_hide_btn.tga"
+ image_disabled_selected="toast_hide_btn.tga"
+ />
+</floater>
diff --git a/indra/newview/skins/default/xui/en/panel_world_map.xml b/indra/newview/skins/default/xui/en/panel_world_map.xml
new file mode 100644
index 0000000000..ee355fa95c
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/panel_world_map.xml
@@ -0,0 +1,128 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<panel
+ follows="left|top|right|bottom"
+ height="300"
+ layout="topleft"
+ name="world_map"
+ width="400">
+ <panel.string
+ name="Loading">
+ Loading...
+ </panel.string>
+ <panel.string
+ name="InvalidLocation">
+ Invalid Location
+ </panel.string>
+ <panel.string
+ name="world_map_north">
+ N
+ </panel.string>
+ <panel.string
+ name="world_map_east">
+ E
+ </panel.string>
+ <panel.string
+ name="world_map_west">
+ W
+ </panel.string>
+ <panel.string
+ name="world_map_south">
+ S
+ </panel.string>
+ <panel.string
+ name="world_map_southeast">
+ SE
+ </panel.string>
+ <panel.string
+ name="world_map_northeast">
+ NE
+ </panel.string>
+ <panel.string
+ name="world_map_southwest">
+ SW
+ </panel.string>
+ <panel.string
+ name="world_map_northwest">
+ NW
+ </panel.string>
+ <text
+ type="string"
+ length="1"
+ label="N"
+ layout="topleft"
+ name="floater_map_north"
+ text="N"
+ text_color="1 1 1 0.7">
+ N
+ </text>
+ <text
+ type="string"
+ length="1"
+ label="E"
+ layout="topleft"
+ name="floater_map_east"
+ text="E"
+ text_color="1 1 1 0.7">
+ E
+ </text>
+ <text
+ type="string"
+ length="1"
+ label="W"
+ layout="topleft"
+ name="floater_map_west"
+ text="W"
+ text_color="1 1 1 0.7">
+ W
+ </text>
+ <text
+ type="string"
+ length="1"
+ label="S"
+ layout="topleft"
+ name="floater_map_south"
+ text="S"
+ text_color="1 1 1 0.7">
+ S
+ </text>
+ <text
+ type="string"
+ length="1"
+ label="SE"
+ layout="topleft"
+ name="floater_map_southeast"
+ text="SE"
+ text_color="1 1 1 0.7">
+ SE
+ </text>
+ <text
+ type="string"
+ length="1"
+ label="NE"
+ layout="topleft"
+ name="floater_map_northeast"
+ text="NE"
+ text_color="1 1 1 0.7">
+ NE
+ </text>
+ <text
+ type="string"
+ length="1"
+ label="SW"
+ layout="topleft"
+ name="floater_map_southwest"
+ text="SW"
+ text_color="1 1 1 0.7">
+ SW
+ </text>
+ <text
+ type="string"
+ length="1"
+ label="NW"
+ layout="topleft"
+ name="floater_map_northwest"
+ text="NW"
+ text_color="1 1 1 0.7">
+ NW
+ </text>
+</panel>
diff --git a/indra/newview/skins/default/xui/en/role_actions.xml b/indra/newview/skins/default/xui/en/role_actions.xml
new file mode 100644
index 0000000000..b89a975430
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/role_actions.xml
@@ -0,0 +1,187 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<role_actions>
+ <action_set
+ description="These Abilities include powers to add and remove group Members, and allow new Members to join without an invitation."
+ name="Membership">
+ <action description="Invite People to this Group"
+ longdescription="Invite People to this Group using the &apos;Invite New Person...&apos; button in the Members &amp; Roles tab &gt; Members sub-tab."
+ name="member invite" value="1" />
+ <action description="Eject Members from this Group"
+ longdescription="Eject Members from this Group using the &apos;Eject From Group&apos; button in the Members &amp; Roles tab &gt; Members sub-tab. An Owner can eject anyone except another Owner. If you&apos;re not an Owner, a Member can be ejected from a group if, and only if, they&apos;re only in the Everyone Role, and NO other Roles. To remove Members from Roles, you need to have the &apos;Remove Members from Roles&apos; Ability."
+ name="member eject" value="2" />
+ <action
+ description="Toggle &apos;Open Enrollment&apos; and change &apos;Signup Fee&apos;"
+ longdescription="Toggle &apos;Open Enrollment&apos; to let new Members join without an invitation, and change &apos;Signup Fee&apos; in the Group Preferences section of the General tab."
+ name="member options" value="3" />
+ </action_set>
+ <action_set
+ description="These Abilities include powers to add, remove, and change group Roles, add and remove Members in Roles, and assign Abilities to Roles."
+ name="Roles">
+ <action description="Create new Roles"
+ longdescription="Create new Roles in the Members &amp; Roles tab &gt; Roles sub-tab."
+ name="role create" value="4" />
+ <action description="Delete Roles"
+ longdescription="Delete Roles in the Members &amp; Roles tab &gt; Roles sub-tab."
+ name="role delete" value="5" />
+ <action description="Change Role names, titles, descriptions, and whether Role members are publicly visible"
+ longdescription="Change Role names, titles, descriptions, and whether Role members are publicly visible. This is done at the bottom of the the Members &amp; Roles tab &gt; Roles sub-tab after selecting a Role."
+ name="role properties" value="6" />
+ <action description="Assign Members to Assigner&apos;s Roles"
+ longdescription="Assign Members to Roles in the Assigned Roles section of the Members &amp; Roles tab &gt; Members sub-tab. A Member with this Ability can only add Members to a Role the assigner is already in."
+ name="role assign member limited" value="7" />
+ <action description="Assign Members to Any Role"
+ longdescription="Assign Members to Any Role in the Assigned Roles section of the Members &amp; Roles tab &gt; Members sub-tab. *WARNING* Any Member in a Role with this Ability can assign themselves--and any other non-Owner Member--to Roles that have more powers than they currently have, potentially elevating themselves to near-Owner power. Be sure you know what you&apos;re doing before assigning this Ability."
+ name="role assign member" value="8" />
+ <action description="Remove Members from Roles"
+ longdescription="Remove Members from Roles in the Assigned Roles section of the Members &amp; Roles tab &gt; Members sub-tab. Owners can&apos;t be removed."
+ name="role remove member" value="9" />
+ <action description="Assign and Remove Abilities in Roles"
+ longdescription="Assign and Remove Abilities in Roles in the Allowed Abilities section of the Members &amp; Roles tab &gt; Roles sub-tab. *WARNING* Any Member in a Role with this Ability can assign themselves--and any other non-Owner Member--all Abilities, potentially elevating themselves to near-Owner power. Be sure you know what you&apos;re doing before assigning this Ability."
+ name="role change actions" value="10" />
+ </action_set>
+ <action_set
+ description="These Abilities include powers to modify this group&apos;s identity, such as changing public visibility, charter, and insignia."
+ name="Group Identity">
+ <action
+ description="Change Charter, Insignia, and &apos;Show in search&apos;"
+ longdescription="Change Charter, Insignia, and &apos;Show in search&apos;. This is done in the General tab."
+ name="group change identity" value="11" />
+ </action_set>
+ <action_set
+ description="These Abilities include powers to deed, modify, and sell land in this group&apos;s land holdings. To get to the About Land window, right-click the ground and select &apos;About Land...&apos;, or click the parcel info in the menu bar."
+ name="Parcel Management">
+ <action description="Deed land and buy land for group"
+ longdescription="Deed land and buy land for group. This is done in About Land &gt; General tab."
+ name="land deed" value="12" />
+ <action description="Abandon land to Governor Linden"
+ longdescription="Abandon land to Governor Linden. *WARNING* Any Member in a Role with this Ability can abandon group-owned land in About Land &gt; General tab, reverting it to Linden ownership without a sale! Be sure you know what you&apos;re doing before assigning this Ability."
+ name="land release" value="13" />
+ <action description="Set land for sale info"
+ longdescription="Set land for sale info. *WARNING* Any Member in a Role with this Ability can sell group-owned land in About Land &gt; General tab as they wish! Be sure you know what you&apos;re doing before assigning this Ability."
+ name="land set sale info" value="14" />
+ <action description="Subdivide and join parcels"
+ longdescription="Subdivide and join parcels. This is done by right-clicking the ground, &apos;Edit Terrain&apos;, and dragging your mouse on the land to make a selection. To subdivide, select what you want to split and click &apos;Subdivide...&apos;. To join, select two or more contiguous parcels and click &apos;Join...&apos;. "
+ name="land divide join" value="15" />
+ </action_set>
+ <action_set
+ description="These Abilities include powers to change the parcel name and publish settings, Find directory visibility, and landing point &amp; TP routing options."
+ name="Parcel Identity">
+ <action description="Toggle &apos;Show in Find Places&apos; and set category"
+ longdescription="Toggle &apos;Show in Find Places&apos; and setting a parcel&apos;s category in About Land &gt; Options tab."
+ name="land find places" value="17" />
+ <action
+ description="Change parcel name, description, and &apos;Show in search&apos; settings"
+ longdescription="Change parcel name, description, and &apos;Show in search&apos; settings. This is done in About Land &gt; Options tab."
+ name="land change identity" value="18" />
+ <action description="Set landing point and set teleport routing"
+ longdescription="On a group-owned parcel, Members in a Role with this Ability can set a landing point to specify where incoming teleports arrive, and also set teleport routing for further control. This is done in About Land &gt; Options tab."
+ name="land set landing point" value="19" />
+ </action_set>
+ <action_set
+ description="These Abilities include powers which affect parcel options, such as &apos;Create Objects&apos;, &apos;Edit Terrain&apos;, and music &amp; media settings."
+ name="Parcel Settings">
+ <action description="Change music &amp; media settings"
+ longdescription="Change streaming music and movie settings in About Land &gt; Media tab."
+ name="land change media" value="20" />
+ <action description="Toggle &apos;Edit Terrain&apos;"
+ longdescription="Toggle &apos;Edit Terrain&apos;. *WARNING* About Land &gt; Options tab &gt; Edit Terrain allows anyone to terraform your land&apos;s shape, and place and move Linden plants. Be sure you know what you&apos;re doing before assigning this Ability. Editing terrain is toggled in About Land &gt; Options tab."
+ name="land edit" value="21" />
+ <action description="Toggle various About Land &gt; Options settings"
+ longdescription="Toggle &apos;Safe (no damage)&apos;, &apos;Fly&apos;, and allow other Residents to: &apos;Create Objects&apos;, &apos;Edit Terrain&apos;, &apos;Create Landmarks&apos;, and &apos;Run Scripts&apos; on group-owned land in About Land &gt; Options tab."
+ name="land options" value="22" />
+ </action_set>
+ <action_set
+ description="These Abilities include powers which allow Members to bypass restrictions on group-owned parcels."
+ name="Parcel Powers">
+ <action description="Always allow &apos;Edit Terrain&apos;"
+ longdescription="Members in a Role with this Ability can edit terrain on a group-owned parcel, even if it&apos;s turned off in About Land &gt; Options tab."
+ name="land allow edit land" value="23" />
+ <action description="Always allow &apos;Fly&apos;"
+ longdescription="Members in a Role with this Ability can fly on a group-owned parcel, even if it&apos;s turned off in About Land &gt; Options tab."
+ name="land allow fly" value="24" />
+ <action description="Always allow &apos;Create Objects&apos;"
+ longdescription="Members in a Role with this Ability can create objects on a group-owned parcel, even if it&apos;s turned off in About Land &gt; Options tab."
+ name="land allow create" value="25" />
+ <action description="Always allow &apos;Create Landmark&apos;"
+ longdescription="Members in a Role with this Ability can landmark a group-owned parcel, even if it&apos;s turned off in About Land &gt; Options tab."
+ name="land allow landmark" value="26" />
+ <action description="Allow &apos;Set Home to Here&apos; on group land"
+ longdescription="Members in a Role with this Ability can use World menu &gt; Set Home to Here on a parcel deeded to this group."
+ name="land allow set home" value="28" />
+ </action_set>
+ <action_set
+ description="These Abilities include powers to allow or restrict access to group-owned parcels, including freezing and ejecting Residents."
+ name="Parcel Access">
+ <action description="Manage parcel Access lists"
+ longdescription="Manage parcel Access lists in About Land &gt; Access tab."
+ name="land manage allowed" value="29" />
+ <action description="Manage parcel Ban lists"
+ longdescription="Manage parcel Ban lists in About Land &gt; Ban tab."
+ name="land manage banned" value="30" />
+ <action description="Change parcel &apos;Sell passes...&apos; settings"
+ longdescription="Change parcel &apos;Sell passes...&apos; settings in About Land &gt; Access tab."
+ name="land manage passes" value="31" />
+ <action description="Eject and freeze Residents on parcels"
+ longdescription="Members in a Role with this Ability can handle an unwelcome Resident on a group-owned parcel by right-clicking them, More &gt;, and selecting &apos;Eject...&apos; or &apos;Freeze...&apos;."
+ name="land admin" value="32" />
+ </action_set>
+ <action_set
+ description="These Abilities include powers to allow members to return objects and place and move Linden plants. This is useful for Members to clean up litter and do landscaping, but it should also be used with care, because there&apos;s no undo for returning objects."
+ name="Parcel Content">
+ <action description="Return objects owned by group"
+ longdescription="Return objects on group-owned parcels that are owned by the group in About Land &gt; Objects tab."
+ name="land return group owned" value="48" />
+ <action description="Return objects set to group"
+ longdescription="Return objects on group-owned parcels that are set to the group in About Land &gt; Objects tab."
+ name="land return group set" value="33" />
+ <action description="Return non-group objects"
+ longdescription="Return objects on group-owned parcels that are non-group in About Land &gt; Objects tab."
+ name="land return non group" value="34" />
+ <action description="Landscaping using Linden plants"
+ longdescription="Landscaping ability to place and move Linden trees, plants, and grasses. These items can be found in your inventory&apos;s Library &gt; Objects folder or they can be created via the Build button."
+ name="land gardening" value="35" />
+ </action_set>
+ <action_set
+ description="These Abilities include powers to deed, modify, and sell group-owned objects. These changes are done in the Edit Tools &gt; General Tab. Right-click an object and Edit to see its settings. "
+ name="Object Management">
+ <action description="Deed objects to group"
+ longdescription="Deed objects to group in the Edit Tools &gt; General Tab."
+ name="object deed" value="36" />
+ <action description="Manipulate (move, copy, modify) group-owned objects"
+ longdescription="Manipulate (move, copy, modify) group-owned objects in the Edit Tools &gt; General Tab."
+ name="object manipulate" value="38" />
+ <action description="Set group-owned objects for sale"
+ longdescription="Set group-owned objects for sale in the Edit Tools &gt; General tab."
+ name="object set sale" value="39" />
+ </action_set>
+ <action_set
+ description="These Abilities include powers which require Members to pay group liabilities and receive group dividends, and restrict access to group account history."
+ name="Accounting">
+ <action description="Pay group liabilities and receive group dividends"
+ longdescription="Members in a Role with this Ability will automatically pay group liabilities and receive group dividends. This means they will receive a portion of group-owned land sales which are distributed daily, as well as contribute towards things like parcel listing fees. "
+ name="accounting accountable" value="40" />
+ </action_set>
+ <action_set
+ description="These Abilities include powers to allow Members to send, receive, and view group Notices."
+ name="Notices">
+ <action description="Send Notices"
+ longdescription="Members in a Role with this Ability can send Notices in Group Information &gt; Notices tab."
+ name="notices send" value="42" />
+ <action description="Receive Notices and view past Notices"
+ longdescription="Members in a Role with this Ability can receive Notices and view past Notices in Group Information &gt; Notices tab."
+ name="notices receive" value="43" />
+ </action_set>
+ <action_set
+ description="These Abilities include powers to allow or restrict access to group chat sessions and group voice chat."
+ name="Chat">
+ <action description="Join Group Chat"
+ longdescription="Members in a Role with this Ability can join group chat sessions, for text and voice."
+ name="join group chat" value="16" />
+ <action description="Join Group Voice Chat"
+ longdescription="Members in a Role with this Ability can join group voice chat sessions. NOTE: The Join Group Chat ability is required to access the voice chat session."
+ name="join voice chat" value="27" />
+ <action description="Moderate Group Chat"
+ longdescription="Members in a Role with this Ability can control access and participation in group voice and text chat sessions."
+ name="moderate group chat" value="37" />
+ </action_set>
+</role_actions>
diff --git a/indra/newview/skins/default/xui/en/strings.xml b/indra/newview/skins/default/xui/en/strings.xml
new file mode 100644
index 0000000000..4c9b1897d5
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/strings.xml
@@ -0,0 +1,1334 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<!-- This file contains strings that used to be hardcoded in the source.
+ It is only for those strings which do not belong in a floater.
+ For example, the strings used in avatar chat bubbles, and strings
+ that are returned from one component and may appear in many places-->
+<strings>
+
+ <!-- Default Args - these arguments will be replaced in all strings -->
+ <string name="SECOND_LIFE">Second Life</string>
+ <string name="APP_NAME">Second Life</string>
+ <string name="SECOND_LIFE_GRID">Second Life Grid</string>
+ <string name="SUPPORT_SITE">Second Life Support Portal</string>
+
+ <!-- starting up -->
+ <string name="StartupDetectingHardware">Detecting hardware...</string>
+ <string name="StartupLoading">Loading</string>
+ <string name="Fullbright">Fullbright (Legacy)</string>
+ <string name="CacheWaiting">(Loading...)</string>
+ <string name="CacheNobody">(nobody)</string>
+ <string name="CacheNone">(none)</string>
+ <!-- Login -->
+ <string name="LoginInProgress">Logging in. [APP_NAME] may appear frozen. Please wait.</string>
+ <string name="LoginInProgressNoFrozen">Logging in...</string>
+ <string name="LoginAuthenticating">Authenticating</string>
+ <string name="LoginMaintenance">Performing account maintenance...</string>
+ <string name="LoginAttempt">Previous login attempt failed. Logging in, attempt [NUMBER]</string>
+ <string name="LoginPrecaching">Loading world...</string>
+ <string name="LoginInitializingBrowser">Initializing embedded web browser...</string>
+ <string name="LoginInitializingMultimedia">Initializing multimedia...</string>
+ <string name="LoginInitializingFonts">Loading fonts...</string>
+ <string name="LoginVerifyingCache">Verifying cache files (can take 60-90 seconds)...</string>
+ <string name="LoginProcessingResponse">Processing Response...</string>
+ <string name="LoginInitializingWorld">Initializing World...</string>
+ <string name="LoginDecodingImages">Decoding images...</string>
+ <string name="LoginInitializingQuicktime">Initializing QuickTime...</string>
+ <string name="LoginQuicktimeNotFound">QuickTime not found - unable to initialize.</string>
+ <string name="LoginQuicktimeOK">QuickTime initialized successfully.</string>
+ <string name="LoginWaitingForRegionHandshake">Waiting for region handshake...</string>
+ <string name="LoginConnectingToRegion">Connecting to region...</string>
+ <string name="LoginDownloadingClothing">Downloading clothing...</string>
+ <string name="LoginFailedNoNetwork">Network Error: Could not establish connection, please check your network connection.</string>
+ <string name="Quit">Quit</string>
+ <string name="create_account_url">http://secondlife.com/registration/</string>
+
+ <!-- Disconnection -->
+ <string name="AgentLostConnection">This region may be experiencing trouble. Please check your connection to the Internet.</string>
+
+
+ <!-- Tooltip, llhoverview.cpp -->
+ <string name="TooltipPerson">Person</string><!-- Object under mouse pointer is an avatar -->
+ <string name="TooltipNoName">(no name)</string> <!-- No name on an object -->
+ <string name="TooltipOwner">Owner:</string> <!-- Owner name follows -->
+ <string name="TooltipPublic">Public</string> <!-- Public permissions on an object -->
+ <string name="TooltipIsGroup">(Group)</string> <!-- The name before this text is that of a group -->
+ <string name="TooltipFlagScript">Script</string>
+ <string name="TooltipFlagPhysics">Physics</string>
+ <string name="TooltipFlagTouch">Touch</string>
+ <string name="TooltipFlagL$">L$</string>
+ <string name="TooltipFlagDropInventory">Drop Inventory</string>
+ <string name="TooltipFlagPhantom">Phantom</string>
+ <string name="TooltipFlagTemporary">Temporary</string>
+ <string name="TooltipFlagRightClickMenu">(Right-click for menu)</string>
+ <string name="TooltipFreeToCopy">Free to copy</string>
+ <string name="TooltipForSaleL$">For Sale: L$[AMOUNT]</string> <!-- L$ version -->
+ <string name="TooltipForSaleMsg">For Sale: [MESSAGE]</string> <!-- Message (RetrievingData) -->
+ <string name="TooltipFlagGroupBuild">Group Build</string>
+ <string name="TooltipFlagNoBuild">No Build</string>
+ <string name="TooltipFlagNoEdit">Group Build</string>
+ <string name="TooltipFlagNotSafe">Not Safe</string><!-- damage area -->
+ <string name="TooltipFlagNoFly">No Fly</string>
+ <string name="TooltipFlagGroupScripts">Group Scripts</string>
+ <string name="TooltipFlagNoScripts">No Scripts</string>
+ <string name="TooltipLand">Land:</string>
+ <string name="TooltipMustSingleDrop">Only a single item can be dragged here</string>
+ <string name="TooltipAltLeft">Alt-Left arrow for previous tab</string>
+ <string name="TooltipAltRight">Alt-Right arrow for next tab</string>
+
+ <!-- ButtonToolTips, llfloater.cpp -->
+ <string name="BUTTON_CLOSE_DARWIN">Close (&#8984;-W)</string>
+ <string name="BUTTON_CLOSE_WIN">Close (Ctrl-W)</string>
+ <string name="BUTTON_RESTORE">Restore</string>
+ <string name="BUTTON_MINIMIZE">Minimize</string>
+ <string name="BUTTON_TEAR_OFF">Tear Off</string>
+ <string name="BUTTON_EDIT">Edit</string>
+ <string name="BUTTON_DOCK">Dock</string>
+ <string name="BUTTON_UNDOCK">Undock</string>
+
+ <!-- searching - generic -->
+ <string name="Searching">Searching...</string>
+ <string name="NoneFound">None found.</string>
+
+ <!-- Indicates that an avatar name or other similar datum is being retrieved. General usage. -->
+ <string name="RetrievingData">Retrieving...</string>
+
+ <string name="ReleaseNotes">Release Notes</string>
+ <string name="RELEASE_NOTES_BASE_URL">http://secondlife.com/app/releasenotes/</string>
+
+ <!-- Indicates something is being loaded. Maybe should be merged with RetrievingData -->
+ <string name="LoadingData">Loading...</string>
+
+
+ <!-- namecache -->
+ <!-- Avatar name: text shown for LLUUID::null -->
+ <string name="AvatarNameNobody">(nobody)</string>
+
+ <!-- Avatar name: text shown while fetching name -->
+ <string name="AvatarNameWaiting">(waiting)</string>
+
+ <!-- Avatar name: text shown as an alternative to AvatarNameFetching, easter egg. -->
+ <string name="AvatarNameHippos">(hippos)</string>
+
+ <!-- Group name: text shown for LLUUID::null -->
+ <string name="GroupNameNone">(none)</string>
+
+ <!-- Asset errors. Used in llassetstorage.cpp, translation from error code to error message. -->
+ <string name="AssetErrorNone">No error</string>
+ <string name="AssetErrorRequestFailed">Asset request: failed</string>
+ <string name="AssetErrorNonexistentFile">Asset request: non-existent file</string>
+ <string name="AssetErrorNotInDatabase">Asset request: asset not found in database</string>
+ <string name="AssetErrorEOF">End of file</string>
+ <string name="AssetErrorCannotOpenFile">Cannot open file</string>
+ <string name="AssetErrorFileNotFound">File not found</string>
+ <string name="AssetErrorTCPTimeout">File transfer timeout</string>
+ <string name="AssetErrorCircuitGone">Circuit gone</string>
+ <string name="AssetErrorPriceMismatch">Viewer and server do not agree on price</string>
+ <string name="AssetErrorUnknownStatus">Unknown status</string>
+
+ <!-- Asset Type Human Names -->
+ <string name="texture">texture</string>
+ <string name="sound">sound</string>
+ <string name="calling card">calling card</string>
+ <string name="landmark">landmark</string>
+ <string name="legacy script">legacy script</string>
+ <string name="clothing">clothing</string>
+ <string name="object">object</string>
+ <string name="note card">note card</string>
+ <string name="folder">folder</string>
+ <string name="root">root</string>
+ <string name="lsl2 script">lsl2 script</string>
+ <string name="lsl bytecode">lsl bytecode</string>
+ <string name="tga texture">tga texture</string>
+ <string name="body part">body part</string>
+ <string name="snapshot">snapshot</string>
+ <string name="lost and found">lost and found</string>
+ <string name="targa image">targa image</string>
+ <string name="trash">trash</string>
+ <string name="jpeg image">jpeg image</string>
+ <string name="animation">animation</string>
+ <string name="gesture">gesture</string>
+ <string name="simstate">simstate</string>
+ <string name="favorite">favorite</string>
+ <string name="symbolic link">link</string>
+
+ <!-- llvoavatar. Displayed in the avatar chat bubble -->
+ <string name="AvatarEditingAppearance">(Editing Appearance)</string>
+ <string name="AvatarAway">Away</string>
+ <string name="AvatarBusy">Busy</string>
+ <string name="AvatarMuted">Blocked</string>
+
+ <!-- animations -->
+ <string name="anim_express_afraid">Afraid</string>
+ <string name="anim_express_anger">Angry</string>
+ <string name="anim_away">Away</string>
+ <string name="anim_backflip">Backflip</string>
+ <string name="anim_express_laugh">Belly Laugh</string>
+ <string name="anim_express_toothsmile">BigSmile</string>
+ <string name="anim_blowkiss">Blow Kiss</string>
+ <string name="anim_express_bored">Bored</string>
+ <string name="anim_bow">Bow</string>
+ <string name="anim_clap">Clap</string>
+ <string name="anim_courtbow">Court Bow</string>
+ <string name="anim_express_cry">Cry</string>
+ <string name="anim_dance1">Dance 1</string>
+ <string name="anim_dance2">Dance 2</string>
+ <string name="anim_dance3">Dance 3</string>
+ <string name="anim_dance4">Dance 4</string>
+ <string name="anim_dance5">Dance 5</string>
+ <string name="anim_dance6">Dance 6</string>
+ <string name="anim_dance7">Dance 7</string>
+ <string name="anim_dance8">Dance 8</string>
+ <string name="anim_express_disdain">Disdain</string>
+ <string name="anim_drink">Drink</string>
+ <string name="anim_express_embarrased">Embarrassed</string>
+ <string name="anim_angry_fingerwag">Finger Wag</string>
+ <string name="anim_fist_pump">Fist Pump</string>
+ <string name="anim_yoga_float">Floating Yoga</string>
+ <string name="anim_express_frown">Frown</string>
+ <string name="anim_impatient">Impatient</string>
+ <string name="anim_jumpforjoy">Jump For Joy</string>
+ <string name="anim_kissmybutt">Kiss My Butt</string>
+ <string name="anim_express_kiss">Kiss</string>
+ <string name="anim_laugh_short">Laugh</string>
+ <string name="anim_musclebeach">Muscle Beach</string>
+ <string name="anim_no_unhappy">No (Unhappy)</string>
+ <string name="anim_no_head">No</string>
+ <string name="anim_nyanya">Nya-nya-nya</string>
+ <string name="anim_punch_onetwo">One-Two Punch</string>
+ <string name="anim_express_open_mouth">Open Mouth</string>
+ <string name="anim_peace">Peace</string>
+ <string name="anim_point_you">Point at Other</string>
+ <string name="anim_point_me">Point at Self</string>
+ <string name="anim_punch_l">Punch Left</string>
+ <string name="anim_punch_r">Punch Right</string>
+ <string name="anim_rps_countdown">RPS count</string>
+ <string name="anim_rps_paper">RPS paper</string>
+ <string name="anim_rps_rock">RPS rock</string>
+ <string name="anim_rps_scissors">RPS scissors</string>
+ <string name="anim_express_repulsed">Repulsed</string>
+ <string name="anim_kick_roundhouse_r">Roundhouse Kick</string>
+ <string name="anim_express_sad">Sad</string>
+ <string name="anim_salute">Salute</string>
+ <string name="anim_shout">Shout</string>
+ <string name="anim_express_shrug">Shrug</string>
+ <string name="anim_express_smile">Smile</string>
+ <string name="anim_smoke_idle">Smoke Idle</string>
+ <string name="anim_smoke_inhale">Smoke Inhale</string>
+ <string name="anim_smoke_throw_down">Smoke Throw Down</string>
+ <string name="anim_express_surprise">Surprise</string>
+ <string name="anim_sword_strike_r">Sword Strike</string>
+ <string name="anim_angry_tantrum">Tantrum</string>
+ <string name="anim_express_tongue_out">TongueOut</string>
+ <string name="anim_hello">Wave</string>
+ <string name="anim_whisper">Whisper</string>
+ <string name="anim_whistle">Whistle</string>
+ <string name="anim_express_wink">Wink</string>
+ <string name="anim_wink_hollywood">Wink (Hollywood)</string>
+ <string name="anim_express_worry">Worry</string>
+ <string name="anim_yes_happy">Yes (Happy)</string>
+ <string name="anim_yes_head">Yes</string>
+
+ <string name="texture_loading">Loading...</string>
+ <string name="worldmap_offline">Offline</string>
+
+ <!-- animations uploading status codes -->
+ <string name="Ok">OK</string>
+ <string name="Premature end of file">Premature end of file</string>
+ <string name="ST_NO_JOINT">Can't find ROOT or JOINT.</string>
+
+ <!-- Chat -->
+ <string name="whisper">whispers:</string>
+ <string name="shout">shouts:</string>
+ <string name="ringing">Connecting to in-world Voice Chat...</string>
+ <string name="connected">Connected</string>
+ <string name="unavailable">Voice not available at your current location</string>
+ <string name="hang_up">Disconnected from in-world Voice Chat</string>
+ <string name="ScriptQuestionCautionChatGranted">'[OBJECTNAME]', an object owned by '[OWNERNAME]', located in [REGIONNAME] at [REGIONPOS], has been granted permission to: [PERMISSIONS].</string>
+ <string name="ScriptQuestionCautionChatDenied">'[OBJECTNAME]', an object owned by '[OWNERNAME]', located in [REGIONNAME] at [REGIONPOS], has been denied permission to: [PERMISSIONS].</string>
+ <string name="ScriptTakeMoney">Take Linden dollars (L$) from you</string>
+ <string name="ActOnControlInputs">Act on your control inputs</string>
+ <string name="RemapControlInputs">Remap your control inputs</string>
+ <string name="AnimateYourAvatar">Animate your avatar</string>
+ <string name="AttachToYourAvatar">Attach to your avatar</string>
+ <string name="ReleaseOwnership">Release ownership and become public</string>
+ <string name="LinkAndDelink">Link and delink from other objects</string>
+ <string name="AddAndRemoveJoints">Add and remove joints with other objects</string>
+ <string name="ChangePermissions">Change its permissions</string>
+ <string name="TrackYourCamera">Track your camera</string>
+ <string name="ControlYourCamera">Control your camera</string>
+
+ <!-- IM -->
+ <string name="IM_logging_string">-- Instant message logging enabled --</string>
+
+ <!-- Sim Access labels -->
+ <string name="SIM_ACCESS_PG">PG</string>
+ <string name="SIM_ACCESS_MATURE">Mature</string>
+ <string name="SIM_ACCESS_ADULT">Adult</string>
+ <string name="SIM_ACCESS_DOWN">Offline</string>
+ <string name="SIM_ACCESS_MIN">Unknown</string>
+
+ <!-- For use when we do not have land type back from the server -->
+ <string name="land_type_unknown">(unknown)</string>
+
+ <!-- File load/save dialogs -->
+ <string name="all_files">All Files</string>
+ <string name="sound_files">Sounds</string>
+ <string name="animation_files">Animations</string>
+ <string name="image_files">Images</string>
+ <string name="save_file_verb">Save</string>
+ <string name="load_file_verb">Load</string>
+ <string name="targa_image_files">Targa Images</string>
+ <string name="bitmap_image_files">Bitmap Images</string>
+ <string name="avi_movie_file">AVI Movie File</string>
+ <string name="xaf_animation_file">XAF Anim File</string>
+ <string name="xml_file">XML File</string>
+ <string name="dot_raw_file">RAW File</string>
+ <string name="compressed_image_files">Compressed Images</string>
+ <string name="load_files">Load Files</string>
+ <string name="choose_the_directory">Choose Directory</string>
+
+ <!-- LSL Usage Hover Tips -->
+ <string name="LSLTipSleepTime">Sleeps script for [SLEEP_TIME] seconds.</string>
+
+ <string name="LSLTipText_llSin">float llSin(float theta)\ntheta in radians</string>
+ <string name="LSLTipText_llCos">float llCos(float theta)\ntheta in radians</string>
+ <string name="LSLTipText_llTan">float llTan(float theta)\ntheta radians</string>
+ <string name="LSLTipText_llAtan2">float llAtan2(float y, float x)</string>
+ <string name="LSLTipText_llSqrt">float llSqrt(float val)\nreturns 0 and triggers a Math Error for imaginary results</string>
+ <string name="LSLTipText_llPow">float llPow(float base, float exponent)\nreturns 0 and triggers Math Error for imaginary results</string>
+ <string name="LSLTipText_llAbs">integer llAbs(integer val)</string>
+ <string name="LSLTipText_llFabs">float llFabs(float val)</string>
+ <string name="LSLTipText_llFrand">float llFrand(float mag)\nreturns random number in range [0,mag)</string>
+ <string name="LSLTipText_llFloor">integer llFloor(float val)\nreturns largest integer value &lt;= val</string>
+ <string name="LSLTipText_llCeil">integer llCeil(float val)\nreturns smallest integer value &gt;= val</string>
+ <string name="LSLTipText_llRound">integer llRound(float val)\nreturns val rounded to the nearest integer</string>
+ <string name="LSLTipText_llVecMag">float llVecMag(vector v)\nreturns the magnitude of v</string>
+ <string name="LSLTipText_llVecNorm">vector llVecNorm(vector v)\nreturns the v normalized</string>
+ <string name="LSLTipText_llVecDist">float llVecDist(vector v1, vector v2)\nreturns the 3D distance between v1 and v2</string>
+ <string name="LSLTipText_llRot2Euler">vector llRot2Euler(rotation q)\nreturns the Euler representation (roll, pitch, yaw) of q</string>
+ <string name="LSLTipText_llEuler2Rot">rotation llEuler2Rot(vector v)\nreturns the rotation representation of Euler Angles v</string>
+ <string name="LSLTipText_llAxes2Rot">rotation llAxes2Rot(vector fwd, vector left, vector up)\nreturns the rotation defined by the coordinate axes</string>
+ <string name="LSLTipText_llRot2Fwd">vector llRot2Fwd(rotation q)\nreturns the forward vector defined by q</string>
+ <string name="LSLTipText_llRot2Left">vector llRot2Left(rotation q)\nreturns the left vector defined by q</string>
+ <string name="LSLTipText_llRot2Up">vector llRot2Up(rotation q)\nreturns the up vector defined by q</string>
+ <string name="LSLTipText_llRotBetween">rotation llRotBetween(vector v1, vector v2)\nreturns the rotation to rotate v1 to v2</string>
+ <string name="LSLTipText_llWhisper">llWhisper(integer channel, string msg)\nwhispers msg on channel</string>
+ <string name="LSLTipText_llSay">llSay(integer channel, string msg)\nsays msg on channel</string>
+ <string name="LSLTipText_llShout">llShout(integer channel, string msg)\nshouts msg on channel</string>
+ <string name="LSLTipText_llListen">integer llListen(integer channel, string name, key id, string msg)\nsets a callback for msg on channel from name and id (name, id, and/or msg can be empty) and returns an identifier that can be used to deactivate or remove the listen</string>
+ <string name="LSLTipText_llListenControl">llListenControl(integer number, integer active)\nmakes a listen event callback active or inactive</string>
+ <string name="LSLTipText_llListenRemove">llListenRemove(integer number)\nremoves listen event callback number</string>
+ <string name="LSLTipText_llSensor">llSensor(string name, key id, integer type, float range, float arc)\nPerforms a single scan for name and id with type (AGENT, ACTIVE, PASSIVE, and/or SCRIPTED) within range meters and arc radians of forward vector (name, id, and/or keytype can be empty or 0)</string>
+ <string name="LSLTipText_llSensorRepeat">llSensorRepeat(string name, key id, integer type, float range, float arc, float rate)\nsets a callback for name and id with type (AGENT, ACTIVE, PASSIVE, and/or SCRIPTED) within range meters and arc radians of forward vector (name, id, and/or keytype can be empty or 0) and repeats every rate seconds</string>
+ <string name="LSLTipText_llSensorRemove">llSensorRemove()\nremoves sensor</string>
+ <string name="LSLTipText_llDetectedName">string llDetectedName(integer number)\nreturns the name of detected object number (returns empty string if number is not valid sensed object)</string>
+ <string name="LSLTipText_llDetectedKey">key llDetectedKey(integer number)\nreturns the key of detected object number (returns empty key if number is not valid sensed object)</string>
+ <string name="LSLTipText_llDetectedOwner">key llDetectedOwner(integer number)\nreturns the key of detected object&apos;s owner (returns empty key if number is not valid sensed object)</string>
+ <string name="LSLTipText_llDetectedType">integer llDetectedType(integer number)\nreturns the type (AGENT, ACTIVE, PASSIVE, SCRIPTED) of detected object (returns 0 if number is not valid sensed object)</string>
+ <string name="LSLTipText_llDetectedPos">vector llDetectedPos(integer number)\nreturns the position of detected object number (returns &lt;0,0,0&gt; if number is not valid sensed object)</string>
+ <string name="LSLTipText_llDetectedVel">vector llDetectedVel(integer number)\nreturns the velocity of detected object number (returns &lt;0,0,0&gt; if number is not valid sensed object)</string>
+ <string name="LSLTipText_llDetectedGrab">vector llDetectedGrab(integer number)\nreturns the grab offset of the user touching object (returns &lt;0,0,0&gt; if number is not valid sensed object)</string>
+ <string name="LSLTipText_llDetectedRot">rotation llDetectedRot(integer number)\nreturns the rotation of detected object number (returns &lt;0,0,0,1&gt; if number is not valid sensed object)</string>
+ <string name="LSLTipText_llDetectedGroup">integer llDetectedGroup(integer number)\nReturns TRUE if detected object is part of same group as owner</string>
+ <string name="LSLTipText_llDetectedLinkNumber">integer llDetectedLinkNumber(integer number)\nreturns the link position of the triggered event for touches and collisions only</string>
+ <string name="LSLTipText_llDie">llDie()\ndeletes the object</string>
+ <string name="LSLTipText_llGround">float llGround(vector v)\nreturns the ground height below the object position + v</string>
+ <string name="LSLTipText_llCloud">float llCloud(vector v)\nreturns the cloud density at the object position + v</string>
+ <string name="LSLTipText_llWind">vector llWind(vector v)\nreturns the wind velocity at the object position + v</string>
+ <string name="LSLTipText_llSetStatus">llSetStatus(integer status, integer value)\nsets status (STATUS_PHYSICS, STATUS_PHANTOM, STATUS_BLOCK_GRAB,\nSTATUS_ROTATE_X, STATUS_ROTATE_Y, and/or STATUS_ROTATE_Z) to value</string>
+ <string name="LSLTipText_llGetStatus">integer llGetStatus(integer status)\ngets value of status (STATUS_PHYSICS, STATUS_PHANTOM, STATUS_BLOCK_GRAB,\nSTATUS_ROTATE_X, STATUS_ROTATE_Y, and/or STATUS_ROTATE_Z)</string>
+ <string name="LSLTipText_llSetScale">llSetScale(vector scale)\nsets the scale</string>
+ <string name="LSLTipText_llGetScale">vector llGetScale()\ngets the scale</string>
+ <string name="LSLTipText_llSetColor">llSetColor(vector color, integer face)\nsets the color</string>
+ <string name="LSLTipText_llGetAlpha">float llGetAlpha(integer face)\ngets the alpha</string>
+ <string name="LSLTipText_llSetAlpha">llSetAlpha(float alpha, integer face)\nsets the alpha</string>
+ <string name="LSLTipText_llGetColor">vector llGetColor(integer face)\ngets the color</string>
+ <string name="LSLTipText_llSetTexture">llSetTexture(string texture, integer face)\nsets the texture of face</string>
+ <string name="LSLTipText_llScaleTexture">llScaleTexture(float scales, float scalet, integer face)\nsets the texture s, t scales for the chosen face</string>
+ <string name="LSLTipText_llOffsetTexture">llOffsetTexture(float offsets, float offsett, integer face)\nsets the texture s, t offsets for the chosen face</string>
+ <string name="LSLTipText_llRotateTexture">llRotateTexture(float rotation, integer face)\nsets the texture rotation for the chosen face</string>
+ <string name="LSLTipText_llGetTexture">string llGetTexture(integer face)\ngets the texture of face (if it&apos;s a texture in the object inventory, otherwise the key in a string)</string>
+ <string name="LSLTipText_llSetPos">llSetPos(vector pos)\nsets the position (if the script isn&apos;t physical)</string>
+ <string name="LSLTipText_llGetPos">vector llGetPos()\ngets the position (if the script isn&apos;t physical)</string>
+ <string name="LSLTipText_llGetLocalPos">vector llGetLocalPos()\ngets the position relative to the root (if the script isn&apos;t physical)</string>
+ <string name="LSLTipText_llSetRot">llSetRot(rotation rot)\nsets the rotation (if the script isn&apos;t physical)</string>
+ <string name="LSLTipText_llGetRot">rotation llGetRot()\ngets the rotation (if the script isn&apos;t physical)</string>
+ <string name="LSLTipText_llGetLocalRot">rotation llGetLocalRot()\ngets the rotation local to the root (if the script isn&apos;t physical)</string>
+ <string name="LSLTipText_llSetForce">llSetForce(vector force, integer local)\nsets force on object, in local coords if local == TRUE (if the script is physical)</string>
+ <string name="LSLTipText_llGetForce">vector llGetForce()\ngets the force (if the script is physical)</string>
+ <string name="LSLTipText_llTarget">integer llTarget(vector position, float range)\nset positions within range of position as a target and return an ID for the target</string>
+ <string name="LSLTipText_llTargetRemove">llTargetRemove(integer number)\nremoves target number</string>
+ <string name="LSLTipText_llRotTarget">integer llRotTarget(rotation rot, float error)\nset rotations with error of rot as a rotational target and return an ID for the rotational target</string>
+ <string name="LSLTipText_llRotTargetRemove">llRotTargetRemove(integer number)\nremoves rotational target number</string>
+ <string name="LSLTipText_llMoveToTarget">llMoveToTarget(vector target, float tau)\ncritically damp to target in tau seconds (if the script is physical)</string>
+ <string name="LSLTipText_llStopMoveToTarget">llStopMoveToTarget()\nStops critically damped motion</string>
+ <string name="LSLTipText_llApplyImpulse">llApplyImpulse(vector force, integer local)\napplies impulse to object, in local coords if local == TRUE (if the script is physical)</string>
+ <string name="LSLTipText_llApplyRotationalImpulse">llApplyRotationalImpulse(vector force, integer local)\napplies rotational impulse to object, in local coords if local == TRUE (if the script is physical)</string>
+ <string name="LSLTipText_llSetTorque">llSetTorque(vector torque, integer local)\nsets the torque of object, in local coords if local == TRUE (if the script is physical)</string>
+ <string name="LSLTipText_llGetTorque">vector llGetTorque()\ngets the torque (if the script is physical)</string>
+ <string name="LSLTipText_llSetForceAndTorque">llSetForceAndTorque(vector force, vector torque, integer local)\nsets the force and torque of object, in local coords if local == TRUE (if the script is physical)</string>
+ <string name="LSLTipText_llGetVel">vector llGetVel()\ngets the velocity</string>
+ <string name="LSLTipText_llGetAccel">vector llGetAccel()\ngets the acceleration</string>
+ <string name="LSLTipText_llGetOmega">vector llGetOmega()\ngets the omega</string>
+ <string name="LSLTipText_llGetTimeOfDay">float llGetTimeOfDay()\ngets the time in seconds since Second Life server midnight (or since server up-time; whichever is smaller)</string>
+ <string name="LSLTipText_llGetWallclock">float llGetWallclock()\ngets the time in seconds since midnight</string>
+ <string name="LSLTipText_llGetTime">float llGetTime()\ngets the time in seconds since creation</string>
+ <string name="LSLTipText_llResetTime">llResetTime()\nsets the time to zero</string>
+ <string name="LSLTipText_llGetAndResetTime">float llGetAndResetTime()\ngets the time in seconds since creation and sets the time to zero</string>
+ <string name="LSLTipText_llSound">llSound(string sound, float volume, integer queue, integer loop)\nplays sound at volume and whether it should loop or not</string>
+ <string name="LSLTipText_llPlaySound">llPlaySound(string sound, float volume)\nplays attached sound once at volume (0.0 - 1.0)</string>
+ <string name="LSLTipText_llLoopSound">llLoopSound(string sound, float volume)\nplays attached sound looping indefinitely at volume (0.0 - 1.0)</string>
+ <string name="LSLTipText_llLoopSoundMaster">llLoopSoundMaster(string sound, float volume)\nplays attached sound looping at volume (0.0 - 1.0), declares it a sync master</string>
+ <string name="LSLTipText_llLoopSoundSlave">llLoopSoundSlave(string sound, float volume)\nplays attached sound looping at volume (0.0 - 1.0), synced to most audible sync master</string>
+ <string name="LSLTipText_llPlaySoundSlave">llPlaySoundSlave(string sound, float volume)\nplays attached sound once at volume (0.0 - 1.0), synced to next loop of most audible sync master</string>
+ <string name="LSLTipText_llTriggerSound">llTriggerSound(string sound, float volume)\nplays sound at volume (0.0 - 1.0), centered at but not attached to object</string>
+ <string name="LSLTipText_llStopSound">llStopSound()\nStops currently attached sound</string>
+ <string name="LSLTipText_llPreloadSound">llPreloadSound(string sound)\npreloads a sound on viewers within range</string>
+ <string name="LSLTipText_llGetSubString">string llGetSubString(string src, integer start, integer end)\nreturns the indicated substring</string>
+ <string name="LSLTipText_llDeleteSubString">string llDeleteSubString(string src, integer start, integer end)\nremoves the indicated substring and returns the result</string>
+ <string name="LSLTipText_llInsertString">string llInsertString(string dst, integer position, string src)\ninserts src into dst at position and returns the result</string>
+ <string name="LSLTipText_llToUpper">string llToUpper(string src)\nconvert src to all upper case and returns the result</string>
+ <string name="LSLTipText_llToLower">string llToLower(string src)\nconvert src to all lower case and returns the result</string>
+ <string name="LSLTipText_llGiveMoney">llGiveMoney(key destination, integer amount)\ntransfer amount of money from script owner to destination</string>
+ <string name="LSLTipText_llMakeExplosion">llMakeExplosion(integer particles, float scale, float vel, float lifetime, float arc, string texture, vector offset)\nMake a round explosion of particles</string>
+ <string name="LSLTipText_llMakeFountain">llMakeFountain(integer particles, float scale, float vel, float lifetime, float arc, integer bounce, string texture, vector offset, float bounce_offset)\nMake a fountain of particles</string>
+ <string name="LSLTipText_llMakeSmoke">llMakeSmoke(integer particles, float scale, float vel, float lifetime, float arc, string texture, vector offset)\nMake smoke like particles</string>
+ <string name="LSLTipText_llMakeFire">llMakeFire(integer particles, float scale, float vel, float lifetime, float arc, string texture, vector offset)\nMake fire like particles</string>
+ <string name="LSLTipText_llRezObject">llRezObject(string inventory, vector pos, vector vel, rotation rot, integer param)\nInstanciate owners inventory object at pos with velocity vel and rotation rot with start parameter param</string>
+ <string name="LSLTipText_llLookAt">llLookAt(vector target, F32 strength, F32 damping)\nCause object name to point it&apos;s forward axis towards target</string>
+ <string name="LSLTipText_llStopLookAt">llStopLookAt()\nStop causing object name to point at a target</string>
+ <string name="LSLTipText_llSetTimerEvent">llSetTimerEvent(float sec)\nCause the timer event to be triggered every sec seconds</string>
+ <string name="LSLTipText_llSleep">llSleep(float sec)\nPut script to sleep for sec seconds</string>
+ <string name="LSLTipText_llGetMass">float llGetMass()\nGet the mass of task name that script is attached to</string>
+ <string name="LSLTipText_llCollisionFilter">llCollisionFilter(string name, key id, integer accept)\nif accept == TRUE, only accept collisions with objects name and id (either is optional), otherwise with objects not name or id</string>
+ <string name="LSLTipText_llTakeControls">llTakeControls(integer controls, integer accept, integer pass_on)\nTake controls from agent task has permissions for. If (accept == (controls &amp; input)), send input to task. If pass_on send to agent also.</string>
+ <string name="LSLTipText_llReleaseControls">llReleaseControls()\nStop taking inputs</string>
+ <string name="LSLTipText_llAttachToAvatar">llAttachToAvatar(integer attachment)\nAttach to avatar task has permissions for at point attachment</string>
+ <string name="LSLTipText_llDetachFromAvatar">llDetachFromAvatar()\nDrop off of avatar</string>
+ <string name="LSLTipText_llTakeCamera">llTakeCamera(key avatar)\nMove avatar&apos;s viewpoint to task</string>
+ <string name="LSLTipText_llReleaseCamera">llReleaseCamera(key avatar)\nReturn camera to agent</string>
+ <string name="LSLTipText_llGetOwner">key llGetOwner()\nReturns the owner of the task</string>
+ <string name="LSLTipText_llInstantMessage">llInstantMessage(key user, string message)\nIMs message to the user</string>
+ <string name="LSLTipText_llEmail">llEmail(string address, string subject, string message)\nSends email to address with subject and message</string>
+ <string name="LSLTipText_llGetNextEmail">llGetNextEmail(string address, string subject)\nGet the next waiting email with appropriate address and/or subject (if blank they are ignored)</string>
+ <string name="LSLTipText_llGetKey">key llGetKey()\nGet the key for the task the script is attached to</string>
+ <string name="LSLTipText_llSetBuoyancy">llSetBuoyancy(float buoyancy)\nSet the tasks buoyancy (0 is none, &lt; 1.0 sinks, 1.0 floats, > 1.0 rises)</string>
+ <string name="LSLTipText_llSetHoverHeight">llSetHoverHeight(float height, integer water, float tau)\nCritically damps to a height (either above ground level or above the higher of land and water if water == TRUE)</string>
+ <string name="LSLTipText_llStopHover">llStopHover()\nStop hovering to a height</string>
+ <string name="LSLTipText_llMinEventDelay">llMinEventDelay(float delay)\nSet the minimum time between events being handled</string>
+ <string name="LSLTipText_llSoundPreload">llSoundPreload(string sound)\npreloads a sound on viewers within range</string>
+ <string name="LSLTipText_llRotLookAt">llRotLookAt(rotation target, F32 strength, F32 damping)\nCause object name to point it&apos;s forward axis towards target</string>
+ <string name="LSLTipText_llStringLength">integer llStringLength(string str)\nReturns the length of string</string>
+ <string name="LSLTipText_llStartAnimation">llStartAnimation(string anim)\nStart animation anim for agent that owns object</string>
+ <string name="LSLTipText_llStopAnimation">llStopAnimation(string anim)\nStop animation anim for agent that owns object</string>
+ <string name="LSLTipText_llPointAt">llPointAt(vector pos)\nMake agent that owns object point at pos</string>
+ <string name="LSLTipText_llStopPointAt">llStopPointAt()\nStop agent that owns object pointing</string>
+ <string name="LSLTipText_llTargetOmega">llTargetOmega(vector axis, float spinrate, float gain)\nAttempt to spin at spinrate with strength gain</string>
+ <string name="LSLTipText_llGetStartParameter">integer llGetStartParameter()\nGet's the start paramter passed to llRezObject</string>
+ <string name="LSLTipText_llGodLikeRezObject">llGodLikeRezObject(key inventory, vector pos)\nrez directly off of a UUID if owner has dog-bit set</string>
+ <string name="LSLTipText_llRequestPermissions">llRequestPermissions(key agent, integer perm)\nask agent to allow the script to do perm (NB: Debit, ownership, link, joint, and permission requests can only go to the task's owner)</string>
+ <string name="LSLTipText_llGetPermissionsKey">key llGetPermissionsKey()\nReturn agent that permissions are enabled for. NULL_KEY if not enabled</string>
+ <string name="LSLTipText_llGetPermissions">integer llGetPermissions()\nreturn what permissions have been enabled</string>
+ <string name="LSLTipText_llGetLinkNumber">integer llGetLinkNumber()\nReturns what number in a link set the script is attached to (0 means no link, 1 the root, 2 for first child, etc)</string>
+ <string name="LSLTipText_llSetLinkColor">llSetLinkColor(integer linknumber, vector color, integer face)\nIf a task exists in the link chain at linknumber, set face to color</string>
+ <string name="LSLTipText_llCreateLink">llCreateLink(key target, integer parent)\nAttempt to link task script is attached to and target (requires permission PERMISSION_CHANGE_LINKS be set). If parent == TRUE, task script is attached to is the root</string>
+ <string name="LSLTipText_llBreakLink">llBreakLink(integer linknum)\nDelinks the task with the given link number (requires permission PERMISSION_CHANGE_LINKS be set)</string>
+ <string name="LSLTipText_llBreakAllLinks">llBreakAllLinks()\nDelinks all tasks in the link set (requires permission PERMISSION_CHANGE_LINKS be set)</string>
+ <string name="LSLTipText_llGetLinkKey">key llGetLinkKey(integer linknum)\nGet the key of linknumber in link set</string>
+ <string name="LSLTipText_llGetLinkName">string llGetLinkName(integer linknum)\nGet the name of linknumber in link set</string>
+ <string name="LSLTipText_llGetInventoryNumber">integer llGetInventoryNumber(integer type)\nGet the number of items of a given type in the task's inventory.\nValid types: INVENTORY_TEXTURE, INVENTORY_SOUND, INVENTORY_OBJECT, INVENTORY_SCRIPT, INVENTORY_CLOTHING, INVENTORY_BODYPART, INVENTORY_NOTECARD, INVENTORY_LANDMARK, INVENTORY_ALL</string>
+ <string name="LSLTipText_llGetInventoryName">string llGetInventoryName(integer type, integer number)\nGet the name of the inventory item number of type</string>
+ <string name="LSLTipText_llSetScriptState">llSetScriptState(string name, integer run)\nControl the state of a script name.</string>
+ <string name="LSLTipText_llGetEnergy">float llGetEnergy()\nReturns how much energy is in the object as a percentage of maximum</string>
+ <string name="LSLTipText_llGiveInventory">llGiveInventory(key destination, string inventory)\nGive inventory to destination</string>
+ <string name="LSLTipText_llRemoveInventory">llRemoveInventory(string inventory)\nRemove the named inventory item</string>
+ <string name="LSLTipText_llSetText">llSetText(string text, vector color, float alpha)\nSet text floating over object</string>
+ <string name="LSLTipText_llWater">float llWater(vector v)\nreturns the water height below the object position + v</string>
+ <string name="LSLTipText_llPassTouches">llPassTouches(integer pass)\nif pass == TRUE, touches are passed from children on to parents (default is FALSE)</string>
+ <string name="LSLTipText_llRequestAgentData">key llRequestAgentData(key id, integer data)\nRequests data about agent id. When data is available the dataserver event will be raised</string>
+ <string name="LSLTipText_llRequestInventoryData">key llRequestInventoryData(string name)\nRequests data from object's inventory object. When data is available the dataserver event will be raised</string>
+ <string name="LSLTipText_llSetDamage">llSetDamage(float damage)\nSets the amount of damage that will be done to an object that this task hits. Task will be killed.</string>
+ <string name="LSLTipText_llTeleportAgentHome">llTeleportAgentHome(key id)\nTeleports agent on owner's land to agent's home location</string>
+ <string name="LSLTipText_llModifyLand">llModifyLand(integer action, integer size)\nModify land with action (LAND_LEVEL, LAND_RAISE, LAND_LOWER, LAND_SMOOTH, LAND_NOISE, LAND_REVERT)\non size (LAND_SMALL_BRUSH, LAND_MEDIUM_BRUSH, LAND_LARGE_BRUSH)</string>
+ <string name="LSLTipText_llCollisionSound">llCollisionSound(string impact_sound, float impact_volume)\nSuppress default collision sounds, replace default impact sounds with impact_sound (empty string to just suppress)</string>
+ <string name="LSLTipText_llCollisionSprite">llCollisionSprite(string impact_sprite)\nSuppress default collision sprites, replace default impact sprite with impact_sprite (empty string to just suppress)</string>
+ <string name="LSLTipText_llGetAnimation">string llGetAnimation(key id)\nGet the currently playing locomotion animation for avatar id</string>
+ <string name="LSLTipText_llResetScript">llResetScript()\nResets the script</string>
+ <string name="LSLTipText_llMessageLinked">llMessageLinked(integer linknum, integer num, string str, key id)\nSends num, str, and id to members of the link set (LINK_ROOT sends to root task in a linked set,\nLINK_SET sends to all tasks,\nLINK_ALL_OTHERS to all other tasks,\nLINK_ALL_CHILDREN to all children,\nLINK_THIS to the task the script it is in)</string>
+ <string name="LSLTipText_llPushObject">llPushObject(key id, vector impulse, vector ang_impulse, integer local)\nApplies impulse and ang_impulse to object id</string>
+ <string name="LSLTipText_llPassCollisions">llPassCollisions(integer pass)\nif pass == TRUE, collisions are passed from children on to parents (default is FALSE)</string>
+ <string name="LSLTipText_llGetScriptName">llGetScriptName()\nReturns the script name</string>
+ <string name="LSLTipText_llGetNumberOfSides">integer llGetNumberOfSides()\nReturns the number of sides</string>
+ <string name="LSLTipText_llAxisAngle2Rot">rotation llAxisAngle2Rot(vector axis, float angle)\nReturns the rotation generated angle about axis</string>
+ <string name="LSLTipText_llRot2Axis">vector llRot2Axis(rotation rot)\nReturns the rotation axis represented by rot</string>
+ <string name="LSLTipText_llRot2Angle">float llRot2Angle(rotation rot)\nReturns the rotation angle represented by rot</string>
+ <string name="LSLTipText_llAcos">float llAcos(float val)\nReturns the arccosine in radians of val</string>
+ <string name="LSLTipText_llAsin">float llAsin(float val)\nReturns the arcsine in radians of val</string>
+ <string name="LSLTipText_llAngleBetween">float llAngleBetween(rotation a, rotation b)\nReturns angle between rotation a and b</string>
+ <string name="LSLTipText_llGetInventoryKey">key llGetInventoryKey(string name)\nReturns the key of the inventory name</string>
+ <string name="LSLTipText_llAllowInventoryDrop">llAllowInventoryDrop(integer add)\nIf add == TRUE, users without permissions can still drop inventory items onto task</string>
+ <string name="LSLTipText_llGetSunDirection">vector llGetSunDirection()\nReturns the sun direction on the simulator</string>
+ <string name="LSLTipText_llGetTextureOffset">vector llGetTextureOffset(integer side)\nReturns the texture offset of side in the x and y components of a vector</string>
+ <string name="LSLTipText_llGetTextureScale">vector llGetTextureScale(integer side)\nReturns the texture scale of side in the x and y components of a vector</string>
+ <string name="LSLTipText_llGetTextureRot">float llGetTextureRot(integer side)\nReturns the texture rotation of side</string>
+ <string name="LSLTipText_llSubStringIndex">integer llSubStringIndex(string source, string pattern)\nFinds index in source where pattern first appears (returns -1 if not found)</string>
+ <string name="LSLTipText_llGetOwnerKey">key llGetOwnerKey(key id)\nFind the owner of id</string>
+ <string name="LSLTipText_llGetCenterOfMass">vector llGetCenterOfMass()\nGet the object's center of mass</string>
+ <string name="LSLTipText_llListSort">list llListSort(list src, integer stride, integer ascending)\nSort the list into blocks of stride in ascending order if ascending == TRUE. Note that sort only works between same types.</string>
+ <string name="LSLTipText_llGetListLength">integer llGetListLength(list src)\nGet the number of elements in the list</string>
+ <string name="LSLTipText_llList2Integer">integer llList2Integer(list src, integer index)\nCopy the integer at index in the list</string>
+ <string name="LSLTipText_llList2Float">float llList2Float(list src, integer index)\nCopy the float at index in the list</string>
+ <string name="LSLTipText_llList2String">string llList2String(list src, integer index)\nCopy the string at index in the list</string>
+ <string name="LSLTipText_llList2Key">key llList2Key(list src, integer index)\nCopy the key at index in the list</string>
+ <string name="LSLTipText_llList2Vector">vector llList2Vector(list src, integer index)\nCopy the vector at index in the list</string>
+ <string name="LSLTipText_llList2Rot">rotation llList2Rot(list src, integer index)\nCopy the rotation at index in the list</string>
+ <string name="LSLTipText_llList2List">list llList2List(list src, integer start, integer end)\nCopy the slice of the list from start to end</string>
+ <string name="LSLTipText_llDeleteSubList">list llDeleteSubList(list src, integer start, integer end)\nRemove the slice from the list and return the remainder</string>
+ <string name="LSLTipText_llGetListEntryType">integer llGetListEntryType(list src, integer index)\nReturns the type of the index entry in the list\n(TYPE_INTEGER, TYPE_FLOAT, TYPE_STRING, TYPE_KEY, TYPE_VECTOR, TYPE_ROTATION, or TYPE_INVALID if index is off list)</string>
+ <string name="LSLTipText_llList2CSV">string llList2CSV(list src)\nCreate a string of comma separated values from list</string>
+ <string name="LSLTipText_llCSV2List">list llCSV2List(string src)\nCreate a list from a string of comma separated values</string>
+ <string name="LSLTipText_llListRandomize">list llListRandomize(list src, integer stride)\nReturns a randomized list of blocks of size stride</string>
+ <string name="LSLTipText_llList2ListStrided">list llList2ListStrided(list src, integer start, integer end, integer stride)\nCopy the strided slice of the list from start to end</string>
+ <string name="LSLTipText_llGetRegionCorner">vector llGetRegionCorner()\nReturns a vector with the south west corner x,y position of the region the object is in</string>
+ <string name="LSLTipText_llListInsertList">list llListInsertList(list dest, list src, integer start)\nInserts src into dest at position start</string>
+ <string name="LSLTipText_llListFindList">integer llListFindList(list src, list test)\nReturns the start of the first instance of test in src, -1 if not found</string>
+ <string name="LSLTipText_llGetObjectName">string llGetObjectName()\nReturns the name of the object script is attached to</string>
+ <string name="LSLTipText_llSetObjectName">llSetObjectName(string name)\nSets the objects name</string>
+ <string name="LSLTipText_llGetDate">string llGetDate()\nGets the date as YYYY-MM-DD</string>
+ <string name="LSLTipText_llEdgeOfWorld">integer llEdgeOfWorld(vector pos, vector dir)\nChecks to see whether the border hit by dir from pos is the edge of the world (has no neighboring simulator)</string>
+ <string name="LSLTipText_llGetAgentInfo">integer llGetAgentInfo(key id)\nGets information about agent ID.\nReturns AGENT_FLYING, AGENT_ATTACHMENTS, AGENT_SCRIPTED, AGENT_SITTING, AGENT_ON_OBJECT, AGENT_MOUSELOOK, AGENT_AWAY, AGENT_BUSY, AGENT_TYPING, AGENT_CROUCHING, AGENT_ALWAYS_RUN, AGENT_WALKING and/or AGENT_IN_AIR.</string>
+ <string name="LSLTipText_llAdjustSoundVolume">llAdjustSoundVolume(float volume)\nadjusts volume of attached sound (0.0 - 1.0)</string>
+ <string name="LSLTipText_llSetSoundQueueing">llSetSoundQueueing(integer queue)\ndetermines whether attached sound calls wait for the current sound to finish (0 = no [default], nonzero = yes)</string>
+ <string name="LSLTipText_llSetSoundRadius">llSetSoundRadius(float radius)\nestablishes a hard cut-off radius for audibility of scripted sounds (both attached and triggered)</string>
+ <string name="LSLTipText_llKey2Name">string llKey2Name(key id)\nReturns the name of the object key, iff the object is in the current simulator, otherwise the empty string</string>
+ <string name="LSLTipText_llSetTextureAnim">llSetTextureAnim(integer mode, integer face, integer sizex, integer sizey, float start, float length, float rate)\nAnimate the texture on the specified face/faces</string>
+ <string name="LSLTipText_llTriggerSoundLimited">llTriggerSoundLimited(string sound, float volume, vector tne, vector bsw)\nplays sound at volume (0.0 - 1.0), centered at but not attached to object, limited to AABB defined by vectors top-north-east and bottom-south-west</string>
+ <string name="LSLTipText_llEjectFromLand">llEjectFromLand(key pest)\nEjects pest from land that you own</string>
+ <string name="LSLTipText_llParseString2List">list llParseString2List(string src, list separators, list spacers)\nBreaks src into a list, discarding separators, keeping spacers (separators and spacers must be lists of strings, maximum of 8 each)</string>
+ <string name="LSLTipText_llOverMyLand">integer llOverMyLand(key id)\nReturns TRUE if id is over land owner of object owns, FALSE otherwise</string>
+ <string name="LSLTipText_llGetLandOwnerAt">key llGetLandOwnerAt(vector pos)\nReturns the key of the land owner, NULL_KEY if public</string>
+ <string name="LSLTipText_llGetNotecardLine">key llGetNotecardLine(string name, integer line)\nReturns line line of notecard name via the dataserver event</string>
+ <string name="LSLTipText_llGetAgentSize">vector llGetAgentSize(key id)\nIf the agent is in the same sim as the object, returns the size of the avatar</string>
+ <string name="LSLTipText_llSameGroup">integer llSameGroup(key id)\nReturns TRUE if ID is in the same sim and has the same active group, otherwise FALSE</string>
+ <string name="LSLTipText_llUnSit">key llUnSit(key id)\nIf agent identified by id is sitting on the object the script is attached to or is over land owned by the objects owner, the agent is forced to stand up</string>
+ <string name="LSLTipText_llGroundSlope">vector llGroundSlope(vector v)\nreturns the ground slope below the object position + v</string>
+ <string name="LSLTipText_llGroundNormal">vector llGroundNormal(vector v)\nreturns the ground normal below the object position + v</string>
+ <string name="LSLTipText_llGroundContour">vector llGroundCountour(vector v)\nreturns the ground contour below the object position + v</string>
+ <string name="LSLTipText_llGetAttached">integer llGetAttached()\nreturns the object attachment point or 0 if not attached</string>
+ <string name="LSLTipText_llGetFreeMemory">integer llGetFreeMemory()\nreturns the available heap space for the current script</string>
+ <string name="LSLTipText_llGetRegionName">string llGetRegionName()\nreturns the current region name</string>
+ <string name="LSLTipText_llGetRegionTimeDilation">float llGetRegionTimeDilation()\nreturns the current time dilation as a float between 0 and 1</string>
+ <string name="LSLTipText_llGetRegionFPS">float llGetRegionFPS()\nreturns the mean region frames per second</string>
+ <string name="LSLTipText_llParticleSystem">llParticleSystem(list rules)\nCreates a particle system based on rules. Empty list removes particle system from object.\nList format is [ rule1, data1, rule2, data2 . . . rulen, datan ]</string>
+ <string name="LSLTipText_llGroundRepel">llGroundRepel(float height, integer water, float tau)\nCritically damps to height if within height*0.5 of level (either above ground level or above the higher of land and water if water == TRUE)</string>
+ <string name="LSLTipText_llGiveInventoryList">llGiveInventoryList(key destination, string category, list inventory)\nGive inventory to destination in a new category</string>
+ <string name="LSLTipText_llSetVehicleType">llSetVehicleType(integer type)\nsets vehicle to one of the default types</string>
+ <string name="LSLTipText_llSetVehicleFloatParam">llSetVehicleFloatParam(integer param, float value)\nsets the specified vehicle float parameter</string>
+ <string name="LSLTipText_llSetVehicleVectorParam">llSetVehicleVectorParam(integer param, vector vec)\nsets the specified vehicle vector parameter</string>
+ <string name="LSLTipText_llSetVehicleRotationParam">llSetVehicleVectorParam(integer param, rotation rot)\nsets the specified vehicle rotation parameter</string>
+ <string name="LSLTipText_llSetVehicleFlags">llSetVehicleFlags(integer flags)\nsets the enabled bits in 'flags'</string>
+ <string name="LSLTipText_llRemoveVehicleFlags">llRemoveVehicleFlags(integer flags)\nremoves the enabled bits in 'flags'</string>
+ <string name="LSLTipText_llSitTarget">llSitTarget(vector offset, rotation rot)\nSet the sit location for this object (if offset == &lt;0,0,0&gt; clear it)</string>
+ <string name="LSLTipText_llAvatarOnSitTarget">key llAvatarOnSitTarget()\nIf an avatar is sitting on the sit target, return the avatar's key, NULL_KEY otherwise</string>
+ <string name="LSLTipText_llAddToLandPassList">llAddToLandPassList(key avatar, float hours)\nAdd avatar to the land pass list for hours</string>
+ <string name="LSLTipText_llSetTouchText">llSetTouchText(string text)\nDisplays text in pie menu that acts as a touch</string>
+ <string name="LSLTipText_llSetSitText">llSetSitText(string text)\nDisplays text rather than sit in pie menu</string>
+ <string name="LSLTipText_llSetCameraEyeOffset">llSetCameraEyeOffset(vector offset)\nSets the camera eye offset used in this object if an avatar sits on it</string>
+ <string name="LSLTipText_llSetCameraAtOffset">llSetCameraAtOffset(vector offset)\nSets the camera at offset used in this object if an avatar sits on it</string>
+ <string name="LSLTipText_llDumpList2String">string llDumpList2String(list src, string separator)\nWrite the list out in a single string using separator between values</string>
+ <string name="LSLTipText_llScriptDanger">integer llScriptDanger(vector pos)\nReturns true if pos is over public land, sandbox land, land that doesn't allow everyone to edit and build, or land that doesn't allow outside scripts</string>
+ <string name="LSLTipText_llDialog">llDialog(key avatar, string message, list buttons, integer chat_channel\nShows a dialog box on the avatar's screen with the message.\nUp to 12 strings in the list form buttons.\nIf a button is clicked, the name is chatted on chat_channel.</string>
+ <string name="LSLTipText_llVolumeDetect">llVolumeDetect(integer detect)\nIf detect = TRUE, object becomes phantom but triggers collision_start and collision_end events\nwhen other objects start and stop interpenetrating.\nMust be applied to the root object.</string>
+ <string name="LSLTipText_llResetOtherScript">llResetOtherScript(string name)\nResets script name</string>
+ <string name="LSLTipText_llGetScriptState">integer llGetScriptState(string name)\nResets TRUE if script name is running</string>
+ <string name="LSLTipText_llRemoteLoadScript">Deprecated. Please use llRemoteLoadScriptPin instead.</string>
+ <string name="LSLTipText_llSetRemoteScriptAccessPin">llSetRemoteScriptAccessPin(integer pin)\nIf pin is set to a non-zero number, the task will accept remote script\nloads via llRemoteLoadScriptPin if it passes in the correct pin.\nOthersise, llRemoteLoadScriptPin is ignored.</string>
+ <string name="LSLTipText_llRemoteLoadScriptPin">llRemoteLoadScriptPin(key target, string name, integer pin, integer running, integer start_param)\nIf the owner of the object this script is attached can modify target,\nthey are in the same region,\nand the matching pin is used,\ncopy script name onto target,\nif running == TRUE, start the script with param.</string>
+ <string name="LSLTipText_llOpenRemoteDataChannel">llOpenRemoteDataChannel()\nCreates a channel to listen for XML-RPC calls. Will trigger a remote_data event with channel id once it is available.</string>
+ <string name="LSLTipText_llSendRemoteData">key llSendRemoteData(key channel, string dest, integer idata, string sdata)\nSend an XML-RPC request to dest through channel with payload of channel (in a string), integer idata and string sdata.\nA message identifier key is returned.\nAn XML-RPC reply will trigger a remote_data event and reference the message id.\nThe message_id is returned.</string>
+ <string name="LSLTipText_llRemoteDataReply">llRemoteDataReply(key channel, key message_id, string sdata, integer idata)\nSend an XML-RPC reply to message_id on channel with payload of string sdata and integer idata</string>
+ <string name="LSLTipText_llCloseRemoteDataChannel">llCloseRemoteDataChannel(key channel)\nCloses XML-RPC channel.</string>
+ <string name="LSLTipText_llMD5String">string llMD5String(string src, integer nonce)\nPerforms a RSA Data Security, Inc. MD5 Message-Digest Algorithm on string with nonce. Returns a 32 character hex string.</string>
+ <string name="LSLTipText_llSetPrimitiveParams">llSetPrimitiveParams(list rules)\nSet primitive parameters based on rules.</string>
+ <string name="LSLTipText_llStringToBase64">string llStringToBase64(string str)\nConverts a string to the Base 64 representation of the string.</string>
+ <string name="LSLTipText_llBase64ToString">string llBase64ToString(string str)\nConverts a Base 64 string to a conventional string. If the conversion creates any unprintable characters, they are converted to spaces.</string>
+ <string name="LSLTipText_llXorBase64Strings">string llXorBase64Strings(string s1, string s2)\nDEPRECATED! Please use llXorBase64StringsCorrect instead!! Incorrectly performs an exclusive or on two Base 64 strings and returns a Base 64 string. s2 repeats if it is shorter than s1. Retained for backwards compatability.</string>
+ <string name="LSLTipText_llRemoteDataSetRegion">llRemoteDataSetRegion()\nIf an object using remote data channels changes regions, you must call this function to reregister the remote data channels.\nYou do not need to make this call if you don't change regions.</string>
+ <string name="LSLTipText_llLog10">float llLog10(float val)\nReturns the base 10 log of val if val &gt; 0, otherwise returns 0.</string>
+ <string name="LSLTipText_llLog">float llLog(float val)\nReturns the base e log of val if val &gt; 0, otherwise returns 0.</string>
+ <string name="LSLTipText_llGetAnimationList">list llGetAnimationList(key id)\nGets a list of all playing animations for avatar id</string>
+ <string name="LSLTipText_llSetParcelMusicURL">llSetParcelMusicURL(string url)\nSets the streaming audio URL for the parcel object is on</string>
+ <string name="LSLTipText_llGetRootPosition">vector llGetRootPosition()\nGets the global position of the root object of the object script is attached to</string>
+ <string name="LSLTipText_llGetRootRotation">rotation llGetRootRotation()\nGets the global rotation of the root object of the object script is attached to</string>
+ <string name="LSLTipText_llGetObjectDesc">string llGetObjectDesc()\nReturns the description of the object the script is attached to</string>
+ <string name="LSLTipText_llSetObjectDesc">llSetObjectDesc(string name)\nSets the object's description</string>
+ <string name="LSLTipText_llGetCreator">key llGetCreator()\nReturns the creator of the object</string>
+ <string name="LSLTipText_llGetTimestamp">string llGetTimestamp()\nGets the timestamp in the format: YYYY-MM-DDThh:mm:ss.ff..fZ</string>
+ <string name="LSLTipText_llSetLinkAlpha">llSetLinkAlpha(integer linknumber, float alpha, integer face)\nIf a prim exists in the link chain at linknumber, set face to alpha</string>
+ <string name="LSLTipText_llGetNumberOfPrims">integer llGetNumberOfPrims()\nReturns the number of prims in a link set the script is attached to</string>
+ <string name="LSLTipText_llGetNumberOfNotecardLines">key llGetNumberOfNotecardLines(string name)\nReturns number of lines in notecard 'name' via the dataserver event (cast return value to integer)</string>
+ <string name="LSLTipText_llGetBoundingBox">list llGetBoundingBox(key object)\nReturns the bounding box around an object (including any linked prims) relative to the root prim, in a list: [ (vector) min_corner, (vector) max_corner ]</string>
+ <string name="LSLTipText_llGetGeometricCenter">vector llGetGeometricCenter()\nReturns the geometric center of the linked set the script is attached to.</string>
+ <string name="LSLTipText_llGetPrimitiveParams">list llGetPrimitiveParams(list params)\nGets primitive parameters specified in the params list.</string>
+ <string name="LSLTipText_llIntegerToBase64">string llIntegerToBase64(integer number)\nBig endian encode of of integer as a Base64 string.</string>
+ <string name="LSLTipText_llBase64ToInteger">integer llBase64ToInteger(string str)\nBig endian decode of a Base64 string into an integer.</string>
+ <string name="LSLTipText_llGetGMTclock">float llGetGMTclock()\nGets the time in seconds since midnight in GMT</string>
+ <string name="LSLTipText_llGetSimulatorHostname">string llGetSimulatorHostname()\nGets the hostname of the machine script is running on (same as string in viewer Help dialog)</string>
+ <string name="LSLTipText_llSetLocalRot">llSetLocalRot(rotation rot)\nsets the rotation of a child prim relative to the root prim</string>
+ <string name="LSLTipText_llParseStringKeepNulls">list llParseStringKeepNulls(string src, list separators, list spacers)\nBreaks src into a list, discarding separators, keeping spacers (separators and spacers must be lists of strings, maximum of 8 each), keeping any null values generated.</string>
+ <string name="LSLTipText_llRezAtRoot">llRezAtRoot(string inventory, vector pos, vector vel, rotation rot, integer param)\nInstantiate owner's inventory object at pos with velocity vel and rotation rot with start parameter param.\nThe last selected root object's location will be set to pos</string>
+ <string name="LSLTipText_llGetObjectPermMask">integer llGetObjectPermMask(integer mask)\nReturns the requested permission mask for the root object the task is attached to.</string>
+ <string name="LSLTipText_llSetObjectPermMask">llSetObjectPermMask(integer mask, integer value)\nSets the given permission mask to the new value on the root object the task is attached to.</string>
+ <string name="LSLTipText_llGetInventoryPermMask">integer llGetInventoryPermMask(string item, integer mask)\nReturns the requested permission mask for the inventory item.</string>
+ <string name="LSLTipText_llSetInventoryPermMask">llSetInventoryPermMask(string item, integer mask, integer value)\nSets the given permission mask to the new value on the inventory item.</string>
+ <string name="LSLTipText_llGetInventoryCreator">key llGetInventoryCreator(string item)\nReturns the key for the creator of the inventory item.</string>
+ <string name="LSLTipText_llOwnerSay">llOwnerSay(string msg)\nsays msg to owner only (if owner in sim)</string>
+ <string name="LSLTipText_llRequestSimulatorData">key llRequestSimulatorData(string simulator, integer data)\nRequests data about simulator. When data is available the dataserver event will be raised</string>
+ <string name="LSLTipText_llForceMouselook">llForceMouselook(integer mouselook)\nIf mouselook is TRUE any avatar that sits on this object is forced into mouselook mode</string>
+ <string name="LSLTipText_llGetObjectMass">float llGetObjectMass(key id)\nGet the mass of the object with key id</string>
+ <string name="LSLTipText_llListReplaceList">list llListReplaceList(list dest, list src, integer start, integer end)\nReplaces start through end of dest with src.</string>
+ <string name="LSLTipText_llLoadURL">llLoadURL(key avatar_id, string message, string url)\nShows dialog to avatar avatar_id offering to load web page at URL. If user clicks yes, launches their web browser.</string>
+ <string name="LSLTipText_llParcelMediaCommandList">llParcelMediaCommandList(list command)\nSends a list of commands, some with arguments, to a parcel.</string>
+ <string name="LSLTipText_llParcelMediaQuery">list llParcelMediaQuery(list query)\nSends a list of queries, returns a list of results.</string>
+ <string name="LSLTipText_llModPow">integer llModPow(integer a, integer b, integer c)\nReturns a raised to the b power, mod c. ( (a**b)%c ). b is capped at 0xFFFF (16 bits).</string>
+ <string name="LSLTipText_llGetInventoryType">integer llGetInventoryType(string name)\nReturns the type of the inventory name</string>
+ <string name="LSLTipText_llSetPayPrice">llSetPayPrice(integer price, list quick_pay_buttons)\nSets the default amount when someone chooses to pay this object.</string>
+ <string name="LSLTipText_llGetCameraPos">vector llGetCameraPos()\nGets current camera position for agent task has permissions for.</string>
+ <string name="LSLTipText_llGetCameraRot">rotation llGetCameraRot()\nGets current camera orientation for agent task has permissions for.</string>
+ <string name="LSLTipText_llSetPrimURL">llSetPrimURL(string url)\nUpdates the URL for the web page shown on the sides of the object.</string>
+ <string name="LSLTipText_llRefreshPrimURL">llRefreshPrimURL()\nReloads the web page shown on the sides of the object.</string>
+ <string name="LSLTipText_llEscapeURL">string llEscapeURL(string url)\nReturns and escaped/encoded version of url, replacing spaces with %20 etc.</string>
+ <string name="LSLTipText_llUnescapeURL">string llUnescapeURL(string url)\nReturns and unescaped/unencoded version of url, replacing %20 with spaces etc.</string>
+ <string name="LSLTipText_llMapDestination">llMapDestination(string simname, vector pos, vector look_at)\nOpens world map centered on region with pos highlighted.\nOnly works for scripts attached to avatar, or during touch events.\n(NOTE: look_at currently does nothing)</string>
+ <string name="LSLTipText_llAddToLandBanList">llAddToLandBanList(key avatar, float hours)\nAdd avatar to the land ban list for hours</string>
+ <string name="LSLTipText_llRemoveFromLandPassList">llRemoveFromLandPassList(key avatar)\nRemove avatar from the land pass list</string>
+ <string name="LSLTipText_llRemoveFromLandBanList">llRemoveFromLandBanList(key avatar)\nRemove avatar from the land ban list</string>
+ <string name="LSLTipText_llSetCameraParams">llSetCameraParams(list rules)\nSets multiple camera parameters at once.\nList format is [ rule1, data1, rule2, data2 . . . rulen, datan ]</string>
+ <string name="LSLTipText_llClearCameraParams">llClearCameraParams()\nResets all camera parameters to default values and turns off scripted camera control.</string>
+ <string name="LSLTipText_llListStatistics">float llListStatistics(integer operation, list l)\nPerform statistical aggregate functions on list l using LIST_STAT_* operations.</string>
+ <string name="LSLTipText_llGetUnixTime">integer llGetUnixTime()\nGet the number of seconds elapsed since 00:00 hours, Jan 1, 1970 UTC from the system clock.</string>
+ <string name="LSLTipText_llGetParcelFlags">integer llGetParcelFlags(vector pos)\nGet the parcel flags (PARCEL_FLAG_*) for the parcel including the point pos.</string>
+ <string name="LSLTipText_llGetRegionFlags">integer llGetRegionFlags()\nGet the region flags (REGION_FLAG_*) for the region the object is in.</string>
+ <string name="LSLTipText_llXorBase64StringsCorrect">string llXorBase64StringsCorrect(string s1, string s2)\nCorrectly performs an exclusive or on two Base 64 strings and returns a Base 64 string. s2 repeats if it is shorter than s1.</string>
+ <string name="LSLTipText_llHTTPRequest">llHTTPRequest(string url, list parameters, string body)\nSend an HTTP request.</string>
+ <string name="LSLTipText_llResetLandBanList">llResetLandBanList()\nRemoves all residents from the land ban list.</string>
+ <string name="LSLTipText_llResetLandPassList">llResetLandPassList()\nRemoves all residents from the land access/pass list.</string>
+ <string name="LSLTipText_llGetObjectPrimCount">integer llGetObjectPrimCount(key object_id)\nReturns the total number of prims for an object.</string>
+ <string name="LSLTipText_llGetParcelPrimOwners">list llGetParcelPrimOwners(vector pos)\nReturns a list of all residents who own objects on the parcel and the number of objects they own.\nRequires owner-like permissions for the parcel.</string>
+ <string name="LSLTipText_llGetParcelPrimCount">integer llGetParcelPrimCount(vector pos, integer category, integer sim_wide)\nGets the number of prims on the parcel of the given category.\nCategories: PARCEL_COUNT_TOTAL, _OWNER, _GROUP, _OTHER, _SELECTED, _TEMP.</string>
+ <string name="LSLTipText_llGetParcelMaxPrims">integer llGetParcelMaxPrims(vector pos, integer sim_wide)\nGets the maximum number of prims allowed on the parcel at pos.</string>
+ <string name="LSLTipText_llGetParcelDetails">list llGetParcelDetails(vector pos, list params)\nGets the parcel details specified in params for the parcel at pos.\nParams is one or more of: PARCEL_DETAILS_NAME, _DESC, _OWNER, _GROUP, _AREA</string>
+ <string name="LSLTipText_llSetLinkPrimitiveParams">llSetLinkPrimitiveParams(integer linknumber, list rules)\nSet primitive parameters for linknumber based on rules.</string>
+ <string name="LSLTipText_llSetLinkTexture">llSetLinkTexture(integer link_pos, string texture, integer face)\nSets the texture of face for link_pos</string>
+ <string name="LSLTipText_llStringTrim">string llStringTrim(string src, integer trim_type)\nTrim leading and/or trailing spaces from a string.\nUses trim_type of STRING_TRIM, STRING_TRIM_HEAD or STRING_TRIM_TAIL.</string>
+ <string name="LSLTipText_llRegionSay">llRegionSay(integer channel, string msg)\nbroadcasts msg to entire region on channel (not 0.)</string>
+ <string name="LSLTipText_llGetObjectDetails">list llGetObjectDetails(key id, list params)\nGets the object details specified in params for the object with key id.\nDetails are OBJECT_NAME, _DESC, _POS, _ROT, _VELOCITY, _OWNER, _GROUP, _CREATOR.</string>
+ <string name="LSLTipText_llSetClickAction">llSetClickAction(integer action)\nSets the action performed when a prim is clicked upon.</string>
+ <string name="LSLTipText_llGetRegionAgentCount">int llGetRegionAgentCount()\nreturns the number of agents in a region</string>
+ <string name="LSLTipText_llTextBox">llTextBox(key avatar, string message, integer chat_channel\nShows a dialog box on the avatar's screen with the message.\nA text box asks for input, and if entered the text is chatted on chat_channel.</string>
+ <string name="LSLTipText_llGetAgentLanguage">string llGetAgentLanguage(key id)\nGets the agents preferred language..</string>
+ <string name="LSLTipText_llDetectedTouchUV">vector llDetectedTouchUV(integer number)\nreturns the u and v coordinates in the first two components of a vector, for a triggered touch event</string>
+ <string name="LSLTipText_llDetectedTouchFace">integer llDetectedTouchFace(integer number)\nreturns the index of the face on the object for a triggered touch event</string>
+ <string name="LSLTipText_llDetectedTouchPos">vector llDetectedTouchPos(integer number)\nreturns the position touched for a triggered touch event</string>
+ <string name="LSLTipText_llDetectedTouchNormal">vector llDetectedTouchNormal(integer number)\nreturns the surface normal for a triggered touch event</string>
+ <string name="LSLTipText_llDetectedTouchBinormal">vector llDetectedTouchBinormal(integer number)\nreturns the surface binormal for a triggered touch event</string>
+ <string name="LSLTipText_llDetectedTouchST">vector llDetectedTouchST(integer number)\nreturns the s and t coordinates in the first two components of a vector, for a triggered touch event</string>
+ <string name="LSLTipText_llSHA1String">string llSHA1String(string sr)\nPerforms a SHA1 security Hash. Returns a 40 character hex string.</string>
+ <string name="LSLTipText_llGetFreeURLs">integer llGetFreeURLs()\nreturns the available urls for the current script</string>
+ <string name="LSLTipText_llRequestURL">key llRequestURL()\nRequests one HTTP:// url for use by this object\nTriggers an http_server event with results.</string>
+ <string name="LSLTipText_llRequestSecureURL">key llRequestSecureURL()\nRequests one HTTPS:// (SSL) url for use by this object\nTriggers an http_server event with results.</string>
+ <string name="LSLTipText_llReleaseURL">llReleaseURL(string url)\nReleases the specified URL, it will no longer be usable.</string>
+ <string name="LSLTipText_llHTTPResponse">llHTTPResponse(key id, integer status, string body)\nResponds to request id with status and body.</string>
+ <string name="LSLTipText_llGetHTTPHeader">string llGetHTTPHeader(key id, string header)\nGet the value for header for request id.</string>
+
+ <!-- Avatar busy/away mode -->
+ <string name="AvatarSetNotAway">Set Not Away</string>
+ <string name="AvatarSetAway">Set Away</string>
+ <string name="AvatarSetNotBusy">Set Not Busy</string>
+ <string name="AvatarSetBusy">Set Busy</string>
+
+ <!-- Wearable Types -->
+ <string name="shape">Shape</string>
+ <string name="skin">Skin</string>
+ <string name="hair">Hair</string>
+ <string name="eyes">Eyes</string>
+ <string name="shirt">Shirt</string>
+ <string name="pants">Pants</string>
+ <string name="shoes">Shoes</string>
+ <string name="socks">Socks</string>
+ <string name="jacket">Jacket</string>
+ <string name="gloves">Gloves</string>
+ <string name="undershirt">Undershirt</string>
+ <string name="underpants">Underpants</string>
+ <string name="skirt">Skirt</string>
+ <string name="alpha">Alpha</string>
+ <string name="tattoo">Tattoo</string>
+ <string name="invalid">invalid</string>
+
+ <!-- notify -->
+ <string name="next">Next</string>
+ <string name="ok">OK</string>
+ <string name="GroupNotifyGroupNotice">Group Notice</string>
+ <string name="GroupNotifyGroupNotices">Group Notices</string>
+ <string name="GroupNotifySentBy">Sent by</string>
+ <string name="GroupNotifyAttached">Attached:</string>
+ <string name="GroupNotifyViewPastNotices">View past notices or opt-out of receiving these messages here.</string>
+ <string name="GroupNotifyOpenAttachment">Open Attachment</string>
+ <string name="GroupNotifySaveAttachment">Save Attachment</string>
+ <string name="TeleportOffer">Teleport offering</string>
+ <!-- start-up toast's string-->
+ <string name="StartUpNotification">%d new notification arrived while you were away...</string>
+ <string name="StartUpNotifications">%d new notifications arrived while you were away...</string>
+ <!-- overflow toast's string-->
+ <string name="OverflowInfoChannelString">You have %d more notification</string>
+
+
+ <!-- body parts -->
+ <string name="BodyPartsRightArm">Right Arm</string>
+ <string name="BodyPartsHead">Head</string>
+ <string name="BodyPartsLeftArm">Left Arm</string>
+ <string name="BodyPartsLeftLeg">Left Leg</string>
+ <string name="BodyPartsTorso">Torso</string>
+ <string name="BodyPartsRightLeg">Right Leg</string>
+
+ <!-- slider -->
+ <string name="GraphicsQualityLow">Low</string>
+ <string name="GraphicsQualityMid">Mid</string>
+ <string name="GraphicsQualityHigh">High</string>
+
+ <!-- mouselook -->
+ <string name="LeaveMouselook">Press ESC to return to World View</string>
+
+ <!-- inventory -->
+ <string name="InventoryNoMatchingItems">No matching items found in inventory.</string>
+ <string name="InventoryNoTexture">
+ You do not have a copy of
+this texture in your inventory
+ </string>
+ <!-- use value="" because they have preceding spaces -->
+ <string name="no_transfer" value=" (no transfer)" />
+ <string name="no_modify" value=" (no modify)" />
+ <string name="no_copy" value=" (no copy)" />
+ <string name="worn" value=" (worn)" />
+ <string name="link" value=" (link)" />
+ <string name="broken_link" value=" (broken_link)" />
+ <string name="LoadingContents">Loading contents...</string>
+ <string name="NoContents">No contents</string>
+
+ <!-- Gestures labels -->
+ <!-- use value="" because they have preceding spaces -->
+ <string name="Chat" value=" Chat : " />
+ <string name="Sound" value=" Sound : " />
+ <string name="Wait" value=" --- Wait : " />
+ <string name="AnimFlagStop" value=" Stop Animation : " />
+ <string name="AnimFlagStart" value=" Start Animation : " />
+ <string name="Wave" value=" Wave " />
+ <string name="HelloAvatar" value=" Hello, avatar! " />
+
+ <!-- inventory filter -->
+ <!-- use value="" because they have preceding spaces -->
+ <string name="Animations" value=" Animations," />
+ <string name="Calling Cards" value=" Calling Cards," />
+ <string name="Clothing" value=" Clothing," />
+ <string name="Gestures" value=" Gestures," />
+ <string name="Landmarks" value=" Landmarks," />
+ <string name="Notecards" value=" Notecards," />
+ <string name="Objects" value=" Objects," />
+ <string name="Scripts" value=" Scripts," />
+ <string name="Sounds" value=" Sounds," />
+ <string name="Textures" value=" Textures," />
+ <string name="Snapshots" value=" Snapshots," />
+ <string name="No Filters" value="No " />
+ <string name="Since Logoff" value=" - Since Logoff" />
+
+ <!-- inventory folder -->
+ <string name="InvFolder My Inventory">My Inventory</string>
+ <string name="InvFolder My Favorites">My Favorites</string>
+ <string name="InvFolder Library">Library</string>
+ <string name="InvFolder Textures">Textures</string>
+ <string name="InvFolder Sounds">Sounds</string>
+ <string name="InvFolder Calling Cards">Calling Cards</string>
+ <string name="InvFolder Landmarks">Landmarks</string>
+ <string name="InvFolder Scripts">Scripts</string>
+ <string name="InvFolder Clothing">Clothing</string>
+ <string name="InvFolder Objects">Objects</string>
+ <string name="InvFolder Notecards">Notecards</string>
+ <string name="InvFolder New Folder">New Folder</string>
+ <string name="InvFolder Inventory">Inventory</string>
+ <string name="InvFolder Uncompressed Images">Uncompressed Images</string>
+ <string name="InvFolder Body Parts">Body Parts</string>
+ <string name="InvFolder Trash">Trash</string>
+ <string name="InvFolder Photo Album">Photo Album</string>
+ <string name="InvFolder Lost And Found">Lost And Found</string>
+ <string name="InvFolder Uncompressed Sounds">Uncompressed Sounds</string>
+ <string name="InvFolder Animations">Animations</string>
+ <string name="InvFolder Gestures">Gestures</string>
+ <string name="InvFolder favorite">Favorites</string>
+ <string name="InvFolder Current Outfit">Current Outfit</string>
+ <string name="InvFolder My Outfits">My Outfits</string>
+
+ <!-- are used for Friends and Friends/All folders in Inventory "Calling cards" folder. See EXT-694-->
+ <string name="InvFolder Friends">Friends</string>
+ <string name="InvFolder All">All</string>
+
+ <!-- inventory FVBridge -->
+ <string name="Buy">Buy</string>
+ <string name="BuyforL$">Buy for L$</string>
+
+ <string name="Stone">Stone</string>
+ <string name="Metal">Metal</string>
+ <string name="Glass">Glass</string>
+ <string name="Wood">Wood</string>
+ <string name="Flesh">Flesh</string>
+ <string name="Plastic">Plastic</string>
+ <string name="Rubber">Rubber</string>
+ <string name="Light">Light</string>
+
+ <!-- keyboard -->
+ <string name="KBShift">Shift</string>
+ <string name="KBCtrl">Ctrl</string>
+
+ <!-- Avatar Skeleton -->
+ <string name="Chest">Chest</string>
+ <string name="Skull">Skull</string>
+ <string name="Left Shoulder">Left Shoulder</string>
+ <string name="Right Shoulder">Right Shoulder</string>
+ <string name="Left Hand">Left Hand</string>
+ <string name="Right Hand">Right Hand</string>
+ <string name="Left Foot">Left Foot</string>
+ <string name="Right Foot">Right Foot</string>
+ <string name="Spine">Spine</string>
+ <string name="Pelvis">Pelvis</string>
+ <string name="Mouth">Mouth</string>
+ <string name="Chin">Chin</string>
+ <string name="Left Ear">Left Ear</string>
+ <string name="Right Ear">Right Ear</string>
+ <string name="Left Eyeball">Left Eyeball</string>
+ <string name="Right Eyeball">Right Eyeball</string>
+ <string name="Nose">Nose</string>
+ <string name="R Upper Arm">R Upper Arm</string>
+ <string name="R Forearm">R Forearm</string>
+ <string name="L Upper Arm">L Upper Arm</string>
+ <string name="L Forearm">L Forearm</string>
+ <string name="Right Hip">Right Hip</string>
+ <string name="R Upper Leg">R Upper Leg</string>
+ <string name="R Lower Leg">R Lower Leg</string>
+ <string name="Left Hip">Left Hip</string>
+ <string name="L Upper Leg">L Upper Leg</string>
+ <string name="L Lower Leg">L Lower Leg</string>
+ <string name="Stomach">Stomach</string>
+ <string name="Left Pec">Left Pec</string>
+ <string name="Right Pec">Right Pec</string>
+
+ <!-- HUD Position -->
+ <string name="Center 2">Center 2</string>
+ <string name="Top Right">Top Right</string>
+ <string name="Top">Top</string>
+ <string name="Top Left">Top Left</string>
+ <string name="Center">Center</string>
+ <string name="Bottom Left">Bottom Left</string>
+ <string name="Bottom">Bottom</string>
+ <string name="Bottom Right">Bottom Right</string>
+
+ <!-- compile queue-->
+ <string name="CompileQueueDownloadedCompiling">Downloaded, now compiling</string>
+ <string name="CompileQueueScriptNotFound">Script not found on server.</string>
+ <string name="CompileQueueProblemDownloading">Problem downloading</string>
+ <string name="CompileQueueInsufficientPermDownload">Insufficient permissions to download a script.</string>
+ <string name="CompileQueueInsufficientPermFor">Insufficient permissions for</string>
+ <string name="CompileQueueUnknownFailure">Unknown failure to download</string>
+ <string name="CompileQueueTitle">Recompilation Progress</string>
+ <string name="CompileQueueStart">recompile</string>
+ <string name="ResetQueueTitle">Reset Progress</string>
+ <string name="ResetQueueStart">reset</string>
+ <string name="RunQueueTitle">Set Running Progress</string>
+ <string name="RunQueueStart">set running</string>
+ <string name="NotRunQueueTitle">Set Not Running Progress</string>
+ <string name="NotRunQueueStart">set not running</string>
+
+ <!-- compile comment text-->
+ <string name="CompileSuccessful">Compile successful!</string>
+ <string name="CompileSuccessfulSaving">Compile successful, saving...</string>
+ <string name="SaveComplete">Save complete.</string>
+ <string name="ObjectOutOfRange">Script (object out of range)</string>
+
+ <!-- god tools -->
+ <string name="GodToolsObjectOwnedBy">Object [OBJECT] owned by [OWNER]</string>
+
+ <!-- groups -->
+ <string name="GroupsNone">none</string>
+ <string name="Group" value=" (group)" />
+ <string name="Unknown">(Unknown)</string>
+ <string name="SummaryForTheWeek" value="Summary for this week, beginning on " />
+ <string name="NextStipendDay" value="The next stipend day is " />
+ <string name="GroupIndividualShare" value=" Group Individual Share" />
+ <string name="Balance">Balance</string>
+ <string name="Credits">Credits</string>
+ <string name="Debits">Debits</string>
+ <string name="Total">Total</string>
+ <string name="NoGroupDataFound">No group data found for group </string>
+
+ <!-- floater IM -->
+ <string name="IMParentEstate">parent estate</string>
+ <string name="IMMainland">mainland</string>
+ <string name="IMTeen">teen</string>
+
+ <!-- floater region info -->
+ <string name="RegionInfoError">error</string>
+ <string name="RegionInfoAllEstatesOwnedBy">
+ all estates
+owned by [OWNER]
+ </string>
+ <string name="RegionInfoAllEstatesYouOwn">all estates you owned</string>
+ <string name="RegionInfoAllEstatesYouManage">
+ all estates that
+you managed for [OWNER]
+ </string>
+ <string name="RegionInfoAllowedResidents">Allowed residents: ([ALLOWEDAGENTS], max [MAXACCESS])</string>
+ <string name="RegionInfoAllowedGroups">Allowed groups: ([ALLOWEDGROUPS], max [MAXACCESS])</string>
+
+ <!-- script editor -->
+ <string name="CursorPos">Line [LINE], Column [COLUMN]</string>
+
+ <!-- panel dir browser -->
+ <string name="PanelDirCountFound">[COUNT] found</string>
+ <string name="PanelDirTimeStr">[hour12,datetime,slt]:[min,datetime,slt] [ampm,datetime,slt]</string>
+
+ <!-- panel dir events -->
+ <string name="PanelDirEventsDateText">[mthnum,datetime,slt]/[day,datetime,slt]</string>
+
+ <!-- panel contents -->
+ <string name="PanelContentsNewScript">New Script</string>
+
+ <!-- panel avatar -->
+ <!-- <string name="None">None</string> Duplicate-->
+
+ <!-- Mute -->
+ <string name="MuteByName">(by name)</string>
+ <string name="MuteAgent">(resident)</string>
+ <string name="MuteObject">(object)</string>
+ <string name="MuteGroup">(group)</string>
+
+ <!-- Region/Estate Covenant -->
+ <string name="RegionNoCovenant">There is no Covenant provided for this Estate.</string>
+ <string name="RegionNoCovenantOtherOwner">There is no Covenant provided for this Estate. The land on this estate is being sold by the Estate owner, not Linden Lab. Please contact the Estate Owner for sales details.</string>
+ <string name="covenant_last_modified">Last Modified:</string>
+ <string name="none_text" value=" (none) " />
+ <string name="never_text" value=" (never) " />
+
+ <!--Region Details-->
+ <string name="GroupOwned">Group Owned</string>
+ <string name="Public">Public</string>
+
+ <!-- panel classified -->
+ <string name="ClassifiedClicksTxt">Clicks: [TELEPORT] teleport, [MAP] map, [PROFILE] profile</string>
+ <string name="ClassifiedUpdateAfterPublish">(will update after publish)</string>
+
+ <!-- group voting dialog -->
+ <string name="GroupVoteYes">Yes</string>
+ <string name="GroupVoteNo">No</string>
+ <string name="GroupVoteNoActiveProposals">There are currently no active proposals</string>
+ <string name="GroupVoteNoArchivedProposals">There are currently no archived proposals</string>
+ <string name="GroupVoteRetrievingArchivedProposals">Retrieving archived proposals</string>
+ <string name="GroupVoteRetrievingActiveProposals">Retrieving active proposals</string>
+
+ <!-- Multi Preview Floater -->
+ <string name="MultiPreviewTitle">Preview</string>
+ <string name="MultiPropertiesTitle">Properties</string>
+
+ <!-- inventory offer -->
+ <string name="InvOfferAnObjectNamed">An object named</string>
+ <string name="InvOfferOwnedByGroup">owned by the group</string>
+ <string name="InvOfferOwnedByUnknownGroup">owned by an unknown group</string>
+ <string name="InvOfferOwnedBy">owned by</string>
+ <string name="InvOfferOwnedByUnknownUser">owned by an unknown user</string>
+ <string name="InvOfferGaveYou">gave you</string>
+ <string name="InvOfferYouDecline">You decline</string>
+ <string name="InvOfferFrom">from</string>
+
+ <!-- group money -->
+ <string name="GroupMoneyTotal">Total</string>
+ <string name="GroupMoneyBought">bought</string>
+ <string name="GroupMoneyPaidYou">paid you</string>
+ <string name="GroupMoneyPaidInto">paid into</string>
+ <string name="GroupMoneyBoughtPassTo">bought pass to</string>
+ <string name="GroupMoneyPaidFeeForEvent">paid fee for event</string>
+ <string name="GroupMoneyPaidPrizeForEvent">paid prize for event</string>
+ <string name="GroupMoneyBalance">Balance</string>
+ <string name="GroupMoneyCredits">Credits</string>
+ <string name="GroupMoneyDebits">Debits</string>
+
+ <!-- viewer object -->
+ <string name="ViewerObjectContents">Contents</string>
+
+ <!-- Viewer menu -->
+ <string name="AcquiredItems">Acquired Items</string>
+ <string name="Cancel">Cancel</string>
+ <string name="UploadingCosts">Uploading %s costs</string>
+ <string name="UnknownFileExtension">
+ Unknown file extension .%s
+Expected .wav, .tga, .bmp, .jpg, .jpeg, or .bvh
+ </string>
+ <string name="AddLandmarkNavBarMenu">Add Landmark...</string>
+ <string name="EditLandmarkNavBarMenu">Edit Landmark...</string>
+
+ <!-- Previews -->
+ <string name="FileSaved">File Saved</string>
+ <string name="Receiving">Receiving</string>
+
+ <!-- status bar , Time -->
+ <string name="AM">AM</string>
+ <string name="PM">PM</string>
+ <string name="PST">PST</string>
+ <string name="PDT">PDT</string>
+
+ <!-- Directions, HUD -->
+ <string name="Forward">Forward</string>
+ <string name="Left">Left</string>
+ <string name="Right">Right</string>
+ <string name="Back">Back</string>
+ <string name="North">North</string>
+ <string name="South">South</string>
+ <string name="West">West</string>
+ <string name="East">East</string>
+ <string name="Up">Up</string>
+ <string name="Down">Down</string>
+
+ <!-- Search Category Strings -->
+ <string name="Any Category">Any Category</string>
+ <string name="Shopping">Shopping</string>
+ <string name="Land Rental">Land Rental</string>
+ <string name="Property Rental">Property Rental</string>
+ <string name="Special Attraction">Special Attraction</string>
+ <string name="New Products">New Products</string>
+ <string name="Employment">Employment</string>
+ <string name="Wanted">Wanted</string>
+ <string name="Service">Service</string>
+ <string name="Personal">Personal</string>
+
+ <!-- PARCEL_CATEGORY_UI_STRING -->
+ <string name="None">None</string>
+ <string name="Linden Location">Linden Location</string>
+ <string name="Adult">Adult</string>
+ <string name="Arts&amp;Culture">Arts &amp; Culture</string>
+ <string name="Business">Business</string>
+ <string name="Educational">Educational</string>
+ <string name="Gaming">Gaming</string>
+ <string name="Hangout">Hangout</string>
+ <string name="Newcomer Friendly">Newcomer Friendly</string>
+ <string name="Parks&amp;Nature">Parks &amp; Nature</string>
+ <string name="Residential">Residential</string>
+ <!--<string name="Shopping">Shopping</string> -->
+ <string name="Stage">Stage</string>
+ <string name="Other">Other</string>
+ <string name="Any">Any</string>
+ <string name="You">You</string>
+
+ <!-- punctuations -->
+ <string name=":">:</string>
+ <string name=",">,</string>
+ <string name="...">...</string>
+ <string name="***">***</string>
+ <string name="(">(</string>
+ <string name=")">)</string>
+ <string name=".">.</string>
+ <string name="'">'</string>
+ <string name="---">---</string>
+
+ <!-- OSMessageBox messages -->
+ <string name="MBCmdLineError">
+ An error was found parsing the command line.
+Please see: http://wiki.secondlife.com/wiki/Client_parameters
+Error:
+ </string>
+ <string name="MBCmdLineUsg">[APP_NAME] Command line usage:</string>
+ <string name="MBUnableToAccessFile">
+ [APP_NAME] is unable to access a file that it needs.
+
+This can be because you somehow have multiple copies running, or your system incorrectly thinks a file is open.
+If this message persists, restart your computer and try again.
+If it continues to persist, you may need to completely uninstall [APP_NAME] and reinstall it.
+ </string>
+ <string name="MBFatalError">Fatal Error</string>
+ <string name="MBRequiresAltiVec"> [APP_NAME] requires a processor with AltiVec (G4 or later).</string>
+ <string name="MBAlreadyRunning">
+ [APP_NAME] is already running.
+Check your task bar for a minimized copy of the program.
+If this message persists, restart your computer.
+ </string>
+ <string name="MBFrozenCrashed">
+ [APP_NAME] appears to have frozen or crashed on the previous run.
+Would you like to send a crash report?
+ </string>
+ <string name="MBAlert">Alert</string>
+ <string name="MBNoDirectX">
+ [APP_NAME] is unable to detect DirectX 9.0b or greater.
+[APP_NAME] uses DirectX to detect hardware and/or outdated drivers that can cause stability problems, poor performance and crashes. While you can run [APP_NAME] without it, we highly recommend running with DirectX 9.0b.
+
+Do you wish to continue?
+ </string>
+ <string name="MBWarning">Warning</string>
+ <string name="MBNoAutoUpdate">
+ Automatic updating is not yet implemented for Linux.
+Please download the latest version from www.secondlife.com.
+ </string>
+ <string name="MBRegClassFailed">RegisterClass failed</string>
+ <string name="MBError">Error</string>
+ <string name="MBFullScreenErr">
+ Unable to run fullscreen at [WIDTH] x [HEIGHT].
+Running in window.
+ </string>
+ <string name="MBDestroyWinFailed">Shutdown Error while destroying window (DestroyWindow() failed)</string>
+ <string name="MBShutdownErr">Shutdown Error</string>
+ <string name="MBDevContextErr">Can't make GL device context</string>
+ <string name="MBPixelFmtErr">Can't find suitable pixel format</string>
+ <string name="MBPixelFmtDescErr">Can't get pixel format description</string>
+ <string name="MBTrueColorWindow">
+ [APP_NAME] requires True Color (32-bit) to run in a window.
+Please go to Control Panels &gt; Display &gt; Settings and set the screen to 32-bit color.
+Alternately, if you choose to run fullscreen, [APP_NAME] will automatically adjust the screen each time it runs.
+ </string>
+ <string name="MBAlpha">
+ [APP_NAME] is unable to run because it can't get an 8 bit alpha channel. Usually this is due to video card driver issues.
+Please make sure you have the latest video card drivers installed.
+Also be sure your monitor is set to True Color (32-bit) in Control Panels &gt; Display &gt; Settings.
+If you continue to receive this message, contact the [SUPPORT_SITE].
+ </string>
+ <string name="MBPixelFmtSetErr">Can't set pixel format</string>
+ <string name="MBGLContextErr">Can't create GL rendering context</string>
+ <string name="MBGLContextActErr">Can't activate GL rendering context</string>
+ <string name="MBVideoDrvErr">
+ [APP_NAME] is unable to run because your video card drivers did not install properly, are out of date, or are for unsupported hardware. Please make sure you have the latest video card drivers and even if you do have the latest, try reinstalling them.
+
+If you continue to receive this message, contact the [SUPPORT_SITE].
+ </string>
+
+ <!-- Avatar Shape Information -->
+ <string name="Attached Earlobes">Attached Earlobes</string>
+ <string name="Arm Length">Arm Length</string>
+ <string name="Back Bangs Down">Back Bangs Down</string>
+ <string name="Back Bangs Up">Back Bangs Up</string>
+ <string name="Back Hair Down">Back Hair Down</string>
+ <string name="Back Hair Up">Back Hair Up</string>
+ <string name="Belly Size">Belly Size</string>
+ <string name="Blonde Hair">Blonde Hair</string>
+ <string name="Big Eyeball">Big Eyeball</string>
+ <string name="Big Hair Back">Big Hair Back</string>
+ <string name="Big Hair Front">Big Hair Front</string>
+ <string name="Big Hair Top">Big Hair Top</string>
+ <string name="Body Fat">Body Fat</string>
+ <string name="Body Thickness">Body Thickness</string>
+ <string name="Breast Buoyancy">Breast Buoyancy</string>
+ <string name="Breast Cleavage">Breast Cleavage</string>
+ <string name="Breast Size">Breast Size</string>
+ <string name="Bridge Width">Bridge Width</string>
+ <string name="Brow Size">Brow Size</string>
+ <string name="Butt Size">Butt Size</string>
+ <string name="Cheek Bones">Cheek Bones</string>
+ <string name="Chest Size">Chest Size</string>
+ <string name="Chin Angle">Chin Angle</string>
+ <string name="Chin Cleft">Chin Cleft</string>
+ <string name="Chin Depth">Chin Depth</string>
+ <string name="Chin-Neck">Chin-Neck</string>
+ <string name="Collar Back">Collar Back</string>
+ <string name="Collar Front">Collar Front</string>
+ <string name="Crooked Nose">Crooked Nose</string>
+ <string name="Cuff Flare">Cuff Flare</string>
+ <string name="Ear Angle">Ear Angle</string>
+ <string name="Ear Size">Ear Size</string>
+ <string name="Ear Tips">Ear Tips</string>
+ <string name="Egg Head">Egg Head</string>
+ <string name="Eye Bags">Eye Bags</string>
+ <string name="Eye Color">Eye Color</string>
+ <string name="Eye Depth">Eye Depth</string>
+ <string name="Eye Lightness">Eye Lightness</string>
+ <string name="Eye Opening">Eye Opening</string>
+ <string name="Eye Pop">Eye Pop</string>
+ <string name="Eye Size">Eye Size</string>
+ <string name="Eye Spacing">Eye Spacing</string>
+ <string name="Eyeball Size">Eyeball Size</string>
+ <string name="Eyebrow Arc">Eyebrow Arc</string>
+ <string name="Eyebrow Height">Eyebrow Height</string>
+ <string name="Eyebrow Points">Eyebrow Points</string>
+ <string name="Eyelash Length">Eyelash Length</string>
+ <string name="Eyeliner">Eyeliner</string>
+ <string name="Eyeliner Color">Eyeliner Color</string>
+ <string name="Face Shear">Face Shear</string>
+ <string name="Facial Definitionr">Facial Definition</string>
+ <string name="Fat Head">Fat Head</string>
+ <string name="Fat Lower Lip">Fat Lower Lip</string>
+ <string name="Fat Torso">Fat Torso</string>
+ <string name="Fat Upper Lip">Fat Upper Lip</string>
+ <string name="Foot Size">Foot Size</string>
+ <string name="Freckles">Freckles</string>
+ <string name="Front Bangs Down">Front Bangs Down</string>
+ <string name="Front Bangs Up">Front Bangs Up</string>
+ <string name="Front Hair Down">Front Hair Down</string>
+ <string name="Front Hair Up">Front Hair Up</string>
+ <string name="Forehead Angle">Forehead Angle</string>
+ <string name="Full Hair Sides">Full Hair Sides</string>
+ <string name="Glove Fingers">Glove Fingers</string>
+ <string name="Glove Length">Glove Length</string>
+ <string name="Hair Thickess">Hair Thickess</string>
+ <string name="Hair Tilted Left">Hair Tilted Left</string>
+ <string name="Hair Tilted Right">Hair Tilted Right</string>
+ <string name="Hair Volume">Hair Volume</string>
+ <string name="Hand Size">Hand Size</string>
+ <string name="Head Length">Head Length</string>
+ <string name="Head Shape">Head Shape</string>
+ <string name="Head Size">Head Size</string>
+ <string name="Head Stretch">Head Stretch</string>
+ <string name="Heel Height">Heel Height</string>
+ <string name="Heel Shape">Heel Shape</string>
+ <string name="Height">Height</string>
+ <string name="Hip Width">Hip Width</string>
+ <string name="Hip Length">Hip Length</string>
+ <string name="Inner Eye Corner">Inner Eye Corner</string>
+ <string name="Jacket Length">Jacket Length</string>
+ <string name="Jacket Wrinkles">Jacket Wrinkles</string>
+ <string name="Jowls">Jowls</string>
+ <string name="Jaw Angle">Jaw Angle</string>
+ <string name="Jaw Jut">Jaw Jut</string>
+ <string name="Jaw Shape">Jaw Shape</string>
+ <string name="Knee Angle">Knee Angle</string>
+ <string name="Left Part">Left Part</string>
+ <string name="Leg Muscles">Leg Muscles</string>
+ <string name="Leg Length">Leg Length</string>
+ <string name="Lip Cleft">Lip Cleft</string>
+ <string name="Lip Cleft Depth">Lip Cleft Depth</string>
+ <string name="Lip Fullness">Lip Fullness</string>
+ <string name="Lip Pinkness">Lip Pinkness</string>
+ <string name="Lip Ratio">Lip Ratio</string>
+ <string name="Lip Thickness">Lip Thickness</string>
+ <string name="Lip Width">Lip Width</string>
+ <string name="Longcuffs">Longcuffs</string>
+ <string name="Love Handles">Love Handles</string>
+ <string name="Lower Bridge">Lower Bridge</string>
+ <string name="Lower Cheeks">Lower Cheeks</string>
+ <string name="Middle Part">Middle Part</string>
+ <string name="Mouth Corner">Mouth Corner</string>
+ <string name="Mouth Position">Mouth Position</string>
+ <string name="Nail Polish">Nail Polish</string>
+ <string name="Nail Polish Color">Nail Polish Color</string>
+ <string name="Neck Length">Neck Length</string>
+ <string name="Neck Thickness">Neck Thickness</string>
+ <string name="Nose Size">Nose Size</string>
+ <string name="Nose Thickness">Nose Thickness</string>
+ <string name="Nose Tip Angle">Nose Tip Angle</string>
+ <string name="Nose Tip Shape">Nose Tip Shape</string>
+ <string name="Nose Width">Nose Width</string>
+ <string name="Nostril Division">Nostril Division</string>
+ <string name="Nostril Width">Nostril Width</string>
+ <string name="Open Front">Open Front</string>
+ <string name="Outer Eye Corner">Outer Eye Corner</string>
+ <string name="Outer Shadow">Outer Shadow</string>
+ <string name="Out Shdw Opacity">Out Shdw Opacity</string>
+ <string name="Out Shdw Color">Out Shdw Color</string>
+ <string name="Package">Package</string>
+ <string name="Pants Crotch">Pants Crotch</string>
+ <string name="Pants Fit">Pants Fit</string>
+ <string name="Pants Length">Pants Length</string>
+ <string name="Pants Waist">Pants Waist</string>
+ <string name="Pants Wrinkles">Pants Wrinkles</string>
+ <string name="Part Bangs">Part Bangs</string>
+ <string name="Pectorals">Pectorals</string>
+ <string name="Platform Height">Platform Height</string>
+ <string name="Platform Width">Platform Width</string>
+ <string name="Pigment">Pigment</string>
+ <string name="Puffy Eyelids">Puffy Eyelids</string>
+ <string name="Rainbow Color">Rainbow Color</string>
+ <string name="Red Hair">Red Hair</string>
+ <string name="Right Part">Right Part</string>
+ <string name="Round Forehead">Round Forehead</string>
+ <string name="Rosy Complexion">Rosy Complexion</string>
+ <string name="Ruddiness">Ruddiness</string>
+ <string name="Rumpled Hair">Rumpled Hair</string>
+ <string name="Saddle Bags">Saddle Bags</string>
+ <string name="Scrawny Leg">Scrawny Leg</string>
+ <string name="Shear Back">Shear Back</string>
+ <string name="Shear Face">Shear Face</string>
+ <string name="Shear Front">Shear Front</string>
+ <string name="Shift Mouth">Shift Mouth</string>
+ <string name="Shirt Bottom">Shirt Bottom</string>
+ <string name="Shirt Fit">Shirt Fit</string>
+ <string name="Shirt Wrinkles">Shirt Wrinkles</string>
+ <string name="Shoe Height">Shoe Height</string>
+ <string name="Shoulders">Shoulders</string>
+ <string name="Side Bangs Down">Side Bangs Down</string>
+ <string name="Side Bangs Up">Side Bangs Up</string>
+ <string name="Sides Hair Down">Sides Hair Down</string>
+ <string name="Sides Hair Up">Sides Hair Up</string>
+ <string name="Skirt Fit">Skirt Fit</string>
+ <string name="Skirt Length">Skirt Length</string>
+ <string name="Slanted Forehead">Slanted Forehead</string>
+ <string name="Sleeve Length">Sleeve Length</string>
+ <string name="Sleeve Looseness">Sleeve Looseness</string>
+ <string name="Slit Back">Slit Back</string>
+ <string name="Slit Front">Slit Front</string>
+ <string name="Slit Left">Slit Left</string>
+ <string name="Slit Right">Slit Right</string>
+ <string name="Socks Length">Socks Length</string>
+ <string name="Spiked Hair">Spiked Hair</string>
+ <string name="Squash/Stretch Head">Squash/Stretch Head</string>
+ <string name="Swept Back Hair">Swept Back Hair</string>
+ <string name="Swept Forward Hair">Swept Forward Hair</string>
+ <string name="Taper Back">Taper Back</string>
+ <string name="Taper Front">Taper Front</string>
+ <string name="Toe Shape">Toe Shape</string>
+ <string name="Toe Thickness">Toe Thickness</string>
+ <string name="Toe Length">Toe Length</string>
+ <string name="Torso Length">Torso Length</string>
+ <string name="Torso Muscles">Torso Muscles</string>
+ <string name="Torso Scrawny">Torso Scrawny</string>
+ <string name="Upper Bridge">Upper Bridge</string>
+ <string name="Upper Cheeks">Upper Cheeks</string>
+ <string name="Upper Chin Cleft">Upper Chin Cleft</string>
+ <string name="Upper Eyelid Fold">Upper Eyelid Fold</string>
+ <string name="Waist Height">Waist Height</string>
+ <string name="White Hair">White Hair</string>
+ <string name="big belly skirt">big belly skirt</string>
+ <string name="bigbutt skirt">bigbutt skirt</string>
+ <string name="bustle skirt">bustle skirt</string>
+ <string name="legs skirt">legs skirt</string>
+ <string name="loose skirt">loose skirt</string>
+ <string name="poofy skirt">poofy skirt</string>
+ <string name="tight skirt">tight skirt</string>
+ <string name="wrinkles">wrinkles</string>
+
+ <!-- Favorites Bar -->
+ <string name="location_ctrl_add_landmark">Add to My Landmarks</string>
+ <string name="location_ctrl_edit_landmark">Edit My Landmark</string>
+ <string name="favorite_landmark_loading_tooltip">(Loading...)</string>
+
+ <!-- Strings used by the (currently Linux) auto-updater app -->
+ <string name="UpdaterWindowTitle">
+ [APP_NAME] Update
+ </string>
+ <string name="UpdaterNowUpdating">
+ Now updating [APP_NAME]...
+ </string>
+ <string name="UpdaterNowInstalling">
+ Installing [APP_NAME]...
+ </string>
+ <string name="UpdaterUpdatingDescriptive">
+ Your [APP_NAME] Viewer is being updated to the latest release. This may take some time, so please be patient.
+ </string>
+ <string name="UpdaterProgressBarTextWithEllipses">
+ Downloading update...
+ </string>
+ <string name="UpdaterProgressBarText">
+ Downloading update
+ </string>
+ <string name="UpdaterFailDownloadTitle">
+ Failed to download update
+ </string>
+ <string name="UpdaterFailUpdateDescriptive">
+ An error occurred while updating [APP_NAME]. Please download the latest version from www.secondlife.com.
+ </string>
+ <string name="UpdaterFailInstallTitle">
+ Failed to install update
+ </string>
+ <string name="UpdaterFailStartTitle">
+ Failed to start viewer
+ </string>
+</strings>
diff --git a/indra/newview/skins/default/xui/en/teleport_strings.xml b/indra/newview/skins/default/xui/en/teleport_strings.xml
new file mode 100644
index 0000000000..e8f6b1319a
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/teleport_strings.xml
@@ -0,0 +1,77 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<teleport_messages>
+ <message_set name="errors">
+ <message name="invalid_tport">
+ Problem encountered processing your teleport request. You may need to log back in before you can teleport.
+If you continue to get this message, please check the [SUPPORT_SITE].
+ </message>
+ <message name="invalid_region_handoff">
+ Problem encountered processing your region crossing. You may need to log back in before you can cross regions.
+If you continue to get this message, please check the [SUPPORT_SITE].
+ </message>
+ <message name="blocked_tport">
+ Sorry, teleport is currently blocked. Try again in a moment.
+If you still cannot teleport, please log out and log back in to resolve the problem.
+ </message>
+ <message name="nolandmark_tport">
+ Sorry, but system was unable to locate landmark destination.
+ </message>
+ <message name="timeout_tport">
+ Sorry, but system was unable to complete the teleport connection.
+Try again in a moment.
+ </message>
+ <message name="noaccess_tport">
+ Sorry, you do not have access to that teleport destination.
+ </message>
+ <message name="missing_attach_tport">
+ Your attachments have not arrived yet. Try waiting for a few more seconds or log out and back in again before attempting to teleport.
+ </message>
+ <message name="too_many_uploads_tport">
+ The asset queue in this region is currently clogged so your teleport request will not be able to succeed in a timely manner. Please try again in a few minutes or go to a less busy area.
+ </message>
+ <message name="expired_tport">
+ Sorry, but the system was unable to complete your teleport request in a timely fashion. Please try again in a few minutes.
+ </message>
+ <message name="expired_region_handoff">
+ Sorry, but the system was unable to complete your region crossing in a timely fashion. Please try again in a few minutes.
+ </message>
+ <message name="no_host">
+ Unable to find teleport destination. The destination may be temporarily unavailable or no longer exists. Please try again in a few minutes.
+ </message>
+ <message name="no_inventory_host">
+ The inventory system is currently unavailable.
+ </message>
+ </message_set>
+ <message_set name="progress">
+ <message name="sending_dest">
+ Sending to destination.
+ </message>
+ <message name="redirecting">
+ Redirecting to different location.
+ </message>
+ <message name="relaying">
+ Relaying to destination.
+ </message>
+ <message name="sending_home">
+ Sending home location request.
+ </message>
+ <message name="sending_landmark">
+ Sending landmark location request.
+ </message>
+ <message name="completing">
+ Completing teleport.
+ </message>
+ <message name="resolving">
+ Resolving destination.
+ </message>
+ <message name="contacting">
+ Contacting new region.
+ </message>
+ <message name="arriving">
+ Arriving...
+ </message>
+ <message name="requesting">
+ Requesting Teleport...
+ </message>
+ </message_set>
+</teleport_messages>
diff --git a/indra/newview/skins/default/xui/en/widgets/button.xml b/indra/newview/skins/default/xui/en/widgets/button.xml
new file mode 100644
index 0000000000..3e7e07749a
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/widgets/button.xml
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<button image_unselected="PushButton_Off"
+ image_selected="PushButton_Selected"
+ image_disabled_selected="PushButton_Selected_Disabled"
+ image_disabled="PushButton_Disabled"
+ label_color="ButtonLabelColor"
+ label_color_selected="ButtonLabelSelectedColor"
+ label_color_disabled="ButtonLabelDisabledColor"
+ label_color_disabled_selected="ButtonLabelSelectedDisabledColor"
+ highlight_color="ButtonUnselectedFgColor"
+ image_color="ButtonImageColor"
+ image_color_disabled="ButtonImageColor"
+ flash_color="ButtonFlashBgColor"
+ hover_glow_amount="0.15"
+ halign="center"
+ scale_image="true">
+</button>
diff --git a/indra/newview/skins/default/xui/en/widgets/check_box.xml b/indra/newview/skins/default/xui/en/widgets/check_box.xml
new file mode 100644
index 0000000000..bbb5e9b56a
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/widgets/check_box.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<check_box text_enabled_color="LabelTextColor"
+ text_disabled_color="LabelDisabledColor"
+ font="SansSerifSmall"
+ follows="left|top">
+ <check_box.label_text name="checkbox label" />
+ <check_box.check_button name="CheckboxCtrl Button"
+ commit_on_return="false"
+ label=""
+ is_toggle="true"
+ font="SansSerif"
+ scale_image="false"
+ image_unselected="Checkbox_Off"
+ image_selected="Checkbox_On"
+ image_disabled="Checkbox_Off_Disabled"
+ image_disabled_selected="Checkbox_On_Disabled"
+ image_pressed="Checkbox_Press"
+ image_pressed_selected="Checkbox_On_Press"/>
+</check_box>
diff --git a/indra/newview/skins/default/xui/en/widgets/color_swatch.xml b/indra/newview/skins/default/xui/en/widgets/color_swatch.xml
new file mode 100644
index 0000000000..178c890c61
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/widgets/color_swatch.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<color_swatch alpha_background_image="color_swatch_alpha.tga"
+ border_color="DefaultHighlightLight"
+ name="color_swatch">
+ <color_swatch.caption_text name="caption"
+ font="SansSerifSmall"
+ follows="left|right|bottom"/>
+</color_swatch>
diff --git a/indra/newview/skins/default/xui/en/widgets/combo_box.xml b/indra/newview/skins/default/xui/en/widgets/combo_box.xml
new file mode 100644
index 0000000000..d7369d0726
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/widgets/combo_box.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<combo_box font="SansSerifSmall"
+ list_position="below"
+ max_chars="20"
+ follows="right|top">
+ <combo_box.combo_button name="Combobox Button"
+ label=""
+ hover_glow_amount="0.15"
+ font="SansSerifSmall"
+ scale_image="true"
+ image_unselected="ComboButton_Off"
+ image_selected="ComboButton_Selected"
+ image_disabled="ComboButton_Disabled" />
+ <combo_box.drop_down_button name="Drop Down Button"
+ label=""
+ hover_glow_amount="0.15"
+ font="SansSerifSmall"
+ scale_image="true"
+ pad_right="24"
+ image_unselected="DropDown_Off"
+ image_selected="DropDown_Selected"
+ image_disabled="DropDown_Disabled" />
+ <combo_box.combo_list bg_writeable_color="MenuDefaultBgColor" />
+ <combo_box.combo_editor name="Combo Text Entry"
+ select_on_focus="true"
+ font="SansSerifSmall" />
+</combo_box>
diff --git a/indra/newview/skins/default/xui/en/widgets/drop_down.xml b/indra/newview/skins/default/xui/en/widgets/drop_down.xml
new file mode 100644
index 0000000000..602250ace6
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/widgets/drop_down.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<drop_down text_enabled_color="LabelTextColor"
+ text_disabled_color="LabelDisabledColor"
+ font="SansSerifSmall"
+ allow_text_entry="false"
+ follows="left|top">
+ <drop_down.combo_button name="Combobox Button"
+ hover_glow_amount="0.15"
+ font="SansSerifSmall"
+ halign="left"
+ scale_image="true"
+ image_unselected="PushButton_Off"
+ image_selected="PushButton_Selected"
+ image_disabled="PushButton_Disabled"
+ image_disabled_selected="PushButton_Disabled_Selected"
+ image_overlay="Combobox_Over"
+ image_overlay_alignment="right" />
+ <drop_down.combo_list bg_writeable_color="white" />
+ <drop_down.combo_editor name="Combo Text Entry" visible="false" select_on_focus="true" />
+</drop_down>
diff --git a/indra/newview/skins/default/xui/en/widgets/filter_editor.xml b/indra/newview/skins/default/xui/en/widgets/filter_editor.xml
new file mode 100644
index 0000000000..d7736832a3
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/widgets/filter_editor.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<filter_editor select_on_focus="true"
+ background_image_disabled="TextField_Search_Disabled"
+ background_image_focused="TextField_Search_Active">
+ <clear_filter_button label=""
+ image_unselected="Icon_Close_Foreground"
+ image_selected="Icon_Close_Press" />
+</filter_editor>
diff --git a/indra/newview/skins/default/xui/en/widgets/flyout_button.xml b/indra/newview/skins/default/xui/en/widgets/flyout_button.xml
new file mode 100644
index 0000000000..a5043c5c14
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/widgets/flyout_button.xml
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<flyout_button list_position="below">
+ <action_button scale_image="true"
+ image_selected="SegmentedBtn_Left_Selected"
+ image_unselected="SegmentedBtn_Left_Off"
+ image_disabled="SegmentedBtn_Left_Disabled"/>
+ <combo_button image_selected="ComboButton_Selected"
+ image_unselected="ComboButton_Off"
+ image_disabled="ComboButton_Disabled"
+ pad_right="6"
+ tab_stop="false"/>
+</flyout_button> \ No newline at end of file
diff --git a/indra/newview/skins/default/xui/en/widgets/gesture_combo_box.xml b/indra/newview/skins/default/xui/en/widgets/gesture_combo_box.xml
new file mode 100644
index 0000000000..26af76d8a3
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/widgets/gesture_combo_box.xml
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<gesture_combo_box font="SansSerifSmall"
+ label="Gestures"
+ list_position="below"
+ max_chars="20"
+ follows="right|top">
+ <gesture_combo_box.combo_button name="Combobox Button"
+ label=""
+ hover_glow_amount="0.15"
+ font="SansSerifSmall"
+ scale_image="true"
+ image_unselected="ComboButton_Off"
+ image_selected="ComboButton_Selected"
+ image_disabled="ComboButton_Disabled"
+ image_disabled_selected="ComboButton_Disabled_Selected" />
+ <gesture_combo_box.drop_down_button name="Drop Down Button"
+ label=""
+ hover_glow_amount="0.15"
+ font="SansSerifSmall"
+ scale_image="true"
+ pad_right="24"
+ image_unselected="DropDown_Off"
+ image_selected="DropDown_Selected"
+ image_disabled="DropDown_Disabled"
+ image_disabled_selected="DropDown_Disabled_Selected" />
+ <gesture_combo_box.combo_list bg_writeable_color="MenuDefaultBgColor" />
+ <gesture_combo_box.combo_editor name="Combo Text Entry"
+ select_on_focus="true"
+ font="SansSerifSmall" />
+</gesture_combo_box>
diff --git a/indra/newview/skins/default/xui/en/widgets/icon.xml b/indra/newview/skins/default/xui/en/widgets/icon.xml
new file mode 100644
index 0000000000..adb743a628
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/widgets/icon.xml
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<icon color="1.0 1.0 1.0 1.0"
+ tab_stop="false"
+ mouse_opaque="false"
+ name="icon"
+ follows="left|top">
+</icon>
diff --git a/indra/newview/skins/default/xui/en/widgets/line_editor.xml b/indra/newview/skins/default/xui/en/widgets/line_editor.xml
new file mode 100644
index 0000000000..8b4126952e
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/widgets/line_editor.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<line_editor
+ background_image="TextField_Off"
+ background_image_disabled="TextField_Disabled"
+ background_image_focused="TextField_Active"
+ select_on_focus="false"
+ handle_edit_keys_directly="false"
+ commit_on_focus_lost="true"
+ ignore_tab="true"
+ cursor_color="TextCursorColor"
+ text_color="TextFgColor"
+ text_readonly_color="TextFgReadOnlyColor"
+ text_tentative_color="TextFgTentativeColor"
+ highlight_color="EmphasisColor"
+ preedit_bg_color="White"
+ mouse_opaque="true"
+ name="line_editor"
+ font="SansSerifSmall">
+</line_editor>
diff --git a/indra/newview/skins/default/xui/en/widgets/list_view.xml b/indra/newview/skins/default/xui/en/widgets/list_view.xml
new file mode 100644
index 0000000000..c66aeb57a0
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/widgets/list_view.xml
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<list_view
+ fg_selected_color="ListViewSelectedFgColor"
+ bg_selected_color="ListViewSelectedBgColor"
+ bg_color="ListViewBgColor"
+ />
diff --git a/indra/newview/skins/default/xui/en/widgets/location_input.xml b/indra/newview/skins/default/xui/en/widgets/location_input.xml
new file mode 100644
index 0000000000..8f4d0edf95
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/widgets/location_input.xml
@@ -0,0 +1,54 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<!--
+*TODO: Replace hardcoded buttons width/height with getting this info from the button images.
+ Currently that doesn't work because LLUIImage::getWidth/getHeight() return 1 for the images.
+-->
+
+
+
+<location_input font="SansSerifSmall"
+ add_landmark_image_enabled="Favorite_Star_Active"
+ add_landmark_image_disabled="Favorite_Star_Off"
+ add_landmark_image_hover="Favorite_Star_Over"
+ add_landmark_image_selected="Favorite_Star_Press"
+ add_landmark_hpad="2"
+ allow_text_entry="true"
+ list_position="below"
+ show_text_as_tentative="false"
+ max_chars="20"
+ follows="left|top"
+ >
+ <info_button name="Place Information"
+ label=""
+ tool_tip="About current location"
+ width="16"
+ height="16"
+ follows="left|top"
+ hover_glow_amount="0.15"
+ image_unselected="Info_Off"
+ image_selected="Info_Off"
+ image_disabled_selected="Info_Off"
+ image_disabled="Info_Off" />
+ <add_landmark_button name="Add Landmark"
+ label=""
+ hover_glow_amount="0.15"
+ image_hover_selected="Favorite_Star_Over"
+ image_hover_unselected="Favorite_Star_Over"
+ width="16"
+ height="16"
+ tool_tip="Add to My Landmarks"
+ follows="right|top"
+ scale_image="false" />
+ <combo_button name="Location History"
+ label=""
+ pad_right="0"
+ tool_tip="My Location History"/>
+ <combo_list bg_writeable_color="MenuDefaultBgColor"/>
+ <combo_editor name="Combo Text Entry"
+ text_pad_left="20"
+ select_on_focus="false"
+ font="SansSerifSmall"
+ bevel_style="none"
+ border_style="line"
+ border.border_thickness="0"/>
+</location_input>
diff --git a/indra/newview/skins/default/xui/en/widgets/menu.xml b/indra/newview/skins/default/xui/en/widgets/menu.xml
new file mode 100644
index 0000000000..58543338f6
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/widgets/menu.xml
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<menu bg_color="MenuDefaultBgColor"
+ bg_visible="true"
+ drop_shadow="true"
+ tear_off="false"
+ shortcut_pad="15">
+</menu>
diff --git a/indra/newview/skins/default/xui/en/widgets/menu_item_call.xml b/indra/newview/skins/default/xui/en/widgets/menu_item_call.xml
new file mode 100644
index 0000000000..24bda97f44
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/widgets/menu_item_call.xml
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<menu_item_call enabled_color="MenuItemEnabledColor"
+ disabled_color="MenuItemDisabledColor"
+ highlight_bg_color="MenuItemHighlightBgColor"
+ highlight_fg_color="MenuItemHighlightFgColor">
+</menu_item_call>
diff --git a/indra/newview/skins/default/xui/en/widgets/menu_item_check.xml b/indra/newview/skins/default/xui/en/widgets/menu_item_check.xml
new file mode 100644
index 0000000000..f6b06cb50b
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/widgets/menu_item_check.xml
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<menu_item_check enabled_color="MenuItemEnabledColor"
+ disabled_color="MenuItemDisabledColor"
+ highlight_bg_color="MenuItemHighlightBgColor"
+ highlight_fg_color="MenuItemHighlightFgColor">
+</menu_item_check>
diff --git a/indra/newview/skins/default/xui/en/widgets/menu_item_separator.xml b/indra/newview/skins/default/xui/en/widgets/menu_item_separator.xml
new file mode 100644
index 0000000000..e5cea476da
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/widgets/menu_item_separator.xml
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<menu_item_separator enabled_color="MenuItemEnabledColor"
+ disabled_color="MenuItemDisabledColor"
+ highlight_bg_color="MenuItemHighlightBgColor"
+ highlight_fg_color="MenuItemHighlightFgColor">
+</menu_item_separator>
diff --git a/indra/newview/skins/default/xui/en/widgets/multi_slider.xml b/indra/newview/skins/default/xui/en/widgets/multi_slider.xml
new file mode 100644
index 0000000000..e0900b48f3
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/widgets/multi_slider.xml
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<multi_slider text_color="LabelTextColor"
+ text_disabled_color="LabelDisabledColor"
+ draw_track="true"
+ use_triangle="false"
+ font="SansSerifSmall"/>
diff --git a/indra/newview/skins/default/xui/en/widgets/multi_slider_bar.xml b/indra/newview/skins/default/xui/en/widgets/multi_slider_bar.xml
new file mode 100644
index 0000000000..04a2cd635c
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/widgets/multi_slider_bar.xml
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<multi_slider_bar track_color="MultiSliderTrackColor"
+ thumb_disabled_color="MultiSliderDisabledThumbColor"
+ thumb_outline_color="MultiSliderThumbOutlineColor"
+ thumb_center_color="MultiSliderThumbCenterColor"
+ thumb_center_selected_color="MultiSliderThumbCenterSelectedColor"
+ triangle_color="MultiSliderTriangleColor"
+ draw_track="true"
+ use_triangle="false"
+ thumb_width="8"/>
diff --git a/indra/newview/skins/default/xui/en/widgets/name_editor.xml b/indra/newview/skins/default/xui/en/widgets/name_editor.xml
new file mode 100644
index 0000000000..21ba5c77f8
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/widgets/name_editor.xml
@@ -0,0 +1,2 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<name_editor default_text="(retrieving)"/> \ No newline at end of file
diff --git a/indra/newview/skins/default/xui/en/widgets/output_monitor.xml b/indra/newview/skins/default/xui/en/widgets/output_monitor.xml
new file mode 100644
index 0000000000..505c7ba936
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/widgets/output_monitor.xml
@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<output_monitor
+ image_mute="mute_icon.tga"
+ image_off="VoicePTT_Off"
+ image_on="VoicePTT_On"
+ image_level_1="VoicePTT_Lvl1"
+ image_level_2="VoicePTT_Lvl2"
+ image_level_3="VoicePTT_Lvl3"
+ />
diff --git a/indra/newview/skins/default/xui/en/widgets/panel.xml b/indra/newview/skins/default/xui/en/widgets/panel.xml
new file mode 100644
index 0000000000..b81a70b845
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/widgets/panel.xml
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<panel bg_opaque_color="PanelFocusBackgroundColor"
+ bg_alpha_color="PanelDefaultBackgroundColor"
+ background_visible="false"
+ background_opaque="false"/> \ No newline at end of file
diff --git a/indra/newview/skins/default/xui/en/widgets/progress_bar.xml b/indra/newview/skins/default/xui/en/widgets/progress_bar.xml
new file mode 100644
index 0000000000..339e53fbb8
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/widgets/progress_bar.xml
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<progress_bar image_bar="ProgressTrack"
+ image_fill="ProgressBar"
+ color_bar.red="0.5764"
+ color_bar.green="0.6627"
+ color_bar.blue="0.8352"
+ color_bar.alpha="1"
+ color_bg.red="0.3254"
+ color_bg.green="0.4000"
+ color_bg.blue="0.5058"
+ color_bg.alpha="1"
+ />
diff --git a/indra/newview/skins/default/xui/en/widgets/radio_group.xml b/indra/newview/skins/default/xui/en/widgets/radio_group.xml
new file mode 100644
index 0000000000..ad7ef5bffc
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/widgets/radio_group.xml
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<radio_group draw_border="false"
+ name="radio_group"
+ mouse_opaque="false"
+ follows="left|top"
+ font="SansSerifSmall"/>
diff --git a/indra/newview/skins/default/xui/en/widgets/radio_item.xml b/indra/newview/skins/default/xui/en/widgets/radio_item.xml
new file mode 100644
index 0000000000..dd848f3acd
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/widgets/radio_item.xml
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<radio_item follows="left|top">
+ <radio_item.label_text name="Radio Item label"/>
+ <radio_item.check_button name="Radio control button"
+ image_unselected="RadioButton_Off"
+ image_selected="RadioButton_On"
+ image_disabled="RadioButton_Disabled"
+ image_disabled_selected="RadioButton_On_Disabled"
+ image_pressed="RadioButton_Press"
+ image_pressed_selected="RadioButton_On_Press"/>
+</radio_item>
+
diff --git a/indra/newview/skins/default/xui/en/widgets/scroll_bar.xml b/indra/newview/skins/default/xui/en/widgets/scroll_bar.xml
new file mode 100644
index 0000000000..48bc021e6d
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/widgets/scroll_bar.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<scroll_bar thumb_image_vertical ="ScrollThumb_Vert"
+ thumb_image_horizontal ="ScrollThumb_Horiz"
+ track_image_vertical ="ScrollTrack_Vert"
+ track_image_horizontal ="ScrollTrack_Horiz"
+ track_color="ScrollbarTrackColor"
+ thumb_color="ScrollbarThumbColor"
+ thickness="15">
+ <up_button image_unselected="ScrollArrow_Up"
+ image_selected="ScrollArrow_Up"
+ scale_image="true" thickness="15"
+ hover_glow_amount="0.35"/>
+ <down_button image_unselected="ScrollArrow_Down"
+ image_selected="ScrollArrow_Down"
+ scale_image="true" thickness="15"
+ hover_glow_amount="0.35"/>
+ <left_button image_unselected="ScrollArrow_Left"
+ image_selected="ScrollArrow_Left"
+ scale_image="true" thickness="15"
+ hover_glow_amount="0.35"/>
+ <right_button image_unselected="ScrollArrow_Right"
+ image_selected="ScrollArrow_Right"
+ scale_image="true" thickness="15"
+ hover_glow_amount="0.35"/>
+</scroll_bar>
diff --git a/indra/newview/skins/default/xui/en/widgets/scroll_container.xml b/indra/newview/skins/default/xui/en/widgets/scroll_container.xml
new file mode 100644
index 0000000000..86356ff563
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/widgets/scroll_container.xml
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<scroll_container color="black"
+ opaque="false"
+ min_auto_scroll_rate="120"
+ max_auto_scroll_rate="500"/>
diff --git a/indra/newview/skins/default/xui/en/widgets/scroll_list.xml b/indra/newview/skins/default/xui/en/widgets/scroll_list.xml
new file mode 100644
index 0000000000..e3a53eee4d
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/widgets/scroll_list.xml
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<scroll_list fg_unselected_color="ScrollUnselectedColor"
+ fg_selected_color="ScrollSelectedFGColor"
+ bg_selected_color="ScrollSelectedBGColor"
+ fg_disable_color="ScrollDisabledColor"
+ bg_writeable_color="ScrollBgWriteableColor"
+ bg_readonly_color="ScrollBgReadOnlyColor"
+ bg_stripe_color="ScrollBGStripeColor"
+ hovered_color="ScrollHoveredColor"
+ highlighted_color="ScrollHighlightedColor"
+ column_padding="5"
+ draw_stripes="true"
+ background_visible="true"
+ heading_height="20"
+ draw_border="true"
+ draw_heading="false"/>
diff --git a/indra/newview/skins/default/xui/en/widgets/search_editor.xml b/indra/newview/skins/default/xui/en/widgets/search_editor.xml
new file mode 100644
index 0000000000..15b23ea9b3
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/widgets/search_editor.xml
@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<search_editor
+ text_pad_left="4"
+ select_on_focus="true"
+ background_image="TextField_Search_Off"
+ background_image_disabled="TextField_Search_Disabled"
+ background_image_focused="TextField_Search_Active" >
+ <search_button label=""
+ top_pad="4"
+ left_pad="4"
+ width="13"
+ height="13"
+ image_unselected="Search"
+ image_selected="Search" />
+</search_editor>
diff --git a/indra/newview/skins/default/xui/en/widgets/side_tray.xml b/indra/newview/skins/default/xui/en/widgets/side_tray.xml
new file mode 100644
index 0000000000..8b4a5afbe9
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/widgets/side_tray.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<side_tray tab_btn_image="TaskPanel_Tab_Off"
+ tab_btn_image_selected="TaskPanel_Tab_Selected"
+ tab_btn_width="32"
+ tab_btn_height="40"
+ tab_btn_margin="1"
+ >
+</side_tray>
diff --git a/indra/newview/skins/default/xui/en/widgets/simple_text_editor.xml b/indra/newview/skins/default/xui/en/widgets/simple_text_editor.xml
new file mode 100644
index 0000000000..4f2261c953
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/widgets/simple_text_editor.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<simple_text_editor
+ mouse_opaque="true"
+ font="SansSerifSmall"
+ max_length="255"
+ embedded_items="false"
+ hide_scrollbar="false"
+ hide_border="true"
+ word_wrap="false"
+ ignore_tab="true"
+ track_bottom="false"
+ cursor_color="TextCursorColor"
+ default_color="TextDefaultColor"
+ text_color="TextFgColor"
+ text_readonly_color="TextFgReadOnlyColor"
+ bg_readonly_color="TextBgReadOnlyColor"
+ bg_writeable_color="TextBgWriteableColor"
+ bg_focus_color="TextBgFocusColor"
+ link_color="HTMLLinkColor">
+ <simple_text_editor.border
+ bevel_style="in"
+ follows="all" />
+</simple_text_editor>
diff --git a/indra/newview/skins/default/xui/en/widgets/slider.xml b/indra/newview/skins/default/xui/en/widgets/slider.xml
new file mode 100644
index 0000000000..f735d09476
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/widgets/slider.xml
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<slider name="slider"
+ can_edit_text="false"
+ font="SansSerifSmall"
+ volume="false"
+ mouse_opaque="true"
+ show_text="true"
+ text_color="LabelTextColor"
+ text_disabled_color="LabelDisabledColor">
+ <slider.value_editor name="slider editor"
+ max_length="10"
+ follows="left|bottom"/>
+ <slider.value_text name="slider text"
+ follows="left|bottom"/>
+ <slider.slider_label name="slider label"/>
+</slider>
diff --git a/indra/newview/skins/default/xui/en/widgets/slider_bar.xml b/indra/newview/skins/default/xui/en/widgets/slider_bar.xml
new file mode 100644
index 0000000000..bc1ca339a2
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/widgets/slider_bar.xml
@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<slider_bar track_color="SliderTrackColor"
+ thumb_outline_color="SliderThumbOutlineColor"
+ thumb_center_color="SliderThumbCenterColor"
+ thumb_image="SliderThumb_Off"
+ thumb_image_pressed="SliderThumb_Press"
+ thumb_image_disabled="SliderThumb_Disabled"
+ track_image="SliderTrack_Horiz"
+ track_highlight_image="SliderTrack_Horiz" />
diff --git a/indra/newview/skins/default/xui/en/widgets/spinner.xml b/indra/newview/skins/default/xui/en/widgets/spinner.xml
new file mode 100644
index 0000000000..7d1a5118cb
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/widgets/spinner.xml
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<spinner text_enabled_color="LabelTextColor"
+ text_disabled_color="LabelDisabledColor"
+ decimal_digits="3"
+ label_width="40" >
+ <spinner.up_button name="SpinCtrl Up"
+ image_unselected="Stepper_Up_Off"
+ image_selected="Stepper_Up_Press"
+ tab_stop="false"
+ follows="left|bottom" />
+ <spinner.down_button name="SpinCtrl Down"
+ image_unselected="Stepper_Down_Off"
+ image_selected="Stepper_Down_Press"
+ tab_stop="false"
+ follows="left|bottom" />
+</spinner> \ No newline at end of file
diff --git a/indra/newview/skins/default/xui/en/widgets/split_button.xml b/indra/newview/skins/default/xui/en/widgets/split_button.xml
new file mode 100644
index 0000000000..b0367b599b
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/widgets/split_button.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<split_button
+ font="SansSerifSmall"
+ arrow_position="left"
+ follows="right|top">
+ <split_button.arrow_button
+ name="Arrow Button"
+ label=""
+ font="SansSerifSmall"
+ scale_image="true"
+ image_selected="camera_presets/camera_presets_arrow.png"
+ image_unselected="camera_presets/camera_presets_arrow.png"
+ image_disabled_selected="camera_presets/camera_presets_arrow.png"
+ image_disabled="camera_presets/camera_presets_arrow.png"
+ width="10"/>
+ <split_button.items_panel
+ background_visible="true"
+ border="true"
+ bg_alpha_color="1 1 1 1"
+ bg_opaq_color="1 1 1 1"
+ layout="topleft"
+ name="item_buttons"
+ />
+</split_button>
diff --git a/indra/newview/skins/default/xui/en/widgets/tab_container.xml b/indra/newview/skins/default/xui/en/widgets/tab_container.xml
new file mode 100644
index 0000000000..7aad55fb37
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/widgets/tab_container.xml
@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<tab_container tab_min_width="60"
+ tab_max_width="150"
+ tab_top_image_unselected="TabTop_Middle_Off"
+ tab_top_image_selected="TabTop_Middle_Selected"
+ tab_bottom_image_unselected="tab_bottom_blue.tga"
+ tab_bottom_image_selected="tab_bottom_selected_blue.tga"
+ tab_left_image_unselected="TabTop_Left_Off"
+ tab_left_image_selected="TabTop_Left_Selected"/> \ No newline at end of file
diff --git a/indra/newview/skins/default/xui/en/widgets/text.xml b/indra/newview/skins/default/xui/en/widgets/text.xml
new file mode 100644
index 0000000000..3d98cd66f9
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/widgets/text.xml
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<text name="text_box"
+ font="SansSerifSmall"
+ font_shadow="soft"
+ tab_stop="false"
+ halign="left"
+ hover_color="LabelSelectedColor"
+ disabled_color="LabelDisabledColor"
+ background_color="FloaterDefaultBackgroundColor"
+ border_color="DefaultHighlightLight"
+ use_ellipses="false"
+ bg_visible="false"
+ border_drop_shadow_visible="false"
+ border_visible="false"
+ hover="false"
+ text_color="LabelTextColor"/>
diff --git a/indra/newview/skins/default/xui/en/widgets/text_editor.xml b/indra/newview/skins/default/xui/en/widgets/text_editor.xml
new file mode 100644
index 0000000000..deaade04f8
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/widgets/text_editor.xml
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<!-- Core parameters are in simple_text_editor.xml -->
+<text_editor
+ allow_html="false" />
diff --git a/indra/newview/skins/default/xui/en/widgets/texture_picker.xml b/indra/newview/skins/default/xui/en/widgets/texture_picker.xml
new file mode 100644
index 0000000000..33c3475eb2
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/widgets/texture_picker.xml
@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<texture_picker border_color="DefaultHighlightLight">
+ <multiselect_text font="SansSerifSmall"/>
+ <caption_text text="Multiple"
+ halign="center"
+ font="SansSerifSmall"/>
+ <border bevel_style="in"/>
+</texture_picker>
+
diff --git a/indra/newview/skins/default/xui/en/widgets/view_border.xml b/indra/newview/skins/default/xui/en/widgets/view_border.xml
new file mode 100644
index 0000000000..0b0a9beb95
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/widgets/view_border.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<view_border highlight_light_color="DefaultHighlightLight"
+ highlight_dark_color="DefaultHighlightDark"
+ shadow_light_color="DefaultShadowLight"
+ shadow_dark_color="DefaultShadowDark"
+ border_thickness="1"
+ border_style="line"
+ bevel_style="out"/> \ No newline at end of file
diff --git a/indra/newview/skins/default/xui/en/widgets/web_browser.xml b/indra/newview/skins/default/xui/en/widgets/web_browser.xml
new file mode 100644
index 0000000000..118d63bbf0
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/widgets/web_browser.xml
@@ -0,0 +1,2 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<web_browser border_visible="true"/>
diff --git a/indra/newview/skins/default/xui/en/xui_version.xml b/indra/newview/skins/default/xui/en/xui_version.xml
new file mode 100644
index 0000000000..0e777751d3
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/xui_version.xml
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<xui_version>
+ 1.0
+</xui_version>
diff --git a/indra/newview/skins/default/xui/es/floater_about.xml b/indra/newview/skins/default/xui/es/floater_about.xml
index e59b5a6fb4..3e0f6513cc 100644
--- a/indra/newview/skins/default/xui/es/floater_about.xml
+++ b/indra/newview/skins/default/xui/es/floater_about.xml
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<floater name="floater_about" title="Acerca de Second Life">
+<floater name="floater_about" title="Acerca de [APP_NAME]">
<text_editor name="credits_editor">
Le ofrecen Second Life Philip, Tessa, Andrew, Cory, James, Ben, Char, Charlie, Colin, Dan, Daniel, Doug, Eric, Hamlet, Haney, Eve, Hunter, Ian, Jeff, Jennifer, Jim, John, Lee, Mark, Peter, Phoenix, Richard, Robin, Xenon, Steve, Tanya, Eddie, Avi, Frank, Bruce, Aaron, Alice, Bob, Debra, Eileen, Helen, Janet, Louie, Leviathania, Stefan, Ray, Kevin, Tom, Mikeb, MikeT, Burgess, Elena, Tracy, Bill, Todd, Ryan, Zach, Sarah, Nova, Tim, Stephanie, Michael, Evan, Nicolas, Catherine, Rachelle, Dave, Holly, Bub, Kelly, Magellan, Ramzi, Don, Sabin, Jill, Rheya, Jeska, Torley, Kona, Callum, Charity, Ventrella, Jack, Vektor, Iris, Chris, Nicole, Mick, Reuben, Blue, Babbage, Yedwab, Deana, Lauren, Brent, Pathfinder, Chadrick, Altruima, Jesse, Teeny, Monroe, Icculus, David, Tess, Lizzie, Patsy, Isaac, Lawrence, Cyn, Bo, Gia, Annette, Marius, Tbone, Jonathan, Karen, Ginsu, Satoko, Yuko, Makiko, Thomas, Harry, Seth, Alexei, Brian, Guy, Runitai, Ethan, Data, Cornelius, Kenny, Swiss, Zero, Natria, Wendy, Stephen, Teeple, Thumper, Lucy, Dee, Mia, Liana, Warren, Branka, Aura, beez, Milo, Hermia, Red, Thrax, Joe, Sally, Magenta, Mogura, Paul, Jose, Rejean, Henrik, Lexie, Amber, Logan, Xan, Nora, Morpheus, Donovan, Leyla, MichaelFrancis, Beast, Cube, Bucky, Joshua, Stryfe, Harmony, Teresa, Claudia, Walker, Glenn, Fritz, Fordak, June, Cleopetra, Jean, Ivy, Betsy, Roosevelt, Spike, Ken, Which, Tofu, Chiyo, Rob, Zee, dustin, George, Del, Matthew, Cat, Jacqui, Lightfoot, Adrian, Viola, Alfred, Noel, Irfan, Sunil, Yool, Rika, Jane, Xtreme, Frontier, a2, Neo, Siobhan, Yoz, Justin, Elle, Qarl, Benjamin, Isabel, Gulliver, Everett, Christopher, Izzy, Stephany, Garry, Sejong, Sean, Tobin, Iridium, Meta, Anthony, Jeremy, JP, Jake, Maurice, Madhavi, Leopard, Kyle, Joon, Kari, Bert, Belinda, Jon, Kristi, Bridie, Pramod, KJ, Socrates, Maria, Ivan, Aric, Yamasaki, Adreanne, Jay, MitchK, Ceren, Coco, Durl, Jenny, Periapse, Kartic, Storrs, Lotte, Sandy, Rohn, Colossus, Zen, BigPapi, Brad, Pastrami, Kurz, Mani, Neuro, Jaime, MJ, Rowan, Sgt, Elvis, Gecko, Samuel, Sardonyx, Leo, Bryan, Niko, Soft, Poppy, Rachel, Aki, Angelo, Banzai, Alexa, Sue, CeeLo, Bender, CG, Gillian, Pelle, Nick, Echo, Zara, Christine, Shamiran, Emma, Blake, Keiko, Plexus, Joppa, Sidewinder, Erica, Ashlei, Twilight, Kristen, Brett, Q, Enus, Simon, Bevis, Kraft, Kip, Chandler, Ron, LauraP, Ram, KyleJM, Scouse, Prospero, Melissa, Marty, Nat, Hamilton, Kend, Lordan, Jimmy, Kosmo, Seraph, Green, Ekim, Wiggo, JT, Rome, Doris, Miz, Benoc, Whump, Trinity, Patch, Kate, TJ, Bao, Joohwan, Christy, Sofia, Matias, Cogsworth, Johan, Oreh, Cheah, Angela, Brandy, Mango, Lan, Aleks, Gloria, Heidy, Mitchell, Space, Colton, Bambers, Einstein, Maggie, Malbers, Rose, Winnie, Stella, Milton, Rothman, Niall, Marin, Allison, Katie, Dawn, Katt, Dusty, Kalpana, Judy, Andrea, Ambroff, Infinity, Gail, Rico, Raymond, Yi, William, Christa, M, Teagan, Scout, Molly, Dante, Corr, Dynamike, Usi, Kaylee, Vidtuts, Lil, Danica, Sascha, Kelv, Jacob, Nya, Rodney, Brandon, Elsie, Blondin, Grant, Katrin, Nyx, Gabriel, Locklainn, Claire, Devin, Minerva, Monty, Austin, Bradford, Si, Keira, H, Caitlin, Dita, Makai, Jenn, Ann, Meredith, Clare, Joy, Praveen, Cody, Edmund, Ruthe, Sirena, Gayathri, Spider, FJ, Davidoff, Tian, Jennie, Louise, Oskar, Landon, Noelle, Jarv, Ingrid, Al, Sommer, Doc, Aria, Huin, Gray, Lili, Vir, DJ, Yang, T, Simone, Maestro, Scott, Charlene, Quixote, Amanda, Susan, Zed, Anne, Enkidu, Esbee, Joroan, Katelin, Roxie, Tay, Scarlet, Kevin, Johnny, Wolfgang, Andren, Bob, Howard, Merov, Rand, Ray, Michon, Newell, Galen, Dessie, Les, Michon, Jenelle, Geo, Siz, Shapiro, Pete, Calyle, Selene, Allen, Phoebe, Goldin, Kimmora, Dakota, Slaton, Lindquist, Zoey, Hari, Othello, Rohit, Sheldon, Petra, Viale, Gordon, Kaye, Pink, Ferny, Emerson, Davy, Bri, Chan, Juan, Robert, Terrence, Nathan, Carl, y otros muchos.
diff --git a/indra/newview/skins/default/xui/es/floater_animation_preview.xml b/indra/newview/skins/default/xui/es/floater_animation_preview.xml
index de01c5c54b..5a03aa6370 100644
--- a/indra/newview/skins/default/xui/es/floater_animation_preview.xml
+++ b/indra/newview/skins/default/xui/es/floater_animation_preview.xml
@@ -14,127 +14,53 @@
Posición de las manos
</text>
<combo_box left_delta="120" width="164" name="hand_pose_combo" tool_tip="Control de lo que hacen las manos durante la animación.">
- <combo_item name="Spread">
- Extendidas
- </combo_item>
- <combo_item name="Relaxed">
- Relajadas
- </combo_item>
- <combo_item name="PointBoth">
- Ambas señalan
- </combo_item>
- <combo_item name="Fist">
- Puño
- </combo_item>
- <combo_item name="RelaxedLeft">
- La izquierda relajada
- </combo_item>
- <combo_item name="PointLeft">
- La izquierda señala
- </combo_item>
- <combo_item name="FistLeft">
- Puño en la izquierda
- </combo_item>
- <combo_item name="RelaxedRight">
- La derecha relajada
- </combo_item>
- <combo_item name="PointRight">
- La derecha señala
- </combo_item>
- <combo_item name="FistRight">
- Puño en la derecha
- </combo_item>
- <combo_item name="SaluteRight">
- La derecha saluda
- </combo_item>
- <combo_item name="Typing">
- Escribiendo
- </combo_item>
- <combo_item name="PeaceRight">
- Paz en la derecha
- </combo_item>
+ <combo_box.item name="Spread" label="Extendidas"/>
+ <combo_box.item name="Relaxed" label="Relajadas"/>
+ <combo_box.item name="PointBoth" label="Ambas señalan"/>
+ <combo_box.item name="Fist" label="Puño"/>
+ <combo_box.item name="RelaxedLeft" label="La izquierda relajada"/>
+ <combo_box.item name="PointLeft" label="La izquierda señala"/>
+ <combo_box.item name="FistLeft" label="Puño en la izquierda"/>
+ <combo_box.item name="RelaxedRight" label="La derecha relajada"/>
+ <combo_box.item name="PointRight" label="La derecha señala"/>
+ <combo_box.item name="FistRight" label="Puño en la derecha"/>
+ <combo_box.item name="SaluteRight" label="La derecha saluda"/>
+ <combo_box.item name="Typing" label="Escribiendo"/>
+ <combo_box.item name="PeaceRight" label="Paz en la derecha"/>
</combo_box>
<text name="emote_label">
Expresión
</text>
<combo_box left_delta="120" width="164" name="emote_combo" tool_tip="Controle qué hace la cara durante la animación.">
- <combo_item name="[None]">
- [Nada]
- </combo_item>
- <combo_item name="Aaaaah">
- Aaaaah
- </combo_item>
- <combo_item name="Afraid">
- Con miedo
- </combo_item>
- <combo_item name="Angry">
- Enfadada
- </combo_item>
- <combo_item name="BigSmile">
- Gran sonrisa
- </combo_item>
- <combo_item name="Bored">
- Aburrida
- </combo_item>
- <combo_item name="Cry">
- Llorar
- </combo_item>
- <combo_item name="Disdain">
- Desdén
- </combo_item>
- <combo_item name="Embarrassed">
- Avergonzada
- </combo_item>
- <combo_item name="Frown">
- Fruncir el ceño
- </combo_item>
- <combo_item name="Kiss">
- Besar
- </combo_item>
- <combo_item name="Laugh">
- Reír
- </combo_item>
- <combo_item name="Plllppt">
- Sacar la lengua
- </combo_item>
- <combo_item name="Repulsed">
- Rechazo
- </combo_item>
- <combo_item name="Sad">
- Triste
- </combo_item>
- <combo_item name="Shrug">
- Encogerse de hombros
- </combo_item>
- <combo_item name="Smile">
- Sonrisa
- </combo_item>
- <combo_item name="Surprise">
- Sorpresa
- </combo_item>
- <combo_item name="Wink">
- Guiño
- </combo_item>
- <combo_item name="Worry">
- Preocupación
- </combo_item>
+ <combo_box.item name="[None]" label="Nada]"/>
+ <combo_box.item name="Aaaaah" label="Aaaaah"/>
+ <combo_box.item name="Afraid" label="Con miedo"/>
+ <combo_box.item name="Angry" label="Enfadada"/>
+ <combo_box.item name="BigSmile" label="Gran sonrisa"/>
+ <combo_box.item name="Bored" label="Aburrida"/>
+ <combo_box.item name="Cry" label="Llorar"/>
+ <combo_box.item name="Disdain" label="Desdén"/>
+ <combo_box.item name="Embarrassed" label="Avergonzada"/>
+ <combo_box.item name="Frown" label="Fruncir el ceño"/>
+ <combo_box.item name="Kiss" label="Besar"/>
+ <combo_box.item name="Laugh" label="Reír"/>
+ <combo_box.item name="Plllppt" label="Sacar la lengua"/>
+ <combo_box.item name="Repulsed" label="Rechazo"/>
+ <combo_box.item name="Sad" label="Triste"/>
+ <combo_box.item name="Shrug" label="Encogerse de hombros"/>
+ <combo_box.item name="Smile" label="Sonrisa"/>
+ <combo_box.item name="Surprise" label="Sorpresa"/>
+ <combo_box.item name="Wink" label="Guiño"/>
+ <combo_box.item name="Worry" label="Preocupación"/>
</combo_box>
<text name="preview_label" width="250">
Vista previa mientras
</text>
<combo_box left_delta="120" width="130" name="preview_base_anim" tool_tip="Compruebe cómo se comporta su animación a la vez que el avatar realiza acciones comunes.">
- <combo_item name="Standing">
- Estar de pie
- </combo_item>
- <combo_item name="Walking">
- Caminar
- </combo_item>
- <combo_item name="Sitting">
- Estar sentado
- </combo_item>
- <combo_item name="Flying">
- Volar
- </combo_item>
+ <combo_box.item name="Standing" label="Estar de pie"/>
+ <combo_box.item name="Walking" label="Caminar"/>
+ <combo_box.item name="Sitting" label="Estar sentado"/>
+ <combo_box.item name="Flying" label="Volar"/>
</combo_box>
<spinner label_width="125" width="192" label="Combinar (sec)" name="ease_in_time" tool_tip="Tiempo (en segundos) en el que se combinan las animaciones."/>
<spinner bottom_delta="-20" label_width="125" left="10" width="192" label="Dejar de combinar (sec)" name="ease_out_time" tool_tip="Tiempo (en segundos) en el que dejan de combinarse las animaciones."/>
diff --git a/indra/newview/skins/default/xui/es/floater_buy_land.xml b/indra/newview/skins/default/xui/es/floater_buy_land.xml
index b926b59195..7ee15955eb 100644
--- a/indra/newview/skins/default/xui/es/floater_buy_land.xml
+++ b/indra/newview/skins/default/xui/es/floater_buy_land.xml
@@ -75,15 +75,9 @@ incluyendo los objetos
Sólo pueden ser propietarios de terreno los miembros premium.
</text>
<combo_box name="account_level">
- <combo_item name="US$9.95/month,billedmonthly">
- 9.95 US$/mes, facturados mensualmente
- </combo_item>
- <combo_item name="US$7.50/month,billedquarterly">
- 7.50 US$/mes, facturados cuatrimestralmente
- </combo_item>
- <combo_item name="US$6.00/month,billedannually">
- 6.00 US$/mes, facturados anualmente
- </combo_item>
+ <combo_box.item name="US$9.95/month,billedmonthly" label="9.95 US$/mes, facturados mensualmente" />
+ <combo_box.item name="US$7.50/month,billedquarterly" label="7.50 US$/mes, facturados cuatrimestralmente" />
+ <combo_box.item name="US$6.00/month,billedannually" label="6.00 US$/mes, facturados anualmente" />
</combo_box>
<text name="land_use_action">
Aumenta su cuota mensual por uso de terreno a 40 US$/mes.
diff --git a/indra/newview/skins/default/xui/es/floater_customize.xml b/indra/newview/skins/default/xui/es/floater_customize.xml
index 58aea9a380..5efc989eff 100644
--- a/indra/newview/skins/default/xui/es/floater_customize.xml
+++ b/indra/newview/skins/default/xui/es/floater_customize.xml
@@ -14,12 +14,8 @@
<button label="Torso" label_selected="Torso" name="Torso"/>
<button label="Piernas" label_selected="Piernas" name="Legs"/>
<radio_group name="sex radio">
- <radio_item length="1" name="radio" type="string">
- Mujer
- </radio_item>
- <radio_item length="1" name="radio2" type="string">
- Varón
- </radio_item>
+ <radio_item length="1" name="radio" type="string" label="Mujer" />
+ <radio_item length="1" name="radio2" type="string" label="Varón" />
</radio_group>
<text length="1" name="title" type="string">
[DESC]
diff --git a/indra/newview/skins/default/xui/es/floater_god_tools.xml b/indra/newview/skins/default/xui/es/floater_god_tools.xml
index 583bc2607f..1ba0b685c6 100644
--- a/indra/newview/skins/default/xui/es/floater_god_tools.xml
+++ b/indra/newview/skins/default/xui/es/floater_god_tools.xml
@@ -114,29 +114,17 @@
Destino:
</text>
<combo_box name="destination">
- <combo_item name="Selection">
- Selección
- </combo_item>
- <combo_item name="AgentRegion">
- Agente de región
- </combo_item>
+ <combo_box.item name="Selection" label="Selección" />
+ <combo_box.item name="AgentRegion" label="Agente de región" />
</combo_box>
<text name="Request:">
Exigencia:
</text>
<combo_box name="request">
- <combo_item name="colliders&lt;steps&gt;">
- colisionadores &lt;pasos&gt;
- </combo_item>
- <combo_item name="scripts&lt;count&gt;,&lt;optionalpattern&gt;">
- scripts &lt;contar&gt;,&lt;patrón opcional&gt;
- </combo_item>
- <combo_item name="objects&lt;pattern&gt;">
- objetos &lt;patrón&gt;
- </combo_item>
- <combo_item name="rez&lt;asset_id&gt;">
- rez &lt;asset_id&gt;
- </combo_item>
+ <combo_box.item name="colliders&lt;steps&gt;" label="colisionadores &lt;pasos&gt;" />
+ <combo_box.item name="scripts&lt;count&gt;,&lt;optionalpattern&gt;" label="scripts &lt;contar&gt;,&lt;patrón opcional&gt;" />
+ <combo_box.item name="objects&lt;pattern&gt;" label="objetos &lt;patrón&gt;" />
+ <combo_box.item name="rez&lt;asset_id&gt;" label="rez &lt;asset_id&gt;" />
</combo_box>
<text name="Parameter:">
Parámetro:
diff --git a/indra/newview/skins/default/xui/es/floater_hardware_settings.xml b/indra/newview/skins/default/xui/es/floater_hardware_settings.xml
index c1149f34c5..29750ee737 100644
--- a/indra/newview/skins/default/xui/es/floater_hardware_settings.xml
+++ b/indra/newview/skins/default/xui/es/floater_hardware_settings.xml
@@ -8,21 +8,11 @@
Antialiasing:
</text>
<combo_box label="Antialiasing" name="fsaa" width="94">
- <combo_item name="FSAADisabled">
- Desactivado
- </combo_item>
- <combo_item name="2x">
- 2x
- </combo_item>
- <combo_item name="4x">
- 4x
- </combo_item>
- <combo_item name="8x">
- 8x
- </combo_item>
- <combo_item name="16x">
- 16x
- </combo_item>
+ <combo_box.item name="FSAADisabled" label="Desactivado"/>
+ <combo_box.item name="2x" label="2x"/>
+ <combo_box.item name="4x" label="4x"/>
+ <combo_box.item name="8x" label="8x"/>
+ <combo_box.item name="16x" label="16x"/>
</combo_box>
<spinner label="Gamma:" name="gamma"/>
<text name="(brightness, lower is brighter)">
diff --git a/indra/newview/skins/default/xui/es/floater_image_preview.xml b/indra/newview/skins/default/xui/es/floater_image_preview.xml
index 55d90da1b2..6d51a800b7 100644
--- a/indra/newview/skins/default/xui/es/floater_image_preview.xml
+++ b/indra/newview/skins/default/xui/es/floater_image_preview.xml
@@ -11,36 +11,16 @@
imagen como:
</text>
<combo_box label="Tipo de ropa" name="clothing_type_combo" left="100" width="186">
- <combo_item name="Image">
- Imagen
- </combo_item>
- <combo_item name="Hair">
- Pelo
- </combo_item>
- <combo_item name="FemaleHead">
- Cabeza de mujer
- </combo_item>
- <combo_item name="FemaleUpperBody">
- Mujer: parte superior del cuerpo
- </combo_item>
- <combo_item name="FemaleLowerBody">
- Mujer: parte inferior del cuerpo
- </combo_item>
- <combo_item name="MaleHead">
- Cabeza de varón
- </combo_item>
- <combo_item name="MaleUpperBody">
- Varón: parte superior del cuerpo
- </combo_item>
- <combo_item name="MaleLowerBody">
- Varón: parte inferior del cuerpo
- </combo_item>
- <combo_item name="Skirt">
- Falda
- </combo_item>
- <combo_item name="SculptedPrim">
- Prim sculpted
- </combo_item>
+ <combo_box.item name="Image" label="Imagen" />
+ <combo_box.item name="Hair" label="Pelo" />
+ <combo_box.item name="FemaleHead" label="Cabeza de mujer" />
+ <combo_box.item name="FemaleUpperBody" label="Mujer: parte superior del cuerpo" />
+ <combo_box.item name="FemaleLowerBody" label="Mujer: parte inferior del cuerpo" />
+ <combo_box.item name="MaleHead" label="Cabeza de varón" />
+ <combo_box.item name="MaleUpperBody" label="Varón: parte superior del cuerpo" />
+ <combo_box.item name="MaleLowerBody" label="Varón: parte inferior del cuerpo" />
+ <combo_box.item name="Skirt" label="Falda" />
+ <combo_box.item name="SculptedPrim" label="Prim sculpted"/>
</combo_box>
<text name="bad_image_text">
Imposible leer la imagen.
diff --git a/indra/newview/skins/default/xui/es/floater_inventory_item_properties.xml b/indra/newview/skins/default/xui/es/floater_inventory_item_properties.xml
index fc8dc4ecb0..4df3ca2cf6 100644
--- a/indra/newview/skins/default/xui/es/floater_inventory_item_properties.xml
+++ b/indra/newview/skins/default/xui/es/floater_inventory_item_properties.xml
@@ -60,12 +60,8 @@
</text>
<check_box label="En venta" name="CheckPurchase"/>
<radio_group name="RadioSaleType" left_delta="88" >
- <radio_item name="radio">
- Original
- </radio_item>
- <radio_item name="radio2">
- Copia
- </radio_item>
+ <radio_item name="radio" label="Original" />
+ <radio_item name="radio2" label="Copia" />
</radio_group>
<text name="TextPrice">
Precio: L$
diff --git a/indra/newview/skins/default/xui/es/floater_joystick.xml b/indra/newview/skins/default/xui/es/floater_joystick.xml
index 5009a31277..da7753a7d7 100644
--- a/indra/newview/skins/default/xui/es/floater_joystick.xml
+++ b/indra/newview/skins/default/xui/es/floater_joystick.xml
@@ -54,10 +54,10 @@
Zona muerta Z
</text>
<text name="PitchDeadZone" left="3" width="115">
- Zona muerta arriba/abajo
+ Zona muerta arri./aba.
</text>
<text name="YawDeadZone" left="3" width="115">
- Zona muerta izq./der
+ Zona muerta izq./der.
</text>
<text name="RollDeadZone">
Zona muerta giro
diff --git a/indra/newview/skins/default/xui/es/floater_postcard.xml b/indra/newview/skins/default/xui/es/floater_postcard.xml
index 315ea98c82..0ebf459cef 100644
--- a/indra/newview/skins/default/xui/es/floater_postcard.xml
+++ b/indra/newview/skins/default/xui/es/floater_postcard.xml
@@ -24,13 +24,13 @@
Escriba aquí el mensaje.
</text_editor>
<text name="fine_print" bottom_delta="-21">
- Si su destinatario se registra en Second Life,
+ Si su destinatario se registra en [SECOND_LIFE],
usted conseguirá un bono de referido.
</text>
<button label="Cancelar" name="cancel_btn"/>
<button label="Enviar" name="send_btn"/>
<string name="default_subject">
- Postal desde Second Life.
+ Postal desde [SECOND_LIFE]
</string>
<string name="default_message">
¡Mira esto!
diff --git a/indra/newview/skins/default/xui/es/floater_preview_gesture.xml b/indra/newview/skins/default/xui/es/floater_preview_gesture.xml
index 492c4f958a..0e43ce536c 100644
--- a/indra/newview/skins/default/xui/es/floater_preview_gesture.xml
+++ b/indra/newview/skins/default/xui/es/floater_preview_gesture.xml
@@ -46,12 +46,8 @@ a menos que añada pasos de espera.
</text>
<text left="230" name="options_text" width="200" />
<radio_group name="animation_trigger_type">
- <radio_item name="start">
- Empezar
- </radio_item>
- <radio_item name="stop">
- Parar
- </radio_item>
+ <radio_item name="start" label="Empezar" />
+ <radio_item name="stop" label="Parar" />
</radio_group>
<check_box bottom_delta="34" label="hasta que las animaciones &#10;estén hechas" name="wait_anim_check"/>
<check_box bottom_delta="-30" label="tiempo en segundos" name="wait_time_check"/>
diff --git a/indra/newview/skins/default/xui/es/floater_report_abuse.xml b/indra/newview/skins/default/xui/es/floater_report_abuse.xml
index 1d2b732d4d..caa0f2a748 100644
--- a/indra/newview/skins/default/xui/es/floater_report_abuse.xml
+++ b/indra/newview/skins/default/xui/es/floater_report_abuse.xml
@@ -37,123 +37,51 @@
Hendrerit Vulputate
</text>
<combo_box name="category_combo" tool_tip="Categoría -- Elija la categoría que describa mejor esta denuncia">
- <combo_item name="Select_category">
- Elegir la categoría
- </combo_item>
- <combo_item name="Age__Age_play">
- Edad &gt; Jugar a ser niño
- </combo_item>
- <combo_item name="Age__Adult_resident_on_Teen_Second_Life">
- Edad &gt; Residente adulto en Teen Second Life
- </combo_item>
+ <combo_box.item name="Select_category" label="Elegir la categoría"/>
+ <combo_box.item name="Age__Age_play" label="Edad &gt; Jugar a ser niño"/>
+ <combo_box.item name="Age__Adult_resident_on_Teen_Second_Life" label="Edad &gt; Residente adulto en Teen Second Life"/>
<combo_item name="Age__Underage_resident_outside_of_Teen_Second_Life">
Edad &gt; Residente menor de edad fuera de Teen Second Life
</combo_item>
- <combo_item name="Assault__Combat_sandbox___unsafe_area">
- Ataque &gt; Sandbox de combate / Zona no segura
- </combo_item>
- <combo_item name="Assault__Safe_area">
- Ataque &gt; Zona segura
- </combo_item>
- <combo_item name="Assault__Weapons_testing_sandbox">
- Ataque &gt; Sandbox de prueba de armas
- </combo_item>
- <combo_item name="Commerce__Failure_to_deliver_product_or_service">
- Comercio &gt; Error en la entrega de productos o servicios
- </combo_item>
- <combo_item name="Disclosure__Real_world_information">
- Indiscreción &gt; Información del mundo real
- </combo_item>
- <combo_item name="Disclosure__Remotely_monitoring chat">
- Indiscreción &gt; Monitorizar a distancia el chat
- </combo_item>
- <combo_item name="Disclosure__Second_Life_information_chat_IMs">
- Indiscreción &gt; Información Se Second Life, el chat o los MI
- </combo_item>
- <combo_item name="Disturbing_the_peace__Unfair_use_of_region_resources">
- Perturbando la paz &gt; Abuso de los recursos de la región
- </combo_item>
- <combo_item name="Disturbing_the_peace__Excessive_scripted_objects">
- Perturbando la paz &gt; Excesivos objetos con script
- </combo_item>
- <combo_item name="Disturbing_the_peace__Object_littering">
- Perturbando la paz &gt; Objeto basura
- </combo_item>
- <combo_item name="Disturbing_the_peace__Repetitive_spam">
- Perturbando la paz &gt; Spam (mensajes no pedidos) repetitivo
- </combo_item>
- <combo_item name="Disturbing_the_peace__Unwanted_advert_spam">
- Perturbando la paz &gt; Publicidad no deseada
- </combo_item>
- <combo_item name="Fraud__L$">
- Fraude &gt; L$
- </combo_item>
- <combo_item name="Fraud__Land">
- Fraude &gt; Terreno
- </combo_item>
- <combo_item name="Fraud__Pyramid_scheme_or_chain_letter">
- Fraude &gt; Esquemas piramidales o cadenas de cartas
- </combo_item>
- <combo_item name="Fraud__US$">
- Fraude &gt; US$
- </combo_item>
- <combo_item name="Harassment__Advert_farms___visual_spam">
- Acoso &gt; Anuncios múltiples / Spam visual
- </combo_item>
- <combo_item name="Harassment__Defaming_individuals_or_groups">
- Acoso &gt; Difamación de individuos o grupos
- </combo_item>
- <combo_item name="Harassment__Impeding_movement">
- Acoso &gt; Impedir el movimiento
- </combo_item>
- <combo_item name="Harassment__Sexual_harassment">
- Acoso &gt; Acoso sexual
- </combo_item>
- <combo_item name="Harassment__Solicting_inciting_others_to_violate_ToS">
- Acoso &gt; Incitar a, o pedir, que otros violen las Condiciones del Servicio
- </combo_item>
- <combo_item name="Harassment__Verbal_abuse">
- Acoso &gt; Abuso verbal
- </combo_item>
- <combo_item name="Indecency__Broadly_offensive_content_or_conduct">
- Indecencia &gt; En general, contenido o conducta ofensivos
- </combo_item>
- <combo_item name="Indecency__Inappropriate_avatar_name">
- Indecencia &gt; Nombre inapropiado del avatar
- </combo_item>
+ <combo_box.item name="Assault__Combat_sandbox___unsafe_area" label="Ataque &gt; Sandbox de combate / Zona no segura"/>
+ <combo_box.item name="Assault__Safe_area" label="Ataque &gt; Zona segura"/>
+ <combo_box.item name="Assault__Weapons_testing_sandbox" label="Ataque &gt; Sandbox de prueba de armas"/>
+ <combo_box.item name="Commerce__Failure_to_deliver_product_or_service" label="Comercio &gt; Error en la entrega de productos o servicios"/>
+ <combo_box.item name="Disclosure__Real_world_information" label="Indiscreción &gt; Información del mundo real"/>
+ <combo_box.item name="Disclosure__Remotely_monitoring chat" label="Indiscreción &gt; Monitorizar a distancia el chat"/>
+ <combo_box.item name="Disclosure__Second_Life_information_chat_IMs" label="Indiscreción &gt; Información Se Second Life, el chat o los MI"/>
+ <combo_box.item name="Disturbing_the_peace__Unfair_use_of_region_resources" label="Perturbando la paz &gt; Abuso de los recursos de la región"/>
+ <combo_box.item name="Disturbing_the_peace__Excessive_scripted_objects" label="Perturbando la paz &gt; Excesivos objetos con script"/>
+ <combo_box.item name="Disturbing_the_peace__Object_littering" label="Perturbando la paz &gt; Objeto basura"/>
+ <combo_box.item name="Disturbing_the_peace__Repetitive_spam" label="Perturbando la paz &gt; Spam (mensajes no pedidos) repetitivo"/>
+ <combo_box.item name="Disturbing_the_peace__Unwanted_advert_spam" label="Perturbando la paz &gt; Publicidad no deseada"/>
+ <combo_box.item name="Fraud__L$" label="Fraude &gt; L$"/>
+ <combo_box.item name="Fraud__Land" label="Fraude &gt; Terreno"/>
+ <combo_box.item name="Fraud__Pyramid_scheme_or_chain_letter" label="Fraude &gt; Esquemas piramidales o cadenas de cartas"/>
+ <combo_box.item name="Fraud__US$" label="Fraude &gt; US$"/>
+ <combo_box.item name="Harassment__Advert_farms___visual_spam" label="Acoso &gt; Anuncios múltiples / Spam visual"/>
+ <combo_box.item name="Harassment__Defaming_individuals_or_groups" label="Acoso &gt; Difamación de individuos o grupos"/>
+ <combo_box.item name="Harassment__Impeding_movement" label="Acoso &gt; Impedir el movimiento"/>
+ <combo_box.item name="Harassment__Sexual_harassment" label="Acoso &gt; Acoso sexual"/>
+ <combo_box.item name="Harassment__Solicting_inciting_others_to_violate_ToS" label="Acoso &gt; Incitar a, o pedir, que otros violen las Condiciones del Servicio"/>
+ <combo_box.item name="Harassment__Verbal_abuse" label="Acoso &gt; Abuso verbal"/>
+ <combo_box.item name="Indecency__Broadly_offensive_content_or_conduct" label="Indecencia &gt; En general, contenido o conducta ofensivos"/>
+ <combo_box.item name="Indecency__Inappropriate_avatar_name" label="Indecencia &gt; Nombre inapropiado del avatar"/>
<combo_item name="Indecency__Mature_content_in_PG_region">
Indecencia &gt; Contenido o conducta inapropiada en una región &apos;PG&apos;
</combo_item>
<combo_item name="Indecency__Inappropriate_content_in_Mature_region">
Indecencia &gt; Contenido o conducta inapropiada en una región &apos;Mature&apos;
</combo_item>
- <combo_item name="Intellectual_property_infringement_Content_Removal">
- Infracción de la propiedad intelectual &gt; Eliminación de contenidos
- </combo_item>
- <combo_item name="Intellectual_property_infringement_CopyBot_or_Permissions_Exploit">
- Infracción de la propiedad intelectual &gt; CopyBot o Exploit (programa malicioso) de permisos
- </combo_item>
- <combo_item name="Intolerance">
- Intolerancia
- </combo_item>
- <combo_item name="Land__Abuse_of_sandbox_resources">
- Terreno &gt; Abuso de los recursos de un sandbox
- </combo_item>
- <combo_item name="Land__Encroachment__Objects_textures">
- Terreno &gt; Invasión &gt; Objetos/Texturas
- </combo_item>
- <combo_item name="Land__Encroachment__Particles">
- Terreno &gt; Invasión &gt; Partículas
- </combo_item>
- <combo_item name="Land__Encroachment__Trees_plants">
- Terreno &gt; Invasión &gt; Ãrboles/Plantas
- </combo_item>
- <combo_item name="Wagering_gambling">
- Apuestas/Juego
- </combo_item>
- <combo_item name="Other">
- Otra
- </combo_item>
+ <combo_box.item name="Intellectual_property_infringement_Content_Removal" label="Infracción de la propiedad intelectual &gt; Eliminación de contenidos"/>
+ <combo_box.item name="Intellectual_property_infringement_CopyBot_or_Permissions_Exploit" label="Infracción de la propiedad intelectual &gt; CopyBot o Exploit (programa malicioso) de permisos"/>
+ <combo_box.item name="Intolerance" label="Intolerancia"/>
+ <combo_box.item name="Land__Abuse_of_sandbox_resources" label="Terreno &gt; Abuso de los recursos de un sandbox"/>
+ <combo_box.item name="Land__Encroachment__Objects_textures" label="Terreno &gt; Invasión &gt; Objetos/Texturas"/>
+ <combo_box.item name="Land__Encroachment__Particles" label="Terreno &gt; Invasión &gt; Partículas"/>
+ <combo_box.item name="Land__Encroachment__Trees_plants" label="Terreno &gt; Invasión &gt; Ãrboles/Plantas"/>
+ <combo_box.item name="Wagering_gambling" label="Apuestas/Juego"/>
+ <combo_box.item name="Other" label="Otra"/>
</combo_box>
<text name="abuser_name_title">
Nombre del infractor:
diff --git a/indra/newview/skins/default/xui/es/floater_sell_land.xml b/indra/newview/skins/default/xui/es/floater_sell_land.xml
index 26aa56f22b..6d1122a771 100644
--- a/indra/newview/skins/default/xui/es/floater_sell_land.xml
+++ b/indra/newview/skins/default/xui/es/floater_sell_land.xml
@@ -35,15 +35,9 @@
Elija si venderlo a cualquiera o a un comprador concreto.
</text>
<combo_box name="sell_to">
- <combo_item name="--selectone--">
- -- seleccione --
- </combo_item>
- <combo_item name="Anyone">
- Cualquiera
- </combo_item>
- <combo_item name="Specificuser:">
- Un usuario concreto:
- </combo_item>
+ <combo_box.item name="--selectone--" label="seleccione --" />
+ <combo_box.item name="Anyone" label="Cualquiera" />
+ <combo_box.item name="Specificuser:" label="Un usuario concreto:" />
</combo_box>
<button label="Seleccionar..." name="sell_to_select_agent"/>
<text name="sell_objects_label">
@@ -54,12 +48,8 @@
de propietario.
</text>
<radio_group name="sell_objects" bottom_delta="-58" >
- <radio_item name="no">
- No, mantener la propiedad de los objetos
- </radio_item>
- <radio_item name="yes">
- Sí, vender los objetos con el terreno
- </radio_item>
+ <radio_item name="no" label="No, mantener la propiedad de los objetos" />
+ <radio_item name="yes" label="Sí, vender los objetos con el terreno" />
</radio_group>
<button label="Mostrar los objetos" name="show_objects" width="120"/>
<text name="nag_message_label">
diff --git a/indra/newview/skins/default/xui/es/floater_settings_debug.xml b/indra/newview/skins/default/xui/es/floater_settings_debug.xml
index e5c652711e..1d5ad2f34c 100644
--- a/indra/newview/skins/default/xui/es/floater_settings_debug.xml
+++ b/indra/newview/skins/default/xui/es/floater_settings_debug.xml
@@ -1,12 +1,8 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<floater name="settings_debug" title="Configuración del depurador">
<combo_box name="boolean_combo">
- <combo_item name="TRUE">
- VERDADERO
- </combo_item>
- <combo_item name="FALSE">
- FALSO
- </combo_item>
+ <combo_box.item name="TRUE" label="TRUE" />
+ <combo_box.item name="FALSE" label="FALSE" />
</combo_box>
<color_swatch label="Color" name="color_swatch"/>
<spinner label="x" name="val_spinner_1"/>
diff --git a/indra/newview/skins/default/xui/es/floater_snapshot.xml b/indra/newview/skins/default/xui/es/floater_snapshot.xml
index 1ea3327d96..c1ace23503 100644
--- a/indra/newview/skins/default/xui/es/floater_snapshot.xml
+++ b/indra/newview/skins/default/xui/es/floater_snapshot.xml
@@ -4,15 +4,9 @@
Destino de la foto
</text>
<radio_group label="Tipo de la foto" name="snapshot_type_radio">
- <radio_item name="postcard">
- Enviar por correo electrónico
- </radio_item>
- <radio_item name="texture">
- Guardarla en su inventario ([AMOUNT] L$)
- </radio_item>
- <radio_item name="local">
- Guardarla en su disco duro
- </radio_item>
+ <radio_item name="postcard" label="Enviar por correo electrónico" />
+ <radio_item name="texture" label="Guardarla en su inventario ([AMOUNT] L$)" />
+ <radio_item name="local" label="Guardarla en su disco duro" />
</radio_group>
<text name="file_size_label">
Tamaño del archivo: [SIZE] KB
@@ -21,12 +15,8 @@
<button label="Enviar" name="send_btn"/>
<button label="Guardar ([AMOUNT] L$)" name="upload_btn"/>
<flyout_button label="Guardar" name="save_btn" tool_tip="Guardar la imagen en un archivo">
- <flyout_button_item name="save_item">
- Guardar
- </flyout_button_item>
- <flyout_button_item name="saveas_item">
- Guardar como...
- </flyout_button_item>
+ <flyout_button_item name="save_item" label="Guardar"/>
+ <flyout_button_item name="saveas_item" label="Guardar como..."/>
</flyout_button>
<button label="Cancelar" name="discard_btn"/>
<button label="Más &gt;&gt;" name="more_btn" tool_tip="Opciones avanzadas"/>
@@ -38,75 +28,33 @@
Formato
</text>
<combo_box label="Resolución" name="postcard_size_combo">
- <combo_item name="CurrentWindow">
- Ventana actual
- </combo_item>
- <combo_item name="640x480">
- 640x480
- </combo_item>
- <combo_item name="800x600">
- 800x600
- </combo_item>
- <combo_item name="1024x768">
- 1024x768
- </combo_item>
- <combo_item name="Custom">
- Personalizar
- </combo_item>
+ <combo_box.item name="CurrentWindow" label="Ventana actual"/>
+ <combo_box.item name="640x480" label="640x480"/>
+ <combo_box.item name="800x600" label="800x600"/>
+ <combo_box.item name="1024x768" label="1024x768"/>
+ <combo_box.item name="Custom" label="Personalizar"/>
</combo_box>
<combo_box label="Resolución" name="texture_size_combo">
- <combo_item name="CurrentWindow">
- Ventana actual
- </combo_item>
- <combo_item name="Small(128x128)">
- Pequeño (128x128)
- </combo_item>
- <combo_item name="Medium(256x256)">
- Medio (256x256)
- </combo_item>
- <combo_item name="Large(512x512)">
- Grande (512x512)
- </combo_item>
- <combo_item name="Custom">
- Personalizar
- </combo_item>
+ <combo_box.item name="CurrentWindow" label="Ventana actual"/>
+ <combo_box.item name="Small(128x128)" label="Pequeño (128x128)"/>
+ <combo_box.item name="Medium(256x256)" label="Medio (256x256)"/>
+ <combo_box.item name="Large(512x512)" label="Grande (512x512)"/>
+ <combo_box.item name="Custom" label="Personalizar"/>
</combo_box>
<combo_box label="Resolución" name="local_size_combo">
- <combo_item name="CurrentWindow">
- Ventana actual
- </combo_item>
- <combo_item name="320x240">
- 320x240
- </combo_item>
- <combo_item name="640x480">
- 640x480
- </combo_item>
- <combo_item name="800x600">
- 800x600
- </combo_item>
- <combo_item name="1024x768">
- 1024x768
- </combo_item>
- <combo_item name="1280x1024">
- 1280x1024
- </combo_item>
- <combo_item name="1600x1200">
- 1600x1200
- </combo_item>
- <combo_item name="Custom">
- Personalizar
- </combo_item>
+ <combo_box.item name="CurrentWindow" label="Ventana actual"/>
+ <combo_box.item name="320x240" label="320x240"/>
+ <combo_box.item name="640x480" label="640x480"/>
+ <combo_box.item name="800x600" label="800x600"/>
+ <combo_box.item name="1024x768" label="1024x768"/>
+ <combo_box.item name="1280x1024" label="1280x1024"/>
+ <combo_box.item name="1600x1200" label="1600x1200"/>
+ <combo_box.item name="Custom" label="Personalizar"/>
</combo_box>
<combo_box label="Formato" name="local_format_combo">
- <combo_item name="PNG">
- PNG
- </combo_item>
- <combo_item name="JPEG">
- JPEG
- </combo_item>
- <combo_item name="BMP">
- BMP
- </combo_item>
+ <combo_box.item name="PNG" label="PNG"/>
+ <combo_box.item name="JPEG" label="JPEG"/>
+ <combo_box.item name="BMP" label="BMP"/>
</combo_box>
<spinner label="Ancho" name="snapshot_width" label_width="41" width="101"/>
<spinner label="Alto" name="snapshot_height" label_width="30" width="90" left="121"/>
@@ -116,15 +64,9 @@
Captura:
</text>
<combo_box label="Capas de la imagen" name="layer_types">
- <combo_item name="Colors">
- Colores
- </combo_item>
- <combo_item name="Depth">
- Profundidad
- </combo_item>
- <combo_item name="ObjectMattes">
- Bandas negras
- </combo_item>
+ <combo_box.item name="Colors" label="Colores"/>
+ <combo_box.item name="Depth" label="Profundidad"/>
+ <combo_box.item name="ObjectMattes" label="Bandas negras"/>
</combo_box>
<check_box label="Incluir la interfaz en la foto" name="ui_check"/>
<check_box bottom_delta="-17" label="Incluir los HUD en la foto" name="hud_check"/>
diff --git a/indra/newview/skins/default/xui/es/floater_tos.xml b/indra/newview/skins/default/xui/es/floater_tos.xml
index e6975e8994..d46c84cb03 100644
--- a/indra/newview/skins/default/xui/es/floater_tos.xml
+++ b/indra/newview/skins/default/xui/es/floater_tos.xml
@@ -5,7 +5,7 @@
<check_box label="Estoy de acuerdo con las Condiciones del Servicio" name="agree_chk"/>
<text name="tos_heading">
Por favor, lea cuidadosamente las siguientes Condiciones del Servicio. Si quiere seguir
-iniciando sesión en Second Life, debe aceptar el acuerdo.
+iniciando sesión en [SECOND_LIFE], debe aceptar el acuerdo.
</text>
<text_editor name="tos_text">
TOS_TEXT
diff --git a/indra/newview/skins/default/xui/es/floater_world_map.xml b/indra/newview/skins/default/xui/es/floater_world_map.xml
index aad417790f..3bfae282cb 100644
--- a/indra/newview/skins/default/xui/es/floater_world_map.xml
+++ b/indra/newview/skins/default/xui/es/floater_world_map.xml
@@ -28,14 +28,10 @@
<check_box label="&apos;Mature&apos;" name="event_mature_chk"/>
<check_box label="&apos;Adult&apos;" name="event_adult_chk"/>
<combo_box label="Amigos conectados" name="friend combo" tool_tip="Amigo a mostrar en el mapa">
- <combo_item name="none_selected">
- Amigos conectados
- </combo_item>
+ <combo_box.item name="none_selected" label="Amigos conectados" />
</combo_box>
<combo_box label="Hitos" name="landmark combo" tool_tip="Hito a mostrar en el mapa">
- <combo_item name="none_selected">
- Hitos
- </combo_item>
+ <combo_box.item name="none_selected" label="Hitos" />
</combo_box>
<line_editor label="Buscar por el nombre de la región" name="location" tool_tip="Escriba el nombre de una región"/>
<button label="Buscar" name="DoSearch" tool_tip="Buscar una región"/>
diff --git a/indra/newview/skins/default/xui/es/language_settings.xml b/indra/newview/skins/default/xui/es/language_settings.xml
new file mode 100644
index 0000000000..71418d446a
--- /dev/null
+++ b/indra/newview/skins/default/xui/es/language_settings.xml
@@ -0,0 +1,55 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<!-- This file contains strings that used to be hardcoded in the source.-->
+<strings>
+
+ <!-- Locale Information -->
+ <string name="MicrosoftLocale">english</string>
+ <string name="DarwinLocale">C</string>
+ <string name="LinuxLocale">C</string>
+
+ <!--
+ datetimeToCodes["wkday"] = "%a"; // Thu
+ datetimeToCodes["weekday"] = "%A"; // Thursday
+ datetimeToCodes["year4"] = "%Y"; // 2009
+ datetimeToCodes["year"] = "%Y"; // 2009
+ datetimeToCodes["year2"] = "%y"; // 09
+ datetimeToCodes["mth"] = "%b"; // Aug
+ datetimeToCodes["month"] = "%B"; // August
+ datetimeToCodes["mthnum"] = "%m"; // 08
+ datetimeToCodes["day"] = "%d"; // 31
+ datetimeToCodes["hour24"] = "%H"; // 14
+ datetimeToCodes["hour"] = "%H"; // 14
+ datetimeToCodes["hour12"] = "%I"; // 02
+ datetimeToCodes["min"] = "%M"; // 59
+ datetimeToCodes["ampm"] = "%p"; // AM
+ datetimeToCodes["second"] = "%S"; // 59
+ datetimeToCodes["timezone"] = "%Z"; // PST
+ -->
+
+ <string name="TimeHour">hour,datetime,slt</string>
+ <string name="TimeMin">min,datetime,slt</string>
+ <string name="TimeYear">year,datetime,slt</string>
+ <string name="TimeDay">day,datetime,slt</string>
+ <string name="TimeMonth">mthnum,datetime,slt</string>
+ <string name="TimeWeek">wkday,datetime,slt</string>
+ <string name="TimeAMPM">ampm,datetime,slt</string>
+ <string name="TimeHour12">hour12,datetime,slt</string>
+
+ <string name="LTimeMthNum">mthnum,datetime,local</string>
+ <string name="LTimeWeek">wkday,datetime,local</string>
+ <string name="LTimeMonth">mth,datetime,local</string>
+ <string name="LTimeDay">day,datetime,local</string>
+ <string name="LTimeSec">second,datetime,local</string>
+ <string name="LTimeHour">hour,datetime,local</string>
+ <string name="LTimeMin">min,datetime,local</string>
+ <string name="LTimeYear">year,datetime,local</string>
+
+ <string name="UTCTimeWeek">weekday,datetime,utc</string>
+ <string name="UTCTimeDay">day,datetime,utc</string>
+ <string name="UTCTimeMth">mth,datetime,utc</string>
+ <string name="UTCTimeYr">year,datetime,utc</string>
+ <string name="UTCTimeHr">hour,datetime,utc</string>
+ <string name="UTCTimeMin">min,datetime,utc</string>
+ <string name="UTCTimeSec">second,datetime,utc</string>
+ <string name="UTCTimeTimezone">timezone,datetime,utc</string>
+</strings>
diff --git a/indra/newview/skins/default/xui/es/menu_inventory.xml b/indra/newview/skins/default/xui/es/menu_inventory.xml
index 557123d4f8..28d47fce52 100644
--- a/indra/newview/skins/default/xui/es/menu_inventory.xml
+++ b/indra/newview/skins/default/xui/es/menu_inventory.xml
@@ -12,7 +12,7 @@
<menu_item_call label="Script nuevo" name="New Script"/>
<menu_item_call label="Nota nueva" name="New Note"/>
<menu_item_call label="Gesto nuevo" name="New Gesture"/>
- <menu name="New Clothes">
+ <menu name="New Clothes" label="Nueva ropa">
<menu_item_call label="Camisa nueva" name="New Shirt"/>
<menu_item_call label="Pantalones nuevos" name="New Pants"/>
<menu_item_call label="Zapatos nuevos" name="New Shoes"/>
@@ -23,7 +23,7 @@
<menu_item_call label="Camiseta nueva" name="New Undershirt"/>
<menu_item_call label="Ropa interior nueva" name="New Underpants"/>
</menu>
- <menu name="New Body Parts">
+ <menu name="New Body Parts" label="Nuevas partes del cuerpo">
<menu_item_call label="Forma nueva" name="New Shape"/>
<menu_item_call label="Piel nueva" name="New Skin"/>
<menu_item_call label="Pelo nuevo" name="New Hair"/>
diff --git a/indra/newview/skins/default/xui/es/menu_login.xml b/indra/newview/skins/default/xui/es/menu_login.xml
index a60e41d896..1cf6ad5ae6 100644
--- a/indra/newview/skins/default/xui/es/menu_login.xml
+++ b/indra/newview/skins/default/xui/es/menu_login.xml
@@ -7,7 +7,7 @@
<menu_item_call label="Preferencias..." name="Preferences..."/>
</menu>
<menu label="Ayuda" name="Help">
- <menu_item_call label="Ayuda de Second Life" name="Second Life Help"/>
- <menu_item_call label="Acerca de Second Life..." name="About Second Life..."/>
+ <menu_item_call label="Ayuda de [SECOND_LIFE]" name="Second Life Help"/>
+ <menu_item_call label="Acerca de [APP_NAME]..." name="About Second Life..."/>
</menu>
</menu_bar>
diff --git a/indra/newview/skins/default/xui/es/menu_viewer.xml b/indra/newview/skins/default/xui/es/menu_viewer.xml
index 4a7ac4e175..33754f3935 100644
--- a/indra/newview/skins/default/xui/es/menu_viewer.xml
+++ b/indra/newview/skins/default/xui/es/menu_viewer.xml
@@ -185,7 +185,7 @@
<menu_item_call label="Definir los scripts a no ejecutar en lo seleccionado" name="Set Scripts to Not Running in Selection"/>
</menu>
<menu label="Ayuda" name="Help">
- <menu_item_call label="Ayuda de Second Life" name="Second Life Help"/>
+ <menu_item_call label="Ayuda de [SECOND_LIFE]" name="Second Life Help"/>
<menu_item_call label="Tutorial" name="Tutorial"/>
<menu_item_separator label="-----------" name="separator"/>
<menu_item_call label="Blog oficial..." name="Official Linden Blog..."/>
@@ -206,6 +206,6 @@
<menu_item_separator label="-----------" name="separator9"/>
<menu_item_call label="Informar de un fallo..." name="Report Bug..."/>
</menu>
- <menu_item_call label="Acerca de Second Life..." name="About Second Life..."/>
+ <menu_item_call label="Acerca de [APP_NAME]..." name="About Second Life..."/>
</menu>
</menu_bar>
diff --git a/indra/newview/skins/default/xui/es/notifications.xml b/indra/newview/skins/default/xui/es/notifications.xml
index 9bbbc6c47f..5778e48fcf 100644
--- a/indra/newview/skins/default/xui/es/notifications.xml
+++ b/indra/newview/skins/default/xui/es/notifications.xml
@@ -6,6 +6,9 @@
<global name="alwayschoose">
Elegir siempre esta opción
</global>
+ <global name="implicitclosebutton">
+ Cerrar
+ </global>
<template name="okbutton">
<form>
<button
@@ -71,7 +74,7 @@
</form>
</template>
<notification functor="GenericAcknowledge" label="Mensaje de alerta desconocida" name="MissingAlert">
- Su versión de Second Life no sabe cómo mostrar el mensaje de alerta que acaba de recibir.
+ Su versión de [APP_NAME] no sabe cómo mostrar el mensaje de alerta que acaba de recibir.
Detalles del error: no se ha encontrado en notifications.xml la alerta llamada &apos;[_NAME]&apos;.
<usetemplate name="okbutton" yestext="OK"/>
@@ -94,7 +97,7 @@ Detalles del error: no se ha encontrado en notifications.xml la alerta llamada &
<usetemplate name="okcancelbuttons" notext="Cancelar" yestext="Sí"/>
</notification>
<notification name="BadInstallation">
- Ha habido un error al actualizar Second Life. Por favor, descargue la última versión desde secondlife.com.
+ Ha habido un error al actualizar [APP_NAME]. Por favor, descargue la última versión desde secondlife.com.
<usetemplate
name="okbutton"
yestext="OK"/>
@@ -226,7 +229,7 @@ Marcando este ítem, se mostrará:
<notification name="ClickPartnerHelpAvatar">
Puede proponérselo a otro residente o disolver su relación con un/a compañero/a en el sitio web de [SECOND_LIFE].
-¿Ir al sitio web de Second Life para tener más información sobre este asunto?
+¿Ir al sitio web de [SECOND_LIFE] para tener más información sobre este asunto?
<usetemplate name="okcancelbuttons" notext="Cancelar" yestext="Ir a la página"/>
</notification>
<notification name="ClickUploadHelpPermissions">
@@ -264,7 +267,7 @@ Su precio de venta será de [SALE_PRICE] L$, y se autorizará la compra sólo a
<usetemplate name="okcancelbuttons" notext="Cancelar" yestext="OK"/>
</notification>
<notification name="ConfirmLandSaleToAnyoneChange">
- ATENCIÓN: Al pulsar &apos;vender a cualquiera&apos;, su terreno estará disponible para toda la comunidad de Second Life, incluso para quienes no están en esta región.
+ ATENCIÓN: Al pulsar &apos;vender a cualquiera&apos;, su terreno estará disponible para toda la comunidad de [SECOND_LIFE], incluso para quienes no están en esta región.
Los [LAND_SIZE] m² de terreno seleccionados se van a poner a la venta.
Su precio de venta será de [SALE_PRICE] L$, y se autorizará la compra a [NAME].
@@ -412,17 +415,17 @@ No se reembolsan las cuotas pagadas.
<usetemplate name="okcancelbuttons" notext="Cancelar" yestext="OK"/>
</notification>
<notification name="CacheWillClear">
- La caché se limpiará cuando reinicie [SECOND_LIFE].
+ La caché se limpiará cuando reinicie [APP_NAME].
</notification>
<notification name="CacheWillBeMoved">
- La caché se moverá cuando reinicie [SECOND_LIFE].
+ La caché se moverá cuando reinicie [APP_NAME].
Nota: esto limpiará la caché.
</notification>
<notification name="ChangeConnectionPort">
- Las configuraciones del puerto tendrán efecto cuando reinicie [SECOND_LIFE].
+ Las configuraciones del puerto tendrán efecto cuando reinicie [APP_NAME].
</notification>
<notification name="ChangeSkin">
- La nueva apariencia se verá cuando reinicie [SECOND_LIFE].
+ La nueva apariencia se verá cuando reinicie [APP_NAME].
</notification>
<notification name="GoToAuctionPage">
¿Ir a la página web de [SECOND_LIFE] para ver los detalles de la subasta
@@ -482,7 +485,7 @@ El objeto debe de haber sido borrado o estar fuera de rango (&apos;out of range&
No se ha podido escribir el archivo [[FILE]]
</notification>
<notification name="UnsupportedHardware">
- Atención: su sistema no tiene los requerimientos mínimos que necesita Second Life. Si sigue usando Second Life, tendrá un funcionamiento pobre. Desafortunadamente, no podemos ofrecer soporte técnico para configuraciones inadecuadas del sistema.
+ Atención: su sistema no tiene los requerimientos mínimos que necesita [APP_NAME]. Si sigue usando [APP_NAME], tendrá un funcionamiento pobre. Desafortunadamente, no podemos ofrecer soporte técnico para configuraciones inadecuadas del sistema.
MINSPECS
Para más información, ¿quiere visitar [_URL]?
@@ -494,14 +497,14 @@ Para más información, ¿quiere visitar [_URL]?
<notification name="UnknownGPU">
En este momento, desconocemos la tarjeta gráfica de su sistema.
Con frecuencia, esto se debe a hardware nuevo que no hemos podido revisar aún.
-Es muy probable que Second Life funcione correctamente, pero deberá ajustar sus configuraciones gráficas a lo que sea más apropiado.
+Es muy probable que [APP_NAME] funcione correctamente, pero deberá ajustar sus configuraciones gráficas a lo que sea más apropiado.
(Menú Editar &gt; Preferencias &gt; Gráficos).
<form name="form">
<ignore name="ignore" text="Cuando se detecte una tarjeta gráfica desconocida"/>
</form>
</notification>
<notification name="DisplaySettingsNoShaders">
- [SECOND_LIFE] se cayó al inicializar los drivers gráficos.
+ [APP_NAME] se cayó al inicializar los drivers gráficos.
La calidad de los gráficos deberá establecerse en un nivel bajo para prevenir algunos errores frecuentes en los drivers.
Esto desactivará algunas opciones gráficas.
Le recomendamos que actualice los drivers de su tarjeta gráfica.
@@ -792,7 +795,7 @@ no se ha seleccionado una parcela.
no se ha podido encontrar en qué región está.
</notification>
<notification name="CannotCloseFloaterBuyLand">
- No puede cerrar la ventana de Comprar terreno hasta que Second Life calcule el precio de esta transacción.
+ No puede cerrar la ventana de Comprar terreno hasta que [APP_NAME] calcule el precio de esta transacción.
</notification>
<notification name="CannotDeedLandNothingSelected">
No se ha podido transferir el terreno:
@@ -963,7 +966,7 @@ Si persiste el problema, por favor, pulse en en el menú &apos;Herramientas &gt;
<notification name="YouHaveBeenLoggedOut">
Se ha cerrado su sesión en [SECOND_LIFE]:
[MESSAGE]
-Aún puede ver el chat y los MI existentes pulsando &apos;Ver MI y Chat&apos;. Si no, pulse &apos;Salir&apos; para dejar inmediatemente [SECOND_LIFE].
+Aún puede ver el chat y los MI existentes pulsando &apos;Ver MI y Chat&apos;. Si no, pulse &apos;Salir&apos; para dejar inmediatemente [APP_NAME].
<usetemplate name="okcancelbuttons" notext="Salir" yestext="Ver MI y Chat"/>
</notification>
<notification name="OnlyOfficerCanBuyLand">
@@ -1135,14 +1138,14 @@ Puede usar normalmente [SECOND_LIFE], los demás residentes le verán correctame
</form>
</notification>
<notification name="FirstRun">
- Se ha completado la instalación de [SECOND_LIFE].
+ Se ha completado la instalación de [APP_NAME].
Si esta es la primera vez que usa [SECOND_LIFE], deberá crear una cuenta antes de que pueda iniciar una sesión.
¿Volver a www.secondlife.com para crear una cuenta nueva?
<usetemplate name="okcancelbuttons" notext="Continuar" yestext="Cuenta nueva..."/>
</notification>
<notification name="LoginPacketNeverReceived">
- Tenemos problemas de conexión. Puede deberse a un problema de su conexión a internet o de los servidores de Second Life.
+ Tenemos problemas de conexión. Puede deberse a un problema de su conexión a internet o de los servidores de [SECOND_LIFE].
Puede revisar su conexión a internet y volver a intentarlo en unos minutos. Pulse Ayuda para conectarse a nuestro sitio de Sporte, o pulse Teleportar para intentar teleportarse a su Base.
<form name="form">
@@ -1246,33 +1249,33 @@ Por favor, ponga en venta el objeto y reinténtelo.
[DOWNLOAD_PATH].
</notification>
<notification name="DownloadWindowsMandatory">
- Está disponible una versión nueva de [SECOND_LIFE].
+ Está disponible una versión nueva de [APP_NAME].
[MESSAGE]
-Debe descargar esta actualización para usar [SECOND_LIFE].
+Debe descargar esta actualización para usar [APP_NAME].
<usetemplate name="okcancelbuttons" notext="Salir" yestext="Descargarla"/>
</notification>
<notification name="DownloadWindows">
- Está disponible una versión actualizada de [SECOND_LIFE].
+ Está disponible una versión actualizada de [APP_NAME].
[MESSAGE]
Esta actualización no es obligatoria, pero le sugerimos instalarla para mejorar el rendimiento y la estabilidad.
<usetemplate name="okcancelbuttons" notext="Continuar" yestext="Descargarla"/>
</notification>
<notification name="DownloadWindowsReleaseForDownload">
- Está disponible una versión actualizada de [SECOND_LIFE].
+ Está disponible una versión actualizada de [APP_NAME].
[MESSAGE]
Esta actualización no es obligatoria, pero le sugerimos instalarla para mejorar el rendimiento y la estabilidad.
<usetemplate name="okcancelbuttons" notext="Continuar" yestext="Descargarla"/>
</notification>
<notification name="DownloadMacMandatory">
- Está disponible una versión nueva de [SECOND_LIFE].
+ Está disponible una versión nueva de [APP_NAME].
[MESSAGE]
-Debe descargar esta actualización para usar [SECOND_LIFE].
+Debe descargar esta actualización para usar [APP_NAME].
¿Descargarla a su carpeta de aplicaciones?
<usetemplate name="okcancelbuttons" notext="Salir" yestext="Descargarla"/>
</notification>
<notification name="DownloadMac">
- Está disponible una versión actualizada de [SECOND_LIFE].
+ Está disponible una versión actualizada de [APP_NAME].
[MESSAGE]
Esta actualización no es obligatoria, pero le sugerimos instalarla para mejorar el rendimiento y la estabilidad.
@@ -1280,7 +1283,7 @@ Esta actualización no es obligatoria, pero le sugerimos instalarla para mejorar
<usetemplate name="okcancelbuttons" notext="Continuar" yestext="Descargarla"/>
</notification>
<notification name="DownloadMacReleaseForDownload">
- Está disponible una versión actualizada de [SECOND_LIFE].
+ Está disponible una versión actualizada de [APP_NAME].
[MESSAGE]
Esta actualización no es obligatoria, pero le sugerimos instalarla para mejorar el rendimiento y la estabilidad.
@@ -1888,7 +1891,7 @@ Si se deja en blanco, las Denuncias de Infracción se enviarán sólo a Linden L
Por defecto: off
</notification>
<notification label="Desajuste en la versión de voz" name="VoiceVersionMismatch">
- En esta región, la versión de Second Life no es compatible con el chat de voz. Para que el chat de voz funcione correctamente, debe actualizar Second Life.
+ En esta región, la versión de [APP_NAME] no es compatible con el chat de voz. Para que el chat de voz funcione correctamente, debe actualizar [APP_NAME].
</notification>
<notification label="Contrato del estado" name="HelpEstateCovenant">
Definir un contrato del estado le permite vender parcelas del mismo. Si no existe un contrato, no puede vender terreno.
@@ -2004,16 +2007,16 @@ Dado que estos objetos tienen scripts, moverlos a su inventario puede provocar u
En este objeto, no hay ítems que esté autorizado a copiar.
</notification>
<notification name="WebLaunchAccountHistory">
- ¿Ir al sitio web de Second Life para ver el historial de su cuenta?
+ ¿Ir al sitio web de [SECOND_LIFE] para ver el historial de su cuenta?
<usetemplate ignoretext="Cuando se cargue la página web del historial de la cuenta" name="okcancelignore" notext="Cancelar" yestext="Ir a la página"/>
</notification>
<notification name="ClickOpenF1Help">
- ¿Visitar el sitio web de Soporte de Second Life?
- <usetemplate ignoretext="Cuando visite el sitio web de Soporte de Second Life." name="okcancelignore" notext="Cancelar" yestext="Ir"/>
+ ¿Visitar el sitio web de Soporte de [SECOND_LIFE]?
+ <usetemplate ignoretext="Cuando visite el sitio web de Soporte de [SECOND_LIFE]." name="okcancelignore" notext="Cancelar" yestext="Ir"/>
</notification>
<notification name="ConfirmQuit">
¿Está seguro de que quiere salir?
- <usetemplate ignoretext="Cuando esté saliendo de Second Life." name="okcancelignore" notext="Continuar" yestext="Salir"/>
+ <usetemplate ignoretext="Cuando esté saliendo de [APP_NAME]." name="okcancelignore" notext="Continuar" yestext="Salir"/>
</notification>
<notification name="HelpReportAbuseEmailLL">
Use esta herramienta para denunciar violaciones de las Normas de la Comunidad y las Condiciones del Servicio. Vea:
@@ -2033,7 +2036,7 @@ Como un servicio a los residentes y visitantes, el propietario de la región ha
El propietario de la región resolverá las denuncias basándose en las reglas locales de la región, tal como se detallan en el Contrato del estado.
(Puede ver el Contrato yendo al menú Mundo y eligiendo Acerca del terreno).
-La resolución de esta denuncia se aplica exclusivamente a esta región; el acceso de los residentes a otras áreas de Second Life no se verá afectado por el resultado de esta denuncia. Únicamente Linden Lab puede impedir el acceso a la totalidad de Second Life.
+La resolución de esta denuncia se aplica exclusivamente a esta región; el acceso de los residentes a otras áreas de [SECOND_LIFE] no se verá afectado por el resultado de esta denuncia. Únicamente Linden Lab puede impedir el acceso a la totalidad de [SECOND_LIFE].
</notification>
<notification name="HelpReportBug">
Use esta herramienta *sólo* para informar de cuestiones técnicas que no se comportan como se describe o era esperable. Por favor, aporte todos los detalles que pueda.
@@ -2086,9 +2089,9 @@ Aportar una descripción precisa nos ayuda a clasificar y procesar los informes
Parece que está usted denunciando una violación de la propiedad intelectual. Por favor, asegúrese de que su denuncia es correcto.
-(1) El proceso de la denuncia. Debe enviar una denuncia de infracción si cree que un Residente está reventando el sistema de permisos de Second Life, por ejemplo, usando un CopyBot u otras herramientas parecidas para copiar, infringiendo los derechos de propiedad intelectual. El Equipo de Infracciones (Abuse Team) investiga y lleva a cabo las acciones disciplinarias apropiadas ante toda acción que viole las las Normas de la Comunidad de Second Life o las Condiciones del Servicio. Sin embargo, el Equipo de Infracciones ni gestiona ni responde a las solicitudes de eliminar contenidos del mundo de Second Life.
+(1) El proceso de la denuncia. Debe enviar una denuncia de infracción si cree que un Residente está reventando el sistema de permisos de [SECOND_LIFE], por ejemplo, usando un CopyBot u otras herramientas parecidas para copiar, infringiendo los derechos de propiedad intelectual. El Equipo de Infracciones (Abuse Team) investiga y lleva a cabo las acciones disciplinarias apropiadas ante toda acción que viole las las Normas de la Comunidad de [SECOND_LIFE] o las Condiciones del Servicio. Sin embargo, el Equipo de Infracciones ni gestiona ni responde a las solicitudes de eliminar contenidos del mundo de [SECOND_LIFE].
-(2) El DMCA o Proceso de Eliminación de Contenido. Para solicitar que se elimine algún contenido de Second Life, DEBE enviar una notificación válida de infracción tal y como se explica en nuestra DMCA Policy en http://secondlife.com/corporate/dmca.php.
+(2) El DMCA o Proceso de Eliminación de Contenido. Para solicitar que se elimine algún contenido de [SECOND_LIFE], DEBE enviar una notificación válida de infracción tal y como se explica en nuestra DMCA Policy en http://secondlife.com/corporate/dmca.php.
Si todavía quiere seguir con el proceso de infracción, por favor, cierre esta ventana y acabe de enviar su denuncia. En concreto, debe seleccionar la categoría &apos;CopyBot o Programa para saltarse los permisos&apos;.
@@ -2210,7 +2213,7 @@ Pulse &apos;Cielo avanzado&apos; para abrir un editor con configuraciones avanza
Pulse &apos;Agua avanzada&apos; para abrir un editor con configuraciones avanzadas para el agua.
</notification>
<notification name="HelpDayCycle">
- El Editor del ciclo del día le permite controlar el cielo de Second Life durante el ciclo día/noche. Este es el ciclo que usa el deslizable Duración de un día del Editor del entorno.
+ El Editor del ciclo del día le permite controlar el cielo de [SECOND_LIFE] durante el ciclo día/noche. Este es el ciclo que usa el deslizable Duración de un día del Editor del entorno.
El Editor del ciclo del día trabaja configurando fotogramas clave (&apos;keyframes&apos;): nodos (representados por los puntos grises en la línea del tiempo) cada uno de los cuales tiene asociado un Cielo definido. Según progresa la Duración de un día, el WindLight realiza la &apos;animación&apos; del cielo interpolándose entre esos fotogramas clave.
@@ -2288,7 +2291,7 @@ Pero, vaya, diviértase si quiere.
Controla la velocidad de las nubes al moverse en la dirección del eje Y.
</notification>
<notification name="HelpClassicClouds">
- Marque esta casilla para activar la aparición de las nubes clásicas de Second Life junto a las nubes del WindLight.
+ Marque esta casilla para activar la aparición de las nubes clásicas de [SECOND_LIFE] junto a las nubes del WindLight.
</notification>
<notification name="HelpWaterFogColor">
Elije el color del agua bajo la superficie.
@@ -2386,7 +2389,7 @@ Pero, vaya, diviértase si quiere.
</notification>
<notification name="NotAgeVerified">
Para acceder a esta parcela, se debe haber verificado su edad.
-¿Quiere visitar la web de Second Life para verificar su edad?
+¿Quiere visitar la web de [SECOND_LIFE] para verificar su edad?
[_URL]
<url name="url" option="0">
@@ -2396,7 +2399,7 @@ Pero, vaya, diviértase si quiere.
</notification>
<notification name="Cannot enter parcel: no payment info on file">
Antes de que pueda acceder a esta parcela, se requiere que usted tenga archivada su información de pago.
-¿Quiere visitar la web de Second Life para actualizar esto?
+¿Quiere visitar la web de [SECOND_LIFE] para actualizar esto?
[_URL]
<url name="url" option="0">
@@ -2713,13 +2716,13 @@ Por favor, reinténtelo en unos momentos.
No se puede crear la conexión.
</notification>
<notification name="InternalUsherError">
- Se ha producido un error interno al intentar acceder al destino de su teleporte. Puede que, en este momento, el servicio de Second Life tenga problemas.
+ Se ha producido un error interno al intentar acceder al destino de su teleporte. Puede que, en este momento, el servicio de [SECOND_LIFE] tenga problemas.
</notification>
<notification name="NoGoodTPDestination">
No se puede encontrar en esta región un buen destino para el teleporte.
</notification>
<notification name="InternalErrorRegionResolver">
- Ha sucedido un error interno al manejar las coordenadas globales de su petición de teleporte. Puede que, en este momento, el servicio de Second Life tenga problemas.
+ Ha sucedido un error interno al manejar las coordenadas globales de su petición de teleporte. Puede que, en este momento, el servicio de [SECOND_LIFE] tenga problemas.
</notification>
<notification name="NoValidLanding">
No se ha podido encontrar un punto de aterrizaje válido.
@@ -2840,7 +2843,7 @@ Del objeto: [OBJECTNAME]; propiedad de: [NAME]?
Búsqueda fallida de [TYPE] de nombre [DESC] en la base de datos.
</notification>
<notification name="InvalidWearable">
- El ítem que intenta llevar usa una característica que su visor no puede leer. Por favor, actualice su versión de Second Life para llevar este ítem.
+ El ítem que intenta llevar usa una característica que su visor no puede leer. Por favor, actualice su versión de [APP_NAME] para llevar este ítem.
</notification>
<notification name="ScriptQuestion">
&apos;[OBJECTNAME]&apos;, un objeto propiedad de &apos;[NAME]&apos;, querría:
@@ -2943,8 +2946,8 @@ Los objetos flexibles no pueden ser materiales, y serán inmateriales hasta que
</notification>
<notification name="FirstDebugMenus">
Ha activado el menú Avanzado.
-Contiene herramientas útiles para los desarrolladores que trabajan mejorando Second Life.
-Para pasar este menú a una ventana, pulse Ctrl-Alt-D. En un Mac, pulse Cmd-Opt-Shift-D.
+Contiene herramientas útiles para los desarrolladores que trabajan mejorando [SECOND_LIFE].
+Para pasar este menú a una ventana, pulse Ctrl-Alt-D. En un Mac, pulse &#8984;-Opt-D.
</notification>
<notification name="FirstSculptedPrim">
Está editando un prim &apos;sculpted&apos;.
@@ -3051,7 +3054,7 @@ Pulse Aceptar para entrar al chat o Rehusar para declinar la invitación. Pulse
- La velocidad de su CPU no cumple los requerimientos mínimos.
</global>
<global name="UnsupportedGLRequirements">
- Parece que no tiene los requerimientos de hardware apropiados para Second Life. Second Life requiere una tarjeta gráfica OpenGL que admita texturas múltiples (&apos;multitexture support&apos;). Si la tiene, compruebe que tiene los últimos drivers para su tarjeta gráfica, así como los últimos parches y &apos;service packs&apos; para su sistema operativo.
+ Parece que no tiene los requerimientos de hardware apropiados para [APP_NAME]. [APP_NAME] requiere una tarjeta gráfica OpenGL que admita texturas múltiples (&apos;multitexture support&apos;). Si la tiene, compruebe que tiene los últimos drivers para su tarjeta gráfica, así como los últimos parches y &apos;service packs&apos; para su sistema operativo.
Si los problemas persisten, por favor, acuda a: http://www.secondlife.com/support
</global>
diff --git a/indra/newview/skins/default/xui/es/panel_login.xml b/indra/newview/skins/default/xui/es/panel_login.xml
index 04edcc4faa..8c3d7ae575 100644
--- a/indra/newview/skins/default/xui/es/panel_login.xml
+++ b/indra/newview/skins/default/xui/es/panel_login.xml
@@ -19,15 +19,9 @@
Posición inicial:
</text>
<combo_box name="start_location_combo">
- <combo_item name="MyHome">
- Mi Base
- </combo_item>
- <combo_item name="MyLastLocation">
- Mi última posición
- </combo_item>
- <combo_item name="Typeregionname">
- &lt;Escriba el nombre de la Región&gt;
- </combo_item>
+ <combo_box.item name="MyHome" label="Mi Base"/>
+ <combo_box.item name="MyLastLocation" label="Mi última posición"/>
+ <combo_box.item name="Typeregionname" label="lt;Escriba el nombre de la Región&gt;"/>
</combo_box>
<check_box label="Recordar la contraseña" name="remember_check"/>
<button label="Iniciar sesión" label_selected="Iniciar sesión" name="connect_btn"/>
diff --git a/indra/newview/skins/default/xui/es/panel_preferences_chat.xml b/indra/newview/skins/default/xui/es/panel_preferences_chat.xml
index d4e6cd1aca..b8c9cc5b44 100644
--- a/indra/newview/skins/default/xui/es/panel_preferences_chat.xml
+++ b/indra/newview/skins/default/xui/es/panel_preferences_chat.xml
@@ -5,15 +5,9 @@
del chat:
</text>
<radio_group name="chat_font_size">
- <radio_item name="radio">
- Pequeño
- </radio_item>
- <radio_item name="radio2">
- Medio
- </radio_item>
- <radio_item name="radio3">
- Grande
- </radio_item>
+ <radio_item name="radio" label="Pequeño" />
+ <radio_item name="radio2" label="Medio" />
+ <radio_item name="radio3" label="Grande" />
</radio_group>
<text length="1" name="text_box2" type="string">
Color del chat:
diff --git a/indra/newview/skins/default/xui/es/panel_preferences_graphics1.xml b/indra/newview/skins/default/xui/es/panel_preferences_graphics1.xml
index 9ba4fbf334..7e19c6dd6b 100644
--- a/indra/newview/skins/default/xui/es/panel_preferences_graphics1.xml
+++ b/indra/newview/skins/default/xui/es/panel_preferences_graphics1.xml
@@ -9,21 +9,11 @@
Tamaño de la ventana:
</text>
<combo_box left="124" name="windowsize combo">
- <combo_item name="640x480">
- 640x480
- </combo_item>
- <combo_item name="800x600">
- 800x600
- </combo_item>
- <combo_item name="720x480">
- 720x480 (NTSC)
- </combo_item>
- <combo_item name="768x576">
- 768x576 (PAL)
- </combo_item>
- <combo_item name="1024x768">
- 1024x768
- </combo_item>
+ <combo_box.item name="640x480" label="640x480"/>
+ <combo_box.item name="800x600" label="800x600"/>
+ <combo_box.item name="720x480" label="720x480 (NTSC)"/>
+ <combo_box.item name="768x576" label="768x576 (PAL)"/>
+ <combo_box.item name="1024x768" label="1024x768"/>
</combo_box>
<text name="DisplayResLabel">
Resolución:
@@ -33,18 +23,10 @@
Proporción:
</text>
<combo_box left="124" name="aspect_ratio" tool_tip="ancho / alto">
- <combo_item length="1" name="4:3(StandardCRT)" type="string">
- 4:3 (Standard CRT)
- </combo_item>
- <combo_item length="1" name="5:4(1280x1024LCD)" type="string">
- 5:4 (1280x1024 LCD)
- </combo_item>
- <combo_item name="8:5(Widescreen)">
- 8:5 (Widescreen)
- </combo_item>
- <combo_item length="1" name="16:9(Widescreen)" type="string">
- 16:9 (Widescreen)
- </combo_item>
+ <combo_box.item length="1" name="4:3(StandardCRT)" type="string" label="4:3 (Standard CRT)"/>
+ <combo_box.item length="1" name="5:4(1280x1024LCD)" type="string" label="5:4 (1280x1024 LCD)"/>
+ <combo_box.item name="8:5(Widescreen)" label="8:5 (Widescreen)"/>
+ <combo_box.item length="1" name="16:9(Widescreen)" type="string" label="16:9 (Widescreen)"/>
</combo_box>
<check_box label="Detectar automáticamente &#10;la proporción" name="aspect_auto_detect" left="295" />
<text name="HigherText">
@@ -86,18 +68,10 @@
Objetos reflejados:
</text>
<radio_group name="ReflectionDetailRadio">
- <radio_item name="0">
- Terreno y árboles
- </radio_item>
- <radio_item name="1">
- Todos los objetos estáticos
- </radio_item>
- <radio_item name="2">
- Todos los avatares y objetos
- </radio_item>
- <radio_item name="3">
- Todo
- </radio_item>
+ <radio_item name="0" label="Terreno y árboles" />
+ <radio_item name="1" label="Todos los objetos estáticos" />
+ <radio_item name="2" label="Todos los avatares y objetos" />
+ <radio_item name="3" label="Todo" />
</radio_group>
<text name="AvatarRenderingText">
Renderización del avatar:
@@ -148,24 +122,16 @@
Detalles de la iluminación:
</text>
<radio_group name="LightingDetailRadio">
- <radio_item name="SunMoon">
- Sólo el Sol y la Luna
- </radio_item>
- <radio_item name="LocalLights">
- Puntos de luz cercanos
- </radio_item>
+ <radio_item name="SunMoon" label="Sólo el Sol y la Luna" />
+ <radio_item name="LocalLights" label="Puntos de luz cercanos" />
</radio_group>
<text name="TerrainDetailText">
Nivel de detalle del
terreno:
</text>
<radio_group name="TerrainDetailRadio" left_delta="60">
- <radio_item name="0">
- Bajo
- </radio_item>
- <radio_item name="2">
- Alto
- </radio_item>
+ <radio_item name="0" label="Bajo" />
+ <radio_item name="2" label="Alto" />
</radio_group>
<button label="Configuraciones recomendadas" name="Defaults" width="195" left="110"/>
<button label="Opciones del hardware" label_selected="Opciones del hardware" name="GraphicsHardwareButton" left="315"/>
diff --git a/indra/newview/skins/default/xui/es/panel_status_bar.xml b/indra/newview/skins/default/xui/es/panel_status_bar.xml
index add7db2f9a..0c5559a359 100644
--- a/indra/newview/skins/default/xui/es/panel_status_bar.xml
+++ b/indra/newview/skins/default/xui/es/panel_status_bar.xml
@@ -27,8 +27,8 @@
<button label="" label_selected="" name="restrictpush" tool_tip="Sin &apos;empujones&apos;"/>
<button label="" label_selected="" name="status_no_voice" tool_tip="Aquí no está disponible la voz"/>
<button label="" label_selected="" name="buyland" tool_tip="Comprar esta parcela"/>
- <line_editor label="Buscar" name="search_editor" tool_tip="Buscar en Second Life"/>
- <button label="" label_selected="" name="search_btn" tool_tip="Buscar en Second Life"/>
+ <line_editor label="Buscar" name="search_editor" tool_tip="Buscar en [SECOND_LIFE]"/>
+ <button label="" label_selected="" name="search_btn" tool_tip="Buscar en [SECOND_LIFE]"/>
<string name="packet_loss_tooltip">
Pérdida de paquetes
</string>
diff --git a/indra/newview/skins/default/xui/es/role_actions.xml b/indra/newview/skins/default/xui/es/role_actions.xml
index 6da277e93e..da9a820eb8 100644
--- a/indra/newview/skins/default/xui/es/role_actions.xml
+++ b/indra/newview/skins/default/xui/es/role_actions.xml
@@ -193,7 +193,7 @@
longdescription="Quien tenga un rol con esta capacidad puede abrir sesiones de chat de voz del grupo. NOTA: para acceder al chat de voz debe tenerse la capacidad &apos;Abrir chat de grupo&apos;."
name="join voice chat" value="27" />
<action description="Moderar el chat de grupo"
- longdescription="Quien tenga esta capacidad puede controlar el acceso y la participaciones en los chats de texto y de voz del grupo."
+ longdescription="Quien tenga esta capacidad puede controlar el acceso y la participación en los chats de texto y de voz del grupo."
name="moderate group chat" value="37" />
</action_set>
</role_actions>
diff --git a/indra/newview/skins/default/xui/es/strings.xml b/indra/newview/skins/default/xui/es/strings.xml
index 4793f6c661..96bf0ea865 100644
--- a/indra/newview/skins/default/xui/es/strings.xml
+++ b/indra/newview/skins/default/xui/es/strings.xml
@@ -55,6 +55,9 @@
<string name="LoginDownloadingClothing">
Descargando la ropa...
</string>
+ <string name="Quit">
+ Salir
+ </string>
<string name="AgentLostConnection">
Esta región puede estar teniendo problemas. Por favor, compruebe su conexión a internet.
</string>
diff --git a/indra/newview/skins/default/xui/fr/floater_about.xml b/indra/newview/skins/default/xui/fr/floater_about.xml
index be5b752080..e05a6d1596 100644
--- a/indra/newview/skins/default/xui/fr/floater_about.xml
+++ b/indra/newview/skins/default/xui/fr/floater_about.xml
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<floater name="floater_about" title="A propos de Second Life">
+<floater name="floater_about" title="A propos de [APP_NAME]">
<text_editor name="credits_editor">
Second Life existe grâce aux efforts de Philip, Tessa, Andrew, Cory, James, Ben, Char, Charlie, Colin, Dan, Daniel, Doug, Eric, Hamlet, Haney, Eve, Hunter, Ian, Jeff, Jennifer, Jim, John, Lee, Mark, Peter, Phoenix, Richard, Robin, Xenon, Steve, Tanya, Eddie, Avi, Frank, Bruce, Aaron, Alice, Bob, Debra, Eileen, Helen, Janet, Louie, Leviathania, Stefan, Ray, Kevin, Tom, Mikeb, MikeT, Burgess, Elena, Tracy, Bill, Todd, Ryan, Zach, Sarah, Nova, Tim, Stephanie, Michael, Evan, Nicolas, Catherine, Rachelle, Dave, Holly, Bub, Kelly, Magellan, Ramzi, Don, Sabin, Jill, Rheya, Jeska, Torley, Kona, Callum, Charity, Ventrella, Jack, Vektor, Iris, Chris, Nicole, Mick, Reuben, Blue, Babbage, Yedwab, Deana, Lauren, Brent, Pathfinder, Chadrick, Altruima, Jesse, Teeny, Monroe, Icculus, David, Tess, Lizzie, Patsy, Isaac, Lawrence, Cyn, Bo, Gia, Annette, Marius, Tbone, Jonathan, Karen, Ginsu, Satoko, Yuko, Makiko, Thomas, Harry, Seth, Alexei, Brian, Guy, Runitai, Ethan, Data, Cornelius, Kenny, Swiss, Zero, Natria, Wendy, Stephen, Teeple, Thumper, Lucy, Dee, Mia, Liana, Warren, Branka, Aura, beez, Milo, Hermia, Red, Thrax, Joe, Sally, Magenta, Mogura, Paul, Jose, Rejean, Henrik, Lexie, Amber, Logan, Xan, Nora, Morpheus, Donovan, Leyla, MichaelFrancis, Beast, Cube, Bucky, Joshua, Stryfe, Harmony, Teresa, Claudia, Walker, Glenn, Fritz, Fordak, June, Cleopetra, Jean, Ivy, Betsy, Roosevelt, Spike, Ken, Which, Tofu, Chiyo, Rob, Zee, dustin, George, Del, Matthew, Cat, Jacqui, Lightfoot, Adrian, Viola, Alfred, Noel, Irfan, Sunil, Yool, Rika, Jane, Xtreme, Frontier, a2, Neo, Siobhan, Yoz, Justin, Elle, Qarl, Benjamin, Isabel, Gulliver, Everett, Christopher, Izzy, Stephany, Garry, Sejong, Sean, Tobin, Iridium, Meta, Anthony, Jeremy, JP, Jake, Maurice, Madhavi, Leopard, Kyle, Joon, Kari, Bert, Belinda, Jon, Kristi, Bridie, Pramod, KJ, Socrates, Maria, Ivan, Aric, Yamasaki, Adreanne, Jay, MitchK, Ceren, Coco, Durl, Jenny, Periapse, Kartic, Storrs, Lotte, Sandy, Rohn, Colossus, Zen, BigPapi, Brad, Pastrami, Kurz, Mani, Neuro, Jaime, MJ, Rowan, Sgt, Elvis, Gecko, Samuel, Sardonyx, Leo, Bryan, Niko, Soft, Poppy, Rachel, Aki, Angelo, Banzai, Alexa, Sue, CeeLo, Bender, CG, Gillian, Pelle, Nick, Echo, Zara, Christine, Shamiran, Emma, Blake, Keiko, Plexus, Joppa, Sidewinder, Erica, Ashlei, Twilight, Kristen, Brett, Q, Enus, Simon, Bevis, Kraft, Kip, Chandler, Ron, LauraP, Ram, KyleJM, Scouse, Prospero, Melissa, Marty, Nat, Hamilton, Kend, Lordan, Jimmy, Kosmo, Seraph, Green, Ekim, Wiggo, JT, Rome, Doris, Miz, Benoc, Whump, Trinity, Patch, Kate, TJ, Bao, Joohwan, Christy, Sofia, Matias, Cogsworth, Johan, Oreh, Cheah, Angela, Brandy, Mango, Lan, Aleks, Gloria, Heidy, Mitchell, Space, Colton, Bambers, Einstein, Maggie, Malbers, Rose, Winnie, Stella, Milton, Rothman, Niall, Marin, Allison, Katie, Dawn, Katt, Dusty, Kalpana, Judy, Andrea, Ambroff, Infinity, Gail, Rico, Raymond, Yi, William, Christa, M, Teagan, Scout, Molly, Dante, Corr, Dynamike, Usi, Kaylee, Vidtuts, Lil, Danica, Sascha, Kelv, Jacob, Nya, Rodney, Brandon, Elsie, Blondin, Grant, Katrin, Nyx, Gabriel, Locklainn, Claire, Devin, Minerva, Monty, Austin, Bradford, Si, Keira, H, Caitlin, Dita, Makai, Jenn, Ann, Meredith, Clare, Joy, Praveen, Cody, Edmund, Ruthe, Sirena, Gayathri, Spider, FJ, Davidoff, Tian, Jennie, Louise, Oskar, Landon, Noelle, Jarv, Ingrid, Al, Sommer, Doc, Aria, Huin, Gray, Lili, Vir, DJ, Yang, T, Simone, Maestro, Scott, Charlene, Quixote, Amanda, Susan, Zed, Anne, Enkidu, Esbee, Joroan, Katelin, Roxie, Tay, Scarlet, Kevin, Johnny, Wolfgang, Andren, Bob, Howard, Merov, Rand, Ray, Michon, Newell, Galen, Dessie, Les, Michon, Jenelle, Geo, Siz, Shapiro, Pete, Calyle, Selene, Allen, Phoebe, Goldin, Kimmora, Dakota, Slaton, Lindquist, Zoey, Hari, Othello, Rohit, Sheldon, Petra, Viale, Gordon, Kaye, Pink, Ferny, Emerson, Davy, Bri, Chan, Juan, Robert, Terrence, Nathan, Carl et de nombreuses autres personnes.
diff --git a/indra/newview/skins/default/xui/fr/floater_animation_preview.xml b/indra/newview/skins/default/xui/fr/floater_animation_preview.xml
index 66e12be5cf..af6cb41ba8 100644
--- a/indra/newview/skins/default/xui/fr/floater_animation_preview.xml
+++ b/indra/newview/skins/default/xui/fr/floater_animation_preview.xml
@@ -11,18 +11,10 @@
Prévisualiser pendant
</text>
<combo_box label="" name="preview_base_anim" tool_tip="Utilisez cette option pour tester votre animation pendant que votre avatar fait des choses banales." left_delta="116" width="124">
- <combo_item name="Standing">
- Debout
- </combo_item>
- <combo_item name="Walking">
- En train de marcher
- </combo_item>
- <combo_item name="Sitting">
- Assis
- </combo_item>
- <combo_item name="Flying">
- En train de voler
- </combo_item>
+ <combo_box.item name="Standing" label="Debout" />
+ <combo_box.item name="Walking" label="En train de marcher" />
+ <combo_box.item name="Sitting" label="Assis" />
+ <combo_box.item name="Flying" label="En train de voler" />
</combo_box>
<check_box left="6" label="Boucle" name="loop_check" tool_tip="Joue cette animation en boucle."/>
<spinner left="76" label_width="55" width="105" label="Début (%)" name="loop_in_point" tool_tip="Définit le moment de l&apos;animation où la boucle repart."/>
@@ -31,110 +23,44 @@
Mouvement de main
</text>
<combo_box label="" name="hand_pose_combo" tool_tip="Contrôle le mouvement des mains au cours de l&apos;animation" left_delta="116" width="124">
- <combo_item name="Spread">
- Doigts écartés
- </combo_item>
- <combo_item name="Relaxed">
- Détendues
- </combo_item>
- <combo_item name="PointBoth">
- Pointer (les deux)
- </combo_item>
- <combo_item name="Fist">
- Poing
- </combo_item>
- <combo_item name="RelaxedLeft">
- Détendue (gauche)
- </combo_item>
- <combo_item name="PointLeft">
- Pointer (gauche)
- </combo_item>
- <combo_item name="FistLeft">
- Poing (gauche)
- </combo_item>
- <combo_item name="RelaxedRight">
- Détendue (droite)
- </combo_item>
- <combo_item name="PointRight">
- Pointer (droite)
- </combo_item>
- <combo_item name="FistRight">
- Poing (droite)
- </combo_item>
- <combo_item name="SaluteRight">
- Saluer (droite)
- </combo_item>
- <combo_item name="Typing">
- Taper
- </combo_item>
- <combo_item name="PeaceRight">
- Paix (main droite)
- </combo_item>
+ <combo_box.item name="Spread" label="Doigts écartés" />
+ <combo_box.item name="Relaxed" label="Détendues" />
+ <combo_box.item name="PointBoth" label="Pointer (les deux)" />
+ <combo_box.item name="Fist" label="Poing" />
+ <combo_box.item name="RelaxedLeft" label="Détendue (gauche)" />
+ <combo_box.item name="PointLeft" label="Pointer (gauche)" />
+ <combo_box.item name="FistLeft" label="Poing (gauche)" />
+ <combo_box.item name="RelaxedRight" label="Détendue (droite)" />
+ <combo_box.item name="PointRight" label="Pointer (droite)" />
+ <combo_box.item name="FistRight" label="Poing (droite)" />
+ <combo_box.item name="SaluteRight" label="Saluer (droite)" />
+ <combo_box.item name="Typing" label="Taper" />
+ <combo_box.item name="PeaceRight" label="Paix (main droite)" />
</combo_box>
<text name="emote_label">
Expression
</text>
<combo_box label="" name="emote_combo" tool_tip="Contrôle l&apos;expression du visage au cours de l&apos;animation." left_delta="116" width="124">
- <combo_item name="[None]">
- [None]
- </combo_item>
- <combo_item name="Aaaaah">
- Aaaaah
- </combo_item>
- <combo_item name="Afraid">
- Effrayé
- </combo_item>
- <combo_item name="Angry">
- En colère
- </combo_item>
- <combo_item name="BigSmile">
- Grand sourire
- </combo_item>
- <combo_item name="Bored">
- Ennui
- </combo_item>
- <combo_item name="Cry">
- Pleurer
- </combo_item>
- <combo_item name="Disdain">
- Mépris
- </combo_item>
- <combo_item name="Embarrassed">
- Gêne
- </combo_item>
- <combo_item name="Frown">
- Froncer les sourcils
- </combo_item>
- <combo_item name="Kiss">
- Embrasser
- </combo_item>
- <combo_item name="Laugh">
- Rire
- </combo_item>
- <combo_item name="Plllppt">
- Plllppt
- </combo_item>
- <combo_item name="Repulsed">
- Dégoût
- </combo_item>
- <combo_item name="Sad">
- Triste
- </combo_item>
- <combo_item name="Shrug">
- Hausser les épaules
- </combo_item>
- <combo_item name="Smile">
- Sourire
- </combo_item>
- <combo_item name="Surprise">
- Surprise
- </combo_item>
- <combo_item name="Wink">
- Clin d&apos;Å“il
- </combo_item>
- <combo_item name="Worry">
- Soucis
- </combo_item>
+ <combo_box.item name="[None]" label="None]" />
+ <combo_box.item name="Aaaaah" label="Aaaaah" />
+ <combo_box.item name="Afraid" label="Effrayé" />
+ <combo_box.item name="Angry" label="En colère" />
+ <combo_box.item name="BigSmile" label="Grand sourire" />
+ <combo_box.item name="Bored" label="Ennui" />
+ <combo_box.item name="Cry" label="Pleurer" />
+ <combo_box.item name="Disdain" label="Mépris" />
+ <combo_box.item name="Embarrassed" label="Gêne" />
+ <combo_box.item name="Frown" label="Froncer les sourcils" />
+ <combo_box.item name="Kiss" label="Embrasser" />
+ <combo_box.item name="Laugh" label="Rire" />
+ <combo_box.item name="Plllppt" label="Plllppt" />
+ <combo_box.item name="Repulsed" label="Dégoût" />
+ <combo_box.item name="Sad" label="Triste" />
+ <combo_box.item name="Shrug" label="Hausser les épaules" />
+ <combo_box.item name="Smile" label="Sourire" />
+ <combo_box.item name="Surprise" label="Surprise" />
+ <combo_box.item name="Wink" label="Clin d&apos;Å“il" />
+ <combo_box.item name="Worry" label="Soucis" />
</combo_box>
<spinner label_width="65" label="Transition &#10;début (s)" name="ease_in_time" tool_tip="Durée (en secondes) pendant laquelle l&apos;animation s&apos;intègre au mouvement."/>
<spinner label_width="65" left="160" width="125" label="Transition &#10;fin (s)" name="ease_out_time" tool_tip="Durée (en secondes) pendant laquelle l&apos;animation disparaît du mouvement."/>
diff --git a/indra/newview/skins/default/xui/fr/floater_auction.xml b/indra/newview/skins/default/xui/fr/floater_auction.xml
index 6fe3f66e13..4bdf9df1be 100644
--- a/indra/newview/skins/default/xui/fr/floater_auction.xml
+++ b/indra/newview/skins/default/xui/fr/floater_auction.xml
@@ -2,12 +2,8 @@
<floater name="floater_auction" title="Commencer la vente de terrain Linden">
<check_box label="Inclure le marquage de sélection jaune" name="fence_check" />
<combo_box name="saletype_combo">
- <combo_item name="Auction">
- Enchères
- </combo_item>
- <combo_item name="FirstLand">
- Premier terrain
- </combo_item>
+ <combo_box.item name="Auction" label="Enchères" />
+ <combo_box.item name="FirstLand" label="Premier terrain" />
</combo_box>
<button label="Capture d&apos;écran" label_selected="Capture d&apos;écran"
name="snapshot_btn" width="110" />
diff --git a/indra/newview/skins/default/xui/fr/floater_buy_land.xml b/indra/newview/skins/default/xui/fr/floater_buy_land.xml
index 5ed36c983c..aaf1577114 100644
--- a/indra/newview/skins/default/xui/fr/floater_buy_land.xml
+++ b/indra/newview/skins/default/xui/fr/floater_buy_land.xml
@@ -75,15 +75,9 @@
Seuls les membres Premium peuvent posséder du terrain.
</text>
<combo_box name="account_level">
- <combo_item name="US$9.95/month,billedmonthly">
- 9,95 US$/mois, facturation mensuelle
- </combo_item>
- <combo_item name="US$7.50/month,billedquarterly">
- 7,50 US$/mois, facturation trimestrielle
- </combo_item>
- <combo_item name="US$6.00/month,billedannually">
- 6,00 US$/mois, facturation annuelle
- </combo_item>
+ <combo_box.item name="US$9.95/month,billedmonthly" label="9,95 US$/mois, facturation mensuelle"/>
+ <combo_box.item name="US$7.50/month,billedquarterly" label="7,50 US$/mois, facturation trimestrielle"/>
+ <combo_box.item name="US$6.00/month,billedannually" label="6,00 US$/mois, facturation annuelle"/>
</combo_box>
<text name="land_use_action">
Augmentez vos frais d&apos;occupation de terrain à 40 US$/mois.
diff --git a/indra/newview/skins/default/xui/fr/floater_god_tools.xml b/indra/newview/skins/default/xui/fr/floater_god_tools.xml
index 81b69eb110..4f43be47ea 100644
--- a/indra/newview/skins/default/xui/fr/floater_god_tools.xml
+++ b/indra/newview/skins/default/xui/fr/floater_god_tools.xml
@@ -78,29 +78,17 @@
Destination :
</text>
<combo_box name="destination">
- <combo_item name="Selection">
- Sélection
- </combo_item>
- <combo_item name="AgentRegion">
- Région de l&apos;avatar
- </combo_item>
+ <combo_box.item name="Selection" label="Sélection" />
+ <combo_box.item name="AgentRegion" label="Région de l&apos;avatar" />
</combo_box>
<text name="Request:">
Requête :
</text>
<combo_box name="request">
- <combo_item name="colliders&lt;steps&gt;">
- Objets responsables de collisions : étapes
- </combo_item>
- <combo_item name="scripts&lt;count&gt;,&lt;optionalpattern&gt;">
- Nombre de scripts et schéma optionnel
- </combo_item>
- <combo_item name="objects&lt;pattern&gt;">
- Schéma des objets
- </combo_item>
- <combo_item name="rez&lt;asset_id&gt;">
- rezzer &lt;asset_id&gt;
- </combo_item>
+ <combo_box.item name="colliders&lt;steps&gt;" label="Objets responsables de collisions : étapes" />
+ <combo_box.item name="scripts&lt;count&gt;,&lt;optionalpattern&gt;" label="Nombre de scripts et schéma optionnel" />
+ <combo_box.item name="objects&lt;pattern&gt;" label="Schéma des objets" />
+ <combo_box.item name="rez&lt;asset_id&gt;" label="rezzer &lt;asset_id&gt;" />
</combo_box>
<text name="Parameter:">
Paramètre :
diff --git a/indra/newview/skins/default/xui/fr/floater_hardware_settings.xml b/indra/newview/skins/default/xui/fr/floater_hardware_settings.xml
index e3624c7ccb..11d7fc28e9 100644
--- a/indra/newview/skins/default/xui/fr/floater_hardware_settings.xml
+++ b/indra/newview/skins/default/xui/fr/floater_hardware_settings.xml
@@ -8,21 +8,11 @@
Anti-aliasing :
</text>
<combo_box label="Anti-aliasing" name="fsaa" width="84">
- <combo_item name="FSAADisabled">
- Désactivé
- </combo_item>
- <combo_item name="2x">
- 2x
- </combo_item>
- <combo_item name="4x">
- 4x
- </combo_item>
- <combo_item name="8x">
- 8x
- </combo_item>
- <combo_item name="16x">
- 16x
- </combo_item>
+ <combo_box.item name="FSAADisabled" label="Désactivé" />
+ <combo_box.item name="2x" label="2x" />
+ <combo_box.item name="4x" label="4x" />
+ <combo_box.item name="8x" label="8x" />
+ <combo_box.item name="16x" label="16x" />
</combo_box>
<spinner label="Gamma :" name="gamma"/>
<text left="217" name="(brightness, lower is brighter)">
diff --git a/indra/newview/skins/default/xui/fr/floater_image_preview.xml b/indra/newview/skins/default/xui/fr/floater_image_preview.xml
index 3727e3590d..f12c1fee44 100644
--- a/indra/newview/skins/default/xui/fr/floater_image_preview.xml
+++ b/indra/newview/skins/default/xui/fr/floater_image_preview.xml
@@ -10,36 +10,16 @@
Prévisualiser comme :
</text>
<combo_box label="Habits" name="clothing_type_combo" left="126" >
- <combo_item name="Image">
- Image
- </combo_item>
- <combo_item name="Hair">
- Cheveux
- </combo_item>
- <combo_item name="FemaleHead">
- Tête de femme
- </combo_item>
- <combo_item name="FemaleUpperBody">
- Corps de femme (haut)
- </combo_item>
- <combo_item name="FemaleLowerBody">
- Corps de femme (bas)
- </combo_item>
- <combo_item name="MaleHead">
- Tête d&apos;homme
- </combo_item>
- <combo_item name="MaleUpperBody">
- Corps d&apos;homme (haut)
- </combo_item>
- <combo_item name="MaleLowerBody">
- Corps d&apos;homme (bas)
- </combo_item>
- <combo_item name="Skirt">
- Jupe
- </combo_item>
- <combo_item name="SculptedPrim">
- Sculptie
- </combo_item>
+ <combo_box.item name="Image" label="Image" />
+ <combo_box.item name="Hair" label="Cheveux" />
+ <combo_box.item name="FemaleHead" label="Tête de femme" />
+ <combo_box.item name="FemaleUpperBody" label="Corps de femme (haut)" />
+ <combo_box.item name="FemaleLowerBody" label="Corps de femme (bas)" />
+ <combo_box.item name="MaleHead" label="Tête d&apos;homme" />
+ <combo_box.item name="MaleUpperBody" label="Corps d&apos;homme (haut)" />
+ <combo_box.item name="MaleLowerBody" label="Corps d&apos;homme (bas)" />
+ <combo_box.item name="Skirt" label="Jupe" />
+ <combo_box.item name="SculptedPrim" label="Sculptie" />
</combo_box>
<text name="bad_image_text">
Impossible de lire l&apos;image.
diff --git a/indra/newview/skins/default/xui/fr/floater_inventory_item_properties.xml b/indra/newview/skins/default/xui/fr/floater_inventory_item_properties.xml
index 92dbc36a03..ec83d5bcaa 100644
--- a/indra/newview/skins/default/xui/fr/floater_inventory_item_properties.xml
+++ b/indra/newview/skins/default/xui/fr/floater_inventory_item_properties.xml
@@ -60,12 +60,8 @@
</text>
<check_box label="À vendre" name="CheckPurchase"/>
<radio_group name="RadioSaleType">
- <radio_item name="radio">
- Original
- </radio_item>
- <radio_item name="radio2">
- Copie
- </radio_item>
+ <radio_item name="radio" label="Original" />
+ <radio_item name="radio2" label="Copie" />
</radio_group>
<text name="TextPrice">
Prix : L$
diff --git a/indra/newview/skins/default/xui/fr/floater_postcard.xml b/indra/newview/skins/default/xui/fr/floater_postcard.xml
index 38eb0ced4a..ab21d7423a 100644
--- a/indra/newview/skins/default/xui/fr/floater_postcard.xml
+++ b/indra/newview/skins/default/xui/fr/floater_postcard.xml
@@ -29,12 +29,12 @@
Saisissez votre message ici.
</text_editor>
<text name="fine_print">
- Si le destinataire s&apos;inscrit sur Second Life, vous recevrez un bonus.
+ Si le destinataire s&apos;inscrit sur [SECOND_LIFE], vous recevrez un bonus.
</text>
<button label="Annuler" name="cancel_btn" />
<button label="Envoyer" name="send_btn" />
<string name="default_subject">
- Carte postale de Second Life.
+ Carte postale de [SECOND_LIFE]
</string>
<string name="default_message">
Ouvrez-moi !
diff --git a/indra/newview/skins/default/xui/fr/floater_preview_gesture.xml b/indra/newview/skins/default/xui/fr/floater_preview_gesture.xml
index d234059dbb..b2c3d18cbd 100644
--- a/indra/newview/skins/default/xui/fr/floater_preview_gesture.xml
+++ b/indra/newview/skins/default/xui/fr/floater_preview_gesture.xml
@@ -49,12 +49,8 @@ simultanément, sauf si vous
ajoutez des pauses.
</text>
<radio_group name="animation_trigger_type">
- <radio_item name="start">
- Commencer
- </radio_item>
- <radio_item name="stop">
- Stop
- </radio_item>
+ <radio_item name="start" label="Commencer" />
+ <radio_item name="stop" label="Stop" />
</radio_group>
<check_box label="jusqu&apos;à la fin des animations" name="wait_anim_check" />
<check_box label="temps en secondes" name="wait_time_check" />
diff --git a/indra/newview/skins/default/xui/fr/floater_sell_land.xml b/indra/newview/skins/default/xui/fr/floater_sell_land.xml
index cf394643bc..6ef12fab4a 100644
--- a/indra/newview/skins/default/xui/fr/floater_sell_land.xml
+++ b/indra/newview/skins/default/xui/fr/floater_sell_land.xml
@@ -37,15 +37,9 @@ parcelle :
spécifique.
</text>
<combo_box name="sell_to" bottom_delta="-32">
- <combo_item name="--selectone--">
- -- Sélectionnez --
- </combo_item>
- <combo_item name="Anyone">
- N&apos;importe qui
- </combo_item>
- <combo_item name="Specificuser:">
- Acheteur spécifique :
- </combo_item>
+ <combo_box.item name="--selectone--" label="Sélectionnez --" />
+ <combo_box.item name="Anyone" label="N&apos;importe qui" />
+ <combo_box.item name="Specificuser:" label="Acheteur spécifique :" />
</combo_box>
<button label="Sélectionner..." name="sell_to_select_agent" width="100"/>
<text name="sell_objects_label">
@@ -56,12 +50,8 @@ spécifique.
de propriétaire.
</text>
<radio_group name="sell_objects" right="430" bottom_delta="-54">
- <radio_item name="no">
- Non, rester le propriétaire des objets
- </radio_item>
- <radio_item name="yes">
- Oui, vendre les objets avec le terrain
- </radio_item>
+ <radio_item name="no" label="Non, rester le propriétaire des objets" />
+ <radio_item name="yes" label="Oui, vendre les objets avec le terrain" />
</radio_group>
<button label="Afficher les objets" name="show_objects" right="420" width="120"/>
<text name="nag_message_label" bottom_delta="-30">
diff --git a/indra/newview/skins/default/xui/fr/floater_settings_debug.xml b/indra/newview/skins/default/xui/fr/floater_settings_debug.xml
index 30183340fc..e67b8e2f79 100644
--- a/indra/newview/skins/default/xui/fr/floater_settings_debug.xml
+++ b/indra/newview/skins/default/xui/fr/floater_settings_debug.xml
@@ -1,12 +1,8 @@
<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
<floater name="settings_debug" title="Paramétrages du mode Debug">
<combo_box name="boolean_combo">
- <combo_item name="TRUE">
- TRUE
- </combo_item>
- <combo_item name="FALSE">
- FALSE
- </combo_item>
+ <combo_box.item name="TRUE" label="TRUE" />
+ <combo_box.item name="FALSE" label="FALSE" />
</combo_box>
<color_swatch label="Couleur" name="color_swatch" width="43" />
<spinner label="x" name="val_spinner_1" />
diff --git a/indra/newview/skins/default/xui/fr/floater_snapshot.xml b/indra/newview/skins/default/xui/fr/floater_snapshot.xml
index 4351a1a789..90feea91e0 100644
--- a/indra/newview/skins/default/xui/fr/floater_snapshot.xml
+++ b/indra/newview/skins/default/xui/fr/floater_snapshot.xml
@@ -4,15 +4,9 @@
Destination de la photo
</text>
<radio_group label="Type de photo" name="snapshot_type_radio" width="228">
- <radio_item name="postcard">
- Envoyer par e-mail
- </radio_item>
- <radio_item name="texture">
- Enregistrer dans votre inventaire ([AMOUNT] L$)
- </radio_item>
- <radio_item name="local">
- Enregistrer sur votre disque dur
- </radio_item>
+ <radio_item name="postcard" label="Envoyer par e-mail" />
+ <radio_item name="texture" label="Enregistrer dans votre inventaire ([AMOUNT] L$)" />
+ <radio_item name="local" label="Enregistrer sur votre disque dur" />
</radio_group>
<button label="Plus &gt;&gt;" name="more_btn" tool_tip="Options avancées"/>
<button label="&lt;&lt; Moins" name="less_btn" tool_tip="Options avancées"/>
@@ -23,75 +17,33 @@
Format
</text>
<combo_box label="Résolution" name="postcard_size_combo">
- <combo_item name="640x480">
- 640 x 480
- </combo_item>
- <combo_item name="800x600">
- 800 x 600
- </combo_item>
- <combo_item name="1024x768">
- 1024 x 768
- </combo_item>
- <combo_item name="CurrentWindow">
- Fenêtre actuelle
- </combo_item>
- <combo_item name="Custom">
- Personnaliser
- </combo_item>
+ <combo_box.item name="640x480" label="640 x 480" />
+ <combo_box.item name="800x600" label="800 x 600" />
+ <combo_box.item name="1024x768" label="1024 x 768" />
+ <combo_box.item name="CurrentWindow" label="Fenêtre actuelle" />
+ <combo_box.item name="Custom" label="Personnaliser" />
</combo_box>
<combo_box label="Résolution" name="texture_size_combo">
- <combo_item name="CurrentWindow">
- Fenêtre actuelle
- </combo_item>
- <combo_item name="Small(128x128)">
- Petite (128 x 128)
- </combo_item>
- <combo_item name="Medium(256x256)">
- Moyenne (256 x 256)
- </combo_item>
- <combo_item name="Large(512x512)">
- Grande (512 x 512)
- </combo_item>
- <combo_item name="Custom">
- Personnaliser
- </combo_item>
+ <combo_box.item name="CurrentWindow" label="Fenêtre actuelle" />
+ <combo_box.item name="Small(128x128)" label="Petite (128 x 128)" />
+ <combo_box.item name="Medium(256x256)" label="Moyenne (256 x 256)" />
+ <combo_box.item name="Large(512x512)" label="Grande (512 x 512)" />
+ <combo_box.item name="Custom" label="Personnaliser" />
</combo_box>
<combo_box label="Résolution" name="local_size_combo">
- <combo_item name="CurrentWindow">
- Fenêtre actuelle
- </combo_item>
- <combo_item name="320x240">
- 320 x 240
- </combo_item>
- <combo_item name="640x480">
- 640 x 480
- </combo_item>
- <combo_item name="800x600">
- 800 x 600
- </combo_item>
- <combo_item name="1024x768">
- 1024 x 768
- </combo_item>
- <combo_item name="1280x1024">
- 1280 x 1024
- </combo_item>
- <combo_item name="1600x1200">
- 1600 x 1200
- </combo_item>
- <combo_item name="Custom">
- Personnaliser
- </combo_item>
+ <combo_box.item name="CurrentWindow" label="Fenêtre actuelle" />
+ <combo_box.item name="320x240" label="320 x 240" />
+ <combo_box.item name="640x480" label="640 x 480" />
+ <combo_box.item name="800x600" label="800 x 600" />
+ <combo_box.item name="1024x768" label="1024 x 768" />
+ <combo_box.item name="1280x1024" label="1280 x 1024" />
+ <combo_box.item name="1600x1200" label="1600 x 1200" />
+ <combo_box.item name="Custom" label="Personnaliser" />
</combo_box>
<combo_box label="Format" name="local_format_combo">
- <combo_item name="PNG">
- PNG
- </combo_item>
- <combo_item name="JPEG">
- JPEG
- </combo_item>
- <combo_item name="BMP">
- BMP
- </combo_item>
+ <combo_box.item name="PNG" label="PNG" />
+ <combo_box.item name="JPEG" label="JPEG" />
+ <combo_box.item name="BMP" label="BMP" />
</combo_box>
<spinner label="Largeur" label_width="41" name="snapshot_width" width="101"/>
<spinner label="Hauteur" label_width="41" left="121" name="snapshot_height" width="101"/>
@@ -100,15 +52,9 @@
Capturer :
</text>
<combo_box label="Couches de l&apos;image" name="layer_types">
- <combo_item name="Colors">
- Couleurs
- </combo_item>
- <combo_item name="Depth">
- Profondeur
- </combo_item>
- <combo_item name="ObjectMattes">
- Matte des objets
- </combo_item>
+ <combo_box.item name="Colors" label="Couleurs" />
+ <combo_box.item name="Depth" label="Profondeur" />
+ <combo_box.item name="ObjectMattes" label="Matte des objets" />
</combo_box>
<text name="file_size_label">
Taille du fichier : [SIZE] Ko
@@ -123,12 +69,12 @@
<button label="Enregistrer ([AMOUNT] L$)" name="upload_btn" width="118"/>
<button label="Envoyer" name="send_btn" width="118"/>
<flyout_button label="Enregistrer" name="save_btn" tool_tip="Enregistrer l&apos;image dans un fichier" width="118">
- <flyout_button_item name="save_item">
- Enregistrer
- </flyout_button_item>
- <flyout_button_item name="saveas_item">
- Enregistrer sous...
- </flyout_button_item>
+ <flyout_button.item name="save_item">
+ Enregistrer
+ </flyout_button.item>
+ <flyout_button.item name="saveas_item">
+ Enregistrer sous...
+ </flyout_button.item>
</flyout_button>
<button label="Annuler" name="discard_btn" left="133" width="72" />
<string name="unknown">
diff --git a/indra/newview/skins/default/xui/fr/floater_sound_preview.xml b/indra/newview/skins/default/xui/fr/floater_sound_preview.xml
index 199a6b846f..1ab3a4a714 100644
--- a/indra/newview/skins/default/xui/fr/floater_sound_preview.xml
+++ b/indra/newview/skins/default/xui/fr/floater_sound_preview.xml
@@ -12,17 +12,9 @@
Débit (kbps) :
</text>
<radio_group name="bitrate">
- <radio_item name="32">
- 32
- </radio_item>
- <radio_item name="64">
- 64
- </radio_item>
- <radio_item name="96">
- 96
- </radio_item>
- <radio_item name="128">
- 128
- </radio_item>
+ <radio_item name="32" label="32" />
+ <radio_item name="64" label="64" />
+ <radio_item name="96" label="96" />
+ <radio_item name="128" label="128" />
</radio_group>
</floater>
diff --git a/indra/newview/skins/default/xui/fr/floater_tools.xml b/indra/newview/skins/default/xui/fr/floater_tools.xml
index c89939ff8d..8c462fc6ec 100644
--- a/indra/newview/skins/default/xui/fr/floater_tools.xml
+++ b/indra/newview/skins/default/xui/fr/floater_tools.xml
@@ -20,15 +20,9 @@
Axe :
</text>
<combo_box name="combobox grid mode">
- <combo_item name="World">
- Monde
- </combo_item>
- <combo_item name="Local">
- Local
- </combo_item>
- <combo_item name="Reference">
- Référence
- </combo_item>
+ <combo_box.item name="World" label="Monde"/>
+ <combo_box.item name="Local" label="Local"/>
+ <combo_box.item name="Reference" label="Référence"/>
</combo_box>
<check_box label="Étirer les deux côtés" name="checkbox uniform"/>
<check_box label="Étirer les textures" name="checkbox stretch textures"/>
@@ -130,15 +124,9 @@
Prix : L$
</text>
<radio_group name="sale type">
- <radio_item name="Original">
- Original
- </radio_item>
- <radio_item name="Copy">
- Copie
- </radio_item>
- <radio_item name="Contents">
- Contenus
- </radio_item>
+ <radio_item name="Original" label="Original" />
+ <radio_item name="Copy" label="Copie" />
+ <radio_item name="Contents" label="Contenus" />
</radio_group>
<text name="Next owner can:">
Le prochain propriétaire pourra :
@@ -150,27 +138,13 @@
Action du clic-gauche :
</text>
<combo_box name="clickaction" width="178">
- <combo_item name="Touch/grab(default)">
- Toucher/attraper (défaut)
- </combo_item>
- <combo_item name="Sitonobject">
- S&apos;asseoir sur l&apos;objet
- </combo_item>
- <combo_item name="Buyobject">
- Acheter l&apos;objet
- </combo_item>
- <combo_item name="Payobject">
- Payer l&apos;objet
- </combo_item>
- <combo_item name="Open">
- Ouvrir
- </combo_item>
- <combo_item name="Play">
- Jouer le média de la parcelle
- </combo_item>
- <combo_item name="Opemmedia">
- Ouvrir le média de la parcelle
- </combo_item>
+ <combo_box.item name="Touch/grab(default)" label="Toucher/attraper (défaut)"/>
+ <combo_box.item name="Sitonobject" label="S&apos;asseoir sur l&apos;objet"/>
+ <combo_box.item name="Buyobject" label="Acheter l&apos;objet"/>
+ <combo_box.item name="Payobject" label="Payer l&apos;objet"/>
+ <combo_box.item name="Open" label="Ouvrir"/>
+ <combo_box.item name="Play" label="Jouer le média de la parcelle"/>
+ <combo_box.item name="Opemmedia" label="Ouvrir le média de la parcelle"/>
</combo_box>
<text name="B:">
B :
@@ -254,56 +228,26 @@
Matériau
</text>
<combo_box name="material">
- <combo_item name="Stone">
- Pierre
- </combo_item>
- <combo_item name="Metal">
- Métal
- </combo_item>
- <combo_item name="Glass">
- Verre
- </combo_item>
- <combo_item name="Wood">
- Bois
- </combo_item>
- <combo_item name="Flesh">
- Chair
- </combo_item>
- <combo_item name="Plastic">
- Plastique
- </combo_item>
- <combo_item name="Rubber">
- Caoutchouc
- </combo_item>
+ <combo_box.item name="Stone" label="Pierre"/>
+ <combo_box.item name="Metal" label="Métal"/>
+ <combo_box.item name="Glass" label="Verre"/>
+ <combo_box.item name="Wood" label="Bois"/>
+ <combo_box.item name="Flesh" label="Chair"/>
+ <combo_box.item name="Plastic" label="Plastique"/>
+ <combo_box.item name="Rubber" label="Caoutchouc"/>
</combo_box>
<text name="label basetype">
Type de construction
</text>
<combo_box name="comboBaseType">
- <combo_item name="Box">
- Boîte
- </combo_item>
- <combo_item name="Cylinder">
- Cylindre
- </combo_item>
- <combo_item name="Prism">
- Prisme
- </combo_item>
- <combo_item name="Sphere">
- Sphère
- </combo_item>
- <combo_item name="Torus">
- Tore
- </combo_item>
- <combo_item name="Tube">
- Tube
- </combo_item>
- <combo_item name="Ring">
- Anneau
- </combo_item>
- <combo_item name="Sculpted">
- Sculptie
- </combo_item>
+ <combo_box.item name="Box" label="Boîte"/>
+ <combo_box.item name="Cylinder" label="Cylindre"/>
+ <combo_box.item name="Prism" label="Prisme"/>
+ <combo_box.item name="Sphere" label="Sphère"/>
+ <combo_box.item name="Torus" label="Tore"/>
+ <combo_box.item name="Tube" label="Tube"/>
+ <combo_box.item name="Ring" label="Anneau"/>
+ <combo_box.item name="Sculpted" label="Sculptie"/>
</combo_box>
<text name="text cut">
Début et fin de découpe du tracé
@@ -320,18 +264,10 @@
Forme du creux
</text>
<combo_box name="hole">
- <combo_item name="Default">
- Défaut
- </combo_item>
- <combo_item name="Circle">
- Cercle
- </combo_item>
- <combo_item name="Square">
- Carré
- </combo_item>
- <combo_item name="Triangle">
- Triangle
- </combo_item>
+ <combo_box.item name="Default" label="Défaut"/>
+ <combo_box.item name="Circle" label="Cercle"/>
+ <combo_box.item name="Square" label="Carré"/>
+ <combo_box.item name="Triangle" label="Triangle"/>
</combo_box>
<text name="text twist">
Début et fin de vrille
@@ -380,21 +316,11 @@
Type de raccord
</text>
<combo_box name="sculpt type control">
- <combo_item name="None">
- (aucun)
- </combo_item>
- <combo_item name="Sphere">
- Sphère
- </combo_item>
- <combo_item name="Torus">
- Tore
- </combo_item>
- <combo_item name="Plane">
- Plan
- </combo_item>
- <combo_item name="Cylinder">
- Cylindre
- </combo_item>
+ <combo_box.item name="None" label="aucun)"/>
+ <combo_box.item name="Sphere" label="Sphère"/>
+ <combo_box.item name="Torus" label="Tore"/>
+ <combo_box.item name="Plane" label="Plan"/>
+ <combo_box.item name="Cylinder" label="Cylindre"/>
</combo_box>
</panel>
<panel label="Attributs" name="Features">
@@ -436,88 +362,40 @@
Application
</text>
<combo_box name="combobox texgen">
- <combo_item name="Default">
- Défaut
- </combo_item>
- <combo_item name="Planar">
- Planar
- </combo_item>
+ <combo_box.item name="Default" label="Défaut"/>
+ <combo_box.item name="Planar" label="Planar"/>
</combo_box>
<text name="label shininess">
Brillance
</text>
<combo_box name="combobox shininess">
- <combo_item name="None">
- Aucune
- </combo_item>
- <combo_item name="Low">
- Faible
- </combo_item>
- <combo_item name="Medium">
- Moyenne
- </combo_item>
- <combo_item name="High">
- Élevée
- </combo_item>
+ <combo_box.item name="None" label="Aucune"/>
+ <combo_box.item name="Low" label="Faible"/>
+ <combo_box.item name="Medium" label="Moyenne"/>
+ <combo_box.item name="High" label="Élevée"/>
</combo_box>
<text name="label bumpiness">
Relief
</text>
<combo_box name="combobox bumpiness">
- <combo_item name="None">
- Aucun
- </combo_item>
- <combo_item name="Brightness">
- Luminosité
- </combo_item>
- <combo_item name="Darkness">
- Obscurité
- </combo_item>
- <combo_item name="woodgrain">
- Aggloméré
- </combo_item>
- <combo_item name="bark">
- Écorce
- </combo_item>
- <combo_item name="bricks">
- Briques
- </combo_item>
- <combo_item name="checker">
- Damier
- </combo_item>
- <combo_item name="concrete">
- Béton
- </combo_item>
- <combo_item name="crustytile">
- Carrelage
- </combo_item>
- <combo_item name="cutstone">
- Pierre de taille
- </combo_item>
- <combo_item name="discs">
- Disques
- </combo_item>
- <combo_item name="gravel">
- Gravier
- </combo_item>
- <combo_item name="petridish">
- Boîte de Petri
- </combo_item>
- <combo_item name="siding">
- Lattes
- </combo_item>
- <combo_item name="stonetile">
- Carreaux
- </combo_item>
- <combo_item name="stucco">
- Stuc
- </combo_item>
- <combo_item name="suction">
- Ventouses
- </combo_item>
- <combo_item name="weave">
- Tissage
- </combo_item>
+ <combo_box.item name="None" label="Aucun"/>
+ <combo_box.item name="Brightness" label="Luminosité"/>
+ <combo_box.item name="Darkness" label="Obscurité"/>
+ <combo_box.item name="woodgrain" label="Aggloméré"/>
+ <combo_box.item name="bark" label="Écorce"/>
+ <combo_box.item name="bricks" label="Briques"/>
+ <combo_box.item name="checker" label="Damier"/>
+ <combo_box.item name="concrete" label="Béton"/>
+ <combo_box.item name="crustytile" label="Carrelage"/>
+ <combo_box.item name="cutstone" label="Pierre de taille"/>
+ <combo_box.item name="discs" label="Disques"/>
+ <combo_box.item name="gravel" label="Gravier"/>
+ <combo_box.item name="petridish" label="Boîte de Petri"/>
+ <combo_box.item name="siding" label="Lattes"/>
+ <combo_box.item name="stonetile" label="Carreaux"/>
+ <combo_box.item name="stucco" label="Stuc"/>
+ <combo_box.item name="suction" label="Ventouses"/>
+ <combo_box.item name="weave" label="Tissage"/>
</combo_box>
<text name="tex scale">
Répétitions par face
diff --git a/indra/newview/skins/default/xui/fr/floater_tos.xml b/indra/newview/skins/default/xui/fr/floater_tos.xml
index b77838d92c..ba7052562c 100644
--- a/indra/newview/skins/default/xui/fr/floater_tos.xml
+++ b/indra/newview/skins/default/xui/fr/floater_tos.xml
@@ -3,12 +3,8 @@
<button label="Continuer" label_selected="Continuer" name="Continue" />
<button label="Annuler" label_selected="Annuler" name="Cancel" />
<radio_group name="tos_agreement">
- <radio_item name="radio_disagree">
- Je n&apos;accepte pas les Conditions Générales d&apos;Utilisation
- </radio_item>
- <radio_item name="radio_agree">
- J&apos;accepte les Conditions Générales d&apos;Utilisation
- </radio_item>
+ <radio_item name="radio_disagree" label="Je n&apos;accepte pas les Conditions Générales d&apos;Utilisation" />
+ <radio_item name="radio_agree" label="J&apos;accepte les Conditions Générales d&apos;Utilisation" />
</radio_group>
<text name="tos_title">
Acceptation des Conditions Générales d&apos;Utilisation
@@ -16,7 +12,7 @@
<check_box label="J&apos;accepte les Conditions d&apos;utilisation" name="agree_chk" />
<text name="tos_heading">
Veuillez lire attentivement les Conditions d&apos;utilisation suivantes. Pour continuer à utiliser
-Second Life, vous devez accepter ces conditions.
+[SECOND_LIFE], vous devez accepter ces conditions.
</text>
<text_editor name="tos_text">
TOS_TEXT
diff --git a/indra/newview/skins/default/xui/fr/floater_world_map.xml b/indra/newview/skins/default/xui/fr/floater_world_map.xml
index bf7004e66f..bb5738be27 100644
--- a/indra/newview/skins/default/xui/fr/floater_world_map.xml
+++ b/indra/newview/skins/default/xui/fr/floater_world_map.xml
@@ -40,15 +40,11 @@
<check_box label="Adult" name="event_adult_chk"/>
<icon left="973" name="avatar_icon"/>
<combo_box label="Amis connectés" name="friend combo" tool_tip="Ami à afficher sur la carte" width="232">
- <combo_item name="none_selected">
- Amis connectés
- </combo_item>
+ <combo_box.item name="none_selected" label="Amis connectés" />
</combo_box>
<icon left="973" name="landmark_icon"/>
<combo_box label="Repères" name="landmark combo" tool_tip="Repère à afficher sur la carte" width="232">
- <combo_item name="none_selected">
- Repères
- </combo_item>
+ <combo_box.item name="none_selected" label="Repères" />
</combo_box>
<icon left="973" name="location_icon"/>
<line_editor label="Rechercher par nom de région" name="location" tool_tip="Saisissez le nom d&apos;une région" width="155"/>
@@ -70,6 +66,6 @@
<button label="Afficher la destination" label_selected="Afficher la destination" name="Show Destination" tool_tip="Centrer la carte sur l&apos;endroit sélectionné" width="165"/>
<button label="Effacer" label_selected="Effacer" left="-270" name="Clear" tool_tip="Arrêter de suivre"/>
<button label="Afficher mon emplacement" label_selected="Afficher mon emplacement" name="Show My Location" tool_tip="Centrer la carte sur l&apos;emplacement de votre avatar" width="165"/>
- <button label="Copier la SLURL dans le presse-papiers" left="-270" name="copy_slurl" tool_tip="Copier l&apos;emplacement actuel comme SLURL pour l&apos;utiliser sur le Web." width="262"/>
+ <button label="Copier la SLurl dans le presse-papiers" left="-270" name="copy_slurl" tool_tip="Copier l&apos;emplacement actuel comme SLurl pour l&apos;utiliser sur le Web." width="262"/>
<slider label="Zoom" left="-270" name="zoom slider"/>
</floater>
diff --git a/indra/newview/skins/default/xui/fr/language_settings.xml b/indra/newview/skins/default/xui/fr/language_settings.xml
new file mode 100644
index 0000000000..71418d446a
--- /dev/null
+++ b/indra/newview/skins/default/xui/fr/language_settings.xml
@@ -0,0 +1,55 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<!-- This file contains strings that used to be hardcoded in the source.-->
+<strings>
+
+ <!-- Locale Information -->
+ <string name="MicrosoftLocale">english</string>
+ <string name="DarwinLocale">C</string>
+ <string name="LinuxLocale">C</string>
+
+ <!--
+ datetimeToCodes["wkday"] = "%a"; // Thu
+ datetimeToCodes["weekday"] = "%A"; // Thursday
+ datetimeToCodes["year4"] = "%Y"; // 2009
+ datetimeToCodes["year"] = "%Y"; // 2009
+ datetimeToCodes["year2"] = "%y"; // 09
+ datetimeToCodes["mth"] = "%b"; // Aug
+ datetimeToCodes["month"] = "%B"; // August
+ datetimeToCodes["mthnum"] = "%m"; // 08
+ datetimeToCodes["day"] = "%d"; // 31
+ datetimeToCodes["hour24"] = "%H"; // 14
+ datetimeToCodes["hour"] = "%H"; // 14
+ datetimeToCodes["hour12"] = "%I"; // 02
+ datetimeToCodes["min"] = "%M"; // 59
+ datetimeToCodes["ampm"] = "%p"; // AM
+ datetimeToCodes["second"] = "%S"; // 59
+ datetimeToCodes["timezone"] = "%Z"; // PST
+ -->
+
+ <string name="TimeHour">hour,datetime,slt</string>
+ <string name="TimeMin">min,datetime,slt</string>
+ <string name="TimeYear">year,datetime,slt</string>
+ <string name="TimeDay">day,datetime,slt</string>
+ <string name="TimeMonth">mthnum,datetime,slt</string>
+ <string name="TimeWeek">wkday,datetime,slt</string>
+ <string name="TimeAMPM">ampm,datetime,slt</string>
+ <string name="TimeHour12">hour12,datetime,slt</string>
+
+ <string name="LTimeMthNum">mthnum,datetime,local</string>
+ <string name="LTimeWeek">wkday,datetime,local</string>
+ <string name="LTimeMonth">mth,datetime,local</string>
+ <string name="LTimeDay">day,datetime,local</string>
+ <string name="LTimeSec">second,datetime,local</string>
+ <string name="LTimeHour">hour,datetime,local</string>
+ <string name="LTimeMin">min,datetime,local</string>
+ <string name="LTimeYear">year,datetime,local</string>
+
+ <string name="UTCTimeWeek">weekday,datetime,utc</string>
+ <string name="UTCTimeDay">day,datetime,utc</string>
+ <string name="UTCTimeMth">mth,datetime,utc</string>
+ <string name="UTCTimeYr">year,datetime,utc</string>
+ <string name="UTCTimeHr">hour,datetime,utc</string>
+ <string name="UTCTimeMin">min,datetime,utc</string>
+ <string name="UTCTimeSec">second,datetime,utc</string>
+ <string name="UTCTimeTimezone">timezone,datetime,utc</string>
+</strings>
diff --git a/indra/newview/skins/default/xui/fr/menu_login.xml b/indra/newview/skins/default/xui/fr/menu_login.xml
index b3169714c3..212216f16f 100644
--- a/indra/newview/skins/default/xui/fr/menu_login.xml
+++ b/indra/newview/skins/default/xui/fr/menu_login.xml
@@ -7,7 +7,7 @@
<menu_item_call label="Préférences..." name="Preferences..." />
</menu>
<menu label="Aide" name="Help">
- <menu_item_call label="Aide de Second Life" name="Second Life Help" />
- <menu_item_call label="À propos de Second Life..." name="About Second Life..." />
+ <menu_item_call label="Aide de [SECOND_LIFE]" name="Second Life Help" />
+ <menu_item_call label="À propos de [APP_NAME]..." name="About Second Life..." />
</menu>
</menu_bar>
diff --git a/indra/newview/skins/default/xui/fr/menu_viewer.xml b/indra/newview/skins/default/xui/fr/menu_viewer.xml
index ed46c87403..ea28b82d7e 100644
--- a/indra/newview/skins/default/xui/fr/menu_viewer.xml
+++ b/indra/newview/skins/default/xui/fr/menu_viewer.xml
@@ -120,10 +120,10 @@
<menu_item_call label="Reprendre le contrôle" name="Release Keys"/>
<menu_item_separator label="-----------" name="separator4"/>
<menu_item_call label="Historique de mon compte..." name="Account History...">
- <on_click name="AccountHistory_url" userdata="WebLaunchAccountHistory,http://secondlife.com/account/transactions.php?lang=fr"/>
+ <menu_item_call.on_click name="AccountHistory_url" userdata="WebLaunchAccountHistory,http://secondlife.com/account/transactions.php?lang=fr"/>
</menu_item_call>
<menu_item_call label="Gérer mon compte..." name="Manage My Account...">
- <on_click name="ManageMyAccount_url" userdata="WebLaunchJoinNow,http://secondlife.com/account/index.php?lang=fr"/>
+ <menu_item_call.on_click name="ManageMyAccount_url" userdata="WebLaunchJoinNow,http://secondlife.com/account/index.php?lang=fr"/>
</menu_item_call>
<menu_item_call label="Acheter des L$..." name="Buy and Sell L$..."/>
<menu_item_separator label="-----------" name="separator5"/>
@@ -170,7 +170,7 @@
<menu_item_call label="Mise au point sur la sélection" name="Focus on Selection"/>
<menu_item_call label="Zoom sur la sélection" name="Zoom to Selection"/>
<menu_item_call label="Acheter l&apos;objet" name="Menu Object Take">
- <on_enable userdata="Acheter,Prendre" name="EnableBuyOrTake"/>
+ <menu_item_call.on_enable parameter="Acheter,Prendre" name="EnableBuyOrTake"/>
</menu_item_call>
<menu_item_call label="Prendre une copie" name="Take Copy"/>
<menu_item_call label="Remplacer l&apos;objet dans le contenu de l&apos;objet" name="Save Object Back to Object Contents"/>
@@ -185,13 +185,13 @@
<menu_item_call label="Désactiver les scripts dans la sélection" name="Set Scripts to Not Running in Selection"/>
</menu>
<menu label="Aide" name="Help">
- <menu_item_call label="Aide de Second Life" name="Second Life Help"/>
+ <menu_item_call label="Aide de [SECOND_LIFE]" name="Second Life Help"/>
<menu_item_call label="Didacticiel" name="Tutorial"/>
<menu_item_separator label="-----------" name="separator"/>
<menu_item_call label="Blog officiel..." name="Official Linden Blog..."/>
<menu_item_separator label="-----------" name="separator2"/>
<menu_item_call label="Aide sur le LSL..." name="Scripting Portal...">
- <on_click name="ScriptingPortal_url" userdata="WebLaunchLSLWiki,http://wiki.secondlife.com/wiki/LSL_Portal/fr" />
+ <menu_item_call.on_click name="ScriptingPortal_url" userdata="WebLaunchLSLWiki,http://wiki.secondlife.com/wiki/LSL_Portal/fr" />
</menu_item_call>
<menu_item_separator label="-----------" name="separator3"/>
<menu_item_call label="Signaler une infraction..." name="Report Abuse..."/>
@@ -201,19 +201,19 @@
<menu label="Signaler des bugs" name="Bug Reporting">
<menu_item_call label="Ouvrir un JIRA..." name="Public Issue Tracker..."/>
<menu_item_call label="Comment utiliser JIRA ?" name="Publc Issue Tracker Help...">
- <on_click name="PublicIssueTrackerHelp_url" userdata="WebLaunchPublicIssueHelp,http://wiki.secondlife.com/wiki/Issue_tracker/fr" />
+ <menu_item_call.on_click name="PublicIssueTrackerHelp_url" userdata="WebLaunchPublicIssueHelp,http://wiki.secondlife.com/wiki/Issue_tracker/fr" />
</menu_item_call>
<menu_item_separator label="-----------" name="separator7"/>
<menu_item_call label="Comment signaler des bugs ?" name="Bug Reporing 101...">
- <on_click name="BugReporting101_url" userdata="WebLaunchBugReport101,http://wiki.secondlife.com/wiki/Bug_Reporting_101/fr"/>
+ <menu_item_call.on_click name="BugReporting101_url" userdata="WebLaunchBugReport101,http://wiki.secondlife.com/wiki/Bug_Reporting_101/fr"/>
</menu_item_call>
<menu_item_call label="Comment signaler un problème de sécurité ?" name="Security Issues...">
- <on_click name="SecurityIssues_url" userdata="WebLaunchSecurityIssues,http://wiki.secondlife.com/wiki/Security_issues/fr"/>
+ <menu_item_call.on_click name="SecurityIssues_url" userdata="WebLaunchSecurityIssues,http://wiki.secondlife.com/wiki/Security_issues/fr"/>
</menu_item_call>
<menu_item_call label="Wiki Assurance Qualité…" name="QA Wiki..."/>
<menu_item_separator label="-----------" name="separator9"/>
<menu_item_call label="Signaler un bug..." name="Report Bug..."/>
</menu>
- <menu_item_call label="À propos de Second Life..." name="About Second Life..."/>
+ <menu_item_call label="À propos de [APP_NAME]..." name="About Second Life..."/>
</menu>
</menu_bar>
diff --git a/indra/newview/skins/default/xui/fr/notifications.xml b/indra/newview/skins/default/xui/fr/notifications.xml
index 342f69f5f4..a9c1cad86f 100644
--- a/indra/newview/skins/default/xui/fr/notifications.xml
+++ b/indra/newview/skins/default/xui/fr/notifications.xml
@@ -6,6 +6,9 @@
<global name="alwayschoose">
Toujours choisir cette option
</global>
+ <global name="implicitclosebutton">
+ Fermer
+ </global>
<template name="okbutton">
<form>
<button
@@ -71,7 +74,7 @@
</form>
</template>
<notification functor="GenericAcknowledge" label="Message d&apos;alerte inconnu" name="MissingAlert">
- Votre version de Second Life ne peut afficher ce message d&apos;erreur.
+ Votre version de [APP_NAME] ne peut afficher ce message d&apos;erreur.
Détails de l&apos;erreur : L&apos;alerte, appelée &apos;[_NAME]&apos; est introuvable dans notifications.xml.
<usetemplate name="okbutton" yestext="OK"/>
@@ -94,7 +97,7 @@ Détails de l&apos;erreur : L&apos;alerte, appelée &apos;[_NAME]&apos; est int
<usetemplate name="okcancelbuttons" notext="Annuler" yestext="Oui"/>
</notification>
<notification name="BadInstallation">
- Une erreur est survenue lors de la mise à jour de Second Life. Veuillez télécharger la dernière version depuis secondlife.com.
+ Une erreur est survenue lors de la mise à jour de [APP_NAME]. Veuillez télécharger la dernière version depuis secondlife.com.
<usetemplate name="okbutton" yestext="OK"/>
</notification>
<notification name="LoginFailedNoNetwork">
@@ -219,7 +222,7 @@ En cochant cette case, votre parcelle apparaîtra :
<notification name="ClickPartnerHelpAvatar">
Vous pouvez proposer à un autre résident de devenir votre partenaire ou dissoudre un partenariat existant à partir du site de [SECOND_LIFE].
-Aller sur le site de Second Life pour avoir plus d&apos;informations sur les partenariats ?
+Aller sur le site de [SECOND_LIFE] pour avoir plus d&apos;informations sur les partenariats ?
<usetemplate name="okcancelbuttons" notext="Annuler" yestext="Aller sur cette page"/>
</notification>
<notification name="ClickUploadHelpPermissions">
@@ -257,7 +260,7 @@ Votre prix de vente sera de [SALE_PRICE] L$ et la vente sera disponible à [NAME
<usetemplate name="okcancelbuttons" notext="Annuler" yestext="OK"/>
</notification>
<notification name="ConfirmLandSaleToAnyoneChange">
- Attention : en cliquant sur Vendre à n&apos;importe qui, vous rendez votre terrain disponible à toute la communauté de Second Life, même aux personnes qui ne sont pas dans cette région.
+ Attention : en cliquant sur Vendre à n&apos;importe qui, vous rendez votre terrain disponible à toute la communauté de [SECOND_LIFE], même aux personnes qui ne sont pas dans cette région.
Le terrain sélectionné, de [LAND_SIZE] m², est mis en vente.
Votre prix de vente sera de [SALE_PRICE] L$ et la vente sera disponible à [NAME].
@@ -404,17 +407,17 @@ Une fois payés, les frais ne sont pas remboursables.
<usetemplate name="okcancelbuttons" notext="Annuler" yestext="OK"/>
</notification>
<notification name="CacheWillClear">
- Le cache sera vidé après le redémarrage de [SECOND_LIFE].
+ Le cache sera vidé après le redémarrage de [APP_NAME].
</notification>
<notification name="CacheWillBeMoved">
- Le cache sera déplacé après le redémarrage de [SECOND_LIFE].
+ Le cache sera déplacé après le redémarrage de [APP_NAME].
Remarque : cela videra le cache.
</notification>
<notification name="ChangeConnectionPort">
- Les paramètres du port prendront effet après le redémarrage de [SECOND_LIFE].
+ Les paramètres du port prendront effet après le redémarrage de [APP_NAME].
</notification>
<notification name="ChangeSkin">
- Le nouveau thème apparaîtra après le redémarrage de [SECOND_LIFE].
+ Le nouveau thème apparaîtra après le redémarrage de [APP_NAME].
</notification>
<notification name="GoToAuctionPage">
Aller à la page web de [SECOND_LIFE] pour voir le détail des enchères ou enchérir ?
@@ -473,7 +476,7 @@ L&apos;objet est peut-être inaccessible ou a peut-être été supprimé.
Impossible d&apos;écrire le fichier [[FILE]]
</notification>
<notification name="UnsupportedHardware">
- Avertissement : vous n&apos;avez pas la configuration système requise pour utiliser Second Life. Si vous continuez à utiliser Second Life, votre performance risque d&apos;être moindre. Malheureusement, nous n&apos;offrons aucune assistance pour les problèmes de configuration système.
+ Avertissement : vous n&apos;avez pas la configuration système requise pour utiliser [APP_NAME]. Si vous continuez à utiliser [APP_NAME], votre performance risque d&apos;être moindre. Malheureusement, nous n&apos;offrons aucune assistance pour les problèmes de configuration système.
MINSPECS
Voulez-vous visiter [_URL] pour plus d&apos;informations ?
@@ -485,14 +488,14 @@ Voulez-vous visiter [_URL] pour plus d&apos;informations ?
<notification name="UnknownGPU">
Votre système contient une carte graphique que nous ne connaissons pas actuellement.
Cela est souvent le cas avec le nouveau materiel qui n&apos;a pas encore été testé.
-Vous pourrez probablement utiliser Second Life sans problème, mais vous devrez peut-être ajuster les paramètres de vos graphiques.
+Vous pourrez probablement utiliser [APP_NAME] sans problème, mais vous devrez peut-être ajuster les paramètres de vos graphiques.
(Menu Édition &gt; Préférences &gt; Graphiques).
<form name="form">
<ignore name="ignore" text="Lors de la détection d&apos;une carte graphique inconnue"/>
</form>
</notification>
<notification name="DisplaySettingsNoShaders">
- [SECOND_LIFE] a planté lors de l&apos;initialisation des drivers graphiques.
+ [APP_NAME] a planté lors de l&apos;initialisation des drivers graphiques.
La qualité des graphiques sera paramétrée sur Faible pour éviter certaines erreurs de driver fréquentes.
Certaines fonctionnalités graphiques seront donc désactivées.
Nous vous recommandons de mettre à jour les drivers de votre carte graphique.
@@ -772,7 +775,7 @@ aucune parcelle sélectionnée.
la région dans laquelle il est situé est introuvable.
</notification>
<notification name="CannotCloseFloaterBuyLand">
- Vous ne pouvez pas fermer la fenêtre Acheter le terrain avant que Second Life n&apos;estime le montant de cette transaction.
+ Vous ne pouvez pas fermer la fenêtre Acheter le terrain avant que [APP_NAME] n&apos;estime le montant de cette transaction.
</notification>
<notification name="CannotDeedLandNothingSelected">
Cession du terrain impossible :
@@ -943,7 +946,7 @@ Si le problème persiste, veuillez cliquer sur Aide | Signaler un bug dans le me
<notification name="YouHaveBeenLoggedOut">
Vous avez été déconnecté(e) de [SECOND_LIFE] :
[MESSAGE]
-Vous pouvez afficher vos messages instantanés et votre chat en cliquant sur Afficher IM et chat. Sinon, cliquez sur Quitter pour quitter immédiatement [SECOND_LIFE].
+Vous pouvez afficher vos messages instantanés et votre chat en cliquant sur Afficher IM et chat. Sinon, cliquez sur Quitter pour quitter immédiatement [APP_NAME].
<usetemplate name="okcancelbuttons" notext="Quitter" yestext="Afficher IM et chat"/>
</notification>
<notification name="OnlyOfficerCanBuyLand">
@@ -1106,14 +1109,14 @@ Vous pouvez utiliser [SECOND_LIFE] sans problème, les autres résidents vous vo
</form>
</notification>
<notification name="FirstRun">
- L&apos;installation de [SECOND_LIFE] est terminée.
+ L&apos;installation de [APP_NAME] est terminée.
S&apos;il s&apos;agit de la première fois que vous utilisez [SECOND_LIFE], vous devrez créer un compte avant de pouvoir vous connecter.
Retourner sur www.secondlife.com pour créer un nouveau compte ?
<usetemplate name="okcancelbuttons" notext="Continuer" yestext="Nouveau compte..."/>
</notification>
<notification name="LoginPacketNeverReceived">
- Vous avez des problèmes à vous connecter. Il peut s&apos;agir d&apos;un problème avec votre connexion internet ou les serveurs de Second Life.
+ Vous avez des problèmes à vous connecter. Il peut s&apos;agir d&apos;un problème avec votre connexion internet ou les serveurs de [SECOND_LIFE].
Nous vous conseillons de vérifier votre connexion Internet et de réessayer dans quelques minutes, de cliquer sur Aide, ou bien de cliquer sur Téléporter pour être téléporté vers votre domicile.
<form name="form">
@@ -1217,33 +1220,33 @@ Veuillez choisir un objet à vendre et réessayer.
[DOWNLOAD_PATH].
</notification>
<notification name="DownloadWindowsMandatory">
- Une nouvelle version de [SECOND_LIFE] est disponible.
+ Une nouvelle version de [APP_NAME] est disponible.
[MESSAGE]
-Pour utiliser [SECOND_LIFE] vous devez télécharger cette mise à jour.
+Pour utiliser [APP_NAME] vous devez télécharger cette mise à jour.
<usetemplate name="okcancelbuttons" notext="Quitter" yestext="Télécharger"/>
</notification>
<notification name="DownloadWindows">
- Une mise à jour de [SECOND_LIFE] est disponible.
+ Une mise à jour de [APP_NAME] est disponible.
[MESSAGE]
Cette mise à jour n&apos;est pas requise mais si vous voulez une meilleure performance et plus de stabilité, nous vous recommandons de l&apos;installer.
<usetemplate name="okcancelbuttons" notext="Continuer" yestext="Télécharger"/>
</notification>
<notification name="DownloadWindowsReleaseForDownload">
- Une mise à jour de [SECOND_LIFE] est disponible.
+ Une mise à jour de [APP_NAME] est disponible.
[MESSAGE]
Cette mise à jour n&apos;est pas requise mais si vous voulez une meilleure performance et plus de stabilité, nous vous recommandons de l&apos;installer.
<usetemplate name="okcancelbuttons" notext="Continuer" yestext="Télécharger"/>
</notification>
<notification name="DownloadMacMandatory">
- Une nouvelle version de [SECOND_LIFE] est disponible.
+ Une nouvelle version de [APP_NAME] est disponible.
[MESSAGE]
-Pour utiliser [SECOND_LIFE] vous devez télécharger cette mise à jour.
+Pour utiliser [APP_NAME] vous devez télécharger cette mise à jour.
Télécharger vers le dossier Applications ?
<usetemplate name="okcancelbuttons" notext="Quitter" yestext="Télécharger"/>
</notification>
<notification name="DownloadMac">
- Une mise à jour de [SECOND_LIFE] est disponible.
+ Une mise à jour de [APP_NAME] est disponible.
[MESSAGE]
Cette mise à jour n&apos;est pas requise mais si vous voulez une meilleure performance et plus de stabilité, nous vous recommandons de l&apos;installer.
@@ -1251,7 +1254,7 @@ Télécharger vers le dossier Applications ?
<usetemplate name="okcancelbuttons" notext="Continuer" yestext="Télécharger"/>
</notification>
<notification name="DownloadMacReleaseForDownload">
- Une mise à jour de [SECOND_LIFE] est disponible.
+ Une mise à jour de [APP_NAME] est disponible.
[MESSAGE]
Cette mise à jour n&apos;est pas requise mais si vous voulez une meilleure performance et plus de stabilité, nous vous recommandons de l&apos;installer.
@@ -1818,7 +1821,7 @@ Si vous laissez ce champ vide, les rapports d&apos;infraction seront envoyés à
Valeur par défaut : désactivé
</notification>
<notification label="Versions de voix non compatibles" name="VoiceVersionMismatch">
- Cette version de Second Life n&apos;est pas compatible avec la fonctionnalité de chat vocal dans cette région. Vous devez mettre à jour Second Life pour que le chat vocal fonctionne correctement.
+ Cette version de [APP_NAME] n&apos;est pas compatible avec la fonctionnalité de chat vocal dans cette région. Vous devez mettre à jour [APP_NAME] pour que le chat vocal fonctionne correctement.
</notification>
<notification label="Règlement du domaine" name="HelpEstateCovenant">
Définir un règlement pour le domaine vous permet de vendre les parcelles de ce domaine. S&apos;il n&apos;y a pas de règlement, vous ne pouvez pas vendre le terrain. Si vous ne souhaitez pas indiquer de règlement ou donner de conseils aux acheteurs, laissez la section relative au règlement vide.
@@ -1923,7 +1926,7 @@ Déplacer les objets de l&apos;inventaire ?
<usetemplate ignoretext="Lors du transfert d&apos;un inventaire non copiable depuis des objets scriptés" name="okcancelignore" notext="Annuler" yestext="OK"/>
</notification>
<notification name="ClickActionNotPayable">
- Avertissement : l&apos;action du clic Payer l&apos;objet a été défini mais ne fonctionnera que si un script est ajouté avec l&apos;event money().
+ Avertissement : l&apos;action du clic Payer l&apos;objet a été défini mais ne fonctionnera que si un script est ajouté avec l&apos;event money().
<form name="form">
<ignore name="ignore" text="Lors du paramétrage de la fonction Payer sur des objets sans événement monétaire"/>
</form>
@@ -1932,16 +1935,16 @@ Déplacer les objets de l&apos;inventaire ?
Vous n&apos;êtes autorisé à copier aucun élément dans cet objet.
</notification>
<notification name="WebLaunchAccountHistory">
- Aller sur le site de Second Life pour consulter l&apos;historique de votre compte ?
+ Aller sur le site de [SECOND_LIFE] pour consulter l&apos;historique de votre compte ?
<usetemplate ignoretext="Lors du chargement de la page web contenant l&apos;historique de votre compte" name="okcancelignore" notext="Annuler" yestext="Aller sur cette page"/>
</notification>
<notification name="ClickOpenF1Help">
- Visiter les pages d&apos;aide de Second Life ?
- <usetemplate ignoretext="Lors de la visite des pages d&apos;aide de Second Life" name="okcancelignore" notext="Annuler" yestext="Aller"/>
+ Visiter les pages d&apos;aide de [SECOND_LIFE] ?
+ <usetemplate ignoretext="Lors de la visite des pages d&apos;aide de [SECOND_LIFE]" name="okcancelignore" notext="Annuler" yestext="Aller"/>
</notification>
<notification name="ConfirmQuit">
Êtes-vous certain de vouloir quitter ?
- <usetemplate ignoretext="Lorsque vous quittez Second Life" name="okcancelignore" notext="Continuer" yestext="Quitter"/>
+ <usetemplate ignoretext="Lorsque vous quittez [APP_NAME]" name="okcancelignore" notext="Continuer" yestext="Quitter"/>
</notification>
<notification name="HelpReportAbuseEmailLL">
Utilisez cet outil pour signaler des infractions aux Conditions d&apos;utilisation et aux Règles de la communauté. Voir :
@@ -1961,7 +1964,7 @@ Pour aider les résidents et les visiteurs, le propriétaire de la région dans
Le propriétaire de la région traitera les rapports en fonction des règles de cette région, comme indiqué dans le réglement du domaine.
(Les réglements sont visibles à partir du menu Monde &gt; À propos du terrain.)
-La résolution de ce rapport ne s&apos;applique qu&apos;à cette région ; L&apos;accès aux autres endroits de Second Life ne sera pas affecté par les résultats de cette enquête. Seul Linden Lab peut interdire l&apos;accès à l&apos;ensemble de Second Life.
+La résolution de ce rapport ne s&apos;applique qu&apos;à cette région ; L&apos;accès aux autres endroits de [SECOND_LIFE] ne sera pas affecté par les résultats de cette enquête. Seul Linden Lab peut interdire l&apos;accès à l&apos;ensemble de [SECOND_LIFE].
</notification>
<notification name="HelpReportBug">
N&apos;utilisez cet outil que pour signaler des problèmes techniques et soyez aussi précis que possible.
@@ -2014,9 +2017,9 @@ Les descriptions précises nous permettent de résoudre les bugs plus rapidement
Il semble que vous souhaitiez reporter une infraction à des droits de propriété intellectuelle. Pour signaler correctement cette infraction :
-(1) Remplissez un rapport d&apos;infraction. Vous pouvez soumettre un rapport d&apos;infraction si vous pensez qu&apos;un résident exploite le système de droits de Second Life, par exemple en utilisant un CopyBot ou des outils similaires pour enfreindre des droits de propriété intellectuelle. Notre équipe chargée des infractions mènera une enquête et prendra les mesures nécessaires à l&apos;encontre du résident non respectueux des Conditions d&apos;utilisation ou des règles de la communauté. Sachez toutefois que l&apos;équipe chargée des infractions ne supprimera pas de contenu à l&apos;intérieur de Second Life.
+(1) Remplissez un rapport d&apos;infraction. Vous pouvez soumettre un rapport d&apos;infraction si vous pensez qu&apos;un résident exploite le système de droits de [SECOND_LIFE], par exemple en utilisant un CopyBot ou des outils similaires pour enfreindre des droits de propriété intellectuelle. Notre équipe chargée des infractions mènera une enquête et prendra les mesures nécessaires à l&apos;encontre du résident non respectueux des Conditions d&apos;utilisation ou des règles de la communauté. Sachez toutefois que l&apos;équipe chargée des infractions ne supprimera pas de contenu à l&apos;intérieur de [SECOND_LIFE].
-(2) Demandez à ce que du contenu à l&apos;intérieur de Second Life soit supprimé. Pour demander à ce que du contenu soit supprimé de Second Life, vous devez soumettre un rapport d&apos;infraction valide, tel que fourni dans notre Règlement contre les violations des droit d&apos;auteurs (DMCA), à http://secondlife.com/corporate/dmca.php.
+(2) Demandez à ce que du contenu à l&apos;intérieur de [SECOND_LIFE] soit supprimé. Pour demander à ce que du contenu soit supprimé de [SECOND_LIFE], vous devez soumettre un rapport d&apos;infraction valide, tel que fourni dans notre Règlement contre les violations des droit d&apos;auteurs (DMCA), à http://secondlife.com/corporate/dmca.php.
Si vous souhaitez toujours reporter cette infraction, veuillez fermer cette fenêtre et soumettre votre rapport. Vous devrez peut-être sélectionner la catégorie CopyBot ou exploitation abusive des droits.
@@ -2068,12 +2071,12 @@ Souhaitez-vous quitter le mode occupé avant de terminer cette transaction ?
<usetemplate ignoretext="Losque vous videz le dossier Objets trouvés dans votre inventaire" name="okcancelignore" notext="Non" yestext="Oui"/>
</notification>
<notification name="CopySLURL">
- La SLURL suivante a été copiée dans votre presse-papiers :
+ La SLurl suivante a été copiée dans votre presse-papiers :
[SLURL]
Mettez-la dans une page web pour permettre aux autres résidents d&apos;accéder facilement à cet endroit ou bien collez-la dans la barre d&apos;adresse de votre navigateur.
<form name="form">
- <ignore name="ignore" text="Lorsque vous copiez une SLURL dans votre presse-papier"/>
+ <ignore name="ignore" text="Lorsque vous copiez une SLurl dans votre presse-papier"/>
</form>
</notification>
<notification name="GraphicsPreferencesHelp">
@@ -2139,7 +2142,7 @@ En cliquant sur le bouton Ciel Avancé, vous aurez accès à tous les réglages
En cliquant sur le bouton Eau Avancée, vous aurez accès à tous les réglages relatifs à l&apos;eau.
</notification>
<notification name="HelpDayCycle">
- L&apos;éditeur du cycle du jour vous permet de contrôler le ciel au cours du cycle jour/nuit de second Life. C&apos;est ce même cycle qui est contrôlé par le curseur Heure de la journée dans l&apos;éditeur d&apos;environnement basique.
+ L&apos;éditeur du cycle du jour vous permet de contrôler le ciel au cours du cycle jour/nuit de [SECOND_LIFE]. C&apos;est ce même cycle qui est contrôlé par le curseur Heure de la journée dans l&apos;éditeur d&apos;environnement basique.
L&apos;éditeur du jour fonctionne grâce au réglage d&apos;images-clés. Ces images-clés sont représentées par les marques grises sur la ligne du temps et ont des préréglages qui leurs sont associées. Au cours de la journée et de la nuit, le ciel WindLight s&apos;anime en passant d&apos;une clé à l&apos;autre.
@@ -2221,7 +2224,7 @@ Même chose que l&apos;azimut.
Contrôle la vitesse des nuages sur l&apos;axe des Y.
</notification>
<notification name="HelpClassicClouds">
- Cochez cette option pour utiliser les anciens nuages de Second Life en plus des nuages WindLight.
+ Cochez cette option pour utiliser les anciens nuages de [SECOND_LIFE] en plus des nuages WindLight.
</notification>
<notification name="HelpWaterFogColor">
Permet de sélectionner la couleur du brouillard sous l&apos;eau.
@@ -2319,7 +2322,7 @@ Même chose que l&apos;azimut.
</notification>
<notification name="NotAgeVerified">
Pour que vous puissiez accéder à cette parcelle, votre âge doit être vérifié.
-Voulez-vous aller sur le site de Second Life pour vérifier votre âge ?
+Voulez-vous aller sur le site de [SECOND_LIFE] pour vérifier votre âge ?
[_URL]
<url name="url" option="0">
@@ -2329,7 +2332,7 @@ Voulez-vous aller sur le site de Second Life pour vérifier votre âge ?
</notification>
<notification name="Cannot enter parcel: no payment info on file">
Avant de pouvoir pénétrer sur cette parcelle, vous devez enregistrer vos informations de paiement.
-Voulez-vous aller sur le site de Second Life pour enregistrer ces informations ?
+Voulez-vous aller sur le site de [SECOND_LIFE] pour enregistrer ces informations ?
[_URL]
<url name="url" option="0">
@@ -2876,8 +2879,8 @@ Les objets flexibles ne peuvent pas avoir de propriétés physiques et doivent r
</notification>
<notification name="FirstDebugMenus">
Vous avez activé le menu Avancé.
-Ce menu contient des fonctionnalités utiles pour les développeurs qui travaillent sur Second Life.
-Pour activer/désactiver ce menu sous Windows, appuyez sur Ctrl-Alt-D. Sur un Mac, appuyez sur Cmd-Opt-Maj-D
+Ce menu contient des fonctionnalités utiles pour les développeurs qui travaillent sur [SECOND_LIFE].
+Pour activer/désactiver ce menu sous Windows, appuyez sur Ctrl-Alt-D. Sur un Mac, appuyez sur &#8984;-Opt-Maj-D
</notification>
<notification name="FirstSculptedPrim">
Vous êtes en train d&apos;éditer un sculptie.
@@ -2984,7 +2987,7 @@ Pour y participer, cliquez sur Accepter. Sinon, cliquez sur Refuser. Pour ignore
- Votre processeur ne remplit pas les conditions minimum requises.
</global>
<global name="UnsupportedGLRequirements">
- Vous semblez ne pas avoir le matériel requis pour utiliser Second Life. Second Life requiert une carte graphique OpenGL avec une prise en charge du multitexturing. Si vous avez une telle carte, assurez-vous que vous avez aussi les drivers les plus récents pour la carte, ainsi que les service packs et les patchs pour votre système d&apos;exploitation.
+ Vous semblez ne pas avoir le matériel requis pour utiliser [APP_NAME]. [APP_NAME] requiert une carte graphique OpenGL avec une prise en charge du multitexturing. Si vous avez une telle carte, assurez-vous que vous avez aussi les drivers les plus récents pour la carte, ainsi que les service packs et les patchs pour votre système d&apos;exploitation.
Si vous avez toujours des problèmes, veuillez consulter la page suivante : http://www.secondlife.com/support
</global>
diff --git a/indra/newview/skins/default/xui/fr/panel_login.xml b/indra/newview/skins/default/xui/fr/panel_login.xml
index c4c6350b4a..74bbe9c5b6 100644
--- a/indra/newview/skins/default/xui/fr/panel_login.xml
+++ b/indra/newview/skins/default/xui/fr/panel_login.xml
@@ -16,18 +16,10 @@
Lieu de départ :
</text>
<combo_box name="start_location_combo">
- <combo_item name="MyHome">
- Domicile
- </combo_item>
- <combo_item name="MyLastLocation">
- Dernier emplacement
- </combo_item>
- <combo_item name="&lt;Typeregionname&gt;">
- &lt;Choisir région&gt;
- </combo_item>
- <combo_item name="Typeregionname">
- &lt;Nom de la région&gt;
- </combo_item>
+ <combo_box.item name="MyHome" label="Domicile" />
+ <combo_box.item name="MyLastLocation" label="Dernier emplacement" />
+ <combo_box.item name="&lt;Typeregionname&gt;" label="lt;Choisir région&gt;" />
+ <combo_box.item name="Typeregionname" label="lt;Nom de la région&gt;" />
</combo_box>
<check_box label="Mémoriser" name="remember_check"/>
<text name="full_screen_text">
diff --git a/indra/newview/skins/default/xui/fr/panel_preferences_chat.xml b/indra/newview/skins/default/xui/fr/panel_preferences_chat.xml
index d29ec67272..5fbd3cec22 100644
--- a/indra/newview/skins/default/xui/fr/panel_preferences_chat.xml
+++ b/indra/newview/skins/default/xui/fr/panel_preferences_chat.xml
@@ -5,15 +5,9 @@
du chat :
</text>
<radio_group name="chat_font_size">
- <radio_item length="1" name="radio" type="string">
- Petite
- </radio_item>
- <radio_item length="1" name="radio2" type="string">
- Moyenne
- </radio_item>
- <radio_item length="1" name="radio3" type="string">
- Grande
- </radio_item>
+ <radio_item length="1" name="radio" type="string" label="Petite" />
+ <radio_item length="1" name="radio2" type="string" label="Moyenne" />
+ <radio_item length="1" name="radio3" type="string" label="Grande" />
</radio_group>
<text length="1" name="text_box2" type="string">
Couleur du chat :
diff --git a/indra/newview/skins/default/xui/fr/panel_preferences_graphics1.xml b/indra/newview/skins/default/xui/fr/panel_preferences_graphics1.xml
index 27825b7ff9..cc9e2a8569 100644
--- a/indra/newview/skins/default/xui/fr/panel_preferences_graphics1.xml
+++ b/indra/newview/skins/default/xui/fr/panel_preferences_graphics1.xml
@@ -8,21 +8,11 @@
Taille de la fenêtre :
</text>
<combo_box name="windowsize combo">
- <combo_item name="640x480">
- 640 x 480
- </combo_item>
- <combo_item name="800x600">
- 800 x 600
- </combo_item>
- <combo_item name="720x480">
- 720 x 480 (NTSC)
- </combo_item>
- <combo_item name="768x576">
- 768 x 576 (PAL)
- </combo_item>
- <combo_item name="1024x768">
- 1024 x 768
- </combo_item>
+ <combo_box.item name="640x480" label="640 x 480" />
+ <combo_box.item name="800x600" label="800 x 600" />
+ <combo_box.item name="720x480" label="720 x 480 (NTSC)" />
+ <combo_box.item name="768x576" label="768 x 576 (PAL)" />
+ <combo_box.item name="1024x768" label="1024 x 768" />
</combo_box>
<text name="DisplayResLabel" width="165">
Résolution de l&apos;affichage :
@@ -31,18 +21,10 @@
Rapport hauteur/largeur :
</text>
<combo_box name="aspect_ratio" tool_tip="largeur/hauteur">
- <combo_item length="1" name="4:3(StandardCRT)" type="string">
- 4:3 (Standard CRT)
- </combo_item>
- <combo_item length="1" name="5:4(1280x1024LCD)" type="string">
- 5:4 (1280 x 1024 LCD)
- </combo_item>
- <combo_item name="8:5(Widescreen)">
- 8:5 (écran large)
- </combo_item>
- <combo_item length="1" name="16:9(Widescreen)" type="string">
- 16:9 (plein écran)
- </combo_item>
+ <combo_box.item length="1" name="4:3(StandardCRT)" type="string" label="4:3 (Standard CRT)" />
+ <combo_box.item length="1" name="5:4(1280x1024LCD)" type="string" label="5:4 (1280 x 1024 LCD)" />
+ <combo_box.item name="8:5(Widescreen)" label="8:5 (écran large)" />
+ <combo_box.item length="1" name="16:9(Widescreen)" type="string" label="16:9 (plein écran)" />
</combo_box>
<text length="1" name="text" type="string">
Résolution d&apos;affichage :
@@ -104,18 +86,10 @@
Objets reflétés :
</text>
<radio_group name="ReflectionDetailRadio">
- <radio_item name="0">
- Terrain et Arbres
- </radio_item>
- <radio_item name="1">
- Objets statiques
- </radio_item>
- <radio_item name="2">
- Objets et avatars
- </radio_item>
- <radio_item name="3">
- Tout
- </radio_item>
+ <radio_item name="0" label="Terrain et Arbres" />
+ <radio_item name="1" label="Objets statiques" />
+ <radio_item name="2" label="Objets et avatars" />
+ <radio_item name="3" label="Tout" />
</radio_group>
<text name="AvatarRenderingText">
Rendu de l&apos;avatar :
@@ -166,23 +140,15 @@
Sources lumineuses :
</text>
<radio_group name="LightingDetailRadio">
- <radio_item name="SunMoon">
- Soleil et lune uniquement
- </radio_item>
- <radio_item name="LocalLights">
- Lumières à proximité
- </radio_item>
+ <radio_item name="SunMoon" label="Soleil et lune uniquement" />
+ <radio_item name="LocalLights" label="Lumières à proximité" />
</radio_group>
<text left="380" name="TerrainDetailText">
Rendu du terrain :
</text>
<radio_group name="TerrainDetailRadio">
- <radio_item name="0">
- Faible
- </radio_item>
- <radio_item name="2">
- Élevé
- </radio_item>
+ <radio_item name="0" label="Faible" />
+ <radio_item name="2" label="Élevé" />
</radio_group>
<button label="Paramètres recommandés" name="Defaults"/>
<button label="Configuration du matériel" label_selected="Configuration du matériel" name="GraphicsHardwareButton"/>
diff --git a/indra/newview/skins/default/xui/fr/panel_status_bar.xml b/indra/newview/skins/default/xui/fr/panel_status_bar.xml
index 2e4c694efa..9ea667fcbf 100644
--- a/indra/newview/skins/default/xui/fr/panel_status_bar.xml
+++ b/indra/newview/skins/default/xui/fr/panel_status_bar.xml
@@ -30,8 +30,8 @@
<button label="" label_selected="" name="restrictpush" tool_tip="Pas de bousculades"/>
<button name="status_no_voice" tool_tip="Voix non disponible ici"/>
<button label="" label_selected="" name="buyland" tool_tip="Acheter cette parcelle"/>
- <line_editor label="Rechercher" name="search_editor" tool_tip="Rechercher dans Second Life"/>
- <button name="search_btn" tool_tip="Rechercher dans Second Life"/>
+ <line_editor label="Rechercher" name="search_editor" tool_tip="Rechercher dans [SECOND_LIFE]"/>
+ <button name="search_btn" tool_tip="Rechercher dans [SECOND_LIFE]"/>
<text name="packet_loss_tooltip">
Perte de paquets
</text>
diff --git a/indra/newview/skins/default/xui/it/floater_about.xml b/indra/newview/skins/default/xui/it/floater_about.xml
index a959638159..597208eedb 100644
--- a/indra/newview/skins/default/xui/it/floater_about.xml
+++ b/indra/newview/skins/default/xui/it/floater_about.xml
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<floater name="floater_about" title="Informazioni su Second Life">
+<floater name="floater_about" title="Informazioni su [APP_NAME]">
<text_editor name="credits_editor">
Second Life è offerto da Philip, Tessa, Andrew, Cory, James, Ben, Char, Charlie, Colin, Dan, Daniel, Doug, Eric, Hamlet, Haney, Eve, Hunter, Ian, Jeff, Jennifer, Jim, John, Lee, Mark, Peter, Phoenix, Richard, Robin, Xenon, Steve, Tanya, Eddie, Avi, Frank, Bruce, Aaron, Alice, Bob, Debra, Eileen, Helen, Janet, Louie, Leviathania, Stefan, Ray, Kevin, Tom, Mikeb, MikeT, Burgess, Elena, Tracy, Bill, Todd, Ryan, Zach, Sarah, Nova, Tim, Stephanie, Michael, Evan, Nicolas, Catherine, Rachelle, Dave, Holly, Bub, Kelly, Magellan, Ramzi, Don, Sabin, Jill, Rheya, Jeska, Torley, Kona, Callum, Charity, Ventrella, Jack, Vektor, Iris, Chris, Nicole, Mick, Reuben, Blue, Babbage, Yedwab, Deana, Lauren, Brent, Pathfinder, Chadrick, Altruima, Jesse, Teeny, Monroe, Icculus, David, Tess, Lizzie, Patsy, Isaac, Lawrence, Cyn, Bo, Gia, Annette, Marius, Tbone, Jonathan, Karen, Ginsu, Satoko, Yuko, Makiko, Thomas, Harry, Seth, Alexei, Brian, Guy, Runitai, Ethan, Data, Cornelius, Kenny, Swiss, Zero, Natria, Wendy, Stephen, Teeple, Thumper, Lucy, Dee, Mia, Liana, Warren, Branka, Aura, beez, Milo, Hermia, Red, Thrax, Joe, Sally, Magenta, Mogura, Paul, Jose, Rejean, Henrik, Lexie, Amber, Logan, Xan, Nora, Morpheus, Donovan, Leyla, MichaelFrancis, Beast, Cube, Bucky, Joshua, Stryfe, Harmony, Teresa, Claudia, Walker, Glenn, Fritz, Fordak, June, Cleopetra, Jean, Ivy, Betsy, Roosevelt, Spike, Ken, Which, Tofu, Chiyo, Rob, Zee, dustin, George, Del, Matthew, Cat, Jacqui, Lightfoot, Adrian, Viola, Alfred, Noel, Irfan, Sunil, Yool, Rika, Jane, Xtreme, Frontier, a2, Neo, Siobhan, Yoz, Justin, Elle, Qarl, Benjamin, Isabel, Gulliver, Everett, Christopher, Izzy, Stephany, Garry, Sejong, Sean, Tobin, Iridium, Meta, Anthony, Jeremy, JP, Jake, Maurice, Madhavi, Leopard, Kyle, Joon, Kari, Bert, Belinda, Jon, Kristi, Bridie, Pramod, KJ, Socrates, Maria, Ivan, Aric, Yamasaki, Adreanne, Jay, MitchK, Ceren, Coco, Durl, Jenny, Periapse, Kartic, Storrs, Lotte, Sandy, Rohn, Colossus, Zen, BigPapi, Brad, Pastrami, Kurz, Mani, Neuro, Jaime, MJ, Rowan, Sgt, Elvis, Gecko, Samuel, Sardonyx, Leo, Bryan, Niko, Soft, Poppy, Rachel, Aki, Angelo, Banzai, Alexa, Sue, CeeLo, Bender, CG, Gillian, Pelle, Nick, Echo, Zara, Christine, Shamiran, Emma, Blake, Keiko, Plexus, Joppa, Sidewinder, Erica, Ashlei, Twilight, Kristen, Brett, Q, Enus, Simon, Bevis, Kraft, Kip, Chandler, Ron, LauraP, Ram, KyleJM, Scouse, Prospero, Melissa, Marty, Nat, Hamilton, Kend, Lordan, Jimmy, Kosmo, Seraph, Green, Ekim, Wiggo, JT, Rome, Doris, Miz, Benoc, Whump, Trinity, Patch, Kate, TJ, Bao, Joohwan, Christy, Sofia, Matias, Cogsworth, Johan, Oreh, Cheah, Angela, Brandy, Mango, Lan, Aleks, Gloria, Heidy, Mitchell, Space, Colton, Bambers, Einstein, Maggie, Malbers, Rose, Winnie, Stella, Milton, Rothman, Niall, Marin, Allison, Katie, Dawn, Katt, Dusty, Kalpana, Judy, Andrea, Ambroff, Infinity, Gail, Rico, Raymond, Yi, William, Christa, M, Teagan, Scout, Molly, Dante, Corr, Dynamike, Usi, Kaylee, Vidtuts, Lil, Danica, Sascha, Kelv, Jacob, Nya, Rodney, Brandon, Elsie, Blondin, Grant, Katrin, Nyx, Gabriel, Locklainn, Claire, Devin, Minerva, Monty, Austin, Bradford, Si, Keira, H, Caitlin, Dita, Makai, Jenn, Ann, Meredith, Clare, Joy, Praveen, Cody, Edmund, Ruthe, Sirena, Gayathri, Spider, FJ, Davidoff, Tian, Jennie, Louise, Oskar, Landon, Noelle, Jarv, Ingrid, Al, Sommer, Doc, Aria, Huin, Gray, Lili, Vir, DJ, Yang, T, Simone, Maestro, Scott, Charlene, Quixote, Amanda, Susan, Zed, Anne, Enkidu, Esbee, Joroan, Katelin, Roxie, Tay, Scarlet, Kevin, Johnny, Wolfgang, Andren, Bob, Howard, Merov, Rand, Ray, Michon, Newell, Galen, Dessie, Les, Michon, Jenelle, Geo, Siz, Shapiro, Pete, Calyle, Selene, Allen, Phoebe, Goldin, Kimmora, Dakota, Slaton, Lindquist, Zoey, Hari, Othello, Rohit, Sheldon, Petra, Viale, Gordon, Kaye, Pink, Ferny, Emerson, Davy, Bri, Chan, Juan, Robert, Terrence, Nathan, Carl and many others.
diff --git a/indra/newview/skins/default/xui/it/floater_animation_preview.xml b/indra/newview/skins/default/xui/it/floater_animation_preview.xml
index a57a568cdf..b6d6148afb 100644
--- a/indra/newview/skins/default/xui/it/floater_animation_preview.xml
+++ b/indra/newview/skins/default/xui/it/floater_animation_preview.xml
@@ -14,127 +14,53 @@
Postura della mano
</text>
<combo_box left_delta="100" width="184" name="hand_pose_combo" tool_tip="Controlla cosa fanno le mani durante l&apos;animazione.">
- <combo_item name="Spread">
- Aperte
- </combo_item>
- <combo_item name="Relaxed">
- Rilassate
- </combo_item>
- <combo_item name="PointBoth">
- Entrambe indicano
- </combo_item>
- <combo_item name="Fist">
- Pugno
- </combo_item>
- <combo_item name="RelaxedLeft">
- Sinistra Rilassata
- </combo_item>
- <combo_item name="PointLeft">
- Sinistra Indica
- </combo_item>
- <combo_item name="FistLeft">
- Sinistra a pugno
- </combo_item>
- <combo_item name="RelaxedRight">
- Destra rilassata
- </combo_item>
- <combo_item name="PointRight">
- Destra Indica
- </combo_item>
- <combo_item name="FistRight">
- Destra a Pugno
- </combo_item>
- <combo_item name="SaluteRight">
- Destra Saluta
- </combo_item>
- <combo_item name="Typing">
- Digitano
- </combo_item>
- <combo_item name="PeaceRight">
- Destra &apos;segno di pace&apos;
- </combo_item>
+ <combo_box.item name="Spread" label="Aperte"/>
+ <combo_box.item name="Relaxed" label="Rilassate"/>
+ <combo_box.item name="PointBoth" label="Entrambe indicano"/>
+ <combo_box.item name="Fist" label="Pugno"/>
+ <combo_box.item name="RelaxedLeft" label="Sinistra Rilassata"/>
+ <combo_box.item name="PointLeft" label="Sinistra Indica"/>
+ <combo_box.item name="FistLeft" label="Sinistra a pugno"/>
+ <combo_box.item name="RelaxedRight" label="Destra rilassata"/>
+ <combo_box.item name="PointRight" label="Destra Indica"/>
+ <combo_box.item name="FistRight" label="Destra a Pugno"/>
+ <combo_box.item name="SaluteRight" label="Destra Saluta"/>
+ <combo_box.item name="Typing" label="Digitano"/>
+ <combo_box.item name="PeaceRight" label="Destra &apos;segno di pace&apos;"/>
</combo_box>
<text name="emote_label">
Espressione
</text>
<combo_box left_delta="100" width="184" name="emote_combo" tool_tip="Controlla l&apos;espressione del viso durante l&apos;animazione.">
- <combo_item name="[None]">
- [None]
- </combo_item>
- <combo_item name="Aaaaah">
- Aaaaah
- </combo_item>
- <combo_item name="Afraid">
- Paura
- </combo_item>
- <combo_item name="Angry">
- Rabbia
- </combo_item>
- <combo_item name="BigSmile">
- Sorriso Aperto
- </combo_item>
- <combo_item name="Bored">
- Noia
- </combo_item>
- <combo_item name="Cry">
- Pianto
- </combo_item>
- <combo_item name="Disdain">
- Sdegno
- </combo_item>
- <combo_item name="Embarrassed">
- Imbarazzo
- </combo_item>
- <combo_item name="Frown">
- Accigliato
- </combo_item>
- <combo_item name="Kiss">
- Bacio
- </combo_item>
- <combo_item name="Laugh">
- Risata
- </combo_item>
- <combo_item name="Plllppt">
- Linguaccia
- </combo_item>
- <combo_item name="Repulsed">
- Repulsione
- </combo_item>
- <combo_item name="Sad">
- Tristezza
- </combo_item>
- <combo_item name="Shrug">
- Spallucce
- </combo_item>
- <combo_item name="Smile">
- Sorriso
- </combo_item>
- <combo_item name="Surprise">
- Sorpresa
- </combo_item>
- <combo_item name="Wink">
- Ammiccamento
- </combo_item>
- <combo_item name="Worry">
- Preoccupazione
- </combo_item>
+ <combo_box.item name="[None]" label="None]"/>
+ <combo_box.item name="Aaaaah" label="Aaaaah"/>
+ <combo_box.item name="Afraid" label="Paura"/>
+ <combo_box.item name="Angry" label="Rabbia"/>
+ <combo_box.item name="BigSmile" label="Sorriso Aperto"/>
+ <combo_box.item name="Bored" label="Noia"/>
+ <combo_box.item name="Cry" label="Pianto"/>
+ <combo_box.item name="Disdain" label="Sdegno"/>
+ <combo_box.item name="Embarrassed" label="Imbarazzo"/>
+ <combo_box.item name="Frown" label="Accigliato"/>
+ <combo_box.item name="Kiss" label="Bacio"/>
+ <combo_box.item name="Laugh" label="Risata"/>
+ <combo_box.item name="Plllppt" label="Linguaccia"/>
+ <combo_box.item name="Repulsed" label="Repulsione"/>
+ <combo_box.item name="Sad" label="Tristezza"/>
+ <combo_box.item name="Shrug" label="Spallucce"/>
+ <combo_box.item name="Smile" label="Sorriso"/>
+ <combo_box.item name="Surprise" label="Sorpresa"/>
+ <combo_box.item name="Wink" label="Ammiccamento"/>
+ <combo_box.item name="Worry" label="Preoccupazione"/>
</combo_box>
<text name="preview_label" width="250">
Vedi anteprima mentre
</text>
<combo_box left_delta="154" width="130" name="preview_base_anim" tool_tip="Da usarsi per controllare il comportamento dell&apos;animazione mentre l&apos;avatar svolge azioni abituali.">
- <combo_item name="Standing">
- In piedi
- </combo_item>
- <combo_item name="Walking">
- Passeggia
- </combo_item>
- <combo_item name="Sitting">
- Siede
- </combo_item>
- <combo_item name="Flying">
- Vola
- </combo_item>
+ <combo_box.item name="Standing" label="In piedi"/>
+ <combo_box.item name="Walking" label="Passeggia"/>
+ <combo_box.item name="Sitting" label="Siede"/>
+ <combo_box.item name="Flying" label="Vola"/>
</combo_box>
<spinner label_width="125" width="192" label="Avvio lento (sec)" name="ease_in_time" tool_tip="Tempo (in secondi) in cui le animazioni iniziano a sfumare."/>
<spinner bottom_delta="-20" label_width="125" left="10" width="192" label="Arresto lento (sec)" name="ease_out_time" tool_tip="Tempo (in secondi) in cui le animazioni iniziano a sfumare."/>
diff --git a/indra/newview/skins/default/xui/it/floater_buy_land.xml b/indra/newview/skins/default/xui/it/floater_buy_land.xml
index 38919aa1e7..d6036c19dd 100644
--- a/indra/newview/skins/default/xui/it/floater_buy_land.xml
+++ b/indra/newview/skins/default/xui/it/floater_buy_land.xml
@@ -75,15 +75,9 @@ venduta con gli oggetti
Solo i membri premium possono possedere terra.
</text>
<combo_box name="account_level">
- <combo_item name="US$9.95/month,billedmonthly">
- 9.95 US$/mese, addebitati mensilmente
- </combo_item>
- <combo_item name="US$7.50/month,billedquarterly">
- 7.50 US$/mese, addebitati ogni quadrimestre
- </combo_item>
- <combo_item name="US$6.00/month,billedannually">
- 6.00 US$/mese, addebitati annualmente
- </combo_item>
+ <combo_box.item name="US$9.95/month,billedmonthly" label="9.95 US$/mese, addebitati mensilmente"/>
+ <combo_box.item name="US$7.50/month,billedquarterly" label="7.50 US$/mese, addebitati ogni quadrimestre"/>
+ <combo_box.item name="US$6.00/month,billedannually" label="6.00 US$/mese, addebitati annualmente"/>
</combo_box>
<text name="land_use_action">
Aumenta il tasso di pagamento mensile delle tasse d&apos;uso della terra a 40 US$/mese.
diff --git a/indra/newview/skins/default/xui/it/floater_customize.xml b/indra/newview/skins/default/xui/it/floater_customize.xml
index aeb285e743..70fc27b3bb 100644
--- a/indra/newview/skins/default/xui/it/floater_customize.xml
+++ b/indra/newview/skins/default/xui/it/floater_customize.xml
@@ -14,12 +14,8 @@
<button label="Torso" label_selected="Torso" name="Torso"/>
<button label="Gambe" label_selected="Gambe" name="Legs"/>
<radio_group name="sex radio">
- <radio_item name="radio">
- Femmina
- </radio_item>
- <radio_item name="radio2">
- Maschio
- </radio_item>
+ <radio_item name="radio" label="Femmina" />
+ <radio_item name="radio2" label="Maschio" />
</radio_group>
<text name="title">
[DESC]
diff --git a/indra/newview/skins/default/xui/it/floater_hardware_settings.xml b/indra/newview/skins/default/xui/it/floater_hardware_settings.xml
index 28a53c45eb..688f9137a2 100644
--- a/indra/newview/skins/default/xui/it/floater_hardware_settings.xml
+++ b/indra/newview/skins/default/xui/it/floater_hardware_settings.xml
@@ -8,21 +8,11 @@
Antialiasing:
</text>
<combo_box label="Antialiasing" name="fsaa" width="94">
- <combo_item name="FSAADisabled">
- Disattivato
- </combo_item>
- <combo_item name="2x">
- 2x
- </combo_item>
- <combo_item name="4x">
- 4x
- </combo_item>
- <combo_item name="8x">
- 8x
- </combo_item>
- <combo_item name="16x">
- 16x
- </combo_item>
+ <combo_box.item name="FSAADisabled" label="Disattivato"/>
+ <combo_box.item name="2x" label="2x"/>
+ <combo_box.item name="4x" label="4x"/>
+ <combo_box.item name="8x" label="8x"/>
+ <combo_box.item name="16x" label="16x"/>
</combo_box>
<spinner label="Gamma:" name="gamma"/>
<text name="(brightness, lower is brighter)">
diff --git a/indra/newview/skins/default/xui/it/floater_image_preview.xml b/indra/newview/skins/default/xui/it/floater_image_preview.xml
index 224ab8df75..8ee3181bce 100644
--- a/indra/newview/skins/default/xui/it/floater_image_preview.xml
+++ b/indra/newview/skins/default/xui/it/floater_image_preview.xml
@@ -11,36 +11,16 @@
immagine come:
</text>
<combo_box label="Tipo d&apos;abito" name="clothing_type_combo" left="120" width="166">
- <combo_item name="Image">
- Immagine
- </combo_item>
- <combo_item name="Hair">
- Capelli
- </combo_item>
- <combo_item name="FemaleHead">
- Testa femminile
- </combo_item>
- <combo_item name="FemaleUpperBody">
- Corpo femminile superiore
- </combo_item>
- <combo_item name="FemaleLowerBody">
- Corpo femminile inferiore
- </combo_item>
- <combo_item name="MaleHead">
- Testa maschile
- </combo_item>
- <combo_item name="MaleUpperBody">
- Corpo maschile superiore
- </combo_item>
- <combo_item name="MaleLowerBody">
- Corpo maschile inferiore
- </combo_item>
- <combo_item name="Skirt">
- Gonna
- </combo_item>
- <combo_item name="SculptedPrim">
- Oggetto sculpt
- </combo_item>
+ <combo_box.item name="Image" label="Immagine"/>
+ <combo_box.item name="Hair" label="Capelli"/>
+ <combo_box.item name="FemaleHead" label="Testa femminile"/>
+ <combo_box.item name="FemaleUpperBody" label="Corpo femminile superiore"/>
+ <combo_box.item name="FemaleLowerBody" label="Corpo femminile inferiore"/>
+ <combo_box.item name="MaleHead" label="Testa maschile"/>
+ <combo_box.item name="MaleUpperBody" label="Corpo maschile superiore"/>
+ <combo_box.item name="MaleLowerBody" label="Corpo maschile inferiore"/>
+ <combo_box.item name="Skirt" label="Gonna"/>
+ <combo_box.item name="SculptedPrim" label="Oggetto sculpt"/>
</combo_box>
<text name="bad_image_text">
Non è stato possibile leggere l&apos;immagine.
diff --git a/indra/newview/skins/default/xui/it/floater_inventory_item_properties.xml b/indra/newview/skins/default/xui/it/floater_inventory_item_properties.xml
index 50e5fb83d7..e32f57e9f4 100644
--- a/indra/newview/skins/default/xui/it/floater_inventory_item_properties.xml
+++ b/indra/newview/skins/default/xui/it/floater_inventory_item_properties.xml
@@ -60,12 +60,8 @@
</text>
<check_box label="In vendita" name="CheckPurchase"/>
<radio_group name="RadioSaleType" left_delta="88" >
- <radio_item name="radio">
- Originale
- </radio_item>
- <radio_item name="radio2">
- Copia
- </radio_item>
+ <radio_item name="radio" label="Originale" />
+ <radio_item name="radio2" label="Copia" />
</radio_group>
<text name="TextPrice">
Prezzo: L$
diff --git a/indra/newview/skins/default/xui/it/floater_postcard.xml b/indra/newview/skins/default/xui/it/floater_postcard.xml
index 947f18ea92..a2522baaf4 100644
--- a/indra/newview/skins/default/xui/it/floater_postcard.xml
+++ b/indra/newview/skins/default/xui/it/floater_postcard.xml
@@ -24,12 +24,12 @@
Scrivi il messaggio qui.
</text_editor>
<text name="fine_print">
- Se il tuo destinatario si registrerà in Second Life, riceverai il relativo bonus.
+ Se il tuo destinatario si registrerà in [SECOND_LIFE], riceverai il relativo bonus.
</text>
<button label="Annulla" name="cancel_btn"/>
<button label="Invia" name="send_btn"/>
<string name="default_subject">
- Cartolina da Second Life.
+ Cartolina da [SECOND_LIFE]
</string>
<string name="default_message">
Vieni a vedere!
diff --git a/indra/newview/skins/default/xui/it/floater_preview_gesture.xml b/indra/newview/skins/default/xui/it/floater_preview_gesture.xml
index abfff9a927..60d3a7710e 100644
--- a/indra/newview/skins/default/xui/it/floater_preview_gesture.xml
+++ b/indra/newview/skins/default/xui/it/floater_preview_gesture.xml
@@ -46,12 +46,8 @@ simultaneamente, a meno che tu
non aggiunga pause.
</text>
<radio_group name="animation_trigger_type">
- <radio_item name="start">
- Avvio
- </radio_item>
- <radio_item name="stop">
- Stop
- </radio_item>
+ <radio_item name="start" label="Avvio" />
+ <radio_item name="stop" label="Stop" />
</radio_group>
<check_box left="226" label="finché le animazioni sono eseguite" name="wait_anim_check"/>
<check_box label="tempo in secondi" name="wait_time_check"/>
diff --git a/indra/newview/skins/default/xui/it/floater_report_abuse.xml b/indra/newview/skins/default/xui/it/floater_report_abuse.xml
index e7d712de0f..abcd953c13 100644
--- a/indra/newview/skins/default/xui/it/floater_report_abuse.xml
+++ b/indra/newview/skins/default/xui/it/floater_report_abuse.xml
@@ -36,123 +36,51 @@
Hendrerit Vulputate
</text>
<combo_box name="category_combo" tool_tip="Categoria -- scegli la categoria che descrive meglio questa segnalazione">
- <combo_item name="Select_category">
- Scegli la categoria
- </combo_item>
- <combo_item name="Age__Age_play">
- Età &gt; Far finta di essere minore
- </combo_item>
- <combo_item name="Age__Adult_resident_on_Teen_Second_Life">
- Età &gt; Residente adulto nella Teen Second Life
- </combo_item>
+ <combo_box.item name="Select_category" label="Scegli la categoria"/>
+ <combo_box.item name="Age__Age_play" label="Età &gt; Far finta di essere minore"/>
+ <combo_box.item name="Age__Adult_resident_on_Teen_Second_Life" label="Età &gt; Residente adulto nella Teen Second Life"/>
<combo_item name="Age__Underage_resident_outside_of_Teen_Second_Life">
Età &gt; Residente minorenne al di fuori della &apos;Second Life per Teenager&apos;
</combo_item>
- <combo_item name="Assault__Combat_sandbox___unsafe_area">
- Assalto &gt; sandbox da combattimento / area pericolosa
- </combo_item>
- <combo_item name="Assault__Safe_area">
- Assalto &gt; Area sicura
- </combo_item>
- <combo_item name="Assault__Weapons_testing_sandbox">
- Assalto &gt; Test di armi in sandbox
- </combo_item>
- <combo_item name="Commerce__Failure_to_deliver_product_or_service">
- Commercio &gt; Problema nella consegna di un prodotto o servizio
- </combo_item>
- <combo_item name="Disclosure__Real_world_information">
- Divulgazione &gt; Informazioni del mondo reale
- </combo_item>
- <combo_item name="Disclosure__Remotely_monitoring chat">
- Divulgazione &gt; Monitoraggio remoto di chat
- </combo_item>
- <combo_item name="Disclosure__Second_Life_information_chat_IMs">
- Divulgazione &gt; Informazione/chat/IMs di Second Life
- </combo_item>
- <combo_item name="Disturbing_the_peace__Unfair_use_of_region_resources">
- Disturbo della quiete &gt; Uso sleale delle risorse di una regione
- </combo_item>
- <combo_item name="Disturbing_the_peace__Excessive_scripted_objects">
- Disturbo della quiete &gt; Numero eccessivo di oggetti scriptati
- </combo_item>
- <combo_item name="Disturbing_the_peace__Object_littering">
- Disturbo della quiete &gt; Oggetti messi a soqquadro
- </combo_item>
- <combo_item name="Disturbing_the_peace__Repetitive_spam">
- Disturbo della quiete &gt; Spam continuato
- </combo_item>
- <combo_item name="Disturbing_the_peace__Unwanted_advert_spam">
- Disturbo della quiete &gt; Spam pubblicitario non richiesto
- </combo_item>
- <combo_item name="Fraud__L$">
- Truffa &gt; L$
- </combo_item>
- <combo_item name="Fraud__Land">
- Truffa &gt; Terreno
- </combo_item>
- <combo_item name="Fraud__Pyramid_scheme_or_chain_letter">
- Truffa &gt; Multilivello o catena di Sant&apos;Antonio
- </combo_item>
- <combo_item name="Fraud__US$">
- Truffa &gt; Dollari US$
- </combo_item>
- <combo_item name="Harassment__Advert_farms___visual_spam">
- Molestie &gt; Territori adibiti a pubblicità / spam visivo
- </combo_item>
- <combo_item name="Harassment__Defaming_individuals_or_groups">
- Molestie &gt; Diffamazione di individui o gruppi
- </combo_item>
- <combo_item name="Harassment__Impeding_movement">
- Molestie &gt; Impedimento di movimenti
- </combo_item>
- <combo_item name="Harassment__Sexual_harassment">
- Molestie &gt; Molestie sessuali
- </combo_item>
- <combo_item name="Harassment__Solicting_inciting_others_to_violate_ToS">
- Molestie &gt; Sollecitare/incitare altri a violare i Termini di Servizio
- </combo_item>
- <combo_item name="Harassment__Verbal_abuse">
- Molestie &gt; Abusi verbali
- </combo_item>
- <combo_item name="Indecency__Broadly_offensive_content_or_conduct">
- Indecenza &gt; Condotta o contenuti largamente offensivi
- </combo_item>
- <combo_item name="Indecency__Inappropriate_avatar_name">
- Indecenza &gt; Nome di un avatar inappropriato
- </combo_item>
+ <combo_box.item name="Assault__Combat_sandbox___unsafe_area" label="Assalto &gt; sandbox da combattimento / area pericolosa"/>
+ <combo_box.item name="Assault__Safe_area" label="Assalto &gt; Area sicura"/>
+ <combo_box.item name="Assault__Weapons_testing_sandbox" label="Assalto &gt; Test di armi in sandbox"/>
+ <combo_box.item name="Commerce__Failure_to_deliver_product_or_service" label="Commercio &gt; Problema nella consegna di un prodotto o servizio"/>
+ <combo_box.item name="Disclosure__Real_world_information" label="Divulgazione &gt; Informazioni del mondo reale"/>
+ <combo_box.item name="Disclosure__Remotely_monitoring chat" label="Divulgazione &gt; Monitoraggio remoto di chat"/>
+ <combo_box.item name="Disclosure__Second_Life_information_chat_IMs" label="Divulgazione &gt; Informazione/chat/IMs di Second Life"/>
+ <combo_box.item name="Disturbing_the_peace__Unfair_use_of_region_resources" label="Disturbo della quiete &gt; Uso sleale delle risorse di una regione"/>
+ <combo_box.item name="Disturbing_the_peace__Excessive_scripted_objects" label="Disturbo della quiete &gt; Numero eccessivo di oggetti scriptati"/>
+ <combo_box.item name="Disturbing_the_peace__Object_littering" label="Disturbo della quiete &gt; Oggetti messi a soqquadro"/>
+ <combo_box.item name="Disturbing_the_peace__Repetitive_spam" label="Disturbo della quiete &gt; Spam continuato"/>
+ <combo_box.item name="Disturbing_the_peace__Unwanted_advert_spam" label="Disturbo della quiete &gt; Spam pubblicitario non richiesto"/>
+ <combo_box.item name="Fraud__L$" label="Truffa &gt; L$"/>
+ <combo_box.item name="Fraud__Land" label="Truffa &gt; Terreno"/>
+ <combo_box.item name="Fraud__Pyramid_scheme_or_chain_letter" label="Truffa &gt; Multilivello o catena di Sant&apos;Antonio"/>
+ <combo_box.item name="Fraud__US$" label="Truffa &gt; Dollari US$"/>
+ <combo_box.item name="Harassment__Advert_farms___visual_spam" label="Molestie &gt; Territori adibiti a pubblicità / spam visivo"/>
+ <combo_box.item name="Harassment__Defaming_individuals_or_groups" label="Molestie &gt; Diffamazione di individui o gruppi"/>
+ <combo_box.item name="Harassment__Impeding_movement" label="Molestie &gt; Impedimento di movimenti"/>
+ <combo_box.item name="Harassment__Sexual_harassment" label="Molestie &gt; Molestie sessuali"/>
+ <combo_box.item name="Harassment__Solicting_inciting_others_to_violate_ToS" label="Molestie &gt; Sollecitare/incitare altri a violare i Termini di Servizio"/>
+ <combo_box.item name="Harassment__Verbal_abuse" label="Molestie &gt; Abusi verbali"/>
+ <combo_box.item name="Indecency__Broadly_offensive_content_or_conduct" label="Indecenza &gt; Condotta o contenuti largamente offensivi"/>
+ <combo_box.item name="Indecency__Inappropriate_avatar_name" label="Indecenza &gt; Nome di un avatar inappropriato"/>
<combo_item name="Indecency__Mature_content_in_PG_region">
Indecenza &gt; Contenuto o condotta inappropriata in una regione PG
</combo_item>
<combo_item name="Indecency__Inappropriate_content_in_Mature_region">
Indecenza &gt; Contenuto o condotta inappropriata in una regione Mature
</combo_item>
- <combo_item name="Intellectual_property_infringement_Content_Removal">
- Violazione della proprietà intellettuale &gt; Rimozione contenuti
- </combo_item>
- <combo_item name="Intellectual_property_infringement_CopyBot_or_Permissions_Exploit">
- Violazione della proprietà intellettuale &gt; CopyBot o sblocco di permessi
- </combo_item>
- <combo_item name="Intolerance">
- Intolleranza
- </combo_item>
- <combo_item name="Land__Abuse_of_sandbox_resources">
- Terreno &gt; Abuso delle risorse di una sandbox
- </combo_item>
- <combo_item name="Land__Encroachment__Objects_textures">
- Terreno &gt; Invasione &gt; Oggetti/textures
- </combo_item>
- <combo_item name="Land__Encroachment__Particles">
- Terreno &gt; Invasione &gt; Particelle
- </combo_item>
- <combo_item name="Land__Encroachment__Trees_plants">
- Terreno &gt; Invasione &gt; Alberi/piante
- </combo_item>
- <combo_item name="Wagering_gambling">
- Chiedere l&apos;elemosina/gioco d&apos;azzardo
- </combo_item>
- <combo_item name="Other">
- Altro
- </combo_item>
+ <combo_box.item name="Intellectual_property_infringement_Content_Removal" label="Violazione della proprietà intellettuale &gt; Rimozione contenuti"/>
+ <combo_box.item name="Intellectual_property_infringement_CopyBot_or_Permissions_Exploit" label="Violazione della proprietà intellettuale &gt; CopyBot o sblocco di permessi"/>
+ <combo_box.item name="Intolerance" label="Intolleranza"/>
+ <combo_box.item name="Land__Abuse_of_sandbox_resources" label="Terreno &gt; Abuso delle risorse di una sandbox"/>
+ <combo_box.item name="Land__Encroachment__Objects_textures" label="Terreno &gt; Invasione &gt; Oggetti/textures"/>
+ <combo_box.item name="Land__Encroachment__Particles" label="Terreno &gt; Invasione &gt; Particelle"/>
+ <combo_box.item name="Land__Encroachment__Trees_plants" label="Terreno &gt; Invasione &gt; Alberi/piante"/>
+ <combo_box.item name="Wagering_gambling" label="Chiedere l&apos;elemosina/gioco d&apos;azzardo"/>
+ <combo_box.item name="Other" label="Altro"/>
</combo_box>
<text name="abuser_name_title">
Nome di chi ha commesso l&apos;abuso:
diff --git a/indra/newview/skins/default/xui/it/floater_sell_land.xml b/indra/newview/skins/default/xui/it/floater_sell_land.xml
index 3f47c0ef78..d9cf612d33 100644
--- a/indra/newview/skins/default/xui/it/floater_sell_land.xml
+++ b/indra/newview/skins/default/xui/it/floater_sell_land.xml
@@ -36,15 +36,9 @@ terreno:
Scegli se vendere a tutti o ad un compratore in particolare.
</text>
<combo_box name="sell_to">
- <combo_item name="--selectone--">
- -- selezionane uno --
- </combo_item>
- <combo_item name="Anyone">
- Chiunque
- </combo_item>
- <combo_item name="Specificuser:">
- Utente specifico:
- </combo_item>
+ <combo_box.item name="--selectone--" label="selezionane uno --"/>
+ <combo_box.item name="Anyone" label="Chiunque"/>
+ <combo_box.item name="Specificuser:" label="Utente specifico:"/>
</combo_box>
<button label="Seleziona..." name="sell_to_select_agent"/>
<text name="sell_objects_label">
@@ -55,12 +49,8 @@ terreno:
cambieranno proprietario.
</text>
<radio_group name="sell_objects" bottom_delta="-58" >
- <radio_item name="no">
- No, voglio mantenere la proprietà degli oggetti
- </radio_item>
- <radio_item name="yes">
- Si, vendi gli oggetti con la terra
- </radio_item>
+ <radio_item name="no" label="No, voglio mantenere la proprietà degli oggetti" />
+ <radio_item name="yes" label="Si, vendi gli oggetti con la terra" />
</radio_group>
<button label="Mostra oggetti" name="show_objects"/>
<text name="nag_message_label">
diff --git a/indra/newview/skins/default/xui/it/floater_settings_debug.xml b/indra/newview/skins/default/xui/it/floater_settings_debug.xml
index 51d0f756f9..6dd1b7978d 100644
--- a/indra/newview/skins/default/xui/it/floater_settings_debug.xml
+++ b/indra/newview/skins/default/xui/it/floater_settings_debug.xml
@@ -1,12 +1,8 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<floater name="settings_debug" title="Configurazioni per il debug">
<combo_box name="boolean_combo">
- <combo_item name="TRUE">
- VERO
- </combo_item>
- <combo_item name="FALSE">
- FALSO
- </combo_item>
+ <combo_box.item name="TRUE" label="VERO"/>
+ <combo_box.item name="FALSE" label="FALSO"/>
</combo_box>
<color_swatch label="Colore" name="color_swatch"/>
<spinner label="x" name="val_spinner_1"/>
diff --git a/indra/newview/skins/default/xui/it/floater_snapshot.xml b/indra/newview/skins/default/xui/it/floater_snapshot.xml
index 5999bad514..808158ff7e 100644
--- a/indra/newview/skins/default/xui/it/floater_snapshot.xml
+++ b/indra/newview/skins/default/xui/it/floater_snapshot.xml
@@ -4,15 +4,9 @@
Destinazione della fotografia
</text>
<radio_group label="Tipo di fotografia" name="snapshot_type_radio" width="228">
- <radio_item name="postcard">
- Invia via email
- </radio_item>
- <radio_item name="texture">
- Salva nel tuo inventario ([AMOUNT] L$)
- </radio_item>
- <radio_item name="local">
- Salva sul tuo disco rigido
- </radio_item>
+ <radio_item name="postcard" label="Invia via email" />
+ <radio_item name="texture" label="Salva nel tuo inventario ([AMOUNT] L$)" />
+ <radio_item name="local" label="Salva sul tuo pc" />
</radio_group>
<text name="file_size_label">
Grandezza del file: [SIZE] KB
@@ -21,12 +15,8 @@
<button label="Invia" name="send_btn"/>
<button label="Salva ([AMOUNT] L$)" name="upload_btn"/>
<flyout_button label="Salva" name="save_btn" tool_tip="Salva l&apos;immagine come file" >
- <flyout_button_item name="save_item">
- Salva
- </flyout_button_item>
- <flyout_button_item name="saveas_item">
- Salva come...
- </flyout_button_item>
+ <flyout_button_item name="save_item" label="Salva"/>
+ <flyout_button_item name="saveas_item" label="Salva come..."/>
</flyout_button>
<button label="Annulla" name="discard_btn"/>
<button label="Espandi &gt;&gt;" name="more_btn" tool_tip="Opzioni avanzate"/>
@@ -38,75 +28,33 @@
Formato
</text>
<combo_box label="Risoluzione" name="postcard_size_combo">
- <combo_item name="CurrentWindow">
- Finestra corrente
- </combo_item>
- <combo_item name="640x480">
- 640x480
- </combo_item>
- <combo_item name="800x600">
- 800x600
- </combo_item>
- <combo_item name="1024x768">
- 1024x768
- </combo_item>
- <combo_item name="Custom">
- Personalizzata
- </combo_item>
+ <combo_box.item name="CurrentWindow" label="Finestra corrente"/>
+ <combo_box.item name="640x480" label="640x480"/>
+ <combo_box.item name="800x600" label="800x600"/>
+ <combo_box.item name="1024x768" label="1024x768"/>
+ <combo_box.item name="Custom" label="Personalizzata"/>
</combo_box>
<combo_box label="Risoluzione" name="texture_size_combo">
- <combo_item name="CurrentWindow">
- Finestra corrente
- </combo_item>
- <combo_item name="Small(128x128)">
- Piccola (128x128)
- </combo_item>
- <combo_item name="Medium(256x256)">
- Media (256x256)
- </combo_item>
- <combo_item name="Large(512x512)">
- Larga (512x512)
- </combo_item>
- <combo_item name="Custom">
- Personalizzata
- </combo_item>
+ <combo_box.item name="CurrentWindow" label="Finestra corrente"/>
+ <combo_box.item name="Small(128x128)" label="Piccola (128x128)"/>
+ <combo_box.item name="Medium(256x256)" label="Media (256x256)"/>
+ <combo_box.item name="Large(512x512)" label="Larga (512x512)"/>
+ <combo_box.item name="Custom" label="Personalizzata"/>
</combo_box>
<combo_box label="Risoluzione" name="local_size_combo">
- <combo_item name="CurrentWindow">
- Finestra corrente
- </combo_item>
- <combo_item name="320x240">
- 320x240
- </combo_item>
- <combo_item name="640x480">
- 640x480
- </combo_item>
- <combo_item name="800x600">
- 800x600
- </combo_item>
- <combo_item name="1024x768">
- 1024x768
- </combo_item>
- <combo_item name="1280x1024">
- 1280x1024
- </combo_item>
- <combo_item name="1600x1200">
- 1600x1200
- </combo_item>
- <combo_item name="Custom">
- Personalizzata
- </combo_item>
+ <combo_box.item name="CurrentWindow" label="Finestra corrente"/>
+ <combo_box.item name="320x240" label="320x240"/>
+ <combo_box.item name="640x480" label="640x480"/>
+ <combo_box.item name="800x600" label="800x600"/>
+ <combo_box.item name="1024x768" label="1024x768"/>
+ <combo_box.item name="1280x1024" label="1280x1024"/>
+ <combo_box.item name="1600x1200" label="1600x1200"/>
+ <combo_box.item name="Custom" label="Personalizzata"/>
</combo_box>
<combo_box label="Formato" name="local_format_combo">
- <combo_item name="PNG">
- PNG
- </combo_item>
- <combo_item name="JPEG">
- JPEG
- </combo_item>
- <combo_item name="BMP">
- BMP
- </combo_item>
+ <combo_box.item name="PNG" label="PNG"/>
+ <combo_box.item name="JPEG" label="JPEG"/>
+ <combo_box.item name="BMP" label="BMP"/>
</combo_box>
<spinner label="Larghezza" name="snapshot_width" label_width="58" width="116"/>
<spinner label="Altezza" name="snapshot_height" label_width="41" width="101" left="130"/>
@@ -116,15 +64,9 @@
Fotografa:
</text>
<combo_box label="Layer dell&apos;immagine" name="layer_types" left="68" width="165">
- <combo_item name="Colors">
- Colori
- </combo_item>
- <combo_item name="Depth">
- Profondità
- </combo_item>
- <combo_item name="ObjectMattes">
- Colori primari degli oggetti
- </combo_item>
+ <combo_box.item name="Colors" label="Colori"/>
+ <combo_box.item name="Depth" label="Profondità"/>
+ <combo_box.item name="ObjectMattes" label="Colori primari degli oggetti"/>
</combo_box>
<check_box label="Mostra l&apos;interfaccia nella fotografia" name="ui_check"/>
<check_box bottom_delta="-17" label="Mostra i dispositivi indossati nella foto" name="hud_check"/>
diff --git a/indra/newview/skins/default/xui/it/floater_tools.xml b/indra/newview/skins/default/xui/it/floater_tools.xml
index c7c5890336..3c79cd8829 100644
--- a/indra/newview/skins/default/xui/it/floater_tools.xml
+++ b/indra/newview/skins/default/xui/it/floater_tools.xml
@@ -78,7 +78,7 @@
Oggetti selezionati: [COUNT]
</text>
<text name="prim_count" left="134">
- primitive: [COUNT]
+ primitivi: [COUNT]
</text>
<tab_container name="Object Info Tabs" tab_max_width="150" tab_min_width="30" width="288">
<panel label="Generale" name="General">
diff --git a/indra/newview/skins/default/xui/it/floater_tos.xml b/indra/newview/skins/default/xui/it/floater_tos.xml
index 671135b058..12b6021b5b 100644
--- a/indra/newview/skins/default/xui/it/floater_tos.xml
+++ b/indra/newview/skins/default/xui/it/floater_tos.xml
@@ -4,7 +4,7 @@
<button label="Annulla" label_selected="Annulla" name="Cancel"/>
<check_box label="Accetto i Termini di Servizio" name="agree_chk"/>
<text name="tos_heading">
- Leggi attentamente i seguenti Termini di Servizio. Per continuare ad entrare in Second Life,
+ Leggi attentamente i seguenti Termini di Servizio. Per continuare ad entrare in [SECOND_LIFE],
devi accettare l&apos;accordo.
</text>
<text_editor name="tos_text">
diff --git a/indra/newview/skins/default/xui/it/floater_world_map.xml b/indra/newview/skins/default/xui/it/floater_world_map.xml
index 8d58b7df3e..9b2fc5aff1 100644
--- a/indra/newview/skins/default/xui/it/floater_world_map.xml
+++ b/indra/newview/skins/default/xui/it/floater_world_map.xml
@@ -30,14 +30,10 @@
<check_box label="Adult" name="event_adult_chk"/>
<icon bottom="-200" name="avatar_icon" />
<combo_box label="Amici Online" name="friend combo" tool_tip="Amici da mostrare sulla mappa">
- <combo_item name="none_selected">
- Amici Online
- </combo_item>
+ <combo_box.item name="none_selected" label="Amici Online"/>
</combo_box>
<combo_box label="Landmark" name="landmark combo" tool_tip="Landmarks da mostrare sulla mappa">
- <combo_item name="none_selected">
- Landmark
- </combo_item>
+ <combo_box.item name="none_selected" label="Landmark"/>
</combo_box>
<line_editor label="Cerca per nome di regione" name="location" tool_tip="Scrivi il nome di una regione"/>
<button label="Cerca" name="DoSearch" tool_tip="Cerca regione"/>
@@ -58,6 +54,6 @@
<button font="SansSerifSmall" left_delta="91" width="135" label="Mostra destinazione" label_selected="Mostra destinazione" name="Show Destination" tool_tip="Centra la mappa sul luogo prescelto"/>
<button font="SansSerifSmall" label="Pulisci" label_selected="Pulisci" name="Clear" tool_tip="Togli traccia"/>
<button font="SansSerifSmall" left_delta="91" width="135" label="Mostra la mia posizione" label_selected="Mostra la mia posizione" name="Show My Location" tool_tip="Centra la mappa alla posizione del tuo avatar"/>
- <button font="SansSerifSmall" label="Copia lo SLURL negli appunti" name="copy_slurl" tool_tip="Copia l&apos;attuale posizione quale SLURL utilizzabile nel web."/>
+ <button font="SansSerifSmall" label="Copia lo SLurl negli appunti" name="copy_slurl" tool_tip="Copia l&apos;attuale posizione quale SLurl utilizzabile nel web."/>
<slider label="Zoom" name="zoom slider"/>
</floater>
diff --git a/indra/newview/skins/default/xui/it/language_settings.xml b/indra/newview/skins/default/xui/it/language_settings.xml
new file mode 100644
index 0000000000..71418d446a
--- /dev/null
+++ b/indra/newview/skins/default/xui/it/language_settings.xml
@@ -0,0 +1,55 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<!-- This file contains strings that used to be hardcoded in the source.-->
+<strings>
+
+ <!-- Locale Information -->
+ <string name="MicrosoftLocale">english</string>
+ <string name="DarwinLocale">C</string>
+ <string name="LinuxLocale">C</string>
+
+ <!--
+ datetimeToCodes["wkday"] = "%a"; // Thu
+ datetimeToCodes["weekday"] = "%A"; // Thursday
+ datetimeToCodes["year4"] = "%Y"; // 2009
+ datetimeToCodes["year"] = "%Y"; // 2009
+ datetimeToCodes["year2"] = "%y"; // 09
+ datetimeToCodes["mth"] = "%b"; // Aug
+ datetimeToCodes["month"] = "%B"; // August
+ datetimeToCodes["mthnum"] = "%m"; // 08
+ datetimeToCodes["day"] = "%d"; // 31
+ datetimeToCodes["hour24"] = "%H"; // 14
+ datetimeToCodes["hour"] = "%H"; // 14
+ datetimeToCodes["hour12"] = "%I"; // 02
+ datetimeToCodes["min"] = "%M"; // 59
+ datetimeToCodes["ampm"] = "%p"; // AM
+ datetimeToCodes["second"] = "%S"; // 59
+ datetimeToCodes["timezone"] = "%Z"; // PST
+ -->
+
+ <string name="TimeHour">hour,datetime,slt</string>
+ <string name="TimeMin">min,datetime,slt</string>
+ <string name="TimeYear">year,datetime,slt</string>
+ <string name="TimeDay">day,datetime,slt</string>
+ <string name="TimeMonth">mthnum,datetime,slt</string>
+ <string name="TimeWeek">wkday,datetime,slt</string>
+ <string name="TimeAMPM">ampm,datetime,slt</string>
+ <string name="TimeHour12">hour12,datetime,slt</string>
+
+ <string name="LTimeMthNum">mthnum,datetime,local</string>
+ <string name="LTimeWeek">wkday,datetime,local</string>
+ <string name="LTimeMonth">mth,datetime,local</string>
+ <string name="LTimeDay">day,datetime,local</string>
+ <string name="LTimeSec">second,datetime,local</string>
+ <string name="LTimeHour">hour,datetime,local</string>
+ <string name="LTimeMin">min,datetime,local</string>
+ <string name="LTimeYear">year,datetime,local</string>
+
+ <string name="UTCTimeWeek">weekday,datetime,utc</string>
+ <string name="UTCTimeDay">day,datetime,utc</string>
+ <string name="UTCTimeMth">mth,datetime,utc</string>
+ <string name="UTCTimeYr">year,datetime,utc</string>
+ <string name="UTCTimeHr">hour,datetime,utc</string>
+ <string name="UTCTimeMin">min,datetime,utc</string>
+ <string name="UTCTimeSec">second,datetime,utc</string>
+ <string name="UTCTimeTimezone">timezone,datetime,utc</string>
+</strings>
diff --git a/indra/newview/skins/default/xui/it/menu_login.xml b/indra/newview/skins/default/xui/it/menu_login.xml
index 45ee43102a..44a801d273 100644
--- a/indra/newview/skins/default/xui/it/menu_login.xml
+++ b/indra/newview/skins/default/xui/it/menu_login.xml
@@ -7,7 +7,7 @@
<menu_item_call label="Preferenze...." name="Preferences..."/>
</menu>
<menu label="Aiuto" name="Help">
- <menu_item_call label="Aiuto di Second Life" name="Second Life Help"/>
- <menu_item_call label="Informazioni su Second Life..." name="About Second Life..."/>
+ <menu_item_call label="Aiuto di [SECOND_LIFE]" name="Second Life Help"/>
+ <menu_item_call label="Informazioni su [APP_NAME]..." name="About Second Life..."/>
</menu>
</menu_bar>
diff --git a/indra/newview/skins/default/xui/it/menu_viewer.xml b/indra/newview/skins/default/xui/it/menu_viewer.xml
index 5741b3931d..0010f42a12 100644
--- a/indra/newview/skins/default/xui/it/menu_viewer.xml
+++ b/indra/newview/skins/default/xui/it/menu_viewer.xml
@@ -181,7 +181,7 @@
<menu_item_call label="Disattiva gli script nella selezione" name="Set Scripts to Not Running in Selection"/>
</menu>
<menu label="Aiuto" name="Help">
- <menu_item_call label="Aiuto di Secondlife" name="Second Life Help"/>
+ <menu_item_call label="Aiuto di [SECOND_LIFE]" name="Second Life Help"/>
<menu_item_call label="Tutorial" name="Tutorial"/>
<menu_item_separator label="-----------" name="separator"/>
<menu_item_call label="Blog ufficiale Linden..." name="Official Linden Blog..."/>
@@ -202,6 +202,6 @@
<menu_item_separator label="-----------" name="separator9"/>
<menu_item_call label="Segnala un bug..." name="Report Bug..."/>
</menu>
- <menu_item_call label="Informazioni su Second Life..." name="About Second Life..."/>
+ <menu_item_call label="Informazioni su [APP_NAME]..." name="About Second Life..."/>
</menu>
</menu_bar>
diff --git a/indra/newview/skins/default/xui/it/notifications.xml b/indra/newview/skins/default/xui/it/notifications.xml
index cc4a3e305a..36fa02978a 100644
--- a/indra/newview/skins/default/xui/it/notifications.xml
+++ b/indra/newview/skins/default/xui/it/notifications.xml
@@ -6,6 +6,9 @@
<global name="alwayschoose">
Scegli sempre questa opzione
</global>
+ <global name="implicitclosebutton">
+ Chiudi
+ </global>
<template name="okbutton">
<form>
<button
@@ -71,7 +74,7 @@
</form>
</template>
<notification functor="GenericAcknowledge" label="Messaggio di allerta sconosciuto" name="MissingAlert">
- La tua versione di Second Life non sa come visualizzare il messaggio di allerta appena ricevuto.
+ La tua versione di [APP_NAME] non sa come visualizzare il messaggio di allerta appena ricevuto.
Dettagli dell&apos;errore: il messaggio di allerta &apos;[_NAME]&apos; non è stato trovato in notifications.xml.
<usetemplate name="okbutton" yestext="OK"/>
@@ -94,7 +97,7 @@ Dettagli dell&apos;errore: il messaggio di allerta &apos;[_NAME]&apos; non è st
<usetemplate name="okcancelbuttons" notext="Annulla" yestext="Si"/>
</notification>
<notification name="BadInstallation">
- Si è verificato un errore durante l&apos;aggiornamento di Second Life. Scarica l&apos;ultima versione da secondlife.com.
+ Si è verificato un errore durante l&apos;aggiornamento di [APP_NAME]. Scarica l&apos;ultima versione da secondlife.com.
<usetemplate
name="okbutton"
yestext="OK"/>
@@ -138,12 +141,12 @@ Scegli solo un oggetto e riprova.
<usetemplate canceltext="Annulla" name="yesnocancelbuttons" notext="Non Salvare" yestext="Salva Tutto"/>
</notification>
<notification name="GrantModifyRights">
- Dare i diritti di modifica ad un altro residente gli consente di cambiare, cancellare o prendere QUALUNQUE oggetto che hai in Second Life. Fai MOLTA attenzione quando concedi questo permesso.
+ Dare i diritti di modifica ad un altro residente gli consente di cambiare, cancellare o prendere QUALUNQUE oggetto che hai in [SECOND_LIFE]. Fai MOLTA attenzione quando concedi questo permesso.
Vuoi davvero dare i diritti di modifica a [FIRST_NAME] [LAST_NAME]?
<usetemplate name="okcancelbuttons" notext="No" yestext="Si"/>
</notification>
<notification name="GrantModifyRightsMultiple">
- Dare i diritti di modifica ad un altro residente gli consente di cambiare QUALUNQUE oggetto che hai in Second Life. Fai MOLTA attenzione quando concedi questo permesso.
+ Dare i diritti di modifica ad un altro residente gli consente di cambiare QUALUNQUE oggetto che hai in [SECOND_LIFE]. Fai MOLTA attenzione quando concedi questo permesso.
Vuoi davvero dare i diritti di modifica ai residenti selezionati?
<usetemplate name="okcancelbuttons" notext="No" yestext="Si"/>
</notification>
@@ -232,7 +235,7 @@ Marcando questo campo si mostrerà:
<notification name="ClickPartnerHelpAvatar">
Puoi proporre o cancellare una partnership con un altro/a residente attraverso il sito web [SECOND_LIFE].
-Vai al sito web di Second Life per ulteriori informazioni sulla partnership?
+Vai al sito web di [SECOND_LIFE] per ulteriori informazioni sulla partnership?
<usetemplate name="okcancelbuttons" notext="Annulla" yestext="Vai alla pagina"/>
</notification>
<notification name="ClickUploadHelpPermissions">
@@ -270,7 +273,7 @@ Il tuo prezzo di vendità è [SALE_PRICE]L$ ed è autorizzato alla vendita a [NA
<usetemplate name="okcancelbuttons" notext="Annulla" yestext="OK"/>
</notification>
<notification name="ConfirmLandSaleToAnyoneChange">
- ATTENZIONE: Cliccando &apos;vendi a tutti&apos; rende il tuo terrono disponibile all&apos;intera comunità di Second Life, anche non in questa regione.
+ ATTENZIONE: Cliccando &apos;vendi a tutti&apos; rende il tuo terrono disponibile all&apos;intera comunità di [SECOND_LIFE], anche non in questa regione.
Il terreno selezionato di [LAND_SIZE] m² sta per essere messo in vendita.
Il tuo prezzo di vendità è [SALE_PRICE]L$ ed è autorizzato alla vendita a [NAME].
@@ -417,17 +420,17 @@ Non ci sono rimborsi per la tariffa pagata.
<usetemplate name="okcancelbuttons" notext="Annulla" yestext="OK"/>
</notification>
<notification name="CacheWillClear">
- La Cache verrà pulita dopo il riavvio di [SECOND_LIFE].
+ La Cache verrà pulita dopo il riavvio di [APP_NAME].
</notification>
<notification name="CacheWillBeMoved">
- La Cache verrà traslocata dopo il riavvio di [SECOND_LIFE].
+ La Cache verrà traslocata dopo il riavvio di [APP_NAME].
Nota: Questo pulirà la cache.
</notification>
<notification name="ChangeConnectionPort">
- Le impostazioni delle porte avranno effetto dopo il riavvio di [SECOND_LIFE].
+ Le impostazioni delle porte avranno effetto dopo il riavvio di [APP_NAME].
</notification>
<notification name="ChangeSkin">
- La nuova pelle apparità dopo il riavvio di [SECOND_LIFE].
+ La nuova pelle apparità dopo il riavvio di [APP_NAME].
</notification>
<notification name="GoToAuctionPage">
Vai alla pagina web [SECOND_LIFE] per vedere i dettagli dell&apos;asta oppure fai un&apos;offerta?
@@ -486,7 +489,7 @@ L&apos;oggetto potrebbe essere troppo lontano oppure essere stato cancellato.
Non è stato possibile scrivere il file [[FILE]]
</notification>
<notification name="UnsupportedHardware">
- Attenzione: Il tuo sistema non soddisfa i requisiti minimi per il funzionamento Second Life. Se continui ad usare Second Life, potresti osservare una lentezza eccessiva. Sfortunatamente non possiamo fornire supporto tecnico per configurazioni di sistema non supportate.
+ Attenzione: Il tuo sistema non soddisfa i requisiti minimi per il funzionamento [APP_NAME]. Se continui ad usare [APP_NAME], potresti osservare una lentezza eccessiva. Sfortunatamente non possiamo fornire supporto tecnico per configurazioni di sistema non supportate.
MINSPECS
Vuoi visitare [_URL] per maggiori informazioni?
@@ -497,14 +500,14 @@ Vuoi visitare [_URL] per maggiori informazioni?
</notification>
<notification name="UnknownGPU">
Il tuo sistema contiene una scheda grafica che attualmente non supportiamo.
-Questo succede spesso con nuovi prodotti che non siamo riusciti a verificare. Probabilmente Second Life funzionerà correttamente ma forse dovrai modificare le impostazioni grafiche in modo appropriato.
+Questo succede spesso con nuovi prodotti che non siamo riusciti a verificare. Probabilmente [APP_NAME] funzionerà correttamente ma forse dovrai modificare le impostazioni grafiche in modo appropriato.
(Modifica &gt; Preferenze &gt; Grafica).
<form name="form">
<ignore name="ignore" text="Quando sto valutando una scheda grafica sconosciuta"/>
</form>
</notification>
<notification name="DisplaySettingsNoShaders">
- [SECOND_LIFE] si è bloccata mentre stava inizializzando i driver grafici.
+ [APP_NAME] si è bloccata mentre stava inizializzando i driver grafici.
La qualità grafica verrà impostata al valore basso per evitare alcuni degli errori più comuni con i driver.
Questo però disabiliterà alcune funzioni grafiche.
Ti raccomandiamo di aggiornare i driver della tua scheda grafica.
@@ -788,7 +791,7 @@ Nessun terreno selezionato.
Non riesco a trovare la regione dove è situato il terreno.
</notification>
<notification name="CannotCloseFloaterBuyLand">
- Non puoi chiudere la finestra di Acquisto Terreno finchè Second Life non stima il prezzo di questa transazione.
+ Non puoi chiudere la finestra di Acquisto Terreno finchè [APP_NAME] non stima il prezzo di questa transazione.
</notification>
<notification name="CannotDeedLandNothingSelected">
Impossibile cedere il terreno:
@@ -959,7 +962,7 @@ Se questo problema persiste, clicca sul menu a tendina &apos;Strumenti &gt; Segn
<notification name="YouHaveBeenLoggedOut">
Sei stato sconnesso da [SECOND_LIFE]:
[MESSAGE]
-Puoi ancora vedere i tuoi IM e la chat cliccando &apos;Vedi IM &amp; Chat&apos;. Altrimenti, clicca &apos;Esci&apos; per uscire immediatamente da [SECOND_LIFE].
+Puoi ancora vedere i tuoi IM e la chat cliccando &apos;Vedi IM &amp; Chat&apos;. Altrimenti, clicca &apos;Esci&apos; per uscire immediatamente da [APP_NAME].
<usetemplate name="okcancelbuttons" notext="Esci" yestext="Vedi IM &amp; Chat"/>
</notification>
<notification name="OnlyOfficerCanBuyLand">
@@ -1131,14 +1134,14 @@ Puoi usare [SECOND_LIFE] normalmente e gli altri utenti ti vedranno correttament
</form>
</notification>
<notification name="FirstRun">
- L&apos;installazione di [SECOND_LIFE] è completata.
+ L&apos;installazione di [APP_NAME] è completata.
Se questa è la prima volta che usi [SECOND_LIFE], avari bisogno di creare un account prima di poterti collegare.
Vai su www.secondlife.com per creare un nuovo account?
<usetemplate name="okcancelbuttons" notext="Continua" yestext="Nuovo Account..."/>
</notification>
<notification name="LoginPacketNeverReceived">
- Ci sono stati problemi durante la connessione. Potrebbero esserci problemi con la tua connessione ad internet oppure con i server di Second Life.
+ Ci sono stati problemi durante la connessione. Potrebbero esserci problemi con la tua connessione ad internet oppure con i server di [SECOND_LIFE].
Puoi controllare la tua connessione internet e riprovare fra qualche minuto, oppure cliccare su Aiuto per collegarti al nostro sito di supporto, oppure cliccare teleporta per cercare di teleportarti a casa.
<form name="form">
@@ -1241,33 +1244,33 @@ Imposta l&apos;oggetto per la vendita e riprova.
[DOWNLOAD_PATH].
</notification>
<notification name="DownloadWindowsMandatory">
- E&apos; disponibile una nuova versione di [SECOND_LIFE].
+ E&apos; disponibile una nuova versione di [APP_NAME].
[MESSAGE]
-Devi scaricare questo aggiornamento per usare [SECOND_LIFE].
+Devi scaricare questo aggiornamento per usare [APP_NAME].
<usetemplate name="okcancelbuttons" notext="Esci" yestext="Scarica l&apos;aggiornamento"/>
</notification>
<notification name="DownloadWindows">
- E&apos; disponibile una versione aggiornata di [SECOND_LIFE].
+ E&apos; disponibile una versione aggiornata di [APP_NAME].
[MESSAGE]
Questo aggiornamento non è obbligatorio, ma ti suggeriamo di installarlo per migliorarne le prestazioni e la stabilità.
<usetemplate name="okcancelbuttons" notext="Continua" yestext="Scarica l&apos;aggiornamento"/>
</notification>
<notification name="DownloadWindowsReleaseForDownload">
- E&apos; disponibile una versione aggiornata di [SECOND_LIFE].
+ E&apos; disponibile una versione aggiornata di [APP_NAME].
[MESSAGE]
Questo aggiornamento non è obbligatorio, ma ti suggeriamo di installarlo per migliorarne le prestazioni e la stabilità.
<usetemplate name="okcancelbuttons" notext="Continua" yestext="Scarica l&apos;aggiornamento"/>
</notification>
<notification name="DownloadMacMandatory">
- E&apos; disponibile una nuova versione di [SECOND_LIFE].
+ E&apos; disponibile una nuova versione di [APP_NAME].
[MESSAGE]
-Devi scaricare questo aggiornamento per usare [SECOND_LIFE].
+Devi scaricare questo aggiornamento per usare [APP_NAME].
Vuoi avviarne lo scaricamento nella tua cartella applicazioni?
<usetemplate name="okcancelbuttons" notext="Esci" yestext="Scarica l&apos;aggiornamento"/>
</notification>
<notification name="DownloadMac">
- E&apos; disponibile una versione aggiornata di [SECOND_LIFE].
+ E&apos; disponibile una versione aggiornata di [APP_NAME].
[MESSAGE]
Questo aggiornamento non è obbligatorio, ma ti suggeriamo di installarlo per migliorarne le prestazioni e la stabilità.
@@ -1275,7 +1278,7 @@ Vuoi avviarne lo scaricamento nella tua cartella applicazioni?
<usetemplate name="okcancelbuttons" notext="Continua" yestext="Scarica l&apos;aggiornamento"/>
</notification>
<notification name="DownloadMacReleaseForDownload">
- E&apos; disponibile una versione aggiornata di [SECOND_LIFE].
+ E&apos; disponibile una versione aggiornata di [APP_NAME].
[MESSAGE]
Questo aggiornamento non è obbligatorio, ma ti suggeriamo di installarlo per migliorarne le prestazioni e la stabilità.
@@ -1718,7 +1721,7 @@ Una volta impostato, fai attenzione che abbassare il bonus può causare la cance
Impostazione base: 1.0
</notification>
<notification label="Categoria di accesso" name="HelpRegionMaturity">
- Imposta la categoria di accesso della regione, come mostrato nella barra dei menu nella parte superiore dello schermo di qualsiasi residente e nelle tooltip sulla mappa di Second Life, quando il cursore si muove su questa regione. Questa impostazione influenza anche l&apos;accesso a questa regione e i risultati della ricerca. Altri residenti possono entrare solo in regioni o visualizzare risultati della ricerca con la stessa categoria di accesso che hanno scelto nella loro preferenze.
+ Imposta la categoria di accesso della regione, come mostrato nella barra dei menu nella parte superiore dello schermo di qualsiasi residente e nelle tooltip sulla mappa di [SECOND_LIFE], quando il cursore si muove su questa regione. Questa impostazione influenza anche l&apos;accesso a questa regione e i risultati della ricerca. Altri residenti possono entrare solo in regioni o visualizzare risultati della ricerca con la stessa categoria di accesso che hanno scelto nella loro preferenze.
Può trascorrere un po&apos; di tempo prima che questa modifica si rifletta sulla mappa.
</notification>
@@ -1891,7 +1894,7 @@ Lasciandolo vuoto causerà l&apos;invio delle segnalazioni di abuso soltanto ai
Impostazione base: spento
</notification>
<notification label="Versione voice non compatibile" name="VoiceVersionMismatch">
- Questa versione di Second Life non è compatibile con le impostazioni di voice chat di questa regione. Per poter fare funzionare correttamente la chat voce devi aggiornare Second Life.
+ Questa versione di [APP_NAME] non è compatibile con le impostazioni di voice chat di questa regione. Per poter fare funzionare correttamente la chat voce devi aggiornare [APP_NAME].
</notification>
<notification label="Regolamento della proprietà" name="HelpEstateCovenant">
Impostare un regolamento della proprietà ti consente di vendere i terreni all&apos;interno di quella proprietà. Se non imposti un regolamento, non puoi vendere i terreni. La notecard per il tuo regolamente può essere vuota se non desideri applicare nessuna regola o informare i compratori di cose inerenti la terra, prima dell&apos;acquisto.
@@ -2006,16 +2009,16 @@ Trasferisci gli elementi nell&apos;inventario?
Non ci sono elementi in questo oggetto che tu possa copiare.
</notification>
<notification name="WebLaunchAccountHistory">
- Vai nel sito web di Second Life per vedere il tuo estratto conto?
+ Vai nel sito web di [SECOND_LIFE] per vedere il tuo estratto conto?
<usetemplate ignoretext="Quando carichi la pagina web dell&apos;estratto conto." name="okcancelignore" notext="Annulla" yestext="Vai alla pagina"/>
</notification>
<notification name="ClickOpenF1Help">
- Visita il sito di supporto di Second Life?
- <usetemplate ignoretext="Quando visiti il sito del supporto di Second Life." name="okcancelignore" notext="Annulla" yestext="Vai"/>
+ Visita il sito di supporto di [SECOND_LIFE]?
+ <usetemplate ignoretext="Quando visiti il sito del supporto di [SECOND_LIFE]." name="okcancelignore" notext="Annulla" yestext="Vai"/>
</notification>
<notification name="ConfirmQuit">
Confermi di voler uscire?
- <usetemplate ignoretext="Quando esci da Second Life." name="okcancelignore" notext="Continua" yestext="Esci"/>
+ <usetemplate ignoretext="Quando esci da [APP_NAME]." name="okcancelignore" notext="Continua" yestext="Esci"/>
</notification>
<notification name="HelpReportAbuseEmailLL">
Usa questo strumento per segnalare violazioni ai Termini di Servizio e agli standard della Comunità. Vedi:
@@ -2035,7 +2038,7 @@ Come servizio ai residenti e ai visitatori, il proprietario della regione in cui
Il proprietario della regione risolverà le segnalazione basandosi sulle regole locali di questa regione così come sono indicate dal regolamento della proprietà.
(Puoi vedere il regolamento andando sul menu Mondo e selezionando Informazioni sul terreno.)
-La risoluzione di questa segnalazione verrà applicata solo in questa regione; L&apos;accesso dei residenti ad altre aree di Second Life non verrà influenzato dal risultato di questa segnalazione. Soltanto i Linden Lab possono restringere l&apos;accesso alla totalità di Second Life.
+La risoluzione di questa segnalazione verrà applicata solo in questa regione; L&apos;accesso dei residenti ad altre aree di [SECOND_LIFE] non verrà influenzato dal risultato di questa segnalazione. Soltanto i Linden Lab possono restringere l&apos;accesso alla totalità di [SECOND_LIFE].
</notification>
<notification name="HelpReportBug">
Usa questo strumento per segnalare *soltanto* caratteristiche tecniche che non funzionano come descitto o atteso, fornisci quanti più dettagli è possibile, Puoi rispondere all&apos;email automatica aggiungendo ulteriori dettagli sulla tua segnalazione.
@@ -2087,9 +2090,9 @@ Inserendo una descrizione accurata, ci aiuti a gestire ed elaborare le segnalazi
Sembra che stai segnalando un problema di furto di proprietà intellettuale. Cerca di essere sicuro che la tua segnalazione stia riportando correttamente:
-(1) Il processo di abuso. Puoi sottomettere una segnalazione di abuso se ritieni che un residente stia sfruttando il sistema di permessi di Second Life, per esempio, usando CopyBot oppure simili strumenti di copia, per rubare i diritti della proprietà intellettuale. L&apos;ufficio Abusi investigherà e deciderà delle azioni disciplinari adeguate per comportamenti che violano gli standard di comunità di Second Life o i Termini di Servizio. Si tenga però presente che l&apos;ufficio Abusi non gestisce e non risponde alle richieste di rimozione di contenuto da Second Life.
+(1) Il processo di abuso. Puoi sottomettere una segnalazione di abuso se ritieni che un residente stia sfruttando il sistema di permessi di [SECOND_LIFE], per esempio, usando CopyBot oppure simili strumenti di copia, per rubare i diritti della proprietà intellettuale. L&apos;ufficio Abusi investigherà e deciderà delle azioni disciplinari adeguate per comportamenti che violano gli standard di comunità di [SECOND_LIFE] o i Termini di Servizio. Si tenga però presente che l&apos;ufficio Abusi non gestisce e non risponde alle richieste di rimozione di contenuto da [SECOND_LIFE].
-(2) Il processo di rimozione DMCA o processo di rimozione dei contenuti. Per richiedere la rimozione di contenuto da Second Life, DEVI sottomettere una notifica valida di furto intellettuale come definito nella nostra politica DMCA che trovi a http://secondlife.com/corporate/dmca.php.
+(2) Il processo di rimozione DMCA o processo di rimozione dei contenuti. Per richiedere la rimozione di contenuto da [SECOND_LIFE], DEVI sottomettere una notifica valida di furto intellettuale come definito nella nostra politica DMCA che trovi a http://secondlife.com/corporate/dmca.php.
Se desideri egualmente continuare con il processo di abuso, chiudi questa finestra e termina di compilare la segnalazione. Potresti dover selezionare la categoria specifica &apos;CopyBot o Sfruttamento permessi&apos;.
@@ -2140,12 +2143,12 @@ Desideri abbandonare la modalità &apos;Occupato&apos; prima di completare quest
<usetemplate ignoretext="Quando cancelli la cartella degli oggetti perduti e ritrovati del tuo inventario." name="okcancelignore" notext="No" yestext="Si"/>
</notification>
<notification name="CopySLURL">
- Lo SLURL seguente è stato copiato nei tuoi appunti:
+ Lo SLurl seguente è stato copiato nei tuoi appunti:
[SLURL]
Lo puoi inserire in una pagina web per dare ad altri modo di accedere a questo posto o puoi provare a copiarla nella barra indirizzi del tuo browser web.
<form name="form">
- <ignore name="ignore" text="Quando copi uno SLURL negli appunti."/>
+ <ignore name="ignore" text="Quando copi uno SLurl negli appunti."/>
</form>
</notification>
<notification name="GraphicsPreferencesHelp">
@@ -2211,7 +2214,7 @@ Clicca &apos;Cielo avanzato&apos; per visualizzare un editor con le impostazioni
Clicca &apos;Acqua Avanzata&apos; per visualizzare un editor con le impostazini avanzate per l&apos;acqua.
</notification>
<notification name="HelpDayCycle">
- L&apos;editor del Ciclo Giorno/Notte permette di controllare il cielo durante il ciclo giornaliero di Second Life. Questo è il ciclo che è usato dal cursore dell&apos;editor base dell&apos;ambiente.
+ L&apos;editor del Ciclo Giorno/Notte permette di controllare il cielo durante il ciclo giornaliero di [SECOND_LIFE]. Questo è il ciclo che è usato dal cursore dell&apos;editor base dell&apos;ambiente.
L&apos;editor del ciclo giorno/notte funziona impostando i fotogrammi chiave. Questi sono nodi (rappresentati da tacche grige sul grafico temporale) che hanno delle preregolazioni associate del cielo. Man mano che l&apos;ora del giorno procede, il cielo di WindLight&apos;si anima&apos; interpolando i valori fra questi fotogrammi chiave.
@@ -2396,7 +2399,7 @@ D (Densità) controlla quanto gonfie o spezzettate appaiono le nuvole.
</notification>
<notification name="NotAgeVerified">
La tua età deve essere verificata per poter entrare in questo territorio.
-Vuoi visitare il sito di Second Life per verificare la tua eta?
+Vuoi visitare il sito di [SECOND_LIFE] per verificare la tua eta?
[_URL]
<url name="url" option="0">
@@ -2406,7 +2409,7 @@ Vuoi visitare il sito di Second Life per verificare la tua eta?
</notification>
<notification name="Cannot enter parcel: no payment info on file">
Questo terreno richiede che tu abbia registrato le tue informazioni di pagamento prima che tu possa accedervi.
-Vuoi visitare il sito di Second Life per impostarle?
+Vuoi visitare il sito di [SECOND_LIFE] per impostarle?
[_URL]
<url name="url" option="0">
@@ -2723,13 +2726,13 @@ Riprova tra qualche istante.
Impossibile creare la connessione in sospeso.
</notification>
<notification name="InternalUsherError">
- Si è verificato un errore interno durante il tentativo di trasportarti alla destinazione. Potrebbero esserci problemi in Second Life al momento.
+ Si è verificato un errore interno durante il tentativo di trasportarti alla destinazione. Potrebbero esserci problemi in [SECOND_LIFE] al momento.
</notification>
<notification name="NoGoodTPDestination">
Impossibile trovare una buona destinazione per il teletrasporto in questa regione.
</notification>
<notification name="InternalErrorRegionResolver">
- Si è verificato un errore interno durante il tentativo di risolvere le coordinate per la richiesta di teletrasporto. Può darsi che ci siano problemi in Second Life al momento.
+ Si è verificato un errore interno durante il tentativo di risolvere le coordinate per la richiesta di teletrasporto. Può darsi che ci siano problemi in [SECOND_LIFE] al momento.
</notification>
<notification name="NoValidLanding">
Non è stato trovato un punto di atterraggio valido.
@@ -2851,7 +2854,7 @@ Dall&apos;oggetto: [OBJECTNAME], di: [NAME]?
Impossibile trovare [TYPE] chiamato [DESC] nel database.
</notification>
<notification name="InvalidWearable">
- L&apos;oggetto che si sta tentando di indossare utilizza una funzione che il programma non riesce a leggere. Aggiorna la tua versione di Second Life per riuscire a indossare l&apos;oggetto.
+ L&apos;oggetto che si sta tentando di indossare utilizza una funzione che il programma non riesce a leggere. Aggiorna la tua versione di [APP_NAME] per riuscire a indossare l&apos;oggetto.
</notification>
<notification name="ScriptQuestion">
&apos;[OBJECTNAME]&apos;, un oggetto di proprietà di &apos;[NAME]&apos;, vorrebbe:
@@ -2956,8 +2959,8 @@ Gli oggetti flessibili non possono essere fisici e devano essere fantasma fino a
</notification>
<notification name="FirstDebugMenus">
Hai attivato il menu Avanzato.
-Questo menu contiene funzioni utili per gli sviluppatori per il debug di Second Life.
-Per attivare o disattivare questo menu su Windows premere Ctrl-Alt-D. Su Mac premere Cmd-Opt-Shift-D.
+Questo menu contiene funzioni utili per gli sviluppatori per il debug di [SECOND_LIFE].
+Per attivare o disattivare questo menu su Windows premere Ctrl-Alt-D. Su Mac premere &#8984;-Opt-D.
</notification>
<notification name="FirstSculptedPrim">
Si sta modificando uno sculpted prim.
@@ -3064,7 +3067,7 @@ Fai clic su Accetta per partecipare alla chiamata o su Rifiuta per rifiutare l&a
- La velocità della tua CPU non soddisfa i requisiti minimi.
</global>
<global name="UnsupportedGLRequirements">
- Sembra che tu non abbia i requisiti appropriati hardware per Second Life. Second Life ha bisogno di una scheda grafica OpenGL che abbia il supporto multitexture. Se ritieni di avere l&apos;hardware giusto verifica di avere installati i driver più aggiornati per la tua scheda grafica e gli aggiornamenti e service pack appropriati per il tuo sistema operativo.
+ Sembra che tu non abbia i requisiti appropriati hardware per [APP_NAME]. [APP_NAME] ha bisogno di una scheda grafica OpenGL che abbia il supporto multitexture. Se ritieni di avere l&apos;hardware giusto verifica di avere installati i driver più aggiornati per la tua scheda grafica e gli aggiornamenti e service pack appropriati per il tuo sistema operativo.
Se continui ad avere problemi, visita il sito: http://www.secondlife.com/support
</global>
diff --git a/indra/newview/skins/default/xui/it/panel_preferences_chat.xml b/indra/newview/skins/default/xui/it/panel_preferences_chat.xml
index 26ee03e0eb..8afcd74bf7 100644
--- a/indra/newview/skins/default/xui/it/panel_preferences_chat.xml
+++ b/indra/newview/skins/default/xui/it/panel_preferences_chat.xml
@@ -5,15 +5,9 @@
chat:
</text>
<radio_group name="chat_font_size">
- <radio_item name="radio">
- Piccolo
- </radio_item>
- <radio_item name="radio2">
- Medio
- </radio_item>
- <radio_item name="radio3">
- Grande
- </radio_item>
+ <radio_item name="radio" label="Piccolo" />
+ <radio_item name="radio2" label="Medio" />
+ <radio_item name="radio3" label="Grande" />
</radio_group>
<text name="text_box2">
Colore carattere chat:
diff --git a/indra/newview/skins/default/xui/it/panel_preferences_graphics1.xml b/indra/newview/skins/default/xui/it/panel_preferences_graphics1.xml
index f1c91e78e6..f9aaa58f09 100644
--- a/indra/newview/skins/default/xui/it/panel_preferences_graphics1.xml
+++ b/indra/newview/skins/default/xui/it/panel_preferences_graphics1.xml
@@ -9,21 +9,11 @@
Dimensione della finestra:
</text>
<combo_box name="windowsize combo">
- <combo_item name="640x480">
- 640x480
- </combo_item>
- <combo_item name="800x600">
- 800x600
- </combo_item>
- <combo_item name="720x480">
- 720x480 (NTSC)
- </combo_item>
- <combo_item name="768x576">
- 768x576 (PAL)
- </combo_item>
- <combo_item name="1024x768">
- 1024x768
- </combo_item>
+ <combo_box.item name="640x480" label="640x480"/>
+ <combo_box.item name="800x600" label="800x600"/>
+ <combo_box.item name="720x480" label="720x480 (NTSC)"/>
+ <combo_box.item name="768x576" label="768x576 (PAL)"/>
+ <combo_box.item name="1024x768" label="1024x768"/>
</combo_box>
<text name="DisplayResLabel">
Risoluzione del monitor:
@@ -32,18 +22,10 @@
Rapporto di visualizzazione:
</text>
<combo_box name="aspect_ratio" tool_tip="larghezza/altezza">
- <combo_item name="4:3(StandardCRT)">
- 4:3 (Monitor Standard)
- </combo_item>
- <combo_item name="5:4(1280x1024LCD)">
- 5:4 (1280x1024 LCD)
- </combo_item>
- <combo_item name="8:5(Widescreen)">
- 8:5 (Widescreen)
- </combo_item>
- <combo_item name="16:9(Widescreen)">
- 16:9 (Widescreen)
- </combo_item>
+ <combo_box.item name="4:3(StandardCRT)" label="4:3 (Monitor Standard)"/>
+ <combo_box.item name="5:4(1280x1024LCD)" label="5:4 (1280x1024 LCD)"/>
+ <combo_box.item name="8:5(Widescreen)" label="8:5 (Widescreen)"/>
+ <combo_box.item name="16:9(Widescreen)" label="16:9 (Widescreen)"/>
</combo_box>
<check_box label="Autoconfigurazione" name="aspect_auto_detect"/>
<text name="HigherText">
@@ -85,18 +67,10 @@
Dettaglio dei riflessi
</text>
<radio_group name="ReflectionDetailRadio">
- <radio_item name="0">
- Terreno ed alberi
- </radio_item>
- <radio_item name="1">
- Tutti gli aggetti statici
- </radio_item>
- <radio_item name="2">
- Tutti gli avatar e gli oggetti
- </radio_item>
- <radio_item name="3">
- Tutto
- </radio_item>
+ <radio_item name="0" label="Terreno ed alberi" />
+ <radio_item name="1" label="Tutti gli aggetti statici" />
+ <radio_item name="2" label="Tutti gli avatar e gli oggetti" />
+ <radio_item name="3" label="Tutto" />
</radio_group>
<text name="AvatarRenderingText">
Rendering dell&apos;avatar:
@@ -147,23 +121,15 @@
Dettagli illuminazione:
</text>
<radio_group name="LightingDetailRadio">
- <radio_item name="SunMoon">
- Solo il sole e la luna
- </radio_item>
- <radio_item name="LocalLights">
- Luci locali
- </radio_item>
+ <radio_item name="SunMoon" label="Solo il sole e la luna" />
+ <radio_item name="LocalLights" label="Luci locali" />
</radio_group>
<text name="TerrainDetailText">
Dettagli terreno:
</text>
<radio_group name="TerrainDetailRadio">
- <radio_item name="0">
- Bassi
- </radio_item>
- <radio_item name="2">
- Alti
- </radio_item>
+ <radio_item name="0" label="Bassi" />
+ <radio_item name="2" label="Alti" />
</radio_group>
<button label="Configurazione raccomandata" name="Defaults" left="110" width="190" />
<button label="Opzioni hardware" label_selected="Opzioni hardware" name="GraphicsHardwareButton"/>
diff --git a/indra/newview/skins/default/xui/it/panel_status_bar.xml b/indra/newview/skins/default/xui/it/panel_status_bar.xml
index 2403dce20e..dfaacb659e 100644
--- a/indra/newview/skins/default/xui/it/panel_status_bar.xml
+++ b/indra/newview/skins/default/xui/it/panel_status_bar.xml
@@ -27,8 +27,8 @@
<button label="" label_selected="" name="restrictpush" tool_tip="Vietato spingere"/>
<button label="" label_selected="" name="status_no_voice" tool_tip="Voice non disponibile qui"/>
<button label="" label_selected="" name="buyland" tool_tip="Compra questo terreno"/>
- <line_editor label="Cerca" name="search_editor" tool_tip="Cerca in Second Life"/>
- <button label="" label_selected="" name="search_btn" tool_tip="Cerca in Second Life"/>
+ <line_editor label="Cerca" name="search_editor" tool_tip="Cerca in [SECOND_LIFE]"/>
+ <button label="" label_selected="" name="search_btn" tool_tip="Cerca in [SECOND_LIFE]"/>
<string name="packet_loss_tooltip">
Perdita di pacchetti
</string>
diff --git a/indra/newview/skins/default/xui/it/strings.xml b/indra/newview/skins/default/xui/it/strings.xml
index 1cf12cbdca..37c003a07b 100644
--- a/indra/newview/skins/default/xui/it/strings.xml
+++ b/indra/newview/skins/default/xui/it/strings.xml
@@ -17,7 +17,7 @@
Un precedente tentativo di login è fallito. Tentativo di connessione [NUMBER]
</string>
<string name="LoginPrecaching">
- Sto caricando Second Life...
+ Sto caricando [SECOND_LIFE]...
</string>
<string name="LoginInitializingBrowser">
Inizializzazione del browser web incorporato...
diff --git a/indra/newview/skins/default/xui/ja/floater_about.xml b/indra/newview/skins/default/xui/ja/floater_about.xml
index 9306a6c6af..fb12e48c9a 100644
--- a/indra/newview/skins/default/xui/ja/floater_about.xml
+++ b/indra/newview/skins/default/xui/ja/floater_about.xml
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
-<floater name="floater_about" title="Second Lifeã«ã¤ã„ã¦">
+<floater name="floater_about" title="[APP_NAME]ã«ã¤ã„ã¦">
<text_editor name="credits_editor">
Second Lifeã¯ã€ Philipã€Tessaã€Andrewã€Coryã€Jamesã€Benã€Charã€Charlieã€Colinã€Danã€Danielã€Dougã€Ericã€Hamletã€Haneyã€Eveã€Hunterã€Ianã€Jeffã€Jenniferã€Jimã€Johnã€Leeã€Markã€Peterã€Phoenixã€Richardã€Robinã€Xenonã€Steveã€Tanyaã€Eddieã€Aviã€Frankã€Bruceã€Aaronã€Aliceã€Bobã€Debraã€Eileenã€Helenã€Janetã€Louieã€Leviathaniaã€Stefanã€Rayã€Kevinã€Tomã€Mikebã€MikeTã€Burgessã€Elenaã€Tracyã€Billã€Toddã€Ryanã€Zachã€Sarahã€Novaã€Timã€Stephanieã€Michaelã€Evanã€Nicolasã€Catherineã€Rachelleã€Daveã€Hollyã€Bubã€Kellyã€Magellanã€Ramziã€Donã€Sabinã€Jillã€Rheyaã€Jeskaã€Torleyã€Konaã€Callumã€Charityã€Ventrellaã€Jackã€Vektorã€Irisã€Chrisã€Nicoleã€Mickã€Reubenã€Blueã€Babbageã€Yedwabã€Deanaã€Laurenã€Brentã€Pathfinderã€Chadrickã€Altruimaã€Jesseã€Teenyã€Monroeã€Icculusã€Davidã€Tessã€Lizzieã€Patsyã€Isaacã€Lawrenceã€Cynã€Boã€Giaã€Annetteã€Mariusã€Tboneã€Jonathanã€Karenã€Ginsuã€Satokoã€Yukoã€Makikoã€Thomasã€Harryã€Sethã€Alexeiã€Brianã€Guyã€Runitaiã€Ethanã€Dataã€Corneliusã€Kennyã€Swissã€Zeroã€Natriaã€Wendyã€Stephenã€Teepleã€Thumperã€Lucyã€Deeã€Miaã€Lianaã€Warrenã€Brankaã€Auraã€beezã€Miloã€Hermiaã€Redã€Thraxã€Joeã€Sallyã€Magentaã€Moguraã€Paulã€Joseã€Rejeanã€Henrikã€Lexieã€Amberã€Loganã€Xanã€Noraã€Morpheusã€Donovanã€Leylaã€MichaelFrancisã€Beastã€Cubeã€Buckyã€Joshuaã€Stryfeã€Harmonyã€Teresaã€Claudiaã€Walkerã€Glennã€Fritzã€Fordakã€Juneã€Cleopetraã€Jeanã€Ivyã€Betsyã€Rooseveltã€Spikeã€Kenã€Whichã€Tofuã€Chiyoã€Robã€Zeeã€dustinã€Georgeã€Delã€Matthewã€Catã€Jacquiã€Lightfootã€Adrianã€Violaã€Alfredã€Noelã€Irfanã€Sunilã€Yoolã€Rikaã€Janeã€Xtremeã€Frontierã€a2ã€Neoã€Siobhanã€Yozã€Justinã€Elleã€Qarlã€Benjaminã€Isabelã€Gulliverã€Everettã€Christopherã€Izzyã€Stephanyã€Garryã€Sejongã€Seanã€Tobinã€Iridiumã€Metaã€Anthonyã€Jeremyã€JPã€Jakeã€Mauriceã€Madhaviã€Leopardã€Kyleã€Joonã€Kariã€Bertã€Belindaã€Jonã€Kristiã€Bridieã€Pramodã€KJã€Socratesã€Mariaã€Ivanã€Aricã€Yamasakiã€Adreanneã€Jayã€MitchKã€Cerenã€Cocoã€Durlã€Jennyã€Periapseã€Karticã€Storrsã€Lotteã€Sandyã€Rohnã€Colossusã€Zenã€BigPapiã€Bradã€Pastramiã€Kurzã€Maniã€Neuroã€Jaimeã€MJã€Rowanã€Sgtã€Elvisã€Geckoã€Samuelã€Sardonyxã€Leoã€Bryanã€Nikoã€Softã€Poppyã€Rachelã€Akiã€Angeloã€Banzaiã€Alexaã€Sueã€CeeLoã€Benderã€CGã€Gillianã€Pelleã€Nickã€Echoã€Zaraã€Christineã€Shamiranã€Emmaã€Blakeã€Keikoã€Plexusã€Joppaã€Sidewinderã€Ericaã€Ashleiã€Twilightã€Kristenã€Brettã€Qã€Enusã€Simonã€Bevisã€Kraftã€Kipã€Chandlerã€Ronã€LauraPã€Ramã€KyleJMã€Scouseã€Prosperoã€Melissaã€Martyã€Natã€Hamiltonã€Kendã€Lordanã€Jimmyã€Kosmoã€Seraphã€Greenã€Ekimã€Wiggoã€JTã€Romeã€Dorisã€Mizã€Benocã€Whumpã€Trinityã€Patchã€Kateã€TJã€Baoã€Joohwanã€Christyã€Sofiaã€Matiasã€Cogsworthã€Johanã€Orehã€Cheahã€Angelaã€Brandyã€Mangoã€Lanã€Aleksã€Gloriaã€Heidyã€Mitchellã€Spaceã€Coltonã€Bambersã€Einsteinã€Maggieã€Malbersã€Roseã€Winnieã€Stellaã€Miltonã€Rothmanã€Niallã€Marinã€Allisonã€Katieã€Dawnã€Kattã€Dustyã€Kalpanaã€Judyã€Andreaã€Ambroffã€Infinityã€Gailã€Ricoã€Raymondã€Yiã€Williamã€Christaã€Mã€Teaganã€Scoutã€Mollyã€Danteã€Corrã€Dynamikeã€Usiã€Kayleeã€Vidtutsã€Lilã€Danicaã€Saschaã€Kelvã€Jacobã€Nyaã€Rodneyã€Brandonã€Elsieã€Blondinã€Grantã€Katrinã€Nyxã€Gabrielã€Locklainnã€Claireã€Devinã€Minervaã€Montyã€Austinã€Bradfordã€Siã€Keiraã€Hã€Caitlinã€Ditaã€Makaiã€Jennã€Annã€Meredithã€Clareã€Joyã€Praveenã€Codyã€Edmundã€Rutheã€Sirenaã€Gayathriã€Spiderã€FJã€Davidoffã€Tianã€Jennieã€Louiseã€Oskarã€Landonã€Noelleã€Jarvã€Ingridã€Alã€Sommerã€Docã€Ariaã€Huinã€Grayã€Liliã€Virã€DJã€Yangã€Tã€Simoneã€Maestroã€Scottã€Charleneã€Quixoteã€Amandaã€Susanã€Zedã€Anneã€Enkiduã€Esbeeã€Joroanã€Katelinã€Roxieã€Tayã€Scarletã€Kevinã€Johnnyã€Wolfgangã€Andrenã€Bobã€Howardã€Merovã€Randã€Rayã€Michonã€Newellã€Galenã€Dessieã€Lesã€Michonã€Jenelleã€Geoã€Sizã€Shapiroã€Peteã€Calyleã€Seleneã€Allenã€Phoebeã€Goldinã€Kimmoraã€Dakotaã€Slatonã€Lindquistã€Zoeyã€Hariã€Othelloã€Rohitã€Sheldonã€Petraã€Vialeã€Gordonã€Kayeã€Pinkã€Fernyã€Emersonã€Davyã€Briã€Chanã€Juanã€Robertã€Terrenceã€Nathanã€Carlã¨ã€ãã®ä»–多数ã®äººé”ã«ã‚ˆã£ã¦ä½œæˆã•ã‚Œã¾ã—ãŸã€‚
diff --git a/indra/newview/skins/default/xui/ja/floater_animation_preview.xml b/indra/newview/skins/default/xui/ja/floater_animation_preview.xml
index 27a07e633b..b61007d86e 100644
--- a/indra/newview/skins/default/xui/ja/floater_animation_preview.xml
+++ b/indra/newview/skins/default/xui/ja/floater_animation_preview.xml
@@ -13,18 +13,10 @@
</text>
<combo_box label="" name="preview_base_anim"
tool_tip="ã‚¢ãƒã‚¿ãƒ¼ãŒæ™®é€šã®è¡Œå‹•ã‚’ã™ã‚‹ã¨ãã®ã‚¢ãƒ‹ãƒ¡ãƒ¼ã‚·ãƒ§ãƒ³ã®å‹•ãをテストã™ã‚‹ãŸã‚ã«ã“れを使ã„ã¾ã™ã€‚">
- <combo_item name="Standing">
- ç«‹ã¤
- </combo_item>
- <combo_item name="Walking">
- æ­©ã
- </combo_item>
- <combo_item name="Sitting">
- 座る
- </combo_item>
- <combo_item name="Flying">
- 飛行
- </combo_item>
+ <combo_box.item name="Standing" label="ç«‹ã¤" />
+ <combo_box.item name="Walking" label="æ­©ã" />
+ <combo_box.item name="Sitting" label="座る" />
+ <combo_box.item name="Flying" label="飛行" />
</combo_box>
<pad height="7" />
<check_box label="ループ" name="loop_check"
@@ -38,111 +30,45 @@
</text>
<combo_box label="" name="hand_pose_combo"
tool_tip="アニメーションã®æ‰‹ã®å‹•ãをコントロールã—ã¾ã™ã€‚">
- <combo_item name="Spread">
- 広ãŒã‚‹
- </combo_item>
- <combo_item name="Relaxed">
- リラックス
- </combo_item>
- <combo_item name="PointBoth">
- 両方を指ã™
- </combo_item>
- <combo_item name="Fist">
- 拳
- </combo_item>
- <combo_item name="RelaxedLeft">
- リラックス左
- </combo_item>
- <combo_item name="PointLeft">
- 左を指ã™
- </combo_item>
- <combo_item name="FistLeft">
- 拳左
- </combo_item>
- <combo_item name="RelaxedRight">
- リラックスå³
- </combo_item>
- <combo_item name="PointRight">
- å³ã‚’指ã™
- </combo_item>
- <combo_item name="FistRight">
- 拳å³
- </combo_item>
- <combo_item name="SaluteRight">
- 敬礼å³
- </combo_item>
- <combo_item name="Typing">
- 入力ã™ã‚‹
- </combo_item>
- <combo_item name="PeaceRight">
- ピース・サインå³
- </combo_item>
+ <combo_box.item name="Spread" label="広ãŒã‚‹" />
+ <combo_box.item name="Relaxed" label="リラックス" />
+ <combo_box.item name="PointBoth" label="両方を指ã™" />
+ <combo_box.item name="Fist" label="拳" />
+ <combo_box.item name="RelaxedLeft" label="リラックス左" />
+ <combo_box.item name="PointLeft" label="左を指ã™" />
+ <combo_box.item name="FistLeft" label="拳左" />
+ <combo_box.item name="RelaxedRight" label="リラックスå³" />
+ <combo_box.item name="PointRight" label="å³ã‚’指ã™" />
+ <combo_box.item name="FistRight" label="拳å³" />
+ <combo_box.item name="SaluteRight" label="敬礼å³" />
+ <combo_box.item name="Typing" label="入力ã™ã‚‹" />
+ <combo_box.item name="PeaceRight" label="ピース・サインå³" />
</combo_box>
<text name="emote_label">
表ç¾
</text>
<combo_box label="" name="emote_combo"
tool_tip="アニメーションã®é¡”を表情をコントロールã—ã¾ã™ã€‚">
- <combo_item name="[None]">
- [None]
- </combo_item>
- <combo_item name="Aaaaah">
- アーーーーー
- </combo_item>
- <combo_item name="Afraid">
- 怖れ
- </combo_item>
- <combo_item name="Angry">
- 怒り
- </combo_item>
- <combo_item name="BigSmile">
- 満é¢ã®ç¬‘ã¿
- </combo_item>
- <combo_item name="Bored">
- 退屈
- </combo_item>
- <combo_item name="Cry">
- æ³£ã
- </combo_item>
- <combo_item name="Disdain">
- 侮蔑
- </combo_item>
- <combo_item name="Embarrassed">
- 困惑
- </combo_item>
- <combo_item name="Frown">
- ã—ã‹ã‚ã£é¢
- </combo_item>
- <combo_item name="Kiss">
- キス
- </combo_item>
- <combo_item name="Laugh">
- 笑ã†
- </combo_item>
- <combo_item name="Plllppt">
- Plllppt
- </combo_item>
- <combo_item name="Repulsed">
- 嫌悪感
- </combo_item>
- <combo_item name="Sad">
- 悲ã—ã„
- </combo_item>
- <combo_item name="Shrug">
- è‚©ã‚’ã™ãã‚ã‚‹
- </combo_item>
- <combo_item name="Smile">
- 笑ã¿
- </combo_item>
- <combo_item name="Surprise">
- é©šã
- </combo_item>
- <combo_item name="Wink">
- ウィンク
- </combo_item>
- <combo_item name="Worry">
- 心é…
- </combo_item>
+ <combo_box.item name="[None]" label="None]" />
+ <combo_box.item name="Aaaaah" label="アーーーーー" />
+ <combo_box.item name="Afraid" label="怖れ" />
+ <combo_box.item name="Angry" label="怒り" />
+ <combo_box.item name="BigSmile" label="満é¢ã®ç¬‘ã¿" />
+ <combo_box.item name="Bored" label="退屈" />
+ <combo_box.item name="Cry" label="æ³£ã" />
+ <combo_box.item name="Disdain" label="侮蔑" />
+ <combo_box.item name="Embarrassed" label="困惑" />
+ <combo_box.item name="Frown" label="ã—ã‹ã‚ã£é¢" />
+ <combo_box.item name="Kiss" label="キス" />
+ <combo_box.item name="Laugh" label="笑ã†" />
+ <combo_box.item name="Plllppt" label="Plllppt" />
+ <combo_box.item name="Repulsed" label="嫌悪感" />
+ <combo_box.item name="Sad" label="悲ã—ã„" />
+ <combo_box.item name="Shrug" label="è‚©ã‚’ã™ãã‚ã‚‹" />
+ <combo_box.item name="Smile" label="笑ã¿" />
+ <combo_box.item name="Surprise" label="é©šã" />
+ <combo_box.item name="Wink" label="ウィンク" />
+ <combo_box.item name="Worry" label="心é…" />
</combo_box>
<spinner label="フェーズイï¾(秒)" name="ease_in_time"
tool_tip="アニメーションã®ãƒ–レンド・イン時間(秒)" />
diff --git a/indra/newview/skins/default/xui/ja/floater_buy_land.xml b/indra/newview/skins/default/xui/ja/floater_buy_land.xml
index 0612d309b9..1ccd1f53a4 100644
--- a/indra/newview/skins/default/xui/ja/floater_buy_land.xml
+++ b/indra/newview/skins/default/xui/ja/floater_buy_land.xml
@@ -75,15 +75,9 @@
土地をä¿æœ‰ã§ãã‚‹ã®ã¯ãƒ—レミアム・メンãƒãƒ¼ã ã‘ã§ã™
</text>
<combo_box name="account_level">
- <combo_item name="US$9.95/month,billedmonthly">
- 月é¡9.95米ドルã€æœˆæ‰•ã„
- </combo_item>
- <combo_item name="US$7.50/month,billedquarterly">
- 月é¡7.50米ドルã€å¹´4回払ã„
- </combo_item>
- <combo_item name="US$6.00/month,billedannually">
- 月é¡6.00米ドルã€å¹´æ‰•ã„
- </combo_item>
+ <combo_box.item name="US$9.95/month,billedmonthly" label="月é¡9.95米ドルã€æœˆæ‰•ã„" />
+ <combo_box.item name="US$7.50/month,billedquarterly" label="月é¡7.50米ドルã€å¹´4回払ã„" />
+ <combo_box.item name="US$6.00/month,billedannually" label="月é¡6.00米ドルã€å¹´æ‰•ã„" />
</combo_box>
<text name="land_use_action">
毎月ã®åœŸåœ°ä½¿ç”¨æ–™ã‚’US$40ã«å¼•ã上ã’ã¾ã™
diff --git a/indra/newview/skins/default/xui/ja/floater_hardware_settings.xml b/indra/newview/skins/default/xui/ja/floater_hardware_settings.xml
index 2466dd5943..67d105c2a4 100644
--- a/indra/newview/skins/default/xui/ja/floater_hardware_settings.xml
+++ b/indra/newview/skins/default/xui/ja/floater_hardware_settings.xml
@@ -10,21 +10,11 @@
アンãƒã‚¨ã‚¤ãƒªã‚¢ã‚·ãƒ³ã‚°:
</text>
<combo_box label="アンãƒã‚¨ã‚¤ãƒªã‚¢ã‚·ãƒ³ã‚°" name="fsaa">
- <combo_item name="FSAADisabled">
- 無効
- </combo_item>
- <combo_item name="2x">
- 2x
- </combo_item>
- <combo_item name="4x">
- 4x
- </combo_item>
- <combo_item name="8x">
- 8x
- </combo_item>
- <combo_item name="16x">
- 16x
- </combo_item>
+ <combo_box.item name="FSAADisabled" label="無効" />
+ <combo_box.item name="2x" label="2x" />
+ <combo_box.item name="4x" label="4x" />
+ <combo_box.item name="8x" label="8x" />
+ <combo_box.item name="16x" label="16x" />
</combo_box>
<spinner label="ガンマ:" name="gamma" />
<text name="(brightness, lower is brighter)">
diff --git a/indra/newview/skins/default/xui/ja/floater_image_preview.xml b/indra/newview/skins/default/xui/ja/floater_image_preview.xml
index be8e5c6416..fae9c87da4 100644
--- a/indra/newview/skins/default/xui/ja/floater_image_preview.xml
+++ b/indra/newview/skins/default/xui/ja/floater_image_preview.xml
@@ -10,36 +10,16 @@
イメージã®ï¾Œï¾Ÿï¾šï¾‹ï¾žï½­ï½°ï¼š
</text>
<combo_box label="æœã®ç¨®é¡ž" name="clothing_type_combo">
- <combo_item name="Image">
- ç”»åƒ
- </combo_item>
- <combo_item name="Hair">
- 髪
- </combo_item>
- <combo_item name="FemaleHead">
- 女性ã®é ­
- </combo_item>
- <combo_item name="FemaleUpperBody">
- 女性ã®ä¸ŠåŠèº«
- </combo_item>
- <combo_item name="FemaleLowerBody">
- 女性ã®ä¸‹åŠèº«
- </combo_item>
- <combo_item name="MaleHead">
- 男性ã®é ­
- </combo_item>
- <combo_item name="MaleUpperBody">
- 男性ã®ä¸ŠåŠèº«
- </combo_item>
- <combo_item name="MaleLowerBody">
- 男性ã®ä¸‹åŠèº«
- </combo_item>
- <combo_item name="Skirt">
- スカート
- </combo_item>
- <combo_item name="SculptedPrim">
- 変形ã•ã‚ŒãŸãƒ—リム
- </combo_item>
+ <combo_box.item name="Image" label="ç”»åƒ" />
+ <combo_box.item name="Hair" label="髪" />
+ <combo_box.item name="FemaleHead" label="女性ã®é ­" />
+ <combo_box.item name="FemaleUpperBody" label="女性ã®ä¸ŠåŠèº«" />
+ <combo_box.item name="FemaleLowerBody" label="女性ã®ä¸‹åŠèº«" />
+ <combo_box.item name="MaleHead" label="男性ã®é ­" />
+ <combo_box.item name="MaleUpperBody" label="男性ã®ä¸ŠåŠèº«" />
+ <combo_box.item name="MaleLowerBody" label="男性ã®ä¸‹åŠèº«" />
+ <combo_box.item name="Skirt" label="スカート" />
+ <combo_box.item name="SculptedPrim" label="変形ã•ã‚ŒãŸãƒ—リム" />
</combo_box>
<text name="bad_image_text">
イメージを読ã¿å–ã‚Œã¾ã›ã‚“。
diff --git a/indra/newview/skins/default/xui/ja/floater_inventory_item_properties.xml b/indra/newview/skins/default/xui/ja/floater_inventory_item_properties.xml
index 9a408b92a9..8588ee1a96 100644
--- a/indra/newview/skins/default/xui/ja/floater_inventory_item_properties.xml
+++ b/indra/newview/skins/default/xui/ja/floater_inventory_item_properties.xml
@@ -60,12 +60,8 @@
</text>
<check_box label="売り出ã—中" name="CheckPurchase" />
<radio_group name="RadioSaleType">
- <radio_item name="radio">
- オリジナル
- </radio_item>
- <radio_item name="radio2">
- コピー
- </radio_item>
+ <radio_item name="radio" label="オリジナル" />
+ <radio_item name="radio2" label="コピー" />
</radio_group>
<text name="TextPrice">
料金:L$
diff --git a/indra/newview/skins/default/xui/ja/floater_postcard.xml b/indra/newview/skins/default/xui/ja/floater_postcard.xml
index 65c4f65185..e22ce24180 100644
--- a/indra/newview/skins/default/xui/ja/floater_postcard.xml
+++ b/indra/newview/skins/default/xui/ja/floater_postcard.xml
@@ -34,7 +34,7 @@
<button bottom_delta="-52" label="å–り消ã—" name="cancel_btn" />
<button label="é€ä¿¡" name="send_btn" />
<text name="default_subject">
- Second Life ã‹ã‚‰ã®ãƒã‚¹ãƒˆã‚«ãƒ¼ãƒ‰
+ [SECOND_LIFE] ã‹ã‚‰ã®ãƒã‚¹ãƒˆã‚«ãƒ¼ãƒ‰
</text>
<text name="default_message">
ã“ã‚Œã¯çµ¶å¯¾ãƒã‚§ãƒƒã‚¯ï¼
diff --git a/indra/newview/skins/default/xui/ja/floater_preview_gesture.xml b/indra/newview/skins/default/xui/ja/floater_preview_gesture.xml
index 9ddf537fee..1ec868d0d8 100644
--- a/indra/newview/skins/default/xui/ja/floater_preview_gesture.xml
+++ b/indra/newview/skins/default/xui/ja/floater_preview_gesture.xml
@@ -46,12 +46,8 @@
ã¾ã™ã€‚
</text>
<radio_group name="animation_trigger_type">
- <radio_item name="start">
- 開始
- </radio_item>
- <radio_item name="stop">
- åœæ­¢
- </radio_item>
+ <radio_item name="start" label="開始" />
+ <radio_item name="stop" label="åœæ­¢" />
</radio_group>
<check_box label="アニメーションãŒå®Œäº†ã™ã‚‹ã¾ã§" name="wait_anim_check"/>
<check_box label="秒表示ã®æ™‚é–“" name="wait_time_check"/>
diff --git a/indra/newview/skins/default/xui/ja/floater_sell_land.xml b/indra/newview/skins/default/xui/ja/floater_sell_land.xml
index 90c83c2103..3860c599fb 100644
--- a/indra/newview/skins/default/xui/ja/floater_sell_land.xml
+++ b/indra/newview/skins/default/xui/ja/floater_sell_land.xml
@@ -36,15 +36,9 @@
誰ã«ã§ã‚‚販売ã™ã‚‹ã‹ã€ç‰¹å®šã®äººã«ã®ã¿è²©å£²ã™ã‚‹ã‹ã‚’é¸æŠžã—ã¦ãã ã•ã„
</text>
<combo_box name="sell_to">
- <combo_item name="--selectone--">
- ï¼ï¼1ã¤é¸æŠžï¼ï¼
- </combo_item>
- <combo_item name="Anyone">
- 誰ã§ã‚‚
- </combo_item>
- <combo_item name="Specificuser:">
- 特定ユーザー:
- </combo_item>
+ <combo_box.item name="--selectone--" label="1ã¤é¸æŠžï¼ï¼" />
+ <combo_box.item name="Anyone" label="誰ã§ã‚‚" />
+ <combo_box.item name="Specificuser:" label="特定ユーザー:" />
</combo_box>
<button label="é¸æŠž..." name="sell_to_select_agent" />
<text name="sell_objects_label">
diff --git a/indra/newview/skins/default/xui/ja/floater_settings_debug.xml b/indra/newview/skins/default/xui/ja/floater_settings_debug.xml
index 1de3763f79..133a8ce2cd 100644
--- a/indra/newview/skins/default/xui/ja/floater_settings_debug.xml
+++ b/indra/newview/skins/default/xui/ja/floater_settings_debug.xml
@@ -1,12 +1,8 @@
<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
<floater name="settings_debug" title="デãƒãƒƒã‚°è¨­å®š">
<combo_box name="boolean_combo">
- <combo_item name="TRUE">
- æ­£
- </combo_item>
- <combo_item name="FALSE">
- 誤
- </combo_item>
+ <combo_box.item name="TRUE" label="æ­£" />
+ <combo_box.item name="FALSE" label="誤" />
</combo_box>
<color_swatch label="色" name="color_swatch" />
<spinner label="x" name="val_spinner_1" />
diff --git a/indra/newview/skins/default/xui/ja/floater_snapshot.xml b/indra/newview/skins/default/xui/ja/floater_snapshot.xml
index 7937de117c..98db0e358e 100644
--- a/indra/newview/skins/default/xui/ja/floater_snapshot.xml
+++ b/indra/newview/skins/default/xui/ja/floater_snapshot.xml
@@ -4,15 +4,9 @@
スナップショットã®é€ã‚Šå…ˆ
</text>
<radio_group label="スナップショット・タイプ" name="snapshot_type_radio">
- <radio_item name="postcard">
- Eメールã§é€ä¿¡
- </radio_item>
- <radio_item name="texture">
- æŒã¡ç‰©ã«ä¿å­˜ï¼ˆL$[AMOUNT])
- </radio_item>
- <radio_item name="local">
- ãƒãƒ¼ãƒ‰ãƒ‡ã‚£ã‚¹ã‚¯ã«ä¿å­˜
- </radio_item>
+ <radio_item name="postcard" label="Eメールã§é€ä¿¡" />
+ <radio_item name="texture" label="æŒã¡ç‰©ã«ä¿å­˜ï¼ˆL$[AMOUNT])" />
+ <radio_item name="local" label="ãƒãƒ¼ãƒ‰ãƒ‡ã‚£ã‚¹ã‚¯ã«ä¿å­˜" />
</radio_group>
<text name="file_size_label">
ファイル・サイズ: [SIZE] KB
@@ -21,12 +15,12 @@
<button label="é€ä¿¡" name="send_btn"/>
<button label="ä¿å­˜ï¼ˆL$[AMOUNT])" name="upload_btn"/>
<flyout_button label="ä¿å­˜" name="save_btn" tool_tip="ç”»åƒã‚’ファイルã«ä¿å­˜">
- <flyout_button_item name="save_item">
- ä¿å­˜
- </flyout_button_item>
- <flyout_button_item name="saveas_item">
- åå‰ã‚’付ã‘ã¦ä¿å­˜
- </flyout_button_item>
+ <flyout_button.item name="save_item">
+ ä¿å­˜
+ </flyout_button.item>
+ <flyout_button.item name="saveas_item">
+ åå‰ã‚’付ã‘ã¦ä¿å­˜
+ </flyout_button.item>
</flyout_button>
<button label="キャンセル" name="discard_btn"/>
<button label="全表示 &gt;&gt;" name="more_btn" tool_tip="高度ãªã‚ªãƒ—ション"/>
@@ -38,75 +32,33 @@
å½¢å¼
</text>
<combo_box label="解åƒåº¦" name="postcard_size_combo">
- <combo_item name="CurrentWindow">
- ç¾åœ¨ã®ï½³ï½¨ï¾ï¾„゙ウ
- </combo_item>
- <combo_item name="640x480">
- 640x480
- </combo_item>
- <combo_item name="800x600">
- 800x600
- </combo_item>
- <combo_item name="1024x768">
- 1024x768
- </combo_item>
- <combo_item name="Custom">
- カスタム
- </combo_item>
+ <combo_box.item name="CurrentWindow" label="ç¾åœ¨ã®ï½³ï½¨ï¾ï¾„゙ウ" />
+ <combo_box.item name="640x480" label="640x480" />
+ <combo_box.item name="800x600" label="800x600" />
+ <combo_box.item name="1024x768" label="1024x768" />
+ <combo_box.item name="Custom" label="カスタム" />
</combo_box>
<combo_box label="解åƒåº¦" name="texture_size_combo">
- <combo_item name="CurrentWindow">
- ç¾åœ¨ã®ï½³ï½¨ï¾ï¾„゙ウ
- </combo_item>
- <combo_item name="Small(128x128)">
- å°ï¼ˆ128x128)
- </combo_item>
- <combo_item name="Medium(256x256)">
- 中(256x256)
- </combo_item>
- <combo_item name="Large(512x512)">
- 大(512x512)
- </combo_item>
- <combo_item name="Custom">
- カスタム
- </combo_item>
+ <combo_box.item name="CurrentWindow" label="ç¾åœ¨ã®ï½³ï½¨ï¾ï¾„゙ウ" />
+ <combo_box.item name="Small(128x128)" label="å°ï¼ˆ128x128)" />
+ <combo_box.item name="Medium(256x256)" label="中(256x256)" />
+ <combo_box.item name="Large(512x512)" label="大(512x512)" />
+ <combo_box.item name="Custom" label="カスタム" />
</combo_box>
<combo_box label="解åƒåº¦" name="local_size_combo">
- <combo_item name="CurrentWindow">
- ç¾åœ¨ã®ï½³ï½¨ï¾ï¾„゙ウ
- </combo_item>
- <combo_item name="320x240">
- 320x240
- </combo_item>
- <combo_item name="640x480">
- 640x480
- </combo_item>
- <combo_item name="800x600">
- 800x600
- </combo_item>
- <combo_item name="1024x768">
- 1024x768
- </combo_item>
- <combo_item name="1280x1024">
- 1280x1024
- </combo_item>
- <combo_item name="1600x1200">
- 1600x1200
- </combo_item>
- <combo_item name="Custom">
- カスタム
- </combo_item>
+ <combo_box.item name="CurrentWindow" label="ç¾åœ¨ã®ï½³ï½¨ï¾ï¾„゙ウ" />
+ <combo_box.item name="320x240" label="320x240" />
+ <combo_box.item name="640x480" label="640x480" />
+ <combo_box.item name="800x600" label="800x600" />
+ <combo_box.item name="1024x768" label="1024x768" />
+ <combo_box.item name="1280x1024" label="1280x1024" />
+ <combo_box.item name="1600x1200" label="1600x1200" />
+ <combo_box.item name="Custom" label="カスタム" />
</combo_box>
<combo_box label="å½¢å¼" name="local_format_combo">
- <combo_item name="PNG">
- PNG
- </combo_item>
- <combo_item name="JPEG">
- JPEG
- </combo_item>
- <combo_item name="BMP">
- BMP
- </combo_item>
+ <combo_box.item name="PNG" label="PNG" />
+ <combo_box.item name="JPEG" label="JPEG" />
+ <combo_box.item name="BMP" label="BMP" />
</combo_box>
<spinner label="å¹…" name="snapshot_width" label_width="25" width="90"/>
<spinner label="高ã•" name="snapshot_height" label_width="30" left="115" width="90"/>
@@ -116,15 +68,9 @@
キャプï¾ï½¬ï¼š
</text>
<combo_box label="ç”»åƒãƒ¬ã‚¤ãƒ¤ãƒ¼" name="layer_types">
- <combo_item name="Colors">
- 色
- </combo_item>
- <combo_item name="Depth">
- æ·±ã•
- </combo_item>
- <combo_item name="ObjectMattes">
- オグジェクトã®ã¤ã‚„消ã—
- </combo_item>
+ <combo_box.item name="Colors" label="色" />
+ <combo_box.item name="Depth" label="æ·±ã•" />
+ <combo_box.item name="ObjectMattes" label="オグジェクトã®ã¤ã‚„消ã—" />
</combo_box>
<check_box label="インタフェースを表示" name="ui_check"/>
<check_box label="HUD オブジェクトを表示" name="hud_check"/>
diff --git a/indra/newview/skins/default/xui/ja/floater_sound_preview.xml b/indra/newview/skins/default/xui/ja/floater_sound_preview.xml
index 6bc259536f..b247914389 100644
--- a/indra/newview/skins/default/xui/ja/floater_sound_preview.xml
+++ b/indra/newview/skins/default/xui/ja/floater_sound_preview.xml
@@ -12,17 +12,9 @@
ビットレート(kbps):
</text>
<radio_group name="bitrate">
- <radio_item name="32">
- 32
- </radio_item>
- <radio_item name="64">
- 64
- </radio_item>
- <radio_item name="96">
- 96
- </radio_item>
- <radio_item name="128">
- 128
- </radio_item>
+ <radio_item name="32" label="32" />
+ <radio_item name="64" label="64" />
+ <radio_item name="96" label="96" />
+ <radio_item name="128" label="128" />
</radio_group>
</floater>
diff --git a/indra/newview/skins/default/xui/ja/floater_tools.xml b/indra/newview/skins/default/xui/ja/floater_tools.xml
index 81f221a933..477ba2bdcb 100644
--- a/indra/newview/skins/default/xui/ja/floater_tools.xml
+++ b/indra/newview/skins/default/xui/ja/floater_tools.xml
@@ -20,15 +20,9 @@
ルーラー:
</text>
<combo_box left_delta="60" name="combobox grid mode" width="76">
- <combo_item name="World">
- 世界
- </combo_item>
- <combo_item name="Local">
- ローカル
- </combo_item>
- <combo_item name="Reference">
- リファレンス
- </combo_item>
+ <combo_box.item name="World" label="世界"/>
+ <combo_box.item name="Local" label="ローカル"/>
+ <combo_box.item name="Reference" label="リファレンス"/>
</combo_box>
<check_box label="両å´ã‚’引伸ã°ã™" left="116" name="checkbox uniform"/>
<check_box label="テクスãƒãƒ£ãƒ¼ã‚’引伸ã°ã™" name="checkbox stretch textures"/>
@@ -130,15 +124,9 @@
価格: L$
</text>
<radio_group left="30" name="sale type">
- <radio_item name="Original">
- オリジナル
- </radio_item>
- <radio_item left="82" name="Copy">
- コピー
- </radio_item>
- <radio_item left="148" name="Contents">
- コンテンツ
- </radio_item>
+ <radio_item name="Original" label="オリジナル" />
+ <radio_item left="82" name="Copy" label="コピー" />
+ <radio_item left="148" name="Contents" label="コンテンツ" />
</radio_group>
<text name="Next owner can:">
次ã®ã‚ªãƒ¼ãƒŠãƒ¼ãŒå®Ÿè¡Œã§ãã‚‹æ“作:
@@ -150,27 +138,13 @@
左クリックã™ã‚‹ã¨ï¼š
</text>
<combo_box name="clickaction">
- <combo_item name="Touch/grab(default)">
- 触るï¼ã¤ã‹ã‚€ (デフォルト)
- </combo_item>
- <combo_item name="Sitonobject">
- オブジェクトã«åº§ã‚‹
- </combo_item>
- <combo_item name="Buyobject">
- オブジェクトを購入
- </combo_item>
- <combo_item name="Payobject">
- オブジェクトã¸ã®æ”¯æ‰•ã„
- </combo_item>
- <combo_item name="Open">
- é–‹ã
- </combo_item>
- <combo_item name="Play">
- 区画メディアをå†ç”Ÿ
- </combo_item>
- <combo_item name="Opemmedia">
- 区画メディアを開ã
- </combo_item>
+ <combo_box.item name="Touch/grab(default)" label="触るï¼ã¤ã‹ã‚€ (デフォルト)"/>
+ <combo_box.item name="Sitonobject" label="オブジェクトã«åº§ã‚‹"/>
+ <combo_box.item name="Buyobject" label="オブジェクトを購入"/>
+ <combo_box.item name="Payobject" label="オブジェクトã¸ã®æ”¯æ‰•ã„"/>
+ <combo_box.item name="Open" label="é–‹ã"/>
+ <combo_box.item name="Play" label="区画メディアをå†ç”Ÿ"/>
+ <combo_box.item name="Opemmedia" label="区画メディアを開ã"/>
</combo_box>
<text name="B:">
B:
@@ -254,56 +228,26 @@
ç´ æ
</text>
<combo_box name="material">
- <combo_item name="Stone">
- 石æ
- </combo_item>
- <combo_item name="Metal">
- 金属
- </combo_item>
- <combo_item name="Glass">
- ガラス
- </combo_item>
- <combo_item name="Wood">
- 木æ
- </combo_item>
- <combo_item name="Flesh">
- 肌
- </combo_item>
- <combo_item name="Plastic">
- プラスãƒãƒƒã‚¯
- </combo_item>
- <combo_item name="Rubber">
- ゴム
- </combo_item>
+ <combo_box.item name="Stone" label="石æ"/>
+ <combo_box.item name="Metal" label="金属"/>
+ <combo_box.item name="Glass" label="ガラス"/>
+ <combo_box.item name="Wood" label="木æ"/>
+ <combo_box.item name="Flesh" label="肌"/>
+ <combo_box.item name="Plastic" label="プラスãƒãƒƒã‚¯"/>
+ <combo_box.item name="Rubber" label="ゴム"/>
</combo_box>
<text name="label basetype">
建造物ブロック・タイプ
</text>
<combo_box name="comboBaseType">
- <combo_item name="Box">
- ボックス
- </combo_item>
- <combo_item name="Cylinder">
- シリンダー
- </combo_item>
- <combo_item name="Prism">
- プリズム
- </combo_item>
- <combo_item name="Sphere">
- çƒå½¢
- </combo_item>
- <combo_item name="Torus">
- トーラス
- </combo_item>
- <combo_item name="Tube">
- ãƒãƒ¥ãƒ¼ãƒ–
- </combo_item>
- <combo_item name="Ring">
- リング
- </combo_item>
- <combo_item name="Sculpted">
- スカルプト
- </combo_item>
+ <combo_box.item name="Box" label="ボックス"/>
+ <combo_box.item name="Cylinder" label="シリンダー"/>
+ <combo_box.item name="Prism" label="プリズム"/>
+ <combo_box.item name="Sphere" label="çƒå½¢"/>
+ <combo_box.item name="Torus" label="トーラス"/>
+ <combo_box.item name="Tube" label="ãƒãƒ¥ãƒ¼ãƒ–"/>
+ <combo_box.item name="Ring" label="リング"/>
+ <combo_box.item name="Sculpted" label="スカルプト"/>
</combo_box>
<text name="text cut">
パス・カットã®å§‹ç‚¹ã¨çµ‚点
@@ -320,18 +264,10 @@
中空(空洞)ã®å½¢
</text>
<combo_box name="hole">
- <combo_item name="Default">
- デフォルト
- </combo_item>
- <combo_item name="Circle">
- サークル
- </combo_item>
- <combo_item name="Square">
- 正方形
- </combo_item>
- <combo_item name="Triangle">
- 三角形
- </combo_item>
+ <combo_box.item name="Default" label="デフォルト"/>
+ <combo_box.item name="Circle" label="サークル"/>
+ <combo_box.item name="Square" label="正方形"/>
+ <combo_box.item name="Triangle" label="三角形"/>
</combo_box>
<text name="text twist">
ã²ã­ã‚Šã®å§‹ã¾ã‚Šã¨çµ‚ã‚ã‚Š
@@ -380,21 +316,11 @@
縫ã„ç›®ã®ã‚¿ã‚¤ãƒ—
</text>
<combo_box name="sculpt type control">
- <combo_item name="None">
- (ãªã—)
- </combo_item>
- <combo_item name="Sphere">
- çƒå½¢
- </combo_item>
- <combo_item name="Torus">
- トーラス
- </combo_item>
- <combo_item name="Plane">
- å¹³é¢
- </combo_item>
- <combo_item name="Cylinder">
- シリンダー
- </combo_item>
+ <combo_box.item name="None" label="ãªã—)"/>
+ <combo_box.item name="Sphere" label="çƒå½¢"/>
+ <combo_box.item name="Torus" label="トーラス"/>
+ <combo_box.item name="Plane" label="å¹³é¢"/>
+ <combo_box.item name="Cylinder" label="シリンダー"/>
</combo_box>
</panel>
<panel label="特徴" name="Features">
@@ -436,88 +362,40 @@
マッピング
</text>
<combo_box name="combobox texgen">
- <combo_item name="Default">
- デフォルト
- </combo_item>
- <combo_item name="Planar">
- å¹³é¢
- </combo_item>
+ <combo_box.item name="Default" label="デフォルト"/>
+ <combo_box.item name="Planar" label="å¹³é¢"/>
</combo_box>
<text name="label shininess">
è¼ã
</text>
<combo_box name="combobox shininess">
- <combo_item name="None">
- ãªã—
- </combo_item>
- <combo_item name="Low">
- 低
- </combo_item>
- <combo_item name="Medium">
- 中
- </combo_item>
- <combo_item name="High">
- 高
- </combo_item>
+ <combo_box.item name="None" label="ãªã—"/>
+ <combo_box.item name="Low" label="低"/>
+ <combo_box.item name="Medium" label="中"/>
+ <combo_box.item name="High" label="高"/>
</combo_box>
<text name="label bumpiness">
凹凸
</text>
<combo_box name="combobox bumpiness">
- <combo_item name="None">
- ãªã—
- </combo_item>
- <combo_item name="Brightness">
- 明るã•
- </combo_item>
- <combo_item name="Darkness">
- æš—ã•
- </combo_item>
- <combo_item name="woodgrain">
- 木目調
- </combo_item>
- <combo_item name="bark">
- 木ã®çš®
- </combo_item>
- <combo_item name="bricks">
- レンガ
- </combo_item>
- <combo_item name="checker">
- ãƒã‚§ãƒƒã‚«ãƒ¼
- </combo_item>
- <combo_item name="concrete">
- コンクリート
- </combo_item>
- <combo_item name="crustytile">
- クラスティ・タイル
- </combo_item>
- <combo_item name="cutstone">
- カットストーン
- </combo_item>
- <combo_item name="discs">
- ディスク
- </combo_item>
- <combo_item name="gravel">
- 砂利
- </combo_item>
- <combo_item name="petridish">
- ペトリ
- </combo_item>
- <combo_item name="siding">
- 羽目æ¿
- </combo_item>
- <combo_item name="stonetile">
- ストーン・タイル
- </combo_item>
- <combo_item name="stucco">
- ã—ã£ãã„
- </combo_item>
- <combo_item name="suction">
- å¸ã„è¾¼ã¿
- </combo_item>
- <combo_item name="weave">
- 織目
- </combo_item>
+ <combo_box.item name="None" label="ãªã—"/>
+ <combo_box.item name="Brightness" label="明るã•"/>
+ <combo_box.item name="Darkness" label="æš—ã•"/>
+ <combo_box.item name="woodgrain" label="木目調"/>
+ <combo_box.item name="bark" label="木ã®çš®"/>
+ <combo_box.item name="bricks" label="レンガ"/>
+ <combo_box.item name="checker" label="ãƒã‚§ãƒƒã‚«ãƒ¼"/>
+ <combo_box.item name="concrete" label="コンクリート"/>
+ <combo_box.item name="crustytile" label="クラスティ・タイル"/>
+ <combo_box.item name="cutstone" label="カットストーン"/>
+ <combo_box.item name="discs" label="ディスク"/>
+ <combo_box.item name="gravel" label="砂利"/>
+ <combo_box.item name="petridish" label="ペトリ"/>
+ <combo_box.item name="siding" label="羽目æ¿"/>
+ <combo_box.item name="stonetile" label="ストーン・タイル"/>
+ <combo_box.item name="stucco" label="ã—ã£ãã„"/>
+ <combo_box.item name="suction" label="å¸ã„è¾¼ã¿"/>
+ <combo_box.item name="weave" label="織目"/>
</combo_box>
<text name="tex scale">
é¢ã”ã¨ã«ç¹°ã‚Šè¿”ã™
diff --git a/indra/newview/skins/default/xui/ja/floater_tos.xml b/indra/newview/skins/default/xui/ja/floater_tos.xml
index 31e3a24045..c0d1af1d6a 100644
--- a/indra/newview/skins/default/xui/ja/floater_tos.xml
+++ b/indra/newview/skins/default/xui/ja/floater_tos.xml
@@ -3,12 +3,8 @@
<button label="続行" label_selected="続行" name="Continue" />
<button label="å–り消ã—" label_selected="å–り消ã—" name="Cancel" />
<radio_group name="tos_agreement">
- <radio_item name="radio_disagree">
- 利用è¦ç´„ã«åŒæ„ã—ã¾ã›ã‚“
- </radio_item>
- <radio_item name="radio_agree">
- 利用è¦ç´„ã«åŒæ„ã—ã¾ã™
- </radio_item>
+ <radio_item name="radio_disagree" label="利用è¦ç´„ã«åŒæ„ã—ã¾ã›ã‚“" />
+ <radio_item name="radio_agree" label="利用è¦ç´„ã«åŒæ„ã—ã¾ã™" />
</radio_group>
<text name="tos_title">
利用è¦ç´„
diff --git a/indra/newview/skins/default/xui/ja/floater_world_map.xml b/indra/newview/skins/default/xui/ja/floater_world_map.xml
index a7a6e305ae..f7fe65bb72 100644
--- a/indra/newview/skins/default/xui/ja/floater_world_map.xml
+++ b/indra/newview/skins/default/xui/ja/floater_world_map.xml
@@ -29,14 +29,10 @@
<check_box label="Mature" name="event_mature_chk"/>
<check_box label="Adult" name="event_adult_chk"/>
<combo_box label="オンラインã®ãƒ•ãƒ¬ãƒ³ãƒ‰" name="friend combo" tool_tip="地図ã«è¡¨ç¤ºã•ã‚ŒãŸãƒ•ãƒ¬ãƒ³ãƒ‰">
- <combo_item name="none_selected">
- オンラインã®ãƒ•ãƒ¬ãƒ³ãƒ‰
- </combo_item>
+ <combo_box.item name="none_selected" label="オンラインã®ãƒ•ãƒ¬ãƒ³ãƒ‰" />
</combo_box>
<combo_box label="ランドマーク" name="landmark combo" tool_tip="地図ã«è¡¨ç¤ºã•ã‚ŒãŸãƒ©ãƒ³ãƒ‰ãƒžãƒ¼ã‚¯">
- <combo_item name="none_selected">
- ランドマーク
- </combo_item>
+ <combo_box.item name="none_selected" label="ランドマーク" />
</combo_box>
<line_editor label="地域åã§æ¤œç´¢" name="location" tool_tip="地域åを入力ã—ã¦ãã ã•ã„。"/>
<button label="検索" name="DoSearch" tool_tip="地域検索"/>
@@ -57,6 +53,6 @@
<button label="目的地を表示" label_selected="目的地を表示" name="Show Destination" tool_tip="é¸æŠžã—ãŸãƒ­ã‚±ãƒ¼ã‚·ãƒ§ãƒ³ã‚’地図ã®ä¸­å¿ƒã«ã™ã‚‹"/>
<button label="クリア" label_selected="クリア" name="Clear" tool_tip="トラッキングをåœæ­¢"/>
<button label="ç¾åœ¨åœ°ã‚’表示" label_selected="ç¾åœ¨åœ°ã‚’表示" name="Show My Location" tool_tip="ã‚ãªãŸã®ã‚¢ãƒã‚¿ãƒ¼ã®ãƒ­ã‚±ãƒ¼ã‚·ãƒ§ãƒ³ã‚’地図ã®ä¸­å¿ƒã«ã™ã‚‹"/>
- <button label="SLURLをクリップボードã«ã‚³ãƒ”ー" name="copy_slurl" tool_tip="ç¾åœ¨åœ°ã‚’SLURLã¨ã—ã¦ã‚³ãƒ”ーã—ã€ã‚¦ã‚§ãƒ–ã§ä½¿ç”¨"/>
+ <button label="SLurlをクリップボードã«ã‚³ãƒ”ー" name="copy_slurl" tool_tip="ç¾åœ¨åœ°ã‚’SLurlã¨ã—ã¦ã‚³ãƒ”ーã—ã€ã‚¦ã‚§ãƒ–ã§ä½¿ç”¨"/>
<slider label="ズーム" name="zoom slider"/>
</floater>
diff --git a/indra/newview/skins/default/xui/ja/language_settings.xml b/indra/newview/skins/default/xui/ja/language_settings.xml
new file mode 100644
index 0000000000..71418d446a
--- /dev/null
+++ b/indra/newview/skins/default/xui/ja/language_settings.xml
@@ -0,0 +1,55 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<!-- This file contains strings that used to be hardcoded in the source.-->
+<strings>
+
+ <!-- Locale Information -->
+ <string name="MicrosoftLocale">english</string>
+ <string name="DarwinLocale">C</string>
+ <string name="LinuxLocale">C</string>
+
+ <!--
+ datetimeToCodes["wkday"] = "%a"; // Thu
+ datetimeToCodes["weekday"] = "%A"; // Thursday
+ datetimeToCodes["year4"] = "%Y"; // 2009
+ datetimeToCodes["year"] = "%Y"; // 2009
+ datetimeToCodes["year2"] = "%y"; // 09
+ datetimeToCodes["mth"] = "%b"; // Aug
+ datetimeToCodes["month"] = "%B"; // August
+ datetimeToCodes["mthnum"] = "%m"; // 08
+ datetimeToCodes["day"] = "%d"; // 31
+ datetimeToCodes["hour24"] = "%H"; // 14
+ datetimeToCodes["hour"] = "%H"; // 14
+ datetimeToCodes["hour12"] = "%I"; // 02
+ datetimeToCodes["min"] = "%M"; // 59
+ datetimeToCodes["ampm"] = "%p"; // AM
+ datetimeToCodes["second"] = "%S"; // 59
+ datetimeToCodes["timezone"] = "%Z"; // PST
+ -->
+
+ <string name="TimeHour">hour,datetime,slt</string>
+ <string name="TimeMin">min,datetime,slt</string>
+ <string name="TimeYear">year,datetime,slt</string>
+ <string name="TimeDay">day,datetime,slt</string>
+ <string name="TimeMonth">mthnum,datetime,slt</string>
+ <string name="TimeWeek">wkday,datetime,slt</string>
+ <string name="TimeAMPM">ampm,datetime,slt</string>
+ <string name="TimeHour12">hour12,datetime,slt</string>
+
+ <string name="LTimeMthNum">mthnum,datetime,local</string>
+ <string name="LTimeWeek">wkday,datetime,local</string>
+ <string name="LTimeMonth">mth,datetime,local</string>
+ <string name="LTimeDay">day,datetime,local</string>
+ <string name="LTimeSec">second,datetime,local</string>
+ <string name="LTimeHour">hour,datetime,local</string>
+ <string name="LTimeMin">min,datetime,local</string>
+ <string name="LTimeYear">year,datetime,local</string>
+
+ <string name="UTCTimeWeek">weekday,datetime,utc</string>
+ <string name="UTCTimeDay">day,datetime,utc</string>
+ <string name="UTCTimeMth">mth,datetime,utc</string>
+ <string name="UTCTimeYr">year,datetime,utc</string>
+ <string name="UTCTimeHr">hour,datetime,utc</string>
+ <string name="UTCTimeMin">min,datetime,utc</string>
+ <string name="UTCTimeSec">second,datetime,utc</string>
+ <string name="UTCTimeTimezone">timezone,datetime,utc</string>
+</strings>
diff --git a/indra/newview/skins/default/xui/ja/menu_login.xml b/indra/newview/skins/default/xui/ja/menu_login.xml
index 906822e54b..afb1219095 100644
--- a/indra/newview/skins/default/xui/ja/menu_login.xml
+++ b/indra/newview/skins/default/xui/ja/menu_login.xml
@@ -7,7 +7,7 @@
<menu_item_call label="環境設定..." name="Preferences..." />
</menu>
<menu label="ヘルプ" name="Help">
- <menu_item_call label="Second Lifeヘルプ" name="Second Life Help" />
- <menu_item_call label="Second Lifeã«ã¤ã„ã¦..." name="About Second Life..." />
+ <menu_item_call label="[SECOND_LIFE]ヘルプ" name="Second Life Help" />
+ <menu_item_call label="[APP_NAME]ã«ã¤ã„ã¦..." name="About Second Life..." />
</menu>
</menu_bar>
diff --git a/indra/newview/skins/default/xui/ja/menu_viewer.xml b/indra/newview/skins/default/xui/ja/menu_viewer.xml
index c69c2e305a..bb33a14be4 100644
--- a/indra/newview/skins/default/xui/ja/menu_viewer.xml
+++ b/indra/newview/skins/default/xui/ja/menu_viewer.xml
@@ -185,7 +185,7 @@
<menu_item_call label="é¸æŠžã—ãŸã‚ªãƒ–ジェクトã®ä¸­ã®ã‚¹ã‚¯ãƒªãƒ—トをåœæ­¢ã™ã‚‹" name="Set Scripts to Not Running in Selection"/>
</menu>
<menu label="ヘルプ" name="Help">
- <menu_item_call label="Second Life ヘルプ" name="Second Life Help"/>
+ <menu_item_call label="[SECOND_LIFE] ヘルプ" name="Second Life Help"/>
<menu_item_call label="ãƒãƒ¥ãƒ¼ãƒˆãƒªã‚¢ãƒ«" name="Tutorial"/>
<menu_item_separator label="-----------" name="separator"/>
<menu_item_call label="Lindenå…¬å¼ãƒ–ログ..." name="Official Linden Blog..."/>
@@ -214,6 +214,6 @@
<menu_item_separator label="-----------" name="separator9"/>
<menu_item_call label="ãƒã‚°ã®å ±å‘Š..." name="Report Bug..."/>
</menu>
- <menu_item_call label="Second Lifeã«ã¤ã„ã¦" name="About Second Life..."/>
+ <menu_item_call label="[APP_NAME]ã«ã¤ã„ã¦" name="About Second Life..."/>
</menu>
</menu_bar>
diff --git a/indra/newview/skins/default/xui/ja/notifications.xml b/indra/newview/skins/default/xui/ja/notifications.xml
index 1d3e206d92..b6d09f893b 100644
--- a/indra/newview/skins/default/xui/ja/notifications.xml
+++ b/indra/newview/skins/default/xui/ja/notifications.xml
@@ -6,6 +6,9 @@
<global name="alwayschoose">
常ã«ã“ã®ã‚ªãƒ—ションをé¸æŠž
</global>
+ <global name="implicitclosebutton">
+ é–‰ã˜ã‚‹
+ </global>
<template name="okbutton">
<form>
<button
@@ -71,7 +74,7 @@
</form>
</template>
<notification functor="GenericAcknowledge" label="ä¸æ˜Žãªè­¦å‘Šãƒ¡ãƒƒã‚»ãƒ¼ã‚¸" name="MissingAlert">
- ã‚ãªãŸã® Second Life ã®ãƒãƒ¼ã‚¸ãƒ§ãƒ³ã§ã¯ã€
+ ã‚ãªãŸã® [APP_NAME] ã®ãƒãƒ¼ã‚¸ãƒ§ãƒ³ã§ã¯ã€
今å—ã‘å–ã£ãŸè­¦å‘Šãƒ¡ãƒƒã‚»ãƒ¼ã‚¸ã‚’表示ã™ã‚‹ã“ã¨ãŒã§ãã¾ã›ã‚“。
エラー詳細: 「[_NAME]ã€ã¨ã„ã†è­¦å‘Šã¯ notifications.xml ã«ã‚ã‚Šã¾ã›ã‚“ã§ã—ãŸã€‚
@@ -94,7 +97,7 @@
<usetemplate name="okcancelbuttons" notext="å–り消ã—" yestext="ã¯ã„"/>
</notification>
<notification name="BadInstallation">
- Second Life をアップデート中ã«ã‚¨ãƒ©ãƒ¼ãŒç™ºç”Ÿã—ã¾ã—ãŸã€‚ secondlife.com ã‹ã‚‰æœ€æ–°ãƒãƒ¼ã‚¸ãƒ§ãƒ³ã‚’ダウンロードã—ã¦ãã ã•ã„。
+ [APP_NAME] をアップデート中ã«ã‚¨ãƒ©ãƒ¼ãŒç™ºç”Ÿã—ã¾ã—ãŸã€‚ secondlife.com ã‹ã‚‰æœ€æ–°ãƒãƒ¼ã‚¸ãƒ§ãƒ³ã‚’ダウンロードã—ã¦ãã ã•ã„。
<usetemplate name="okbutton" yestext="OK"/>
</notification>
<notification name="LoginFailedNoNetwork">
@@ -274,7 +277,7 @@ L$ãŒä¸è¶³ã—ã¦ã„ã‚‹ã®ã§ã“ã®ã‚°ãƒ«ãƒ¼ãƒ—ã«å‚加ã™ã‚‹ã“ã¨ãŒã§ãã¾
</notification>
<notification name="ConfirmLandSaleToAnyoneChange">
注:「誰ã«ã§ã‚‚売å´ã™ã‚‹ã€ã‚’クリックã™ã‚‹ã¨ã€
-ã‚ãªãŸã®åœŸåœ°ã¯Second Life ã®ã‚³ãƒŸãƒ¥ãƒ‹ãƒ†ã‚£ã®ã©ã“ã‹ã‚‰ã§ã‚‚
+ã‚ãªãŸã®åœŸåœ°ã¯[SECOND_LIFE] ã®ã‚³ãƒŸãƒ¥ãƒ‹ãƒ†ã‚£ã®ã©ã“ã‹ã‚‰ã§ã‚‚
(ã“ã®åœ°åŸŸã«ãªã„コミュニティをå«ã‚€ï¼‰è³¼å…¥ã§ãるよã†ã«ãªã‚Šã¾ã™ã€‚
é¸æŠžã•ã‚ŒãŸ[LAND_SIZE]平方メートルã®åœŸåœ°ã¯ã€
@@ -435,17 +438,17 @@ L$ãŒä¸è¶³ã—ã¦ã„ã‚‹ã®ã§ã“ã®ã‚°ãƒ«ãƒ¼ãƒ—ã«å‚加ã™ã‚‹ã“ã¨ãŒã§ãã¾
<usetemplate name="okcancelbuttons" notext="キャンセル" yestext="OK"/>
</notification>
<notification name="CacheWillClear">
- [SECOND_LIFE]ã®å†èµ·å‹•å¾Œã«ã‚­ãƒ£ãƒƒã‚·ãƒ¥ãŒã‚¯ãƒªã‚¢ã•ã‚Œã¾ã™ã€‚
+ [APP_NAME]ã®å†èµ·å‹•å¾Œã«ã‚­ãƒ£ãƒƒã‚·ãƒ¥ãŒã‚¯ãƒªã‚¢ã•ã‚Œã¾ã™ã€‚
</notification>
<notification name="CacheWillBeMoved">
- [SECOND_LIFE]ã®å†èµ·å‹•å¾Œã«ã‚­ãƒ£ãƒƒã‚·ãƒ¥ãŒç§»å‹•ã•ã‚Œã¾ã™ã€‚
+ [APP_NAME]ã®å†èµ·å‹•å¾Œã«ã‚­ãƒ£ãƒƒã‚·ãƒ¥ãŒç§»å‹•ã•ã‚Œã¾ã™ã€‚
注æ„:ã“ã‚Œã«ã‚ˆã‚Šã‚­ãƒ£ãƒƒã‚·ãƒ¥ãŒã‚¯ãƒªã‚¢ã•ã‚Œã¾ã™ã€‚
</notification>
<notification name="ChangeConnectionPort">
- ãƒãƒ¼ãƒˆã®è¨­å®šã¯ã€[SECOND_LIFE]ã®å†èµ·å‹•å¾Œã«æœ‰åŠ¹ã«ãªã‚Šã¾ã™ã€‚
+ ãƒãƒ¼ãƒˆã®è¨­å®šã¯ã€[APP_NAME]ã®å†èµ·å‹•å¾Œã«æœ‰åŠ¹ã«ãªã‚Šã¾ã™ã€‚
</notification>
<notification name="ChangeSkin">
- æ–°ã—ã„スキンã¯[SECOND_LIFE]ã‚’å†èµ·å‹•ã™ã‚‹ã¨ç¾ã‚Œã¾ã™
+ æ–°ã—ã„スキンã¯[APP_NAME]ã‚’å†èµ·å‹•ã™ã‚‹ã¨ç¾ã‚Œã¾ã™
</notification>
<notification name="GoToAuctionPage">
[SECOND_LIFE]ウェブ・ページã«ç§»å‹•ã—〠入札ã‚ã‚‹ã„ã¯ã‚ªãƒ¼ã‚¯ã‚·ãƒ§ãƒ³ã®è©³ç´°ã‚’確èªã—ã¾ã™ã‹ï¼Ÿ
@@ -504,8 +507,8 @@ L$ãŒä¸è¶³ã—ã¦ã„ã‚‹ã®ã§ã“ã®ã‚°ãƒ«ãƒ¼ãƒ—ã«å‚加ã™ã‚‹ã“ã¨ãŒã§ãã¾
ファイル[[FILE]]を書ãè¾¼ã‚ã¾ã›ã‚“。
</notification>
<notification name="UnsupportedHardware">
- 警告: ã‚ãªãŸã®ã‚·ã‚¹ãƒ†ãƒ ã¯ Second Life を使用ã™ã‚‹ãŸã‚ã«å¿…è¦ãªå¿…須動作環境ã®æ¡ä»¶ã‚’満ãŸã—ã¦ã„ã¾ã›ã‚“。
-Second Life ã‚’ã“ã®ã¾ã¾ã”使用ã«ãªã‚‹ã¨ã€ä¸å分ãªãƒ‘フォーマンスã—ã‹å¾—られãªã„ãŠãã‚ŒãŒã‚ã‚Šã¾ã™ã€‚
+ 警告: ã‚ãªãŸã®ã‚·ã‚¹ãƒ†ãƒ ã¯ [APP_NAME] を使用ã™ã‚‹ãŸã‚ã«å¿…è¦ãªå¿…須動作環境ã®æ¡ä»¶ã‚’満ãŸã—ã¦ã„ã¾ã›ã‚“。
+[APP_NAME] ã‚’ã“ã®ã¾ã¾ã”使用ã«ãªã‚‹ã¨ã€ä¸å分ãªãƒ‘フォーマンスã—ã‹å¾—られãªã„ãŠãã‚ŒãŒã‚ã‚Šã¾ã™ã€‚
ã¾ãŸã€ã‚µãƒãƒ¼ãƒˆå¤–ã®ã‚·ã‚¹ãƒ†ãƒ æ§‹æˆã§ã”使用ã®å ´åˆã€ãƒ†ã‚¯ãƒ‹ã‚«ãƒ«ã‚µãƒãƒ¼ãƒˆã‚’ã”利用ã„ãŸã ãã“ã¨ãŒã§ãã¾ã›ã‚“。
必須動作環境ã®æ¡ä»¶
@@ -518,7 +521,7 @@ Second Life ã‚’ã“ã®ã¾ã¾ã”使用ã«ãªã‚‹ã¨ã€ä¸å分ãªãƒ‘フォーマãƒ
<notification name="UnknownGPU">
ãŠä½¿ã„ã®ã‚·ã‚¹ãƒ†ãƒ ã«ã¯ã€ç¾æ™‚点ã§ã¯ä¸æ˜Žãªã‚°ãƒ©ãƒ•ã‚£ãƒƒã‚¯ãƒ»ã‚«ãƒ¼ãƒ‰ãŒæ­è¼‰ã•ã‚Œã¦ã„ã¾ã™ã€‚
ã“ã‚Œã¯ã€å½“社ã«ã‚ˆã‚‹å‹•ä½œãƒ†ã‚¹ãƒˆãŒè¡Œã‚ã‚Œã¦ã„ãªã„æ–°ã—ã„ãƒãƒ¼ãƒ‰ã‚¦ã‚§ã‚¢ãŒä½¿ç”¨ã•ã‚Œã¦ã„ã‚‹å ´åˆãŒã»ã¨ã‚“ã©ã§ã™ã€‚
-Second Life ã¯ã»ã¼é–“é•ã„ãªã正常ã«å‹•ä½œã—ã¾ã™ãŒã€
+[APP_NAME] ã¯ã»ã¼é–“é•ã„ãªã正常ã«å‹•ä½œã—ã¾ã™ãŒã€
å¿…è¦ã«å¿œã˜ãŸã‚°ãƒ©ãƒ•ã‚£ãƒƒã‚¯è¨­å®šã®èª¿æ•´ãŒå¿…è¦ã«ãªã‚‹å ´åˆãŒã‚ã‚Šã¾ã™ã€‚
(「編集ã€ï¼žã€Œç’°å¢ƒè¨­å®šã€ï¼žã€Œè¡¨ç¤ºã€ï¼‰
<form name="form">
@@ -526,7 +529,7 @@ Second Life ã¯ã»ã¼é–“é•ã„ãªã正常ã«å‹•ä½œã—ã¾ã™ãŒã€
</form>
</notification>
<notification name="DisplaySettingsNoShaders">
- [SECOND_LIFE] ã¯ã€
+ [APP_NAME] ã¯ã€
グラフィック・ドライãƒã®åˆæœŸåŒ–中ã«ã‚¯ãƒ©ãƒƒã‚·ãƒ¥ã—ã¾ã—ãŸã€‚
一般的ãªãƒ‰ãƒ©ã‚¤ãƒãƒ»ã‚¨ãƒ©ãƒ¼ã‚’回é¿ã™ã‚‹ãŸã‚ã€ã€Œå“質ãŠã‚ˆã³ãƒ‘フォーマンスã€ã¯ã€Œä½Žã€ã«è¨­å®šã•ã‚Œã¾ã™ã€‚
ã“ã‚Œã«ã‚ˆã‚Šã€ã„ãã¤ã‹ã®ã‚°ãƒ©ãƒ•ã‚£ãƒƒã‚¯ã‚¹æ©Ÿèƒ½ã¯ç„¡åŠ¹ã«ãªã‚Šã¾ã™ã€‚
@@ -828,7 +831,7 @@ Second Life ã¯ã»ã¼é–“é•ã„ãªã正常ã«å‹•ä½œã—ã¾ã™ãŒã€
ã“ã®åœŸåœ°ãŒã‚る地域を見ã¤ã‘ã‚‹ã“ã¨ãŒã§ãã¾ã›ã‚“
</notification>
<notification name="CannotCloseFloaterBuyLand">
- Second Lifeã«ã‚ˆã‚‹ã€
+ [APP_NAME]ã«ã‚ˆã‚‹ã€
ã“ã®å–引ã®è¦‹ç©ã‚ŠãŒå®Œäº†ã™ã‚‹ã¾ã§ã€ŒåœŸåœ°ã‚’購入ã€ã‚¦ã‚£ãƒ³ãƒ‰ã‚¦ã‚’é–‰ã˜ã‚‹ã“ã¨ã¯ã§ãã¾ã›ã‚“。
</notification>
<notification name="CannotDeedLandNothingSelected">
@@ -1009,7 +1012,7 @@ L$ã¯è¿”金ã•ã‚Œã¾ã›ã‚“。
「IMã¨ãƒãƒ£ãƒƒãƒˆã‚’表示ã€ã‚’クリックã™ã‚‹ã¨ã€
ç¾åœ¨ã‚ã‚‹IMã¨ãƒãƒ£ãƒƒãƒˆã‚’確èªã§ãã¾ã™ã€‚
確èªã—ãªã„å ´åˆã¯ã€Œçµ‚了ã€ã‚’クリックã—ã€
-ã™ãã«[SECOND_LIFE]を終了ã—ã¦ãã ã•ã„。
+ã™ãã«[APP_NAME]を終了ã—ã¦ãã ã•ã„。
<usetemplate name="okcancelbuttons" notext="終了" yestext="IMã¨ãƒãƒ£ãƒƒãƒˆã‚’表示"/>
</notification>
<notification name="OnlyOfficerCanBuyLand">
@@ -1187,7 +1190,7 @@ L$ã¯è¿”金ã•ã‚Œã¾ã›ã‚“。
</form>
</notification>
<notification name="FirstRun">
- [SECOND_LIFE]ã®ã‚¤ãƒ³ã‚¹ãƒˆãƒ¼ãƒ«ãŒå®Œäº†ã—ã¾ã—ãŸã€‚
+ [APP_NAME]ã®ã‚¤ãƒ³ã‚¹ãƒˆãƒ¼ãƒ«ãŒå®Œäº†ã—ã¾ã—ãŸã€‚
[SECOND_LIFE] ã®ä½¿ç”¨ãŒåˆã‚ã¦ã®æ–¹ã¯ã€
ログインå‰ã«ã‚¢ã‚«ã‚¦ãƒ³ãƒˆã®ä½œæˆãŒå¿…è¦ã§ã™ã€‚
@@ -1195,7 +1198,7 @@ www.secondlife.comã«ç§»å‹•ã—ã€æ–°è¦ã‚¢ã‚«ã‚¦ãƒ³ãƒˆã®ä½œæˆã‚’è¡Œã„ã¾ã™ã
<usetemplate name="okcancelbuttons" notext="続行" yestext="æ–°è¦ã‚¢ã‚«ã‚¦ãƒ³ãƒˆ..."/>
</notification>
<notification name="LoginPacketNeverReceived">
- 接続ã«å•é¡ŒãŒç”Ÿã˜ã¦ã„ã¾ã™ã€‚ ã‚ãªãŸã®ã‚¤ãƒ³ã‚¿ãƒ¼ãƒãƒƒãƒˆæŽ¥ç¶šã€ã¾ãŸã¯Second Life サーãƒãƒ¼ã«å•é¡ŒãŒã‚ã‚‹å¯èƒ½æ€§ãŒã‚ã‚Šã¾ã™ã€‚
+ 接続ã«å•é¡ŒãŒç”Ÿã˜ã¦ã„ã¾ã™ã€‚ ã‚ãªãŸã®ã‚¤ãƒ³ã‚¿ãƒ¼ãƒãƒƒãƒˆæŽ¥ç¶šã€ã¾ãŸã¯[SECOND_LIFE] サーãƒãƒ¼ã«å•é¡ŒãŒã‚ã‚‹å¯èƒ½æ€§ãŒã‚ã‚Šã¾ã™ã€‚
インターãƒãƒƒãƒˆæŽ¥ç¶šã‚’確èªã—ã¦æ•°åˆ†å¾Œã«ã‚‚ã†ä¸€åº¦è©¦ã¿ã‚‹ã‹ã€ã€Œãƒ˜ãƒ«ãƒ—ã€ã‚’クリックã—ã¦å½“社ã®ã‚µãƒãƒ¼ãƒˆã‚µã‚¤ãƒˆã«æŽ¥ç¶šã—ã¦ãã ã•ã„。ã¾ãŸã¯ã€ã€Œãƒ†ãƒ¬ãƒãƒ¼ãƒˆã€ã‚’クリックã—ã¦ãƒ›ãƒ¼ãƒ ã«ãƒ†ãƒ¬ãƒãƒ¼ãƒˆã—ã¦ã¿ã¦ãã ã•ã„。
<form name="form">
@@ -1306,35 +1309,35 @@ F1キーを押ã—ã¦ãã ã•ã„。
[DOWNLOAD_PATH]。
</notification>
<notification name="DownloadWindowsMandatory">
- [SECOND_LIFE]ã®æ–°ã—ã„ãƒãƒ¼ã‚¸ãƒ§ãƒ³ãŒåˆ©ç”¨å¯èƒ½ã§ã™ã€‚
+ [APP_NAME]ã®æ–°ã—ã„ãƒãƒ¼ã‚¸ãƒ§ãƒ³ãŒåˆ©ç”¨å¯èƒ½ã§ã™ã€‚
[MESSAGE]
-[SECOND_LIFE]を使用ã™ã‚‹ãŸã‚ã«ã¯ã€
+[APP_NAME]を使用ã™ã‚‹ãŸã‚ã«ã¯ã€
ã“ã®ã‚¢ãƒƒãƒ—デートをダウンロードã™ã‚‹å¿…è¦ãŒã‚ã‚Šã¾ã™ã€‚
<usetemplate name="okcancelbuttons" notext="終了" yestext="ダウンロード"/>
</notification>
<notification name="DownloadWindows">
- [SECOND_LIFE]ã®ã‚¢ãƒƒãƒ—デート・ãƒãƒ¼ã‚¸ãƒ§ãƒ³ãŒåˆ©ç”¨å¯èƒ½ã§ã™ã€‚
+ [APP_NAME]ã®ã‚¢ãƒƒãƒ—デート・ãƒãƒ¼ã‚¸ãƒ§ãƒ³ãŒåˆ©ç”¨å¯èƒ½ã§ã™ã€‚
[MESSAGE]
ã“ã®ã‚¢ãƒƒãƒ—デートã¯å¿…é ˆã§ã¯ã‚ã‚Šã¾ã›ã‚“ãŒã€ãƒ‘フォーマンスã¨å®‰å®šæ€§ã‚’å‘上ã•ã›ã‚‹ãŸã‚ã«ã‚¤ãƒ³ã‚¹ãƒˆãƒ¼ãƒ«ã™ã‚‹ã“ã¨ã‚’ãŠå‹§ã‚ã—ã¾ã™ã€‚
<usetemplate name="okcancelbuttons" notext="続行" yestext="ダウンロード"/>
</notification>
<notification name="DownloadWindowsReleaseForDownload">
- [SECOND_LIFE]ã®ã‚¢ãƒƒãƒ—デート・ãƒãƒ¼ã‚¸ãƒ§ãƒ³ãŒåˆ©ç”¨å¯èƒ½ã§ã™ã€‚
+ [APP_NAME]ã®ã‚¢ãƒƒãƒ—デート・ãƒãƒ¼ã‚¸ãƒ§ãƒ³ãŒåˆ©ç”¨å¯èƒ½ã§ã™ã€‚
[MESSAGE]
ã“ã®ã‚¢ãƒƒãƒ—デートã¯å¿…é ˆã§ã¯ã‚ã‚Šã¾ã›ã‚“ãŒã€ãƒ‘フォーマンスã¨å®‰å®šæ€§ã‚’å‘上ã•ã›ã‚‹ãŸã‚ã«ã‚¤ãƒ³ã‚¹ãƒˆãƒ¼ãƒ«ã™ã‚‹ã“ã¨ã‚’ãŠå‹§ã‚ã—ã¾ã™ã€‚
<usetemplate name="okcancelbuttons" notext="続行" yestext="ダウンロード"/>
</notification>
<notification name="DownloadMacMandatory">
- [SECOND_LIFE]ã®æ–°ã—ã„ãƒãƒ¼ã‚¸ãƒ§ãƒ³ãŒåˆ©ç”¨å¯èƒ½ã§ã™ã€‚
+ [APP_NAME]ã®æ–°ã—ã„ãƒãƒ¼ã‚¸ãƒ§ãƒ³ãŒåˆ©ç”¨å¯èƒ½ã§ã™ã€‚
[MESSAGE]
-[SECOND_LIFE]を使用ã™ã‚‹ãŸã‚ã«ã€
+[APP_NAME]を使用ã™ã‚‹ãŸã‚ã«ã€
ã“ã®ã‚¢ãƒƒãƒ—デートをダウンロードã™ã‚‹å¿…è¦ãŒã‚ã‚Šã¾ã™ã€‚
アプリケーションãŒã‚るフォルダã«ãƒ€ã‚¦ãƒ³ãƒ­ãƒ¼ãƒ‰ã—ã¾ã™ã‹ï¼Ÿ
<usetemplate name="okcancelbuttons" notext="終了" yestext="ダウンロード"/>
</notification>
<notification name="DownloadMac">
- [SECOND_LIFE]ã®ã‚¢ãƒƒãƒ—デート・ãƒãƒ¼ã‚¸ãƒ§ãƒ³ãŒåˆ©ç”¨å¯èƒ½ã§ã™ã€‚
+ [APP_NAME]ã®ã‚¢ãƒƒãƒ—デート・ãƒãƒ¼ã‚¸ãƒ§ãƒ³ãŒåˆ©ç”¨å¯èƒ½ã§ã™ã€‚
[MESSAGE]
ã“ã®ã‚¢ãƒƒãƒ—デートã¯å¿…é ˆã§ã¯ã‚ã‚Šã¾ã›ã‚“ãŒã€ãƒ‘フォーマンスã¨å®‰å®šæ€§ã‚’å‘上ã•ã›ã‚‹ãŸã‚ã«ã‚¤ãƒ³ã‚¹ãƒˆãƒ¼ãƒ«ã™ã‚‹ã“ã¨ã‚’ãŠå‹§ã‚ã—ã¾ã™ã€‚
@@ -1342,7 +1345,7 @@ F1キーを押ã—ã¦ãã ã•ã„。
<usetemplate name="okcancelbuttons" notext="続行" yestext="ダウンロード"/>
</notification>
<notification name="DownloadMacReleaseForDownload">
- [SECOND_LIFE]ã®ã‚¢ãƒƒãƒ—デート・ãƒãƒ¼ã‚¸ãƒ§ãƒ³ãŒåˆ©ç”¨å¯èƒ½ã§ã™ã€‚
+ [APP_NAME]ã®ã‚¢ãƒƒãƒ—デート・ãƒãƒ¼ã‚¸ãƒ§ãƒ³ãŒåˆ©ç”¨å¯èƒ½ã§ã™ã€‚
[MESSAGE]
ã“ã®ã‚¢ãƒƒãƒ—デートã¯å¿…é ˆã§ã¯ã‚ã‚Šã¾ã›ã‚“ãŒã€ãƒ‘フォーマンスã¨å®‰å®šæ€§ã‚’å‘上ã•ã›ã‚‹ãŸã‚ã«ã‚¤ãƒ³ã‚¹ãƒˆãƒ¼ãƒ«ã™ã‚‹ã“ã¨ã‚’ãŠå‹§ã‚ã—ã¾ã™ã€‚
@@ -2015,10 +2018,10 @@ RGBã€256x256ã§ã€ãƒãƒ£ãƒ³ãƒãƒ«æ•°ãŒ13
デフォルト: オフ
</notification>
<notification label="ボイスãƒãƒ¼ã‚¸ãƒ§ãƒ³ã®ä¸ä¸€è‡´" name="VoiceVersionMismatch">
- ã“ã®ãƒãƒ¼ã‚¸ãƒ§ãƒ³ã® Second Life ã¯ã€
+ ã“ã®ãƒãƒ¼ã‚¸ãƒ§ãƒ³ã® [APP_NAME] ã¯ã€
ã“ã®åœ°åŸŸã®ãƒœã‚¤ã‚¹ãƒãƒ£ãƒƒãƒˆæ©Ÿèƒ½ã«å¯¾å¿œã—ã¦ã„ã¾ã›ã‚“。
ボイスãƒãƒ£ãƒƒãƒˆã‚’æ­£ã—ã使用ã™ã‚‹ã«ã¯ã€
-Second Life ã®ã‚¢ãƒƒãƒ—デートãŒå¿…è¦ã§ã™ã€‚
+[APP_NAME] ã®ã‚¢ãƒƒãƒ—デートãŒå¿…è¦ã§ã™ã€‚
</notification>
<notification label="ä¸å‹•ç”£ç´„款" name="HelpEstateCovenant">
ä¸å‹•ç”£ç´„款を定ã‚ã‚‹ã¨ã€è‡ªåˆ†ã®ä¸å‹•ç”£å†…ã®åŒºç”»ã‚’販売ã§ãるよã†ã«ãªã‚Šã¾ã™ã€‚
@@ -2137,17 +2140,17 @@ Second Life ã®ã‚¢ãƒƒãƒ—デートãŒå¿…è¦ã§ã™ã€‚
ã“ã®ã‚ªãƒ–ジェクトã«ã¯ã€ã‚ãªãŸãŒã‚³ãƒ”ーã§ãるアイテムã¯ã‚ã‚Šã¾ã›ã‚“。
</notification>
<notification name="WebLaunchAccountHistory">
- Second Life ウェブ・ページを開ã„ã¦
+ [SECOND_LIFE] ウェブ・ページを開ã„ã¦
アカウント履歴を確èªã—ã¾ã™ã‹ï¼Ÿ
<usetemplate ignoretext="アカウント履歴ã®ã‚¦ã‚§ãƒ–・ページをロードã™ã‚‹ã¨ã" name="okcancelignore" notext="å–り消ã—" yestext="ページã«ç§»å‹•"/>
</notification>
<notification name="ClickOpenF1Help">
- Second Life ã®ã‚µãƒãƒ¼ãƒˆã‚¦ã‚§ãƒ–サイトを利用ã—ã¾ã™ã‹ï¼Ÿ
- <usetemplate ignoretext="Second Life ã®ã‚µãƒãƒ¼ãƒˆã‚¦ã‚§ãƒ–サイトを閲覧ã™ã‚‹ã«ã‚ãŸã£ã¦ã€‚" name="okcancelignore" notext="キャンセル" yestext="è¡Œã"/>
+ [SECOND_LIFE] ã®ã‚µãƒãƒ¼ãƒˆã‚¦ã‚§ãƒ–サイトを利用ã—ã¾ã™ã‹ï¼Ÿ
+ <usetemplate ignoretext="[SECOND_LIFE] ã®ã‚µãƒãƒ¼ãƒˆã‚¦ã‚§ãƒ–サイトを閲覧ã™ã‚‹ã«ã‚ãŸã£ã¦ã€‚" name="okcancelignore" notext="キャンセル" yestext="è¡Œã"/>
</notification>
<notification name="ConfirmQuit">
終了ã—よã†ã¨ã—ã¦ã„ã¾ã™ã€‚æ“作を続行ã—ã¾ã™ã‹ï¼Ÿ
- <usetemplate ignoretext="Second Life ã®çµ‚了ã«ã‚ãŸã£ã¦ã€‚" name="okcancelignore" notext="継続" yestext="終了"/>
+ <usetemplate ignoretext="[APP_NAME] ã®çµ‚了ã«ã‚ãŸã£ã¦ã€‚" name="okcancelignore" notext="継続" yestext="終了"/>
</notification>
<notification name="HelpReportAbuseEmailLL">
利用è¦ç´„é•åã¨ã‚³ãƒŸãƒ¥ãƒ‹ãƒ†ã‚£ãƒ¼ã‚¹ã‚¿ãƒ³ãƒ€ãƒ¼ãƒ‰é•åã®å ±å‘Šã«ã“ã®ãƒ„ールをã”使用ãã ã•ã„。 å‚照:
@@ -2172,9 +2175,9 @@ http://secondlife.com/support/incidentreport.php
(「世界ã€ã®ãƒ¡ãƒ‹ãƒ¥ãƒ¼ã‹ã‚‰ã€ŒåœŸåœ°æƒ…å ±ã€ã‚’é¸ã¶ã¨ã€ç´„款を閲覧ã§ãã¾ã™ï¼‰
-
ã“ã®ãƒ¬ãƒãƒ¼ãƒˆã«é–¢ã™ã‚‹è§£æ±ºç­–ã¯ã€ã“ã®åœ°åŸŸã«ã ã‘当ã¦ã¯ã¾ã‚Šã¾ã™ã€‚
-ä½äººãŒSecond Life ã®ä»–ã®åœ°åŸŸã¸ã‚¢ã‚¯ã‚»ã‚¹ã™ã‚‹éš›ã€
+ä½äººãŒ[SECOND_LIFE] ã®ä»–ã®åœ°åŸŸã¸ã‚¢ã‚¯ã‚»ã‚¹ã™ã‚‹éš›ã€
ã“ã®ãƒ¬ãƒãƒ¼ãƒˆã®çµæžœã«å½±éŸ¿ã•ã‚Œã‚‹ã“ã¨ã¯ã‚ã‚Šã¾ã›ã‚“。
-Linden Lab 社ã ã‘ãŒSecond Life 全域ã«ãŠã‘ã‚‹
+Linden Lab 社ã ã‘ãŒ[SECOND_LIFE] 全域ã«ãŠã‘ã‚‹
アクセス制é™æ¨©ã‚’æŒã£ã¦ã„ã¾ã™ã€‚
</notification>
<notification name="HelpReportBug">
@@ -2233,17 +2236,17 @@ http://secondlife.com/community/support.php
知的財産ã®ä¾µå®³ã«é–¢ã™ã‚‹å ±å‘Šã‚’è¡Œã†éš›ã«ã¯ã€ä»¥ä¸‹ã®ç‚¹ã«æ³¨æ„ã—ã¦ãã ã•ã„。
(1) å«ŒãŒã‚‰ã›ã®å ±å‘Šã®ãƒ—ロセス
-Second Life ã®æ¨©é™ã‚·ã‚¹ãƒ†ãƒ ã‚’悪用ã—ã¦ã„ã‚‹ä½äººã‚’見ã¤ã‘ãŸã‚‰ã€
+[SECOND_LIFE] ã®æ¨©é™ã‚·ã‚¹ãƒ†ãƒ ã‚’悪用ã—ã¦ã„ã‚‹ä½äººã‚’見ã¤ã‘ãŸã‚‰ã€
å«ŒãŒã‚‰ã›ã®å ±å‘Šã‚’è¡Œã£ã¦ãã ã•ã„。
例ãˆã°ã‚³ãƒ”ーBotã®ä½¿ç”¨ã€ãã‚Œã«ä¼¼ãŸãƒ„ールã®ä½¿ç”¨ã«ã‚ˆã‚‹çŸ¥çš„財産権ã®ä¾µå®³ãŒã‚ã‚Šã¾ã™ã€‚
アビューズãƒãƒ¼ãƒ ã¯èª¿æŸ»ã«åŸºã¥ãã€
-Second Life ã®ã‚³ãƒŸãƒ¥ãƒ‹ãƒ†ã‚£ãƒ¼ã‚¹ã‚¿ãƒ³ãƒ€ãƒ¼ãƒ‰ã‚„
+[SECOND_LIFE] ã®ã‚³ãƒŸãƒ¥ãƒ‹ãƒ†ã‚£ãƒ¼ã‚¹ã‚¿ãƒ³ãƒ€ãƒ¼ãƒ‰ã‚„
利用è¦ç´„ã«é•åã™ã‚‹è¡Œç‚ºã¨åˆ¤æ–­ã•ã‚ŒãŸå ´åˆã«ã¯é©åˆ‡ãªå‡¦ç½®ã‚’è¡Œã£ã¦ã„ã¾ã™ã€‚
-ãŸã ã—ã€ã‚³ãƒ³ãƒ†ãƒ³ãƒ„ã‚’Second Life ã‹ã‚‰æ’¤åŽ»ã—ã¦ã»ã—ã„ã€
+ãŸã ã—ã€ã‚³ãƒ³ãƒ†ãƒ³ãƒ„ã‚’[SECOND_LIFE] ã‹ã‚‰æ’¤åŽ»ã—ã¦ã»ã—ã„ã€
ã¨ã„ã£ãŸè¦æœ›ã«ã¯ã‚¢ãƒ“ューズãƒãƒ¼ãƒ ã¯å¿œãˆã‚‹ã“ã¨ãŒã§ãã¾ã›ã‚“。
(2) DMCA(デジタルミレニアム著作権法)åŠã³ã‚³ãƒ³ãƒ†ãƒ³ãƒ„撤去プロセス
-Second Life ã‹ã‚‰ã®ã‚³ãƒ³ãƒ†ãƒ³ãƒ„ã®æ’¤åŽ»ã‚’リクエストã™ã‚‹ã«ã¯ã€
+[SECOND_LIFE] ã‹ã‚‰ã®ã‚³ãƒ³ãƒ†ãƒ³ãƒ„ã®æ’¤åŽ»ã‚’リクエストã™ã‚‹ã«ã¯ã€
著作権侵害通知ã®æ出を行ã†å¿…è¦ãŒã‚ã‚Šã¾ã™ã€‚
å‚照: http://secondlife.com/corporate/dmca.php
@@ -2299,13 +2302,13 @@ Linden Lab
<usetemplate ignoretext="æŒã¡ç‰©å†…ã®ã€Œéºå¤±ç‰©ã€ãƒ•ã‚©ãƒ«ãƒ€ã‚’空ã«ã™ã‚‹ã¨ã" name="okcancelignore" notext="ã„ã„ãˆ" yestext="ã¯ã„"/>
</notification>
<notification name="CopySLURL">
- 以下ã®SLURLãŒã‚¯ãƒªãƒƒãƒ—ボードã«ã‚³ãƒ”ーã•ã‚Œã¾ã—ãŸã€‚
+ 以下ã®SLurlãŒã‚¯ãƒªãƒƒãƒ—ボードã«ã‚³ãƒ”ーã•ã‚Œã¾ã—ãŸã€‚
[SLURL]
ä»–ã®äººãŒã‚¢ã‚¯ã‚»ã‚¹ã—ã‚„ã™ã„よã†ã«ã‚¦ã‚§ãƒ–・ページã«è¼‰ã›ãŸã‚Šã€
ブラウザã®ã‚¢ãƒ‰ãƒ¬ã‚¹ãƒ»ãƒãƒ¼ã«è²¼ã‚Šä»˜ã‘ã¦ã€è‡ªåˆ†ã§ã‚¢ã‚¯ã‚»ã‚¹ã—ã¦ã¿ã¾ã—ょã†ã€‚
<form name="form">
- <ignore name="ignore" text="SLURLをクリップボードã«ã‚³ãƒ”ーã™ã‚‹ã¨ã"/>
+ <ignore name="ignore" text="SLurlをクリップボードã«ã‚³ãƒ”ーã™ã‚‹ã¨ã"/>
</form>
</notification>
<notification name="GraphicsPreferencesHelp">
@@ -2372,7 +2375,7 @@ Linden Lab
</notification>
<notification name="HelpDayCycle">
「デイ・サイクル編集ã€ã§ã¯ã€
-Second Life ã§ã®æ˜¼ã¨å¤œã®ç©ºã®å¤‰åŒ–を制御ã§ãã¾ã™ã€‚
+[SECOND_LIFE] ã§ã®æ˜¼ã¨å¤œã®ç©ºã®å¤‰åŒ–を制御ã§ãã¾ã™ã€‚
ã“ã‚Œã¯ã€ŒåŸºæœ¬ç’°å¢ƒç·¨é›†ã€ã®ã€Œæ™‚間帯ã€ã‚¹ãƒ©ã‚¤ãƒ€ãƒ¼ã§ä½¿ç”¨ã•ã‚Œã‚‹ã‚µã‚¤ã‚¯ãƒ«ã§ã™ã€‚
「デイ・サイクル編集ã€ã¯ã‚­ãƒ¼ãƒ•ãƒ¬ãƒ¼ãƒ ã‚’設定ã™ã‚‹ã“ã¨ã§æ©Ÿèƒ½ã—ã¾ã™ã€‚
@@ -2480,7 +2483,7 @@ Second Life ã§ã®æ˜¼ã¨å¤œã®ç©ºã®å¤‰åŒ–を制御ã§ãã¾ã™ã€‚
「Y〠ã®æ–¹å‘ã«é›²ãŒç§»å‹•ã™ã‚‹éš›ã®é€Ÿåº¦ã‚’制御ã—ã¾ã™ã€‚
</notification>
<notification name="HelpClassicClouds">
- ã“ã®ãƒœãƒƒã‚¯ã‚¹ã‚’有効ã«ã™ã‚‹ã¨ã€WindLight ã®é›²ã«åŠ ãˆã¦ã€Second Life ã®å¾“æ¥ã®é›²ã‚‚レンダリングã§ãるよã†ã«ãªã‚Šã¾ã™ã€‚
+ ã“ã®ãƒœãƒƒã‚¯ã‚¹ã‚’有効ã«ã™ã‚‹ã¨ã€WindLight ã®é›²ã«åŠ ãˆã¦ã€[SECOND_LIFE] ã®å¾“æ¥ã®é›²ã‚‚レンダリングã§ãるよã†ã«ãªã‚Šã¾ã™ã€‚
</notification>
<notification name="HelpWaterFogColor">
水中ã®ãƒ•ã‚©ã‚°åŠ¹æžœã«è‰²ã‚’ã¤ã‘ã¾ã™ã€‚
@@ -2581,7 +2584,7 @@ Second Life ã§ã®æ˜¼ã¨å¤œã®ç©ºã®å¤‰åŒ–を制御ã§ãã¾ã™ã€‚
<notification name="NotAgeVerified">
ã“ã®åŒºç”»ã«ã‚¢ã‚¯ã‚»ã‚¹ã™ã‚‹ãŸã‚ã«ã¯ã€
年齢確èªã‚’è¡Œã†å¿…è¦ãŒã‚ã‚Šã¾ã™ã€‚
-Second Life ã®ã‚¦ã‚§ãƒ–サイトã«ã‚¢ã‚¯ã‚»ã‚¹ã—ã€
+[SECOND_LIFE] ã®ã‚¦ã‚§ãƒ–サイトã«ã‚¢ã‚¯ã‚»ã‚¹ã—ã€
年齢確èªã‚’è¡Œã„ã¾ã™ã‹ï¼Ÿ
[_URL]
@@ -2592,7 +2595,7 @@ Second Life ã®ã‚¦ã‚§ãƒ–サイトã«ã‚¢ã‚¯ã‚»ã‚¹ã—ã€
</notification>
<notification name="Cannot enter parcel: no payment info on file">
ã“ã®åŒºç”»ã«ã‚¢ã‚¯ã‚»ã‚¹ã™ã‚‹ã«ã¯ã€æ”¯æ‰•ã„情報ãŒäº‹å‰ã«ç™»éŒ²ã•ã‚Œã¦ã„ã‚‹å¿…è¦ãŒã‚ã‚Šã¾ã™ã€‚
-Second Life ã®ã‚¦ã‚§ãƒ–サイトã«ã‚¢ã‚¯ã‚»ã‚¹ã—ã¦ã€è¨­å®šã—ã¾ã™ã‹ï¼Ÿ
+[SECOND_LIFE] ã®ã‚¦ã‚§ãƒ–サイトã«ã‚¢ã‚¯ã‚»ã‚¹ã—ã¦ã€è¨­å®šã—ã¾ã™ã‹ï¼Ÿ
[_URL]
<url name="url" option="0">
@@ -3052,7 +3055,7 @@ Second Life ã®ã‚¦ã‚§ãƒ–サイトã«ã‚¢ã‚¯ã‚»ã‚¹ã—ã¦ã€è¨­å®šã—ã¾ã™ã‹ï¼Ÿ
データベースã«[DESC]ã¨ã„ã†åå‰ã®[TYPE]ãŒè¦‹ã¤ã‹ã‚Šã¾ã›ã‚“ã§ã—ãŸã€‚
</notification>
<notification name="InvalidWearable">
- ç€ç”¨ã—よã†ã¨ã—ã¦ã„るアイテムã¯ã‚ãªãŸã®ãƒ“ューワã§ã¯èª­ã¿è¾¼ã‚€ã“ã¨ãŒã§ãã¾ã›ã‚“。 Second Lifeビューワを最新ã®ã‚‚ã®ã«ã‚¢ãƒƒãƒ—グレードã—ã¦ã‹ã‚‰ã“ã®ã‚¢ã‚¤ãƒ†ãƒ ã‚’ç€ç”¨ã—ã¦ãã ã•ã„。
+ ç€ç”¨ã—よã†ã¨ã—ã¦ã„るアイテムã¯ã‚ãªãŸã®ãƒ“ューワã§ã¯èª­ã¿è¾¼ã‚€ã“ã¨ãŒã§ãã¾ã›ã‚“。 [APP_NAME]ビューワを最新ã®ã‚‚ã®ã«ã‚¢ãƒƒãƒ—グレードã—ã¦ã‹ã‚‰ã“ã®ã‚¢ã‚¤ãƒ†ãƒ ã‚’ç€ç”¨ã—ã¦ãã ã•ã„。
</notification>
<notification name="ScriptQuestion">
「[NAME]ã€ãŒæ‰€æœ‰ã™ã‚‹ã‚ªãƒ–ジェクト「[OBJECTNAME]ã€ã‚’:
@@ -3161,11 +3164,11 @@ Mキーを押ã—ã¦å¤‰æ›´ã—ã¾ã™ã€‚
<notification name="FirstDebugMenus">
高度ãªè¨­å®šã‚’有効ã«ã—ã¾ã—ãŸã€‚
ã“ã®ãƒ¡ãƒ‹ãƒ¥ãƒ¼ã«ã¯ã€
-Second Life をデãƒãƒƒã‚°ã™ã‚‹ãƒ‡ãƒ™ãƒ­ãƒƒãƒ‘ーã«ã¨ã£ã¦
+[SECOND_LIFE] をデãƒãƒƒã‚°ã™ã‚‹ãƒ‡ãƒ™ãƒ­ãƒƒãƒ‘ーã«ã¨ã£ã¦
有用ãªæ©Ÿèƒ½ãŒã‚ã‚Šã¾ã™ã€‚
ã“ã®ãƒ¡ãƒ‹ãƒ¥ãƒ¼ã‚’切り替ãˆã‚‹ã«ã¯ã€
Windowsã§ã¯Ctrl-Alt-Dを押ã—ã¾ã™ã€‚
-Macã®å ´åˆã¯ã€Cmd-Opt-Shift-Dを押ã—ã¦ãã ã•ã„。
+Macã®å ´åˆã¯ã€&#8984;-Opt-Shift-Dを押ã—ã¦ãã ã•ã„。
</notification>
<notification name="FirstSculptedPrim">
スカルプトプリムを編集ã—ã¦ã„ã¾ã™ã€‚
@@ -3275,7 +3278,7 @@ Macã®å ´åˆã¯ã€Cmd-Opt-Shift-Dを押ã—ã¦ãã ã•ã„。
- ã‚ãªãŸã® CPU ã®é€Ÿåº¦ã¯å¿…須動作環境ã®æ¡ä»¶ã‚’満ãŸã—ã¦ã„ã¾ã›ã‚“。
</global>
<global name="UnsupportedGLRequirements">
- Second Life ã®ä½¿ç”¨ã«å¿…è¦ãªãƒãƒ¼ãƒ‰ã‚¦ã‚§ã‚¢ã®ç’°å¢ƒãŒæº€ãŸã•ã‚Œã¦ã„ãªã„よã†ã§ã™ã€‚ Second Life ã§ã¯ãƒžãƒ«ãƒãƒ†ã‚¯ã‚¹ãƒãƒ£ãƒ¼ã«å¯¾å¿œã—ãŸOpenGLグラフィック・カードãŒå¿…è¦ã§ã™ã€‚ ã“ã®å ´åˆã€ã‚°ãƒ©ãƒ•ã‚£ãƒƒã‚¯ãƒ»ã‚«ãƒ¼ãƒ‰ã®æœ€æ–°ãƒ‰ãƒ©ã‚¤ãƒãŒã‚¤ãƒ³ã‚¹ãƒˆãƒ¼ãƒ«ã•ã‚Œã¦ã„ã‚‹ã“ã¨ã€ãŠã‚ˆã³ã‚ªãƒšãƒ¬ãƒ¼ãƒ†ã‚£ãƒ³ã‚°ãƒ»ã‚·ã‚¹ãƒ†ãƒ ã«ã‚µãƒ¼ãƒ“ス・パックã¨ä¿®æ­£ãƒ—ログラムãŒé©ç”¨ã•ã‚Œã¦ã„ã‚‹ã“ã¨ã‚’ã”確èªãã ã•ã„。
+ [APP_NAME] ã®ä½¿ç”¨ã«å¿…è¦ãªãƒãƒ¼ãƒ‰ã‚¦ã‚§ã‚¢ã®ç’°å¢ƒãŒæº€ãŸã•ã‚Œã¦ã„ãªã„よã†ã§ã™ã€‚ [APP_NAME] ã§ã¯ãƒžãƒ«ãƒãƒ†ã‚¯ã‚¹ãƒãƒ£ãƒ¼ã«å¯¾å¿œã—ãŸOpenGLグラフィック・カードãŒå¿…è¦ã§ã™ã€‚ ã“ã®å ´åˆã€ã‚°ãƒ©ãƒ•ã‚£ãƒƒã‚¯ãƒ»ã‚«ãƒ¼ãƒ‰ã®æœ€æ–°ãƒ‰ãƒ©ã‚¤ãƒãŒã‚¤ãƒ³ã‚¹ãƒˆãƒ¼ãƒ«ã•ã‚Œã¦ã„ã‚‹ã“ã¨ã€ãŠã‚ˆã³ã‚ªãƒšãƒ¬ãƒ¼ãƒ†ã‚£ãƒ³ã‚°ãƒ»ã‚·ã‚¹ãƒ†ãƒ ã«ã‚µãƒ¼ãƒ“ス・パックã¨ä¿®æ­£ãƒ—ログラムãŒé©ç”¨ã•ã‚Œã¦ã„ã‚‹ã“ã¨ã‚’ã”確èªãã ã•ã„。
å•é¡ŒãŒè§£æ±ºã•ã‚Œãªã„å ´åˆã«ã¯ã€æ¬¡ã®ã‚µã‚¤ãƒˆã«ã‚¢ã‚¯ã‚»ã‚¹ã—ã¦ãã ã•ã„。 http://www.secondlife.com/support
</global>
diff --git a/indra/newview/skins/default/xui/ja/panel_login.xml b/indra/newview/skins/default/xui/ja/panel_login.xml
index 03e22dd9a2..dc57b51b0d 100644
--- a/indra/newview/skins/default/xui/ja/panel_login.xml
+++ b/indra/newview/skins/default/xui/ja/panel_login.xml
@@ -15,15 +15,9 @@
ログインä½ç½®ï¼š
</text>
<combo_box name="start_location_combo" left_delta="92" width="172">
- <combo_item name="MyHome">
- 自宅(ホーム)
- </combo_item>
- <combo_item name="MyLastLocation">
- 最後ã«ãƒ­ã‚°ã‚¢ã‚¦ãƒˆã—ãŸå ´æ‰€
- </combo_item>
- <combo_item name="Typeregionname">
- &lt; 地域ã®åå‰å…¥åŠ› &gt;
- </combo_item>
+ <combo_box.item name="MyHome" label="自宅(ホーム)" />
+ <combo_box.item name="MyLastLocation" label="最後ã«ãƒ­ã‚°ã‚¢ã‚¦ãƒˆã—ãŸå ´æ‰€" />
+ <combo_box.item name="Typeregionname" label="lt; 地域ã®åå‰å…¥åŠ› &gt;" />
</combo_box>
<check_box label="パスワードを記憶" name="remember_check" left_delta="180"/>
<text name="full_screen_text">
diff --git a/indra/newview/skins/default/xui/ja/panel_preferences_chat.xml b/indra/newview/skins/default/xui/ja/panel_preferences_chat.xml
index cc2421c9e9..875755a8c7 100644
--- a/indra/newview/skins/default/xui/ja/panel_preferences_chat.xml
+++ b/indra/newview/skins/default/xui/ja/panel_preferences_chat.xml
@@ -4,15 +4,9 @@
ãƒãƒ£ãƒƒãƒˆã®ãƒ•ã‚©ãƒ³ãƒˆï¼š
</text>
<radio_group name="chat_font_size">
- <radio_item length="1" name="radio" type="string">
- å°
- </radio_item>
- <radio_item length="1" name="radio2" type="string">
- 中
- </radio_item>
- <radio_item length="1" name="radio3" type="string">
- 大
- </radio_item>
+ <radio_item length="1" name="radio" type="string" label="å°" />
+ <radio_item length="1" name="radio2" type="string" label="中" />
+ <radio_item length="1" name="radio3" type="string" label="大" />
</radio_group>
<text length="1" name="text_box2" type="string">
ãƒãƒ£ãƒƒãƒˆãƒ»ã‚«ãƒ©ãƒ¼ï¼š
diff --git a/indra/newview/skins/default/xui/ja/panel_preferences_graphics1.xml b/indra/newview/skins/default/xui/ja/panel_preferences_graphics1.xml
index 167bc2a1ce..b70f04645f 100644
--- a/indra/newview/skins/default/xui/ja/panel_preferences_graphics1.xml
+++ b/indra/newview/skins/default/xui/ja/panel_preferences_graphics1.xml
@@ -21,21 +21,11 @@
ウィンドウ・サイズ:
</text>
<combo_box name="windowsize combo">
- <combo_item name="640x480">
- 640x480
- </combo_item>
- <combo_item name="800x600">
- 800x600
- </combo_item>
- <combo_item name="720x480">
- 720x480 (NTSC)
- </combo_item>
- <combo_item name="768x576">
- 768x576 (PAL)
- </combo_item>
- <combo_item name="1024x768">
- 1024x768
- </combo_item>
+ <combo_box.item name="640x480" label="640x480" />
+ <combo_box.item name="800x600" label="800x600" />
+ <combo_box.item name="720x480" label="720x480 (NTSC)" />
+ <combo_box.item name="768x576" label="768x576 (PAL)" />
+ <combo_box.item name="1024x768" label="1024x768" />
</combo_box>
<text name="DisplayResLabel">
表示解åƒåº¦ï¼š
@@ -44,18 +34,10 @@
縦横比:
</text>
<combo_box name="aspect_ratio" tool_tip="(幅/高ã•ï¼‰">
- <combo_item type="string" length="1" name="4:3(StandardCRT)">
- 4:3(標準CRT)
- </combo_item>
- <combo_item type="string" length="1" name="5:4(1280x1024LCD)">
- 5:4(1280x1024 LCD)
- </combo_item>
- <combo_item name="8:5(Widescreen)">
- 8:5(ワイドスクリï¼ãƒ³ï¼‰
- </combo_item>
- <combo_item type="string" length="1" name="16:9(Widescreen)">
- 16:9(ワイドスクリï¼ãƒ³ï¼‰
- </combo_item>
+ <combo_box.item type="string" length="1" name="4:3(StandardCRT)" label="4:3(標準CRT)" />
+ <combo_box.item type="string" length="1" name="5:4(1280x1024LCD)" label="5:4(1280x1024 LCD)" />
+ <combo_box.item name="8:5(Widescreen)" label="8:5(ワイドスクリï¼ãƒ³ï¼‰" />
+ <combo_box.item type="string" length="1" name="16:9(Widescreen)" label="16:9(ワイドスクリï¼ãƒ³ï¼‰" />
</combo_box>
<check_box label="自動検出率" name="aspect_auto_detect" />
<text type="string" length="1" name="UI Size:">
@@ -110,18 +92,10 @@
å射詳細:
</text>
<radio_group name="ReflectionDetailRadio">
- <radio_item name="0">
- 地形ã¨æ¨¹æœ¨
- </radio_item>
- <radio_item name="1">
- ã™ã¹ã¦ã®é™çš„オブジェクト
- </radio_item>
- <radio_item name="2">
- ã™ã¹ã¦ã®ã‚¢ãƒã‚¿ãƒ¼ã¨ã‚ªãƒ–ジェクト
- </radio_item>
- <radio_item name="3">
- ã™ã¹ã¦
- </radio_item>
+ <radio_item name="0" label="地形ã¨æ¨¹æœ¨" />
+ <radio_item name="1" label="ã™ã¹ã¦ã®é™çš„オブジェクト" />
+ <radio_item name="2" label="ã™ã¹ã¦ã®ã‚¢ãƒã‚¿ãƒ¼ã¨ã‚ªãƒ–ジェクト" />
+ <radio_item name="3" label="ã™ã¹ã¦" />
</radio_group>
<text name="AvatarRenderingText">
ã‚¢ãƒã‚¿ãƒ¼è¡¨ç¤ºï¼š
@@ -172,23 +146,15 @@
ライティング詳細:
</text>
<radio_group name="LightingDetailRadio">
- <radio_item name="SunMoon">
- 太陽ã¨æœˆã®ã¿
- </radio_item>
- <radio_item name="LocalLights">
- 近隣ã®ãƒ­ãƒ¼ã‚«ãƒ«ãƒ»ãƒ©ã‚¤ãƒˆ
- </radio_item>
+ <radio_item name="SunMoon" label="太陽ã¨æœˆã®ã¿" />
+ <radio_item name="LocalLights" label="近隣ã®ãƒ­ãƒ¼ã‚«ãƒ«ãƒ»ãƒ©ã‚¤ãƒˆ" />
</radio_group>
<text name="TerrainDetailText">
地形詳細:
</text>
<radio_group name="TerrainDetailRadio">
- <radio_item name="0">
- 低
- </radio_item>
- <radio_item name="2">
- 高
- </radio_item>
+ <radio_item name="0" label="低" />
+ <radio_item name="2" label="高" />
</radio_group>
<button label="推奨ã•ã‚ŒãŸè¨­å®š" name="Defaults" />
<button label="ãƒãƒ¼ãƒ‰ã‚¦ã‚§ã‚¢ãƒ»ã‚ªãƒ—ション"
diff --git a/indra/newview/skins/default/xui/ja/panel_status_bar.xml b/indra/newview/skins/default/xui/ja/panel_status_bar.xml
index 08c66182c4..d713d867c4 100644
--- a/indra/newview/skins/default/xui/ja/panel_status_bar.xml
+++ b/indra/newview/skins/default/xui/ja/panel_status_bar.xml
@@ -37,6 +37,6 @@
<text name="bandwidth_tooltip">
帯域幅
</text>
- <line_editor label="検索" name="search_editor" tool_tip="Second Lifeを検索"/>
- <button name="search_btn" tool_tip="Second Lifeを検索"/>
+ <line_editor label="検索" name="search_editor" tool_tip="[SECOND_LIFE]を検索"/>
+ <button name="search_btn" tool_tip="[SECOND_LIFE]を検索"/>
</panel>
diff --git a/indra/newview/skins/default/xui/nl/floater_about.xml b/indra/newview/skins/default/xui/nl/floater_about.xml
index 1e9551bb85..4d5d8b1032 100644
--- a/indra/newview/skins/default/xui/nl/floater_about.xml
+++ b/indra/newview/skins/default/xui/nl/floater_about.xml
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<floater name="floater_about" title="Over Second Life">
+<floater name="floater_about" title="Over [APP_NAME]">
<text_editor name="credits_editor">
Second Life wordt u aangeboden door Philip, Tessa, Andrew, Cory, James, Ben, Char, Charlie, Colin, Dan, Daniel, Doug, Eric, Hamlet, Haney, Eve, Hunter, Ian, Jeff, Jennifer, Jim, John, Lee, Mark, Peter, Phoenix, Richard, Robin, Xenon, Steve, Tanya, Eddie, Avi, Frank, Bruce, Aaron, Alice, Bob, Debra, Eileen, Helen, Janet, Louie, Leviathania, Stefan, Ray, Kevin, Tom, Mikeb, MikeT, Burgess, Elena, Tracy, Bill, Todd, Ryan, Zach, Sarah, Nova, Tim, Stephanie, Michael, Evan, Nicolas, Catherine, Rachelle, Dave, Holly, Bub, Kelly, Magellan, Ramzi, Don, Sabin, Jill, Rheya, Jeska, Torley, Kona, Callum, Charity, Ventrella, Jack, Vektor, Iris, Chris, Nicole, Mick, Reuben, Blue, Babbage, Yedwab, Deana, Lauren, Brent, Pathfinder, Chadrick, Altruima, Jesse, Teeny, Monroe, Icculus, David, Tess, Lizzie, Patsy, Isaac, Lawrence, Cyn, Bo, Gia, Annette, Marius, Tbone, Jonathan, Karen, Ginsu, Satoko, Yuko, Makiko, Thomas, Harry, Seth, Alexei, Brian, Guy, Runitai, Ethan, Data, Cornelius, Kenny, Swiss, Zero, Natria, Wendy, Stephen, Teeple, Thumper, Lucy, Dee, Mia, Liana, Warren, Branka, Aura, beez, Milo, Hermia, Red, Thrax, Joe, Sally, Magenta, Mogura, Paul, Jose, Rejean, Henrik, Lexie, Amber, Logan, Xan, Nora, Morpheus, Donovan, Leyla, MichaelFrancis, Beast, Cube, Bucky, Joshua, Stryfe, Harmony, Teresa, Claudia, Walker, Glenn, Fritz, Fordak, June, Cleopetra, Jean, Ivy, Betsy, Roosevelt, Spike, Ken, Which, Tofu, Chiyo, Rob, Zee, dustin, George, Del, Matthew, Cat, Jacqui, Lightfoot, Adrian, Viola, Alfred, Noel, Irfan, Sunil, Yool, Rika, Jane, Xtreme, Frontier, a2, Neo, Siobhan, Yoz, Justin, Elle, Qarl, Benjamin, Isabel, Gulliver, Everett, Christopher, Izzy, Stephany, Garry, Sejong, Sean, Tobin, Iridium, Meta, Anthony, Jeremy, JP, Jake, Maurice, Madhavi, Leopard, Kyle, Joon, Kari, Bert, Belinda, Jon, Kristi, Bridie, Pramod, KJ, Socrates, Maria, Ivan, Aric, Yamasaki, Adreanne, Jay, MitchK, Ceren, Coco, Durl, Jenny, Periapse, Kartic, Storrs, Lotte, Sandy, Rohn, Colossus, Zen, BigPapi, Brad, Pastrami, Kurz, Mani, Neuro, Jaime, MJ, Rowan, Sgt, Elvis, Gecko, Samuel, Sardonyx, Leo, Bryan, Niko, Soft, Poppy, Rachel, Aki, Angelo, Banzai, Alexa, Sue, CeeLo, Bender, CG, Gillian, Pelle, Nick, Echo, Zara, Christine, Shamiran, Emma, Blake, Keiko, Plexus, Joppa, Sidewinder, Erica, Ashlei, Twilight, Kristen, Brett, Q, Enus, Simon, Bevis, Kraft, Kip, Chandler, Ron, LauraP, Ram, KyleJM, Scouse, Prospero, Melissa, Marty, Nat, Hamilton, Kend, Lordan, Jimmy, Kosmo, Seraph, Green, Ekim, Wiggo, JT, Rome, Doris, Miz, Benoc, Whump, Trinity, Patch, Kate, TJ, Bao, Joohwan, Christy, Sofia, Matias, Cogsworth, Johan, Oreh, Cheah, Angela, Brandy, Mango, Lan, Aleks, Gloria, Heidy, Mitchell, Space, Colton, Bambers, Einstein, Maggie, Malbers, Rose, Winnie, Stella, Milton, Rothman, Niall, Marin, Allison, Katie, Dawn, Katt, Dusty, Kalpana, Judy, Andrea, Ambroff, Infinity, Gail, Rico, Raymond, Yi, William, Christa, M, Teagan, Scout, Molly, Dante, Corr, Dynamike, Usi, Kaylee, Vidtuts, Lil, Danica, Sascha, Kelv, Jacob, Nya, Rodney, Brandon, Elsie, Blondin, Grant, Katrin, Nyx, Gabriel, Locklainn, Claire, Devin, Minerva, Monty, Austin, Bradford, Si, Keira, H, Caitlin, Dita, Makai, Jenn, Ann, Meredith, Clare, Joy, Praveen, Cody, Edmund, Ruthe, Sirena, Gayathri, Spider, FJ, Davidoff, Tian, Jennie, Louise, Oskar, Landon, Noelle, Jarv, Ingrid, Al, Sommer, Doc, Aria, Huin, Gray, Lili, Vir, DJ, Yang, T, Simone, Maestro, Scott, Charlene, Quixote, Amanda, Susan, Zed, Anne, Enkidu, Esbee, Joroan, Katelin, Roxie, Tay, Scarlet, Kevin, Johnny, Wolfgang, Andren, Bob, Howard, Merov, Rand, Ray, Michon, Newell, Galen, Dessie, Les, Michon, Jenelle, Geo, Siz, Shapiro, Pete, Calyle, Selene, Allen, Phoebe, Goldin, Kimmora, Dakota, Slaton, Lindquist, Zoey, Hari, Othello, Rohit, Sheldon, Petra, Viale, Gordon, Kaye, Pink, Ferny, Emerson, Davy, Bri, Chan, Juan, Robert, Terrence, Nathan, Carl and many others.
diff --git a/indra/newview/skins/default/xui/nl/floater_buy_land.xml b/indra/newview/skins/default/xui/nl/floater_buy_land.xml
index ab4bec7787..1bb02cc7d0 100644
--- a/indra/newview/skins/default/xui/nl/floater_buy_land.xml
+++ b/indra/newview/skins/default/xui/nl/floater_buy_land.xml
@@ -75,15 +75,9 @@ verkocht met objecten
Alleen premiumleden kunnen land bezitten.
</text>
<combo_box name="account_level">
- <combo_item name="US$9.95/month,billedmonthly">
- US$9.95/maand, gefactureerd per maand
- </combo_item>
- <combo_item name="US$7.50/month,billedquarterly">
- US$7.50/maand, gefactureerd per kwartaal
- </combo_item>
- <combo_item name="US$6.00/month,billedannually">
- US$6.00/maand, gefactureerd per jaar
- </combo_item>
+ <combo_box.item name="US$9.95/month,billedmonthly" label="US$9.95/maand, gefactureerd per maand"/>
+ <combo_box.item name="US$7.50/month,billedquarterly" label="US$7.50/maand, gefactureerd per kwartaal"/>
+ <combo_box.item name="US$6.00/month,billedannually" label="US$6.00/maand, gefactureerd per jaar"/>
</combo_box>
<text name="land_use_action">
Verhoog uw maandelijkse landgebruikskosten tot US$ 40/maand
diff --git a/indra/newview/skins/default/xui/nl/floater_customize.xml b/indra/newview/skins/default/xui/nl/floater_customize.xml
index de42aa85e3..a94f4f2348 100644
--- a/indra/newview/skins/default/xui/nl/floater_customize.xml
+++ b/indra/newview/skins/default/xui/nl/floater_customize.xml
@@ -14,12 +14,8 @@
<button label="Torso" label_selected="Torso" name="Torso"/>
<button label="Benen" label_selected="Benen" name="Legs"/>
<radio_group name="sex radio">
- <radio_item name="radio">
- Vrouw
- </radio_item>
- <radio_item name="radio2">
- Man
- </radio_item>
+ <radio_item name="radio" label="Vrouw" />
+ <radio_item name="radio2" label="Man" />
</radio_group>
<text name="title">
[DESC]
diff --git a/indra/newview/skins/default/xui/nl/floater_postcard.xml b/indra/newview/skins/default/xui/nl/floater_postcard.xml
index f31b479576..9ca6fcc026 100644
--- a/indra/newview/skins/default/xui/nl/floater_postcard.xml
+++ b/indra/newview/skins/default/xui/nl/floater_postcard.xml
@@ -25,7 +25,7 @@
<button label="Annuleren" name="cancel_btn"/>
<button label="Verzenden" name="send_btn"/>
<string name="default_subject">
- Ansichtkaart uit Second Life
+ Ansichtkaart uit [SECOND_LIFE]
</string>
<string name="default_message">
Kom dit zien!
diff --git a/indra/newview/skins/default/xui/nl/floater_report_abuse.xml b/indra/newview/skins/default/xui/nl/floater_report_abuse.xml
index 1f64c8719c..e82a5a3b89 100644
--- a/indra/newview/skins/default/xui/nl/floater_report_abuse.xml
+++ b/indra/newview/skins/default/xui/nl/floater_report_abuse.xml
@@ -36,123 +36,51 @@
Hendrerit Vulputate
</text>
<combo_box name="category_combo" tool_tip="Categorie -- selecteer de categorie die dit rapport het best beschrijft">
- <combo_item name="Select_category">
- Selecteer categorie
- </combo_item>
- <combo_item name="Age__Age_play">
- Leeftijd &gt; Leeftijd spelen
- </combo_item>
- <combo_item name="Age__Adult_resident_on_Teen_Second_Life">
- Leeftijd &gt; Volwassen inwoner in Teen Second Life
- </combo_item>
+ <combo_box.item name="Select_category" label="Selecteer categorie"/>
+ <combo_box.item name="Age__Age_play" label="Leeftijd &gt; Leeftijd spelen"/>
+ <combo_box.item name="Age__Adult_resident_on_Teen_Second_Life" label="Leeftijd &gt; Volwassen inwoner in Teen Second Life"/>
<combo_item name="Age__Underage_resident_outside_of_Teen_Second_Life">
Leeftijd &gt; Minderjarige inwoner buiten Teen Second Life
</combo_item>
- <combo_item name="Assault__Combat_sandbox___unsafe_area">
- Aanval &gt; Gevechtszandbak / onveilig gebied
- </combo_item>
- <combo_item name="Assault__Safe_area">
- Aanval &gt; Veilig gebied
- </combo_item>
- <combo_item name="Assault__Weapons_testing_sandbox">
- Aanval &gt; Zandbak voor het testen van wapens
- </combo_item>
- <combo_item name="Commerce__Failure_to_deliver_product_or_service">
- Handel &gt; Product of dienst is niet geleverd
- </combo_item>
- <combo_item name="Disclosure__Real_world_information">
- Openbaring &gt; Echte wereld informatie
- </combo_item>
- <combo_item name="Disclosure__Remotely_monitoring chat">
- Openbaring &gt; Op afstand chat afluisteren
- </combo_item>
- <combo_item name="Disclosure__Second_Life_information_chat_IMs">
- Openbaring &gt; Second Life informatie/chat/IMs
- </combo_item>
- <combo_item name="Disturbing_the_peace__Unfair_use_of_region_resources">
- Vredebreuk &gt; Oneerlijk gebruik van regiomiddelen
- </combo_item>
- <combo_item name="Disturbing_the_peace__Excessive_scripted_objects">
- Vredebreuk &gt; Excessieve gescripte objecten
- </combo_item>
- <combo_item name="Disturbing_the_peace__Object_littering">
- Vredebreuk &gt; Objecten laten rondslingeren
- </combo_item>
- <combo_item name="Disturbing_the_peace__Repetitive_spam">
- Vredebreuk &gt; Herhaalde spam
- </combo_item>
- <combo_item name="Disturbing_the_peace__Unwanted_advert_spam">
- Vredebreuk &gt; Ongewenste reclame-spam
- </combo_item>
- <combo_item name="Fraud__L$">
- Fraude &gt; L$
- </combo_item>
- <combo_item name="Fraud__Land">
- Fraude &gt; Land
- </combo_item>
- <combo_item name="Fraud__Pyramid_scheme_or_chain_letter">
- Fraude &gt; Piramideschema of kettingbrief
- </combo_item>
- <combo_item name="Fraud__US$">
- Fraude &gt; US$
- </combo_item>
- <combo_item name="Harassment__Advert_farms___visual_spam">
- Intimidatie &gt; Reclameverzamelingen / visuele spam
- </combo_item>
- <combo_item name="Harassment__Defaming_individuals_or_groups">
- Intimidatie &gt; Individuen of groepen in diskrediet brengen
- </combo_item>
- <combo_item name="Harassment__Impeding_movement">
- Intimidatie &gt; Beweging verhinderen
- </combo_item>
- <combo_item name="Harassment__Sexual_harassment">
- Intimidatie &gt; Seksuele intimidatie
- </combo_item>
- <combo_item name="Harassment__Solicting_inciting_others_to_violate_ToS">
- Intimidatie &gt; Anderen uitnodigen/aanzetten tot het schenden van de ToS
- </combo_item>
- <combo_item name="Harassment__Verbal_abuse">
- Intimidatie &gt; Verbaal misbruik
- </combo_item>
- <combo_item name="Indecency__Broadly_offensive_content_or_conduct">
- Onfatsoenlijkheid &gt; Globaal beledigende inhoud of gedrag
- </combo_item>
- <combo_item name="Indecency__Inappropriate_avatar_name">
- Onfatsoenlijkheid &gt; Ongepaste avatar naam
- </combo_item>
+ <combo_box.item name="Assault__Combat_sandbox___unsafe_area" label="Aanval &gt; Gevechtszandbak / onveilig gebied"/>
+ <combo_box.item name="Assault__Safe_area" label="Aanval &gt; Veilig gebied"/>
+ <combo_box.item name="Assault__Weapons_testing_sandbox" label="Aanval &gt; Zandbak voor het testen van wapens"/>
+ <combo_box.item name="Commerce__Failure_to_deliver_product_or_service" label="Handel &gt; Product of dienst is niet geleverd"/>
+ <combo_box.item name="Disclosure__Real_world_information" label="Openbaring &gt; Echte wereld informatie"/>
+ <combo_box.item name="Disclosure__Remotely_monitoring chat" label="Openbaring &gt; Op afstand chat afluisteren"/>
+ <combo_box.item name="Disclosure__Second_Life_information_chat_IMs" label="Openbaring &gt; Second Life informatie/chat/IMs"/>
+ <combo_box.item name="Disturbing_the_peace__Unfair_use_of_region_resources" label="Vredebreuk &gt; Oneerlijk gebruik van regiomiddelen"/>
+ <combo_box.item name="Disturbing_the_peace__Excessive_scripted_objects" label="Vredebreuk &gt; Excessieve gescripte objecten"/>
+ <combo_box.item name="Disturbing_the_peace__Object_littering" label="Vredebreuk &gt; Objecten laten rondslingeren"/>
+ <combo_box.item name="Disturbing_the_peace__Repetitive_spam" label="Vredebreuk &gt; Herhaalde spam"/>
+ <combo_box.item name="Disturbing_the_peace__Unwanted_advert_spam" label="Vredebreuk &gt; Ongewenste reclame-spam"/>
+ <combo_box.item name="Fraud__L$" label="Fraude &gt; L$"/>
+ <combo_box.item name="Fraud__Land" label="Fraude &gt; Land"/>
+ <combo_box.item name="Fraud__Pyramid_scheme_or_chain_letter" label="Fraude &gt; Piramideschema of kettingbrief"/>
+ <combo_box.item name="Fraud__US$" label="Fraude &gt; US$"/>
+ <combo_box.item name="Harassment__Advert_farms___visual_spam" label="Intimidatie &gt; Reclameverzamelingen / visuele spam"/>
+ <combo_box.item name="Harassment__Defaming_individuals_or_groups" label="Intimidatie &gt; Individuen of groepen in diskrediet brengen"/>
+ <combo_box.item name="Harassment__Impeding_movement" label="Intimidatie &gt; Beweging verhinderen"/>
+ <combo_box.item name="Harassment__Sexual_harassment" label="Intimidatie &gt; Seksuele intimidatie"/>
+ <combo_box.item name="Harassment__Solicting_inciting_others_to_violate_ToS" label="Intimidatie &gt; Anderen uitnodigen/aanzetten tot het schenden van de ToS"/>
+ <combo_box.item name="Harassment__Verbal_abuse" label="Intimidatie &gt; Verbaal misbruik"/>
+ <combo_box.item name="Indecency__Broadly_offensive_content_or_conduct" label="Onfatsoenlijkheid &gt; Globaal beledigende inhoud of gedrag"/>
+ <combo_box.item name="Indecency__Inappropriate_avatar_name" label="Onfatsoenlijkheid &gt; Ongepaste avatar naam"/>
<combo_item name="Indecency__Mature_content_in_PG_region">
Onfatsoenlijkheid &gt; Ongepaste inhoud of gedrag in een PG regio
</combo_item>
<combo_item name="Indecency__Inappropriate_content_in_Mature_region">
Onfatsoenlijkheid &gt; Ongepaste inhoud of gedrag in een Mature regio
</combo_item>
- <combo_item name="Intellectual_property_infringement_Content_Removal">
- Inbreuk op intellectueel eigendom &gt; Verwijderen van inhoud
- </combo_item>
- <combo_item name="Intellectual_property_infringement_CopyBot_or_Permissions_Exploit">
- Inbreuk op intellectueel eigendom &gt; CopyBot of misbruik van permissies
- </combo_item>
- <combo_item name="Intolerance">
- Intolerantie
- </combo_item>
- <combo_item name="Land__Abuse_of_sandbox_resources">
- Land &gt; Misbruik van zandbakmiddelen
- </combo_item>
- <combo_item name="Land__Encroachment__Objects_textures">
- Land &gt; Indringing &gt; Objecten/texturen
- </combo_item>
- <combo_item name="Land__Encroachment__Particles">
- Land &gt; Indringing &gt; Particles
- </combo_item>
- <combo_item name="Land__Encroachment__Trees_plants">
- Land &gt; Indringing &gt; Bomen/planten
- </combo_item>
- <combo_item name="Wagering_gambling">
- Weddenschappen/gokken
- </combo_item>
- <combo_item name="Other">
- Anders
- </combo_item>
+ <combo_box.item name="Intellectual_property_infringement_Content_Removal" label="Inbreuk op intellectueel eigendom &gt; Verwijderen van inhoud"/>
+ <combo_box.item name="Intellectual_property_infringement_CopyBot_or_Permissions_Exploit" label="Inbreuk op intellectueel eigendom &gt; CopyBot of misbruik van permissies"/>
+ <combo_box.item name="Intolerance" label="Intolerantie"/>
+ <combo_box.item name="Land__Abuse_of_sandbox_resources" label="Land &gt; Misbruik van zandbakmiddelen"/>
+ <combo_box.item name="Land__Encroachment__Objects_textures" label="Land &gt; Indringing &gt; Objecten/texturen"/>
+ <combo_box.item name="Land__Encroachment__Particles" label="Land &gt; Indringing &gt; Particles"/>
+ <combo_box.item name="Land__Encroachment__Trees_plants" label="Land &gt; Indringing &gt; Bomen/planten"/>
+ <combo_box.item name="Wagering_gambling" label="Weddenschappen/gokken"/>
+ <combo_box.item name="Other" label="Anders"/>
</combo_box>
<text name="abuser_name_title">
Misbruikernaam:
diff --git a/indra/newview/skins/default/xui/nl/floater_sell_land.xml b/indra/newview/skins/default/xui/nl/floater_sell_land.xml
index 0208886813..ed5cd50165 100644
--- a/indra/newview/skins/default/xui/nl/floater_sell_land.xml
+++ b/indra/newview/skins/default/xui/nl/floater_sell_land.xml
@@ -36,15 +36,9 @@ verkopen:
Kies of u aan iedereen wil verkopen of een specifieke koper.
</text>
<combo_box name="sell_to">
- <combo_item name="--selectone--">
- -- selecteer een --
- </combo_item>
- <combo_item name="Anyone">
- Iedereen
- </combo_item>
- <combo_item name="Specificuser:">
- Specifieke gebruiker:
- </combo_item>
+ <combo_box.item name="--selectone--" label="selecteer een --"/>
+ <combo_box.item name="Anyone" label="Iedereen"/>
+ <combo_box.item name="Specificuser:" label="Specifieke gebruiker:"/>
</combo_box>
<button label="Selecteren..." name="sell_to_select_agent"/>
<text name="sell_objects_label">
@@ -55,12 +49,8 @@ verkopen:
zullen van eigenaar veranderen.
</text>
<radio_group name="sell_objects" bottom_delta="-58">
- <radio_item name="no">
- Nee, behoud het eigendom van objecten
- </radio_item>
- <radio_item name="yes">
- Ja, verkoop objecten met het land
- </radio_item>
+ <radio_item name="no" label="Nee, behoud het eigendom van objecten" />
+ <radio_item name="yes" label="Ja, verkoop objecten met het land" />
</radio_group>
<button label="Toon objecten" name="show_objects"/>
<text name="nag_message_label">
diff --git a/indra/newview/skins/default/xui/nl/floater_snapshot.xml b/indra/newview/skins/default/xui/nl/floater_snapshot.xml
index 52583f3c55..c7174d42f3 100644
--- a/indra/newview/skins/default/xui/nl/floater_snapshot.xml
+++ b/indra/newview/skins/default/xui/nl/floater_snapshot.xml
@@ -4,15 +4,9 @@
Fotobestemming
</text>
<radio_group label="Fototype" name="snapshot_type_radio">
- <radio_item name="postcard">
- Verzend via e-mail
- </radio_item>
- <radio_item name="texture">
- Opslaan in uw inventaris (L$[AMOUNT])
- </radio_item>
- <radio_item name="local">
- Opslaan op uw harde schijf
- </radio_item>
+ <radio_item name="postcard" label="Verzend via e-mail" />
+ <radio_item name="texture" label="Opslaan in uw inventaris (L$[AMOUNT])" />
+ <radio_item name="local" label="Opslaan op uw harde schijf" />
</radio_group>
<text name="file_size_label">
Bestandsgrootte: [SIZE] KB
@@ -21,12 +15,8 @@
<button label="Verzenden" name="send_btn"/>
<button label="Opslaan (L$[AMOUNT])" name="upload_btn"/>
<flyout_button label="Opslaan" name="save_btn" tool_tip="Afbeelding in een bestand opslaan">
- <flyout_button_item name="save_item">
- Opslaan
- </flyout_button_item>
- <flyout_button_item name="saveas_item">
- Opslaan als...
- </flyout_button_item>
+ <flyout_button_item name="save_item" label="Opslaan"/>
+ <flyout_button_item name="saveas_item" label="Opslaan als..."/>
</flyout_button>
<button label="Annuleren" name="discard_btn"/>
<button label="Meer &gt;&gt;" name="more_btn" tool_tip="Geavanceerde opties"/>
@@ -38,75 +28,33 @@
Formaat
</text>
<combo_box label="Resolutie" name="postcard_size_combo">
- <combo_item name="CurrentWindow">
- Huidig venster
- </combo_item>
- <combo_item name="640x480">
- 640x480
- </combo_item>
- <combo_item name="800x600">
- 800x600
- </combo_item>
- <combo_item name="1024x768">
- 1024x768
- </combo_item>
- <combo_item name="Custom">
- Aangepast
- </combo_item>
+ <combo_box.item name="CurrentWindow" label="Huidig venster"/>
+ <combo_box.item name="640x480" label="640x480"/>
+ <combo_box.item name="800x600" label="800x600"/>
+ <combo_box.item name="1024x768" label="1024x768"/>
+ <combo_box.item name="Custom" label="Aangepast"/>
</combo_box>
<combo_box label="Resolutie" name="texture_size_combo">
- <combo_item name="CurrentWindow">
- Huidig venster
- </combo_item>
- <combo_item name="Small(128x128)">
- Klein (128x128)
- </combo_item>
- <combo_item name="Medium(256x256)">
- Middel (256x256)
- </combo_item>
- <combo_item name="Large(512x512)">
- Groot (512x512)
- </combo_item>
- <combo_item name="Custom">
- Aangepast
- </combo_item>
+ <combo_box.item name="CurrentWindow" label="Huidig venster"/>
+ <combo_box.item name="Small(128x128)" label="Klein (128x128)"/>
+ <combo_box.item name="Medium(256x256)" label="Middel (256x256)"/>
+ <combo_box.item name="Large(512x512)" label="Groot (512x512)"/>
+ <combo_box.item name="Custom" label="Aangepast"/>
</combo_box>
<combo_box label="Resolutie" name="local_size_combo">
- <combo_item name="CurrentWindow">
- Huidig venster
- </combo_item>
- <combo_item name="320x240">
- 320x240
- </combo_item>
- <combo_item name="640x480">
- 640x480
- </combo_item>
- <combo_item name="800x600">
- 800x600
- </combo_item>
- <combo_item name="1024x768">
- 1024x768
- </combo_item>
- <combo_item name="1280x1024">
- 1280x1024
- </combo_item>
- <combo_item name="1600x1200">
- 1600x1200
- </combo_item>
- <combo_item name="Custom">
- Aangepast
- </combo_item>
+ <combo_box.item name="CurrentWindow" label="Huidig venster"/>
+ <combo_box.item name="320x240" label="320x240"/>
+ <combo_box.item name="640x480" label="640x480"/>
+ <combo_box.item name="800x600" label="800x600"/>
+ <combo_box.item name="1024x768" label="1024x768"/>
+ <combo_box.item name="1280x1024" label="1280x1024"/>
+ <combo_box.item name="1600x1200" label="1600x1200"/>
+ <combo_box.item name="Custom" label="Aangepast"/>
</combo_box>
<combo_box label="Formaat" name="local_format_combo">
- <combo_item name="PNG">
- PNG
- </combo_item>
- <combo_item name="JPEG">
- JPEG
- </combo_item>
- <combo_item name="BMP">
- BMP
- </combo_item>
+ <combo_box.item name="PNG" label="PNG"/>
+ <combo_box.item name="JPEG" label="JPEG"/>
+ <combo_box.item name="BMP" label="BMP"/>
</combo_box>
<spinner label="Breedte" name="snapshot_width" label_width="48" width="100"/>
<spinner label="Hoogte" name="snapshot_height" label_width="41" width="95" left="114"/>
@@ -116,15 +64,9 @@
Vastleggen:
</text>
<combo_box label="Afbeeldingslagen" name="layer_types" width="130" left="76">
- <combo_item name="Colors">
- Kleuren
- </combo_item>
- <combo_item name="Depth">
- Diepte
- </combo_item>
- <combo_item name="ObjectMattes">
- Object matheid
- </combo_item>
+ <combo_box.item name="Colors" label="Kleuren"/>
+ <combo_box.item name="Depth" label="Diepte"/>
+ <combo_box.item name="ObjectMattes" label="Object matheid"/>
</combo_box>
<check_box label="Toon interface in foto" name="ui_check"/>
<check_box label="Toon HUD objecten in foto" name="hud_check"/>
diff --git a/indra/newview/skins/default/xui/nl/floater_tos.xml b/indra/newview/skins/default/xui/nl/floater_tos.xml
index a8f08a09a9..d71412664c 100644
--- a/indra/newview/skins/default/xui/nl/floater_tos.xml
+++ b/indra/newview/skins/default/xui/nl/floater_tos.xml
@@ -5,7 +5,7 @@
<check_box label="Ik ga akkoord met de voorwaarden van service" name="agree_chk"/>
<text name="tos_heading">
Leest u alstublieft de volgende voorwaarden van service door. Om door te gaan met inloggen in
-Second Life dient u de overeenkomst te accepteren.
+[SECOND_LIFE] dient u de overeenkomst te accepteren.
</text>
<text_editor name="tos_text">
TOS_TEXT
diff --git a/indra/newview/skins/default/xui/nl/floater_world_map.xml b/indra/newview/skins/default/xui/nl/floater_world_map.xml
index a13eba4dc7..4385442cd3 100644
--- a/indra/newview/skins/default/xui/nl/floater_world_map.xml
+++ b/indra/newview/skins/default/xui/nl/floater_world_map.xml
@@ -29,14 +29,10 @@
<check_box label="Mature" name="event_mature_chk"/>
<check_box label="Adult" name="event_adult_chk"/>
<combo_box label="Online vrienden" name="friend combo" tool_tip="Vriend die op kaart getoond wordt">
- <combo_item name="none_selected">
- Online vrienden
- </combo_item>
+ <combo_box.item name="none_selected" label="Online vrienden"/>
</combo_box>
<combo_box label="Landmarkeringen" name="landmark combo" tool_tip="Landmarkering die op kaart getoond wordt">
- <combo_item name="none_selected">
- Landmarkeringen
- </combo_item>
+ <combo_box.item name="none_selected" label="Landmarkeringen"/>
</combo_box>
<line_editor label="Zoek op regionaam" name="location" tool_tip="Type de naam van een regio"/>
<button label="Zoeken" name="DoSearch" tool_tip="Zoek naar regio"/>
@@ -53,6 +49,6 @@
<button label="Toon bestemming" label_selected="Toon bestemming" name="Show Destination" tool_tip="Centreer kaart op geselecteerde locatie"/>
<button label="Verwijder" label_selected="Verwijder" name="Clear" tool_tip="Stop volgen"/>
<button label="Toon mijn locatie" label_selected="Toon mijn locatie" name="Show My Location" tool_tip="Centreer kaart op de locatie van uw avatar"/>
- <button label="Kopieer SLURL naar klembord" name="copy_slurl" tool_tip="Kopieert huidige locatie als SLURL, zodat deze op het web gebruikt kan worden."/>
+ <button label="Kopieer SLurl naar klembord" name="copy_slurl" tool_tip="Kopieert huidige locatie als SLurl, zodat deze op het web gebruikt kan worden."/>
<slider label="Zoom" name="zoom slider"/>
</floater>
diff --git a/indra/newview/skins/default/xui/nl/language_settings.xml b/indra/newview/skins/default/xui/nl/language_settings.xml
new file mode 100644
index 0000000000..71418d446a
--- /dev/null
+++ b/indra/newview/skins/default/xui/nl/language_settings.xml
@@ -0,0 +1,55 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<!-- This file contains strings that used to be hardcoded in the source.-->
+<strings>
+
+ <!-- Locale Information -->
+ <string name="MicrosoftLocale">english</string>
+ <string name="DarwinLocale">C</string>
+ <string name="LinuxLocale">C</string>
+
+ <!--
+ datetimeToCodes["wkday"] = "%a"; // Thu
+ datetimeToCodes["weekday"] = "%A"; // Thursday
+ datetimeToCodes["year4"] = "%Y"; // 2009
+ datetimeToCodes["year"] = "%Y"; // 2009
+ datetimeToCodes["year2"] = "%y"; // 09
+ datetimeToCodes["mth"] = "%b"; // Aug
+ datetimeToCodes["month"] = "%B"; // August
+ datetimeToCodes["mthnum"] = "%m"; // 08
+ datetimeToCodes["day"] = "%d"; // 31
+ datetimeToCodes["hour24"] = "%H"; // 14
+ datetimeToCodes["hour"] = "%H"; // 14
+ datetimeToCodes["hour12"] = "%I"; // 02
+ datetimeToCodes["min"] = "%M"; // 59
+ datetimeToCodes["ampm"] = "%p"; // AM
+ datetimeToCodes["second"] = "%S"; // 59
+ datetimeToCodes["timezone"] = "%Z"; // PST
+ -->
+
+ <string name="TimeHour">hour,datetime,slt</string>
+ <string name="TimeMin">min,datetime,slt</string>
+ <string name="TimeYear">year,datetime,slt</string>
+ <string name="TimeDay">day,datetime,slt</string>
+ <string name="TimeMonth">mthnum,datetime,slt</string>
+ <string name="TimeWeek">wkday,datetime,slt</string>
+ <string name="TimeAMPM">ampm,datetime,slt</string>
+ <string name="TimeHour12">hour12,datetime,slt</string>
+
+ <string name="LTimeMthNum">mthnum,datetime,local</string>
+ <string name="LTimeWeek">wkday,datetime,local</string>
+ <string name="LTimeMonth">mth,datetime,local</string>
+ <string name="LTimeDay">day,datetime,local</string>
+ <string name="LTimeSec">second,datetime,local</string>
+ <string name="LTimeHour">hour,datetime,local</string>
+ <string name="LTimeMin">min,datetime,local</string>
+ <string name="LTimeYear">year,datetime,local</string>
+
+ <string name="UTCTimeWeek">weekday,datetime,utc</string>
+ <string name="UTCTimeDay">day,datetime,utc</string>
+ <string name="UTCTimeMth">mth,datetime,utc</string>
+ <string name="UTCTimeYr">year,datetime,utc</string>
+ <string name="UTCTimeHr">hour,datetime,utc</string>
+ <string name="UTCTimeMin">min,datetime,utc</string>
+ <string name="UTCTimeSec">second,datetime,utc</string>
+ <string name="UTCTimeTimezone">timezone,datetime,utc</string>
+</strings>
diff --git a/indra/newview/skins/default/xui/nl/menu_inventory.xml b/indra/newview/skins/default/xui/nl/menu_inventory.xml
index f406bcf6bc..6a514422b9 100644
--- a/indra/newview/skins/default/xui/nl/menu_inventory.xml
+++ b/indra/newview/skins/default/xui/nl/menu_inventory.xml
@@ -12,7 +12,7 @@
<menu_item_call label="Nieuw script" name="New Script"/>
<menu_item_call label="Nieuwe notitie" name="New Note"/>
<menu_item_call label="Nieuw gebaar" name="New Gesture"/>
- <menu name="New Clothes">
+ <menu name="New Clothes" label="Nieuwe Kleding">
<menu_item_call label="Nieuw shirt" name="New Shirt"/>
<menu_item_call label="Nieuwe broek" name="New Pants"/>
<menu_item_call label="Nieuwe schoenen" name="New Shoes"/>
@@ -23,7 +23,7 @@
<menu_item_call label="Nieuw onderhemd" name="New Undershirt"/>
<menu_item_call label="Nieuwe onderbroek" name="New Underpants"/>
</menu>
- <menu name="New Body Parts">
+ <menu name="New Body Parts" label="Nieuwe Lichaamsdelen">
<menu_item_call label="Nieuwe postuur" name="New Shape"/>
<menu_item_call label="Nieuwe huid" name="New Skin"/>
<menu_item_call label="Nieuw haar" name="New Hair"/>
diff --git a/indra/newview/skins/default/xui/nl/menu_login.xml b/indra/newview/skins/default/xui/nl/menu_login.xml
index 188418e34c..987b82b128 100644
--- a/indra/newview/skins/default/xui/nl/menu_login.xml
+++ b/indra/newview/skins/default/xui/nl/menu_login.xml
@@ -7,7 +7,7 @@
<menu_item_call label="Voorkeuren..." name="Preferences..."/>
</menu>
<menu label="Help" name="Help">
- <menu_item_call label="Second Life Help" name="Second Life Help"/>
- <menu_item_call label="Over Second Life..." name="About Second Life..."/>
+ <menu_item_call label="[SECOND_LIFE] Help" name="Second Life Help"/>
+ <menu_item_call label="Over [APP_NAME]..." name="About Second Life..."/>
</menu>
</menu_bar>
diff --git a/indra/newview/skins/default/xui/nl/menu_viewer.xml b/indra/newview/skins/default/xui/nl/menu_viewer.xml
index 37116be5f5..6d5c833610 100644
--- a/indra/newview/skins/default/xui/nl/menu_viewer.xml
+++ b/indra/newview/skins/default/xui/nl/menu_viewer.xml
@@ -181,7 +181,7 @@
<menu_item_call label="Scripts in selectie instellen op niet uitvoeren" name="Set Scripts to Not Running in Selection"/>
</menu>
<menu label="Help" name="Help">
- <menu_item_call label="Second Life Help" name="Second Life Help"/>
+ <menu_item_call label="[SECOND_LIFE] Help" name="Second Life Help"/>
<menu_item_call label="Handleiding" name="Tutorial"/>
<menu_item_separator label="-----------" name="separator"/>
<menu_item_call label="Officiële Linden blog..." name="Official Linden Blog..."/>
@@ -202,6 +202,6 @@
<menu_item_separator label="-----------" name="separator9"/>
<menu_item_call label="Rapporteer bug..." name="Report Bug..."/>
</menu>
- <menu_item_call label="Over Second Life..." name="About Second Life..."/>
+ <menu_item_call label="Over [APP_NAME]..." name="About Second Life..."/>
</menu>
</menu_bar>
diff --git a/indra/newview/skins/default/xui/nl/notifications.xml b/indra/newview/skins/default/xui/nl/notifications.xml
index 35dc507c6e..179ad2ace1 100644
--- a/indra/newview/skins/default/xui/nl/notifications.xml
+++ b/indra/newview/skins/default/xui/nl/notifications.xml
@@ -6,6 +6,9 @@
<global name="alwayschoose">
Kies altijd deze optie
</global>
+ <global name="implicitclosebutton">
+ Sluiten
+ </global>
<template name="okbutton">
<form>
<button
@@ -71,7 +74,7 @@
</form>
</template>
<notification functor="GenericAcknowledge" label="Onbekende waarschuwingsboodschap" name="MissingAlert">
- Uw versie van Second Life weet niet hoe het de waarschuwingsboodschap die zojuist ontvangen is moet weergeven.
+ Uw versie van [APP_NAME] weet niet hoe het de waarschuwingsboodschap die zojuist ontvangen is moet weergeven.
Foutdetails: De waarschuwing genaamd &apos;[_NAME]&apos; is niet gevonden in notifications.xml.
<usetemplate name="okbutton" yestext="OK"/>
@@ -94,7 +97,7 @@ Foutdetails: De waarschuwing genaamd &apos;[_NAME]&apos; is niet gevonden in not
<usetemplate name="okcancelbuttons" notext="Annuleren" yestext="Ja"/>
</notification>
<notification name="BadInstallation">
- Er is een fout opgetreden tijdens het bijwerken van Second Life. Download alstublieft de meest recente versie van secondlife.com
+ Er is een fout opgetreden tijdens het bijwerken van [APP_NAME]. Download alstublieft de meest recente versie van secondlife.com
<usetemplate
name="okbutton"
yestext="OK"/>
@@ -232,7 +235,7 @@ Het aan vinken van deze optie zal:
<notification name="ClickPartnerHelpAvatar">
U kunt een andere Inwoner ten huwelijk vragen of een bestaand partner schap verbreken via de [SECOND_LIFE] website.
-Naar de Second Life website gaan voor meer informatie over partner schap?
+Naar de [SECOND_LIFE] website gaan voor meer informatie over partner schap?
<usetemplate name="okcancelbuttons" notext="Annuleren" yestext="Ga naar Pagina"/>
</notification>
<notification name="ClickUploadHelpPermissions">
@@ -272,7 +275,7 @@ Uw verkoopprijs is L$[SALE_PRICE] en zal geautoriseerd worden voor verkoop door
<usetemplate name="okcancelbuttons" notext="Annuleren" yestext="OK"/>
</notification>
<notification name="ConfirmLandSaleToAnyoneChange">
- ATTENTIE: Het aanklikken van &apos;verkoop aan iedereen&apos; zal uw land beschikbaar maken aan de gehele Second Life gemeenschap, zo ook diegenen niet in deze regio!
+ ATTENTIE: Het aanklikken van &apos;verkoop aan iedereen&apos; zal uw land beschikbaar maken aan de gehele [SECOND_LIFE] gemeenschap, zo ook diegenen niet in deze regio!
De geselecteerde [LAND_SIZE] m² land is te koop gezet.
Uw verkoopprijs is L$[SALE_PRICE] en zal geautoriseerd worden voor verkoop door [NAME].
@@ -418,17 +421,17 @@ Betaalde advertentiekosten zullen niet worden terug gestort.
<usetemplate name="okcancelbuttons" notext="Annuleren" yestext="OK"/>
</notification>
<notification name="CacheWillClear">
- De cache zal geleegd worden als u [SECOND_LIFE] opnieuw start.
+ De cache zal geleegd worden als u [APP_NAME] opnieuw start.
</notification>
<notification name="CacheWillBeMoved">
- De cache zal verplaatst worden als u [SECOND_LIFE] opnieuw start.
+ De cache zal verplaatst worden als u [APP_NAME] opnieuw start.
Opmerking: Dit zal de Cache legen.
</notification>
<notification name="ChangeConnectionPort">
- Poort instelling zullen effect hebben nadat u [SECOND_LIFE] opnieuw start.
+ Poort instelling zullen effect hebben nadat u [APP_NAME] opnieuw start.
</notification>
<notification name="ChangeSkin">
- De nieuwe skin zal verschijnen nadat u [SECOND_LIFE] opnieuw start.
+ De nieuwe skin zal verschijnen nadat u [APP_NAME] opnieuw start.
</notification>
<notification name="GoToAuctionPage">
Ga naar de [SECOND_LIFE] web pagina om de veiling details te zien of een bod uit te brengen.
@@ -489,7 +492,7 @@ Het object kan buiten bereik of mogelijk verwijderd zijn.
Kan niet naar bestand [[FILE]] schrijven
</notification>
<notification name="UnsupportedHardware">
- Waarschuwing: Uw systeem voldoet niet aan de Second Life minimum systeem eisen. Indien u Second Life gebruikt, ervaart u mogelijk slechte prestaties. Helaas kunnen we geen technische ondersteuning geven voor niet ondersteunde configuraties.
+ Waarschuwing: Uw systeem voldoet niet aan de [APP_NAME] minimum systeem eisen. Indien u [APP_NAME] gebruikt, ervaart u mogelijk slechte prestaties. Helaas kunnen we geen technische ondersteuning geven voor niet ondersteunde configuraties.
MINSPECS
Wilt u [_URL] bezoeken voor meer informatie?
@@ -501,14 +504,14 @@ Wilt u [_URL] bezoeken voor meer informatie?
<notification name="UnknownGPU">
Uw systeem heeft een grafische kaart die bij ons nog niet bekend is op dit moment.
-Dit is vaak het geval met nieuwe hardware waarbij wij nog niet de kans gehad hebben om het te testen. Second Life zal mogelijk naar behoren functioneren, doch het kan zijn dat u uw grafische instellingen naar geschiktere waarden zult moeten instellen.
+Dit is vaak het geval met nieuwe hardware waarbij wij nog niet de kans gehad hebben om het te testen. [APP_NAME] zal mogelijk naar behoren functioneren, doch het kan zijn dat u uw grafische instellingen naar geschiktere waarden zult moeten instellen.
(Bewerken menu &gt; Voorkeuren &gt; Grafisch).
<form name="form">
<ignore name="ignore" text="Indien een onbekende grafische kaart gedetecteerd"/>
</form>
</notification>
<notification name="DisplaySettingsNoShaders">
- [SECOND_LIFE] is gestopt bij het initialiseren van de grafische stuurprogramma&apos;s.
+ [APP_NAME] is gestopt bij het initialiseren van de grafische stuurprogramma&apos;s.
Grafische kwaliteit zal op zijn laagst worden ingesteld om veel voorkomende fouten met stuurprogramma&apos;s te vermijden.
Dit zal sommige grafische opties uitschakelen.
Wij adviseren u de stuurprogramma&apos;s van uw grafische kaart bij te werken.
@@ -789,7 +792,7 @@ Geen perceel geselecteerd.
Kan de regio niet vinden waar dit land zich bevind.
</notification>
<notification name="CannotCloseFloaterBuyLand">
- U kunt het Koop Land venster niet sluiten totdat Second Life de prijs van de transactie geschat heeft.
+ U kunt het Koop Land venster niet sluiten totdat [APP_NAME] de prijs van de transactie geschat heeft.
</notification>
<notification name="CannotDeedLandNothingSelected">
Kan land niet toekennen:
@@ -962,7 +965,7 @@ Indien dit probleem aanhoudt, klik dan alstublieft op &apos;Gereedschap &gt; Rap
<notification name="YouHaveBeenLoggedOut">
U bent uitgelogd uit [SECOND_LIFE]:
[MESSAGE]
-U kunt uw bestaande IM en chat bekijken door te klikken op &apos;Toon IM &amp; Chat&apos;. Anders, klik op Afsluiten om [SECOND_LIFE] direct te verlaten.
+U kunt uw bestaande IM en chat bekijken door te klikken op &apos;Toon IM &amp; Chat&apos;. Anders, klik op Afsluiten om [APP_NAME] direct te verlaten.
<usetemplate name="okcancelbuttons" notext="Afsluiten" yestext="Toon IM &amp; Chat"/>
</notification>
<notification name="OnlyOfficerCanBuyLand">
@@ -1134,14 +1137,14 @@ U kunt [SECOND_LIFE] normaal gebruiken en anderen zullen u correct zien.
</form>
</notification>
<notification name="FirstRun">
- [SECOND_LIFE] installatie compleet.
+ [APP_NAME] installatie compleet.
Als dit de eerste keer is dat u [SECOND_LIFE] gebruikt, zult u een account aan moeten maken voordat u in kan loggen.
Terugkeren naar www.secondlife.com om een nieuw account aan te maken?
<usetemplate name="okcancelbuttons" notext="Doorgaan" yestext="Nieuw Account..."/>
</notification>
<notification name="LoginPacketNeverReceived">
- Wij hebben problemen verbinding te maken. Er zou een probleem kunnen zijn met uw internet verbinding of met de Second Life servers.
+ Wij hebben problemen verbinding te maken. Er zou een probleem kunnen zijn met uw internet verbinding of met de [SECOND_LIFE] servers.
U kunt uw internet verbinding controleren en het over een paar minuten opnieuw proberen, op Help klikken om verbinding te maken met onze support website, of klik op Teleporteren om een poging te doen naar uw thuis locatie te teleporteren.
<form name="form">
@@ -1245,33 +1248,33 @@ Zet het object alstublieft te koop en probeer het opnieuw.
[DOWNLOAD_PATH].
</notification>
<notification name="DownloadWindowsMandatory">
- Een nieuwe versie van [SECOND_LIFE] is beschikbaar.
+ Een nieuwe versie van [APP_NAME] is beschikbaar.
[MESSAGE]
-U moet deze update downloaden om [SECOND_LIFE] te kunnen gebruiken.
+U moet deze update downloaden om [APP_NAME] te kunnen gebruiken.
<usetemplate name="okcancelbuttons" notext="Afsluiten" yestext="Download"/>
</notification>
<notification name="DownloadWindows">
- Een bijgewerkte versie van [SECOND_LIFE] is beschikbaar.
+ Een bijgewerkte versie van [APP_NAME] is beschikbaar.
[MESSAGE]
Deze update is niet vereist, maar wij raden aan dat u het installeert om de prestaties en stabiliteit te verbeteren.
<usetemplate name="okcancelbuttons" notext="Doorgaan" yestext="Download"/>
</notification>
<notification name="DownloadWindowsReleaseForDownload">
- Een bijgewerkte versie van [SECOND_LIFE] is beschikbaar.
+ Een bijgewerkte versie van [APP_NAME] is beschikbaar.
[MESSAGE]
Deze update is niet vereist, maar wij raden aan dat u het installeert om de prestaties en stabiliteit te verbeteren.
<usetemplate name="okcancelbuttons" notext="Doorgaan" yestext="Download"/>
</notification>
<notification name="DownloadMacMandatory">
- Een nieuwe versie van [SECOND_LIFE] is beschikbaar.
+ Een nieuwe versie van [APP_NAME] is beschikbaar.
[MESSAGE]
-U moet deze update downloaden om [SECOND_LIFE] te kunnen gebruiken.
+U moet deze update downloaden om [APP_NAME] te kunnen gebruiken.
Downloaden naar uw Applicatie Data map?
<usetemplate name="okcancelbuttons" notext="Afsluiten" yestext="Download"/>
</notification>
<notification name="DownloadMac">
- Een bijgewerkte versie van [SECOND_LIFE] is beschikbaar.
+ Een bijgewerkte versie van [APP_NAME] is beschikbaar.
[MESSAGE]
Deze update is niet vereist, maar wij raden aan dat u het installeert om de prestaties en stabiliteit te verbeteren.
@@ -1279,7 +1282,7 @@ Downloaden naar uw Applicatie Data map?
<usetemplate name="okcancelbuttons" notext="Doorgaan" yestext="Download"/>
</notification>
<notification name="DownloadMacReleaseForDownload">
- Een bijgewerkte versie van [SECOND_LIFE] is beschikbaar.
+ Een bijgewerkte versie van [APP_NAME] is beschikbaar.
[MESSAGE]
Deze update is niet vereist, maar wij raden aan dat u het installeert om de prestaties en stabiliteit te verbeteren.
@@ -1890,7 +1893,7 @@ Indien u het leeg laat, zullen misbruik rapporten alleen verzonden worden naar L
Standaard: Uitgeschakeld
</notification>
<notification label="Voice Versie Ongelijkheid" name="VoiceVersionMismatch">
- Deze versie van Second Life is niet compatibel met de Voice spraak optie in deze regio. Om Voice Chat goed te laten functioneren, moet u Second Life bijwerken.
+ Deze versie van [APP_NAME] is niet compatibel met de Voice spraak optie in deze regio. Om Voice Chat goed te laten functioneren, moet u [APP_NAME] bijwerken.
</notification>
<notification label="Estate Convenant" name="HelpEstateCovenant">
Het instellen van een Estate Convenant maakt het u mogelijk om percelen in het Estate te verkopen. Indien de Convenant niet is ingesteld kunt u het niet verkopen. Een notitiekaart voor uw Convenant kan leeg zijn indien u geen regels wilt instellen, advies aan kopers wilt geven of iets anders in relatie tot het land wilt mededelen voor als men het koopt.
@@ -2010,16 +2013,16 @@ inventaris item(s) verplaatsen?
Er zitten geen items in dit object die u kunt kopiëren.
</notification>
<notification name="WebLaunchAccountHistory">
- Naar de Second Life web site gaan om uw account geschiedenis te bekijken?
+ Naar de [SECOND_LIFE] web site gaan om uw account geschiedenis te bekijken?
<usetemplate ignoretext="Bij laden van de account geschiedenis webpagina" name="okcancelignore" notext="Annuleren" yestext="Ga naar pagina"/>
</notification>
<notification name="ClickOpenF1Help">
- De Second Life Support Web site bezoeken?
- <usetemplate ignoretext="Bij bezoeken van de Second Life Support Website." name="okcancelignore" notext="Annuleren" yestext="Ga"/>
+ De [SECOND_LIFE] Support Web site bezoeken?
+ <usetemplate ignoretext="Bij bezoeken van de [SECOND_LIFE] Support Website." name="okcancelignore" notext="Annuleren" yestext="Ga"/>
</notification>
<notification name="ConfirmQuit">
Weet u zeker dat u wilt afsluiten?
- <usetemplate ignoretext="Bij afsluiten Second Life." name="okcancelignore" notext="Doorgaan" yestext="Afsluiten"/>
+ <usetemplate ignoretext="Bij afsluiten [APP_NAME]." name="okcancelignore" notext="Doorgaan" yestext="Afsluiten"/>
</notification>
<notification name="HelpReportAbuseEmailLL">
Gebruik dit gereedschap om overtredingen van de Voorwaarden voor Service (Terms of Service) en Gemeenschaps Standaarden (Community Standards)te rapporteren. Zie:
@@ -2039,7 +2042,7 @@ Als een service aan Inwoners en bezoekers heeft de eigenaar van deze regio er vo
De regio eigenaar zal de rapporten afhandelen op basis van de regels geldend voor deze regio zoals weergegeven in het Estate Convenant (Bekijk Convenants door naar Wereld te gaan in het menu en te kiezen voor Over Land).
De afhandeling van dit rapport is alleen van toepassing op deze regio.
-Toegang van Inwoners tot andere gebieden van Second Life zullen niet beïnvloed worden door de uitkomst van dit rapport. Alleen Linden Lab kan de toegang tot geheel Second Life beperken.
+Toegang van Inwoners tot andere gebieden van [SECOND_LIFE] zullen niet beïnvloed worden door de uitkomst van dit rapport. Alleen Linden Lab kan de toegang tot geheel [SECOND_LIFE] beperken.
</notification>
<notification name="HelpReportBug">
Gebruik dit gereedschap *alleen* voor het rapporteren van technische opties die niet functioneren als verwacht. Geef alstublieft zoveel mogelijk technische details als mogelijk. U kunt de automatische-antwoord email gebruiken om op te reageren om aanvullende gegevens toe te voegen aan uw rapport.
@@ -2100,9 +2103,9 @@ Het opgeven van een accurate omschrijving helpt ons met het archiveren en verwer
Het lijkt er op dat u intellectueel eigendoms misbruik rapporteert. Wees er alstublieft van overtuigd dat u dit correct rapporteert:
-(1) Het Misbruik Proces. U kunt een misbruik rapport indienen als u er van overtuigd bent dat een Inwoner het Second Life permissie systeem uitbuit, bijvoorbeeld door gebruik van CopyBot of soortgelijke gereedschappen, daarmee de intellectuele eigendoms rechten overtredend. Het Abuse Team onderzoekt en zal passende maatregelen uitvaardigen tegen gedrag dat de Second Life Gemeenschaps Standaarden overtreedt. Echter, het Abuse Team zal geen actie ondernemen en niet reageren op verzoeken om inhoud te verwijderen uit de Second Life wereld.
+(1) Het Misbruik Proces. U kunt een misbruik rapport indienen als u er van overtuigd bent dat een Inwoner het [SECOND_LIFE] permissie systeem uitbuit, bijvoorbeeld door gebruik van CopyBot of soortgelijke gereedschappen, daarmee de intellectuele eigendoms rechten overtredend. Het Abuse Team onderzoekt en zal passende maatregelen uitvaardigen tegen gedrag dat de [SECOND_LIFE] Gemeenschaps Standaarden overtreedt. Echter, het Abuse Team zal geen actie ondernemen en niet reageren op verzoeken om inhoud te verwijderen uit de [SECOND_LIFE] wereld.
-(2) Het DMCA of Inhoud Verwijder Proces. Voor een verzoek tot verwijdering van inhoud in Second Life, MOET u een geldige berichtgeving van misbruik indienen zoals voorzien in onze DMCA beleid op http://secondlife.com/corporate/dmca.php.
+(2) Het DMCA of Inhoud Verwijder Proces. Voor een verzoek tot verwijdering van inhoud in [SECOND_LIFE], MOET u een geldige berichtgeving van misbruik indienen zoals voorzien in onze DMCA beleid op http://secondlife.com/corporate/dmca.php.
Indien u nog steeds door wilt gaan met het misbruik proces, sluit dan alstublieft dit venster en maak het indienen van uw rapport af. U zult mogelijk een specifieke catagorie moeten kiezen &apos;CopyBot of Permissie Uitbuiting&apos;.
@@ -2153,12 +2156,12 @@ Wilt u de Niet Storen Modus verlaten voordat u deze transactie completeert?
<usetemplate ignoretext="Bij legen van uw inventaris Verloren en Gevonden map" name="okcancelignore" notext="Nee" yestext="Ja"/>
</notification>
<notification name="CopySLURL">
- De volgende SLURL is gekopieerd naar uw klem bord:
+ De volgende SLurl is gekopieerd naar uw klem bord:
[SLURL]
Plaats het in een web pagina om anderen eenvoudig toegang te verschaffen naar de locatie of test het zelf door het te plakken in de adres balk van uw web browser.
<form name="form">
- <ignore name="ignore" text="Bij kopiëren van een SLURL naar het klem bord"/>
+ <ignore name="ignore" text="Bij kopiëren van een SLurl naar het klem bord"/>
</form>
</notification>
<notification name="GraphicsPreferencesHelp">
@@ -2224,7 +2227,7 @@ Klik op &quot;Geavanceerde Lucht&quot; om de editor op te roepen voor geavanceer
Klik op &quot;Geavanceerd Water&quot; om de editor op te roepen voor geavanceerde instellingen voor water.
</notification>
<notification name="HelpDayCycle">
- De Dag Cyclus Editor geeft u controle over de lucht gedurende de Second Life&apos;s dag/nacht cyclus. Dit is de cyclus die gebruikt wordt in de Basis Omgeving Editor&apos;s Tijd van de Dag schuif knop.
+ De Dag Cyclus Editor geeft u controle over de lucht gedurende de [SECOND_LIFE]&apos;s dag/nacht cyclus. Dit is de cyclus die gebruikt wordt in de Basis Omgeving Editor&apos;s Tijd van de Dag schuif knop.
De Dag Cyclus Editor werkt beter met het instellen van gemarkeerde frames. Dit zijn nodes (weergegeven als grijze blips in de tijd weergave) die Hemel voorinstelling met zich geassocieerd hebben. Als de Tijd van de Dag voortschrijdt, &quot;animeert&quot; de WindLight Hemel als het interpoleert tussen de gemarkeerde frames.
@@ -2304,7 +2307,7 @@ Gelijkwaardig aan azimut.
Bepaald de snelheid van de wolken terwijl zij in Y richting bewegen.
</notification>
<notification name="HelpClassicClouds">
- Vink dit aan voor weergave van Second Life&apos;s oudere klassieke wolken als toevoeging op WindLight&apos;s wolken.
+ Vink dit aan voor weergave van [SECOND_LIFE]&apos;s oudere klassieke wolken als toevoeging op WindLight&apos;s wolken.
</notification>
<notification name="HelpWaterFogColor">
Kiest de kleur van de onder water nevel.
@@ -2403,7 +2406,7 @@ Om dit recht in te trekken, moet de object eigenaar het object verwijderen of de
</notification>
<notification name="NotAgeVerified">
U moet leeftijd geverifieerd zijn om toegang te verkrijgen tot dit perceel.
-Wilt u de Second Life website bezoeken om uw leeftijd te verifiëren?
+Wilt u de [SECOND_LIFE] website bezoeken om uw leeftijd te verifiëren?
[_URL]
<url name="url" option="0">
@@ -2413,7 +2416,7 @@ Wilt u de Second Life website bezoeken om uw leeftijd te verifiëren?
</notification>
<notification name="Cannot enter parcel: no payment info on file">
Dit perceel verlangd dat u betaal informatie geregistreerd hebt staan alvorens toegang te verkrijgen.
-Wilt u de Second Life website bezoeken om dit in te stellen?
+Wilt u de [SECOND_LIFE] website bezoeken om dit in te stellen?
[_URL]
<url name="url" option="0">
@@ -2721,13 +2724,13 @@ Probeer het alstublieft opnieuw over enkele ogenblikken.
Kan wachtende verbinding niet maken.
</notification>
<notification name="InternalUsherError">
- Er is een interne fout opgetreden terwijl geprobeerd werd u naar uw teleportbestemming te begeleiden. Second Life heeft op dit moment mogelijk problemen met de dienstverlening.
+ Er is een interne fout opgetreden terwijl geprobeerd werd u naar uw teleportbestemming te begeleiden. [SECOND_LIFE] heeft op dit moment mogelijk problemen met de dienstverlening.
</notification>
<notification name="NoGoodTPDestination">
Kan geen goede teleportbestemming vinden in deze regio.
</notification>
<notification name="InternalErrorRegionResolver">
- Er is een interne fout opgetreden terwijl de globale coördinaten voor uw teleportverzoek werden bepaald. Second Life heeft op dit moment mogelijk problemen met de dienstverlening.
+ Er is een interne fout opgetreden terwijl de globale coördinaten voor uw teleportverzoek werden bepaald. [SECOND_LIFE] heeft op dit moment mogelijk problemen met de dienstverlening.
</notification>
<notification name="NoValidLanding">
Er kon geen geldig landingspunt worden gevonden.
@@ -2848,7 +2851,7 @@ Van object: [OBJECTNAME], eigenaar: [NAME]?
Kon [TYPE] genaamd [DESC] niet in de database vinden.
</notification>
<notification name="InvalidWearable">
- Het item dat u probeert te dragen gebruikt een kenmerk dat uw viewer niet kan lezen. Upgrade u alstublieft uw versie van Second Life om dit item te dragen.
+ Het item dat u probeert te dragen gebruikt een kenmerk dat uw viewer niet kan lezen. Upgrade u alstublieft uw versie van [APP_NAME] om dit item te dragen.
</notification>
<notification name="ScriptQuestion">
[OBJECTNAME]&apos;, een object van &apos;[NAME]&apos;, wil graag:
@@ -2952,8 +2955,8 @@ Flexibele objecten mogen niet fysiek zijn en moeten fantoom zijn tot de &apos;fl
</notification>
<notification name="FirstDebugMenus">
U heeft het menu Geavanceerd geactiveerd.
-Dit menu bevat opties die handig zijn voor ontwikkelaars tijdens het debuggen van Second Life.
-Om dit menu in en uit te schakelen drukt u binnen Windows Ctrl-Alt-D. Met een Mac drukt u Cmd-Opt-Shift-D.
+Dit menu bevat opties die handig zijn voor ontwikkelaars tijdens het debuggen van [SECOND_LIFE].
+Om dit menu in en uit te schakelen drukt u binnen Windows Ctrl-Alt-D. Met een Mac drukt u &#8984;-Opt-D.
</notification>
<notification name="FirstSculptedPrim">
U bent een sculpted prim aan het bewerken.
@@ -3060,7 +3063,7 @@ Klik Accepteren om deel te nemen aan de chat of Afwijzen om de uitnodiging af te
- Uw Processor snelheid (CPU) voldoet niet aan de minimale eisen.
</global>
<global name="UnsupportedGLRequirements">
- U heeft mogelijk niet de vereiste hardware voor Second Life. Second Life verlangd een OpenGL grafische kaart die multi-texture ondersteund. Indien dat het geval is, overtuig u er dan van dat u de laatste stuurprogramma&apos;s voor uw grafische kaart, service packs en patches voor uw Operating systeem heeft.
+ U heeft mogelijk niet de vereiste hardware voor [APP_NAME]. [APP_NAME] verlangd een OpenGL grafische kaart die multi-texture ondersteund. Indien dat het geval is, overtuig u er dan van dat u de laatste stuurprogramma&apos;s voor uw grafische kaart, service packs en patches voor uw Operating systeem heeft.
Indien u problemen blijft houden, bezoek dan: http://www.secondlife.com/support
</global>
diff --git a/indra/newview/skins/default/xui/nl/panel_login.xml b/indra/newview/skins/default/xui/nl/panel_login.xml
index b9e10804a1..5014d7761c 100644
--- a/indra/newview/skins/default/xui/nl/panel_login.xml
+++ b/indra/newview/skins/default/xui/nl/panel_login.xml
@@ -19,15 +19,9 @@
Startlocatie:
</text>
<combo_box name="start_location_combo">
- <combo_item name="MyHome">
- Mijn Thuis
- </combo_item>
- <combo_item name="MyLastLocation">
- Mijn Laatste Locatie
- </combo_item>
- <combo_item name="Typeregionname">
- &lt; Type regio naam &gt;
- </combo_item>
+ <combo_box.item name="MyHome" label="Mijn Thuis"/>
+ <combo_box.item name="MyLastLocation" label="Mijn Laatste Locatie"/>
+ <combo_box.item name="Typeregionname" label="lt; Type regio naam &gt;"/>
</combo_box>
<check_box label="Onthoud wachtwoord" name="remember_check"/>
<button label="Inloggen" label_selected="Inloggen" name="connect_btn"/>
diff --git a/indra/newview/skins/default/xui/nl/panel_status_bar.xml b/indra/newview/skins/default/xui/nl/panel_status_bar.xml
index d499ef5af0..1d68d25f66 100644
--- a/indra/newview/skins/default/xui/nl/panel_status_bar.xml
+++ b/indra/newview/skins/default/xui/nl/panel_status_bar.xml
@@ -27,8 +27,8 @@
<button label="" label_selected="" name="restrictpush" tool_tip="Niet duwen"/>
<button label="" label_selected="" name="status_no_voice" tool_tip="Voice is niet beschikbaar hier"/>
<button label="" label_selected="" name="buyland" tool_tip="Koop dit perceel"/>
- <line_editor label="Zoeken" name="search_editor" tool_tip="Doorzoek Second Life"/>
- <button label="" label_selected="" name="search_btn" tool_tip="Doorzoek Second Life"/>
+ <line_editor label="Zoeken" name="search_editor" tool_tip="Doorzoek [SECOND_LIFE]"/>
+ <button label="" label_selected="" name="search_btn" tool_tip="Doorzoek [SECOND_LIFE]"/>
<string name="packet_loss_tooltip">
Pakketten verlies
</string>
diff --git a/indra/newview/skins/default/xui/nl/strings.xml b/indra/newview/skins/default/xui/nl/strings.xml
index 4b64586887..49e566080a 100644
--- a/indra/newview/skins/default/xui/nl/strings.xml
+++ b/indra/newview/skins/default/xui/nl/strings.xml
@@ -55,6 +55,9 @@
<string name="LoginDownloadingClothing">
Kleding downloaden...
</string>
+ <string name="Quit">
+ Afsluiten
+ </string>
<string name="AgentLostConnection">
Deze regio kan problemen ondervinden. Controleer alstublieft uw verbinding met het internet.
</string>
diff --git a/indra/newview/skins/default/xui/pl/floater_about.xml b/indra/newview/skins/default/xui/pl/floater_about.xml
index e58b3e4ed4..bbf8165883 100755
--- a/indra/newview/skins/default/xui/pl/floater_about.xml
+++ b/indra/newview/skins/default/xui/pl/floater_about.xml
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
-<floater name="floater_about" title="O Second Life">
+<floater name="floater_about" title="O [APP_NAME]">
<text_editor name="credits_editor">
Second Life zostało stworzone dla Was przez: Philip, Tessa, Andrew, Cory, James, Ben, Char, Charlie, Colin, Dan, Daniel, Doug, Eric, Hamlet, Haney, Eve, Hunter, Ian, Jeff, Jennifer, Jim, John, Lee, Mark, Peter, Phoenix, Richard, Robin, Xenon, Steve, Tanya, Eddie, Avi, Frank, Bruce, Aaron, Alice, Bob, Debra, Eileen, Helen, Janet, Louie, Leviathania, Stefan, Ray, Kevin, Tom, Mikeb, MikeT, Burgess, Elena, Tracy, Bill, Todd, Ryan, Zach, Sarah, Nova, Tim, Stephanie, Michael, Evan, Nicolas, Catherine, Rachelle, Dave, Holly, Bub, Kelly, Magellan, Ramzi, Don, Sabin, Jill, Rheya, Jeska, Torley, Kona, Callum, Charity, Ventrella, Jack, Vektor, Iris, Chris, Nicole, Mick, Reuben, Blue, Babbage, Yedwab, Deana, Lauren, Brent, Pathfinder, Chadrick, Altruima, Jesse, Teeny, Monroe, Icculus, David, Tess, Lizzie, Patsy, Isaac, Lawrence, Cyn, Bo, Gia, Annette, Marius, Tbone, Jonathan, Karen, Ginsu, Satoko, Yuko, Makiko, Thomas, Harry, Seth, Alexei, Brian, Guy, Runitai, Ethan, Data, Cornelius, Kenny, Swiss, Zero, Natria, Wendy, Stephen, Teeple, Thumper, Lucy, Dee, Mia, Liana, Warren, Branka, Aura, beez, Milo, Hermia, Red, Thrax, Joe, Sally, Magenta, Mogura, Paul, Jose, Rejean, Henrik, Lexie, Amber, Logan, Xan, Nora, Morpheus, Donovan, Leyla, MichaelFrancis, Beast, Cube, Bucky, Joshua, Stryfe, Harmony, Teresa, Claudia, Walker, Glenn, Fritz, Fordak, June, Cleopetra, Jean, Ivy, Betsy, Roosevelt, Spike, Ken, Which, Tofu, Chiyo, Rob, Zee, dustin, George, Del, Matthew, Cat, Jacqui, Lightfoot, Adrian, Viola, Alfred, Noel, Irfan, Sunil, Yool, Rika, Jane, Xtreme, Frontier, a2, Neo, Siobhan, Yoz, Justin, Elle, Qarl, Benjamin, Isabel, Gulliver, Everett, Christopher, Izzy, Stephany, Garry, Sejong, Sean, Tobin, Iridium, Meta, Anthony, Jeremy, JP, Jake, Maurice, Madhavi, Leopard, Kyle, Joon, Kari, Bert, Belinda, Jon, Kristi, Bridie, Pramod, KJ, Socrates, Maria, Ivan, Aric, Yamasaki, Adreanne, Jay, MitchK, Ceren, Coco, Durl, Jenny, Periapse, Kartic, Storrs, Lotte, Sandy, Rohn, Colossus, Zen, BigPapi, Brad, Pastrami, Kurz, Mani, Neuro, Jaime, MJ, Rowan, Sgt, Elvis, Gecko, Samuel, Sardonyx, Leo, Bryan, Niko, Soft, Poppy, Rachel, Aki, Angelo, Banzai, Alexa, Sue, CeeLo, Bender, CG, Gillian, Pelle, Nick, Echo, Zara, Christine, Shamiran, Emma, Blake, Keiko, Plexus, Joppa, Sidewinder, Erica, Ashlei, Twilight, Kristen, Brett, Q, Enus, Simon, Bevis, Kraft, Kip, Chandler, Ron, LauraP, Ram, KyleJM, Scouse, Prospero, Melissa, Marty, Nat, Hamilton, Kend, Lordan, Jimmy, Kosmo, Seraph, Green, Ekim, Wiggo, JT, Rome, Doris, Miz, Benoc, Whump, Trinity, Patch, Kate, TJ, Bao, Joohwan, Christy, Sofia, Matias, Cogsworth, Johan, Oreh, Cheah, Angela, Brandy, Mango, Lan, Aleks, Gloria, Heidy, Mitchell, Space, Colton, Bambers, Einstein, Maggie, Malbers, Rose, Winnie, Stella, Milton, Rothman, Niall, Marin, Allison, Katie, Dawn, Katt, Dusty, Kalpana, Judy, Andrea, Ambroff, Infinity, Gail, Rico, Raymond, Yi, William, Christa, M, Teagan, Scout, Molly, Dante, Corr, Dynamike, Usi, Kaylee, Vidtuts, Lil, Danica, Sascha, Kelv, Jacob, Nya, Rodney, Brandon, Elsie, Blondin, Grant, Katrin, Nyx, Gabriel, Locklainn, Claire, Devin, Minerva, Monty, Austin, Bradford, Si, Keira, H, Caitlin, Dita, Makai, Jenn, Ann, Meredith, Clare, Joy, Praveen, Cody, Edmund, Ruthe, Sirena, Gayathri, Spider, FJ, Davidoff, Tian, Jennie, Louise, Oskar, Landon, Noelle, Jarv, Ingrid, Al, Sommer, Doc, Aria, Huin, Gray, Lili, Vir, DJ, Yang, T, Simone, Maestro, Scott, Charlene, Quixote, Amanda, Susan, Zed, Anne, Enkidu, Esbee, Joroan, Katelin, Roxie, Tay, Scarlet, Kevin, Johnny, Wolfgang, Andren, Bob, Howard, Merov, Rand, Ray, Michon, Newell, Galen, Dessie, Les, Michon, Jenelle, Geo, Siz, Shapiro, Pete, Calyle, Selene, Allen, Phoebe, Goldin, Kimmora, Dakota, Slaton, Lindquist, Zoey, Hari, Othello, Rohit, Sheldon, Petra, Viale, Gordon, Kaye, Pink, Ferny, Emerson, Davy, Bri, Chan, Juan, Robert, Terrence, Nathan, Carl i wielu innych.
diff --git a/indra/newview/skins/default/xui/pl/floater_buy_land.xml b/indra/newview/skins/default/xui/pl/floater_buy_land.xml
index 1103606569..ff371b38c0 100755
--- a/indra/newview/skins/default/xui/pl/floater_buy_land.xml
+++ b/indra/newview/skins/default/xui/pl/floater_buy_land.xml
@@ -74,15 +74,9 @@ sprzedaż z obiektami
Tylko członkowie z kontem Premium mogą mieć Posiadłosci.
</text>
<combo_box name="account_level">
- <combo_item name="US$9.95/month,billedmonthly">
- 9.95US$/miesiąc, płatne miesięcznie
- </combo_item>
- <combo_item name="US$7.50/month,billedquarterly">
- 7.50US$/miesiąc, płatne kwartalnie
- </combo_item>
- <combo_item name="US$6.00/month,billedannually">
- 6.00US$/miesiąc, płatne rocznie
- </combo_item>
+ <combo_box.item name="US$9.95/month,billedmonthly" label="9.95US$/miesiąc, płatne miesięcznie" />
+ <combo_box.item name="US$7.50/month,billedquarterly" label="7.50US$/miesiąc, płatne kwartalnie" />
+ <combo_box.item name="US$6.00/month,billedannually" label="6.00US$/miesiąc, płatne rocznie" />
</combo_box>
<text name="land_use_action">
Zwiększ opłatę za używanie Posiadłości do 40US$/miesiąc.
diff --git a/indra/newview/skins/default/xui/pl/floater_god_tools.xml b/indra/newview/skins/default/xui/pl/floater_god_tools.xml
index f46cbaa862..762b9f0f55 100755
--- a/indra/newview/skins/default/xui/pl/floater_god_tools.xml
+++ b/indra/newview/skins/default/xui/pl/floater_god_tools.xml
@@ -42,7 +42,7 @@
<line_editor left_delta="45" name="redirecty" width="35" />
<spinner name="billable factor"/>
<text name="billable factor text">
- Czynnik Płatnośći:
+ Czynnik Płatności:
</text>
<spinner name="land cost"/>
<text name="land cost text">
@@ -68,8 +68,8 @@
<text name="target_avatar_name">
(brak)
</text>
- <button label="Usuń cel &apos;s skryptowane obiekty na innych posiadłościach" label_selected="Usuń cel &apos;s skryptowane obiekty na innych posiadłościach" name="Delete Target&apos;s Scripted Objects On Others Land" />
- <button label="Usuń cel &apos;s skryptowane obiekty na jakichkolwiek posiadłościach" label_selected="Usuń cel &apos;s skryptowane obiekty na jakichkolwiek posiadłościach" name="Delete Target&apos;s Scripted Objects On *Any* Land" />
+ <button label="Usuń cel z oskryptowanych obiektów na innych posiadłościach" label_selected="Usuń cel &apos;s skryptowane obiekty na innych posiadłościach" name="Delete Target&apos;s Scripted Objects On Others Land" />
+ <button label="Usuń cel z oskryptowanych obiektów na jakichkolwiek posiadłościach" label_selected="Usuń cel &apos;s skryptowane obiekty na jakichkolwiek posiadłościach" name="Delete Target&apos;s Scripted Objects On *Any* Land" />
<button label="Usuń wszystkie cele i obiekty" label_selected="Usuń wszystkie cele i obiekty" name="Delete *ALL* Of Target&apos;s Objects" />
<button label="Główne Kolizje" label_selected="Główne Kolizje" name="Get Top Colliders" />
<button label="Główne Skrypty" label_selected="Główne Skrypty" name="Get Top Scripts" />
@@ -80,29 +80,17 @@
Cel:
</text>
<combo_box name="destination">
- <combo_item name="Selection">
- Selekcja
- </combo_item>
- <combo_item name="AgentRegion">
- Agent Regionu
- </combo_item>
+ <combo_box.item name="Selection" label="Selekcja" />
+ <combo_box.item name="AgentRegion" label="Agent Regionu" />
</combo_box>
<text name="Request:">
Żądanie:
</text>
<combo_box name="request">
- <combo_item name="colliders&lt;steps&gt;">
- kolidery &lt;kroki&gt;
- </combo_item>
- <combo_item name="scripts&lt;count&gt;,&lt;optionalpattern&gt;">
- skrypty &lt;policz&gt;,&lt;opcjonalnie powtórzenie&gt;
- </combo_item>
- <combo_item name="objects&lt;pattern&gt;">
- obiekty &lt;powtórzenia&gt;
- </combo_item>
- <combo_item name="rez&lt;asset_id&gt;">
- rez &lt;asset_id&gt;
- </combo_item>
+ <combo_box.item name="colliders&lt;steps&gt;" label="kolidery &lt;kroki&gt;" />
+ <combo_box.item name="scripts&lt;count&gt;,&lt;optionalpattern&gt;" label="skrypty &lt;policz&gt;,&lt;opcjonalnie powtórzenie&gt;" />
+ <combo_box.item name="objects&lt;pattern&gt;" label="obiekty &lt;powtórzenia&gt;" />
+ <combo_box.item name="rez&lt;asset_id&gt;" label="rez &lt;asset_id&gt;" />
</combo_box>
<text name="Parameter:">
Parameter:
diff --git a/indra/newview/skins/default/xui/pl/floater_hardware_settings.xml b/indra/newview/skins/default/xui/pl/floater_hardware_settings.xml
index 010537d555..051e9b510d 100755
--- a/indra/newview/skins/default/xui/pl/floater_hardware_settings.xml
+++ b/indra/newview/skins/default/xui/pl/floater_hardware_settings.xml
@@ -8,21 +8,11 @@
Antialiasing:
</text>
<combo_box label="Antialiasing" name="fsaa" width="84">
- <combo_item name="FSAADisabled">
- Wyłączone
- </combo_item>
- <combo_item name="2x">
- 2x
- </combo_item>
- <combo_item name="4x">
- 4x
- </combo_item>
- <combo_item name="8x">
- 8x
- </combo_item>
- <combo_item name="16x">
- 16x
- </combo_item>
+ <combo_box.item name="FSAADisabled" label="Wyłączone" />
+ <combo_box.item name="2x" label="2x" />
+ <combo_box.item name="4x" label="4x" />
+ <combo_box.item name="8x" label="8x" />
+ <combo_box.item name="16x" label="16x" />
</combo_box>
<spinner label="Gamma:" name="gamma" />
<text type="string" length="1" name="(brightness, lower is brighter)">
diff --git a/indra/newview/skins/default/xui/pl/floater_image_preview.xml b/indra/newview/skins/default/xui/pl/floater_image_preview.xml
index 9772dc7808..27f898a66b 100755
--- a/indra/newview/skins/default/xui/pl/floater_image_preview.xml
+++ b/indra/newview/skins/default/xui/pl/floater_image_preview.xml
@@ -10,36 +10,16 @@
Wyświetl obraz jako:
</text>
<combo_box label="Rodzaj Ubrania" name="clothing_type_combo">
- <combo_item name="Image">
- Obraz
- </combo_item>
- <combo_item name="Hair">
- WÅ‚osy
- </combo_item>
- <combo_item name="FemaleHead">
- Damska GÅ‚owa
- </combo_item>
- <combo_item name="FemaleUpperBody">
- Damska Górna Część Ciała
- </combo_item>
- <combo_item name="FemaleLowerBody">
- Damska Górna Część Ciała
- </combo_item>
- <combo_item name="MaleHead">
- Męska Głowa
- </combo_item>
- <combo_item name="MaleUpperBody">
- Męska Górna Część Ciała
- </combo_item>
- <combo_item name="MaleLowerBody">
- Męska Dolna Część Ciała
- </combo_item>
- <combo_item name="Skirt">
- Spódnica
- </combo_item>
- <combo_item name="SculptedPrim">
- Sculpt
- </combo_item>
+ <combo_box.item name="Image" label="Obraz" />
+ <combo_box.item name="Hair" label="WÅ‚osy" />
+ <combo_box.item name="FemaleHead" label="Damska GÅ‚owa" />
+ <combo_box.item name="FemaleUpperBody" label="Damska Górna Część Ciała" />
+ <combo_box.item name="FemaleLowerBody" label="Damska Górna Część Ciała" />
+ <combo_box.item name="MaleHead" label="Męska Głowa" />
+ <combo_box.item name="MaleUpperBody" label="Męska Górna Część Ciała" />
+ <combo_box.item name="MaleLowerBody" label="Męska Dolna Część Ciała" />
+ <combo_box.item name="Skirt" label="Spódnica" />
+ <combo_box.item name="SculptedPrim" label="Sculpt" />
</combo_box>
<text name="bad_image_text">
Nie można wczytać obrazu.
diff --git a/indra/newview/skins/default/xui/pl/floater_inventory_item_properties.xml b/indra/newview/skins/default/xui/pl/floater_inventory_item_properties.xml
index f754610ee3..c32d1eeabf 100755
--- a/indra/newview/skins/default/xui/pl/floater_inventory_item_properties.xml
+++ b/indra/newview/skins/default/xui/pl/floater_inventory_item_properties.xml
@@ -60,12 +60,8 @@
</text>
<check_box label="Sprzedaż" name="CheckPurchase" />
<radio_group name="RadioSaleType">
- <radio_item name="radio">
- Oryginał
- </radio_item>
- <radio_item name="radio2">
- Kopia
- </radio_item>
+ <radio_item name="radio" label="Oryginał" />
+ <radio_item name="radio2" label="Kopia" />
</radio_group>
<text name="TextPrice">
Cena: L$
diff --git a/indra/newview/skins/default/xui/pl/floater_postcard.xml b/indra/newview/skins/default/xui/pl/floater_postcard.xml
index 080edd5623..b6b0dcb858 100755
--- a/indra/newview/skins/default/xui/pl/floater_postcard.xml
+++ b/indra/newview/skins/default/xui/pl/floater_postcard.xml
@@ -20,12 +20,12 @@
Wpisz treść swojej wiadomości tutaj
</text_editor>
<text name="fine_print">
- Jeżeli odbiorca tej pocztówki dołączy do Second Life, otrzymasz bonusa.
+ Jeżeli odbiorca tej pocztówki dołączy do [SECOND_LIFE], otrzymasz bonusa.
</text>
<button label="Anuluj" name="cancel_btn"/>
<button label="Wyślij" name="send_btn"/>
<string name="default_subject">
- Pocztówki z Second Life.
+ Pocztówki z [SECOND_LIFE]
</string>
<string name="default_message">
Sprawdź i przekonaj się sam!
diff --git a/indra/newview/skins/default/xui/pl/floater_preview_gesture.xml b/indra/newview/skins/default/xui/pl/floater_preview_gesture.xml
index 02c6e1ef8a..1c7a3f6631 100755
--- a/indra/newview/skins/default/xui/pl/floater_preview_gesture.xml
+++ b/indra/newview/skins/default/xui/pl/floater_preview_gesture.xml
@@ -45,12 +45,8 @@ Wstrzymaj
chyba, że dodasz pauzy.
</text>
<radio_group name="animation_trigger_type">
- <radio_item name="start">
- Start
- </radio_item>
- <radio_item name="stop">
- Stop
- </radio_item>
+ <radio_item name="start" label="Start" />
+ <radio_item name="stop" label="Stop" />
</radio_group>
<check_box label="do końca animacji" name="wait_anim_check"/>
<check_box label="czas w sekundach" name="wait_time_check"/>
diff --git a/indra/newview/skins/default/xui/pl/floater_report_abuse.xml b/indra/newview/skins/default/xui/pl/floater_report_abuse.xml
index 329fd9b2e0..a831c7e511 100755
--- a/indra/newview/skins/default/xui/pl/floater_report_abuse.xml
+++ b/indra/newview/skins/default/xui/pl/floater_report_abuse.xml
@@ -37,123 +37,51 @@
Hendrerit Vulputate
</text>
<combo_box name="category_combo" tool_tip="Wybór kategorii - wybierz kategorię, której dotyczy raport">
- <combo_item name="Select_category">
- Wybierz KategoriÄ™:
- </combo_item>
- <combo_item name="Age__Age_play">
- Wiek &gt; Udawanie Nieletniej Osoby
- </combo_item>
- <combo_item name="Age__Adult_resident_on_Teen_Second_Life">
- Wiek &gt; Dorosły Rezydent w Teen Second Life
- </combo_item>
+ <combo_box.item name="Select_category" label="Wybierz KategoriÄ™:"/>
+ <combo_box.item name="Age__Age_play" label="Wiek &gt; Udawanie Nieletniej Osoby"/>
+ <combo_box.item name="Age__Adult_resident_on_Teen_Second_Life" label="Wiek &gt; Dorosły Rezydent w Teen Second Life"/>
<combo_item name="Age__Underage_resident_outside_of_Teen_Second_Life">
Wiek &gt; Nieletni Rezydent poza Teen Second Life
</combo_item>
- <combo_item name="Assault__Combat_sandbox___unsafe_area">
- Napaść &gt; Strefa Militarna / Niebezpieczny Obszar
- </combo_item>
- <combo_item name="Assault__Safe_area">
- Napaść &gt; Bezpieczny Obszar
- </combo_item>
- <combo_item name="Assault__Weapons_testing_sandbox">
- Napaść &gt; Obszar do Testowania Broni
- </combo_item>
- <combo_item name="Commerce__Failure_to_deliver_product_or_service">
- Handel &gt; Niedostarczenie Produktu lub Usługi
- </combo_item>
- <combo_item name="Disclosure__Real_world_information">
- Naruszenie Prywatności &gt; Dane Osobiste
- </combo_item>
- <combo_item name="Disclosure__Remotely_monitoring chat">
- Ujawnienie &gt; Monitorowanie Czatu
- </combo_item>
- <combo_item name="Disclosure__Second_Life_information_chat_IMs">
- Ujawnienie &gt; Dane z Second Life / Czatu / IM
- </combo_item>
- <combo_item name="Disturbing_the_peace__Unfair_use_of_region_resources">
- Zakłócanie Spokoju &gt; Nieuczciwe Używanie Zasobów Regionu
- </combo_item>
- <combo_item name="Disturbing_the_peace__Excessive_scripted_objects">
- Zakłócanie Spokoju &gt; Przesadnie Skryptowane Obiekty
- </combo_item>
- <combo_item name="Disturbing_the_peace__Object_littering">
- Zakłócanie Spokoju &gt; Śmiecenie Obiektami
- </combo_item>
- <combo_item name="Disturbing_the_peace__Repetitive_spam">
- Zakłócanie Spokoju &gt; Ciągły Spam
- </combo_item>
- <combo_item name="Disturbing_the_peace__Unwanted_advert_spam">
- Zakłócanie Spokoju &gt; Nieporządany Spam Reklamowy
- </combo_item>
- <combo_item name="Fraud__L$">
- Oszustwo &gt; L$
- </combo_item>
- <combo_item name="Fraud__Land">
- Oszustwo &gt; Posiadłości
- </combo_item>
- <combo_item name="Fraud__Pyramid_scheme_or_chain_letter">
- Oszustwo &gt; Piramidy albo Listy ÅaÅ„cuchowe
- </combo_item>
- <combo_item name="Fraud__US$">
- Oszustwo &gt; US$
- </combo_item>
- <combo_item name="Harassment__Advert_farms___visual_spam">
- Prześladowanie &gt; Farmy Reklamowe / Wizualny Spam
- </combo_item>
- <combo_item name="Harassment__Defaming_individuals_or_groups">
- Prześladowanie &gt; Zniesławianie Jedostek lub Grup
- </combo_item>
- <combo_item name="Harassment__Impeding_movement">
- Prześladowanie &gt; Ograniczanie Ruchu
- </combo_item>
- <combo_item name="Harassment__Sexual_harassment">
- Prześladowanie &gt; Molestowanie Seksualne
- </combo_item>
- <combo_item name="Harassment__Solicting_inciting_others_to_violate_ToS">
- PrzeÅ›ladowanie &gt; Namawianie/ZachÄ™canie Innych do Åamania Warunków Umowy
- </combo_item>
- <combo_item name="Harassment__Verbal_abuse">
- Prześladowanie &gt; Znieważanie Słowne
- </combo_item>
- <combo_item name="Indecency__Broadly_offensive_content_or_conduct">
- Nieprzyzwoitość &gt; Obraźliwa Treść lub Postępowanie
- </combo_item>
- <combo_item name="Indecency__Inappropriate_avatar_name">
- Nieprzyzwoitość &gt; Niestosowne Imię Awatara
- </combo_item>
+ <combo_box.item name="Assault__Combat_sandbox___unsafe_area" label="Napaść &gt; Strefa Militarna / Niebezpieczny Obszar"/>
+ <combo_box.item name="Assault__Safe_area" label="Napaść &gt; Bezpieczny Obszar"/>
+ <combo_box.item name="Assault__Weapons_testing_sandbox" label="Napaść &gt; Obszar do Testowania Broni"/>
+ <combo_box.item name="Commerce__Failure_to_deliver_product_or_service" label="Handel &gt; Niedostarczenie Produktu lub Usługi"/>
+ <combo_box.item name="Disclosure__Real_world_information" label="Naruszenie Prywatności &gt; Dane Osobiste"/>
+ <combo_box.item name="Disclosure__Remotely_monitoring chat" label="Ujawnienie &gt; Monitorowanie Czatu"/>
+ <combo_box.item name="Disclosure__Second_Life_information_chat_IMs" label="Ujawnienie &gt; Dane z Second Life / Czatu / IM"/>
+ <combo_box.item name="Disturbing_the_peace__Unfair_use_of_region_resources" label="Zakłócanie Spokoju &gt; Nieuczciwe Używanie Zasobów Regionu"/>
+ <combo_box.item name="Disturbing_the_peace__Excessive_scripted_objects" label="Zakłócanie Spokoju &gt; Przesadnie Skryptowane Obiekty"/>
+ <combo_box.item name="Disturbing_the_peace__Object_littering" label="Zakłócanie Spokoju &gt; Śmiecenie Obiektami"/>
+ <combo_box.item name="Disturbing_the_peace__Repetitive_spam" label="Zakłócanie Spokoju &gt; Ciągły Spam"/>
+ <combo_box.item name="Disturbing_the_peace__Unwanted_advert_spam" label="Zakłócanie Spokoju &gt; Nieporządany Spam Reklamowy"/>
+ <combo_box.item name="Fraud__L$" label="Oszustwo &gt; L$"/>
+ <combo_box.item name="Fraud__Land" label="Oszustwo &gt; Posiadłości"/>
+ <combo_box.item name="Fraud__Pyramid_scheme_or_chain_letter" label="Oszustwo &gt; Piramidy albo Listy ÅaÅ„cuchowe"/>
+ <combo_box.item name="Fraud__US$" label="Oszustwo &gt; US$"/>
+ <combo_box.item name="Harassment__Advert_farms___visual_spam" label="Prześladowanie &gt; Farmy Reklamowe / Wizualny Spam"/>
+ <combo_box.item name="Harassment__Defaming_individuals_or_groups" label="Prześladowanie &gt; Zniesławianie Jedostek lub Grup"/>
+ <combo_box.item name="Harassment__Impeding_movement" label="Prześladowanie &gt; Ograniczanie Ruchu"/>
+ <combo_box.item name="Harassment__Sexual_harassment" label="Prześladowanie &gt; Molestowanie Seksualne"/>
+ <combo_box.item name="Harassment__Solicting_inciting_others_to_violate_ToS" label="PrzeÅ›ladowanie &gt; Namawianie/ZachÄ™canie Innych do Åamania Warunków Umowy (ToS)"/>
+ <combo_box.item name="Harassment__Verbal_abuse" label="Prześladowanie &gt; Znieważanie Słowne"/>
+ <combo_box.item name="Indecency__Broadly_offensive_content_or_conduct" label="Nieprzyzwoitość &gt; Obraźliwa Treść lub Postępowanie"/>
+ <combo_box.item name="Indecency__Inappropriate_avatar_name" label="Nieprzyzwoitość &gt; Niestosowne Imię Awatara"/>
<combo_item name="Indecency__Mature_content_in_PG_region">
Nieprzyzwoitość &gt; Obraźliwa treść i postępowanie w regionie &apos;PG&apos;
</combo_item>
<combo_item name="Indecency__Inappropriate_content_in_Mature_region">
Nieprzyzwoitość &gt; Obraźliwa treść i postępowanie w regionie &apos;Mature&apos;
</combo_item>
- <combo_item name="Intellectual_property_infringement_Content_Removal">
- Naruszenie Własności Intelektualnej &gt; Usunięcie Treści
- </combo_item>
- <combo_item name="Intellectual_property_infringement_CopyBot_or_Permissions_Exploit">
- Naruszenie Własności Intelektualnej &gt; CopyBot albo Nadużycie Przywilejów
- </combo_item>
- <combo_item name="Intolerance">
- Nietolerancja
- </combo_item>
- <combo_item name="Land__Abuse_of_sandbox_resources">
- Posiadłości &gt; Nadużywanie Piaskownicy
- </combo_item>
- <combo_item name="Land__Encroachment__Objects_textures">
- Posiadłości &gt; Naruszenie &gt; Obiekty/Tekstury
- </combo_item>
- <combo_item name="Land__Encroachment__Particles">
- Posiadłości &gt; Naruszenie &gt; Cząsteczki
- </combo_item>
- <combo_item name="Land__Encroachment__Trees_plants">
- Posiadłości &gt; Naruszenie &gt; Drzewa/Rośliny
- </combo_item>
- <combo_item name="Wagering_gambling">
- Zakłady/Hazard
- </combo_item>
- <combo_item name="Other">
- Inne
- </combo_item>
+ <combo_box.item name="Intellectual_property_infringement_Content_Removal" label="Naruszenie Własności Intelektualnej &gt; Usunięcie Treści"/>
+ <combo_box.item name="Intellectual_property_infringement_CopyBot_or_Permissions_Exploit" label="Naruszenie Własności Intelektualnej &gt; CopyBot albo Nadużycie Przywilejów"/>
+ <combo_box.item name="Intolerance" label="Nietolerancja"/>
+ <combo_box.item name="Land__Abuse_of_sandbox_resources" label="Posiadłości &gt; Nadużywanie Piaskownicy"/>
+ <combo_box.item name="Land__Encroachment__Objects_textures" label="Posiadłości &gt; Naruszenie &gt; Obiekty/Tekstury"/>
+ <combo_box.item name="Land__Encroachment__Particles" label="Posiadłości &gt; Naruszenie &gt; Cząsteczki"/>
+ <combo_box.item name="Land__Encroachment__Trees_plants" label="Posiadłości &gt; Naruszenie &gt; Drzewa/Rośliny"/>
+ <combo_box.item name="Wagering_gambling" label="Zakłady/Hazard"/>
+ <combo_box.item name="Other" label="Inne"/>
</combo_box>
<text name="abuser_name_title">
Dane osobowe:
diff --git a/indra/newview/skins/default/xui/pl/floater_sell_land.xml b/indra/newview/skins/default/xui/pl/floater_sell_land.xml
index 94500d0295..70451fb5f6 100755
--- a/indra/newview/skins/default/xui/pl/floater_sell_land.xml
+++ b/indra/newview/skins/default/xui/pl/floater_sell_land.xml
@@ -34,15 +34,9 @@
Wybierz sprzedaż dla kogokolwiek albo dla wybranego kupca.
</text>
<combo_box name="sell_to">
- <combo_item name="--selectone--">
- -- wybierz --
- </combo_item>
- <combo_item name="Anyone">
- Ktokolwiek
- </combo_item>
- <combo_item name="Specificuser:">
- Wybrany kupiec:
- </combo_item>
+ <combo_box.item name="--selectone--" label="wybierz --" />
+ <combo_box.item name="Anyone" label="Ktokolwiek" />
+ <combo_box.item name="Specificuser:" label="Wybrany kupiec:" />
</combo_box>
<button label="Wybierz..." name="sell_to_select_agent" />
<text name="sell_objects_label">
@@ -52,12 +46,8 @@
Przekazywalne obiekty właściciela Posiadłości zmienią właściciela.
</text>
<radio_group name="sell_objects">
- <radio_item name="no">
- Nie, zatrzymaj obiekty
- </radio_item>
- <radio_item name="yes">
- Tak, sprzedaj obiekty razem z Posiadłością
- </radio_item>
+ <radio_item name="no" label="Nie, zatrzymaj obiekty" />
+ <radio_item name="yes" label="Tak, sprzedaj obiekty razem z Posiadłością" />
</radio_group>
<button label="Pokaż Obiekty" name="show_objects" />
<text name="nag_message_label">
diff --git a/indra/newview/skins/default/xui/pl/floater_settings_debug.xml b/indra/newview/skins/default/xui/pl/floater_settings_debug.xml
index 496f8af2db..99fa444a1b 100755
--- a/indra/newview/skins/default/xui/pl/floater_settings_debug.xml
+++ b/indra/newview/skins/default/xui/pl/floater_settings_debug.xml
@@ -1,12 +1,8 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<floater name="settings_debug" title="Ustawienia Usuwania Błędów">
<combo_box name="boolean_combo">
- <combo_item name="TRUE">
- PRAWDA
- </combo_item>
- <combo_item name="FALSE">
- NIEPRAWDA
- </combo_item>
+ <combo_box.item name="TRUE" label="PRAWDA" />
+ <combo_box.item name="FALSE" label="NIEPRAWDA" />
</combo_box>
<color_swatch label="Kolor" name="color_swatch"/>
<spinner label="x" name="val_spinner_1"/>
diff --git a/indra/newview/skins/default/xui/pl/floater_snapshot.xml b/indra/newview/skins/default/xui/pl/floater_snapshot.xml
index 9c011b9a64..24bf88da85 100755
--- a/indra/newview/skins/default/xui/pl/floater_snapshot.xml
+++ b/indra/newview/skins/default/xui/pl/floater_snapshot.xml
@@ -4,15 +4,9 @@
Lokacja zapisu
</text>
<radio_group label="Rodzaje zdjęć" name="snapshot_type_radio">
- <radio_item name="postcard">
- Wyślij (email) pocztówkę
- </radio_item>
- <radio_item name="texture">
- Załaduj do szafy ([AMOUNT]L$)
- </radio_item>
- <radio_item name="local">
- Zapisz na dysk
- </radio_item>
+ <radio_item name="postcard" label="Wyślij (email) pocztówkę" />
+ <radio_item name="texture" label="Załaduj do szafy ([AMOUNT]L$)" />
+ <radio_item name="local" label="Zapisz na dysk" />
</radio_group>
<text name="file_size_label">
Rozmiar pliku: [SIZE] KB
@@ -21,12 +15,12 @@
<button label="Wyślij" name="send_btn"/>
<button label="Załaduj (L$[AMOUNT])" name="upload_btn"/>
<flyout_button label="Zapisz" name="save_btn" tool_tip="Zapisz zdjęcie na dysk">
- <flyout_button_item name="save_item">
- Zapisz
- </flyout_button_item>
- <flyout_button_item name="saveas_item">
- Zapisz Jako...
- </flyout_button_item>
+ <flyout_button.item name="save_item">
+ Zapisz
+ </flyout_button.item>
+ <flyout_button.item name="saveas_item">
+ Zapisz Jako...
+ </flyout_button.item>
</flyout_button>
<button label="Anuluj" name="discard_btn"/>
<button label="Więcej &gt;&gt;" name="more_btn" tool_tip="Ustawienia Zaawansowane"/>
@@ -38,75 +32,33 @@
Format
</text>
<combo_box label="Rozdzielczość" name="postcard_size_combo">
- <combo_item name="CurrentWindow">
- Obecne Okno
- </combo_item>
- <combo_item name="640x480">
- 640x480
- </combo_item>
- <combo_item name="800x600">
- 800x600
- </combo_item>
- <combo_item name="1024x768">
- 1024x768
- </combo_item>
- <combo_item name="Custom">
- Wybierz
- </combo_item>
+ <combo_box.item name="CurrentWindow" label="Obecne Okno" />
+ <combo_box.item name="640x480" label="640x480" />
+ <combo_box.item name="800x600" label="800x600" />
+ <combo_box.item name="1024x768" label="1024x768" />
+ <combo_box.item name="Custom" label="Wybierz" />
</combo_box>
<combo_box label="Rozdzielczość" name="texture_size_combo">
- <combo_item name="CurrentWindow">
- Obecne Okno
- </combo_item>
- <combo_item name="Small(128x128)">
- Mały (128x128)
- </combo_item>
- <combo_item name="Medium(256x256)">
- Åšredni (256x256)
- </combo_item>
- <combo_item name="Large(512x512)">
- Duży (512x512)
- </combo_item>
- <combo_item name="Custom">
- Wybierz
- </combo_item>
+ <combo_box.item name="CurrentWindow" label="Obecne Okno" />
+ <combo_box.item name="Small(128x128)" label="Mały (128x128)" />
+ <combo_box.item name="Medium(256x256)" label="Åšredni (256x256)" />
+ <combo_box.item name="Large(512x512)" label="Duży (512x512)" />
+ <combo_box.item name="Custom" label="Wybierz" />
</combo_box>
<combo_box label="Rozdzielczość" name="local_size_combo">
- <combo_item name="CurrentWindow">
- Obecne Okno
- </combo_item>
- <combo_item name="320x240">
- 320x240
- </combo_item>
- <combo_item name="640x480">
- 640x480
- </combo_item>
- <combo_item name="800x600">
- 800x600
- </combo_item>
- <combo_item name="1024x768">
- 1024x768
- </combo_item>
- <combo_item name="1280x1024">
- 1280x1024
- </combo_item>
- <combo_item name="1600x1200">
- 1600x1200
- </combo_item>
- <combo_item name="Custom">
- Wybierz
- </combo_item>
+ <combo_box.item name="CurrentWindow" label="Obecne Okno" />
+ <combo_box.item name="320x240" label="320x240" />
+ <combo_box.item name="640x480" label="640x480" />
+ <combo_box.item name="800x600" label="800x600" />
+ <combo_box.item name="1024x768" label="1024x768" />
+ <combo_box.item name="1280x1024" label="1280x1024" />
+ <combo_box.item name="1600x1200" label="1600x1200" />
+ <combo_box.item name="Custom" label="Wybierz" />
</combo_box>
<combo_box label="Format" name="local_format_combo">
- <combo_item name="PNG">
- PNG
- </combo_item>
- <combo_item name="JPEG">
- JPEG
- </combo_item>
- <combo_item name="BMP">
- BMP
- </combo_item>
+ <combo_box.item name="PNG" label="PNG" />
+ <combo_box.item name="JPEG" label="JPEG" />
+ <combo_box.item name="BMP" label="BMP" />
</combo_box>
<spinner label="Szer." name="snapshot_width"/>
<spinner label="Wys." name="snapshot_height"/>
@@ -116,15 +68,9 @@
Zapisz:
</text>
<combo_box label="Warstwy Obrazu" name="layer_types">
- <combo_item name="Colors">
- Kolory
- </combo_item>
- <combo_item name="Depth">
- Głębokość
- </combo_item>
- <combo_item name="ObjectMattes">
- Obiekty Åšlepe
- </combo_item>
+ <combo_box.item name="Colors" label="Kolory" />
+ <combo_box.item name="Depth" label="Głębokość" />
+ <combo_box.item name="ObjectMattes" label="Obiekty Åšlepe" />
</combo_box>
<check_box label="Pokaż interfejs na zdjęciu" name="ui_check"/>
<check_box label="Pokaż obiekty HUD na zdjęciu" name="hud_check"/>
diff --git a/indra/newview/skins/default/xui/pl/floater_tos.xml b/indra/newview/skins/default/xui/pl/floater_tos.xml
index c2d266b6b0..b9a146df22 100755
--- a/indra/newview/skins/default/xui/pl/floater_tos.xml
+++ b/indra/newview/skins/default/xui/pl/floater_tos.xml
@@ -5,7 +5,7 @@
<check_box label="Zgadzam siÄ™ na Warunki Serwisu (Terms of Service)" name="agree_chk" />
<text name="tos_heading">
Proszę dokładnie przeczytać następujące Warunki Serwisu (Terms of Service). Musisz
-zaakceptować umowę żeby kontynuować logowanie do Second Life.
+zaakceptować umowę żeby kontynuować logowanie do [SECOND_LIFE].
</text>
<text_editor name="tos_text">
TOS_TEXT
diff --git a/indra/newview/skins/default/xui/pl/floater_world_map.xml b/indra/newview/skins/default/xui/pl/floater_world_map.xml
index 46e6091b33..42befb1aff 100755
--- a/indra/newview/skins/default/xui/pl/floater_world_map.xml
+++ b/indra/newview/skins/default/xui/pl/floater_world_map.xml
@@ -30,14 +30,10 @@
<check_box label="&apos;Adult&apos;" name="event_adult_chk"/>
<icon bottom="-196" name="avatar_icon"/>
<combo_box label="Dostępni Znajomi" name="friend combo" tool_tip="Znajomi na mapie">
- <combo_item name="none_selected">
- Dostępni Znajomi
- </combo_item>
+ <combo_box.item name="none_selected" label="Dostępni Znajomi" />
</combo_box>
<combo_box label="Zapisane Miejsca" name="landmark combo" tool_tip="Zapisane miejsca na mapie">
- <combo_item name="none_selected">
- Zapisane Miejsca
- </combo_item>
+ <combo_box.item name="none_selected" label="Zapisane Miejsca" />
</combo_box>
<line_editor label="Szukaj po nazwie regionu" name="location" tool_tip="Wpisz nazwÄ™ regionu"/>
<button label="Szukaj" name="DoSearch" tool_tip="Wyszukiwaie regionu"/>
@@ -58,6 +54,6 @@
<button label="Pokaż Cel" label_selected="Pokaż Cel" name="Show Destination" tool_tip="Wycentruj miejsce celu na mapie"/>
<button label="Wyczyść" label_selected="Wyczyść" name="Clear" tool_tip="Stop tracking"/>
<button label="Pokaż moje miejsce" label_selected="Pokaż moje miejsce" name="Show My Location" tool_tip="Wycentruj pozcję awatara na mapie"/>
- <button label="Kopiuj SLURL do schowka" name="copy_slurl" tool_tip="Kopie SLURL obecnego miejsca będę mogły zostać użyte na stronie internetowej."/>
+ <button label="Kopiuj SLurl do schowka" name="copy_slurl" tool_tip="Kopie SLurl obecnego miejsca będę mogły zostać użyte na stronie internetowej."/>
<slider label="Skala" name="zoom slider"/>
</floater>
diff --git a/indra/newview/skins/default/xui/pl/language_settings.xml b/indra/newview/skins/default/xui/pl/language_settings.xml
new file mode 100644
index 0000000000..71418d446a
--- /dev/null
+++ b/indra/newview/skins/default/xui/pl/language_settings.xml
@@ -0,0 +1,55 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<!-- This file contains strings that used to be hardcoded in the source.-->
+<strings>
+
+ <!-- Locale Information -->
+ <string name="MicrosoftLocale">english</string>
+ <string name="DarwinLocale">C</string>
+ <string name="LinuxLocale">C</string>
+
+ <!--
+ datetimeToCodes["wkday"] = "%a"; // Thu
+ datetimeToCodes["weekday"] = "%A"; // Thursday
+ datetimeToCodes["year4"] = "%Y"; // 2009
+ datetimeToCodes["year"] = "%Y"; // 2009
+ datetimeToCodes["year2"] = "%y"; // 09
+ datetimeToCodes["mth"] = "%b"; // Aug
+ datetimeToCodes["month"] = "%B"; // August
+ datetimeToCodes["mthnum"] = "%m"; // 08
+ datetimeToCodes["day"] = "%d"; // 31
+ datetimeToCodes["hour24"] = "%H"; // 14
+ datetimeToCodes["hour"] = "%H"; // 14
+ datetimeToCodes["hour12"] = "%I"; // 02
+ datetimeToCodes["min"] = "%M"; // 59
+ datetimeToCodes["ampm"] = "%p"; // AM
+ datetimeToCodes["second"] = "%S"; // 59
+ datetimeToCodes["timezone"] = "%Z"; // PST
+ -->
+
+ <string name="TimeHour">hour,datetime,slt</string>
+ <string name="TimeMin">min,datetime,slt</string>
+ <string name="TimeYear">year,datetime,slt</string>
+ <string name="TimeDay">day,datetime,slt</string>
+ <string name="TimeMonth">mthnum,datetime,slt</string>
+ <string name="TimeWeek">wkday,datetime,slt</string>
+ <string name="TimeAMPM">ampm,datetime,slt</string>
+ <string name="TimeHour12">hour12,datetime,slt</string>
+
+ <string name="LTimeMthNum">mthnum,datetime,local</string>
+ <string name="LTimeWeek">wkday,datetime,local</string>
+ <string name="LTimeMonth">mth,datetime,local</string>
+ <string name="LTimeDay">day,datetime,local</string>
+ <string name="LTimeSec">second,datetime,local</string>
+ <string name="LTimeHour">hour,datetime,local</string>
+ <string name="LTimeMin">min,datetime,local</string>
+ <string name="LTimeYear">year,datetime,local</string>
+
+ <string name="UTCTimeWeek">weekday,datetime,utc</string>
+ <string name="UTCTimeDay">day,datetime,utc</string>
+ <string name="UTCTimeMth">mth,datetime,utc</string>
+ <string name="UTCTimeYr">year,datetime,utc</string>
+ <string name="UTCTimeHr">hour,datetime,utc</string>
+ <string name="UTCTimeMin">min,datetime,utc</string>
+ <string name="UTCTimeSec">second,datetime,utc</string>
+ <string name="UTCTimeTimezone">timezone,datetime,utc</string>
+</strings>
diff --git a/indra/newview/skins/default/xui/pl/menu_login.xml b/indra/newview/skins/default/xui/pl/menu_login.xml
index 4d44af19fb..2445d69ac0 100755
--- a/indra/newview/skins/default/xui/pl/menu_login.xml
+++ b/indra/newview/skins/default/xui/pl/menu_login.xml
@@ -7,7 +7,7 @@
<menu_item_call label="Ustawienia..." name="Preferences..." />
</menu>
<menu label="Pomoc" name="Help">
- <menu_item_call label="Second Life: Pomoc" name="Second Life Help" />
- <menu_item_call label="O Second Life..." name="About Second Life..." />
+ <menu_item_call label="[SECOND_LIFE]: Pomoc" name="Second Life Help" />
+ <menu_item_call label="O [APP_NAME]..." name="About Second Life..." />
</menu>
</menu_bar>
diff --git a/indra/newview/skins/default/xui/pl/menu_viewer.xml b/indra/newview/skins/default/xui/pl/menu_viewer.xml
index aafd2d412d..1898906d9f 100755
--- a/indra/newview/skins/default/xui/pl/menu_viewer.xml
+++ b/indra/newview/skins/default/xui/pl/menu_viewer.xml
@@ -181,10 +181,10 @@
<menu_item_call label="Wstrzymaj Działanie Skryptów w Selekcji" name="Set Scripts to Not Running in Selection"/>
</menu>
<menu label="Pomoc" name="Help">
- <menu_item_call label="Second Life: Pomoc" name="Second Life Help"/>
+ <menu_item_call label="[SECOND_LIFE]: Pomoc" name="Second Life Help"/>
<menu_item_call label="Samouczek" name="Tutorial"/>
<menu_item_separator label="-----------" name="separator"/>
- <menu_item_call label="Oficjalny Blog Second Life..." name="Official Linden Blog..."/>
+ <menu_item_call label="Oficjalny Blog [SECOND_LIFE]..." name="Official Linden Blog..."/>
<menu_item_separator label="-----------" name="separator2"/>
<menu_item_call label="Portal dla Skrypterów..." name="Scripting Portal..."/>
<menu_item_separator label="-----------" name="separator3"/>
@@ -202,6 +202,6 @@
<menu_item_separator label="-----------" name="separator9"/>
<menu_item_call label="Wyślij Raport Błędu..." name="Report Bug..."/>
</menu>
- <menu_item_call label="O Second Life..." name="About Second Life..."/>
+ <menu_item_call label="O [APP_NAME]..." name="About Second Life..."/>
</menu>
</menu_bar>
diff --git a/indra/newview/skins/default/xui/pl/notifications.xml b/indra/newview/skins/default/xui/pl/notifications.xml
index ded22590f2..3c21f7f5b5 100644
--- a/indra/newview/skins/default/xui/pl/notifications.xml
+++ b/indra/newview/skins/default/xui/pl/notifications.xml
@@ -6,6 +6,9 @@
<global name="alwayschoose">
Pozwalaj na wybór tej opcji
</global>
+ <global name="implicitclosebutton">
+ Zamknij
+ </global>
<template name="okbutton">
<form>
<button
@@ -71,7 +74,7 @@
</form>
</template>
<notification functor="GenericAcknowledge" label="Nieznany rodzaj komunikatu" name="MissingAlert">
- Twoja wersja klienta Second Life nie może wyświetlić odebranej wiadomości.
+ Twoja wersja klienta [APP_NAME] nie może wyświetlić odebranej wiadomości.
Szczegóły błędu: Błąd o nazwie &apos;[_NAME]&apos; nie został odnaleziony w pliku notifications.xml.
<usetemplate name="okbutton" yestext="OK"/>
@@ -94,7 +97,7 @@ Szczegóły błędu: Błąd o nazwie &apos;[_NAME]&apos; nie został odnaleziony
<usetemplate name="okcancelbuttons" notext="Anuluj" yestext="Tak"/>
</notification>
<notification name="BadInstallation">
- Podczas aktualizacji klienta Second Life wystąpił błąd. Proszę odwiedzić stronę secondlife.com by ściągnąć najnowszą wersje klienta.
+ Podczas aktualizacji klienta [APP_NAME] wystąpił błąd. Proszę odwiedzić stronę secondlife.com by ściągnąć najnowszą wersje klienta.
<usetemplate
name="okbutton"
yestext="OK"/>
@@ -205,23 +208,23 @@ Dodać ten przywilej do funkcji [ROLE_NAME]?
- tej posiadłości w przeglądarce internetowej
</notification>
<notification name="ClickSoundHelpLand">
- Media oraz muzyka są aktywne według ustawień posiadłości dla mediów. Dźwięk oraz komunikacja głosowa mogą być ograniczone w danej posiadłości, w zależności od ustawień rodzaju treści jaką zawiera. Skorzystaj z Second Life:Pomoc by uzyskać więcej informacji na temat dostępu do regionów z podanym rodzajem treści jaką zawiera.
+ Media oraz muzyka są aktywne według ustawień posiadłości dla mediów. Dźwięk oraz komunikacja głosowa mogą być ograniczone w danej posiadłości, w zależności od ustawień rodzaju treści jaką zawiera. Skorzystaj z [SECOND_LIFE]:Pomoc by uzyskać więcej informacji na temat dostępu do regionów z podanym rodzajem treści jaką zawiera.
<url name="url">
https://support.secondlife.com/ics/support/default.asp?deptID=4417&amp;task=knowledge&amp;questionID=5046
</url>
<usetemplate
name="okcancelbuttons"
- yestext="Second Life:Pomoc"
+ yestext="[SECOND_LIFE]:Pomoc"
notext="Zamknij" />
</notification>
<notification name="ClickSearchHelpAll">
- Wyniki wyszukiwania wyświetlają się na podstawie rodzaju zakładki wyszukiwarki, z której korzystasz, rodzaju statusu Twojego wieku, wybranej kategorii, oraz innych czynników. By uzyskać wiecej szczegółów skorzystaj z Second Life: Pomoc.
+ Wyniki wyszukiwania wyświetlają się na podstawie rodzaju zakładki wyszukiwarki, z której korzystasz, rodzaju statusu Twojego wieku, wybranej kategorii, oraz innych czynników. By uzyskać wiecej szczegółów skorzystaj z [SECOND_LIFE]:Pomoc.
<url name="url">
https://support.secondlife.com/ics/support/default.asp?deptID=4417&amp;task=knowledge&amp;questionID=4722
</url>
<usetemplate
name="okcancelbuttons"
- yestext="Second Life:Pomoc"
+ yestext="[SECOND_LIFE]:Pomoc"
notext="Zamknij" />
</notification>
<notification name="ClickPublishHelpLandDisabled">
@@ -235,7 +238,7 @@ Dodać ten przywilej do funkcji [ROLE_NAME]?
<notification name="ClickPartnerHelpAvatar">
Możesz zaproponować związek innemu Rezydentowi lub rozwiązać istniejący związek na stronie internetowej [SECOND_LIFE].
-Chcesz dowiedzieć się więcej na temat związków w Second Life?
+Chcesz dowiedzieć się więcej na temat związków w [SECOND_LIFE]?
<usetemplate name="okcancelbuttons" notext="Anuluj" yestext="Idź na stronę"/>
</notification>
<notification name="ClickUploadHelpPermissions">
@@ -273,7 +276,7 @@ Cena wynosi [SALE_PRICE]L$ i sprzedaż będzie autoryzowana dla [NAME].
<usetemplate name="okcancelbuttons" notext="Anuluj" yestext="OK"/>
</notification>
<notification name="ConfirmLandSaleToAnyoneChange">
- UWAGA: Wybierając Sprzedaż dla Kogokolwiek umożliwiasz zakup posiadłości wszystkim Rezydentom Second Life.
+ UWAGA: Wybierając Sprzedaż dla Kogokolwiek umożliwiasz zakup posiadłości wszystkim Rezydentom [SECOND_LIFE].
Posiadłość o powierzchni [LAND_SIZE] m zostaje wystawiona na sprzedaż.
Cena wynosi [SALE_PRICE]L$ i sprzedaż będzie autoryzowana dla [NAME].
@@ -417,17 +420,17 @@ Pamiętaj! Nie ma rekompensaty za poniesione koszta.
<usetemplate name="okcancelbuttons" notext="Anuluj" yestext="OK"/>
</notification>
<notification name="CacheWillClear">
- Bufor danych na dysku zostanie zresetowany po relogu do [SECOND_LIFE].
+ Bufor danych na dysku zostanie zresetowany po relogu do [APP_NAME].
</notification>
<notification name="CacheWillBeMoved">
- Bufor danych na dysku zostanie przemieszczony po relogu do [SECOND_LIFE].
+ Bufor danych na dysku zostanie przemieszczony po relogu do [APP_NAME].
Bufor będzie również wyczyszczony.
</notification>
<notification name="ChangeConnectionPort">
- Ustawienia portu zostanÄ… wprowadzone po relogu do [SECOND_LIFE].
+ Ustawienia portu zostanÄ… wprowadzone po relogu do [APP_NAME].
</notification>
<notification name="ChangeSkin">
- Nowa skórka zostanie wprowadzona po relogu do [SECOND_LIFE].
+ Nowa skórka zostanie wprowadzona po relogu do [APP_NAME].
</notification>
<notification name="GoToAuctionPage">
Odwiedzić stronę internetową [SECOND_LIFE] żeby zobaczyć szczgóły aukcji lub zrobić ofertę?
@@ -486,7 +489,7 @@ Obiekt może znajdować się zbyt daleko albo został usuniety.
Nie można zapisać pliku [[FILE]]
</notification>
<notification name="UnsupportedHardware">
- Uwaga: Twój system nie spełnia minimalnych wymagań sprzętowych Second Life. Jakość i prędkość Second Life mogą być pogorszone. Niestety, nie będziemy w stanie udzielić Ci technicznej pomocy, ponieważ konfiguracja Twojego systemu nie spełnia wymagań sprzętowych.
+ Uwaga: Twój system nie spełnia minimalnych wymagań sprzętowych [APP_NAME]. Jakość i prędkość [APP_NAME] mogą być pogorszone. Niestety, nie będziemy w stanie udzielić Ci technicznej pomocy, ponieważ konfiguracja Twojego systemu nie spełnia wymagań sprzętowych.
MINSPECS
Czy chcesz odwiedzić stronę [_URL] po dodatkowe informacje?
@@ -498,14 +501,14 @@ Czy chcesz odwiedzić stronę [_URL] po dodatkowe informacje?
<notification name="UnknownGPU">
Twój system jest wyposażony w kartę graficzną której jeszcze nie znamy.
To się często zdarza z nowym sprzętem, którego jeszcze nie testowaliśmy.
-Second Life najprawdopodobniej będzie działało poprawnie. Możliwe, że będziesz musiał wyregulować ustawienia grafiki.
+[APP_NAME] najprawdopodobniej będzie działało poprawnie. Możliwe, że będziesz musiał wyregulować ustawienia grafiki.
(Edycja &gt; Ustawienia &gt; Grafika).
<form name="form">
<ignore name="ignore" text="Zignoruj ostrzeżenie"/>
</form>
</notification>
<notification name="DisplaySettingsNoShaders">
- [SECOND_LIFE] zawiesił się podczas inicjalizacji sterowników graficznych. Jakość grafiki została zmniejszona - może pomoże. Pewne funkcje graficzne zostały wyłączone. Zalecamy aktualizcje strerowników grapicznych.
+ [APP_NAME] zawiesił się podczas inicjalizacji sterowników graficznych. Jakość grafiki została zmniejszona - może pomoże. Pewne funkcje graficzne zostały wyłączone. Zalecamy aktualizcje strerowników grapicznych.
Możesz podnieść jakość grafiki pod Ustawienia &gt; Grafika.
</notification>
<notification name="RegionNoTerraforming">
@@ -776,7 +779,7 @@ Posiadłość nie została wybrana.
Region nie znaleziony.
</notification>
<notification name="CannotCloseFloaterBuyLand">
- Dialog Kup Posiadłość nie może zostać zamknięty dopóki Second Life nie oszacuje ceny tej tranzakcji.
+ Dialog Kup Posiadłość nie może zostać zamknięty dopóki [APP_NAME] nie oszacuje ceny tej tranzakcji.
</notification>
<notification name="CannotDeedLandNothingSelected">
Nie można przekazać posiadłości:
@@ -950,7 +953,7 @@ Jeżeli wciąż masz ten problem, wybierz Pomoc &gt; Zgłoś Błędy Klienta i p
[MESSAGE]
Kliknij Kontynuuj żeby zobaczyć IMy i czat.
-Żadne inne operacje nie będą dozwolone. Kliknij Wyłącz w celu natychmiastowego opuszczenia [SECOND_LIFE].
+Żadne inne operacje nie będą dozwolone. Kliknij Wyłącz w celu natychmiastowego opuszczenia [APP_NAME].
<usetemplate name="okcancelbuttons" notext="Wyłącz" yestext="Kontynuuj"/>
</notification>
<notification name="OnlyOfficerCanBuyLand">
@@ -1116,14 +1119,14 @@ Możesz normalnie używać [SECOND_LIFE], inni użytkownicy będą Cię widzieli
</form>
</notification>
<notification name="FirstRun">
- Instalacja [SECOND_LIFE] zakończona.
+ Instalacja [APP_NAME] zakończona.
Jeżeli używasz [SECOND_LIFE] po raz pierwszy to musisz stworzyć konto żeby móc się zalogować.
Przejść na stronę www.secondlife.com żeby stworzyć nowe konto?
<usetemplate name="okcancelbuttons" notext="Kontynuuj" yestext="Nowe Konto..."/>
</notification>
<notification name="LoginPacketNeverReceived">
- Problemy z połączeniem. Problem może być spowodowany Twoim połączeniem z Internetem albo może istnieć po stronie serwerów Second Life.
+ Problemy z połączeniem. Problem może być spowodowany Twoim połączeniem z Internetem albo może istnieć po stronie serwerów [SECOND_LIFE].
Możesz sprawdzić swoje połączenie z Internetem i spróbować ponownie za kilka minut albo kliknij Pomoc żeby połączyć się ze stroną pomocy technicznej albo wybierz Teleportuj żeby spróbować teleportacji do Twojego miejsca startu.
<form name="form">
@@ -1225,33 +1228,33 @@ Wybierz obiekt na sprzedaż i spróbuj jeszcze raz.
[DOWNLOAD_PATH].
</notification>
<notification name="DownloadWindowsMandatory">
- Nowa wersja [SECOND_LIFE] została opublikowana.
+ Nowa wersja [APP_NAME] została opublikowana.
[MESSAGE]
-Musisz zainstalować nową wersję żeby używać [SECOND_LIFE].
+Musisz zainstalować nową wersję żeby używać [APP_NAME].
<usetemplate name="okcancelbuttons" notext="Wyłącz program" yestext="Załaduj"/>
</notification>
<notification name="DownloadWindows">
- Uaktualniona wersja [SECOND_LIFE] została opublikowana.
+ Uaktualniona wersja [APP_NAME] została opublikowana.
[MESSAGE]
Aktualizacja nie jest wymagana ale jest zalecana w celu poprawy prędkości i stabilności.
<usetemplate name="okcancelbuttons" notext="Kontynuuj" yestext="Załaduj"/>
</notification>
<notification name="DownloadWindowsReleaseForDownload">
- Uaktualniona wersja [SECOND_LIFE] została opublikowana.
+ Uaktualniona wersja [APP_NAME] została opublikowana.
[MESSAGE]
Aktualizacja nie jest wymagana ale jest zalecana w celu poprawy prędkości i stabilności.
<usetemplate name="okcancelbuttons" notext="Kontynuuj" yestext="Załaduj"/>
</notification>
<notification name="DownloadMacMandatory">
- Nowa wersja [SECOND_LIFE] została opublikowana.
+ Nowa wersja [APP_NAME] została opublikowana.
[MESSAGE]
-Musisz zainstalować nową wersję żeby używać [SECOND_LIFE].
+Musisz zainstalować nową wersję żeby używać [APP_NAME].
Załadować do foldera Aplikacji?
<usetemplate name="okcancelbuttons" notext="Wyłącz program" yestext="Załaduj"/>
</notification>
<notification name="DownloadMac">
- Uaktualniona wersja [SECOND_LIFE] została opublikowana.
+ Uaktualniona wersja [APP_NAME] została opublikowana.
[MESSAGE]
Aktualizacja nie jest wymagana ale jest zalecana w celu poprawy prędkości i stabilności.
@@ -1259,7 +1262,7 @@ Załadować do foldera Aplikacji?
<usetemplate name="okcancelbuttons" notext="Kontynuuj" yestext="Załaduj"/>
</notification>
<notification name="DownloadMacReleaseForDownload">
- Uaktualniona wersja [SECOND_LIFE] została opublikowana.
+ Uaktualniona wersja [APP_NAME] została opublikowana.
[MESSAGE]
Aktualizacja nie jest wymagana ale jest zalecana w celu poprawy prędkości i stabilności.
@@ -1494,7 +1497,7 @@ Kontynuować?
<notification name="RegionEntryAccessBlocked">
Ze względu na Twój wiek, nie jesteś uprawniony do przebywania w tym regionie. Może być to wynikiem braku informacji na temat weryfikacji Twojego wieku.
-Upewnij się, że masz zainstalowaną najnowszą wersję klienta i skorzystaj z Second Life:Pomoc by uzyskać więcej informacji na temat dostępu do regionów z podanym rodzajem treści jaką zawiera.
+Upewnij się, że masz zainstalowaną najnowszą wersję klienta i skorzystaj z [SECOND_LIFE]:Pomoc by uzyskać więcej informacji na temat dostępu do regionów z podanym rodzajem treści jaką zawiera.
<usetemplate
name="okbutton"
yestext="OK"/>
@@ -1502,13 +1505,13 @@ Upewnij się, że masz zainstalowaną najnowszą wersję klienta i skorzystaj z
<notification name="RegionEntryAccessBlocked_KB">
Ze względu na Twój wiek, nie jesteś uprawniony do przebywania w tym regionie.
-Skorzystaj z Second Life:Pomoc by uzyskać więcej informacji na temat dostępu do regionów z podanym rodzajem treści jaką zawiera.
+Skorzystaj z [SECOND_LIFE]:Pomoc by uzyskać więcej informacji na temat dostępu do regionów z podanym rodzajem treści jaką zawiera.
<url name="url">
https://support.secondlife.com/ics/support/default.asp?deptID=4417&amp;task=knowledge&amp;questionID=6010
</url>
<usetemplate
name="okcancelignore"
- yestext="Second Life:Pomoc"
+ yestext="[SECOND_LIFE]:Pomoc"
notext="Zamknij"
ignoretext="Dostęp do posiadłości jest zablokowany ze względu na rodzaj treści jaką zawiera"/>
</notification>
@@ -1533,7 +1536,7 @@ Możeszy wybrać &apos;Zmień Ustawienia&apos; by dokonać zmian w ustawieniach
<notification name="LandClaimAccessBlocked">
W związku ze statusem ustawień Twojego wieku, nie możesz odzyskać tej posiadłości. Możesz potrzebować weryfikacji wieku bądź instalacji najnowszej wersji klienta.
-Upewnij się, że masz zainstalowaną najnowszą wersję klienta i skorzystaj z Second Life:Pomoc by uzyskać więcej informacji na temat dostępu do regionów z podanym rodzajem treści jaką zawiera.
+Upewnij się, że masz zainstalowaną najnowszą wersję klienta i skorzystaj z [SECOND_LIFE]:Pomoc by uzyskać więcej informacji na temat dostępu do regionów z podanym rodzajem treści jaką zawiera.
<usetemplate
name="okbutton"
yestext="OK"/>
@@ -1541,13 +1544,13 @@ Upewnij się, że masz zainstalowaną najnowszą wersję klienta i skorzystaj z
<notification name="LandClaimAccessBlocked_KB">
Ze względu na Twój wiek, nie możesz odzyskać tej posiadłości.
-Skorzystaj z Second Life:Pomoc by uzyskać więcej informacji na temat dostępu do regionów z podanym rodzajem treści jaką zawiera.
+Skorzystaj z [SECOND_LIFE]:Pomoc by uzyskać więcej informacji na temat dostępu do regionów z podanym rodzajem treści jaką zawiera.
<url name="url">
https://support.secondlife.com/ics/support/default.asp?deptID=4417&amp;task=knowledge&amp;questionID=6010
</url>
<usetemplate
name="okcancelignore"
- yestext="Second Life:Pomoc"
+ yestext="[SECOND_LIFE]:Pomoc"
notext="Zamknij"
ignoretext="Odzyskanie posiadłości jest zablokowane ze względu na rodzaj treści jaką zwiera"/>
</notification>
@@ -1567,7 +1570,7 @@ Możeszy wybrać &apos;Zmień Ustawienia&apos; by dokonać zmian w ustawieniach
<notification name="LandBuyAccessBlocked">
Ze względu na Twój wiek, nie możesz kupić tej posiadłości. Może być to wynikiem braku informacji na temat weryfikacji Twojego wieku.
-Upewnij się, że masz zainstalowaną najnowszą wersję klienta i skorzystaj z Second Life:Pomoc by uzyskać więcej informacji na temat dostępu do regionów z podanym rodzajem treści jaką zawiera.
+Upewnij się, że masz zainstalowaną najnowszą wersję klienta i skorzystaj z [SECOND_LIFE]:Pomoc by uzyskać więcej informacji na temat dostępu do regionów z podanym rodzajem treści jaką zawiera.
<usetemplate
name="okbutton"
yestext="OK"/>
@@ -1575,13 +1578,13 @@ Upewnij się, że masz zainstalowaną najnowszą wersję klienta i skorzystaj z
<notification name="LandBuyAccessBlocked_KB">
Ze względu na Twój wiek, nie możesz kupić tej posiadłości.
-Skorzystaj z Second Life:Pomoc by uzyskać więcej informacji na temat dostępu do regionów z podanym rodzajem treści jaką zawiera.
+Skorzystaj z [SECOND_LIFE]:Pomoc by uzyskać więcej informacji na temat dostępu do regionów z podanym rodzajem treści jaką zawiera.
<url name="url">
https://support.secondlife.com/ics/support/default.asp?deptID=4417&amp;task=knowledge&amp;questionID=6010
</url>
<usetemplate
name="okcancelignore"
- yestext="Second Life:Pomoc"
+ yestext="[SECOND_LIFE]:Pomoc"
notext="Zamknij"
ignoretext="Zakup posiadłości jest zablokowany ze względu na rodzaj treści jaką zawiera"/>
</notification>
@@ -1841,7 +1844,7 @@ Domyślnie: nie włączona
Domyślnie: nie włączone
</notification>
<notification label="Wersja Niezgodna z Systemem Rozmów" name="VoiceVersionMismatch">
- Ta wersja Second Life nie jest kompatybilna z systemem Rozmów w tym regionie. Musisz zainstalować aktualną wersję Second Life żeby Rozmowy działały porawnie.
+ Ta wersja [APP_NAME] nie jest kompatybilna z systemem Rozmów w tym regionie. Musisz zainstalować aktualną wersję [APP_NAME] żeby Rozmowy działały porawnie.
</notification>
<notification label="Umowa MajÄ…tku" name="HelpEstateCovenant">
Włączenie opcji umowy majątku jest wymagane w celu umożliwienia sprzedaży posiadłości w obrębie majątku.
@@ -1955,16 +1958,16 @@ Przenieść obiekty szafy?
W tym obiekcie nie ma elementów które możesz skopiować.
</notification>
<notification name="WebLaunchAccountHistory">
- Przejść na stronę Second Life żeby zobaczyć historię konta?
+ Przejść na stronę [SECOND_LIFE] żeby zobaczyć historię konta?
<usetemplate ignoretext="ÅadujÄ…c stronÄ™ historii konta." name="okcancelignore" notext="Anuluj" yestext="Idź na stronÄ™"/>
</notification>
<notification name="ClickOpenF1Help">
- Przejść na stronę Second Life?
- <usetemplate ignoretext="Odwiedzając stronę Second Life." name="okcancelignore" notext="Anuluj" yestext="Idź"/>
+ Przejść na stronę [SECOND_LIFE]?
+ <usetemplate ignoretext="Odwiedzając stronę [SECOND_LIFE]." name="okcancelignore" notext="Anuluj" yestext="Idź"/>
</notification>
<notification name="ConfirmQuit">
Na pewno chcesz skończyć?
- <usetemplate ignoretext="Wyłączając Second Life." name="okcancelignore" notext="Kontynuuj" yestext="Wyłącz"/>
+ <usetemplate ignoretext="Wyłączając [APP_NAME]." name="okcancelignore" notext="Kontynuuj" yestext="Wyłącz"/>
</notification>
<notification name="HelpReportAbuseEmailLL">
Używaj tej opcji do zgłaszania nadużyć Warunków Umowy (Terms of Service) i Standardów Społeczeństwa (Community Standards). Zobacz:
@@ -1983,7 +1986,7 @@ W ramach serwisu dla Rezydentów i gości właściciel tego regionu postanowił
Właściciel regionu będzie rozpatrywał raporty w oparciu o lokalne prawa tego regionu zdefiniowane w umowie majątku. (Możesz zobaczyć umowę wybierając opcję O Posiadłości z menu Świat.)
-Rozwiązanie tego raportu odnosi się wyłącznie do tego regionu; konkluzja tego raportu nie będzie miała wpływu na dostęp Rezydentów do innych regionów w Second Life. Wyłącznie Linden Lab może całkowicie odebrać dostęp do Second Life.
+Rozwiązanie tego raportu odnosi się wyłącznie do tego regionu; konkluzja tego raportu nie będzie miała wpływu na dostęp Rezydentów do innych regionów w [SECOND_LIFE]. Wyłącznie Linden Lab może całkowicie odebrać dostęp do [SECOND_LIFE].
</notification>
<notification name="HelpReportBug">
Używaj tej opcji *wyłącznie* w celu zgłaszania technicznych problemów, dołączając szczegółowy opis problemu. Możesz odpowiedzieć na automatyczną email z odpowiedzią żeby dodać więcej szczegółów do Twojego raportu.
@@ -2034,9 +2037,9 @@ Dokładne dane pomogą nam w klasyfikacji i prztwarzaniu raportu.
Jeżeli składasz raport dotyczący naruszenia praw autorskich proszę się upewnić, że robisz to poprawnie:
-(1) Przypadek Nadużycia. Możesz złożyć raport jeżeli sądzisz, że Rezydent narusza system przywilejów Second Life, na przykład używając CopyBot lub podobnych narzędzi robiących kopie, naruszając prawa autorskie. Komisja Nadużyć bada wykrocznia i stosuje akcje dyscyplinarne za zachowania sprzeczne z zasadami Warunków Umowy (Terms of Service) i Standardów Społeczeństwa (Community Standards) Second Life. Komisja Nadużyć nie zajmuje się i nie odpowiada na żądania usunięcia treści ze środowiska Second Life.
+(1) Przypadek Nadużycia. Możesz złożyć raport jeżeli sądzisz, że Rezydent narusza system przywilejów [SECOND_LIFE], na przykład używając CopyBot lub podobnych narzędzi robiących kopie, naruszając prawa autorskie. Komisja Nadużyć bada wykrocznia i stosuje akcje dyscyplinarne za zachowania sprzeczne z zasadami Warunków Umowy (Terms of Service) i Standardów Społeczeństwa (Community Standards) [SECOND_LIFE]. Komisja Nadużyć nie zajmuje się i nie odpowiada na żądania usunięcia treści ze środowiska [SECOND_LIFE].
-(2) Przypadek DMCA lub Usuwanie Treści. Aby wystąpić z żądaniem o usunięcie treści ze środowiska Second Life MUSISZ przedłożyć ważne zawiadomienie o nadużyciu zgodne z naszą polisą DMCA pod http://secondlife.com/corporate/dmca.php.
+(2) Przypadek DMCA lub Usuwanie Treści. Aby wystąpić z żądaniem o usunięcie treści ze środowiska [SECOND_LIFE] MUSISZ przedłożyć ważne zawiadomienie o nadużyciu zgodne z naszą polisą DMCA pod http://secondlife.com/corporate/dmca.php.
Jeżeli chcesz kontynuować dalej zamknij to okno i dokończ wysyłanie raportu. Może być potrzebny wybór kategorii &apos;CopyBot albo Nadużycie Przywilejów&apos;.
@@ -2088,12 +2091,12 @@ Chcesz wyłączyć Tryb Pracy przed zakończeniem tej tranzakcji?
<usetemplate ignoretext="UsuwajÄ…c szafÄ™ z Twojego foldera Zgubione i Znalezione" name="okcancelignore" notext="Nie" yestext="Tak"/>
</notification>
<notification name="CopySLURL">
- Następujący link SLURL został skopiowany do pamięci podręcznej:
+ Następujący link SLurl został skopiowany do pamięci podręcznej:
[SLURL]
Zamieść go na stronie Internetowej żeby umożliwić innym łatwy dostęp do tego miejsca, albo wklej go do panela adresu Twojej przeglądarki żeby go wypróbować.
<form name="form">
- <ignore name="ignore" text="Kopiując SLURL do pamięci podręcznej"/>
+ <ignore name="ignore" text="Kopiując SLurl do pamięci podręcznej"/>
</form>
</notification>
<notification name="GraphicsPreferencesHelp">
@@ -2159,7 +2162,7 @@ Kliknij &quot;Zaawansowane Niebo&quot; żeby wybrać bardziej szczegółowy edyt
Kliknij &quot;Zaawansowana Woda&quot; żeby wybrać bardziej szczegółowy edytor ustawień wody.
</notification>
<notification name="HelpDayCycle">
- Edytor Cyklu Dnia pozwala na kontrolę nieba podczas cyklu dnia/nocy w Second Life. Ten cykl jest używany przez suwak Pora Dnia w podstawowym Edytorze Środowiska.
+ Edytor Cyklu Dnia pozwala na kontrolę nieba podczas cyklu dnia/nocy w [SECOND_LIFE]. Ten cykl jest używany przez suwak Pora Dnia w podstawowym Edytorze Środowiska.
Edytor Cyklu Dnia ustala klatki odniesienia. Są to punkty (widoczne jako szare plamki na wykresie czasu) które mają przypisane Ustawienia Nieba. W miarę upływu czasu niebo jest animowane używając średnich pomiędzy klatkami odniesienia.
@@ -2240,7 +2243,7 @@ Suwak G (Gęstość) kontroluje gęstość chmur.
Kontroluje prędkość przemieszczania chmur wzdłuż osi Y.
</notification>
<notification name="HelpClassicClouds">
- Wybierz tą opcję w celu używania dodatkowo starszej, klasycznej wersji chmur Second Life.
+ Wybierz tą opcję w celu używania dodatkowo starszej, klasycznej wersji chmur [SECOND_LIFE].
</notification>
<notification name="HelpWaterFogColor">
Kontroluje kolor podwodnej mgły.
@@ -2339,7 +2342,7 @@ Suwak G (Gęstość) kontroluje gęstość chmur.
</notification>
<notification name="NotAgeVerified">
Nie masz dostępu do tej posiadłości ze względu na brak weryfikacji Twojego wieku.
-Czy chcesz odwiedzić stronę Second Life żeby to zmienić?
+Czy chcesz odwiedzić stronę [SECOND_LIFE] żeby to zmienić?
[_URL]
<url name="url" option="0">
@@ -2349,7 +2352,7 @@ Czy chcesz odwiedzić stronę Second Life żeby to zmienić?
</notification>
<notification name="Cannot enter parcel: no payment info on file">
Nie masz dostępu do tej posiadłości ze względu na brak danych o Twoim koncie.
-Czy chcesz odwiedzić stronę Second Life żeby to zmienić?
+Czy chcesz odwiedzić stronę [SECOND_LIFE] żeby to zmienić?
[_URL]
<url name="url" option="0">
@@ -2379,10 +2382,10 @@ Czy chcesz odwiedzić stronę Second Life żeby to zmienić?
Temat: [SUBJECT], Treść: [MESSAGE]
</notification>
<notification name="FriendOnline">
- [FIRST] [LAST] jest w Second Life
+ [FIRST] [LAST] jest w [SECOND_LIFE]
</notification>
<notification name="FriendOffline">
- [FIRST] [LAST] opuszcza Second Life
+ [FIRST] [LAST] opuszcza [SECOND_LIFE]
</notification>
<notification name="AddSelfFriend">
Nie możesz dodać siebie do listy znajomych.
@@ -2602,7 +2605,7 @@ Nie możesz tworzyć tutaj obiektów.
<notification name="RegionTPAccessBlocked">
Ze względu na Twój wiek, nie jesteś uprawniony do przebywania w tym regionie. Możesz potrzebować weryfikacji wieku bądź instalacji najnowszej wersji klienta.
-Skorzystaj z Second Life:Pomoc by uzyskać więcej informacji na temat dostępu do regionów z podanym rodzajem treści jaką zawiera.
+Skorzystaj z [SECOND_LIFE]:Pomoc by uzyskać więcej informacji na temat dostępu do regionów z podanym rodzajem treści jaką zawiera.
</notification>
<notification name="URBannedFromRegion">
Zostałeś zbanowany w regionie.
@@ -2718,7 +2721,7 @@ Spróbuj ponowanie za kilka minut.
</form>
</notification>
<notification name="TeleportOffered">
- [NAME] proponuje Ci teleportcjÄ™ do siebie:
+ [NAME] proponuje Ci teleportacjÄ™ do siebie:
[MESSAGE]
<form name="form">
@@ -2794,7 +2797,7 @@ Obiekt: [OBJECTNAME], właściciel: [NAME]?
[TYPE] [DESC] - nie znaleziono w bazie danych.
</notification>
<notification name="InvalidWearable">
- Obiekt, który chcesz założyć używa narzędzia nieobecnego w wersji klienta, którą używasz. By go założyć ściągnij najnowszą wersję klienta Second Life.
+ Obiekt, który chcesz założyć używa narzędzia nieobecnego w wersji klienta, którą używasz. By go założyć ściągnij najnowszą wersję klienta [APP_NAME].
</notification>
<notification name="ScriptQuestion">
&apos;[OBJECTNAME]&apos;, właściciel: &apos;[NAME]&apos;, chciał by:
@@ -2899,8 +2902,8 @@ Obiekty elastyczne nie mogą być fizyczne i muszą być typu fantom.
</notification>
<notification name="FirstDebugMenus">
Zaawansowane menu zostało włączone.
-To menu zawiera funkcje użyteczne dla programistów analizujących Secon Life.
-To menu jest włączne przez Ctrl-Alt-D pod Windows. Mac używa Cmd-Opt-Shift-D.
+To menu zawiera funkcje użyteczne dla programistów analizujących [SECOND_LIFE].
+To menu jest aktywowane dzięki kombinacji klawiszy Ctrl-Alt-D (Windows) lub &#8984;-Opt-D (Mac).
</notification>
<notification name="FirstSculptedPrim">
Edytujesz sculpt.
@@ -3012,7 +3015,7 @@ Wybierz Wycisz żeby wyciszyć tą osobę.
- Prędkość Twojego CPU nie spełnia minimalnych wymagań.
</global>
<global name="UnsupportedGLRequirements">
- Wygląda na to, że Twój system nie spełnia wymagań sprzętowych Second Life. Second Life wymaga karty graficznej kompatybilnej z OpenGL z multiteksturami. Jeżeli masz taką kartę zainstaluj najnowsze sterowniki do niej i uaktualnienia systemu operacyjnego.
+ Wygląda na to, że Twój system nie spełnia wymagań sprzętowych [APP_NAME]. [APP_NAME] wymaga karty graficznej kompatybilnej z OpenGL z multiteksturami. Jeżeli masz taką kartę zainstaluj najnowsze sterowniki do niej i uaktualnienia systemu operacyjnego.
Jeżeli wciąż masz problemy sprawdź: http://www.secondlife.com/support
</global>
diff --git a/indra/newview/skins/default/xui/pl/panel_login.xml b/indra/newview/skins/default/xui/pl/panel_login.xml
index 08a768d44f..63659cf429 100755
--- a/indra/newview/skins/default/xui/pl/panel_login.xml
+++ b/indra/newview/skins/default/xui/pl/panel_login.xml
@@ -18,16 +18,10 @@
<text name="start_location_text">
Miejsce Startu:
</text>
- <combo_box name="start_location_combo">
- <combo_item name="MyHome">
- Mój Start
- </combo_item>
- <combo_item name="MyLastLocation">
- Ostatnie Miejsce
- </combo_item>
- <combo_item name="Typeregionname">
- &lt;Wpisz Region&gt;
- </combo_item>
+ <combo_box name="start_location_combo">
+ <combo_box.item name="MyHome" label="Mój Start" />
+ <combo_box.item name="MyLastLocation" label="Ostatnie Miejsce" />
+ <combo_box.item name="Typeregionname" label="lt;Wpisz Region&gt;" />
</combo_box>
<check_box label="Zapamiętaj Hasło" name="remember_check" />
<button label="Połącz" label_selected="Połącz" name="connect_btn" />
diff --git a/indra/newview/skins/default/xui/pl/panel_preferences_chat.xml b/indra/newview/skins/default/xui/pl/panel_preferences_chat.xml
index 5e397c2b06..67252f6fd2 100755
--- a/indra/newview/skins/default/xui/pl/panel_preferences_chat.xml
+++ b/indra/newview/skins/default/xui/pl/panel_preferences_chat.xml
@@ -4,15 +4,9 @@
Rozmiar Czcionki Czatu:
</text>
<radio_group name="chat_font_size">
- <radio_item type="string" length="1" name="radio">
- Mała
- </radio_item>
- <radio_item type="string" length="1" name="radio2">
- Åšrednia
- </radio_item>
- <radio_item type="string" length="1" name="radio3">
- Duża
- </radio_item>
+ <radio_item type="string" length="1" name="radio" label="Mała" />
+ <radio_item type="string" length="1" name="radio2" label="Åšrednia" />
+ <radio_item type="string" length="1" name="radio3" label="Duża" />
</radio_group>
<text type="string" length="1" name="text_box2">
Kolor Czatu:
diff --git a/indra/newview/skins/default/xui/pl/panel_preferences_graphics1.xml b/indra/newview/skins/default/xui/pl/panel_preferences_graphics1.xml
index 302501ef33..d59e6dbaf0 100755
--- a/indra/newview/skins/default/xui/pl/panel_preferences_graphics1.xml
+++ b/indra/newview/skins/default/xui/pl/panel_preferences_graphics1.xml
@@ -9,21 +9,11 @@
Wymiary Okna:
</text>
<combo_box name="windowsize combo">
- <combo_item type="string" length="1" name="640x480">
- 640x480
- </combo_item>
- <combo_item type="string" length="1" name="800x600">
- 800x600
- </combo_item>
- <combo_item type="string" length="1" name="720x480">
- 720x480 (NTSC)
- </combo_item>
- <combo_item type="string" length="1" name="768x576">
- 768x576 (PAL)
- </combo_item>
- <combo_item type="string" length="1" name="1024x768">
- 1024x768
- </combo_item>
+ <combo_box.item type="string" length="1" name="640x480" label="640x480" />
+ <combo_box.item type="string" length="1" name="800x600" label="800x600" />
+ <combo_box.item type="string" length="1" name="720x480" label="720x480 (NTSC)" />
+ <combo_box.item type="string" length="1" name="768x576" label="768x576 (PAL)" />
+ <combo_box.item type="string" length="1" name="1024x768" label="1024x768" />
</combo_box>
<text type="string" length="1" name="DisplayResLabel">
Rozdzielczość:
@@ -32,18 +22,10 @@
Proporcje:
</text>
<combo_box name="aspect_ratio" tool_tip="width / height">
- <combo_item type="string" length="1" name="4:3(StandardCRT)">
- 4:3 (Standardowy CRT)
- </combo_item>
- <combo_item type="string" length="1" name="5:4(1280x1024LCD)">
- 5:4 (1280x1024 LCD)
- </combo_item>
- <combo_item type="string" length="1" name="8:5(Widescreen)">
- 8:5 (Panoramiczny)
- </combo_item>
- <combo_item type="string" length="1" name="16:9(Widescreen)">
- 16:9 (Panoramiczny)
- </combo_item>
+ <combo_box.item type="string" length="1" name="4:3(StandardCRT)" label="4:3 (Standardowy CRT)" />
+ <combo_box.item type="string" length="1" name="5:4(1280x1024LCD)" label="5:4 (1280x1024 LCD)" />
+ <combo_box.item type="string" length="1" name="8:5(Widescreen)" label="8:5 (Panoramiczny)" />
+ <combo_box.item type="string" length="1" name="16:9(Widescreen)" label="16:9 (Panoramiczny)" />
</combo_box>
<check_box label="Detekcja proporcji" name="aspect_auto_detect" />
<text type="string" length="1" name="HigherText">
@@ -87,18 +69,10 @@
Ustawienia Odbić:
</text>
<radio_group name="ReflectionDetailRadio">
- <radio_item type="string" length="1" name="0">
- Teren i Drzewa
- </radio_item>
- <radio_item type="string" length="1" name="1">
- Obiekty Statyczne
- </radio_item>
- <radio_item type="string" length="1" name="2">
- Awatary i Obiekty
- </radio_item>
- <radio_item type="string" length="1" name="3">
- Wszystko
- </radio_item>
+ <radio_item type="string" length="1" name="0" label="Teren i Drzewa" />
+ <radio_item type="string" length="1" name="1" label="Obiekty Statyczne" />
+ <radio_item type="string" length="1" name="2" label="Awatary i Obiekty" />
+ <radio_item type="string" length="1" name="3" label="Wszystko" />
</radio_group>
<text type="string" length="1" name="AvatarRenderingText">
Prezentacja Awatarów:
@@ -149,23 +123,15 @@
Ustawienia Światła:
</text>
<radio_group name="LightingDetailRadio">
- <radio_item type="string" length="1" name="SunMoon">
- Tylko Słońce i Księżyc
- </radio_item>
- <radio_item type="string" length="1" name="LocalLights">
- Tylko Bliskie Światła
- </radio_item>
+ <radio_item type="string" length="1" name="SunMoon" label="Tylko Słońce i Księżyc" />
+ <radio_item type="string" length="1" name="LocalLights" label="Tylko Bliskie Światła" />
</radio_group>
<text type="string" length="1" name="TerrainDetailText">
Szczgóły Terenu:
</text>
<radio_group name="TerrainDetailRadio">
- <radio_item type="string" length="1" name="0">
- Mało
- </radio_item>
- <radio_item type="string" length="1" name="2">
- Dużo
- </radio_item>
+ <radio_item type="string" length="1" name="0" label="Mało" />
+ <radio_item type="string" length="1" name="2" label="Dużo" />
</radio_group>
<button label="Ustawienia Domyślne" name="Defaults" />
<button label="Ustawnia Sprzętowe" label_selected="Ustawienia Sprzętowe"
diff --git a/indra/newview/skins/default/xui/pl/panel_status_bar.xml b/indra/newview/skins/default/xui/pl/panel_status_bar.xml
index bdf22fa66d..fcaac7f116 100755
--- a/indra/newview/skins/default/xui/pl/panel_status_bar.xml
+++ b/indra/newview/skins/default/xui/pl/panel_status_bar.xml
@@ -28,8 +28,8 @@
<button label="" label_selected="" name="status_no_voice" tool_tip="Używanie komunikacji głosowej jest niedozwolone" />
<button label="" label_selected="" name="buyland" tool_tip="Kup tą posiadłość" />
<button label="" name="menubar_search_bevel_bg" />
- <line_editor label="Szukaj" name="search_editor" tool_tip="Szukaj w Second Life" />
- <button label="" label_selected="" name="search_btn" tool_tip="Szukaj w Second Life" />
+ <line_editor label="Szukaj" name="search_editor" tool_tip="Szukaj w [SECOND_LIFE]" />
+ <button label="" label_selected="" name="search_btn" tool_tip="Szukaj w [SECOND_LIFE]" />
<string name="packet_loss_tooltip">
Utracone Pakiety
</string>
diff --git a/indra/newview/skins/default/xui/pl/strings.xml b/indra/newview/skins/default/xui/pl/strings.xml
index 5067f044e0..3ec2b45237 100755
--- a/indra/newview/skins/default/xui/pl/strings.xml
+++ b/indra/newview/skins/default/xui/pl/strings.xml
@@ -55,6 +55,9 @@
<string name="LoginDownloadingClothing">
Åadowanie ubrania...
</string>
+ <string name="Quit">
+ Wyjdź
+ </string>
<string name="AgentLostConnection">
Ten region może mieć problemy. Sprawdź podłączenie do Internetu.
</string>
diff --git a/indra/newview/skins/default/xui/pt/floater_about.xml b/indra/newview/skins/default/xui/pt/floater_about.xml
index 0cab45175b..c8c0442d1d 100644
--- a/indra/newview/skins/default/xui/pt/floater_about.xml
+++ b/indra/newview/skins/default/xui/pt/floater_about.xml
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<floater name="floater_about" title="Sobre o Second Life">
+<floater name="floater_about" title="Sobre o [APP_NAME]">
<text_editor name="credits_editor">
Second Life é oferecido a você por Philip, Tessa, Andrew, Cory, James, Ben, Char, Charlie, Colin, Dan, Daniel, Doug, Eric, Hamlet, Haney, Eve, Hunter, Ian, Jeff, Jennifer, Jim, John, Lee, Mark, Peter, Phoenix, Richard, Robin, Xenon, Steve, Tanya, Eddie, Avi, Frank, Bruce, Aaron, Alice, Bob, Debra, Eileen, Helen, Janet, Louie, Leviathania, Stefan, Ray, Kevin, Tom, Mikeb, MikeT, Burgess, Elena, Tracy, Bill, Todd, Ryan, Zach, Sarah, Nova, Tim, Stephanie, Michael, Evan, Nicolas, Catherine, Rachelle, Dave, Holly, Bub, Kelly, Magellan, Ramzi, Don, Sabin, Jill, Rheya, Jeska, Torley, Kona, Callum, Charity, Ventrella, Jack, Vektor, Iris, Chris, Nicole, Mick, Reuben, Blue, Babbage, Yedwab, Deana, Lauren, Brent, Pathfinder, Chadrick, Altruima, Jesse, Teeny, Monroe, Icculus, David, Tess, Lizzie, Patsy, Isaac, Lawrence, Cyn, Bo, Gia, Annette, Marius, Tbone, Jonathan, Karen, Ginsu, Satoko, Yuko, Makiko, Thomas, Harry, Seth, Alexei, Brian, Guy, Runitai, Ethan, Data, Cornelius, Kenny, Swiss, Zero, Natria, Wendy, Stephen, Teeple, Thumper, Lucy, Dee, Mia, Liana, Warren, Branka, Aura, beez, Milo, Hermia, Red, Thrax, Joe, Sally, Magenta, Mogura, Paul, Jose, Rejean, Henrik, Lexie, Amber, Logan, Xan, Nora, Morpheus, Donovan, Leyla, MichaelFrancis, Beast, Cube, Bucky, Joshua, Stryfe, Harmony, Teresa, Claudia, Walker, Glenn, Fritz, Fordak, June, Cleopetra, Jean, Ivy, Betsy, Roosevelt, Spike, Ken, Which, Tofu, Chiyo, Rob, Zee, dustin, George, Del, Matthew, Cat, Jacqui, Lightfoot, Adrian, Viola, Alfred, Noel, Irfan, Sunil, Yool, Rika, Jane, Xtreme, Frontier, a2, Neo, Siobhan, Yoz, Justin, Elle, Qarl, Benjamin, Isabel, Gulliver, Everett, Christopher, Izzy, Stephany, Garry, Sejong, Sean, Tobin, Iridium, Meta, Anthony, Jeremy, JP, Jake, Maurice, Madhavi, Leopard, Kyle, Joon, Kari, Bert, Belinda, Jon, Kristi, Bridie, Pramod, KJ, Socrates, Maria, Ivan, Aric, Yamasaki, Adreanne, Jay, MitchK, Ceren, Coco, Durl, Jenny, Periapse, Kartic, Storrs, Lotte, Sandy, Rohn, Colossus, Zen, BigPapi, Brad, Pastrami, Kurz, Mani, Neuro, Jaime, MJ, Rowan, Sgt, Elvis, Gecko, Samuel, Sardonyx, Leo, Bryan, Niko, Soft, Poppy, Rachel, Aki, Angelo, Banzai, Alexa, Sue, CeeLo, Bender, CG, Gillian, Pelle, Nick, Echo, Zara, Christine, Shamiran, Emma, Blake, Keiko, Plexus, Joppa, Sidewinder, Erica, Ashlei, Twilight, Kristen, Brett, Q, Enus, Simon, Bevis, Kraft, Kip, Chandler, Ron, LauraP, Ram, KyleJM, Scouse, Prospero, Melissa, Marty, Nat, Hamilton, Kend, Lordan, Jimmy, Kosmo, Seraph, Green, Ekim, Wiggo, JT, Rome, Doris, Miz, Benoc, Whump, Trinity, Patch, Kate, TJ, Bao, Joohwan, Christy, Sofia, Matias, Cogsworth, Johan, Oreh, Cheah, Angela, Brandy, Mango, Lan, Aleks, Gloria, Heidy, Mitchell, Space, Colton, Bambers, Einstein, Maggie, Malbers, Rose, Winnie, Stella, Milton, Rothman, Niall, Marin, Allison, Katie, Dawn, Katt, Dusty, Kalpana, Judy, Andrea, Ambroff, Infinity, Gail, Rico, Raymond, Yi, William, Christa, M, Teagan, Scout, Molly, Dante, Corr, Dynamike, Usi, Kaylee, Vidtuts, Lil, Danica, Sascha, Kelv, Jacob, Nya, Rodney, Brandon, Elsie, Blondin, Grant, Katrin, Nyx, Gabriel, Locklainn, Claire, Devin, Minerva, Monty, Austin, Bradford, Si, Keira, H, Caitlin, Dita, Makai, Jenn, Ann, Meredith, Clare, Joy, Praveen, Cody, Edmund, Ruthe, Sirena, Gayathri, Spider, FJ, Davidoff, Tian, Jennie, Louise, Oskar, Landon, Noelle, Jarv, Ingrid, Al, Sommer, Doc, Aria, Huin, Gray, Lili, Vir, DJ, Yang, T, Simone, Maestro, Scott, Charlene, Quixote, Amanda, Susan, Zed, Anne, Enkidu, Esbee, Joroan, Katelin, Roxie, Tay, Scarlet, Kevin, Johnny, Wolfgang, Andren, Bob, Howard, Merov, Rand, Ray, Michon, Newell, Galen, Dessie, Les, Michon, Jenelle, Geo, Siz, Shapiro, Pete, Calyle, Selene, Allen, Phoebe, Goldin, Kimmora, Dakota, Slaton, Lindquist, Zoey, Hari, Othello, Rohit, Sheldon, Petra, Viale, Gordon, Kaye, Pink, Ferny, Emerson, Davy, Bri, Chan, Juan, Robert, Terrence, Nathan, Carl e muitos outros.
diff --git a/indra/newview/skins/default/xui/pt/floater_animation_preview.xml b/indra/newview/skins/default/xui/pt/floater_animation_preview.xml
index 054a8855a9..f3297ea5ee 100644
--- a/indra/newview/skins/default/xui/pt/floater_animation_preview.xml
+++ b/indra/newview/skins/default/xui/pt/floater_animation_preview.xml
@@ -14,127 +14,53 @@
Pose de Mão
</text>
<combo_box left_delta="100" width="184" name="hand_pose_combo" tool_tip="Controla o que as mãos fazem durante a animação">
- <combo_item name="Spread">
- Espreguiçar
- </combo_item>
- <combo_item name="Relaxed">
- Relaxado
- </combo_item>
- <combo_item name="PointBoth">
- Apontar Ambos
- </combo_item>
- <combo_item name="Fist">
- Punho
- </combo_item>
- <combo_item name="RelaxedLeft">
- Relaxado para Esquerda
- </combo_item>
- <combo_item name="PointLeft">
- Apontar à Esquerda
- </combo_item>
- <combo_item name="FistLeft">
- Punho Esquerdo
- </combo_item>
- <combo_item name="RelaxedRight">
- Relaxado para Direita
- </combo_item>
- <combo_item name="PointRight">
- Apontar à Direita
- </combo_item>
- <combo_item name="FistRight">
- Punho Direito
- </combo_item>
- <combo_item name="SaluteRight">
- Saudar à Direita
- </combo_item>
- <combo_item name="Typing">
- Digitando
- </combo_item>
- <combo_item name="PeaceRight">
- Pacífico à Direita
- </combo_item>
+ <combo_box.item name="Spread" label="Espreguiçar" />
+ <combo_box.item name="Relaxed" label="Relaxado" />
+ <combo_box.item name="PointBoth" label="Apontar Ambos" />
+ <combo_box.item name="Fist" label="Punho" />
+ <combo_box.item name="RelaxedLeft" label="Relaxado para Esquerda" />
+ <combo_box.item name="PointLeft" label="Apontar à Esquerda" />
+ <combo_box.item name="FistLeft" label="Punho Esquerdo" />
+ <combo_box.item name="RelaxedRight" label="Relaxado para Direita" />
+ <combo_box.item name="PointRight" label="Apontar à Direita" />
+ <combo_box.item name="FistRight" label="Punho Direito" />
+ <combo_box.item name="SaluteRight" label="Saudar à Direita" />
+ <combo_box.item name="Typing" label="Digitando" />
+ <combo_box.item name="PeaceRight" label="Pacífico à Direita" />
</combo_box>
<text name="emote_label">
Expressão
</text>
<combo_box left_delta="100" width="184" name="emote_combo" tool_tip="Controla o que a face faz durante a animação.">
- <combo_item name="[None]">
- [None]
- </combo_item>
- <combo_item name="Aaaaah">
- Aaaaah
- </combo_item>
- <combo_item name="Afraid">
- Temeroso
- </combo_item>
- <combo_item name="Angry">
- Raivoso
- </combo_item>
- <combo_item name="BigSmile">
- Sorrisão
- </combo_item>
- <combo_item name="Bored">
- Entediado
- </combo_item>
- <combo_item name="Cry">
- Chorar
- </combo_item>
- <combo_item name="Disdain">
- Desprezar
- </combo_item>
- <combo_item name="Embarrassed">
- Envergonhado
- </combo_item>
- <combo_item name="Frown">
- Franzir a testa
- </combo_item>
- <combo_item name="Kiss">
- Beijar
- </combo_item>
- <combo_item name="Laugh">
- Rir
- </combo_item>
- <combo_item name="Plllppt">
- Plllppt
- </combo_item>
- <combo_item name="Repulsed">
- Enojado
- </combo_item>
- <combo_item name="Sad">
- Triste
- </combo_item>
- <combo_item name="Shrug">
- Indiferença
- </combo_item>
- <combo_item name="Smile">
- Sorriso
- </combo_item>
- <combo_item name="Surprise">
- Surpreso
- </combo_item>
- <combo_item name="Wink">
- Piscar
- </combo_item>
- <combo_item name="Worry">
- Preocupado
- </combo_item>
+ <combo_box.item name="[None]" label="None]" />
+ <combo_box.item name="Aaaaah" label="Aaaaah" />
+ <combo_box.item name="Afraid" label="Temeroso" />
+ <combo_box.item name="Angry" label="Raivoso" />
+ <combo_box.item name="BigSmile" label="Sorrisão" />
+ <combo_box.item name="Bored" label="Entediado" />
+ <combo_box.item name="Cry" label="Chorar" />
+ <combo_box.item name="Disdain" label="Desprezar" />
+ <combo_box.item name="Embarrassed" label="Envergonhado" />
+ <combo_box.item name="Frown" label="Franzir a testa" />
+ <combo_box.item name="Kiss" label="Beijar" />
+ <combo_box.item name="Laugh" label="Rir" />
+ <combo_box.item name="Plllppt" label="Plllppt" />
+ <combo_box.item name="Repulsed" label="Enojado" />
+ <combo_box.item name="Sad" label="Triste" />
+ <combo_box.item name="Shrug" label="Indiferença" />
+ <combo_box.item name="Smile" label="Sorriso" />
+ <combo_box.item name="Surprise" label="Surpreso" />
+ <combo_box.item name="Wink" label="Piscar" />
+ <combo_box.item name="Worry" label="Preocupado" />
</combo_box>
<text name="preview_label" width="250">
Prever enquanto
</text>
<combo_box left_delta="100" width="130" name="preview_base_anim" tool_tip="Use isto para testar o comportamento de sua animação enquanto seu avatar executa ações comuns.">
- <combo_item name="Standing">
- Parado
- </combo_item>
- <combo_item name="Walking">
- Andando
- </combo_item>
- <combo_item name="Sitting">
- Sentando
- </combo_item>
- <combo_item name="Flying">
- Voando
- </combo_item>
+ <combo_box.item name="Standing" label="Parado" />
+ <combo_box.item name="Walking" label="Andando" />
+ <combo_box.item name="Sitting" label="Sentando" />
+ <combo_box.item name="Flying" label="Voando" />
</combo_box>
<spinner label_width="125" width="192" label="Facilitar a entrada (sec)" name="ease_in_time" tool_tip="Quantidade de tempo (em segundos) para que as animações se mesclem."/>
<spinner bottom_delta="-20" label_width="125" left="10" width="192" label="Facilitar a saída (sec)" name="ease_out_time" tool_tip="Quantidade de tempo (em segundos) para que a animações se mesclem."/>
diff --git a/indra/newview/skins/default/xui/pt/floater_buy_land.xml b/indra/newview/skins/default/xui/pt/floater_buy_land.xml
index e3c5fcde0e..2caf057283 100644
--- a/indra/newview/skins/default/xui/pt/floater_buy_land.xml
+++ b/indra/newview/skins/default/xui/pt/floater_buy_land.xml
@@ -75,15 +75,9 @@ vendido com os objetos
Somente membros Premium podem possuir terra.
</text>
<combo_box name="account_level">
- <combo_item name="US$9.95/month,billedmonthly">
- US$9.95/mês, debitado mensalmente
- </combo_item>
- <combo_item name="US$7.50/month,billedquarterly">
- US$7.50/mês, debitado trimestralmente
- </combo_item>
- <combo_item name="US$6.00/month,billedannually">
- US$6.00/mês, debitado anualmente
- </combo_item>
+ <combo_box.item name="US$9.95/month,billedmonthly" label="US$9.95/mês, debitado mensalmente" />
+ <combo_box.item name="US$7.50/month,billedquarterly" label="US$7.50/mês, debitado trimestralmente" />
+ <combo_box.item name="US$6.00/month,billedannually" label="US$6.00/mês, debitado anualmente" />
</combo_box>
<text name="land_use_action">
Aumente sua taxa de locação de terra para US$ 40/mês.
diff --git a/indra/newview/skins/default/xui/pt/floater_customize.xml b/indra/newview/skins/default/xui/pt/floater_customize.xml
index 31f3f3d59c..7c4fa20f1b 100644
--- a/indra/newview/skins/default/xui/pt/floater_customize.xml
+++ b/indra/newview/skins/default/xui/pt/floater_customize.xml
@@ -14,12 +14,8 @@
<button label="Tórax" label_selected="Tórax" name="Torso"/>
<button label="Pernas" label_selected="Pernas" name="Legs"/>
<radio_group name="sex radio">
- <radio_item length="1" name="radio" type="string">
- Feminino
- </radio_item>
- <radio_item length="1" name="radio2" type="string">
- Masculino
- </radio_item>
+ <radio_item length="1" name="radio" type="string" label="Feminino" />
+ <radio_item length="1" name="radio2" type="string" label="Masculino" />
</radio_group>
<text length="1" name="title" type="string">
[DESC]
diff --git a/indra/newview/skins/default/xui/pt/floater_god_tools.xml b/indra/newview/skins/default/xui/pt/floater_god_tools.xml
index 86c6b087f8..6b88db1d9c 100644
--- a/indra/newview/skins/default/xui/pt/floater_god_tools.xml
+++ b/indra/newview/skins/default/xui/pt/floater_god_tools.xml
@@ -73,29 +73,17 @@
Destino:
</text>
<combo_box name="destination">
- <combo_item name="Selection">
- Seleção
- </combo_item>
- <combo_item name="AgentRegion">
- Região do Agente
- </combo_item>
+ <combo_box.item name="Selection" label="Seleção" />
+ <combo_box.item name="AgentRegion" label="Região do Agente" />
</combo_box>
<text name="Request:">
Requisição:
</text>
<combo_box name="request">
- <combo_item name="colliders&lt;steps&gt;">
- Passos de Colisão
- </combo_item>
- <combo_item name="scripts&lt;count&gt;,&lt;optionalpattern&gt;">
- Contagem de scripts, padrão opcional
- </combo_item>
- <combo_item name="objects&lt;pattern&gt;">
- Padrão de Objetos
- </combo_item>
- <combo_item name="rez&lt;asset_id&gt;">
- rez &lt;asset_id&gt;
- </combo_item>
+ <combo_box.item name="colliders&lt;steps&gt;" label="Passos de Colisão" />
+ <combo_box.item name="scripts&lt;count&gt;,&lt;optionalpattern&gt;" label="Contagem de scripts, padrão opcional" />
+ <combo_box.item name="objects&lt;pattern&gt;" label="Padrão de Objetos" />
+ <combo_box.item name="rez&lt;asset_id&gt;" label="rez &lt;asset_id&gt;" />
</combo_box>
<text name="Parameter:">
Parametro:
diff --git a/indra/newview/skins/default/xui/pt/floater_hardware_settings.xml b/indra/newview/skins/default/xui/pt/floater_hardware_settings.xml
index 10ed0339a3..0f9c1fd487 100644
--- a/indra/newview/skins/default/xui/pt/floater_hardware_settings.xml
+++ b/indra/newview/skins/default/xui/pt/floater_hardware_settings.xml
@@ -8,21 +8,11 @@
Suavização:
</text>
<combo_box label="Suavização" name="fsaa" width="94">
- <combo_item name="FSAADisabled">
- Desabilitado
- </combo_item>
- <combo_item name="2x">
- 2x
- </combo_item>
- <combo_item name="4x">
- 4x
- </combo_item>
- <combo_item name="8x">
- 8x
- </combo_item>
- <combo_item name="16x">
- 16x
- </combo_item>
+ <combo_box.item name="FSAADisabled" label="Desabilitado"/>
+ <combo_box.item name="2x" label="2x"/>
+ <combo_box.item name="4x" label="4x"/>
+ <combo_box.item name="8x" label="8x"/>
+ <combo_box.item name="16x" label="16x"/>
</combo_box>
<spinner label="Gama:" name="gamma"/>
<text name="(brightness, lower is brighter)">
diff --git a/indra/newview/skins/default/xui/pt/floater_image_preview.xml b/indra/newview/skins/default/xui/pt/floater_image_preview.xml
index c7a7976a41..a0d8c02ef0 100644
--- a/indra/newview/skins/default/xui/pt/floater_image_preview.xml
+++ b/indra/newview/skins/default/xui/pt/floater_image_preview.xml
@@ -11,36 +11,16 @@
imagem como:
</text>
<combo_box label="Tipo de Roupas" name="clothing_type_combo" left="100" width="186">
- <combo_item name="Image">
- Imagem
- </combo_item>
- <combo_item name="Hair">
- Cabelo
- </combo_item>
- <combo_item name="FemaleHead">
- Cabeça Feminina
- </combo_item>
- <combo_item name="FemaleUpperBody">
- Parte Superior do Corpo Feminino
- </combo_item>
- <combo_item name="FemaleLowerBody">
- Parte Inferior do Corpo Feminino
- </combo_item>
- <combo_item name="MaleHead">
- Cabeça Masculina
- </combo_item>
- <combo_item name="MaleUpperBody">
- Parte Superior do Corpo Masculino
- </combo_item>
- <combo_item name="MaleLowerBody">
- Parte Inferiro do Corpo Masculino
- </combo_item>
- <combo_item name="Skirt">
- Saia
- </combo_item>
- <combo_item name="SculptedPrim">
- Primitiva Esculpida
- </combo_item>
+ <combo_box.item name="Image" label="Imagem" />
+ <combo_box.item name="Hair" label="Cabelo" />
+ <combo_box.item name="FemaleHead" label="Cabeça Feminina" />
+ <combo_box.item name="FemaleUpperBody" label="Parte Superior do Corpo Feminino" />
+ <combo_box.item name="FemaleLowerBody" label="Parte Inferior do Corpo Feminino" />
+ <combo_box.item name="MaleHead" label="Cabeça Masculina" />
+ <combo_box.item name="MaleUpperBody" label="Parte Superior do Corpo Masculino" />
+ <combo_box.item name="MaleLowerBody" label="Parte Inferiro do Corpo Masculino" />
+ <combo_box.item name="Skirt" label="Saia" />
+ <combo_box.item name="SculptedPrim" label="Primitiva Esculpida" />
</combo_box>
<text name="bad_image_text">
Incapaz de ler a imagem.
diff --git a/indra/newview/skins/default/xui/pt/floater_inventory_item_properties.xml b/indra/newview/skins/default/xui/pt/floater_inventory_item_properties.xml
index 0b78453182..69752253b6 100644
--- a/indra/newview/skins/default/xui/pt/floater_inventory_item_properties.xml
+++ b/indra/newview/skins/default/xui/pt/floater_inventory_item_properties.xml
@@ -60,12 +60,8 @@
</text>
<check_box label="À venda" name="CheckPurchase"/>
<radio_group name="RadioSaleType">
- <radio_item name="radio">
- Original
- </radio_item>
- <radio_item name="radio2">
- Cópia
- </radio_item>
+ <radio_item name="radio" label="Original" />
+ <radio_item name="radio2" label="Cópia" />
</radio_group>
<text name="TextPrice">
Price: L$
diff --git a/indra/newview/skins/default/xui/pt/floater_postcard.xml b/indra/newview/skins/default/xui/pt/floater_postcard.xml
index 60d3d1829c..bd3d41e52f 100644
--- a/indra/newview/skins/default/xui/pt/floater_postcard.xml
+++ b/indra/newview/skins/default/xui/pt/floater_postcard.xml
@@ -24,12 +24,12 @@
Digite sua mensagem aqui.
</text_editor>
<text name="fine_print">
- Se seu indicado entrar no Second Life, você receberá um bônus pela indicação.
+ Se seu indicado entrar no [SECOND_LIFE], você receberá um bônus pela indicação.
</text>
<button label="Cancelar" name="cancel_btn"/>
<button label="Enviar" name="send_btn"/>
<string name="default_subject">
- Cartão postal do Second Life.
+ Cartão postal do [SECOND_LIFE]
</string>
<string name="default_message">
Dá uma olhada nisto!
diff --git a/indra/newview/skins/default/xui/pt/floater_preview_gesture.xml b/indra/newview/skins/default/xui/pt/floater_preview_gesture.xml
index bf7f3989f2..87bf86c282 100644
--- a/indra/newview/skins/default/xui/pt/floater_preview_gesture.xml
+++ b/indra/newview/skins/default/xui/pt/floater_preview_gesture.xml
@@ -47,12 +47,8 @@ simultaneamente, a menos que
você inclua passos de espera.
</text>
<radio_group name="animation_trigger_type">
- <radio_item name="start">
- Iniciar
- </radio_item>
- <radio_item name="stop">
- Parar
- </radio_item>
+ <radio_item name="start" label="Iniciar" />
+ <radio_item name="stop" label="Parar" />
</radio_group>
<check_box bottom_delta="34" label="até que as animações estejam &#10;concluídas" name="wait_anim_check"/>
<check_box bottom_delta="-30" label="tempo em segundos" name="wait_time_check"/>
diff --git a/indra/newview/skins/default/xui/pt/floater_report_abuse.xml b/indra/newview/skins/default/xui/pt/floater_report_abuse.xml
index 964b164cd1..79dcf76494 100644
--- a/indra/newview/skins/default/xui/pt/floater_report_abuse.xml
+++ b/indra/newview/skins/default/xui/pt/floater_report_abuse.xml
@@ -36,123 +36,51 @@
Hendrerit Vulputate
</text>
<combo_box name="category_combo" tool_tip="Categoria -- Selecione a categoria que melhor descreve este report">
- <combo_item name="Select_category">
- Selecionar categoria
- </combo_item>
- <combo_item name="Age__Age_play">
- Idade &gt; Idade no jogo
- </combo_item>
- <combo_item name="Age__Adult_resident_on_Teen_Second_Life">
- Idade &gt; Residente adulto no Second Life Jovem
- </combo_item>
+ <combo_box.item name="Select_category" label="Selecionar categoria"/>
+ <combo_box.item name="Age__Age_play" label="Idade &gt; Idade no jogo"/>
+ <combo_box.item name="Age__Adult_resident_on_Teen_Second_Life" label="Idade &gt; Residente adulto no Second Life Jovem"/>
<combo_item name="Age__Underage_resident_outside_of_Teen_Second_Life">
Idade &gt; Residente menor de idade fora do Second Life Teen
</combo_item>
- <combo_item name="Assault__Combat_sandbox___unsafe_area">
- Assalto &gt; Sandbox de combate / área não segura
- </combo_item>
- <combo_item name="Assault__Safe_area">
- Assalto &gt; Ãrea segura
- </combo_item>
- <combo_item name="Assault__Weapons_testing_sandbox">
- Assalto &gt; Testando armas em sandbox
- </combo_item>
- <combo_item name="Commerce__Failure_to_deliver_product_or_service">
- Comércio &gt; Falha em enviar produto ou serviço
- </combo_item>
- <combo_item name="Disclosure__Real_world_information">
- Revelar &gt; Informação do mundo real
- </combo_item>
- <combo_item name="Disclosure__Remotely_monitoring chat">
- Revelar &gt; Conversa monitorada remotamente
- </combo_item>
- <combo_item name="Disclosure__Second_Life_information_chat_IMs">
- Revelar &gt; Informação do Second Life/conversa/MIs
- </combo_item>
- <combo_item name="Disturbing_the_peace__Unfair_use_of_region_resources">
- Distúrbio da paz &gt; Uso injusto dos recursos da região
- </combo_item>
- <combo_item name="Disturbing_the_peace__Excessive_scripted_objects">
- Distúrbio da paz &gt; Objetos com excesso de scripts
- </combo_item>
- <combo_item name="Disturbing_the_peace__Object_littering">
- Distúrbio da paz &gt; Objeto despejando lixo
- </combo_item>
- <combo_item name="Disturbing_the_peace__Repetitive_spam">
- Distúrbio da paz &gt; Spam repetitivo
- </combo_item>
- <combo_item name="Disturbing_the_peace__Unwanted_advert_spam">
- Distúrbio da paz &gt; Spam de anúncio indesejado
- </combo_item>
- <combo_item name="Fraud__L$">
- Fraude &gt; L$
- </combo_item>
- <combo_item name="Fraud__Land">
- Fraude &gt; Terra
- </combo_item>
- <combo_item name="Fraud__Pyramid_scheme_or_chain_letter">
- Fraude &gt; Esquema de pirâmide ou cartas encadeadas
- </combo_item>
- <combo_item name="Fraud__US$">
- Fraude &gt; R$
- </combo_item>
- <combo_item name="Harassment__Advert_farms___visual_spam">
- Perturbação &gt; Fazendas de Anúncios / spam visual
- </combo_item>
- <combo_item name="Harassment__Defaming_individuals_or_groups">
- Perturbação &gt; Difamação de indivíduos ou grupos
- </combo_item>
- <combo_item name="Harassment__Impeding_movement">
- Perturbação &gt; Impedindo movimentos
- </combo_item>
- <combo_item name="Harassment__Sexual_harassment">
- Perturbação &gt; Perturbação sexual
- </combo_item>
- <combo_item name="Harassment__Solicting_inciting_others_to_violate_ToS">
- Perturbação &gt; Solicitando/incitando outros a violarem o ToS
- </combo_item>
- <combo_item name="Harassment__Verbal_abuse">
- Perturbação &gt; Abuso verbal
- </combo_item>
- <combo_item name="Indecency__Broadly_offensive_content_or_conduct">
- Indecência &gt; Conteúdo ou conduta amplamente ofensivos
- </combo_item>
- <combo_item name="Indecency__Inappropriate_avatar_name">
- Indecência &gt; Nome de avatar inapropriado
- </combo_item>
+ <combo_box.item name="Assault__Combat_sandbox___unsafe_area" label="Assalto &gt; Sandbox de combate / área não segura"/>
+ <combo_box.item name="Assault__Safe_area" label="Assalto &gt; Ãrea segura"/>
+ <combo_box.item name="Assault__Weapons_testing_sandbox" label="Assalto &gt; Testando armas em sandbox"/>
+ <combo_box.item name="Commerce__Failure_to_deliver_product_or_service" label="Comércio &gt; Falha em enviar produto ou serviço"/>
+ <combo_box.item name="Disclosure__Real_world_information" label="Revelar &gt; Informação do mundo real"/>
+ <combo_box.item name="Disclosure__Remotely_monitoring chat" label="Revelar &gt; Conversa monitorada remotamente"/>
+ <combo_box.item name="Disclosure__Second_Life_information_chat_IMs" label="Revelar &gt; Informação do Second Life/conversa/MIs"/>
+ <combo_box.item name="Disturbing_the_peace__Unfair_use_of_region_resources" label="Distúrbio da paz &gt; Uso injusto dos recursos da região"/>
+ <combo_box.item name="Disturbing_the_peace__Excessive_scripted_objects" label="Distúrbio da paz &gt; Objetos com excesso de scripts"/>
+ <combo_box.item name="Disturbing_the_peace__Object_littering" label="Distúrbio da paz &gt; Objeto despejando lixo"/>
+ <combo_box.item name="Disturbing_the_peace__Repetitive_spam" label="Distúrbio da paz &gt; Spam repetitivo"/>
+ <combo_box.item name="Disturbing_the_peace__Unwanted_advert_spam" label="Distúrbio da paz &gt; Spam de anúncio indesejado"/>
+ <combo_box.item name="Fraud__L$" label="Fraude &gt; L$"/>
+ <combo_box.item name="Fraud__Land" label="Fraude &gt; Terra"/>
+ <combo_box.item name="Fraud__Pyramid_scheme_or_chain_letter" label="Fraude &gt; Esquema de pirâmide ou cartas encadeadas"/>
+ <combo_box.item name="Fraud__US$" label="Fraude &gt; R$"/>
+ <combo_box.item name="Harassment__Advert_farms___visual_spam" label="Perturbação &gt; Fazendas de Anúncios / spam visual"/>
+ <combo_box.item name="Harassment__Defaming_individuals_or_groups" label="Perturbação &gt; Difamação de indivíduos ou grupos"/>
+ <combo_box.item name="Harassment__Impeding_movement" label="Perturbação &gt; Impedindo movimentos"/>
+ <combo_box.item name="Harassment__Sexual_harassment" label="Perturbação &gt; Perturbação sexual"/>
+ <combo_box.item name="Harassment__Solicting_inciting_others_to_violate_ToS" label="Perturbação &gt; Solicitando/incitando outros a violarem o ToS"/>
+ <combo_box.item name="Harassment__Verbal_abuse" label="Perturbação &gt; Abuso verbal"/>
+ <combo_box.item name="Indecency__Broadly_offensive_content_or_conduct" label="Indecência &gt; Conteúdo ou conduta amplamente ofensivos"/>
+ <combo_box.item name="Indecency__Inappropriate_avatar_name" label="Indecência &gt; Nome de avatar inapropriado"/>
<combo_item name="Indecency__Mature_content_in_PG_region">
Indecência &gt; Conduta ou conteúdo inapropriados numa região PG
</combo_item>
<combo_item name="Indecency__Inappropriate_content_in_Mature_region">
Indecência &gt; Conduta ou conteúdo inapropriados numa região Mature
</combo_item>
- <combo_item name="Intellectual_property_infringement_Content_Removal">
- Violação de propriedade intelectual &gt; Remoção de Conteúdo
- </combo_item>
- <combo_item name="Intellectual_property_infringement_CopyBot_or_Permissions_Exploit">
- Violação de Propriedade intelectual &gt; Cópia Ilegal ou Aproveitar-se de Permissões
- </combo_item>
- <combo_item name="Intolerance">
- Intolerância
- </combo_item>
- <combo_item name="Land__Abuse_of_sandbox_resources">
- Terra &gt; Abuso dos recursos da sandbox
- </combo_item>
- <combo_item name="Land__Encroachment__Objects_textures">
- Terra &gt; Invasão &gt; Objetos/texturas
- </combo_item>
- <combo_item name="Land__Encroachment__Particles">
- Terra &gt; Invasão &gt; Partículas
- </combo_item>
- <combo_item name="Land__Encroachment__Trees_plants">
- Terra &gt; Violação &gt; Ãrvores/plantas
- </combo_item>
- <combo_item name="Wagering_gambling">
- Apostas/jogos de azar
- </combo_item>
- <combo_item name="Other">
- Outro
- </combo_item>
+ <combo_box.item name="Intellectual_property_infringement_Content_Removal" label="Violação de propriedade intelectual &gt; Remoção de Conteúdo"/>
+ <combo_box.item name="Intellectual_property_infringement_CopyBot_or_Permissions_Exploit" label="Violação de Propriedade intelectual &gt; Cópia Ilegal ou Aproveitar-se de Permissões"/>
+ <combo_box.item name="Intolerance" label="Intolerância"/>
+ <combo_box.item name="Land__Abuse_of_sandbox_resources" label="Terra &gt; Abuso dos recursos da sandbox"/>
+ <combo_box.item name="Land__Encroachment__Objects_textures" label="Terra &gt; Invasão &gt; Objetos/texturas"/>
+ <combo_box.item name="Land__Encroachment__Particles" label="Terra &gt; Invasão &gt; Partículas"/>
+ <combo_box.item name="Land__Encroachment__Trees_plants" label="Terra &gt; Violação &gt; Ãrvores/plantas"/>
+ <combo_box.item name="Wagering_gambling" label="Apostas/jogos de azar"/>
+ <combo_box.item name="Other" label="Outro"/>
</combo_box>
<text name="abuser_name_title">
Nome do Denunciado:
diff --git a/indra/newview/skins/default/xui/pt/floater_sell_land.xml b/indra/newview/skins/default/xui/pt/floater_sell_land.xml
index 4236d2a465..20f9972c73 100644
--- a/indra/newview/skins/default/xui/pt/floater_sell_land.xml
+++ b/indra/newview/skins/default/xui/pt/floater_sell_land.xml
@@ -36,15 +36,9 @@
particular.
</text>
<combo_box name="sell_to" bottom_delta="-32">
- <combo_item name="--selectone--">
- -- Selecione um --
- </combo_item>
- <combo_item name="Anyone">
- Qualquer um
- </combo_item>
- <combo_item name="Specificuser:">
- Usuário Específico:
- </combo_item>
+ <combo_box.item name="--selectone--" label="Selecione um --" />
+ <combo_box.item name="Anyone" label="Qualquer um" />
+ <combo_box.item name="Specificuser:" label="Usuário Específico:" />
</combo_box>
<button label="Selecione..." name="sell_to_select_agent"/>
<text name="sell_objects_label">
@@ -55,12 +49,8 @@ particular.
lote irão mudar de propriedade.
</text>
<radio_group name="sell_objects" bottom_delta="-58">
- <radio_item name="no">
- Não, manter a propriedade sobre os objetos
- </radio_item>
- <radio_item name="yes">
- Sim, vender objetos com a terra
- </radio_item>
+ <radio_item name="no" label="Não, manter a propriedade sobre os objetos" />
+ <radio_item name="yes" label="Sim, vender objetos com a terra" />
</radio_group>
<button label="Mostrar Objetos" name="show_objects"/>
<text name="nag_message_label">
diff --git a/indra/newview/skins/default/xui/pt/floater_settings_debug.xml b/indra/newview/skins/default/xui/pt/floater_settings_debug.xml
index 2109c311e3..f7b468bb22 100644
--- a/indra/newview/skins/default/xui/pt/floater_settings_debug.xml
+++ b/indra/newview/skins/default/xui/pt/floater_settings_debug.xml
@@ -1,12 +1,8 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<floater name="settings_debug" title="Configurações de Debug">
<combo_box name="boolean_combo">
- <combo_item name="TRUE">
- VERDADEIRO
- </combo_item>
- <combo_item name="FALSE">
- FALSO
- </combo_item>
+ <combo_box.item name="TRUE" label="VERDADEIRO" />
+ <combo_box.item name="FALSE" label="FALSO" />
</combo_box>
<color_swatch label="Cor" name="color_swatch"/>
<spinner label="x" name="val_spinner_1"/>
diff --git a/indra/newview/skins/default/xui/pt/floater_snapshot.xml b/indra/newview/skins/default/xui/pt/floater_snapshot.xml
index dd82e6deb3..2f6efd4998 100644
--- a/indra/newview/skins/default/xui/pt/floater_snapshot.xml
+++ b/indra/newview/skins/default/xui/pt/floater_snapshot.xml
@@ -4,15 +4,9 @@
Destino da foto
</text>
<radio_group label="Tipo de Foto" name="snapshot_type_radio">
- <radio_item name="postcard">
- Enviar por email
- </radio_item>
- <radio_item name="texture">
- Salvar no seu inventário (L$[AMOUNT])
- </radio_item>
- <radio_item name="local">
- Salvar no seu disco rígido
- </radio_item>
+ <radio_item name="postcard" label="Enviar por email" />
+ <radio_item name="texture" label="Salvar no seu inventário (L$[AMOUNT])" />
+ <radio_item name="local" label="Salvar no seu disco rígido" />
</radio_group>
<text name="file_size_label">
Tamanho do arquivo: [SIZE] KB
@@ -21,12 +15,12 @@
<button label="Enviar" name="send_btn"/>
<button label="Salvar (L$[AMOUNT])" name="upload_btn"/>
<flyout_button label="Salvar" name="save_btn" tool_tip="Salvar imagem em um arquivo">
- <flyout_button_item name="save_item">
- Salvar
- </flyout_button_item>
- <flyout_button_item name="saveas_item">
- Salvar como...
- </flyout_button_item>
+ <flyout_button.item name="save_item">
+ Salvar
+ </flyout_button.item>
+ <flyout_button.item name="saveas_item">
+ Salvar como...
+ </flyout_button.item>
</flyout_button>
<button label="Cancelar" name="discard_btn"/>
<button label="Mais &gt;" name="more_btn" tool_tip="Opções Avançadas"/>
@@ -38,75 +32,33 @@
Formato
</text>
<combo_box label="Resolução" name="postcard_size_combo">
- <combo_item name="CurrentWindow">
- Janela Atual
- </combo_item>
- <combo_item name="640x480">
- 640x480
- </combo_item>
- <combo_item name="800x600">
- 800x600
- </combo_item>
- <combo_item name="1024x768">
- 1024x768
- </combo_item>
- <combo_item name="Custom">
- Customizado
- </combo_item>
+ <combo_box.item name="CurrentWindow" label="Janela Atual" />
+ <combo_box.item name="640x480" label="640x480" />
+ <combo_box.item name="800x600" label="800x600" />
+ <combo_box.item name="1024x768" label="1024x768" />
+ <combo_box.item name="Custom" label="Customizado" />
</combo_box>
<combo_box label="Resolução" name="texture_size_combo">
- <combo_item name="CurrentWindow">
- Janela Atual
- </combo_item>
- <combo_item name="Small(128x128)">
- Pequeno (128x128)
- </combo_item>
- <combo_item name="Medium(256x256)">
- Médio (256x256)
- </combo_item>
- <combo_item name="Large(512x512)">
- Grande (512x512)
- </combo_item>
- <combo_item name="Custom">
- Customizado
- </combo_item>
+ <combo_box.item name="CurrentWindow" label="Janela Atual" />
+ <combo_box.item name="Small(128x128)" label="Pequeno (128x128)" />
+ <combo_box.item name="Medium(256x256)" label="Médio (256x256)" />
+ <combo_box.item name="Large(512x512)" label="Grande (512x512)" />
+ <combo_box.item name="Custom" label="Customizado" />
</combo_box>
<combo_box label="Resolução" name="local_size_combo">
- <combo_item name="CurrentWindow">
- Janela Atual
- </combo_item>
- <combo_item name="320x240">
- 320x240
- </combo_item>
- <combo_item name="640x480">
- 640x480
- </combo_item>
- <combo_item name="800x600">
- 800x600
- </combo_item>
- <combo_item name="1024x768">
- 1024x768
- </combo_item>
- <combo_item name="1280x1024">
- 1280x1024
- </combo_item>
- <combo_item name="1600x1200">
- 1600x1200
- </combo_item>
- <combo_item name="Custom">
- Customizado
- </combo_item>
+ <combo_box.item name="CurrentWindow" label="Janela Atual" />
+ <combo_box.item name="320x240" label="320x240" />
+ <combo_box.item name="640x480" label="640x480" />
+ <combo_box.item name="800x600" label="800x600" />
+ <combo_box.item name="1024x768" label="1024x768" />
+ <combo_box.item name="1280x1024" label="1280x1024" />
+ <combo_box.item name="1600x1200" label="1600x1200" />
+ <combo_box.item name="Custom" label="Customizado" />
</combo_box>
<combo_box label="Formato" name="local_format_combo">
- <combo_item name="PNG">
- PNG
- </combo_item>
- <combo_item name="JPEG">
- JPEG
- </combo_item>
- <combo_item name="BMP">
- BMP
- </combo_item>
+ <combo_box.item name="PNG" label="PNG" />
+ <combo_box.item name="JPEG" label="JPEG" />
+ <combo_box.item name="BMP" label="BMP" />
</combo_box>
<spinner label="Largura" name="snapshot_width" label_width="41" width="101"/>
<spinner label="Altura" name="snapshot_height" label_width="31" width="91" left="119"/>
@@ -116,15 +68,9 @@
Capturar:
</text>
<combo_box label="Camadas da Imagem" name="layer_types">
- <combo_item name="Colors">
- Cores
- </combo_item>
- <combo_item name="Depth">
- Formato
- </combo_item>
- <combo_item name="ObjectMattes">
- Decoração do Objeto
- </combo_item>
+ <combo_box.item name="Colors" label="Cores" />
+ <combo_box.item name="Depth" label="Formato" />
+ <combo_box.item name="ObjectMattes" label="Decoração do Objeto" />
</combo_box>
<check_box label="Mostrar interface na Foto" name="ui_check"/>
<check_box bottom_delta="-17" label="Mostrar Objetos HUD na Foto" name="hud_check"/>
diff --git a/indra/newview/skins/default/xui/pt/floater_tos.xml b/indra/newview/skins/default/xui/pt/floater_tos.xml
index 4bb4539b80..7a0c187517 100644
--- a/indra/newview/skins/default/xui/pt/floater_tos.xml
+++ b/indra/newview/skins/default/xui/pt/floater_tos.xml
@@ -5,7 +5,7 @@
<check_box label="Eu concordo com os Termos do Serviço" name="agree_chk"/>
<text name="tos_heading">
Por favor, leia os seguintes Termos de Serviço cuidadosamente. Para continuar acessando o
-Second Life, você precisa aceitar o acordo.
+[SECOND_LIFE], você precisa aceitar o acordo.
</text>
<text_editor name="tos_text">
TOS_TEXT
diff --git a/indra/newview/skins/default/xui/pt/floater_world_map.xml b/indra/newview/skins/default/xui/pt/floater_world_map.xml
index 66279e82d3..bc4b5462ef 100644
--- a/indra/newview/skins/default/xui/pt/floater_world_map.xml
+++ b/indra/newview/skins/default/xui/pt/floater_world_map.xml
@@ -28,14 +28,10 @@
<check_box label="Mature" name="event_mature_chk"/>
<check_box label="Adult" name="event_adult_chk"/>
<combo_box label="Amigos Conectados" name="friend combo" tool_tip="Amigos para mostrar no Mapa">
- <combo_item name="none_selected">
- Amigos Conectados
- </combo_item>
+ <combo_box.item name="none_selected" label="Amigos Conectados" />
</combo_box>
<combo_box label="Landmarks" name="landmark combo" tool_tip="Landmark para mostrar no Mapa">
- <combo_item name="none_selected">
- Landmarks
- </combo_item>
+ <combo_box.item name="none_selected" label="Landmarks" />
</combo_box>
<line_editor label="Procurar por nome de região" name="location" tool_tip="Digite o nome de uma Região"/>
<button label="Procurar" name="DoSearch" tool_tip="Procurar por região"/>
@@ -52,6 +48,6 @@
<button font="SansSerifSmall" left_delta="91" width="135" label="Mostrar destino" label_selected="Mostrar Destino" name="Show Destination" tool_tip="Centralizar mapa na posição selecionada"/>
<button font="SansSerifSmall" label="Limpar" label_selected="Limpar" name="Clear" tool_tip="Parar de percorrer"/>
<button font="SansSerifSmall" left_delta="91" width="135" label="Mostra minha localização" label_selected="Mostra minha localização" name="Show My Location" tool_tip="Centraliza o mapa na posição do seu Avatar"/>
- <button font="SansSerifSmall" label="Copiar SLURL para área de transferência" name="copy_slurl" tool_tip="Copia a posição atual como SLURL para ser usada na Web"/>
+ <button font="SansSerifSmall" label="Copiar SLurl para área de transferência" name="copy_slurl" tool_tip="Copia a posição atual como SLurl para ser usada na Web"/>
<slider label="Zoom" name="zoom slider"/>
</floater>
diff --git a/indra/newview/skins/default/xui/pt/language_settings.xml b/indra/newview/skins/default/xui/pt/language_settings.xml
new file mode 100644
index 0000000000..71418d446a
--- /dev/null
+++ b/indra/newview/skins/default/xui/pt/language_settings.xml
@@ -0,0 +1,55 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<!-- This file contains strings that used to be hardcoded in the source.-->
+<strings>
+
+ <!-- Locale Information -->
+ <string name="MicrosoftLocale">english</string>
+ <string name="DarwinLocale">C</string>
+ <string name="LinuxLocale">C</string>
+
+ <!--
+ datetimeToCodes["wkday"] = "%a"; // Thu
+ datetimeToCodes["weekday"] = "%A"; // Thursday
+ datetimeToCodes["year4"] = "%Y"; // 2009
+ datetimeToCodes["year"] = "%Y"; // 2009
+ datetimeToCodes["year2"] = "%y"; // 09
+ datetimeToCodes["mth"] = "%b"; // Aug
+ datetimeToCodes["month"] = "%B"; // August
+ datetimeToCodes["mthnum"] = "%m"; // 08
+ datetimeToCodes["day"] = "%d"; // 31
+ datetimeToCodes["hour24"] = "%H"; // 14
+ datetimeToCodes["hour"] = "%H"; // 14
+ datetimeToCodes["hour12"] = "%I"; // 02
+ datetimeToCodes["min"] = "%M"; // 59
+ datetimeToCodes["ampm"] = "%p"; // AM
+ datetimeToCodes["second"] = "%S"; // 59
+ datetimeToCodes["timezone"] = "%Z"; // PST
+ -->
+
+ <string name="TimeHour">hour,datetime,slt</string>
+ <string name="TimeMin">min,datetime,slt</string>
+ <string name="TimeYear">year,datetime,slt</string>
+ <string name="TimeDay">day,datetime,slt</string>
+ <string name="TimeMonth">mthnum,datetime,slt</string>
+ <string name="TimeWeek">wkday,datetime,slt</string>
+ <string name="TimeAMPM">ampm,datetime,slt</string>
+ <string name="TimeHour12">hour12,datetime,slt</string>
+
+ <string name="LTimeMthNum">mthnum,datetime,local</string>
+ <string name="LTimeWeek">wkday,datetime,local</string>
+ <string name="LTimeMonth">mth,datetime,local</string>
+ <string name="LTimeDay">day,datetime,local</string>
+ <string name="LTimeSec">second,datetime,local</string>
+ <string name="LTimeHour">hour,datetime,local</string>
+ <string name="LTimeMin">min,datetime,local</string>
+ <string name="LTimeYear">year,datetime,local</string>
+
+ <string name="UTCTimeWeek">weekday,datetime,utc</string>
+ <string name="UTCTimeDay">day,datetime,utc</string>
+ <string name="UTCTimeMth">mth,datetime,utc</string>
+ <string name="UTCTimeYr">year,datetime,utc</string>
+ <string name="UTCTimeHr">hour,datetime,utc</string>
+ <string name="UTCTimeMin">min,datetime,utc</string>
+ <string name="UTCTimeSec">second,datetime,utc</string>
+ <string name="UTCTimeTimezone">timezone,datetime,utc</string>
+</strings>
diff --git a/indra/newview/skins/default/xui/pt/menu_login.xml b/indra/newview/skins/default/xui/pt/menu_login.xml
index f60946fcce..7ec324cb3f 100644
--- a/indra/newview/skins/default/xui/pt/menu_login.xml
+++ b/indra/newview/skins/default/xui/pt/menu_login.xml
@@ -7,7 +7,7 @@
<menu_item_call label="Preferências..." name="Preferences..."/>
</menu>
<menu label="Ajuda" name="Help">
- <menu_item_call label="Ajuda do Second Life" name="Second Life Help"/>
- <menu_item_call label="Sobre o Second Life..." name="About Second Life..."/>
+ <menu_item_call label="Ajuda do [SECOND_LIFE]" name="Second Life Help"/>
+ <menu_item_call label="Sobre o [APP_NAME]..." name="About Second Life..."/>
</menu>
</menu_bar>
diff --git a/indra/newview/skins/default/xui/pt/menu_viewer.xml b/indra/newview/skins/default/xui/pt/menu_viewer.xml
index 76b674ab66..c476ef0bbc 100644
--- a/indra/newview/skins/default/xui/pt/menu_viewer.xml
+++ b/indra/newview/skins/default/xui/pt/menu_viewer.xml
@@ -185,7 +185,7 @@
<menu_item_call label="Ajustar scripts para não rodar na seleção" name="Set Scripts to Not Running in Selection"/>
</menu>
<menu label="Ajuda" name="Help">
- <menu_item_call label="Ajuda Second Life" name="Second Life Help"/>
+ <menu_item_call label="Ajuda [SECOND_LIFE]" name="Second Life Help"/>
<menu_item_call label="Tutorial" name="Tutorial"/>
<menu_item_separator label="-----------" name="separator"/>
<menu_item_call label="Blog oficial da Linden..." name="Official Linden Blog..."/>
@@ -206,6 +206,6 @@
<menu_item_separator label="-----------" name="separator9"/>
<menu_item_call label="Reportar Bug..." name="Report Bug..."/>
</menu>
- <menu_item_call label="Sobre Second Life..." name="About Second Life..."/>
+ <menu_item_call label="Sobre [APP_NAME]..." name="About Second Life..."/>
</menu>
</menu_bar>
diff --git a/indra/newview/skins/default/xui/pt/notifications.xml b/indra/newview/skins/default/xui/pt/notifications.xml
index 0e3ab9c644..a303b38348 100644
--- a/indra/newview/skins/default/xui/pt/notifications.xml
+++ b/indra/newview/skins/default/xui/pt/notifications.xml
@@ -6,6 +6,9 @@
<global name="alwayschoose">
Sempre escolher esta opção
</global>
+ <global name="implicitclosebutton">
+ Fechar
+ </global>
<template name="okbutton">
<form>
<button
@@ -71,7 +74,7 @@
</form>
</template>
<notification functor="GenericAcknowledge" label="Mensagem de Alerta Desconhecida" name="MissingAlert">
- Sua versão do Second Life não sabe como mostrar a mensagem de alerta que acabou de receber.
+ Sua versão do [APP_NAME] não sabe como mostrar a mensagem de alerta que acabou de receber.
Detalhes do erro: O alerta chamado &apos;[_NAME]&apos; não foi encontrado em notifications.xml.
<usetemplate name="okbutton" yestext="OK"/>
@@ -93,7 +96,7 @@ Detalhes do erro: O alerta chamado &apos;[_NAME]&apos; não foi encontrado em no
<usetemplate name="okcancelbuttons" notext="Cancelar" yestext="Sim"/>
</notification>
<notification name="BadInstallation">
- Ocorreu um erro atualizando o Second Life. Por favor, faça o download da última versão em secondlife.com.
+ Ocorreu um erro atualizando o [APP_NAME]. Por favor, faça o download da última versão em secondlife.com.
<usetemplate
name="okbutton"
yestext="OK"/>
@@ -232,7 +235,7 @@ Clicando neste Box, será mostrado:
<notification name="ClickPartnerHelpAvatar">
Você pode propor a outro Residente ou dissolver uma parceria existente através do website [SECOND_LIFE].
-Ir para o site do Second Life para mais informações sobre parceria?
+Ir para o site do [SECOND_LIFE] para mais informações sobre parceria?
<usetemplate name="okcancelbuttons" notext="Cancelar" yestext="Ir para a Página"/>
</notification>
<notification name="ClickUploadHelpPermissions">
@@ -270,7 +273,7 @@ Seu preço de venda será L$[SALE_PRICE] e está autorizado para venda para [NA
<usetemplate name="okcancelbuttons" notext="Cancelar" yestext="Continuar"/>
</notification>
<notification name="ConfirmLandSaleToAnyoneChange">
- ATENÇÃO: Ao clicar em &apos;vender para qualquer um&apos; torna a sua terra disponível para toda a comunidade Second Life, mesmo aqueles que não estão nesta região.
+ ATENÇÃO: Ao clicar em &apos;vender para qualquer um&apos; torna a sua terra disponível para toda a comunidade [SECOND_LIFE], mesmo aqueles que não estão nesta região.
A área de [LAND_SIZE] m² de terra selecionada está posta para venda.
Seu preço de venda será L$ [SALE_PRICE] e está autorizado para [NAME].
@@ -415,17 +418,17 @@ Não há reembolso por taxas já pagas.
<usetemplate name="okcancelbuttons" notext="Cancelar" yestext="OK"/>
</notification>
<notification name="CacheWillClear">
- O cache será limpo quando você reiniciar [SECOND_LIFE].
+ O cache será limpo quando você reiniciar [APP_NAME].
</notification>
<notification name="CacheWillBeMoved">
- O Cache será removido após reiniciar [SECOND_LIFE].
+ O Cache será removido após reiniciar [APP_NAME].
Nota: Isto limpará o cache.
</notification>
<notification name="ChangeConnectionPort">
- Configuração de porta terá efeito após reiniciar [SECOND_LIFE].
+ Configuração de porta terá efeito após reiniciar [APP_NAME].
</notification>
<notification name="ChangeSkin">
- A nova pele será exibida após reiniciar [SECOND_LIFE].
+ A nova pele será exibida após reiniciar [APP_NAME].
</notification>
<notification name="GoToAuctionPage">
Ir para a página do [SECOND_LIFE] para ver os detalhes do leilão ou fazer um lance?
@@ -484,7 +487,7 @@ O objeto pode estar fora de alcance ou ter sido deletado.
Não foi possível escrever o arquivo [[FILE]]
</notification>
<notification name="UnsupportedHardware">
- Aviso: Seu sistema não é compatível com os requisitos mínimos exigidos pelo Second Life. Se você continuar usando o Second Life pode experimentar uma performance ruim. Infelizmente não podemos oferecer suporte técnico para configurações de sistema não suportado.
+ Aviso: Seu sistema não é compatível com os requisitos mínimos exigidos pelo [APP_NAME]. Se você continuar usando o [APP_NAME] pode experimentar uma performance ruim. Infelizmente não podemos oferecer suporte técnico para configurações de sistema não suportado.
MINSPECS
Você deseja visitar [_URL] para maiores informações?
@@ -495,14 +498,14 @@ Você deseja visitar [_URL] para maiores informações?
</notification>
<notification name="UnknownGPU">
Seu sistema possui uma placa gráfica que nos é desconhecido neste momento.
-Este é normalmente o caso de um novo hardware que nós não tivemos a chance de testar. Second Life vai muito provavelmente executar corretamente, mas talvez seja necessário ajustar suas configurações de gráficos para algo mais apropriado.
+Este é normalmente o caso de um novo hardware que nós não tivemos a chance de testar. [APP_NAME] vai muito provavelmente executar corretamente, mas talvez seja necessário ajustar suas configurações de gráficos para algo mais apropriado.
(Menu Editar &gt; Preferências &gt; Gráficos).
<form name="form">
<ignore name="ignore" text="Ao detectar uma placa de vídeo desconhecida"/>
</form>
</notification>
<notification name="DisplaySettingsNoShaders">
- [SECOND_LIFE] travou quando inicializava os drivers gráficos.
+ [APP_NAME] travou quando inicializava os drivers gráficos.
A Qualidade Gráfica será ajustada para baixa, para evitar alguns erros comuns de drivers.
Isto irá desabilitar alguns atributos gráficos.
Nós recomendamos a atualização dos drivers de sua placa gráfica.
@@ -782,7 +785,7 @@ Nenhum lote selecionado.
Não é possível achar a região em que este terreno se encontra.
</notification>
<notification name="CannotCloseFloaterBuyLand">
- Você não pode fechar a janela de Compra de Terreno até que o Second Life calcule o preço desta transação.
+ Você não pode fechar a janela de Compra de Terreno até que o [APP_NAME] calcule o preço desta transação.
</notification>
<notification name="CannotDeedLandNothingSelected">
Não é possível transferir posse do terreno:
@@ -953,7 +956,7 @@ Se o problema persistir, por favor clicar sobre &apos;Ferramentas &gt; Bug Repor
<notification name="YouHaveBeenLoggedOut">
Você foi deslogado do [SECOND_LIFE]:
[MESSAGE]
-Você ainda pode olhar o bate-papo e as mensagens instantâneas existentes, clicando em &apos;Exibir IM &amp; bate-papo&apos;. Caso contrário, clique em &apos;Sair&apos; para sair do [SECOND_LIFE] imediatamente.
+Você ainda pode olhar o bate-papo e as mensagens instantâneas existentes, clicando em &apos;Exibir IM &amp; bate-papo&apos;. Caso contrário, clique em &apos;Sair&apos; para sair do [APP_NAME] imediatamente.
<usetemplate name="okcancelbuttons" notext="Sair" yestext="Exibir IM &amp; bate-papo"/>
</notification>
<notification name="OnlyOfficerCanBuyLand">
@@ -1118,14 +1121,14 @@ Você pode usar o [SECOND_LIFE] normalmente e os outros o visualizarão corretam
</form>
</notification>
<notification name="FirstRun">
- A instalação do [SECOND_LIFE] está completa.
+ A instalação do [APP_NAME] está completa.
Se esta é a primeira vez usando o[SECOND_LIFE], será necessário que você crie uma conta antes de poder se logar.
Retornar a www.secondlife.com para criar uma nova conta?
<usetemplate name="okcancelbuttons" notext="Continuar" yestext="Nova conta.."/>
</notification>
<notification name="LoginPacketNeverReceived">
- Estamos com problemas de conexão. Pode ser problema com a conexão de sua internet ou com os servidores do Second Life.
+ Estamos com problemas de conexão. Pode ser problema com a conexão de sua internet ou com os servidores do [SECOND_LIFE].
Voce tanto pode checar a conexão de sua internet e tentar novamente em alguns minutos, ou clicar em Teletransporte para tentar teletransportar-se para sua casa.
<form name="form">
@@ -1138,7 +1141,7 @@ Voce tanto pode checar a conexão de sua internet e tentar novamente em alguns m
Seu personagem irá aparecer num momento.
Use as teclas de seta para andar.
-Pressione a tecla F1 para ajuda ou aprender mais sobre [SECOND_LIFE].
+Pressione a tecla F1 para ajuda ou aprender mais sobre [SECOND_LIFE].
Por favor, escolha se o seu avatar é feminino ou masculino. Você pode mudar de idéia depois.
<usetemplate name="okcancelbuttons" notext="Feminino" yestext="Masculino"/>
</notification>
@@ -1226,33 +1229,33 @@ Por favor, ponha o objeto à venda e tente novamente.
[DOWNLOAD_PATH]
</notification>
<notification name="DownloadWindowsMandatory">
- Uma nova versão do [SECOND_LIFE] está disponível.
+ Uma nova versão do [APP_NAME] está disponível.
[MESSAGE]
-Você deve baixar essa atualização para utilizar o [SECOND_LIFE].
+Você deve baixar essa atualização para utilizar o [APP_NAME].
<usetemplate name="okcancelbuttons" notext="Sair" yestext="Atualizar"/>
</notification>
<notification name="DownloadWindows">
- Uma versão atualizada do [SECOND_LIFE] está disponível.
+ Uma versão atualizada do [APP_NAME] está disponível.
[MESSAGE]
Essa atualização não é mandatória, mas sugerimos que você a instale para melhorar a performance e a estabilidade.
<usetemplate name="okcancelbuttons" notext="Continuar" yestext="Atualizar"/>
</notification>
<notification name="DownloadWindowsReleaseForDownload">
- Uma versão atualizada do [SECOND_LIFE] está disponível.
+ Uma versão atualizada do [APP_NAME] está disponível.
[MESSAGE]
Essa atualização não é mandatória, mas sugerimos que você a instale para melhorar a performance e a estabilidade.
<usetemplate name="okcancelbuttons" notext="Continuar" yestext="Atualizar"/>
</notification>
<notification name="DownloadMacMandatory">
- Uma nova versão do [SECOND_LIFE] está disponível.
+ Uma nova versão do [APP_NAME] está disponível.
[MESSAGE]
-Você deve baixar esta atualização para utilizar o [SECOND_LIFE].
+Você deve baixar esta atualização para utilizar o [APP_NAME].
Baixar para sua pasta de Aplicativos?
<usetemplate name="okcancelbuttons" notext="Sair" yestext="Atualizar"/>
</notification>
<notification name="DownloadMac">
- Uma nova versão do [SECOND_LIFE] está disponível.
+ Uma nova versão do [APP_NAME] está disponível.
[MESSAGE]
Essa atualização não é mandatória, mas sugerimos que você a instale para melhorar a performance e a estabilidade.
@@ -1260,7 +1263,7 @@ Baixar para a sua pasta de Aplicativos?
<usetemplate name="okcancelbuttons" notext="Continuar" yestext="Atualizar"/>
</notification>
<notification name="DownloadMacReleaseForDownload">
- Uma nova versão do [SECOND_LIFE] está disponível.
+ Uma nova versão do [APP_NAME] está disponível.
[MESSAGE]
Essa atualização não é mandatória, mas sugerimos que você a instale para melhorar a performance e a estabilidade.
@@ -1859,7 +1862,7 @@ Definí-lo em branco fará com que os relatórios de abuso sejam enviados apenas
Padrão: desligado
</notification>
<notification label="Discordância de Versão de Voz" name="VoiceVersionMismatch">
- Esta versão do Second Life não é compatível com as características do Canal de Voz desta região. Para que a Conversa por Voz funcione corretamente, você precisará atualizar o Second Life.
+ Esta versão do [APP_NAME] não é compatível com as características do Canal de Voz desta região. Para que a Conversa por Voz funcione corretamente, você precisará atualizar o [APP_NAME].
</notification>
<notification label="Corretor da Propriedade" name="HelpEstateCovenant">
Definir um corretor da propriedade lhe permite vender lotes nesta propriedade. Se um corretor não for definido, você não pode vender terras. O cartão do seu corretor pode ficar vazio se você não desejar aplicar quaisquer regras ou avisar os compradores sobre qualquer coisa em relação ao lote antes da compra.
@@ -1973,16 +1976,16 @@ Mover para o inventário o(s) item(s)?
Não há itens neste objeto que você está autorizado a copiar.
</notification>
<notification name="WebLaunchAccountHistory">
- Ir para o site do Second Life para visualizar o histórico de sua conta?
+ Ir para o site do [SECOND_LIFE] para visualizar o histórico de sua conta?
<usetemplate ignoretext="Ao abrir a página web de histórico de conta" name="okcancelignore" notext="Cancelar" yestext="Ir para a página"/>
</notification>
<notification name="ClickOpenF1Help">
- Visitar o website de Suporte do Second Life?
- <usetemplate ignoretext="Quando visitando o website de Suporte do Second Life" name="okcancelignore" notext="Cancelar" yestext="Ir"/>
+ Visitar o website de Suporte do [SECOND_LIFE]?
+ <usetemplate ignoretext="Quando visitando o website de Suporte do [SECOND_LIFE]" name="okcancelignore" notext="Cancelar" yestext="Ir"/>
</notification>
<notification name="ConfirmQuit">
Tem certeza que deseja sair?
- <usetemplate ignoretext="Quando Saindo do Second Life." name="okcancelignore" notext="Continuar" yestext="Sair"/>
+ <usetemplate ignoretext="Quando Saindo do [APP_NAME]." name="okcancelignore" notext="Continuar" yestext="Sair"/>
</notification>
<notification name="HelpReportAbuseEmailLL">
Use esta ferramenta para reportar violações aos Termos de Serviço e aos Padrões da Comunidade. Veja:
@@ -2002,8 +2005,8 @@ Como um serviço aos residentes e visitantes, o dono da região em que você se
O dono da região resolverá as reportagens baseado nas regras locais desta região, como definido na Declaração da propriedade.
(Veja as declarações indo ao menu Mundo e selecionando Sobre a Terra.)
-A resolução desta reportagem se aplica apenas a esta região; o acesso de Residentes às outras áreas do Second Life não será afetado pelas decisões desta reportagem.
-Apenas a Linden Lab pode restringir acesso a todo o Second Life.
+A resolução desta reportagem se aplica apenas a esta região; o acesso de Residentes às outras áreas do [SECOND_LIFE] não será afetado pelas decisões desta reportagem.
+Apenas a Linden Lab pode restringir acesso a todo o [SECOND_LIFE].
</notification>
<notification name="HelpReportBug">
Use esta ferramenta para reportar *apenas* características técnicas que não atuem como descrito ou esperado.
@@ -2056,9 +2059,9 @@ Fazer uma descrição precisa nos ajuda a arquivar e processar os relatórios de
Você parece estar relatando violação de propriedade intelectual. Por favor, certifique-se de que está relatando corretamente:
-(1) O Processo de abuso. Você pode apresentar um relatório de abuso se você acredita que um Residente está infringindo o sistema de permissões do Second Life, por exemplo, utilizando ferramentas CopyBot para copiar ou similar, para violar os direitos de propriedade intelectual. A Equipe de Abuso investiga e divulga a ação disciplinar adequada para o comportamento que viola o Estatuto da Comunidade do Second Life ou os Termos de Serviço. No entanto, a mesma não controla e não irá responder aos pedidos para remover o conteúdo do mundo Second Life.
+(1) O Processo de abuso. Você pode apresentar um relatório de abuso se você acredita que um Residente está infringindo o sistema de permissões do [SECOND_LIFE], por exemplo, utilizando ferramentas CopyBot para copiar ou similar, para violar os direitos de propriedade intelectual. A Equipe de Abuso investiga e divulga a ação disciplinar adequada para o comportamento que viola o Estatuto da Comunidade do [SECOND_LIFE] ou os Termos de Serviço. No entanto, a mesma não controla e não irá responder aos pedidos para remover o conteúdo do mundo [SECOND_LIFE].
-(2) O processo de remoção de conteúdo ou DMCA. Para solicitar a remoção de conteúdo do Second Life, você deve enviar uma notificação válida de infração, conforme previsto em nossa Política de DMCA em http://secondlife.com/corporate/dmca.php.
+(2) O processo de remoção de conteúdo ou DMCA. Para solicitar a remoção de conteúdo do [SECOND_LIFE], você deve enviar uma notificação válida de infração, conforme previsto em nossa Política de DMCA em http://secondlife.com/corporate/dmca.php.
Se você ainda deseja prosseguir com o processo de abuso, por favor, feche esta janela e termine de enviar seu relatório. Pode ser necessário selecionar a categoria específica &apos;CopyBot Infração de Permissões&apos;.
@@ -2109,7 +2112,7 @@ Você gostaria de deixar o modo Ocupado antes de completar esta transação?
<usetemplate ignoretext="Ao esvaziar pasta Achados e Perdidos do seu inventário" name="okcancelignore" notext="Não" yestext="Sim"/>
</notification>
<notification name="CopySLURL">
- A seguinte SLURL foi copiada para o seu clipboard:
+ A seguinte SLurl foi copiada para o seu clipboard:
[SLURL]
Coloque-a em uma página web para dar aos outros um fácil acesso a este local ou tente você, colando-a na barra de endereços do seu navegador.
@@ -2118,7 +2121,7 @@ Coloque-a em uma página web para dar aos outros um fácil acesso a este local o
</form>
</notification>
<notification name="GraphicsPreferencesHelp">
- Este painel controla o tamanho da janela, resolução e a qualidade dos gráficos do computador cliente. O Preferências &gt; Interface Gráfica permite escolher entre quatro níveis gráficos: Baixo, Médio, Alto e Ultra. Você também pode personalizar suas configurações de gráficos selecionando a opção Padrão e manipulando as seguintes definições:
+ Este painel controla o tamanho da janela, resolução e a qualidade dos gráficos do computador cliente. O Preferências &gt; Interface Gráfica permite escolher entre quatro níveis gráficos: Baixo, Médio, Alto e Ultra. Você também pode personalizar suas configurações de gráficos selecionando a opção Personalizar e manipulando as seguintes definições:
Sombreamento: Ativar ou desativar vários tipos de sombreadores de pixel.
@@ -2180,7 +2183,7 @@ Clique &quot;Céu Avançado &quot; para abrir um editor com configurações mais
Clique &quot;Ãgua Avançada &quot; para abrir um editor com configurações mais avançadas para a água.
</notification>
<notification name="HelpDayCycle">
- O editor de Ciclo do Dia dá a você o controle do céu durante um ciclo de dia/noite do Second Life. Este é o ciclo usado pelo controle gradual da hora do dia do editor de ambiente básico.
+ O editor de Ciclo do Dia dá a você o controle do céu durante um ciclo de dia/noite do [SECOND_LIFE]. Este é o ciclo usado pelo controle gradual da hora do dia do editor de ambiente básico.
O editor do ciclo de dia trabalha configurando quadros-chave. Estes são pontos (representados pelos ícones cinza no gráfico de horário) que possuem um pré-ajuste de céu associado a eles. Conforme o dia passa, o céu do Windlight &quot; anima &quot; a interpolação entre esses quadros-chave.
@@ -2258,7 +2261,7 @@ Similar ao azimute.
Controla a velocidade que as núvens se movem na direção Y.
</notification>
<notification name="HelpClassicClouds">
- Marque esta check box para permitir a reprodução das nuvens clássicas mais velhas do Second Life, além das nuvens WindLight.
+ Marque esta check box para permitir a reprodução das nuvens clássicas mais velhas do [SECOND_LIFE], além das nuvens WindLight.
</notification>
<notification name="HelpWaterFogColor">
Escolhe a cor da neblina subaquática.
@@ -2356,7 +2359,7 @@ Similar ao azimute.
</notification>
<notification name="NotAgeVerified">
Você precisa ter a idade verificada para acessar este lote.
-Gostaria de visitar o site do Second Life para verificação de idade?
+Gostaria de visitar o site do [SECOND_LIFE] para verificação de idade?
[_URL]
<url name="url" option="0">
@@ -2366,7 +2369,7 @@ Gostaria de visitar o site do Second Life para verificação de idade?
</notification>
<notification name="Cannot enter parcel: no payment info on file">
Este lote exige que você tenha informações de pagamento no arquivo antes de poder acessá-lo.
-Gostaria de visitar o site do Second Life para configurá-lo?
+Gostaria de visitar o site do [SECOND_LIFE] para configurá-lo?
[_URL]
<url name="url" option="0">
@@ -2677,13 +2680,13 @@ Por favor, tente novamente em alguns instantes.
Impossível criar a conexão pendente.
</notification>
<notification name="InternalUsherError">
- Um erro interno ocorreu enquanto se tentava direcioná-lo para seu destino de Tele-transporte. O Second Life pode estar passando por problemas no serviço, neste momento.
+ Um erro interno ocorreu enquanto se tentava direcioná-lo para seu destino de Tele-transporte. O [SECOND_LIFE] pode estar passando por problemas no serviço, neste momento.
</notification>
<notification name="NoGoodTPDestination">
Impossível encontrar um bom destino para tele-transporte nesta região.
</notification>
<notification name="InternalErrorRegionResolver">
- Um erro interno ocorreu enquanto tentava-se definir as coordenadas globais da sua solicitação de tele-transporte. O Second Life pode estar passando por problemas no serviço, no momento.
+ Um erro interno ocorreu enquanto tentava-se definir as coordenadas globais da sua solicitação de tele-transporte. O [SECOND_LIFE] pode estar passando por problemas no serviço, no momento.
</notification>
<notification name="NoValidLanding">
Não se achou um ponto de aterrissagem válido.
@@ -2804,7 +2807,7 @@ Do objeto: [OBJECTNAME], dono: [NAME]?
Falhou ao procurar [TYPE] nomeado [DESC] no banco de dados.
</notification>
<notification name="InvalidWearable">
- O item que você está tentando vestir usa uma característica que seu Visualizador não lê. Por favor, atualize sua versão do Second Life para vestir este item.
+ O item que você está tentando vestir usa uma característica que seu Visualizador não lê. Por favor, atualize sua versão do [APP_NAME] para vestir este item.
</notification>
<notification name="ScriptQuestion">
&apos;[OBJECTNAME]&apos;, um objeto pertencente a &apos;[NAME]&apos;, gostaria de:
@@ -2909,8 +2912,8 @@ Objetos flexíveis não podem ser físicos e devem ser fantasmas até que a caix
</notification>
<notification name="FirstDebugMenus">
Você ativou o menu Avançado.
-Este menu contém funcionalidades úteis para desenvolvedores debugarem o Second Life.
-Para mostrar esse menu no Windows pressione Ctrl-Alt-D. No Mac pressione Cmd-Opt-Shift-D.
+Este menu contém funcionalidades úteis para desenvolvedores debugarem o [SECOND_LIFE].
+Para mostrar esse menu no Windows pressione Ctrl-Alt-D. No Mac pressione &#8984;-Opt-D.
</notification>
<notification name="FirstSculptedPrim">
Você está editando uma primitiva esculpida.
@@ -3017,7 +3020,7 @@ Clique Aceitar para juntar-se à chamada ou Recusar para recusar o convite. Cliq
- A velocidade da sua CPU não suporta os requisitos mínimos exigidos.
</global>
<global name="UnsupportedGLRequirements">
- Você não parece ter os requisitos de hardware recomendados para rodar o Second Life. O Second Life exige uma placa gráfica OpenGL que tem apoio a multi- texturas. Se este for o caso, você pode se certificar de que tem os drivers mais recentes para sua placa gráfica, e os patches e pacotes de serviços para seu sistema operacional.
+ Você não parece ter os requisitos de hardware recomendados para rodar o [APP_NAME]. O [APP_NAME] exige uma placa gráfica OpenGL que tem apoio a multi- texturas. Se este for o caso, você pode se certificar de que tem os drivers mais recentes para sua placa gráfica, e os patches e pacotes de serviços para seu sistema operacional.
Se continuar com problemas, por favor visite: http://www.secondlife.com/support
</global>
diff --git a/indra/newview/skins/default/xui/pt/panel_login.xml b/indra/newview/skins/default/xui/pt/panel_login.xml
index a556a9d2c6..9f9b80912d 100644
--- a/indra/newview/skins/default/xui/pt/panel_login.xml
+++ b/indra/newview/skins/default/xui/pt/panel_login.xml
@@ -13,15 +13,9 @@
Posição inicial:
</text>
<combo_box name="start_location_combo">
- <combo_item name="MyHome">
- Minha casa
- </combo_item>
- <combo_item name="MyLastLocation">
- Minha última localização
- </combo_item>
- <combo_item name="Typeregionname">
- &lt;Digite o nome da região&gt;
- </combo_item>
+ <combo_box.item name="MyHome" label="Minha casa" />
+ <combo_box.item name="MyLastLocation" label="Minha última localização" />
+ <combo_box.item name="Typeregionname" label="lt; Digite o nome da região;" />
</combo_box>
<check_box label="Lembrar senha" name="remember_check"/>
<button label="Entrar" label_selected="Entrar" name="connect_btn"/>
diff --git a/indra/newview/skins/default/xui/pt/panel_preferences_chat.xml b/indra/newview/skins/default/xui/pt/panel_preferences_chat.xml
index 9aa1381f27..b32e1fb3e1 100644
--- a/indra/newview/skins/default/xui/pt/panel_preferences_chat.xml
+++ b/indra/newview/skins/default/xui/pt/panel_preferences_chat.xml
@@ -5,15 +5,9 @@
do Chat:
</text>
<radio_group name="chat_font_size">
- <radio_item name="radio">
- Pequeno
- </radio_item>
- <radio_item name="radio2">
- Médio
- </radio_item>
- <radio_item name="radio3">
- Grande
- </radio_item>
+ <radio_item name="radio" label="Pequeno" />
+ <radio_item name="radio2" label="Médio" />
+ <radio_item name="radio3" label="Grande" />
</radio_group>
<text length="1" name="text_box2" type="string">
Cor do Chat:
diff --git a/indra/newview/skins/default/xui/pt/panel_preferences_graphics1.xml b/indra/newview/skins/default/xui/pt/panel_preferences_graphics1.xml
index 81dc7f960c..621e99c9c5 100644
--- a/indra/newview/skins/default/xui/pt/panel_preferences_graphics1.xml
+++ b/indra/newview/skins/default/xui/pt/panel_preferences_graphics1.xml
@@ -3,27 +3,17 @@
<button label="?" name="GraphicsPreferencesHelpButton"/>
<check_box label="Execute Second Life em uma janela" name="windowed mode"/>
<text_editor bottom="-56" height="40" name="FullScreenInfo" width="480">
- Se desmarcado, o visualizador irá exibir em tela inteira quando fizer o acesso.
+ Se desmarcado, o visualizador exibirá tela inteira quando fizer o acesso.
</text_editor>
<text name="WindowSizeLabel">
Tamanho da Janela:
</text>
<combo_box name="windowsize combo">
- <combo_item name="640x480">
- 640x480
- </combo_item>
- <combo_item name="800x600">
- 800x600
- </combo_item>
- <combo_item name="720x480">
- 720x480 (NTSC)
- </combo_item>
- <combo_item name="768x576">
- 768x576 (PAL)
- </combo_item>
- <combo_item name="1024x768">
- 1024x768
- </combo_item>
+ <combo_box.item name="640x480" label="640x480" />
+ <combo_box.item name="800x600" label="800x600" />
+ <combo_box.item name="720x480" label="720x480 (NTSC)" />
+ <combo_box.item name="768x576" label="768x576 (PAL)" />
+ <combo_box.item name="1024x768" label="1024x768" />
</combo_box>
<text name="DisplayResLabel">
Resolução de Display:
@@ -32,18 +22,10 @@
Relação de Aspecto:
</text>
<combo_box name="aspect_ratio" tool_tip="largura / altura">
- <combo_item length="1" name="4:3(StandardCRT)" type="string">
- 4:3 (CRT Padrão)
- </combo_item>
- <combo_item length="1" name="5:4(1280x1024LCD)" type="string">
- 5:4 (1280x1024 LCD)
- </combo_item>
- <combo_item name="8:5(Widescreen)">
- 8:5 (tela ampla)
- </combo_item>
- <combo_item length="1" name="16:9(Widescreen)" type="string">
- 16:9 (tela ampla)
- </combo_item>
+ <combo_box.item length="1" name="4:3(StandardCRT)" type="string" label="4:3 (CRT Padrão)" />
+ <combo_box.item length="1" name="5:4(1280x1024LCD)" type="string" label="5:4 (1280x1024 LCD)" />
+ <combo_box.item name="8:5(Widescreen)" label="8:5 (tela ampla)" />
+ <combo_box.item length="1" name="16:9(Widescreen)" type="string" label="16:9 (tela ampla)" />
</combo_box>
<check_box label="Auto-detectar a relação" name="aspect_auto_detect"/>
<text name="HigherText">
@@ -74,7 +56,7 @@ rápido
<text name="QualityText2">
Qualidade
</text>
- <check_box label="Padrão" left="395" name="CustomSettings"/>
+ <check_box label="Personalizar" left="395" name="CustomSettings"/>
<text name="ShadersText">
Sombreadores:
</text>
@@ -86,18 +68,10 @@ rápido
Detalhes de Reflexão:
</text>
<radio_group name="ReflectionDetailRadio">
- <radio_item name="0">
- Terreno e Ãrvores
- </radio_item>
- <radio_item name="1">
- Todos os objetos estáticos
- </radio_item>
- <radio_item name="2">
- Todos os avatares e Objetos
- </radio_item>
- <radio_item name="3">
- Tudo
- </radio_item>
+ <radio_item name="0" label="Terreno e Ãrvores" />
+ <radio_item name="1" label="Todos os objetos estáticos" />
+ <radio_item name="2" label="Todos os avatares e Objetos" />
+ <radio_item name="3" label="Tudo" />
</radio_group>
<text name="AvatarRenderingText">
Renderização de Avatar:
@@ -148,23 +122,15 @@ rápido
Detalhes de Iluminação:
</text>
<radio_group name="LightingDetailRadio">
- <radio_item name="SunMoon">
- Sol e Lua apenas
- </radio_item>
- <radio_item name="LocalLights">
- Luzes locais nas proximidades
- </radio_item>
+ <radio_item name="SunMoon" label="Sol e Lua apenas" />
+ <radio_item name="LocalLights" label="Luzes locais nas proximidades" />
</radio_group>
<text name="TerrainDetailText">
Detalhe do Terreno:
</text>
<radio_group left_delta="45" name="TerrainDetailRadio" width="276">
- <radio_item name="0">
- Baixo
- </radio_item>
- <radio_item name="2">
- Alto
- </radio_item>
+ <radio_item name="0" label="Baixo" />
+ <radio_item name="2" label="Alto" />
</radio_group>
<button label="Configurações Recomendadas" name="Defaults" width="190" left="110"/>
<button label="Opções de Hardware" label_selected="Opções de Hardware" name="GraphicsHardwareButton"/>
diff --git a/indra/newview/skins/default/xui/pt/panel_status_bar.xml b/indra/newview/skins/default/xui/pt/panel_status_bar.xml
index 2a5108b4cb..e9a02344ab 100644
--- a/indra/newview/skins/default/xui/pt/panel_status_bar.xml
+++ b/indra/newview/skins/default/xui/pt/panel_status_bar.xml
@@ -27,8 +27,8 @@
<button label="" label_selected="" name="restrictpush" tool_tip="Não Empurrar"/>
<button label="" label_selected="" name="status_no_voice" tool_tip="Voz não disponível aqui"/>
<button label="" label_selected="" name="buyland" tool_tip="Comprar este lote"/>
- <line_editor label="Buscar" name="search_editor" tool_tip="Buscar no Second Life"/>
- <button label="" label_selected="" name="search_btn" tool_tip="Buscar no Second Life"/>
+ <line_editor label="Buscar" name="search_editor" tool_tip="Buscar no [SECOND_LIFE]"/>
+ <button label="" label_selected="" name="search_btn" tool_tip="Buscar no [SECOND_LIFE]"/>
<string name="packet_loss_tooltip">
Perda de pacote
</string>
diff --git a/indra/newview/skins/paths.xml b/indra/newview/skins/paths.xml
index 949cc145d9..3b91a904b0 100644
--- a/indra/newview/skins/paths.xml
+++ b/indra/newview/skins/paths.xml
@@ -1,4 +1,4 @@
<paths>
- <directory>xui/en-us</directory>
+ <directory>xui/en</directory>
<directory>xui/[LANGUAGE]</directory>
</paths> \ No newline at end of file
diff --git a/indra/newview/tests/llagentaccess_test.cpp b/indra/newview/tests/llagentaccess_test.cpp
index fc18f10e7d..42872d85fb 100644
--- a/indra/newview/tests/llagentaccess_test.cpp
+++ b/indra/newview/tests/llagentaccess_test.cpp
@@ -3,59 +3,73 @@
* @brief LLAgentAccess tests
*
* $LicenseInfo:firstyear=2001&license=viewergpl$
+ *
* Copyright (c) 2001-2009, Linden Research, Inc.
+ *
+ * Second Life Viewer Source Code
+ * The source code in this file ("Source Code") is provided by Linden Lab
+ * to you under the terms of the GNU General Public License, version 2.0
+ * ("GPL"), unless you have obtained a separate licensing agreement
+ * ("Other License"), formally executed by you and Linden Lab. Terms of
+ * the GPL can be found in doc/GPL-license.txt in this distribution, or
+ * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
+ *
+ * There are special exceptions to the terms and conditions of the GPL as
+ * it is applied to this Source Code. View the full text of the exception
+ * in the file doc/FLOSS-exception.txt in this software distribution, or
+ * online at
+ * http://secondlifegrid.net/programs/open_source/licensing/flossexception
+ *
+ * By copying, modifying or distributing this software, you acknowledge
+ * that you have read and understood your obligations described above,
+ * and agree to abide by those obligations.
+ *
+ * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+ * COMPLETENESS OR PERFORMANCE.
* $/LicenseInfo$
*/
#include "../test/lltut.h"
#include "../llagentaccess.h"
-#include "llcontrolgroupreader.h"
+#include "llcontrol.h"
#include "indra_constants.h"
#include <iostream>
-class LLControlGroupReader_Test : public LLControlGroupReader
+//----------------------------------------------------------------------------
+// Implementation of enough of LLControlGroup to support the tests:
+
+static U32 test_preferred_maturity = SIM_ACCESS_PG;
+
+LLControlGroup::LLControlGroup(const std::string& name)
+ : LLInstanceTracker<LLControlGroup, std::string>(name)
{
-public:
- LLControlGroupReader_Test() : test_preferred_maturity(SIM_ACCESS_PG) {}
-
- virtual std::string getString(const std::string& name)
- {
- return "";
- }
- virtual std::string getText(const std::string& name)
- {
- return "";
- }
- virtual BOOL getBOOL(const std::string& name)
- {
- return false;
- }
- virtual S32 getS32(const std::string& name)
- {
- return 0;
- }
- virtual F32 getF32(const std::string& name)
- {
- return 0;
- }
- virtual U32 getU32(const std::string& name)
- {
- return test_preferred_maturity;
- }
-
- //--------------------------------------
- // Everything from here down is test code and not part of the interface
- void setPreferredMaturity(U32 m)
- {
- test_preferred_maturity = m;
- }
-private:
- U32 test_preferred_maturity;
-
-};
+}
+LLControlGroup::~LLControlGroup()
+{
+}
+
+// Implementation of just the LLControlGroup methods we requre
+BOOL LLControlGroup::declareU32(const std::string& name, U32 initial_val, const std::string& comment, BOOL persist)
+{
+ test_preferred_maturity = initial_val;
+ return true;
+}
+
+void LLControlGroup::setU32(const std::string& name, U32 val)
+{
+ test_preferred_maturity = val;
+}
+
+U32 LLControlGroup::getU32(const std::string& name)
+{
+ return test_preferred_maturity;
+}
+//----------------------------------------------------------------------------
+
namespace tut
{
struct agentaccess
@@ -69,20 +83,21 @@ namespace tut
template<> template<>
void agentaccess_object_t::test<1>()
{
- LLControlGroupReader_Test cgr;
+ LLControlGroup cgr("test");
+ cgr.declareU32("PreferredMaturity", SIM_ACCESS_PG, "declared_for_test", FALSE);
LLAgentAccess aa(cgr);
- cgr.setPreferredMaturity(SIM_ACCESS_PG);
+ cgr.setU32("PreferredMaturity", SIM_ACCESS_PG);
ensure("1 prefersPG", aa.prefersPG());
ensure("1 prefersMature", !aa.prefersMature());
ensure("1 prefersAdult", !aa.prefersAdult());
- cgr.setPreferredMaturity(SIM_ACCESS_MATURE);
+ cgr.setU32("PreferredMaturity", SIM_ACCESS_MATURE);
ensure("2 prefersPG", !aa.prefersPG());
ensure("2 prefersMature", aa.prefersMature());
ensure("2 prefersAdult", !aa.prefersAdult());
- cgr.setPreferredMaturity(SIM_ACCESS_ADULT);
+ cgr.setU32("PreferredMaturity", SIM_ACCESS_ADULT);
ensure("3 prefersPG", !aa.prefersPG());
ensure("3 prefersMature", aa.prefersMature());
ensure("3 prefersAdult", aa.prefersAdult());
@@ -91,7 +106,8 @@ namespace tut
template<> template<>
void agentaccess_object_t::test<2>()
{
- LLControlGroupReader_Test cgr;
+ LLControlGroup cgr("test");
+ cgr.declareU32("PreferredMaturity", SIM_ACCESS_PG, "declared_for_test", FALSE);
LLAgentAccess aa(cgr);
// make sure default is PG
@@ -140,7 +156,8 @@ namespace tut
template<> template<>
void agentaccess_object_t::test<3>()
{
- LLControlGroupReader_Test cgr;
+ LLControlGroup cgr("test");
+ cgr.declareU32("PreferredMaturity", SIM_ACCESS_PG, "declared_for_test", FALSE);
LLAgentAccess aa(cgr);
ensure("starts normal", !aa.isGodlike());
@@ -163,7 +180,8 @@ namespace tut
template<> template<>
void agentaccess_object_t::test<4>()
{
- LLControlGroupReader_Test cgr;
+ LLControlGroup cgr("test");
+ cgr.declareU32("PreferredMaturity", SIM_ACCESS_PG, "declared_for_test", FALSE);
LLAgentAccess aa(cgr);
ensure("1 pg to start", aa.wantsPGOnly());
@@ -188,12 +206,12 @@ namespace tut
ensure("2 mature pref pg", !aa.canAccessMature());
ensure("3 mature pref pg", !aa.canAccessAdult());
- cgr.setPreferredMaturity(SIM_ACCESS_MATURE);
+ cgr.setU32("PreferredMaturity", SIM_ACCESS_MATURE);
ensure("1 mature", !aa.wantsPGOnly());
ensure("2 mature", aa.canAccessMature());
ensure("3 mature", !aa.canAccessAdult());
- cgr.setPreferredMaturity(SIM_ACCESS_PG);
+ cgr.setU32("PreferredMaturity", SIM_ACCESS_PG);
ensure("1 mature pref pg", aa.wantsPGOnly());
ensure("2 mature pref pg", !aa.canAccessMature());
ensure("3 mature pref pg", !aa.canAccessAdult());
@@ -203,14 +221,14 @@ namespace tut
ensure("2 adult pref pg", !aa.canAccessMature());
ensure("3 adult pref pg", !aa.canAccessAdult());
- cgr.setPreferredMaturity(SIM_ACCESS_ADULT);
+ cgr.setU32("PreferredMaturity", SIM_ACCESS_ADULT);
ensure("1 adult", !aa.wantsPGOnly());
ensure("2 adult", aa.canAccessMature());
ensure("3 adult", aa.canAccessAdult());
// make sure that even if pref is high, if access is low we block access
// this shouldn't occur in real life but we want to be safe
- cgr.setPreferredMaturity(SIM_ACCESS_ADULT);
+ cgr.setU32("PreferredMaturity", SIM_ACCESS_ADULT);
aa.setMaturity('P');
ensure("1 pref adult, actual pg", aa.wantsPGOnly());
ensure("2 pref adult, actual pg", !aa.canAccessMature());
@@ -221,7 +239,8 @@ namespace tut
template<> template<>
void agentaccess_object_t::test<5>()
{
- LLControlGroupReader_Test cgr;
+ LLControlGroup cgr("test");
+ cgr.declareU32("PreferredMaturity", SIM_ACCESS_PG, "declared_for_test", FALSE);
LLAgentAccess aa(cgr);
ensure("1 transition starts false", !aa.isInTransition());
@@ -229,6 +248,20 @@ namespace tut
ensure("2 transition now true", aa.isInTransition());
}
+ template<> template<>
+ void agentaccess_object_t::test<6>()
+ {
+ LLControlGroup cgr("test");
+ cgr.declareU32("PreferredMaturity", SIM_ACCESS_PG, "declared_for_test", FALSE);
+ LLAgentAccess aa(cgr);
+
+ cgr.setU32("PreferredMaturity", SIM_ACCESS_ADULT);
+ aa.setMaturity('M');
+ ensure("1 preferred maturity pegged to M when maturity is M", cgr.getU32("PreferredMaturity") == SIM_ACCESS_MATURE);
+
+ aa.setMaturity('P');
+ ensure("1 preferred maturity pegged to P when maturity is P", cgr.getU32("PreferredMaturity") == SIM_ACCESS_PG);
+ }
}
diff --git a/indra/newview/viewer_manifest.py b/indra/newview/viewer_manifest.py
index 38685ecbb1..ae3b1ba43e 100755
--- a/indra/newview/viewer_manifest.py
+++ b/indra/newview/viewer_manifest.py
@@ -77,6 +77,10 @@ class ViewerManifest(LLManifest):
self.path("paths.xml")
# include the entire textures directory recursively
if self.prefix(src="*/textures"):
+ self.path("*/*.tga")
+ self.path("*/*.j2c")
+ self.path("*/*.jpg")
+ self.path("*/*.png")
self.path("*.tga")
self.path("*.j2c")
self.path("*.jpg")
@@ -84,6 +88,7 @@ class ViewerManifest(LLManifest):
self.path("textures.xml")
self.end_prefix("*/textures")
self.path("*/xui/*/*.xml")
+ self.path("*/xui/*/widgets/*.xml")
self.path("*/*.xml")
# Local HTML files (e.g. loading screen)
@@ -188,7 +193,42 @@ class WindowsManifest(ViewerManifest):
self.path("openjpeg.dll")
self.end_prefix()
- # Mozilla appears to force a dependency on these files so we need to ship it (CP) - updated to vc8 versions (nyx)
+ # Plugin host application
+ if self.prefix(src='../llplugin/slplugin/%s' % self.args['configuration'], dst="llplugin"):
+ self.path("slplugin.exe")
+ self.end_prefix()
+
+ # Media plugins - QuickTime
+ if self.prefix(src='../media_plugins/quicktime/%s' % self.args['configuration'], dst="llplugin"):
+ self.path("media_plugin_quicktime.dll")
+ self.end_prefix()
+
+ # Media plugins - WebKit/Qt
+ if self.prefix(src='../media_plugins/webkit/%s' % self.args['configuration'], dst="llplugin"):
+ self.path("media_plugin_webkit.dll")
+ self.end_prefix()
+
+ # For WebKit/Qt plugin runtimes
+ if self.prefix(src="../../libraries/i686-win32/lib/release", dst="llplugin"):
+ self.path("libeay32.dll")
+ self.path("qtcore4.dll")
+ self.path("qtgui4.dll")
+ self.path("qtnetwork4.dll")
+ self.path("qtopengl4.dll")
+ self.path("qtwebkit4.dll")
+ self.path("ssleay32.dll")
+ self.end_prefix()
+
+ # For WebKit/Qt plugin runtimes (image format plugins)
+ if self.prefix(src="../../libraries/i686-win32/lib/release/imageformats", dst="llplugin/imageformats"):
+ self.path("qgif4.dll")
+ self.path("qico4.dll")
+ self.path("qjpeg4.dll")
+ self.path("qmng4.dll")
+ self.path("qsvg4.dll")
+ self.path("qtiff4.dll")
+ self.end_prefix()
+
# These need to be installed as a SxS assembly, currently a 'private' assembly.
# See http://msdn.microsoft.com/en-us/library/ms235291(VS.80).aspx
if self.prefix(src=self.args['configuration'], dst=""):
@@ -202,36 +242,8 @@ class WindowsManifest(ViewerManifest):
self.path("Microsoft.VC80.CRT.manifest")
self.end_prefix()
- # Mozilla runtime DLLs (CP)
- if self.prefix(src="../../libraries/i686-win32/lib/release", dst=""):
- self.path("freebl3.dll")
- self.path("js3250.dll")
- self.path("nspr4.dll")
- self.path("nss3.dll")
- self.path("nssckbi.dll")
- self.path("plc4.dll")
- self.path("plds4.dll")
- self.path("smime3.dll")
- self.path("softokn3.dll")
- self.path("ssl3.dll")
- self.path("xpcom.dll")
- self.path("xul.dll")
- self.end_prefix()
-
- # Mozilla runtime misc files (CP)
- if self.prefix(src="app_settings/mozilla"):
- self.path("chrome/*.*")
- self.path("components/*.*")
- self.path("greprefs/*.*")
- self.path("plugins/*.*")
- self.path("res/*.*")
- self.path("res/*/*")
- self.end_prefix()
-
- # Mozilla hack to get it to accept newer versions of msvc*80.dll than are listed in manifest
- # necessary as llmozlib2-vc80.lib refers to an old version of msvc*80.dll - can be removed when new version of llmozlib is built - Nyx
# The config file name needs to match the exe's name.
- self.path("SecondLife.exe.config", dst=self.final_exe() + ".config")
+ self.path(src="%s/secondlife-bin.exe.config" % self.args['configuration'], dst=self.final_exe() + ".config")
# Vivox runtimes
if self.prefix(src="vivox-runtime/i686-win32", dst=""):
@@ -255,9 +267,9 @@ class WindowsManifest(ViewerManifest):
dst="updater.exe")
# For google-perftools tcmalloc allocator.
- #if self.prefix(src="../../libraries/i686-win32/lib/release", dst=""):
- # self.path("libtcmalloc_minimal.dll")
- # self.end_prefix()
+ if self.prefix(src="../../libraries/i686-win32/lib/release", dst=""):
+ self.path("libtcmalloc_minimal.dll")
+ self.end_prefix()
def nsi_file_commands(self, install=True):
@@ -398,21 +410,11 @@ class DarwinManifest(ViewerManifest):
self.path(self.args['configuration'] + "/Second Life.app", dst="")
if self.prefix(src="", dst="Contents"): # everything goes in Contents
- # Expand the tar file containing the assorted mozilla bits into
- # <bundle>/Contents/MacOS/
- self.contents_of_tar(self.args['source']+'/mozilla-universal-darwin.tgz', 'MacOS')
-
self.path("Info-SecondLife.plist", dst="Info.plist")
# copy additional libs in <bundle>/Contents/MacOS/
self.path("../../libraries/universal-darwin/lib_release/libndofdev.dylib", dst="MacOS/libndofdev.dylib")
- # replace the default theme with our custom theme (so scrollbars work).
- if self.prefix(src="mozilla-theme", dst="MacOS/chrome"):
- self.path("classic.jar")
- self.path("classic.manifest")
- self.end_prefix("MacOS/chrome")
-
# most everything goes in the Resources directory
if self.prefix(src="", dst="Resources"):
super(DarwinManifest, self).construct()
@@ -475,6 +477,15 @@ class DarwinManifest(ViewerManifest):
self.path("../mac_crash_logger/" + self.args['configuration'] + "/mac-crash-logger.app", "mac-crash-logger.app")
self.path("../mac_updater/" + self.args['configuration'] + "/mac-updater.app", "mac-updater.app")
+ # plugins
+ if self.prefix(src="", dst="llplugin"):
+ self.path("../llplugin/slplugin/" + self.args['configuration'] + "/SLPlugin", "SLPlugin")
+ self.path("../media_plugins/quicktime/" + self.args['configuration'] + "/media_plugin_quicktime.dylib", "media_plugin_quicktime.dylib")
+ self.path("../media_plugins/webkit/" + self.args['configuration'] + "/media_plugin_webkit.dylib", "media_plugin_webkit.dylib")
+ self.path("../../libraries/universal-darwin/lib_release/libllqtwebkit.dylib", "libllqtwebkit.dylib")
+
+ self.end_prefix("llplugin")
+
# command line arguments for connecting to the proper grid
self.put_in_file(self.flags_list(), 'arguments.txt')
@@ -517,7 +528,7 @@ class DarwinManifest(ViewerManifest):
# make sure we don't have stale files laying about
self.remove(sparsename, finalname)
- self.run_command('hdiutil create "%(sparse)s" -volname "%(vol)s" -fs HFS+ -type SPARSE -megabytes 300 -layout SPUD' % {
+ self.run_command('hdiutil create "%(sparse)s" -volname "%(vol)s" -fs HFS+ -type SPARSE -megabytes 400 -layout SPUD' % {
'sparse':sparsename,
'vol':volname})
@@ -588,12 +599,15 @@ class LinuxManifest(ViewerManifest):
self.path("client-readme-voice.txt","README-linux-voice.txt")
self.path("client-readme-joystick.txt","README-linux-joystick.txt")
self.path("wrapper.sh","secondlife")
- self.path("handle_secondlifeprotocol.sh")
- self.path("register_secondlifeprotocol.sh")
+ self.path("handle_secondlifeprotocol.sh", "etc/handle_secondlifeprotocol.sh")
+ self.path("register_secondlifeprotocol.sh", "etc/register_secondlifeprotocol.sh")
+ self.path("refresh_desktop_app_entry.sh", "etc/refresh_desktop_app_entry.sh")
+ self.path("launch_url.sh","etc/launch_url.sh")
+ self.path("install.sh")
self.end_prefix("linux_tools")
# Create an appropriate gridargs.dat for this package, denoting required grid.
- self.put_in_file(self.flags_list(), 'gridargs.dat')
+ self.put_in_file(self.flags_list(), 'etc/gridargs.dat')
def package_finish(self):
@@ -654,20 +668,25 @@ class Linux_i686Manifest(LinuxManifest):
pass
self.path("secondlife-stripped","bin/do-not-directly-run-secondlife-bin")
- self.path("../linux_crash_logger/linux-crash-logger-stripped","linux-crash-logger.bin")
- self.path("linux_tools/launch_url.sh","launch_url.sh")
+ self.path("../linux_crash_logger/linux-crash-logger-stripped","bin/linux-crash-logger.bin")
+ self.path("../linux_updater/linux-updater-stripped", "bin/linux-updater.bin")
if self.prefix("res-sdl"):
self.path("*")
# recurse
self.end_prefix("res-sdl")
+ # plugins
+ if self.prefix(src="", dst="bin/llplugin"):
+ self.path("../llplugin/slplugin/SLPlugin", "SLPlugin")
+ self.path("../media_plugins/webkit/libmedia_plugin_webkit.so", "libmedia_plugin_webkit.so")
+ self.path("../media_plugins/gstreamer010/libmedia_plugin_gstreamer010.so", "libmedia_plugin_quicktime.so")
+ self.end_prefix("bin/llplugin")
+
self.path("featuretable_linux.txt")
#self.path("secondlife-i686.supp")
- self.path("app_settings/mozilla-runtime-linux-i686")
-
if self.prefix("../../libraries/i686-linux/lib_release_client", dst="lib"):
- self.path("libkdu_v42R.so", "libkdu.so")
+ #self.path("libkdu_v42R.so", "libkdu.so")
self.path("libfmod-3.75.so")
self.path("libapr-1.so.0")
self.path("libaprutil-1.so.0")
@@ -697,7 +716,6 @@ class Linux_x86_64Manifest(LinuxManifest):
super(Linux_x86_64Manifest, self).construct()
self.path("secondlife-stripped","bin/do-not-directly-run-secondlife-bin")
self.path("../linux_crash_logger/linux-crash-logger-stripped","linux-crash-logger.bin")
- self.path("linux_tools/launch_url.sh","launch_url.sh")
if self.prefix("res-sdl"):
self.path("*")
# recurse
diff --git a/indra/test/CMakeLists.txt b/indra/test/CMakeLists.txt
index 53109ca196..98ad8af02d 100644
--- a/indra/test/CMakeLists.txt
+++ b/indra/test/CMakeLists.txt
@@ -34,10 +34,13 @@ set(test_SOURCE_FILES
io.cpp
# llapp_tut.cpp # Temporarily removed until thread issues can be solved
llbase64_tut.cpp
+ llbbox_tut.cpp
+ llbboxlocal_tut.cpp
llblowfish_tut.cpp
llbuffer_tut.cpp
lldate_tut.cpp
lldependencies_tut.cpp
+ lldoubledispatch_tut.cpp
llerror_tut.cpp
llevents_tut.cpp
llhost_tut.cpp
@@ -55,6 +58,7 @@ set(test_SOURCE_FILES
llpipeutil.cpp
llquaternion_tut.cpp
llrandom_tut.cpp
+ llrect_tut.cpp
llsaleinfo_tut.cpp
llscriptresource_tut.cpp
llsdmessagebuilder_tut.cpp
@@ -69,6 +73,7 @@ set(test_SOURCE_FILES
lltimestampcache_tut.cpp
lltiming_tut.cpp
lltranscode_tut.cpp
+ lltreeiterators_tut.cpp
lltut.cpp
lluri_tut.cpp
lluuidhashmap_tut.cpp
@@ -127,7 +132,10 @@ target_link_libraries(test
${APRICONV_LIBRARIES}
${PTHREAD_LIBRARY}
${WINDOWS_LIBRARIES}
+ ${BOOST_PROGRAM_OPTIONS_LIBRARY}
+ ${BOOST_REGEX_LIBRARY}
${DL_LIBRARY}
+ ${GOOGLE_PERFTOOLS_LIBRARIES}
)
if (WINDOWS)
diff --git a/indra/test/lldoubledispatch_tut.cpp b/indra/test/lldoubledispatch_tut.cpp
new file mode 100755
index 0000000000..63ef4d4497
--- /dev/null
+++ b/indra/test/lldoubledispatch_tut.cpp
@@ -0,0 +1,245 @@
+/**
+ * @file lldoubledispatch_tut.cpp
+ * @author Nat Goodspeed
+ * @date 2008-11-13
+ * @brief Test for lldoubledispatch.h
+ *
+ * This program tests the DoubleDispatch class, using a variation on the example
+ * from Scott Meyers' "More Effective C++", Item 31.
+ *
+ * $LicenseInfo:firstyear=2008&license=viewergpl$
+ *
+ * Copyright (c) 2008-2009, Linden Research, Inc.
+ *
+ * Second Life Viewer Source Code
+ * The source code in this file ("Source Code") is provided by Linden Lab
+ * to you under the terms of the GNU General Public License, version 2.0
+ * ("GPL"), unless you have obtained a separate licensing agreement
+ * ("Other License"), formally executed by you and Linden Lab. Terms of
+ * the GPL can be found in doc/GPL-license.txt in this distribution, or
+ * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
+ *
+ * There are special exceptions to the terms and conditions of the GPL as
+ * it is applied to this Source Code. View the full text of the exception
+ * in the file doc/FLOSS-exception.txt in this software distribution, or
+ * online at
+ * http://secondlifegrid.net/programs/open_source/licensing/flossexception
+ *
+ * By copying, modifying or distributing this software, you acknowledge
+ * that you have read and understood your obligations described above,
+ * and agree to abide by those obligations.
+ *
+ * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+ * COMPLETENESS OR PERFORMANCE.
+ * $/LicenseInfo$
+ */
+
+// Precompiled header
+#include "linden_common.h"
+// associated header
+#include "lldoubledispatch.h"
+// STL headers
+// std headers
+#include <string>
+#include <iostream>
+#include <typeinfo>
+// external library headers
+// other Linden headers
+#include "lltut.h"
+
+
+/*---------------------------- Class hierarchy -----------------------------*/
+// All objects are GameObjects.
+class GameObject
+{
+public:
+ GameObject(const std::string& name): mName(name) {}
+ virtual ~GameObject() {}
+ virtual std::string stringize() { return std::string(typeid(*this).name()) + " " + mName; }
+
+protected:
+ std::string mName;
+};
+
+// SpaceStation, Asteroid and SpaceShip are peer GameObjects.
+struct SpaceStation: public GameObject
+{
+ SpaceStation(const std::string& name): GameObject(name) {}
+ // Only a dummy SpaceStation is constructed without a name
+ SpaceStation(): GameObject("dummy") {}
+};
+
+struct Asteroid: public GameObject
+{
+ Asteroid(const std::string& name): GameObject(name) {}
+ Asteroid(): GameObject("dummy") {}
+};
+
+struct SpaceShip: public GameObject
+{
+ SpaceShip(const std::string& name): GameObject(name) {}
+ SpaceShip(): GameObject("dummy") {}
+};
+
+// SpaceShip is specialized further into CommercialShip and MilitaryShip.
+struct CommercialShip: public SpaceShip
+{
+ CommercialShip(const std::string& name): SpaceShip(name) {}
+ CommercialShip(): SpaceShip("dummy") {}
+};
+
+struct MilitaryShip: public SpaceShip
+{
+ MilitaryShip(const std::string& name): SpaceShip(name) {}
+ MilitaryShip(): SpaceShip("dummy") {}
+};
+
+/*-------------------------- Collision functions ---------------------------*/
+// This mechanism permits us to overcome a limitation of Meyers' approach: we
+// can declare the parameter types exactly as we want, rather than having to
+// make them all GameObject& parameters.
+std::string shipAsteroid(SpaceShip& ship, Asteroid& rock)
+{
+// std::cout << rock.stringize() << " has pulverized " << ship.stringize() << std::endl;
+ return "shipAsteroid";
+}
+
+std::string militaryShipAsteroid(MilitaryShip& ship, Asteroid& rock)
+{
+// std::cout << rock.stringize() << " has severely damaged " << ship.stringize() << std::endl;
+ return "militaryShipAsteroid";
+}
+
+std::string shipStation(SpaceShip& ship, SpaceStation& dock)
+{
+// std::cout << ship.stringize() << " has docked at " << dock.stringize() << std::endl;
+ return "shipStation";
+}
+
+std::string asteroidStation(Asteroid& rock, SpaceStation& dock)
+{
+// std::cout << rock.stringize() << " has damaged " << dock.stringize() << std::endl;
+ return "asteroidStation";
+}
+
+/*------------------------------- Test code --------------------------------*/
+namespace tut
+{
+ struct dispatch_data
+ {
+ dispatch_data():
+ home(new SpaceStation("Terra Station")),
+ obstacle(new Asteroid("Ganymede")),
+ tug(new CommercialShip("Pilotfish")),
+ patrol(new MilitaryShip("Enterprise"))
+ {}
+
+ // Instantiate and populate the DoubleDispatch object.
+ typedef LLDoubleDispatch<std::string, GameObject> DD;
+ DD dispatcher;
+
+ // Instantiate a few GameObjects. Make sure we refer to them
+ // polymorphically, and don't let them leak.
+ std::auto_ptr<GameObject> home;
+ std::auto_ptr<GameObject> obstacle;
+ std::auto_ptr<GameObject> tug;
+ std::auto_ptr<GameObject> patrol;
+
+ // prototype objects
+ Asteroid dummyAsteroid;
+ SpaceShip dummyShip;
+ MilitaryShip dummyMilitary;
+ CommercialShip dummyCommercial;
+ SpaceStation dummyStation;
+ };
+ typedef test_group<dispatch_data> dispatch_group;
+ typedef dispatch_group::object dispatch_object;
+ tut::dispatch_group ddgr("double dispatch");
+
+ template<> template<>
+ void dispatch_object::test<1>()
+ {
+ // Describe param types using explicit DD::Type objects
+ // (order-sensitive add() variant)
+ dispatcher.add(DD::Type<SpaceShip>(), DD::Type<Asteroid>(), shipAsteroid, true);
+ // naive adding, won't work
+ dispatcher.add(DD::Type<MilitaryShip>(), DD::Type<Asteroid>(), militaryShipAsteroid, true);
+ dispatcher.add(DD::Type<SpaceShip>(), DD::Type<SpaceStation>(), shipStation, true);
+ dispatcher.add(DD::Type<Asteroid>(), DD::Type<SpaceStation>(), asteroidStation, true);
+
+ // Try colliding them.
+ ensure_equals(dispatcher(*home, *tug), // reverse params, SpaceShip subclass
+ "shipStation");
+ ensure_equals(dispatcher(*patrol, *home), // forward params, SpaceShip subclass
+ "shipStation");
+ ensure_equals(dispatcher(*obstacle, *home), // forward params
+ "asteroidStation");
+ ensure_equals(dispatcher(*home, *obstacle), // reverse params
+ "asteroidStation");
+ ensure_equals(dispatcher(*tug, *obstacle), // forward params, SpaceShip subclass
+ "shipAsteroid");
+ ensure_equals(dispatcher(*obstacle, *patrol), // reverse params, SpaceShip subclass
+ // won't use militaryShipAsteroid() because it was added
+ // in wrong order
+ "shipAsteroid");
+ }
+
+ template<> template<>
+ void dispatch_object::test<2>()
+ {
+ // Describe param types using explicit DD::Type objects
+ // (order-sensitive add() variant)
+ // adding in correct order
+ dispatcher.add(DD::Type<MilitaryShip>(), DD::Type<Asteroid>(), militaryShipAsteroid, true);
+ dispatcher.add(DD::Type<SpaceShip>(), DD::Type<Asteroid>(), shipAsteroid, true);
+ dispatcher.add(DD::Type<SpaceShip>(), DD::Type<SpaceStation>(), shipStation, true);
+ dispatcher.add(DD::Type<Asteroid>(), DD::Type<SpaceStation>(), asteroidStation, true);
+
+ ensure_equals(dispatcher(*patrol, *obstacle), "militaryShipAsteroid");
+ ensure_equals(dispatcher(*tug, *obstacle), "shipAsteroid");
+ }
+
+ template<> template<>
+ void dispatch_object::test<3>()
+ {
+ // Describe param types with actual prototype instances
+ // (order-insensitive add() variant)
+ dispatcher.add(dummyMilitary, dummyAsteroid, militaryShipAsteroid);
+ dispatcher.add(dummyShip, dummyAsteroid, shipAsteroid);
+ dispatcher.add(dummyShip, dummyStation, shipStation);
+ dispatcher.add(dummyAsteroid, dummyStation, asteroidStation);
+
+ ensure_equals(dispatcher(*patrol, *obstacle), "militaryShipAsteroid");
+ ensure_equals(dispatcher(*tug, *obstacle), "shipAsteroid");
+ ensure_equals(dispatcher(*obstacle, *patrol), "");
+ }
+
+ template<> template<>
+ void dispatch_object::test<4>()
+ {
+ // Describe param types with actual prototype instances
+ // (order-insensitive add() variant)
+ dispatcher.add(dummyShip, dummyAsteroid, shipAsteroid);
+ // Even if we add the militaryShipAsteroid in the wrong order, it
+ // should still work.
+ dispatcher.add(dummyMilitary, dummyAsteroid, militaryShipAsteroid);
+ dispatcher.add(dummyShip, dummyStation, shipStation);
+ dispatcher.add(dummyAsteroid, dummyStation, asteroidStation);
+
+ ensure_equals(dispatcher(*patrol, *obstacle), "militaryShipAsteroid");
+ ensure_equals(dispatcher(*tug, *obstacle), "shipAsteroid");
+ }
+
+ template<> template<>
+ void dispatch_object::test<5>()
+ {
+ dispatcher.add<SpaceShip, Asteroid>(shipAsteroid);
+ dispatcher.add<MilitaryShip, Asteroid>(militaryShipAsteroid);
+ dispatcher.add<SpaceShip, SpaceStation>(shipStation);
+ dispatcher.add<Asteroid, SpaceStation>(asteroidStation);
+
+ ensure_equals(dispatcher(*patrol, *obstacle), "militaryShipAsteroid");
+ ensure_equals(dispatcher(*tug, *obstacle), "shipAsteroid");
+ }
+} // namespace tut
diff --git a/indra/test/llhttpclient_tut.cpp b/indra/test/llhttpclient_tut.cpp
index d1bf8ae5a9..c541997e89 100644
--- a/indra/test/llhttpclient_tut.cpp
+++ b/indra/test/llhttpclient_tut.cpp
@@ -59,8 +59,8 @@ namespace tut
class LLSDStorageNode : public LLHTTPNode
{
public:
- LLSD get() const { return storage; }
- LLSD put(const LLSD& value) const { storage = value; return LLSD(); }
+ LLSD simpleGet() const { return storage; }
+ LLSD simplePut(const LLSD& value) const { storage = value; return LLSD(); }
};
class ErrorNode : public LLHTTPNode
diff --git a/indra/test/llhttpdate_tut.cpp b/indra/test/llhttpdate_tut.cpp
index b764696dae..b9733dc030 100644
--- a/indra/test/llhttpdate_tut.cpp
+++ b/indra/test/llhttpdate_tut.cpp
@@ -50,6 +50,7 @@ namespace tut
template<> template<>
void httpdate_object::test<1>()
{
+
static std::string epoch_expected = "Thursday, 01 Jan 1970 00:00:00 GMT" ;
ensure("Check Epoch in RFC 1123", ( epoch_expected == some_date.asRFC1123()));
}
@@ -57,6 +58,7 @@ namespace tut
template<> template<>
void httpdate_object::test<2>()
{
+
static std::string expected = "Wednesday, 18 Jul 2007 22:17:24 GMT" ;
some_date = LLDate(1184797044.037586);
ensure("Check some timestamp in RFC 1123", ( expected == some_date.asRFC1123()));
@@ -66,6 +68,7 @@ namespace tut
template<> template<>
void httpdate_object::test<3>()
{
+
//F64 sometime = LLFrameTimer::getTotalSeconds();
time_t sometime;
time(&sometime);
diff --git a/indra/test/llpermissions_tut.cpp b/indra/test/llpermissions_tut.cpp
index 9dbb9642dd..4eadc64b5a 100644
--- a/indra/test/llpermissions_tut.cpp
+++ b/indra/test/llpermissions_tut.cpp
@@ -485,15 +485,8 @@ namespace tut
template<> template<>
void permission_object_t::test<22>()
{
- LLPermissions perm,perm1;
- LLUUID creator("abf0d56b-82e5-47a2-a8ad-74741bb2c29e");
- LLUUID owner("68edcf47-ccd7-45b8-9f90-1649d7f12806");
- LLUUID lastOwner("5e47a0dc-97bf-44e0-8b40-de06718cee9d");
- LLUUID group("9c8eca51-53d5-42a7-bb58-cef070395db8");
- perm.init(creator,owner,lastOwner,group);
- LLXMLNode* xml_node = perm.exportFileXML();
- perm1.importXML(xml_node);
- ensure("exportFileXML()/importXML():failed to export and import the data ", perm1 == perm);
+ // Deleted LLPermissions::exportFileXML() and LLPermissions::importXML()
+ // because I can't find any non-test code references to it. 2009-05-04 JC
}
template<> template<>
diff --git a/indra/test/llsaleinfo_tut.cpp b/indra/test/llsaleinfo_tut.cpp
index 7f8219cdc8..fa5e047513 100644
--- a/indra/test/llsaleinfo_tut.cpp
+++ b/indra/test/llsaleinfo_tut.cpp
@@ -167,19 +167,8 @@ namespace tut
template<> template<>
void llsaleinfo_test_t::test<4>()
{
-// LLXMLNode is teh suck.
-#if 0
- S32 sale_price = 23445;
- LLSaleInfo saleinfo(LLSaleInfo::FS_CONTENTS, sale_price);
-
- LLXMLNode* x_node = saleinfo.exportFileXML();
-
- LLSaleInfo saleinfo1(LLSaleInfo::FS_NOT, 0);
-
- saleinfo1.importXML(x_node);
- ensure_equals("1.importXML() fn failed", saleinfo.getSalePrice(), saleinfo1.getSalePrice());
- ensure_equals("2.importXML() fn failed", saleinfo.getSaleType(), saleinfo1.getSaleType());
-#endif
+ // Deleted LLSaleInfo::exportFileXML() and LLSaleInfo::importXML()
+ // because I can't find any non-test code references to it. 2009-05-04 JC
}
template<> template<>
diff --git a/indra/test/llscriptresource_tut.cpp b/indra/test/llscriptresource_tut.cpp
index e384c275a3..705fdd16ae 100644
--- a/indra/test/llscriptresource_tut.cpp
+++ b/indra/test/llscriptresource_tut.cpp
@@ -4,7 +4,7 @@
*
* $LicenseInfo:firstyear=2008&license=viewergpl$
*
- * Copyright (c) 2006-2007, Linden Research, Inc.
+ * Copyright (c) 2008-2009, Linden Research, Inc.
*
* Second Life Viewer Source Code
* The source code in this file ("Source Code") is provided by Linden Lab
@@ -12,12 +12,13 @@
* ("GPL"), unless you have obtained a separate licensing agreement
* ("Other License"), formally executed by you and Linden Lab. Terms of
* the GPL can be found in doc/GPL-license.txt in this distribution, or
- * online at http://secondlife.com/developers/opensource/gplv2
+ * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
*
* There are special exceptions to the terms and conditions of the GPL as
* it is applied to this Source Code. View the full text of the exception
* in the file doc/FLOSS-exception.txt in this software distribution, or
- * online at http://secondlife.com/developers/opensource/flossexception
+ * online at
+ * http://secondlifegrid.net/programs/open_source/licensing/flossexception
*
* By copying, modifying or distributing this software, you acknowledge
* that you have read and understood your obligations described above,
diff --git a/indra/test/lltimestampcache_tut.cpp b/indra/test/lltimestampcache_tut.cpp
index 9e0de0fe60..3b102a3366 100644
--- a/indra/test/lltimestampcache_tut.cpp
+++ b/indra/test/lltimestampcache_tut.cpp
@@ -5,7 +5,7 @@
*
* $LicenseInfo:firstyear=2008&license=viewergpl$
*
- * Copyright (c) 2008, Linden Research, Inc.
+ * Copyright (c) 2008-2009, Linden Research, Inc.
*
* Second Life Viewer Source Code
* The source code in this file ("Source Code") is provided by Linden Lab
@@ -13,12 +13,13 @@
* ("GPL"), unless you have obtained a separate licensing agreement
* ("Other License"), formally executed by you and Linden Lab. Terms of
* the GPL can be found in doc/GPL-license.txt in this distribution, or
- * online at http://secondlife.com/developers/opensource/gplv2
+ * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
*
* There are special exceptions to the terms and conditions of the GPL as
* it is applied to this Source Code. View the full text of the exception
* in the file doc/FLOSS-exception.txt in this software distribution, or
- * online at http://secondlife.com/developers/opensource/flossexception
+ * online at
+ * http://secondlifegrid.net/programs/open_source/licensing/flossexception
*
* By copying, modifying or distributing this software, you acknowledge
* that you have read and understood your obligations described above,
diff --git a/indra/test/lltranscode_tut.cpp b/indra/test/lltranscode_tut.cpp
index 8abf9dc224..eb21979db0 100644
--- a/indra/test/lltranscode_tut.cpp
+++ b/indra/test/lltranscode_tut.cpp
@@ -4,7 +4,7 @@
*
* $LicenseInfo:firstyear=2008&license=viewergpl$
*
- * Copyright (c) 2006-2007, Linden Research, Inc.
+ * Copyright (c) 2008-2009, Linden Research, Inc.
*
* Second Life Viewer Source Code
* The source code in this file ("Source Code") is provided by Linden Lab
@@ -12,12 +12,13 @@
* ("GPL"), unless you have obtained a separate licensing agreement
* ("Other License"), formally executed by you and Linden Lab. Terms of
* the GPL can be found in doc/GPL-license.txt in this distribution, or
- * online at http://secondlife.com/developers/opensource/gplv2
+ * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
*
* There are special exceptions to the terms and conditions of the GPL as
* it is applied to this Source Code. View the full text of the exception
* in the file doc/FLOSS-exception.txt in this software distribution, or
- * online at http://secondlife.com/developers/opensource/flossexception
+ * online at
+ * http://secondlifegrid.net/programs/open_source/licensing/flossexception
*
* By copying, modifying or distributing this software, you acknowledge
* that you have read and understood your obligations described above,
diff --git a/indra/test/test.h b/indra/test/test.h
index 16ec4effcf..cee185140c 100644
--- a/indra/test/test.h
+++ b/indra/test/test.h
@@ -13,12 +13,13 @@
* ("GPL"), unless you have obtained a separate licensing agreement
* ("Other License"), formally executed by you and Linden Lab. Terms of
* the GPL can be found in doc/GPL-license.txt in this distribution, or
- * online at http://secondlife.com/developers/opensource/gplv2
+ * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
*
* There are special exceptions to the terms and conditions of the GPL as
* it is applied to this Source Code. View the full text of the exception
* in the file doc/FLOSS-exception.txt in this software distribution, or
- * online at http://secondlife.com/developers/opensource/flossexception
+ * online at
+ * http://secondlifegrid.net/programs/open_source/licensing/flossexception
*
* By copying, modifying or distributing this software, you acknowledge
* that you have read and understood your obligations described above,
diff --git a/indra/test_apps/llplugintest/CMakeLists.txt b/indra/test_apps/llplugintest/CMakeLists.txt
new file mode 100644
index 0000000000..789ead04fe
--- /dev/null
+++ b/indra/test_apps/llplugintest/CMakeLists.txt
@@ -0,0 +1,342 @@
+# -*- cmake -*-
+
+project(llplugintest)
+
+include(00-Common)
+include(FindOpenGL)
+include(LLCommon)
+include(LLPlugin)
+include(Linking)
+include(PluginAPI)
+include(LLImage)
+include(LLMath)
+include(LLMessage)
+include(LLRender)
+include(LLWindow)
+include(Glut)
+include(Glui)
+
+include_directories(
+ ${LLPLUGIN_INCLUDE_DIRS}
+ ${LLCOMMON_INCLUDE_DIRS}
+ ${LLIMAGE_INCLUDE_DIRS}
+ ${LLMATH_INCLUDE_DIRS}
+ ${LLMESSAGE_INCLUDE_DIRS}
+ ${LLRENDER_INCLUDE_DIRS}
+ ${LLWINDOW_INCLUDE_DIRS}
+)
+
+if (DARWIN)
+ include(CMakeFindFrameworks)
+ find_library(CARBON_LIBRARY Carbon)
+endif (DARWIN)
+
+### demo_plugin
+
+#set(demo_plugin_SOURCE_FILES
+# demo_plugin.cpp
+# )
+#
+#add_library(demo_plugin
+# SHARED
+# ${demo_plugin_SOURCE_FILES}
+#)
+#
+#target_link_libraries(demo_plugin
+# ${LLPLUGIN_LIBRARIES}
+# ${LLCOMMON_LIBRARIES}
+# ${PLUGIN_API_WINDOWS_LIBRARIES}
+#)
+#
+#add_dependencies(demo_plugin
+# ${LLPLUGIN_LIBRARIES}
+# ${LLCOMMON_LIBRARIES}
+#)
+#
+#if (DARWIN)
+# # Don't prepend 'lib' to the executable name, and don't embed a full path in the library's install name
+# set_target_properties(
+# demo_plugin
+# PROPERTIES
+# PREFIX ""
+# BUILD_WITH_INSTALL_RPATH 1
+# INSTALL_NAME_DIR "@executable_path"
+# )
+#endif (DARWIN)
+
+### plugin_host
+
+#set(plugin_host_SOURCE_FILES
+# plugin_host.cpp
+# )
+#
+#add_executable(plugin_host
+# WIN32
+# ${plugin_host_SOURCE_FILES}
+#)
+#
+#set_target_properties(plugin_host
+# PROPERTIES
+# WIN32_EXECUTABLE
+# FALSE
+#)
+#
+#target_link_libraries(plugin_host
+# ${LLPLUGIN_LIBRARIES}
+# ${LLCOMMON_LIBRARIES}
+# ${PLUGIN_API_WINDOWS_LIBRARIES}
+#)
+#
+#add_dependencies(plugin_host
+# demo_plugin
+# ${LLPLUGIN_LIBRARIES}
+# ${LLCOMMON_LIBRARIES}
+#)
+
+### plugin_process_launcher
+
+#set(plugin_process_launcher_SOURCE_FILES
+# plugin_process_launcher.cpp
+# )
+#
+#add_executable(plugin_process_launcher
+# WIN32
+# ${plugin_process_launcher_SOURCE_FILES}
+#)
+#
+#set_target_properties(plugin_process_launcher
+# PROPERTIES
+# WIN32_EXECUTABLE
+# FALSE
+#)
+#
+#target_link_libraries(plugin_process_launcher
+# ${LLPLUGIN_LIBRARIES}
+# ${LLMESSAGE_LIBRARIES}
+# ${LLCOMMON_LIBRARIES}
+# ${PLUGIN_API_WINDOWS_LIBRARIES}
+#)
+#
+#add_dependencies(plugin_process_launcher
+# SLPlugin
+# demo_plugin
+# ${LLPLUGIN_LIBRARIES}
+# ${LLMESSAGE_LIBRARIES}
+# ${LLCOMMON_LIBRARIES}
+#)
+
+### media_simple_test
+
+#set(media_simple_test_SOURCE_FILES
+# media_simple_test.cpp
+# )
+#
+#add_executable(media_simple_test
+# WIN32
+# ${media_simple_test_SOURCE_FILES}
+#)
+#
+#add_dependencies(media_simple_test copy_win_libs)
+#
+#set_target_properties(media_simple_test
+# PROPERTIES
+# WIN32_EXECUTABLE
+# FALSE
+#)
+#
+#target_link_libraries(media_simple_test
+# ${GLUT_LIBRARY}
+# ${OPENGL_LIBRARIES}
+# ${LLCOMMON_LIBRARIES}
+#)
+
+### media_plugin_test
+
+#set(media_plugin_test_SOURCE_FILES
+# media_plugin_test.cpp
+# )
+#
+#add_executable(media_plugin_test
+# WIN32
+# ${media_plugin_test_SOURCE_FILES}
+#)
+#
+#set_target_properties(media_plugin_test
+# PROPERTIES
+# WIN32_EXECUTABLE
+# FALSE
+#)
+#
+#target_link_libraries(media_plugin_test
+# ${GLUT_LIBRARY}
+# ${OPENGL_LIBRARIES}
+# ${LLPLUGIN_LIBRARIES}
+# ${LLMESSAGE_LIBRARIES}
+# ${LLCOMMON_LIBRARIES}
+# ${PLUGIN_API_WINDOWS_LIBRARIES}
+#)
+#
+#add_dependencies(media_plugin_test
+# copy_win_libs
+# SLPlugin
+# demo_media_plugin
+# ${LLPLUGIN_LIBRARIES}
+# ${LLMESSAGE_LIBRARIES}
+# ${LLCOMMON_LIBRARIES}
+#)
+
+### demo_media_plugin
+
+#set(demo_media_plugin_SOURCE_FILES
+# demo_media_plugin.cpp
+# )
+#
+#add_library(demo_media_plugin
+# SHARED
+# ${demo_media_plugin_SOURCE_FILES}
+#)
+#
+#target_link_libraries(demo_media_plugin
+# ${LLPLUGIN_LIBRARIES}
+# ${LLCOMMON_LIBRARIES}
+# ${PLUGIN_API_WINDOWS_LIBRARIES}
+#)
+#
+#add_dependencies(demo_media_plugin
+# ${LLPLUGIN_LIBRARIES}
+# ${LLCOMMON_LIBRARIES}
+#)
+#
+#if (DARWIN)
+# # Don't prepend 'lib' to the executable name, and don't embed a full path in the library's install name
+# set_target_properties(
+# demo_media_plugin
+# PROPERTIES
+# PREFIX ""
+# BUILD_WITH_INSTALL_RPATH 1
+# INSTALL_NAME_DIR "@executable_path"
+# )
+#endif (DARWIN)
+
+### demo_media_plugin_2
+
+#set(demo_media_plugin_2_SOURCE_FILES
+# demo_media_plugin_2.cpp
+# )
+#
+#add_library(demo_media_plugin_2
+# SHARED
+# ${demo_media_plugin_2_SOURCE_FILES}
+#)
+#
+#target_link_libraries(demo_media_plugin_2
+# ${LLPLUGIN_LIBRARIES}
+# ${LLCOMMON_LIBRARIES}
+# ${PLUGIN_API_WINDOWS_LIBRARIES}
+#)
+#
+#add_dependencies(demo_media_plugin_2
+# ${LLPLUGIN_LIBRARIES}
+# ${LLCOMMON_LIBRARIES}
+#)
+#
+#if (DARWIN)
+# # Don't prepend 'lib' to the executable name, and don't embed a full path in the library's install name
+# set_target_properties(
+# demo_media_plugin_2
+# PROPERTIES
+# PREFIX ""
+# BUILD_WITH_INSTALL_RPATH 1
+# INSTALL_NAME_DIR "@executable_path"
+# )
+#endif (DARWIN)
+
+### llmediaplugintest
+
+set(llmediaplugintest_SOURCE_FILES
+ llmediaplugintest.cpp
+ llmediaplugintest.h
+ bookmarks.txt
+ )
+
+add_executable(llmediaplugintest
+ WIN32
+ ${llmediaplugintest_SOURCE_FILES}
+)
+
+set_target_properties(llmediaplugintest
+ PROPERTIES
+ WIN32_EXECUTABLE
+ FALSE
+)
+
+target_link_libraries(llmediaplugintest
+ ${GLUT_LIBRARY}
+ ${GLUI_LIBRARY}
+ ${OPENGL_LIBRARIES}
+ ${LLPLUGIN_LIBRARIES}
+ ${LLMESSAGE_LIBRARIES}
+ ${LLCOMMON_LIBRARIES}
+ ${PLUGIN_API_WINDOWS_LIBRARIES}
+)
+
+add_dependencies(llmediaplugintest
+ copy_win_libs
+ SLPlugin
+ media_plugin_quicktime
+ media_plugin_webkit
+ ${LLPLUGIN_LIBRARIES}
+ ${LLMESSAGE_LIBRARIES}
+ ${LLCOMMON_LIBRARIES}
+)
+
+# turn off weird GLUI pragma
+add_definitions(-DGLUI_NO_LIB_PRAGMA)
+
+if (DARWIN OR LINUX)
+ # glui.h contains code that triggers the "overloaded-virtual" warning in gcc.
+ set_source_files_properties(llmediaplugintest.cpp PROPERTIES COMPILE_FLAGS "-Wno-overloaded-virtual")
+endif (DARWIN OR LINUX)
+
+# Gather build products of the various dependencies into the build directory for the testbed.
+
+get_target_property(BUILT_SLPLUGIN SLPlugin LOCATION)
+add_custom_command(TARGET llmediaplugintest POST_BUILD
+ COMMAND ${CMAKE_COMMAND} -E copy ${BUILT_SLPLUGIN} ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/
+ DEPENDS ${BUILT_SLPLUGIN}
+)
+
+if (DARWIN OR WINDOWS)
+ get_target_property(BUILT_WEBKIT_PLUGIN media_plugin_webkit LOCATION)
+ add_custom_command(TARGET llmediaplugintest POST_BUILD
+ COMMAND ${CMAKE_COMMAND} -E copy ${BUILT_WEBKIT_PLUGIN} ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/
+ DEPENDS ${BUILT_WEBKIT_PLUGIN}
+ )
+
+ get_target_property(BUILT_QUICKTIME_PLUGIN media_plugin_quicktime LOCATION)
+ add_custom_command(TARGET llmediaplugintest POST_BUILD
+ COMMAND ${CMAKE_COMMAND} -E copy ${BUILT_QUICKTIME_PLUGIN} ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/
+ DEPENDS ${BUILT_QUICKTIME_PLUGIN}
+ )
+
+ # copy over bookmarks file if llmediaplugintest gets built
+ get_target_property(BUILT_LLMEDIAPLUGINTEST llmediaplugintest LOCATION)
+ add_custom_command(TARGET llmediaplugintest POST_BUILD
+ COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_SOURCE_DIR}/bookmarks.txt ${CMAKE_CURRENT_BINARY_DIR}/
+ DEPENDS ${BUILT_LLMEDIAPLUGINTEST}
+ )
+ # also copy it to the build configuration directory, which is what the mac wants...
+ add_custom_command(TARGET llmediaplugintest POST_BUILD
+ COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_SOURCE_DIR}/bookmarks.txt ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/
+ DEPENDS ${BUILT_LLMEDIAPLUGINTEST}
+ )
+endif (DARWIN OR WINDOWS)
+
+if (DARWIN)
+ add_custom_command(TARGET llmediaplugintest POST_BUILD
+ COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_SOURCE_DIR}/../libraries/universal-darwin/lib_release/libllqtwebkit.dylib ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/
+ DEPENDS ${CMAKE_SOURCE_DIR}/../libraries/universal-darwin/lib_release/libllqtwebkit.dylib
+ )
+endif (DARWIN)
+
+
diff --git a/indra/test_apps/llplugintest/bookmarks.txt b/indra/test_apps/llplugintest/bookmarks.txt
new file mode 100644
index 0000000000..796cc5d1b2
--- /dev/null
+++ b/indra/test_apps/llplugintest/bookmarks.txt
@@ -0,0 +1,28 @@
+# format is description, url (don't put ',' chars in description :)
+# if no ',' found, whole line is used for both description and url
+(WK) Google Home Page,http://www.google.com
+(WK) BBC News Home Page,http://news.bbc.co.uk
+(WK) Second Life,http://secondlife.com
+(WK) WebKit Home ,http://www.webkit.org
+(WK) Yahoo News,http://news.yahoo.com
+(WK) Canvas Paint (DHTML version of MS Paint),http://www.canvaspaint.org
+(WK) DHTML Lemmings!,http://www.elizium.nu/scripts/lemmings/
+(WK) DHTML graphics demos,http://www.dhteumeuleu.com/
+(WK) Neat Javascript 3D,http://gyu.que.jp/jscloth/
+(QT) Local sample,file:///C|/Program Files/QuickTime/Sample.mov
+(QT) Movie - Watchmen Trailer,http://movies.apple.com/movies/wb/watchmen/watchmen-tlr2_480p.mov
+(QT) Movie - Transformers - Revenge of the Fallen,http://movies.apple.com/movies/paramount/transformers2/transformersrevengeofthefallen-tlr1_h.320.mov
+(QT) Movie - Terminator Salvation,http://movies.apple.com/movies/wb/terminatorsalvation/terminatorsalvation-tlr3_h.320.mov
+(QT) Movie - Angels and Demons,http://movies.apple.com/movies/sony_pictures/angelsanddemons/angelsanddemons-video_h.320.mov
+(QT) Movie - Sin City Trailer,http://movies.apple.com/movies/miramax/sin_city/sin_city_480.mov
+(QT) Movie - The Incredibles Trailer,http://movies.apple.com/movies/disney/the_incredibles/the_incredibles-tlr_a480.mov
+(QT) Movie - Streaming Apple Event,http://stream.qtv.apple.com/events/mar/0903lajkszg/m_090374535329zdwg_650_ref.mov
+(QT) Movie - MPEG-4 from Amazon S3,http://s3.amazonaws.com/callum-linden/flashdemo/interactive_flash_demo.mp4
+(QT) Movie - Star Trek,http://movies.apple.com/movies/paramount/star_trek/startrek-tlr3_h.320.mov
+(QT) Movie - Ice Age 3,http://movies.apple.com/movies/fox/ice_age_iii/iceage3-tlrd_h.320.mov
+(QT) Movie - AstroBoy,http://movies.apple.com/movies/summit/astroboy/astroboy-tsr_h.320.mov
+(QT) Movie - Ante Up,http://movies.apple.com/movies/independent/anteup/anteup_h.320.mov
+(QT) Movie - Every Little Step,http://movies.apple.com/movies/sony/everylittlestep/everylittlestep-clip_h.320.mov
+(QT) Movie - The Informers,http://movies.apple.com/movies/independent/theinformers/theinformers_h.320.mov
+(QT) Animated GIF,http://upload.wikimedia.org/wikipedia/commons/4/44/Optical.greysquares.arp-animated.gif
+(QT) Apple Text Descriptors,http://ubrowser.com/tmp/apple_text.txt
diff --git a/indra/test_apps/llplugintest/llmediaplugintest.cpp b/indra/test_apps/llplugintest/llmediaplugintest.cpp
new file mode 100644
index 0000000000..cd90884d09
--- /dev/null
+++ b/indra/test_apps/llplugintest/llmediaplugintest.cpp
@@ -0,0 +1,2145 @@
+/**
+ * @file LLMediaPluginTest2.cpp
+ * @brief Primary test application for LLMedia (Separate Process) Plugin system
+ *
+ * $LicenseInfo:firstyear=2008&license=viewergpl$
+ *
+ * Copyright (c) 2009, Linden Research, Inc.
+ *
+ * Second Life Viewer Source Code
+ * The source code in this file ("Source Code") is provided by Linden Lab
+ * to you under the terms of the GNU General Public License, version 2.0
+ * ("GPL"), unless you have obtained a separate licensing agreement
+ * ("Other License"), formally executed by you and Linden Lab. Terms of
+ * the GPL can be found in doc/GPL-license.txt in this distribution, or
+ * online at http://secondlife.com/developers/opensource/gplv2
+ *
+ * There are special exceptions to the terms and conditions of the GPL as
+ * it is applied to this Source Code. View the full text of the exception
+ * in the file doc/FLOSS-exception.txt in this software distribution, or
+ * online at http://secondlife.com/developers/opensource/flossexception
+ *
+ * By copying, modifying or distributing this software, you acknowledge
+ * that you have read and understood your obligations described above,
+ * and agree to abide by those obligations.
+ *
+ * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+ * COMPLETENESS OR PERFORMANCE.
+ * $/LicenseInfo$
+ */
+
+#include "linden_common.h"
+#include "indra_constants.h"
+
+#include "llapr.h"
+#include "llerrorcontrol.h"
+
+#include <math.h>
+#include <iomanip>
+#include <sstream>
+#include <ctime>
+
+#include "llmediaplugintest.h"
+
+#if __APPLE__
+ #include <GLUT/glut.h>
+#else
+ #define FREEGLUT_STATIC
+ #include "GL/freeglut.h"
+ #define GLUI_FREEGLUT
+#endif
+
+#if LL_WINDOWS
+#pragma warning(disable: 4263)
+#pragma warning(disable: 4264)
+#endif
+#include "glui.h"
+
+
+LLMediaPluginTest* gApplication = 0;
+static void gluiCallbackWrapper( int control_id );
+
+////////////////////////////////////////////////////////////////////////////////
+//
+static bool isTexture( GLuint texture )
+{
+ bool result = false;
+
+ // glIsTexture will sometimes return false for real textures... do this instead.
+ if(texture != 0)
+ result = true;
+
+ return result;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+//
+mediaPanel::mediaPanel()
+{
+ mMediaTextureHandle = 0;
+ mPickTextureHandle = 0;
+ mMediaSource = NULL;
+ mPickTexturePixels = NULL;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+//
+mediaPanel::~mediaPanel()
+{
+ // delete OpenGL texture handles
+ if ( isTexture( mPickTextureHandle ) )
+ {
+ std::cerr << "remMediaPanel: deleting pick texture " << mPickTextureHandle << std::endl;
+ glDeleteTextures( 1, &mPickTextureHandle );
+ mPickTextureHandle = 0;
+ }
+
+ if ( isTexture( mMediaTextureHandle ) )
+ {
+ std::cerr << "remMediaPanel: deleting media texture " << mMediaTextureHandle << std::endl;
+ glDeleteTextures( 1, &mMediaTextureHandle );
+ mMediaTextureHandle = 0;
+ }
+
+ if(mPickTexturePixels)
+ {
+ delete mPickTexturePixels;
+ }
+
+ if(mMediaSource)
+ {
+ delete mMediaSource;
+ }
+
+}
+
+////////////////////////////////////////////////////////////////////////////////
+//
+LLMediaPluginTest::LLMediaPluginTest( int app_window, int window_width, int window_height ) :
+ mVersionMajor( 2 ),
+ mVersionMinor( 0 ),
+ mVersionPatch( 0 ),
+ mMaxPanels( 25 ),
+ mViewportAspect( 0 ),
+ mAppWindow( app_window ),
+ mCurMouseX( 0 ),
+ mCurMouseY( 0 ),
+ mFuzzyMedia( true ),
+ mSelectedPanel( 0 ),
+ mMediaBrowserControlEnableCookies( 0 ),
+ mMediaBrowserControlBackButton( 0 ),
+ mMediaBrowserControlForwardButton( 0 ),
+ mMediaTimeControlVolume( 100 ),
+ mMediaTimeControlSeekSeconds( 0 ),
+ mGluiMediaTimeControlWindowFlag( true ),
+ mGluiMediaBrowserControlWindowFlag( true ),
+ mMediaBrowserControlBackButtonFlag( true ),
+ mMediaBrowserControlForwardButtonFlag( true ),
+ mHomeWebUrl( "http://www.google.com/" )
+{
+ // debugging spam
+ std::cout << std::endl << " GLUT version: " << "3.7.6" << std::endl; // no way to get real version from GLUT
+ std::cout << std::endl << " GLUI version: " << GLUI_Master.get_version() << std::endl;
+ std::cout << std::endl << "Media Plugin Test version: " << mVersionMajor << "." << mVersionMinor << "." << mVersionPatch << std::endl;
+
+ // bookmark title
+ mBookmarks.push_back( std::pair< std::string, std::string >( "--- Bookmarks ---", "" ) );
+
+ // insert hardcoded URLs here as required for testing
+ //mBookmarks.push_back( std::pair< std::string, std::string >( "description", "url" ) );
+
+ // read bookmarks from file.
+ // note: uses command in ./CmakeLists.txt which copies bookmmarks file from source directory
+ // to app directory (WITHOUT build configuration dir) (this is cwd in Windows within MSVC)
+ // For example, test_apps\llplugintest and not test_apps\llplugintest\Release
+ // This may need to be changed for Mac/Linux builds.
+ // See https://jira.lindenlab.com/browse/DEV-31350 for large list of media URLs from AGNI
+ const std::string bookmarks_filename( "bookmarks.txt" );
+ std::ifstream file_handle( bookmarks_filename.c_str() );
+ if ( file_handle.is_open() )
+ {
+ std::cout << "Reading bookmarks for test" << std::endl;
+ while( ! file_handle.eof() )
+ {
+ std::string line;
+ std::getline( file_handle, line );
+ if ( file_handle.eof() )
+ break;
+
+ if ( line.substr( 0, 1 ) != "#" )
+ {
+ size_t comma_pos = line.find_first_of( ',' );
+ if ( comma_pos != std::string::npos )
+ {
+ std::string description = line.substr( 0, comma_pos );
+ std::string url = line.substr( comma_pos + 1 );
+ mBookmarks.push_back( std::pair< std::string, std::string >( description, url ) );
+ }
+ else
+ {
+ mBookmarks.push_back( std::pair< std::string, std::string >( line, line ) );
+ };
+ };
+ };
+ std::cout << "Read " << mBookmarks.size() << " bookmarks" << std::endl;
+ }
+ else
+ {
+ std::cout << "Unable to read bookmarks from file: " << bookmarks_filename << std::endl;
+ };
+
+ // initialize linden lab APR module
+ ll_init_apr();
+
+ // Set up llerror logging
+ {
+ LLError::initForApplication(".");
+ LLError::setDefaultLevel(LLError::LEVEL_INFO);
+// LLError::setTagLevel("Plugin", LLError::LEVEL_DEBUG);
+ }
+
+ // lots of randomness in this app
+ srand( ( unsigned int )time( 0 ) );
+
+ // build GUI
+ makeChrome();
+
+ // OpenGL initialilzation
+ glClearColor( 0.0f, 0.0f, 0.0f, 1.0f );
+ glClearDepth( 1.0f );
+ glEnable( GL_DEPTH_TEST );
+ glEnable( GL_COLOR_MATERIAL );
+ glColorMaterial( GL_FRONT, GL_AMBIENT_AND_DIFFUSE );
+ glDepthFunc( GL_LEQUAL );
+ glEnable( GL_TEXTURE_2D );
+ glDisable( GL_BLEND );
+ glColor3f( 1.0f, 1.0f, 1.0f );
+ glPixelStorei( GL_UNPACK_ALIGNMENT, 1 );
+ glPixelStorei( GL_UNPACK_ROW_LENGTH, 0 );
+
+ // start with a sane view
+ resetView();
+
+ // initial media panel
+ //const int num_initial_panels = 4;
+ //for( int i = 0; i < num_initial_panels; ++i )
+ //{
+ // addMediaPanel( mBookmarks[ rand() % ( mBookmarks.size() - 1 ) + 1 ].second );
+ //};
+
+ // always add a Web panel for testing
+ addMediaPanel( "http://www.google.com" );
+}
+
+////////////////////////////////////////////////////////////////////////////////
+//
+LLMediaPluginTest::~LLMediaPluginTest()
+{
+ // delete all media panels
+ for( int i = 0; i < (int)mMediaPanels.size(); ++i )
+ {
+ remMediaPanel( mMediaPanels[ i ] );
+ };
+}
+
+////////////////////////////////////////////////////////////////////////////////
+//
+void LLMediaPluginTest::reshape( int width, int height )
+{
+ // update viewport (the active window inside the chrome)
+ int viewport_x, viewport_y;
+ int viewport_height, viewport_width;
+ GLUI_Master.get_viewport_area( &viewport_x, &viewport_y, &viewport_width, &viewport_height );
+ mViewportAspect = (float)( viewport_width ) / (float)( viewport_height );
+ glViewport( viewport_x, viewport_y, viewport_width, viewport_height );
+
+ // save these as we'll need them later
+ mWindowWidth = width;
+ mWindowHeight = height;
+
+ // adjust size of URL bar so it doesn't get clipped
+ mUrlEdit->set_w( mWindowWidth - 360 );
+
+ // GLUI requires this
+ if ( glutGetWindow() != mAppWindow )
+ glutSetWindow( mAppWindow );
+
+ // trigger re-display
+ glutPostRedisplay();
+};
+
+////////////////////////////////////////////////////////////////////////////////
+//
+void LLMediaPluginTest::bindTexture(GLuint texture, GLint row_length, GLint alignment)
+{
+ glEnable( GL_TEXTURE_2D );
+
+// std::cerr << "binding texture " << texture << std::endl;
+
+ glBindTexture( GL_TEXTURE_2D, texture );
+ glPixelStorei( GL_UNPACK_ROW_LENGTH, row_length );
+ glPixelStorei( GL_UNPACK_ALIGNMENT, alignment );
+}
+
+////////////////////////////////////////////////////////////////////////////////
+//
+bool LLMediaPluginTest::checkGLError(char *name)
+{
+ bool result = false;
+ GLenum error = glGetError();
+
+ if(error != GL_NO_ERROR)
+ {
+ // For some reason, glGenTextures is returning GL_INVALID_VALUE...
+ std::cout << name << " ERROR 0x" << std::hex << error << std::dec << std::endl;
+ result = true;
+ }
+
+ return result;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+//
+void LLMediaPluginTest::drawGeometry( int panel )
+{
+ // texture coordinates for each panel
+ GLfloat non_opengl_texture_coords[ 8 ] = { 0.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 0.0f };
+ GLfloat opengl_texture_coords[ 8 ] = { 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, 1.0f, 0.0f, 1.0f };
+
+ GLfloat *texture_coords = mMediaPanels[ panel ]->mAppTextureCoordsOpenGL?opengl_texture_coords:non_opengl_texture_coords;
+
+ // base coordinates for each panel
+ GLfloat base_vertex_pos[ 8 ] = { 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, 1.0f, 0.0f, 1.0f };
+
+ // calculate posiitons
+ const int num_panels = (int)mMediaPanels.size();
+ const int num_rows = (int)sqrt( (float)num_panels );
+ const int num_cols = num_panels / num_rows;
+ const int panel_x = ( panel / num_rows );
+ const int panel_y = ( panel % num_rows );
+
+ const float spacing = 0.1f;
+ const GLfloat offset_x = num_cols * ( 1.0 + spacing ) / 2;
+ const GLfloat offset_y = num_rows * ( 1.0 + spacing ) / 2;
+
+ // Adjust for media aspect ratios
+ {
+ float aspect = 1.0f;
+
+ if(mMediaPanels[ panel ]->mMediaHeight != 0)
+ {
+ aspect = (float)mMediaPanels[ panel ]->mMediaWidth / (float)mMediaPanels[ panel ]->mMediaHeight;
+ }
+
+ if(aspect > 1.0f)
+ {
+ // media is wider than it is high -- adjust the top and bottom in
+ for( int corner = 0; corner < 4; ++corner )
+ {
+ float temp = base_vertex_pos[corner * 2 + 1];
+
+ if(temp < 0.5f)
+ temp += 0.5 - (0.5f / aspect);
+ else
+ temp -= 0.5 - (0.5f / aspect);
+
+ base_vertex_pos[corner * 2 + 1] = temp;
+ }
+ }
+ else if(aspect < 1.0f)
+ {
+ // media is higher than it is wide -- adjust the left and right sides in
+ for( int corner = 0; corner < 4; ++corner )
+ {
+ float temp = base_vertex_pos[corner * 2];
+
+ if(temp < 0.5f)
+ temp += 0.5f - (0.5f * aspect);
+ else
+ temp -= 0.5f - (0.5f * aspect);
+
+ base_vertex_pos[corner * 2] = temp;
+ }
+ }
+ }
+
+ glBegin( GL_QUADS );
+ for( int corner = 0; corner < 4; ++corner )
+ {
+ glTexCoord2f( texture_coords[ corner * 2 ], texture_coords[ corner * 2 + 1 ] );
+ GLfloat x = base_vertex_pos[ corner * 2 ] + panel_x * ( 1.0 + spacing ) - offset_x + spacing / 2.0f;
+ GLfloat y = base_vertex_pos[ corner * 2 + 1 ] + panel_y * ( 1.0 + spacing ) - offset_y + spacing / 2.0f;
+
+ glVertex3f( x, y, 0.0f );
+ };
+ glEnd();
+}
+
+//////////////////////////////////////////////////////////////////////////////
+//
+void LLMediaPluginTest::startPanelHighlight( float red, float green, float blue, float line_width )
+{
+ glPushAttrib( GL_ALL_ATTRIB_BITS );
+ glEnable( GL_POLYGON_OFFSET_FILL );
+ glPolygonOffset( -2.5f, -2.5f );
+ glPolygonMode( GL_FRONT_AND_BACK, GL_LINE );
+ glLineWidth( line_width );
+ glColor3f( red, green, blue );
+ glDisable( GL_TEXTURE_2D );
+}
+
+//////////////////////////////////////////////////////////////////////////////
+//
+void LLMediaPluginTest::endPanelHighlight()
+{
+ glPopAttrib();
+}
+
+////////////////////////////////////////////////////////////////////////////////
+//
+void LLMediaPluginTest::draw( int draw_type )
+{
+ for( int panel = 0; panel < (int)mMediaPanels.size(); ++panel )
+ {
+ // drawing pick texture
+ if ( draw_type == DrawTypePickTexture )
+ {
+ // only bother with pick if we have something to render
+ // Actually, we need to pick even if we're not ready to render.
+ // Otherwise you can't select and remove a panel which has gone bad.
+// if ( mMediaPanels[ panel ]->mReadyToRender )
+ {
+ glMatrixMode( GL_TEXTURE );
+ glPushMatrix();
+
+ // pick texture is a power of 2 so no need to scale
+ glLoadIdentity();
+
+ // bind to media texture
+ glLoadIdentity();
+ bindTexture( mMediaPanels[ panel ]->mPickTextureHandle );
+ glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST );
+ glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST );
+
+ // draw geometry using pick texture
+ drawGeometry( panel );
+
+ glMatrixMode( GL_TEXTURE );
+ glPopMatrix();
+ };
+ }
+ else
+ if ( draw_type == DrawTypeMediaTexture )
+ {
+ bool texture_valid = false;
+ bool plugin_exited = false;
+
+ if(mMediaPanels[ panel ]->mMediaSource)
+ {
+ texture_valid = mMediaPanels[ panel ]->mMediaSource->textureValid();
+ plugin_exited = mMediaPanels[ panel ]->mMediaSource->isPluginExited();
+ }
+
+ // save texture matrix (changes for each panel)
+ glMatrixMode( GL_TEXTURE );
+ glPushMatrix();
+
+ // only process texture if the media is ready to draw
+ // (we still want to draw the geometry)
+ if ( mMediaPanels[ panel ]->mReadyToRender && texture_valid )
+ {
+ // bind to media texture
+ bindTexture( mMediaPanels[ panel ]->mMediaTextureHandle );
+
+ if ( mFuzzyMedia )
+ {
+ glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
+ glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
+ }
+ else
+ {
+ glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST );
+ glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST );
+ }
+
+ // scale to fit panel
+ glScalef( mMediaPanels[ panel ]->mTextureScaleX,
+ mMediaPanels[ panel ]->mTextureScaleY,
+ 1.0f );
+ };
+
+ float intensity = plugin_exited?0.25f:1.0f;
+
+ // highlight the selected panel
+ if ( mSelectedPanel && ( mMediaPanels[ panel ]->mId == mSelectedPanel->mId ) )
+ {
+ startPanelHighlight( intensity, intensity, 0.0f, 5.0f );
+ drawGeometry( panel );
+ endPanelHighlight();
+ }
+ else
+ // this panel not able to render yet since it
+ // doesn't have enough information
+ if ( !mMediaPanels[ panel ]->mReadyToRender )
+ {
+ startPanelHighlight( intensity, 0.0f, 0.0f, 2.0f );
+ drawGeometry( panel );
+ endPanelHighlight();
+ }
+ else
+ // just display a border around the media
+ {
+ startPanelHighlight( 0.0f, intensity, 0.0f, 2.0f );
+ drawGeometry( panel );
+ endPanelHighlight();
+ };
+
+ if ( mMediaPanels[ panel ]->mReadyToRender && texture_valid )
+ {
+ // draw visual geometry
+ drawGeometry( panel );
+ }
+
+ // restore texture matrix (changes for each panel)
+ glMatrixMode( GL_TEXTURE );
+ glPopMatrix();
+ };
+ };
+}
+
+////////////////////////////////////////////////////////////////////////////////
+//
+void LLMediaPluginTest::display()
+{
+ // GLUI requires this
+ if ( glutGetWindow() != mAppWindow )
+ glutSetWindow( mAppWindow );
+
+ // start with a clean slate
+ glClearColor( 0.0f, 0.0f, 0.0f, 1.0f );
+ glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
+
+ // set up OpenGL view
+ glMatrixMode( GL_PROJECTION );
+ glLoadIdentity();
+ glFrustum( -mViewportAspect * 0.04f, mViewportAspect * 0.04f, -0.04f, 0.04f, 0.1f, 50.0f );
+ glMatrixMode( GL_MODELVIEW );
+ glLoadIdentity();
+ glTranslatef( 0.0, 0.0, 0.0f );
+ glTranslatef( mViewPos[ 0 ], mViewPos[ 1 ], -mViewPos[ 2 ] );
+ glMultMatrixf( mViewRotation );
+
+ // draw pick texture
+ draw( DrawTypePickTexture );
+
+ // read colors and get coordinate values
+ glReadPixels( mCurMouseX, mCurMouseY, 1, 1, GL_RGB, GL_UNSIGNED_BYTE, mPixelReadColor );
+
+ // clear the pick render (otherwise it may depth-fight with the textures rendered later)
+ glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
+
+ // draw visible geometry
+ draw( DrawTypeMediaTexture );
+
+ glutSwapBuffers();
+}
+
+////////////////////////////////////////////////////////////////////////////////
+//
+void LLMediaPluginTest::idle()
+{
+// checkGLError("LLMediaPluginTest::idle");
+
+ // GLUI requires this
+ if ( glutGetWindow() != mAppWindow )
+ glutSetWindow( mAppWindow );
+
+ // random creation/destruction of panels enabled?
+ const time_t panel_timeout_time = 5;
+ if ( mRandomPanelCount )
+ {
+ // time for a change
+ static time_t last_panel_time = 0;
+ if ( time( NULL ) - last_panel_time > panel_timeout_time )
+ {
+ if ( rand() % 2 == 0 )
+ {
+ if ( mMediaPanels.size() < 16 )
+ {
+ std::cout << "Randomly adding new panel" << std::endl;
+ addMediaPanel( mBookmarks[ rand() % ( mBookmarks.size() - 1 ) + 1 ].second );
+ };
+ }
+ else
+ {
+ if ( mMediaPanels.size() > 0 )
+ {
+ std::cout << "Deleting selected panel" << std::endl;
+ remMediaPanel( mSelectedPanel );
+ };
+ };
+ time( &last_panel_time );
+ };
+ };
+
+ // random selection of bookmarks enabled?
+ const time_t bookmark_timeout_time = 5;
+ if ( mRandomBookmarks )
+ {
+ // time for a change
+ static time_t last_bookmark_time = 0;
+ if ( time( NULL ) - last_bookmark_time > bookmark_timeout_time )
+ {
+ // go to a different random bookmark on each panel
+ for( int panel = 0; panel < (int)mMediaPanels.size(); ++panel )
+ {
+ std::string uri = mBookmarks[ rand() % ( mBookmarks.size() - 1 ) + 1 ].second;
+
+ std::cout << "Random: navigating to : " << uri << std::endl;
+
+ std::string mime_type = mimeTypeFromUrl( uri );
+
+ if ( mime_type != mMediaPanels[ panel ]->mMimeType )
+ {
+ replaceMediaPanel( mMediaPanels[ panel ], uri );
+ }
+ else
+ {
+ mMediaPanels[ panel ]->mMediaSource->loadURI( uri );
+ mMediaPanels[ panel ]->mMediaSource->start();
+ };
+ };
+
+ time( &last_bookmark_time );
+ };
+ };
+
+ // update UI
+ if ( mSelectedPanel )
+ {
+ // set volume based on slider if we have time media
+// if ( mGluiMediaTimeControlWindowFlag )
+// {
+// mSelectedPanel->mMediaSource->setVolume( (float)mMediaTimeControlVolume / 100.0f );
+// };
+
+ // NOTE: it is absurd that we need cache the state of GLUI controls
+ // but enabling/disabling controls drags framerate from 500+
+ // down to 15. Not a problem for plugin system - only this test
+ // enable/disable time based UI controls based on type of plugin
+ if ( mSelectedPanel->mMediaSource->pluginSupportsMediaTime() )
+ {
+ if ( ! mGluiMediaTimeControlWindowFlag )
+ {
+ mGluiMediaTimeControlWindow->enable();
+ mGluiMediaTimeControlWindowFlag = true;
+ };
+ }
+ else
+ {
+ if ( mGluiMediaTimeControlWindowFlag )
+ {
+ mGluiMediaTimeControlWindow->disable();
+ mGluiMediaTimeControlWindowFlag = false;
+ };
+ };
+
+ // enable/disable browser based UI controls based on type of plugin
+ if ( mSelectedPanel->mMediaSource->pluginSupportsMediaBrowser() )
+ {
+ if ( ! mGluiMediaBrowserControlWindowFlag )
+ {
+ mGluiMediaBrowserControlWindow->enable();
+ mGluiMediaBrowserControlWindowFlag = true;
+ };
+ }
+ else
+ {
+ if ( mGluiMediaBrowserControlWindowFlag )
+ {
+ mGluiMediaBrowserControlWindow->disable();
+ mGluiMediaBrowserControlWindowFlag = false;
+ };
+ };
+
+ // enable/disable browser back button depending on browser history
+ if ( mSelectedPanel->mMediaSource->getHistoryBackAvailable() )
+ {
+ if ( ! mMediaBrowserControlBackButtonFlag )
+ {
+ mMediaBrowserControlBackButton->enable();
+ mMediaBrowserControlBackButtonFlag = true;
+ };
+ }
+ else
+ {
+ if ( mMediaBrowserControlBackButtonFlag )
+ {
+ mMediaBrowserControlBackButton->disable();
+ mMediaBrowserControlBackButtonFlag = false;
+ };
+ };
+
+ // enable/disable browser forward button depending on browser history
+ if ( mSelectedPanel->mMediaSource->getHistoryForwardAvailable() )
+ {
+ if ( ! mMediaBrowserControlForwardButtonFlag )
+ {
+ mMediaBrowserControlForwardButton->enable();
+ mMediaBrowserControlForwardButtonFlag = true;
+ };
+ }
+ else
+ {
+ if ( mMediaBrowserControlForwardButtonFlag )
+ {
+ mMediaBrowserControlForwardButton->disable();
+ mMediaBrowserControlForwardButtonFlag = false;
+ };
+ };
+
+ // NOTE: This is *very* slow and not worth optimising
+ updateStatusBar();
+ };
+
+ // update all the panels
+ for( int panel_index = 0; panel_index < (int)mMediaPanels.size(); ++panel_index )
+ {
+ mediaPanel *panel = mMediaPanels[ panel_index ];
+
+ // call plugins idle function so it can potentially update itself
+ panel->mMediaSource->idle();
+
+ // update each media panel
+ updateMediaPanel( panel );
+
+ LLRect dirty_rect;
+ if ( ! panel->mMediaSource->textureValid() )
+ {
+ //std::cout << "texture invalid, skipping update..." << std::endl;
+ }
+ else
+ if ( panel &&
+ ( panel->mMediaWidth != panel->mMediaSource->getWidth() ||
+ panel->mMediaHeight != panel->mMediaSource->getHeight() ) )
+ {
+ //std::cout << "Resize in progress, skipping update..." << std::endl;
+ }
+ else
+ if ( panel->mMediaSource->getDirty( &dirty_rect ) )
+ {
+ const unsigned char* pixels = panel->mMediaSource->getBitsData();
+ if ( pixels && isTexture(panel->mMediaTextureHandle))
+ {
+ int x_offset = dirty_rect.mLeft;
+ int y_offset = dirty_rect.mBottom;
+ int width = dirty_rect.mRight - dirty_rect.mLeft;
+ int height = dirty_rect.mTop - dirty_rect.mBottom;
+
+ if((dirty_rect.mRight <= panel->mTextureWidth) && (dirty_rect.mTop <= panel->mTextureHeight))
+ {
+ // Offset the pixels pointer properly
+ pixels += ( y_offset * panel->mMediaSource->getTextureDepth() * panel->mMediaSource->getBitsWidth() );
+ pixels += ( x_offset * panel->mMediaSource->getTextureDepth() );
+
+ // set up texture
+ bindTexture( panel->mMediaTextureHandle, panel->mMediaSource->getBitsWidth() );
+ if ( mFuzzyMedia )
+ {
+ glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
+ glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
+ }
+ else
+ {
+ glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST );
+ glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST );
+ };
+
+ checkGLError("glTexParameteri");
+
+ if(panel->mMediaSource->getTextureFormatSwapBytes())
+ {
+ glPixelStorei(GL_UNPACK_SWAP_BYTES, 1);
+ checkGLError("glPixelStorei");
+ }
+
+ // draw portion that changes into texture
+ glTexSubImage2D( GL_TEXTURE_2D, 0,
+ x_offset,
+ y_offset,
+ width,
+ height,
+ panel->mMediaSource->getTextureFormatPrimary(),
+ panel->mMediaSource->getTextureFormatType(),
+ pixels );
+
+ if(checkGLError("glTexSubImage2D"))
+ {
+ std::cerr << " panel ID=" << panel->mId << std::endl;
+ std::cerr << " texture size = " << panel->mTextureWidth << " x " << panel->mTextureHeight << std::endl;
+ std::cerr << " media size = " << panel->mMediaWidth << " x " << panel->mMediaHeight << std::endl;
+ std::cerr << " dirty rect = " << dirty_rect.mLeft << ", " << dirty_rect.mBottom << ", " << dirty_rect.mRight << ", " << dirty_rect.mTop << std::endl;
+ std::cerr << " texture width = " << panel->mMediaSource->getBitsWidth() << std::endl;
+ std::cerr << " format primary = 0x" << std::hex << panel->mMediaSource->getTextureFormatPrimary() << std::dec << std::endl;
+ std::cerr << " format type = 0x" << std::hex << panel->mMediaSource->getTextureFormatType() << std::dec << std::endl;
+ std::cerr << " pixels = " << (void*)pixels << std::endl;
+ }
+
+ if(panel->mMediaSource->getTextureFormatSwapBytes())
+ {
+ glPixelStorei(GL_UNPACK_SWAP_BYTES, 0);
+ checkGLError("glPixelStorei");
+ }
+
+ panel->mMediaSource->resetDirty();
+
+ panel->mReadyToRender = true;
+ }
+ else
+ {
+ std::cerr << "dirty rect is outside current media size, skipping update" << std::endl;
+ }
+ };
+ };
+ };
+
+ // GLUI requires this
+ if ( glutGetWindow() != mAppWindow )
+ glutSetWindow( mAppWindow );
+
+ // trigger re-display
+ glutPostRedisplay();
+}
+
+////////////////////////////////////////////////////////////////////////////////
+//
+void LLMediaPluginTest::windowPosToTexturePos( int window_x, int window_y,
+ int& media_x, int& media_y,
+ int& id )
+{
+ if ( ! mSelectedPanel )
+ {
+ media_x = 0;
+ media_y = 0;
+ id = 0;
+ return;
+ };
+
+ // record cursor poisiton for a readback next frame
+ mCurMouseX = window_x;
+ // OpenGL app == coordinate system this way
+ // NOTE: unrelated to settings in plugin - this
+ // is just for this app
+ mCurMouseY = mWindowHeight - window_y;
+
+ // extract x (0..1023, y (0..1023) and id (0..15) from RGB components
+ unsigned long pixel_read_color_bits = ( mPixelReadColor[ 0 ] << 16 ) | ( mPixelReadColor[ 1 ] << 8 ) | mPixelReadColor[ 2 ];
+ int texture_x = pixel_read_color_bits & 0x3ff;
+ int texture_y = ( pixel_read_color_bits >> 10 ) & 0x3ff;
+ id = ( pixel_read_color_bits >> 20 ) & 0x0f;
+
+ // scale to size of media (1024 because we use 10 bits for X and Y from 24)
+ media_x = (int)( ( (float)mSelectedPanel->mMediaWidth * (float)texture_x ) / 1024.0f );
+ media_y = (int)( ( (float)mSelectedPanel->mMediaHeight * (float)texture_y ) / 1024.0f );
+
+ // we assume the plugin uses an inverted coordinate scheme like OpenGL
+ // if not, the plugin code inverts the Y coordinate for us - we don't need to
+ media_y = mSelectedPanel->mMediaHeight - media_y;
+
+ if ( media_x > 0 && media_y > 0 )
+ {
+ //std::cout << " mouse coords: " << mCurMouseX << " x " << mCurMouseY << " and id = " << id << std::endl;
+ //std::cout << "raw texture coords: " << texture_x << " x " << texture_y << " and id = " << id << std::endl;
+ //std::cout << " media coords: " << media_x << " x " << media_y << " and id = " << id << std::endl;
+ //std::cout << std::endl;
+ };
+}
+
+////////////////////////////////////////////////////////////////////////////////
+//
+void LLMediaPluginTest::selectPanelById( int id )
+{
+ for( int panel = 0; panel < (int)mMediaPanels.size(); ++panel )
+ {
+ if ( mMediaPanels[ panel ]->mId == id )
+ {
+ selectPanel(mMediaPanels[ panel ]);
+ return;
+ };
+ };
+}
+
+////////////////////////////////////////////////////////////////////////////////
+//
+void LLMediaPluginTest::selectPanel( mediaPanel* panel )
+{
+ if( mSelectedPanel == panel )
+ return;
+
+ // turn off volume before we delete it
+ if( mSelectedPanel && mSelectedPanel->mMediaSource )
+ {
+ mSelectedPanel->mMediaSource->setVolume( 0.0f );
+ mSelectedPanel->mMediaSource->setPriority( LLPluginClassMedia::PRIORITY_LOW );
+ };
+
+ mSelectedPanel = panel;
+
+ if( mSelectedPanel && mSelectedPanel->mMediaSource )
+ {
+ mSelectedPanel->mMediaSource->setVolume( (float)mMediaTimeControlVolume / 100.0f );
+ mSelectedPanel->mMediaSource->setPriority( LLPluginClassMedia::PRIORITY_NORMAL );
+
+ if(!mSelectedPanel->mStartUrl.empty())
+ {
+ mUrlEdit->set_text(const_cast<char*>(mSelectedPanel->mStartUrl.c_str()) );
+ }
+ };
+}
+
+////////////////////////////////////////////////////////////////////////////////
+//
+mediaPanel* LLMediaPluginTest::findMediaPanel( LLPluginClassMedia* source )
+{
+ mediaPanel *result = NULL;
+
+ for( int panel = 0; panel < (int)mMediaPanels.size(); ++panel )
+ {
+ if ( mMediaPanels[ panel ]->mMediaSource == source )
+ {
+ result = mMediaPanels[ panel ];
+ }
+ }
+
+ return result;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+//
+void LLMediaPluginTest::navigateToNewURI( std::string uri )
+{
+ if ( uri.length() )
+ {
+ std::string mime_type = mimeTypeFromUrl( uri );
+
+ if ( !mSelectedPanel->mMediaSource->isPluginExited() && (mime_type == mSelectedPanel->mMimeType) )
+ {
+ std::cout << "MIME type is the same" << std::endl;
+ mSelectedPanel->mMediaSource->loadURI( uri );
+ mSelectedPanel->mMediaSource->start();
+ mBookmarkList->do_selection( 0 );
+ }
+ else
+ {
+ std::cout << "MIME type changed or plugin had exited" << std::endl;
+ replaceMediaPanel( mSelectedPanel, uri );
+ mBookmarkList->do_selection( 0 );
+ }
+ };
+}
+
+////////////////////////////////////////////////////////////////////////////////
+//
+void LLMediaPluginTest::initUrlHistory( std::string uris )
+{
+ if ( uris.length() > 0 )
+ {
+ std::cout << "init URL : " << uris << std::endl;
+ LLSD historySD;
+
+ char *cstr, *p;
+ cstr = new char[uris.size()+1];
+ strcpy(cstr, uris.c_str());
+ const char *DELIMS = " ,;";
+ p = strtok(cstr, DELIMS);
+ while (p != NULL) {
+ historySD.insert(0, p);
+ p = strtok(NULL, DELIMS);
+ }
+ mSelectedPanel->mMediaSource->initializeUrlHistory(historySD);
+ delete[] cstr;
+ }
+}
+
+////////////////////////////////////////////////////////////////////////////////
+//
+void LLMediaPluginTest::gluiCallback( int control_id )
+{
+ if ( control_id == mIdBookmarks )
+ {
+ std::string uri = mBookmarks[ mSelBookmark ].second;
+
+ navigateToNewURI( uri );
+ }
+ else
+ if ( control_id == mIdUrlEdit)
+ {
+ std::string uri = mUrlEdit->get_text();
+
+ navigateToNewURI( uri );
+ }
+ else
+ if ( control_id == mIdUrlInitHistoryEdit )
+ {
+ std::string uri = mUrlInitHistoryEdit->get_text();
+
+ initUrlHistory( uri );
+ }
+ else
+ if ( control_id == mIdControlAddPanel )
+ {
+ addMediaPanel( mBookmarks[ rand() % ( mBookmarks.size() - 1 ) + 1 ].second );
+ }
+ else
+ if ( control_id == mIdControlRemPanel )
+ {
+ remMediaPanel( mSelectedPanel );
+ }
+ else
+ if ( control_id == mIdDisableTimeout )
+ {
+ // Set the "disable timeout" flag for all active plugins.
+ for( int i = 0; i < (int)mMediaPanels.size(); ++i )
+ {
+ mMediaPanels[ i ]->mMediaSource->setDisableTimeout(mDisableTimeout);
+ }
+ }
+ else
+ if ( control_id == mIdControlCrashPlugin )
+ {
+ // send message to plugin and ask it to crash
+ // (switch out for ReleaseCandidate version :) )
+ if(mSelectedPanel && mSelectedPanel->mMediaSource)
+ {
+ mSelectedPanel->mMediaSource->crashPlugin();
+ }
+ }
+ else
+ if ( control_id == mIdControlHangPlugin )
+ {
+ // send message to plugin and ask it to hang
+ // (switch out for ReleaseCandidate version :) )
+ if(mSelectedPanel && mSelectedPanel->mMediaSource)
+ {
+ mSelectedPanel->mMediaSource->hangPlugin();
+ }
+ }
+ else
+ if ( control_id == mIdControlExitApp )
+ {
+ // text for exiting plugin system cleanly
+ delete this; // clean up
+ exit( 0 );
+ }
+ else
+ if ( control_id == mIdMediaTimeControlPlay )
+ {
+ if ( mSelectedPanel )
+ {
+ mSelectedPanel->mMediaSource->setLoop( false );
+ mSelectedPanel->mMediaSource->start();
+ };
+ }
+ else
+ if ( control_id == mIdMediaTimeControlLoop )
+ {
+ if ( mSelectedPanel )
+ {
+ mSelectedPanel->mMediaSource->setLoop( true );
+ mSelectedPanel->mMediaSource->start();
+ };
+ }
+ else
+ if ( control_id == mIdMediaTimeControlPause )
+ {
+ if ( mSelectedPanel )
+ mSelectedPanel->mMediaSource->pause();
+ }
+ else
+ if ( control_id == mIdMediaTimeControlStop )
+ {
+ if ( mSelectedPanel )
+ {
+ mSelectedPanel->mMediaSource->stop();
+ };
+ }
+ else
+ if ( control_id == mIdMediaTimeControlSeek )
+ {
+ if ( mSelectedPanel )
+ {
+ // get value from spinner
+ float seconds_to_seek = mMediaTimeControlSeekSeconds;
+ mSelectedPanel->mMediaSource->seek( seconds_to_seek );
+ mSelectedPanel->mMediaSource->start();
+ };
+ }
+ else
+ if ( control_id == mIdMediaTimeControlRewind )
+ {
+ if ( mSelectedPanel )
+ {
+ mSelectedPanel->mMediaSource->setLoop( false );
+ mSelectedPanel->mMediaSource->start(-2.0f);
+ };
+ }
+ else
+ if ( control_id == mIdMediaTimeControlFastForward )
+ {
+ if ( mSelectedPanel )
+ {
+ mSelectedPanel->mMediaSource->setLoop( false );
+ mSelectedPanel->mMediaSource->start(2.0f);
+ };
+ }
+ else
+ if ( control_id == mIdMediaBrowserControlBack )
+ {
+ if ( mSelectedPanel )
+ mSelectedPanel->mMediaSource->browse_back();
+ }
+ else
+ if ( control_id == mIdMediaBrowserControlStop )
+ {
+ if ( mSelectedPanel )
+ mSelectedPanel->mMediaSource->browse_stop();
+ }
+ else
+ if ( control_id == mIdMediaBrowserControlForward )
+ {
+ if ( mSelectedPanel )
+ mSelectedPanel->mMediaSource->browse_forward();
+ }
+ else
+ if ( control_id == mIdMediaBrowserControlHome )
+ {
+ if ( mSelectedPanel )
+ mSelectedPanel->mMediaSource->loadURI( mHomeWebUrl );
+ }
+ else
+ if ( control_id == mIdMediaBrowserControlReload )
+ {
+ if ( mSelectedPanel )
+ mSelectedPanel->mMediaSource->browse_reload( true );
+ }
+ else
+ if ( control_id == mIdMediaBrowserControlClearCache )
+ {
+ if ( mSelectedPanel )
+ mSelectedPanel->mMediaSource->clear_cache();
+ }
+ else
+ if ( control_id == mIdMediaBrowserControlClearCookies )
+ {
+ if ( mSelectedPanel )
+ mSelectedPanel->mMediaSource->clear_cookies();
+ }
+ else
+ if ( control_id == mIdMediaBrowserControlEnableCookies )
+ {
+ if ( mSelectedPanel )
+ {
+ if ( mMediaBrowserControlEnableCookies )
+ {
+ mSelectedPanel->mMediaSource->enable_cookies( true );
+ }
+ else
+ {
+ mSelectedPanel->mMediaSource->enable_cookies( false );
+ }
+ };
+ };
+}
+
+////////////////////////////////////////////////////////////////////////////////
+//
+void LLMediaPluginTest::keyboard( int key )
+{
+ //if ( key == 'a' || key == 'A' )
+ // addMediaPanel( mBookmarks[ rand() % ( mBookmarks.size() - 1 ) + 1 ].second );
+ //else
+ //if ( key == 'r' || key == 'R' )
+ // remMediaPanel( mSelectedPanel );
+ //else
+ //if ( key == 'd' || key == 'D' )
+ // dumpPanelInfo();
+ //else
+ if ( key == 27 )
+ {
+ std::cout << "Application finished - exiting..." << std::endl;
+ delete this;
+ exit( 0 );
+ };
+
+ mSelectedPanel->mMediaSource->keyEvent( LLPluginClassMedia::KEY_EVENT_DOWN, key, 0 );
+ mSelectedPanel->mMediaSource->keyEvent( LLPluginClassMedia::KEY_EVENT_UP, key, 0 );
+};
+
+////////////////////////////////////////////////////////////////////////////////
+//
+void LLMediaPluginTest::mouseButton( int button, int state, int x, int y )
+{
+ if ( button == GLUT_LEFT_BUTTON )
+ {
+ if ( state == GLUT_DOWN )
+ {
+ int media_x, media_y, id;
+ windowPosToTexturePos( x, y, media_x, media_y, id );
+
+ if ( mSelectedPanel )
+ mSelectedPanel->mMediaSource->mouseEvent( LLPluginClassMedia::MOUSE_EVENT_DOWN, media_x, media_y, 0 );
+ }
+ else
+ if ( state == GLUT_UP )
+ {
+ int media_x, media_y, id;
+ windowPosToTexturePos( x, y, media_x, media_y, id );
+
+ // only select a panel if we're on a panel
+ // (HACK: strictly speaking this rules out clicking on
+ // the origin of a panel but that's very unlikely)
+ if ( media_x > 0 && media_y > 0 )
+ {
+ selectPanelById( id );
+
+ if ( mSelectedPanel )
+ mSelectedPanel->mMediaSource->mouseEvent( LLPluginClassMedia::MOUSE_EVENT_UP, media_x, media_y, 0 );
+ };
+ };
+ };
+}
+
+////////////////////////////////////////////////////////////////////////////////
+//
+void LLMediaPluginTest::mousePassive( int x, int y )
+{
+ int media_x, media_y, id;
+ windowPosToTexturePos( x, y, media_x, media_y, id );
+
+ if ( mSelectedPanel )
+ mSelectedPanel->mMediaSource->mouseEvent( LLPluginClassMedia::MOUSE_EVENT_MOVE, media_x, media_y, 0 );
+}
+
+////////////////////////////////////////////////////////////////////////////////
+//
+void LLMediaPluginTest::mouseMove( int x, int y )
+{
+ int media_x, media_y, id;
+ windowPosToTexturePos( x, y, media_x, media_y, id );
+
+ if ( mSelectedPanel )
+ mSelectedPanel->mMediaSource->mouseEvent( LLPluginClassMedia::MOUSE_EVENT_MOVE, media_x, media_y, 0 );
+}
+
+////////////////////////////////////////////////////////////////////////////////
+//
+void LLMediaPluginTest::makeChrome()
+{
+ // IDs used by GLUI
+ int start_id = 0x1000;
+
+ // right side window - geometry manipulators
+#if __APPLE__
+ // the Apple GLUT implementation doesn't seem to set the graphic offset of subwindows correctly when they overlap in certain ways.
+ // Use a separate controls window in this case.
+ // GLUI window at right containing manipulation controls and other buttons
+ int x = glutGet(GLUT_WINDOW_X) + glutGet(GLUT_WINDOW_WIDTH) + 4;
+ int y = glutGet(GLUT_WINDOW_Y);
+ GLUI* right_glui_window = GLUI_Master.create_glui( "", 0, x, y );
+#else
+ GLUI* right_glui_window = GLUI_Master.create_glui_subwindow( mAppWindow, GLUI_SUBWINDOW_RIGHT );
+#endif
+ mViewRotationCtrl = right_glui_window->add_rotation( "Rotation", mViewRotation );
+ mViewTranslationCtrl = right_glui_window->add_translation( "Translate", GLUI_TRANSLATION_XY, mViewPos );
+ mViewTranslationCtrl->set_speed( 0.01f );
+ mViewScaleCtrl = right_glui_window->add_translation( "Scale", GLUI_TRANSLATION_Z, &mViewPos[ 2 ] );
+ mViewScaleCtrl->set_speed( 0.05f );
+ right_glui_window->set_main_gfx_window( mAppWindow );
+
+ // right side window - app controls
+ mIdControlAddPanel = start_id++;
+ right_glui_window->add_statictext( "" );
+ right_glui_window->add_separator();
+ right_glui_window->add_statictext( "" );
+ right_glui_window->add_button( "Add panel", mIdControlAddPanel, gluiCallbackWrapper );
+ right_glui_window->add_statictext( "" );
+ mIdControlRemPanel = start_id++;
+ right_glui_window->add_button( "Rem panel", mIdControlRemPanel, gluiCallbackWrapper );
+ right_glui_window->add_statictext( "" );
+ right_glui_window->add_separator();
+ right_glui_window->add_statictext( "" );
+ mIdControlCrashPlugin = start_id++;
+ right_glui_window->add_button( "Crash plugin", mIdControlCrashPlugin, gluiCallbackWrapper );
+ mIdControlHangPlugin = start_id++;
+ right_glui_window->add_button( "Hang plugin", mIdControlHangPlugin, gluiCallbackWrapper );
+
+ right_glui_window->add_statictext( "" );
+ right_glui_window->add_separator();
+ right_glui_window->add_statictext( "" );
+ mIdControlExitApp = start_id++;
+ right_glui_window->add_button( "Exit app", mIdControlExitApp, gluiCallbackWrapper );
+
+ //// top window - holds bookmark UI
+ mIdBookmarks = start_id++;
+ mSelBookmark = 0;
+ GLUI* glui_window_top = GLUI_Master.create_glui_subwindow( mAppWindow, GLUI_SUBWINDOW_TOP );
+ mBookmarkList = glui_window_top->add_listbox( "", &mSelBookmark, mIdBookmarks, gluiCallbackWrapper );
+ // only add the first 50 bookmarks - list can be very long sometimes (30,000+)
+ // when testing list of media URLs from AGNI for example
+ for( unsigned int each = 0; each < mBookmarks.size() && each < 50; ++each )
+ mBookmarkList->add_item( each, const_cast< char* >( mBookmarks[ each ].first.c_str() ) );
+ glui_window_top->set_main_gfx_window( mAppWindow );
+
+ glui_window_top->add_column( false );
+ mIdUrlEdit = start_id++;
+ mUrlEdit = glui_window_top->add_edittext( "Url:", GLUI_EDITTEXT_TEXT, 0, mIdUrlEdit, gluiCallbackWrapper );
+ mUrlEdit->set_w( 600 );
+ GLUI* glui_window_top2 = GLUI_Master.create_glui_subwindow( mAppWindow, GLUI_SUBWINDOW_TOP );
+ mIdUrlInitHistoryEdit = start_id++;
+ mUrlInitHistoryEdit = glui_window_top2->add_edittext( "Init History (separate by commas or semicolons):",
+ GLUI_EDITTEXT_TEXT, 0, mIdUrlInitHistoryEdit, gluiCallbackWrapper );
+ mUrlInitHistoryEdit->set_w( 800 );
+
+ // top window - media controls for "time" media types (e.g. movies)
+ mGluiMediaTimeControlWindow = GLUI_Master.create_glui_subwindow( mAppWindow, GLUI_SUBWINDOW_TOP );
+ mGluiMediaTimeControlWindow->set_main_gfx_window( mAppWindow );
+ mIdMediaTimeControlPlay = start_id++;
+ mGluiMediaTimeControlWindow->add_button( "PLAY", mIdMediaTimeControlPlay, gluiCallbackWrapper );
+ mGluiMediaTimeControlWindow->add_column( false );
+ mIdMediaTimeControlLoop = start_id++;
+ mGluiMediaTimeControlWindow->add_button( "LOOP", mIdMediaTimeControlLoop, gluiCallbackWrapper );
+ mGluiMediaTimeControlWindow->add_column( false );
+ mIdMediaTimeControlPause = start_id++;
+ mGluiMediaTimeControlWindow->add_button( "PAUSE", mIdMediaTimeControlPause, gluiCallbackWrapper );
+ mGluiMediaTimeControlWindow->add_column( false );
+
+ GLUI_Button *button;
+ mIdMediaTimeControlRewind = start_id++;
+ button = mGluiMediaTimeControlWindow->add_button( "<<", mIdMediaTimeControlRewind, gluiCallbackWrapper );
+ button->set_w(30);
+ mGluiMediaTimeControlWindow->add_column( false );
+ mIdMediaTimeControlFastForward = start_id++;
+ button = mGluiMediaTimeControlWindow->add_button( ">>", mIdMediaTimeControlFastForward, gluiCallbackWrapper );
+ button->set_w(30);
+
+ mGluiMediaTimeControlWindow->add_column( true );
+
+ mIdMediaTimeControlStop = start_id++;
+ mGluiMediaTimeControlWindow->add_button( "STOP", mIdMediaTimeControlStop, gluiCallbackWrapper );
+ mGluiMediaTimeControlWindow->add_column( false );
+ mIdMediaTimeControlVolume = start_id++;
+ GLUI_Spinner* spinner = mGluiMediaTimeControlWindow->add_spinner( "Volume", 2, &mMediaTimeControlVolume, mIdMediaTimeControlVolume, gluiCallbackWrapper);
+ spinner->set_float_limits( 0, 100 );
+ mGluiMediaTimeControlWindow->add_column( true );
+ mIdMediaTimeControlSeekSeconds = start_id++;
+ spinner = mGluiMediaTimeControlWindow->add_spinner( "", 2, &mMediaTimeControlSeekSeconds, mIdMediaTimeControlSeekSeconds, gluiCallbackWrapper);
+ spinner->set_float_limits( 0, 200 );
+ spinner->set_w( 32 );
+ spinner->set_speed( 0.025f );
+ mGluiMediaTimeControlWindow->add_column( false );
+ mIdMediaTimeControlSeek = start_id++;
+ mGluiMediaTimeControlWindow->add_button( "SEEK", mIdMediaTimeControlSeek, gluiCallbackWrapper );
+ mGluiMediaTimeControlWindow->add_column( false );
+
+
+ // top window - media controls for "browser" media types (e.g. web browser)
+ mGluiMediaBrowserControlWindow = GLUI_Master.create_glui_subwindow( mAppWindow, GLUI_SUBWINDOW_TOP );
+ mGluiMediaBrowserControlWindow->set_main_gfx_window( mAppWindow );
+ mIdMediaBrowserControlBack = start_id++;
+ mMediaBrowserControlBackButton = mGluiMediaBrowserControlWindow->add_button( "BACK", mIdMediaBrowserControlBack, gluiCallbackWrapper );
+ mGluiMediaBrowserControlWindow->add_column( false );
+ mIdMediaBrowserControlStop = start_id++;
+ mGluiMediaBrowserControlWindow->add_button( "STOP", mIdMediaBrowserControlStop, gluiCallbackWrapper );
+ mGluiMediaBrowserControlWindow->add_column( false );
+ mIdMediaBrowserControlForward = start_id++;
+ mMediaBrowserControlForwardButton = mGluiMediaBrowserControlWindow->add_button( "FORWARD", mIdMediaBrowserControlForward, gluiCallbackWrapper );
+ mGluiMediaBrowserControlWindow->add_column( false );
+ mIdMediaBrowserControlHome = start_id++;
+ mGluiMediaBrowserControlWindow->add_button( "HOME", mIdMediaBrowserControlHome, gluiCallbackWrapper );
+ mGluiMediaBrowserControlWindow->add_column( false );
+ mIdMediaBrowserControlReload = start_id++;
+ mGluiMediaBrowserControlWindow->add_button( "RELOAD", mIdMediaBrowserControlReload, gluiCallbackWrapper );
+ mGluiMediaBrowserControlWindow->add_column( false );
+ mIdMediaBrowserControlClearCache = start_id++;
+ mGluiMediaBrowserControlWindow->add_button( "CLEAR CACHE", mIdMediaBrowserControlClearCache, gluiCallbackWrapper );
+ mGluiMediaBrowserControlWindow->add_column( false );
+ mIdMediaBrowserControlClearCookies = start_id++;
+ mGluiMediaBrowserControlWindow->add_button( "CLEAR COOKIES", mIdMediaBrowserControlClearCookies, gluiCallbackWrapper );
+ mGluiMediaBrowserControlWindow->add_column( false );
+ mIdMediaBrowserControlEnableCookies = start_id++;
+ mMediaBrowserControlEnableCookies = 0;
+ mGluiMediaBrowserControlWindow->add_checkbox( "Enable Cookies", &mMediaBrowserControlEnableCookies, mIdMediaBrowserControlEnableCookies, gluiCallbackWrapper );
+
+ // top window - misc controls
+ GLUI* glui_window_misc_control = GLUI_Master.create_glui_subwindow( mAppWindow, GLUI_SUBWINDOW_TOP );
+ mIdRandomPanelCount = start_id++;
+ mRandomPanelCount = 0;
+ glui_window_misc_control->add_checkbox( "Randomize panel count", &mRandomPanelCount, mIdRandomPanelCount, gluiCallbackWrapper );
+ glui_window_misc_control->set_main_gfx_window( mAppWindow );
+ glui_window_misc_control->add_column( true );
+ mIdRandomBookmarks = start_id++;
+ mRandomBookmarks = 0;
+ glui_window_misc_control->add_checkbox( "Randomize bookmarks", &mRandomBookmarks, mIdRandomBookmarks, gluiCallbackWrapper );
+ glui_window_misc_control->set_main_gfx_window( mAppWindow );
+ glui_window_misc_control->add_column( true );
+
+ mIdDisableTimeout = start_id++;
+ mDisableTimeout = 0;
+ glui_window_misc_control->add_checkbox( "Disable plugin timeout", &mDisableTimeout, mIdDisableTimeout, gluiCallbackWrapper );
+ glui_window_misc_control->set_main_gfx_window( mAppWindow );
+
+ // bottom window - status
+ mBottomGLUIWindow = GLUI_Master.create_glui_subwindow( mAppWindow, GLUI_SUBWINDOW_BOTTOM );
+ mStatusText = mBottomGLUIWindow->add_statictext( "" );
+ mBottomGLUIWindow->set_main_gfx_window( mAppWindow );
+}
+
+////////////////////////////////////////////////////////////////////////////////
+//
+void LLMediaPluginTest::resetView()
+{
+ mViewRotationCtrl->reset();
+
+ mViewScaleCtrl->set_x( 0.0f );
+ mViewScaleCtrl->set_y( 0.0f );
+ mViewScaleCtrl->set_z( 3.0f );
+
+ mViewTranslationCtrl->set_x( 0.0f );
+ mViewTranslationCtrl->set_y( 0.0f );
+ mViewTranslationCtrl->set_z( 0.0f );
+}
+
+////////////////////////////////////////////////////////////////////////////////
+//
+void LLMediaPluginTest::makePickTexture( int id, GLuint* texture_handle, unsigned char** texture_pixels )
+{
+ int pick_texture_width = 1024;
+ int pick_texture_height = 1024;
+ int pick_texture_depth = 3;
+ unsigned char* ptr = new unsigned char[ pick_texture_width * pick_texture_height * pick_texture_depth ];
+ for( int y = 0; y < pick_texture_height; ++y )
+ {
+ for( int x = 0; x < pick_texture_width * pick_texture_depth ; x += pick_texture_depth )
+ {
+ unsigned long bits = 0L;
+ bits |= ( id << 20 ) | ( y << 10 ) | ( x / 3 );
+ unsigned char r_component = ( bits >> 16 ) & 0xff;
+ unsigned char g_component = ( bits >> 8 ) & 0xff;
+ unsigned char b_component = bits & 0xff;
+
+ ptr[ y * pick_texture_width * pick_texture_depth + x + 0 ] = r_component;
+ ptr[ y * pick_texture_width * pick_texture_depth + x + 1 ] = g_component;
+ ptr[ y * pick_texture_width * pick_texture_depth + x + 2 ] = b_component;
+ };
+ };
+
+ glGenTextures( 1, texture_handle );
+
+ checkGLError("glGenTextures");
+ std::cout << "glGenTextures returned " << *texture_handle << std::endl;
+
+ bindTexture( *texture_handle );
+ glTexImage2D( GL_TEXTURE_2D, 0,
+ GL_RGB,
+ pick_texture_width, pick_texture_height,
+ 0, GL_RGB, GL_UNSIGNED_BYTE, ptr );
+
+ *texture_pixels = ptr;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+//
+std::string LLMediaPluginTest::mimeTypeFromUrl( std::string& url )
+{
+ // default to web
+ std::string mime_type = "text/html";
+
+ // we may need a more advanced MIME type accessor later :-)
+ if ( url.find( ".mov" ) != std::string::npos ) // Movies
+ mime_type = "video/quicktime";
+ else
+ if ( url.find( ".txt" ) != std::string::npos ) // Apple Text descriptors
+ mime_type = "video/quicktime";
+
+ return mime_type;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+//
+std::string LLMediaPluginTest::pluginNameFromMimeType( std::string& mime_type )
+{
+#if LL_DARWIN
+ std::string plugin_name( "media_plugin_null.dylib" );
+ if ( mime_type == "video/quicktime" )
+ plugin_name = "media_plugin_quicktime.dylib";
+ else
+ if ( mime_type == "text/html" )
+ plugin_name = "media_plugin_webkit.dylib";
+
+#elif LL_WINDOWS
+ std::string plugin_name( "media_plugin_null.dll" );
+
+ if ( mime_type == "video/quicktime" )
+ plugin_name = "media_plugin_quicktime.dll";
+ else
+ if ( mime_type == "text/html" )
+ plugin_name = "media_plugin_webkit.dll";
+
+#elif LL_LINUX
+ std::string plugin_name( "libmedia_plugin_null.so" );
+
+ if ( mime_type == "video/quicktime" )
+ plugin_name = "libmedia_plugin_quicktime.so";
+ else
+ if ( mime_type == "text/html" )
+ plugin_name = "libmedia_plugin_webkit.so";
+#endif
+ return plugin_name;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+//
+void LLMediaPluginTest::addMediaPanel( std::string url )
+{
+ // Get the plugin filename using the URL
+ std::string mime_type = mimeTypeFromUrl( url );
+ std::string plugin_name = pluginNameFromMimeType( mime_type );
+
+ // create a random size for the new media
+ int media_width;
+ int media_height;
+ getRandomMediaSize( media_width, media_height, mime_type );
+
+ // make a new plugin
+ LLPluginClassMedia* media_source = new LLPluginClassMedia(this);
+
+ // tell the plugin what size we asked for
+ media_source->setSize( media_width, media_height );
+
+ // Use the launcher start and initialize the plugin
+#if LL_DARWIN || LL_LINUX
+ std::string launcher_name( "SLPlugin" );
+#elif LL_WINDOWS
+ std::string launcher_name( "SLPlugin.exe" );
+#endif
+ media_source->init( launcher_name, plugin_name );
+ media_source->setDisableTimeout(mDisableTimeout);
+
+ // make a new panel and save parameters
+ mediaPanel* panel = new mediaPanel;
+ panel->mMediaSource = media_source;
+ panel->mStartUrl = url;
+ panel->mMimeType = mime_type;
+ panel->mMediaWidth = media_width;
+ panel->mMediaHeight = media_height;
+ panel->mTextureWidth = 0;
+ panel->mTextureHeight = 0;
+ panel->mTextureScaleX = 0;
+ panel->mTextureScaleY = 0;
+ panel->mMediaTextureHandle = 0;
+ panel->mPickTextureHandle = 0;
+ panel->mAppTextureCoordsOpenGL = false; // really need an 'undefined' state here too
+ panel->mReadyToRender = false;
+
+ // look through current media panels to find an unused index number
+ bool id_exists = true;
+ for( int nid = 0; nid < mMaxPanels; ++nid )
+ {
+ // does this id exist already?
+ id_exists = false;
+ for( int pid = 0; pid < (int)mMediaPanels.size(); ++pid )
+ {
+ if ( nid == mMediaPanels[ pid ]->mId )
+ {
+ id_exists = true;
+ break;
+ };
+ };
+
+ // id wasn't found so we can use it
+ if ( ! id_exists )
+ {
+ panel->mId = nid;
+ break;
+ };
+ };
+
+ // if we get here and this flag is set, there is no room for any more panels
+ if ( id_exists )
+ {
+ std::cout << "No room for any more panels" << std::endl;
+ }
+ else
+ {
+ // now we have the ID we can use it to make the
+ // pick texture (id is baked into texture pixels)
+ makePickTexture( panel->mId, &panel->mPickTextureHandle, &panel->mPickTexturePixels );
+
+ // save this in the list of panels
+ mMediaPanels.push_back( panel );
+
+ // select the panel that was just created
+ selectPanel( panel );
+
+ // load and start the URL
+ panel->mMediaSource->loadURI( url );
+ panel->mMediaSource->start();
+
+ std::cout << "Adding new media panel for " << url << "(" << media_width << "x" << media_height << ") with index " << panel->mId << " - total panels = " << mMediaPanels.size() << std::endl;
+ }
+}
+
+////////////////////////////////////////////////////////////////////////////////
+//
+void LLMediaPluginTest::updateMediaPanel( mediaPanel* panel )
+{
+// checkGLError("LLMediaPluginTest::updateMediaPanel");
+
+ if ( ! panel )
+ return;
+
+ if(!panel->mMediaSource || !panel->mMediaSource->textureValid())
+ {
+ panel->mReadyToRender = false;
+ return;
+ }
+
+ // take a reference copy of the plugin values since they
+ // might change during this lifetime of this function
+ int plugin_media_width = panel->mMediaSource->getWidth();
+ int plugin_media_height = panel->mMediaSource->getHeight();
+ int plugin_texture_width = panel->mMediaSource->getBitsWidth();
+ int plugin_texture_height = panel->mMediaSource->getBitsHeight();
+
+ // If the texture isn't created or the media or texture dimensions changed AND
+ // the sizes are valid then we need to delete the old media texture (if necessary)
+ // then make a new one.
+ if ((panel->mMediaTextureHandle == 0 ||
+ panel->mMediaWidth != plugin_media_width ||
+ panel->mMediaHeight != plugin_media_height ||
+ panel->mTextureWidth != plugin_texture_width ||
+ panel->mTextureHeight != plugin_texture_height) &&
+ ( plugin_media_width > 0 && plugin_media_height > 0 &&
+ plugin_texture_width > 0 && plugin_texture_height > 0 ) )
+ {
+ std::cout << "Valid media size (" << plugin_media_width << " x " << plugin_media_height
+ << ") and texture size (" << plugin_texture_width << " x " << plugin_texture_height
+ << ") for panel with ID=" << panel->mId << " - making texture" << std::endl;
+
+ // delete old GL texture
+ if ( isTexture( panel->mMediaTextureHandle ) )
+ {
+ std::cerr << "updateMediaPanel: deleting texture " << panel->mMediaTextureHandle << std::endl;
+ glDeleteTextures( 1, &panel->mMediaTextureHandle );
+ panel->mMediaTextureHandle = 0;
+ }
+
+ std::cerr << "before: pick texture is " << panel->mPickTextureHandle << ", media texture is " << panel->mMediaTextureHandle << std::endl;
+
+ // make a GL texture based on the dimensions the plugin told us
+ GLuint new_texture = 0;
+ glGenTextures( 1, &new_texture );
+
+ checkGLError("glGenTextures");
+
+ std::cout << "glGenTextures returned " << new_texture << std::endl;
+
+ panel->mMediaTextureHandle = new_texture;
+
+ bindTexture( panel->mMediaTextureHandle );
+
+ std::cout << "Setting texture size to " << plugin_texture_width << " x " << plugin_texture_height << std::endl;
+ glTexImage2D( GL_TEXTURE_2D, 0,
+ GL_RGB,
+ plugin_texture_width, plugin_texture_height,
+ 0, GL_RGB, GL_UNSIGNED_BYTE,
+ 0 );
+
+
+ std::cerr << "after: pick texture is " << panel->mPickTextureHandle << ", media texture is " << panel->mMediaTextureHandle << std::endl;
+ };
+
+ // update our record of the media and texture dimensions
+ // NOTE: do this after we we check for sizes changes
+ panel->mMediaWidth = plugin_media_width;
+ panel->mMediaHeight = plugin_media_height;
+ panel->mTextureWidth = plugin_texture_width;
+ panel->mTextureHeight = plugin_texture_height;
+ if ( plugin_texture_width > 0 )
+ {
+ panel->mTextureScaleX = (double)panel->mMediaWidth / (double)panel->mTextureWidth;
+ };
+ if ( plugin_texture_height > 0 )
+ {
+ panel->mTextureScaleY = (double)panel->mMediaHeight / (double)panel->mTextureHeight;
+ };
+
+ // update the flag which tells us if the media source uses OprnGL coords or not.
+ panel->mAppTextureCoordsOpenGL = panel->mMediaSource->getTextureCoordsOpenGL();
+
+ // Check to see if we have enough to render this panel.
+ // If we do, set a flag that the display functions use so
+ // they only render a panel with media if it's ready.
+ if ( panel->mMediaWidth < 0 ||
+ panel->mMediaHeight < 0 ||
+ panel->mTextureWidth < 1 ||
+ panel->mTextureHeight < 1 ||
+ panel->mMediaTextureHandle == 0 )
+ {
+ panel->mReadyToRender = false;
+ };
+}
+
+////////////////////////////////////////////////////////////////////////////////
+//
+void LLMediaPluginTest::replaceMediaPanel( mediaPanel* panel, std::string url )
+{
+ // no media panels so we can't change anything - have to add
+ if ( mMediaPanels.size() == 0 )
+ return;
+
+ // sanity check
+ if ( ! panel )
+ return;
+
+ int index;
+ for(index = 0; index < (int)mMediaPanels.size(); index++)
+ {
+ if(mMediaPanels[index] == panel)
+ break;
+ }
+
+ if(index >= (int)mMediaPanels.size())
+ {
+ // panel isn't in mMediaPanels
+ return;
+ }
+
+ std::cout << "Replacing media panel with index " << panel->mId << std::endl;
+
+ int panel_id = panel->mId;
+
+ if(mSelectedPanel == panel)
+ mSelectedPanel = NULL;
+
+ delete panel;
+
+ // Get the plugin filename using the URL
+ std::string mime_type = mimeTypeFromUrl( url );
+ std::string plugin_name = pluginNameFromMimeType( mime_type );
+
+ // create a random size for the new media
+ int media_width;
+ int media_height;
+ getRandomMediaSize( media_width, media_height, mime_type );
+
+ // make a new plugin
+ LLPluginClassMedia* media_source = new LLPluginClassMedia(this);
+
+ // tell the plugin what size we asked for
+ media_source->setSize( media_width, media_height );
+
+ // Use the launcher start and initialize the plugin
+#if LL_DARWIN || LL_LINUX
+ std::string launcher_name( "SLPlugin" );
+#elif LL_WINDOWS
+ std::string launcher_name( "SLPlugin.exe" );
+#endif
+ media_source->init( launcher_name, plugin_name );
+ media_source->setDisableTimeout(mDisableTimeout);
+
+ // make a new panel and save parameters
+ panel = new mediaPanel;
+ panel->mMediaSource = media_source;
+ panel->mStartUrl = url;
+ panel->mMimeType = mime_type;
+ panel->mMediaWidth = media_width;
+ panel->mMediaHeight = media_height;
+ panel->mTextureWidth = 0;
+ panel->mTextureHeight = 0;
+ panel->mTextureScaleX = 0;
+ panel->mTextureScaleY = 0;
+ panel->mMediaTextureHandle = 0;
+ panel->mPickTextureHandle = 0;
+ panel->mAppTextureCoordsOpenGL = false; // really need an 'undefined' state here too
+ panel->mReadyToRender = false;
+
+ panel->mId = panel_id;
+
+ // Replace the entry in the panels array
+ mMediaPanels[index] = panel;
+
+ // now we have the ID we can use it to make the
+ // pick texture (id is baked into texture pixels)
+ makePickTexture( panel->mId, &panel->mPickTextureHandle, &panel->mPickTexturePixels );
+
+ // select the panel that was just created
+ selectPanel( panel );
+
+ // load and start the URL
+ panel->mMediaSource->loadURI( url );
+ panel->mMediaSource->start();
+}
+
+////////////////////////////////////////////////////////////////////////////////
+//
+void LLMediaPluginTest::getRandomMediaSize( int& width, int& height, std::string mime_type )
+{
+ // Make a new media source with a random size which we'll either
+ // directly or the media plugin will tell us what it wants later.
+ // Use a random size so we can test support for weird media sizes.
+ // (Almost everything else will get filled in later once the
+ // plugin responds)
+ // NB. Do we need to enforce that width is on 4 pixel boundary?
+ width = ( ( rand() % 170 ) + 30 ) * 4;
+ height = ( ( rand() % 170 ) + 30 ) * 4;
+
+ // adjust this random size if it's a browser so we get
+ // a more useful size for testing..
+ if ( mime_type == "text/html" )
+ {
+ width = ( ( rand() % 100 ) + 100 ) * 4;
+ height = ( width * ( ( rand() % 400 ) + 1000 ) ) / 1000;
+ };
+}
+
+////////////////////////////////////////////////////////////////////////////////
+//
+void LLMediaPluginTest::remMediaPanel( mediaPanel* panel )
+{
+ // always leave one panel
+ if ( mMediaPanels.size() == 1 )
+ return;
+
+ // sanity check - don't think this can happen but see above for a case where it might...
+ if ( ! panel )
+ return;
+
+ std::cout << "Removing media panel with index " << panel->mId << " - total panels = " << mMediaPanels.size() - 1 << std::endl;
+
+ if(mSelectedPanel == panel)
+ mSelectedPanel = NULL;
+
+ delete panel;
+
+ // remove from storage list
+ for( int i = 0; i < (int)mMediaPanels.size(); ++i )
+ {
+ if ( mMediaPanels[ i ] == panel )
+ {
+ mMediaPanels.erase( mMediaPanels.begin() + i );
+ break;
+ };
+ };
+
+ // select the first panel
+ selectPanel( mMediaPanels[ 0 ] );
+}
+
+////////////////////////////////////////////////////////////////////////////////
+//
+void LLMediaPluginTest::updateStatusBar()
+{
+ if ( ! mSelectedPanel )
+ return;
+
+ // cache results - this is a very slow function
+ static int cached_id = -1;
+ static int cached_media_width = -1;
+ static int cached_media_height = -1;
+ static int cached_texture_width = -1;
+ static int cached_texture_height = -1;
+ static bool cached_supports_browser_media = true;
+ static bool cached_supports_time_media = false;
+ static int cached_movie_time = -1;
+
+ static std::string cached_plugin_version = "";
+ if (
+ cached_id == mSelectedPanel->mId &&
+ cached_media_width == mSelectedPanel->mMediaWidth &&
+ cached_media_height == mSelectedPanel->mMediaHeight &&
+ cached_texture_width == mSelectedPanel->mTextureWidth &&
+ cached_texture_height == mSelectedPanel->mTextureHeight &&
+ cached_supports_browser_media == mSelectedPanel->mMediaSource->pluginSupportsMediaBrowser() &&
+ cached_supports_time_media == mSelectedPanel->mMediaSource->pluginSupportsMediaTime() &&
+ cached_plugin_version == mSelectedPanel->mMediaSource->getPluginVersion() &&
+ cached_movie_time == (int)mSelectedPanel->mMediaSource->getCurrentTime()
+ )
+ {
+ // nothing changed so don't spend time in this shitty function
+ return;
+ };
+
+ std::ostringstream stream( "" );
+
+ stream.str( "" );
+ stream.clear();
+
+ stream << "Id: ";
+ stream << std::setw( 2 ) << std::setfill( '0' );
+ stream << mSelectedPanel->mId;
+ stream << " | ";
+ stream << "Media: ";
+ stream << std::setw( 3 ) << std::setfill( '0' );
+ stream << mSelectedPanel->mMediaWidth;
+ stream << " x ";
+ stream << std::setw( 3 ) << std::setfill( '0' );
+ stream << mSelectedPanel->mMediaHeight;
+ stream << " | ";
+ stream << "Texture: ";
+ stream << std::setw( 4 ) << std::setfill( '0' );
+ stream << mSelectedPanel->mTextureWidth;
+ stream << " x ";
+ stream << std::setw( 4 ) << std::setfill( '0' );
+ stream << mSelectedPanel->mTextureHeight;
+ stream << " | ";
+ if ( mSelectedPanel->mMediaSource->pluginSupportsMediaBrowser() )
+ stream << "BROWSER";
+ else
+ if ( mSelectedPanel->mMediaSource->pluginSupportsMediaTime() )
+ stream << "TIME ";
+ stream << " | ";
+ stream << mSelectedPanel->mMediaSource->getPluginVersion();
+ stream << " | ";
+ if ( mSelectedPanel->mMediaSource->pluginSupportsMediaTime() )
+ {
+ stream << std::setw( 3 ) << std::setfill( '0' );
+ stream << (int)mSelectedPanel->mMediaSource->getCurrentTime();
+ stream << " / ";
+ stream << std::setw( 3 ) << std::setfill( '0' );
+ stream << (int)mSelectedPanel->mMediaSource->getDuration();
+ stream << " @ ";
+ stream << (int)mSelectedPanel->mMediaSource->getCurrentPlayRate();
+ stream << " | ";
+ };
+
+ glutSetWindow( mBottomGLUIWindow->get_glut_window_id() );
+ mStatusText->set_text( const_cast< char*>( stream.str().c_str() ) );
+ glutSetWindow( mAppWindow );
+
+ // caching
+ cached_id = mSelectedPanel->mId;
+ cached_media_width = mSelectedPanel->mMediaWidth;
+ cached_media_height = mSelectedPanel->mMediaHeight;
+ cached_texture_width = mSelectedPanel->mTextureWidth;
+ cached_texture_height = mSelectedPanel->mTextureHeight;
+ cached_supports_browser_media = mSelectedPanel->mMediaSource->pluginSupportsMediaBrowser();
+ cached_supports_time_media = mSelectedPanel->mMediaSource->pluginSupportsMediaTime();
+ cached_plugin_version = mSelectedPanel->mMediaSource->getPluginVersion();
+ cached_movie_time = (int)mSelectedPanel->mMediaSource->getCurrentTime();
+}
+
+////////////////////////////////////////////////////////////////////////////////
+//
+void LLMediaPluginTest::dumpPanelInfo()
+{
+ std::cout << std::endl << "===== Media Panels =====" << std::endl;
+ for( int i = 0; i < (int)mMediaPanels.size(); ++i )
+ {
+ std::cout << std::setw( 2 ) << std::setfill( '0' );
+ std::cout << i + 1 << "> ";
+ std::cout << "Id: ";
+ std::cout << std::setw( 2 ) << std::setfill( '0' );
+ std::cout << mMediaPanels[ i ]->mId;
+ std::cout << " | ";
+ std::cout << "Media: ";
+ std::cout << std::setw( 3 ) << std::setfill( '0' );
+ std::cout << mMediaPanels[ i ]->mMediaWidth;
+ std::cout << " x ";
+ std::cout << std::setw( 3 ) << std::setfill( '0' );
+ std::cout << mMediaPanels[ i ]->mMediaHeight;
+ std::cout << " | ";
+ std::cout << "Texture: ";
+ std::cout << std::setw( 4 ) << std::setfill( '0' );
+ std::cout << mMediaPanels[ i ]->mTextureWidth;
+ std::cout << " x ";
+ std::cout << std::setw( 4 ) << std::setfill( '0' );
+ std::cout << mMediaPanels[ i ]->mTextureHeight;
+ std::cout << " | ";
+ if ( mMediaPanels[ i ] == mSelectedPanel )
+ std::cout << "(selected)";
+
+ std::cout << std::endl;
+ };
+ std::cout << "========================" << std::endl;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+//
+void LLMediaPluginTest::handleMediaEvent(LLPluginClassMedia* self, EMediaEvent event)
+{
+ // Uncomment this to make things much, much quieter.
+// return;
+
+ switch(event)
+ {
+ case MEDIA_EVENT_CONTENT_UPDATED:
+ // too spammy -- don't log these
+// std::cerr << "Media event: MEDIA_EVENT_CONTENT_UPDATED " << std::endl;
+ break;
+
+ case MEDIA_EVENT_TIME_DURATION_UPDATED:
+ // too spammy -- don't log these
+// std::cerr << "Media event: MEDIA_EVENT_TIME_DURATION_UPDATED, time is " << self->getCurrentTime() << " of " << self->getDuration() << std::endl;
+ break;
+
+ case MEDIA_EVENT_SIZE_CHANGED:
+ std::cerr << "Media event: MEDIA_EVENT_SIZE_CHANGED " << std::endl;
+ break;
+
+ case MEDIA_EVENT_CURSOR_CHANGED:
+ std::cerr << "Media event: MEDIA_EVENT_CURSOR_CHANGED, new cursor is " << self->getCursorName() << std::endl;
+ break;
+
+ case MEDIA_EVENT_NAVIGATE_BEGIN:
+ std::cerr << "Media event: MEDIA_EVENT_NAVIGATE_BEGIN " << std::endl;
+ break;
+
+ case MEDIA_EVENT_NAVIGATE_COMPLETE:
+ std::cerr << "Media event: MEDIA_EVENT_NAVIGATE_COMPLETE, result string is: " << self->getNavigateResultString() << std::endl;
+ break;
+
+ case MEDIA_EVENT_PROGRESS_UPDATED:
+ std::cerr << "Media event: MEDIA_EVENT_PROGRESS_UPDATED, loading at " << self->getProgressPercent() << "%" << std::endl;
+ break;
+
+ case MEDIA_EVENT_STATUS_TEXT_CHANGED:
+ std::cerr << "Media event: MEDIA_EVENT_STATUS_TEXT_CHANGED, new status text is: " << self->getStatusText() << std::endl;
+ break;
+
+ case MEDIA_EVENT_LOCATION_CHANGED:
+ {
+ std::cerr << "Media event: MEDIA_EVENT_LOCATION_CHANGED, new uri is: " << self->getLocation() << std::endl;
+ mediaPanel* panel = findMediaPanel(self);
+ if(panel != NULL)
+ {
+ panel->mStartUrl = self->getLocation();
+ if(panel == mSelectedPanel)
+ {
+ mUrlEdit->set_text(const_cast<char*>(panel->mStartUrl.c_str()) );
+ }
+ }
+ }
+ break;
+
+ case MEDIA_EVENT_CLICK_LINK_HREF:
+ std::cerr << "Media event: MEDIA_EVENT_CLICK_LINK_HREF, uri is " << self->getClickURL() << std::endl;
+ break;
+
+ case MEDIA_EVENT_CLICK_LINK_NOFOLLOW:
+ std::cerr << "Media event: MEDIA_EVENT_CLICK_LINK_NOFOLLOW, uri is " << self->getClickURL() << std::endl;
+ break;
+
+ case MEDIA_EVENT_PLUGIN_FAILED:
+ std::cerr << "Media event: MEDIA_EVENT_PLUGIN_FAILED" << std::endl;
+ break;
+ }
+}
+
+////////////////////////////////////////////////////////////////////////////////
+//
+static void gluiCallbackWrapper( int control_id )
+{
+ if ( gApplication )
+ gApplication->gluiCallback( control_id );
+}
+
+////////////////////////////////////////////////////////////////////////////////
+//
+void glutReshape( int width, int height )
+{
+ if ( gApplication )
+ gApplication->reshape( width, height );
+};
+
+////////////////////////////////////////////////////////////////////////////////
+//
+void glutDisplay()
+{
+ if ( gApplication )
+ gApplication->display();
+};
+
+////////////////////////////////////////////////////////////////////////////////
+//
+void glutIdle(int update_ms)
+{
+ GLUI_Master.set_glutTimerFunc( update_ms, glutIdle, update_ms);
+
+ if ( gApplication )
+ gApplication->idle();
+
+};
+
+////////////////////////////////////////////////////////////////////////////////
+//
+void glutKeyboard( unsigned char key, int x, int y )
+{
+ if ( gApplication )
+ gApplication->keyboard( key );
+};
+
+////////////////////////////////////////////////////////////////////////////////
+//
+void glutMousePassive( int x, int y )
+{
+ if ( gApplication )
+ gApplication->mousePassive( x, y );
+}
+
+////////////////////////////////////////////////////////////////////////////////
+//
+void glutMouseMove( int x , int y )
+{
+ if ( gApplication )
+ gApplication->mouseMove( x, y );
+}
+
+////////////////////////////////////////////////////////////////////////////////
+//
+void glutMouseButton( int button, int state, int x, int y )
+{
+ if ( gApplication )
+ gApplication->mouseButton( button, state, x, y );
+}
+
+////////////////////////////////////////////////////////////////////////////////
+//
+int main( int argc, char* argv[] )
+{
+ glutInit( &argc, argv );
+ glutInitDisplayMode( GLUT_DEPTH | GLUT_DOUBLE | GLUT_RGB );
+
+ const int app_window_x = 80;
+ const int app_window_y = 0;
+ const int app_window_width = 964;
+ const int app_window_height = 964;
+
+ glutInitWindowPosition( app_window_x, app_window_y );
+ glutInitWindowSize( app_window_width, app_window_height );
+
+ int app_window_handle = glutCreateWindow( "LLMediaPluginTest2" );
+
+ glutDisplayFunc( glutDisplay );
+
+ GLUI_Master.set_glutReshapeFunc( glutReshape );
+ GLUI_Master.set_glutKeyboardFunc( glutKeyboard );
+ GLUI_Master.set_glutMouseFunc( glutMouseButton );
+
+ glutPassiveMotionFunc( glutMousePassive );
+ glutMotionFunc( glutMouseMove );
+
+ glutSetWindow( app_window_handle );
+
+ gApplication = new LLMediaPluginTest( app_window_handle, app_window_width, app_window_height );
+
+ // update at approximately 60hz
+ int update_ms = 1000 / 60;
+
+ GLUI_Master.set_glutTimerFunc( update_ms, glutIdle, update_ms);
+
+ glutMainLoop();
+
+ delete gApplication;
+}
diff --git a/indra/test_apps/llplugintest/llmediaplugintest.h b/indra/test_apps/llplugintest/llmediaplugintest.h
new file mode 100644
index 0000000000..079b40ddc0
--- /dev/null
+++ b/indra/test_apps/llplugintest/llmediaplugintest.h
@@ -0,0 +1,200 @@
+/**
+ * @file LLMediaPluginTest2.cpp
+ * @brief Primary test application for LLMedia (Separate Process) Plugin system
+ *
+ * $LicenseInfo:firstyear=2008&license=viewergpl$
+ *
+ * Copyright (c) 2009, Linden Research, Inc.
+ *
+ * Second Life Viewer Source Code
+ * The source code in this file ("Source Code") is provided by Linden Lab
+ * to you under the terms of the GNU General Public License, version 2.0
+ * ("GPL"), unless you have obtained a separate licensing agreement
+ * ("Other License"), formally executed by you and Linden Lab. Terms of
+ * the GPL can be found in doc/GPL-license.txt in this distribution, or
+ * online at http://secondlife.com/developers/opensource/gplv2
+ *
+ * There are special exceptions to the terms and conditions of the GPL as
+ * it is applied to this Source Code. View the full text of the exception
+ * in the file doc/FLOSS-exception.txt in this software distribution, or
+ * online at http://secondlife.com/developers/opensource/flossexception
+ *
+ * By copying, modifying or distributing this software, you acknowledge
+ * that you have read and understood your obligations described above,
+ * and agree to abide by those obligations.
+ *
+ * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+ * COMPLETENESS OR PERFORMANCE.
+ * $/LicenseInfo$
+ */
+
+#ifndef LL_MEDIA_PLUGIN_TEST_H
+#define LL_MEDIA_PLUGIN_TEST_H
+
+#include <vector>
+#include <string>
+#include "llpluginclassmedia.h"
+
+// Forward declarations
+class GLUI_Rotation;
+class GLUI_Translation;
+class GLUI_Listbox;
+class GLUI_EditText;
+class GLUI_StaticText;
+class GLUI;
+class GLUI_Button;
+
+////////////////////////////////////////////////////////////////////////////////
+//
+struct mediaPanel
+{
+ public:
+ mediaPanel();
+ ~mediaPanel();
+ int mId;
+ std::string mStartUrl;
+ std::string mMimeType;
+ LLPluginClassMedia *mMediaSource;
+ int mMediaWidth;
+ int mMediaHeight;
+ int mTextureWidth;
+ int mTextureHeight;
+ double mTextureScaleX;
+ double mTextureScaleY;
+ GLuint mMediaTextureHandle;
+ GLuint mPickTextureHandle;
+ unsigned char* mPickTexturePixels;
+ bool mAppTextureCoordsOpenGL;
+ bool mReadyToRender;
+};
+
+////////////////////////////////////////////////////////////////////////////////
+//
+class LLMediaPluginTest : public LLPluginClassMediaOwner
+{
+ public:
+ LLMediaPluginTest( int app_window, int window_width, int window_height );
+ ~LLMediaPluginTest();
+
+ void reshape( int width, int height );
+ void display();
+ void idle();
+ void gluiCallback( int control_id );
+ void keyboard( int key );
+ void mousePassive( int x, int y );
+ void mouseButton( int button, int state, int x, int y );
+ void mouseMove( int x, int y );
+
+ void bindTexture(GLuint texture, GLint row_length = 0, GLint alignment = 1);
+ bool checkGLError(char *name = "OpenGL");
+ void drawGeometry( int panel );
+ void startPanelHighlight( float red, float green, float blue, float line_width );
+ void endPanelHighlight();
+ enum { DrawTypePickTexture, DrawTypeMediaTexture };
+ void draw( int draw_type );
+ void windowPosToTexturePos( int window_x, int window_y, int& media_x, int& media_y, int& id );
+
+ void addMediaPanel( std::string url );
+ void updateMediaPanel( mediaPanel* panel );
+ void remMediaPanel( mediaPanel* panel );
+ void replaceMediaPanel( mediaPanel* panel, std::string url );
+ void getRandomMediaSize( int& width, int& height, std::string mime_type );
+ void navigateToNewURI( std::string uri );
+ void initUrlHistory( std::string uri );
+ void selectPanelById( int id );
+ void selectPanel( mediaPanel* panel );
+ mediaPanel* findMediaPanel( LLPluginClassMedia* panel );
+ void makePickTexture( int id, GLuint* texture_handle, unsigned char** texture_pixels );
+ void makeChrome();
+ void resetView();
+
+ void dumpPanelInfo();
+ void updateStatusBar();
+
+ // Inherited from LLPluginClassMediaOwner
+ /*virtual*/ void handleMediaEvent(LLPluginClassMedia* self, LLPluginClassMediaOwner::EMediaEvent);
+
+ private:
+ const int mVersionMajor;
+ const int mVersionMinor;
+ const int mVersionPatch;
+ const int mMaxPanels;
+ int mAppWindow;
+ int mWindowWidth;
+ int mWindowHeight;
+ int mCurMouseX;
+ int mCurMouseY;
+ unsigned char mPixelReadColor[ 3 ];
+ bool mFuzzyMedia;
+ const std::string mHomeWebUrl;
+
+ std::vector< mediaPanel* > mMediaPanels;
+ mediaPanel* mSelectedPanel;
+ std::string mimeTypeFromUrl( std::string& url );
+ std::string pluginNameFromMimeType( std::string& mime_type );
+
+ GLUI_Rotation* mViewRotationCtrl;
+ GLUI_Translation* mViewScaleCtrl;
+ GLUI_Translation* mViewTranslationCtrl;
+ float mViewportAspect;
+ float mViewPos[ 3 ];
+ float mViewRotation[ 16 ];
+
+ int mIdControlAddPanel;
+ int mIdControlRemPanel;
+
+ std::vector< std::pair< std::string, std::string > > mBookmarks;
+ GLUI_Listbox* mBookmarkList;
+ int mIdBookmarks;
+ int mIdUrlEdit;
+ GLUI_EditText* mUrlEdit;
+ int mIdUrlInitHistoryEdit;
+ GLUI_EditText* mUrlInitHistoryEdit;
+ int mSelBookmark;
+ int mIdRandomPanelCount;
+ int mRandomPanelCount;
+ int mIdRandomBookmarks;
+ int mRandomBookmarks;
+ int mIdDisableTimeout;
+ int mDisableTimeout;
+ int mIdControlCrashPlugin;
+ int mIdControlHangPlugin;
+ int mIdControlExitApp;
+
+ GLUI* mGluiMediaTimeControlWindow;
+ int mIdMediaTimeControlPlay;
+ int mIdMediaTimeControlLoop;
+ int mIdMediaTimeControlPause;
+ int mIdMediaTimeControlStop;
+ int mIdMediaTimeControlSeek;
+ int mIdMediaTimeControlVolume;
+ int mMediaTimeControlVolume;
+ int mIdMediaTimeControlSeekSeconds;
+ int mMediaTimeControlSeekSeconds;
+ int mIdMediaTimeControlRewind;
+ int mIdMediaTimeControlFastForward;
+
+ GLUI* mGluiMediaBrowserControlWindow;
+ int mIdMediaBrowserControlBack;
+ GLUI_Button* mMediaBrowserControlBackButton;
+ int mIdMediaBrowserControlStop;
+ int mIdMediaBrowserControlForward;
+ GLUI_Button* mMediaBrowserControlForwardButton;
+ bool mGluiMediaTimeControlWindowFlag;
+ bool mGluiMediaBrowserControlWindowFlag;
+ bool mMediaBrowserControlBackButtonFlag;
+ bool mMediaBrowserControlForwardButtonFlag;
+ int mIdMediaBrowserControlHome;
+ int mIdMediaBrowserControlReload;
+ int mIdMediaBrowserControlClearCache;
+ int mIdMediaBrowserControlClearCookies;
+ int mIdMediaBrowserControlEnableCookies;
+ int mMediaBrowserControlEnableCookies;
+
+ GLUI* mBottomGLUIWindow;
+ GLUI_StaticText* mStatusText;
+};
+
+#endif // LL_MEDIA_PLUGIN_TEST_H
+
diff --git a/indra/win_crash_logger/CMakeLists.txt b/indra/win_crash_logger/CMakeLists.txt
index 27022680b8..0bd59f0990 100644
--- a/indra/win_crash_logger/CMakeLists.txt
+++ b/indra/win_crash_logger/CMakeLists.txt
@@ -72,6 +72,7 @@ target_link_libraries(windows-crash-logger
${LLCOMMON_LIBRARIES}
${WINDOWS_LIBRARIES}
${DXGUID_LIBRARY}
+ ${GOOGLE_PERFTOOLS_LIBRARIES}
user32
gdi32
ole32
diff --git a/install.xml b/install.xml
index b980028447..bffb4b2903 100644
--- a/install.xml
+++ b/install.xml
@@ -37,9 +37,9 @@
<key>windows</key>
<map>
<key>md5sum</key>
- <string>e6ba152b7edd4ad2c9db4f9ff7bd38e1</string>
+ <string>91155239b02f576384603795d41eb971</string>
<key>url</key>
- <uri>http://s3.amazonaws.com/viewer-source-downloads/install_pkgs/GL-windows-20080613.tar.bz2</uri>
+ <uri>http://s3.amazonaws.com/viewer-source-downloads/install_pkgs/GL-windows-20090505.tar.bz2</uri>
</map>
</map>
</map>
@@ -207,30 +207,30 @@
<key>darwin</key>
<map>
<key>md5sum</key>
- <string>081ef195a856c708cc473c4421b4b290</string>
+ <string>6be5bca5f4b031b1b79824da5cfd4ddf</string>
<key>url</key>
- <uri>http://s3.amazonaws.com/viewer-source-downloads/install_pkgs/boost-1.34.1-darwin-20090223.tar.bz2</uri>
+ <uri>http://s3.amazonaws.com/viewer-source-downloads/install_pkgs/boost-1.34.1-darwin-20090702a.tar.bz2</uri>
</map>
<key>linux</key>
<map>
<key>md5sum</key>
- <string>b516a8576ecad0f957db7fc2cd972aac</string>
+ <string>113ca35011c916660a8aa55bc1ca462a</string>
<key>url</key>
- <uri>http://s3.amazonaws.com/viewer-source-downloads/install_pkgs/boost-1.34.1-linux-20090223a.tar.bz2</uri>
+ <uri>http://s3.amazonaws.com/viewer-source-downloads/install_pkgs/boost-1.34.1-linux-20090702.tar.bz2</uri>
</map>
<key>linux64</key>
<map>
<key>md5sum</key>
- <string>6db62bb7f141b3a1b3107e1f9aad0eb0</string>
+ <string>270f64d3aa416cec96f445d58dfcfb6d</string>
<key>url</key>
- <uri>http://s3.amazonaws.com/viewer-source-downloads/install_pkgs/boost-1.34.1-linux64-20090223a.tar.bz2</uri>
+ <uri>http://s3.amazonaws.com/viewer-source-downloads/install_pkgs/boost-1.34.1-linux64-20090702.tar.bz2</uri>
</map>
<key>windows</key>
<map>
<key>md5sum</key>
- <string>3b56fe9e8d2975c612639d0a5370ffe7</string>
+ <string>44d4fdf386742b94419c93ad2baa1616</string>
<key>url</key>
- <uri>http://s3.amazonaws.com/viewer-source-downloads/install_pkgs/boost-1.34.1-windows-20090225.tar.bz2</uri>
+ <uri>http://s3.amazonaws.com/viewer-source-downloads/install_pkgs/boost-1.34.1-windows-20090702.tar.bz2</uri>
</map>
</map>
</map>
@@ -415,6 +415,21 @@
</map>
</map>
</map>
+ <key>freeglut</key>
+ <map>
+ <key>license</key>
+ <string>mit</string>
+ <key>packages</key>
+ <map>
+ <key>windows</key>
+ <map>
+ <key>md5sum</key>
+ <string>fcbb695ff203775fad96d184bf5f34fc</string>
+ <key>url</key>
+ <uri>http://s3.amazonaws.com/viewer-source-downloads/install_pkgs/freeglut-2.4.0-windows-20090608.tar.bz2</uri>
+ </map>
+ </map>
+ </map>
<key>freetype</key>
<map>
<key>copyright</key>
@@ -435,9 +450,9 @@
<key>linux</key>
<map>
<key>md5sum</key>
- <string>eeffb03bd6672b6e7751448e5306d874</string>
+ <string>978ad7c67fe4a2419bfc841e2956ff9f</string>
<key>url</key>
- <uri>http://s3.amazonaws.com/viewer-source-downloads/install_pkgs/freetype-2.1.5-linux-20081201.tar.bz2</uri>
+ <uri>http://s3.amazonaws.com/viewer-source-downloads/install_pkgs/freetype-2.3.9-linux-20090521c.tar.bz2</uri>
</map>
<key>linux64</key>
<map>
@@ -526,6 +541,28 @@
</map>
</map>
</map>
+ <key>glui</key>
+ <map>
+ <key>license</key>
+ <string>lgpl</string>
+ <key>packages</key>
+ <map>
+ <key>darwin</key>
+ <map>
+ <key>md5sum</key>
+ <string>84f792a860691d0fad6d1de6eeb31baa</string>
+ <key>url</key>
+ <uri>http://s3.amazonaws.com/viewer-source-downloads/install_pkgs/glui-2.36-darwin-20090623a.tar.bz2</uri>
+ </map>
+ <key>windows</key>
+ <map>
+ <key>md5sum</key>
+ <string>5b8631fe510d4ebaeb965c673937e1e7</string>
+ <key>url</key>
+ <uri>http://s3.amazonaws.com/viewer-source-downloads/install_pkgs/glui-2.3.6-windows-freeglut-20090608.tar.bz2</uri>
+ </map>
+ </map>
+ </map>
<key>google</key>
<map>
<key>license</key>
@@ -541,36 +578,22 @@
</map>
</map>
</map>
- <key>googlemock</key>
+ <key>google-perftools</key>
<map>
<key>copyright</key>
- <string>Copyright 2008, Google Inc.</string>
+ <string>Copyright (c) 2005, Google Inc.</string>
<key>description</key>
- <string>Google C++ Mocking Framework (or Google Mock for short) is a library for writing and using C++ mock classes.</string>
+ <string>Heap performance and validity checking tools from google. Includes TCMalloc, heap-checker, heap-profiler and cpu-profiler.</string>
<key>license</key>
<string>bsd</string>
<key>packages</key>
<map>
- <key>darwin</key>
- <map>
- <key>md5sum</key>
- <string>4863e9fea433d0a4be761ea5d3e8346a</string>
- <key>url</key>
- <uri>http://s3.amazonaws.com/viewer-source-downloads/install_pkgs/googlemock-1.1.0-darwin-20090626.tar.bz2</uri>
- </map>
- <key>linux</key>
- <map>
- <key>md5sum</key>
- <string>877dabecf84339690191c6115c76366e</string>
- <key>url</key>
- <uri>http://s3.amazonaws.com/viewer-source-downloads/install_pkgs/googlemock-1.1.0-linux32-20090527.tar.bz2</uri>
- </map>
<key>windows</key>
<map>
<key>md5sum</key>
- <string>be37695d9f26552aec81c8e97ded0212</string>
+ <string>32dba32ddd460a08e082898ebba6315c</string>
<key>url</key>
- <uri>http://s3.amazonaws.com/viewer-source-downloads/install_pkgs/googlemock-1.1.0-windows-20090529.tar.bz2</uri>
+ <uri>http://s3.amazonaws.com/viewer-source-downloads/install_pkgs/google-perftools-1.0-windows-20090406.tar.bz2</uri>
</map>
</map>
</map>
@@ -897,39 +920,32 @@ anguage Infrstructure (CLI) international standard</string>
</map>
</map>
</map>
- <key>llmozlib</key>
+ <key>llqtwebkit</key>
<map>
<key>license</key>
- <string>mozillaPL</string>
+ <string>lgpl</string>
<key>packages</key>
<map>
<key>darwin</key>
<map>
<key>md5sum</key>
- <string>c951587726618d33646f2b169c290bd3</string>
+ <string>1859f5f6335d702cc42aeb602669b55e</string>
<key>url</key>
- <uri>http://s3.amazonaws.com/viewer-source-downloads/install_pkgs/llmozlib-2_0_0_21-darwin-20090304.tar.bz2</uri>
+ <uri>http://s3.amazonaws.com/viewer-source-downloads/install_pkgs/llqtwebkit-darwin-20090827.tar.bz2</uri>
</map>
<key>linux</key>
<map>
<key>md5sum</key>
- <string>b7ebcf0fb764ed4fa57c62d068b4a769</string>
- <key>url</key>
- <uri>http://s3.amazonaws.com/viewer-source-downloads/install_pkgs/llmozlib-linux-20090304prfhk.tar.bz2</uri>
- </map>
- <key>linux64</key>
- <map>
- <key>md5sum</key>
- <string>c2ae53462b56e0999ba386774ab0b789</string>
+ <string>5e91fba63006aa5e6266496cf7497100</string>
<key>url</key>
- <uri>http://s3.amazonaws.com/viewer-source-downloads/install_pkgs/llmozlib-linux64-20080909.tar.bz2</uri>
+ <uri>http://s3.amazonaws.com/viewer-source-downloads/install_pkgs/llqtwebkit-linux-20090819a.tar.bz2</uri>
</map>
<key>windows</key>
<map>
<key>md5sum</key>
- <string>e9454e258b99668782d8570481b5eda1</string>
+ <string>0edde7f54c0229cd6f615917198becaf</string>
<key>url</key>
- <uri>http://s3.amazonaws.com/viewer-source-downloads/install_pkgs/llmozlib-windows-20090306.tar.bz2</uri>
+ <uri>http://s3.amazonaws.com/viewer-source-downloads/install_pkgs/llqtwebkit-windows-20090920.tar.bz2</uri>
</map>
</map>
</map>
@@ -1365,9 +1381,9 @@ anguage Infrstructure (CLI) international standard</string>
<key>linux</key>
<map>
<key>md5sum</key>
- <string>80ee8d5a30563ce0f55d37fed6dfc744</string>
+ <string>1804b54034ef7f82832506a44acb06b8</string>
<key>url</key>
- <uri>http://s3.amazonaws.com/viewer-source-downloads/install_pkgs/zlib-1.2.3-linux-20090417.tar.bz2</uri>
+ <uri>http://s3.amazonaws.com/viewer-source-downloads/install_pkgs/zlib-1.2.3-linux-20090603.tar.bz2</uri>
</map>
<key>linux64</key>
<map>
@@ -1379,9 +1395,9 @@ anguage Infrstructure (CLI) international standard</string>
<key>windows</key>
<map>
<key>md5sum</key>
- <string>9ad657cc5146fef77ffa8dd1c069018f</string>
+ <string>ddb09c2dd7d2caed1bd7cc1686c4214c</string>
<key>url</key>
- <uri>http://s3.amazonaws.com/viewer-source-downloads/install_pkgs/zlib-1.2.3-windows-20080723.tar.bz2</uri>
+ <uri>http://s3.amazonaws.com/viewer-source-downloads/install_pkgs/zlib-1.2.3-windows-20090505.tar.bz2</uri>
</map>
</map>
</map>
@@ -1583,7 +1599,7 @@ your work.
<key>glh_linear</key>
<map>
<key>text</key>
- <string>glh - is a platform-indepenedent C++ OpenGL helper library
+ <string>glh - is a platform-indepenedent C++ OpenGL helper library
Copyright (c) 2000 Cass Everitt
Copyright (c) 2000 NVIDIA Corporation
@@ -1595,14 +1611,14 @@ conditions are met:
Redistributions of source code must retain the above
copyright notice, this list of conditions and the following
-disclaimer.
+disclaimer.
Redistributions in binary form must reproduce the above
copyright notice, this list of conditions and the following
disclaimer in the documentation and/or other materials
-provided with the distribution.
+provided with the distribution.
The names of contributors to this software may not be used
to endorse or promote products derived from this software
-without specific prior written permission.
+without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
@@ -1613,13 +1629,18 @@ BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
-ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
-POSSIBILITY OF SUCH DAMAGE.
+ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGE.
Cass Everitt - cass@r3.nu
</string>
</map>
+ <key>glut</key>
+ <map>
+ <key>url</key>
+ <string>http://www.xmission.com/~nate/glut/README-win32.txt</string>
+ </map>
<key>gpl</key>
<map>
<key>url</key>
@@ -1671,11 +1692,6 @@ Cass Everitt - cass@r3.nu
<key>text</key>
<string>http://www.jclark.com/xml/copying.txt</string>
</map>
- <key>mozillaPL</key>
- <map>
- <key>url</key>
- <string>http://www.mozilla.org/MPL/MPL-1.1.html</string>
- </map>
<key>ogg-vorbis</key>
<map>
<key>url</key>
@@ -1697,26 +1713,26 @@ Cass Everitt - cass@r3.nu
<string>ENGLISH
Apple Computer, Inc.
-QuickTime 7 Software Developer Kit (SDK)
+QuickTime 7 Software Developer Kit (SDK)
Software License Agreement
PLEASE READ THIS SOFTWARE LICENSE AGREEMENT ("LICENSE") BEFORE USING THE SOFTWARE. BY USING THE SOFTWARE, YOU ARE AGREEING TO BE BOUND BY THE TERMS OF THIS LICENSE. IF YOU ARE ACCESSING THE SOFTWARE ELECTRONICALLY, SIGNIFY YOUR AGREEMENT TO BE BOUND BY THE TERMS OF THIS LICENSE BY CLICKING THE "AGREE/ACCEPT" BUTTON. IF YOU DO NOT AGREE TO THE TERMS OF THIS LICENSE, RETURN THE APPLE SOFTWARE TO THE PLACE WHERE YOU OBTAINED IT FOR A REFUND OR, IF THE SOFTWARE WAS ACCESSED ELECTRONICALLY, CLICK "DISAGREE/DECLINE".
-IMPORTANT NOTE: To the extent this software may be used to reproduce materials, it is licensed to you only for reproduction of materials you are authorized or legally permitted to reproduce.
+IMPORTANT NOTE: To the extent this software may be used to reproduce materials, it is licensed to you only for reproduction of materials you are authorized or legally permitted to reproduce.
-1. License. Any software, tools, utilities, sample code, documentation, fonts, API?s, header files and other materials accompanying this License, whether on disk, print or electronic documentation, in read only memory, or any other media, (collectively, the "Apple Software") are licensed, not sold, to you by Apple Computer, Inc. ("Apple") for use only under the terms of this License, and Apple reserves all rights not expressly granted to you. The rights granted herein are limited to Apple's and its licensors' intellectual property rights in the Apple Software and do not include any other patents or intellectual property rights. You own the media on which the Apple Software is recorded but Apple and/or Apple's licensor(s) retain ownership of the Apple Software itself. The Apple Software in this package and any copies, modifications and derivative works that this License authorizes you to make are subject to this License.
+1. License. Any software, tools, utilities, sample code, documentation, fonts, API?s, header files and other materials accompanying this License, whether on disk, print or electronic documentation, in read only memory, or any other media, (collectively, the "Apple Software") are licensed, not sold, to you by Apple Computer, Inc. ("Apple") for use only under the terms of this License, and Apple reserves all rights not expressly granted to you. The rights granted herein are limited to Apple's and its licensors' intellectual property rights in the Apple Software and do not include any other patents or intellectual property rights. You own the media on which the Apple Software is recorded but Apple and/or Apple's licensor(s) retain ownership of the Apple Software itself. The Apple Software in this package and any copies, modifications and derivative works that this License authorizes you to make are subject to this License.
-2. Permitted Uses and Restrictions. You may use the Apple Software to develop application software that is compatible with, and runs only on Mac OS X and/or Windows platforms with QuickTime installed. Except for compiling header files and linking libraries as necessary to build your application software, you have no right to modify, incorporate into or include in combination with your own programs, license or otherwise redistribute any portion of the Apple Software. Your software application may not interfere with the functionality of QuickTime Player or the QuickTime Plug-in, including but not limited to file type or MIME type associations that are registered to QuickTime. You may make only as many internal use copies of the Apple Software as reasonably necessary to use the Apple Software as permitted in this paragraph and distribute such copies only to your employees whose job duties require them to so use the Apple Software. You must reproduce on each copy of the Apple Software or portion thereof, the Apple copyright notice and any other proprietary legends that were on the original copy of the Apple Software. Except as expressly permitted in this License, you may not decompile, reverse engineer, disassemble, modify, rent, lease, loan, sublicense, distribute or create derivative works based upon the Apple Software in whole or part. Your rights under this License will terminate automatically without notice from Apple if you fail to comply with any term(s) of this License. In addition, Apple reserves the right to terminate this License if a new version of Apple's operating system software or the Apple Software is released which is incompatible with the Apple Software.
+2. Permitted Uses and Restrictions. You may use the Apple Software to develop application software that is compatible with, and runs only on Mac OS X and/or Windows platforms with QuickTime installed. Except for compiling header files and linking libraries as necessary to build your application software, you have no right to modify, incorporate into or include in combination with your own programs, license or otherwise redistribute any portion of the Apple Software. Your software application may not interfere with the functionality of QuickTime Player or the QuickTime Plug-in, including but not limited to file type or MIME type associations that are registered to QuickTime. You may make only as many internal use copies of the Apple Software as reasonably necessary to use the Apple Software as permitted in this paragraph and distribute such copies only to your employees whose job duties require them to so use the Apple Software. You must reproduce on each copy of the Apple Software or portion thereof, the Apple copyright notice and any other proprietary legends that were on the original copy of the Apple Software. Except as expressly permitted in this License, you may not decompile, reverse engineer, disassemble, modify, rent, lease, loan, sublicense, distribute or create derivative works based upon the Apple Software in whole or part. Your rights under this License will terminate automatically without notice from Apple if you fail to comply with any term(s) of this License. In addition, Apple reserves the right to terminate this License if a new version of Apple's operating system software or the Apple Software is released which is incompatible with the Apple Software.
-3. Disclaimer Of Warranty. The Apple Software may be "alpha", "beta", "development", pre-release, untested, and/or not fully tested and may contain errors that could cause failures or loss of data, be incomplete or contain inaccuracies. YOU EXPRESSLY ACKNOWLEDGE AND AGREE THAT USE OF THE APPLE SOFTWARE IS AT YOUR SOLE RISK AND THAT THE ENTIRE RISK AS TO SATISFACTORY QUALITY, PERFORMANCE, ACCURACY AND EFFORT IS WITH YOU. EXCEPT FOR THE LIMITED WARRANTY ON MEDIA SET FORTH ABOVE AND TO THE MAXIMUM EXTENT PERMITTED BY APPLICABLE LAW, THE APPLE SOFTWARE IS PROVIDED "AS IS", WITH ALL FAULTS AND WITHOUT WARRANTY OF ANY KIND, AND APPLE AND APPLE'S LICENSORS (COLLECTIVELY REFERRED TO AS "APPLE" FOR THE PURPOSES OF SECTIONS 4 AND 5) HEREBY DISCLAIM ALL WARRANTIES AND CONDITIONS WITH RESPECT TO THE APPLE SOFTWARE, EITHER EXPRESS, IMPLIED OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES AND/OR CONDITIONS OF MERCHANTABILITY, OF SATISFACTORY QUALITY, OF FITNESS FOR A PARTICULAR PURPOSE, OF ACCURACY, OF QUIET ENJOYMENT, AND NON-INFRINGEMENT OF THIRD PARTY RIGHTS. APPLE DOES NOT WARRANT AGAINST INTERFERENCE WITH YOUR ENJOYMENT OF THE APPLE SOFTWARE, THAT THE FUNCTIONS CONTAINED IN THE APPLE SOFTWARE WILL MEET YOUR REQUIREMENTS, THAT THE OPERATION OF THE APPLE SOFTWARE WILL BE UNINTERRUPTED OR ERROR-FREE, OR THAT DEFECTS IN THE APPLE SOFTWARE WILL BE CORRECTED. NO ORAL OR WRITTEN INFORMATION OR ADVICE GIVEN BY APPLE OR AN APPLE AUTHORIZED REPRESENTATIVE SHALL CREATE A WARRANTY. SHOULD THE APPLE SOFTWARE PROVE DEFECTIVE, YOU ASSUME THE ENTIRE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. SOME JURISDICTIONS DO NOT ALLOW THE EXCLUSION OF IMPLIED WARRANTIES OR LIMITATIONS ON APPLICABLE STATUTORY RIGHTS OF A CONSUMER, SO THE ABOVE EXCLUSION AND LIMITATIONS MAY NOT APPLY TO YOU.
+3. Disclaimer Of Warranty. The Apple Software may be "alpha", "beta", "development", pre-release, untested, and/or not fully tested and may contain errors that could cause failures or loss of data, be incomplete or contain inaccuracies. YOU EXPRESSLY ACKNOWLEDGE AND AGREE THAT USE OF THE APPLE SOFTWARE IS AT YOUR SOLE RISK AND THAT THE ENTIRE RISK AS TO SATISFACTORY QUALITY, PERFORMANCE, ACCURACY AND EFFORT IS WITH YOU. EXCEPT FOR THE LIMITED WARRANTY ON MEDIA SET FORTH ABOVE AND TO THE MAXIMUM EXTENT PERMITTED BY APPLICABLE LAW, THE APPLE SOFTWARE IS PROVIDED "AS IS", WITH ALL FAULTS AND WITHOUT WARRANTY OF ANY KIND, AND APPLE AND APPLE'S LICENSORS (COLLECTIVELY REFERRED TO AS "APPLE" FOR THE PURPOSES OF SECTIONS 4 AND 5) HEREBY DISCLAIM ALL WARRANTIES AND CONDITIONS WITH RESPECT TO THE APPLE SOFTWARE, EITHER EXPRESS, IMPLIED OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES AND/OR CONDITIONS OF MERCHANTABILITY, OF SATISFACTORY QUALITY, OF FITNESS FOR A PARTICULAR PURPOSE, OF ACCURACY, OF QUIET ENJOYMENT, AND NON-INFRINGEMENT OF THIRD PARTY RIGHTS. APPLE DOES NOT WARRANT AGAINST INTERFERENCE WITH YOUR ENJOYMENT OF THE APPLE SOFTWARE, THAT THE FUNCTIONS CONTAINED IN THE APPLE SOFTWARE WILL MEET YOUR REQUIREMENTS, THAT THE OPERATION OF THE APPLE SOFTWARE WILL BE UNINTERRUPTED OR ERROR-FREE, OR THAT DEFECTS IN THE APPLE SOFTWARE WILL BE CORRECTED. NO ORAL OR WRITTEN INFORMATION OR ADVICE GIVEN BY APPLE OR AN APPLE AUTHORIZED REPRESENTATIVE SHALL CREATE A WARRANTY. SHOULD THE APPLE SOFTWARE PROVE DEFECTIVE, YOU ASSUME THE ENTIRE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. SOME JURISDICTIONS DO NOT ALLOW THE EXCLUSION OF IMPLIED WARRANTIES OR LIMITATIONS ON APPLICABLE STATUTORY RIGHTS OF A CONSUMER, SO THE ABOVE EXCLUSION AND LIMITATIONS MAY NOT APPLY TO YOU.
4. Limitation Of Liability. TO THE EXTENT NOT PROHIBITED BY LAW, IN NO EVENT SHALL APPLE BE LIABLE FOR PERSONAL INJURY, OR ANY INCIDENTAL, SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES WHATSOEVER, INCLUDING, WITHOUT LIMITATION, DAMAGES FOR LOSS OF PROFITS, LOSS OF DATA, BUSINESS INTERRUPTION OR ANY OTHER COMMERCIAL DAMAGES OR LOSSES, ARISING OUT OF OR RELATED TO YOUR USE OR INABILITY TO USE THE APPLE SOFTWARE, HOWEVER CAUSED, REGARDLESS OF THE THEORY OF LIABILITY (CONTRACT, TORT OR OTHERWISE) AND EVEN IF APPLE HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. SOME JURISDICTIONS DO NOT ALLOW THE LIMITATION OF LIABILITY FOR PERSONAL INJURY, OR OF INCIDENTAL OR CONSEQUENTIAL DAMAGES, SO THIS LIMITATION MAY NOT APPLY TO YOU. In no event shall Apple's total liability to you for all damages (other than as may be required by applicable law in cases involving personal injury) exceed the amount of fifty dollars ($50.00). The foregoing limitations will apply even if the above stated remedy fails of its essential purpose.
-5. Export Control. You may not use or otherwise export or reexport the Apple Product except as authorized by United States law and the laws of the jurisdiction in which the Apple Product was obtained. In particular, but without limitation, the Apple Product may not be exported or re-exported (a) into any U.S. embargoed countries or (b) to anyone on the U.S. Treasury Department's list of Specially Designated Nationals or the U.S. Department of Commerce Denied Person?s List or Entity List. By using the Apple Product, you represent and warrant that you are not located in any such country or on any such list.
+5. Export Control. You may not use or otherwise export or reexport the Apple Product except as authorized by United States law and the laws of the jurisdiction in which the Apple Product was obtained. In particular, but without limitation, the Apple Product may not be exported or re-exported (a) into any U.S. embargoed countries or (b) to anyone on the U.S. Treasury Department's list of Specially Designated Nationals or the U.S. Department of Commerce Denied Person?s List or Entity List. By using the Apple Product, you represent and warrant that you are not located in any such country or on any such list.
6. Government End Users. The Apple Software and related documentation are "Commercial Items", as that term is defined at 48 C.F.R. ?2.101, consisting of "Commercial Computer Software" and "Commercial Computer Software Documentation", as such terms are used in 48 C.F.R. ?12.212 or 48 C.F.R. ?227.7202, as applicable. Consistent with 48 C.F.R. ?12.212 or 48 C.F.R. ?227.7202-1through 227.7202-4, as applicable, the Commercial Computer Software and Commercial Computer Software Documentation are being licensed to U.S. Government end users (a) only as Commercial Items and (b) with only those rights as are granted to all other end users pursuant to the terms and conditions herein. Unpublished-rights reserved under the copyright laws of the United States.
-7. Controlling Law and Severability. This License will be governed by and construed in accordance with the laws of the State of California, as applied to agreements entered into and to be performed entirely within California between California residents. This License shall not be governed by the United Nations Convention on Contracts for the International Sale of Goods, the application of which is expressly excluded. If for any reason a court of competent jurisdiction finds any provision, or portion thereof, to be unenforceable, the remainder of this License shall continue in full force and effect.
+7. Controlling Law and Severability. This License will be governed by and construed in accordance with the laws of the State of California, as applied to agreements entered into and to be performed entirely within California between California residents. This License shall not be governed by the United Nations Convention on Contracts for the International Sale of Goods, the application of which is expressly excluded. If for any reason a court of competent jurisdiction finds any provision, or portion thereof, to be unenforceable, the remainder of this License shall continue in full force and effect.
8. Complete Agreement. This License constitutes the entire agreement between the parties with respect to the use of the Apple Software licensed hereunder and supersedes all prior or contemporaneous understandings regarding such subject matter. No amendment to or modification of this License will be binding unless in writing and signed by Apple. Any translation of this License is done for local requirements and in the event of a dispute between the English and any non-English versions, the English version of this License shall govern.